Merge "Update javadocs for ACTION_CONFIGURE_VOICEMAIL"
diff --git a/Android.bp b/Android.bp
index 9e8c384..1f4c59a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,48 +12,66 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+// Build ext.jar
+// ============================================================
+java_library {
+    name: "ext",
+    no_framework_libs: true,
+    static_libs: [
+        "libphonenumber-platform",
+        "nist-sip",
+        "tagsoup",
+    ],
+    dxflags: ["--core-library"],
+}
+
 // ====  c++ proto device library  ==============================
 cc_library {
     name: "libplatformprotos",
     host_supported: true,
-    // b/34740546, work around clang-tidy segmentation fault.
-    tidy_checks: ["-modernize*"],
     proto: {
         export_proto_headers: true,
         include_dirs: ["external/protobuf/src"],
     },
 
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-unused-parameter",
+    ],
     target: {
         host: {
             proto: {
                 type: "full",
             },
+            srcs: [
+                "core/proto/**/*.proto",
+                "libs/incident/**/*.proto",
+            ],
         },
         android: {
             proto: {
                 type: "lite",
             },
+            // We only build the protos that are optimized for the lite
+            // runtime, as well as the only protos that are actually
+            // needed by the device.
+            srcs: [
+                "core/proto/android/service/graphicsstats.proto",
+            ],
             shared: {
-                // The proto files generate full protos, but we only use
-                // them as lite on device.  This works fine for a static
-                // library, where the unused full symbols are stripped,
-                // but fails if it is linked as a standalone shared
-                // library because it is missing the full runtime.
                 enabled: false,
             },
         },
     },
-
-    srcs: [
-        "core/proto/**/*.proto",
-        "libs/incident/**/*.proto",
-    ],
 }
 
 subdirs = [
-    "core/jni",
+    "cmds/*",
+    "core/*",
     "libs/*",
     "media/*",
+    "proto",
     "tools/*",
     "native/android",
     "native/graphics/jni",
@@ -62,3 +80,51 @@
 optional_subdirs = [
     "core/tests/utiltests/jni",
 ]
+
+java_library {
+    name: "hwbinder",
+    no_framework_libs: true,
+
+    srcs: [
+        "core/java/android/os/HidlSupport.java",
+        "core/java/android/annotation/NonNull.java",
+        "core/java/android/os/HwBinder.java",
+        "core/java/android/os/HwBlob.java",
+        "core/java/android/os/HwParcel.java",
+        "core/java/android/os/IHwBinder.java",
+        "core/java/android/os/IHwInterface.java",
+        "core/java/android/os/DeadObjectException.java",
+        "core/java/android/os/DeadSystemException.java",
+        "core/java/android/os/RemoteException.java",
+        "core/java/android/util/AndroidException.java",
+    ],
+
+    dxflags: ["--core-library"],
+    installable: false,
+}
+
+python_defaults {
+    name: "base_default",
+    version: {
+        py2: {
+            enabled: true,
+            embedded_launcher: true,
+        },
+        py3: {
+            enabled: false,
+            embedded_launcher: false,
+        },
+    },
+}
+
+python_binary_host {
+    name: "fontchain_linter",
+    defaults: ["base_default"],
+    main: "tools/fonts/fontchain_linter.py",
+    srcs: [
+        "tools/fonts/fontchain_linter.py",
+    ],
+    libs: [
+        "fontTools",
+    ],
+}
diff --git a/Android.mk b/Android.mk
index 0e6642d7..6fce011 100644
--- a/Android.mk
+++ b/Android.mk
@@ -129,7 +129,7 @@
 	../../system/bt/binder/android/bluetooth/IBluetoothHeadsetPhone.aidl \
 	../../system/bt/binder/android/bluetooth/IBluetoothHealth.aidl \
 	../../system/bt/binder/android/bluetooth/IBluetoothHealthCallback.aidl \
-	../../system/bt/binder/android/bluetooth/IBluetoothInputDevice.aidl \
+	../../system/bt/binder/android/bluetooth/IBluetoothHidHost.aidl \
 	../../system/bt/binder/android/bluetooth/IBluetoothPan.aidl \
 	../../system/bt/binder/android/bluetooth/IBluetoothManager.aidl \
 	../../system/bt/binder/android/bluetooth/IBluetoothManagerCallback.aidl \
@@ -138,9 +138,10 @@
 	../../system/bt/binder/android/bluetooth/IBluetoothPbap.aidl \
 	../../system/bt/binder/android/bluetooth/IBluetoothPbapClient.aidl \
 	../../system/bt/binder/android/bluetooth/IBluetoothSap.aidl \
+	../../system/bt/binder/android/bluetooth/IBluetoothSocketManager.aidl \
 	../../system/bt/binder/android/bluetooth/IBluetoothStateChangeCallback.aidl \
 	../../system/bt/binder/android/bluetooth/IBluetoothHeadsetClient.aidl \
-	../../system/bt/binder/android/bluetooth/IBluetoothInputHost.aidl \
+	../../system/bt/binder/android/bluetooth/IBluetoothHidDevice.aidl \
 	../../system/bt/binder/android/bluetooth/IBluetoothHidDeviceCallback.aidl \
 	../../system/bt/binder/android/bluetooth/IBluetoothGatt.aidl \
 	../../system/bt/binder/android/bluetooth/IBluetoothGattCallback.aidl \
@@ -159,6 +160,7 @@
 	core/java/android/content/ISyncServiceAdapter.aidl \
 	core/java/android/content/ISyncStatusObserver.aidl \
 	core/java/android/content/om/IOverlayManager.aidl \
+	core/java/android/content/pm/IDexModuleRegisterCallback.aidl \
 	core/java/android/content/pm/ILauncherApps.aidl \
 	core/java/android/content/pm/IOnAppsChangedListener.aidl \
 	core/java/android/content/pm/IOnPermissionsChangeListener.aidl \
@@ -217,6 +219,9 @@
 	core/java/android/hardware/location/IGeofenceHardwareMonitorCallback.aidl \
 	core/java/android/hardware/location/IContextHubCallback.aidl \
 	core/java/android/hardware/location/IContextHubService.aidl \
+	core/java/android/hardware/radio/IRadioService.aidl \
+	core/java/android/hardware/radio/ITuner.aidl \
+	core/java/android/hardware/radio/ITunerCallback.aidl \
 	core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl \
 	core/java/android/hardware/usb/IUsbManager.aidl \
 	core/java/android/net/ICaptivePortal.aidl \
@@ -281,6 +286,18 @@
 	core/java/android/service/carrier/ICarrierService.aidl \
 	core/java/android/service/carrier/ICarrierMessagingCallback.aidl \
 	core/java/android/service/carrier/ICarrierMessagingService.aidl \
+	core/java/android/service/euicc/IDeleteSubscriptionCallback.aidl \
+	core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl \
+	core/java/android/service/euicc/IEraseSubscriptionsCallback.aidl \
+	core/java/android/service/euicc/IEuiccService.aidl \
+	core/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl \
+	core/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl \
+	core/java/android/service/euicc/IGetEidCallback.aidl \
+	core/java/android/service/euicc/IGetEuiccInfoCallback.aidl \
+	core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl \
+	core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl \
+	core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl \
+	core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl \
 	core/java/android/service/gatekeeper/IGateKeeperService.aidl \
 	core/java/android/service/notification/INotificationListener.aidl \
 	core/java/android/service/notification/IStatusBarNotificationHolder.aidl \
@@ -344,6 +361,7 @@
 	core/java/android/view/IPinnedStackController.aidl \
 	core/java/android/view/IPinnedStackListener.aidl \
 	core/java/android/view/IRotationWatcher.aidl \
+	core/java/android/view/IWallpaperVisibilityListener.aidl \
 	core/java/android/view/IWindow.aidl \
 	core/java/android/view/IWindowFocusObserver.aidl \
 	core/java/android/view/IWindowId.aidl \
@@ -372,6 +390,7 @@
 	core/java/com/android/internal/appwidget/IAppWidgetHost.aidl \
 	core/java/com/android/internal/backup/IBackupTransport.aidl \
 	core/java/com/android/internal/backup/IObbBackupService.aidl \
+	core/java/com/android/internal/car/ICarServiceHelper.aidl \
 	core/java/com/android/internal/inputmethod/IInputContentUriToken.aidl \
 	core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl \
 	core/java/com/android/internal/policy/IKeyguardDismissCallback.aidl \
@@ -486,9 +505,9 @@
 	telecomm/java/com/android/internal/telecom/IInCallService.aidl \
 	telecomm/java/com/android/internal/telecom/ITelecomService.aidl \
 	telecomm/java/com/android/internal/telecom/RemoteServiceCallback.aidl \
-        telephony/java/android/telephony/mbms/IMbmsDownloadManagerCallback.aidl \
-	telephony/java/android/telephony/mbms/IMbmsStreamingManagerCallback.aidl \
-	telephony/java/android/telephony/mbms/IDownloadProgressListener.aidl \
+	telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl \
+	telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl \
+	telephony/java/android/telephony/mbms/IDownloadStateCallback.aidl \
         telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl \
 	telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl \
 	telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl \
@@ -500,10 +519,12 @@
 	telephony/java/com/android/ims/internal/IImsEcbmListener.aidl \
         telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl \
         telephony/java/com/android/ims/internal/IImsFeatureStatusCallback.aidl \
+        telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl \
         telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl \
+	telephony/java/com/android/ims/internal/IImsRcsFeature.aidl \
 	telephony/java/com/android/ims/internal/IImsService.aidl \
 	telephony/java/com/android/ims/internal/IImsServiceController.aidl \
-	telephony/java/com/android/ims/internal/IImsServiceFeatureListener.aidl \
+	telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl \
 	telephony/java/com/android/ims/internal/IImsStreamMediaSession.aidl \
 	telephony/java/com/android/ims/internal/IImsUt.aidl \
 	telephony/java/com/android/ims/internal/IImsUtListener.aidl \
@@ -527,6 +548,7 @@
 	telephony/java/com/android/internal/telephony/ITelephony.aidl \
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
+	telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl \
 	wifi/java/android/net/wifi/IWifiManager.aidl \
 	wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl \
 	wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl \
@@ -584,7 +606,10 @@
     android.hardware.thermal-V1.0-java-constants         \
     android.hardware.tv.input-V1.0-java-constants        \
     android.hardware.usb-V1.0-java-constants             \
+    android.hardware.usb-V1.1-java-constants             \
     android.hardware.vibrator-V1.0-java-constants        \
+    android.hardware.vibrator-V1.1-java-constants        \
+    android.hardware.wifi-V1.0-java-constants            \
 
 # Loaded with System.loadLibrary by android.view.textclassifier
 LOCAL_REQUIRED_MODULES += libtextclassifier
@@ -595,6 +620,8 @@
 
 LOCAL_MODULE := framework
 
+LOCAL_JAVAC_SHARD_SIZE := 150
+
 LOCAL_DX_FLAGS := --core-library --multi-dex
 LOCAL_JACK_FLAGS := --multi-dex native
 
@@ -611,32 +638,6 @@
 
 framework_built := $(call java-lib-deps,framework)
 
-# HwBinder
-# =======================================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-        core/java/android/os/HidlSupport.java \
-        core/java/android/annotation/NonNull.java \
-        core/java/android/os/HwBinder.java \
-        core/java/android/os/HwBlob.java \
-        core/java/android/os/HwParcel.java \
-        core/java/android/os/IHwBinder.java \
-        core/java/android/os/IHwInterface.java \
-        core/java/android/os/DeadObjectException.java \
-        core/java/android/os/DeadSystemException.java \
-        core/java/android/os/RemoteException.java \
-        core/java/android/util/AndroidException.java \
-
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-oj core-libart
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := hwbinder
-
-LOCAL_DX_FLAGS := --core-library
-LOCAL_UNINSTALLABLE_MODULE := true
-include $(BUILD_JAVA_LIBRARY)
-
 # Copy AIDL files to be preprocessed and included in the SDK,
 # specified relative to the root of the build tree.
 # ============================================================
@@ -655,6 +656,9 @@
 	frameworks/base/telephony/java/android/telephony/IccOpenLogicalChannelResponse.aidl \
 	frameworks/base/telephony/java/android/telephony/NeighboringCellInfo.aidl \
 	frameworks/base/telephony/java/android/telephony/ModemActivityInfo.aidl \
+	frameworks/base/telephony/java/android/telephony/UiccAccessRule.aidl \
+	frameworks/base/telephony/java/android/telephony/euicc/DownloadableSubscription.aidl \
+	frameworks/base/telephony/java/android/telephony/euicc/EuiccInfo.aidl \
 	frameworks/base/location/java/android/location/Location.aidl \
 	frameworks/base/location/java/android/location/Address.aidl \
 	frameworks/base/location/java/android/location/Criteria.aidl \
@@ -708,6 +712,7 @@
 	frameworks/base/core/java/android/print/PrinterInfo.aidl \
 	frameworks/base/core/java/android/print/PrintJobId.aidl \
 	frameworks/base/core/java/android/printservice/recommendation/RecommendationInfo.aidl \
+	frameworks/base/core/java/android/hardware/radio/RadioManager.aidl \
 	frameworks/base/core/java/android/hardware/usb/UsbDevice.aidl \
 	frameworks/base/core/java/android/hardware/usb/UsbInterface.aidl \
 	frameworks/base/core/java/android/hardware/usb/UsbEndpoint.aidl \
@@ -767,6 +772,9 @@
 	frameworks/base/core/java/android/view/textservice/SuggestionsInfo.aidl \
 	frameworks/base/core/java/android/service/carrier/CarrierIdentifier.aidl \
 	frameworks/base/core/java/android/service/carrier/MessagePdu.aidl \
+	frameworks/base/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.aidl \
+	frameworks/base/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.aidl \
+	frameworks/base/core/java/android/service/euicc/GetEuiccProfileInfoListResult.aidl \
 	frameworks/base/core/java/android/service/notification/Adjustment.aidl \
 	frameworks/base/core/java/android/service/notification/Condition.aidl \
 	frameworks/base/core/java/android/service/notification/SnoozeCriterion.aidl \
@@ -901,8 +909,7 @@
 # FRAMEWORKS_BASE_SUBDIRS comes from build/core/pathmap.mk
 dirs_to_document := \
 	$(dirs_to_check_apis) \
-  $(addprefix ../../, $(FRAMEWORKS_DATA_BINDING_JAVA_SRC_DIRS)) \
-  $(addprefix ../../, $(FRAMEWORKS_SUPPORT_JAVA_SRC_DIRS)) \
+	$(addprefix ../../, $(FRAMEWORKS_DATA_BINDING_JAVA_SRC_DIRS))
 
 patterns_to_not_document := \
 	$(call find-no-docs-pattern, $(dirs_to_document))
@@ -937,7 +944,8 @@
 framework_docs_LOCAL_INTERMEDIATE_SOURCES := \
 	$(framework_res_source_path)/android/R.java \
 	$(framework_res_source_path)/android/Manifest.java \
-	$(framework_res_source_path)/com/android/internal/R.java
+	$(framework_res_source_path)/com/android/internal/R.java \
+	$(patsubst $(TARGET_OUT_COMMON_INTERMEDIATES)/%,%,$(libcore_to_document_generated))
 
 framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES := \
 	core-oj \
@@ -950,6 +958,8 @@
 	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)
@@ -992,24 +1002,19 @@
     -since $(SRC_API_DIR)/23.txt 23 \
     -since $(SRC_API_DIR)/24.txt 24 \
     -since $(SRC_API_DIR)/25.txt 25 \
-    -since ./frameworks/base/api/current.txt O \
+    -since $(SRC_API_DIR)/26.txt 26 \
     -werror -hide 111 -hide 113 -hide 121 \
     -overview $(LOCAL_PATH)/core/java/overview.html \
 
-# Allow the support library to add its own droiddoc options.
-include $(LOCAL_PATH)/../support/droiddoc.mk
-
 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) \
-	$(foreach lib,$(FRAMEWORKS_SUPPORT_JAVA_LIBRARIES),$(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)) \
-	$(foreach lib,$(FRAMEWORKS_SUPPORT_JAVA_LIBRARIES),$(call intermediates-dir-for,JAVA_LIBRARIES,$(lib)-res,,COMMON))
+	$(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR)
 
 framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES := \
     frameworks/base/docs/knowntags.txt \
-    libcore/Docs.mk
+    $(libcore_to_document_generated)
 
 samples_dir := development/samples/browseable
 
@@ -1048,6 +1053,11 @@
 		-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
+
 # ====  the api stubs and current.xml ===========================
 include $(CLEAR_VARS)
 
@@ -1463,35 +1473,6 @@
 
 include $(BUILD_DROIDDOC)
 
-# Build ext.jar
-# ============================================================
-
-ext_dirs := \
-	../../external/nist-sip/java \
-	../../external/tagsoup/src \
-
-ext_src_files := $(call all-java-files-under,$(ext_dirs))
-
-# ====  the library  =========================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(ext_src_files)
-
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-oj core-libart
-LOCAL_STATIC_JAVA_LIBRARIES := libphonenumber-platform
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := ext
-
-LOCAL_DX_FLAGS := --core-library
-
-ifneq ($(INCREMENTAL_BUILDS),)
-    LOCAL_PROGUARD_ENABLED := disabled
-    LOCAL_JACK_ENABLED := incremental
-endif
-
-include $(BUILD_JAVA_LIBRARY)
-
 # ====  java proto host library  ==============================
 include $(CLEAR_VARS)
 LOCAL_MODULE := platformprotos
diff --git a/apct-tests/perftests/core/src/android/os/SharedPreferencesTest.java b/apct-tests/perftests/core/src/android/os/SharedPreferencesTest.java
new file mode 100644
index 0000000..099134f
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/os/SharedPreferencesTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.os;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SharedPreferencesTest {
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeCachedGetSharedPreferences() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        final Context context = InstrumentationRegistry.getTargetContext();
+        // Do the real work once as we're only interested in cache-hit performance
+        SharedPreferences prefs = context.getSharedPreferences("test", Context.MODE_PRIVATE);
+        while (state.keepRunning()) {
+            prefs = context.getSharedPreferences("test", Context.MODE_PRIVATE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java
index f56c763..e89157b 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java
@@ -56,20 +56,8 @@
 @LargeTest
 @RunWith(AndroidJUnit4.class)
 public class UserLifecycleTest {
-    private final int TIMEOUT_REMOVE_USER_MS = 4 * 1000; // 4 sec
-    private final int CHECK_USER_REMOVED_INTERVAL_MS = 200; // 0.2 sec
-
-    private final int TIMEOUT_USER_START_SEC = 4; // 4 sec
-
-    private final int TIMEOUT_USER_SWITCH_SEC = 8; // 8 sec
-
-    private final int TIMEOUT_USER_STOP_SEC = 1; // 1 sec
-
-    private final int TIMEOUT_MANAGED_PROFILE_UNLOCK_SEC = 2; // 2 sec
-
-    private final int TIMEOUT_LOCKED_BOOT_COMPLETE_MS = 5 * 1000; // 5 sec
-
-    private final int TIMEOUT_EPHERMAL_USER_STOP_SEC = 6; // 6 sec
+    private final int TIMEOUT_IN_SECOND = 10;
+    private final int CHECK_USER_REMOVED_INTERVAL_MS = 200;
 
     private UserManager mUm;
     private ActivityManager mAm;
@@ -109,7 +97,7 @@
             final CountDownLatch latch = new CountDownLatch(1);
             registerBroadcastReceiver(Intent.ACTION_USER_STARTED, latch, userInfo.id);
             mIam.startUserInBackground(userInfo.id);
-            latch.await(TIMEOUT_USER_START_SEC, TimeUnit.SECONDS);
+            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
 
             mState.pauseTiming();
             removeUser(userInfo.id);
@@ -142,10 +130,10 @@
             final CountDownLatch latch = new CountDownLatch(1);
             registerBroadcastReceiver(Intent.ACTION_USER_STARTED, latch, userInfo.id);
             mIam.startUserInBackground(userInfo.id);
-            latch.await(TIMEOUT_USER_START_SEC, TimeUnit.SECONDS);
+            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
             mState.resumeTiming();
 
-            stopUser(userInfo.id);
+            stopUser(userInfo.id, false);
 
             mState.pauseTiming();
             removeUser(userInfo.id);
@@ -164,7 +152,7 @@
             mState.resumeTiming();
 
             mAm.switchUser(userInfo.id);
-            latch.await(TIMEOUT_LOCKED_BOOT_COMPLETE_MS, TimeUnit.SECONDS);
+            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
 
             mState.pauseTiming();
             switchUser(startUser);
@@ -184,7 +172,7 @@
             mState.resumeTiming();
 
             mIam.startUserInBackground(userInfo.id);
-            latch.await(TIMEOUT_MANAGED_PROFILE_UNLOCK_SEC, TimeUnit.SECONDS);
+            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
 
             mState.pauseTiming();
             removeUser(userInfo.id);
@@ -215,10 +203,30 @@
             mState.resumeTiming();
 
             mAm.switchUser(startUser);
-            latch.await(TIMEOUT_EPHERMAL_USER_STOP_SEC, TimeUnit.SECONDS);
+            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
 
             mState.pauseTiming();
-            switchLatch.await(TIMEOUT_USER_SWITCH_SEC, TimeUnit.SECONDS);
+            switchLatch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
+            removeUser(userInfo.id);
+            mState.resumeTiming();
+        }
+    }
+
+    @Test
+    public void managedProfileStoppedPerf() throws Exception {
+        while (mState.keepRunning()) {
+            mState.pauseTiming();
+            final UserInfo userInfo = mUm.createProfileForUser("TestUser",
+                    UserInfo.FLAG_MANAGED_PROFILE, mAm.getCurrentUser());
+            final CountDownLatch latch = new CountDownLatch(1);
+            registerBroadcastReceiver(Intent.ACTION_USER_UNLOCKED, latch, userInfo.id);
+            mIam.startUserInBackground(userInfo.id);
+            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
+            mState.resumeTiming();
+
+            stopUser(userInfo.id, true);
+
+            mState.pauseTiming();
             removeUser(userInfo.id);
             mState.resumeTiming();
         }
@@ -228,12 +236,12 @@
         final CountDownLatch latch = new CountDownLatch(1);
         registerUserSwitchObserver(latch, null, userId);
         mAm.switchUser(userId);
-        latch.await(TIMEOUT_USER_SWITCH_SEC, TimeUnit.SECONDS);
+        latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
     }
 
-    private void stopUser(int userId) throws Exception {
+    private void stopUser(int userId, boolean force) throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
-        mIam.stopUser(userId, false /* force */, new IStopUserCallback.Stub() {
+        mIam.stopUser(userId, force /* force */, new IStopUserCallback.Stub() {
             @Override
             public void userStopped(int userId) throws RemoteException {
                 latch.countDown();
@@ -243,7 +251,7 @@
             public void userStopAborted(int userId) throws RemoteException {
             }
         });
-        latch.await(TIMEOUT_USER_STOP_SEC, TimeUnit.SECONDS);
+        latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
     }
 
     private void registerUserSwitchObserver(final CountDownLatch switchLatch,
@@ -283,9 +291,10 @@
         try {
             mUm.removeUser(userId);
             final long startTime = System.currentTimeMillis();
+            final long timeoutInMs = TIMEOUT_IN_SECOND * 1000;
             while (mUm.getUserInfo(userId) != null &&
-                    System.currentTimeMillis() - startTime < TIMEOUT_REMOVE_USER_MS) {
-                Thread.sleep(CHECK_USER_REMOVED_INTERVAL_MS);
+                    System.currentTimeMillis() - startTime < timeoutInMs) {
+                TimeUnit.MILLISECONDS.sleep(CHECK_USER_REMOVED_INTERVAL_MS);
             }
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
diff --git a/api/current.txt b/api/current.txt
index c095202..2b9e372 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3163,7 +3163,6 @@
 
   public final class AnimatorSet extends android.animation.Animator {
     ctor public AnimatorSet();
-    method public android.animation.AnimatorSet clone();
     method public java.util.ArrayList<android.animation.Animator> getChildAnimations();
     method public long getCurrentPlayTime();
     method public long getDuration();
@@ -3282,7 +3281,6 @@
 
   public final class ObjectAnimator extends android.animation.ValueAnimator {
     ctor public ObjectAnimator();
-    method public android.animation.ObjectAnimator clone();
     method public java.lang.String getPropertyName();
     method public java.lang.Object getTarget();
     method public static android.animation.ObjectAnimator ofArgb(java.lang.Object, java.lang.String, int...);
@@ -3308,7 +3306,6 @@
     method public static <T, V> android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofPropertyValuesHolder(java.lang.Object, android.animation.PropertyValuesHolder...);
     method public void setAutoCancel(boolean);
-    method public android.animation.ObjectAnimator setDuration(long);
     method public void setProperty(android.util.Property);
     method public void setPropertyName(java.lang.String);
   }
@@ -3390,7 +3387,6 @@
     ctor public ValueAnimator();
     method public void addUpdateListener(android.animation.ValueAnimator.AnimatorUpdateListener);
     method public static boolean areAnimatorsEnabled();
-    method public android.animation.ValueAnimator clone();
     method public float getAnimatedFraction();
     method public java.lang.Object getAnimatedValue();
     method public java.lang.Object getAnimatedValue(java.lang.String);
@@ -4964,7 +4960,6 @@
     ctor public IntentService(java.lang.String);
     method public android.os.IBinder onBind(android.content.Intent);
     method protected abstract void onHandleIntent(android.content.Intent);
-    method public void onStart(android.content.Intent, int);
     method public void setIntentRedelivery(boolean);
   }
 
@@ -6093,6 +6088,19 @@
     method public void onDetached();
   }
 
+  public final class WallpaperColors implements android.os.Parcelable {
+    ctor public WallpaperColors(android.os.Parcel);
+    ctor public WallpaperColors(android.graphics.Color, android.graphics.Color, android.graphics.Color);
+    method public int describeContents();
+    method public static android.app.WallpaperColors fromBitmap(android.graphics.Bitmap);
+    method public static android.app.WallpaperColors fromDrawable(android.graphics.drawable.Drawable);
+    method public android.graphics.Color getPrimaryColor();
+    method public android.graphics.Color getSecondaryColor();
+    method public android.graphics.Color getTertiaryColor();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR;
+  }
+
   public final class WallpaperInfo implements android.os.Parcelable {
     ctor public WallpaperInfo(android.content.Context, android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public int describeContents();
@@ -6115,6 +6123,8 @@
   }
 
   public class WallpaperManager {
+    method public void addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener);
+    method public void addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener, android.os.Handler);
     method public void clear() throws java.io.IOException;
     method public void clear(int) throws java.io.IOException;
     method public void clearWallpaperOffsets(android.os.IBinder);
@@ -6129,6 +6139,7 @@
     method public android.graphics.drawable.Drawable getDrawable();
     method public android.graphics.drawable.Drawable getFastDrawable();
     method public static android.app.WallpaperManager getInstance(android.content.Context);
+    method public android.app.WallpaperColors getWallpaperColors(int);
     method public android.os.ParcelFileDescriptor getWallpaperFile(int);
     method public int getWallpaperId(int);
     method public android.app.WallpaperInfo getWallpaperInfo();
@@ -6137,6 +6148,7 @@
     method public boolean isWallpaperSupported();
     method public android.graphics.drawable.Drawable peekDrawable();
     method public android.graphics.drawable.Drawable peekFastDrawable();
+    method public void removeOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener);
     method public void sendWallpaperCommand(android.os.IBinder, java.lang.String, int, int, int, android.os.Bundle);
     method public void setBitmap(android.graphics.Bitmap) throws java.io.IOException;
     method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
@@ -6161,6 +6173,10 @@
     field public static final java.lang.String WALLPAPER_PREVIEW_META_DATA = "android.wallpaper.preview";
   }
 
+  public static abstract interface WallpaperManager.OnColorsChangedListener {
+    method public abstract void onColorsChanged(android.app.WallpaperColors, int);
+  }
+
 }
 
 package android.app.admin {
@@ -8935,6 +8951,7 @@
     field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
+    field public static final java.lang.String IPSEC_SERVICE = "ipsec";
     field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
     field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
     field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -11046,7 +11063,6 @@
 
   public static class AssetFileDescriptor.AutoCloseInputStream extends android.os.ParcelFileDescriptor.AutoCloseInputStream {
     ctor public AssetFileDescriptor.AutoCloseInputStream(android.content.res.AssetFileDescriptor) throws java.io.IOException;
-    method public void mark(int);
   }
 
   public static class AssetFileDescriptor.AutoCloseOutputStream extends android.os.ParcelFileDescriptor.AutoCloseOutputStream {
@@ -11354,7 +11370,6 @@
     method public void copyStringToBuffer(int, android.database.CharArrayBuffer);
     method public void deactivate();
     method public void fillWindow(int, android.database.CursorWindow);
-    method protected void finalize();
     method public byte[] getBlob(int);
     method public int getColumnCount();
     method public int getColumnIndex(java.lang.String);
@@ -13829,7 +13844,6 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setOpacity(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
   }
@@ -13910,7 +13924,6 @@
     method public void setAlpha(int);
     method public void setAntiAlias(boolean);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setGravity(int);
     method public void setMipMap(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
@@ -14036,7 +14049,6 @@
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method protected void setConstantState(android.graphics.drawable.DrawableContainer.DrawableContainerState);
-    method public void setDither(boolean);
     method public void setEnterFadeDuration(int);
     method public void setExitFadeDuration(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
@@ -14103,7 +14115,6 @@
     method public void setColors(int[]);
     method public void setCornerRadii(float[]);
     method public void setCornerRadius(float);
-    method public void setDither(boolean);
     method public void setGradientCenter(float, float);
     method public void setGradientRadius(float);
     method public void setGradientType(int);
@@ -14198,7 +14209,6 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setDrawable(int, android.graphics.drawable.Drawable);
     method public boolean setDrawableByLayerId(int, android.graphics.drawable.Drawable);
     method public void setId(int, int);
@@ -14239,7 +14249,6 @@
     method public android.graphics.Paint getPaint();
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
     method public void setTargetDensity(android.util.DisplayMetrics);
     method public void setTargetDensity(int);
@@ -14302,7 +14311,6 @@
     method protected void onDraw(android.graphics.drawable.shapes.Shape, android.graphics.Canvas, android.graphics.Paint);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setIntrinsicHeight(int);
     method public void setIntrinsicWidth(int);
     method public void setPadding(int, int, int, int);
@@ -14344,32 +14352,27 @@
 
   public class ArcShape extends android.graphics.drawable.shapes.RectShape {
     ctor public ArcShape(float, float);
-    method public android.graphics.drawable.shapes.ArcShape clone() throws java.lang.CloneNotSupportedException;
     method public final float getStartAngle();
     method public final float getSweepAngle();
   }
 
   public class OvalShape extends android.graphics.drawable.shapes.RectShape {
     ctor public OvalShape();
-    method public android.graphics.drawable.shapes.OvalShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public class PathShape extends android.graphics.drawable.shapes.Shape {
     ctor public PathShape(android.graphics.Path, float, float);
-    method public android.graphics.drawable.shapes.PathShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
   }
 
   public class RectShape extends android.graphics.drawable.shapes.Shape {
     ctor public RectShape();
-    method public android.graphics.drawable.shapes.RectShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
     method protected final android.graphics.RectF rect();
   }
 
   public class RoundRectShape extends android.graphics.drawable.shapes.RectShape {
     ctor public RoundRectShape(float[], android.graphics.RectF, float[]);
-    method public android.graphics.drawable.shapes.RoundRectShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public abstract class Shape implements java.lang.Cloneable {
@@ -14454,7 +14457,6 @@
     method public final void autoFocus(android.hardware.Camera.AutoFocusCallback);
     method public final void cancelAutoFocus();
     method public final boolean enableShutterSound(boolean);
-    method protected void finalize();
     method public static void getCameraInfo(int, android.hardware.Camera.CameraInfo);
     method public static int getNumberOfCameras();
     method public android.hardware.Camera.Parameters getParameters();
@@ -15064,7 +15066,6 @@
     method public <T> T get(android.hardware.camera2.CameraCharacteristics.Key<T>);
     method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getAvailableCaptureRequestKeys();
     method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getAvailableCaptureResultKeys();
-    method public java.util.List<android.hardware.camera2.CameraCharacteristics.Key<?>> getKeys();
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_MODES;
@@ -15421,7 +15422,6 @@
   public final class CaptureRequest extends android.hardware.camera2.CameraMetadata implements android.os.Parcelable {
     method public int describeContents();
     method public <T> T get(android.hardware.camera2.CaptureRequest.Key<T>);
-    method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getKeys();
     method public java.lang.Object getTag();
     method public boolean isReprocess();
     method public void writeToParcel(android.os.Parcel, int);
@@ -15500,7 +15500,6 @@
   public class CaptureResult extends android.hardware.camera2.CameraMetadata {
     method public <T> T get(android.hardware.camera2.CaptureResult.Key<T>);
     method public long getFrameNumber();
-    method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getKeys();
     method public android.hardware.camera2.CaptureRequest getRequest();
     method public int getSequenceId();
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Boolean> BLACK_LEVEL_LOCK;
@@ -17938,7 +17937,6 @@
   }
 
   public class DateIntervalFormat extends android.icu.text.UFormat {
-    method public synchronized java.lang.Object clone();
     method public final java.lang.StringBuffer format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.DateInterval, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.Calendar, android.icu.util.Calendar, java.lang.StringBuffer, java.text.FieldPosition);
@@ -18744,7 +18742,6 @@
 
   public final class RuleBasedCollator extends android.icu.text.Collator {
     ctor public RuleBasedCollator(java.lang.String) throws java.lang.Exception;
-    method public android.icu.text.RuleBasedCollator cloneAsThawed();
     method public int compare(java.lang.String, java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.text.CharacterIterator);
@@ -18771,7 +18768,6 @@
     method public void setFrenchCollation(boolean);
     method public void setFrenchCollationDefault();
     method public void setLowerCaseFirst(boolean);
-    method public android.icu.text.RuleBasedCollator setMaxVariable(int);
     method public void setNumericCollation(boolean);
     method public void setNumericCollationDefault();
     method public void setStrengthDefault();
@@ -21295,7 +21291,6 @@
     ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException;
     method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
-    method protected void finalize();
     method public int getAudioFormat();
     method public int getAudioSessionId();
     method public int getAudioSource();
@@ -21400,7 +21395,6 @@
     method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
     method public int attachAuxEffect(int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
-    method protected void finalize();
     method public void flush();
     method public int getAudioFormat();
     method public int getAudioSessionId();
@@ -21799,7 +21793,6 @@
     method public boolean clearQueue();
     method public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
     method public boolean closeJetFile();
-    method protected void finalize();
     method public static android.media.JetPlayer getJetPlayer();
     method public static int getMaxTracks();
     method public boolean loadJetFile(java.lang.String);
@@ -21839,7 +21832,6 @@
     ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
-    method protected void finalize();
     method public static boolean isSystemIdSupported(int);
     method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
     method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
@@ -21896,7 +21888,6 @@
     method public static android.view.Surface createPersistentInputSurface();
     method public final int dequeueInputBuffer(long);
     method public final int dequeueOutputBuffer(android.media.MediaCodec.BufferInfo, long);
-    method protected void finalize();
     method public final void flush();
     method public android.media.MediaCodecInfo getCodecInfo();
     method public java.nio.ByteBuffer getInputBuffer(int);
@@ -22308,7 +22299,6 @@
 
   public final class MediaCrypto {
     ctor public MediaCrypto(java.util.UUID, byte[]) throws android.media.MediaCryptoException;
-    method protected void finalize();
     method public static final boolean isCryptoSchemeSupported(java.util.UUID);
     method public final void release();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
@@ -22329,7 +22319,6 @@
     ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
-    method protected void finalize();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
     method public final void setMediaCasSession(android.media.MediaCas.Session);
   }
@@ -22372,7 +22361,6 @@
   public final class MediaDrm {
     ctor public MediaDrm(java.util.UUID) throws android.media.UnsupportedSchemeException;
     method public void closeSession(byte[]);
-    method protected void finalize();
     method public android.media.MediaDrm.CryptoSession getCryptoSession(byte[], java.lang.String, java.lang.String);
     method public android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>) throws android.media.NotProvisionedException;
     method public byte[] getPropertyByteArray(java.lang.String);
@@ -22469,7 +22457,6 @@
   public final class MediaExtractor {
     ctor public MediaExtractor();
     method public boolean advance();
-    method protected void finalize();
     method public long getCachedDuration();
     method public android.media.MediaExtractor.CasInfo getCasInfo(int);
     method public android.media.DrmInitData getDrmInitData();
@@ -22771,7 +22758,6 @@
     method public static android.media.MediaPlayer create(android.content.Context, int, android.media.AudioAttributes, int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
     method public void deselectTrack(int) throws java.lang.IllegalStateException;
-    method protected void finalize();
     method public int getAudioSessionId();
     method public int getCurrentPosition();
     method public android.media.MediaPlayer.DrmInfo getDrmInfo();
@@ -22967,7 +22953,6 @@
 
   public class MediaRecorder {
     ctor public MediaRecorder();
-    method protected void finalize();
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
     method public android.os.PersistableBundle getMetrics();
@@ -23239,7 +23224,6 @@
   public final class MediaSync {
     ctor public MediaSync();
     method public final android.view.Surface createInputSurface();
-    method protected void finalize();
     method public void flush();
     method public android.media.PlaybackParams getPlaybackParams();
     method public android.media.SyncParams getSyncParams();
@@ -23359,10 +23343,6 @@
 
   public deprecated class RemoteControlClient.MetadataEditor extends android.media.MediaMetadataEditor {
     method public synchronized void apply();
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putBitmap(int, android.graphics.Bitmap) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putLong(int, long) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putObject(int, java.lang.Object) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putString(int, java.lang.String) throws java.lang.IllegalArgumentException;
     field public static final int BITMAP_KEY_ARTWORK = 100; // 0x64
   }
 
@@ -23409,7 +23389,6 @@
   }
 
   public class Ringtone {
-    method protected void finalize();
     method public android.media.AudioAttributes getAudioAttributes();
     method public deprecated int getStreamType();
     method public java.lang.String getTitle(android.content.Context);
@@ -23463,7 +23442,6 @@
     ctor public deprecated SoundPool(int, int, int);
     method public final void autoPause();
     method public final void autoResume();
-    method protected void finalize();
     method public int load(java.lang.String, int);
     method public int load(android.content.Context, int, int);
     method public int load(android.content.res.AssetFileDescriptor, int);
@@ -23532,7 +23510,6 @@
 
   public class ToneGenerator {
     ctor public ToneGenerator(int, int);
-    method protected void finalize();
     method public final int getAudioSessionId();
     method public void release();
     method public boolean startTone(int);
@@ -23665,7 +23642,6 @@
   public final class VolumeShaper implements java.lang.AutoCloseable {
     method public void apply(android.media.VolumeShaper.Operation);
     method public void close();
-    method protected void finalize();
     method public float getVolume();
     method public void replace(android.media.VolumeShaper.Configuration, android.media.VolumeShaper.Operation, boolean);
   }
@@ -23720,7 +23696,6 @@
   }
 
   public class AudioEffect {
-    method protected void finalize();
     method public android.media.audiofx.AudioEffect.Descriptor getDescriptor() throws java.lang.IllegalStateException;
     method public boolean getEnabled() throws java.lang.IllegalStateException;
     method public int getId() throws java.lang.IllegalStateException;
@@ -23973,7 +23948,6 @@
 
   public class Visualizer {
     ctor public Visualizer(int) throws java.lang.RuntimeException, java.lang.UnsupportedOperationException;
-    method protected void finalize();
     method public int getCaptureSize() throws java.lang.IllegalStateException;
     method public static int[] getCaptureSizeRange();
     method public boolean getEnabled();
@@ -25530,6 +25504,67 @@
     field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
   }
 
+  public final class IpSecAlgorithm implements android.os.Parcelable {
+    ctor public IpSecAlgorithm(java.lang.String, byte[]);
+    ctor public IpSecAlgorithm(java.lang.String, byte[], int);
+    method public int describeContents();
+    method public byte[] getKey();
+    method public java.lang.String getName();
+    method public int getTruncationLengthBits();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final java.lang.String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";
+    field public static final java.lang.String AUTH_HMAC_MD5 = "hmac(md5)";
+    field public static final java.lang.String AUTH_HMAC_SHA1 = "hmac(sha1)";
+    field public static final java.lang.String AUTH_HMAC_SHA256 = "hmac(sha256)";
+    field public static final java.lang.String AUTH_HMAC_SHA384 = "hmac(sha384)";
+    field public static final java.lang.String AUTH_HMAC_SHA512 = "hmac(sha512)";
+    field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
+    field public static final java.lang.String CRYPT_AES_CBC = "cbc(aes)";
+  }
+
+  public final class IpSecManager {
+    method public void applyTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
+    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
+    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
+    method public void removeTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
+    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress) throws android.net.IpSecManager.ResourceUnavailableException;
+    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+  }
+
+  public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
+  }
+
+  public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
+    method public void close();
+    method public int getSpi();
+  }
+
+  public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
+    method public int getSpi();
+  }
+
+  public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
+    method public void close() throws java.io.IOException;
+    method public int getPort();
+    method public java.io.FileDescriptor getSocket();
+  }
+
+  public final class IpSecTransform implements java.lang.AutoCloseable {
+    method public void close();
+    field public static final int DIRECTION_IN = 0; // 0x0
+    field public static final int DIRECTION_OUT = 1; // 0x1
+  }
+
+  public static class IpSecTransform.Builder {
+    ctor public IpSecTransform.Builder(android.content.Context);
+    method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+    method public android.net.IpSecTransform.Builder setAuthenticatedEncryption(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
+    method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
+  }
+
   public class LinkAddress implements android.os.Parcelable {
     method public int describeContents();
     method public java.net.InetAddress getAddress();
@@ -25655,6 +25690,7 @@
     field public static final int NET_CAPABILITY_MMS = 0; // 0x0
     field public static final int NET_CAPABILITY_NOT_METERED = 11; // 0xb
     field public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; // 0xd
+    field public static final int NET_CAPABILITY_NOT_ROAMING = 18; // 0x12
     field public static final int NET_CAPABILITY_NOT_VPN = 15; // 0xf
     field public static final int NET_CAPABILITY_RCS = 8; // 0x8
     field public static final int NET_CAPABILITY_SUPL = 1; // 0x1
@@ -25685,7 +25721,7 @@
     method public boolean isConnected();
     method public boolean isConnectedOrConnecting();
     method public boolean isFailover();
-    method public boolean isRoaming();
+    method public deprecated boolean isRoaming();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
   }
@@ -25982,6 +26018,7 @@
     method public boolean protect(java.net.DatagramSocket);
     method public boolean setUnderlyingNetworks(android.net.Network[]);
     field public static final java.lang.String SERVICE_INTERFACE = "android.net.VpnService";
+    field public static final java.lang.String SERVICE_META_DATA_SUPPORTS_ALWAYS_ON = "android.net.VpnService.SUPPORTS_ALWAYS_ON";
   }
 
   public class VpnService.Builder {
@@ -30637,7 +30674,6 @@
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
-    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.Bundle> CREATOR;
     field public static final android.os.Bundle EMPTY;
@@ -30690,6 +30726,7 @@
   }
 
   public final class Debug {
+    method public static void attachJvmtiAgent(java.lang.String, java.lang.String) throws java.io.IOException;
     method public static deprecated void changeDebugPort(int);
     method public static void dumpHprofData(java.lang.String) throws java.io.IOException;
     method public static boolean dumpService(java.lang.String, java.io.FileDescriptor, java.lang.String[]);
@@ -30868,7 +30905,6 @@
   public abstract class FileObserver {
     ctor public FileObserver(java.lang.String);
     ctor public FileObserver(java.lang.String, int);
-    method protected void finalize();
     method public abstract void onEvent(int, java.lang.String);
     method public void startWatching();
     method public void stopWatching();
@@ -31022,7 +31058,6 @@
     ctor public MemoryFile(java.lang.String, int) throws java.io.IOException;
     method public synchronized boolean allowPurging(boolean) throws java.io.IOException;
     method public void close();
-    method protected void finalize();
     method public java.io.InputStream getInputStream();
     method public java.io.OutputStream getOutputStream();
     method public boolean isPurgingAllowed();
@@ -31322,7 +31357,6 @@
     method public int describeContents();
     method public android.os.PersistableBundle getPersistableBundle(java.lang.String);
     method public void putPersistableBundle(java.lang.String, android.os.PersistableBundle);
-    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.PersistableBundle> CREATOR;
     field public static final android.os.PersistableBundle EMPTY;
@@ -35645,7 +35679,6 @@
     method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
-    method public synchronized void resize(int);
     method public void setFace(android.renderscript.Type.CubemapFace);
     method public void setLOD(int);
     method public void setX(int);
@@ -37971,6 +38004,16 @@
     field public final int errno;
   }
 
+  public class Int32Ref {
+    ctor public Int32Ref(int);
+    field public int value;
+  }
+
+  public class Int64Ref {
+    ctor public Int64Ref(long);
+    field public long value;
+  }
+
   public final class Os {
     method public static java.io.FileDescriptor accept(java.io.FileDescriptor, java.net.InetSocketAddress) throws android.system.ErrnoException, java.net.SocketException;
     method public static boolean access(java.lang.String, int) throws android.system.ErrnoException;
@@ -38040,7 +38083,8 @@
     method public static void remove(java.lang.String) throws android.system.ErrnoException;
     method public static void removexattr(java.lang.String, java.lang.String) throws android.system.ErrnoException;
     method public static void rename(java.lang.String, java.lang.String) throws android.system.ErrnoException;
-    method public static long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.util.MutableLong, long) throws android.system.ErrnoException;
+    method public static deprecated long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.util.MutableLong, long) throws android.system.ErrnoException;
+    method public static long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.system.Int64Ref, long) throws android.system.ErrnoException;
     method public static int sendto(java.io.FileDescriptor, java.nio.ByteBuffer, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
     method public static int sendto(java.io.FileDescriptor, byte[], int, int, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
     method public static void setegid(int) throws android.system.ErrnoException;
@@ -38065,7 +38109,8 @@
     method public static int umask(int);
     method public static android.system.StructUtsname uname();
     method public static void unsetenv(java.lang.String) throws android.system.ErrnoException;
-    method public static int waitpid(int, android.util.MutableInt, int) throws android.system.ErrnoException;
+    method public static deprecated int waitpid(int, android.util.MutableInt, int) throws android.system.ErrnoException;
+    method public static int waitpid(int, android.system.Int32Ref, int) throws android.system.ErrnoException;
     method public static int write(java.io.FileDescriptor, java.nio.ByteBuffer) throws android.system.ErrnoException, java.io.InterruptedIOException;
     method public static int write(java.io.FileDescriptor, byte[], int, int) throws android.system.ErrnoException, java.io.InterruptedIOException;
     method public static int writev(java.io.FileDescriptor, java.lang.Object[], int[], int[]) throws android.system.ErrnoException, java.io.InterruptedIOException;
@@ -38641,6 +38686,7 @@
     method public android.telecom.Call.RttCall getRttCall();
     method public int getState();
     method public android.telecom.InCallService.VideoCall getVideoCall();
+    method public void handoverTo(android.telecom.PhoneAccountHandle, int, android.os.Bundle);
     method public void hold();
     method public boolean isRttActive();
     method public void mergeConference();
@@ -38685,6 +38731,8 @@
     method public void onConferenceableCallsChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
     method public void onConnectionEvent(android.telecom.Call, java.lang.String, android.os.Bundle);
     method public void onDetailsChanged(android.telecom.Call, android.telecom.Call.Details);
+    method public void onHandoverComplete(android.telecom.Call);
+    method public void onHandoverFailed(android.telecom.Call, int);
     method public void onParentChanged(android.telecom.Call, android.telecom.Call);
     method public void onPostDialWait(android.telecom.Call, java.lang.String);
     method public void onRttInitiationFailure(android.telecom.Call, int);
@@ -38693,6 +38741,10 @@
     method public void onRttStatusChanged(android.telecom.Call, boolean, android.telecom.Call.RttCall);
     method public void onStateChanged(android.telecom.Call, int);
     method public void onVideoCallChanged(android.telecom.Call, android.telecom.InCallService.VideoCall);
+    field public static final int HANDOVER_FAILURE_DEST_APP_REJECTED = 1; // 0x1
+    field public static final int HANDOVER_FAILURE_DEST_INVALID_PERM = 3; // 0x3
+    field public static final int HANDOVER_FAILURE_DEST_NOT_SUPPORTED = 2; // 0x2
+    field public static final int HANDOVER_FAILURE_DEST_USER_REJECTED = 4; // 0x4
   }
 
   public static class Call.Details {
@@ -38748,8 +38800,7 @@
 
   public static final class Call.RttCall {
     method public int getRttAudioMode();
-    method public java.lang.String read() throws java.io.IOException;
-    method public java.lang.String readImmediately() throws java.io.IOException;
+    method public java.lang.String read();
     method public void setRttMode(int);
     method public void write(java.lang.String) throws java.io.IOException;
     field public static final int RTT_MODE_FULL = 1; // 0x1
@@ -38761,7 +38812,9 @@
     ctor public CallAudioState(boolean, int, int);
     method public static java.lang.String audioRouteToString(int);
     method public int describeContents();
+    method public android.bluetooth.BluetoothDevice getActiveBluetoothDevice();
     method public int getRoute();
+    method public java.util.Collection<android.bluetooth.BluetoothDevice> getSupportedBluetoothDevices();
     method public int getSupportedRouteMask();
     method public boolean isMuted();
     method public void writeToParcel(android.os.Parcel, int);
@@ -38833,6 +38886,7 @@
     method public final void setActive();
     method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
     method public final void setConnectionCapabilities(int);
+    method public final void setConnectionElapsedTime(long);
     method public final void setConnectionProperties(int);
     method public final void setConnectionTime(long);
     method public final void setDialing();
@@ -38892,6 +38946,7 @@
     method public final void putExtras(android.os.Bundle);
     method public final void removeExtras(java.util.List<java.lang.String>);
     method public final void removeExtras(java.lang.String...);
+    method public void requestBluetoothAudio(java.lang.String);
     method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
     method public final void setActive();
     method public final void setAddress(android.net.Uri, int);
@@ -39023,8 +39078,11 @@
     method public void onConference(android.telecom.Connection, android.telecom.Connection);
     method public android.telecom.Connection onCreateIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public void onCreateIncomingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+    method public android.telecom.Connection onCreateIncomingHandoverConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public void onCreateOutgoingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+    method public android.telecom.Connection onCreateOutgoingHandoverConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+    method public void onHandoverFailed(android.telecom.ConnectionRequest, int);
     method public void onRemoteConferenceAdded(android.telecom.RemoteConference);
     method public void onRemoteExistingConnectionAdded(android.telecom.RemoteConnection);
     field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.ConnectionService";
@@ -39082,6 +39140,7 @@
     method public void onCanAddCallChanged(boolean);
     method public void onConnectionEvent(android.telecom.Call, java.lang.String, android.os.Bundle);
     method public void onSilenceRinger();
+    method public final void requestBluetoothAudio(java.lang.String);
     method public final void setAudioRoute(int);
     method public final void setMuted(boolean);
     field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.InCallService";
@@ -39146,6 +39205,9 @@
     field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR;
     field public static final java.lang.String EXTRA_CALL_SUBJECT_CHARACTER_ENCODING = "android.telecom.extra.CALL_SUBJECT_CHARACTER_ENCODING";
     field public static final java.lang.String EXTRA_CALL_SUBJECT_MAX_LENGTH = "android.telecom.extra.CALL_SUBJECT_MAX_LENGTH";
+    field public static final java.lang.String EXTRA_LOG_SELF_MANAGED_CALLS = "android.telecom.extra.LOG_SELF_MANAGED_CALLS";
+    field public static final java.lang.String EXTRA_SUPPORTS_HANDOVER_FROM = "android.telecom.extra.SUPPORTS_HANDOVER_FROM";
+    field public static final java.lang.String EXTRA_SUPPORTS_HANDOVER_TO = "android.telecom.extra.SUPPORTS_HANDOVER_TO";
     field public static final int NO_HIGHLIGHT_COLOR = 0; // 0x0
     field public static final int NO_RESOURCE_ID = -1; // 0xffffffff
     field public static final java.lang.String SCHEME_SIP = "sip";
@@ -39306,6 +39368,7 @@
   }
 
   public class TelecomManager {
+    method public void acceptHandover(android.net.Uri, int, android.telecom.PhoneAccountHandle);
     method public void acceptRingingCall();
     method public void acceptRingingCall(int);
     method public void addNewIncomingCall(android.telecom.PhoneAccountHandle, android.os.Bundle);
@@ -39326,6 +39389,7 @@
     method public boolean isInManagedCall();
     method public boolean isIncomingCallPermitted(android.telecom.PhoneAccountHandle);
     method public boolean isOutgoingCallPermitted(android.telecom.PhoneAccountHandle);
+    method public boolean isTtySupported();
     method public boolean isVoiceMailNumber(android.telecom.PhoneAccountHandle, java.lang.String);
     method public void placeCall(android.net.Uri, android.os.Bundle);
     method public void registerPhoneAccount(android.telecom.PhoneAccount);
@@ -39470,6 +39534,7 @@
     field public static final java.lang.String KEY_DURATION_BLOCKING_DISABLED_AFTER_EMERGENCY_INT = "duration_blocking_disabled_after_emergency_int";
     field public static final java.lang.String KEY_EDITABLE_ENHANCED_4G_LTE_BOOL = "editable_enhanced_4g_lte_bool";
     field public static final java.lang.String KEY_EDITABLE_VOICEMAIL_NUMBER_BOOL = "editable_voicemail_number_bool";
+    field public static final java.lang.String KEY_EDITABLE_VOICEMAIL_NUMBER_SETTING_BOOL = "editable_voicemail_number_setting_bool";
     field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_key_vibration_bool";
     field public static final java.lang.String KEY_FORCE_HOME_NETWORK_BOOL = "force_home_network_bool";
     field public static final java.lang.String KEY_GSM_DTMF_TONE_DELAY_INT = "gsm_dtmf_tone_delay_int";
@@ -39560,6 +39625,8 @@
     method public int getLatitude();
     method public int getLongitude();
     method public int getNetworkId();
+    method public java.lang.CharSequence getOperatorAlphaLong();
+    method public java.lang.CharSequence getOperatorAlphaShort();
     method public int getSystemId();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityCdma> CREATOR;
@@ -39571,8 +39638,13 @@
     method public int getBsic();
     method public int getCid();
     method public int getLac();
-    method public int getMcc();
-    method public int getMnc();
+    method public deprecated int getMcc();
+    method public java.lang.String getMccStr();
+    method public deprecated int getMnc();
+    method public java.lang.String getMncStr();
+    method public java.lang.String getMobileNetworkOperator();
+    method public java.lang.CharSequence getOperatorAlphaLong();
+    method public java.lang.CharSequence getOperatorAlphaShort();
     method public deprecated int getPsc();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityGsm> CREATOR;
@@ -39582,8 +39654,13 @@
     method public int describeContents();
     method public int getCi();
     method public int getEarfcn();
-    method public int getMcc();
-    method public int getMnc();
+    method public deprecated int getMcc();
+    method public java.lang.String getMccStr();
+    method public deprecated int getMnc();
+    method public java.lang.String getMncStr();
+    method public java.lang.String getMobileNetworkOperator();
+    method public java.lang.CharSequence getOperatorAlphaLong();
+    method public java.lang.CharSequence getOperatorAlphaShort();
     method public int getPci();
     method public int getTac();
     method public void writeToParcel(android.os.Parcel, int);
@@ -39594,8 +39671,13 @@
     method public int describeContents();
     method public int getCid();
     method public int getLac();
-    method public int getMcc();
-    method public int getMnc();
+    method public deprecated int getMcc();
+    method public java.lang.String getMccStr();
+    method public deprecated int getMnc();
+    method public java.lang.String getMncStr();
+    method public java.lang.String getMobileNetworkOperator();
+    method public java.lang.CharSequence getOperatorAlphaLong();
+    method public java.lang.CharSequence getOperatorAlphaShort();
     method public int getPsc();
     method public int getUarfcn();
     method public void writeToParcel(android.os.Parcel, int);
@@ -39728,13 +39810,46 @@
     field public static final int STATUS_UNKNOWN_ERROR = 4; // 0x4
   }
 
-  public class MbmsStreamingManager {
-    method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback, int, android.os.Handler) throws android.telephony.mbms.MbmsException;
-    method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback, android.os.Handler) throws android.telephony.mbms.MbmsException;
-    method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback) throws android.telephony.mbms.MbmsException;
-    method public void dispose();
-    method public void getStreamingServices(java.util.List<java.lang.String>) throws android.telephony.mbms.MbmsException;
-    method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, android.telephony.mbms.StreamingServiceCallback, android.os.Handler) throws android.telephony.mbms.MbmsException;
+  public class MbmsDownloadSession implements java.lang.AutoCloseable {
+    method public void cancelDownload(android.telephony.mbms.DownloadRequest);
+    method public void close();
+    method public static android.telephony.MbmsDownloadSession create(android.content.Context, android.telephony.mbms.MbmsDownloadSessionCallback, android.os.Handler);
+    method public static android.telephony.MbmsDownloadSession create(android.content.Context, android.telephony.mbms.MbmsDownloadSessionCallback, int, android.os.Handler);
+    method public void download(android.telephony.mbms.DownloadRequest);
+    method public int getDownloadStatus(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo);
+    method public java.io.File getTempFileRootDirectory();
+    method public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads();
+    method public void registerStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback, android.os.Handler);
+    method public void requestUpdateFileServices(java.util.List<java.lang.String>);
+    method public void resetDownloadKnowledge(android.telephony.mbms.DownloadRequest);
+    method public void setTempFileRootDirectory(java.io.File);
+    method public void unregisterStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback);
+    field public static final java.lang.String DEFAULT_TOP_LEVEL_TEMP_DIRECTORY = "androidMbmsTempFileRoot";
+    field public static final java.lang.String EXTRA_MBMS_COMPLETED_FILE_URI = "android.telephony.extra.MBMS_COMPLETED_FILE_URI";
+    field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_REQUEST = "android.telephony.extra.MBMS_DOWNLOAD_REQUEST";
+    field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_RESULT = "android.telephony.extra.MBMS_DOWNLOAD_RESULT";
+    field public static final java.lang.String EXTRA_MBMS_FILE_INFO = "android.telephony.extra.MBMS_FILE_INFO";
+    field public static final int RESULT_CANCELLED = 2; // 0x2
+    field public static final int RESULT_DOWNLOAD_FAILURE = 6; // 0x6
+    field public static final int RESULT_EXPIRED = 3; // 0x3
+    field public static final int RESULT_FILE_ROOT_UNREACHABLE = 8; // 0x8
+    field public static final int RESULT_IO_ERROR = 4; // 0x4
+    field public static final int RESULT_OUT_OF_STORAGE = 7; // 0x7
+    field public static final int RESULT_SERVICE_ID_NOT_DEFINED = 5; // 0x5
+    field public static final int RESULT_SUCCESSFUL = 1; // 0x1
+    field public static final int STATUS_ACTIVELY_DOWNLOADING = 1; // 0x1
+    field public static final int STATUS_PENDING_DOWNLOAD = 2; // 0x2
+    field public static final int STATUS_PENDING_DOWNLOAD_WINDOW = 4; // 0x4
+    field public static final int STATUS_PENDING_REPAIR = 3; // 0x3
+    field public static final int STATUS_UNKNOWN = 0; // 0x0
+  }
+
+  public class MbmsStreamingSession implements java.lang.AutoCloseable {
+    method public void close();
+    method public static android.telephony.MbmsStreamingSession create(android.content.Context, android.telephony.mbms.MbmsStreamingSessionCallback, int, android.os.Handler);
+    method public static android.telephony.MbmsStreamingSession create(android.content.Context, android.telephony.mbms.MbmsStreamingSessionCallback, android.os.Handler);
+    method public void requestUpdateStreamingServices(java.util.List<java.lang.String>);
+    method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, android.telephony.mbms.StreamingServiceCallback, android.os.Handler);
   }
 
   public class NeighboringCellInfo implements android.os.Parcelable {
@@ -39767,8 +39882,10 @@
   public class PhoneNumberUtils {
     ctor public PhoneNumberUtils();
     method public static void addTtsSpan(android.text.Spannable, int, int);
-    method public static java.lang.String calledPartyBCDFragmentToString(byte[], int, int);
-    method public static java.lang.String calledPartyBCDToString(byte[], int, int);
+    method public static deprecated java.lang.String calledPartyBCDFragmentToString(byte[], int, int);
+    method public static java.lang.String calledPartyBCDFragmentToString(byte[], int, int, int);
+    method public static deprecated java.lang.String calledPartyBCDToString(byte[], int, int);
+    method public static java.lang.String calledPartyBCDToString(byte[], int, int, int);
     method public static boolean compare(java.lang.String, java.lang.String);
     method public static boolean compare(android.content.Context, java.lang.String, java.lang.String);
     method public static java.lang.String convertKeypadLettersToDigits(java.lang.String);
@@ -39801,12 +39918,15 @@
     method public static byte[] networkPortionToCalledPartyBCD(java.lang.String);
     method public static byte[] networkPortionToCalledPartyBCDWithLength(java.lang.String);
     method public static java.lang.String normalizeNumber(java.lang.String);
-    method public static byte[] numberToCalledPartyBCD(java.lang.String);
+    method public static deprecated byte[] numberToCalledPartyBCD(java.lang.String);
+    method public static byte[] numberToCalledPartyBCD(java.lang.String, int);
     method public static java.lang.String replaceUnicodeDigits(java.lang.String);
     method public static java.lang.String stringFromStringAndTOA(java.lang.String, int);
     method public static java.lang.String stripSeparators(java.lang.String);
     method public static java.lang.String toCallerIDMinMatch(java.lang.String);
     method public static int toaFromString(java.lang.String);
+    field public static final int BCD_EXTENDED_TYPE_CALLED_PARTY = 2; // 0x2
+    field public static final int BCD_EXTENDED_TYPE_EF_ADN = 1; // 0x1
     field public static final int FORMAT_JAPAN = 2; // 0x2
     field public static final int FORMAT_NANP = 1; // 0x1
     field public static final int FORMAT_UNKNOWN = 0; // 0x0
@@ -39939,9 +40059,12 @@
     field public static final int MMS_ERROR_UNABLE_CONNECT_MMS = 3; // 0x3
     field public static final int MMS_ERROR_UNSPECIFIED = 1; // 0x1
     field public static final int RESULT_ERROR_GENERIC_FAILURE = 1; // 0x1
+    field public static final int RESULT_ERROR_LIMIT_EXCEEDED = 5; // 0x5
     field public static final int RESULT_ERROR_NO_SERVICE = 4; // 0x4
     field public static final int RESULT_ERROR_NULL_PDU = 3; // 0x3
     field public static final int RESULT_ERROR_RADIO_OFF = 2; // 0x2
+    field public static final int RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED = 8; // 0x8
+    field public static final int RESULT_ERROR_SHORT_CODE_NOT_ALLOWED = 7; // 0x7
     field public static final int STATUS_ON_ICC_FREE = 0; // 0x0
     field public static final int STATUS_ON_ICC_READ = 1; // 0x1
     field public static final int STATUS_ON_ICC_SENT = 5; // 0x5
@@ -40086,6 +40209,7 @@
     method public int getPhoneCount();
     method public int getPhoneType();
     method public android.telephony.ServiceState getServiceState();
+    method public android.telephony.SignalStrength getSignalStrength();
     method public java.lang.String getSimCountryIso();
     method public java.lang.String getSimOperator();
     method public java.lang.String getSimOperatorName();
@@ -40111,7 +40235,7 @@
     method public boolean isHearingAidCompatibilitySupported();
     method public boolean isNetworkRoaming();
     method public boolean isSmsCapable();
-    method public boolean isTtyModeSupported();
+    method public deprecated boolean isTtyModeSupported();
     method public boolean isVoiceCapable();
     method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle);
     method public boolean isWorldPhone();
@@ -40355,7 +40479,6 @@
 
   public static deprecated class SmsMessage.SubmitPdu {
     ctor public deprecated SmsMessage.SubmitPdu();
-    method public deprecated java.lang.String toString();
     field public deprecated byte[] encodedMessage;
     field public deprecated byte[] encodedScAddress;
   }
@@ -40364,15 +40487,77 @@
 
 package android.telephony.mbms {
 
-  public class MbmsException extends java.lang.Exception {
-    method public int getErrorCode();
+  public final class DownloadRequest implements android.os.Parcelable {
+    method public static android.telephony.mbms.DownloadRequest copy(android.telephony.mbms.DownloadRequest);
+    method public int describeContents();
+    method public java.lang.String getFileServiceId();
+    method public static int getMaxAppIntentSize();
+    method public static int getMaxDestinationUriSize();
+    method public android.net.Uri getSourceUri();
+    method public int getSubscriptionId();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.mbms.DownloadRequest> CREATOR;
+  }
+
+  public static class DownloadRequest.Builder {
+    ctor public DownloadRequest.Builder(android.net.Uri);
+    method public android.telephony.mbms.DownloadRequest build();
+    method public android.telephony.mbms.DownloadRequest.Builder setAppIntent(android.content.Intent);
+    method public android.telephony.mbms.DownloadRequest.Builder setServiceInfo(android.telephony.mbms.FileServiceInfo);
+    method public android.telephony.mbms.DownloadRequest.Builder setSubscriptionId(int);
+  }
+
+  public class DownloadStateCallback {
+    ctor public DownloadStateCallback();
+    ctor public DownloadStateCallback(int);
+    method public final boolean isFilterFlagSet(int);
+    method public void onProgressUpdated(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo, int, int, int, int);
+    method public void onStateUpdated(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo, int);
+    field public static final int ALL_UPDATES = 0; // 0x0
+    field public static final int PROGRESS_UPDATES = 1; // 0x1
+    field public static final int STATE_UPDATES = 2; // 0x2
+  }
+
+  public final class FileInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.lang.String getMimeType();
+    method public android.net.Uri getUri();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.mbms.FileInfo> CREATOR;
+  }
+
+  public final class FileServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.util.List<android.telephony.mbms.FileInfo> getFiles();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.mbms.FileServiceInfo> CREATOR;
+  }
+
+  public class MbmsDownloadReceiver extends android.content.BroadcastReceiver {
+    ctor public MbmsDownloadReceiver();
+    method public void onReceive(android.content.Context, android.content.Intent);
+  }
+
+  public class MbmsDownloadSessionCallback {
+    ctor public MbmsDownloadSessionCallback();
+    method public void onError(int, java.lang.String);
+    method public void onFileServicesUpdated(java.util.List<android.telephony.mbms.FileServiceInfo>);
+    method public void onMiddlewareReady();
+  }
+
+  public class MbmsErrors {
     field public static final int ERROR_MIDDLEWARE_LOST = 3; // 0x3
     field public static final int ERROR_MIDDLEWARE_NOT_BOUND = 2; // 0x2
     field public static final int ERROR_NO_UNIQUE_MIDDLEWARE = 1; // 0x1
     field public static final int SUCCESS = 0; // 0x0
   }
 
-  public static class MbmsException.GeneralErrors {
+  public static class MbmsErrors.DownloadErrors {
+    field public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 401; // 0x191
+    field public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402; // 0x192
+  }
+
+  public static class MbmsErrors.GeneralErrors {
     field public static final int ERROR_CARRIER_CHANGE_NOT_ALLOWED = 207; // 0xcf
     field public static final int ERROR_IN_E911 = 204; // 0xcc
     field public static final int ERROR_MIDDLEWARE_NOT_YET_READY = 201; // 0xc9
@@ -40382,39 +40567,39 @@
     field public static final int ERROR_UNABLE_TO_READ_SIM = 206; // 0xce
   }
 
-  public static class MbmsException.InitializationErrors {
+  public static class MbmsErrors.InitializationErrors {
     field public static final int ERROR_APP_PERMISSIONS_NOT_GRANTED = 102; // 0x66
     field public static final int ERROR_DUPLICATE_INITIALIZE = 101; // 0x65
     field public static final int ERROR_UNABLE_TO_INITIALIZE = 103; // 0x67
   }
 
-  public static class MbmsException.StreamingErrors {
+  public static class MbmsErrors.StreamingErrors {
     field public static final int ERROR_CONCURRENT_SERVICE_LIMIT_REACHED = 301; // 0x12d
     field public static final int ERROR_DUPLICATE_START_STREAM = 303; // 0x12f
     field public static final int ERROR_UNABLE_TO_START_SERVICE = 302; // 0x12e
   }
 
-  public class MbmsStreamingManagerCallback {
-    ctor public MbmsStreamingManagerCallback();
+  public class MbmsStreamingSessionCallback {
+    ctor public MbmsStreamingSessionCallback();
     method public void onError(int, java.lang.String);
     method public void onMiddlewareReady();
     method public void onStreamingServicesUpdated(java.util.List<android.telephony.mbms.StreamingServiceInfo>);
   }
 
   public class ServiceInfo {
-    method public java.lang.String getClassName();
     method public java.util.List<java.util.Locale> getLocales();
-    method public java.util.Map<java.util.Locale, java.lang.String> getNames();
+    method public java.lang.CharSequence getNameForLocale(java.util.Locale);
+    method public java.util.Set<java.util.Locale> getNamedContentLocales();
+    method public java.lang.String getServiceClassName();
     method public java.lang.String getServiceId();
     method public java.util.Date getSessionEndTime();
     method public java.util.Date getSessionStartTime();
   }
 
   public class StreamingService {
-    method public void dispose() throws android.telephony.mbms.MbmsException;
     method public android.telephony.mbms.StreamingServiceInfo getInfo();
-    method public android.net.Uri getPlaybackUri() throws android.telephony.mbms.MbmsException;
-    method public void stopStreaming() throws android.telephony.mbms.MbmsException;
+    method public android.net.Uri getPlaybackUri();
+    method public void stopStreaming();
     field public static final int BROADCAST_METHOD = 1; // 0x1
     field public static final int REASON_BY_USER_REQUEST = 1; // 0x1
     field public static final int REASON_END_OF_SESSION = 2; // 0x2
@@ -40504,7 +40689,6 @@
     method public java.util.List<junit.framework.TestCase> getTestCases();
     method public java.lang.String getTestClassName();
     method public junit.framework.TestResult getTestResult();
-    method protected java.lang.Class loadSuiteClass(java.lang.String) throws java.lang.ClassNotFoundException;
     method protected void runFailed(java.lang.String);
     method public void runTest();
     method public void runTest(junit.framework.TestResult);
@@ -40765,12 +40949,10 @@
     ctor protected MockContentProvider();
     ctor public MockContentProvider(android.content.Context);
     ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
-    method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>);
     method public int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public java.lang.String getType(android.net.Uri);
     method public android.net.Uri insert(android.net.Uri, android.content.ContentValues);
     method public boolean onCreate();
-    method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
@@ -41040,10 +41222,6 @@
 
   public deprecated class MockResources extends android.content.res.Resources {
     ctor public MockResources();
-    method public int getColor(int) throws android.content.res.Resources.NotFoundException;
-    method public android.content.res.ColorStateList getColorStateList(int) throws android.content.res.Resources.NotFoundException;
-    method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
-    method public void updateConfiguration(android.content.res.Configuration, android.util.DisplayMetrics);
   }
 
 }
@@ -42291,7 +42469,6 @@
 
   public abstract class MetricAffectingSpan extends android.text.style.CharacterStyle implements android.text.style.UpdateLayout {
     ctor public MetricAffectingSpan();
-    method public android.text.style.MetricAffectingSpan getUnderlying();
     method public abstract void updateMeasureState(android.text.TextPaint);
   }
 
@@ -42972,28 +43149,14 @@
   public class TransitionSet extends android.transition.Transition {
     ctor public TransitionSet();
     ctor public TransitionSet(android.content.Context, android.util.AttributeSet);
-    method public android.transition.TransitionSet addListener(android.transition.Transition.TransitionListener);
-    method public android.transition.TransitionSet addTarget(android.view.View);
-    method public android.transition.TransitionSet addTarget(int);
-    method public android.transition.TransitionSet addTarget(java.lang.String);
-    method public android.transition.TransitionSet addTarget(java.lang.Class);
     method public android.transition.TransitionSet addTransition(android.transition.Transition);
     method public void captureEndValues(android.transition.TransitionValues);
     method public void captureStartValues(android.transition.TransitionValues);
-    method public android.transition.TransitionSet clone();
     method public int getOrdering();
     method public android.transition.Transition getTransitionAt(int);
     method public int getTransitionCount();
-    method public android.transition.TransitionSet removeListener(android.transition.Transition.TransitionListener);
-    method public android.transition.TransitionSet removeTarget(int);
-    method public android.transition.TransitionSet removeTarget(android.view.View);
-    method public android.transition.TransitionSet removeTarget(java.lang.Class);
-    method public android.transition.TransitionSet removeTarget(java.lang.String);
     method public android.transition.TransitionSet removeTransition(android.transition.Transition);
-    method public android.transition.TransitionSet setDuration(long);
-    method public android.transition.TransitionSet setInterpolator(android.animation.TimeInterpolator);
     method public android.transition.TransitionSet setOrdering(int);
-    method public android.transition.TransitionSet setStartDelay(long);
     field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
     field public static final int ORDERING_TOGETHER = 0; // 0x0
   }
@@ -43158,9 +43321,6 @@
 
   public class Base64InputStream extends java.io.FilterInputStream {
     ctor public Base64InputStream(java.io.InputStream, int);
-    method public int available();
-    method public void mark(int);
-    method public void reset();
   }
 
   public class Base64OutputStream extends java.io.FilterOutputStream {
@@ -45274,7 +45434,6 @@
     method public android.graphics.Canvas lockCanvas();
     method public android.graphics.Canvas lockCanvas(android.graphics.Rect);
     method protected final void onDraw(android.graphics.Canvas);
-    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setOpaque(boolean);
     method public void setSurfaceTexture(android.graphics.SurfaceTexture);
     method public void setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener);
@@ -46298,7 +46457,6 @@
     method public int getLayoutMode();
     method public android.animation.LayoutTransition getLayoutTransition();
     method public int getNestedScrollAxes();
-    method public android.view.ViewGroupOverlay getOverlay();
     method public int getPersistentDrawingCache();
     method public boolean getTouchscreenBlocksFocus();
     method public int indexOfChild(android.view.View);
@@ -47568,7 +47726,6 @@
     ctor public Animation(android.content.Context, android.util.AttributeSet);
     method protected void applyTransformation(float, android.view.animation.Transformation);
     method public void cancel();
-    method protected android.view.animation.Animation clone() throws java.lang.CloneNotSupportedException;
     method public long computeDurationHint();
     method protected void ensureInterpolator();
     method public int getBackgroundColor();
@@ -47640,7 +47797,6 @@
     ctor public AnimationSet(android.content.Context, android.util.AttributeSet);
     ctor public AnimationSet(boolean);
     method public void addAnimation(android.view.animation.Animation);
-    method protected android.view.animation.AnimationSet clone() throws java.lang.CloneNotSupportedException;
     method public java.util.List<android.view.animation.Animation> getAnimations();
   }
 
@@ -48491,10 +48647,6 @@
   public final deprecated class CookieSyncManager extends android.webkit.WebSyncManager {
     method public static android.webkit.CookieSyncManager createInstance(android.content.Context);
     method public static android.webkit.CookieSyncManager getInstance();
-    method public deprecated void resetSync();
-    method public deprecated void startSync();
-    method public deprecated void stopSync();
-    method public deprecated void sync();
     method protected deprecated void syncFromRamToFlash();
     field protected static final java.lang.String LOGTAG = "websync";
     field protected android.webkit.WebViewDatabase mDataBase;
@@ -49046,7 +49198,6 @@
     method public void setWebChromeClient(android.webkit.WebChromeClient);
     method public static void setWebContentsDebuggingEnabled(boolean);
     method public void setWebViewClient(android.webkit.WebViewClient);
-    method public deprecated boolean shouldDelayChildPressedState();
     method public deprecated boolean showFindDialog(java.lang.String, boolean);
     method public void stopLoading();
     method public void zoomBy(float);
@@ -49170,7 +49321,6 @@
     method public void clearTextFilter();
     method public void deferNotifyDataSetChanged();
     method public void fling(int);
-    method public android.widget.AbsListView.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCacheColorHint();
     method public int getCheckedItemCount();
     method public long[] getCheckedItemIds();
@@ -49337,9 +49487,6 @@
     ctor public ActionMenuView(android.content.Context);
     ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
     method public void dismissPopupMenus();
-    method protected android.widget.ActionMenuView.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public android.view.Menu getMenu();
     method public android.graphics.drawable.Drawable getOverflowIcon();
     method public int getPopupTheme();
@@ -49515,6 +49662,7 @@
     method public void addAll(T...);
     method public void clear();
     method public static android.widget.ArrayAdapter<java.lang.CharSequence> createFromResource(android.content.Context, int, int);
+    method public java.lang.CharSequence[] getAutofillOptions();
     method public android.content.Context getContext();
     method public int getCount();
     method public android.content.res.Resources.Theme getDropDownViewTheme();
@@ -49882,7 +50030,6 @@
     ctor public EditText(android.content.Context, android.util.AttributeSet, int);
     ctor public EditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void extendSelection(int);
-    method public android.text.Editable getText();
     method public void selectAll();
     method public void setSelection(int, int);
     method public void setSelection(int);
@@ -50004,8 +50151,6 @@
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.FrameLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.FrameLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public deprecated boolean getConsiderGoneChildrenWhenMeasuring();
     method public boolean getMeasureAllChildren();
     method protected void onLayout(boolean, int, int, int, int);
@@ -50052,9 +50197,6 @@
     ctor public GridLayout(android.content.Context, android.util.AttributeSet);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.GridLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.GridLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.GridLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getAlignmentMode();
     method public int getColumnCount();
     method public int getOrientation();
@@ -50267,9 +50409,6 @@
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.LinearLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.LinearLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.LinearLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
@@ -50656,8 +50795,6 @@
     method public final synchronized void incrementSecondaryProgressBy(int);
     method public boolean isAnimating();
     method public synchronized boolean isIndeterminate();
-    method protected synchronized void onDraw(android.graphics.Canvas);
-    method protected synchronized void onMeasure(int, int);
     method public void onRestoreInstanceState(android.os.Parcelable);
     method public android.os.Parcelable onSaveInstanceState();
     method public synchronized void setIndeterminate(boolean);
@@ -50713,7 +50850,6 @@
     ctor public RadioGroup(android.content.Context, android.util.AttributeSet);
     method public void check(int);
     method public void clearCheck();
-    method public android.widget.RadioGroup.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCheckedRadioButtonId();
     method public void setOnCheckedChangeListener(android.widget.RadioGroup.OnCheckedChangeListener);
   }
@@ -50756,7 +50892,6 @@
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method public android.widget.RelativeLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getGravity();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setGravity(int);
@@ -51300,7 +51435,6 @@
   public class TableLayout extends android.widget.LinearLayout {
     ctor public TableLayout(android.content.Context);
     ctor public TableLayout(android.content.Context, android.util.AttributeSet);
-    method public android.widget.TableLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public boolean isColumnCollapsed(int);
     method public boolean isColumnShrinkable(int);
     method public boolean isColumnStretchable(int);
@@ -51325,7 +51459,6 @@
   public class TableRow extends android.widget.LinearLayout {
     ctor public TableRow(android.content.Context);
     ctor public TableRow(android.content.Context, android.util.AttributeSet);
-    method public android.widget.TableRow.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public android.view.View getVirtualChildAt(int);
     method public int getVirtualChildCount();
   }
@@ -51667,7 +51800,6 @@
     ctor public ToggleButton(android.content.Context);
     method public java.lang.CharSequence getTextOff();
     method public java.lang.CharSequence getTextOn();
-    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setTextOff(java.lang.CharSequence);
     method public void setTextOn(java.lang.CharSequence);
   }
@@ -51679,9 +51811,6 @@
     ctor public Toolbar(android.content.Context, android.util.AttributeSet, int, int);
     method public void collapseActionView();
     method public void dismissPopupMenus();
-    method protected android.widget.Toolbar.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.Toolbar.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.Toolbar.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getContentInsetEnd();
     method public int getContentInsetEndWithActions();
     method public int getContentInsetLeft();
@@ -51959,6 +52088,8 @@
     field public static final int OP_CONST_CLASS = 28; // 0x1c
     field public static final int OP_CONST_CLASS_JUMBO = 255; // 0xff
     field public static final int OP_CONST_HIGH16 = 21; // 0x15
+    field public static final int OP_CONST_METHOD_HANDLE = 254; // 0xfe
+    field public static final int OP_CONST_METHOD_TYPE = 255; // 0xff
     field public static final int OP_CONST_STRING = 26; // 0x1a
     field public static final int OP_CONST_STRING_JUMBO = 27; // 0x1b
     field public static final int OP_CONST_WIDE = 24; // 0x18
@@ -52203,8 +52334,6 @@
   public class BaseDexClassLoader extends java.lang.ClassLoader {
     ctor public BaseDexClassLoader(java.lang.String, java.io.File, java.lang.String, java.lang.ClassLoader);
     method public java.lang.String findLibrary(java.lang.String);
-    method protected java.util.Enumeration<java.net.URL> findResources(java.lang.String);
-    method protected synchronized java.lang.Package getPackage(java.lang.String);
   }
 
   public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
@@ -52427,10 +52556,6 @@
   public class BufferedInputStream extends java.io.FilterInputStream {
     ctor public BufferedInputStream(java.io.InputStream);
     ctor public BufferedInputStream(java.io.InputStream, int);
-    method public synchronized int available() throws java.io.IOException;
-    method public synchronized int read() throws java.io.IOException;
-    method public synchronized int read(byte[], int, int) throws java.io.IOException;
-    method public synchronized long skip(long) throws java.io.IOException;
     field protected volatile byte[] buf;
     field protected int count;
     field protected int marklimit;
@@ -52441,9 +52566,6 @@
   public class BufferedOutputStream extends java.io.FilterOutputStream {
     ctor public BufferedOutputStream(java.io.OutputStream);
     ctor public BufferedOutputStream(java.io.OutputStream, int);
-    method public synchronized void flush() throws java.io.IOException;
-    method public synchronized void write(int) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
   }
@@ -52469,12 +52591,7 @@
   public class ByteArrayInputStream extends java.io.InputStream {
     ctor public ByteArrayInputStream(byte[]);
     ctor public ByteArrayInputStream(byte[], int, int);
-    method public synchronized int available();
-    method public void mark(int);
     method public synchronized int read();
-    method public synchronized int read(byte[], int, int);
-    method public synchronized void reset();
-    method public synchronized long skip(long);
     field protected byte[] buf;
     field protected int count;
     field protected int mark;
@@ -52487,11 +52604,9 @@
     method public synchronized void reset();
     method public synchronized int size();
     method public synchronized byte[] toByteArray();
-    method public synchronized java.lang.String toString();
     method public synchronized java.lang.String toString(java.lang.String) throws java.io.UnsupportedEncodingException;
     method public deprecated synchronized java.lang.String toString(int);
     method public synchronized void write(int);
-    method public synchronized void write(byte[], int, int);
     method public synchronized void writeTo(java.io.OutputStream) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
@@ -52511,17 +52626,12 @@
   public class CharArrayWriter extends java.io.Writer {
     ctor public CharArrayWriter();
     ctor public CharArrayWriter(int);
-    method public java.io.CharArrayWriter append(java.lang.CharSequence);
-    method public java.io.CharArrayWriter append(java.lang.CharSequence, int, int);
-    method public java.io.CharArrayWriter append(char);
     method public void close();
     method public void flush();
     method public void reset();
     method public int size();
     method public char[] toCharArray();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(java.lang.String, int, int);
     method public void writeTo(java.io.Writer) throws java.io.IOException;
     field protected char[] buf;
     field protected int count;
@@ -52608,8 +52718,6 @@
   public class DataOutputStream extends java.io.FilterOutputStream implements java.io.DataOutput {
     ctor public DataOutputStream(java.io.OutputStream);
     method public final int size();
-    method public synchronized void write(int) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     method public final void writeBoolean(boolean) throws java.io.IOException;
     method public final void writeByte(int) throws java.io.IOException;
     method public final void writeBytes(java.lang.String) throws java.io.IOException;
@@ -52709,7 +52817,6 @@
     ctor public FileInputStream(java.lang.String) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.FileDescriptor);
-    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public int read() throws java.io.IOException;
@@ -52726,7 +52833,6 @@
     ctor public FileOutputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.File, boolean) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.FileDescriptor);
-    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
@@ -52840,8 +52946,6 @@
   public deprecated class LineNumberInputStream extends java.io.FilterInputStream {
     ctor public LineNumberInputStream(java.io.InputStream);
     method public int getLineNumber();
-    method public void mark(int);
-    method public void reset() throws java.io.IOException;
     method public void setLineNumber(int);
   }
 
@@ -53071,10 +53175,8 @@
     ctor public PipedInputStream(java.io.PipedOutputStream, int) throws java.io.IOException;
     ctor public PipedInputStream();
     ctor public PipedInputStream(int);
-    method public synchronized int available() throws java.io.IOException;
     method public void connect(java.io.PipedOutputStream) throws java.io.IOException;
     method public synchronized int read() throws java.io.IOException;
-    method public synchronized int read(byte[], int, int) throws java.io.IOException;
     method protected synchronized void receive(int) throws java.io.IOException;
     field protected static final int PIPE_SIZE = 1024; // 0x400
     field protected byte[] buffer;
@@ -53086,7 +53188,6 @@
     ctor public PipedOutputStream(java.io.PipedInputStream) throws java.io.IOException;
     ctor public PipedOutputStream();
     method public synchronized void connect(java.io.PipedInputStream) throws java.io.IOException;
-    method public synchronized void flush() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
   }
 
@@ -53097,9 +53198,7 @@
     ctor public PipedReader(int);
     method public void close() throws java.io.IOException;
     method public void connect(java.io.PipedWriter) throws java.io.IOException;
-    method public synchronized int read() throws java.io.IOException;
     method public synchronized int read(char[], int, int) throws java.io.IOException;
-    method public synchronized boolean ready() throws java.io.IOException;
   }
 
   public class PipedWriter extends java.io.Writer {
@@ -53124,8 +53223,6 @@
     method public java.io.PrintStream append(char);
     method public boolean checkError();
     method protected void clearError();
-    method public void close();
-    method public void flush();
     method public java.io.PrintStream format(java.lang.String, java.lang.Object...);
     method public java.io.PrintStream format(java.util.Locale, java.lang.String, java.lang.Object...);
     method public void print(boolean);
@@ -53150,8 +53247,6 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
-    method public void write(int);
-    method public void write(byte[], int, int);
   }
 
   public class PrintWriter extends java.io.Writer {
@@ -53163,9 +53258,6 @@
     ctor public PrintWriter(java.lang.String, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
     ctor public PrintWriter(java.io.File) throws java.io.FileNotFoundException;
     ctor public PrintWriter(java.io.File, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
-    method public java.io.PrintWriter append(java.lang.CharSequence);
-    method public java.io.PrintWriter append(java.lang.CharSequence, int, int);
-    method public java.io.PrintWriter append(char);
     method public boolean checkError();
     method protected void clearError();
     method public void close();
@@ -53194,18 +53286,13 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(char[]);
-    method public void write(java.lang.String, int, int);
-    method public void write(java.lang.String);
     field protected java.io.Writer out;
   }
 
   public class PushbackInputStream extends java.io.FilterInputStream {
     ctor public PushbackInputStream(java.io.InputStream, int);
     ctor public PushbackInputStream(java.io.InputStream);
-    method public synchronized void close() throws java.io.IOException;
     method public void unread(int) throws java.io.IOException;
     method public void unread(byte[], int, int) throws java.io.IOException;
     method public void unread(byte[]) throws java.io.IOException;
@@ -53329,11 +53416,7 @@
 
   public deprecated class StringBufferInputStream extends java.io.InputStream {
     ctor public StringBufferInputStream(java.lang.String);
-    method public synchronized int available();
     method public synchronized int read();
-    method public synchronized int read(byte[], int, int);
-    method public synchronized void reset();
-    method public synchronized long skip(long);
     field protected java.lang.String buffer;
     field protected int count;
     field protected int pos;
@@ -53348,16 +53431,10 @@
   public class StringWriter extends java.io.Writer {
     ctor public StringWriter();
     ctor public StringWriter(int);
-    method public java.io.StringWriter append(java.lang.CharSequence);
-    method public java.io.StringWriter append(java.lang.CharSequence, int, int);
-    method public java.io.StringWriter append(char);
     method public void close() throws java.io.IOException;
     method public void flush();
     method public java.lang.StringBuffer getBuffer();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(java.lang.String);
-    method public void write(java.lang.String, int, int);
   }
 
   public class SyncFailedException extends java.io.IOException {
@@ -53372,7 +53449,6 @@
   public class UncheckedIOException extends java.lang.RuntimeException {
     ctor public UncheckedIOException(java.lang.String, java.io.IOException);
     ctor public UncheckedIOException(java.io.IOException);
-    method public java.io.IOException getCause();
   }
 
   public class UnsupportedEncodingException extends java.io.IOException {
@@ -53382,7 +53458,6 @@
 
   public class WriteAbortedException extends java.io.ObjectStreamException {
     ctor public WriteAbortedException(java.lang.String, java.lang.Exception);
-    method public java.lang.Throwable getCause();
     field public java.lang.Exception detail;
   }
 
@@ -54150,7 +54225,6 @@
     ctor public ClassNotFoundException();
     ctor public ClassNotFoundException(java.lang.String);
     ctor public ClassNotFoundException(java.lang.String, java.lang.Throwable);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -54255,7 +54329,6 @@
     ctor public ExceptionInInitializerError();
     ctor public ExceptionInInitializerError(java.lang.Throwable);
     ctor public ExceptionInInitializerError(java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -55043,16 +55116,8 @@
     method public synchronized java.lang.StringBuffer append(float);
     method public synchronized java.lang.StringBuffer append(double);
     method public synchronized java.lang.StringBuffer appendCodePoint(int);
-    method public synchronized int capacity();
-    method public synchronized char charAt(int);
-    method public synchronized int codePointAt(int);
-    method public synchronized int codePointBefore(int);
-    method public synchronized int codePointCount(int, int);
     method public synchronized java.lang.StringBuffer delete(int, int);
     method public synchronized java.lang.StringBuffer deleteCharAt(int);
-    method public synchronized void ensureCapacity(int);
-    method public synchronized void getChars(int, int, char[], int);
-    method public synchronized int indexOf(java.lang.String, int);
     method public synchronized java.lang.StringBuffer insert(int, char[], int, int);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.Object);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.String);
@@ -55065,18 +55130,9 @@
     method public java.lang.StringBuffer insert(int, long);
     method public java.lang.StringBuffer insert(int, float);
     method public java.lang.StringBuffer insert(int, double);
-    method public synchronized int lastIndexOf(java.lang.String, int);
-    method public synchronized int length();
-    method public synchronized int offsetByCodePoints(int, int);
     method public synchronized java.lang.StringBuffer replace(int, int, java.lang.String);
     method public synchronized java.lang.StringBuffer reverse();
-    method public synchronized void setCharAt(int, char);
-    method public synchronized void setLength(int);
-    method public synchronized java.lang.CharSequence subSequence(int, int);
-    method public synchronized java.lang.String substring(int);
-    method public synchronized java.lang.String substring(int, int);
     method public synchronized java.lang.String toString();
-    method public synchronized void trimToSize();
   }
 
   public final class StringBuilder extends java.lang.AbstractStringBuilder implements java.lang.CharSequence java.io.Serializable {
@@ -55731,7 +55787,6 @@
     ctor protected InvocationTargetException();
     ctor public InvocationTargetException(java.lang.Throwable);
     ctor public InvocationTargetException(java.lang.Throwable, java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getTargetException();
   }
 
@@ -55847,7 +55902,6 @@
   public class UndeclaredThrowableException extends java.lang.RuntimeException {
     ctor public UndeclaredThrowableException(java.lang.Throwable);
     ctor public UndeclaredThrowableException(java.lang.Throwable, java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getUndeclaredThrowable();
   }
 
@@ -56745,7 +56799,6 @@
     method public java.lang.String getQuery();
     method public java.lang.String getRef();
     method public java.lang.String getUserInfo();
-    method public synchronized int hashCode();
     method public java.net.URLConnection openConnection() throws java.io.IOException;
     method public java.net.URLConnection openConnection(java.net.Proxy) throws java.io.IOException;
     method public final java.io.InputStream openStream() throws java.io.IOException;
@@ -56975,6 +57028,7 @@
     method public final int arrayOffset();
     method public abstract java.nio.CharBuffer asReadOnlyBuffer();
     method public final char charAt(int);
+    method public java.util.stream.IntStream chars();
     method public abstract java.nio.CharBuffer compact();
     method public int compareTo(java.nio.CharBuffer);
     method public abstract java.nio.CharBuffer duplicate();
@@ -57831,7 +57885,6 @@
 
   public final class DirectoryIteratorException extends java.util.ConcurrentModificationException {
     ctor public DirectoryIteratorException(java.io.IOException);
-    method public java.io.IOException getCause();
   }
 
   public class DirectoryNotEmptyException extends java.nio.file.FileSystemException {
@@ -58797,11 +58850,9 @@
   public static class KeyStore.PasswordProtection implements javax.security.auth.Destroyable java.security.KeyStore.ProtectionParameter {
     ctor public KeyStore.PasswordProtection(char[]);
     ctor public KeyStore.PasswordProtection(char[], java.lang.String, java.security.spec.AlgorithmParameterSpec);
-    method public synchronized void destroy() throws javax.security.auth.DestroyFailedException;
     method public synchronized char[] getPassword();
     method public java.lang.String getProtectionAlgorithm();
     method public java.security.spec.AlgorithmParameterSpec getProtectionParameters();
-    method public synchronized boolean isDestroyed();
   }
 
   public static final class KeyStore.PrivateKeyEntry implements java.security.KeyStore.Entry {
@@ -58981,7 +59032,6 @@
 
   public class PrivilegedActionException extends java.lang.Exception {
     ctor public PrivilegedActionException(java.lang.Exception);
-    method public java.lang.Throwable getCause();
     method public java.lang.Exception getException();
   }
 
@@ -59004,30 +59054,22 @@
     method public synchronized java.lang.Object compute(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfAbsent(java.lang.Object, java.util.function.Function<? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfPresent(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
-    method public java.util.Enumeration<java.lang.Object> elements();
-    method public synchronized java.util.Set<java.util.Map.Entry<java.lang.Object, java.lang.Object>> entrySet();
     method public synchronized void forEach(java.util.function.BiConsumer<? super java.lang.Object, ? super java.lang.Object>);
-    method public java.lang.Object get(java.lang.Object);
     method public java.lang.String getInfo();
     method public java.lang.String getName();
     method public synchronized java.lang.Object getOrDefault(java.lang.Object, java.lang.Object);
     method public synchronized java.security.Provider.Service getService(java.lang.String, java.lang.String);
     method public synchronized java.util.Set<java.security.Provider.Service> getServices();
     method public double getVersion();
-    method public java.util.Set<java.lang.Object> keySet();
-    method public java.util.Enumeration<java.lang.Object> keys();
     method public synchronized java.lang.Object merge(java.lang.Object, java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object put(java.lang.Object, java.lang.Object);
     method public synchronized void putAll(java.util.Map<?, ?>);
     method public synchronized java.lang.Object putIfAbsent(java.lang.Object, java.lang.Object);
     method protected synchronized void putService(java.security.Provider.Service);
-    method public synchronized java.lang.Object remove(java.lang.Object);
     method protected synchronized void removeService(java.security.Provider.Service);
     method public synchronized boolean replace(java.lang.Object, java.lang.Object, java.lang.Object);
     method public synchronized java.lang.Object replace(java.lang.Object, java.lang.Object);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
-    method public java.lang.String toString();
-    method public java.util.Collection<java.lang.Object> values();
   }
 
   public static class Provider.Service {
@@ -59073,9 +59115,7 @@
     method public final java.security.Provider getProvider();
     method public static byte[] getSeed(int);
     method protected final int next(int);
-    method public synchronized void nextBytes(byte[]);
     method public synchronized void setSeed(byte[]);
-    method public void setSeed(long);
   }
 
   public abstract class SecureRandomSpi implements java.io.Serializable {
@@ -59622,7 +59662,6 @@
 
   public abstract class PKIXRevocationChecker extends java.security.cert.PKIXCertPathChecker {
     ctor protected PKIXRevocationChecker();
-    method public java.security.cert.PKIXRevocationChecker clone();
     method public java.util.List<java.security.cert.Extension> getOcspExtensions();
     method public java.net.URI getOcspResponder();
     method public java.security.cert.X509Certificate getOcspResponderCert();
@@ -61875,6 +61914,7 @@
   public final class DayOfWeek extends java.lang.Enum implements java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public static java.time.DayOfWeek from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -61882,6 +61922,8 @@
     method public java.time.DayOfWeek minus(long);
     method public static java.time.DayOfWeek of(int);
     method public java.time.DayOfWeek plus(long);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.DayOfWeek valueOf(java.lang.String);
     method public static final java.time.DayOfWeek[] values();
     enum_constant public static final java.time.DayOfWeek FRIDAY;
@@ -61957,8 +61999,6 @@
     method public boolean isBefore(java.time.Instant);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.Instant minus(java.time.temporal.TemporalAmount);
-    method public java.time.Instant minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant minusMillis(long);
     method public java.time.Instant minusNanos(long);
     method public java.time.Instant minusSeconds(long);
@@ -61968,7 +62008,6 @@
     method public static java.time.Instant ofEpochSecond(long);
     method public static java.time.Instant ofEpochSecond(long, long);
     method public static java.time.Instant parse(java.lang.CharSequence);
-    method public java.time.Instant plus(java.time.temporal.TemporalAmount);
     method public java.time.Instant plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant plusMillis(long);
     method public java.time.Instant plusNanos(long);
@@ -61976,7 +62015,6 @@
     method public long toEpochMilli();
     method public java.time.Instant truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Instant with(java.time.temporal.TemporalAdjuster);
     method public java.time.Instant with(java.time.temporal.TemporalField, long);
     field public static final java.time.Instant EPOCH;
     field public static final java.time.Instant MAX;
@@ -61986,7 +62024,6 @@
   public final class LocalDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
     method public java.time.LocalDateTime atStartOfDay();
     method public java.time.ZonedDateTime atStartOfDay(java.time.ZoneId);
-    method public java.time.LocalDateTime atTime(java.time.LocalTime);
     method public java.time.LocalDateTime atTime(int, int);
     method public java.time.LocalDateTime atTime(int, int, int);
     method public java.time.LocalDateTime atTime(int, int, int, int);
@@ -62001,8 +62038,6 @@
     method public int getMonthValue();
     method public int getYear();
     method public int lengthOfMonth();
-    method public java.time.LocalDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDate minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate minusDays(long);
     method public java.time.LocalDate minusMonths(long);
     method public java.time.LocalDate minusWeeks(long);
@@ -62016,16 +62051,12 @@
     method public static java.time.LocalDate ofYearDay(int, int);
     method public static java.time.LocalDate parse(java.lang.CharSequence);
     method public static java.time.LocalDate parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate plusDays(long);
     method public java.time.LocalDate plusMonths(long);
     method public java.time.LocalDate plusWeeks(long);
     method public java.time.LocalDate plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public java.time.Period until(java.time.chrono.ChronoLocalDate);
-    method public java.time.LocalDate with(java.time.temporal.TemporalAdjuster);
-    method public java.time.LocalDate with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDate withDayOfMonth(int);
     method public java.time.LocalDate withDayOfYear(int);
     method public java.time.LocalDate withMonth(int);
@@ -62050,8 +62081,6 @@
     method public int getSecond();
     method public int getYear();
     method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.LocalDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime minusDays(long);
     method public java.time.LocalDateTime minusHours(long);
     method public java.time.LocalDateTime minusMinutes(long);
@@ -62074,7 +62103,6 @@
     method public static java.time.LocalDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime plusDays(long);
     method public java.time.LocalDateTime plusHours(long);
@@ -62088,7 +62116,6 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.LocalDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.LocalDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDateTime withDayOfMonth(int);
     method public java.time.LocalDateTime withDayOfYear(int);
@@ -62118,8 +62145,6 @@
     method public boolean isBefore(java.time.LocalTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime minusHours(long);
     method public java.time.LocalTime minusMinutes(long);
     method public java.time.LocalTime minusNanos(long);
@@ -62134,7 +62159,6 @@
     method public static java.time.LocalTime ofSecondOfDay(long);
     method public static java.time.LocalTime parse(java.lang.CharSequence);
     method public static java.time.LocalTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime plusHours(long);
     method public java.time.LocalTime plusMinutes(long);
@@ -62144,7 +62168,6 @@
     method public int toSecondOfDay();
     method public java.time.LocalTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalTime withHour(int);
     method public java.time.LocalTime withMinute(int);
@@ -62161,6 +62184,7 @@
     method public int firstDayOfYear(boolean);
     method public java.time.Month firstMonthOfQuarter();
     method public static java.time.Month from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -62171,6 +62195,8 @@
     method public java.time.Month minus(long);
     method public static java.time.Month of(int);
     method public java.time.Month plus(long);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.Month valueOf(java.lang.String);
     method public static final java.time.Month[] values();
     enum_constant public static final java.time.Month APRIL;
@@ -62237,8 +62263,6 @@
     method public boolean isEqual(java.time.OffsetDateTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime minusDays(long);
     method public java.time.OffsetDateTime minusHours(long);
     method public java.time.OffsetDateTime minusMinutes(long);
@@ -62256,7 +62280,6 @@
     method public static java.time.OffsetDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.OffsetDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime plusDays(long);
     method public java.time.OffsetDateTime plusHours(long);
@@ -62276,7 +62299,6 @@
     method public java.time.ZonedDateTime toZonedDateTime();
     method public java.time.OffsetDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetDateTime withDayOfMonth(int);
     method public java.time.OffsetDateTime withDayOfYear(int);
@@ -62309,8 +62331,6 @@
     method public boolean isEqual(java.time.OffsetTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime minusHours(long);
     method public java.time.OffsetTime minusMinutes(long);
     method public java.time.OffsetTime minusNanos(long);
@@ -62323,7 +62343,6 @@
     method public static java.time.OffsetTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetTime parse(java.lang.CharSequence);
     method public static java.time.OffsetTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.OffsetTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime plusHours(long);
     method public java.time.OffsetTime plusMinutes(long);
@@ -62332,7 +62351,6 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.OffsetTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetTime withHour(int);
     method public java.time.OffsetTime withMinute(int);
@@ -62359,7 +62377,6 @@
     method public java.time.Period minusMonths(long);
     method public java.time.Period minusYears(long);
     method public java.time.Period multipliedBy(int);
-    method public java.time.Period negated();
     method public java.time.Period normalized();
     method public static java.time.Period of(int, int, int);
     method public static java.time.Period ofDays(int);
@@ -62398,8 +62415,6 @@
     method public boolean isSupported(java.time.temporal.TemporalUnit);
     method public boolean isValidMonthDay(java.time.MonthDay);
     method public int length();
-    method public java.time.Year minus(java.time.temporal.TemporalAmount);
-    method public java.time.Year minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year minusYears(long);
     method public static java.time.Year now();
     method public static java.time.Year now(java.time.ZoneId);
@@ -62407,11 +62422,9 @@
     method public static java.time.Year of(int);
     method public static java.time.Year parse(java.lang.CharSequence);
     method public static java.time.Year parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.Year plus(java.time.temporal.TemporalAmount);
     method public java.time.Year plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Year with(java.time.temporal.TemporalAdjuster);
     method public java.time.Year with(java.time.temporal.TemporalField, long);
     field public static final int MAX_VALUE = 999999999; // 0x3b9ac9ff
     field public static final int MIN_VALUE = -999999999; // 0xc4653601
@@ -62436,8 +62449,6 @@
     method public boolean isValidDay(int);
     method public int lengthOfMonth();
     method public int lengthOfYear();
-    method public java.time.YearMonth minus(java.time.temporal.TemporalAmount);
-    method public java.time.YearMonth minus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth minusMonths(long);
     method public java.time.YearMonth minusYears(long);
     method public static java.time.YearMonth now();
@@ -62447,12 +62458,10 @@
     method public static java.time.YearMonth of(int, int);
     method public static java.time.YearMonth parse(java.lang.CharSequence);
     method public static java.time.YearMonth parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.YearMonth plus(java.time.temporal.TemporalAmount);
     method public java.time.YearMonth plus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth plusMonths(long);
     method public java.time.YearMonth plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.YearMonth with(java.time.temporal.TemporalAdjuster);
     method public java.time.YearMonth with(java.time.temporal.TemporalField, long);
     method public java.time.YearMonth withMonth(int);
     method public java.time.YearMonth withYear(int);
@@ -62476,6 +62485,7 @@
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public int compareTo(java.time.ZoneOffset);
     method public static java.time.ZoneOffset from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getId();
     method public long getLong(java.time.temporal.TemporalField);
     method public java.time.zone.ZoneRules getRules();
@@ -62486,6 +62496,8 @@
     method public static java.time.ZoneOffset ofHoursMinutes(int, int);
     method public static java.time.ZoneOffset ofHoursMinutesSeconds(int, int, int);
     method public static java.time.ZoneOffset ofTotalSeconds(int);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     field public static final java.time.ZoneOffset MAX;
     field public static final java.time.ZoneOffset MIN;
     field public static final java.time.ZoneOffset UTC;
@@ -62506,8 +62518,6 @@
     method public int getYear();
     method public java.time.ZoneId getZone();
     method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.ZonedDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.ZonedDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime minusDays(long);
     method public java.time.ZonedDateTime minusHours(long);
     method public java.time.ZonedDateTime minusMinutes(long);
@@ -62528,7 +62538,6 @@
     method public static java.time.ZonedDateTime ofStrict(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneId);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.ZonedDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.ZonedDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime plusDays(long);
     method public java.time.ZonedDateTime plusHours(long);
@@ -62538,12 +62547,10 @@
     method public java.time.ZonedDateTime plusSeconds(long);
     method public java.time.ZonedDateTime plusWeeks(long);
     method public java.time.ZonedDateTime plusYears(long);
-    method public java.time.LocalDate toLocalDate();
     method public java.time.LocalDateTime toLocalDateTime();
     method public java.time.OffsetDateTime toOffsetDateTime();
     method public java.time.ZonedDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.ZonedDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.ZonedDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.ZonedDateTime withDayOfMonth(int);
     method public java.time.ZonedDateTime withDayOfYear(int);
@@ -62588,27 +62595,17 @@
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
     method public abstract int lengthOfMonth();
     method public default int lengthOfYear();
-    method public default java.time.chrono.ChronoLocalDate minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDate minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDate plus(java.time.temporal.TemporalAmount);
     method public default java.time.chrono.ChronoLocalDate plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDate> timeLineOrder();
     method public default long toEpochDay();
     method public abstract java.lang.String toString();
     method public abstract long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public abstract java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalAdjuster);
     method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalField, long);
   }
 
    abstract class ChronoLocalDateImpl<D extends java.time.chrono.ChronoLocalDate> implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public D minus(java.time.temporal.TemporalAmount);
-    method public D minus(long, java.time.temporal.TemporalUnit);
-    method public D plus(java.time.temporal.TemporalAmount);
-    method public D plus(long, java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public D with(java.time.temporal.TemporalAdjuster);
-    method public D with(java.time.temporal.TemporalField, long);
   }
 
   public abstract interface ChronoLocalDateTime<D extends java.time.chrono.ChronoLocalDate> implements java.lang.Comparable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
@@ -62625,9 +62622,6 @@
     method public default boolean isEqual(java.time.chrono.ChronoLocalDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDateTime<D> minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDateTime<D> minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDateTime<?>> timeLineOrder();
     method public default long toEpochSecond(java.time.ZoneOffset);
@@ -62635,7 +62629,6 @@
     method public abstract D toLocalDate();
     method public abstract java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
-    method public default java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalField, long);
   }
 
@@ -62673,9 +62666,6 @@
     method public default boolean isEqual(java.time.chrono.ChronoZonedDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoZonedDateTime<D> minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoZonedDateTime<D> minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoZonedDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoZonedDateTime<?>> timeLineOrder();
     method public default long toEpochSecond();
@@ -62684,7 +62674,6 @@
     method public abstract java.time.chrono.ChronoLocalDateTime<D> toLocalDateTime();
     method public default java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
-    method public default java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalField, long);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withEarlierOffsetAtOverlap();
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withLaterOffsetAtOverlap();
@@ -62751,7 +62740,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.HijrahDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.HijrahDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.HijrahChronology INSTANCE;
@@ -62763,24 +62751,23 @@
     method public java.time.chrono.HijrahChronology getChronology();
     method public java.time.chrono.HijrahEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
+    method public boolean isLeapYear();
     method public int lengthOfMonth();
-    method public java.time.chrono.HijrahDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.HijrahDate minus(long, java.time.temporal.TemporalUnit);
+    method public int lengthOfYear();
     method public static java.time.chrono.HijrahDate now();
     method public static java.time.chrono.HijrahDate now(java.time.ZoneId);
     method public static java.time.chrono.HijrahDate now(java.time.Clock);
     method public static java.time.chrono.HijrahDate of(int, int, int);
-    method public java.time.chrono.HijrahDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.HijrahDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalAdjuster);
     method public java.time.chrono.HijrahDate withVariant(java.time.chrono.HijrahChronology);
   }
 
   public final class HijrahEra extends java.lang.Enum implements java.time.chrono.Era {
     method public int getValue();
     method public static java.time.chrono.HijrahEra of(int);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.chrono.HijrahEra valueOf(java.lang.String);
     method public static final java.time.chrono.HijrahEra[] values();
     enum_constant public static final java.time.chrono.HijrahEra AH;
@@ -62805,7 +62792,6 @@
     method public java.time.Period period(int, int, int);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.LocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.ZonedDateTime zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.ZonedDateTime zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.IsoChronology INSTANCE;
@@ -62838,7 +62824,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.JapaneseDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.JapaneseDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.JapaneseChronology INSTANCE;
@@ -62850,19 +62835,17 @@
     method public java.time.chrono.JapaneseChronology getChronology();
     method public java.time.chrono.JapaneseEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
+    method public boolean isSupported(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.JapaneseDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.JapaneseDate minus(long, java.time.temporal.TemporalUnit);
+    method public int lengthOfYear();
     method public static java.time.chrono.JapaneseDate now();
     method public static java.time.chrono.JapaneseDate now(java.time.ZoneId);
     method public static java.time.chrono.JapaneseDate now(java.time.Clock);
     method public static java.time.chrono.JapaneseDate of(java.time.chrono.JapaneseEra, int, int, int);
     method public static java.time.chrono.JapaneseDate of(int, int, int);
-    method public java.time.chrono.JapaneseDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.JapaneseDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class JapaneseEra implements java.time.chrono.Era java.io.Serializable {
@@ -62894,7 +62877,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.MinguoDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.MinguoDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.MinguoChronology INSTANCE;
@@ -62907,17 +62889,13 @@
     method public java.time.chrono.MinguoEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.MinguoDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.MinguoDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.MinguoDate now();
     method public static java.time.chrono.MinguoDate now(java.time.ZoneId);
     method public static java.time.chrono.MinguoDate now(java.time.Clock);
     method public static java.time.chrono.MinguoDate of(int, int, int);
-    method public java.time.chrono.MinguoDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.MinguoDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class MinguoEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -62947,7 +62925,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.ThaiBuddhistDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.ThaiBuddhistDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.ThaiBuddhistChronology INSTANCE;
@@ -62960,17 +62937,13 @@
     method public java.time.chrono.ThaiBuddhistEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.ThaiBuddhistDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ThaiBuddhistDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.ThaiBuddhistDate now();
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.ZoneId);
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.Clock);
     method public static java.time.chrono.ThaiBuddhistDate of(int, int, int);
-    method public java.time.chrono.ThaiBuddhistDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ThaiBuddhistDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class ThaiBuddhistEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -63149,6 +63122,7 @@
     method public int checkValidIntValue(long);
     method public long checkValidValue(long);
     method public java.time.temporal.TemporalUnit getBaseUnit();
+    method public java.lang.String getDisplayName(java.util.Locale);
     method public long getFrom(java.time.temporal.TemporalAccessor);
     method public java.time.temporal.TemporalUnit getRangeUnit();
     method public boolean isDateBased();
@@ -63196,6 +63170,7 @@
     method public java.time.Duration getDuration();
     method public boolean isDateBased();
     method public boolean isDurationEstimated();
+    method public boolean isSupportedBy(java.time.temporal.Temporal);
     method public boolean isTimeBased();
     method public static java.time.temporal.ChronoUnit valueOf(java.lang.String);
     method public static final java.time.temporal.ChronoUnit[] values();
@@ -63535,6 +63510,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ArrayList<E> extends java.util.AbstractList implements java.lang.Cloneable java.util.List java.util.RandomAccess java.io.Serializable {
@@ -63545,7 +63521,11 @@
     method public void ensureCapacity(int);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public E get(int);
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
+    method public void replaceAll(java.util.function.UnaryOperator<E>);
     method public int size();
+    method public void sort(java.util.Comparator<? super E>);
+    method public java.util.Spliterator<E> spliterator();
     method public void trimToSize();
   }
 
@@ -63916,7 +63896,6 @@
     method public default boolean removeIf(java.util.function.Predicate<? super E>);
     method public abstract boolean retainAll(java.util.Collection<?>);
     method public abstract int size();
-    method public default java.util.Spliterator<E> spliterator();
     method public default java.util.stream.Stream<E> stream();
     method public abstract java.lang.Object[] toArray();
     method public abstract <T> T[] toArray(T[]);
@@ -64257,7 +64236,18 @@
     ctor public HashMap();
     ctor public HashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
+    method public V putIfAbsent(K, V);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class HashSet<E> extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set {
@@ -64268,6 +64258,7 @@
     method public java.lang.Object clone();
     method public java.util.Iterator<E> iterator();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class Hashtable<K, V> extends java.util.Dictionary implements java.lang.Cloneable java.util.Map java.io.Serializable {
@@ -64285,11 +64276,9 @@
     method public boolean containsValue(java.lang.Object);
     method public synchronized java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
-    method public synchronized boolean equals(java.lang.Object);
     method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public synchronized V get(java.lang.Object);
     method public synchronized V getOrDefault(java.lang.Object, V);
-    method public synchronized int hashCode();
     method public synchronized boolean isEmpty();
     method public java.util.Set<K> keySet();
     method public synchronized java.util.Enumeration<K> keys();
@@ -64304,7 +64293,6 @@
     method public synchronized V replace(K, V);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public synchronized int size();
-    method public synchronized java.lang.String toString();
     method public java.util.Collection<V> values();
   }
 
@@ -64314,6 +64302,8 @@
     ctor public IdentityHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class IllegalFormatCodePointException extends java.util.IllegalFormatException {
@@ -64424,6 +64414,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface List<E> implements java.util.Collection {
@@ -65046,7 +65037,6 @@
     ctor public SimpleTimeZone(int, java.lang.String, int, int, int, int, int, int, int, int, int, int, int);
     method public int getOffset(int, int, int, int, int, int);
     method public int getRawOffset();
-    method public synchronized int hashCode();
     method public boolean inDaylightTime(java.util.Date);
     method public void setDSTSavings(int);
     method public void setEndRule(int, int, int, int);
@@ -65319,6 +65309,7 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public java.util.NavigableMap<K, V> headMap(K, boolean);
     method public java.util.SortedMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
@@ -65330,6 +65321,9 @@
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.SortedMap<K, V> subMap(K, K);
     method public java.util.NavigableMap<K, V> tailMap(K, boolean);
@@ -65357,6 +65351,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.SortedSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -65393,49 +65388,30 @@
     ctor public Vector(int);
     ctor public Vector();
     ctor public Vector(java.util.Collection<? extends E>);
-    method public synchronized boolean add(E);
-    method public synchronized boolean addAll(java.util.Collection<? extends E>);
-    method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
     method public synchronized void addElement(E);
     method public synchronized int capacity();
     method public synchronized java.lang.Object clone();
-    method public synchronized boolean containsAll(java.util.Collection<?>);
     method public synchronized void copyInto(java.lang.Object[]);
     method public synchronized E elementAt(int);
     method public java.util.Enumeration<E> elements();
     method public synchronized void ensureCapacity(int);
-    method public synchronized boolean equals(java.lang.Object);
     method public synchronized E firstElement();
     method public synchronized void forEach(java.util.function.Consumer<? super E>);
     method public synchronized E get(int);
-    method public synchronized int hashCode();
     method public synchronized int indexOf(java.lang.Object, int);
     method public synchronized void insertElementAt(E, int);
-    method public synchronized boolean isEmpty();
-    method public synchronized java.util.Iterator<E> iterator();
     method public synchronized E lastElement();
-    method public synchronized int lastIndexOf(java.lang.Object);
     method public synchronized int lastIndexOf(java.lang.Object, int);
-    method public synchronized java.util.ListIterator<E> listIterator(int);
-    method public synchronized java.util.ListIterator<E> listIterator();
-    method public synchronized E remove(int);
-    method public synchronized boolean removeAll(java.util.Collection<?>);
     method public synchronized void removeAllElements();
     method public synchronized boolean removeElement(java.lang.Object);
     method public synchronized void removeElementAt(int);
     method public synchronized boolean removeIf(java.util.function.Predicate<? super E>);
-    method protected synchronized void removeRange(int, int);
     method public synchronized void replaceAll(java.util.function.UnaryOperator<E>);
-    method public synchronized boolean retainAll(java.util.Collection<?>);
-    method public synchronized E set(int, E);
     method public synchronized void setElementAt(E, int);
     method public synchronized void setSize(int);
     method public synchronized int size();
     method public synchronized void sort(java.util.Comparator<? super E>);
-    method public synchronized java.util.List<E> subList(int, int);
-    method public synchronized java.lang.Object[] toArray();
-    method public synchronized <T> T[] toArray(T[]);
-    method public synchronized java.lang.String toString();
+    method public java.util.Spliterator<E> spliterator();
     method public synchronized void trimToSize();
     field protected int capacityIncrement;
     field protected int elementCount;
@@ -65448,6 +65424,8 @@
     ctor public WeakHashMap();
     ctor public WeakHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
 }
@@ -65482,6 +65460,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -65672,9 +65651,13 @@
     ctor public ConcurrentHashMap(java.util.Map<? extends K, ? extends V>);
     ctor public ConcurrentHashMap(int, float);
     ctor public ConcurrentHashMap(int, float, int);
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public boolean contains(java.lang.Object);
     method public java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public void forEach(long, java.util.function.BiConsumer<? super K, ? super V>);
     method public <U> void forEach(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.Consumer<? super U>);
     method public void forEachEntry(long, java.util.function.Consumer<? super java.util.Map.Entry<K, V>>);
@@ -65683,11 +65666,14 @@
     method public <U> void forEachKey(long, java.util.function.Function<? super K, ? extends U>, java.util.function.Consumer<? super U>);
     method public void forEachValue(long, java.util.function.Consumer<? super V>);
     method public <U> void forEachValue(long, java.util.function.Function<? super V, ? extends U>, java.util.function.Consumer<? super U>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentHashMap.KeySetView<K, V> keySet(V);
     method public java.util.Enumeration<K> keys();
     method public long mappingCount();
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet();
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet(int);
+    method public V putIfAbsent(K, V);
     method public <U> U reduce(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
     method public java.util.Map.Entry<K, V> reduceEntries(long, java.util.function.BiFunction<java.util.Map.Entry<K, V>, java.util.Map.Entry<K, V>, ? extends java.util.Map.Entry<K, V>>);
     method public <U> U reduceEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
@@ -65707,6 +65693,10 @@
     method public double reduceValuesToDouble(long, java.util.function.ToDoubleFunction<? super V>, double, java.util.function.DoubleBinaryOperator);
     method public int reduceValuesToInt(long, java.util.function.ToIntFunction<? super V>, int, java.util.function.IntBinaryOperator);
     method public long reduceValuesToLong(long, java.util.function.ToLongFunction<? super V>, long, java.util.function.LongBinaryOperator);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public <U> U search(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>);
     method public <U> U searchEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>);
     method public <U> U searchKeys(long, java.util.function.Function<? super K, ? extends U>);
@@ -65767,6 +65757,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ConcurrentLinkedQueue<E> extends java.util.AbstractQueue implements java.util.Queue java.io.Serializable {
@@ -65777,6 +65768,7 @@
     method public E peek();
     method public E poll();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface ConcurrentMap<K, V> implements java.util.Map {
@@ -65808,6 +65800,9 @@
     method public K ceilingKey(K);
     method public java.util.concurrent.ConcurrentSkipListMap<K, V> clone();
     method public java.util.Comparator<? super K> comparator();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> descendingKeySet();
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> descendingMap();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
@@ -65815,18 +65810,25 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
     method public K higherKey(K);
-    method public java.util.NavigableSet<K> keySet();
     method public java.util.Map.Entry<K, V> lastEntry();
     method public K lastKey();
     method public java.util.Map.Entry<K, V> lowerEntry(K);
     method public K lowerKey(K);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
+    method public V putIfAbsent(K, V);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, K);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> tailMap(K, boolean);
@@ -65854,6 +65856,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.NavigableSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -65900,7 +65903,9 @@
     ctor public CopyOnWriteArraySet(java.util.Collection<? extends E>);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public java.util.Iterator<E> iterator();
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class CountDownLatch {
@@ -66059,7 +66064,6 @@
     method public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
     method public boolean hasQueuedSubmissions();
     method public <T> T invoke(java.util.concurrent.ForkJoinTask<T>);
-    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>);
     method public boolean isQuiescent();
     method public boolean isShutdown();
     method public boolean isTerminated();
@@ -66069,9 +66073,6 @@
     method public void shutdown();
     method public java.util.List<java.lang.Runnable> shutdownNow();
     method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.ForkJoinTask<T>);
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.Callable<T>);
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.lang.Runnable, T);
-    method public java.util.concurrent.ForkJoinTask<?> submit(java.lang.Runnable);
     field public static final java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory defaultForkJoinWorkerThreadFactory;
   }
 
@@ -66195,6 +66196,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public E takeFirst() throws java.lang.InterruptedException;
     method public E takeLast() throws java.lang.InterruptedException;
@@ -66215,6 +66217,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -66234,6 +66237,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public void transfer(E) throws java.lang.InterruptedException;
     method public boolean tryTransfer(E);
@@ -66281,6 +66285,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -66384,6 +66389,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -66395,11 +66401,9 @@
     method public static java.util.concurrent.ThreadLocalRandom current();
     method public double nextDouble(double);
     method public double nextDouble(double, double);
-    method public double nextGaussian();
     method public int nextInt(int, int);
     method public long nextLong(long);
     method public long nextLong(long, long);
-    method public void setSeed(long);
   }
 
   public class ThreadPoolExecutor extends java.util.concurrent.AbstractExecutorService {
@@ -66413,7 +66417,6 @@
     method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
     method protected void beforeExecute(java.lang.Thread, java.lang.Runnable);
     method public void execute(java.lang.Runnable);
-    method protected void finalize();
     method public int getActiveCount();
     method public long getCompletedTaskCount();
     method public int getCorePoolSize();
@@ -67284,11 +67287,8 @@
     ctor public JarFile(java.io.File) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean, int) throws java.io.IOException;
-    method public java.util.Enumeration<java.util.jar.JarEntry> entries();
-    method public synchronized java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.util.jar.JarEntry getJarEntry(java.lang.String);
     method public java.util.jar.Manifest getManifest() throws java.io.IOException;
-    method public java.util.stream.Stream<java.util.jar.JarEntry> stream();
     field public static final java.lang.String MANIFEST_NAME = "META-INF/MANIFEST.MF";
   }
 
@@ -67368,8 +67368,6 @@
 
   public class ConsoleHandler extends java.util.logging.StreamHandler {
     ctor public ConsoleHandler();
-    method public void close();
-    method public void publish(java.util.logging.LogRecord);
   }
 
   public class ErrorManager {
@@ -68159,7 +68157,6 @@
     method public int deflate(byte[]);
     method public int deflate(byte[], int, int, int);
     method public void end();
-    method protected void finalize();
     method public void finish();
     method public boolean finished();
     method public int getAdler();
@@ -68192,8 +68189,6 @@
     ctor public DeflaterInputStream(java.io.InputStream);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater, int);
-    method public void mark(int);
-    method public void reset() throws java.io.IOException;
     field protected final byte[] buf;
     field protected final java.util.zip.Deflater def;
   }
@@ -68224,7 +68219,6 @@
     ctor public GZIPOutputStream(java.io.OutputStream, int, boolean) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream, boolean) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected java.util.zip.CRC32 crc;
   }
 
@@ -68232,7 +68226,6 @@
     ctor public Inflater(boolean);
     ctor public Inflater();
     method public void end();
-    method protected void finalize();
     method public boolean finished();
     method public int getAdler();
     method public long getBytesRead();
@@ -68359,7 +68352,6 @@
     ctor public ZipFile(java.io.File, java.nio.charset.Charset) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public java.util.Enumeration<? extends java.util.zip.ZipEntry> entries();
-    method protected void finalize() throws java.io.IOException;
     method public java.lang.String getComment();
     method public java.util.zip.ZipEntry getEntry(java.lang.String);
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
@@ -68466,7 +68458,6 @@
     method public void setComment(java.lang.String);
     method public void setLevel(int);
     method public void setMethod(int);
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
@@ -68623,7 +68614,6 @@
 
   public class ExemptionMechanism {
     ctor protected ExemptionMechanism(javax.crypto.ExemptionMechanismSpi, java.security.Provider, java.lang.String);
-    method protected void finalize();
     method public final byte[] genExemptionBlob() throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException;
     method public final int genExemptionBlob(byte[]) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
     method public final int genExemptionBlob(byte[], int) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
@@ -70201,7 +70191,6 @@
   public abstract class SSLSocketFactory extends javax.net.SocketFactory {
     ctor public SSLSocketFactory();
     method public abstract java.net.Socket createSocket(java.net.Socket, java.lang.String, int, boolean) throws java.io.IOException;
-    method public java.net.Socket createSocket(java.net.Socket, java.io.InputStream, boolean) throws java.io.IOException;
     method public static synchronized javax.net.SocketFactory getDefault();
     method public abstract java.lang.String[] getDefaultCipherSuites();
     method public abstract java.lang.String[] getSupportedCipherSuites();
@@ -71013,7 +71002,6 @@
     ctor public TransformerException(java.lang.String, java.lang.Throwable);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator, java.lang.Throwable);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
     method public java.lang.String getLocationAsString();
     method public javax.xml.transform.SourceLocator getLocator();
@@ -71284,7 +71272,6 @@
   public class XPathException extends java.lang.Exception {
     ctor public XPathException(java.lang.String);
     ctor public XPathException(java.lang.Throwable);
-    method public java.lang.Throwable getCause();
   }
 
   public abstract interface XPathExpression {
diff --git a/api/system-current.txt b/api/system-current.txt
index 2f07556..a859bcd 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3294,7 +3294,6 @@
 
   public final class AnimatorSet extends android.animation.Animator {
     ctor public AnimatorSet();
-    method public android.animation.AnimatorSet clone();
     method public java.util.ArrayList<android.animation.Animator> getChildAnimations();
     method public long getCurrentPlayTime();
     method public long getDuration();
@@ -3413,7 +3412,6 @@
 
   public final class ObjectAnimator extends android.animation.ValueAnimator {
     ctor public ObjectAnimator();
-    method public android.animation.ObjectAnimator clone();
     method public java.lang.String getPropertyName();
     method public java.lang.Object getTarget();
     method public static android.animation.ObjectAnimator ofArgb(java.lang.Object, java.lang.String, int...);
@@ -3439,7 +3437,6 @@
     method public static <T, V> android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofPropertyValuesHolder(java.lang.Object, android.animation.PropertyValuesHolder...);
     method public void setAutoCancel(boolean);
-    method public android.animation.ObjectAnimator setDuration(long);
     method public void setProperty(android.util.Property);
     method public void setPropertyName(java.lang.String);
   }
@@ -3521,7 +3518,6 @@
     ctor public ValueAnimator();
     method public void addUpdateListener(android.animation.ValueAnimator.AnimatorUpdateListener);
     method public static boolean areAnimatorsEnabled();
-    method public android.animation.ValueAnimator clone();
     method public float getAnimatedFraction();
     method public java.lang.Object getAnimatedValue();
     method public java.lang.Object getAnimatedValue(java.lang.String);
@@ -5146,7 +5142,6 @@
     ctor public IntentService(java.lang.String);
     method public android.os.IBinder onBind(android.content.Intent);
     method protected abstract void onHandleIntent(android.content.Intent);
-    method public void onStart(android.content.Intent, int);
     method public void setIntentRedelivery(boolean);
   }
 
@@ -6303,6 +6298,19 @@
     method public void setPersistentVrModeEnabled(boolean);
   }
 
+  public final class WallpaperColors implements android.os.Parcelable {
+    ctor public WallpaperColors(android.os.Parcel);
+    ctor public WallpaperColors(android.graphics.Color, android.graphics.Color, android.graphics.Color);
+    method public int describeContents();
+    method public static android.app.WallpaperColors fromBitmap(android.graphics.Bitmap);
+    method public static android.app.WallpaperColors fromDrawable(android.graphics.drawable.Drawable);
+    method public android.graphics.Color getPrimaryColor();
+    method public android.graphics.Color getSecondaryColor();
+    method public android.graphics.Color getTertiaryColor();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR;
+  }
+
   public final class WallpaperInfo implements android.os.Parcelable {
     ctor public WallpaperInfo(android.content.Context, android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public int describeContents();
@@ -6325,6 +6333,8 @@
   }
 
   public class WallpaperManager {
+    method public void addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener);
+    method public void addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener, android.os.Handler);
     method public void clear() throws java.io.IOException;
     method public void clear(int) throws java.io.IOException;
     method public void clearWallpaper();
@@ -6341,6 +6351,7 @@
     method public android.graphics.drawable.Drawable getDrawable();
     method public android.graphics.drawable.Drawable getFastDrawable();
     method public static android.app.WallpaperManager getInstance(android.content.Context);
+    method public android.app.WallpaperColors getWallpaperColors(int);
     method public android.os.ParcelFileDescriptor getWallpaperFile(int);
     method public int getWallpaperId(int);
     method public android.app.WallpaperInfo getWallpaperInfo();
@@ -6349,6 +6360,7 @@
     method public boolean isWallpaperSupported();
     method public android.graphics.drawable.Drawable peekDrawable();
     method public android.graphics.drawable.Drawable peekFastDrawable();
+    method public void removeOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener);
     method public void sendWallpaperCommand(android.os.IBinder, java.lang.String, int, int, int, android.os.Bundle);
     method public void setBitmap(android.graphics.Bitmap) throws java.io.IOException;
     method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
@@ -6376,6 +6388,10 @@
     field public static final java.lang.String WALLPAPER_PREVIEW_META_DATA = "android.wallpaper.preview";
   }
 
+  public static abstract interface WallpaperManager.OnColorsChangedListener {
+    method public abstract void onColorsChanged(android.app.WallpaperColors, int);
+  }
+
 }
 
 package android.app.admin {
@@ -9446,6 +9462,7 @@
     field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
+    field public static final java.lang.String IPSEC_SERVICE = "ipsec";
     field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
     field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
     field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -11826,7 +11843,6 @@
 
   public static class AssetFileDescriptor.AutoCloseInputStream extends android.os.ParcelFileDescriptor.AutoCloseInputStream {
     ctor public AssetFileDescriptor.AutoCloseInputStream(android.content.res.AssetFileDescriptor) throws java.io.IOException;
-    method public void mark(int);
   }
 
   public static class AssetFileDescriptor.AutoCloseOutputStream extends android.os.ParcelFileDescriptor.AutoCloseOutputStream {
@@ -12134,7 +12150,6 @@
     method public void copyStringToBuffer(int, android.database.CharArrayBuffer);
     method public void deactivate();
     method public void fillWindow(int, android.database.CursorWindow);
-    method protected void finalize();
     method public byte[] getBlob(int);
     method public int getColumnCount();
     method public int getColumnIndex(java.lang.String);
@@ -14609,7 +14624,6 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setOpacity(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
   }
@@ -14690,7 +14704,6 @@
     method public void setAlpha(int);
     method public void setAntiAlias(boolean);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setGravity(int);
     method public void setMipMap(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
@@ -14816,7 +14829,6 @@
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method protected void setConstantState(android.graphics.drawable.DrawableContainer.DrawableContainerState);
-    method public void setDither(boolean);
     method public void setEnterFadeDuration(int);
     method public void setExitFadeDuration(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
@@ -14883,7 +14895,6 @@
     method public void setColors(int[]);
     method public void setCornerRadii(float[]);
     method public void setCornerRadius(float);
-    method public void setDither(boolean);
     method public void setGradientCenter(float, float);
     method public void setGradientRadius(float);
     method public void setGradientType(int);
@@ -14978,7 +14989,6 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setDrawable(int, android.graphics.drawable.Drawable);
     method public boolean setDrawableByLayerId(int, android.graphics.drawable.Drawable);
     method public void setId(int, int);
@@ -15019,7 +15029,6 @@
     method public android.graphics.Paint getPaint();
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
     method public void setTargetDensity(android.util.DisplayMetrics);
     method public void setTargetDensity(int);
@@ -15082,7 +15091,6 @@
     method protected void onDraw(android.graphics.drawable.shapes.Shape, android.graphics.Canvas, android.graphics.Paint);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setIntrinsicHeight(int);
     method public void setIntrinsicWidth(int);
     method public void setPadding(int, int, int, int);
@@ -15124,32 +15132,27 @@
 
   public class ArcShape extends android.graphics.drawable.shapes.RectShape {
     ctor public ArcShape(float, float);
-    method public android.graphics.drawable.shapes.ArcShape clone() throws java.lang.CloneNotSupportedException;
     method public final float getStartAngle();
     method public final float getSweepAngle();
   }
 
   public class OvalShape extends android.graphics.drawable.shapes.RectShape {
     ctor public OvalShape();
-    method public android.graphics.drawable.shapes.OvalShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public class PathShape extends android.graphics.drawable.shapes.Shape {
     ctor public PathShape(android.graphics.Path, float, float);
-    method public android.graphics.drawable.shapes.PathShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
   }
 
   public class RectShape extends android.graphics.drawable.shapes.Shape {
     ctor public RectShape();
-    method public android.graphics.drawable.shapes.RectShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
     method protected final android.graphics.RectF rect();
   }
 
   public class RoundRectShape extends android.graphics.drawable.shapes.RectShape {
     ctor public RoundRectShape(float[], android.graphics.RectF, float[]);
-    method public android.graphics.drawable.shapes.RoundRectShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public abstract class Shape implements java.lang.Cloneable {
@@ -15234,7 +15237,6 @@
     method public final void autoFocus(android.hardware.Camera.AutoFocusCallback);
     method public final void cancelAutoFocus();
     method public final boolean enableShutterSound(boolean);
-    method protected void finalize();
     method public static void getCameraInfo(int, android.hardware.Camera.CameraInfo);
     method public static int getNumberOfCameras();
     method public android.hardware.Camera.Parameters getParameters();
@@ -15852,7 +15854,6 @@
     method public <T> T get(android.hardware.camera2.CameraCharacteristics.Key<T>);
     method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getAvailableCaptureRequestKeys();
     method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getAvailableCaptureResultKeys();
-    method public java.util.List<android.hardware.camera2.CameraCharacteristics.Key<?>> getKeys();
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_MODES;
@@ -16213,7 +16214,6 @@
   public final class CaptureRequest extends android.hardware.camera2.CameraMetadata implements android.os.Parcelable {
     method public int describeContents();
     method public <T> T get(android.hardware.camera2.CaptureRequest.Key<T>);
-    method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getKeys();
     method public java.lang.Object getTag();
     method public boolean isReprocess();
     method public void writeToParcel(android.os.Parcel, int);
@@ -16292,7 +16292,6 @@
   public class CaptureResult extends android.hardware.camera2.CameraMetadata {
     method public <T> T get(android.hardware.camera2.CaptureResult.Key<T>);
     method public long getFrameNumber();
-    method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getKeys();
     method public android.hardware.camera2.CaptureRequest getRequest();
     method public int getSequenceId();
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Boolean> BLACK_LEVEL_LOCK;
@@ -19446,7 +19445,6 @@
   }
 
   public class DateIntervalFormat extends android.icu.text.UFormat {
-    method public synchronized java.lang.Object clone();
     method public final java.lang.StringBuffer format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.DateInterval, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.Calendar, android.icu.util.Calendar, java.lang.StringBuffer, java.text.FieldPosition);
@@ -20252,7 +20250,6 @@
 
   public final class RuleBasedCollator extends android.icu.text.Collator {
     ctor public RuleBasedCollator(java.lang.String) throws java.lang.Exception;
-    method public android.icu.text.RuleBasedCollator cloneAsThawed();
     method public int compare(java.lang.String, java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.text.CharacterIterator);
@@ -20279,7 +20276,6 @@
     method public void setFrenchCollation(boolean);
     method public void setFrenchCollationDefault();
     method public void setLowerCaseFirst(boolean);
-    method public android.icu.text.RuleBasedCollator setMaxVariable(int);
     method public void setNumericCollation(boolean);
     method public void setNumericCollationDefault();
     method public void setStrengthDefault();
@@ -23135,7 +23131,6 @@
     ctor public AudioRecord(android.media.AudioAttributes, android.media.AudioFormat, int, int) throws java.lang.IllegalArgumentException;
     method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
-    method protected void finalize();
     method public int getAudioFormat();
     method public int getAudioSessionId();
     method public int getAudioSource();
@@ -23242,7 +23237,6 @@
     method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
     method public int attachAuxEffect(int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
-    method protected void finalize();
     method public void flush();
     method public int getAudioFormat();
     method public int getAudioSessionId();
@@ -23641,7 +23635,6 @@
     method public boolean clearQueue();
     method public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
     method public boolean closeJetFile();
-    method protected void finalize();
     method public static android.media.JetPlayer getJetPlayer();
     method public static int getMaxTracks();
     method public boolean loadJetFile(java.lang.String);
@@ -23681,7 +23674,6 @@
     ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
-    method protected void finalize();
     method public static boolean isSystemIdSupported(int);
     method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
     method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
@@ -23738,7 +23730,6 @@
     method public static android.view.Surface createPersistentInputSurface();
     method public final int dequeueInputBuffer(long);
     method public final int dequeueOutputBuffer(android.media.MediaCodec.BufferInfo, long);
-    method protected void finalize();
     method public final void flush();
     method public android.media.MediaCodecInfo getCodecInfo();
     method public java.nio.ByteBuffer getInputBuffer(int);
@@ -24150,7 +24141,6 @@
 
   public final class MediaCrypto {
     ctor public MediaCrypto(java.util.UUID, byte[]) throws android.media.MediaCryptoException;
-    method protected void finalize();
     method public static final boolean isCryptoSchemeSupported(java.util.UUID);
     method public final void release();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
@@ -24171,7 +24161,6 @@
     ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
-    method protected void finalize();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
     method public final void setMediaCasSession(android.media.MediaCas.Session);
   }
@@ -24214,7 +24203,6 @@
   public final class MediaDrm {
     ctor public MediaDrm(java.util.UUID) throws android.media.UnsupportedSchemeException;
     method public void closeSession(byte[]);
-    method protected void finalize();
     method public android.media.MediaDrm.CryptoSession getCryptoSession(byte[], java.lang.String, java.lang.String);
     method public android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>) throws android.media.NotProvisionedException;
     method public byte[] getPropertyByteArray(java.lang.String);
@@ -24311,7 +24299,6 @@
   public final class MediaExtractor {
     ctor public MediaExtractor();
     method public boolean advance();
-    method protected void finalize();
     method public long getCachedDuration();
     method public android.media.MediaExtractor.CasInfo getCasInfo(int);
     method public android.media.DrmInitData getDrmInitData();
@@ -24613,7 +24600,6 @@
     method public static android.media.MediaPlayer create(android.content.Context, int, android.media.AudioAttributes, int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
     method public void deselectTrack(int) throws java.lang.IllegalStateException;
-    method protected void finalize();
     method public int getAudioSessionId();
     method public int getCurrentPosition();
     method public android.media.MediaPlayer.DrmInfo getDrmInfo();
@@ -24809,7 +24795,6 @@
 
   public class MediaRecorder {
     ctor public MediaRecorder();
-    method protected void finalize();
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
     method public android.os.PersistableBundle getMetrics();
@@ -25083,7 +25068,6 @@
   public final class MediaSync {
     ctor public MediaSync();
     method public final android.view.Surface createInputSurface();
-    method protected void finalize();
     method public void flush();
     method public android.media.PlaybackParams getPlaybackParams();
     method public android.media.SyncParams getSyncParams();
@@ -25212,10 +25196,6 @@
 
   public deprecated class RemoteControlClient.MetadataEditor extends android.media.MediaMetadataEditor {
     method public synchronized void apply();
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putBitmap(int, android.graphics.Bitmap) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putLong(int, long) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putObject(int, java.lang.Object) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putString(int, java.lang.String) throws java.lang.IllegalArgumentException;
     field public static final int BITMAP_KEY_ARTWORK = 100; // 0x64
   }
 
@@ -25262,7 +25242,6 @@
   }
 
   public class Ringtone {
-    method protected void finalize();
     method public android.media.AudioAttributes getAudioAttributes();
     method public deprecated int getStreamType();
     method public java.lang.String getTitle(android.content.Context);
@@ -25316,7 +25295,6 @@
     ctor public deprecated SoundPool(int, int, int);
     method public final void autoPause();
     method public final void autoResume();
-    method protected void finalize();
     method public int load(java.lang.String, int);
     method public int load(android.content.Context, int, int);
     method public int load(android.content.res.AssetFileDescriptor, int);
@@ -25385,7 +25363,6 @@
 
   public class ToneGenerator {
     ctor public ToneGenerator(int, int);
-    method protected void finalize();
     method public final int getAudioSessionId();
     method public void release();
     method public boolean startTone(int);
@@ -25518,7 +25495,6 @@
   public final class VolumeShaper implements java.lang.AutoCloseable {
     method public void apply(android.media.VolumeShaper.Operation);
     method public void close();
-    method protected void finalize();
     method public float getVolume();
     method public void replace(android.media.VolumeShaper.Configuration, android.media.VolumeShaper.Operation, boolean);
   }
@@ -25573,7 +25549,6 @@
   }
 
   public class AudioEffect {
-    method protected void finalize();
     method public android.media.audiofx.AudioEffect.Descriptor getDescriptor() throws java.lang.IllegalStateException;
     method public boolean getEnabled() throws java.lang.IllegalStateException;
     method public int getId() throws java.lang.IllegalStateException;
@@ -25826,7 +25801,6 @@
 
   public class Visualizer {
     ctor public Visualizer(int) throws java.lang.RuntimeException, java.lang.UnsupportedOperationException;
-    method protected void finalize();
     method public int getCaptureSize() throws java.lang.IllegalStateException;
     method public static int[] getCaptureSizeRange();
     method public boolean getEnabled();
@@ -27726,6 +27700,69 @@
     field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
   }
 
+  public final class IpSecAlgorithm implements android.os.Parcelable {
+    ctor public IpSecAlgorithm(java.lang.String, byte[]);
+    ctor public IpSecAlgorithm(java.lang.String, byte[], int);
+    method public int describeContents();
+    method public byte[] getKey();
+    method public java.lang.String getName();
+    method public int getTruncationLengthBits();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final java.lang.String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";
+    field public static final java.lang.String AUTH_HMAC_MD5 = "hmac(md5)";
+    field public static final java.lang.String AUTH_HMAC_SHA1 = "hmac(sha1)";
+    field public static final java.lang.String AUTH_HMAC_SHA256 = "hmac(sha256)";
+    field public static final java.lang.String AUTH_HMAC_SHA384 = "hmac(sha384)";
+    field public static final java.lang.String AUTH_HMAC_SHA512 = "hmac(sha512)";
+    field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
+    field public static final java.lang.String CRYPT_AES_CBC = "cbc(aes)";
+  }
+
+  public final class IpSecManager {
+    method public void applyTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
+    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
+    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
+    method public void removeTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
+    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress) throws android.net.IpSecManager.ResourceUnavailableException;
+    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+  }
+
+  public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
+  }
+
+  public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
+    method public void close();
+    method public int getSpi();
+  }
+
+  public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
+    method public int getSpi();
+  }
+
+  public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
+    method public void close() throws java.io.IOException;
+    method public int getPort();
+    method public java.io.FileDescriptor getSocket();
+  }
+
+  public final class IpSecTransform implements java.lang.AutoCloseable {
+    method public void close();
+    field public static final int DIRECTION_IN = 0; // 0x0
+    field public static final int DIRECTION_OUT = 1; // 0x1
+  }
+
+  public static class IpSecTransform.Builder {
+    ctor public IpSecTransform.Builder(android.content.Context);
+    method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+    method public android.net.IpSecTransform.Builder setAuthenticatedEncryption(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
+    method public android.net.IpSecTransform.Builder setNattKeepalive(int);
+    method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
+    method public android.net.IpSecTransform.Builder setUnderlyingNetwork(android.net.Network);
+  }
+
   public class LinkAddress implements android.os.Parcelable {
     method public int describeContents();
     method public java.net.InetAddress getAddress();
@@ -27851,6 +27888,7 @@
     field public static final int NET_CAPABILITY_MMS = 0; // 0x0
     field public static final int NET_CAPABILITY_NOT_METERED = 11; // 0xb
     field public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; // 0xd
+    field public static final int NET_CAPABILITY_NOT_ROAMING = 18; // 0x12
     field public static final int NET_CAPABILITY_NOT_VPN = 15; // 0xf
     field public static final int NET_CAPABILITY_RCS = 8; // 0x8
     field public static final int NET_CAPABILITY_SUPL = 1; // 0x1
@@ -27881,7 +27919,7 @@
     method public boolean isConnected();
     method public boolean isConnectedOrConnecting();
     method public boolean isFailover();
-    method public boolean isRoaming();
+    method public deprecated boolean isRoaming();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
   }
@@ -28246,6 +28284,7 @@
     method public boolean protect(java.net.DatagramSocket);
     method public boolean setUnderlyingNetworks(android.net.Network[]);
     field public static final java.lang.String SERVICE_INTERFACE = "android.net.VpnService";
+    field public static final java.lang.String SERVICE_META_DATA_SUPPORTS_ALWAYS_ON = "android.net.VpnService.SUPPORTS_ALWAYS_ON";
   }
 
   public class VpnService.Builder {
@@ -33347,7 +33386,6 @@
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
-    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.Bundle> CREATOR;
     field public static final android.os.Bundle EMPTY;
@@ -33411,6 +33449,7 @@
   }
 
   public final class Debug {
+    method public static void attachJvmtiAgent(java.lang.String, java.lang.String) throws java.io.IOException;
     method public static deprecated void changeDebugPort(int);
     method public static void dumpHprofData(java.lang.String) throws java.io.IOException;
     method public static boolean dumpService(java.lang.String, java.io.FileDescriptor, java.lang.String[]);
@@ -33589,7 +33628,6 @@
   public abstract class FileObserver {
     ctor public FileObserver(java.lang.String);
     ctor public FileObserver(java.lang.String, int);
-    method protected void finalize();
     method public abstract void onEvent(int, java.lang.String);
     method public void startWatching();
     method public void stopWatching();
@@ -33764,7 +33802,6 @@
     ctor public MemoryFile(java.lang.String, int) throws java.io.IOException;
     method public synchronized boolean allowPurging(boolean) throws java.io.IOException;
     method public void close();
-    method protected void finalize();
     method public java.io.InputStream getInputStream();
     method public java.io.OutputStream getOutputStream();
     method public boolean isPurgingAllowed();
@@ -34064,7 +34101,6 @@
     method public int describeContents();
     method public android.os.PersistableBundle getPersistableBundle(java.lang.String);
     method public void putPersistableBundle(java.lang.String, android.os.PersistableBundle);
-    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.PersistableBundle> CREATOR;
     field public static final android.os.PersistableBundle EMPTY;
@@ -38702,7 +38738,6 @@
     method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
-    method public synchronized void resize(int);
     method public void setFace(android.renderscript.Type.CubemapFace);
     method public void setLOD(int);
     method public void setX(int);
@@ -41183,6 +41218,16 @@
     field public final int errno;
   }
 
+  public class Int32Ref {
+    ctor public Int32Ref(int);
+    field public int value;
+  }
+
+  public class Int64Ref {
+    ctor public Int64Ref(long);
+    field public long value;
+  }
+
   public final class Os {
     method public static java.io.FileDescriptor accept(java.io.FileDescriptor, java.net.InetSocketAddress) throws android.system.ErrnoException, java.net.SocketException;
     method public static boolean access(java.lang.String, int) throws android.system.ErrnoException;
@@ -41252,7 +41297,8 @@
     method public static void remove(java.lang.String) throws android.system.ErrnoException;
     method public static void removexattr(java.lang.String, java.lang.String) throws android.system.ErrnoException;
     method public static void rename(java.lang.String, java.lang.String) throws android.system.ErrnoException;
-    method public static long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.util.MutableLong, long) throws android.system.ErrnoException;
+    method public static deprecated long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.util.MutableLong, long) throws android.system.ErrnoException;
+    method public static long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.system.Int64Ref, long) throws android.system.ErrnoException;
     method public static int sendto(java.io.FileDescriptor, java.nio.ByteBuffer, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
     method public static int sendto(java.io.FileDescriptor, byte[], int, int, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
     method public static void setegid(int) throws android.system.ErrnoException;
@@ -41277,7 +41323,8 @@
     method public static int umask(int);
     method public static android.system.StructUtsname uname();
     method public static void unsetenv(java.lang.String) throws android.system.ErrnoException;
-    method public static int waitpid(int, android.util.MutableInt, int) throws android.system.ErrnoException;
+    method public static deprecated int waitpid(int, android.util.MutableInt, int) throws android.system.ErrnoException;
+    method public static int waitpid(int, android.system.Int32Ref, int) throws android.system.ErrnoException;
     method public static int write(java.io.FileDescriptor, java.nio.ByteBuffer) throws android.system.ErrnoException, java.io.InterruptedIOException;
     method public static int write(java.io.FileDescriptor, byte[], int, int) throws android.system.ErrnoException, java.io.InterruptedIOException;
     method public static int writev(java.io.FileDescriptor, java.lang.Object[], int[], int[]) throws android.system.ErrnoException, java.io.InterruptedIOException;
@@ -41872,6 +41919,7 @@
     method public android.telecom.Call.RttCall getRttCall();
     method public int getState();
     method public android.telecom.InCallService.VideoCall getVideoCall();
+    method public void handoverTo(android.telecom.PhoneAccountHandle, int, android.os.Bundle);
     method public void hold();
     method public boolean isRttActive();
     method public void mergeConference();
@@ -41918,6 +41966,8 @@
     method public void onConferenceableCallsChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
     method public void onConnectionEvent(android.telecom.Call, java.lang.String, android.os.Bundle);
     method public void onDetailsChanged(android.telecom.Call, android.telecom.Call.Details);
+    method public void onHandoverComplete(android.telecom.Call);
+    method public void onHandoverFailed(android.telecom.Call, int);
     method public void onParentChanged(android.telecom.Call, android.telecom.Call);
     method public void onPostDialWait(android.telecom.Call, java.lang.String);
     method public void onRttInitiationFailure(android.telecom.Call, int);
@@ -41926,6 +41976,10 @@
     method public void onRttStatusChanged(android.telecom.Call, boolean, android.telecom.Call.RttCall);
     method public void onStateChanged(android.telecom.Call, int);
     method public void onVideoCallChanged(android.telecom.Call, android.telecom.InCallService.VideoCall);
+    field public static final int HANDOVER_FAILURE_DEST_APP_REJECTED = 1; // 0x1
+    field public static final int HANDOVER_FAILURE_DEST_INVALID_PERM = 3; // 0x3
+    field public static final int HANDOVER_FAILURE_DEST_NOT_SUPPORTED = 2; // 0x2
+    field public static final int HANDOVER_FAILURE_DEST_USER_REJECTED = 4; // 0x4
   }
 
   public static class Call.Details {
@@ -41985,8 +42039,7 @@
 
   public static final class Call.RttCall {
     method public int getRttAudioMode();
-    method public java.lang.String read() throws java.io.IOException;
-    method public java.lang.String readImmediately() throws java.io.IOException;
+    method public java.lang.String read();
     method public void setRttMode(int);
     method public void write(java.lang.String) throws java.io.IOException;
     field public static final int RTT_MODE_FULL = 1; // 0x1
@@ -41998,7 +42051,9 @@
     ctor public CallAudioState(boolean, int, int);
     method public static java.lang.String audioRouteToString(int);
     method public int describeContents();
+    method public android.bluetooth.BluetoothDevice getActiveBluetoothDevice();
     method public int getRoute();
+    method public java.util.Collection<android.bluetooth.BluetoothDevice> getSupportedBluetoothDevices();
     method public int getSupportedRouteMask();
     method public boolean isMuted();
     method public void writeToParcel(android.os.Parcel, int);
@@ -42075,6 +42130,7 @@
     method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
     method public final deprecated void setConnectTimeMillis(long);
     method public final void setConnectionCapabilities(int);
+    method public final void setConnectionElapsedTime(long);
     method public final void setConnectionProperties(int);
     method public final void setConnectionTime(long);
     method public final void setDialing();
@@ -42136,6 +42192,7 @@
     method public final void putExtras(android.os.Bundle);
     method public final void removeExtras(java.util.List<java.lang.String>);
     method public final void removeExtras(java.lang.String...);
+    method public void requestBluetoothAudio(java.lang.String);
     method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
     method public final void setActive();
     method public final void setAddress(android.net.Uri, int);
@@ -42267,8 +42324,11 @@
     method public void onConference(android.telecom.Connection, android.telecom.Connection);
     method public android.telecom.Connection onCreateIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public void onCreateIncomingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+    method public android.telecom.Connection onCreateIncomingHandoverConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public void onCreateOutgoingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+    method public android.telecom.Connection onCreateOutgoingHandoverConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+    method public void onHandoverFailed(android.telecom.ConnectionRequest, int);
     method public void onRemoteConferenceAdded(android.telecom.RemoteConference);
     method public void onRemoteExistingConnectionAdded(android.telecom.RemoteConnection);
     field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.ConnectionService";
@@ -42329,6 +42389,7 @@
     method public deprecated void onPhoneCreated(android.telecom.Phone);
     method public deprecated void onPhoneDestroyed(android.telecom.Phone);
     method public void onSilenceRinger();
+    method public final void requestBluetoothAudio(java.lang.String);
     method public final void setAudioRoute(int);
     method public final void setMuted(boolean);
     field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.InCallService";
@@ -42467,6 +42528,7 @@
     method public final android.telecom.CallAudioState getCallAudioState();
     method public final java.util.List<android.telecom.Call> getCalls();
     method public final void removeListener(android.telecom.Phone.Listener);
+    method public void requestBluetoothAudio(java.lang.String);
     method public final void setAudioRoute(int);
     method public final void setMuted(boolean);
   }
@@ -42514,6 +42576,9 @@
     field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR;
     field public static final java.lang.String EXTRA_CALL_SUBJECT_CHARACTER_ENCODING = "android.telecom.extra.CALL_SUBJECT_CHARACTER_ENCODING";
     field public static final java.lang.String EXTRA_CALL_SUBJECT_MAX_LENGTH = "android.telecom.extra.CALL_SUBJECT_MAX_LENGTH";
+    field public static final java.lang.String EXTRA_LOG_SELF_MANAGED_CALLS = "android.telecom.extra.LOG_SELF_MANAGED_CALLS";
+    field public static final java.lang.String EXTRA_SUPPORTS_HANDOVER_FROM = "android.telecom.extra.SUPPORTS_HANDOVER_FROM";
+    field public static final java.lang.String EXTRA_SUPPORTS_HANDOVER_TO = "android.telecom.extra.SUPPORTS_HANDOVER_TO";
     field public static final int NO_HIGHLIGHT_COLOR = 0; // 0x0
     field public static final int NO_RESOURCE_ID = -1; // 0xffffffff
     field public static final java.lang.String SCHEME_SIP = "sip";
@@ -42715,6 +42780,7 @@
   }
 
   public class TelecomManager {
+    method public void acceptHandover(android.net.Uri, int, android.telecom.PhoneAccountHandle);
     method public void acceptRingingCall();
     method public void acceptRingingCall(int);
     method public void addNewIncomingCall(android.telecom.PhoneAccountHandle, android.os.Bundle);
@@ -42900,6 +42966,7 @@
     field public static final java.lang.String KEY_DURATION_BLOCKING_DISABLED_AFTER_EMERGENCY_INT = "duration_blocking_disabled_after_emergency_int";
     field public static final java.lang.String KEY_EDITABLE_ENHANCED_4G_LTE_BOOL = "editable_enhanced_4g_lte_bool";
     field public static final java.lang.String KEY_EDITABLE_VOICEMAIL_NUMBER_BOOL = "editable_voicemail_number_bool";
+    field public static final java.lang.String KEY_EDITABLE_VOICEMAIL_NUMBER_SETTING_BOOL = "editable_voicemail_number_setting_bool";
     field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_key_vibration_bool";
     field public static final java.lang.String KEY_FORCE_HOME_NETWORK_BOOL = "force_home_network_bool";
     field public static final java.lang.String KEY_GSM_DTMF_TONE_DELAY_INT = "gsm_dtmf_tone_delay_int";
@@ -42990,6 +43057,8 @@
     method public int getLatitude();
     method public int getLongitude();
     method public int getNetworkId();
+    method public java.lang.CharSequence getOperatorAlphaLong();
+    method public java.lang.CharSequence getOperatorAlphaShort();
     method public int getSystemId();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityCdma> CREATOR;
@@ -43001,8 +43070,13 @@
     method public int getBsic();
     method public int getCid();
     method public int getLac();
-    method public int getMcc();
-    method public int getMnc();
+    method public deprecated int getMcc();
+    method public java.lang.String getMccStr();
+    method public deprecated int getMnc();
+    method public java.lang.String getMncStr();
+    method public java.lang.String getMobileNetworkOperator();
+    method public java.lang.CharSequence getOperatorAlphaLong();
+    method public java.lang.CharSequence getOperatorAlphaShort();
     method public deprecated int getPsc();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityGsm> CREATOR;
@@ -43012,8 +43086,13 @@
     method public int describeContents();
     method public int getCi();
     method public int getEarfcn();
-    method public int getMcc();
-    method public int getMnc();
+    method public deprecated int getMcc();
+    method public java.lang.String getMccStr();
+    method public deprecated int getMnc();
+    method public java.lang.String getMncStr();
+    method public java.lang.String getMobileNetworkOperator();
+    method public java.lang.CharSequence getOperatorAlphaLong();
+    method public java.lang.CharSequence getOperatorAlphaShort();
     method public int getPci();
     method public int getTac();
     method public void writeToParcel(android.os.Parcel, int);
@@ -43024,8 +43103,13 @@
     method public int describeContents();
     method public int getCid();
     method public int getLac();
-    method public int getMcc();
-    method public int getMnc();
+    method public deprecated int getMcc();
+    method public java.lang.String getMccStr();
+    method public deprecated int getMnc();
+    method public java.lang.String getMncStr();
+    method public java.lang.String getMobileNetworkOperator();
+    method public java.lang.CharSequence getOperatorAlphaLong();
+    method public java.lang.CharSequence getOperatorAlphaShort();
     method public int getPsc();
     method public int getUarfcn();
     method public void writeToParcel(android.os.Parcel, int);
@@ -43158,13 +43242,47 @@
     field public static final int STATUS_UNKNOWN_ERROR = 4; // 0x4
   }
 
-  public class MbmsStreamingManager {
-    method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback, int, android.os.Handler) throws android.telephony.mbms.MbmsException;
-    method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback, android.os.Handler) throws android.telephony.mbms.MbmsException;
-    method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback) throws android.telephony.mbms.MbmsException;
-    method public void dispose();
-    method public void getStreamingServices(java.util.List<java.lang.String>) throws android.telephony.mbms.MbmsException;
-    method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, android.telephony.mbms.StreamingServiceCallback, android.os.Handler) throws android.telephony.mbms.MbmsException;
+  public class MbmsDownloadSession implements java.lang.AutoCloseable {
+    method public void cancelDownload(android.telephony.mbms.DownloadRequest);
+    method public void close();
+    method public static android.telephony.MbmsDownloadSession create(android.content.Context, android.telephony.mbms.MbmsDownloadSessionCallback, android.os.Handler);
+    method public static android.telephony.MbmsDownloadSession create(android.content.Context, android.telephony.mbms.MbmsDownloadSessionCallback, int, android.os.Handler);
+    method public void download(android.telephony.mbms.DownloadRequest);
+    method public int getDownloadStatus(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo);
+    method public java.io.File getTempFileRootDirectory();
+    method public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads();
+    method public void registerStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback, android.os.Handler);
+    method public void requestUpdateFileServices(java.util.List<java.lang.String>);
+    method public void resetDownloadKnowledge(android.telephony.mbms.DownloadRequest);
+    method public void setTempFileRootDirectory(java.io.File);
+    method public void unregisterStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback);
+    field public static final java.lang.String DEFAULT_TOP_LEVEL_TEMP_DIRECTORY = "androidMbmsTempFileRoot";
+    field public static final java.lang.String EXTRA_MBMS_COMPLETED_FILE_URI = "android.telephony.extra.MBMS_COMPLETED_FILE_URI";
+    field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_REQUEST = "android.telephony.extra.MBMS_DOWNLOAD_REQUEST";
+    field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_RESULT = "android.telephony.extra.MBMS_DOWNLOAD_RESULT";
+    field public static final java.lang.String EXTRA_MBMS_FILE_INFO = "android.telephony.extra.MBMS_FILE_INFO";
+    field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload";
+    field public static final int RESULT_CANCELLED = 2; // 0x2
+    field public static final int RESULT_DOWNLOAD_FAILURE = 6; // 0x6
+    field public static final int RESULT_EXPIRED = 3; // 0x3
+    field public static final int RESULT_FILE_ROOT_UNREACHABLE = 8; // 0x8
+    field public static final int RESULT_IO_ERROR = 4; // 0x4
+    field public static final int RESULT_OUT_OF_STORAGE = 7; // 0x7
+    field public static final int RESULT_SERVICE_ID_NOT_DEFINED = 5; // 0x5
+    field public static final int RESULT_SUCCESSFUL = 1; // 0x1
+    field public static final int STATUS_ACTIVELY_DOWNLOADING = 1; // 0x1
+    field public static final int STATUS_PENDING_DOWNLOAD = 2; // 0x2
+    field public static final int STATUS_PENDING_DOWNLOAD_WINDOW = 4; // 0x4
+    field public static final int STATUS_PENDING_REPAIR = 3; // 0x3
+    field public static final int STATUS_UNKNOWN = 0; // 0x0
+  }
+
+  public class MbmsStreamingSession implements java.lang.AutoCloseable {
+    method public void close();
+    method public static android.telephony.MbmsStreamingSession create(android.content.Context, android.telephony.mbms.MbmsStreamingSessionCallback, int, android.os.Handler);
+    method public static android.telephony.MbmsStreamingSession create(android.content.Context, android.telephony.mbms.MbmsStreamingSessionCallback, android.os.Handler);
+    method public void requestUpdateStreamingServices(java.util.List<java.lang.String>);
+    method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, android.telephony.mbms.StreamingServiceCallback, android.os.Handler);
     field public static final java.lang.String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming";
   }
 
@@ -43198,8 +43316,10 @@
   public class PhoneNumberUtils {
     ctor public PhoneNumberUtils();
     method public static void addTtsSpan(android.text.Spannable, int, int);
-    method public static java.lang.String calledPartyBCDFragmentToString(byte[], int, int);
-    method public static java.lang.String calledPartyBCDToString(byte[], int, int);
+    method public static deprecated java.lang.String calledPartyBCDFragmentToString(byte[], int, int);
+    method public static java.lang.String calledPartyBCDFragmentToString(byte[], int, int, int);
+    method public static deprecated java.lang.String calledPartyBCDToString(byte[], int, int);
+    method public static java.lang.String calledPartyBCDToString(byte[], int, int, int);
     method public static boolean compare(java.lang.String, java.lang.String);
     method public static boolean compare(android.content.Context, java.lang.String, java.lang.String);
     method public static java.lang.String convertKeypadLettersToDigits(java.lang.String);
@@ -43232,12 +43352,15 @@
     method public static byte[] networkPortionToCalledPartyBCD(java.lang.String);
     method public static byte[] networkPortionToCalledPartyBCDWithLength(java.lang.String);
     method public static java.lang.String normalizeNumber(java.lang.String);
-    method public static byte[] numberToCalledPartyBCD(java.lang.String);
+    method public static deprecated byte[] numberToCalledPartyBCD(java.lang.String);
+    method public static byte[] numberToCalledPartyBCD(java.lang.String, int);
     method public static java.lang.String replaceUnicodeDigits(java.lang.String);
     method public static java.lang.String stringFromStringAndTOA(java.lang.String, int);
     method public static java.lang.String stripSeparators(java.lang.String);
     method public static java.lang.String toCallerIDMinMatch(java.lang.String);
     method public static int toaFromString(java.lang.String);
+    field public static final int BCD_EXTENDED_TYPE_CALLED_PARTY = 2; // 0x2
+    field public static final int BCD_EXTENDED_TYPE_EF_ADN = 1; // 0x1
     field public static final int FORMAT_JAPAN = 2; // 0x2
     field public static final int FORMAT_NANP = 1; // 0x1
     field public static final int FORMAT_UNKNOWN = 0; // 0x0
@@ -43372,9 +43495,12 @@
     field public static final int MMS_ERROR_UNABLE_CONNECT_MMS = 3; // 0x3
     field public static final int MMS_ERROR_UNSPECIFIED = 1; // 0x1
     field public static final int RESULT_ERROR_GENERIC_FAILURE = 1; // 0x1
+    field public static final int RESULT_ERROR_LIMIT_EXCEEDED = 5; // 0x5
     field public static final int RESULT_ERROR_NO_SERVICE = 4; // 0x4
     field public static final int RESULT_ERROR_NULL_PDU = 3; // 0x3
     field public static final int RESULT_ERROR_RADIO_OFF = 2; // 0x2
+    field public static final int RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED = 8; // 0x8
+    field public static final int RESULT_ERROR_SHORT_CODE_NOT_ALLOWED = 7; // 0x7
     field public static final int STATUS_ON_ICC_FREE = 0; // 0x0
     field public static final int STATUS_ON_ICC_READ = 1; // 0x1
     field public static final int STATUS_ON_ICC_SENT = 5; // 0x5
@@ -43507,8 +43633,8 @@
   }
 
   public class TelephonyManager {
-    method public void answerRingingCall();
-    method public void call(java.lang.String, java.lang.String);
+    method public deprecated void answerRingingCall();
+    method public deprecated void call(java.lang.String, java.lang.String);
     method public boolean canChangeDtmfToneLength();
     method public int checkCarrierPrivilegesForPackage(java.lang.String);
     method public int checkCarrierPrivilegesForPackageAnyPhone(java.lang.String);
@@ -43518,7 +43644,7 @@
     method public boolean disableDataConnectivity();
     method public boolean enableDataConnectivity();
     method public void enableVideoCalling(boolean);
-    method public boolean endCall();
+    method public deprecated boolean endCall();
     method public java.util.List<android.telephony.CellInfo> getAllCellInfo();
     method public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
     method public int getCallState();
@@ -43559,6 +43685,7 @@
     method public int getPhoneCount();
     method public int getPhoneType();
     method public android.telephony.ServiceState getServiceState();
+    method public android.telephony.SignalStrength getSignalStrength();
     method public java.lang.String getSimCountryIso();
     method public java.lang.String getSimOperator();
     method public java.lang.String getSimOperatorName();
@@ -43593,7 +43720,7 @@
     method public boolean isRadioOn();
     method public boolean isRinging();
     method public boolean isSmsCapable();
-    method public boolean isTtyModeSupported();
+    method public deprecated boolean isTtyModeSupported();
     method public boolean isVideoCallingEnabled();
     method public deprecated boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
     method public boolean isVoiceCapable();
@@ -43618,7 +43745,7 @@
     method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
     method public void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
     method public void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean);
-    method public void silenceRinger();
+    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);
@@ -43860,7 +43987,6 @@
 
   public static deprecated class SmsMessage.SubmitPdu {
     ctor public deprecated SmsMessage.SubmitPdu();
-    method public deprecated java.lang.String toString();
     field public deprecated byte[] encodedMessage;
     field public deprecated byte[] encodedScAddress;
   }
@@ -43878,15 +44004,89 @@
 
 package android.telephony.mbms {
 
-  public class MbmsException extends java.lang.Exception {
-    method public int getErrorCode();
+  public final class DownloadRequest implements android.os.Parcelable {
+    method public static android.telephony.mbms.DownloadRequest copy(android.telephony.mbms.DownloadRequest);
+    method public int describeContents();
+    method public java.lang.String getFileServiceId();
+    method public static int getMaxAppIntentSize();
+    method public static int getMaxDestinationUriSize();
+    method public byte[] getOpaqueData();
+    method public android.net.Uri getSourceUri();
+    method public int getSubscriptionId();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.mbms.DownloadRequest> CREATOR;
+  }
+
+  public static class DownloadRequest.Builder {
+    ctor public DownloadRequest.Builder(android.net.Uri);
+    method public android.telephony.mbms.DownloadRequest build();
+    method public android.telephony.mbms.DownloadRequest.Builder setAppIntent(android.content.Intent);
+    method public android.telephony.mbms.DownloadRequest.Builder setOpaqueData(byte[]);
+    method public android.telephony.mbms.DownloadRequest.Builder setServiceId(java.lang.String);
+    method public android.telephony.mbms.DownloadRequest.Builder setServiceInfo(android.telephony.mbms.FileServiceInfo);
+    method public android.telephony.mbms.DownloadRequest.Builder setSubscriptionId(int);
+  }
+
+  public class DownloadStateCallback {
+    ctor public DownloadStateCallback();
+    ctor public DownloadStateCallback(int);
+    method public final boolean isFilterFlagSet(int);
+    method public void onProgressUpdated(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo, int, int, int, int);
+    method public void onStateUpdated(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo, int);
+    field public static final int ALL_UPDATES = 0; // 0x0
+    field public static final int PROGRESS_UPDATES = 1; // 0x1
+    field public static final int STATE_UPDATES = 2; // 0x2
+  }
+
+  public final class FileInfo implements android.os.Parcelable {
+    ctor public FileInfo(android.net.Uri, java.lang.String);
+    method public int describeContents();
+    method public java.lang.String getMimeType();
+    method public android.net.Uri getUri();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.mbms.FileInfo> CREATOR;
+  }
+
+  public final class FileServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable {
+    ctor public FileServiceInfo(java.util.Map<java.util.Locale, java.lang.String>, java.lang.String, java.util.List<java.util.Locale>, java.lang.String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>);
+    method public int describeContents();
+    method public java.util.List<android.telephony.mbms.FileInfo> getFiles();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.mbms.FileServiceInfo> CREATOR;
+  }
+
+  public class MbmsDownloadReceiver extends android.content.BroadcastReceiver {
+    ctor public MbmsDownloadReceiver();
+    method public void onReceive(android.content.Context, android.content.Intent);
+    field public static final int RESULT_APP_NOTIFICATION_ERROR = 6; // 0x6
+    field public static final int RESULT_BAD_TEMP_FILE_ROOT = 3; // 0x3
+    field public static final int RESULT_DOWNLOAD_FINALIZATION_ERROR = 4; // 0x4
+    field public static final int RESULT_INVALID_ACTION = 1; // 0x1
+    field public static final int RESULT_MALFORMED_INTENT = 2; // 0x2
+    field public static final int RESULT_OK = 0; // 0x0
+    field public static final int RESULT_TEMP_FILE_GENERATION_ERROR = 5; // 0x5
+  }
+
+  public class MbmsDownloadSessionCallback {
+    ctor public MbmsDownloadSessionCallback();
+    method public void onError(int, java.lang.String);
+    method public void onFileServicesUpdated(java.util.List<android.telephony.mbms.FileServiceInfo>);
+    method public void onMiddlewareReady();
+  }
+
+  public class MbmsErrors {
     field public static final int ERROR_MIDDLEWARE_LOST = 3; // 0x3
     field public static final int ERROR_MIDDLEWARE_NOT_BOUND = 2; // 0x2
     field public static final int ERROR_NO_UNIQUE_MIDDLEWARE = 1; // 0x1
     field public static final int SUCCESS = 0; // 0x0
   }
 
-  public static class MbmsException.GeneralErrors {
+  public static class MbmsErrors.DownloadErrors {
+    field public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 401; // 0x191
+    field public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402; // 0x192
+  }
+
+  public static class MbmsErrors.GeneralErrors {
     field public static final int ERROR_CARRIER_CHANGE_NOT_ALLOWED = 207; // 0xcf
     field public static final int ERROR_IN_E911 = 204; // 0xcc
     field public static final int ERROR_MIDDLEWARE_NOT_YET_READY = 201; // 0xc9
@@ -43896,39 +44096,39 @@
     field public static final int ERROR_UNABLE_TO_READ_SIM = 206; // 0xce
   }
 
-  public static class MbmsException.InitializationErrors {
+  public static class MbmsErrors.InitializationErrors {
     field public static final int ERROR_APP_PERMISSIONS_NOT_GRANTED = 102; // 0x66
     field public static final int ERROR_DUPLICATE_INITIALIZE = 101; // 0x65
     field public static final int ERROR_UNABLE_TO_INITIALIZE = 103; // 0x67
   }
 
-  public static class MbmsException.StreamingErrors {
+  public static class MbmsErrors.StreamingErrors {
     field public static final int ERROR_CONCURRENT_SERVICE_LIMIT_REACHED = 301; // 0x12d
     field public static final int ERROR_DUPLICATE_START_STREAM = 303; // 0x12f
     field public static final int ERROR_UNABLE_TO_START_SERVICE = 302; // 0x12e
   }
 
-  public class MbmsStreamingManagerCallback {
-    ctor public MbmsStreamingManagerCallback();
+  public class MbmsStreamingSessionCallback {
+    ctor public MbmsStreamingSessionCallback();
     method public void onError(int, java.lang.String);
     method public void onMiddlewareReady();
     method public void onStreamingServicesUpdated(java.util.List<android.telephony.mbms.StreamingServiceInfo>);
   }
 
   public class ServiceInfo {
-    method public java.lang.String getClassName();
     method public java.util.List<java.util.Locale> getLocales();
-    method public java.util.Map<java.util.Locale, java.lang.String> getNames();
+    method public java.lang.CharSequence getNameForLocale(java.util.Locale);
+    method public java.util.Set<java.util.Locale> getNamedContentLocales();
+    method public java.lang.String getServiceClassName();
     method public java.lang.String getServiceId();
     method public java.util.Date getSessionEndTime();
     method public java.util.Date getSessionStartTime();
   }
 
   public class StreamingService {
-    method public void dispose() throws android.telephony.mbms.MbmsException;
     method public android.telephony.mbms.StreamingServiceInfo getInfo();
-    method public android.net.Uri getPlaybackUri() throws android.telephony.mbms.MbmsException;
-    method public void stopStreaming() throws android.telephony.mbms.MbmsException;
+    method public android.net.Uri getPlaybackUri();
+    method public void stopStreaming();
     field public static final int BROADCAST_METHOD = 1; // 0x1
     field public static final int REASON_BY_USER_REQUEST = 1; // 0x1
     field public static final int REASON_END_OF_SESSION = 2; // 0x2
@@ -43960,22 +44160,62 @@
     field public static final android.os.Parcelable.Creator<android.telephony.mbms.StreamingServiceInfo> CREATOR;
   }
 
+  public final class UriPathPair implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.net.Uri getContentUri();
+    method public android.net.Uri getFilePathUri();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.mbms.UriPathPair> CREATOR;
+  }
+
 }
 
 package android.telephony.mbms.vendor {
 
+  public class MbmsDownloadServiceBase extends android.os.Binder {
+    ctor public MbmsDownloadServiceBase();
+    method public int cancelDownload(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
+    method public void dispose(int) throws android.os.RemoteException;
+    method public int download(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
+    method public int getDownloadStatus(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) throws android.os.RemoteException;
+    method public int initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback) throws android.os.RemoteException;
+    method public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads(int) throws android.os.RemoteException;
+    method public void onAppCallbackDied(int, int);
+    method public int registerStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback) throws android.os.RemoteException;
+    method public int requestUpdateFileServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
+    method public int resetDownloadKnowledge(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
+    method public int setTempFileRootDirectory(int, java.lang.String) throws android.os.RemoteException;
+    method public int unregisterStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback) throws android.os.RemoteException;
+  }
+
   public class MbmsStreamingServiceBase extends android.os.Binder {
     ctor public MbmsStreamingServiceBase();
     method public void dispose(int) throws android.os.RemoteException;
-    method public void disposeStream(int, java.lang.String) throws android.os.RemoteException;
     method public android.net.Uri getPlaybackUri(int, java.lang.String) throws android.os.RemoteException;
-    method public int getStreamingServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
-    method public int initialize(android.telephony.mbms.MbmsStreamingManagerCallback, int) throws android.os.RemoteException;
+    method public int initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int) throws android.os.RemoteException;
     method public void onAppCallbackDied(int, int);
+    method public int requestUpdateStreamingServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
     method public int startStreaming(int, java.lang.String, android.telephony.mbms.StreamingServiceCallback) throws android.os.RemoteException;
     method public void stopStreaming(int, java.lang.String) throws android.os.RemoteException;
   }
 
+  public class VendorUtils {
+    ctor public VendorUtils();
+    method public static android.content.ComponentName getAppReceiverFromPackageName(android.content.Context, java.lang.String);
+    field public static final java.lang.String ACTION_CLEANUP = "android.telephony.mbms.action.CLEANUP";
+    field public static final java.lang.String ACTION_DOWNLOAD_RESULT_INTERNAL = "android.telephony.mbms.action.DOWNLOAD_RESULT_INTERNAL";
+    field public static final java.lang.String ACTION_FILE_DESCRIPTOR_REQUEST = "android.telephony.mbms.action.FILE_DESCRIPTOR_REQUEST";
+    field public static final java.lang.String EXTRA_FD_COUNT = "android.telephony.mbms.extra.FD_COUNT";
+    field public static final java.lang.String EXTRA_FINAL_URI = "android.telephony.mbms.extra.FINAL_URI";
+    field public static final java.lang.String EXTRA_FREE_URI_LIST = "android.telephony.mbms.extra.FREE_URI_LIST";
+    field public static final java.lang.String EXTRA_PAUSED_LIST = "android.telephony.mbms.extra.PAUSED_LIST";
+    field public static final java.lang.String EXTRA_PAUSED_URI_LIST = "android.telephony.mbms.extra.PAUSED_URI_LIST";
+    field public static final java.lang.String EXTRA_SERVICE_ID = "android.telephony.mbms.extra.SERVICE_ID";
+    field public static final java.lang.String EXTRA_TEMP_FILES_IN_USE = "android.telephony.mbms.extra.TEMP_FILES_IN_USE";
+    field public static final java.lang.String EXTRA_TEMP_FILE_ROOT = "android.telephony.mbms.extra.TEMP_FILE_ROOT";
+    field public static final java.lang.String EXTRA_TEMP_LIST = "android.telephony.mbms.extra.TEMP_LIST";
+  }
+
 }
 
 package android.test {
@@ -44035,7 +44275,6 @@
     method public java.util.List<junit.framework.TestCase> getTestCases();
     method public java.lang.String getTestClassName();
     method public junit.framework.TestResult getTestResult();
-    method protected java.lang.Class loadSuiteClass(java.lang.String) throws java.lang.ClassNotFoundException;
     method protected void runFailed(java.lang.String);
     method public void runTest();
     method public void runTest(junit.framework.TestResult);
@@ -44296,12 +44535,10 @@
     ctor protected MockContentProvider();
     ctor public MockContentProvider(android.content.Context);
     ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
-    method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>);
     method public int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public java.lang.String getType(android.net.Uri);
     method public android.net.Uri insert(android.net.Uri, android.content.ContentValues);
     method public boolean onCreate();
-    method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
@@ -44595,10 +44832,6 @@
 
   public deprecated class MockResources extends android.content.res.Resources {
     ctor public MockResources();
-    method public int getColor(int) throws android.content.res.Resources.NotFoundException;
-    method public android.content.res.ColorStateList getColorStateList(int) throws android.content.res.Resources.NotFoundException;
-    method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
-    method public void updateConfiguration(android.content.res.Configuration, android.util.DisplayMetrics);
   }
 
 }
@@ -45846,7 +46079,6 @@
 
   public abstract class MetricAffectingSpan extends android.text.style.CharacterStyle implements android.text.style.UpdateLayout {
     ctor public MetricAffectingSpan();
-    method public android.text.style.MetricAffectingSpan getUnderlying();
     method public abstract void updateMeasureState(android.text.TextPaint);
   }
 
@@ -46527,28 +46759,14 @@
   public class TransitionSet extends android.transition.Transition {
     ctor public TransitionSet();
     ctor public TransitionSet(android.content.Context, android.util.AttributeSet);
-    method public android.transition.TransitionSet addListener(android.transition.Transition.TransitionListener);
-    method public android.transition.TransitionSet addTarget(android.view.View);
-    method public android.transition.TransitionSet addTarget(int);
-    method public android.transition.TransitionSet addTarget(java.lang.String);
-    method public android.transition.TransitionSet addTarget(java.lang.Class);
     method public android.transition.TransitionSet addTransition(android.transition.Transition);
     method public void captureEndValues(android.transition.TransitionValues);
     method public void captureStartValues(android.transition.TransitionValues);
-    method public android.transition.TransitionSet clone();
     method public int getOrdering();
     method public android.transition.Transition getTransitionAt(int);
     method public int getTransitionCount();
-    method public android.transition.TransitionSet removeListener(android.transition.Transition.TransitionListener);
-    method public android.transition.TransitionSet removeTarget(int);
-    method public android.transition.TransitionSet removeTarget(android.view.View);
-    method public android.transition.TransitionSet removeTarget(java.lang.Class);
-    method public android.transition.TransitionSet removeTarget(java.lang.String);
     method public android.transition.TransitionSet removeTransition(android.transition.Transition);
-    method public android.transition.TransitionSet setDuration(long);
-    method public android.transition.TransitionSet setInterpolator(android.animation.TimeInterpolator);
     method public android.transition.TransitionSet setOrdering(int);
-    method public android.transition.TransitionSet setStartDelay(long);
     field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
     field public static final int ORDERING_TOGETHER = 0; // 0x0
   }
@@ -46713,9 +46931,6 @@
 
   public class Base64InputStream extends java.io.FilterInputStream {
     ctor public Base64InputStream(java.io.InputStream, int);
-    method public int available();
-    method public void mark(int);
-    method public void reset();
   }
 
   public class Base64OutputStream extends java.io.FilterOutputStream {
@@ -48831,7 +49046,6 @@
     method public android.graphics.Canvas lockCanvas();
     method public android.graphics.Canvas lockCanvas(android.graphics.Rect);
     method protected final void onDraw(android.graphics.Canvas);
-    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setOpaque(boolean);
     method public void setSurfaceTexture(android.graphics.SurfaceTexture);
     method public void setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener);
@@ -49855,7 +50069,6 @@
     method public int getLayoutMode();
     method public android.animation.LayoutTransition getLayoutTransition();
     method public int getNestedScrollAxes();
-    method public android.view.ViewGroupOverlay getOverlay();
     method public int getPersistentDrawingCache();
     method public boolean getTouchscreenBlocksFocus();
     method public int indexOfChild(android.view.View);
@@ -50483,6 +50696,7 @@
   }
 
   public abstract interface WindowManager implements android.view.ViewManager {
+    method public abstract android.graphics.Region getCurrentImeTouchRegion();
     method public abstract android.view.Display getDefaultDisplay();
     method public abstract void removeViewImmediate(android.view.View);
   }
@@ -51129,7 +51343,6 @@
     ctor public Animation(android.content.Context, android.util.AttributeSet);
     method protected void applyTransformation(float, android.view.animation.Transformation);
     method public void cancel();
-    method protected android.view.animation.Animation clone() throws java.lang.CloneNotSupportedException;
     method public long computeDurationHint();
     method protected void ensureInterpolator();
     method public int getBackgroundColor();
@@ -51201,7 +51414,6 @@
     ctor public AnimationSet(android.content.Context, android.util.AttributeSet);
     ctor public AnimationSet(boolean);
     method public void addAnimation(android.view.animation.Animation);
-    method protected android.view.animation.AnimationSet clone() throws java.lang.CloneNotSupportedException;
     method public java.util.List<android.view.animation.Animation> getAnimations();
   }
 
@@ -52057,10 +52269,6 @@
   public final deprecated class CookieSyncManager extends android.webkit.WebSyncManager {
     method public static android.webkit.CookieSyncManager createInstance(android.content.Context);
     method public static android.webkit.CookieSyncManager getInstance();
-    method public deprecated void resetSync();
-    method public deprecated void startSync();
-    method public deprecated void stopSync();
-    method public deprecated void sync();
     method protected deprecated void syncFromRamToFlash();
     field protected static final java.lang.String LOGTAG = "websync";
     field protected android.webkit.WebViewDatabase mDataBase;
@@ -52701,7 +52909,6 @@
     method public void setWebChromeClient(android.webkit.WebChromeClient);
     method public static void setWebContentsDebuggingEnabled(boolean);
     method public void setWebViewClient(android.webkit.WebViewClient);
-    method public deprecated boolean shouldDelayChildPressedState();
     method public deprecated boolean showFindDialog(java.lang.String, boolean);
     method public void stopLoading();
     method public void zoomBy(float);
@@ -53096,7 +53303,6 @@
     method public void clearTextFilter();
     method public void deferNotifyDataSetChanged();
     method public void fling(int);
-    method public android.widget.AbsListView.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCacheColorHint();
     method public int getCheckedItemCount();
     method public long[] getCheckedItemIds();
@@ -53263,9 +53469,6 @@
     ctor public ActionMenuView(android.content.Context);
     ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
     method public void dismissPopupMenus();
-    method protected android.widget.ActionMenuView.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public android.view.Menu getMenu();
     method public android.graphics.drawable.Drawable getOverflowIcon();
     method public int getPopupTheme();
@@ -53441,6 +53644,7 @@
     method public void addAll(T...);
     method public void clear();
     method public static android.widget.ArrayAdapter<java.lang.CharSequence> createFromResource(android.content.Context, int, int);
+    method public java.lang.CharSequence[] getAutofillOptions();
     method public android.content.Context getContext();
     method public int getCount();
     method public android.content.res.Resources.Theme getDropDownViewTheme();
@@ -53808,7 +54012,6 @@
     ctor public EditText(android.content.Context, android.util.AttributeSet, int);
     ctor public EditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void extendSelection(int);
-    method public android.text.Editable getText();
     method public void selectAll();
     method public void setSelection(int, int);
     method public void setSelection(int);
@@ -53930,8 +54133,6 @@
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.FrameLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.FrameLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public deprecated boolean getConsiderGoneChildrenWhenMeasuring();
     method public boolean getMeasureAllChildren();
     method protected void onLayout(boolean, int, int, int, int);
@@ -53978,9 +54179,6 @@
     ctor public GridLayout(android.content.Context, android.util.AttributeSet);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.GridLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.GridLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.GridLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getAlignmentMode();
     method public int getColumnCount();
     method public int getOrientation();
@@ -54193,9 +54391,6 @@
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.LinearLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.LinearLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.LinearLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
@@ -54582,8 +54777,6 @@
     method public final synchronized void incrementSecondaryProgressBy(int);
     method public boolean isAnimating();
     method public synchronized boolean isIndeterminate();
-    method protected synchronized void onDraw(android.graphics.Canvas);
-    method protected synchronized void onMeasure(int, int);
     method public void onRestoreInstanceState(android.os.Parcelable);
     method public android.os.Parcelable onSaveInstanceState();
     method public synchronized void setIndeterminate(boolean);
@@ -54639,7 +54832,6 @@
     ctor public RadioGroup(android.content.Context, android.util.AttributeSet);
     method public void check(int);
     method public void clearCheck();
-    method public android.widget.RadioGroup.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCheckedRadioButtonId();
     method public void setOnCheckedChangeListener(android.widget.RadioGroup.OnCheckedChangeListener);
   }
@@ -54682,7 +54874,6 @@
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method public android.widget.RelativeLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getGravity();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setGravity(int);
@@ -55226,7 +55417,6 @@
   public class TableLayout extends android.widget.LinearLayout {
     ctor public TableLayout(android.content.Context);
     ctor public TableLayout(android.content.Context, android.util.AttributeSet);
-    method public android.widget.TableLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public boolean isColumnCollapsed(int);
     method public boolean isColumnShrinkable(int);
     method public boolean isColumnStretchable(int);
@@ -55251,7 +55441,6 @@
   public class TableRow extends android.widget.LinearLayout {
     ctor public TableRow(android.content.Context);
     ctor public TableRow(android.content.Context, android.util.AttributeSet);
-    method public android.widget.TableRow.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public android.view.View getVirtualChildAt(int);
     method public int getVirtualChildCount();
   }
@@ -55593,7 +55782,6 @@
     ctor public ToggleButton(android.content.Context);
     method public java.lang.CharSequence getTextOff();
     method public java.lang.CharSequence getTextOn();
-    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setTextOff(java.lang.CharSequence);
     method public void setTextOn(java.lang.CharSequence);
   }
@@ -55605,9 +55793,6 @@
     ctor public Toolbar(android.content.Context, android.util.AttributeSet, int, int);
     method public void collapseActionView();
     method public void dismissPopupMenus();
-    method protected android.widget.Toolbar.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.Toolbar.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.Toolbar.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getContentInsetEnd();
     method public int getContentInsetEndWithActions();
     method public int getContentInsetLeft();
@@ -55885,6 +56070,8 @@
     field public static final int OP_CONST_CLASS = 28; // 0x1c
     field public static final int OP_CONST_CLASS_JUMBO = 255; // 0xff
     field public static final int OP_CONST_HIGH16 = 21; // 0x15
+    field public static final int OP_CONST_METHOD_HANDLE = 254; // 0xfe
+    field public static final int OP_CONST_METHOD_TYPE = 255; // 0xff
     field public static final int OP_CONST_STRING = 26; // 0x1a
     field public static final int OP_CONST_STRING_JUMBO = 27; // 0x1b
     field public static final int OP_CONST_WIDE = 24; // 0x18
@@ -56129,8 +56316,6 @@
   public class BaseDexClassLoader extends java.lang.ClassLoader {
     ctor public BaseDexClassLoader(java.lang.String, java.io.File, java.lang.String, java.lang.ClassLoader);
     method public java.lang.String findLibrary(java.lang.String);
-    method protected java.util.Enumeration<java.net.URL> findResources(java.lang.String);
-    method protected synchronized java.lang.Package getPackage(java.lang.String);
   }
 
   public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
@@ -56353,10 +56538,6 @@
   public class BufferedInputStream extends java.io.FilterInputStream {
     ctor public BufferedInputStream(java.io.InputStream);
     ctor public BufferedInputStream(java.io.InputStream, int);
-    method public synchronized int available() throws java.io.IOException;
-    method public synchronized int read() throws java.io.IOException;
-    method public synchronized int read(byte[], int, int) throws java.io.IOException;
-    method public synchronized long skip(long) throws java.io.IOException;
     field protected volatile byte[] buf;
     field protected int count;
     field protected int marklimit;
@@ -56367,9 +56548,6 @@
   public class BufferedOutputStream extends java.io.FilterOutputStream {
     ctor public BufferedOutputStream(java.io.OutputStream);
     ctor public BufferedOutputStream(java.io.OutputStream, int);
-    method public synchronized void flush() throws java.io.IOException;
-    method public synchronized void write(int) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
   }
@@ -56395,12 +56573,7 @@
   public class ByteArrayInputStream extends java.io.InputStream {
     ctor public ByteArrayInputStream(byte[]);
     ctor public ByteArrayInputStream(byte[], int, int);
-    method public synchronized int available();
-    method public void mark(int);
     method public synchronized int read();
-    method public synchronized int read(byte[], int, int);
-    method public synchronized void reset();
-    method public synchronized long skip(long);
     field protected byte[] buf;
     field protected int count;
     field protected int mark;
@@ -56413,11 +56586,9 @@
     method public synchronized void reset();
     method public synchronized int size();
     method public synchronized byte[] toByteArray();
-    method public synchronized java.lang.String toString();
     method public synchronized java.lang.String toString(java.lang.String) throws java.io.UnsupportedEncodingException;
     method public deprecated synchronized java.lang.String toString(int);
     method public synchronized void write(int);
-    method public synchronized void write(byte[], int, int);
     method public synchronized void writeTo(java.io.OutputStream) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
@@ -56437,17 +56608,12 @@
   public class CharArrayWriter extends java.io.Writer {
     ctor public CharArrayWriter();
     ctor public CharArrayWriter(int);
-    method public java.io.CharArrayWriter append(java.lang.CharSequence);
-    method public java.io.CharArrayWriter append(java.lang.CharSequence, int, int);
-    method public java.io.CharArrayWriter append(char);
     method public void close();
     method public void flush();
     method public void reset();
     method public int size();
     method public char[] toCharArray();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(java.lang.String, int, int);
     method public void writeTo(java.io.Writer) throws java.io.IOException;
     field protected char[] buf;
     field protected int count;
@@ -56534,8 +56700,6 @@
   public class DataOutputStream extends java.io.FilterOutputStream implements java.io.DataOutput {
     ctor public DataOutputStream(java.io.OutputStream);
     method public final int size();
-    method public synchronized void write(int) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     method public final void writeBoolean(boolean) throws java.io.IOException;
     method public final void writeByte(int) throws java.io.IOException;
     method public final void writeBytes(java.lang.String) throws java.io.IOException;
@@ -56635,7 +56799,6 @@
     ctor public FileInputStream(java.lang.String) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.FileDescriptor);
-    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public int read() throws java.io.IOException;
@@ -56652,7 +56815,6 @@
     ctor public FileOutputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.File, boolean) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.FileDescriptor);
-    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
@@ -56766,8 +56928,6 @@
   public deprecated class LineNumberInputStream extends java.io.FilterInputStream {
     ctor public LineNumberInputStream(java.io.InputStream);
     method public int getLineNumber();
-    method public void mark(int);
-    method public void reset() throws java.io.IOException;
     method public void setLineNumber(int);
   }
 
@@ -56997,10 +57157,8 @@
     ctor public PipedInputStream(java.io.PipedOutputStream, int) throws java.io.IOException;
     ctor public PipedInputStream();
     ctor public PipedInputStream(int);
-    method public synchronized int available() throws java.io.IOException;
     method public void connect(java.io.PipedOutputStream) throws java.io.IOException;
     method public synchronized int read() throws java.io.IOException;
-    method public synchronized int read(byte[], int, int) throws java.io.IOException;
     method protected synchronized void receive(int) throws java.io.IOException;
     field protected static final int PIPE_SIZE = 1024; // 0x400
     field protected byte[] buffer;
@@ -57012,7 +57170,6 @@
     ctor public PipedOutputStream(java.io.PipedInputStream) throws java.io.IOException;
     ctor public PipedOutputStream();
     method public synchronized void connect(java.io.PipedInputStream) throws java.io.IOException;
-    method public synchronized void flush() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
   }
 
@@ -57023,9 +57180,7 @@
     ctor public PipedReader(int);
     method public void close() throws java.io.IOException;
     method public void connect(java.io.PipedWriter) throws java.io.IOException;
-    method public synchronized int read() throws java.io.IOException;
     method public synchronized int read(char[], int, int) throws java.io.IOException;
-    method public synchronized boolean ready() throws java.io.IOException;
   }
 
   public class PipedWriter extends java.io.Writer {
@@ -57050,8 +57205,6 @@
     method public java.io.PrintStream append(char);
     method public boolean checkError();
     method protected void clearError();
-    method public void close();
-    method public void flush();
     method public java.io.PrintStream format(java.lang.String, java.lang.Object...);
     method public java.io.PrintStream format(java.util.Locale, java.lang.String, java.lang.Object...);
     method public void print(boolean);
@@ -57076,8 +57229,6 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
-    method public void write(int);
-    method public void write(byte[], int, int);
   }
 
   public class PrintWriter extends java.io.Writer {
@@ -57089,9 +57240,6 @@
     ctor public PrintWriter(java.lang.String, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
     ctor public PrintWriter(java.io.File) throws java.io.FileNotFoundException;
     ctor public PrintWriter(java.io.File, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
-    method public java.io.PrintWriter append(java.lang.CharSequence);
-    method public java.io.PrintWriter append(java.lang.CharSequence, int, int);
-    method public java.io.PrintWriter append(char);
     method public boolean checkError();
     method protected void clearError();
     method public void close();
@@ -57120,18 +57268,13 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(char[]);
-    method public void write(java.lang.String, int, int);
-    method public void write(java.lang.String);
     field protected java.io.Writer out;
   }
 
   public class PushbackInputStream extends java.io.FilterInputStream {
     ctor public PushbackInputStream(java.io.InputStream, int);
     ctor public PushbackInputStream(java.io.InputStream);
-    method public synchronized void close() throws java.io.IOException;
     method public void unread(int) throws java.io.IOException;
     method public void unread(byte[], int, int) throws java.io.IOException;
     method public void unread(byte[]) throws java.io.IOException;
@@ -57255,11 +57398,7 @@
 
   public deprecated class StringBufferInputStream extends java.io.InputStream {
     ctor public StringBufferInputStream(java.lang.String);
-    method public synchronized int available();
     method public synchronized int read();
-    method public synchronized int read(byte[], int, int);
-    method public synchronized void reset();
-    method public synchronized long skip(long);
     field protected java.lang.String buffer;
     field protected int count;
     field protected int pos;
@@ -57274,16 +57413,10 @@
   public class StringWriter extends java.io.Writer {
     ctor public StringWriter();
     ctor public StringWriter(int);
-    method public java.io.StringWriter append(java.lang.CharSequence);
-    method public java.io.StringWriter append(java.lang.CharSequence, int, int);
-    method public java.io.StringWriter append(char);
     method public void close() throws java.io.IOException;
     method public void flush();
     method public java.lang.StringBuffer getBuffer();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(java.lang.String);
-    method public void write(java.lang.String, int, int);
   }
 
   public class SyncFailedException extends java.io.IOException {
@@ -57298,7 +57431,6 @@
   public class UncheckedIOException extends java.lang.RuntimeException {
     ctor public UncheckedIOException(java.lang.String, java.io.IOException);
     ctor public UncheckedIOException(java.io.IOException);
-    method public java.io.IOException getCause();
   }
 
   public class UnsupportedEncodingException extends java.io.IOException {
@@ -57308,7 +57440,6 @@
 
   public class WriteAbortedException extends java.io.ObjectStreamException {
     ctor public WriteAbortedException(java.lang.String, java.lang.Exception);
-    method public java.lang.Throwable getCause();
     field public java.lang.Exception detail;
   }
 
@@ -58076,7 +58207,6 @@
     ctor public ClassNotFoundException();
     ctor public ClassNotFoundException(java.lang.String);
     ctor public ClassNotFoundException(java.lang.String, java.lang.Throwable);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -58181,7 +58311,6 @@
     ctor public ExceptionInInitializerError();
     ctor public ExceptionInInitializerError(java.lang.Throwable);
     ctor public ExceptionInInitializerError(java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -58969,16 +59098,8 @@
     method public synchronized java.lang.StringBuffer append(float);
     method public synchronized java.lang.StringBuffer append(double);
     method public synchronized java.lang.StringBuffer appendCodePoint(int);
-    method public synchronized int capacity();
-    method public synchronized char charAt(int);
-    method public synchronized int codePointAt(int);
-    method public synchronized int codePointBefore(int);
-    method public synchronized int codePointCount(int, int);
     method public synchronized java.lang.StringBuffer delete(int, int);
     method public synchronized java.lang.StringBuffer deleteCharAt(int);
-    method public synchronized void ensureCapacity(int);
-    method public synchronized void getChars(int, int, char[], int);
-    method public synchronized int indexOf(java.lang.String, int);
     method public synchronized java.lang.StringBuffer insert(int, char[], int, int);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.Object);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.String);
@@ -58991,18 +59112,9 @@
     method public java.lang.StringBuffer insert(int, long);
     method public java.lang.StringBuffer insert(int, float);
     method public java.lang.StringBuffer insert(int, double);
-    method public synchronized int lastIndexOf(java.lang.String, int);
-    method public synchronized int length();
-    method public synchronized int offsetByCodePoints(int, int);
     method public synchronized java.lang.StringBuffer replace(int, int, java.lang.String);
     method public synchronized java.lang.StringBuffer reverse();
-    method public synchronized void setCharAt(int, char);
-    method public synchronized void setLength(int);
-    method public synchronized java.lang.CharSequence subSequence(int, int);
-    method public synchronized java.lang.String substring(int);
-    method public synchronized java.lang.String substring(int, int);
     method public synchronized java.lang.String toString();
-    method public synchronized void trimToSize();
   }
 
   public final class StringBuilder extends java.lang.AbstractStringBuilder implements java.lang.CharSequence java.io.Serializable {
@@ -59657,7 +59769,6 @@
     ctor protected InvocationTargetException();
     ctor public InvocationTargetException(java.lang.Throwable);
     ctor public InvocationTargetException(java.lang.Throwable, java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getTargetException();
   }
 
@@ -59773,7 +59884,6 @@
   public class UndeclaredThrowableException extends java.lang.RuntimeException {
     ctor public UndeclaredThrowableException(java.lang.Throwable);
     ctor public UndeclaredThrowableException(java.lang.Throwable, java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getUndeclaredThrowable();
   }
 
@@ -60671,7 +60781,6 @@
     method public java.lang.String getQuery();
     method public java.lang.String getRef();
     method public java.lang.String getUserInfo();
-    method public synchronized int hashCode();
     method public java.net.URLConnection openConnection() throws java.io.IOException;
     method public java.net.URLConnection openConnection(java.net.Proxy) throws java.io.IOException;
     method public final java.io.InputStream openStream() throws java.io.IOException;
@@ -60901,6 +61010,7 @@
     method public final int arrayOffset();
     method public abstract java.nio.CharBuffer asReadOnlyBuffer();
     method public final char charAt(int);
+    method public java.util.stream.IntStream chars();
     method public abstract java.nio.CharBuffer compact();
     method public int compareTo(java.nio.CharBuffer);
     method public abstract java.nio.CharBuffer duplicate();
@@ -61757,7 +61867,6 @@
 
   public final class DirectoryIteratorException extends java.util.ConcurrentModificationException {
     ctor public DirectoryIteratorException(java.io.IOException);
-    method public java.io.IOException getCause();
   }
 
   public class DirectoryNotEmptyException extends java.nio.file.FileSystemException {
@@ -62723,11 +62832,9 @@
   public static class KeyStore.PasswordProtection implements javax.security.auth.Destroyable java.security.KeyStore.ProtectionParameter {
     ctor public KeyStore.PasswordProtection(char[]);
     ctor public KeyStore.PasswordProtection(char[], java.lang.String, java.security.spec.AlgorithmParameterSpec);
-    method public synchronized void destroy() throws javax.security.auth.DestroyFailedException;
     method public synchronized char[] getPassword();
     method public java.lang.String getProtectionAlgorithm();
     method public java.security.spec.AlgorithmParameterSpec getProtectionParameters();
-    method public synchronized boolean isDestroyed();
   }
 
   public static final class KeyStore.PrivateKeyEntry implements java.security.KeyStore.Entry {
@@ -62907,7 +63014,6 @@
 
   public class PrivilegedActionException extends java.lang.Exception {
     ctor public PrivilegedActionException(java.lang.Exception);
-    method public java.lang.Throwable getCause();
     method public java.lang.Exception getException();
   }
 
@@ -62930,30 +63036,22 @@
     method public synchronized java.lang.Object compute(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfAbsent(java.lang.Object, java.util.function.Function<? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfPresent(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
-    method public java.util.Enumeration<java.lang.Object> elements();
-    method public synchronized java.util.Set<java.util.Map.Entry<java.lang.Object, java.lang.Object>> entrySet();
     method public synchronized void forEach(java.util.function.BiConsumer<? super java.lang.Object, ? super java.lang.Object>);
-    method public java.lang.Object get(java.lang.Object);
     method public java.lang.String getInfo();
     method public java.lang.String getName();
     method public synchronized java.lang.Object getOrDefault(java.lang.Object, java.lang.Object);
     method public synchronized java.security.Provider.Service getService(java.lang.String, java.lang.String);
     method public synchronized java.util.Set<java.security.Provider.Service> getServices();
     method public double getVersion();
-    method public java.util.Set<java.lang.Object> keySet();
-    method public java.util.Enumeration<java.lang.Object> keys();
     method public synchronized java.lang.Object merge(java.lang.Object, java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object put(java.lang.Object, java.lang.Object);
     method public synchronized void putAll(java.util.Map<?, ?>);
     method public synchronized java.lang.Object putIfAbsent(java.lang.Object, java.lang.Object);
     method protected synchronized void putService(java.security.Provider.Service);
-    method public synchronized java.lang.Object remove(java.lang.Object);
     method protected synchronized void removeService(java.security.Provider.Service);
     method public synchronized boolean replace(java.lang.Object, java.lang.Object, java.lang.Object);
     method public synchronized java.lang.Object replace(java.lang.Object, java.lang.Object);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
-    method public java.lang.String toString();
-    method public java.util.Collection<java.lang.Object> values();
   }
 
   public static class Provider.Service {
@@ -62999,9 +63097,7 @@
     method public final java.security.Provider getProvider();
     method public static byte[] getSeed(int);
     method protected final int next(int);
-    method public synchronized void nextBytes(byte[]);
     method public synchronized void setSeed(byte[]);
-    method public void setSeed(long);
   }
 
   public abstract class SecureRandomSpi implements java.io.Serializable {
@@ -63548,7 +63644,6 @@
 
   public abstract class PKIXRevocationChecker extends java.security.cert.PKIXCertPathChecker {
     ctor protected PKIXRevocationChecker();
-    method public java.security.cert.PKIXRevocationChecker clone();
     method public java.util.List<java.security.cert.Extension> getOcspExtensions();
     method public java.net.URI getOcspResponder();
     method public java.security.cert.X509Certificate getOcspResponderCert();
@@ -65801,6 +65896,7 @@
   public final class DayOfWeek extends java.lang.Enum implements java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public static java.time.DayOfWeek from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -65808,6 +65904,8 @@
     method public java.time.DayOfWeek minus(long);
     method public static java.time.DayOfWeek of(int);
     method public java.time.DayOfWeek plus(long);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.DayOfWeek valueOf(java.lang.String);
     method public static final java.time.DayOfWeek[] values();
     enum_constant public static final java.time.DayOfWeek FRIDAY;
@@ -65883,8 +65981,6 @@
     method public boolean isBefore(java.time.Instant);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.Instant minus(java.time.temporal.TemporalAmount);
-    method public java.time.Instant minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant minusMillis(long);
     method public java.time.Instant minusNanos(long);
     method public java.time.Instant minusSeconds(long);
@@ -65894,7 +65990,6 @@
     method public static java.time.Instant ofEpochSecond(long);
     method public static java.time.Instant ofEpochSecond(long, long);
     method public static java.time.Instant parse(java.lang.CharSequence);
-    method public java.time.Instant plus(java.time.temporal.TemporalAmount);
     method public java.time.Instant plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant plusMillis(long);
     method public java.time.Instant plusNanos(long);
@@ -65902,7 +65997,6 @@
     method public long toEpochMilli();
     method public java.time.Instant truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Instant with(java.time.temporal.TemporalAdjuster);
     method public java.time.Instant with(java.time.temporal.TemporalField, long);
     field public static final java.time.Instant EPOCH;
     field public static final java.time.Instant MAX;
@@ -65912,7 +66006,6 @@
   public final class LocalDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
     method public java.time.LocalDateTime atStartOfDay();
     method public java.time.ZonedDateTime atStartOfDay(java.time.ZoneId);
-    method public java.time.LocalDateTime atTime(java.time.LocalTime);
     method public java.time.LocalDateTime atTime(int, int);
     method public java.time.LocalDateTime atTime(int, int, int);
     method public java.time.LocalDateTime atTime(int, int, int, int);
@@ -65927,8 +66020,6 @@
     method public int getMonthValue();
     method public int getYear();
     method public int lengthOfMonth();
-    method public java.time.LocalDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDate minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate minusDays(long);
     method public java.time.LocalDate minusMonths(long);
     method public java.time.LocalDate minusWeeks(long);
@@ -65942,16 +66033,12 @@
     method public static java.time.LocalDate ofYearDay(int, int);
     method public static java.time.LocalDate parse(java.lang.CharSequence);
     method public static java.time.LocalDate parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate plusDays(long);
     method public java.time.LocalDate plusMonths(long);
     method public java.time.LocalDate plusWeeks(long);
     method public java.time.LocalDate plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public java.time.Period until(java.time.chrono.ChronoLocalDate);
-    method public java.time.LocalDate with(java.time.temporal.TemporalAdjuster);
-    method public java.time.LocalDate with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDate withDayOfMonth(int);
     method public java.time.LocalDate withDayOfYear(int);
     method public java.time.LocalDate withMonth(int);
@@ -65976,8 +66063,6 @@
     method public int getSecond();
     method public int getYear();
     method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.LocalDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime minusDays(long);
     method public java.time.LocalDateTime minusHours(long);
     method public java.time.LocalDateTime minusMinutes(long);
@@ -66000,7 +66085,6 @@
     method public static java.time.LocalDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime plusDays(long);
     method public java.time.LocalDateTime plusHours(long);
@@ -66014,7 +66098,6 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.LocalDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.LocalDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDateTime withDayOfMonth(int);
     method public java.time.LocalDateTime withDayOfYear(int);
@@ -66044,8 +66127,6 @@
     method public boolean isBefore(java.time.LocalTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime minusHours(long);
     method public java.time.LocalTime minusMinutes(long);
     method public java.time.LocalTime minusNanos(long);
@@ -66060,7 +66141,6 @@
     method public static java.time.LocalTime ofSecondOfDay(long);
     method public static java.time.LocalTime parse(java.lang.CharSequence);
     method public static java.time.LocalTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime plusHours(long);
     method public java.time.LocalTime plusMinutes(long);
@@ -66070,7 +66150,6 @@
     method public int toSecondOfDay();
     method public java.time.LocalTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalTime withHour(int);
     method public java.time.LocalTime withMinute(int);
@@ -66087,6 +66166,7 @@
     method public int firstDayOfYear(boolean);
     method public java.time.Month firstMonthOfQuarter();
     method public static java.time.Month from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -66097,6 +66177,8 @@
     method public java.time.Month minus(long);
     method public static java.time.Month of(int);
     method public java.time.Month plus(long);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.Month valueOf(java.lang.String);
     method public static final java.time.Month[] values();
     enum_constant public static final java.time.Month APRIL;
@@ -66163,8 +66245,6 @@
     method public boolean isEqual(java.time.OffsetDateTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime minusDays(long);
     method public java.time.OffsetDateTime minusHours(long);
     method public java.time.OffsetDateTime minusMinutes(long);
@@ -66182,7 +66262,6 @@
     method public static java.time.OffsetDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.OffsetDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime plusDays(long);
     method public java.time.OffsetDateTime plusHours(long);
@@ -66202,7 +66281,6 @@
     method public java.time.ZonedDateTime toZonedDateTime();
     method public java.time.OffsetDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetDateTime withDayOfMonth(int);
     method public java.time.OffsetDateTime withDayOfYear(int);
@@ -66235,8 +66313,6 @@
     method public boolean isEqual(java.time.OffsetTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime minusHours(long);
     method public java.time.OffsetTime minusMinutes(long);
     method public java.time.OffsetTime minusNanos(long);
@@ -66249,7 +66325,6 @@
     method public static java.time.OffsetTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetTime parse(java.lang.CharSequence);
     method public static java.time.OffsetTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.OffsetTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime plusHours(long);
     method public java.time.OffsetTime plusMinutes(long);
@@ -66258,7 +66333,6 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.OffsetTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetTime withHour(int);
     method public java.time.OffsetTime withMinute(int);
@@ -66285,7 +66359,6 @@
     method public java.time.Period minusMonths(long);
     method public java.time.Period minusYears(long);
     method public java.time.Period multipliedBy(int);
-    method public java.time.Period negated();
     method public java.time.Period normalized();
     method public static java.time.Period of(int, int, int);
     method public static java.time.Period ofDays(int);
@@ -66324,8 +66397,6 @@
     method public boolean isSupported(java.time.temporal.TemporalUnit);
     method public boolean isValidMonthDay(java.time.MonthDay);
     method public int length();
-    method public java.time.Year minus(java.time.temporal.TemporalAmount);
-    method public java.time.Year minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year minusYears(long);
     method public static java.time.Year now();
     method public static java.time.Year now(java.time.ZoneId);
@@ -66333,11 +66404,9 @@
     method public static java.time.Year of(int);
     method public static java.time.Year parse(java.lang.CharSequence);
     method public static java.time.Year parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.Year plus(java.time.temporal.TemporalAmount);
     method public java.time.Year plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Year with(java.time.temporal.TemporalAdjuster);
     method public java.time.Year with(java.time.temporal.TemporalField, long);
     field public static final int MAX_VALUE = 999999999; // 0x3b9ac9ff
     field public static final int MIN_VALUE = -999999999; // 0xc4653601
@@ -66362,8 +66431,6 @@
     method public boolean isValidDay(int);
     method public int lengthOfMonth();
     method public int lengthOfYear();
-    method public java.time.YearMonth minus(java.time.temporal.TemporalAmount);
-    method public java.time.YearMonth minus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth minusMonths(long);
     method public java.time.YearMonth minusYears(long);
     method public static java.time.YearMonth now();
@@ -66373,12 +66440,10 @@
     method public static java.time.YearMonth of(int, int);
     method public static java.time.YearMonth parse(java.lang.CharSequence);
     method public static java.time.YearMonth parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.YearMonth plus(java.time.temporal.TemporalAmount);
     method public java.time.YearMonth plus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth plusMonths(long);
     method public java.time.YearMonth plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.YearMonth with(java.time.temporal.TemporalAdjuster);
     method public java.time.YearMonth with(java.time.temporal.TemporalField, long);
     method public java.time.YearMonth withMonth(int);
     method public java.time.YearMonth withYear(int);
@@ -66402,6 +66467,7 @@
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public int compareTo(java.time.ZoneOffset);
     method public static java.time.ZoneOffset from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getId();
     method public long getLong(java.time.temporal.TemporalField);
     method public java.time.zone.ZoneRules getRules();
@@ -66412,6 +66478,8 @@
     method public static java.time.ZoneOffset ofHoursMinutes(int, int);
     method public static java.time.ZoneOffset ofHoursMinutesSeconds(int, int, int);
     method public static java.time.ZoneOffset ofTotalSeconds(int);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     field public static final java.time.ZoneOffset MAX;
     field public static final java.time.ZoneOffset MIN;
     field public static final java.time.ZoneOffset UTC;
@@ -66432,8 +66500,6 @@
     method public int getYear();
     method public java.time.ZoneId getZone();
     method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.ZonedDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.ZonedDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime minusDays(long);
     method public java.time.ZonedDateTime minusHours(long);
     method public java.time.ZonedDateTime minusMinutes(long);
@@ -66454,7 +66520,6 @@
     method public static java.time.ZonedDateTime ofStrict(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneId);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.ZonedDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.ZonedDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime plusDays(long);
     method public java.time.ZonedDateTime plusHours(long);
@@ -66464,12 +66529,10 @@
     method public java.time.ZonedDateTime plusSeconds(long);
     method public java.time.ZonedDateTime plusWeeks(long);
     method public java.time.ZonedDateTime plusYears(long);
-    method public java.time.LocalDate toLocalDate();
     method public java.time.LocalDateTime toLocalDateTime();
     method public java.time.OffsetDateTime toOffsetDateTime();
     method public java.time.ZonedDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.ZonedDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.ZonedDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.ZonedDateTime withDayOfMonth(int);
     method public java.time.ZonedDateTime withDayOfYear(int);
@@ -66514,27 +66577,17 @@
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
     method public abstract int lengthOfMonth();
     method public default int lengthOfYear();
-    method public default java.time.chrono.ChronoLocalDate minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDate minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDate plus(java.time.temporal.TemporalAmount);
     method public default java.time.chrono.ChronoLocalDate plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDate> timeLineOrder();
     method public default long toEpochDay();
     method public abstract java.lang.String toString();
     method public abstract long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public abstract java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalAdjuster);
     method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalField, long);
   }
 
    abstract class ChronoLocalDateImpl<D extends java.time.chrono.ChronoLocalDate> implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public D minus(java.time.temporal.TemporalAmount);
-    method public D minus(long, java.time.temporal.TemporalUnit);
-    method public D plus(java.time.temporal.TemporalAmount);
-    method public D plus(long, java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public D with(java.time.temporal.TemporalAdjuster);
-    method public D with(java.time.temporal.TemporalField, long);
   }
 
   public abstract interface ChronoLocalDateTime<D extends java.time.chrono.ChronoLocalDate> implements java.lang.Comparable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
@@ -66551,9 +66604,6 @@
     method public default boolean isEqual(java.time.chrono.ChronoLocalDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDateTime<D> minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDateTime<D> minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDateTime<?>> timeLineOrder();
     method public default long toEpochSecond(java.time.ZoneOffset);
@@ -66561,7 +66611,6 @@
     method public abstract D toLocalDate();
     method public abstract java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
-    method public default java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalField, long);
   }
 
@@ -66599,9 +66648,6 @@
     method public default boolean isEqual(java.time.chrono.ChronoZonedDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoZonedDateTime<D> minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoZonedDateTime<D> minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoZonedDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoZonedDateTime<?>> timeLineOrder();
     method public default long toEpochSecond();
@@ -66610,7 +66656,6 @@
     method public abstract java.time.chrono.ChronoLocalDateTime<D> toLocalDateTime();
     method public default java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
-    method public default java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalField, long);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withEarlierOffsetAtOverlap();
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withLaterOffsetAtOverlap();
@@ -66677,7 +66722,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.HijrahDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.HijrahDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.HijrahChronology INSTANCE;
@@ -66689,24 +66733,23 @@
     method public java.time.chrono.HijrahChronology getChronology();
     method public java.time.chrono.HijrahEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
+    method public boolean isLeapYear();
     method public int lengthOfMonth();
-    method public java.time.chrono.HijrahDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.HijrahDate minus(long, java.time.temporal.TemporalUnit);
+    method public int lengthOfYear();
     method public static java.time.chrono.HijrahDate now();
     method public static java.time.chrono.HijrahDate now(java.time.ZoneId);
     method public static java.time.chrono.HijrahDate now(java.time.Clock);
     method public static java.time.chrono.HijrahDate of(int, int, int);
-    method public java.time.chrono.HijrahDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.HijrahDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalAdjuster);
     method public java.time.chrono.HijrahDate withVariant(java.time.chrono.HijrahChronology);
   }
 
   public final class HijrahEra extends java.lang.Enum implements java.time.chrono.Era {
     method public int getValue();
     method public static java.time.chrono.HijrahEra of(int);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.chrono.HijrahEra valueOf(java.lang.String);
     method public static final java.time.chrono.HijrahEra[] values();
     enum_constant public static final java.time.chrono.HijrahEra AH;
@@ -66731,7 +66774,6 @@
     method public java.time.Period period(int, int, int);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.LocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.ZonedDateTime zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.ZonedDateTime zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.IsoChronology INSTANCE;
@@ -66764,7 +66806,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.JapaneseDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.JapaneseDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.JapaneseChronology INSTANCE;
@@ -66776,19 +66817,17 @@
     method public java.time.chrono.JapaneseChronology getChronology();
     method public java.time.chrono.JapaneseEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
+    method public boolean isSupported(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.JapaneseDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.JapaneseDate minus(long, java.time.temporal.TemporalUnit);
+    method public int lengthOfYear();
     method public static java.time.chrono.JapaneseDate now();
     method public static java.time.chrono.JapaneseDate now(java.time.ZoneId);
     method public static java.time.chrono.JapaneseDate now(java.time.Clock);
     method public static java.time.chrono.JapaneseDate of(java.time.chrono.JapaneseEra, int, int, int);
     method public static java.time.chrono.JapaneseDate of(int, int, int);
-    method public java.time.chrono.JapaneseDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.JapaneseDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class JapaneseEra implements java.time.chrono.Era java.io.Serializable {
@@ -66820,7 +66859,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.MinguoDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.MinguoDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.MinguoChronology INSTANCE;
@@ -66833,17 +66871,13 @@
     method public java.time.chrono.MinguoEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.MinguoDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.MinguoDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.MinguoDate now();
     method public static java.time.chrono.MinguoDate now(java.time.ZoneId);
     method public static java.time.chrono.MinguoDate now(java.time.Clock);
     method public static java.time.chrono.MinguoDate of(int, int, int);
-    method public java.time.chrono.MinguoDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.MinguoDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class MinguoEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -66873,7 +66907,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.ThaiBuddhistDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.ThaiBuddhistDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.ThaiBuddhistChronology INSTANCE;
@@ -66886,17 +66919,13 @@
     method public java.time.chrono.ThaiBuddhistEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.ThaiBuddhistDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ThaiBuddhistDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.ThaiBuddhistDate now();
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.ZoneId);
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.Clock);
     method public static java.time.chrono.ThaiBuddhistDate of(int, int, int);
-    method public java.time.chrono.ThaiBuddhistDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ThaiBuddhistDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class ThaiBuddhistEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -67075,6 +67104,7 @@
     method public int checkValidIntValue(long);
     method public long checkValidValue(long);
     method public java.time.temporal.TemporalUnit getBaseUnit();
+    method public java.lang.String getDisplayName(java.util.Locale);
     method public long getFrom(java.time.temporal.TemporalAccessor);
     method public java.time.temporal.TemporalUnit getRangeUnit();
     method public boolean isDateBased();
@@ -67122,6 +67152,7 @@
     method public java.time.Duration getDuration();
     method public boolean isDateBased();
     method public boolean isDurationEstimated();
+    method public boolean isSupportedBy(java.time.temporal.Temporal);
     method public boolean isTimeBased();
     method public static java.time.temporal.ChronoUnit valueOf(java.lang.String);
     method public static final java.time.temporal.ChronoUnit[] values();
@@ -67461,6 +67492,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ArrayList<E> extends java.util.AbstractList implements java.lang.Cloneable java.util.List java.util.RandomAccess java.io.Serializable {
@@ -67471,7 +67503,11 @@
     method public void ensureCapacity(int);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public E get(int);
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
+    method public void replaceAll(java.util.function.UnaryOperator<E>);
     method public int size();
+    method public void sort(java.util.Comparator<? super E>);
+    method public java.util.Spliterator<E> spliterator();
     method public void trimToSize();
   }
 
@@ -67842,7 +67878,6 @@
     method public default boolean removeIf(java.util.function.Predicate<? super E>);
     method public abstract boolean retainAll(java.util.Collection<?>);
     method public abstract int size();
-    method public default java.util.Spliterator<E> spliterator();
     method public default java.util.stream.Stream<E> stream();
     method public abstract java.lang.Object[] toArray();
     method public abstract <T> T[] toArray(T[]);
@@ -68183,7 +68218,18 @@
     ctor public HashMap();
     ctor public HashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
+    method public V putIfAbsent(K, V);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class HashSet<E> extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set {
@@ -68194,6 +68240,7 @@
     method public java.lang.Object clone();
     method public java.util.Iterator<E> iterator();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class Hashtable<K, V> extends java.util.Dictionary implements java.lang.Cloneable java.util.Map java.io.Serializable {
@@ -68211,11 +68258,9 @@
     method public boolean containsValue(java.lang.Object);
     method public synchronized java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
-    method public synchronized boolean equals(java.lang.Object);
     method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public synchronized V get(java.lang.Object);
     method public synchronized V getOrDefault(java.lang.Object, V);
-    method public synchronized int hashCode();
     method public synchronized boolean isEmpty();
     method public java.util.Set<K> keySet();
     method public synchronized java.util.Enumeration<K> keys();
@@ -68230,7 +68275,6 @@
     method public synchronized V replace(K, V);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public synchronized int size();
-    method public synchronized java.lang.String toString();
     method public java.util.Collection<V> values();
   }
 
@@ -68240,6 +68284,8 @@
     ctor public IdentityHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class IllegalFormatCodePointException extends java.util.IllegalFormatException {
@@ -68350,6 +68396,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface List<E> implements java.util.Collection {
@@ -68972,7 +69019,6 @@
     ctor public SimpleTimeZone(int, java.lang.String, int, int, int, int, int, int, int, int, int, int, int);
     method public int getOffset(int, int, int, int, int, int);
     method public int getRawOffset();
-    method public synchronized int hashCode();
     method public boolean inDaylightTime(java.util.Date);
     method public void setDSTSavings(int);
     method public void setEndRule(int, int, int, int);
@@ -69245,6 +69291,7 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public java.util.NavigableMap<K, V> headMap(K, boolean);
     method public java.util.SortedMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
@@ -69256,6 +69303,9 @@
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.SortedMap<K, V> subMap(K, K);
     method public java.util.NavigableMap<K, V> tailMap(K, boolean);
@@ -69283,6 +69333,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.SortedSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -69319,49 +69370,30 @@
     ctor public Vector(int);
     ctor public Vector();
     ctor public Vector(java.util.Collection<? extends E>);
-    method public synchronized boolean add(E);
-    method public synchronized boolean addAll(java.util.Collection<? extends E>);
-    method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
     method public synchronized void addElement(E);
     method public synchronized int capacity();
     method public synchronized java.lang.Object clone();
-    method public synchronized boolean containsAll(java.util.Collection<?>);
     method public synchronized void copyInto(java.lang.Object[]);
     method public synchronized E elementAt(int);
     method public java.util.Enumeration<E> elements();
     method public synchronized void ensureCapacity(int);
-    method public synchronized boolean equals(java.lang.Object);
     method public synchronized E firstElement();
     method public synchronized void forEach(java.util.function.Consumer<? super E>);
     method public synchronized E get(int);
-    method public synchronized int hashCode();
     method public synchronized int indexOf(java.lang.Object, int);
     method public synchronized void insertElementAt(E, int);
-    method public synchronized boolean isEmpty();
-    method public synchronized java.util.Iterator<E> iterator();
     method public synchronized E lastElement();
-    method public synchronized int lastIndexOf(java.lang.Object);
     method public synchronized int lastIndexOf(java.lang.Object, int);
-    method public synchronized java.util.ListIterator<E> listIterator(int);
-    method public synchronized java.util.ListIterator<E> listIterator();
-    method public synchronized E remove(int);
-    method public synchronized boolean removeAll(java.util.Collection<?>);
     method public synchronized void removeAllElements();
     method public synchronized boolean removeElement(java.lang.Object);
     method public synchronized void removeElementAt(int);
     method public synchronized boolean removeIf(java.util.function.Predicate<? super E>);
-    method protected synchronized void removeRange(int, int);
     method public synchronized void replaceAll(java.util.function.UnaryOperator<E>);
-    method public synchronized boolean retainAll(java.util.Collection<?>);
-    method public synchronized E set(int, E);
     method public synchronized void setElementAt(E, int);
     method public synchronized void setSize(int);
     method public synchronized int size();
     method public synchronized void sort(java.util.Comparator<? super E>);
-    method public synchronized java.util.List<E> subList(int, int);
-    method public synchronized java.lang.Object[] toArray();
-    method public synchronized <T> T[] toArray(T[]);
-    method public synchronized java.lang.String toString();
+    method public java.util.Spliterator<E> spliterator();
     method public synchronized void trimToSize();
     field protected int capacityIncrement;
     field protected int elementCount;
@@ -69374,6 +69406,8 @@
     ctor public WeakHashMap();
     ctor public WeakHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
 }
@@ -69408,6 +69442,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -69598,9 +69633,13 @@
     ctor public ConcurrentHashMap(java.util.Map<? extends K, ? extends V>);
     ctor public ConcurrentHashMap(int, float);
     ctor public ConcurrentHashMap(int, float, int);
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public boolean contains(java.lang.Object);
     method public java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public void forEach(long, java.util.function.BiConsumer<? super K, ? super V>);
     method public <U> void forEach(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.Consumer<? super U>);
     method public void forEachEntry(long, java.util.function.Consumer<? super java.util.Map.Entry<K, V>>);
@@ -69609,11 +69648,14 @@
     method public <U> void forEachKey(long, java.util.function.Function<? super K, ? extends U>, java.util.function.Consumer<? super U>);
     method public void forEachValue(long, java.util.function.Consumer<? super V>);
     method public <U> void forEachValue(long, java.util.function.Function<? super V, ? extends U>, java.util.function.Consumer<? super U>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentHashMap.KeySetView<K, V> keySet(V);
     method public java.util.Enumeration<K> keys();
     method public long mappingCount();
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet();
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet(int);
+    method public V putIfAbsent(K, V);
     method public <U> U reduce(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
     method public java.util.Map.Entry<K, V> reduceEntries(long, java.util.function.BiFunction<java.util.Map.Entry<K, V>, java.util.Map.Entry<K, V>, ? extends java.util.Map.Entry<K, V>>);
     method public <U> U reduceEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
@@ -69633,6 +69675,10 @@
     method public double reduceValuesToDouble(long, java.util.function.ToDoubleFunction<? super V>, double, java.util.function.DoubleBinaryOperator);
     method public int reduceValuesToInt(long, java.util.function.ToIntFunction<? super V>, int, java.util.function.IntBinaryOperator);
     method public long reduceValuesToLong(long, java.util.function.ToLongFunction<? super V>, long, java.util.function.LongBinaryOperator);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public <U> U search(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>);
     method public <U> U searchEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>);
     method public <U> U searchKeys(long, java.util.function.Function<? super K, ? extends U>);
@@ -69693,6 +69739,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ConcurrentLinkedQueue<E> extends java.util.AbstractQueue implements java.util.Queue java.io.Serializable {
@@ -69703,6 +69750,7 @@
     method public E peek();
     method public E poll();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface ConcurrentMap<K, V> implements java.util.Map {
@@ -69734,6 +69782,9 @@
     method public K ceilingKey(K);
     method public java.util.concurrent.ConcurrentSkipListMap<K, V> clone();
     method public java.util.Comparator<? super K> comparator();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> descendingKeySet();
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> descendingMap();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
@@ -69741,18 +69792,25 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
     method public K higherKey(K);
-    method public java.util.NavigableSet<K> keySet();
     method public java.util.Map.Entry<K, V> lastEntry();
     method public K lastKey();
     method public java.util.Map.Entry<K, V> lowerEntry(K);
     method public K lowerKey(K);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
+    method public V putIfAbsent(K, V);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, K);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> tailMap(K, boolean);
@@ -69780,6 +69838,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.NavigableSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -69826,7 +69885,9 @@
     ctor public CopyOnWriteArraySet(java.util.Collection<? extends E>);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public java.util.Iterator<E> iterator();
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class CountDownLatch {
@@ -69985,7 +70046,6 @@
     method public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
     method public boolean hasQueuedSubmissions();
     method public <T> T invoke(java.util.concurrent.ForkJoinTask<T>);
-    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>);
     method public boolean isQuiescent();
     method public boolean isShutdown();
     method public boolean isTerminated();
@@ -69995,9 +70055,6 @@
     method public void shutdown();
     method public java.util.List<java.lang.Runnable> shutdownNow();
     method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.ForkJoinTask<T>);
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.Callable<T>);
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.lang.Runnable, T);
-    method public java.util.concurrent.ForkJoinTask<?> submit(java.lang.Runnable);
     field public static final java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory defaultForkJoinWorkerThreadFactory;
   }
 
@@ -70121,6 +70178,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public E takeFirst() throws java.lang.InterruptedException;
     method public E takeLast() throws java.lang.InterruptedException;
@@ -70141,6 +70199,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -70160,6 +70219,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public void transfer(E) throws java.lang.InterruptedException;
     method public boolean tryTransfer(E);
@@ -70207,6 +70267,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -70310,6 +70371,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -70321,11 +70383,9 @@
     method public static java.util.concurrent.ThreadLocalRandom current();
     method public double nextDouble(double);
     method public double nextDouble(double, double);
-    method public double nextGaussian();
     method public int nextInt(int, int);
     method public long nextLong(long);
     method public long nextLong(long, long);
-    method public void setSeed(long);
   }
 
   public class ThreadPoolExecutor extends java.util.concurrent.AbstractExecutorService {
@@ -70339,7 +70399,6 @@
     method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
     method protected void beforeExecute(java.lang.Thread, java.lang.Runnable);
     method public void execute(java.lang.Runnable);
-    method protected void finalize();
     method public int getActiveCount();
     method public long getCompletedTaskCount();
     method public int getCorePoolSize();
@@ -71210,11 +71269,8 @@
     ctor public JarFile(java.io.File) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean, int) throws java.io.IOException;
-    method public java.util.Enumeration<java.util.jar.JarEntry> entries();
-    method public synchronized java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.util.jar.JarEntry getJarEntry(java.lang.String);
     method public java.util.jar.Manifest getManifest() throws java.io.IOException;
-    method public java.util.stream.Stream<java.util.jar.JarEntry> stream();
     field public static final java.lang.String MANIFEST_NAME = "META-INF/MANIFEST.MF";
   }
 
@@ -71294,8 +71350,6 @@
 
   public class ConsoleHandler extends java.util.logging.StreamHandler {
     ctor public ConsoleHandler();
-    method public void close();
-    method public void publish(java.util.logging.LogRecord);
   }
 
   public class ErrorManager {
@@ -72085,7 +72139,6 @@
     method public int deflate(byte[]);
     method public int deflate(byte[], int, int, int);
     method public void end();
-    method protected void finalize();
     method public void finish();
     method public boolean finished();
     method public int getAdler();
@@ -72118,8 +72171,6 @@
     ctor public DeflaterInputStream(java.io.InputStream);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater, int);
-    method public void mark(int);
-    method public void reset() throws java.io.IOException;
     field protected final byte[] buf;
     field protected final java.util.zip.Deflater def;
   }
@@ -72150,7 +72201,6 @@
     ctor public GZIPOutputStream(java.io.OutputStream, int, boolean) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream, boolean) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected java.util.zip.CRC32 crc;
   }
 
@@ -72158,7 +72208,6 @@
     ctor public Inflater(boolean);
     ctor public Inflater();
     method public void end();
-    method protected void finalize();
     method public boolean finished();
     method public int getAdler();
     method public long getBytesRead();
@@ -72285,7 +72334,6 @@
     ctor public ZipFile(java.io.File, java.nio.charset.Charset) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public java.util.Enumeration<? extends java.util.zip.ZipEntry> entries();
-    method protected void finalize() throws java.io.IOException;
     method public java.lang.String getComment();
     method public java.util.zip.ZipEntry getEntry(java.lang.String);
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
@@ -72392,7 +72440,6 @@
     method public void setComment(java.lang.String);
     method public void setLevel(int);
     method public void setMethod(int);
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
@@ -72549,7 +72596,6 @@
 
   public class ExemptionMechanism {
     ctor protected ExemptionMechanism(javax.crypto.ExemptionMechanismSpi, java.security.Provider, java.lang.String);
-    method protected void finalize();
     method public final byte[] genExemptionBlob() throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException;
     method public final int genExemptionBlob(byte[]) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
     method public final int genExemptionBlob(byte[], int) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
@@ -74127,7 +74173,6 @@
   public abstract class SSLSocketFactory extends javax.net.SocketFactory {
     ctor public SSLSocketFactory();
     method public abstract java.net.Socket createSocket(java.net.Socket, java.lang.String, int, boolean) throws java.io.IOException;
-    method public java.net.Socket createSocket(java.net.Socket, java.io.InputStream, boolean) throws java.io.IOException;
     method public static synchronized javax.net.SocketFactory getDefault();
     method public abstract java.lang.String[] getDefaultCipherSuites();
     method public abstract java.lang.String[] getSupportedCipherSuites();
@@ -74939,7 +74984,6 @@
     ctor public TransformerException(java.lang.String, java.lang.Throwable);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator, java.lang.Throwable);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
     method public java.lang.String getLocationAsString();
     method public javax.xml.transform.SourceLocator getLocator();
@@ -75210,7 +75254,6 @@
   public class XPathException extends java.lang.Exception {
     ctor public XPathException(java.lang.String);
     ctor public XPathException(java.lang.Throwable);
-    method public java.lang.Throwable getCause();
   }
 
   public abstract interface XPathExpression {
diff --git a/api/test-current.txt b/api/test-current.txt
index 62e9b1e..33d96a7 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3163,7 +3163,6 @@
 
   public final class AnimatorSet extends android.animation.Animator {
     ctor public AnimatorSet();
-    method public android.animation.AnimatorSet clone();
     method public java.util.ArrayList<android.animation.Animator> getChildAnimations();
     method public long getCurrentPlayTime();
     method public long getDuration();
@@ -3282,7 +3281,6 @@
 
   public final class ObjectAnimator extends android.animation.ValueAnimator {
     ctor public ObjectAnimator();
-    method public android.animation.ObjectAnimator clone();
     method public java.lang.String getPropertyName();
     method public java.lang.Object getTarget();
     method public static android.animation.ObjectAnimator ofArgb(java.lang.Object, java.lang.String, int...);
@@ -3308,7 +3306,6 @@
     method public static <T, V> android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofPropertyValuesHolder(java.lang.Object, android.animation.PropertyValuesHolder...);
     method public void setAutoCancel(boolean);
-    method public android.animation.ObjectAnimator setDuration(long);
     method public void setProperty(android.util.Property);
     method public void setPropertyName(java.lang.String);
   }
@@ -3390,7 +3387,6 @@
     ctor public ValueAnimator();
     method public void addUpdateListener(android.animation.ValueAnimator.AnimatorUpdateListener);
     method public static boolean areAnimatorsEnabled();
-    method public android.animation.ValueAnimator clone();
     method public float getAnimatedFraction();
     method public java.lang.Object getAnimatedValue();
     method public java.lang.Object getAnimatedValue(java.lang.String);
@@ -4977,7 +4973,6 @@
     ctor public IntentService(java.lang.String);
     method public android.os.IBinder onBind(android.content.Intent);
     method protected abstract void onHandleIntent(android.content.Intent);
-    method public void onStart(android.content.Intent, int);
     method public void setIntentRedelivery(boolean);
   }
 
@@ -5992,6 +5987,7 @@
     method public void destroy();
     method public android.view.accessibility.AccessibilityEvent executeAndWaitForEvent(java.lang.Runnable, android.app.UiAutomation.AccessibilityEventFilter, long) throws java.util.concurrent.TimeoutException;
     method public android.os.ParcelFileDescriptor executeShellCommand(java.lang.String);
+    method public android.os.ParcelFileDescriptor[] executeShellCommandRw(java.lang.String);
     method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
     method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
     method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
@@ -6113,6 +6109,19 @@
     method public void onDetached();
   }
 
+  public final class WallpaperColors implements android.os.Parcelable {
+    ctor public WallpaperColors(android.os.Parcel);
+    ctor public WallpaperColors(android.graphics.Color, android.graphics.Color, android.graphics.Color);
+    method public int describeContents();
+    method public static android.app.WallpaperColors fromBitmap(android.graphics.Bitmap);
+    method public static android.app.WallpaperColors fromDrawable(android.graphics.drawable.Drawable);
+    method public android.graphics.Color getPrimaryColor();
+    method public android.graphics.Color getSecondaryColor();
+    method public android.graphics.Color getTertiaryColor();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR;
+  }
+
   public final class WallpaperInfo implements android.os.Parcelable {
     ctor public WallpaperInfo(android.content.Context, android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public int describeContents();
@@ -6135,6 +6144,8 @@
   }
 
   public class WallpaperManager {
+    method public void addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener);
+    method public void addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener, android.os.Handler);
     method public void clear() throws java.io.IOException;
     method public void clear(int) throws java.io.IOException;
     method public void clearWallpaperOffsets(android.os.IBinder);
@@ -6149,6 +6160,7 @@
     method public android.graphics.drawable.Drawable getDrawable();
     method public android.graphics.drawable.Drawable getFastDrawable();
     method public static android.app.WallpaperManager getInstance(android.content.Context);
+    method public android.app.WallpaperColors getWallpaperColors(int);
     method public android.os.ParcelFileDescriptor getWallpaperFile(int);
     method public int getWallpaperId(int);
     method public android.app.WallpaperInfo getWallpaperInfo();
@@ -6157,6 +6169,7 @@
     method public boolean isWallpaperSupported();
     method public android.graphics.drawable.Drawable peekDrawable();
     method public android.graphics.drawable.Drawable peekFastDrawable();
+    method public void removeOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener);
     method public void sendWallpaperCommand(android.os.IBinder, java.lang.String, int, int, int, android.os.Bundle);
     method public void setBitmap(android.graphics.Bitmap) throws java.io.IOException;
     method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
@@ -6181,6 +6194,10 @@
     field public static final java.lang.String WALLPAPER_PREVIEW_META_DATA = "android.wallpaper.preview";
   }
 
+  public static abstract interface WallpaperManager.OnColorsChangedListener {
+    method public abstract void onColorsChanged(android.app.WallpaperColors, int);
+  }
+
 }
 
 package android.app.admin {
@@ -8968,6 +8985,7 @@
     field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
+    field public static final java.lang.String IPSEC_SERVICE = "ipsec";
     field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
     field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
     field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -11088,7 +11106,6 @@
 
   public static class AssetFileDescriptor.AutoCloseInputStream extends android.os.ParcelFileDescriptor.AutoCloseInputStream {
     ctor public AssetFileDescriptor.AutoCloseInputStream(android.content.res.AssetFileDescriptor) throws java.io.IOException;
-    method public void mark(int);
   }
 
   public static class AssetFileDescriptor.AutoCloseOutputStream extends android.os.ParcelFileDescriptor.AutoCloseOutputStream {
@@ -11396,7 +11413,6 @@
     method public void copyStringToBuffer(int, android.database.CharArrayBuffer);
     method public void deactivate();
     method public void fillWindow(int, android.database.CursorWindow);
-    method protected void finalize();
     method public byte[] getBlob(int);
     method public int getColumnCount();
     method public int getColumnIndex(java.lang.String);
@@ -13872,7 +13888,6 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setOpacity(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
     field public static final float MASK_SIZE = 100.0f;
@@ -13954,7 +13969,6 @@
     method public void setAlpha(int);
     method public void setAntiAlias(boolean);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setGravity(int);
     method public void setMipMap(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
@@ -14082,7 +14096,6 @@
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method protected void setConstantState(android.graphics.drawable.DrawableContainer.DrawableContainerState);
-    method public void setDither(boolean);
     method public void setEnterFadeDuration(int);
     method public void setExitFadeDuration(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
@@ -14149,7 +14162,6 @@
     method public void setColors(int[]);
     method public void setCornerRadii(float[]);
     method public void setCornerRadius(float);
-    method public void setDither(boolean);
     method public void setGradientCenter(float, float);
     method public void setGradientRadius(float);
     method public void setGradientType(int);
@@ -14244,7 +14256,6 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setDrawable(int, android.graphics.drawable.Drawable);
     method public boolean setDrawableByLayerId(int, android.graphics.drawable.Drawable);
     method public void setId(int, int);
@@ -14285,7 +14296,6 @@
     method public android.graphics.Paint getPaint();
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
     method public void setTargetDensity(android.util.DisplayMetrics);
     method public void setTargetDensity(int);
@@ -14348,7 +14358,6 @@
     method protected void onDraw(android.graphics.drawable.shapes.Shape, android.graphics.Canvas, android.graphics.Paint);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setIntrinsicHeight(int);
     method public void setIntrinsicWidth(int);
     method public void setPadding(int, int, int, int);
@@ -14391,32 +14400,27 @@
 
   public class ArcShape extends android.graphics.drawable.shapes.RectShape {
     ctor public ArcShape(float, float);
-    method public android.graphics.drawable.shapes.ArcShape clone() throws java.lang.CloneNotSupportedException;
     method public final float getStartAngle();
     method public final float getSweepAngle();
   }
 
   public class OvalShape extends android.graphics.drawable.shapes.RectShape {
     ctor public OvalShape();
-    method public android.graphics.drawable.shapes.OvalShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public class PathShape extends android.graphics.drawable.shapes.Shape {
     ctor public PathShape(android.graphics.Path, float, float);
-    method public android.graphics.drawable.shapes.PathShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
   }
 
   public class RectShape extends android.graphics.drawable.shapes.Shape {
     ctor public RectShape();
-    method public android.graphics.drawable.shapes.RectShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
     method protected final android.graphics.RectF rect();
   }
 
   public class RoundRectShape extends android.graphics.drawable.shapes.RectShape {
     ctor public RoundRectShape(float[], android.graphics.RectF, float[]);
-    method public android.graphics.drawable.shapes.RoundRectShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public abstract class Shape implements java.lang.Cloneable {
@@ -14501,7 +14505,6 @@
     method public final void autoFocus(android.hardware.Camera.AutoFocusCallback);
     method public final void cancelAutoFocus();
     method public final boolean enableShutterSound(boolean);
-    method protected void finalize();
     method public static void getCameraInfo(int, android.hardware.Camera.CameraInfo);
     method public static int getNumberOfCameras();
     method public android.hardware.Camera.Parameters getParameters();
@@ -15111,7 +15114,6 @@
     method public <T> T get(android.hardware.camera2.CameraCharacteristics.Key<T>);
     method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getAvailableCaptureRequestKeys();
     method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getAvailableCaptureResultKeys();
-    method public java.util.List<android.hardware.camera2.CameraCharacteristics.Key<?>> getKeys();
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_MODES;
@@ -15472,7 +15474,6 @@
   public final class CaptureRequest extends android.hardware.camera2.CameraMetadata implements android.os.Parcelable {
     method public int describeContents();
     method public <T> T get(android.hardware.camera2.CaptureRequest.Key<T>);
-    method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getKeys();
     method public java.lang.Object getTag();
     method public boolean isReprocess();
     method public void writeToParcel(android.os.Parcel, int);
@@ -15551,7 +15552,6 @@
   public class CaptureResult extends android.hardware.camera2.CameraMetadata {
     method public <T> T get(android.hardware.camera2.CaptureResult.Key<T>);
     method public long getFrameNumber();
-    method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getKeys();
     method public android.hardware.camera2.CaptureRequest getRequest();
     method public int getSequenceId();
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Boolean> BLACK_LEVEL_LOCK;
@@ -17989,7 +17989,6 @@
   }
 
   public class DateIntervalFormat extends android.icu.text.UFormat {
-    method public synchronized java.lang.Object clone();
     method public final java.lang.StringBuffer format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.DateInterval, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.Calendar, android.icu.util.Calendar, java.lang.StringBuffer, java.text.FieldPosition);
@@ -18795,7 +18794,6 @@
 
   public final class RuleBasedCollator extends android.icu.text.Collator {
     ctor public RuleBasedCollator(java.lang.String) throws java.lang.Exception;
-    method public android.icu.text.RuleBasedCollator cloneAsThawed();
     method public int compare(java.lang.String, java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.text.CharacterIterator);
@@ -18822,7 +18820,6 @@
     method public void setFrenchCollation(boolean);
     method public void setFrenchCollationDefault();
     method public void setLowerCaseFirst(boolean);
-    method public android.icu.text.RuleBasedCollator setMaxVariable(int);
     method public void setNumericCollation(boolean);
     method public void setNumericCollationDefault();
     method public void setStrengthDefault();
@@ -21404,7 +21401,6 @@
     ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException;
     method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
-    method protected void finalize();
     method public int getAudioFormat();
     method public int getAudioSessionId();
     method public int getAudioSource();
@@ -21509,7 +21505,6 @@
     method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
     method public int attachAuxEffect(int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
-    method protected void finalize();
     method public void flush();
     method public int getAudioFormat();
     method public int getAudioSessionId();
@@ -21908,7 +21903,6 @@
     method public boolean clearQueue();
     method public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
     method public boolean closeJetFile();
-    method protected void finalize();
     method public static android.media.JetPlayer getJetPlayer();
     method public static int getMaxTracks();
     method public boolean loadJetFile(java.lang.String);
@@ -21948,7 +21942,6 @@
     ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
-    method protected void finalize();
     method public static boolean isSystemIdSupported(int);
     method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
     method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
@@ -22005,7 +21998,6 @@
     method public static android.view.Surface createPersistentInputSurface();
     method public final int dequeueInputBuffer(long);
     method public final int dequeueOutputBuffer(android.media.MediaCodec.BufferInfo, long);
-    method protected void finalize();
     method public final void flush();
     method public android.media.MediaCodecInfo getCodecInfo();
     method public java.nio.ByteBuffer getInputBuffer(int);
@@ -22417,7 +22409,6 @@
 
   public final class MediaCrypto {
     ctor public MediaCrypto(java.util.UUID, byte[]) throws android.media.MediaCryptoException;
-    method protected void finalize();
     method public static final boolean isCryptoSchemeSupported(java.util.UUID);
     method public final void release();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
@@ -22438,7 +22429,6 @@
     ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
-    method protected void finalize();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
     method public final void setMediaCasSession(android.media.MediaCas.Session);
   }
@@ -22481,7 +22471,6 @@
   public final class MediaDrm {
     ctor public MediaDrm(java.util.UUID) throws android.media.UnsupportedSchemeException;
     method public void closeSession(byte[]);
-    method protected void finalize();
     method public android.media.MediaDrm.CryptoSession getCryptoSession(byte[], java.lang.String, java.lang.String);
     method public android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>) throws android.media.NotProvisionedException;
     method public byte[] getPropertyByteArray(java.lang.String);
@@ -22578,7 +22567,6 @@
   public final class MediaExtractor {
     ctor public MediaExtractor();
     method public boolean advance();
-    method protected void finalize();
     method public long getCachedDuration();
     method public android.media.MediaExtractor.CasInfo getCasInfo(int);
     method public android.media.DrmInitData getDrmInitData();
@@ -22880,7 +22868,6 @@
     method public static android.media.MediaPlayer create(android.content.Context, int, android.media.AudioAttributes, int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
     method public void deselectTrack(int) throws java.lang.IllegalStateException;
-    method protected void finalize();
     method public int getAudioSessionId();
     method public int getCurrentPosition();
     method public android.media.MediaPlayer.DrmInfo getDrmInfo();
@@ -23076,7 +23063,6 @@
 
   public class MediaRecorder {
     ctor public MediaRecorder();
-    method protected void finalize();
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
     method public android.os.PersistableBundle getMetrics();
@@ -23348,7 +23334,6 @@
   public final class MediaSync {
     ctor public MediaSync();
     method public final android.view.Surface createInputSurface();
-    method protected void finalize();
     method public void flush();
     method public android.media.PlaybackParams getPlaybackParams();
     method public android.media.SyncParams getSyncParams();
@@ -23468,10 +23453,6 @@
 
   public deprecated class RemoteControlClient.MetadataEditor extends android.media.MediaMetadataEditor {
     method public synchronized void apply();
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putBitmap(int, android.graphics.Bitmap) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putLong(int, long) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putObject(int, java.lang.Object) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putString(int, java.lang.String) throws java.lang.IllegalArgumentException;
     field public static final int BITMAP_KEY_ARTWORK = 100; // 0x64
   }
 
@@ -23518,7 +23499,6 @@
   }
 
   public class Ringtone {
-    method protected void finalize();
     method public android.media.AudioAttributes getAudioAttributes();
     method public deprecated int getStreamType();
     method public java.lang.String getTitle(android.content.Context);
@@ -23572,7 +23552,6 @@
     ctor public deprecated SoundPool(int, int, int);
     method public final void autoPause();
     method public final void autoResume();
-    method protected void finalize();
     method public int load(java.lang.String, int);
     method public int load(android.content.Context, int, int);
     method public int load(android.content.res.AssetFileDescriptor, int);
@@ -23641,7 +23620,6 @@
 
   public class ToneGenerator {
     ctor public ToneGenerator(int, int);
-    method protected void finalize();
     method public final int getAudioSessionId();
     method public void release();
     method public boolean startTone(int);
@@ -23774,7 +23752,6 @@
   public final class VolumeShaper implements java.lang.AutoCloseable {
     method public void apply(android.media.VolumeShaper.Operation);
     method public void close();
-    method protected void finalize();
     method public float getVolume();
     method public void replace(android.media.VolumeShaper.Configuration, android.media.VolumeShaper.Operation, boolean);
   }
@@ -23829,7 +23806,6 @@
   }
 
   public class AudioEffect {
-    method protected void finalize();
     method public android.media.audiofx.AudioEffect.Descriptor getDescriptor() throws java.lang.IllegalStateException;
     method public boolean getEnabled() throws java.lang.IllegalStateException;
     method public int getId() throws java.lang.IllegalStateException;
@@ -24082,7 +24058,6 @@
 
   public class Visualizer {
     ctor public Visualizer(int) throws java.lang.RuntimeException, java.lang.UnsupportedOperationException;
-    method protected void finalize();
     method public int getCaptureSize() throws java.lang.IllegalStateException;
     method public static int[] getCaptureSizeRange();
     method public boolean getEnabled();
@@ -25639,6 +25614,68 @@
     field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
   }
 
+  public final class IpSecAlgorithm implements android.os.Parcelable {
+    ctor public IpSecAlgorithm(java.lang.String, byte[]);
+    ctor public IpSecAlgorithm(java.lang.String, byte[], int);
+    method public int describeContents();
+    method public byte[] getKey();
+    method public java.lang.String getName();
+    method public int getTruncationLengthBits();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final java.lang.String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";
+    field public static final java.lang.String AUTH_HMAC_MD5 = "hmac(md5)";
+    field public static final java.lang.String AUTH_HMAC_SHA1 = "hmac(sha1)";
+    field public static final java.lang.String AUTH_HMAC_SHA256 = "hmac(sha256)";
+    field public static final java.lang.String AUTH_HMAC_SHA384 = "hmac(sha384)";
+    field public static final java.lang.String AUTH_HMAC_SHA512 = "hmac(sha512)";
+    field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
+    field public static final java.lang.String CRYPT_AES_CBC = "cbc(aes)";
+  }
+
+  public final class IpSecManager {
+    method public void applyTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
+    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
+    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
+    method public void removeTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
+    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress) throws android.net.IpSecManager.ResourceUnavailableException;
+    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+    field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
+  }
+
+  public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
+  }
+
+  public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
+    method public void close();
+    method public int getSpi();
+  }
+
+  public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
+    method public int getSpi();
+  }
+
+  public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
+    method public void close() throws java.io.IOException;
+    method public int getPort();
+    method public java.io.FileDescriptor getSocket();
+  }
+
+  public final class IpSecTransform implements java.lang.AutoCloseable {
+    method public void close();
+    field public static final int DIRECTION_IN = 0; // 0x0
+    field public static final int DIRECTION_OUT = 1; // 0x1
+  }
+
+  public static class IpSecTransform.Builder {
+    ctor public IpSecTransform.Builder(android.content.Context);
+    method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+    method public android.net.IpSecTransform.Builder setAuthenticatedEncryption(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
+    method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
+  }
+
   public class LinkAddress implements android.os.Parcelable {
     method public int describeContents();
     method public java.net.InetAddress getAddress();
@@ -25764,6 +25801,7 @@
     field public static final int NET_CAPABILITY_MMS = 0; // 0x0
     field public static final int NET_CAPABILITY_NOT_METERED = 11; // 0xb
     field public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; // 0xd
+    field public static final int NET_CAPABILITY_NOT_ROAMING = 18; // 0x12
     field public static final int NET_CAPABILITY_NOT_VPN = 15; // 0xf
     field public static final int NET_CAPABILITY_RCS = 8; // 0x8
     field public static final int NET_CAPABILITY_SUPL = 1; // 0x1
@@ -25794,7 +25832,7 @@
     method public boolean isConnected();
     method public boolean isConnectedOrConnecting();
     method public boolean isFailover();
-    method public boolean isRoaming();
+    method public deprecated boolean isRoaming();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
   }
@@ -26091,6 +26129,7 @@
     method public boolean protect(java.net.DatagramSocket);
     method public boolean setUnderlyingNetworks(android.net.Network[]);
     field public static final java.lang.String SERVICE_INTERFACE = "android.net.VpnService";
+    field public static final java.lang.String SERVICE_META_DATA_SUPPORTS_ALWAYS_ON = "android.net.VpnService.SUPPORTS_ALWAYS_ON";
   }
 
   public class VpnService.Builder {
@@ -30746,7 +30785,6 @@
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
-    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.Bundle> CREATOR;
     field public static final android.os.Bundle EMPTY;
@@ -30799,6 +30837,7 @@
   }
 
   public final class Debug {
+    method public static void attachJvmtiAgent(java.lang.String, java.lang.String) throws java.io.IOException;
     method public static deprecated void changeDebugPort(int);
     method public static void dumpHprofData(java.lang.String) throws java.io.IOException;
     method public static boolean dumpService(java.lang.String, java.io.FileDescriptor, java.lang.String[]);
@@ -30977,7 +31016,6 @@
   public abstract class FileObserver {
     ctor public FileObserver(java.lang.String);
     ctor public FileObserver(java.lang.String, int);
-    method protected void finalize();
     method public abstract void onEvent(int, java.lang.String);
     method public void startWatching();
     method public void stopWatching();
@@ -31152,7 +31190,6 @@
     ctor public MemoryFile(java.lang.String, int) throws java.io.IOException;
     method public synchronized boolean allowPurging(boolean) throws java.io.IOException;
     method public void close();
-    method protected void finalize();
     method public java.io.InputStream getInputStream();
     method public java.io.OutputStream getOutputStream();
     method public boolean isPurgingAllowed();
@@ -31452,7 +31489,6 @@
     method public int describeContents();
     method public android.os.PersistableBundle getPersistableBundle(java.lang.String);
     method public void putPersistableBundle(java.lang.String, android.os.PersistableBundle);
-    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.PersistableBundle> CREATOR;
     field public static final android.os.PersistableBundle EMPTY;
@@ -35798,7 +35834,6 @@
     method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
-    method public synchronized void resize(int);
     method public void setFace(android.renderscript.Type.CubemapFace);
     method public void setLOD(int);
     method public void setX(int);
@@ -38177,6 +38212,16 @@
     field public final int errno;
   }
 
+  public class Int32Ref {
+    ctor public Int32Ref(int);
+    field public int value;
+  }
+
+  public class Int64Ref {
+    ctor public Int64Ref(long);
+    field public long value;
+  }
+
   public final class Os {
     method public static java.io.FileDescriptor accept(java.io.FileDescriptor, java.net.InetSocketAddress) throws android.system.ErrnoException, java.net.SocketException;
     method public static boolean access(java.lang.String, int) throws android.system.ErrnoException;
@@ -38246,7 +38291,8 @@
     method public static void remove(java.lang.String) throws android.system.ErrnoException;
     method public static void removexattr(java.lang.String, java.lang.String) throws android.system.ErrnoException;
     method public static void rename(java.lang.String, java.lang.String) throws android.system.ErrnoException;
-    method public static long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.util.MutableLong, long) throws android.system.ErrnoException;
+    method public static deprecated long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.util.MutableLong, long) throws android.system.ErrnoException;
+    method public static long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.system.Int64Ref, long) throws android.system.ErrnoException;
     method public static int sendto(java.io.FileDescriptor, java.nio.ByteBuffer, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
     method public static int sendto(java.io.FileDescriptor, byte[], int, int, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
     method public static void setegid(int) throws android.system.ErrnoException;
@@ -38271,7 +38317,8 @@
     method public static int umask(int);
     method public static android.system.StructUtsname uname();
     method public static void unsetenv(java.lang.String) throws android.system.ErrnoException;
-    method public static int waitpid(int, android.util.MutableInt, int) throws android.system.ErrnoException;
+    method public static deprecated int waitpid(int, android.util.MutableInt, int) throws android.system.ErrnoException;
+    method public static int waitpid(int, android.system.Int32Ref, int) throws android.system.ErrnoException;
     method public static int write(java.io.FileDescriptor, java.nio.ByteBuffer) throws android.system.ErrnoException, java.io.InterruptedIOException;
     method public static int write(java.io.FileDescriptor, byte[], int, int) throws android.system.ErrnoException, java.io.InterruptedIOException;
     method public static int writev(java.io.FileDescriptor, java.lang.Object[], int[], int[]) throws android.system.ErrnoException, java.io.InterruptedIOException;
@@ -38847,6 +38894,7 @@
     method public android.telecom.Call.RttCall getRttCall();
     method public int getState();
     method public android.telecom.InCallService.VideoCall getVideoCall();
+    method public void handoverTo(android.telecom.PhoneAccountHandle, int, android.os.Bundle);
     method public void hold();
     method public boolean isRttActive();
     method public void mergeConference();
@@ -38891,6 +38939,8 @@
     method public void onConferenceableCallsChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
     method public void onConnectionEvent(android.telecom.Call, java.lang.String, android.os.Bundle);
     method public void onDetailsChanged(android.telecom.Call, android.telecom.Call.Details);
+    method public void onHandoverComplete(android.telecom.Call);
+    method public void onHandoverFailed(android.telecom.Call, int);
     method public void onParentChanged(android.telecom.Call, android.telecom.Call);
     method public void onPostDialWait(android.telecom.Call, java.lang.String);
     method public void onRttInitiationFailure(android.telecom.Call, int);
@@ -38899,6 +38949,10 @@
     method public void onRttStatusChanged(android.telecom.Call, boolean, android.telecom.Call.RttCall);
     method public void onStateChanged(android.telecom.Call, int);
     method public void onVideoCallChanged(android.telecom.Call, android.telecom.InCallService.VideoCall);
+    field public static final int HANDOVER_FAILURE_DEST_APP_REJECTED = 1; // 0x1
+    field public static final int HANDOVER_FAILURE_DEST_INVALID_PERM = 3; // 0x3
+    field public static final int HANDOVER_FAILURE_DEST_NOT_SUPPORTED = 2; // 0x2
+    field public static final int HANDOVER_FAILURE_DEST_USER_REJECTED = 4; // 0x4
   }
 
   public static class Call.Details {
@@ -38954,7 +39008,7 @@
 
   public static final class Call.RttCall {
     method public int getRttAudioMode();
-    method public java.lang.String read() throws java.io.IOException;
+    method public java.lang.String read();
     method public java.lang.String readImmediately() throws java.io.IOException;
     method public void setRttMode(int);
     method public void write(java.lang.String) throws java.io.IOException;
@@ -38967,7 +39021,9 @@
     ctor public CallAudioState(boolean, int, int);
     method public static java.lang.String audioRouteToString(int);
     method public int describeContents();
+    method public android.bluetooth.BluetoothDevice getActiveBluetoothDevice();
     method public int getRoute();
+    method public java.util.Collection<android.bluetooth.BluetoothDevice> getSupportedBluetoothDevices();
     method public int getSupportedRouteMask();
     method public boolean isMuted();
     method public void writeToParcel(android.os.Parcel, int);
@@ -39039,6 +39095,7 @@
     method public final void setActive();
     method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
     method public final void setConnectionCapabilities(int);
+    method public final void setConnectionElapsedTime(long);
     method public final void setConnectionProperties(int);
     method public final void setConnectionTime(long);
     method public final void setDialing();
@@ -39101,6 +39158,7 @@
     method public final void putExtras(android.os.Bundle);
     method public final void removeExtras(java.util.List<java.lang.String>);
     method public final void removeExtras(java.lang.String...);
+    method public void requestBluetoothAudio(java.lang.String);
     method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
     method public final void sendRemoteRttRequest();
     method public final void sendRttInitiationFailure(int);
@@ -39245,8 +39303,11 @@
     method public void onConference(android.telecom.Connection, android.telecom.Connection);
     method public android.telecom.Connection onCreateIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public void onCreateIncomingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+    method public android.telecom.Connection onCreateIncomingHandoverConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public void onCreateOutgoingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+    method public android.telecom.Connection onCreateOutgoingHandoverConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+    method public void onHandoverFailed(android.telecom.ConnectionRequest, int);
     method public void onRemoteConferenceAdded(android.telecom.RemoteConference);
     method public void onRemoteExistingConnectionAdded(android.telecom.RemoteConnection);
     field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.ConnectionService";
@@ -39304,6 +39365,7 @@
     method public void onCanAddCallChanged(boolean);
     method public void onConnectionEvent(android.telecom.Call, java.lang.String, android.os.Bundle);
     method public void onSilenceRinger();
+    method public final void requestBluetoothAudio(java.lang.String);
     method public final void setAudioRoute(int);
     method public final void setMuted(boolean);
     field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.InCallService";
@@ -39368,6 +39430,9 @@
     field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR;
     field public static final java.lang.String EXTRA_CALL_SUBJECT_CHARACTER_ENCODING = "android.telecom.extra.CALL_SUBJECT_CHARACTER_ENCODING";
     field public static final java.lang.String EXTRA_CALL_SUBJECT_MAX_LENGTH = "android.telecom.extra.CALL_SUBJECT_MAX_LENGTH";
+    field public static final java.lang.String EXTRA_LOG_SELF_MANAGED_CALLS = "android.telecom.extra.LOG_SELF_MANAGED_CALLS";
+    field public static final java.lang.String EXTRA_SUPPORTS_HANDOVER_FROM = "android.telecom.extra.SUPPORTS_HANDOVER_FROM";
+    field public static final java.lang.String EXTRA_SUPPORTS_HANDOVER_TO = "android.telecom.extra.SUPPORTS_HANDOVER_TO";
     field public static final int NO_HIGHLIGHT_COLOR = 0; // 0x0
     field public static final int NO_RESOURCE_ID = -1; // 0xffffffff
     field public static final java.lang.String SCHEME_SIP = "sip";
@@ -39528,6 +39593,7 @@
   }
 
   public class TelecomManager {
+    method public void acceptHandover(android.net.Uri, int, android.telecom.PhoneAccountHandle);
     method public void acceptRingingCall();
     method public void acceptRingingCall(int);
     method public void addNewIncomingCall(android.telecom.PhoneAccountHandle, android.os.Bundle);
@@ -39548,6 +39614,7 @@
     method public boolean isInManagedCall();
     method public boolean isIncomingCallPermitted(android.telecom.PhoneAccountHandle);
     method public boolean isOutgoingCallPermitted(android.telecom.PhoneAccountHandle);
+    method public boolean isTtySupported();
     method public boolean isVoiceMailNumber(android.telecom.PhoneAccountHandle, java.lang.String);
     method public void placeCall(android.net.Uri, android.os.Bundle);
     method public void registerPhoneAccount(android.telecom.PhoneAccount);
@@ -39692,6 +39759,7 @@
     field public static final java.lang.String KEY_DURATION_BLOCKING_DISABLED_AFTER_EMERGENCY_INT = "duration_blocking_disabled_after_emergency_int";
     field public static final java.lang.String KEY_EDITABLE_ENHANCED_4G_LTE_BOOL = "editable_enhanced_4g_lte_bool";
     field public static final java.lang.String KEY_EDITABLE_VOICEMAIL_NUMBER_BOOL = "editable_voicemail_number_bool";
+    field public static final java.lang.String KEY_EDITABLE_VOICEMAIL_NUMBER_SETTING_BOOL = "editable_voicemail_number_setting_bool";
     field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_key_vibration_bool";
     field public static final java.lang.String KEY_FORCE_HOME_NETWORK_BOOL = "force_home_network_bool";
     field public static final java.lang.String KEY_GSM_DTMF_TONE_DELAY_INT = "gsm_dtmf_tone_delay_int";
@@ -39782,6 +39850,8 @@
     method public int getLatitude();
     method public int getLongitude();
     method public int getNetworkId();
+    method public java.lang.CharSequence getOperatorAlphaLong();
+    method public java.lang.CharSequence getOperatorAlphaShort();
     method public int getSystemId();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityCdma> CREATOR;
@@ -39793,8 +39863,13 @@
     method public int getBsic();
     method public int getCid();
     method public int getLac();
-    method public int getMcc();
-    method public int getMnc();
+    method public deprecated int getMcc();
+    method public java.lang.String getMccStr();
+    method public deprecated int getMnc();
+    method public java.lang.String getMncStr();
+    method public java.lang.String getMobileNetworkOperator();
+    method public java.lang.CharSequence getOperatorAlphaLong();
+    method public java.lang.CharSequence getOperatorAlphaShort();
     method public deprecated int getPsc();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityGsm> CREATOR;
@@ -39804,8 +39879,13 @@
     method public int describeContents();
     method public int getCi();
     method public int getEarfcn();
-    method public int getMcc();
-    method public int getMnc();
+    method public deprecated int getMcc();
+    method public java.lang.String getMccStr();
+    method public deprecated int getMnc();
+    method public java.lang.String getMncStr();
+    method public java.lang.String getMobileNetworkOperator();
+    method public java.lang.CharSequence getOperatorAlphaLong();
+    method public java.lang.CharSequence getOperatorAlphaShort();
     method public int getPci();
     method public int getTac();
     method public void writeToParcel(android.os.Parcel, int);
@@ -39816,8 +39896,13 @@
     method public int describeContents();
     method public int getCid();
     method public int getLac();
-    method public int getMcc();
-    method public int getMnc();
+    method public deprecated int getMcc();
+    method public java.lang.String getMccStr();
+    method public deprecated int getMnc();
+    method public java.lang.String getMncStr();
+    method public java.lang.String getMobileNetworkOperator();
+    method public java.lang.CharSequence getOperatorAlphaLong();
+    method public java.lang.CharSequence getOperatorAlphaShort();
     method public int getPsc();
     method public int getUarfcn();
     method public void writeToParcel(android.os.Parcel, int);
@@ -39950,13 +40035,48 @@
     field public static final int STATUS_UNKNOWN_ERROR = 4; // 0x4
   }
 
-  public class MbmsStreamingManager {
-    method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback, int, android.os.Handler) throws android.telephony.mbms.MbmsException;
-    method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback, android.os.Handler) throws android.telephony.mbms.MbmsException;
-    method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback) throws android.telephony.mbms.MbmsException;
-    method public void dispose();
-    method public void getStreamingServices(java.util.List<java.lang.String>) throws android.telephony.mbms.MbmsException;
-    method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, android.telephony.mbms.StreamingServiceCallback, android.os.Handler) throws android.telephony.mbms.MbmsException;
+  public class MbmsDownloadSession implements java.lang.AutoCloseable {
+    method public void cancelDownload(android.telephony.mbms.DownloadRequest);
+    method public void close();
+    method public static android.telephony.MbmsDownloadSession create(android.content.Context, android.telephony.mbms.MbmsDownloadSessionCallback, android.os.Handler);
+    method public static android.telephony.MbmsDownloadSession create(android.content.Context, android.telephony.mbms.MbmsDownloadSessionCallback, int, android.os.Handler);
+    method public void download(android.telephony.mbms.DownloadRequest);
+    method public int getDownloadStatus(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo);
+    method public java.io.File getTempFileRootDirectory();
+    method public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads();
+    method public void registerStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback, android.os.Handler);
+    method public void requestUpdateFileServices(java.util.List<java.lang.String>);
+    method public void resetDownloadKnowledge(android.telephony.mbms.DownloadRequest);
+    method public void setTempFileRootDirectory(java.io.File);
+    method public void unregisterStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback);
+    field public static final java.lang.String DEFAULT_TOP_LEVEL_TEMP_DIRECTORY = "androidMbmsTempFileRoot";
+    field public static final java.lang.String EXTRA_MBMS_COMPLETED_FILE_URI = "android.telephony.extra.MBMS_COMPLETED_FILE_URI";
+    field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_REQUEST = "android.telephony.extra.MBMS_DOWNLOAD_REQUEST";
+    field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_RESULT = "android.telephony.extra.MBMS_DOWNLOAD_RESULT";
+    field public static final java.lang.String EXTRA_MBMS_FILE_INFO = "android.telephony.extra.MBMS_FILE_INFO";
+    field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_OVERRIDE_METADATA = "mbms-download-service-override";
+    field public static final int RESULT_CANCELLED = 2; // 0x2
+    field public static final int RESULT_DOWNLOAD_FAILURE = 6; // 0x6
+    field public static final int RESULT_EXPIRED = 3; // 0x3
+    field public static final int RESULT_FILE_ROOT_UNREACHABLE = 8; // 0x8
+    field public static final int RESULT_IO_ERROR = 4; // 0x4
+    field public static final int RESULT_OUT_OF_STORAGE = 7; // 0x7
+    field public static final int RESULT_SERVICE_ID_NOT_DEFINED = 5; // 0x5
+    field public static final int RESULT_SUCCESSFUL = 1; // 0x1
+    field public static final int STATUS_ACTIVELY_DOWNLOADING = 1; // 0x1
+    field public static final int STATUS_PENDING_DOWNLOAD = 2; // 0x2
+    field public static final int STATUS_PENDING_DOWNLOAD_WINDOW = 4; // 0x4
+    field public static final int STATUS_PENDING_REPAIR = 3; // 0x3
+    field public static final int STATUS_UNKNOWN = 0; // 0x0
+  }
+
+  public class MbmsStreamingSession implements java.lang.AutoCloseable {
+    method public void close();
+    method public static android.telephony.MbmsStreamingSession create(android.content.Context, android.telephony.mbms.MbmsStreamingSessionCallback, int, android.os.Handler);
+    method public static android.telephony.MbmsStreamingSession create(android.content.Context, android.telephony.mbms.MbmsStreamingSessionCallback, android.os.Handler);
+    method public void requestUpdateStreamingServices(java.util.List<java.lang.String>);
+    method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, android.telephony.mbms.StreamingServiceCallback, android.os.Handler);
+    field public static final java.lang.String MBMS_STREAMING_SERVICE_OVERRIDE_METADATA = "mbms-streaming-service-override";
   }
 
   public class NeighboringCellInfo implements android.os.Parcelable {
@@ -39989,8 +40109,10 @@
   public class PhoneNumberUtils {
     ctor public PhoneNumberUtils();
     method public static void addTtsSpan(android.text.Spannable, int, int);
-    method public static java.lang.String calledPartyBCDFragmentToString(byte[], int, int);
-    method public static java.lang.String calledPartyBCDToString(byte[], int, int);
+    method public static deprecated java.lang.String calledPartyBCDFragmentToString(byte[], int, int);
+    method public static java.lang.String calledPartyBCDFragmentToString(byte[], int, int, int);
+    method public static deprecated java.lang.String calledPartyBCDToString(byte[], int, int);
+    method public static java.lang.String calledPartyBCDToString(byte[], int, int, int);
     method public static boolean compare(java.lang.String, java.lang.String);
     method public static boolean compare(android.content.Context, java.lang.String, java.lang.String);
     method public static java.lang.String convertKeypadLettersToDigits(java.lang.String);
@@ -40023,12 +40145,15 @@
     method public static byte[] networkPortionToCalledPartyBCD(java.lang.String);
     method public static byte[] networkPortionToCalledPartyBCDWithLength(java.lang.String);
     method public static java.lang.String normalizeNumber(java.lang.String);
-    method public static byte[] numberToCalledPartyBCD(java.lang.String);
+    method public static deprecated byte[] numberToCalledPartyBCD(java.lang.String);
+    method public static byte[] numberToCalledPartyBCD(java.lang.String, int);
     method public static java.lang.String replaceUnicodeDigits(java.lang.String);
     method public static java.lang.String stringFromStringAndTOA(java.lang.String, int);
     method public static java.lang.String stripSeparators(java.lang.String);
     method public static java.lang.String toCallerIDMinMatch(java.lang.String);
     method public static int toaFromString(java.lang.String);
+    field public static final int BCD_EXTENDED_TYPE_CALLED_PARTY = 2; // 0x2
+    field public static final int BCD_EXTENDED_TYPE_EF_ADN = 1; // 0x1
     field public static final int FORMAT_JAPAN = 2; // 0x2
     field public static final int FORMAT_NANP = 1; // 0x1
     field public static final int FORMAT_UNKNOWN = 0; // 0x0
@@ -40161,9 +40286,12 @@
     field public static final int MMS_ERROR_UNABLE_CONNECT_MMS = 3; // 0x3
     field public static final int MMS_ERROR_UNSPECIFIED = 1; // 0x1
     field public static final int RESULT_ERROR_GENERIC_FAILURE = 1; // 0x1
+    field public static final int RESULT_ERROR_LIMIT_EXCEEDED = 5; // 0x5
     field public static final int RESULT_ERROR_NO_SERVICE = 4; // 0x4
     field public static final int RESULT_ERROR_NULL_PDU = 3; // 0x3
     field public static final int RESULT_ERROR_RADIO_OFF = 2; // 0x2
+    field public static final int RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED = 8; // 0x8
+    field public static final int RESULT_ERROR_SHORT_CODE_NOT_ALLOWED = 7; // 0x7
     field public static final int STATUS_ON_ICC_FREE = 0; // 0x0
     field public static final int STATUS_ON_ICC_READ = 1; // 0x1
     field public static final int STATUS_ON_ICC_SENT = 5; // 0x5
@@ -40308,6 +40436,7 @@
     method public int getPhoneCount();
     method public int getPhoneType();
     method public android.telephony.ServiceState getServiceState();
+    method public android.telephony.SignalStrength getSignalStrength();
     method public java.lang.String getSimCountryIso();
     method public java.lang.String getSimOperator();
     method public java.lang.String getSimOperatorName();
@@ -40333,7 +40462,7 @@
     method public boolean isHearingAidCompatibilitySupported();
     method public boolean isNetworkRoaming();
     method public boolean isSmsCapable();
-    method public boolean isTtyModeSupported();
+    method public deprecated boolean isTtyModeSupported();
     method public boolean isVoiceCapable();
     method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle);
     method public boolean isWorldPhone();
@@ -40577,7 +40706,6 @@
 
   public static deprecated class SmsMessage.SubmitPdu {
     ctor public deprecated SmsMessage.SubmitPdu();
-    method public deprecated java.lang.String toString();
     field public deprecated byte[] encodedMessage;
     field public deprecated byte[] encodedScAddress;
   }
@@ -40586,15 +40714,79 @@
 
 package android.telephony.mbms {
 
-  public class MbmsException extends java.lang.Exception {
-    method public int getErrorCode();
+  public final class DownloadRequest implements android.os.Parcelable {
+    method public static android.telephony.mbms.DownloadRequest copy(android.telephony.mbms.DownloadRequest);
+    method public int describeContents();
+    method public java.lang.String getFileServiceId();
+    method public static int getMaxAppIntentSize();
+    method public static int getMaxDestinationUriSize();
+    method public android.net.Uri getSourceUri();
+    method public int getSubscriptionId();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.mbms.DownloadRequest> CREATOR;
+  }
+
+  public static class DownloadRequest.Builder {
+    ctor public DownloadRequest.Builder(android.net.Uri);
+    method public android.telephony.mbms.DownloadRequest build();
+    method public android.telephony.mbms.DownloadRequest.Builder setAppIntent(android.content.Intent);
+    method public android.telephony.mbms.DownloadRequest.Builder setServiceInfo(android.telephony.mbms.FileServiceInfo);
+    method public android.telephony.mbms.DownloadRequest.Builder setSubscriptionId(int);
+  }
+
+  public class DownloadStateCallback {
+    ctor public DownloadStateCallback();
+    ctor public DownloadStateCallback(int);
+    method public final boolean isFilterFlagSet(int);
+    method public void onProgressUpdated(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo, int, int, int, int);
+    method public void onStateUpdated(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo, int);
+    field public static final int ALL_UPDATES = 0; // 0x0
+    field public static final int PROGRESS_UPDATES = 1; // 0x1
+    field public static final int STATE_UPDATES = 2; // 0x2
+  }
+
+  public final class FileInfo implements android.os.Parcelable {
+    ctor public FileInfo(android.net.Uri, java.lang.String);
+    method public int describeContents();
+    method public java.lang.String getMimeType();
+    method public android.net.Uri getUri();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.mbms.FileInfo> CREATOR;
+  }
+
+  public final class FileServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable {
+    ctor public FileServiceInfo(java.util.Map<java.util.Locale, java.lang.String>, java.lang.String, java.util.List<java.util.Locale>, java.lang.String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>);
+    method public int describeContents();
+    method public java.util.List<android.telephony.mbms.FileInfo> getFiles();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.mbms.FileServiceInfo> CREATOR;
+  }
+
+  public class MbmsDownloadReceiver extends android.content.BroadcastReceiver {
+    ctor public MbmsDownloadReceiver();
+    method public void onReceive(android.content.Context, android.content.Intent);
+  }
+
+  public class MbmsDownloadSessionCallback {
+    ctor public MbmsDownloadSessionCallback();
+    method public void onError(int, java.lang.String);
+    method public void onFileServicesUpdated(java.util.List<android.telephony.mbms.FileServiceInfo>);
+    method public void onMiddlewareReady();
+  }
+
+  public class MbmsErrors {
     field public static final int ERROR_MIDDLEWARE_LOST = 3; // 0x3
     field public static final int ERROR_MIDDLEWARE_NOT_BOUND = 2; // 0x2
     field public static final int ERROR_NO_UNIQUE_MIDDLEWARE = 1; // 0x1
     field public static final int SUCCESS = 0; // 0x0
   }
 
-  public static class MbmsException.GeneralErrors {
+  public static class MbmsErrors.DownloadErrors {
+    field public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 401; // 0x191
+    field public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402; // 0x192
+  }
+
+  public static class MbmsErrors.GeneralErrors {
     field public static final int ERROR_CARRIER_CHANGE_NOT_ALLOWED = 207; // 0xcf
     field public static final int ERROR_IN_E911 = 204; // 0xcc
     field public static final int ERROR_MIDDLEWARE_NOT_YET_READY = 201; // 0xc9
@@ -40604,39 +40796,39 @@
     field public static final int ERROR_UNABLE_TO_READ_SIM = 206; // 0xce
   }
 
-  public static class MbmsException.InitializationErrors {
+  public static class MbmsErrors.InitializationErrors {
     field public static final int ERROR_APP_PERMISSIONS_NOT_GRANTED = 102; // 0x66
     field public static final int ERROR_DUPLICATE_INITIALIZE = 101; // 0x65
     field public static final int ERROR_UNABLE_TO_INITIALIZE = 103; // 0x67
   }
 
-  public static class MbmsException.StreamingErrors {
+  public static class MbmsErrors.StreamingErrors {
     field public static final int ERROR_CONCURRENT_SERVICE_LIMIT_REACHED = 301; // 0x12d
     field public static final int ERROR_DUPLICATE_START_STREAM = 303; // 0x12f
     field public static final int ERROR_UNABLE_TO_START_SERVICE = 302; // 0x12e
   }
 
-  public class MbmsStreamingManagerCallback {
-    ctor public MbmsStreamingManagerCallback();
+  public class MbmsStreamingSessionCallback {
+    ctor public MbmsStreamingSessionCallback();
     method public void onError(int, java.lang.String);
     method public void onMiddlewareReady();
     method public void onStreamingServicesUpdated(java.util.List<android.telephony.mbms.StreamingServiceInfo>);
   }
 
   public class ServiceInfo {
-    method public java.lang.String getClassName();
     method public java.util.List<java.util.Locale> getLocales();
-    method public java.util.Map<java.util.Locale, java.lang.String> getNames();
+    method public java.lang.CharSequence getNameForLocale(java.util.Locale);
+    method public java.util.Set<java.util.Locale> getNamedContentLocales();
+    method public java.lang.String getServiceClassName();
     method public java.lang.String getServiceId();
     method public java.util.Date getSessionEndTime();
     method public java.util.Date getSessionStartTime();
   }
 
   public class StreamingService {
-    method public void dispose() throws android.telephony.mbms.MbmsException;
     method public android.telephony.mbms.StreamingServiceInfo getInfo();
-    method public android.net.Uri getPlaybackUri() throws android.telephony.mbms.MbmsException;
-    method public void stopStreaming() throws android.telephony.mbms.MbmsException;
+    method public android.net.Uri getPlaybackUri();
+    method public void stopStreaming();
     field public static final int BROADCAST_METHOD = 1; // 0x1
     field public static final int REASON_BY_USER_REQUEST = 1; // 0x1
     field public static final int REASON_END_OF_SESSION = 2; // 0x2
@@ -40662,11 +40854,68 @@
   }
 
   public final class StreamingServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable {
+    ctor public StreamingServiceInfo(java.util.Map<java.util.Locale, java.lang.String>, java.lang.String, java.util.List<java.util.Locale>, java.lang.String, java.util.Date, java.util.Date);
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.mbms.StreamingServiceInfo> CREATOR;
   }
 
+  public final class UriPathPair implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.net.Uri getContentUri();
+    method public android.net.Uri getFilePathUri();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.mbms.UriPathPair> CREATOR;
+  }
+
+}
+
+package android.telephony.mbms.vendor {
+
+  public class MbmsDownloadServiceBase extends android.os.Binder {
+    ctor public MbmsDownloadServiceBase();
+    method public int cancelDownload(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
+    method public void dispose(int) throws android.os.RemoteException;
+    method public int download(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
+    method public int getDownloadStatus(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) throws android.os.RemoteException;
+    method public int initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback) throws android.os.RemoteException;
+    method public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads(int) throws android.os.RemoteException;
+    method public void onAppCallbackDied(int, int);
+    method public int registerStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback) throws android.os.RemoteException;
+    method public int requestUpdateFileServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
+    method public int resetDownloadKnowledge(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
+    method public int setTempFileRootDirectory(int, java.lang.String) throws android.os.RemoteException;
+    method public int unregisterStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback) throws android.os.RemoteException;
+  }
+
+  public class MbmsStreamingServiceBase extends android.os.Binder {
+    ctor public MbmsStreamingServiceBase();
+    method public void dispose(int) throws android.os.RemoteException;
+    method public android.net.Uri getPlaybackUri(int, java.lang.String) throws android.os.RemoteException;
+    method public int initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int) throws android.os.RemoteException;
+    method public void onAppCallbackDied(int, int);
+    method public int requestUpdateStreamingServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
+    method public int startStreaming(int, java.lang.String, android.telephony.mbms.StreamingServiceCallback) throws android.os.RemoteException;
+    method public void stopStreaming(int, java.lang.String) throws android.os.RemoteException;
+  }
+
+  public class VendorUtils {
+    ctor public VendorUtils();
+    method public static android.content.ComponentName getAppReceiverFromPackageName(android.content.Context, java.lang.String);
+    field public static final java.lang.String ACTION_CLEANUP = "android.telephony.mbms.action.CLEANUP";
+    field public static final java.lang.String ACTION_DOWNLOAD_RESULT_INTERNAL = "android.telephony.mbms.action.DOWNLOAD_RESULT_INTERNAL";
+    field public static final java.lang.String ACTION_FILE_DESCRIPTOR_REQUEST = "android.telephony.mbms.action.FILE_DESCRIPTOR_REQUEST";
+    field public static final java.lang.String EXTRA_FD_COUNT = "android.telephony.mbms.extra.FD_COUNT";
+    field public static final java.lang.String EXTRA_FINAL_URI = "android.telephony.mbms.extra.FINAL_URI";
+    field public static final java.lang.String EXTRA_FREE_URI_LIST = "android.telephony.mbms.extra.FREE_URI_LIST";
+    field public static final java.lang.String EXTRA_PAUSED_LIST = "android.telephony.mbms.extra.PAUSED_LIST";
+    field public static final java.lang.String EXTRA_PAUSED_URI_LIST = "android.telephony.mbms.extra.PAUSED_URI_LIST";
+    field public static final java.lang.String EXTRA_SERVICE_ID = "android.telephony.mbms.extra.SERVICE_ID";
+    field public static final java.lang.String EXTRA_TEMP_FILES_IN_USE = "android.telephony.mbms.extra.TEMP_FILES_IN_USE";
+    field public static final java.lang.String EXTRA_TEMP_FILE_ROOT = "android.telephony.mbms.extra.TEMP_FILE_ROOT";
+    field public static final java.lang.String EXTRA_TEMP_LIST = "android.telephony.mbms.extra.TEMP_LIST";
+  }
+
 }
 
 package android.test {
@@ -40726,7 +40975,6 @@
     method public java.util.List<junit.framework.TestCase> getTestCases();
     method public java.lang.String getTestClassName();
     method public junit.framework.TestResult getTestResult();
-    method protected java.lang.Class loadSuiteClass(java.lang.String) throws java.lang.ClassNotFoundException;
     method protected void runFailed(java.lang.String);
     method public void runTest();
     method public void runTest(junit.framework.TestResult);
@@ -40987,12 +41235,10 @@
     ctor protected MockContentProvider();
     ctor public MockContentProvider(android.content.Context);
     ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
-    method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>);
     method public int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public java.lang.String getType(android.net.Uri);
     method public android.net.Uri insert(android.net.Uri, android.content.ContentValues);
     method public boolean onCreate();
-    method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
@@ -41266,10 +41512,6 @@
 
   public deprecated class MockResources extends android.content.res.Resources {
     ctor public MockResources();
-    method public int getColor(int) throws android.content.res.Resources.NotFoundException;
-    method public android.content.res.ColorStateList getColorStateList(int) throws android.content.res.Resources.NotFoundException;
-    method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
-    method public void updateConfiguration(android.content.res.Configuration, android.util.DisplayMetrics);
   }
 
 }
@@ -42517,7 +42759,6 @@
 
   public abstract class MetricAffectingSpan extends android.text.style.CharacterStyle implements android.text.style.UpdateLayout {
     ctor public MetricAffectingSpan();
-    method public android.text.style.MetricAffectingSpan getUnderlying();
     method public abstract void updateMeasureState(android.text.TextPaint);
   }
 
@@ -43199,28 +43440,14 @@
   public class TransitionSet extends android.transition.Transition {
     ctor public TransitionSet();
     ctor public TransitionSet(android.content.Context, android.util.AttributeSet);
-    method public android.transition.TransitionSet addListener(android.transition.Transition.TransitionListener);
-    method public android.transition.TransitionSet addTarget(android.view.View);
-    method public android.transition.TransitionSet addTarget(int);
-    method public android.transition.TransitionSet addTarget(java.lang.String);
-    method public android.transition.TransitionSet addTarget(java.lang.Class);
     method public android.transition.TransitionSet addTransition(android.transition.Transition);
     method public void captureEndValues(android.transition.TransitionValues);
     method public void captureStartValues(android.transition.TransitionValues);
-    method public android.transition.TransitionSet clone();
     method public int getOrdering();
     method public android.transition.Transition getTransitionAt(int);
     method public int getTransitionCount();
-    method public android.transition.TransitionSet removeListener(android.transition.Transition.TransitionListener);
-    method public android.transition.TransitionSet removeTarget(int);
-    method public android.transition.TransitionSet removeTarget(android.view.View);
-    method public android.transition.TransitionSet removeTarget(java.lang.Class);
-    method public android.transition.TransitionSet removeTarget(java.lang.String);
     method public android.transition.TransitionSet removeTransition(android.transition.Transition);
-    method public android.transition.TransitionSet setDuration(long);
-    method public android.transition.TransitionSet setInterpolator(android.animation.TimeInterpolator);
     method public android.transition.TransitionSet setOrdering(int);
-    method public android.transition.TransitionSet setStartDelay(long);
     field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
     field public static final int ORDERING_TOGETHER = 0; // 0x0
   }
@@ -43385,9 +43612,6 @@
 
   public class Base64InputStream extends java.io.FilterInputStream {
     ctor public Base64InputStream(java.io.InputStream, int);
-    method public int available();
-    method public void mark(int);
-    method public void reset();
   }
 
   public class Base64OutputStream extends java.io.FilterOutputStream {
@@ -44534,6 +44758,8 @@
 
   public final class InputDevice implements android.os.Parcelable {
     method public int describeContents();
+    method public void disable();
+    method public void enable();
     method public int getControllerNumber();
     method public java.lang.String getDescriptor();
     method public static android.view.InputDevice getDevice(int);
@@ -45075,10 +45301,13 @@
   public final class KeyboardShortcutGroup implements android.os.Parcelable {
     ctor public KeyboardShortcutGroup(java.lang.CharSequence, java.util.List<android.view.KeyboardShortcutInfo>);
     ctor public KeyboardShortcutGroup(java.lang.CharSequence);
+    ctor public KeyboardShortcutGroup(java.lang.CharSequence, java.util.List<android.view.KeyboardShortcutInfo>, boolean);
+    ctor public KeyboardShortcutGroup(java.lang.CharSequence, boolean);
     method public void addItem(android.view.KeyboardShortcutInfo);
     method public int describeContents();
     method public java.util.List<android.view.KeyboardShortcutInfo> getItems();
     method public java.lang.CharSequence getLabel();
+    method public boolean isSystemGroup();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.view.KeyboardShortcutGroup> CREATOR;
   }
@@ -45668,7 +45897,6 @@
     method public android.graphics.Canvas lockCanvas();
     method public android.graphics.Canvas lockCanvas(android.graphics.Rect);
     method protected final void onDraw(android.graphics.Canvas);
-    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setOpaque(boolean);
     method public void setSurfaceTexture(android.graphics.SurfaceTexture);
     method public void setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener);
@@ -46701,7 +46929,6 @@
     method public int getLayoutMode();
     method public android.animation.LayoutTransition getLayoutTransition();
     method public int getNestedScrollAxes();
-    method public android.view.ViewGroupOverlay getOverlay();
     method public int getPersistentDrawingCache();
     method public boolean getTouchscreenBlocksFocus();
     method public int indexOfChild(android.view.View);
@@ -47557,6 +47784,7 @@
   }
 
   public final class AccessibilityManager {
+    method public void addAccessibilityRequestPreparer(android.view.accessibility.AccessibilityRequestPreparer);
     method public boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener);
     method public void addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener, android.os.Handler);
     method public boolean addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener);
@@ -47567,6 +47795,7 @@
     method public void interrupt();
     method public boolean isEnabled();
     method public boolean isTouchExplorationEnabled();
+    method public void removeAccessibilityRequestPreparer(android.view.accessibility.AccessibilityRequestPreparer);
     method public boolean removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener);
     method public boolean removeTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener);
     method public void sendAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
@@ -47884,6 +48113,13 @@
     method public void setToIndex(int);
   }
 
+  public abstract class AccessibilityRequestPreparer {
+    ctor public AccessibilityRequestPreparer(android.view.View, int);
+    method public android.view.View getView();
+    method public abstract void onPrepareExtraData(int, java.lang.String, android.os.Bundle, android.os.Message);
+    field public static final int REQUEST_TYPE_EXTRA_DATA = 1; // 0x1
+  }
+
   public final class AccessibilityWindowInfo implements android.os.Parcelable {
     method public int describeContents();
     method public android.view.accessibility.AccessibilityNodeInfo getAnchor();
@@ -47977,7 +48213,6 @@
     ctor public Animation(android.content.Context, android.util.AttributeSet);
     method protected void applyTransformation(float, android.view.animation.Transformation);
     method public void cancel();
-    method protected android.view.animation.Animation clone() throws java.lang.CloneNotSupportedException;
     method public long computeDurationHint();
     method protected void ensureInterpolator();
     method public int getBackgroundColor();
@@ -48049,7 +48284,6 @@
     ctor public AnimationSet(android.content.Context, android.util.AttributeSet);
     ctor public AnimationSet(boolean);
     method public void addAnimation(android.view.animation.Animation);
-    method protected android.view.animation.AnimationSet clone() throws java.lang.CloneNotSupportedException;
     method public java.util.List<android.view.animation.Animation> getAnimations();
   }
 
@@ -48900,10 +49134,6 @@
   public final deprecated class CookieSyncManager extends android.webkit.WebSyncManager {
     method public static android.webkit.CookieSyncManager createInstance(android.content.Context);
     method public static android.webkit.CookieSyncManager getInstance();
-    method public deprecated void resetSync();
-    method public deprecated void startSync();
-    method public deprecated void stopSync();
-    method public deprecated void sync();
     method protected deprecated void syncFromRamToFlash();
     field protected static final java.lang.String LOGTAG = "websync";
     field protected android.webkit.WebViewDatabase mDataBase;
@@ -49455,7 +49685,6 @@
     method public void setWebChromeClient(android.webkit.WebChromeClient);
     method public static void setWebContentsDebuggingEnabled(boolean);
     method public void setWebViewClient(android.webkit.WebViewClient);
-    method public deprecated boolean shouldDelayChildPressedState();
     method public deprecated boolean showFindDialog(java.lang.String, boolean);
     method public void stopLoading();
     method public void zoomBy(float);
@@ -49579,7 +49808,6 @@
     method public void clearTextFilter();
     method public void deferNotifyDataSetChanged();
     method public void fling(int);
-    method public android.widget.AbsListView.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCacheColorHint();
     method public int getCheckedItemCount();
     method public long[] getCheckedItemIds();
@@ -49746,9 +49974,6 @@
     ctor public ActionMenuView(android.content.Context);
     ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
     method public void dismissPopupMenus();
-    method protected android.widget.ActionMenuView.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public android.view.Menu getMenu();
     method public android.graphics.drawable.Drawable getOverflowIcon();
     method public int getPopupTheme();
@@ -49924,6 +50149,7 @@
     method public void addAll(T...);
     method public void clear();
     method public static android.widget.ArrayAdapter<java.lang.CharSequence> createFromResource(android.content.Context, int, int);
+    method public java.lang.CharSequence[] getAutofillOptions();
     method public android.content.Context getContext();
     method public int getCount();
     method public android.content.res.Resources.Theme getDropDownViewTheme();
@@ -50295,7 +50521,6 @@
     ctor public EditText(android.content.Context, android.util.AttributeSet, int);
     ctor public EditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void extendSelection(int);
-    method public android.text.Editable getText();
     method public void selectAll();
     method public void setSelection(int, int);
     method public void setSelection(int);
@@ -50417,8 +50642,6 @@
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.FrameLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.FrameLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public deprecated boolean getConsiderGoneChildrenWhenMeasuring();
     method public boolean getMeasureAllChildren();
     method protected void onLayout(boolean, int, int, int, int);
@@ -50465,9 +50688,6 @@
     ctor public GridLayout(android.content.Context, android.util.AttributeSet);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.GridLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.GridLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.GridLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getAlignmentMode();
     method public int getColumnCount();
     method public int getOrientation();
@@ -50680,9 +50900,6 @@
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.LinearLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.LinearLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.LinearLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
@@ -51071,8 +51288,6 @@
     method public final synchronized void incrementSecondaryProgressBy(int);
     method public boolean isAnimating();
     method public synchronized boolean isIndeterminate();
-    method protected synchronized void onDraw(android.graphics.Canvas);
-    method protected synchronized void onMeasure(int, int);
     method public void onRestoreInstanceState(android.os.Parcelable);
     method public android.os.Parcelable onSaveInstanceState();
     method public synchronized void setIndeterminate(boolean);
@@ -51128,7 +51343,6 @@
     ctor public RadioGroup(android.content.Context, android.util.AttributeSet);
     method public void check(int);
     method public void clearCheck();
-    method public android.widget.RadioGroup.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCheckedRadioButtonId();
     method public void setOnCheckedChangeListener(android.widget.RadioGroup.OnCheckedChangeListener);
   }
@@ -51171,7 +51385,6 @@
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method public android.widget.RelativeLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getGravity();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setGravity(int);
@@ -51716,7 +51929,6 @@
   public class TableLayout extends android.widget.LinearLayout {
     ctor public TableLayout(android.content.Context);
     ctor public TableLayout(android.content.Context, android.util.AttributeSet);
-    method public android.widget.TableLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public boolean isColumnCollapsed(int);
     method public boolean isColumnShrinkable(int);
     method public boolean isColumnStretchable(int);
@@ -51741,7 +51953,6 @@
   public class TableRow extends android.widget.LinearLayout {
     ctor public TableRow(android.content.Context);
     ctor public TableRow(android.content.Context, android.util.AttributeSet);
-    method public android.widget.TableRow.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public android.view.View getVirtualChildAt(int);
     method public int getVirtualChildCount();
   }
@@ -52090,7 +52301,6 @@
     ctor public ToggleButton(android.content.Context);
     method public java.lang.CharSequence getTextOff();
     method public java.lang.CharSequence getTextOn();
-    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setTextOff(java.lang.CharSequence);
     method public void setTextOn(java.lang.CharSequence);
   }
@@ -52102,9 +52312,6 @@
     ctor public Toolbar(android.content.Context, android.util.AttributeSet, int, int);
     method public void collapseActionView();
     method public void dismissPopupMenus();
-    method protected android.widget.Toolbar.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.Toolbar.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.Toolbar.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getContentInsetEnd();
     method public int getContentInsetEndWithActions();
     method public int getContentInsetLeft();
@@ -52383,6 +52590,8 @@
     field public static final int OP_CONST_CLASS = 28; // 0x1c
     field public static final int OP_CONST_CLASS_JUMBO = 255; // 0xff
     field public static final int OP_CONST_HIGH16 = 21; // 0x15
+    field public static final int OP_CONST_METHOD_HANDLE = 254; // 0xfe
+    field public static final int OP_CONST_METHOD_TYPE = 255; // 0xff
     field public static final int OP_CONST_STRING = 26; // 0x1a
     field public static final int OP_CONST_STRING_JUMBO = 27; // 0x1b
     field public static final int OP_CONST_WIDE = 24; // 0x18
@@ -52627,8 +52836,6 @@
   public class BaseDexClassLoader extends java.lang.ClassLoader {
     ctor public BaseDexClassLoader(java.lang.String, java.io.File, java.lang.String, java.lang.ClassLoader);
     method public java.lang.String findLibrary(java.lang.String);
-    method protected java.util.Enumeration<java.net.URL> findResources(java.lang.String);
-    method protected synchronized java.lang.Package getPackage(java.lang.String);
   }
 
   public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
@@ -52851,10 +53058,6 @@
   public class BufferedInputStream extends java.io.FilterInputStream {
     ctor public BufferedInputStream(java.io.InputStream);
     ctor public BufferedInputStream(java.io.InputStream, int);
-    method public synchronized int available() throws java.io.IOException;
-    method public synchronized int read() throws java.io.IOException;
-    method public synchronized int read(byte[], int, int) throws java.io.IOException;
-    method public synchronized long skip(long) throws java.io.IOException;
     field protected volatile byte[] buf;
     field protected int count;
     field protected int marklimit;
@@ -52865,9 +53068,6 @@
   public class BufferedOutputStream extends java.io.FilterOutputStream {
     ctor public BufferedOutputStream(java.io.OutputStream);
     ctor public BufferedOutputStream(java.io.OutputStream, int);
-    method public synchronized void flush() throws java.io.IOException;
-    method public synchronized void write(int) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
   }
@@ -52893,12 +53093,7 @@
   public class ByteArrayInputStream extends java.io.InputStream {
     ctor public ByteArrayInputStream(byte[]);
     ctor public ByteArrayInputStream(byte[], int, int);
-    method public synchronized int available();
-    method public void mark(int);
     method public synchronized int read();
-    method public synchronized int read(byte[], int, int);
-    method public synchronized void reset();
-    method public synchronized long skip(long);
     field protected byte[] buf;
     field protected int count;
     field protected int mark;
@@ -52911,11 +53106,9 @@
     method public synchronized void reset();
     method public synchronized int size();
     method public synchronized byte[] toByteArray();
-    method public synchronized java.lang.String toString();
     method public synchronized java.lang.String toString(java.lang.String) throws java.io.UnsupportedEncodingException;
     method public deprecated synchronized java.lang.String toString(int);
     method public synchronized void write(int);
-    method public synchronized void write(byte[], int, int);
     method public synchronized void writeTo(java.io.OutputStream) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
@@ -52935,17 +53128,12 @@
   public class CharArrayWriter extends java.io.Writer {
     ctor public CharArrayWriter();
     ctor public CharArrayWriter(int);
-    method public java.io.CharArrayWriter append(java.lang.CharSequence);
-    method public java.io.CharArrayWriter append(java.lang.CharSequence, int, int);
-    method public java.io.CharArrayWriter append(char);
     method public void close();
     method public void flush();
     method public void reset();
     method public int size();
     method public char[] toCharArray();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(java.lang.String, int, int);
     method public void writeTo(java.io.Writer) throws java.io.IOException;
     field protected char[] buf;
     field protected int count;
@@ -53032,8 +53220,6 @@
   public class DataOutputStream extends java.io.FilterOutputStream implements java.io.DataOutput {
     ctor public DataOutputStream(java.io.OutputStream);
     method public final int size();
-    method public synchronized void write(int) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     method public final void writeBoolean(boolean) throws java.io.IOException;
     method public final void writeByte(int) throws java.io.IOException;
     method public final void writeBytes(java.lang.String) throws java.io.IOException;
@@ -53133,7 +53319,6 @@
     ctor public FileInputStream(java.lang.String) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.FileDescriptor);
-    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public int read() throws java.io.IOException;
@@ -53150,7 +53335,6 @@
     ctor public FileOutputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.File, boolean) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.FileDescriptor);
-    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
@@ -53264,8 +53448,6 @@
   public deprecated class LineNumberInputStream extends java.io.FilterInputStream {
     ctor public LineNumberInputStream(java.io.InputStream);
     method public int getLineNumber();
-    method public void mark(int);
-    method public void reset() throws java.io.IOException;
     method public void setLineNumber(int);
   }
 
@@ -53495,10 +53677,8 @@
     ctor public PipedInputStream(java.io.PipedOutputStream, int) throws java.io.IOException;
     ctor public PipedInputStream();
     ctor public PipedInputStream(int);
-    method public synchronized int available() throws java.io.IOException;
     method public void connect(java.io.PipedOutputStream) throws java.io.IOException;
     method public synchronized int read() throws java.io.IOException;
-    method public synchronized int read(byte[], int, int) throws java.io.IOException;
     method protected synchronized void receive(int) throws java.io.IOException;
     field protected static final int PIPE_SIZE = 1024; // 0x400
     field protected byte[] buffer;
@@ -53510,7 +53690,6 @@
     ctor public PipedOutputStream(java.io.PipedInputStream) throws java.io.IOException;
     ctor public PipedOutputStream();
     method public synchronized void connect(java.io.PipedInputStream) throws java.io.IOException;
-    method public synchronized void flush() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
   }
 
@@ -53521,9 +53700,7 @@
     ctor public PipedReader(int);
     method public void close() throws java.io.IOException;
     method public void connect(java.io.PipedWriter) throws java.io.IOException;
-    method public synchronized int read() throws java.io.IOException;
     method public synchronized int read(char[], int, int) throws java.io.IOException;
-    method public synchronized boolean ready() throws java.io.IOException;
   }
 
   public class PipedWriter extends java.io.Writer {
@@ -53548,8 +53725,6 @@
     method public java.io.PrintStream append(char);
     method public boolean checkError();
     method protected void clearError();
-    method public void close();
-    method public void flush();
     method public java.io.PrintStream format(java.lang.String, java.lang.Object...);
     method public java.io.PrintStream format(java.util.Locale, java.lang.String, java.lang.Object...);
     method public void print(boolean);
@@ -53574,8 +53749,6 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
-    method public void write(int);
-    method public void write(byte[], int, int);
   }
 
   public class PrintWriter extends java.io.Writer {
@@ -53587,9 +53760,6 @@
     ctor public PrintWriter(java.lang.String, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
     ctor public PrintWriter(java.io.File) throws java.io.FileNotFoundException;
     ctor public PrintWriter(java.io.File, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
-    method public java.io.PrintWriter append(java.lang.CharSequence);
-    method public java.io.PrintWriter append(java.lang.CharSequence, int, int);
-    method public java.io.PrintWriter append(char);
     method public boolean checkError();
     method protected void clearError();
     method public void close();
@@ -53618,18 +53788,13 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(char[]);
-    method public void write(java.lang.String, int, int);
-    method public void write(java.lang.String);
     field protected java.io.Writer out;
   }
 
   public class PushbackInputStream extends java.io.FilterInputStream {
     ctor public PushbackInputStream(java.io.InputStream, int);
     ctor public PushbackInputStream(java.io.InputStream);
-    method public synchronized void close() throws java.io.IOException;
     method public void unread(int) throws java.io.IOException;
     method public void unread(byte[], int, int) throws java.io.IOException;
     method public void unread(byte[]) throws java.io.IOException;
@@ -53753,11 +53918,7 @@
 
   public deprecated class StringBufferInputStream extends java.io.InputStream {
     ctor public StringBufferInputStream(java.lang.String);
-    method public synchronized int available();
     method public synchronized int read();
-    method public synchronized int read(byte[], int, int);
-    method public synchronized void reset();
-    method public synchronized long skip(long);
     field protected java.lang.String buffer;
     field protected int count;
     field protected int pos;
@@ -53772,16 +53933,10 @@
   public class StringWriter extends java.io.Writer {
     ctor public StringWriter();
     ctor public StringWriter(int);
-    method public java.io.StringWriter append(java.lang.CharSequence);
-    method public java.io.StringWriter append(java.lang.CharSequence, int, int);
-    method public java.io.StringWriter append(char);
     method public void close() throws java.io.IOException;
     method public void flush();
     method public java.lang.StringBuffer getBuffer();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(java.lang.String);
-    method public void write(java.lang.String, int, int);
   }
 
   public class SyncFailedException extends java.io.IOException {
@@ -53796,7 +53951,6 @@
   public class UncheckedIOException extends java.lang.RuntimeException {
     ctor public UncheckedIOException(java.lang.String, java.io.IOException);
     ctor public UncheckedIOException(java.io.IOException);
-    method public java.io.IOException getCause();
   }
 
   public class UnsupportedEncodingException extends java.io.IOException {
@@ -53806,7 +53960,6 @@
 
   public class WriteAbortedException extends java.io.ObjectStreamException {
     ctor public WriteAbortedException(java.lang.String, java.lang.Exception);
-    method public java.lang.Throwable getCause();
     field public java.lang.Exception detail;
   }
 
@@ -54574,7 +54727,6 @@
     ctor public ClassNotFoundException();
     ctor public ClassNotFoundException(java.lang.String);
     ctor public ClassNotFoundException(java.lang.String, java.lang.Throwable);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -54679,7 +54831,6 @@
     ctor public ExceptionInInitializerError();
     ctor public ExceptionInInitializerError(java.lang.Throwable);
     ctor public ExceptionInInitializerError(java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -55467,16 +55618,8 @@
     method public synchronized java.lang.StringBuffer append(float);
     method public synchronized java.lang.StringBuffer append(double);
     method public synchronized java.lang.StringBuffer appendCodePoint(int);
-    method public synchronized int capacity();
-    method public synchronized char charAt(int);
-    method public synchronized int codePointAt(int);
-    method public synchronized int codePointBefore(int);
-    method public synchronized int codePointCount(int, int);
     method public synchronized java.lang.StringBuffer delete(int, int);
     method public synchronized java.lang.StringBuffer deleteCharAt(int);
-    method public synchronized void ensureCapacity(int);
-    method public synchronized void getChars(int, int, char[], int);
-    method public synchronized int indexOf(java.lang.String, int);
     method public synchronized java.lang.StringBuffer insert(int, char[], int, int);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.Object);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.String);
@@ -55489,18 +55632,9 @@
     method public java.lang.StringBuffer insert(int, long);
     method public java.lang.StringBuffer insert(int, float);
     method public java.lang.StringBuffer insert(int, double);
-    method public synchronized int lastIndexOf(java.lang.String, int);
-    method public synchronized int length();
-    method public synchronized int offsetByCodePoints(int, int);
     method public synchronized java.lang.StringBuffer replace(int, int, java.lang.String);
     method public synchronized java.lang.StringBuffer reverse();
-    method public synchronized void setCharAt(int, char);
-    method public synchronized void setLength(int);
-    method public synchronized java.lang.CharSequence subSequence(int, int);
-    method public synchronized java.lang.String substring(int);
-    method public synchronized java.lang.String substring(int, int);
     method public synchronized java.lang.String toString();
-    method public synchronized void trimToSize();
   }
 
   public final class StringBuilder extends java.lang.AbstractStringBuilder implements java.lang.CharSequence java.io.Serializable {
@@ -56155,7 +56289,6 @@
     ctor protected InvocationTargetException();
     ctor public InvocationTargetException(java.lang.Throwable);
     ctor public InvocationTargetException(java.lang.Throwable, java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getTargetException();
   }
 
@@ -56271,7 +56404,6 @@
   public class UndeclaredThrowableException extends java.lang.RuntimeException {
     ctor public UndeclaredThrowableException(java.lang.Throwable);
     ctor public UndeclaredThrowableException(java.lang.Throwable, java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getUndeclaredThrowable();
   }
 
@@ -57169,7 +57301,6 @@
     method public java.lang.String getQuery();
     method public java.lang.String getRef();
     method public java.lang.String getUserInfo();
-    method public synchronized int hashCode();
     method public java.net.URLConnection openConnection() throws java.io.IOException;
     method public java.net.URLConnection openConnection(java.net.Proxy) throws java.io.IOException;
     method public final java.io.InputStream openStream() throws java.io.IOException;
@@ -57399,6 +57530,7 @@
     method public final int arrayOffset();
     method public abstract java.nio.CharBuffer asReadOnlyBuffer();
     method public final char charAt(int);
+    method public java.util.stream.IntStream chars();
     method public abstract java.nio.CharBuffer compact();
     method public int compareTo(java.nio.CharBuffer);
     method public abstract java.nio.CharBuffer duplicate();
@@ -58255,7 +58387,6 @@
 
   public final class DirectoryIteratorException extends java.util.ConcurrentModificationException {
     ctor public DirectoryIteratorException(java.io.IOException);
-    method public java.io.IOException getCause();
   }
 
   public class DirectoryNotEmptyException extends java.nio.file.FileSystemException {
@@ -59221,11 +59352,9 @@
   public static class KeyStore.PasswordProtection implements javax.security.auth.Destroyable java.security.KeyStore.ProtectionParameter {
     ctor public KeyStore.PasswordProtection(char[]);
     ctor public KeyStore.PasswordProtection(char[], java.lang.String, java.security.spec.AlgorithmParameterSpec);
-    method public synchronized void destroy() throws javax.security.auth.DestroyFailedException;
     method public synchronized char[] getPassword();
     method public java.lang.String getProtectionAlgorithm();
     method public java.security.spec.AlgorithmParameterSpec getProtectionParameters();
-    method public synchronized boolean isDestroyed();
   }
 
   public static final class KeyStore.PrivateKeyEntry implements java.security.KeyStore.Entry {
@@ -59405,7 +59534,6 @@
 
   public class PrivilegedActionException extends java.lang.Exception {
     ctor public PrivilegedActionException(java.lang.Exception);
-    method public java.lang.Throwable getCause();
     method public java.lang.Exception getException();
   }
 
@@ -59428,30 +59556,22 @@
     method public synchronized java.lang.Object compute(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfAbsent(java.lang.Object, java.util.function.Function<? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfPresent(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
-    method public java.util.Enumeration<java.lang.Object> elements();
-    method public synchronized java.util.Set<java.util.Map.Entry<java.lang.Object, java.lang.Object>> entrySet();
     method public synchronized void forEach(java.util.function.BiConsumer<? super java.lang.Object, ? super java.lang.Object>);
-    method public java.lang.Object get(java.lang.Object);
     method public java.lang.String getInfo();
     method public java.lang.String getName();
     method public synchronized java.lang.Object getOrDefault(java.lang.Object, java.lang.Object);
     method public synchronized java.security.Provider.Service getService(java.lang.String, java.lang.String);
     method public synchronized java.util.Set<java.security.Provider.Service> getServices();
     method public double getVersion();
-    method public java.util.Set<java.lang.Object> keySet();
-    method public java.util.Enumeration<java.lang.Object> keys();
     method public synchronized java.lang.Object merge(java.lang.Object, java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object put(java.lang.Object, java.lang.Object);
     method public synchronized void putAll(java.util.Map<?, ?>);
     method public synchronized java.lang.Object putIfAbsent(java.lang.Object, java.lang.Object);
     method protected synchronized void putService(java.security.Provider.Service);
-    method public synchronized java.lang.Object remove(java.lang.Object);
     method protected synchronized void removeService(java.security.Provider.Service);
     method public synchronized boolean replace(java.lang.Object, java.lang.Object, java.lang.Object);
     method public synchronized java.lang.Object replace(java.lang.Object, java.lang.Object);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
-    method public java.lang.String toString();
-    method public java.util.Collection<java.lang.Object> values();
   }
 
   public static class Provider.Service {
@@ -59497,9 +59617,7 @@
     method public final java.security.Provider getProvider();
     method public static byte[] getSeed(int);
     method protected final int next(int);
-    method public synchronized void nextBytes(byte[]);
     method public synchronized void setSeed(byte[]);
-    method public void setSeed(long);
   }
 
   public abstract class SecureRandomSpi implements java.io.Serializable {
@@ -60046,7 +60164,6 @@
 
   public abstract class PKIXRevocationChecker extends java.security.cert.PKIXCertPathChecker {
     ctor protected PKIXRevocationChecker();
-    method public java.security.cert.PKIXRevocationChecker clone();
     method public java.util.List<java.security.cert.Extension> getOcspExtensions();
     method public java.net.URI getOcspResponder();
     method public java.security.cert.X509Certificate getOcspResponderCert();
@@ -62299,6 +62416,7 @@
   public final class DayOfWeek extends java.lang.Enum implements java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public static java.time.DayOfWeek from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -62306,6 +62424,8 @@
     method public java.time.DayOfWeek minus(long);
     method public static java.time.DayOfWeek of(int);
     method public java.time.DayOfWeek plus(long);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.DayOfWeek valueOf(java.lang.String);
     method public static final java.time.DayOfWeek[] values();
     enum_constant public static final java.time.DayOfWeek FRIDAY;
@@ -62381,8 +62501,6 @@
     method public boolean isBefore(java.time.Instant);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.Instant minus(java.time.temporal.TemporalAmount);
-    method public java.time.Instant minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant minusMillis(long);
     method public java.time.Instant minusNanos(long);
     method public java.time.Instant minusSeconds(long);
@@ -62392,7 +62510,6 @@
     method public static java.time.Instant ofEpochSecond(long);
     method public static java.time.Instant ofEpochSecond(long, long);
     method public static java.time.Instant parse(java.lang.CharSequence);
-    method public java.time.Instant plus(java.time.temporal.TemporalAmount);
     method public java.time.Instant plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant plusMillis(long);
     method public java.time.Instant plusNanos(long);
@@ -62400,7 +62517,6 @@
     method public long toEpochMilli();
     method public java.time.Instant truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Instant with(java.time.temporal.TemporalAdjuster);
     method public java.time.Instant with(java.time.temporal.TemporalField, long);
     field public static final java.time.Instant EPOCH;
     field public static final java.time.Instant MAX;
@@ -62410,7 +62526,6 @@
   public final class LocalDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
     method public java.time.LocalDateTime atStartOfDay();
     method public java.time.ZonedDateTime atStartOfDay(java.time.ZoneId);
-    method public java.time.LocalDateTime atTime(java.time.LocalTime);
     method public java.time.LocalDateTime atTime(int, int);
     method public java.time.LocalDateTime atTime(int, int, int);
     method public java.time.LocalDateTime atTime(int, int, int, int);
@@ -62425,8 +62540,6 @@
     method public int getMonthValue();
     method public int getYear();
     method public int lengthOfMonth();
-    method public java.time.LocalDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDate minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate minusDays(long);
     method public java.time.LocalDate minusMonths(long);
     method public java.time.LocalDate minusWeeks(long);
@@ -62440,16 +62553,12 @@
     method public static java.time.LocalDate ofYearDay(int, int);
     method public static java.time.LocalDate parse(java.lang.CharSequence);
     method public static java.time.LocalDate parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate plusDays(long);
     method public java.time.LocalDate plusMonths(long);
     method public java.time.LocalDate plusWeeks(long);
     method public java.time.LocalDate plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public java.time.Period until(java.time.chrono.ChronoLocalDate);
-    method public java.time.LocalDate with(java.time.temporal.TemporalAdjuster);
-    method public java.time.LocalDate with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDate withDayOfMonth(int);
     method public java.time.LocalDate withDayOfYear(int);
     method public java.time.LocalDate withMonth(int);
@@ -62474,8 +62583,6 @@
     method public int getSecond();
     method public int getYear();
     method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.LocalDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime minusDays(long);
     method public java.time.LocalDateTime minusHours(long);
     method public java.time.LocalDateTime minusMinutes(long);
@@ -62498,7 +62605,6 @@
     method public static java.time.LocalDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime plusDays(long);
     method public java.time.LocalDateTime plusHours(long);
@@ -62512,7 +62618,6 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.LocalDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.LocalDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDateTime withDayOfMonth(int);
     method public java.time.LocalDateTime withDayOfYear(int);
@@ -62542,8 +62647,6 @@
     method public boolean isBefore(java.time.LocalTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime minusHours(long);
     method public java.time.LocalTime minusMinutes(long);
     method public java.time.LocalTime minusNanos(long);
@@ -62558,7 +62661,6 @@
     method public static java.time.LocalTime ofSecondOfDay(long);
     method public static java.time.LocalTime parse(java.lang.CharSequence);
     method public static java.time.LocalTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime plusHours(long);
     method public java.time.LocalTime plusMinutes(long);
@@ -62568,7 +62670,6 @@
     method public int toSecondOfDay();
     method public java.time.LocalTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalTime withHour(int);
     method public java.time.LocalTime withMinute(int);
@@ -62585,6 +62686,7 @@
     method public int firstDayOfYear(boolean);
     method public java.time.Month firstMonthOfQuarter();
     method public static java.time.Month from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -62595,6 +62697,8 @@
     method public java.time.Month minus(long);
     method public static java.time.Month of(int);
     method public java.time.Month plus(long);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.Month valueOf(java.lang.String);
     method public static final java.time.Month[] values();
     enum_constant public static final java.time.Month APRIL;
@@ -62661,8 +62765,6 @@
     method public boolean isEqual(java.time.OffsetDateTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime minusDays(long);
     method public java.time.OffsetDateTime minusHours(long);
     method public java.time.OffsetDateTime minusMinutes(long);
@@ -62680,7 +62782,6 @@
     method public static java.time.OffsetDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.OffsetDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime plusDays(long);
     method public java.time.OffsetDateTime plusHours(long);
@@ -62700,7 +62801,6 @@
     method public java.time.ZonedDateTime toZonedDateTime();
     method public java.time.OffsetDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetDateTime withDayOfMonth(int);
     method public java.time.OffsetDateTime withDayOfYear(int);
@@ -62733,8 +62833,6 @@
     method public boolean isEqual(java.time.OffsetTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime minusHours(long);
     method public java.time.OffsetTime minusMinutes(long);
     method public java.time.OffsetTime minusNanos(long);
@@ -62747,7 +62845,6 @@
     method public static java.time.OffsetTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetTime parse(java.lang.CharSequence);
     method public static java.time.OffsetTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.OffsetTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime plusHours(long);
     method public java.time.OffsetTime plusMinutes(long);
@@ -62756,7 +62853,6 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.OffsetTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetTime withHour(int);
     method public java.time.OffsetTime withMinute(int);
@@ -62783,7 +62879,6 @@
     method public java.time.Period minusMonths(long);
     method public java.time.Period minusYears(long);
     method public java.time.Period multipliedBy(int);
-    method public java.time.Period negated();
     method public java.time.Period normalized();
     method public static java.time.Period of(int, int, int);
     method public static java.time.Period ofDays(int);
@@ -62822,8 +62917,6 @@
     method public boolean isSupported(java.time.temporal.TemporalUnit);
     method public boolean isValidMonthDay(java.time.MonthDay);
     method public int length();
-    method public java.time.Year minus(java.time.temporal.TemporalAmount);
-    method public java.time.Year minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year minusYears(long);
     method public static java.time.Year now();
     method public static java.time.Year now(java.time.ZoneId);
@@ -62831,11 +62924,9 @@
     method public static java.time.Year of(int);
     method public static java.time.Year parse(java.lang.CharSequence);
     method public static java.time.Year parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.Year plus(java.time.temporal.TemporalAmount);
     method public java.time.Year plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Year with(java.time.temporal.TemporalAdjuster);
     method public java.time.Year with(java.time.temporal.TemporalField, long);
     field public static final int MAX_VALUE = 999999999; // 0x3b9ac9ff
     field public static final int MIN_VALUE = -999999999; // 0xc4653601
@@ -62860,8 +62951,6 @@
     method public boolean isValidDay(int);
     method public int lengthOfMonth();
     method public int lengthOfYear();
-    method public java.time.YearMonth minus(java.time.temporal.TemporalAmount);
-    method public java.time.YearMonth minus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth minusMonths(long);
     method public java.time.YearMonth minusYears(long);
     method public static java.time.YearMonth now();
@@ -62871,12 +62960,10 @@
     method public static java.time.YearMonth of(int, int);
     method public static java.time.YearMonth parse(java.lang.CharSequence);
     method public static java.time.YearMonth parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.YearMonth plus(java.time.temporal.TemporalAmount);
     method public java.time.YearMonth plus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth plusMonths(long);
     method public java.time.YearMonth plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.YearMonth with(java.time.temporal.TemporalAdjuster);
     method public java.time.YearMonth with(java.time.temporal.TemporalField, long);
     method public java.time.YearMonth withMonth(int);
     method public java.time.YearMonth withYear(int);
@@ -62900,6 +62987,7 @@
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public int compareTo(java.time.ZoneOffset);
     method public static java.time.ZoneOffset from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getId();
     method public long getLong(java.time.temporal.TemporalField);
     method public java.time.zone.ZoneRules getRules();
@@ -62910,6 +62998,8 @@
     method public static java.time.ZoneOffset ofHoursMinutes(int, int);
     method public static java.time.ZoneOffset ofHoursMinutesSeconds(int, int, int);
     method public static java.time.ZoneOffset ofTotalSeconds(int);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     field public static final java.time.ZoneOffset MAX;
     field public static final java.time.ZoneOffset MIN;
     field public static final java.time.ZoneOffset UTC;
@@ -62930,8 +63020,6 @@
     method public int getYear();
     method public java.time.ZoneId getZone();
     method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.ZonedDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.ZonedDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime minusDays(long);
     method public java.time.ZonedDateTime minusHours(long);
     method public java.time.ZonedDateTime minusMinutes(long);
@@ -62952,7 +63040,6 @@
     method public static java.time.ZonedDateTime ofStrict(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneId);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.ZonedDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.ZonedDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime plusDays(long);
     method public java.time.ZonedDateTime plusHours(long);
@@ -62962,12 +63049,10 @@
     method public java.time.ZonedDateTime plusSeconds(long);
     method public java.time.ZonedDateTime plusWeeks(long);
     method public java.time.ZonedDateTime plusYears(long);
-    method public java.time.LocalDate toLocalDate();
     method public java.time.LocalDateTime toLocalDateTime();
     method public java.time.OffsetDateTime toOffsetDateTime();
     method public java.time.ZonedDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.ZonedDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.ZonedDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.ZonedDateTime withDayOfMonth(int);
     method public java.time.ZonedDateTime withDayOfYear(int);
@@ -63012,27 +63097,17 @@
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
     method public abstract int lengthOfMonth();
     method public default int lengthOfYear();
-    method public default java.time.chrono.ChronoLocalDate minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDate minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDate plus(java.time.temporal.TemporalAmount);
     method public default java.time.chrono.ChronoLocalDate plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDate> timeLineOrder();
     method public default long toEpochDay();
     method public abstract java.lang.String toString();
     method public abstract long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public abstract java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalAdjuster);
     method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalField, long);
   }
 
    abstract class ChronoLocalDateImpl<D extends java.time.chrono.ChronoLocalDate> implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public D minus(java.time.temporal.TemporalAmount);
-    method public D minus(long, java.time.temporal.TemporalUnit);
-    method public D plus(java.time.temporal.TemporalAmount);
-    method public D plus(long, java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public D with(java.time.temporal.TemporalAdjuster);
-    method public D with(java.time.temporal.TemporalField, long);
   }
 
   public abstract interface ChronoLocalDateTime<D extends java.time.chrono.ChronoLocalDate> implements java.lang.Comparable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
@@ -63049,9 +63124,6 @@
     method public default boolean isEqual(java.time.chrono.ChronoLocalDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDateTime<D> minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDateTime<D> minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDateTime<?>> timeLineOrder();
     method public default long toEpochSecond(java.time.ZoneOffset);
@@ -63059,7 +63131,6 @@
     method public abstract D toLocalDate();
     method public abstract java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
-    method public default java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalField, long);
   }
 
@@ -63097,9 +63168,6 @@
     method public default boolean isEqual(java.time.chrono.ChronoZonedDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoZonedDateTime<D> minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoZonedDateTime<D> minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoZonedDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoZonedDateTime<?>> timeLineOrder();
     method public default long toEpochSecond();
@@ -63108,7 +63176,6 @@
     method public abstract java.time.chrono.ChronoLocalDateTime<D> toLocalDateTime();
     method public default java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
-    method public default java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalField, long);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withEarlierOffsetAtOverlap();
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withLaterOffsetAtOverlap();
@@ -63175,7 +63242,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.HijrahDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.HijrahDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.HijrahChronology INSTANCE;
@@ -63187,24 +63253,23 @@
     method public java.time.chrono.HijrahChronology getChronology();
     method public java.time.chrono.HijrahEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
+    method public boolean isLeapYear();
     method public int lengthOfMonth();
-    method public java.time.chrono.HijrahDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.HijrahDate minus(long, java.time.temporal.TemporalUnit);
+    method public int lengthOfYear();
     method public static java.time.chrono.HijrahDate now();
     method public static java.time.chrono.HijrahDate now(java.time.ZoneId);
     method public static java.time.chrono.HijrahDate now(java.time.Clock);
     method public static java.time.chrono.HijrahDate of(int, int, int);
-    method public java.time.chrono.HijrahDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.HijrahDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalAdjuster);
     method public java.time.chrono.HijrahDate withVariant(java.time.chrono.HijrahChronology);
   }
 
   public final class HijrahEra extends java.lang.Enum implements java.time.chrono.Era {
     method public int getValue();
     method public static java.time.chrono.HijrahEra of(int);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.chrono.HijrahEra valueOf(java.lang.String);
     method public static final java.time.chrono.HijrahEra[] values();
     enum_constant public static final java.time.chrono.HijrahEra AH;
@@ -63229,7 +63294,6 @@
     method public java.time.Period period(int, int, int);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.LocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.ZonedDateTime zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.ZonedDateTime zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.IsoChronology INSTANCE;
@@ -63262,7 +63326,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.JapaneseDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.JapaneseDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.JapaneseChronology INSTANCE;
@@ -63274,19 +63337,17 @@
     method public java.time.chrono.JapaneseChronology getChronology();
     method public java.time.chrono.JapaneseEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
+    method public boolean isSupported(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.JapaneseDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.JapaneseDate minus(long, java.time.temporal.TemporalUnit);
+    method public int lengthOfYear();
     method public static java.time.chrono.JapaneseDate now();
     method public static java.time.chrono.JapaneseDate now(java.time.ZoneId);
     method public static java.time.chrono.JapaneseDate now(java.time.Clock);
     method public static java.time.chrono.JapaneseDate of(java.time.chrono.JapaneseEra, int, int, int);
     method public static java.time.chrono.JapaneseDate of(int, int, int);
-    method public java.time.chrono.JapaneseDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.JapaneseDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class JapaneseEra implements java.time.chrono.Era java.io.Serializable {
@@ -63318,7 +63379,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.MinguoDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.MinguoDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.MinguoChronology INSTANCE;
@@ -63331,17 +63391,13 @@
     method public java.time.chrono.MinguoEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.MinguoDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.MinguoDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.MinguoDate now();
     method public static java.time.chrono.MinguoDate now(java.time.ZoneId);
     method public static java.time.chrono.MinguoDate now(java.time.Clock);
     method public static java.time.chrono.MinguoDate of(int, int, int);
-    method public java.time.chrono.MinguoDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.MinguoDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class MinguoEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -63371,7 +63427,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.ThaiBuddhistDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.ThaiBuddhistDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.ThaiBuddhistChronology INSTANCE;
@@ -63384,17 +63439,13 @@
     method public java.time.chrono.ThaiBuddhistEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.ThaiBuddhistDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ThaiBuddhistDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.ThaiBuddhistDate now();
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.ZoneId);
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.Clock);
     method public static java.time.chrono.ThaiBuddhistDate of(int, int, int);
-    method public java.time.chrono.ThaiBuddhistDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ThaiBuddhistDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class ThaiBuddhistEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -63573,6 +63624,7 @@
     method public int checkValidIntValue(long);
     method public long checkValidValue(long);
     method public java.time.temporal.TemporalUnit getBaseUnit();
+    method public java.lang.String getDisplayName(java.util.Locale);
     method public long getFrom(java.time.temporal.TemporalAccessor);
     method public java.time.temporal.TemporalUnit getRangeUnit();
     method public boolean isDateBased();
@@ -63620,6 +63672,7 @@
     method public java.time.Duration getDuration();
     method public boolean isDateBased();
     method public boolean isDurationEstimated();
+    method public boolean isSupportedBy(java.time.temporal.Temporal);
     method public boolean isTimeBased();
     method public static java.time.temporal.ChronoUnit valueOf(java.lang.String);
     method public static final java.time.temporal.ChronoUnit[] values();
@@ -63959,6 +64012,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ArrayList<E> extends java.util.AbstractList implements java.lang.Cloneable java.util.List java.util.RandomAccess java.io.Serializable {
@@ -63969,7 +64023,11 @@
     method public void ensureCapacity(int);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public E get(int);
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
+    method public void replaceAll(java.util.function.UnaryOperator<E>);
     method public int size();
+    method public void sort(java.util.Comparator<? super E>);
+    method public java.util.Spliterator<E> spliterator();
     method public void trimToSize();
   }
 
@@ -64340,7 +64398,6 @@
     method public default boolean removeIf(java.util.function.Predicate<? super E>);
     method public abstract boolean retainAll(java.util.Collection<?>);
     method public abstract int size();
-    method public default java.util.Spliterator<E> spliterator();
     method public default java.util.stream.Stream<E> stream();
     method public abstract java.lang.Object[] toArray();
     method public abstract <T> T[] toArray(T[]);
@@ -64681,7 +64738,18 @@
     ctor public HashMap();
     ctor public HashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
+    method public V putIfAbsent(K, V);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class HashSet<E> extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set {
@@ -64692,6 +64760,7 @@
     method public java.lang.Object clone();
     method public java.util.Iterator<E> iterator();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class Hashtable<K, V> extends java.util.Dictionary implements java.lang.Cloneable java.util.Map java.io.Serializable {
@@ -64709,11 +64778,9 @@
     method public boolean containsValue(java.lang.Object);
     method public synchronized java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
-    method public synchronized boolean equals(java.lang.Object);
     method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public synchronized V get(java.lang.Object);
     method public synchronized V getOrDefault(java.lang.Object, V);
-    method public synchronized int hashCode();
     method public synchronized boolean isEmpty();
     method public java.util.Set<K> keySet();
     method public synchronized java.util.Enumeration<K> keys();
@@ -64728,7 +64795,6 @@
     method public synchronized V replace(K, V);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public synchronized int size();
-    method public synchronized java.lang.String toString();
     method public java.util.Collection<V> values();
   }
 
@@ -64738,6 +64804,8 @@
     ctor public IdentityHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class IllegalFormatCodePointException extends java.util.IllegalFormatException {
@@ -64848,6 +64916,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface List<E> implements java.util.Collection {
@@ -65470,7 +65539,6 @@
     ctor public SimpleTimeZone(int, java.lang.String, int, int, int, int, int, int, int, int, int, int, int);
     method public int getOffset(int, int, int, int, int, int);
     method public int getRawOffset();
-    method public synchronized int hashCode();
     method public boolean inDaylightTime(java.util.Date);
     method public void setDSTSavings(int);
     method public void setEndRule(int, int, int, int);
@@ -65743,6 +65811,7 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public java.util.NavigableMap<K, V> headMap(K, boolean);
     method public java.util.SortedMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
@@ -65754,6 +65823,9 @@
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.SortedMap<K, V> subMap(K, K);
     method public java.util.NavigableMap<K, V> tailMap(K, boolean);
@@ -65781,6 +65853,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.SortedSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -65817,49 +65890,30 @@
     ctor public Vector(int);
     ctor public Vector();
     ctor public Vector(java.util.Collection<? extends E>);
-    method public synchronized boolean add(E);
-    method public synchronized boolean addAll(java.util.Collection<? extends E>);
-    method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
     method public synchronized void addElement(E);
     method public synchronized int capacity();
     method public synchronized java.lang.Object clone();
-    method public synchronized boolean containsAll(java.util.Collection<?>);
     method public synchronized void copyInto(java.lang.Object[]);
     method public synchronized E elementAt(int);
     method public java.util.Enumeration<E> elements();
     method public synchronized void ensureCapacity(int);
-    method public synchronized boolean equals(java.lang.Object);
     method public synchronized E firstElement();
     method public synchronized void forEach(java.util.function.Consumer<? super E>);
     method public synchronized E get(int);
-    method public synchronized int hashCode();
     method public synchronized int indexOf(java.lang.Object, int);
     method public synchronized void insertElementAt(E, int);
-    method public synchronized boolean isEmpty();
-    method public synchronized java.util.Iterator<E> iterator();
     method public synchronized E lastElement();
-    method public synchronized int lastIndexOf(java.lang.Object);
     method public synchronized int lastIndexOf(java.lang.Object, int);
-    method public synchronized java.util.ListIterator<E> listIterator(int);
-    method public synchronized java.util.ListIterator<E> listIterator();
-    method public synchronized E remove(int);
-    method public synchronized boolean removeAll(java.util.Collection<?>);
     method public synchronized void removeAllElements();
     method public synchronized boolean removeElement(java.lang.Object);
     method public synchronized void removeElementAt(int);
     method public synchronized boolean removeIf(java.util.function.Predicate<? super E>);
-    method protected synchronized void removeRange(int, int);
     method public synchronized void replaceAll(java.util.function.UnaryOperator<E>);
-    method public synchronized boolean retainAll(java.util.Collection<?>);
-    method public synchronized E set(int, E);
     method public synchronized void setElementAt(E, int);
     method public synchronized void setSize(int);
     method public synchronized int size();
     method public synchronized void sort(java.util.Comparator<? super E>);
-    method public synchronized java.util.List<E> subList(int, int);
-    method public synchronized java.lang.Object[] toArray();
-    method public synchronized <T> T[] toArray(T[]);
-    method public synchronized java.lang.String toString();
+    method public java.util.Spliterator<E> spliterator();
     method public synchronized void trimToSize();
     field protected int capacityIncrement;
     field protected int elementCount;
@@ -65872,6 +65926,8 @@
     ctor public WeakHashMap();
     ctor public WeakHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
 }
@@ -65906,6 +65962,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -66096,9 +66153,13 @@
     ctor public ConcurrentHashMap(java.util.Map<? extends K, ? extends V>);
     ctor public ConcurrentHashMap(int, float);
     ctor public ConcurrentHashMap(int, float, int);
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public boolean contains(java.lang.Object);
     method public java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public void forEach(long, java.util.function.BiConsumer<? super K, ? super V>);
     method public <U> void forEach(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.Consumer<? super U>);
     method public void forEachEntry(long, java.util.function.Consumer<? super java.util.Map.Entry<K, V>>);
@@ -66107,11 +66168,14 @@
     method public <U> void forEachKey(long, java.util.function.Function<? super K, ? extends U>, java.util.function.Consumer<? super U>);
     method public void forEachValue(long, java.util.function.Consumer<? super V>);
     method public <U> void forEachValue(long, java.util.function.Function<? super V, ? extends U>, java.util.function.Consumer<? super U>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentHashMap.KeySetView<K, V> keySet(V);
     method public java.util.Enumeration<K> keys();
     method public long mappingCount();
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet();
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet(int);
+    method public V putIfAbsent(K, V);
     method public <U> U reduce(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
     method public java.util.Map.Entry<K, V> reduceEntries(long, java.util.function.BiFunction<java.util.Map.Entry<K, V>, java.util.Map.Entry<K, V>, ? extends java.util.Map.Entry<K, V>>);
     method public <U> U reduceEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
@@ -66131,6 +66195,10 @@
     method public double reduceValuesToDouble(long, java.util.function.ToDoubleFunction<? super V>, double, java.util.function.DoubleBinaryOperator);
     method public int reduceValuesToInt(long, java.util.function.ToIntFunction<? super V>, int, java.util.function.IntBinaryOperator);
     method public long reduceValuesToLong(long, java.util.function.ToLongFunction<? super V>, long, java.util.function.LongBinaryOperator);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public <U> U search(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>);
     method public <U> U searchEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>);
     method public <U> U searchKeys(long, java.util.function.Function<? super K, ? extends U>);
@@ -66191,6 +66259,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ConcurrentLinkedQueue<E> extends java.util.AbstractQueue implements java.util.Queue java.io.Serializable {
@@ -66201,6 +66270,7 @@
     method public E peek();
     method public E poll();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface ConcurrentMap<K, V> implements java.util.Map {
@@ -66232,6 +66302,9 @@
     method public K ceilingKey(K);
     method public java.util.concurrent.ConcurrentSkipListMap<K, V> clone();
     method public java.util.Comparator<? super K> comparator();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> descendingKeySet();
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> descendingMap();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
@@ -66239,18 +66312,25 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
     method public K higherKey(K);
-    method public java.util.NavigableSet<K> keySet();
     method public java.util.Map.Entry<K, V> lastEntry();
     method public K lastKey();
     method public java.util.Map.Entry<K, V> lowerEntry(K);
     method public K lowerKey(K);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
+    method public V putIfAbsent(K, V);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, K);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> tailMap(K, boolean);
@@ -66278,6 +66358,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.NavigableSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -66324,7 +66405,9 @@
     ctor public CopyOnWriteArraySet(java.util.Collection<? extends E>);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public java.util.Iterator<E> iterator();
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class CountDownLatch {
@@ -66483,7 +66566,6 @@
     method public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
     method public boolean hasQueuedSubmissions();
     method public <T> T invoke(java.util.concurrent.ForkJoinTask<T>);
-    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>);
     method public boolean isQuiescent();
     method public boolean isShutdown();
     method public boolean isTerminated();
@@ -66493,9 +66575,6 @@
     method public void shutdown();
     method public java.util.List<java.lang.Runnable> shutdownNow();
     method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.ForkJoinTask<T>);
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.Callable<T>);
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.lang.Runnable, T);
-    method public java.util.concurrent.ForkJoinTask<?> submit(java.lang.Runnable);
     field public static final java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory defaultForkJoinWorkerThreadFactory;
   }
 
@@ -66619,6 +66698,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public E takeFirst() throws java.lang.InterruptedException;
     method public E takeLast() throws java.lang.InterruptedException;
@@ -66639,6 +66719,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -66658,6 +66739,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public void transfer(E) throws java.lang.InterruptedException;
     method public boolean tryTransfer(E);
@@ -66705,6 +66787,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -66808,6 +66891,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -66819,11 +66903,9 @@
     method public static java.util.concurrent.ThreadLocalRandom current();
     method public double nextDouble(double);
     method public double nextDouble(double, double);
-    method public double nextGaussian();
     method public int nextInt(int, int);
     method public long nextLong(long);
     method public long nextLong(long, long);
-    method public void setSeed(long);
   }
 
   public class ThreadPoolExecutor extends java.util.concurrent.AbstractExecutorService {
@@ -66837,7 +66919,6 @@
     method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
     method protected void beforeExecute(java.lang.Thread, java.lang.Runnable);
     method public void execute(java.lang.Runnable);
-    method protected void finalize();
     method public int getActiveCount();
     method public long getCompletedTaskCount();
     method public int getCorePoolSize();
@@ -67708,11 +67789,8 @@
     ctor public JarFile(java.io.File) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean, int) throws java.io.IOException;
-    method public java.util.Enumeration<java.util.jar.JarEntry> entries();
-    method public synchronized java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.util.jar.JarEntry getJarEntry(java.lang.String);
     method public java.util.jar.Manifest getManifest() throws java.io.IOException;
-    method public java.util.stream.Stream<java.util.jar.JarEntry> stream();
     field public static final java.lang.String MANIFEST_NAME = "META-INF/MANIFEST.MF";
   }
 
@@ -67792,8 +67870,6 @@
 
   public class ConsoleHandler extends java.util.logging.StreamHandler {
     ctor public ConsoleHandler();
-    method public void close();
-    method public void publish(java.util.logging.LogRecord);
   }
 
   public class ErrorManager {
@@ -68583,7 +68659,6 @@
     method public int deflate(byte[]);
     method public int deflate(byte[], int, int, int);
     method public void end();
-    method protected void finalize();
     method public void finish();
     method public boolean finished();
     method public int getAdler();
@@ -68616,8 +68691,6 @@
     ctor public DeflaterInputStream(java.io.InputStream);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater, int);
-    method public void mark(int);
-    method public void reset() throws java.io.IOException;
     field protected final byte[] buf;
     field protected final java.util.zip.Deflater def;
   }
@@ -68648,7 +68721,6 @@
     ctor public GZIPOutputStream(java.io.OutputStream, int, boolean) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream, boolean) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected java.util.zip.CRC32 crc;
   }
 
@@ -68656,7 +68728,6 @@
     ctor public Inflater(boolean);
     ctor public Inflater();
     method public void end();
-    method protected void finalize();
     method public boolean finished();
     method public int getAdler();
     method public long getBytesRead();
@@ -68783,7 +68854,6 @@
     ctor public ZipFile(java.io.File, java.nio.charset.Charset) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public java.util.Enumeration<? extends java.util.zip.ZipEntry> entries();
-    method protected void finalize() throws java.io.IOException;
     method public java.lang.String getComment();
     method public java.util.zip.ZipEntry getEntry(java.lang.String);
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
@@ -68890,7 +68960,6 @@
     method public void setComment(java.lang.String);
     method public void setLevel(int);
     method public void setMethod(int);
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
@@ -69047,7 +69116,6 @@
 
   public class ExemptionMechanism {
     ctor protected ExemptionMechanism(javax.crypto.ExemptionMechanismSpi, java.security.Provider, java.lang.String);
-    method protected void finalize();
     method public final byte[] genExemptionBlob() throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException;
     method public final int genExemptionBlob(byte[]) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
     method public final int genExemptionBlob(byte[], int) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
@@ -70625,7 +70693,6 @@
   public abstract class SSLSocketFactory extends javax.net.SocketFactory {
     ctor public SSLSocketFactory();
     method public abstract java.net.Socket createSocket(java.net.Socket, java.lang.String, int, boolean) throws java.io.IOException;
-    method public java.net.Socket createSocket(java.net.Socket, java.io.InputStream, boolean) throws java.io.IOException;
     method public static synchronized javax.net.SocketFactory getDefault();
     method public abstract java.lang.String[] getDefaultCipherSuites();
     method public abstract java.lang.String[] getSupportedCipherSuites();
@@ -71437,7 +71504,6 @@
     ctor public TransformerException(java.lang.String, java.lang.Throwable);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator, java.lang.Throwable);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
     method public java.lang.String getLocationAsString();
     method public javax.xml.transform.SourceLocator getLocator();
@@ -71708,7 +71774,6 @@
   public class XPathException extends java.lang.Exception {
     ctor public XPathException(java.lang.String);
     ctor public XPathException(java.lang.Throwable);
-    method public java.lang.Throwable getCause();
   }
 
   public abstract interface XPathExpression {
diff --git a/cmds/am/Android.bp b/cmds/am/Android.bp
new file mode 100644
index 0000000..bb16df1
--- /dev/null
+++ b/cmds/am/Android.bp
@@ -0,0 +1,12 @@
+// Copyright 2008 The Android Open Source Project
+//
+
+cc_library_host_static {
+    name: "libinstrumentation",
+    srcs: ["**/*.proto"],
+    cflags: ["-Wall", "-Werror"],
+    proto: {
+        type: "full",
+        export_proto_headers: true,
+    },
+}
diff --git a/cmds/am/Android.mk b/cmds/am/Android.mk
index 5586dd4..9411c32 100644
--- a/cmds/am/Android.mk
+++ b/cmds/am/Android.mk
@@ -16,14 +16,3 @@
 LOCAL_MODULE_CLASS := EXECUTABLES
 LOCAL_MODULE_TAGS := optional
 include $(BUILD_PREBUILT)
-
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := \
-    $(call all-proto-files-under, proto)
-LOCAL_MODULE := libinstrumentation
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-LOCAL_EXPORT_C_INCLUDE_DIRS := \
-    $(call intermediates-dir-for,STATIC_LIBRARIES,libinstrumentation,HOST,,,)/proto/$(LOCAL_PATH)/proto
-include $(BUILD_HOST_STATIC_LIBRARY)
-
diff --git a/cmds/appwidget/appwidget b/cmds/appwidget/appwidget
index 6105009..26ab173 100755
--- a/cmds/appwidget/appwidget
+++ b/cmds/appwidget/appwidget
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "appwidget" on the device, which has a very rudimentary shell.
 base=/system
 export CLASSPATH=$base/framework/appwidget.jar
diff --git a/cmds/bmgr/bmgr b/cmds/bmgr/bmgr
index 6b4bbe2d..60b5833 100755
--- a/cmds/bmgr/bmgr
+++ b/cmds/bmgr/bmgr
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "bmgr" on the device, which has a very rudimentary
 # shell.
 #
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index 0e2c13e..7ab402a 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -1,15 +1,50 @@
+bootanimation_CommonCFlags = -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+bootanimation_CommonCFlags += -Wall -Werror -Wunused -Wunreachable-code
+
+
+# bootanimation executable
+# =========================================================
+
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
     bootanimation_main.cpp \
     audioplay.cpp \
+
+LOCAL_CFLAGS += ${bootanimation_CommonCFlags}
+
+LOCAL_SHARED_LIBRARIES := \
+    libOpenSLES \
+    libandroidfw \
+    libbase \
+    libbinder \
+    libbootanimation \
+    libcutils \
+    liblog \
+    libutils \
+
+LOCAL_MODULE:= bootanimation
+
+LOCAL_INIT_RC := bootanim.rc
+
+ifdef TARGET_32_BIT_SURFACEFLINGER
+LOCAL_32_BIT_ONLY := true
+endif
+
+include $(BUILD_EXECUTABLE)
+
+
+# libbootanimation
+# ===========================================================
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libbootanimation
+LOCAL_CFLAGS += ${bootanimation_CommonCFlags}
+
+LOCAL_SRC_FILES:= \
     BootAnimation.cpp
 
-LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
-
 LOCAL_C_INCLUDES += \
     external/tinyalsa/include \
     frameworks/wilhelm/include
@@ -25,16 +60,11 @@
     libEGL \
     libGLESv1_CM \
     libgui \
-    libOpenSLES \
     libtinyalsa \
     libbase
 
-LOCAL_MODULE:= bootanimation
-
-LOCAL_INIT_RC := bootanim.rc
-
 ifdef TARGET_32_BIT_SURFACEFLINGER
 LOCAL_32_BIT_ONLY := true
 endif
 
-include $(BUILD_EXECUTABLE)
+include ${BUILD_SHARED_LIBRARY}
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 7394490..6b2de4b 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -62,7 +62,6 @@
 #include <EGL/eglext.h>
 
 #include "BootAnimation.h"
-#include "audioplay.h"
 
 namespace android {
 
@@ -92,26 +91,18 @@
 static const int TEXT_CENTER_VALUE = INT_MAX;
 static const int TEXT_MISSING_VALUE = INT_MIN;
 static const char EXIT_PROP_NAME[] = "service.bootanim.exit";
-static const char PLAY_SOUND_PROP_NAME[] = "persist.sys.bootanim.play_sound";
 static const int ANIM_ENTRY_NAME_MAX = 256;
 static constexpr size_t TEXT_POS_LEN_MAX = 16;
-static const char BOOT_COMPLETED_PROP_NAME[] = "sys.boot_completed";
-static const char BOOTREASON_PROP_NAME[] = "ro.boot.bootreason";
-// bootreasons list in "system/core/bootstat/bootstat.cpp".
-static const std::vector<std::string> PLAY_SOUND_BOOTREASON_BLACKLIST {
-  "kernel_panic",
-  "Panic",
-  "Watchdog",
-};
 
 // ---------------------------------------------------------------------------
 
-BootAnimation::BootAnimation() : Thread(false), mClockEnabled(true), mTimeIsAccurate(false),
-        mTimeFormat12Hour(false), mTimeCheckThread(NULL) {
+BootAnimation::BootAnimation(InitCallback initCallback,
+                             PlayPartCallback partCallback)
+        : Thread(false), mClockEnabled(true), mTimeIsAccurate(false),
+        mTimeFormat12Hour(false), mTimeCheckThread(NULL),
+        mInitCallback(initCallback), mPlayPartCallback(partCallback) {
     mSession = new SurfaceComposerClient();
 
-    // If the system has already booted, the animation is not being used for a boot.
-    mSystemBoot = !android::base::GetBoolProperty(BOOT_COMPLETED_PROP_NAME, false);
     std::string powerCtl = android::base::GetProperty("sys.powerctl", "");
     if (powerCtl.empty()) {
         mShuttingDown = false;
@@ -142,7 +133,6 @@
     // might be blocked on a condition variable that will never be updated.
     kill( getpid(), SIGKILL );
     requestExit();
-    audioplay::destroy();
 }
 
 status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
@@ -158,10 +148,6 @@
     asset->close();
     delete asset;
 
-    // ensure we can call getPixels(). No need to call unlock, since the
-    // bitmap will go out of scope when we return from this method.
-    bitmap.lockPixels();
-
     const int w = bitmap.width();
     const int h = bitmap.height();
     const void* p = bitmap.getPixels();
@@ -216,10 +202,6 @@
     // the packed resource can be released.
     delete map;
 
-    // ensure we can call getPixels(). No need to call unlock, since the
-    // bitmap will go out of scope when we return from this method.
-    bitmap.lockPixels();
-
     const int w = bitmap.width();
     const int h = bitmap.height();
     const void* p = bitmap.getPixels();
@@ -712,7 +694,6 @@
         return false;
     }
 
-    Animation::Part* partWithAudio = NULL;
     ZipEntryRO entry;
     char name[ANIM_ENTRY_NAME_MAX];
     while ((entry = zip->nextEntry(cookie)) != NULL) {
@@ -747,7 +728,6 @@
                                     // a part may have at most one audio file
                                     part.audioData = (uint8_t *)map->getDataPtr();
                                     part.audioLength = map->getDataLength();
-                                    partWithAudio = &part;
                                 } else if (leaf == "trim.txt") {
                                     part.trimData.setTo((char const*)map->getDataPtr(),
                                                         map->getDataLength());
@@ -797,13 +777,8 @@
         }
     }
 
-    // Create and initialize audioplay if there is a wav file in any of the animations.
-    // Do it on a separate thread so we don't hold up the animation intro.
-    if (partWithAudio != NULL) {
-        ALOGD("found audio.wav, creating playback engine");
-        mInitAudioThread = new InitAudioThread(partWithAudio->audioData,
-                                               partWithAudio->audioLength);
-        mInitAudioThread->run("BootAnimation::InitAudioThread", PRIORITY_NORMAL);
+    if (mInitCallback != nullptr) {
+        mInitCallback(animation.parts);
     }
 
     zip->endIteration(cookie);
@@ -876,11 +851,6 @@
         mTimeCheckThread = nullptr;
     }
 
-    // We should have joined mInitAudioThread thread in playAnimation
-    if (mInitAudioThread != nullptr) {
-        mInitAudioThread = nullptr;
-    }
-
     releaseAnimation(animation);
 
     if (clockFontInitialized) {
@@ -917,14 +887,8 @@
             if(exitPending() && !part.playUntilComplete)
                 break;
 
-            // only play audio file the first time we animate the part
-            if (r == 0 && part.audioData && playSoundsAllowed()) {
-                ALOGD("playing clip for part%d, size=%d", (int) i, part.audioLength);
-                // Block until the audio engine is finished initializing.
-                if (mInitAudioThread != nullptr) {
-                    mInitAudioThread->join();
-                }
-                audioplay::playClip(part.audioData, part.audioLength);
+            if (mPlayPartCallback != nullptr) {
+                mPlayPartCallback(i, part, r);
             }
 
             glClearColor(
@@ -1013,10 +977,6 @@
         }
     }
 
-    // we've finally played everything we're going to play
-    audioplay::setPlaying(false);
-    audioplay::destroy();
-
     return true;
 }
 
@@ -1062,32 +1022,6 @@
     return animation;
 }
 
-bool BootAnimation::playSoundsAllowed() const {
-    // Only play sounds for system boots, not runtime restarts.
-    if (!mSystemBoot) {
-        return false;
-    }
-    if (mShuttingDown) { // no audio while shutting down
-        return false;
-    }
-    // Read the system property to see if we should play the sound.
-    // If it's not present, default to allowed.
-    if (!property_get_bool(PLAY_SOUND_PROP_NAME, 1)) {
-        return false;
-    }
-
-    // Don't play sounds if this is a reboot due to an error.
-    char bootreason[PROPERTY_VALUE_MAX];
-    if (property_get(BOOTREASON_PROP_NAME, bootreason, nullptr) > 0) {
-        for (const auto& str : PLAY_SOUND_BOOTREASON_BLACKLIST) {
-            if (strcasecmp(str.c_str(), bootreason) == 0) {
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
 bool BootAnimation::updateIsTimeAccurate() {
     static constexpr long long MAX_TIME_IN_PAST =   60000LL * 60LL * 24LL * 30LL;  // 30 days
     static constexpr long long MAX_TIME_IN_FUTURE = 60000LL * 90LL;  // 90 minutes
@@ -1219,17 +1153,6 @@
     return NO_ERROR;
 }
 
-BootAnimation::InitAudioThread::InitAudioThread(uint8_t* exampleAudioData, int exampleAudioLength)
-    : Thread(false),
-      mExampleAudioData(exampleAudioData),
-      mExampleAudioLength(exampleAudioLength) {}
-
-bool BootAnimation::InitAudioThread::threadLoop() {
-    audioplay::create(mExampleAudioData, mExampleAudioLength);
-    // Exit immediately
-    return false;
-}
-
 // ---------------------------------------------------------------------------
 
 }
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 181ef1c..3ebe7d6 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -39,44 +39,6 @@
 class BootAnimation : public Thread, public IBinder::DeathRecipient
 {
 public:
-    BootAnimation();
-
-    sp<SurfaceComposerClient> session() const;
-
-private:
-    virtual bool        threadLoop();
-    virtual status_t    readyToRun();
-    virtual void        onFirstRef();
-    virtual void        binderDied(const wp<IBinder>& who);
-
-    bool                updateIsTimeAccurate();
-
-    class TimeCheckThread : public Thread {
-    public:
-        TimeCheckThread(BootAnimation* bootAnimation);
-        virtual ~TimeCheckThread();
-    private:
-        virtual status_t    readyToRun();
-        virtual bool        threadLoop();
-        bool                doThreadLoop();
-        void                addTimeDirWatch();
-
-        int mInotifyFd;
-        int mSystemWd;
-        int mTimeWd;
-        BootAnimation* mBootAnimation;
-    };
-
-    class InitAudioThread : public Thread {
-    public:
-        InitAudioThread(uint8_t* exampleAudioData, int mExampleAudioLength);
-    private:
-        virtual bool threadLoop();
-
-        uint8_t* mExampleAudioData;
-        int mExampleAudioLength;
-    };
-
     struct Texture {
         GLint   w;
         GLint   h;
@@ -131,6 +93,49 @@
         Font clockFont;
     };
 
+    // Callback will be called during initialization after we have loaded
+    // the animation and be provided with all parts in animation.
+    typedef std::function<void(const Vector<Animation::Part>& parts)> InitCallback;
+
+    // Callback will be called while animation is playing before each part is
+    // played. It will be provided with the part and play count for it.
+    // It will be provided with the partNumber for the part about to be played,
+    // as well as a reference to the part itself. It will also be provided with
+    // which play of that part is about to start, some parts are repeated
+    // multiple times.
+    typedef std::function<void(int partNumber, const Animation::Part& part, int playNumber)>
+            PlayPartCallback;
+
+    // Callbacks may be null and will be called from this class's internal
+    // thread.
+    BootAnimation(InitCallback initCallback, PlayPartCallback partCallback);
+
+    sp<SurfaceComposerClient> session() const;
+
+private:
+    virtual bool        threadLoop();
+    virtual status_t    readyToRun();
+    virtual void        onFirstRef();
+    virtual void        binderDied(const wp<IBinder>& who);
+
+    bool                updateIsTimeAccurate();
+
+    class TimeCheckThread : public Thread {
+    public:
+        TimeCheckThread(BootAnimation* bootAnimation);
+        virtual ~TimeCheckThread();
+    private:
+        virtual status_t    readyToRun();
+        virtual bool        threadLoop();
+        bool                doThreadLoop();
+        void                addTimeDirWatch();
+
+        int mInotifyFd;
+        int mSystemWd;
+        int mTimeWd;
+        BootAnimation* mBootAnimation;
+    };
+
     status_t initTexture(Texture* texture, AssetManager& asset, const char* name);
     status_t initTexture(FileMap* map, int* width, int* height);
     status_t initFont(Font* font, const char* fallback);
@@ -144,7 +149,6 @@
     void releaseAnimation(Animation*) const;
     bool parseAnimationDesc(Animation&);
     bool preloadZip(Animation &animation);
-    bool playSoundsAllowed() const;
 
     void checkExit();
 
@@ -162,12 +166,12 @@
     bool        mClockEnabled;
     bool        mTimeIsAccurate;
     bool        mTimeFormat12Hour;
-    bool        mSystemBoot;
     bool        mShuttingDown;
     String8     mZipFileName;
     SortedVector<String8> mLoadedFiles;
     sp<TimeCheckThread> mTimeCheckThread = nullptr;
-    sp<InitAudioThread> mInitAudioThread = nullptr;
+    InitCallback mInitCallback = nullptr;
+    PlayPartCallback mPlayPartCallback = nullptr;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/cmds/bootanimation/bootanimation_main.cpp b/cmds/bootanimation/bootanimation_main.cpp
index 3689d5e..c11d905 100644
--- a/cmds/bootanimation/bootanimation_main.cpp
+++ b/cmds/bootanimation/bootanimation_main.cpp
@@ -27,13 +27,77 @@
 #include <utils/Log.h>
 #include <utils/SystemClock.h>
 #include <utils/threads.h>
+#include <android-base/properties.h>
 
 #include "BootAnimation.h"
+#include "audioplay.h"
 
 using namespace android;
 
 // ---------------------------------------------------------------------------
 
+namespace {
+
+// Create a typedef for readability.
+typedef android::BootAnimation::Animation Animation;
+
+static const char PLAY_SOUND_PROP_NAME[] = "persist.sys.bootanim.play_sound";
+static const char BOOT_COMPLETED_PROP_NAME[] = "sys.boot_completed";
+static const char POWER_CTL_PROP_NAME[] = "sys.powerctl";
+static const char BOOTREASON_PROP_NAME[] = "ro.boot.bootreason";
+static const std::vector<std::string> PLAY_SOUND_BOOTREASON_BLACKLIST {
+  "kernel_panic",
+  "Panic",
+  "Watchdog",
+};
+
+class InitAudioThread : public Thread {
+public:
+    InitAudioThread(uint8_t* exampleAudioData, int exampleAudioLength)
+        : Thread(false),
+          mExampleAudioData(exampleAudioData),
+          mExampleAudioLength(exampleAudioLength) {}
+private:
+    virtual bool threadLoop() {
+        audioplay::create(mExampleAudioData, mExampleAudioLength);
+        // Exit immediately
+        return false;
+    }
+
+    uint8_t* mExampleAudioData;
+    int mExampleAudioLength;
+};
+
+bool playSoundsAllowed() {
+    // Only play sounds for system boots, not runtime restarts.
+    if (android::base::GetBoolProperty(BOOT_COMPLETED_PROP_NAME, false)) {
+        return false;
+    }
+    // no audio while shutting down
+    if (!android::base::GetProperty(POWER_CTL_PROP_NAME, "").empty()) {
+        return false;
+    }
+    // Read the system property to see if we should play the sound.
+    // If it's not present, default to allowed.
+    if (!property_get_bool(PLAY_SOUND_PROP_NAME, 1)) {
+        return false;
+    }
+
+    // Don't play sounds if this is a reboot due to an error.
+    char bootreason[PROPERTY_VALUE_MAX];
+    if (property_get(BOOTREASON_PROP_NAME, bootreason, nullptr) > 0) {
+        for (const auto& str : PLAY_SOUND_BOOTREASON_BLACKLIST) {
+            if (strcasecmp(str.c_str(), bootreason) == 0) {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+}  // namespace
+
+
 int main()
 {
     setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
@@ -71,10 +135,50 @@
             ALOGI("Waiting for SurfaceFlinger took %" PRId64 " ms", totalWaited);
         }
 
+        // TODO: Move audio code to a new class that just exports the callbacks.
+        sp<InitAudioThread> initAudioThread = nullptr;
+
+        auto initCallback = [&](const Vector<Animation::Part>& parts) {
+            const Animation::Part* partWithAudio = nullptr;
+            for (const Animation::Part& part : parts) {
+                if (part.audioData != nullptr) {
+                    partWithAudio = &part;
+                }
+            }
+
+            if (partWithAudio == nullptr) {
+                return;
+            }
+
+            ALOGD("found audio.wav, creating playback engine");
+            initAudioThread = new InitAudioThread(partWithAudio->audioData,
+                    partWithAudio->audioLength);
+            initAudioThread->run("BootAnimation::InitAudioThread", PRIORITY_NORMAL);
+
+        };
+
+        auto partCallback = [&](int partNumber, const Animation::Part& part,
+                                int playNumber) {
+            // only play audio file the first time we animate the part
+            if (playNumber == 0 && part.audioData && playSoundsAllowed()) {
+                ALOGD("playing clip for part%d, size=%d",
+                      partNumber, part.audioLength);
+                // Block until the audio engine is finished initializing.
+                if (initAudioThread != nullptr) {
+                    initAudioThread->join();
+                }
+                audioplay::playClip(part.audioData, part.audioLength);
+            }
+        };
+
         // create the boot animation object
-        sp<BootAnimation> boot = new BootAnimation();
+        sp<BootAnimation> boot = new BootAnimation(initCallback, partCallback);
 
         IPCThreadState::self()->joinThreadPool();
+
+        // we've finally played everything we're going to play
+        audioplay::setPlaying(false);
+        audioplay::destroy();
     }
     return 0;
 }
diff --git a/cmds/bu/bu b/cmds/bu/bu
index e8dbc31..e50b53d 100755
--- a/cmds/bu/bu
+++ b/cmds/bu/bu
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "bu" on the device
 #
 base=/system
diff --git a/cmds/content/content b/cmds/content/content
index a8e056d..f1bfe17 100755
--- a/cmds/content/content
+++ b/cmds/content/content
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "content" on the device, which has a very rudimentary shell.
 base=/system
 export CLASSPATH=$base/framework/content.jar
diff --git a/cmds/dpm/dpm b/cmds/dpm/dpm
index c2e5cbb..e0efdc1 100755
--- a/cmds/dpm/dpm
+++ b/cmds/dpm/dpm
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "dpm" on the device
 #
 base=/system
diff --git a/cmds/hid/Android.bp b/cmds/hid/Android.bp
new file mode 100644
index 0000000..2b7963a
--- /dev/null
+++ b/cmds/hid/Android.bp
@@ -0,0 +1 @@
+subdirs = ["jni"]
diff --git a/cmds/hid/README.md b/cmds/hid/README.md
new file mode 100644
index 0000000..7e22d08
--- /dev/null
+++ b/cmds/hid/README.md
@@ -0,0 +1,145 @@
+# Usage
+##  Two options to use the hid command:
+### 1. Interactive through stdin:
+type `hid -` into the terminal, then type/paste commands to send to the binary.
+Use Ctrl+D to signal end of stream to the binary (EOF).
+
+This mode can be also used from an app to send HID events.
+For an example, see the cts test case at: [InputTestCase.java][2]
+
+When using another program to control hid in interactive mode, registering a
+new input device (for example, a bluetooth joystick) should be the first step.
+After the device is added, you need to wait for the _onInputDeviceAdded_
+(see [InputDeviceListener][1]) notification before issuing commands
+to the device.
+Failure to do so will cause missed events and inconsistent behaviour.
+In the current implementation of the hid command, the hid binary will wait
+for the file descriptor to the uhid node to send the UHID_START and UHID_OPEN
+signals before returning. However, this is not sufficient. These signals
+only notify the readiness of the kernel driver,
+but do not take into account the inputflinger framework.
+
+
+### 2. Using a file as an input:
+type `hid <filename>`, and the file will be used an an input to the binary.
+You must add a sufficient delay after a "register" command to ensure device
+is ready. The interactive mode is the recommended method of communicating
+with the hid binary.
+
+All of the input commands should be in pseudo-JSON format as documented below.
+See examples [here][3].
+
+The file can have multiple commands one after the other (which is not strictly
+legal JSON format, as this would imply multiple root elements).
+
+## Command description
+
+1. `register`
+Register a new uhid device
+
+| Field         | Type          | Description                |
+|:-------------:|:-------------:|:--------------------------|
+| id            | integer       | Device id                  |
+| command       | string        | Must be set to "register"  |
+| name          | string        | Device name                |
+| vid           | 16-bit integer| Vendor id                  |
+| pid           | 16-bit integer| Product id                 |
+| descriptor    | byte array    | USB HID report descriptor  |
+
+Device ID is used for matching the subsequent commands to a specific device
+to avoid ambiguity when multiple devices are registered.
+
+USB HID report descriptor should be generated according the the USB HID spec
+and can be checked by reverse parsing using a variety of tools, for example
+[usbdescreqparser][5].
+
+Example:
+```json
+{
+  "id": 1,
+  "command": "register",
+  "name": "Odie (Test)",
+  "vid": 0x18d1,
+  "pid": 0x2c40,
+  "descriptor": [0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01, 0x05, 0x09, 0x0a, 0x01, 0x00,
+    0x0a, 0x02, 0x00, 0x0a, 0x04, 0x00, 0x0a, 0x05, 0x00, 0x0a, 0x07, 0x00, 0x0a, 0x08, 0x00,
+    0x0a, 0x0e, 0x00, 0x0a, 0x0f, 0x00, 0x0a, 0x0d, 0x00, 0x05, 0x0c, 0x0a, 0x24, 0x02, 0x0a,
+    0x23, 0x02, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x0b, 0x81, 0x02, 0x75, 0x01, 0x95,
+    0x01, 0x81, 0x03, 0x05, 0x01, 0x75, 0x04, 0x95, 0x01, 0x25, 0x07, 0x46, 0x3b, 0x01, 0x66,
+    0x14, 0x00, 0x09, 0x39, 0x81, 0x42, 0x66, 0x00, 0x00, 0x09, 0x01, 0xa1, 0x00, 0x09, 0x30,
+    0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x05, 0x02, 0x09, 0xc5, 0x09, 0xc4, 0x15, 0x00, 0x26,
+    0xff, 0x00, 0x35, 0x00, 0x46, 0xff, 0x00, 0x75, 0x08, 0x95, 0x06, 0x81, 0x02, 0xc0, 0x85,
+    0x02, 0x05, 0x08, 0x0a, 0x01, 0x00, 0x0a, 0x02, 0x00, 0x0a, 0x03, 0x00, 0x0a, 0x04, 0x00,
+    0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x04, 0x91, 0x02, 0x75, 0x04, 0x95, 0x01, 0x91,
+    0x03, 0xc0, 0x05, 0x0c, 0x09, 0x01, 0xa1, 0x01, 0x85, 0x03, 0x05, 0x01, 0x09, 0x06, 0xa1,
+    0x02, 0x05, 0x06, 0x09, 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81,
+    0x02, 0x06, 0xbc, 0xff, 0x0a, 0xad, 0xbd, 0x75, 0x08, 0x95, 0x06, 0x81, 0x02, 0xc0, 0xc0]
+}
+```
+2. `delay`
+Add a delay to command processing
+
+| Field         | Type          | Description                |
+|:-------------:|:-------------:|:-------------------------- |
+| id            | integer       | Device id                  |
+| command       | string        | Must be set to "delay"     |
+| duration      | integer       | Delay in milliseconds      |
+
+Example:
+```json
+{
+  "id": 1,
+  "command": "delay",
+  "duration": 10
+}
+```
+
+3. `report`
+Send a report to the HID device
+
+| Field         | Type          | Description                |
+|:-------------:|:-------------:|:-------------------------- |
+| id            | integer       | Device id                  |
+| command       | string        | Must be set to "report"    |
+| report        | byte array    | Report data to send        |
+
+Example:
+```json
+{
+  "id": 1,
+  "command": "report",
+  "report": [0x01, 0x01, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00]
+}
+```
+
+### Sending a joystick button press event
+To send a button press event on a joystick device:
+1. Register the joystick device
+2. Send button down event with coordinates ABS_X, ABS_Y, ABS_Z, and ABS_RZ
+at the center of the range. If the coordinates are not centered, this event
+will generate a motion event within the input framework, in addition to the
+button press event. The range can be determined from the uhid report descriptor.
+3. Send the button up event with the same coordinates as in 2.
+4. Check that the button press event was received.
+
+### Notes
+1. As soon as EOF is reached (either in interactive mode, or in file mode),
+the device that was created will be unregistered. There is no
+explicit command for unregistering a device.
+2. The linux input subsystem does not generate events for those values
+that remain unchanged. For example, if there are two events sent to the driver,
+and both events have the same value of ABS_X, then ABS_X coordinate
+will not be reported.
+3. The description of joystick actions is available [here][6].
+4. Joysticks are split axes. When an analog stick is in a resting state,
+the reported coordinates are at the center of the range.
+5. The `getevent` utility can used to print out the key events
+for debugging purposes.
+
+
+[1]: https://developer.android.com/reference/android/hardware/input/InputManager.InputDeviceListener.html
+[2]: ../../../../cts/tests/tests/hardware/src/android/hardware/input/cts/tests/InputTestCase.java
+[3]: ../../../../cts/tests/tests/hardware/res/raw/
+[4]: https://developer.android.com/training/game-controllers/controller-input.html#button
+[5]: http://eleccelerator.com/usbdescreqparser/
+[6]: https://developer.android.com/training/game-controllers/controller-input.html
\ No newline at end of file
diff --git a/cmds/hid/jni/Android.bp b/cmds/hid/jni/Android.bp
new file mode 100644
index 0000000..095cfc6
--- /dev/null
+++ b/cmds/hid/jni/Android.bp
@@ -0,0 +1,17 @@
+cc_library_shared {
+    name: "libhidcommand_jni",
+
+    srcs: ["com_android_commands_hid_Device.cpp"],
+
+    shared_libs: [
+        "libandroid",
+        "liblog",
+        "libnativehelper",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+}
diff --git a/cmds/hid/jni/Android.mk b/cmds/hid/jni/Android.mk
deleted file mode 100644
index d41d39d..0000000
--- a/cmds/hid/jni/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    com_android_commands_hid_Device.cpp
-
-LOCAL_C_INCLUDES := \
-    $(JNI_H_INCLUDE) \
-    frameworks/base/core/jni
-
-LOCAL_SHARED_LIBRARIES := \
-    libandroid_runtime \
-    liblog \
-    libnativehelper \
-    libutils
-
-LOCAL_MODULE := libhidcommand_jni
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_CFLAGS += -Wall -Wextra -Werror
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.cpp b/cmds/hid/jni/com_android_commands_hid_Device.cpp
index 59953b8..5cc4fc4 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.cpp
+++ b/cmds/hid/jni/com_android_commands_hid_Device.cpp
@@ -26,17 +26,17 @@
 #include <memory>
 #include <unistd.h>
 
-#include <android_runtime/AndroidRuntime.h>
-#include <android_runtime/Log.h>
-#include <android_os_MessageQueue.h>
-#include <core_jni_helpers.h>
 #include <jni.h>
 #include <nativehelper/JNIHelp.h>
 #include <nativehelper/ScopedPrimitiveArray.h>
 #include <nativehelper/ScopedUtfChars.h>
-#include <utils/Log.h>
-#include <utils/Looper.h>
-#include <utils/StrongPointer.h>
+#include <android/looper.h>
+#include <android/log.h>
+
+#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
+#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
+#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
+#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
 
 namespace android {
 namespace uhid {
@@ -56,59 +56,67 @@
 
 static void checkAndClearException(JNIEnv* env, const char* methodName) {
     if (env->ExceptionCheck()) {
-        ALOGE("An exception was thrown by callback '%s'.", methodName);
-        LOGE_EX(env);
+        LOGE("An exception was thrown by callback '%s'.", methodName);
         env->ExceptionClear();
     }
 }
 
 DeviceCallback::DeviceCallback(JNIEnv* env, jobject callback) :
-    mCallbackObject(env->NewGlobalRef(callback)) { }
+    mCallbackObject(env->NewGlobalRef(callback)) {
+    env->GetJavaVM(&mJavaVM);
+ }
 
 DeviceCallback::~DeviceCallback() {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    JNIEnv* env = getJNIEnv();
     env->DeleteGlobalRef(mCallbackObject);
 }
 
 void DeviceCallback::onDeviceError() {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    JNIEnv* env = getJNIEnv();
     env->CallVoidMethod(mCallbackObject, gDeviceCallbackClassInfo.onDeviceError);
     checkAndClearException(env, "onDeviceError");
 }
 
 void DeviceCallback::onDeviceOpen() {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    JNIEnv* env = getJNIEnv();
     env->CallVoidMethod(mCallbackObject, gDeviceCallbackClassInfo.onDeviceOpen);
     checkAndClearException(env, "onDeviceOpen");
 }
 
+JNIEnv* DeviceCallback::getJNIEnv() {
+    JNIEnv* env;
+    mJavaVM->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
+    return env;
+}
+
 Device* Device::open(int32_t id, const char* name, int32_t vid, int32_t pid,
         std::unique_ptr<uint8_t[]> descriptor, size_t descriptorSize,
-        std::unique_ptr<DeviceCallback> callback, sp<Looper> looper) {
+        std::unique_ptr<DeviceCallback> callback) {
 
     int fd = ::open(UHID_PATH, O_RDWR | O_CLOEXEC);
     if (fd < 0) {
-        ALOGE("Failed to open uhid: %s", strerror(errno));
+        LOGE("Failed to open uhid: %s", strerror(errno));
         return nullptr;
     }
 
     struct uhid_event ev;
     memset(&ev, 0, sizeof(ev));
-    ev.type = UHID_CREATE;
-    strncpy((char*)ev.u.create.name, name, UHID_MAX_NAME_LENGTH);
-    ev.u.create.rd_data = descriptor.get();
-    ev.u.create.rd_size = descriptorSize;
-    ev.u.create.bus = BUS_BLUETOOTH;
-    ev.u.create.vendor = vid;
-    ev.u.create.product = pid;
-    ev.u.create.version = 0;
-    ev.u.create.country = 0;
+    ev.type = UHID_CREATE2;
+    strncpy((char*)ev.u.create2.name, name, UHID_MAX_NAME_LENGTH);
+    memcpy(&ev.u.create2.rd_data, descriptor.get(),
+            descriptorSize * sizeof(ev.u.create2.rd_data[0]));
+    ev.u.create2.rd_size = descriptorSize;
+    ev.u.create2.bus = BUS_BLUETOOTH;
+    ev.u.create2.vendor = vid;
+    ev.u.create2.product = pid;
+    ev.u.create2.version = 0;
+    ev.u.create2.country = 0;
 
     errno = 0;
     ssize_t ret = TEMP_FAILURE_RETRY(::write(fd, &ev, sizeof(ev)));
     if (ret < 0 || ret != sizeof(ev)) {
         ::close(fd);
-        ALOGE("Failed to create uhid node: %s", strerror(errno));
+        LOGE("Failed to create uhid node: %s", strerror(errno));
         return nullptr;
     }
 
@@ -116,20 +124,30 @@
     ret = TEMP_FAILURE_RETRY(::read(fd, &ev, sizeof(ev)));
     if (ret < 0 || ev.type != UHID_START) {
         ::close(fd);
-        ALOGE("uhid node failed to start: %s", strerror(errno));
+        LOGE("uhid node failed to start: %s", strerror(errno));
         return nullptr;
     }
-
-    return new Device(id, fd, std::move(callback), looper);
+    return new Device(id, fd, std::move(callback));
 }
 
-Device::Device(int32_t id, int fd, std::unique_ptr<DeviceCallback> callback, sp<Looper> looper) :
-            mId(id), mFd(fd), mDeviceCallback(std::move(callback)), mLooper(looper) {
-    looper->addFd(fd, 0, Looper::EVENT_INPUT, handleLooperEvents, reinterpret_cast<void*>(this));
+Device::Device(int32_t id, int fd, std::unique_ptr<DeviceCallback> callback) :
+            mId(id), mFd(fd), mDeviceCallback(std::move(callback)) {
+    ALooper* aLooper = ALooper_forThread();
+    if (aLooper == NULL) {
+        LOGE("Could not get ALooper, ALooper_forThread returned NULL");
+        aLooper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
+    }
+    ALooper_addFd(aLooper, fd, 0, ALOOPER_EVENT_INPUT, handleLooperEvents,
+                  reinterpret_cast<void*>(this));
 }
 
 Device::~Device() {
-    mLooper->removeFd(mFd);
+    ALooper* looper = ALooper_forThread();
+    if (looper != NULL) {
+        ALooper_removeFd(looper, mFd);
+    } else {
+        LOGE("Could not remove fd, ALooper_forThread() returned NULL!");
+    }
     struct uhid_event ev;
     memset(&ev, 0, sizeof(ev));
     ev.type = UHID_DESTROY;
@@ -141,25 +159,25 @@
 void Device::sendReport(uint8_t* report, size_t reportSize) {
     struct uhid_event ev;
     memset(&ev, 0, sizeof(ev));
-    ev.type = UHID_INPUT;
-    ev.u.input.size = reportSize;
-    memcpy(&ev.u.input.data, report, reportSize);
+    ev.type = UHID_INPUT2;
+    ev.u.input2.size = reportSize;
+    memcpy(&ev.u.input2.data, report, reportSize);
     ssize_t ret = TEMP_FAILURE_RETRY(::write(mFd, &ev, sizeof(ev)));
     if (ret < 0 || ret != sizeof(ev)) {
-        ALOGE("Failed to send hid event: %s", strerror(errno));
+        LOGE("Failed to send hid event: %s", strerror(errno));
     }
 }
 
 int Device::handleEvents(int events) {
-    if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
-        ALOGE("uhid node was closed or an error occurred. events=0x%x", events);
+    if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
+        LOGE("uhid node was closed or an error occurred. events=0x%x", events);
         mDeviceCallback->onDeviceError();
         return 0;
     }
     struct uhid_event ev;
     ssize_t ret = TEMP_FAILURE_RETRY(::read(mFd, &ev, sizeof(ev)));
     if (ret < 0) {
-        ALOGE("Failed to read from uhid node: %s", strerror(errno));
+        LOGE("Failed to read from uhid node: %s", strerror(errno));
         mDeviceCallback->onDeviceError();
         return 0;
     }
@@ -184,7 +202,7 @@
 }
 
 static jlong openDevice(JNIEnv* env, jclass /* clazz */, jstring rawName, jint id, jint vid, jint pid,
-        jbyteArray rawDescriptor, jobject queue, jobject callback) {
+        jbyteArray rawDescriptor, jobject callback) {
     ScopedUtfChars name(env, rawName);
     if (name.c_str() == nullptr) {
         return 0;
@@ -194,20 +212,21 @@
     std::unique_ptr<uint8_t[]> desc = getData(env, rawDescriptor, size);
 
     std::unique_ptr<uhid::DeviceCallback> cb(new uhid::DeviceCallback(env, callback));
-    sp<Looper> looper = android_os_MessageQueue_getMessageQueue(env, queue)->getLooper();
 
     uhid::Device* d = uhid::Device::open(
             id, reinterpret_cast<const char*>(name.c_str()), vid, pid,
-            std::move(desc), size, std::move(cb), std::move(looper));
+            std::move(desc), size, std::move(cb));
     return reinterpret_cast<jlong>(d);
 }
 
-static void sendReport(JNIEnv* env, jclass /* clazz */, jlong ptr,jbyteArray rawReport) {
+static void sendReport(JNIEnv* env, jclass /* clazz */, jlong ptr, jbyteArray rawReport) {
     size_t size;
     std::unique_ptr<uint8_t[]> report = getData(env, rawReport, size);
     uhid::Device* d = reinterpret_cast<uhid::Device*>(ptr);
     if (d) {
         d->sendReport(report.get(), size);
+    } else {
+        LOGE("Could not send report, Device* is null!");
     }
 }
 
@@ -220,7 +239,7 @@
 
 static JNINativeMethod sMethods[] = {
     { "nativeOpenDevice",
-            "(Ljava/lang/String;III[BLandroid/os/MessageQueue;"
+            "(Ljava/lang/String;III[B"
             "Lcom/android/commands/hid/Device$DeviceCallback;)J",
             reinterpret_cast<void*>(openDevice) },
     { "nativeSendReport", "(J[B)V", reinterpret_cast<void*>(sendReport) },
@@ -228,11 +247,21 @@
 };
 
 int register_com_android_commands_hid_Device(JNIEnv* env) {
-    jclass clazz = FindClassOrDie(env, "com/android/commands/hid/Device$DeviceCallback");
+    jclass clazz = env->FindClass("com/android/commands/hid/Device$DeviceCallback");
+    if (clazz == NULL) {
+        LOGE("Unable to find class 'DeviceCallback'");
+        return JNI_ERR;
+    }
     uhid::gDeviceCallbackClassInfo.onDeviceOpen =
-            GetMethodIDOrDie(env, clazz, "onDeviceOpen", "()V");
-    uhid::gDeviceCallbackClassInfo.onDeviceError=
-            GetMethodIDOrDie(env, clazz, "onDeviceError", "()V");
+            env->GetMethodID(clazz, "onDeviceOpen", "()V");
+    uhid::gDeviceCallbackClassInfo.onDeviceError =
+            env->GetMethodID(clazz, "onDeviceError", "()V");
+    if (uhid::gDeviceCallbackClassInfo.onDeviceOpen == NULL ||
+            uhid::gDeviceCallbackClassInfo.onDeviceError == NULL) {
+        LOGE("Unable to obtain onDeviceOpen or onDeviceError methods");
+        return JNI_ERR;
+    }
+
     return jniRegisterNativeMethods(env, "com/android/commands/hid/Device",
             sMethods, NELEM(sMethods));
 }
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.h b/cmds/hid/jni/com_android_commands_hid_Device.h
index 6c5899e..149456d 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.h
+++ b/cmds/hid/jni/com_android_commands_hid_Device.h
@@ -17,8 +17,6 @@
 #include <memory>
 
 #include <jni.h>
-#include <utils/Looper.h>
-#include <utils/StrongPointer.h>
 
 namespace android {
 namespace uhid {
@@ -32,16 +30,18 @@
     void onDeviceError();
 
 private:
+    JNIEnv* getJNIEnv();
     jobject mCallbackObject;
+    JavaVM* mJavaVM;
 };
 
 class Device {
 public:
     static Device* open(int32_t id, const char* name, int32_t vid, int32_t pid,
             std::unique_ptr<uint8_t[]> descriptor, size_t descriptorSize,
-            std::unique_ptr<DeviceCallback> callback, sp<Looper> looper);
+            std::unique_ptr<DeviceCallback> callback);
 
-    Device(int32_t id, int fd, std::unique_ptr<DeviceCallback> callback, sp<Looper> looper);
+    Device(int32_t id, int fd, std::unique_ptr<DeviceCallback> callback);
     ~Device();
 
     void sendReport(uint8_t* report, size_t reportSize);
@@ -53,7 +53,6 @@
     int32_t mId;
     int mFd;
     std::unique_ptr<DeviceCallback> mDeviceCallback;
-    sp<Looper> mLooper;
 };
 
 
diff --git a/cmds/hid/src/com/android/commands/hid/Device.java b/cmds/hid/src/com/android/commands/hid/Device.java
index dbe883b..8c52a8e 100644
--- a/cmds/hid/src/com/android/commands/hid/Device.java
+++ b/cmds/hid/src/com/android/commands/hid/Device.java
@@ -29,22 +29,14 @@
 public class Device {
     private static final String TAG = "HidDevice";
 
-    // Minimum amount of time to wait before sending input events to a device. Even though we're
-    // guaranteed that the device has been created and opened by the input system, there's still a
-    // window in which the system hasn't started reading events out of it. If a stream of events
-    // begins in during this window (like a button down event) and *then* we start reading, we're
-    // liable to ignore the whole stream.
-    private static final int MIN_WAIT_FOR_FIRST_EVENT = 150;
-
     private static final int MSG_OPEN_DEVICE = 1;
     private static final int MSG_SEND_REPORT = 2;
     private static final int MSG_CLOSE_DEVICE = 3;
 
-
     private final int mId;
     private final HandlerThread mThread;
     private final DeviceHandler mHandler;
-    private long mEventTime;
+    private long mTimeToSend;
 
     private final Object mCond = new Object();
 
@@ -53,7 +45,7 @@
     }
 
     private static native long nativeOpenDevice(String name, int id, int vid, int pid,
-            byte[] descriptor, MessageQueue queue, DeviceCallback callback);
+            byte[] descriptor, DeviceCallback callback);
     private static native void nativeSendReport(long ptr, byte[] data);
     private static native void nativeCloseDevice(long ptr);
 
@@ -74,22 +66,22 @@
         args.arg2 = descriptor;
         args.arg3 = report;
         mHandler.obtainMessage(MSG_OPEN_DEVICE, args).sendToTarget();
-        mEventTime = SystemClock.uptimeMillis() + MIN_WAIT_FOR_FIRST_EVENT;
+        mTimeToSend = SystemClock.uptimeMillis();
     }
 
     public void sendReport(byte[] report) {
         Message msg = mHandler.obtainMessage(MSG_SEND_REPORT, report);
-        mHandler.sendMessageAtTime(msg, mEventTime);
+        // if two messages are sent at identical time, they will be processed in order received
+        mHandler.sendMessageAtTime(msg, mTimeToSend);
     }
 
     public void addDelay(int delay) {
-        mEventTime += delay;
+        mTimeToSend = Math.max(SystemClock.uptimeMillis(), mTimeToSend) + delay;
     }
 
     public void close() {
         Message msg = mHandler.obtainMessage(MSG_CLOSE_DEVICE);
-        msg.setAsynchronous(true);
-        mHandler.sendMessageAtTime(msg, mEventTime + 1);
+        mHandler.sendMessageAtTime(msg, Math.max(SystemClock.uptimeMillis(), mTimeToSend) + 1);
         try {
             synchronized (mCond) {
                 mCond.wait();
@@ -111,8 +103,7 @@
                 case MSG_OPEN_DEVICE:
                     SomeArgs args = (SomeArgs) msg.obj;
                     mPtr = nativeOpenDevice((String) args.arg1, args.argi1, args.argi2, args.argi3,
-                            (byte[]) args.arg2, getLooper().myQueue(), new DeviceCallback());
-                    nativeSendReport(mPtr, (byte[]) args.arg3);
+                            (byte[]) args.arg2, new DeviceCallback());
                     pauseEvents();
                     break;
                 case MSG_SEND_REPORT:
@@ -155,6 +146,7 @@
         }
 
         public void onDeviceError() {
+            Log.e(TAG, "Device error occurred, closing /dev/uhid");
             Message msg = mHandler.obtainMessage(MSG_CLOSE_DEVICE);
             msg.setAsynchronous(true);
             msg.sendToTarget();
diff --git a/cmds/hid/src/com/android/commands/hid/Hid.java b/cmds/hid/src/com/android/commands/hid/Hid.java
index 976a782..234e47f 100644
--- a/cmds/hid/src/com/android/commands/hid/Hid.java
+++ b/cmds/hid/src/com/android/commands/hid/Hid.java
@@ -16,7 +16,6 @@
 
 package com.android.commands.hid;
 
-import android.os.SystemClock;
 import android.util.JsonReader;
 import android.util.JsonToken;
 import android.util.Log;
@@ -91,7 +90,6 @@
         }
     }
 
-
     private void process(Event e) {
         final int index = mDevices.indexOfKey(e.getId());
         if (index >= 0) {
@@ -101,10 +99,16 @@
             } else if (Event.COMMAND_REPORT.equals(e.getCommand())) {
                 d.sendReport(e.getReport());
             } else {
-                error("Unknown command \"" + e.getCommand() + "\". Ignoring event.");
+                if (Event.COMMAND_REGISTER.equals(e.getCommand())) {
+                    error("Device id=" + e.getId() + " is already registered. Ignoring event.");
+                } else {
+                    error("Unknown command \"" + e.getCommand() + "\". Ignoring event.");
+                }
             }
-        } else {
+        } else if (Event.COMMAND_REGISTER.equals(e.getCommand())) {
             registerDevice(e);
+        } else {
+            Log.e(TAG, "Unknown device id specified. Ignoring event.");
         }
     }
 
@@ -124,7 +128,6 @@
     }
 
     private static void error(String msg, Exception e) {
-        System.out.println(msg);
         Log.e(TAG, msg);
         if (e != null) {
             Log.e(TAG, Log.getStackTraceString(e));
diff --git a/cmds/idmap/create.cpp b/cmds/idmap/create.cpp
index 524db14..f415f8f 100644
--- a/cmds/idmap/create.cpp
+++ b/cmds/idmap/create.cpp
@@ -104,13 +104,17 @@
             }
         }
 
-        uint32_t cached_target_crc, cached_overlay_crc;
+        uint32_t version, cached_target_crc, cached_overlay_crc;
         String8 cached_target_path, cached_overlay_path;
-        if (!ResTable::getIdmapInfo(buf, N, NULL, &cached_target_crc, &cached_overlay_crc,
+        if (!ResTable::getIdmapInfo(buf, N, &version, &cached_target_crc, &cached_overlay_crc,
                     &cached_target_path, &cached_overlay_path)) {
             return true;
         }
 
+        if (version != ResTable::IDMAP_CURRENT_VERSION) {
+            return true;
+        }
+
         if (cached_target_path != target_apk_path) {
             return true;
         }
diff --git a/cmds/idmap/inspect.cpp b/cmds/idmap/inspect.cpp
index 154cb25..20005e27 100644
--- a/cmds/idmap/inspect.cpp
+++ b/cmds/idmap/inspect.cpp
@@ -284,7 +284,9 @@
                 if (err != NO_ERROR) {
                     return err;
                 }
-                print("", "entry", data32, "%s/%s", type.string(), name.string());
+                if (data32 != ResTable_type::NO_ENTRY) {
+                    print("", "entry", data32, "%s/%s", type.string(), name.string());
+                }
             }
         }
 
diff --git a/cmds/ime/ime b/cmds/ime/ime
index 96c56d3..1a1fdd9 100755
--- a/cmds/ime/ime
+++ b/cmds/ime/ime
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "pm" on the device, which has a very rudimentary
 # shell.
 #
diff --git a/cmds/input/input b/cmds/input/input
index 7f1a18e..54ab947 100755
--- a/cmds/input/input
+++ b/cmds/input/input
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "input" on the device, which has a very rudimentary
 # shell.
 #
diff --git a/cmds/interrupter/Android.bp b/cmds/interrupter/Android.bp
new file mode 100644
index 0000000..d68e7fe
--- /dev/null
+++ b/cmds/interrupter/Android.bp
@@ -0,0 +1,11 @@
+cc_library_shared {
+    name: "interrupter",
+    host_supported: true,
+    srcs: ["interrupter.c"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wunused",
+        "-Wunreachable-code",
+    ],
+}
diff --git a/cmds/interrupter/Android.mk b/cmds/interrupter/Android.mk
deleted file mode 100644
index 97a96bf..0000000
--- a/cmds/interrupter/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    interrupter.c
-LOCAL_MODULE := interrupter
-LOCAL_MODULE_TAGS := eng tests
-LOCAL_LDFLAGS := -ldl
-LOCAL_CFLAGS := -Wall -Werror -Wunused -Wunreachable-code
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    interrupter.c
-LOCAL_MODULE := interrupter
-LOCAL_MODULE_TAGS := eng tests
-LOCAL_LDFLAGS := -ldl
-LOCAL_CFLAGS := -Wall -Werror -Wunused -Wunreachable-code
-
-include $(BUILD_HOST_SHARED_LIBRARY)
diff --git a/cmds/locksettings/locksettings b/cmds/locksettings/locksettings
index c963b23..0ef4fa9 100755
--- a/cmds/locksettings/locksettings
+++ b/cmds/locksettings/locksettings
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "locksettings" on the device
 #
 base=/system
diff --git a/cmds/media/media b/cmds/media/media
index 1194442..5c0eb2f 100755
--- a/cmds/media/media
+++ b/cmds/media/media
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "media_cmd" on the device, which has a very rudimentary
 # shell.
 #
diff --git a/cmds/pm/pm b/cmds/pm/pm
index 8183838..53f85b2 100755
--- a/cmds/pm/pm
+++ b/cmds/pm/pm
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "pm" on the device, which has a very rudimentary
 # shell.
 #
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index d71573f..c4193f6 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -1473,7 +1473,7 @@
         ClearDataObserver obs = new ClearDataObserver();
         try {
             mPm.freeStorageAndNotify(volumeUuid, sizeVal,
-                    StorageManager.FLAG_ALLOCATE_DEFY_RESERVED, obs);
+                    StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs);
             synchronized (obs) {
                 while (!obs.finished) {
                     try {
diff --git a/cmds/requestsync/requestsync b/cmds/requestsync/requestsync
index 9315675..2d5d0e4 100755
--- a/cmds/requestsync/requestsync
+++ b/cmds/requestsync/requestsync
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "requestsync" on the device
 #
 base=/system
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index e5c2466..6ded246 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -33,17 +33,24 @@
 #include <ui/DisplayInfo.h>
 #include <ui/PixelFormat.h>
 
+#include <system/graphics.h>
+
 // TODO: Fix Skia.
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wunused-parameter"
 #include <SkImageEncoder.h>
 #include <SkData.h>
+#include <SkColorSpace.h>
 #pragma GCC diagnostic pop
 
 using namespace android;
 
 static uint32_t DEFAULT_DISPLAY_ID = ISurfaceComposer::eDisplayIdMain;
 
+#define COLORSPACE_UNKNOWN    0
+#define COLORSPACE_SRGB       1
+#define COLORSPACE_DISPLAY_P3 2
+
 static void usage(const char* pname)
 {
     fprintf(stderr,
@@ -67,11 +74,33 @@
     }
 }
 
+static sk_sp<SkColorSpace> dataSpaceToColorSpace(android_dataspace d)
+{
+    switch (d) {
+        case HAL_DATASPACE_V0_SRGB:
+            return SkColorSpace::MakeSRGB();
+        case HAL_DATASPACE_DISPLAY_P3:
+            return SkColorSpace::MakeRGB(
+                    SkColorSpace::kSRGB_RenderTargetGamma, SkColorSpace::kDCIP3_D65_Gamut);
+        default:
+            return nullptr;
+    }
+}
+
+static uint32_t dataSpaceToInt(android_dataspace d)
+{
+    switch (d) {
+        case HAL_DATASPACE_V0_SRGB:
+            return COLORSPACE_SRGB;
+        case HAL_DATASPACE_DISPLAY_P3:
+            return COLORSPACE_DISPLAY_P3;
+        default:
+            return COLORSPACE_UNKNOWN;
+    }
+}
+
 static status_t notifyMediaScanner(const char* fileName) {
     String8 cmd("am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file://");
-    String8 fileUrl("\"");
-    fileUrl.append(fileName);
-    fileUrl.append("\"");
     cmd.append(fileName);
     cmd.append(" > /dev/null");
     int result = system(cmd.string());
@@ -84,13 +113,6 @@
 
 int main(int argc, char** argv)
 {
-    // setThreadPoolMaxThreadCount(0) actually tells the kernel it's
-    // not allowed to spawn any additional threads, but we still spawn
-    // a binder thread from userspace when we call startThreadPool().
-    // See b/36066697 for rationale
-    ProcessState::self()->setThreadPoolMaxThreadCount(0);
-    ProcessState::self()->startThreadPool();
-
     const char* pname = argv[0];
     bool png = false;
     int32_t displayId = DEFAULT_DISPLAY_ID;
@@ -139,6 +161,7 @@
 
     void const* base = NULL;
     uint32_t w, s, h, f;
+    android_dataspace d;
     size_t size = 0;
 
     // Maps orientations from DisplayInfo to ISurfaceComposer
@@ -149,11 +172,19 @@
         ISurfaceComposer::eRotate90, // 3 == DISPLAY_ORIENTATION_270
     };
 
+    // setThreadPoolMaxThreadCount(0) actually tells the kernel it's
+    // not allowed to spawn any additional threads, but we still spawn
+    // a binder thread from userspace when we call startThreadPool().
+    // See b/36066697 for rationale
+    ProcessState::self()->setThreadPoolMaxThreadCount(0);
+    ProcessState::self()->startThreadPool();
+
     ScreenshotClient screenshot;
     sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
     if (display == NULL) {
         fprintf(stderr, "Unable to get handle for display %d\n", displayId);
-        return 1;
+        // b/36066697: Avoid running static destructors.
+        _exit(1);
     }
 
     Vector<DisplayInfo> configs;
@@ -162,7 +193,8 @@
     if (static_cast<size_t>(activeConfig) >= configs.size()) {
         fprintf(stderr, "Active config %d not inside configs (size %zu)\n",
                 activeConfig, configs.size());
-        return 1;
+        // b/36066697: Avoid running static destructors.
+        _exit(1);
     }
     uint8_t displayOrientation = configs[activeConfig].orientation;
     uint32_t captureOrientation = ORIENTATION_MAP[displayOrientation];
@@ -177,13 +209,15 @@
         h = screenshot.getHeight();
         s = screenshot.getStride();
         f = screenshot.getFormat();
+        d = screenshot.getDataSpace();
         size = screenshot.getSize();
     }
 
     if (base != NULL) {
         if (png) {
             const SkImageInfo info =
-                SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType);
+                SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType,
+                    dataSpaceToColorSpace(d));
             SkPixmap pixmap(info, base, s * bytesPerPixel(f));
             struct FDWStream final : public SkWStream {
               size_t fBytesWritten = 0;
@@ -200,9 +234,11 @@
                 notifyMediaScanner(fn);
             }
         } else {
+            uint32_t c = dataSpaceToInt(d);
             write(fd, &w, 4);
             write(fd, &h, 4);
             write(fd, &f, 4);
+            write(fd, &c, 4);
             size_t Bpp = bytesPerPixel(f);
             for (size_t y=0 ; y<h ; y++) {
                 write(fd, base, w*Bpp);
diff --git a/cmds/sm/sm b/cmds/sm/sm
index 8fba007..4bc859e0 100755
--- a/cmds/sm/sm
+++ b/cmds/sm/sm
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "sm" on the device, which has a very rudimentary
 # shell.
 #
diff --git a/cmds/svc/svc b/cmds/svc/svc
index 27111cd..07b50fe 100755
--- a/cmds/svc/svc
+++ b/cmds/svc/svc
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "am" on the device, which has a very rudimentary
 # shell.
 #
diff --git a/cmds/telecom/telecom b/cmds/telecom/telecom
index 9efdcfd..a19036b 100755
--- a/cmds/telecom/telecom
+++ b/cmds/telecom/telecom
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "telecom" on the device
 #
 base=/system
diff --git a/cmds/uiautomator/cmds/uiautomator/uiautomator b/cmds/uiautomator/cmds/uiautomator/uiautomator
index 86a1dba..889c2b5 100755
--- a/cmds/uiautomator/cmds/uiautomator/uiautomator
+++ b/cmds/uiautomator/cmds/uiautomator/uiautomator
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 #
 # Copyright (C) 2012 The Android Open Source Project
 #
diff --git a/cmds/vr/src/com/android/commands/vr/Vr.java b/cmds/vr/src/com/android/commands/vr/Vr.java
index b765866..8fb1b7b 100644
--- a/cmds/vr/src/com/android/commands/vr/Vr.java
+++ b/cmds/vr/src/com/android/commands/vr/Vr.java
@@ -41,6 +41,7 @@
         "set-persistent-vr-mode-enabled";
     private static final String COMMAND_SET_VR2D_DISPLAY_PROPERTIES =
         "set-display-props";
+    private static final String COMMAND_ENABLE_VD = "enable-virtual-display";
 
     private IVrManager mVrService;
 
@@ -49,7 +50,8 @@
         out.println(
                 "usage: vr [subcommand]\n" +
                 "usage: vr set-persistent-vr-mode-enabled [true|false]\n" +
-                "usage: vr set-display-props [width] [height] [dpi]\n"
+                "usage: vr set-display-props [width] [height] [dpi]\n" +
+                "usage: vr enable-virtual-display [true|false]\n"
                 );
     }
 
@@ -69,6 +71,9 @@
             case COMMAND_SET_PERSISTENT_VR_MODE_ENABLED:
                 runSetPersistentVrModeEnabled();
                 break;
+            case COMMAND_ENABLE_VD:
+                runEnableVd();
+                break;
             default:
                 throw new IllegalArgumentException ("unknown command '" + command + "'");
         }
@@ -94,6 +99,23 @@
         }
     }
 
+    private void runEnableVd() throws RemoteException {
+        Vr2dDisplayProperties.Builder builder = new Vr2dDisplayProperties.Builder();
+
+        String value = nextArgRequired();
+        if ("true".equals(value)) {
+            builder.setEnabled(true);
+        } else if ("false".equals(value)) {
+            builder.setEnabled(false);
+        } // Don't do anything if not exactly true/false
+
+        try {
+            mVrService.setVr2dDisplayProperties(builder.build());
+        } catch (RemoteException re) {
+            System.err.println("Error: Can't enable (" + value +") virtual display" + re);
+        }
+    }
+
     private void runSetPersistentVrModeEnabled() throws RemoteException {
         String enableStr = nextArg();
         boolean enabled = Boolean.parseBoolean(enableStr);
diff --git a/cmds/vr/vr b/cmds/vr/vr
index a279007..dbde02a 100755
--- a/cmds/vr/vr
+++ b/cmds/vr/vr
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "vr" on the device
 #
 base=/system
diff --git a/cmds/webview_zygote/Android.mk b/cmds/webview_zygote/Android.mk
index 66e762c..955e58e 100644
--- a/cmds/webview_zygote/Android.mk
+++ b/cmds/webview_zygote/Android.mk
@@ -21,6 +21,8 @@
 
 LOCAL_SRC_FILES := webview_zygote.cpp
 
+LOCAL_CFLAGS := -Wall -Werror
+
 LOCAL_SHARED_LIBRARIES := \
 	libandroid_runtime \
 	libbinder \
diff --git a/cmds/wm/wm b/cmds/wm/wm
index f7a5bc7..16d6bd6 100755
--- a/cmds/wm/wm
+++ b/cmds/wm/wm
@@ -1,3 +1,4 @@
+#!/system/bin/sh
 # Script to start "wm" on the device, which has a very rudimentary
 # shell.
 #
diff --git a/compiled-classes-phone b/compiled-classes-phone
deleted file mode 100644
index cf4b28b..0000000
--- a/compiled-classes-phone
+++ /dev/null
@@ -1,8524 +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.
-#
-#
-#
-# Compiled-classes filter file for phones.
-#
-# Using a compiled-classes file filters non-mentioned classes from being compiled into
-# the boot.oat file(s), reducing the size of the boot image. This is a tradeoff, as classes
-# that have not been compiled must be run with the interpreter or through JIT.
-#
-# This file has been derived for mainline phone (and tablet) usage in concern with the
-# preloaded-classes file, but is not used by default. To use this file, add a copy statement
-# to your device.mk, e.g.,
-#
-#   PRODUCT_COPY_FILES += \
-#     frameworks/base/compiled-classes-phone:system/etc/compiled-classes
-#
-android.R$styleable
-android.accessibilityservice.AccessibilityServiceInfo
-android.accessibilityservice.AccessibilityServiceInfo$1
-android.accessibilityservice.IAccessibilityServiceClient
-android.accessibilityservice.IAccessibilityServiceConnection
-android.accessibilityservice.IAccessibilityServiceConnection$Stub
-android.accounts.AbstractAccountAuthenticator
-android.accounts.AbstractAccountAuthenticator$Transport
-android.accounts.Account
-android.accounts.Account$1
-android.accounts.AccountAndUser
-android.accounts.AccountAuthenticatorResponse
-android.accounts.AccountAuthenticatorResponse$1
-android.accounts.AccountManager
-android.accounts.AccountManager$1
-android.accounts.AccountManager$11
-android.accounts.AccountManager$19
-android.accounts.AccountManager$3
-android.accounts.AccountManager$4
-android.accounts.AccountManager$AmsTask
-android.accounts.AccountManager$AmsTask$1
-android.accounts.AccountManager$AmsTask$Response
-android.accounts.AccountManager$BaseFutureTask
-android.accounts.AccountManager$BaseFutureTask$1
-android.accounts.AccountManager$BaseFutureTask$Response
-android.accounts.AccountManager$Future2Task
-android.accounts.AccountManager$Future2Task$1
-android.accounts.AccountManagerCallback
-android.accounts.AccountManagerFuture
-android.accounts.AccountManagerInternal
-android.accounts.AccountManagerInternal$OnAppPermissionChangeListener
-android.accounts.AccountsException
-android.accounts.AuthenticatorDescription
-android.accounts.AuthenticatorDescription$1
-android.accounts.AuthenticatorException
-android.accounts.IAccountAuthenticator
-android.accounts.IAccountAuthenticator$Stub
-android.accounts.IAccountAuthenticator$Stub$Proxy
-android.accounts.IAccountAuthenticatorResponse
-android.accounts.IAccountAuthenticatorResponse$Stub
-android.accounts.IAccountAuthenticatorResponse$Stub$Proxy
-android.accounts.IAccountManager
-android.accounts.IAccountManager$Stub
-android.accounts.IAccountManager$Stub$Proxy
-android.accounts.IAccountManagerResponse
-android.accounts.IAccountManagerResponse$Stub
-android.accounts.IAccountManagerResponse$Stub$Proxy
-android.accounts.OnAccountsUpdateListener
-android.accounts.OperationCanceledException
-android.animation.AnimationHandler
-android.animation.AnimationHandler$1
-android.animation.AnimationHandler$AnimationFrameCallback
-android.animation.AnimationHandler$AnimationFrameCallbackProvider
-android.animation.AnimationHandler$MyFrameCallbackProvider
-android.animation.Animator
-android.animation.Animator$AnimatorConstantState
-android.animation.Animator$AnimatorListener
-android.animation.Animator$AnimatorPauseListener
-android.animation.AnimatorInflater
-android.animation.AnimatorInflater$PathDataEvaluator
-android.animation.AnimatorListenerAdapter
-android.animation.AnimatorSet
-android.animation.AnimatorSet$1
-android.animation.AnimatorSet$2
-android.animation.AnimatorSet$3
-android.animation.AnimatorSet$AnimationEvent
-android.animation.AnimatorSet$Builder
-android.animation.AnimatorSet$Node
-android.animation.AnimatorSet$SeekState
-android.animation.ArgbEvaluator
-android.animation.FloatArrayEvaluator
-android.animation.FloatEvaluator
-android.animation.FloatKeyframeSet
-android.animation.IntEvaluator
-android.animation.IntKeyframeSet
-android.animation.Keyframe
-android.animation.Keyframe$FloatKeyframe
-android.animation.Keyframe$IntKeyframe
-android.animation.Keyframe$ObjectKeyframe
-android.animation.KeyframeSet
-android.animation.Keyframes
-android.animation.Keyframes$FloatKeyframes
-android.animation.Keyframes$IntKeyframes
-android.animation.LayoutTransition
-android.animation.LayoutTransition$1
-android.animation.LayoutTransition$2
-android.animation.LayoutTransition$3
-android.animation.LayoutTransition$4
-android.animation.LayoutTransition$5
-android.animation.LayoutTransition$CleanupCallback
-android.animation.LayoutTransition$TransitionListener
-android.animation.ObjectAnimator
-android.animation.PathKeyframes
-android.animation.PathKeyframes$1
-android.animation.PathKeyframes$2
-android.animation.PathKeyframes$FloatKeyframesBase
-android.animation.PathKeyframes$IntKeyframesBase
-android.animation.PathKeyframes$SimpleKeyframes
-android.animation.PropertyValuesHolder
-android.animation.PropertyValuesHolder$1
-android.animation.PropertyValuesHolder$FloatPropertyValuesHolder
-android.animation.PropertyValuesHolder$IntPropertyValuesHolder
-android.animation.PropertyValuesHolder$PropertyValues
-android.animation.PropertyValuesHolder$PropertyValues$DataSource
-android.animation.RectEvaluator
-android.animation.RevealAnimator
-android.animation.StateListAnimator
-android.animation.StateListAnimator$1
-android.animation.StateListAnimator$StateListAnimatorConstantState
-android.animation.StateListAnimator$Tuple
-android.animation.TimeAnimator
-android.animation.TimeAnimator$TimeListener
-android.animation.TimeInterpolator
-android.animation.TypeEvaluator
-android.animation.ValueAnimator
-android.animation.ValueAnimator$AnimatorUpdateListener
-android.app.-$Lambda$9I5WEMsoBc7l4QrNqZ4wx59yuHU
-android.app.-$Lambda$9I5WEMsoBc7l4QrNqZ4wx59yuHU$1
-android.app.-$Lambda$CsyQO--8YdRe5wlajUCi-L98enA$1
-android.app.-$Lambda$CsyQO--8YdRe5wlajUCi-L98enA$2
-android.app.-$Lambda$CsyQO--8YdRe5wlajUCi-L98enA$3
-android.app.-$Lambda$FilBqgnXJrN9Mgyks1XHeAxzSTk
-android.app.-$Lambda$c44uHH2WE4sJvw5tZZB6gRzEaHI
-android.app.-$Lambda$c44uHH2WE4sJvw5tZZB6gRzEaHI$1
-android.app.-$Lambda$vZ1qb742P9hE4drBY-TrOZB_qKo
-android.app.-$Lambda$w9bG0NLfK6B6UpQKzQS6S1ayAh0
-android.app.-$Lambda$w9bG0NLfK6B6UpQKzQS6S1ayAh0$1
-android.app.ActionBar
-android.app.ActionBar$LayoutParams
-android.app.Activity
-android.app.Activity$HostCallbacks
-android.app.ActivityManager
-android.app.ActivityManager$1
-android.app.ActivityManager$AppTask
-android.app.ActivityManager$MemoryInfo
-android.app.ActivityManager$MemoryInfo$1
-android.app.ActivityManager$OnUidImportanceListener
-android.app.ActivityManager$ProcessErrorStateInfo
-android.app.ActivityManager$RecentTaskInfo
-android.app.ActivityManager$RecentTaskInfo$1
-android.app.ActivityManager$RunningAppProcessInfo
-android.app.ActivityManager$RunningAppProcessInfo$1
-android.app.ActivityManager$RunningServiceInfo
-android.app.ActivityManager$RunningServiceInfo$1
-android.app.ActivityManager$RunningTaskInfo
-android.app.ActivityManager$RunningTaskInfo$1
-android.app.ActivityManager$StackId
-android.app.ActivityManager$StackInfo
-android.app.ActivityManager$StackInfo$1
-android.app.ActivityManager$TaskDescription
-android.app.ActivityManager$TaskDescription$1
-android.app.ActivityManager$TaskSnapshot
-android.app.ActivityManager$TaskSnapshot$1
-android.app.ActivityManager$TaskThumbnail
-android.app.ActivityManager$TaskThumbnailInfo
-android.app.ActivityManager$TaskThumbnailInfo$1
-android.app.ActivityManager$UidObserver
-android.app.ActivityManagerInternal
-android.app.ActivityManagerInternal$SleepToken
-android.app.ActivityOptions
-android.app.ActivityOptions$1
-android.app.ActivityOptions$1$1
-android.app.ActivityOptions$OnAnimationFinishedListener
-android.app.ActivityOptions$OnAnimationStartedListener
-android.app.ActivityThread
-android.app.ActivityThread$1
-android.app.ActivityThread$2
-android.app.ActivityThread$ActivityClientRecord
-android.app.ActivityThread$ActivityConfigChangeData
-android.app.ActivityThread$AppBindData
-android.app.ActivityThread$ApplicationThread
-android.app.ActivityThread$BindServiceData
-android.app.ActivityThread$ContextCleanupInfo
-android.app.ActivityThread$CreateServiceData
-android.app.ActivityThread$DropBoxReporter
-android.app.ActivityThread$EventLoggingReporter
-android.app.ActivityThread$GcIdler
-android.app.ActivityThread$H
-android.app.ActivityThread$Idler
-android.app.ActivityThread$NewIntentData
-android.app.ActivityThread$Profiler
-android.app.ActivityThread$ProviderClientRecord
-android.app.ActivityThread$ProviderKey
-android.app.ActivityThread$ProviderRefCount
-android.app.ActivityThread$ReceiverData
-android.app.ActivityThread$RequestAssistContextExtras
-android.app.ActivityThread$ResultData
-android.app.ActivityThread$ServiceArgsData
-android.app.ActivityThread$StopInfo
-android.app.ActivityTransitionCoordinator
-android.app.ActivityTransitionCoordinator$ContinueTransitionListener
-android.app.ActivityTransitionCoordinator$FixedEpicenterCallback
-android.app.ActivityTransitionCoordinator$GhostViewListeners
-android.app.ActivityTransitionCoordinator$SharedElementOriginalState
-android.app.ActivityTransitionState
-android.app.AlarmManager$AlarmClockInfo
-android.app.AlarmManager$ListenerWrapper
-android.app.AlarmManager$OnAlarmListener
-android.app.AlertDialog
-android.app.AlertDialog$Builder
-android.app.AppGlobals
-android.app.AppOpsManager
-android.app.AppOpsManager$1
-android.app.AppOpsManager$OnOpChangedInternalListener
-android.app.AppOpsManager$OnOpChangedListener
-android.app.AppOpsManager$OpEntry
-android.app.AppOpsManager$OpEntry$1
-android.app.AppOpsManager$PackageOps
-android.app.AppOpsManager$PackageOps$1
-android.app.Application
-android.app.Application$ActivityLifecycleCallbacks
-android.app.ApplicationErrorReport
-android.app.ApplicationErrorReport$AnrInfo
-android.app.ApplicationErrorReport$CrashInfo
-android.app.ApplicationErrorReport$ParcelableCrashInfo
-android.app.ApplicationErrorReport$ParcelableCrashInfo$1
-android.app.ApplicationLoaders
-android.app.ApplicationPackageManager
-android.app.ApplicationPackageManager$MoveCallbackDelegate
-android.app.ApplicationPackageManager$OnPermissionsChangeListenerDelegate
-android.app.ApplicationPackageManager$ResourceName
-android.app.AutomaticZenRule
-android.app.BackStackRecord
-android.app.BackStackRecord$Op
-android.app.BroadcastOptions
-android.app.ContentProviderHolder
-android.app.ContentProviderHolder$1
-android.app.ContextImpl
-android.app.ContextImpl$ApplicationContentResolver
-android.app.DatePickerDialog$OnDateSetListener
-android.app.DexLoadReporter
-android.app.Dialog
-android.app.Dialog$ListenersHandler
-android.app.DialogFragment
-android.app.DownloadManager
-android.app.DownloadManager$CursorTranslator
-android.app.DownloadManager$Query
-android.app.EnterTransitionCoordinator
-android.app.EnterTransitionCoordinator$1
-android.app.EnterTransitionCoordinator$2
-android.app.EnterTransitionCoordinator$3
-android.app.EnterTransitionCoordinator$4
-android.app.EnterTransitionCoordinator$5
-android.app.EnterTransitionCoordinator$6
-android.app.ExitTransitionCoordinator
-android.app.ExitTransitionCoordinator$10
-android.app.ExitTransitionCoordinator$3
-android.app.ExitTransitionCoordinator$9
-android.app.Fragment
-android.app.Fragment$1
-android.app.Fragment$AnimationInfo
-android.app.FragmentContainer
-android.app.FragmentController
-android.app.FragmentHostCallback
-android.app.FragmentManager
-android.app.FragmentManager$BackStackEntry
-android.app.FragmentManager$FragmentLifecycleCallbacks
-android.app.FragmentManager$OnBackStackChangedListener
-android.app.FragmentManagerImpl
-android.app.FragmentManagerImpl$1
-android.app.FragmentManagerImpl$AnimateOnHWLayerIfNeededListener
-android.app.FragmentManagerImpl$OpGenerator
-android.app.FragmentManagerState
-android.app.FragmentManagerState$1
-android.app.FragmentState
-android.app.FragmentState$1
-android.app.FragmentTransaction
-android.app.FragmentTransition
-android.app.FragmentTransition$FragmentContainerTransition
-android.app.IActivityContainer
-android.app.IActivityContainer$Stub
-android.app.IActivityContainerCallback
-android.app.IActivityController
-android.app.IActivityManager
-android.app.IActivityManager$Stub
-android.app.IActivityManager$Stub$Proxy
-android.app.IAlarmCompleteListener
-android.app.IAlarmCompleteListener$Stub
-android.app.IAlarmCompleteListener$Stub$Proxy
-android.app.IAlarmListener
-android.app.IAlarmListener$Stub
-android.app.IAlarmListener$Stub$Proxy
-android.app.IAlarmManager
-android.app.IAlarmManager$Stub
-android.app.IAlarmManager$Stub$Proxy
-android.app.IAppTask
-android.app.IAppTask$Stub
-android.app.IAppTask$Stub$Proxy
-android.app.IApplicationThread
-android.app.IApplicationThread$Stub
-android.app.IApplicationThread$Stub$Proxy
-android.app.IInstantAppResolver
-android.app.IInstantAppResolver$Stub
-android.app.IInstantAppResolver$Stub$Proxy
-android.app.IInstrumentationWatcher
-android.app.IInstrumentationWatcher$Stub
-android.app.INotificationManager
-android.app.INotificationManager$Stub
-android.app.INotificationManager$Stub$Proxy
-android.app.IProcessObserver
-android.app.IProcessObserver$Stub
-android.app.IProcessObserver$Stub$Proxy
-android.app.ISearchManager
-android.app.ISearchManager$Stub
-android.app.ISearchManager$Stub$Proxy
-android.app.IServiceConnection
-android.app.IServiceConnection$Stub
-android.app.IServiceConnection$Stub$Proxy
-android.app.IStopUserCallback
-android.app.ITaskStackListener
-android.app.ITaskStackListener$Stub
-android.app.ITaskStackListener$Stub$Proxy
-android.app.ITransientNotification
-android.app.ITransientNotification$Stub
-android.app.ITransientNotification$Stub$Proxy
-android.app.IUiAutomationConnection
-android.app.IUiAutomationConnection$Stub
-android.app.IUiModeManager
-android.app.IUiModeManager$Stub
-android.app.IUiModeManager$Stub$Proxy
-android.app.IUidObserver
-android.app.IUidObserver$Stub
-android.app.IUidObserver$Stub$Proxy
-android.app.IUserSwitchObserver
-android.app.IUserSwitchObserver$Stub
-android.app.IUserSwitchObserver$Stub$Proxy
-android.app.IWallpaperManager
-android.app.IWallpaperManager$Stub
-android.app.IWallpaperManager$Stub$Proxy
-android.app.IWallpaperManagerCallback
-android.app.IWallpaperManagerCallback$Stub
-android.app.IWallpaperManagerCallback$Stub$Proxy
-android.app.InstantAppResolverService
-android.app.InstantAppResolverService$1
-android.app.InstantAppResolverService$InstantAppResolutionCallback
-android.app.InstantAppResolverService$ServiceHandler
-android.app.Instrumentation
-android.app.IntentReceiverLeaked
-android.app.IntentService
-android.app.IntentService$ServiceHandler
-android.app.JobSchedulerImpl
-android.app.KeyguardManager
-android.app.ListActivity
-android.app.ListFragment
-android.app.ListFragment$1
-android.app.ListFragment$2
-android.app.LoadedApk
-android.app.LoadedApk$ReceiverDispatcher
-android.app.LoadedApk$ReceiverDispatcher$Args
-android.app.LoadedApk$ReceiverDispatcher$InnerReceiver
-android.app.LoadedApk$ServiceDispatcher
-android.app.LoadedApk$ServiceDispatcher$ConnectionInfo
-android.app.LoadedApk$ServiceDispatcher$DeathMonitor
-android.app.LoadedApk$ServiceDispatcher$InnerConnection
-android.app.LoadedApk$ServiceDispatcher$RunConnection
-android.app.LoadedApk$WarningContextClassLoader
-android.app.LoaderManager
-android.app.LoaderManager$LoaderCallbacks
-android.app.LoaderManagerImpl
-android.app.LoaderManagerImpl$LoaderInfo
-android.app.NativeActivity
-android.app.Notification
-android.app.Notification$1
-android.app.Notification$Action
-android.app.Notification$Action$1
-android.app.Notification$Action$Builder
-android.app.Notification$BigPictureStyle
-android.app.Notification$BigTextStyle
-android.app.Notification$Builder
-android.app.Notification$BuilderRemoteViews
-android.app.Notification$DecoratedCustomViewStyle
-android.app.Notification$DecoratedMediaCustomViewStyle
-android.app.Notification$Extender
-android.app.Notification$InboxStyle
-android.app.Notification$MediaStyle
-android.app.Notification$MessagingStyle
-android.app.Notification$StandardTemplateParams
-android.app.Notification$Style
-android.app.Notification$TvExtender
-android.app.Notification$WearableExtender
-android.app.NotificationChannel
-android.app.NotificationChannel$1
-android.app.NotificationChannelGroup
-android.app.NotificationChannelGroup$1
-android.app.NotificationManager
-android.app.NotificationManager$Policy
-android.app.NotificationManager$Policy$1
-android.app.OnActivityPausedListener
-android.app.PackageInstallObserver
-android.app.PackageInstallObserver$1
-android.app.PendingIntent
-android.app.PendingIntent$1
-android.app.PendingIntent$CanceledException
-android.app.PendingIntent$FinishedDispatcher
-android.app.PendingIntent$OnFinished
-android.app.PendingIntent$OnMarshaledListener
-android.app.PictureInPictureParams
-android.app.PictureInPictureParams$1
-android.app.PictureInPictureParams$Builder
-android.app.ProfilerInfo
-android.app.ProgressDialog
-android.app.QueuedWork
-android.app.QueuedWork$QueuedWorkHandler
-android.app.ReceiverRestrictedContext
-android.app.RemoteAction
-android.app.RemoteAction$1
-android.app.RemoteInput
-android.app.RemoteInput$1
-android.app.ResourcesManager
-android.app.ResourcesManager$1
-android.app.ResourcesManager$ActivityResources
-android.app.ResultInfo
-android.app.ResultInfo$1
-android.app.RetailDemoModeServiceInternal
-android.app.SearchableInfo
-android.app.SearchableInfo$1
-android.app.Service
-android.app.ServiceConnectionLeaked
-android.app.ServiceStartArgs
-android.app.ServiceStartArgs$1
-android.app.SharedElementCallback
-android.app.SharedElementCallback$1
-android.app.SharedElementCallback$OnSharedElementsReadyListener
-android.app.SharedPreferencesImpl
-android.app.SharedPreferencesImpl$1
-android.app.SharedPreferencesImpl$2
-android.app.SharedPreferencesImpl$EditorImpl
-android.app.SharedPreferencesImpl$EditorImpl$1
-android.app.SharedPreferencesImpl$EditorImpl$2
-android.app.SharedPreferencesImpl$EditorImpl$3
-android.app.SharedPreferencesImpl$MemoryCommitResult
-android.app.StatusBarManager
-android.app.SynchronousUserSwitchObserver
-android.app.SystemServiceRegistry
-android.app.SystemServiceRegistry$1
-android.app.SystemServiceRegistry$10
-android.app.SystemServiceRegistry$11
-android.app.SystemServiceRegistry$12
-android.app.SystemServiceRegistry$13
-android.app.SystemServiceRegistry$14
-android.app.SystemServiceRegistry$15
-android.app.SystemServiceRegistry$16
-android.app.SystemServiceRegistry$17
-android.app.SystemServiceRegistry$18
-android.app.SystemServiceRegistry$19
-android.app.SystemServiceRegistry$2
-android.app.SystemServiceRegistry$20
-android.app.SystemServiceRegistry$21
-android.app.SystemServiceRegistry$22
-android.app.SystemServiceRegistry$23
-android.app.SystemServiceRegistry$24
-android.app.SystemServiceRegistry$25
-android.app.SystemServiceRegistry$26
-android.app.SystemServiceRegistry$27
-android.app.SystemServiceRegistry$28
-android.app.SystemServiceRegistry$29
-android.app.SystemServiceRegistry$3
-android.app.SystemServiceRegistry$30
-android.app.SystemServiceRegistry$31
-android.app.SystemServiceRegistry$32
-android.app.SystemServiceRegistry$33
-android.app.SystemServiceRegistry$34
-android.app.SystemServiceRegistry$35
-android.app.SystemServiceRegistry$36
-android.app.SystemServiceRegistry$37
-android.app.SystemServiceRegistry$38
-android.app.SystemServiceRegistry$39
-android.app.SystemServiceRegistry$4
-android.app.SystemServiceRegistry$40
-android.app.SystemServiceRegistry$41
-android.app.SystemServiceRegistry$42
-android.app.SystemServiceRegistry$43
-android.app.SystemServiceRegistry$44
-android.app.SystemServiceRegistry$45
-android.app.SystemServiceRegistry$46
-android.app.SystemServiceRegistry$47
-android.app.SystemServiceRegistry$48
-android.app.SystemServiceRegistry$49
-android.app.SystemServiceRegistry$5
-android.app.SystemServiceRegistry$50
-android.app.SystemServiceRegistry$51
-android.app.SystemServiceRegistry$52
-android.app.SystemServiceRegistry$53
-android.app.SystemServiceRegistry$54
-android.app.SystemServiceRegistry$55
-android.app.SystemServiceRegistry$56
-android.app.SystemServiceRegistry$57
-android.app.SystemServiceRegistry$58
-android.app.SystemServiceRegistry$59
-android.app.SystemServiceRegistry$6
-android.app.SystemServiceRegistry$60
-android.app.SystemServiceRegistry$61
-android.app.SystemServiceRegistry$62
-android.app.SystemServiceRegistry$63
-android.app.SystemServiceRegistry$64
-android.app.SystemServiceRegistry$65
-android.app.SystemServiceRegistry$66
-android.app.SystemServiceRegistry$67
-android.app.SystemServiceRegistry$68
-android.app.SystemServiceRegistry$69
-android.app.SystemServiceRegistry$7
-android.app.SystemServiceRegistry$70
-android.app.SystemServiceRegistry$71
-android.app.SystemServiceRegistry$72
-android.app.SystemServiceRegistry$73
-android.app.SystemServiceRegistry$74
-android.app.SystemServiceRegistry$75
-android.app.SystemServiceRegistry$76
-android.app.SystemServiceRegistry$77
-android.app.SystemServiceRegistry$78
-android.app.SystemServiceRegistry$79
-android.app.SystemServiceRegistry$8
-android.app.SystemServiceRegistry$80
-android.app.SystemServiceRegistry$81
-android.app.SystemServiceRegistry$82
-android.app.SystemServiceRegistry$9
-android.app.SystemServiceRegistry$CachedServiceFetcher
-android.app.SystemServiceRegistry$ServiceFetcher
-android.app.SystemServiceRegistry$StaticApplicationContextServiceFetcher
-android.app.SystemServiceRegistry$StaticServiceFetcher
-android.app.TaskStackListener
-android.app.TimePickerDialog$OnTimeSetListener
-android.app.UiModeManager
-android.app.UserSwitchObserver
-android.app.Vr2dDisplayProperties
-android.app.VrManager
-android.app.WaitResult
-android.app.WallpaperInfo
-android.app.WallpaperManager
-android.app.WallpaperManager$Globals
-android.app.admin.DeviceAdminInfo
-android.app.admin.DeviceAdminInfo$1
-android.app.admin.DeviceAdminInfo$PolicyInfo
-android.app.admin.DevicePolicyManager
-android.app.admin.DevicePolicyManagerInternal
-android.app.admin.DevicePolicyManagerInternal$OnCrossProfileWidgetProvidersChangeListener
-android.app.admin.IDevicePolicyManager
-android.app.admin.IDevicePolicyManager$Stub
-android.app.admin.IDevicePolicyManager$Stub$Proxy
-android.app.admin.PasswordMetrics
-android.app.admin.PasswordMetrics$1
-android.app.admin.SecurityLog
-android.app.admin.SecurityLog$SecurityEvent
-android.app.admin.SecurityLog$SecurityEvent$1
-android.app.admin.SystemUpdateInfo
-android.app.admin.SystemUpdateInfo$1
-android.app.admin.SystemUpdatePolicy
-android.app.admin.SystemUpdatePolicy$1
-android.app.assist.AssistContent
-android.app.assist.AssistStructure
-android.app.assist.AssistStructure$1
-android.app.assist.AssistStructure$AutofillOverlay
-android.app.assist.AssistStructure$ParcelTransferReader
-android.app.assist.AssistStructure$ParcelTransferWriter
-android.app.assist.AssistStructure$SendChannel
-android.app.assist.AssistStructure$ViewNode
-android.app.assist.AssistStructure$ViewNodeBuilder
-android.app.assist.AssistStructure$ViewNodeText
-android.app.assist.AssistStructure$ViewStackEntry
-android.app.assist.AssistStructure$WindowNode
-android.app.backup.BackupAgent
-android.app.backup.BackupAgentHelper
-android.app.backup.BackupDataInput
-android.app.backup.BackupDataInput$EntityHeader
-android.app.backup.BackupDataOutput
-android.app.backup.BackupHelper
-android.app.backup.BackupHelperDispatcher
-android.app.backup.BackupHelperDispatcher$Header
-android.app.backup.BackupManager
-android.app.backup.BackupTransport
-android.app.backup.BackupTransport$TransportImpl
-android.app.backup.FileBackupHelperBase
-android.app.backup.FullBackup
-android.app.backup.FullBackupDataOutput
-android.app.backup.IBackupManager
-android.app.backup.IBackupManager$Stub
-android.app.backup.IBackupManager$Stub$Proxy
-android.app.backup.IBackupManagerMonitor
-android.app.backup.IBackupObserver
-android.app.backup.IFullBackupRestoreObserver
-android.app.backup.IRestoreSession
-android.app.backup.ISelectBackupTransportCallback
-android.app.backup.RestoreDescription
-android.app.backup.RestoreSet
-android.app.job.IJobCallback
-android.app.job.IJobCallback$Stub
-android.app.job.IJobCallback$Stub$Proxy
-android.app.job.IJobScheduler
-android.app.job.IJobScheduler$Stub
-android.app.job.IJobScheduler$Stub$Proxy
-android.app.job.IJobService
-android.app.job.IJobService$Stub
-android.app.job.IJobService$Stub$Proxy
-android.app.job.JobInfo
-android.app.job.JobInfo$1
-android.app.job.JobInfo$Builder
-android.app.job.JobInfo$TriggerContentUri
-android.app.job.JobInfo$TriggerContentUri$1
-android.app.job.JobParameters
-android.app.job.JobParameters$1
-android.app.job.JobScheduler
-android.app.job.JobService
-android.app.job.JobService$1
-android.app.job.JobServiceEngine
-android.app.job.JobServiceEngine$JobHandler
-android.app.job.JobServiceEngine$JobInterface
-android.app.job.JobWorkItem
-android.app.trust.IStrongAuthTracker
-android.app.trust.IStrongAuthTracker$Stub
-android.app.trust.IStrongAuthTracker$Stub$Proxy
-android.app.trust.ITrustListener
-android.app.trust.ITrustListener$Stub
-android.app.trust.ITrustListener$Stub$Proxy
-android.app.trust.ITrustManager
-android.app.trust.ITrustManager$Stub
-android.app.trust.ITrustManager$Stub$Proxy
-android.app.trust.TrustManager
-android.app.trust.TrustManager$1
-android.app.trust.TrustManager$2
-android.app.trust.TrustManager$TrustListener
-android.app.usage.CacheQuotaHint
-android.app.usage.CacheQuotaHint$1
-android.app.usage.CacheQuotaHint$Builder
-android.app.usage.ConfigurationStats
-android.app.usage.ConfigurationStats$1
-android.app.usage.ExternalStorageStats
-android.app.usage.ICacheQuotaService
-android.app.usage.ICacheQuotaService$Stub
-android.app.usage.ICacheQuotaService$Stub$Proxy
-android.app.usage.IStorageStatsManager
-android.app.usage.IStorageStatsManager$Stub
-android.app.usage.IUsageStatsManager
-android.app.usage.IUsageStatsManager$Stub
-android.app.usage.IUsageStatsManager$Stub$Proxy
-android.app.usage.NetworkStatsManager
-android.app.usage.StorageStats
-android.app.usage.StorageStatsManager
-android.app.usage.TimeSparseArray
-android.app.usage.UsageEvents
-android.app.usage.UsageEvents$1
-android.app.usage.UsageEvents$Event
-android.app.usage.UsageStats
-android.app.usage.UsageStats$1
-android.app.usage.UsageStatsManager
-android.app.usage.UsageStatsManagerInternal
-android.app.usage.UsageStatsManagerInternal$AppIdleStateChangeListener
-android.appwidget.AppWidgetHost
-android.appwidget.AppWidgetHost$Callbacks
-android.appwidget.AppWidgetHost$UpdateHandler
-android.appwidget.AppWidgetHostView
-android.appwidget.AppWidgetHostView$1
-android.appwidget.AppWidgetHostView$ParcelableSparseArray
-android.appwidget.AppWidgetHostView$ParcelableSparseArray$1
-android.appwidget.AppWidgetManager
-android.appwidget.AppWidgetProvider
-android.appwidget.AppWidgetProviderInfo
-android.appwidget.AppWidgetProviderInfo$1
-android.appwidget.PendingHostUpdate
-android.appwidget.PendingHostUpdate$1
-android.bluetooth.BluetoothA2dp
-android.bluetooth.BluetoothA2dp$1
-android.bluetooth.BluetoothA2dp$2
-android.bluetooth.BluetoothActivityEnergyInfo
-android.bluetooth.BluetoothAdapter
-android.bluetooth.BluetoothAdapter$1
-android.bluetooth.BluetoothAdapter$BluetoothStateChangeCallback
-android.bluetooth.BluetoothCodecConfig
-android.bluetooth.BluetoothCodecConfig$1
-android.bluetooth.BluetoothCodecStatus
-android.bluetooth.BluetoothDevice
-android.bluetooth.BluetoothDevice$1
-android.bluetooth.BluetoothDevice$2
-android.bluetooth.BluetoothGatt
-android.bluetooth.BluetoothGattCallback
-android.bluetooth.BluetoothGattCharacteristic
-android.bluetooth.BluetoothGattDescriptor
-android.bluetooth.BluetoothGattService
-android.bluetooth.BluetoothHeadset
-android.bluetooth.BluetoothHeadset$1
-android.bluetooth.BluetoothHeadset$2
-android.bluetooth.BluetoothHeadset$3
-android.bluetooth.BluetoothHealthAppConfiguration
-android.bluetooth.BluetoothInputDevice
-android.bluetooth.BluetoothInputDevice$1
-android.bluetooth.BluetoothInputDevice$2
-android.bluetooth.BluetoothInputStream
-android.bluetooth.BluetoothManager
-android.bluetooth.BluetoothMap
-android.bluetooth.BluetoothMap$1
-android.bluetooth.BluetoothMap$2
-android.bluetooth.BluetoothOutputStream
-android.bluetooth.BluetoothPan
-android.bluetooth.BluetoothPan$1
-android.bluetooth.BluetoothPan$2
-android.bluetooth.BluetoothPbap
-android.bluetooth.BluetoothPbap$1
-android.bluetooth.BluetoothPbap$2
-android.bluetooth.BluetoothPbap$ServiceListener
-android.bluetooth.BluetoothProfile
-android.bluetooth.BluetoothProfile$ServiceListener
-android.bluetooth.BluetoothServerSocket
-android.bluetooth.BluetoothSocket
-android.bluetooth.BluetoothSocket$SocketState
-android.bluetooth.BluetoothUuid
-android.bluetooth.IBluetooth
-android.bluetooth.IBluetooth$Stub
-android.bluetooth.IBluetooth$Stub$Proxy
-android.bluetooth.IBluetoothA2dp
-android.bluetooth.IBluetoothA2dp$Stub
-android.bluetooth.IBluetoothA2dp$Stub$Proxy
-android.bluetooth.IBluetoothCallback
-android.bluetooth.IBluetoothCallback$Stub
-android.bluetooth.IBluetoothCallback$Stub$Proxy
-android.bluetooth.IBluetoothGatt
-android.bluetooth.IBluetoothGatt$Stub
-android.bluetooth.IBluetoothGatt$Stub$Proxy
-android.bluetooth.IBluetoothGattCallback
-android.bluetooth.IBluetoothGattServerCallback
-android.bluetooth.IBluetoothHeadset
-android.bluetooth.IBluetoothHeadset$Stub
-android.bluetooth.IBluetoothHeadset$Stub$Proxy
-android.bluetooth.IBluetoothHeadsetPhone
-android.bluetooth.IBluetoothHeadsetPhone$Stub
-android.bluetooth.IBluetoothHeadsetPhone$Stub$Proxy
-android.bluetooth.IBluetoothHealth
-android.bluetooth.IBluetoothHealth$Stub
-android.bluetooth.IBluetoothHealthCallback
-android.bluetooth.IBluetoothInputDevice
-android.bluetooth.IBluetoothInputDevice$Stub
-android.bluetooth.IBluetoothInputDevice$Stub$Proxy
-android.bluetooth.IBluetoothManager
-android.bluetooth.IBluetoothManager$Stub
-android.bluetooth.IBluetoothManager$Stub$Proxy
-android.bluetooth.IBluetoothManagerCallback
-android.bluetooth.IBluetoothManagerCallback$Stub
-android.bluetooth.IBluetoothManagerCallback$Stub$Proxy
-android.bluetooth.IBluetoothMap
-android.bluetooth.IBluetoothMap$Stub
-android.bluetooth.IBluetoothMap$Stub$Proxy
-android.bluetooth.IBluetoothPan
-android.bluetooth.IBluetoothPan$Stub
-android.bluetooth.IBluetoothPan$Stub$Proxy
-android.bluetooth.IBluetoothPbap
-android.bluetooth.IBluetoothPbap$Stub
-android.bluetooth.IBluetoothPbap$Stub$Proxy
-android.bluetooth.IBluetoothProfileServiceConnection
-android.bluetooth.IBluetoothProfileServiceConnection$Stub
-android.bluetooth.IBluetoothProfileServiceConnection$Stub$Proxy
-android.bluetooth.IBluetoothSap
-android.bluetooth.IBluetoothSap$Stub
-android.bluetooth.IBluetoothStateChangeCallback
-android.bluetooth.IBluetoothStateChangeCallback$Stub
-android.bluetooth.IBluetoothStateChangeCallback$Stub$Proxy
-android.bluetooth.OobData
-android.bluetooth.UidTraffic
-android.bluetooth.UidTraffic$1
-android.bluetooth.le.AdvertiseData
-android.bluetooth.le.AdvertisingSetParameters
-android.bluetooth.le.BluetoothLeAdvertiser
-android.bluetooth.le.BluetoothLeScanner
-android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper
-android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1
-android.bluetooth.le.BluetoothLeUtils
-android.bluetooth.le.IAdvertisingSetCallback
-android.bluetooth.le.IPeriodicAdvertisingCallback
-android.bluetooth.le.IScannerCallback
-android.bluetooth.le.IScannerCallback$Stub
-android.bluetooth.le.IScannerCallback$Stub$Proxy
-android.bluetooth.le.PeriodicAdvertisingParameters
-android.bluetooth.le.ScanCallback
-android.bluetooth.le.ScanFilter
-android.bluetooth.le.ScanFilter$1
-android.bluetooth.le.ScanFilter$Builder
-android.bluetooth.le.ScanRecord
-android.bluetooth.le.ScanResult
-android.bluetooth.le.ScanResult$1
-android.bluetooth.le.ScanSettings
-android.bluetooth.le.ScanSettings$1
-android.bluetooth.le.ScanSettings$Builder
-android.companion.AssociationRequest
-android.companion.CompanionDeviceManager
-android.companion.ICompanionDeviceManager
-android.companion.ICompanionDeviceManager$Stub
-android.companion.IFindDeviceCallback
-android.content.AbstractThreadedSyncAdapter
-android.content.AbstractThreadedSyncAdapter$ISyncAdapterImpl
-android.content.AbstractThreadedSyncAdapter$SyncThread
-android.content.ActivityNotFoundException
-android.content.AsyncQueryHandler
-android.content.AsyncQueryHandler$WorkerArgs
-android.content.AsyncQueryHandler$WorkerHandler
-android.content.AsyncTaskLoader
-android.content.AsyncTaskLoader$LoadTask
-android.content.BroadcastReceiver
-android.content.BroadcastReceiver$PendingResult
-android.content.BroadcastReceiver$PendingResult$1
-android.content.ClipData
-android.content.ClipData$1
-android.content.ClipData$Item
-android.content.ClipDescription
-android.content.ClipDescription$1
-android.content.ClipboardManager
-android.content.ClipboardManager$1
-android.content.ClipboardManager$2
-android.content.ClipboardManager$OnPrimaryClipChangedListener
-android.content.ComponentCallbacks
-android.content.ComponentCallbacks2
-android.content.ComponentName
-android.content.ComponentName$1
-android.content.ContentProvider
-android.content.ContentProvider$PipeDataWriter
-android.content.ContentProvider$Transport
-android.content.ContentProviderClient
-android.content.ContentProviderClient$CursorWrapperInner
-android.content.ContentProviderNative
-android.content.ContentProviderOperation
-android.content.ContentProviderOperation$1
-android.content.ContentProviderOperation$Builder
-android.content.ContentProviderProxy
-android.content.ContentProviderResult
-android.content.ContentProviderResult$1
-android.content.ContentQueryMap
-android.content.ContentResolver
-android.content.ContentResolver$1
-android.content.ContentResolver$CursorWrapperInner
-android.content.ContentResolver$ParcelFileDescriptorInner
-android.content.ContentUris
-android.content.ContentValues
-android.content.ContentValues$1
-android.content.Context
-android.content.ContextWrapper
-android.content.CursorLoader
-android.content.DialogInterface
-android.content.DialogInterface$OnCancelListener
-android.content.DialogInterface$OnClickListener
-android.content.DialogInterface$OnDismissListener
-android.content.DialogInterface$OnKeyListener
-android.content.DialogInterface$OnMultiChoiceClickListener
-android.content.DialogInterface$OnShowListener
-android.content.IClipboard
-android.content.IClipboard$Stub
-android.content.IClipboard$Stub$Proxy
-android.content.IContentProvider
-android.content.IContentService
-android.content.IContentService$Stub
-android.content.IContentService$Stub$Proxy
-android.content.IIntentReceiver
-android.content.IIntentReceiver$Stub
-android.content.IIntentReceiver$Stub$Proxy
-android.content.IIntentSender
-android.content.IIntentSender$Stub
-android.content.IIntentSender$Stub$Proxy
-android.content.IOnPrimaryClipChangedListener
-android.content.IOnPrimaryClipChangedListener$Stub
-android.content.IRestrictionsManager
-android.content.IRestrictionsManager$Stub
-android.content.IRestrictionsManager$Stub$Proxy
-android.content.ISyncAdapter
-android.content.ISyncAdapter$Stub
-android.content.ISyncAdapter$Stub$Proxy
-android.content.ISyncContext
-android.content.ISyncContext$Stub
-android.content.ISyncContext$Stub$Proxy
-android.content.ISyncStatusObserver
-android.content.ISyncStatusObserver$Stub
-android.content.ISyncStatusObserver$Stub$Proxy
-android.content.Intent
-android.content.Intent$1
-android.content.Intent$FilterComparison
-android.content.Intent$ShortcutIconResource
-android.content.Intent$ShortcutIconResource$1
-android.content.IntentFilter
-android.content.IntentFilter$1
-android.content.IntentFilter$AuthorityEntry
-android.content.IntentFilter$MalformedMimeTypeException
-android.content.IntentSender
-android.content.IntentSender$1
-android.content.IntentSender$SendIntentException
-android.content.Loader
-android.content.Loader$ForceLoadContentObserver
-android.content.Loader$OnLoadCanceledListener
-android.content.Loader$OnLoadCompleteListener
-android.content.OperationApplicationException
-android.content.PeriodicSync
-android.content.PeriodicSync$1
-android.content.ReceiverCallNotAllowedException
-android.content.RestrictionEntry
-android.content.RestrictionEntry$1
-android.content.RestrictionsManager
-android.content.SearchRecentSuggestionsProvider
-android.content.SearchRecentSuggestionsProvider$DatabaseHelper
-android.content.ServiceConnection
-android.content.SharedPreferences
-android.content.SharedPreferences$Editor
-android.content.SharedPreferences$OnSharedPreferenceChangeListener
-android.content.SyncAdapterType
-android.content.SyncAdapterType$1
-android.content.SyncAdaptersCache
-android.content.SyncAdaptersCache$MySerializer
-android.content.SyncContext
-android.content.SyncInfo
-android.content.SyncInfo$1
-android.content.SyncRequest
-android.content.SyncRequest$1
-android.content.SyncRequest$Builder
-android.content.SyncResult
-android.content.SyncResult$1
-android.content.SyncStats
-android.content.SyncStats$1
-android.content.SyncStatusInfo
-android.content.SyncStatusInfo$1
-android.content.SyncStatusObserver
-android.content.UndoManager
-android.content.UndoManager$UndoState
-android.content.UndoOperation
-android.content.UndoOwner
-android.content.UriMatcher
-android.content.om.IOverlayManager
-android.content.om.IOverlayManager$Stub
-android.content.om.OverlayInfo
-android.content.pm.ActivityInfo
-android.content.pm.ActivityInfo$1
-android.content.pm.ActivityInfo$WindowLayout
-android.content.pm.ApplicationInfo
-android.content.pm.ApplicationInfo$1
-android.content.pm.AuxiliaryResolveInfo
-android.content.pm.BaseParceledListSlice
-android.content.pm.BaseParceledListSlice$1
-android.content.pm.ChangedPackages
-android.content.pm.ComponentInfo
-android.content.pm.ConfigurationInfo
-android.content.pm.ConfigurationInfo$1
-android.content.pm.FallbackCategoryProvider
-android.content.pm.FeatureGroupInfo
-android.content.pm.FeatureGroupInfo$1
-android.content.pm.FeatureInfo
-android.content.pm.FeatureInfo$1
-android.content.pm.ILauncherApps
-android.content.pm.ILauncherApps$Stub
-android.content.pm.ILauncherApps$Stub$Proxy
-android.content.pm.IOnAppsChangedListener
-android.content.pm.IOnAppsChangedListener$Stub
-android.content.pm.IOnAppsChangedListener$Stub$Proxy
-android.content.pm.IOnPermissionsChangeListener
-android.content.pm.IOnPermissionsChangeListener$Stub
-android.content.pm.IOnPermissionsChangeListener$Stub$Proxy
-android.content.pm.IOtaDexopt
-android.content.pm.IOtaDexopt$Stub
-android.content.pm.IPackageDataObserver
-android.content.pm.IPackageDataObserver$Stub
-android.content.pm.IPackageDataObserver$Stub$Proxy
-android.content.pm.IPackageDeleteObserver
-android.content.pm.IPackageDeleteObserver2
-android.content.pm.IPackageInstallObserver
-android.content.pm.IPackageInstallObserver2
-android.content.pm.IPackageInstallObserver2$Stub
-android.content.pm.IPackageInstaller
-android.content.pm.IPackageInstaller$Stub
-android.content.pm.IPackageInstaller$Stub$Proxy
-android.content.pm.IPackageInstallerCallback
-android.content.pm.IPackageInstallerCallback$Stub
-android.content.pm.IPackageInstallerCallback$Stub$Proxy
-android.content.pm.IPackageInstallerSession
-android.content.pm.IPackageInstallerSession$Stub
-android.content.pm.IPackageInstallerSession$Stub$Proxy
-android.content.pm.IPackageManager
-android.content.pm.IPackageManager$Stub
-android.content.pm.IPackageManager$Stub$Proxy
-android.content.pm.IPackageMoveObserver
-android.content.pm.IPackageMoveObserver$Stub
-android.content.pm.IPackageMoveObserver$Stub$Proxy
-android.content.pm.IPackageStatsObserver
-android.content.pm.IPackageStatsObserver$Stub
-android.content.pm.IShortcutService
-android.content.pm.IShortcutService$Stub
-android.content.pm.IShortcutService$Stub$Proxy
-android.content.pm.InstantAppRequest
-android.content.pm.InstantAppResolveInfo$InstantAppDigest
-android.content.pm.InstantAppResolveInfo$InstantAppDigest$1
-android.content.pm.InstrumentationInfo
-android.content.pm.InstrumentationInfo$1
-android.content.pm.IntentFilterVerificationInfo
-android.content.pm.IntentFilterVerificationInfo$1
-android.content.pm.KeySet
-android.content.pm.LauncherActivityInfo
-android.content.pm.LauncherApps
-android.content.pm.LauncherApps$1
-android.content.pm.LauncherApps$Callback
-android.content.pm.LauncherApps$CallbackMessageHandler
-android.content.pm.LauncherApps$CallbackMessageHandler$CallbackInfo
-android.content.pm.LauncherApps$ShortcutQuery
-android.content.pm.PackageCleanItem
-android.content.pm.PackageInfo
-android.content.pm.PackageInfo$1
-android.content.pm.PackageInfoLite
-android.content.pm.PackageInfoLite$1
-android.content.pm.PackageInstaller
-android.content.pm.PackageInstaller$Session
-android.content.pm.PackageInstaller$SessionCallback
-android.content.pm.PackageInstaller$SessionCallbackDelegate
-android.content.pm.PackageInstaller$SessionInfo
-android.content.pm.PackageInstaller$SessionInfo$1
-android.content.pm.PackageInstaller$SessionParams
-android.content.pm.PackageInstaller$SessionParams$1
-android.content.pm.PackageItemInfo
-android.content.pm.PackageManager
-android.content.pm.PackageManager$MoveCallback
-android.content.pm.PackageManager$NameNotFoundException
-android.content.pm.PackageManager$OnPermissionsChangedListener
-android.content.pm.PackageManagerInternal
-android.content.pm.PackageManagerInternal$ExternalSourcesPolicy
-android.content.pm.PackageManagerInternal$PackagesProvider
-android.content.pm.PackageManagerInternal$SyncAdapterPackagesProvider
-android.content.pm.PackageParser
-android.content.pm.PackageParser$Activity
-android.content.pm.PackageParser$Activity$1
-android.content.pm.PackageParser$ActivityIntentInfo
-android.content.pm.PackageParser$ApkLite
-android.content.pm.PackageParser$Callback
-android.content.pm.PackageParser$CallbackImpl
-android.content.pm.PackageParser$Component
-android.content.pm.PackageParser$IntentInfo
-android.content.pm.PackageParser$NewPermissionInfo
-android.content.pm.PackageParser$Package
-android.content.pm.PackageParser$Package$1
-android.content.pm.PackageParser$PackageLite
-android.content.pm.PackageParser$PackageParserException
-android.content.pm.PackageParser$ParseComponentArgs
-android.content.pm.PackageParser$ParsePackageItemArgs
-android.content.pm.PackageParser$Permission
-android.content.pm.PackageParser$Permission$1
-android.content.pm.PackageParser$PermissionGroup
-android.content.pm.PackageParser$PermissionGroup$1
-android.content.pm.PackageParser$Provider
-android.content.pm.PackageParser$Provider$1
-android.content.pm.PackageParser$ProviderIntentInfo
-android.content.pm.PackageParser$Service
-android.content.pm.PackageParser$Service$1
-android.content.pm.PackageParser$ServiceIntentInfo
-android.content.pm.PackageParser$SplitNameComparator
-android.content.pm.PackageParser$SplitPermissionInfo
-android.content.pm.PackageStats
-android.content.pm.PackageUserState
-android.content.pm.ParceledListSlice
-android.content.pm.ParceledListSlice$1
-android.content.pm.PathPermission
-android.content.pm.PathPermission$1
-android.content.pm.PermissionGroupInfo
-android.content.pm.PermissionGroupInfo$1
-android.content.pm.PermissionInfo
-android.content.pm.PermissionInfo$1
-android.content.pm.ProviderInfo
-android.content.pm.ProviderInfo$1
-android.content.pm.RegisteredServicesCache
-android.content.pm.RegisteredServicesCache$1
-android.content.pm.RegisteredServicesCache$2
-android.content.pm.RegisteredServicesCache$3
-android.content.pm.RegisteredServicesCache$ServiceInfo
-android.content.pm.RegisteredServicesCache$UserServices
-android.content.pm.RegisteredServicesCacheListener
-android.content.pm.ResolveInfo
-android.content.pm.ResolveInfo$1
-android.content.pm.SELinuxUtil
-android.content.pm.ServiceInfo
-android.content.pm.ServiceInfo$1
-android.content.pm.SharedLibraryInfo
-android.content.pm.SharedLibraryInfo$1
-android.content.pm.ShortcutInfo
-android.content.pm.ShortcutInfo$1
-android.content.pm.ShortcutInfo$Builder
-android.content.pm.ShortcutManager
-android.content.pm.ShortcutServiceInternal
-android.content.pm.ShortcutServiceInternal$ShortcutChangeListener
-android.content.pm.Signature
-android.content.pm.Signature$1
-android.content.pm.StringParceledListSlice
-android.content.pm.StringParceledListSlice$1
-android.content.pm.UserInfo
-android.content.pm.UserInfo$1
-android.content.pm.VerifierDeviceIdentity
-android.content.pm.VerifierInfo
-android.content.pm.VersionedPackage
-android.content.pm.VersionedPackage$1
-android.content.pm.XmlSerializerAndParser
-android.content.pm.split.DefaultSplitAssetLoader
-android.content.pm.split.SplitAssetLoader
-android.content.pm.split.SplitDependencyLoader$IllegalDependencyException
-android.content.res.AssetFileDescriptor
-android.content.res.AssetFileDescriptor$1
-android.content.res.AssetFileDescriptor$AutoCloseInputStream
-android.content.res.AssetManager
-android.content.res.AssetManager$AssetInputStream
-android.content.res.ColorStateList
-android.content.res.ColorStateList$1
-android.content.res.ColorStateList$ColorStateListFactory
-android.content.res.CompatResources
-android.content.res.CompatibilityInfo
-android.content.res.CompatibilityInfo$1
-android.content.res.CompatibilityInfo$2
-android.content.res.ComplexColor
-android.content.res.Configuration
-android.content.res.Configuration$1
-android.content.res.ConfigurationBoundResourceCache
-android.content.res.ConstantState
-android.content.res.DrawableCache
-android.content.res.GradientColor
-android.content.res.ObbInfo
-android.content.res.ObbInfo$1
-android.content.res.ObbScanner
-android.content.res.Resources
-android.content.res.Resources$NotFoundException
-android.content.res.Resources$Theme
-android.content.res.Resources$ThemeKey
-android.content.res.ResourcesImpl
-android.content.res.ResourcesImpl$ThemeImpl
-android.content.res.ResourcesKey
-android.content.res.StringBlock
-android.content.res.StringBlock$StyleIDs
-android.content.res.ThemedResourceCache
-android.content.res.TypedArray
-android.content.res.XmlBlock
-android.content.res.XmlBlock$Parser
-android.content.res.XmlResourceParser
-android.database.AbstractCursor
-android.database.AbstractCursor$SelfContentObserver
-android.database.AbstractWindowedCursor
-android.database.BulkCursorDescriptor
-android.database.BulkCursorDescriptor$1
-android.database.BulkCursorNative
-android.database.BulkCursorProxy
-android.database.BulkCursorToCursorAdaptor
-android.database.CharArrayBuffer
-android.database.ContentObservable
-android.database.ContentObserver
-android.database.ContentObserver$NotificationRunnable
-android.database.ContentObserver$Transport
-android.database.CrossProcessCursor
-android.database.CrossProcessCursorWrapper
-android.database.Cursor
-android.database.CursorIndexOutOfBoundsException
-android.database.CursorToBulkCursorAdaptor
-android.database.CursorToBulkCursorAdaptor$ContentObserverProxy
-android.database.CursorWindow
-android.database.CursorWindow$1
-android.database.CursorWrapper
-android.database.DataSetObservable
-android.database.DataSetObserver
-android.database.DatabaseErrorHandler
-android.database.DatabaseUtils
-android.database.DatabaseUtils$InsertHelper
-android.database.DefaultDatabaseErrorHandler
-android.database.IBulkCursor
-android.database.IContentObserver
-android.database.IContentObserver$Stub
-android.database.IContentObserver$Stub$Proxy
-android.database.MatrixCursor
-android.database.MatrixCursor$RowBuilder
-android.database.MergeCursor
-android.database.MergeCursor$1
-android.database.Observable
-android.database.SQLException
-android.database.StaleDataException
-android.database.sqlite.DatabaseObjectNotClosedException
-android.database.sqlite.SQLiteAbortException
-android.database.sqlite.SQLiteCantOpenDatabaseException
-android.database.sqlite.SQLiteClosable
-android.database.sqlite.SQLiteConnection
-android.database.sqlite.SQLiteConnection$Operation
-android.database.sqlite.SQLiteConnection$OperationLog
-android.database.sqlite.SQLiteConnection$PreparedStatement
-android.database.sqlite.SQLiteConnection$PreparedStatementCache
-android.database.sqlite.SQLiteConnectionPool
-android.database.sqlite.SQLiteConnectionPool$AcquiredConnectionStatus
-android.database.sqlite.SQLiteConnectionPool$ConnectionWaiter
-android.database.sqlite.SQLiteConstraintException
-android.database.sqlite.SQLiteCursor
-android.database.sqlite.SQLiteCursorDriver
-android.database.sqlite.SQLiteCustomFunction
-android.database.sqlite.SQLiteDatabase
-android.database.sqlite.SQLiteDatabase$1
-android.database.sqlite.SQLiteDatabase$2
-android.database.sqlite.SQLiteDatabase$CursorFactory
-android.database.sqlite.SQLiteDatabase$CustomFunction
-android.database.sqlite.SQLiteDatabaseConfiguration
-android.database.sqlite.SQLiteDatabaseCorruptException
-android.database.sqlite.SQLiteDatabaseLockedException
-android.database.sqlite.SQLiteDebug
-android.database.sqlite.SQLiteDebug$PagerStats
-android.database.sqlite.SQLiteDirectCursorDriver
-android.database.sqlite.SQLiteDiskIOException
-android.database.sqlite.SQLiteDoneException
-android.database.sqlite.SQLiteException
-android.database.sqlite.SQLiteFullException
-android.database.sqlite.SQLiteGlobal
-android.database.sqlite.SQLiteOpenHelper
-android.database.sqlite.SQLiteProgram
-android.database.sqlite.SQLiteQuery
-android.database.sqlite.SQLiteQueryBuilder
-android.database.sqlite.SQLiteReadOnlyDatabaseException
-android.database.sqlite.SQLiteSession
-android.database.sqlite.SQLiteSession$Transaction
-android.database.sqlite.SQLiteStatement
-android.database.sqlite.SQLiteStatementInfo
-android.database.sqlite.SQLiteTransactionListener
-android.database.sqlite.SqliteWrapper
-android.ddm.DdmHandleAppName
-android.ddm.DdmHandleExit
-android.ddm.DdmHandleHeap
-android.ddm.DdmHandleHello
-android.ddm.DdmHandleNativeHeap
-android.ddm.DdmHandleProfiling
-android.ddm.DdmHandleThread
-android.ddm.DdmHandleViewDebug
-android.ddm.DdmRegister
-android.drm.DrmManagerClient$OnErrorListener
-android.drm.DrmManagerClient$OnEventListener
-android.drm.DrmManagerClient$OnInfoListener
-android.drm.DrmOutputStream
-android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8
-android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$1
-android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$2
-android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$4
-android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$6
-android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$7
-android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$8
-android.graphics.BaseCanvas
-android.graphics.Bitmap
-android.graphics.Bitmap$1
-android.graphics.Bitmap$CompressFormat
-android.graphics.Bitmap$Config
-android.graphics.BitmapFactory
-android.graphics.BitmapFactory$Options
-android.graphics.BitmapRegionDecoder
-android.graphics.BitmapShader
-android.graphics.BlurMaskFilter
-android.graphics.BlurMaskFilter$Blur
-android.graphics.Camera
-android.graphics.Canvas
-android.graphics.Canvas$EdgeType
-android.graphics.Canvas$NoImagePreloadHolder
-android.graphics.CanvasProperty
-android.graphics.Color
-android.graphics.ColorFilter
-android.graphics.ColorMatrix
-android.graphics.ColorMatrixColorFilter
-android.graphics.ColorSpace
-android.graphics.ColorSpace$Adaptation
-android.graphics.ColorSpace$Lab
-android.graphics.ColorSpace$Model
-android.graphics.ColorSpace$Named
-android.graphics.ColorSpace$Rgb
-android.graphics.ColorSpace$Rgb$TransferParameters
-android.graphics.ColorSpace$Xyz
-android.graphics.ComposePathEffect
-android.graphics.ComposeShader
-android.graphics.CornerPathEffect
-android.graphics.DashPathEffect
-android.graphics.DiscretePathEffect
-android.graphics.DrawFilter
-android.graphics.EmbossMaskFilter
-android.graphics.FontFamily
-android.graphics.FontListParser
-android.graphics.GraphicBuffer
-android.graphics.GraphicBuffer$1
-android.graphics.ImageFormat
-android.graphics.Insets
-android.graphics.Interpolator
-android.graphics.Interpolator$Result
-android.graphics.LightingColorFilter
-android.graphics.LinearGradient
-android.graphics.MaskFilter
-android.graphics.Matrix
-android.graphics.Matrix$1
-android.graphics.Matrix$NoImagePreloadHolder
-android.graphics.Matrix$ScaleToFit
-android.graphics.Movie
-android.graphics.NinePatch
-android.graphics.NinePatch$InsetStruct
-android.graphics.Outline
-android.graphics.Paint
-android.graphics.Paint$Align
-android.graphics.Paint$Cap
-android.graphics.Paint$FontMetrics
-android.graphics.Paint$FontMetricsInt
-android.graphics.Paint$Join
-android.graphics.Paint$NoImagePreloadHolder
-android.graphics.Paint$Style
-android.graphics.PaintFlagsDrawFilter
-android.graphics.Path
-android.graphics.Path$Direction
-android.graphics.Path$FillType
-android.graphics.Path$Op
-android.graphics.PathDashPathEffect
-android.graphics.PathEffect
-android.graphics.PathMeasure
-android.graphics.Picture
-android.graphics.Picture$RecordingCanvas
-android.graphics.PixelFormat
-android.graphics.Point
-android.graphics.Point$1
-android.graphics.PointF
-android.graphics.PointF$1
-android.graphics.PorterDuff
-android.graphics.PorterDuff$Mode
-android.graphics.PorterDuffColorFilter
-android.graphics.PorterDuffXfermode
-android.graphics.RadialGradient
-android.graphics.Rect
-android.graphics.Rect$1
-android.graphics.Rect$UnflattenHelper
-android.graphics.RectF
-android.graphics.RectF$1
-android.graphics.Region
-android.graphics.Region$1
-android.graphics.Region$Op
-android.graphics.RegionIterator
-android.graphics.Shader
-android.graphics.Shader$TileMode
-android.graphics.SumPathEffect
-android.graphics.SurfaceTexture
-android.graphics.SurfaceTexture$1
-android.graphics.SurfaceTexture$OnFrameAvailableListener
-android.graphics.SweepGradient
-android.graphics.TableMaskFilter
-android.graphics.TemporaryBuffer
-android.graphics.Typeface
-android.graphics.Typeface$Builder
-android.graphics.Xfermode
-android.graphics.YuvImage
-android.graphics.drawable.AdaptiveIconDrawable
-android.graphics.drawable.AdaptiveIconDrawable$ChildDrawable
-android.graphics.drawable.AdaptiveIconDrawable$LayerState
-android.graphics.drawable.Animatable
-android.graphics.drawable.Animatable2
-android.graphics.drawable.Animatable2$AnimationCallback
-android.graphics.drawable.AnimatedStateListDrawable
-android.graphics.drawable.AnimatedStateListDrawable$AnimatedStateListState
-android.graphics.drawable.AnimatedStateListDrawable$AnimatedVectorDrawableTransition
-android.graphics.drawable.AnimatedStateListDrawable$AnimationDrawableTransition
-android.graphics.drawable.AnimatedStateListDrawable$FrameInterpolator
-android.graphics.drawable.AnimatedStateListDrawable$Transition
-android.graphics.drawable.AnimatedVectorDrawable
-android.graphics.drawable.AnimatedVectorDrawable$1
-android.graphics.drawable.AnimatedVectorDrawable$2
-android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState
-android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator
-android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimator
-android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT
-android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorUI
-android.graphics.drawable.AnimationDrawable
-android.graphics.drawable.AnimationDrawable$AnimationState
-android.graphics.drawable.BitmapDrawable
-android.graphics.drawable.BitmapDrawable$BitmapState
-android.graphics.drawable.ClipDrawable
-android.graphics.drawable.ClipDrawable$ClipState
-android.graphics.drawable.ColorDrawable
-android.graphics.drawable.ColorDrawable$ColorState
-android.graphics.drawable.Drawable
-android.graphics.drawable.Drawable$Callback
-android.graphics.drawable.Drawable$ConstantState
-android.graphics.drawable.DrawableContainer
-android.graphics.drawable.DrawableContainer$1
-android.graphics.drawable.DrawableContainer$BlockInvalidateCallback
-android.graphics.drawable.DrawableContainer$DrawableContainerState
-android.graphics.drawable.DrawableInflater
-android.graphics.drawable.DrawableWrapper
-android.graphics.drawable.DrawableWrapper$DrawableWrapperState
-android.graphics.drawable.GradientDrawable
-android.graphics.drawable.GradientDrawable$GradientState
-android.graphics.drawable.GradientDrawable$Orientation
-android.graphics.drawable.Icon
-android.graphics.drawable.Icon$1
-android.graphics.drawable.InsetDrawable
-android.graphics.drawable.InsetDrawable$InsetState
-android.graphics.drawable.InsetDrawable$InsetValue
-android.graphics.drawable.LayerDrawable
-android.graphics.drawable.LayerDrawable$ChildDrawable
-android.graphics.drawable.LayerDrawable$LayerState
-android.graphics.drawable.NinePatchDrawable
-android.graphics.drawable.NinePatchDrawable$NinePatchState
-android.graphics.drawable.PaintDrawable
-android.graphics.drawable.PictureDrawable
-android.graphics.drawable.RippleBackground
-android.graphics.drawable.RippleBackground$1
-android.graphics.drawable.RippleBackground$BackgroundProperty
-android.graphics.drawable.RippleComponent
-android.graphics.drawable.RippleComponent$RenderNodeAnimatorSet
-android.graphics.drawable.RippleDrawable
-android.graphics.drawable.RippleDrawable$RippleState
-android.graphics.drawable.RippleForeground
-android.graphics.drawable.RippleForeground$1
-android.graphics.drawable.RippleForeground$2
-android.graphics.drawable.RippleForeground$3
-android.graphics.drawable.RippleForeground$4
-android.graphics.drawable.RippleForeground$LogDecelerateInterpolator
-android.graphics.drawable.RotateDrawable
-android.graphics.drawable.RotateDrawable$RotateState
-android.graphics.drawable.ScaleDrawable
-android.graphics.drawable.ScaleDrawable$ScaleState
-android.graphics.drawable.ShapeDrawable
-android.graphics.drawable.ShapeDrawable$ShaderFactory
-android.graphics.drawable.ShapeDrawable$ShapeState
-android.graphics.drawable.StateListDrawable
-android.graphics.drawable.StateListDrawable$StateListState
-android.graphics.drawable.TransitionDrawable
-android.graphics.drawable.TransitionDrawable$TransitionState
-android.graphics.drawable.VectorDrawable
-android.graphics.drawable.VectorDrawable$VClipPath
-android.graphics.drawable.VectorDrawable$VFullPath
-android.graphics.drawable.VectorDrawable$VFullPath$1
-android.graphics.drawable.VectorDrawable$VFullPath$10
-android.graphics.drawable.VectorDrawable$VFullPath$2
-android.graphics.drawable.VectorDrawable$VFullPath$3
-android.graphics.drawable.VectorDrawable$VFullPath$4
-android.graphics.drawable.VectorDrawable$VFullPath$5
-android.graphics.drawable.VectorDrawable$VFullPath$6
-android.graphics.drawable.VectorDrawable$VFullPath$7
-android.graphics.drawable.VectorDrawable$VFullPath$8
-android.graphics.drawable.VectorDrawable$VFullPath$9
-android.graphics.drawable.VectorDrawable$VGroup
-android.graphics.drawable.VectorDrawable$VGroup$1
-android.graphics.drawable.VectorDrawable$VGroup$2
-android.graphics.drawable.VectorDrawable$VGroup$3
-android.graphics.drawable.VectorDrawable$VGroup$4
-android.graphics.drawable.VectorDrawable$VGroup$5
-android.graphics.drawable.VectorDrawable$VGroup$6
-android.graphics.drawable.VectorDrawable$VGroup$7
-android.graphics.drawable.VectorDrawable$VGroup$8
-android.graphics.drawable.VectorDrawable$VGroup$9
-android.graphics.drawable.VectorDrawable$VObject
-android.graphics.drawable.VectorDrawable$VPath
-android.graphics.drawable.VectorDrawable$VPath$1
-android.graphics.drawable.VectorDrawable$VectorDrawableState
-android.graphics.drawable.VectorDrawable$VectorDrawableState$1
-android.graphics.drawable.shapes.OvalShape
-android.graphics.drawable.shapes.RectShape
-android.graphics.drawable.shapes.RoundRectShape
-android.graphics.drawable.shapes.Shape
-android.graphics.fonts.FontVariationAxis
-android.graphics.pdf.PdfDocument
-android.graphics.pdf.PdfEditor
-android.graphics.pdf.PdfRenderer
-android.hardware.Camera
-android.hardware.Camera$CameraInfo
-android.hardware.Camera$ErrorCallback
-android.hardware.Camera$Face
-android.hardware.CameraStatus
-android.hardware.CameraStatus$1
-android.hardware.ConsumerIrManager
-android.hardware.GeomagneticField
-android.hardware.GeomagneticField$LegendreTable
-android.hardware.HardwareBuffer
-android.hardware.HardwareBuffer$1
-android.hardware.ICameraService
-android.hardware.ICameraService$Stub
-android.hardware.ICameraService$Stub$Proxy
-android.hardware.ICameraServiceListener
-android.hardware.ICameraServiceListener$Stub
-android.hardware.ICameraServiceProxy
-android.hardware.ICameraServiceProxy$Stub
-android.hardware.IConsumerIrService
-android.hardware.IConsumerIrService$Stub
-android.hardware.ISerialManager
-android.hardware.ISerialManager$Stub
-android.hardware.Sensor
-android.hardware.SensorAdditionalInfo
-android.hardware.SensorEvent
-android.hardware.SensorEventListener
-android.hardware.SensorManager
-android.hardware.SerialManager
-android.hardware.SerialPort
-android.hardware.SystemSensorManager
-android.hardware.SystemSensorManager$BaseEventQueue
-android.hardware.SystemSensorManager$SensorEventQueue
-android.hardware.SystemSensorManager$TriggerEventQueue
-android.hardware.TriggerEvent
-android.hardware.TriggerEventListener
-android.hardware.camera2.CameraAccessException
-android.hardware.camera2.CameraCaptureSession
-android.hardware.camera2.CameraCaptureSession$CaptureCallback
-android.hardware.camera2.CameraCaptureSession$StateCallback
-android.hardware.camera2.CameraCharacteristics
-android.hardware.camera2.CameraCharacteristics$1
-android.hardware.camera2.CameraCharacteristics$2
-android.hardware.camera2.CameraCharacteristics$3
-android.hardware.camera2.CameraCharacteristics$4
-android.hardware.camera2.CameraCharacteristics$5
-android.hardware.camera2.CameraCharacteristics$Key
-android.hardware.camera2.CameraDevice
-android.hardware.camera2.CameraDevice$StateCallback
-android.hardware.camera2.CameraManager
-android.hardware.camera2.CameraManager$AvailabilityCallback
-android.hardware.camera2.CameraManager$CameraManagerGlobal
-android.hardware.camera2.CameraManager$CameraManagerGlobal$1
-android.hardware.camera2.CameraManager$CameraManagerGlobal$2
-android.hardware.camera2.CameraManager$CameraManagerGlobal$3
-android.hardware.camera2.CameraManager$CameraManagerGlobal$4
-android.hardware.camera2.CameraManager$TorchCallback
-android.hardware.camera2.CameraMetadata
-android.hardware.camera2.CaptureFailure
-android.hardware.camera2.CaptureRequest
-android.hardware.camera2.CaptureRequest$1
-android.hardware.camera2.CaptureRequest$2
-android.hardware.camera2.CaptureRequest$Builder
-android.hardware.camera2.CaptureRequest$Key
-android.hardware.camera2.CaptureResult
-android.hardware.camera2.CaptureResult$1
-android.hardware.camera2.CaptureResult$2
-android.hardware.camera2.CaptureResult$3
-android.hardware.camera2.CaptureResult$Key
-android.hardware.camera2.DngCreator
-android.hardware.camera2.ICameraDeviceCallbacks
-android.hardware.camera2.ICameraDeviceCallbacks$Stub
-android.hardware.camera2.ICameraDeviceUser
-android.hardware.camera2.ICameraDeviceUser$Stub
-android.hardware.camera2.ICameraDeviceUser$Stub$Proxy
-android.hardware.camera2.TotalCaptureResult
-android.hardware.camera2.dispatch.ArgumentReplacingDispatcher
-android.hardware.camera2.dispatch.BroadcastDispatcher
-android.hardware.camera2.dispatch.Dispatchable
-android.hardware.camera2.dispatch.DuckTypingDispatcher
-android.hardware.camera2.dispatch.HandlerDispatcher
-android.hardware.camera2.dispatch.HandlerDispatcher$1
-android.hardware.camera2.dispatch.InvokeDispatcher
-android.hardware.camera2.dispatch.MethodNameInvoker
-android.hardware.camera2.impl.CallbackProxies$DeviceCaptureCallbackProxy
-android.hardware.camera2.impl.CallbackProxies$SessionStateCallbackProxy
-android.hardware.camera2.impl.CameraCaptureSessionCore
-android.hardware.camera2.impl.CameraCaptureSessionImpl
-android.hardware.camera2.impl.CameraCaptureSessionImpl$1
-android.hardware.camera2.impl.CameraCaptureSessionImpl$2
-android.hardware.camera2.impl.CameraCaptureSessionImpl$AbortDrainListener
-android.hardware.camera2.impl.CameraCaptureSessionImpl$IdleDrainListener
-android.hardware.camera2.impl.CameraCaptureSessionImpl$SequenceDrainListener
-android.hardware.camera2.impl.CameraDeviceImpl
-android.hardware.camera2.impl.CameraDeviceImpl$1
-android.hardware.camera2.impl.CameraDeviceImpl$10
-android.hardware.camera2.impl.CameraDeviceImpl$2
-android.hardware.camera2.impl.CameraDeviceImpl$3
-android.hardware.camera2.impl.CameraDeviceImpl$4
-android.hardware.camera2.impl.CameraDeviceImpl$5
-android.hardware.camera2.impl.CameraDeviceImpl$6
-android.hardware.camera2.impl.CameraDeviceImpl$7
-android.hardware.camera2.impl.CameraDeviceImpl$9
-android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks
-android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$2
-android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$3
-android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$4
-android.hardware.camera2.impl.CameraDeviceImpl$CaptureCallback
-android.hardware.camera2.impl.CameraDeviceImpl$CaptureCallbackHolder
-android.hardware.camera2.impl.CameraDeviceImpl$FrameNumberTracker
-android.hardware.camera2.impl.CameraDeviceImpl$RequestLastFrameNumbersHolder
-android.hardware.camera2.impl.CameraDeviceImpl$StateCallbackKK
-android.hardware.camera2.impl.CameraMetadataNative
-android.hardware.camera2.impl.CameraMetadataNative$1
-android.hardware.camera2.impl.CameraMetadataNative$10
-android.hardware.camera2.impl.CameraMetadataNative$11
-android.hardware.camera2.impl.CameraMetadataNative$12
-android.hardware.camera2.impl.CameraMetadataNative$13
-android.hardware.camera2.impl.CameraMetadataNative$14
-android.hardware.camera2.impl.CameraMetadataNative$15
-android.hardware.camera2.impl.CameraMetadataNative$16
-android.hardware.camera2.impl.CameraMetadataNative$17
-android.hardware.camera2.impl.CameraMetadataNative$18
-android.hardware.camera2.impl.CameraMetadataNative$19
-android.hardware.camera2.impl.CameraMetadataNative$2
-android.hardware.camera2.impl.CameraMetadataNative$3
-android.hardware.camera2.impl.CameraMetadataNative$4
-android.hardware.camera2.impl.CameraMetadataNative$5
-android.hardware.camera2.impl.CameraMetadataNative$6
-android.hardware.camera2.impl.CameraMetadataNative$7
-android.hardware.camera2.impl.CameraMetadataNative$8
-android.hardware.camera2.impl.CameraMetadataNative$9
-android.hardware.camera2.impl.CameraMetadataNative$Key
-android.hardware.camera2.impl.CaptureResultExtras
-android.hardware.camera2.impl.CaptureResultExtras$1
-android.hardware.camera2.impl.GetCommand
-android.hardware.camera2.impl.ICameraDeviceUserWrapper
-android.hardware.camera2.impl.SetCommand
-android.hardware.camera2.legacy.LegacyCameraDevice
-android.hardware.camera2.legacy.LegacyExceptionUtils
-android.hardware.camera2.legacy.LegacyExceptionUtils$BufferQueueAbandonedException
-android.hardware.camera2.legacy.PerfMeasurement
-android.hardware.camera2.marshal.MarshalHelpers
-android.hardware.camera2.marshal.MarshalQueryable
-android.hardware.camera2.marshal.MarshalRegistry
-android.hardware.camera2.marshal.MarshalRegistry$MarshalToken
-android.hardware.camera2.marshal.Marshaler
-android.hardware.camera2.marshal.impl.MarshalQueryableArray
-android.hardware.camera2.marshal.impl.MarshalQueryableArray$MarshalerArray
-android.hardware.camera2.marshal.impl.MarshalQueryableBlackLevelPattern
-android.hardware.camera2.marshal.impl.MarshalQueryableBlackLevelPattern$MarshalerBlackLevelPattern
-android.hardware.camera2.marshal.impl.MarshalQueryableBoolean
-android.hardware.camera2.marshal.impl.MarshalQueryableBoolean$MarshalerBoolean
-android.hardware.camera2.marshal.impl.MarshalQueryableColorSpaceTransform
-android.hardware.camera2.marshal.impl.MarshalQueryableColorSpaceTransform$MarshalerColorSpaceTransform
-android.hardware.camera2.marshal.impl.MarshalQueryableEnum
-android.hardware.camera2.marshal.impl.MarshalQueryableHighSpeedVideoConfiguration
-android.hardware.camera2.marshal.impl.MarshalQueryableHighSpeedVideoConfiguration$MarshalerHighSpeedVideoConfiguration
-android.hardware.camera2.marshal.impl.MarshalQueryableMeteringRectangle
-android.hardware.camera2.marshal.impl.MarshalQueryableMeteringRectangle$MarshalerMeteringRectangle
-android.hardware.camera2.marshal.impl.MarshalQueryableNativeByteToInteger
-android.hardware.camera2.marshal.impl.MarshalQueryableNativeByteToInteger$MarshalerNativeByteToInteger
-android.hardware.camera2.marshal.impl.MarshalQueryablePair
-android.hardware.camera2.marshal.impl.MarshalQueryablePair$MarshalerPair
-android.hardware.camera2.marshal.impl.MarshalQueryableParcelable
-android.hardware.camera2.marshal.impl.MarshalQueryablePrimitive
-android.hardware.camera2.marshal.impl.MarshalQueryablePrimitive$MarshalerPrimitive
-android.hardware.camera2.marshal.impl.MarshalQueryableRange
-android.hardware.camera2.marshal.impl.MarshalQueryableRange$MarshalerRange
-android.hardware.camera2.marshal.impl.MarshalQueryableRect
-android.hardware.camera2.marshal.impl.MarshalQueryableRect$MarshalerRect
-android.hardware.camera2.marshal.impl.MarshalQueryableReprocessFormatsMap
-android.hardware.camera2.marshal.impl.MarshalQueryableReprocessFormatsMap$MarshalerReprocessFormatsMap
-android.hardware.camera2.marshal.impl.MarshalQueryableRggbChannelVector
-android.hardware.camera2.marshal.impl.MarshalQueryableRggbChannelVector$MarshalerRggbChannelVector
-android.hardware.camera2.marshal.impl.MarshalQueryableSize
-android.hardware.camera2.marshal.impl.MarshalQueryableSize$MarshalerSize
-android.hardware.camera2.marshal.impl.MarshalQueryableSizeF
-android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfiguration
-android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfiguration$MarshalerStreamConfiguration
-android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfigurationDuration
-android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfigurationDuration$MarshalerStreamConfigurationDuration
-android.hardware.camera2.marshal.impl.MarshalQueryableString
-android.hardware.camera2.params.BlackLevelPattern
-android.hardware.camera2.params.ColorSpaceTransform
-android.hardware.camera2.params.Face
-android.hardware.camera2.params.HighSpeedVideoConfiguration
-android.hardware.camera2.params.InputConfiguration
-android.hardware.camera2.params.LensShadingMap
-android.hardware.camera2.params.MeteringRectangle
-android.hardware.camera2.params.OutputConfiguration
-android.hardware.camera2.params.OutputConfiguration$1
-android.hardware.camera2.params.ReprocessFormatsMap
-android.hardware.camera2.params.RggbChannelVector
-android.hardware.camera2.params.StreamConfiguration
-android.hardware.camera2.params.StreamConfigurationDuration
-android.hardware.camera2.params.StreamConfigurationMap
-android.hardware.camera2.params.TonemapCurve
-android.hardware.camera2.utils.HashCodeHelpers
-android.hardware.camera2.utils.SubmitInfo
-android.hardware.camera2.utils.SubmitInfo$1
-android.hardware.camera2.utils.SurfaceUtils
-android.hardware.camera2.utils.TaskDrainer
-android.hardware.camera2.utils.TaskDrainer$1
-android.hardware.camera2.utils.TaskDrainer$DrainListener
-android.hardware.camera2.utils.TaskSingleDrainer
-android.hardware.camera2.utils.TypeReference
-android.hardware.camera2.utils.TypeReference$SpecializedBaseTypeReference
-android.hardware.camera2.utils.TypeReference$SpecializedTypeReference
-android.hardware.display.DisplayManager
-android.hardware.display.DisplayManager$DisplayListener
-android.hardware.display.DisplayManagerGlobal
-android.hardware.display.DisplayManagerGlobal$DisplayListenerDelegate
-android.hardware.display.DisplayManagerGlobal$DisplayManagerCallback
-android.hardware.display.DisplayManagerInternal
-android.hardware.display.DisplayManagerInternal$DisplayPowerCallbacks
-android.hardware.display.DisplayManagerInternal$DisplayPowerRequest
-android.hardware.display.DisplayManagerInternal$DisplayTransactionListener
-android.hardware.display.DisplayViewport
-android.hardware.display.IDisplayManager
-android.hardware.display.IDisplayManager$Stub
-android.hardware.display.IDisplayManager$Stub$Proxy
-android.hardware.display.IDisplayManagerCallback
-android.hardware.display.IDisplayManagerCallback$Stub
-android.hardware.display.IDisplayManagerCallback$Stub$Proxy
-android.hardware.display.IVirtualDisplayCallback
-android.hardware.display.WifiDisplay
-android.hardware.display.WifiDisplay$1
-android.hardware.display.WifiDisplaySessionInfo
-android.hardware.display.WifiDisplaySessionInfo$1
-android.hardware.display.WifiDisplayStatus
-android.hardware.display.WifiDisplayStatus$1
-android.hardware.fingerprint.Fingerprint
-android.hardware.fingerprint.Fingerprint$1
-android.hardware.fingerprint.FingerprintManager
-android.hardware.fingerprint.FingerprintManager$1
-android.hardware.fingerprint.FingerprintManager$2
-android.hardware.fingerprint.FingerprintManager$AuthenticationCallback
-android.hardware.fingerprint.FingerprintManager$AuthenticationResult
-android.hardware.fingerprint.FingerprintManager$LockoutResetCallback
-android.hardware.fingerprint.FingerprintManager$MyHandler
-android.hardware.fingerprint.IFingerprintClientActiveCallback
-android.hardware.fingerprint.IFingerprintService
-android.hardware.fingerprint.IFingerprintService$Stub
-android.hardware.fingerprint.IFingerprintService$Stub$Proxy
-android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback
-android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback$Stub
-android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback$Stub$Proxy
-android.hardware.fingerprint.IFingerprintServiceReceiver
-android.hardware.fingerprint.IFingerprintServiceReceiver$Stub
-android.hardware.hdmi.HdmiControlManager
-android.hardware.hdmi.HdmiPlaybackClient$DisplayStatusCallback
-android.hardware.input.IInputDevicesChangedListener
-android.hardware.input.IInputDevicesChangedListener$Stub
-android.hardware.input.IInputDevicesChangedListener$Stub$Proxy
-android.hardware.input.IInputManager
-android.hardware.input.IInputManager$Stub
-android.hardware.input.IInputManager$Stub$Proxy
-android.hardware.input.ITabletModeChangedListener
-android.hardware.input.InputDeviceIdentifier
-android.hardware.input.InputDeviceIdentifier$1
-android.hardware.input.InputManager
-android.hardware.input.InputManager$InputDeviceListener
-android.hardware.input.InputManager$InputDeviceListenerDelegate
-android.hardware.input.InputManager$InputDevicesChangedListener
-android.hardware.input.InputManager$OnTabletModeChangedListener
-android.hardware.input.InputManagerInternal
-android.hardware.input.KeyboardLayout
-android.hardware.input.KeyboardLayout$1
-android.hardware.input.TouchCalibration
-android.hardware.input.TouchCalibration$1
-android.hardware.location.ActivityRecognitionHardware
-android.hardware.location.ContextHubInfo
-android.hardware.location.ContextHubInfo$1
-android.hardware.location.ContextHubManager
-android.hardware.location.ContextHubManager$1
-android.hardware.location.ContextHubManager$Callback
-android.hardware.location.ContextHubManager$ICallback
-android.hardware.location.ContextHubMessage
-android.hardware.location.ContextHubMessage$1
-android.hardware.location.GeofenceHardware
-android.hardware.location.GeofenceHardware$GeofenceHardwareMonitorCallbackWrapper
-android.hardware.location.GeofenceHardwareCallback
-android.hardware.location.GeofenceHardwareImpl
-android.hardware.location.GeofenceHardwareImpl$1
-android.hardware.location.GeofenceHardwareImpl$2
-android.hardware.location.GeofenceHardwareImpl$3
-android.hardware.location.GeofenceHardwareImpl$Reaper
-android.hardware.location.GeofenceHardwareMonitorCallback
-android.hardware.location.GeofenceHardwareService
-android.hardware.location.GeofenceHardwareService$1
-android.hardware.location.IActivityRecognitionHardware
-android.hardware.location.IActivityRecognitionHardware$Stub
-android.hardware.location.IActivityRecognitionHardwareClient
-android.hardware.location.IActivityRecognitionHardwareClient$Stub
-android.hardware.location.IActivityRecognitionHardwareClient$Stub$Proxy
-android.hardware.location.IActivityRecognitionHardwareWatcher
-android.hardware.location.IContextHubCallback
-android.hardware.location.IContextHubCallback$Stub
-android.hardware.location.IContextHubCallback$Stub$Proxy
-android.hardware.location.IContextHubService
-android.hardware.location.IContextHubService$Stub
-android.hardware.location.IContextHubService$Stub$Proxy
-android.hardware.location.IFusedLocationHardware
-android.hardware.location.IGeofenceHardware
-android.hardware.location.IGeofenceHardware$Stub
-android.hardware.location.IGeofenceHardware$Stub$Proxy
-android.hardware.location.IGeofenceHardwareMonitorCallback
-android.hardware.location.IGeofenceHardwareMonitorCallback$Stub
-android.hardware.location.IGeofenceHardwareMonitorCallback$Stub$Proxy
-android.hardware.location.MemoryRegion
-android.hardware.location.MemoryRegion$1
-android.hardware.location.NanoApp
-android.hardware.location.NanoAppFilter
-android.hardware.location.NanoAppFilter$1
-android.hardware.location.NanoAppInstanceInfo
-android.hardware.location.NanoAppInstanceInfo$1
-android.hardware.radio.RadioManager
-android.hardware.radio.RadioManager$AmBandConfig
-android.hardware.radio.RadioManager$AmBandConfig$1
-android.hardware.radio.RadioManager$AmBandDescriptor
-android.hardware.radio.RadioManager$AmBandDescriptor$1
-android.hardware.radio.RadioManager$BandConfig
-android.hardware.radio.RadioManager$BandConfig$1
-android.hardware.radio.RadioManager$BandDescriptor
-android.hardware.radio.RadioManager$BandDescriptor$1
-android.hardware.radio.RadioManager$FmBandConfig
-android.hardware.radio.RadioManager$FmBandConfig$1
-android.hardware.radio.RadioManager$FmBandDescriptor
-android.hardware.radio.RadioManager$FmBandDescriptor$1
-android.hardware.radio.RadioManager$ModuleProperties
-android.hardware.radio.RadioManager$ModuleProperties$1
-android.hardware.radio.RadioManager$ProgramInfo
-android.hardware.radio.RadioManager$ProgramInfo$1
-android.hardware.radio.RadioMetadata
-android.hardware.radio.RadioMetadata$1
-android.hardware.radio.RadioModule
-android.hardware.radio.RadioTuner
-android.hardware.radio.V1_0.Call
-android.hardware.radio.V1_0.CardStatus
-android.hardware.radio.V1_0.CdmaSignalStrength
-android.hardware.radio.V1_0.CellIdentity
-android.hardware.radio.V1_0.CellIdentityCdma
-android.hardware.radio.V1_0.CellIdentityGsm
-android.hardware.radio.V1_0.CellIdentityLte
-android.hardware.radio.V1_0.CellIdentityTdscdma
-android.hardware.radio.V1_0.CellIdentityWcdma
-android.hardware.radio.V1_0.CellInfo
-android.hardware.radio.V1_0.CellInfoCdma
-android.hardware.radio.V1_0.CellInfoGsm
-android.hardware.radio.V1_0.CellInfoLte
-android.hardware.radio.V1_0.CellInfoTdscdma
-android.hardware.radio.V1_0.CellInfoType
-android.hardware.radio.V1_0.CellInfoWcdma
-android.hardware.radio.V1_0.DataRegStateResult
-android.hardware.radio.V1_0.EvdoSignalStrength
-android.hardware.radio.V1_0.GsmSignalStrength
-android.hardware.radio.V1_0.HardwareConfig
-android.hardware.radio.V1_0.IRadio
-android.hardware.radio.V1_0.IRadio$Proxy
-android.hardware.radio.V1_0.IRadioIndication
-android.hardware.radio.V1_0.IRadioIndication$Stub
-android.hardware.radio.V1_0.IRadioResponse
-android.hardware.radio.V1_0.IRadioResponse$Stub
-android.hardware.radio.V1_0.LceStatusInfo
-android.hardware.radio.V1_0.LteSignalStrength
-android.hardware.radio.V1_0.RadioCapability
-android.hardware.radio.V1_0.RadioResponseInfo
-android.hardware.radio.V1_0.RegState
-android.hardware.radio.V1_0.SignalStrength
-android.hardware.radio.V1_0.TdScdmaSignalStrength
-android.hardware.radio.V1_0.VoiceRegStateResult
-android.hardware.radio.V1_0.WcdmaSignalStrength
-android.hardware.radio.deprecated.V1_0.IOemHook
-android.hardware.radio.deprecated.V1_0.IOemHook$Proxy
-android.hardware.radio.deprecated.V1_0.IOemHookIndication
-android.hardware.radio.deprecated.V1_0.IOemHookIndication$Stub
-android.hardware.radio.deprecated.V1_0.IOemHookResponse
-android.hardware.radio.deprecated.V1_0.IOemHookResponse$Stub
-android.hardware.soundtrigger.IRecognitionStatusCallback
-android.hardware.soundtrigger.IRecognitionStatusCallback$Stub
-android.hardware.soundtrigger.KeyphraseEnrollmentInfo
-android.hardware.soundtrigger.KeyphraseMetadata
-android.hardware.soundtrigger.SoundTrigger
-android.hardware.soundtrigger.SoundTrigger$ConfidenceLevel
-android.hardware.soundtrigger.SoundTrigger$ConfidenceLevel$1
-android.hardware.soundtrigger.SoundTrigger$GenericRecognitionEvent
-android.hardware.soundtrigger.SoundTrigger$GenericRecognitionEvent$1
-android.hardware.soundtrigger.SoundTrigger$GenericSoundModel
-android.hardware.soundtrigger.SoundTrigger$Keyphrase
-android.hardware.soundtrigger.SoundTrigger$Keyphrase$1
-android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionEvent
-android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionEvent$1
-android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionExtra
-android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionExtra$1
-android.hardware.soundtrigger.SoundTrigger$KeyphraseSoundModel
-android.hardware.soundtrigger.SoundTrigger$KeyphraseSoundModel$1
-android.hardware.soundtrigger.SoundTrigger$ModuleProperties
-android.hardware.soundtrigger.SoundTrigger$ModuleProperties$1
-android.hardware.soundtrigger.SoundTrigger$RecognitionConfig
-android.hardware.soundtrigger.SoundTrigger$RecognitionConfig$1
-android.hardware.soundtrigger.SoundTrigger$RecognitionEvent
-android.hardware.soundtrigger.SoundTrigger$RecognitionEvent$1
-android.hardware.soundtrigger.SoundTrigger$SoundModel
-android.hardware.soundtrigger.SoundTrigger$SoundModelEvent
-android.hardware.soundtrigger.SoundTrigger$SoundModelEvent$1
-android.hardware.soundtrigger.SoundTrigger$StatusListener
-android.hardware.soundtrigger.SoundTriggerModule
-android.hardware.usb.IUsbManager
-android.hardware.usb.IUsbManager$Stub
-android.hardware.usb.IUsbManager$Stub$Proxy
-android.hardware.usb.UsbAccessory
-android.hardware.usb.UsbDevice
-android.hardware.usb.UsbDeviceConnection
-android.hardware.usb.UsbManager
-android.hardware.usb.UsbPort
-android.hardware.usb.UsbPort$1
-android.hardware.usb.UsbPortStatus
-android.hardware.usb.UsbPortStatus$1
-android.hardware.usb.UsbRequest
-android.hidl.base.V1_0.DebugInfo
-android.hidl.base.V1_0.IBase
-android.hidl.manager.V1_0.IServiceManager
-android.hidl.manager.V1_0.IServiceManager$Proxy
-android.hidl.manager.V1_0.IServiceNotification
-android.hidl.manager.V1_0.IServiceNotification$Stub
-android.icu.impl.BMPSet
-android.icu.impl.CacheBase
-android.icu.impl.CacheValue
-android.icu.impl.CacheValue$NullValue
-android.icu.impl.CacheValue$SoftValue
-android.icu.impl.CacheValue$Strength
-android.icu.impl.CalendarUtil
-android.icu.impl.CalendarUtil$CalendarPreferences
-android.icu.impl.CaseMapImpl
-android.icu.impl.CaseMapImpl$GreekUpper
-android.icu.impl.CaseMapImpl$StringContextIterator
-android.icu.impl.CharTrie
-android.icu.impl.CharacterIteration
-android.icu.impl.ClassLoaderUtil
-android.icu.impl.CurrencyData
-android.icu.impl.CurrencyData$CurrencyDisplayInfo
-android.icu.impl.CurrencyData$CurrencyDisplayInfoProvider
-android.icu.impl.CurrencyData$CurrencySpacingInfo
-android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingPattern
-android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingType
-android.icu.impl.DateNumberFormat
-android.icu.impl.DontCareFieldPosition
-android.icu.impl.Grego
-android.icu.impl.ICUBinary
-android.icu.impl.ICUBinary$Authenticate
-android.icu.impl.ICUBinary$DatPackageReader
-android.icu.impl.ICUBinary$DatPackageReader$IsAcceptable
-android.icu.impl.ICUBinary$DataFile
-android.icu.impl.ICUBinary$PackageDataFile
-android.icu.impl.ICUCache
-android.icu.impl.ICUConfig
-android.icu.impl.ICUCurrencyDisplayInfoProvider
-android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo
-android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo$SpacingInfoSink
-android.icu.impl.ICUCurrencyMetaInfo
-android.icu.impl.ICUCurrencyMetaInfo$Collector
-android.icu.impl.ICUCurrencyMetaInfo$CurrencyCollector
-android.icu.impl.ICUCurrencyMetaInfo$UniqueList
-android.icu.impl.ICUData
-android.icu.impl.ICUDebug
-android.icu.impl.ICULangDataTables
-android.icu.impl.ICULocaleService
-android.icu.impl.ICULocaleService$ICUResourceBundleFactory
-android.icu.impl.ICULocaleService$LocaleKey
-android.icu.impl.ICULocaleService$LocaleKeyFactory
-android.icu.impl.ICUNotifier
-android.icu.impl.ICURWLock
-android.icu.impl.ICURegionDataTables
-android.icu.impl.ICUResourceBundle
-android.icu.impl.ICUResourceBundle$1
-android.icu.impl.ICUResourceBundle$2
-android.icu.impl.ICUResourceBundle$3
-android.icu.impl.ICUResourceBundle$3$1
-android.icu.impl.ICUResourceBundle$4
-android.icu.impl.ICUResourceBundle$AvailEntry
-android.icu.impl.ICUResourceBundle$Loader
-android.icu.impl.ICUResourceBundle$OpenType
-android.icu.impl.ICUResourceBundle$WholeBundle
-android.icu.impl.ICUResourceBundleImpl
-android.icu.impl.ICUResourceBundleImpl$ResourceArray
-android.icu.impl.ICUResourceBundleImpl$ResourceBinary
-android.icu.impl.ICUResourceBundleImpl$ResourceContainer
-android.icu.impl.ICUResourceBundleImpl$ResourceInt
-android.icu.impl.ICUResourceBundleImpl$ResourceIntVector
-android.icu.impl.ICUResourceBundleImpl$ResourceString
-android.icu.impl.ICUResourceBundleImpl$ResourceTable
-android.icu.impl.ICUResourceBundleReader
-android.icu.impl.ICUResourceBundleReader$Array
-android.icu.impl.ICUResourceBundleReader$Array16
-android.icu.impl.ICUResourceBundleReader$Array32
-android.icu.impl.ICUResourceBundleReader$Container
-android.icu.impl.ICUResourceBundleReader$IsAcceptable
-android.icu.impl.ICUResourceBundleReader$ReaderCache
-android.icu.impl.ICUResourceBundleReader$ReaderCacheKey
-android.icu.impl.ICUResourceBundleReader$ReaderValue
-android.icu.impl.ICUResourceBundleReader$ResourceCache
-android.icu.impl.ICUResourceBundleReader$ResourceCache$Level
-android.icu.impl.ICUResourceBundleReader$Table
-android.icu.impl.ICUResourceBundleReader$Table16
-android.icu.impl.ICUResourceBundleReader$Table1632
-android.icu.impl.ICUResourceTableAccess
-android.icu.impl.ICUService
-android.icu.impl.ICUService$CacheEntry
-android.icu.impl.ICUService$Factory
-android.icu.impl.ICUService$Key
-android.icu.impl.IDNA2003
-android.icu.impl.JavaTimeZone
-android.icu.impl.LocaleDisplayNamesImpl
-android.icu.impl.LocaleDisplayNamesImpl$Cache
-android.icu.impl.LocaleDisplayNamesImpl$CapitalizationContextUsage
-android.icu.impl.LocaleDisplayNamesImpl$DataTable
-android.icu.impl.LocaleDisplayNamesImpl$DataTables
-android.icu.impl.LocaleDisplayNamesImpl$ICUDataTable
-android.icu.impl.LocaleDisplayNamesImpl$ICUDataTables
-android.icu.impl.LocaleDisplayNamesImpl$LangDataTables
-android.icu.impl.LocaleDisplayNamesImpl$RegionDataTables
-android.icu.impl.LocaleIDParser
-android.icu.impl.LocaleIDs
-android.icu.impl.Norm2AllModes
-android.icu.impl.Norm2AllModes$1
-android.icu.impl.Norm2AllModes$ComposeNormalizer2
-android.icu.impl.Norm2AllModes$DecomposeNormalizer2
-android.icu.impl.Norm2AllModes$FCDNormalizer2
-android.icu.impl.Norm2AllModes$NFCSingleton
-android.icu.impl.Norm2AllModes$NFKCSingleton
-android.icu.impl.Norm2AllModes$NoopNormalizer2
-android.icu.impl.Norm2AllModes$Norm2AllModesSingleton
-android.icu.impl.Norm2AllModes$Normalizer2WithImpl
-android.icu.impl.Normalizer2Impl
-android.icu.impl.Normalizer2Impl$1
-android.icu.impl.Normalizer2Impl$IsAcceptable
-android.icu.impl.Normalizer2Impl$ReorderingBuffer
-android.icu.impl.OlsonTimeZone
-android.icu.impl.Pair
-android.icu.impl.PatternProps
-android.icu.impl.PatternTokenizer
-android.icu.impl.PluralRulesLoader
-android.icu.impl.ReplaceableUCharacterIterator
-android.icu.impl.RuleCharacterIterator
-android.icu.impl.SimpleCache
-android.icu.impl.SimpleFormatterImpl
-android.icu.impl.SoftCache
-android.icu.impl.StandardPlural
-android.icu.impl.StringPrepDataReader
-android.icu.impl.Trie
-android.icu.impl.Trie$DataManipulate
-android.icu.impl.Trie$DefaultGetFoldingOffset
-android.icu.impl.Trie2
-android.icu.impl.Trie2$1
-android.icu.impl.Trie2$Range
-android.icu.impl.Trie2$Trie2Iterator
-android.icu.impl.Trie2$UTrie2Header
-android.icu.impl.Trie2$ValueMapper
-android.icu.impl.Trie2$ValueWidth
-android.icu.impl.Trie2_16
-android.icu.impl.Trie2_32
-android.icu.impl.UBiDiProps
-android.icu.impl.UBiDiProps$IsAcceptable
-android.icu.impl.UCaseProps
-android.icu.impl.UCaseProps$ContextIterator
-android.icu.impl.UCaseProps$IsAcceptable
-android.icu.impl.UCharacterProperty
-android.icu.impl.UCharacterProperty$1
-android.icu.impl.UCharacterProperty$10
-android.icu.impl.UCharacterProperty$11
-android.icu.impl.UCharacterProperty$12
-android.icu.impl.UCharacterProperty$13
-android.icu.impl.UCharacterProperty$14
-android.icu.impl.UCharacterProperty$15
-android.icu.impl.UCharacterProperty$16
-android.icu.impl.UCharacterProperty$17
-android.icu.impl.UCharacterProperty$18
-android.icu.impl.UCharacterProperty$19
-android.icu.impl.UCharacterProperty$2
-android.icu.impl.UCharacterProperty$20
-android.icu.impl.UCharacterProperty$21
-android.icu.impl.UCharacterProperty$22
-android.icu.impl.UCharacterProperty$23
-android.icu.impl.UCharacterProperty$3
-android.icu.impl.UCharacterProperty$4
-android.icu.impl.UCharacterProperty$5
-android.icu.impl.UCharacterProperty$6
-android.icu.impl.UCharacterProperty$7
-android.icu.impl.UCharacterProperty$8
-android.icu.impl.UCharacterProperty$9
-android.icu.impl.UCharacterProperty$BiDiIntProperty
-android.icu.impl.UCharacterProperty$BinaryProperty
-android.icu.impl.UCharacterProperty$CaseBinaryProperty
-android.icu.impl.UCharacterProperty$CombiningClassIntProperty
-android.icu.impl.UCharacterProperty$IntProperty
-android.icu.impl.UCharacterProperty$IsAcceptable
-android.icu.impl.UCharacterProperty$NormInertBinaryProperty
-android.icu.impl.UCharacterProperty$NormQuickCheckIntProperty
-android.icu.impl.UPropertyAliases
-android.icu.impl.UPropertyAliases$IsAcceptable
-android.icu.impl.URLHandler$URLVisitor
-android.icu.impl.UResource$Array
-android.icu.impl.UResource$Key
-android.icu.impl.UResource$Sink
-android.icu.impl.UResource$Table
-android.icu.impl.UResource$Value
-android.icu.impl.USerializedSet
-android.icu.impl.Utility
-android.icu.impl.ZoneMeta
-android.icu.impl.ZoneMeta$CustomTimeZoneCache
-android.icu.impl.ZoneMeta$SystemTimeZoneCache
-android.icu.impl.coll.Collation
-android.icu.impl.coll.CollationCompare
-android.icu.impl.coll.CollationData
-android.icu.impl.coll.CollationDataReader
-android.icu.impl.coll.CollationDataReader$IsAcceptable
-android.icu.impl.coll.CollationFCD
-android.icu.impl.coll.CollationFastLatin
-android.icu.impl.coll.CollationIterator
-android.icu.impl.coll.CollationIterator$CEBuffer
-android.icu.impl.coll.CollationKeys
-android.icu.impl.coll.CollationKeys$LevelCallback
-android.icu.impl.coll.CollationKeys$SortKeyByteSink
-android.icu.impl.coll.CollationLoader
-android.icu.impl.coll.CollationRoot
-android.icu.impl.coll.CollationSettings
-android.icu.impl.coll.CollationTailoring
-android.icu.impl.coll.ContractionsAndExpansions
-android.icu.impl.coll.FCDUTF16CollationIterator
-android.icu.impl.coll.SharedObject
-android.icu.impl.coll.SharedObject$Reference
-android.icu.impl.coll.UTF16CollationIterator
-android.icu.impl.locale.AsciiUtil
-android.icu.impl.locale.BaseLocale
-android.icu.impl.locale.BaseLocale$Cache
-android.icu.impl.locale.BaseLocale$Key
-android.icu.impl.locale.LocaleObjectCache
-android.icu.impl.locale.LocaleObjectCache$CacheEntry
-android.icu.impl.locale.LocaleSyntaxException
-android.icu.lang.UCharacter
-android.icu.lang.UCharacterEnums$ECharacterCategory
-android.icu.lang.UCharacterEnums$ECharacterDirection
-android.icu.lang.UScript
-android.icu.lang.UScript$ScriptUsage
-android.icu.math.BigDecimal
-android.icu.math.MathContext
-android.icu.text.AlphabeticIndex
-android.icu.text.AlphabeticIndex$1
-android.icu.text.AlphabeticIndex$Bucket
-android.icu.text.AlphabeticIndex$Bucket$LabelType
-android.icu.text.AlphabeticIndex$BucketList
-android.icu.text.AlphabeticIndex$ImmutableIndex
-android.icu.text.Bidi
-android.icu.text.Bidi$ImpTabPair
-android.icu.text.BreakIterator
-android.icu.text.BreakIterator$BreakIteratorCache
-android.icu.text.BreakIterator$BreakIteratorServiceShim
-android.icu.text.BreakIteratorFactory
-android.icu.text.BreakIteratorFactory$BFService
-android.icu.text.BreakIteratorFactory$BFService$1RBBreakIteratorFactory
-android.icu.text.CaseMap
-android.icu.text.CaseMap$Upper
-android.icu.text.CollationKey
-android.icu.text.Collator
-android.icu.text.Collator$ServiceShim
-android.icu.text.CollatorServiceShim
-android.icu.text.CollatorServiceShim$CService
-android.icu.text.CollatorServiceShim$CService$1CollatorFactory
-android.icu.text.CurrencyDisplayNames
-android.icu.text.CurrencyMetaInfo
-android.icu.text.CurrencyMetaInfo$CurrencyDigits
-android.icu.text.CurrencyMetaInfo$CurrencyFilter
-android.icu.text.CurrencyPluralInfo
-android.icu.text.DateFormat
-android.icu.text.DateFormat$BooleanAttribute
-android.icu.text.DateFormat$Field
-android.icu.text.DateFormatSymbols
-android.icu.text.DateFormatSymbols$1
-android.icu.text.DateFormatSymbols$CalendarDataSink
-android.icu.text.DateFormatSymbols$CalendarDataSink$AliasType
-android.icu.text.DateFormatSymbols$CapitalizationContextUsage
-android.icu.text.DateIntervalFormat
-android.icu.text.DateIntervalFormat$BestMatchInfo
-android.icu.text.DateIntervalFormat$SkeletonAndItsBestMatch
-android.icu.text.DateIntervalInfo
-android.icu.text.DateIntervalInfo$DateIntervalSink
-android.icu.text.DateIntervalInfo$PatternInfo
-android.icu.text.DateTimePatternGenerator
-android.icu.text.DateTimePatternGenerator$AppendItemFormatsSink
-android.icu.text.DateTimePatternGenerator$AppendItemNamesSink
-android.icu.text.DateTimePatternGenerator$AvailableFormatsSink
-android.icu.text.DateTimePatternGenerator$DTPGflags
-android.icu.text.DateTimePatternGenerator$DateTimeMatcher
-android.icu.text.DateTimePatternGenerator$DayPeriodAllowedHoursSink
-android.icu.text.DateTimePatternGenerator$DistanceInfo
-android.icu.text.DateTimePatternGenerator$FormatParser
-android.icu.text.DateTimePatternGenerator$PatternInfo
-android.icu.text.DateTimePatternGenerator$PatternWithMatcher
-android.icu.text.DateTimePatternGenerator$PatternWithSkeletonFlag
-android.icu.text.DateTimePatternGenerator$SkeletonFields
-android.icu.text.DateTimePatternGenerator$VariableField
-android.icu.text.DecimalFormat
-android.icu.text.DecimalFormat$Unit
-android.icu.text.DecimalFormatSymbols
-android.icu.text.DecimalFormatSymbols$1
-android.icu.text.DecimalFormatSymbols$CacheData
-android.icu.text.DecimalFormatSymbols$DecFmtDataSink
-android.icu.text.DigitList
-android.icu.text.DisplayContext
-android.icu.text.DisplayContext$Type
-android.icu.text.Edits
-android.icu.text.IDNA
-android.icu.text.LanguageBreakEngine
-android.icu.text.ListFormatter$Style
-android.icu.text.LocaleDisplayNames
-android.icu.text.LocaleDisplayNames$DialectHandling
-android.icu.text.MeasureFormat
-android.icu.text.MeasureFormat$FormatWidth
-android.icu.text.MeasureFormat$ImmutableNumberFormat
-android.icu.text.MeasureFormat$MeasureFormatData
-android.icu.text.MeasureFormat$UnitDataSink
-android.icu.text.Normalizer
-android.icu.text.Normalizer$FCDMode
-android.icu.text.Normalizer$Mode
-android.icu.text.Normalizer$ModeImpl
-android.icu.text.Normalizer$NFCMode
-android.icu.text.Normalizer$NFCModeImpl
-android.icu.text.Normalizer$NFDMode
-android.icu.text.Normalizer$NFKCMode
-android.icu.text.Normalizer$NFKDMode
-android.icu.text.Normalizer$NFKDModeImpl
-android.icu.text.Normalizer$NONEMode
-android.icu.text.Normalizer$QuickCheckResult
-android.icu.text.Normalizer2
-android.icu.text.NumberFormat
-android.icu.text.NumberFormat$Field
-android.icu.text.NumberFormat$NumberFormatShim
-android.icu.text.NumberFormatServiceShim
-android.icu.text.NumberFormatServiceShim$NFService
-android.icu.text.NumberFormatServiceShim$NFService$1RBNumberFormatFactory
-android.icu.text.NumberingSystem
-android.icu.text.NumberingSystem$1
-android.icu.text.NumberingSystem$2
-android.icu.text.NumberingSystem$LocaleLookupData
-android.icu.text.PluralRanges
-android.icu.text.PluralRanges$Matrix
-android.icu.text.PluralRules
-android.icu.text.PluralRules$1
-android.icu.text.PluralRules$AndConstraint
-android.icu.text.PluralRules$BinaryConstraint
-android.icu.text.PluralRules$Constraint
-android.icu.text.PluralRules$Factory
-android.icu.text.PluralRules$FixedDecimal
-android.icu.text.PluralRules$FixedDecimalRange
-android.icu.text.PluralRules$FixedDecimalSamples
-android.icu.text.PluralRules$Operand
-android.icu.text.PluralRules$PluralType
-android.icu.text.PluralRules$RangeConstraint
-android.icu.text.PluralRules$Rule
-android.icu.text.PluralRules$RuleList
-android.icu.text.PluralRules$SampleType
-android.icu.text.PluralRules$SimpleTokenizer
-android.icu.text.QuantityFormatter
-android.icu.text.RBBIDataWrapper
-android.icu.text.RBBIDataWrapper$IsAcceptable
-android.icu.text.RBBIDataWrapper$RBBIDataHeader
-android.icu.text.RBBIDataWrapper$TrieFoldingFunc
-android.icu.text.RawCollationKey
-android.icu.text.RelativeDateTimeFormatter
-android.icu.text.RelativeDateTimeFormatter$AbsoluteUnit
-android.icu.text.RelativeDateTimeFormatter$Cache
-android.icu.text.RelativeDateTimeFormatter$Cache$1
-android.icu.text.RelativeDateTimeFormatter$Direction
-android.icu.text.RelativeDateTimeFormatter$Loader
-android.icu.text.RelativeDateTimeFormatter$RelDateTimeDataSink
-android.icu.text.RelativeDateTimeFormatter$RelDateTimeDataSink$DateTimeUnit
-android.icu.text.RelativeDateTimeFormatter$RelativeDateTimeFormatterData
-android.icu.text.RelativeDateTimeFormatter$RelativeUnit
-android.icu.text.RelativeDateTimeFormatter$Style
-android.icu.text.Replaceable
-android.icu.text.ReplaceableString
-android.icu.text.RuleBasedBreakIterator
-android.icu.text.RuleBasedBreakIterator$LookAheadResults
-android.icu.text.RuleBasedCollator
-android.icu.text.RuleBasedCollator$CollationBuffer
-android.icu.text.RuleBasedCollator$CollationKeyByteSink
-android.icu.text.RuleBasedCollator$FCDUTF16NFDIterator
-android.icu.text.RuleBasedCollator$NFDIterator
-android.icu.text.RuleBasedCollator$UTF16NFDIterator
-android.icu.text.SimpleDateFormat
-android.icu.text.SimpleDateFormat$PatternItem
-android.icu.text.StringPrep
-android.icu.text.StringPrepParseException
-android.icu.text.TimeZoneNames$NameType
-android.icu.text.UCharacterIterator
-android.icu.text.UFieldPosition
-android.icu.text.UFormat
-android.icu.text.UForwardCharacterIterator
-android.icu.text.UTF16
-android.icu.text.UTF16$StringComparator
-android.icu.text.UnhandledBreakEngine
-android.icu.text.UnicodeFilter
-android.icu.text.UnicodeMatcher
-android.icu.text.UnicodeSet
-android.icu.text.UnicodeSet$Filter
-android.icu.text.UnicodeSet$GeneralCategoryMaskFilter
-android.icu.text.UnicodeSet$IntPropertyFilter
-android.icu.text.UnicodeSet$UnicodeSetIterator2
-android.icu.util.BasicTimeZone
-android.icu.util.ByteArrayWrapper
-android.icu.util.BytesTrie
-android.icu.util.BytesTrie$Result
-android.icu.util.Calendar
-android.icu.util.Calendar$CalType
-android.icu.util.Calendar$FormatConfiguration
-android.icu.util.Calendar$PatternData
-android.icu.util.Calendar$WeekData
-android.icu.util.Calendar$WeekDataCache
-android.icu.util.CharsTrie
-android.icu.util.CharsTrie$Entry
-android.icu.util.CharsTrie$Iterator
-android.icu.util.Currency
-android.icu.util.Currency$1
-android.icu.util.Currency$CurrencyUsage
-android.icu.util.Currency$EquivalenceRelation
-android.icu.util.CurrencyAmount
-android.icu.util.Freezable
-android.icu.util.GregorianCalendar
-android.icu.util.ICUException
-android.icu.util.ICUUncheckedIOException
-android.icu.util.LocaleData
-android.icu.util.Measure
-android.icu.util.MeasureUnit
-android.icu.util.MeasureUnit$1
-android.icu.util.MeasureUnit$2
-android.icu.util.MeasureUnit$3
-android.icu.util.MeasureUnit$Factory
-android.icu.util.Output
-android.icu.util.SimpleTimeZone
-android.icu.util.TimeUnit
-android.icu.util.TimeZone
-android.icu.util.TimeZone$ConstantZone
-android.icu.util.ULocale
-android.icu.util.ULocale$1
-android.icu.util.ULocale$2
-android.icu.util.ULocale$Category
-android.icu.util.ULocale$JDKLocaleHelper
-android.icu.util.ULocale$Type
-android.icu.util.UResourceBundle
-android.icu.util.UResourceBundle$RootType
-android.icu.util.UResourceBundleIterator
-android.icu.util.UResourceTypeMismatchException
-android.icu.util.VersionInfo
-android.inputmethodservice.AbstractInputMethodService
-android.inputmethodservice.AbstractInputMethodService$AbstractInputMethodImpl
-android.inputmethodservice.AbstractInputMethodService$AbstractInputMethodSessionImpl
-android.inputmethodservice.IInputMethodSessionWrapper
-android.inputmethodservice.IInputMethodSessionWrapper$ImeInputEventReceiver
-android.inputmethodservice.IInputMethodWrapper
-android.inputmethodservice.IInputMethodWrapper$InputMethodSessionCallbackWrapper
-android.inputmethodservice.InputMethodService
-android.inputmethodservice.InputMethodService$1
-android.inputmethodservice.InputMethodService$2
-android.inputmethodservice.InputMethodService$InputMethodImpl
-android.inputmethodservice.InputMethodService$InputMethodSessionImpl
-android.inputmethodservice.InputMethodService$Insets
-android.inputmethodservice.InputMethodService$SettingsObserver
-android.inputmethodservice.SoftInputWindow
-android.location.Address
-android.location.Address$1
-android.location.BatchedLocationCallbackTransport
-android.location.BatchedLocationCallbackTransport$CallbackTransport
-android.location.Country
-android.location.Country$1
-android.location.CountryDetector
-android.location.CountryDetector$ListenerTransport
-android.location.CountryDetector$ListenerTransport$1
-android.location.CountryListener
-android.location.Criteria
-android.location.Criteria$1
-android.location.Geocoder
-android.location.GeocoderParams
-android.location.GeocoderParams$1
-android.location.Geofence
-android.location.GnssMeasurementCallbackTransport
-android.location.GnssMeasurementCallbackTransport$ListenerTransport
-android.location.GnssNavigationMessageCallbackTransport
-android.location.GnssNavigationMessageCallbackTransport$ListenerTransport
-android.location.GnssStatus
-android.location.GnssStatus$Callback
-android.location.GpsSatellite
-android.location.GpsStatus
-android.location.GpsStatus$1
-android.location.GpsStatus$Listener
-android.location.GpsStatus$SatelliteIterator
-android.location.IBatchedLocationCallback
-android.location.IBatchedLocationCallback$Stub
-android.location.ICountryDetector
-android.location.ICountryDetector$Stub
-android.location.ICountryDetector$Stub$Proxy
-android.location.ICountryListener
-android.location.ICountryListener$Stub
-android.location.ICountryListener$Stub$Proxy
-android.location.IFusedProvider
-android.location.IFusedProvider$Stub
-android.location.IGeocodeProvider
-android.location.IGeocodeProvider$Stub
-android.location.IGeocodeProvider$Stub$Proxy
-android.location.IGeofenceProvider
-android.location.IGeofenceProvider$Stub
-android.location.IGeofenceProvider$Stub$Proxy
-android.location.IGnssMeasurementsListener
-android.location.IGnssMeasurementsListener$Stub
-android.location.IGnssNavigationMessageListener
-android.location.IGnssNavigationMessageListener$Stub
-android.location.IGnssStatusListener
-android.location.IGnssStatusListener$Stub
-android.location.IGnssStatusListener$Stub$Proxy
-android.location.IGnssStatusProvider
-android.location.IGnssStatusProvider$Stub
-android.location.IGpsGeofenceHardware
-android.location.IGpsGeofenceHardware$Stub
-android.location.ILocationListener
-android.location.ILocationListener$Stub
-android.location.ILocationListener$Stub$Proxy
-android.location.ILocationManager
-android.location.ILocationManager$Stub
-android.location.ILocationManager$Stub$Proxy
-android.location.INetInitiatedListener
-android.location.INetInitiatedListener$Stub
-android.location.LocalListenerHelper
-android.location.Location
-android.location.Location$1
-android.location.Location$2
-android.location.Location$BearingDistanceCache
-android.location.LocationListener
-android.location.LocationManager
-android.location.LocationManager$GnssStatusListenerTransport
-android.location.LocationManager$GnssStatusListenerTransport$1
-android.location.LocationManager$GnssStatusListenerTransport$GnssHandler
-android.location.LocationManager$ListenerTransport
-android.location.LocationManager$ListenerTransport$1
-android.location.LocationManager$ListenerTransport$2
-android.location.LocationProvider
-android.location.LocationRequest
-android.location.LocationRequest$1
-android.media.AudioAttributes
-android.media.AudioAttributes$1
-android.media.AudioAttributes$Builder
-android.media.AudioDeviceCallback
-android.media.AudioDeviceInfo
-android.media.AudioDevicePort
-android.media.AudioDevicePortConfig
-android.media.AudioFocusInfo
-android.media.AudioFocusInfo$1
-android.media.AudioFocusRequest
-android.media.AudioFocusRequest$Builder
-android.media.AudioFormat
-android.media.AudioFormat$1
-android.media.AudioFormat$Builder
-android.media.AudioGain
-android.media.AudioGainConfig
-android.media.AudioHandle
-android.media.AudioManager
-android.media.AudioManager$1
-android.media.AudioManager$2
-android.media.AudioManager$3
-android.media.AudioManager$FocusRequestInfo
-android.media.AudioManager$NativeEventHandlerDelegate
-android.media.AudioManager$NativeEventHandlerDelegate$1
-android.media.AudioManager$OnAmPortUpdateListener
-android.media.AudioManager$OnAudioFocusChangeListener
-android.media.AudioManager$OnAudioPortUpdateListener
-android.media.AudioManager$ServiceEventHandlerDelegate
-android.media.AudioManager$ServiceEventHandlerDelegate$1
-android.media.AudioManagerInternal
-android.media.AudioManagerInternal$RingerModeDelegate
-android.media.AudioMixPort
-android.media.AudioMixPortConfig
-android.media.AudioPatch
-android.media.AudioPlaybackConfiguration
-android.media.AudioPlaybackConfiguration$1
-android.media.AudioPlaybackConfiguration$IPlayerShell
-android.media.AudioPlaybackConfiguration$PlayerDeathMonitor
-android.media.AudioPort
-android.media.AudioPortConfig
-android.media.AudioPortEventHandler
-android.media.AudioPortEventHandler$1
-android.media.AudioRecord
-android.media.AudioRoutesInfo
-android.media.AudioRoutesInfo$1
-android.media.AudioRouting
-android.media.AudioSystem
-android.media.AudioSystem$AudioRecordingCallback
-android.media.AudioSystem$DynamicPolicyCallback
-android.media.AudioSystem$ErrorCallback
-android.media.AudioTimestamp
-android.media.AudioTrack
-android.media.BufferingParams
-android.media.BufferingParams$1
-android.media.CamcorderProfile
-android.media.CameraProfile
-android.media.DecoderCapabilities
-android.media.DeniedByServerException
-android.media.EncoderCapabilities
-android.media.ExifInterface
-android.media.ExifInterface$ByteOrderedDataInputStream
-android.media.ExifInterface$ExifAttribute
-android.media.ExifInterface$ExifTag
-android.media.IAudioFocusDispatcher
-android.media.IAudioFocusDispatcher$Stub
-android.media.IAudioFocusDispatcher$Stub$Proxy
-android.media.IAudioRoutesObserver
-android.media.IAudioRoutesObserver$Stub
-android.media.IAudioRoutesObserver$Stub$Proxy
-android.media.IAudioService
-android.media.IAudioService$Stub
-android.media.IAudioService$Stub$Proxy
-android.media.IMediaHTTPConnection
-android.media.IMediaHTTPConnection$Stub
-android.media.IMediaHTTPService
-android.media.IMediaHTTPService$Stub
-android.media.IMediaResourceMonitor
-android.media.IMediaResourceMonitor$Stub
-android.media.IMediaRouterClient
-android.media.IMediaRouterClient$Stub
-android.media.IMediaRouterClient$Stub$Proxy
-android.media.IMediaRouterService
-android.media.IMediaRouterService$Stub
-android.media.IMediaRouterService$Stub$Proxy
-android.media.IPlaybackConfigDispatcher
-android.media.IPlaybackConfigDispatcher$Stub
-android.media.IPlayer
-android.media.IPlayer$Stub
-android.media.IPlayer$Stub$Proxy
-android.media.IRecordingConfigDispatcher
-android.media.IRecordingConfigDispatcher$Stub
-android.media.IRemoteVolumeController
-android.media.IRemoteVolumeController$Stub
-android.media.IRemoteVolumeController$Stub$Proxy
-android.media.IRemoteVolumeObserver
-android.media.IRemoteVolumeObserver$Stub
-android.media.IRingtonePlayer
-android.media.IRingtonePlayer$Stub
-android.media.IRingtonePlayer$Stub$Proxy
-android.media.IVolumeController
-android.media.IVolumeController$Stub
-android.media.IVolumeController$Stub$Proxy
-android.media.Image
-android.media.Image$Plane
-android.media.ImageReader
-android.media.ImageReader$ListenerHandler
-android.media.ImageReader$OnImageAvailableListener
-android.media.ImageReader$SurfaceImage
-android.media.ImageReader$SurfaceImage$SurfacePlane
-android.media.ImageUtils
-android.media.ImageWriter
-android.media.ImageWriter$ListenerHandler
-android.media.ImageWriter$OnImageReleasedListener
-android.media.ImageWriter$WriterSurfaceImage
-android.media.ImageWriter$WriterSurfaceImage$SurfacePlane
-android.media.JetPlayer
-android.media.MediaCodec
-android.media.MediaCodec$BufferInfo
-android.media.MediaCodec$BufferMap
-android.media.MediaCodec$BufferMap$CodecBuffer
-android.media.MediaCodec$CodecException
-android.media.MediaCodec$CryptoException
-android.media.MediaCodec$CryptoInfo
-android.media.MediaCodec$CryptoInfo$Pattern
-android.media.MediaCodec$EventHandler
-android.media.MediaCodec$PersistentSurface
-android.media.MediaCodecInfo
-android.media.MediaCodecInfo$AudioCapabilities
-android.media.MediaCodecInfo$CodecCapabilities
-android.media.MediaCodecInfo$CodecProfileLevel
-android.media.MediaCodecInfo$EncoderCapabilities
-android.media.MediaCodecInfo$Feature
-android.media.MediaCodecInfo$VideoCapabilities
-android.media.MediaCodecList
-android.media.MediaCrypto
-android.media.MediaCryptoException
-android.media.MediaDescrambler
-android.media.MediaDescription
-android.media.MediaDescription$1
-android.media.MediaDescription$Builder
-android.media.MediaDrm
-android.media.MediaDrm$Certificate
-android.media.MediaDrm$EventHandler
-android.media.MediaDrm$KeyRequest
-android.media.MediaDrm$MediaDrmStateException
-android.media.MediaDrm$OnEventListener
-android.media.MediaDrm$ProvisionRequest
-android.media.MediaDrmException
-android.media.MediaExtractor
-android.media.MediaFile
-android.media.MediaFile$MediaFileType
-android.media.MediaFormat
-android.media.MediaHTTPConnection
-android.media.MediaHTTPService
-android.media.MediaMetadata
-android.media.MediaMetadata$1
-android.media.MediaMetadata$Builder
-android.media.MediaMetadataRetriever
-android.media.MediaMuxer
-android.media.MediaPlayer
-android.media.MediaPlayer$1
-android.media.MediaPlayer$2
-android.media.MediaPlayer$4
-android.media.MediaPlayer$4$1
-android.media.MediaPlayer$EventHandler
-android.media.MediaPlayer$OnCompletionListener
-android.media.MediaPlayer$OnErrorListener
-android.media.MediaPlayer$OnInfoListener
-android.media.MediaPlayer$OnPreparedListener
-android.media.MediaPlayer$OnSeekCompleteListener
-android.media.MediaPlayer$OnSubtitleDataListener
-android.media.MediaPlayer$TimeProvider
-android.media.MediaPlayer$TimeProvider$EventHandler
-android.media.MediaPlayer$TrackInfo
-android.media.MediaPlayer$TrackInfo$1
-android.media.MediaRecorder
-android.media.MediaRecorder$EventHandler
-android.media.MediaRecorder$OnErrorListener
-android.media.MediaRouter
-android.media.MediaRouter$Callback
-android.media.MediaRouter$CallbackInfo
-android.media.MediaRouter$RouteCategory
-android.media.MediaRouter$RouteGroup
-android.media.MediaRouter$RouteInfo
-android.media.MediaRouter$RouteInfo$1
-android.media.MediaRouter$SimpleCallback
-android.media.MediaRouter$Static
-android.media.MediaRouter$Static$1
-android.media.MediaRouter$Static$Client
-android.media.MediaRouter$Static$Client$1
-android.media.MediaRouter$VolumeCallback
-android.media.MediaRouter$VolumeChangeReceiver
-android.media.MediaRouter$WifiDisplayStatusChangedReceiver
-android.media.MediaRouterClientState
-android.media.MediaRouterClientState$1
-android.media.MediaRouterClientState$RouteInfo
-android.media.MediaRouterClientState$RouteInfo$1
-android.media.MediaScanner
-android.media.MediaScannerConnection
-android.media.MediaScannerConnection$OnScanCompletedListener
-android.media.MediaSync
-android.media.MediaTimeProvider
-android.media.MediaTimeProvider$OnMediaTimeListener
-android.media.MiniThumbFile
-android.media.NotProvisionedException
-android.media.PlaybackParams
-android.media.PlaybackParams$1
-android.media.PlayerBase
-android.media.PlayerBase$IAppOpsCallbackWrapper
-android.media.PlayerBase$IPlayerWrapper
-android.media.PlayerBase$PlayerIdCard
-android.media.PlayerBase$PlayerIdCard$1
-android.media.PlayerProxy
-android.media.Rating
-android.media.Rating$1
-android.media.RemoteDisplay
-android.media.ResampleInputStream
-android.media.SoundPool
-android.media.SoundPool$Builder
-android.media.SoundPool$EventHandler
-android.media.SoundPool$OnLoadCompleteListener
-android.media.SubtitleController
-android.media.SubtitleController$1
-android.media.SubtitleController$2
-android.media.SubtitleController$Anchor
-android.media.SubtitleController$Listener
-android.media.SubtitleTrack
-android.media.SyncParams
-android.media.ThumbnailUtils
-android.media.ThumbnailUtils$SizedThumbnailBitmap
-android.media.ToneGenerator
-android.media.UnsupportedSchemeException
-android.media.Utils
-android.media.Utils$1
-android.media.Utils$2
-android.media.VolumeAutomation
-android.media.VolumePolicy
-android.media.VolumePolicy$1
-android.media.VolumeShaper
-android.media.VolumeShaper$Configuration
-android.media.VolumeShaper$Configuration$1
-android.media.VolumeShaper$Configuration$Builder
-android.media.VolumeShaper$Operation
-android.media.VolumeShaper$Operation$1
-android.media.VolumeShaper$Operation$Builder
-android.media.VolumeShaper$State
-android.media.VolumeShaper$State$1
-android.media.audiofx.AudioEffect
-android.media.audiofx.AudioEffect$Descriptor
-android.media.audiofx.LoudnessEnhancer
-android.media.audiofx.Virtualizer
-android.media.audiofx.Visualizer
-android.media.audiopolicy.AudioMix
-android.media.audiopolicy.AudioMixingRule
-android.media.audiopolicy.AudioMixingRule$AudioMixMatchCriterion
-android.media.audiopolicy.AudioPolicyConfig
-android.media.audiopolicy.IAudioPolicyCallback
-android.media.audiopolicy.IAudioPolicyCallback$Stub
-android.media.browse.MediaBrowser
-android.media.browse.MediaBrowser$1
-android.media.browse.MediaBrowser$2
-android.media.browse.MediaBrowser$6
-android.media.browse.MediaBrowser$ConnectionCallback
-android.media.browse.MediaBrowser$MediaServiceConnection
-android.media.browse.MediaBrowser$MediaServiceConnection$1
-android.media.browse.MediaBrowser$ServiceCallbacks
-android.media.midi.IMidiDeviceListener
-android.media.midi.IMidiDeviceOpenCallback
-android.media.midi.IMidiDeviceServer
-android.media.midi.IMidiManager
-android.media.midi.IMidiManager$Stub
-android.media.midi.MidiDeviceInfo
-android.media.midi.MidiDeviceStatus
-android.media.midi.MidiManager
-android.media.projection.IMediaProjection
-android.media.projection.IMediaProjectionManager
-android.media.projection.IMediaProjectionManager$Stub
-android.media.projection.IMediaProjectionManager$Stub$Proxy
-android.media.projection.IMediaProjectionWatcherCallback
-android.media.projection.IMediaProjectionWatcherCallback$Stub
-android.media.projection.IMediaProjectionWatcherCallback$Stub$Proxy
-android.media.projection.MediaProjectionInfo
-android.media.projection.MediaProjectionManager
-android.media.projection.MediaProjectionManager$Callback
-android.media.projection.MediaProjectionManager$CallbackDelegate
-android.media.session.IActiveSessionsListener
-android.media.session.IActiveSessionsListener$Stub
-android.media.session.IActiveSessionsListener$Stub$Proxy
-android.media.session.ICallback
-android.media.session.ICallback$Stub
-android.media.session.ICallback$Stub$Proxy
-android.media.session.IOnMediaKeyListener
-android.media.session.IOnVolumeKeyLongPressListener
-android.media.session.ISession
-android.media.session.ISession$Stub
-android.media.session.ISession$Stub$Proxy
-android.media.session.ISessionCallback
-android.media.session.ISessionCallback$Stub
-android.media.session.ISessionCallback$Stub$Proxy
-android.media.session.ISessionController
-android.media.session.ISessionController$Stub
-android.media.session.ISessionController$Stub$Proxy
-android.media.session.ISessionControllerCallback
-android.media.session.ISessionControllerCallback$Stub
-android.media.session.ISessionControllerCallback$Stub$Proxy
-android.media.session.ISessionManager
-android.media.session.ISessionManager$Stub
-android.media.session.ISessionManager$Stub$Proxy
-android.media.session.MediaController
-android.media.session.MediaController$Callback
-android.media.session.MediaController$CallbackStub
-android.media.session.MediaController$MessageHandler
-android.media.session.MediaController$PlaybackInfo
-android.media.session.MediaController$TransportControls
-android.media.session.MediaSession
-android.media.session.MediaSession$Callback
-android.media.session.MediaSession$CallbackMessageHandler
-android.media.session.MediaSession$CallbackStub
-android.media.session.MediaSession$QueueItem
-android.media.session.MediaSession$QueueItem$1
-android.media.session.MediaSession$Token
-android.media.session.MediaSession$Token$1
-android.media.session.MediaSessionManager
-android.media.session.MediaSessionManager$Callback
-android.media.session.MediaSessionManager$CallbackImpl
-android.media.session.MediaSessionManager$CallbackImpl$3
-android.media.session.MediaSessionManager$CallbackImpl$4
-android.media.session.MediaSessionManager$OnActiveSessionsChangedListener
-android.media.session.MediaSessionManager$SessionsChangedWrapper
-android.media.session.MediaSessionManager$SessionsChangedWrapper$1
-android.media.session.MediaSessionManager$SessionsChangedWrapper$1$1
-android.media.session.ParcelableVolumeInfo
-android.media.session.ParcelableVolumeInfo$1
-android.media.session.PlaybackState
-android.media.session.PlaybackState$1
-android.media.session.PlaybackState$Builder
-android.media.session.PlaybackState$CustomAction
-android.media.session.PlaybackState$CustomAction$1
-android.media.session.PlaybackState$CustomAction$Builder
-android.media.soundtrigger.SoundTriggerManager
-android.media.tv.TvInputHardwareInfo$Builder
-android.media.tv.TvInputManager
-android.media.tv.TvStreamConfig
-android.media.tv.TvStreamConfig$Builder
-android.metrics.LogMaker
-android.mtp.MtpDatabase
-android.mtp.MtpDevice
-android.mtp.MtpDeviceInfo
-android.mtp.MtpEvent
-android.mtp.MtpObjectInfo
-android.mtp.MtpPropertyGroup
-android.mtp.MtpPropertyList
-android.mtp.MtpServer
-android.mtp.MtpStorage
-android.mtp.MtpStorageInfo
-android.net.ConnectivityManager
-android.net.ConnectivityManager$CallbackHandler
-android.net.ConnectivityManager$NetworkCallback
-android.net.ConnectivityManager$OnNetworkActiveListener
-android.net.ConnectivityManager$PacketKeepaliveCallback
-android.net.ConnectivityMetricsEvent
-android.net.ConnectivityMetricsEvent$1
-android.net.ConnectivityThread
-android.net.ConnectivityThread$Singleton
-android.net.Credentials
-android.net.DataUsageRequest
-android.net.DhcpInfo
-android.net.DhcpInfo$1
-android.net.DhcpResults
-android.net.DhcpResults$1
-android.net.EthernetManager
-android.net.EthernetManager$1
-android.net.EthernetManager$2
-android.net.EventLogTags
-android.net.IConnectivityManager
-android.net.IConnectivityManager$Stub
-android.net.IConnectivityManager$Stub$Proxy
-android.net.IEthernetManager
-android.net.IEthernetManager$Stub
-android.net.IEthernetServiceListener
-android.net.IEthernetServiceListener$Stub
-android.net.IIpConnectivityMetrics
-android.net.IIpConnectivityMetrics$Stub
-android.net.IIpSecService
-android.net.IIpSecService$Stub
-android.net.INetd
-android.net.INetd$Stub
-android.net.INetd$Stub$Proxy
-android.net.INetdEventCallback
-android.net.INetworkManagementEventObserver
-android.net.INetworkManagementEventObserver$Stub
-android.net.INetworkPolicyListener
-android.net.INetworkPolicyListener$Stub
-android.net.INetworkPolicyListener$Stub$Proxy
-android.net.INetworkPolicyManager
-android.net.INetworkPolicyManager$Stub
-android.net.INetworkPolicyManager$Stub$Proxy
-android.net.INetworkRecommendationProvider
-android.net.INetworkRecommendationProvider$Stub
-android.net.INetworkRecommendationProvider$Stub$Proxy
-android.net.INetworkScoreCache
-android.net.INetworkScoreCache$Stub
-android.net.INetworkScoreCache$Stub$Proxy
-android.net.INetworkScoreService
-android.net.INetworkScoreService$Stub
-android.net.INetworkScoreService$Stub$Proxy
-android.net.INetworkStatsService
-android.net.INetworkStatsService$Stub
-android.net.INetworkStatsService$Stub$Proxy
-android.net.INetworkStatsSession
-android.net.InterfaceConfiguration
-android.net.InterfaceConfiguration$1
-android.net.IpConfiguration
-android.net.IpConfiguration$1
-android.net.IpConfiguration$IpAssignment
-android.net.IpConfiguration$ProxySettings
-android.net.IpPrefix
-android.net.IpPrefix$1
-android.net.IpSecConfig
-android.net.IpSecManager
-android.net.LinkAddress
-android.net.LinkAddress$1
-android.net.LinkProperties
-android.net.LinkProperties$1
-android.net.LinkProperties$CompareResult
-android.net.LinkProperties$ProvisioningChange
-android.net.LocalServerSocket
-android.net.LocalSocket
-android.net.LocalSocketAddress
-android.net.LocalSocketAddress$Namespace
-android.net.LocalSocketImpl
-android.net.LocalSocketImpl$SocketInputStream
-android.net.LocalSocketImpl$SocketOutputStream
-android.net.MatchAllNetworkSpecifier
-android.net.MatchAllNetworkSpecifier$1
-android.net.Network
-android.net.Network$1
-android.net.Network$2
-android.net.Network$NetworkBoundSocketFactory
-android.net.NetworkAgent
-android.net.NetworkCapabilities
-android.net.NetworkCapabilities$1
-android.net.NetworkConfig
-android.net.NetworkFactory
-android.net.NetworkFactory$NetworkRequestInfo
-android.net.NetworkIdentity
-android.net.NetworkInfo
-android.net.NetworkInfo$1
-android.net.NetworkInfo$DetailedState
-android.net.NetworkInfo$State
-android.net.NetworkKey
-android.net.NetworkKey$1
-android.net.NetworkMisc
-android.net.NetworkMisc$1
-android.net.NetworkPolicy
-android.net.NetworkPolicy$1
-android.net.NetworkPolicyManager
-android.net.NetworkQuotaInfo
-android.net.NetworkRecommendationProvider
-android.net.NetworkRecommendationProvider$ServiceWrapper
-android.net.NetworkRecommendationProvider$ServiceWrapper$1
-android.net.NetworkRequest
-android.net.NetworkRequest$1
-android.net.NetworkRequest$Builder
-android.net.NetworkRequest$Type
-android.net.NetworkScoreManager
-android.net.NetworkScorerAppData
-android.net.NetworkScorerAppData$1
-android.net.NetworkSpecifier
-android.net.NetworkState
-android.net.NetworkState$1
-android.net.NetworkStats
-android.net.NetworkStats$1
-android.net.NetworkStats$Entry
-android.net.NetworkStats$NonMonotonicObserver
-android.net.NetworkStatsHistory
-android.net.NetworkStatsHistory$1
-android.net.NetworkStatsHistory$DataStreamUtils
-android.net.NetworkStatsHistory$Entry
-android.net.NetworkTemplate
-android.net.NetworkTemplate$1
-android.net.NetworkUtils
-android.net.ParseException
-android.net.Proxy
-android.net.ProxyInfo
-android.net.ProxyInfo$1
-android.net.RouteInfo
-android.net.RouteInfo$1
-android.net.RssiCurve
-android.net.RssiCurve$1
-android.net.SSLCertificateSocketFactory
-android.net.SSLCertificateSocketFactory$1
-android.net.SSLSessionCache
-android.net.ScoredNetwork
-android.net.ScoredNetwork$1
-android.net.SntpClient
-android.net.StaticIpConfiguration
-android.net.StaticIpConfiguration$1
-android.net.StringNetworkSpecifier
-android.net.StringNetworkSpecifier$1
-android.net.TrafficStats
-android.net.UidRange
-android.net.Uri
-android.net.Uri$1
-android.net.Uri$AbstractHierarchicalUri
-android.net.Uri$AbstractPart
-android.net.Uri$Builder
-android.net.Uri$HierarchicalUri
-android.net.Uri$OpaqueUri
-android.net.Uri$Part
-android.net.Uri$Part$EmptyPart
-android.net.Uri$PathPart
-android.net.Uri$PathSegments
-android.net.Uri$PathSegmentsBuilder
-android.net.Uri$StringUri
-android.net.WebAddress
-android.net.WifiKey
-android.net.WifiKey$1
-android.net.http.AndroidHttpClient
-android.net.http.AndroidHttpClient$1
-android.net.http.AndroidHttpClient$2
-android.net.http.AndroidHttpClient$CurlLogger
-android.net.http.AndroidHttpClient$LoggingConfiguration
-android.net.http.HttpResponseCache
-android.net.http.SslCertificate
-android.net.http.X509TrustManagerExtensions
-android.net.metrics.ApfProgramEvent
-android.net.metrics.ApfProgramEvent$1
-android.net.metrics.ApfStats
-android.net.metrics.ApfStats$1
-android.net.metrics.ConnectStats
-android.net.metrics.DefaultNetworkEvent
-android.net.metrics.DefaultNetworkEvent$1
-android.net.metrics.DhcpClientEvent
-android.net.metrics.DhcpClientEvent$1
-android.net.metrics.DnsEvent
-android.net.metrics.IpConnectivityLog
-android.net.metrics.IpManagerEvent
-android.net.metrics.IpManagerEvent$1
-android.net.metrics.NetworkEvent
-android.net.metrics.NetworkEvent$1
-android.net.metrics.RaEvent
-android.net.metrics.RaEvent$1
-android.net.metrics.RaEvent$Builder
-android.net.metrics.ValidationProbeEvent
-android.net.metrics.ValidationProbeEvent$1
-android.net.metrics.ValidationProbeEvent$Decoder
-android.net.nsd.INsdManager
-android.net.nsd.INsdManager$Stub
-android.net.nsd.NsdManager
-android.net.sip.ISipService
-android.net.sip.ISipService$Stub
-android.net.sip.SipManager
-android.net.wifi.IRttManager
-android.net.wifi.IRttManager$Stub
-android.net.wifi.IWifiManager
-android.net.wifi.IWifiManager$Stub
-android.net.wifi.IWifiManager$Stub$Proxy
-android.net.wifi.IWifiScanner
-android.net.wifi.IWifiScanner$Stub
-android.net.wifi.IWifiScanner$Stub$Proxy
-android.net.wifi.ParcelUtil
-android.net.wifi.RttManager
-android.net.wifi.RttManager$RttCapabilities
-android.net.wifi.RttManager$RttListener
-android.net.wifi.RttManager$RttResult
-android.net.wifi.ScanResult
-android.net.wifi.ScanResult$1
-android.net.wifi.ScanResult$InformationElement
-android.net.wifi.ScanSettings
-android.net.wifi.SupplicantState
-android.net.wifi.SupplicantState$1
-android.net.wifi.WifiActivityEnergyInfo
-android.net.wifi.WifiActivityEnergyInfo$1
-android.net.wifi.WifiConfiguration
-android.net.wifi.WifiConfiguration$1
-android.net.wifi.WifiConfiguration$KeyMgmt
-android.net.wifi.WifiConfiguration$NetworkSelectionStatus
-android.net.wifi.WifiConfiguration$Visibility
-android.net.wifi.WifiConnectionStatistics
-android.net.wifi.WifiConnectionStatistics$1
-android.net.wifi.WifiEnterpriseConfig
-android.net.wifi.WifiEnterpriseConfig$1
-android.net.wifi.WifiInfo
-android.net.wifi.WifiInfo$1
-android.net.wifi.WifiLinkLayerStats
-android.net.wifi.WifiLinkLayerStats$1
-android.net.wifi.WifiManager
-android.net.wifi.WifiManager$ActionListener
-android.net.wifi.WifiManager$MulticastLock
-android.net.wifi.WifiManager$WifiLock
-android.net.wifi.WifiNetworkScoreCache
-android.net.wifi.WifiNetworkScoreCache$CacheListener
-android.net.wifi.WifiNetworkScoreCache$CacheListener$1
-android.net.wifi.WifiScanner
-android.net.wifi.WifiScanner$ActionListener
-android.net.wifi.WifiScanner$ChannelSpec
-android.net.wifi.WifiScanner$ParcelableScanData
-android.net.wifi.WifiScanner$ParcelableScanData$1
-android.net.wifi.WifiScanner$ParcelableScanResults
-android.net.wifi.WifiScanner$ParcelableScanResults$1
-android.net.wifi.WifiScanner$PnoScanListener
-android.net.wifi.WifiScanner$ScanData
-android.net.wifi.WifiScanner$ScanData$1
-android.net.wifi.WifiScanner$ScanListener
-android.net.wifi.WifiScanner$ScanSettings
-android.net.wifi.WifiScanner$ScanSettings$1
-android.net.wifi.WifiScanner$ScanSettings$HiddenNetwork
-android.net.wifi.WifiScanner$ServiceHandler
-android.net.wifi.WifiSsid
-android.net.wifi.WifiSsid$1
-android.net.wifi.WpsInfo
-android.net.wifi.WpsInfo$1
-android.net.wifi.aware.WifiAwareManager
-android.net.wifi.hotspot2.PasspointConfiguration
-android.net.wifi.p2p.IWifiP2pManager
-android.net.wifi.p2p.IWifiP2pManager$Stub
-android.net.wifi.p2p.WifiP2pConfig
-android.net.wifi.p2p.WifiP2pConfig$1
-android.net.wifi.p2p.WifiP2pDevice
-android.net.wifi.p2p.WifiP2pDevice$1
-android.net.wifi.p2p.WifiP2pDeviceList
-android.net.wifi.p2p.WifiP2pDeviceList$1
-android.net.wifi.p2p.WifiP2pGroup
-android.net.wifi.p2p.WifiP2pGroup$1
-android.net.wifi.p2p.WifiP2pGroupList
-android.net.wifi.p2p.WifiP2pGroupList$1
-android.net.wifi.p2p.WifiP2pGroupList$2
-android.net.wifi.p2p.WifiP2pGroupList$GroupDeleteListener
-android.net.wifi.p2p.WifiP2pInfo
-android.net.wifi.p2p.WifiP2pInfo$1
-android.net.wifi.p2p.WifiP2pManager
-android.net.wifi.p2p.WifiP2pWfdInfo
-android.net.wifi.p2p.WifiP2pWfdInfo$1
-android.nfc.BeamShareData
-android.nfc.FormatException
-android.nfc.IAppCallback
-android.nfc.IAppCallback$Stub
-android.nfc.IAppCallback$Stub$Proxy
-android.nfc.INfcAdapter
-android.nfc.INfcAdapter$Stub
-android.nfc.INfcAdapter$Stub$Proxy
-android.nfc.INfcAdapterExtras
-android.nfc.INfcCardEmulation
-android.nfc.INfcCardEmulation$Stub
-android.nfc.INfcCardEmulation$Stub$Proxy
-android.nfc.INfcFCardEmulation
-android.nfc.INfcFCardEmulation$Stub
-android.nfc.INfcFCardEmulation$Stub$Proxy
-android.nfc.INfcTag
-android.nfc.INfcTag$Stub
-android.nfc.INfcTag$Stub$Proxy
-android.nfc.INfcUnlockHandler
-android.nfc.ITagRemovedCallback
-android.nfc.NdefMessage
-android.nfc.NfcActivityManager
-android.nfc.NfcActivityManager$NfcActivityState
-android.nfc.NfcActivityManager$NfcApplicationState
-android.nfc.NfcAdapter
-android.nfc.NfcAdapter$1
-android.nfc.NfcAdapter$CreateBeamUrisCallback
-android.nfc.NfcAdapter$CreateNdefMessageCallback
-android.nfc.NfcAdapter$OnNdefPushCompleteCallback
-android.nfc.NfcEvent
-android.nfc.NfcManager
-android.nfc.Tag
-android.nfc.TechListParcel
-android.nfc.TransceiveResult
-android.nfc.cardemulation.AidGroup
-android.nfc.cardemulation.AidGroup$1
-android.nfc.cardemulation.ApduServiceInfo
-android.nfc.cardemulation.ApduServiceInfo$1
-android.nfc.cardemulation.CardEmulation
-android.nfc.cardemulation.HostApduService
-android.nfc.cardemulation.HostApduService$MsgHandler
-android.opengl.EGL14
-android.opengl.EGLConfig
-android.opengl.EGLContext
-android.opengl.EGLDisplay
-android.opengl.EGLExt
-android.opengl.EGLObjectHandle
-android.opengl.EGLSurface
-android.opengl.ETC1
-android.opengl.GLES10
-android.opengl.GLES10Ext
-android.opengl.GLES11
-android.opengl.GLES11Ext
-android.opengl.GLES20
-android.opengl.GLES30
-android.opengl.GLES31
-android.opengl.GLES31Ext
-android.opengl.GLES32
-android.opengl.GLUtils
-android.opengl.Matrix
-android.opengl.Visibility
-android.os.-$Lambda$-dncxFEc2F2bgG2fsIoC6FC6WNE
-android.os.-$Lambda$-dncxFEc2F2bgG2fsIoC6FC6WNE$1
-android.os.-$Lambda$6x30vPJhBKUfNY8tswxuZo3DCe0
-android.os.AsyncResult
-android.os.AsyncTask$1
-android.os.AsyncTask$2
-android.os.AsyncTask$3
-android.os.AsyncTask$AsyncTaskResult
-android.os.AsyncTask$InternalHandler
-android.os.AsyncTask$SerialExecutor
-android.os.AsyncTask$SerialExecutor$1
-android.os.AsyncTask$Status
-android.os.AsyncTask$WorkerRunnable
-android.os.BadParcelableException
-android.os.BaseBundle
-android.os.BaseBundle$NoImagePreloadHolder
-android.os.BatteryManager
-android.os.BatteryManagerInternal
-android.os.BatteryProperties
-android.os.BatteryProperties$1
-android.os.BatteryStats
-android.os.BatteryStats$BitDescription
-android.os.BatteryStats$ControllerActivityCounter
-android.os.BatteryStats$Counter
-android.os.BatteryStats$DailyItem
-android.os.BatteryStats$HistoryEventTracker
-android.os.BatteryStats$HistoryItem
-android.os.BatteryStats$HistoryStepDetails
-android.os.BatteryStats$HistoryTag
-android.os.BatteryStats$IntToString
-android.os.BatteryStats$LevelStepTracker
-android.os.BatteryStats$LongCounter
-android.os.BatteryStats$LongCounterArray
-android.os.BatteryStats$PackageChange
-android.os.BatteryStats$Timer
-android.os.BatteryStats$Uid
-android.os.BatteryStats$Uid$Pid
-android.os.BatteryStats$Uid$Pkg
-android.os.BatteryStats$Uid$Pkg$Serv
-android.os.BatteryStats$Uid$Sensor
-android.os.BatteryStats$Uid$Wakelock
-android.os.Binder
-android.os.BinderProxy
-android.os.Build
-android.os.Build$VERSION
-android.os.Bundle
-android.os.Bundle$1
-android.os.CancellationSignal
-android.os.CancellationSignal$OnCancelListener
-android.os.CancellationSignal$Transport
-android.os.CommonTimeConfig$OnServerDiedListener
-android.os.ConditionVariable
-android.os.CountDownTimer
-android.os.CpuUsageInfo
-android.os.CpuUsageInfo$1
-android.os.DeadObjectException
-android.os.DeadSystemException
-android.os.Debug
-android.os.Debug$MemoryInfo
-android.os.Debug$MemoryInfo$1
-android.os.DropBoxManager
-android.os.DropBoxManager$Entry
-android.os.DropBoxManager$Entry$1
-android.os.Environment
-android.os.Environment$UserEnvironment
-android.os.FactoryTest
-android.os.FileBridge
-android.os.FileBridge$FileBridgeOutputStream
-android.os.FileObserver$ObserverThread
-android.os.FileUtils
-android.os.GraphicsEnvironment
-android.os.Handler
-android.os.Handler$BlockingRunnable
-android.os.Handler$Callback
-android.os.Handler$MessengerImpl
-android.os.HandlerThread
-android.os.HardwarePropertiesManager
-android.os.HwBinder
-android.os.HwBlob
-android.os.HwParcel
-android.os.HwRemoteBinder
-android.os.IBatteryPropertiesListener
-android.os.IBatteryPropertiesListener$Stub
-android.os.IBatteryPropertiesRegistrar
-android.os.IBatteryPropertiesRegistrar$Stub
-android.os.IBatteryPropertiesRegistrar$Stub$Proxy
-android.os.IBinder
-android.os.IBinder$DeathRecipient
-android.os.ICancellationSignal
-android.os.ICancellationSignal$Stub
-android.os.ICancellationSignal$Stub$Proxy
-android.os.IDeviceIdentifiersPolicyService
-android.os.IDeviceIdentifiersPolicyService$Stub
-android.os.IDeviceIdleController
-android.os.IDeviceIdleController$Stub
-android.os.IDeviceIdleController$Stub$Proxy
-android.os.IHardwarePropertiesManager
-android.os.IHardwarePropertiesManager$Stub
-android.os.IHardwarePropertiesManager$Stub$Proxy
-android.os.IHwBinder
-android.os.IHwBinder$DeathRecipient
-android.os.IHwInterface
-android.os.IIncidentManager
-android.os.IIncidentManager$Stub
-android.os.IInstalld
-android.os.IInstalld$Stub
-android.os.IInstalld$Stub$Proxy
-android.os.IInterface
-android.os.IMaintenanceActivityListener
-android.os.IMessenger
-android.os.IMessenger$Stub
-android.os.IMessenger$Stub$Proxy
-android.os.INetworkActivityListener
-android.os.INetworkManagementService
-android.os.INetworkManagementService$Stub
-android.os.INetworkManagementService$Stub$Proxy
-android.os.IPermissionController
-android.os.IPermissionController$Stub
-android.os.IPowerManager
-android.os.IPowerManager$Stub
-android.os.IPowerManager$Stub$Proxy
-android.os.IProcessInfoService
-android.os.IProcessInfoService$Stub
-android.os.IProgressListener
-android.os.IRecoverySystem
-android.os.IRecoverySystem$Stub
-android.os.IRecoverySystemProgressListener
-android.os.IRemoteCallback
-android.os.IRemoteCallback$Stub
-android.os.IRemoteCallback$Stub$Proxy
-android.os.ISchedulingPolicyService
-android.os.ISchedulingPolicyService$Stub
-android.os.IServiceManager
-android.os.IUpdateLock
-android.os.IUpdateLock$Stub
-android.os.IUserManager
-android.os.IUserManager$Stub
-android.os.IUserManager$Stub$Proxy
-android.os.IVibratorService
-android.os.IVibratorService$Stub
-android.os.IVibratorService$Stub$Proxy
-android.os.IncidentManager
-android.os.LocaleList
-android.os.LocaleList$1
-android.os.Looper
-android.os.MemoryFile
-android.os.Message
-android.os.Message$1
-android.os.MessageQueue
-android.os.MessageQueue$FileDescriptorRecord
-android.os.MessageQueue$IdleHandler
-android.os.MessageQueue$OnFileDescriptorEventListener
-android.os.Messenger
-android.os.Messenger$1
-android.os.OperationCanceledException
-android.os.Parcel
-android.os.Parcel$1
-android.os.Parcel$2
-android.os.ParcelFileDescriptor
-android.os.ParcelFileDescriptor$1
-android.os.ParcelFileDescriptor$2
-android.os.ParcelFileDescriptor$AutoCloseInputStream
-android.os.ParcelFileDescriptor$AutoCloseOutputStream
-android.os.ParcelFileDescriptor$OnCloseListener
-android.os.ParcelFileDescriptor$Status
-android.os.ParcelFormatException
-android.os.ParcelUuid
-android.os.ParcelUuid$1
-android.os.Parcelable
-android.os.Parcelable$ClassLoaderCreator
-android.os.Parcelable$Creator
-android.os.ParcelableException
-android.os.ParcelableParcel
-android.os.ParcelableParcel$1
-android.os.PatternMatcher
-android.os.PatternMatcher$1
-android.os.PersistableBundle
-android.os.PersistableBundle$1
-android.os.PersistableBundle$MyReadMapCallback
-android.os.PooledStringReader
-android.os.PooledStringWriter
-android.os.PowerManager
-android.os.PowerManager$WakeLock
-android.os.PowerManager$WakeLock$1
-android.os.PowerManagerInternal
-android.os.PowerManagerInternal$LowPowerModeListener
-android.os.PowerSaveState
-android.os.PowerSaveState$1
-android.os.PowerSaveState$Builder
-android.os.Process
-android.os.Process$ProcessStartResult
-android.os.RecoverySystem
-android.os.RecoverySystem$ProgressListener
-android.os.Registrant
-android.os.RegistrantList
-android.os.RemoteCallback
-android.os.RemoteCallback$1
-android.os.RemoteCallback$2
-android.os.RemoteCallback$OnResultListener
-android.os.RemoteCallbackList
-android.os.RemoteCallbackList$Callback
-android.os.RemoteException
-android.os.ResultReceiver
-android.os.ResultReceiver$1
-android.os.ResultReceiver$MyResultReceiver
-android.os.ResultReceiver$MyRunnable
-android.os.SELinux
-android.os.Seccomp
-android.os.ServiceManager
-android.os.ServiceManager$ServiceNotFoundException
-android.os.ServiceManagerNative
-android.os.ServiceManagerProxy
-android.os.ServiceSpecificException
-android.os.ShellCallback
-android.os.StatFs
-android.os.StrictMode
-android.os.StrictMode$1
-android.os.StrictMode$2
-android.os.StrictMode$3
-android.os.StrictMode$4
-android.os.StrictMode$5
-android.os.StrictMode$6
-android.os.StrictMode$7
-android.os.StrictMode$8
-android.os.StrictMode$9
-android.os.StrictMode$AndroidBlockGuardPolicy
-android.os.StrictMode$AndroidBlockGuardPolicy$1
-android.os.StrictMode$AndroidCloseGuardReporter
-android.os.StrictMode$InstanceCountViolation
-android.os.StrictMode$InstanceTracker
-android.os.StrictMode$LogStackTrace
-android.os.StrictMode$Span
-android.os.StrictMode$StrictModeCustomViolation
-android.os.StrictMode$StrictModeDiskReadViolation
-android.os.StrictMode$StrictModeDiskWriteViolation
-android.os.StrictMode$StrictModeViolation
-android.os.StrictMode$ThreadPolicy
-android.os.StrictMode$ThreadPolicy$Builder
-android.os.StrictMode$ThreadSpanState
-android.os.StrictMode$ViolationInfo
-android.os.StrictMode$ViolationInfo$1
-android.os.StrictMode$VmPolicy
-android.os.StrictMode$VmPolicy$Builder
-android.os.SynchronousResultReceiver
-android.os.SynchronousResultReceiver$Result
-android.os.SystemClock
-android.os.SystemProperties
-android.os.SystemService
-android.os.SystemService$1
-android.os.SystemService$State
-android.os.SystemVibrator
-android.os.TokenWatcher
-android.os.TokenWatcher$1
-android.os.Trace
-android.os.Trace$1
-android.os.TransactionTooLargeException
-android.os.UEventObserver
-android.os.UEventObserver$UEvent
-android.os.UEventObserver$UEventThread
-android.os.UpdateLock
-android.os.UserHandle
-android.os.UserHandle$1
-android.os.UserManager
-android.os.UserManager$EnforcingUser
-android.os.UserManager$EnforcingUser$1
-android.os.UserManagerInternal
-android.os.UserManagerInternal$UserRestrictionsListener
-android.os.VibrationEffect
-android.os.VibrationEffect$1
-android.os.VibrationEffect$OneShot
-android.os.VibrationEffect$Prebaked
-android.os.VibrationEffect$Prebaked$1
-android.os.VibrationEffect$Waveform
-android.os.VibrationEffect$Waveform$1
-android.os.Vibrator
-android.os.VintfObject
-android.os.VintfRuntimeInfo
-android.os.WorkSource
-android.os.WorkSource$1
-android.os.ZygoteProcess
-android.os.ZygoteProcess$ZygoteState
-android.os.ZygoteStartFailedEx
-android.os.health.HealthStatsParceler
-android.os.health.SystemHealthManager
-android.os.storage.DiskInfo
-android.os.storage.DiskInfo$1
-android.os.storage.IObbActionListener
-android.os.storage.IObbActionListener$Stub
-android.os.storage.IStorageEventListener
-android.os.storage.IStorageEventListener$Stub
-android.os.storage.IStorageEventListener$Stub$Proxy
-android.os.storage.IStorageManager
-android.os.storage.IStorageManager$Stub
-android.os.storage.IStorageManager$Stub$Proxy
-android.os.storage.IStorageShutdownObserver
-android.os.storage.StorageEventListener
-android.os.storage.StorageManager
-android.os.storage.StorageManager$ObbActionListener
-android.os.storage.StorageManager$StorageEventListenerDelegate
-android.os.storage.StorageManagerInternal
-android.os.storage.StorageManagerInternal$ExternalStorageMountPolicy
-android.os.storage.StorageVolume
-android.os.storage.StorageVolume$1
-android.os.storage.VolumeInfo
-android.os.storage.VolumeInfo$1
-android.os.storage.VolumeInfo$2
-android.os.storage.VolumeRecord
-android.os.storage.VolumeRecord$1
-android.preference.GenericInflater$Parent
-android.preference.Preference
-android.preference.Preference$BaseSavedState
-android.preference.Preference$BaseSavedState$1
-android.preference.Preference$OnPreferenceChangeListener
-android.preference.PreferenceActivity
-android.preference.PreferenceFragment
-android.preference.PreferenceFragment$OnPreferenceStartFragmentCallback
-android.preference.PreferenceGroup
-android.preference.PreferenceManager
-android.preference.PreferenceManager$OnPreferenceTreeClickListener
-android.preference.PreferenceScreen
-android.print.IPrintDocumentAdapter
-android.print.IPrintJobStateChangeListener
-android.print.IPrintManager
-android.print.IPrintManager$Stub
-android.print.IPrintServicesChangeListener
-android.print.IPrintSpooler
-android.print.IPrintSpooler$Stub
-android.print.IPrintSpooler$Stub$Proxy
-android.print.IPrintSpoolerCallbacks
-android.print.IPrintSpoolerCallbacks$Stub
-android.print.IPrintSpoolerClient
-android.print.IPrintSpoolerClient$Stub
-android.print.IPrinterDiscoveryObserver
-android.print.PageRange
-android.print.PrintAttributes
-android.print.PrintDocumentAdapter
-android.print.PrintDocumentAdapter$LayoutResultCallback
-android.print.PrintDocumentAdapter$WriteResultCallback
-android.print.PrintJobId
-android.print.PrintJobInfo
-android.print.PrintManager
-android.print.PrinterId
-android.printservice.IPrintServiceClient
-android.printservice.IPrintServiceClient$Stub
-android.printservice.PrintServiceInfo
-android.printservice.PrintServiceInfo$1
-android.printservice.recommendation.IRecommendationsChangeListener
-android.provider.-$Lambda$87WmhkvObehVg0OMBzwa_MTVV8g
-android.provider.-$Lambda$a7Jyr6j_Mb70hHJ2ssL1AAhKh4c
-android.provider.BaseColumns
-android.provider.BlockedNumberContract
-android.provider.BlockedNumberContract$BlockedNumbers
-android.provider.CalendarContract
-android.provider.CalendarContract$Attendees
-android.provider.CalendarContract$AttendeesColumns
-android.provider.CalendarContract$CalendarAlerts
-android.provider.CalendarContract$CalendarAlertsColumns
-android.provider.CalendarContract$CalendarCache
-android.provider.CalendarContract$CalendarCacheColumns
-android.provider.CalendarContract$CalendarColumns
-android.provider.CalendarContract$CalendarSyncColumns
-android.provider.CalendarContract$Calendars
-android.provider.CalendarContract$Colors
-android.provider.CalendarContract$ColorsColumns
-android.provider.CalendarContract$Events
-android.provider.CalendarContract$EventsColumns
-android.provider.CalendarContract$ExtendedProperties
-android.provider.CalendarContract$ExtendedPropertiesColumns
-android.provider.CalendarContract$Instances
-android.provider.CalendarContract$Reminders
-android.provider.CalendarContract$RemindersColumns
-android.provider.CalendarContract$SyncColumns
-android.provider.CallLog
-android.provider.CallLog$Calls
-android.provider.ContactsContract
-android.provider.ContactsContract$BaseSyncColumns
-android.provider.ContactsContract$CommonDataKinds$BaseTypes
-android.provider.ContactsContract$CommonDataKinds$Callable
-android.provider.ContactsContract$CommonDataKinds$CommonColumns
-android.provider.ContactsContract$CommonDataKinds$Email
-android.provider.ContactsContract$CommonDataKinds$Event
-android.provider.ContactsContract$CommonDataKinds$Im
-android.provider.ContactsContract$CommonDataKinds$Phone
-android.provider.ContactsContract$CommonDataKinds$Relation
-android.provider.ContactsContract$CommonDataKinds$StructuredPostal
-android.provider.ContactsContract$ContactCounts
-android.provider.ContactsContract$ContactNameColumns
-android.provider.ContactsContract$ContactOptionsColumns
-android.provider.ContactsContract$ContactStatusColumns
-android.provider.ContactsContract$Contacts
-android.provider.ContactsContract$ContactsColumns
-android.provider.ContactsContract$Data
-android.provider.ContactsContract$DataColumns
-android.provider.ContactsContract$DataColumnsWithJoins
-android.provider.ContactsContract$DataUsageFeedback
-android.provider.ContactsContract$DataUsageStatColumns
-android.provider.ContactsContract$DeletedContacts
-android.provider.ContactsContract$DeletedContactsColumns
-android.provider.ContactsContract$Directory
-android.provider.ContactsContract$DisplayPhoto
-android.provider.ContactsContract$Groups
-android.provider.ContactsContract$GroupsColumns
-android.provider.ContactsContract$MetadataSync
-android.provider.ContactsContract$MetadataSyncColumns
-android.provider.ContactsContract$PhoneLookup
-android.provider.ContactsContract$PhoneLookupColumns
-android.provider.ContactsContract$Profile
-android.provider.ContactsContract$ProviderStatus
-android.provider.ContactsContract$RawContacts
-android.provider.ContactsContract$RawContactsColumns
-android.provider.ContactsContract$RawContactsEntity
-android.provider.ContactsContract$StatusColumns
-android.provider.ContactsContract$SyncColumns
-android.provider.DocumentsContract
-android.provider.DocumentsContract$Path
-android.provider.DocumentsProvider
-android.provider.Downloads
-android.provider.Downloads$Impl
-android.provider.FontsContract
-android.provider.FontsContract$1
-android.provider.MediaStore$Audio
-android.provider.MediaStore$Audio$AlbumColumns
-android.provider.MediaStore$Audio$Albums
-android.provider.MediaStore$Audio$AudioColumns
-android.provider.MediaStore$Audio$Media
-android.provider.MediaStore$Audio$Playlists
-android.provider.MediaStore$Audio$PlaylistsColumns
-android.provider.MediaStore$Files
-android.provider.MediaStore$Images$ImageColumns
-android.provider.MediaStore$Images$Media
-android.provider.MediaStore$Images$Thumbnails
-android.provider.MediaStore$MediaColumns
-android.provider.MediaStore$Video$Media
-android.provider.MediaStore$Video$VideoColumns
-android.provider.OpenableColumns
-android.provider.SearchIndexableData
-android.provider.SearchIndexableResource
-android.provider.SearchIndexablesProvider
-android.provider.SearchRecentSuggestions
-android.provider.Settings
-android.provider.Settings$ContentProviderHolder
-android.provider.Settings$GenerationTracker
-android.provider.Settings$Global
-android.provider.Settings$NameValueCache
-android.provider.Settings$NameValueTable
-android.provider.Settings$Secure
-android.provider.Settings$SettingNotFoundException
-android.provider.Settings$System
-android.provider.Settings$System$1
-android.provider.Settings$System$2
-android.provider.Settings$System$3
-android.provider.Settings$System$4
-android.provider.Settings$System$5
-android.provider.Settings$System$6
-android.provider.Settings$System$7
-android.provider.Settings$System$8
-android.provider.Settings$System$9
-android.provider.Settings$System$DiscreteValueValidator
-android.provider.Settings$System$InclusiveFloatRangeValidator
-android.provider.Settings$System$InclusiveIntegerRangeValidator
-android.provider.Settings$System$Validator
-android.provider.SyncStateContract$Columns
-android.provider.Telephony$BaseMmsColumns
-android.provider.Telephony$Carriers
-android.provider.Telephony$Mms
-android.provider.Telephony$MmsSms
-android.provider.Telephony$ServiceStateTable
-android.provider.Telephony$Sms
-android.provider.Telephony$TextBasedSmsColumns
-android.provider.Telephony$Threads
-android.provider.Telephony$ThreadsColumns
-android.provider.UserDictionary$Words
-android.provider.VoicemailContract$Status
-android.provider.VoicemailContract$Voicemails
-android.renderscript.Allocation
-android.renderscript.BaseObj
-android.renderscript.Matrix4f
-android.renderscript.RenderScriptCacheDir
-android.security.GateKeeper
-android.security.IKeyChainService
-android.security.IKeyChainService$Stub
-android.security.IKeyChainService$Stub$Proxy
-android.security.IKeystoreService
-android.security.IKeystoreService$Stub
-android.security.IKeystoreService$Stub$Proxy
-android.security.KeyChain
-android.security.KeyChain$1
-android.security.KeyChain$KeyChainConnection
-android.security.KeyStore
-android.security.NetworkSecurityPolicy
-android.security.keymaster.IKeyAttestationApplicationIdProvider
-android.security.keymaster.IKeyAttestationApplicationIdProvider$Stub
-android.security.keymaster.KeyAttestationApplicationId
-android.security.keymaster.KeymasterArguments
-android.security.keymaster.KeymasterArguments$1
-android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
-android.security.keystore.AndroidKeyStoreKeyGeneratorSpi
-android.security.keystore.AndroidKeyStoreKeyGeneratorSpi$AES
-android.security.keystore.AndroidKeyStoreProvider
-android.security.keystore.AndroidKeyStoreSpi
-android.security.keystore.ArrayUtils
-android.security.keystore.KeyGenParameterSpec
-android.security.keystore.KeyGenParameterSpec$Builder
-android.security.keystore.KeyInfo
-android.security.keystore.KeyPermanentlyInvalidatedException
-android.security.keystore.KeyProperties
-android.security.keystore.KeyProperties$BlockMode
-android.security.keystore.KeyProperties$EncryptionPadding
-android.security.keystore.KeyProperties$Purpose
-android.security.keystore.KeymasterUtils
-android.security.keystore.UserNotAuthenticatedException
-android.security.keystore.Utils
-android.security.net.config.ApplicationConfig
-android.security.net.config.CertificateSource
-android.security.net.config.CertificatesEntryRef
-android.security.net.config.ConfigNetworkSecurityPolicy
-android.security.net.config.ConfigSource
-android.security.net.config.DirectoryCertificateSource
-android.security.net.config.DirectoryCertificateSource$1
-android.security.net.config.DirectoryCertificateSource$3
-android.security.net.config.DirectoryCertificateSource$CertSelector
-android.security.net.config.KeyStoreCertificateSource
-android.security.net.config.KeyStoreConfigSource
-android.security.net.config.ManifestConfigSource
-android.security.net.config.ManifestConfigSource$DefaultConfigSource
-android.security.net.config.NetworkSecurityConfig
-android.security.net.config.NetworkSecurityConfig$1
-android.security.net.config.NetworkSecurityConfig$Builder
-android.security.net.config.NetworkSecurityConfigProvider
-android.security.net.config.NetworkSecurityTrustManager
-android.security.net.config.PinSet
-android.security.net.config.RootTrustManager
-android.security.net.config.RootTrustManagerFactorySpi
-android.security.net.config.SystemCertificateSource
-android.security.net.config.TrustedCertificateStoreAdapter
-android.security.net.config.UserCertificateSource
-android.security.net.config.XmlConfigSource
-android.security.net.config.XmlConfigSource$ParserException
-android.service.autofill.-$Lambda$svbjmB3NFhHnuZrn67G14PFSJlY
-android.service.autofill.AutofillService
-android.service.autofill.AutofillService$1
-android.service.autofill.AutofillServiceInfo
-android.service.autofill.FillCallback
-android.service.autofill.FillContext
-android.service.autofill.FillContext$1
-android.service.autofill.FillEventHistory
-android.service.autofill.FillRequest
-android.service.autofill.FillRequest$1
-android.service.autofill.FillResponse
-android.service.autofill.IAutoFillService
-android.service.autofill.IAutoFillService$Stub
-android.service.autofill.IAutoFillService$Stub$Proxy
-android.service.autofill.IFillCallback
-android.service.autofill.IFillCallback$Stub
-android.service.autofill.IFillCallback$Stub$Proxy
-android.service.autofill.SaveCallback
-android.service.autofill.SaveRequest
-android.service.carrier.CarrierIdentifier
-android.service.carrier.CarrierIdentifier$1
-android.service.carrier.ICarrierService
-android.service.carrier.ICarrierService$Stub
-android.service.carrier.ICarrierService$Stub$Proxy
-android.service.dreams.DreamManagerInternal
-android.service.dreams.IDreamManager
-android.service.dreams.IDreamManager$Stub
-android.service.dreams.IDreamManager$Stub$Proxy
-android.service.gatekeeper.IGateKeeperService
-android.service.gatekeeper.IGateKeeperService$Stub
-android.service.gatekeeper.IGateKeeperService$Stub$Proxy
-android.service.media.IMediaBrowserService
-android.service.media.IMediaBrowserService$Stub
-android.service.media.IMediaBrowserService$Stub$Proxy
-android.service.media.IMediaBrowserServiceCallbacks
-android.service.media.IMediaBrowserServiceCallbacks$Stub
-android.service.notification.Adjustment
-android.service.notification.Condition
-android.service.notification.Condition$1
-android.service.notification.ConditionProviderService
-android.service.notification.ConditionProviderService$H
-android.service.notification.ConditionProviderService$Provider
-android.service.notification.IConditionListener
-android.service.notification.IConditionListener$Stub
-android.service.notification.IConditionProvider
-android.service.notification.IConditionProvider$Stub
-android.service.notification.INotificationListener
-android.service.notification.INotificationListener$Stub
-android.service.notification.INotificationListener$Stub$Proxy
-android.service.notification.IStatusBarNotificationHolder
-android.service.notification.IStatusBarNotificationHolder$Stub
-android.service.notification.IStatusBarNotificationHolder$Stub$Proxy
-android.service.notification.NotificationListenerService
-android.service.notification.NotificationListenerService$MyHandler
-android.service.notification.NotificationListenerService$NotificationListenerWrapper
-android.service.notification.NotificationListenerService$Ranking
-android.service.notification.NotificationListenerService$RankingMap
-android.service.notification.NotificationListenerService$RankingMap$1
-android.service.notification.NotificationRankingUpdate
-android.service.notification.NotificationRankingUpdate$1
-android.service.notification.StatusBarNotification
-android.service.notification.StatusBarNotification$1
-android.service.notification.ZenModeConfig
-android.service.notification.ZenModeConfig$1
-android.service.notification.ZenModeConfig$Diff
-android.service.notification.ZenModeConfig$EventInfo
-android.service.notification.ZenModeConfig$ScheduleInfo
-android.service.notification.ZenModeConfig$ZenRule
-android.service.notification.ZenModeConfig$ZenRule$1
-android.service.oemlock.IOemLockService
-android.service.oemlock.IOemLockService$Stub
-android.service.oemlock.OemLockManager
-android.service.persistentdata.IPersistentDataBlockService
-android.service.persistentdata.IPersistentDataBlockService$Stub
-android.service.persistentdata.IPersistentDataBlockService$Stub$Proxy
-android.service.persistentdata.PersistentDataBlockManager
-android.service.quicksettings.IQSService
-android.service.quicksettings.IQSService$Stub
-android.service.quicksettings.Tile
-android.service.textservice.SpellCheckerService
-android.service.textservice.SpellCheckerService$InternalISpellCheckerSession
-android.service.textservice.SpellCheckerService$Session
-android.service.textservice.SpellCheckerService$SpellCheckerServiceBinder
-android.service.voice.AlwaysOnHotwordDetector
-android.service.voice.AlwaysOnHotwordDetector$Callback
-android.service.voice.AlwaysOnHotwordDetector$EventPayload
-android.service.voice.AlwaysOnHotwordDetector$MyHandler
-android.service.voice.AlwaysOnHotwordDetector$RefreshAvailabiltyTask
-android.service.voice.AlwaysOnHotwordDetector$SoundTriggerListener
-android.service.voice.IVoiceInteractionService
-android.service.voice.IVoiceInteractionService$Stub
-android.service.voice.IVoiceInteractionService$Stub$Proxy
-android.service.voice.IVoiceInteractionSession
-android.service.voice.VoiceInteractionManagerInternal
-android.service.voice.VoiceInteractionService
-android.service.voice.VoiceInteractionService$1
-android.service.voice.VoiceInteractionService$MyHandler
-android.service.voice.VoiceInteractionServiceInfo
-android.service.vr.IPersistentVrStateCallbacks
-android.service.vr.IPersistentVrStateCallbacks$Stub
-android.service.vr.IVrManager
-android.service.vr.IVrManager$Stub
-android.service.vr.IVrManager$Stub$Proxy
-android.service.vr.IVrStateCallbacks
-android.service.vr.IVrStateCallbacks$Stub
-android.service.vr.IVrStateCallbacks$Stub$Proxy
-android.service.wallpaper.IWallpaperConnection
-android.service.wallpaper.IWallpaperConnection$Stub
-android.service.wallpaper.IWallpaperConnection$Stub$Proxy
-android.service.wallpaper.IWallpaperEngine
-android.service.wallpaper.IWallpaperEngine$Stub
-android.service.wallpaper.IWallpaperEngine$Stub$Proxy
-android.service.wallpaper.IWallpaperService
-android.service.wallpaper.IWallpaperService$Stub
-android.service.wallpaper.IWallpaperService$Stub$Proxy
-android.service.wallpaper.WallpaperService
-android.service.wallpaper.WallpaperService$Engine
-android.service.wallpaper.WallpaperService$Engine$1
-android.service.wallpaper.WallpaperService$Engine$2
-android.service.wallpaper.WallpaperService$Engine$3
-android.service.wallpaper.WallpaperService$Engine$WallpaperInputEventReceiver
-android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper
-android.service.wallpaper.WallpaperService$IWallpaperServiceWrapper
-android.service.wallpaper.WallpaperService$WallpaperCommand
-android.speech.SpeechRecognizer
-android.speech.tts.AbstractEventLogger
-android.speech.tts.AbstractSynthesisCallback
-android.speech.tts.AudioPlaybackHandler
-android.speech.tts.AudioPlaybackHandler$MessageLoop
-android.speech.tts.EventLogger
-android.speech.tts.FileSynthesisCallback
-android.speech.tts.ITextToSpeechCallback
-android.speech.tts.ITextToSpeechCallback$Stub
-android.speech.tts.ITextToSpeechCallback$Stub$Proxy
-android.speech.tts.ITextToSpeechService
-android.speech.tts.ITextToSpeechService$Stub
-android.speech.tts.ITextToSpeechService$Stub$Proxy
-android.speech.tts.SynthesisCallback
-android.speech.tts.SynthesisRequest
-android.speech.tts.TextToSpeech
-android.speech.tts.TextToSpeech$10
-android.speech.tts.TextToSpeech$16
-android.speech.tts.TextToSpeech$17
-android.speech.tts.TextToSpeech$7
-android.speech.tts.TextToSpeech$Action
-android.speech.tts.TextToSpeech$Connection
-android.speech.tts.TextToSpeech$Connection$1
-android.speech.tts.TextToSpeech$Connection$SetupConnectionAsyncTask
-android.speech.tts.TextToSpeech$EngineInfo
-android.speech.tts.TextToSpeech$OnInitListener
-android.speech.tts.TextToSpeechService
-android.speech.tts.TextToSpeechService$1
-android.speech.tts.TextToSpeechService$CallbackMap
-android.speech.tts.TextToSpeechService$SpeechItem
-android.speech.tts.TextToSpeechService$SynthHandler
-android.speech.tts.TextToSpeechService$SynthHandler$1
-android.speech.tts.TextToSpeechService$SynthHandler$2
-android.speech.tts.TextToSpeechService$SynthThread
-android.speech.tts.TextToSpeechService$SynthesisSpeechItem
-android.speech.tts.TextToSpeechService$SynthesisToFileOutputStreamSpeechItem
-android.speech.tts.TextToSpeechService$UtteranceProgressDispatcher
-android.speech.tts.TextToSpeechService$UtteranceSpeechItem
-android.speech.tts.TextToSpeechService$UtteranceSpeechItemWithParams
-android.speech.tts.TtsEngines
-android.speech.tts.TtsEngines$EngineInfoComparator
-android.speech.tts.UtteranceProgressListener
-android.system.ErrnoException
-android.system.GaiException
-android.system.NetlinkSocketAddress
-android.system.Os
-android.system.OsConstants
-android.system.PacketSocketAddress
-android.system.StructAddrinfo
-android.system.StructFlock
-android.system.StructGroupReq
-android.system.StructGroupSourceReq
-android.system.StructIcmpHdr
-android.system.StructIfaddrs
-android.system.StructLinger
-android.system.StructPasswd
-android.system.StructPollfd
-android.system.StructStat
-android.system.StructStatVfs
-android.system.StructTimeval
-android.system.StructUcred
-android.system.StructUtsname
-android.system.UnixSocketAddress
-android.telecom.-$Lambda$afyb_ODGzn3xMew6fjs8ANSIdVo
-android.telecom.CallAudioState
-android.telecom.CallAudioState$1
-android.telecom.Conference
-android.telecom.Conference$Listener
-android.telecom.Conferenceable
-android.telecom.Connection
-android.telecom.Connection$1
-android.telecom.Connection$2
-android.telecom.Connection$FailureSignalingConnection
-android.telecom.Connection$Listener
-android.telecom.ConnectionRequest
-android.telecom.ConnectionRequest$1
-android.telecom.ConnectionRequest$Builder
-android.telecom.ConnectionService
-android.telecom.ConnectionService$1
-android.telecom.ConnectionService$2
-android.telecom.ConnectionService$2$1
-android.telecom.ConnectionService$3
-android.telecom.ConnectionService$4
-android.telecom.ConnectionService$5
-android.telecom.ConnectionService$5$1
-android.telecom.ConnectionServiceAdapter
-android.telecom.DefaultDialerManager
-android.telecom.DisconnectCause
-android.telecom.DisconnectCause$1
-android.telecom.Log
-android.telecom.Log$1
-android.telecom.Logging.-$Lambda$OwO3BlCgqcOx28O1BaOAPVPor24
-android.telecom.Logging.-$Lambda$OwO3BlCgqcOx28O1BaOAPVPor24$1
-android.telecom.Logging.-$Lambda$OwO3BlCgqcOx28O1BaOAPVPor24$2
-android.telecom.Logging.EventManager
-android.telecom.Logging.EventManager$Event
-android.telecom.Logging.EventManager$EventListener
-android.telecom.Logging.EventManager$EventRecord
-android.telecom.Logging.EventManager$Loggable
-android.telecom.Logging.EventManager$TimedEventPair
-android.telecom.Logging.Runnable
-android.telecom.Logging.Runnable$1
-android.telecom.Logging.Session
-android.telecom.Logging.Session$Info
-android.telecom.Logging.Session$Info$1
-android.telecom.Logging.SessionManager
-android.telecom.Logging.SessionManager$ICurrentThreadId
-android.telecom.Logging.SessionManager$ISessionCleanupTimeoutMs
-android.telecom.Logging.SessionManager$ISessionIdQueryHandler
-android.telecom.Logging.SessionManager$ISessionListener
-android.telecom.ParcelableCall
-android.telecom.ParcelableCall$1
-android.telecom.ParcelableConference
-android.telecom.ParcelableConnection
-android.telecom.ParcelableConnection$1
-android.telecom.PhoneAccount
-android.telecom.PhoneAccount$1
-android.telecom.PhoneAccount$Builder
-android.telecom.PhoneAccountHandle
-android.telecom.PhoneAccountHandle$1
-android.telecom.RemoteConnectionManager
-android.telecom.StatusHints
-android.telecom.TelecomAnalytics
-android.telecom.TelecomManager
-android.telecom.VideoProfile
-android.telecom.VideoProfile$1
-android.telephony.CarrierConfigManager
-android.telephony.CellIdentityWcdma
-android.telephony.CellIdentityWcdma$1
-android.telephony.CellInfo
-android.telephony.CellInfo$1
-android.telephony.CellInfoCdma
-android.telephony.CellInfoGsm
-android.telephony.CellInfoLte
-android.telephony.CellInfoWcdma
-android.telephony.CellInfoWcdma$1
-android.telephony.CellLocation
-android.telephony.CellSignalStrength
-android.telephony.CellSignalStrengthWcdma
-android.telephony.CellSignalStrengthWcdma$1
-android.telephony.ClientRequestStats
-android.telephony.ClientRequestStats$1
-android.telephony.DisconnectCause
-android.telephony.IccOpenLogicalChannelResponse
-android.telephony.ModemActivityInfo
-android.telephony.PhoneNumberFormattingTextWatcher
-android.telephony.PhoneNumberUtils
-android.telephony.PhoneStateListener
-android.telephony.PhoneStateListener$1
-android.telephony.PhoneStateListener$IPhoneStateListenerStub
-android.telephony.PreciseCallState
-android.telephony.PreciseCallState$1
-android.telephony.PreciseDataConnectionState
-android.telephony.PreciseDataConnectionState$1
-android.telephony.RadioAccessFamily
-android.telephony.Rlog
-android.telephony.ServiceState
-android.telephony.ServiceState$1
-android.telephony.SignalStrength
-android.telephony.SignalStrength$1
-android.telephony.SmsManager
-android.telephony.SmsMessage
-android.telephony.SubscriptionInfo
-android.telephony.SubscriptionInfo$1
-android.telephony.SubscriptionManager
-android.telephony.SubscriptionManager$OnSubscriptionsChangedListener
-android.telephony.SubscriptionManager$OnSubscriptionsChangedListener$1
-android.telephony.SubscriptionManager$OnSubscriptionsChangedListener$2
-android.telephony.TelephonyHistogram
-android.telephony.TelephonyHistogram$1
-android.telephony.TelephonyManager
-android.telephony.TelephonyManager$MultiSimVariants
-android.telephony.VisualVoicemailSmsFilterSettings
-android.telephony.VoLteServiceState
-android.telephony.VoLteServiceState$1
-android.telephony.gsm.GsmCellLocation
-android.telephony.ims.ImsServiceProxy$INotifyStatusChanged
-android.telephony.ims.ImsServiceProxyCompat
-android.telephony.ims.feature.IMMTelFeature
-android.telephony.ims.stub.ImsConfigImplBase
-android.telephony.ims.stub.ImsEcbmImplBase
-android.telephony.ims.stub.ImsUtImplBase
-android.telephony.ims.stub.ImsUtListenerImplBase
-android.text.AndroidBidi
-android.text.AndroidCharacter
-android.text.Annotation
-android.text.BidiFormatter
-android.text.BidiFormatter$DirectionalityEstimator
-android.text.BoringLayout
-android.text.BoringLayout$Metrics
-android.text.CharSequenceCharacterIterator
-android.text.ClipboardManager
-android.text.DynamicLayout
-android.text.DynamicLayout$ChangeWatcher
-android.text.Editable
-android.text.Editable$Factory
-android.text.FontConfig
-android.text.FontConfig$Alias
-android.text.FontConfig$Family
-android.text.FontConfig$Font
-android.text.GetChars
-android.text.GraphicsOperations
-android.text.Html
-android.text.Html$HtmlParser
-android.text.Html$TagHandler
-android.text.HtmlToSpannedConverter
-android.text.HtmlToSpannedConverter$Bold
-android.text.HtmlToSpannedConverter$Href
-android.text.Hyphenator
-android.text.Hyphenator$HyphenationData
-android.text.InputFilter
-android.text.InputFilter$LengthFilter
-android.text.InputType
-android.text.Layout
-android.text.Layout$Alignment
-android.text.Layout$Directions
-android.text.Layout$Ellipsizer
-android.text.Layout$SpannedEllipsizer
-android.text.MeasuredText
-android.text.NoCopySpan
-android.text.NoCopySpan$Concrete
-android.text.PackedIntVector
-android.text.PackedObjectVector
-android.text.ParcelableSpan
-android.text.Selection
-android.text.Selection$END
-android.text.Selection$PositionIterator
-android.text.Selection$START
-android.text.SpanSet
-android.text.SpanWatcher
-android.text.Spannable
-android.text.Spannable$Factory
-android.text.SpannableString
-android.text.SpannableStringBuilder
-android.text.SpannableStringInternal
-android.text.Spanned
-android.text.SpannedString
-android.text.StaticLayout
-android.text.StaticLayout$Builder
-android.text.StaticLayout$LineBreaks
-android.text.TextDirectionHeuristic
-android.text.TextDirectionHeuristics
-android.text.TextDirectionHeuristics$AnyStrong
-android.text.TextDirectionHeuristics$FirstStrong
-android.text.TextDirectionHeuristics$TextDirectionAlgorithm
-android.text.TextDirectionHeuristics$TextDirectionHeuristicImpl
-android.text.TextDirectionHeuristics$TextDirectionHeuristicInternal
-android.text.TextDirectionHeuristics$TextDirectionHeuristicLocale
-android.text.TextLine
-android.text.TextPaint
-android.text.TextUtils
-android.text.TextUtils$1
-android.text.TextUtils$EllipsizeCallback
-android.text.TextUtils$SimpleStringSplitter
-android.text.TextUtils$StringSplitter
-android.text.TextUtils$TruncateAt
-android.text.TextWatcher
-android.text.format.DateFormat
-android.text.format.DateUtils
-android.text.format.Formatter
-android.text.format.Formatter$BytesResult
-android.text.format.Time
-android.text.format.Time$TimeCalculator
-android.text.format.TimeFormatter
-android.text.method.AllCapsTransformationMethod
-android.text.method.ArrowKeyMovementMethod
-android.text.method.BaseKeyListener
-android.text.method.BaseMovementMethod
-android.text.method.DialerKeyListener
-android.text.method.KeyListener
-android.text.method.LinkMovementMethod
-android.text.method.MetaKeyKeyListener
-android.text.method.MovementMethod
-android.text.method.NumberKeyListener
-android.text.method.PasswordTransformationMethod
-android.text.method.QwertyKeyListener
-android.text.method.QwertyKeyListener$Replaced
-android.text.method.ReplacementTransformationMethod
-android.text.method.ReplacementTransformationMethod$ReplacementCharSequence
-android.text.method.ReplacementTransformationMethod$SpannedReplacementCharSequence
-android.text.method.ScrollingMovementMethod
-android.text.method.SingleLineTransformationMethod
-android.text.method.TextKeyListener
-android.text.method.TextKeyListener$Capitalize
-android.text.method.TextKeyListener$SettingsObserver
-android.text.method.Touch
-android.text.method.Touch$DragState
-android.text.method.TransformationMethod
-android.text.method.TransformationMethod2
-android.text.method.WordIterator
-android.text.style.AlignmentSpan
-android.text.style.BackgroundColorSpan
-android.text.style.CharacterStyle
-android.text.style.CharacterStyle$Passthrough
-android.text.style.ClickableSpan
-android.text.style.DynamicDrawableSpan
-android.text.style.EasyEditSpan
-android.text.style.ForegroundColorSpan
-android.text.style.ImageSpan
-android.text.style.LeadingMarginSpan
-android.text.style.LeadingMarginSpan$LeadingMarginSpan2
-android.text.style.LeadingMarginSpan$Standard
-android.text.style.LineBackgroundSpan
-android.text.style.LineHeightSpan
-android.text.style.LineHeightSpan$WithDensity
-android.text.style.MetricAffectingSpan
-android.text.style.MetricAffectingSpan$Passthrough
-android.text.style.ParagraphStyle
-android.text.style.RelativeSizeSpan
-android.text.style.ReplacementSpan
-android.text.style.SpellCheckSpan
-android.text.style.StrikethroughSpan
-android.text.style.StyleSpan
-android.text.style.SuggestionSpan
-android.text.style.TabStopSpan
-android.text.style.TextAppearanceSpan
-android.text.style.TtsSpan
-android.text.style.TtsSpan$Builder
-android.text.style.TtsSpan$SemioticClassBuilder
-android.text.style.TtsSpan$TelephoneBuilder
-android.text.style.TtsSpan$VerbatimBuilder
-android.text.style.TypefaceSpan
-android.text.style.URLSpan
-android.text.style.UnderlineSpan
-android.text.style.UpdateAppearance
-android.text.style.UpdateLayout
-android.text.style.WrapTogetherSpan
-android.text.util.Linkify
-android.text.util.Linkify$1
-android.text.util.Linkify$2
-android.text.util.Linkify$3
-android.text.util.Linkify$4
-android.text.util.Linkify$MatchFilter
-android.text.util.Linkify$TransformFilter
-android.text.util.Rfc822Token
-android.text.util.Rfc822Tokenizer
-android.transition.ArcMotion
-android.transition.AutoTransition
-android.transition.ChangeBounds
-android.transition.ChangeBounds$1
-android.transition.ChangeBounds$2
-android.transition.ChangeBounds$3
-android.transition.ChangeBounds$4
-android.transition.ChangeBounds$5
-android.transition.ChangeBounds$6
-android.transition.ChangeBounds$9
-android.transition.ChangeClipBounds
-android.transition.ChangeImageTransform
-android.transition.ChangeImageTransform$1
-android.transition.ChangeImageTransform$2
-android.transition.ChangeTransform
-android.transition.ChangeTransform$1
-android.transition.ChangeTransform$2
-android.transition.ChangeTransform$3
-android.transition.ChangeTransform$GhostListener
-android.transition.ChangeTransform$PathAnimatorMatrix
-android.transition.ChangeTransform$Transforms
-android.transition.CircularPropagation
-android.transition.Explode
-android.transition.Fade
-android.transition.Fade$1
-android.transition.Fade$FadeAnimatorListener
-android.transition.PathMotion
-android.transition.Scene
-android.transition.SidePropagation
-android.transition.Slide
-android.transition.Slide$1
-android.transition.Slide$2
-android.transition.Slide$3
-android.transition.Slide$4
-android.transition.Slide$5
-android.transition.Slide$6
-android.transition.Slide$CalculateSlide
-android.transition.Slide$CalculateSlideHorizontal
-android.transition.Slide$CalculateSlideVertical
-android.transition.Transition
-android.transition.Transition$1
-android.transition.Transition$2
-android.transition.Transition$3
-android.transition.Transition$AnimationInfo
-android.transition.Transition$ArrayListManager
-android.transition.Transition$EpicenterCallback
-android.transition.Transition$TransitionListener
-android.transition.TransitionInflater
-android.transition.TransitionListenerAdapter
-android.transition.TransitionManager
-android.transition.TransitionManager$MultiListener
-android.transition.TransitionManager$MultiListener$1
-android.transition.TransitionPropagation
-android.transition.TransitionSet
-android.transition.TransitionSet$TransitionSetListener
-android.transition.TransitionUtils
-android.transition.TransitionValues
-android.transition.TransitionValuesMaps
-android.transition.Visibility
-android.transition.Visibility$1
-android.transition.Visibility$VisibilityInfo
-android.transition.VisibilityPropagation
-android.util.AndroidException
-android.util.AndroidRuntimeException
-android.util.ArrayMap
-android.util.ArrayMap$1
-android.util.ArraySet
-android.util.ArraySet$1
-android.util.AtomicFile
-android.util.AttributeSet
-android.util.Base64
-android.util.Base64$Coder
-android.util.Base64$Decoder
-android.util.Base64$Encoder
-android.util.BootTimingsTraceLog
-android.util.ByteStringUtils
-android.util.ContainerHelpers
-android.util.DebugUtils
-android.util.DisplayMetrics
-android.util.EventLog
-android.util.EventLog$Event
-android.util.FastImmutableArraySet
-android.util.FastImmutableArraySet$FastIterator
-android.util.FloatProperty
-android.util.IconDrawableFactory
-android.util.IntArray
-android.util.IntProperty
-android.util.JsonReader
-android.util.JsonScope
-android.util.JsonToken
-android.util.JsonWriter
-android.util.KeyValueListParser
-android.util.LauncherIcons
-android.util.LauncherIcons$ShadowDrawable
-android.util.LauncherIcons$ShadowDrawable$MyConstantState
-android.util.LocalLog
-android.util.LocalLog$ReadOnlyLocalLog
-android.util.Log
-android.util.Log$1
-android.util.Log$ImmediateLogWriter
-android.util.Log$TerribleFailure
-android.util.Log$TerribleFailureHandler
-android.util.LogPrinter
-android.util.LongArray
-android.util.LongSparseArray
-android.util.LongSparseLongArray
-android.util.LruCache
-android.util.MapCollections
-android.util.MapCollections$ArrayIterator
-android.util.MapCollections$EntrySet
-android.util.MapCollections$KeySet
-android.util.MapCollections$MapIterator
-android.util.MapCollections$ValuesCollection
-android.util.MathUtils
-android.util.MemoryIntArray
-android.util.MemoryIntArray$1
-android.util.MergedConfiguration
-android.util.MergedConfiguration$1
-android.util.MutableBoolean
-android.util.MutableInt
-android.util.MutableLong
-android.util.NtpTrustedTime
-android.util.Pair
-android.util.PathParser
-android.util.PathParser$PathData
-android.util.Patterns
-android.util.Pools$Pool
-android.util.Pools$SimplePool
-android.util.Pools$SynchronizedPool
-android.util.Printer
-android.util.Property
-android.util.Range
-android.util.Rational
-android.util.ReflectiveProperty
-android.util.Singleton
-android.util.Size
-android.util.SizeF
-android.util.Slog
-android.util.SparseArray
-android.util.SparseBooleanArray
-android.util.SparseIntArray
-android.util.SparseLongArray
-android.util.Spline
-android.util.Spline$MonotoneCubicSpline
-android.util.StateSet
-android.util.SuperNotCalledException
-android.util.TimeFormatException
-android.util.TimeUtils
-android.util.TimedRemoteCaller
-android.util.TimingLogger
-android.util.TrustedTime
-android.util.TypedValue
-android.util.Xml
-android.util.Xml$XmlSerializerFactory
-android.util.XmlPullAttributes
-android.util.apk.ApkSignatureSchemeV2Verifier
-android.util.apk.ApkSignatureSchemeV2Verifier$SignatureNotFoundException
-android.util.apk.ZipUtils
-android.util.jar.StrictJarFile
-android.util.jar.StrictJarFile$EntryIterator
-android.util.jar.StrictJarFile$FDStream
-android.util.jar.StrictJarFile$JarFileInputStream
-android.util.jar.StrictJarFile$ZipInflaterInputStream
-android.util.jar.StrictJarManifest
-android.util.jar.StrictJarManifest$Chunk
-android.util.jar.StrictJarManifestReader
-android.util.jar.StrictJarVerifier
-android.util.jar.StrictJarVerifier$VerifierEntry
-android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk
-android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk$1
-android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk$2
-android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk$3
-android.view.-$Lambda$P6MTGFSudLpwrqb6oVD8FdorW1c
-android.view.-$Lambda$iU_USrtPm1XIm5H9QYQvXfBGDE4
-android.view.-$Lambda$iU_USrtPm1XIm5H9QYQvXfBGDE4$1
-android.view.AbsSavedState
-android.view.AbsSavedState$1
-android.view.AbsSavedState$2
-android.view.ActionMode
-android.view.ActionMode$Callback
-android.view.ActionMode$Callback2
-android.view.ActionProvider
-android.view.ActionProvider$SubUiVisibilityListener
-android.view.AppTransitionAnimationSpec
-android.view.AppTransitionAnimationSpec$1
-android.view.Choreographer
-android.view.Choreographer$1
-android.view.Choreographer$2
-android.view.Choreographer$CallbackQueue
-android.view.Choreographer$CallbackRecord
-android.view.Choreographer$FrameCallback
-android.view.Choreographer$FrameDisplayEventReceiver
-android.view.Choreographer$FrameHandler
-android.view.ContextMenu
-android.view.ContextMenu$ContextMenuInfo
-android.view.ContextThemeWrapper
-android.view.Display
-android.view.Display$HdrCapabilities
-android.view.Display$HdrCapabilities$1
-android.view.Display$Mode
-android.view.Display$Mode$1
-android.view.DisplayAdjustments
-android.view.DisplayEventReceiver
-android.view.DisplayInfo
-android.view.DisplayInfo$1
-android.view.DisplayListCanvas
-android.view.DragEvent
-android.view.FallbackEventHandler
-android.view.FocusFinder
-android.view.FocusFinder$1
-android.view.FocusFinder$FocusSorter
-android.view.FocusFinder$UserSpecifiedFocusComparator
-android.view.FocusFinder$UserSpecifiedFocusComparator$NextFocusGetter
-android.view.FrameInfo
-android.view.FrameMetrics
-android.view.FrameMetricsObserver
-android.view.FrameStats
-android.view.GestureDetector
-android.view.GestureDetector$GestureHandler
-android.view.GestureDetector$OnContextClickListener
-android.view.GestureDetector$OnDoubleTapListener
-android.view.GestureDetector$OnGestureListener
-android.view.GestureDetector$SimpleOnGestureListener
-android.view.GhostView
-android.view.Gravity
-android.view.HandlerActionQueue
-android.view.HandlerActionQueue$HandlerAction
-android.view.HardwareLayer
-android.view.IAppTransitionAnimationSpecsFuture
-android.view.IAppTransitionAnimationSpecsFuture$Stub
-android.view.IAppTransitionAnimationSpecsFuture$Stub$Proxy
-android.view.IApplicationToken
-android.view.IApplicationToken$Stub
-android.view.IDockedStackListener
-android.view.IDockedStackListener$Stub
-android.view.IDockedStackListener$Stub$Proxy
-android.view.IGraphicsStats
-android.view.IGraphicsStats$Stub
-android.view.IGraphicsStats$Stub$Proxy
-android.view.IGraphicsStatsCallback
-android.view.IGraphicsStatsCallback$Stub
-android.view.IGraphicsStatsCallback$Stub$Proxy
-android.view.IInputFilter
-android.view.IOnKeyguardExitResult
-android.view.IPinnedStackController
-android.view.IPinnedStackController$Stub
-android.view.IPinnedStackController$Stub$Proxy
-android.view.IPinnedStackListener
-android.view.IPinnedStackListener$Stub
-android.view.IPinnedStackListener$Stub$Proxy
-android.view.IRotationWatcher
-android.view.IRotationWatcher$Stub
-android.view.IRotationWatcher$Stub$Proxy
-android.view.IWindow
-android.view.IWindow$Stub
-android.view.IWindow$Stub$Proxy
-android.view.IWindowFocusObserver
-android.view.IWindowId
-android.view.IWindowId$Stub
-android.view.IWindowId$Stub$Proxy
-android.view.IWindowManager
-android.view.IWindowManager$Stub
-android.view.IWindowManager$Stub$Proxy
-android.view.IWindowSession
-android.view.IWindowSession$Stub
-android.view.IWindowSession$Stub$Proxy
-android.view.IWindowSessionCallback
-android.view.IWindowSessionCallback$Stub
-android.view.IWindowSessionCallback$Stub$Proxy
-android.view.InflateException
-android.view.InputChannel
-android.view.InputChannel$1
-android.view.InputDevice
-android.view.InputDevice$1
-android.view.InputDevice$MotionRange
-android.view.InputEvent
-android.view.InputEvent$1
-android.view.InputEventConsistencyVerifier
-android.view.InputEventReceiver
-android.view.InputEventReceiver$Factory
-android.view.InputEventSender
-android.view.InputQueue
-android.view.InputQueue$Callback
-android.view.InputQueue$FinishedInputEventCallback
-android.view.KeyCharacterMap
-android.view.KeyCharacterMap$1
-android.view.KeyCharacterMap$FallbackAction
-android.view.KeyEvent
-android.view.KeyEvent$1
-android.view.KeyEvent$Callback
-android.view.KeyEvent$DispatcherState
-android.view.KeyboardShortcutGroup
-android.view.KeyboardShortcutGroup$1
-android.view.KeyboardShortcutInfo
-android.view.KeyboardShortcutInfo$1
-android.view.LayoutInflater
-android.view.LayoutInflater$Factory
-android.view.LayoutInflater$Factory2
-android.view.LayoutInflater$FactoryMerger
-android.view.LayoutInflater$Filter
-android.view.MagnificationSpec
-android.view.Menu
-android.view.MenuInflater
-android.view.MenuInflater$MenuState
-android.view.MenuItem
-android.view.MenuItem$OnActionExpandListener
-android.view.MenuItem$OnMenuItemClickListener
-android.view.MotionEvent
-android.view.MotionEvent$1
-android.view.MotionEvent$PointerCoords
-android.view.MotionEvent$PointerProperties
-android.view.NotificationHeaderView
-android.view.NotificationHeaderView$1
-android.view.NotificationHeaderView$HeaderTouchListener
-android.view.OrientationEventListener
-android.view.OrientationEventListener$SensorEventListenerImpl
-android.view.PointerIcon
-android.view.PointerIcon$1
-android.view.RecordingCanvas
-android.view.RemotableViewMethod
-android.view.RenderNode
-android.view.RenderNode$NoImagePreloadHolder
-android.view.RenderNodeAnimator
-android.view.RenderNodeAnimator$1
-android.view.RenderNodeAnimatorSetHelper
-android.view.ScaleGestureDetector
-android.view.ScaleGestureDetector$1
-android.view.ScaleGestureDetector$OnScaleGestureListener
-android.view.ScaleGestureDetector$SimpleOnScaleGestureListener
-android.view.SearchEvent
-android.view.SubMenu
-android.view.Surface
-android.view.Surface$1
-android.view.Surface$CompatibleCanvas
-android.view.Surface$OutOfResourcesException
-android.view.SurfaceControl
-android.view.SurfaceControl$PhysicalDisplayInfo
-android.view.SurfaceHolder
-android.view.SurfaceHolder$Callback
-android.view.SurfaceHolder$Callback2
-android.view.SurfaceSession
-android.view.SurfaceView
-android.view.SurfaceView$1
-android.view.SurfaceView$2
-android.view.SurfaceView$3
-android.view.SurfaceView$4
-android.view.TextureView
-android.view.TextureView$1
-android.view.TextureView$SurfaceTextureListener
-android.view.ThreadedRenderer
-android.view.ThreadedRenderer$DrawCallbacks
-android.view.ThreadedRenderer$ProcessInitializer
-android.view.ThreadedRenderer$ProcessInitializer$1
-android.view.TouchDelegate
-android.view.VelocityTracker
-android.view.VelocityTracker$Estimator
-android.view.View
-android.view.View$1
-android.view.View$10
-android.view.View$11
-android.view.View$12
-android.view.View$2
-android.view.View$3
-android.view.View$4
-android.view.View$5
-android.view.View$6
-android.view.View$7
-android.view.View$8
-android.view.View$9
-android.view.View$AccessibilityDelegate
-android.view.View$AttachInfo
-android.view.View$AttachInfo$Callbacks
-android.view.View$BaseSavedState
-android.view.View$BaseSavedState$1
-android.view.View$CheckForLongPress
-android.view.View$CheckForTap
-android.view.View$DeclaredOnClickListener
-android.view.View$ForegroundInfo
-android.view.View$ListenerInfo
-android.view.View$MatchIdPredicate
-android.view.View$MeasureSpec
-android.view.View$OnApplyWindowInsetsListener
-android.view.View$OnAttachStateChangeListener
-android.view.View$OnClickListener
-android.view.View$OnCreateContextMenuListener
-android.view.View$OnDragListener
-android.view.View$OnFocusChangeListener
-android.view.View$OnGenericMotionListener
-android.view.View$OnHoverListener
-android.view.View$OnKeyListener
-android.view.View$OnLayoutChangeListener
-android.view.View$OnLongClickListener
-android.view.View$OnScrollChangeListener
-android.view.View$OnSystemUiVisibilityChangeListener
-android.view.View$OnTouchListener
-android.view.View$PerformClick
-android.view.View$ScrollabilityCache
-android.view.View$TintInfo
-android.view.View$TooltipInfo
-android.view.View$TransformationInfo
-android.view.View$UnsetPressedState
-android.view.View$VisibilityChangeForAutofillHandler
-android.view.ViewAnimationUtils
-android.view.ViewConfiguration
-android.view.ViewDebug$CapturedViewProperty
-android.view.ViewDebug$ExportedProperty
-android.view.ViewDebug$HierarchyHandler
-android.view.ViewGroup
-android.view.ViewGroup$1
-android.view.ViewGroup$2
-android.view.ViewGroup$3
-android.view.ViewGroup$4
-android.view.ViewGroup$ChildListForAutoFill
-android.view.ViewGroup$LayoutParams
-android.view.ViewGroup$MarginLayoutParams
-android.view.ViewGroup$OnHierarchyChangeListener
-android.view.ViewGroup$TouchTarget
-android.view.ViewGroupOverlay
-android.view.ViewManager
-android.view.ViewOutlineProvider
-android.view.ViewOutlineProvider$1
-android.view.ViewOutlineProvider$2
-android.view.ViewOutlineProvider$3
-android.view.ViewOverlay
-android.view.ViewOverlay$OverlayViewGroup
-android.view.ViewParent
-android.view.ViewPropertyAnimator
-android.view.ViewPropertyAnimator$1
-android.view.ViewPropertyAnimator$2
-android.view.ViewPropertyAnimator$3
-android.view.ViewPropertyAnimator$AnimatorEventListener
-android.view.ViewPropertyAnimator$NameValuesHolder
-android.view.ViewPropertyAnimator$PropertyBundle
-android.view.ViewRootImpl
-android.view.ViewRootImpl$1
-android.view.ViewRootImpl$2
-android.view.ViewRootImpl$4
-android.view.ViewRootImpl$AccessibilityInteractionConnectionManager
-android.view.ViewRootImpl$ActivityConfigCallback
-android.view.ViewRootImpl$AsyncInputStage
-android.view.ViewRootImpl$ConfigChangedCallback
-android.view.ViewRootImpl$ConsumeBatchedInputImmediatelyRunnable
-android.view.ViewRootImpl$ConsumeBatchedInputRunnable
-android.view.ViewRootImpl$EarlyPostImeInputStage
-android.view.ViewRootImpl$HighContrastTextManager
-android.view.ViewRootImpl$ImeInputStage
-android.view.ViewRootImpl$InputStage
-android.view.ViewRootImpl$InvalidateOnAnimationRunnable
-android.view.ViewRootImpl$NativePostImeInputStage
-android.view.ViewRootImpl$NativePreImeInputStage
-android.view.ViewRootImpl$QueuedInputEvent
-android.view.ViewRootImpl$SyntheticInputStage
-android.view.ViewRootImpl$SyntheticJoystickHandler
-android.view.ViewRootImpl$SyntheticKeyboardHandler
-android.view.ViewRootImpl$SyntheticTouchNavigationHandler
-android.view.ViewRootImpl$SyntheticTouchNavigationHandler$1
-android.view.ViewRootImpl$SyntheticTrackballHandler
-android.view.ViewRootImpl$SystemUiVisibilityInfo
-android.view.ViewRootImpl$TrackballAxis
-android.view.ViewRootImpl$TraversalRunnable
-android.view.ViewRootImpl$ViewPostImeInputStage
-android.view.ViewRootImpl$ViewPreImeInputStage
-android.view.ViewRootImpl$ViewRootHandler
-android.view.ViewRootImpl$W
-android.view.ViewRootImpl$WindowInputEventReceiver
-android.view.ViewRootImpl$WindowStoppedCallback
-android.view.ViewStructure
-android.view.ViewStructure$HtmlInfo
-android.view.ViewStub
-android.view.ViewStub$OnInflateListener
-android.view.ViewStub$ViewReplaceRunnable
-android.view.ViewTreeObserver
-android.view.ViewTreeObserver$CopyOnWriteArray
-android.view.ViewTreeObserver$CopyOnWriteArray$Access
-android.view.ViewTreeObserver$InternalInsetsInfo
-android.view.ViewTreeObserver$OnComputeInternalInsetsListener
-android.view.ViewTreeObserver$OnDrawListener
-android.view.ViewTreeObserver$OnGlobalFocusChangeListener
-android.view.ViewTreeObserver$OnGlobalLayoutListener
-android.view.ViewTreeObserver$OnPreDrawListener
-android.view.ViewTreeObserver$OnScrollChangedListener
-android.view.ViewTreeObserver$OnTouchModeChangeListener
-android.view.Window
-android.view.Window$Callback
-android.view.Window$OnWindowDismissedCallback
-android.view.Window$OnWindowSwipeDismissedCallback
-android.view.Window$WindowControllerCallback
-android.view.WindowAnimationFrameStats
-android.view.WindowAnimationFrameStats$1
-android.view.WindowCallbackWrapper
-android.view.WindowCallbacks
-android.view.WindowContentFrameStats
-android.view.WindowContentFrameStats$1
-android.view.WindowId
-android.view.WindowId$1
-android.view.WindowInsets
-android.view.WindowLeaked
-android.view.WindowManager
-android.view.WindowManager$BadTokenException
-android.view.WindowManager$InvalidDisplayException
-android.view.WindowManager$KeyboardShortcutsReceiver
-android.view.WindowManager$LayoutParams
-android.view.WindowManager$LayoutParams$1
-android.view.WindowManagerGlobal
-android.view.WindowManagerGlobal$1
-android.view.WindowManagerGlobal$2
-android.view.WindowManagerImpl
-android.view.WindowManagerInternal
-android.view.WindowManagerInternal$AppTransitionListener
-android.view.WindowManagerInternal$MagnificationCallbacks
-android.view.WindowManagerInternal$OnHardKeyboardStatusChangeListener
-android.view.WindowManagerInternal$WindowsForAccessibilityCallback
-android.view.WindowManagerPolicy
-android.view.WindowManagerPolicy$InputConsumer
-android.view.WindowManagerPolicy$OnKeyguardExitResult
-android.view.WindowManagerPolicy$PointerEventListener
-android.view.WindowManagerPolicy$ScreenOffListener
-android.view.WindowManagerPolicy$ScreenOnListener
-android.view.WindowManagerPolicy$StartingSurface
-android.view.WindowManagerPolicy$WindowManagerFuncs
-android.view.WindowManagerPolicy$WindowState
-android.view.accessibility.AccessibilityEvent
-android.view.accessibility.AccessibilityEvent$1
-android.view.accessibility.AccessibilityEventSource
-android.view.accessibility.AccessibilityManager
-android.view.accessibility.AccessibilityManager$1
-android.view.accessibility.AccessibilityManager$AccessibilityServicesStateChangeListener
-android.view.accessibility.AccessibilityManager$AccessibilityStateChangeListener
-android.view.accessibility.AccessibilityManager$HighTextContrastChangeListener
-android.view.accessibility.AccessibilityManager$MyCallback
-android.view.accessibility.AccessibilityManager$TouchExplorationStateChangeListener
-android.view.accessibility.AccessibilityNodeInfo
-android.view.accessibility.AccessibilityNodeInfo$AccessibilityAction
-android.view.accessibility.AccessibilityNodeProvider
-android.view.accessibility.AccessibilityRecord
-android.view.accessibility.CaptioningManager
-android.view.accessibility.CaptioningManager$1
-android.view.accessibility.CaptioningManager$CaptionStyle
-android.view.accessibility.CaptioningManager$CaptioningChangeListener
-android.view.accessibility.CaptioningManager$MyContentObserver
-android.view.accessibility.IAccessibilityInteractionConnection
-android.view.accessibility.IAccessibilityInteractionConnection$Stub
-android.view.accessibility.IAccessibilityInteractionConnection$Stub$Proxy
-android.view.accessibility.IAccessibilityInteractionConnectionCallback
-android.view.accessibility.IAccessibilityManager
-android.view.accessibility.IAccessibilityManager$Stub
-android.view.accessibility.IAccessibilityManager$Stub$Proxy
-android.view.accessibility.IAccessibilityManagerClient
-android.view.accessibility.IAccessibilityManagerClient$Stub
-android.view.accessibility.IAccessibilityManagerClient$Stub$Proxy
-android.view.animation.AccelerateDecelerateInterpolator
-android.view.animation.AccelerateInterpolator
-android.view.animation.AlphaAnimation
-android.view.animation.Animation
-android.view.animation.Animation$1
-android.view.animation.Animation$2
-android.view.animation.Animation$3
-android.view.animation.Animation$AnimationListener
-android.view.animation.Animation$Description
-android.view.animation.Animation$NoImagePreloadHolder
-android.view.animation.AnimationSet
-android.view.animation.AnimationUtils
-android.view.animation.AnimationUtils$1
-android.view.animation.AnimationUtils$AnimationState
-android.view.animation.BaseInterpolator
-android.view.animation.ClipRectAnimation
-android.view.animation.CycleInterpolator
-android.view.animation.DecelerateInterpolator
-android.view.animation.GridLayoutAnimationController$AnimationParameters
-android.view.animation.Interpolator
-android.view.animation.LayoutAnimationController
-android.view.animation.LayoutAnimationController$AnimationParameters
-android.view.animation.LinearInterpolator
-android.view.animation.OvershootInterpolator
-android.view.animation.PathInterpolator
-android.view.animation.ScaleAnimation
-android.view.animation.Transformation
-android.view.animation.TranslateAnimation
-android.view.autofill.AutofillId
-android.view.autofill.AutofillId$1
-android.view.autofill.AutofillManager
-android.view.autofill.AutofillManager$AutofillClient
-android.view.autofill.AutofillManager$AutofillManagerClient
-android.view.autofill.AutofillValue
-android.view.autofill.AutofillValue$1
-android.view.autofill.Helper
-android.view.autofill.IAutoFillManager
-android.view.autofill.IAutoFillManager$Stub
-android.view.autofill.IAutoFillManager$Stub$Proxy
-android.view.autofill.IAutoFillManagerClient
-android.view.autofill.IAutoFillManagerClient$Stub
-android.view.autofill.IAutoFillManagerClient$Stub$Proxy
-android.view.autofill.IAutofillWindowPresenter
-android.view.inputmethod.BaseInputConnection
-android.view.inputmethod.CompletionInfo
-android.view.inputmethod.CompletionInfo$1
-android.view.inputmethod.ComposingText
-android.view.inputmethod.CorrectionInfo
-android.view.inputmethod.CursorAnchorInfo
-android.view.inputmethod.CursorAnchorInfo$Builder
-android.view.inputmethod.EditorInfo
-android.view.inputmethod.EditorInfo$1
-android.view.inputmethod.ExtractedText
-android.view.inputmethod.ExtractedText$1
-android.view.inputmethod.ExtractedTextRequest
-android.view.inputmethod.ExtractedTextRequest$1
-android.view.inputmethod.InputBinding
-android.view.inputmethod.InputBinding$1
-android.view.inputmethod.InputConnection
-android.view.inputmethod.InputConnectionInspector
-android.view.inputmethod.InputConnectionWrapper
-android.view.inputmethod.InputContentInfo
-android.view.inputmethod.InputMethod
-android.view.inputmethod.InputMethod$SessionCallback
-android.view.inputmethod.InputMethodInfo
-android.view.inputmethod.InputMethodInfo$1
-android.view.inputmethod.InputMethodManager
-android.view.inputmethod.InputMethodManager$1
-android.view.inputmethod.InputMethodManager$2
-android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper
-android.view.inputmethod.InputMethodManager$FinishedInputEventCallback
-android.view.inputmethod.InputMethodManager$H
-android.view.inputmethod.InputMethodManager$ImeInputEventSender
-android.view.inputmethod.InputMethodManager$PendingEvent
-android.view.inputmethod.InputMethodManagerInternal
-android.view.inputmethod.InputMethodSession
-android.view.inputmethod.InputMethodSession$EventCallback
-android.view.inputmethod.InputMethodSubtype
-android.view.inputmethod.InputMethodSubtype$1
-android.view.inputmethod.InputMethodSubtype$InputMethodSubtypeBuilder
-android.view.inputmethod.InputMethodSubtypeArray
-android.view.textclassifier.TextClassificationManager
-android.view.textclassifier.TextClassifier
-android.view.textclassifier.TextClassifier$1
-android.view.textclassifier.TextClassifierImpl
-android.view.textservice.SpellCheckerInfo
-android.view.textservice.SpellCheckerInfo$1
-android.view.textservice.SpellCheckerSession
-android.view.textservice.SpellCheckerSession$1
-android.view.textservice.SpellCheckerSession$InternalListener
-android.view.textservice.SpellCheckerSession$SpellCheckerSessionListener
-android.view.textservice.SpellCheckerSession$SpellCheckerSessionListenerImpl
-android.view.textservice.SpellCheckerSession$SpellCheckerSessionListenerImpl$SpellCheckerParams
-android.view.textservice.SpellCheckerSubtype
-android.view.textservice.SpellCheckerSubtype$1
-android.view.textservice.SuggestionsInfo
-android.view.textservice.TextInfo
-android.view.textservice.TextServicesManager
-android.webkit.ConsoleMessage
-android.webkit.ConsoleMessage$MessageLevel
-android.webkit.CookieManager
-android.webkit.CookieSyncManager
-android.webkit.DownloadListener
-android.webkit.GeolocationPermissions
-android.webkit.IWebViewUpdateService
-android.webkit.IWebViewUpdateService$Stub
-android.webkit.IWebViewUpdateService$Stub$Proxy
-android.webkit.JavascriptInterface
-android.webkit.MimeTypeMap
-android.webkit.ServiceWorkerClient
-android.webkit.ServiceWorkerController
-android.webkit.ServiceWorkerWebSettings
-android.webkit.TokenBindingService
-android.webkit.URLUtil
-android.webkit.UserPackage
-android.webkit.ValueCallback
-android.webkit.WebBackForwardList
-android.webkit.WebChromeClient
-android.webkit.WebChromeClient$CustomViewCallback
-android.webkit.WebIconDatabase
-android.webkit.WebMessage
-android.webkit.WebMessagePort
-android.webkit.WebResourceRequest
-android.webkit.WebSettings
-android.webkit.WebSettings$LayoutAlgorithm
-android.webkit.WebSettings$PluginState
-android.webkit.WebSettings$RenderPriority
-android.webkit.WebSettings$ZoomDensity
-android.webkit.WebStorage
-android.webkit.WebSyncManager
-android.webkit.WebView
-android.webkit.WebView$FindListener
-android.webkit.WebView$HitTestResult
-android.webkit.WebView$PictureListener
-android.webkit.WebView$PrivateAccess
-android.webkit.WebView$VisualStateCallback
-android.webkit.WebViewClient
-android.webkit.WebViewDatabase
-android.webkit.WebViewDelegate
-android.webkit.WebViewDelegate$1
-android.webkit.WebViewDelegate$OnTraceEnabledChangeListener
-android.webkit.WebViewFactory
-android.webkit.WebViewFactory$1
-android.webkit.WebViewFactory$MissingWebViewPackageException
-android.webkit.WebViewFactory$RelroFileCreator
-android.webkit.WebViewFactoryProvider
-android.webkit.WebViewFactoryProvider$Statics
-android.webkit.WebViewProvider
-android.webkit.WebViewProvider$ScrollDelegate
-android.webkit.WebViewProvider$ViewDelegate
-android.webkit.WebViewProviderInfo
-android.webkit.WebViewProviderInfo$1
-android.webkit.WebViewProviderResponse
-android.webkit.WebViewProviderResponse$1
-android.webkit.WebViewZygote
-android.widget.-$Lambda$ISuHLqeK-K4pmesAfzlFglc3xF4
-android.widget.-$Lambda$ISuHLqeK-K4pmesAfzlFglc3xF4$1
-android.widget.-$Lambda$ISuHLqeK-K4pmesAfzlFglc3xF4$2
-android.widget.-$Lambda$ISuHLqeK-K4pmesAfzlFglc3xF4$3
-android.widget.-$Lambda$tfOQKOmkDz_xLYaBQX_cysn8vbE
-android.widget.AbsListView
-android.widget.AbsListView$3
-android.widget.AbsListView$AdapterDataSetObserver
-android.widget.AbsListView$CheckForTap
-android.widget.AbsListView$FlingRunnable
-android.widget.AbsListView$FlingRunnable$1
-android.widget.AbsListView$LayoutParams
-android.widget.AbsListView$MultiChoiceModeListener
-android.widget.AbsListView$MultiChoiceModeWrapper
-android.widget.AbsListView$OnScrollListener
-android.widget.AbsListView$PerformClick
-android.widget.AbsListView$RecycleBin
-android.widget.AbsListView$RecyclerListener
-android.widget.AbsListView$SavedState
-android.widget.AbsListView$SavedState$1
-android.widget.AbsListView$SelectionBoundsAdjuster
-android.widget.AbsListView$WindowRunnnable
-android.widget.AbsSeekBar
-android.widget.AbsSpinner
-android.widget.AbsSpinner$RecycleBin
-android.widget.AbsoluteLayout
-android.widget.ActionMenuPresenter
-android.widget.ActionMenuPresenter$1
-android.widget.ActionMenuPresenter$2
-android.widget.ActionMenuPresenter$ActionMenuPopupCallback
-android.widget.ActionMenuPresenter$OverflowMenuButton
-android.widget.ActionMenuPresenter$OverflowMenuButton$1
-android.widget.ActionMenuPresenter$PopupPresenterCallback
-android.widget.ActionMenuView
-android.widget.ActionMenuView$ActionMenuChildView
-android.widget.ActionMenuView$ActionMenuPresenterCallback
-android.widget.ActionMenuView$LayoutParams
-android.widget.ActionMenuView$MenuBuilderCallback
-android.widget.ActionMenuView$OnMenuItemClickListener
-android.widget.Adapter
-android.widget.AdapterView
-android.widget.AdapterView$AdapterDataSetObserver
-android.widget.AdapterView$OnItemClickListener
-android.widget.AdapterView$OnItemLongClickListener
-android.widget.AdapterView$OnItemSelectedListener
-android.widget.AdapterView$SelectionNotifier
-android.widget.ArrayAdapter
-android.widget.AutoCompleteTextView
-android.widget.AutoCompleteTextView$DropDownItemClickListener
-android.widget.AutoCompleteTextView$MyWatcher
-android.widget.AutoCompleteTextView$PassThroughClickListener
-android.widget.AutoCompleteTextView$PopupDataSetObserver
-android.widget.AutoCompleteTextView$PopupDataSetObserver$1
-android.widget.AutoCompleteTextView$Validator
-android.widget.BaseAdapter
-android.widget.Button
-android.widget.CheckBox
-android.widget.Checkable
-android.widget.CheckedTextView
-android.widget.Chronometer
-android.widget.Chronometer$1
-android.widget.CompoundButton
-android.widget.CompoundButton$OnCheckedChangeListener
-android.widget.CursorAdapter
-android.widget.CursorFilter$CursorFilterClient
-android.widget.DatePicker
-android.widget.DateTimeView
-android.widget.DateTimeView$ReceiverInfo
-android.widget.DateTimeView$ReceiverInfo$1
-android.widget.DateTimeView$ReceiverInfo$2
-android.widget.DropDownListView
-android.widget.EdgeEffect
-android.widget.EditText
-android.widget.Editor
-android.widget.Editor$1
-android.widget.Editor$2
-android.widget.Editor$Blink
-android.widget.Editor$CursorAnchorInfoNotifier
-android.widget.Editor$CursorController
-android.widget.Editor$EditOperation
-android.widget.Editor$EditOperation$1
-android.widget.Editor$HandleView
-android.widget.Editor$InputContentType
-android.widget.Editor$InputMethodState
-android.widget.Editor$InsertionHandleView
-android.widget.Editor$InsertionHandleView$2
-android.widget.Editor$InsertionPointCursorController
-android.widget.Editor$PositionListener
-android.widget.Editor$ProcessTextIntentActionsHandler
-android.widget.Editor$SelectionModifierCursorController
-android.widget.Editor$SpanController
-android.widget.Editor$SuggestionHelper
-android.widget.Editor$SuggestionHelper$SuggestionSpanComparator
-android.widget.Editor$TextRenderNode
-android.widget.Editor$TextViewPositionListener
-android.widget.Editor$UndoInputFilter
-android.widget.ExpandableListConnector
-android.widget.FastScroller
-android.widget.FastScroller$1
-android.widget.FastScroller$2
-android.widget.FastScroller$3
-android.widget.FastScroller$4
-android.widget.FastScroller$5
-android.widget.FastScroller$6
-android.widget.Filter
-android.widget.Filter$FilterListener
-android.widget.Filter$FilterResults
-android.widget.Filter$RequestArguments
-android.widget.Filter$RequestHandler
-android.widget.Filter$ResultsHandler
-android.widget.Filterable
-android.widget.ForwardingListener
-android.widget.FrameLayout
-android.widget.FrameLayout$LayoutParams
-android.widget.GridLayout
-android.widget.GridLayout$1
-android.widget.GridLayout$2
-android.widget.GridLayout$3
-android.widget.GridLayout$4
-android.widget.GridLayout$5
-android.widget.GridLayout$6
-android.widget.GridLayout$6$1
-android.widget.GridLayout$7
-android.widget.GridLayout$8
-android.widget.GridLayout$Alignment
-android.widget.GridLayout$Arc
-android.widget.GridLayout$Assoc
-android.widget.GridLayout$Axis
-android.widget.GridLayout$Axis$1
-android.widget.GridLayout$Bounds
-android.widget.GridLayout$Interval
-android.widget.GridLayout$LayoutParams
-android.widget.GridLayout$MutableInt
-android.widget.GridLayout$PackedMap
-android.widget.GridLayout$Spec
-android.widget.GridView
-android.widget.HeaderViewListAdapter
-android.widget.HorizontalScrollView
-android.widget.HorizontalScrollView$SavedState
-android.widget.HorizontalScrollView$SavedState$1
-android.widget.ImageButton
-android.widget.ImageView
-android.widget.ImageView$ImageDrawableCallback
-android.widget.ImageView$ScaleType
-android.widget.LinearLayout
-android.widget.LinearLayout$LayoutParams
-android.widget.ListAdapter
-android.widget.ListPopupWindow
-android.widget.ListPopupWindow$2
-android.widget.ListPopupWindow$3
-android.widget.ListPopupWindow$ListSelectorHider
-android.widget.ListPopupWindow$PopupDataSetObserver
-android.widget.ListPopupWindow$PopupScrollListener
-android.widget.ListPopupWindow$PopupTouchInterceptor
-android.widget.ListPopupWindow$ResizePopupRunnable
-android.widget.ListView
-android.widget.ListView$ArrowScrollFocusResult
-android.widget.ListView$FixedViewInfo
-android.widget.MediaController
-android.widget.MediaController$MediaPlayerControl
-android.widget.MultiAutoCompleteTextView
-android.widget.MultiAutoCompleteTextView$Tokenizer
-android.widget.NumberPicker
-android.widget.NumberPicker$Formatter
-android.widget.NumberPicker$OnValueChangeListener
-android.widget.OverScroller
-android.widget.OverScroller$SplineOverScroller
-android.widget.PopupMenu
-android.widget.PopupMenu$1
-android.widget.PopupMenu$2
-android.widget.PopupMenu$3
-android.widget.PopupMenu$OnMenuItemClickListener
-android.widget.PopupWindow
-android.widget.PopupWindow$1
-android.widget.PopupWindow$2
-android.widget.PopupWindow$OnDismissListener
-android.widget.PopupWindow$PopupBackgroundView
-android.widget.PopupWindow$PopupDecorView
-android.widget.PopupWindow$PopupDecorView$1
-android.widget.ProgressBar
-android.widget.ProgressBar$1
-android.widget.ProgressBar$ProgressTintInfo
-android.widget.ProgressBar$RefreshData
-android.widget.ProgressBar$RefreshProgressRunnable
-android.widget.ProgressBar$SavedState
-android.widget.ProgressBar$SavedState$1
-android.widget.QuickContactBadge
-android.widget.QuickContactBadge$QueryHandler
-android.widget.RadioButton
-android.widget.RadioGroup
-android.widget.RadioGroup$CheckedStateTracker
-android.widget.RadioGroup$LayoutParams
-android.widget.RadioGroup$OnCheckedChangeListener
-android.widget.RadioGroup$PassThroughHierarchyChangeListener
-android.widget.RatingBar
-android.widget.RelativeLayout
-android.widget.RelativeLayout$DependencyGraph
-android.widget.RelativeLayout$DependencyGraph$Node
-android.widget.RelativeLayout$LayoutParams
-android.widget.RemoteViews
-android.widget.RemoteViews$1
-android.widget.RemoteViews$2
-android.widget.RemoteViews$3
-android.widget.RemoteViews$Action
-android.widget.RemoteViews$ActionException
-android.widget.RemoteViews$AsyncApplyTask
-android.widget.RemoteViews$BitmapCache
-android.widget.RemoteViews$BitmapReflectionAction
-android.widget.RemoteViews$LayoutParamAction
-android.widget.RemoteViews$MemoryUsageCounter
-android.widget.RemoteViews$MutablePair
-android.widget.RemoteViews$OnClickHandler
-android.widget.RemoteViews$OnViewAppliedListener
-android.widget.RemoteViews$ReflectionAction
-android.widget.RemoteViews$RemoteView
-android.widget.RemoteViews$RemoteViewsContextWrapper
-android.widget.RemoteViews$RunnableAction
-android.widget.RemoteViews$RuntimeAction
-android.widget.RemoteViews$SetDrawableParameters
-android.widget.RemoteViews$SetOnClickPendingIntent
-android.widget.RemoteViews$SetOnClickPendingIntent$1
-android.widget.RemoteViews$ViewGroupAction
-android.widget.RemoteViews$ViewGroupAction$1
-android.widget.RemoteViews$ViewGroupAction$2
-android.widget.RemoteViews$ViewPaddingAction
-android.widget.RemoteViews$ViewTree
-android.widget.RemoteViewsAdapter$RemoteAdapterConnectionCallback
-android.widget.ResourceCursorAdapter
-android.widget.RtlSpacingHelper
-android.widget.ScrollBarDrawable
-android.widget.ScrollView
-android.widget.ScrollView$SavedState
-android.widget.ScrollView$SavedState$1
-android.widget.Scroller
-android.widget.Scroller$ViscousFluidInterpolator
-android.widget.SearchView$OnCloseListener
-android.widget.SectionIndexer
-android.widget.SeekBar
-android.widget.SeekBar$OnSeekBarChangeListener
-android.widget.SelectionActionModeHelper
-android.widget.SelectionActionModeHelper$SelectionTracker
-android.widget.SelectionActionModeHelper$TextClassificationHelper
-android.widget.SimpleCursorAdapter
-android.widget.Space
-android.widget.SpellChecker
-android.widget.SpellChecker$SpellParser
-android.widget.Spinner
-android.widget.Spinner$1
-android.widget.Spinner$DialogPopup
-android.widget.Spinner$DropDownAdapter
-android.widget.Spinner$DropdownPopup
-android.widget.Spinner$DropdownPopup$1
-android.widget.Spinner$SpinnerPopup
-android.widget.SpinnerAdapter
-android.widget.Switch
-android.widget.Switch$1
-android.widget.TabHost
-android.widget.TabHost$1
-android.widget.TabHost$2
-android.widget.TabHost$ContentStrategy
-android.widget.TabHost$FactoryContentStrategy
-android.widget.TabHost$IndicatorStrategy
-android.widget.TabHost$OnTabChangeListener
-android.widget.TabHost$TabContentFactory
-android.widget.TabHost$TabSpec
-android.widget.TabHost$ViewIndicatorStrategy
-android.widget.TabWidget
-android.widget.TabWidget$OnTabSelectionChanged
-android.widget.TabWidget$TabClickListener
-android.widget.TableLayout
-android.widget.TextClock
-android.widget.TextClock$1
-android.widget.TextClock$2
-android.widget.TextClock$FormatChangeObserver
-android.widget.TextSwitcher
-android.widget.TextView
-android.widget.TextView$2
-android.widget.TextView$3
-android.widget.TextView$BufferType
-android.widget.TextView$ChangeWatcher
-android.widget.TextView$CharWrapper
-android.widget.TextView$Drawables
-android.widget.TextView$Marquee
-android.widget.TextView$Marquee$1
-android.widget.TextView$Marquee$2
-android.widget.TextView$Marquee$3
-android.widget.TextView$OnEditorActionListener
-android.widget.TextView$SavedState
-android.widget.TextView$SavedState$1
-android.widget.ThemedSpinnerAdapter
-android.widget.TimePicker
-android.widget.TimePicker$OnTimeChangedListener
-android.widget.Toast
-android.widget.Toast$TN
-android.widget.Toast$TN$1
-android.widget.ToggleButton
-android.widget.Toolbar
-android.widget.Toolbar$1
-android.widget.Toolbar$2
-android.widget.Toolbar$ExpandedActionViewMenuPresenter
-android.widget.Toolbar$LayoutParams
-android.widget.Toolbar$OnMenuItemClickListener
-android.widget.VideoView
-android.widget.ViewAnimator
-android.widget.ViewFlipper
-android.widget.ViewFlipper$1
-android.widget.ViewFlipper$2
-android.widget.ViewSwitcher
-android.widget.WrapperListAdapter
-com.android.framework.protobuf.nano.CodedInputByteBufferNano
-com.android.framework.protobuf.nano.CodedOutputByteBufferNano
-com.android.framework.protobuf.nano.InternalNano
-com.android.framework.protobuf.nano.InvalidProtocolBufferNanoException
-com.android.framework.protobuf.nano.MessageNano
-com.android.framework.protobuf.nano.WireFormatNano
-com.android.i18n.phonenumbers.AlternateFormatsCountryCodeSet
-com.android.i18n.phonenumbers.AsYouTypeFormatter
-com.android.i18n.phonenumbers.CountryCodeToRegionCodeMap
-com.android.i18n.phonenumbers.MetadataLoader
-com.android.i18n.phonenumbers.MetadataManager
-com.android.i18n.phonenumbers.MetadataManager$1
-com.android.i18n.phonenumbers.MetadataSource
-com.android.i18n.phonenumbers.MultiFileMetadataSourceImpl
-com.android.i18n.phonenumbers.NumberParseException
-com.android.i18n.phonenumbers.NumberParseException$ErrorType
-com.android.i18n.phonenumbers.PhoneNumberMatcher
-com.android.i18n.phonenumbers.PhoneNumberMatcher$State
-com.android.i18n.phonenumbers.PhoneNumberUtil
-com.android.i18n.phonenumbers.PhoneNumberUtil$1
-com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency
-com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency$1
-com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency$2
-com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency$3
-com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency$4
-com.android.i18n.phonenumbers.PhoneNumberUtil$PhoneNumberFormat
-com.android.i18n.phonenumbers.PhoneNumberUtil$PhoneNumberType
-com.android.i18n.phonenumbers.PhoneNumberUtil$ValidationResult
-com.android.i18n.phonenumbers.Phonemetadata$NumberFormat
-com.android.i18n.phonenumbers.Phonemetadata$PhoneMetadata
-com.android.i18n.phonenumbers.Phonemetadata$PhoneMetadataCollection
-com.android.i18n.phonenumbers.Phonemetadata$PhoneNumberDesc
-com.android.i18n.phonenumbers.Phonenumber$PhoneNumber
-com.android.i18n.phonenumbers.Phonenumber$PhoneNumber$CountryCodeSource
-com.android.i18n.phonenumbers.RegexCache
-com.android.i18n.phonenumbers.RegexCache$LRUCache
-com.android.i18n.phonenumbers.RegexCache$LRUCache$1
-com.android.i18n.phonenumbers.ShortNumbersRegionCodeSet
-com.android.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder
-com.android.i18n.phonenumbers.prefixmapper.MappingFileProvider
-com.android.i18n.phonenumbers.prefixmapper.PrefixFileReader
-com.android.ims.-$Lambda$AvFHcs3Z6Dq6dkOugMW9Kc7Qzng$4
-com.android.ims.ImsCall$Listener
-com.android.ims.ImsCallForwardInfo
-com.android.ims.ImsCallProfile
-com.android.ims.ImsConfig
-com.android.ims.ImsConfigListener
-com.android.ims.ImsConfigListener$Stub
-com.android.ims.ImsConnectionStateListener
-com.android.ims.ImsEcbm
-com.android.ims.ImsEcbm$ImsEcbmListenerProxy
-com.android.ims.ImsEcbmStateListener
-com.android.ims.ImsException
-com.android.ims.ImsExternalCallStateListener
-com.android.ims.ImsManager
-com.android.ims.ImsManager$1
-com.android.ims.ImsManager$ImsRegistrationListenerProxy
-com.android.ims.ImsManager$ImsServiceDeathRecipient
-com.android.ims.ImsReasonInfo
-com.android.ims.ImsReasonInfo$1
-com.android.ims.ImsSsInfo
-com.android.ims.internal.IImsCallSession
-com.android.ims.internal.IImsCallSessionListener
-com.android.ims.internal.IImsConfig
-com.android.ims.internal.IImsConfig$Stub
-com.android.ims.internal.IImsEcbm
-com.android.ims.internal.IImsEcbm$Stub
-com.android.ims.internal.IImsEcbmListener
-com.android.ims.internal.IImsEcbmListener$Stub
-com.android.ims.internal.IImsMultiEndpoint
-com.android.ims.internal.IImsRegistrationListener
-com.android.ims.internal.IImsRegistrationListener$Stub
-com.android.ims.internal.IImsService
-com.android.ims.internal.IImsService$Stub
-com.android.ims.internal.IImsServiceController
-com.android.ims.internal.IImsServiceFeatureListener
-com.android.ims.internal.IImsUt
-com.android.ims.internal.IImsUt$Stub
-com.android.ims.internal.IImsUtListener
-com.android.ims.internal.IImsUtListener$Stub
-com.android.internal.R$styleable
-com.android.internal.alsa.AlsaCardsParser
-com.android.internal.alsa.AlsaCardsParser$AlsaCardRecord
-com.android.internal.alsa.AlsaDevicesParser
-com.android.internal.alsa.LineTokenizer
-com.android.internal.app.AlertController
-com.android.internal.app.AlertController$1
-com.android.internal.app.AlertController$AlertParams
-com.android.internal.app.AlertController$AlertParams$1
-com.android.internal.app.AlertController$AlertParams$4
-com.android.internal.app.AlertController$ButtonHandler
-com.android.internal.app.AlertController$RecycleListView
-com.android.internal.app.AssistUtils
-com.android.internal.app.IAppOpsCallback
-com.android.internal.app.IAppOpsCallback$Stub
-com.android.internal.app.IAppOpsCallback$Stub$Proxy
-com.android.internal.app.IAppOpsService
-com.android.internal.app.IAppOpsService$Stub
-com.android.internal.app.IAppOpsService$Stub$Proxy
-com.android.internal.app.IAssistScreenshotReceiver
-com.android.internal.app.IBatteryStats
-com.android.internal.app.IBatteryStats$Stub
-com.android.internal.app.IBatteryStats$Stub$Proxy
-com.android.internal.app.IMediaContainerService
-com.android.internal.app.IMediaContainerService$Stub
-com.android.internal.app.IMediaContainerService$Stub$Proxy
-com.android.internal.app.ISoundTriggerService
-com.android.internal.app.ISoundTriggerService$Stub
-com.android.internal.app.IVoiceInteractionManagerService
-com.android.internal.app.IVoiceInteractionManagerService$Stub
-com.android.internal.app.IVoiceInteractionManagerService$Stub$Proxy
-com.android.internal.app.IVoiceInteractionSessionListener
-com.android.internal.app.IVoiceInteractionSessionListener$Stub
-com.android.internal.app.IVoiceInteractionSessionListener$Stub$Proxy
-com.android.internal.app.IVoiceInteractionSessionShowCallback
-com.android.internal.app.IVoiceInteractionSessionShowCallback$Stub
-com.android.internal.app.IVoiceInteractor
-com.android.internal.app.IVoiceInteractor$Stub
-com.android.internal.app.NightDisplayController
-com.android.internal.app.NightDisplayController$Callback
-com.android.internal.app.NightDisplayController$LocalTime
-com.android.internal.app.ProcessMap
-com.android.internal.app.ResolverActivity
-com.android.internal.app.ToolbarActionBar
-com.android.internal.app.ToolbarActionBar$1
-com.android.internal.app.ToolbarActionBar$2
-com.android.internal.app.ToolbarActionBar$ActionMenuPresenterCallback
-com.android.internal.app.ToolbarActionBar$MenuBuilderCallback
-com.android.internal.app.ToolbarActionBar$ToolbarCallbackWrapper
-com.android.internal.app.WindowDecorActionBar
-com.android.internal.app.WindowDecorActionBar$1
-com.android.internal.app.WindowDecorActionBar$2
-com.android.internal.app.WindowDecorActionBar$3
-com.android.internal.app.WindowDecorActionBar$ActionModeImpl
-com.android.internal.app.procstats.DurationsTable
-com.android.internal.app.procstats.IProcessStats
-com.android.internal.app.procstats.IProcessStats$Stub
-com.android.internal.app.procstats.ProcessState
-com.android.internal.app.procstats.ProcessState$1
-com.android.internal.app.procstats.ProcessStats
-com.android.internal.app.procstats.ProcessStats$1
-com.android.internal.app.procstats.ProcessStats$PackageState
-com.android.internal.app.procstats.ProcessStats$ProcessStateHolder
-com.android.internal.app.procstats.PssTable
-com.android.internal.app.procstats.ServiceState
-com.android.internal.app.procstats.SparseMappingTable
-com.android.internal.app.procstats.SparseMappingTable$Table
-com.android.internal.app.procstats.SysMemUsageTable
-com.android.internal.appwidget.IAppWidgetHost
-com.android.internal.appwidget.IAppWidgetHost$Stub
-com.android.internal.appwidget.IAppWidgetHost$Stub$Proxy
-com.android.internal.appwidget.IAppWidgetService
-com.android.internal.appwidget.IAppWidgetService$Stub
-com.android.internal.appwidget.IAppWidgetService$Stub$Proxy
-com.android.internal.backup.IBackupTransport
-com.android.internal.backup.IBackupTransport$Stub
-com.android.internal.backup.IBackupTransport$Stub$Proxy
-com.android.internal.backup.LocalTransport
-com.android.internal.backup.LocalTransportService
-com.android.internal.content.FileSystemProvider
-com.android.internal.content.NativeLibraryHelper
-com.android.internal.content.NativeLibraryHelper$Handle
-com.android.internal.content.PackageHelper
-com.android.internal.content.PackageHelper$1
-com.android.internal.content.PackageHelper$TestableInterface
-com.android.internal.content.PackageMonitor
-com.android.internal.content.ReferrerIntent
-com.android.internal.content.ReferrerIntent$1
-com.android.internal.graphics.drawable.AnimationScaleListDrawable
-com.android.internal.graphics.drawable.AnimationScaleListDrawable$AnimationScaleListState
-com.android.internal.hardware.AmbientDisplayConfiguration
-com.android.internal.inputmethod.IInputContentUriToken
-com.android.internal.inputmethod.InputMethodSubtypeHandle
-com.android.internal.inputmethod.InputMethodSubtypeSwitchingController
-com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$ControllerImpl
-com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$DynamicRotationList
-com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$ImeSubtypeListItem
-com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$InputMethodAndSubtypeList
-com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$InputMethodAndSubtypeList$1
-com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$StaticRotationList
-com.android.internal.inputmethod.InputMethodUtils
-com.android.internal.inputmethod.InputMethodUtils$1
-com.android.internal.inputmethod.InputMethodUtils$InputMethodListBuilder
-com.android.internal.inputmethod.InputMethodUtils$InputMethodSettings
-com.android.internal.inputmethod.LocaleUtils
-com.android.internal.inputmethod.LocaleUtils$LocaleExtractor
-com.android.internal.inputmethod.LocaleUtils$ScoreEntry
-com.android.internal.location.GpsNetInitiatedHandler
-com.android.internal.location.GpsNetInitiatedHandler$1
-com.android.internal.location.GpsNetInitiatedHandler$2
-com.android.internal.location.ILocationProvider
-com.android.internal.location.ILocationProvider$Stub
-com.android.internal.location.ILocationProvider$Stub$Proxy
-com.android.internal.location.ProviderProperties
-com.android.internal.location.ProviderProperties$1
-com.android.internal.location.ProviderRequest
-com.android.internal.location.ProviderRequest$1
-com.android.internal.logging.AndroidConfig
-com.android.internal.logging.AndroidHandler
-com.android.internal.logging.AndroidHandler$1
-com.android.internal.logging.EventLogTags
-com.android.internal.logging.MetricsLogger
-com.android.internal.net.LegacyVpnInfo
-com.android.internal.net.NetworkStatsFactory
-com.android.internal.net.VpnConfig
-com.android.internal.net.VpnInfo
-com.android.internal.net.VpnProfile
-com.android.internal.notification.SystemNotificationChannels
-com.android.internal.os.AndroidPrintStream
-com.android.internal.os.AppFuseMount
-com.android.internal.os.AtomicFile
-com.android.internal.os.BackgroundThread
-com.android.internal.os.BatteryStatsHelper
-com.android.internal.os.BatteryStatsImpl
-com.android.internal.os.BatteryStatsImpl$1
-com.android.internal.os.BatteryStatsImpl$6
-com.android.internal.os.BatteryStatsImpl$BatchTimer
-com.android.internal.os.BatteryStatsImpl$BatteryCallback
-com.android.internal.os.BatteryStatsImpl$Clocks
-com.android.internal.os.BatteryStatsImpl$ControllerActivityCounterImpl
-com.android.internal.os.BatteryStatsImpl$Counter
-com.android.internal.os.BatteryStatsImpl$DualTimer
-com.android.internal.os.BatteryStatsImpl$DurationTimer
-com.android.internal.os.BatteryStatsImpl$ExternalStatsSync
-com.android.internal.os.BatteryStatsImpl$LongSamplingCounter
-com.android.internal.os.BatteryStatsImpl$LongSamplingCounterArray
-com.android.internal.os.BatteryStatsImpl$MyHandler
-com.android.internal.os.BatteryStatsImpl$OverflowArrayMap
-com.android.internal.os.BatteryStatsImpl$PlatformIdleStateCallback
-com.android.internal.os.BatteryStatsImpl$SamplingTimer
-com.android.internal.os.BatteryStatsImpl$StopwatchTimer
-com.android.internal.os.BatteryStatsImpl$SystemClocks
-com.android.internal.os.BatteryStatsImpl$TimeBase
-com.android.internal.os.BatteryStatsImpl$TimeBaseObs
-com.android.internal.os.BatteryStatsImpl$Timer
-com.android.internal.os.BatteryStatsImpl$Uid
-com.android.internal.os.BatteryStatsImpl$Uid$1
-com.android.internal.os.BatteryStatsImpl$Uid$2
-com.android.internal.os.BatteryStatsImpl$Uid$3
-com.android.internal.os.BatteryStatsImpl$Uid$Pkg
-com.android.internal.os.BatteryStatsImpl$Uid$Pkg$Serv
-com.android.internal.os.BatteryStatsImpl$Uid$Sensor
-com.android.internal.os.BatteryStatsImpl$Uid$Wakelock
-com.android.internal.os.BinderInternal
-com.android.internal.os.BinderInternal$GcWatcher
-com.android.internal.os.FuseAppLoop
-com.android.internal.os.FuseAppLoop$1
-com.android.internal.os.FuseUnavailableMountException
-com.android.internal.os.HandlerCaller
-com.android.internal.os.HandlerCaller$Callback
-com.android.internal.os.HandlerCaller$MyHandler
-com.android.internal.os.IDropBoxManagerService
-com.android.internal.os.IDropBoxManagerService$Stub
-com.android.internal.os.IDropBoxManagerService$Stub$Proxy
-com.android.internal.os.IResultReceiver
-com.android.internal.os.IResultReceiver$Stub
-com.android.internal.os.IResultReceiver$Stub$Proxy
-com.android.internal.os.KernelCpuSpeedReader
-com.android.internal.os.KernelMemoryBandwidthStats
-com.android.internal.os.KernelUidCpuFreqTimeReader
-com.android.internal.os.KernelUidCpuTimeReader
-com.android.internal.os.KernelWakelockReader
-com.android.internal.os.KernelWakelockStats
-com.android.internal.os.KernelWakelockStats$Entry
-com.android.internal.os.LoggingPrintStream
-com.android.internal.os.LoggingPrintStream$1
-com.android.internal.os.PathClassLoaderFactory
-com.android.internal.os.PowerProfile
-com.android.internal.os.PowerProfile$CpuClusterKey
-com.android.internal.os.ProcessCpuTracker
-com.android.internal.os.ProcessCpuTracker$1
-com.android.internal.os.ProcessCpuTracker$FilterStats
-com.android.internal.os.ProcessCpuTracker$Stats
-com.android.internal.os.RoSystemProperties
-com.android.internal.os.RuntimeInit
-com.android.internal.os.RuntimeInit$1
-com.android.internal.os.RuntimeInit$Arguments
-com.android.internal.os.RuntimeInit$KillApplicationHandler
-com.android.internal.os.RuntimeInit$LoggingHandler
-com.android.internal.os.SamplingProfilerIntegration
-com.android.internal.os.SomeArgs
-com.android.internal.os.Zygote
-com.android.internal.os.Zygote$MethodAndArgsCaller
-com.android.internal.os.ZygoteConnection
-com.android.internal.os.ZygoteConnection$Arguments
-com.android.internal.os.ZygoteInit
-com.android.internal.os.ZygoteSecurityException
-com.android.internal.os.ZygoteServer
-com.android.internal.policy.DecorContext
-com.android.internal.policy.DecorView
-com.android.internal.policy.DecorView$1
-com.android.internal.policy.DecorView$ActionModeCallback2Wrapper
-com.android.internal.policy.DecorView$ColorViewAttributes
-com.android.internal.policy.DecorView$ColorViewState
-com.android.internal.policy.DividerSnapAlgorithm
-com.android.internal.policy.DividerSnapAlgorithm$SnapTarget
-com.android.internal.policy.DockedDividerUtils
-com.android.internal.policy.IKeyguardDismissCallback
-com.android.internal.policy.IKeyguardDrawnCallback
-com.android.internal.policy.IKeyguardDrawnCallback$Stub
-com.android.internal.policy.IKeyguardDrawnCallback$Stub$Proxy
-com.android.internal.policy.IKeyguardExitCallback
-com.android.internal.policy.IKeyguardService
-com.android.internal.policy.IKeyguardService$Stub
-com.android.internal.policy.IKeyguardService$Stub$Proxy
-com.android.internal.policy.IKeyguardStateCallback
-com.android.internal.policy.IKeyguardStateCallback$Stub
-com.android.internal.policy.IKeyguardStateCallback$Stub$Proxy
-com.android.internal.policy.IShortcutService
-com.android.internal.policy.IShortcutService$Stub
-com.android.internal.policy.IShortcutService$Stub$Proxy
-com.android.internal.policy.PhoneFallbackEventHandler
-com.android.internal.policy.PhoneLayoutInflater
-com.android.internal.policy.PhoneWindow
-com.android.internal.policy.PhoneWindow$1
-com.android.internal.policy.PhoneWindow$ActionMenuPresenterCallback
-com.android.internal.policy.PhoneWindow$PanelFeatureState
-com.android.internal.policy.PhoneWindow$PhoneWindowMenuCallback
-com.android.internal.policy.PhoneWindow$RotationWatcher
-com.android.internal.policy.PhoneWindow$RotationWatcher$1
-com.android.internal.policy.PipSnapAlgorithm
-com.android.internal.statusbar.IStatusBar
-com.android.internal.statusbar.IStatusBar$Stub
-com.android.internal.statusbar.IStatusBar$Stub$Proxy
-com.android.internal.statusbar.IStatusBarService
-com.android.internal.statusbar.IStatusBarService$Stub
-com.android.internal.statusbar.IStatusBarService$Stub$Proxy
-com.android.internal.statusbar.NotificationVisibility
-com.android.internal.statusbar.NotificationVisibility$1
-com.android.internal.statusbar.StatusBarIcon
-com.android.internal.statusbar.StatusBarIcon$1
-com.android.internal.telecom.IConnectionService
-com.android.internal.telecom.IConnectionService$Stub
-com.android.internal.telecom.IConnectionService$Stub$Proxy
-com.android.internal.telecom.IConnectionServiceAdapter
-com.android.internal.telecom.IConnectionServiceAdapter$Stub
-com.android.internal.telecom.IConnectionServiceAdapter$Stub$Proxy
-com.android.internal.telecom.IInCallAdapter
-com.android.internal.telecom.IInCallAdapter$Stub
-com.android.internal.telecom.IInCallService
-com.android.internal.telecom.IInCallService$Stub
-com.android.internal.telecom.IInCallService$Stub$Proxy
-com.android.internal.telecom.ITelecomService
-com.android.internal.telecom.ITelecomService$Stub
-com.android.internal.telecom.ITelecomService$Stub$Proxy
-com.android.internal.telecom.IVideoProvider
-com.android.internal.telecom.IVideoProvider$Stub
-com.android.internal.telecom.RemoteServiceCallback
-com.android.internal.telecom.RemoteServiceCallback$Stub
-com.android.internal.telecom.RemoteServiceCallback$Stub$Proxy
-com.android.internal.telephony.AppSmsManager
-com.android.internal.telephony.BaseCommands
-com.android.internal.telephony.Call
-com.android.internal.telephony.Call$SrvccState
-com.android.internal.telephony.Call$State
-com.android.internal.telephony.CallManager
-com.android.internal.telephony.CallManager$CallManagerHandler
-com.android.internal.telephony.CallStateException
-com.android.internal.telephony.CallTracker
-com.android.internal.telephony.CallerInfo
-com.android.internal.telephony.CallerInfoAsyncQuery
-com.android.internal.telephony.CallerInfoAsyncQuery$CallerInfoAsyncQueryHandler
-com.android.internal.telephony.CallerInfoAsyncQuery$CallerInfoAsyncQueryHandler$CallerInfoWorkerHandler
-com.android.internal.telephony.CallerInfoAsyncQuery$CookieWrapper
-com.android.internal.telephony.CallerInfoAsyncQuery$OnQueryCompleteListener
-com.android.internal.telephony.CarrierActionAgent
-com.android.internal.telephony.CarrierActionAgent$1
-com.android.internal.telephony.CarrierActionAgent$SettingsObserver
-com.android.internal.telephony.CarrierAppUtils
-com.android.internal.telephony.CarrierServiceBindHelper
-com.android.internal.telephony.CarrierServiceBindHelper$1
-com.android.internal.telephony.CarrierServiceBindHelper$2
-com.android.internal.telephony.CarrierServiceBindHelper$AppBinding
-com.android.internal.telephony.CarrierServiceBindHelper$CarrierServicePackageMonitor
-com.android.internal.telephony.CarrierServiceStateTracker
-com.android.internal.telephony.CarrierServiceStateTracker$1
-com.android.internal.telephony.CarrierSignalAgent
-com.android.internal.telephony.CarrierSignalAgent$1
-com.android.internal.telephony.CellBroadcastHandler
-com.android.internal.telephony.CellNetworkScanResult
-com.android.internal.telephony.ClientWakelockAccountant
-com.android.internal.telephony.ClientWakelockTracker
-com.android.internal.telephony.CommandException
-com.android.internal.telephony.CommandException$Error
-com.android.internal.telephony.CommandsInterface
-com.android.internal.telephony.CommandsInterface$RadioState
-com.android.internal.telephony.Connection
-com.android.internal.telephony.DctConstants$Activity
-com.android.internal.telephony.DctConstants$State
-com.android.internal.telephony.DebugService
-com.android.internal.telephony.DefaultPhoneNotifier
-com.android.internal.telephony.DeviceStateMonitor
-com.android.internal.telephony.DeviceStateMonitor$1
-com.android.internal.telephony.DeviceStateMonitor$2
-com.android.internal.telephony.EncodeException
-com.android.internal.telephony.GsmAlphabet
-com.android.internal.telephony.GsmAlphabet$TextEncodingDetails
-com.android.internal.telephony.GsmCdmaCall
-com.android.internal.telephony.GsmCdmaCallTracker
-com.android.internal.telephony.GsmCdmaCallTracker$1
-com.android.internal.telephony.GsmCdmaConnection
-com.android.internal.telephony.GsmCdmaPhone
-com.android.internal.telephony.GsmCdmaPhone$1
-com.android.internal.telephony.GsmCdmaPhone$2
-com.android.internal.telephony.HardwareConfig
-com.android.internal.telephony.ICarrierConfigLoader
-com.android.internal.telephony.ICarrierConfigLoader$Stub
-com.android.internal.telephony.ICarrierConfigLoader$Stub$Proxy
-com.android.internal.telephony.IIccPhoneBook
-com.android.internal.telephony.IIccPhoneBook$Stub
-com.android.internal.telephony.IMms
-com.android.internal.telephony.IMms$Stub
-com.android.internal.telephony.IOnSubscriptionsChangedListener
-com.android.internal.telephony.IOnSubscriptionsChangedListener$Stub
-com.android.internal.telephony.IOnSubscriptionsChangedListener$Stub$Proxy
-com.android.internal.telephony.IPhoneStateListener
-com.android.internal.telephony.IPhoneStateListener$Stub
-com.android.internal.telephony.IPhoneStateListener$Stub$Proxy
-com.android.internal.telephony.IPhoneSubInfo
-com.android.internal.telephony.IPhoneSubInfo$Stub
-com.android.internal.telephony.IPhoneSubInfo$Stub$Proxy
-com.android.internal.telephony.ISms
-com.android.internal.telephony.ISms$Stub
-com.android.internal.telephony.ISms$Stub$Proxy
-com.android.internal.telephony.ISub
-com.android.internal.telephony.ISub$Stub
-com.android.internal.telephony.ISub$Stub$Proxy
-com.android.internal.telephony.ITelephony
-com.android.internal.telephony.ITelephony$Stub
-com.android.internal.telephony.ITelephony$Stub$Proxy
-com.android.internal.telephony.ITelephonyRegistry
-com.android.internal.telephony.ITelephonyRegistry$Stub
-com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy
-com.android.internal.telephony.IWapPushManager
-com.android.internal.telephony.IccCard
-com.android.internal.telephony.IccCardConstants$State
-com.android.internal.telephony.IccPhoneBookInterfaceManager
-com.android.internal.telephony.IccPhoneBookInterfaceManager$1
-com.android.internal.telephony.IccProvider
-com.android.internal.telephony.IccSmsInterfaceManager
-com.android.internal.telephony.IccSmsInterfaceManager$1
-com.android.internal.telephony.IccSmsInterfaceManager$CdmaBroadcastRangeManager
-com.android.internal.telephony.IccSmsInterfaceManager$CellBroadcastRangeManager
-com.android.internal.telephony.ImsSMSDispatcher
-com.android.internal.telephony.InboundSmsHandler
-com.android.internal.telephony.InboundSmsHandler$1
-com.android.internal.telephony.InboundSmsHandler$DefaultState
-com.android.internal.telephony.InboundSmsHandler$DeliveringState
-com.android.internal.telephony.InboundSmsHandler$IdleState
-com.android.internal.telephony.InboundSmsHandler$NewMessageNotificationActionReceiver
-com.android.internal.telephony.InboundSmsHandler$StartupState
-com.android.internal.telephony.InboundSmsHandler$WaitingState
-com.android.internal.telephony.IntRangeManager
-com.android.internal.telephony.OemHookIndication
-com.android.internal.telephony.OemHookResponse
-com.android.internal.telephony.OperatorInfo
-com.android.internal.telephony.Phone
-com.android.internal.telephony.Phone$1
-com.android.internal.telephony.PhoneConstantConversions
-com.android.internal.telephony.PhoneConstants$DataState
-com.android.internal.telephony.PhoneConstants$State
-com.android.internal.telephony.PhoneFactory
-com.android.internal.telephony.PhoneInternalInterface
-com.android.internal.telephony.PhoneInternalInterface$DataActivityState
-com.android.internal.telephony.PhoneNotifier
-com.android.internal.telephony.PhoneSubInfoController
-com.android.internal.telephony.PhoneSwitcher
-com.android.internal.telephony.PhoneSwitcher$1
-com.android.internal.telephony.PhoneSwitcher$2
-com.android.internal.telephony.PhoneSwitcher$PhoneState
-com.android.internal.telephony.PhoneSwitcher$PhoneSwitcherNetworkRequestListener
-com.android.internal.telephony.ProxyController
-com.android.internal.telephony.ProxyController$1
-com.android.internal.telephony.RIL
-com.android.internal.telephony.RIL$RadioProxyDeathRecipient
-com.android.internal.telephony.RIL$RilHandler
-com.android.internal.telephony.RILConstants
-com.android.internal.telephony.RILRequest
-com.android.internal.telephony.RadioCapability
-com.android.internal.telephony.RadioIndication
-com.android.internal.telephony.RadioResponse
-com.android.internal.telephony.RatRatcheter
-com.android.internal.telephony.RatRatcheter$1
-com.android.internal.telephony.RestrictedState
-com.android.internal.telephony.RetryManager
-com.android.internal.telephony.RilWakelockInfo
-com.android.internal.telephony.SMSDispatcher
-com.android.internal.telephony.SMSDispatcher$SettingsObserver
-com.android.internal.telephony.ServiceStateTracker
-com.android.internal.telephony.ServiceStateTracker$1
-com.android.internal.telephony.ServiceStateTracker$2
-com.android.internal.telephony.ServiceStateTracker$3
-com.android.internal.telephony.ServiceStateTracker$CellInfoResult
-com.android.internal.telephony.ServiceStateTracker$SstSubscriptionsChangedListener
-com.android.internal.telephony.SimActivationTracker
-com.android.internal.telephony.SimActivationTracker$1
-com.android.internal.telephony.SmsApplication
-com.android.internal.telephony.SmsApplication$SmsApplicationData
-com.android.internal.telephony.SmsApplication$SmsPackageMonitor
-com.android.internal.telephony.SmsBroadcastUndelivered
-com.android.internal.telephony.SmsBroadcastUndelivered$1
-com.android.internal.telephony.SmsBroadcastUndelivered$ScanRawTableThread
-com.android.internal.telephony.SmsMessageBase
-com.android.internal.telephony.SmsStorageMonitor
-com.android.internal.telephony.SmsStorageMonitor$1
-com.android.internal.telephony.SmsUsageMonitor
-com.android.internal.telephony.SmsUsageMonitor$SettingsObserver
-com.android.internal.telephony.SmsUsageMonitor$SettingsObserverHandler
-com.android.internal.telephony.SubscriptionController
-com.android.internal.telephony.SubscriptionController$ScLocalLog
-com.android.internal.telephony.SubscriptionInfoUpdater
-com.android.internal.telephony.SubscriptionInfoUpdater$1
-com.android.internal.telephony.SubscriptionInfoUpdater$2
-com.android.internal.telephony.SubscriptionMonitor
-com.android.internal.telephony.SubscriptionMonitor$1
-com.android.internal.telephony.SubscriptionMonitor$2
-com.android.internal.telephony.TelephonyCapabilities
-com.android.internal.telephony.TelephonyComponentFactory
-com.android.internal.telephony.TelephonyDevController
-com.android.internal.telephony.TelephonyTester
-com.android.internal.telephony.TelephonyTester$1
-com.android.internal.telephony.UiccPhoneBookController
-com.android.internal.telephony.UiccSmsController
-com.android.internal.telephony.WakeLockStateMachine
-com.android.internal.telephony.WakeLockStateMachine$1
-com.android.internal.telephony.WakeLockStateMachine$DefaultState
-com.android.internal.telephony.WakeLockStateMachine$IdleState
-com.android.internal.telephony.WakeLockStateMachine$WaitingState
-com.android.internal.telephony.WapPushOverSms
-com.android.internal.telephony.WapPushOverSms$1
-com.android.internal.telephony.WapPushOverSms$BindServiceThread
-com.android.internal.telephony.cat.AppInterface
-com.android.internal.telephony.cat.CatLog
-com.android.internal.telephony.cat.CatService
-com.android.internal.telephony.cdma.CdmaInboundSmsHandler
-com.android.internal.telephony.cdma.CdmaSMSDispatcher
-com.android.internal.telephony.cdma.CdmaServiceCategoryProgramHandler
-com.android.internal.telephony.cdma.CdmaServiceCategoryProgramHandler$1
-com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager
-com.android.internal.telephony.cdma.EriInfo
-com.android.internal.telephony.cdma.EriManager
-com.android.internal.telephony.cdma.EriManager$EriFile
-com.android.internal.telephony.dataconnection.ApnContext
-com.android.internal.telephony.dataconnection.DataConnection
-com.android.internal.telephony.dataconnection.DataEnabledSettings
-com.android.internal.telephony.dataconnection.DcController
-com.android.internal.telephony.dataconnection.DcController$1
-com.android.internal.telephony.dataconnection.DcController$DccDefaultState
-com.android.internal.telephony.dataconnection.DcFailBringUp
-com.android.internal.telephony.dataconnection.DcFailCause
-com.android.internal.telephony.dataconnection.DcRequest
-com.android.internal.telephony.dataconnection.DcTesterDeactivateAll
-com.android.internal.telephony.dataconnection.DcTesterDeactivateAll$1
-com.android.internal.telephony.dataconnection.DcTesterFailBringUpAll
-com.android.internal.telephony.dataconnection.DcTesterFailBringUpAll$1
-com.android.internal.telephony.dataconnection.DcTracker
-com.android.internal.telephony.dataconnection.DcTracker$1
-com.android.internal.telephony.dataconnection.DcTracker$2
-com.android.internal.telephony.dataconnection.DcTracker$3
-com.android.internal.telephony.dataconnection.DcTracker$4
-com.android.internal.telephony.dataconnection.DcTracker$ApnChangeObserver
-com.android.internal.telephony.dataconnection.DcTracker$DataAllowFailReason
-com.android.internal.telephony.dataconnection.DcTracker$DataAllowFailReasonType
-com.android.internal.telephony.dataconnection.DcTracker$RetryFailures
-com.android.internal.telephony.dataconnection.DcTracker$SettingsObserver
-com.android.internal.telephony.dataconnection.DcTracker$TxRxSum
-com.android.internal.telephony.dataconnection.TelephonyNetworkFactory
-com.android.internal.telephony.dataconnection.TelephonyNetworkFactory$InternalHandler
-com.android.internal.telephony.gsm.GsmCellBroadcastHandler
-com.android.internal.telephony.gsm.GsmInboundSmsHandler
-com.android.internal.telephony.gsm.GsmSMSDispatcher
-com.android.internal.telephony.gsm.SmsMessage
-com.android.internal.telephony.gsm.UsimDataDownloadHandler
-com.android.internal.telephony.ims.-$Lambda$6hDwuvYxqWrzW_Ex5wc53XnUOpg
-com.android.internal.telephony.ims.-$Lambda$6hDwuvYxqWrzW_Ex5wc53XnUOpg$1
-com.android.internal.telephony.ims.-$Lambda$6hDwuvYxqWrzW_Ex5wc53XnUOpg$2
-com.android.internal.telephony.ims.ImsResolver
-com.android.internal.telephony.ims.ImsResolver$1
-com.android.internal.telephony.ims.ImsResolver$2
-com.android.internal.telephony.ims.ImsResolver$3
-com.android.internal.telephony.ims.ImsResolver$ImsServiceControllerFactory
-com.android.internal.telephony.ims.ImsResolver$SubscriptionManagerProxy
-com.android.internal.telephony.ims.ImsServiceController$ImsServiceControllerCallbacks
-com.android.internal.telephony.imsphone.-$Lambda$tILLuSJl16qfDJK1ikBVGFm2D5w
-com.android.internal.telephony.imsphone.-$Lambda$tILLuSJl16qfDJK1ikBVGFm2D5w$1
-com.android.internal.telephony.imsphone.ImsExternalCallTracker
-com.android.internal.telephony.imsphone.ImsExternalCallTracker$1
-com.android.internal.telephony.imsphone.ImsExternalCallTracker$2
-com.android.internal.telephony.imsphone.ImsExternalCallTracker$ExternalCallStateListener
-com.android.internal.telephony.imsphone.ImsExternalCallTracker$ExternalConnectionListener
-com.android.internal.telephony.imsphone.ImsExternalCallTracker$ImsCallNotify
-com.android.internal.telephony.imsphone.ImsExternalConnection$Listener
-com.android.internal.telephony.imsphone.ImsPhone
-com.android.internal.telephony.imsphone.ImsPhone$1
-com.android.internal.telephony.imsphone.ImsPhone$2
-com.android.internal.telephony.imsphone.ImsPhone$3
-com.android.internal.telephony.imsphone.ImsPhoneBase
-com.android.internal.telephony.imsphone.ImsPhoneCall
-com.android.internal.telephony.imsphone.ImsPhoneCallTracker
-com.android.internal.telephony.imsphone.ImsPhoneCallTracker$1
-com.android.internal.telephony.imsphone.ImsPhoneCallTracker$2
-com.android.internal.telephony.imsphone.ImsPhoneCallTracker$3
-com.android.internal.telephony.imsphone.ImsPhoneCallTracker$4
-com.android.internal.telephony.imsphone.ImsPhoneCallTracker$5
-com.android.internal.telephony.imsphone.ImsPhoneCallTracker$IRetryTimeout
-com.android.internal.telephony.imsphone.ImsPhoneCallTracker$PhoneStateListener
-com.android.internal.telephony.imsphone.ImsPhoneCommandInterface
-com.android.internal.telephony.imsphone.ImsPhoneFactory
-com.android.internal.telephony.imsphone.ImsPullCall
-com.android.internal.telephony.metrics.CallSessionEventBuilder
-com.android.internal.telephony.metrics.InProgressCallSession
-com.android.internal.telephony.metrics.InProgressSmsSession
-com.android.internal.telephony.metrics.SmsSessionEventBuilder
-com.android.internal.telephony.metrics.TelephonyEventBuilder
-com.android.internal.telephony.metrics.TelephonyMetrics
-com.android.internal.telephony.nano.TelephonyProto$ImsCapabilities
-com.android.internal.telephony.nano.TelephonyProto$ImsConnectionState
-com.android.internal.telephony.nano.TelephonyProto$ImsReasonInfo
-com.android.internal.telephony.nano.TelephonyProto$RilDataCall
-com.android.internal.telephony.nano.TelephonyProto$SmsSession$Event
-com.android.internal.telephony.nano.TelephonyProto$TelephonyCallSession$Event
-com.android.internal.telephony.nano.TelephonyProto$TelephonyCallSession$Event$RilCall
-com.android.internal.telephony.nano.TelephonyProto$TelephonyEvent
-com.android.internal.telephony.nano.TelephonyProto$TelephonyServiceState
-com.android.internal.telephony.nano.TelephonyProto$TelephonyServiceState$TelephonyOperator
-com.android.internal.telephony.nano.TelephonyProto$TelephonySettings
-com.android.internal.telephony.protobuf.nano.CodedOutputByteBufferNano
-com.android.internal.telephony.protobuf.nano.ExtendableMessageNano
-com.android.internal.telephony.protobuf.nano.InternalNano
-com.android.internal.telephony.protobuf.nano.InvalidProtocolBufferNanoException
-com.android.internal.telephony.protobuf.nano.MessageNano
-com.android.internal.telephony.protobuf.nano.WireFormatNano
-com.android.internal.telephony.test.SimulatedRadioControl
-com.android.internal.telephony.uicc.IccCardApplicationStatus
-com.android.internal.telephony.uicc.IccCardApplicationStatus$AppType
-com.android.internal.telephony.uicc.IccCardProxy
-com.android.internal.telephony.uicc.IccCardStatus
-com.android.internal.telephony.uicc.IccCardStatus$CardState
-com.android.internal.telephony.uicc.IccCardStatus$PinState
-com.android.internal.telephony.uicc.IccConstants
-com.android.internal.telephony.uicc.IccRecords
-com.android.internal.telephony.uicc.IccUtils
-com.android.internal.telephony.uicc.UiccCard
-com.android.internal.telephony.uicc.UiccCard$1
-com.android.internal.telephony.uicc.UiccCardApplication
-com.android.internal.telephony.uicc.UiccController
-com.android.internal.telephony.uicc.UiccStateChangedLauncher
-com.android.internal.telephony.util.NotificationChannelController
-com.android.internal.telephony.util.NotificationChannelController$1
-com.android.internal.textservice.ISpellCheckerService
-com.android.internal.textservice.ISpellCheckerService$Stub
-com.android.internal.textservice.ISpellCheckerService$Stub$Proxy
-com.android.internal.textservice.ISpellCheckerServiceCallback
-com.android.internal.textservice.ISpellCheckerServiceCallback$Stub
-com.android.internal.textservice.ISpellCheckerServiceCallback$Stub$Proxy
-com.android.internal.textservice.ISpellCheckerSession
-com.android.internal.textservice.ISpellCheckerSession$Stub
-com.android.internal.textservice.ISpellCheckerSession$Stub$Proxy
-com.android.internal.textservice.ISpellCheckerSessionListener
-com.android.internal.textservice.ISpellCheckerSessionListener$Stub
-com.android.internal.textservice.ISpellCheckerSessionListener$Stub$Proxy
-com.android.internal.textservice.ITextServicesManager
-com.android.internal.textservice.ITextServicesManager$Stub
-com.android.internal.textservice.ITextServicesManager$Stub$Proxy
-com.android.internal.textservice.ITextServicesSessionListener
-com.android.internal.textservice.ITextServicesSessionListener$Stub
-com.android.internal.textservice.ITextServicesSessionListener$Stub$Proxy
-com.android.internal.transition.EpicenterTranslateClipReveal
-com.android.internal.transition.TransitionConstants
-com.android.internal.util.ArrayUtils
-com.android.internal.util.AsyncChannel
-com.android.internal.util.AsyncChannel$AsyncChannelConnection
-com.android.internal.util.AsyncChannel$DeathMonitor
-com.android.internal.util.AsyncChannel$SyncMessenger
-com.android.internal.util.AsyncChannel$SyncMessenger$SyncHandler
-com.android.internal.util.BitUtils
-com.android.internal.util.CollectionUtils
-com.android.internal.util.ConcurrentUtils
-com.android.internal.util.ConcurrentUtils$1
-com.android.internal.util.ConcurrentUtils$1$1
-com.android.internal.util.DumpUtils$Dump
-com.android.internal.util.ExponentiallyBucketedHistogram
-com.android.internal.util.FastMath
-com.android.internal.util.FastPrintWriter
-com.android.internal.util.FastPrintWriter$DummyWriter
-com.android.internal.util.FastXmlSerializer
-com.android.internal.util.FileRotator
-com.android.internal.util.FileRotator$FileInfo
-com.android.internal.util.FileRotator$Reader
-com.android.internal.util.FileRotator$Rewriter
-com.android.internal.util.FileRotator$Writer
-com.android.internal.util.GrowingArrayUtils
-com.android.internal.util.HexDump
-com.android.internal.util.IState
-com.android.internal.util.ImageUtils
-com.android.internal.util.IndentingPrintWriter
-com.android.internal.util.IntPair
-com.android.internal.util.JournaledFile
-com.android.internal.util.LineBreakBufferedWriter
-com.android.internal.util.LocalLog
-com.android.internal.util.MemInfoReader
-com.android.internal.util.MessageUtils
-com.android.internal.util.NotificationColorUtil
-com.android.internal.util.NotificationColorUtil$ColorUtilsFromCompat
-com.android.internal.util.NotificationMessagingUtil
-com.android.internal.util.NotificationMessagingUtil$1
-com.android.internal.util.Preconditions
-com.android.internal.util.ProcFileReader
-com.android.internal.util.ProgressReporter
-com.android.internal.util.RingBufferIndices
-com.android.internal.util.ScreenShapeHelper
-com.android.internal.util.State
-com.android.internal.util.StateMachine
-com.android.internal.util.StateMachine$LogRec
-com.android.internal.util.StateMachine$LogRecords
-com.android.internal.util.StateMachine$SmHandler
-com.android.internal.util.StateMachine$SmHandler$HaltingState
-com.android.internal.util.StateMachine$SmHandler$QuittingState
-com.android.internal.util.StateMachine$SmHandler$StateInfo
-com.android.internal.util.ToBooleanFunction
-com.android.internal.util.TokenBucket
-com.android.internal.util.VirtualRefBasePtr
-com.android.internal.util.WakeupMessage
-com.android.internal.util.XmlUtils
-com.android.internal.util.XmlUtils$ReadMapCallback
-com.android.internal.util.XmlUtils$WriteMapCallback
-com.android.internal.view.ActionBarPolicy
-com.android.internal.view.BaseIWindow
-com.android.internal.view.BaseSurfaceHolder
-com.android.internal.view.IInputConnectionWrapper
-com.android.internal.view.IInputConnectionWrapper$MyHandler
-com.android.internal.view.IInputContext
-com.android.internal.view.IInputContext$Stub
-com.android.internal.view.IInputContext$Stub$Proxy
-com.android.internal.view.IInputContextCallback
-com.android.internal.view.IInputContextCallback$Stub
-com.android.internal.view.IInputContextCallback$Stub$Proxy
-com.android.internal.view.IInputMethod
-com.android.internal.view.IInputMethod$Stub
-com.android.internal.view.IInputMethod$Stub$Proxy
-com.android.internal.view.IInputMethodClient
-com.android.internal.view.IInputMethodClient$Stub
-com.android.internal.view.IInputMethodClient$Stub$Proxy
-com.android.internal.view.IInputMethodManager
-com.android.internal.view.IInputMethodManager$Stub
-com.android.internal.view.IInputMethodManager$Stub$Proxy
-com.android.internal.view.IInputMethodSession
-com.android.internal.view.IInputMethodSession$Stub
-com.android.internal.view.IInputMethodSession$Stub$Proxy
-com.android.internal.view.IInputSessionCallback
-com.android.internal.view.IInputSessionCallback$Stub
-com.android.internal.view.IInputSessionCallback$Stub$Proxy
-com.android.internal.view.InputBindResult
-com.android.internal.view.InputBindResult$1
-com.android.internal.view.InputConnectionWrapper
-com.android.internal.view.InputConnectionWrapper$InputContextCallback
-com.android.internal.view.OneShotPreDrawListener
-com.android.internal.view.RootViewSurfaceTaker
-com.android.internal.view.RotationPolicy
-com.android.internal.view.RotationPolicy$RotationPolicyListener
-com.android.internal.view.RotationPolicy$RotationPolicyListener$1
-com.android.internal.view.SurfaceCallbackHelper
-com.android.internal.view.SurfaceCallbackHelper$1
-com.android.internal.view.SurfaceFlingerVsyncChoreographer
-com.android.internal.view.WindowManagerPolicyThread
-com.android.internal.view.animation.FallbackLUTInterpolator
-com.android.internal.view.animation.HasNativeInterpolator
-com.android.internal.view.animation.NativeInterpolatorFactory
-com.android.internal.view.animation.NativeInterpolatorFactoryHelper
-com.android.internal.view.menu.ActionMenuItem
-com.android.internal.view.menu.ActionMenuItemView
-com.android.internal.view.menu.ActionMenuItemView$PopupCallback
-com.android.internal.view.menu.BaseMenuPresenter
-com.android.internal.view.menu.ContextMenuBuilder
-com.android.internal.view.menu.MenuBuilder
-com.android.internal.view.menu.MenuBuilder$Callback
-com.android.internal.view.menu.MenuBuilder$ItemInvoker
-com.android.internal.view.menu.MenuHelper
-com.android.internal.view.menu.MenuItemImpl
-com.android.internal.view.menu.MenuPopupHelper
-com.android.internal.view.menu.MenuPopupHelper$1
-com.android.internal.view.menu.MenuPresenter
-com.android.internal.view.menu.MenuPresenter$Callback
-com.android.internal.view.menu.MenuView
-com.android.internal.view.menu.MenuView$ItemView
-com.android.internal.view.menu.ShowableListMenu
-com.android.internal.widget.-$Lambda$LaTFiUorkqfcqmu-zMQbCLeO77c
-com.android.internal.widget.AbsActionBarView
-com.android.internal.widget.AbsActionBarView$VisibilityAnimListener
-com.android.internal.widget.ActionBarContainer
-com.android.internal.widget.ActionBarContainer$ActionBarBackgroundDrawable
-com.android.internal.widget.ActionBarContextView
-com.android.internal.widget.ActionBarContextView$1
-com.android.internal.widget.ActionBarOverlayLayout
-com.android.internal.widget.ActionBarOverlayLayout$1
-com.android.internal.widget.ActionBarOverlayLayout$2
-com.android.internal.widget.ActionBarOverlayLayout$3
-com.android.internal.widget.ActionBarOverlayLayout$4
-com.android.internal.widget.ActionBarOverlayLayout$5
-com.android.internal.widget.ActionBarOverlayLayout$ActionBarVisibilityCallback
-com.android.internal.widget.ActionBarOverlayLayout$LayoutParams
-com.android.internal.widget.AlertDialogLayout
-com.android.internal.widget.BackgroundFallback
-com.android.internal.widget.ButtonBarLayout
-com.android.internal.widget.CachingIconView
-com.android.internal.widget.DecorContentParent
-com.android.internal.widget.DecorToolbar
-com.android.internal.widget.DialogTitle
-com.android.internal.widget.EditableInputConnection
-com.android.internal.widget.ICheckCredentialProgressCallback
-com.android.internal.widget.ILockSettings
-com.android.internal.widget.ILockSettings$Stub
-com.android.internal.widget.ILockSettings$Stub$Proxy
-com.android.internal.widget.ImageFloatingTextView
-com.android.internal.widget.LockPatternUtils
-com.android.internal.widget.LockPatternUtils$RequestThrottledException
-com.android.internal.widget.LockPatternUtils$StrongAuthTracker
-com.android.internal.widget.LockPatternUtils$StrongAuthTracker$1
-com.android.internal.widget.LockPatternUtils$StrongAuthTracker$H
-com.android.internal.widget.MediaNotificationView
-com.android.internal.widget.NotificationActionListLayout
-com.android.internal.widget.NotificationExpandButton
-com.android.internal.widget.ScrollBarUtils
-com.android.internal.widget.ToolbarWidgetWrapper
-com.android.internal.widget.ToolbarWidgetWrapper$1
-com.android.internal.widget.ToolbarWidgetWrapper$2
-com.android.internal.widget.VerifyCredentialResponse
-com.android.okhttp.Address
-com.android.okhttp.AndroidInternal
-com.android.okhttp.AndroidShimResponseCache
-com.android.okhttp.Authenticator
-com.android.okhttp.Cache
-com.android.okhttp.Cache$1
-com.android.okhttp.Cache$CacheRequestImpl
-com.android.okhttp.Cache$CacheRequestImpl$1
-com.android.okhttp.Cache$Entry
-com.android.okhttp.CacheControl
-com.android.okhttp.CacheControl$Builder
-com.android.okhttp.CertificatePinner
-com.android.okhttp.CertificatePinner$Builder
-com.android.okhttp.CipherSuite
-com.android.okhttp.ConfigAwareConnectionPool
-com.android.okhttp.ConfigAwareConnectionPool$1
-com.android.okhttp.Connection
-com.android.okhttp.ConnectionPool
-com.android.okhttp.ConnectionPool$1
-com.android.okhttp.ConnectionSpec
-com.android.okhttp.ConnectionSpec$Builder
-com.android.okhttp.Dispatcher
-com.android.okhttp.Dns
-com.android.okhttp.Dns$1
-com.android.okhttp.Handshake
-com.android.okhttp.Headers
-com.android.okhttp.Headers$Builder
-com.android.okhttp.HttpHandler
-com.android.okhttp.HttpHandler$CleartextURLFilter
-com.android.okhttp.HttpUrl
-com.android.okhttp.HttpUrl$Builder
-com.android.okhttp.HttpUrl$Builder$ParseResult
-com.android.okhttp.HttpsHandler
-com.android.okhttp.OkCacheContainer
-com.android.okhttp.OkHttpClient
-com.android.okhttp.OkHttpClient$1
-com.android.okhttp.OkUrlFactory
-com.android.okhttp.Protocol
-com.android.okhttp.Request
-com.android.okhttp.Request$Builder
-com.android.okhttp.RequestBody
-com.android.okhttp.RequestBody$2
-com.android.okhttp.Response
-com.android.okhttp.Response$Builder
-com.android.okhttp.ResponseBody
-com.android.okhttp.Route
-com.android.okhttp.TlsVersion
-com.android.okhttp.internal.ConnectionSpecSelector
-com.android.okhttp.internal.DiskLruCache
-com.android.okhttp.internal.DiskLruCache$1
-com.android.okhttp.internal.DiskLruCache$2
-com.android.okhttp.internal.DiskLruCache$3
-com.android.okhttp.internal.DiskLruCache$Editor
-com.android.okhttp.internal.DiskLruCache$Editor$1
-com.android.okhttp.internal.DiskLruCache$Entry
-com.android.okhttp.internal.FaultHidingSink
-com.android.okhttp.internal.Internal
-com.android.okhttp.internal.InternalCache
-com.android.okhttp.internal.OptionalMethod
-com.android.okhttp.internal.Platform
-com.android.okhttp.internal.RouteDatabase
-com.android.okhttp.internal.URLFilter
-com.android.okhttp.internal.Util
-com.android.okhttp.internal.Util$1
-com.android.okhttp.internal.http.AuthenticatorAdapter
-com.android.okhttp.internal.http.CacheRequest
-com.android.okhttp.internal.http.CacheStrategy
-com.android.okhttp.internal.http.CacheStrategy$Factory
-com.android.okhttp.internal.http.HeaderParser
-com.android.okhttp.internal.http.Http1xStream
-com.android.okhttp.internal.http.Http1xStream$AbstractSource
-com.android.okhttp.internal.http.Http1xStream$ChunkedSink
-com.android.okhttp.internal.http.Http1xStream$ChunkedSource
-com.android.okhttp.internal.http.Http1xStream$FixedLengthSink
-com.android.okhttp.internal.http.Http1xStream$FixedLengthSource
-com.android.okhttp.internal.http.Http1xStream$UnknownLengthSource
-com.android.okhttp.internal.http.HttpEngine
-com.android.okhttp.internal.http.HttpEngine$1
-com.android.okhttp.internal.http.HttpEngine$2
-com.android.okhttp.internal.http.HttpMethod
-com.android.okhttp.internal.http.HttpStream
-com.android.okhttp.internal.http.OkHeaders
-com.android.okhttp.internal.http.OkHeaders$1
-com.android.okhttp.internal.http.RealResponseBody
-com.android.okhttp.internal.http.RequestException
-com.android.okhttp.internal.http.RequestLine
-com.android.okhttp.internal.http.RetryableSink
-com.android.okhttp.internal.http.RouteException
-com.android.okhttp.internal.http.RouteSelector
-com.android.okhttp.internal.http.StatusLine
-com.android.okhttp.internal.http.StreamAllocation
-com.android.okhttp.internal.huc.DelegatingHttpsURLConnection
-com.android.okhttp.internal.huc.HttpURLConnectionImpl
-com.android.okhttp.internal.huc.HttpsURLConnectionImpl
-com.android.okhttp.internal.io.FileSystem
-com.android.okhttp.internal.io.FileSystem$1
-com.android.okhttp.internal.io.RealConnection
-com.android.okhttp.internal.tls.OkHostnameVerifier
-com.android.okhttp.okio.AsyncTimeout
-com.android.okhttp.okio.AsyncTimeout$1
-com.android.okhttp.okio.AsyncTimeout$2
-com.android.okhttp.okio.AsyncTimeout$Watchdog
-com.android.okhttp.okio.Base64
-com.android.okhttp.okio.Buffer
-com.android.okhttp.okio.BufferedSink
-com.android.okhttp.okio.BufferedSource
-com.android.okhttp.okio.ByteString
-com.android.okhttp.okio.ForwardingSink
-com.android.okhttp.okio.ForwardingTimeout
-com.android.okhttp.okio.GzipSource
-com.android.okhttp.okio.InflaterSource
-com.android.okhttp.okio.Okio
-com.android.okhttp.okio.Okio$1
-com.android.okhttp.okio.Okio$2
-com.android.okhttp.okio.Okio$3
-com.android.okhttp.okio.RealBufferedSink
-com.android.okhttp.okio.RealBufferedSink$1
-com.android.okhttp.okio.RealBufferedSource
-com.android.okhttp.okio.RealBufferedSource$1
-com.android.okhttp.okio.Segment
-com.android.okhttp.okio.SegmentPool
-com.android.okhttp.okio.Sink
-com.android.okhttp.okio.Source
-com.android.okhttp.okio.Timeout
-com.android.okhttp.okio.Timeout$1
-com.android.okhttp.okio.Util
-com.android.org.bouncycastle.asn1.ASN1BitString
-com.android.org.bouncycastle.asn1.ASN1Choice
-com.android.org.bouncycastle.asn1.ASN1Encodable
-com.android.org.bouncycastle.asn1.ASN1EncodableVector
-com.android.org.bouncycastle.asn1.ASN1InputStream
-com.android.org.bouncycastle.asn1.ASN1Integer
-com.android.org.bouncycastle.asn1.ASN1Null
-com.android.org.bouncycastle.asn1.ASN1Object
-com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier
-com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier$OidHandle
-com.android.org.bouncycastle.asn1.ASN1OutputStream
-com.android.org.bouncycastle.asn1.ASN1Primitive
-com.android.org.bouncycastle.asn1.ASN1Sequence
-com.android.org.bouncycastle.asn1.ASN1Set
-com.android.org.bouncycastle.asn1.ASN1StreamParser
-com.android.org.bouncycastle.asn1.ASN1String
-com.android.org.bouncycastle.asn1.ASN1TaggedObject
-com.android.org.bouncycastle.asn1.ASN1TaggedObjectParser
-com.android.org.bouncycastle.asn1.ASN1UTCTime
-com.android.org.bouncycastle.asn1.BERTags
-com.android.org.bouncycastle.asn1.DERBitString
-com.android.org.bouncycastle.asn1.DERFactory
-com.android.org.bouncycastle.asn1.DERNull
-com.android.org.bouncycastle.asn1.DEROutputStream
-com.android.org.bouncycastle.asn1.DERPrintableString
-com.android.org.bouncycastle.asn1.DERSequence
-com.android.org.bouncycastle.asn1.DERSet
-com.android.org.bouncycastle.asn1.DERTaggedObject
-com.android.org.bouncycastle.asn1.DLSequence
-com.android.org.bouncycastle.asn1.DLSet
-com.android.org.bouncycastle.asn1.DefiniteLengthInputStream
-com.android.org.bouncycastle.asn1.InMemoryRepresentable
-com.android.org.bouncycastle.asn1.IndefiniteLengthInputStream
-com.android.org.bouncycastle.asn1.LimitedInputStream
-com.android.org.bouncycastle.asn1.OIDTokenizer
-com.android.org.bouncycastle.asn1.StreamUtil
-com.android.org.bouncycastle.asn1.bc.BCObjectIdentifiers
-com.android.org.bouncycastle.asn1.iana.IANAObjectIdentifiers
-com.android.org.bouncycastle.asn1.misc.MiscObjectIdentifiers
-com.android.org.bouncycastle.asn1.nist.NISTObjectIdentifiers
-com.android.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers
-com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers
-com.android.org.bouncycastle.asn1.x500.RDN
-com.android.org.bouncycastle.asn1.x500.X500Name
-com.android.org.bouncycastle.asn1.x500.X500NameStyle
-com.android.org.bouncycastle.asn1.x500.style.AbstractX500NameStyle
-com.android.org.bouncycastle.asn1.x500.style.BCStyle
-com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier
-com.android.org.bouncycastle.asn1.x509.Certificate
-com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
-com.android.org.bouncycastle.asn1.x509.TBSCertificate
-com.android.org.bouncycastle.asn1.x509.Time
-com.android.org.bouncycastle.asn1.x509.X509ObjectIdentifiers
-com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers
-com.android.org.bouncycastle.crypto.AsymmetricBlockCipher
-com.android.org.bouncycastle.crypto.CipherKeyGenerator
-com.android.org.bouncycastle.crypto.CipherParameters
-com.android.org.bouncycastle.crypto.CryptoException
-com.android.org.bouncycastle.crypto.Digest
-com.android.org.bouncycastle.crypto.ExtendedDigest
-com.android.org.bouncycastle.crypto.InvalidCipherTextException
-com.android.org.bouncycastle.crypto.KeyGenerationParameters
-com.android.org.bouncycastle.crypto.Mac
-com.android.org.bouncycastle.crypto.PBEParametersGenerator
-com.android.org.bouncycastle.crypto.digests.AndroidDigestFactory
-com.android.org.bouncycastle.crypto.digests.AndroidDigestFactoryInterface
-com.android.org.bouncycastle.crypto.digests.AndroidDigestFactoryOpenSSL
-com.android.org.bouncycastle.crypto.digests.EncodableDigest
-com.android.org.bouncycastle.crypto.digests.GeneralDigest
-com.android.org.bouncycastle.crypto.digests.OpenSSLDigest
-com.android.org.bouncycastle.crypto.digests.OpenSSLDigest$SHA1
-com.android.org.bouncycastle.crypto.digests.SHA1Digest
-com.android.org.bouncycastle.crypto.encodings.OAEPEncoding
-com.android.org.bouncycastle.crypto.engines.RSABlindedEngine
-com.android.org.bouncycastle.crypto.engines.RSACoreEngine
-com.android.org.bouncycastle.crypto.generators.PKCS12ParametersGenerator
-com.android.org.bouncycastle.crypto.io.MacInputStream
-com.android.org.bouncycastle.crypto.macs.HMac
-com.android.org.bouncycastle.crypto.params.KeyParameter
-com.android.org.bouncycastle.jcajce.provider.asymmetric.DH$Mappings
-com.android.org.bouncycastle.jcajce.provider.asymmetric.DSA$Mappings
-com.android.org.bouncycastle.jcajce.provider.asymmetric.EC$Mappings
-com.android.org.bouncycastle.jcajce.provider.asymmetric.RSA$Mappings
-com.android.org.bouncycastle.jcajce.provider.asymmetric.X509$Mappings
-com.android.org.bouncycastle.jcajce.provider.asymmetric.dh.KeyFactorySpi
-com.android.org.bouncycastle.jcajce.provider.asymmetric.dsa.DSAUtil
-com.android.org.bouncycastle.jcajce.provider.asymmetric.dsa.KeyFactorySpi
-com.android.org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi
-com.android.org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi$EC
-com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi
-com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi$NoPadding
-com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi
-com.android.org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi
-com.android.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi
-com.android.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl
-com.android.org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory
-com.android.org.bouncycastle.jcajce.provider.asymmetric.x509.PEMUtil
-com.android.org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateObject
-com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider
-com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration
-com.android.org.bouncycastle.jcajce.provider.config.ProviderConfigurationPermission
-com.android.org.bouncycastle.jcajce.provider.digest.DigestAlgorithmProvider
-com.android.org.bouncycastle.jcajce.provider.digest.MD5
-com.android.org.bouncycastle.jcajce.provider.digest.MD5$Mappings
-com.android.org.bouncycastle.jcajce.provider.digest.SHA1
-com.android.org.bouncycastle.jcajce.provider.digest.SHA1$KeyGenerator
-com.android.org.bouncycastle.jcajce.provider.digest.SHA1$Mappings
-com.android.org.bouncycastle.jcajce.provider.digest.SHA224
-com.android.org.bouncycastle.jcajce.provider.digest.SHA224$Mappings
-com.android.org.bouncycastle.jcajce.provider.digest.SHA256
-com.android.org.bouncycastle.jcajce.provider.digest.SHA256$Mappings
-com.android.org.bouncycastle.jcajce.provider.digest.SHA384
-com.android.org.bouncycastle.jcajce.provider.digest.SHA384$Mappings
-com.android.org.bouncycastle.jcajce.provider.digest.SHA512
-com.android.org.bouncycastle.jcajce.provider.digest.SHA512$Mappings
-com.android.org.bouncycastle.jcajce.provider.keystore.BC$Mappings
-com.android.org.bouncycastle.jcajce.provider.keystore.PKCS12$Mappings
-com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi
-com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi$Std
-com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi$StoreEntry
-com.android.org.bouncycastle.jcajce.provider.symmetric.AES
-com.android.org.bouncycastle.jcajce.provider.symmetric.AES$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.ARC4
-com.android.org.bouncycastle.jcajce.provider.symmetric.ARC4$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.Blowfish
-com.android.org.bouncycastle.jcajce.provider.symmetric.Blowfish$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.DES
-com.android.org.bouncycastle.jcajce.provider.symmetric.DES$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.DESede
-com.android.org.bouncycastle.jcajce.provider.symmetric.DESede$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2
-com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12
-com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters
-com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.RC2
-com.android.org.bouncycastle.jcajce.provider.symmetric.RC2$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.SymmetricAlgorithmProvider
-com.android.org.bouncycastle.jcajce.provider.symmetric.Twofish
-com.android.org.bouncycastle.jcajce.provider.symmetric.Twofish$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator
-com.android.org.bouncycastle.jcajce.provider.util.AlgorithmProvider
-com.android.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider
-com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter
-com.android.org.bouncycastle.jcajce.provider.util.DigestFactory
-com.android.org.bouncycastle.jcajce.util.BCJcaJceHelper
-com.android.org.bouncycastle.jcajce.util.JcaJceHelper
-com.android.org.bouncycastle.jcajce.util.ProviderJcaJceHelper
-com.android.org.bouncycastle.jce.interfaces.BCKeyStore
-com.android.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier
-com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
-com.android.org.bouncycastle.jce.provider.BouncyCastleProvider$1
-com.android.org.bouncycastle.jce.provider.BouncyCastleProviderConfiguration
-com.android.org.bouncycastle.jce.provider.CertStoreCollectionSpi
-com.android.org.bouncycastle.util.Arrays
-com.android.org.bouncycastle.util.Encodable
-com.android.org.bouncycastle.util.Integers
-com.android.org.bouncycastle.util.Iterable
-com.android.org.bouncycastle.util.Memoable
-com.android.org.bouncycastle.util.Pack
-com.android.org.bouncycastle.util.Strings
-com.android.org.bouncycastle.util.Strings$1
-com.android.org.bouncycastle.util.io.Streams
-com.android.org.conscrypt.AbstractOpenSSLSession
-com.android.org.conscrypt.AbstractSessionContext
-com.android.org.conscrypt.AbstractSessionContext$1
-com.android.org.conscrypt.AddressUtils
-com.android.org.conscrypt.ArrayUtils
-com.android.org.conscrypt.ByteArray
-com.android.org.conscrypt.CertBlacklist
-com.android.org.conscrypt.CertificatePriorityComparator
-com.android.org.conscrypt.ChainStrengthAnalyzer
-com.android.org.conscrypt.ClientSessionContext
-com.android.org.conscrypt.ClientSessionContext$HostAndPort
-com.android.org.conscrypt.CryptoUpcalls
-com.android.org.conscrypt.EvpMdRef$MD5
-com.android.org.conscrypt.EvpMdRef$SHA1
-com.android.org.conscrypt.EvpMdRef$SHA256
-com.android.org.conscrypt.FileClientSessionCache
-com.android.org.conscrypt.FileClientSessionCache$CacheFile
-com.android.org.conscrypt.FileClientSessionCache$Impl
-com.android.org.conscrypt.Hex
-com.android.org.conscrypt.JSSEProvider
-com.android.org.conscrypt.KeyManagerFactoryImpl
-com.android.org.conscrypt.KeyManagerImpl
-com.android.org.conscrypt.NativeCrypto
-com.android.org.conscrypt.NativeCrypto$SSLHandshakeCallbacks
-com.android.org.conscrypt.NativeCryptoJni
-com.android.org.conscrypt.NativeRef
-com.android.org.conscrypt.NativeRef$EC_GROUP
-com.android.org.conscrypt.NativeRef$EC_POINT
-com.android.org.conscrypt.NativeRef$EVP_CIPHER_CTX
-com.android.org.conscrypt.NativeRef$EVP_MD_CTX
-com.android.org.conscrypt.NativeRef$EVP_PKEY
-com.android.org.conscrypt.NativeRef$HMAC_CTX
-com.android.org.conscrypt.OpenSSLBIOInputStream
-com.android.org.conscrypt.OpenSSLCipher
-com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER
-com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES
-com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES$CBC
-com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES$CBC$PKCS5Padding
-com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES_BASE
-com.android.org.conscrypt.OpenSSLCipher$Mode
-com.android.org.conscrypt.OpenSSLCipher$Padding
-com.android.org.conscrypt.OpenSSLContextImpl
-com.android.org.conscrypt.OpenSSLContextImpl$TLSv12
-com.android.org.conscrypt.OpenSSLECGroupContext
-com.android.org.conscrypt.OpenSSLECKeyFactory
-com.android.org.conscrypt.OpenSSLECPointContext
-com.android.org.conscrypt.OpenSSLECPublicKey
-com.android.org.conscrypt.OpenSSLExtendedSessionImpl
-com.android.org.conscrypt.OpenSSLKey
-com.android.org.conscrypt.OpenSSLKeyHolder
-com.android.org.conscrypt.OpenSSLMac
-com.android.org.conscrypt.OpenSSLMac$HmacSHA1
-com.android.org.conscrypt.OpenSSLMac$HmacSHA256
-com.android.org.conscrypt.OpenSSLMessageDigestJDK
-com.android.org.conscrypt.OpenSSLMessageDigestJDK$MD5
-com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA1
-com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA256
-com.android.org.conscrypt.OpenSSLProvider
-com.android.org.conscrypt.OpenSSLRSAKeyFactory
-com.android.org.conscrypt.OpenSSLRSAPublicKey
-com.android.org.conscrypt.OpenSSLRandom
-com.android.org.conscrypt.OpenSSLSessionImpl
-com.android.org.conscrypt.OpenSSLSignature
-com.android.org.conscrypt.OpenSSLSignature$EngineType
-com.android.org.conscrypt.OpenSSLSignature$RSAPKCS1Padding
-com.android.org.conscrypt.OpenSSLSignature$SHA1RSA
-com.android.org.conscrypt.OpenSSLSignature$SHA256RSA
-com.android.org.conscrypt.OpenSSLSocketFactoryImpl
-com.android.org.conscrypt.OpenSSLSocketImpl
-com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream
-com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream
-com.android.org.conscrypt.OpenSSLSocketImplWrapper
-com.android.org.conscrypt.OpenSSLX509CertPath
-com.android.org.conscrypt.OpenSSLX509CertPath$Encoding
-com.android.org.conscrypt.OpenSSLX509Certificate
-com.android.org.conscrypt.OpenSSLX509CertificateFactory
-com.android.org.conscrypt.OpenSSLX509CertificateFactory$1
-com.android.org.conscrypt.OpenSSLX509CertificateFactory$2
-com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser
-com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException
-com.android.org.conscrypt.Platform
-com.android.org.conscrypt.SSLClientSessionCache
-com.android.org.conscrypt.SSLParametersImpl
-com.android.org.conscrypt.SSLParametersImpl$AliasChooser
-com.android.org.conscrypt.SSLParametersImpl$PSKCallbacks
-com.android.org.conscrypt.SSLUtils
-com.android.org.conscrypt.ServerSessionContext
-com.android.org.conscrypt.TrustManagerFactoryImpl
-com.android.org.conscrypt.TrustManagerImpl
-com.android.org.conscrypt.TrustManagerImpl$ExtendedKeyUsagePKIXCertPathChecker
-com.android.org.conscrypt.TrustManagerImpl$TrustAnchorComparator
-com.android.org.conscrypt.TrustedCertificateIndex
-com.android.org.conscrypt.TrustedCertificateKeyStoreSpi
-com.android.org.conscrypt.TrustedCertificateStore
-com.android.org.conscrypt.TrustedCertificateStore$1
-com.android.org.conscrypt.TrustedCertificateStore$2
-com.android.org.conscrypt.TrustedCertificateStore$4
-com.android.org.conscrypt.TrustedCertificateStore$5
-com.android.org.conscrypt.TrustedCertificateStore$CertSelector
-com.android.org.conscrypt.TrustedCertificateStore$PreloadHolder
-com.android.org.conscrypt.ct.CTLogInfo
-com.android.org.conscrypt.ct.CTLogStore
-com.android.org.conscrypt.ct.CTLogStoreImpl
-com.android.org.conscrypt.ct.CTLogStoreImpl$InvalidLogFileException
-com.android.org.conscrypt.ct.CTPolicy
-com.android.org.conscrypt.ct.CTPolicyImpl
-com.android.org.conscrypt.ct.CTVerifier
-com.android.org.conscrypt.ct.KnownLogs
-com.android.org.conscrypt.ct.SerializationException
-com.android.server.AppWidgetBackupBridge
-com.android.server.BootReceiver
-com.android.server.BootReceiver$1
-com.android.server.BootReceiver$2
-com.android.server.LocalServices
-com.android.server.NetworkManagementSocketTagger
-com.android.server.NetworkManagementSocketTagger$1
-com.android.server.NetworkManagementSocketTagger$SocketTags
-com.android.server.SystemConfig
-com.android.server.SystemConfig$PermissionEntry
-com.android.server.WidgetBackupProvider
-com.android.server.backup.AccountSyncSettingsBackupHelper
-com.android.server.net.BaseNetworkObserver
-com.android.server.net.DnsServerEntry
-com.android.server.net.DnsServerRepository
-com.android.server.net.NetlinkTracker
-com.android.server.net.NetlinkTracker$Callback
-com.android.server.sip.SipService
-com.android.server.sip.SipService$ConnectivityReceiver
-com.android.server.sip.SipService$MyExecutor
-com.android.server.sip.SipWakeLock
-com.android.server.sip.SipWakeupTimer
-com.android.server.sip.SipWakeupTimer$MyEventComparator
-com.android.server.wifi.nano.WifiMetricsProto$AlertReasonCount
-com.android.server.wifi.nano.WifiMetricsProto$ConnectionEvent
-com.android.server.wifi.nano.WifiMetricsProto$RouterFingerPrint
-com.android.server.wifi.nano.WifiMetricsProto$RssiPollCount
-com.android.server.wifi.nano.WifiMetricsProto$SoftApDurationBucket
-com.android.server.wifi.nano.WifiMetricsProto$SoftApReturnCodeCount
-com.android.server.wifi.nano.WifiMetricsProto$StaEvent
-com.android.server.wifi.nano.WifiMetricsProto$StaEvent$ConfigInfo
-com.android.server.wifi.nano.WifiMetricsProto$WifiLog
-com.android.server.wifi.nano.WifiMetricsProto$WifiLog$ScanReturnEntry
-com.android.server.wifi.nano.WifiMetricsProto$WifiLog$WifiSystemStateEntry
-com.android.server.wifi.nano.WifiMetricsProto$WifiScoreCount
-com.android.server.wm.nano.WindowManagerProtos$TaskSnapshotProto
-com.google.android.collect.Lists
-com.google.android.collect.Maps
-com.google.android.collect.Sets
-com.google.android.gles_jni.EGLConfigImpl
-com.google.android.gles_jni.EGLContextImpl
-com.google.android.gles_jni.EGLDisplayImpl
-com.google.android.gles_jni.EGLImpl
-com.google.android.gles_jni.EGLSurfaceImpl
-com.google.android.gles_jni.GLImpl
-com.google.android.mms.MmsException
-dalvik.annotation.optimization.CriticalNative
-dalvik.annotation.optimization.FastNative
-dalvik.system.-$Lambda$xxvwQBVHC44UYbpcpA8j0sUqLOo
-dalvik.system.BaseDexClassLoader
-dalvik.system.BaseDexClassLoader$Reporter
-dalvik.system.BlockGuard
-dalvik.system.BlockGuard$1
-dalvik.system.BlockGuard$2
-dalvik.system.BlockGuard$BlockGuardPolicyException
-dalvik.system.BlockGuard$Policy
-dalvik.system.ClassExt
-dalvik.system.CloseGuard
-dalvik.system.CloseGuard$DefaultReporter
-dalvik.system.CloseGuard$DefaultTracker
-dalvik.system.CloseGuard$Reporter
-dalvik.system.CloseGuard$Tracker
-dalvik.system.DalvikLogHandler
-dalvik.system.DalvikLogging
-dalvik.system.DexClassLoader
-dalvik.system.DexFile
-dalvik.system.DexFile$DFEnum
-dalvik.system.DexPathList
-dalvik.system.DexPathList$Element
-dalvik.system.DexPathList$NativeLibraryElement
-dalvik.system.EmulatedStackFrame
-dalvik.system.EmulatedStackFrame$Range
-dalvik.system.PathClassLoader
-dalvik.system.SocketTagger
-dalvik.system.SocketTagger$1
-dalvik.system.VMDebug
-dalvik.system.VMRuntime
-dalvik.system.VMStack
-dalvik.system.ZygoteHooks
-java.io.Bits
-java.io.BufferedInputStream
-java.io.BufferedOutputStream
-java.io.BufferedReader
-java.io.BufferedWriter
-java.io.ByteArrayInputStream
-java.io.ByteArrayOutputStream
-java.io.CharArrayWriter
-java.io.Closeable
-java.io.Console
-java.io.DataInput
-java.io.DataInputStream
-java.io.DataOutput
-java.io.DataOutputStream
-java.io.DefaultFileSystem
-java.io.EOFException
-java.io.ExpiringCache
-java.io.ExpiringCache$1
-java.io.ExpiringCache$Entry
-java.io.Externalizable
-java.io.File
-java.io.File$PathStatus
-java.io.File$TempDirectory
-java.io.FileDescriptor
-java.io.FileDescriptor$1
-java.io.FileFilter
-java.io.FileInputStream
-java.io.FileInputStream$UseManualSkipException
-java.io.FileNotFoundException
-java.io.FileOutputStream
-java.io.FileReader
-java.io.FileSystem
-java.io.FileWriter
-java.io.FilenameFilter
-java.io.FilterInputStream
-java.io.FilterOutputStream
-java.io.FilterReader
-java.io.Flushable
-java.io.IOException
-java.io.InputStream
-java.io.InputStreamReader
-java.io.InterruptedIOException
-java.io.InvalidClassException
-java.io.InvalidObjectException
-java.io.ObjectInput
-java.io.ObjectInputStream
-java.io.ObjectInputStream$BlockDataInputStream
-java.io.ObjectInputStream$HandleTable
-java.io.ObjectInputStream$HandleTable$HandleList
-java.io.ObjectInputStream$PeekInputStream
-java.io.ObjectInputStream$ValidationList
-java.io.ObjectOutput
-java.io.ObjectOutputStream
-java.io.ObjectOutputStream$BlockDataOutputStream
-java.io.ObjectOutputStream$HandleTable
-java.io.ObjectOutputStream$PutField
-java.io.ObjectOutputStream$ReplaceTable
-java.io.ObjectStreamClass
-java.io.ObjectStreamClass$1
-java.io.ObjectStreamClass$2
-java.io.ObjectStreamClass$3
-java.io.ObjectStreamClass$4
-java.io.ObjectStreamClass$5
-java.io.ObjectStreamClass$Caches
-java.io.ObjectStreamClass$ClassDataSlot
-java.io.ObjectStreamClass$EntryFuture
-java.io.ObjectStreamClass$ExceptionInfo
-java.io.ObjectStreamClass$FieldReflector
-java.io.ObjectStreamClass$FieldReflectorKey
-java.io.ObjectStreamClass$MemberSignature
-java.io.ObjectStreamClass$WeakClassKey
-java.io.ObjectStreamConstants
-java.io.ObjectStreamException
-java.io.ObjectStreamField
-java.io.OutputStream
-java.io.OutputStreamWriter
-java.io.PrintStream
-java.io.PrintWriter
-java.io.PushbackInputStream
-java.io.PushbackReader
-java.io.RandomAccessFile
-java.io.Reader
-java.io.SequenceInputStream
-java.io.SerialCallbackContext
-java.io.Serializable
-java.io.SerializablePermission
-java.io.StreamCorruptedException
-java.io.StringReader
-java.io.StringWriter
-java.io.UnixFileSystem
-java.io.UnsupportedEncodingException
-java.io.Writer
-java.lang.-$Lambda$S9HjrJh0nDg7IyU6wZdPArnZWRQ
-java.lang.-$Lambda$S9HjrJh0nDg7IyU6wZdPArnZWRQ$1
-java.lang.AbstractMethodError
-java.lang.AbstractStringBuilder
-java.lang.AndroidHardcodedSystemProperties
-java.lang.Appendable
-java.lang.ArithmeticException
-java.lang.ArrayIndexOutOfBoundsException
-java.lang.ArrayStoreException
-java.lang.AssertionError
-java.lang.AutoCloseable
-java.lang.Boolean
-java.lang.BootClassLoader
-java.lang.Byte
-java.lang.Byte$ByteCache
-java.lang.CaseMapper
-java.lang.CaseMapper$1
-java.lang.CharSequence
-java.lang.CharSequence$1CharIterator
-java.lang.CharSequence$1CodePointIterator
-java.lang.Character
-java.lang.Character$CharacterCache
-java.lang.Character$Subset
-java.lang.Character$UnicodeBlock
-java.lang.Class
-java.lang.Class$Caches
-java.lang.ClassCastException
-java.lang.ClassLoader
-java.lang.ClassLoader$SystemClassLoader
-java.lang.ClassNotFoundException
-java.lang.CloneNotSupportedException
-java.lang.Cloneable
-java.lang.Comparable
-java.lang.Daemons
-java.lang.Daemons$Daemon
-java.lang.Daemons$FinalizerDaemon
-java.lang.Daemons$FinalizerWatchdogDaemon
-java.lang.Daemons$HeapTaskDaemon
-java.lang.Daemons$ReferenceQueueDaemon
-java.lang.Deprecated
-java.lang.DexCache
-java.lang.Double
-java.lang.Enum
-java.lang.Enum$1
-java.lang.EnumConstantNotPresentException
-java.lang.Error
-java.lang.Exception
-java.lang.ExceptionInInitializerError
-java.lang.Float
-java.lang.IllegalAccessError
-java.lang.IllegalAccessException
-java.lang.IllegalArgumentException
-java.lang.IllegalMonitorStateException
-java.lang.IllegalStateException
-java.lang.IllegalThreadStateException
-java.lang.IncompatibleClassChangeError
-java.lang.IndexOutOfBoundsException
-java.lang.InheritableThreadLocal
-java.lang.InstantiationError
-java.lang.InstantiationException
-java.lang.Integer
-java.lang.Integer$IntegerCache
-java.lang.InternalError
-java.lang.InterruptedException
-java.lang.Iterable
-java.lang.JavaLangAccess
-java.lang.LinkageError
-java.lang.Long
-java.lang.Long$LongCache
-java.lang.Math
-java.lang.Math$RandomNumberGeneratorHolder
-java.lang.NegativeArraySizeException
-java.lang.NoClassDefFoundError
-java.lang.NoSuchFieldError
-java.lang.NoSuchFieldException
-java.lang.NoSuchMethodError
-java.lang.NoSuchMethodException
-java.lang.NullPointerException
-java.lang.Number
-java.lang.NumberFormatException
-java.lang.Object
-java.lang.OutOfMemoryError
-java.lang.Package
-java.lang.Process
-java.lang.ProcessBuilder
-java.lang.ProcessEnvironment
-java.lang.Readable
-java.lang.ReflectiveOperationException
-java.lang.Runnable
-java.lang.Runtime
-java.lang.RuntimeException
-java.lang.RuntimePermission
-java.lang.SecurityException
-java.lang.SecurityManager
-java.lang.Short
-java.lang.Short$ShortCache
-java.lang.StackOverflowError
-java.lang.StackTraceElement
-java.lang.StrictMath
-java.lang.String
-java.lang.String$CaseInsensitiveComparator
-java.lang.StringBuffer
-java.lang.StringBuilder
-java.lang.StringFactory
-java.lang.StringIndexOutOfBoundsException
-java.lang.System
-java.lang.System$PropertiesWithNonOverrideableDefaults
-java.lang.Thread
-java.lang.Thread$1
-java.lang.Thread$Caches
-java.lang.Thread$State
-java.lang.Thread$UncaughtExceptionHandler
-java.lang.Thread$WeakClassKey
-java.lang.ThreadDeath
-java.lang.ThreadGroup
-java.lang.ThreadLocal
-java.lang.ThreadLocal$SuppliedThreadLocal
-java.lang.ThreadLocal$ThreadLocalMap
-java.lang.ThreadLocal$ThreadLocalMap$Entry
-java.lang.Throwable
-java.lang.Throwable$PrintStreamOrWriter
-java.lang.Throwable$SentinelHolder
-java.lang.Throwable$WrappedPrintStream
-java.lang.Throwable$WrappedPrintWriter
-java.lang.TypeNotPresentException
-java.lang.UNIXProcess
-java.lang.UnsatisfiedLinkError
-java.lang.UnsupportedOperationException
-java.lang.VMClassLoader
-java.lang.VerifyError
-java.lang.VirtualMachineError
-java.lang.Void
-java.lang.annotation.Annotation
-java.lang.annotation.AnnotationTypeMismatchException
-java.lang.annotation.IncompleteAnnotationException
-java.lang.annotation.Inherited
-java.lang.annotation.Retention
-java.lang.annotation.Target
-java.lang.invoke.CallSite
-java.lang.invoke.ConstantCallSite
-java.lang.invoke.MethodHandle
-java.lang.invoke.MethodHandleImpl
-java.lang.invoke.MethodHandleImpl$HandleInfo
-java.lang.invoke.MethodHandleInfo
-java.lang.invoke.MethodHandleStatics
-java.lang.invoke.MethodHandles
-java.lang.invoke.MethodHandles$Lookup
-java.lang.invoke.MethodType
-java.lang.invoke.MethodType$ConcurrentWeakInternSet
-java.lang.invoke.MethodType$ConcurrentWeakInternSet$WeakEntry
-java.lang.invoke.MethodTypeForm
-java.lang.invoke.Transformers$BindTo
-java.lang.invoke.Transformers$Collector
-java.lang.invoke.Transformers$Construct
-java.lang.invoke.Transformers$Spreader
-java.lang.invoke.Transformers$Transformer
-java.lang.invoke.Transformers$VarargsCollector
-java.lang.invoke.WrongMethodTypeException
-java.lang.ref.FinalizerReference
-java.lang.ref.FinalizerReference$Sentinel
-java.lang.ref.PhantomReference
-java.lang.ref.Reference
-java.lang.ref.ReferenceQueue
-java.lang.ref.SoftReference
-java.lang.ref.WeakReference
-java.lang.reflect.AccessibleObject
-java.lang.reflect.AnnotatedElement
-java.lang.reflect.Array
-java.lang.reflect.Constructor
-java.lang.reflect.Executable
-java.lang.reflect.Executable$GenericInfo
-java.lang.reflect.Field
-java.lang.reflect.GenericArrayType
-java.lang.reflect.GenericDeclaration
-java.lang.reflect.InvocationHandler
-java.lang.reflect.InvocationTargetException
-java.lang.reflect.MalformedParametersException
-java.lang.reflect.Member
-java.lang.reflect.Method
-java.lang.reflect.Method$1
-java.lang.reflect.Modifier
-java.lang.reflect.Parameter
-java.lang.reflect.ParameterizedType
-java.lang.reflect.Proxy
-java.lang.reflect.Proxy$1
-java.lang.reflect.Proxy$Key1
-java.lang.reflect.Proxy$Key2
-java.lang.reflect.Proxy$KeyFactory
-java.lang.reflect.Proxy$KeyX
-java.lang.reflect.Proxy$ProxyClassFactory
-java.lang.reflect.Type
-java.lang.reflect.TypeVariable
-java.lang.reflect.UndeclaredThrowableException
-java.lang.reflect.WeakCache
-java.lang.reflect.WeakCache$CacheKey
-java.lang.reflect.WeakCache$CacheValue
-java.lang.reflect.WeakCache$Factory
-java.lang.reflect.WeakCache$LookupValue
-java.lang.reflect.WeakCache$Value
-java.lang.reflect.WildcardType
-java.math.BigDecimal
-java.math.BigInt
-java.math.BigInteger
-java.math.Conversion
-java.math.Division
-java.math.MathContext
-java.math.Multiplication
-java.math.NativeBN
-java.math.RoundingMode
-java.net.AbstractPlainDatagramSocketImpl
-java.net.AbstractPlainSocketImpl
-java.net.AddressCache
-java.net.AddressCache$AddressCacheEntry
-java.net.AddressCache$AddressCacheKey
-java.net.ConnectException
-java.net.CookieHandler
-java.net.CookieManager
-java.net.CookiePolicy
-java.net.CookiePolicy$1
-java.net.CookiePolicy$2
-java.net.CookiePolicy$3
-java.net.CookieStore
-java.net.DatagramPacket
-java.net.DatagramSocket
-java.net.DatagramSocket$1
-java.net.DatagramSocketImpl
-java.net.DefaultDatagramSocketImplFactory
-java.net.DefaultFileNameMap
-java.net.DefaultInterface
-java.net.FileNameMap
-java.net.HttpURLConnection
-java.net.IDN
-java.net.InMemoryCookieStore
-java.net.Inet4Address
-java.net.Inet6Address
-java.net.Inet6Address$Inet6AddressHolder
-java.net.Inet6AddressImpl
-java.net.InetAddress
-java.net.InetAddress$1
-java.net.InetAddress$InetAddressHolder
-java.net.InetAddressImpl
-java.net.InetSocketAddress
-java.net.InetSocketAddress$InetSocketAddressHolder
-java.net.InterfaceAddress
-java.net.JarURLConnection
-java.net.MalformedURLException
-java.net.MulticastSocket
-java.net.NetworkInterface
-java.net.NetworkInterface$1checkedAddresses
-java.net.NoRouteToHostException
-java.net.Parts
-java.net.PlainDatagramSocketImpl
-java.net.PlainSocketImpl
-java.net.PortUnreachableException
-java.net.ProtocolException
-java.net.ProtocolFamily
-java.net.Proxy
-java.net.Proxy$Type
-java.net.ProxySelector
-java.net.ResponseCache
-java.net.ServerSocket
-java.net.Socket
-java.net.Socket$1
-java.net.Socket$2
-java.net.Socket$3
-java.net.SocketAddress
-java.net.SocketException
-java.net.SocketImpl
-java.net.SocketInputStream
-java.net.SocketOptions
-java.net.SocketOutputStream
-java.net.SocketTimeoutException
-java.net.SocksConsts
-java.net.SocksSocketImpl
-java.net.StandardProtocolFamily
-java.net.URI
-java.net.URI$Parser
-java.net.URISyntaxException
-java.net.URL
-java.net.URLConnection
-java.net.URLDecoder
-java.net.URLEncoder
-java.net.URLStreamHandler
-java.net.URLStreamHandlerFactory
-java.net.UnknownHostException
-java.net.UnknownServiceException
-java.nio.Bits
-java.nio.Buffer
-java.nio.BufferOverflowException
-java.nio.BufferUnderflowException
-java.nio.ByteBuffer
-java.nio.ByteBufferAsCharBuffer
-java.nio.ByteBufferAsDoubleBuffer
-java.nio.ByteBufferAsFloatBuffer
-java.nio.ByteBufferAsIntBuffer
-java.nio.ByteBufferAsLongBuffer
-java.nio.ByteBufferAsShortBuffer
-java.nio.ByteOrder
-java.nio.CharBuffer
-java.nio.DirectByteBuffer
-java.nio.DirectByteBuffer$MemoryRef
-java.nio.DoubleBuffer
-java.nio.FloatBuffer
-java.nio.HeapByteBuffer
-java.nio.HeapCharBuffer
-java.nio.IntBuffer
-java.nio.InvalidMarkException
-java.nio.LongBuffer
-java.nio.MappedByteBuffer
-java.nio.NIOAccess
-java.nio.NioUtils
-java.nio.ReadOnlyBufferException
-java.nio.ShortBuffer
-java.nio.StringCharBuffer
-java.nio.channels.AsynchronousCloseException
-java.nio.channels.ByteChannel
-java.nio.channels.CancelledKeyException
-java.nio.channels.Channel
-java.nio.channels.Channels
-java.nio.channels.Channels$1
-java.nio.channels.ClosedByInterruptException
-java.nio.channels.ClosedChannelException
-java.nio.channels.DatagramChannel
-java.nio.channels.FileChannel
-java.nio.channels.FileChannel$MapMode
-java.nio.channels.FileLock
-java.nio.channels.GatheringByteChannel
-java.nio.channels.InterruptibleChannel
-java.nio.channels.MulticastChannel
-java.nio.channels.NetworkChannel
-java.nio.channels.NonWritableChannelException
-java.nio.channels.OverlappingFileLockException
-java.nio.channels.ReadableByteChannel
-java.nio.channels.ScatteringByteChannel
-java.nio.channels.SeekableByteChannel
-java.nio.channels.SelectableChannel
-java.nio.channels.SelectionKey
-java.nio.channels.Selector
-java.nio.channels.ServerSocketChannel
-java.nio.channels.SocketChannel
-java.nio.channels.WritableByteChannel
-java.nio.channels.spi.AbstractInterruptibleChannel
-java.nio.channels.spi.AbstractInterruptibleChannel$1
-java.nio.channels.spi.AbstractSelectableChannel
-java.nio.channels.spi.AbstractSelectionKey
-java.nio.channels.spi.AbstractSelector
-java.nio.channels.spi.AbstractSelector$1
-java.nio.channels.spi.SelectorProvider
-java.nio.channels.spi.SelectorProvider$1
-java.nio.charset.CharacterCodingException
-java.nio.charset.Charset
-java.nio.charset.CharsetDecoder
-java.nio.charset.CharsetDecoderICU
-java.nio.charset.CharsetEncoder
-java.nio.charset.CharsetEncoderICU
-java.nio.charset.CharsetICU
-java.nio.charset.CoderResult
-java.nio.charset.CoderResult$1
-java.nio.charset.CoderResult$2
-java.nio.charset.CoderResult$Cache
-java.nio.charset.CodingErrorAction
-java.nio.charset.IllegalCharsetNameException
-java.nio.charset.StandardCharsets
-java.nio.charset.UnsupportedCharsetException
-java.nio.file.AccessMode
-java.nio.file.CopyOption
-java.nio.file.FileAlreadyExistsException
-java.nio.file.FileSystem
-java.nio.file.FileSystemException
-java.nio.file.FileSystems
-java.nio.file.FileSystems$DefaultFileSystemHolder
-java.nio.file.FileSystems$DefaultFileSystemHolder$1
-java.nio.file.Files
-java.nio.file.LinkOption
-java.nio.file.NoSuchFileException
-java.nio.file.OpenOption
-java.nio.file.Path
-java.nio.file.Paths
-java.nio.file.StandardOpenOption
-java.nio.file.Watchable
-java.nio.file.attribute.AttributeView
-java.nio.file.attribute.BasicFileAttributeView
-java.nio.file.attribute.BasicFileAttributes
-java.nio.file.attribute.FileAttribute
-java.nio.file.attribute.FileAttributeView
-java.nio.file.attribute.PosixFileAttributes
-java.nio.file.spi.FileSystemProvider
-java.security.AccessControlContext
-java.security.AccessControlException
-java.security.AccessController
-java.security.AlgorithmConstraints
-java.security.AlgorithmParameters
-java.security.AlgorithmParametersSpi
-java.security.BasicPermission
-java.security.CodeSigner
-java.security.CryptoPrimitive
-java.security.DigestException
-java.security.GeneralSecurityException
-java.security.Guard
-java.security.InvalidAlgorithmParameterException
-java.security.InvalidKeyException
-java.security.InvalidParameterException
-java.security.Key
-java.security.KeyException
-java.security.KeyFactory
-java.security.KeyFactorySpi
-java.security.KeyManagementException
-java.security.KeyPair
-java.security.KeyPairGenerator
-java.security.KeyPairGeneratorSpi
-java.security.KeyStore
-java.security.KeyStore$1
-java.security.KeyStoreException
-java.security.KeyStoreSpi
-java.security.MessageDigest
-java.security.MessageDigest$Delegate
-java.security.MessageDigestSpi
-java.security.NoSuchAlgorithmException
-java.security.NoSuchProviderException
-java.security.Permission
-java.security.PermissionCollection
-java.security.Permissions
-java.security.Principal
-java.security.PrivateKey
-java.security.PrivilegedAction
-java.security.PrivilegedActionException
-java.security.PrivilegedExceptionAction
-java.security.ProtectionDomain
-java.security.Provider
-java.security.Provider$EngineDescription
-java.security.Provider$Service
-java.security.Provider$ServiceKey
-java.security.Provider$UString
-java.security.PublicKey
-java.security.SecureRandom
-java.security.SecureRandomSpi
-java.security.Security
-java.security.Signature
-java.security.Signature$Delegate
-java.security.SignatureException
-java.security.SignatureSpi
-java.security.UnrecoverableEntryException
-java.security.UnrecoverableKeyException
-java.security.cert.CRL
-java.security.cert.CRLException
-java.security.cert.CRLReason
-java.security.cert.CertPath
-java.security.cert.CertPathBuilderException
-java.security.cert.CertPathChecker
-java.security.cert.CertPathHelperImpl
-java.security.cert.CertPathParameters
-java.security.cert.CertPathValidator
-java.security.cert.CertPathValidatorException
-java.security.cert.CertPathValidatorResult
-java.security.cert.CertPathValidatorSpi
-java.security.cert.CertSelector
-java.security.cert.CertStore
-java.security.cert.CertStoreException
-java.security.cert.CertStoreParameters
-java.security.cert.CertStoreSpi
-java.security.cert.Certificate
-java.security.cert.CertificateEncodingException
-java.security.cert.CertificateException
-java.security.cert.CertificateExpiredException
-java.security.cert.CertificateFactory
-java.security.cert.CertificateFactorySpi
-java.security.cert.CertificateNotYetValidException
-java.security.cert.CertificateParsingException
-java.security.cert.CollectionCertStoreParameters
-java.security.cert.Extension
-java.security.cert.PKIXCertPathChecker
-java.security.cert.PKIXCertPathValidatorResult
-java.security.cert.PKIXParameters
-java.security.cert.PKIXRevocationChecker
-java.security.cert.PKIXRevocationChecker$Option
-java.security.cert.PolicyNode
-java.security.cert.PolicyQualifierInfo
-java.security.cert.TrustAnchor
-java.security.cert.X509CertSelector
-java.security.cert.X509Certificate
-java.security.cert.X509Extension
-java.security.interfaces.DSAKey
-java.security.interfaces.DSAPublicKey
-java.security.interfaces.ECKey
-java.security.interfaces.ECPrivateKey
-java.security.interfaces.ECPublicKey
-java.security.interfaces.RSAKey
-java.security.interfaces.RSAPrivateKey
-java.security.interfaces.RSAPublicKey
-java.security.spec.AlgorithmParameterSpec
-java.security.spec.ECField
-java.security.spec.ECFieldFp
-java.security.spec.ECGenParameterSpec
-java.security.spec.ECParameterSpec
-java.security.spec.ECPoint
-java.security.spec.ECPrivateKeySpec
-java.security.spec.ECPublicKeySpec
-java.security.spec.EllipticCurve
-java.security.spec.EncodedKeySpec
-java.security.spec.InvalidKeySpecException
-java.security.spec.InvalidParameterSpecException
-java.security.spec.KeySpec
-java.security.spec.MGF1ParameterSpec
-java.security.spec.PKCS8EncodedKeySpec
-java.security.spec.RSAPrivateCrtKeySpec
-java.security.spec.RSAPrivateKeySpec
-java.security.spec.RSAPublicKeySpec
-java.security.spec.X509EncodedKeySpec
-java.sql.Timestamp
-java.text.AttributedCharacterIterator$Attribute
-java.text.Bidi
-java.text.BreakIterator
-java.text.CalendarBuilder
-java.text.CharacterIterator
-java.text.CollationKey
-java.text.Collator
-java.text.DateFormat
-java.text.DateFormat$Field
-java.text.DateFormatSymbols
-java.text.DecimalFormat
-java.text.DecimalFormatSymbols
-java.text.DontCareFieldPosition
-java.text.DontCareFieldPosition$1
-java.text.FieldPosition
-java.text.FieldPosition$Delegate
-java.text.Format
-java.text.Format$Field
-java.text.Format$FieldDelegate
-java.text.IcuIteratorWrapper
-java.text.MessageFormat
-java.text.MessageFormat$Field
-java.text.Normalizer
-java.text.Normalizer$Form
-java.text.NumberFormat
-java.text.ParseException
-java.text.ParsePosition
-java.text.RuleBasedCollator
-java.text.SimpleDateFormat
-java.text.StringCharacterIterator
-java.time.DateTimeException
-java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo
-java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$1
-java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$2
-java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$3
-java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$4
-java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$5
-java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw
-java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw$1
-java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw$2
-java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw$3
-java.util.AbstractCollection
-java.util.AbstractList
-java.util.AbstractList$Itr
-java.util.AbstractList$ListItr
-java.util.AbstractMap
-java.util.AbstractMap$1
-java.util.AbstractMap$2
-java.util.AbstractMap$2$1
-java.util.AbstractMap$SimpleEntry
-java.util.AbstractMap$SimpleImmutableEntry
-java.util.AbstractQueue
-java.util.AbstractSequentialList
-java.util.AbstractSet
-java.util.ArrayDeque
-java.util.ArrayDeque$DeqIterator
-java.util.ArrayDeque$DescendingIterator
-java.util.ArrayList
-java.util.ArrayList$ArrayListSpliterator
-java.util.ArrayList$Itr
-java.util.ArrayList$ListItr
-java.util.ArrayList$SubList
-java.util.ArrayList$SubList$1
-java.util.ArrayPrefixHelpers$CumulateTask
-java.util.ArrayPrefixHelpers$DoubleCumulateTask
-java.util.ArrayPrefixHelpers$IntCumulateTask
-java.util.ArrayPrefixHelpers$LongCumulateTask
-java.util.Arrays
-java.util.Arrays$ArrayList
-java.util.Arrays$NaturalOrder
-java.util.ArraysParallelSortHelpers$FJByte$Sorter
-java.util.ArraysParallelSortHelpers$FJChar$Sorter
-java.util.ArraysParallelSortHelpers$FJDouble$Sorter
-java.util.ArraysParallelSortHelpers$FJFloat$Sorter
-java.util.ArraysParallelSortHelpers$FJInt$Sorter
-java.util.ArraysParallelSortHelpers$FJLong$Sorter
-java.util.ArraysParallelSortHelpers$FJObject$Sorter
-java.util.ArraysParallelSortHelpers$FJShort$Sorter
-java.util.Base64
-java.util.Base64$Decoder
-java.util.Base64$Encoder
-java.util.BitSet
-java.util.Calendar
-java.util.Collection
-java.util.Collections
-java.util.Collections$1
-java.util.Collections$2
-java.util.Collections$3
-java.util.Collections$AsLIFOQueue
-java.util.Collections$CheckedCollection
-java.util.Collections$CheckedList
-java.util.Collections$CheckedMap
-java.util.Collections$CheckedNavigableMap
-java.util.Collections$CheckedNavigableSet
-java.util.Collections$CheckedQueue
-java.util.Collections$CheckedRandomAccessList
-java.util.Collections$CheckedSet
-java.util.Collections$CheckedSortedMap
-java.util.Collections$CheckedSortedSet
-java.util.Collections$CopiesList
-java.util.Collections$EmptyEnumeration
-java.util.Collections$EmptyIterator
-java.util.Collections$EmptyList
-java.util.Collections$EmptyListIterator
-java.util.Collections$EmptyMap
-java.util.Collections$EmptySet
-java.util.Collections$ReverseComparator
-java.util.Collections$ReverseComparator2
-java.util.Collections$SetFromMap
-java.util.Collections$SingletonList
-java.util.Collections$SingletonMap
-java.util.Collections$SingletonSet
-java.util.Collections$SynchronizedCollection
-java.util.Collections$SynchronizedList
-java.util.Collections$SynchronizedMap
-java.util.Collections$SynchronizedNavigableMap
-java.util.Collections$SynchronizedNavigableSet
-java.util.Collections$SynchronizedRandomAccessList
-java.util.Collections$SynchronizedSet
-java.util.Collections$SynchronizedSortedMap
-java.util.Collections$SynchronizedSortedSet
-java.util.Collections$UnmodifiableCollection
-java.util.Collections$UnmodifiableCollection$1
-java.util.Collections$UnmodifiableList
-java.util.Collections$UnmodifiableList$1
-java.util.Collections$UnmodifiableMap
-java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet
-java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$1
-java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry
-java.util.Collections$UnmodifiableNavigableMap
-java.util.Collections$UnmodifiableNavigableMap$EmptyNavigableMap
-java.util.Collections$UnmodifiableNavigableSet
-java.util.Collections$UnmodifiableNavigableSet$EmptyNavigableSet
-java.util.Collections$UnmodifiableRandomAccessList
-java.util.Collections$UnmodifiableSet
-java.util.Collections$UnmodifiableSortedMap
-java.util.Collections$UnmodifiableSortedSet
-java.util.ComparableTimSort
-java.util.Comparator
-java.util.Comparators$NaturalOrderComparator
-java.util.Comparators$NullComparator
-java.util.ConcurrentModificationException
-java.util.Currency
-java.util.Date
-java.util.Deque
-java.util.Dictionary
-java.util.DualPivotQuicksort
-java.util.EmptyStackException
-java.util.EnumMap
-java.util.EnumMap$1
-java.util.EnumMap$EntryIterator
-java.util.EnumMap$EntryIterator$Entry
-java.util.EnumMap$EntrySet
-java.util.EnumMap$EnumMapIterator
-java.util.EnumMap$KeyIterator
-java.util.EnumMap$KeySet
-java.util.EnumMap$ValueIterator
-java.util.EnumMap$Values
-java.util.EnumSet
-java.util.EnumSet$SerializationProxy
-java.util.Enumeration
-java.util.EventListener
-java.util.FormatFlagsConversionMismatchException
-java.util.Formattable
-java.util.Formatter
-java.util.Formatter$Conversion
-java.util.Formatter$DateTime
-java.util.Formatter$FixedString
-java.util.Formatter$Flags
-java.util.Formatter$FormatSpecifier
-java.util.Formatter$FormatSpecifierParser
-java.util.Formatter$FormatString
-java.util.FormatterClosedException
-java.util.GregorianCalendar
-java.util.HashMap
-java.util.HashMap$EntryIterator
-java.util.HashMap$EntrySet
-java.util.HashMap$HashIterator
-java.util.HashMap$KeyIterator
-java.util.HashMap$KeySet
-java.util.HashMap$Node
-java.util.HashMap$TreeNode
-java.util.HashMap$ValueIterator
-java.util.HashMap$Values
-java.util.HashSet
-java.util.Hashtable
-java.util.Hashtable$EntrySet
-java.util.Hashtable$Enumerator
-java.util.Hashtable$HashtableEntry
-java.util.Hashtable$KeySet
-java.util.Hashtable$ValueCollection
-java.util.IdentityHashMap
-java.util.IdentityHashMap$EntryIterator
-java.util.IdentityHashMap$EntryIterator$Entry
-java.util.IdentityHashMap$EntrySet
-java.util.IdentityHashMap$IdentityHashMapIterator
-java.util.IdentityHashMap$KeyIterator
-java.util.IdentityHashMap$KeySet
-java.util.IdentityHashMap$ValueIterator
-java.util.IdentityHashMap$Values
-java.util.IllegalFormatException
-java.util.IllformedLocaleException
-java.util.Iterator
-java.util.JumboEnumSet
-java.util.JumboEnumSet$EnumSetIterator
-java.util.LinkedHashMap
-java.util.LinkedHashMap$LinkedEntryIterator
-java.util.LinkedHashMap$LinkedEntrySet
-java.util.LinkedHashMap$LinkedHashIterator
-java.util.LinkedHashMap$LinkedHashMapEntry
-java.util.LinkedHashMap$LinkedKeyIterator
-java.util.LinkedHashMap$LinkedKeySet
-java.util.LinkedHashMap$LinkedValueIterator
-java.util.LinkedHashMap$LinkedValues
-java.util.LinkedHashSet
-java.util.LinkedList
-java.util.LinkedList$DescendingIterator
-java.util.LinkedList$ListItr
-java.util.LinkedList$Node
-java.util.List
-java.util.ListIterator
-java.util.Locale
-java.util.Locale$Builder
-java.util.Locale$Cache
-java.util.Locale$Category
-java.util.Locale$FilteringMode
-java.util.Locale$LanguageRange
-java.util.Locale$LocaleKey
-java.util.Locale$NoImagePreloadHolder
-java.util.Map
-java.util.Map$Entry
-java.util.MissingFormatArgumentException
-java.util.MissingResourceException
-java.util.NavigableMap
-java.util.NavigableSet
-java.util.NoSuchElementException
-java.util.Objects
-java.util.Observable
-java.util.Observer
-java.util.Optional
-java.util.PrimitiveIterator
-java.util.PrimitiveIterator$OfInt
-java.util.PriorityQueue
-java.util.PriorityQueue$Itr
-java.util.Properties
-java.util.Properties$LineReader
-java.util.PropertyResourceBundle
-java.util.Queue
-java.util.Random
-java.util.RandomAccess
-java.util.RandomAccessSubList
-java.util.RegularEnumSet
-java.util.RegularEnumSet$EnumSetIterator
-java.util.ResourceBundle
-java.util.ResourceBundle$1
-java.util.ResourceBundle$BundleReference
-java.util.ResourceBundle$CacheKey
-java.util.ResourceBundle$CacheKeyReference
-java.util.ResourceBundle$Control
-java.util.ResourceBundle$Control$1
-java.util.ResourceBundle$Control$CandidateListCache
-java.util.ResourceBundle$LoaderReference
-java.util.Scanner
-java.util.Scanner$1
-java.util.ServiceConfigurationError
-java.util.ServiceLoader
-java.util.ServiceLoader$1
-java.util.ServiceLoader$LazyIterator
-java.util.Set
-java.util.SimpleTimeZone
-java.util.SortedMap
-java.util.SortedSet
-java.util.Spliterator
-java.util.Spliterator$OfDouble
-java.util.Spliterator$OfInt
-java.util.Spliterator$OfLong
-java.util.Spliterator$OfPrimitive
-java.util.Spliterators
-java.util.Spliterators$EmptySpliterator
-java.util.Spliterators$EmptySpliterator$OfDouble
-java.util.Spliterators$EmptySpliterator$OfInt
-java.util.Spliterators$EmptySpliterator$OfLong
-java.util.Spliterators$EmptySpliterator$OfRef
-java.util.Spliterators$IntArraySpliterator
-java.util.Spliterators$IteratorSpliterator
-java.util.Stack
-java.util.StringJoiner
-java.util.StringTokenizer
-java.util.SubList
-java.util.SubList$1
-java.util.TaskQueue
-java.util.TimSort
-java.util.TimeZone
-java.util.Timer
-java.util.Timer$1
-java.util.TimerTask
-java.util.TimerThread
-java.util.TreeMap
-java.util.TreeMap$AscendingSubMap
-java.util.TreeMap$AscendingSubMap$AscendingEntrySetView
-java.util.TreeMap$EntryIterator
-java.util.TreeMap$EntrySet
-java.util.TreeMap$KeyIterator
-java.util.TreeMap$KeySet
-java.util.TreeMap$NavigableSubMap
-java.util.TreeMap$NavigableSubMap$EntrySetView
-java.util.TreeMap$NavigableSubMap$SubMapEntryIterator
-java.util.TreeMap$NavigableSubMap$SubMapIterator
-java.util.TreeMap$NavigableSubMap$SubMapKeyIterator
-java.util.TreeMap$PrivateEntryIterator
-java.util.TreeMap$TreeMapEntry
-java.util.TreeMap$ValueIterator
-java.util.TreeMap$Values
-java.util.TreeSet
-java.util.UUID
-java.util.UUID$Holder
-java.util.UnknownFormatConversionException
-java.util.Vector
-java.util.Vector$1
-java.util.Vector$Itr
-java.util.WeakHashMap
-java.util.WeakHashMap$Entry
-java.util.WeakHashMap$EntrySet
-java.util.WeakHashMap$HashIterator
-java.util.WeakHashMap$KeyIterator
-java.util.WeakHashMap$KeySet
-java.util.WeakHashMap$ValueIterator
-java.util.WeakHashMap$Values
-java.util.concurrent.-$Lambda$xR9BLpu6SifNikvFgr4lEiECBsk
-java.util.concurrent.AbstractExecutorService
-java.util.concurrent.ArrayBlockingQueue
-java.util.concurrent.BlockingDeque
-java.util.concurrent.BlockingQueue
-java.util.concurrent.Callable
-java.util.concurrent.CancellationException
-java.util.concurrent.CompletableFuture
-java.util.concurrent.CompletableFuture$AltResult
-java.util.concurrent.CompletableFuture$AsynchronousCompletionTask
-java.util.concurrent.CompletableFuture$Completion
-java.util.concurrent.CompletionStage
-java.util.concurrent.ConcurrentHashMap
-java.util.concurrent.ConcurrentHashMap$BaseIterator
-java.util.concurrent.ConcurrentHashMap$BulkTask
-java.util.concurrent.ConcurrentHashMap$CollectionView
-java.util.concurrent.ConcurrentHashMap$CounterCell
-java.util.concurrent.ConcurrentHashMap$EntryIterator
-java.util.concurrent.ConcurrentHashMap$EntrySetView
-java.util.concurrent.ConcurrentHashMap$ForEachEntryTask
-java.util.concurrent.ConcurrentHashMap$ForEachKeyTask
-java.util.concurrent.ConcurrentHashMap$ForEachMappingTask
-java.util.concurrent.ConcurrentHashMap$ForEachTransformedEntryTask
-java.util.concurrent.ConcurrentHashMap$ForEachTransformedKeyTask
-java.util.concurrent.ConcurrentHashMap$ForEachTransformedMappingTask
-java.util.concurrent.ConcurrentHashMap$ForEachTransformedValueTask
-java.util.concurrent.ConcurrentHashMap$ForEachValueTask
-java.util.concurrent.ConcurrentHashMap$ForwardingNode
-java.util.concurrent.ConcurrentHashMap$KeyIterator
-java.util.concurrent.ConcurrentHashMap$KeySetView
-java.util.concurrent.ConcurrentHashMap$KeySpliterator
-java.util.concurrent.ConcurrentHashMap$MapEntry
-java.util.concurrent.ConcurrentHashMap$MapReduceEntriesTask
-java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToDoubleTask
-java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToIntTask
-java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToLongTask
-java.util.concurrent.ConcurrentHashMap$MapReduceKeysTask
-java.util.concurrent.ConcurrentHashMap$MapReduceKeysToDoubleTask
-java.util.concurrent.ConcurrentHashMap$MapReduceKeysToIntTask
-java.util.concurrent.ConcurrentHashMap$MapReduceKeysToLongTask
-java.util.concurrent.ConcurrentHashMap$MapReduceMappingsTask
-java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToDoubleTask
-java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToIntTask
-java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToLongTask
-java.util.concurrent.ConcurrentHashMap$MapReduceValuesTask
-java.util.concurrent.ConcurrentHashMap$MapReduceValuesToDoubleTask
-java.util.concurrent.ConcurrentHashMap$MapReduceValuesToIntTask
-java.util.concurrent.ConcurrentHashMap$MapReduceValuesToLongTask
-java.util.concurrent.ConcurrentHashMap$Node
-java.util.concurrent.ConcurrentHashMap$ReduceEntriesTask
-java.util.concurrent.ConcurrentHashMap$ReduceKeysTask
-java.util.concurrent.ConcurrentHashMap$ReduceValuesTask
-java.util.concurrent.ConcurrentHashMap$ReservationNode
-java.util.concurrent.ConcurrentHashMap$SearchEntriesTask
-java.util.concurrent.ConcurrentHashMap$SearchKeysTask
-java.util.concurrent.ConcurrentHashMap$SearchMappingsTask
-java.util.concurrent.ConcurrentHashMap$SearchValuesTask
-java.util.concurrent.ConcurrentHashMap$Segment
-java.util.concurrent.ConcurrentHashMap$Traverser
-java.util.concurrent.ConcurrentHashMap$TreeBin
-java.util.concurrent.ConcurrentHashMap$TreeNode
-java.util.concurrent.ConcurrentHashMap$ValueIterator
-java.util.concurrent.ConcurrentHashMap$ValuesView
-java.util.concurrent.ConcurrentLinkedDeque
-java.util.concurrent.ConcurrentLinkedDeque$Node
-java.util.concurrent.ConcurrentLinkedQueue
-java.util.concurrent.ConcurrentLinkedQueue$Itr
-java.util.concurrent.ConcurrentLinkedQueue$Node
-java.util.concurrent.ConcurrentMap
-java.util.concurrent.ConcurrentNavigableMap
-java.util.concurrent.ConcurrentSkipListMap
-java.util.concurrent.ConcurrentSkipListMap$HeadIndex
-java.util.concurrent.ConcurrentSkipListMap$Index
-java.util.concurrent.ConcurrentSkipListMap$Iter
-java.util.concurrent.ConcurrentSkipListMap$Node
-java.util.concurrent.ConcurrentSkipListMap$ValueIterator
-java.util.concurrent.ConcurrentSkipListMap$Values
-java.util.concurrent.CopyOnWriteArrayList
-java.util.concurrent.CopyOnWriteArrayList$COWIterator
-java.util.concurrent.CopyOnWriteArraySet
-java.util.concurrent.CountDownLatch
-java.util.concurrent.CountDownLatch$Sync
-java.util.concurrent.CountedCompleter
-java.util.concurrent.DelayQueue
-java.util.concurrent.Delayed
-java.util.concurrent.ExecutionException
-java.util.concurrent.Executor
-java.util.concurrent.ExecutorService
-java.util.concurrent.Executors
-java.util.concurrent.Executors$DefaultThreadFactory
-java.util.concurrent.Executors$DelegatedExecutorService
-java.util.concurrent.Executors$DelegatedScheduledExecutorService
-java.util.concurrent.Executors$FinalizableDelegatedExecutorService
-java.util.concurrent.Executors$RunnableAdapter
-java.util.concurrent.ForkJoinPool
-java.util.concurrent.ForkJoinPool$1
-java.util.concurrent.ForkJoinPool$DefaultForkJoinWorkerThreadFactory
-java.util.concurrent.ForkJoinPool$ForkJoinWorkerThreadFactory
-java.util.concurrent.ForkJoinTask
-java.util.concurrent.ForkJoinTask$ExceptionNode
-java.util.concurrent.Future
-java.util.concurrent.FutureTask
-java.util.concurrent.FutureTask$WaitNode
-java.util.concurrent.LinkedBlockingDeque
-java.util.concurrent.LinkedBlockingDeque$AbstractItr
-java.util.concurrent.LinkedBlockingDeque$Itr
-java.util.concurrent.LinkedBlockingDeque$Node
-java.util.concurrent.LinkedBlockingQueue
-java.util.concurrent.LinkedBlockingQueue$Itr
-java.util.concurrent.LinkedBlockingQueue$Node
-java.util.concurrent.PriorityBlockingQueue
-java.util.concurrent.RejectedExecutionException
-java.util.concurrent.RejectedExecutionHandler
-java.util.concurrent.RunnableFuture
-java.util.concurrent.RunnableScheduledFuture
-java.util.concurrent.ScheduledExecutorService
-java.util.concurrent.ScheduledFuture
-java.util.concurrent.ScheduledThreadPoolExecutor
-java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue
-java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask
-java.util.concurrent.Semaphore
-java.util.concurrent.Semaphore$NonfairSync
-java.util.concurrent.Semaphore$Sync
-java.util.concurrent.SynchronousQueue
-java.util.concurrent.SynchronousQueue$TransferQueue
-java.util.concurrent.SynchronousQueue$TransferStack
-java.util.concurrent.SynchronousQueue$TransferStack$SNode
-java.util.concurrent.SynchronousQueue$Transferer
-java.util.concurrent.ThreadFactory
-java.util.concurrent.ThreadLocalRandom
-java.util.concurrent.ThreadLocalRandom$1
-java.util.concurrent.ThreadPoolExecutor
-java.util.concurrent.ThreadPoolExecutor$AbortPolicy
-java.util.concurrent.ThreadPoolExecutor$DiscardOldestPolicy
-java.util.concurrent.ThreadPoolExecutor$DiscardPolicy
-java.util.concurrent.ThreadPoolExecutor$Worker
-java.util.concurrent.TimeUnit
-java.util.concurrent.TimeUnit$1
-java.util.concurrent.TimeUnit$2
-java.util.concurrent.TimeUnit$3
-java.util.concurrent.TimeUnit$4
-java.util.concurrent.TimeUnit$5
-java.util.concurrent.TimeUnit$6
-java.util.concurrent.TimeUnit$7
-java.util.concurrent.TimeoutException
-java.util.concurrent.atomic.AtomicBoolean
-java.util.concurrent.atomic.AtomicInteger
-java.util.concurrent.atomic.AtomicIntegerArray
-java.util.concurrent.atomic.AtomicIntegerFieldUpdater
-java.util.concurrent.atomic.AtomicIntegerFieldUpdater$AtomicIntegerFieldUpdaterImpl
-java.util.concurrent.atomic.AtomicIntegerFieldUpdater$AtomicIntegerFieldUpdaterImpl$1
-java.util.concurrent.atomic.AtomicLong
-java.util.concurrent.atomic.AtomicLongArray
-java.util.concurrent.atomic.AtomicReference
-java.util.concurrent.atomic.AtomicReferenceArray
-java.util.concurrent.atomic.AtomicReferenceFieldUpdater
-java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl
-java.util.concurrent.locks.AbstractOwnableSynchronizer
-java.util.concurrent.locks.AbstractQueuedSynchronizer
-java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject
-java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
-java.util.concurrent.locks.Condition
-java.util.concurrent.locks.Lock
-java.util.concurrent.locks.LockSupport
-java.util.concurrent.locks.ReadWriteLock
-java.util.concurrent.locks.ReentrantLock
-java.util.concurrent.locks.ReentrantLock$FairSync
-java.util.concurrent.locks.ReentrantLock$NonfairSync
-java.util.concurrent.locks.ReentrantLock$Sync
-java.util.concurrent.locks.ReentrantReadWriteLock
-java.util.concurrent.locks.ReentrantReadWriteLock$FairSync
-java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync
-java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock
-java.util.concurrent.locks.ReentrantReadWriteLock$Sync
-java.util.concurrent.locks.ReentrantReadWriteLock$Sync$HoldCounter
-java.util.concurrent.locks.ReentrantReadWriteLock$Sync$ThreadLocalHoldCounter
-java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock
-java.util.function.-$Lambda$1MZdIZ-DL_fjy9l0o8IMJk57T2g
-java.util.function.-$Lambda$VGDeaUHZQIZywZW2ttlyhwk3Cmk
-java.util.function.-$Lambda$VGDeaUHZQIZywZW2ttlyhwk3Cmk$1
-java.util.function.BiConsumer
-java.util.function.BiFunction
-java.util.function.BinaryOperator
-java.util.function.Consumer
-java.util.function.DoubleBinaryOperator
-java.util.function.DoubleUnaryOperator
-java.util.function.Function
-java.util.function.IntBinaryOperator
-java.util.function.IntConsumer
-java.util.function.IntFunction
-java.util.function.IntToDoubleFunction
-java.util.function.IntToLongFunction
-java.util.function.IntUnaryOperator
-java.util.function.LongBinaryOperator
-java.util.function.LongConsumer
-java.util.function.LongUnaryOperator
-java.util.function.Predicate
-java.util.function.Supplier
-java.util.function.ToDoubleBiFunction
-java.util.function.ToDoubleFunction
-java.util.function.ToIntBiFunction
-java.util.function.ToIntFunction
-java.util.function.ToLongBiFunction
-java.util.function.ToLongFunction
-java.util.function.UnaryOperator
-java.util.jar.Attributes
-java.util.jar.Attributes$Name
-java.util.jar.JarEntry
-java.util.jar.JarFile
-java.util.jar.JarFile$JarEntryIterator
-java.util.jar.JarFile$JarFileEntry
-java.util.jar.JarVerifier
-java.util.jar.JarVerifier$1
-java.util.jar.JarVerifier$VerifierStream
-java.util.jar.Manifest
-java.util.jar.Manifest$FastInputStream
-java.util.logging.ErrorManager
-java.util.logging.FileHandler
-java.util.logging.FileHandler$InitializationErrorManager
-java.util.logging.FileHandler$MeteredStream
-java.util.logging.Filter
-java.util.logging.Formatter
-java.util.logging.Handler
-java.util.logging.Level
-java.util.logging.Level$KnownLevel
-java.util.logging.LogManager
-java.util.logging.LogManager$1
-java.util.logging.LogManager$2
-java.util.logging.LogManager$3
-java.util.logging.LogManager$5
-java.util.logging.LogManager$Cleaner
-java.util.logging.LogManager$LogNode
-java.util.logging.LogManager$LoggerContext
-java.util.logging.LogManager$LoggerContext$1
-java.util.logging.LogManager$LoggerWeakRef
-java.util.logging.LogManager$RootLogger
-java.util.logging.LogManager$SystemLoggerContext
-java.util.logging.LogRecord
-java.util.logging.Logger
-java.util.logging.Logger$1
-java.util.logging.Logger$LoggerBundle
-java.util.logging.LoggingPermission
-java.util.logging.LoggingProxyImpl
-java.util.logging.SimpleFormatter
-java.util.logging.StreamHandler
-java.util.logging.XMLFormatter
-java.util.prefs.AbstractPreferences
-java.util.prefs.FileSystemPreferences
-java.util.prefs.Preferences
-java.util.regex.MatchResult
-java.util.regex.Matcher
-java.util.regex.Matcher$OffsetBasedMatchResult
-java.util.regex.Pattern
-java.util.regex.PatternSyntaxException
-java.util.stream.-$Lambda$DJvCeprCIGMk0JvfSkTmQUmEYKA$1
-java.util.stream.-$Lambda$QgGTJrv63_zzBbeGjswm_UMqEbo$12
-java.util.stream.-$Lambda$QgGTJrv63_zzBbeGjswm_UMqEbo$5
-java.util.stream.-$Lambda$QgGTJrv63_zzBbeGjswm_UMqEbo$6
-java.util.stream.-$Lambda$RYrQKhHyGc-mMxiERR98xxRAWkA$5
-java.util.stream.-$Lambda$ioGbka_-VkWTFjRjTt8T4zzsxgk$3
-java.util.stream.-$Lambda$ioGbka_-VkWTFjRjTt8T4zzsxgk$7
-java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$21
-java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$22
-java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$26
-java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$4
-java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$5
-java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$51
-java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$54
-java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$67
-java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$83
-java.util.stream.AbstractPipeline
-java.util.stream.AbstractSpinedBuffer
-java.util.stream.BaseStream
-java.util.stream.Collector
-java.util.stream.Collector$Characteristics
-java.util.stream.Collectors
-java.util.stream.Collectors$CollectorImpl
-java.util.stream.DistinctOps
-java.util.stream.DistinctOps$1
-java.util.stream.DistinctOps$1$2
-java.util.stream.DoubleStream
-java.util.stream.FindOps
-java.util.stream.FindOps$FindOp
-java.util.stream.FindOps$FindSink
-java.util.stream.FindOps$FindSink$OfRef
-java.util.stream.ForEachOps
-java.util.stream.ForEachOps$ForEachOp
-java.util.stream.ForEachOps$ForEachOp$OfRef
-java.util.stream.IntPipeline
-java.util.stream.IntPipeline$4
-java.util.stream.IntPipeline$4$1
-java.util.stream.IntPipeline$Head
-java.util.stream.IntPipeline$StatelessOp
-java.util.stream.IntStream
-java.util.stream.LongPipeline
-java.util.stream.LongPipeline$StatelessOp
-java.util.stream.LongStream
-java.util.stream.Node
-java.util.stream.Node$Builder
-java.util.stream.Node$Builder$OfInt
-java.util.stream.Node$OfDouble
-java.util.stream.Node$OfInt
-java.util.stream.Node$OfLong
-java.util.stream.Node$OfPrimitive
-java.util.stream.Nodes
-java.util.stream.Nodes$EmptyNode
-java.util.stream.Nodes$EmptyNode$OfDouble
-java.util.stream.Nodes$EmptyNode$OfInt
-java.util.stream.Nodes$EmptyNode$OfLong
-java.util.stream.Nodes$EmptyNode$OfRef
-java.util.stream.Nodes$IntSpinedNodeBuilder
-java.util.stream.PipelineHelper
-java.util.stream.ReduceOps
-java.util.stream.ReduceOps$3
-java.util.stream.ReduceOps$3ReducingSink
-java.util.stream.ReduceOps$8
-java.util.stream.ReduceOps$8ReducingSink
-java.util.stream.ReduceOps$AccumulatingSink
-java.util.stream.ReduceOps$Box
-java.util.stream.ReduceOps$ReduceOp
-java.util.stream.ReferencePipeline
-java.util.stream.ReferencePipeline$2
-java.util.stream.ReferencePipeline$2$1
-java.util.stream.ReferencePipeline$3
-java.util.stream.ReferencePipeline$3$1
-java.util.stream.ReferencePipeline$4
-java.util.stream.ReferencePipeline$4$1
-java.util.stream.ReferencePipeline$5
-java.util.stream.ReferencePipeline$5$1
-java.util.stream.ReferencePipeline$Head
-java.util.stream.ReferencePipeline$StatefulOp
-java.util.stream.ReferencePipeline$StatelessOp
-java.util.stream.Sink
-java.util.stream.Sink$ChainedInt
-java.util.stream.Sink$ChainedReference
-java.util.stream.Sink$OfInt
-java.util.stream.Sink$OfLong
-java.util.stream.SliceOps
-java.util.stream.SliceOps$1
-java.util.stream.SliceOps$1$1
-java.util.stream.SpinedBuffer$OfInt
-java.util.stream.SpinedBuffer$OfPrimitive
-java.util.stream.Stream
-java.util.stream.StreamOpFlag
-java.util.stream.StreamOpFlag$MaskBuilder
-java.util.stream.StreamOpFlag$Type
-java.util.stream.StreamShape
-java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator
-java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator$OfRef
-java.util.stream.StreamSupport
-java.util.stream.TerminalOp
-java.util.stream.TerminalSink
-java.util.zip.Adler32
-java.util.zip.CRC32
-java.util.zip.CheckedInputStream
-java.util.zip.Checksum
-java.util.zip.DataFormatException
-java.util.zip.Deflater
-java.util.zip.DeflaterOutputStream
-java.util.zip.GZIPInputStream
-java.util.zip.GZIPInputStream$1
-java.util.zip.GZIPOutputStream
-java.util.zip.Inflater
-java.util.zip.InflaterInputStream
-java.util.zip.ZStreamRef
-java.util.zip.ZipCoder
-java.util.zip.ZipConstants
-java.util.zip.ZipEntry
-java.util.zip.ZipException
-java.util.zip.ZipFile
-java.util.zip.ZipFile$ZipEntryIterator
-java.util.zip.ZipFile$ZipFileInflaterInputStream
-java.util.zip.ZipFile$ZipFileInputStream
-java.util.zip.ZipInputStream
-java.util.zip.ZipUtils
-javax.crypto.BadPaddingException
-javax.crypto.Cipher
-javax.crypto.Cipher$CipherSpiAndProvider
-javax.crypto.Cipher$InitParams
-javax.crypto.Cipher$InitType
-javax.crypto.Cipher$NeedToSet
-javax.crypto.Cipher$SpiAndProviderUpdater
-javax.crypto.Cipher$Transform
-javax.crypto.CipherSpi
-javax.crypto.IllegalBlockSizeException
-javax.crypto.JarVerifier
-javax.crypto.JceSecurity
-javax.crypto.JceSecurity$1
-javax.crypto.KeyGenerator
-javax.crypto.KeyGeneratorSpi
-javax.crypto.Mac
-javax.crypto.MacSpi
-javax.crypto.NoSuchPaddingException
-javax.crypto.NullCipher
-javax.crypto.SecretKey
-javax.crypto.ShortBufferException
-javax.crypto.spec.IvParameterSpec
-javax.crypto.spec.OAEPParameterSpec
-javax.crypto.spec.PBEParameterSpec
-javax.crypto.spec.PSource
-javax.crypto.spec.PSource$PSpecified
-javax.crypto.spec.SecretKeySpec
-javax.microedition.khronos.egl.EGL
-javax.microedition.khronos.egl.EGL10
-javax.microedition.khronos.egl.EGLConfig
-javax.microedition.khronos.egl.EGLContext
-javax.microedition.khronos.egl.EGLDisplay
-javax.microedition.khronos.egl.EGLSurface
-javax.microedition.khronos.opengles.GL
-javax.microedition.khronos.opengles.GL10
-javax.microedition.khronos.opengles.GL10Ext
-javax.microedition.khronos.opengles.GL11
-javax.microedition.khronos.opengles.GL11Ext
-javax.microedition.khronos.opengles.GL11ExtensionPack
-javax.net.DefaultSocketFactory
-javax.net.ServerSocketFactory
-javax.net.SocketFactory
-javax.net.ssl.ExtendedSSLSession
-javax.net.ssl.HandshakeCompletedListener
-javax.net.ssl.HostnameVerifier
-javax.net.ssl.HttpsURLConnection
-javax.net.ssl.KeyManager
-javax.net.ssl.KeyManagerFactory
-javax.net.ssl.KeyManagerFactory$1
-javax.net.ssl.KeyManagerFactorySpi
-javax.net.ssl.SNIHostName
-javax.net.ssl.SNIServerName
-javax.net.ssl.SSLContext
-javax.net.ssl.SSLContextSpi
-javax.net.ssl.SSLEngine
-javax.net.ssl.SSLException
-javax.net.ssl.SSLParameters
-javax.net.ssl.SSLPeerUnverifiedException
-javax.net.ssl.SSLProtocolException
-javax.net.ssl.SSLServerSocketFactory
-javax.net.ssl.SSLSession
-javax.net.ssl.SSLSessionContext
-javax.net.ssl.SSLSocket
-javax.net.ssl.SSLSocketFactory
-javax.net.ssl.SSLSocketFactory$1
-javax.net.ssl.TrustManager
-javax.net.ssl.TrustManagerFactory
-javax.net.ssl.TrustManagerFactory$1
-javax.net.ssl.TrustManagerFactorySpi
-javax.net.ssl.X509ExtendedKeyManager
-javax.net.ssl.X509ExtendedTrustManager
-javax.net.ssl.X509KeyManager
-javax.net.ssl.X509TrustManager
-javax.security.auth.Destroyable
-javax.security.auth.callback.UnsupportedCallbackException
-javax.security.auth.x500.X500Principal
-javax.security.cert.Certificate
-javax.security.cert.CertificateEncodingException
-javax.security.cert.CertificateException
-javax.security.cert.X509Certificate
-javax.sip.SipException
-javax.xml.parsers.ParserConfigurationException
-javax.xml.parsers.SAXParser
-javax.xml.parsers.SAXParserFactory
-javax.xml.transform.TransformerConfigurationException
-javax.xml.transform.TransformerException
-junit.framework.Assert
-libcore.icu.CollationKeyICU
-libcore.icu.DateIntervalFormat
-libcore.icu.DateUtilsBridge
-libcore.icu.ICU
-libcore.icu.LocaleData
-libcore.icu.NativeConverter
-libcore.icu.RelativeDateTimeFormatter
-libcore.icu.RelativeDateTimeFormatter$FormatterCache
-libcore.icu.TimeZoneNames
-libcore.icu.TimeZoneNames$1
-libcore.icu.TimeZoneNames$ZoneStringsCache
-libcore.internal.StringPool
-libcore.io.AsynchronousCloseMonitor
-libcore.io.BlockGuardOs
-libcore.io.BufferIterator
-libcore.io.ClassPathURLStreamHandler
-libcore.io.ClassPathURLStreamHandler$ClassPathURLConnection
-libcore.io.ClassPathURLStreamHandler$ClassPathURLConnection$1
-libcore.io.DropBox
-libcore.io.DropBox$DefaultReporter
-libcore.io.DropBox$Reporter
-libcore.io.EventLogger
-libcore.io.EventLogger$DefaultReporter
-libcore.io.EventLogger$Reporter
-libcore.io.ForwardingOs
-libcore.io.IoBridge
-libcore.io.IoTracker
-libcore.io.IoTracker$Mode
-libcore.io.IoUtils
-libcore.io.IoUtils$FileReader
-libcore.io.Libcore
-libcore.io.Linux
-libcore.io.Memory
-libcore.io.MemoryMappedFile
-libcore.io.NioBufferIterator
-libcore.io.Os
-libcore.io.Streams
-libcore.math.MathUtils
-libcore.net.MimeUtils
-libcore.net.NetworkSecurityPolicy
-libcore.net.NetworkSecurityPolicy$DefaultNetworkSecurityPolicy
-libcore.net.UriCodec
-libcore.net.event.NetworkEventDispatcher
-libcore.net.event.NetworkEventListener
-libcore.reflect.AnnotatedElements
-libcore.reflect.AnnotationFactory
-libcore.reflect.AnnotationMember
-libcore.reflect.AnnotationMember$DefaultValues
-libcore.reflect.GenericArrayTypeImpl
-libcore.reflect.GenericSignatureParser
-libcore.reflect.ListOfTypes
-libcore.reflect.ListOfVariables
-libcore.reflect.ParameterizedTypeImpl
-libcore.reflect.TypeVariableImpl
-libcore.reflect.Types
-libcore.util.BasicLruCache
-libcore.util.CharsetUtils
-libcore.util.CollectionUtils
-libcore.util.EmptyArray
-libcore.util.HexEncoding
-libcore.util.NativeAllocationRegistry
-libcore.util.NativeAllocationRegistry$CleanerRunner
-libcore.util.NativeAllocationRegistry$CleanerThunk
-libcore.util.Objects
-libcore.util.TimeZoneDataFiles
-libcore.util.ZoneInfo
-libcore.util.ZoneInfo$CheckedArithmeticException
-libcore.util.ZoneInfo$OffsetInterval
-libcore.util.ZoneInfo$WallTime
-libcore.util.ZoneInfoDB
-libcore.util.ZoneInfoDB$TzData
-libcore.util.ZoneInfoDB$TzData$1
-org.apache.commons.logging.Log
-org.apache.commons.logging.LogFactory
-org.apache.commons.logging.impl.Jdk14Logger
-org.apache.commons.logging.impl.WeakHashtable
-org.apache.harmony.dalvik.NativeTestTarget
-org.apache.harmony.dalvik.ddmc.Chunk
-org.apache.harmony.dalvik.ddmc.ChunkHandler
-org.apache.harmony.dalvik.ddmc.DdmServer
-org.apache.harmony.dalvik.ddmc.DdmVmInternal
-org.apache.harmony.luni.internal.util.TimezoneGetter
-org.apache.harmony.xml.ExpatAttributes
-org.apache.harmony.xml.ExpatException
-org.apache.harmony.xml.ExpatParser
-org.apache.harmony.xml.ExpatParser$CurrentAttributes
-org.apache.harmony.xml.ExpatParser$ExpatLocator
-org.apache.harmony.xml.ExpatReader
-org.apache.harmony.xml.parsers.SAXParserFactoryImpl
-org.apache.harmony.xml.parsers.SAXParserImpl
-org.apache.http.ConnectionReuseStrategy
-org.apache.http.FormattedHeader
-org.apache.http.Header
-org.apache.http.HeaderElement
-org.apache.http.HeaderElementIterator
-org.apache.http.HeaderIterator
-org.apache.http.HttpClientConnection
-org.apache.http.HttpConnection
-org.apache.http.HttpConnectionMetrics
-org.apache.http.HttpEntity
-org.apache.http.HttpEntityEnclosingRequest
-org.apache.http.HttpException
-org.apache.http.HttpHost
-org.apache.http.HttpInetConnection
-org.apache.http.HttpMessage
-org.apache.http.HttpRequest
-org.apache.http.HttpRequestFactory
-org.apache.http.HttpRequestInterceptor
-org.apache.http.HttpResponse
-org.apache.http.HttpResponseFactory
-org.apache.http.HttpResponseInterceptor
-org.apache.http.HttpServerConnection
-org.apache.http.HttpVersion
-org.apache.http.NameValuePair
-org.apache.http.ParseException
-org.apache.http.ProtocolException
-org.apache.http.ProtocolVersion
-org.apache.http.ReasonPhraseCatalog
-org.apache.http.RequestLine
-org.apache.http.StatusLine
-org.apache.http.auth.AuthSchemeFactory
-org.apache.http.auth.AuthSchemeRegistry
-org.apache.http.auth.AuthState
-org.apache.http.auth.AuthenticationException
-org.apache.http.client.AuthenticationHandler
-org.apache.http.client.ClientProtocolException
-org.apache.http.client.CookieStore
-org.apache.http.client.CredentialsProvider
-org.apache.http.client.HttpClient
-org.apache.http.client.HttpRequestRetryHandler
-org.apache.http.client.HttpResponseException
-org.apache.http.client.RedirectHandler
-org.apache.http.client.RequestDirector
-org.apache.http.client.ResponseHandler
-org.apache.http.client.UserTokenHandler
-org.apache.http.client.entity.UrlEncodedFormEntity
-org.apache.http.client.methods.AbortableHttpRequest
-org.apache.http.client.methods.HttpEntityEnclosingRequestBase
-org.apache.http.client.methods.HttpGet
-org.apache.http.client.methods.HttpPost
-org.apache.http.client.methods.HttpPut
-org.apache.http.client.methods.HttpRequestBase
-org.apache.http.client.methods.HttpUriRequest
-org.apache.http.client.params.HttpClientParams
-org.apache.http.client.protocol.RequestAddCookies
-org.apache.http.client.protocol.RequestDefaultHeaders
-org.apache.http.client.protocol.RequestProxyAuthentication
-org.apache.http.client.protocol.RequestTargetAuthentication
-org.apache.http.client.protocol.ResponseProcessCookies
-org.apache.http.client.utils.URIUtils
-org.apache.http.client.utils.URLEncodedUtils
-org.apache.http.conn.BasicManagedEntity
-org.apache.http.conn.ClientConnectionManager
-org.apache.http.conn.ClientConnectionOperator
-org.apache.http.conn.ClientConnectionRequest
-org.apache.http.conn.ConnectTimeoutException
-org.apache.http.conn.ConnectionKeepAliveStrategy
-org.apache.http.conn.ConnectionReleaseTrigger
-org.apache.http.conn.EofSensorInputStream
-org.apache.http.conn.EofSensorWatcher
-org.apache.http.conn.ManagedClientConnection
-org.apache.http.conn.OperatedClientConnection
-org.apache.http.conn.params.ConnManagerPNames
-org.apache.http.conn.params.ConnManagerParamBean
-org.apache.http.conn.params.ConnManagerParams
-org.apache.http.conn.params.ConnManagerParams$1
-org.apache.http.conn.params.ConnPerRoute
-org.apache.http.conn.params.ConnPerRouteBean
-org.apache.http.conn.params.ConnRoutePNames
-org.apache.http.conn.params.ConnRouteParams
-org.apache.http.conn.routing.BasicRouteDirector
-org.apache.http.conn.routing.HttpRoute
-org.apache.http.conn.routing.HttpRouteDirector
-org.apache.http.conn.routing.HttpRoutePlanner
-org.apache.http.conn.routing.RouteInfo
-org.apache.http.conn.routing.RouteInfo$LayerType
-org.apache.http.conn.routing.RouteInfo$TunnelType
-org.apache.http.conn.routing.RouteTracker
-org.apache.http.conn.scheme.LayeredSocketFactory
-org.apache.http.conn.scheme.PlainSocketFactory
-org.apache.http.conn.scheme.Scheme
-org.apache.http.conn.scheme.SchemeRegistry
-org.apache.http.conn.scheme.SocketFactory
-org.apache.http.conn.ssl.AbstractVerifier
-org.apache.http.conn.ssl.AllowAllHostnameVerifier
-org.apache.http.conn.ssl.AndroidDistinguishedNameParser
-org.apache.http.conn.ssl.BrowserCompatHostnameVerifier
-org.apache.http.conn.ssl.SSLSocketFactory
-org.apache.http.conn.ssl.StrictHostnameVerifier
-org.apache.http.conn.ssl.X509HostnameVerifier
-org.apache.http.cookie.ClientCookie
-org.apache.http.cookie.Cookie
-org.apache.http.cookie.CookieAttributeHandler
-org.apache.http.cookie.CookieIdentityComparator
-org.apache.http.cookie.CookieOrigin
-org.apache.http.cookie.CookiePathComparator
-org.apache.http.cookie.CookieSpec
-org.apache.http.cookie.CookieSpecFactory
-org.apache.http.cookie.CookieSpecRegistry
-org.apache.http.cookie.MalformedCookieException
-org.apache.http.cookie.SetCookie
-org.apache.http.entity.AbstractHttpEntity
-org.apache.http.entity.BasicHttpEntity
-org.apache.http.entity.ByteArrayEntity
-org.apache.http.entity.ContentLengthStrategy
-org.apache.http.entity.HttpEntityWrapper
-org.apache.http.entity.InputStreamEntity
-org.apache.http.entity.StringEntity
-org.apache.http.impl.AbstractHttpClientConnection
-org.apache.http.impl.AbstractHttpServerConnection
-org.apache.http.impl.DefaultConnectionReuseStrategy
-org.apache.http.impl.DefaultHttpRequestFactory
-org.apache.http.impl.DefaultHttpResponseFactory
-org.apache.http.impl.DefaultHttpServerConnection
-org.apache.http.impl.EnglishReasonPhraseCatalog
-org.apache.http.impl.HttpConnectionMetricsImpl
-org.apache.http.impl.SocketHttpClientConnection
-org.apache.http.impl.SocketHttpServerConnection
-org.apache.http.impl.auth.BasicSchemeFactory
-org.apache.http.impl.auth.DigestSchemeFactory
-org.apache.http.impl.client.AbstractAuthenticationHandler
-org.apache.http.impl.client.AbstractHttpClient
-org.apache.http.impl.client.BasicCookieStore
-org.apache.http.impl.client.BasicCredentialsProvider
-org.apache.http.impl.client.ClientParamsStack
-org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy
-org.apache.http.impl.client.DefaultHttpClient
-org.apache.http.impl.client.DefaultHttpRequestRetryHandler
-org.apache.http.impl.client.DefaultProxyAuthenticationHandler
-org.apache.http.impl.client.DefaultRedirectHandler
-org.apache.http.impl.client.DefaultRequestDirector
-org.apache.http.impl.client.DefaultTargetAuthenticationHandler
-org.apache.http.impl.client.DefaultUserTokenHandler
-org.apache.http.impl.client.EntityEnclosingRequestWrapper
-org.apache.http.impl.client.RequestWrapper
-org.apache.http.impl.client.RoutedRequest
-org.apache.http.impl.client.TunnelRefusedException
-org.apache.http.impl.conn.AbstractClientConnAdapter
-org.apache.http.impl.conn.AbstractPoolEntry
-org.apache.http.impl.conn.AbstractPooledConnAdapter
-org.apache.http.impl.conn.DefaultClientConnection
-org.apache.http.impl.conn.DefaultClientConnectionOperator
-org.apache.http.impl.conn.DefaultResponseParser
-org.apache.http.impl.conn.IdleConnectionHandler
-org.apache.http.impl.conn.IdleConnectionHandler$TimeValues
-org.apache.http.impl.conn.ProxySelectorRoutePlanner
-org.apache.http.impl.conn.tsccm.AbstractConnPool
-org.apache.http.impl.conn.tsccm.BasicPoolEntry
-org.apache.http.impl.conn.tsccm.BasicPoolEntryRef
-org.apache.http.impl.conn.tsccm.BasicPooledConnAdapter
-org.apache.http.impl.conn.tsccm.ConnPoolByRoute
-org.apache.http.impl.conn.tsccm.ConnPoolByRoute$1
-org.apache.http.impl.conn.tsccm.PoolEntryRequest
-org.apache.http.impl.conn.tsccm.RefQueueHandler
-org.apache.http.impl.conn.tsccm.RefQueueWorker
-org.apache.http.impl.conn.tsccm.RouteSpecificPool
-org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager
-org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager$1
-org.apache.http.impl.conn.tsccm.WaitingThreadAborter
-org.apache.http.impl.cookie.AbstractCookieAttributeHandler
-org.apache.http.impl.cookie.AbstractCookieSpec
-org.apache.http.impl.cookie.BasicClientCookie
-org.apache.http.impl.cookie.BasicCommentHandler
-org.apache.http.impl.cookie.BasicDomainHandler
-org.apache.http.impl.cookie.BasicExpiresHandler
-org.apache.http.impl.cookie.BasicMaxAgeHandler
-org.apache.http.impl.cookie.BasicPathHandler
-org.apache.http.impl.cookie.BasicSecureHandler
-org.apache.http.impl.cookie.BestMatchSpec
-org.apache.http.impl.cookie.BestMatchSpecFactory
-org.apache.http.impl.cookie.BrowserCompatSpec
-org.apache.http.impl.cookie.BrowserCompatSpecFactory
-org.apache.http.impl.cookie.CookieSpecBase
-org.apache.http.impl.cookie.DateParseException
-org.apache.http.impl.cookie.DateUtils
-org.apache.http.impl.cookie.DateUtils$DateFormatHolder
-org.apache.http.impl.cookie.DateUtils$DateFormatHolder$1
-org.apache.http.impl.cookie.NetscapeDomainHandler
-org.apache.http.impl.cookie.NetscapeDraftHeaderParser
-org.apache.http.impl.cookie.NetscapeDraftSpec
-org.apache.http.impl.cookie.NetscapeDraftSpecFactory
-org.apache.http.impl.cookie.RFC2109DomainHandler
-org.apache.http.impl.cookie.RFC2109Spec
-org.apache.http.impl.cookie.RFC2109SpecFactory
-org.apache.http.impl.cookie.RFC2109VersionHandler
-org.apache.http.impl.cookie.RFC2965CommentUrlAttributeHandler
-org.apache.http.impl.cookie.RFC2965DiscardAttributeHandler
-org.apache.http.impl.cookie.RFC2965DomainAttributeHandler
-org.apache.http.impl.cookie.RFC2965PortAttributeHandler
-org.apache.http.impl.cookie.RFC2965Spec
-org.apache.http.impl.cookie.RFC2965SpecFactory
-org.apache.http.impl.cookie.RFC2965VersionAttributeHandler
-org.apache.http.impl.entity.EntityDeserializer
-org.apache.http.impl.entity.EntitySerializer
-org.apache.http.impl.entity.LaxContentLengthStrategy
-org.apache.http.impl.entity.StrictContentLengthStrategy
-org.apache.http.impl.io.AbstractMessageParser
-org.apache.http.impl.io.AbstractMessageWriter
-org.apache.http.impl.io.AbstractSessionInputBuffer
-org.apache.http.impl.io.AbstractSessionOutputBuffer
-org.apache.http.impl.io.ChunkedInputStream
-org.apache.http.impl.io.ContentLengthInputStream
-org.apache.http.impl.io.ContentLengthOutputStream
-org.apache.http.impl.io.HttpRequestParser
-org.apache.http.impl.io.HttpRequestWriter
-org.apache.http.impl.io.HttpResponseWriter
-org.apache.http.impl.io.HttpTransportMetricsImpl
-org.apache.http.impl.io.IdentityOutputStream
-org.apache.http.impl.io.SocketInputBuffer
-org.apache.http.impl.io.SocketOutputBuffer
-org.apache.http.io.HttpMessageParser
-org.apache.http.io.HttpMessageWriter
-org.apache.http.io.HttpTransportMetrics
-org.apache.http.io.SessionInputBuffer
-org.apache.http.io.SessionOutputBuffer
-org.apache.http.message.AbstractHttpMessage
-org.apache.http.message.BasicHeader
-org.apache.http.message.BasicHeaderElement
-org.apache.http.message.BasicHeaderElementIterator
-org.apache.http.message.BasicHeaderValueParser
-org.apache.http.message.BasicHttpRequest
-org.apache.http.message.BasicHttpResponse
-org.apache.http.message.BasicLineFormatter
-org.apache.http.message.BasicLineParser
-org.apache.http.message.BasicListHeaderIterator
-org.apache.http.message.BasicNameValuePair
-org.apache.http.message.BasicRequestLine
-org.apache.http.message.BasicStatusLine
-org.apache.http.message.BufferedHeader
-org.apache.http.message.HeaderGroup
-org.apache.http.message.HeaderValueParser
-org.apache.http.message.LineFormatter
-org.apache.http.message.LineParser
-org.apache.http.message.ParserCursor
-org.apache.http.params.AbstractHttpParams
-org.apache.http.params.BasicHttpParams
-org.apache.http.params.CoreConnectionPNames
-org.apache.http.params.CoreProtocolPNames
-org.apache.http.params.DefaultedHttpParams
-org.apache.http.params.HttpAbstractParamBean
-org.apache.http.params.HttpConnectionParams
-org.apache.http.params.HttpParams
-org.apache.http.params.HttpProtocolParams
-org.apache.http.protocol.BasicHttpContext
-org.apache.http.protocol.BasicHttpProcessor
-org.apache.http.protocol.DefaultedHttpContext
-org.apache.http.protocol.HTTP
-org.apache.http.protocol.HttpContext
-org.apache.http.protocol.HttpProcessor
-org.apache.http.protocol.HttpRequestExecutor
-org.apache.http.protocol.HttpRequestHandler
-org.apache.http.protocol.HttpRequestHandlerRegistry
-org.apache.http.protocol.HttpRequestHandlerResolver
-org.apache.http.protocol.HttpRequestInterceptorList
-org.apache.http.protocol.HttpResponseInterceptorList
-org.apache.http.protocol.HttpService
-org.apache.http.protocol.RequestConnControl
-org.apache.http.protocol.RequestContent
-org.apache.http.protocol.RequestExpectContinue
-org.apache.http.protocol.RequestTargetHost
-org.apache.http.protocol.RequestUserAgent
-org.apache.http.protocol.ResponseConnControl
-org.apache.http.protocol.ResponseContent
-org.apache.http.protocol.UriPatternMatcher
-org.apache.http.util.ByteArrayBuffer
-org.apache.http.util.CharArrayBuffer
-org.apache.http.util.EntityUtils
-org.apache.http.util.LangUtils
-org.ccil.cowan.tagsoup.AttributesImpl
-org.ccil.cowan.tagsoup.AutoDetector
-org.ccil.cowan.tagsoup.Element
-org.ccil.cowan.tagsoup.ElementType
-org.ccil.cowan.tagsoup.HTMLModels
-org.ccil.cowan.tagsoup.HTMLScanner
-org.ccil.cowan.tagsoup.HTMLSchema
-org.ccil.cowan.tagsoup.Parser
-org.ccil.cowan.tagsoup.Parser$1
-org.ccil.cowan.tagsoup.ScanHandler
-org.ccil.cowan.tagsoup.Scanner
-org.ccil.cowan.tagsoup.Schema
-org.json.JSON
-org.json.JSONArray
-org.json.JSONException
-org.json.JSONObject
-org.json.JSONObject$1
-org.json.JSONStringer
-org.json.JSONStringer$Scope
-org.json.JSONTokener
-org.kxml2.io.KXmlParser
-org.kxml2.io.KXmlParser$ValueContext
-org.kxml2.io.KXmlSerializer
-org.xml.sax.Attributes
-org.xml.sax.ContentHandler
-org.xml.sax.DTDHandler
-org.xml.sax.EntityResolver
-org.xml.sax.ErrorHandler
-org.xml.sax.InputSource
-org.xml.sax.Locator
-org.xml.sax.SAXException
-org.xml.sax.SAXNotRecognizedException
-org.xml.sax.SAXNotSupportedException
-org.xml.sax.SAXParseException
-org.xml.sax.XMLReader
-org.xml.sax.ext.DeclHandler
-org.xml.sax.ext.DefaultHandler2
-org.xml.sax.ext.EntityResolver2
-org.xml.sax.ext.LexicalHandler
-org.xml.sax.helpers.AttributesImpl
-org.xml.sax.helpers.DefaultHandler
-org.xmlpull.v1.XmlPullParser
-org.xmlpull.v1.XmlPullParserException
-org.xmlpull.v1.XmlPullParserFactory
-org.xmlpull.v1.XmlSerializer
-sun.invoke.util.BytecodeDescriptor
-sun.invoke.util.VerifyAccess
-sun.invoke.util.Wrapper
-sun.invoke.util.Wrapper$Format
-sun.misc.ASCIICaseInsensitiveComparator
-sun.misc.Cleaner
-sun.misc.CompoundEnumeration
-sun.misc.FDBigInteger
-sun.misc.FloatingDecimal
-sun.misc.FloatingDecimal$1
-sun.misc.FloatingDecimal$ASCIIToBinaryBuffer
-sun.misc.FloatingDecimal$ASCIIToBinaryConverter
-sun.misc.FloatingDecimal$BinaryToASCIIBuffer
-sun.misc.FloatingDecimal$BinaryToASCIIConverter
-sun.misc.FloatingDecimal$ExceptionalBinaryToASCIIBuffer
-sun.misc.FloatingDecimal$PreparedASCIIToBinaryBuffer
-sun.misc.FormattedFloatingDecimal
-sun.misc.FormattedFloatingDecimal$1
-sun.misc.FormattedFloatingDecimal$Form
-sun.misc.IOUtils
-sun.misc.JavaIOFileDescriptorAccess
-sun.misc.LRUCache
-sun.misc.REException
-sun.misc.SharedSecrets
-sun.misc.Unsafe
-sun.misc.VM
-sun.misc.Version
-sun.net.ConnectionResetException
-sun.net.NetHooks
-sun.net.NetProperties
-sun.net.NetProperties$1
-sun.net.ResourceManager
-sun.net.spi.DefaultProxySelector
-sun.net.spi.DefaultProxySelector$1
-sun.net.spi.DefaultProxySelector$NonProxyInfo
-sun.net.spi.nameservice.NameService
-sun.net.util.IPAddressUtil
-sun.net.www.ParseUtil
-sun.net.www.protocol.file.Handler
-sun.net.www.protocol.jar.Handler
-sun.nio.ch.AbstractPollArrayWrapper
-sun.nio.ch.AbstractPollSelectorImpl
-sun.nio.ch.AllocatedNativeObject
-sun.nio.ch.ChannelInputStream
-sun.nio.ch.DatagramChannelImpl
-sun.nio.ch.DatagramDispatcher
-sun.nio.ch.DefaultSelectorProvider
-sun.nio.ch.DirectBuffer
-sun.nio.ch.FileChannelImpl
-sun.nio.ch.FileChannelImpl$Unmapper
-sun.nio.ch.FileDescriptorHolderSocketImpl
-sun.nio.ch.FileDispatcher
-sun.nio.ch.FileDispatcherImpl
-sun.nio.ch.FileKey
-sun.nio.ch.FileLockImpl
-sun.nio.ch.FileLockTable
-sun.nio.ch.IOStatus
-sun.nio.ch.IOUtil
-sun.nio.ch.Interruptible
-sun.nio.ch.NativeDispatcher
-sun.nio.ch.NativeObject
-sun.nio.ch.NativeThread
-sun.nio.ch.NativeThreadSet
-sun.nio.ch.Net
-sun.nio.ch.Net$1
-sun.nio.ch.Net$4
-sun.nio.ch.PollArrayWrapper
-sun.nio.ch.PollSelectorImpl
-sun.nio.ch.PollSelectorProvider
-sun.nio.ch.SelChImpl
-sun.nio.ch.SelectionKeyImpl
-sun.nio.ch.SelectorImpl
-sun.nio.ch.SelectorProviderImpl
-sun.nio.ch.ServerSocketChannelImpl
-sun.nio.ch.SharedFileLockTable
-sun.nio.ch.SharedFileLockTable$FileLockReference
-sun.nio.ch.SocketAdaptor
-sun.nio.ch.SocketAdaptor$1
-sun.nio.ch.SocketAdaptor$2
-sun.nio.ch.SocketAdaptor$SocketInputStream
-sun.nio.ch.SocketChannelImpl
-sun.nio.ch.SocketDispatcher
-sun.nio.ch.Util
-sun.nio.ch.Util$1
-sun.nio.ch.Util$2
-sun.nio.ch.Util$BufferCache
-sun.nio.cs.ArrayDecoder
-sun.nio.cs.ArrayEncoder
-sun.nio.cs.StreamDecoder
-sun.nio.cs.StreamEncoder
-sun.nio.cs.ThreadLocalCoders
-sun.nio.cs.ThreadLocalCoders$1
-sun.nio.cs.ThreadLocalCoders$2
-sun.nio.cs.ThreadLocalCoders$Cache
-sun.nio.fs.AbstractBasicFileAttributeView
-sun.nio.fs.AbstractFileSystemProvider
-sun.nio.fs.AbstractPath
-sun.nio.fs.DefaultFileSystemProvider
-sun.nio.fs.DynamicFileAttributeView
-sun.nio.fs.LinuxFileSystem
-sun.nio.fs.LinuxFileSystemProvider
-sun.nio.fs.NativeBuffer
-sun.nio.fs.NativeBuffer$Deallocator
-sun.nio.fs.NativeBuffers
-sun.nio.fs.UnixChannelFactory
-sun.nio.fs.UnixChannelFactory$Flags
-sun.nio.fs.UnixConstants
-sun.nio.fs.UnixException
-sun.nio.fs.UnixFileAttributeViews
-sun.nio.fs.UnixFileAttributeViews$Basic
-sun.nio.fs.UnixFileAttributes
-sun.nio.fs.UnixFileAttributes$UnixAsBasicFileAttributes
-sun.nio.fs.UnixFileModeAttribute
-sun.nio.fs.UnixFileStoreAttributes
-sun.nio.fs.UnixFileSystem
-sun.nio.fs.UnixFileSystemProvider
-sun.nio.fs.UnixMountEntry
-sun.nio.fs.UnixNativeDispatcher
-sun.nio.fs.UnixPath
-sun.nio.fs.Util
-sun.reflect.misc.ReflectUtil
-sun.security.action.GetBooleanAction
-sun.security.action.GetIntegerAction
-sun.security.action.GetPropertyAction
-sun.security.jca.GetInstance
-sun.security.jca.GetInstance$Instance
-sun.security.jca.JCAUtil
-sun.security.jca.ProviderConfig
-sun.security.jca.ProviderConfig$2
-sun.security.jca.ProviderList
-sun.security.jca.ProviderList$1
-sun.security.jca.ProviderList$2
-sun.security.jca.ProviderList$3
-sun.security.jca.ProviderList$ServiceList
-sun.security.jca.ProviderList$ServiceList$1
-sun.security.jca.Providers
-sun.security.jca.ServiceId
-sun.security.pkcs.ContentInfo
-sun.security.pkcs.PKCS7
-sun.security.pkcs.PKCS7$VerbatimX509Certificate
-sun.security.pkcs.PKCS7$WrappedX509Certificate
-sun.security.pkcs.PKCS9Attribute
-sun.security.pkcs.SignerInfo
-sun.security.provider.CertPathProvider
-sun.security.provider.X509Factory
-sun.security.provider.certpath.AdaptableX509CertSelector
-sun.security.provider.certpath.AlgorithmChecker
-sun.security.provider.certpath.BasicChecker
-sun.security.provider.certpath.CertId
-sun.security.provider.certpath.CertPathHelper
-sun.security.provider.certpath.ConstraintsChecker
-sun.security.provider.certpath.KeyChecker
-sun.security.provider.certpath.OCSP$RevocationStatus
-sun.security.provider.certpath.OCSP$RevocationStatus$CertStatus
-sun.security.provider.certpath.OCSPResponse
-sun.security.provider.certpath.OCSPResponse$ResponseStatus
-sun.security.provider.certpath.OCSPResponse$SingleResponse
-sun.security.provider.certpath.PKIX
-sun.security.provider.certpath.PKIX$ValidatorParams
-sun.security.provider.certpath.PKIXCertPathValidator
-sun.security.provider.certpath.PKIXMasterCertPathValidator
-sun.security.provider.certpath.PolicyChecker
-sun.security.provider.certpath.PolicyNodeImpl
-sun.security.provider.certpath.RevocationChecker
-sun.security.provider.certpath.RevocationChecker$1
-sun.security.provider.certpath.RevocationChecker$Mode
-sun.security.provider.certpath.RevocationChecker$RevocationProperties
-sun.security.util.AbstractAlgorithmConstraints
-sun.security.util.AbstractAlgorithmConstraints$1
-sun.security.util.AlgorithmDecomposer
-sun.security.util.BitArray
-sun.security.util.ByteArrayLexOrder
-sun.security.util.ByteArrayTagOrder
-sun.security.util.Cache
-sun.security.util.Cache$EqualByteArray
-sun.security.util.CertConstraintParameters
-sun.security.util.Debug
-sun.security.util.DerEncoder
-sun.security.util.DerIndefLenConverter
-sun.security.util.DerInputBuffer
-sun.security.util.DerInputStream
-sun.security.util.DerOutputStream
-sun.security.util.DerValue
-sun.security.util.DisabledAlgorithmConstraints
-sun.security.util.DisabledAlgorithmConstraints$Constraint
-sun.security.util.DisabledAlgorithmConstraints$Constraint$Operator
-sun.security.util.DisabledAlgorithmConstraints$Constraints
-sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraint
-sun.security.util.KeyUtil
-sun.security.util.Length
-sun.security.util.ManifestDigester
-sun.security.util.ManifestDigester$Entry
-sun.security.util.ManifestDigester$Position
-sun.security.util.ManifestEntryVerifier
-sun.security.util.ManifestEntryVerifier$SunProviderHolder
-sun.security.util.MemoryCache
-sun.security.util.MemoryCache$CacheEntry
-sun.security.util.MemoryCache$SoftCacheEntry
-sun.security.util.ObjectIdentifier
-sun.security.util.SignatureFileVerifier
-sun.security.x509.AVA
-sun.security.x509.AVAKeyword
-sun.security.x509.AccessDescription
-sun.security.x509.AlgorithmId
-sun.security.x509.AuthorityInfoAccessExtension
-sun.security.x509.AuthorityKeyIdentifierExtension
-sun.security.x509.BasicConstraintsExtension
-sun.security.x509.CRLDistributionPointsExtension
-sun.security.x509.CRLNumberExtension
-sun.security.x509.CRLReasonCodeExtension
-sun.security.x509.CertAttrSet
-sun.security.x509.CertificateAlgorithmId
-sun.security.x509.CertificateExtensions
-sun.security.x509.CertificateIssuerExtension
-sun.security.x509.CertificatePoliciesExtension
-sun.security.x509.CertificatePolicyId
-sun.security.x509.CertificateSerialNumber
-sun.security.x509.CertificateValidity
-sun.security.x509.CertificateVersion
-sun.security.x509.CertificateX509Key
-sun.security.x509.DNSName
-sun.security.x509.DeltaCRLIndicatorExtension
-sun.security.x509.DistributionPoint
-sun.security.x509.ExtendedKeyUsageExtension
-sun.security.x509.Extension
-sun.security.x509.FreshestCRLExtension
-sun.security.x509.GeneralName
-sun.security.x509.GeneralNameInterface
-sun.security.x509.GeneralNames
-sun.security.x509.InhibitAnyPolicyExtension
-sun.security.x509.IssuerAlternativeNameExtension
-sun.security.x509.IssuingDistributionPointExtension
-sun.security.x509.KeyIdentifier
-sun.security.x509.KeyUsageExtension
-sun.security.x509.NameConstraintsExtension
-sun.security.x509.NetscapeCertTypeExtension
-sun.security.x509.OCSPNoCheckExtension
-sun.security.x509.OIDMap
-sun.security.x509.OIDMap$OIDInfo
-sun.security.x509.PKIXExtensions
-sun.security.x509.PolicyConstraintsExtension
-sun.security.x509.PolicyInformation
-sun.security.x509.PolicyMappingsExtension
-sun.security.x509.PrivateKeyUsageExtension
-sun.security.x509.RDN
-sun.security.x509.SerialNumber
-sun.security.x509.SubjectAlternativeNameExtension
-sun.security.x509.SubjectInfoAccessExtension
-sun.security.x509.SubjectKeyIdentifierExtension
-sun.security.x509.URIName
-sun.security.x509.X500Name
-sun.security.x509.X500Name$1
-sun.security.x509.X509AttributeName
-sun.security.x509.X509CertImpl
-sun.security.x509.X509CertInfo
-sun.security.x509.X509Key
-sun.util.calendar.AbstractCalendar
-sun.util.calendar.BaseCalendar
-sun.util.calendar.BaseCalendar$Date
-sun.util.calendar.CalendarDate
-sun.util.calendar.CalendarSystem
-sun.util.calendar.CalendarUtils
-sun.util.calendar.Gregorian
-sun.util.calendar.Gregorian$Date
-sun.util.calendar.JulianCalendar
-sun.util.calendar.LocalGregorianCalendar
-sun.util.locale.BaseLocale
-sun.util.locale.BaseLocale$Cache
-sun.util.locale.BaseLocale$Key
-sun.util.locale.Extension
-sun.util.locale.InternalLocaleBuilder
-sun.util.locale.InternalLocaleBuilder$CaseInsensitiveChar
-sun.util.locale.LanguageTag
-sun.util.locale.LocaleExtensions
-sun.util.locale.LocaleObjectCache
-sun.util.locale.LocaleObjectCache$CacheEntry
-sun.util.locale.LocaleSyntaxException
-sun.util.locale.LocaleUtils
-sun.util.locale.ParseStatus
-sun.util.locale.StringTokenIterator
-sun.util.locale.UnicodeLocaleExtension
-sun.util.logging.LoggingProxy
-sun.util.logging.LoggingSupport
-sun.util.logging.LoggingSupport$1
-sun.util.logging.LoggingSupport$2
-sun.util.logging.PlatformLogger
-sun.util.logging.PlatformLogger$1
-sun.util.logging.PlatformLogger$JavaLoggerProxy
-sun.util.logging.PlatformLogger$Level
-sun.util.logging.PlatformLogger$LoggerProxy
diff --git a/config/compiled-classes-phone b/config/compiled-classes-phone
new file mode 100644
index 0000000..384540a
--- /dev/null
+++ b/config/compiled-classes-phone
@@ -0,0 +1,8520 @@
+#
+# 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.
+#
+#
+#
+# Compiled-classes filter file for phones.
+#
+# Using a compiled-classes file filters non-mentioned classes from being compiled into
+# the boot.oat file(s), reducing the size of the boot image. This is a tradeoff, as classes
+# that have not been compiled must be run with the interpreter or through JIT.
+#
+# This file has been derived for mainline phone (and tablet) usage in concern with the
+# preloaded-classes file, but is not used by default. To use this file, add a copy statement
+# to your device.mk, e.g.,
+#
+#   PRODUCT_COPY_FILES += \
+#     frameworks/base/config/compiled-classes-phone:system/etc/compiled-classes
+#
+android.R$styleable
+android.accessibilityservice.AccessibilityServiceInfo
+android.accessibilityservice.AccessibilityServiceInfo$1
+android.accessibilityservice.IAccessibilityServiceClient
+android.accessibilityservice.IAccessibilityServiceConnection
+android.accessibilityservice.IAccessibilityServiceConnection$Stub
+android.accounts.AbstractAccountAuthenticator
+android.accounts.AbstractAccountAuthenticator$Transport
+android.accounts.Account
+android.accounts.Account$1
+android.accounts.AccountAndUser
+android.accounts.AccountAuthenticatorResponse
+android.accounts.AccountAuthenticatorResponse$1
+android.accounts.AccountManager
+android.accounts.AccountManager$1
+android.accounts.AccountManager$11
+android.accounts.AccountManager$19
+android.accounts.AccountManager$3
+android.accounts.AccountManager$4
+android.accounts.AccountManager$AmsTask
+android.accounts.AccountManager$AmsTask$1
+android.accounts.AccountManager$AmsTask$Response
+android.accounts.AccountManager$BaseFutureTask
+android.accounts.AccountManager$BaseFutureTask$1
+android.accounts.AccountManager$BaseFutureTask$Response
+android.accounts.AccountManager$Future2Task
+android.accounts.AccountManager$Future2Task$1
+android.accounts.AccountManagerCallback
+android.accounts.AccountManagerFuture
+android.accounts.AccountManagerInternal
+android.accounts.AccountManagerInternal$OnAppPermissionChangeListener
+android.accounts.AccountsException
+android.accounts.AuthenticatorDescription
+android.accounts.AuthenticatorDescription$1
+android.accounts.AuthenticatorException
+android.accounts.IAccountAuthenticator
+android.accounts.IAccountAuthenticator$Stub
+android.accounts.IAccountAuthenticator$Stub$Proxy
+android.accounts.IAccountAuthenticatorResponse
+android.accounts.IAccountAuthenticatorResponse$Stub
+android.accounts.IAccountAuthenticatorResponse$Stub$Proxy
+android.accounts.IAccountManager
+android.accounts.IAccountManager$Stub
+android.accounts.IAccountManager$Stub$Proxy
+android.accounts.IAccountManagerResponse
+android.accounts.IAccountManagerResponse$Stub
+android.accounts.IAccountManagerResponse$Stub$Proxy
+android.accounts.OnAccountsUpdateListener
+android.accounts.OperationCanceledException
+android.animation.AnimationHandler
+android.animation.AnimationHandler$1
+android.animation.AnimationHandler$AnimationFrameCallback
+android.animation.AnimationHandler$AnimationFrameCallbackProvider
+android.animation.AnimationHandler$MyFrameCallbackProvider
+android.animation.Animator
+android.animation.Animator$AnimatorConstantState
+android.animation.Animator$AnimatorListener
+android.animation.Animator$AnimatorPauseListener
+android.animation.AnimatorInflater
+android.animation.AnimatorInflater$PathDataEvaluator
+android.animation.AnimatorListenerAdapter
+android.animation.AnimatorSet
+android.animation.AnimatorSet$1
+android.animation.AnimatorSet$2
+android.animation.AnimatorSet$3
+android.animation.AnimatorSet$AnimationEvent
+android.animation.AnimatorSet$Builder
+android.animation.AnimatorSet$Node
+android.animation.AnimatorSet$SeekState
+android.animation.ArgbEvaluator
+android.animation.FloatArrayEvaluator
+android.animation.FloatEvaluator
+android.animation.FloatKeyframeSet
+android.animation.IntEvaluator
+android.animation.IntKeyframeSet
+android.animation.Keyframe
+android.animation.Keyframe$FloatKeyframe
+android.animation.Keyframe$IntKeyframe
+android.animation.Keyframe$ObjectKeyframe
+android.animation.KeyframeSet
+android.animation.Keyframes
+android.animation.Keyframes$FloatKeyframes
+android.animation.Keyframes$IntKeyframes
+android.animation.LayoutTransition
+android.animation.LayoutTransition$1
+android.animation.LayoutTransition$2
+android.animation.LayoutTransition$3
+android.animation.LayoutTransition$4
+android.animation.LayoutTransition$5
+android.animation.LayoutTransition$CleanupCallback
+android.animation.LayoutTransition$TransitionListener
+android.animation.ObjectAnimator
+android.animation.PathKeyframes
+android.animation.PathKeyframes$1
+android.animation.PathKeyframes$2
+android.animation.PathKeyframes$FloatKeyframesBase
+android.animation.PathKeyframes$IntKeyframesBase
+android.animation.PathKeyframes$SimpleKeyframes
+android.animation.PropertyValuesHolder
+android.animation.PropertyValuesHolder$1
+android.animation.PropertyValuesHolder$FloatPropertyValuesHolder
+android.animation.PropertyValuesHolder$IntPropertyValuesHolder
+android.animation.PropertyValuesHolder$PropertyValues
+android.animation.PropertyValuesHolder$PropertyValues$DataSource
+android.animation.RectEvaluator
+android.animation.RevealAnimator
+android.animation.StateListAnimator
+android.animation.StateListAnimator$1
+android.animation.StateListAnimator$StateListAnimatorConstantState
+android.animation.StateListAnimator$Tuple
+android.animation.TimeAnimator
+android.animation.TimeAnimator$TimeListener
+android.animation.TimeInterpolator
+android.animation.TypeEvaluator
+android.animation.ValueAnimator
+android.animation.ValueAnimator$AnimatorUpdateListener
+android.app.-$Lambda$9I5WEMsoBc7l4QrNqZ4wx59yuHU
+android.app.-$Lambda$9I5WEMsoBc7l4QrNqZ4wx59yuHU$1
+android.app.-$Lambda$CsyQO--8YdRe5wlajUCi-L98enA$1
+android.app.-$Lambda$CsyQO--8YdRe5wlajUCi-L98enA$2
+android.app.-$Lambda$CsyQO--8YdRe5wlajUCi-L98enA$3
+android.app.-$Lambda$FilBqgnXJrN9Mgyks1XHeAxzSTk
+android.app.-$Lambda$c44uHH2WE4sJvw5tZZB6gRzEaHI
+android.app.-$Lambda$c44uHH2WE4sJvw5tZZB6gRzEaHI$1
+android.app.-$Lambda$vZ1qb742P9hE4drBY-TrOZB_qKo
+android.app.-$Lambda$w9bG0NLfK6B6UpQKzQS6S1ayAh0
+android.app.-$Lambda$w9bG0NLfK6B6UpQKzQS6S1ayAh0$1
+android.app.ActionBar
+android.app.ActionBar$LayoutParams
+android.app.Activity
+android.app.Activity$HostCallbacks
+android.app.ActivityManager
+android.app.ActivityManager$1
+android.app.ActivityManager$AppTask
+android.app.ActivityManager$MemoryInfo
+android.app.ActivityManager$MemoryInfo$1
+android.app.ActivityManager$OnUidImportanceListener
+android.app.ActivityManager$ProcessErrorStateInfo
+android.app.ActivityManager$RecentTaskInfo
+android.app.ActivityManager$RecentTaskInfo$1
+android.app.ActivityManager$RunningAppProcessInfo
+android.app.ActivityManager$RunningAppProcessInfo$1
+android.app.ActivityManager$RunningServiceInfo
+android.app.ActivityManager$RunningServiceInfo$1
+android.app.ActivityManager$RunningTaskInfo
+android.app.ActivityManager$RunningTaskInfo$1
+android.app.ActivityManager$StackId
+android.app.ActivityManager$StackInfo
+android.app.ActivityManager$StackInfo$1
+android.app.ActivityManager$TaskDescription
+android.app.ActivityManager$TaskDescription$1
+android.app.ActivityManager$TaskSnapshot
+android.app.ActivityManager$TaskSnapshot$1
+android.app.ActivityManager$TaskThumbnail
+android.app.ActivityManager$TaskThumbnailInfo
+android.app.ActivityManager$TaskThumbnailInfo$1
+android.app.ActivityManager$UidObserver
+android.app.ActivityManagerInternal
+android.app.ActivityManagerInternal$SleepToken
+android.app.ActivityOptions
+android.app.ActivityOptions$1
+android.app.ActivityOptions$1$1
+android.app.ActivityOptions$OnAnimationFinishedListener
+android.app.ActivityOptions$OnAnimationStartedListener
+android.app.ActivityThread
+android.app.ActivityThread$1
+android.app.ActivityThread$2
+android.app.ActivityThread$ActivityClientRecord
+android.app.ActivityThread$ActivityConfigChangeData
+android.app.ActivityThread$AppBindData
+android.app.ActivityThread$ApplicationThread
+android.app.ActivityThread$BindServiceData
+android.app.ActivityThread$ContextCleanupInfo
+android.app.ActivityThread$CreateServiceData
+android.app.ActivityThread$DropBoxReporter
+android.app.ActivityThread$EventLoggingReporter
+android.app.ActivityThread$GcIdler
+android.app.ActivityThread$H
+android.app.ActivityThread$Idler
+android.app.ActivityThread$NewIntentData
+android.app.ActivityThread$Profiler
+android.app.ActivityThread$ProviderClientRecord
+android.app.ActivityThread$ProviderKey
+android.app.ActivityThread$ProviderRefCount
+android.app.ActivityThread$ReceiverData
+android.app.ActivityThread$RequestAssistContextExtras
+android.app.ActivityThread$ResultData
+android.app.ActivityThread$ServiceArgsData
+android.app.ActivityThread$StopInfo
+android.app.ActivityTransitionCoordinator
+android.app.ActivityTransitionCoordinator$ContinueTransitionListener
+android.app.ActivityTransitionCoordinator$FixedEpicenterCallback
+android.app.ActivityTransitionCoordinator$GhostViewListeners
+android.app.ActivityTransitionCoordinator$SharedElementOriginalState
+android.app.ActivityTransitionState
+android.app.AlarmManager$AlarmClockInfo
+android.app.AlarmManager$ListenerWrapper
+android.app.AlarmManager$OnAlarmListener
+android.app.AlertDialog
+android.app.AlertDialog$Builder
+android.app.AppGlobals
+android.app.AppOpsManager
+android.app.AppOpsManager$1
+android.app.AppOpsManager$OnOpChangedInternalListener
+android.app.AppOpsManager$OnOpChangedListener
+android.app.AppOpsManager$OpEntry
+android.app.AppOpsManager$OpEntry$1
+android.app.AppOpsManager$PackageOps
+android.app.AppOpsManager$PackageOps$1
+android.app.Application
+android.app.Application$ActivityLifecycleCallbacks
+android.app.ApplicationErrorReport
+android.app.ApplicationErrorReport$AnrInfo
+android.app.ApplicationErrorReport$CrashInfo
+android.app.ApplicationErrorReport$ParcelableCrashInfo
+android.app.ApplicationErrorReport$ParcelableCrashInfo$1
+android.app.ApplicationLoaders
+android.app.ApplicationPackageManager
+android.app.ApplicationPackageManager$MoveCallbackDelegate
+android.app.ApplicationPackageManager$OnPermissionsChangeListenerDelegate
+android.app.ApplicationPackageManager$ResourceName
+android.app.AutomaticZenRule
+android.app.BackStackRecord
+android.app.BackStackRecord$Op
+android.app.BroadcastOptions
+android.app.ContentProviderHolder
+android.app.ContentProviderHolder$1
+android.app.ContextImpl
+android.app.ContextImpl$ApplicationContentResolver
+android.app.DatePickerDialog$OnDateSetListener
+android.app.DexLoadReporter
+android.app.Dialog
+android.app.Dialog$ListenersHandler
+android.app.DialogFragment
+android.app.DownloadManager
+android.app.DownloadManager$CursorTranslator
+android.app.DownloadManager$Query
+android.app.EnterTransitionCoordinator
+android.app.EnterTransitionCoordinator$1
+android.app.EnterTransitionCoordinator$2
+android.app.EnterTransitionCoordinator$3
+android.app.EnterTransitionCoordinator$4
+android.app.EnterTransitionCoordinator$5
+android.app.EnterTransitionCoordinator$6
+android.app.ExitTransitionCoordinator
+android.app.ExitTransitionCoordinator$10
+android.app.ExitTransitionCoordinator$3
+android.app.ExitTransitionCoordinator$9
+android.app.Fragment
+android.app.Fragment$1
+android.app.Fragment$AnimationInfo
+android.app.FragmentContainer
+android.app.FragmentController
+android.app.FragmentHostCallback
+android.app.FragmentManager
+android.app.FragmentManager$BackStackEntry
+android.app.FragmentManager$FragmentLifecycleCallbacks
+android.app.FragmentManager$OnBackStackChangedListener
+android.app.FragmentManagerImpl
+android.app.FragmentManagerImpl$1
+android.app.FragmentManagerImpl$AnimateOnHWLayerIfNeededListener
+android.app.FragmentManagerImpl$OpGenerator
+android.app.FragmentManagerState
+android.app.FragmentManagerState$1
+android.app.FragmentState
+android.app.FragmentState$1
+android.app.FragmentTransaction
+android.app.FragmentTransition
+android.app.FragmentTransition$FragmentContainerTransition
+android.app.IActivityContainer
+android.app.IActivityContainer$Stub
+android.app.IActivityContainerCallback
+android.app.IActivityController
+android.app.IActivityManager
+android.app.IActivityManager$Stub
+android.app.IActivityManager$Stub$Proxy
+android.app.IAlarmCompleteListener
+android.app.IAlarmCompleteListener$Stub
+android.app.IAlarmCompleteListener$Stub$Proxy
+android.app.IAlarmListener
+android.app.IAlarmListener$Stub
+android.app.IAlarmListener$Stub$Proxy
+android.app.IAlarmManager
+android.app.IAlarmManager$Stub
+android.app.IAlarmManager$Stub$Proxy
+android.app.IAppTask
+android.app.IAppTask$Stub
+android.app.IAppTask$Stub$Proxy
+android.app.IApplicationThread
+android.app.IApplicationThread$Stub
+android.app.IApplicationThread$Stub$Proxy
+android.app.IInstantAppResolver
+android.app.IInstantAppResolver$Stub
+android.app.IInstantAppResolver$Stub$Proxy
+android.app.IInstrumentationWatcher
+android.app.IInstrumentationWatcher$Stub
+android.app.INotificationManager
+android.app.INotificationManager$Stub
+android.app.INotificationManager$Stub$Proxy
+android.app.IProcessObserver
+android.app.IProcessObserver$Stub
+android.app.IProcessObserver$Stub$Proxy
+android.app.ISearchManager
+android.app.ISearchManager$Stub
+android.app.ISearchManager$Stub$Proxy
+android.app.IServiceConnection
+android.app.IServiceConnection$Stub
+android.app.IServiceConnection$Stub$Proxy
+android.app.IStopUserCallback
+android.app.ITaskStackListener
+android.app.ITaskStackListener$Stub
+android.app.ITaskStackListener$Stub$Proxy
+android.app.ITransientNotification
+android.app.ITransientNotification$Stub
+android.app.ITransientNotification$Stub$Proxy
+android.app.IUiAutomationConnection
+android.app.IUiAutomationConnection$Stub
+android.app.IUiModeManager
+android.app.IUiModeManager$Stub
+android.app.IUiModeManager$Stub$Proxy
+android.app.IUidObserver
+android.app.IUidObserver$Stub
+android.app.IUidObserver$Stub$Proxy
+android.app.IUserSwitchObserver
+android.app.IUserSwitchObserver$Stub
+android.app.IUserSwitchObserver$Stub$Proxy
+android.app.IWallpaperManager
+android.app.IWallpaperManager$Stub
+android.app.IWallpaperManager$Stub$Proxy
+android.app.IWallpaperManagerCallback
+android.app.IWallpaperManagerCallback$Stub
+android.app.IWallpaperManagerCallback$Stub$Proxy
+android.app.InstantAppResolverService
+android.app.InstantAppResolverService$1
+android.app.InstantAppResolverService$InstantAppResolutionCallback
+android.app.InstantAppResolverService$ServiceHandler
+android.app.Instrumentation
+android.app.IntentReceiverLeaked
+android.app.IntentService
+android.app.IntentService$ServiceHandler
+android.app.JobSchedulerImpl
+android.app.KeyguardManager
+android.app.ListActivity
+android.app.ListFragment
+android.app.ListFragment$1
+android.app.ListFragment$2
+android.app.LoadedApk
+android.app.LoadedApk$ReceiverDispatcher
+android.app.LoadedApk$ReceiverDispatcher$Args
+android.app.LoadedApk$ReceiverDispatcher$InnerReceiver
+android.app.LoadedApk$ServiceDispatcher
+android.app.LoadedApk$ServiceDispatcher$ConnectionInfo
+android.app.LoadedApk$ServiceDispatcher$DeathMonitor
+android.app.LoadedApk$ServiceDispatcher$InnerConnection
+android.app.LoadedApk$ServiceDispatcher$RunConnection
+android.app.LoadedApk$WarningContextClassLoader
+android.app.LoaderManager
+android.app.LoaderManager$LoaderCallbacks
+android.app.LoaderManagerImpl
+android.app.LoaderManagerImpl$LoaderInfo
+android.app.NativeActivity
+android.app.Notification
+android.app.Notification$1
+android.app.Notification$Action
+android.app.Notification$Action$1
+android.app.Notification$Action$Builder
+android.app.Notification$BigPictureStyle
+android.app.Notification$BigTextStyle
+android.app.Notification$Builder
+android.app.Notification$BuilderRemoteViews
+android.app.Notification$DecoratedCustomViewStyle
+android.app.Notification$DecoratedMediaCustomViewStyle
+android.app.Notification$Extender
+android.app.Notification$InboxStyle
+android.app.Notification$MediaStyle
+android.app.Notification$MessagingStyle
+android.app.Notification$StandardTemplateParams
+android.app.Notification$Style
+android.app.Notification$TvExtender
+android.app.Notification$WearableExtender
+android.app.NotificationChannel
+android.app.NotificationChannel$1
+android.app.NotificationChannelGroup
+android.app.NotificationChannelGroup$1
+android.app.NotificationManager
+android.app.NotificationManager$Policy
+android.app.NotificationManager$Policy$1
+android.app.OnActivityPausedListener
+android.app.PackageInstallObserver
+android.app.PackageInstallObserver$1
+android.app.PendingIntent
+android.app.PendingIntent$1
+android.app.PendingIntent$CanceledException
+android.app.PendingIntent$FinishedDispatcher
+android.app.PendingIntent$OnFinished
+android.app.PendingIntent$OnMarshaledListener
+android.app.PictureInPictureParams
+android.app.PictureInPictureParams$1
+android.app.PictureInPictureParams$Builder
+android.app.ProfilerInfo
+android.app.ProgressDialog
+android.app.QueuedWork
+android.app.QueuedWork$QueuedWorkHandler
+android.app.ReceiverRestrictedContext
+android.app.RemoteAction
+android.app.RemoteAction$1
+android.app.RemoteInput
+android.app.RemoteInput$1
+android.app.ResourcesManager
+android.app.ResourcesManager$1
+android.app.ResourcesManager$ActivityResources
+android.app.ResultInfo
+android.app.ResultInfo$1
+android.app.SearchableInfo
+android.app.SearchableInfo$1
+android.app.Service
+android.app.ServiceConnectionLeaked
+android.app.ServiceStartArgs
+android.app.ServiceStartArgs$1
+android.app.SharedElementCallback
+android.app.SharedElementCallback$1
+android.app.SharedElementCallback$OnSharedElementsReadyListener
+android.app.SharedPreferencesImpl
+android.app.SharedPreferencesImpl$1
+android.app.SharedPreferencesImpl$2
+android.app.SharedPreferencesImpl$EditorImpl
+android.app.SharedPreferencesImpl$EditorImpl$1
+android.app.SharedPreferencesImpl$EditorImpl$2
+android.app.SharedPreferencesImpl$EditorImpl$3
+android.app.SharedPreferencesImpl$MemoryCommitResult
+android.app.StatusBarManager
+android.app.SynchronousUserSwitchObserver
+android.app.SystemServiceRegistry
+android.app.SystemServiceRegistry$1
+android.app.SystemServiceRegistry$10
+android.app.SystemServiceRegistry$11
+android.app.SystemServiceRegistry$12
+android.app.SystemServiceRegistry$13
+android.app.SystemServiceRegistry$14
+android.app.SystemServiceRegistry$15
+android.app.SystemServiceRegistry$16
+android.app.SystemServiceRegistry$17
+android.app.SystemServiceRegistry$18
+android.app.SystemServiceRegistry$19
+android.app.SystemServiceRegistry$2
+android.app.SystemServiceRegistry$20
+android.app.SystemServiceRegistry$21
+android.app.SystemServiceRegistry$22
+android.app.SystemServiceRegistry$23
+android.app.SystemServiceRegistry$24
+android.app.SystemServiceRegistry$25
+android.app.SystemServiceRegistry$26
+android.app.SystemServiceRegistry$27
+android.app.SystemServiceRegistry$28
+android.app.SystemServiceRegistry$29
+android.app.SystemServiceRegistry$3
+android.app.SystemServiceRegistry$30
+android.app.SystemServiceRegistry$31
+android.app.SystemServiceRegistry$32
+android.app.SystemServiceRegistry$33
+android.app.SystemServiceRegistry$34
+android.app.SystemServiceRegistry$35
+android.app.SystemServiceRegistry$36
+android.app.SystemServiceRegistry$37
+android.app.SystemServiceRegistry$38
+android.app.SystemServiceRegistry$39
+android.app.SystemServiceRegistry$4
+android.app.SystemServiceRegistry$40
+android.app.SystemServiceRegistry$41
+android.app.SystemServiceRegistry$42
+android.app.SystemServiceRegistry$43
+android.app.SystemServiceRegistry$44
+android.app.SystemServiceRegistry$45
+android.app.SystemServiceRegistry$46
+android.app.SystemServiceRegistry$47
+android.app.SystemServiceRegistry$48
+android.app.SystemServiceRegistry$49
+android.app.SystemServiceRegistry$5
+android.app.SystemServiceRegistry$50
+android.app.SystemServiceRegistry$51
+android.app.SystemServiceRegistry$52
+android.app.SystemServiceRegistry$53
+android.app.SystemServiceRegistry$54
+android.app.SystemServiceRegistry$55
+android.app.SystemServiceRegistry$56
+android.app.SystemServiceRegistry$57
+android.app.SystemServiceRegistry$58
+android.app.SystemServiceRegistry$59
+android.app.SystemServiceRegistry$6
+android.app.SystemServiceRegistry$60
+android.app.SystemServiceRegistry$61
+android.app.SystemServiceRegistry$62
+android.app.SystemServiceRegistry$63
+android.app.SystemServiceRegistry$64
+android.app.SystemServiceRegistry$65
+android.app.SystemServiceRegistry$66
+android.app.SystemServiceRegistry$67
+android.app.SystemServiceRegistry$68
+android.app.SystemServiceRegistry$69
+android.app.SystemServiceRegistry$7
+android.app.SystemServiceRegistry$70
+android.app.SystemServiceRegistry$71
+android.app.SystemServiceRegistry$72
+android.app.SystemServiceRegistry$73
+android.app.SystemServiceRegistry$74
+android.app.SystemServiceRegistry$75
+android.app.SystemServiceRegistry$76
+android.app.SystemServiceRegistry$77
+android.app.SystemServiceRegistry$78
+android.app.SystemServiceRegistry$79
+android.app.SystemServiceRegistry$8
+android.app.SystemServiceRegistry$80
+android.app.SystemServiceRegistry$81
+android.app.SystemServiceRegistry$82
+android.app.SystemServiceRegistry$9
+android.app.SystemServiceRegistry$CachedServiceFetcher
+android.app.SystemServiceRegistry$ServiceFetcher
+android.app.SystemServiceRegistry$StaticApplicationContextServiceFetcher
+android.app.SystemServiceRegistry$StaticServiceFetcher
+android.app.TaskStackListener
+android.app.TimePickerDialog$OnTimeSetListener
+android.app.UiModeManager
+android.app.UserSwitchObserver
+android.app.Vr2dDisplayProperties
+android.app.VrManager
+android.app.WaitResult
+android.app.WallpaperInfo
+android.app.WallpaperManager
+android.app.WallpaperManager$Globals
+android.app.admin.DeviceAdminInfo
+android.app.admin.DeviceAdminInfo$1
+android.app.admin.DeviceAdminInfo$PolicyInfo
+android.app.admin.DevicePolicyManager
+android.app.admin.DevicePolicyManagerInternal
+android.app.admin.DevicePolicyManagerInternal$OnCrossProfileWidgetProvidersChangeListener
+android.app.admin.IDevicePolicyManager
+android.app.admin.IDevicePolicyManager$Stub
+android.app.admin.IDevicePolicyManager$Stub$Proxy
+android.app.admin.PasswordMetrics
+android.app.admin.PasswordMetrics$1
+android.app.admin.SecurityLog
+android.app.admin.SecurityLog$SecurityEvent
+android.app.admin.SecurityLog$SecurityEvent$1
+android.app.admin.SystemUpdateInfo
+android.app.admin.SystemUpdateInfo$1
+android.app.admin.SystemUpdatePolicy
+android.app.admin.SystemUpdatePolicy$1
+android.app.assist.AssistContent
+android.app.assist.AssistStructure
+android.app.assist.AssistStructure$1
+android.app.assist.AssistStructure$AutofillOverlay
+android.app.assist.AssistStructure$ParcelTransferReader
+android.app.assist.AssistStructure$ParcelTransferWriter
+android.app.assist.AssistStructure$SendChannel
+android.app.assist.AssistStructure$ViewNode
+android.app.assist.AssistStructure$ViewNodeBuilder
+android.app.assist.AssistStructure$ViewNodeText
+android.app.assist.AssistStructure$ViewStackEntry
+android.app.assist.AssistStructure$WindowNode
+android.app.backup.BackupAgent
+android.app.backup.BackupAgentHelper
+android.app.backup.BackupDataInput
+android.app.backup.BackupDataInput$EntityHeader
+android.app.backup.BackupDataOutput
+android.app.backup.BackupHelper
+android.app.backup.BackupHelperDispatcher
+android.app.backup.BackupHelperDispatcher$Header
+android.app.backup.BackupManager
+android.app.backup.BackupTransport
+android.app.backup.BackupTransport$TransportImpl
+android.app.backup.FileBackupHelperBase
+android.app.backup.FullBackup
+android.app.backup.FullBackupDataOutput
+android.app.backup.IBackupManager
+android.app.backup.IBackupManager$Stub
+android.app.backup.IBackupManager$Stub$Proxy
+android.app.backup.IBackupManagerMonitor
+android.app.backup.IBackupObserver
+android.app.backup.IFullBackupRestoreObserver
+android.app.backup.IRestoreSession
+android.app.backup.ISelectBackupTransportCallback
+android.app.backup.RestoreDescription
+android.app.backup.RestoreSet
+android.app.job.IJobCallback
+android.app.job.IJobCallback$Stub
+android.app.job.IJobCallback$Stub$Proxy
+android.app.job.IJobScheduler
+android.app.job.IJobScheduler$Stub
+android.app.job.IJobScheduler$Stub$Proxy
+android.app.job.IJobService
+android.app.job.IJobService$Stub
+android.app.job.IJobService$Stub$Proxy
+android.app.job.JobInfo
+android.app.job.JobInfo$1
+android.app.job.JobInfo$Builder
+android.app.job.JobInfo$TriggerContentUri
+android.app.job.JobInfo$TriggerContentUri$1
+android.app.job.JobParameters
+android.app.job.JobParameters$1
+android.app.job.JobScheduler
+android.app.job.JobService
+android.app.job.JobService$1
+android.app.job.JobServiceEngine
+android.app.job.JobServiceEngine$JobHandler
+android.app.job.JobServiceEngine$JobInterface
+android.app.job.JobWorkItem
+android.app.trust.IStrongAuthTracker
+android.app.trust.IStrongAuthTracker$Stub
+android.app.trust.IStrongAuthTracker$Stub$Proxy
+android.app.trust.ITrustListener
+android.app.trust.ITrustListener$Stub
+android.app.trust.ITrustListener$Stub$Proxy
+android.app.trust.ITrustManager
+android.app.trust.ITrustManager$Stub
+android.app.trust.ITrustManager$Stub$Proxy
+android.app.trust.TrustManager
+android.app.trust.TrustManager$1
+android.app.trust.TrustManager$2
+android.app.trust.TrustManager$TrustListener
+android.app.usage.CacheQuotaHint
+android.app.usage.CacheQuotaHint$1
+android.app.usage.CacheQuotaHint$Builder
+android.app.usage.ConfigurationStats
+android.app.usage.ConfigurationStats$1
+android.app.usage.ExternalStorageStats
+android.app.usage.ICacheQuotaService
+android.app.usage.ICacheQuotaService$Stub
+android.app.usage.ICacheQuotaService$Stub$Proxy
+android.app.usage.IStorageStatsManager
+android.app.usage.IStorageStatsManager$Stub
+android.app.usage.IUsageStatsManager
+android.app.usage.IUsageStatsManager$Stub
+android.app.usage.IUsageStatsManager$Stub$Proxy
+android.app.usage.NetworkStatsManager
+android.app.usage.StorageStats
+android.app.usage.StorageStatsManager
+android.app.usage.TimeSparseArray
+android.app.usage.UsageEvents
+android.app.usage.UsageEvents$1
+android.app.usage.UsageEvents$Event
+android.app.usage.UsageStats
+android.app.usage.UsageStats$1
+android.app.usage.UsageStatsManager
+android.app.usage.UsageStatsManagerInternal
+android.app.usage.UsageStatsManagerInternal$AppIdleStateChangeListener
+android.appwidget.AppWidgetHost
+android.appwidget.AppWidgetHost$Callbacks
+android.appwidget.AppWidgetHost$UpdateHandler
+android.appwidget.AppWidgetHostView
+android.appwidget.AppWidgetHostView$1
+android.appwidget.AppWidgetHostView$ParcelableSparseArray
+android.appwidget.AppWidgetHostView$ParcelableSparseArray$1
+android.appwidget.AppWidgetManager
+android.appwidget.AppWidgetProvider
+android.appwidget.AppWidgetProviderInfo
+android.appwidget.AppWidgetProviderInfo$1
+android.appwidget.PendingHostUpdate
+android.appwidget.PendingHostUpdate$1
+android.bluetooth.BluetoothA2dp
+android.bluetooth.BluetoothA2dp$1
+android.bluetooth.BluetoothA2dp$2
+android.bluetooth.BluetoothActivityEnergyInfo
+android.bluetooth.BluetoothAdapter
+android.bluetooth.BluetoothAdapter$1
+android.bluetooth.BluetoothAdapter$BluetoothStateChangeCallback
+android.bluetooth.BluetoothCodecConfig
+android.bluetooth.BluetoothCodecConfig$1
+android.bluetooth.BluetoothCodecStatus
+android.bluetooth.BluetoothDevice
+android.bluetooth.BluetoothDevice$1
+android.bluetooth.BluetoothDevice$2
+android.bluetooth.BluetoothGatt
+android.bluetooth.BluetoothGattCallback
+android.bluetooth.BluetoothGattCharacteristic
+android.bluetooth.BluetoothGattDescriptor
+android.bluetooth.BluetoothGattService
+android.bluetooth.BluetoothHeadset
+android.bluetooth.BluetoothHeadset$1
+android.bluetooth.BluetoothHeadset$2
+android.bluetooth.BluetoothHeadset$3
+android.bluetooth.BluetoothHealthAppConfiguration
+android.bluetooth.BluetoothHidHost
+android.bluetooth.BluetoothHidHost$1
+android.bluetooth.BluetoothHidHost$2
+android.bluetooth.BluetoothInputStream
+android.bluetooth.BluetoothManager
+android.bluetooth.BluetoothMap
+android.bluetooth.BluetoothMap$1
+android.bluetooth.BluetoothMap$2
+android.bluetooth.BluetoothOutputStream
+android.bluetooth.BluetoothPan
+android.bluetooth.BluetoothPan$1
+android.bluetooth.BluetoothPan$2
+android.bluetooth.BluetoothPbap
+android.bluetooth.BluetoothPbap$1
+android.bluetooth.BluetoothPbap$2
+android.bluetooth.BluetoothPbap$ServiceListener
+android.bluetooth.BluetoothProfile
+android.bluetooth.BluetoothProfile$ServiceListener
+android.bluetooth.BluetoothServerSocket
+android.bluetooth.BluetoothSocket
+android.bluetooth.BluetoothSocket$SocketState
+android.bluetooth.BluetoothUuid
+android.bluetooth.IBluetooth
+android.bluetooth.IBluetooth$Stub
+android.bluetooth.IBluetooth$Stub$Proxy
+android.bluetooth.IBluetoothA2dp
+android.bluetooth.IBluetoothA2dp$Stub
+android.bluetooth.IBluetoothA2dp$Stub$Proxy
+android.bluetooth.IBluetoothCallback
+android.bluetooth.IBluetoothCallback$Stub
+android.bluetooth.IBluetoothCallback$Stub$Proxy
+android.bluetooth.IBluetoothGatt
+android.bluetooth.IBluetoothGatt$Stub
+android.bluetooth.IBluetoothGatt$Stub$Proxy
+android.bluetooth.IBluetoothGattCallback
+android.bluetooth.IBluetoothGattServerCallback
+android.bluetooth.IBluetoothHeadset
+android.bluetooth.IBluetoothHeadset$Stub
+android.bluetooth.IBluetoothHeadset$Stub$Proxy
+android.bluetooth.IBluetoothHeadsetPhone
+android.bluetooth.IBluetoothHeadsetPhone$Stub
+android.bluetooth.IBluetoothHeadsetPhone$Stub$Proxy
+android.bluetooth.IBluetoothHealth
+android.bluetooth.IBluetoothHealth$Stub
+android.bluetooth.IBluetoothHealthCallback
+android.bluetooth.IBluetoothHidHost
+android.bluetooth.IBluetoothHidHost$Stub
+android.bluetooth.IBluetoothHidHost$Stub$Proxy
+android.bluetooth.IBluetoothManager
+android.bluetooth.IBluetoothManager$Stub
+android.bluetooth.IBluetoothManager$Stub$Proxy
+android.bluetooth.IBluetoothManagerCallback
+android.bluetooth.IBluetoothManagerCallback$Stub
+android.bluetooth.IBluetoothManagerCallback$Stub$Proxy
+android.bluetooth.IBluetoothMap
+android.bluetooth.IBluetoothMap$Stub
+android.bluetooth.IBluetoothMap$Stub$Proxy
+android.bluetooth.IBluetoothPan
+android.bluetooth.IBluetoothPan$Stub
+android.bluetooth.IBluetoothPan$Stub$Proxy
+android.bluetooth.IBluetoothPbap
+android.bluetooth.IBluetoothPbap$Stub
+android.bluetooth.IBluetoothPbap$Stub$Proxy
+android.bluetooth.IBluetoothProfileServiceConnection
+android.bluetooth.IBluetoothProfileServiceConnection$Stub
+android.bluetooth.IBluetoothProfileServiceConnection$Stub$Proxy
+android.bluetooth.IBluetoothSap
+android.bluetooth.IBluetoothSap$Stub
+android.bluetooth.IBluetoothStateChangeCallback
+android.bluetooth.IBluetoothStateChangeCallback$Stub
+android.bluetooth.IBluetoothStateChangeCallback$Stub$Proxy
+android.bluetooth.OobData
+android.bluetooth.UidTraffic
+android.bluetooth.UidTraffic$1
+android.bluetooth.le.AdvertiseData
+android.bluetooth.le.AdvertisingSetParameters
+android.bluetooth.le.BluetoothLeAdvertiser
+android.bluetooth.le.BluetoothLeScanner
+android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper
+android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1
+android.bluetooth.le.BluetoothLeUtils
+android.bluetooth.le.IAdvertisingSetCallback
+android.bluetooth.le.IPeriodicAdvertisingCallback
+android.bluetooth.le.IScannerCallback
+android.bluetooth.le.IScannerCallback$Stub
+android.bluetooth.le.IScannerCallback$Stub$Proxy
+android.bluetooth.le.PeriodicAdvertisingParameters
+android.bluetooth.le.ScanCallback
+android.bluetooth.le.ScanFilter
+android.bluetooth.le.ScanFilter$1
+android.bluetooth.le.ScanFilter$Builder
+android.bluetooth.le.ScanRecord
+android.bluetooth.le.ScanResult
+android.bluetooth.le.ScanResult$1
+android.bluetooth.le.ScanSettings
+android.bluetooth.le.ScanSettings$1
+android.bluetooth.le.ScanSettings$Builder
+android.companion.AssociationRequest
+android.companion.CompanionDeviceManager
+android.companion.ICompanionDeviceManager
+android.companion.ICompanionDeviceManager$Stub
+android.companion.IFindDeviceCallback
+android.content.AbstractThreadedSyncAdapter
+android.content.AbstractThreadedSyncAdapter$ISyncAdapterImpl
+android.content.AbstractThreadedSyncAdapter$SyncThread
+android.content.ActivityNotFoundException
+android.content.AsyncQueryHandler
+android.content.AsyncQueryHandler$WorkerArgs
+android.content.AsyncQueryHandler$WorkerHandler
+android.content.AsyncTaskLoader
+android.content.AsyncTaskLoader$LoadTask
+android.content.BroadcastReceiver
+android.content.BroadcastReceiver$PendingResult
+android.content.BroadcastReceiver$PendingResult$1
+android.content.ClipData
+android.content.ClipData$1
+android.content.ClipData$Item
+android.content.ClipDescription
+android.content.ClipDescription$1
+android.content.ClipboardManager
+android.content.ClipboardManager$1
+android.content.ClipboardManager$2
+android.content.ClipboardManager$OnPrimaryClipChangedListener
+android.content.ComponentCallbacks
+android.content.ComponentCallbacks2
+android.content.ComponentName
+android.content.ComponentName$1
+android.content.ContentProvider
+android.content.ContentProvider$PipeDataWriter
+android.content.ContentProvider$Transport
+android.content.ContentProviderClient
+android.content.ContentProviderClient$CursorWrapperInner
+android.content.ContentProviderNative
+android.content.ContentProviderOperation
+android.content.ContentProviderOperation$1
+android.content.ContentProviderOperation$Builder
+android.content.ContentProviderProxy
+android.content.ContentProviderResult
+android.content.ContentProviderResult$1
+android.content.ContentQueryMap
+android.content.ContentResolver
+android.content.ContentResolver$1
+android.content.ContentResolver$CursorWrapperInner
+android.content.ContentResolver$ParcelFileDescriptorInner
+android.content.ContentUris
+android.content.ContentValues
+android.content.ContentValues$1
+android.content.Context
+android.content.ContextWrapper
+android.content.CursorLoader
+android.content.DialogInterface
+android.content.DialogInterface$OnCancelListener
+android.content.DialogInterface$OnClickListener
+android.content.DialogInterface$OnDismissListener
+android.content.DialogInterface$OnKeyListener
+android.content.DialogInterface$OnMultiChoiceClickListener
+android.content.DialogInterface$OnShowListener
+android.content.IClipboard
+android.content.IClipboard$Stub
+android.content.IClipboard$Stub$Proxy
+android.content.IContentProvider
+android.content.IContentService
+android.content.IContentService$Stub
+android.content.IContentService$Stub$Proxy
+android.content.IIntentReceiver
+android.content.IIntentReceiver$Stub
+android.content.IIntentReceiver$Stub$Proxy
+android.content.IIntentSender
+android.content.IIntentSender$Stub
+android.content.IIntentSender$Stub$Proxy
+android.content.IOnPrimaryClipChangedListener
+android.content.IOnPrimaryClipChangedListener$Stub
+android.content.IRestrictionsManager
+android.content.IRestrictionsManager$Stub
+android.content.IRestrictionsManager$Stub$Proxy
+android.content.ISyncAdapter
+android.content.ISyncAdapter$Stub
+android.content.ISyncAdapter$Stub$Proxy
+android.content.ISyncContext
+android.content.ISyncContext$Stub
+android.content.ISyncContext$Stub$Proxy
+android.content.ISyncStatusObserver
+android.content.ISyncStatusObserver$Stub
+android.content.ISyncStatusObserver$Stub$Proxy
+android.content.Intent
+android.content.Intent$1
+android.content.Intent$FilterComparison
+android.content.Intent$ShortcutIconResource
+android.content.Intent$ShortcutIconResource$1
+android.content.IntentFilter
+android.content.IntentFilter$1
+android.content.IntentFilter$AuthorityEntry
+android.content.IntentFilter$MalformedMimeTypeException
+android.content.IntentSender
+android.content.IntentSender$1
+android.content.IntentSender$SendIntentException
+android.content.Loader
+android.content.Loader$ForceLoadContentObserver
+android.content.Loader$OnLoadCanceledListener
+android.content.Loader$OnLoadCompleteListener
+android.content.OperationApplicationException
+android.content.PeriodicSync
+android.content.PeriodicSync$1
+android.content.ReceiverCallNotAllowedException
+android.content.RestrictionEntry
+android.content.RestrictionEntry$1
+android.content.RestrictionsManager
+android.content.SearchRecentSuggestionsProvider
+android.content.SearchRecentSuggestionsProvider$DatabaseHelper
+android.content.ServiceConnection
+android.content.SharedPreferences
+android.content.SharedPreferences$Editor
+android.content.SharedPreferences$OnSharedPreferenceChangeListener
+android.content.SyncAdapterType
+android.content.SyncAdapterType$1
+android.content.SyncAdaptersCache
+android.content.SyncAdaptersCache$MySerializer
+android.content.SyncContext
+android.content.SyncInfo
+android.content.SyncInfo$1
+android.content.SyncRequest
+android.content.SyncRequest$1
+android.content.SyncRequest$Builder
+android.content.SyncResult
+android.content.SyncResult$1
+android.content.SyncStats
+android.content.SyncStats$1
+android.content.SyncStatusInfo
+android.content.SyncStatusInfo$1
+android.content.SyncStatusObserver
+android.content.UndoManager
+android.content.UndoManager$UndoState
+android.content.UndoOperation
+android.content.UndoOwner
+android.content.UriMatcher
+android.content.om.IOverlayManager
+android.content.om.IOverlayManager$Stub
+android.content.om.OverlayInfo
+android.content.pm.ActivityInfo
+android.content.pm.ActivityInfo$1
+android.content.pm.ActivityInfo$WindowLayout
+android.content.pm.ApplicationInfo
+android.content.pm.ApplicationInfo$1
+android.content.pm.AuxiliaryResolveInfo
+android.content.pm.BaseParceledListSlice
+android.content.pm.BaseParceledListSlice$1
+android.content.pm.ChangedPackages
+android.content.pm.ComponentInfo
+android.content.pm.ConfigurationInfo
+android.content.pm.ConfigurationInfo$1
+android.content.pm.FallbackCategoryProvider
+android.content.pm.FeatureGroupInfo
+android.content.pm.FeatureGroupInfo$1
+android.content.pm.FeatureInfo
+android.content.pm.FeatureInfo$1
+android.content.pm.ILauncherApps
+android.content.pm.ILauncherApps$Stub
+android.content.pm.ILauncherApps$Stub$Proxy
+android.content.pm.IOnAppsChangedListener
+android.content.pm.IOnAppsChangedListener$Stub
+android.content.pm.IOnAppsChangedListener$Stub$Proxy
+android.content.pm.IOnPermissionsChangeListener
+android.content.pm.IOnPermissionsChangeListener$Stub
+android.content.pm.IOnPermissionsChangeListener$Stub$Proxy
+android.content.pm.IOtaDexopt
+android.content.pm.IOtaDexopt$Stub
+android.content.pm.IPackageDataObserver
+android.content.pm.IPackageDataObserver$Stub
+android.content.pm.IPackageDataObserver$Stub$Proxy
+android.content.pm.IPackageDeleteObserver
+android.content.pm.IPackageDeleteObserver2
+android.content.pm.IPackageInstallObserver
+android.content.pm.IPackageInstallObserver2
+android.content.pm.IPackageInstallObserver2$Stub
+android.content.pm.IPackageInstaller
+android.content.pm.IPackageInstaller$Stub
+android.content.pm.IPackageInstaller$Stub$Proxy
+android.content.pm.IPackageInstallerCallback
+android.content.pm.IPackageInstallerCallback$Stub
+android.content.pm.IPackageInstallerCallback$Stub$Proxy
+android.content.pm.IPackageInstallerSession
+android.content.pm.IPackageInstallerSession$Stub
+android.content.pm.IPackageInstallerSession$Stub$Proxy
+android.content.pm.IPackageManager
+android.content.pm.IPackageManager$Stub
+android.content.pm.IPackageManager$Stub$Proxy
+android.content.pm.IPackageMoveObserver
+android.content.pm.IPackageMoveObserver$Stub
+android.content.pm.IPackageMoveObserver$Stub$Proxy
+android.content.pm.IPackageStatsObserver
+android.content.pm.IPackageStatsObserver$Stub
+android.content.pm.IShortcutService
+android.content.pm.IShortcutService$Stub
+android.content.pm.IShortcutService$Stub$Proxy
+android.content.pm.InstantAppRequest
+android.content.pm.InstantAppResolveInfo$InstantAppDigest
+android.content.pm.InstantAppResolveInfo$InstantAppDigest$1
+android.content.pm.InstrumentationInfo
+android.content.pm.InstrumentationInfo$1
+android.content.pm.IntentFilterVerificationInfo
+android.content.pm.IntentFilterVerificationInfo$1
+android.content.pm.KeySet
+android.content.pm.LauncherActivityInfo
+android.content.pm.LauncherApps
+android.content.pm.LauncherApps$1
+android.content.pm.LauncherApps$Callback
+android.content.pm.LauncherApps$CallbackMessageHandler
+android.content.pm.LauncherApps$CallbackMessageHandler$CallbackInfo
+android.content.pm.LauncherApps$ShortcutQuery
+android.content.pm.PackageCleanItem
+android.content.pm.PackageInfo
+android.content.pm.PackageInfo$1
+android.content.pm.PackageInfoLite
+android.content.pm.PackageInfoLite$1
+android.content.pm.PackageInstaller
+android.content.pm.PackageInstaller$Session
+android.content.pm.PackageInstaller$SessionCallback
+android.content.pm.PackageInstaller$SessionCallbackDelegate
+android.content.pm.PackageInstaller$SessionInfo
+android.content.pm.PackageInstaller$SessionInfo$1
+android.content.pm.PackageInstaller$SessionParams
+android.content.pm.PackageInstaller$SessionParams$1
+android.content.pm.PackageItemInfo
+android.content.pm.PackageManager
+android.content.pm.PackageManager$MoveCallback
+android.content.pm.PackageManager$NameNotFoundException
+android.content.pm.PackageManager$OnPermissionsChangedListener
+android.content.pm.PackageManagerInternal
+android.content.pm.PackageManagerInternal$ExternalSourcesPolicy
+android.content.pm.PackageManagerInternal$PackagesProvider
+android.content.pm.PackageManagerInternal$SyncAdapterPackagesProvider
+android.content.pm.PackageParser
+android.content.pm.PackageParser$Activity
+android.content.pm.PackageParser$Activity$1
+android.content.pm.PackageParser$ActivityIntentInfo
+android.content.pm.PackageParser$ApkLite
+android.content.pm.PackageParser$Callback
+android.content.pm.PackageParser$CallbackImpl
+android.content.pm.PackageParser$Component
+android.content.pm.PackageParser$IntentInfo
+android.content.pm.PackageParser$NewPermissionInfo
+android.content.pm.PackageParser$Package
+android.content.pm.PackageParser$Package$1
+android.content.pm.PackageParser$PackageLite
+android.content.pm.PackageParser$PackageParserException
+android.content.pm.PackageParser$ParseComponentArgs
+android.content.pm.PackageParser$ParsePackageItemArgs
+android.content.pm.PackageParser$Permission
+android.content.pm.PackageParser$Permission$1
+android.content.pm.PackageParser$PermissionGroup
+android.content.pm.PackageParser$PermissionGroup$1
+android.content.pm.PackageParser$Provider
+android.content.pm.PackageParser$Provider$1
+android.content.pm.PackageParser$ProviderIntentInfo
+android.content.pm.PackageParser$Service
+android.content.pm.PackageParser$Service$1
+android.content.pm.PackageParser$ServiceIntentInfo
+android.content.pm.PackageParser$SplitNameComparator
+android.content.pm.PackageParser$SplitPermissionInfo
+android.content.pm.PackageStats
+android.content.pm.PackageUserState
+android.content.pm.ParceledListSlice
+android.content.pm.ParceledListSlice$1
+android.content.pm.PathPermission
+android.content.pm.PathPermission$1
+android.content.pm.PermissionGroupInfo
+android.content.pm.PermissionGroupInfo$1
+android.content.pm.PermissionInfo
+android.content.pm.PermissionInfo$1
+android.content.pm.ProviderInfo
+android.content.pm.ProviderInfo$1
+android.content.pm.RegisteredServicesCache
+android.content.pm.RegisteredServicesCache$1
+android.content.pm.RegisteredServicesCache$2
+android.content.pm.RegisteredServicesCache$3
+android.content.pm.RegisteredServicesCache$ServiceInfo
+android.content.pm.RegisteredServicesCache$UserServices
+android.content.pm.RegisteredServicesCacheListener
+android.content.pm.ResolveInfo
+android.content.pm.ResolveInfo$1
+android.content.pm.SELinuxUtil
+android.content.pm.ServiceInfo
+android.content.pm.ServiceInfo$1
+android.content.pm.SharedLibraryInfo
+android.content.pm.SharedLibraryInfo$1
+android.content.pm.ShortcutInfo
+android.content.pm.ShortcutInfo$1
+android.content.pm.ShortcutInfo$Builder
+android.content.pm.ShortcutManager
+android.content.pm.ShortcutServiceInternal
+android.content.pm.ShortcutServiceInternal$ShortcutChangeListener
+android.content.pm.Signature
+android.content.pm.Signature$1
+android.content.pm.StringParceledListSlice
+android.content.pm.StringParceledListSlice$1
+android.content.pm.UserInfo
+android.content.pm.UserInfo$1
+android.content.pm.VerifierDeviceIdentity
+android.content.pm.VerifierInfo
+android.content.pm.VersionedPackage
+android.content.pm.VersionedPackage$1
+android.content.pm.XmlSerializerAndParser
+android.content.pm.split.DefaultSplitAssetLoader
+android.content.pm.split.SplitAssetLoader
+android.content.pm.split.SplitDependencyLoader$IllegalDependencyException
+android.content.res.AssetFileDescriptor
+android.content.res.AssetFileDescriptor$1
+android.content.res.AssetFileDescriptor$AutoCloseInputStream
+android.content.res.AssetManager
+android.content.res.AssetManager$AssetInputStream
+android.content.res.ColorStateList
+android.content.res.ColorStateList$1
+android.content.res.ColorStateList$ColorStateListFactory
+android.content.res.CompatResources
+android.content.res.CompatibilityInfo
+android.content.res.CompatibilityInfo$1
+android.content.res.CompatibilityInfo$2
+android.content.res.ComplexColor
+android.content.res.Configuration
+android.content.res.Configuration$1
+android.content.res.ConfigurationBoundResourceCache
+android.content.res.ConstantState
+android.content.res.DrawableCache
+android.content.res.GradientColor
+android.content.res.ObbInfo
+android.content.res.ObbInfo$1
+android.content.res.ObbScanner
+android.content.res.Resources
+android.content.res.Resources$NotFoundException
+android.content.res.Resources$Theme
+android.content.res.Resources$ThemeKey
+android.content.res.ResourcesImpl
+android.content.res.ResourcesImpl$ThemeImpl
+android.content.res.ResourcesKey
+android.content.res.StringBlock
+android.content.res.StringBlock$StyleIDs
+android.content.res.ThemedResourceCache
+android.content.res.TypedArray
+android.content.res.XmlBlock
+android.content.res.XmlBlock$Parser
+android.content.res.XmlResourceParser
+android.database.AbstractCursor
+android.database.AbstractCursor$SelfContentObserver
+android.database.AbstractWindowedCursor
+android.database.BulkCursorDescriptor
+android.database.BulkCursorDescriptor$1
+android.database.BulkCursorNative
+android.database.BulkCursorProxy
+android.database.BulkCursorToCursorAdaptor
+android.database.CharArrayBuffer
+android.database.ContentObservable
+android.database.ContentObserver
+android.database.ContentObserver$NotificationRunnable
+android.database.ContentObserver$Transport
+android.database.CrossProcessCursor
+android.database.CrossProcessCursorWrapper
+android.database.Cursor
+android.database.CursorIndexOutOfBoundsException
+android.database.CursorToBulkCursorAdaptor
+android.database.CursorToBulkCursorAdaptor$ContentObserverProxy
+android.database.CursorWindow
+android.database.CursorWindow$1
+android.database.CursorWrapper
+android.database.DataSetObservable
+android.database.DataSetObserver
+android.database.DatabaseErrorHandler
+android.database.DatabaseUtils
+android.database.DatabaseUtils$InsertHelper
+android.database.DefaultDatabaseErrorHandler
+android.database.IBulkCursor
+android.database.IContentObserver
+android.database.IContentObserver$Stub
+android.database.IContentObserver$Stub$Proxy
+android.database.MatrixCursor
+android.database.MatrixCursor$RowBuilder
+android.database.MergeCursor
+android.database.MergeCursor$1
+android.database.Observable
+android.database.SQLException
+android.database.StaleDataException
+android.database.sqlite.DatabaseObjectNotClosedException
+android.database.sqlite.SQLiteAbortException
+android.database.sqlite.SQLiteCantOpenDatabaseException
+android.database.sqlite.SQLiteClosable
+android.database.sqlite.SQLiteConnection
+android.database.sqlite.SQLiteConnection$Operation
+android.database.sqlite.SQLiteConnection$OperationLog
+android.database.sqlite.SQLiteConnection$PreparedStatement
+android.database.sqlite.SQLiteConnection$PreparedStatementCache
+android.database.sqlite.SQLiteConnectionPool
+android.database.sqlite.SQLiteConnectionPool$AcquiredConnectionStatus
+android.database.sqlite.SQLiteConnectionPool$ConnectionWaiter
+android.database.sqlite.SQLiteConstraintException
+android.database.sqlite.SQLiteCursor
+android.database.sqlite.SQLiteCursorDriver
+android.database.sqlite.SQLiteCustomFunction
+android.database.sqlite.SQLiteDatabase
+android.database.sqlite.SQLiteDatabase$1
+android.database.sqlite.SQLiteDatabase$2
+android.database.sqlite.SQLiteDatabase$CursorFactory
+android.database.sqlite.SQLiteDatabase$CustomFunction
+android.database.sqlite.SQLiteDatabaseConfiguration
+android.database.sqlite.SQLiteDatabaseCorruptException
+android.database.sqlite.SQLiteDatabaseLockedException
+android.database.sqlite.SQLiteDebug
+android.database.sqlite.SQLiteDebug$PagerStats
+android.database.sqlite.SQLiteDirectCursorDriver
+android.database.sqlite.SQLiteDiskIOException
+android.database.sqlite.SQLiteDoneException
+android.database.sqlite.SQLiteException
+android.database.sqlite.SQLiteFullException
+android.database.sqlite.SQLiteGlobal
+android.database.sqlite.SQLiteOpenHelper
+android.database.sqlite.SQLiteProgram
+android.database.sqlite.SQLiteQuery
+android.database.sqlite.SQLiteQueryBuilder
+android.database.sqlite.SQLiteReadOnlyDatabaseException
+android.database.sqlite.SQLiteSession
+android.database.sqlite.SQLiteSession$Transaction
+android.database.sqlite.SQLiteStatement
+android.database.sqlite.SQLiteStatementInfo
+android.database.sqlite.SQLiteTransactionListener
+android.database.sqlite.SqliteWrapper
+android.ddm.DdmHandleAppName
+android.ddm.DdmHandleExit
+android.ddm.DdmHandleHeap
+android.ddm.DdmHandleHello
+android.ddm.DdmHandleNativeHeap
+android.ddm.DdmHandleProfiling
+android.ddm.DdmHandleThread
+android.ddm.DdmHandleViewDebug
+android.ddm.DdmRegister
+android.drm.DrmManagerClient$OnErrorListener
+android.drm.DrmManagerClient$OnEventListener
+android.drm.DrmManagerClient$OnInfoListener
+android.drm.DrmOutputStream
+android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8
+android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$1
+android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$2
+android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$4
+android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$6
+android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$7
+android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$8
+android.graphics.BaseCanvas
+android.graphics.Bitmap
+android.graphics.Bitmap$1
+android.graphics.Bitmap$CompressFormat
+android.graphics.Bitmap$Config
+android.graphics.BitmapFactory
+android.graphics.BitmapFactory$Options
+android.graphics.BitmapRegionDecoder
+android.graphics.BitmapShader
+android.graphics.BlurMaskFilter
+android.graphics.BlurMaskFilter$Blur
+android.graphics.Camera
+android.graphics.Canvas
+android.graphics.Canvas$EdgeType
+android.graphics.Canvas$NoImagePreloadHolder
+android.graphics.CanvasProperty
+android.graphics.Color
+android.graphics.ColorFilter
+android.graphics.ColorMatrix
+android.graphics.ColorMatrixColorFilter
+android.graphics.ColorSpace
+android.graphics.ColorSpace$Adaptation
+android.graphics.ColorSpace$Lab
+android.graphics.ColorSpace$Model
+android.graphics.ColorSpace$Named
+android.graphics.ColorSpace$Rgb
+android.graphics.ColorSpace$Rgb$TransferParameters
+android.graphics.ColorSpace$Xyz
+android.graphics.ComposePathEffect
+android.graphics.ComposeShader
+android.graphics.CornerPathEffect
+android.graphics.DashPathEffect
+android.graphics.DiscretePathEffect
+android.graphics.DrawFilter
+android.graphics.EmbossMaskFilter
+android.graphics.FontFamily
+android.graphics.FontListParser
+android.graphics.GraphicBuffer
+android.graphics.GraphicBuffer$1
+android.graphics.ImageFormat
+android.graphics.Insets
+android.graphics.Interpolator
+android.graphics.Interpolator$Result
+android.graphics.LightingColorFilter
+android.graphics.LinearGradient
+android.graphics.MaskFilter
+android.graphics.Matrix
+android.graphics.Matrix$1
+android.graphics.Matrix$NoImagePreloadHolder
+android.graphics.Matrix$ScaleToFit
+android.graphics.Movie
+android.graphics.NinePatch
+android.graphics.NinePatch$InsetStruct
+android.graphics.Outline
+android.graphics.Paint
+android.graphics.Paint$Align
+android.graphics.Paint$Cap
+android.graphics.Paint$FontMetrics
+android.graphics.Paint$FontMetricsInt
+android.graphics.Paint$Join
+android.graphics.Paint$NoImagePreloadHolder
+android.graphics.Paint$Style
+android.graphics.PaintFlagsDrawFilter
+android.graphics.Path
+android.graphics.Path$Direction
+android.graphics.Path$FillType
+android.graphics.Path$Op
+android.graphics.PathDashPathEffect
+android.graphics.PathEffect
+android.graphics.PathMeasure
+android.graphics.Picture
+android.graphics.Picture$RecordingCanvas
+android.graphics.PixelFormat
+android.graphics.Point
+android.graphics.Point$1
+android.graphics.PointF
+android.graphics.PointF$1
+android.graphics.PorterDuff
+android.graphics.PorterDuff$Mode
+android.graphics.PorterDuffColorFilter
+android.graphics.PorterDuffXfermode
+android.graphics.RadialGradient
+android.graphics.Rect
+android.graphics.Rect$1
+android.graphics.Rect$UnflattenHelper
+android.graphics.RectF
+android.graphics.RectF$1
+android.graphics.Region
+android.graphics.Region$1
+android.graphics.Region$Op
+android.graphics.RegionIterator
+android.graphics.Shader
+android.graphics.Shader$TileMode
+android.graphics.SumPathEffect
+android.graphics.SurfaceTexture
+android.graphics.SurfaceTexture$1
+android.graphics.SurfaceTexture$OnFrameAvailableListener
+android.graphics.SweepGradient
+android.graphics.TableMaskFilter
+android.graphics.TemporaryBuffer
+android.graphics.Typeface
+android.graphics.Typeface$Builder
+android.graphics.Xfermode
+android.graphics.YuvImage
+android.graphics.drawable.AdaptiveIconDrawable
+android.graphics.drawable.AdaptiveIconDrawable$ChildDrawable
+android.graphics.drawable.AdaptiveIconDrawable$LayerState
+android.graphics.drawable.Animatable
+android.graphics.drawable.Animatable2
+android.graphics.drawable.Animatable2$AnimationCallback
+android.graphics.drawable.AnimatedStateListDrawable
+android.graphics.drawable.AnimatedStateListDrawable$AnimatedStateListState
+android.graphics.drawable.AnimatedStateListDrawable$AnimatedVectorDrawableTransition
+android.graphics.drawable.AnimatedStateListDrawable$AnimationDrawableTransition
+android.graphics.drawable.AnimatedStateListDrawable$FrameInterpolator
+android.graphics.drawable.AnimatedStateListDrawable$Transition
+android.graphics.drawable.AnimatedVectorDrawable
+android.graphics.drawable.AnimatedVectorDrawable$1
+android.graphics.drawable.AnimatedVectorDrawable$2
+android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState
+android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator
+android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimator
+android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT
+android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorUI
+android.graphics.drawable.AnimationDrawable
+android.graphics.drawable.AnimationDrawable$AnimationState
+android.graphics.drawable.BitmapDrawable
+android.graphics.drawable.BitmapDrawable$BitmapState
+android.graphics.drawable.ClipDrawable
+android.graphics.drawable.ClipDrawable$ClipState
+android.graphics.drawable.ColorDrawable
+android.graphics.drawable.ColorDrawable$ColorState
+android.graphics.drawable.Drawable
+android.graphics.drawable.Drawable$Callback
+android.graphics.drawable.Drawable$ConstantState
+android.graphics.drawable.DrawableContainer
+android.graphics.drawable.DrawableContainer$1
+android.graphics.drawable.DrawableContainer$BlockInvalidateCallback
+android.graphics.drawable.DrawableContainer$DrawableContainerState
+android.graphics.drawable.DrawableInflater
+android.graphics.drawable.DrawableWrapper
+android.graphics.drawable.DrawableWrapper$DrawableWrapperState
+android.graphics.drawable.GradientDrawable
+android.graphics.drawable.GradientDrawable$GradientState
+android.graphics.drawable.GradientDrawable$Orientation
+android.graphics.drawable.Icon
+android.graphics.drawable.Icon$1
+android.graphics.drawable.InsetDrawable
+android.graphics.drawable.InsetDrawable$InsetState
+android.graphics.drawable.InsetDrawable$InsetValue
+android.graphics.drawable.LayerDrawable
+android.graphics.drawable.LayerDrawable$ChildDrawable
+android.graphics.drawable.LayerDrawable$LayerState
+android.graphics.drawable.NinePatchDrawable
+android.graphics.drawable.NinePatchDrawable$NinePatchState
+android.graphics.drawable.PaintDrawable
+android.graphics.drawable.PictureDrawable
+android.graphics.drawable.RippleBackground
+android.graphics.drawable.RippleBackground$1
+android.graphics.drawable.RippleBackground$BackgroundProperty
+android.graphics.drawable.RippleComponent
+android.graphics.drawable.RippleComponent$RenderNodeAnimatorSet
+android.graphics.drawable.RippleDrawable
+android.graphics.drawable.RippleDrawable$RippleState
+android.graphics.drawable.RippleForeground
+android.graphics.drawable.RippleForeground$1
+android.graphics.drawable.RippleForeground$2
+android.graphics.drawable.RippleForeground$3
+android.graphics.drawable.RippleForeground$4
+android.graphics.drawable.RippleForeground$LogDecelerateInterpolator
+android.graphics.drawable.RotateDrawable
+android.graphics.drawable.RotateDrawable$RotateState
+android.graphics.drawable.ScaleDrawable
+android.graphics.drawable.ScaleDrawable$ScaleState
+android.graphics.drawable.ShapeDrawable
+android.graphics.drawable.ShapeDrawable$ShaderFactory
+android.graphics.drawable.ShapeDrawable$ShapeState
+android.graphics.drawable.StateListDrawable
+android.graphics.drawable.StateListDrawable$StateListState
+android.graphics.drawable.TransitionDrawable
+android.graphics.drawable.TransitionDrawable$TransitionState
+android.graphics.drawable.VectorDrawable
+android.graphics.drawable.VectorDrawable$VClipPath
+android.graphics.drawable.VectorDrawable$VFullPath
+android.graphics.drawable.VectorDrawable$VFullPath$1
+android.graphics.drawable.VectorDrawable$VFullPath$10
+android.graphics.drawable.VectorDrawable$VFullPath$2
+android.graphics.drawable.VectorDrawable$VFullPath$3
+android.graphics.drawable.VectorDrawable$VFullPath$4
+android.graphics.drawable.VectorDrawable$VFullPath$5
+android.graphics.drawable.VectorDrawable$VFullPath$6
+android.graphics.drawable.VectorDrawable$VFullPath$7
+android.graphics.drawable.VectorDrawable$VFullPath$8
+android.graphics.drawable.VectorDrawable$VFullPath$9
+android.graphics.drawable.VectorDrawable$VGroup
+android.graphics.drawable.VectorDrawable$VGroup$1
+android.graphics.drawable.VectorDrawable$VGroup$2
+android.graphics.drawable.VectorDrawable$VGroup$3
+android.graphics.drawable.VectorDrawable$VGroup$4
+android.graphics.drawable.VectorDrawable$VGroup$5
+android.graphics.drawable.VectorDrawable$VGroup$6
+android.graphics.drawable.VectorDrawable$VGroup$7
+android.graphics.drawable.VectorDrawable$VGroup$8
+android.graphics.drawable.VectorDrawable$VGroup$9
+android.graphics.drawable.VectorDrawable$VObject
+android.graphics.drawable.VectorDrawable$VPath
+android.graphics.drawable.VectorDrawable$VPath$1
+android.graphics.drawable.VectorDrawable$VectorDrawableState
+android.graphics.drawable.VectorDrawable$VectorDrawableState$1
+android.graphics.drawable.shapes.OvalShape
+android.graphics.drawable.shapes.RectShape
+android.graphics.drawable.shapes.RoundRectShape
+android.graphics.drawable.shapes.Shape
+android.graphics.fonts.FontVariationAxis
+android.graphics.pdf.PdfDocument
+android.graphics.pdf.PdfEditor
+android.graphics.pdf.PdfRenderer
+android.hardware.Camera
+android.hardware.Camera$CameraInfo
+android.hardware.Camera$ErrorCallback
+android.hardware.Camera$Face
+android.hardware.CameraStatus
+android.hardware.CameraStatus$1
+android.hardware.ConsumerIrManager
+android.hardware.GeomagneticField
+android.hardware.GeomagneticField$LegendreTable
+android.hardware.HardwareBuffer
+android.hardware.HardwareBuffer$1
+android.hardware.ICameraService
+android.hardware.ICameraService$Stub
+android.hardware.ICameraService$Stub$Proxy
+android.hardware.ICameraServiceListener
+android.hardware.ICameraServiceListener$Stub
+android.hardware.ICameraServiceProxy
+android.hardware.ICameraServiceProxy$Stub
+android.hardware.IConsumerIrService
+android.hardware.IConsumerIrService$Stub
+android.hardware.ISerialManager
+android.hardware.ISerialManager$Stub
+android.hardware.Sensor
+android.hardware.SensorAdditionalInfo
+android.hardware.SensorEvent
+android.hardware.SensorEventListener
+android.hardware.SensorManager
+android.hardware.SerialManager
+android.hardware.SerialPort
+android.hardware.SystemSensorManager
+android.hardware.SystemSensorManager$BaseEventQueue
+android.hardware.SystemSensorManager$SensorEventQueue
+android.hardware.SystemSensorManager$TriggerEventQueue
+android.hardware.TriggerEvent
+android.hardware.TriggerEventListener
+android.hardware.camera2.CameraAccessException
+android.hardware.camera2.CameraCaptureSession
+android.hardware.camera2.CameraCaptureSession$CaptureCallback
+android.hardware.camera2.CameraCaptureSession$StateCallback
+android.hardware.camera2.CameraCharacteristics
+android.hardware.camera2.CameraCharacteristics$1
+android.hardware.camera2.CameraCharacteristics$2
+android.hardware.camera2.CameraCharacteristics$3
+android.hardware.camera2.CameraCharacteristics$4
+android.hardware.camera2.CameraCharacteristics$5
+android.hardware.camera2.CameraCharacteristics$Key
+android.hardware.camera2.CameraDevice
+android.hardware.camera2.CameraDevice$StateCallback
+android.hardware.camera2.CameraManager
+android.hardware.camera2.CameraManager$AvailabilityCallback
+android.hardware.camera2.CameraManager$CameraManagerGlobal
+android.hardware.camera2.CameraManager$CameraManagerGlobal$1
+android.hardware.camera2.CameraManager$CameraManagerGlobal$2
+android.hardware.camera2.CameraManager$CameraManagerGlobal$3
+android.hardware.camera2.CameraManager$CameraManagerGlobal$4
+android.hardware.camera2.CameraManager$TorchCallback
+android.hardware.camera2.CameraMetadata
+android.hardware.camera2.CaptureFailure
+android.hardware.camera2.CaptureRequest
+android.hardware.camera2.CaptureRequest$1
+android.hardware.camera2.CaptureRequest$2
+android.hardware.camera2.CaptureRequest$Builder
+android.hardware.camera2.CaptureRequest$Key
+android.hardware.camera2.CaptureResult
+android.hardware.camera2.CaptureResult$1
+android.hardware.camera2.CaptureResult$2
+android.hardware.camera2.CaptureResult$3
+android.hardware.camera2.CaptureResult$Key
+android.hardware.camera2.DngCreator
+android.hardware.camera2.ICameraDeviceCallbacks
+android.hardware.camera2.ICameraDeviceCallbacks$Stub
+android.hardware.camera2.ICameraDeviceUser
+android.hardware.camera2.ICameraDeviceUser$Stub
+android.hardware.camera2.ICameraDeviceUser$Stub$Proxy
+android.hardware.camera2.TotalCaptureResult
+android.hardware.camera2.dispatch.ArgumentReplacingDispatcher
+android.hardware.camera2.dispatch.BroadcastDispatcher
+android.hardware.camera2.dispatch.Dispatchable
+android.hardware.camera2.dispatch.DuckTypingDispatcher
+android.hardware.camera2.dispatch.HandlerDispatcher
+android.hardware.camera2.dispatch.HandlerDispatcher$1
+android.hardware.camera2.dispatch.InvokeDispatcher
+android.hardware.camera2.dispatch.MethodNameInvoker
+android.hardware.camera2.impl.CallbackProxies$DeviceCaptureCallbackProxy
+android.hardware.camera2.impl.CallbackProxies$SessionStateCallbackProxy
+android.hardware.camera2.impl.CameraCaptureSessionCore
+android.hardware.camera2.impl.CameraCaptureSessionImpl
+android.hardware.camera2.impl.CameraCaptureSessionImpl$1
+android.hardware.camera2.impl.CameraCaptureSessionImpl$2
+android.hardware.camera2.impl.CameraCaptureSessionImpl$AbortDrainListener
+android.hardware.camera2.impl.CameraCaptureSessionImpl$IdleDrainListener
+android.hardware.camera2.impl.CameraCaptureSessionImpl$SequenceDrainListener
+android.hardware.camera2.impl.CameraDeviceImpl
+android.hardware.camera2.impl.CameraDeviceImpl$1
+android.hardware.camera2.impl.CameraDeviceImpl$10
+android.hardware.camera2.impl.CameraDeviceImpl$2
+android.hardware.camera2.impl.CameraDeviceImpl$3
+android.hardware.camera2.impl.CameraDeviceImpl$4
+android.hardware.camera2.impl.CameraDeviceImpl$5
+android.hardware.camera2.impl.CameraDeviceImpl$6
+android.hardware.camera2.impl.CameraDeviceImpl$7
+android.hardware.camera2.impl.CameraDeviceImpl$9
+android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks
+android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$2
+android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$3
+android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$4
+android.hardware.camera2.impl.CameraDeviceImpl$CaptureCallback
+android.hardware.camera2.impl.CameraDeviceImpl$CaptureCallbackHolder
+android.hardware.camera2.impl.CameraDeviceImpl$FrameNumberTracker
+android.hardware.camera2.impl.CameraDeviceImpl$RequestLastFrameNumbersHolder
+android.hardware.camera2.impl.CameraDeviceImpl$StateCallbackKK
+android.hardware.camera2.impl.CameraMetadataNative
+android.hardware.camera2.impl.CameraMetadataNative$1
+android.hardware.camera2.impl.CameraMetadataNative$10
+android.hardware.camera2.impl.CameraMetadataNative$11
+android.hardware.camera2.impl.CameraMetadataNative$12
+android.hardware.camera2.impl.CameraMetadataNative$13
+android.hardware.camera2.impl.CameraMetadataNative$14
+android.hardware.camera2.impl.CameraMetadataNative$15
+android.hardware.camera2.impl.CameraMetadataNative$16
+android.hardware.camera2.impl.CameraMetadataNative$17
+android.hardware.camera2.impl.CameraMetadataNative$18
+android.hardware.camera2.impl.CameraMetadataNative$19
+android.hardware.camera2.impl.CameraMetadataNative$2
+android.hardware.camera2.impl.CameraMetadataNative$3
+android.hardware.camera2.impl.CameraMetadataNative$4
+android.hardware.camera2.impl.CameraMetadataNative$5
+android.hardware.camera2.impl.CameraMetadataNative$6
+android.hardware.camera2.impl.CameraMetadataNative$7
+android.hardware.camera2.impl.CameraMetadataNative$8
+android.hardware.camera2.impl.CameraMetadataNative$9
+android.hardware.camera2.impl.CameraMetadataNative$Key
+android.hardware.camera2.impl.CaptureResultExtras
+android.hardware.camera2.impl.CaptureResultExtras$1
+android.hardware.camera2.impl.GetCommand
+android.hardware.camera2.impl.ICameraDeviceUserWrapper
+android.hardware.camera2.impl.SetCommand
+android.hardware.camera2.legacy.LegacyCameraDevice
+android.hardware.camera2.legacy.LegacyExceptionUtils
+android.hardware.camera2.legacy.LegacyExceptionUtils$BufferQueueAbandonedException
+android.hardware.camera2.legacy.PerfMeasurement
+android.hardware.camera2.marshal.MarshalHelpers
+android.hardware.camera2.marshal.MarshalQueryable
+android.hardware.camera2.marshal.MarshalRegistry
+android.hardware.camera2.marshal.MarshalRegistry$MarshalToken
+android.hardware.camera2.marshal.Marshaler
+android.hardware.camera2.marshal.impl.MarshalQueryableArray
+android.hardware.camera2.marshal.impl.MarshalQueryableArray$MarshalerArray
+android.hardware.camera2.marshal.impl.MarshalQueryableBlackLevelPattern
+android.hardware.camera2.marshal.impl.MarshalQueryableBlackLevelPattern$MarshalerBlackLevelPattern
+android.hardware.camera2.marshal.impl.MarshalQueryableBoolean
+android.hardware.camera2.marshal.impl.MarshalQueryableBoolean$MarshalerBoolean
+android.hardware.camera2.marshal.impl.MarshalQueryableColorSpaceTransform
+android.hardware.camera2.marshal.impl.MarshalQueryableColorSpaceTransform$MarshalerColorSpaceTransform
+android.hardware.camera2.marshal.impl.MarshalQueryableEnum
+android.hardware.camera2.marshal.impl.MarshalQueryableHighSpeedVideoConfiguration
+android.hardware.camera2.marshal.impl.MarshalQueryableHighSpeedVideoConfiguration$MarshalerHighSpeedVideoConfiguration
+android.hardware.camera2.marshal.impl.MarshalQueryableMeteringRectangle
+android.hardware.camera2.marshal.impl.MarshalQueryableMeteringRectangle$MarshalerMeteringRectangle
+android.hardware.camera2.marshal.impl.MarshalQueryableNativeByteToInteger
+android.hardware.camera2.marshal.impl.MarshalQueryableNativeByteToInteger$MarshalerNativeByteToInteger
+android.hardware.camera2.marshal.impl.MarshalQueryablePair
+android.hardware.camera2.marshal.impl.MarshalQueryablePair$MarshalerPair
+android.hardware.camera2.marshal.impl.MarshalQueryableParcelable
+android.hardware.camera2.marshal.impl.MarshalQueryablePrimitive
+android.hardware.camera2.marshal.impl.MarshalQueryablePrimitive$MarshalerPrimitive
+android.hardware.camera2.marshal.impl.MarshalQueryableRange
+android.hardware.camera2.marshal.impl.MarshalQueryableRange$MarshalerRange
+android.hardware.camera2.marshal.impl.MarshalQueryableRect
+android.hardware.camera2.marshal.impl.MarshalQueryableRect$MarshalerRect
+android.hardware.camera2.marshal.impl.MarshalQueryableReprocessFormatsMap
+android.hardware.camera2.marshal.impl.MarshalQueryableReprocessFormatsMap$MarshalerReprocessFormatsMap
+android.hardware.camera2.marshal.impl.MarshalQueryableRggbChannelVector
+android.hardware.camera2.marshal.impl.MarshalQueryableRggbChannelVector$MarshalerRggbChannelVector
+android.hardware.camera2.marshal.impl.MarshalQueryableSize
+android.hardware.camera2.marshal.impl.MarshalQueryableSize$MarshalerSize
+android.hardware.camera2.marshal.impl.MarshalQueryableSizeF
+android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfiguration
+android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfiguration$MarshalerStreamConfiguration
+android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfigurationDuration
+android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfigurationDuration$MarshalerStreamConfigurationDuration
+android.hardware.camera2.marshal.impl.MarshalQueryableString
+android.hardware.camera2.params.BlackLevelPattern
+android.hardware.camera2.params.ColorSpaceTransform
+android.hardware.camera2.params.Face
+android.hardware.camera2.params.HighSpeedVideoConfiguration
+android.hardware.camera2.params.InputConfiguration
+android.hardware.camera2.params.LensShadingMap
+android.hardware.camera2.params.MeteringRectangle
+android.hardware.camera2.params.OutputConfiguration
+android.hardware.camera2.params.OutputConfiguration$1
+android.hardware.camera2.params.ReprocessFormatsMap
+android.hardware.camera2.params.RggbChannelVector
+android.hardware.camera2.params.StreamConfiguration
+android.hardware.camera2.params.StreamConfigurationDuration
+android.hardware.camera2.params.StreamConfigurationMap
+android.hardware.camera2.params.TonemapCurve
+android.hardware.camera2.utils.HashCodeHelpers
+android.hardware.camera2.utils.SubmitInfo
+android.hardware.camera2.utils.SubmitInfo$1
+android.hardware.camera2.utils.SurfaceUtils
+android.hardware.camera2.utils.TaskDrainer
+android.hardware.camera2.utils.TaskDrainer$1
+android.hardware.camera2.utils.TaskDrainer$DrainListener
+android.hardware.camera2.utils.TaskSingleDrainer
+android.hardware.camera2.utils.TypeReference
+android.hardware.camera2.utils.TypeReference$SpecializedBaseTypeReference
+android.hardware.camera2.utils.TypeReference$SpecializedTypeReference
+android.hardware.display.DisplayManager
+android.hardware.display.DisplayManager$DisplayListener
+android.hardware.display.DisplayManagerGlobal
+android.hardware.display.DisplayManagerGlobal$DisplayListenerDelegate
+android.hardware.display.DisplayManagerGlobal$DisplayManagerCallback
+android.hardware.display.DisplayManagerInternal
+android.hardware.display.DisplayManagerInternal$DisplayPowerCallbacks
+android.hardware.display.DisplayManagerInternal$DisplayPowerRequest
+android.hardware.display.DisplayManagerInternal$DisplayTransactionListener
+android.hardware.display.DisplayViewport
+android.hardware.display.IDisplayManager
+android.hardware.display.IDisplayManager$Stub
+android.hardware.display.IDisplayManager$Stub$Proxy
+android.hardware.display.IDisplayManagerCallback
+android.hardware.display.IDisplayManagerCallback$Stub
+android.hardware.display.IDisplayManagerCallback$Stub$Proxy
+android.hardware.display.IVirtualDisplayCallback
+android.hardware.display.WifiDisplay
+android.hardware.display.WifiDisplay$1
+android.hardware.display.WifiDisplaySessionInfo
+android.hardware.display.WifiDisplaySessionInfo$1
+android.hardware.display.WifiDisplayStatus
+android.hardware.display.WifiDisplayStatus$1
+android.hardware.fingerprint.Fingerprint
+android.hardware.fingerprint.Fingerprint$1
+android.hardware.fingerprint.FingerprintManager
+android.hardware.fingerprint.FingerprintManager$1
+android.hardware.fingerprint.FingerprintManager$2
+android.hardware.fingerprint.FingerprintManager$AuthenticationCallback
+android.hardware.fingerprint.FingerprintManager$AuthenticationResult
+android.hardware.fingerprint.FingerprintManager$LockoutResetCallback
+android.hardware.fingerprint.FingerprintManager$MyHandler
+android.hardware.fingerprint.IFingerprintClientActiveCallback
+android.hardware.fingerprint.IFingerprintService
+android.hardware.fingerprint.IFingerprintService$Stub
+android.hardware.fingerprint.IFingerprintService$Stub$Proxy
+android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback
+android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback$Stub
+android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback$Stub$Proxy
+android.hardware.fingerprint.IFingerprintServiceReceiver
+android.hardware.fingerprint.IFingerprintServiceReceiver$Stub
+android.hardware.hdmi.HdmiControlManager
+android.hardware.hdmi.HdmiPlaybackClient$DisplayStatusCallback
+android.hardware.input.IInputDevicesChangedListener
+android.hardware.input.IInputDevicesChangedListener$Stub
+android.hardware.input.IInputDevicesChangedListener$Stub$Proxy
+android.hardware.input.IInputManager
+android.hardware.input.IInputManager$Stub
+android.hardware.input.IInputManager$Stub$Proxy
+android.hardware.input.ITabletModeChangedListener
+android.hardware.input.InputDeviceIdentifier
+android.hardware.input.InputDeviceIdentifier$1
+android.hardware.input.InputManager
+android.hardware.input.InputManager$InputDeviceListener
+android.hardware.input.InputManager$InputDeviceListenerDelegate
+android.hardware.input.InputManager$InputDevicesChangedListener
+android.hardware.input.InputManager$OnTabletModeChangedListener
+android.hardware.input.InputManagerInternal
+android.hardware.input.KeyboardLayout
+android.hardware.input.KeyboardLayout$1
+android.hardware.input.TouchCalibration
+android.hardware.input.TouchCalibration$1
+android.hardware.location.ActivityRecognitionHardware
+android.hardware.location.ContextHubInfo
+android.hardware.location.ContextHubInfo$1
+android.hardware.location.ContextHubManager
+android.hardware.location.ContextHubManager$1
+android.hardware.location.ContextHubManager$Callback
+android.hardware.location.ContextHubManager$ICallback
+android.hardware.location.ContextHubMessage
+android.hardware.location.ContextHubMessage$1
+android.hardware.location.GeofenceHardware
+android.hardware.location.GeofenceHardware$GeofenceHardwareMonitorCallbackWrapper
+android.hardware.location.GeofenceHardwareCallback
+android.hardware.location.GeofenceHardwareImpl
+android.hardware.location.GeofenceHardwareImpl$1
+android.hardware.location.GeofenceHardwareImpl$2
+android.hardware.location.GeofenceHardwareImpl$3
+android.hardware.location.GeofenceHardwareImpl$Reaper
+android.hardware.location.GeofenceHardwareMonitorCallback
+android.hardware.location.GeofenceHardwareService
+android.hardware.location.GeofenceHardwareService$1
+android.hardware.location.IActivityRecognitionHardware
+android.hardware.location.IActivityRecognitionHardware$Stub
+android.hardware.location.IActivityRecognitionHardwareClient
+android.hardware.location.IActivityRecognitionHardwareClient$Stub
+android.hardware.location.IActivityRecognitionHardwareClient$Stub$Proxy
+android.hardware.location.IActivityRecognitionHardwareWatcher
+android.hardware.location.IContextHubCallback
+android.hardware.location.IContextHubCallback$Stub
+android.hardware.location.IContextHubCallback$Stub$Proxy
+android.hardware.location.IContextHubService
+android.hardware.location.IContextHubService$Stub
+android.hardware.location.IContextHubService$Stub$Proxy
+android.hardware.location.IFusedLocationHardware
+android.hardware.location.IGeofenceHardware
+android.hardware.location.IGeofenceHardware$Stub
+android.hardware.location.IGeofenceHardware$Stub$Proxy
+android.hardware.location.IGeofenceHardwareMonitorCallback
+android.hardware.location.IGeofenceHardwareMonitorCallback$Stub
+android.hardware.location.IGeofenceHardwareMonitorCallback$Stub$Proxy
+android.hardware.location.MemoryRegion
+android.hardware.location.MemoryRegion$1
+android.hardware.location.NanoApp
+android.hardware.location.NanoAppFilter
+android.hardware.location.NanoAppFilter$1
+android.hardware.location.NanoAppInstanceInfo
+android.hardware.location.NanoAppInstanceInfo$1
+android.hardware.radio.RadioManager
+android.hardware.radio.RadioManager$AmBandConfig
+android.hardware.radio.RadioManager$AmBandConfig$1
+android.hardware.radio.RadioManager$AmBandDescriptor
+android.hardware.radio.RadioManager$AmBandDescriptor$1
+android.hardware.radio.RadioManager$BandConfig
+android.hardware.radio.RadioManager$BandConfig$1
+android.hardware.radio.RadioManager$BandDescriptor
+android.hardware.radio.RadioManager$BandDescriptor$1
+android.hardware.radio.RadioManager$FmBandConfig
+android.hardware.radio.RadioManager$FmBandConfig$1
+android.hardware.radio.RadioManager$FmBandDescriptor
+android.hardware.radio.RadioManager$FmBandDescriptor$1
+android.hardware.radio.RadioManager$ModuleProperties
+android.hardware.radio.RadioManager$ModuleProperties$1
+android.hardware.radio.RadioManager$ProgramInfo
+android.hardware.radio.RadioManager$ProgramInfo$1
+android.hardware.radio.RadioMetadata
+android.hardware.radio.RadioMetadata$1
+android.hardware.radio.RadioModule
+android.hardware.radio.RadioTuner
+android.hardware.radio.V1_0.Call
+android.hardware.radio.V1_0.CardStatus
+android.hardware.radio.V1_0.CdmaSignalStrength
+android.hardware.radio.V1_0.CellIdentity
+android.hardware.radio.V1_0.CellIdentityCdma
+android.hardware.radio.V1_0.CellIdentityGsm
+android.hardware.radio.V1_0.CellIdentityLte
+android.hardware.radio.V1_0.CellIdentityTdscdma
+android.hardware.radio.V1_0.CellIdentityWcdma
+android.hardware.radio.V1_0.CellInfo
+android.hardware.radio.V1_0.CellInfoCdma
+android.hardware.radio.V1_0.CellInfoGsm
+android.hardware.radio.V1_0.CellInfoLte
+android.hardware.radio.V1_0.CellInfoTdscdma
+android.hardware.radio.V1_0.CellInfoType
+android.hardware.radio.V1_0.CellInfoWcdma
+android.hardware.radio.V1_0.DataRegStateResult
+android.hardware.radio.V1_0.EvdoSignalStrength
+android.hardware.radio.V1_0.GsmSignalStrength
+android.hardware.radio.V1_0.HardwareConfig
+android.hardware.radio.V1_0.IRadio
+android.hardware.radio.V1_0.IRadio$Proxy
+android.hardware.radio.V1_0.IRadioIndication
+android.hardware.radio.V1_0.IRadioIndication$Stub
+android.hardware.radio.V1_0.IRadioResponse
+android.hardware.radio.V1_0.IRadioResponse$Stub
+android.hardware.radio.V1_0.LceStatusInfo
+android.hardware.radio.V1_0.LteSignalStrength
+android.hardware.radio.V1_0.RadioCapability
+android.hardware.radio.V1_0.RadioResponseInfo
+android.hardware.radio.V1_0.RegState
+android.hardware.radio.V1_0.SignalStrength
+android.hardware.radio.V1_0.TdScdmaSignalStrength
+android.hardware.radio.V1_0.VoiceRegStateResult
+android.hardware.radio.V1_0.WcdmaSignalStrength
+android.hardware.radio.deprecated.V1_0.IOemHook
+android.hardware.radio.deprecated.V1_0.IOemHook$Proxy
+android.hardware.radio.deprecated.V1_0.IOemHookIndication
+android.hardware.radio.deprecated.V1_0.IOemHookIndication$Stub
+android.hardware.radio.deprecated.V1_0.IOemHookResponse
+android.hardware.radio.deprecated.V1_0.IOemHookResponse$Stub
+android.hardware.soundtrigger.IRecognitionStatusCallback
+android.hardware.soundtrigger.IRecognitionStatusCallback$Stub
+android.hardware.soundtrigger.KeyphraseEnrollmentInfo
+android.hardware.soundtrigger.KeyphraseMetadata
+android.hardware.soundtrigger.SoundTrigger
+android.hardware.soundtrigger.SoundTrigger$ConfidenceLevel
+android.hardware.soundtrigger.SoundTrigger$ConfidenceLevel$1
+android.hardware.soundtrigger.SoundTrigger$GenericRecognitionEvent
+android.hardware.soundtrigger.SoundTrigger$GenericRecognitionEvent$1
+android.hardware.soundtrigger.SoundTrigger$GenericSoundModel
+android.hardware.soundtrigger.SoundTrigger$Keyphrase
+android.hardware.soundtrigger.SoundTrigger$Keyphrase$1
+android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionEvent
+android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionEvent$1
+android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionExtra
+android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionExtra$1
+android.hardware.soundtrigger.SoundTrigger$KeyphraseSoundModel
+android.hardware.soundtrigger.SoundTrigger$KeyphraseSoundModel$1
+android.hardware.soundtrigger.SoundTrigger$ModuleProperties
+android.hardware.soundtrigger.SoundTrigger$ModuleProperties$1
+android.hardware.soundtrigger.SoundTrigger$RecognitionConfig
+android.hardware.soundtrigger.SoundTrigger$RecognitionConfig$1
+android.hardware.soundtrigger.SoundTrigger$RecognitionEvent
+android.hardware.soundtrigger.SoundTrigger$RecognitionEvent$1
+android.hardware.soundtrigger.SoundTrigger$SoundModel
+android.hardware.soundtrigger.SoundTrigger$SoundModelEvent
+android.hardware.soundtrigger.SoundTrigger$SoundModelEvent$1
+android.hardware.soundtrigger.SoundTrigger$StatusListener
+android.hardware.soundtrigger.SoundTriggerModule
+android.hardware.usb.IUsbManager
+android.hardware.usb.IUsbManager$Stub
+android.hardware.usb.IUsbManager$Stub$Proxy
+android.hardware.usb.UsbAccessory
+android.hardware.usb.UsbDevice
+android.hardware.usb.UsbDeviceConnection
+android.hardware.usb.UsbManager
+android.hardware.usb.UsbPort
+android.hardware.usb.UsbPort$1
+android.hardware.usb.UsbPortStatus
+android.hardware.usb.UsbPortStatus$1
+android.hardware.usb.UsbRequest
+android.hidl.base.V1_0.DebugInfo
+android.hidl.base.V1_0.IBase
+android.hidl.manager.V1_0.IServiceManager
+android.hidl.manager.V1_0.IServiceManager$Proxy
+android.hidl.manager.V1_0.IServiceNotification
+android.hidl.manager.V1_0.IServiceNotification$Stub
+android.icu.impl.BMPSet
+android.icu.impl.CacheBase
+android.icu.impl.CacheValue
+android.icu.impl.CacheValue$NullValue
+android.icu.impl.CacheValue$SoftValue
+android.icu.impl.CacheValue$Strength
+android.icu.impl.CalendarUtil
+android.icu.impl.CalendarUtil$CalendarPreferences
+android.icu.impl.CaseMapImpl
+android.icu.impl.CaseMapImpl$GreekUpper
+android.icu.impl.CaseMapImpl$StringContextIterator
+android.icu.impl.CharTrie
+android.icu.impl.CharacterIteration
+android.icu.impl.ClassLoaderUtil
+android.icu.impl.CurrencyData
+android.icu.impl.CurrencyData$CurrencyDisplayInfo
+android.icu.impl.CurrencyData$CurrencyDisplayInfoProvider
+android.icu.impl.CurrencyData$CurrencySpacingInfo
+android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingPattern
+android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingType
+android.icu.impl.DateNumberFormat
+android.icu.impl.DontCareFieldPosition
+android.icu.impl.Grego
+android.icu.impl.ICUBinary
+android.icu.impl.ICUBinary$Authenticate
+android.icu.impl.ICUBinary$DatPackageReader
+android.icu.impl.ICUBinary$DatPackageReader$IsAcceptable
+android.icu.impl.ICUBinary$DataFile
+android.icu.impl.ICUBinary$PackageDataFile
+android.icu.impl.ICUCache
+android.icu.impl.ICUConfig
+android.icu.impl.ICUCurrencyDisplayInfoProvider
+android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo
+android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo$SpacingInfoSink
+android.icu.impl.ICUCurrencyMetaInfo
+android.icu.impl.ICUCurrencyMetaInfo$Collector
+android.icu.impl.ICUCurrencyMetaInfo$CurrencyCollector
+android.icu.impl.ICUCurrencyMetaInfo$UniqueList
+android.icu.impl.ICUData
+android.icu.impl.ICUDebug
+android.icu.impl.ICULangDataTables
+android.icu.impl.ICULocaleService
+android.icu.impl.ICULocaleService$ICUResourceBundleFactory
+android.icu.impl.ICULocaleService$LocaleKey
+android.icu.impl.ICULocaleService$LocaleKeyFactory
+android.icu.impl.ICUNotifier
+android.icu.impl.ICURWLock
+android.icu.impl.ICURegionDataTables
+android.icu.impl.ICUResourceBundle
+android.icu.impl.ICUResourceBundle$1
+android.icu.impl.ICUResourceBundle$2
+android.icu.impl.ICUResourceBundle$3
+android.icu.impl.ICUResourceBundle$3$1
+android.icu.impl.ICUResourceBundle$4
+android.icu.impl.ICUResourceBundle$AvailEntry
+android.icu.impl.ICUResourceBundle$Loader
+android.icu.impl.ICUResourceBundle$OpenType
+android.icu.impl.ICUResourceBundle$WholeBundle
+android.icu.impl.ICUResourceBundleImpl
+android.icu.impl.ICUResourceBundleImpl$ResourceArray
+android.icu.impl.ICUResourceBundleImpl$ResourceBinary
+android.icu.impl.ICUResourceBundleImpl$ResourceContainer
+android.icu.impl.ICUResourceBundleImpl$ResourceInt
+android.icu.impl.ICUResourceBundleImpl$ResourceIntVector
+android.icu.impl.ICUResourceBundleImpl$ResourceString
+android.icu.impl.ICUResourceBundleImpl$ResourceTable
+android.icu.impl.ICUResourceBundleReader
+android.icu.impl.ICUResourceBundleReader$Array
+android.icu.impl.ICUResourceBundleReader$Array16
+android.icu.impl.ICUResourceBundleReader$Array32
+android.icu.impl.ICUResourceBundleReader$Container
+android.icu.impl.ICUResourceBundleReader$IsAcceptable
+android.icu.impl.ICUResourceBundleReader$ReaderCache
+android.icu.impl.ICUResourceBundleReader$ReaderCacheKey
+android.icu.impl.ICUResourceBundleReader$ReaderValue
+android.icu.impl.ICUResourceBundleReader$ResourceCache
+android.icu.impl.ICUResourceBundleReader$ResourceCache$Level
+android.icu.impl.ICUResourceBundleReader$Table
+android.icu.impl.ICUResourceBundleReader$Table16
+android.icu.impl.ICUResourceBundleReader$Table1632
+android.icu.impl.ICUResourceTableAccess
+android.icu.impl.ICUService
+android.icu.impl.ICUService$CacheEntry
+android.icu.impl.ICUService$Factory
+android.icu.impl.ICUService$Key
+android.icu.impl.IDNA2003
+android.icu.impl.JavaTimeZone
+android.icu.impl.LocaleDisplayNamesImpl
+android.icu.impl.LocaleDisplayNamesImpl$Cache
+android.icu.impl.LocaleDisplayNamesImpl$CapitalizationContextUsage
+android.icu.impl.LocaleDisplayNamesImpl$DataTable
+android.icu.impl.LocaleDisplayNamesImpl$DataTables
+android.icu.impl.LocaleDisplayNamesImpl$ICUDataTable
+android.icu.impl.LocaleDisplayNamesImpl$ICUDataTables
+android.icu.impl.LocaleDisplayNamesImpl$LangDataTables
+android.icu.impl.LocaleDisplayNamesImpl$RegionDataTables
+android.icu.impl.LocaleIDParser
+android.icu.impl.LocaleIDs
+android.icu.impl.Norm2AllModes
+android.icu.impl.Norm2AllModes$1
+android.icu.impl.Norm2AllModes$ComposeNormalizer2
+android.icu.impl.Norm2AllModes$DecomposeNormalizer2
+android.icu.impl.Norm2AllModes$FCDNormalizer2
+android.icu.impl.Norm2AllModes$NFCSingleton
+android.icu.impl.Norm2AllModes$NFKCSingleton
+android.icu.impl.Norm2AllModes$NoopNormalizer2
+android.icu.impl.Norm2AllModes$Norm2AllModesSingleton
+android.icu.impl.Norm2AllModes$Normalizer2WithImpl
+android.icu.impl.Normalizer2Impl
+android.icu.impl.Normalizer2Impl$1
+android.icu.impl.Normalizer2Impl$IsAcceptable
+android.icu.impl.Normalizer2Impl$ReorderingBuffer
+android.icu.impl.OlsonTimeZone
+android.icu.impl.Pair
+android.icu.impl.PatternProps
+android.icu.impl.PatternTokenizer
+android.icu.impl.PluralRulesLoader
+android.icu.impl.ReplaceableUCharacterIterator
+android.icu.impl.RuleCharacterIterator
+android.icu.impl.SimpleCache
+android.icu.impl.SimpleFormatterImpl
+android.icu.impl.SoftCache
+android.icu.impl.StandardPlural
+android.icu.impl.StringPrepDataReader
+android.icu.impl.Trie
+android.icu.impl.Trie$DataManipulate
+android.icu.impl.Trie$DefaultGetFoldingOffset
+android.icu.impl.Trie2
+android.icu.impl.Trie2$1
+android.icu.impl.Trie2$Range
+android.icu.impl.Trie2$Trie2Iterator
+android.icu.impl.Trie2$UTrie2Header
+android.icu.impl.Trie2$ValueMapper
+android.icu.impl.Trie2$ValueWidth
+android.icu.impl.Trie2_16
+android.icu.impl.Trie2_32
+android.icu.impl.UBiDiProps
+android.icu.impl.UBiDiProps$IsAcceptable
+android.icu.impl.UCaseProps
+android.icu.impl.UCaseProps$ContextIterator
+android.icu.impl.UCaseProps$IsAcceptable
+android.icu.impl.UCharacterProperty
+android.icu.impl.UCharacterProperty$1
+android.icu.impl.UCharacterProperty$10
+android.icu.impl.UCharacterProperty$11
+android.icu.impl.UCharacterProperty$12
+android.icu.impl.UCharacterProperty$13
+android.icu.impl.UCharacterProperty$14
+android.icu.impl.UCharacterProperty$15
+android.icu.impl.UCharacterProperty$16
+android.icu.impl.UCharacterProperty$17
+android.icu.impl.UCharacterProperty$18
+android.icu.impl.UCharacterProperty$19
+android.icu.impl.UCharacterProperty$2
+android.icu.impl.UCharacterProperty$20
+android.icu.impl.UCharacterProperty$21
+android.icu.impl.UCharacterProperty$22
+android.icu.impl.UCharacterProperty$23
+android.icu.impl.UCharacterProperty$3
+android.icu.impl.UCharacterProperty$4
+android.icu.impl.UCharacterProperty$5
+android.icu.impl.UCharacterProperty$6
+android.icu.impl.UCharacterProperty$7
+android.icu.impl.UCharacterProperty$8
+android.icu.impl.UCharacterProperty$9
+android.icu.impl.UCharacterProperty$BiDiIntProperty
+android.icu.impl.UCharacterProperty$BinaryProperty
+android.icu.impl.UCharacterProperty$CaseBinaryProperty
+android.icu.impl.UCharacterProperty$CombiningClassIntProperty
+android.icu.impl.UCharacterProperty$IntProperty
+android.icu.impl.UCharacterProperty$IsAcceptable
+android.icu.impl.UCharacterProperty$NormInertBinaryProperty
+android.icu.impl.UCharacterProperty$NormQuickCheckIntProperty
+android.icu.impl.UPropertyAliases
+android.icu.impl.UPropertyAliases$IsAcceptable
+android.icu.impl.URLHandler$URLVisitor
+android.icu.impl.UResource$Array
+android.icu.impl.UResource$Key
+android.icu.impl.UResource$Sink
+android.icu.impl.UResource$Table
+android.icu.impl.UResource$Value
+android.icu.impl.USerializedSet
+android.icu.impl.Utility
+android.icu.impl.ZoneMeta
+android.icu.impl.ZoneMeta$CustomTimeZoneCache
+android.icu.impl.ZoneMeta$SystemTimeZoneCache
+android.icu.impl.coll.Collation
+android.icu.impl.coll.CollationCompare
+android.icu.impl.coll.CollationData
+android.icu.impl.coll.CollationDataReader
+android.icu.impl.coll.CollationDataReader$IsAcceptable
+android.icu.impl.coll.CollationFCD
+android.icu.impl.coll.CollationFastLatin
+android.icu.impl.coll.CollationIterator
+android.icu.impl.coll.CollationIterator$CEBuffer
+android.icu.impl.coll.CollationKeys
+android.icu.impl.coll.CollationKeys$LevelCallback
+android.icu.impl.coll.CollationKeys$SortKeyByteSink
+android.icu.impl.coll.CollationLoader
+android.icu.impl.coll.CollationRoot
+android.icu.impl.coll.CollationSettings
+android.icu.impl.coll.CollationTailoring
+android.icu.impl.coll.ContractionsAndExpansions
+android.icu.impl.coll.FCDUTF16CollationIterator
+android.icu.impl.coll.SharedObject
+android.icu.impl.coll.SharedObject$Reference
+android.icu.impl.coll.UTF16CollationIterator
+android.icu.impl.locale.AsciiUtil
+android.icu.impl.locale.BaseLocale
+android.icu.impl.locale.BaseLocale$Cache
+android.icu.impl.locale.BaseLocale$Key
+android.icu.impl.locale.LocaleObjectCache
+android.icu.impl.locale.LocaleObjectCache$CacheEntry
+android.icu.impl.locale.LocaleSyntaxException
+android.icu.lang.UCharacter
+android.icu.lang.UCharacterEnums$ECharacterCategory
+android.icu.lang.UCharacterEnums$ECharacterDirection
+android.icu.lang.UScript
+android.icu.lang.UScript$ScriptUsage
+android.icu.math.BigDecimal
+android.icu.math.MathContext
+android.icu.text.AlphabeticIndex
+android.icu.text.AlphabeticIndex$1
+android.icu.text.AlphabeticIndex$Bucket
+android.icu.text.AlphabeticIndex$Bucket$LabelType
+android.icu.text.AlphabeticIndex$BucketList
+android.icu.text.AlphabeticIndex$ImmutableIndex
+android.icu.text.Bidi
+android.icu.text.Bidi$ImpTabPair
+android.icu.text.BreakIterator
+android.icu.text.BreakIterator$BreakIteratorCache
+android.icu.text.BreakIterator$BreakIteratorServiceShim
+android.icu.text.BreakIteratorFactory
+android.icu.text.BreakIteratorFactory$BFService
+android.icu.text.BreakIteratorFactory$BFService$1RBBreakIteratorFactory
+android.icu.text.CaseMap
+android.icu.text.CaseMap$Upper
+android.icu.text.CollationKey
+android.icu.text.Collator
+android.icu.text.Collator$ServiceShim
+android.icu.text.CollatorServiceShim
+android.icu.text.CollatorServiceShim$CService
+android.icu.text.CollatorServiceShim$CService$1CollatorFactory
+android.icu.text.CurrencyDisplayNames
+android.icu.text.CurrencyMetaInfo
+android.icu.text.CurrencyMetaInfo$CurrencyDigits
+android.icu.text.CurrencyMetaInfo$CurrencyFilter
+android.icu.text.CurrencyPluralInfo
+android.icu.text.DateFormat
+android.icu.text.DateFormat$BooleanAttribute
+android.icu.text.DateFormat$Field
+android.icu.text.DateFormatSymbols
+android.icu.text.DateFormatSymbols$1
+android.icu.text.DateFormatSymbols$CalendarDataSink
+android.icu.text.DateFormatSymbols$CalendarDataSink$AliasType
+android.icu.text.DateFormatSymbols$CapitalizationContextUsage
+android.icu.text.DateIntervalFormat
+android.icu.text.DateIntervalFormat$BestMatchInfo
+android.icu.text.DateIntervalFormat$SkeletonAndItsBestMatch
+android.icu.text.DateIntervalInfo
+android.icu.text.DateIntervalInfo$DateIntervalSink
+android.icu.text.DateIntervalInfo$PatternInfo
+android.icu.text.DateTimePatternGenerator
+android.icu.text.DateTimePatternGenerator$AppendItemFormatsSink
+android.icu.text.DateTimePatternGenerator$AppendItemNamesSink
+android.icu.text.DateTimePatternGenerator$AvailableFormatsSink
+android.icu.text.DateTimePatternGenerator$DTPGflags
+android.icu.text.DateTimePatternGenerator$DateTimeMatcher
+android.icu.text.DateTimePatternGenerator$DayPeriodAllowedHoursSink
+android.icu.text.DateTimePatternGenerator$DistanceInfo
+android.icu.text.DateTimePatternGenerator$FormatParser
+android.icu.text.DateTimePatternGenerator$PatternInfo
+android.icu.text.DateTimePatternGenerator$PatternWithMatcher
+android.icu.text.DateTimePatternGenerator$PatternWithSkeletonFlag
+android.icu.text.DateTimePatternGenerator$SkeletonFields
+android.icu.text.DateTimePatternGenerator$VariableField
+android.icu.text.DecimalFormat
+android.icu.text.DecimalFormat$Unit
+android.icu.text.DecimalFormatSymbols
+android.icu.text.DecimalFormatSymbols$1
+android.icu.text.DecimalFormatSymbols$CacheData
+android.icu.text.DecimalFormatSymbols$DecFmtDataSink
+android.icu.text.DigitList
+android.icu.text.DisplayContext
+android.icu.text.DisplayContext$Type
+android.icu.text.Edits
+android.icu.text.IDNA
+android.icu.text.LanguageBreakEngine
+android.icu.text.ListFormatter$Style
+android.icu.text.LocaleDisplayNames
+android.icu.text.LocaleDisplayNames$DialectHandling
+android.icu.text.MeasureFormat
+android.icu.text.MeasureFormat$FormatWidth
+android.icu.text.MeasureFormat$ImmutableNumberFormat
+android.icu.text.MeasureFormat$MeasureFormatData
+android.icu.text.MeasureFormat$UnitDataSink
+android.icu.text.Normalizer
+android.icu.text.Normalizer$FCDMode
+android.icu.text.Normalizer$Mode
+android.icu.text.Normalizer$ModeImpl
+android.icu.text.Normalizer$NFCMode
+android.icu.text.Normalizer$NFCModeImpl
+android.icu.text.Normalizer$NFDMode
+android.icu.text.Normalizer$NFKCMode
+android.icu.text.Normalizer$NFKDMode
+android.icu.text.Normalizer$NFKDModeImpl
+android.icu.text.Normalizer$NONEMode
+android.icu.text.Normalizer$QuickCheckResult
+android.icu.text.Normalizer2
+android.icu.text.NumberFormat
+android.icu.text.NumberFormat$Field
+android.icu.text.NumberFormat$NumberFormatShim
+android.icu.text.NumberFormatServiceShim
+android.icu.text.NumberFormatServiceShim$NFService
+android.icu.text.NumberFormatServiceShim$NFService$1RBNumberFormatFactory
+android.icu.text.NumberingSystem
+android.icu.text.NumberingSystem$1
+android.icu.text.NumberingSystem$2
+android.icu.text.NumberingSystem$LocaleLookupData
+android.icu.text.PluralRanges
+android.icu.text.PluralRanges$Matrix
+android.icu.text.PluralRules
+android.icu.text.PluralRules$1
+android.icu.text.PluralRules$AndConstraint
+android.icu.text.PluralRules$BinaryConstraint
+android.icu.text.PluralRules$Constraint
+android.icu.text.PluralRules$Factory
+android.icu.text.PluralRules$FixedDecimal
+android.icu.text.PluralRules$FixedDecimalRange
+android.icu.text.PluralRules$FixedDecimalSamples
+android.icu.text.PluralRules$Operand
+android.icu.text.PluralRules$PluralType
+android.icu.text.PluralRules$RangeConstraint
+android.icu.text.PluralRules$Rule
+android.icu.text.PluralRules$RuleList
+android.icu.text.PluralRules$SampleType
+android.icu.text.PluralRules$SimpleTokenizer
+android.icu.text.QuantityFormatter
+android.icu.text.RBBIDataWrapper
+android.icu.text.RBBIDataWrapper$IsAcceptable
+android.icu.text.RBBIDataWrapper$RBBIDataHeader
+android.icu.text.RBBIDataWrapper$TrieFoldingFunc
+android.icu.text.RawCollationKey
+android.icu.text.RelativeDateTimeFormatter
+android.icu.text.RelativeDateTimeFormatter$AbsoluteUnit
+android.icu.text.RelativeDateTimeFormatter$Cache
+android.icu.text.RelativeDateTimeFormatter$Cache$1
+android.icu.text.RelativeDateTimeFormatter$Direction
+android.icu.text.RelativeDateTimeFormatter$Loader
+android.icu.text.RelativeDateTimeFormatter$RelDateTimeDataSink
+android.icu.text.RelativeDateTimeFormatter$RelDateTimeDataSink$DateTimeUnit
+android.icu.text.RelativeDateTimeFormatter$RelativeDateTimeFormatterData
+android.icu.text.RelativeDateTimeFormatter$RelativeUnit
+android.icu.text.RelativeDateTimeFormatter$Style
+android.icu.text.Replaceable
+android.icu.text.ReplaceableString
+android.icu.text.RuleBasedBreakIterator
+android.icu.text.RuleBasedBreakIterator$LookAheadResults
+android.icu.text.RuleBasedCollator
+android.icu.text.RuleBasedCollator$CollationBuffer
+android.icu.text.RuleBasedCollator$CollationKeyByteSink
+android.icu.text.RuleBasedCollator$FCDUTF16NFDIterator
+android.icu.text.RuleBasedCollator$NFDIterator
+android.icu.text.RuleBasedCollator$UTF16NFDIterator
+android.icu.text.SimpleDateFormat
+android.icu.text.SimpleDateFormat$PatternItem
+android.icu.text.StringPrep
+android.icu.text.StringPrepParseException
+android.icu.text.TimeZoneNames$NameType
+android.icu.text.UCharacterIterator
+android.icu.text.UFieldPosition
+android.icu.text.UFormat
+android.icu.text.UForwardCharacterIterator
+android.icu.text.UTF16
+android.icu.text.UTF16$StringComparator
+android.icu.text.UnhandledBreakEngine
+android.icu.text.UnicodeFilter
+android.icu.text.UnicodeMatcher
+android.icu.text.UnicodeSet
+android.icu.text.UnicodeSet$Filter
+android.icu.text.UnicodeSet$GeneralCategoryMaskFilter
+android.icu.text.UnicodeSet$IntPropertyFilter
+android.icu.text.UnicodeSet$UnicodeSetIterator2
+android.icu.util.BasicTimeZone
+android.icu.util.ByteArrayWrapper
+android.icu.util.BytesTrie
+android.icu.util.BytesTrie$Result
+android.icu.util.Calendar
+android.icu.util.Calendar$CalType
+android.icu.util.Calendar$FormatConfiguration
+android.icu.util.Calendar$PatternData
+android.icu.util.Calendar$WeekData
+android.icu.util.Calendar$WeekDataCache
+android.icu.util.CharsTrie
+android.icu.util.CharsTrie$Entry
+android.icu.util.CharsTrie$Iterator
+android.icu.util.Currency
+android.icu.util.Currency$1
+android.icu.util.Currency$CurrencyUsage
+android.icu.util.Currency$EquivalenceRelation
+android.icu.util.CurrencyAmount
+android.icu.util.Freezable
+android.icu.util.GregorianCalendar
+android.icu.util.ICUException
+android.icu.util.ICUUncheckedIOException
+android.icu.util.LocaleData
+android.icu.util.Measure
+android.icu.util.MeasureUnit
+android.icu.util.MeasureUnit$1
+android.icu.util.MeasureUnit$2
+android.icu.util.MeasureUnit$3
+android.icu.util.MeasureUnit$Factory
+android.icu.util.Output
+android.icu.util.SimpleTimeZone
+android.icu.util.TimeUnit
+android.icu.util.TimeZone
+android.icu.util.TimeZone$ConstantZone
+android.icu.util.ULocale
+android.icu.util.ULocale$1
+android.icu.util.ULocale$2
+android.icu.util.ULocale$Category
+android.icu.util.ULocale$JDKLocaleHelper
+android.icu.util.ULocale$Type
+android.icu.util.UResourceBundle
+android.icu.util.UResourceBundle$RootType
+android.icu.util.UResourceBundleIterator
+android.icu.util.UResourceTypeMismatchException
+android.icu.util.VersionInfo
+android.inputmethodservice.AbstractInputMethodService
+android.inputmethodservice.AbstractInputMethodService$AbstractInputMethodImpl
+android.inputmethodservice.AbstractInputMethodService$AbstractInputMethodSessionImpl
+android.inputmethodservice.IInputMethodSessionWrapper
+android.inputmethodservice.IInputMethodSessionWrapper$ImeInputEventReceiver
+android.inputmethodservice.IInputMethodWrapper
+android.inputmethodservice.IInputMethodWrapper$InputMethodSessionCallbackWrapper
+android.inputmethodservice.InputMethodService
+android.inputmethodservice.InputMethodService$1
+android.inputmethodservice.InputMethodService$2
+android.inputmethodservice.InputMethodService$InputMethodImpl
+android.inputmethodservice.InputMethodService$InputMethodSessionImpl
+android.inputmethodservice.InputMethodService$Insets
+android.inputmethodservice.InputMethodService$SettingsObserver
+android.inputmethodservice.SoftInputWindow
+android.location.Address
+android.location.Address$1
+android.location.BatchedLocationCallbackTransport
+android.location.BatchedLocationCallbackTransport$CallbackTransport
+android.location.Country
+android.location.Country$1
+android.location.CountryDetector
+android.location.CountryDetector$ListenerTransport
+android.location.CountryDetector$ListenerTransport$1
+android.location.CountryListener
+android.location.Criteria
+android.location.Criteria$1
+android.location.Geocoder
+android.location.GeocoderParams
+android.location.GeocoderParams$1
+android.location.Geofence
+android.location.GnssMeasurementCallbackTransport
+android.location.GnssMeasurementCallbackTransport$ListenerTransport
+android.location.GnssNavigationMessageCallbackTransport
+android.location.GnssNavigationMessageCallbackTransport$ListenerTransport
+android.location.GnssStatus
+android.location.GnssStatus$Callback
+android.location.GpsSatellite
+android.location.GpsStatus
+android.location.GpsStatus$1
+android.location.GpsStatus$Listener
+android.location.GpsStatus$SatelliteIterator
+android.location.IBatchedLocationCallback
+android.location.IBatchedLocationCallback$Stub
+android.location.ICountryDetector
+android.location.ICountryDetector$Stub
+android.location.ICountryDetector$Stub$Proxy
+android.location.ICountryListener
+android.location.ICountryListener$Stub
+android.location.ICountryListener$Stub$Proxy
+android.location.IFusedProvider
+android.location.IFusedProvider$Stub
+android.location.IGeocodeProvider
+android.location.IGeocodeProvider$Stub
+android.location.IGeocodeProvider$Stub$Proxy
+android.location.IGeofenceProvider
+android.location.IGeofenceProvider$Stub
+android.location.IGeofenceProvider$Stub$Proxy
+android.location.IGnssMeasurementsListener
+android.location.IGnssMeasurementsListener$Stub
+android.location.IGnssNavigationMessageListener
+android.location.IGnssNavigationMessageListener$Stub
+android.location.IGnssStatusListener
+android.location.IGnssStatusListener$Stub
+android.location.IGnssStatusListener$Stub$Proxy
+android.location.IGnssStatusProvider
+android.location.IGnssStatusProvider$Stub
+android.location.IGpsGeofenceHardware
+android.location.IGpsGeofenceHardware$Stub
+android.location.ILocationListener
+android.location.ILocationListener$Stub
+android.location.ILocationListener$Stub$Proxy
+android.location.ILocationManager
+android.location.ILocationManager$Stub
+android.location.ILocationManager$Stub$Proxy
+android.location.INetInitiatedListener
+android.location.INetInitiatedListener$Stub
+android.location.LocalListenerHelper
+android.location.Location
+android.location.Location$1
+android.location.Location$2
+android.location.Location$BearingDistanceCache
+android.location.LocationListener
+android.location.LocationManager
+android.location.LocationManager$GnssStatusListenerTransport
+android.location.LocationManager$GnssStatusListenerTransport$1
+android.location.LocationManager$GnssStatusListenerTransport$GnssHandler
+android.location.LocationManager$ListenerTransport
+android.location.LocationManager$ListenerTransport$1
+android.location.LocationManager$ListenerTransport$2
+android.location.LocationProvider
+android.location.LocationRequest
+android.location.LocationRequest$1
+android.media.AudioAttributes
+android.media.AudioAttributes$1
+android.media.AudioAttributes$Builder
+android.media.AudioDeviceCallback
+android.media.AudioDeviceInfo
+android.media.AudioDevicePort
+android.media.AudioDevicePortConfig
+android.media.AudioFocusInfo
+android.media.AudioFocusInfo$1
+android.media.AudioFocusRequest
+android.media.AudioFocusRequest$Builder
+android.media.AudioFormat
+android.media.AudioFormat$1
+android.media.AudioFormat$Builder
+android.media.AudioGain
+android.media.AudioGainConfig
+android.media.AudioHandle
+android.media.AudioManager
+android.media.AudioManager$1
+android.media.AudioManager$2
+android.media.AudioManager$3
+android.media.AudioManager$FocusRequestInfo
+android.media.AudioManager$NativeEventHandlerDelegate
+android.media.AudioManager$NativeEventHandlerDelegate$1
+android.media.AudioManager$OnAmPortUpdateListener
+android.media.AudioManager$OnAudioFocusChangeListener
+android.media.AudioManager$OnAudioPortUpdateListener
+android.media.AudioManager$ServiceEventHandlerDelegate
+android.media.AudioManager$ServiceEventHandlerDelegate$1
+android.media.AudioManagerInternal
+android.media.AudioManagerInternal$RingerModeDelegate
+android.media.AudioMixPort
+android.media.AudioMixPortConfig
+android.media.AudioPatch
+android.media.AudioPlaybackConfiguration
+android.media.AudioPlaybackConfiguration$1
+android.media.AudioPlaybackConfiguration$IPlayerShell
+android.media.AudioPlaybackConfiguration$PlayerDeathMonitor
+android.media.AudioPort
+android.media.AudioPortConfig
+android.media.AudioPortEventHandler
+android.media.AudioPortEventHandler$1
+android.media.AudioRecord
+android.media.AudioRoutesInfo
+android.media.AudioRoutesInfo$1
+android.media.AudioRouting
+android.media.AudioSystem
+android.media.AudioSystem$AudioRecordingCallback
+android.media.AudioSystem$DynamicPolicyCallback
+android.media.AudioSystem$ErrorCallback
+android.media.AudioTimestamp
+android.media.AudioTrack
+android.media.BufferingParams
+android.media.BufferingParams$1
+android.media.CamcorderProfile
+android.media.CameraProfile
+android.media.DecoderCapabilities
+android.media.DeniedByServerException
+android.media.EncoderCapabilities
+android.media.ExifInterface
+android.media.ExifInterface$ByteOrderedDataInputStream
+android.media.ExifInterface$ExifAttribute
+android.media.ExifInterface$ExifTag
+android.media.IAudioFocusDispatcher
+android.media.IAudioFocusDispatcher$Stub
+android.media.IAudioFocusDispatcher$Stub$Proxy
+android.media.IAudioRoutesObserver
+android.media.IAudioRoutesObserver$Stub
+android.media.IAudioRoutesObserver$Stub$Proxy
+android.media.IAudioService
+android.media.IAudioService$Stub
+android.media.IAudioService$Stub$Proxy
+android.media.IMediaHTTPConnection
+android.media.IMediaHTTPConnection$Stub
+android.media.IMediaHTTPService
+android.media.IMediaHTTPService$Stub
+android.media.IMediaResourceMonitor
+android.media.IMediaResourceMonitor$Stub
+android.media.IMediaRouterClient
+android.media.IMediaRouterClient$Stub
+android.media.IMediaRouterClient$Stub$Proxy
+android.media.IMediaRouterService
+android.media.IMediaRouterService$Stub
+android.media.IMediaRouterService$Stub$Proxy
+android.media.IPlaybackConfigDispatcher
+android.media.IPlaybackConfigDispatcher$Stub
+android.media.IPlayer
+android.media.IPlayer$Stub
+android.media.IPlayer$Stub$Proxy
+android.media.IRecordingConfigDispatcher
+android.media.IRecordingConfigDispatcher$Stub
+android.media.IRemoteVolumeController
+android.media.IRemoteVolumeController$Stub
+android.media.IRemoteVolumeController$Stub$Proxy
+android.media.IRemoteVolumeObserver
+android.media.IRemoteVolumeObserver$Stub
+android.media.IRingtonePlayer
+android.media.IRingtonePlayer$Stub
+android.media.IRingtonePlayer$Stub$Proxy
+android.media.IVolumeController
+android.media.IVolumeController$Stub
+android.media.IVolumeController$Stub$Proxy
+android.media.Image
+android.media.Image$Plane
+android.media.ImageReader
+android.media.ImageReader$ListenerHandler
+android.media.ImageReader$OnImageAvailableListener
+android.media.ImageReader$SurfaceImage
+android.media.ImageReader$SurfaceImage$SurfacePlane
+android.media.ImageUtils
+android.media.ImageWriter
+android.media.ImageWriter$ListenerHandler
+android.media.ImageWriter$OnImageReleasedListener
+android.media.ImageWriter$WriterSurfaceImage
+android.media.ImageWriter$WriterSurfaceImage$SurfacePlane
+android.media.JetPlayer
+android.media.MediaCodec
+android.media.MediaCodec$BufferInfo
+android.media.MediaCodec$BufferMap
+android.media.MediaCodec$BufferMap$CodecBuffer
+android.media.MediaCodec$CodecException
+android.media.MediaCodec$CryptoException
+android.media.MediaCodec$CryptoInfo
+android.media.MediaCodec$CryptoInfo$Pattern
+android.media.MediaCodec$EventHandler
+android.media.MediaCodec$PersistentSurface
+android.media.MediaCodecInfo
+android.media.MediaCodecInfo$AudioCapabilities
+android.media.MediaCodecInfo$CodecCapabilities
+android.media.MediaCodecInfo$CodecProfileLevel
+android.media.MediaCodecInfo$EncoderCapabilities
+android.media.MediaCodecInfo$Feature
+android.media.MediaCodecInfo$VideoCapabilities
+android.media.MediaCodecList
+android.media.MediaCrypto
+android.media.MediaCryptoException
+android.media.MediaDescrambler
+android.media.MediaDescription
+android.media.MediaDescription$1
+android.media.MediaDescription$Builder
+android.media.MediaDrm
+android.media.MediaDrm$Certificate
+android.media.MediaDrm$EventHandler
+android.media.MediaDrm$KeyRequest
+android.media.MediaDrm$MediaDrmStateException
+android.media.MediaDrm$OnEventListener
+android.media.MediaDrm$ProvisionRequest
+android.media.MediaDrmException
+android.media.MediaExtractor
+android.media.MediaFile
+android.media.MediaFile$MediaFileType
+android.media.MediaFormat
+android.media.MediaHTTPConnection
+android.media.MediaHTTPService
+android.media.MediaMetadata
+android.media.MediaMetadata$1
+android.media.MediaMetadata$Builder
+android.media.MediaMetadataRetriever
+android.media.MediaMuxer
+android.media.MediaPlayer
+android.media.MediaPlayer$1
+android.media.MediaPlayer$2
+android.media.MediaPlayer$4
+android.media.MediaPlayer$4$1
+android.media.MediaPlayer$EventHandler
+android.media.MediaPlayer$OnCompletionListener
+android.media.MediaPlayer$OnErrorListener
+android.media.MediaPlayer$OnInfoListener
+android.media.MediaPlayer$OnPreparedListener
+android.media.MediaPlayer$OnSeekCompleteListener
+android.media.MediaPlayer$OnSubtitleDataListener
+android.media.MediaPlayer$TimeProvider
+android.media.MediaPlayer$TimeProvider$EventHandler
+android.media.MediaPlayer$TrackInfo
+android.media.MediaPlayer$TrackInfo$1
+android.media.MediaRecorder
+android.media.MediaRecorder$EventHandler
+android.media.MediaRecorder$OnErrorListener
+android.media.MediaRouter
+android.media.MediaRouter$Callback
+android.media.MediaRouter$CallbackInfo
+android.media.MediaRouter$RouteCategory
+android.media.MediaRouter$RouteGroup
+android.media.MediaRouter$RouteInfo
+android.media.MediaRouter$RouteInfo$1
+android.media.MediaRouter$SimpleCallback
+android.media.MediaRouter$Static
+android.media.MediaRouter$Static$1
+android.media.MediaRouter$Static$Client
+android.media.MediaRouter$Static$Client$1
+android.media.MediaRouter$VolumeCallback
+android.media.MediaRouter$VolumeChangeReceiver
+android.media.MediaRouter$WifiDisplayStatusChangedReceiver
+android.media.MediaRouterClientState
+android.media.MediaRouterClientState$1
+android.media.MediaRouterClientState$RouteInfo
+android.media.MediaRouterClientState$RouteInfo$1
+android.media.MediaScanner
+android.media.MediaScannerConnection
+android.media.MediaScannerConnection$OnScanCompletedListener
+android.media.MediaSync
+android.media.MediaTimeProvider
+android.media.MediaTimeProvider$OnMediaTimeListener
+android.media.MiniThumbFile
+android.media.NotProvisionedException
+android.media.PlaybackParams
+android.media.PlaybackParams$1
+android.media.PlayerBase
+android.media.PlayerBase$IAppOpsCallbackWrapper
+android.media.PlayerBase$IPlayerWrapper
+android.media.PlayerBase$PlayerIdCard
+android.media.PlayerBase$PlayerIdCard$1
+android.media.PlayerProxy
+android.media.Rating
+android.media.Rating$1
+android.media.RemoteDisplay
+android.media.ResampleInputStream
+android.media.SoundPool
+android.media.SoundPool$Builder
+android.media.SoundPool$EventHandler
+android.media.SoundPool$OnLoadCompleteListener
+android.media.SubtitleController
+android.media.SubtitleController$1
+android.media.SubtitleController$2
+android.media.SubtitleController$Anchor
+android.media.SubtitleController$Listener
+android.media.SubtitleTrack
+android.media.SyncParams
+android.media.ThumbnailUtils
+android.media.ThumbnailUtils$SizedThumbnailBitmap
+android.media.ToneGenerator
+android.media.UnsupportedSchemeException
+android.media.Utils
+android.media.Utils$1
+android.media.Utils$2
+android.media.VolumeAutomation
+android.media.VolumePolicy
+android.media.VolumePolicy$1
+android.media.VolumeShaper
+android.media.VolumeShaper$Configuration
+android.media.VolumeShaper$Configuration$1
+android.media.VolumeShaper$Configuration$Builder
+android.media.VolumeShaper$Operation
+android.media.VolumeShaper$Operation$1
+android.media.VolumeShaper$Operation$Builder
+android.media.VolumeShaper$State
+android.media.VolumeShaper$State$1
+android.media.audiofx.AudioEffect
+android.media.audiofx.AudioEffect$Descriptor
+android.media.audiofx.LoudnessEnhancer
+android.media.audiofx.Virtualizer
+android.media.audiofx.Visualizer
+android.media.audiopolicy.AudioMix
+android.media.audiopolicy.AudioMixingRule
+android.media.audiopolicy.AudioMixingRule$AudioMixMatchCriterion
+android.media.audiopolicy.AudioPolicyConfig
+android.media.audiopolicy.IAudioPolicyCallback
+android.media.audiopolicy.IAudioPolicyCallback$Stub
+android.media.browse.MediaBrowser
+android.media.browse.MediaBrowser$1
+android.media.browse.MediaBrowser$2
+android.media.browse.MediaBrowser$6
+android.media.browse.MediaBrowser$ConnectionCallback
+android.media.browse.MediaBrowser$MediaServiceConnection
+android.media.browse.MediaBrowser$MediaServiceConnection$1
+android.media.browse.MediaBrowser$ServiceCallbacks
+android.media.midi.IMidiDeviceListener
+android.media.midi.IMidiDeviceOpenCallback
+android.media.midi.IMidiDeviceServer
+android.media.midi.IMidiManager
+android.media.midi.IMidiManager$Stub
+android.media.midi.MidiDeviceInfo
+android.media.midi.MidiDeviceStatus
+android.media.midi.MidiManager
+android.media.projection.IMediaProjection
+android.media.projection.IMediaProjectionManager
+android.media.projection.IMediaProjectionManager$Stub
+android.media.projection.IMediaProjectionManager$Stub$Proxy
+android.media.projection.IMediaProjectionWatcherCallback
+android.media.projection.IMediaProjectionWatcherCallback$Stub
+android.media.projection.IMediaProjectionWatcherCallback$Stub$Proxy
+android.media.projection.MediaProjectionInfo
+android.media.projection.MediaProjectionManager
+android.media.projection.MediaProjectionManager$Callback
+android.media.projection.MediaProjectionManager$CallbackDelegate
+android.media.session.IActiveSessionsListener
+android.media.session.IActiveSessionsListener$Stub
+android.media.session.IActiveSessionsListener$Stub$Proxy
+android.media.session.ICallback
+android.media.session.ICallback$Stub
+android.media.session.ICallback$Stub$Proxy
+android.media.session.IOnMediaKeyListener
+android.media.session.IOnVolumeKeyLongPressListener
+android.media.session.ISession
+android.media.session.ISession$Stub
+android.media.session.ISession$Stub$Proxy
+android.media.session.ISessionCallback
+android.media.session.ISessionCallback$Stub
+android.media.session.ISessionCallback$Stub$Proxy
+android.media.session.ISessionController
+android.media.session.ISessionController$Stub
+android.media.session.ISessionController$Stub$Proxy
+android.media.session.ISessionControllerCallback
+android.media.session.ISessionControllerCallback$Stub
+android.media.session.ISessionControllerCallback$Stub$Proxy
+android.media.session.ISessionManager
+android.media.session.ISessionManager$Stub
+android.media.session.ISessionManager$Stub$Proxy
+android.media.session.MediaController
+android.media.session.MediaController$Callback
+android.media.session.MediaController$CallbackStub
+android.media.session.MediaController$MessageHandler
+android.media.session.MediaController$PlaybackInfo
+android.media.session.MediaController$TransportControls
+android.media.session.MediaSession
+android.media.session.MediaSession$Callback
+android.media.session.MediaSession$CallbackMessageHandler
+android.media.session.MediaSession$CallbackStub
+android.media.session.MediaSession$QueueItem
+android.media.session.MediaSession$QueueItem$1
+android.media.session.MediaSession$Token
+android.media.session.MediaSession$Token$1
+android.media.session.MediaSessionManager
+android.media.session.MediaSessionManager$Callback
+android.media.session.MediaSessionManager$CallbackImpl
+android.media.session.MediaSessionManager$CallbackImpl$3
+android.media.session.MediaSessionManager$CallbackImpl$4
+android.media.session.MediaSessionManager$OnActiveSessionsChangedListener
+android.media.session.MediaSessionManager$SessionsChangedWrapper
+android.media.session.MediaSessionManager$SessionsChangedWrapper$1
+android.media.session.MediaSessionManager$SessionsChangedWrapper$1$1
+android.media.session.ParcelableVolumeInfo
+android.media.session.ParcelableVolumeInfo$1
+android.media.session.PlaybackState
+android.media.session.PlaybackState$1
+android.media.session.PlaybackState$Builder
+android.media.session.PlaybackState$CustomAction
+android.media.session.PlaybackState$CustomAction$1
+android.media.session.PlaybackState$CustomAction$Builder
+android.media.soundtrigger.SoundTriggerManager
+android.media.tv.TvInputHardwareInfo$Builder
+android.media.tv.TvInputManager
+android.media.tv.TvStreamConfig
+android.media.tv.TvStreamConfig$Builder
+android.metrics.LogMaker
+android.mtp.MtpDatabase
+android.mtp.MtpDevice
+android.mtp.MtpDeviceInfo
+android.mtp.MtpEvent
+android.mtp.MtpObjectInfo
+android.mtp.MtpPropertyGroup
+android.mtp.MtpPropertyList
+android.mtp.MtpServer
+android.mtp.MtpStorage
+android.mtp.MtpStorageInfo
+android.net.ConnectivityManager
+android.net.ConnectivityManager$CallbackHandler
+android.net.ConnectivityManager$NetworkCallback
+android.net.ConnectivityManager$OnNetworkActiveListener
+android.net.ConnectivityManager$PacketKeepaliveCallback
+android.net.ConnectivityMetricsEvent
+android.net.ConnectivityMetricsEvent$1
+android.net.ConnectivityThread
+android.net.ConnectivityThread$Singleton
+android.net.Credentials
+android.net.DataUsageRequest
+android.net.DhcpInfo
+android.net.DhcpInfo$1
+android.net.DhcpResults
+android.net.DhcpResults$1
+android.net.EthernetManager
+android.net.EthernetManager$1
+android.net.EthernetManager$2
+android.net.EventLogTags
+android.net.IConnectivityManager
+android.net.IConnectivityManager$Stub
+android.net.IConnectivityManager$Stub$Proxy
+android.net.IEthernetManager
+android.net.IEthernetManager$Stub
+android.net.IEthernetServiceListener
+android.net.IEthernetServiceListener$Stub
+android.net.IIpConnectivityMetrics
+android.net.IIpConnectivityMetrics$Stub
+android.net.IIpSecService
+android.net.IIpSecService$Stub
+android.net.INetd
+android.net.INetd$Stub
+android.net.INetd$Stub$Proxy
+android.net.INetdEventCallback
+android.net.INetworkManagementEventObserver
+android.net.INetworkManagementEventObserver$Stub
+android.net.INetworkPolicyListener
+android.net.INetworkPolicyListener$Stub
+android.net.INetworkPolicyListener$Stub$Proxy
+android.net.INetworkPolicyManager
+android.net.INetworkPolicyManager$Stub
+android.net.INetworkPolicyManager$Stub$Proxy
+android.net.INetworkRecommendationProvider
+android.net.INetworkRecommendationProvider$Stub
+android.net.INetworkRecommendationProvider$Stub$Proxy
+android.net.INetworkScoreCache
+android.net.INetworkScoreCache$Stub
+android.net.INetworkScoreCache$Stub$Proxy
+android.net.INetworkScoreService
+android.net.INetworkScoreService$Stub
+android.net.INetworkScoreService$Stub$Proxy
+android.net.INetworkStatsService
+android.net.INetworkStatsService$Stub
+android.net.INetworkStatsService$Stub$Proxy
+android.net.INetworkStatsSession
+android.net.InterfaceConfiguration
+android.net.InterfaceConfiguration$1
+android.net.IpConfiguration
+android.net.IpConfiguration$1
+android.net.IpConfiguration$IpAssignment
+android.net.IpConfiguration$ProxySettings
+android.net.IpPrefix
+android.net.IpPrefix$1
+android.net.IpSecConfig
+android.net.IpSecManager
+android.net.LinkAddress
+android.net.LinkAddress$1
+android.net.LinkProperties
+android.net.LinkProperties$1
+android.net.LinkProperties$CompareResult
+android.net.LinkProperties$ProvisioningChange
+android.net.LocalServerSocket
+android.net.LocalSocket
+android.net.LocalSocketAddress
+android.net.LocalSocketAddress$Namespace
+android.net.LocalSocketImpl
+android.net.LocalSocketImpl$SocketInputStream
+android.net.LocalSocketImpl$SocketOutputStream
+android.net.MatchAllNetworkSpecifier
+android.net.MatchAllNetworkSpecifier$1
+android.net.Network
+android.net.Network$1
+android.net.Network$2
+android.net.Network$NetworkBoundSocketFactory
+android.net.NetworkAgent
+android.net.NetworkCapabilities
+android.net.NetworkCapabilities$1
+android.net.NetworkConfig
+android.net.NetworkFactory
+android.net.NetworkFactory$NetworkRequestInfo
+android.net.NetworkIdentity
+android.net.NetworkInfo
+android.net.NetworkInfo$1
+android.net.NetworkInfo$DetailedState
+android.net.NetworkInfo$State
+android.net.NetworkKey
+android.net.NetworkKey$1
+android.net.NetworkMisc
+android.net.NetworkMisc$1
+android.net.NetworkPolicy
+android.net.NetworkPolicy$1
+android.net.NetworkPolicyManager
+android.net.NetworkQuotaInfo
+android.net.NetworkRecommendationProvider
+android.net.NetworkRecommendationProvider$ServiceWrapper
+android.net.NetworkRecommendationProvider$ServiceWrapper$1
+android.net.NetworkRequest
+android.net.NetworkRequest$1
+android.net.NetworkRequest$Builder
+android.net.NetworkRequest$Type
+android.net.NetworkScoreManager
+android.net.NetworkScorerAppData
+android.net.NetworkScorerAppData$1
+android.net.NetworkSpecifier
+android.net.NetworkState
+android.net.NetworkState$1
+android.net.NetworkStats
+android.net.NetworkStats$1
+android.net.NetworkStats$Entry
+android.net.NetworkStats$NonMonotonicObserver
+android.net.NetworkStatsHistory
+android.net.NetworkStatsHistory$1
+android.net.NetworkStatsHistory$DataStreamUtils
+android.net.NetworkStatsHistory$Entry
+android.net.NetworkTemplate
+android.net.NetworkTemplate$1
+android.net.NetworkUtils
+android.net.ParseException
+android.net.Proxy
+android.net.ProxyInfo
+android.net.ProxyInfo$1
+android.net.RouteInfo
+android.net.RouteInfo$1
+android.net.RssiCurve
+android.net.RssiCurve$1
+android.net.SSLCertificateSocketFactory
+android.net.SSLCertificateSocketFactory$1
+android.net.SSLSessionCache
+android.net.ScoredNetwork
+android.net.ScoredNetwork$1
+android.net.SntpClient
+android.net.StaticIpConfiguration
+android.net.StaticIpConfiguration$1
+android.net.StringNetworkSpecifier
+android.net.StringNetworkSpecifier$1
+android.net.TrafficStats
+android.net.UidRange
+android.net.Uri
+android.net.Uri$1
+android.net.Uri$AbstractHierarchicalUri
+android.net.Uri$AbstractPart
+android.net.Uri$Builder
+android.net.Uri$HierarchicalUri
+android.net.Uri$OpaqueUri
+android.net.Uri$Part
+android.net.Uri$Part$EmptyPart
+android.net.Uri$PathPart
+android.net.Uri$PathSegments
+android.net.Uri$PathSegmentsBuilder
+android.net.Uri$StringUri
+android.net.WebAddress
+android.net.WifiKey
+android.net.WifiKey$1
+android.net.http.AndroidHttpClient
+android.net.http.AndroidHttpClient$1
+android.net.http.AndroidHttpClient$2
+android.net.http.AndroidHttpClient$CurlLogger
+android.net.http.AndroidHttpClient$LoggingConfiguration
+android.net.http.HttpResponseCache
+android.net.http.SslCertificate
+android.net.http.X509TrustManagerExtensions
+android.net.metrics.ApfProgramEvent
+android.net.metrics.ApfProgramEvent$1
+android.net.metrics.ApfStats
+android.net.metrics.ApfStats$1
+android.net.metrics.ConnectStats
+android.net.metrics.DefaultNetworkEvent
+android.net.metrics.DefaultNetworkEvent$1
+android.net.metrics.DhcpClientEvent
+android.net.metrics.DhcpClientEvent$1
+android.net.metrics.DnsEvent
+android.net.metrics.IpConnectivityLog
+android.net.metrics.IpManagerEvent
+android.net.metrics.IpManagerEvent$1
+android.net.metrics.NetworkEvent
+android.net.metrics.NetworkEvent$1
+android.net.metrics.RaEvent
+android.net.metrics.RaEvent$1
+android.net.metrics.RaEvent$Builder
+android.net.metrics.ValidationProbeEvent
+android.net.metrics.ValidationProbeEvent$1
+android.net.metrics.ValidationProbeEvent$Decoder
+android.net.nsd.INsdManager
+android.net.nsd.INsdManager$Stub
+android.net.nsd.NsdManager
+android.net.sip.ISipService
+android.net.sip.ISipService$Stub
+android.net.sip.SipManager
+android.net.wifi.IRttManager
+android.net.wifi.IRttManager$Stub
+android.net.wifi.IWifiManager
+android.net.wifi.IWifiManager$Stub
+android.net.wifi.IWifiManager$Stub$Proxy
+android.net.wifi.IWifiScanner
+android.net.wifi.IWifiScanner$Stub
+android.net.wifi.IWifiScanner$Stub$Proxy
+android.net.wifi.ParcelUtil
+android.net.wifi.RttManager
+android.net.wifi.RttManager$RttCapabilities
+android.net.wifi.RttManager$RttListener
+android.net.wifi.RttManager$RttResult
+android.net.wifi.ScanResult
+android.net.wifi.ScanResult$1
+android.net.wifi.ScanResult$InformationElement
+android.net.wifi.ScanSettings
+android.net.wifi.SupplicantState
+android.net.wifi.SupplicantState$1
+android.net.wifi.WifiActivityEnergyInfo
+android.net.wifi.WifiActivityEnergyInfo$1
+android.net.wifi.WifiConfiguration
+android.net.wifi.WifiConfiguration$1
+android.net.wifi.WifiConfiguration$KeyMgmt
+android.net.wifi.WifiConfiguration$NetworkSelectionStatus
+android.net.wifi.WifiConfiguration$Visibility
+android.net.wifi.WifiConnectionStatistics
+android.net.wifi.WifiConnectionStatistics$1
+android.net.wifi.WifiEnterpriseConfig
+android.net.wifi.WifiEnterpriseConfig$1
+android.net.wifi.WifiInfo
+android.net.wifi.WifiInfo$1
+android.net.wifi.WifiLinkLayerStats
+android.net.wifi.WifiLinkLayerStats$1
+android.net.wifi.WifiManager
+android.net.wifi.WifiManager$ActionListener
+android.net.wifi.WifiManager$MulticastLock
+android.net.wifi.WifiManager$WifiLock
+android.net.wifi.WifiNetworkScoreCache
+android.net.wifi.WifiNetworkScoreCache$CacheListener
+android.net.wifi.WifiNetworkScoreCache$CacheListener$1
+android.net.wifi.WifiScanner
+android.net.wifi.WifiScanner$ActionListener
+android.net.wifi.WifiScanner$ChannelSpec
+android.net.wifi.WifiScanner$ParcelableScanData
+android.net.wifi.WifiScanner$ParcelableScanData$1
+android.net.wifi.WifiScanner$ParcelableScanResults
+android.net.wifi.WifiScanner$ParcelableScanResults$1
+android.net.wifi.WifiScanner$PnoScanListener
+android.net.wifi.WifiScanner$ScanData
+android.net.wifi.WifiScanner$ScanData$1
+android.net.wifi.WifiScanner$ScanListener
+android.net.wifi.WifiScanner$ScanSettings
+android.net.wifi.WifiScanner$ScanSettings$1
+android.net.wifi.WifiScanner$ScanSettings$HiddenNetwork
+android.net.wifi.WifiScanner$ServiceHandler
+android.net.wifi.WifiSsid
+android.net.wifi.WifiSsid$1
+android.net.wifi.WpsInfo
+android.net.wifi.WpsInfo$1
+android.net.wifi.aware.WifiAwareManager
+android.net.wifi.hotspot2.PasspointConfiguration
+android.net.wifi.p2p.IWifiP2pManager
+android.net.wifi.p2p.IWifiP2pManager$Stub
+android.net.wifi.p2p.WifiP2pConfig
+android.net.wifi.p2p.WifiP2pConfig$1
+android.net.wifi.p2p.WifiP2pDevice
+android.net.wifi.p2p.WifiP2pDevice$1
+android.net.wifi.p2p.WifiP2pDeviceList
+android.net.wifi.p2p.WifiP2pDeviceList$1
+android.net.wifi.p2p.WifiP2pGroup
+android.net.wifi.p2p.WifiP2pGroup$1
+android.net.wifi.p2p.WifiP2pGroupList
+android.net.wifi.p2p.WifiP2pGroupList$1
+android.net.wifi.p2p.WifiP2pGroupList$2
+android.net.wifi.p2p.WifiP2pGroupList$GroupDeleteListener
+android.net.wifi.p2p.WifiP2pInfo
+android.net.wifi.p2p.WifiP2pInfo$1
+android.net.wifi.p2p.WifiP2pManager
+android.net.wifi.p2p.WifiP2pWfdInfo
+android.net.wifi.p2p.WifiP2pWfdInfo$1
+android.nfc.BeamShareData
+android.nfc.FormatException
+android.nfc.IAppCallback
+android.nfc.IAppCallback$Stub
+android.nfc.IAppCallback$Stub$Proxy
+android.nfc.INfcAdapter
+android.nfc.INfcAdapter$Stub
+android.nfc.INfcAdapter$Stub$Proxy
+android.nfc.INfcAdapterExtras
+android.nfc.INfcCardEmulation
+android.nfc.INfcCardEmulation$Stub
+android.nfc.INfcCardEmulation$Stub$Proxy
+android.nfc.INfcFCardEmulation
+android.nfc.INfcFCardEmulation$Stub
+android.nfc.INfcFCardEmulation$Stub$Proxy
+android.nfc.INfcTag
+android.nfc.INfcTag$Stub
+android.nfc.INfcTag$Stub$Proxy
+android.nfc.INfcUnlockHandler
+android.nfc.ITagRemovedCallback
+android.nfc.NdefMessage
+android.nfc.NfcActivityManager
+android.nfc.NfcActivityManager$NfcActivityState
+android.nfc.NfcActivityManager$NfcApplicationState
+android.nfc.NfcAdapter
+android.nfc.NfcAdapter$1
+android.nfc.NfcAdapter$CreateBeamUrisCallback
+android.nfc.NfcAdapter$CreateNdefMessageCallback
+android.nfc.NfcAdapter$OnNdefPushCompleteCallback
+android.nfc.NfcEvent
+android.nfc.NfcManager
+android.nfc.Tag
+android.nfc.TechListParcel
+android.nfc.TransceiveResult
+android.nfc.cardemulation.AidGroup
+android.nfc.cardemulation.AidGroup$1
+android.nfc.cardemulation.ApduServiceInfo
+android.nfc.cardemulation.ApduServiceInfo$1
+android.nfc.cardemulation.CardEmulation
+android.nfc.cardemulation.HostApduService
+android.nfc.cardemulation.HostApduService$MsgHandler
+android.opengl.EGL14
+android.opengl.EGLConfig
+android.opengl.EGLContext
+android.opengl.EGLDisplay
+android.opengl.EGLExt
+android.opengl.EGLObjectHandle
+android.opengl.EGLSurface
+android.opengl.ETC1
+android.opengl.GLES10
+android.opengl.GLES10Ext
+android.opengl.GLES11
+android.opengl.GLES11Ext
+android.opengl.GLES20
+android.opengl.GLES30
+android.opengl.GLES31
+android.opengl.GLES31Ext
+android.opengl.GLES32
+android.opengl.GLUtils
+android.opengl.Matrix
+android.opengl.Visibility
+android.os.-$Lambda$-dncxFEc2F2bgG2fsIoC6FC6WNE
+android.os.-$Lambda$-dncxFEc2F2bgG2fsIoC6FC6WNE$1
+android.os.-$Lambda$6x30vPJhBKUfNY8tswxuZo3DCe0
+android.os.AsyncResult
+android.os.AsyncTask
+android.os.AsyncTask$1
+android.os.AsyncTask$2
+android.os.AsyncTask$3
+android.os.AsyncTask$AsyncTaskResult
+android.os.AsyncTask$InternalHandler
+android.os.AsyncTask$SerialExecutor
+android.os.AsyncTask$SerialExecutor$1
+android.os.AsyncTask$Status
+android.os.AsyncTask$WorkerRunnable
+android.os.BadParcelableException
+android.os.BaseBundle
+android.os.BaseBundle$NoImagePreloadHolder
+android.os.BatteryManager
+android.os.BatteryManagerInternal
+android.os.BatteryProperties
+android.os.BatteryProperties$1
+android.os.BatteryStats
+android.os.BatteryStats$BitDescription
+android.os.BatteryStats$ControllerActivityCounter
+android.os.BatteryStats$Counter
+android.os.BatteryStats$DailyItem
+android.os.BatteryStats$HistoryEventTracker
+android.os.BatteryStats$HistoryItem
+android.os.BatteryStats$HistoryStepDetails
+android.os.BatteryStats$HistoryTag
+android.os.BatteryStats$IntToString
+android.os.BatteryStats$LevelStepTracker
+android.os.BatteryStats$LongCounter
+android.os.BatteryStats$LongCounterArray
+android.os.BatteryStats$PackageChange
+android.os.BatteryStats$Timer
+android.os.BatteryStats$Uid
+android.os.BatteryStats$Uid$Pid
+android.os.BatteryStats$Uid$Pkg
+android.os.BatteryStats$Uid$Pkg$Serv
+android.os.BatteryStats$Uid$Sensor
+android.os.BatteryStats$Uid$Wakelock
+android.os.Binder
+android.os.BinderProxy
+android.os.Build
+android.os.Build$VERSION
+android.os.Bundle
+android.os.Bundle$1
+android.os.CancellationSignal
+android.os.CancellationSignal$OnCancelListener
+android.os.CancellationSignal$Transport
+android.os.CommonTimeConfig$OnServerDiedListener
+android.os.ConditionVariable
+android.os.CountDownTimer
+android.os.CpuUsageInfo
+android.os.CpuUsageInfo$1
+android.os.DeadObjectException
+android.os.DeadSystemException
+android.os.Debug
+android.os.Debug$MemoryInfo
+android.os.Debug$MemoryInfo$1
+android.os.DropBoxManager
+android.os.DropBoxManager$Entry
+android.os.DropBoxManager$Entry$1
+android.os.Environment
+android.os.Environment$UserEnvironment
+android.os.FactoryTest
+android.os.FileBridge
+android.os.FileBridge$FileBridgeOutputStream
+android.os.FileObserver$ObserverThread
+android.os.FileUtils
+android.os.GraphicsEnvironment
+android.os.Handler
+android.os.Handler$BlockingRunnable
+android.os.Handler$Callback
+android.os.Handler$MessengerImpl
+android.os.HandlerThread
+android.os.HardwarePropertiesManager
+android.os.HwBinder
+android.os.HwBlob
+android.os.HwParcel
+android.os.HwRemoteBinder
+android.os.IBatteryPropertiesListener
+android.os.IBatteryPropertiesListener$Stub
+android.os.IBatteryPropertiesRegistrar
+android.os.IBatteryPropertiesRegistrar$Stub
+android.os.IBatteryPropertiesRegistrar$Stub$Proxy
+android.os.IBinder
+android.os.IBinder$DeathRecipient
+android.os.ICancellationSignal
+android.os.ICancellationSignal$Stub
+android.os.ICancellationSignal$Stub$Proxy
+android.os.IDeviceIdentifiersPolicyService
+android.os.IDeviceIdentifiersPolicyService$Stub
+android.os.IDeviceIdleController
+android.os.IDeviceIdleController$Stub
+android.os.IDeviceIdleController$Stub$Proxy
+android.os.IHardwarePropertiesManager
+android.os.IHardwarePropertiesManager$Stub
+android.os.IHardwarePropertiesManager$Stub$Proxy
+android.os.IHwBinder
+android.os.IHwBinder$DeathRecipient
+android.os.IHwInterface
+android.os.IIncidentManager
+android.os.IIncidentManager$Stub
+android.os.IInstalld
+android.os.IInstalld$Stub
+android.os.IInstalld$Stub$Proxy
+android.os.IInterface
+android.os.IMaintenanceActivityListener
+android.os.IMessenger
+android.os.IMessenger$Stub
+android.os.IMessenger$Stub$Proxy
+android.os.INetworkActivityListener
+android.os.INetworkManagementService
+android.os.INetworkManagementService$Stub
+android.os.INetworkManagementService$Stub$Proxy
+android.os.IPermissionController
+android.os.IPermissionController$Stub
+android.os.IPowerManager
+android.os.IPowerManager$Stub
+android.os.IPowerManager$Stub$Proxy
+android.os.IProcessInfoService
+android.os.IProcessInfoService$Stub
+android.os.IProgressListener
+android.os.IRecoverySystem
+android.os.IRecoverySystem$Stub
+android.os.IRecoverySystemProgressListener
+android.os.IRemoteCallback
+android.os.IRemoteCallback$Stub
+android.os.IRemoteCallback$Stub$Proxy
+android.os.ISchedulingPolicyService
+android.os.ISchedulingPolicyService$Stub
+android.os.IServiceManager
+android.os.IUpdateLock
+android.os.IUpdateLock$Stub
+android.os.IUserManager
+android.os.IUserManager$Stub
+android.os.IUserManager$Stub$Proxy
+android.os.IVibratorService
+android.os.IVibratorService$Stub
+android.os.IVibratorService$Stub$Proxy
+android.os.IncidentManager
+android.os.LocaleList
+android.os.LocaleList$1
+android.os.Looper
+android.os.MemoryFile
+android.os.Message
+android.os.Message$1
+android.os.MessageQueue
+android.os.MessageQueue$FileDescriptorRecord
+android.os.MessageQueue$IdleHandler
+android.os.MessageQueue$OnFileDescriptorEventListener
+android.os.Messenger
+android.os.Messenger$1
+android.os.OperationCanceledException
+android.os.Parcel
+android.os.Parcel$1
+android.os.Parcel$2
+android.os.ParcelFileDescriptor
+android.os.ParcelFileDescriptor$1
+android.os.ParcelFileDescriptor$2
+android.os.ParcelFileDescriptor$AutoCloseInputStream
+android.os.ParcelFileDescriptor$AutoCloseOutputStream
+android.os.ParcelFileDescriptor$OnCloseListener
+android.os.ParcelFileDescriptor$Status
+android.os.ParcelFormatException
+android.os.ParcelUuid
+android.os.ParcelUuid$1
+android.os.Parcelable
+android.os.Parcelable$ClassLoaderCreator
+android.os.Parcelable$Creator
+android.os.ParcelableException
+android.os.ParcelableParcel
+android.os.ParcelableParcel$1
+android.os.PatternMatcher
+android.os.PatternMatcher$1
+android.os.PersistableBundle
+android.os.PersistableBundle$1
+android.os.PersistableBundle$MyReadMapCallback
+android.os.PooledStringReader
+android.os.PooledStringWriter
+android.os.PowerManager
+android.os.PowerManager$WakeLock
+android.os.PowerManager$WakeLock$1
+android.os.PowerManagerInternal
+android.os.PowerManagerInternal$LowPowerModeListener
+android.os.PowerSaveState
+android.os.PowerSaveState$1
+android.os.PowerSaveState$Builder
+android.os.Process
+android.os.Process$ProcessStartResult
+android.os.RecoverySystem
+android.os.RecoverySystem$ProgressListener
+android.os.Registrant
+android.os.RegistrantList
+android.os.RemoteCallback
+android.os.RemoteCallback$1
+android.os.RemoteCallback$2
+android.os.RemoteCallback$OnResultListener
+android.os.RemoteCallbackList
+android.os.RemoteCallbackList$Callback
+android.os.RemoteException
+android.os.ResultReceiver
+android.os.ResultReceiver$1
+android.os.ResultReceiver$MyResultReceiver
+android.os.ResultReceiver$MyRunnable
+android.os.SELinux
+android.os.Seccomp
+android.os.ServiceManager
+android.os.ServiceManager$ServiceNotFoundException
+android.os.ServiceManagerNative
+android.os.ServiceManagerProxy
+android.os.ServiceSpecificException
+android.os.ShellCallback
+android.os.StatFs
+android.os.StrictMode
+android.os.StrictMode$1
+android.os.StrictMode$2
+android.os.StrictMode$3
+android.os.StrictMode$4
+android.os.StrictMode$5
+android.os.StrictMode$6
+android.os.StrictMode$7
+android.os.StrictMode$8
+android.os.StrictMode$9
+android.os.StrictMode$AndroidBlockGuardPolicy
+android.os.StrictMode$AndroidBlockGuardPolicy$1
+android.os.StrictMode$AndroidCloseGuardReporter
+android.os.StrictMode$InstanceCountViolation
+android.os.StrictMode$InstanceTracker
+android.os.StrictMode$LogStackTrace
+android.os.StrictMode$Span
+android.os.StrictMode$StrictModeCustomViolation
+android.os.StrictMode$StrictModeDiskReadViolation
+android.os.StrictMode$StrictModeDiskWriteViolation
+android.os.StrictMode$StrictModeViolation
+android.os.StrictMode$ThreadPolicy
+android.os.StrictMode$ThreadPolicy$Builder
+android.os.StrictMode$ThreadSpanState
+android.os.StrictMode$ViolationInfo
+android.os.StrictMode$ViolationInfo$1
+android.os.StrictMode$VmPolicy
+android.os.StrictMode$VmPolicy$Builder
+android.os.SynchronousResultReceiver
+android.os.SynchronousResultReceiver$Result
+android.os.SystemClock
+android.os.SystemProperties
+android.os.SystemService
+android.os.SystemService$1
+android.os.SystemService$State
+android.os.SystemVibrator
+android.os.TokenWatcher
+android.os.TokenWatcher$1
+android.os.Trace
+android.os.Trace$1
+android.os.TransactionTooLargeException
+android.os.UEventObserver
+android.os.UEventObserver$UEvent
+android.os.UEventObserver$UEventThread
+android.os.UpdateLock
+android.os.UserHandle
+android.os.UserHandle$1
+android.os.UserManager
+android.os.UserManager$EnforcingUser
+android.os.UserManager$EnforcingUser$1
+android.os.UserManagerInternal
+android.os.UserManagerInternal$UserRestrictionsListener
+android.os.VibrationEffect
+android.os.VibrationEffect$1
+android.os.VibrationEffect$OneShot
+android.os.VibrationEffect$Prebaked
+android.os.VibrationEffect$Prebaked$1
+android.os.VibrationEffect$Waveform
+android.os.VibrationEffect$Waveform$1
+android.os.Vibrator
+android.os.VintfObject
+android.os.VintfRuntimeInfo
+android.os.WorkSource
+android.os.WorkSource$1
+android.os.ZygoteProcess
+android.os.ZygoteProcess$ZygoteState
+android.os.ZygoteStartFailedEx
+android.os.health.HealthStatsParceler
+android.os.health.SystemHealthManager
+android.os.storage.DiskInfo
+android.os.storage.DiskInfo$1
+android.os.storage.IObbActionListener
+android.os.storage.IObbActionListener$Stub
+android.os.storage.IStorageEventListener
+android.os.storage.IStorageEventListener$Stub
+android.os.storage.IStorageEventListener$Stub$Proxy
+android.os.storage.IStorageManager
+android.os.storage.IStorageManager$Stub
+android.os.storage.IStorageManager$Stub$Proxy
+android.os.storage.IStorageShutdownObserver
+android.os.storage.StorageEventListener
+android.os.storage.StorageManager
+android.os.storage.StorageManager$ObbActionListener
+android.os.storage.StorageManager$StorageEventListenerDelegate
+android.os.storage.StorageManagerInternal
+android.os.storage.StorageManagerInternal$ExternalStorageMountPolicy
+android.os.storage.StorageVolume
+android.os.storage.StorageVolume$1
+android.os.storage.VolumeInfo
+android.os.storage.VolumeInfo$1
+android.os.storage.VolumeInfo$2
+android.os.storage.VolumeRecord
+android.os.storage.VolumeRecord$1
+android.preference.GenericInflater$Parent
+android.preference.Preference
+android.preference.Preference$BaseSavedState
+android.preference.Preference$BaseSavedState$1
+android.preference.Preference$OnPreferenceChangeListener
+android.preference.PreferenceActivity
+android.preference.PreferenceFragment
+android.preference.PreferenceFragment$OnPreferenceStartFragmentCallback
+android.preference.PreferenceGroup
+android.preference.PreferenceManager
+android.preference.PreferenceManager$OnPreferenceTreeClickListener
+android.preference.PreferenceScreen
+android.print.IPrintDocumentAdapter
+android.print.IPrintJobStateChangeListener
+android.print.IPrintManager
+android.print.IPrintManager$Stub
+android.print.IPrintServicesChangeListener
+android.print.IPrintSpooler
+android.print.IPrintSpooler$Stub
+android.print.IPrintSpooler$Stub$Proxy
+android.print.IPrintSpoolerCallbacks
+android.print.IPrintSpoolerCallbacks$Stub
+android.print.IPrintSpoolerClient
+android.print.IPrintSpoolerClient$Stub
+android.print.IPrinterDiscoveryObserver
+android.print.PageRange
+android.print.PrintAttributes
+android.print.PrintDocumentAdapter
+android.print.PrintDocumentAdapter$LayoutResultCallback
+android.print.PrintDocumentAdapter$WriteResultCallback
+android.print.PrintJobId
+android.print.PrintJobInfo
+android.print.PrintManager
+android.print.PrinterId
+android.printservice.IPrintServiceClient
+android.printservice.IPrintServiceClient$Stub
+android.printservice.PrintServiceInfo
+android.printservice.PrintServiceInfo$1
+android.printservice.recommendation.IRecommendationsChangeListener
+android.provider.-$Lambda$87WmhkvObehVg0OMBzwa_MTVV8g
+android.provider.-$Lambda$a7Jyr6j_Mb70hHJ2ssL1AAhKh4c
+android.provider.BaseColumns
+android.provider.BlockedNumberContract
+android.provider.BlockedNumberContract$BlockedNumbers
+android.provider.CalendarContract
+android.provider.CalendarContract$Attendees
+android.provider.CalendarContract$AttendeesColumns
+android.provider.CalendarContract$CalendarAlerts
+android.provider.CalendarContract$CalendarAlertsColumns
+android.provider.CalendarContract$CalendarCache
+android.provider.CalendarContract$CalendarCacheColumns
+android.provider.CalendarContract$CalendarColumns
+android.provider.CalendarContract$CalendarSyncColumns
+android.provider.CalendarContract$Calendars
+android.provider.CalendarContract$Colors
+android.provider.CalendarContract$ColorsColumns
+android.provider.CalendarContract$Events
+android.provider.CalendarContract$EventsColumns
+android.provider.CalendarContract$ExtendedProperties
+android.provider.CalendarContract$ExtendedPropertiesColumns
+android.provider.CalendarContract$Instances
+android.provider.CalendarContract$Reminders
+android.provider.CalendarContract$RemindersColumns
+android.provider.CalendarContract$SyncColumns
+android.provider.CallLog
+android.provider.CallLog$Calls
+android.provider.ContactsContract
+android.provider.ContactsContract$BaseSyncColumns
+android.provider.ContactsContract$CommonDataKinds$BaseTypes
+android.provider.ContactsContract$CommonDataKinds$Callable
+android.provider.ContactsContract$CommonDataKinds$CommonColumns
+android.provider.ContactsContract$CommonDataKinds$Email
+android.provider.ContactsContract$CommonDataKinds$Event
+android.provider.ContactsContract$CommonDataKinds$Im
+android.provider.ContactsContract$CommonDataKinds$Phone
+android.provider.ContactsContract$CommonDataKinds$Relation
+android.provider.ContactsContract$CommonDataKinds$StructuredPostal
+android.provider.ContactsContract$ContactCounts
+android.provider.ContactsContract$ContactNameColumns
+android.provider.ContactsContract$ContactOptionsColumns
+android.provider.ContactsContract$ContactStatusColumns
+android.provider.ContactsContract$Contacts
+android.provider.ContactsContract$ContactsColumns
+android.provider.ContactsContract$Data
+android.provider.ContactsContract$DataColumns
+android.provider.ContactsContract$DataColumnsWithJoins
+android.provider.ContactsContract$DataUsageFeedback
+android.provider.ContactsContract$DataUsageStatColumns
+android.provider.ContactsContract$DeletedContacts
+android.provider.ContactsContract$DeletedContactsColumns
+android.provider.ContactsContract$Directory
+android.provider.ContactsContract$DisplayPhoto
+android.provider.ContactsContract$Groups
+android.provider.ContactsContract$GroupsColumns
+android.provider.ContactsContract$MetadataSync
+android.provider.ContactsContract$MetadataSyncColumns
+android.provider.ContactsContract$PhoneLookup
+android.provider.ContactsContract$PhoneLookupColumns
+android.provider.ContactsContract$Profile
+android.provider.ContactsContract$ProviderStatus
+android.provider.ContactsContract$RawContacts
+android.provider.ContactsContract$RawContactsColumns
+android.provider.ContactsContract$RawContactsEntity
+android.provider.ContactsContract$StatusColumns
+android.provider.ContactsContract$SyncColumns
+android.provider.DocumentsContract
+android.provider.DocumentsContract$Path
+android.provider.DocumentsProvider
+android.provider.Downloads
+android.provider.Downloads$Impl
+android.provider.FontsContract
+android.provider.FontsContract$1
+android.provider.MediaStore$Audio
+android.provider.MediaStore$Audio$AlbumColumns
+android.provider.MediaStore$Audio$Albums
+android.provider.MediaStore$Audio$AudioColumns
+android.provider.MediaStore$Audio$Media
+android.provider.MediaStore$Audio$Playlists
+android.provider.MediaStore$Audio$PlaylistsColumns
+android.provider.MediaStore$Files
+android.provider.MediaStore$Images$ImageColumns
+android.provider.MediaStore$Images$Media
+android.provider.MediaStore$Images$Thumbnails
+android.provider.MediaStore$MediaColumns
+android.provider.MediaStore$Video$Media
+android.provider.MediaStore$Video$VideoColumns
+android.provider.OpenableColumns
+android.provider.SearchIndexableData
+android.provider.SearchIndexableResource
+android.provider.SearchIndexablesProvider
+android.provider.SearchRecentSuggestions
+android.provider.Settings
+android.provider.Settings$ContentProviderHolder
+android.provider.Settings$GenerationTracker
+android.provider.Settings$Global
+android.provider.Settings$NameValueCache
+android.provider.Settings$NameValueTable
+android.provider.Settings$Secure
+android.provider.Settings$SettingNotFoundException
+android.provider.Settings$System
+android.provider.Settings$System$1
+android.provider.Settings$System$2
+android.provider.Settings$System$3
+android.provider.Settings$System$4
+android.provider.Settings$System$5
+android.provider.Settings$System$6
+android.provider.Settings$System$7
+android.provider.Settings$System$8
+android.provider.Settings$System$9
+android.provider.Settings$System$DiscreteValueValidator
+android.provider.Settings$System$InclusiveFloatRangeValidator
+android.provider.Settings$System$InclusiveIntegerRangeValidator
+android.provider.Settings$System$Validator
+android.provider.SyncStateContract$Columns
+android.provider.Telephony$BaseMmsColumns
+android.provider.Telephony$Carriers
+android.provider.Telephony$Mms
+android.provider.Telephony$MmsSms
+android.provider.Telephony$ServiceStateTable
+android.provider.Telephony$Sms
+android.provider.Telephony$TextBasedSmsColumns
+android.provider.Telephony$Threads
+android.provider.Telephony$ThreadsColumns
+android.provider.UserDictionary$Words
+android.provider.VoicemailContract$Status
+android.provider.VoicemailContract$Voicemails
+android.renderscript.Allocation
+android.renderscript.BaseObj
+android.renderscript.Matrix4f
+android.renderscript.RenderScriptCacheDir
+android.security.GateKeeper
+android.security.IKeyChainService
+android.security.IKeyChainService$Stub
+android.security.IKeyChainService$Stub$Proxy
+android.security.IKeystoreService
+android.security.IKeystoreService$Stub
+android.security.IKeystoreService$Stub$Proxy
+android.security.KeyChain
+android.security.KeyChain$1
+android.security.KeyChain$KeyChainConnection
+android.security.KeyStore
+android.security.NetworkSecurityPolicy
+android.security.keymaster.IKeyAttestationApplicationIdProvider
+android.security.keymaster.IKeyAttestationApplicationIdProvider$Stub
+android.security.keymaster.KeyAttestationApplicationId
+android.security.keymaster.KeymasterArguments
+android.security.keymaster.KeymasterArguments$1
+android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
+android.security.keystore.AndroidKeyStoreKeyGeneratorSpi
+android.security.keystore.AndroidKeyStoreKeyGeneratorSpi$AES
+android.security.keystore.AndroidKeyStoreProvider
+android.security.keystore.AndroidKeyStoreSpi
+android.security.keystore.ArrayUtils
+android.security.keystore.KeyGenParameterSpec
+android.security.keystore.KeyGenParameterSpec$Builder
+android.security.keystore.KeyInfo
+android.security.keystore.KeyPermanentlyInvalidatedException
+android.security.keystore.KeyProperties
+android.security.keystore.KeyProperties$BlockMode
+android.security.keystore.KeyProperties$EncryptionPadding
+android.security.keystore.KeyProperties$Purpose
+android.security.keystore.KeymasterUtils
+android.security.keystore.UserNotAuthenticatedException
+android.security.keystore.Utils
+android.security.net.config.ApplicationConfig
+android.security.net.config.CertificateSource
+android.security.net.config.CertificatesEntryRef
+android.security.net.config.ConfigNetworkSecurityPolicy
+android.security.net.config.ConfigSource
+android.security.net.config.DirectoryCertificateSource
+android.security.net.config.DirectoryCertificateSource$1
+android.security.net.config.DirectoryCertificateSource$3
+android.security.net.config.DirectoryCertificateSource$CertSelector
+android.security.net.config.KeyStoreCertificateSource
+android.security.net.config.KeyStoreConfigSource
+android.security.net.config.ManifestConfigSource
+android.security.net.config.ManifestConfigSource$DefaultConfigSource
+android.security.net.config.NetworkSecurityConfig
+android.security.net.config.NetworkSecurityConfig$1
+android.security.net.config.NetworkSecurityConfig$Builder
+android.security.net.config.NetworkSecurityConfigProvider
+android.security.net.config.NetworkSecurityTrustManager
+android.security.net.config.PinSet
+android.security.net.config.RootTrustManager
+android.security.net.config.RootTrustManagerFactorySpi
+android.security.net.config.SystemCertificateSource
+android.security.net.config.TrustedCertificateStoreAdapter
+android.security.net.config.UserCertificateSource
+android.security.net.config.XmlConfigSource
+android.security.net.config.XmlConfigSource$ParserException
+android.service.autofill.-$Lambda$svbjmB3NFhHnuZrn67G14PFSJlY
+android.service.autofill.AutofillService
+android.service.autofill.AutofillService$1
+android.service.autofill.AutofillServiceInfo
+android.service.autofill.FillCallback
+android.service.autofill.FillContext
+android.service.autofill.FillContext$1
+android.service.autofill.FillEventHistory
+android.service.autofill.FillRequest
+android.service.autofill.FillRequest$1
+android.service.autofill.FillResponse
+android.service.autofill.IAutoFillService
+android.service.autofill.IAutoFillService$Stub
+android.service.autofill.IAutoFillService$Stub$Proxy
+android.service.autofill.IFillCallback
+android.service.autofill.IFillCallback$Stub
+android.service.autofill.IFillCallback$Stub$Proxy
+android.service.autofill.SaveCallback
+android.service.autofill.SaveRequest
+android.service.carrier.CarrierIdentifier
+android.service.carrier.CarrierIdentifier$1
+android.service.carrier.ICarrierService
+android.service.carrier.ICarrierService$Stub
+android.service.carrier.ICarrierService$Stub$Proxy
+android.service.dreams.DreamManagerInternal
+android.service.dreams.IDreamManager
+android.service.dreams.IDreamManager$Stub
+android.service.dreams.IDreamManager$Stub$Proxy
+android.service.gatekeeper.IGateKeeperService
+android.service.gatekeeper.IGateKeeperService$Stub
+android.service.gatekeeper.IGateKeeperService$Stub$Proxy
+android.service.media.IMediaBrowserService
+android.service.media.IMediaBrowserService$Stub
+android.service.media.IMediaBrowserService$Stub$Proxy
+android.service.media.IMediaBrowserServiceCallbacks
+android.service.media.IMediaBrowserServiceCallbacks$Stub
+android.service.notification.Adjustment
+android.service.notification.Condition
+android.service.notification.Condition$1
+android.service.notification.ConditionProviderService
+android.service.notification.ConditionProviderService$H
+android.service.notification.ConditionProviderService$Provider
+android.service.notification.IConditionListener
+android.service.notification.IConditionListener$Stub
+android.service.notification.IConditionProvider
+android.service.notification.IConditionProvider$Stub
+android.service.notification.INotificationListener
+android.service.notification.INotificationListener$Stub
+android.service.notification.INotificationListener$Stub$Proxy
+android.service.notification.IStatusBarNotificationHolder
+android.service.notification.IStatusBarNotificationHolder$Stub
+android.service.notification.IStatusBarNotificationHolder$Stub$Proxy
+android.service.notification.NotificationListenerService
+android.service.notification.NotificationListenerService$MyHandler
+android.service.notification.NotificationListenerService$NotificationListenerWrapper
+android.service.notification.NotificationListenerService$Ranking
+android.service.notification.NotificationListenerService$RankingMap
+android.service.notification.NotificationListenerService$RankingMap$1
+android.service.notification.NotificationRankingUpdate
+android.service.notification.NotificationRankingUpdate$1
+android.service.notification.StatusBarNotification
+android.service.notification.StatusBarNotification$1
+android.service.notification.ZenModeConfig
+android.service.notification.ZenModeConfig$1
+android.service.notification.ZenModeConfig$Diff
+android.service.notification.ZenModeConfig$EventInfo
+android.service.notification.ZenModeConfig$ScheduleInfo
+android.service.notification.ZenModeConfig$ZenRule
+android.service.notification.ZenModeConfig$ZenRule$1
+android.service.oemlock.IOemLockService
+android.service.oemlock.IOemLockService$Stub
+android.service.oemlock.OemLockManager
+android.service.persistentdata.IPersistentDataBlockService
+android.service.persistentdata.IPersistentDataBlockService$Stub
+android.service.persistentdata.IPersistentDataBlockService$Stub$Proxy
+android.service.persistentdata.PersistentDataBlockManager
+android.service.quicksettings.IQSService
+android.service.quicksettings.IQSService$Stub
+android.service.quicksettings.Tile
+android.service.textservice.SpellCheckerService
+android.service.textservice.SpellCheckerService$InternalISpellCheckerSession
+android.service.textservice.SpellCheckerService$Session
+android.service.textservice.SpellCheckerService$SpellCheckerServiceBinder
+android.service.voice.AlwaysOnHotwordDetector
+android.service.voice.AlwaysOnHotwordDetector$Callback
+android.service.voice.AlwaysOnHotwordDetector$EventPayload
+android.service.voice.AlwaysOnHotwordDetector$MyHandler
+android.service.voice.AlwaysOnHotwordDetector$RefreshAvailabiltyTask
+android.service.voice.AlwaysOnHotwordDetector$SoundTriggerListener
+android.service.voice.IVoiceInteractionService
+android.service.voice.IVoiceInteractionService$Stub
+android.service.voice.IVoiceInteractionService$Stub$Proxy
+android.service.voice.IVoiceInteractionSession
+android.service.voice.VoiceInteractionManagerInternal
+android.service.voice.VoiceInteractionService
+android.service.voice.VoiceInteractionService$1
+android.service.voice.VoiceInteractionService$MyHandler
+android.service.voice.VoiceInteractionServiceInfo
+android.service.vr.IPersistentVrStateCallbacks
+android.service.vr.IPersistentVrStateCallbacks$Stub
+android.service.vr.IVrManager
+android.service.vr.IVrManager$Stub
+android.service.vr.IVrManager$Stub$Proxy
+android.service.vr.IVrStateCallbacks
+android.service.vr.IVrStateCallbacks$Stub
+android.service.vr.IVrStateCallbacks$Stub$Proxy
+android.service.wallpaper.IWallpaperConnection
+android.service.wallpaper.IWallpaperConnection$Stub
+android.service.wallpaper.IWallpaperConnection$Stub$Proxy
+android.service.wallpaper.IWallpaperEngine
+android.service.wallpaper.IWallpaperEngine$Stub
+android.service.wallpaper.IWallpaperEngine$Stub$Proxy
+android.service.wallpaper.IWallpaperService
+android.service.wallpaper.IWallpaperService$Stub
+android.service.wallpaper.IWallpaperService$Stub$Proxy
+android.service.wallpaper.WallpaperService
+android.service.wallpaper.WallpaperService$Engine
+android.service.wallpaper.WallpaperService$Engine$1
+android.service.wallpaper.WallpaperService$Engine$2
+android.service.wallpaper.WallpaperService$Engine$3
+android.service.wallpaper.WallpaperService$Engine$WallpaperInputEventReceiver
+android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper
+android.service.wallpaper.WallpaperService$IWallpaperServiceWrapper
+android.service.wallpaper.WallpaperService$WallpaperCommand
+android.speech.SpeechRecognizer
+android.speech.tts.AbstractEventLogger
+android.speech.tts.AbstractSynthesisCallback
+android.speech.tts.AudioPlaybackHandler
+android.speech.tts.AudioPlaybackHandler$MessageLoop
+android.speech.tts.EventLogger
+android.speech.tts.FileSynthesisCallback
+android.speech.tts.ITextToSpeechCallback
+android.speech.tts.ITextToSpeechCallback$Stub
+android.speech.tts.ITextToSpeechCallback$Stub$Proxy
+android.speech.tts.ITextToSpeechService
+android.speech.tts.ITextToSpeechService$Stub
+android.speech.tts.ITextToSpeechService$Stub$Proxy
+android.speech.tts.SynthesisCallback
+android.speech.tts.SynthesisRequest
+android.speech.tts.TextToSpeech
+android.speech.tts.TextToSpeech$10
+android.speech.tts.TextToSpeech$16
+android.speech.tts.TextToSpeech$17
+android.speech.tts.TextToSpeech$7
+android.speech.tts.TextToSpeech$Action
+android.speech.tts.TextToSpeech$Connection
+android.speech.tts.TextToSpeech$Connection$1
+android.speech.tts.TextToSpeech$Connection$SetupConnectionAsyncTask
+android.speech.tts.TextToSpeech$EngineInfo
+android.speech.tts.TextToSpeech$OnInitListener
+android.speech.tts.TextToSpeechService
+android.speech.tts.TextToSpeechService$1
+android.speech.tts.TextToSpeechService$CallbackMap
+android.speech.tts.TextToSpeechService$SpeechItem
+android.speech.tts.TextToSpeechService$SynthHandler
+android.speech.tts.TextToSpeechService$SynthHandler$1
+android.speech.tts.TextToSpeechService$SynthHandler$2
+android.speech.tts.TextToSpeechService$SynthThread
+android.speech.tts.TextToSpeechService$SynthesisSpeechItem
+android.speech.tts.TextToSpeechService$SynthesisToFileOutputStreamSpeechItem
+android.speech.tts.TextToSpeechService$UtteranceProgressDispatcher
+android.speech.tts.TextToSpeechService$UtteranceSpeechItem
+android.speech.tts.TextToSpeechService$UtteranceSpeechItemWithParams
+android.speech.tts.TtsEngines
+android.speech.tts.TtsEngines$EngineInfoComparator
+android.speech.tts.UtteranceProgressListener
+android.system.ErrnoException
+android.system.GaiException
+android.system.NetlinkSocketAddress
+android.system.Os
+android.system.OsConstants
+android.system.PacketSocketAddress
+android.system.StructAddrinfo
+android.system.StructFlock
+android.system.StructGroupReq
+android.system.StructIcmpHdr
+android.system.StructIfaddrs
+android.system.StructLinger
+android.system.StructPasswd
+android.system.StructPollfd
+android.system.StructStat
+android.system.StructStatVfs
+android.system.StructTimeval
+android.system.StructUcred
+android.system.StructUtsname
+android.system.UnixSocketAddress
+android.telecom.-$Lambda$afyb_ODGzn3xMew6fjs8ANSIdVo
+android.telecom.CallAudioState
+android.telecom.CallAudioState$1
+android.telecom.Conference
+android.telecom.Conference$Listener
+android.telecom.Conferenceable
+android.telecom.Connection
+android.telecom.Connection$1
+android.telecom.Connection$2
+android.telecom.Connection$FailureSignalingConnection
+android.telecom.Connection$Listener
+android.telecom.ConnectionRequest
+android.telecom.ConnectionRequest$1
+android.telecom.ConnectionRequest$Builder
+android.telecom.ConnectionService
+android.telecom.ConnectionService$1
+android.telecom.ConnectionService$2
+android.telecom.ConnectionService$2$1
+android.telecom.ConnectionService$3
+android.telecom.ConnectionService$4
+android.telecom.ConnectionService$5
+android.telecom.ConnectionService$5$1
+android.telecom.ConnectionServiceAdapter
+android.telecom.DefaultDialerManager
+android.telecom.DisconnectCause
+android.telecom.DisconnectCause$1
+android.telecom.Log
+android.telecom.Log$1
+android.telecom.Logging.-$Lambda$OwO3BlCgqcOx28O1BaOAPVPor24
+android.telecom.Logging.-$Lambda$OwO3BlCgqcOx28O1BaOAPVPor24$1
+android.telecom.Logging.-$Lambda$OwO3BlCgqcOx28O1BaOAPVPor24$2
+android.telecom.Logging.EventManager
+android.telecom.Logging.EventManager$Event
+android.telecom.Logging.EventManager$EventListener
+android.telecom.Logging.EventManager$EventRecord
+android.telecom.Logging.EventManager$Loggable
+android.telecom.Logging.EventManager$TimedEventPair
+android.telecom.Logging.Runnable
+android.telecom.Logging.Runnable$1
+android.telecom.Logging.Session
+android.telecom.Logging.Session$Info
+android.telecom.Logging.Session$Info$1
+android.telecom.Logging.SessionManager
+android.telecom.Logging.SessionManager$ICurrentThreadId
+android.telecom.Logging.SessionManager$ISessionCleanupTimeoutMs
+android.telecom.Logging.SessionManager$ISessionIdQueryHandler
+android.telecom.Logging.SessionManager$ISessionListener
+android.telecom.ParcelableCall
+android.telecom.ParcelableCall$1
+android.telecom.ParcelableConference
+android.telecom.ParcelableConnection
+android.telecom.ParcelableConnection$1
+android.telecom.PhoneAccount
+android.telecom.PhoneAccount$1
+android.telecom.PhoneAccount$Builder
+android.telecom.PhoneAccountHandle
+android.telecom.PhoneAccountHandle$1
+android.telecom.RemoteConnectionManager
+android.telecom.StatusHints
+android.telecom.TelecomAnalytics
+android.telecom.TelecomManager
+android.telecom.VideoProfile
+android.telecom.VideoProfile$1
+android.telephony.CarrierConfigManager
+android.telephony.CellIdentityWcdma
+android.telephony.CellIdentityWcdma$1
+android.telephony.CellInfo
+android.telephony.CellInfo$1
+android.telephony.CellInfoCdma
+android.telephony.CellInfoGsm
+android.telephony.CellInfoLte
+android.telephony.CellInfoWcdma
+android.telephony.CellInfoWcdma$1
+android.telephony.CellLocation
+android.telephony.CellSignalStrength
+android.telephony.CellSignalStrengthWcdma
+android.telephony.CellSignalStrengthWcdma$1
+android.telephony.ClientRequestStats
+android.telephony.ClientRequestStats$1
+android.telephony.DisconnectCause
+android.telephony.IccOpenLogicalChannelResponse
+android.telephony.ModemActivityInfo
+android.telephony.PhoneNumberFormattingTextWatcher
+android.telephony.PhoneNumberUtils
+android.telephony.PhoneStateListener
+android.telephony.PhoneStateListener$1
+android.telephony.PhoneStateListener$IPhoneStateListenerStub
+android.telephony.PreciseCallState
+android.telephony.PreciseCallState$1
+android.telephony.PreciseDataConnectionState
+android.telephony.PreciseDataConnectionState$1
+android.telephony.RadioAccessFamily
+android.telephony.Rlog
+android.telephony.ServiceState
+android.telephony.ServiceState$1
+android.telephony.SignalStrength
+android.telephony.SignalStrength$1
+android.telephony.SmsManager
+android.telephony.SmsMessage
+android.telephony.SubscriptionInfo
+android.telephony.SubscriptionInfo$1
+android.telephony.SubscriptionManager
+android.telephony.SubscriptionManager$OnSubscriptionsChangedListener
+android.telephony.SubscriptionManager$OnSubscriptionsChangedListener$1
+android.telephony.SubscriptionManager$OnSubscriptionsChangedListener$2
+android.telephony.TelephonyHistogram
+android.telephony.TelephonyHistogram$1
+android.telephony.TelephonyManager
+android.telephony.TelephonyManager$MultiSimVariants
+android.telephony.VisualVoicemailSmsFilterSettings
+android.telephony.VoLteServiceState
+android.telephony.VoLteServiceState$1
+android.telephony.gsm.GsmCellLocation
+android.telephony.ims.stub.ImsConfigImplBase
+android.telephony.ims.stub.ImsEcbmImplBase
+android.telephony.ims.stub.ImsUtImplBase
+android.telephony.ims.stub.ImsUtListenerImplBase
+android.text.AndroidBidi
+android.text.AndroidCharacter
+android.text.Annotation
+android.text.BidiFormatter
+android.text.BidiFormatter$DirectionalityEstimator
+android.text.BoringLayout
+android.text.BoringLayout$Metrics
+android.text.CharSequenceCharacterIterator
+android.text.ClipboardManager
+android.text.DynamicLayout
+android.text.DynamicLayout$ChangeWatcher
+android.text.Editable
+android.text.Editable$Factory
+android.text.FontConfig
+android.text.FontConfig$Alias
+android.text.FontConfig$Family
+android.text.FontConfig$Font
+android.text.GetChars
+android.text.GraphicsOperations
+android.text.Html
+android.text.Html$HtmlParser
+android.text.Html$TagHandler
+android.text.HtmlToSpannedConverter
+android.text.HtmlToSpannedConverter$Bold
+android.text.HtmlToSpannedConverter$Href
+android.text.Hyphenator
+android.text.Hyphenator$HyphenationData
+android.text.InputFilter
+android.text.InputFilter$LengthFilter
+android.text.InputType
+android.text.Layout
+android.text.Layout$Alignment
+android.text.Layout$Directions
+android.text.Layout$Ellipsizer
+android.text.Layout$SpannedEllipsizer
+android.text.MeasuredText
+android.text.NoCopySpan
+android.text.NoCopySpan$Concrete
+android.text.PackedIntVector
+android.text.PackedObjectVector
+android.text.ParcelableSpan
+android.text.Selection
+android.text.Selection$END
+android.text.Selection$PositionIterator
+android.text.Selection$START
+android.text.SpanSet
+android.text.SpanWatcher
+android.text.Spannable
+android.text.Spannable$Factory
+android.text.SpannableString
+android.text.SpannableStringBuilder
+android.text.SpannableStringInternal
+android.text.Spanned
+android.text.SpannedString
+android.text.StaticLayout
+android.text.StaticLayout$Builder
+android.text.StaticLayout$LineBreaks
+android.text.TextDirectionHeuristic
+android.text.TextDirectionHeuristics
+android.text.TextDirectionHeuristics$AnyStrong
+android.text.TextDirectionHeuristics$FirstStrong
+android.text.TextDirectionHeuristics$TextDirectionAlgorithm
+android.text.TextDirectionHeuristics$TextDirectionHeuristicImpl
+android.text.TextDirectionHeuristics$TextDirectionHeuristicInternal
+android.text.TextDirectionHeuristics$TextDirectionHeuristicLocale
+android.text.TextLine
+android.text.TextPaint
+android.text.TextUtils
+android.text.TextUtils$1
+android.text.TextUtils$EllipsizeCallback
+android.text.TextUtils$SimpleStringSplitter
+android.text.TextUtils$StringSplitter
+android.text.TextUtils$TruncateAt
+android.text.TextWatcher
+android.text.format.DateFormat
+android.text.format.DateUtils
+android.text.format.Formatter
+android.text.format.Formatter$BytesResult
+android.text.format.Time
+android.text.format.Time$TimeCalculator
+android.text.format.TimeFormatter
+android.text.method.AllCapsTransformationMethod
+android.text.method.ArrowKeyMovementMethod
+android.text.method.BaseKeyListener
+android.text.method.BaseMovementMethod
+android.text.method.DialerKeyListener
+android.text.method.KeyListener
+android.text.method.LinkMovementMethod
+android.text.method.MetaKeyKeyListener
+android.text.method.MovementMethod
+android.text.method.NumberKeyListener
+android.text.method.PasswordTransformationMethod
+android.text.method.QwertyKeyListener
+android.text.method.QwertyKeyListener$Replaced
+android.text.method.ReplacementTransformationMethod
+android.text.method.ReplacementTransformationMethod$ReplacementCharSequence
+android.text.method.ReplacementTransformationMethod$SpannedReplacementCharSequence
+android.text.method.ScrollingMovementMethod
+android.text.method.SingleLineTransformationMethod
+android.text.method.TextKeyListener
+android.text.method.TextKeyListener$Capitalize
+android.text.method.TextKeyListener$SettingsObserver
+android.text.method.Touch
+android.text.method.Touch$DragState
+android.text.method.TransformationMethod
+android.text.method.TransformationMethod2
+android.text.method.WordIterator
+android.text.style.AlignmentSpan
+android.text.style.BackgroundColorSpan
+android.text.style.CharacterStyle
+android.text.style.CharacterStyle$Passthrough
+android.text.style.ClickableSpan
+android.text.style.DynamicDrawableSpan
+android.text.style.EasyEditSpan
+android.text.style.ForegroundColorSpan
+android.text.style.ImageSpan
+android.text.style.LeadingMarginSpan
+android.text.style.LeadingMarginSpan$LeadingMarginSpan2
+android.text.style.LeadingMarginSpan$Standard
+android.text.style.LineBackgroundSpan
+android.text.style.LineHeightSpan
+android.text.style.LineHeightSpan$WithDensity
+android.text.style.MetricAffectingSpan
+android.text.style.MetricAffectingSpan$Passthrough
+android.text.style.ParagraphStyle
+android.text.style.RelativeSizeSpan
+android.text.style.ReplacementSpan
+android.text.style.SpellCheckSpan
+android.text.style.StrikethroughSpan
+android.text.style.StyleSpan
+android.text.style.SuggestionSpan
+android.text.style.TabStopSpan
+android.text.style.TextAppearanceSpan
+android.text.style.TtsSpan
+android.text.style.TtsSpan$Builder
+android.text.style.TtsSpan$SemioticClassBuilder
+android.text.style.TtsSpan$TelephoneBuilder
+android.text.style.TtsSpan$VerbatimBuilder
+android.text.style.TypefaceSpan
+android.text.style.URLSpan
+android.text.style.UnderlineSpan
+android.text.style.UpdateAppearance
+android.text.style.UpdateLayout
+android.text.style.WrapTogetherSpan
+android.text.util.Linkify
+android.text.util.Linkify$1
+android.text.util.Linkify$2
+android.text.util.Linkify$3
+android.text.util.Linkify$4
+android.text.util.Linkify$MatchFilter
+android.text.util.Linkify$TransformFilter
+android.text.util.Rfc822Token
+android.text.util.Rfc822Tokenizer
+android.transition.ArcMotion
+android.transition.AutoTransition
+android.transition.ChangeBounds
+android.transition.ChangeBounds$1
+android.transition.ChangeBounds$2
+android.transition.ChangeBounds$3
+android.transition.ChangeBounds$4
+android.transition.ChangeBounds$5
+android.transition.ChangeBounds$6
+android.transition.ChangeBounds$9
+android.transition.ChangeClipBounds
+android.transition.ChangeImageTransform
+android.transition.ChangeImageTransform$1
+android.transition.ChangeImageTransform$2
+android.transition.ChangeTransform
+android.transition.ChangeTransform$1
+android.transition.ChangeTransform$2
+android.transition.ChangeTransform$3
+android.transition.ChangeTransform$GhostListener
+android.transition.ChangeTransform$PathAnimatorMatrix
+android.transition.ChangeTransform$Transforms
+android.transition.CircularPropagation
+android.transition.Explode
+android.transition.Fade
+android.transition.Fade$1
+android.transition.Fade$FadeAnimatorListener
+android.transition.PathMotion
+android.transition.Scene
+android.transition.SidePropagation
+android.transition.Slide
+android.transition.Slide$1
+android.transition.Slide$2
+android.transition.Slide$3
+android.transition.Slide$4
+android.transition.Slide$5
+android.transition.Slide$6
+android.transition.Slide$CalculateSlide
+android.transition.Slide$CalculateSlideHorizontal
+android.transition.Slide$CalculateSlideVertical
+android.transition.Transition
+android.transition.Transition$1
+android.transition.Transition$2
+android.transition.Transition$3
+android.transition.Transition$AnimationInfo
+android.transition.Transition$ArrayListManager
+android.transition.Transition$EpicenterCallback
+android.transition.Transition$TransitionListener
+android.transition.TransitionInflater
+android.transition.TransitionListenerAdapter
+android.transition.TransitionManager
+android.transition.TransitionManager$MultiListener
+android.transition.TransitionManager$MultiListener$1
+android.transition.TransitionPropagation
+android.transition.TransitionSet
+android.transition.TransitionSet$TransitionSetListener
+android.transition.TransitionUtils
+android.transition.TransitionValues
+android.transition.TransitionValuesMaps
+android.transition.Visibility
+android.transition.Visibility$1
+android.transition.Visibility$VisibilityInfo
+android.transition.VisibilityPropagation
+android.util.AndroidException
+android.util.AndroidRuntimeException
+android.util.ArrayMap
+android.util.ArrayMap$1
+android.util.ArraySet
+android.util.ArraySet$1
+android.util.AtomicFile
+android.util.AttributeSet
+android.util.Base64
+android.util.Base64$Coder
+android.util.Base64$Decoder
+android.util.Base64$Encoder
+android.util.BootTimingsTraceLog
+android.util.ByteStringUtils
+android.util.ContainerHelpers
+android.util.DebugUtils
+android.util.DisplayMetrics
+android.util.EventLog
+android.util.EventLog$Event
+android.util.FastImmutableArraySet
+android.util.FastImmutableArraySet$FastIterator
+android.util.FloatProperty
+android.util.IconDrawableFactory
+android.util.IntArray
+android.util.IntProperty
+android.util.JsonReader
+android.util.JsonScope
+android.util.JsonToken
+android.util.JsonWriter
+android.util.KeyValueListParser
+android.util.LauncherIcons
+android.util.LauncherIcons$ShadowDrawable
+android.util.LauncherIcons$ShadowDrawable$MyConstantState
+android.util.LocalLog
+android.util.LocalLog$ReadOnlyLocalLog
+android.util.Log
+android.util.Log$1
+android.util.Log$ImmediateLogWriter
+android.util.Log$TerribleFailure
+android.util.Log$TerribleFailureHandler
+android.util.LogPrinter
+android.util.LongArray
+android.util.LongSparseArray
+android.util.LongSparseLongArray
+android.util.LruCache
+android.util.MapCollections
+android.util.MapCollections$ArrayIterator
+android.util.MapCollections$EntrySet
+android.util.MapCollections$KeySet
+android.util.MapCollections$MapIterator
+android.util.MapCollections$ValuesCollection
+android.util.MathUtils
+android.util.MemoryIntArray
+android.util.MemoryIntArray$1
+android.util.MergedConfiguration
+android.util.MergedConfiguration$1
+android.util.MutableBoolean
+android.util.MutableInt
+android.util.MutableLong
+android.util.NtpTrustedTime
+android.util.Pair
+android.util.PathParser
+android.util.PathParser$PathData
+android.util.Patterns
+android.util.Pools$Pool
+android.util.Pools$SimplePool
+android.util.Pools$SynchronizedPool
+android.util.Printer
+android.util.Property
+android.util.Range
+android.util.Rational
+android.util.ReflectiveProperty
+android.util.Singleton
+android.util.Size
+android.util.SizeF
+android.util.Slog
+android.util.SparseArray
+android.util.SparseBooleanArray
+android.util.SparseIntArray
+android.util.SparseLongArray
+android.util.Spline
+android.util.Spline$MonotoneCubicSpline
+android.util.StateSet
+android.util.SuperNotCalledException
+android.util.TimeFormatException
+android.util.TimeUtils
+android.util.TimedRemoteCaller
+android.util.TimingLogger
+android.util.TrustedTime
+android.util.TypedValue
+android.util.Xml
+android.util.Xml$XmlSerializerFactory
+android.util.XmlPullAttributes
+android.util.apk.ApkSignatureSchemeV2Verifier
+android.util.apk.ApkSignatureSchemeV2Verifier$SignatureNotFoundException
+android.util.apk.ZipUtils
+android.util.jar.StrictJarFile
+android.util.jar.StrictJarFile$EntryIterator
+android.util.jar.StrictJarFile$FDStream
+android.util.jar.StrictJarFile$JarFileInputStream
+android.util.jar.StrictJarFile$ZipInflaterInputStream
+android.util.jar.StrictJarManifest
+android.util.jar.StrictJarManifest$Chunk
+android.util.jar.StrictJarManifestReader
+android.util.jar.StrictJarVerifier
+android.util.jar.StrictJarVerifier$VerifierEntry
+android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk
+android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk$1
+android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk$2
+android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk$3
+android.view.-$Lambda$P6MTGFSudLpwrqb6oVD8FdorW1c
+android.view.-$Lambda$iU_USrtPm1XIm5H9QYQvXfBGDE4
+android.view.-$Lambda$iU_USrtPm1XIm5H9QYQvXfBGDE4$1
+android.view.AbsSavedState
+android.view.AbsSavedState$1
+android.view.AbsSavedState$2
+android.view.ActionMode
+android.view.ActionMode$Callback
+android.view.ActionMode$Callback2
+android.view.ActionProvider
+android.view.ActionProvider$SubUiVisibilityListener
+android.view.AppTransitionAnimationSpec
+android.view.AppTransitionAnimationSpec$1
+android.view.Choreographer
+android.view.Choreographer$1
+android.view.Choreographer$2
+android.view.Choreographer$CallbackQueue
+android.view.Choreographer$CallbackRecord
+android.view.Choreographer$FrameCallback
+android.view.Choreographer$FrameDisplayEventReceiver
+android.view.Choreographer$FrameHandler
+android.view.ContextMenu
+android.view.ContextMenu$ContextMenuInfo
+android.view.ContextThemeWrapper
+android.view.Display
+android.view.Display$HdrCapabilities
+android.view.Display$HdrCapabilities$1
+android.view.Display$Mode
+android.view.Display$Mode$1
+android.view.DisplayAdjustments
+android.view.DisplayEventReceiver
+android.view.DisplayInfo
+android.view.DisplayInfo$1
+android.view.DisplayListCanvas
+android.view.DragEvent
+android.view.FallbackEventHandler
+android.view.FocusFinder
+android.view.FocusFinder$1
+android.view.FocusFinder$FocusSorter
+android.view.FocusFinder$UserSpecifiedFocusComparator
+android.view.FocusFinder$UserSpecifiedFocusComparator$NextFocusGetter
+android.view.FrameInfo
+android.view.FrameMetrics
+android.view.FrameMetricsObserver
+android.view.FrameStats
+android.view.GestureDetector
+android.view.GestureDetector$GestureHandler
+android.view.GestureDetector$OnContextClickListener
+android.view.GestureDetector$OnDoubleTapListener
+android.view.GestureDetector$OnGestureListener
+android.view.GestureDetector$SimpleOnGestureListener
+android.view.GhostView
+android.view.Gravity
+android.view.HandlerActionQueue
+android.view.HandlerActionQueue$HandlerAction
+android.view.HardwareLayer
+android.view.IAppTransitionAnimationSpecsFuture
+android.view.IAppTransitionAnimationSpecsFuture$Stub
+android.view.IAppTransitionAnimationSpecsFuture$Stub$Proxy
+android.view.IApplicationToken
+android.view.IApplicationToken$Stub
+android.view.IDockedStackListener
+android.view.IDockedStackListener$Stub
+android.view.IDockedStackListener$Stub$Proxy
+android.view.IGraphicsStats
+android.view.IGraphicsStats$Stub
+android.view.IGraphicsStats$Stub$Proxy
+android.view.IGraphicsStatsCallback
+android.view.IGraphicsStatsCallback$Stub
+android.view.IGraphicsStatsCallback$Stub$Proxy
+android.view.IInputFilter
+android.view.IOnKeyguardExitResult
+android.view.IPinnedStackController
+android.view.IPinnedStackController$Stub
+android.view.IPinnedStackController$Stub$Proxy
+android.view.IPinnedStackListener
+android.view.IPinnedStackListener$Stub
+android.view.IPinnedStackListener$Stub$Proxy
+android.view.IRotationWatcher
+android.view.IRotationWatcher$Stub
+android.view.IRotationWatcher$Stub$Proxy
+android.view.IWindow
+android.view.IWindow$Stub
+android.view.IWindow$Stub$Proxy
+android.view.IWindowFocusObserver
+android.view.IWindowId
+android.view.IWindowId$Stub
+android.view.IWindowId$Stub$Proxy
+android.view.IWindowManager
+android.view.IWindowManager$Stub
+android.view.IWindowManager$Stub$Proxy
+android.view.IWindowSession
+android.view.IWindowSession$Stub
+android.view.IWindowSession$Stub$Proxy
+android.view.IWindowSessionCallback
+android.view.IWindowSessionCallback$Stub
+android.view.IWindowSessionCallback$Stub$Proxy
+android.view.InflateException
+android.view.InputChannel
+android.view.InputChannel$1
+android.view.InputDevice
+android.view.InputDevice$1
+android.view.InputDevice$MotionRange
+android.view.InputEvent
+android.view.InputEvent$1
+android.view.InputEventConsistencyVerifier
+android.view.InputEventReceiver
+android.view.InputEventReceiver$Factory
+android.view.InputEventSender
+android.view.InputQueue
+android.view.InputQueue$Callback
+android.view.InputQueue$FinishedInputEventCallback
+android.view.KeyCharacterMap
+android.view.KeyCharacterMap$1
+android.view.KeyCharacterMap$FallbackAction
+android.view.KeyEvent
+android.view.KeyEvent$1
+android.view.KeyEvent$Callback
+android.view.KeyEvent$DispatcherState
+android.view.KeyboardShortcutGroup
+android.view.KeyboardShortcutGroup$1
+android.view.KeyboardShortcutInfo
+android.view.KeyboardShortcutInfo$1
+android.view.LayoutInflater
+android.view.LayoutInflater$Factory
+android.view.LayoutInflater$Factory2
+android.view.LayoutInflater$FactoryMerger
+android.view.LayoutInflater$Filter
+android.view.MagnificationSpec
+android.view.Menu
+android.view.MenuInflater
+android.view.MenuInflater$MenuState
+android.view.MenuItem
+android.view.MenuItem$OnActionExpandListener
+android.view.MenuItem$OnMenuItemClickListener
+android.view.MotionEvent
+android.view.MotionEvent$1
+android.view.MotionEvent$PointerCoords
+android.view.MotionEvent$PointerProperties
+android.view.NotificationHeaderView
+android.view.NotificationHeaderView$1
+android.view.NotificationHeaderView$HeaderTouchListener
+android.view.OrientationEventListener
+android.view.OrientationEventListener$SensorEventListenerImpl
+android.view.PointerIcon
+android.view.PointerIcon$1
+android.view.RecordingCanvas
+android.view.RemotableViewMethod
+android.view.RenderNode
+android.view.RenderNode$NoImagePreloadHolder
+android.view.RenderNodeAnimator
+android.view.RenderNodeAnimator$1
+android.view.RenderNodeAnimatorSetHelper
+android.view.ScaleGestureDetector
+android.view.ScaleGestureDetector$1
+android.view.ScaleGestureDetector$OnScaleGestureListener
+android.view.ScaleGestureDetector$SimpleOnScaleGestureListener
+android.view.SearchEvent
+android.view.SubMenu
+android.view.Surface
+android.view.Surface$1
+android.view.Surface$CompatibleCanvas
+android.view.Surface$OutOfResourcesException
+android.view.SurfaceControl
+android.view.SurfaceControl$PhysicalDisplayInfo
+android.view.SurfaceHolder
+android.view.SurfaceHolder$Callback
+android.view.SurfaceHolder$Callback2
+android.view.SurfaceSession
+android.view.SurfaceView
+android.view.SurfaceView$1
+android.view.SurfaceView$2
+android.view.SurfaceView$3
+android.view.SurfaceView$4
+android.view.TextureView
+android.view.TextureView$1
+android.view.TextureView$SurfaceTextureListener
+android.view.ThreadedRenderer
+android.view.ThreadedRenderer$DrawCallbacks
+android.view.ThreadedRenderer$ProcessInitializer
+android.view.ThreadedRenderer$ProcessInitializer$1
+android.view.TouchDelegate
+android.view.VelocityTracker
+android.view.VelocityTracker$Estimator
+android.view.View
+android.view.View$1
+android.view.View$10
+android.view.View$11
+android.view.View$12
+android.view.View$2
+android.view.View$3
+android.view.View$4
+android.view.View$5
+android.view.View$6
+android.view.View$7
+android.view.View$8
+android.view.View$9
+android.view.View$AccessibilityDelegate
+android.view.View$AttachInfo
+android.view.View$AttachInfo$Callbacks
+android.view.View$BaseSavedState
+android.view.View$BaseSavedState$1
+android.view.View$CheckForLongPress
+android.view.View$CheckForTap
+android.view.View$DeclaredOnClickListener
+android.view.View$ForegroundInfo
+android.view.View$ListenerInfo
+android.view.View$MatchIdPredicate
+android.view.View$MeasureSpec
+android.view.View$OnApplyWindowInsetsListener
+android.view.View$OnAttachStateChangeListener
+android.view.View$OnClickListener
+android.view.View$OnCreateContextMenuListener
+android.view.View$OnDragListener
+android.view.View$OnFocusChangeListener
+android.view.View$OnGenericMotionListener
+android.view.View$OnHoverListener
+android.view.View$OnKeyListener
+android.view.View$OnLayoutChangeListener
+android.view.View$OnLongClickListener
+android.view.View$OnScrollChangeListener
+android.view.View$OnSystemUiVisibilityChangeListener
+android.view.View$OnTouchListener
+android.view.View$PerformClick
+android.view.View$ScrollabilityCache
+android.view.View$TintInfo
+android.view.View$TooltipInfo
+android.view.View$TransformationInfo
+android.view.View$UnsetPressedState
+android.view.View$VisibilityChangeForAutofillHandler
+android.view.ViewAnimationUtils
+android.view.ViewConfiguration
+android.view.ViewDebug$CapturedViewProperty
+android.view.ViewDebug$ExportedProperty
+android.view.ViewDebug$HierarchyHandler
+android.view.ViewGroup
+android.view.ViewGroup$1
+android.view.ViewGroup$2
+android.view.ViewGroup$3
+android.view.ViewGroup$4
+android.view.ViewGroup$ChildListForAutoFill
+android.view.ViewGroup$LayoutParams
+android.view.ViewGroup$MarginLayoutParams
+android.view.ViewGroup$OnHierarchyChangeListener
+android.view.ViewGroup$TouchTarget
+android.view.ViewGroupOverlay
+android.view.ViewManager
+android.view.ViewOutlineProvider
+android.view.ViewOutlineProvider$1
+android.view.ViewOutlineProvider$2
+android.view.ViewOutlineProvider$3
+android.view.ViewOverlay
+android.view.ViewOverlay$OverlayViewGroup
+android.view.ViewParent
+android.view.ViewPropertyAnimator
+android.view.ViewPropertyAnimator$1
+android.view.ViewPropertyAnimator$2
+android.view.ViewPropertyAnimator$3
+android.view.ViewPropertyAnimator$AnimatorEventListener
+android.view.ViewPropertyAnimator$NameValuesHolder
+android.view.ViewPropertyAnimator$PropertyBundle
+android.view.ViewRootImpl
+android.view.ViewRootImpl$1
+android.view.ViewRootImpl$2
+android.view.ViewRootImpl$4
+android.view.ViewRootImpl$AccessibilityInteractionConnectionManager
+android.view.ViewRootImpl$ActivityConfigCallback
+android.view.ViewRootImpl$AsyncInputStage
+android.view.ViewRootImpl$ConfigChangedCallback
+android.view.ViewRootImpl$ConsumeBatchedInputImmediatelyRunnable
+android.view.ViewRootImpl$ConsumeBatchedInputRunnable
+android.view.ViewRootImpl$EarlyPostImeInputStage
+android.view.ViewRootImpl$HighContrastTextManager
+android.view.ViewRootImpl$ImeInputStage
+android.view.ViewRootImpl$InputStage
+android.view.ViewRootImpl$InvalidateOnAnimationRunnable
+android.view.ViewRootImpl$NativePostImeInputStage
+android.view.ViewRootImpl$NativePreImeInputStage
+android.view.ViewRootImpl$QueuedInputEvent
+android.view.ViewRootImpl$SyntheticInputStage
+android.view.ViewRootImpl$SyntheticJoystickHandler
+android.view.ViewRootImpl$SyntheticKeyboardHandler
+android.view.ViewRootImpl$SyntheticTouchNavigationHandler
+android.view.ViewRootImpl$SyntheticTouchNavigationHandler$1
+android.view.ViewRootImpl$SyntheticTrackballHandler
+android.view.ViewRootImpl$SystemUiVisibilityInfo
+android.view.ViewRootImpl$TrackballAxis
+android.view.ViewRootImpl$TraversalRunnable
+android.view.ViewRootImpl$ViewPostImeInputStage
+android.view.ViewRootImpl$ViewPreImeInputStage
+android.view.ViewRootImpl$ViewRootHandler
+android.view.ViewRootImpl$W
+android.view.ViewRootImpl$WindowInputEventReceiver
+android.view.ViewRootImpl$WindowStoppedCallback
+android.view.ViewStructure
+android.view.ViewStructure$HtmlInfo
+android.view.ViewStub
+android.view.ViewStub$OnInflateListener
+android.view.ViewStub$ViewReplaceRunnable
+android.view.ViewTreeObserver
+android.view.ViewTreeObserver$CopyOnWriteArray
+android.view.ViewTreeObserver$CopyOnWriteArray$Access
+android.view.ViewTreeObserver$InternalInsetsInfo
+android.view.ViewTreeObserver$OnComputeInternalInsetsListener
+android.view.ViewTreeObserver$OnDrawListener
+android.view.ViewTreeObserver$OnGlobalFocusChangeListener
+android.view.ViewTreeObserver$OnGlobalLayoutListener
+android.view.ViewTreeObserver$OnPreDrawListener
+android.view.ViewTreeObserver$OnScrollChangedListener
+android.view.ViewTreeObserver$OnTouchModeChangeListener
+android.view.Window
+android.view.Window$Callback
+android.view.Window$OnWindowDismissedCallback
+android.view.Window$OnWindowSwipeDismissedCallback
+android.view.Window$WindowControllerCallback
+android.view.WindowAnimationFrameStats
+android.view.WindowAnimationFrameStats$1
+android.view.WindowCallbackWrapper
+android.view.WindowCallbacks
+android.view.WindowContentFrameStats
+android.view.WindowContentFrameStats$1
+android.view.WindowId
+android.view.WindowId$1
+android.view.WindowInsets
+android.view.WindowLeaked
+android.view.WindowManager
+android.view.WindowManager$BadTokenException
+android.view.WindowManager$InvalidDisplayException
+android.view.WindowManager$KeyboardShortcutsReceiver
+android.view.WindowManager$LayoutParams
+android.view.WindowManager$LayoutParams$1
+android.view.WindowManagerGlobal
+android.view.WindowManagerGlobal$1
+android.view.WindowManagerGlobal$2
+android.view.WindowManagerImpl
+android.view.WindowManagerInternal
+android.view.WindowManagerInternal$AppTransitionListener
+android.view.WindowManagerInternal$MagnificationCallbacks
+android.view.WindowManagerInternal$OnHardKeyboardStatusChangeListener
+android.view.WindowManagerInternal$WindowsForAccessibilityCallback
+android.view.WindowManagerPolicy
+android.view.WindowManagerPolicy$InputConsumer
+android.view.WindowManagerPolicy$OnKeyguardExitResult
+android.view.WindowManagerPolicy$PointerEventListener
+android.view.WindowManagerPolicy$ScreenOffListener
+android.view.WindowManagerPolicy$ScreenOnListener
+android.view.WindowManagerPolicy$StartingSurface
+android.view.WindowManagerPolicy$WindowManagerFuncs
+android.view.WindowManagerPolicy$WindowState
+android.view.accessibility.AccessibilityEvent
+android.view.accessibility.AccessibilityEvent$1
+android.view.accessibility.AccessibilityEventSource
+android.view.accessibility.AccessibilityManager
+android.view.accessibility.AccessibilityManager$1
+android.view.accessibility.AccessibilityManager$AccessibilityServicesStateChangeListener
+android.view.accessibility.AccessibilityManager$AccessibilityStateChangeListener
+android.view.accessibility.AccessibilityManager$HighTextContrastChangeListener
+android.view.accessibility.AccessibilityManager$MyCallback
+android.view.accessibility.AccessibilityManager$TouchExplorationStateChangeListener
+android.view.accessibility.AccessibilityNodeInfo
+android.view.accessibility.AccessibilityNodeInfo$AccessibilityAction
+android.view.accessibility.AccessibilityNodeProvider
+android.view.accessibility.AccessibilityRecord
+android.view.accessibility.CaptioningManager
+android.view.accessibility.CaptioningManager$1
+android.view.accessibility.CaptioningManager$CaptionStyle
+android.view.accessibility.CaptioningManager$CaptioningChangeListener
+android.view.accessibility.CaptioningManager$MyContentObserver
+android.view.accessibility.IAccessibilityInteractionConnection
+android.view.accessibility.IAccessibilityInteractionConnection$Stub
+android.view.accessibility.IAccessibilityInteractionConnection$Stub$Proxy
+android.view.accessibility.IAccessibilityInteractionConnectionCallback
+android.view.accessibility.IAccessibilityManager
+android.view.accessibility.IAccessibilityManager$Stub
+android.view.accessibility.IAccessibilityManager$Stub$Proxy
+android.view.accessibility.IAccessibilityManagerClient
+android.view.accessibility.IAccessibilityManagerClient$Stub
+android.view.accessibility.IAccessibilityManagerClient$Stub$Proxy
+android.view.animation.AccelerateDecelerateInterpolator
+android.view.animation.AccelerateInterpolator
+android.view.animation.AlphaAnimation
+android.view.animation.Animation
+android.view.animation.Animation$1
+android.view.animation.Animation$2
+android.view.animation.Animation$3
+android.view.animation.Animation$AnimationListener
+android.view.animation.Animation$Description
+android.view.animation.Animation$NoImagePreloadHolder
+android.view.animation.AnimationSet
+android.view.animation.AnimationUtils
+android.view.animation.AnimationUtils$1
+android.view.animation.AnimationUtils$AnimationState
+android.view.animation.BaseInterpolator
+android.view.animation.ClipRectAnimation
+android.view.animation.CycleInterpolator
+android.view.animation.DecelerateInterpolator
+android.view.animation.GridLayoutAnimationController$AnimationParameters
+android.view.animation.Interpolator
+android.view.animation.LayoutAnimationController
+android.view.animation.LayoutAnimationController$AnimationParameters
+android.view.animation.LinearInterpolator
+android.view.animation.OvershootInterpolator
+android.view.animation.PathInterpolator
+android.view.animation.ScaleAnimation
+android.view.animation.Transformation
+android.view.animation.TranslateAnimation
+android.view.autofill.AutofillId
+android.view.autofill.AutofillId$1
+android.view.autofill.AutofillManager
+android.view.autofill.AutofillManager$AutofillClient
+android.view.autofill.AutofillManager$AutofillManagerClient
+android.view.autofill.AutofillValue
+android.view.autofill.AutofillValue$1
+android.view.autofill.Helper
+android.view.autofill.IAutoFillManager
+android.view.autofill.IAutoFillManager$Stub
+android.view.autofill.IAutoFillManager$Stub$Proxy
+android.view.autofill.IAutoFillManagerClient
+android.view.autofill.IAutoFillManagerClient$Stub
+android.view.autofill.IAutoFillManagerClient$Stub$Proxy
+android.view.autofill.IAutofillWindowPresenter
+android.view.inputmethod.BaseInputConnection
+android.view.inputmethod.CompletionInfo
+android.view.inputmethod.CompletionInfo$1
+android.view.inputmethod.ComposingText
+android.view.inputmethod.CorrectionInfo
+android.view.inputmethod.CursorAnchorInfo
+android.view.inputmethod.CursorAnchorInfo$Builder
+android.view.inputmethod.EditorInfo
+android.view.inputmethod.EditorInfo$1
+android.view.inputmethod.ExtractedText
+android.view.inputmethod.ExtractedText$1
+android.view.inputmethod.ExtractedTextRequest
+android.view.inputmethod.ExtractedTextRequest$1
+android.view.inputmethod.InputBinding
+android.view.inputmethod.InputBinding$1
+android.view.inputmethod.InputConnection
+android.view.inputmethod.InputConnectionInspector
+android.view.inputmethod.InputConnectionWrapper
+android.view.inputmethod.InputContentInfo
+android.view.inputmethod.InputMethod
+android.view.inputmethod.InputMethod$SessionCallback
+android.view.inputmethod.InputMethodInfo
+android.view.inputmethod.InputMethodInfo$1
+android.view.inputmethod.InputMethodManager
+android.view.inputmethod.InputMethodManager$1
+android.view.inputmethod.InputMethodManager$2
+android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper
+android.view.inputmethod.InputMethodManager$FinishedInputEventCallback
+android.view.inputmethod.InputMethodManager$H
+android.view.inputmethod.InputMethodManager$ImeInputEventSender
+android.view.inputmethod.InputMethodManager$PendingEvent
+android.view.inputmethod.InputMethodManagerInternal
+android.view.inputmethod.InputMethodSession
+android.view.inputmethod.InputMethodSession$EventCallback
+android.view.inputmethod.InputMethodSubtype
+android.view.inputmethod.InputMethodSubtype$1
+android.view.inputmethod.InputMethodSubtype$InputMethodSubtypeBuilder
+android.view.inputmethod.InputMethodSubtypeArray
+android.view.textclassifier.TextClassificationManager
+android.view.textclassifier.TextClassifier
+android.view.textclassifier.TextClassifier$1
+android.view.textclassifier.TextClassifierImpl
+android.view.textservice.SpellCheckerInfo
+android.view.textservice.SpellCheckerInfo$1
+android.view.textservice.SpellCheckerSession
+android.view.textservice.SpellCheckerSession$1
+android.view.textservice.SpellCheckerSession$InternalListener
+android.view.textservice.SpellCheckerSession$SpellCheckerSessionListener
+android.view.textservice.SpellCheckerSession$SpellCheckerSessionListenerImpl
+android.view.textservice.SpellCheckerSession$SpellCheckerSessionListenerImpl$SpellCheckerParams
+android.view.textservice.SpellCheckerSubtype
+android.view.textservice.SpellCheckerSubtype$1
+android.view.textservice.SuggestionsInfo
+android.view.textservice.TextInfo
+android.view.textservice.TextServicesManager
+android.webkit.ConsoleMessage
+android.webkit.ConsoleMessage$MessageLevel
+android.webkit.CookieManager
+android.webkit.CookieSyncManager
+android.webkit.DownloadListener
+android.webkit.GeolocationPermissions
+android.webkit.IWebViewUpdateService
+android.webkit.IWebViewUpdateService$Stub
+android.webkit.IWebViewUpdateService$Stub$Proxy
+android.webkit.JavascriptInterface
+android.webkit.MimeTypeMap
+android.webkit.ServiceWorkerClient
+android.webkit.ServiceWorkerController
+android.webkit.ServiceWorkerWebSettings
+android.webkit.TokenBindingService
+android.webkit.URLUtil
+android.webkit.UserPackage
+android.webkit.ValueCallback
+android.webkit.WebBackForwardList
+android.webkit.WebChromeClient
+android.webkit.WebChromeClient$CustomViewCallback
+android.webkit.WebIconDatabase
+android.webkit.WebMessage
+android.webkit.WebMessagePort
+android.webkit.WebResourceRequest
+android.webkit.WebSettings
+android.webkit.WebSettings$LayoutAlgorithm
+android.webkit.WebSettings$PluginState
+android.webkit.WebSettings$RenderPriority
+android.webkit.WebSettings$ZoomDensity
+android.webkit.WebStorage
+android.webkit.WebSyncManager
+android.webkit.WebView
+android.webkit.WebView$FindListener
+android.webkit.WebView$HitTestResult
+android.webkit.WebView$PictureListener
+android.webkit.WebView$PrivateAccess
+android.webkit.WebView$VisualStateCallback
+android.webkit.WebViewClient
+android.webkit.WebViewDatabase
+android.webkit.WebViewDelegate
+android.webkit.WebViewDelegate$1
+android.webkit.WebViewDelegate$OnTraceEnabledChangeListener
+android.webkit.WebViewFactory
+android.webkit.WebViewFactory$1
+android.webkit.WebViewFactory$MissingWebViewPackageException
+android.webkit.WebViewFactory$RelroFileCreator
+android.webkit.WebViewFactoryProvider
+android.webkit.WebViewFactoryProvider$Statics
+android.webkit.WebViewProvider
+android.webkit.WebViewProvider$ScrollDelegate
+android.webkit.WebViewProvider$ViewDelegate
+android.webkit.WebViewProviderInfo
+android.webkit.WebViewProviderInfo$1
+android.webkit.WebViewProviderResponse
+android.webkit.WebViewProviderResponse$1
+android.webkit.WebViewZygote
+android.widget.-$Lambda$ISuHLqeK-K4pmesAfzlFglc3xF4
+android.widget.-$Lambda$ISuHLqeK-K4pmesAfzlFglc3xF4$1
+android.widget.-$Lambda$ISuHLqeK-K4pmesAfzlFglc3xF4$2
+android.widget.-$Lambda$ISuHLqeK-K4pmesAfzlFglc3xF4$3
+android.widget.-$Lambda$tfOQKOmkDz_xLYaBQX_cysn8vbE
+android.widget.AbsListView
+android.widget.AbsListView$3
+android.widget.AbsListView$AdapterDataSetObserver
+android.widget.AbsListView$CheckForTap
+android.widget.AbsListView$FlingRunnable
+android.widget.AbsListView$FlingRunnable$1
+android.widget.AbsListView$LayoutParams
+android.widget.AbsListView$MultiChoiceModeListener
+android.widget.AbsListView$MultiChoiceModeWrapper
+android.widget.AbsListView$OnScrollListener
+android.widget.AbsListView$PerformClick
+android.widget.AbsListView$RecycleBin
+android.widget.AbsListView$RecyclerListener
+android.widget.AbsListView$SavedState
+android.widget.AbsListView$SavedState$1
+android.widget.AbsListView$SelectionBoundsAdjuster
+android.widget.AbsListView$WindowRunnnable
+android.widget.AbsSeekBar
+android.widget.AbsSpinner
+android.widget.AbsSpinner$RecycleBin
+android.widget.AbsoluteLayout
+android.widget.ActionMenuPresenter
+android.widget.ActionMenuPresenter$1
+android.widget.ActionMenuPresenter$2
+android.widget.ActionMenuPresenter$ActionMenuPopupCallback
+android.widget.ActionMenuPresenter$OverflowMenuButton
+android.widget.ActionMenuPresenter$OverflowMenuButton$1
+android.widget.ActionMenuPresenter$PopupPresenterCallback
+android.widget.ActionMenuView
+android.widget.ActionMenuView$ActionMenuChildView
+android.widget.ActionMenuView$ActionMenuPresenterCallback
+android.widget.ActionMenuView$LayoutParams
+android.widget.ActionMenuView$MenuBuilderCallback
+android.widget.ActionMenuView$OnMenuItemClickListener
+android.widget.Adapter
+android.widget.AdapterView
+android.widget.AdapterView$AdapterDataSetObserver
+android.widget.AdapterView$OnItemClickListener
+android.widget.AdapterView$OnItemLongClickListener
+android.widget.AdapterView$OnItemSelectedListener
+android.widget.AdapterView$SelectionNotifier
+android.widget.ArrayAdapter
+android.widget.AutoCompleteTextView
+android.widget.AutoCompleteTextView$DropDownItemClickListener
+android.widget.AutoCompleteTextView$MyWatcher
+android.widget.AutoCompleteTextView$PassThroughClickListener
+android.widget.AutoCompleteTextView$PopupDataSetObserver
+android.widget.AutoCompleteTextView$PopupDataSetObserver$1
+android.widget.AutoCompleteTextView$Validator
+android.widget.BaseAdapter
+android.widget.Button
+android.widget.CheckBox
+android.widget.Checkable
+android.widget.CheckedTextView
+android.widget.Chronometer
+android.widget.Chronometer$1
+android.widget.CompoundButton
+android.widget.CompoundButton$OnCheckedChangeListener
+android.widget.CursorAdapter
+android.widget.CursorFilter$CursorFilterClient
+android.widget.DatePicker
+android.widget.DateTimeView
+android.widget.DateTimeView$ReceiverInfo
+android.widget.DateTimeView$ReceiverInfo$1
+android.widget.DateTimeView$ReceiverInfo$2
+android.widget.DropDownListView
+android.widget.EdgeEffect
+android.widget.EditText
+android.widget.Editor
+android.widget.Editor$1
+android.widget.Editor$2
+android.widget.Editor$Blink
+android.widget.Editor$CursorAnchorInfoNotifier
+android.widget.Editor$CursorController
+android.widget.Editor$EditOperation
+android.widget.Editor$EditOperation$1
+android.widget.Editor$HandleView
+android.widget.Editor$InputContentType
+android.widget.Editor$InputMethodState
+android.widget.Editor$InsertionHandleView
+android.widget.Editor$InsertionHandleView$2
+android.widget.Editor$InsertionPointCursorController
+android.widget.Editor$PositionListener
+android.widget.Editor$ProcessTextIntentActionsHandler
+android.widget.Editor$SelectionModifierCursorController
+android.widget.Editor$SpanController
+android.widget.Editor$SuggestionHelper
+android.widget.Editor$SuggestionHelper$SuggestionSpanComparator
+android.widget.Editor$TextRenderNode
+android.widget.Editor$TextViewPositionListener
+android.widget.Editor$UndoInputFilter
+android.widget.ExpandableListConnector
+android.widget.FastScroller
+android.widget.FastScroller$1
+android.widget.FastScroller$2
+android.widget.FastScroller$3
+android.widget.FastScroller$4
+android.widget.FastScroller$5
+android.widget.FastScroller$6
+android.widget.Filter
+android.widget.Filter$FilterListener
+android.widget.Filter$FilterResults
+android.widget.Filter$RequestArguments
+android.widget.Filter$RequestHandler
+android.widget.Filter$ResultsHandler
+android.widget.Filterable
+android.widget.ForwardingListener
+android.widget.FrameLayout
+android.widget.FrameLayout$LayoutParams
+android.widget.GridLayout
+android.widget.GridLayout$1
+android.widget.GridLayout$2
+android.widget.GridLayout$3
+android.widget.GridLayout$4
+android.widget.GridLayout$5
+android.widget.GridLayout$6
+android.widget.GridLayout$6$1
+android.widget.GridLayout$7
+android.widget.GridLayout$8
+android.widget.GridLayout$Alignment
+android.widget.GridLayout$Arc
+android.widget.GridLayout$Assoc
+android.widget.GridLayout$Axis
+android.widget.GridLayout$Axis$1
+android.widget.GridLayout$Bounds
+android.widget.GridLayout$Interval
+android.widget.GridLayout$LayoutParams
+android.widget.GridLayout$MutableInt
+android.widget.GridLayout$PackedMap
+android.widget.GridLayout$Spec
+android.widget.GridView
+android.widget.HeaderViewListAdapter
+android.widget.HorizontalScrollView
+android.widget.HorizontalScrollView$SavedState
+android.widget.HorizontalScrollView$SavedState$1
+android.widget.ImageButton
+android.widget.ImageView
+android.widget.ImageView$ImageDrawableCallback
+android.widget.ImageView$ScaleType
+android.widget.LinearLayout
+android.widget.LinearLayout$LayoutParams
+android.widget.ListAdapter
+android.widget.ListPopupWindow
+android.widget.ListPopupWindow$2
+android.widget.ListPopupWindow$3
+android.widget.ListPopupWindow$ListSelectorHider
+android.widget.ListPopupWindow$PopupDataSetObserver
+android.widget.ListPopupWindow$PopupScrollListener
+android.widget.ListPopupWindow$PopupTouchInterceptor
+android.widget.ListPopupWindow$ResizePopupRunnable
+android.widget.ListView
+android.widget.ListView$ArrowScrollFocusResult
+android.widget.ListView$FixedViewInfo
+android.widget.MediaController
+android.widget.MediaController$MediaPlayerControl
+android.widget.MultiAutoCompleteTextView
+android.widget.MultiAutoCompleteTextView$Tokenizer
+android.widget.NumberPicker
+android.widget.NumberPicker$Formatter
+android.widget.NumberPicker$OnValueChangeListener
+android.widget.OverScroller
+android.widget.OverScroller$SplineOverScroller
+android.widget.PopupMenu
+android.widget.PopupMenu$1
+android.widget.PopupMenu$2
+android.widget.PopupMenu$3
+android.widget.PopupMenu$OnMenuItemClickListener
+android.widget.PopupWindow
+android.widget.PopupWindow$1
+android.widget.PopupWindow$2
+android.widget.PopupWindow$OnDismissListener
+android.widget.PopupWindow$PopupBackgroundView
+android.widget.PopupWindow$PopupDecorView
+android.widget.PopupWindow$PopupDecorView$1
+android.widget.ProgressBar
+android.widget.ProgressBar$1
+android.widget.ProgressBar$ProgressTintInfo
+android.widget.ProgressBar$RefreshData
+android.widget.ProgressBar$RefreshProgressRunnable
+android.widget.ProgressBar$SavedState
+android.widget.ProgressBar$SavedState$1
+android.widget.QuickContactBadge
+android.widget.QuickContactBadge$QueryHandler
+android.widget.RadioButton
+android.widget.RadioGroup
+android.widget.RadioGroup$CheckedStateTracker
+android.widget.RadioGroup$LayoutParams
+android.widget.RadioGroup$OnCheckedChangeListener
+android.widget.RadioGroup$PassThroughHierarchyChangeListener
+android.widget.RatingBar
+android.widget.RelativeLayout
+android.widget.RelativeLayout$DependencyGraph
+android.widget.RelativeLayout$DependencyGraph$Node
+android.widget.RelativeLayout$LayoutParams
+android.widget.RemoteViews
+android.widget.RemoteViews$1
+android.widget.RemoteViews$2
+android.widget.RemoteViews$3
+android.widget.RemoteViews$Action
+android.widget.RemoteViews$ActionException
+android.widget.RemoteViews$AsyncApplyTask
+android.widget.RemoteViews$BitmapCache
+android.widget.RemoteViews$BitmapReflectionAction
+android.widget.RemoteViews$LayoutParamAction
+android.widget.RemoteViews$MemoryUsageCounter
+android.widget.RemoteViews$MutablePair
+android.widget.RemoteViews$OnClickHandler
+android.widget.RemoteViews$OnViewAppliedListener
+android.widget.RemoteViews$ReflectionAction
+android.widget.RemoteViews$RemoteView
+android.widget.RemoteViews$RemoteViewsContextWrapper
+android.widget.RemoteViews$RunnableAction
+android.widget.RemoteViews$RuntimeAction
+android.widget.RemoteViews$SetDrawableParameters
+android.widget.RemoteViews$SetOnClickPendingIntent
+android.widget.RemoteViews$SetOnClickPendingIntent$1
+android.widget.RemoteViews$ViewGroupAction
+android.widget.RemoteViews$ViewGroupAction$1
+android.widget.RemoteViews$ViewGroupAction$2
+android.widget.RemoteViews$ViewPaddingAction
+android.widget.RemoteViews$ViewTree
+android.widget.RemoteViewsAdapter$RemoteAdapterConnectionCallback
+android.widget.ResourceCursorAdapter
+android.widget.RtlSpacingHelper
+android.widget.ScrollBarDrawable
+android.widget.ScrollView
+android.widget.ScrollView$SavedState
+android.widget.ScrollView$SavedState$1
+android.widget.Scroller
+android.widget.Scroller$ViscousFluidInterpolator
+android.widget.SearchView$OnCloseListener
+android.widget.SectionIndexer
+android.widget.SeekBar
+android.widget.SeekBar$OnSeekBarChangeListener
+android.widget.SelectionActionModeHelper
+android.widget.SelectionActionModeHelper$SelectionTracker
+android.widget.SelectionActionModeHelper$TextClassificationHelper
+android.widget.SimpleCursorAdapter
+android.widget.Space
+android.widget.SpellChecker
+android.widget.SpellChecker$SpellParser
+android.widget.Spinner
+android.widget.Spinner$1
+android.widget.Spinner$DialogPopup
+android.widget.Spinner$DropDownAdapter
+android.widget.Spinner$DropdownPopup
+android.widget.Spinner$DropdownPopup$1
+android.widget.Spinner$SpinnerPopup
+android.widget.SpinnerAdapter
+android.widget.Switch
+android.widget.Switch$1
+android.widget.TabHost
+android.widget.TabHost$1
+android.widget.TabHost$2
+android.widget.TabHost$ContentStrategy
+android.widget.TabHost$FactoryContentStrategy
+android.widget.TabHost$IndicatorStrategy
+android.widget.TabHost$OnTabChangeListener
+android.widget.TabHost$TabContentFactory
+android.widget.TabHost$TabSpec
+android.widget.TabHost$ViewIndicatorStrategy
+android.widget.TabWidget
+android.widget.TabWidget$OnTabSelectionChanged
+android.widget.TabWidget$TabClickListener
+android.widget.TableLayout
+android.widget.TextClock
+android.widget.TextClock$1
+android.widget.TextClock$2
+android.widget.TextClock$FormatChangeObserver
+android.widget.TextSwitcher
+android.widget.TextView
+android.widget.TextView$2
+android.widget.TextView$3
+android.widget.TextView$BufferType
+android.widget.TextView$ChangeWatcher
+android.widget.TextView$CharWrapper
+android.widget.TextView$Drawables
+android.widget.TextView$Marquee
+android.widget.TextView$Marquee$1
+android.widget.TextView$Marquee$2
+android.widget.TextView$Marquee$3
+android.widget.TextView$OnEditorActionListener
+android.widget.TextView$SavedState
+android.widget.TextView$SavedState$1
+android.widget.ThemedSpinnerAdapter
+android.widget.TimePicker
+android.widget.TimePicker$OnTimeChangedListener
+android.widget.Toast
+android.widget.Toast$TN
+android.widget.Toast$TN$1
+android.widget.ToggleButton
+android.widget.Toolbar
+android.widget.Toolbar$1
+android.widget.Toolbar$2
+android.widget.Toolbar$ExpandedActionViewMenuPresenter
+android.widget.Toolbar$LayoutParams
+android.widget.Toolbar$OnMenuItemClickListener
+android.widget.VideoView
+android.widget.ViewAnimator
+android.widget.ViewFlipper
+android.widget.ViewFlipper$1
+android.widget.ViewFlipper$2
+android.widget.ViewSwitcher
+android.widget.WrapperListAdapter
+com.android.framework.protobuf.nano.CodedInputByteBufferNano
+com.android.framework.protobuf.nano.CodedOutputByteBufferNano
+com.android.framework.protobuf.nano.InternalNano
+com.android.framework.protobuf.nano.InvalidProtocolBufferNanoException
+com.android.framework.protobuf.nano.MessageNano
+com.android.framework.protobuf.nano.WireFormatNano
+com.android.i18n.phonenumbers.AlternateFormatsCountryCodeSet
+com.android.i18n.phonenumbers.AsYouTypeFormatter
+com.android.i18n.phonenumbers.CountryCodeToRegionCodeMap
+com.android.i18n.phonenumbers.MetadataLoader
+com.android.i18n.phonenumbers.MetadataManager
+com.android.i18n.phonenumbers.MetadataManager$1
+com.android.i18n.phonenumbers.MetadataSource
+com.android.i18n.phonenumbers.MultiFileMetadataSourceImpl
+com.android.i18n.phonenumbers.NumberParseException
+com.android.i18n.phonenumbers.NumberParseException$ErrorType
+com.android.i18n.phonenumbers.PhoneNumberMatcher
+com.android.i18n.phonenumbers.PhoneNumberMatcher$State
+com.android.i18n.phonenumbers.PhoneNumberUtil
+com.android.i18n.phonenumbers.PhoneNumberUtil$1
+com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency
+com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency$1
+com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency$2
+com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency$3
+com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency$4
+com.android.i18n.phonenumbers.PhoneNumberUtil$PhoneNumberFormat
+com.android.i18n.phonenumbers.PhoneNumberUtil$PhoneNumberType
+com.android.i18n.phonenumbers.PhoneNumberUtil$ValidationResult
+com.android.i18n.phonenumbers.Phonemetadata$NumberFormat
+com.android.i18n.phonenumbers.Phonemetadata$PhoneMetadata
+com.android.i18n.phonenumbers.Phonemetadata$PhoneMetadataCollection
+com.android.i18n.phonenumbers.Phonemetadata$PhoneNumberDesc
+com.android.i18n.phonenumbers.Phonenumber$PhoneNumber
+com.android.i18n.phonenumbers.Phonenumber$PhoneNumber$CountryCodeSource
+com.android.i18n.phonenumbers.RegexCache
+com.android.i18n.phonenumbers.RegexCache$LRUCache
+com.android.i18n.phonenumbers.RegexCache$LRUCache$1
+com.android.i18n.phonenumbers.ShortNumbersRegionCodeSet
+com.android.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder
+com.android.i18n.phonenumbers.prefixmapper.MappingFileProvider
+com.android.i18n.phonenumbers.prefixmapper.PrefixFileReader
+com.android.ims.-$Lambda$AvFHcs3Z6Dq6dkOugMW9Kc7Qzng$4
+com.android.ims.ImsCall$Listener
+com.android.ims.ImsCallForwardInfo
+com.android.ims.ImsCallProfile
+com.android.ims.ImsConfig
+com.android.ims.ImsConfigListener
+com.android.ims.ImsConfigListener$Stub
+com.android.ims.ImsConnectionStateListener
+com.android.ims.ImsEcbm
+com.android.ims.ImsEcbm$ImsEcbmListenerProxy
+com.android.ims.ImsEcbmStateListener
+com.android.ims.ImsException
+com.android.ims.ImsExternalCallStateListener
+com.android.ims.ImsManager
+com.android.ims.ImsManager$1
+com.android.ims.ImsManager$ImsRegistrationListenerProxy
+com.android.ims.ImsManager$ImsServiceDeathRecipient
+com.android.ims.ImsReasonInfo
+com.android.ims.ImsReasonInfo$1
+com.android.ims.ImsSsInfo
+com.android.ims.internal.IImsCallSession
+com.android.ims.internal.IImsCallSessionListener
+com.android.ims.internal.IImsConfig
+com.android.ims.internal.IImsConfig$Stub
+com.android.ims.internal.IImsEcbm
+com.android.ims.internal.IImsEcbm$Stub
+com.android.ims.internal.IImsEcbmListener
+com.android.ims.internal.IImsEcbmListener$Stub
+com.android.ims.internal.IImsMultiEndpoint
+com.android.ims.internal.IImsRegistrationListener
+com.android.ims.internal.IImsRegistrationListener$Stub
+com.android.ims.internal.IImsService
+com.android.ims.internal.IImsService$Stub
+com.android.ims.internal.IImsServiceController
+com.android.ims.internal.IImsServiceFeatureCallback
+com.android.ims.internal.IImsUt
+com.android.ims.internal.IImsUt$Stub
+com.android.ims.internal.IImsUtListener
+com.android.ims.internal.IImsUtListener$Stub
+com.android.internal.R$styleable
+com.android.internal.alsa.AlsaCardsParser
+com.android.internal.alsa.AlsaCardsParser$AlsaCardRecord
+com.android.internal.alsa.AlsaDevicesParser
+com.android.internal.alsa.LineTokenizer
+com.android.internal.app.AlertController
+com.android.internal.app.AlertController$1
+com.android.internal.app.AlertController$AlertParams
+com.android.internal.app.AlertController$AlertParams$1
+com.android.internal.app.AlertController$AlertParams$4
+com.android.internal.app.AlertController$ButtonHandler
+com.android.internal.app.AlertController$RecycleListView
+com.android.internal.app.AssistUtils
+com.android.internal.app.IAppOpsCallback
+com.android.internal.app.IAppOpsCallback$Stub
+com.android.internal.app.IAppOpsCallback$Stub$Proxy
+com.android.internal.app.IAppOpsService
+com.android.internal.app.IAppOpsService$Stub
+com.android.internal.app.IAppOpsService$Stub$Proxy
+com.android.internal.app.IAssistScreenshotReceiver
+com.android.internal.app.IBatteryStats
+com.android.internal.app.IBatteryStats$Stub
+com.android.internal.app.IBatteryStats$Stub$Proxy
+com.android.internal.app.IMediaContainerService
+com.android.internal.app.IMediaContainerService$Stub
+com.android.internal.app.IMediaContainerService$Stub$Proxy
+com.android.internal.app.ISoundTriggerService
+com.android.internal.app.ISoundTriggerService$Stub
+com.android.internal.app.IVoiceInteractionManagerService
+com.android.internal.app.IVoiceInteractionManagerService$Stub
+com.android.internal.app.IVoiceInteractionManagerService$Stub$Proxy
+com.android.internal.app.IVoiceInteractionSessionListener
+com.android.internal.app.IVoiceInteractionSessionListener$Stub
+com.android.internal.app.IVoiceInteractionSessionListener$Stub$Proxy
+com.android.internal.app.IVoiceInteractionSessionShowCallback
+com.android.internal.app.IVoiceInteractionSessionShowCallback$Stub
+com.android.internal.app.IVoiceInteractor
+com.android.internal.app.IVoiceInteractor$Stub
+com.android.internal.app.NightDisplayController
+com.android.internal.app.NightDisplayController$Callback
+com.android.internal.app.NightDisplayController$LocalTime
+com.android.internal.app.ProcessMap
+com.android.internal.app.ResolverActivity
+com.android.internal.app.ToolbarActionBar
+com.android.internal.app.ToolbarActionBar$1
+com.android.internal.app.ToolbarActionBar$2
+com.android.internal.app.ToolbarActionBar$ActionMenuPresenterCallback
+com.android.internal.app.ToolbarActionBar$MenuBuilderCallback
+com.android.internal.app.ToolbarActionBar$ToolbarCallbackWrapper
+com.android.internal.app.WindowDecorActionBar
+com.android.internal.app.WindowDecorActionBar$1
+com.android.internal.app.WindowDecorActionBar$2
+com.android.internal.app.WindowDecorActionBar$3
+com.android.internal.app.WindowDecorActionBar$ActionModeImpl
+com.android.internal.app.procstats.DurationsTable
+com.android.internal.app.procstats.IProcessStats
+com.android.internal.app.procstats.IProcessStats$Stub
+com.android.internal.app.procstats.ProcessState
+com.android.internal.app.procstats.ProcessState$1
+com.android.internal.app.procstats.ProcessStats
+com.android.internal.app.procstats.ProcessStats$1
+com.android.internal.app.procstats.ProcessStats$PackageState
+com.android.internal.app.procstats.ProcessStats$ProcessStateHolder
+com.android.internal.app.procstats.PssTable
+com.android.internal.app.procstats.ServiceState
+com.android.internal.app.procstats.SparseMappingTable
+com.android.internal.app.procstats.SparseMappingTable$Table
+com.android.internal.app.procstats.SysMemUsageTable
+com.android.internal.appwidget.IAppWidgetHost
+com.android.internal.appwidget.IAppWidgetHost$Stub
+com.android.internal.appwidget.IAppWidgetHost$Stub$Proxy
+com.android.internal.appwidget.IAppWidgetService
+com.android.internal.appwidget.IAppWidgetService$Stub
+com.android.internal.appwidget.IAppWidgetService$Stub$Proxy
+com.android.internal.backup.IBackupTransport
+com.android.internal.backup.IBackupTransport$Stub
+com.android.internal.backup.IBackupTransport$Stub$Proxy
+com.android.internal.backup.LocalTransport
+com.android.internal.backup.LocalTransportService
+com.android.internal.content.FileSystemProvider
+com.android.internal.content.NativeLibraryHelper
+com.android.internal.content.NativeLibraryHelper$Handle
+com.android.internal.content.PackageHelper
+com.android.internal.content.PackageHelper$1
+com.android.internal.content.PackageHelper$TestableInterface
+com.android.internal.content.PackageMonitor
+com.android.internal.content.ReferrerIntent
+com.android.internal.content.ReferrerIntent$1
+com.android.internal.graphics.drawable.AnimationScaleListDrawable
+com.android.internal.graphics.drawable.AnimationScaleListDrawable$AnimationScaleListState
+com.android.internal.hardware.AmbientDisplayConfiguration
+com.android.internal.inputmethod.IInputContentUriToken
+com.android.internal.inputmethod.InputMethodSubtypeHandle
+com.android.internal.inputmethod.InputMethodSubtypeSwitchingController
+com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$ControllerImpl
+com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$DynamicRotationList
+com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$ImeSubtypeListItem
+com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$InputMethodAndSubtypeList
+com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$InputMethodAndSubtypeList$1
+com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$StaticRotationList
+com.android.internal.inputmethod.InputMethodUtils
+com.android.internal.inputmethod.InputMethodUtils$1
+com.android.internal.inputmethod.InputMethodUtils$InputMethodListBuilder
+com.android.internal.inputmethod.InputMethodUtils$InputMethodSettings
+com.android.internal.inputmethod.LocaleUtils
+com.android.internal.inputmethod.LocaleUtils$LocaleExtractor
+com.android.internal.inputmethod.LocaleUtils$ScoreEntry
+com.android.internal.location.GpsNetInitiatedHandler
+com.android.internal.location.GpsNetInitiatedHandler$1
+com.android.internal.location.GpsNetInitiatedHandler$2
+com.android.internal.location.ILocationProvider
+com.android.internal.location.ILocationProvider$Stub
+com.android.internal.location.ILocationProvider$Stub$Proxy
+com.android.internal.location.ProviderProperties
+com.android.internal.location.ProviderProperties$1
+com.android.internal.location.ProviderRequest
+com.android.internal.location.ProviderRequest$1
+com.android.internal.logging.AndroidConfig
+com.android.internal.logging.AndroidHandler
+com.android.internal.logging.AndroidHandler$1
+com.android.internal.logging.EventLogTags
+com.android.internal.logging.MetricsLogger
+com.android.internal.net.LegacyVpnInfo
+com.android.internal.net.NetworkStatsFactory
+com.android.internal.net.VpnConfig
+com.android.internal.net.VpnInfo
+com.android.internal.net.VpnProfile
+com.android.internal.notification.SystemNotificationChannels
+com.android.internal.os.AndroidPrintStream
+com.android.internal.os.AppFuseMount
+com.android.internal.os.AtomicFile
+com.android.internal.os.BackgroundThread
+com.android.internal.os.BatteryStatsHelper
+com.android.internal.os.BatteryStatsImpl
+com.android.internal.os.BatteryStatsImpl$1
+com.android.internal.os.BatteryStatsImpl$6
+com.android.internal.os.BatteryStatsImpl$BatchTimer
+com.android.internal.os.BatteryStatsImpl$BatteryCallback
+com.android.internal.os.BatteryStatsImpl$Clocks
+com.android.internal.os.BatteryStatsImpl$ControllerActivityCounterImpl
+com.android.internal.os.BatteryStatsImpl$Counter
+com.android.internal.os.BatteryStatsImpl$DualTimer
+com.android.internal.os.BatteryStatsImpl$DurationTimer
+com.android.internal.os.BatteryStatsImpl$ExternalStatsSync
+com.android.internal.os.BatteryStatsImpl$LongSamplingCounter
+com.android.internal.os.BatteryStatsImpl$LongSamplingCounterArray
+com.android.internal.os.BatteryStatsImpl$MyHandler
+com.android.internal.os.BatteryStatsImpl$OverflowArrayMap
+com.android.internal.os.BatteryStatsImpl$PlatformIdleStateCallback
+com.android.internal.os.BatteryStatsImpl$SamplingTimer
+com.android.internal.os.BatteryStatsImpl$StopwatchTimer
+com.android.internal.os.BatteryStatsImpl$SystemClocks
+com.android.internal.os.BatteryStatsImpl$TimeBase
+com.android.internal.os.BatteryStatsImpl$TimeBaseObs
+com.android.internal.os.BatteryStatsImpl$Timer
+com.android.internal.os.BatteryStatsImpl$Uid
+com.android.internal.os.BatteryStatsImpl$Uid$1
+com.android.internal.os.BatteryStatsImpl$Uid$2
+com.android.internal.os.BatteryStatsImpl$Uid$3
+com.android.internal.os.BatteryStatsImpl$Uid$Pkg
+com.android.internal.os.BatteryStatsImpl$Uid$Pkg$Serv
+com.android.internal.os.BatteryStatsImpl$Uid$Sensor
+com.android.internal.os.BatteryStatsImpl$Uid$Wakelock
+com.android.internal.os.BinderInternal
+com.android.internal.os.BinderInternal$GcWatcher
+com.android.internal.os.FuseAppLoop
+com.android.internal.os.FuseAppLoop$1
+com.android.internal.os.FuseUnavailableMountException
+com.android.internal.os.HandlerCaller
+com.android.internal.os.HandlerCaller$Callback
+com.android.internal.os.HandlerCaller$MyHandler
+com.android.internal.os.IDropBoxManagerService
+com.android.internal.os.IDropBoxManagerService$Stub
+com.android.internal.os.IDropBoxManagerService$Stub$Proxy
+com.android.internal.os.IResultReceiver
+com.android.internal.os.IResultReceiver$Stub
+com.android.internal.os.IResultReceiver$Stub$Proxy
+com.android.internal.os.KernelCpuSpeedReader
+com.android.internal.os.KernelMemoryBandwidthStats
+com.android.internal.os.KernelUidCpuFreqTimeReader
+com.android.internal.os.KernelUidCpuTimeReader
+com.android.internal.os.KernelWakelockReader
+com.android.internal.os.KernelWakelockStats
+com.android.internal.os.KernelWakelockStats$Entry
+com.android.internal.os.LoggingPrintStream
+com.android.internal.os.LoggingPrintStream$1
+com.android.internal.os.PathClassLoaderFactory
+com.android.internal.os.PowerProfile
+com.android.internal.os.PowerProfile$CpuClusterKey
+com.android.internal.os.ProcessCpuTracker
+com.android.internal.os.ProcessCpuTracker$1
+com.android.internal.os.ProcessCpuTracker$FilterStats
+com.android.internal.os.ProcessCpuTracker$Stats
+com.android.internal.os.RoSystemProperties
+com.android.internal.os.RuntimeInit
+com.android.internal.os.RuntimeInit$1
+com.android.internal.os.RuntimeInit$Arguments
+com.android.internal.os.RuntimeInit$KillApplicationHandler
+com.android.internal.os.RuntimeInit$LoggingHandler
+com.android.internal.os.SamplingProfilerIntegration
+com.android.internal.os.SomeArgs
+com.android.internal.os.Zygote
+com.android.internal.os.Zygote$MethodAndArgsCaller
+com.android.internal.os.ZygoteConnection
+com.android.internal.os.ZygoteConnection$Arguments
+com.android.internal.os.ZygoteInit
+com.android.internal.os.ZygoteSecurityException
+com.android.internal.os.ZygoteServer
+com.android.internal.policy.DecorContext
+com.android.internal.policy.DecorView
+com.android.internal.policy.DecorView$1
+com.android.internal.policy.DecorView$ActionModeCallback2Wrapper
+com.android.internal.policy.DecorView$ColorViewAttributes
+com.android.internal.policy.DecorView$ColorViewState
+com.android.internal.policy.DividerSnapAlgorithm
+com.android.internal.policy.DividerSnapAlgorithm$SnapTarget
+com.android.internal.policy.DockedDividerUtils
+com.android.internal.policy.IKeyguardDismissCallback
+com.android.internal.policy.IKeyguardDrawnCallback
+com.android.internal.policy.IKeyguardDrawnCallback$Stub
+com.android.internal.policy.IKeyguardDrawnCallback$Stub$Proxy
+com.android.internal.policy.IKeyguardExitCallback
+com.android.internal.policy.IKeyguardService
+com.android.internal.policy.IKeyguardService$Stub
+com.android.internal.policy.IKeyguardService$Stub$Proxy
+com.android.internal.policy.IKeyguardStateCallback
+com.android.internal.policy.IKeyguardStateCallback$Stub
+com.android.internal.policy.IKeyguardStateCallback$Stub$Proxy
+com.android.internal.policy.IShortcutService
+com.android.internal.policy.IShortcutService$Stub
+com.android.internal.policy.IShortcutService$Stub$Proxy
+com.android.internal.policy.PhoneFallbackEventHandler
+com.android.internal.policy.PhoneLayoutInflater
+com.android.internal.policy.PhoneWindow
+com.android.internal.policy.PhoneWindow$1
+com.android.internal.policy.PhoneWindow$ActionMenuPresenterCallback
+com.android.internal.policy.PhoneWindow$PanelFeatureState
+com.android.internal.policy.PhoneWindow$PhoneWindowMenuCallback
+com.android.internal.policy.PhoneWindow$RotationWatcher
+com.android.internal.policy.PhoneWindow$RotationWatcher$1
+com.android.internal.policy.PipSnapAlgorithm
+com.android.internal.statusbar.IStatusBar
+com.android.internal.statusbar.IStatusBar$Stub
+com.android.internal.statusbar.IStatusBar$Stub$Proxy
+com.android.internal.statusbar.IStatusBarService
+com.android.internal.statusbar.IStatusBarService$Stub
+com.android.internal.statusbar.IStatusBarService$Stub$Proxy
+com.android.internal.statusbar.NotificationVisibility
+com.android.internal.statusbar.NotificationVisibility$1
+com.android.internal.statusbar.StatusBarIcon
+com.android.internal.statusbar.StatusBarIcon$1
+com.android.internal.telecom.IConnectionService
+com.android.internal.telecom.IConnectionService$Stub
+com.android.internal.telecom.IConnectionService$Stub$Proxy
+com.android.internal.telecom.IConnectionServiceAdapter
+com.android.internal.telecom.IConnectionServiceAdapter$Stub
+com.android.internal.telecom.IConnectionServiceAdapter$Stub$Proxy
+com.android.internal.telecom.IInCallAdapter
+com.android.internal.telecom.IInCallAdapter$Stub
+com.android.internal.telecom.IInCallService
+com.android.internal.telecom.IInCallService$Stub
+com.android.internal.telecom.IInCallService$Stub$Proxy
+com.android.internal.telecom.ITelecomService
+com.android.internal.telecom.ITelecomService$Stub
+com.android.internal.telecom.ITelecomService$Stub$Proxy
+com.android.internal.telecom.IVideoProvider
+com.android.internal.telecom.IVideoProvider$Stub
+com.android.internal.telecom.RemoteServiceCallback
+com.android.internal.telecom.RemoteServiceCallback$Stub
+com.android.internal.telecom.RemoteServiceCallback$Stub$Proxy
+com.android.internal.telephony.AppSmsManager
+com.android.internal.telephony.BaseCommands
+com.android.internal.telephony.Call
+com.android.internal.telephony.Call$SrvccState
+com.android.internal.telephony.Call$State
+com.android.internal.telephony.CallManager
+com.android.internal.telephony.CallManager$CallManagerHandler
+com.android.internal.telephony.CallStateException
+com.android.internal.telephony.CallTracker
+com.android.internal.telephony.CallerInfo
+com.android.internal.telephony.CallerInfoAsyncQuery
+com.android.internal.telephony.CallerInfoAsyncQuery$CallerInfoAsyncQueryHandler
+com.android.internal.telephony.CallerInfoAsyncQuery$CallerInfoAsyncQueryHandler$CallerInfoWorkerHandler
+com.android.internal.telephony.CallerInfoAsyncQuery$CookieWrapper
+com.android.internal.telephony.CallerInfoAsyncQuery$OnQueryCompleteListener
+com.android.internal.telephony.CarrierActionAgent
+com.android.internal.telephony.CarrierActionAgent$1
+com.android.internal.telephony.CarrierActionAgent$SettingsObserver
+com.android.internal.telephony.CarrierAppUtils
+com.android.internal.telephony.CarrierServiceBindHelper
+com.android.internal.telephony.CarrierServiceBindHelper$1
+com.android.internal.telephony.CarrierServiceBindHelper$2
+com.android.internal.telephony.CarrierServiceBindHelper$AppBinding
+com.android.internal.telephony.CarrierServiceBindHelper$CarrierServicePackageMonitor
+com.android.internal.telephony.CarrierServiceStateTracker
+com.android.internal.telephony.CarrierServiceStateTracker$1
+com.android.internal.telephony.CarrierSignalAgent
+com.android.internal.telephony.CarrierSignalAgent$1
+com.android.internal.telephony.CellBroadcastHandler
+com.android.internal.telephony.CellNetworkScanResult
+com.android.internal.telephony.ClientWakelockAccountant
+com.android.internal.telephony.ClientWakelockTracker
+com.android.internal.telephony.CommandException
+com.android.internal.telephony.CommandException$Error
+com.android.internal.telephony.CommandsInterface
+com.android.internal.telephony.CommandsInterface$RadioState
+com.android.internal.telephony.Connection
+com.android.internal.telephony.DctConstants$Activity
+com.android.internal.telephony.DctConstants$State
+com.android.internal.telephony.DebugService
+com.android.internal.telephony.DefaultPhoneNotifier
+com.android.internal.telephony.DeviceStateMonitor
+com.android.internal.telephony.DeviceStateMonitor$1
+com.android.internal.telephony.DeviceStateMonitor$2
+com.android.internal.telephony.EncodeException
+com.android.internal.telephony.GsmAlphabet
+com.android.internal.telephony.GsmAlphabet$TextEncodingDetails
+com.android.internal.telephony.GsmCdmaCall
+com.android.internal.telephony.GsmCdmaCallTracker
+com.android.internal.telephony.GsmCdmaCallTracker$1
+com.android.internal.telephony.GsmCdmaConnection
+com.android.internal.telephony.GsmCdmaPhone
+com.android.internal.telephony.GsmCdmaPhone$1
+com.android.internal.telephony.GsmCdmaPhone$2
+com.android.internal.telephony.HardwareConfig
+com.android.internal.telephony.ICarrierConfigLoader
+com.android.internal.telephony.ICarrierConfigLoader$Stub
+com.android.internal.telephony.ICarrierConfigLoader$Stub$Proxy
+com.android.internal.telephony.IIccPhoneBook
+com.android.internal.telephony.IIccPhoneBook$Stub
+com.android.internal.telephony.IMms
+com.android.internal.telephony.IMms$Stub
+com.android.internal.telephony.IOnSubscriptionsChangedListener
+com.android.internal.telephony.IOnSubscriptionsChangedListener$Stub
+com.android.internal.telephony.IOnSubscriptionsChangedListener$Stub$Proxy
+com.android.internal.telephony.IPhoneStateListener
+com.android.internal.telephony.IPhoneStateListener$Stub
+com.android.internal.telephony.IPhoneStateListener$Stub$Proxy
+com.android.internal.telephony.IPhoneSubInfo
+com.android.internal.telephony.IPhoneSubInfo$Stub
+com.android.internal.telephony.IPhoneSubInfo$Stub$Proxy
+com.android.internal.telephony.ISms
+com.android.internal.telephony.ISms$Stub
+com.android.internal.telephony.ISms$Stub$Proxy
+com.android.internal.telephony.ISub
+com.android.internal.telephony.ISub$Stub
+com.android.internal.telephony.ISub$Stub$Proxy
+com.android.internal.telephony.ITelephony
+com.android.internal.telephony.ITelephony$Stub
+com.android.internal.telephony.ITelephony$Stub$Proxy
+com.android.internal.telephony.ITelephonyRegistry
+com.android.internal.telephony.ITelephonyRegistry$Stub
+com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy
+com.android.internal.telephony.IWapPushManager
+com.android.internal.telephony.IccCard
+com.android.internal.telephony.IccCardConstants$State
+com.android.internal.telephony.IccPhoneBookInterfaceManager
+com.android.internal.telephony.IccPhoneBookInterfaceManager$1
+com.android.internal.telephony.IccProvider
+com.android.internal.telephony.IccSmsInterfaceManager
+com.android.internal.telephony.IccSmsInterfaceManager$1
+com.android.internal.telephony.IccSmsInterfaceManager$CdmaBroadcastRangeManager
+com.android.internal.telephony.IccSmsInterfaceManager$CellBroadcastRangeManager
+com.android.internal.telephony.ImsSMSDispatcher
+com.android.internal.telephony.InboundSmsHandler
+com.android.internal.telephony.InboundSmsHandler$1
+com.android.internal.telephony.InboundSmsHandler$DefaultState
+com.android.internal.telephony.InboundSmsHandler$DeliveringState
+com.android.internal.telephony.InboundSmsHandler$IdleState
+com.android.internal.telephony.InboundSmsHandler$NewMessageNotificationActionReceiver
+com.android.internal.telephony.InboundSmsHandler$StartupState
+com.android.internal.telephony.InboundSmsHandler$WaitingState
+com.android.internal.telephony.IntRangeManager
+com.android.internal.telephony.OemHookIndication
+com.android.internal.telephony.OemHookResponse
+com.android.internal.telephony.OperatorInfo
+com.android.internal.telephony.Phone
+com.android.internal.telephony.Phone$1
+com.android.internal.telephony.PhoneConstantConversions
+com.android.internal.telephony.PhoneConstants$DataState
+com.android.internal.telephony.PhoneConstants$State
+com.android.internal.telephony.PhoneFactory
+com.android.internal.telephony.PhoneInternalInterface
+com.android.internal.telephony.PhoneInternalInterface$DataActivityState
+com.android.internal.telephony.PhoneNotifier
+com.android.internal.telephony.PhoneSubInfoController
+com.android.internal.telephony.PhoneSwitcher
+com.android.internal.telephony.PhoneSwitcher$1
+com.android.internal.telephony.PhoneSwitcher$2
+com.android.internal.telephony.PhoneSwitcher$PhoneState
+com.android.internal.telephony.PhoneSwitcher$PhoneSwitcherNetworkRequestListener
+com.android.internal.telephony.ProxyController
+com.android.internal.telephony.ProxyController$1
+com.android.internal.telephony.RIL
+com.android.internal.telephony.RIL$RadioProxyDeathRecipient
+com.android.internal.telephony.RIL$RilHandler
+com.android.internal.telephony.RILConstants
+com.android.internal.telephony.RILRequest
+com.android.internal.telephony.RadioCapability
+com.android.internal.telephony.RadioIndication
+com.android.internal.telephony.RadioResponse
+com.android.internal.telephony.RatRatcheter
+com.android.internal.telephony.RatRatcheter$1
+com.android.internal.telephony.RestrictedState
+com.android.internal.telephony.RetryManager
+com.android.internal.telephony.RilWakelockInfo
+com.android.internal.telephony.SMSDispatcher
+com.android.internal.telephony.SMSDispatcher$SettingsObserver
+com.android.internal.telephony.ServiceStateTracker
+com.android.internal.telephony.ServiceStateTracker$1
+com.android.internal.telephony.ServiceStateTracker$2
+com.android.internal.telephony.ServiceStateTracker$3
+com.android.internal.telephony.ServiceStateTracker$CellInfoResult
+com.android.internal.telephony.ServiceStateTracker$SstSubscriptionsChangedListener
+com.android.internal.telephony.SimActivationTracker
+com.android.internal.telephony.SimActivationTracker$1
+com.android.internal.telephony.SmsApplication
+com.android.internal.telephony.SmsApplication$SmsApplicationData
+com.android.internal.telephony.SmsApplication$SmsPackageMonitor
+com.android.internal.telephony.SmsBroadcastUndelivered
+com.android.internal.telephony.SmsBroadcastUndelivered$1
+com.android.internal.telephony.SmsBroadcastUndelivered$ScanRawTableThread
+com.android.internal.telephony.SmsMessageBase
+com.android.internal.telephony.SmsStorageMonitor
+com.android.internal.telephony.SmsStorageMonitor$1
+com.android.internal.telephony.SmsUsageMonitor
+com.android.internal.telephony.SmsUsageMonitor$SettingsObserver
+com.android.internal.telephony.SmsUsageMonitor$SettingsObserverHandler
+com.android.internal.telephony.SubscriptionController
+com.android.internal.telephony.SubscriptionController$ScLocalLog
+com.android.internal.telephony.SubscriptionInfoUpdater
+com.android.internal.telephony.SubscriptionInfoUpdater$1
+com.android.internal.telephony.SubscriptionInfoUpdater$2
+com.android.internal.telephony.SubscriptionMonitor
+com.android.internal.telephony.SubscriptionMonitor$1
+com.android.internal.telephony.SubscriptionMonitor$2
+com.android.internal.telephony.TelephonyCapabilities
+com.android.internal.telephony.TelephonyComponentFactory
+com.android.internal.telephony.TelephonyDevController
+com.android.internal.telephony.TelephonyTester
+com.android.internal.telephony.TelephonyTester$1
+com.android.internal.telephony.UiccPhoneBookController
+com.android.internal.telephony.UiccSmsController
+com.android.internal.telephony.WakeLockStateMachine
+com.android.internal.telephony.WakeLockStateMachine$1
+com.android.internal.telephony.WakeLockStateMachine$DefaultState
+com.android.internal.telephony.WakeLockStateMachine$IdleState
+com.android.internal.telephony.WakeLockStateMachine$WaitingState
+com.android.internal.telephony.WapPushOverSms
+com.android.internal.telephony.WapPushOverSms$1
+com.android.internal.telephony.WapPushOverSms$BindServiceThread
+com.android.internal.telephony.cat.AppInterface
+com.android.internal.telephony.cat.CatLog
+com.android.internal.telephony.cat.CatService
+com.android.internal.telephony.cdma.CdmaInboundSmsHandler
+com.android.internal.telephony.cdma.CdmaSMSDispatcher
+com.android.internal.telephony.cdma.CdmaServiceCategoryProgramHandler
+com.android.internal.telephony.cdma.CdmaServiceCategoryProgramHandler$1
+com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager
+com.android.internal.telephony.cdma.EriInfo
+com.android.internal.telephony.cdma.EriManager
+com.android.internal.telephony.cdma.EriManager$EriFile
+com.android.internal.telephony.dataconnection.ApnContext
+com.android.internal.telephony.dataconnection.DataConnection
+com.android.internal.telephony.dataconnection.DataEnabledSettings
+com.android.internal.telephony.dataconnection.DcController
+com.android.internal.telephony.dataconnection.DcController$1
+com.android.internal.telephony.dataconnection.DcController$DccDefaultState
+com.android.internal.telephony.dataconnection.DcFailBringUp
+com.android.internal.telephony.dataconnection.DcFailCause
+com.android.internal.telephony.dataconnection.DcRequest
+com.android.internal.telephony.dataconnection.DcTesterDeactivateAll
+com.android.internal.telephony.dataconnection.DcTesterDeactivateAll$1
+com.android.internal.telephony.dataconnection.DcTesterFailBringUpAll
+com.android.internal.telephony.dataconnection.DcTesterFailBringUpAll$1
+com.android.internal.telephony.dataconnection.DcTracker
+com.android.internal.telephony.dataconnection.DcTracker$1
+com.android.internal.telephony.dataconnection.DcTracker$2
+com.android.internal.telephony.dataconnection.DcTracker$3
+com.android.internal.telephony.dataconnection.DcTracker$4
+com.android.internal.telephony.dataconnection.DcTracker$ApnChangeObserver
+com.android.internal.telephony.dataconnection.DcTracker$DataAllowFailReason
+com.android.internal.telephony.dataconnection.DcTracker$DataAllowFailReasonType
+com.android.internal.telephony.dataconnection.DcTracker$RetryFailures
+com.android.internal.telephony.dataconnection.DcTracker$SettingsObserver
+com.android.internal.telephony.dataconnection.DcTracker$TxRxSum
+com.android.internal.telephony.dataconnection.TelephonyNetworkFactory
+com.android.internal.telephony.dataconnection.TelephonyNetworkFactory$InternalHandler
+com.android.internal.telephony.gsm.GsmCellBroadcastHandler
+com.android.internal.telephony.gsm.GsmInboundSmsHandler
+com.android.internal.telephony.gsm.GsmSMSDispatcher
+com.android.internal.telephony.gsm.SmsMessage
+com.android.internal.telephony.gsm.UsimDataDownloadHandler
+com.android.internal.telephony.ims.-$Lambda$6hDwuvYxqWrzW_Ex5wc53XnUOpg
+com.android.internal.telephony.ims.-$Lambda$6hDwuvYxqWrzW_Ex5wc53XnUOpg$1
+com.android.internal.telephony.ims.-$Lambda$6hDwuvYxqWrzW_Ex5wc53XnUOpg$2
+com.android.internal.telephony.ims.ImsResolver
+com.android.internal.telephony.ims.ImsResolver$1
+com.android.internal.telephony.ims.ImsResolver$2
+com.android.internal.telephony.ims.ImsResolver$3
+com.android.internal.telephony.ims.ImsResolver$ImsServiceControllerFactory
+com.android.internal.telephony.ims.ImsResolver$SubscriptionManagerProxy
+com.android.internal.telephony.ims.ImsServiceController$ImsServiceControllerCallbacks
+com.android.internal.telephony.imsphone.-$Lambda$tILLuSJl16qfDJK1ikBVGFm2D5w
+com.android.internal.telephony.imsphone.-$Lambda$tILLuSJl16qfDJK1ikBVGFm2D5w$1
+com.android.internal.telephony.imsphone.ImsExternalCallTracker
+com.android.internal.telephony.imsphone.ImsExternalCallTracker$1
+com.android.internal.telephony.imsphone.ImsExternalCallTracker$2
+com.android.internal.telephony.imsphone.ImsExternalCallTracker$ExternalCallStateListener
+com.android.internal.telephony.imsphone.ImsExternalCallTracker$ExternalConnectionListener
+com.android.internal.telephony.imsphone.ImsExternalCallTracker$ImsCallNotify
+com.android.internal.telephony.imsphone.ImsExternalConnection$Listener
+com.android.internal.telephony.imsphone.ImsPhone
+com.android.internal.telephony.imsphone.ImsPhone$1
+com.android.internal.telephony.imsphone.ImsPhone$2
+com.android.internal.telephony.imsphone.ImsPhone$3
+com.android.internal.telephony.imsphone.ImsPhoneBase
+com.android.internal.telephony.imsphone.ImsPhoneCall
+com.android.internal.telephony.imsphone.ImsPhoneCallTracker
+com.android.internal.telephony.imsphone.ImsPhoneCallTracker$1
+com.android.internal.telephony.imsphone.ImsPhoneCallTracker$2
+com.android.internal.telephony.imsphone.ImsPhoneCallTracker$3
+com.android.internal.telephony.imsphone.ImsPhoneCallTracker$4
+com.android.internal.telephony.imsphone.ImsPhoneCallTracker$5
+com.android.internal.telephony.imsphone.ImsPhoneCallTracker$IRetryTimeout
+com.android.internal.telephony.imsphone.ImsPhoneCallTracker$PhoneStateListener
+com.android.internal.telephony.imsphone.ImsPhoneCommandInterface
+com.android.internal.telephony.imsphone.ImsPhoneFactory
+com.android.internal.telephony.imsphone.ImsPullCall
+com.android.internal.telephony.metrics.CallSessionEventBuilder
+com.android.internal.telephony.metrics.InProgressCallSession
+com.android.internal.telephony.metrics.InProgressSmsSession
+com.android.internal.telephony.metrics.SmsSessionEventBuilder
+com.android.internal.telephony.metrics.TelephonyEventBuilder
+com.android.internal.telephony.metrics.TelephonyMetrics
+com.android.internal.telephony.nano.TelephonyProto$ImsCapabilities
+com.android.internal.telephony.nano.TelephonyProto$ImsConnectionState
+com.android.internal.telephony.nano.TelephonyProto$ImsReasonInfo
+com.android.internal.telephony.nano.TelephonyProto$RilDataCall
+com.android.internal.telephony.nano.TelephonyProto$SmsSession$Event
+com.android.internal.telephony.nano.TelephonyProto$TelephonyCallSession$Event
+com.android.internal.telephony.nano.TelephonyProto$TelephonyCallSession$Event$RilCall
+com.android.internal.telephony.nano.TelephonyProto$TelephonyEvent
+com.android.internal.telephony.nano.TelephonyProto$TelephonyServiceState
+com.android.internal.telephony.nano.TelephonyProto$TelephonyServiceState$TelephonyOperator
+com.android.internal.telephony.nano.TelephonyProto$TelephonySettings
+com.android.internal.telephony.protobuf.nano.CodedOutputByteBufferNano
+com.android.internal.telephony.protobuf.nano.ExtendableMessageNano
+com.android.internal.telephony.protobuf.nano.InternalNano
+com.android.internal.telephony.protobuf.nano.InvalidProtocolBufferNanoException
+com.android.internal.telephony.protobuf.nano.MessageNano
+com.android.internal.telephony.protobuf.nano.WireFormatNano
+com.android.internal.telephony.test.SimulatedRadioControl
+com.android.internal.telephony.uicc.IccCardApplicationStatus
+com.android.internal.telephony.uicc.IccCardApplicationStatus$AppType
+com.android.internal.telephony.uicc.IccCardProxy
+com.android.internal.telephony.uicc.IccCardStatus
+com.android.internal.telephony.uicc.IccCardStatus$CardState
+com.android.internal.telephony.uicc.IccCardStatus$PinState
+com.android.internal.telephony.uicc.IccConstants
+com.android.internal.telephony.uicc.IccRecords
+com.android.internal.telephony.uicc.IccUtils
+com.android.internal.telephony.uicc.UiccCard
+com.android.internal.telephony.uicc.UiccCard$1
+com.android.internal.telephony.uicc.UiccCardApplication
+com.android.internal.telephony.uicc.UiccController
+com.android.internal.telephony.uicc.UiccStateChangedLauncher
+com.android.internal.telephony.util.NotificationChannelController
+com.android.internal.telephony.util.NotificationChannelController$1
+com.android.internal.textservice.ISpellCheckerService
+com.android.internal.textservice.ISpellCheckerService$Stub
+com.android.internal.textservice.ISpellCheckerService$Stub$Proxy
+com.android.internal.textservice.ISpellCheckerServiceCallback
+com.android.internal.textservice.ISpellCheckerServiceCallback$Stub
+com.android.internal.textservice.ISpellCheckerServiceCallback$Stub$Proxy
+com.android.internal.textservice.ISpellCheckerSession
+com.android.internal.textservice.ISpellCheckerSession$Stub
+com.android.internal.textservice.ISpellCheckerSession$Stub$Proxy
+com.android.internal.textservice.ISpellCheckerSessionListener
+com.android.internal.textservice.ISpellCheckerSessionListener$Stub
+com.android.internal.textservice.ISpellCheckerSessionListener$Stub$Proxy
+com.android.internal.textservice.ITextServicesManager
+com.android.internal.textservice.ITextServicesManager$Stub
+com.android.internal.textservice.ITextServicesManager$Stub$Proxy
+com.android.internal.textservice.ITextServicesSessionListener
+com.android.internal.textservice.ITextServicesSessionListener$Stub
+com.android.internal.textservice.ITextServicesSessionListener$Stub$Proxy
+com.android.internal.transition.EpicenterTranslateClipReveal
+com.android.internal.transition.TransitionConstants
+com.android.internal.util.ArrayUtils
+com.android.internal.util.AsyncChannel
+com.android.internal.util.AsyncChannel$AsyncChannelConnection
+com.android.internal.util.AsyncChannel$DeathMonitor
+com.android.internal.util.AsyncChannel$SyncMessenger
+com.android.internal.util.AsyncChannel$SyncMessenger$SyncHandler
+com.android.internal.util.BitUtils
+com.android.internal.util.CollectionUtils
+com.android.internal.util.ConcurrentUtils
+com.android.internal.util.ConcurrentUtils$1
+com.android.internal.util.ConcurrentUtils$1$1
+com.android.internal.util.DumpUtils$Dump
+com.android.internal.util.ExponentiallyBucketedHistogram
+com.android.internal.util.FastMath
+com.android.internal.util.FastPrintWriter
+com.android.internal.util.FastPrintWriter$DummyWriter
+com.android.internal.util.FastXmlSerializer
+com.android.internal.util.FileRotator
+com.android.internal.util.FileRotator$FileInfo
+com.android.internal.util.FileRotator$Reader
+com.android.internal.util.FileRotator$Rewriter
+com.android.internal.util.FileRotator$Writer
+com.android.internal.util.GrowingArrayUtils
+com.android.internal.util.HexDump
+com.android.internal.util.IState
+com.android.internal.util.ImageUtils
+com.android.internal.util.IndentingPrintWriter
+com.android.internal.util.IntPair
+com.android.internal.util.JournaledFile
+com.android.internal.util.LineBreakBufferedWriter
+com.android.internal.util.LocalLog
+com.android.internal.util.MemInfoReader
+com.android.internal.util.MessageUtils
+com.android.internal.util.NotificationColorUtil
+com.android.internal.util.NotificationColorUtil$ColorUtilsFromCompat
+com.android.internal.util.NotificationMessagingUtil
+com.android.internal.util.NotificationMessagingUtil$1
+com.android.internal.util.Preconditions
+com.android.internal.util.ProcFileReader
+com.android.internal.util.ProgressReporter
+com.android.internal.util.RingBufferIndices
+com.android.internal.util.ScreenShapeHelper
+com.android.internal.util.State
+com.android.internal.util.StateMachine
+com.android.internal.util.StateMachine$LogRec
+com.android.internal.util.StateMachine$LogRecords
+com.android.internal.util.StateMachine$SmHandler
+com.android.internal.util.StateMachine$SmHandler$HaltingState
+com.android.internal.util.StateMachine$SmHandler$QuittingState
+com.android.internal.util.StateMachine$SmHandler$StateInfo
+com.android.internal.util.ToBooleanFunction
+com.android.internal.util.TokenBucket
+com.android.internal.util.VirtualRefBasePtr
+com.android.internal.util.WakeupMessage
+com.android.internal.util.XmlUtils
+com.android.internal.util.XmlUtils$ReadMapCallback
+com.android.internal.util.XmlUtils$WriteMapCallback
+com.android.internal.view.ActionBarPolicy
+com.android.internal.view.BaseIWindow
+com.android.internal.view.BaseSurfaceHolder
+com.android.internal.view.IInputConnectionWrapper
+com.android.internal.view.IInputConnectionWrapper$MyHandler
+com.android.internal.view.IInputContext
+com.android.internal.view.IInputContext$Stub
+com.android.internal.view.IInputContext$Stub$Proxy
+com.android.internal.view.IInputContextCallback
+com.android.internal.view.IInputContextCallback$Stub
+com.android.internal.view.IInputContextCallback$Stub$Proxy
+com.android.internal.view.IInputMethod
+com.android.internal.view.IInputMethod$Stub
+com.android.internal.view.IInputMethod$Stub$Proxy
+com.android.internal.view.IInputMethodClient
+com.android.internal.view.IInputMethodClient$Stub
+com.android.internal.view.IInputMethodClient$Stub$Proxy
+com.android.internal.view.IInputMethodManager
+com.android.internal.view.IInputMethodManager$Stub
+com.android.internal.view.IInputMethodManager$Stub$Proxy
+com.android.internal.view.IInputMethodSession
+com.android.internal.view.IInputMethodSession$Stub
+com.android.internal.view.IInputMethodSession$Stub$Proxy
+com.android.internal.view.IInputSessionCallback
+com.android.internal.view.IInputSessionCallback$Stub
+com.android.internal.view.IInputSessionCallback$Stub$Proxy
+com.android.internal.view.InputBindResult
+com.android.internal.view.InputBindResult$1
+com.android.internal.view.InputConnectionWrapper
+com.android.internal.view.InputConnectionWrapper$InputContextCallback
+com.android.internal.view.OneShotPreDrawListener
+com.android.internal.view.RootViewSurfaceTaker
+com.android.internal.view.RotationPolicy
+com.android.internal.view.RotationPolicy$RotationPolicyListener
+com.android.internal.view.RotationPolicy$RotationPolicyListener$1
+com.android.internal.view.SurfaceCallbackHelper
+com.android.internal.view.SurfaceCallbackHelper$1
+com.android.internal.view.SurfaceFlingerVsyncChoreographer
+com.android.internal.view.WindowManagerPolicyThread
+com.android.internal.view.animation.FallbackLUTInterpolator
+com.android.internal.view.animation.HasNativeInterpolator
+com.android.internal.view.animation.NativeInterpolatorFactory
+com.android.internal.view.animation.NativeInterpolatorFactoryHelper
+com.android.internal.view.menu.ActionMenuItem
+com.android.internal.view.menu.ActionMenuItemView
+com.android.internal.view.menu.ActionMenuItemView$PopupCallback
+com.android.internal.view.menu.BaseMenuPresenter
+com.android.internal.view.menu.ContextMenuBuilder
+com.android.internal.view.menu.MenuBuilder
+com.android.internal.view.menu.MenuBuilder$Callback
+com.android.internal.view.menu.MenuBuilder$ItemInvoker
+com.android.internal.view.menu.MenuHelper
+com.android.internal.view.menu.MenuItemImpl
+com.android.internal.view.menu.MenuPopupHelper
+com.android.internal.view.menu.MenuPopupHelper$1
+com.android.internal.view.menu.MenuPresenter
+com.android.internal.view.menu.MenuPresenter$Callback
+com.android.internal.view.menu.MenuView
+com.android.internal.view.menu.MenuView$ItemView
+com.android.internal.view.menu.ShowableListMenu
+com.android.internal.widget.-$Lambda$LaTFiUorkqfcqmu-zMQbCLeO77c
+com.android.internal.widget.AbsActionBarView
+com.android.internal.widget.AbsActionBarView$VisibilityAnimListener
+com.android.internal.widget.ActionBarContainer
+com.android.internal.widget.ActionBarContainer$ActionBarBackgroundDrawable
+com.android.internal.widget.ActionBarContextView
+com.android.internal.widget.ActionBarContextView$1
+com.android.internal.widget.ActionBarOverlayLayout
+com.android.internal.widget.ActionBarOverlayLayout$1
+com.android.internal.widget.ActionBarOverlayLayout$2
+com.android.internal.widget.ActionBarOverlayLayout$3
+com.android.internal.widget.ActionBarOverlayLayout$4
+com.android.internal.widget.ActionBarOverlayLayout$5
+com.android.internal.widget.ActionBarOverlayLayout$ActionBarVisibilityCallback
+com.android.internal.widget.ActionBarOverlayLayout$LayoutParams
+com.android.internal.widget.AlertDialogLayout
+com.android.internal.widget.BackgroundFallback
+com.android.internal.widget.ButtonBarLayout
+com.android.internal.widget.CachingIconView
+com.android.internal.widget.DecorContentParent
+com.android.internal.widget.DecorToolbar
+com.android.internal.widget.DialogTitle
+com.android.internal.widget.EditableInputConnection
+com.android.internal.widget.ICheckCredentialProgressCallback
+com.android.internal.widget.ILockSettings
+com.android.internal.widget.ILockSettings$Stub
+com.android.internal.widget.ILockSettings$Stub$Proxy
+com.android.internal.widget.ImageFloatingTextView
+com.android.internal.widget.LockPatternUtils
+com.android.internal.widget.LockPatternUtils$RequestThrottledException
+com.android.internal.widget.LockPatternUtils$StrongAuthTracker
+com.android.internal.widget.LockPatternUtils$StrongAuthTracker$1
+com.android.internal.widget.LockPatternUtils$StrongAuthTracker$H
+com.android.internal.widget.MediaNotificationView
+com.android.internal.widget.NotificationActionListLayout
+com.android.internal.widget.NotificationExpandButton
+com.android.internal.widget.ScrollBarUtils
+com.android.internal.widget.ToolbarWidgetWrapper
+com.android.internal.widget.ToolbarWidgetWrapper$1
+com.android.internal.widget.ToolbarWidgetWrapper$2
+com.android.internal.widget.VerifyCredentialResponse
+com.android.okhttp.Address
+com.android.okhttp.AndroidInternal
+com.android.okhttp.AndroidShimResponseCache
+com.android.okhttp.Authenticator
+com.android.okhttp.Cache
+com.android.okhttp.Cache$1
+com.android.okhttp.Cache$CacheRequestImpl
+com.android.okhttp.Cache$CacheRequestImpl$1
+com.android.okhttp.Cache$Entry
+com.android.okhttp.CacheControl
+com.android.okhttp.CacheControl$Builder
+com.android.okhttp.CertificatePinner
+com.android.okhttp.CertificatePinner$Builder
+com.android.okhttp.CipherSuite
+com.android.okhttp.ConfigAwareConnectionPool
+com.android.okhttp.ConfigAwareConnectionPool$1
+com.android.okhttp.Connection
+com.android.okhttp.ConnectionPool
+com.android.okhttp.ConnectionPool$1
+com.android.okhttp.ConnectionSpec
+com.android.okhttp.ConnectionSpec$Builder
+com.android.okhttp.Dispatcher
+com.android.okhttp.Dns
+com.android.okhttp.Dns$1
+com.android.okhttp.Handshake
+com.android.okhttp.Headers
+com.android.okhttp.Headers$Builder
+com.android.okhttp.HttpHandler
+com.android.okhttp.HttpHandler$CleartextURLFilter
+com.android.okhttp.HttpUrl
+com.android.okhttp.HttpUrl$Builder
+com.android.okhttp.HttpUrl$Builder$ParseResult
+com.android.okhttp.HttpsHandler
+com.android.okhttp.OkCacheContainer
+com.android.okhttp.OkHttpClient
+com.android.okhttp.OkHttpClient$1
+com.android.okhttp.OkUrlFactory
+com.android.okhttp.Protocol
+com.android.okhttp.Request
+com.android.okhttp.Request$Builder
+com.android.okhttp.RequestBody
+com.android.okhttp.RequestBody$2
+com.android.okhttp.Response
+com.android.okhttp.Response$Builder
+com.android.okhttp.ResponseBody
+com.android.okhttp.Route
+com.android.okhttp.TlsVersion
+com.android.okhttp.internal.ConnectionSpecSelector
+com.android.okhttp.internal.DiskLruCache
+com.android.okhttp.internal.DiskLruCache$1
+com.android.okhttp.internal.DiskLruCache$2
+com.android.okhttp.internal.DiskLruCache$3
+com.android.okhttp.internal.DiskLruCache$Editor
+com.android.okhttp.internal.DiskLruCache$Editor$1
+com.android.okhttp.internal.DiskLruCache$Entry
+com.android.okhttp.internal.FaultHidingSink
+com.android.okhttp.internal.Internal
+com.android.okhttp.internal.InternalCache
+com.android.okhttp.internal.OptionalMethod
+com.android.okhttp.internal.Platform
+com.android.okhttp.internal.RouteDatabase
+com.android.okhttp.internal.URLFilter
+com.android.okhttp.internal.Util
+com.android.okhttp.internal.Util$1
+com.android.okhttp.internal.http.AuthenticatorAdapter
+com.android.okhttp.internal.http.CacheRequest
+com.android.okhttp.internal.http.CacheStrategy
+com.android.okhttp.internal.http.CacheStrategy$Factory
+com.android.okhttp.internal.http.HeaderParser
+com.android.okhttp.internal.http.Http1xStream
+com.android.okhttp.internal.http.Http1xStream$AbstractSource
+com.android.okhttp.internal.http.Http1xStream$ChunkedSink
+com.android.okhttp.internal.http.Http1xStream$ChunkedSource
+com.android.okhttp.internal.http.Http1xStream$FixedLengthSink
+com.android.okhttp.internal.http.Http1xStream$FixedLengthSource
+com.android.okhttp.internal.http.Http1xStream$UnknownLengthSource
+com.android.okhttp.internal.http.HttpEngine
+com.android.okhttp.internal.http.HttpEngine$1
+com.android.okhttp.internal.http.HttpEngine$2
+com.android.okhttp.internal.http.HttpMethod
+com.android.okhttp.internal.http.HttpStream
+com.android.okhttp.internal.http.OkHeaders
+com.android.okhttp.internal.http.OkHeaders$1
+com.android.okhttp.internal.http.RealResponseBody
+com.android.okhttp.internal.http.RequestException
+com.android.okhttp.internal.http.RequestLine
+com.android.okhttp.internal.http.RetryableSink
+com.android.okhttp.internal.http.RouteException
+com.android.okhttp.internal.http.RouteSelector
+com.android.okhttp.internal.http.StatusLine
+com.android.okhttp.internal.http.StreamAllocation
+com.android.okhttp.internal.huc.DelegatingHttpsURLConnection
+com.android.okhttp.internal.huc.HttpURLConnectionImpl
+com.android.okhttp.internal.huc.HttpsURLConnectionImpl
+com.android.okhttp.internal.io.FileSystem
+com.android.okhttp.internal.io.FileSystem$1
+com.android.okhttp.internal.io.RealConnection
+com.android.okhttp.internal.tls.OkHostnameVerifier
+com.android.okhttp.okio.AsyncTimeout
+com.android.okhttp.okio.AsyncTimeout$1
+com.android.okhttp.okio.AsyncTimeout$2
+com.android.okhttp.okio.AsyncTimeout$Watchdog
+com.android.okhttp.okio.Base64
+com.android.okhttp.okio.Buffer
+com.android.okhttp.okio.BufferedSink
+com.android.okhttp.okio.BufferedSource
+com.android.okhttp.okio.ByteString
+com.android.okhttp.okio.ForwardingSink
+com.android.okhttp.okio.ForwardingTimeout
+com.android.okhttp.okio.GzipSource
+com.android.okhttp.okio.InflaterSource
+com.android.okhttp.okio.Okio
+com.android.okhttp.okio.Okio$1
+com.android.okhttp.okio.Okio$2
+com.android.okhttp.okio.Okio$3
+com.android.okhttp.okio.RealBufferedSink
+com.android.okhttp.okio.RealBufferedSink$1
+com.android.okhttp.okio.RealBufferedSource
+com.android.okhttp.okio.RealBufferedSource$1
+com.android.okhttp.okio.Segment
+com.android.okhttp.okio.SegmentPool
+com.android.okhttp.okio.Sink
+com.android.okhttp.okio.Source
+com.android.okhttp.okio.Timeout
+com.android.okhttp.okio.Timeout$1
+com.android.okhttp.okio.Util
+com.android.org.bouncycastle.asn1.ASN1BitString
+com.android.org.bouncycastle.asn1.ASN1Choice
+com.android.org.bouncycastle.asn1.ASN1Encodable
+com.android.org.bouncycastle.asn1.ASN1EncodableVector
+com.android.org.bouncycastle.asn1.ASN1InputStream
+com.android.org.bouncycastle.asn1.ASN1Integer
+com.android.org.bouncycastle.asn1.ASN1Null
+com.android.org.bouncycastle.asn1.ASN1Object
+com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier
+com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier$OidHandle
+com.android.org.bouncycastle.asn1.ASN1OutputStream
+com.android.org.bouncycastle.asn1.ASN1Primitive
+com.android.org.bouncycastle.asn1.ASN1Sequence
+com.android.org.bouncycastle.asn1.ASN1Set
+com.android.org.bouncycastle.asn1.ASN1StreamParser
+com.android.org.bouncycastle.asn1.ASN1String
+com.android.org.bouncycastle.asn1.ASN1TaggedObject
+com.android.org.bouncycastle.asn1.ASN1TaggedObjectParser
+com.android.org.bouncycastle.asn1.ASN1UTCTime
+com.android.org.bouncycastle.asn1.BERTags
+com.android.org.bouncycastle.asn1.DERBitString
+com.android.org.bouncycastle.asn1.DERFactory
+com.android.org.bouncycastle.asn1.DERNull
+com.android.org.bouncycastle.asn1.DEROutputStream
+com.android.org.bouncycastle.asn1.DERPrintableString
+com.android.org.bouncycastle.asn1.DERSequence
+com.android.org.bouncycastle.asn1.DERSet
+com.android.org.bouncycastle.asn1.DERTaggedObject
+com.android.org.bouncycastle.asn1.DLSequence
+com.android.org.bouncycastle.asn1.DLSet
+com.android.org.bouncycastle.asn1.DefiniteLengthInputStream
+com.android.org.bouncycastle.asn1.InMemoryRepresentable
+com.android.org.bouncycastle.asn1.IndefiniteLengthInputStream
+com.android.org.bouncycastle.asn1.LimitedInputStream
+com.android.org.bouncycastle.asn1.OIDTokenizer
+com.android.org.bouncycastle.asn1.StreamUtil
+com.android.org.bouncycastle.asn1.bc.BCObjectIdentifiers
+com.android.org.bouncycastle.asn1.iana.IANAObjectIdentifiers
+com.android.org.bouncycastle.asn1.misc.MiscObjectIdentifiers
+com.android.org.bouncycastle.asn1.nist.NISTObjectIdentifiers
+com.android.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers
+com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers
+com.android.org.bouncycastle.asn1.x500.RDN
+com.android.org.bouncycastle.asn1.x500.X500Name
+com.android.org.bouncycastle.asn1.x500.X500NameStyle
+com.android.org.bouncycastle.asn1.x500.style.AbstractX500NameStyle
+com.android.org.bouncycastle.asn1.x500.style.BCStyle
+com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier
+com.android.org.bouncycastle.asn1.x509.Certificate
+com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
+com.android.org.bouncycastle.asn1.x509.TBSCertificate
+com.android.org.bouncycastle.asn1.x509.Time
+com.android.org.bouncycastle.asn1.x509.X509ObjectIdentifiers
+com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers
+com.android.org.bouncycastle.crypto.AsymmetricBlockCipher
+com.android.org.bouncycastle.crypto.CipherKeyGenerator
+com.android.org.bouncycastle.crypto.CipherParameters
+com.android.org.bouncycastle.crypto.CryptoException
+com.android.org.bouncycastle.crypto.Digest
+com.android.org.bouncycastle.crypto.ExtendedDigest
+com.android.org.bouncycastle.crypto.InvalidCipherTextException
+com.android.org.bouncycastle.crypto.KeyGenerationParameters
+com.android.org.bouncycastle.crypto.Mac
+com.android.org.bouncycastle.crypto.PBEParametersGenerator
+com.android.org.bouncycastle.crypto.digests.AndroidDigestFactory
+com.android.org.bouncycastle.crypto.digests.AndroidDigestFactoryInterface
+com.android.org.bouncycastle.crypto.digests.AndroidDigestFactoryOpenSSL
+com.android.org.bouncycastle.crypto.digests.EncodableDigest
+com.android.org.bouncycastle.crypto.digests.GeneralDigest
+com.android.org.bouncycastle.crypto.digests.OpenSSLDigest
+com.android.org.bouncycastle.crypto.digests.OpenSSLDigest$SHA1
+com.android.org.bouncycastle.crypto.digests.SHA1Digest
+com.android.org.bouncycastle.crypto.encodings.OAEPEncoding
+com.android.org.bouncycastle.crypto.engines.RSABlindedEngine
+com.android.org.bouncycastle.crypto.engines.RSACoreEngine
+com.android.org.bouncycastle.crypto.generators.PKCS12ParametersGenerator
+com.android.org.bouncycastle.crypto.io.MacInputStream
+com.android.org.bouncycastle.crypto.macs.HMac
+com.android.org.bouncycastle.crypto.params.KeyParameter
+com.android.org.bouncycastle.jcajce.provider.asymmetric.DH$Mappings
+com.android.org.bouncycastle.jcajce.provider.asymmetric.DSA$Mappings
+com.android.org.bouncycastle.jcajce.provider.asymmetric.EC$Mappings
+com.android.org.bouncycastle.jcajce.provider.asymmetric.RSA$Mappings
+com.android.org.bouncycastle.jcajce.provider.asymmetric.X509$Mappings
+com.android.org.bouncycastle.jcajce.provider.asymmetric.dh.KeyFactorySpi
+com.android.org.bouncycastle.jcajce.provider.asymmetric.dsa.DSAUtil
+com.android.org.bouncycastle.jcajce.provider.asymmetric.dsa.KeyFactorySpi
+com.android.org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi
+com.android.org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi$EC
+com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi
+com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi$NoPadding
+com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi
+com.android.org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi
+com.android.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi
+com.android.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl
+com.android.org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory
+com.android.org.bouncycastle.jcajce.provider.asymmetric.x509.PEMUtil
+com.android.org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateObject
+com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider
+com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration
+com.android.org.bouncycastle.jcajce.provider.config.ProviderConfigurationPermission
+com.android.org.bouncycastle.jcajce.provider.digest.DigestAlgorithmProvider
+com.android.org.bouncycastle.jcajce.provider.digest.MD5
+com.android.org.bouncycastle.jcajce.provider.digest.MD5$Mappings
+com.android.org.bouncycastle.jcajce.provider.digest.SHA1
+com.android.org.bouncycastle.jcajce.provider.digest.SHA1$KeyGenerator
+com.android.org.bouncycastle.jcajce.provider.digest.SHA1$Mappings
+com.android.org.bouncycastle.jcajce.provider.digest.SHA224
+com.android.org.bouncycastle.jcajce.provider.digest.SHA224$Mappings
+com.android.org.bouncycastle.jcajce.provider.digest.SHA256
+com.android.org.bouncycastle.jcajce.provider.digest.SHA256$Mappings
+com.android.org.bouncycastle.jcajce.provider.digest.SHA384
+com.android.org.bouncycastle.jcajce.provider.digest.SHA384$Mappings
+com.android.org.bouncycastle.jcajce.provider.digest.SHA512
+com.android.org.bouncycastle.jcajce.provider.digest.SHA512$Mappings
+com.android.org.bouncycastle.jcajce.provider.keystore.BC$Mappings
+com.android.org.bouncycastle.jcajce.provider.keystore.PKCS12$Mappings
+com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi
+com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi$Std
+com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi$StoreEntry
+com.android.org.bouncycastle.jcajce.provider.symmetric.AES
+com.android.org.bouncycastle.jcajce.provider.symmetric.AES$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.ARC4
+com.android.org.bouncycastle.jcajce.provider.symmetric.ARC4$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.Blowfish
+com.android.org.bouncycastle.jcajce.provider.symmetric.Blowfish$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.DES
+com.android.org.bouncycastle.jcajce.provider.symmetric.DES$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.DESede
+com.android.org.bouncycastle.jcajce.provider.symmetric.DESede$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.RC2
+com.android.org.bouncycastle.jcajce.provider.symmetric.RC2$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.SymmetricAlgorithmProvider
+com.android.org.bouncycastle.jcajce.provider.symmetric.Twofish
+com.android.org.bouncycastle.jcajce.provider.symmetric.Twofish$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator
+com.android.org.bouncycastle.jcajce.provider.util.AlgorithmProvider
+com.android.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider
+com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter
+com.android.org.bouncycastle.jcajce.provider.util.DigestFactory
+com.android.org.bouncycastle.jcajce.util.BCJcaJceHelper
+com.android.org.bouncycastle.jcajce.util.JcaJceHelper
+com.android.org.bouncycastle.jcajce.util.ProviderJcaJceHelper
+com.android.org.bouncycastle.jce.interfaces.BCKeyStore
+com.android.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier
+com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
+com.android.org.bouncycastle.jce.provider.BouncyCastleProvider$1
+com.android.org.bouncycastle.jce.provider.BouncyCastleProviderConfiguration
+com.android.org.bouncycastle.jce.provider.CertStoreCollectionSpi
+com.android.org.bouncycastle.util.Arrays
+com.android.org.bouncycastle.util.Encodable
+com.android.org.bouncycastle.util.Integers
+com.android.org.bouncycastle.util.Iterable
+com.android.org.bouncycastle.util.Memoable
+com.android.org.bouncycastle.util.Pack
+com.android.org.bouncycastle.util.Strings
+com.android.org.bouncycastle.util.Strings$1
+com.android.org.bouncycastle.util.io.Streams
+com.android.org.conscrypt.AbstractOpenSSLSession
+com.android.org.conscrypt.AbstractSessionContext
+com.android.org.conscrypt.AbstractSessionContext$1
+com.android.org.conscrypt.AddressUtils
+com.android.org.conscrypt.ArrayUtils
+com.android.org.conscrypt.ByteArray
+com.android.org.conscrypt.CertBlacklist
+com.android.org.conscrypt.CertificatePriorityComparator
+com.android.org.conscrypt.ChainStrengthAnalyzer
+com.android.org.conscrypt.ClientSessionContext
+com.android.org.conscrypt.ClientSessionContext$HostAndPort
+com.android.org.conscrypt.CryptoUpcalls
+com.android.org.conscrypt.EvpMdRef$MD5
+com.android.org.conscrypt.EvpMdRef$SHA1
+com.android.org.conscrypt.EvpMdRef$SHA256
+com.android.org.conscrypt.FileClientSessionCache
+com.android.org.conscrypt.FileClientSessionCache$CacheFile
+com.android.org.conscrypt.FileClientSessionCache$Impl
+com.android.org.conscrypt.Hex
+com.android.org.conscrypt.JSSEProvider
+com.android.org.conscrypt.KeyManagerFactoryImpl
+com.android.org.conscrypt.KeyManagerImpl
+com.android.org.conscrypt.NativeCrypto
+com.android.org.conscrypt.NativeCrypto$SSLHandshakeCallbacks
+com.android.org.conscrypt.NativeCryptoJni
+com.android.org.conscrypt.NativeRef
+com.android.org.conscrypt.NativeRef$EC_GROUP
+com.android.org.conscrypt.NativeRef$EC_POINT
+com.android.org.conscrypt.NativeRef$EVP_CIPHER_CTX
+com.android.org.conscrypt.NativeRef$EVP_MD_CTX
+com.android.org.conscrypt.NativeRef$EVP_PKEY
+com.android.org.conscrypt.NativeRef$HMAC_CTX
+com.android.org.conscrypt.OpenSSLBIOInputStream
+com.android.org.conscrypt.OpenSSLCipher
+com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER
+com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES
+com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES$CBC
+com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES$CBC$PKCS5Padding
+com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES_BASE
+com.android.org.conscrypt.OpenSSLCipher$Mode
+com.android.org.conscrypt.OpenSSLCipher$Padding
+com.android.org.conscrypt.OpenSSLContextImpl
+com.android.org.conscrypt.OpenSSLContextImpl$TLSv12
+com.android.org.conscrypt.OpenSSLECGroupContext
+com.android.org.conscrypt.OpenSSLECKeyFactory
+com.android.org.conscrypt.OpenSSLECPointContext
+com.android.org.conscrypt.OpenSSLECPublicKey
+com.android.org.conscrypt.OpenSSLExtendedSessionImpl
+com.android.org.conscrypt.OpenSSLKey
+com.android.org.conscrypt.OpenSSLKeyHolder
+com.android.org.conscrypt.OpenSSLMac
+com.android.org.conscrypt.OpenSSLMac$HmacSHA1
+com.android.org.conscrypt.OpenSSLMac$HmacSHA256
+com.android.org.conscrypt.OpenSSLMessageDigestJDK
+com.android.org.conscrypt.OpenSSLMessageDigestJDK$MD5
+com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA1
+com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA256
+com.android.org.conscrypt.OpenSSLProvider
+com.android.org.conscrypt.OpenSSLRSAKeyFactory
+com.android.org.conscrypt.OpenSSLRSAPublicKey
+com.android.org.conscrypt.OpenSSLRandom
+com.android.org.conscrypt.OpenSSLSessionImpl
+com.android.org.conscrypt.OpenSSLSignature
+com.android.org.conscrypt.OpenSSLSignature$EngineType
+com.android.org.conscrypt.OpenSSLSignature$RSAPKCS1Padding
+com.android.org.conscrypt.OpenSSLSignature$SHA1RSA
+com.android.org.conscrypt.OpenSSLSignature$SHA256RSA
+com.android.org.conscrypt.OpenSSLSocketFactoryImpl
+com.android.org.conscrypt.OpenSSLSocketImpl
+com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream
+com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream
+com.android.org.conscrypt.OpenSSLSocketImplWrapper
+com.android.org.conscrypt.OpenSSLX509CertPath
+com.android.org.conscrypt.OpenSSLX509CertPath$Encoding
+com.android.org.conscrypt.OpenSSLX509Certificate
+com.android.org.conscrypt.OpenSSLX509CertificateFactory
+com.android.org.conscrypt.OpenSSLX509CertificateFactory$1
+com.android.org.conscrypt.OpenSSLX509CertificateFactory$2
+com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser
+com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException
+com.android.org.conscrypt.Platform
+com.android.org.conscrypt.SSLClientSessionCache
+com.android.org.conscrypt.SSLParametersImpl
+com.android.org.conscrypt.SSLParametersImpl$AliasChooser
+com.android.org.conscrypt.SSLParametersImpl$PSKCallbacks
+com.android.org.conscrypt.SSLUtils
+com.android.org.conscrypt.ServerSessionContext
+com.android.org.conscrypt.TrustManagerFactoryImpl
+com.android.org.conscrypt.TrustManagerImpl
+com.android.org.conscrypt.TrustManagerImpl$ExtendedKeyUsagePKIXCertPathChecker
+com.android.org.conscrypt.TrustManagerImpl$TrustAnchorComparator
+com.android.org.conscrypt.TrustedCertificateIndex
+com.android.org.conscrypt.TrustedCertificateKeyStoreSpi
+com.android.org.conscrypt.TrustedCertificateStore
+com.android.org.conscrypt.TrustedCertificateStore$1
+com.android.org.conscrypt.TrustedCertificateStore$2
+com.android.org.conscrypt.TrustedCertificateStore$4
+com.android.org.conscrypt.TrustedCertificateStore$5
+com.android.org.conscrypt.TrustedCertificateStore$CertSelector
+com.android.org.conscrypt.TrustedCertificateStore$PreloadHolder
+com.android.org.conscrypt.ct.CTLogInfo
+com.android.org.conscrypt.ct.CTLogStore
+com.android.org.conscrypt.ct.CTLogStoreImpl
+com.android.org.conscrypt.ct.CTLogStoreImpl$InvalidLogFileException
+com.android.org.conscrypt.ct.CTPolicy
+com.android.org.conscrypt.ct.CTPolicyImpl
+com.android.org.conscrypt.ct.CTVerifier
+com.android.org.conscrypt.ct.KnownLogs
+com.android.org.conscrypt.ct.SerializationException
+com.android.server.AppWidgetBackupBridge
+com.android.server.BootReceiver
+com.android.server.BootReceiver$1
+com.android.server.BootReceiver$2
+com.android.server.LocalServices
+com.android.server.NetworkManagementSocketTagger
+com.android.server.NetworkManagementSocketTagger$1
+com.android.server.NetworkManagementSocketTagger$SocketTags
+com.android.server.SystemConfig
+com.android.server.SystemConfig$PermissionEntry
+com.android.server.WidgetBackupProvider
+com.android.server.backup.AccountSyncSettingsBackupHelper
+com.android.server.net.BaseNetworkObserver
+com.android.server.net.DnsServerEntry
+com.android.server.net.DnsServerRepository
+com.android.server.net.NetlinkTracker
+com.android.server.net.NetlinkTracker$Callback
+com.android.server.sip.SipService
+com.android.server.sip.SipService$ConnectivityReceiver
+com.android.server.sip.SipService$MyExecutor
+com.android.server.sip.SipWakeLock
+com.android.server.sip.SipWakeupTimer
+com.android.server.sip.SipWakeupTimer$MyEventComparator
+com.android.server.wifi.nano.WifiMetricsProto$AlertReasonCount
+com.android.server.wifi.nano.WifiMetricsProto$ConnectionEvent
+com.android.server.wifi.nano.WifiMetricsProto$RouterFingerPrint
+com.android.server.wifi.nano.WifiMetricsProto$RssiPollCount
+com.android.server.wifi.nano.WifiMetricsProto$SoftApDurationBucket
+com.android.server.wifi.nano.WifiMetricsProto$SoftApReturnCodeCount
+com.android.server.wifi.nano.WifiMetricsProto$StaEvent
+com.android.server.wifi.nano.WifiMetricsProto$StaEvent$ConfigInfo
+com.android.server.wifi.nano.WifiMetricsProto$WifiLog
+com.android.server.wifi.nano.WifiMetricsProto$WifiLog$ScanReturnEntry
+com.android.server.wifi.nano.WifiMetricsProto$WifiLog$WifiSystemStateEntry
+com.android.server.wifi.nano.WifiMetricsProto$WifiScoreCount
+com.android.server.wm.nano.WindowManagerProtos$TaskSnapshotProto
+com.google.android.collect.Lists
+com.google.android.collect.Maps
+com.google.android.collect.Sets
+com.google.android.gles_jni.EGLConfigImpl
+com.google.android.gles_jni.EGLContextImpl
+com.google.android.gles_jni.EGLDisplayImpl
+com.google.android.gles_jni.EGLImpl
+com.google.android.gles_jni.EGLSurfaceImpl
+com.google.android.gles_jni.GLImpl
+com.google.android.mms.MmsException
+dalvik.annotation.optimization.CriticalNative
+dalvik.annotation.optimization.FastNative
+dalvik.system.-$Lambda$xxvwQBVHC44UYbpcpA8j0sUqLOo
+dalvik.system.BaseDexClassLoader
+dalvik.system.BaseDexClassLoader$Reporter
+dalvik.system.BlockGuard
+dalvik.system.BlockGuard$1
+dalvik.system.BlockGuard$2
+dalvik.system.BlockGuard$BlockGuardPolicyException
+dalvik.system.BlockGuard$Policy
+dalvik.system.ClassExt
+dalvik.system.CloseGuard
+dalvik.system.CloseGuard$DefaultReporter
+dalvik.system.CloseGuard$DefaultTracker
+dalvik.system.CloseGuard$Reporter
+dalvik.system.CloseGuard$Tracker
+dalvik.system.DalvikLogHandler
+dalvik.system.DalvikLogging
+dalvik.system.DexClassLoader
+dalvik.system.DexFile
+dalvik.system.DexFile$DFEnum
+dalvik.system.DexPathList
+dalvik.system.DexPathList$Element
+dalvik.system.DexPathList$NativeLibraryElement
+dalvik.system.EmulatedStackFrame
+dalvik.system.EmulatedStackFrame$Range
+dalvik.system.PathClassLoader
+dalvik.system.SocketTagger
+dalvik.system.SocketTagger$1
+dalvik.system.VMDebug
+dalvik.system.VMRuntime
+dalvik.system.VMStack
+dalvik.system.ZygoteHooks
+java.io.Bits
+java.io.BufferedInputStream
+java.io.BufferedOutputStream
+java.io.BufferedReader
+java.io.BufferedWriter
+java.io.ByteArrayInputStream
+java.io.ByteArrayOutputStream
+java.io.CharArrayWriter
+java.io.Closeable
+java.io.Console
+java.io.DataInput
+java.io.DataInputStream
+java.io.DataOutput
+java.io.DataOutputStream
+java.io.DefaultFileSystem
+java.io.EOFException
+java.io.ExpiringCache
+java.io.ExpiringCache$1
+java.io.ExpiringCache$Entry
+java.io.Externalizable
+java.io.File
+java.io.File$PathStatus
+java.io.File$TempDirectory
+java.io.FileDescriptor
+java.io.FileDescriptor$1
+java.io.FileFilter
+java.io.FileInputStream
+java.io.FileInputStream$UseManualSkipException
+java.io.FileNotFoundException
+java.io.FileOutputStream
+java.io.FileReader
+java.io.FileSystem
+java.io.FileWriter
+java.io.FilenameFilter
+java.io.FilterInputStream
+java.io.FilterOutputStream
+java.io.FilterReader
+java.io.Flushable
+java.io.IOException
+java.io.InputStream
+java.io.InputStreamReader
+java.io.InterruptedIOException
+java.io.InvalidClassException
+java.io.InvalidObjectException
+java.io.ObjectInput
+java.io.ObjectInputStream
+java.io.ObjectInputStream$BlockDataInputStream
+java.io.ObjectInputStream$HandleTable
+java.io.ObjectInputStream$HandleTable$HandleList
+java.io.ObjectInputStream$PeekInputStream
+java.io.ObjectInputStream$ValidationList
+java.io.ObjectOutput
+java.io.ObjectOutputStream
+java.io.ObjectOutputStream$BlockDataOutputStream
+java.io.ObjectOutputStream$HandleTable
+java.io.ObjectOutputStream$PutField
+java.io.ObjectOutputStream$ReplaceTable
+java.io.ObjectStreamClass
+java.io.ObjectStreamClass$1
+java.io.ObjectStreamClass$2
+java.io.ObjectStreamClass$3
+java.io.ObjectStreamClass$4
+java.io.ObjectStreamClass$5
+java.io.ObjectStreamClass$Caches
+java.io.ObjectStreamClass$ClassDataSlot
+java.io.ObjectStreamClass$EntryFuture
+java.io.ObjectStreamClass$ExceptionInfo
+java.io.ObjectStreamClass$FieldReflector
+java.io.ObjectStreamClass$FieldReflectorKey
+java.io.ObjectStreamClass$MemberSignature
+java.io.ObjectStreamClass$WeakClassKey
+java.io.ObjectStreamConstants
+java.io.ObjectStreamException
+java.io.ObjectStreamField
+java.io.OutputStream
+java.io.OutputStreamWriter
+java.io.PrintStream
+java.io.PrintWriter
+java.io.PushbackInputStream
+java.io.PushbackReader
+java.io.RandomAccessFile
+java.io.Reader
+java.io.SequenceInputStream
+java.io.SerialCallbackContext
+java.io.Serializable
+java.io.SerializablePermission
+java.io.StreamCorruptedException
+java.io.StringReader
+java.io.StringWriter
+java.io.UnixFileSystem
+java.io.UnsupportedEncodingException
+java.io.Writer
+java.lang.-$Lambda$S9HjrJh0nDg7IyU6wZdPArnZWRQ
+java.lang.-$Lambda$S9HjrJh0nDg7IyU6wZdPArnZWRQ$1
+java.lang.AbstractMethodError
+java.lang.AbstractStringBuilder
+java.lang.AndroidHardcodedSystemProperties
+java.lang.Appendable
+java.lang.ArithmeticException
+java.lang.ArrayIndexOutOfBoundsException
+java.lang.ArrayStoreException
+java.lang.AssertionError
+java.lang.AutoCloseable
+java.lang.Boolean
+java.lang.BootClassLoader
+java.lang.Byte
+java.lang.Byte$ByteCache
+java.lang.CaseMapper
+java.lang.CaseMapper$1
+java.lang.CharSequence
+java.lang.CharSequence$1CharIterator
+java.lang.CharSequence$1CodePointIterator
+java.lang.Character
+java.lang.Character$CharacterCache
+java.lang.Character$Subset
+java.lang.Character$UnicodeBlock
+java.lang.Class
+java.lang.Class$Caches
+java.lang.ClassCastException
+java.lang.ClassLoader
+java.lang.ClassLoader$SystemClassLoader
+java.lang.ClassNotFoundException
+java.lang.CloneNotSupportedException
+java.lang.Cloneable
+java.lang.Comparable
+java.lang.Daemons
+java.lang.Daemons$Daemon
+java.lang.Daemons$FinalizerDaemon
+java.lang.Daemons$FinalizerWatchdogDaemon
+java.lang.Daemons$HeapTaskDaemon
+java.lang.Daemons$ReferenceQueueDaemon
+java.lang.Deprecated
+java.lang.DexCache
+java.lang.Double
+java.lang.Enum
+java.lang.Enum$1
+java.lang.EnumConstantNotPresentException
+java.lang.Error
+java.lang.Exception
+java.lang.ExceptionInInitializerError
+java.lang.Float
+java.lang.IllegalAccessError
+java.lang.IllegalAccessException
+java.lang.IllegalArgumentException
+java.lang.IllegalMonitorStateException
+java.lang.IllegalStateException
+java.lang.IllegalThreadStateException
+java.lang.IncompatibleClassChangeError
+java.lang.IndexOutOfBoundsException
+java.lang.InheritableThreadLocal
+java.lang.InstantiationError
+java.lang.InstantiationException
+java.lang.Integer
+java.lang.Integer$IntegerCache
+java.lang.InternalError
+java.lang.InterruptedException
+java.lang.Iterable
+java.lang.JavaLangAccess
+java.lang.LinkageError
+java.lang.Long
+java.lang.Long$LongCache
+java.lang.Math
+java.lang.Math$RandomNumberGeneratorHolder
+java.lang.NegativeArraySizeException
+java.lang.NoClassDefFoundError
+java.lang.NoSuchFieldError
+java.lang.NoSuchFieldException
+java.lang.NoSuchMethodError
+java.lang.NoSuchMethodException
+java.lang.NullPointerException
+java.lang.Number
+java.lang.NumberFormatException
+java.lang.Object
+java.lang.OutOfMemoryError
+java.lang.Package
+java.lang.Process
+java.lang.ProcessBuilder
+java.lang.ProcessEnvironment
+java.lang.Readable
+java.lang.ReflectiveOperationException
+java.lang.Runnable
+java.lang.Runtime
+java.lang.RuntimeException
+java.lang.RuntimePermission
+java.lang.SecurityException
+java.lang.SecurityManager
+java.lang.Short
+java.lang.Short$ShortCache
+java.lang.StackOverflowError
+java.lang.StackTraceElement
+java.lang.StrictMath
+java.lang.String
+java.lang.String$CaseInsensitiveComparator
+java.lang.StringBuffer
+java.lang.StringBuilder
+java.lang.StringFactory
+java.lang.StringIndexOutOfBoundsException
+java.lang.System
+java.lang.System$PropertiesWithNonOverrideableDefaults
+java.lang.Thread
+java.lang.Thread$1
+java.lang.Thread$Caches
+java.lang.Thread$State
+java.lang.Thread$UncaughtExceptionHandler
+java.lang.Thread$WeakClassKey
+java.lang.ThreadDeath
+java.lang.ThreadGroup
+java.lang.ThreadLocal
+java.lang.ThreadLocal$SuppliedThreadLocal
+java.lang.ThreadLocal$ThreadLocalMap
+java.lang.ThreadLocal$ThreadLocalMap$Entry
+java.lang.Throwable
+java.lang.Throwable$PrintStreamOrWriter
+java.lang.Throwable$SentinelHolder
+java.lang.Throwable$WrappedPrintStream
+java.lang.Throwable$WrappedPrintWriter
+java.lang.TypeNotPresentException
+java.lang.UNIXProcess
+java.lang.UnsatisfiedLinkError
+java.lang.UnsupportedOperationException
+java.lang.VMClassLoader
+java.lang.VerifyError
+java.lang.VirtualMachineError
+java.lang.Void
+java.lang.annotation.Annotation
+java.lang.annotation.AnnotationTypeMismatchException
+java.lang.annotation.IncompleteAnnotationException
+java.lang.annotation.Inherited
+java.lang.annotation.Retention
+java.lang.annotation.Target
+java.lang.invoke.CallSite
+java.lang.invoke.ConstantCallSite
+java.lang.invoke.MethodHandle
+java.lang.invoke.MethodHandleImpl
+java.lang.invoke.MethodHandleImpl$HandleInfo
+java.lang.invoke.MethodHandleInfo
+java.lang.invoke.MethodHandleStatics
+java.lang.invoke.MethodHandles
+java.lang.invoke.MethodHandles$Lookup
+java.lang.invoke.MethodType
+java.lang.invoke.MethodType$ConcurrentWeakInternSet
+java.lang.invoke.MethodType$ConcurrentWeakInternSet$WeakEntry
+java.lang.invoke.MethodTypeForm
+java.lang.invoke.Transformers$BindTo
+java.lang.invoke.Transformers$Collector
+java.lang.invoke.Transformers$Construct
+java.lang.invoke.Transformers$Spreader
+java.lang.invoke.Transformers$Transformer
+java.lang.invoke.Transformers$VarargsCollector
+java.lang.invoke.WrongMethodTypeException
+java.lang.ref.FinalizerReference
+java.lang.ref.FinalizerReference$Sentinel
+java.lang.ref.PhantomReference
+java.lang.ref.Reference
+java.lang.ref.ReferenceQueue
+java.lang.ref.SoftReference
+java.lang.ref.WeakReference
+java.lang.reflect.AccessibleObject
+java.lang.reflect.AnnotatedElement
+java.lang.reflect.Array
+java.lang.reflect.Constructor
+java.lang.reflect.Executable
+java.lang.reflect.Executable$GenericInfo
+java.lang.reflect.Field
+java.lang.reflect.GenericArrayType
+java.lang.reflect.GenericDeclaration
+java.lang.reflect.InvocationHandler
+java.lang.reflect.InvocationTargetException
+java.lang.reflect.MalformedParametersException
+java.lang.reflect.Member
+java.lang.reflect.Method
+java.lang.reflect.Method$1
+java.lang.reflect.Modifier
+java.lang.reflect.Parameter
+java.lang.reflect.ParameterizedType
+java.lang.reflect.Proxy
+java.lang.reflect.Proxy$1
+java.lang.reflect.Proxy$Key1
+java.lang.reflect.Proxy$Key2
+java.lang.reflect.Proxy$KeyFactory
+java.lang.reflect.Proxy$KeyX
+java.lang.reflect.Proxy$ProxyClassFactory
+java.lang.reflect.Type
+java.lang.reflect.TypeVariable
+java.lang.reflect.UndeclaredThrowableException
+java.lang.reflect.WeakCache
+java.lang.reflect.WeakCache$CacheKey
+java.lang.reflect.WeakCache$CacheValue
+java.lang.reflect.WeakCache$Factory
+java.lang.reflect.WeakCache$LookupValue
+java.lang.reflect.WeakCache$Value
+java.lang.reflect.WildcardType
+java.math.BigDecimal
+java.math.BigInt
+java.math.BigInteger
+java.math.Conversion
+java.math.Division
+java.math.MathContext
+java.math.Multiplication
+java.math.NativeBN
+java.math.RoundingMode
+java.net.AbstractPlainDatagramSocketImpl
+java.net.AbstractPlainSocketImpl
+java.net.AddressCache
+java.net.AddressCache$AddressCacheEntry
+java.net.AddressCache$AddressCacheKey
+java.net.ConnectException
+java.net.CookieHandler
+java.net.CookieManager
+java.net.CookiePolicy
+java.net.CookiePolicy$1
+java.net.CookiePolicy$2
+java.net.CookiePolicy$3
+java.net.CookieStore
+java.net.DatagramPacket
+java.net.DatagramSocket
+java.net.DatagramSocket$1
+java.net.DatagramSocketImpl
+java.net.DefaultDatagramSocketImplFactory
+java.net.DefaultFileNameMap
+java.net.DefaultInterface
+java.net.FileNameMap
+java.net.HttpURLConnection
+java.net.IDN
+java.net.InMemoryCookieStore
+java.net.Inet4Address
+java.net.Inet6Address
+java.net.Inet6Address$Inet6AddressHolder
+java.net.Inet6AddressImpl
+java.net.InetAddress
+java.net.InetAddress$1
+java.net.InetAddress$InetAddressHolder
+java.net.InetAddressImpl
+java.net.InetSocketAddress
+java.net.InetSocketAddress$InetSocketAddressHolder
+java.net.InterfaceAddress
+java.net.JarURLConnection
+java.net.MalformedURLException
+java.net.MulticastSocket
+java.net.NetworkInterface
+java.net.NetworkInterface$1checkedAddresses
+java.net.NoRouteToHostException
+java.net.Parts
+java.net.PlainDatagramSocketImpl
+java.net.PlainSocketImpl
+java.net.PortUnreachableException
+java.net.ProtocolException
+java.net.ProtocolFamily
+java.net.Proxy
+java.net.Proxy$Type
+java.net.ProxySelector
+java.net.ResponseCache
+java.net.ServerSocket
+java.net.Socket
+java.net.Socket$1
+java.net.Socket$2
+java.net.Socket$3
+java.net.SocketAddress
+java.net.SocketException
+java.net.SocketImpl
+java.net.SocketInputStream
+java.net.SocketOptions
+java.net.SocketOutputStream
+java.net.SocketTimeoutException
+java.net.SocksConsts
+java.net.SocksSocketImpl
+java.net.StandardProtocolFamily
+java.net.URI
+java.net.URI$Parser
+java.net.URISyntaxException
+java.net.URL
+java.net.URLConnection
+java.net.URLDecoder
+java.net.URLEncoder
+java.net.URLStreamHandler
+java.net.URLStreamHandlerFactory
+java.net.UnknownHostException
+java.net.UnknownServiceException
+java.nio.Bits
+java.nio.Buffer
+java.nio.BufferOverflowException
+java.nio.BufferUnderflowException
+java.nio.ByteBuffer
+java.nio.ByteBufferAsCharBuffer
+java.nio.ByteBufferAsDoubleBuffer
+java.nio.ByteBufferAsFloatBuffer
+java.nio.ByteBufferAsIntBuffer
+java.nio.ByteBufferAsLongBuffer
+java.nio.ByteBufferAsShortBuffer
+java.nio.ByteOrder
+java.nio.CharBuffer
+java.nio.DirectByteBuffer
+java.nio.DirectByteBuffer$MemoryRef
+java.nio.DoubleBuffer
+java.nio.FloatBuffer
+java.nio.HeapByteBuffer
+java.nio.HeapCharBuffer
+java.nio.IntBuffer
+java.nio.InvalidMarkException
+java.nio.LongBuffer
+java.nio.MappedByteBuffer
+java.nio.NIOAccess
+java.nio.NioUtils
+java.nio.ReadOnlyBufferException
+java.nio.ShortBuffer
+java.nio.StringCharBuffer
+java.nio.channels.AsynchronousCloseException
+java.nio.channels.ByteChannel
+java.nio.channels.CancelledKeyException
+java.nio.channels.Channel
+java.nio.channels.Channels
+java.nio.channels.Channels$1
+java.nio.channels.ClosedByInterruptException
+java.nio.channels.ClosedChannelException
+java.nio.channels.DatagramChannel
+java.nio.channels.FileChannel
+java.nio.channels.FileChannel$MapMode
+java.nio.channels.FileLock
+java.nio.channels.GatheringByteChannel
+java.nio.channels.InterruptibleChannel
+java.nio.channels.MulticastChannel
+java.nio.channels.NetworkChannel
+java.nio.channels.NonWritableChannelException
+java.nio.channels.OverlappingFileLockException
+java.nio.channels.ReadableByteChannel
+java.nio.channels.ScatteringByteChannel
+java.nio.channels.SeekableByteChannel
+java.nio.channels.SelectableChannel
+java.nio.channels.SelectionKey
+java.nio.channels.Selector
+java.nio.channels.ServerSocketChannel
+java.nio.channels.SocketChannel
+java.nio.channels.WritableByteChannel
+java.nio.channels.spi.AbstractInterruptibleChannel
+java.nio.channels.spi.AbstractInterruptibleChannel$1
+java.nio.channels.spi.AbstractSelectableChannel
+java.nio.channels.spi.AbstractSelectionKey
+java.nio.channels.spi.AbstractSelector
+java.nio.channels.spi.AbstractSelector$1
+java.nio.channels.spi.SelectorProvider
+java.nio.channels.spi.SelectorProvider$1
+java.nio.charset.CharacterCodingException
+java.nio.charset.Charset
+java.nio.charset.CharsetDecoder
+java.nio.charset.CharsetDecoderICU
+java.nio.charset.CharsetEncoder
+java.nio.charset.CharsetEncoderICU
+java.nio.charset.CharsetICU
+java.nio.charset.CoderResult
+java.nio.charset.CoderResult$1
+java.nio.charset.CoderResult$2
+java.nio.charset.CoderResult$Cache
+java.nio.charset.CodingErrorAction
+java.nio.charset.IllegalCharsetNameException
+java.nio.charset.StandardCharsets
+java.nio.charset.UnsupportedCharsetException
+java.nio.file.AccessMode
+java.nio.file.CopyOption
+java.nio.file.FileAlreadyExistsException
+java.nio.file.FileSystem
+java.nio.file.FileSystemException
+java.nio.file.FileSystems
+java.nio.file.FileSystems$DefaultFileSystemHolder
+java.nio.file.FileSystems$DefaultFileSystemHolder$1
+java.nio.file.Files
+java.nio.file.LinkOption
+java.nio.file.NoSuchFileException
+java.nio.file.OpenOption
+java.nio.file.Path
+java.nio.file.Paths
+java.nio.file.StandardOpenOption
+java.nio.file.Watchable
+java.nio.file.attribute.AttributeView
+java.nio.file.attribute.BasicFileAttributeView
+java.nio.file.attribute.BasicFileAttributes
+java.nio.file.attribute.FileAttribute
+java.nio.file.attribute.FileAttributeView
+java.nio.file.attribute.PosixFileAttributes
+java.nio.file.spi.FileSystemProvider
+java.security.AccessControlContext
+java.security.AccessControlException
+java.security.AccessController
+java.security.AlgorithmConstraints
+java.security.AlgorithmParameters
+java.security.AlgorithmParametersSpi
+java.security.BasicPermission
+java.security.CodeSigner
+java.security.CryptoPrimitive
+java.security.DigestException
+java.security.GeneralSecurityException
+java.security.Guard
+java.security.InvalidAlgorithmParameterException
+java.security.InvalidKeyException
+java.security.InvalidParameterException
+java.security.Key
+java.security.KeyException
+java.security.KeyFactory
+java.security.KeyFactorySpi
+java.security.KeyManagementException
+java.security.KeyPair
+java.security.KeyPairGenerator
+java.security.KeyPairGeneratorSpi
+java.security.KeyStore
+java.security.KeyStore$1
+java.security.KeyStoreException
+java.security.KeyStoreSpi
+java.security.MessageDigest
+java.security.MessageDigest$Delegate
+java.security.MessageDigestSpi
+java.security.NoSuchAlgorithmException
+java.security.NoSuchProviderException
+java.security.Permission
+java.security.PermissionCollection
+java.security.Permissions
+java.security.Principal
+java.security.PrivateKey
+java.security.PrivilegedAction
+java.security.PrivilegedActionException
+java.security.PrivilegedExceptionAction
+java.security.ProtectionDomain
+java.security.Provider
+java.security.Provider$EngineDescription
+java.security.Provider$Service
+java.security.Provider$ServiceKey
+java.security.Provider$UString
+java.security.PublicKey
+java.security.SecureRandom
+java.security.SecureRandomSpi
+java.security.Security
+java.security.Signature
+java.security.Signature$Delegate
+java.security.SignatureException
+java.security.SignatureSpi
+java.security.UnrecoverableEntryException
+java.security.UnrecoverableKeyException
+java.security.cert.CRL
+java.security.cert.CRLException
+java.security.cert.CRLReason
+java.security.cert.CertPath
+java.security.cert.CertPathBuilderException
+java.security.cert.CertPathChecker
+java.security.cert.CertPathHelperImpl
+java.security.cert.CertPathParameters
+java.security.cert.CertPathValidator
+java.security.cert.CertPathValidatorException
+java.security.cert.CertPathValidatorResult
+java.security.cert.CertPathValidatorSpi
+java.security.cert.CertSelector
+java.security.cert.CertStore
+java.security.cert.CertStoreException
+java.security.cert.CertStoreParameters
+java.security.cert.CertStoreSpi
+java.security.cert.Certificate
+java.security.cert.CertificateEncodingException
+java.security.cert.CertificateException
+java.security.cert.CertificateExpiredException
+java.security.cert.CertificateFactory
+java.security.cert.CertificateFactorySpi
+java.security.cert.CertificateNotYetValidException
+java.security.cert.CertificateParsingException
+java.security.cert.CollectionCertStoreParameters
+java.security.cert.Extension
+java.security.cert.PKIXCertPathChecker
+java.security.cert.PKIXCertPathValidatorResult
+java.security.cert.PKIXParameters
+java.security.cert.PKIXRevocationChecker
+java.security.cert.PKIXRevocationChecker$Option
+java.security.cert.PolicyNode
+java.security.cert.PolicyQualifierInfo
+java.security.cert.TrustAnchor
+java.security.cert.X509CertSelector
+java.security.cert.X509Certificate
+java.security.cert.X509Extension
+java.security.interfaces.DSAKey
+java.security.interfaces.DSAPublicKey
+java.security.interfaces.ECKey
+java.security.interfaces.ECPrivateKey
+java.security.interfaces.ECPublicKey
+java.security.interfaces.RSAKey
+java.security.interfaces.RSAPrivateKey
+java.security.interfaces.RSAPublicKey
+java.security.spec.AlgorithmParameterSpec
+java.security.spec.ECField
+java.security.spec.ECFieldFp
+java.security.spec.ECGenParameterSpec
+java.security.spec.ECParameterSpec
+java.security.spec.ECPoint
+java.security.spec.ECPrivateKeySpec
+java.security.spec.ECPublicKeySpec
+java.security.spec.EllipticCurve
+java.security.spec.EncodedKeySpec
+java.security.spec.InvalidKeySpecException
+java.security.spec.InvalidParameterSpecException
+java.security.spec.KeySpec
+java.security.spec.MGF1ParameterSpec
+java.security.spec.PKCS8EncodedKeySpec
+java.security.spec.RSAPrivateCrtKeySpec
+java.security.spec.RSAPrivateKeySpec
+java.security.spec.RSAPublicKeySpec
+java.security.spec.X509EncodedKeySpec
+java.sql.Timestamp
+java.text.AttributedCharacterIterator$Attribute
+java.text.Bidi
+java.text.BreakIterator
+java.text.CalendarBuilder
+java.text.CharacterIterator
+java.text.CollationKey
+java.text.Collator
+java.text.DateFormat
+java.text.DateFormat$Field
+java.text.DateFormatSymbols
+java.text.DecimalFormat
+java.text.DecimalFormatSymbols
+java.text.DontCareFieldPosition
+java.text.DontCareFieldPosition$1
+java.text.FieldPosition
+java.text.FieldPosition$Delegate
+java.text.Format
+java.text.Format$Field
+java.text.Format$FieldDelegate
+java.text.IcuIteratorWrapper
+java.text.MessageFormat
+java.text.MessageFormat$Field
+java.text.Normalizer
+java.text.Normalizer$Form
+java.text.NumberFormat
+java.text.ParseException
+java.text.ParsePosition
+java.text.RuleBasedCollator
+java.text.SimpleDateFormat
+java.text.StringCharacterIterator
+java.time.DateTimeException
+java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$1
+java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$2
+java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$3
+java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$4
+java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$5
+java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw
+java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw$1
+java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw$2
+java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw$3
+java.util.AbstractCollection
+java.util.AbstractList
+java.util.AbstractList$Itr
+java.util.AbstractList$ListItr
+java.util.AbstractMap
+java.util.AbstractMap$1
+java.util.AbstractMap$2
+java.util.AbstractMap$2$1
+java.util.AbstractMap$SimpleEntry
+java.util.AbstractMap$SimpleImmutableEntry
+java.util.AbstractQueue
+java.util.AbstractSequentialList
+java.util.AbstractSet
+java.util.ArrayDeque
+java.util.ArrayDeque$DeqIterator
+java.util.ArrayDeque$DescendingIterator
+java.util.ArrayList
+java.util.ArrayList$ArrayListSpliterator
+java.util.ArrayList$Itr
+java.util.ArrayList$ListItr
+java.util.ArrayList$SubList
+java.util.ArrayList$SubList$1
+java.util.ArrayPrefixHelpers$CumulateTask
+java.util.ArrayPrefixHelpers$DoubleCumulateTask
+java.util.ArrayPrefixHelpers$IntCumulateTask
+java.util.ArrayPrefixHelpers$LongCumulateTask
+java.util.Arrays
+java.util.Arrays$ArrayList
+java.util.Arrays$NaturalOrder
+java.util.ArraysParallelSortHelpers$FJByte$Sorter
+java.util.ArraysParallelSortHelpers$FJChar$Sorter
+java.util.ArraysParallelSortHelpers$FJDouble$Sorter
+java.util.ArraysParallelSortHelpers$FJFloat$Sorter
+java.util.ArraysParallelSortHelpers$FJInt$Sorter
+java.util.ArraysParallelSortHelpers$FJLong$Sorter
+java.util.ArraysParallelSortHelpers$FJObject$Sorter
+java.util.ArraysParallelSortHelpers$FJShort$Sorter
+java.util.Base64
+java.util.Base64$Decoder
+java.util.Base64$Encoder
+java.util.BitSet
+java.util.Calendar
+java.util.Collection
+java.util.Collections
+java.util.Collections$1
+java.util.Collections$2
+java.util.Collections$3
+java.util.Collections$AsLIFOQueue
+java.util.Collections$CheckedCollection
+java.util.Collections$CheckedList
+java.util.Collections$CheckedMap
+java.util.Collections$CheckedNavigableMap
+java.util.Collections$CheckedNavigableSet
+java.util.Collections$CheckedQueue
+java.util.Collections$CheckedRandomAccessList
+java.util.Collections$CheckedSet
+java.util.Collections$CheckedSortedMap
+java.util.Collections$CheckedSortedSet
+java.util.Collections$CopiesList
+java.util.Collections$EmptyEnumeration
+java.util.Collections$EmptyIterator
+java.util.Collections$EmptyList
+java.util.Collections$EmptyListIterator
+java.util.Collections$EmptyMap
+java.util.Collections$EmptySet
+java.util.Collections$ReverseComparator
+java.util.Collections$ReverseComparator2
+java.util.Collections$SetFromMap
+java.util.Collections$SingletonList
+java.util.Collections$SingletonMap
+java.util.Collections$SingletonSet
+java.util.Collections$SynchronizedCollection
+java.util.Collections$SynchronizedList
+java.util.Collections$SynchronizedMap
+java.util.Collections$SynchronizedNavigableMap
+java.util.Collections$SynchronizedNavigableSet
+java.util.Collections$SynchronizedRandomAccessList
+java.util.Collections$SynchronizedSet
+java.util.Collections$SynchronizedSortedMap
+java.util.Collections$SynchronizedSortedSet
+java.util.Collections$UnmodifiableCollection
+java.util.Collections$UnmodifiableCollection$1
+java.util.Collections$UnmodifiableList
+java.util.Collections$UnmodifiableList$1
+java.util.Collections$UnmodifiableMap
+java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet
+java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$1
+java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry
+java.util.Collections$UnmodifiableNavigableMap
+java.util.Collections$UnmodifiableNavigableMap$EmptyNavigableMap
+java.util.Collections$UnmodifiableNavigableSet
+java.util.Collections$UnmodifiableNavigableSet$EmptyNavigableSet
+java.util.Collections$UnmodifiableRandomAccessList
+java.util.Collections$UnmodifiableSet
+java.util.Collections$UnmodifiableSortedMap
+java.util.Collections$UnmodifiableSortedSet
+java.util.ComparableTimSort
+java.util.Comparator
+java.util.Comparators$NaturalOrderComparator
+java.util.Comparators$NullComparator
+java.util.ConcurrentModificationException
+java.util.Currency
+java.util.Date
+java.util.Deque
+java.util.Dictionary
+java.util.DualPivotQuicksort
+java.util.EmptyStackException
+java.util.EnumMap
+java.util.EnumMap$1
+java.util.EnumMap$EntryIterator
+java.util.EnumMap$EntryIterator$Entry
+java.util.EnumMap$EntrySet
+java.util.EnumMap$EnumMapIterator
+java.util.EnumMap$KeyIterator
+java.util.EnumMap$KeySet
+java.util.EnumMap$ValueIterator
+java.util.EnumMap$Values
+java.util.EnumSet
+java.util.EnumSet$SerializationProxy
+java.util.Enumeration
+java.util.EventListener
+java.util.FormatFlagsConversionMismatchException
+java.util.Formattable
+java.util.Formatter
+java.util.Formatter$Conversion
+java.util.Formatter$DateTime
+java.util.Formatter$FixedString
+java.util.Formatter$Flags
+java.util.Formatter$FormatSpecifier
+java.util.Formatter$FormatSpecifierParser
+java.util.Formatter$FormatString
+java.util.FormatterClosedException
+java.util.GregorianCalendar
+java.util.HashMap
+java.util.HashMap$EntryIterator
+java.util.HashMap$EntrySet
+java.util.HashMap$HashIterator
+java.util.HashMap$KeyIterator
+java.util.HashMap$KeySet
+java.util.HashMap$Node
+java.util.HashMap$TreeNode
+java.util.HashMap$ValueIterator
+java.util.HashMap$Values
+java.util.HashSet
+java.util.Hashtable
+java.util.Hashtable$EntrySet
+java.util.Hashtable$Enumerator
+java.util.Hashtable$HashtableEntry
+java.util.Hashtable$KeySet
+java.util.Hashtable$ValueCollection
+java.util.IdentityHashMap
+java.util.IdentityHashMap$EntryIterator
+java.util.IdentityHashMap$EntryIterator$Entry
+java.util.IdentityHashMap$EntrySet
+java.util.IdentityHashMap$IdentityHashMapIterator
+java.util.IdentityHashMap$KeyIterator
+java.util.IdentityHashMap$KeySet
+java.util.IdentityHashMap$ValueIterator
+java.util.IdentityHashMap$Values
+java.util.IllegalFormatException
+java.util.IllformedLocaleException
+java.util.Iterator
+java.util.JumboEnumSet
+java.util.JumboEnumSet$EnumSetIterator
+java.util.LinkedHashMap
+java.util.LinkedHashMap$LinkedEntryIterator
+java.util.LinkedHashMap$LinkedEntrySet
+java.util.LinkedHashMap$LinkedHashIterator
+java.util.LinkedHashMap$LinkedHashMapEntry
+java.util.LinkedHashMap$LinkedKeyIterator
+java.util.LinkedHashMap$LinkedKeySet
+java.util.LinkedHashMap$LinkedValueIterator
+java.util.LinkedHashMap$LinkedValues
+java.util.LinkedHashSet
+java.util.LinkedList
+java.util.LinkedList$DescendingIterator
+java.util.LinkedList$ListItr
+java.util.LinkedList$Node
+java.util.List
+java.util.ListIterator
+java.util.Locale
+java.util.Locale$Builder
+java.util.Locale$Cache
+java.util.Locale$Category
+java.util.Locale$FilteringMode
+java.util.Locale$LanguageRange
+java.util.Locale$LocaleKey
+java.util.Locale$NoImagePreloadHolder
+java.util.Map
+java.util.Map$Entry
+java.util.MissingFormatArgumentException
+java.util.MissingResourceException
+java.util.NavigableMap
+java.util.NavigableSet
+java.util.NoSuchElementException
+java.util.Objects
+java.util.Observable
+java.util.Observer
+java.util.Optional
+java.util.PrimitiveIterator
+java.util.PrimitiveIterator$OfInt
+java.util.PriorityQueue
+java.util.PriorityQueue$Itr
+java.util.Properties
+java.util.Properties$LineReader
+java.util.PropertyResourceBundle
+java.util.Queue
+java.util.Random
+java.util.RandomAccess
+java.util.RandomAccessSubList
+java.util.RegularEnumSet
+java.util.RegularEnumSet$EnumSetIterator
+java.util.ResourceBundle
+java.util.ResourceBundle$1
+java.util.ResourceBundle$BundleReference
+java.util.ResourceBundle$CacheKey
+java.util.ResourceBundle$CacheKeyReference
+java.util.ResourceBundle$Control
+java.util.ResourceBundle$Control$1
+java.util.ResourceBundle$Control$CandidateListCache
+java.util.ResourceBundle$LoaderReference
+java.util.Scanner
+java.util.Scanner$1
+java.util.ServiceConfigurationError
+java.util.ServiceLoader
+java.util.ServiceLoader$1
+java.util.ServiceLoader$LazyIterator
+java.util.Set
+java.util.SimpleTimeZone
+java.util.SortedMap
+java.util.SortedSet
+java.util.Spliterator
+java.util.Spliterator$OfDouble
+java.util.Spliterator$OfInt
+java.util.Spliterator$OfLong
+java.util.Spliterator$OfPrimitive
+java.util.Spliterators
+java.util.Spliterators$EmptySpliterator
+java.util.Spliterators$EmptySpliterator$OfDouble
+java.util.Spliterators$EmptySpliterator$OfInt
+java.util.Spliterators$EmptySpliterator$OfLong
+java.util.Spliterators$EmptySpliterator$OfRef
+java.util.Spliterators$IntArraySpliterator
+java.util.Spliterators$IteratorSpliterator
+java.util.Stack
+java.util.StringJoiner
+java.util.StringTokenizer
+java.util.SubList
+java.util.SubList$1
+java.util.TaskQueue
+java.util.TimSort
+java.util.TimeZone
+java.util.Timer
+java.util.Timer$1
+java.util.TimerTask
+java.util.TimerThread
+java.util.TreeMap
+java.util.TreeMap$AscendingSubMap
+java.util.TreeMap$AscendingSubMap$AscendingEntrySetView
+java.util.TreeMap$EntryIterator
+java.util.TreeMap$EntrySet
+java.util.TreeMap$KeyIterator
+java.util.TreeMap$KeySet
+java.util.TreeMap$NavigableSubMap
+java.util.TreeMap$NavigableSubMap$EntrySetView
+java.util.TreeMap$NavigableSubMap$SubMapEntryIterator
+java.util.TreeMap$NavigableSubMap$SubMapIterator
+java.util.TreeMap$NavigableSubMap$SubMapKeyIterator
+java.util.TreeMap$PrivateEntryIterator
+java.util.TreeMap$TreeMapEntry
+java.util.TreeMap$ValueIterator
+java.util.TreeMap$Values
+java.util.TreeSet
+java.util.UUID
+java.util.UUID$Holder
+java.util.UnknownFormatConversionException
+java.util.Vector
+java.util.Vector$1
+java.util.Vector$Itr
+java.util.WeakHashMap
+java.util.WeakHashMap$Entry
+java.util.WeakHashMap$EntrySet
+java.util.WeakHashMap$HashIterator
+java.util.WeakHashMap$KeyIterator
+java.util.WeakHashMap$KeySet
+java.util.WeakHashMap$ValueIterator
+java.util.WeakHashMap$Values
+java.util.concurrent.-$Lambda$xR9BLpu6SifNikvFgr4lEiECBsk
+java.util.concurrent.AbstractExecutorService
+java.util.concurrent.ArrayBlockingQueue
+java.util.concurrent.BlockingDeque
+java.util.concurrent.BlockingQueue
+java.util.concurrent.Callable
+java.util.concurrent.CancellationException
+java.util.concurrent.CompletableFuture
+java.util.concurrent.CompletableFuture$AltResult
+java.util.concurrent.CompletableFuture$AsynchronousCompletionTask
+java.util.concurrent.CompletableFuture$Completion
+java.util.concurrent.CompletionStage
+java.util.concurrent.ConcurrentHashMap
+java.util.concurrent.ConcurrentHashMap$BaseIterator
+java.util.concurrent.ConcurrentHashMap$BulkTask
+java.util.concurrent.ConcurrentHashMap$CollectionView
+java.util.concurrent.ConcurrentHashMap$CounterCell
+java.util.concurrent.ConcurrentHashMap$EntryIterator
+java.util.concurrent.ConcurrentHashMap$EntrySetView
+java.util.concurrent.ConcurrentHashMap$ForEachEntryTask
+java.util.concurrent.ConcurrentHashMap$ForEachKeyTask
+java.util.concurrent.ConcurrentHashMap$ForEachMappingTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedEntryTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedKeyTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedMappingTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedValueTask
+java.util.concurrent.ConcurrentHashMap$ForEachValueTask
+java.util.concurrent.ConcurrentHashMap$ForwardingNode
+java.util.concurrent.ConcurrentHashMap$KeyIterator
+java.util.concurrent.ConcurrentHashMap$KeySetView
+java.util.concurrent.ConcurrentHashMap$KeySpliterator
+java.util.concurrent.ConcurrentHashMap$MapEntry
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToLongTask
+java.util.concurrent.ConcurrentHashMap$Node
+java.util.concurrent.ConcurrentHashMap$ReduceEntriesTask
+java.util.concurrent.ConcurrentHashMap$ReduceKeysTask
+java.util.concurrent.ConcurrentHashMap$ReduceValuesTask
+java.util.concurrent.ConcurrentHashMap$ReservationNode
+java.util.concurrent.ConcurrentHashMap$SearchEntriesTask
+java.util.concurrent.ConcurrentHashMap$SearchKeysTask
+java.util.concurrent.ConcurrentHashMap$SearchMappingsTask
+java.util.concurrent.ConcurrentHashMap$SearchValuesTask
+java.util.concurrent.ConcurrentHashMap$Segment
+java.util.concurrent.ConcurrentHashMap$Traverser
+java.util.concurrent.ConcurrentHashMap$TreeBin
+java.util.concurrent.ConcurrentHashMap$TreeNode
+java.util.concurrent.ConcurrentHashMap$ValueIterator
+java.util.concurrent.ConcurrentHashMap$ValuesView
+java.util.concurrent.ConcurrentLinkedDeque
+java.util.concurrent.ConcurrentLinkedDeque$Node
+java.util.concurrent.ConcurrentLinkedQueue
+java.util.concurrent.ConcurrentLinkedQueue$Itr
+java.util.concurrent.ConcurrentLinkedQueue$Node
+java.util.concurrent.ConcurrentMap
+java.util.concurrent.ConcurrentNavigableMap
+java.util.concurrent.ConcurrentSkipListMap
+java.util.concurrent.ConcurrentSkipListMap$HeadIndex
+java.util.concurrent.ConcurrentSkipListMap$Index
+java.util.concurrent.ConcurrentSkipListMap$Iter
+java.util.concurrent.ConcurrentSkipListMap$Node
+java.util.concurrent.ConcurrentSkipListMap$ValueIterator
+java.util.concurrent.ConcurrentSkipListMap$Values
+java.util.concurrent.CopyOnWriteArrayList
+java.util.concurrent.CopyOnWriteArrayList$COWIterator
+java.util.concurrent.CopyOnWriteArraySet
+java.util.concurrent.CountDownLatch
+java.util.concurrent.CountDownLatch$Sync
+java.util.concurrent.CountedCompleter
+java.util.concurrent.DelayQueue
+java.util.concurrent.Delayed
+java.util.concurrent.ExecutionException
+java.util.concurrent.Executor
+java.util.concurrent.ExecutorService
+java.util.concurrent.Executors
+java.util.concurrent.Executors$DefaultThreadFactory
+java.util.concurrent.Executors$DelegatedExecutorService
+java.util.concurrent.Executors$DelegatedScheduledExecutorService
+java.util.concurrent.Executors$FinalizableDelegatedExecutorService
+java.util.concurrent.Executors$RunnableAdapter
+java.util.concurrent.ForkJoinPool
+java.util.concurrent.ForkJoinPool$1
+java.util.concurrent.ForkJoinPool$DefaultForkJoinWorkerThreadFactory
+java.util.concurrent.ForkJoinPool$ForkJoinWorkerThreadFactory
+java.util.concurrent.ForkJoinTask
+java.util.concurrent.ForkJoinTask$ExceptionNode
+java.util.concurrent.Future
+java.util.concurrent.FutureTask
+java.util.concurrent.FutureTask$WaitNode
+java.util.concurrent.LinkedBlockingDeque
+java.util.concurrent.LinkedBlockingDeque$AbstractItr
+java.util.concurrent.LinkedBlockingDeque$Itr
+java.util.concurrent.LinkedBlockingDeque$Node
+java.util.concurrent.LinkedBlockingQueue
+java.util.concurrent.LinkedBlockingQueue$Itr
+java.util.concurrent.LinkedBlockingQueue$Node
+java.util.concurrent.PriorityBlockingQueue
+java.util.concurrent.RejectedExecutionException
+java.util.concurrent.RejectedExecutionHandler
+java.util.concurrent.RunnableFuture
+java.util.concurrent.RunnableScheduledFuture
+java.util.concurrent.ScheduledExecutorService
+java.util.concurrent.ScheduledFuture
+java.util.concurrent.ScheduledThreadPoolExecutor
+java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue
+java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask
+java.util.concurrent.Semaphore
+java.util.concurrent.Semaphore$NonfairSync
+java.util.concurrent.Semaphore$Sync
+java.util.concurrent.SynchronousQueue
+java.util.concurrent.SynchronousQueue$TransferQueue
+java.util.concurrent.SynchronousQueue$TransferStack
+java.util.concurrent.SynchronousQueue$TransferStack$SNode
+java.util.concurrent.SynchronousQueue$Transferer
+java.util.concurrent.ThreadFactory
+java.util.concurrent.ThreadLocalRandom
+java.util.concurrent.ThreadLocalRandom$1
+java.util.concurrent.ThreadPoolExecutor
+java.util.concurrent.ThreadPoolExecutor$AbortPolicy
+java.util.concurrent.ThreadPoolExecutor$DiscardOldestPolicy
+java.util.concurrent.ThreadPoolExecutor$DiscardPolicy
+java.util.concurrent.ThreadPoolExecutor$Worker
+java.util.concurrent.TimeUnit
+java.util.concurrent.TimeUnit$1
+java.util.concurrent.TimeUnit$2
+java.util.concurrent.TimeUnit$3
+java.util.concurrent.TimeUnit$4
+java.util.concurrent.TimeUnit$5
+java.util.concurrent.TimeUnit$6
+java.util.concurrent.TimeUnit$7
+java.util.concurrent.TimeoutException
+java.util.concurrent.atomic.AtomicBoolean
+java.util.concurrent.atomic.AtomicInteger
+java.util.concurrent.atomic.AtomicIntegerArray
+java.util.concurrent.atomic.AtomicIntegerFieldUpdater
+java.util.concurrent.atomic.AtomicIntegerFieldUpdater$AtomicIntegerFieldUpdaterImpl
+java.util.concurrent.atomic.AtomicIntegerFieldUpdater$AtomicIntegerFieldUpdaterImpl$1
+java.util.concurrent.atomic.AtomicLong
+java.util.concurrent.atomic.AtomicLongArray
+java.util.concurrent.atomic.AtomicReference
+java.util.concurrent.atomic.AtomicReferenceArray
+java.util.concurrent.atomic.AtomicReferenceFieldUpdater
+java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl
+java.util.concurrent.locks.AbstractOwnableSynchronizer
+java.util.concurrent.locks.AbstractQueuedSynchronizer
+java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject
+java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
+java.util.concurrent.locks.Condition
+java.util.concurrent.locks.Lock
+java.util.concurrent.locks.LockSupport
+java.util.concurrent.locks.ReadWriteLock
+java.util.concurrent.locks.ReentrantLock
+java.util.concurrent.locks.ReentrantLock$FairSync
+java.util.concurrent.locks.ReentrantLock$NonfairSync
+java.util.concurrent.locks.ReentrantLock$Sync
+java.util.concurrent.locks.ReentrantReadWriteLock
+java.util.concurrent.locks.ReentrantReadWriteLock$FairSync
+java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync
+java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock
+java.util.concurrent.locks.ReentrantReadWriteLock$Sync
+java.util.concurrent.locks.ReentrantReadWriteLock$Sync$HoldCounter
+java.util.concurrent.locks.ReentrantReadWriteLock$Sync$ThreadLocalHoldCounter
+java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock
+java.util.function.-$Lambda$1MZdIZ-DL_fjy9l0o8IMJk57T2g
+java.util.function.-$Lambda$VGDeaUHZQIZywZW2ttlyhwk3Cmk
+java.util.function.-$Lambda$VGDeaUHZQIZywZW2ttlyhwk3Cmk$1
+java.util.function.BiConsumer
+java.util.function.BiFunction
+java.util.function.BinaryOperator
+java.util.function.Consumer
+java.util.function.DoubleBinaryOperator
+java.util.function.DoubleUnaryOperator
+java.util.function.Function
+java.util.function.IntBinaryOperator
+java.util.function.IntConsumer
+java.util.function.IntFunction
+java.util.function.IntToDoubleFunction
+java.util.function.IntToLongFunction
+java.util.function.IntUnaryOperator
+java.util.function.LongBinaryOperator
+java.util.function.LongConsumer
+java.util.function.LongUnaryOperator
+java.util.function.Predicate
+java.util.function.Supplier
+java.util.function.ToDoubleBiFunction
+java.util.function.ToDoubleFunction
+java.util.function.ToIntBiFunction
+java.util.function.ToIntFunction
+java.util.function.ToLongBiFunction
+java.util.function.ToLongFunction
+java.util.function.UnaryOperator
+java.util.jar.Attributes
+java.util.jar.Attributes$Name
+java.util.jar.JarEntry
+java.util.jar.JarFile
+java.util.jar.JarFile$JarEntryIterator
+java.util.jar.JarFile$JarFileEntry
+java.util.jar.JarVerifier
+java.util.jar.JarVerifier$1
+java.util.jar.JarVerifier$VerifierStream
+java.util.jar.Manifest
+java.util.jar.Manifest$FastInputStream
+java.util.logging.ErrorManager
+java.util.logging.FileHandler
+java.util.logging.FileHandler$InitializationErrorManager
+java.util.logging.FileHandler$MeteredStream
+java.util.logging.Filter
+java.util.logging.Formatter
+java.util.logging.Handler
+java.util.logging.Level
+java.util.logging.Level$KnownLevel
+java.util.logging.LogManager
+java.util.logging.LogManager$1
+java.util.logging.LogManager$2
+java.util.logging.LogManager$3
+java.util.logging.LogManager$5
+java.util.logging.LogManager$Cleaner
+java.util.logging.LogManager$LogNode
+java.util.logging.LogManager$LoggerContext
+java.util.logging.LogManager$LoggerContext$1
+java.util.logging.LogManager$LoggerWeakRef
+java.util.logging.LogManager$RootLogger
+java.util.logging.LogManager$SystemLoggerContext
+java.util.logging.LogRecord
+java.util.logging.Logger
+java.util.logging.Logger$1
+java.util.logging.Logger$LoggerBundle
+java.util.logging.LoggingPermission
+java.util.logging.LoggingProxyImpl
+java.util.logging.SimpleFormatter
+java.util.logging.StreamHandler
+java.util.logging.XMLFormatter
+java.util.prefs.AbstractPreferences
+java.util.prefs.FileSystemPreferences
+java.util.prefs.Preferences
+java.util.regex.MatchResult
+java.util.regex.Matcher
+java.util.regex.Matcher$OffsetBasedMatchResult
+java.util.regex.Pattern
+java.util.regex.PatternSyntaxException
+java.util.stream.-$Lambda$DJvCeprCIGMk0JvfSkTmQUmEYKA$1
+java.util.stream.-$Lambda$QgGTJrv63_zzBbeGjswm_UMqEbo$12
+java.util.stream.-$Lambda$QgGTJrv63_zzBbeGjswm_UMqEbo$5
+java.util.stream.-$Lambda$QgGTJrv63_zzBbeGjswm_UMqEbo$6
+java.util.stream.-$Lambda$RYrQKhHyGc-mMxiERR98xxRAWkA$5
+java.util.stream.-$Lambda$ioGbka_-VkWTFjRjTt8T4zzsxgk$3
+java.util.stream.-$Lambda$ioGbka_-VkWTFjRjTt8T4zzsxgk$7
+java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$21
+java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$22
+java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$26
+java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$4
+java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$5
+java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$51
+java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$54
+java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$67
+java.util.stream.-$Lambda$qTstLJg88fs2C3g6LH-R51vCVP0$83
+java.util.stream.AbstractPipeline
+java.util.stream.AbstractSpinedBuffer
+java.util.stream.BaseStream
+java.util.stream.Collector
+java.util.stream.Collector$Characteristics
+java.util.stream.Collectors
+java.util.stream.Collectors$CollectorImpl
+java.util.stream.DistinctOps
+java.util.stream.DistinctOps$1
+java.util.stream.DistinctOps$1$2
+java.util.stream.DoubleStream
+java.util.stream.FindOps
+java.util.stream.FindOps$FindOp
+java.util.stream.FindOps$FindSink
+java.util.stream.FindOps$FindSink$OfRef
+java.util.stream.ForEachOps
+java.util.stream.ForEachOps$ForEachOp
+java.util.stream.ForEachOps$ForEachOp$OfRef
+java.util.stream.IntPipeline
+java.util.stream.IntPipeline$4
+java.util.stream.IntPipeline$4$1
+java.util.stream.IntPipeline$Head
+java.util.stream.IntPipeline$StatelessOp
+java.util.stream.IntStream
+java.util.stream.LongPipeline
+java.util.stream.LongPipeline$StatelessOp
+java.util.stream.LongStream
+java.util.stream.Node
+java.util.stream.Node$Builder
+java.util.stream.Node$Builder$OfInt
+java.util.stream.Node$OfDouble
+java.util.stream.Node$OfInt
+java.util.stream.Node$OfLong
+java.util.stream.Node$OfPrimitive
+java.util.stream.Nodes
+java.util.stream.Nodes$EmptyNode
+java.util.stream.Nodes$EmptyNode$OfDouble
+java.util.stream.Nodes$EmptyNode$OfInt
+java.util.stream.Nodes$EmptyNode$OfLong
+java.util.stream.Nodes$EmptyNode$OfRef
+java.util.stream.Nodes$IntSpinedNodeBuilder
+java.util.stream.PipelineHelper
+java.util.stream.ReduceOps
+java.util.stream.ReduceOps$3
+java.util.stream.ReduceOps$3ReducingSink
+java.util.stream.ReduceOps$8
+java.util.stream.ReduceOps$8ReducingSink
+java.util.stream.ReduceOps$AccumulatingSink
+java.util.stream.ReduceOps$Box
+java.util.stream.ReduceOps$ReduceOp
+java.util.stream.ReferencePipeline
+java.util.stream.ReferencePipeline$2
+java.util.stream.ReferencePipeline$2$1
+java.util.stream.ReferencePipeline$3
+java.util.stream.ReferencePipeline$3$1
+java.util.stream.ReferencePipeline$4
+java.util.stream.ReferencePipeline$4$1
+java.util.stream.ReferencePipeline$5
+java.util.stream.ReferencePipeline$5$1
+java.util.stream.ReferencePipeline$Head
+java.util.stream.ReferencePipeline$StatefulOp
+java.util.stream.ReferencePipeline$StatelessOp
+java.util.stream.Sink
+java.util.stream.Sink$ChainedInt
+java.util.stream.Sink$ChainedReference
+java.util.stream.Sink$OfInt
+java.util.stream.Sink$OfLong
+java.util.stream.SliceOps
+java.util.stream.SliceOps$1
+java.util.stream.SliceOps$1$1
+java.util.stream.SpinedBuffer$OfInt
+java.util.stream.SpinedBuffer$OfPrimitive
+java.util.stream.Stream
+java.util.stream.StreamOpFlag
+java.util.stream.StreamOpFlag$MaskBuilder
+java.util.stream.StreamOpFlag$Type
+java.util.stream.StreamShape
+java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator
+java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator$OfRef
+java.util.stream.StreamSupport
+java.util.stream.TerminalOp
+java.util.stream.TerminalSink
+java.util.zip.Adler32
+java.util.zip.CRC32
+java.util.zip.CheckedInputStream
+java.util.zip.Checksum
+java.util.zip.DataFormatException
+java.util.zip.Deflater
+java.util.zip.DeflaterOutputStream
+java.util.zip.GZIPInputStream
+java.util.zip.GZIPInputStream$1
+java.util.zip.GZIPOutputStream
+java.util.zip.Inflater
+java.util.zip.InflaterInputStream
+java.util.zip.ZStreamRef
+java.util.zip.ZipCoder
+java.util.zip.ZipConstants
+java.util.zip.ZipEntry
+java.util.zip.ZipException
+java.util.zip.ZipFile
+java.util.zip.ZipFile$ZipEntryIterator
+java.util.zip.ZipFile$ZipFileInflaterInputStream
+java.util.zip.ZipFile$ZipFileInputStream
+java.util.zip.ZipInputStream
+java.util.zip.ZipUtils
+javax.crypto.BadPaddingException
+javax.crypto.Cipher
+javax.crypto.Cipher$CipherSpiAndProvider
+javax.crypto.Cipher$InitParams
+javax.crypto.Cipher$InitType
+javax.crypto.Cipher$NeedToSet
+javax.crypto.Cipher$SpiAndProviderUpdater
+javax.crypto.Cipher$Transform
+javax.crypto.CipherSpi
+javax.crypto.IllegalBlockSizeException
+javax.crypto.JarVerifier
+javax.crypto.JceSecurity
+javax.crypto.JceSecurity$1
+javax.crypto.KeyGenerator
+javax.crypto.KeyGeneratorSpi
+javax.crypto.Mac
+javax.crypto.MacSpi
+javax.crypto.NoSuchPaddingException
+javax.crypto.NullCipher
+javax.crypto.SecretKey
+javax.crypto.ShortBufferException
+javax.crypto.spec.IvParameterSpec
+javax.crypto.spec.OAEPParameterSpec
+javax.crypto.spec.PBEParameterSpec
+javax.crypto.spec.PSource
+javax.crypto.spec.PSource$PSpecified
+javax.crypto.spec.SecretKeySpec
+javax.microedition.khronos.egl.EGL
+javax.microedition.khronos.egl.EGL10
+javax.microedition.khronos.egl.EGLConfig
+javax.microedition.khronos.egl.EGLContext
+javax.microedition.khronos.egl.EGLDisplay
+javax.microedition.khronos.egl.EGLSurface
+javax.microedition.khronos.opengles.GL
+javax.microedition.khronos.opengles.GL10
+javax.microedition.khronos.opengles.GL10Ext
+javax.microedition.khronos.opengles.GL11
+javax.microedition.khronos.opengles.GL11Ext
+javax.microedition.khronos.opengles.GL11ExtensionPack
+javax.net.DefaultSocketFactory
+javax.net.ServerSocketFactory
+javax.net.SocketFactory
+javax.net.ssl.ExtendedSSLSession
+javax.net.ssl.HandshakeCompletedListener
+javax.net.ssl.HostnameVerifier
+javax.net.ssl.HttpsURLConnection
+javax.net.ssl.KeyManager
+javax.net.ssl.KeyManagerFactory
+javax.net.ssl.KeyManagerFactory$1
+javax.net.ssl.KeyManagerFactorySpi
+javax.net.ssl.SNIHostName
+javax.net.ssl.SNIServerName
+javax.net.ssl.SSLContext
+javax.net.ssl.SSLContextSpi
+javax.net.ssl.SSLEngine
+javax.net.ssl.SSLException
+javax.net.ssl.SSLParameters
+javax.net.ssl.SSLPeerUnverifiedException
+javax.net.ssl.SSLProtocolException
+javax.net.ssl.SSLServerSocketFactory
+javax.net.ssl.SSLSession
+javax.net.ssl.SSLSessionContext
+javax.net.ssl.SSLSocket
+javax.net.ssl.SSLSocketFactory
+javax.net.ssl.SSLSocketFactory$1
+javax.net.ssl.TrustManager
+javax.net.ssl.TrustManagerFactory
+javax.net.ssl.TrustManagerFactory$1
+javax.net.ssl.TrustManagerFactorySpi
+javax.net.ssl.X509ExtendedKeyManager
+javax.net.ssl.X509ExtendedTrustManager
+javax.net.ssl.X509KeyManager
+javax.net.ssl.X509TrustManager
+javax.security.auth.Destroyable
+javax.security.auth.callback.UnsupportedCallbackException
+javax.security.auth.x500.X500Principal
+javax.security.cert.Certificate
+javax.security.cert.CertificateEncodingException
+javax.security.cert.CertificateException
+javax.security.cert.X509Certificate
+javax.sip.SipException
+javax.xml.parsers.ParserConfigurationException
+javax.xml.parsers.SAXParser
+javax.xml.parsers.SAXParserFactory
+javax.xml.transform.TransformerConfigurationException
+javax.xml.transform.TransformerException
+junit.framework.Assert
+libcore.icu.CollationKeyICU
+libcore.icu.DateIntervalFormat
+libcore.icu.DateUtilsBridge
+libcore.icu.ICU
+libcore.icu.LocaleData
+libcore.icu.NativeConverter
+libcore.icu.RelativeDateTimeFormatter
+libcore.icu.RelativeDateTimeFormatter$FormatterCache
+libcore.icu.TimeZoneNames
+libcore.icu.TimeZoneNames$1
+libcore.icu.TimeZoneNames$ZoneStringsCache
+libcore.internal.StringPool
+libcore.io.AsynchronousCloseMonitor
+libcore.io.BlockGuardOs
+libcore.io.BufferIterator
+libcore.io.ClassPathURLStreamHandler
+libcore.io.ClassPathURLStreamHandler$ClassPathURLConnection
+libcore.io.ClassPathURLStreamHandler$ClassPathURLConnection$1
+libcore.io.DropBox
+libcore.io.DropBox$DefaultReporter
+libcore.io.DropBox$Reporter
+libcore.io.EventLogger
+libcore.io.EventLogger$DefaultReporter
+libcore.io.EventLogger$Reporter
+libcore.io.ForwardingOs
+libcore.io.IoBridge
+libcore.io.IoTracker
+libcore.io.IoTracker$Mode
+libcore.io.IoUtils
+libcore.io.IoUtils$FileReader
+libcore.io.Libcore
+libcore.io.Linux
+libcore.io.Memory
+libcore.io.MemoryMappedFile
+libcore.io.NioBufferIterator
+libcore.io.Os
+libcore.io.Streams
+libcore.math.MathUtils
+libcore.net.MimeUtils
+libcore.net.NetworkSecurityPolicy
+libcore.net.NetworkSecurityPolicy$DefaultNetworkSecurityPolicy
+libcore.net.UriCodec
+libcore.net.event.NetworkEventDispatcher
+libcore.net.event.NetworkEventListener
+libcore.reflect.AnnotatedElements
+libcore.reflect.AnnotationFactory
+libcore.reflect.AnnotationMember
+libcore.reflect.AnnotationMember$DefaultValues
+libcore.reflect.GenericArrayTypeImpl
+libcore.reflect.GenericSignatureParser
+libcore.reflect.ListOfTypes
+libcore.reflect.ListOfVariables
+libcore.reflect.ParameterizedTypeImpl
+libcore.reflect.TypeVariableImpl
+libcore.reflect.Types
+libcore.util.BasicLruCache
+libcore.util.CharsetUtils
+libcore.util.CollectionUtils
+libcore.util.EmptyArray
+libcore.util.HexEncoding
+libcore.util.NativeAllocationRegistry
+libcore.util.NativeAllocationRegistry$CleanerRunner
+libcore.util.NativeAllocationRegistry$CleanerThunk
+libcore.util.Objects
+libcore.util.TimeZoneDataFiles
+libcore.util.ZoneInfo
+libcore.util.ZoneInfo$CheckedArithmeticException
+libcore.util.ZoneInfo$OffsetInterval
+libcore.util.ZoneInfo$WallTime
+libcore.util.ZoneInfoDB
+libcore.util.ZoneInfoDB$TzData
+libcore.util.ZoneInfoDB$TzData$1
+org.apache.commons.logging.Log
+org.apache.commons.logging.LogFactory
+org.apache.commons.logging.impl.Jdk14Logger
+org.apache.commons.logging.impl.WeakHashtable
+org.apache.harmony.dalvik.NativeTestTarget
+org.apache.harmony.dalvik.ddmc.Chunk
+org.apache.harmony.dalvik.ddmc.ChunkHandler
+org.apache.harmony.dalvik.ddmc.DdmServer
+org.apache.harmony.dalvik.ddmc.DdmVmInternal
+org.apache.harmony.luni.internal.util.TimezoneGetter
+org.apache.harmony.xml.ExpatAttributes
+org.apache.harmony.xml.ExpatException
+org.apache.harmony.xml.ExpatParser
+org.apache.harmony.xml.ExpatParser$CurrentAttributes
+org.apache.harmony.xml.ExpatParser$ExpatLocator
+org.apache.harmony.xml.ExpatReader
+org.apache.harmony.xml.parsers.SAXParserFactoryImpl
+org.apache.harmony.xml.parsers.SAXParserImpl
+org.apache.http.ConnectionReuseStrategy
+org.apache.http.FormattedHeader
+org.apache.http.Header
+org.apache.http.HeaderElement
+org.apache.http.HeaderElementIterator
+org.apache.http.HeaderIterator
+org.apache.http.HttpClientConnection
+org.apache.http.HttpConnection
+org.apache.http.HttpConnectionMetrics
+org.apache.http.HttpEntity
+org.apache.http.HttpEntityEnclosingRequest
+org.apache.http.HttpException
+org.apache.http.HttpHost
+org.apache.http.HttpInetConnection
+org.apache.http.HttpMessage
+org.apache.http.HttpRequest
+org.apache.http.HttpRequestFactory
+org.apache.http.HttpRequestInterceptor
+org.apache.http.HttpResponse
+org.apache.http.HttpResponseFactory
+org.apache.http.HttpResponseInterceptor
+org.apache.http.HttpServerConnection
+org.apache.http.HttpVersion
+org.apache.http.NameValuePair
+org.apache.http.ParseException
+org.apache.http.ProtocolException
+org.apache.http.ProtocolVersion
+org.apache.http.ReasonPhraseCatalog
+org.apache.http.RequestLine
+org.apache.http.StatusLine
+org.apache.http.auth.AuthSchemeFactory
+org.apache.http.auth.AuthSchemeRegistry
+org.apache.http.auth.AuthState
+org.apache.http.auth.AuthenticationException
+org.apache.http.client.AuthenticationHandler
+org.apache.http.client.ClientProtocolException
+org.apache.http.client.CookieStore
+org.apache.http.client.CredentialsProvider
+org.apache.http.client.HttpClient
+org.apache.http.client.HttpRequestRetryHandler
+org.apache.http.client.HttpResponseException
+org.apache.http.client.RedirectHandler
+org.apache.http.client.RequestDirector
+org.apache.http.client.ResponseHandler
+org.apache.http.client.UserTokenHandler
+org.apache.http.client.entity.UrlEncodedFormEntity
+org.apache.http.client.methods.AbortableHttpRequest
+org.apache.http.client.methods.HttpEntityEnclosingRequestBase
+org.apache.http.client.methods.HttpGet
+org.apache.http.client.methods.HttpPost
+org.apache.http.client.methods.HttpPut
+org.apache.http.client.methods.HttpRequestBase
+org.apache.http.client.methods.HttpUriRequest
+org.apache.http.client.params.HttpClientParams
+org.apache.http.client.protocol.RequestAddCookies
+org.apache.http.client.protocol.RequestDefaultHeaders
+org.apache.http.client.protocol.RequestProxyAuthentication
+org.apache.http.client.protocol.RequestTargetAuthentication
+org.apache.http.client.protocol.ResponseProcessCookies
+org.apache.http.client.utils.URIUtils
+org.apache.http.client.utils.URLEncodedUtils
+org.apache.http.conn.BasicManagedEntity
+org.apache.http.conn.ClientConnectionManager
+org.apache.http.conn.ClientConnectionOperator
+org.apache.http.conn.ClientConnectionRequest
+org.apache.http.conn.ConnectTimeoutException
+org.apache.http.conn.ConnectionKeepAliveStrategy
+org.apache.http.conn.ConnectionReleaseTrigger
+org.apache.http.conn.EofSensorInputStream
+org.apache.http.conn.EofSensorWatcher
+org.apache.http.conn.ManagedClientConnection
+org.apache.http.conn.OperatedClientConnection
+org.apache.http.conn.params.ConnManagerPNames
+org.apache.http.conn.params.ConnManagerParamBean
+org.apache.http.conn.params.ConnManagerParams
+org.apache.http.conn.params.ConnManagerParams$1
+org.apache.http.conn.params.ConnPerRoute
+org.apache.http.conn.params.ConnPerRouteBean
+org.apache.http.conn.params.ConnRoutePNames
+org.apache.http.conn.params.ConnRouteParams
+org.apache.http.conn.routing.BasicRouteDirector
+org.apache.http.conn.routing.HttpRoute
+org.apache.http.conn.routing.HttpRouteDirector
+org.apache.http.conn.routing.HttpRoutePlanner
+org.apache.http.conn.routing.RouteInfo
+org.apache.http.conn.routing.RouteInfo$LayerType
+org.apache.http.conn.routing.RouteInfo$TunnelType
+org.apache.http.conn.routing.RouteTracker
+org.apache.http.conn.scheme.LayeredSocketFactory
+org.apache.http.conn.scheme.PlainSocketFactory
+org.apache.http.conn.scheme.Scheme
+org.apache.http.conn.scheme.SchemeRegistry
+org.apache.http.conn.scheme.SocketFactory
+org.apache.http.conn.ssl.AbstractVerifier
+org.apache.http.conn.ssl.AllowAllHostnameVerifier
+org.apache.http.conn.ssl.AndroidDistinguishedNameParser
+org.apache.http.conn.ssl.BrowserCompatHostnameVerifier
+org.apache.http.conn.ssl.SSLSocketFactory
+org.apache.http.conn.ssl.StrictHostnameVerifier
+org.apache.http.conn.ssl.X509HostnameVerifier
+org.apache.http.cookie.ClientCookie
+org.apache.http.cookie.Cookie
+org.apache.http.cookie.CookieAttributeHandler
+org.apache.http.cookie.CookieIdentityComparator
+org.apache.http.cookie.CookieOrigin
+org.apache.http.cookie.CookiePathComparator
+org.apache.http.cookie.CookieSpec
+org.apache.http.cookie.CookieSpecFactory
+org.apache.http.cookie.CookieSpecRegistry
+org.apache.http.cookie.MalformedCookieException
+org.apache.http.cookie.SetCookie
+org.apache.http.entity.AbstractHttpEntity
+org.apache.http.entity.BasicHttpEntity
+org.apache.http.entity.ByteArrayEntity
+org.apache.http.entity.ContentLengthStrategy
+org.apache.http.entity.HttpEntityWrapper
+org.apache.http.entity.InputStreamEntity
+org.apache.http.entity.StringEntity
+org.apache.http.impl.AbstractHttpClientConnection
+org.apache.http.impl.AbstractHttpServerConnection
+org.apache.http.impl.DefaultConnectionReuseStrategy
+org.apache.http.impl.DefaultHttpRequestFactory
+org.apache.http.impl.DefaultHttpResponseFactory
+org.apache.http.impl.DefaultHttpServerConnection
+org.apache.http.impl.EnglishReasonPhraseCatalog
+org.apache.http.impl.HttpConnectionMetricsImpl
+org.apache.http.impl.SocketHttpClientConnection
+org.apache.http.impl.SocketHttpServerConnection
+org.apache.http.impl.auth.BasicSchemeFactory
+org.apache.http.impl.auth.DigestSchemeFactory
+org.apache.http.impl.client.AbstractAuthenticationHandler
+org.apache.http.impl.client.AbstractHttpClient
+org.apache.http.impl.client.BasicCookieStore
+org.apache.http.impl.client.BasicCredentialsProvider
+org.apache.http.impl.client.ClientParamsStack
+org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy
+org.apache.http.impl.client.DefaultHttpClient
+org.apache.http.impl.client.DefaultHttpRequestRetryHandler
+org.apache.http.impl.client.DefaultProxyAuthenticationHandler
+org.apache.http.impl.client.DefaultRedirectHandler
+org.apache.http.impl.client.DefaultRequestDirector
+org.apache.http.impl.client.DefaultTargetAuthenticationHandler
+org.apache.http.impl.client.DefaultUserTokenHandler
+org.apache.http.impl.client.EntityEnclosingRequestWrapper
+org.apache.http.impl.client.RequestWrapper
+org.apache.http.impl.client.RoutedRequest
+org.apache.http.impl.client.TunnelRefusedException
+org.apache.http.impl.conn.AbstractClientConnAdapter
+org.apache.http.impl.conn.AbstractPoolEntry
+org.apache.http.impl.conn.AbstractPooledConnAdapter
+org.apache.http.impl.conn.DefaultClientConnection
+org.apache.http.impl.conn.DefaultClientConnectionOperator
+org.apache.http.impl.conn.DefaultResponseParser
+org.apache.http.impl.conn.IdleConnectionHandler
+org.apache.http.impl.conn.IdleConnectionHandler$TimeValues
+org.apache.http.impl.conn.ProxySelectorRoutePlanner
+org.apache.http.impl.conn.tsccm.AbstractConnPool
+org.apache.http.impl.conn.tsccm.BasicPoolEntry
+org.apache.http.impl.conn.tsccm.BasicPoolEntryRef
+org.apache.http.impl.conn.tsccm.BasicPooledConnAdapter
+org.apache.http.impl.conn.tsccm.ConnPoolByRoute
+org.apache.http.impl.conn.tsccm.ConnPoolByRoute$1
+org.apache.http.impl.conn.tsccm.PoolEntryRequest
+org.apache.http.impl.conn.tsccm.RefQueueHandler
+org.apache.http.impl.conn.tsccm.RefQueueWorker
+org.apache.http.impl.conn.tsccm.RouteSpecificPool
+org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager
+org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager$1
+org.apache.http.impl.conn.tsccm.WaitingThreadAborter
+org.apache.http.impl.cookie.AbstractCookieAttributeHandler
+org.apache.http.impl.cookie.AbstractCookieSpec
+org.apache.http.impl.cookie.BasicClientCookie
+org.apache.http.impl.cookie.BasicCommentHandler
+org.apache.http.impl.cookie.BasicDomainHandler
+org.apache.http.impl.cookie.BasicExpiresHandler
+org.apache.http.impl.cookie.BasicMaxAgeHandler
+org.apache.http.impl.cookie.BasicPathHandler
+org.apache.http.impl.cookie.BasicSecureHandler
+org.apache.http.impl.cookie.BestMatchSpec
+org.apache.http.impl.cookie.BestMatchSpecFactory
+org.apache.http.impl.cookie.BrowserCompatSpec
+org.apache.http.impl.cookie.BrowserCompatSpecFactory
+org.apache.http.impl.cookie.CookieSpecBase
+org.apache.http.impl.cookie.DateParseException
+org.apache.http.impl.cookie.DateUtils
+org.apache.http.impl.cookie.DateUtils$DateFormatHolder
+org.apache.http.impl.cookie.DateUtils$DateFormatHolder$1
+org.apache.http.impl.cookie.NetscapeDomainHandler
+org.apache.http.impl.cookie.NetscapeDraftHeaderParser
+org.apache.http.impl.cookie.NetscapeDraftSpec
+org.apache.http.impl.cookie.NetscapeDraftSpecFactory
+org.apache.http.impl.cookie.RFC2109DomainHandler
+org.apache.http.impl.cookie.RFC2109Spec
+org.apache.http.impl.cookie.RFC2109SpecFactory
+org.apache.http.impl.cookie.RFC2109VersionHandler
+org.apache.http.impl.cookie.RFC2965CommentUrlAttributeHandler
+org.apache.http.impl.cookie.RFC2965DiscardAttributeHandler
+org.apache.http.impl.cookie.RFC2965DomainAttributeHandler
+org.apache.http.impl.cookie.RFC2965PortAttributeHandler
+org.apache.http.impl.cookie.RFC2965Spec
+org.apache.http.impl.cookie.RFC2965SpecFactory
+org.apache.http.impl.cookie.RFC2965VersionAttributeHandler
+org.apache.http.impl.entity.EntityDeserializer
+org.apache.http.impl.entity.EntitySerializer
+org.apache.http.impl.entity.LaxContentLengthStrategy
+org.apache.http.impl.entity.StrictContentLengthStrategy
+org.apache.http.impl.io.AbstractMessageParser
+org.apache.http.impl.io.AbstractMessageWriter
+org.apache.http.impl.io.AbstractSessionInputBuffer
+org.apache.http.impl.io.AbstractSessionOutputBuffer
+org.apache.http.impl.io.ChunkedInputStream
+org.apache.http.impl.io.ContentLengthInputStream
+org.apache.http.impl.io.ContentLengthOutputStream
+org.apache.http.impl.io.HttpRequestParser
+org.apache.http.impl.io.HttpRequestWriter
+org.apache.http.impl.io.HttpResponseWriter
+org.apache.http.impl.io.HttpTransportMetricsImpl
+org.apache.http.impl.io.IdentityOutputStream
+org.apache.http.impl.io.SocketInputBuffer
+org.apache.http.impl.io.SocketOutputBuffer
+org.apache.http.io.HttpMessageParser
+org.apache.http.io.HttpMessageWriter
+org.apache.http.io.HttpTransportMetrics
+org.apache.http.io.SessionInputBuffer
+org.apache.http.io.SessionOutputBuffer
+org.apache.http.message.AbstractHttpMessage
+org.apache.http.message.BasicHeader
+org.apache.http.message.BasicHeaderElement
+org.apache.http.message.BasicHeaderElementIterator
+org.apache.http.message.BasicHeaderValueParser
+org.apache.http.message.BasicHttpRequest
+org.apache.http.message.BasicHttpResponse
+org.apache.http.message.BasicLineFormatter
+org.apache.http.message.BasicLineParser
+org.apache.http.message.BasicListHeaderIterator
+org.apache.http.message.BasicNameValuePair
+org.apache.http.message.BasicRequestLine
+org.apache.http.message.BasicStatusLine
+org.apache.http.message.BufferedHeader
+org.apache.http.message.HeaderGroup
+org.apache.http.message.HeaderValueParser
+org.apache.http.message.LineFormatter
+org.apache.http.message.LineParser
+org.apache.http.message.ParserCursor
+org.apache.http.params.AbstractHttpParams
+org.apache.http.params.BasicHttpParams
+org.apache.http.params.CoreConnectionPNames
+org.apache.http.params.CoreProtocolPNames
+org.apache.http.params.DefaultedHttpParams
+org.apache.http.params.HttpAbstractParamBean
+org.apache.http.params.HttpConnectionParams
+org.apache.http.params.HttpParams
+org.apache.http.params.HttpProtocolParams
+org.apache.http.protocol.BasicHttpContext
+org.apache.http.protocol.BasicHttpProcessor
+org.apache.http.protocol.DefaultedHttpContext
+org.apache.http.protocol.HTTP
+org.apache.http.protocol.HttpContext
+org.apache.http.protocol.HttpProcessor
+org.apache.http.protocol.HttpRequestExecutor
+org.apache.http.protocol.HttpRequestHandler
+org.apache.http.protocol.HttpRequestHandlerRegistry
+org.apache.http.protocol.HttpRequestHandlerResolver
+org.apache.http.protocol.HttpRequestInterceptorList
+org.apache.http.protocol.HttpResponseInterceptorList
+org.apache.http.protocol.HttpService
+org.apache.http.protocol.RequestConnControl
+org.apache.http.protocol.RequestContent
+org.apache.http.protocol.RequestExpectContinue
+org.apache.http.protocol.RequestTargetHost
+org.apache.http.protocol.RequestUserAgent
+org.apache.http.protocol.ResponseConnControl
+org.apache.http.protocol.ResponseContent
+org.apache.http.protocol.UriPatternMatcher
+org.apache.http.util.ByteArrayBuffer
+org.apache.http.util.CharArrayBuffer
+org.apache.http.util.EntityUtils
+org.apache.http.util.LangUtils
+org.ccil.cowan.tagsoup.AttributesImpl
+org.ccil.cowan.tagsoup.AutoDetector
+org.ccil.cowan.tagsoup.Element
+org.ccil.cowan.tagsoup.ElementType
+org.ccil.cowan.tagsoup.HTMLModels
+org.ccil.cowan.tagsoup.HTMLScanner
+org.ccil.cowan.tagsoup.HTMLSchema
+org.ccil.cowan.tagsoup.Parser
+org.ccil.cowan.tagsoup.Parser$1
+org.ccil.cowan.tagsoup.ScanHandler
+org.ccil.cowan.tagsoup.Scanner
+org.ccil.cowan.tagsoup.Schema
+org.json.JSON
+org.json.JSONArray
+org.json.JSONException
+org.json.JSONObject
+org.json.JSONObject$1
+org.json.JSONStringer
+org.json.JSONStringer$Scope
+org.json.JSONTokener
+org.kxml2.io.KXmlParser
+org.kxml2.io.KXmlParser$ValueContext
+org.kxml2.io.KXmlSerializer
+org.xml.sax.Attributes
+org.xml.sax.ContentHandler
+org.xml.sax.DTDHandler
+org.xml.sax.EntityResolver
+org.xml.sax.ErrorHandler
+org.xml.sax.InputSource
+org.xml.sax.Locator
+org.xml.sax.SAXException
+org.xml.sax.SAXNotRecognizedException
+org.xml.sax.SAXNotSupportedException
+org.xml.sax.SAXParseException
+org.xml.sax.XMLReader
+org.xml.sax.ext.DeclHandler
+org.xml.sax.ext.DefaultHandler2
+org.xml.sax.ext.EntityResolver2
+org.xml.sax.ext.LexicalHandler
+org.xml.sax.helpers.AttributesImpl
+org.xml.sax.helpers.DefaultHandler
+org.xmlpull.v1.XmlPullParser
+org.xmlpull.v1.XmlPullParserException
+org.xmlpull.v1.XmlPullParserFactory
+org.xmlpull.v1.XmlSerializer
+sun.invoke.util.BytecodeDescriptor
+sun.invoke.util.VerifyAccess
+sun.invoke.util.Wrapper
+sun.invoke.util.Wrapper$Format
+sun.misc.ASCIICaseInsensitiveComparator
+sun.misc.Cleaner
+sun.misc.CompoundEnumeration
+sun.misc.FDBigInteger
+sun.misc.FloatingDecimal
+sun.misc.FloatingDecimal$1
+sun.misc.FloatingDecimal$ASCIIToBinaryBuffer
+sun.misc.FloatingDecimal$ASCIIToBinaryConverter
+sun.misc.FloatingDecimal$BinaryToASCIIBuffer
+sun.misc.FloatingDecimal$BinaryToASCIIConverter
+sun.misc.FloatingDecimal$ExceptionalBinaryToASCIIBuffer
+sun.misc.FloatingDecimal$PreparedASCIIToBinaryBuffer
+sun.misc.FormattedFloatingDecimal
+sun.misc.FormattedFloatingDecimal$1
+sun.misc.FormattedFloatingDecimal$Form
+sun.misc.IOUtils
+sun.misc.JavaIOFileDescriptorAccess
+sun.misc.LRUCache
+sun.misc.REException
+sun.misc.SharedSecrets
+sun.misc.Unsafe
+sun.misc.VM
+sun.misc.Version
+sun.net.ConnectionResetException
+sun.net.NetHooks
+sun.net.NetProperties
+sun.net.NetProperties$1
+sun.net.ResourceManager
+sun.net.spi.DefaultProxySelector
+sun.net.spi.DefaultProxySelector$1
+sun.net.spi.DefaultProxySelector$NonProxyInfo
+sun.net.spi.nameservice.NameService
+sun.net.util.IPAddressUtil
+sun.net.www.ParseUtil
+sun.net.www.protocol.file.Handler
+sun.net.www.protocol.jar.Handler
+sun.nio.ch.AbstractPollArrayWrapper
+sun.nio.ch.AbstractPollSelectorImpl
+sun.nio.ch.AllocatedNativeObject
+sun.nio.ch.ChannelInputStream
+sun.nio.ch.DatagramChannelImpl
+sun.nio.ch.DatagramDispatcher
+sun.nio.ch.DefaultSelectorProvider
+sun.nio.ch.DirectBuffer
+sun.nio.ch.FileChannelImpl
+sun.nio.ch.FileChannelImpl$Unmapper
+sun.nio.ch.FileDescriptorHolderSocketImpl
+sun.nio.ch.FileDispatcher
+sun.nio.ch.FileDispatcherImpl
+sun.nio.ch.FileKey
+sun.nio.ch.FileLockImpl
+sun.nio.ch.FileLockTable
+sun.nio.ch.IOStatus
+sun.nio.ch.IOUtil
+sun.nio.ch.Interruptible
+sun.nio.ch.NativeDispatcher
+sun.nio.ch.NativeObject
+sun.nio.ch.NativeThread
+sun.nio.ch.NativeThreadSet
+sun.nio.ch.Net
+sun.nio.ch.Net$1
+sun.nio.ch.Net$4
+sun.nio.ch.PollArrayWrapper
+sun.nio.ch.PollSelectorImpl
+sun.nio.ch.PollSelectorProvider
+sun.nio.ch.SelChImpl
+sun.nio.ch.SelectionKeyImpl
+sun.nio.ch.SelectorImpl
+sun.nio.ch.SelectorProviderImpl
+sun.nio.ch.ServerSocketChannelImpl
+sun.nio.ch.SharedFileLockTable
+sun.nio.ch.SharedFileLockTable$FileLockReference
+sun.nio.ch.SocketAdaptor
+sun.nio.ch.SocketAdaptor$1
+sun.nio.ch.SocketAdaptor$2
+sun.nio.ch.SocketAdaptor$SocketInputStream
+sun.nio.ch.SocketChannelImpl
+sun.nio.ch.SocketDispatcher
+sun.nio.ch.Util
+sun.nio.ch.Util$1
+sun.nio.ch.Util$2
+sun.nio.ch.Util$BufferCache
+sun.nio.cs.ArrayDecoder
+sun.nio.cs.ArrayEncoder
+sun.nio.cs.StreamDecoder
+sun.nio.cs.StreamEncoder
+sun.nio.cs.ThreadLocalCoders
+sun.nio.cs.ThreadLocalCoders$1
+sun.nio.cs.ThreadLocalCoders$2
+sun.nio.cs.ThreadLocalCoders$Cache
+sun.nio.fs.AbstractBasicFileAttributeView
+sun.nio.fs.AbstractFileSystemProvider
+sun.nio.fs.AbstractPath
+sun.nio.fs.DefaultFileSystemProvider
+sun.nio.fs.DynamicFileAttributeView
+sun.nio.fs.LinuxFileSystem
+sun.nio.fs.LinuxFileSystemProvider
+sun.nio.fs.NativeBuffer
+sun.nio.fs.NativeBuffer$Deallocator
+sun.nio.fs.NativeBuffers
+sun.nio.fs.UnixChannelFactory
+sun.nio.fs.UnixChannelFactory$Flags
+sun.nio.fs.UnixConstants
+sun.nio.fs.UnixException
+sun.nio.fs.UnixFileAttributeViews
+sun.nio.fs.UnixFileAttributeViews$Basic
+sun.nio.fs.UnixFileAttributes
+sun.nio.fs.UnixFileAttributes$UnixAsBasicFileAttributes
+sun.nio.fs.UnixFileModeAttribute
+sun.nio.fs.UnixFileStoreAttributes
+sun.nio.fs.UnixFileSystem
+sun.nio.fs.UnixFileSystemProvider
+sun.nio.fs.UnixMountEntry
+sun.nio.fs.UnixNativeDispatcher
+sun.nio.fs.UnixPath
+sun.nio.fs.Util
+sun.reflect.misc.ReflectUtil
+sun.security.action.GetBooleanAction
+sun.security.action.GetIntegerAction
+sun.security.action.GetPropertyAction
+sun.security.jca.GetInstance
+sun.security.jca.GetInstance$Instance
+sun.security.jca.JCAUtil
+sun.security.jca.ProviderConfig
+sun.security.jca.ProviderConfig$2
+sun.security.jca.ProviderList
+sun.security.jca.ProviderList$1
+sun.security.jca.ProviderList$2
+sun.security.jca.ProviderList$3
+sun.security.jca.ProviderList$ServiceList
+sun.security.jca.ProviderList$ServiceList$1
+sun.security.jca.Providers
+sun.security.jca.ServiceId
+sun.security.pkcs.ContentInfo
+sun.security.pkcs.PKCS7
+sun.security.pkcs.PKCS7$VerbatimX509Certificate
+sun.security.pkcs.PKCS7$WrappedX509Certificate
+sun.security.pkcs.PKCS9Attribute
+sun.security.pkcs.SignerInfo
+sun.security.provider.CertPathProvider
+sun.security.provider.X509Factory
+sun.security.provider.certpath.AdaptableX509CertSelector
+sun.security.provider.certpath.AlgorithmChecker
+sun.security.provider.certpath.BasicChecker
+sun.security.provider.certpath.CertId
+sun.security.provider.certpath.CertPathHelper
+sun.security.provider.certpath.ConstraintsChecker
+sun.security.provider.certpath.KeyChecker
+sun.security.provider.certpath.OCSP$RevocationStatus
+sun.security.provider.certpath.OCSP$RevocationStatus$CertStatus
+sun.security.provider.certpath.OCSPResponse
+sun.security.provider.certpath.OCSPResponse$ResponseStatus
+sun.security.provider.certpath.OCSPResponse$SingleResponse
+sun.security.provider.certpath.PKIX
+sun.security.provider.certpath.PKIX$ValidatorParams
+sun.security.provider.certpath.PKIXCertPathValidator
+sun.security.provider.certpath.PKIXMasterCertPathValidator
+sun.security.provider.certpath.PolicyChecker
+sun.security.provider.certpath.PolicyNodeImpl
+sun.security.provider.certpath.RevocationChecker
+sun.security.provider.certpath.RevocationChecker$1
+sun.security.provider.certpath.RevocationChecker$Mode
+sun.security.provider.certpath.RevocationChecker$RevocationProperties
+sun.security.util.AbstractAlgorithmConstraints
+sun.security.util.AbstractAlgorithmConstraints$1
+sun.security.util.AlgorithmDecomposer
+sun.security.util.BitArray
+sun.security.util.ByteArrayLexOrder
+sun.security.util.ByteArrayTagOrder
+sun.security.util.Cache
+sun.security.util.Cache$EqualByteArray
+sun.security.util.CertConstraintParameters
+sun.security.util.Debug
+sun.security.util.DerEncoder
+sun.security.util.DerIndefLenConverter
+sun.security.util.DerInputBuffer
+sun.security.util.DerInputStream
+sun.security.util.DerOutputStream
+sun.security.util.DerValue
+sun.security.util.DisabledAlgorithmConstraints
+sun.security.util.DisabledAlgorithmConstraints$Constraint
+sun.security.util.DisabledAlgorithmConstraints$Constraint$Operator
+sun.security.util.DisabledAlgorithmConstraints$Constraints
+sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraint
+sun.security.util.KeyUtil
+sun.security.util.Length
+sun.security.util.ManifestDigester
+sun.security.util.ManifestDigester$Entry
+sun.security.util.ManifestDigester$Position
+sun.security.util.ManifestEntryVerifier
+sun.security.util.ManifestEntryVerifier$SunProviderHolder
+sun.security.util.MemoryCache
+sun.security.util.MemoryCache$CacheEntry
+sun.security.util.MemoryCache$SoftCacheEntry
+sun.security.util.ObjectIdentifier
+sun.security.util.SignatureFileVerifier
+sun.security.x509.AVA
+sun.security.x509.AVAKeyword
+sun.security.x509.AccessDescription
+sun.security.x509.AlgorithmId
+sun.security.x509.AuthorityInfoAccessExtension
+sun.security.x509.AuthorityKeyIdentifierExtension
+sun.security.x509.BasicConstraintsExtension
+sun.security.x509.CRLDistributionPointsExtension
+sun.security.x509.CRLNumberExtension
+sun.security.x509.CRLReasonCodeExtension
+sun.security.x509.CertAttrSet
+sun.security.x509.CertificateAlgorithmId
+sun.security.x509.CertificateExtensions
+sun.security.x509.CertificateIssuerExtension
+sun.security.x509.CertificatePoliciesExtension
+sun.security.x509.CertificatePolicyId
+sun.security.x509.CertificateSerialNumber
+sun.security.x509.CertificateValidity
+sun.security.x509.CertificateVersion
+sun.security.x509.CertificateX509Key
+sun.security.x509.DNSName
+sun.security.x509.DeltaCRLIndicatorExtension
+sun.security.x509.DistributionPoint
+sun.security.x509.ExtendedKeyUsageExtension
+sun.security.x509.Extension
+sun.security.x509.FreshestCRLExtension
+sun.security.x509.GeneralName
+sun.security.x509.GeneralNameInterface
+sun.security.x509.GeneralNames
+sun.security.x509.InhibitAnyPolicyExtension
+sun.security.x509.IssuerAlternativeNameExtension
+sun.security.x509.IssuingDistributionPointExtension
+sun.security.x509.KeyIdentifier
+sun.security.x509.KeyUsageExtension
+sun.security.x509.NameConstraintsExtension
+sun.security.x509.NetscapeCertTypeExtension
+sun.security.x509.OCSPNoCheckExtension
+sun.security.x509.OIDMap
+sun.security.x509.OIDMap$OIDInfo
+sun.security.x509.PKIXExtensions
+sun.security.x509.PolicyConstraintsExtension
+sun.security.x509.PolicyInformation
+sun.security.x509.PolicyMappingsExtension
+sun.security.x509.PrivateKeyUsageExtension
+sun.security.x509.RDN
+sun.security.x509.SerialNumber
+sun.security.x509.SubjectAlternativeNameExtension
+sun.security.x509.SubjectInfoAccessExtension
+sun.security.x509.SubjectKeyIdentifierExtension
+sun.security.x509.URIName
+sun.security.x509.X500Name
+sun.security.x509.X500Name$1
+sun.security.x509.X509AttributeName
+sun.security.x509.X509CertImpl
+sun.security.x509.X509CertInfo
+sun.security.x509.X509Key
+sun.util.calendar.AbstractCalendar
+sun.util.calendar.BaseCalendar
+sun.util.calendar.BaseCalendar$Date
+sun.util.calendar.CalendarDate
+sun.util.calendar.CalendarSystem
+sun.util.calendar.CalendarUtils
+sun.util.calendar.Gregorian
+sun.util.calendar.Gregorian$Date
+sun.util.calendar.JulianCalendar
+sun.util.calendar.LocalGregorianCalendar
+sun.util.locale.BaseLocale
+sun.util.locale.BaseLocale$Cache
+sun.util.locale.BaseLocale$Key
+sun.util.locale.Extension
+sun.util.locale.InternalLocaleBuilder
+sun.util.locale.InternalLocaleBuilder$CaseInsensitiveChar
+sun.util.locale.LanguageTag
+sun.util.locale.LocaleExtensions
+sun.util.locale.LocaleObjectCache
+sun.util.locale.LocaleObjectCache$CacheEntry
+sun.util.locale.LocaleSyntaxException
+sun.util.locale.LocaleUtils
+sun.util.locale.ParseStatus
+sun.util.locale.StringTokenIterator
+sun.util.locale.UnicodeLocaleExtension
+sun.util.logging.LoggingProxy
+sun.util.logging.LoggingSupport
+sun.util.logging.LoggingSupport$1
+sun.util.logging.LoggingSupport$2
+sun.util.logging.PlatformLogger
+sun.util.logging.PlatformLogger$1
+sun.util.logging.PlatformLogger$JavaLoggerProxy
+sun.util.logging.PlatformLogger$Level
+sun.util.logging.PlatformLogger$LoggerProxy
diff --git a/dirty-image-objects b/config/dirty-image-objects
similarity index 100%
rename from dirty-image-objects
rename to config/dirty-image-objects
diff --git a/config/preloaded-classes b/config/preloaded-classes
new file mode 100644
index 0000000..8233b03
--- /dev/null
+++ b/config/preloaded-classes
@@ -0,0 +1,4595 @@
+#
+# 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.
+#
+#
+#
+# Preloaded-classes filter file for phones.
+#
+# Classes in this file will be allocated into the boot image, and forcibly initialized in
+# the zygote during initialization. This is a trade-off, using virtual address space to share
+# common heap between apps.
+#
+# This file has been derived for mainline phone (and tablet) usage.
+#
+[B
+[C
+[D
+[F
+[I
+[J
+[Landroid.accounts.Account;
+[Landroid.animation.Animator;
+[Landroid.animation.Keyframe$FloatKeyframe;
+[Landroid.animation.Keyframe$IntKeyframe;
+[Landroid.animation.PropertyValuesHolder;
+[Landroid.app.LoaderManagerImpl;
+[Landroid.app.Notification$Action;
+[Landroid.app.NotificationChannel;
+[Landroid.app.RemoteInput;
+[Landroid.app.job.JobInfo$TriggerContentUri;
+[Landroid.bluetooth.BluetoothDevice;
+[Landroid.content.ContentProviderResult;
+[Landroid.content.ContentValues;
+[Landroid.content.Intent;
+[Landroid.content.UndoOwner;
+[Landroid.content.pm.ActivityInfo;
+[Landroid.content.pm.ConfigurationInfo;
+[Landroid.content.pm.FeatureGroupInfo;
+[Landroid.content.pm.FeatureInfo;
+[Landroid.content.pm.InstrumentationInfo;
+[Landroid.content.pm.PathPermission;
+[Landroid.content.pm.PermissionInfo;
+[Landroid.content.pm.ProviderInfo;
+[Landroid.content.pm.ServiceInfo;
+[Landroid.content.pm.Signature;
+[Landroid.content.res.Configuration;
+[Landroid.content.res.StringBlock;
+[Landroid.content.res.XmlBlock;
+[Landroid.database.CursorWindow;
+[Landroid.database.sqlite.SQLiteConnection$Operation;
+[Landroid.database.sqlite.SQLiteConnectionPool$AcquiredConnectionStatus;
+[Landroid.graphics.Bitmap$CompressFormat;
+[Landroid.graphics.Bitmap$Config;
+[Landroid.graphics.Bitmap;
+[Landroid.graphics.Canvas$EdgeType;
+[Landroid.graphics.ColorSpace$Model;
+[Landroid.graphics.ColorSpace$Named;
+[Landroid.graphics.ColorSpace;
+[Landroid.graphics.FontFamily;
+[Landroid.graphics.Interpolator$Result;
+[Landroid.graphics.Matrix$ScaleToFit;
+[Landroid.graphics.Paint$Align;
+[Landroid.graphics.Paint$Cap;
+[Landroid.graphics.Paint$Join;
+[Landroid.graphics.Paint$Style;
+[Landroid.graphics.Path$Direction;
+[Landroid.graphics.Path$FillType;
+[Landroid.graphics.Point;
+[Landroid.graphics.PorterDuff$Mode;
+[Landroid.graphics.Rect;
+[Landroid.graphics.Region$Op;
+[Landroid.graphics.Shader$TileMode;
+[Landroid.graphics.Typeface;
+[Landroid.graphics.drawable.Drawable;
+[Landroid.graphics.drawable.GradientDrawable$Orientation;
+[Landroid.graphics.drawable.LayerDrawable$ChildDrawable;
+[Landroid.graphics.drawable.RippleForeground;
+[Landroid.graphics.fonts.FontVariationAxis;
+[Landroid.hardware.camera2.marshal.MarshalQueryable;
+[Landroid.hardware.camera2.params.Face;
+[Landroid.hardware.camera2.params.HighSpeedVideoConfiguration;
+[Landroid.hardware.camera2.params.MeteringRectangle;
+[Landroid.hardware.camera2.params.StreamConfiguration;
+[Landroid.hardware.camera2.params.StreamConfigurationDuration;
+[Landroid.hardware.soundtrigger.SoundTrigger$ConfidenceLevel;
+[Landroid.hardware.soundtrigger.SoundTrigger$Keyphrase;
+[Landroid.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionExtra;
+[Landroid.icu.impl.CacheValue$Strength;
+[Landroid.icu.impl.CacheValue;
+[Landroid.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingPattern;
+[Landroid.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingType;
+[Landroid.icu.impl.ICUResourceBundle$OpenType;
+[Landroid.icu.impl.StandardPlural;
+[Landroid.icu.impl.Trie2$ValueWidth;
+[Landroid.icu.impl.UCharacterProperty$BinaryProperty;
+[Landroid.icu.impl.UCharacterProperty$IntProperty;
+[Landroid.icu.text.DisplayContext$Type;
+[Landroid.icu.text.DisplayContext;
+[Landroid.icu.text.PluralRules$Operand;
+[Landroid.icu.text.PluralRules$PluralType;
+[Landroid.icu.text.PluralRules$SampleType;
+[Landroid.icu.text.TimeZoneNames$NameType;
+[Landroid.icu.text.UnicodeSet;
+[Landroid.icu.util.Currency$CurrencyUsage;
+[Landroid.icu.util.ULocale$Category;
+[Landroid.icu.util.ULocale;
+[Landroid.icu.util.UResourceBundle$RootType;
+[Landroid.media.AudioGain;
+[Landroid.net.IpConfiguration$IpAssignment;
+[Landroid.net.IpConfiguration$ProxySettings;
+[Landroid.net.LocalSocketAddress$Namespace;
+[Landroid.net.NetworkInfo$DetailedState;
+[Landroid.net.NetworkInfo$State;
+[Landroid.net.NetworkKey;
+[Landroid.net.NetworkRequest$Type;
+[Landroid.net.ScoredNetwork;
+[Landroid.net.Uri;
+[Landroid.net.wifi.ScanResult$InformationElement;
+[Landroid.net.wifi.SupplicantState;
+[Landroid.os.AsyncTask$Status;
+[Landroid.os.MessageQueue$IdleHandler;
+[Landroid.os.Parcel;
+[Landroid.os.Parcelable;
+[Landroid.os.PatternMatcher;
+[Landroid.os.PersistableBundle;
+[Landroid.os.storage.StorageVolume;
+[Landroid.service.notification.StatusBarNotification;
+[Landroid.system.StructPollfd;
+[Landroid.telephony.TelephonyManager$MultiSimVariants;
+[Landroid.text.DynamicLayout$ChangeWatcher;
+[Landroid.text.FontConfig$Alias;
+[Landroid.text.FontConfig$Family;
+[Landroid.text.FontConfig$Font;
+[Landroid.text.Hyphenator$HyphenationData;
+[Landroid.text.InputFilter;
+[Landroid.text.Layout$Alignment;
+[Landroid.text.Layout$Directions;
+[Landroid.text.MeasuredText;
+[Landroid.text.SpanWatcher;
+[Landroid.text.TextLine;
+[Landroid.text.TextUtils$TruncateAt;
+[Landroid.text.TextWatcher;
+[Landroid.text.method.TextKeyListener$Capitalize;
+[Landroid.text.method.TextKeyListener;
+[Landroid.text.style.AlignmentSpan;
+[Landroid.text.style.CharacterStyle;
+[Landroid.text.style.LeadingMarginSpan;
+[Landroid.text.style.LineBackgroundSpan;
+[Landroid.text.style.LineHeightSpan;
+[Landroid.text.style.MetricAffectingSpan;
+[Landroid.text.style.ParagraphStyle;
+[Landroid.text.style.ReplacementSpan;
+[Landroid.text.style.SpellCheckSpan;
+[Landroid.text.style.SuggestionSpan;
+[Landroid.text.style.TabStopSpan;
+[Landroid.text.style.WrapTogetherSpan;
+[Landroid.util.LongSparseArray;
+[Landroid.util.Pair;
+[Landroid.util.Range;
+[Landroid.util.Rational;
+[Landroid.util.Size;
+[Landroid.view.Choreographer$CallbackQueue;
+[Landroid.view.Display$Mode;
+[Landroid.view.Display;
+[Landroid.view.HandlerActionQueue$HandlerAction;
+[Landroid.view.MenuItem;
+[Landroid.view.View;
+[Landroid.widget.Editor$TextViewPositionListener;
+[Landroid.widget.ImageView$ScaleType;
+[Landroid.widget.TextView$BufferType;
+[Landroid.widget.TextView$ChangeWatcher;
+[Lcom.android.internal.policy.PhoneWindow$PanelFeatureState;
+[Lcom.android.internal.telephony.IccCardConstants$State;
+[Lcom.android.internal.telephony.PhoneConstants$State;
+[Lcom.android.internal.util.StateMachine$SmHandler$StateInfo;
+[Lcom.android.okhttp.CipherSuite;
+[Lcom.android.okhttp.ConnectionSpec;
+[Lcom.android.okhttp.HttpUrl$Builder$ParseResult;
+[Lcom.android.okhttp.Protocol;
+[Lcom.android.okhttp.TlsVersion;
+[Lcom.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+[Lcom.android.org.conscrypt.OpenSSLSignature$EngineType;
+[Lcom.android.org.conscrypt.OpenSSLX509CertPath$Encoding;
+[Lcom.android.org.conscrypt.OpenSSLX509Certificate;
+[Lcom.android.org.conscrypt.ct.CTLogInfo;
+[Ldalvik.system.DexPathList$Element;
+[Ldalvik.system.DexPathList$NativeLibraryElement;
+[Ljava.io.File$PathStatus;
+[Ljava.io.File;
+[Ljava.io.FileDescriptor;
+[Ljava.io.IOException;
+[Ljava.io.ObjectInputStream$HandleTable$HandleList;
+[Ljava.io.ObjectStreamField;
+[Ljava.lang.Byte;
+[Ljava.lang.CharSequence;
+[Ljava.lang.Character$UnicodeBlock;
+[Ljava.lang.Character;
+[Ljava.lang.Class;
+[Ljava.lang.Comparable;
+[Ljava.lang.Enum;
+[Ljava.lang.Integer;
+[Ljava.lang.Long;
+[Ljava.lang.Object;
+[Ljava.lang.Package;
+[Ljava.lang.Runnable;
+[Ljava.lang.Short;
+[Ljava.lang.StackTraceElement;
+[Ljava.lang.String;
+[Ljava.lang.Thread$State;
+[Ljava.lang.Thread;
+[Ljava.lang.ThreadGroup;
+[Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;
+[Ljava.lang.Throwable;
+[Ljava.lang.Void;
+[Ljava.lang.annotation.Annotation;
+[Ljava.lang.invoke.MethodType;
+[Ljava.lang.ref.WeakReference;
+[Ljava.lang.reflect.AccessibleObject;
+[Ljava.lang.reflect.Constructor;
+[Ljava.lang.reflect.Field;
+[Ljava.lang.reflect.Method;
+[Ljava.lang.reflect.Parameter;
+[Ljava.lang.reflect.Type;
+[Ljava.lang.reflect.TypeVariable;
+[Ljava.math.BigInteger;
+[Ljava.math.RoundingMode;
+[Ljava.net.InetAddress;
+[Ljava.net.Proxy$Type;
+[Ljava.nio.ByteBuffer;
+[Ljava.nio.file.attribute.FileAttribute;
+[Ljava.security.CryptoPrimitive;
+[Ljava.security.Provider;
+[Ljava.security.cert.Certificate;
+[Ljava.security.cert.X509Certificate;
+[Ljava.text.DateFormat$Field;
+[Ljava.text.Normalizer$Form;
+[Ljava.util.ArrayList;
+[Ljava.util.Comparators$NaturalOrderComparator;
+[Ljava.util.Enumeration;
+[Ljava.util.Formatter$Flags;
+[Ljava.util.Formatter$FormatString;
+[Ljava.util.HashMap$Node;
+[Ljava.util.Hashtable$HashtableEntry;
+[Ljava.util.Locale$Category;
+[Ljava.util.Locale;
+[Ljava.util.Map$Entry;
+[Ljava.util.WeakHashMap$Entry;
+[Ljava.util.concurrent.ConcurrentHashMap$CounterCell;
+[Ljava.util.concurrent.ConcurrentHashMap$Node;
+[Ljava.util.concurrent.ConcurrentHashMap$Segment;
+[Ljava.util.concurrent.ForkJoinTask$ExceptionNode;
+[Ljava.util.concurrent.RunnableScheduledFuture;
+[Ljava.util.concurrent.TimeUnit;
+[Ljava.util.logging.Handler;
+[Ljava.util.regex.Pattern;
+[Ljava.util.stream.StreamOpFlag$Type;
+[Ljava.util.stream.StreamOpFlag;
+[Ljava.util.stream.StreamShape;
+[Ljavax.crypto.Cipher$InitType;
+[Ljavax.crypto.Cipher$NeedToSet;
+[Ljavax.microedition.khronos.egl.EGLConfig;
+[Ljavax.net.ssl.KeyManager;
+[Ljavax.net.ssl.TrustManager;
+[Ljavax.security.cert.X509Certificate;
+[Llibcore.io.ClassPathURLStreamHandler;
+[Llibcore.io.IoTracker$Mode;
+[Llibcore.reflect.AnnotationMember$DefaultValues;
+[Llibcore.reflect.AnnotationMember;
+[Lorg.apache.http.Header;
+[Lorg.json.JSONStringer$Scope;
+[Lorg.kxml2.io.KXmlParser$ValueContext;
+[Lsun.invoke.util.Wrapper;
+[Lsun.misc.FDBigInteger;
+[Lsun.misc.FormattedFloatingDecimal$Form;
+[Lsun.security.jca.ProviderConfig;
+[Lsun.security.jca.ServiceId;
+[Lsun.security.pkcs.SignerInfo;
+[Lsun.security.util.DerOutputStream;
+[Lsun.security.util.DerValue;
+[Lsun.security.util.DisabledAlgorithmConstraints$Constraint$Operator;
+[Lsun.security.util.ObjectIdentifier;
+[Lsun.security.x509.AVA;
+[Lsun.security.x509.RDN;
+[Lsun.util.logging.PlatformLogger$Level;
+[S
+[Z
+[[B
+[[I
+[[Ljava.lang.Byte;
+[[Ljava.lang.Class;
+[[Ljava.lang.Object;
+[[Ljava.lang.String;
+[[Ljava.lang.annotation.Annotation;
+android.R$styleable
+android.accounts.Account
+android.accounts.Account$1
+android.accounts.AccountManager
+android.accounts.AccountManager$1
+android.accounts.AccountManager$19
+android.accounts.AccountManager$BaseFutureTask
+android.accounts.AccountManager$BaseFutureTask$1
+android.accounts.AccountManager$BaseFutureTask$Response
+android.accounts.AccountManager$Future2Task
+android.accounts.AccountManagerCallback
+android.accounts.AccountManagerFuture
+android.accounts.AccountsException
+android.accounts.AuthenticatorException
+android.accounts.IAccountManager
+android.accounts.IAccountManager$Stub
+android.accounts.IAccountManager$Stub$Proxy
+android.accounts.IAccountManagerResponse
+android.accounts.IAccountManagerResponse$Stub
+android.accounts.OnAccountsUpdateListener
+android.accounts.OperationCanceledException
+android.animation.AnimationHandler
+android.animation.AnimationHandler$1
+android.animation.AnimationHandler$AnimationFrameCallback
+android.animation.AnimationHandler$AnimationFrameCallbackProvider
+android.animation.AnimationHandler$MyFrameCallbackProvider
+android.animation.Animator
+android.animation.Animator$AnimatorConstantState
+android.animation.Animator$AnimatorListener
+android.animation.Animator$AnimatorPauseListener
+android.animation.AnimatorInflater
+android.animation.AnimatorListenerAdapter
+android.animation.AnimatorSet
+android.animation.AnimatorSet$1
+android.animation.AnimatorSet$2
+android.animation.AnimatorSet$3
+android.animation.AnimatorSet$AnimationEvent
+android.animation.AnimatorSet$Builder
+android.animation.AnimatorSet$Node
+android.animation.AnimatorSet$SeekState
+android.animation.FloatEvaluator
+android.animation.FloatKeyframeSet
+android.animation.IntEvaluator
+android.animation.IntKeyframeSet
+android.animation.Keyframe
+android.animation.Keyframe$FloatKeyframe
+android.animation.Keyframe$IntKeyframe
+android.animation.KeyframeSet
+android.animation.Keyframes
+android.animation.Keyframes$FloatKeyframes
+android.animation.Keyframes$IntKeyframes
+android.animation.LayoutTransition
+android.animation.LayoutTransition$TransitionListener
+android.animation.ObjectAnimator
+android.animation.PathKeyframes$FloatKeyframesBase
+android.animation.PathKeyframes$IntKeyframesBase
+android.animation.PathKeyframes$SimpleKeyframes
+android.animation.PropertyValuesHolder
+android.animation.PropertyValuesHolder$FloatPropertyValuesHolder
+android.animation.PropertyValuesHolder$IntPropertyValuesHolder
+android.animation.PropertyValuesHolder$PropertyValues
+android.animation.RectEvaluator
+android.animation.StateListAnimator
+android.animation.StateListAnimator$1
+android.animation.StateListAnimator$StateListAnimatorConstantState
+android.animation.StateListAnimator$Tuple
+android.animation.TimeInterpolator
+android.animation.TypeEvaluator
+android.animation.ValueAnimator
+android.animation.ValueAnimator$AnimatorUpdateListener
+android.app.-$Lambda$9I5WEMsoBc7l4QrNqZ4wx59yuHU
+android.app.-$Lambda$9I5WEMsoBc7l4QrNqZ4wx59yuHU$1
+android.app.-$Lambda$FilBqgnXJrN9Mgyks1XHeAxzSTk
+android.app.-$Lambda$c44uHH2WE4sJvw5tZZB6gRzEaHI
+android.app.-$Lambda$c44uHH2WE4sJvw5tZZB6gRzEaHI$1
+android.app.Activity
+android.app.Activity$HostCallbacks
+android.app.ActivityManager
+android.app.ActivityManager$1
+android.app.ActivityManager$RecentTaskInfo
+android.app.ActivityManager$RecentTaskInfo$1
+android.app.ActivityManager$RunningAppProcessInfo
+android.app.ActivityManager$RunningAppProcessInfo$1
+android.app.ActivityManager$RunningServiceInfo
+android.app.ActivityManager$RunningServiceInfo$1
+android.app.ActivityManager$RunningTaskInfo
+android.app.ActivityManager$RunningTaskInfo$1
+android.app.ActivityManager$StackId
+android.app.ActivityManager$TaskDescription
+android.app.ActivityManager$TaskDescription$1
+android.app.ActivityOptions
+android.app.ActivityThread
+android.app.ActivityThread$1
+android.app.ActivityThread$2
+android.app.ActivityThread$ActivityClientRecord
+android.app.ActivityThread$ActivityConfigChangeData
+android.app.ActivityThread$AppBindData
+android.app.ActivityThread$ApplicationThread
+android.app.ActivityThread$BindServiceData
+android.app.ActivityThread$ContextCleanupInfo
+android.app.ActivityThread$CreateServiceData
+android.app.ActivityThread$DropBoxReporter
+android.app.ActivityThread$EventLoggingReporter
+android.app.ActivityThread$GcIdler
+android.app.ActivityThread$H
+android.app.ActivityThread$Idler
+android.app.ActivityThread$Profiler
+android.app.ActivityThread$ProviderClientRecord
+android.app.ActivityThread$ProviderKey
+android.app.ActivityThread$ProviderRefCount
+android.app.ActivityThread$ReceiverData
+android.app.ActivityThread$ServiceArgsData
+android.app.ActivityThread$StopInfo
+android.app.ActivityTransitionState
+android.app.AlertDialog
+android.app.AppGlobals
+android.app.AppOpsManager
+android.app.AppOpsManager$OnOpChangedListener
+android.app.Application
+android.app.Application$ActivityLifecycleCallbacks
+android.app.ApplicationErrorReport$CrashInfo
+android.app.ApplicationLoaders
+android.app.ApplicationPackageManager
+android.app.ApplicationPackageManager$OnPermissionsChangeListenerDelegate
+android.app.ApplicationPackageManager$ResourceName
+android.app.ContentProviderHolder
+android.app.ContentProviderHolder$1
+android.app.ContextImpl
+android.app.ContextImpl$ApplicationContentResolver
+android.app.DexLoadReporter
+android.app.Dialog
+android.app.Dialog$ListenersHandler
+android.app.DownloadManager
+android.app.Fragment
+android.app.FragmentContainer
+android.app.FragmentController
+android.app.FragmentHostCallback
+android.app.FragmentManager
+android.app.FragmentManagerImpl
+android.app.FragmentManagerImpl$1
+android.app.IActivityManager
+android.app.IActivityManager$Stub
+android.app.IActivityManager$Stub$Proxy
+android.app.IAlarmManager
+android.app.IAlarmManager$Stub
+android.app.IAlarmManager$Stub$Proxy
+android.app.IApplicationThread
+android.app.IApplicationThread$Stub
+android.app.IInstrumentationWatcher
+android.app.IInstrumentationWatcher$Stub
+android.app.INotificationManager
+android.app.INotificationManager$Stub
+android.app.INotificationManager$Stub$Proxy
+android.app.IServiceConnection
+android.app.IServiceConnection$Stub
+android.app.IUiAutomationConnection
+android.app.IUiAutomationConnection$Stub
+android.app.IUiModeManager
+android.app.IUiModeManager$Stub
+android.app.IUiModeManager$Stub$Proxy
+android.app.IUserSwitchObserver
+android.app.IUserSwitchObserver$Stub
+android.app.IWallpaperManager
+android.app.IWallpaperManager$Stub
+android.app.IWallpaperManagerCallback
+android.app.IWallpaperManagerCallback$Stub
+android.app.Instrumentation
+android.app.IntentReceiverLeaked
+android.app.IntentService
+android.app.IntentService$ServiceHandler
+android.app.JobSchedulerImpl
+android.app.KeyguardManager
+android.app.LoadedApk
+android.app.LoadedApk$ReceiverDispatcher
+android.app.LoadedApk$ReceiverDispatcher$Args
+android.app.LoadedApk$ReceiverDispatcher$InnerReceiver
+android.app.LoadedApk$ServiceDispatcher
+android.app.LoadedApk$ServiceDispatcher$ConnectionInfo
+android.app.LoadedApk$ServiceDispatcher$DeathMonitor
+android.app.LoadedApk$ServiceDispatcher$InnerConnection
+android.app.LoadedApk$ServiceDispatcher$RunConnection
+android.app.LoadedApk$WarningContextClassLoader
+android.app.LoaderManager
+android.app.LoaderManagerImpl
+android.app.NativeActivity
+android.app.Notification
+android.app.Notification$1
+android.app.Notification$Action
+android.app.Notification$Action$1
+android.app.Notification$BigPictureStyle
+android.app.Notification$BigTextStyle
+android.app.Notification$Builder
+android.app.Notification$BuilderRemoteViews
+android.app.Notification$DecoratedCustomViewStyle
+android.app.Notification$DecoratedMediaCustomViewStyle
+android.app.Notification$InboxStyle
+android.app.Notification$MediaStyle
+android.app.Notification$MessagingStyle
+android.app.Notification$StandardTemplateParams
+android.app.Notification$Style
+android.app.NotificationChannel
+android.app.NotificationChannel$1
+android.app.NotificationChannelGroup
+android.app.NotificationChannelGroup$1
+android.app.NotificationManager
+android.app.PendingIntent
+android.app.PendingIntent$1
+android.app.PendingIntent$CanceledException
+android.app.PendingIntent$OnMarshaledListener
+android.app.QueuedWork
+android.app.QueuedWork$QueuedWorkHandler
+android.app.ReceiverRestrictedContext
+android.app.RemoteInput
+android.app.ResourcesManager
+android.app.ResourcesManager$1
+android.app.ResourcesManager$ActivityResources
+android.app.ResultInfo
+android.app.ResultInfo$1
+android.app.Service
+android.app.ServiceConnectionLeaked
+android.app.ServiceStartArgs
+android.app.ServiceStartArgs$1
+android.app.SharedElementCallback
+android.app.SharedElementCallback$1
+android.app.SharedPreferencesImpl
+android.app.SharedPreferencesImpl$1
+android.app.SharedPreferencesImpl$2
+android.app.SharedPreferencesImpl$EditorImpl
+android.app.SharedPreferencesImpl$EditorImpl$1
+android.app.SharedPreferencesImpl$EditorImpl$2
+android.app.SharedPreferencesImpl$MemoryCommitResult
+android.app.StatusBarManager
+android.app.SystemServiceRegistry
+android.app.SystemServiceRegistry$1
+android.app.SystemServiceRegistry$10
+android.app.SystemServiceRegistry$11
+android.app.SystemServiceRegistry$12
+android.app.SystemServiceRegistry$13
+android.app.SystemServiceRegistry$14
+android.app.SystemServiceRegistry$15
+android.app.SystemServiceRegistry$16
+android.app.SystemServiceRegistry$17
+android.app.SystemServiceRegistry$18
+android.app.SystemServiceRegistry$19
+android.app.SystemServiceRegistry$2
+android.app.SystemServiceRegistry$20
+android.app.SystemServiceRegistry$21
+android.app.SystemServiceRegistry$22
+android.app.SystemServiceRegistry$23
+android.app.SystemServiceRegistry$24
+android.app.SystemServiceRegistry$25
+android.app.SystemServiceRegistry$26
+android.app.SystemServiceRegistry$27
+android.app.SystemServiceRegistry$28
+android.app.SystemServiceRegistry$29
+android.app.SystemServiceRegistry$3
+android.app.SystemServiceRegistry$30
+android.app.SystemServiceRegistry$31
+android.app.SystemServiceRegistry$32
+android.app.SystemServiceRegistry$33
+android.app.SystemServiceRegistry$34
+android.app.SystemServiceRegistry$35
+android.app.SystemServiceRegistry$36
+android.app.SystemServiceRegistry$37
+android.app.SystemServiceRegistry$38
+android.app.SystemServiceRegistry$39
+android.app.SystemServiceRegistry$4
+android.app.SystemServiceRegistry$40
+android.app.SystemServiceRegistry$41
+android.app.SystemServiceRegistry$42
+android.app.SystemServiceRegistry$43
+android.app.SystemServiceRegistry$44
+android.app.SystemServiceRegistry$45
+android.app.SystemServiceRegistry$46
+android.app.SystemServiceRegistry$47
+android.app.SystemServiceRegistry$48
+android.app.SystemServiceRegistry$49
+android.app.SystemServiceRegistry$5
+android.app.SystemServiceRegistry$50
+android.app.SystemServiceRegistry$51
+android.app.SystemServiceRegistry$52
+android.app.SystemServiceRegistry$53
+android.app.SystemServiceRegistry$54
+android.app.SystemServiceRegistry$55
+android.app.SystemServiceRegistry$56
+android.app.SystemServiceRegistry$57
+android.app.SystemServiceRegistry$58
+android.app.SystemServiceRegistry$59
+android.app.SystemServiceRegistry$6
+android.app.SystemServiceRegistry$60
+android.app.SystemServiceRegistry$61
+android.app.SystemServiceRegistry$62
+android.app.SystemServiceRegistry$63
+android.app.SystemServiceRegistry$64
+android.app.SystemServiceRegistry$65
+android.app.SystemServiceRegistry$66
+android.app.SystemServiceRegistry$67
+android.app.SystemServiceRegistry$68
+android.app.SystemServiceRegistry$69
+android.app.SystemServiceRegistry$7
+android.app.SystemServiceRegistry$70
+android.app.SystemServiceRegistry$71
+android.app.SystemServiceRegistry$72
+android.app.SystemServiceRegistry$73
+android.app.SystemServiceRegistry$74
+android.app.SystemServiceRegistry$75
+android.app.SystemServiceRegistry$76
+android.app.SystemServiceRegistry$77
+android.app.SystemServiceRegistry$78
+android.app.SystemServiceRegistry$79
+android.app.SystemServiceRegistry$8
+android.app.SystemServiceRegistry$80
+android.app.SystemServiceRegistry$81
+android.app.SystemServiceRegistry$82
+android.app.SystemServiceRegistry$9
+android.app.SystemServiceRegistry$CachedServiceFetcher
+android.app.SystemServiceRegistry$ServiceFetcher
+android.app.SystemServiceRegistry$StaticApplicationContextServiceFetcher
+android.app.SystemServiceRegistry$StaticServiceFetcher
+android.app.UiModeManager
+android.app.UserSwitchObserver
+android.app.VrManager
+android.app.WallpaperManager
+android.app.admin.DevicePolicyManager
+android.app.admin.IDevicePolicyManager
+android.app.admin.IDevicePolicyManager$Stub
+android.app.admin.IDevicePolicyManager$Stub$Proxy
+android.app.admin.SecurityLog
+android.app.admin.SecurityLog$SecurityEvent
+android.app.admin.SecurityLog$SecurityEvent$1
+android.app.backup.BackupAgent
+android.app.backup.BackupDataInput
+android.app.backup.BackupDataInput$EntityHeader
+android.app.backup.BackupDataOutput
+android.app.backup.BackupHelperDispatcher
+android.app.backup.BackupHelperDispatcher$Header
+android.app.backup.BackupManager
+android.app.backup.FileBackupHelperBase
+android.app.backup.FullBackup
+android.app.backup.FullBackupDataOutput
+android.app.backup.IBackupManager
+android.app.backup.IBackupManager$Stub
+android.app.backup.IBackupManager$Stub$Proxy
+android.app.job.IJobCallback
+android.app.job.IJobCallback$Stub
+android.app.job.IJobCallback$Stub$Proxy
+android.app.job.IJobScheduler
+android.app.job.IJobScheduler$Stub
+android.app.job.IJobScheduler$Stub$Proxy
+android.app.job.IJobService
+android.app.job.IJobService$Stub
+android.app.job.JobInfo
+android.app.job.JobInfo$1
+android.app.job.JobInfo$Builder
+android.app.job.JobInfo$TriggerContentUri
+android.app.job.JobInfo$TriggerContentUri$1
+android.app.job.JobParameters
+android.app.job.JobParameters$1
+android.app.job.JobScheduler
+android.app.job.JobService
+android.app.job.JobService$1
+android.app.job.JobServiceEngine
+android.app.job.JobServiceEngine$JobHandler
+android.app.job.JobServiceEngine$JobInterface
+android.app.trust.ITrustManager
+android.app.trust.ITrustManager$Stub
+android.app.trust.ITrustManager$Stub$Proxy
+android.app.trust.TrustManager
+android.app.usage.IUsageStatsManager
+android.app.usage.IUsageStatsManager$Stub
+android.app.usage.NetworkStatsManager
+android.app.usage.StorageStatsManager
+android.app.usage.UsageEvents
+android.app.usage.UsageEvents$1
+android.app.usage.UsageStatsManager
+android.appwidget.AppWidgetManager
+android.appwidget.AppWidgetProvider
+android.bluetooth.BluetoothActivityEnergyInfo
+android.bluetooth.BluetoothAdapter
+android.bluetooth.BluetoothAdapter$1
+android.bluetooth.BluetoothDevice
+android.bluetooth.BluetoothDevice$1
+android.bluetooth.BluetoothDevice$2
+android.bluetooth.BluetoothHeadset
+android.bluetooth.BluetoothHeadset$1
+android.bluetooth.BluetoothHeadset$2
+android.bluetooth.BluetoothHeadset$3
+android.bluetooth.BluetoothManager
+android.bluetooth.BluetoothProfile
+android.bluetooth.BluetoothProfile$ServiceListener
+android.bluetooth.IBluetooth
+android.bluetooth.IBluetooth$Stub
+android.bluetooth.IBluetooth$Stub$Proxy
+android.bluetooth.IBluetoothA2dp
+android.bluetooth.IBluetoothA2dp$Stub
+android.bluetooth.IBluetoothGatt
+android.bluetooth.IBluetoothGatt$Stub
+android.bluetooth.IBluetoothHeadset
+android.bluetooth.IBluetoothHeadset$Stub
+android.bluetooth.IBluetoothHeadset$Stub$Proxy
+android.bluetooth.IBluetoothManager
+android.bluetooth.IBluetoothManager$Stub
+android.bluetooth.IBluetoothManager$Stub$Proxy
+android.bluetooth.IBluetoothManagerCallback
+android.bluetooth.IBluetoothManagerCallback$Stub
+android.bluetooth.IBluetoothProfileServiceConnection
+android.bluetooth.IBluetoothProfileServiceConnection$Stub
+android.bluetooth.IBluetoothStateChangeCallback
+android.bluetooth.IBluetoothStateChangeCallback$Stub
+android.companion.CompanionDeviceManager
+android.content.AbstractThreadedSyncAdapter
+android.content.AbstractThreadedSyncAdapter$ISyncAdapterImpl
+android.content.ActivityNotFoundException
+android.content.BroadcastReceiver
+android.content.BroadcastReceiver$PendingResult
+android.content.BroadcastReceiver$PendingResult$1
+android.content.ClipboardManager
+android.content.ComponentCallbacks
+android.content.ComponentCallbacks2
+android.content.ComponentName
+android.content.ComponentName$1
+android.content.ContentProvider
+android.content.ContentProvider$Transport
+android.content.ContentProviderClient
+android.content.ContentProviderNative
+android.content.ContentProviderProxy
+android.content.ContentProviderResult
+android.content.ContentResolver
+android.content.ContentResolver$CursorWrapperInner
+android.content.ContentUris
+android.content.ContentValues
+android.content.ContentValues$1
+android.content.Context
+android.content.ContextWrapper
+android.content.DialogInterface
+android.content.DialogInterface$OnCancelListener
+android.content.DialogInterface$OnClickListener
+android.content.DialogInterface$OnDismissListener
+android.content.IContentProvider
+android.content.IContentService
+android.content.IContentService$Stub
+android.content.IContentService$Stub$Proxy
+android.content.IIntentReceiver
+android.content.IIntentReceiver$Stub
+android.content.IIntentSender
+android.content.IIntentSender$Stub
+android.content.IIntentSender$Stub$Proxy
+android.content.ISyncAdapter
+android.content.ISyncAdapter$Stub
+android.content.ISyncContext
+android.content.ISyncContext$Stub
+android.content.Intent
+android.content.Intent$1
+android.content.Intent$FilterComparison
+android.content.IntentFilter
+android.content.IntentFilter$1
+android.content.IntentFilter$MalformedMimeTypeException
+android.content.IntentSender
+android.content.IntentSender$SendIntentException
+android.content.OperationApplicationException
+android.content.RestrictionsManager
+android.content.ServiceConnection
+android.content.SharedPreferences
+android.content.SharedPreferences$Editor
+android.content.SharedPreferences$OnSharedPreferenceChangeListener
+android.content.SyncResult
+android.content.SyncResult$1
+android.content.SyncStats
+android.content.SyncStats$1
+android.content.UndoManager
+android.content.UndoOwner
+android.content.UriMatcher
+android.content.pm.ActivityInfo
+android.content.pm.ActivityInfo$1
+android.content.pm.ApplicationInfo
+android.content.pm.ApplicationInfo$1
+android.content.pm.BaseParceledListSlice
+android.content.pm.ComponentInfo
+android.content.pm.ConfigurationInfo
+android.content.pm.ConfigurationInfo$1
+android.content.pm.FeatureGroupInfo
+android.content.pm.FeatureGroupInfo$1
+android.content.pm.FeatureInfo
+android.content.pm.FeatureInfo$1
+android.content.pm.IOnPermissionsChangeListener
+android.content.pm.IOnPermissionsChangeListener$Stub
+android.content.pm.IPackageInstaller
+android.content.pm.IPackageInstaller$Stub
+android.content.pm.IPackageManager
+android.content.pm.IPackageManager$Stub
+android.content.pm.IPackageManager$Stub$Proxy
+android.content.pm.IShortcutService
+android.content.pm.IShortcutService$Stub
+android.content.pm.InstrumentationInfo
+android.content.pm.InstrumentationInfo$1
+android.content.pm.LauncherApps
+android.content.pm.PackageInfo
+android.content.pm.PackageInfo$1
+android.content.pm.PackageItemInfo
+android.content.pm.PackageManager
+android.content.pm.PackageManager$NameNotFoundException
+android.content.pm.PackageManager$OnPermissionsChangedListener
+android.content.pm.PackageParser$PackageParserException
+android.content.pm.ParceledListSlice
+android.content.pm.ParceledListSlice$1
+android.content.pm.PathPermission
+android.content.pm.PathPermission$1
+android.content.pm.PermissionInfo
+android.content.pm.PermissionInfo$1
+android.content.pm.ProviderInfo
+android.content.pm.ProviderInfo$1
+android.content.pm.ResolveInfo
+android.content.pm.ResolveInfo$1
+android.content.pm.ServiceInfo
+android.content.pm.ServiceInfo$1
+android.content.pm.ShortcutInfo
+android.content.pm.ShortcutInfo$1
+android.content.pm.ShortcutManager
+android.content.pm.Signature
+android.content.pm.Signature$1
+android.content.pm.UserInfo
+android.content.pm.UserInfo$1
+android.content.res.AssetFileDescriptor
+android.content.res.AssetFileDescriptor$1
+android.content.res.AssetManager
+android.content.res.AssetManager$AssetInputStream
+android.content.res.ColorStateList
+android.content.res.ColorStateList$1
+android.content.res.ColorStateList$ColorStateListFactory
+android.content.res.CompatResources
+android.content.res.CompatibilityInfo
+android.content.res.CompatibilityInfo$1
+android.content.res.CompatibilityInfo$2
+android.content.res.ComplexColor
+android.content.res.Configuration
+android.content.res.Configuration$1
+android.content.res.ConfigurationBoundResourceCache
+android.content.res.ConstantState
+android.content.res.DrawableCache
+android.content.res.GradientColor
+android.content.res.ObbInfo
+android.content.res.ObbInfo$1
+android.content.res.ObbScanner
+android.content.res.Resources
+android.content.res.Resources$NotFoundException
+android.content.res.Resources$Theme
+android.content.res.Resources$ThemeKey
+android.content.res.ResourcesImpl
+android.content.res.ResourcesImpl$ThemeImpl
+android.content.res.ResourcesKey
+android.content.res.StringBlock
+android.content.res.ThemedResourceCache
+android.content.res.TypedArray
+android.content.res.XmlBlock
+android.content.res.XmlBlock$Parser
+android.content.res.XmlResourceParser
+android.database.AbstractCursor
+android.database.AbstractCursor$SelfContentObserver
+android.database.AbstractWindowedCursor
+android.database.BulkCursorDescriptor
+android.database.BulkCursorDescriptor$1
+android.database.BulkCursorNative
+android.database.BulkCursorProxy
+android.database.BulkCursorToCursorAdaptor
+android.database.CharArrayBuffer
+android.database.ContentObservable
+android.database.ContentObserver
+android.database.ContentObserver$NotificationRunnable
+android.database.ContentObserver$Transport
+android.database.CrossProcessCursor
+android.database.CrossProcessCursorWrapper
+android.database.Cursor
+android.database.CursorIndexOutOfBoundsException
+android.database.CursorToBulkCursorAdaptor
+android.database.CursorToBulkCursorAdaptor$ContentObserverProxy
+android.database.CursorWindow
+android.database.CursorWindow$1
+android.database.CursorWrapper
+android.database.DataSetObservable
+android.database.DataSetObserver
+android.database.DatabaseErrorHandler
+android.database.DatabaseUtils
+android.database.DefaultDatabaseErrorHandler
+android.database.IBulkCursor
+android.database.IContentObserver
+android.database.IContentObserver$Stub
+android.database.IContentObserver$Stub$Proxy
+android.database.MatrixCursor
+android.database.Observable
+android.database.SQLException
+android.database.sqlite.DatabaseObjectNotClosedException
+android.database.sqlite.SQLiteCantOpenDatabaseException
+android.database.sqlite.SQLiteClosable
+android.database.sqlite.SQLiteConnection
+android.database.sqlite.SQLiteConnection$Operation
+android.database.sqlite.SQLiteConnection$OperationLog
+android.database.sqlite.SQLiteConnection$PreparedStatement
+android.database.sqlite.SQLiteConnection$PreparedStatementCache
+android.database.sqlite.SQLiteConnectionPool
+android.database.sqlite.SQLiteConnectionPool$AcquiredConnectionStatus
+android.database.sqlite.SQLiteConnectionPool$ConnectionWaiter
+android.database.sqlite.SQLiteCursor
+android.database.sqlite.SQLiteCursorDriver
+android.database.sqlite.SQLiteCustomFunction
+android.database.sqlite.SQLiteDatabase
+android.database.sqlite.SQLiteDatabase$1
+android.database.sqlite.SQLiteDatabaseConfiguration
+android.database.sqlite.SQLiteDatabaseCorruptException
+android.database.sqlite.SQLiteDatabaseLockedException
+android.database.sqlite.SQLiteDebug
+android.database.sqlite.SQLiteDebug$PagerStats
+android.database.sqlite.SQLiteDirectCursorDriver
+android.database.sqlite.SQLiteDoneException
+android.database.sqlite.SQLiteException
+android.database.sqlite.SQLiteGlobal
+android.database.sqlite.SQLiteOpenHelper
+android.database.sqlite.SQLiteProgram
+android.database.sqlite.SQLiteQuery
+android.database.sqlite.SQLiteQueryBuilder
+android.database.sqlite.SQLiteSession
+android.database.sqlite.SQLiteSession$Transaction
+android.database.sqlite.SQLiteStatement
+android.database.sqlite.SQLiteStatementInfo
+android.database.sqlite.SQLiteTransactionListener
+android.ddm.DdmHandleAppName
+android.ddm.DdmHandleExit
+android.ddm.DdmHandleHeap
+android.ddm.DdmHandleHello
+android.ddm.DdmHandleNativeHeap
+android.ddm.DdmHandleProfiling
+android.ddm.DdmHandleThread
+android.ddm.DdmHandleViewDebug
+android.ddm.DdmRegister
+android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8
+android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$1
+android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$2
+android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$4
+android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$6
+android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$7
+android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$8
+android.graphics.BaseCanvas
+android.graphics.Bitmap
+android.graphics.Bitmap$1
+android.graphics.Bitmap$CompressFormat
+android.graphics.Bitmap$Config
+android.graphics.BitmapFactory
+android.graphics.BitmapFactory$Options
+android.graphics.BitmapRegionDecoder
+android.graphics.BitmapShader
+android.graphics.BlurMaskFilter
+android.graphics.Camera
+android.graphics.Canvas
+android.graphics.Canvas$EdgeType
+android.graphics.Canvas$NoImagePreloadHolder
+android.graphics.CanvasProperty
+android.graphics.Color
+android.graphics.ColorFilter
+android.graphics.ColorMatrixColorFilter
+android.graphics.ColorSpace
+android.graphics.ColorSpace$Lab
+android.graphics.ColorSpace$Model
+android.graphics.ColorSpace$Named
+android.graphics.ColorSpace$Rgb
+android.graphics.ColorSpace$Rgb$TransferParameters
+android.graphics.ColorSpace$Xyz
+android.graphics.ComposePathEffect
+android.graphics.ComposeShader
+android.graphics.CornerPathEffect
+android.graphics.DashPathEffect
+android.graphics.DiscretePathEffect
+android.graphics.DrawFilter
+android.graphics.EmbossMaskFilter
+android.graphics.FontFamily
+android.graphics.FontListParser
+android.graphics.GraphicBuffer
+android.graphics.GraphicBuffer$1
+android.graphics.Insets
+android.graphics.Interpolator
+android.graphics.Interpolator$Result
+android.graphics.LightingColorFilter
+android.graphics.LinearGradient
+android.graphics.MaskFilter
+android.graphics.Matrix
+android.graphics.Matrix$1
+android.graphics.Matrix$NoImagePreloadHolder
+android.graphics.Matrix$ScaleToFit
+android.graphics.Movie
+android.graphics.NinePatch
+android.graphics.NinePatch$InsetStruct
+android.graphics.Outline
+android.graphics.Paint
+android.graphics.Paint$Align
+android.graphics.Paint$Cap
+android.graphics.Paint$FontMetrics
+android.graphics.Paint$FontMetricsInt
+android.graphics.Paint$Join
+android.graphics.Paint$NoImagePreloadHolder
+android.graphics.Paint$Style
+android.graphics.PaintFlagsDrawFilter
+android.graphics.Path
+android.graphics.Path$Direction
+android.graphics.Path$FillType
+android.graphics.PathDashPathEffect
+android.graphics.PathEffect
+android.graphics.PathMeasure
+android.graphics.Picture
+android.graphics.Point
+android.graphics.Point$1
+android.graphics.PointF
+android.graphics.PointF$1
+android.graphics.PorterDuff
+android.graphics.PorterDuff$Mode
+android.graphics.PorterDuffColorFilter
+android.graphics.PorterDuffXfermode
+android.graphics.RadialGradient
+android.graphics.Rect
+android.graphics.Rect$1
+android.graphics.RectF
+android.graphics.RectF$1
+android.graphics.Region
+android.graphics.Region$1
+android.graphics.Region$Op
+android.graphics.RegionIterator
+android.graphics.Shader
+android.graphics.Shader$TileMode
+android.graphics.SumPathEffect
+android.graphics.SurfaceTexture
+android.graphics.SweepGradient
+android.graphics.TableMaskFilter
+android.graphics.TemporaryBuffer
+android.graphics.Typeface
+android.graphics.Xfermode
+android.graphics.YuvImage
+android.graphics.drawable.AdaptiveIconDrawable
+android.graphics.drawable.Animatable
+android.graphics.drawable.Animatable2
+android.graphics.drawable.AnimatedStateListDrawable
+android.graphics.drawable.AnimatedStateListDrawable$AnimatedStateListState
+android.graphics.drawable.AnimatedVectorDrawable
+android.graphics.drawable.AnimatedVectorDrawable$1
+android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState
+android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator
+android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimator
+android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT
+android.graphics.drawable.AnimationDrawable
+android.graphics.drawable.AnimationDrawable$AnimationState
+android.graphics.drawable.BitmapDrawable
+android.graphics.drawable.BitmapDrawable$BitmapState
+android.graphics.drawable.ColorDrawable
+android.graphics.drawable.ColorDrawable$ColorState
+android.graphics.drawable.Drawable
+android.graphics.drawable.Drawable$Callback
+android.graphics.drawable.Drawable$ConstantState
+android.graphics.drawable.DrawableContainer
+android.graphics.drawable.DrawableContainer$BlockInvalidateCallback
+android.graphics.drawable.DrawableContainer$DrawableContainerState
+android.graphics.drawable.DrawableInflater
+android.graphics.drawable.DrawableWrapper
+android.graphics.drawable.DrawableWrapper$DrawableWrapperState
+android.graphics.drawable.GradientDrawable
+android.graphics.drawable.GradientDrawable$GradientState
+android.graphics.drawable.GradientDrawable$Orientation
+android.graphics.drawable.Icon
+android.graphics.drawable.Icon$1
+android.graphics.drawable.InsetDrawable
+android.graphics.drawable.InsetDrawable$InsetState
+android.graphics.drawable.InsetDrawable$InsetValue
+android.graphics.drawable.LayerDrawable
+android.graphics.drawable.LayerDrawable$ChildDrawable
+android.graphics.drawable.LayerDrawable$LayerState
+android.graphics.drawable.NinePatchDrawable
+android.graphics.drawable.NinePatchDrawable$NinePatchState
+android.graphics.drawable.RippleBackground
+android.graphics.drawable.RippleBackground$1
+android.graphics.drawable.RippleBackground$BackgroundProperty
+android.graphics.drawable.RippleComponent
+android.graphics.drawable.RippleComponent$RenderNodeAnimatorSet
+android.graphics.drawable.RippleDrawable
+android.graphics.drawable.RippleDrawable$RippleState
+android.graphics.drawable.RippleForeground
+android.graphics.drawable.RippleForeground$1
+android.graphics.drawable.RippleForeground$2
+android.graphics.drawable.RippleForeground$3
+android.graphics.drawable.RippleForeground$4
+android.graphics.drawable.RippleForeground$LogDecelerateInterpolator
+android.graphics.drawable.ScaleDrawable
+android.graphics.drawable.ScaleDrawable$ScaleState
+android.graphics.drawable.ShapeDrawable
+android.graphics.drawable.ShapeDrawable$ShapeState
+android.graphics.drawable.StateListDrawable
+android.graphics.drawable.StateListDrawable$StateListState
+android.graphics.drawable.TransitionDrawable
+android.graphics.drawable.TransitionDrawable$TransitionState
+android.graphics.drawable.VectorDrawable
+android.graphics.drawable.VectorDrawable$VFullPath
+android.graphics.drawable.VectorDrawable$VFullPath$1
+android.graphics.drawable.VectorDrawable$VFullPath$10
+android.graphics.drawable.VectorDrawable$VFullPath$2
+android.graphics.drawable.VectorDrawable$VFullPath$3
+android.graphics.drawable.VectorDrawable$VFullPath$4
+android.graphics.drawable.VectorDrawable$VFullPath$5
+android.graphics.drawable.VectorDrawable$VFullPath$6
+android.graphics.drawable.VectorDrawable$VFullPath$7
+android.graphics.drawable.VectorDrawable$VFullPath$8
+android.graphics.drawable.VectorDrawable$VFullPath$9
+android.graphics.drawable.VectorDrawable$VGroup
+android.graphics.drawable.VectorDrawable$VGroup$1
+android.graphics.drawable.VectorDrawable$VGroup$2
+android.graphics.drawable.VectorDrawable$VGroup$3
+android.graphics.drawable.VectorDrawable$VGroup$4
+android.graphics.drawable.VectorDrawable$VGroup$5
+android.graphics.drawable.VectorDrawable$VGroup$6
+android.graphics.drawable.VectorDrawable$VGroup$7
+android.graphics.drawable.VectorDrawable$VGroup$8
+android.graphics.drawable.VectorDrawable$VGroup$9
+android.graphics.drawable.VectorDrawable$VObject
+android.graphics.drawable.VectorDrawable$VPath
+android.graphics.drawable.VectorDrawable$VPath$1
+android.graphics.drawable.VectorDrawable$VectorDrawableState
+android.graphics.drawable.VectorDrawable$VectorDrawableState$1
+android.graphics.drawable.shapes.OvalShape
+android.graphics.drawable.shapes.RectShape
+android.graphics.drawable.shapes.Shape
+android.graphics.fonts.FontVariationAxis
+android.graphics.pdf.PdfDocument
+android.graphics.pdf.PdfEditor
+android.graphics.pdf.PdfRenderer
+android.hardware.Camera
+android.hardware.Camera$CameraInfo
+android.hardware.Camera$Face
+android.hardware.ConsumerIrManager
+android.hardware.HardwareBuffer
+android.hardware.HardwareBuffer$1
+android.hardware.ICameraService
+android.hardware.ICameraService$Stub
+android.hardware.ICameraService$Stub$Proxy
+android.hardware.Sensor
+android.hardware.SensorEvent
+android.hardware.SensorEventListener
+android.hardware.SensorManager
+android.hardware.SerialManager
+android.hardware.SerialPort
+android.hardware.SystemSensorManager
+android.hardware.SystemSensorManager$BaseEventQueue
+android.hardware.SystemSensorManager$SensorEventQueue
+android.hardware.camera2.CameraAccessException
+android.hardware.camera2.CameraCharacteristics
+android.hardware.camera2.CameraCharacteristics$1
+android.hardware.camera2.CameraCharacteristics$2
+android.hardware.camera2.CameraCharacteristics$3
+android.hardware.camera2.CameraCharacteristics$4
+android.hardware.camera2.CameraCharacteristics$5
+android.hardware.camera2.CameraCharacteristics$Key
+android.hardware.camera2.CameraManager
+android.hardware.camera2.CameraMetadata
+android.hardware.camera2.CaptureRequest
+android.hardware.camera2.CaptureRequest$1
+android.hardware.camera2.CaptureRequest$2
+android.hardware.camera2.CaptureRequest$Key
+android.hardware.camera2.CaptureResult
+android.hardware.camera2.CaptureResult$1
+android.hardware.camera2.CaptureResult$2
+android.hardware.camera2.CaptureResult$3
+android.hardware.camera2.CaptureResult$Key
+android.hardware.camera2.DngCreator
+android.hardware.camera2.impl.CameraMetadataNative
+android.hardware.camera2.impl.CameraMetadataNative$1
+android.hardware.camera2.impl.CameraMetadataNative$10
+android.hardware.camera2.impl.CameraMetadataNative$11
+android.hardware.camera2.impl.CameraMetadataNative$12
+android.hardware.camera2.impl.CameraMetadataNative$13
+android.hardware.camera2.impl.CameraMetadataNative$14
+android.hardware.camera2.impl.CameraMetadataNative$15
+android.hardware.camera2.impl.CameraMetadataNative$16
+android.hardware.camera2.impl.CameraMetadataNative$17
+android.hardware.camera2.impl.CameraMetadataNative$18
+android.hardware.camera2.impl.CameraMetadataNative$19
+android.hardware.camera2.impl.CameraMetadataNative$2
+android.hardware.camera2.impl.CameraMetadataNative$3
+android.hardware.camera2.impl.CameraMetadataNative$4
+android.hardware.camera2.impl.CameraMetadataNative$5
+android.hardware.camera2.impl.CameraMetadataNative$6
+android.hardware.camera2.impl.CameraMetadataNative$7
+android.hardware.camera2.impl.CameraMetadataNative$8
+android.hardware.camera2.impl.CameraMetadataNative$9
+android.hardware.camera2.impl.CameraMetadataNative$Key
+android.hardware.camera2.impl.GetCommand
+android.hardware.camera2.impl.SetCommand
+android.hardware.camera2.legacy.LegacyCameraDevice
+android.hardware.camera2.legacy.PerfMeasurement
+android.hardware.camera2.marshal.MarshalQueryable
+android.hardware.camera2.marshal.MarshalRegistry
+android.hardware.camera2.marshal.impl.MarshalQueryableArray
+android.hardware.camera2.marshal.impl.MarshalQueryableBlackLevelPattern
+android.hardware.camera2.marshal.impl.MarshalQueryableBoolean
+android.hardware.camera2.marshal.impl.MarshalQueryableColorSpaceTransform
+android.hardware.camera2.marshal.impl.MarshalQueryableEnum
+android.hardware.camera2.marshal.impl.MarshalQueryableHighSpeedVideoConfiguration
+android.hardware.camera2.marshal.impl.MarshalQueryableMeteringRectangle
+android.hardware.camera2.marshal.impl.MarshalQueryableNativeByteToInteger
+android.hardware.camera2.marshal.impl.MarshalQueryablePair
+android.hardware.camera2.marshal.impl.MarshalQueryableParcelable
+android.hardware.camera2.marshal.impl.MarshalQueryablePrimitive
+android.hardware.camera2.marshal.impl.MarshalQueryableRange
+android.hardware.camera2.marshal.impl.MarshalQueryableRect
+android.hardware.camera2.marshal.impl.MarshalQueryableReprocessFormatsMap
+android.hardware.camera2.marshal.impl.MarshalQueryableRggbChannelVector
+android.hardware.camera2.marshal.impl.MarshalQueryableSize
+android.hardware.camera2.marshal.impl.MarshalQueryableSizeF
+android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfiguration
+android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfigurationDuration
+android.hardware.camera2.marshal.impl.MarshalQueryableString
+android.hardware.camera2.params.BlackLevelPattern
+android.hardware.camera2.params.ColorSpaceTransform
+android.hardware.camera2.params.Face
+android.hardware.camera2.params.HighSpeedVideoConfiguration
+android.hardware.camera2.params.LensShadingMap
+android.hardware.camera2.params.MeteringRectangle
+android.hardware.camera2.params.ReprocessFormatsMap
+android.hardware.camera2.params.RggbChannelVector
+android.hardware.camera2.params.StreamConfiguration
+android.hardware.camera2.params.StreamConfigurationDuration
+android.hardware.camera2.params.StreamConfigurationMap
+android.hardware.camera2.params.TonemapCurve
+android.hardware.camera2.utils.TypeReference
+android.hardware.camera2.utils.TypeReference$SpecializedTypeReference
+android.hardware.display.DisplayManager
+android.hardware.display.DisplayManager$DisplayListener
+android.hardware.display.DisplayManagerGlobal
+android.hardware.display.DisplayManagerGlobal$DisplayListenerDelegate
+android.hardware.display.DisplayManagerGlobal$DisplayManagerCallback
+android.hardware.display.IDisplayManager
+android.hardware.display.IDisplayManager$Stub
+android.hardware.display.IDisplayManager$Stub$Proxy
+android.hardware.display.IDisplayManagerCallback
+android.hardware.display.IDisplayManagerCallback$Stub
+android.hardware.fingerprint.FingerprintManager
+android.hardware.hdmi.HdmiControlManager
+android.hardware.input.IInputDevicesChangedListener
+android.hardware.input.IInputDevicesChangedListener$Stub
+android.hardware.input.IInputManager
+android.hardware.input.IInputManager$Stub
+android.hardware.input.IInputManager$Stub$Proxy
+android.hardware.input.InputDeviceIdentifier
+android.hardware.input.InputDeviceIdentifier$1
+android.hardware.input.InputManager
+android.hardware.input.InputManager$InputDevicesChangedListener
+android.hardware.location.ActivityRecognitionHardware
+android.hardware.location.ContextHubManager
+android.hardware.location.IActivityRecognitionHardware
+android.hardware.location.IActivityRecognitionHardware$Stub
+android.hardware.radio.RadioManager
+android.hardware.radio.RadioManager$AmBandConfig
+android.hardware.radio.RadioManager$AmBandConfig$1
+android.hardware.radio.RadioManager$AmBandDescriptor
+android.hardware.radio.RadioManager$AmBandDescriptor$1
+android.hardware.radio.RadioManager$BandConfig
+android.hardware.radio.RadioManager$BandConfig$1
+android.hardware.radio.RadioManager$BandDescriptor
+android.hardware.radio.RadioManager$BandDescriptor$1
+android.hardware.radio.RadioManager$FmBandConfig
+android.hardware.radio.RadioManager$FmBandConfig$1
+android.hardware.radio.RadioManager$FmBandDescriptor
+android.hardware.radio.RadioManager$FmBandDescriptor$1
+android.hardware.radio.RadioManager$ModuleProperties
+android.hardware.radio.RadioManager$ModuleProperties$1
+android.hardware.radio.RadioManager$ProgramInfo
+android.hardware.radio.RadioManager$ProgramInfo$1
+android.hardware.radio.RadioMetadata
+android.hardware.radio.RadioMetadata$1
+android.hardware.radio.RadioModule
+android.hardware.radio.RadioTuner
+android.hardware.soundtrigger.SoundTrigger
+android.hardware.soundtrigger.SoundTrigger$ConfidenceLevel
+android.hardware.soundtrigger.SoundTrigger$ConfidenceLevel$1
+android.hardware.soundtrigger.SoundTrigger$GenericRecognitionEvent
+android.hardware.soundtrigger.SoundTrigger$GenericRecognitionEvent$1
+android.hardware.soundtrigger.SoundTrigger$GenericSoundModel
+android.hardware.soundtrigger.SoundTrigger$Keyphrase
+android.hardware.soundtrigger.SoundTrigger$Keyphrase$1
+android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionEvent
+android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionEvent$1
+android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionExtra
+android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionExtra$1
+android.hardware.soundtrigger.SoundTrigger$KeyphraseSoundModel
+android.hardware.soundtrigger.SoundTrigger$KeyphraseSoundModel$1
+android.hardware.soundtrigger.SoundTrigger$ModuleProperties
+android.hardware.soundtrigger.SoundTrigger$ModuleProperties$1
+android.hardware.soundtrigger.SoundTrigger$RecognitionConfig
+android.hardware.soundtrigger.SoundTrigger$RecognitionConfig$1
+android.hardware.soundtrigger.SoundTrigger$RecognitionEvent
+android.hardware.soundtrigger.SoundTrigger$RecognitionEvent$1
+android.hardware.soundtrigger.SoundTrigger$SoundModel
+android.hardware.soundtrigger.SoundTrigger$SoundModelEvent
+android.hardware.soundtrigger.SoundTrigger$SoundModelEvent$1
+android.hardware.soundtrigger.SoundTriggerModule
+android.hardware.usb.UsbDevice
+android.hardware.usb.UsbDeviceConnection
+android.hardware.usb.UsbManager
+android.hardware.usb.UsbRequest
+android.icu.impl.BMPSet
+android.icu.impl.CacheBase
+android.icu.impl.CacheValue
+android.icu.impl.CacheValue$NullValue
+android.icu.impl.CacheValue$SoftValue
+android.icu.impl.CacheValue$Strength
+android.icu.impl.CaseMapImpl
+android.icu.impl.CaseMapImpl$StringContextIterator
+android.icu.impl.CharTrie
+android.icu.impl.ClassLoaderUtil
+android.icu.impl.CurrencyData
+android.icu.impl.CurrencyData$CurrencyDisplayInfo
+android.icu.impl.CurrencyData$CurrencyDisplayInfoProvider
+android.icu.impl.CurrencyData$CurrencySpacingInfo
+android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingPattern
+android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingType
+android.icu.impl.ICUBinary
+android.icu.impl.ICUBinary$Authenticate
+android.icu.impl.ICUBinary$DatPackageReader
+android.icu.impl.ICUBinary$DatPackageReader$IsAcceptable
+android.icu.impl.ICUBinary$DataFile
+android.icu.impl.ICUBinary$PackageDataFile
+android.icu.impl.ICUCache
+android.icu.impl.ICUConfig
+android.icu.impl.ICUCurrencyDisplayInfoProvider
+android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo
+android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo$SpacingInfoSink
+android.icu.impl.ICUCurrencyMetaInfo
+android.icu.impl.ICUCurrencyMetaInfo$Collector
+android.icu.impl.ICUCurrencyMetaInfo$CurrencyCollector
+android.icu.impl.ICUCurrencyMetaInfo$UniqueList
+android.icu.impl.ICUData
+android.icu.impl.ICUDebug
+android.icu.impl.ICULocaleService
+android.icu.impl.ICULocaleService$ICUResourceBundleFactory
+android.icu.impl.ICULocaleService$LocaleKey
+android.icu.impl.ICULocaleService$LocaleKeyFactory
+android.icu.impl.ICUNotifier
+android.icu.impl.ICURWLock
+android.icu.impl.ICUResourceBundle
+android.icu.impl.ICUResourceBundle$1
+android.icu.impl.ICUResourceBundle$2
+android.icu.impl.ICUResourceBundle$3
+android.icu.impl.ICUResourceBundle$3$1
+android.icu.impl.ICUResourceBundle$4
+android.icu.impl.ICUResourceBundle$AvailEntry
+android.icu.impl.ICUResourceBundle$Loader
+android.icu.impl.ICUResourceBundle$OpenType
+android.icu.impl.ICUResourceBundle$WholeBundle
+android.icu.impl.ICUResourceBundleImpl
+android.icu.impl.ICUResourceBundleImpl$ResourceArray
+android.icu.impl.ICUResourceBundleImpl$ResourceContainer
+android.icu.impl.ICUResourceBundleImpl$ResourceInt
+android.icu.impl.ICUResourceBundleImpl$ResourceString
+android.icu.impl.ICUResourceBundleImpl$ResourceTable
+android.icu.impl.ICUResourceBundleReader
+android.icu.impl.ICUResourceBundleReader$Array
+android.icu.impl.ICUResourceBundleReader$Array16
+android.icu.impl.ICUResourceBundleReader$Array32
+android.icu.impl.ICUResourceBundleReader$Container
+android.icu.impl.ICUResourceBundleReader$IsAcceptable
+android.icu.impl.ICUResourceBundleReader$ReaderCache
+android.icu.impl.ICUResourceBundleReader$ReaderCacheKey
+android.icu.impl.ICUResourceBundleReader$ReaderValue
+android.icu.impl.ICUResourceBundleReader$ResourceCache
+android.icu.impl.ICUResourceBundleReader$ResourceCache$Level
+android.icu.impl.ICUResourceBundleReader$Table
+android.icu.impl.ICUResourceBundleReader$Table16
+android.icu.impl.ICUResourceBundleReader$Table1632
+android.icu.impl.ICUService
+android.icu.impl.ICUService$CacheEntry
+android.icu.impl.ICUService$Factory
+android.icu.impl.ICUService$Key
+android.icu.impl.IDNA2003
+android.icu.impl.LocaleIDParser
+android.icu.impl.LocaleIDs
+android.icu.impl.Norm2AllModes
+android.icu.impl.Norm2AllModes$1
+android.icu.impl.Norm2AllModes$ComposeNormalizer2
+android.icu.impl.Norm2AllModes$DecomposeNormalizer2
+android.icu.impl.Norm2AllModes$FCDNormalizer2
+android.icu.impl.Norm2AllModes$NFKCSingleton
+android.icu.impl.Norm2AllModes$NoopNormalizer2
+android.icu.impl.Norm2AllModes$Norm2AllModesSingleton
+android.icu.impl.Norm2AllModes$Normalizer2WithImpl
+android.icu.impl.Normalizer2Impl
+android.icu.impl.Normalizer2Impl$1
+android.icu.impl.Normalizer2Impl$IsAcceptable
+android.icu.impl.Pair
+android.icu.impl.PatternProps
+android.icu.impl.PluralRulesLoader
+android.icu.impl.ReplaceableUCharacterIterator
+android.icu.impl.RuleCharacterIterator
+android.icu.impl.SimpleCache
+android.icu.impl.SoftCache
+android.icu.impl.StandardPlural
+android.icu.impl.StringPrepDataReader
+android.icu.impl.Trie
+android.icu.impl.Trie$DataManipulate
+android.icu.impl.Trie$DefaultGetFoldingOffset
+android.icu.impl.Trie2
+android.icu.impl.Trie2$1
+android.icu.impl.Trie2$Range
+android.icu.impl.Trie2$Trie2Iterator
+android.icu.impl.Trie2$UTrie2Header
+android.icu.impl.Trie2$ValueMapper
+android.icu.impl.Trie2$ValueWidth
+android.icu.impl.Trie2_16
+android.icu.impl.UBiDiProps
+android.icu.impl.UBiDiProps$IsAcceptable
+android.icu.impl.UCaseProps
+android.icu.impl.UCaseProps$ContextIterator
+android.icu.impl.UCaseProps$IsAcceptable
+android.icu.impl.UCharacterProperty
+android.icu.impl.UCharacterProperty$1
+android.icu.impl.UCharacterProperty$10
+android.icu.impl.UCharacterProperty$11
+android.icu.impl.UCharacterProperty$12
+android.icu.impl.UCharacterProperty$13
+android.icu.impl.UCharacterProperty$14
+android.icu.impl.UCharacterProperty$15
+android.icu.impl.UCharacterProperty$16
+android.icu.impl.UCharacterProperty$17
+android.icu.impl.UCharacterProperty$18
+android.icu.impl.UCharacterProperty$19
+android.icu.impl.UCharacterProperty$2
+android.icu.impl.UCharacterProperty$20
+android.icu.impl.UCharacterProperty$21
+android.icu.impl.UCharacterProperty$22
+android.icu.impl.UCharacterProperty$23
+android.icu.impl.UCharacterProperty$3
+android.icu.impl.UCharacterProperty$4
+android.icu.impl.UCharacterProperty$5
+android.icu.impl.UCharacterProperty$6
+android.icu.impl.UCharacterProperty$7
+android.icu.impl.UCharacterProperty$8
+android.icu.impl.UCharacterProperty$9
+android.icu.impl.UCharacterProperty$BiDiIntProperty
+android.icu.impl.UCharacterProperty$BinaryProperty
+android.icu.impl.UCharacterProperty$CaseBinaryProperty
+android.icu.impl.UCharacterProperty$CombiningClassIntProperty
+android.icu.impl.UCharacterProperty$IntProperty
+android.icu.impl.UCharacterProperty$IsAcceptable
+android.icu.impl.UCharacterProperty$NormInertBinaryProperty
+android.icu.impl.UCharacterProperty$NormQuickCheckIntProperty
+android.icu.impl.URLHandler$URLVisitor
+android.icu.impl.UResource$Array
+android.icu.impl.UResource$Key
+android.icu.impl.UResource$Sink
+android.icu.impl.UResource$Table
+android.icu.impl.UResource$Value
+android.icu.impl.Utility
+android.icu.impl.locale.AsciiUtil
+android.icu.impl.locale.BaseLocale
+android.icu.impl.locale.BaseLocale$Cache
+android.icu.impl.locale.BaseLocale$Key
+android.icu.impl.locale.LocaleObjectCache
+android.icu.impl.locale.LocaleObjectCache$CacheEntry
+android.icu.impl.locale.LocaleSyntaxException
+android.icu.lang.UCharacter
+android.icu.lang.UCharacterEnums$ECharacterCategory
+android.icu.lang.UCharacterEnums$ECharacterDirection
+android.icu.math.BigDecimal
+android.icu.math.MathContext
+android.icu.text.BreakIterator
+android.icu.text.BreakIterator$BreakIteratorCache
+android.icu.text.BreakIterator$BreakIteratorServiceShim
+android.icu.text.BreakIteratorFactory
+android.icu.text.BreakIteratorFactory$BFService
+android.icu.text.BreakIteratorFactory$BFService$1RBBreakIteratorFactory
+android.icu.text.CaseMap
+android.icu.text.CaseMap$Upper
+android.icu.text.CurrencyDisplayNames
+android.icu.text.CurrencyMetaInfo
+android.icu.text.CurrencyMetaInfo$CurrencyDigits
+android.icu.text.CurrencyMetaInfo$CurrencyFilter
+android.icu.text.DecimalFormat
+android.icu.text.DecimalFormat$Unit
+android.icu.text.DecimalFormatSymbols
+android.icu.text.DecimalFormatSymbols$1
+android.icu.text.DecimalFormatSymbols$CacheData
+android.icu.text.DecimalFormatSymbols$DecFmtDataSink
+android.icu.text.DigitList
+android.icu.text.DisplayContext
+android.icu.text.DisplayContext$Type
+android.icu.text.IDNA
+android.icu.text.LanguageBreakEngine
+android.icu.text.Normalizer
+android.icu.text.Normalizer$FCDMode
+android.icu.text.Normalizer$Mode
+android.icu.text.Normalizer$ModeImpl
+android.icu.text.Normalizer$NFCMode
+android.icu.text.Normalizer$NFDMode
+android.icu.text.Normalizer$NFKCMode
+android.icu.text.Normalizer$NFKDMode
+android.icu.text.Normalizer$NFKDModeImpl
+android.icu.text.Normalizer$NONEMode
+android.icu.text.Normalizer$QuickCheckResult
+android.icu.text.Normalizer2
+android.icu.text.NumberFormat
+android.icu.text.NumberFormat$Field
+android.icu.text.NumberingSystem
+android.icu.text.NumberingSystem$1
+android.icu.text.NumberingSystem$2
+android.icu.text.NumberingSystem$LocaleLookupData
+android.icu.text.PluralRanges
+android.icu.text.PluralRanges$Matrix
+android.icu.text.PluralRules
+android.icu.text.PluralRules$1
+android.icu.text.PluralRules$AndConstraint
+android.icu.text.PluralRules$BinaryConstraint
+android.icu.text.PluralRules$Constraint
+android.icu.text.PluralRules$Factory
+android.icu.text.PluralRules$FixedDecimal
+android.icu.text.PluralRules$FixedDecimalRange
+android.icu.text.PluralRules$FixedDecimalSamples
+android.icu.text.PluralRules$Operand
+android.icu.text.PluralRules$PluralType
+android.icu.text.PluralRules$RangeConstraint
+android.icu.text.PluralRules$Rule
+android.icu.text.PluralRules$RuleList
+android.icu.text.PluralRules$SampleType
+android.icu.text.PluralRules$SimpleTokenizer
+android.icu.text.RBBIDataWrapper
+android.icu.text.RBBIDataWrapper$IsAcceptable
+android.icu.text.RBBIDataWrapper$RBBIDataHeader
+android.icu.text.RBBIDataWrapper$TrieFoldingFunc
+android.icu.text.Replaceable
+android.icu.text.ReplaceableString
+android.icu.text.RuleBasedBreakIterator
+android.icu.text.RuleBasedBreakIterator$LookAheadResults
+android.icu.text.StringPrep
+android.icu.text.StringPrepParseException
+android.icu.text.TimeZoneNames$NameType
+android.icu.text.UCharacterIterator
+android.icu.text.UFieldPosition
+android.icu.text.UFormat
+android.icu.text.UForwardCharacterIterator
+android.icu.text.UTF16
+android.icu.text.UnhandledBreakEngine
+android.icu.text.UnicodeFilter
+android.icu.text.UnicodeMatcher
+android.icu.text.UnicodeSet
+android.icu.util.Currency
+android.icu.util.Currency$1
+android.icu.util.Currency$CurrencyUsage
+android.icu.util.Currency$EquivalenceRelation
+android.icu.util.Freezable
+android.icu.util.MeasureUnit
+android.icu.util.MeasureUnit$1
+android.icu.util.MeasureUnit$2
+android.icu.util.MeasureUnit$3
+android.icu.util.MeasureUnit$Factory
+android.icu.util.TimeUnit
+android.icu.util.TimeZone
+android.icu.util.TimeZone$ConstantZone
+android.icu.util.ULocale
+android.icu.util.ULocale$1
+android.icu.util.ULocale$2
+android.icu.util.ULocale$Category
+android.icu.util.ULocale$JDKLocaleHelper
+android.icu.util.ULocale$Type
+android.icu.util.UResourceBundle
+android.icu.util.UResourceBundle$RootType
+android.icu.util.UResourceTypeMismatchException
+android.icu.util.VersionInfo
+android.location.BatchedLocationCallbackTransport
+android.location.BatchedLocationCallbackTransport$CallbackTransport
+android.location.CountryDetector
+android.location.GnssMeasurementCallbackTransport
+android.location.GnssMeasurementCallbackTransport$ListenerTransport
+android.location.GnssNavigationMessageCallbackTransport
+android.location.GnssNavigationMessageCallbackTransport$ListenerTransport
+android.location.IBatchedLocationCallback
+android.location.IBatchedLocationCallback$Stub
+android.location.IGnssMeasurementsListener
+android.location.IGnssMeasurementsListener$Stub
+android.location.IGnssNavigationMessageListener
+android.location.IGnssNavigationMessageListener$Stub
+android.location.ILocationManager
+android.location.ILocationManager$Stub
+android.location.ILocationManager$Stub$Proxy
+android.location.LocalListenerHelper
+android.location.Location
+android.location.LocationListener
+android.location.LocationManager
+android.location.LocationRequest
+android.location.LocationRequest$1
+android.media.AudioAttributes
+android.media.AudioAttributes$1
+android.media.AudioAttributes$Builder
+android.media.AudioDevicePort
+android.media.AudioDevicePortConfig
+android.media.AudioFormat
+android.media.AudioFormat$1
+android.media.AudioGain
+android.media.AudioGainConfig
+android.media.AudioHandle
+android.media.AudioManager
+android.media.AudioManager$1
+android.media.AudioManager$2
+android.media.AudioManager$3
+android.media.AudioManager$ServiceEventHandlerDelegate
+android.media.AudioManager$ServiceEventHandlerDelegate$1
+android.media.AudioMixPort
+android.media.AudioMixPortConfig
+android.media.AudioPatch
+android.media.AudioPort
+android.media.AudioPortConfig
+android.media.AudioPortEventHandler
+android.media.AudioRecord
+android.media.AudioRouting
+android.media.AudioSystem
+android.media.AudioTimestamp
+android.media.AudioTrack
+android.media.CamcorderProfile
+android.media.CameraProfile
+android.media.DecoderCapabilities
+android.media.EncoderCapabilities
+android.media.IAudioFocusDispatcher
+android.media.IAudioFocusDispatcher$Stub
+android.media.IAudioService
+android.media.IAudioService$Stub
+android.media.IAudioService$Stub$Proxy
+android.media.IMediaHTTPConnection
+android.media.IMediaHTTPConnection$Stub
+android.media.IPlaybackConfigDispatcher
+android.media.IPlaybackConfigDispatcher$Stub
+android.media.IPlayer
+android.media.IPlayer$Stub
+android.media.IRecordingConfigDispatcher
+android.media.IRecordingConfigDispatcher$Stub
+android.media.IRingtonePlayer
+android.media.IRingtonePlayer$Stub
+android.media.Image
+android.media.ImageReader
+android.media.ImageReader$SurfaceImage
+android.media.ImageWriter
+android.media.ImageWriter$WriterSurfaceImage
+android.media.JetPlayer
+android.media.MediaCodec
+android.media.MediaCodecList
+android.media.MediaCrypto
+android.media.MediaDescrambler
+android.media.MediaDrm
+android.media.MediaExtractor
+android.media.MediaFormat
+android.media.MediaHTTPConnection
+android.media.MediaMetadataRetriever
+android.media.MediaMuxer
+android.media.MediaPlayer
+android.media.MediaRecorder
+android.media.MediaRouter
+android.media.MediaScanner
+android.media.MediaSync
+android.media.PlaybackParams
+android.media.PlaybackParams$1
+android.media.PlayerBase
+android.media.PlayerBase$IAppOpsCallbackWrapper
+android.media.PlayerBase$IPlayerWrapper
+android.media.PlayerBase$PlayerIdCard
+android.media.PlayerBase$PlayerIdCard$1
+android.media.RemoteDisplay
+android.media.ResampleInputStream
+android.media.SoundPool
+android.media.SubtitleController$Listener
+android.media.ToneGenerator
+android.media.VolumeAutomation
+android.media.VolumeShaper$Configuration
+android.media.VolumeShaper$Configuration$1
+android.media.VolumeShaper$Configuration$Builder
+android.media.VolumeShaper$Operation
+android.media.VolumeShaper$Operation$1
+android.media.VolumeShaper$Operation$Builder
+android.media.VolumeShaper$State
+android.media.VolumeShaper$State$1
+android.media.audiopolicy.AudioMix
+android.media.audiopolicy.AudioMixingRule
+android.media.audiopolicy.AudioMixingRule$AudioMixMatchCriterion
+android.media.midi.MidiManager
+android.media.projection.MediaProjectionManager
+android.media.session.IActiveSessionsListener
+android.media.session.IActiveSessionsListener$Stub
+android.media.session.ISessionController
+android.media.session.ISessionController$Stub
+android.media.session.ISessionControllerCallback
+android.media.session.ISessionControllerCallback$Stub
+android.media.session.ISessionManager
+android.media.session.ISessionManager$Stub
+android.media.session.MediaController
+android.media.session.MediaController$CallbackStub
+android.media.session.MediaController$TransportControls
+android.media.session.MediaSession$Token
+android.media.session.MediaSession$Token$1
+android.media.session.MediaSessionManager
+android.media.session.PlaybackState
+android.media.session.PlaybackState$1
+android.media.session.PlaybackState$CustomAction
+android.media.session.PlaybackState$CustomAction$1
+android.media.soundtrigger.SoundTriggerManager
+android.media.tv.TvInputManager
+android.mtp.MtpDatabase
+android.mtp.MtpDevice
+android.mtp.MtpDeviceInfo
+android.mtp.MtpEvent
+android.mtp.MtpObjectInfo
+android.mtp.MtpPropertyGroup
+android.mtp.MtpPropertyList
+android.mtp.MtpServer
+android.mtp.MtpStorage
+android.mtp.MtpStorageInfo
+android.net.ConnectivityManager
+android.net.ConnectivityManager$CallbackHandler
+android.net.ConnectivityManager$NetworkCallback
+android.net.ConnectivityThread
+android.net.Credentials
+android.net.DhcpInfo
+android.net.DhcpInfo$1
+android.net.EthernetManager
+android.net.IConnectivityManager
+android.net.IConnectivityManager$Stub
+android.net.IConnectivityManager$Stub$Proxy
+android.net.INetworkPolicyManager
+android.net.INetworkPolicyManager$Stub
+android.net.INetworkScoreService
+android.net.INetworkScoreService$Stub
+android.net.INetworkScoreService$Stub$Proxy
+android.net.INetworkStatsService
+android.net.INetworkStatsService$Stub
+android.net.INetworkStatsService$Stub$Proxy
+android.net.IpConfiguration
+android.net.IpConfiguration$1
+android.net.IpConfiguration$IpAssignment
+android.net.IpConfiguration$ProxySettings
+android.net.IpPrefix
+android.net.IpPrefix$1
+android.net.IpSecManager
+android.net.LinkAddress
+android.net.LinkAddress$1
+android.net.LinkProperties
+android.net.LinkProperties$1
+android.net.LocalServerSocket
+android.net.LocalSocket
+android.net.LocalSocketAddress
+android.net.LocalSocketAddress$Namespace
+android.net.LocalSocketImpl
+android.net.LocalSocketImpl$SocketInputStream
+android.net.LocalSocketImpl$SocketOutputStream
+android.net.Network
+android.net.Network$1
+android.net.NetworkCapabilities
+android.net.NetworkCapabilities$1
+android.net.NetworkFactory
+android.net.NetworkInfo
+android.net.NetworkInfo$1
+android.net.NetworkInfo$DetailedState
+android.net.NetworkInfo$State
+android.net.NetworkKey
+android.net.NetworkKey$1
+android.net.NetworkPolicyManager
+android.net.NetworkRequest
+android.net.NetworkRequest$1
+android.net.NetworkRequest$Builder
+android.net.NetworkRequest$Type
+android.net.NetworkScoreManager
+android.net.NetworkSpecifier
+android.net.NetworkStats
+android.net.NetworkStats$1
+android.net.NetworkUtils
+android.net.Proxy
+android.net.ProxyInfo
+android.net.RouteInfo
+android.net.RouteInfo$1
+android.net.RssiCurve
+android.net.RssiCurve$1
+android.net.SSLCertificateSocketFactory
+android.net.SSLCertificateSocketFactory$1
+android.net.SSLSessionCache
+android.net.ScoredNetwork
+android.net.ScoredNetwork$1
+android.net.StaticIpConfiguration
+android.net.TrafficStats
+android.net.Uri
+android.net.Uri$1
+android.net.Uri$AbstractHierarchicalUri
+android.net.Uri$AbstractPart
+android.net.Uri$Builder
+android.net.Uri$HierarchicalUri
+android.net.Uri$OpaqueUri
+android.net.Uri$Part
+android.net.Uri$Part$EmptyPart
+android.net.Uri$PathPart
+android.net.Uri$PathSegments
+android.net.Uri$PathSegmentsBuilder
+android.net.Uri$StringUri
+android.net.WifiKey
+android.net.WifiKey$1
+android.net.nsd.NsdManager
+android.net.wifi.IWifiManager
+android.net.wifi.IWifiManager$Stub
+android.net.wifi.IWifiManager$Stub$Proxy
+android.net.wifi.ParcelUtil
+android.net.wifi.RttManager
+android.net.wifi.ScanResult
+android.net.wifi.ScanResult$1
+android.net.wifi.ScanResult$InformationElement
+android.net.wifi.SupplicantState
+android.net.wifi.SupplicantState$1
+android.net.wifi.WifiConfiguration
+android.net.wifi.WifiConfiguration$1
+android.net.wifi.WifiConfiguration$NetworkSelectionStatus
+android.net.wifi.WifiEnterpriseConfig
+android.net.wifi.WifiEnterpriseConfig$1
+android.net.wifi.WifiInfo
+android.net.wifi.WifiInfo$1
+android.net.wifi.WifiManager
+android.net.wifi.WifiManager$WifiLock
+android.net.wifi.WifiScanner
+android.net.wifi.WifiSsid
+android.net.wifi.WifiSsid$1
+android.net.wifi.aware.WifiAwareManager
+android.net.wifi.p2p.WifiP2pManager
+android.nfc.NfcManager
+android.opengl.EGL14
+android.opengl.EGLConfig
+android.opengl.EGLContext
+android.opengl.EGLDisplay
+android.opengl.EGLExt
+android.opengl.EGLObjectHandle
+android.opengl.EGLSurface
+android.opengl.ETC1
+android.opengl.GLES10
+android.opengl.GLES10Ext
+android.opengl.GLES11
+android.opengl.GLES11Ext
+android.opengl.GLES20
+android.opengl.GLES30
+android.opengl.GLES31
+android.opengl.GLES31Ext
+android.opengl.GLES32
+android.opengl.GLUtils
+android.opengl.Matrix
+android.opengl.Visibility
+android.os.-$Lambda$6x30vPJhBKUfNY8tswxuZo3DCe0
+android.os.AsyncResult
+android.os.AsyncTask$1
+android.os.AsyncTask$2
+android.os.AsyncTask$3
+android.os.AsyncTask$AsyncTaskResult
+android.os.AsyncTask$InternalHandler
+android.os.AsyncTask$SerialExecutor
+android.os.AsyncTask$SerialExecutor$1
+android.os.AsyncTask$Status
+android.os.AsyncTask$WorkerRunnable
+android.os.BadParcelableException
+android.os.BaseBundle
+android.os.BaseBundle$NoImagePreloadHolder
+android.os.BatteryManager
+android.os.Binder
+android.os.BinderProxy
+android.os.Build
+android.os.Build$VERSION
+android.os.Bundle
+android.os.Bundle$1
+android.os.CancellationSignal
+android.os.CancellationSignal$OnCancelListener
+android.os.CancellationSignal$Transport
+android.os.ConditionVariable
+android.os.DeadObjectException
+android.os.DeadSystemException
+android.os.Debug
+android.os.Debug$MemoryInfo
+android.os.Debug$MemoryInfo$1
+android.os.DropBoxManager
+android.os.Environment
+android.os.Environment$UserEnvironment
+android.os.FactoryTest
+android.os.FileObserver$ObserverThread
+android.os.FileUtils
+android.os.GraphicsEnvironment
+android.os.Handler
+android.os.Handler$Callback
+android.os.Handler$MessengerImpl
+android.os.HandlerThread
+android.os.HardwarePropertiesManager
+android.os.HwBinder
+android.os.HwBlob
+android.os.HwParcel
+android.os.HwRemoteBinder
+android.os.IBatteryPropertiesRegistrar
+android.os.IBatteryPropertiesRegistrar$Stub
+android.os.IBatteryPropertiesRegistrar$Stub$Proxy
+android.os.IBinder
+android.os.IBinder$DeathRecipient
+android.os.ICancellationSignal
+android.os.ICancellationSignal$Stub
+android.os.IDeviceIdleController
+android.os.IDeviceIdleController$Stub
+android.os.IHwBinder
+android.os.IInterface
+android.os.IMessenger
+android.os.IMessenger$Stub
+android.os.IMessenger$Stub$Proxy
+android.os.INetworkManagementService
+android.os.INetworkManagementService$Stub
+android.os.INetworkManagementService$Stub$Proxy
+android.os.IPowerManager
+android.os.IPowerManager$Stub
+android.os.IPowerManager$Stub$Proxy
+android.os.IRemoteCallback
+android.os.IServiceManager
+android.os.IUserManager
+android.os.IUserManager$Stub
+android.os.IUserManager$Stub$Proxy
+android.os.IVibratorService
+android.os.IVibratorService$Stub
+android.os.IncidentManager
+android.os.LocaleList
+android.os.LocaleList$1
+android.os.Looper
+android.os.MemoryFile
+android.os.Message
+android.os.Message$1
+android.os.MessageQueue
+android.os.MessageQueue$IdleHandler
+android.os.Messenger
+android.os.Messenger$1
+android.os.OperationCanceledException
+android.os.Parcel
+android.os.Parcel$1
+android.os.ParcelFileDescriptor
+android.os.ParcelFileDescriptor$1
+android.os.ParcelUuid
+android.os.ParcelUuid$1
+android.os.Parcelable
+android.os.Parcelable$ClassLoaderCreator
+android.os.Parcelable$Creator
+android.os.ParcelableException
+android.os.PatternMatcher
+android.os.PatternMatcher$1
+android.os.PersistableBundle
+android.os.PersistableBundle$1
+android.os.PowerManager
+android.os.PowerManager$WakeLock
+android.os.PowerManager$WakeLock$1
+android.os.Process
+android.os.RecoverySystem
+android.os.Registrant
+android.os.RemoteCallbackList
+android.os.RemoteException
+android.os.ResultReceiver
+android.os.SELinux
+android.os.Seccomp
+android.os.ServiceManager
+android.os.ServiceManager$ServiceNotFoundException
+android.os.ServiceManagerNative
+android.os.ServiceManagerProxy
+android.os.ServiceSpecificException
+android.os.ShellCallback
+android.os.StatFs
+android.os.StrictMode
+android.os.StrictMode$1
+android.os.StrictMode$2
+android.os.StrictMode$3
+android.os.StrictMode$4
+android.os.StrictMode$5
+android.os.StrictMode$6
+android.os.StrictMode$7
+android.os.StrictMode$8
+android.os.StrictMode$9
+android.os.StrictMode$AndroidBlockGuardPolicy
+android.os.StrictMode$AndroidBlockGuardPolicy$1
+android.os.StrictMode$AndroidCloseGuardReporter
+android.os.StrictMode$InstanceCountViolation
+android.os.StrictMode$InstanceTracker
+android.os.StrictMode$LogStackTrace
+android.os.StrictMode$Span
+android.os.StrictMode$StrictModeDiskReadViolation
+android.os.StrictMode$StrictModeDiskWriteViolation
+android.os.StrictMode$StrictModeViolation
+android.os.StrictMode$ThreadPolicy
+android.os.StrictMode$ThreadPolicy$Builder
+android.os.StrictMode$ThreadSpanState
+android.os.StrictMode$ViolationInfo
+android.os.StrictMode$ViolationInfo$1
+android.os.StrictMode$VmPolicy
+android.os.StrictMode$VmPolicy$Builder
+android.os.SystemClock
+android.os.SystemProperties
+android.os.SystemVibrator
+android.os.Trace
+android.os.Trace$1
+android.os.UEventObserver
+android.os.UpdateLock
+android.os.UserHandle
+android.os.UserHandle$1
+android.os.UserManager
+android.os.Vibrator
+android.os.VintfObject
+android.os.VintfRuntimeInfo
+android.os.WorkSource
+android.os.WorkSource$1
+android.os.ZygoteProcess
+android.os.ZygoteStartFailedEx
+android.os.health.SystemHealthManager
+android.os.storage.IObbActionListener
+android.os.storage.IObbActionListener$Stub
+android.os.storage.IStorageManager
+android.os.storage.IStorageManager$Stub
+android.os.storage.IStorageManager$Stub$Proxy
+android.os.storage.StorageManager
+android.os.storage.StorageManager$ObbActionListener
+android.os.storage.StorageVolume
+android.os.storage.StorageVolume$1
+android.preference.PreferenceManager
+android.print.PrintManager
+android.provider.-$Lambda$87WmhkvObehVg0OMBzwa_MTVV8g
+android.provider.-$Lambda$a7Jyr6j_Mb70hHJ2ssL1AAhKh4c
+android.provider.BaseColumns
+android.provider.CalendarContract$CalendarColumns
+android.provider.CalendarContract$CalendarSyncColumns
+android.provider.CalendarContract$EventsColumns
+android.provider.CalendarContract$SyncColumns
+android.provider.ContactsContract
+android.provider.ContactsContract$CommonDataKinds$BaseTypes
+android.provider.ContactsContract$CommonDataKinds$CommonColumns
+android.provider.ContactsContract$ContactCounts
+android.provider.ContactsContract$ContactNameColumns
+android.provider.ContactsContract$ContactOptionsColumns
+android.provider.ContactsContract$ContactStatusColumns
+android.provider.ContactsContract$ContactsColumns
+android.provider.ContactsContract$DataColumns
+android.provider.ContactsContract$DataColumnsWithJoins
+android.provider.ContactsContract$DataUsageStatColumns
+android.provider.ContactsContract$RawContactsColumns
+android.provider.ContactsContract$StatusColumns
+android.provider.Downloads$Impl
+android.provider.FontsContract
+android.provider.FontsContract$1
+android.provider.Settings
+android.provider.Settings$ContentProviderHolder
+android.provider.Settings$GenerationTracker
+android.provider.Settings$Global
+android.provider.Settings$NameValueCache
+android.provider.Settings$NameValueTable
+android.provider.Settings$Secure
+android.provider.Settings$SettingNotFoundException
+android.provider.Settings$System
+android.provider.Settings$System$1
+android.provider.Settings$System$2
+android.provider.Settings$System$3
+android.provider.Settings$System$4
+android.provider.Settings$System$5
+android.provider.Settings$System$6
+android.provider.Settings$System$7
+android.provider.Settings$System$8
+android.provider.Settings$System$9
+android.provider.Settings$System$DiscreteValueValidator
+android.provider.Settings$System$InclusiveFloatRangeValidator
+android.provider.Settings$System$InclusiveIntegerRangeValidator
+android.provider.Settings$System$Validator
+android.renderscript.RenderScriptCacheDir
+android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
+android.security.keystore.AndroidKeyStoreProvider
+android.security.net.config.ApplicationConfig
+android.security.net.config.CertificateSource
+android.security.net.config.CertificatesEntryRef
+android.security.net.config.ConfigNetworkSecurityPolicy
+android.security.net.config.ConfigSource
+android.security.net.config.DirectoryCertificateSource
+android.security.net.config.DirectoryCertificateSource$1
+android.security.net.config.DirectoryCertificateSource$3
+android.security.net.config.DirectoryCertificateSource$CertSelector
+android.security.net.config.ManifestConfigSource
+android.security.net.config.ManifestConfigSource$DefaultConfigSource
+android.security.net.config.NetworkSecurityConfig
+android.security.net.config.NetworkSecurityConfig$1
+android.security.net.config.NetworkSecurityConfig$Builder
+android.security.net.config.NetworkSecurityConfigProvider
+android.security.net.config.NetworkSecurityTrustManager
+android.security.net.config.PinSet
+android.security.net.config.RootTrustManager
+android.security.net.config.RootTrustManagerFactorySpi
+android.security.net.config.SystemCertificateSource
+android.security.net.config.TrustedCertificateStoreAdapter
+android.security.net.config.UserCertificateSource
+android.service.notification.StatusBarNotification
+android.service.oemlock.OemLockManager
+android.service.persistentdata.IPersistentDataBlockService
+android.service.persistentdata.IPersistentDataBlockService$Stub
+android.service.persistentdata.IPersistentDataBlockService$Stub$Proxy
+android.service.persistentdata.PersistentDataBlockManager
+android.system.ErrnoException
+android.system.GaiException
+android.system.NetlinkSocketAddress
+android.system.Os
+android.system.OsConstants
+android.system.PacketSocketAddress
+android.system.StructAddrinfo
+android.system.StructFlock
+android.system.StructGroupReq
+android.system.StructIfaddrs
+android.system.StructLinger
+android.system.StructPasswd
+android.system.StructPollfd
+android.system.StructStat
+android.system.StructStatVfs
+android.system.StructTimeval
+android.system.StructUcred
+android.system.StructUtsname
+android.system.UnixSocketAddress
+android.telecom.TelecomManager
+android.telephony.CarrierConfigManager
+android.telephony.CellIdentityWcdma
+android.telephony.CellIdentityWcdma$1
+android.telephony.CellInfo
+android.telephony.CellInfo$1
+android.telephony.CellInfoWcdma
+android.telephony.CellInfoWcdma$1
+android.telephony.CellLocation
+android.telephony.CellSignalStrength
+android.telephony.CellSignalStrengthWcdma
+android.telephony.CellSignalStrengthWcdma$1
+android.telephony.PhoneStateListener
+android.telephony.PhoneStateListener$1
+android.telephony.PhoneStateListener$IPhoneStateListenerStub
+android.telephony.Rlog
+android.telephony.ServiceState
+android.telephony.ServiceState$1
+android.telephony.SignalStrength
+android.telephony.SignalStrength$1
+android.telephony.SubscriptionInfo
+android.telephony.SubscriptionInfo$1
+android.telephony.SubscriptionManager
+android.telephony.SubscriptionManager$OnSubscriptionsChangedListener
+android.telephony.SubscriptionManager$OnSubscriptionsChangedListener$1
+android.telephony.SubscriptionManager$OnSubscriptionsChangedListener$2
+android.telephony.TelephonyManager
+android.telephony.TelephonyManager$MultiSimVariants
+android.text.AndroidBidi
+android.text.AndroidCharacter
+android.text.BoringLayout
+android.text.BoringLayout$Metrics
+android.text.ClipboardManager
+android.text.DynamicLayout
+android.text.DynamicLayout$ChangeWatcher
+android.text.Editable
+android.text.Editable$Factory
+android.text.FontConfig
+android.text.FontConfig$Alias
+android.text.FontConfig$Family
+android.text.FontConfig$Font
+android.text.GetChars
+android.text.GraphicsOperations
+android.text.Hyphenator
+android.text.Hyphenator$HyphenationData
+android.text.InputFilter
+android.text.InputType
+android.text.Layout
+android.text.Layout$Alignment
+android.text.Layout$Directions
+android.text.Layout$Ellipsizer
+android.text.MeasuredText
+android.text.NoCopySpan
+android.text.NoCopySpan$Concrete
+android.text.PackedIntVector
+android.text.PackedObjectVector
+android.text.ParcelableSpan
+android.text.Selection
+android.text.Selection$END
+android.text.Selection$START
+android.text.SpanSet
+android.text.SpanWatcher
+android.text.Spannable
+android.text.Spannable$Factory
+android.text.SpannableString
+android.text.SpannableStringBuilder
+android.text.SpannableStringInternal
+android.text.Spanned
+android.text.SpannedString
+android.text.StaticLayout
+android.text.StaticLayout$Builder
+android.text.StaticLayout$LineBreaks
+android.text.TextDirectionHeuristic
+android.text.TextDirectionHeuristics
+android.text.TextDirectionHeuristics$AnyStrong
+android.text.TextDirectionHeuristics$FirstStrong
+android.text.TextDirectionHeuristics$TextDirectionAlgorithm
+android.text.TextDirectionHeuristics$TextDirectionHeuristicImpl
+android.text.TextDirectionHeuristics$TextDirectionHeuristicInternal
+android.text.TextDirectionHeuristics$TextDirectionHeuristicLocale
+android.text.TextLine
+android.text.TextPaint
+android.text.TextUtils
+android.text.TextUtils$1
+android.text.TextUtils$EllipsizeCallback
+android.text.TextUtils$SimpleStringSplitter
+android.text.TextUtils$StringSplitter
+android.text.TextUtils$TruncateAt
+android.text.TextWatcher
+android.text.format.Time
+android.text.format.Time$TimeCalculator
+android.text.format.TimeFormatter
+android.text.method.AllCapsTransformationMethod
+android.text.method.ArrowKeyMovementMethod
+android.text.method.BaseKeyListener
+android.text.method.BaseMovementMethod
+android.text.method.KeyListener
+android.text.method.LinkMovementMethod
+android.text.method.MetaKeyKeyListener
+android.text.method.MovementMethod
+android.text.method.PasswordTransformationMethod
+android.text.method.ReplacementTransformationMethod
+android.text.method.ReplacementTransformationMethod$ReplacementCharSequence
+android.text.method.ReplacementTransformationMethod$SpannedReplacementCharSequence
+android.text.method.ScrollingMovementMethod
+android.text.method.SingleLineTransformationMethod
+android.text.method.TextKeyListener
+android.text.method.TextKeyListener$Capitalize
+android.text.method.TransformationMethod
+android.text.method.TransformationMethod2
+android.text.style.AlignmentSpan
+android.text.style.CharacterStyle
+android.text.style.EasyEditSpan
+android.text.style.LeadingMarginSpan
+android.text.style.LineBackgroundSpan
+android.text.style.LineHeightSpan
+android.text.style.MetricAffectingSpan
+android.text.style.ParagraphStyle
+android.text.style.ReplacementSpan
+android.text.style.SpellCheckSpan
+android.text.style.StyleSpan
+android.text.style.SuggestionSpan
+android.text.style.TabStopSpan
+android.text.style.UpdateAppearance
+android.text.style.UpdateLayout
+android.text.style.WrapTogetherSpan
+android.transition.AutoTransition
+android.transition.ChangeBounds
+android.transition.ChangeBounds$1
+android.transition.ChangeBounds$2
+android.transition.ChangeBounds$3
+android.transition.ChangeBounds$4
+android.transition.ChangeBounds$5
+android.transition.ChangeBounds$6
+android.transition.ChangeClipBounds
+android.transition.ChangeImageTransform
+android.transition.ChangeImageTransform$1
+android.transition.ChangeImageTransform$2
+android.transition.ChangeTransform
+android.transition.ChangeTransform$1
+android.transition.ChangeTransform$2
+android.transition.Fade
+android.transition.PathMotion
+android.transition.Transition
+android.transition.Transition$1
+android.transition.TransitionInflater
+android.transition.TransitionManager
+android.transition.TransitionSet
+android.transition.TransitionValuesMaps
+android.transition.Visibility
+android.util.AndroidException
+android.util.AndroidRuntimeException
+android.util.ArrayMap
+android.util.ArrayMap$1
+android.util.ArraySet
+android.util.ArraySet$1
+android.util.AtomicFile
+android.util.AttributeSet
+android.util.Base64
+android.util.Base64$Coder
+android.util.Base64$Decoder
+android.util.Base64$Encoder
+android.util.BootTimingsTraceLog
+android.util.ContainerHelpers
+android.util.DisplayMetrics
+android.util.EventLog
+android.util.EventLog$Event
+android.util.FloatProperty
+android.util.IntArray
+android.util.IntProperty
+android.util.Log
+android.util.Log$1
+android.util.Log$ImmediateLogWriter
+android.util.Log$PreloadHolder
+android.util.Log$TerribleFailure
+android.util.Log$TerribleFailureHandler
+android.util.LogPrinter
+android.util.LongArray
+android.util.LongSparseArray
+android.util.LongSparseLongArray
+android.util.LruCache
+android.util.MapCollections
+android.util.MapCollections$ArrayIterator
+android.util.MapCollections$EntrySet
+android.util.MapCollections$KeySet
+android.util.MapCollections$MapIterator
+android.util.MapCollections$ValuesCollection
+android.util.MathUtils
+android.util.MemoryIntArray
+android.util.MemoryIntArray$1
+android.util.MergedConfiguration
+android.util.MergedConfiguration$1
+android.util.MutableInt
+android.util.MutableLong
+android.util.Pair
+android.util.PathParser
+android.util.PathParser$PathData
+android.util.Pools$Pool
+android.util.Pools$SimplePool
+android.util.Pools$SynchronizedPool
+android.util.Printer
+android.util.Property
+android.util.Range
+android.util.Rational
+android.util.Singleton
+android.util.Size
+android.util.SizeF
+android.util.Slog
+android.util.SparseArray
+android.util.SparseBooleanArray
+android.util.SparseIntArray
+android.util.SparseLongArray
+android.util.StateSet
+android.util.SuperNotCalledException
+android.util.TimeUtils
+android.util.TypedValue
+android.util.Xml
+android.util.jar.StrictJarFile
+android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk
+android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk$1
+android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk$2
+android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk$3
+android.view.-$Lambda$iU_USrtPm1XIm5H9QYQvXfBGDE4
+android.view.-$Lambda$iU_USrtPm1XIm5H9QYQvXfBGDE4$1
+android.view.AbsSavedState
+android.view.AbsSavedState$1
+android.view.AbsSavedState$2
+android.view.ActionMode
+android.view.ActionMode$Callback
+android.view.ActionProvider
+android.view.Choreographer
+android.view.Choreographer$1
+android.view.Choreographer$2
+android.view.Choreographer$CallbackQueue
+android.view.Choreographer$CallbackRecord
+android.view.Choreographer$FrameCallback
+android.view.Choreographer$FrameDisplayEventReceiver
+android.view.Choreographer$FrameHandler
+android.view.ContextMenu
+android.view.ContextMenu$ContextMenuInfo
+android.view.ContextThemeWrapper
+android.view.Display
+android.view.Display$HdrCapabilities
+android.view.Display$HdrCapabilities$1
+android.view.Display$Mode
+android.view.Display$Mode$1
+android.view.DisplayAdjustments
+android.view.DisplayEventReceiver
+android.view.DisplayInfo
+android.view.DisplayInfo$1
+android.view.DisplayListCanvas
+android.view.FallbackEventHandler
+android.view.FocusFinder
+android.view.FocusFinder$1
+android.view.FocusFinder$FocusSorter
+android.view.FocusFinder$UserSpecifiedFocusComparator
+android.view.FocusFinder$UserSpecifiedFocusComparator$NextFocusGetter
+android.view.FrameInfo
+android.view.FrameMetrics
+android.view.FrameMetricsObserver
+android.view.FrameStats
+android.view.GestureDetector
+android.view.GestureDetector$GestureHandler
+android.view.GestureDetector$OnContextClickListener
+android.view.GestureDetector$OnDoubleTapListener
+android.view.GestureDetector$OnGestureListener
+android.view.GestureDetector$SimpleOnGestureListener
+android.view.Gravity
+android.view.HandlerActionQueue
+android.view.HandlerActionQueue$HandlerAction
+android.view.HardwareLayer
+android.view.IGraphicsStats
+android.view.IGraphicsStats$Stub
+android.view.IGraphicsStats$Stub$Proxy
+android.view.IGraphicsStatsCallback
+android.view.IGraphicsStatsCallback$Stub
+android.view.IRotationWatcher
+android.view.IRotationWatcher$Stub
+android.view.IWindow
+android.view.IWindow$Stub
+android.view.IWindowManager
+android.view.IWindowManager$Stub
+android.view.IWindowManager$Stub$Proxy
+android.view.IWindowSession
+android.view.IWindowSession$Stub
+android.view.IWindowSession$Stub$Proxy
+android.view.IWindowSessionCallback
+android.view.IWindowSessionCallback$Stub
+android.view.InflateException
+android.view.InputChannel
+android.view.InputChannel$1
+android.view.InputDevice
+android.view.InputDevice$1
+android.view.InputEvent
+android.view.InputEvent$1
+android.view.InputEventConsistencyVerifier
+android.view.InputEventReceiver
+android.view.InputEventSender
+android.view.InputQueue
+android.view.InputQueue$Callback
+android.view.InputQueue$FinishedInputEventCallback
+android.view.KeyCharacterMap
+android.view.KeyCharacterMap$1
+android.view.KeyCharacterMap$FallbackAction
+android.view.KeyEvent
+android.view.KeyEvent$1
+android.view.KeyEvent$Callback
+android.view.KeyEvent$DispatcherState
+android.view.LayoutInflater
+android.view.LayoutInflater$Factory
+android.view.LayoutInflater$Factory2
+android.view.LayoutInflater$FactoryMerger
+android.view.LayoutInflater$Filter
+android.view.Menu
+android.view.MenuInflater
+android.view.MenuItem
+android.view.MenuItem$OnActionExpandListener
+android.view.MenuItem$OnMenuItemClickListener
+android.view.MotionEvent
+android.view.MotionEvent$1
+android.view.MotionEvent$PointerCoords
+android.view.MotionEvent$PointerProperties
+android.view.PointerIcon
+android.view.PointerIcon$1
+android.view.RecordingCanvas
+android.view.RenderNode
+android.view.RenderNode$NoImagePreloadHolder
+android.view.RenderNodeAnimator
+android.view.RenderNodeAnimator$1
+android.view.RenderNodeAnimatorSetHelper
+android.view.SearchEvent
+android.view.SubMenu
+android.view.Surface
+android.view.Surface$1
+android.view.Surface$CompatibleCanvas
+android.view.Surface$OutOfResourcesException
+android.view.SurfaceControl
+android.view.SurfaceControl$PhysicalDisplayInfo
+android.view.SurfaceHolder$Callback
+android.view.SurfaceHolder$Callback2
+android.view.SurfaceSession
+android.view.SurfaceView
+android.view.TextureView
+android.view.ThreadedRenderer
+android.view.ThreadedRenderer$DrawCallbacks
+android.view.ThreadedRenderer$ProcessInitializer
+android.view.ThreadedRenderer$ProcessInitializer$1
+android.view.VelocityTracker
+android.view.VelocityTracker$Estimator
+android.view.View
+android.view.View$1
+android.view.View$10
+android.view.View$11
+android.view.View$12
+android.view.View$2
+android.view.View$3
+android.view.View$4
+android.view.View$5
+android.view.View$6
+android.view.View$7
+android.view.View$8
+android.view.View$9
+android.view.View$AccessibilityDelegate
+android.view.View$AttachInfo
+android.view.View$AttachInfo$Callbacks
+android.view.View$BaseSavedState
+android.view.View$BaseSavedState$1
+android.view.View$CheckForTap
+android.view.View$ForegroundInfo
+android.view.View$ListenerInfo
+android.view.View$MeasureSpec
+android.view.View$OnApplyWindowInsetsListener
+android.view.View$OnAttachStateChangeListener
+android.view.View$OnClickListener
+android.view.View$OnCreateContextMenuListener
+android.view.View$OnFocusChangeListener
+android.view.View$OnKeyListener
+android.view.View$OnLayoutChangeListener
+android.view.View$OnLongClickListener
+android.view.View$OnTouchListener
+android.view.View$PerformClick
+android.view.View$ScrollabilityCache
+android.view.View$TooltipInfo
+android.view.View$TransformationInfo
+android.view.View$UnsetPressedState
+android.view.ViewConfiguration
+android.view.ViewGroup
+android.view.ViewGroup$1
+android.view.ViewGroup$2
+android.view.ViewGroup$LayoutParams
+android.view.ViewGroup$MarginLayoutParams
+android.view.ViewGroup$OnHierarchyChangeListener
+android.view.ViewGroup$TouchTarget
+android.view.ViewManager
+android.view.ViewOutlineProvider
+android.view.ViewOutlineProvider$1
+android.view.ViewOutlineProvider$2
+android.view.ViewOutlineProvider$3
+android.view.ViewParent
+android.view.ViewPropertyAnimator
+android.view.ViewPropertyAnimator$1
+android.view.ViewPropertyAnimator$AnimatorEventListener
+android.view.ViewPropertyAnimator$NameValuesHolder
+android.view.ViewPropertyAnimator$PropertyBundle
+android.view.ViewRootImpl
+android.view.ViewRootImpl$1
+android.view.ViewRootImpl$4
+android.view.ViewRootImpl$AccessibilityInteractionConnectionManager
+android.view.ViewRootImpl$ActivityConfigCallback
+android.view.ViewRootImpl$AsyncInputStage
+android.view.ViewRootImpl$ConfigChangedCallback
+android.view.ViewRootImpl$ConsumeBatchedInputImmediatelyRunnable
+android.view.ViewRootImpl$ConsumeBatchedInputRunnable
+android.view.ViewRootImpl$EarlyPostImeInputStage
+android.view.ViewRootImpl$HighContrastTextManager
+android.view.ViewRootImpl$ImeInputStage
+android.view.ViewRootImpl$InputStage
+android.view.ViewRootImpl$InvalidateOnAnimationRunnable
+android.view.ViewRootImpl$NativePostImeInputStage
+android.view.ViewRootImpl$NativePreImeInputStage
+android.view.ViewRootImpl$QueuedInputEvent
+android.view.ViewRootImpl$SyntheticInputStage
+android.view.ViewRootImpl$SyntheticJoystickHandler
+android.view.ViewRootImpl$SyntheticKeyboardHandler
+android.view.ViewRootImpl$SyntheticTouchNavigationHandler
+android.view.ViewRootImpl$SyntheticTouchNavigationHandler$1
+android.view.ViewRootImpl$SyntheticTrackballHandler
+android.view.ViewRootImpl$TrackballAxis
+android.view.ViewRootImpl$TraversalRunnable
+android.view.ViewRootImpl$ViewPostImeInputStage
+android.view.ViewRootImpl$ViewPreImeInputStage
+android.view.ViewRootImpl$ViewRootHandler
+android.view.ViewRootImpl$W
+android.view.ViewRootImpl$WindowInputEventReceiver
+android.view.ViewRootImpl$WindowStoppedCallback
+android.view.ViewStub
+android.view.ViewTreeObserver
+android.view.ViewTreeObserver$CopyOnWriteArray
+android.view.ViewTreeObserver$CopyOnWriteArray$Access
+android.view.ViewTreeObserver$InternalInsetsInfo
+android.view.ViewTreeObserver$OnGlobalLayoutListener
+android.view.ViewTreeObserver$OnPreDrawListener
+android.view.ViewTreeObserver$OnScrollChangedListener
+android.view.ViewTreeObserver$OnTouchModeChangeListener
+android.view.Window
+android.view.Window$Callback
+android.view.Window$OnWindowDismissedCallback
+android.view.Window$OnWindowSwipeDismissedCallback
+android.view.Window$WindowControllerCallback
+android.view.WindowAnimationFrameStats
+android.view.WindowAnimationFrameStats$1
+android.view.WindowCallbacks
+android.view.WindowContentFrameStats
+android.view.WindowContentFrameStats$1
+android.view.WindowInsets
+android.view.WindowLeaked
+android.view.WindowManager
+android.view.WindowManager$BadTokenException
+android.view.WindowManager$LayoutParams
+android.view.WindowManager$LayoutParams$1
+android.view.WindowManagerGlobal
+android.view.WindowManagerGlobal$1
+android.view.WindowManagerGlobal$2
+android.view.WindowManagerImpl
+android.view.accessibility.AccessibilityEvent
+android.view.accessibility.AccessibilityEventSource
+android.view.accessibility.AccessibilityManager
+android.view.accessibility.AccessibilityManager$1
+android.view.accessibility.AccessibilityManager$AccessibilityStateChangeListener
+android.view.accessibility.AccessibilityManager$HighTextContrastChangeListener
+android.view.accessibility.AccessibilityManager$MyCallback
+android.view.accessibility.AccessibilityManager$TouchExplorationStateChangeListener
+android.view.accessibility.AccessibilityNodeInfo
+android.view.accessibility.AccessibilityNodeProvider
+android.view.accessibility.AccessibilityRecord
+android.view.accessibility.CaptioningManager
+android.view.accessibility.IAccessibilityManager
+android.view.accessibility.IAccessibilityManager$Stub
+android.view.accessibility.IAccessibilityManager$Stub$Proxy
+android.view.accessibility.IAccessibilityManagerClient
+android.view.accessibility.IAccessibilityManagerClient$Stub
+android.view.animation.AccelerateDecelerateInterpolator
+android.view.animation.AccelerateInterpolator
+android.view.animation.AlphaAnimation
+android.view.animation.Animation
+android.view.animation.Animation$AnimationListener
+android.view.animation.Animation$NoImagePreloadHolder
+android.view.animation.AnimationUtils
+android.view.animation.AnimationUtils$1
+android.view.animation.AnimationUtils$AnimationState
+android.view.animation.BaseInterpolator
+android.view.animation.DecelerateInterpolator
+android.view.animation.Interpolator
+android.view.animation.LinearInterpolator
+android.view.animation.PathInterpolator
+android.view.animation.Transformation
+android.view.autofill.AutofillManager
+android.view.autofill.AutofillManager$AutofillClient
+android.view.autofill.AutofillManager$AutofillManagerClient
+android.view.autofill.Helper
+android.view.autofill.IAutoFillManager
+android.view.autofill.IAutoFillManager$Stub
+android.view.autofill.IAutoFillManager$Stub$Proxy
+android.view.autofill.IAutoFillManagerClient
+android.view.autofill.IAutoFillManagerClient$Stub
+android.view.autofill.IAutofillWindowPresenter
+android.view.inputmethod.BaseInputConnection
+android.view.inputmethod.ComposingText
+android.view.inputmethod.CursorAnchorInfo$Builder
+android.view.inputmethod.EditorInfo
+android.view.inputmethod.EditorInfo$1
+android.view.inputmethod.InputConnection
+android.view.inputmethod.InputMethodManager
+android.view.inputmethod.InputMethodManager$1
+android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper
+android.view.inputmethod.InputMethodManager$FinishedInputEventCallback
+android.view.inputmethod.InputMethodManager$H
+android.view.textclassifier.TextClassificationManager
+android.view.textservice.TextServicesManager
+android.webkit.WebViewFactory
+android.webkit.WebViewFactory$MissingWebViewPackageException
+android.widget.AbsListView
+android.widget.AbsListView$AdapterDataSetObserver
+android.widget.AbsListView$LayoutParams
+android.widget.AbsListView$OnScrollListener
+android.widget.AbsListView$RecycleBin
+android.widget.AbsSeekBar
+android.widget.AbsSpinner
+android.widget.Adapter
+android.widget.AdapterView
+android.widget.AdapterView$AdapterDataSetObserver
+android.widget.AdapterView$OnItemClickListener
+android.widget.AdapterView$OnItemSelectedListener
+android.widget.AutoCompleteTextView
+android.widget.BaseAdapter
+android.widget.Button
+android.widget.CheckBox
+android.widget.Checkable
+android.widget.CheckedTextView
+android.widget.CompoundButton
+android.widget.EdgeEffect
+android.widget.EditText
+android.widget.Editor
+android.widget.Editor$1
+android.widget.Editor$2
+android.widget.Editor$CursorAnchorInfoNotifier
+android.widget.Editor$InputContentType
+android.widget.Editor$PositionListener
+android.widget.Editor$ProcessTextIntentActionsHandler
+android.widget.Editor$SpanController
+android.widget.Editor$SuggestionHelper
+android.widget.Editor$SuggestionHelper$SuggestionSpanComparator
+android.widget.Editor$TextViewPositionListener
+android.widget.Editor$UndoInputFilter
+android.widget.Filter$FilterListener
+android.widget.Filterable
+android.widget.FrameLayout
+android.widget.FrameLayout$LayoutParams
+android.widget.HorizontalScrollView
+android.widget.ImageButton
+android.widget.ImageView
+android.widget.ImageView$ScaleType
+android.widget.LinearLayout
+android.widget.LinearLayout$LayoutParams
+android.widget.ListAdapter
+android.widget.ListView
+android.widget.ListView$ArrowScrollFocusResult
+android.widget.MultiAutoCompleteTextView
+android.widget.OverScroller
+android.widget.OverScroller$SplineOverScroller
+android.widget.PopupWindow
+android.widget.ProgressBar
+android.widget.ProgressBar$1
+android.widget.RadioButton
+android.widget.RatingBar
+android.widget.RelativeLayout
+android.widget.RelativeLayout$DependencyGraph
+android.widget.RelativeLayout$DependencyGraph$Node
+android.widget.RelativeLayout$LayoutParams
+android.widget.RemoteViews
+android.widget.RemoteViews$1
+android.widget.RemoteViews$2
+android.widget.RemoteViews$3
+android.widget.RemoteViews$Action
+android.widget.RemoteViews$ActionException
+android.widget.RemoteViews$BitmapCache
+android.widget.RemoteViews$MemoryUsageCounter
+android.widget.RemoteViews$MutablePair
+android.widget.RemoteViews$OnClickHandler
+android.widget.RemoteViews$ReflectionAction
+android.widget.RemoteViews$RemoteView
+android.widget.RemoteViews$RuntimeAction
+android.widget.RemoteViews$SetOnClickPendingIntent
+android.widget.RemoteViewsAdapter$RemoteAdapterConnectionCallback
+android.widget.ScrollBarDrawable
+android.widget.ScrollView
+android.widget.Scroller
+android.widget.Scroller$ViscousFluidInterpolator
+android.widget.SeekBar
+android.widget.Space
+android.widget.Spinner
+android.widget.SpinnerAdapter
+android.widget.TextView
+android.widget.TextView$BufferType
+android.widget.TextView$ChangeWatcher
+android.widget.TextView$CharWrapper
+android.widget.TextView$Drawables
+android.widget.TextView$OnEditorActionListener
+com.android.internal.R$styleable
+com.android.internal.app.IAppOpsCallback
+com.android.internal.app.IAppOpsCallback$Stub
+com.android.internal.app.IAppOpsService
+com.android.internal.app.IAppOpsService$Stub
+com.android.internal.app.IAppOpsService$Stub$Proxy
+com.android.internal.app.IBatteryStats
+com.android.internal.app.IBatteryStats$Stub
+com.android.internal.app.IBatteryStats$Stub$Proxy
+com.android.internal.app.IVoiceInteractionManagerService
+com.android.internal.app.IVoiceInteractionManagerService$Stub
+com.android.internal.app.IVoiceInteractor
+com.android.internal.app.IVoiceInteractor$Stub
+com.android.internal.appwidget.IAppWidgetService
+com.android.internal.appwidget.IAppWidgetService$Stub
+com.android.internal.appwidget.IAppWidgetService$Stub$Proxy
+com.android.internal.content.NativeLibraryHelper
+com.android.internal.content.ReferrerIntent
+com.android.internal.content.ReferrerIntent$1
+com.android.internal.graphics.drawable.AnimationScaleListDrawable
+com.android.internal.graphics.drawable.AnimationScaleListDrawable$AnimationScaleListState
+com.android.internal.inputmethod.InputMethodUtils
+com.android.internal.inputmethod.InputMethodUtils$1
+com.android.internal.inputmethod.LocaleUtils$LocaleExtractor
+com.android.internal.logging.AndroidConfig
+com.android.internal.logging.AndroidHandler
+com.android.internal.logging.AndroidHandler$1
+com.android.internal.logging.MetricsLogger
+com.android.internal.net.NetworkStatsFactory
+com.android.internal.os.AndroidPrintStream
+com.android.internal.os.BinderInternal
+com.android.internal.os.BinderInternal$GcWatcher
+com.android.internal.os.FuseAppLoop
+com.android.internal.os.FuseAppLoop$1
+com.android.internal.os.FuseUnavailableMountException
+com.android.internal.os.HandlerCaller
+com.android.internal.os.HandlerCaller$Callback
+com.android.internal.os.HandlerCaller$MyHandler
+com.android.internal.os.LoggingPrintStream
+com.android.internal.os.LoggingPrintStream$1
+com.android.internal.os.PathClassLoaderFactory
+com.android.internal.os.RoSystemProperties
+com.android.internal.os.RuntimeInit
+com.android.internal.os.RuntimeInit$1
+com.android.internal.os.RuntimeInit$Arguments
+com.android.internal.os.RuntimeInit$KillApplicationHandler
+com.android.internal.os.RuntimeInit$LoggingHandler
+com.android.internal.os.SamplingProfilerIntegration
+com.android.internal.os.SomeArgs
+com.android.internal.os.Zygote
+com.android.internal.os.Zygote$MethodAndArgsCaller
+com.android.internal.os.ZygoteConnection
+com.android.internal.os.ZygoteConnection$Arguments
+com.android.internal.os.ZygoteInit
+com.android.internal.os.ZygoteSecurityException
+com.android.internal.os.ZygoteServer
+com.android.internal.policy.DecorContext
+com.android.internal.policy.DecorView
+com.android.internal.policy.DecorView$ColorViewAttributes
+com.android.internal.policy.DecorView$ColorViewState
+com.android.internal.policy.PhoneFallbackEventHandler
+com.android.internal.policy.PhoneLayoutInflater
+com.android.internal.policy.PhoneWindow
+com.android.internal.policy.PhoneWindow$1
+com.android.internal.policy.PhoneWindow$PanelFeatureState
+com.android.internal.policy.PhoneWindow$PhoneWindowMenuCallback
+com.android.internal.policy.PhoneWindow$RotationWatcher
+com.android.internal.policy.PhoneWindow$RotationWatcher$1
+com.android.internal.telecom.ITelecomService
+com.android.internal.telecom.ITelecomService$Stub
+com.android.internal.telephony.ICarrierConfigLoader
+com.android.internal.telephony.ICarrierConfigLoader$Stub
+com.android.internal.telephony.ICarrierConfigLoader$Stub$Proxy
+com.android.internal.telephony.IOnSubscriptionsChangedListener
+com.android.internal.telephony.IOnSubscriptionsChangedListener$Stub
+com.android.internal.telephony.IPhoneStateListener
+com.android.internal.telephony.IPhoneStateListener$Stub
+com.android.internal.telephony.IPhoneSubInfo
+com.android.internal.telephony.IPhoneSubInfo$Stub
+com.android.internal.telephony.IPhoneSubInfo$Stub$Proxy
+com.android.internal.telephony.ISms
+com.android.internal.telephony.ISms$Stub
+com.android.internal.telephony.ISub
+com.android.internal.telephony.ISub$Stub
+com.android.internal.telephony.ISub$Stub$Proxy
+com.android.internal.telephony.ITelephony
+com.android.internal.telephony.ITelephony$Stub
+com.android.internal.telephony.ITelephony$Stub$Proxy
+com.android.internal.telephony.ITelephonyRegistry
+com.android.internal.telephony.ITelephonyRegistry$Stub
+com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy
+com.android.internal.telephony.IccCardConstants$State
+com.android.internal.telephony.PhoneConstants$State
+com.android.internal.textservice.ITextServicesManager
+com.android.internal.textservice.ITextServicesManager$Stub
+com.android.internal.util.ArrayUtils
+com.android.internal.util.AsyncChannel
+com.android.internal.util.AsyncChannel$DeathMonitor
+com.android.internal.util.BitUtils
+com.android.internal.util.ExponentiallyBucketedHistogram
+com.android.internal.util.FastPrintWriter
+com.android.internal.util.FastPrintWriter$DummyWriter
+com.android.internal.util.FastXmlSerializer
+com.android.internal.util.GrowingArrayUtils
+com.android.internal.util.IState
+com.android.internal.util.IntPair
+com.android.internal.util.LineBreakBufferedWriter
+com.android.internal.util.Preconditions
+com.android.internal.util.State
+com.android.internal.util.StateMachine
+com.android.internal.util.StateMachine$LogRec
+com.android.internal.util.StateMachine$LogRecords
+com.android.internal.util.StateMachine$SmHandler
+com.android.internal.util.StateMachine$SmHandler$HaltingState
+com.android.internal.util.StateMachine$SmHandler$QuittingState
+com.android.internal.util.StateMachine$SmHandler$StateInfo
+com.android.internal.util.VirtualRefBasePtr
+com.android.internal.util.XmlUtils
+com.android.internal.util.XmlUtils$WriteMapCallback
+com.android.internal.view.IInputConnectionWrapper
+com.android.internal.view.IInputConnectionWrapper$MyHandler
+com.android.internal.view.IInputContext
+com.android.internal.view.IInputContext$Stub
+com.android.internal.view.IInputMethodClient
+com.android.internal.view.IInputMethodClient$Stub
+com.android.internal.view.IInputMethodManager
+com.android.internal.view.IInputMethodManager$Stub
+com.android.internal.view.IInputMethodManager$Stub$Proxy
+com.android.internal.view.IInputMethodSession
+com.android.internal.view.IInputMethodSession$Stub
+com.android.internal.view.IInputMethodSession$Stub$Proxy
+com.android.internal.view.InputBindResult
+com.android.internal.view.InputBindResult$1
+com.android.internal.view.RootViewSurfaceTaker
+com.android.internal.view.animation.FallbackLUTInterpolator
+com.android.internal.view.animation.HasNativeInterpolator
+com.android.internal.view.animation.NativeInterpolatorFactory
+com.android.internal.view.animation.NativeInterpolatorFactoryHelper
+com.android.internal.view.menu.MenuBuilder$Callback
+com.android.internal.view.menu.MenuPresenter$Callback
+com.android.internal.widget.BackgroundFallback
+com.android.internal.widget.DecorContentParent
+com.android.internal.widget.LockPatternUtils
+com.android.okhttp.Address
+com.android.okhttp.Authenticator
+com.android.okhttp.CacheControl
+com.android.okhttp.CacheControl$Builder
+com.android.okhttp.CertificatePinner
+com.android.okhttp.CertificatePinner$Builder
+com.android.okhttp.CipherSuite
+com.android.okhttp.ConfigAwareConnectionPool
+com.android.okhttp.ConfigAwareConnectionPool$1
+com.android.okhttp.Connection
+com.android.okhttp.ConnectionPool
+com.android.okhttp.ConnectionPool$1
+com.android.okhttp.ConnectionSpec
+com.android.okhttp.ConnectionSpec$Builder
+com.android.okhttp.Dispatcher
+com.android.okhttp.Dns
+com.android.okhttp.Dns$1
+com.android.okhttp.Handshake
+com.android.okhttp.Headers
+com.android.okhttp.Headers$Builder
+com.android.okhttp.HttpHandler
+com.android.okhttp.HttpHandler$CleartextURLFilter
+com.android.okhttp.HttpUrl
+com.android.okhttp.HttpUrl$Builder
+com.android.okhttp.HttpUrl$Builder$ParseResult
+com.android.okhttp.HttpsHandler
+com.android.okhttp.OkHttpClient
+com.android.okhttp.OkHttpClient$1
+com.android.okhttp.OkUrlFactory
+com.android.okhttp.Protocol
+com.android.okhttp.Request
+com.android.okhttp.Request$Builder
+com.android.okhttp.RequestBody
+com.android.okhttp.RequestBody$2
+com.android.okhttp.Response
+com.android.okhttp.Response$Builder
+com.android.okhttp.ResponseBody
+com.android.okhttp.Route
+com.android.okhttp.TlsVersion
+com.android.okhttp.internal.ConnectionSpecSelector
+com.android.okhttp.internal.Internal
+com.android.okhttp.internal.OptionalMethod
+com.android.okhttp.internal.Platform
+com.android.okhttp.internal.RouteDatabase
+com.android.okhttp.internal.URLFilter
+com.android.okhttp.internal.Util
+com.android.okhttp.internal.Util$1
+com.android.okhttp.internal.http.AuthenticatorAdapter
+com.android.okhttp.internal.http.CacheStrategy
+com.android.okhttp.internal.http.CacheStrategy$Factory
+com.android.okhttp.internal.http.Http1xStream
+com.android.okhttp.internal.http.Http1xStream$AbstractSource
+com.android.okhttp.internal.http.Http1xStream$ChunkedSource
+com.android.okhttp.internal.http.Http1xStream$FixedLengthSource
+com.android.okhttp.internal.http.HttpEngine
+com.android.okhttp.internal.http.HttpEngine$1
+com.android.okhttp.internal.http.HttpMethod
+com.android.okhttp.internal.http.HttpStream
+com.android.okhttp.internal.http.OkHeaders
+com.android.okhttp.internal.http.OkHeaders$1
+com.android.okhttp.internal.http.RealResponseBody
+com.android.okhttp.internal.http.RequestException
+com.android.okhttp.internal.http.RequestLine
+com.android.okhttp.internal.http.RetryableSink
+com.android.okhttp.internal.http.RouteException
+com.android.okhttp.internal.http.RouteSelector
+com.android.okhttp.internal.http.StatusLine
+com.android.okhttp.internal.http.StreamAllocation
+com.android.okhttp.internal.huc.DelegatingHttpsURLConnection
+com.android.okhttp.internal.huc.HttpURLConnectionImpl
+com.android.okhttp.internal.huc.HttpsURLConnectionImpl
+com.android.okhttp.internal.io.RealConnection
+com.android.okhttp.internal.tls.OkHostnameVerifier
+com.android.okhttp.okio.AsyncTimeout
+com.android.okhttp.okio.AsyncTimeout$1
+com.android.okhttp.okio.AsyncTimeout$2
+com.android.okhttp.okio.AsyncTimeout$Watchdog
+com.android.okhttp.okio.Buffer
+com.android.okhttp.okio.BufferedSink
+com.android.okhttp.okio.BufferedSource
+com.android.okhttp.okio.ForwardingTimeout
+com.android.okhttp.okio.GzipSource
+com.android.okhttp.okio.InflaterSource
+com.android.okhttp.okio.Okio
+com.android.okhttp.okio.Okio$1
+com.android.okhttp.okio.Okio$2
+com.android.okhttp.okio.Okio$3
+com.android.okhttp.okio.RealBufferedSink
+com.android.okhttp.okio.RealBufferedSink$1
+com.android.okhttp.okio.RealBufferedSource
+com.android.okhttp.okio.RealBufferedSource$1
+com.android.okhttp.okio.Segment
+com.android.okhttp.okio.SegmentPool
+com.android.okhttp.okio.Sink
+com.android.okhttp.okio.Source
+com.android.okhttp.okio.Timeout
+com.android.okhttp.okio.Timeout$1
+com.android.okhttp.okio.Util
+com.android.org.bouncycastle.asn1.ASN1Encodable
+com.android.org.bouncycastle.asn1.ASN1Object
+com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier
+com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier$OidHandle
+com.android.org.bouncycastle.asn1.ASN1Primitive
+com.android.org.bouncycastle.asn1.OIDTokenizer
+com.android.org.bouncycastle.asn1.bc.BCObjectIdentifiers
+com.android.org.bouncycastle.asn1.iana.IANAObjectIdentifiers
+com.android.org.bouncycastle.asn1.misc.MiscObjectIdentifiers
+com.android.org.bouncycastle.asn1.nist.NISTObjectIdentifiers
+com.android.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers
+com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers
+com.android.org.bouncycastle.asn1.x509.X509ObjectIdentifiers
+com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers
+com.android.org.bouncycastle.jcajce.provider.asymmetric.DH$Mappings
+com.android.org.bouncycastle.jcajce.provider.asymmetric.DSA$Mappings
+com.android.org.bouncycastle.jcajce.provider.asymmetric.EC$Mappings
+com.android.org.bouncycastle.jcajce.provider.asymmetric.RSA$Mappings
+com.android.org.bouncycastle.jcajce.provider.asymmetric.X509$Mappings
+com.android.org.bouncycastle.jcajce.provider.asymmetric.dh.KeyFactorySpi
+com.android.org.bouncycastle.jcajce.provider.asymmetric.dsa.DSAUtil
+com.android.org.bouncycastle.jcajce.provider.asymmetric.dsa.KeyFactorySpi
+com.android.org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi
+com.android.org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi$EC
+com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi
+com.android.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi
+com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider
+com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration
+com.android.org.bouncycastle.jcajce.provider.config.ProviderConfigurationPermission
+com.android.org.bouncycastle.jcajce.provider.digest.DigestAlgorithmProvider
+com.android.org.bouncycastle.jcajce.provider.digest.MD5
+com.android.org.bouncycastle.jcajce.provider.digest.MD5$Mappings
+com.android.org.bouncycastle.jcajce.provider.digest.SHA1
+com.android.org.bouncycastle.jcajce.provider.digest.SHA1$Mappings
+com.android.org.bouncycastle.jcajce.provider.digest.SHA224
+com.android.org.bouncycastle.jcajce.provider.digest.SHA224$Mappings
+com.android.org.bouncycastle.jcajce.provider.digest.SHA256
+com.android.org.bouncycastle.jcajce.provider.digest.SHA256$Mappings
+com.android.org.bouncycastle.jcajce.provider.digest.SHA384
+com.android.org.bouncycastle.jcajce.provider.digest.SHA384$Mappings
+com.android.org.bouncycastle.jcajce.provider.digest.SHA512
+com.android.org.bouncycastle.jcajce.provider.digest.SHA512$Mappings
+com.android.org.bouncycastle.jcajce.provider.keystore.BC$Mappings
+com.android.org.bouncycastle.jcajce.provider.keystore.PKCS12$Mappings
+com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi
+com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi$Std
+com.android.org.bouncycastle.jcajce.provider.symmetric.AES
+com.android.org.bouncycastle.jcajce.provider.symmetric.AES$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.ARC4
+com.android.org.bouncycastle.jcajce.provider.symmetric.ARC4$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.Blowfish
+com.android.org.bouncycastle.jcajce.provider.symmetric.Blowfish$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.DES
+com.android.org.bouncycastle.jcajce.provider.symmetric.DES$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.DESede
+com.android.org.bouncycastle.jcajce.provider.symmetric.DESede$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.RC2
+com.android.org.bouncycastle.jcajce.provider.symmetric.RC2$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.SymmetricAlgorithmProvider
+com.android.org.bouncycastle.jcajce.provider.symmetric.Twofish
+com.android.org.bouncycastle.jcajce.provider.symmetric.Twofish$Mappings
+com.android.org.bouncycastle.jcajce.provider.util.AlgorithmProvider
+com.android.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider
+com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter
+com.android.org.bouncycastle.jcajce.util.BCJcaJceHelper
+com.android.org.bouncycastle.jcajce.util.JcaJceHelper
+com.android.org.bouncycastle.jcajce.util.ProviderJcaJceHelper
+com.android.org.bouncycastle.jce.interfaces.BCKeyStore
+com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
+com.android.org.bouncycastle.jce.provider.BouncyCastleProvider$1
+com.android.org.bouncycastle.jce.provider.BouncyCastleProviderConfiguration
+com.android.org.bouncycastle.util.Arrays
+com.android.org.bouncycastle.util.Encodable
+com.android.org.bouncycastle.util.Strings
+com.android.org.bouncycastle.util.Strings$1
+com.android.org.conscrypt.AbstractOpenSSLSession
+com.android.org.conscrypt.AbstractSessionContext
+com.android.org.conscrypt.AbstractSessionContext$1
+com.android.org.conscrypt.AddressUtils
+com.android.org.conscrypt.ArrayUtils
+com.android.org.conscrypt.ByteArray
+com.android.org.conscrypt.CertBlacklist
+com.android.org.conscrypt.CertificatePriorityComparator
+com.android.org.conscrypt.ChainStrengthAnalyzer
+com.android.org.conscrypt.ClientSessionContext
+com.android.org.conscrypt.ClientSessionContext$HostAndPort
+com.android.org.conscrypt.CryptoUpcalls
+com.android.org.conscrypt.EvpMdRef$MD5
+com.android.org.conscrypt.EvpMdRef$SHA1
+com.android.org.conscrypt.EvpMdRef$SHA256
+com.android.org.conscrypt.FileClientSessionCache
+com.android.org.conscrypt.FileClientSessionCache$Impl
+com.android.org.conscrypt.Hex
+com.android.org.conscrypt.JSSEProvider
+com.android.org.conscrypt.KeyManagerFactoryImpl
+com.android.org.conscrypt.KeyManagerImpl
+com.android.org.conscrypt.NativeCrypto
+com.android.org.conscrypt.NativeCrypto$SSLHandshakeCallbacks
+com.android.org.conscrypt.NativeCryptoJni
+com.android.org.conscrypt.NativeRef
+com.android.org.conscrypt.NativeRef$EC_GROUP
+com.android.org.conscrypt.NativeRef$EC_POINT
+com.android.org.conscrypt.NativeRef$EVP_MD_CTX
+com.android.org.conscrypt.NativeRef$EVP_PKEY
+com.android.org.conscrypt.OpenSSLBIOInputStream
+com.android.org.conscrypt.OpenSSLContextImpl
+com.android.org.conscrypt.OpenSSLContextImpl$TLSv12
+com.android.org.conscrypt.OpenSSLECGroupContext
+com.android.org.conscrypt.OpenSSLECPointContext
+com.android.org.conscrypt.OpenSSLECPublicKey
+com.android.org.conscrypt.OpenSSLExtendedSessionImpl
+com.android.org.conscrypt.OpenSSLKey
+com.android.org.conscrypt.OpenSSLKeyHolder
+com.android.org.conscrypt.OpenSSLMessageDigestJDK
+com.android.org.conscrypt.OpenSSLMessageDigestJDK$MD5
+com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA1
+com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA256
+com.android.org.conscrypt.OpenSSLProvider
+com.android.org.conscrypt.OpenSSLRSAKeyFactory
+com.android.org.conscrypt.OpenSSLRSAPublicKey
+com.android.org.conscrypt.OpenSSLRandom
+com.android.org.conscrypt.OpenSSLSessionImpl
+com.android.org.conscrypt.OpenSSLSignature
+com.android.org.conscrypt.OpenSSLSignature$EngineType
+com.android.org.conscrypt.OpenSSLSignature$RSAPKCS1Padding
+com.android.org.conscrypt.OpenSSLSignature$SHA1RSA
+com.android.org.conscrypt.OpenSSLSocketFactoryImpl
+com.android.org.conscrypt.OpenSSLSocketImpl
+com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream
+com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream
+com.android.org.conscrypt.OpenSSLSocketImplWrapper
+com.android.org.conscrypt.OpenSSLX509CertPath
+com.android.org.conscrypt.OpenSSLX509CertPath$Encoding
+com.android.org.conscrypt.OpenSSLX509Certificate
+com.android.org.conscrypt.OpenSSLX509CertificateFactory
+com.android.org.conscrypt.OpenSSLX509CertificateFactory$1
+com.android.org.conscrypt.OpenSSLX509CertificateFactory$2
+com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser
+com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException
+com.android.org.conscrypt.Platform
+com.android.org.conscrypt.SSLClientSessionCache
+com.android.org.conscrypt.SSLParametersImpl
+com.android.org.conscrypt.SSLParametersImpl$AliasChooser
+com.android.org.conscrypt.SSLParametersImpl$PSKCallbacks
+com.android.org.conscrypt.SSLUtils
+com.android.org.conscrypt.ServerSessionContext
+com.android.org.conscrypt.TrustManagerFactoryImpl
+com.android.org.conscrypt.TrustManagerImpl
+com.android.org.conscrypt.TrustManagerImpl$ExtendedKeyUsagePKIXCertPathChecker
+com.android.org.conscrypt.TrustManagerImpl$TrustAnchorComparator
+com.android.org.conscrypt.TrustedCertificateIndex
+com.android.org.conscrypt.TrustedCertificateKeyStoreSpi
+com.android.org.conscrypt.TrustedCertificateStore
+com.android.org.conscrypt.TrustedCertificateStore$PreloadHolder
+com.android.org.conscrypt.ct.CTLogInfo
+com.android.org.conscrypt.ct.CTLogStore
+com.android.org.conscrypt.ct.CTLogStoreImpl
+com.android.org.conscrypt.ct.CTLogStoreImpl$InvalidLogFileException
+com.android.org.conscrypt.ct.CTPolicy
+com.android.org.conscrypt.ct.CTPolicyImpl
+com.android.org.conscrypt.ct.CTVerifier
+com.android.org.conscrypt.ct.KnownLogs
+com.android.org.conscrypt.ct.SerializationException
+com.android.server.NetworkManagementSocketTagger
+com.android.server.NetworkManagementSocketTagger$1
+com.android.server.NetworkManagementSocketTagger$SocketTags
+com.google.android.collect.Lists
+com.google.android.collect.Maps
+com.google.android.gles_jni.EGLConfigImpl
+com.google.android.gles_jni.EGLContextImpl
+com.google.android.gles_jni.EGLDisplayImpl
+com.google.android.gles_jni.EGLImpl
+com.google.android.gles_jni.EGLSurfaceImpl
+com.google.android.gles_jni.GLImpl
+dalvik.annotation.optimization.CriticalNative
+dalvik.annotation.optimization.FastNative
+dalvik.system.-$Lambda$xxvwQBVHC44UYbpcpA8j0sUqLOo
+dalvik.system.BaseDexClassLoader
+dalvik.system.BaseDexClassLoader$Reporter
+dalvik.system.BlockGuard
+dalvik.system.BlockGuard$1
+dalvik.system.BlockGuard$2
+dalvik.system.BlockGuard$BlockGuardPolicyException
+dalvik.system.BlockGuard$Policy
+dalvik.system.ClassExt
+dalvik.system.CloseGuard
+dalvik.system.CloseGuard$DefaultReporter
+dalvik.system.CloseGuard$DefaultTracker
+dalvik.system.CloseGuard$Reporter
+dalvik.system.CloseGuard$Tracker
+dalvik.system.DalvikLogHandler
+dalvik.system.DalvikLogging
+dalvik.system.DexClassLoader
+dalvik.system.DexFile
+dalvik.system.DexFile$DFEnum
+dalvik.system.DexPathList
+dalvik.system.DexPathList$Element
+dalvik.system.DexPathList$NativeLibraryElement
+dalvik.system.EmulatedStackFrame
+dalvik.system.EmulatedStackFrame$Range
+dalvik.system.PathClassLoader
+dalvik.system.SocketTagger
+dalvik.system.SocketTagger$1
+dalvik.system.VMDebug
+dalvik.system.VMRuntime
+dalvik.system.VMStack
+dalvik.system.ZygoteHooks
+java.io.Bits
+java.io.BufferedInputStream
+java.io.BufferedOutputStream
+java.io.BufferedReader
+java.io.ByteArrayInputStream
+java.io.ByteArrayOutputStream
+java.io.CharArrayWriter
+java.io.Closeable
+java.io.Console
+java.io.DataInput
+java.io.DataInputStream
+java.io.DataOutput
+java.io.DataOutputStream
+java.io.DefaultFileSystem
+java.io.EOFException
+java.io.ExpiringCache
+java.io.ExpiringCache$1
+java.io.ExpiringCache$Entry
+java.io.Externalizable
+java.io.File
+java.io.File$PathStatus
+java.io.File$TempDirectory
+java.io.FileDescriptor
+java.io.FileDescriptor$1
+java.io.FileFilter
+java.io.FileInputStream
+java.io.FileInputStream$UseManualSkipException
+java.io.FileNotFoundException
+java.io.FileOutputStream
+java.io.FileReader
+java.io.FileSystem
+java.io.FilenameFilter
+java.io.FilterInputStream
+java.io.FilterOutputStream
+java.io.Flushable
+java.io.IOException
+java.io.InputStream
+java.io.InputStreamReader
+java.io.InterruptedIOException
+java.io.InvalidObjectException
+java.io.ObjectInput
+java.io.ObjectInputStream
+java.io.ObjectInputStream$BlockDataInputStream
+java.io.ObjectInputStream$HandleTable
+java.io.ObjectInputStream$HandleTable$HandleList
+java.io.ObjectInputStream$PeekInputStream
+java.io.ObjectInputStream$ValidationList
+java.io.ObjectOutput
+java.io.ObjectOutputStream
+java.io.ObjectOutputStream$PutField
+java.io.ObjectStreamClass
+java.io.ObjectStreamConstants
+java.io.ObjectStreamException
+java.io.ObjectStreamField
+java.io.OutputStream
+java.io.OutputStreamWriter
+java.io.PrintStream
+java.io.PrintWriter
+java.io.PushbackInputStream
+java.io.RandomAccessFile
+java.io.Reader
+java.io.Serializable
+java.io.SerializablePermission
+java.io.StringReader
+java.io.StringWriter
+java.io.UnixFileSystem
+java.io.UnsupportedEncodingException
+java.io.Writer
+java.lang.-$Lambda$S9HjrJh0nDg7IyU6wZdPArnZWRQ
+java.lang.-$Lambda$S9HjrJh0nDg7IyU6wZdPArnZWRQ$1
+java.lang.AbstractMethodError
+java.lang.AbstractStringBuilder
+java.lang.AndroidHardcodedSystemProperties
+java.lang.Appendable
+java.lang.ArithmeticException
+java.lang.ArrayIndexOutOfBoundsException
+java.lang.ArrayStoreException
+java.lang.AssertionError
+java.lang.AutoCloseable
+java.lang.Boolean
+java.lang.BootClassLoader
+java.lang.Byte
+java.lang.Byte$ByteCache
+java.lang.CaseMapper
+java.lang.CaseMapper$1
+java.lang.CharSequence
+java.lang.CharSequence$1CharIterator
+java.lang.CharSequence$1CodePointIterator
+java.lang.Character
+java.lang.Character$CharacterCache
+java.lang.Character$Subset
+java.lang.Character$UnicodeBlock
+java.lang.Class
+java.lang.Class$Caches
+java.lang.ClassCastException
+java.lang.ClassLoader
+java.lang.ClassLoader$SystemClassLoader
+java.lang.ClassNotFoundException
+java.lang.CloneNotSupportedException
+java.lang.Cloneable
+java.lang.Comparable
+java.lang.Daemons
+java.lang.Daemons$Daemon
+java.lang.Daemons$FinalizerDaemon
+java.lang.Daemons$FinalizerWatchdogDaemon
+java.lang.Daemons$HeapTaskDaemon
+java.lang.Daemons$ReferenceQueueDaemon
+java.lang.DexCache
+java.lang.Double
+java.lang.Enum
+java.lang.Enum$1
+java.lang.EnumConstantNotPresentException
+java.lang.Error
+java.lang.Exception
+java.lang.Float
+java.lang.IllegalAccessError
+java.lang.IllegalAccessException
+java.lang.IllegalArgumentException
+java.lang.IllegalStateException
+java.lang.IllegalThreadStateException
+java.lang.IncompatibleClassChangeError
+java.lang.IndexOutOfBoundsException
+java.lang.InheritableThreadLocal
+java.lang.InstantiationException
+java.lang.Integer
+java.lang.Integer$IntegerCache
+java.lang.InternalError
+java.lang.InterruptedException
+java.lang.Iterable
+java.lang.JavaLangAccess
+java.lang.LinkageError
+java.lang.Long
+java.lang.Long$LongCache
+java.lang.Math
+java.lang.Math$RandomNumberGeneratorHolder
+java.lang.NegativeArraySizeException
+java.lang.NoClassDefFoundError
+java.lang.NoSuchFieldError
+java.lang.NoSuchFieldException
+java.lang.NoSuchMethodError
+java.lang.NoSuchMethodException
+java.lang.NullPointerException
+java.lang.Number
+java.lang.NumberFormatException
+java.lang.Object
+java.lang.OutOfMemoryError
+java.lang.Package
+java.lang.Process
+java.lang.ProcessBuilder
+java.lang.ProcessEnvironment
+java.lang.Readable
+java.lang.ReflectiveOperationException
+java.lang.Runnable
+java.lang.Runtime
+java.lang.RuntimeException
+java.lang.RuntimePermission
+java.lang.SecurityException
+java.lang.SecurityManager
+java.lang.Short
+java.lang.Short$ShortCache
+java.lang.StackOverflowError
+java.lang.StackTraceElement
+java.lang.StrictMath
+java.lang.String
+java.lang.String$CaseInsensitiveComparator
+java.lang.StringBuffer
+java.lang.StringBuilder
+java.lang.StringFactory
+java.lang.StringIndexOutOfBoundsException
+java.lang.System
+java.lang.System$PropertiesWithNonOverrideableDefaults
+java.lang.Thread
+java.lang.Thread$1
+java.lang.Thread$Caches
+java.lang.Thread$State
+java.lang.Thread$UncaughtExceptionHandler
+java.lang.Thread$WeakClassKey
+java.lang.ThreadDeath
+java.lang.ThreadGroup
+java.lang.ThreadLocal
+java.lang.ThreadLocal$ThreadLocalMap
+java.lang.ThreadLocal$ThreadLocalMap$Entry
+java.lang.Throwable
+java.lang.Throwable$PrintStreamOrWriter
+java.lang.Throwable$SentinelHolder
+java.lang.Throwable$WrappedPrintStream
+java.lang.Throwable$WrappedPrintWriter
+java.lang.TypeNotPresentException
+java.lang.UNIXProcess
+java.lang.UnsatisfiedLinkError
+java.lang.UnsupportedOperationException
+java.lang.VMClassLoader
+java.lang.VerifyError
+java.lang.VirtualMachineError
+java.lang.Void
+java.lang.annotation.Annotation
+java.lang.annotation.AnnotationTypeMismatchException
+java.lang.annotation.IncompleteAnnotationException
+java.lang.annotation.Inherited
+java.lang.annotation.Retention
+java.lang.annotation.Target
+java.lang.invoke.CallSite
+java.lang.invoke.ConstantCallSite
+java.lang.invoke.MethodHandle
+java.lang.invoke.MethodHandleImpl
+java.lang.invoke.MethodHandleImpl$HandleInfo
+java.lang.invoke.MethodHandleInfo
+java.lang.invoke.MethodHandleStatics
+java.lang.invoke.MethodHandles
+java.lang.invoke.MethodHandles$Lookup
+java.lang.invoke.MethodType
+java.lang.invoke.MethodType$ConcurrentWeakInternSet
+java.lang.invoke.MethodType$ConcurrentWeakInternSet$WeakEntry
+java.lang.invoke.MethodTypeForm
+java.lang.invoke.Transformers$BindTo
+java.lang.invoke.Transformers$Collector
+java.lang.invoke.Transformers$Construct
+java.lang.invoke.Transformers$Spreader
+java.lang.invoke.Transformers$Transformer
+java.lang.invoke.Transformers$VarargsCollector
+java.lang.invoke.WrongMethodTypeException
+java.lang.ref.FinalizerReference
+java.lang.ref.FinalizerReference$Sentinel
+java.lang.ref.PhantomReference
+java.lang.ref.Reference
+java.lang.ref.ReferenceQueue
+java.lang.ref.SoftReference
+java.lang.ref.WeakReference
+java.lang.reflect.AccessibleObject
+java.lang.reflect.AnnotatedElement
+java.lang.reflect.Array
+java.lang.reflect.Constructor
+java.lang.reflect.Executable
+java.lang.reflect.Executable$GenericInfo
+java.lang.reflect.Field
+java.lang.reflect.GenericArrayType
+java.lang.reflect.GenericDeclaration
+java.lang.reflect.InvocationHandler
+java.lang.reflect.InvocationTargetException
+java.lang.reflect.MalformedParametersException
+java.lang.reflect.Member
+java.lang.reflect.Method
+java.lang.reflect.Method$1
+java.lang.reflect.Modifier
+java.lang.reflect.Parameter
+java.lang.reflect.ParameterizedType
+java.lang.reflect.Proxy
+java.lang.reflect.Proxy$1
+java.lang.reflect.Proxy$Key1
+java.lang.reflect.Proxy$Key2
+java.lang.reflect.Proxy$KeyFactory
+java.lang.reflect.Proxy$KeyX
+java.lang.reflect.Proxy$ProxyClassFactory
+java.lang.reflect.Type
+java.lang.reflect.TypeVariable
+java.lang.reflect.UndeclaredThrowableException
+java.lang.reflect.WeakCache
+java.lang.reflect.WeakCache$CacheKey
+java.lang.reflect.WeakCache$CacheValue
+java.lang.reflect.WeakCache$Factory
+java.lang.reflect.WeakCache$LookupValue
+java.lang.reflect.WeakCache$Value
+java.lang.reflect.WildcardType
+java.math.BigDecimal
+java.math.BigInt
+java.math.BigInteger
+java.math.NativeBN
+java.math.RoundingMode
+java.net.AbstractPlainSocketImpl
+java.net.AddressCache
+java.net.AddressCache$AddressCacheEntry
+java.net.AddressCache$AddressCacheKey
+java.net.ConnectException
+java.net.CookieHandler
+java.net.HttpURLConnection
+java.net.IDN
+java.net.Inet4Address
+java.net.Inet6Address
+java.net.Inet6Address$Inet6AddressHolder
+java.net.Inet6AddressImpl
+java.net.InetAddress
+java.net.InetAddress$1
+java.net.InetAddress$InetAddressHolder
+java.net.InetAddressImpl
+java.net.InetSocketAddress
+java.net.InetSocketAddress$InetSocketAddressHolder
+java.net.JarURLConnection
+java.net.MalformedURLException
+java.net.NetworkInterface
+java.net.Parts
+java.net.PlainSocketImpl
+java.net.Proxy
+java.net.Proxy$Type
+java.net.ProxySelector
+java.net.ResponseCache
+java.net.ServerSocket
+java.net.Socket
+java.net.Socket$2
+java.net.Socket$3
+java.net.SocketAddress
+java.net.SocketException
+java.net.SocketImpl
+java.net.SocketInputStream
+java.net.SocketOptions
+java.net.SocketOutputStream
+java.net.SocketTimeoutException
+java.net.SocksConsts
+java.net.SocksSocketImpl
+java.net.URI
+java.net.URI$Parser
+java.net.URISyntaxException
+java.net.URL
+java.net.URLConnection
+java.net.URLEncoder
+java.net.URLStreamHandler
+java.net.URLStreamHandlerFactory
+java.net.UnknownHostException
+java.nio.Bits
+java.nio.Buffer
+java.nio.BufferOverflowException
+java.nio.BufferUnderflowException
+java.nio.ByteBuffer
+java.nio.ByteBufferAsCharBuffer
+java.nio.ByteBufferAsDoubleBuffer
+java.nio.ByteBufferAsFloatBuffer
+java.nio.ByteBufferAsIntBuffer
+java.nio.ByteBufferAsLongBuffer
+java.nio.ByteBufferAsShortBuffer
+java.nio.ByteOrder
+java.nio.CharBuffer
+java.nio.DirectByteBuffer
+java.nio.DirectByteBuffer$MemoryRef
+java.nio.DoubleBuffer
+java.nio.FloatBuffer
+java.nio.HeapByteBuffer
+java.nio.HeapCharBuffer
+java.nio.IntBuffer
+java.nio.InvalidMarkException
+java.nio.LongBuffer
+java.nio.MappedByteBuffer
+java.nio.NIOAccess
+java.nio.ReadOnlyBufferException
+java.nio.ShortBuffer
+java.nio.StringCharBuffer
+java.nio.channels.AsynchronousCloseException
+java.nio.channels.ByteChannel
+java.nio.channels.Channel
+java.nio.channels.ClosedByInterruptException
+java.nio.channels.ClosedChannelException
+java.nio.channels.DatagramChannel
+java.nio.channels.FileChannel
+java.nio.channels.FileChannel$MapMode
+java.nio.channels.FileLock
+java.nio.channels.GatheringByteChannel
+java.nio.channels.InterruptibleChannel
+java.nio.channels.MulticastChannel
+java.nio.channels.NetworkChannel
+java.nio.channels.OverlappingFileLockException
+java.nio.channels.ReadableByteChannel
+java.nio.channels.ScatteringByteChannel
+java.nio.channels.SeekableByteChannel
+java.nio.channels.SelectableChannel
+java.nio.channels.ServerSocketChannel
+java.nio.channels.SocketChannel
+java.nio.channels.WritableByteChannel
+java.nio.channels.spi.AbstractInterruptibleChannel
+java.nio.channels.spi.AbstractInterruptibleChannel$1
+java.nio.channels.spi.AbstractSelectableChannel
+java.nio.charset.CharacterCodingException
+java.nio.charset.Charset
+java.nio.charset.CharsetDecoder
+java.nio.charset.CharsetDecoderICU
+java.nio.charset.CharsetEncoder
+java.nio.charset.CharsetEncoderICU
+java.nio.charset.CharsetICU
+java.nio.charset.CoderResult
+java.nio.charset.CoderResult$1
+java.nio.charset.CoderResult$2
+java.nio.charset.CoderResult$Cache
+java.nio.charset.CodingErrorAction
+java.nio.charset.IllegalCharsetNameException
+java.nio.charset.StandardCharsets
+java.nio.charset.UnsupportedCharsetException
+java.nio.file.attribute.FileAttribute
+java.security.AccessControlContext
+java.security.AccessControlException
+java.security.AccessController
+java.security.AlgorithmConstraints
+java.security.AlgorithmParameters
+java.security.AlgorithmParametersSpi
+java.security.BasicPermission
+java.security.CryptoPrimitive
+java.security.GeneralSecurityException
+java.security.Guard
+java.security.InvalidAlgorithmParameterException
+java.security.InvalidKeyException
+java.security.Key
+java.security.KeyException
+java.security.KeyFactory
+java.security.KeyFactorySpi
+java.security.KeyManagementException
+java.security.KeyStore
+java.security.KeyStore$1
+java.security.KeyStoreException
+java.security.KeyStoreSpi
+java.security.MessageDigest
+java.security.MessageDigest$Delegate
+java.security.MessageDigestSpi
+java.security.NoSuchAlgorithmException
+java.security.NoSuchProviderException
+java.security.Permission
+java.security.PermissionCollection
+java.security.Permissions
+java.security.Principal
+java.security.PrivateKey
+java.security.PrivilegedAction
+java.security.PrivilegedActionException
+java.security.PrivilegedExceptionAction
+java.security.ProtectionDomain
+java.security.Provider
+java.security.Provider$EngineDescription
+java.security.Provider$Service
+java.security.Provider$ServiceKey
+java.security.Provider$UString
+java.security.PublicKey
+java.security.SecureRandom
+java.security.SecureRandomSpi
+java.security.Security
+java.security.Signature
+java.security.Signature$Delegate
+java.security.SignatureException
+java.security.SignatureSpi
+java.security.UnrecoverableEntryException
+java.security.UnrecoverableKeyException
+java.security.cert.CRL
+java.security.cert.CRLException
+java.security.cert.CertPath
+java.security.cert.CertPathChecker
+java.security.cert.CertPathHelperImpl
+java.security.cert.CertPathParameters
+java.security.cert.CertPathValidator
+java.security.cert.CertPathValidatorException
+java.security.cert.CertPathValidatorResult
+java.security.cert.CertPathValidatorSpi
+java.security.cert.CertSelector
+java.security.cert.Certificate
+java.security.cert.CertificateEncodingException
+java.security.cert.CertificateException
+java.security.cert.CertificateExpiredException
+java.security.cert.CertificateFactory
+java.security.cert.CertificateFactorySpi
+java.security.cert.CertificateNotYetValidException
+java.security.cert.CertificateParsingException
+java.security.cert.Extension
+java.security.cert.PKIXCertPathChecker
+java.security.cert.PKIXCertPathValidatorResult
+java.security.cert.PKIXParameters
+java.security.cert.PKIXRevocationChecker
+java.security.cert.PolicyNode
+java.security.cert.TrustAnchor
+java.security.cert.X509CertSelector
+java.security.cert.X509Certificate
+java.security.cert.X509Extension
+java.security.interfaces.DSAKey
+java.security.interfaces.DSAPublicKey
+java.security.interfaces.ECKey
+java.security.interfaces.ECPrivateKey
+java.security.interfaces.ECPublicKey
+java.security.interfaces.RSAKey
+java.security.interfaces.RSAPrivateKey
+java.security.interfaces.RSAPublicKey
+java.security.spec.AlgorithmParameterSpec
+java.security.spec.ECField
+java.security.spec.ECFieldFp
+java.security.spec.ECParameterSpec
+java.security.spec.ECPoint
+java.security.spec.ECPublicKeySpec
+java.security.spec.EllipticCurve
+java.security.spec.EncodedKeySpec
+java.security.spec.InvalidKeySpecException
+java.security.spec.InvalidParameterSpecException
+java.security.spec.KeySpec
+java.security.spec.RSAPublicKeySpec
+java.security.spec.X509EncodedKeySpec
+java.text.AttributedCharacterIterator$Attribute
+java.text.CharacterIterator
+java.text.DateFormat
+java.text.DateFormat$Field
+java.text.DateFormatSymbols
+java.text.DecimalFormat
+java.text.DecimalFormatSymbols
+java.text.DontCareFieldPosition
+java.text.DontCareFieldPosition$1
+java.text.FieldPosition
+java.text.Format
+java.text.Format$Field
+java.text.Format$FieldDelegate
+java.text.Normalizer
+java.text.Normalizer$Form
+java.text.NumberFormat
+java.text.ParseException
+java.text.ParsePosition
+java.text.SimpleDateFormat
+java.text.StringCharacterIterator
+java.time.DateTimeException
+java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$1
+java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$2
+java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$3
+java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$4
+java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$5
+java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw
+java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw$1
+java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw$2
+java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw$3
+java.util.AbstractCollection
+java.util.AbstractList
+java.util.AbstractList$Itr
+java.util.AbstractList$ListItr
+java.util.AbstractMap
+java.util.AbstractMap$1
+java.util.AbstractMap$2
+java.util.AbstractMap$SimpleImmutableEntry
+java.util.AbstractQueue
+java.util.AbstractSequentialList
+java.util.AbstractSet
+java.util.ArrayDeque
+java.util.ArrayDeque$DeqIterator
+java.util.ArrayList
+java.util.ArrayList$ArrayListSpliterator
+java.util.ArrayList$Itr
+java.util.ArrayList$ListItr
+java.util.ArrayList$SubList
+java.util.ArrayList$SubList$1
+java.util.ArrayPrefixHelpers$CumulateTask
+java.util.ArrayPrefixHelpers$DoubleCumulateTask
+java.util.ArrayPrefixHelpers$IntCumulateTask
+java.util.ArrayPrefixHelpers$LongCumulateTask
+java.util.Arrays
+java.util.Arrays$ArrayList
+java.util.Arrays$NaturalOrder
+java.util.ArraysParallelSortHelpers$FJByte$Sorter
+java.util.ArraysParallelSortHelpers$FJChar$Sorter
+java.util.ArraysParallelSortHelpers$FJDouble$Sorter
+java.util.ArraysParallelSortHelpers$FJFloat$Sorter
+java.util.ArraysParallelSortHelpers$FJInt$Sorter
+java.util.ArraysParallelSortHelpers$FJLong$Sorter
+java.util.ArraysParallelSortHelpers$FJObject$Sorter
+java.util.ArraysParallelSortHelpers$FJShort$Sorter
+java.util.BitSet
+java.util.Calendar
+java.util.Collection
+java.util.Collections
+java.util.Collections$1
+java.util.Collections$2
+java.util.Collections$3
+java.util.Collections$AsLIFOQueue
+java.util.Collections$CheckedCollection
+java.util.Collections$CheckedList
+java.util.Collections$CheckedMap
+java.util.Collections$CheckedNavigableMap
+java.util.Collections$CheckedNavigableSet
+java.util.Collections$CheckedQueue
+java.util.Collections$CheckedRandomAccessList
+java.util.Collections$CheckedSet
+java.util.Collections$CheckedSortedMap
+java.util.Collections$CheckedSortedSet
+java.util.Collections$CopiesList
+java.util.Collections$EmptyEnumeration
+java.util.Collections$EmptyIterator
+java.util.Collections$EmptyList
+java.util.Collections$EmptyListIterator
+java.util.Collections$EmptyMap
+java.util.Collections$EmptySet
+java.util.Collections$ReverseComparator
+java.util.Collections$ReverseComparator2
+java.util.Collections$SetFromMap
+java.util.Collections$SingletonList
+java.util.Collections$SingletonMap
+java.util.Collections$SingletonSet
+java.util.Collections$SynchronizedCollection
+java.util.Collections$SynchronizedList
+java.util.Collections$SynchronizedMap
+java.util.Collections$SynchronizedNavigableMap
+java.util.Collections$SynchronizedNavigableSet
+java.util.Collections$SynchronizedRandomAccessList
+java.util.Collections$SynchronizedSet
+java.util.Collections$SynchronizedSortedMap
+java.util.Collections$SynchronizedSortedSet
+java.util.Collections$UnmodifiableCollection
+java.util.Collections$UnmodifiableCollection$1
+java.util.Collections$UnmodifiableList
+java.util.Collections$UnmodifiableList$1
+java.util.Collections$UnmodifiableMap
+java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet
+java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$1
+java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry
+java.util.Collections$UnmodifiableNavigableMap
+java.util.Collections$UnmodifiableNavigableMap$EmptyNavigableMap
+java.util.Collections$UnmodifiableNavigableSet
+java.util.Collections$UnmodifiableNavigableSet$EmptyNavigableSet
+java.util.Collections$UnmodifiableRandomAccessList
+java.util.Collections$UnmodifiableSet
+java.util.Collections$UnmodifiableSortedMap
+java.util.Collections$UnmodifiableSortedSet
+java.util.ComparableTimSort
+java.util.Comparator
+java.util.Comparators$NaturalOrderComparator
+java.util.Comparators$NullComparator
+java.util.ConcurrentModificationException
+java.util.Currency
+java.util.Date
+java.util.Deque
+java.util.Dictionary
+java.util.DualPivotQuicksort
+java.util.EnumMap
+java.util.EnumMap$1
+java.util.EnumSet
+java.util.Enumeration
+java.util.EventListener
+java.util.Formattable
+java.util.Formatter
+java.util.Formatter$Conversion
+java.util.Formatter$FixedString
+java.util.Formatter$Flags
+java.util.Formatter$FormatSpecifier
+java.util.Formatter$FormatSpecifierParser
+java.util.Formatter$FormatString
+java.util.FormatterClosedException
+java.util.GregorianCalendar
+java.util.HashMap
+java.util.HashMap$EntryIterator
+java.util.HashMap$EntrySet
+java.util.HashMap$HashIterator
+java.util.HashMap$KeyIterator
+java.util.HashMap$KeySet
+java.util.HashMap$Node
+java.util.HashMap$TreeNode
+java.util.HashMap$ValueIterator
+java.util.HashMap$Values
+java.util.HashSet
+java.util.Hashtable
+java.util.Hashtable$Enumerator
+java.util.Hashtable$HashtableEntry
+java.util.IdentityHashMap
+java.util.IdentityHashMap$KeySet
+java.util.IllegalFormatException
+java.util.IllformedLocaleException
+java.util.Iterator
+java.util.LinkedHashMap
+java.util.LinkedHashMap$LinkedEntryIterator
+java.util.LinkedHashMap$LinkedEntrySet
+java.util.LinkedHashMap$LinkedHashIterator
+java.util.LinkedHashMap$LinkedHashMapEntry
+java.util.LinkedHashMap$LinkedKeyIterator
+java.util.LinkedHashMap$LinkedKeySet
+java.util.LinkedHashMap$LinkedValueIterator
+java.util.LinkedHashMap$LinkedValues
+java.util.LinkedHashSet
+java.util.LinkedList
+java.util.LinkedList$ListItr
+java.util.LinkedList$Node
+java.util.List
+java.util.ListIterator
+java.util.Locale
+java.util.Locale$Builder
+java.util.Locale$Cache
+java.util.Locale$Category
+java.util.Locale$FilteringMode
+java.util.Locale$LanguageRange
+java.util.Locale$LocaleKey
+java.util.Locale$NoImagePreloadHolder
+java.util.Map
+java.util.Map$Entry
+java.util.MissingResourceException
+java.util.NavigableMap
+java.util.NavigableSet
+java.util.NoSuchElementException
+java.util.Objects
+java.util.PrimitiveIterator
+java.util.PrimitiveIterator$OfInt
+java.util.PriorityQueue
+java.util.PriorityQueue$Itr
+java.util.Properties
+java.util.Properties$LineReader
+java.util.Queue
+java.util.Random
+java.util.RandomAccess
+java.util.RandomAccessSubList
+java.util.RegularEnumSet
+java.util.ResourceBundle
+java.util.ResourceBundle$1
+java.util.Set
+java.util.SimpleTimeZone
+java.util.SortedMap
+java.util.SortedSet
+java.util.Spliterator
+java.util.Spliterator$OfDouble
+java.util.Spliterator$OfInt
+java.util.Spliterator$OfLong
+java.util.Spliterator$OfPrimitive
+java.util.Spliterators
+java.util.Spliterators$EmptySpliterator
+java.util.Spliterators$EmptySpliterator$OfDouble
+java.util.Spliterators$EmptySpliterator$OfInt
+java.util.Spliterators$EmptySpliterator$OfLong
+java.util.Spliterators$EmptySpliterator$OfRef
+java.util.Stack
+java.util.StringJoiner
+java.util.StringTokenizer
+java.util.SubList
+java.util.TimSort
+java.util.TimeZone
+java.util.TreeMap
+java.util.TreeMap$AscendingSubMap
+java.util.TreeMap$AscendingSubMap$AscendingEntrySetView
+java.util.TreeMap$EntryIterator
+java.util.TreeMap$EntrySet
+java.util.TreeMap$KeyIterator
+java.util.TreeMap$KeySet
+java.util.TreeMap$NavigableSubMap
+java.util.TreeMap$NavigableSubMap$EntrySetView
+java.util.TreeMap$NavigableSubMap$SubMapIterator
+java.util.TreeMap$PrivateEntryIterator
+java.util.TreeMap$TreeMapEntry
+java.util.TreeMap$ValueIterator
+java.util.TreeMap$Values
+java.util.TreeSet
+java.util.UUID
+java.util.UUID$Holder
+java.util.Vector
+java.util.Vector$1
+java.util.Vector$Itr
+java.util.WeakHashMap
+java.util.WeakHashMap$Entry
+java.util.WeakHashMap$EntrySet
+java.util.WeakHashMap$HashIterator
+java.util.WeakHashMap$KeyIterator
+java.util.WeakHashMap$KeySet
+java.util.WeakHashMap$Values
+java.util.concurrent.-$Lambda$xR9BLpu6SifNikvFgr4lEiECBsk
+java.util.concurrent.AbstractExecutorService
+java.util.concurrent.ArrayBlockingQueue
+java.util.concurrent.BlockingQueue
+java.util.concurrent.Callable
+java.util.concurrent.CancellationException
+java.util.concurrent.ConcurrentHashMap
+java.util.concurrent.ConcurrentHashMap$BaseIterator
+java.util.concurrent.ConcurrentHashMap$BulkTask
+java.util.concurrent.ConcurrentHashMap$CollectionView
+java.util.concurrent.ConcurrentHashMap$CounterCell
+java.util.concurrent.ConcurrentHashMap$EntryIterator
+java.util.concurrent.ConcurrentHashMap$EntrySetView
+java.util.concurrent.ConcurrentHashMap$ForEachEntryTask
+java.util.concurrent.ConcurrentHashMap$ForEachKeyTask
+java.util.concurrent.ConcurrentHashMap$ForEachMappingTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedEntryTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedKeyTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedMappingTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedValueTask
+java.util.concurrent.ConcurrentHashMap$ForEachValueTask
+java.util.concurrent.ConcurrentHashMap$ForwardingNode
+java.util.concurrent.ConcurrentHashMap$KeyIterator
+java.util.concurrent.ConcurrentHashMap$KeySetView
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToLongTask
+java.util.concurrent.ConcurrentHashMap$Node
+java.util.concurrent.ConcurrentHashMap$ReduceEntriesTask
+java.util.concurrent.ConcurrentHashMap$ReduceKeysTask
+java.util.concurrent.ConcurrentHashMap$ReduceValuesTask
+java.util.concurrent.ConcurrentHashMap$ReservationNode
+java.util.concurrent.ConcurrentHashMap$SearchEntriesTask
+java.util.concurrent.ConcurrentHashMap$SearchKeysTask
+java.util.concurrent.ConcurrentHashMap$SearchMappingsTask
+java.util.concurrent.ConcurrentHashMap$SearchValuesTask
+java.util.concurrent.ConcurrentHashMap$Segment
+java.util.concurrent.ConcurrentHashMap$Traverser
+java.util.concurrent.ConcurrentHashMap$TreeBin
+java.util.concurrent.ConcurrentHashMap$TreeNode
+java.util.concurrent.ConcurrentHashMap$ValueIterator
+java.util.concurrent.ConcurrentHashMap$ValuesView
+java.util.concurrent.ConcurrentLinkedDeque
+java.util.concurrent.ConcurrentLinkedDeque$Node
+java.util.concurrent.ConcurrentLinkedQueue
+java.util.concurrent.ConcurrentLinkedQueue$Node
+java.util.concurrent.ConcurrentMap
+java.util.concurrent.CopyOnWriteArrayList
+java.util.concurrent.CopyOnWriteArrayList$COWIterator
+java.util.concurrent.CopyOnWriteArraySet
+java.util.concurrent.CountDownLatch
+java.util.concurrent.CountDownLatch$Sync
+java.util.concurrent.CountedCompleter
+java.util.concurrent.Delayed
+java.util.concurrent.ExecutionException
+java.util.concurrent.Executor
+java.util.concurrent.ExecutorService
+java.util.concurrent.Executors
+java.util.concurrent.Executors$DefaultThreadFactory
+java.util.concurrent.Executors$DelegatedExecutorService
+java.util.concurrent.Executors$DelegatedScheduledExecutorService
+java.util.concurrent.Executors$FinalizableDelegatedExecutorService
+java.util.concurrent.Executors$RunnableAdapter
+java.util.concurrent.ForkJoinPool
+java.util.concurrent.ForkJoinTask
+java.util.concurrent.ForkJoinTask$ExceptionNode
+java.util.concurrent.Future
+java.util.concurrent.FutureTask
+java.util.concurrent.FutureTask$WaitNode
+java.util.concurrent.LinkedBlockingQueue
+java.util.concurrent.LinkedBlockingQueue$Node
+java.util.concurrent.PriorityBlockingQueue
+java.util.concurrent.RejectedExecutionException
+java.util.concurrent.RejectedExecutionHandler
+java.util.concurrent.RunnableFuture
+java.util.concurrent.RunnableScheduledFuture
+java.util.concurrent.ScheduledExecutorService
+java.util.concurrent.ScheduledFuture
+java.util.concurrent.ScheduledThreadPoolExecutor
+java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue
+java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask
+java.util.concurrent.Semaphore
+java.util.concurrent.Semaphore$NonfairSync
+java.util.concurrent.Semaphore$Sync
+java.util.concurrent.SynchronousQueue
+java.util.concurrent.SynchronousQueue$TransferStack
+java.util.concurrent.SynchronousQueue$TransferStack$SNode
+java.util.concurrent.SynchronousQueue$Transferer
+java.util.concurrent.ThreadFactory
+java.util.concurrent.ThreadLocalRandom
+java.util.concurrent.ThreadPoolExecutor
+java.util.concurrent.ThreadPoolExecutor$AbortPolicy
+java.util.concurrent.ThreadPoolExecutor$DiscardPolicy
+java.util.concurrent.ThreadPoolExecutor$Worker
+java.util.concurrent.TimeUnit
+java.util.concurrent.TimeUnit$1
+java.util.concurrent.TimeUnit$2
+java.util.concurrent.TimeUnit$3
+java.util.concurrent.TimeUnit$4
+java.util.concurrent.TimeUnit$5
+java.util.concurrent.TimeUnit$6
+java.util.concurrent.TimeUnit$7
+java.util.concurrent.TimeoutException
+java.util.concurrent.atomic.AtomicBoolean
+java.util.concurrent.atomic.AtomicInteger
+java.util.concurrent.atomic.AtomicLong
+java.util.concurrent.atomic.AtomicReference
+java.util.concurrent.atomic.AtomicReferenceArray
+java.util.concurrent.atomic.AtomicReferenceFieldUpdater
+java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl
+java.util.concurrent.locks.AbstractOwnableSynchronizer
+java.util.concurrent.locks.AbstractQueuedSynchronizer
+java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject
+java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
+java.util.concurrent.locks.Condition
+java.util.concurrent.locks.Lock
+java.util.concurrent.locks.LockSupport
+java.util.concurrent.locks.ReadWriteLock
+java.util.concurrent.locks.ReentrantLock
+java.util.concurrent.locks.ReentrantLock$NonfairSync
+java.util.concurrent.locks.ReentrantLock$Sync
+java.util.concurrent.locks.ReentrantReadWriteLock
+java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync
+java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock
+java.util.concurrent.locks.ReentrantReadWriteLock$Sync
+java.util.concurrent.locks.ReentrantReadWriteLock$Sync$ThreadLocalHoldCounter
+java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock
+java.util.function.-$Lambda$1MZdIZ-DL_fjy9l0o8IMJk57T2g
+java.util.function.-$Lambda$VGDeaUHZQIZywZW2ttlyhwk3Cmk
+java.util.function.-$Lambda$VGDeaUHZQIZywZW2ttlyhwk3Cmk$1
+java.util.function.BiConsumer
+java.util.function.BiFunction
+java.util.function.BinaryOperator
+java.util.function.Consumer
+java.util.function.DoubleBinaryOperator
+java.util.function.DoubleUnaryOperator
+java.util.function.Function
+java.util.function.IntBinaryOperator
+java.util.function.IntConsumer
+java.util.function.IntFunction
+java.util.function.IntToDoubleFunction
+java.util.function.IntToLongFunction
+java.util.function.IntUnaryOperator
+java.util.function.LongBinaryOperator
+java.util.function.LongUnaryOperator
+java.util.function.Predicate
+java.util.function.Supplier
+java.util.function.ToDoubleBiFunction
+java.util.function.ToDoubleFunction
+java.util.function.ToIntBiFunction
+java.util.function.ToIntFunction
+java.util.function.ToLongBiFunction
+java.util.function.ToLongFunction
+java.util.function.UnaryOperator
+java.util.jar.JarEntry
+java.util.jar.JarFile
+java.util.jar.JarFile$JarEntryIterator
+java.util.jar.JarFile$JarFileEntry
+java.util.logging.ErrorManager
+java.util.logging.Formatter
+java.util.logging.Handler
+java.util.logging.Level
+java.util.logging.Level$KnownLevel
+java.util.logging.LogManager
+java.util.logging.LogManager$1
+java.util.logging.LogManager$2
+java.util.logging.LogManager$3
+java.util.logging.LogManager$5
+java.util.logging.LogManager$Cleaner
+java.util.logging.LogManager$LogNode
+java.util.logging.LogManager$LoggerContext
+java.util.logging.LogManager$LoggerContext$1
+java.util.logging.LogManager$LoggerWeakRef
+java.util.logging.LogManager$RootLogger
+java.util.logging.LogManager$SystemLoggerContext
+java.util.logging.LogRecord
+java.util.logging.Logger
+java.util.logging.Logger$LoggerBundle
+java.util.logging.LoggingPermission
+java.util.logging.LoggingProxyImpl
+java.util.prefs.AbstractPreferences
+java.util.prefs.FileSystemPreferences
+java.util.prefs.Preferences
+java.util.regex.MatchResult
+java.util.regex.Matcher
+java.util.regex.Pattern
+java.util.regex.PatternSyntaxException
+java.util.stream.AbstractPipeline
+java.util.stream.BaseStream
+java.util.stream.DoubleStream
+java.util.stream.IntStream
+java.util.stream.LongStream
+java.util.stream.PipelineHelper
+java.util.stream.ReferencePipeline
+java.util.stream.ReferencePipeline$Head
+java.util.stream.Sink
+java.util.stream.Sink$ChainedReference
+java.util.stream.Stream
+java.util.stream.StreamOpFlag
+java.util.stream.StreamOpFlag$MaskBuilder
+java.util.stream.StreamOpFlag$Type
+java.util.stream.StreamShape
+java.util.stream.StreamSupport
+java.util.stream.TerminalOp
+java.util.stream.TerminalSink
+java.util.zip.Adler32
+java.util.zip.CRC32
+java.util.zip.CheckedInputStream
+java.util.zip.Checksum
+java.util.zip.DataFormatException
+java.util.zip.Deflater
+java.util.zip.DeflaterOutputStream
+java.util.zip.GZIPInputStream
+java.util.zip.GZIPOutputStream
+java.util.zip.Inflater
+java.util.zip.InflaterInputStream
+java.util.zip.ZStreamRef
+java.util.zip.ZipCoder
+java.util.zip.ZipConstants
+java.util.zip.ZipEntry
+java.util.zip.ZipFile
+java.util.zip.ZipFile$ZipEntryIterator
+java.util.zip.ZipFile$ZipFileInflaterInputStream
+java.util.zip.ZipFile$ZipFileInputStream
+java.util.zip.ZipUtils
+javax.crypto.BadPaddingException
+javax.crypto.Cipher
+javax.crypto.Cipher$CipherSpiAndProvider
+javax.crypto.Cipher$InitParams
+javax.crypto.Cipher$InitType
+javax.crypto.Cipher$NeedToSet
+javax.crypto.Cipher$SpiAndProviderUpdater
+javax.crypto.Cipher$Transform
+javax.crypto.CipherSpi
+javax.crypto.IllegalBlockSizeException
+javax.crypto.JceSecurity
+javax.crypto.NoSuchPaddingException
+javax.crypto.SecretKey
+javax.crypto.ShortBufferException
+javax.crypto.spec.IvParameterSpec
+javax.crypto.spec.SecretKeySpec
+javax.microedition.khronos.egl.EGL
+javax.microedition.khronos.egl.EGL10
+javax.microedition.khronos.egl.EGLConfig
+javax.microedition.khronos.egl.EGLContext
+javax.microedition.khronos.egl.EGLDisplay
+javax.microedition.khronos.egl.EGLSurface
+javax.microedition.khronos.opengles.GL
+javax.microedition.khronos.opengles.GL10
+javax.microedition.khronos.opengles.GL10Ext
+javax.microedition.khronos.opengles.GL11
+javax.microedition.khronos.opengles.GL11Ext
+javax.microedition.khronos.opengles.GL11ExtensionPack
+javax.net.DefaultSocketFactory
+javax.net.ServerSocketFactory
+javax.net.SocketFactory
+javax.net.ssl.ExtendedSSLSession
+javax.net.ssl.HandshakeCompletedListener
+javax.net.ssl.HostnameVerifier
+javax.net.ssl.HttpsURLConnection
+javax.net.ssl.KeyManager
+javax.net.ssl.KeyManagerFactory
+javax.net.ssl.KeyManagerFactory$1
+javax.net.ssl.KeyManagerFactorySpi
+javax.net.ssl.SNIHostName
+javax.net.ssl.SNIServerName
+javax.net.ssl.SSLContext
+javax.net.ssl.SSLContextSpi
+javax.net.ssl.SSLEngine
+javax.net.ssl.SSLException
+javax.net.ssl.SSLParameters
+javax.net.ssl.SSLPeerUnverifiedException
+javax.net.ssl.SSLProtocolException
+javax.net.ssl.SSLServerSocketFactory
+javax.net.ssl.SSLSession
+javax.net.ssl.SSLSessionContext
+javax.net.ssl.SSLSocket
+javax.net.ssl.SSLSocketFactory
+javax.net.ssl.SSLSocketFactory$1
+javax.net.ssl.TrustManager
+javax.net.ssl.TrustManagerFactory
+javax.net.ssl.TrustManagerFactory$1
+javax.net.ssl.TrustManagerFactorySpi
+javax.net.ssl.X509ExtendedKeyManager
+javax.net.ssl.X509ExtendedTrustManager
+javax.net.ssl.X509KeyManager
+javax.net.ssl.X509TrustManager
+javax.security.auth.Destroyable
+javax.security.auth.callback.UnsupportedCallbackException
+javax.security.auth.x500.X500Principal
+javax.security.cert.Certificate
+javax.security.cert.CertificateException
+javax.security.cert.X509Certificate
+libcore.icu.ICU
+libcore.icu.LocaleData
+libcore.icu.NativeConverter
+libcore.icu.TimeZoneNames
+libcore.internal.StringPool
+libcore.io.AsynchronousCloseMonitor
+libcore.io.BlockGuardOs
+libcore.io.BufferIterator
+libcore.io.ClassPathURLStreamHandler
+libcore.io.ClassPathURLStreamHandler$ClassPathURLConnection
+libcore.io.ClassPathURLStreamHandler$ClassPathURLConnection$1
+libcore.io.DropBox
+libcore.io.DropBox$DefaultReporter
+libcore.io.DropBox$Reporter
+libcore.io.EventLogger
+libcore.io.EventLogger$DefaultReporter
+libcore.io.EventLogger$Reporter
+libcore.io.ForwardingOs
+libcore.io.IoBridge
+libcore.io.IoTracker
+libcore.io.IoTracker$Mode
+libcore.io.IoUtils
+libcore.io.Libcore
+libcore.io.Linux
+libcore.io.Memory
+libcore.io.MemoryMappedFile
+libcore.io.NioBufferIterator
+libcore.io.Os
+libcore.net.NetworkSecurityPolicy
+libcore.net.NetworkSecurityPolicy$DefaultNetworkSecurityPolicy
+libcore.net.UriCodec
+libcore.net.event.NetworkEventDispatcher
+libcore.net.event.NetworkEventListener
+libcore.reflect.AnnotatedElements
+libcore.reflect.AnnotationFactory
+libcore.reflect.AnnotationMember
+libcore.reflect.AnnotationMember$DefaultValues
+libcore.reflect.GenericArrayTypeImpl
+libcore.reflect.GenericSignatureParser
+libcore.reflect.ListOfTypes
+libcore.reflect.ListOfVariables
+libcore.reflect.ParameterizedTypeImpl
+libcore.reflect.Types
+libcore.util.BasicLruCache
+libcore.util.CharsetUtils
+libcore.util.CollectionUtils
+libcore.util.EmptyArray
+libcore.util.NativeAllocationRegistry
+libcore.util.NativeAllocationRegistry$CleanerRunner
+libcore.util.NativeAllocationRegistry$CleanerThunk
+libcore.util.TimeZoneDataFiles
+libcore.util.ZoneInfo
+libcore.util.ZoneInfo$CheckedArithmeticException
+libcore.util.ZoneInfo$OffsetInterval
+libcore.util.ZoneInfo$WallTime
+libcore.util.ZoneInfoDB
+libcore.util.ZoneInfoDB$TzData
+libcore.util.ZoneInfoDB$TzData$1
+org.apache.commons.logging.Log
+org.apache.commons.logging.LogFactory
+org.apache.commons.logging.impl.Jdk14Logger
+org.apache.commons.logging.impl.WeakHashtable
+org.apache.harmony.dalvik.NativeTestTarget
+org.apache.harmony.dalvik.ddmc.Chunk
+org.apache.harmony.dalvik.ddmc.ChunkHandler
+org.apache.harmony.dalvik.ddmc.DdmServer
+org.apache.harmony.dalvik.ddmc.DdmVmInternal
+org.apache.harmony.luni.internal.util.TimezoneGetter
+org.apache.harmony.xml.ExpatAttributes
+org.apache.harmony.xml.ExpatParser
+org.apache.http.Header
+org.apache.http.HttpEntity
+org.apache.http.HttpException
+org.apache.http.HttpHost
+org.apache.http.HttpMessage
+org.apache.http.HttpRequest
+org.apache.http.HttpRequestInterceptor
+org.apache.http.HttpResponse
+org.apache.http.ProtocolException
+org.apache.http.ProtocolVersion
+org.apache.http.StatusLine
+org.apache.http.client.HttpClient
+org.apache.http.client.ResponseHandler
+org.apache.http.client.methods.HttpUriRequest
+org.apache.http.client.params.HttpClientParams
+org.apache.http.conn.ClientConnectionManager
+org.apache.http.conn.ClientConnectionOperator
+org.apache.http.conn.ClientConnectionRequest
+org.apache.http.conn.ConnectTimeoutException
+org.apache.http.conn.ConnectionReleaseTrigger
+org.apache.http.conn.params.ConnManagerPNames
+org.apache.http.conn.params.ConnManagerParams
+org.apache.http.conn.params.ConnManagerParams$1
+org.apache.http.conn.params.ConnPerRoute
+org.apache.http.conn.scheme.LayeredSocketFactory
+org.apache.http.conn.scheme.PlainSocketFactory
+org.apache.http.conn.scheme.Scheme
+org.apache.http.conn.scheme.SchemeRegistry
+org.apache.http.conn.scheme.SocketFactory
+org.apache.http.conn.ssl.AbstractVerifier
+org.apache.http.conn.ssl.AllowAllHostnameVerifier
+org.apache.http.conn.ssl.BrowserCompatHostnameVerifier
+org.apache.http.conn.ssl.SSLSocketFactory
+org.apache.http.conn.ssl.StrictHostnameVerifier
+org.apache.http.conn.ssl.X509HostnameVerifier
+org.apache.http.entity.AbstractHttpEntity
+org.apache.http.impl.client.AbstractHttpClient
+org.apache.http.impl.client.DefaultHttpClient
+org.apache.http.impl.conn.DefaultClientConnectionOperator
+org.apache.http.impl.conn.IdleConnectionHandler
+org.apache.http.impl.conn.tsccm.AbstractConnPool
+org.apache.http.impl.conn.tsccm.ConnPoolByRoute
+org.apache.http.impl.conn.tsccm.RefQueueHandler
+org.apache.http.impl.conn.tsccm.RefQueueWorker
+org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager
+org.apache.http.message.AbstractHttpMessage
+org.apache.http.message.BasicHeader
+org.apache.http.message.BasicHttpResponse
+org.apache.http.message.BasicStatusLine
+org.apache.http.message.HeaderGroup
+org.apache.http.params.AbstractHttpParams
+org.apache.http.params.BasicHttpParams
+org.apache.http.params.CoreConnectionPNames
+org.apache.http.params.CoreProtocolPNames
+org.apache.http.params.HttpConnectionParams
+org.apache.http.params.HttpParams
+org.apache.http.params.HttpProtocolParams
+org.apache.http.protocol.HttpContext
+org.ccil.cowan.tagsoup.AttributesImpl
+org.ccil.cowan.tagsoup.AutoDetector
+org.ccil.cowan.tagsoup.Element
+org.ccil.cowan.tagsoup.ElementType
+org.ccil.cowan.tagsoup.HTMLModels
+org.ccil.cowan.tagsoup.HTMLScanner
+org.ccil.cowan.tagsoup.HTMLSchema
+org.ccil.cowan.tagsoup.Parser
+org.ccil.cowan.tagsoup.Parser$1
+org.ccil.cowan.tagsoup.ScanHandler
+org.ccil.cowan.tagsoup.Scanner
+org.ccil.cowan.tagsoup.Schema
+org.json.JSON
+org.json.JSONArray
+org.json.JSONException
+org.json.JSONObject
+org.json.JSONObject$1
+org.json.JSONStringer
+org.json.JSONStringer$Scope
+org.json.JSONTokener
+org.kxml2.io.KXmlParser
+org.kxml2.io.KXmlParser$ValueContext
+org.xml.sax.Attributes
+org.xml.sax.ContentHandler
+org.xml.sax.DTDHandler
+org.xml.sax.EntityResolver
+org.xml.sax.ErrorHandler
+org.xml.sax.InputSource
+org.xml.sax.Locator
+org.xml.sax.SAXException
+org.xml.sax.SAXNotRecognizedException
+org.xml.sax.SAXNotSupportedException
+org.xml.sax.XMLReader
+org.xml.sax.helpers.DefaultHandler
+org.xmlpull.v1.XmlPullParser
+org.xmlpull.v1.XmlPullParserException
+org.xmlpull.v1.XmlSerializer
+sun.invoke.util.BytecodeDescriptor
+sun.invoke.util.VerifyAccess
+sun.invoke.util.Wrapper
+sun.invoke.util.Wrapper$Format
+sun.misc.Cleaner
+sun.misc.CompoundEnumeration
+sun.misc.FDBigInteger
+sun.misc.FloatingDecimal
+sun.misc.FloatingDecimal$1
+sun.misc.FloatingDecimal$ASCIIToBinaryBuffer
+sun.misc.FloatingDecimal$ASCIIToBinaryConverter
+sun.misc.FloatingDecimal$BinaryToASCIIBuffer
+sun.misc.FloatingDecimal$BinaryToASCIIConverter
+sun.misc.FloatingDecimal$ExceptionalBinaryToASCIIBuffer
+sun.misc.FloatingDecimal$PreparedASCIIToBinaryBuffer
+sun.misc.FormattedFloatingDecimal
+sun.misc.FormattedFloatingDecimal$1
+sun.misc.FormattedFloatingDecimal$Form
+sun.misc.IOUtils
+sun.misc.JavaIOFileDescriptorAccess
+sun.misc.REException
+sun.misc.SharedSecrets
+sun.misc.Unsafe
+sun.misc.VM
+sun.misc.Version
+sun.net.ConnectionResetException
+sun.net.NetHooks
+sun.net.NetProperties
+sun.net.NetProperties$1
+sun.net.spi.DefaultProxySelector
+sun.net.spi.DefaultProxySelector$1
+sun.net.spi.DefaultProxySelector$NonProxyInfo
+sun.net.spi.nameservice.NameService
+sun.net.util.IPAddressUtil
+sun.net.www.ParseUtil
+sun.net.www.protocol.file.Handler
+sun.net.www.protocol.jar.Handler
+sun.nio.ch.DatagramChannelImpl
+sun.nio.ch.DatagramDispatcher
+sun.nio.ch.DirectBuffer
+sun.nio.ch.FileChannelImpl
+sun.nio.ch.FileChannelImpl$Unmapper
+sun.nio.ch.FileDispatcher
+sun.nio.ch.FileDispatcherImpl
+sun.nio.ch.FileKey
+sun.nio.ch.FileLockImpl
+sun.nio.ch.FileLockTable
+sun.nio.ch.IOStatus
+sun.nio.ch.IOUtil
+sun.nio.ch.Interruptible
+sun.nio.ch.NativeDispatcher
+sun.nio.ch.NativeThread
+sun.nio.ch.NativeThreadSet
+sun.nio.ch.Net
+sun.nio.ch.SelChImpl
+sun.nio.ch.ServerSocketChannelImpl
+sun.nio.ch.SharedFileLockTable
+sun.nio.ch.SharedFileLockTable$FileLockReference
+sun.nio.ch.SocketChannelImpl
+sun.nio.ch.Util
+sun.nio.ch.Util$1
+sun.nio.ch.Util$BufferCache
+sun.nio.cs.ArrayDecoder
+sun.nio.cs.ArrayEncoder
+sun.nio.cs.StreamDecoder
+sun.nio.cs.StreamEncoder
+sun.security.action.GetBooleanAction
+sun.security.action.GetPropertyAction
+sun.security.jca.GetInstance
+sun.security.jca.GetInstance$Instance
+sun.security.jca.ProviderConfig
+sun.security.jca.ProviderConfig$2
+sun.security.jca.ProviderList
+sun.security.jca.ProviderList$1
+sun.security.jca.ProviderList$2
+sun.security.jca.ProviderList$3
+sun.security.jca.ProviderList$ServiceList
+sun.security.jca.ProviderList$ServiceList$1
+sun.security.jca.Providers
+sun.security.jca.ServiceId
+sun.security.pkcs.PKCS9Attribute
+sun.security.pkcs.SignerInfo
+sun.security.provider.CertPathProvider
+sun.security.provider.X509Factory
+sun.security.provider.certpath.AdaptableX509CertSelector
+sun.security.provider.certpath.AlgorithmChecker
+sun.security.provider.certpath.BasicChecker
+sun.security.provider.certpath.CertPathHelper
+sun.security.provider.certpath.ConstraintsChecker
+sun.security.provider.certpath.KeyChecker
+sun.security.provider.certpath.PKIX
+sun.security.provider.certpath.PKIX$ValidatorParams
+sun.security.provider.certpath.PKIXCertPathValidator
+sun.security.provider.certpath.PKIXMasterCertPathValidator
+sun.security.provider.certpath.PolicyChecker
+sun.security.provider.certpath.PolicyNodeImpl
+sun.security.util.AbstractAlgorithmConstraints
+sun.security.util.AbstractAlgorithmConstraints$1
+sun.security.util.AlgorithmDecomposer
+sun.security.util.BitArray
+sun.security.util.ByteArrayLexOrder
+sun.security.util.ByteArrayTagOrder
+sun.security.util.Cache
+sun.security.util.Cache$EqualByteArray
+sun.security.util.CertConstraintParameters
+sun.security.util.Debug
+sun.security.util.DerEncoder
+sun.security.util.DerIndefLenConverter
+sun.security.util.DerInputBuffer
+sun.security.util.DerInputStream
+sun.security.util.DerOutputStream
+sun.security.util.DerValue
+sun.security.util.DisabledAlgorithmConstraints
+sun.security.util.DisabledAlgorithmConstraints$Constraint
+sun.security.util.DisabledAlgorithmConstraints$Constraint$Operator
+sun.security.util.DisabledAlgorithmConstraints$Constraints
+sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraint
+sun.security.util.KeyUtil
+sun.security.util.Length
+sun.security.util.MemoryCache
+sun.security.util.MemoryCache$CacheEntry
+sun.security.util.MemoryCache$SoftCacheEntry
+sun.security.util.ObjectIdentifier
+sun.security.x509.AVA
+sun.security.x509.AVAKeyword
+sun.security.x509.AccessDescription
+sun.security.x509.AlgorithmId
+sun.security.x509.AuthorityInfoAccessExtension
+sun.security.x509.AuthorityKeyIdentifierExtension
+sun.security.x509.BasicConstraintsExtension
+sun.security.x509.CRLDistributionPointsExtension
+sun.security.x509.CRLNumberExtension
+sun.security.x509.CRLReasonCodeExtension
+sun.security.x509.CertAttrSet
+sun.security.x509.CertificateAlgorithmId
+sun.security.x509.CertificateExtensions
+sun.security.x509.CertificateIssuerExtension
+sun.security.x509.CertificatePoliciesExtension
+sun.security.x509.CertificatePolicyId
+sun.security.x509.CertificateSerialNumber
+sun.security.x509.CertificateValidity
+sun.security.x509.CertificateVersion
+sun.security.x509.CertificateX509Key
+sun.security.x509.DNSName
+sun.security.x509.DeltaCRLIndicatorExtension
+sun.security.x509.DistributionPoint
+sun.security.x509.ExtendedKeyUsageExtension
+sun.security.x509.Extension
+sun.security.x509.FreshestCRLExtension
+sun.security.x509.GeneralName
+sun.security.x509.GeneralNameInterface
+sun.security.x509.GeneralNames
+sun.security.x509.InhibitAnyPolicyExtension
+sun.security.x509.IssuerAlternativeNameExtension
+sun.security.x509.IssuingDistributionPointExtension
+sun.security.x509.KeyIdentifier
+sun.security.x509.KeyUsageExtension
+sun.security.x509.NameConstraintsExtension
+sun.security.x509.NetscapeCertTypeExtension
+sun.security.x509.OCSPNoCheckExtension
+sun.security.x509.OIDMap
+sun.security.x509.OIDMap$OIDInfo
+sun.security.x509.PKIXExtensions
+sun.security.x509.PolicyConstraintsExtension
+sun.security.x509.PolicyInformation
+sun.security.x509.PolicyMappingsExtension
+sun.security.x509.PrivateKeyUsageExtension
+sun.security.x509.RDN
+sun.security.x509.SerialNumber
+sun.security.x509.SubjectAlternativeNameExtension
+sun.security.x509.SubjectInfoAccessExtension
+sun.security.x509.SubjectKeyIdentifierExtension
+sun.security.x509.URIName
+sun.security.x509.X500Name
+sun.security.x509.X500Name$1
+sun.security.x509.X509AttributeName
+sun.security.x509.X509CertImpl
+sun.security.x509.X509CertInfo
+sun.security.x509.X509Key
+sun.util.calendar.AbstractCalendar
+sun.util.calendar.BaseCalendar
+sun.util.calendar.BaseCalendar$Date
+sun.util.calendar.CalendarDate
+sun.util.calendar.CalendarSystem
+sun.util.calendar.CalendarUtils
+sun.util.calendar.Gregorian
+sun.util.calendar.Gregorian$Date
+sun.util.calendar.JulianCalendar
+sun.util.calendar.LocalGregorianCalendar
+sun.util.locale.BaseLocale
+sun.util.locale.BaseLocale$Cache
+sun.util.locale.BaseLocale$Key
+sun.util.locale.InternalLocaleBuilder
+sun.util.locale.InternalLocaleBuilder$CaseInsensitiveChar
+sun.util.locale.LanguageTag
+sun.util.locale.LocaleObjectCache
+sun.util.locale.LocaleObjectCache$CacheEntry
+sun.util.locale.LocaleSyntaxException
+sun.util.locale.LocaleUtils
+sun.util.locale.ParseStatus
+sun.util.locale.StringTokenIterator
+sun.util.logging.LoggingProxy
+sun.util.logging.LoggingSupport
+sun.util.logging.LoggingSupport$1
+sun.util.logging.PlatformLogger
+sun.util.logging.PlatformLogger$1
+sun.util.logging.PlatformLogger$Level
diff --git a/core/java/Android.bp b/core/java/Android.bp
new file mode 100644
index 0000000..42b0f6b
--- /dev/null
+++ b/core/java/Android.bp
@@ -0,0 +1,4 @@
+filegroup {
+    name: "IKeyAttestationApplicationIdProvider.aidl",
+    srcs: ["android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl"],
+}
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index 87e512c..7ca65a4 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -175,6 +175,9 @@
                 }
                 if (result != null) {
                     response.onResult(result);
+                } else {
+                    response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
+                            "null bundle returned");
                 }
             } catch (Exception e) {
                 handleException(response, "addAccount", accountType, e);
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index a446296..d22e268 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -2318,6 +2318,10 @@
         private class Response extends IAccountManagerResponse.Stub {
             @Override
             public void onResult(Bundle bundle) {
+                if (bundle == null) {
+                    onError(ERROR_CODE_INVALID_RESPONSE, "null bundle returned");
+                    return;
+                }
                 Intent intent = bundle.getParcelable(KEY_INTENT);
                 if (intent != null && mActivity != null) {
                     // since the user provided an Activity we will silently start intents
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 854e531..00d6657 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -1667,6 +1667,8 @@
         int childrenSize = parent.mChildNodes.size();
         for (int i = 0; i < childrenSize; i++) {
             Node child = parent.mChildNodes.get(i);
+            child.mTotalDuration = child.mAnimation.getTotalDuration();  // Update cached duration.
+
             int index = visited.indexOf(child);
             if (index >= 0) {
                 // Child has been visited, cycle found. Mark all the nodes in the cycle.
@@ -1693,9 +1695,8 @@
                         child.mStartTime = parent.mEndTime;
                     }
 
-                    long duration = child.mAnimation.getTotalDuration();
-                    child.mEndTime = duration == DURATION_INFINITE ?
-                            DURATION_INFINITE : child.mStartTime + duration;
+                    child.mEndTime = child.mTotalDuration == DURATION_INFINITE
+                            ? DURATION_INFINITE : child.mStartTime + child.mTotalDuration;
                 }
             }
             updatePlayTime(child, visited);
diff --git a/core/java/android/annotation/IntDef.java b/core/java/android/annotation/IntDef.java
index dd712a6..3f9064e 100644
--- a/core/java/android/annotation/IntDef.java
+++ b/core/java/android/annotation/IntDef.java
@@ -19,7 +19,7 @@
 import java.lang.annotation.Target;
 
 import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.RetentionPolicy.CLASS;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 /**
  * Denotes that the annotated element of integer type, represents
@@ -48,7 +48,7 @@
  *
  * @hide
  */
-@Retention(CLASS)
+@Retention(SOURCE)
 @Target({ANNOTATION_TYPE})
 public @interface IntDef {
     /** Defines the constant prefix for this element */
diff --git a/core/java/android/annotation/StringDef.java b/core/java/android/annotation/StringDef.java
index 8c8d5d8..d5157c3 100644
--- a/core/java/android/annotation/StringDef.java
+++ b/core/java/android/annotation/StringDef.java
@@ -19,7 +19,7 @@
 import java.lang.annotation.Target;
 
 import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.RetentionPolicy.CLASS;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 /**
  * Denotes that the annotated String element, represents a logical
@@ -43,7 +43,7 @@
  *
  * @hide
  */
-@Retention(CLASS)
+@Retention(SOURCE)
 @Target({ANNOTATION_TYPE})
 public @interface StringDef {
     /** Defines the allowed constants for this element */
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index bc6e9cd..0d89c6f 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -16,8 +16,6 @@
 
 package android.app;
 
-import static android.os.Build.VERSION_CODES.O;
-
 import static java.lang.Character.MIN_VALUE;
 
 import android.annotation.CallSuper;
@@ -976,18 +974,6 @@
     @CallSuper
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
-
-        if (getApplicationInfo().targetSdkVersion > O && mActivityInfo.isFixedOrientation()) {
-            final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window);
-            final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta);
-            ta.recycle();
-
-            if (isTranslucentOrFloating) {
-                throw new IllegalStateException(
-                        "Only fullscreen opaque activities can request orientation");
-            }
-        }
-
         if (mLastNonConfigurationInstances != null) {
             mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
         }
@@ -4358,7 +4344,7 @@
             throw new IllegalArgumentException("requestCode should be >= 0");
         }
         if (mHasCurrentPermissionsRequest) {
-            Log.w(TAG, "Can reqeust only one set of permissions at a time");
+            Log.w(TAG, "Can request only one set of permissions at a time");
             // Dispatch the callback with empty arrays which means a cancellation.
             onRequestPermissionsResult(requestCode, new String[0], new int[0]);
             return;
@@ -6416,17 +6402,7 @@
      */
     @Deprecated
     public boolean requestVisibleBehind(boolean visible) {
-        if (!mResumed) {
-            // Do not permit paused or stopped activities to do this.
-            visible = false;
-        }
-        try {
-            mVisibleBehind = ActivityManager.getService()
-                    .requestVisibleBehind(mToken, visible) && visible;
-        } catch (RemoteException e) {
-            mVisibleBehind = false;
-        }
-        return mVisibleBehind;
+        return false;
     }
 
     /**
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index f398c8d..06dbe82 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -360,6 +360,13 @@
             FIRST_START_NON_FATAL_ERROR_CODE + 1;
 
     /**
+     * Result for IActivityManaqer.startActivity: a new activity start was aborted. Never returned
+     * externally.
+     * @hide
+     */
+    public static final int START_ABORTED = FIRST_START_NON_FATAL_ERROR_CODE + 2;
+
+    /**
      * Flag for IActivityManaqer.startActivity: do special start mode where
      * a new activity is launched only if it is needed.
      * @hide
@@ -649,6 +656,9 @@
      */
     public static final int COMPAT_MODE_TOGGLE = 2;
 
+    private static final boolean DEVELOPMENT_FORCE_LOW_RAM =
+            SystemProperties.getBoolean("debug.force_low_ram", false);
+
     /** @hide */
     public static class StackId {
         /** Invalid stack ID. */
@@ -1108,7 +1118,20 @@
 
     /** @hide */
     public static boolean isLowRamDeviceStatic() {
-        return RoSystemProperties.CONFIG_LOW_RAM;
+        return RoSystemProperties.CONFIG_LOW_RAM ||
+                (Build.IS_DEBUGGABLE && DEVELOPMENT_FORCE_LOW_RAM);
+    }
+
+    /**
+     * Returns true if this is a small battery device. Exactly whether a device is considered to be
+     * small battery is ultimately up to the device configuration, but currently it generally means
+     * something in the class of a device with 1000 mAh or less. This is mostly intended to be used
+     * to determine whether certain features should be altered to account for a drastically smaller
+     * battery.
+     * @hide
+     */
+    public static boolean isSmallBatteryDevice() {
+        return RoSystemProperties.CONFIG_SMALL_BATTERY;
     }
 
     /**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 4aac830..14ac726 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -29,8 +29,8 @@
 import android.content.ContentProvider;
 import android.content.Context;
 import android.content.IContentProvider;
-import android.content.Intent;
 import android.content.IIntentReceiver;
+import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
@@ -91,6 +91,7 @@
 import android.provider.Downloads;
 import android.provider.FontsContract;
 import android.provider.Settings;
+import android.renderscript.RenderScriptCacheDir;
 import android.security.NetworkSecurityPolicy;
 import android.security.net.config.NetworkSecurityConfigProvider;
 import android.util.AndroidRuntimeException;
@@ -114,7 +115,6 @@
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
-import android.renderscript.RenderScriptCacheDir;
 import android.webkit.WebView;
 
 import com.android.internal.annotations.GuardedBy;
@@ -127,8 +127,21 @@
 import com.android.internal.util.FastPrintWriter;
 import com.android.org.conscrypt.OpenSSLSocketImpl;
 import com.android.org.conscrypt.TrustedCertificateStore;
+
+import dalvik.system.BaseDexClassLoader;
+import dalvik.system.CloseGuard;
+import dalvik.system.VMDebug;
+import dalvik.system.VMRuntime;
+
 import com.google.android.collect.Lists;
 
+import libcore.io.DropBox;
+import libcore.io.EventLogger;
+import libcore.io.IoUtils;
+import libcore.net.event.NetworkEventDispatcher;
+
+import org.apache.harmony.dalvik.ddmc.DdmVmInternal;
+
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
@@ -145,16 +158,6 @@
 import java.util.Objects;
 import java.util.TimeZone;
 
-import libcore.io.DropBox;
-import libcore.io.EventLogger;
-import libcore.io.IoUtils;
-import libcore.net.event.NetworkEventDispatcher;
-import dalvik.system.BaseDexClassLoader;
-import dalvik.system.CloseGuard;
-import dalvik.system.VMDebug;
-import dalvik.system.VMRuntime;
-import org.apache.harmony.dalvik.ddmc.DdmVmInternal;
-
 final class RemoteServiceException extends AndroidRuntimeException {
     public RemoteServiceException(String msg) {
         super(msg);
@@ -2358,13 +2361,13 @@
                         memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
                         memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
                         memInfo.nativePrivateClean, memInfo.hasSwappedOutPss ?
-                        memInfo.nativeSwappedOut : memInfo.nativeSwappedOutPss,
+                        memInfo.nativeSwappedOutPss : memInfo.nativeSwappedOut,
                         nativeMax, nativeAllocated, nativeFree);
                 printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
                         memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
                         memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
                         memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss ?
-                        memInfo.dalvikSwappedOut : memInfo.dalvikSwappedOutPss,
+                        memInfo.dalvikSwappedOutPss : memInfo.dalvikSwappedOut,
                         dalvikMax, dalvikAllocated, dalvikFree);
             } else {
                 printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
@@ -2675,8 +2678,14 @@
         Activity activity = null;
         try {
             java.lang.ClassLoader cl = appContext.getClassLoader();
-            activity = mInstrumentation.newActivity(
-                    cl, component.getClassName(), r.intent);
+            if (appContext.getApplicationContext() instanceof Application) {
+                activity = ((Application) appContext.getApplicationContext())
+                        .instantiateActivity(cl, component.getClassName(), r.intent);
+            }
+            if (activity == null) {
+                activity = mInstrumentation.newActivity(
+                        cl, component.getClassName(), r.intent);
+            }
             StrictMode.incrementExpectedActivityCount(activity.getClass());
             r.intent.setExtrasClassLoader(cl);
             r.intent.prepareToEnterProcess();
@@ -2857,6 +2866,9 @@
             TAG, "Handling launch of " + r);
 
         // Initialize before creating the activity
+        if (!ThreadedRenderer.sRendererDisabled) {
+            GraphicsEnvironment.earlyInitEGL();
+        }
         WindowManagerGlobal.initialize();
 
         Activity a = performLaunchActivity(r, customIntent);
@@ -3198,7 +3210,8 @@
             data.intent.setExtrasClassLoader(cl);
             data.intent.prepareToEnterProcess();
             data.setExtrasClassLoader(cl);
-            receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
+            receiver = instantiate(cl, component, data.intent, app,
+                    Application::instantiateReceiver);
         } catch (Exception e) {
             if (DEBUG_BROADCAST) Slog.i(TAG,
                     "Finishing failed broadcast to " + data.intent.getComponent());
@@ -3286,12 +3299,13 @@
             } else {
                 try {
                     if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
+                    ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
 
                     java.lang.ClassLoader cl = packageInfo.getClassLoader();
-                    agent = (BackupAgent) cl.loadClass(classname).newInstance();
+                    agent = instantiate(cl, classname, context,
+                            Application::instantiateBackupAgent);
 
                     // set up the agent's context
-                    ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
                     context.setOuterContext(agent);
                     agent.attach(context);
 
@@ -3351,9 +3365,12 @@
         LoadedApk packageInfo = getPackageInfoNoCheck(
                 data.info.applicationInfo, data.compatInfo);
         Service service = null;
+        Application app = null;
         try {
+            app = packageInfo.makeApplication(false, mInstrumentation);
             java.lang.ClassLoader cl = packageInfo.getClassLoader();
-            service = (Service) cl.loadClass(data.info.name).newInstance();
+            service = instantiate(cl, data.info.name, data.intent, app,
+                    Application::instantiateService);
         } catch (Exception e) {
             if (!mInstrumentation.onException(service, e)) {
                 throw new RuntimeException(
@@ -3368,7 +3385,6 @@
             ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
             context.setOuterContext(service);
 
-            Application app = packageInfo.makeApplication(false, mInstrumentation);
             service.attach(context, this, data.info.name, data.token, app,
                     ActivityManager.getService());
             service.onCreate();
@@ -4908,7 +4924,8 @@
             // If the new config is the same as the config this Activity is already running with and
             // the override config also didn't change, then don't bother calling
             // onConfigurationChanged.
-            int diff = activity.mCurrentConfig.diff(newConfig);
+            final int diff = activity.mCurrentConfig.diffPublicOnly(newConfig);
+
             if (diff != 0 || !mResourcesManager.isSameResourcesOverrideConfig(activityToken,
                     amOverrideConfig)) {
                 // Always send the task-level config changes. For system-level configuration, if
@@ -4996,6 +5013,14 @@
 
         int configDiff = 0;
 
+        // This flag tracks whether the new configuration is fundamentally equivalent to the
+        // existing configuration. This is necessary to determine whether non-activity
+        // callbacks should receive notice when the only changes are related to non-public fields.
+        // We do not gate calling {@link #performActivityConfigurationChanged} based on this flag
+        // as that method uses the same check on the activity config override as well.
+        final boolean equivalent = config != null && mConfiguration != null
+                && (0 == mConfiguration.diffPublicOnly(config));
+
         synchronized (mResourcesManager) {
             if (mPendingConfiguration != null) {
                 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
@@ -5052,7 +5077,7 @@
                     Activity a = (Activity) cb;
                     performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()),
                             config);
-                } else {
+                } else if (!equivalent) {
                     performConfigurationChanged(cb, config);
                 }
             }
@@ -5342,26 +5367,45 @@
         WindowManagerGlobal.getInstance().trimMemory(level);
     }
 
-    private void setupGraphicsSupport(Context context, File cacheDir) {
-        if (Process.isIsolated()) {
-            // Isolated processes aren't going to do UI.
-            return;
-        }
+    private void setupGraphicsSupport(Context context) {
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setupGraphicsSupport");
-        try {
-            int uid = Process.myUid();
-            String[] packages = getPackageManager().getPackagesForUid(uid);
 
-            if (packages != null) {
-                ThreadedRenderer.setupDiskCache(cacheDir);
-                RenderScriptCacheDir.setupDiskCache(cacheDir);
-                GraphicsEnvironment.setupGraphicsEnvironment(context);
+        // The system package doesn't have real data directories, so don't set up cache paths.
+        if (!"android".equals(context.getPackageName())) {
+            // This cache location probably points at credential-encrypted
+            // storage which may not be accessible yet; assign it anyway instead
+            // of pointing at device-encrypted storage.
+            final File cacheDir = context.getCacheDir();
+            if (cacheDir != null) {
+                // Provide a usable directory for temporary files
+                System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
+            } else {
+                Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "
+                        + "due to missing cache directory");
             }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+
+            // Setup a location to store generated/compiled graphics code.
+            final Context deviceContext = context.createDeviceProtectedStorageContext();
+            final File codeCacheDir = deviceContext.getCodeCacheDir();
+            if (codeCacheDir != null) {
+                try {
+                    int uid = Process.myUid();
+                    String[] packages = getPackageManager().getPackagesForUid(uid);
+                    if (packages != null) {
+                        ThreadedRenderer.setupDiskCache(codeCacheDir);
+                        RenderScriptCacheDir.setupDiskCache(codeCacheDir);
+                    }
+                } catch (RemoteException e) {
+                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+                    throw e.rethrowFromSystemServer();
+                }
+            } else {
+                Log.w(TAG, "Unable to use shader/script cache: missing code-cache directory");
+            }
         }
+
+        GraphicsEnvironment.chooseDriver(context);
+        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
     }
 
     private void updateDefaultDensity() {
@@ -5448,15 +5492,6 @@
         android.ddm.DdmHandleAppName.setAppName(data.processName,
                                                 UserHandle.myUserId());
 
-        if (data.persistent) {
-            // Persistent processes on low-memory devices do not get to
-            // use hardware accelerated drawing, since this can add too much
-            // overhead to the process.
-            if (!ActivityManager.isHighEndGfx()) {
-                ThreadedRenderer.disable(false);
-            }
-        }
-
         if (mProfiler.profileFd != null) {
             mProfiler.startProfiling();
         }
@@ -5643,27 +5678,8 @@
         updateLocaleListFromAppContext(appContext,
                 mResourcesManager.getConfiguration().getLocales());
 
-        if (!Process.isIsolated() && !"android".equals(appContext.getPackageName())) {
-            // This cache location probably points at credential-encrypted
-            // storage which may not be accessible yet; assign it anyway instead
-            // of pointing at device-encrypted storage.
-            final File cacheDir = appContext.getCacheDir();
-            if (cacheDir != null) {
-                // Provide a usable directory for temporary files
-                System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
-            } else {
-                Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "
-                        + "due to missing cache directory");
-            }
-
-            // Setup a location to store generated/compiled graphics code.
-            final Context deviceContext = appContext.createDeviceProtectedStorageContext();
-            final File codeCacheDir = deviceContext.getCodeCacheDir();
-            if (codeCacheDir != null) {
-                setupGraphicsSupport(appContext, codeCacheDir);
-            } else {
-                Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
-            }
+        if (!Process.isIsolated()) {
+            setupGraphicsSupport(appContext);
         }
 
         // If we use profiles, setup the dex reporter to notify package manager
@@ -5694,8 +5710,8 @@
 
             try {
                 final ClassLoader cl = instrContext.getClassLoader();
-                mInstrumentation = (Instrumentation)
-                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
+                mInstrumentation = instantiate(cl, data.instrumentationName.getClassName(),
+                        instrContext, Application::instantiateInstrumentation);
             } catch (Exception e) {
                 throw new RuntimeException(
                     "Unable to instantiate instrumentation "
@@ -6240,8 +6256,8 @@
 
             try {
                 final java.lang.ClassLoader cl = c.getClassLoader();
-                localProvider = (ContentProvider)cl.
-                    loadClass(info.name).newInstance();
+                localProvider = instantiate(cl, info.name, context,
+                        Application::instantiateProvider);
                 provider = localProvider.getIContentProvider();
                 if (provider == null) {
                     Slog.e(TAG, "Failed to instantiate class " +
@@ -6440,6 +6456,49 @@
         }
     }
 
+    private <T> T instantiate(ClassLoader cl, String className, Context c,
+            Instantiator<T> instantiator)
+            throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+        Application app = getApp(c);
+        if (app != null) {
+            T a = instantiator.instantiate(app, cl, className);
+            if (a != null) return a;
+        }
+        return (T) cl.loadClass(className).newInstance();
+    }
+
+    private <T> T instantiate(ClassLoader cl, String className, Intent intent, Context c,
+            IntentInstantiator<T> instantiator)
+            throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+        Application app = getApp(c);
+        if (app != null) {
+            T a = instantiator.instantiate(app, cl, className, intent);
+            if (a != null) return a;
+        }
+        return (T) cl.loadClass(className).newInstance();
+    }
+
+    private Application getApp(Context c) {
+        // We need this shortcut to avoid actually calling getApplicationContext() on an Application
+        // because the Application may not return itself for getApplicationContext() because the
+        // API doesn't enforce it.
+        if (c instanceof Application) return (Application) c;
+        if (c.getApplicationContext() instanceof Application) {
+            return (Application) c.getApplicationContext();
+        }
+        return null;
+    }
+
+    private interface Instantiator<T> {
+        T instantiate(Application app, ClassLoader cl, String className)
+                throws ClassNotFoundException, IllegalAccessException, InstantiationException;
+    }
+
+    private interface IntentInstantiator<T> {
+        T instantiate(Application app, ClassLoader cl, String className, Intent intent)
+                throws ClassNotFoundException, IllegalAccessException, InstantiationException;
+    }
+
     private static class EventLoggingReporter implements EventLogger.Reporter {
         @Override
         public void report (int code, Object... list) {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index e672ada..b331d84 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1947,4 +1947,13 @@
     public void finishOp(int op) {
         finishOp(op, Process.myUid(), mContext.getOpPackageName());
     }
+
+    /** @hide */
+    public boolean isOperationActive(int code, int uid, String packageName) {
+        try {
+            return mService.isOperationActive(code, uid, packageName);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index 156df36..7fb5e2e 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -16,17 +16,20 @@
 
 package android.app;
 
-import java.util.ArrayList;
-
 import android.annotation.CallSuper;
+import android.app.backup.BackupAgent;
+import android.content.BroadcastReceiver;
 import android.content.ComponentCallbacks;
 import android.content.ComponentCallbacks2;
+import android.content.ContentProvider;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.os.Bundle;
 
+import java.util.ArrayList;
+
 /**
  * Base class for maintaining global application state. You can provide your own
  * implementation by creating a subclass and specifying the fully-qualified name
@@ -289,4 +292,79 @@
             }
         }
     }
+
+    /**
+     * Allows application to override the creation of activities. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @param intent Intent creating the class.
+     * @hide
+     */
+    public Activity instantiateActivity(ClassLoader cl, String className, Intent intent) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of receivers. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @param intent Intent creating the class.
+     * @hide
+     */
+    public BroadcastReceiver instantiateReceiver(ClassLoader cl, String className, Intent intent) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of services. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @param intent Intent creating the class.
+     * @hide
+     */
+    public Service instantiateService(ClassLoader cl, String className, Intent intent) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of providers. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @hide
+     */
+    public ContentProvider instantiateProvider(ClassLoader cl, String className) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of backup agents. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @hide
+     */
+    public BackupAgent instantiateBackupAgent(ClassLoader cl, String className) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of instrumentation. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @hide
+     */
+    public Instrumentation instantiateInstrumentation(ClassLoader cl, String className) {
+        return null;
+    }
 }
\ No newline at end of file
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index e5c42087..7fc9a69 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -78,6 +78,10 @@
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 import android.provider.Settings;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.StructStat;
 import android.util.ArrayMap;
 import android.util.IconDrawableFactory;
 import android.util.LauncherIcons;
@@ -281,7 +285,8 @@
     public PermissionInfo getPermissionInfo(String name, int flags)
             throws NameNotFoundException {
         try {
-            PermissionInfo pi = mPM.getPermissionInfo(name, flags);
+            PermissionInfo pi = mPM.getPermissionInfo(name,
+                    mContext.getOpPackageName(), flags);
             if (pi != null) {
                 return pi;
             }
@@ -2674,4 +2679,78 @@
             throw e.rethrowAsRuntimeException();
         }
     }
+
+    private static class DexModuleRegisterResult {
+        final String dexModulePath;
+        final boolean success;
+        final String message;
+
+        private DexModuleRegisterResult(String dexModulePath, boolean success, String message) {
+            this.dexModulePath = dexModulePath;
+            this.success = success;
+            this.message = message;
+        }
+    }
+
+    private static class DexModuleRegisterCallbackDelegate
+            extends android.content.pm.IDexModuleRegisterCallback.Stub
+            implements Handler.Callback {
+        private static final int MSG_DEX_MODULE_REGISTERED = 1;
+        private final DexModuleRegisterCallback callback;
+        private final Handler mHandler;
+
+        DexModuleRegisterCallbackDelegate(@NonNull DexModuleRegisterCallback callback) {
+            this.callback = callback;
+            mHandler = new Handler(Looper.getMainLooper(), this);
+        }
+
+        @Override
+        public void onDexModuleRegistered(@NonNull String dexModulePath, boolean success,
+                @Nullable String message)throws RemoteException {
+            mHandler.obtainMessage(MSG_DEX_MODULE_REGISTERED,
+                    new DexModuleRegisterResult(dexModulePath, success, message)).sendToTarget();
+        }
+
+        @Override
+        public boolean handleMessage(Message msg) {
+            if (msg.what != MSG_DEX_MODULE_REGISTERED) {
+                return false;
+            }
+            DexModuleRegisterResult result = (DexModuleRegisterResult)msg.obj;
+            callback.onDexModuleRegistered(result.dexModulePath, result.success, result.message);
+            return true;
+        }
+    }
+
+    @Override
+    public void registerDexModule(@NonNull String dexModule,
+            @Nullable DexModuleRegisterCallback callback) {
+        // Check if this is a shared module by looking if the others can read it.
+        boolean isSharedModule = false;
+        try {
+            StructStat stat = Os.stat(dexModule);
+            if ((OsConstants.S_IROTH & stat.st_mode) != 0) {
+                isSharedModule = true;
+            }
+        } catch (ErrnoException e) {
+            callback.onDexModuleRegistered(dexModule, false,
+                    "Could not get stat the module file: " + e.getMessage());
+            return;
+        }
+
+        // Module path is ok.
+        // Create the callback delegate to be passed to package manager service.
+        DexModuleRegisterCallbackDelegate callbackDelegate = null;
+        if (callback != null) {
+            callbackDelegate = new DexModuleRegisterCallbackDelegate(callback);
+        }
+
+        // Invoke the package manager service.
+        try {
+            mPM.registerDexModule(mContext.getPackageName(), dexModule,
+                    isSharedModule, callbackDelegate);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
 }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 3ea0c83..318c7ac 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -63,7 +63,6 @@
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.system.ErrnoException;
@@ -90,6 +89,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.ByteOrder;
+import java.util.ArrayList;
 import java.util.Objects;
 
 class ReceiverRestrictedContext extends ContextWrapper {
@@ -374,27 +374,26 @@
         // STOPSHIP: fix buggy apps
         if (SystemProperties.getBoolean("fw.ignore_buggy", false)) return false;
         if ("com.google.android.tts".equals(getApplicationInfo().packageName)) return true;
-        if ("com.breel.geswallpapers".equals(getApplicationInfo().packageName)) return true;
         return false;
     }
 
     @Override
     public SharedPreferences getSharedPreferences(File file, int mode) {
-        checkMode(mode);
-        if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O) {
-            if (isCredentialProtectedStorage()
-                    && !getSystemService(StorageManager.class).isUserKeyUnlocked(
-                            UserHandle.myUserId())
-                    && !isBuggy()) {
-                throw new IllegalStateException("SharedPreferences in credential encrypted "
-                        + "storage are not available until after user is unlocked");
-            }
-        }
         SharedPreferencesImpl sp;
         synchronized (ContextImpl.class) {
             final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked();
             sp = cache.get(file);
             if (sp == null) {
+                checkMode(mode);
+                if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O) {
+                    if (isCredentialProtectedStorage()
+                            && !getSystemService(StorageManager.class).isUserKeyUnlocked(
+                            UserHandle.myUserId())
+                            && !isBuggy()) {
+                        throw new IllegalStateException("SharedPreferences in credential encrypted "
+                                + "storage are not available until after user is unlocked");
+                    }
+                }
                 sp = new SharedPreferencesImpl(file, mode);
                 cache.put(file, sp);
                 return sp;
@@ -425,6 +424,26 @@
         return packagePrefs;
     }
 
+    @Override
+    public void reloadSharedPreferences() {
+        // Build the list of all per-context impls (i.e. caches) we know about
+        ArrayList<SharedPreferencesImpl> spImpls = new ArrayList<>();
+        synchronized (ContextImpl.class) {
+            final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked();
+            for (int i = 0; i < cache.size(); i++) {
+                final SharedPreferencesImpl sp = cache.valueAt(i);
+                if (sp != null) {
+                    spImpls.add(sp);
+                }
+            }
+        }
+
+        // Issue the reload outside the cache lock
+        for (int i = 0; i < spImpls.size(); i++) {
+            spImpls.get(i).startReloadIfChangedUnexpectedly();
+        }
+    }
+
     /**
      * Try our best to migrate all files from source to target that match
      * requested prefix.
diff --git a/core/java/android/app/DexLoadReporter.java b/core/java/android/app/DexLoadReporter.java
index 5f61e07..01c045b 100644
--- a/core/java/android/app/DexLoadReporter.java
+++ b/core/java/android/app/DexLoadReporter.java
@@ -29,7 +29,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -114,13 +113,18 @@
         registerSecondaryDexForProfiling(dexPathsForRegistration);
     }
 
-    private void notifyPackageManager(List<BaseDexClassLoader> ignored,
+    private void notifyPackageManager(List<BaseDexClassLoader> classLoadersChain,
             List<String> classPaths) {
+        // Get the class loader names for the binder call.
+        List<String> classLoadersNames = new ArrayList<>(classPaths.size());
+        for (BaseDexClassLoader bdc : classLoadersChain) {
+            classLoadersNames.add(bdc.getClass().getName());
+        }
         String packageName = ActivityThread.currentPackageName();
         try {
             // Notify only the paths of the first class loader for now.
             ActivityThread.getPackageManager().notifyDexLoad(
-                    packageName, Arrays.asList(classPaths.get(0).split(File.pathSeparator)),
+                    packageName, classLoadersNames, classPaths,
                     VMRuntime.getRuntime().vmInstructionSet());
         } catch (RemoteException re) {
             Slog.e(TAG, "Failed to notify PM about dex load for package " + packageName, re);
@@ -148,22 +152,39 @@
             // The dex path is not a secondary dex file. Nothing to do.
             return;
         }
-        File secondaryProfile = getSecondaryProfileFile(dexPath);
+
+        // Secondary dex profiles are stored in the oat directory, next to dex file
+        // and have the same name with 'cur.prof' appended.
+        // NOTE: Keep this in sync with installd expectations.
+        File dexPathFile = new File(dexPath);
+        File secondaryProfileDir = new File(dexPathFile.getParent(), "oat");
+        File secondaryProfile = new File(secondaryProfileDir, dexPathFile.getName() + ".cur.prof");
+
+        // Create the profile if not already there.
+        // Returns true if the file was created, false if the file already exists.
+        // or throws exceptions in case of errors.
+        if (!secondaryProfileDir.exists()) {
+            if (!secondaryProfileDir.mkdir()) {
+                Slog.e(TAG, "Could not create the profile directory: " + secondaryProfile);
+                // Do not continue with registration if we could not create the oat dir.
+                return;
+            }
+        }
+
         try {
-            // Create the profile if not already there.
-            // Returns true if the file was created, false if the file already exists.
-            // or throws exceptions in case of errors.
             boolean created = secondaryProfile.createNewFile();
             if (DEBUG && created) {
                 Slog.i(TAG, "Created profile for secondary dex: " + secondaryProfile);
             }
         } catch (IOException ex) {
-            Slog.e(TAG, "Failed to create profile for secondary dex " + secondaryProfile +
-                    ":" + ex.getMessage());
-            // Don't move forward with the registration if we failed to create the profile.
+            Slog.e(TAG, "Failed to create profile for secondary dex " + dexPath
+                    + ":" + ex.getMessage());
+            // Do not continue with registration if we could not create the profile files.
             return;
         }
 
+        // If we got here, the dex paths is a secondary dex and we were able to create the profile.
+        // Register the path to the runtime.
         VMRuntime.registerAppInfo(secondaryProfile.getPath(), new String[] { dexPath });
     }
 
@@ -177,11 +198,4 @@
         }
         return false;
     }
-
-    // Secondary dex profiles are stored next to the dex file and have the same
-    // name with '.prof' appended.
-    // NOTE: Keep in sync with installd.
-    private File getSecondaryProfileFile(String dexPath) {
-        return new File(dexPath + ".prof");
-    }
 }
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index c2fd007..66dc6a1 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -60,114 +60,6 @@
 import java.io.PrintWriter;
 import java.lang.reflect.InvocationTargetException;
 
-final class FragmentState implements Parcelable {
-    final String mClassName;
-    final int mIndex;
-    final boolean mFromLayout;
-    final int mFragmentId;
-    final int mContainerId;
-    final String mTag;
-    final boolean mRetainInstance;
-    final boolean mDetached;
-    final Bundle mArguments;
-    final boolean mHidden;
-
-    Bundle mSavedFragmentState;
-
-    Fragment mInstance;
-
-    public FragmentState(Fragment frag) {
-        mClassName = frag.getClass().getName();
-        mIndex = frag.mIndex;
-        mFromLayout = frag.mFromLayout;
-        mFragmentId = frag.mFragmentId;
-        mContainerId = frag.mContainerId;
-        mTag = frag.mTag;
-        mRetainInstance = frag.mRetainInstance;
-        mDetached = frag.mDetached;
-        mArguments = frag.mArguments;
-        mHidden = frag.mHidden;
-    }
-
-    public FragmentState(Parcel in) {
-        mClassName = in.readString();
-        mIndex = in.readInt();
-        mFromLayout = in.readInt() != 0;
-        mFragmentId = in.readInt();
-        mContainerId = in.readInt();
-        mTag = in.readString();
-        mRetainInstance = in.readInt() != 0;
-        mDetached = in.readInt() != 0;
-        mArguments = in.readBundle();
-        mHidden = in.readInt() != 0;
-        mSavedFragmentState = in.readBundle();
-    }
-
-    public Fragment instantiate(FragmentHostCallback host, FragmentContainer container,
-            Fragment parent, FragmentManagerNonConfig childNonConfig) {
-        if (mInstance == null) {
-            final Context context = host.getContext();
-            if (mArguments != null) {
-                mArguments.setClassLoader(context.getClassLoader());
-            }
-
-            if (container != null) {
-                mInstance = container.instantiate(context, mClassName, mArguments);
-            } else {
-                mInstance = Fragment.instantiate(context, mClassName, mArguments);
-            }
-
-            if (mSavedFragmentState != null) {
-                mSavedFragmentState.setClassLoader(context.getClassLoader());
-                mInstance.mSavedFragmentState = mSavedFragmentState;
-            }
-            mInstance.setIndex(mIndex, parent);
-            mInstance.mFromLayout = mFromLayout;
-            mInstance.mRestored = true;
-            mInstance.mFragmentId = mFragmentId;
-            mInstance.mContainerId = mContainerId;
-            mInstance.mTag = mTag;
-            mInstance.mRetainInstance = mRetainInstance;
-            mInstance.mDetached = mDetached;
-            mInstance.mHidden = mHidden;
-            mInstance.mFragmentManager = host.mFragmentManager;
-            if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
-                    "Instantiated fragment " + mInstance);
-        }
-        mInstance.mChildNonConfig = childNonConfig;
-        return mInstance;
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(mClassName);
-        dest.writeInt(mIndex);
-        dest.writeInt(mFromLayout ? 1 : 0);
-        dest.writeInt(mFragmentId);
-        dest.writeInt(mContainerId);
-        dest.writeString(mTag);
-        dest.writeInt(mRetainInstance ? 1 : 0);
-        dest.writeInt(mDetached ? 1 : 0);
-        dest.writeBundle(mArguments);
-        dest.writeInt(mHidden ? 1 : 0);
-        dest.writeBundle(mSavedFragmentState);
-    }
-
-    public static final Parcelable.Creator<FragmentState> CREATOR
-            = new Parcelable.Creator<FragmentState>() {
-        public FragmentState createFromParcel(Parcel in) {
-            return new FragmentState(in);
-        }
-
-        public FragmentState[] newArray(int size) {
-            return new FragmentState[size];
-        }
-    };
-}
-
 /**
  * A Fragment is a piece of an application's user interface or behavior
  * that can be placed in an {@link Activity}.  Interaction with fragments
@@ -984,7 +876,7 @@
 
     /**
      * Return true if the fragment is currently visible to the user.  This means
-     * it: (1) has been added, (2) has its view attached to the window, and 
+     * it: (1) has been added, (2) has its view attached to the window, and
      * (3) is not hidden.
      */
     final public boolean isVisible() {
@@ -1463,7 +1355,7 @@
      * declaration for the styleable used here is:</p>
      *
      * {@sample development/samples/ApiDemos/res/values/attrs.xml fragment_arguments}
-     * 
+     *
      * <p>The fragment can then be declared within its activity's content layout
      * through a tag like this:</p>
      *
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 6af1f12..6cb987c 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -670,7 +670,7 @@
 
     int mNextFragmentIndex = 0;
     SparseArray<Fragment> mActive;
-    ArrayList<Fragment> mAdded;
+    final ArrayList<Fragment> mAdded = new ArrayList<>();
     ArrayList<BackStackRecord> mBackStack;
     ArrayList<Fragment> mCreatedMenus;
     
@@ -925,7 +925,7 @@
 
     @Override
     public List<Fragment> getFragments() {
-        if (mAdded == null) {
+        if (mAdded.isEmpty()) {
             return Collections.EMPTY_LIST;
         }
         synchronized (mAdded) {
@@ -988,15 +988,17 @@
             }
         }
 
-        if (mAdded != null) {
-            N = mAdded.size();
-            if (N > 0) {
-                writer.print(prefix); writer.println("Added Fragments:");
-                for (int i=0; i<N; i++) {
-                    Fragment f = mAdded.get(i);
-                    writer.print(prefix); writer.print("  #"); writer.print(i);
-                            writer.print(": "); writer.println(f.toString());
-                }
+        N = mAdded.size();
+        if (N > 0) {
+            writer.print(prefix);
+            writer.println("Added Fragments:");
+            for (int i = 0; i < N; i++) {
+                Fragment f = mAdded.get(i);
+                writer.print(prefix);
+                writer.print("  #");
+                writer.print(i);
+                writer.print(": ");
+                writer.println(f.toString());
             }
         }
 
@@ -1604,14 +1606,12 @@
             boolean loadersRunning = false;
 
             // Must add them in the proper order. mActive fragments may be out of order
-            if (mAdded != null) {
-                final int numAdded = mAdded.size();
-                for (int i = 0; i < numAdded; i++) {
-                    Fragment f = mAdded.get(i);
-                    moveFragmentToExpectedState(f);
-                    if (f.mLoaderManager != null) {
-                        loadersRunning |= f.mLoaderManager.hasRunningLoaders();
-                    }
+            final int numAdded = mAdded.size();
+            for (int i = 0; i < numAdded; i++) {
+                Fragment f = mAdded.get(i);
+                moveFragmentToExpectedState(f);
+                if (f.mLoaderManager != null) {
+                    loadersRunning |= f.mLoaderManager.hasRunningLoaders();
                 }
             }
 
@@ -1677,9 +1677,6 @@
     }
     
     public void addFragment(Fragment fragment, boolean moveToStateNow) {
-        if (mAdded == null) {
-            mAdded = new ArrayList<Fragment>();
-        }
         if (DEBUG) Log.v(TAG, "add: " + fragment);
         makeActive(fragment);
         if (!fragment.mDetached) {
@@ -1715,10 +1712,8 @@
                     throw new IllegalStateException("Fragment not added: " + fragment);
                 }
             }
-            if (mAdded != null) {
-                synchronized (mAdded) {
-                    mAdded.remove(fragment);
-                }
+            synchronized (mAdded) {
+                mAdded.remove(fragment);
             }
             if (fragment.mHasMenu && fragment.mMenuVisible) {
                 mNeedMenuInvalidate = true;
@@ -1766,11 +1761,9 @@
             fragment.mDetached = true;
             if (fragment.mAdded) {
                 // We are not already in back stack, so need to remove the fragment.
-                if (mAdded != null) {
-                    if (DEBUG) Log.v(TAG, "remove from detach: " + fragment);
-                    synchronized (mAdded) {
-                        mAdded.remove(fragment);
-                    }
+                if (DEBUG) Log.v(TAG, "remove from detach: " + fragment);
+                synchronized (mAdded) {
+                    mAdded.remove(fragment);
                 }
                 if (fragment.mHasMenu && fragment.mMenuVisible) {
                     mNeedMenuInvalidate = true;
@@ -1785,9 +1778,6 @@
         if (fragment.mDetached) {
             fragment.mDetached = false;
             if (!fragment.mAdded) {
-                if (mAdded == null) {
-                    mAdded = new ArrayList<Fragment>();
-                }
                 if (mAdded.contains(fragment)) {
                     throw new IllegalStateException("Fragment already added: " + fragment);
                 }
@@ -1804,13 +1794,11 @@
     }
 
     public Fragment findFragmentById(int id) {
-        if (mAdded != null) {
-            // First look through added fragments.
-            for (int i=mAdded.size()-1; i>=0; i--) {
-                Fragment f = mAdded.get(i);
-                if (f != null && f.mFragmentId == id) {
-                    return f;
-                }
+        // First look through added fragments.
+        for (int i = mAdded.size() - 1; i >= 0; i--) {
+            Fragment f = mAdded.get(i);
+            if (f != null && f.mFragmentId == id) {
+                return f;
             }
         }
         if (mActive != null) {
@@ -1826,7 +1814,7 @@
     }
     
     public Fragment findFragmentByTag(String tag) {
-        if (mAdded != null && tag != null) {
+        if (tag != null) {
             // First look through added fragments.
             for (int i=mAdded.size()-1; i>=0; i--) {
                 Fragment f = mAdded.get(i);
@@ -1846,7 +1834,7 @@
         }
         return null;
     }
-    
+
     public Fragment findFragmentByWho(String who) {
         if (mActive != null && who != null) {
             for (int i=mActive.size()-1; i>=0; i--) {
@@ -2166,9 +2154,7 @@
         } else {
             mTmpAddedFragments.clear();
         }
-        if (mAdded != null) {
-            mTmpAddedFragments.addAll(mAdded);
-        }
+        mTmpAddedFragments.addAll(mAdded);
         Fragment oldPrimaryNav = getPrimaryNavigationFragment();
         for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
             final BackStackRecord record = records.get(recordNum);
@@ -2408,7 +2394,7 @@
         }
         // We want to leave the fragment in the started state
         final int state = Math.min(mCurState, Fragment.STARTED);
-        final int numAdded = mAdded == null ? 0 : mAdded.size();
+        final int numAdded = mAdded.size();
         for (int i = 0; i < numAdded; i++) {
             Fragment fragment = mAdded.get(i);
             if (fragment.mState < state) {
@@ -2756,23 +2742,21 @@
         BackStackState[] backStack = null;
         
         // Build list of currently added fragments.
-        if (mAdded != null) {
-            N = mAdded.size();
-            if (N > 0) {
-                added = new int[N];
-                for (int i=0; i<N; i++) {
-                    added[i] = mAdded.get(i).mIndex;
-                    if (added[i] < 0) {
-                        throwException(new IllegalStateException(
-                                "Failure saving state: active " + mAdded.get(i)
-                                + " has cleared index: " + added[i]));
-                    }
-                    if (DEBUG) Log.v(TAG, "saveAllState: adding fragment #" + i
-                            + ": " + mAdded.get(i));
+        N = mAdded.size();
+        if (N > 0) {
+            added = new int[N];
+            for (int i=0; i<N; i++) {
+                added[i] = mAdded.get(i).mIndex;
+                if (added[i] < 0) {
+                    throwException(new IllegalStateException(
+                            "Failure saving state: active " + mAdded.get(i)
+                            + " has cleared index: " + added[i]));
                 }
+                if (DEBUG) Log.v(TAG, "saveAllState: adding fragment #" + i
+                        + ": " + mAdded.get(i));
             }
         }
-        
+
         // Now save back stack.
         if (mBackStack != null) {
             N = mBackStack.size();
@@ -2878,8 +2862,8 @@
         }
 
         // Build the list of currently added fragments.
+        mAdded.clear();
         if (fms.mAdded != null) {
-            mAdded = new ArrayList<Fragment>(fms.mAdded.length);
             for (int i=0; i<fms.mAdded.length; i++) {
                 Fragment f = mActive.get(fms.mAdded[i]);
                 if (f == null) {
@@ -2895,8 +2879,6 @@
                     mAdded.add(f);
                 }
             }
-        } else {
-            mAdded = null;
         }
         
         // Build the back stack.
@@ -2972,7 +2954,7 @@
     public void noteStateNotSaved() {
         mSavedNonConfig = null;
         mStateSaved = false;
-        final int addedCount = mAdded == null ? 0 : mAdded.size();
+        final int addedCount = mAdded.size();
         for (int i = 0; i < addedCount; i++) {
             Fragment fragment = mAdded.get(i);
             if (fragment != null) {
@@ -3049,9 +3031,6 @@
      */
     @Deprecated
     public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode) {
-        if (mAdded == null) {
-            return;
-        }
         for (int i = mAdded.size() - 1; i >= 0; --i) {
             final Fragment f = mAdded.get(i);
             if (f != null) {
@@ -3062,9 +3041,6 @@
 
     public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode,
             Configuration newConfig) {
-        if (mAdded == null) {
-            return;
-        }
         for (int i = mAdded.size() - 1; i >= 0; --i) {
             final Fragment f = mAdded.get(i);
             if (f != null) {
@@ -3078,9 +3054,6 @@
      */
     @Deprecated
     public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
-        if (mAdded == null) {
-            return;
-        }
         for (int i = mAdded.size() - 1; i >= 0; --i) {
             final Fragment f = mAdded.get(i);
             if (f != null) {
@@ -3091,9 +3064,6 @@
 
     public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode,
             Configuration newConfig) {
-        if (mAdded == null) {
-            return;
-        }
         for (int i = mAdded.size() - 1; i >= 0; --i) {
             final Fragment f = mAdded.get(i);
             if (f != null) {
@@ -3103,34 +3073,28 @@
     }
 
     public void dispatchConfigurationChanged(Configuration newConfig) {
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    f.performConfigurationChanged(newConfig);
-                }
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                f.performConfigurationChanged(newConfig);
             }
         }
     }
 
     public void dispatchLowMemory() {
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    f.performLowMemory();
-                }
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                f.performLowMemory();
             }
         }
     }
 
     public void dispatchTrimMemory(int level) {
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    f.performTrimMemory(level);
-                }
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                f.performTrimMemory(level);
             }
         }
     }
@@ -3138,21 +3102,19 @@
     public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         boolean show = false;
         ArrayList<Fragment> newMenus = null;
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    if (f.performCreateOptionsMenu(menu, inflater)) {
-                        show = true;
-                        if (newMenus == null) {
-                            newMenus = new ArrayList<Fragment>();
-                        }
-                        newMenus.add(f);
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                if (f.performCreateOptionsMenu(menu, inflater)) {
+                    show = true;
+                    if (newMenus == null) {
+                        newMenus = new ArrayList<Fragment>();
                     }
+                    newMenus.add(f);
                 }
             }
         }
-        
+
         if (mCreatedMenus != null) {
             for (int i=0; i<mCreatedMenus.size(); i++) {
                 Fragment f = mCreatedMenus.get(i);
@@ -3169,13 +3131,11 @@
     
     public boolean dispatchPrepareOptionsMenu(Menu menu) {
         boolean show = false;
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    if (f.performPrepareOptionsMenu(menu)) {
-                        show = true;
-                    }
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                if (f.performPrepareOptionsMenu(menu)) {
+                    show = true;
                 }
             }
         }
@@ -3183,13 +3143,11 @@
     }
     
     public boolean dispatchOptionsItemSelected(MenuItem item) {
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    if (f.performOptionsItemSelected(item)) {
-                        return true;
-                    }
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                if (f.performOptionsItemSelected(item)) {
+                    return true;
                 }
             }
         }
@@ -3197,13 +3155,11 @@
     }
     
     public boolean dispatchContextItemSelected(MenuItem item) {
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    if (f.performContextItemSelected(item)) {
-                        return true;
-                    }
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                if (f.performContextItemSelected(item)) {
+                    return true;
                 }
             }
         }
@@ -3211,12 +3167,10 @@
     }
     
     public void dispatchOptionsMenuClosed(Menu menu) {
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    f.performOptionsMenuClosed(menu);
-                }
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                f.performOptionsMenuClosed(menu);
             }
         }
     }
diff --git a/core/java/android/app/FragmentState.java b/core/java/android/app/FragmentState.java
new file mode 100644
index 0000000..a61da3bb
--- /dev/null
+++ b/core/java/android/app/FragmentState.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+final class FragmentState implements Parcelable {
+    final String mClassName;
+    final int mIndex;
+    final boolean mFromLayout;
+    final int mFragmentId;
+    final int mContainerId;
+    final String mTag;
+    final boolean mRetainInstance;
+    final boolean mDetached;
+    final Bundle mArguments;
+    final boolean mHidden;
+
+    Bundle mSavedFragmentState;
+
+    Fragment mInstance;
+
+    FragmentState(Fragment frag) {
+        mClassName = frag.getClass().getName();
+        mIndex = frag.mIndex;
+        mFromLayout = frag.mFromLayout;
+        mFragmentId = frag.mFragmentId;
+        mContainerId = frag.mContainerId;
+        mTag = frag.mTag;
+        mRetainInstance = frag.mRetainInstance;
+        mDetached = frag.mDetached;
+        mArguments = frag.mArguments;
+        mHidden = frag.mHidden;
+    }
+
+    FragmentState(Parcel in) {
+        mClassName = in.readString();
+        mIndex = in.readInt();
+        mFromLayout = in.readInt() != 0;
+        mFragmentId = in.readInt();
+        mContainerId = in.readInt();
+        mTag = in.readString();
+        mRetainInstance = in.readInt() != 0;
+        mDetached = in.readInt() != 0;
+        mArguments = in.readBundle();
+        mHidden = in.readInt() != 0;
+        mSavedFragmentState = in.readBundle();
+    }
+
+    public Fragment instantiate(FragmentHostCallback host, FragmentContainer container,
+            Fragment parent, FragmentManagerNonConfig childNonConfig) {
+        if (mInstance == null) {
+            final Context context = host.getContext();
+            if (mArguments != null) {
+                mArguments.setClassLoader(context.getClassLoader());
+            }
+
+            if (container != null) {
+                mInstance = container.instantiate(context, mClassName, mArguments);
+            } else {
+                mInstance = Fragment.instantiate(context, mClassName, mArguments);
+            }
+
+            if (mSavedFragmentState != null) {
+                mSavedFragmentState.setClassLoader(context.getClassLoader());
+                mInstance.mSavedFragmentState = mSavedFragmentState;
+            }
+            mInstance.setIndex(mIndex, parent);
+            mInstance.mFromLayout = mFromLayout;
+            mInstance.mRestored = true;
+            mInstance.mFragmentId = mFragmentId;
+            mInstance.mContainerId = mContainerId;
+            mInstance.mTag = mTag;
+            mInstance.mRetainInstance = mRetainInstance;
+            mInstance.mDetached = mDetached;
+            mInstance.mHidden = mHidden;
+            mInstance.mFragmentManager = host.mFragmentManager;
+
+            if (FragmentManagerImpl.DEBUG) {
+                Log.v(FragmentManagerImpl.TAG, "Instantiated fragment " + mInstance);
+            }
+        }
+        mInstance.mChildNonConfig = childNonConfig;
+        return mInstance;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mClassName);
+        dest.writeInt(mIndex);
+        dest.writeInt(mFromLayout ? 1 : 0);
+        dest.writeInt(mFragmentId);
+        dest.writeInt(mContainerId);
+        dest.writeString(mTag);
+        dest.writeInt(mRetainInstance ? 1 : 0);
+        dest.writeInt(mDetached ? 1 : 0);
+        dest.writeBundle(mArguments);
+        dest.writeInt(mHidden ? 1 : 0);
+        dest.writeBundle(mSavedFragmentState);
+    }
+
+    public static final Parcelable.Creator<FragmentState> CREATOR =
+            new Parcelable.Creator<FragmentState>() {
+                @Override
+                public FragmentState createFromParcel(Parcel in) {
+                    return new FragmentState(in);
+                }
+
+                @Override
+                public FragmentState[] newArray(int size) {
+                    return new FragmentState[size];
+                }
+            };
+}
\ No newline at end of file
diff --git a/core/java/android/app/IUiAutomationConnection.aidl b/core/java/android/app/IUiAutomationConnection.aidl
index 7640e75..b26117d 100644
--- a/core/java/android/app/IUiAutomationConnection.aidl
+++ b/core/java/android/app/IUiAutomationConnection.aidl
@@ -42,7 +42,8 @@
     WindowContentFrameStats getWindowContentFrameStats(int windowId);
     void clearWindowAnimationFrameStats();
     WindowAnimationFrameStats getWindowAnimationFrameStats();
-    void executeShellCommand(String command, in ParcelFileDescriptor fd);
+    void executeShellCommand(String command, in ParcelFileDescriptor sink,
+            in ParcelFileDescriptor source);
     void grantRuntimePermission(String packageName, String permission, int userId);
     void revokeRuntimePermission(String packageName, String permission, int userId);
 
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 75a5bf7..7ac2223 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -22,6 +22,7 @@
 import android.app.IWallpaperManagerCallback;
 import android.app.WallpaperInfo;
 import android.content.ComponentName;
+import android.app.WallpaperColors;
 
 /** @hide */
 interface IWallpaperManager {
@@ -135,4 +136,23 @@
      * wallpaper content has changed.
      */
     boolean setLockWallpaperCallback(IWallpaperManagerCallback cb);
+
+    /**
+     * Returns the colors used by the lock screen or system wallpaper.
+     *
+     * @param which either {@link WallpaperManager#FLAG_LOCK}
+     * or {@link WallpaperManager#FLAG_SYSTEM}
+     * @return colors of chosen wallpaper
+     */
+    WallpaperColors getWallpaperColors(int which, int userId);
+
+    /**
+     * Register a callback to receive color updates
+     */
+    void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId);
+
+    /**
+     * Unregister a callback that was receiving color updates
+     */
+    void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId);
 }
diff --git a/core/java/android/app/IWallpaperManagerCallback.aidl b/core/java/android/app/IWallpaperManagerCallback.aidl
index 991b2bc..ea0ceab 100644
--- a/core/java/android/app/IWallpaperManagerCallback.aidl
+++ b/core/java/android/app/IWallpaperManagerCallback.aidl
@@ -16,6 +16,8 @@
 
 package android.app;
 
+import android.app.WallpaperColors;
+
 /**
  * Callback interface used by IWallpaperManager to send asynchronous 
  * notifications back to its clients.  Note that this is a
@@ -28,4 +30,10 @@
      * Called when the wallpaper has changed
      */
     void onWallpaperChanged();
+
+    /**
+     * Called when wallpaper colors change
+     */
+    void onWallpaperColorsChanged(in WallpaperColors colors, int which, int userId);
+
 }
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index dbea349..467fc95 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -816,7 +816,7 @@
      * returned.  If the timeout expires, a null object is returned. 
      *
      * @param monitor The ActivityMonitor to wait for.
-     * @param timeOut The timeout value in secs.
+     * @param timeOut The timeout value in milliseconds.
      *
      * @return The Activity object that matched the monitor.
      */
diff --git a/core/java/android/app/IntentService.java b/core/java/android/app/IntentService.java
index e4a22c4..95ec24c 100644
--- a/core/java/android/app/IntentService.java
+++ b/core/java/android/app/IntentService.java
@@ -43,6 +43,13 @@
  * long as necessary (and will not block the application's main loop), but
  * only one request will be processed at a time.
  *
+ * <p class="note"><b>Note:</b> IntentService is subject to all the
+ * <a href="/preview/features/background.html">background execution limits</a>
+ * imposed with Android 8.0 (API level 26). In most cases, you are better off
+ * using {@link android.support.v4.app.JobIntentService}, which uses jobs
+ * instead of services when running on Android 8.0 or higher.
+ * </p>
+ *
  * <div class="special reference">
  * <h3>Developer Guides</h3>
  * <p>For a detailed discussion about how to create services, read the
@@ -50,6 +57,7 @@
  * guide.</p>
  * </div>
  *
+ * @see android.support.v4.app.JobIntentService
  * @see android.os.AsyncTask
  */
 public abstract class IntentService extends Service {
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 2a29616..16b21f1 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -29,11 +29,12 @@
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceManager.ServiceNotFoundException;
 import android.os.UserHandle;
+import android.provider.Settings;
+import android.service.persistentdata.IPersistentDataBlockService;
 import android.util.Log;
 import android.view.IOnKeyguardExitResult;
 import android.view.IWindowManager;
@@ -41,6 +42,7 @@
 import android.view.WindowManagerGlobal;
 
 import com.android.internal.policy.IKeyguardDismissCallback;
+import com.android.internal.widget.LockPatternUtils;
 
 import java.util.List;
 
@@ -74,6 +76,13 @@
             "android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER";
 
     /**
+     * Intent used to prompt user for factory reset credentials.
+     * @hide
+     */
+    public static final String ACTION_CONFIRM_FRP_CREDENTIAL =
+            "android.app.action.CONFIRM_FRP_CREDENTIAL";
+
+    /**
      * A CharSequence dialog title to show to the user when used with a
      * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
      * @hide
@@ -88,6 +97,23 @@
     public static final String EXTRA_DESCRIPTION = "android.app.extra.DESCRIPTION";
 
     /**
+     * A CharSequence description to show to the user on the alternate button when used with
+     * {@link #ACTION_CONFIRM_FRP_CREDENTIAL}.
+     * @hide
+     */
+    public static final String EXTRA_ALTERNATE_BUTTON_LABEL =
+            "android.app.extra.ALTERNATE_BUTTON_LABEL";
+
+    /**
+     * Result code returned by the activity started by
+     * {@link #createConfirmFactoryResetCredentialIntent} indicating that the user clicked the
+     * alternate button.
+     *
+     * @hide
+     */
+    public static final int RESULT_ALTERNATE = 1;
+
+    /**
      * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
      * for the current user of the device. The caller is expected to launch this activity using
      * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
@@ -130,6 +156,63 @@
         return intent;
     }
 
+    /**
+     * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
+     * for the previous owner of the device. The caller is expected to launch this activity using
+     * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
+     * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
+     *
+     * @param alternateButtonLabel if not empty, a button is provided with the given label. Upon
+     *                             clicking this button, the activity returns
+     *                             {@link #RESULT_ALTERNATE}
+     *
+     * @return  the intent for launching the activity or null if the credential of the previous
+     * owner can not be verified (e.g. because there was none, or the device does not support
+     * verifying credentials after a factory reset, or device setup has already been completed).
+     *
+     * @hide
+     */
+    public Intent createConfirmFactoryResetCredentialIntent(
+            CharSequence title, CharSequence description, CharSequence alternateButtonLabel) {
+        if (!LockPatternUtils.frpCredentialEnabled()) {
+            Log.w(TAG, "Factory reset credentials not supported.");
+            return null;
+        }
+
+        // Cannot verify credential if the device is provisioned
+        if (Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
+            Log.e(TAG, "Factory reset credential cannot be verified after provisioning.");
+            return null;
+        }
+
+        // Make sure we have a credential
+        try {
+            IPersistentDataBlockService pdb = IPersistentDataBlockService.Stub.asInterface(
+                    ServiceManager.getService(Context.PERSISTENT_DATA_BLOCK_SERVICE));
+            if (pdb == null) {
+                Log.e(TAG, "No persistent data block service");
+                return null;
+            }
+            if (!pdb.hasFrpCredentialHandle()) {
+                Log.i(TAG, "The persistent data block does not have a factory reset credential.");
+                return null;
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+
+        Intent intent = new Intent(ACTION_CONFIRM_FRP_CREDENTIAL);
+        intent.putExtra(EXTRA_TITLE, title);
+        intent.putExtra(EXTRA_DESCRIPTION, description);
+        intent.putExtra(EXTRA_ALTERNATE_BUTTON_LABEL, alternateButtonLabel);
+
+        // explicitly set the package for security
+        intent.setPackage(getSettingsPackageForIntent(intent));
+
+        return intent;
+    }
+
     private String getSettingsPackageForIntent(Intent intent) {
         List<ResolveInfo> resolveInfos = mContext.getPackageManager()
                 .queryIntentActivities(intent, PackageManager.MATCH_SYSTEM_ONLY);
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 393909b..79e5407 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -448,10 +448,13 @@
             }
         }
 
+        // Prepend the shared libraries, maintaining their original order where possible.
         if (sharedLibraries != null) {
+            int index = 0;
             for (String lib : sharedLibraries) {
                 if (!outZipPaths.contains(lib)) {
-                    outZipPaths.add(0, lib);
+                    outZipPaths.add(index, lib);
+                    index++;
                     appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
                 }
             }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 4dd71b4..531afa4 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -33,6 +33,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ShortcutInfo;
 import android.content.res.ColorStateList;
+import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -559,6 +560,11 @@
     @SystemApi
     public static final int FLAG_AUTOGROUP_SUMMARY  = 0x00000400;
 
+    /**
+     * @hide
+     */
+    public static final int FLAG_CAN_COLORIZE = 0x00000800;
+
     public int flags;
 
     /** @hide */
@@ -1085,6 +1091,11 @@
     public static final String EXTRA_CONTAINS_CUSTOM_VIEW = "android.contains.customView";
 
     /**
+     * @hide
+     */
+    public static final String EXTRA_REDUCED_IMAGES = "android.reduced.images";
+
+    /**
      * {@link #extras} key: the audio contents of this notification.
      *
      * This is for use when rendering the notification on an audio-focused interface;
@@ -2536,6 +2547,22 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    public boolean hasCompletedProgress() {
+        // not a progress notification; can't be complete
+        if (!extras.containsKey(EXTRA_PROGRESS)
+                || !extras.containsKey(EXTRA_PROGRESS_MAX)) {
+            return false;
+        }
+        // many apps use max 0 for 'indeterminate'; not complete
+        if (extras.getInt(EXTRA_PROGRESS_MAX) == 0) {
+            return false;
+        }
+        return extras.getInt(EXTRA_PROGRESS) == extras.getInt(EXTRA_PROGRESS_MAX);
+    }
+
     /** @removed */
     @Deprecated
     public String getChannel() {
@@ -2745,6 +2772,11 @@
         private int mBackgroundColor = COLOR_INVALID;
         private int mForegroundColor = COLOR_INVALID;
         private int mBackgroundColorHint = COLOR_INVALID;
+        /**
+         * A temporary location where actions are stored. If != null the view originally has action
+         * but doesn't have any for this inflation.
+         */
+        private ArrayList<Action> mOriginalActions;
         private boolean mRebuildStyledRemoteViews;
 
         /**
@@ -4057,7 +4089,53 @@
                 contentView.setViewLayoutMarginEndDimen(R.id.line1, endMargin);
                 contentView.setViewLayoutMarginEndDimen(R.id.text, endMargin);
                 contentView.setViewLayoutMarginEndDimen(R.id.progress, endMargin);
+                // Bind the reply action
+                Action action = findReplyAction();
+                contentView.setViewVisibility(R.id.reply_icon_action, action != null
+                        ? View.VISIBLE
+                        : View.GONE);
+
+                if (action != null) {
+                    int contrastColor = resolveContrastColor();
+                    contentView.setDrawableParameters(R.id.reply_icon_action,
+                            true /* targetBackground */,
+                            -1,
+                            contrastColor,
+                            PorterDuff.Mode.SRC_ATOP, -1);
+                    int iconColor = NotificationColorUtil.isColorLight(contrastColor)
+                            ? Color.BLACK : Color.WHITE;
+                    contentView.setDrawableParameters(R.id.reply_icon_action,
+                            false /* targetBackground */,
+                            -1,
+                            iconColor,
+                            PorterDuff.Mode.SRC_ATOP, -1);
+                    contentView.setOnClickPendingIntent(R.id.right_icon,
+                            action.actionIntent);
+                    contentView.setOnClickPendingIntent(R.id.reply_icon_action,
+                            action.actionIntent);
+                    contentView.setRemoteInputs(R.id.right_icon, action.mRemoteInputs);
+                    contentView.setRemoteInputs(R.id.reply_icon_action, action.mRemoteInputs);
+
+                }
             }
+            contentView.setViewVisibility(R.id.right_icon_container, mN.mLargeIcon != null
+                    ? View.VISIBLE
+                    : View.GONE);
+        }
+
+        private Action findReplyAction() {
+            ArrayList<Action> actions = mActions;
+            if (mOriginalActions != null) {
+                actions = mOriginalActions;
+            }
+            int numActions = actions.size();
+            for (int i = 0; i < numActions; i++) {
+                Action action = actions.get(i);
+                if (hasValidRemoteInput(action)) {
+                    return action;
+                }
+            }
+            return null;
         }
 
         private void bindNotificationHeader(RemoteViews contentView, boolean ambient) {
@@ -4473,11 +4551,16 @@
                     savedBundle.getBoolean(EXTRA_SHOW_CHRONOMETER));
             publicExtras.putBoolean(EXTRA_CHRONOMETER_COUNT_DOWN,
                     savedBundle.getBoolean(EXTRA_CHRONOMETER_COUNT_DOWN));
-            publicExtras.putCharSequence(EXTRA_TITLE,
-                    mContext.getString(com.android.internal.R.string.notification_hidden_text));
             mN.extras = publicExtras;
-            final RemoteViews view = ambient ? makeAmbientNotification()
-                    : applyStandardTemplate(getBaseLayoutResource());
+            RemoteViews view;
+            if (ambient) {
+                publicExtras.putCharSequence(EXTRA_TITLE,
+                        mContext.getString(com.android.internal.R.string.notification_hidden_text));
+                view = makeAmbientNotification();
+            } else{
+                view = makeNotificationHeader(false /* ambient */);
+                view.setBoolean(R.id.notification_header, "setExpandOnlyOnButton", true);
+            }
             mN.extras = savedBundle;
             mN.mLargeIcon = largeIcon;
             mN.largeIcon = largeIconLegacy;
@@ -4871,9 +4954,13 @@
             buildUnstyled();
 
             if (mStyle != null) {
+                mStyle.reduceImageSizes(mContext);
+                mStyle.purgeResources();
                 mStyle.buildStyled(mN);
             }
 
+            mN.reduceImageSizes(mContext);
+
             if (mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N
                     && (useExistingRemoteView())) {
                 if (mN.contentView == null) {
@@ -5063,6 +5150,52 @@
     }
 
     /**
+     * Reduces the image sizes to conform to a maximum allowed size. This also processes all custom
+     * remote views.
+     *
+     * @hide
+     */
+    void reduceImageSizes(Context context) {
+        if (extras.getBoolean(EXTRA_REDUCED_IMAGES)) {
+            return;
+        }
+        if (mLargeIcon != null || largeIcon != null) {
+            Resources resources = context.getResources();
+            Class<? extends Style> style = getNotificationStyle();
+            int maxWidth = resources.getDimensionPixelSize(R.dimen.notification_right_icon_size);
+            int maxHeight = maxWidth;
+            if (MediaStyle.class.equals(style)
+                    || DecoratedMediaCustomViewStyle.class.equals(style)) {
+                maxHeight = resources.getDimensionPixelSize(
+                        R.dimen.notification_media_image_max_height);
+                maxWidth = resources.getDimensionPixelSize(
+                        R.dimen.notification_media_image_max_width);
+            }
+            if (mLargeIcon != null) {
+                mLargeIcon.scaleDownIfNecessary(maxWidth, maxHeight);
+            }
+            if (largeIcon != null) {
+                largeIcon = Icon.scaleDownIfNecessary(largeIcon, maxWidth, maxHeight);
+            }
+        }
+        reduceImageSizesForRemoteView(contentView, context);
+        reduceImageSizesForRemoteView(headsUpContentView, context);
+        reduceImageSizesForRemoteView(bigContentView, context);
+        extras.putBoolean(EXTRA_REDUCED_IMAGES, true);
+    }
+
+    private void reduceImageSizesForRemoteView(RemoteViews remoteView, Context context) {
+        if (remoteView != null) {
+            Resources resources = context.getResources();
+            int maxWidth = resources.getDimensionPixelSize(
+                    R.dimen.notification_custom_view_max_image_width);
+            int maxHeight = resources.getDimensionPixelSize(
+                    R.dimen.notification_custom_view_max_image_height);
+            remoteView.reduceImageSizes(maxWidth, maxHeight);
+        }
+    }
+
+    /**
      * @return whether this notification is a foreground service notification
      */
     private boolean isForegroundService() {
@@ -5099,7 +5232,16 @@
         if (isColorizedMedia()) {
             return true;
         }
-        return extras.getBoolean(EXTRA_COLORIZED) && isForegroundService();
+        return extras.getBoolean(EXTRA_COLORIZED)
+                && (hasColorizedPermission() || isForegroundService());
+    }
+
+    /**
+     * Returns whether an app can colorize due to the android.permission.USE_COLORIZED_NOTIFICATIONS
+     * permission. The permission is checked when a notification is enqueued.
+     */
+    private boolean hasColorizedPermission() {
+        return (flags & Notification.FLAG_CAN_COLORIZE) != 0;
     }
 
     /**
@@ -5354,6 +5496,14 @@
         public boolean displayCustomViewInline() {
             return false;
         }
+
+        /**
+         * Reduces the image sizes contained in this style.
+         *
+         * @hide
+         */
+        public void reduceImageSizes(Context context) {
+        }
     }
 
     /**
@@ -5452,6 +5602,27 @@
         /**
          * @hide
          */
+        @Override
+        public void reduceImageSizes(Context context) {
+            super.reduceImageSizes(context);
+            Resources resources = context.getResources();
+            if (mPicture != null) {
+                int maxPictureWidth = resources.getDimensionPixelSize(
+                        R.dimen.notification_big_picture_max_height);
+                int maxPictureHeight = resources.getDimensionPixelSize(
+                        R.dimen.notification_big_picture_max_width);
+                mPicture = Icon.scaleDownIfNecessary(mPicture, maxPictureWidth, maxPictureHeight);
+            }
+            if (mBigLargeIcon != null) {
+                int rightIconSize = resources.getDimensionPixelSize(
+                        R.dimen.notification_right_icon_size);
+                mBigLargeIcon.scaleDownIfNecessary(rightIconSize, rightIconSize);
+            }
+        }
+
+        /**
+         * @hide
+         */
         public RemoteViews makeBigContentView() {
             // Replace mN.mLargeIcon with mBigLargeIcon if mBigLargeIconSet
             // This covers the following cases:
@@ -5607,10 +5778,11 @@
         @Override
         public RemoteViews makeContentView(boolean increasedHeight) {
             if (increasedHeight) {
-                ArrayList<Action> actions = mBuilder.mActions;
+                mBuilder.mOriginalActions = mBuilder.mActions;
                 mBuilder.mActions = new ArrayList<>();
                 RemoteViews remoteViews = makeBigContentView();
-                mBuilder.mActions = actions;
+                mBuilder.mActions = mBuilder.mOriginalActions;
+                mBuilder.mOriginalActions = null;
                 return remoteViews;
             }
             return super.makeContentView(increasedHeight);
@@ -5894,10 +6066,11 @@
                 return mBuilder.applyStandardTemplate(mBuilder.getBaseLayoutResource(),
                         mBuilder.mParams.reset().hasProgress(false).title(title).text(text));
             } else {
-                ArrayList<Action> actions = mBuilder.mActions;
+                mBuilder.mOriginalActions = mBuilder.mActions;
                 mBuilder.mActions = new ArrayList<>();
                 RemoteViews remoteViews = makeBigContentView();
-                mBuilder.mActions = actions;
+                mBuilder.mActions = mBuilder.mOriginalActions;
+                mBuilder.mOriginalActions = null;
                 return remoteViews;
             }
         }
@@ -6727,8 +6900,8 @@
                 // Need to clone customContent before adding, because otherwise it can no longer be
                 // parceled independently of remoteViews.
                 customContent = customContent.clone();
-                remoteViews.removeAllViews(R.id.notification_main_column);
-                remoteViews.addView(R.id.notification_main_column, customContent);
+                remoteViews.removeAllViewsExceptId(R.id.notification_main_column, R.id.progress);
+                remoteViews.addView(R.id.notification_main_column, customContent, 0 /* index */);
             }
             // also update the end margin if there is an image
             int endMargin = R.dimen.notification_content_margin_end;
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 143d147..d6e3691 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -15,11 +15,6 @@
  */
 package android.app;
 
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlSerializer;
-
 import android.annotation.SystemApi;
 import android.app.NotificationManager.Importance;
 import android.content.Intent;
@@ -31,6 +26,11 @@
 import android.service.notification.NotificationListenerService;
 import android.text.TextUtils;
 
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
+
 import java.io.IOException;
 import java.util.Arrays;
 
@@ -743,7 +743,7 @@
 
     private static String longArrayToString(long[] values) {
         StringBuffer sb = new StringBuffer();
-        if (values != null) {
+        if (values != null && values.length > 0) {
             for (int i = 0; i < values.length - 1; i++) {
                 sb.append(values[i]).append(DELIMITER);
             }
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 235b8d4..9d7e4a2 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -18,14 +18,12 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
 import android.app.Notification.Builder;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
 import android.content.pm.ParceledListSlice;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
@@ -33,7 +31,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
@@ -41,7 +38,6 @@
 import android.os.StrictMode;
 import android.os.UserHandle;
 import android.provider.Settings.Global;
-import android.service.notification.NotificationListenerService.Ranking;
 import android.service.notification.StatusBarNotification;
 import android.service.notification.ZenModeConfig;
 import android.util.ArraySet;
@@ -312,6 +308,7 @@
             }
         }
         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
+        notification.reduceImageSizes(mContext);
         final Notification copy = Builder.maybeCloneStrippedForDelivery(notification);
         try {
             service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index f83f39f..b7d3f57 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -102,6 +102,7 @@
                     FLAG_NO_CREATE,
                     FLAG_CANCEL_CURRENT,
                     FLAG_UPDATE_CURRENT,
+                    FLAG_IMMUTABLE,
 
                     Intent.FILL_IN_ACTION,
                     Intent.FILL_IN_DATA,
diff --git a/core/java/android/app/ProgressDialog.java b/core/java/android/app/ProgressDialog.java
index 8ec9622..8a083eb 100644
--- a/core/java/android/app/ProgressDialog.java
+++ b/core/java/android/app/ProgressDialog.java
@@ -42,8 +42,12 @@
  *
  * <p>The progress range is 0 to {@link #getMax() max}.</p>
  *
- * @deprecated Use a progress indicator such as ProgressBar inline inside of
- * an activity rather than using this modal dialog.
+ * @deprecated <code>ProgressDialog</code> is a modal dialog, which prevents the
+ * user from interacting with the app. Instead of using this class, you should
+ * use a progress indicator like {@link android.widget.ProgressBar}, which can
+ * be embedded in your app's UI. Alternatively, you can use a
+ * <a href="/guide/topics/ui/notifiers/notifications.html">notification</a>
+ * to inform the user of the task's progress.
  */
 @Deprecated
 public class ProgressDialog extends AlertDialog {
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 6f326de..fb11272 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -44,8 +44,6 @@
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map;
 import java.util.Objects;
 import java.util.WeakHashMap;
 import java.util.function.Predicate;
@@ -417,7 +415,12 @@
             if (activityResources == null) {
                 return overrideConfig == null;
             } else {
-                return Objects.equals(activityResources.overrideConfig, overrideConfig);
+                // The two configurations must either be equal or publicly equivalent to be
+                // considered the same.
+                return Objects.equals(activityResources.overrideConfig, overrideConfig)
+                        || (overrideConfig != null && activityResources.overrideConfig != null
+                                && 0 == overrideConfig.diffPublicOnly(
+                                        activityResources.overrideConfig));
             }
         }
     }
@@ -961,7 +964,7 @@
 
     // TODO(adamlesinski): Make this accept more than just overlay directories.
     final void applyNewResourceDirsLocked(@NonNull final String baseCodePath,
-            @NonNull final String[] newResourceDirs) {
+            @Nullable final String[] newResourceDirs) {
         try {
             Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
                     "ResourcesManager#applyNewResourceDirsLocked");
@@ -984,8 +987,6 @@
                 }
             }
 
-            invalidatePath("/");
-
             redirectResourcesToNewImplLocked(updatedResourceKeys);
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
diff --git a/core/java/android/app/RetailDemoModeServiceInternal.java b/core/java/android/app/RetailDemoModeServiceInternal.java
deleted file mode 100644
index 7ca214a..0000000
--- a/core/java/android/app/RetailDemoModeServiceInternal.java
+++ /dev/null
@@ -1,29 +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.app;
-
-/**
- * Retail Demo Mode Service interface to be used locally inside system server
- *
- * @hide Only for use inside system server
- */
-public interface RetailDemoModeServiceInternal {
-    /**
-     * Used to notify RetailDemoModeService of any user activity.
-     */
-    public void onUserActivity();
-}
\ No newline at end of file
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index 063ad24..aab7d77 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -23,16 +23,19 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.StructStat;
+import android.system.StructTimespec;
 import android.util.Log;
 
-import com.google.android.collect.Maps;
-
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.ExponentiallyBucketedHistogram;
 import com.android.internal.util.XmlUtils;
 
 import dalvik.system.BlockGuard;
 
+import libcore.io.IoUtils;
+
+import com.google.android.collect.Maps;
+
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.BufferedInputStream;
@@ -50,8 +53,6 @@
 import java.util.WeakHashMap;
 import java.util.concurrent.CountDownLatch;
 
-import libcore.io.IoUtils;
-
 final class SharedPreferencesImpl implements SharedPreferences {
     private static final String TAG = "SharedPreferencesImpl";
     private static final boolean DEBUG = false;
@@ -80,7 +81,7 @@
     private boolean mLoaded = false;
 
     @GuardedBy("mLock")
-    private long mStatTimestamp;
+    private StructTimespec mStatTimestamp;
 
     @GuardedBy("mLock")
     private long mStatSize;
@@ -162,7 +163,7 @@
             mLoaded = true;
             if (map != null) {
                 mMap = map;
-                mStatTimestamp = stat.st_mtime;
+                mStatTimestamp = stat.st_mtim;
                 mStatSize = stat.st_size;
             } else {
                 mMap = new HashMap<>();
@@ -209,7 +210,7 @@
         }
 
         synchronized (mLock) {
-            return mStatTimestamp != stat.st_mtime || mStatSize != stat.st_size;
+            return !stat.st_mtim.equals(mStatTimestamp) || mStatSize != stat.st_size;
         }
     }
 
@@ -744,7 +745,7 @@
             try {
                 final StructStat stat = Os.stat(mFile.getPath());
                 synchronized (mLock) {
-                    mStatTimestamp = stat.st_mtime;
+                    mStatTimestamp = stat.st_mtim;
                     mStatSize = stat.st_size;
                 }
             } catch (ErrnoException e) {
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index fb8bd39..4a09214 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -94,6 +94,7 @@
 
     public static final int CAMERA_LAUNCH_SOURCE_WIGGLE = 0;
     public static final int CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = 1;
+    public static final int CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER = 2;
 
     private Context mContext;
     private IStatusBarService mService;
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index a13c69d7..9a019b8 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -127,6 +127,7 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.euicc.EuiccManager;
 import android.util.Log;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
@@ -493,6 +494,13 @@
                 return new TelecomManager(ctx.getOuterContext());
             }});
 
+        registerService(Context.EUICC_SERVICE, EuiccManager.class,
+                new CachedServiceFetcher<EuiccManager>() {
+            @Override
+            public EuiccManager createService(ContextImpl ctx) {
+                return new EuiccManager(ctx.getOuterContext());
+            }});
+
         registerService(Context.UI_MODE_SERVICE, UiModeManager.class,
                 new CachedServiceFetcher<UiModeManager>() {
             @Override
@@ -794,7 +802,7 @@
         registerService(Context.RADIO_SERVICE, RadioManager.class,
                 new CachedServiceFetcher<RadioManager>() {
             @Override
-            public RadioManager createService(ContextImpl ctx) {
+            public RadioManager createService(ContextImpl ctx) throws ServiceNotFoundException {
                 return new RadioManager(ctx);
             }});
 
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index 0f006b6..8686944 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -152,6 +152,9 @@
             public void onClick(View view) {
                 if (mTimePicker.validateInput()) {
                     TimePickerDialog.this.onClick(TimePickerDialog.this, BUTTON_POSITIVE);
+                    // Clearing focus forces the dialog to commit any pending
+                    // changes, e.g. typed text in a NumberPicker.
+                    mTimePicker.clearFocus();
                     dismiss();
                 }
             }
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 18e7599..c99de5d 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -975,11 +975,11 @@
     }
 
     /**
-     * Executes a shell command. This method returs a file descriptor that points
+     * Executes a shell command. This method returns a file descriptor that points
      * to the standard output stream. The command execution is similar to running
      * "adb shell <command>" from a host connected to the device.
      * <p>
-     * <strong>Note:</strong> It is your responsibility to close the retunred file
+     * <strong>Note:</strong> It is your responsibility to close the returned file
      * descriptor once you are done reading.
      * </p>
      *
@@ -1000,7 +1000,7 @@
             sink = pipe[1];
 
             // Calling out without a lock held.
-            mUiAutomationConnection.executeShellCommand(command, sink);
+            mUiAutomationConnection.executeShellCommand(command, sink, null);
         } catch (IOException ioe) {
             Log.e(LOG_TAG, "Error executing shell command!", ioe);
         } catch (RemoteException re) {
@@ -1012,6 +1012,59 @@
         return source;
     }
 
+    /**
+     * Executes a shell command. This method returns two file descriptors,
+     * one that points to the standard output stream (element at index 0), and one that points
+     * to the standard input stream (element at index 1). The command execution is similar
+     * to running "adb shell <command>" from a host connected to the device.
+     * <p>
+     * <strong>Note:</strong> It is your responsibility to close the returned file
+     * descriptors once you are done reading/writing.
+     * </p>
+     *
+     * @param command The command to execute.
+     * @return File descriptors (out, in) to the standard output/input streams.
+     *
+     * @hide
+     */
+    @TestApi
+    public ParcelFileDescriptor[] executeShellCommandRw(String command) {
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+        }
+
+        ParcelFileDescriptor source_read = null;
+        ParcelFileDescriptor sink_read = null;
+
+        ParcelFileDescriptor source_write = null;
+        ParcelFileDescriptor sink_write = null;
+
+        try {
+            ParcelFileDescriptor[] pipe_read = ParcelFileDescriptor.createPipe();
+            source_read = pipe_read[0];
+            sink_read = pipe_read[1];
+
+            ParcelFileDescriptor[] pipe_write = ParcelFileDescriptor.createPipe();
+            source_write = pipe_write[0];
+            sink_write = pipe_write[1];
+
+            // Calling out without a lock held.
+            mUiAutomationConnection.executeShellCommand(command, sink_read, source_write);
+        } catch (IOException ioe) {
+            Log.e(LOG_TAG, "Error executing shell command!", ioe);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error executing shell command!", re);
+        } finally {
+            IoUtils.closeQuietly(sink_read);
+            IoUtils.closeQuietly(source_write);
+        }
+
+        ParcelFileDescriptor[] result = new ParcelFileDescriptor[2];
+        result[0] = source_read;
+        result[1] = sink_write;
+        return result;
+    }
+
     private static float getDegreesForRotation(int value) {
         switch (value) {
             case Surface.ROTATION_90: {
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 9960df6..5e414b8 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -36,9 +36,11 @@
 import android.view.WindowContentFrameStats;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.IAccessibilityManager;
+import android.util.Log;
 
 import libcore.io.IoUtils;
 
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -55,6 +57,8 @@
  */
 public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
 
+    private static final String TAG = "UiAutomationConnection";
+
     private static final int INITIAL_FROZEN_ROTATION_UNSPECIFIED = -1;
 
     private final IWindowManager mWindowManager = IWindowManager.Stub.asInterface(
@@ -267,47 +271,95 @@
         }
     }
 
+    public class Repeater implements Runnable {
+        // Continuously read readFrom and write back to writeTo until EOF is encountered
+        private final InputStream readFrom;
+        private final OutputStream writeTo;
+        public Repeater (InputStream readFrom, OutputStream writeTo) {
+            this.readFrom = readFrom;
+            this.writeTo = writeTo;
+        }
+        @Override
+        public void run() {
+            try {
+                final byte[] buffer = new byte[8192];
+                int readByteCount;
+                while (true) {
+                    readByteCount = readFrom.read(buffer);
+                    if (readByteCount < 0) {
+                        break;
+                    }
+                    writeTo.write(buffer, 0, readByteCount);
+                    writeTo.flush();
+                }
+            } catch (IOException ioe) {
+                throw new RuntimeException("Error while reading/writing ", ioe);
+            } finally {
+                IoUtils.closeQuietly(readFrom);
+                IoUtils.closeQuietly(writeTo);
+            }
+        }
+    }
+
     @Override
-    public void executeShellCommand(final String command, final ParcelFileDescriptor sink)
-            throws RemoteException {
+    public void executeShellCommand(final String command, final ParcelFileDescriptor sink,
+            final ParcelFileDescriptor source) throws RemoteException {
         synchronized (mLock) {
             throwIfCalledByNotTrustedUidLocked();
             throwIfShutdownLocked();
             throwIfNotConnectedLocked();
         }
+        final java.lang.Process process;
 
-        Thread streamReader = new Thread() {
+        try {
+            process = Runtime.getRuntime().exec(command);
+        } catch (IOException exc) {
+            throw new RuntimeException("Error running shell command '" + command + "'", exc);
+        }
+
+        // Read from process and write to pipe
+        final Thread readFromProcess;
+        if (sink != null) {
+            InputStream sink_in = process.getInputStream();;
+            OutputStream sink_out = new FileOutputStream(sink.getFileDescriptor());
+
+            readFromProcess = new Thread(new Repeater(sink_in, sink_out));
+            readFromProcess.start();
+        } else {
+            readFromProcess = null;
+        }
+
+        // Read from pipe and write to process
+        final Thread writeToProcess;
+        if (source != null) {
+            OutputStream source_out = process.getOutputStream();
+            InputStream source_in = new FileInputStream(source.getFileDescriptor());
+
+            writeToProcess = new Thread(new Repeater(source_in, source_out));
+            writeToProcess.start();
+        } else {
+            writeToProcess = null;
+        }
+
+        Thread cleanup = new Thread(new Runnable() {
+            @Override
             public void run() {
-                InputStream in = null;
-                OutputStream out = null;
-                java.lang.Process process = null;
-
                 try {
-                    process = Runtime.getRuntime().exec(command);
-
-                    in = process.getInputStream();
-                    out = new FileOutputStream(sink.getFileDescriptor());
-
-                    final byte[] buffer = new byte[8192];
-                    while (true) {
-                        final int readByteCount = in.read(buffer);
-                        if (readByteCount < 0) {
-                            break;
-                        }
-                        out.write(buffer, 0, readByteCount);
+                    if (writeToProcess != null) {
+                        writeToProcess.join();
                     }
-                } catch (IOException ioe) {
-                    throw new RuntimeException("Error running shell command", ioe);
-                } finally {
-                    if (process != null) {
-                        process.destroy();
+                    if (readFromProcess != null) {
+                        readFromProcess.join();
                     }
-                    IoUtils.closeQuietly(out);
-                    IoUtils.closeQuietly(sink);
+                } catch (InterruptedException exc) {
+                    Log.e(TAG, "At least one of the threads was interrupted");
                 }
-            };
-        };
-        streamReader.start();
+                IoUtils.closeQuietly(sink);
+                IoUtils.closeQuietly(source);
+                process.destroy();
+                }
+            });
+        cleanup.start();
     }
 
     @Override
diff --git a/core/java/android/app/Vr2dDisplayProperties.java b/core/java/android/app/Vr2dDisplayProperties.java
index a608bb0..0eb2af3 100644
--- a/core/java/android/app/Vr2dDisplayProperties.java
+++ b/core/java/android/app/Vr2dDisplayProperties.java
@@ -16,7 +16,6 @@
 
 package android.app;
 
-import android.content.ComponentName;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -27,19 +26,31 @@
  *
  * @hide
  */
-public class Vr2dDisplayProperties implements Parcelable {
+public final class Vr2dDisplayProperties implements Parcelable {
 
-   /**
-    * The actual width, height and dpi.
-    */
+    public static final int FLAG_VIRTUAL_DISPLAY_ENABLED = 1;
+
+    /**
+     * The actual width, height and dpi.
+     */
     private final int mWidth;
     private final int mHeight;
     private final int mDpi;
 
+    // Flags describing the virtual display behavior.
+    private final int mAddedFlags;
+    private final int mRemovedFlags;
+
     public Vr2dDisplayProperties(int width, int height, int dpi) {
+        this(width, height, dpi, 0, 0);
+    }
+
+    private Vr2dDisplayProperties(int width, int height, int dpi, int flags, int removedFlags) {
         mWidth = width;
         mHeight = height;
         mDpi = dpi;
+        mAddedFlags = flags;
+        mRemovedFlags = removedFlags;
     }
 
     @Override
@@ -52,11 +63,13 @@
 
     @Override
     public String toString() {
-        return "Vr2dDisplayProperties{" +
-                "mWidth=" + mWidth +
-                ", mHeight=" + mHeight +
-                ", mDpi=" + mDpi +
-                "}";
+        return "Vr2dDisplayProperties{"
+                + "mWidth=" + mWidth
+                + ", mHeight=" + mHeight
+                + ", mDpi=" + mDpi
+                + ", flags=" + toReadableFlags(mAddedFlags)
+                + ", removed_flags=" + toReadableFlags(mRemovedFlags)
+                + "}";
     }
 
     @Override
@@ -66,6 +79,8 @@
 
         Vr2dDisplayProperties that = (Vr2dDisplayProperties) o;
 
+        if (getFlags() != that.getFlags()) return false;
+        if (getRemovedFlags() != that.getRemovedFlags()) return false;
         if (getWidth() != that.getWidth()) return false;
         if (getHeight() != that.getHeight()) return false;
         return getDpi() == that.getDpi();
@@ -81,6 +96,8 @@
         dest.writeInt(mWidth);
         dest.writeInt(mHeight);
         dest.writeInt(mDpi);
+        dest.writeInt(mAddedFlags);
+        dest.writeInt(mRemovedFlags);
     }
 
     public static final Parcelable.Creator<Vr2dDisplayProperties> CREATOR
@@ -100,13 +117,12 @@
         mWidth = source.readInt();
         mHeight = source.readInt();
         mDpi = source.readInt();
+        mAddedFlags = source.readInt();
+        mRemovedFlags = source.readInt();
     }
 
     public void dump(PrintWriter pw, String prefix) {
-        pw.println(prefix + "Vr2dDisplayProperties:");
-        pw.println(prefix + "  width=" + mWidth);
-        pw.println(prefix + "  height=" + mHeight);
-        pw.println(prefix + "  dpi=" + mDpi);
+        pw.println(prefix + toString());
     }
 
     public int getWidth() {
@@ -120,4 +136,83 @@
     public int getDpi() {
         return mDpi;
     }
+
+    public int getFlags() {
+        return mAddedFlags;
+    }
+
+    public int getRemovedFlags() {
+        return mRemovedFlags;
+    }
+
+    private static String toReadableFlags(int flags) {
+        String retval = "{";
+        if ((flags & FLAG_VIRTUAL_DISPLAY_ENABLED) == FLAG_VIRTUAL_DISPLAY_ENABLED) {
+            retval += "enabled";
+        }
+        return retval + "}";
+    }
+
+    /**
+     * Convenience class for creating Vr2dDisplayProperties.
+     */
+    public static class Builder {
+        private int mAddedFlags = 0;
+        private int mRemovedFlags = 0;
+
+        // Negative values are translated as an "ignore" to VrManagerService.
+        private int mWidth = -1;
+        private int mHeight = -1;
+        private int mDpi = -1;
+
+        public Builder() {
+        }
+
+        /**
+         * Sets the dimensions to use for the virtual display.
+         */
+        public Builder setDimensions(int width, int height, int dpi) {
+            mWidth = width;
+            mHeight = height;
+            mDpi = dpi;
+            return this;
+        }
+
+        /**
+         * Toggles the virtual display functionality for 2D activities in VR.
+         */
+        public Builder setEnabled(boolean enabled) {
+            if (enabled) {
+                addFlags(FLAG_VIRTUAL_DISPLAY_ENABLED);
+            } else {
+                removeFlags(FLAG_VIRTUAL_DISPLAY_ENABLED);
+            }
+            return this;
+        }
+
+        /**
+         * Adds property flags.
+         */
+        public Builder addFlags(int flags) {
+            mAddedFlags |= flags;
+            mRemovedFlags &= ~flags;
+            return this;
+        }
+
+        /**
+         * Removes property flags.
+         */
+        public Builder removeFlags(int flags) {
+            mRemovedFlags |= flags;
+            mAddedFlags &= ~flags;
+            return this;
+        }
+
+        /**
+         * Builds the Vr2dDisplayProperty instance.
+         */
+        public Vr2dDisplayProperties build() {
+            return new Vr2dDisplayProperties(mWidth, mHeight, mDpi, mAddedFlags, mRemovedFlags);
+        }
+    }
 }
diff --git a/core/java/android/app/WallpaperColors.aidl b/core/java/android/app/WallpaperColors.aidl
new file mode 100644
index 0000000..f5edff2
--- /dev/null
+++ b/core/java/android/app/WallpaperColors.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+parcelable WallpaperColors;
\ No newline at end of file
diff --git a/core/java/android/app/WallpaperColors.java b/core/java/android/app/WallpaperColors.java
new file mode 100644
index 0000000..2a8130f
--- /dev/null
+++ b/core/java/android/app/WallpaperColors.java
@@ -0,0 +1,420 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.app;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Size;
+
+import com.android.internal.graphics.ColorUtils;
+import com.android.internal.graphics.palette.Palette;
+import com.android.internal.graphics.palette.VariationalKMeansQuantizer;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Provides information about the colors of a wallpaper.
+ * <p>
+ * Exposes the 3 most visually representative colors of a wallpaper. Can be either
+ * {@link WallpaperColors#getPrimaryColor()}, {@link WallpaperColors#getSecondaryColor()}
+ * or {@link WallpaperColors#getTertiaryColor()}.
+ */
+public final class WallpaperColors implements Parcelable {
+
+    /**
+     * Specifies that dark text is preferred over the current wallpaper for best presentation.
+     * <p>
+     * eg. A launcher may set its text color to black if this flag is specified.
+     * @hide
+     */
+    public static final int HINT_SUPPORTS_DARK_TEXT = 0x1;
+
+    /**
+     * Specifies that dark theme is preferred over the current wallpaper for best presentation.
+     * <p>
+     * eg. A launcher may set its drawer color to black if this flag is specified.
+     * @hide
+     */
+    public static final int HINT_SUPPORTS_DARK_THEME = 0x2;
+
+    // Maximum size that a bitmap can have to keep our calculations sane
+    private static final int MAX_BITMAP_SIZE = 112;
+
+    // Even though we have a maximum size, we'll mainly match bitmap sizes
+    // using the area instead. This way our comparisons are aspect ratio independent.
+    private static final int MAX_WALLPAPER_EXTRACTION_AREA = MAX_BITMAP_SIZE * MAX_BITMAP_SIZE;
+
+    // When extracting the main colors, only consider colors
+    // present in at least MIN_COLOR_OCCURRENCE of the image
+    private static final float MIN_COLOR_OCCURRENCE = 0.05f;
+
+    // Decides when dark theme is optimal for this wallpaper
+    private static final float DARK_THEME_MEAN_LUMINANCE = 0.25f;
+    // Minimum mean luminosity that an image needs to have to support dark text
+    private static final float BRIGHT_IMAGE_MEAN_LUMINANCE = 0.75f;
+    // We also check if the image has dark pixels in it,
+    // to avoid bright images with some dark spots.
+    private static final float DARK_PIXEL_LUMINANCE = 0.45f;
+    private static final float MAX_DARK_AREA = 0.05f;
+
+    private final ArrayList<Color> mMainColors;
+    private int mColorHints;
+
+    public WallpaperColors(Parcel parcel) {
+        mMainColors = new ArrayList<>();
+        final int count = parcel.readInt();
+        for (int i = 0; i < count; i++) {
+            final int colorInt = parcel.readInt();
+            Color color = Color.valueOf(colorInt);
+            mMainColors.add(color);
+        }
+        mColorHints = parcel.readInt();
+    }
+
+    /**
+     * Constructs {@link WallpaperColors} from a drawable.
+     * <p>
+     * Main colors will be extracted from the drawable.
+     *
+     * @param drawable Source where to extract from.
+     */
+    public static WallpaperColors fromDrawable(Drawable drawable) {
+        int width = drawable.getIntrinsicWidth();
+        int height = drawable.getIntrinsicHeight();
+
+        // Some drawables do not have intrinsic dimensions
+        if (width <= 0 || height <= 0) {
+            width = MAX_BITMAP_SIZE;
+            height = MAX_BITMAP_SIZE;
+        }
+
+        Size optimalSize = calculateOptimalSize(width, height);
+        Bitmap bitmap = Bitmap.createBitmap(optimalSize.getWidth(), optimalSize.getHeight(),
+                Bitmap.Config.ARGB_8888);
+        final Canvas bmpCanvas = new Canvas(bitmap);
+        drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
+        drawable.draw(bmpCanvas);
+
+        final WallpaperColors colors = WallpaperColors.fromBitmap(bitmap);
+        bitmap.recycle();
+
+        return colors;
+    }
+
+    /**
+     * Constructs {@link WallpaperColors} from a bitmap.
+     * <p>
+     * Main colors will be extracted from the bitmap.
+     *
+     * @param bitmap Source where to extract from.
+     */
+    public static WallpaperColors fromBitmap(@NonNull Bitmap bitmap) {
+        if (bitmap == null) {
+            throw new IllegalArgumentException("Bitmap can't be null");
+        }
+
+        final int bitmapArea = bitmap.getWidth() * bitmap.getHeight();
+        boolean shouldRecycle = false;
+        if (bitmapArea > MAX_WALLPAPER_EXTRACTION_AREA) {
+            shouldRecycle = true;
+            Size optimalSize = calculateOptimalSize(bitmap.getWidth(), bitmap.getHeight());
+            bitmap = Bitmap.createScaledBitmap(bitmap, optimalSize.getWidth(),
+                    optimalSize.getHeight(), true /* filter */);
+        }
+
+        final Palette palette = Palette
+                .from(bitmap)
+                .setQuantizer(new VariationalKMeansQuantizer())
+                .maximumColorCount(5)
+                .clearFilters()
+                .resizeBitmapArea(MAX_WALLPAPER_EXTRACTION_AREA)
+                .generate();
+
+        // Remove insignificant colors and sort swatches by population
+        final ArrayList<Palette.Swatch> swatches = new ArrayList<>(palette.getSwatches());
+        final float minColorArea = bitmap.getWidth() * bitmap.getHeight() * MIN_COLOR_OCCURRENCE;
+        swatches.removeIf(s -> s.getPopulation() < minColorArea);
+        swatches.sort((a, b) -> b.getPopulation() - a.getPopulation());
+
+        final int swatchesSize = swatches.size();
+        Color primary = null, secondary = null, tertiary = null;
+
+        swatchLoop:
+        for (int i = 0; i < swatchesSize; i++) {
+            Color color = Color.valueOf(swatches.get(i).getRgb());
+            switch (i) {
+                case 0:
+                    primary = color;
+                    break;
+                case 1:
+                    secondary = color;
+                    break;
+                case 2:
+                    tertiary = color;
+                    break;
+                default:
+                    // out of bounds
+                    break swatchLoop;
+            }
+        }
+
+        int hints = calculateHints(bitmap);
+
+        if (shouldRecycle) {
+            bitmap.recycle();
+        }
+
+        return new WallpaperColors(primary, secondary, tertiary, hints);
+    }
+
+    /**
+     * Constructs a new object from three colors.
+     *
+     * @param primaryColor Primary color.
+     * @param secondaryColor Secondary color.
+     * @param tertiaryColor Tertiary color.
+     * @see WallpaperColors#fromBitmap(Bitmap)
+     * @see WallpaperColors#fromDrawable(Drawable)
+     */
+    public WallpaperColors(@NonNull Color primaryColor, @Nullable Color secondaryColor,
+            @Nullable Color tertiaryColor) {
+        this(primaryColor, secondaryColor, tertiaryColor, 0);
+    }
+
+    /**
+     * Constructs a new object from three colors, where hints can be specified.
+     *
+     * @param primaryColor Primary color.
+     * @param secondaryColor Secondary color.
+     * @param tertiaryColor Tertiary color.
+     * @param colorHints A combination of WallpaperColor hints.
+     * @see WallpaperColors#HINT_SUPPORTS_DARK_TEXT
+     * @see WallpaperColors#fromBitmap(Bitmap)
+     * @see WallpaperColors#fromDrawable(Drawable)
+     * @hide
+     */
+    public WallpaperColors(@NonNull Color primaryColor, @Nullable Color secondaryColor,
+            @Nullable Color tertiaryColor, int colorHints) {
+
+        if (primaryColor == null) {
+            throw new IllegalArgumentException("Primary color should never be null.");
+        }
+
+        mMainColors = new ArrayList<>(3);
+        mMainColors.add(primaryColor);
+        if (secondaryColor != null) {
+            mMainColors.add(secondaryColor);
+        }
+        if (tertiaryColor != null) {
+            if (secondaryColor == null) {
+                throw new IllegalArgumentException("tertiaryColor can't be specified when "
+                        + "secondaryColor is null");
+            }
+            mMainColors.add(tertiaryColor);
+        }
+
+        mColorHints = colorHints;
+    }
+
+    public static final Creator<WallpaperColors> CREATOR = new Creator<WallpaperColors>() {
+        @Override
+        public WallpaperColors createFromParcel(Parcel in) {
+            return new WallpaperColors(in);
+        }
+
+        @Override
+        public WallpaperColors[] newArray(int size) {
+            return new WallpaperColors[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        List<Color> mainColors = getMainColors();
+        int count = mainColors.size();
+        dest.writeInt(count);
+        for (int i = 0; i < count; i++) {
+            Color color = mainColors.get(i);
+            dest.writeInt(color.toArgb());
+        }
+        dest.writeInt(mColorHints);
+    }
+
+    /**
+     * Gets the most visually representative color of the wallpaper.
+     * "Visually representative" means easily noticeable in the image,
+     * probably happening at high frequency.
+     *
+     * @return A color.
+     */
+    public @NonNull Color getPrimaryColor() {
+        return mMainColors.get(0);
+    }
+
+    /**
+     * Gets the second most preeminent color of the wallpaper. Can be null.
+     *
+     * @return A color, may be null.
+     */
+    public @Nullable Color getSecondaryColor() {
+        return mMainColors.size() < 2 ? null : mMainColors.get(1);
+    }
+
+    /**
+     * Gets the third most preeminent color of the wallpaper. Can be null.
+     *
+     * @return A color, may be null.
+     */
+    public @Nullable Color getTertiaryColor() {
+        return mMainColors.size() < 3 ? null : mMainColors.get(2);
+    }
+
+    /**
+     * List of most preeminent colors, sorted by importance.
+     *
+     * @return List of colors.
+     * @hide
+     */
+    public @NonNull List<Color> getMainColors() {
+        return Collections.unmodifiableList(mMainColors);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        WallpaperColors other = (WallpaperColors) o;
+        return mMainColors.equals(other.mMainColors)
+                && mColorHints == other.mColorHints;
+    }
+
+    @Override
+    public int hashCode() {
+        return 31 * mMainColors.hashCode() + mColorHints;
+    }
+
+    /**
+     * Combination of WallpaperColor hints.
+     *
+     * @see WallpaperColors#HINT_SUPPORTS_DARK_TEXT
+     * @return True if dark text is supported.
+     * @hide
+     */
+    public int getColorHints() {
+        return mColorHints;
+    }
+
+    /**
+     * @param colorHints Combination of WallpaperColors hints.
+     * @see WallpaperColors#HINT_SUPPORTS_DARK_TEXT
+     * @hide
+     */
+    public void setColorHints(int colorHints) {
+        mColorHints = colorHints;
+    }
+
+    /**
+     * Checks if image is bright and clean enough to support light text.
+     *
+     * @param source What to read.
+     * @return Whether image supports dark text or not.
+     */
+    private static int calculateHints(Bitmap source) {
+        if (source == null) {
+            return 0;
+        }
+
+        int[] pixels = new int[source.getWidth() * source.getHeight()];
+        double totalLuminance = 0;
+        final int maxDarkPixels = (int) (pixels.length * MAX_DARK_AREA);
+        int darkPixels = 0;
+        source.getPixels(pixels, 0 /* offset */, source.getWidth(), 0 /* x */, 0 /* y */,
+                source.getWidth(), source.getHeight());
+
+        // This bitmap was already resized to fit the maximum allowed area.
+        // Let's just loop through the pixels, no sweat!
+        float[] tmpHsl = new float[3];
+        for (int i = 0; i < pixels.length; i++) {
+            ColorUtils.colorToHSL(pixels[i], tmpHsl);
+            final float luminance = tmpHsl[2];
+            final int alpha = Color.alpha(pixels[i]);
+            // Make sure we don't have a dark pixel mass that will
+            // make text illegible.
+            if (luminance < DARK_PIXEL_LUMINANCE && alpha != 0) {
+                darkPixels++;
+            }
+            totalLuminance += luminance;
+        }
+
+        int hints = 0;
+        double meanLuminance = totalLuminance / pixels.length;
+        if (meanLuminance > BRIGHT_IMAGE_MEAN_LUMINANCE && darkPixels < maxDarkPixels) {
+            hints |= HINT_SUPPORTS_DARK_TEXT;
+        }
+        if (meanLuminance < DARK_THEME_MEAN_LUMINANCE) {
+            hints |= HINT_SUPPORTS_DARK_THEME;
+        }
+
+        return hints;
+    }
+
+    private static Size calculateOptimalSize(int width, int height) {
+        // Calculate how big the bitmap needs to be.
+        // This avoids unnecessary processing and allocation inside Palette.
+        final int requestedArea = width * height;
+        double scale = 1;
+        if (requestedArea > MAX_WALLPAPER_EXTRACTION_AREA) {
+            scale = Math.sqrt(MAX_WALLPAPER_EXTRACTION_AREA / (double) requestedArea);
+        }
+        int newWidth = (int) (width * scale);
+        int newHeight = (int) (height * scale);
+        // Dealing with edge cases of the drawable being too wide or too tall.
+        // Width or height would end up being 0, in this case we'll set it to 1.
+        if (newWidth == 0) {
+            newWidth = 1;
+        }
+        if (newHeight == 0) {
+            newHeight = 1;
+        }
+
+        return new Size(newWidth, newHeight);
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder colors = new StringBuilder();
+        for (int i = 0; i < mMainColors.size(); i++) {
+            colors.append(Integer.toHexString(mMainColors.get(i).toArgb())).append(" ");
+        }
+        return "[WallpaperColors: " + colors.toString() + "h: " + mColorHints + "]";
+    }
+}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index a850423..84839bf 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -17,12 +17,14 @@
 package android.app;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.RawRes;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
-import android.annotation.SdkConstant.SdkConstantType;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -52,13 +54,13 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.ParcelFileDescriptor;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.Pair;
 import android.view.WindowManagerGlobal;
 
 import libcore.io.IoUtils;
@@ -71,6 +73,7 @@
 import java.io.InputStream;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -271,15 +274,20 @@
         }
     }
 
-    static class Globals extends IWallpaperManagerCallback.Stub {
+    private static class Globals extends IWallpaperManagerCallback.Stub {
         private final IWallpaperManager mService;
+        private boolean mColorCallbackRegistered;
+        private final ArrayList<Pair<OnColorsChangedListener, Handler>> mColorListeners =
+                new ArrayList<>();
         private Bitmap mCachedWallpaper;
         private int mCachedWallpaperUserId;
         private Bitmap mDefaultWallpaper;
+        private Handler mMainLooperHandler;
 
         Globals(Looper looper) {
             IBinder b = ServiceManager.getService(Context.WALLPAPER_SERVICE);
             mService = IWallpaperManager.Stub.asInterface(b);
+            mMainLooperHandler = new Handler(looper);
             forgetLoadedWallpaper();
         }
 
@@ -292,6 +300,90 @@
             forgetLoadedWallpaper();
         }
 
+        /**
+         * Start listening to wallpaper color events.
+         * Will be called whenever someone changes their wallpaper or if a live wallpaper
+         * changes its colors.
+         * @param callback Listener
+         * @param handler Thread to call it from. Main thread if null.
+         * @param userId Owner of the wallpaper or UserHandle.USER_ALL
+         */
+        public void addOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
+                @Nullable Handler handler, int userId) {
+            synchronized (this) {
+                if (!mColorCallbackRegistered) {
+                    try {
+                        mService.registerWallpaperColorsCallback(this, userId);
+                        mColorCallbackRegistered = true;
+                    } catch (RemoteException e) {
+                        // Failed, service is gone
+                        Log.w(TAG, "Can't register for color updates", e);
+                    }
+                }
+                mColorListeners.add(new Pair<>(callback, handler));
+            }
+        }
+
+        /**
+         * Stop listening to wallpaper color events.
+         *
+         * @param callback listener
+         * @param userId Owner of the wallpaper or UserHandle.USER_ALL
+         */
+        public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
+                int userId) {
+            synchronized (this) {
+                mColorListeners.removeIf(pair -> pair.first == callback);
+
+                if (mColorListeners.size() == 0 && mColorCallbackRegistered) {
+                    mColorCallbackRegistered = false;
+                    try {
+                        mService.unregisterWallpaperColorsCallback(this, userId);
+                    } catch (RemoteException e) {
+                        // Failed, service is gone
+                        Log.w(TAG, "Can't unregister color updates", e);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId) {
+            synchronized (this) {
+                for (Pair<OnColorsChangedListener, Handler> listener : mColorListeners) {
+                    Handler handler = listener.second;
+                    if (listener.second == null) {
+                        handler = mMainLooperHandler;
+                    }
+                    handler.post(() -> {
+                        // Dealing with race conditions between posting a callback and
+                        // removeOnColorsChangedListener being called.
+                        boolean stillExists;
+                        synchronized (sGlobals) {
+                            stillExists = mColorListeners.contains(listener);
+                        }
+                        if (stillExists) {
+                            listener.first.onColorsChanged(colors, which, userId);
+                        }
+                    });
+                }
+            }
+        }
+
+        WallpaperColors getWallpaperColors(int which, int userId) {
+            if (which != FLAG_LOCK && which != FLAG_SYSTEM) {
+                throw new IllegalArgumentException(
+                        "Must request colors for exactly one kind of wallpaper");
+            }
+
+            try {
+                return mService.getWallpaperColors(which, userId);
+            } catch (RemoteException e) {
+                // Can't get colors, connection lost.
+            }
+            return null;
+        }
+
         public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault,
                 @SetWallpaperFlags int which) {
             return peekWallpaperBitmap(context, returnDefault, which, context.getUserId());
@@ -747,6 +839,81 @@
     }
 
     /**
+     * Registers a listener to get notified when the wallpaper colors change.
+     * Callback might be called from an arbitrary background thread.
+     *
+     * @param listener A listener to register
+     */
+    public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener) {
+        addOnColorsChangedListener(listener, null);
+    }
+
+    /**
+     * Registers a listener to get notified when the wallpaper colors change
+     * @param listener A listener to register
+     * @param handler Where to call it from. Will be called from the main thread
+     *                if null.
+     */
+    public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener,
+            @NonNull Handler handler) {
+        addOnColorsChangedListener(listener, handler, mContext.getUserId());
+    }
+
+    /**
+     * Registers a listener to get notified when the wallpaper colors change
+     * @param listener A listener to register
+     * @param handler Where to call it from. Will be called from the main thread
+     *                if null.
+     * @param userId Owner of the wallpaper or UserHandle.USER_ALL.
+     * @hide
+     */
+    public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener,
+            @NonNull Handler handler, int userId) {
+        sGlobals.addOnColorsChangedListener(listener, handler, userId);
+    }
+
+    /**
+     * Stop listening to color updates.
+     * @param callback A callback to unsubscribe.
+     */
+    public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback) {
+        removeOnColorsChangedListener(callback, mContext.getUserId());
+    }
+
+    /**
+     * Stop listening to color updates.
+     * @param callback A callback to unsubscribe.
+     * @param userId Owner of the wallpaper or UserHandle.USER_ALL.
+     * @hide
+     */
+    public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
+            int userId) {
+        sGlobals.removeOnColorsChangedListener(callback, userId);
+    }
+
+    /**
+     * Get the primary colors of a wallpaper
+     * @param which wallpaper type. Must be either {@link #FLAG_SYSTEM} or
+     *     {@link #FLAG_LOCK}
+     * @return {@link WallpaperColors} or null if colors are unknown.
+     */
+    public @Nullable WallpaperColors getWallpaperColors(int which) {
+        return getWallpaperColors(which, mContext.getUserId());
+    }
+
+    /**
+     * Get the primary colors of a wallpaper
+     * @param which wallpaper type. Must be either {@link #FLAG_SYSTEM} or
+     *     {@link #FLAG_LOCK}
+     * @param userId Owner of the wallpaper.
+     * @return {@link WallpaperColors} or null if colors are unknown.
+     * @hide
+     */
+    public @Nullable WallpaperColors getWallpaperColors(int which, int userId) {
+        return sGlobals.getWallpaperColors(which, userId);
+    }
+
+    /**
      * Version of {@link #getWallpaperFile(int)} that can access the wallpaper data
      * for a given user.  The caller must hold the INTERACT_ACROSS_USERS_FULL
      * permission to access another user's wallpaper data.
@@ -1737,5 +1904,40 @@
         public void onWallpaperChanged() throws RemoteException {
             mLatch.countDown();
         }
+
+        @Override
+        public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId)
+            throws RemoteException {
+            sGlobals.onWallpaperColorsChanged(colors, which, userId);
+        }
+    }
+
+    /**
+     * Interface definition for a callback to be invoked when colors change on a wallpaper.
+     */
+    public interface OnColorsChangedListener {
+        /**
+         * Called when colors change.
+         * A {@link android.app.WallpaperColors} object containing a simplified
+         * color histogram will be given.
+         *
+         * @param colors Wallpaper color info
+         * @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM}
+         */
+        void onColorsChanged(WallpaperColors colors, int which);
+
+        /**
+         * Called when colors change.
+         * A {@link android.app.WallpaperColors} object containing a simplified
+         * color histogram will be given.
+         *
+         * @param colors Wallpaper color info
+         * @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM}
+         * @param userId Owner of the wallpaper
+         * @hide
+         */
+        default void onColorsChanged(WallpaperColors colors, int which, int userId) {
+            onColorsChanged(colors, which);
+        }
     }
 }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 01c4656..f8aa948 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -55,7 +55,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.ContactsContract.Directory;
-import android.provider.Settings;
 import android.security.Credentials;
 import android.service.restrictions.RestrictionsReceiver;
 import android.telephony.TelephonyManager;
@@ -264,6 +263,25 @@
         = "android.app.action.PROVISION_MANAGED_DEVICE";
 
     /**
+     * Activity action: launch when user provisioning completed, i.e.
+     * {@link #getUserProvisioningState()} returns one of the complete state.
+     *
+     * <p> Please note that the API behavior is not necessarily consistent across various releases,
+     * and devices, as it's contract between SetupWizard and ManagedProvisioning. The default
+     * implementation is that ManagedProvisioning launches SetupWizard in NFC provisioning only.
+     *
+     * <p> The activity must be protected by permission
+     * {@link android.Manifest.permission#BIND_DEVICE_ADMIN}, and the process must hold
+     * {@link android.Manifest.permission#DISPATCH_PROVISIONING_MESSAGE} to be launched.
+     * Only one {@link ComponentName} in the entire system should be enabled, and the rest of the
+     * components are not started by this intent.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_STATE_USER_SETUP_COMPLETE =
+            "android.app.action.STATE_USER_SETUP_COMPLETE";
+
+    /**
      * Activity action: Starts the provisioning flow which sets up a managed device.
      *
      * <p>During device owner provisioning, a device admin app is downloaded and set as the owner of
@@ -3115,6 +3133,14 @@
     public static final int WIPE_RESET_PROTECTION_DATA = 0x0002;
 
     /**
+     * Flag for {@link #wipeData(int)}: also erase the device's eUICC data.
+     *
+     * TODO(b/35851809): make this public.
+     * @hide
+     */
+    public static final int WIPE_EUICC = 0x0004;
+
+    /**
      * Ask that all user data be wiped. If called as a secondary user, the user will be removed and
      * other users will remain unaffected. Calling from the primary user will cause the device to
      * reboot, erasing all device data - including all the secondary users and their data - while
@@ -3904,26 +3930,18 @@
 
     /**
      * Called by a device or profile owner to configure an always-on VPN connection through a
-     * specific application for the current user.
-     *
-     * @deprecated this version only exists for compability with previous developer preview builds.
-     *             TODO: delete once there are no longer any live references.
-     * @hide
-     */
-    @Deprecated
-    public void setAlwaysOnVpnPackage(@NonNull ComponentName admin, @Nullable String vpnPackage)
-            throws NameNotFoundException, UnsupportedOperationException {
-        setAlwaysOnVpnPackage(admin, vpnPackage, /* lockdownEnabled */ true);
-    }
-
-    /**
-     * Called by a device or profile owner to configure an always-on VPN connection through a
      * specific application for the current user. This connection is automatically granted and
      * persisted after a reboot.
      * <p>
-     * The designated package should declare a {@link android.net.VpnService} in its manifest
-     * guarded by {@link android.Manifest.permission#BIND_VPN_SERVICE}, otherwise the call will
-     * fail.
+     * To support the always-on feature, an app must
+     * <ul>
+     *     <li>declare a {@link android.net.VpnService} in its manifest, guarded by
+     *         {@link android.Manifest.permission#BIND_VPN_SERVICE};</li>
+     *     <li>target {@link android.os.Build.VERSION_CODES#N API 24} or above; and</li>
+     *     <li><i>not</i> explicitly opt out of the feature through
+     *         {@link android.net.VpnService#SERVICE_META_DATA_SUPPORTS_ALWAYS_ON}.</li>
+     * </ul>
+     * The call will fail if called with the package name of an unsupported VPN app.
      *
      * @param vpnPackage The package name for an installed VPN app on the device, or {@code null} to
      *        remove an existing always-on VPN configuration.
@@ -5956,6 +5974,13 @@
     public static final int MAKE_USER_EPHEMERAL = 0x0002;
 
     /**
+     * Flag used by {@link #createAndManageUser} to specify that the user should be created as a
+     * demo user.
+     * @hide
+     */
+    public static final int MAKE_USER_DEMO = 0x0004;
+
+    /**
      * Called by a device owner to create a user with the specified name and a given component of
      * the calling package as profile owner. The UserHandle returned by this method should not be
      * persisted as user handles are recycled as users are removed and created. If you need to
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index 5f92af9..42e6147 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -942,6 +942,11 @@
             long ident = Binder.clearCallingIdentity();
 
             if (DEBUG) Log.v(TAG, "doRestore() invoked");
+
+            // Ensure that any side-effect SharedPreferences writes have landed *before*
+            // we may be about to rewrite the file out from underneath
+            waitForSharedPrefs();
+
             BackupDataInput input = new BackupDataInput(data.getFileDescriptor());
             try {
                 BackupAgent.this.onRestore(input, appVersionCode, newState);
@@ -952,8 +957,8 @@
                 Log.d(TAG, "onRestore (" + BackupAgent.this.getClass().getName() + ") threw", ex);
                 throw ex;
             } finally {
-                // Ensure that any side-effect SharedPreferences writes have landed
-                waitForSharedPrefs();
+                // And bring live SharedPreferences instances up to date
+                reloadSharedPreferences();
 
                 Binder.restoreCallingIdentity(ident);
                 try {
@@ -1053,6 +1058,8 @@
             } finally {
                 // Ensure that any side-effect SharedPreferences writes have landed
                 waitForSharedPrefs();
+                // And bring live SharedPreferences instances up to date
+                reloadSharedPreferences();
 
                 Binder.restoreCallingIdentity(ident);
                 try {
diff --git a/core/java/android/app/timezone/RulesUpdaterContract.java b/core/java/android/app/timezone/RulesUpdaterContract.java
index 9c62f46..1f354af 100644
--- a/core/java/android/app/timezone/RulesUpdaterContract.java
+++ b/core/java/android/app/timezone/RulesUpdaterContract.java
@@ -83,8 +83,7 @@
         Intent intent = createUpdaterIntent(updaterAppPackageName);
         intent.putExtra(EXTRA_CHECK_TOKEN, checkTokenBytes);
         context.sendBroadcastAsUser(
-                intent,
-                UserHandle.of(UserHandle.myUserId()),
+                intent, UserHandle.SYSTEM,
                 RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION);
     }
 }
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index a10de45..6d65e3e 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -34,4 +34,6 @@
     boolean isDeviceLocked(int userId);
     boolean isDeviceSecure(int userId);
     boolean isTrustUsuallyManaged(int userId);
+    void unlockedByFingerprintForUser(int userId);
+    void clearAllFingerprints();
 }
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index 54a7e5c..852cb8e 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -27,8 +27,6 @@
 import android.os.RemoteException;
 import android.util.ArrayMap;
 
-import com.android.internal.widget.LockPatternUtils;
-
 /**
  * See {@link com.android.server.trust.TrustManagerService}
  * @hide
@@ -187,6 +185,32 @@
         }
     }
 
+    /**
+     * Updates the trust state for the user due to the user unlocking via fingerprint.
+     * Should only be called if user authenticated via fingerprint and bouncer can be skipped.
+     * @param userId
+     */
+    @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
+    public void unlockedByFingerprintForUser(int userId) {
+        try {
+            mService.unlockedByFingerprintForUser(userId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Clears authenticated fingerprints for all users.
+     */
+    @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
+    public void clearAllFingerprints() {
+        try {
+            mService.clearAllFingerprints();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
         @Override
         public void handleMessage(Message msg) {
diff --git a/core/java/android/app/usage/ExternalStorageStats.java b/core/java/android/app/usage/ExternalStorageStats.java
index d7e570f..f00e5c2 100644
--- a/core/java/android/app/usage/ExternalStorageStats.java
+++ b/core/java/android/app/usage/ExternalStorageStats.java
@@ -33,6 +33,7 @@
     /** {@hide} */ public long videoBytes;
     /** {@hide} */ public long imageBytes;
     /** {@hide} */ public long appBytes;
+    /** {@hide} */ public long obbBytes;
 
     /**
      * Return the total bytes used by all files in the shared/external storage
@@ -97,6 +98,11 @@
     }
 
     /** {@hide} */
+    public @BytesLong long getObbBytes() {
+        return obbBytes;
+    }
+
+    /** {@hide} */
     public ExternalStorageStats() {
     }
 
@@ -107,6 +113,7 @@
         this.videoBytes = in.readLong();
         this.imageBytes = in.readLong();
         this.appBytes = in.readLong();
+        this.obbBytes = in.readLong();
     }
 
     @Override
@@ -121,6 +128,7 @@
         dest.writeLong(videoBytes);
         dest.writeLong(imageBytes);
         dest.writeLong(appBytes);
+        dest.writeLong(obbBytes);
     }
 
     public static final Creator<ExternalStorageStats> CREATOR = new Creator<ExternalStorageStats>() {
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index c58eaa1..7841b83 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -42,7 +42,7 @@
  * This class provides the public APIs to control the Bluetooth A2DP
  * profile.
  *
- *<p>BluetoothA2dp is a proxy object for controlling the Bluetooth A2DP
+ * <p>BluetoothA2dp is a proxy object for controlling the Bluetooth A2DP
  * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
  * the BluetoothA2dp proxy object.
  *
@@ -60,9 +60,9 @@
      *
      * <p>This intent will have 3 extras:
      * <ul>
-     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
      * </ul>
      *
      * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -74,7 +74,7 @@
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_CONNECTION_STATE_CHANGED =
-        "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED";
+            "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED";
 
     /**
      * Intent used to broadcast the change in the Playing state of the A2DP
@@ -82,9 +82,9 @@
      *
      * <p>This intent will have 3 extras:
      * <ul>
-     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
      * </ul>
      *
      * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -95,12 +95,12 @@
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_PLAYING_STATE_CHANGED =
-        "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED";
+            "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED";
 
     /** @hide */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_AVRCP_CONNECTION_STATE_CHANGED =
-        "android.bluetooth.a2dp.profile.action.AVRCP_CONNECTION_STATE_CHANGED";
+            "android.bluetooth.a2dp.profile.action.AVRCP_CONNECTION_STATE_CHANGED";
 
     /**
      * Intent used to broadcast the change in the Audio Codec state of the
@@ -108,9 +108,9 @@
      *
      * <p>This intent will have 2 extras:
      * <ul>
-     *   <li> {@link BluetoothCodecStatus#EXTRA_CODEC_STATUS} - The codec status. </li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device if the device is currently
-     *   connected, otherwise it is not included.</li>
+     * <li> {@link BluetoothCodecStatus#EXTRA_CODEC_STATUS} - The codec status. </li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device if the device is currently
+     * connected, otherwise it is not included.</li>
      * </ul>
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
@@ -120,61 +120,74 @@
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_CODEC_CONFIG_CHANGED =
-        "android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED";
+            "android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED";
 
     /**
      * A2DP sink device is streaming music. This state can be one of
      * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
      * {@link #ACTION_PLAYING_STATE_CHANGED} intent.
      */
-    public static final int STATE_PLAYING   =  10;
+    public static final int STATE_PLAYING = 10;
 
     /**
      * A2DP sink device is NOT streaming music. This state can be one of
      * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
      * {@link #ACTION_PLAYING_STATE_CHANGED} intent.
      */
-    public static final int STATE_NOT_PLAYING   =  11;
+    public static final int STATE_NOT_PLAYING = 11;
 
     /**
      * We don't have a stored preference for whether or not the given A2DP sink device supports
      * optional codecs.
-     * @hide */
+     *
+     * @hide
+     */
     public static final int OPTIONAL_CODECS_SUPPORT_UNKNOWN = -1;
 
     /**
      * The given A2DP sink device does not support optional codecs.
-     * @hide */
+     *
+     * @hide
+     */
     public static final int OPTIONAL_CODECS_NOT_SUPPORTED = 0;
 
     /**
      * The given A2DP sink device does support optional codecs.
-     * @hide */
+     *
+     * @hide
+     */
     public static final int OPTIONAL_CODECS_SUPPORTED = 1;
 
     /**
      * We don't have a stored preference for whether optional codecs should be enabled or disabled
      * for the given A2DP device.
-     * @hide */
+     *
+     * @hide
+     */
     public static final int OPTIONAL_CODECS_PREF_UNKNOWN = -1;
 
     /**
      * Optional codecs should be disabled for the given A2DP device.
-     * @hide */
+     *
+     * @hide
+     */
     public static final int OPTIONAL_CODECS_PREF_DISABLED = 0;
 
     /**
-     *  Optional codecs should be enabled for the given A2DP device.
-     *  @hide */
+     * Optional codecs should be enabled for the given A2DP device.
+     *
+     * @hide
+     */
     public static final int OPTIONAL_CODECS_PREF_ENABLED = 1;
 
     private Context mContext;
     private ServiceListener mServiceListener;
     private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
-    @GuardedBy("mServiceLock") private IBluetoothA2dp mService;
+    @GuardedBy("mServiceLock")
+    private IBluetoothA2dp mService;
     private BluetoothAdapter mAdapter;
 
-    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
             new IBluetoothStateChangeCallback.Stub() {
                 public void onBluetoothStateChange(boolean up) {
                     if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
@@ -193,21 +206,21 @@
                         try {
                             mServiceLock.readLock().lock();
                             if (mService == null) {
-                                if (VDBG) Log.d(TAG,"Binding service...");
+                                if (VDBG) Log.d(TAG, "Binding service...");
                                 doBind();
                             }
                         } catch (Exception re) {
-                            Log.e(TAG,"",re);
+                            Log.e(TAG, "", re);
                         } finally {
                             mServiceLock.readLock().unlock();
                         }
                     }
                 }
-        };
+            };
+
     /**
      * Create a BluetoothA2dp proxy object for interacting with the local
      * Bluetooth A2DP service.
-     *
      */
     /*package*/ BluetoothA2dp(Context context, ServiceListener l) {
         mContext = context;
@@ -218,7 +231,7 @@
             try {
                 mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (RemoteException e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -244,7 +257,7 @@
             try {
                 mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (Exception e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -261,10 +274,12 @@
         }
     }
 
+    @Override
     public void finalize() {
         // The empty finalize needs to be kept or the
         // cts signature tests would fail.
     }
+
     /**
      * Initiate connection to a profile of the remote bluetooth device.
      *
@@ -283,16 +298,14 @@
      * permission.
      *
      * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
+     * @return false on immediate error, true otherwise
      * @hide
      */
     public boolean connect(BluetoothDevice device) {
         if (DBG) log("connect(" + device + ")");
         try {
             mServiceLock.readLock().lock();
-            if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+            if (mService != null && isEnabled() && isValidDevice(device)) {
                 return mService.connect(device);
             }
             if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -327,16 +340,14 @@
      * permission.
      *
      * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
+     * @return false on immediate error, true otherwise
      * @hide
      */
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) log("disconnect(" + device + ")");
         try {
             mServiceLock.readLock().lock();
-            if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+            if (mService != null && isEnabled() && isValidDevice(device)) {
                 return mService.disconnect(device);
             }
             if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -352,6 +363,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public List<BluetoothDevice> getConnectedDevices() {
         if (VDBG) log("getConnectedDevices()");
         try {
@@ -372,6 +384,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         if (VDBG) log("getDevicesMatchingStates()");
         try {
@@ -392,12 +405,13 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public int getConnectionState(BluetoothDevice device) {
         if (VDBG) log("getState(" + device + ")");
         try {
             mServiceLock.readLock().lock();
             if (mService != null && isEnabled()
-                && isValidDevice(device)) {
+                    && isValidDevice(device)) {
                 return mService.getConnectionState(device);
             }
             if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -414,7 +428,7 @@
      * Set priority of the profile
      *
      * <p> The device should already be paired.
-     *  Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
+     * Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
      * {@link #PRIORITY_OFF},
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
@@ -430,9 +444,9 @@
         try {
             mServiceLock.readLock().lock();
             if (mService != null && isEnabled()
-                && isValidDevice(device)) {
-                if (priority != BluetoothProfile.PRIORITY_OFF &&
-                    priority != BluetoothProfile.PRIORITY_ON) {
+                    && isValidDevice(device)) {
+                if (priority != BluetoothProfile.PRIORITY_OFF
+                        && priority != BluetoothProfile.PRIORITY_ON) {
                     return false;
                 }
                 return mService.setPriority(device, priority);
@@ -464,7 +478,7 @@
         try {
             mServiceLock.readLock().lock();
             if (mService != null && isEnabled()
-                && isValidDevice(device)) {
+                    && isValidDevice(device)) {
                 return mService.getPriority(device);
             }
             if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -560,7 +574,7 @@
         try {
             mServiceLock.readLock().lock();
             if (mService != null && isEnabled()
-                && isValidDevice(device)) {
+                    && isValidDevice(device)) {
                 return mService.isA2dpPlaying(device);
             }
             if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -577,6 +591,7 @@
      * This function checks if the remote device is an AVCRP
      * target and thus whether we should send volume keys
      * changes or not.
+     *
      * @hide
      */
     public boolean shouldSendVolumeKeys(BluetoothDevice device) {
@@ -584,7 +599,7 @@
             ParcelUuid[] uuids = device.getUuids();
             if (uuids == null) return false;
 
-            for (ParcelUuid uuid: uuids) {
+            for (ParcelUuid uuid : uuids) {
                 if (BluetoothUuid.isAvrcpTarget(uuid)) {
                     return true;
                 }
@@ -691,8 +706,7 @@
      *
      * @param device The device to check
      * @return one of OPTIONAL_CODECS_SUPPORT_UNKNOWN, OPTIONAL_CODECS_NOT_SUPPORTED, or
-     *         OPTIONAL_CODECS_SUPPORTED.
-     *
+     * OPTIONAL_CODECS_SUPPORTED.
      * @hide
      */
     public int supportsOptionalCodecs(BluetoothDevice device) {
@@ -716,8 +730,7 @@
      *
      * @param device The device in question.
      * @return one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
-     *         OPTIONAL_CODECS_PREF_DISABLED.
-     *
+     * OPTIONAL_CODECS_PREF_DISABLED.
      * @hide
      */
     public int getOptionalCodecsEnabled(BluetoothDevice device) {
@@ -741,15 +754,15 @@
      *
      * @param device The device to set this preference for.
      * @param value Whether the optional codecs should be enabled for this device.  This should be
-     *              one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
-     *              OPTIONAL_CODECS_PREF_DISABLED.
+     * one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
+     * OPTIONAL_CODECS_PREF_DISABLED.
      * @hide
      */
     public void setOptionalCodecsEnabled(BluetoothDevice device, int value) {
         try {
-            if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN &&
-                    value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED &&
-                    value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
+            if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN
+                    && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED
+                    && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
                 Log.e(TAG, "Invalid value passed to setOptionalCodecsEnabled: " + value);
                 return;
             }
@@ -772,24 +785,25 @@
      * Helper for converting a state to a string.
      *
      * For debug use only - strings are not internationalized.
+     *
      * @hide
      */
     public static String stateToString(int state) {
         switch (state) {
-        case STATE_DISCONNECTED:
-            return "disconnected";
-        case STATE_CONNECTING:
-            return "connecting";
-        case STATE_CONNECTED:
-            return "connected";
-        case STATE_DISCONNECTING:
-            return "disconnecting";
-        case STATE_PLAYING:
-            return "playing";
-        case STATE_NOT_PLAYING:
-          return "not playing";
-        default:
-            return "<unknown state " + state + ">";
+            case STATE_DISCONNECTED:
+                return "disconnected";
+            case STATE_CONNECTING:
+                return "connecting";
+            case STATE_CONNECTED:
+                return "connected";
+            case STATE_DISCONNECTING:
+                return "disconnecting";
+            case STATE_PLAYING:
+                return "playing";
+            case STATE_NOT_PLAYING:
+                return "not playing";
+            default:
+                return "<unknown state " + state + ">";
         }
     }
 
@@ -807,6 +821,7 @@
                 mServiceListener.onServiceConnected(BluetoothProfile.A2DP, BluetoothA2dp.this);
             }
         }
+
         public void onServiceDisconnected(ComponentName className) {
             if (DBG) Log.d(TAG, "Proxy object disconnected");
             try {
@@ -822,18 +837,18 @@
     };
 
     private boolean isEnabled() {
-       if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
-       return false;
+        if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
+        return false;
     }
 
     private boolean isValidDevice(BluetoothDevice device) {
-       if (device == null) return false;
+        if (device == null) return false;
 
-       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-       return false;
+        if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
+        return false;
     }
 
     private static void log(String msg) {
-      Log.d(TAG, msg);
+        Log.d(TAG, msg);
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java
index 9dfc4b4..faab000 100755
--- a/core/java/android/bluetooth/BluetoothA2dpSink.java
+++ b/core/java/android/bluetooth/BluetoothA2dpSink.java
@@ -32,7 +32,7 @@
  * This class provides the public APIs to control the Bluetooth A2DP Sink
  * profile.
  *
- *<p>BluetoothA2dpSink is a proxy object for controlling the Bluetooth A2DP Sink
+ * <p>BluetoothA2dpSink is a proxy object for controlling the Bluetooth A2DP Sink
  * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
  * the BluetoothA2dpSink proxy object.
  *
@@ -49,9 +49,9 @@
      *
      * <p>This intent will have 3 extras:
      * <ul>
-     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
      * </ul>
      *
      * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -62,7 +62,7 @@
      * receive.
      */
     public static final String ACTION_CONNECTION_STATE_CHANGED =
-        "android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED";
+            "android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED";
 
     /**
      * Intent used to broadcast the change in the Playing state of the A2DP Sink
@@ -70,9 +70,9 @@
      *
      * <p>This intent will have 3 extras:
      * <ul>
-     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
      * </ul>
      *
      * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -82,21 +82,21 @@
      * receive.
      */
     public static final String ACTION_PLAYING_STATE_CHANGED =
-        "android.bluetooth.a2dp-sink.profile.action.PLAYING_STATE_CHANGED";
+            "android.bluetooth.a2dp-sink.profile.action.PLAYING_STATE_CHANGED";
 
     /**
      * A2DP sink device is streaming music. This state can be one of
      * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
      * {@link #ACTION_PLAYING_STATE_CHANGED} intent.
      */
-    public static final int STATE_PLAYING   =  10;
+    public static final int STATE_PLAYING = 10;
 
     /**
      * A2DP sink device is NOT streaming music. This state can be one of
      * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
      * {@link #ACTION_PLAYING_STATE_CHANGED} intent.
      */
-    public static final int STATE_NOT_PLAYING   =  11;
+    public static final int STATE_NOT_PLAYING = 11;
 
     /**
      * Intent used to broadcast the change in the Playing state of the A2DP Sink
@@ -104,15 +104,15 @@
      *
      * <p>This intent will have 3 extras:
      * <ul>
-     *   <li> {@link #EXTRA_AUDIO_CONFIG} - The audio configuration for the remote device. </li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * <li> {@link #EXTRA_AUDIO_CONFIG} - The audio configuration for the remote device. </li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
      * </ul>
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
      * receive.
      */
     public static final String ACTION_AUDIO_CONFIG_CHANGED =
-        "android.bluetooth.a2dp-sink.profile.action.AUDIO_CONFIG_CHANGED";
+            "android.bluetooth.a2dp-sink.profile.action.AUDIO_CONFIG_CHANGED";
 
     /**
      * Extra for the {@link #ACTION_AUDIO_CONFIG_CHANGED} intent.
@@ -120,46 +120,46 @@
      * This extra represents the current audio configuration of the A2DP source device.
      * {@see BluetoothAudioConfig}
      */
-    public static final String EXTRA_AUDIO_CONFIG
-            = "android.bluetooth.a2dp-sink.profile.extra.AUDIO_CONFIG";
+    public static final String EXTRA_AUDIO_CONFIG =
+            "android.bluetooth.a2dp-sink.profile.extra.AUDIO_CONFIG";
 
     private Context mContext;
     private ServiceListener mServiceListener;
-    private IBluetoothA2dpSink mService;
+    private volatile IBluetoothA2dpSink mService;
     private BluetoothAdapter mAdapter;
 
-    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
             new IBluetoothStateChangeCallback.Stub() {
                 public void onBluetoothStateChange(boolean up) {
                     if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
                     if (!up) {
-                        if (VDBG) Log.d(TAG,"Unbinding service...");
+                        if (VDBG) Log.d(TAG, "Unbinding service...");
                         synchronized (mConnection) {
                             try {
                                 mService = null;
                                 mContext.unbindService(mConnection);
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     } else {
                         synchronized (mConnection) {
                             try {
                                 if (mService == null) {
-                                    if (VDBG) Log.d(TAG,"Binding service...");
+                                    if (VDBG) Log.d(TAG, "Binding service...");
                                     doBind();
                                 }
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     }
                 }
-        };
+            };
+
     /**
      * Create a BluetoothA2dp proxy object for interacting with the local
      * Bluetooth A2DP service.
-     *
      */
     /*package*/ BluetoothA2dpSink(Context context, ServiceListener l) {
         mContext = context;
@@ -170,7 +170,7 @@
             try {
                 mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (RemoteException e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -196,7 +196,7 @@
             try {
                 mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (Exception e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -206,15 +206,17 @@
                     mService = null;
                     mContext.unbindService(mConnection);
                 } catch (Exception re) {
-                    Log.e(TAG,"",re);
+                    Log.e(TAG, "", re);
                 }
             }
         }
     }
 
+    @Override
     public void finalize() {
         close();
     }
+
     /**
      * Initiate connection to a profile of the remote bluetooth device.
      *
@@ -233,22 +235,21 @@
      * permission.
      *
      * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
+     * @return false on immediate error, true otherwise
      * @hide
      */
     public boolean connect(BluetoothDevice device) {
         if (DBG) log("connect(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothA2dpSink service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.connect(device);
+                return service.connect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -274,74 +275,78 @@
      * permission.
      *
      * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
+     * @return false on immediate error, true otherwise
      * @hide
      */
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) log("disconnect(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothA2dpSink service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.disconnect(device);
+                return service.disconnect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public List<BluetoothDevice> getConnectedDevices() {
         if (VDBG) log("getConnectedDevices()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothA2dpSink service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getConnectedDevices();
+                return service.getConnectedDevices();
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         if (VDBG) log("getDevicesMatchingStates()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothA2dpSink service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getDevicesMatchingConnectionStates(states);
+                return service.getDevicesMatchingConnectionStates(states);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public int getConnectionState(BluetoothDevice device) {
         if (VDBG) log("getState(" + device + ")");
-        if (mService != null && isEnabled()
-            && isValidDevice(device)) {
+        final IBluetoothA2dpSink service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getConnectionState(device);
+                return service.getConnectionState(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.STATE_DISCONNECTED;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return BluetoothProfile.STATE_DISCONNECTED;
     }
 
@@ -356,18 +361,18 @@
      *
      * {@see BluetoothAudioConfig}
      */
-          public BluetoothAudioConfig getAudioConfig(BluetoothDevice device) {
+    public BluetoothAudioConfig getAudioConfig(BluetoothDevice device) {
         if (VDBG) log("getAudioConfig(" + device + ")");
-        if (mService != null && isEnabled()
-            && isValidDevice(device)) {
+        final IBluetoothA2dpSink service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getAudioConfig(device);
+                return service.getAudioConfig(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return null;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return null;
     }
 
@@ -375,7 +380,7 @@
      * Set priority of the profile
      *
      * <p> The device should already be paired.
-     *  Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
+     * Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
      * {@link #PRIORITY_OFF},
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
@@ -388,21 +393,21 @@
      */
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        if (mService != null && isEnabled()
-            && isValidDevice(device)) {
-            if (priority != BluetoothProfile.PRIORITY_OFF &&
-                priority != BluetoothProfile.PRIORITY_ON){
+        final IBluetoothA2dpSink service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            if (priority != BluetoothProfile.PRIORITY_OFF
+                    && priority != BluetoothProfile.PRIORITY_ON) {
                 return false;
             }
             try {
-                return mService.setPriority(device, priority);
+                return service.setPriority(device, priority);
             } catch (RemoteException e) {
-                   Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                   return false;
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-            return false;
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
     }
 
     /**
@@ -420,16 +425,16 @@
      */
     public int getPriority(BluetoothDevice device) {
         if (VDBG) log("getPriority(" + device + ")");
-        if (mService != null && isEnabled()
-            && isValidDevice(device)) {
+        final IBluetoothA2dpSink service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getPriority(device);
+                return service.getPriority(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.PRIORITY_OFF;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return BluetoothProfile.PRIORITY_OFF;
     }
 
@@ -441,16 +446,16 @@
      * @param device BluetoothDevice device
      */
     public boolean isA2dpPlaying(BluetoothDevice device) {
-        if (mService != null && isEnabled()
-            && isValidDevice(device)) {
+        final IBluetoothA2dpSink service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.isA2dpPlaying(device);
+                return service.isA2dpPlaying(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -458,24 +463,25 @@
      * Helper for converting a state to a string.
      *
      * For debug use only - strings are not internationalized.
+     *
      * @hide
      */
     public static String stateToString(int state) {
         switch (state) {
-        case STATE_DISCONNECTED:
-            return "disconnected";
-        case STATE_CONNECTING:
-            return "connecting";
-        case STATE_CONNECTED:
-            return "connected";
-        case STATE_DISCONNECTING:
-            return "disconnecting";
-        case STATE_PLAYING:
-            return "playing";
-        case STATE_NOT_PLAYING:
-          return "not playing";
-        default:
-            return "<unknown state " + state + ">";
+            case STATE_DISCONNECTED:
+                return "disconnected";
+            case STATE_CONNECTING:
+                return "connecting";
+            case STATE_CONNECTED:
+                return "connected";
+            case STATE_DISCONNECTING:
+                return "disconnecting";
+            case STATE_PLAYING:
+                return "playing";
+            case STATE_NOT_PLAYING:
+                return "not playing";
+            default:
+                return "<unknown state " + state + ">";
         }
     }
 
@@ -483,12 +489,12 @@
         public void onServiceConnected(ComponentName className, IBinder service) {
             if (DBG) Log.d(TAG, "Proxy object connected");
             mService = IBluetoothA2dpSink.Stub.asInterface(Binder.allowBlocking(service));
-
             if (mServiceListener != null) {
                 mServiceListener.onServiceConnected(BluetoothProfile.A2DP_SINK,
                         BluetoothA2dpSink.this);
             }
         }
+
         public void onServiceDisconnected(ComponentName className) {
             if (DBG) Log.d(TAG, "Proxy object disconnected");
             mService = null;
@@ -499,18 +505,14 @@
     };
 
     private boolean isEnabled() {
-       if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
-       return false;
+        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
     }
 
-    private boolean isValidDevice(BluetoothDevice device) {
-       if (device == null) return false;
-
-       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-       return false;
+    private static boolean isValidDevice(BluetoothDevice device) {
+        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
     }
 
     private static void log(String msg) {
-      Log.d(TAG, msg);
+        Log.d(TAG, msg);
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
index 84f6060..43b79db 100644
--- a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
+++ b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
@@ -25,6 +25,7 @@
  * Record of energy and activity information from controller and
  * underlying bt stack state.Timestamp the record with system
  * time
+ *
  * @hide
  */
 public final class BluetoothActivityEnergyInfo implements Parcelable {
@@ -42,7 +43,7 @@
     public static final int BT_STACK_STATE_STATE_IDLE = 3;
 
     public BluetoothActivityEnergyInfo(long timestamp, int stackState,
-                                       long txTime, long rxTime, long idleTime, long energyUsed) {
+            long txTime, long rxTime, long idleTime, long energyUsed) {
         mTimestamp = timestamp;
         mBluetoothStackState = stackState;
         mControllerTxTimeMs = txTime;
@@ -65,27 +66,29 @@
     @Override
     public String toString() {
         return "BluetoothActivityEnergyInfo{"
-            + " mTimestamp=" + mTimestamp
-            + " mBluetoothStackState=" + mBluetoothStackState
-            + " mControllerTxTimeMs=" + mControllerTxTimeMs
-            + " mControllerRxTimeMs=" + mControllerRxTimeMs
-            + " mControllerIdleTimeMs=" + mControllerIdleTimeMs
-            + " mControllerEnergyUsed=" + mControllerEnergyUsed
-            + " mUidTraffic=" + Arrays.toString(mUidTraffic)
-            + " }";
+                + " mTimestamp=" + mTimestamp
+                + " mBluetoothStackState=" + mBluetoothStackState
+                + " mControllerTxTimeMs=" + mControllerTxTimeMs
+                + " mControllerRxTimeMs=" + mControllerRxTimeMs
+                + " mControllerIdleTimeMs=" + mControllerIdleTimeMs
+                + " mControllerEnergyUsed=" + mControllerEnergyUsed
+                + " mUidTraffic=" + Arrays.toString(mUidTraffic)
+                + " }";
     }
 
     public static final Parcelable.Creator<BluetoothActivityEnergyInfo> CREATOR =
             new Parcelable.Creator<BluetoothActivityEnergyInfo>() {
-        public BluetoothActivityEnergyInfo createFromParcel(Parcel in) {
-            return new BluetoothActivityEnergyInfo(in);
-        }
+                public BluetoothActivityEnergyInfo createFromParcel(Parcel in) {
+                    return new BluetoothActivityEnergyInfo(in);
+                }
 
-        public BluetoothActivityEnergyInfo[] newArray(int size) {
-            return new BluetoothActivityEnergyInfo[size];
-        }
-    };
+                public BluetoothActivityEnergyInfo[] newArray(int size) {
+                    return new BluetoothActivityEnergyInfo[size];
+                }
+            };
 
+
+    @Override
     @SuppressWarnings("unchecked")
     public void writeToParcel(Parcel out, int flags) {
         out.writeLong(mTimestamp);
@@ -97,6 +100,7 @@
         out.writeTypedArray(mUidTraffic, flags);
     }
 
+    @Override
     public int describeContents() {
         return 0;
     }
@@ -131,6 +135,7 @@
 
     /**
      * product of current(mA), voltage(V) and time(ms)
+     *
      * @return energy used
      */
     public long getControllerEnergyUsed() {
@@ -156,8 +161,7 @@
      * @return if the record is valid
      */
     public boolean isValid() {
-        return ((mControllerTxTimeMs >=0) &&
-                (mControllerRxTimeMs >=0) &&
-                (mControllerIdleTimeMs >=0));
+        return ((mControllerTxTimeMs >= 0) && (mControllerRxTimeMs >= 0)
+                && (mControllerIdleTimeMs >= 0));
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index fc3a724..3d9651d 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -80,7 +80,7 @@
  * {@link #getBondedDevices()}; start device discovery with
  * {@link #startDiscovery()}; or create a {@link BluetoothServerSocket} to
  * listen for incoming connection requests with
- * {@link #listenUsingRfcommWithServiceRecord(String,UUID)}; or start a scan for
+ * {@link #listenUsingRfcommWithServiceRecord(String, UUID)}; or start a scan for
  * Bluetooth LE devices with {@link #startLeScan(LeScanCallback callback)}.
  * </p>
  * <p>This class is thread safe.</p>
@@ -92,7 +92,7 @@
  * <div class="special reference">
  * <h3>Developer Guides</h3>
  * <p>
- *  For more information about using Bluetooth, read the <a href=
+ * For more information about using Bluetooth, read the <a href=
  * "{@docRoot}guide/topics/connectivity/bluetooth.html">Bluetooth</a> developer
  * guide.
  * </p>
@@ -161,7 +161,8 @@
     @IntDef({STATE_OFF, STATE_TURNING_ON, STATE_ON, STATE_TURNING_OFF, STATE_BLE_TURNING_ON,
             STATE_BLE_ON, STATE_BLE_TURNING_OFF})
     @Retention(RetentionPolicy.SOURCE)
-    public @interface AdapterState {}
+    public @interface AdapterState {
+    }
 
     /**
      * Indicates the local Bluetooth adapter is off.
@@ -185,36 +186,48 @@
 
     /**
      * Indicates the local Bluetooth adapter is turning Bluetooth LE mode on.
+     *
      * @hide
      */
     public static final int STATE_BLE_TURNING_ON = 14;
 
     /**
      * Indicates the local Bluetooth adapter is in LE only mode.
+     *
      * @hide
      */
     public static final int STATE_BLE_ON = 15;
 
     /**
      * Indicates the local Bluetooth adapter is turning off LE only mode.
+     *
      * @hide
      */
     public static final int STATE_BLE_TURNING_OFF = 16;
 
     /**
      * Human-readable string helper for AdapterState
+     *
      * @hide
      */
     public static String nameForState(@AdapterState int state) {
-        switch(state) {
-            case STATE_OFF: return "OFF";
-            case STATE_TURNING_ON: return "TURNING_ON";
-            case STATE_ON: return "ON";
-            case STATE_TURNING_OFF: return "TURNING_OFF";
-            case STATE_BLE_TURNING_ON: return "BLE_TURNING_ON";
-            case STATE_BLE_ON: return "BLE_ON";
-            case STATE_BLE_TURNING_OFF: return "BLE_TURNING_OFF";
-            default: return "?!?!? (" + state + ")";
+        switch (state) {
+            case STATE_OFF:
+                return "OFF";
+            case STATE_TURNING_ON:
+                return "TURNING_ON";
+            case STATE_ON:
+                return "ON";
+            case STATE_TURNING_OFF:
+                return "TURNING_OFF";
+            case STATE_BLE_TURNING_ON:
+                return "BLE_TURNING_ON";
+            case STATE_BLE_ON:
+                return "BLE_ON";
+            case STATE_BLE_TURNING_OFF:
+                return "BLE_TURNING_OFF";
+            default:
+                return "?!?!? (" + state + ")";
         }
     }
 
@@ -346,7 +359,8 @@
     /** @hide */
     @IntDef({SCAN_MODE_NONE, SCAN_MODE_CONNECTABLE, SCAN_MODE_CONNECTABLE_DISCOVERABLE})
     @Retention(RetentionPolicy.SOURCE)
-    public @interface ScanMode {}
+    public @interface ScanMode {
+    }
 
     /**
      * Indicates that both inquiry scan and page scan are disabled on the local
@@ -439,7 +453,7 @@
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_CONNECTION_STATE_CHANGED =
-        "android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED";
+            "android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED";
 
     /**
      * Extra used by {@link #ACTION_CONNECTION_STATE_CHANGED}
@@ -447,7 +461,7 @@
      * This extra represents the current connection state.
      */
     public static final String EXTRA_CONNECTION_STATE =
-        "android.bluetooth.adapter.extra.CONNECTION_STATE";
+            "android.bluetooth.adapter.extra.CONNECTION_STATE";
 
     /**
      * Extra used by {@link #ACTION_CONNECTION_STATE_CHANGED}
@@ -455,15 +469,16 @@
      * This extra represents the previous connection state.
      */
     public static final String EXTRA_PREVIOUS_CONNECTION_STATE =
-          "android.bluetooth.adapter.extra.PREVIOUS_CONNECTION_STATE";
+            "android.bluetooth.adapter.extra.PREVIOUS_CONNECTION_STATE";
 
     /**
      * Broadcast Action: The Bluetooth adapter state has changed in LE only mode.
+     *
      * @hide
      */
     @SystemApi
     public static final String ACTION_BLE_STATE_CHANGED =
-        "android.bluetooth.adapter.action.BLE_STATE_CHANGED";
+            "android.bluetooth.adapter.action.BLE_STATE_CHANGED";
 
     /**
      * Intent used to broadcast the change in the Bluetooth address
@@ -477,7 +492,7 @@
      * @hide
      */
     public static final String ACTION_BLUETOOTH_ADDRESS_CHANGED =
-        "android.bluetooth.adapter.action.BLUETOOTH_ADDRESS_CHANGED";
+            "android.bluetooth.adapter.action.BLUETOOTH_ADDRESS_CHANGED";
 
     /**
      * Used as a String extra field in {@link
@@ -487,7 +502,7 @@
      * @hide
      */
     public static final String EXTRA_BLUETOOTH_ADDRESS =
-          "android.bluetooth.adapter.extra.BLUETOOTH_ADDRESS";
+            "android.bluetooth.adapter.extra.BLUETOOTH_ADDRESS";
 
     /**
      * Broadcast Action: The notifys Bluetooth ACL connected event. This will be
@@ -497,10 +512,11 @@
      *
      * This is counterpart of {@link BluetoothDevice#ACTION_ACL_CONNECTED} which
      * works in Bluetooth state STATE_ON
+     *
      * @hide
      */
     public static final String ACTION_BLE_ACL_CONNECTED =
-        "android.bluetooth.adapter.action.BLE_ACL_CONNECTED";
+            "android.bluetooth.adapter.action.BLE_ACL_CONNECTED";
 
     /**
      * Broadcast Action: The notifys Bluetooth ACL connected event. This will be
@@ -510,17 +526,18 @@
      *
      * This is counterpart of {@link BluetoothDevice#ACTION_ACL_DISCONNECTED} which
      * works in Bluetooth state STATE_ON
+     *
      * @hide
      */
     public static final String ACTION_BLE_ACL_DISCONNECTED =
-        "android.bluetooth.adapter.action.BLE_ACL_DISCONNECTED";
+            "android.bluetooth.adapter.action.BLE_ACL_DISCONNECTED";
 
     /** The profile is in disconnected state */
-    public static final int STATE_DISCONNECTED  = 0;
+    public static final int STATE_DISCONNECTED = 0;
     /** The profile is in connecting state */
-    public static final int STATE_CONNECTING    = 1;
+    public static final int STATE_CONNECTING = 1;
     /** The profile is in connected state */
-    public static final int STATE_CONNECTED     = 2;
+    public static final int STATE_CONNECTED = 2;
     /** The profile is in disconnecting state */
     public static final int STATE_DISCONNECTING = 3;
 
@@ -529,14 +546,17 @@
     private final IBinder mToken;
 
 
-    /** When creating a ServerSocket using listenUsingRfcommOn() or
-     *  listenUsingL2capOn() use SOCKET_CHANNEL_AUTO_STATIC to create
-     *  a ServerSocket that auto assigns a channel number to the first
-     *  bluetooth socket.
-     *  The channel number assigned to this first Bluetooth Socket will
-     *  be stored in the ServerSocket, and reused for subsequent Bluetooth
-     *  sockets.
-     * @hide */
+    /**
+     * When creating a ServerSocket using listenUsingRfcommOn() or
+     * listenUsingL2capOn() use SOCKET_CHANNEL_AUTO_STATIC to create
+     * a ServerSocket that auto assigns a channel number to the first
+     * bluetooth socket.
+     * The channel number assigned to this first Bluetooth Socket will
+     * be stored in the ServerSocket, and reused for subsequent Bluetooth
+     * sockets.
+     *
+     * @hide
+     */
     public static final int SOCKET_CHANNEL_AUTO_STATIC_NO_SDP = -2;
 
 
@@ -555,7 +575,7 @@
     private final IBluetoothManager mManagerService;
     private IBluetooth mService;
     private final ReentrantReadWriteLock mServiceLock =
-        new ReentrantReadWriteLock();
+            new ReentrantReadWriteLock();
 
     private final Object mLock = new Object();
     private final Map<LeScanCallback, ScanCallback> mLeScanClients;
@@ -566,8 +586,9 @@
      * could be extended to support more. This will always return the default
      * adapter.
      * </p>
-     * @return the default local adapter, or null if Bluetooth is not supported
-     *         on this hardware platform
+     *
+     * @return the default local adapter, or null if Bluetooth is not supported on this hardware
+     * platform
      */
     public static synchronized BluetoothAdapter getDefaultAdapter() {
         if (sAdapter == null) {
@@ -648,7 +669,7 @@
      */
     public BluetoothLeAdvertiser getBluetoothLeAdvertiser() {
         if (!getLeAccess()) return null;
-        synchronized(mLock) {
+        synchronized (mLock) {
             if (sBluetoothLeAdvertiser == null) {
                 sBluetoothLeAdvertiser = new BluetoothLeAdvertiser(mManagerService);
             }
@@ -663,22 +684,25 @@
      * <p>
      * Use {@link #isLePeriodicAdvertisingSupported()} to check whether LE Periodic Advertising is
      * supported on this device before calling this method.
+     *
      * @hide
      */
     public PeriodicAdvertisingManager getPeriodicAdvertisingManager() {
-      if (!getLeAccess())
-        return null;
-
-      if (!isLePeriodicAdvertisingSupported())
-        return null;
-
-      synchronized (mLock) {
-        if (sPeriodicAdvertisingManager == null) {
-          sPeriodicAdvertisingManager =
-              new PeriodicAdvertisingManager(mManagerService);
+        if (!getLeAccess()) {
+            return null;
         }
-      }
-      return sPeriodicAdvertisingManager;
+
+        if (!isLePeriodicAdvertisingSupported()) {
+            return null;
+        }
+
+        synchronized (mLock) {
+            if (sPeriodicAdvertisingManager == null) {
+                sPeriodicAdvertisingManager =
+                        new PeriodicAdvertisingManager(mManagerService);
+            }
+        }
+        return sPeriodicAdvertisingManager;
     }
 
     /**
@@ -686,7 +710,7 @@
      */
     public BluetoothLeScanner getBluetoothLeScanner() {
         if (!getLeAccess()) return null;
-        synchronized(mLock) {
+        synchronized (mLock) {
             if (sBluetoothLeScanner == null) {
                 sBluetoothLeScanner = new BluetoothLeScanner(mManagerService);
             }
@@ -725,9 +749,9 @@
      */
     @SystemApi
     public boolean isLeEnabled() {
-       final int state = getLeState();
-       if (DBG) Log.d(TAG, "isLeEnabled(): " + BluetoothAdapter.nameForState(state));
-       return (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_BLE_ON);
+        final int state = getLeState();
+        if (DBG) Log.d(TAG, "isLeEnabled(): " + BluetoothAdapter.nameForState(state));
+        return (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_BLE_ON);
     }
 
     /**
@@ -752,8 +776,7 @@
      * immediate problem that will prevent the QAdapter from being turned off -
      * such as the QAadapter already being turned off.
      *
-     * @return true to indicate success, or false on
-     *         immediate error
+     * @return true to indicate success, or false on immediate error
      * @hide
      */
     @SystemApi
@@ -763,7 +786,7 @@
         int state = getLeState();
         if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_BLE_ON) {
             String packageName = ActivityThread.currentPackageName();
-            if (DBG) Log.d (TAG, "disableBLE(): de-registering " + packageName);
+            if (DBG) Log.d(TAG, "disableBLE(): de-registering " + packageName);
             try {
                 mManagerService.updateBleAppCount(mToken, false, packageName);
             } catch (RemoteException e) {
@@ -772,7 +795,7 @@
             return true;
         }
 
-        if (DBG) Log.d (TAG, "disableBLE(): Already disabled");
+        if (DBG) Log.d(TAG, "disableBLE(): Already disabled");
         return false;
     }
 
@@ -804,8 +827,7 @@
      * states, It includes all the classic Bluetooth Adapter states along with
      * internal BLE only states
      *
-     * @return true to indicate Bluetooth LE will be available, or false on
-     *         immediate error
+     * @return true to indicate Bluetooth LE will be available, or false on immediate error
      * @hide
      */
     @SystemApi
@@ -856,12 +878,19 @@
 
         // Consider all internal states as OFF
         if (state == BluetoothAdapter.STATE_BLE_ON
-            || state == BluetoothAdapter.STATE_BLE_TURNING_ON
-            || state == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
-            if (VDBG) Log.d(TAG, "Consider " + BluetoothAdapter.nameForState(state) + " state as OFF");
+                || state == BluetoothAdapter.STATE_BLE_TURNING_ON
+                || state == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
+            if (VDBG) {
+                Log.d(TAG,
+                        "Consider " + BluetoothAdapter.nameForState(state) + " state as OFF");
+            }
             state = BluetoothAdapter.STATE_OFF;
         }
-        if (VDBG) Log.d(TAG, "" + hashCode() + ": getState(). Returning " + BluetoothAdapter.nameForState(state));
+        if (VDBG) {
+            Log.d(TAG,
+                    "" + hashCode() + ": getState(). Returning " + BluetoothAdapter.nameForState(
+                            state));
+        }
         return state;
     }
 
@@ -897,16 +926,16 @@
             mServiceLock.readLock().unlock();
         }
 
-        if (VDBG) Log.d(TAG,"getLeState() returning " + BluetoothAdapter.nameForState(state));
+        if (VDBG) Log.d(TAG, "getLeState() returning " + BluetoothAdapter.nameForState(state));
         return state;
     }
 
     boolean getLeAccess() {
-        if (getLeState() == STATE_ON)
+        if (getLeState() == STATE_ON) {
             return true;
-
-        else if (getLeState() == STATE_BLE_ON)
+        } else if (getLeState() == STATE_BLE_ON) {
             return true; // TODO: FILTER SYSTEM APPS HERE <--
+        }
 
         return false;
     }
@@ -933,8 +962,7 @@
      * immediate problem that will prevent the adapter from being turned on -
      * such as Airplane mode, or the adapter is already turned on.
      *
-     * @return true to indicate adapter startup has begun, or false on
-     *         immediate error
+     * @return true to indicate adapter startup has begun, or false on immediate error
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
     public boolean enable() {
@@ -944,7 +972,9 @@
         }
         try {
             return mManagerService.enable(ActivityThread.currentPackageName());
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return false;
     }
 
@@ -967,14 +997,15 @@
      * immediate problem that will prevent the adapter from being turned off -
      * such as the adapter already being turned off.
      *
-     * @return true to indicate adapter shutdown has begun, or false on
-     *         immediate error
+     * @return true to indicate adapter shutdown has begun, or false on immediate error
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
     public boolean disable() {
         try {
             return mManagerService.disable(ActivityThread.currentPackageName(), true);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return false;
     }
 
@@ -984,15 +1015,16 @@
      * <p>Requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN}
      * permission
      *
-     * @return true to indicate adapter shutdown has begun, or false on
-     *         immediate error
+     * @return true to indicate adapter shutdown has begun, or false on immediate error
      * @hide
      */
     public boolean disable(boolean persist) {
 
         try {
             return mManagerService.disable(ActivityThread.currentPackageName(), persist);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return false;
     }
 
@@ -1006,7 +1038,9 @@
     public String getAddress() {
         try {
             return mManagerService.getAddress();
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return null;
     }
 
@@ -1020,7 +1054,9 @@
     public String getName() {
         try {
             return mManagerService.getName();
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return null;
     }
 
@@ -1031,7 +1067,6 @@
      * permission
      *
      * @return true to indicate that the config file was successfully cleared
-     *
      * @hide
      */
     public boolean factoryReset() {
@@ -1082,7 +1117,7 @@
      * to get the updated value.
      *
      * @param name a valid Bluetooth name
-     * @return     true if the name was set, false otherwise
+     * @return true if the name was set, false otherwise
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
     public boolean setName(String name) {
@@ -1099,6 +1134,53 @@
     }
 
     /**
+     * Returns the {@link BluetoothClass} Bluetooth Class of Device (CoD) of the local Bluetooth
+     * adapter.
+     *
+     * @return {@link BluetoothClass} Bluetooth CoD of local Bluetooth device.
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    public BluetoothClass getBluetoothClass() {
+        if (getState() != STATE_ON) return null;
+        try {
+            mServiceLock.readLock().lock();
+            if (mService != null) return mService.getBluetoothClass();
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        } finally {
+            mServiceLock.readLock().unlock();
+        }
+        return null;
+    }
+
+    /**
+     * Sets the {@link BluetoothClass} Bluetooth Class of Device (CoD) of the local Bluetooth
+     * adapter.
+     *
+     * <p>Note: This value persists across system reboot.
+     *
+     * @param bluetoothClass {@link BluetoothClass} to set the local Bluetooth adapter to.
+     * @return true if successful, false if unsuccessful.
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    public boolean setBluetoothClass(BluetoothClass bluetoothClass) {
+        if (getState() != STATE_ON) return false;
+        try {
+            mServiceLock.readLock().lock();
+            if (mService != null) return mService.setBluetoothClass(bluetoothClass);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        } finally {
+            mServiceLock.readLock().unlock();
+        }
+        return false;
+    }
+
+    /**
      * Get the current Bluetooth scan mode of the local Bluetooth adapter.
      * <p>The Bluetooth scan mode determines if the local adapter is
      * connectable and/or discoverable from remote Bluetooth devices.
@@ -1151,9 +1233,9 @@
      * </code>instead.
      *
      * @param mode valid scan mode
-     * @param duration time in seconds to apply scan mode, only used for
-     *                 {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}
-     * @return     true if the scan mode was set, false otherwise
+     * @param duration time in seconds to apply scan mode, only used for {@link
+     * #SCAN_MODE_CONNECTABLE_DISCOVERABLE}
+     * @return true if the scan mode was set, false otherwise
      * @hide
      */
     public boolean setScanMode(@ScanMode int mode, int duration) {
@@ -1205,9 +1287,10 @@
 
     /**
      * Get the end time of the latest remote device discovery process.
-     * @return the latest time that the bluetooth adapter was/will be in discovery mode,
-     * in milliseconds since the epoch.
-     * This time can be in the future if {@link #startDiscovery()} has been called recently.
+     *
+     * @return the latest time that the bluetooth adapter was/will be in discovery mode, in
+     * milliseconds since the epoch. This time can be in the future if {@link #startDiscovery()} has
+     * been called recently.
      * @hide
      */
     public long getDiscoveryEndMillis() {
@@ -1517,13 +1600,13 @@
      * Return the record of {@link BluetoothActivityEnergyInfo} object that
      * has the activity and energy info. This can be used to ascertain what
      * the controller has been up to, since the last sample.
-     * @param updateType Type of info, cached vs refreshed.
      *
-     * @return a record with {@link BluetoothActivityEnergyInfo} or null if
-     * report is unavailable or unsupported
-     * @deprecated use the asynchronous
-     * {@link #requestControllerActivityEnergyInfo(ResultReceiver)} instead.
+     * @param updateType Type of info, cached vs refreshed.
+     * @return a record with {@link BluetoothActivityEnergyInfo} or null if report is unavailable or
+     * unsupported
      * @hide
+     * @deprecated use the asynchronous {@link #requestControllerActivityEnergyInfo(ResultReceiver)}
+     * instead.
      */
     @Deprecated
     public BluetoothActivityEnergyInfo getControllerActivityEnergyInfo(int updateType) {
@@ -1599,11 +1682,11 @@
     /**
      * Gets the currently supported profiles by the adapter.
      *
-     *<p> This can be used to check whether a profile is supported before attempting
+     * <p> This can be used to check whether a profile is supported before attempting
      * to connect to its respective proxy.
      *
-     * @return a list of integers indicating the ids of supported profiles as defined in
-     * {@link BluetoothProfile}.
+     * @return a list of integers indicating the ids of supported profiles as defined in {@link
+     * BluetoothProfile}.
      * @hide
      */
     public List<Integer> getSupportedProfiles() {
@@ -1622,7 +1705,7 @@
                 }
             }
         } catch (RemoteException e) {
-          Log.e(TAG, "getSupportedProfiles:", e);
+            Log.e(TAG, "getSupportedProfiles:", e);
         }
         return supportedProfiles;
     }
@@ -1635,9 +1718,8 @@
      * <p> Use this function along with {@link #ACTION_CONNECTION_STATE_CHANGED}
      * intent to get the connection state of the adapter.
      *
-     * @return One of {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTED},
-     * {@link #STATE_CONNECTING} or {@link #STATE_DISCONNECTED}
-     *
+     * @return One of {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTED}, {@link
+     * #STATE_CONNECTING} or {@link #STATE_DISCONNECTED}
      * @hide
      */
     public int getConnectionState() {
@@ -1688,10 +1770,11 @@
      * connections from a listening {@link BluetoothServerSocket}.
      * <p>Valid RFCOMM channels are in range 1 to 30.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     *
      * @param channel RFCOMM channel to listen on
      * @return a listening RFCOMM BluetoothServerSocket
-     * @throws IOException on error, for example Bluetooth not available, or
-     *                     insufficient permissions, or channel in use.
+     * @throws IOException on error, for example Bluetooth not available, or insufficient
+     * permissions, or channel in use.
      * @hide
      */
     public BluetoothServerSocket listenUsingRfcommOn(int channel) throws IOException {
@@ -1708,12 +1791,14 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
      * <p>To auto assign a channel without creating a SDP record use
      * {@link SOCKET_CHANNEL_AUTO_STATIC_NO_SDP} as channel number.
+     *
      * @param channel RFCOMM channel to listen on
-     * @param mitm    enforce man-in-the-middle protection for authentication.
-     * @param min16DigitPin enforce a pin key length og minimum 16 digit for sec mode 2 connections.
+     * @param mitm enforce man-in-the-middle protection for authentication.
+     * @param min16DigitPin enforce a pin key length og minimum 16 digit for sec mode 2
+     * connections.
      * @return a listening RFCOMM BluetoothServerSocket
-     * @throws IOException on error, for example Bluetooth not available, or
-     *                     insufficient permissions, or channel in use.
+     * @throws IOException on error, for example Bluetooth not available, or insufficient
+     * permissions, or channel in use.
      * @hide
      */
     public BluetoothServerSocket listenUsingRfcommOn(int channel, boolean mitm,
@@ -1749,11 +1834,12 @@
      * closed, or if this application closes unexpectedly.
      * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to
      * connect to this socket from another device using the same {@link UUID}.
+     *
      * @param name service name for SDP record
      * @param uuid uuid for SDP record
      * @return a listening RFCOMM BluetoothServerSocket
-     * @throws IOException on error, for example Bluetooth not available, or
-     *                     insufficient permissions, or channel in use.
+     * @throws IOException on error, for example Bluetooth not available, or insufficient
+     * permissions, or channel in use.
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public BluetoothServerSocket listenUsingRfcommWithServiceRecord(String name, UUID uuid)
@@ -1780,11 +1866,12 @@
      * closed, or if this application closes unexpectedly.
      * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to
      * connect to this socket from another device using the same {@link UUID}.
+     *
      * @param name service name for SDP record
      * @param uuid uuid for SDP record
      * @return a listening RFCOMM BluetoothServerSocket
-     * @throws IOException on error, for example Bluetooth not available, or
-     *                     insufficient permissions, or channel in use.
+     * @throws IOException on error, for example Bluetooth not available, or insufficient
+     * permissions, or channel in use.
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(String name, UUID uuid)
@@ -1792,7 +1879,7 @@
         return createNewRfcommSocketAndRecord(name, uuid, false, false);
     }
 
-     /**
+    /**
      * Create a listening, encrypted,
      * RFCOMM Bluetooth socket with Service Record.
      * <p>The link will be encrypted, but the link key is not required to be authenticated
@@ -1818,11 +1905,12 @@
      * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to
      * connect to this socket from another device using the same {@link UUID}.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+     *
      * @param name service name for SDP record
      * @param uuid uuid for SDP record
      * @return a listening RFCOMM BluetoothServerSocket
-     * @throws IOException on error, for example Bluetooth not available, or
-     *                     insufficient permissions, or channel in use.
+     * @throws IOException on error, for example Bluetooth not available, or insufficient
+     * permissions, or channel in use.
      * @hide
      */
     public BluetoothServerSocket listenUsingEncryptedRfcommWithServiceRecord(
@@ -1835,7 +1923,7 @@
             boolean auth, boolean encrypt) throws IOException {
         BluetoothServerSocket socket;
         socket = new BluetoothServerSocket(BluetoothSocket.TYPE_RFCOMM, auth,
-                        encrypt, new ParcelUuid(uuid));
+                encrypt, new ParcelUuid(uuid));
         socket.setServiceName(name);
         int errno = socket.mSocket.bindListen();
         if (errno != 0) {
@@ -1850,16 +1938,17 @@
     /**
      * Construct an unencrypted, unauthenticated, RFCOMM server socket.
      * Call #accept to retrieve connections to this socket.
+     *
      * @return An RFCOMM BluetoothServerSocket
-     * @throws IOException On error, for example Bluetooth not available, or
-     *                     insufficient permissions.
+     * @throws IOException On error, for example Bluetooth not available, or insufficient
+     * permissions.
      * @hide
      */
     public BluetoothServerSocket listenUsingInsecureRfcommOn(int port) throws IOException {
         BluetoothServerSocket socket = new BluetoothServerSocket(
                 BluetoothSocket.TYPE_RFCOMM, false, false, port);
         int errno = socket.mSocket.bindListen();
-        if(port == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
+        if (port == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
             socket.setChannel(socket.mSocket.getPort());
         }
         if (errno != 0) {
@@ -1871,12 +1960,13 @@
         return socket;
     }
 
-     /**
+    /**
      * Construct an encrypted, RFCOMM server socket.
      * Call #accept to retrieve connections to this socket.
+     *
      * @return An RFCOMM BluetoothServerSocket
-     * @throws IOException On error, for example Bluetooth not available, or
-     *                     insufficient permissions.
+     * @throws IOException On error, for example Bluetooth not available, or insufficient
+     * permissions.
      * @hide
      */
     public BluetoothServerSocket listenUsingEncryptedRfcommOn(int port)
@@ -1884,7 +1974,7 @@
         BluetoothServerSocket socket = new BluetoothServerSocket(
                 BluetoothSocket.TYPE_RFCOMM, false, true, port);
         int errno = socket.mSocket.bindListen();
-        if(port == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
+        if (port == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
             socket.setChannel(socket.mSocket.getPort());
         }
         if (errno < 0) {
@@ -1899,9 +1989,10 @@
     /**
      * Construct a SCO server socket.
      * Call #accept to retrieve connections to this socket.
+     *
      * @return A SCO BluetoothServerSocket
-     * @throws IOException On error, for example Bluetooth not available, or
-     *                     insufficient permissions.
+     * @throws IOException On error, for example Bluetooth not available, or insufficient
+     * permissions.
      * @hide
      */
     public static BluetoothServerSocket listenUsingScoOn() throws IOException {
@@ -1921,12 +2012,14 @@
      * Call #accept to retrieve connections to this socket.
      * <p>To auto assign a port without creating a SDP record use
      * {@link SOCKET_CHANNEL_AUTO_STATIC_NO_SDP} as port number.
-     * @param port    the PSM to listen on
-     * @param mitm    enforce man-in-the-middle protection for authentication.
-     * @param min16DigitPin enforce a pin key length og minimum 16 digit for sec mode 2 connections.
+     *
+     * @param port the PSM to listen on
+     * @param mitm enforce man-in-the-middle protection for authentication.
+     * @param min16DigitPin enforce a pin key length og minimum 16 digit for sec mode 2
+     * connections.
      * @return An L2CAP BluetoothServerSocket
-     * @throws IOException On error, for example Bluetooth not available, or
-     *                     insufficient permissions.
+     * @throws IOException On error, for example Bluetooth not available, or insufficient
+     * permissions.
      * @hide
      */
     public BluetoothServerSocket listenUsingL2capOn(int port, boolean mitm, boolean min16DigitPin)
@@ -1934,7 +2027,7 @@
         BluetoothServerSocket socket = new BluetoothServerSocket(
                 BluetoothSocket.TYPE_L2CAP, true, true, port, mitm, min16DigitPin);
         int errno = socket.mSocket.bindListen();
-        if(port == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
+        if (port == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
             socket.setChannel(socket.mSocket.getPort());
         }
         if (errno != 0) {
@@ -1951,10 +2044,11 @@
      * Call #accept to retrieve connections to this socket.
      * <p>To auto assign a port without creating a SDP record use
      * {@link SOCKET_CHANNEL_AUTO_STATIC_NO_SDP} as port number.
-     * @param port    the PSM to listen on
+     *
+     * @param port the PSM to listen on
      * @return An L2CAP BluetoothServerSocket
-     * @throws IOException On error, for example Bluetooth not available, or
-     *                     insufficient permissions.
+     * @throws IOException On error, for example Bluetooth not available, or insufficient
+     * permissions.
      * @hide
      */
     public BluetoothServerSocket listenUsingL2capOn(int port) throws IOException {
@@ -1967,17 +2061,18 @@
      * Call #accept to retrieve connections to this socket.
      * <p>To auto assign a port without creating a SDP record use
      * {@link SOCKET_CHANNEL_AUTO_STATIC_NO_SDP} as port number.
-     * @param port    the PSM to listen on
+     *
+     * @param port the PSM to listen on
      * @return An L2CAP BluetoothServerSocket
-     * @throws IOException On error, for example Bluetooth not available, or
-     *                     insufficient permissions.
+     * @throws IOException On error, for example Bluetooth not available, or insufficient
+     * permissions.
      * @hide
      */
     public BluetoothServerSocket listenUsingInsecureL2capOn(int port) throws IOException {
         BluetoothServerSocket socket = new BluetoothServerSocket(
                 BluetoothSocket.TYPE_L2CAP, false, false, port, false, false);
         int errno = socket.mSocket.bindListen();
-        if(port == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
+        if (port == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
             socket.setChannel(socket.mSocket.getPort());
         }
         if (errno != 0) {
@@ -1995,7 +2090,6 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
      * @return Pair<byte[], byte[]> of Hash and Randomizer
-     *
      * @hide
      */
     public Pair<byte[], byte[]> readOutOfBandData() {
@@ -2013,13 +2107,13 @@
      *
      * @param context Context of the application
      * @param listener The service Listener for connection callbacks.
-     * @param profile The Bluetooth profile; either {@link BluetoothProfile#HEALTH},
-     *                {@link BluetoothProfile#HEADSET}, {@link BluetoothProfile#A2DP}.
-     *                {@link BluetoothProfile#GATT} or {@link BluetoothProfile#GATT_SERVER}.
+     * @param profile The Bluetooth profile; either {@link BluetoothProfile#HEALTH}, {@link
+     * BluetoothProfile#HEADSET}, {@link BluetoothProfile#A2DP}. {@link BluetoothProfile#GATT} or
+     * {@link BluetoothProfile#GATT_SERVER}.
      * @return true on success, false on error
      */
     public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener,
-                                   int profile) {
+            int profile) {
         if (context == null || listener == null) return false;
 
         if (profile == BluetoothProfile.HEADSET) {
@@ -2034,8 +2128,8 @@
         } else if (profile == BluetoothProfile.AVRCP_CONTROLLER) {
             BluetoothAvrcpController avrcp = new BluetoothAvrcpController(context, listener);
             return true;
-        } else if (profile == BluetoothProfile.INPUT_DEVICE) {
-            BluetoothInputDevice iDev = new BluetoothInputDevice(context, listener);
+        } else if (profile == BluetoothProfile.HID_HOST) {
+            BluetoothHidHost iDev = new BluetoothHidHost(context, listener);
             return true;
         } else if (profile == BluetoothProfile.PAN) {
             BluetoothPan pan = new BluetoothPan(context, listener);
@@ -2058,8 +2152,8 @@
         } else if (profile == BluetoothProfile.MAP_CLIENT) {
             BluetoothMapClient mapClient = new BluetoothMapClient(context, listener);
             return true;
-        } else if (profile == BluetoothProfile.INPUT_HOST) {
-            BluetoothInputHost iHost = new BluetoothInputHost(context, listener);
+        } else if (profile == BluetoothProfile.HID_DEVICE) {
+            BluetoothHidDevice hidDevice = new BluetoothHidDevice(context, listener);
             return true;
         } else {
             return false;
@@ -2082,138 +2176,141 @@
 
         switch (profile) {
             case BluetoothProfile.HEADSET:
-                BluetoothHeadset headset = (BluetoothHeadset)proxy;
+                BluetoothHeadset headset = (BluetoothHeadset) proxy;
                 headset.close();
                 break;
             case BluetoothProfile.A2DP:
-                BluetoothA2dp a2dp = (BluetoothA2dp)proxy;
+                BluetoothA2dp a2dp = (BluetoothA2dp) proxy;
                 a2dp.close();
                 break;
             case BluetoothProfile.A2DP_SINK:
-                BluetoothA2dpSink a2dpSink = (BluetoothA2dpSink)proxy;
+                BluetoothA2dpSink a2dpSink = (BluetoothA2dpSink) proxy;
                 a2dpSink.close();
                 break;
             case BluetoothProfile.AVRCP_CONTROLLER:
-                BluetoothAvrcpController avrcp = (BluetoothAvrcpController)proxy;
+                BluetoothAvrcpController avrcp = (BluetoothAvrcpController) proxy;
                 avrcp.close();
                 break;
-            case BluetoothProfile.INPUT_DEVICE:
-                BluetoothInputDevice iDev = (BluetoothInputDevice)proxy;
+            case BluetoothProfile.HID_HOST:
+                BluetoothHidHost iDev = (BluetoothHidHost) proxy;
                 iDev.close();
                 break;
             case BluetoothProfile.PAN:
-                BluetoothPan pan = (BluetoothPan)proxy;
+                BluetoothPan pan = (BluetoothPan) proxy;
                 pan.close();
                 break;
             case BluetoothProfile.HEALTH:
-                BluetoothHealth health = (BluetoothHealth)proxy;
+                BluetoothHealth health = (BluetoothHealth) proxy;
                 health.close();
                 break;
-           case BluetoothProfile.GATT:
-                BluetoothGatt gatt = (BluetoothGatt)proxy;
+            case BluetoothProfile.GATT:
+                BluetoothGatt gatt = (BluetoothGatt) proxy;
                 gatt.close();
                 break;
             case BluetoothProfile.GATT_SERVER:
-                BluetoothGattServer gattServer = (BluetoothGattServer)proxy;
+                BluetoothGattServer gattServer = (BluetoothGattServer) proxy;
                 gattServer.close();
                 break;
             case BluetoothProfile.MAP:
-                BluetoothMap map = (BluetoothMap)proxy;
+                BluetoothMap map = (BluetoothMap) proxy;
                 map.close();
                 break;
             case BluetoothProfile.HEADSET_CLIENT:
-                BluetoothHeadsetClient headsetClient = (BluetoothHeadsetClient)proxy;
+                BluetoothHeadsetClient headsetClient = (BluetoothHeadsetClient) proxy;
                 headsetClient.close();
                 break;
             case BluetoothProfile.SAP:
-                BluetoothSap sap = (BluetoothSap)proxy;
+                BluetoothSap sap = (BluetoothSap) proxy;
                 sap.close();
                 break;
             case BluetoothProfile.PBAP_CLIENT:
-                BluetoothPbapClient pbapClient = (BluetoothPbapClient)proxy;
+                BluetoothPbapClient pbapClient = (BluetoothPbapClient) proxy;
                 pbapClient.close();
                 break;
             case BluetoothProfile.MAP_CLIENT:
-                BluetoothMapClient mapClient = (BluetoothMapClient)proxy;
+                BluetoothMapClient mapClient = (BluetoothMapClient) proxy;
                 mapClient.close();
                 break;
-            case BluetoothProfile.INPUT_HOST:
-                BluetoothInputHost iHost = (BluetoothInputHost) proxy;
-                iHost.close();
+            case BluetoothProfile.HID_DEVICE:
+                BluetoothHidDevice hidDevice = (BluetoothHidDevice) proxy;
+                hidDevice.close();
                 break;
         }
     }
 
-    final private IBluetoothManagerCallback mManagerCallback =
-        new IBluetoothManagerCallback.Stub() {
-            public void onBluetoothServiceUp(IBluetooth bluetoothService) {
-                if (DBG) Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService);
+    private final IBluetoothManagerCallback mManagerCallback =
+            new IBluetoothManagerCallback.Stub() {
+                public void onBluetoothServiceUp(IBluetooth bluetoothService) {
+                    if (DBG) Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService);
 
-                mServiceLock.writeLock().lock();
-                mService = bluetoothService;
-                mServiceLock.writeLock().unlock();
-
-                synchronized (mProxyServiceStateCallbacks) {
-                    for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ) {
-                        try {
-                            if (cb != null) {
-                                cb.onBluetoothServiceUp(bluetoothService);
-                            } else {
-                                Log.d(TAG, "onBluetoothServiceUp: cb is null!");
-                            }
-                        } catch (Exception e) {
-                            Log.e(TAG,"",e);
-                        }
-                    }
-                }
-            }
-
-            public void onBluetoothServiceDown() {
-                if (DBG) Log.d(TAG, "onBluetoothServiceDown: " + mService);
-
-                try {
                     mServiceLock.writeLock().lock();
-                    mService = null;
-                    if (mLeScanClients != null) mLeScanClients.clear();
-                    if (sBluetoothLeAdvertiser != null) sBluetoothLeAdvertiser.cleanup();
-                    if (sBluetoothLeScanner != null) sBluetoothLeScanner.cleanup();
-                } finally {
+                    mService = bluetoothService;
                     mServiceLock.writeLock().unlock();
-                }
 
-                synchronized (mProxyServiceStateCallbacks) {
-                    for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ){
-                        try {
-                            if (cb != null) {
-                                cb.onBluetoothServiceDown();
-                            } else {
-                                Log.d(TAG, "onBluetoothServiceDown: cb is null!");
+                    synchronized (mProxyServiceStateCallbacks) {
+                        for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks) {
+                            try {
+                                if (cb != null) {
+                                    cb.onBluetoothServiceUp(bluetoothService);
+                                } else {
+                                    Log.d(TAG, "onBluetoothServiceUp: cb is null!");
+                                }
+                            } catch (Exception e) {
+                                Log.e(TAG, "", e);
                             }
-                        } catch (Exception e) {
-                            Log.e(TAG,"",e);
                         }
                     }
                 }
-            }
 
-            public void onBrEdrDown() {
-                if (VDBG) Log.i(TAG, "onBrEdrDown: " + mService);
-            }
-    };
+                public void onBluetoothServiceDown() {
+                    if (DBG) Log.d(TAG, "onBluetoothServiceDown: " + mService);
+
+                    try {
+                        mServiceLock.writeLock().lock();
+                        mService = null;
+                        if (mLeScanClients != null) mLeScanClients.clear();
+                        if (sBluetoothLeAdvertiser != null) sBluetoothLeAdvertiser.cleanup();
+                        if (sBluetoothLeScanner != null) sBluetoothLeScanner.cleanup();
+                    } finally {
+                        mServiceLock.writeLock().unlock();
+                    }
+
+                    synchronized (mProxyServiceStateCallbacks) {
+                        for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks) {
+                            try {
+                                if (cb != null) {
+                                    cb.onBluetoothServiceDown();
+                                } else {
+                                    Log.d(TAG, "onBluetoothServiceDown: cb is null!");
+                                }
+                            } catch (Exception e) {
+                                Log.e(TAG, "", e);
+                            }
+                        }
+                    }
+                }
+
+                public void onBrEdrDown() {
+                    if (VDBG) Log.i(TAG, "onBrEdrDown: " + mService);
+                }
+            };
 
     /**
      * Enable the Bluetooth Adapter, but don't auto-connect devices
      * and don't persist state. Only for use by system applications.
+     *
      * @hide
      */
     public boolean enableNoAutoConnect() {
-        if (isEnabled() == true){
+        if (isEnabled()) {
             if (DBG) Log.d(TAG, "enableNoAutoConnect(): BT already enabled!");
             return true;
         }
         try {
             return mManagerService.enableNoAutoConnect(ActivityThread.currentPackageName());
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return false;
     }
 
@@ -2247,7 +2344,7 @@
      * @hide
      */
     public boolean changeApplicationBluetoothState(boolean on,
-                                                   BluetoothStateChangeCallback callback) {
+            BluetoothStateChangeCallback callback) {
         return false;
     }
 
@@ -2305,28 +2402,29 @@
         for (int i = 0; i < ADDRESS_LENGTH; i++) {
             char c = address.charAt(i);
             switch (i % 3) {
-            case 0:
-            case 1:
-                if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
-                    // hex character, OK
-                    break;
-                }
-                return false;
-            case 2:
-                if (c == ':') {
-                    break;  // OK
-                }
-                return false;
+                case 0:
+                case 1:
+                    if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
+                        // hex character, OK
+                        break;
+                    }
+                    return false;
+                case 2:
+                    if (c == ':') {
+                        break;  // OK
+                    }
+                    return false;
             }
         }
         return true;
     }
 
     /*package*/ IBluetoothManager getBluetoothManager() {
-            return mManagerService;
+        return mManagerService;
     }
 
-    final private ArrayList<IBluetoothManagerCallback> mProxyServiceStateCallbacks = new ArrayList<IBluetoothManagerCallback>();
+    private final ArrayList<IBluetoothManagerCallback> mProxyServiceStateCallbacks =
+            new ArrayList<IBluetoothManagerCallback>();
 
     /*package*/ IBluetooth getBluetoothService(IBluetoothManagerCallback cb) {
         synchronized (mProxyServiceStateCallbacks) {
@@ -2357,10 +2455,9 @@
          * by the {@link BluetoothAdapter#startLeScan} function.
          *
          * @param device Identifies the remote device
-         * @param rssi The RSSI value for the remote device as reported by the
-         *             Bluetooth hardware. 0 if no RSSI value is available.
-         * @param scanRecord The content of the advertisement record offered by
-         *                   the remote device.
+         * @param rssi The RSSI value for the remote device as reported by the Bluetooth hardware. 0
+         * if no RSSI value is available.
+         * @param scanRecord The content of the advertisement record offered by the remote device.
          */
         public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord);
     }
@@ -2374,7 +2471,7 @@
      * @param callback the callback LE scan results are delivered
      * @return true, if the scan was started successfully
      * @deprecated use {@link BluetoothLeScanner#startScan(List, ScanSettings, ScanCallback)}
-     *             instead.
+     * instead.
      */
     @Deprecated
     @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
@@ -2393,7 +2490,7 @@
      * @param callback the callback LE scan results are delivered
      * @return true, if the scan was started successfully
      * @deprecated use {@link BluetoothLeScanner#startScan(List, ScanSettings, ScanCallback)}
-     *             instead.
+     * instead.
      */
     @Deprecated
     @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
@@ -2409,7 +2506,7 @@
             return false;
         }
 
-        synchronized(mLeScanClients) {
+        synchronized (mLeScanClients) {
             if (mLeScanClients.containsKey(callback)) {
                 if (DBG) Log.e(TAG, "LE Scan has already started");
                 return false;
@@ -2450,8 +2547,8 @@
                     }
                 };
                 ScanSettings settings = new ScanSettings.Builder()
-                    .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
-                    .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
+                        .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
+                        .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
 
                 List<ScanFilter> filters = new ArrayList<ScanFilter>();
                 if (serviceUuids != null && serviceUuids.length > 0) {
@@ -2467,7 +2564,7 @@
                 return true;
 
             } catch (RemoteException e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
         return false;
@@ -2476,8 +2573,8 @@
     /**
      * Stops an ongoing Bluetooth LE device scan.
      *
-     * @param callback used to identify which scan to stop
-     *        must be the same handle used to start the scan
+     * @param callback used to identify which scan to stop must be the same handle used to start the
+     * scan
      * @deprecated Use {@link BluetoothLeScanner#stopScan(ScanCallback)} instead.
      */
     @Deprecated
diff --git a/core/java/android/bluetooth/BluetoothAssignedNumbers.java b/core/java/android/bluetooth/BluetoothAssignedNumbers.java
index 124bdc1..41a34e0 100644
--- a/core/java/android/bluetooth/BluetoothAssignedNumbers.java
+++ b/core/java/android/bluetooth/BluetoothAssignedNumbers.java
@@ -20,9 +20,9 @@
  * Bluetooth Assigned Numbers.
  * <p>
  * For now we only include Company ID values.
- * @see <a href="https://www.bluetooth.org/technical/assignednumbers/identifiers.htm">
- * The Official Bluetooth SIG Member Website | Company Identifiers</a>
  *
+ * @see <a href="https://www.bluetooth.org/technical/assignednumbers/identifiers.htm"> The Official
+ * Bluetooth SIG Member Website | Company Identifiers</a>
  */
 public class BluetoothAssignedNumbers {
 
diff --git a/core/java/android/bluetooth/BluetoothAudioConfig.java b/core/java/android/bluetooth/BluetoothAudioConfig.java
index 03176b9..a441056 100644
--- a/core/java/android/bluetooth/BluetoothAudioConfig.java
+++ b/core/java/android/bluetooth/BluetoothAudioConfig.java
@@ -41,10 +41,9 @@
     @Override
     public boolean equals(Object o) {
         if (o instanceof BluetoothAudioConfig) {
-            BluetoothAudioConfig bac = (BluetoothAudioConfig)o;
-            return (bac.mSampleRate == mSampleRate &&
-                    bac.mChannelConfig == mChannelConfig &&
-                    bac.mAudioFormat == mAudioFormat);
+            BluetoothAudioConfig bac = (BluetoothAudioConfig) o;
+            return (bac.mSampleRate == mSampleRate && bac.mChannelConfig == mChannelConfig
+                    && bac.mAudioFormat == mAudioFormat);
         }
         return false;
     }
@@ -60,23 +59,26 @@
                 + ",mAudioFormat:" + mAudioFormat + "}";
     }
 
+    @Override
     public int describeContents() {
         return 0;
     }
 
     public static final Parcelable.Creator<BluetoothAudioConfig> CREATOR =
             new Parcelable.Creator<BluetoothAudioConfig>() {
-        public BluetoothAudioConfig createFromParcel(Parcel in) {
-            int sampleRate = in.readInt();
-            int channelConfig = in.readInt();
-            int audioFormat = in.readInt();
-            return new BluetoothAudioConfig(sampleRate, channelConfig, audioFormat);
-        }
-        public BluetoothAudioConfig[] newArray(int size) {
-            return new BluetoothAudioConfig[size];
-        }
-    };
+                public BluetoothAudioConfig createFromParcel(Parcel in) {
+                    int sampleRate = in.readInt();
+                    int channelConfig = in.readInt();
+                    int audioFormat = in.readInt();
+                    return new BluetoothAudioConfig(sampleRate, channelConfig, audioFormat);
+                }
 
+                public BluetoothAudioConfig[] newArray(int size) {
+                    return new BluetoothAudioConfig[size];
+                }
+            };
+
+    @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mSampleRate);
         out.writeInt(mChannelConfig);
@@ -85,6 +87,7 @@
 
     /**
      * Returns the sample rate in samples per second
+     *
      * @return sample rate
      */
     public int getSampleRate() {
@@ -94,6 +97,7 @@
     /**
      * Returns the channel configuration (either {@link android.media.AudioFormat#CHANNEL_IN_MONO}
      * or {@link android.media.AudioFormat#CHANNEL_IN_STEREO})
+     *
      * @return channel configuration
      */
     public int getChannelConfig() {
@@ -103,6 +107,7 @@
     /**
      * Returns the channel audio format (either {@link android.media.AudioFormat#ENCODING_PCM_16BIT}
      * or {@link android.media.AudioFormat#ENCODING_PCM_8BIT}
+     *
      * @return audio format
      */
     public int getAudioFormat() {
diff --git a/core/java/android/bluetooth/BluetoothAvrcp.java b/core/java/android/bluetooth/BluetoothAvrcp.java
index 44fe1b7..1a4c759 100644
--- a/core/java/android/bluetooth/BluetoothAvrcp.java
+++ b/core/java/android/bluetooth/BluetoothAvrcp.java
@@ -26,68 +26,68 @@
     /*
      * State flags for Passthrough commands
     */
-    public static final int PASSTHROUGH_STATE_PRESS    = 0;
-    public static final int PASSTHROUGH_STATE_RELEASE  = 1;
+    public static final int PASSTHROUGH_STATE_PRESS = 0;
+    public static final int PASSTHROUGH_STATE_RELEASE = 1;
 
     /*
      * Operation IDs for Passthrough commands
     */
-    public static final int PASSTHROUGH_ID_SELECT      = 0x00;    /* select */
-    public static final int PASSTHROUGH_ID_UP          = 0x01;    /* up */
-    public static final int PASSTHROUGH_ID_DOWN        = 0x02;    /* down */
-    public static final int PASSTHROUGH_ID_LEFT        = 0x03;    /* left */
-    public static final int PASSTHROUGH_ID_RIGHT       = 0x04;    /* right */
-    public static final int PASSTHROUGH_ID_RIGHT_UP    = 0x05;    /* right-up */
-    public static final int PASSTHROUGH_ID_RIGHT_DOWN  = 0x06;    /* right-down */
-    public static final int PASSTHROUGH_ID_LEFT_UP     = 0x07;    /* left-up */
-    public static final int PASSTHROUGH_ID_LEFT_DOWN   = 0x08;    /* left-down */
-    public static final int PASSTHROUGH_ID_ROOT_MENU   = 0x09;    /* root menu */
-    public static final int PASSTHROUGH_ID_SETUP_MENU  = 0x0A;    /* setup menu */
-    public static final int PASSTHROUGH_ID_CONT_MENU   = 0x0B;    /* contents menu */
-    public static final int PASSTHROUGH_ID_FAV_MENU    = 0x0C;    /* favorite menu */
-    public static final int PASSTHROUGH_ID_EXIT        = 0x0D;    /* exit */
-    public static final int PASSTHROUGH_ID_0           = 0x20;    /* 0 */
-    public static final int PASSTHROUGH_ID_1           = 0x21;    /* 1 */
-    public static final int PASSTHROUGH_ID_2           = 0x22;    /* 2 */
-    public static final int PASSTHROUGH_ID_3           = 0x23;    /* 3 */
-    public static final int PASSTHROUGH_ID_4           = 0x24;    /* 4 */
-    public static final int PASSTHROUGH_ID_5           = 0x25;    /* 5 */
-    public static final int PASSTHROUGH_ID_6           = 0x26;    /* 6 */
-    public static final int PASSTHROUGH_ID_7           = 0x27;    /* 7 */
-    public static final int PASSTHROUGH_ID_8           = 0x28;    /* 8 */
-    public static final int PASSTHROUGH_ID_9           = 0x29;    /* 9 */
-    public static final int PASSTHROUGH_ID_DOT         = 0x2A;    /* dot */
-    public static final int PASSTHROUGH_ID_ENTER       = 0x2B;    /* enter */
-    public static final int PASSTHROUGH_ID_CLEAR       = 0x2C;    /* clear */
-    public static final int PASSTHROUGH_ID_CHAN_UP     = 0x30;    /* channel up */
-    public static final int PASSTHROUGH_ID_CHAN_DOWN   = 0x31;    /* channel down */
-    public static final int PASSTHROUGH_ID_PREV_CHAN   = 0x32;    /* previous channel */
-    public static final int PASSTHROUGH_ID_SOUND_SEL   = 0x33;    /* sound select */
-    public static final int PASSTHROUGH_ID_INPUT_SEL   = 0x34;    /* input select */
-    public static final int PASSTHROUGH_ID_DISP_INFO   = 0x35;    /* display information */
-    public static final int PASSTHROUGH_ID_HELP        = 0x36;    /* help */
-    public static final int PASSTHROUGH_ID_PAGE_UP     = 0x37;    /* page up */
-    public static final int PASSTHROUGH_ID_PAGE_DOWN   = 0x38;    /* page down */
-    public static final int PASSTHROUGH_ID_POWER       = 0x40;    /* power */
-    public static final int PASSTHROUGH_ID_VOL_UP      = 0x41;    /* volume up */
-    public static final int PASSTHROUGH_ID_VOL_DOWN    = 0x42;    /* volume down */
-    public static final int PASSTHROUGH_ID_MUTE        = 0x43;    /* mute */
-    public static final int PASSTHROUGH_ID_PLAY        = 0x44;    /* play */
-    public static final int PASSTHROUGH_ID_STOP        = 0x45;    /* stop */
-    public static final int PASSTHROUGH_ID_PAUSE       = 0x46;    /* pause */
-    public static final int PASSTHROUGH_ID_RECORD      = 0x47;    /* record */
-    public static final int PASSTHROUGH_ID_REWIND      = 0x48;    /* rewind */
-    public static final int PASSTHROUGH_ID_FAST_FOR    = 0x49;    /* fast forward */
-    public static final int PASSTHROUGH_ID_EJECT       = 0x4A;    /* eject */
-    public static final int PASSTHROUGH_ID_FORWARD     = 0x4B;    /* forward */
-    public static final int PASSTHROUGH_ID_BACKWARD    = 0x4C;    /* backward */
-    public static final int PASSTHROUGH_ID_ANGLE       = 0x50;    /* angle */
-    public static final int PASSTHROUGH_ID_SUBPICT     = 0x51;    /* subpicture */
-    public static final int PASSTHROUGH_ID_F1          = 0x71;    /* F1 */
-    public static final int PASSTHROUGH_ID_F2          = 0x72;    /* F2 */
-    public static final int PASSTHROUGH_ID_F3          = 0x73;    /* F3 */
-    public static final int PASSTHROUGH_ID_F4          = 0x74;    /* F4 */
-    public static final int PASSTHROUGH_ID_F5          = 0x75;    /* F5 */
-    public static final int PASSTHROUGH_ID_VENDOR      = 0x7E;    /* vendor unique */
+    public static final int PASSTHROUGH_ID_SELECT = 0x00;    /* select */
+    public static final int PASSTHROUGH_ID_UP = 0x01;    /* up */
+    public static final int PASSTHROUGH_ID_DOWN = 0x02;    /* down */
+    public static final int PASSTHROUGH_ID_LEFT = 0x03;    /* left */
+    public static final int PASSTHROUGH_ID_RIGHT = 0x04;    /* right */
+    public static final int PASSTHROUGH_ID_RIGHT_UP = 0x05;    /* right-up */
+    public static final int PASSTHROUGH_ID_RIGHT_DOWN = 0x06;    /* right-down */
+    public static final int PASSTHROUGH_ID_LEFT_UP = 0x07;    /* left-up */
+    public static final int PASSTHROUGH_ID_LEFT_DOWN = 0x08;    /* left-down */
+    public static final int PASSTHROUGH_ID_ROOT_MENU = 0x09;    /* root menu */
+    public static final int PASSTHROUGH_ID_SETUP_MENU = 0x0A;    /* setup menu */
+    public static final int PASSTHROUGH_ID_CONT_MENU = 0x0B;    /* contents menu */
+    public static final int PASSTHROUGH_ID_FAV_MENU = 0x0C;    /* favorite menu */
+    public static final int PASSTHROUGH_ID_EXIT = 0x0D;    /* exit */
+    public static final int PASSTHROUGH_ID_0 = 0x20;    /* 0 */
+    public static final int PASSTHROUGH_ID_1 = 0x21;    /* 1 */
+    public static final int PASSTHROUGH_ID_2 = 0x22;    /* 2 */
+    public static final int PASSTHROUGH_ID_3 = 0x23;    /* 3 */
+    public static final int PASSTHROUGH_ID_4 = 0x24;    /* 4 */
+    public static final int PASSTHROUGH_ID_5 = 0x25;    /* 5 */
+    public static final int PASSTHROUGH_ID_6 = 0x26;    /* 6 */
+    public static final int PASSTHROUGH_ID_7 = 0x27;    /* 7 */
+    public static final int PASSTHROUGH_ID_8 = 0x28;    /* 8 */
+    public static final int PASSTHROUGH_ID_9 = 0x29;    /* 9 */
+    public static final int PASSTHROUGH_ID_DOT = 0x2A;    /* dot */
+    public static final int PASSTHROUGH_ID_ENTER = 0x2B;    /* enter */
+    public static final int PASSTHROUGH_ID_CLEAR = 0x2C;    /* clear */
+    public static final int PASSTHROUGH_ID_CHAN_UP = 0x30;    /* channel up */
+    public static final int PASSTHROUGH_ID_CHAN_DOWN = 0x31;    /* channel down */
+    public static final int PASSTHROUGH_ID_PREV_CHAN = 0x32;    /* previous channel */
+    public static final int PASSTHROUGH_ID_SOUND_SEL = 0x33;    /* sound select */
+    public static final int PASSTHROUGH_ID_INPUT_SEL = 0x34;    /* input select */
+    public static final int PASSTHROUGH_ID_DISP_INFO = 0x35;    /* display information */
+    public static final int PASSTHROUGH_ID_HELP = 0x36;    /* help */
+    public static final int PASSTHROUGH_ID_PAGE_UP = 0x37;    /* page up */
+    public static final int PASSTHROUGH_ID_PAGE_DOWN = 0x38;    /* page down */
+    public static final int PASSTHROUGH_ID_POWER = 0x40;    /* power */
+    public static final int PASSTHROUGH_ID_VOL_UP = 0x41;    /* volume up */
+    public static final int PASSTHROUGH_ID_VOL_DOWN = 0x42;    /* volume down */
+    public static final int PASSTHROUGH_ID_MUTE = 0x43;    /* mute */
+    public static final int PASSTHROUGH_ID_PLAY = 0x44;    /* play */
+    public static final int PASSTHROUGH_ID_STOP = 0x45;    /* stop */
+    public static final int PASSTHROUGH_ID_PAUSE = 0x46;    /* pause */
+    public static final int PASSTHROUGH_ID_RECORD = 0x47;    /* record */
+    public static final int PASSTHROUGH_ID_REWIND = 0x48;    /* rewind */
+    public static final int PASSTHROUGH_ID_FAST_FOR = 0x49;    /* fast forward */
+    public static final int PASSTHROUGH_ID_EJECT = 0x4A;    /* eject */
+    public static final int PASSTHROUGH_ID_FORWARD = 0x4B;    /* forward */
+    public static final int PASSTHROUGH_ID_BACKWARD = 0x4C;    /* backward */
+    public static final int PASSTHROUGH_ID_ANGLE = 0x50;    /* angle */
+    public static final int PASSTHROUGH_ID_SUBPICT = 0x51;    /* subpicture */
+    public static final int PASSTHROUGH_ID_F1 = 0x71;    /* F1 */
+    public static final int PASSTHROUGH_ID_F2 = 0x72;    /* F2 */
+    public static final int PASSTHROUGH_ID_F3 = 0x73;    /* F3 */
+    public static final int PASSTHROUGH_ID_F4 = 0x74;    /* F4 */
+    public static final int PASSTHROUGH_ID_F5 = 0x75;    /* F5 */
+    public static final int PASSTHROUGH_ID_VENDOR = 0x7E;    /* vendor unique */
     public static final int PASSTHROUGH_KEYPRESSED_RELEASE = 0x80;
 }
diff --git a/core/java/android/bluetooth/BluetoothAvrcpController.java b/core/java/android/bluetooth/BluetoothAvrcpController.java
index 0261b1b..5f0e5d9 100644
--- a/core/java/android/bluetooth/BluetoothAvrcpController.java
+++ b/core/java/android/bluetooth/BluetoothAvrcpController.java
@@ -20,8 +20,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.media.MediaMetadata;
-import android.media.session.PlaybackState;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -34,7 +32,7 @@
  * This class provides the public APIs to control the Bluetooth AVRCP Controller. It currently
  * supports player information, playback support and track metadata.
  *
- *<p>BluetoothAvrcpController is a proxy object for controlling the Bluetooth AVRCP
+ * <p>BluetoothAvrcpController is a proxy object for controlling the Bluetooth AVRCP
  * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
  * the BluetoothAvrcpController proxy object.
  *
@@ -51,9 +49,9 @@
      *
      * <p>This intent will have 3 extras:
      * <ul>
-     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
      * </ul>
      *
      * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -64,61 +62,60 @@
      * receive.
      */
     public static final String ACTION_CONNECTION_STATE_CHANGED =
-        "android.bluetooth.avrcp-controller.profile.action.CONNECTION_STATE_CHANGED";
+            "android.bluetooth.avrcp-controller.profile.action.CONNECTION_STATE_CHANGED";
 
     /**
      * Intent used to broadcast the change in player application setting state on AVRCP AG.
      *
      * <p>This intent will have the following extras:
      * <ul>
-     *    <li> {@link #EXTRA_PLAYER_SETTING} - {@link BluetoothAvrcpPlayerSettings} containing the
-     *    most recent player setting. </li>
+     * <li> {@link #EXTRA_PLAYER_SETTING} - {@link BluetoothAvrcpPlayerSettings} containing the
+     * most recent player setting. </li>
      * </ul>
      */
     public static final String ACTION_PLAYER_SETTING =
-        "android.bluetooth.avrcp-controller.profile.action.PLAYER_SETTING";
+            "android.bluetooth.avrcp-controller.profile.action.PLAYER_SETTING";
 
     public static final String EXTRA_PLAYER_SETTING =
             "android.bluetooth.avrcp-controller.profile.extra.PLAYER_SETTING";
 
     private Context mContext;
     private ServiceListener mServiceListener;
-    private IBluetoothAvrcpController mService;
+    private volatile IBluetoothAvrcpController mService;
     private BluetoothAdapter mAdapter;
 
-    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
-        new IBluetoothStateChangeCallback.Stub() {
-            public void onBluetoothStateChange(boolean up) {
-                if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
-                if (!up) {
-                    if (VDBG) Log.d(TAG,"Unbinding service...");
-                    synchronized (mConnection) {
-                        try {
-                            mService = null;
-                            mContext.unbindService(mConnection);
-                        } catch (Exception re) {
-                            Log.e(TAG,"",re);
-                        }
-                    }
-                } else {
-                    synchronized (mConnection) {
-                        try {
-                            if (mService == null) {
-                                if (VDBG) Log.d(TAG,"Binding service...");
-                                doBind();
+    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+            new IBluetoothStateChangeCallback.Stub() {
+                public void onBluetoothStateChange(boolean up) {
+                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
+                    if (!up) {
+                        if (VDBG) Log.d(TAG, "Unbinding service...");
+                        synchronized (mConnection) {
+                            try {
+                                mService = null;
+                                mContext.unbindService(mConnection);
+                            } catch (Exception re) {
+                                Log.e(TAG, "", re);
                             }
-                        } catch (Exception re) {
-                            Log.e(TAG,"",re);
+                        }
+                    } else {
+                        synchronized (mConnection) {
+                            try {
+                                if (mService == null) {
+                                    if (VDBG) Log.d(TAG, "Binding service...");
+                                    doBind();
+                                }
+                            } catch (Exception re) {
+                                Log.e(TAG, "", re);
+                            }
                         }
                     }
                 }
-            }
-      };
+            };
 
     /**
      * Create a BluetoothAvrcpController proxy object for interacting with the local
      * Bluetooth AVRCP service.
-     *
      */
     /*package*/ BluetoothAvrcpController(Context context, ServiceListener l) {
         mContext = context;
@@ -129,7 +126,7 @@
             try {
                 mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (RemoteException e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -155,7 +152,7 @@
             try {
                 mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (Exception e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -165,12 +162,13 @@
                     mService = null;
                     mContext.unbindService(mConnection);
                 } catch (Exception re) {
-                    Log.e(TAG,"",re);
+                    Log.e(TAG, "", re);
                 }
             }
         }
     }
 
+    @Override
     public void finalize() {
         close();
     }
@@ -178,52 +176,57 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public List<BluetoothDevice> getConnectedDevices() {
         if (VDBG) log("getConnectedDevices()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothAvrcpController service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getConnectedDevices();
+                return service.getConnectedDevices();
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         if (VDBG) log("getDevicesMatchingStates()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothAvrcpController service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getDevicesMatchingConnectionStates(states);
+                return service.getDevicesMatchingConnectionStates(states);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public int getConnectionState(BluetoothDevice device) {
         if (VDBG) log("getState(" + device + ")");
-        if (mService != null && isEnabled()
-            && isValidDevice(device)) {
+        final IBluetoothAvrcpController service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getConnectionState(device);
+                return service.getConnectionState(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.STATE_DISCONNECTED;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return BluetoothProfile.STATE_DISCONNECTED;
     }
 
@@ -235,9 +238,10 @@
     public BluetoothAvrcpPlayerSettings getPlayerSettings(BluetoothDevice device) {
         if (DBG) Log.d(TAG, "getPlayerSettings");
         BluetoothAvrcpPlayerSettings settings = null;
-        if (mService != null && isEnabled()) {
+        final IBluetoothAvrcpController service = mService;
+        if (service != null && isEnabled()) {
             try {
-                settings = mService.getPlayerSettings(device);
+                settings = service.getPlayerSettings(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Error talking to BT service in getMetadata() " + e);
                 return null;
@@ -252,46 +256,49 @@
      */
     public boolean setPlayerApplicationSetting(BluetoothAvrcpPlayerSettings plAppSetting) {
         if (DBG) Log.d(TAG, "setPlayerApplicationSetting");
-        if (mService != null && isEnabled()) {
+        final IBluetoothAvrcpController service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.setPlayerApplicationSetting(plAppSetting);
+                return service.setPlayerApplicationSetting(plAppSetting);
             } catch (RemoteException e) {
                 Log.e(TAG, "Error talking to BT service in setPlayerApplicationSetting() " + e);
                 return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
-    /*
+    /**
      * Send Group Navigation Command to Remote.
      * possible keycode values: next_grp, previous_grp defined above
      */
     public void sendGroupNavigationCmd(BluetoothDevice device, int keyCode, int keyState) {
-        Log.d(TAG, "sendGroupNavigationCmd dev = " + device + " key " + keyCode + " State = " + keyState);
-        if (mService != null && isEnabled()) {
+        Log.d(TAG, "sendGroupNavigationCmd dev = " + device + " key " + keyCode + " State = "
+                + keyState);
+        final IBluetoothAvrcpController service = mService;
+        if (service != null && isEnabled()) {
             try {
-                mService.sendGroupNavigationCmd(device, keyCode, keyState);
+                service.sendGroupNavigationCmd(device, keyCode, keyState);
                 return;
             } catch (RemoteException e) {
                 Log.e(TAG, "Error talking to BT service in sendGroupNavigationCmd()", e);
                 return;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
     }
 
     private final ServiceConnection mConnection = new ServiceConnection() {
         public void onServiceConnected(ComponentName className, IBinder service) {
             if (DBG) Log.d(TAG, "Proxy object connected");
             mService = IBluetoothAvrcpController.Stub.asInterface(Binder.allowBlocking(service));
-
             if (mServiceListener != null) {
                 mServiceListener.onServiceConnected(BluetoothProfile.AVRCP_CONTROLLER,
                         BluetoothAvrcpController.this);
             }
         }
+
         public void onServiceDisconnected(ComponentName className) {
             if (DBG) Log.d(TAG, "Proxy object disconnected");
             mService = null;
@@ -302,18 +309,14 @@
     };
 
     private boolean isEnabled() {
-       if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
-       return false;
+        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
     }
 
-    private boolean isValidDevice(BluetoothDevice device) {
-       if (device == null) return false;
-
-       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-       return false;
+    private static boolean isValidDevice(BluetoothDevice device) {
+        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
     }
 
     private static void log(String msg) {
-      Log.d(TAG, msg);
+        Log.d(TAG, msg);
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothAvrcpPlayerSettings.java b/core/java/android/bluetooth/BluetoothAvrcpPlayerSettings.java
index 927cb56..3d3d80e 100644
--- a/core/java/android/bluetooth/BluetoothAvrcpPlayerSettings.java
+++ b/core/java/android/bluetooth/BluetoothAvrcpPlayerSettings.java
@@ -34,22 +34,22 @@
     /**
      * Equalizer setting.
      */
-    public static final int SETTING_EQUALIZER    = 0x01;
+    public static final int SETTING_EQUALIZER = 0x01;
 
     /**
      * Repeat setting.
      */
-    public static final int SETTING_REPEAT       = 0x02;
+    public static final int SETTING_REPEAT = 0x02;
 
     /**
      * Shuffle setting.
      */
-    public static final int SETTING_SHUFFLE      = 0x04;
+    public static final int SETTING_SHUFFLE = 0x04;
 
     /**
      * Scan mode setting.
      */
-    public static final int SETTING_SCAN         = 0x08;
+    public static final int SETTING_SCAN = 0x08;
 
     /**
      * Invalid state.
@@ -82,16 +82,16 @@
     /**
      * All track repeat/shuffle.
      *
-     * Applies to {@link SETTING_REPEAT}, {@link SETTING_SHUFFLE} and {@link SETTING_SCAN}.
+     * Applies to {@link #SETTING_REPEAT}, {@link #SETTING_SHUFFLE} and {@link #SETTING_SCAN}.
      */
-    public static final int STATE_ALL_TRACK    = 0x03;
+    public static final int STATE_ALL_TRACK = 0x03;
 
     /**
      * Group repeat/shuffle.
      *
-     * Applies to {@link SETTING_REPEAT}, {@link SETTING_SHUFFLE} and {@link SETTING_SCAN}.
+     * Applies to {@link #SETTING_REPEAT}, {@link #SETTING_SHUFFLE} and {@link #SETTING_SCAN}.
      */
-    public static final int STATE_GROUP        = 0x04;
+    public static final int STATE_GROUP = 0x04;
 
     /**
      * List of supported settings ORed.
@@ -103,10 +103,12 @@
      */
     private Map<Integer, Integer> mSettingsValue = new HashMap<Integer, Integer>();
 
+    @Override
     public int describeContents() {
         return 0;
     }
 
+    @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mSettings);
         out.writeInt(mSettingsValue.size());
@@ -116,8 +118,8 @@
         }
     }
 
-    public static final Parcelable.Creator<BluetoothAvrcpPlayerSettings> CREATOR
-            = new Parcelable.Creator<BluetoothAvrcpPlayerSettings>() {
+    public static final Parcelable.Creator<BluetoothAvrcpPlayerSettings> CREATOR =
+            new Parcelable.Creator<BluetoothAvrcpPlayerSettings>() {
         public BluetoothAvrcpPlayerSettings createFromParcel(Parcel in) {
             return new BluetoothAvrcpPlayerSettings(in);
         }
@@ -157,6 +159,7 @@
      * Add a setting value.
      *
      * The setting must be part of possible settings in {@link getSettings()}.
+     *
      * @param setting setting config.
      * @param value value for the setting.
      * @throws IllegalStateException if the setting is not supported.
@@ -173,6 +176,7 @@
      * Get a setting value.
      *
      * The setting must be part of possible settings in {@link getSettings()}.
+     *
      * @param setting setting config.
      * @return value value for the setting.
      * @throws IllegalStateException if the setting is not supported.
diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java
index 4a38287..f22ea6e 100755
--- a/core/java/android/bluetooth/BluetoothClass.java
+++ b/core/java/android/bluetooth/BluetoothClass.java
@@ -19,6 +19,10 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
 /**
  * Represents a Bluetooth class, which describes general characteristics
  * and capabilities of a device. For example, a Bluetooth class will
@@ -51,6 +55,7 @@
 public final class BluetoothClass implements Parcelable {
     /**
      * Legacy error value. Applications should use null instead.
+     *
      * @hide
      */
     public static final int ERROR = 0xFF000000;
@@ -65,7 +70,7 @@
     @Override
     public boolean equals(Object o) {
         if (o instanceof BluetoothClass) {
-            return mClass == ((BluetoothClass)o).mClass;
+            return mClass == ((BluetoothClass) o).mClass;
         }
         return false;
     }
@@ -80,20 +85,23 @@
         return Integer.toHexString(mClass);
     }
 
+    @Override
     public int describeContents() {
         return 0;
     }
 
     public static final Parcelable.Creator<BluetoothClass> CREATOR =
             new Parcelable.Creator<BluetoothClass>() {
-        public BluetoothClass createFromParcel(Parcel in) {
-            return new BluetoothClass(in.readInt());
-        }
-        public BluetoothClass[] newArray(int size) {
-            return new BluetoothClass[size];
-        }
-    };
+                public BluetoothClass createFromParcel(Parcel in) {
+                    return new BluetoothClass(in.readInt());
+                }
 
+                public BluetoothClass[] newArray(int size) {
+                    return new BluetoothClass[size];
+                }
+            };
+
+    @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mClass);
     }
@@ -103,17 +111,17 @@
      * <p>Each {@link BluetoothClass} encodes zero or more service classes.
      */
     public static final class Service {
-        private static final int BITMASK                 = 0xFFE000;
+        private static final int BITMASK = 0xFFE000;
 
         public static final int LIMITED_DISCOVERABILITY = 0x002000;
-        public static final int POSITIONING             = 0x010000;
-        public static final int NETWORKING              = 0x020000;
-        public static final int RENDER                  = 0x040000;
-        public static final int CAPTURE                 = 0x080000;
-        public static final int OBJECT_TRANSFER         = 0x100000;
-        public static final int AUDIO                   = 0x200000;
-        public static final int TELEPHONY               = 0x400000;
-        public static final int INFORMATION             = 0x800000;
+        public static final int POSITIONING = 0x010000;
+        public static final int NETWORKING = 0x020000;
+        public static final int RENDER = 0x040000;
+        public static final int CAPTURE = 0x080000;
+        public static final int OBJECT_TRANSFER = 0x100000;
+        public static final int AUDIO = 0x200000;
+        public static final int TELEPHONY = 0x400000;
+        public static final int INFORMATION = 0x800000;
     }
 
     /**
@@ -141,91 +149,91 @@
      * <p>See {@link BluetoothClass.Service} for service class constants.
      */
     public static class Device {
-        private static final int BITMASK               = 0x1FFC;
+        private static final int BITMASK = 0x1FFC;
 
         /**
          * Defines all major device class constants.
          * <p>See {@link BluetoothClass.Device} for minor classes.
          */
         public static class Major {
-            private static final int BITMASK           = 0x1F00;
+            private static final int BITMASK = 0x1F00;
 
-            public static final int MISC              = 0x0000;
-            public static final int COMPUTER          = 0x0100;
-            public static final int PHONE             = 0x0200;
-            public static final int NETWORKING        = 0x0300;
-            public static final int AUDIO_VIDEO       = 0x0400;
-            public static final int PERIPHERAL        = 0x0500;
-            public static final int IMAGING           = 0x0600;
-            public static final int WEARABLE          = 0x0700;
-            public static final int TOY               = 0x0800;
-            public static final int HEALTH            = 0x0900;
-            public static final int UNCATEGORIZED     = 0x1F00;
+            public static final int MISC = 0x0000;
+            public static final int COMPUTER = 0x0100;
+            public static final int PHONE = 0x0200;
+            public static final int NETWORKING = 0x0300;
+            public static final int AUDIO_VIDEO = 0x0400;
+            public static final int PERIPHERAL = 0x0500;
+            public static final int IMAGING = 0x0600;
+            public static final int WEARABLE = 0x0700;
+            public static final int TOY = 0x0800;
+            public static final int HEALTH = 0x0900;
+            public static final int UNCATEGORIZED = 0x1F00;
         }
 
         // Devices in the COMPUTER major class
-        public static final int COMPUTER_UNCATEGORIZED              = 0x0100;
-        public static final int COMPUTER_DESKTOP                    = 0x0104;
-        public static final int COMPUTER_SERVER                     = 0x0108;
-        public static final int COMPUTER_LAPTOP                     = 0x010C;
-        public static final int COMPUTER_HANDHELD_PC_PDA            = 0x0110;
-        public static final int COMPUTER_PALM_SIZE_PC_PDA           = 0x0114;
-        public static final int COMPUTER_WEARABLE                   = 0x0118;
+        public static final int COMPUTER_UNCATEGORIZED = 0x0100;
+        public static final int COMPUTER_DESKTOP = 0x0104;
+        public static final int COMPUTER_SERVER = 0x0108;
+        public static final int COMPUTER_LAPTOP = 0x010C;
+        public static final int COMPUTER_HANDHELD_PC_PDA = 0x0110;
+        public static final int COMPUTER_PALM_SIZE_PC_PDA = 0x0114;
+        public static final int COMPUTER_WEARABLE = 0x0118;
 
         // Devices in the PHONE major class
-        public static final int PHONE_UNCATEGORIZED                 = 0x0200;
-        public static final int PHONE_CELLULAR                      = 0x0204;
-        public static final int PHONE_CORDLESS                      = 0x0208;
-        public static final int PHONE_SMART                         = 0x020C;
-        public static final int PHONE_MODEM_OR_GATEWAY              = 0x0210;
-        public static final int PHONE_ISDN                          = 0x0214;
+        public static final int PHONE_UNCATEGORIZED = 0x0200;
+        public static final int PHONE_CELLULAR = 0x0204;
+        public static final int PHONE_CORDLESS = 0x0208;
+        public static final int PHONE_SMART = 0x020C;
+        public static final int PHONE_MODEM_OR_GATEWAY = 0x0210;
+        public static final int PHONE_ISDN = 0x0214;
 
         // Minor classes for the AUDIO_VIDEO major class
-        public static final int AUDIO_VIDEO_UNCATEGORIZED           = 0x0400;
-        public static final int AUDIO_VIDEO_WEARABLE_HEADSET        = 0x0404;
-        public static final int AUDIO_VIDEO_HANDSFREE               = 0x0408;
+        public static final int AUDIO_VIDEO_UNCATEGORIZED = 0x0400;
+        public static final int AUDIO_VIDEO_WEARABLE_HEADSET = 0x0404;
+        public static final int AUDIO_VIDEO_HANDSFREE = 0x0408;
         //public static final int AUDIO_VIDEO_RESERVED              = 0x040C;
-        public static final int AUDIO_VIDEO_MICROPHONE              = 0x0410;
-        public static final int AUDIO_VIDEO_LOUDSPEAKER             = 0x0414;
-        public static final int AUDIO_VIDEO_HEADPHONES              = 0x0418;
-        public static final int AUDIO_VIDEO_PORTABLE_AUDIO          = 0x041C;
-        public static final int AUDIO_VIDEO_CAR_AUDIO               = 0x0420;
-        public static final int AUDIO_VIDEO_SET_TOP_BOX             = 0x0424;
-        public static final int AUDIO_VIDEO_HIFI_AUDIO              = 0x0428;
-        public static final int AUDIO_VIDEO_VCR                     = 0x042C;
-        public static final int AUDIO_VIDEO_VIDEO_CAMERA            = 0x0430;
-        public static final int AUDIO_VIDEO_CAMCORDER               = 0x0434;
-        public static final int AUDIO_VIDEO_VIDEO_MONITOR           = 0x0438;
+        public static final int AUDIO_VIDEO_MICROPHONE = 0x0410;
+        public static final int AUDIO_VIDEO_LOUDSPEAKER = 0x0414;
+        public static final int AUDIO_VIDEO_HEADPHONES = 0x0418;
+        public static final int AUDIO_VIDEO_PORTABLE_AUDIO = 0x041C;
+        public static final int AUDIO_VIDEO_CAR_AUDIO = 0x0420;
+        public static final int AUDIO_VIDEO_SET_TOP_BOX = 0x0424;
+        public static final int AUDIO_VIDEO_HIFI_AUDIO = 0x0428;
+        public static final int AUDIO_VIDEO_VCR = 0x042C;
+        public static final int AUDIO_VIDEO_VIDEO_CAMERA = 0x0430;
+        public static final int AUDIO_VIDEO_CAMCORDER = 0x0434;
+        public static final int AUDIO_VIDEO_VIDEO_MONITOR = 0x0438;
         public static final int AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER = 0x043C;
-        public static final int AUDIO_VIDEO_VIDEO_CONFERENCING      = 0x0440;
+        public static final int AUDIO_VIDEO_VIDEO_CONFERENCING = 0x0440;
         //public static final int AUDIO_VIDEO_RESERVED              = 0x0444;
-        public static final int AUDIO_VIDEO_VIDEO_GAMING_TOY        = 0x0448;
+        public static final int AUDIO_VIDEO_VIDEO_GAMING_TOY = 0x0448;
 
         // Devices in the WEARABLE major class
-        public static final int WEARABLE_UNCATEGORIZED              = 0x0700;
-        public static final int WEARABLE_WRIST_WATCH                = 0x0704;
-        public static final int WEARABLE_PAGER                      = 0x0708;
-        public static final int WEARABLE_JACKET                     = 0x070C;
-        public static final int WEARABLE_HELMET                     = 0x0710;
-        public static final int WEARABLE_GLASSES                    = 0x0714;
+        public static final int WEARABLE_UNCATEGORIZED = 0x0700;
+        public static final int WEARABLE_WRIST_WATCH = 0x0704;
+        public static final int WEARABLE_PAGER = 0x0708;
+        public static final int WEARABLE_JACKET = 0x070C;
+        public static final int WEARABLE_HELMET = 0x0710;
+        public static final int WEARABLE_GLASSES = 0x0714;
 
         // Devices in the TOY major class
-        public static final int TOY_UNCATEGORIZED                   = 0x0800;
-        public static final int TOY_ROBOT                           = 0x0804;
-        public static final int TOY_VEHICLE                         = 0x0808;
-        public static final int TOY_DOLL_ACTION_FIGURE              = 0x080C;
-        public static final int TOY_CONTROLLER                      = 0x0810;
-        public static final int TOY_GAME                            = 0x0814;
+        public static final int TOY_UNCATEGORIZED = 0x0800;
+        public static final int TOY_ROBOT = 0x0804;
+        public static final int TOY_VEHICLE = 0x0808;
+        public static final int TOY_DOLL_ACTION_FIGURE = 0x080C;
+        public static final int TOY_CONTROLLER = 0x0810;
+        public static final int TOY_GAME = 0x0814;
 
         // Devices in the HEALTH major class
-        public static final int HEALTH_UNCATEGORIZED                = 0x0900;
-        public static final int HEALTH_BLOOD_PRESSURE               = 0x0904;
-        public static final int HEALTH_THERMOMETER                  = 0x0908;
-        public static final int HEALTH_WEIGHING                     = 0x090C;
-        public static final int HEALTH_GLUCOSE                      = 0x0910;
-        public static final int HEALTH_PULSE_OXIMETER               = 0x0914;
-        public static final int HEALTH_PULSE_RATE                   = 0x0918;
-        public static final int HEALTH_DATA_DISPLAY                 = 0x091C;
+        public static final int HEALTH_UNCATEGORIZED = 0x0900;
+        public static final int HEALTH_BLOOD_PRESSURE = 0x0904;
+        public static final int HEALTH_THERMOMETER = 0x0908;
+        public static final int HEALTH_WEIGHING = 0x090C;
+        public static final int HEALTH_GLUCOSE = 0x0910;
+        public static final int HEALTH_PULSE_OXIMETER = 0x0914;
+        public static final int HEALTH_PULSE_RATE = 0x0918;
+        public static final int HEALTH_DATA_DISPLAY = 0x091C;
 
         // Devices in PERIPHERAL major class
         /**
@@ -235,15 +243,15 @@
         /**
          * @hide
          */
-        public static final int PERIPHERAL_KEYBOARD                  = 0x0540;
+        public static final int PERIPHERAL_KEYBOARD = 0x0540;
         /**
          * @hide
          */
-        public static final int PERIPHERAL_POINTING                  = 0x0580;
+        public static final int PERIPHERAL_POINTING = 0x0580;
         /**
          * @hide
          */
-        public static final int PERIPHERAL_KEYBOARD_POINTING         = 0x05C0;
+        public static final int PERIPHERAL_KEYBOARD_POINTING = 0x05C0;
     }
 
     /**
@@ -271,6 +279,48 @@
         return (mClass & Device.BITMASK);
     }
 
+    /**
+     * Return the Bluetooth Class of Device (CoD) value including the
+     * {@link BluetoothClass.Service}, {@link BluetoothClass.Device.Major} and
+     * minor device fields.
+     *
+     * <p>This value is an integer representation of Bluetooth CoD as in
+     * Bluetooth specification.
+     *
+     * @see <a href="Bluetooth CoD">https://www.bluetooth.com/specifications/assigned-numbers/baseband</a>
+     *
+     * @hide
+     */
+    public int getClassOfDevice() {
+        return mClass;
+    }
+
+    /**
+     * Return the Bluetooth Class of Device (CoD) value including the
+     * {@link BluetoothClass.Service}, {@link BluetoothClass.Device.Major} and
+     * minor device fields.
+     *
+     * <p>This value is a byte array representation of Bluetooth CoD as in
+     * Bluetooth specification.
+     *
+     * <p>Bluetooth COD information is 3 bytes, but stored as an int. Hence the
+     * MSB is useless and needs to be thrown away. The lower 3 bytes are
+     * converted into a byte array MSB to LSB. Hence, using BIG_ENDIAN.
+     *
+     * @see <a href="Bluetooth CoD">https://www.bluetooth.com/specifications/assigned-numbers/baseband</a>
+     *
+     * @hide
+     */
+    public byte[] getClassOfDeviceBytes() {
+        byte[] bytes = ByteBuffer.allocate(4)
+                .order(ByteOrder.BIG_ENDIAN)
+                .putInt(mClass)
+                .array();
+
+        // Discard the top byte
+        return Arrays.copyOfRange(bytes, 1, bytes.length);
+    }
+
     /** @hide */
     public static final int PROFILE_HEADSET = 0;
     /** @hide */
@@ -291,6 +341,7 @@
      * This is a simple heuristic that tries to guess if a device with the
      * given class bits might support specified profile. It is not accurate for all
      * devices. It tries to err on the side of false positives.
+     *
      * @param profile The profile to be checked
      * @return True if this device might support specified profile.
      * @hide
@@ -322,7 +373,7 @@
             switch (getDeviceClass()) {
                 case Device.AUDIO_VIDEO_HIFI_AUDIO:
                 case Device.AUDIO_VIDEO_SET_TOP_BOX:
-                case Device.AUDIO_VIDEO_VCR :
+                case Device.AUDIO_VIDEO_VCR:
                     return true;
                 default:
                     return false;
@@ -367,7 +418,7 @@
             }
         } else if (profile == PROFILE_HID) {
             return (getDeviceClass() & Device.Major.PERIPHERAL) == Device.Major.PERIPHERAL;
-        } else if (profile == PROFILE_PANU || profile == PROFILE_NAP){
+        } else if (profile == PROFILE_PANU || profile == PROFILE_NAP) {
             // No good way to distinguish between the two, based on class bits.
             if (hasService(Service.NETWORKING)) {
                 return true;
diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java
index d5e1429..e3a6e06 100644
--- a/core/java/android/bluetooth/BluetoothCodecConfig.java
+++ b/core/java/android/bluetooth/BluetoothCodecConfig.java
@@ -32,12 +32,12 @@
     // Add an entry for each source codec here.
     // NOTE: The values should be same as those listed in the following file:
     //   hardware/libhardware/include/hardware/bt_av.h
-    public static final int SOURCE_CODEC_TYPE_SBC     = 0;
-    public static final int SOURCE_CODEC_TYPE_AAC     = 1;
-    public static final int SOURCE_CODEC_TYPE_APTX    = 2;
+    public static final int SOURCE_CODEC_TYPE_SBC = 0;
+    public static final int SOURCE_CODEC_TYPE_AAC = 1;
+    public static final int SOURCE_CODEC_TYPE_APTX = 2;
     public static final int SOURCE_CODEC_TYPE_APTX_HD = 3;
-    public static final int SOURCE_CODEC_TYPE_LDAC    = 4;
-    public static final int SOURCE_CODEC_TYPE_MAX     = 5;
+    public static final int SOURCE_CODEC_TYPE_LDAC = 4;
+    public static final int SOURCE_CODEC_TYPE_MAX = 5;
 
     public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
 
@@ -45,21 +45,21 @@
     public static final int CODEC_PRIORITY_DEFAULT = 0;
     public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000;
 
-    public static final int SAMPLE_RATE_NONE   = 0;
-    public static final int SAMPLE_RATE_44100  = 0x1 << 0;
-    public static final int SAMPLE_RATE_48000  = 0x1 << 1;
-    public static final int SAMPLE_RATE_88200  = 0x1 << 2;
-    public static final int SAMPLE_RATE_96000  = 0x1 << 3;
+    public static final int SAMPLE_RATE_NONE = 0;
+    public static final int SAMPLE_RATE_44100 = 0x1 << 0;
+    public static final int SAMPLE_RATE_48000 = 0x1 << 1;
+    public static final int SAMPLE_RATE_88200 = 0x1 << 2;
+    public static final int SAMPLE_RATE_96000 = 0x1 << 3;
     public static final int SAMPLE_RATE_176400 = 0x1 << 4;
     public static final int SAMPLE_RATE_192000 = 0x1 << 5;
 
     public static final int BITS_PER_SAMPLE_NONE = 0;
-    public static final int BITS_PER_SAMPLE_16   = 0x1 << 0;
-    public static final int BITS_PER_SAMPLE_24   = 0x1 << 1;
-    public static final int BITS_PER_SAMPLE_32   = 0x1 << 2;
+    public static final int BITS_PER_SAMPLE_16 = 0x1 << 0;
+    public static final int BITS_PER_SAMPLE_24 = 0x1 << 1;
+    public static final int BITS_PER_SAMPLE_32 = 0x1 << 2;
 
-    public static final int CHANNEL_MODE_NONE   = 0;
-    public static final int CHANNEL_MODE_MONO   = 0x1 << 0;
+    public static final int CHANNEL_MODE_NONE = 0;
+    public static final int CHANNEL_MODE_MONO = 0x1 << 0;
     public static final int CHANNEL_MODE_STEREO = 0x1 << 1;
 
     private final int mCodecType;
@@ -73,10 +73,10 @@
     private final long mCodecSpecific4;
 
     public BluetoothCodecConfig(int codecType, int codecPriority,
-                                int sampleRate, int bitsPerSample,
-                                int channelMode, long codecSpecific1,
-                                long codecSpecific2, long codecSpecific3,
-                                long codecSpecific4) {
+            int sampleRate, int bitsPerSample,
+            int channelMode, long codecSpecific1,
+            long codecSpecific2, long codecSpecific3,
+            long codecSpecific4) {
         mCodecType = codecType;
         mCodecPriority = codecPriority;
         mSampleRate = sampleRate;
@@ -91,16 +91,16 @@
     @Override
     public boolean equals(Object o) {
         if (o instanceof BluetoothCodecConfig) {
-            BluetoothCodecConfig other = (BluetoothCodecConfig)o;
-            return (other.mCodecType == mCodecType &&
-                    other.mCodecPriority == mCodecPriority &&
-                    other.mSampleRate == mSampleRate &&
-                    other.mBitsPerSample == mBitsPerSample &&
-                    other.mChannelMode == mChannelMode &&
-                    other.mCodecSpecific1 == mCodecSpecific1 &&
-                    other.mCodecSpecific2 == mCodecSpecific2 &&
-                    other.mCodecSpecific3 == mCodecSpecific3 &&
-                    other.mCodecSpecific4 == mCodecSpecific4);
+            BluetoothCodecConfig other = (BluetoothCodecConfig) o;
+            return (other.mCodecType == mCodecType
+                    && other.mCodecPriority == mCodecPriority
+                    && other.mSampleRate == mSampleRate
+                    && other.mBitsPerSample == mBitsPerSample
+                    && other.mChannelMode == mChannelMode
+                    && other.mCodecSpecific1 == mCodecSpecific1
+                    && other.mCodecSpecific2 == mCodecSpecific2
+                    && other.mCodecSpecific3 == mCodecSpecific3
+                    && other.mCodecSpecific4 == mCodecSpecific4);
         }
         return false;
     }
@@ -108,32 +108,30 @@
     @Override
     public int hashCode() {
         return Objects.hash(mCodecType, mCodecPriority, mSampleRate,
-                            mBitsPerSample, mChannelMode, mCodecSpecific1,
-                            mCodecSpecific2, mCodecSpecific3, mCodecSpecific4);
+                mBitsPerSample, mChannelMode, mCodecSpecific1,
+                mCodecSpecific2, mCodecSpecific3, mCodecSpecific4);
     }
 
     /**
      * Checks whether the object contains valid codec configuration.
      *
-     * @return true if the object contains valid codec configuration,
-     * otherwise false.
+     * @return true if the object contains valid codec configuration, otherwise false.
      */
     public boolean isValid() {
-        return (mSampleRate != SAMPLE_RATE_NONE) &&
-            (mBitsPerSample != BITS_PER_SAMPLE_NONE) &&
-            (mChannelMode != CHANNEL_MODE_NONE);
+        return (mSampleRate != SAMPLE_RATE_NONE)
+                && (mBitsPerSample != BITS_PER_SAMPLE_NONE)
+                && (mChannelMode != CHANNEL_MODE_NONE);
     }
 
     /**
      * Adds capability string to an existing string.
      *
-     * @param prevStr the previous string with the capabilities. Can be
-     * a null pointer.
+     * @param prevStr the previous string with the capabilities. Can be a null pointer.
      * @param capStr the capability string to append to prevStr argument.
      * @return the result string in the form "prevStr|capStr".
      */
     private static String appendCapabilityToString(String prevStr,
-                                                   String capStr) {
+            String capStr) {
         if (prevStr == null) {
             return capStr;
         }
@@ -190,48 +188,51 @@
             channelModeStr = appendCapabilityToString(channelModeStr, "STEREO");
         }
 
-        return "{codecName:" + getCodecName() +
-            ",mCodecType:" + mCodecType +
-            ",mCodecPriority:" + mCodecPriority +
-            ",mSampleRate:" + String.format("0x%x", mSampleRate) +
-            "(" + sampleRateStr + ")" +
-            ",mBitsPerSample:" + String.format("0x%x", mBitsPerSample) +
-            "(" + bitsPerSampleStr + ")" +
-            ",mChannelMode:" + String.format("0x%x", mChannelMode) +
-            "(" + channelModeStr + ")" +
-            ",mCodecSpecific1:" + mCodecSpecific1 +
-            ",mCodecSpecific2:" + mCodecSpecific2 +
-            ",mCodecSpecific3:" + mCodecSpecific3 +
-            ",mCodecSpecific4:" + mCodecSpecific4 + "}";
+        return "{codecName:" + getCodecName()
+                + ",mCodecType:" + mCodecType
+                + ",mCodecPriority:" + mCodecPriority
+                + ",mSampleRate:" + String.format("0x%x", mSampleRate)
+                + "(" + sampleRateStr + ")"
+                + ",mBitsPerSample:" + String.format("0x%x", mBitsPerSample)
+                + "(" + bitsPerSampleStr + ")"
+                + ",mChannelMode:" + String.format("0x%x", mChannelMode)
+                + "(" + channelModeStr + ")"
+                + ",mCodecSpecific1:" + mCodecSpecific1
+                + ",mCodecSpecific2:" + mCodecSpecific2
+                + ",mCodecSpecific3:" + mCodecSpecific3
+                + ",mCodecSpecific4:" + mCodecSpecific4 + "}";
     }
 
+    @Override
     public int describeContents() {
         return 0;
     }
 
     public static final Parcelable.Creator<BluetoothCodecConfig> CREATOR =
             new Parcelable.Creator<BluetoothCodecConfig>() {
-        public BluetoothCodecConfig createFromParcel(Parcel in) {
-            final int codecType = in.readInt();
-            final int codecPriority = in.readInt();
-            final int sampleRate = in.readInt();
-            final int bitsPerSample = in.readInt();
-            final int channelMode = in.readInt();
-            final long codecSpecific1 = in.readLong();
-            final long codecSpecific2 = in.readLong();
-            final long codecSpecific3 = in.readLong();
-            final long codecSpecific4 = in.readLong();
-            return new BluetoothCodecConfig(codecType, codecPriority,
-                                            sampleRate, bitsPerSample,
-                                            channelMode, codecSpecific1,
-                                            codecSpecific2, codecSpecific3,
-                                            codecSpecific4);
-        }
-        public BluetoothCodecConfig[] newArray(int size) {
-            return new BluetoothCodecConfig[size];
-        }
-    };
+                public BluetoothCodecConfig createFromParcel(Parcel in) {
+                    final int codecType = in.readInt();
+                    final int codecPriority = in.readInt();
+                    final int sampleRate = in.readInt();
+                    final int bitsPerSample = in.readInt();
+                    final int channelMode = in.readInt();
+                    final long codecSpecific1 = in.readLong();
+                    final long codecSpecific2 = in.readLong();
+                    final long codecSpecific3 = in.readLong();
+                    final long codecSpecific4 = in.readLong();
+                    return new BluetoothCodecConfig(codecType, codecPriority,
+                            sampleRate, bitsPerSample,
+                            channelMode, codecSpecific1,
+                            codecSpecific2, codecSpecific3,
+                            codecSpecific4);
+                }
 
+                public BluetoothCodecConfig[] newArray(int size) {
+                    return new BluetoothCodecConfig[size];
+                }
+            };
+
+    @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mCodecType);
         out.writeInt(mCodecPriority);
@@ -251,20 +252,20 @@
      */
     public String getCodecName() {
         switch (mCodecType) {
-        case SOURCE_CODEC_TYPE_SBC:
-            return "SBC";
-        case SOURCE_CODEC_TYPE_AAC:
-            return "AAC";
-        case SOURCE_CODEC_TYPE_APTX:
-            return "aptX";
-        case SOURCE_CODEC_TYPE_APTX_HD:
-            return "aptX HD";
-        case SOURCE_CODEC_TYPE_LDAC:
-            return "LDAC";
-        case SOURCE_CODEC_TYPE_INVALID:
-            return "INVALID CODEC";
-        default:
-            break;
+            case SOURCE_CODEC_TYPE_SBC:
+                return "SBC";
+            case SOURCE_CODEC_TYPE_AAC:
+                return "AAC";
+            case SOURCE_CODEC_TYPE_APTX:
+                return "aptX";
+            case SOURCE_CODEC_TYPE_APTX_HD:
+                return "aptX HD";
+            case SOURCE_CODEC_TYPE_LDAC:
+                return "LDAC";
+            case SOURCE_CODEC_TYPE_INVALID:
+                return "INVALID CODEC";
+            default:
+                break;
         }
         return "UNKNOWN CODEC(" + mCodecType + ")";
     }
@@ -397,8 +398,8 @@
      * @return true if the audio feeding parameters are same, otherwise false
      */
     public boolean sameAudioFeedingParameters(BluetoothCodecConfig other) {
-        return (other != null && other.mSampleRate == mSampleRate &&
-                other.mBitsPerSample == mBitsPerSample &&
-                other.mChannelMode == mChannelMode);
+        return (other != null && other.mSampleRate == mSampleRate
+                && other.mBitsPerSample == mBitsPerSample
+                && other.mChannelMode == mChannelMode);
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothCodecStatus.java b/core/java/android/bluetooth/BluetoothCodecStatus.java
index c8cd8d1..7ae4cb7 100644
--- a/core/java/android/bluetooth/BluetoothCodecStatus.java
+++ b/core/java/android/bluetooth/BluetoothCodecStatus.java
@@ -38,15 +38,15 @@
      * profile.
      */
     public static final String EXTRA_CODEC_STATUS =
-        "android.bluetooth.codec.extra.CODEC_STATUS";
+            "android.bluetooth.codec.extra.CODEC_STATUS";
 
     private final BluetoothCodecConfig mCodecConfig;
     private final BluetoothCodecConfig[] mCodecsLocalCapabilities;
     private final BluetoothCodecConfig[] mCodecsSelectableCapabilities;
 
     public BluetoothCodecStatus(BluetoothCodecConfig codecConfig,
-                                BluetoothCodecConfig[] codecsLocalCapabilities,
-                                BluetoothCodecConfig[] codecsSelectableCapabilities) {
+            BluetoothCodecConfig[] codecsLocalCapabilities,
+            BluetoothCodecConfig[] codecsSelectableCapabilities) {
         mCodecConfig = codecConfig;
         mCodecsLocalCapabilities = codecsLocalCapabilities;
         mCodecsSelectableCapabilities = codecsSelectableCapabilities;
@@ -55,12 +55,11 @@
     @Override
     public boolean equals(Object o) {
         if (o instanceof BluetoothCodecStatus) {
-            BluetoothCodecStatus other = (BluetoothCodecStatus)o;
-            return (Objects.equals(other.mCodecConfig, mCodecConfig) &&
-                    Objects.equals(other.mCodecsLocalCapabilities,
-                                   mCodecsLocalCapabilities) &&
-                    Objects.equals(other.mCodecsSelectableCapabilities,
-                                   mCodecsSelectableCapabilities));
+            BluetoothCodecStatus other = (BluetoothCodecStatus) o;
+            return (Objects.equals(other.mCodecConfig, mCodecConfig)
+                    && Objects.equals(other.mCodecsLocalCapabilities, mCodecsLocalCapabilities)
+                    && Objects.equals(other.mCodecsSelectableCapabilities,
+                    mCodecsSelectableCapabilities));
         }
         return false;
     }
@@ -68,37 +67,43 @@
     @Override
     public int hashCode() {
         return Objects.hash(mCodecConfig, mCodecsLocalCapabilities,
-                            mCodecsLocalCapabilities);
+                mCodecsLocalCapabilities);
     }
 
     @Override
     public String toString() {
-        return "{mCodecConfig:" + mCodecConfig +
-            ",mCodecsLocalCapabilities:" + Arrays.toString(mCodecsLocalCapabilities) +
-            ",mCodecsSelectableCapabilities:" + Arrays.toString(mCodecsSelectableCapabilities) +
-            "}";
+        return "{mCodecConfig:" + mCodecConfig
+                + ",mCodecsLocalCapabilities:" + Arrays.toString(mCodecsLocalCapabilities)
+                + ",mCodecsSelectableCapabilities:" + Arrays.toString(mCodecsSelectableCapabilities)
+                + "}";
     }
 
+    @Override
     public int describeContents() {
         return 0;
     }
 
     public static final Parcelable.Creator<BluetoothCodecStatus> CREATOR =
             new Parcelable.Creator<BluetoothCodecStatus>() {
-        public BluetoothCodecStatus createFromParcel(Parcel in) {
-            final BluetoothCodecConfig codecConfig = in.readTypedObject(BluetoothCodecConfig.CREATOR);
-            final BluetoothCodecConfig[] codecsLocalCapabilities = in.createTypedArray(BluetoothCodecConfig.CREATOR);
-            final BluetoothCodecConfig[] codecsSelectableCapabilities = in.createTypedArray(BluetoothCodecConfig.CREATOR);
+                public BluetoothCodecStatus createFromParcel(Parcel in) {
+                    final BluetoothCodecConfig codecConfig = in.readTypedObject(
+                            BluetoothCodecConfig.CREATOR);
+                    final BluetoothCodecConfig[] codecsLocalCapabilities = in.createTypedArray(
+                            BluetoothCodecConfig.CREATOR);
+                    final BluetoothCodecConfig[] codecsSelectableCapabilities = in.createTypedArray(
+                            BluetoothCodecConfig.CREATOR);
 
-            return new BluetoothCodecStatus(codecConfig,
-                                            codecsLocalCapabilities,
-                                            codecsSelectableCapabilities);
-        }
-        public BluetoothCodecStatus[] newArray(int size) {
-            return new BluetoothCodecStatus[size];
-        }
-    };
+                    return new BluetoothCodecStatus(codecConfig,
+                            codecsLocalCapabilities,
+                            codecsSelectableCapabilities);
+                }
 
+                public BluetoothCodecStatus[] newArray(int size) {
+                    return new BluetoothCodecStatus[size];
+                }
+            };
+
+    @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeTypedObject(mCodecConfig, 0);
         out.writeTypedArray(mCodecsLocalCapabilities, 0);
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index a206b53..d982bb7 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -23,10 +23,9 @@
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.os.Handler;
-import android.os.Looper;
 import android.os.Parcel;
-import android.os.Parcelable;
 import android.os.ParcelUuid;
+import android.os.Parcelable;
 import android.os.Process;
 import android.os.RemoteException;
 import android.util.Log;
@@ -101,7 +100,7 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} and
      * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} to receive.
      */
-     // TODO: Change API to not broadcast RSSI if not available (incoming connection)
+    // TODO: Change API to not broadcast RSSI if not available (incoming connection)
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_FOUND =
             "android.bluetooth.device.action.FOUND";
@@ -112,6 +111,7 @@
      * found in the current discovery.
      * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     *
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@@ -208,6 +208,7 @@
      * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
      * #EXTRA_BATTERY_LEVEL}.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     *
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@@ -219,6 +220,7 @@
      * intent. It contains the most recently retrieved battery level information
      * ranging from 0% to 100% for a remote device, {@link #BATTERY_LEVEL_UNKNOWN}
      * when the valid is unknown or there is an error
+     *
      * @hide
      */
     public static final String EXTRA_BATTERY_LEVEL =
@@ -226,6 +228,7 @@
 
     /**
      * Used as the unknown value for {@link #EXTRA_BATTERY_LEVEL} and {@link #getBatteryLevel()}
+     *
      * @hide
      */
     public static final int BATTERY_LEVEL_UNKNOWN = -1;
@@ -300,6 +303,7 @@
     /**
      * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
      * intents for unbond reason.
+     *
      * @hide
      */
     public static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON";
@@ -368,6 +372,7 @@
      * device.
      * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     *
      * @hide
      */
     //TODO: is this actually useful?
@@ -405,26 +410,28 @@
 
     /**
      * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intent.
+     *
      * @hide
      */
     public static final String EXTRA_ACCESS_REQUEST_TYPE =
-        "android.bluetooth.device.extra.ACCESS_REQUEST_TYPE";
+            "android.bluetooth.device.extra.ACCESS_REQUEST_TYPE";
 
-    /**@hide*/
+    /** @hide */
     public static final int REQUEST_TYPE_PROFILE_CONNECTION = 1;
 
-    /**@hide*/
+    /** @hide */
     public static final int REQUEST_TYPE_PHONEBOOK_ACCESS = 2;
 
-    /**@hide*/
+    /** @hide */
     public static final int REQUEST_TYPE_MESSAGE_ACCESS = 3;
 
-    /**@hide*/
+    /** @hide */
     public static final int REQUEST_TYPE_SIM_ACCESS = 4;
 
     /**
      * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intents,
      * Contains package name to return reply intent to.
+     *
      * @hide
      */
     public static final String EXTRA_PACKAGE_NAME = "android.bluetooth.device.extra.PACKAGE_NAME";
@@ -432,34 +439,38 @@
     /**
      * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intents,
      * Contains class name to return reply intent to.
+     *
      * @hide
      */
     public static final String EXTRA_CLASS_NAME = "android.bluetooth.device.extra.CLASS_NAME";
 
     /**
      * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REPLY} intent.
+     *
      * @hide
      */
     public static final String EXTRA_CONNECTION_ACCESS_RESULT =
-        "android.bluetooth.device.extra.CONNECTION_ACCESS_RESULT";
+            "android.bluetooth.device.extra.CONNECTION_ACCESS_RESULT";
 
-    /**@hide*/
+    /** @hide */
     public static final int CONNECTION_ACCESS_YES = 1;
 
-    /**@hide*/
+    /** @hide */
     public static final int CONNECTION_ACCESS_NO = 2;
 
     /**
      * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REPLY} intents,
      * Contains boolean to indicate if the allowed response is once-for-all so that
      * next request will be granted without asking user again.
+     *
      * @hide
      */
     public static final String EXTRA_ALWAYS_ALLOWED =
-        "android.bluetooth.device.extra.ALWAYS_ALLOWED";
+            "android.bluetooth.device.extra.ALWAYS_ALLOWED";
 
     /**
      * A bond attempt succeeded
+     *
      * @hide
      */
     public static final int BOND_SUCCESS = 0;
@@ -467,6 +478,7 @@
     /**
      * A bond attempt failed because pins did not match, or remote device did
      * not respond to pin request in time
+     *
      * @hide
      */
     public static final int UNBOND_REASON_AUTH_FAILED = 1;
@@ -474,36 +486,42 @@
     /**
      * A bond attempt failed because the other side explicitly rejected
      * bonding
+     *
      * @hide
      */
     public static final int UNBOND_REASON_AUTH_REJECTED = 2;
 
     /**
      * A bond attempt failed because we canceled the bonding process
+     *
      * @hide
      */
     public static final int UNBOND_REASON_AUTH_CANCELED = 3;
 
     /**
      * A bond attempt failed because we could not contact the remote device
+     *
      * @hide
      */
     public static final int UNBOND_REASON_REMOTE_DEVICE_DOWN = 4;
 
     /**
      * A bond attempt failed because a discovery is in progress
+     *
      * @hide
      */
     public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
 
     /**
      * A bond attempt failed because of authentication timeout
+     *
      * @hide
      */
     public static final int UNBOND_REASON_AUTH_TIMEOUT = 6;
 
     /**
      * A bond attempt failed because of repeated attempts
+     *
      * @hide
      */
     public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7;
@@ -511,12 +529,14 @@
     /**
      * A bond attempt failed because we received an Authentication Cancel
      * by remote end
+     *
      * @hide
      */
     public static final int UNBOND_REASON_REMOTE_AUTH_CANCELED = 8;
 
     /**
      * An existing bond was explicitly revoked
+     *
      * @hide
      */
     public static final int UNBOND_REASON_REMOVED = 9;
@@ -529,6 +549,7 @@
 
     /**
      * The user will be prompted to enter a passkey
+     *
      * @hide
      */
     public static final int PAIRING_VARIANT_PASSKEY = 1;
@@ -541,6 +562,7 @@
 
     /**
      * The user will be prompted to accept or deny the incoming pairing request
+     *
      * @hide
      */
     public static final int PAIRING_VARIANT_CONSENT = 3;
@@ -548,6 +570,7 @@
     /**
      * The user will be prompted to enter the passkey displayed on remote device
      * This is used for Bluetooth 2.1 pairing.
+     *
      * @hide
      */
     public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
@@ -555,12 +578,14 @@
     /**
      * The user will be prompted to enter the PIN displayed on remote device.
      * This is used for Bluetooth 2.0 pairing.
+     *
      * @hide
      */
     public static final int PAIRING_VARIANT_DISPLAY_PIN = 5;
 
     /**
      * The user will be prompted to accept or deny the OOB pairing request
+     *
      * @hide
      */
     public static final int PAIRING_VARIANT_OOB_CONSENT = 6;
@@ -568,6 +593,7 @@
     /**
      * The user will be prompted to enter a 16 digit pin or
      * an app will enter a 16 digit pin for user.
+     *
      * @hide
      */
     public static final int PAIRING_VARIANT_PIN_16_DIGITS = 7;
@@ -581,7 +607,7 @@
 
     /** @hide */
     public static final String EXTRA_SDP_RECORD =
-        "android.bluetooth.device.extra.SDP_RECORD";
+            "android.bluetooth.device.extra.SDP_RECORD";
 
     /** @hide */
     public static final String EXTRA_SDP_SEARCH_STATUS =
@@ -589,6 +615,7 @@
     /**
      * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
      * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
+     *
      * @hide
      */
     public static final int ACCESS_UNKNOWN = 0;
@@ -596,6 +623,7 @@
     /**
      * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
      * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
+     *
      * @hide
      */
     public static final int ACCESS_ALLOWED = 1;
@@ -603,13 +631,14 @@
     /**
      * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
      * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
+     *
      * @hide
      */
     public static final int ACCESS_REJECTED = 2;
 
-     /**
-      * No preferrence of physical transport for GATT connections to remote dual-mode devices
-      */
+    /**
+     * No preferrence of physical transport for GATT connections to remote dual-mode devices
+     */
     public static final int TRANSPORT_AUTO = 0;
 
     /**
@@ -676,28 +705,29 @@
 
     /** @hide */
     public static final String EXTRA_MAS_INSTANCE =
-        "android.bluetooth.device.extra.MAS_INSTANCE";
+            "android.bluetooth.device.extra.MAS_INSTANCE";
 
     /**
      * Lazy initialization. Guaranteed final after first object constructed, or
      * getService() called.
      * TODO: Unify implementation of sService amongst BluetoothFoo API's
      */
-    private static IBluetooth sService;
+    private static volatile IBluetooth sService;
 
     private final String mAddress;
 
-    /*package*/ static IBluetooth getService() {
+    /*package*/
+    static IBluetooth getService() {
         synchronized (BluetoothDevice.class) {
             if (sService == null) {
                 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-                sService = adapter.getBluetoothService(mStateChangeCallback);
+                sService = adapter.getBluetoothService(sStateChangeCallback);
             }
         }
         return sService;
     }
 
-    static IBluetoothManagerCallback mStateChangeCallback = new IBluetoothManagerCallback.Stub() {
+    static IBluetoothManagerCallback sStateChangeCallback = new IBluetoothManagerCallback.Stub() {
 
         public void onBluetoothServiceUp(IBluetooth bluetoothService)
                 throws RemoteException {
@@ -709,21 +739,22 @@
         }
 
         public void onBluetoothServiceDown()
-            throws RemoteException {
+                throws RemoteException {
             synchronized (BluetoothDevice.class) {
                 sService = null;
             }
         }
 
-        public void onBrEdrDown()
-        {
+        public void onBrEdrDown() {
             if (DBG) Log.d(TAG, "onBrEdrDown: reached BLE ON state");
         }
     };
+
     /**
      * Create a new BluetoothDevice
      * Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB",
      * and is validated in this constructor.
+     *
      * @param address valid Bluetooth MAC address
      * @throws RuntimeException Bluetooth is not available on this platform
      * @throws IllegalArgumentException address is invalid
@@ -741,7 +772,7 @@
     @Override
     public boolean equals(Object o) {
         if (o instanceof BluetoothDevice) {
-            return mAddress.equals(((BluetoothDevice)o).getAddress());
+            return mAddress.equals(((BluetoothDevice) o).getAddress());
         }
         return false;
     }
@@ -757,6 +788,7 @@
      * "00:11:22:AA:BB:CC". However, you should always use {@link #getAddress}
      * if you explicitly require the Bluetooth hardware address in case the
      * {@link #toString} representation changes in the future.
+     *
      * @return string representation of this BluetoothDevice
      */
     @Override
@@ -764,20 +796,23 @@
         return mAddress;
     }
 
+    @Override
     public int describeContents() {
         return 0;
     }
 
     public static final Parcelable.Creator<BluetoothDevice> CREATOR =
             new Parcelable.Creator<BluetoothDevice>() {
-        public BluetoothDevice createFromParcel(Parcel in) {
-            return new BluetoothDevice(in.readString());
-        }
-        public BluetoothDevice[] newArray(int size) {
-            return new BluetoothDevice[size];
-        }
-    };
+                public BluetoothDevice createFromParcel(Parcel in) {
+                    return new BluetoothDevice(in.readString());
+                }
 
+                public BluetoothDevice[] newArray(int size) {
+                    return new BluetoothDevice[size];
+                }
+            };
+
+    @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeString(mAddress);
     }
@@ -785,6 +820,7 @@
     /**
      * Returns the hardware address of this BluetoothDevice.
      * <p> For example, "00:11:22:AA:BB:CC".
+     *
      * @return Bluetooth hardware address as string
      */
     public String getAddress() {
@@ -803,32 +839,37 @@
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public String getName() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot get Remote Device name");
             return null;
         }
         try {
-            return sService.getRemoteName(this);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            return service.getRemoteName(this);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return null;
     }
 
     /**
      * Get the Bluetooth device type of the remote device.
      *
-     * @return the device type {@link #DEVICE_TYPE_CLASSIC}, {@link #DEVICE_TYPE_LE}
-     *                         {@link #DEVICE_TYPE_DUAL}.
-     *         {@link #DEVICE_TYPE_UNKNOWN} if it's not available
+     * @return the device type {@link #DEVICE_TYPE_CLASSIC}, {@link #DEVICE_TYPE_LE} {@link
+     * #DEVICE_TYPE_DUAL}. {@link #DEVICE_TYPE_UNKNOWN} if it's not available
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public int getType() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot get Remote Device type");
             return DEVICE_TYPE_UNKNOWN;
         }
         try {
-            return sService.getRemoteType(this);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            return service.getRemoteType(this);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return DEVICE_TYPE_UNKNOWN;
     }
 
@@ -840,13 +881,16 @@
      * @hide
      */
     public String getAlias() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot get Remote Device Alias");
             return null;
         }
         try {
-            return sService.getRemoteAlias(this);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            return service.getRemoteAlias(this);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return null;
     }
 
@@ -861,24 +905,27 @@
      * @hide
      */
     public boolean setAlias(String alias) {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot set Remote Device name");
             return false;
         }
         try {
-            return sService.setRemoteAlias(this, alias);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            return service.setRemoteAlias(this, alias);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return false;
     }
 
     /**
      * Get the Bluetooth alias of the remote device.
      * If Alias is null, get the Bluetooth name instead.
-     * @see #getAlias()
-     * @see #getName()
      *
      * @return the Bluetooth alias, or null if no alias or there was a problem
      * @hide
+     * @see #getAlias()
+     * @see #getName()
      */
     public String getAliasName() {
         String name = getAlias();
@@ -893,19 +940,22 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
      * @return Battery level in percents from 0 to 100, or {@link #BATTERY_LEVEL_UNKNOWN} if
-     *         Bluetooth is disabled, or device is disconnected, or does not have any battery
-     *         reporting service, or return value is invalid
+     * Bluetooth is disabled, or device is disconnected, or does not have any battery reporting
+     * service, or return value is invalid
      * @hide
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public int getBatteryLevel() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             Log.e(TAG, "Bluetooth disabled. Cannot get remote device battery level");
             return BATTERY_LEVEL_UNKNOWN;
         }
         try {
-            return sService.getBatteryLevel(this);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            return service.getBatteryLevel(this);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return BATTERY_LEVEL_UNKNOWN;
     }
 
@@ -921,16 +971,19 @@
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
     public boolean createBond() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
             return false;
         }
         try {
-            Log.i(TAG, "createBond() for device " + getAddress() +
-                    " called by pid: " + Process.myPid() +
-                    " tid: " + Process.myTid());
-            return sService.createBond(this, TRANSPORT_AUTO);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            Log.i(TAG, "createBond() for device " + getAddress()
+                    + " called by pid: " + Process.myPid()
+                    + " tid: " + Process.myTid());
+            return service.createBond(this, TRANSPORT_AUTO);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return false;
     }
 
@@ -951,20 +1004,22 @@
      * @hide
      */
     public boolean createBond(int transport) {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
             return false;
         }
-        if (TRANSPORT_AUTO > transport || transport > TRANSPORT_LE)
-        {
+        if (TRANSPORT_AUTO > transport || transport > TRANSPORT_LE) {
             throw new IllegalArgumentException(transport + " is not a valid Bluetooth transport");
         }
         try {
-            Log.i(TAG, "createBond() for device " + getAddress() +
-                    " called by pid: " + Process.myPid() +
-                    " tid: " + Process.myTid());
-            return sService.createBond(this, transport);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            Log.i(TAG, "createBond() for device " + getAddress()
+                    + " called by pid: " + Process.myPid()
+                    + " tid: " + Process.myTid());
+            return service.createBond(this, transport);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return false;
     }
 
@@ -984,21 +1039,34 @@
      * @param transport - Transport to use
      * @param oobData - Out Of Band data
      * @return false on immediate error, true if bonding will begin
-     *
      * @hide
      */
     public boolean createBondOutOfBand(int transport, OobData oobData) {
+        final IBluetooth service = sService;
+        if (service == null) {
+            Log.w(TAG, "BT not enabled, createBondOutOfBand failed");
+            return false;
+        }
         try {
-            return sService.createBondOutOfBand(this, transport, oobData);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            return service.createBondOutOfBand(this, transport, oobData);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return false;
     }
 
     /** @hide */
     public boolean isBondingInitiatedLocally() {
+        final IBluetooth service = sService;
+        if (service == null) {
+            Log.w(TAG, "BT not enabled, isBondingInitiatedLocally failed");
+            return false;
+        }
         try {
-            return sService.isBondingInitiatedLocally(this);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            return service.isBondingInitiatedLocally(this);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return false;
     }
 
@@ -1012,16 +1080,15 @@
      * @param hash Simple Secure pairing hash
      * @param randomizer The random key obtained using OOB
      * @return false on error; true otherwise
-     *
      * @hide
      */
     public boolean setDeviceOutOfBandData(byte[] hash, byte[] randomizer) {
-      //TODO(BT)
+        //TODO(BT)
       /*
       try {
         return sService.setDeviceOutOfBandData(this, hash, randomizer);
       } catch (RemoteException e) {Log.e(TAG, "", e);} */
-      return false;
+        return false;
     }
 
     /**
@@ -1032,16 +1099,19 @@
      * @hide
      */
     public boolean cancelBondProcess() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot cancel Remote Device bond");
             return false;
         }
         try {
-            Log.i(TAG, "cancelBondProcess() for device " + getAddress() +
-                    " called by pid: " + Process.myPid() +
-                    " tid: " + Process.myTid());
-            return sService.cancelBondProcess(this);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            Log.i(TAG, "cancelBondProcess() for device " + getAddress()
+                    + " called by pid: " + Process.myPid()
+                    + " tid: " + Process.myTid());
+            return service.cancelBondProcess(this);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return false;
     }
 
@@ -1056,16 +1126,19 @@
      * @hide
      */
     public boolean removeBond() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot remove Remote Device bond");
             return false;
         }
         try {
-            Log.i(TAG, "removeBond() for device " + getAddress() +
-                    " called by pid: " + Process.myPid() +
-                    " tid: " + Process.myTid());
-            return sService.removeBond(this);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            Log.i(TAG, "removeBond() for device " + getAddress()
+                    + " called by pid: " + Process.myPid()
+                    + " tid: " + Process.myTid());
+            return service.removeBond(this);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return false;
     }
 
@@ -1080,18 +1153,15 @@
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public int getBondState() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot get bond state");
             return BOND_NONE;
         }
         try {
-            return sService.getBondState(this);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
-        catch (NullPointerException npe) {
-            // Handle case where bluetooth service proxy
-            // is already null.
-            Log.e(TAG, "NullPointerException for getBondState() of device ("+
-                getAddress()+")", npe);
+            return service.getBondState(this);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
         }
         return BOND_NONE;
     }
@@ -1105,12 +1175,13 @@
      */
     @SystemApi
     public boolean isConnected() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             // BT is not enabled, we cannot be connected.
             return false;
         }
         try {
-            return sService.getConnectionState(this) != CONNECTION_STATE_DISCONNECTED;
+            return service.getConnectionState(this) != CONNECTION_STATE_DISCONNECTED;
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
             return false;
@@ -1127,12 +1198,13 @@
      */
     @SystemApi
     public boolean isEncrypted() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             // BT is not enabled, we cannot be connected.
             return false;
         }
         try {
-            return sService.getConnectionState(this) > CONNECTION_STATE_CONNECTED;
+            return service.getConnectionState(this) > CONNECTION_STATE_CONNECTED;
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
             return false;
@@ -1146,15 +1218,18 @@
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public BluetoothClass getBluetoothClass() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot get Bluetooth Class");
             return null;
         }
         try {
-            int classInt = sService.getRemoteClass(this);
+            int classInt = service.getRemoteClass(this);
             if (classInt == BluetoothClass.ERROR) return null;
             return new BluetoothClass(classInt);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return null;
     }
 
@@ -1166,95 +1241,103 @@
      * UUIDs are returned.
      * <p>Use {@link #fetchUuidsWithSdp} if fresh UUIDs are desired.
      *
-     * @return the supported features (UUIDs) of the remote device,
-     *         or null on error
+     * @return the supported features (UUIDs) of the remote device, or null on error
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
-     public ParcelUuid[] getUuids() {
-         if (sService == null || isBluetoothEnabled() == false) {
+    public ParcelUuid[] getUuids() {
+        final IBluetooth service = sService;
+        if (service == null || !isBluetoothEnabled()) {
             Log.e(TAG, "BT not enabled. Cannot get remote device Uuids");
-             return null;
-         }
+            return null;
+        }
         try {
-            return sService.getRemoteUuids(this);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            return service.getRemoteUuids(this);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return null;
     }
 
-     /**
-      * Perform a service discovery on the remote device to get the UUIDs supported.
-      *
-      * <p>This API is asynchronous and {@link #ACTION_UUID} intent is sent,
-      * with the UUIDs supported by the remote end. If there is an error
-      * in getting the SDP records or if the process takes a long time,
-      * {@link #ACTION_UUID} intent is sent with the UUIDs that is currently
-      * present in the cache. Clients should use the {@link #getUuids} to get UUIDs
-      * if service discovery is not to be performed.
-      *
-      * @return False if the sanity check fails, True if the process
-      *               of initiating an ACL connection to the remote device
-      *               was started.
-      */
-     @RequiresPermission(Manifest.permission.BLUETOOTH)
-     public boolean fetchUuidsWithSdp() {
-        IBluetooth service = sService;
-        if (service == null || isBluetoothEnabled() == false) {
+    /**
+     * Perform a service discovery on the remote device to get the UUIDs supported.
+     *
+     * <p>This API is asynchronous and {@link #ACTION_UUID} intent is sent,
+     * with the UUIDs supported by the remote end. If there is an error
+     * in getting the SDP records or if the process takes a long time,
+     * {@link #ACTION_UUID} intent is sent with the UUIDs that is currently
+     * present in the cache. Clients should use the {@link #getUuids} to get UUIDs
+     * if service discovery is not to be performed.
+     *
+     * @return False if the sanity check fails, True if the process of initiating an ACL connection
+     * to the remote device was started.
+     */
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    public boolean fetchUuidsWithSdp() {
+        final IBluetooth service = sService;
+        if (service == null || !isBluetoothEnabled()) {
             Log.e(TAG, "BT not enabled. Cannot fetchUuidsWithSdp");
             return false;
         }
         try {
             return service.fetchRemoteUuids(this);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
-            return false;
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
+        return false;
     }
 
-     /**
-      * Perform a service discovery on the remote device to get the SDP records associated
-      * with the specified UUID.
-      *
-      * <p>This API is asynchronous and {@link #ACTION_SDP_RECORD} intent is sent,
-      * with the SDP records found on the remote end. If there is an error
-      * in getting the SDP records or if the process takes a long time,
-      * {@link #ACTION_SDP_RECORD} intent is sent with an status value in
-      * {@link #EXTRA_SDP_SEARCH_STATUS} different from 0.
-      * Detailed status error codes can be found by members of the Bluetooth package in
-      * the AbstractionLayer class.
-      * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
-      * The SDP record data will be stored in the intent as {@link #EXTRA_SDP_RECORD}.
-      * The object type will match one of the SdpXxxRecord types, depending on the UUID searched
-      * for.
-      *
-      * @return False if the sanity check fails, True if the process
-      *               of initiating an ACL connection to the remote device
-      *               was started.
-      */
-     /** @hide */
-     public boolean sdpSearch(ParcelUuid uuid) {
-         if (sService == null) {
-             Log.e(TAG, "BT not enabled. Cannot query remote device sdp records");
-             return false;
-         }
-         try {
-             return sService.sdpSearch(this,uuid);
-         } catch (RemoteException e) {Log.e(TAG, "", e);}
-         return false;
-     }
+    /**
+     * Perform a service discovery on the remote device to get the SDP records associated
+     * with the specified UUID.
+     *
+     * <p>This API is asynchronous and {@link #ACTION_SDP_RECORD} intent is sent,
+     * with the SDP records found on the remote end. If there is an error
+     * in getting the SDP records or if the process takes a long time,
+     * {@link #ACTION_SDP_RECORD} intent is sent with an status value in
+     * {@link #EXTRA_SDP_SEARCH_STATUS} different from 0.
+     * Detailed status error codes can be found by members of the Bluetooth package in
+     * the AbstractionLayer class.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
+     * The SDP record data will be stored in the intent as {@link #EXTRA_SDP_RECORD}.
+     * The object type will match one of the SdpXxxRecord types, depending on the UUID searched
+     * for.
+     *
+     * @return False if the sanity check fails, True if the process
+     *               of initiating an ACL connection to the remote device
+     *               was started.
+     */
+    /** @hide */
+    public boolean sdpSearch(ParcelUuid uuid) {
+        final IBluetooth service = sService;
+        if (service == null) {
+            Log.e(TAG, "BT not enabled. Cannot query remote device sdp records");
+            return false;
+        }
+        try {
+            return service.sdpSearch(this, uuid);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
+        return false;
+    }
 
     /**
      * Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN}
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
      *
-     * @return true pin has been set
-     *         false for error
+     * @return true pin has been set false for error
      */
     public boolean setPin(byte[] pin) {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot set Remote Device pin");
             return false;
         }
         try {
-            return sService.setPin(this, true, pin.length, pin);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            return service.setPin(this, true, pin.length, pin);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return false;
     }
 
@@ -1271,18 +1354,20 @@
     /**
      * Confirm passkey for {@link #PAIRING_VARIANT_PASSKEY_CONFIRMATION} pairing.
      *
-     * @return true confirmation has been sent out
-     *         false for error
+     * @return true confirmation has been sent out false for error
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setPairingConfirmation(boolean confirm) {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot set pairing confirmation");
             return false;
         }
         try {
-            return sService.setPairingConfirmation(this, confirm);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            return service.setPairingConfirmation(this, confirm);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return false;
     }
 
@@ -1293,18 +1378,21 @@
         try {
           return sService.setRemoteOutOfBandData(this);
       } catch (RemoteException e) {Log.e(TAG, "", e);}*/
-      return false;
+        return false;
     }
 
     /** @hide */
     public boolean cancelPairingUserInput() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot create pairing user input");
             return false;
         }
         try {
-            return sService.cancelBondProcess(this);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            return service.cancelBondProcess(this);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return false;
     }
 
@@ -1318,27 +1406,29 @@
         return false;
     }
 
-     boolean isBluetoothEnabled() {
-         boolean ret = false;
-         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-         if (adapter != null && adapter.isEnabled() == true) {
-             ret = true;
-         }
-         return ret;
-     }
+    boolean isBluetoothEnabled() {
+        boolean ret = false;
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        if (adapter != null && adapter.isEnabled()) {
+            ret = true;
+        }
+        return ret;
+    }
 
     /**
      * Requires {@link android.Manifest.permission#BLUETOOTH}.
-     * @return Whether the phonebook access is allowed to this device. Can be
-     *         {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
+     *
+     * @return Whether the phonebook access is allowed to this device. Can be {@link
+     * #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
      * @hide
      */
     public int getPhonebookAccessPermission() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             return ACCESS_UNKNOWN;
         }
         try {
-            return sService.getPhonebookAccessPermission(this);
+            return service.getPhonebookAccessPermission(this);
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
         }
@@ -1348,17 +1438,19 @@
     /**
      * Sets whether the phonebook access is allowed to this device.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
-     * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or
-     *              {@link #ACCESS_REJECTED}.
+     *
+     * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link
+     * #ACCESS_REJECTED}.
      * @return Whether the value has been successfully set.
      * @hide
      */
     public boolean setPhonebookAccessPermission(int value) {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             return false;
         }
         try {
-            return sService.setPhonebookAccessPermission(this, value);
+            return service.setPhonebookAccessPermission(this, value);
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
         }
@@ -1367,16 +1459,18 @@
 
     /**
      * Requires {@link android.Manifest.permission#BLUETOOTH}.
-     * @return Whether the message access is allowed to this device. Can be
-     *         {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
+     *
+     * @return Whether the message access is allowed to this device. Can be {@link #ACCESS_UNKNOWN},
+     * {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
      * @hide
      */
     public int getMessageAccessPermission() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             return ACCESS_UNKNOWN;
         }
         try {
-            return sService.getMessageAccessPermission(this);
+            return service.getMessageAccessPermission(this);
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
         }
@@ -1386,17 +1480,19 @@
     /**
      * Sets whether the message access is allowed to this device.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
-     * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or
-     *              {@link #ACCESS_REJECTED}.
+     *
+     * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link
+     * #ACCESS_REJECTED}.
      * @return Whether the value has been successfully set.
      * @hide
      */
     public boolean setMessageAccessPermission(int value) {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             return false;
         }
         try {
-            return sService.setMessageAccessPermission(this, value);
+            return service.setMessageAccessPermission(this, value);
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
         }
@@ -1405,16 +1501,18 @@
 
     /**
      * Requires {@link android.Manifest.permission#BLUETOOTH}.
-     * @return Whether the Sim access is allowed to this device. Can be
-     *         {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
+     *
+     * @return Whether the Sim access is allowed to this device. Can be {@link #ACCESS_UNKNOWN},
+     * {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
      * @hide
      */
     public int getSimAccessPermission() {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             return ACCESS_UNKNOWN;
         }
         try {
-            return sService.getSimAccessPermission(this);
+            return service.getSimAccessPermission(this);
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
         }
@@ -1424,17 +1522,19 @@
     /**
      * Sets whether the Sim access is allowed to this device.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
-     * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or
-     *              {@link #ACCESS_REJECTED}.
+     *
+     * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link
+     * #ACCESS_REJECTED}.
      * @return Whether the value has been successfully set.
      * @hide
      */
     public boolean setSimAccessPermission(int value) {
-        if (sService == null) {
+        final IBluetooth service = sService;
+        if (service == null) {
             return false;
         }
         try {
-            return sService.setSimAccessPermission(this, value);
+            return service.setSimAccessPermission(this, value);
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
         }
@@ -1462,12 +1562,12 @@
      *
      * @param channel RFCOMM channel to connect to
      * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
-     * @throws IOException on error, for example Bluetooth not available, or
-     *                     insufficient permissions
+     * @throws IOException on error, for example Bluetooth not available, or insufficient
+     * permissions
      * @hide
      */
     public BluetoothSocket createRfcommSocket(int channel) throws IOException {
-        if (isBluetoothEnabled() == false) {
+        if (!isBluetoothEnabled()) {
             Log.e(TAG, "Bluetooth is not enabled");
             throw new IOException();
         }
@@ -1496,8 +1596,8 @@
      *
      * @param channel L2cap PSM/channel to connect to
      * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
-     * @throws IOException on error, for example Bluetooth not available, or
-     *                     insufficient permissions
+     * @throws IOException on error, for example Bluetooth not available, or insufficient
+     * permissions
      * @hide
      */
     public BluetoothSocket createL2capSocket(int channel) throws IOException {
@@ -1517,8 +1617,8 @@
      *
      * @param channel L2cap PSM/channel to connect to
      * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
-     * @throws IOException on error, for example Bluetooth not available, or
-     *                     insufficient permissions
+     * @throws IOException on error, for example Bluetooth not available, or insufficient
+     * permissions
      * @hide
      */
     public BluetoothSocket createInsecureL2capSocket(int channel) throws IOException {
@@ -1553,12 +1653,12 @@
      *
      * @param uuid service record uuid to lookup RFCOMM channel
      * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
-     * @throws IOException on error, for example Bluetooth not available, or
-     *                     insufficient permissions
+     * @throws IOException on error, for example Bluetooth not available, or insufficient
+     * permissions
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
-        if (isBluetoothEnabled() == false) {
+        if (!isBluetoothEnabled()) {
             Log.e(TAG, "Bluetooth is not enabled");
             throw new IOException();
         }
@@ -1591,12 +1691,12 @@
      *
      * @param uuid service record uuid to lookup RFCOMM channel
      * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
-     * @throws IOException on error, for example Bluetooth not available, or
-     *                     insufficient permissions
+     * @throws IOException on error, for example Bluetooth not available, or insufficient
+     * permissions
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public BluetoothSocket createInsecureRfcommSocketToServiceRecord(UUID uuid) throws IOException {
-        if (isBluetoothEnabled() == false) {
+        if (!isBluetoothEnabled()) {
             Log.e(TAG, "Bluetooth is not enabled");
             throw new IOException();
         }
@@ -1612,15 +1712,14 @@
      * socket will not be encrypted.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
      *
-     * @param port    remote port
+     * @param port remote port
      * @return An RFCOMM BluetoothSocket
-     * @throws IOException On error, for example Bluetooth not available, or
-     *                     insufficient permissions.
+     * @throws IOException On error, for example Bluetooth not available, or insufficient
+     * permissions.
      * @hide
      */
     public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
-
-        if (isBluetoothEnabled() == false) {
+        if (!isBluetoothEnabled()) {
             Log.e(TAG, "Bluetooth is not enabled");
             throw new IOException();
         }
@@ -1634,13 +1733,12 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
      *
      * @return a SCO BluetoothSocket
-     * @throws IOException on error, for example Bluetooth not available, or
-     *                     insufficient permissions.
+     * @throws IOException on error, for example Bluetooth not available, or insufficient
+     * permissions.
      * @hide
      */
     public BluetoothSocket createScoSocket() throws IOException {
-
-        if (isBluetoothEnabled() == false) {
+        if (!isBluetoothEnabled()) {
             Log.e(TAG, "Bluetooth is not enabled");
             throw new IOException();
         }
@@ -1651,9 +1749,9 @@
      * Check that a pin is valid and convert to byte array.
      *
      * Bluetooth pin's are 1 to 16 bytes of UTF-8 characters.
+     *
      * @param pin pin as java String
-     * @return the pin code as a UTF-8 byte array, or null if it is an invalid
-     *         Bluetooth pin.
+     * @return the pin code as a UTF-8 byte array, or null if it is an invalid Bluetooth pin.
      * @hide
      */
     public static byte[] convertPinToBytes(String pin) {
@@ -1679,15 +1777,15 @@
      * as any further GATT client operations.
      * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
      * GATT client operations.
+     *
      * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @param autoConnect Whether to directly connect to the remote device (false)
-     *                    or to automatically connect as soon as the remote
-     *                    device becomes available (true).
+     * @param autoConnect Whether to directly connect to the remote device (false) or to
+     * automatically connect as soon as the remote device becomes available (true).
      * @throws IllegalArgumentException if callback is null
      */
     public BluetoothGatt connectGatt(Context context, boolean autoConnect,
-                                     BluetoothGattCallback callback) {
-        return (connectGatt(context, autoConnect,callback, TRANSPORT_AUTO));
+            BluetoothGattCallback callback) {
+        return (connectGatt(context, autoConnect, callback, TRANSPORT_AUTO));
     }
 
     /**
@@ -1696,18 +1794,18 @@
      * as any further GATT client operations.
      * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
      * GATT client operations.
+     *
      * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @param autoConnect Whether to directly connect to the remote device (false)
-     *                    or to automatically connect as soon as the remote
-     *                    device becomes available (true).
-     * @param transport preferred transport for GATT connections to remote dual-mode devices
-     *             {@link BluetoothDevice#TRANSPORT_AUTO} or
-     *             {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
+     * @param autoConnect Whether to directly connect to the remote device (false) or to
+     * automatically connect as soon as the remote device becomes available (true).
+     * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
+     * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
+     * BluetoothDevice#TRANSPORT_LE}
      * @throws IllegalArgumentException if callback is null
      */
     public BluetoothGatt connectGatt(Context context, boolean autoConnect,
-                                     BluetoothGattCallback callback, int transport) {
-        return (connectGatt(context, autoConnect,callback, transport, PHY_LE_1M_MASK));
+            BluetoothGattCallback callback, int transport) {
+        return (connectGatt(context, autoConnect, callback, transport, PHY_LE_1M_MASK));
     }
 
     /**
@@ -1716,22 +1814,22 @@
      * as any further GATT client operations.
      * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
      * GATT client operations.
+     *
      * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @param autoConnect Whether to directly connect to the remote device (false)
-     *                    or to automatically connect as soon as the remote
-     *                    device becomes available (true).
-     * @param transport preferred transport for GATT connections to remote dual-mode devices
-     *             {@link BluetoothDevice#TRANSPORT_AUTO} or
-     *             {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
-     * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of
-     *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
-     *             and {@link BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect
-     *             if {@code autoConnect} is set to true.
+     * @param autoConnect Whether to directly connect to the remote device (false) or to
+     * automatically connect as soon as the remote device becomes available (true).
+     * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
+     * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
+     * BluetoothDevice#TRANSPORT_LE}
+     * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of {@link
+     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link
+     * BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if {@code autoConnect}
+     * is set to true.
      * @throws NullPointerException if callback is null
      */
     public BluetoothGatt connectGatt(Context context, boolean autoConnect,
-                                     BluetoothGattCallback callback, int transport, int phy) {
-        return connectGatt(context, autoConnect,callback, transport, phy, null);
+            BluetoothGattCallback callback, int transport, int phy) {
+        return connectGatt(context, autoConnect, callback, transport, phy, null);
     }
 
     /**
@@ -1740,24 +1838,24 @@
      * as any further GATT client operations.
      * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
      * GATT client operations.
+     *
      * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @param autoConnect Whether to directly connect to the remote device (false)
-     *                    or to automatically connect as soon as the remote
-     *                    device becomes available (true).
-     * @param transport preferred transport for GATT connections to remote dual-mode devices
-     *             {@link BluetoothDevice#TRANSPORT_AUTO} or
-     *             {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
-     * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of
-     *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
-     *             an d{@link BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect
-     *             if {@code autoConnect} is set to true.
-     * @param handler The handler to use for the callback. If {@code null}, callbacks will happen
-     *             on an un-specified background thread.
+     * @param autoConnect Whether to directly connect to the remote device (false) or to
+     * automatically connect as soon as the remote device becomes available (true).
+     * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
+     * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
+     * BluetoothDevice#TRANSPORT_LE}
+     * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of {@link
+     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, an d{@link
+     * BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if {@code autoConnect}
+     * is set to true.
+     * @param handler The handler to use for the callback. If {@code null}, callbacks will happen on
+     * an un-specified background thread.
      * @throws NullPointerException if callback is null
      */
     public BluetoothGatt connectGatt(Context context, boolean autoConnect,
-                                     BluetoothGattCallback callback, int transport, int phy,
-                                     Handler handler) {
+            BluetoothGattCallback callback, int transport, int phy,
+            Handler handler) {
         return connectGatt(context, autoConnect, callback, transport, false, phy, handler);
     }
 
@@ -1767,31 +1865,32 @@
      * as any further GATT client operations.
      * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
      * GATT client operations.
+     *
      * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @param autoConnect Whether to directly connect to the remote device (false)
-     *                    or to automatically connect as soon as the remote
-     *                    device becomes available (true).
-     * @param transport preferred transport for GATT connections to remote dual-mode devices
-     *             {@link BluetoothDevice#TRANSPORT_AUTO} or
-     *             {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
+     * @param autoConnect Whether to directly connect to the remote device (false) or to
+     * automatically connect as soon as the remote device becomes available (true).
+     * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
+     * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
+     * BluetoothDevice#TRANSPORT_LE}
      * @param opportunistic Whether this GATT client is opportunistic. An opportunistic GATT client
-     *                      does not hold a GATT connection. It automatically disconnects when no
-     *                      other GATT connections are active for the remote device.
-     * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of
-     *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
-     *             an d{@link BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect
-     *             if {@code autoConnect} is set to true.
-     * @param handler The handler to use for the callback. If {@code null}, callbacks will happen
-     *             on an un-specified background thread.
+     * does not hold a GATT connection. It automatically disconnects when no other GATT connections
+     * are active for the remote device.
+     * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of {@link
+     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, an d{@link
+     * BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if {@code autoConnect}
+     * is set to true.
+     * @param handler The handler to use for the callback. If {@code null}, callbacks will happen on
+     * an un-specified background thread.
      * @return A BluetoothGatt instance. You can use BluetoothGatt to conduct GATT client
-     *         operations.
+     * operations.
      * @hide
      */
     public BluetoothGatt connectGatt(Context context, boolean autoConnect,
-                                     BluetoothGattCallback callback, int transport,
-                                     boolean opportunistic, int phy, Handler handler) {
-        if (callback == null)
+            BluetoothGattCallback callback, int transport,
+            boolean opportunistic, int phy, Handler handler) {
+        if (callback == null) {
             throw new NullPointerException("callback is null");
+        }
 
         // TODO(Bluetooth) check whether platform support BLE
         //     Do the check here or in GattServer?
@@ -1806,7 +1905,9 @@
             BluetoothGatt gatt = new BluetoothGatt(iGatt, this, transport, opportunistic, phy);
             gatt.connect(autoConnect, callback, handler);
             return gatt;
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
         return null;
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothDevicePicker.java b/core/java/android/bluetooth/BluetoothDevicePicker.java
index c794be2..09b0a80 100644
--- a/core/java/android/bluetooth/BluetoothDevicePicker.java
+++ b/core/java/android/bluetooth/BluetoothDevicePicker.java
@@ -48,11 +48,11 @@
      * This intent contains below extra data:
      * - {@link #EXTRA_NEED_AUTH} (boolean): if need authentication
      * - {@link #EXTRA_FILTER_TYPE} (int): what kinds of device should be
-     *                                     listed
+     * listed
      * - {@link #EXTRA_LAUNCH_PACKAGE} (string): where(which package) this
-     *                                           intent come from
+     * intent come from
      * - {@link #EXTRA_LAUNCH_CLASS} (string): where(which class) this intent
-     *                                         come from
+     * come from
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_LAUNCH =
@@ -64,8 +64,10 @@
     public static final int FILTER_TYPE_AUDIO = 1;
     /** Ask device picker to show BT devices that support Object Transfer */
     public static final int FILTER_TYPE_TRANSFER = 2;
-    /** Ask device picker to show BT devices that support
-     * Personal Area Networking User (PANU) profile*/
+    /**
+     * Ask device picker to show BT devices that support
+     * Personal Area Networking User (PANU) profile
+     */
     public static final int FILTER_TYPE_PANU = 3;
     /** Ask device picker to show BT devices that support Network Access Point (NAP) profile */
     public static final int FILTER_TYPE_NAP = 4;
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 678159b..a2af342 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -42,7 +42,7 @@
     private static final boolean VDBG = false;
 
     private IBluetoothGatt mService;
-    private BluetoothGattCallback mCallback;
+    private volatile BluetoothGattCallback mCallback;
     private Handler mHandler;
     private int mClientIf;
     private BluetoothDevice mDevice;
@@ -118,18 +118,21 @@
 
     /**
      * No authentication required.
+     *
      * @hide
      */
     /*package*/ static final int AUTHENTICATION_NONE = 0;
 
     /**
      * Authentication requested; no man-in-the-middle protection required.
+     *
      * @hide
      */
     /*package*/ static final int AUTHENTICATION_NO_MITM = 1;
 
     /**
      * Authentication with man-in-the-middle protection requested.
+     *
      * @hide
      */
     /*package*/ static final int AUTHENTICATION_MITM = 2;
@@ -138,498 +141,547 @@
      * Bluetooth GATT callbacks. Overrides the default BluetoothGattCallback implementation.
      */
     private final IBluetoothGattCallback mBluetoothGattCallback =
-        new IBluetoothGattCallback.Stub() {
-            /**
-             * Application interface registered - app is ready to go
-             * @hide
-             */
-            @Override
-            public void onClientRegistered(int status, int clientIf) {
-                if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status
-                    + " clientIf=" + clientIf);
-                if (VDBG) {
-                    synchronized(mStateLock) {
-                        if (mConnState != CONN_STATE_CONNECTING) {
-                            Log.e(TAG, "Bad connection state: " + mConnState);
+            new IBluetoothGattCallback.Stub() {
+                /**
+                 * Application interface registered - app is ready to go
+                 * @hide
+                 */
+                @Override
+                public void onClientRegistered(int status, int clientIf) {
+                    if (DBG) {
+                        Log.d(TAG, "onClientRegistered() - status=" + status
+                                + " clientIf=" + clientIf);
+                    }
+                    if (VDBG) {
+                        synchronized (mStateLock) {
+                            if (mConnState != CONN_STATE_CONNECTING) {
+                                Log.e(TAG, "Bad connection state: " + mConnState);
+                            }
                         }
                     }
+                    mClientIf = clientIf;
+                    if (status != GATT_SUCCESS) {
+                        runOrQueueCallback(new Runnable() {
+                            @Override
+                            public void run() {
+                                final BluetoothGattCallback callback = mCallback;
+                                if (callback != null) {
+                                    callback.onConnectionStateChange(BluetoothGatt.this,
+                                            GATT_FAILURE,
+                                            BluetoothProfile.STATE_DISCONNECTED);
+                                }
+                            }
+                        });
+
+                        synchronized (mStateLock) {
+                            mConnState = CONN_STATE_IDLE;
+                        }
+                        return;
+                    }
+                    try {
+                        mService.clientConnect(mClientIf, mDevice.getAddress(),
+                                !mAutoConnect, mTransport, mOpportunistic,
+                                mPhy); // autoConnect is inverse of "isDirect"
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "", e);
+                    }
                 }
-                mClientIf = clientIf;
-                if (status != GATT_SUCCESS) {
+
+                /**
+                 * Phy update callback
+                 * @hide
+                 */
+                @Override
+                public void onPhyUpdate(String address, int txPhy, int rxPhy, int status) {
+                    if (DBG) {
+                        Log.d(TAG, "onPhyUpdate() - status=" + status
+                                + " address=" + address + " txPhy=" + txPhy + " rxPhy=" + rxPhy);
+                    }
+                    if (!address.equals(mDevice.getAddress())) {
+                        return;
+                    }
+
                     runOrQueueCallback(new Runnable() {
                         @Override
                         public void run() {
-                            if (mCallback != null) {
-                                mCallback.onConnectionStateChange(BluetoothGatt.this, GATT_FAILURE,
-                                                  BluetoothProfile.STATE_DISCONNECTED);
+                            final BluetoothGattCallback callback = mCallback;
+                            if (callback != null) {
+                                callback.onPhyUpdate(BluetoothGatt.this, txPhy, rxPhy, status);
+                            }
+                        }
+                    });
+                }
+
+                /**
+                 * Phy read callback
+                 * @hide
+                 */
+                @Override
+                public void onPhyRead(String address, int txPhy, int rxPhy, int status) {
+                    if (DBG) {
+                        Log.d(TAG, "onPhyRead() - status=" + status
+                                + " address=" + address + " txPhy=" + txPhy + " rxPhy=" + rxPhy);
+                    }
+                    if (!address.equals(mDevice.getAddress())) {
+                        return;
+                    }
+
+                    runOrQueueCallback(new Runnable() {
+                        @Override
+                        public void run() {
+                            final BluetoothGattCallback callback = mCallback;
+                            if (callback != null) {
+                                callback.onPhyRead(BluetoothGatt.this, txPhy, rxPhy, status);
+                            }
+                        }
+                    });
+                }
+
+                /**
+                 * Client connection state changed
+                 * @hide
+                 */
+                @Override
+                public void onClientConnectionState(int status, int clientIf,
+                        boolean connected, String address) {
+                    if (DBG) {
+                        Log.d(TAG, "onClientConnectionState() - status=" + status
+                                + " clientIf=" + clientIf + " device=" + address);
+                    }
+                    if (!address.equals(mDevice.getAddress())) {
+                        return;
+                    }
+                    int profileState = connected ? BluetoothProfile.STATE_CONNECTED :
+                            BluetoothProfile.STATE_DISCONNECTED;
+
+                    runOrQueueCallback(new Runnable() {
+                        @Override
+                        public void run() {
+                            final BluetoothGattCallback callback = mCallback;
+                            if (callback != null) {
+                                callback.onConnectionStateChange(BluetoothGatt.this, status,
+                                        profileState);
                             }
                         }
                     });
 
-                    synchronized(mStateLock) {
-                        mConnState = CONN_STATE_IDLE;
-                    }
-                    return;
-                }
-                try {
-                    mService.clientConnect(mClientIf, mDevice.getAddress(),
-                                           !mAutoConnect, mTransport, mOpportunistic, mPhy); // autoConnect is inverse of "isDirect"
-                } catch (RemoteException e) {
-                    Log.e(TAG,"",e);
-                }
-            }
-
-            /**
-             * Phy update callback
-             * @hide
-             */
-            @Override
-            public void onPhyUpdate(String address, int txPhy, int rxPhy, int status) {
-                if (DBG) Log.d(TAG, "onPhyUpdate() - status=" + status
-                                 + " address=" + address + " txPhy=" + txPhy + " rxPhy=" + rxPhy);
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
-                }
-
-                runOrQueueCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCallback != null) {
-                            mCallback.onPhyUpdate(BluetoothGatt.this, txPhy, rxPhy, status);
-                        }
-                    }
-                });
-            }
-
-            /**
-             * Phy read callback
-             * @hide
-             */
-            @Override
-            public void onPhyRead(String address, int txPhy, int rxPhy, int status) {
-                if (DBG) Log.d(TAG, "onPhyRead() - status=" + status
-                                 + " address=" + address + " txPhy=" + txPhy + " rxPhy=" + rxPhy);
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
-                }
-
-                runOrQueueCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCallback != null) {
-                            mCallback.onPhyRead(BluetoothGatt.this, txPhy, rxPhy, status);
-                        }
-                    }
-                });
-            }
-
-            /**
-             * Client connection state changed
-             * @hide
-             */
-            @Override
-            public void onClientConnectionState(int status, int clientIf,
-                                                boolean connected, String address) {
-                if (DBG) Log.d(TAG, "onClientConnectionState() - status=" + status
-                                 + " clientIf=" + clientIf + " device=" + address);
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
-                }
-                int profileState = connected ? BluetoothProfile.STATE_CONNECTED :
-                                               BluetoothProfile.STATE_DISCONNECTED;
-
-                runOrQueueCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCallback != null) {
-                            mCallback.onConnectionStateChange(BluetoothGatt.this, status,
-                                                              profileState);
-                        }
-                    }
-                });
-
-                synchronized(mStateLock) {
-                    if (connected) {
-                        mConnState = CONN_STATE_CONNECTED;
-                    } else {
-                        mConnState = CONN_STATE_IDLE;
-                    }
-                }
-
-                synchronized(mDeviceBusy) {
-                    mDeviceBusy = false;
-                }
-            }
-
-            /**
-             * Remote search has been completed.
-             * The internal object structure should now reflect the state
-             * of the remote device database. Let the application know that
-             * we are done at this point.
-             * @hide
-             */
-            @Override
-            public void onSearchComplete(String address, List<BluetoothGattService> services,
-                                         int status) {
-                if (DBG) Log.d(TAG, "onSearchComplete() = Device=" + address + " Status=" + status);
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
-                }
-
-                for (BluetoothGattService s : services) {
-                    //services we receive don't have device set properly.
-                    s.setDevice(mDevice);
-                }
-
-                mServices.addAll(services);
-
-                // Fix references to included services, as they doesn't point to right objects.
-                for (BluetoothGattService fixedService : mServices) {
-                    ArrayList<BluetoothGattService> includedServices =
-                        new ArrayList(fixedService.getIncludedServices());
-                    fixedService.getIncludedServices().clear();
-
-                    for(BluetoothGattService brokenRef : includedServices) {
-                        BluetoothGattService includedService = getService(mDevice,
-                            brokenRef.getUuid(), brokenRef.getInstanceId(), brokenRef.getType());
-                        if (includedService != null) {
-                            fixedService.addIncludedService(includedService);
+                    synchronized (mStateLock) {
+                        if (connected) {
+                            mConnState = CONN_STATE_CONNECTED;
                         } else {
-                            Log.e(TAG, "Broken GATT database: can't find included service.");
+                            mConnState = CONN_STATE_IDLE;
                         }
                     }
+
+                    synchronized (mDeviceBusy) {
+                        mDeviceBusy = false;
+                    }
                 }
 
-                runOrQueueCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCallback != null) {
-                            mCallback.onServicesDiscovered(BluetoothGatt.this, status);
-                        }
+                /**
+                 * Remote search has been completed.
+                 * The internal object structure should now reflect the state
+                 * of the remote device database. Let the application know that
+                 * we are done at this point.
+                 * @hide
+                 */
+                @Override
+                public void onSearchComplete(String address, List<BluetoothGattService> services,
+                        int status) {
+                    if (DBG) {
+                        Log.d(TAG,
+                                "onSearchComplete() = Device=" + address + " Status=" + status);
                     }
-                });
-            }
-
-            /**
-             * Remote characteristic has been read.
-             * Updates the internal value.
-             * @hide
-             */
-            @Override
-            public void onCharacteristicRead(String address, int status, int handle, byte[] value) {
-                if (VDBG) Log.d(TAG, "onCharacteristicRead() - Device=" + address
-                            + " handle=" + handle + " Status=" + status);
-
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
-                }
-
-                synchronized(mDeviceBusy) {
-                    mDeviceBusy = false;
-                }
-
-                if ((status == GATT_INSUFFICIENT_AUTHENTICATION
-                  || status == GATT_INSUFFICIENT_ENCRYPTION)
-                  && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
-                    try {
-                        final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE) ?
-                                AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
-                        mService.readCharacteristic(mClientIf, address, handle, authReq);
-                        mAuthRetryState++;
+                    if (!address.equals(mDevice.getAddress())) {
                         return;
-                    } catch (RemoteException e) {
-                        Log.e(TAG,"",e);
                     }
-                }
 
-                mAuthRetryState = AUTH_RETRY_STATE_IDLE;
+                    for (BluetoothGattService s : services) {
+                        //services we receive don't have device set properly.
+                        s.setDevice(mDevice);
+                    }
 
-                BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice, handle);
-                if (characteristic == null) {
-                    Log.w(TAG, "onCharacteristicRead() failed to find characteristic!");
-                    return;
-                }
+                    mServices.addAll(services);
 
-                if (status == 0) characteristic.setValue(value);
+                    // Fix references to included services, as they doesn't point to right objects.
+                    for (BluetoothGattService fixedService : mServices) {
+                        ArrayList<BluetoothGattService> includedServices =
+                                new ArrayList(fixedService.getIncludedServices());
+                        fixedService.getIncludedServices().clear();
 
-                runOrQueueCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCallback != null) {
-                            mCallback.onCharacteristicRead(BluetoothGatt.this, characteristic,
-                                                           status);
+                        for (BluetoothGattService brokenRef : includedServices) {
+                            BluetoothGattService includedService = getService(mDevice,
+                                    brokenRef.getUuid(), brokenRef.getInstanceId());
+                            if (includedService != null) {
+                                fixedService.addIncludedService(includedService);
+                            } else {
+                                Log.e(TAG, "Broken GATT database: can't find included service.");
+                            }
                         }
                     }
-                });
-            }
 
-            /**
-             * Characteristic has been written to the remote device.
-             * Let the app know how we did...
-             * @hide
-             */
-            @Override
-            public void onCharacteristicWrite(String address, int status, int handle) {
-                if (VDBG) Log.d(TAG, "onCharacteristicWrite() - Device=" + address
-                            + " handle=" + handle + " Status=" + status);
-
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
+                    runOrQueueCallback(new Runnable() {
+                        @Override
+                        public void run() {
+                            final BluetoothGattCallback callback = mCallback;
+                            if (callback != null) {
+                                callback.onServicesDiscovered(BluetoothGatt.this, status);
+                            }
+                        }
+                    });
                 }
 
-                synchronized(mDeviceBusy) {
-                    mDeviceBusy = false;
-                }
+                /**
+                 * Remote characteristic has been read.
+                 * Updates the internal value.
+                 * @hide
+                 */
+                @Override
+                public void onCharacteristicRead(String address, int status, int handle,
+                        byte[] value) {
+                    if (VDBG) {
+                        Log.d(TAG, "onCharacteristicRead() - Device=" + address
+                                + " handle=" + handle + " Status=" + status);
+                    }
 
-                BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice, handle);
-                if (characteristic == null) return;
-
-                if ((status == GATT_INSUFFICIENT_AUTHENTICATION
-                  || status == GATT_INSUFFICIENT_ENCRYPTION)
-                  && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
-                    try {
-                        final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE) ?
-                                AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
-                        mService.writeCharacteristic(mClientIf, address, handle,
-                            characteristic.getWriteType(), authReq, characteristic.getValue());
-                        mAuthRetryState++;
+                    if (!address.equals(mDevice.getAddress())) {
                         return;
-                    } catch (RemoteException e) {
-                        Log.e(TAG,"",e);
                     }
-                }
 
-                mAuthRetryState = AUTH_RETRY_STATE_IDLE;
+                    synchronized (mDeviceBusy) {
+                        mDeviceBusy = false;
+                    }
 
-                runOrQueueCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCallback != null) {
-                            mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic,
-                                                            status);
+                    if ((status == GATT_INSUFFICIENT_AUTHENTICATION
+                            || status == GATT_INSUFFICIENT_ENCRYPTION)
+                            && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
+                        try {
+                            final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE)
+                                    ? AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
+                            mService.readCharacteristic(mClientIf, address, handle, authReq);
+                            mAuthRetryState++;
+                            return;
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "", e);
                         }
                     }
-                });
-            }
 
-            /**
-             * Remote characteristic has been updated.
-             * Updates the internal value.
-             * @hide
-             */
-            @Override
-            public void onNotify(String address, int handle, byte[] value) {
-                if (VDBG) Log.d(TAG, "onNotify() - Device=" + address + " handle=" + handle);
+                    mAuthRetryState = AUTH_RETRY_STATE_IDLE;
 
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
-                }
-
-                BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice, handle);
-                if (characteristic == null) return;
-
-                characteristic.setValue(value);
-
-                runOrQueueCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCallback != null) {
-                            mCallback.onCharacteristicChanged(BluetoothGatt.this, characteristic);
-                        }
-                    }
-                });
-            }
-
-            /**
-             * Descriptor has been read.
-             * @hide
-             */
-            @Override
-            public void onDescriptorRead(String address, int status, int handle, byte[] value) {
-                if (VDBG) Log.d(TAG, "onDescriptorRead() - Device=" + address + " handle=" + handle);
-
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
-                }
-
-                synchronized(mDeviceBusy) {
-                    mDeviceBusy = false;
-                }
-
-                BluetoothGattDescriptor descriptor = getDescriptorById(mDevice, handle);
-                if (descriptor == null) return;
-
-                if (status == 0) descriptor.setValue(value);
-
-                if ((status == GATT_INSUFFICIENT_AUTHENTICATION
-                  || status == GATT_INSUFFICIENT_ENCRYPTION)
-                  && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
-                    try {
-                        final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE) ?
-                                AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
-                        mService.readDescriptor(mClientIf, address, handle, authReq);
-                        mAuthRetryState++;
+                    BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice,
+                            handle);
+                    if (characteristic == null) {
+                        Log.w(TAG, "onCharacteristicRead() failed to find characteristic!");
                         return;
-                    } catch (RemoteException e) {
-                        Log.e(TAG,"",e);
                     }
-                }
 
-                mAuthRetryState = AUTH_RETRY_STATE_IDLE;
-
-                runOrQueueCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCallback != null) {
-                            mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status);
+                    runOrQueueCallback(new Runnable() {
+                        @Override
+                        public void run() {
+                            final BluetoothGattCallback callback = mCallback;
+                            if (callback != null) {
+                                if (status == 0) characteristic.setValue(value);
+                                callback.onCharacteristicRead(BluetoothGatt.this, characteristic,
+                                        status);
+                            }
                         }
+                    });
+                }
+
+                /**
+                 * Characteristic has been written to the remote device.
+                 * Let the app know how we did...
+                 * @hide
+                 */
+                @Override
+                public void onCharacteristicWrite(String address, int status, int handle) {
+                    if (VDBG) {
+                        Log.d(TAG, "onCharacteristicWrite() - Device=" + address
+                                + " handle=" + handle + " Status=" + status);
                     }
-                });
-            }
 
-            /**
-             * Descriptor write operation complete.
-             * @hide
-             */
-            @Override
-            public void onDescriptorWrite(String address, int status, int handle) {
-                if (VDBG) Log.d(TAG, "onDescriptorWrite() - Device=" + address + " handle=" + handle);
-
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
-                }
-
-                synchronized(mDeviceBusy) {
-                    mDeviceBusy = false;
-                }
-
-                BluetoothGattDescriptor descriptor = getDescriptorById(mDevice, handle);
-                if (descriptor == null) return;
-
-                if ((status == GATT_INSUFFICIENT_AUTHENTICATION
-                  || status == GATT_INSUFFICIENT_ENCRYPTION)
-                  && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
-                    try {
-                        final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE) ?
-                                AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
-                        mService.writeDescriptor(mClientIf, address, handle,
-                            authReq, descriptor.getValue());
-                        mAuthRetryState++;
+                    if (!address.equals(mDevice.getAddress())) {
                         return;
-                    } catch (RemoteException e) {
-                        Log.e(TAG,"",e);
                     }
-                }
 
-                mAuthRetryState = AUTH_RETRY_STATE_IDLE;
+                    synchronized (mDeviceBusy) {
+                        mDeviceBusy = false;
+                    }
 
-                runOrQueueCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCallback != null) {
-                            mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status);
+                    BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice,
+                            handle);
+                    if (characteristic == null) return;
+
+                    if ((status == GATT_INSUFFICIENT_AUTHENTICATION
+                            || status == GATT_INSUFFICIENT_ENCRYPTION)
+                            && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
+                        try {
+                            final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE)
+                                    ? AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
+                            mService.writeCharacteristic(mClientIf, address, handle,
+                                    characteristic.getWriteType(), authReq,
+                                    characteristic.getValue());
+                            mAuthRetryState++;
+                            return;
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "", e);
                         }
                     }
-                });
-            }
 
-            /**
-             * Prepared write transaction completed (or aborted)
-             * @hide
-             */
-            @Override
-            public void onExecuteWrite(String address, int status) {
-                if (VDBG) Log.d(TAG, "onExecuteWrite() - Device=" + address
-                    + " status=" + status);
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
+                    mAuthRetryState = AUTH_RETRY_STATE_IDLE;
+
+                    runOrQueueCallback(new Runnable() {
+                        @Override
+                        public void run() {
+                            final BluetoothGattCallback callback = mCallback;
+                            if (callback != null) {
+                                callback.onCharacteristicWrite(BluetoothGatt.this, characteristic,
+                                        status);
+                            }
+                        }
+                    });
                 }
 
-                synchronized(mDeviceBusy) {
-                    mDeviceBusy = false;
+                /**
+                 * Remote characteristic has been updated.
+                 * Updates the internal value.
+                 * @hide
+                 */
+                @Override
+                public void onNotify(String address, int handle, byte[] value) {
+                    if (VDBG) Log.d(TAG, "onNotify() - Device=" + address + " handle=" + handle);
+
+                    if (!address.equals(mDevice.getAddress())) {
+                        return;
+                    }
+
+                    BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice,
+                            handle);
+                    if (characteristic == null) return;
+
+                    runOrQueueCallback(new Runnable() {
+                        @Override
+                        public void run() {
+                            final BluetoothGattCallback callback = mCallback;
+                            if (callback != null) {
+                                characteristic.setValue(value);
+                                callback.onCharacteristicChanged(BluetoothGatt.this,
+                                        characteristic);
+                            }
+                        }
+                    });
                 }
 
-                runOrQueueCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCallback != null) {
-                           mCallback.onReliableWriteCompleted(BluetoothGatt.this, status);
+                /**
+                 * Descriptor has been read.
+                 * @hide
+                 */
+                @Override
+                public void onDescriptorRead(String address, int status, int handle, byte[] value) {
+                    if (VDBG) {
+                        Log.d(TAG,
+                                "onDescriptorRead() - Device=" + address + " handle=" + handle);
+                    }
+
+                    if (!address.equals(mDevice.getAddress())) {
+                        return;
+                    }
+
+                    synchronized (mDeviceBusy) {
+                        mDeviceBusy = false;
+                    }
+
+                    BluetoothGattDescriptor descriptor = getDescriptorById(mDevice, handle);
+                    if (descriptor == null) return;
+
+
+                    if ((status == GATT_INSUFFICIENT_AUTHENTICATION
+                            || status == GATT_INSUFFICIENT_ENCRYPTION)
+                            && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
+                        try {
+                            final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE)
+                                    ? AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
+                            mService.readDescriptor(mClientIf, address, handle, authReq);
+                            mAuthRetryState++;
+                            return;
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "", e);
                         }
                     }
-                });
-            }
 
-            /**
-             * Remote device RSSI has been read
-             * @hide
-             */
-            @Override
-            public void onReadRemoteRssi(String address, int rssi, int status) {
-                if (VDBG) Log.d(TAG, "onReadRemoteRssi() - Device=" + address +
-                            " rssi=" + rssi + " status=" + status);
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
-                }
-                runOrQueueCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCallback != null) {
-                            mCallback.onReadRemoteRssi(BluetoothGatt.this, rssi, status);
+                    mAuthRetryState = AUTH_RETRY_STATE_IDLE;
+
+                    runOrQueueCallback(new Runnable() {
+                        @Override
+                        public void run() {
+                            final BluetoothGattCallback callback = mCallback;
+                            if (callback != null) {
+                                if (status == 0) descriptor.setValue(value);
+                                callback.onDescriptorRead(BluetoothGatt.this, descriptor, status);
+                            }
                         }
-                    }
-                });
-            }
-
-            /**
-             * Callback invoked when the MTU for a given connection changes
-             * @hide
-             */
-            @Override
-            public void onConfigureMTU(String address, int mtu, int status) {
-                if (DBG) Log.d(TAG, "onConfigureMTU() - Device=" + address +
-                            " mtu=" + mtu + " status=" + status);
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
+                    });
                 }
 
-                runOrQueueCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCallback != null) {
-                            mCallback.onMtuChanged(BluetoothGatt.this, mtu, status);
+                /**
+                 * Descriptor write operation complete.
+                 * @hide
+                 */
+                @Override
+                public void onDescriptorWrite(String address, int status, int handle) {
+                    if (VDBG) {
+                        Log.d(TAG,
+                                "onDescriptorWrite() - Device=" + address + " handle=" + handle);
+                    }
+
+                    if (!address.equals(mDevice.getAddress())) {
+                        return;
+                    }
+
+                    synchronized (mDeviceBusy) {
+                        mDeviceBusy = false;
+                    }
+
+                    BluetoothGattDescriptor descriptor = getDescriptorById(mDevice, handle);
+                    if (descriptor == null) return;
+
+                    if ((status == GATT_INSUFFICIENT_AUTHENTICATION
+                            || status == GATT_INSUFFICIENT_ENCRYPTION)
+                            && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
+                        try {
+                            final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE)
+                                    ? AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
+                            mService.writeDescriptor(mClientIf, address, handle,
+                                    authReq, descriptor.getValue());
+                            mAuthRetryState++;
+                            return;
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "", e);
                         }
                     }
-                });
-            }
 
-            /**
-             * Callback invoked when the given connection is updated
-             * @hide
-             */
-            @Override
-            public void onConnectionUpdated(String address, int interval, int latency,
-                                            int timeout, int status) {
-                if (DBG) Log.d(TAG, "onConnectionUpdated() - Device=" + address +
-                            " interval=" + interval + " latency=" + latency +
-                            " timeout=" + timeout + " status=" + status);
-                if (!address.equals(mDevice.getAddress())) {
-                    return;
+                    mAuthRetryState = AUTH_RETRY_STATE_IDLE;
+
+                    runOrQueueCallback(new Runnable() {
+                        @Override
+                        public void run() {
+                            final BluetoothGattCallback callback = mCallback;
+                            if (callback != null) {
+                                callback.onDescriptorWrite(BluetoothGatt.this, descriptor, status);
+                            }
+                        }
+                    });
                 }
 
-                runOrQueueCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCallback != null) {
-                            mCallback.onConnectionUpdated(BluetoothGatt.this, interval, latency,
-                                                          timeout, status);
-                        }
+                /**
+                 * Prepared write transaction completed (or aborted)
+                 * @hide
+                 */
+                @Override
+                public void onExecuteWrite(String address, int status) {
+                    if (VDBG) {
+                        Log.d(TAG, "onExecuteWrite() - Device=" + address
+                                + " status=" + status);
                     }
-                });
-            }
-        };
+                    if (!address.equals(mDevice.getAddress())) {
+                        return;
+                    }
+
+                    synchronized (mDeviceBusy) {
+                        mDeviceBusy = false;
+                    }
+
+                    runOrQueueCallback(new Runnable() {
+                        @Override
+                        public void run() {
+                            final BluetoothGattCallback callback = mCallback;
+                            if (callback != null) {
+                                callback.onReliableWriteCompleted(BluetoothGatt.this, status);
+                            }
+                        }
+                    });
+                }
+
+                /**
+                 * Remote device RSSI has been read
+                 * @hide
+                 */
+                @Override
+                public void onReadRemoteRssi(String address, int rssi, int status) {
+                    if (VDBG) {
+                        Log.d(TAG, "onReadRemoteRssi() - Device=" + address
+                                + " rssi=" + rssi + " status=" + status);
+                    }
+                    if (!address.equals(mDevice.getAddress())) {
+                        return;
+                    }
+                    runOrQueueCallback(new Runnable() {
+                        @Override
+                        public void run() {
+                            final BluetoothGattCallback callback = mCallback;
+                            if (callback != null) {
+                                callback.onReadRemoteRssi(BluetoothGatt.this, rssi, status);
+                            }
+                        }
+                    });
+                }
+
+                /**
+                 * Callback invoked when the MTU for a given connection changes
+                 * @hide
+                 */
+                @Override
+                public void onConfigureMTU(String address, int mtu, int status) {
+                    if (DBG) {
+                        Log.d(TAG, "onConfigureMTU() - Device=" + address
+                                + " mtu=" + mtu + " status=" + status);
+                    }
+                    if (!address.equals(mDevice.getAddress())) {
+                        return;
+                    }
+
+                    runOrQueueCallback(new Runnable() {
+                        @Override
+                        public void run() {
+                            final BluetoothGattCallback callback = mCallback;
+                            if (callback != null) {
+                                callback.onMtuChanged(BluetoothGatt.this, mtu, status);
+                            }
+                        }
+                    });
+                }
+
+                /**
+                 * Callback invoked when the given connection is updated
+                 * @hide
+                 */
+                @Override
+                public void onConnectionUpdated(String address, int interval, int latency,
+                        int timeout, int status) {
+                    if (DBG) {
+                        Log.d(TAG, "onConnectionUpdated() - Device=" + address
+                                + " interval=" + interval + " latency=" + latency
+                                + " timeout=" + timeout + " status=" + status);
+                    }
+                    if (!address.equals(mDevice.getAddress())) {
+                        return;
+                    }
+
+                    runOrQueueCallback(new Runnable() {
+                        @Override
+                        public void run() {
+                            final BluetoothGattCallback callback = mCallback;
+                            if (callback != null) {
+                                callback.onConnectionUpdated(BluetoothGatt.this, interval, latency,
+                                        timeout, status);
+                            }
+                        }
+                    });
+                }
+            };
 
     /*package*/ BluetoothGatt(IBluetoothGatt iGatt, BluetoothDevice device,
-                                int transport, boolean opportunistic, int phy) {
+            int transport, boolean opportunistic, int phy) {
         mService = iGatt;
         mDevice = device;
         mTransport = transport;
@@ -657,15 +709,15 @@
 
     /**
      * Returns a service by UUID, instance and type.
+     *
      * @hide
      */
     /*package*/ BluetoothGattService getService(BluetoothDevice device, UUID uuid,
-                                                int instanceId, int type) {
-        for(BluetoothGattService svc : mServices) {
-            if (svc.getDevice().equals(device) &&
-                svc.getType() == type &&
-                svc.getInstanceId() == instanceId &&
-                svc.getUuid().equals(uuid)) {
+            int instanceId) {
+        for (BluetoothGattService svc : mServices) {
+            if (svc.getDevice().equals(device)
+                    && svc.getInstanceId() == instanceId
+                    && svc.getUuid().equals(uuid)) {
                 return svc;
             }
         }
@@ -675,13 +727,16 @@
 
     /**
      * Returns a characteristic with id equal to instanceId.
+     *
      * @hide
      */
-    /*package*/ BluetoothGattCharacteristic getCharacteristicById(BluetoothDevice device, int instanceId) {
-        for(BluetoothGattService svc : mServices) {
-            for(BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
-                if (charac.getInstanceId() == instanceId)
+    /*package*/ BluetoothGattCharacteristic getCharacteristicById(BluetoothDevice device,
+            int instanceId) {
+        for (BluetoothGattService svc : mServices) {
+            for (BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
+                if (charac.getInstanceId() == instanceId) {
                     return charac;
+                }
             }
         }
         return null;
@@ -689,14 +744,16 @@
 
     /**
      * Returns a descriptor with id equal to instanceId.
+     *
      * @hide
      */
     /*package*/ BluetoothGattDescriptor getDescriptorById(BluetoothDevice device, int instanceId) {
-        for(BluetoothGattService svc : mServices) {
-            for(BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
-                for(BluetoothGattDescriptor desc : charac.getDescriptors()) {
-                    if (desc.getInstanceId() == instanceId)
+        for (BluetoothGattService svc : mServices) {
+            for (BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
+                for (BluetoothGattDescriptor desc : charac.getDescriptors()) {
+                    if (desc.getInstanceId() == instanceId) {
                         return desc;
+                    }
                 }
             }
         }
@@ -709,13 +766,13 @@
      */
     private void runOrQueueCallback(final Runnable cb) {
         if (mHandler == null) {
-          try {
-            cb.run();
-          } catch (Exception ex) {
-            Log.w(TAG, "Unhandled exception in callback", ex);
-          }
+            try {
+                cb.run();
+            } catch (Exception ex) {
+                Log.w(TAG, "Unhandled exception in callback", ex);
+            }
         } else {
-          mHandler.post(cb);
+            mHandler.post(cb);
         }
     }
 
@@ -728,8 +785,8 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @return If true, the callback will be called to notify success or failure,
-     *         false on immediate error
+     * @return If true, the callback will be called to notify success or failure, false on immediate
+     * error
      */
     private boolean registerApp(BluetoothGattCallback callback, Handler handler) {
         if (DBG) Log.d(TAG, "registerApp()");
@@ -743,7 +800,7 @@
         try {
             mService.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return false;
         }
 
@@ -762,7 +819,7 @@
             mService.unregisterClient(mClientIf);
             mClientIf = 0;
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
         }
     }
 
@@ -784,15 +841,17 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param device Remote device to connect to
-     * @param autoConnect Whether to directly connect to the remote device (false)
-     *                    or to automatically connect as soon as the remote
-     *                    device becomes available (true).
+     * @param autoConnect Whether to directly connect to the remote device (false) or to
+     * automatically connect as soon as the remote device becomes available (true).
      * @return true, if the connection attempt was initiated successfully
      */
     /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback,
-                                Handler handler) {
-        if (DBG) Log.d(TAG, "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect);
-        synchronized(mStateLock) {
+            Handler handler) {
+        if (DBG) {
+            Log.d(TAG,
+                    "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect);
+        }
+        synchronized (mStateLock) {
             if (mConnState != CONN_STATE_IDLE) {
                 throw new IllegalStateException("Not idle");
             }
@@ -802,7 +861,7 @@
         mAutoConnect = autoConnect;
 
         if (!registerApp(callback, handler)) {
-            synchronized(mStateLock) {
+            synchronized (mStateLock) {
                 mConnState = CONN_STATE_IDLE;
             }
             Log.e(TAG, "Failed to register callback");
@@ -826,7 +885,7 @@
         try {
             mService.clientDisconnect(mClientIf, mDevice.getAddress());
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
         }
     }
 
@@ -845,35 +904,35 @@
                     mOpportunistic, mPhy); // autoConnect is inverse of "isDirect"
             return true;
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return false;
         }
     }
 
     /**
      * Set the preferred connection PHY for this app. Please note that this is just a
-     * recommendation, whether the PHY change will happen depends on other applications peferences,
+     * recommendation, whether the PHY change will happen depends on other applications preferences,
      * local and remote controller capabilities. Controller can override these settings.
      * <p>
      * {@link BluetoothGattCallback#onPhyUpdate} will be triggered as a result of this call, even
      * if no PHY change happens. It is also triggered when remote device updates the PHY.
      *
-     * @param txPhy preferred transmitter PHY. Bitwise OR of any of
-     *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
-     *             and {@link BluetoothDevice#PHY_LE_CODED_MASK}.
-     * @param rxPhy preferred receiver PHY. Bitwise OR of any of
-     *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
-     *             and {@link BluetoothDevice#PHY_LE_CODED_MASK}.
+     * @param txPhy preferred transmitter PHY. Bitwise OR of any of {@link
+     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link
+     * BluetoothDevice#PHY_LE_CODED_MASK}.
+     * @param rxPhy preferred receiver PHY. Bitwise OR of any of {@link
+     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link
+     * BluetoothDevice#PHY_LE_CODED_MASK}.
      * @param phyOptions preferred coding to use when transmitting on the LE Coded PHY. Can be one
-     *             of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED},
-     *             {@link BluetoothDevice#PHY_OPTION_S2} or {@link BluetoothDevice#PHY_OPTION_S8}
+     * of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED}, {@link BluetoothDevice#PHY_OPTION_S2} or
+     * {@link BluetoothDevice#PHY_OPTION_S8}
      */
     public void setPreferredPhy(int txPhy, int rxPhy, int phyOptions) {
         try {
             mService.clientSetPreferredPhy(mClientIf, mDevice.getAddress(), txPhy, rxPhy,
-                                           phyOptions);
+                    phyOptions);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
         }
     }
 
@@ -885,7 +944,7 @@
         try {
             mService.clientReadPhy(mClientIf, mDevice.getAddress());
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
         }
     }
 
@@ -920,7 +979,7 @@
         try {
             mService.discoverServices(mClientIf, mDevice.getAddress());
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return false;
         }
 
@@ -960,8 +1019,8 @@
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
-     * @return List of services on the remote device. Returns an empty list
-     *         if service discovery has not yet been performed.
+     * @return List of services on the remote device. Returns an empty list if service discovery has
+     * not yet been performed.
      */
     public List<BluetoothGattService> getServices() {
         List<BluetoothGattService> result =
@@ -989,13 +1048,12 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param uuid UUID of the requested service
-     * @return BluetoothGattService if supported, or null if the requested
-     *         service is not offered by the remote device.
+     * @return BluetoothGattService if supported, or null if the requested service is not offered by
+     * the remote device.
      */
     public BluetoothGattService getService(UUID uuid) {
         for (BluetoothGattService service : mServices) {
-            if (service.getDevice().equals(mDevice) &&
-                service.getUuid().equals(uuid)) {
+            if (service.getDevice().equals(mDevice) && service.getUuid().equals(uuid)) {
                 return service;
             }
         }
@@ -1016,8 +1074,9 @@
      * @return true, if the read operation was initiated successfully
      */
     public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) {
-        if ((characteristic.getProperties() &
-                BluetoothGattCharacteristic.PROPERTY_READ) == 0) return false;
+        if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_READ) == 0) {
+            return false;
+        }
 
         if (VDBG) Log.d(TAG, "readCharacteristic() - uuid: " + characteristic.getUuid());
         if (mService == null || mClientIf == 0) return false;
@@ -1028,16 +1087,16 @@
         BluetoothDevice device = service.getDevice();
         if (device == null) return false;
 
-        synchronized(mDeviceBusy) {
+        synchronized (mDeviceBusy) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
 
         try {
             mService.readCharacteristic(mClientIf, device.getAddress(),
-                characteristic.getInstanceId(), AUTHENTICATION_NONE);
+                    characteristic.getInstanceId(), AUTHENTICATION_NONE);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             mDeviceBusy = false;
             return false;
         }
@@ -1062,16 +1121,16 @@
         if (VDBG) Log.d(TAG, "readUsingCharacteristicUuid() - uuid: " + uuid);
         if (mService == null || mClientIf == 0) return false;
 
-        synchronized(mDeviceBusy) {
+        synchronized (mDeviceBusy) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
 
         try {
             mService.readUsingCharacteristicUuid(mClientIf, mDevice.getAddress(),
-                new ParcelUuid(uuid), startHandle, endHandle, AUTHENTICATION_NONE);
+                    new ParcelUuid(uuid), startHandle, endHandle, AUTHENTICATION_NONE);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             mDeviceBusy = false;
             return false;
         }
@@ -1094,8 +1153,10 @@
      */
     public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
         if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0
-            && (characteristic.getProperties() &
-                BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) return false;
+                && (characteristic.getProperties()
+                & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) {
+            return false;
+        }
 
         if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
         if (mService == null || mClientIf == 0 || characteristic.getValue() == null) return false;
@@ -1106,17 +1167,17 @@
         BluetoothDevice device = service.getDevice();
         if (device == null) return false;
 
-        synchronized(mDeviceBusy) {
+        synchronized (mDeviceBusy) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
 
         try {
             mService.writeCharacteristic(mClientIf, device.getAddress(),
-                characteristic.getInstanceId(), characteristic.getWriteType(),
-                AUTHENTICATION_NONE, characteristic.getValue());
+                    characteristic.getInstanceId(), characteristic.getWriteType(),
+                    AUTHENTICATION_NONE, characteristic.getValue());
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             mDeviceBusy = false;
             return false;
         }
@@ -1149,16 +1210,16 @@
         BluetoothDevice device = service.getDevice();
         if (device == null) return false;
 
-        synchronized(mDeviceBusy) {
+        synchronized (mDeviceBusy) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
 
         try {
             mService.readDescriptor(mClientIf, device.getAddress(),
-                descriptor.getInstanceId(), AUTHENTICATION_NONE);
+                    descriptor.getInstanceId(), AUTHENTICATION_NONE);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             mDeviceBusy = false;
             return false;
         }
@@ -1190,16 +1251,16 @@
         BluetoothDevice device = service.getDevice();
         if (device == null) return false;
 
-        synchronized(mDeviceBusy) {
+        synchronized (mDeviceBusy) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
 
         try {
             mService.writeDescriptor(mClientIf, device.getAddress(), descriptor.getInstanceId(),
-                AUTHENTICATION_NONE, descriptor.getValue());
+                    AUTHENTICATION_NONE, descriptor.getValue());
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             mDeviceBusy = false;
             return false;
         }
@@ -1234,7 +1295,7 @@
         try {
             mService.beginReliableWrite(mClientIf, mDevice.getAddress());
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return false;
         }
 
@@ -1258,7 +1319,7 @@
         if (VDBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress());
         if (mService == null || mClientIf == 0) return false;
 
-        synchronized(mDeviceBusy) {
+        synchronized (mDeviceBusy) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
@@ -1266,7 +1327,7 @@
         try {
             mService.endReliableWrite(mClientIf, mDevice.getAddress(), true);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             mDeviceBusy = false;
             return false;
         }
@@ -1289,7 +1350,7 @@
         try {
             mService.endReliableWrite(mClientIf, mDevice.getAddress(), false);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
         }
     }
 
@@ -1316,9 +1377,11 @@
      * @return true, if the requested notification status was set successfully
      */
     public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
-                                              boolean enable) {
-        if (DBG) Log.d(TAG, "setCharacteristicNotification() - uuid: " + characteristic.getUuid()
-                         + " enable: " + enable);
+            boolean enable) {
+        if (DBG) {
+            Log.d(TAG, "setCharacteristicNotification() - uuid: " + characteristic.getUuid()
+                    + " enable: " + enable);
+        }
         if (mService == null || mClientIf == 0) return false;
 
         BluetoothGattService service = characteristic.getService();
@@ -1329,9 +1392,9 @@
 
         try {
             mService.registerForNotification(mClientIf, device.getAddress(),
-                characteristic.getInstanceId(), enable);
+                    characteristic.getInstanceId(), enable);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return false;
         }
 
@@ -1341,6 +1404,7 @@
     /**
      * Clears the internal cache and forces a refresh of the services from the
      * remote device.
+     *
      * @hide
      */
     public boolean refresh() {
@@ -1350,7 +1414,7 @@
         try {
             mService.refreshDevice(mClientIf, mDevice.getAddress());
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return false;
         }
 
@@ -1374,7 +1438,7 @@
         try {
             mService.readRemoteRssi(mClientIf, mDevice.getAddress());
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return false;
         }
 
@@ -1396,14 +1460,16 @@
      * @return true, if the new MTU value has been requested successfully
      */
     public boolean requestMtu(int mtu) {
-        if (DBG) Log.d(TAG, "configureMTU() - device: " + mDevice.getAddress()
-                            + " mtu: " + mtu);
+        if (DBG) {
+            Log.d(TAG, "configureMTU() - device: " + mDevice.getAddress()
+                    + " mtu: " + mtu);
+        }
         if (mService == null || mClientIf == 0) return false;
 
         try {
             mService.configureMTU(mClientIf, mDevice.getAddress(), mtu);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return false;
         }
 
@@ -1416,16 +1482,14 @@
      * <p>This function will send a connection parameter update request to the
      * remote device.
      *
-     * @param connectionPriority Request a specific connection priority. Must be one of
-     *          {@link BluetoothGatt#CONNECTION_PRIORITY_BALANCED},
-     *          {@link BluetoothGatt#CONNECTION_PRIORITY_HIGH}
-     *          or {@link BluetoothGatt#CONNECTION_PRIORITY_LOW_POWER}.
-     * @throws IllegalArgumentException If the parameters are outside of their
-     *                                  specified range.
+     * @param connectionPriority Request a specific connection priority. Must be one of {@link
+     * BluetoothGatt#CONNECTION_PRIORITY_BALANCED}, {@link BluetoothGatt#CONNECTION_PRIORITY_HIGH}
+     * or {@link BluetoothGatt#CONNECTION_PRIORITY_LOW_POWER}.
+     * @throws IllegalArgumentException If the parameters are outside of their specified range.
      */
     public boolean requestConnectionPriority(int connectionPriority) {
-        if (connectionPriority < CONNECTION_PRIORITY_BALANCED ||
-            connectionPriority > CONNECTION_PRIORITY_LOW_POWER) {
+        if (connectionPriority < CONNECTION_PRIORITY_BALANCED
+                || connectionPriority > CONNECTION_PRIORITY_LOW_POWER) {
             throw new IllegalArgumentException("connectionPriority not within valid range");
         }
 
@@ -1435,7 +1499,7 @@
         try {
             mService.connectionParameterUpdate(mClientIf, mDevice.getAddress(), connectionPriority);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return false;
         }
 
@@ -1461,8 +1525,8 @@
      */
     @Override
     public List<BluetoothDevice> getConnectedDevices() {
-        throw new UnsupportedOperationException
-            ("Use BluetoothManager#getConnectedDevices instead.");
+        throw new UnsupportedOperationException(
+                "Use BluetoothManager#getConnectedDevices instead.");
     }
 
     /**
@@ -1474,7 +1538,7 @@
      */
     @Override
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        throw new UnsupportedOperationException
-            ("Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
+        throw new UnsupportedOperationException(
+                "Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java
index c6f82ff..cf82a33 100644
--- a/core/java/android/bluetooth/BluetoothGattCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattCallback.java
@@ -19,19 +19,19 @@
 /**
  * This abstract class is used to implement {@link BluetoothGatt} callbacks.
  */
-public abstract class BluetoothGattCallback{
+public abstract class BluetoothGattCallback {
 
     /**
      * Callback triggered as result of {@link BluetoothGatt#setPreferredPhy}, or as a result of
      * remote device changing the PHY.
      *
      * @param gatt GATT client
-     * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
-     *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
-     * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
-     *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
-     * @param status Status of the PHY update operation.
-     *                  {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
+     * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
+     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
+     * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
+     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
+     * @param status Status of the PHY update operation. {@link BluetoothGatt#GATT_SUCCESS} if the
+     * operation succeeds.
      */
     public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
     }
@@ -40,12 +40,12 @@
      * Callback triggered as result of {@link BluetoothGatt#readPhy}
      *
      * @param gatt GATT client
-     * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
-     *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
-     * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
-     *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
-     * @param status Status of the PHY read operation.
-     *                  {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
+     * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
+     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
+     * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
+     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
+     * @param status Status of the PHY read operation. {@link BluetoothGatt#GATT_SUCCESS} if the
+     * operation succeeds.
      */
     public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
     }
@@ -55,14 +55,13 @@
      * GATT server.
      *
      * @param gatt GATT client
-     * @param status Status of the connect or disconnect operation.
-     *               {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
-     * @param newState Returns the new connection state. Can be one of
-     *                  {@link BluetoothProfile#STATE_DISCONNECTED} or
-     *                  {@link BluetoothProfile#STATE_CONNECTED}
+     * @param status Status of the connect or disconnect operation. {@link
+     * BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
+     * @param newState Returns the new connection state. Can be one of {@link
+     * BluetoothProfile#STATE_DISCONNECTED} or {@link BluetoothProfile#STATE_CONNECTED}
      */
     public void onConnectionStateChange(BluetoothGatt gatt, int status,
-                                        int newState) {
+            int newState) {
     }
 
     /**
@@ -70,8 +69,8 @@
      * for the remote device have been updated, ie new services have been discovered.
      *
      * @param gatt GATT client invoked {@link BluetoothGatt#discoverServices}
-     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the remote device
-     *               has been explored successfully.
+     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the remote device has been explored
+     * successfully.
      */
     public void onServicesDiscovered(BluetoothGatt gatt, int status) {
     }
@@ -80,13 +79,12 @@
      * Callback reporting the result of a characteristic read operation.
      *
      * @param gatt GATT client invoked {@link BluetoothGatt#readCharacteristic}
-     * @param characteristic Characteristic that was read from the associated
-     *                       remote device.
-     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation
-     *               was completed successfully.
+     * @param characteristic Characteristic that was read from the associated remote device.
+     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation was completed
+     * successfully.
      */
     public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
-                                     int status) {
+            int status) {
     }
 
     /**
@@ -99,58 +97,55 @@
      * the application must abort the reliable write transaction.
      *
      * @param gatt GATT client invoked {@link BluetoothGatt#writeCharacteristic}
-     * @param characteristic Characteristic that was written to the associated
-     *                       remote device.
-     * @param status The result of the write operation
-     *               {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
+     * @param characteristic Characteristic that was written to the associated remote device.
+     * @param status The result of the write operation {@link BluetoothGatt#GATT_SUCCESS} if the
+     * operation succeeds.
      */
     public void onCharacteristicWrite(BluetoothGatt gatt,
-                                      BluetoothGattCharacteristic characteristic, int status) {
+            BluetoothGattCharacteristic characteristic, int status) {
     }
 
     /**
      * Callback triggered as a result of a remote characteristic notification.
      *
      * @param gatt GATT client the characteristic is associated with
-     * @param characteristic Characteristic that has been updated as a result
-     *                       of a remote notification event.
+     * @param characteristic Characteristic that has been updated as a result of a remote
+     * notification event.
      */
     public void onCharacteristicChanged(BluetoothGatt gatt,
-                                        BluetoothGattCharacteristic characteristic) {
+            BluetoothGattCharacteristic characteristic) {
     }
 
     /**
      * Callback reporting the result of a descriptor read operation.
      *
      * @param gatt GATT client invoked {@link BluetoothGatt#readDescriptor}
-     * @param descriptor Descriptor that was read from the associated
-     *                   remote device.
-     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation
-     *               was completed successfully
+     * @param descriptor Descriptor that was read from the associated remote device.
+     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation was completed
+     * successfully
      */
     public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
-                                 int status) {
+            int status) {
     }
 
     /**
      * Callback indicating the result of a descriptor write operation.
      *
      * @param gatt GATT client invoked {@link BluetoothGatt#writeDescriptor}
-     * @param descriptor Descriptor that was writte to the associated
-     *                   remote device.
-     * @param status The result of the write operation
-     *               {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
+     * @param descriptor Descriptor that was writte to the associated remote device.
+     * @param status The result of the write operation {@link BluetoothGatt#GATT_SUCCESS} if the
+     * operation succeeds.
      */
     public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
-                                  int status) {
+            int status) {
     }
 
     /**
      * Callback invoked when a reliable write transaction has been completed.
      *
      * @param gatt GATT client invoked {@link BluetoothGatt#executeReliableWrite}
-     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the reliable write
-     *               transaction was executed successfully
+     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the reliable write transaction was
+     * executed successfully
      */
     public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
     }
@@ -186,17 +181,17 @@
      * Callback indicating the connection parameters were updated.
      *
      * @param gatt GATT client involved
-     * @param interval Connection interval used on this connection, 1.25ms unit. Valid
-     *            range is from 6 (7.5ms) to 3200 (4000ms).
-     * @param latency Slave latency for the connection in number of connection events. Valid
-     *            range is from 0 to 499
-     * @param timeout Supervision timeout for this connection, in 10ms unit. Valid range is
-     *            from 10 (0.1s) to 3200 (32s)
+     * @param interval Connection interval used on this connection, 1.25ms unit. Valid range is from
+     * 6 (7.5ms) to 3200 (4000ms).
+     * @param latency Slave latency for the connection in number of connection events. Valid range
+     * is from 0 to 499
+     * @param timeout Supervision timeout for this connection, in 10ms unit. Valid range is from 10
+     * (0.1s) to 3200 (32s)
      * @param status {@link BluetoothGatt#GATT_SUCCESS} if the connection has been updated
-     *                successfully
+     * successfully
      * @hide
      */
     public void onConnectionUpdated(BluetoothGatt gatt, int interval, int latency, int timeout,
-                                    int status) {
+            int status) {
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothGattCharacteristic.java b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
index 1cc2270..2c12403 100644
--- a/core/java/android/bluetooth/BluetoothGattCharacteristic.java
+++ b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
@@ -16,8 +16,9 @@
 package android.bluetooth;
 
 import android.os.Parcel;
-import android.os.Parcelable;
 import android.os.ParcelUuid;
+import android.os.Parcelable;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
@@ -171,30 +172,35 @@
 
     /**
      * The UUID of this characteristic.
+     *
      * @hide
      */
     protected UUID mUuid;
 
     /**
      * Instance ID for this characteristic.
+     *
      * @hide
      */
     protected int mInstance;
 
     /**
      * Characteristic properties.
+     *
      * @hide
      */
     protected int mProperties;
 
     /**
      * Characteristic permissions.
+     *
      * @hide
      */
     protected int mPermissions;
 
     /**
      * Key size (default = 16).
+     *
      * @hide
      */
     protected int mKeySize = 16;
@@ -202,18 +208,21 @@
     /**
      * Write type for this characteristic.
      * See WRITE_TYPE_* constants.
+     *
      * @hide
      */
     protected int mWriteType;
 
     /**
      * Back-reference to the service this characteristic belongs to.
+     *
      * @hide
      */
     protected BluetoothGattService mService;
 
     /**
      * The cached value of this characteristic.
+     *
      * @hide
      */
     protected byte[] mValue;
@@ -237,26 +246,28 @@
 
     /**
      * Create a new BluetoothGattCharacteristic
+     *
      * @hide
      */
     /*package*/ BluetoothGattCharacteristic(BluetoothGattService service,
-                                            UUID uuid, int instanceId,
-                                            int properties, int permissions) {
+            UUID uuid, int instanceId,
+            int properties, int permissions) {
         initCharacteristic(service, uuid, instanceId, properties, permissions);
     }
 
     /**
      * Create a new BluetoothGattCharacteristic
+     *
      * @hide
      */
     public BluetoothGattCharacteristic(UUID uuid, int instanceId,
-                                       int properties, int permissions) {
+            int properties, int permissions) {
         initCharacteristic(null, uuid, instanceId, properties, permissions);
     }
 
     private void initCharacteristic(BluetoothGattService service,
-                                    UUID uuid, int instanceId,
-                                    int properties, int permissions) {
+            UUID uuid, int instanceId,
+            int properties, int permissions) {
         mUuid = uuid;
         mInstance = instanceId;
         mProperties = properties;
@@ -272,13 +283,12 @@
         }
     }
 
-    /**
-     * @hide
-     */
+    @Override
     public int describeContents() {
         return 0;
     }
 
+    @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeParcelable(new ParcelUuid(mUuid), 0);
         out.writeInt(mInstance);
@@ -289,8 +299,8 @@
         out.writeTypedList(mDescriptors);
     }
 
-    public static final Parcelable.Creator<BluetoothGattCharacteristic> CREATOR
-            = new Parcelable.Creator<BluetoothGattCharacteristic>() {
+    public static final Parcelable.Creator<BluetoothGattCharacteristic> CREATOR =
+            new Parcelable.Creator<BluetoothGattCharacteristic>() {
         public BluetoothGattCharacteristic createFromParcel(Parcel in) {
             return new BluetoothGattCharacteristic(in);
         }
@@ -301,7 +311,7 @@
     };
 
     private BluetoothGattCharacteristic(Parcel in) {
-        mUuid = ((ParcelUuid)in.readParcelable(null)).getUuid();
+        mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
         mInstance = in.readInt();
         mProperties = in.readInt();
         mPermissions = in.readInt();
@@ -313,7 +323,7 @@
         ArrayList<BluetoothGattDescriptor> descs =
                 in.createTypedArrayList(BluetoothGattDescriptor.CREATOR);
         if (descs != null) {
-            for (BluetoothGattDescriptor desc: descs) {
+            for (BluetoothGattDescriptor desc : descs) {
                 desc.setCharacteristic(this);
                 mDescriptors.add(desc);
             }
@@ -322,6 +332,7 @@
 
     /**
      * Returns the desired key size.
+     *
      * @hide
      */
     public int getKeySize() {
@@ -343,12 +354,13 @@
 
     /**
      * Get a descriptor by UUID and isntance id.
+     *
      * @hide
      */
     /*package*/  BluetoothGattDescriptor getDescriptor(UUID uuid, int instanceId) {
-        for(BluetoothGattDescriptor descriptor : mDescriptors) {
+        for (BluetoothGattDescriptor descriptor : mDescriptors) {
             if (descriptor.getUuid().equals(uuid)
-             && descriptor.getInstanceId() == instanceId) {
+                    && descriptor.getInstanceId() == instanceId) {
                 return descriptor;
             }
         }
@@ -357,6 +369,7 @@
 
     /**
      * Returns the service this characteristic belongs to.
+     *
      * @return The asscociated service
      */
     public BluetoothGattService getService() {
@@ -365,6 +378,7 @@
 
     /**
      * Sets the service associated with this device.
+     *
      * @hide
      */
     /*package*/ void setService(BluetoothGattService service) {
@@ -394,6 +408,7 @@
 
     /**
      * Force the instance ID.
+     *
      * @hide
      */
     public void setInstanceId(int instanceId) {
@@ -437,11 +452,8 @@
      * {@link BluetoothGatt#writeCharacteristic} function write this
      * characteristic.
      *
-     * @param writeType The write type to for this characteristic. Can be one
-     *                  of:
-     *                  {@link #WRITE_TYPE_DEFAULT},
-     *                  {@link #WRITE_TYPE_NO_RESPONSE} or
-     *                  {@link #WRITE_TYPE_SIGNED}.
+     * @param writeType The write type to for this characteristic. Can be one of: {@link
+     * #WRITE_TYPE_DEFAULT}, {@link #WRITE_TYPE_NO_RESPONSE} or {@link #WRITE_TYPE_SIGNED}.
      */
     public void setWriteType(int writeType) {
         mWriteType = writeType;
@@ -449,6 +461,7 @@
 
     /**
      * Set the desired key size.
+     *
      * @hide
      */
     public void setKeySize(int keySize) {
@@ -468,11 +481,10 @@
      * Returns a descriptor with a given UUID out of the list of
      * descriptors for this characteristic.
      *
-     * @return GATT descriptor object or null if no descriptor with the
-     *         given UUID was found.
+     * @return GATT descriptor object or null if no descriptor with the given UUID was found.
      */
     public BluetoothGattDescriptor getDescriptor(UUID uuid) {
-        for(BluetoothGattDescriptor descriptor : mDescriptors) {
+        for (BluetoothGattDescriptor descriptor : mDescriptors) {
             if (descriptor.getUuid().equals(uuid)) {
                 return descriptor;
             }
@@ -503,11 +515,9 @@
      * characteristic value at the given offset are interpreted to generate the
      * return value.
      *
-     * @param formatType The format type used to interpret the characteristic
-     *                   value.
+     * @param formatType The format type used to interpret the characteristic value.
      * @param offset Offset at which the integer value can be found.
-     * @return Cached value of the characteristic or null of offset exceeds
-     *         value size.
+     * @return Cached value of the characteristic or null of offset exceeds value size.
      */
     public Integer getIntValue(int formatType, int offset) {
         if ((offset + getTypeLen(formatType)) > mValue.length) return null;
@@ -517,21 +527,21 @@
                 return unsignedByteToInt(mValue[offset]);
 
             case FORMAT_UINT16:
-                return unsignedBytesToInt(mValue[offset], mValue[offset+1]);
+                return unsignedBytesToInt(mValue[offset], mValue[offset + 1]);
 
             case FORMAT_UINT32:
-                return unsignedBytesToInt(mValue[offset],   mValue[offset+1],
-                                          mValue[offset+2], mValue[offset+3]);
+                return unsignedBytesToInt(mValue[offset], mValue[offset + 1],
+                        mValue[offset + 2], mValue[offset + 3]);
             case FORMAT_SINT8:
                 return unsignedToSigned(unsignedByteToInt(mValue[offset]), 8);
 
             case FORMAT_SINT16:
                 return unsignedToSigned(unsignedBytesToInt(mValue[offset],
-                                                           mValue[offset+1]), 16);
+                        mValue[offset + 1]), 16);
 
             case FORMAT_SINT32:
                 return unsignedToSigned(unsignedBytesToInt(mValue[offset],
-                        mValue[offset+1], mValue[offset+2], mValue[offset+3]), 32);
+                        mValue[offset + 1], mValue[offset + 2], mValue[offset + 3]), 32);
         }
 
         return null;
@@ -541,22 +551,21 @@
      * Return the stored value of this characteristic.
      * <p>See {@link #getValue} for details.
      *
-     * @param formatType The format type used to interpret the characteristic
-     *                   value.
+     * @param formatType The format type used to interpret the characteristic value.
      * @param offset Offset at which the float value can be found.
-     * @return Cached value of the characteristic at a given offset or null
-     *         if the requested offset exceeds the value size.
+     * @return Cached value of the characteristic at a given offset or null if the requested offset
+     * exceeds the value size.
      */
     public Float getFloatValue(int formatType, int offset) {
         if ((offset + getTypeLen(formatType)) > mValue.length) return null;
 
         switch (formatType) {
             case FORMAT_SFLOAT:
-                return bytesToFloat(mValue[offset], mValue[offset+1]);
+                return bytesToFloat(mValue[offset], mValue[offset + 1]);
 
             case FORMAT_FLOAT:
-                return bytesToFloat(mValue[offset],   mValue[offset+1],
-                                    mValue[offset+2], mValue[offset+3]);
+                return bytesToFloat(mValue[offset], mValue[offset + 1],
+                        mValue[offset + 2], mValue[offset + 3]);
         }
 
         return null;
@@ -572,7 +581,7 @@
     public String getStringValue(int offset) {
         if (mValue == null || offset > mValue.length) return null;
         byte[] strBytes = new byte[mValue.length - offset];
-        for (int i=0; i != (mValue.length-offset); ++i) strBytes[i] = mValue[offset+i];
+        for (int i = 0; i != (mValue.length - offset); ++i) strBytes[i] = mValue[offset + i];
         return new String(strBytes);
     }
 
@@ -585,8 +594,8 @@
      * remote device.
      *
      * @param value New value for this characteristic
-     * @return true if the locally stored value has been set, false if the
-     *              requested value could not be stored locally.
+     * @return true if the locally stored value has been set, false if the requested value could not
+     * be stored locally.
      */
     public boolean setValue(byte[] value) {
         mValue = value;
@@ -612,25 +621,25 @@
                 value = intToSignedBits(value, 8);
                 // Fall-through intended
             case FORMAT_UINT8:
-                mValue[offset] = (byte)(value & 0xFF);
+                mValue[offset] = (byte) (value & 0xFF);
                 break;
 
             case FORMAT_SINT16:
                 value = intToSignedBits(value, 16);
                 // Fall-through intended
             case FORMAT_UINT16:
-                mValue[offset++] = (byte)(value & 0xFF);
-                mValue[offset] = (byte)((value >> 8) & 0xFF);
+                mValue[offset++] = (byte) (value & 0xFF);
+                mValue[offset] = (byte) ((value >> 8) & 0xFF);
                 break;
 
             case FORMAT_SINT32:
                 value = intToSignedBits(value, 32);
                 // Fall-through intended
             case FORMAT_UINT32:
-                mValue[offset++] = (byte)(value & 0xFF);
-                mValue[offset++] = (byte)((value >> 8) & 0xFF);
-                mValue[offset++] = (byte)((value >> 16) & 0xFF);
-                mValue[offset] = (byte)((value >> 24) & 0xFF);
+                mValue[offset++] = (byte) (value & 0xFF);
+                mValue[offset++] = (byte) ((value >> 8) & 0xFF);
+                mValue[offset++] = (byte) ((value >> 16) & 0xFF);
+                mValue[offset] = (byte) ((value >> 24) & 0xFF);
                 break;
 
             default:
@@ -644,7 +653,7 @@
      * <p>See {@link #setValue(byte[])} for details.
      *
      * @param mantissa Mantissa for this characteristic
-     * @param exponent  exponent value for this characteristic
+     * @param exponent exponent value for this characteristic
      * @param formatType Float format type used to transform the value parameter
      * @param offset Offset at which the value should be placed
      * @return true if the locally stored value has been set
@@ -658,18 +667,18 @@
             case FORMAT_SFLOAT:
                 mantissa = intToSignedBits(mantissa, 12);
                 exponent = intToSignedBits(exponent, 4);
-                mValue[offset++] = (byte)(mantissa & 0xFF);
-                mValue[offset] = (byte)((mantissa >> 8) & 0x0F);
-                mValue[offset] += (byte)((exponent & 0x0F) << 4);
+                mValue[offset++] = (byte) (mantissa & 0xFF);
+                mValue[offset] = (byte) ((mantissa >> 8) & 0x0F);
+                mValue[offset] += (byte) ((exponent & 0x0F) << 4);
                 break;
 
             case FORMAT_FLOAT:
                 mantissa = intToSignedBits(mantissa, 24);
                 exponent = intToSignedBits(exponent, 8);
-                mValue[offset++] = (byte)(mantissa & 0xFF);
-                mValue[offset++] = (byte)((mantissa >> 8) & 0xFF);
-                mValue[offset++] = (byte)((mantissa >> 16) & 0xFF);
-                mValue[offset] += (byte)(exponent & 0xFF);
+                mValue[offset++] = (byte) (mantissa & 0xFF);
+                mValue[offset++] = (byte) ((mantissa >> 8) & 0xFF);
+                mValue[offset++] = (byte) ((mantissa >> 16) & 0xFF);
+                mValue[offset] += (byte) (exponent & 0xFF);
                 break;
 
             default:
@@ -717,7 +726,7 @@
      */
     private int unsignedBytesToInt(byte b0, byte b1, byte b2, byte b3) {
         return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8))
-             + (unsignedByteToInt(b2) << 16) + (unsignedByteToInt(b3) << 24);
+                + (unsignedByteToInt(b2) << 16) + (unsignedByteToInt(b3) << 24);
     }
 
     /**
@@ -725,9 +734,9 @@
      */
     private float bytesToFloat(byte b0, byte b1) {
         int mantissa = unsignedToSigned(unsignedByteToInt(b0)
-                        + ((unsignedByteToInt(b1) & 0x0F) << 8), 12);
+                + ((unsignedByteToInt(b1) & 0x0F) << 8), 12);
         int exponent = unsignedToSigned(unsignedByteToInt(b1) >> 4, 4);
-        return (float)(mantissa * Math.pow(10, exponent));
+        return (float) (mantissa * Math.pow(10, exponent));
     }
 
     /**
@@ -735,9 +744,9 @@
      */
     private float bytesToFloat(byte b0, byte b1, byte b2, byte b3) {
         int mantissa = unsignedToSigned(unsignedByteToInt(b0)
-                        + (unsignedByteToInt(b1) << 8)
-                        + (unsignedByteToInt(b2) << 16), 24);
-        return (float)(mantissa * Math.pow(10, b3));
+                + (unsignedByteToInt(b1) << 8)
+                + (unsignedByteToInt(b2) << 16), 24);
+        return (float) (mantissa * Math.pow(10, b3));
     }
 
     /**
@@ -745,8 +754,8 @@
      * signed value.
      */
     private int unsignedToSigned(int unsigned, int size) {
-        if ((unsigned & (1 << size-1)) != 0) {
-            unsigned = -1 * ((1 << size-1) - (unsigned & ((1 << size-1) - 1)));
+        if ((unsigned & (1 << size - 1)) != 0) {
+            unsigned = -1 * ((1 << size - 1) - (unsigned & ((1 << size - 1) - 1)));
         }
         return unsigned;
     }
@@ -756,7 +765,7 @@
      */
     private int intToSignedBits(int i, int size) {
         if (i < 0) {
-            i = (1 << size-1) + (i & ((1 << size-1) - 1));
+            i = (1 << size - 1) + (i & ((1 << size - 1) - 1));
         }
         return i;
     }
diff --git a/core/java/android/bluetooth/BluetoothGattDescriptor.java b/core/java/android/bluetooth/BluetoothGattDescriptor.java
index 1a4fa48..217a5ab 100644
--- a/core/java/android/bluetooth/BluetoothGattDescriptor.java
+++ b/core/java/android/bluetooth/BluetoothGattDescriptor.java
@@ -17,8 +17,9 @@
 package android.bluetooth;
 
 import android.os.Parcel;
-import android.os.Parcelable;
 import android.os.ParcelUuid;
+import android.os.Parcelable;
+
 import java.util.UUID;
 
 /**
@@ -89,30 +90,35 @@
 
     /**
      * The UUID of this descriptor.
+     *
      * @hide
      */
     protected UUID mUuid;
 
     /**
      * Instance ID for this descriptor.
+     *
      * @hide
      */
     protected int mInstance;
 
     /**
      * Permissions for this descriptor
+     *
      * @hide
      */
     protected int mPermissions;
 
     /**
      * Back-reference to the characteristic this descriptor belongs to.
+     *
      * @hide
      */
     protected BluetoothGattCharacteristic mCharacteristic;
 
     /**
      * The value for this descriptor.
+     *
      * @hide
      */
     protected byte[] mValue;
@@ -137,7 +143,7 @@
      * @param permissions Permissions for this descriptor
      */
     /*package*/ BluetoothGattDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
-                                    int instance, int permissions) {
+            int instance, int permissions) {
         initDescriptor(characteristic, uuid, instance, permissions);
     }
 
@@ -149,28 +155,27 @@
     }
 
     private void initDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
-                                int instance, int permissions) {
+            int instance, int permissions) {
         mCharacteristic = characteristic;
         mUuid = uuid;
         mInstance = instance;
         mPermissions = permissions;
     }
 
-    /**
-     * @hide
-     */
+    @Override
     public int describeContents() {
         return 0;
     }
 
+    @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeParcelable(new ParcelUuid(mUuid), 0);
         out.writeInt(mInstance);
         out.writeInt(mPermissions);
     }
 
-    public static final Parcelable.Creator<BluetoothGattDescriptor> CREATOR
-            = new Parcelable.Creator<BluetoothGattDescriptor>() {
+    public static final Parcelable.Creator<BluetoothGattDescriptor> CREATOR =
+            new Parcelable.Creator<BluetoothGattDescriptor>() {
         public BluetoothGattDescriptor createFromParcel(Parcel in) {
             return new BluetoothGattDescriptor(in);
         }
@@ -181,13 +186,14 @@
     };
 
     private BluetoothGattDescriptor(Parcel in) {
-        mUuid = ((ParcelUuid)in.readParcelable(null)).getUuid();
+        mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
         mInstance = in.readInt();
         mPermissions = in.readInt();
     }
 
     /**
      * Returns the characteristic this descriptor belongs to.
+     *
      * @return The characteristic.
      */
     public BluetoothGattCharacteristic getCharacteristic() {
@@ -196,6 +202,7 @@
 
     /**
      * Set the back-reference to the associated characteristic
+     *
      * @hide
      */
     /*package*/ void setCharacteristic(BluetoothGattCharacteristic characteristic) {
@@ -228,6 +235,7 @@
 
     /**
      * Force the instance ID.
+     *
      * @hide
      */
     public void setInstanceId(int instanceId) {
@@ -266,8 +274,8 @@
      * remote device.
      *
      * @param value New value for this descriptor
-     * @return true if the locally stored value has been set, false if the
-     *              requested value could not be stored locally.
+     * @return true if the locally stored value has been set, false if the requested value could not
+     * be stored locally.
      */
     public boolean setValue(byte[] value) {
         mValue = value;
diff --git a/core/java/android/bluetooth/BluetoothGattIncludedService.java b/core/java/android/bluetooth/BluetoothGattIncludedService.java
index 155dc57..bccf20e 100644
--- a/core/java/android/bluetooth/BluetoothGattIncludedService.java
+++ b/core/java/android/bluetooth/BluetoothGattIncludedService.java
@@ -16,14 +16,14 @@
 package android.bluetooth;
 
 import android.os.Parcel;
-import android.os.Parcelable;
 import android.os.ParcelUuid;
-import java.util.ArrayList;
-import java.util.List;
+import android.os.Parcelable;
+
 import java.util.UUID;
 
 /**
  * Represents a Bluetooth GATT Included Service
+ *
  * @hide
  */
 public class BluetoothGattIncludedService implements Parcelable {
@@ -52,18 +52,20 @@
         mServiceType = serviceType;
     }
 
+    @Override
     public int describeContents() {
         return 0;
     }
 
+    @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeParcelable(new ParcelUuid(mUuid), 0);
         out.writeInt(mInstanceId);
         out.writeInt(mServiceType);
-     }
+    }
 
-    public static final Parcelable.Creator<BluetoothGattIncludedService> CREATOR
-            = new Parcelable.Creator<BluetoothGattIncludedService>() {
+    public static final Parcelable.Creator<BluetoothGattIncludedService> CREATOR =
+            new Parcelable.Creator<BluetoothGattIncludedService>() {
         public BluetoothGattIncludedService createFromParcel(Parcel in) {
             return new BluetoothGattIncludedService(in);
         }
@@ -74,7 +76,7 @@
     };
 
     private BluetoothGattIncludedService(Parcel in) {
-        mUuid = ((ParcelUuid)in.readParcelable(null)).getUuid();
+        mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
         mInstanceId = in.readInt();
         mServiceType = in.readInt();
     }
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index eddc278..4ed2500 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -16,10 +16,6 @@
 
 package android.bluetooth;
 
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
-import android.content.Context;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
 import android.util.Log;
@@ -60,300 +56,322 @@
      * Bluetooth GATT interface callbacks
      */
     private final IBluetoothGattServerCallback mBluetoothGattServerCallback =
-        new IBluetoothGattServerCallback.Stub() {
-            /**
-             * Application interface registered - app is ready to go
-             * @hide
-             */
-            @Override
-            public void onServerRegistered(int status, int serverIf) {
-                if (DBG) Log.d(TAG, "onServerRegistered() - status=" + status
-                    + " serverIf=" + serverIf);
-                synchronized(mServerIfLock) {
-                    if (mCallback != null) {
-                        mServerIf = serverIf;
-                        mServerIfLock.notify();
-                    } else {
-                        // registration timeout
-                        Log.e(TAG, "onServerRegistered: mCallback is null");
+            new IBluetoothGattServerCallback.Stub() {
+                /**
+                 * Application interface registered - app is ready to go
+                 * @hide
+                 */
+                @Override
+                public void onServerRegistered(int status, int serverIf) {
+                    if (DBG) {
+                        Log.d(TAG, "onServerRegistered() - status=" + status
+                                + " serverIf=" + serverIf);
                     }
-                }
-            }
-
-            /**
-             * Server connection state changed
-             * @hide
-             */
-            @Override
-            public void onServerConnectionState(int status, int serverIf,
-                                                boolean connected, String address) {
-                if (DBG) Log.d(TAG, "onServerConnectionState() - status=" + status
-                    + " serverIf=" + serverIf + " device=" + address);
-                try {
-                    mCallback.onConnectionStateChange(mAdapter.getRemoteDevice(address), status,
-                                                      connected ? BluetoothProfile.STATE_CONNECTED :
-                                                      BluetoothProfile.STATE_DISCONNECTED);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
-            }
-
-            /**
-             * Service has been added
-             * @hide
-             */
-            @Override
-            public void onServiceAdded(int status, BluetoothGattService service) {
-                if (DBG) Log.d(TAG, "onServiceAdded() - handle=" + service.getInstanceId()
-                    + " uuid=" + service.getUuid() + " status=" + status);
-
-                if (mPendingService == null)
-                    return;
-
-                BluetoothGattService tmp = mPendingService;
-                mPendingService = null;
-
-                // Rewrite newly assigned handles to existing service.
-                tmp.setInstanceId(service.getInstanceId());
-                List<BluetoothGattCharacteristic> temp_chars = tmp.getCharacteristics();
-                List<BluetoothGattCharacteristic> svc_chars = service.getCharacteristics();
-                for (int i=0; i<svc_chars.size(); i++) {
-                    BluetoothGattCharacteristic temp_char = temp_chars.get(i);
-                    BluetoothGattCharacteristic svc_char = svc_chars.get(i);
-
-                    temp_char.setInstanceId(svc_char.getInstanceId());
-
-                    List<BluetoothGattDescriptor> temp_descs = temp_char.getDescriptors();
-                    List<BluetoothGattDescriptor> svc_descs = svc_char.getDescriptors();
-                    for (int j=0; j<svc_descs.size(); j++) {
-                        temp_descs.get(j).setInstanceId(svc_descs.get(j).getInstanceId());
+                    synchronized (mServerIfLock) {
+                        if (mCallback != null) {
+                            mServerIf = serverIf;
+                            mServerIfLock.notify();
+                        } else {
+                            // registration timeout
+                            Log.e(TAG, "onServerRegistered: mCallback is null");
+                        }
                     }
                 }
 
-                mServices.add(tmp);
-
-                try {
-                    mCallback.onServiceAdded((int)status, tmp);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
-            }
-
-            /**
-             * Remote client characteristic read request.
-             * @hide
-             */
-            @Override
-            public void onCharacteristicReadRequest(String address, int transId,
-                            int offset, boolean isLong, int handle) {
-                if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle);
-
-                BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                BluetoothGattCharacteristic characteristic = getCharacteristicByHandle(handle);
-                if (characteristic == null) {
-                    Log.w(TAG, "onCharacteristicReadRequest() no char for handle " + handle);
-                    return;
+                /**
+                 * Server connection state changed
+                 * @hide
+                 */
+                @Override
+                public void onServerConnectionState(int status, int serverIf,
+                        boolean connected, String address) {
+                    if (DBG) {
+                        Log.d(TAG, "onServerConnectionState() - status=" + status
+                                + " serverIf=" + serverIf + " device=" + address);
+                    }
+                    try {
+                        mCallback.onConnectionStateChange(mAdapter.getRemoteDevice(address), status,
+                                connected ? BluetoothProfile.STATE_CONNECTED :
+                                        BluetoothProfile.STATE_DISCONNECTED);
+                    } catch (Exception ex) {
+                        Log.w(TAG, "Unhandled exception in callback", ex);
+                    }
                 }
 
-                try {
-                    mCallback.onCharacteristicReadRequest(device, transId, offset, characteristic);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
-            }
+                /**
+                 * Service has been added
+                 * @hide
+                 */
+                @Override
+                public void onServiceAdded(int status, BluetoothGattService service) {
+                    if (DBG) {
+                        Log.d(TAG, "onServiceAdded() - handle=" + service.getInstanceId()
+                                + " uuid=" + service.getUuid() + " status=" + status);
+                    }
 
-            /**
-             * Remote client descriptor read request.
-             * @hide
-             */
-            @Override
-            public void onDescriptorReadRequest(String address, int transId,
-                            int offset, boolean isLong, int handle) {
-                if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle);
+                    if (mPendingService == null) {
+                        return;
+                    }
 
-                BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                BluetoothGattDescriptor descriptor = getDescriptorByHandle(handle);
-                if (descriptor == null) {
-                    Log.w(TAG, "onDescriptorReadRequest() no desc for handle " + handle);
-                    return;
+                    BluetoothGattService tmp = mPendingService;
+                    mPendingService = null;
+
+                    // Rewrite newly assigned handles to existing service.
+                    tmp.setInstanceId(service.getInstanceId());
+                    List<BluetoothGattCharacteristic> temp_chars = tmp.getCharacteristics();
+                    List<BluetoothGattCharacteristic> svc_chars = service.getCharacteristics();
+                    for (int i = 0; i < svc_chars.size(); i++) {
+                        BluetoothGattCharacteristic temp_char = temp_chars.get(i);
+                        BluetoothGattCharacteristic svc_char = svc_chars.get(i);
+
+                        temp_char.setInstanceId(svc_char.getInstanceId());
+
+                        List<BluetoothGattDescriptor> temp_descs = temp_char.getDescriptors();
+                        List<BluetoothGattDescriptor> svc_descs = svc_char.getDescriptors();
+                        for (int j = 0; j < svc_descs.size(); j++) {
+                            temp_descs.get(j).setInstanceId(svc_descs.get(j).getInstanceId());
+                        }
+                    }
+
+                    mServices.add(tmp);
+
+                    try {
+                        mCallback.onServiceAdded((int) status, tmp);
+                    } catch (Exception ex) {
+                        Log.w(TAG, "Unhandled exception in callback", ex);
+                    }
                 }
 
-                try {
-                    mCallback.onDescriptorReadRequest(device, transId, offset, descriptor);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
-            }
+                /**
+                 * Remote client characteristic read request.
+                 * @hide
+                 */
+                @Override
+                public void onCharacteristicReadRequest(String address, int transId,
+                        int offset, boolean isLong, int handle) {
+                    if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle);
 
-            /**
-             * Remote client characteristic write request.
-             * @hide
-             */
-            @Override
-            public void onCharacteristicWriteRequest(String address, int transId,
-                            int offset, int length, boolean isPrep, boolean needRsp,
-                            int handle, byte[] value) {
-                if (VDBG) Log.d(TAG, "onCharacteristicWriteRequest() - handle=" + handle);
+                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
+                    BluetoothGattCharacteristic characteristic = getCharacteristicByHandle(handle);
+                    if (characteristic == null) {
+                        Log.w(TAG, "onCharacteristicReadRequest() no char for handle " + handle);
+                        return;
+                    }
 
-                BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                BluetoothGattCharacteristic characteristic = getCharacteristicByHandle(handle);
-                if (characteristic == null) {
-                    Log.w(TAG, "onCharacteristicWriteRequest() no char for handle " + handle);
-                    return;
+                    try {
+                        mCallback.onCharacteristicReadRequest(device, transId, offset,
+                                characteristic);
+                    } catch (Exception ex) {
+                        Log.w(TAG, "Unhandled exception in callback", ex);
+                    }
                 }
 
-                try {
-                    mCallback.onCharacteristicWriteRequest(device, transId, characteristic,
-                                                           isPrep, needRsp, offset, value);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
+                /**
+                 * Remote client descriptor read request.
+                 * @hide
+                 */
+                @Override
+                public void onDescriptorReadRequest(String address, int transId,
+                        int offset, boolean isLong, int handle) {
+                    if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle);
+
+                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
+                    BluetoothGattDescriptor descriptor = getDescriptorByHandle(handle);
+                    if (descriptor == null) {
+                        Log.w(TAG, "onDescriptorReadRequest() no desc for handle " + handle);
+                        return;
+                    }
+
+                    try {
+                        mCallback.onDescriptorReadRequest(device, transId, offset, descriptor);
+                    } catch (Exception ex) {
+                        Log.w(TAG, "Unhandled exception in callback", ex);
+                    }
                 }
 
-            }
+                /**
+                 * Remote client characteristic write request.
+                 * @hide
+                 */
+                @Override
+                public void onCharacteristicWriteRequest(String address, int transId,
+                        int offset, int length, boolean isPrep, boolean needRsp,
+                        int handle, byte[] value) {
+                    if (VDBG) Log.d(TAG, "onCharacteristicWriteRequest() - handle=" + handle);
 
-            /**
-             * Remote client descriptor write request.
-             * @hide
-             */
-            @Override
-            public void onDescriptorWriteRequest(String address, int transId, int offset,
-                            int length, boolean isPrep, boolean needRsp, int handle, byte[] value) {
-                if (VDBG) Log.d(TAG, "onDescriptorWriteRequest() - handle=" + handle);
+                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
+                    BluetoothGattCharacteristic characteristic = getCharacteristicByHandle(handle);
+                    if (characteristic == null) {
+                        Log.w(TAG, "onCharacteristicWriteRequest() no char for handle " + handle);
+                        return;
+                    }
 
-                BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                BluetoothGattDescriptor descriptor = getDescriptorByHandle(handle);
-                if (descriptor == null) {
-                    Log.w(TAG, "onDescriptorWriteRequest() no desc for handle " + handle);
-                    return;
+                    try {
+                        mCallback.onCharacteristicWriteRequest(device, transId, characteristic,
+                                isPrep, needRsp, offset, value);
+                    } catch (Exception ex) {
+                        Log.w(TAG, "Unhandled exception in callback", ex);
+                    }
+
                 }
 
-                try {
-                    mCallback.onDescriptorWriteRequest(device, transId, descriptor,
-                                                       isPrep, needRsp, offset, value);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
+                /**
+                 * Remote client descriptor write request.
+                 * @hide
+                 */
+                @Override
+                public void onDescriptorWriteRequest(String address, int transId, int offset,
+                        int length, boolean isPrep, boolean needRsp, int handle, byte[] value) {
+                    if (VDBG) Log.d(TAG, "onDescriptorWriteRequest() - handle=" + handle);
+
+                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
+                    BluetoothGattDescriptor descriptor = getDescriptorByHandle(handle);
+                    if (descriptor == null) {
+                        Log.w(TAG, "onDescriptorWriteRequest() no desc for handle " + handle);
+                        return;
+                    }
+
+                    try {
+                        mCallback.onDescriptorWriteRequest(device, transId, descriptor,
+                                isPrep, needRsp, offset, value);
+                    } catch (Exception ex) {
+                        Log.w(TAG, "Unhandled exception in callback", ex);
+                    }
                 }
-            }
 
-            /**
-             * Execute pending writes.
-             * @hide
-             */
-            @Override
-            public void onExecuteWrite(String address, int transId,
-                                       boolean execWrite) {
-                if (DBG) Log.d(TAG, "onExecuteWrite() - "
-                    + "device=" + address + ", transId=" + transId
-                    + "execWrite=" + execWrite);
+                /**
+                 * Execute pending writes.
+                 * @hide
+                 */
+                @Override
+                public void onExecuteWrite(String address, int transId,
+                        boolean execWrite) {
+                    if (DBG) {
+                        Log.d(TAG, "onExecuteWrite() - "
+                                + "device=" + address + ", transId=" + transId
+                                + "execWrite=" + execWrite);
+                    }
 
-                BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                if (device == null) return;
+                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
+                    if (device == null) return;
 
-                try {
-                    mCallback.onExecuteWrite(device, transId, execWrite);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
+                    try {
+                        mCallback.onExecuteWrite(device, transId, execWrite);
+                    } catch (Exception ex) {
+                        Log.w(TAG, "Unhandled exception in callback", ex);
+                    }
                 }
-            }
 
-            /**
-             * A notification/indication has been sent.
-             * @hide
-             */
-            @Override
-            public void onNotificationSent(String address, int status) {
-                if (VDBG) Log.d(TAG, "onNotificationSent() - "
-                    + "device=" + address + ", status=" + status);
+                /**
+                 * A notification/indication has been sent.
+                 * @hide
+                 */
+                @Override
+                public void onNotificationSent(String address, int status) {
+                    if (VDBG) {
+                        Log.d(TAG, "onNotificationSent() - "
+                                + "device=" + address + ", status=" + status);
+                    }
 
-                BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                if (device == null) return;
+                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
+                    if (device == null) return;
 
-                try {
-                    mCallback.onNotificationSent(device, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    try {
+                        mCallback.onNotificationSent(device, status);
+                    } catch (Exception ex) {
+                        Log.w(TAG, "Unhandled exception: " + ex);
+                    }
                 }
-            }
 
-            /**
-             * The MTU for a connection has changed
-             * @hide
-             */
-            @Override
-            public void onMtuChanged(String address, int mtu) {
-                if (DBG) Log.d(TAG, "onMtuChanged() - "
-                    + "device=" + address + ", mtu=" + mtu);
+                /**
+                 * The MTU for a connection has changed
+                 * @hide
+                 */
+                @Override
+                public void onMtuChanged(String address, int mtu) {
+                    if (DBG) {
+                        Log.d(TAG, "onMtuChanged() - "
+                                + "device=" + address + ", mtu=" + mtu);
+                    }
 
-                BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                if (device == null) return;
+                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
+                    if (device == null) return;
 
-                try {
-                    mCallback.onMtuChanged(device, mtu);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    try {
+                        mCallback.onMtuChanged(device, mtu);
+                    } catch (Exception ex) {
+                        Log.w(TAG, "Unhandled exception: " + ex);
+                    }
                 }
-            }
 
-            /**
-             * The PHY for a connection was updated
-             * @hide
-             */
-            @Override
-            public void onPhyUpdate(String address, int txPhy, int rxPhy, int status) {
-                if (DBG) Log.d(TAG, "onPhyUpdate() - " + "device=" + address + ", txPHy=" + txPhy
-                    + ", rxPHy=" + rxPhy);
+                /**
+                 * The PHY for a connection was updated
+                 * @hide
+                 */
+                @Override
+                public void onPhyUpdate(String address, int txPhy, int rxPhy, int status) {
+                    if (DBG) {
+                        Log.d(TAG,
+                                "onPhyUpdate() - " + "device=" + address + ", txPHy=" + txPhy
+                                        + ", rxPHy=" + rxPhy);
+                    }
 
-                BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                if (device == null) return;
+                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
+                    if (device == null) return;
 
-                try {
-                    mCallback.onPhyUpdate(device, txPhy, rxPhy, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    try {
+                        mCallback.onPhyUpdate(device, txPhy, rxPhy, status);
+                    } catch (Exception ex) {
+                        Log.w(TAG, "Unhandled exception: " + ex);
+                    }
                 }
-            }
 
-            /**
-             * The PHY for a connection was read
-             * @hide
-             */
-            @Override
-            public void onPhyRead(String address, int txPhy, int rxPhy, int status) {
-                if (DBG) Log.d(TAG, "onPhyUpdate() - " + "device=" + address + ", txPHy=" + txPhy
-                    + ", rxPHy=" + rxPhy);
+                /**
+                 * The PHY for a connection was read
+                 * @hide
+                 */
+                @Override
+                public void onPhyRead(String address, int txPhy, int rxPhy, int status) {
+                    if (DBG) {
+                        Log.d(TAG,
+                                "onPhyUpdate() - " + "device=" + address + ", txPHy=" + txPhy
+                                        + ", rxPHy=" + rxPhy);
+                    }
 
-                BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                if (device == null) return;
+                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
+                    if (device == null) return;
 
-                try {
-                    mCallback.onPhyRead(device, txPhy, rxPhy, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    try {
+                        mCallback.onPhyRead(device, txPhy, rxPhy, status);
+                    } catch (Exception ex) {
+                        Log.w(TAG, "Unhandled exception: " + ex);
+                    }
                 }
-            }
 
-            /**
-             * Callback invoked when the given connection is updated
-             * @hide
-             */
-            @Override
-            public void onConnectionUpdated(String address, int interval, int latency,
-                                            int timeout, int status) {
-                if (DBG) Log.d(TAG, "onConnectionUpdated() - Device=" + address +
-                            " interval=" + interval + " latency=" + latency +
-                            " timeout=" + timeout + " status=" + status);
-                BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                if (device == null) return;
+                /**
+                 * Callback invoked when the given connection is updated
+                 * @hide
+                 */
+                @Override
+                public void onConnectionUpdated(String address, int interval, int latency,
+                        int timeout, int status) {
+                    if (DBG) {
+                        Log.d(TAG, "onConnectionUpdated() - Device=" + address
+                                + " interval=" + interval + " latency=" + latency
+                                + " timeout=" + timeout + " status=" + status);
+                    }
+                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
+                    if (device == null) return;
 
-                try {
-                    mCallback.onConnectionUpdated(device, interval, latency,
-                                                  timeout, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    try {
+                        mCallback.onConnectionUpdated(device, interval, latency,
+                                timeout, status);
+                    } catch (Exception ex) {
+                        Log.w(TAG, "Unhandled exception: " + ex);
+                    }
                 }
-            }
 
-        };
+            };
 
     /**
      * Create a BluetoothGattServer proxy object.
@@ -369,13 +387,15 @@
 
     /**
      * Returns a characteristic with given handle.
+     *
      * @hide
      */
     /*package*/ BluetoothGattCharacteristic getCharacteristicByHandle(int handle) {
-        for(BluetoothGattService svc : mServices) {
-            for(BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
-                if (charac.getInstanceId() == handle)
+        for (BluetoothGattService svc : mServices) {
+            for (BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
+                if (charac.getInstanceId() == handle) {
                     return charac;
+                }
             }
         }
         return null;
@@ -383,14 +403,16 @@
 
     /**
      * Returns a descriptor with given handle.
+     *
      * @hide
      */
     /*package*/ BluetoothGattDescriptor getDescriptorByHandle(int handle) {
-        for(BluetoothGattService svc : mServices) {
-            for(BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
-                for(BluetoothGattDescriptor desc : charac.getDescriptors()) {
-                    if (desc.getInstanceId() == handle)
+        for (BluetoothGattService svc : mServices) {
+            for (BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
+                for (BluetoothGattDescriptor desc : charac.getDescriptors()) {
+                    if (desc.getInstanceId() == handle) {
                         return desc;
+                    }
                 }
             }
         }
@@ -416,10 +438,9 @@
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
-     * @param callback GATT callback handler that will receive asynchronous
-     *                 callbacks.
-     * @return true, the callback will be called to notify success or failure,
-     *         false on immediate error
+     * @param callback GATT callback handler that will receive asynchronous callbacks.
+     * @return true, the callback will be called to notify success or failure, false on immediate
+     * error
      */
     /*package*/ boolean registerCallback(BluetoothGattServerCallback callback) {
         if (DBG) Log.d(TAG, "registerCallback()");
@@ -430,7 +451,7 @@
         UUID uuid = UUID.randomUUID();
         if (DBG) Log.d(TAG, "registerCallback() - UUID=" + uuid);
 
-        synchronized(mServerIfLock) {
+        synchronized (mServerIfLock) {
             if (mCallback != null) {
                 Log.e(TAG, "App can register callback only once");
                 return false;
@@ -440,7 +461,7 @@
             try {
                 mService.registerServer(new ParcelUuid(uuid), mBluetoothGattServerCallback);
             } catch (RemoteException e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
                 mCallback = null;
                 return false;
             }
@@ -473,19 +494,20 @@
             mService.unregisterServer(mServerIf);
             mServerIf = 0;
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
         }
     }
 
     /**
      * Returns a service by UUID, instance and type.
+     *
      * @hide
      */
     /*package*/ BluetoothGattService getService(UUID uuid, int instanceId, int type) {
-        for(BluetoothGattService svc : mServices) {
-            if (svc.getType() == type &&
-                svc.getInstanceId() == instanceId &&
-                svc.getUuid().equals(uuid)) {
+        for (BluetoothGattService svc : mServices) {
+            if (svc.getType() == type
+                    && svc.getInstanceId() == instanceId
+                    && svc.getUuid().equals(uuid)) {
                 return svc;
             }
         }
@@ -509,20 +531,22 @@
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
-     * @param autoConnect Whether to directly connect to the remote device (false)
-     *                    or to automatically connect as soon as the remote
-     *                    device becomes available (true).
+     * @param autoConnect Whether to directly connect to the remote device (false) or to
+     * automatically connect as soon as the remote device becomes available (true).
      * @return true, if the connection attempt was initiated successfully
      */
     public boolean connect(BluetoothDevice device, boolean autoConnect) {
-        if (DBG) Log.d(TAG, "connect() - device: " + device.getAddress() + ", auto: " + autoConnect);
+        if (DBG) {
+            Log.d(TAG,
+                    "connect() - device: " + device.getAddress() + ", auto: " + autoConnect);
+        }
         if (mService == null || mServerIf == 0) return false;
 
         try {
-            mService.serverConnect(mServerIf, device.getAddress(),
-                               autoConnect ? false : true,mTransport); // autoConnect is inverse of "isDirect"
+            // autoConnect is inverse of "isDirect"
+            mService.serverConnect(mServerIf, device.getAddress(), !autoConnect, mTransport);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return false;
         }
 
@@ -544,35 +568,34 @@
         try {
             mService.serverDisconnect(mServerIf, device.getAddress());
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
         }
     }
 
     /**
      * Set the preferred connection PHY for this app. Please note that this is just a
      * recommendation, whether the PHY change will happen depends on other applications peferences,
-     * local and remote controller capabilities. Controller can override these settings.
-     * <p>
-     * {@link BluetoothGattServerCallback#onPhyUpdate} will be triggered as a result of this call, even
-     * if no PHY change happens. It is also triggered when remote device updates the PHY.
+     * local and remote controller capabilities. Controller can override these settings. <p> {@link
+     * BluetoothGattServerCallback#onPhyUpdate} will be triggered as a result of this call, even if
+     * no PHY change happens. It is also triggered when remote device updates the PHY.
      *
      * @param device The remote device to send this response to
-     * @param txPhy preferred transmitter PHY. Bitwise OR of any of
-     *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
-     *             and {@link BluetoothDevice#PHY_LE_CODED_MASK}.
-     * @param rxPhy preferred receiver PHY. Bitwise OR of any of
-     *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
-     *             and {@link BluetoothDevice#PHY_LE_CODED_MASK}.
+     * @param txPhy preferred transmitter PHY. Bitwise OR of any of {@link
+     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link
+     * BluetoothDevice#PHY_LE_CODED_MASK}.
+     * @param rxPhy preferred receiver PHY. Bitwise OR of any of {@link
+     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link
+     * BluetoothDevice#PHY_LE_CODED_MASK}.
      * @param phyOptions preferred coding to use when transmitting on the LE Coded PHY. Can be one
-     *             of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED},
-     *             {@link BluetoothDevice#PHY_OPTION_S2} or {@link BluetoothDevice#PHY_OPTION_S8}
+     * of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED}, {@link BluetoothDevice#PHY_OPTION_S2} or
+     * {@link BluetoothDevice#PHY_OPTION_S8}
      */
     public void setPreferredPhy(BluetoothDevice device, int txPhy, int rxPhy, int phyOptions) {
         try {
             mService.serverSetPreferredPhy(mServerIf, device.getAddress(), txPhy, rxPhy,
-                                           phyOptions);
+                    phyOptions);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
         }
     }
 
@@ -586,7 +609,7 @@
         try {
             mService.serverReadPhy(mServerIf, device.getAddress());
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
         }
     }
 
@@ -597,10 +620,10 @@
      * is received by one of these callback methods:
      *
      * <ul>
-     *      <li>{@link BluetoothGattServerCallback#onCharacteristicReadRequest}
-     *      <li>{@link BluetoothGattServerCallback#onCharacteristicWriteRequest}
-     *      <li>{@link BluetoothGattServerCallback#onDescriptorReadRequest}
-     *      <li>{@link BluetoothGattServerCallback#onDescriptorWriteRequest}
+     * <li>{@link BluetoothGattServerCallback#onCharacteristicReadRequest}
+     * <li>{@link BluetoothGattServerCallback#onCharacteristicWriteRequest}
+     * <li>{@link BluetoothGattServerCallback#onDescriptorReadRequest}
+     * <li>{@link BluetoothGattServerCallback#onDescriptorWriteRequest}
      * </ul>
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
@@ -612,15 +635,15 @@
      * @param value The value of the attribute that was read/written (optional)
      */
     public boolean sendResponse(BluetoothDevice device, int requestId,
-                                int status, int offset, byte[] value) {
+            int status, int offset, byte[] value) {
         if (VDBG) Log.d(TAG, "sendResponse() - device: " + device.getAddress());
         if (mService == null || mServerIf == 0) return false;
 
         try {
             mService.sendResponse(mServerIf, device.getAddress(), requestId,
-                                  status, offset, value);
+                    status, offset, value);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return false;
         }
         return true;
@@ -639,13 +662,13 @@
      *
      * @param device The remote device to receive the notification/indication
      * @param characteristic The local characteristic that has been updated
-     * @param confirm true to request confirmation from the client (indication),
-     *                false to send a notification
-     * @throws IllegalArgumentException
+     * @param confirm true to request confirmation from the client (indication), false to send a
+     * notification
      * @return true, if the notification has been triggered successfully
+     * @throws IllegalArgumentException
      */
     public boolean notifyCharacteristicChanged(BluetoothDevice device,
-                    BluetoothGattCharacteristic characteristic, boolean confirm) {
+            BluetoothGattCharacteristic characteristic, boolean confirm) {
         if (VDBG) Log.d(TAG, "notifyCharacteristicChanged() - device: " + device.getAddress());
         if (mService == null || mServerIf == 0) return false;
 
@@ -662,7 +685,7 @@
                     characteristic.getInstanceId(), confirm,
                     characteristic.getValue());
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return false;
         }
 
@@ -680,8 +703,7 @@
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
-     * @param service Service to be added to the list of services provided
-     *                by this device.
+     * @param service Service to be added to the list of services provided by this device.
      * @return true, if the service has been added successfully
      */
     public boolean addService(BluetoothGattService service) {
@@ -693,7 +715,7 @@
         try {
             mService.addService(mServerIf, service);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return false;
         }
 
@@ -713,14 +735,14 @@
         if (mService == null || mServerIf == 0) return false;
 
         BluetoothGattService intService = getService(service.getUuid(),
-                                service.getInstanceId(), service.getType());
+                service.getInstanceId(), service.getType());
         if (intService == null) return false;
 
         try {
             mService.removeService(mServerIf, service.getInstanceId());
             mServices.remove(intService);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return false;
         }
 
@@ -739,7 +761,7 @@
             mService.clearServices(mServerIf);
             mServices.clear();
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
         }
     }
 
@@ -751,8 +773,7 @@
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
-     * @return List of services. Returns an empty list
-     *         if no services have been added yet.
+     * @return List of services. Returns an empty list if no services have been added yet.
      */
     public List<BluetoothGattService> getServices() {
         return mServices;
@@ -768,8 +789,8 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param uuid UUID of the requested service
-     * @return BluetoothGattService if supported, or null if the requested
-     *         service is not offered by this device.
+     * @return BluetoothGattService if supported, or null if the requested service is not offered by
+     * this device.
      */
     public BluetoothGattService getService(UUID uuid) {
         for (BluetoothGattService service : mServices) {
@@ -801,8 +822,8 @@
      */
     @Override
     public List<BluetoothDevice> getConnectedDevices() {
-        throw new UnsupportedOperationException
-            ("Use BluetoothManager#getConnectedDevices instead.");
+        throw new UnsupportedOperationException(
+                "Use BluetoothManager#getConnectedDevices instead.");
     }
 
     /**
@@ -814,7 +835,7 @@
      */
     @Override
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        throw new UnsupportedOperationException
-            ("Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
+        throw new UnsupportedOperationException(
+                "Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothGattServerCallback.java b/core/java/android/bluetooth/BluetoothGattServerCallback.java
index 02307bd..2c8114b 100644
--- a/core/java/android/bluetooth/BluetoothGattServerCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattServerCallback.java
@@ -16,8 +16,6 @@
 
 package android.bluetooth;
 
-import android.bluetooth.BluetoothDevice;
-
 /**
  * This abstract class is used to implement {@link BluetoothGattServer} callbacks.
  */
@@ -28,19 +26,18 @@
      *
      * @param device Remote device that has been connected or disconnected.
      * @param status Status of the connect or disconnect operation.
-     * @param newState Returns the new connection state. Can be one of
-     *                  {@link BluetoothProfile#STATE_DISCONNECTED} or
-     *                  {@link BluetoothProfile#STATE_CONNECTED}
+     * @param newState Returns the new connection state. Can be one of {@link
+     * BluetoothProfile#STATE_DISCONNECTED} or {@link BluetoothProfile#STATE_CONNECTED}
      */
     public void onConnectionStateChange(BluetoothDevice device, int status,
-                                        int newState) {
+            int newState) {
     }
 
     /**
      * Indicates whether a local service has been added successfully.
      *
-     * @param status Returns {@link BluetoothGatt#GATT_SUCCESS} if the service
-     *               was added successfully.
+     * @param status Returns {@link BluetoothGatt#GATT_SUCCESS} if the service was added
+     * successfully.
      * @param service The service that has been added
      */
     public void onServiceAdded(int status, BluetoothGattService service) {
@@ -58,7 +55,7 @@
      * @param characteristic Characteristic to be read
      */
     public void onCharacteristicReadRequest(BluetoothDevice device, int requestId,
-                        int offset, BluetoothGattCharacteristic characteristic) {
+            int offset, BluetoothGattCharacteristic characteristic) {
     }
 
     /**
@@ -70,16 +67,15 @@
      * @param device The remote device that has requested the write operation
      * @param requestId The Id of the request
      * @param characteristic Characteristic to be written to.
-     * @param preparedWrite true, if this write operation should be queued for
-     *                      later execution.
+     * @param preparedWrite true, if this write operation should be queued for later execution.
      * @param responseNeeded true, if the remote device requires a response
      * @param offset The offset given for the value
      * @param value The value the client wants to assign to the characteristic
      */
     public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,
-                                             BluetoothGattCharacteristic characteristic,
-                                             boolean preparedWrite, boolean responseNeeded,
-                                             int offset, byte[] value) {
+            BluetoothGattCharacteristic characteristic,
+            boolean preparedWrite, boolean responseNeeded,
+            int offset, byte[] value) {
     }
 
     /**
@@ -94,7 +90,7 @@
      * @param descriptor Descriptor to be read
      */
     public void onDescriptorReadRequest(BluetoothDevice device, int requestId,
-                                        int offset, BluetoothGattDescriptor descriptor) {
+            int offset, BluetoothGattDescriptor descriptor) {
     }
 
     /**
@@ -106,16 +102,15 @@
      * @param device The remote device that has requested the write operation
      * @param requestId The Id of the request
      * @param descriptor Descriptor to be written to.
-     * @param preparedWrite true, if this write operation should be queued for
-     *                      later execution.
+     * @param preparedWrite true, if this write operation should be queued for later execution.
      * @param responseNeeded true, if the remote device requires a response
      * @param offset The offset given for the value
      * @param value The value the client wants to assign to the descriptor
      */
     public void onDescriptorWriteRequest(BluetoothDevice device, int requestId,
-                                         BluetoothGattDescriptor descriptor,
-                                         boolean preparedWrite, boolean responseNeeded,
-                                         int offset,  byte[] value) {
+            BluetoothGattDescriptor descriptor,
+            boolean preparedWrite, boolean responseNeeded,
+            int offset, byte[] value) {
     }
 
     /**
@@ -126,8 +121,7 @@
      *
      * @param device The remote device that has requested the write operations
      * @param requestId The Id of the request
-     * @param execute Whether the pending writes should be executed (true) or
-     *                cancelled (false)
+     * @param execute Whether the pending writes should be executed (true) or cancelled (false)
      */
     public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
     }
@@ -163,12 +157,12 @@
      * of remote device changing the PHY.
      *
      * @param device The remote device
-     * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
-     *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
-     * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
-     *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
-     * @param status Status of the PHY update operation.
-     *                  {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
+     * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
+     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
+     * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
+     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
+     * @param status Status of the PHY update operation. {@link BluetoothGatt#GATT_SUCCESS} if the
+     * operation succeeds.
      */
     public void onPhyUpdate(BluetoothDevice device, int txPhy, int rxPhy, int status) {
     }
@@ -177,12 +171,12 @@
      * Callback triggered as result of {@link BluetoothGattServer#readPhy}
      *
      * @param device The remote device that requested the PHY read
-     * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
-     *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
-     * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
-     *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
-     * @param status Status of the PHY read operation.
-     *                  {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
+     * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
+     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
+     * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
+     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
+     * @param status Status of the PHY read operation. {@link BluetoothGatt#GATT_SUCCESS} if the
+     * operation succeeds.
      */
     public void onPhyRead(BluetoothDevice device, int txPhy, int rxPhy, int status) {
     }
@@ -191,18 +185,18 @@
      * Callback indicating the connection parameters were updated.
      *
      * @param device The remote device involved
-     * @param interval Connection interval used on this connection, 1.25ms unit. Valid
-     *            range is from 6 (7.5ms) to 3200 (4000ms).
-     * @param latency Slave latency for the connection in number of connection events. Valid
-     *            range is from 0 to 499
-     * @param timeout Supervision timeout for this connection, in 10ms unit. Valid range is
-     *            from 10 (0.1s) to 3200 (32s)
+     * @param interval Connection interval used on this connection, 1.25ms unit. Valid range is from
+     * 6 (7.5ms) to 3200 (4000ms).
+     * @param latency Slave latency for the connection in number of connection events. Valid range
+     * is from 0 to 499
+     * @param timeout Supervision timeout for this connection, in 10ms unit. Valid range is from 10
+     * (0.1s) to 3200 (32s)
      * @param status {@link BluetoothGatt#GATT_SUCCESS} if the connection has been updated
-     *                successfully
+     * successfully
      * @hide
      */
-    public void onConnectionUpdated(BluetoothDevice gatt, int interval, int latency, int timeout,
-                                    int status) {
+    public void onConnectionUpdated(BluetoothDevice device, int interval, int latency, int timeout,
+            int status) {
     }
 
 }
diff --git a/core/java/android/bluetooth/BluetoothGattService.java b/core/java/android/bluetooth/BluetoothGattService.java
index c888a45..ce1dc1c 100644
--- a/core/java/android/bluetooth/BluetoothGattService.java
+++ b/core/java/android/bluetooth/BluetoothGattService.java
@@ -16,8 +16,9 @@
 package android.bluetooth;
 
 import android.os.Parcel;
-import android.os.Parcelable;
 import android.os.ParcelUuid;
+import android.os.Parcelable;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
@@ -44,30 +45,35 @@
     /**
      * The remote device his service is associated with.
      * This applies to client applications only.
+     *
      * @hide
      */
     protected BluetoothDevice mDevice;
 
     /**
      * The UUID of this service.
+     *
      * @hide
      */
     protected UUID mUuid;
 
     /**
      * Instance ID for this service.
+     *
      * @hide
      */
     protected int mInstanceId;
 
     /**
      * Handle counter override (for conformance testing).
+     *
      * @hide
      */
     protected int mHandles = 0;
 
     /**
      * Service type (Primary/Secondary).
+     *
      * @hide
      */
     protected int mServiceType;
@@ -93,8 +99,8 @@
      *
      * @param uuid The UUID for this service
      * @param serviceType The type of this service,
-     *        {@link BluetoothGattService#SERVICE_TYPE_PRIMARY} or
-     *        {@link BluetoothGattService#SERVICE_TYPE_SECONDARY}
+     * {@link BluetoothGattService#SERVICE_TYPE_PRIMARY}
+     * or {@link BluetoothGattService#SERVICE_TYPE_SECONDARY}
      */
     public BluetoothGattService(UUID uuid, int serviceType) {
         mDevice = null;
@@ -107,10 +113,11 @@
 
     /**
      * Create a new BluetoothGattService
+     *
      * @hide
      */
     /*package*/ BluetoothGattService(BluetoothDevice device, UUID uuid,
-                                     int instanceId, int serviceType) {
+            int instanceId, int serviceType) {
         mDevice = device;
         mUuid = uuid;
         mInstanceId = instanceId;
@@ -121,6 +128,7 @@
 
     /**
      * Create a new BluetoothGattService
+     *
      * @hide
      */
     public BluetoothGattService(UUID uuid, int instanceId, int serviceType) {
@@ -148,15 +156,15 @@
 
         ArrayList<BluetoothGattIncludedService> includedServices =
                 new ArrayList<BluetoothGattIncludedService>(mIncludedServices.size());
-        for(BluetoothGattService s : mIncludedServices) {
+        for (BluetoothGattService s : mIncludedServices) {
             includedServices.add(new BluetoothGattIncludedService(s.getUuid(),
-                                                                  s.getInstanceId(), s.getType()));
+                    s.getInstanceId(), s.getType()));
         }
         out.writeTypedList(includedServices);
-     }
+    }
 
-    public static final Parcelable.Creator<BluetoothGattService> CREATOR
-            = new Parcelable.Creator<BluetoothGattService>() {
+    public static final Parcelable.Creator<BluetoothGattService> CREATOR =
+            new Parcelable.Creator<BluetoothGattService>() {
         public BluetoothGattService createFromParcel(Parcel in) {
             return new BluetoothGattService(in);
         }
@@ -167,7 +175,7 @@
     };
 
     private BluetoothGattService(Parcel in) {
-        mUuid = ((ParcelUuid)in.readParcelable(null)).getUuid();
+        mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
         mInstanceId = in.readInt();
         mServiceType = in.readInt();
 
@@ -189,13 +197,14 @@
         if (chrcs != null) {
             for (BluetoothGattIncludedService isvc : inclSvcs) {
                 mIncludedServices.add(new BluetoothGattService(null, isvc.getUuid(),
-                                                            isvc.getInstanceId(), isvc.getType()));
+                        isvc.getInstanceId(), isvc.getType()));
             }
         }
     }
 
     /**
      * Returns the device associated with this service.
+     *
      * @hide
      */
     /*package*/ BluetoothDevice getDevice() {
@@ -204,10 +213,11 @@
 
     /**
      * Returns the device associated with this service.
+     *
      * @hide
      */
     /*package*/ void setDevice(BluetoothDevice device) {
-        this.mDevice = device;
+        mDevice = device;
     }
 
     /**
@@ -237,19 +247,22 @@
 
     /**
      * Get characteristic by UUID and instanceId.
+     *
      * @hide
      */
     /*package*/ BluetoothGattCharacteristic getCharacteristic(UUID uuid, int instanceId) {
-        for(BluetoothGattCharacteristic characteristic : mCharacteristics) {
+        for (BluetoothGattCharacteristic characteristic : mCharacteristics) {
             if (uuid.equals(characteristic.getUuid())
-             && characteristic.getInstanceId() == instanceId)
+                    && characteristic.getInstanceId() == instanceId) {
                 return characteristic;
+            }
         }
         return null;
     }
 
     /**
      * Force the instance ID.
+     *
      * @hide
      */
     public void setInstanceId(int instanceId) {
@@ -258,6 +271,7 @@
 
     /**
      * Get the handle count override (conformance testing.
+     *
      * @hide
      */
     /*package*/ int getHandles() {
@@ -267,6 +281,7 @@
     /**
      * Force the number of handles to reserve for this service.
      * This is needed for conformance testing only.
+     *
      * @hide
      */
     public void setHandles(int handles) {
@@ -275,6 +290,7 @@
 
     /**
      * Add an included service to the internal map.
+     *
      * @hide
      */
     public void addIncludedService(BluetoothGattService includedService) {
@@ -313,8 +329,7 @@
     /**
      * Get the list of included GATT services for this service.
      *
-     * @return List of included services or empty list if no included services
-     *         were discovered.
+     * @return List of included services or empty list if no included services were discovered.
      */
     public List<BluetoothGattService> getIncludedServices() {
         return mIncludedServices;
@@ -341,30 +356,33 @@
      * UUID, the first instance of a characteristic with the given UUID
      * is returned.
      *
-     * @return GATT characteristic object or null if no characteristic with the
-     *         given UUID was found.
+     * @return GATT characteristic object or null if no characteristic with the given UUID was
+     * found.
      */
     public BluetoothGattCharacteristic getCharacteristic(UUID uuid) {
-        for(BluetoothGattCharacteristic characteristic : mCharacteristics) {
-            if (uuid.equals(characteristic.getUuid()))
+        for (BluetoothGattCharacteristic characteristic : mCharacteristics) {
+            if (uuid.equals(characteristic.getUuid())) {
                 return characteristic;
+            }
         }
         return null;
     }
 
     /**
      * Returns whether the uuid of the service should be advertised.
+     *
      * @hide
      */
     public boolean isAdvertisePreferred() {
-      return mAdvertisePreferred;
+        return mAdvertisePreferred;
     }
 
     /**
      * Set whether the service uuid should be advertised.
+     *
      * @hide
      */
     public void setAdvertisePreferred(boolean advertisePreferred) {
-      this.mAdvertisePreferred = advertisePreferred;
+        mAdvertisePreferred = advertisePreferred;
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index c84643f..85550c7 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -56,9 +56,9 @@
      *
      * <p>This intent will have 3 extras:
      * <ul>
-     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
      * </ul>
      * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
      * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
@@ -69,7 +69,7 @@
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_CONNECTION_STATE_CHANGED =
-        "android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED";
+            "android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED";
 
     /**
      * Intent used to broadcast the change in the Audio Connection state of the
@@ -77,9 +77,9 @@
      *
      * <p>This intent will have 3 extras:
      * <ul>
-     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
      * </ul>
      * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
      * {@link #STATE_AUDIO_CONNECTED}, {@link #STATE_AUDIO_DISCONNECTED},
@@ -89,7 +89,7 @@
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_AUDIO_STATE_CHANGED =
-        "android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED";
+            "android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED";
 
 
     /**
@@ -98,19 +98,19 @@
      *
      * <p>This intent will have 4 extras and 1 category.
      * <ul>
-     *  <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote Bluetooth Device
-     *       </li>
-     *  <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD} - The vendor
-     *       specific command </li>
-     *  <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE} - The AT
-     *       command type which can be one of  {@link #AT_CMD_TYPE_READ},
-     *       {@link #AT_CMD_TYPE_TEST}, or {@link #AT_CMD_TYPE_SET},
-     *       {@link #AT_CMD_TYPE_BASIC},{@link #AT_CMD_TYPE_ACTION}. </li>
-     *  <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS} - Command
-     *       arguments. </li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote Bluetooth Device
+     * </li>
+     * <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD} - The vendor
+     * specific command </li>
+     * <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE} - The AT
+     * command type which can be one of  {@link #AT_CMD_TYPE_READ},
+     * {@link #AT_CMD_TYPE_TEST}, or {@link #AT_CMD_TYPE_SET},
+     * {@link #AT_CMD_TYPE_BASIC},{@link #AT_CMD_TYPE_ACTION}. </li>
+     * <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS} - Command
+     * arguments. </li>
      * </ul>
      *
-     *<p> The category is the Company ID of the vendor defining the
+     * <p> The category is the Company ID of the vendor defining the
      * vendor-specific command. {@link BluetoothAssignedNumbers}
      *
      * For example, for Plantronics specific events
@@ -118,9 +118,9 @@
      *
      * <p> For example, an AT+XEVENT=foo,3 will get translated into
      * <ul>
-     *   <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD = +XEVENT </li>
-     *   <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE = AT_CMD_TYPE_SET </li>
-     *   <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS = foo, 3 </li>
+     * <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD = +XEVENT </li>
+     * <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE = AT_CMD_TYPE_SET </li>
+     * <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS = foo, 3 </li>
      * </ul>
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission
      * to receive.
@@ -191,7 +191,7 @@
      * The intent category to be used with {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
      * for the companyId
      */
-    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY  =
+    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY =
             "android.bluetooth.headset.intent.category.companyid";
 
     /**
@@ -201,12 +201,14 @@
 
     /**
      * A vendor-specific AT command
+     *
      * @hide
      */
     public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XAPL = "+XAPL";
 
     /**
      * A vendor-specific AT command
+     *
      * @hide
      */
     public static final String VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV = "+IPHONEACCEV";
@@ -214,18 +216,21 @@
     /**
      * Battery level indicator associated with
      * {@link #VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV}
+     *
      * @hide
      */
     public static final int VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL = 1;
 
     /**
      * A vendor-specific AT command
+     *
      * @hide
      */
     public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT = "+XEVENT";
 
     /**
      * Battery level indicator associated with {@link #VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT}
+     *
      * @hide
      */
     public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT_BATTERY_LEVEL = "BATTERY";
@@ -258,17 +263,18 @@
      *
      * <p>This intent will have 3 extras:
      * <ul>
-     *   <li> {@link #EXTRA_HF_INDICATORS_IND_ID} - The Assigned number of headset Indicator which
-     *              is supported by the headset ( as indicated by AT+BIND command in the SLC
-     *              sequence) or whose value is changed (indicated by AT+BIEV command) </li>
-     *   <li> {@link #EXTRA_HF_INDICATORS_IND_VALUE} - Updated value of headset indicator. </li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - Remote device. </li>
+     * <li> {@link #EXTRA_HF_INDICATORS_IND_ID} - The Assigned number of headset Indicator which
+     * is supported by the headset ( as indicated by AT+BIND command in the SLC
+     * sequence) or whose value is changed (indicated by AT+BIEV command) </li>
+     * <li> {@link #EXTRA_HF_INDICATORS_IND_VALUE} - Updated value of headset indicator. </li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - Remote device. </li>
      * </ul>
      * <p>{@link #EXTRA_HF_INDICATORS_IND_ID} is defined by Bluetooth SIG and each of the indicators
-     *     are given an assigned number. Below shows the assigned number of Indicator added so far
+     * are given an assigned number. Below shows the assigned number of Indicator added so far
      * - Enhanced Safety - 1, Valid Values: 0 - Disabled, 1 - Enabled
      * - Battery Level - 2, Valid Values: 0~100 - Remaining level of Battery
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to receive.
+     *
      * @hide
      */
     public static final String ACTION_HF_INDICATORS_VALUE_CHANGED =
@@ -278,6 +284,7 @@
      * A int extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED}
      * intents that contains the assigned number of the headset indicator as defined by
      * Bluetooth SIG that is being sent. Value range is 0-65535 as defined in HFP 1.7
+     *
      * @hide
      */
     public static final String EXTRA_HF_INDICATORS_IND_ID =
@@ -286,6 +293,7 @@
     /**
      * A int extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED}
      * intents that contains the value of the Headset indicator that is being sent.
+     *
      * @hide
      */
     public static final String EXTRA_HF_INDICATORS_IND_VALUE =
@@ -298,30 +306,30 @@
 
     private Context mContext;
     private ServiceListener mServiceListener;
-    private IBluetoothHeadset mService;
+    private volatile IBluetoothHeadset mService;
     private BluetoothAdapter mAdapter;
 
-    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
             new IBluetoothStateChangeCallback.Stub() {
                 public void onBluetoothStateChange(boolean up) {
                     if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
                     if (!up) {
-                        if (VDBG) Log.d(TAG,"Unbinding service...");
+                        if (VDBG) Log.d(TAG, "Unbinding service...");
                         doUnbind();
                     } else {
                         synchronized (mConnection) {
                             try {
                                 if (mService == null) {
-                                    if (VDBG) Log.d(TAG,"Binding service...");
+                                    if (VDBG) Log.d(TAG, "Binding service...");
                                     doBind();
                                 }
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     }
                 }
-        };
+            };
 
     /**
      * Create a BluetoothHeadset proxy object.
@@ -336,7 +344,7 @@
             try {
                 mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (RemoteException e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -360,7 +368,7 @@
                     mAdapter.getBluetoothManager().unbindBluetoothProfileService(
                             BluetoothProfile.HEADSET, mConnection);
                 } catch (RemoteException e) {
-                    Log.e(TAG,"Unable to unbind HeadsetService", e);
+                    Log.e(TAG, "Unable to unbind HeadsetService", e);
                 }
             }
         }
@@ -380,7 +388,7 @@
             try {
                 mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (Exception e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
         mServiceListener = null;
@@ -405,22 +413,21 @@
      * permission.
      *
      * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
+     * @return false on immediate error, true otherwise
      * @hide
      */
     public boolean connect(BluetoothDevice device) {
         if (DBG) log("connect(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.connect(device);
+                return service.connect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -446,74 +453,78 @@
      * permission.
      *
      * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
+     * @return false on immediate error, true otherwise
      * @hide
      */
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) log("disconnect(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.disconnect(device);
+                return service.disconnect(device);
             } catch (RemoteException e) {
-              Log.e(TAG, Log.getStackTraceString(new Throwable()));
-              return false;
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public List<BluetoothDevice> getConnectedDevices() {
         if (VDBG) log("getConnectedDevices()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getConnectedDevices();
+                return service.getConnectedDevices();
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         if (VDBG) log("getDevicesMatchingStates()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getDevicesMatchingConnectionStates(states);
+                return service.getDevicesMatchingConnectionStates(states);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public int getConnectionState(BluetoothDevice device) {
         if (VDBG) log("getConnectionState(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getConnectionState(device);
+                return service.getConnectionState(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.STATE_DISCONNECTED;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return BluetoothProfile.STATE_DISCONNECTED;
     }
 
@@ -521,7 +532,7 @@
      * Set priority of the profile
      *
      * <p> The device should already be paired.
-     *  Priority can be one of {@link #PRIORITY_ON} or
+     * Priority can be one of {@link #PRIORITY_ON} or
      * {@link #PRIORITY_OFF},
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
@@ -534,20 +545,20 @@
      */
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
-            if (priority != BluetoothProfile.PRIORITY_OFF &&
-                priority != BluetoothProfile.PRIORITY_ON) {
-              return false;
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            if (priority != BluetoothProfile.PRIORITY_OFF
+                    && priority != BluetoothProfile.PRIORITY_ON) {
+                return false;
             }
             try {
-                return mService.setPriority(device, priority);
+                return service.setPriority(device, priority);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -566,16 +577,16 @@
      */
     public int getPriority(BluetoothDevice device) {
         if (VDBG) log("getPriority(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getPriority(device);
+                return service.getPriority(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return PRIORITY_OFF;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return PRIORITY_OFF;
     }
 
@@ -596,21 +607,20 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param device Bluetooth headset
-     * @return false if there is no headset connected of if the
-     *               connected headset doesn't support voice recognition
-     *               or on error, true otherwise
+     * @return false if there is no headset connected of if the connected headset doesn't support
+     * voice recognition or on error, true otherwise
      */
     public boolean startVoiceRecognition(BluetoothDevice device) {
         if (DBG) log("startVoiceRecognition()");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.startVoiceRecognition(device);
+                return service.startVoiceRecognition(device);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -621,20 +631,19 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param device Bluetooth headset
-     * @return false if there is no headset connected
-     *               or on error, true otherwise
+     * @return false if there is no headset connected or on error, true otherwise
      */
     public boolean stopVoiceRecognition(BluetoothDevice device) {
         if (DBG) log("stopVoiceRecognition()");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.stopVoiceRecognition(device);
+                return service.stopVoiceRecognition(device);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -644,20 +653,19 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param device Bluetooth headset
-     * @return true if SCO is connected,
-     *         false otherwise or on error
+     * @return true if SCO is connected, false otherwise or on error
      */
     public boolean isAudioConnected(BluetoothDevice device) {
         if (VDBG) log("isAudioConnected()");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-              return mService.isAudioConnected(device);
+                return service.isAudioConnected(device);
             } catch (RemoteException e) {
-              Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -671,21 +679,20 @@
      * rule of thumb, each AT command prevents the CPU from sleeping for 500 ms
      *
      * @param device the bluetooth headset.
-     * @return monotonically increasing battery usage hint, or a negative error
-     *         code on error
+     * @return monotonically increasing battery usage hint, or a negative error code on error
      * @hide
      */
     public int getBatteryUsageHint(BluetoothDevice device) {
         if (VDBG) log("getBatteryUsageHint()");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getBatteryUsageHint(device);
+                return service.getBatteryUsageHint(device);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return -1;
     }
 
@@ -708,10 +715,13 @@
      */
     public boolean acceptIncomingConnect(BluetoothDevice device) {
         if (DBG) log("acceptIncomingConnect");
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.acceptIncomingConnect(device);
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.acceptIncomingConnect(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -721,14 +731,18 @@
 
     /**
      * Reject the incoming connection.
+     *
      * @hide
      */
     public boolean rejectIncomingConnect(BluetoothDevice device) {
         if (DBG) log("rejectIncomingConnect");
-        if (mService != null) {
+        final IBluetoothHeadset service = mService;
+        if (service != null) {
             try {
-                return mService.rejectIncomingConnect(device);
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.rejectIncomingConnect(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -744,10 +758,13 @@
      */
     public int getAudioState(BluetoothDevice device) {
         if (VDBG) log("getAudioState");
-        if (mService != null && !isDisabled()) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && !isDisabled()) {
             try {
-                return mService.getAudioState(device);
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.getAudioState(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -763,15 +780,17 @@
      * Note: This is an internal function and shouldn't be exposed
      *
      * @param allowed {@code true} if the profile can reroute audio, {@code false} otherwise.
-     *
      * @hide
      */
     public void setAudioRouteAllowed(boolean allowed) {
         if (VDBG) log("setAudioRouteAllowed");
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled()) {
             try {
-                mService.setAudioRouteAllowed(allowed);
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                service.setAudioRouteAllowed(allowed);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -786,10 +805,13 @@
      */
     public boolean getAudioRouteAllowed() {
         if (VDBG) log("getAudioRouteAllowed");
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getAudioRouteAllowed();
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.getAudioRouteAllowed();
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -800,18 +822,18 @@
     /**
      * Force SCO audio to be opened regardless any other restrictions
      *
-     * @param forced Whether or not SCO audio connection should be forced:
-     *                 True to force SCO audio
-     *                 False to use SCO audio in normal manner
+     * @param forced Whether or not SCO audio connection should be forced: True to force SCO audio
+     * False to use SCO audio in normal manner
      * @hide
      */
     public void setForceScoAudio(boolean forced) {
         if (VDBG) log("setForceScoAudio " + String.valueOf(forced));
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled()) {
             try {
-                mService.setForceScoAudio(forced);
+                service.setForceScoAudio(forced);
             } catch (RemoteException e) {
-              Log.e(TAG, e.toString());
+                Log.e(TAG, e.toString());
             }
         } else {
             Log.w(TAG, "Proxy not attached to service");
@@ -824,20 +846,20 @@
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
-     * @return true if SCO is connected,
-     *         false otherwise or on error
+     * @return true if SCO is connected, false otherwise or on error
      * @hide
      */
     public boolean isAudioOn() {
         if (VDBG) log("isAudioOn()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled()) {
             try {
-              return mService.isAudioOn();
+                return service.isAudioOn();
             } catch (RemoteException e) {
-              Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
 
     }
@@ -846,15 +868,15 @@
      * Initiates a connection of headset audio.
      * It setup SCO channel with remote connected headset device.
      *
-     * @return true if successful
-     *         false if there was some error such as
-     *               there is no connected headset
+     * @return true if successful false if there was some error such as there is no connected
+     * headset
      * @hide
      */
     public boolean connectAudio() {
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.connectAudio();
+                return service.connectAudio();
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -869,15 +891,15 @@
      * Initiates a disconnection of headset audio.
      * It tears down the SCO channel from remote headset device.
      *
-     * @return true if successful
-     *         false if there was some error such as
-     *               there is no connected SCO channel
+     * @return true if successful false if there was some error such as there is no connected SCO
+     * channel
      * @hide
      */
     public boolean disconnectAudio() {
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.disconnectAudio();
+                return service.disconnectAudio();
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -901,9 +923,10 @@
      */
     public boolean startScoUsingVirtualVoiceCall(BluetoothDevice device) {
         if (DBG) log("startScoUsingVirtualVoiceCall()");
-        if (mService != null && isEnabled() && isValidDevice(device)) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.startScoUsingVirtualVoiceCall(device);
+                return service.startScoUsingVirtualVoiceCall(device);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -924,9 +947,10 @@
      */
     public boolean stopScoUsingVirtualVoiceCall(BluetoothDevice device) {
         if (DBG) log("stopScoUsingVirtualVoiceCall()");
-        if (mService != null && isEnabled() && isValidDevice(device)) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.stopScoUsingVirtualVoiceCall(device);
+                return service.stopScoUsingVirtualVoiceCall(device);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -946,10 +970,11 @@
      * @hide
      */
     public void phoneStateChanged(int numActive, int numHeld, int callState, String number,
-                                  int type) {
-        if (mService != null && isEnabled()) {
+            int type) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled()) {
             try {
-                mService.phoneStateChanged(numActive, numHeld, callState, number, type);
+                service.phoneStateChanged(numActive, numHeld, callState, number, type);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -965,10 +990,11 @@
      * @hide
      */
     public void clccResponse(int index, int direction, int status, int mode, boolean mpty,
-                             String number, int type) {
-        if (mService != null && isEnabled()) {
+            String number, int type) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled()) {
             try {
-                mService.clccResponse(index, direction, status, mode, mpty, number, type);
+                service.clccResponse(index, direction, status, mode, mpty, number, type);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -981,9 +1007,9 @@
     /**
      * Sends a vendor-specific unsolicited result code to the headset.
      *
-     * <p>The actual string to be sent is <code>command + ": " + arg</code>.
-     * For example, if {@code command} is {@link #VENDOR_RESULT_CODE_COMMAND_ANDROID} and {@code arg}
-     * is {@code "0"}, the string <code>"+ANDROID: 0"</code> will be sent.
+     * <p>The actual string to be sent is <code>command + ": " + arg</code>. For example, if {@code
+     * command} is {@link #VENDOR_RESULT_CODE_COMMAND_ANDROID} and {@code arg} is {@code "0"}, the
+     * string <code>"+ANDROID: 0"</code> will be sent.
      *
      * <p>Currently only {@link #VENDOR_RESULT_CODE_COMMAND_ANDROID} is allowed as {@code command}.
      *
@@ -993,7 +1019,7 @@
      * @param command A vendor-specific command.
      * @param arg The argument that will be attached to the command.
      * @return {@code false} if there is no headset connected, or if the command is not an allowed
-     *         vendor-specific unsolicited result code, or on error. {@code true} otherwise.
+     * vendor-specific unsolicited result code, or on error. {@code true} otherwise.
      * @throws IllegalArgumentException if {@code command} is {@code null}.
      */
     public boolean sendVendorSpecificResultCode(BluetoothDevice device, String command,
@@ -1004,15 +1030,15 @@
         if (command == null) {
             throw new IllegalArgumentException("command is null");
         }
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.sendVendorSpecificResultCode(device, command, arg);
+                return service.sendVendorSpecificResultCode(device, command, arg);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) {
+        if (service == null) {
             Log.w(TAG, "Proxy not attached to service");
         }
         return false;
@@ -1021,15 +1047,15 @@
     /**
      * enable WBS codec setting.
      *
-     * @return true if successful
-     *         false if there was some error such as
-     *               there is no connected headset
+     * @return true if successful false if there was some error such as there is no connected
+     * headset
      * @hide
      */
     public boolean enableWBS() {
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.enableWBS();
+                return service.enableWBS();
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -1043,15 +1069,15 @@
     /**
      * disable WBS codec settting. It set NBS codec.
      *
-     * @return true if successful
-     *         false if there was some error such as
-     *               there is no connected headset
+     * @return true if successful false if there was some error such as there is no connected
+     * headset
      * @hide
      */
     public boolean disableWBS() {
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.disableWBS();
+                return service.disableWBS();
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -1065,8 +1091,7 @@
     /**
      * check if in-band ringing is supported for this platform.
      *
-     * @return true if in-band ringing is supported
-     *         false if in-band ringing is not supported
+     * @return true if in-band ringing is supported false if in-band ringing is not supported
      * @hide
      */
     public static boolean isInbandRingingSupported(Context context) {
@@ -1078,16 +1103,17 @@
      * Send Headset the BIND response from AG to report change in the status of the
      * HF indicators to the headset
      *
-     * @param ind_id Assigned Number of the indicator (defined by SIG)
-     * @param ind_status
-     * possible values- false-Indicator is disabled, no value changes shall be sent for this indicator
-     *                  true-Indicator is enabled, value changes may be sent for this indicator
+     * @param indId Assigned Number of the indicator (defined by SIG)
+     * @param indStatus possible values- false-Indicator is disabled, no value changes shall be
+     * sent for this indicator true-Indicator is enabled, value changes may be sent for this
+     * indicator
      * @hide
      */
-    public void bindResponse(int ind_id, boolean ind_status) {
-        if (mService != null && isEnabled()) {
+    public void bindResponse(int indId, boolean indStatus) {
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled()) {
             try {
-                mService.bindResponse(ind_id, ind_status);
+                service.bindResponse(indId, indStatus);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -1097,8 +1123,8 @@
         }
     }
 
-    private final IBluetoothProfileServiceConnection mConnection
-            = new IBluetoothProfileServiceConnection.Stub()  {
+    private final IBluetoothProfileServiceConnection mConnection =
+            new IBluetoothProfileServiceConnection.Stub() {
         @Override
         public void onServiceConnected(ComponentName className, IBinder service) {
             if (DBG) Log.d(TAG, "Proxy object connected");
@@ -1106,6 +1132,7 @@
             mHandler.sendMessage(mHandler.obtainMessage(
                     MESSAGE_HEADSET_SERVICE_CONNECTED));
         }
+
         @Override
         public void onServiceDisconnected(ComponentName className) {
             if (DBG) Log.d(TAG, "Proxy object disconnected");
@@ -1116,20 +1143,15 @@
     };
 
     private boolean isEnabled() {
-       if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
-       return false;
+        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
     }
 
     private boolean isDisabled() {
-       if (mAdapter.getState() == BluetoothAdapter.STATE_OFF) return true;
-       return false;
+        return mAdapter.getState() == BluetoothAdapter.STATE_OFF;
     }
 
-    private boolean isValidDevice(BluetoothDevice device) {
-       if (device == null) return false;
-
-       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-       return false;
+    private static boolean isValidDevice(BluetoothDevice device) {
+        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
     }
 
     private static void log(String msg) {
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index 544b3b95..031287f 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -28,7 +28,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.UUID;
 
 /**
  * Public API to control Hands Free Profile (HFP role only).
@@ -38,7 +37,7 @@
  * <p>
  *
  * @hide
- * */
+ */
 public final class BluetoothHeadsetClient implements BluetoothProfile {
     private static final String TAG = "BluetoothHeadsetClient";
     private static final boolean DBG = true;
@@ -71,14 +70,14 @@
      * and not supported ones are <strong>not</strong> being sent at all.</p>
      */
     public static final String ACTION_CONNECTION_STATE_CHANGED =
-        "android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED";
+            "android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED";
 
     /**
      * Intent sent whenever audio state changes.
      *
      * <p>It includes two mandatory extras:
-     * {@link BluetoothProfile.EXTRA_STATE},
-     * {@link BluetoothProfile.EXTRA_PREVIOUS_STATE},
+     * {@link BluetoothProfile#EXTRA_STATE},
+     * {@link BluetoothProfile#EXTRA_PREVIOUS_STATE},
      * with possible values:
      * {@link #STATE_AUDIO_CONNECTING},
      * {@link #STATE_AUDIO_CONNECTED},
@@ -89,7 +88,7 @@
      * indicating wide band speech support.</p>
      */
     public static final String ACTION_AUDIO_STATE_CHANGED =
-        "android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED";
+            "android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED";
 
     /**
      * Intent sending updates of the Audio Gateway state.
@@ -146,7 +145,7 @@
     /**
      * Extra with information if connected audio is WBS.
      * <p>Possible values: <code>true</code>,
-     *                     <code>false</code>.</p>
+     * <code>false</code>.</p>
      */
     public static final String EXTRA_AUDIO_WBS =
             "android.bluetooth.headsetclient.extra.AUDIO_WBS";
@@ -154,7 +153,7 @@
     /**
      * Extra for AG_EVENT indicates network status.
      * <p>Value: 0 - network unavailable,
-     *           1 - network available </p>
+     * 1 - network available </p>
      */
     public static final String EXTRA_NETWORK_STATUS =
             "android.bluetooth.headsetclient.extra.NETWORK_STATUS";
@@ -167,7 +166,7 @@
     /**
      * Extra for AG_EVENT intent indicates roaming state.
      * <p>Value: 0 - no roaming
-     *           1 - active roaming</p>
+     * 1 - active roaming</p>
      */
     public static final String EXTRA_NETWORK_ROAMING =
             "android.bluetooth.headsetclient.extra.NETWORK_ROAMING";
@@ -186,16 +185,16 @@
     /**
      * Extra for AG_EVENT intent indicates voice recognition state.
      * <p>Value:
-     *          0 - voice recognition stopped,
-     *          1 - voice recognition started.</p>
+     * 0 - voice recognition stopped,
+     * 1 - voice recognition started.</p>
      */
     public static final String EXTRA_VOICE_RECOGNITION =
             "android.bluetooth.headsetclient.extra.VOICE_RECOGNITION";
     /**
      * Extra for AG_EVENT intent indicates in band ring state.
      * <p>Value:
-     *          0 - in band ring tone not supported, or
-     *          1 - in band ring tone supported.</p>
+     * 0 - in band ring tone not supported, or
+     * 1 - in band ring tone supported.</p>
      */
     public static final String EXTRA_IN_BAND_RING =
             "android.bluetooth.headsetclient.extra.IN_BAND_RING";
@@ -208,8 +207,8 @@
             "android.bluetooth.headsetclient.extra.SUBSCRIBER_INFO";
 
     /**
-     *  Extra for AG_CALL_CHANGED intent indicates the
-     *  {@link BluetoothHeadsetClientCall} object that has changed.
+     * Extra for AG_CALL_CHANGED intent indicates the
+     * {@link BluetoothHeadsetClientCall} object that has changed.
      */
     public static final String EXTRA_CALL =
             "android.bluetooth.headsetclient.extra.CALL";
@@ -251,53 +250,53 @@
     /**
      * AG feature: three way calling.
      */
-    public final static String EXTRA_AG_FEATURE_3WAY_CALLING =
+    public static final String EXTRA_AG_FEATURE_3WAY_CALLING =
             "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_3WAY_CALLING";
     /**
      * AG feature: voice recognition.
      */
-    public final static String EXTRA_AG_FEATURE_VOICE_RECOGNITION =
+    public static final String EXTRA_AG_FEATURE_VOICE_RECOGNITION =
             "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_VOICE_RECOGNITION";
     /**
      * AG feature: fetching phone number for voice tagging procedure.
      */
-    public final static String EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT =
+    public static final String EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT =
             "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT";
     /**
      * AG feature: ability to reject incoming call.
      */
-    public final static String EXTRA_AG_FEATURE_REJECT_CALL =
+    public static final String EXTRA_AG_FEATURE_REJECT_CALL =
             "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_REJECT_CALL";
     /**
      * AG feature: enhanced call handling (terminate specific call, private consultation).
      */
-    public final static String EXTRA_AG_FEATURE_ECC =
+    public static final String EXTRA_AG_FEATURE_ECC =
             "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_ECC";
     /**
      * AG feature: response and hold.
      */
-    public final static String EXTRA_AG_FEATURE_RESPONSE_AND_HOLD =
+    public static final String EXTRA_AG_FEATURE_RESPONSE_AND_HOLD =
             "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_RESPONSE_AND_HOLD";
     /**
      * AG call handling feature: accept held or waiting call in three way calling scenarios.
      */
-    public final static String EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL =
+    public static final String EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL =
             "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL";
     /**
      * AG call handling feature: release held or waiting call in three way calling scenarios.
      */
-    public final static String EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL =
+    public static final String EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL =
             "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL";
     /**
      * AG call handling feature: release active call and accept held or waiting call in three way
      * calling scenarios.
      */
-    public final static String EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT =
+    public static final String EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT =
             "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT";
     /**
      * AG call handling feature: merge two calls, held and active - multi party conference mode.
      */
-    public final static String EXTRA_AG_FEATURE_MERGE =
+    public static final String EXTRA_AG_FEATURE_MERGE =
             "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_MERGE";
     /**
      * AG call handling feature: merge calls and disconnect from multi party
@@ -305,61 +304,61 @@
      * Note that this feature needs to be supported by mobile network operator
      * as it requires connection and billing transfer.
      */
-    public final static String EXTRA_AG_FEATURE_MERGE_AND_DETACH =
+    public static final String EXTRA_AG_FEATURE_MERGE_AND_DETACH =
             "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_MERGE_AND_DETACH";
 
     /* Action result codes */
-    public final static int ACTION_RESULT_OK = 0;
-    public final static int ACTION_RESULT_ERROR = 1;
-    public final static int ACTION_RESULT_ERROR_NO_CARRIER = 2;
-    public final static int ACTION_RESULT_ERROR_BUSY = 3;
-    public final static int ACTION_RESULT_ERROR_NO_ANSWER = 4;
-    public final static int ACTION_RESULT_ERROR_DELAYED = 5;
-    public final static int ACTION_RESULT_ERROR_BLACKLISTED = 6;
-    public final static int ACTION_RESULT_ERROR_CME = 7;
+    public static final int ACTION_RESULT_OK = 0;
+    public static final int ACTION_RESULT_ERROR = 1;
+    public static final int ACTION_RESULT_ERROR_NO_CARRIER = 2;
+    public static final int ACTION_RESULT_ERROR_BUSY = 3;
+    public static final int ACTION_RESULT_ERROR_NO_ANSWER = 4;
+    public static final int ACTION_RESULT_ERROR_DELAYED = 5;
+    public static final int ACTION_RESULT_ERROR_BLACKLISTED = 6;
+    public static final int ACTION_RESULT_ERROR_CME = 7;
 
     /* Detailed CME error codes */
-    public final static int CME_PHONE_FAILURE                           = 0;
-    public final static int CME_NO_CONNECTION_TO_PHONE                  = 1;
-    public final static int CME_OPERATION_NOT_ALLOWED                   = 3;
-    public final static int CME_OPERATION_NOT_SUPPORTED                 = 4;
-    public final static int CME_PHSIM_PIN_REQUIRED                      = 5;
-    public final static int CME_PHFSIM_PIN_REQUIRED                     = 6;
-    public final static int CME_PHFSIM_PUK_REQUIRED                     = 7;
-    public final static int CME_SIM_NOT_INSERTED                        = 10;
-    public final static int CME_SIM_PIN_REQUIRED                        = 11;
-    public final static int CME_SIM_PUK_REQUIRED                        = 12;
-    public final static int CME_SIM_FAILURE                             = 13;
-    public final static int CME_SIM_BUSY                                = 14;
-    public final static int CME_SIM_WRONG                               = 15;
-    public final static int CME_INCORRECT_PASSWORD                      = 16;
-    public final static int CME_SIM_PIN2_REQUIRED                       = 17;
-    public final static int CME_SIM_PUK2_REQUIRED                       = 18;
-    public final static int CME_MEMORY_FULL                             = 20;
-    public final static int CME_INVALID_INDEX                           = 21;
-    public final static int CME_NOT_FOUND                               = 22;
-    public final static int CME_MEMORY_FAILURE                          = 23;
-    public final static int CME_TEXT_STRING_TOO_LONG                    = 24;
-    public final static int CME_INVALID_CHARACTER_IN_TEXT_STRING        = 25;
-    public final static int CME_DIAL_STRING_TOO_LONG                    = 26;
-    public final static int CME_INVALID_CHARACTER_IN_DIAL_STRING        = 27;
-    public final static int CME_NO_NETWORK_SERVICE                      = 30;
-    public final static int CME_NETWORK_TIMEOUT                         = 31;
-    public final static int CME_EMERGENCY_SERVICE_ONLY                  = 32;
-    public final static int CME_NO_SIMULTANOUS_VOIP_CS_CALLS            = 33;
-    public final static int CME_NOT_SUPPORTED_FOR_VOIP                  = 34;
-    public final static int CME_SIP_RESPONSE_CODE                       = 35;
-    public final static int CME_NETWORK_PERSONALIZATION_PIN_REQUIRED    = 40;
-    public final static int CME_NETWORK_PERSONALIZATION_PUK_REQUIRED    = 41;
-    public final static int CME_NETWORK_SUBSET_PERSONALIZATION_PIN_REQUIRED   = 42;
-    public final static int CME_NETWORK_SUBSET_PERSONALIZATION_PUK_REQUIRED   = 43;
-    public final static int CME_SERVICE_PROVIDER_PERSONALIZATION_PIN_REQUIRED = 44;
-    public final static int CME_SERVICE_PROVIDER_PERSONALIZATION_PUK_REQUIRED = 45;
-    public final static int CME_CORPORATE_PERSONALIZATION_PIN_REQUIRED  = 46;
-    public final static int CME_CORPORATE_PERSONALIZATION_PUK_REQUIRED  = 47;
-    public final static int CME_HIDDEN_KEY_REQUIRED                     = 48;
-    public final static int CME_EAP_NOT_SUPPORTED                       = 49;
-    public final static int CME_INCORRECT_PARAMETERS                    = 50;
+    public static final int CME_PHONE_FAILURE = 0;
+    public static final int CME_NO_CONNECTION_TO_PHONE = 1;
+    public static final int CME_OPERATION_NOT_ALLOWED = 3;
+    public static final int CME_OPERATION_NOT_SUPPORTED = 4;
+    public static final int CME_PHSIM_PIN_REQUIRED = 5;
+    public static final int CME_PHFSIM_PIN_REQUIRED = 6;
+    public static final int CME_PHFSIM_PUK_REQUIRED = 7;
+    public static final int CME_SIM_NOT_INSERTED = 10;
+    public static final int CME_SIM_PIN_REQUIRED = 11;
+    public static final int CME_SIM_PUK_REQUIRED = 12;
+    public static final int CME_SIM_FAILURE = 13;
+    public static final int CME_SIM_BUSY = 14;
+    public static final int CME_SIM_WRONG = 15;
+    public static final int CME_INCORRECT_PASSWORD = 16;
+    public static final int CME_SIM_PIN2_REQUIRED = 17;
+    public static final int CME_SIM_PUK2_REQUIRED = 18;
+    public static final int CME_MEMORY_FULL = 20;
+    public static final int CME_INVALID_INDEX = 21;
+    public static final int CME_NOT_FOUND = 22;
+    public static final int CME_MEMORY_FAILURE = 23;
+    public static final int CME_TEXT_STRING_TOO_LONG = 24;
+    public static final int CME_INVALID_CHARACTER_IN_TEXT_STRING = 25;
+    public static final int CME_DIAL_STRING_TOO_LONG = 26;
+    public static final int CME_INVALID_CHARACTER_IN_DIAL_STRING = 27;
+    public static final int CME_NO_NETWORK_SERVICE = 30;
+    public static final int CME_NETWORK_TIMEOUT = 31;
+    public static final int CME_EMERGENCY_SERVICE_ONLY = 32;
+    public static final int CME_NO_SIMULTANOUS_VOIP_CS_CALLS = 33;
+    public static final int CME_NOT_SUPPORTED_FOR_VOIP = 34;
+    public static final int CME_SIP_RESPONSE_CODE = 35;
+    public static final int CME_NETWORK_PERSONALIZATION_PIN_REQUIRED = 40;
+    public static final int CME_NETWORK_PERSONALIZATION_PUK_REQUIRED = 41;
+    public static final int CME_NETWORK_SUBSET_PERSONALIZATION_PIN_REQUIRED = 42;
+    public static final int CME_NETWORK_SUBSET_PERSONALIZATION_PUK_REQUIRED = 43;
+    public static final int CME_SERVICE_PROVIDER_PERSONALIZATION_PIN_REQUIRED = 44;
+    public static final int CME_SERVICE_PROVIDER_PERSONALIZATION_PUK_REQUIRED = 45;
+    public static final int CME_CORPORATE_PERSONALIZATION_PIN_REQUIRED = 46;
+    public static final int CME_CORPORATE_PERSONALIZATION_PUK_REQUIRED = 47;
+    public static final int CME_HIDDEN_KEY_REQUIRED = 48;
+    public static final int CME_EAP_NOT_SUPPORTED = 49;
+    public static final int CME_INCORRECT_PARAMETERS = 50;
 
     /* Action policy for other calls when accepting call */
     public static final int CALL_ACCEPT_NONE = 0;
@@ -368,39 +367,40 @@
 
     private Context mContext;
     private ServiceListener mServiceListener;
-    private IBluetoothHeadsetClient mService;
+    private volatile IBluetoothHeadsetClient mService;
     private BluetoothAdapter mAdapter;
 
-    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
             new IBluetoothStateChangeCallback.Stub() {
                 @Override
                 public void onBluetoothStateChange(boolean up) {
                     if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
                     if (!up) {
-                        if (VDBG) Log.d(TAG,"Unbinding service...");
+                        if (VDBG) Log.d(TAG, "Unbinding service...");
                         synchronized (mConnection) {
                             try {
                                 mService = null;
                                 mContext.unbindService(mConnection);
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     } else {
                         synchronized (mConnection) {
                             try {
                                 if (mService == null) {
-                                    if (VDBG) Log.d(TAG,"Binding service...");
-                                    Intent intent = new Intent(IBluetoothHeadsetClient.class.getName());
+                                    if (VDBG) Log.d(TAG, "Binding service...");
+                                    Intent intent = new Intent(
+                                            IBluetoothHeadsetClient.class.getName());
                                     doBind();
                                 }
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     }
                 }
-        };
+            };
 
     /**
      * Create a BluetoothHeadsetClient proxy object.
@@ -415,7 +415,7 @@
             try {
                 mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (RemoteException e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -427,7 +427,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                 android.os.Process.myUserHandle())) {
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth Headset Client Service with " + intent);
             return false;
         }
@@ -448,7 +448,7 @@
             try {
                 mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (Exception e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -458,7 +458,7 @@
                     mService = null;
                     mContext.unbindService(mConnection);
                 } catch (Exception re) {
-                    Log.e(TAG,"",re);
+                    Log.e(TAG, "", re);
                 }
             }
         }
@@ -472,48 +472,44 @@
      * second connection, this implementation will disconnect already connected
      * device automatically and will process the new one.
      *
-     * @param device    a remote device we want connect to
-     * @return <code>true</code> if command has been issued successfully;
-     *          <code>false</code> otherwise;
-     *          upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED}
-     *          intent.
+     * @param device a remote device we want connect to
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise; upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED} intent.
      */
     public boolean connect(BluetoothDevice device) {
         if (DBG) log("connect(" + device + ")");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.connect(device);
+                return service.connect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
     /**
      * Disconnects remote device
      *
-     * @param device    a remote device we want disconnect
-     * @return          <code>true</code> if command has been issued successfully;
-     *                  <code>false</code> otherwise;
-     *                  upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED}
-     *                  intent.
+     * @param device a remote device we want disconnect
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise; upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED} intent.
      */
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) log("disconnect(" + device + ")");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.disconnect(device);
+                return service.disconnect(device);
             } catch (RemoteException e) {
-              Log.e(TAG, Log.getStackTraceString(new Throwable()));
-              return false;
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -525,60 +521,61 @@
     @Override
     public List<BluetoothDevice> getConnectedDevices() {
         if (VDBG) log("getConnectedDevices()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getConnectedDevices();
+                return service.getConnectedDevices();
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
     /**
      * Returns list of remote devices in a particular state
      *
-     * @param states    collection of states
-     * @return          list of devices that state matches the states listed in
-     *                  <code>states</code>; empty list if nothing matches the
-     *                  <code>states</code>
+     * @param states collection of states
+     * @return list of devices that state matches the states listed in <code>states</code>; empty
+     * list if nothing matches the <code>states</code>
      */
     @Override
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         if (VDBG) log("getDevicesMatchingStates()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getDevicesMatchingConnectionStates(states);
+                return service.getDevicesMatchingConnectionStates(states);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
     /**
      * Returns state of the <code>device</code>
      *
-     * @param device    a remote device
-     * @return          the state of connection of the device
+     * @param device a remote device
+     * @return the state of connection of the device
      */
     @Override
     public int getConnectionState(BluetoothDevice device) {
         if (VDBG) log("getConnectionState(" + device + ")");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getConnectionState(device);
+                return service.getConnectionState(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.STATE_DISCONNECTED;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return BluetoothProfile.STATE_DISCONNECTED;
     }
 
@@ -589,20 +586,20 @@
      */
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
-            if (priority != BluetoothProfile.PRIORITY_OFF &&
-                    priority != BluetoothProfile.PRIORITY_ON) {
-              return false;
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            if (priority != BluetoothProfile.PRIORITY_OFF
+                    && priority != BluetoothProfile.PRIORITY_ON) {
+                return false;
             }
             try {
-                return mService.setPriority(device, priority);
+                return service.setPriority(device, priority);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -611,187 +608,175 @@
      */
     public int getPriority(BluetoothDevice device) {
         if (VDBG) log("getPriority(" + device + ")");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getPriority(device);
+                return service.getPriority(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return PRIORITY_OFF;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return PRIORITY_OFF;
     }
 
     /**
      * Starts voice recognition.
      *
-     * @param device    remote device
-     * @return          <code>true</code> if command has been issued successfully;
-     *                   <code>false</code> otherwise;
-     *                   upon completion HFP sends {@link #ACTION_AG_EVENT}
-     *                   intent.
+     * @param device remote device
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise; upon completion HFP sends {@link #ACTION_AG_EVENT} intent.
      *
-     * <p>Feature required for successful execution is being reported by:
-     * {@link #EXTRA_AG_FEATURE_VOICE_RECOGNITION}.
-     * This method invocation will fail silently when feature is not supported.</p>
+     * <p>Feature required for successful execution is being reported by: {@link
+     * #EXTRA_AG_FEATURE_VOICE_RECOGNITION}. This method invocation will fail silently when feature
+     * is not supported.</p>
      */
     public boolean startVoiceRecognition(BluetoothDevice device) {
         if (DBG) log("startVoiceRecognition()");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.startVoiceRecognition(device);
+                return service.startVoiceRecognition(device);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
     /**
      * Stops voice recognition.
      *
-     * @param device    remote device
-     * @return          <code>true</code> if command has been issued successfully;
-     *                   <code>false</code> otherwise;
-     *                   upon completion HFP sends {@link #ACTION_AG_EVENT}
-     *                   intent.
+     * @param device remote device
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise; upon completion HFP sends {@link #ACTION_AG_EVENT} intent.
      *
-     * <p>Feature required for successful execution is being reported by:
-     * {@link #EXTRA_AG_FEATURE_VOICE_RECOGNITION}.
-     * This method invocation will fail silently when feature is not supported.</p>
+     * <p>Feature required for successful execution is being reported by: {@link
+     * #EXTRA_AG_FEATURE_VOICE_RECOGNITION}. This method invocation will fail silently when feature
+     * is not supported.</p>
      */
     public boolean stopVoiceRecognition(BluetoothDevice device) {
         if (DBG) log("stopVoiceRecognition()");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.stopVoiceRecognition(device);
+                return service.stopVoiceRecognition(device);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
     /**
      * Returns list of all calls in any state.
      *
-     * @param device    remote device
-     * @return          list of calls; empty list if none call exists
+     * @param device remote device
+     * @return list of calls; empty list if none call exists
      */
     public List<BluetoothHeadsetClientCall> getCurrentCalls(BluetoothDevice device) {
         if (DBG) log("getCurrentCalls()");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getCurrentCalls(device);
+                return service.getCurrentCalls(device);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return null;
     }
 
     /**
      * Returns list of current values of AG indicators.
      *
-     * @param device    remote device
-     * @return          bundle of AG  indicators; null if device is not in
-     *                  CONNECTED state
+     * @param device remote device
+     * @return bundle of AG  indicators; null if device is not in CONNECTED state
      */
     public Bundle getCurrentAgEvents(BluetoothDevice device) {
         if (DBG) log("getCurrentCalls()");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getCurrentAgEvents(device);
+                return service.getCurrentAgEvents(device);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return null;
     }
 
     /**
      * Accepts a call
      *
-     * @param device    remote device
-     * @param flag      action policy while accepting a call. Possible values
-     *                   {@link #CALL_ACCEPT_NONE}, {@link #CALL_ACCEPT_HOLD},
-     *                   {@link #CALL_ACCEPT_TERMINATE}
-     * @return          <code>true</code> if command has been issued successfully;
-     *                   <code>false</code> otherwise;
-     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
-     *                   intent.
+     * @param device remote device
+     * @param flag action policy while accepting a call. Possible values {@link #CALL_ACCEPT_NONE},
+     * {@link #CALL_ACCEPT_HOLD}, {@link #CALL_ACCEPT_TERMINATE}
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
      */
     public boolean acceptCall(BluetoothDevice device, int flag) {
         if (DBG) log("acceptCall()");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.acceptCall(device, flag);
+                return service.acceptCall(device, flag);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
     /**
      * Holds a call.
      *
-     * @param device    remote device
-     * @return          <code>true</code> if command has been issued successfully;
-     *                   <code>false</code> otherwise;
-     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
-     *                   intent.
+     * @param device remote device
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
      */
     public boolean holdCall(BluetoothDevice device) {
         if (DBG) log("holdCall()");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.holdCall(device);
+                return service.holdCall(device);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
     /**
      * Rejects a call.
      *
-     * @param device    remote device
-     * @return          <code>true</code> if command has been issued successfully;
-     *                   <code>false</code> otherwise;
-     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
-     *                   intent.
+     * @param device remote device
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
      *
-     * <p>Feature required for successful execution is being reported by:
-     * {@link #EXTRA_AG_FEATURE_REJECT_CALL}.
-     * This method invocation will fail silently when feature is not supported.</p>
+     * <p>Feature required for successful execution is being reported by: {@link
+     * #EXTRA_AG_FEATURE_REJECT_CALL}. This method invocation will fail silently when feature is not
+     * supported.</p>
      */
     public boolean rejectCall(BluetoothDevice device) {
         if (DBG) log("rejectCall()");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.rejectCall(device);
+                return service.rejectCall(device);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -800,30 +785,28 @@
      *
      * Works only when Extended Call Control is supported by Audio Gateway.
      *
-     * @param device    remote device
-     * @param call      Handle of call obtained in {@link dial()} or obtained via
-     *                  {@link ACTION_CALL_CHANGED}. {@code call} may be null in which
-     *                  case we will hangup all active calls.
-     * @return          <code>true</code> if command has been issued successfully;
-     *                   <code>false</code> otherwise;
-     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
-     *                   intent.
+     * @param device remote device
+     * @param call Handle of call obtained in {@link #dial(BluetoothDevice, String)} or obtained via
+     * {@link #ACTION_CALL_CHANGED}. {@code call} may be null in which case we will hangup all active
+     * calls.
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
      *
-     * <p>Feature required for successful execution is being reported by:
-     * {@link #EXTRA_AG_FEATURE_ECC}.
-     * This method invocation will fail silently when feature is not supported.</p>
+     * <p>Feature required for successful execution is being reported by: {@link
+     * #EXTRA_AG_FEATURE_ECC}. This method invocation will fail silently when feature is not
+     * supported.</p>
      */
     public boolean terminateCall(BluetoothDevice device, BluetoothHeadsetClientCall call) {
         if (DBG) log("terminateCall()");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.terminateCall(device, call);
+                return service.terminateCall(device, call);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -832,28 +815,26 @@
      *
      * Works only when Extended Call Control is supported by Audio Gateway.
      *
-     * @param device    remote device
-     * @param index     index of the call to connect in private mode
-     * @return          <code>true</code> if command has been issued successfully;
-     *                   <code>false</code> otherwise;
-     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
-     *                   intent.
+     * @param device remote device
+     * @param index index of the call to connect in private mode
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
      *
-     * <p>Feature required for successful execution is being reported by:
-     * {@link #EXTRA_AG_FEATURE_ECC}.
-     * This method invocation will fail silently when feature is not supported.</p>
+     * <p>Feature required for successful execution is being reported by: {@link
+     * #EXTRA_AG_FEATURE_ECC}. This method invocation will fail silently when feature is not
+     * supported.</p>
      */
     public boolean enterPrivateMode(BluetoothDevice device, int index) {
         if (DBG) log("enterPrivateMode()");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.enterPrivateMode(device, index);
+                return service.enterPrivateMode(device, index);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -862,53 +843,48 @@
      *
      * That means connect other calls and disconnect.
      *
-     * @param device    remote device
-     * @return          <code>true</code> if command has been issued successfully;
-     *                   <code>false</code> otherwise;
-     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
-     *                   intent.
+     * @param device remote device
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
      *
-     * <p>Feature required for successful execution is being reported by:
-     * {@link #EXTRA_AG_FEATURE_MERGE_AND_DETACH}.
-     * This method invocation will fail silently when feature is not supported.</p>
+     * <p>Feature required for successful execution is being reported by: {@link
+     * #EXTRA_AG_FEATURE_MERGE_AND_DETACH}. This method invocation will fail silently when feature
+     * is not supported.</p>
      */
     public boolean explicitCallTransfer(BluetoothDevice device) {
         if (DBG) log("explicitCallTransfer()");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.explicitCallTransfer(device);
+                return service.explicitCallTransfer(device);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
     /**
      * Places a call with specified number.
      *
-     * @param device    remote device
-     * @param number    valid phone number
-     * @return          <code>{@link BluetoothHeadsetClientCall} call</code> if command has been
-     *                  issued successfully;
-     *                  <code>{@link null}</code> otherwise;
-     *                  upon completion HFP sends {@link #ACTION_CALL_CHANGED}
-     *                  intent in case of success; {@link #ACTION_RESULT} is sent
-     *                  otherwise;
+     * @param device remote device
+     * @param number valid phone number
+     * @return <code>{@link BluetoothHeadsetClientCall} call</code> if command has been issued
+     * successfully; <code>{@link null}</code> otherwise; upon completion HFP sends {@link
+     * #ACTION_CALL_CHANGED} intent in case of success; {@link #ACTION_RESULT} is sent otherwise;
      */
     public BluetoothHeadsetClientCall dial(BluetoothDevice device, String number) {
         if (DBG) log("dial()");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.dial(device, number);
+                return service.dial(device, number);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return null;
     }
 
@@ -917,50 +893,48 @@
      *
      * Possible code values : 0,1,2,3,4,5,6,7,8,9,A,B,C,D,*,#
      *
-     * @param device    remote device
-     * @param code  ASCII code
-     * @return          <code>true</code> if command has been issued successfully;
-     *                   <code>false</code> otherwise;
-     *                   upon completion HFP sends {@link #ACTION_RESULT} intent;
+     * @param device remote device
+     * @param code ASCII code
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise; upon completion HFP sends {@link #ACTION_RESULT} intent;
      */
     public boolean sendDTMF(BluetoothDevice device, byte code) {
         if (DBG) log("sendDTMF()");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.sendDTMF(device, code);
+                return service.sendDTMF(device, code);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
     /**
      * Get a number corresponding to last voice tag recorded on AG.
      *
-     * @param device    remote device
-     * @return          <code>true</code> if command has been issued successfully;
-     *                   <code>false</code> otherwise;
-     *                   upon completion HFP sends {@link #ACTION_LAST_VTAG}
-     *                   or {@link #ACTION_RESULT} intent;
+     * @param device remote device
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise; upon completion HFP sends {@link #ACTION_LAST_VTAG} or {@link #ACTION_RESULT}
+     * intent;
      *
-     * <p>Feature required for successful execution is being reported by:
-     * {@link #EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT}.
-     * This method invocation will fail silently when feature is not supported.</p>
+     * <p>Feature required for successful execution is being reported by: {@link
+     * #EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT}. This method invocation will fail silently when
+     * feature is not supported.</p>
      */
     public boolean getLastVoiceTagNumber(BluetoothDevice device) {
         if (DBG) log("getLastVoiceTagNumber()");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getLastVoiceTagNumber(device);
+                return service.getLastVoiceTagNumber(device);
             } catch (RemoteException e) {
-                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -971,10 +945,13 @@
      */
     public int getAudioState(BluetoothDevice device) {
         if (VDBG) log("getAudioState");
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getAudioState(device);
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.getAudioState(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -985,16 +962,19 @@
     /**
      * Sets whether audio routing is allowed.
      *
-     * @param device    remote device
-     * @param allowed   if routing is allowed to the device
-     * Note: This is an internal function and shouldn't be exposed
+     * @param device remote device
+     * @param allowed if routing is allowed to the device Note: This is an internal function and
+     * shouldn't be exposed
      */
     public void setAudioRouteAllowed(BluetoothDevice device, boolean allowed) {
         if (VDBG) log("setAudioRouteAllowed");
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled()) {
             try {
-                mService.setAudioRouteAllowed(device, allowed);
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                service.setAudioRouteAllowed(device, allowed);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -1003,16 +983,20 @@
 
     /**
      * Returns whether audio routing is allowed.
-     * @param device    remote device
-     * @return whether the command succeeded
-     * Note: This is an internal function and shouldn't be exposed
+     *
+     * @param device remote device
+     * @return whether the command succeeded Note: This is an internal function and shouldn't be
+     * exposed
      */
     public boolean getAudioRouteAllowed(BluetoothDevice device) {
         if (VDBG) log("getAudioRouteAllowed");
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getAudioRouteAllowed(device);
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.getAudioRouteAllowed(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -1025,16 +1009,15 @@
      *
      * It setup SCO channel with remote connected Handsfree AG device.
      *
-     * @param device    remote device
-     * @return          <code>true</code> if command has been issued successfully;
-     *                   <code>false</code> otherwise;
-     *                   upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED}
-     *                   intent;
+     * @param device remote device
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise; upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED} intent;
      */
     public boolean connectAudio(BluetoothDevice device) {
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.connectAudio(device);
+                return service.connectAudio(device);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -1050,16 +1033,15 @@
      *
      * It tears down the SCO channel from remote AG device.
      *
-     * @param   device  remote device
-     * @return          <code>true</code> if command has been issued successfully;
-     *                   <code>false</code> otherwise;
-     *                   upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED}
-     *                   intent;
+     * @param device remote device
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise; upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED} intent;
      */
     public boolean disconnectAudio(BluetoothDevice device) {
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.disconnectAudio(device);
+                return service.disconnectAudio(device);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -1073,14 +1055,14 @@
     /**
      * Get Audio Gateway features
      *
-     * @param device    remote device
-     * @return          bundle of AG features; null if no service or
-     *                  AG not connected
+     * @param device remote device
+     * @return bundle of AG features; null if no service or AG not connected
      */
     public Bundle getCurrentAgFeatures(BluetoothDevice device) {
-        if (mService != null && isEnabled()) {
+        final IBluetoothHeadsetClient service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getCurrentAgFeatures(device);
+                return service.getCurrentAgFeatures(device);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -1092,7 +1074,7 @@
     }
 
 
-    private ServiceConnection mConnection = new ServiceConnection() {
+    private final ServiceConnection mConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName className, IBinder service) {
             if (DBG) Log.d(TAG, "Proxy object connected");
@@ -1103,6 +1085,7 @@
                         BluetoothHeadsetClient.this);
             }
         }
+
         @Override
         public void onServiceDisconnected(ComponentName className) {
             if (DBG) Log.d(TAG, "Proxy object disconnected");
@@ -1114,15 +1097,11 @@
     };
 
     private boolean isEnabled() {
-       if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
-       return false;
+        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
     }
 
-    private boolean isValidDevice(BluetoothDevice device) {
-       if (device == null) return false;
-
-       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-       return false;
+    private static boolean isValidDevice(BluetoothDevice device) {
+        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
     }
 
     private static void log(String msg) {
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
index 420c079f..dc00d63 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
@@ -25,6 +25,7 @@
 /**
  * This class represents a single call, its state and properties.
  * It implements {@link Parcelable} for inter-process message passing.
+ *
  * @hide
  */
 public final class BluetoothHeadsetClientCall implements Parcelable {
@@ -98,7 +99,7 @@
      *
      * <p>Note: This is an internal function and shouldn't be exposed</p>
      *
-     * @param  state    new call state.
+     * @param state new call state.
      */
     public void setState(int state) {
         mState = state;
@@ -109,7 +110,7 @@
      *
      * <p>Note: This is an internal function and shouldn't be exposed</p>
      *
-     * @param number    String representing phone number.
+     * @param number String representing phone number.
      */
     public void setNumber(String number) {
         mNumber = number;
@@ -120,8 +121,7 @@
      *
      * <p>Note: This is an internal function and shouldn't be exposed</p>
      *
-     * @param multiParty    if <code>true</code> sets this call as a part
-     *                      of multi party conference.
+     * @param multiParty if <code>true</code> sets this call as a part of multi party conference.
      */
     public void setMultiParty(boolean multiParty) {
         mMultiParty = multiParty;
@@ -185,8 +185,7 @@
     /**
      * Checks if call is an active call in a conference mode (aka multi party).
      *
-     * @return <code>true</code> if call is a multi party call,
-     *         <code>false</code> otherwise.
+     * @return <code>true</code> if call is a multi party call, <code>false</code> otherwise.
      */
     public boolean isMultiParty() {
         return mMultiParty;
@@ -195,17 +194,22 @@
     /**
      * Checks if this call is an outgoing call.
      *
-     * @return <code>true</code> if its outgoing call,
-     *         <code>false</code> otherwise.
+     * @return <code>true</code> if its outgoing call, <code>false</code> otherwise.
      */
     public boolean isOutgoing() {
         return mOutgoing;
     }
 
+    @Override
     public String toString() {
         return toString(false);
     }
 
+    /**
+     * Generate a log string for this call
+     * @param loggable whether device address should be logged
+     * @return log string
+     */
     public String toString(boolean loggable) {
         StringBuilder builder = new StringBuilder("BluetoothHeadsetClientCall{mDevice: ");
         builder.append(loggable ? mDevice : mDevice.hashCode());
@@ -215,15 +219,33 @@
         builder.append(mUUID);
         builder.append(", mState: ");
         switch (mState) {
-            case CALL_STATE_ACTIVE: builder.append("ACTIVE"); break;
-            case CALL_STATE_HELD: builder.append("HELD"); break;
-            case CALL_STATE_DIALING: builder.append("DIALING"); break;
-            case CALL_STATE_ALERTING: builder.append("ALERTING"); break;
-            case CALL_STATE_INCOMING: builder.append("INCOMING"); break;
-            case CALL_STATE_WAITING: builder.append("WAITING"); break;
-            case CALL_STATE_HELD_BY_RESPONSE_AND_HOLD: builder.append("HELD_BY_RESPONSE_AND_HOLD"); break;
-            case CALL_STATE_TERMINATED: builder.append("TERMINATED"); break;
-            default: builder.append(mState); break;
+            case CALL_STATE_ACTIVE:
+                builder.append("ACTIVE");
+                break;
+            case CALL_STATE_HELD:
+                builder.append("HELD");
+                break;
+            case CALL_STATE_DIALING:
+                builder.append("DIALING");
+                break;
+            case CALL_STATE_ALERTING:
+                builder.append("ALERTING");
+                break;
+            case CALL_STATE_INCOMING:
+                builder.append("INCOMING");
+                break;
+            case CALL_STATE_WAITING:
+                builder.append("WAITING");
+                break;
+            case CALL_STATE_HELD_BY_RESPONSE_AND_HOLD:
+                builder.append("HELD_BY_RESPONSE_AND_HOLD");
+                break;
+            case CALL_STATE_TERMINATED:
+                builder.append("TERMINATED");
+                break;
+            default:
+                builder.append(mState);
+                break;
         }
         builder.append(", mNumber: ");
         builder.append(loggable ? mNumber : mNumber.hashCode());
@@ -242,7 +264,7 @@
             new Parcelable.Creator<BluetoothHeadsetClientCall>() {
                 @Override
                 public BluetoothHeadsetClientCall createFromParcel(Parcel in) {
-                    return new BluetoothHeadsetClientCall((BluetoothDevice)in.readParcelable(null),
+                    return new BluetoothHeadsetClientCall((BluetoothDevice) in.readParcelable(null),
                             in.readInt(), UUID.fromString(in.readString()), in.readInt(),
                             in.readString(), in.readInt() == 1, in.readInt() == 1);
                 }
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index 8d77888..57a0197 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -36,24 +36,23 @@
  * Service via IPC.
  *
  * <p> How to connect to a health device which is acting in the source role.
- *  <li> Use {@link BluetoothAdapter#getProfileProxy} to get
- *  the BluetoothHealth proxy object. </li>
- *  <li> Create an {@link BluetoothHealth} callback and call
- *  {@link #registerSinkAppConfiguration} to register an application
- *  configuration </li>
- *  <li> Pair with the remote device. This currently needs to be done manually
- *  from Bluetooth Settings </li>
- *  <li> Connect to a health device using {@link #connectChannelToSource}. Some
- *  devices will connect the channel automatically. The {@link BluetoothHealth}
- *  callback will inform the application of channel state change. </li>
- *  <li> Use the file descriptor provided with a connected channel to read and
- *  write data to the health channel. </li>
- *  <li> The received data needs to be interpreted using a health manager which
- *  implements the IEEE 11073-xxxxx specifications.
- *  <li> When done, close the health channel by calling {@link #disconnectChannel}
- *  and unregister the application configuration calling
- *  {@link #unregisterAppConfiguration}
- *
+ * <li> Use {@link BluetoothAdapter#getProfileProxy} to get
+ * the BluetoothHealth proxy object. </li>
+ * <li> Create an {@link BluetoothHealth} callback and call
+ * {@link #registerSinkAppConfiguration} to register an application
+ * configuration </li>
+ * <li> Pair with the remote device. This currently needs to be done manually
+ * from Bluetooth Settings </li>
+ * <li> Connect to a health device using {@link #connectChannelToSource}. Some
+ * devices will connect the channel automatically. The {@link BluetoothHealth}
+ * callback will inform the application of channel state change. </li>
+ * <li> Use the file descriptor provided with a connected channel to read and
+ * write data to the health channel. </li>
+ * <li> The received data needs to be interpreted using a health manager which
+ * implements the IEEE 11073-xxxxx specifications.
+ * <li> When done, close the health channel by calling {@link #disconnectChannel}
+ * and unregister the application configuration calling
+ * {@link #unregisterAppConfiguration}
  */
 public final class BluetoothHealth implements BluetoothProfile {
     private static final String TAG = "BluetoothHealth";
@@ -98,34 +97,34 @@
     /** @hide */
     public static final int HEALTH_OPERATION_NOT_ALLOWED = 6005;
 
-    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
             new IBluetoothStateChangeCallback.Stub() {
                 public void onBluetoothStateChange(boolean up) {
                     if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
                     if (!up) {
-                        if (VDBG) Log.d(TAG,"Unbinding service...");
+                        if (VDBG) Log.d(TAG, "Unbinding service...");
                         synchronized (mConnection) {
                             try {
                                 mService = null;
                                 mContext.unbindService(mConnection);
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     } else {
                         synchronized (mConnection) {
                             try {
                                 if (mService == null) {
-                                    if (VDBG) Log.d(TAG,"Binding service...");
+                                    if (VDBG) Log.d(TAG, "Binding service...");
                                     doBind();
                                 }
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     }
                 }
-        };
+            };
 
 
     /**
@@ -137,10 +136,10 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param name The friendly name associated with the application or configuration.
-     * @param dataType The dataType of the Source role of Health Profile to which
-     *                   the sink wants to connect to.
-     * @param callback A callback to indicate success or failure of the registration and
-     *               all operations done on this application configuration.
+     * @param dataType The dataType of the Source role of Health Profile to which the sink wants to
+     * connect to.
+     * @param callback A callback to indicate success or failure of the registration and all
+     * operations done on this application configuration.
      * @return If true, callback will be called.
      */
     public boolean registerSinkAppConfiguration(String name, int dataType,
@@ -161,9 +160,8 @@
      *
      * @param name The friendly name associated with the application or configuration.
      * @param dataType The dataType of the Source role of Health Profile.
-     * @param channelType The channel type. Will be one of
-     *                              {@link #CHANNEL_TYPE_RELIABLE}  or
-     *                              {@link #CHANNEL_TYPE_STREAMING}
+     * @param channelType The channel type. Will be one of {@link #CHANNEL_TYPE_RELIABLE}  or {@link
+     * #CHANNEL_TYPE_STREAMING}
      * @param callback - A callback to indicate success or failure.
      * @return If true, callback will be called.
      * @hide
@@ -178,9 +176,10 @@
         BluetoothHealthAppConfiguration config =
                 new BluetoothHealthAppConfiguration(name, dataType, role, channelType);
 
-        if (mService != null) {
+        final IBluetoothHealth service = mService;
+        if (service != null) {
             try {
-                result = mService.registerAppConfiguration(config, wrapper);
+                result = service.registerAppConfiguration(config, wrapper);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -197,14 +196,15 @@
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
-     * @param config  The health app configuration
+     * @param config The health app configuration
      * @return Success or failure.
      */
     public boolean unregisterAppConfiguration(BluetoothHealthAppConfiguration config) {
         boolean result = false;
-        if (mService != null && isEnabled() && config != null) {
+        final IBluetoothHealth service = mService;
+        if (service != null && isEnabled() && config != null) {
             try {
-                result = mService.unregisterAppConfiguration(config);
+                result = service.unregisterAppConfiguration(config);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -224,16 +224,16 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param device The remote Bluetooth device.
-     * @param config The application configuration which has been registered using
-     *        {@link #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
+     * @param config The application configuration which has been registered using {@link
+     * #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
      * @return If true, the callback associated with the application config will be called.
      */
     public boolean connectChannelToSource(BluetoothDevice device,
             BluetoothHealthAppConfiguration config) {
-        if (mService != null && isEnabled() && isValidDevice(device) &&
-                config != null) {
+        final IBluetoothHealth service = mService;
+        if (service != null && isEnabled() && isValidDevice(device) && config != null) {
             try {
-                return mService.connectChannelToSource(device, config);
+                return service.connectChannelToSource(device, config);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -249,20 +249,20 @@
      * This is an asynchronous call. If this function returns true, the callback
      * associated with the application configuration will be called.
      *
-     *<p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param device The remote Bluetooth device.
-     * @param config The application configuration which has been registered using
-     *        {@link #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
+     * @param config The application configuration which has been registered using {@link
+     * #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
      * @return If true, the callback associated with the application config will be called.
      * @hide
      */
     public boolean connectChannelToSink(BluetoothDevice device,
             BluetoothHealthAppConfiguration config, int channelType) {
-        if (mService != null && isEnabled() && isValidDevice(device) &&
-                config != null) {
+        final IBluetoothHealth service = mService;
+        if (service != null && isEnabled() && isValidDevice(device) && config != null) {
             try {
-                return mService.connectChannelToSink(device, config, channelType);
+                return service.connectChannelToSink(device, config, channelType);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -278,20 +278,20 @@
      * This is an asynchronous call. If this function returns true, the callback
      * associated with the application configuration will be called.
      *
-     *<p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param device The remote Bluetooth device.
-     * @param config The application configuration which has been registered using
-     *        {@link #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
+     * @param config The application configuration which has been registered using {@link
+     * #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
      * @param channelId The channel id associated with the channel
      * @return If true, the callback associated with the application config will be called.
      */
     public boolean disconnectChannel(BluetoothDevice device,
             BluetoothHealthAppConfiguration config, int channelId) {
-        if (mService != null && isEnabled() && isValidDevice(device) &&
-                config != null) {
+        final IBluetoothHealth service = mService;
+        if (service != null && isEnabled() && isValidDevice(device) && config != null) {
             try {
-                return mService.disconnectChannel(device, config, channelId);
+                return service.disconnectChannel(device, config, channelId);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -317,10 +317,10 @@
      */
     public ParcelFileDescriptor getMainChannelFd(BluetoothDevice device,
             BluetoothHealthAppConfiguration config) {
-        if (mService != null && isEnabled() && isValidDevice(device) &&
-                config != null) {
+        final IBluetoothHealth service = mService;
+        if (service != null && isEnabled() && isValidDevice(device) && config != null) {
             try {
-                return mService.getMainChannelFd(device, config);
+                return service.getMainChannelFd(device, config);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -342,15 +342,15 @@
      * local adapter.
      *
      * @param device Remote bluetooth device.
-     * @return State of the profile connection. One of
-     *               {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
-     *               {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
+     * @return State of the profile connection. One of {@link #STATE_CONNECTED}, {@link
+     * #STATE_CONNECTING}, {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
      */
     @Override
     public int getConnectionState(BluetoothDevice device) {
-        if (mService != null && isEnabled() && isValidDevice(device)) {
+        final IBluetoothHealth service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getHealthDeviceConnectionState(device);
+                return service.getHealthDeviceConnectionState(device);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -372,19 +372,21 @@
      * state of the local Bluetooth adapter for this profile. This can be used
      * by applications like status bar which would just like to know the state of the
      * local adapter.
+     *
      * @return List of devices. The list will be empty on error.
      */
     @Override
     public List<BluetoothDevice> getConnectedDevices() {
-        if (mService != null && isEnabled()) {
+        final IBluetoothHealth service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getConnectedHealthDevices();
+                return service.getConnectedHealthDevices();
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
@@ -401,22 +403,22 @@
      * by applications like status bar which would just like to know the state of the
      * local adapter.
      *
-     * @param states Array of states. States can be one of
-     *              {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
-     *              {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
+     * @param states Array of states. States can be one of {@link #STATE_CONNECTED}, {@link
+     * #STATE_CONNECTING}, {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
      * @return List of devices. The list will be empty on error.
      */
     @Override
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        if (mService != null && isEnabled()) {
+        final IBluetoothHealth service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getHealthDevicesMatchingConnectionStates(states);
+                return service.getHealthDevicesMatchingConnectionStates(states);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
@@ -429,25 +431,25 @@
 
         @Override
         public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config,
-                                                         int status) {
-           mCallback.onHealthAppConfigurationStatusChange(config, status);
+                int status) {
+            mCallback.onHealthAppConfigurationStatusChange(config, status);
         }
 
         @Override
         public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config,
-                                       BluetoothDevice device, int prevState, int newState,
-                                       ParcelFileDescriptor fd, int channelId) {
+                BluetoothDevice device, int prevState, int newState,
+                ParcelFileDescriptor fd, int channelId) {
             mCallback.onHealthChannelStateChange(config, device, prevState, newState, fd,
-                                                 channelId);
+                    channelId);
         }
     }
 
-     /** Health Channel Connection State - Disconnected */
-    public static final int STATE_CHANNEL_DISCONNECTED  = 0;
+    /** Health Channel Connection State - Disconnected */
+    public static final int STATE_CHANNEL_DISCONNECTED = 0;
     /** Health Channel Connection State - Connecting */
-    public static final int STATE_CHANNEL_CONNECTING    = 1;
+    public static final int STATE_CHANNEL_CONNECTING = 1;
     /** Health Channel Connection State - Connected */
-    public static final int STATE_CHANNEL_CONNECTED     = 2;
+    public static final int STATE_CHANNEL_CONNECTED = 2;
     /** Health Channel Connection State - Disconnecting */
     public static final int STATE_CHANNEL_DISCONNECTING = 3;
 
@@ -462,7 +464,7 @@
 
     private Context mContext;
     private ServiceListener mServiceListener;
-    private IBluetoothHealth mService;
+    private volatile IBluetoothHealth mService;
     BluetoothAdapter mAdapter;
 
     /**
@@ -477,7 +479,7 @@
             try {
                 mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (RemoteException e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -503,7 +505,7 @@
             try {
                 mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (Exception e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -513,7 +515,7 @@
                     mService = null;
                     mContext.unbindService(mConnection);
                 } catch (Exception re) {
-                    Log.e(TAG,"",re);
+                    Log.e(TAG, "", re);
                 }
             }
         }
@@ -529,6 +531,7 @@
                 mServiceListener.onServiceConnected(BluetoothProfile.HEALTH, BluetoothHealth.this);
             }
         }
+
         public void onServiceDisconnected(ComponentName className) {
             if (DBG) Log.d(TAG, "Proxy object disconnected");
             mService = null;
@@ -546,19 +549,16 @@
         return false;
     }
 
-    private boolean isValidDevice(BluetoothDevice device) {
-        if (device == null) return false;
-
-        if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-        return false;
+    private static boolean isValidDevice(BluetoothDevice device) {
+        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
     }
 
     private boolean checkAppParam(String name, int role, int channelType,
             BluetoothHealthCallback callback) {
-        if (name == null || (role != SOURCE_ROLE && role != SINK_ROLE) ||
-                (channelType != CHANNEL_TYPE_RELIABLE &&
-                channelType != CHANNEL_TYPE_STREAMING &&
-                channelType != CHANNEL_TYPE_ANY) || callback == null) {
+        if (name == null || (role != SOURCE_ROLE && role != SINK_ROLE)
+                || (channelType != CHANNEL_TYPE_RELIABLE && channelType != CHANNEL_TYPE_STREAMING
+                    && channelType != CHANNEL_TYPE_ANY)
+                || callback == null) {
             return false;
         }
         if (role == SOURCE_ROLE && channelType == CHANNEL_TYPE_ANY) return false;
diff --git a/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java b/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java
index 1717a1e..7c9db6f 100644
--- a/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java
+++ b/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java
@@ -25,7 +25,6 @@
  * the {@link BluetoothHealth} class. This class represents an application configuration
  * that the Bluetooth Health third party application will register to communicate with the
  * remote Bluetooth health device.
- *
  */
 public final class BluetoothHealthAppConfiguration implements Parcelable {
     private final String mName;
@@ -52,12 +51,11 @@
      *
      * @param name Friendly name associated with the application configuration
      * @param dataType Data Type of the remote Bluetooth Health device
-     * @param role {@link BluetoothHealth#SOURCE_ROLE} or
-     *                     {@link BluetoothHealth#SINK_ROLE}
+     * @param role {@link BluetoothHealth#SOURCE_ROLE} or {@link BluetoothHealth#SINK_ROLE}
      * @hide
      */
     BluetoothHealthAppConfiguration(String name, int dataType, int role, int
-        channelType) {
+            channelType) {
         mName = name;
         mDataType = dataType;
         mRole = role;
@@ -71,10 +69,8 @@
 
             if (mName == null) return false;
 
-            return mName.equals(config.getName()) &&
-                    mDataType == config.getDataType() &&
-                    mRole == config.getRole() &&
-                    mChannelType == config.getChannelType();
+            return mName.equals(config.getName()) && mDataType == config.getDataType()
+                    && mRole == config.getRole() && mChannelType == config.getChannelType();
         }
         return false;
     }
@@ -91,11 +87,11 @@
 
     @Override
     public String toString() {
-        return "BluetoothHealthAppConfiguration [mName = " + mName +
-            ",mDataType = " + mDataType + ", mRole = " + mRole + ",mChannelType = " +
-            mChannelType + "]";
+        return "BluetoothHealthAppConfiguration [mName = " + mName + ",mDataType = " + mDataType
+                + ", mRole = " + mRole + ",mChannelType = " + mChannelType + "]";
     }
 
+    @Override
     public int describeContents() {
         return 0;
     }
@@ -121,8 +117,7 @@
     /**
      * Return the role associated with this application configuration.
      *
-     * @return One of {@link BluetoothHealth#SOURCE_ROLE} or
-     *                         {@link BluetoothHealth#SINK_ROLE}
+     * @return One of {@link BluetoothHealth#SOURCE_ROLE} or {@link BluetoothHealth#SINK_ROLE}
      */
     public int getRole() {
         return mRole;
@@ -131,9 +126,8 @@
     /**
      * Return the channel type associated with this application configuration.
      *
-     * @return One of {@link BluetoothHealth#CHANNEL_TYPE_RELIABLE} or
-     *                         {@link BluetoothHealth#CHANNEL_TYPE_STREAMING} or
-     *                         {@link BluetoothHealth#CHANNEL_TYPE_ANY}.
+     * @return One of {@link BluetoothHealth#CHANNEL_TYPE_RELIABLE} or {@link
+     * BluetoothHealth#CHANNEL_TYPE_STREAMING} or {@link BluetoothHealth#CHANNEL_TYPE_ANY}.
      * @hide
      */
     public int getChannelType() {
@@ -141,23 +135,24 @@
     }
 
     public static final Parcelable.Creator<BluetoothHealthAppConfiguration> CREATOR =
-        new Parcelable.Creator<BluetoothHealthAppConfiguration>() {
-        @Override
-        public BluetoothHealthAppConfiguration createFromParcel(Parcel in) {
-            String name = in.readString();
-            int type = in.readInt();
-            int role = in.readInt();
-            int channelType = in.readInt();
-            return new BluetoothHealthAppConfiguration(name, type, role,
-                channelType);
-        }
+            new Parcelable.Creator<BluetoothHealthAppConfiguration>() {
+                @Override
+                public BluetoothHealthAppConfiguration createFromParcel(Parcel in) {
+                    String name = in.readString();
+                    int type = in.readInt();
+                    int role = in.readInt();
+                    int channelType = in.readInt();
+                    return new BluetoothHealthAppConfiguration(name, type, role,
+                            channelType);
+                }
 
-        @Override
-        public BluetoothHealthAppConfiguration[] newArray(int size) {
-            return new BluetoothHealthAppConfiguration[size];
-        }
-    };
+                @Override
+                public BluetoothHealthAppConfiguration[] newArray(int size) {
+                    return new BluetoothHealthAppConfiguration[size];
+                }
+            };
 
+    @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeString(mName);
         out.writeInt(mDataType);
diff --git a/core/java/android/bluetooth/BluetoothHealthCallback.java b/core/java/android/bluetooth/BluetoothHealthCallback.java
index 128376f..4023485 100644
--- a/core/java/android/bluetooth/BluetoothHealthCallback.java
+++ b/core/java/android/bluetooth/BluetoothHealthCallback.java
@@ -33,12 +33,11 @@
      * <p> This callback is called on the binder thread (not on the UI thread)
      *
      * @param config Bluetooth Health app configuration
-     * @param status Success or failure of the registration or unregistration
-     *            calls. Can be one of
-     *            {@link BluetoothHealth#APP_CONFIG_REGISTRATION_SUCCESS} or
-     *            {@link BluetoothHealth#APP_CONFIG_REGISTRATION_FAILURE} or
-     *            {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_SUCCESS} or
-     *            {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_FAILURE}
+     * @param status Success or failure of the registration or unregistration calls. Can be one of
+     * {@link BluetoothHealth#APP_CONFIG_REGISTRATION_SUCCESS} or {@link
+     * BluetoothHealth#APP_CONFIG_REGISTRATION_FAILURE} or
+     * {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_SUCCESS}
+     * or {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_FAILURE}
      */
     @BinderThread
     public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config,
@@ -57,15 +56,15 @@
      * @param prevState The previous state of the channel
      * @param newState The new state of the channel.
      * @param fd The Parcel File Descriptor when the channel state is connected.
-     * @param channelId The id associated with the channel. This id will be used
-     *            in future calls like when disconnecting the channel.
+     * @param channelId The id associated with the channel. This id will be used in future calls
+     * like when disconnecting the channel.
      */
     @BinderThread
     public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config,
             BluetoothDevice device, int prevState, int newState, ParcelFileDescriptor fd,
             int channelId) {
-        Log.d(TAG, "onHealthChannelStateChange: " + config + "Device: " + device +
-              "prevState:" + prevState + "newState:" + newState + "ParcelFd:" + fd +
-              "ChannelId:" + channelId);
+        Log.d(TAG, "onHealthChannelStateChange: " + config + "Device: " + device
+                + "prevState:" + prevState + "newState:" + newState + "ParcelFd:" + fd
+                + "ChannelId:" + channelId);
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothHidDevice.java b/core/java/android/bluetooth/BluetoothHidDevice.java
new file mode 100644
index 0000000..6692e13
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothHidDevice.java
@@ -0,0 +1,592 @@
+/*
+ * 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.bluetooth;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Provides the public APIs to control the Bluetooth HID Device
+ * profile.
+ *
+ * BluetoothHidDevice is a proxy object for controlling the Bluetooth HID
+ * Device Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
+ * the BluetoothHidDevice proxy object.
+ *
+ * {@hide}
+ */
+public final class BluetoothHidDevice implements BluetoothProfile {
+
+    private static final String TAG = BluetoothHidDevice.class.getSimpleName();
+
+    /**
+     * Intent used to broadcast the change in connection state of the Input
+     * Host profile.
+     *
+     * <p>This intent will have 3 extras:
+     * <ul>
+     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * </ul>
+     *
+     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
+     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+     * receive.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_CONNECTION_STATE_CHANGED =
+            "android.bluetooth.hiddevice.profile.action.CONNECTION_STATE_CHANGED";
+
+    /**
+     * Constants representing device subclass.
+     *
+     * @see #registerApp
+     * (BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceAppQosSettings,
+     * BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceCallback)
+     */
+    public static final byte SUBCLASS1_NONE = (byte) 0x00;
+    public static final byte SUBCLASS1_KEYBOARD = (byte) 0x40;
+    public static final byte SUBCLASS1_MOUSE = (byte) 0x80;
+    public static final byte SUBCLASS1_COMBO = (byte) 0xC0;
+
+    public static final byte SUBCLASS2_UNCATEGORIZED = (byte) 0x00;
+    public static final byte SUBCLASS2_JOYSTICK = (byte) 0x01;
+    public static final byte SUBCLASS2_GAMEPAD = (byte) 0x02;
+    public static final byte SUBCLASS2_REMOTE_CONTROL = (byte) 0x03;
+    public static final byte SUBCLASS2_SENSING_DEVICE = (byte) 0x04;
+    public static final byte SUBCLASS2_DIGITIZER_TABLET = (byte) 0x05;
+    public static final byte SUBCLASS2_CARD_READER = (byte) 0x06;
+
+    /**
+     * Constants representing report types.
+     *
+     * @see BluetoothHidDeviceCallback#onGetReport(BluetoothDevice, byte, byte, int)
+     * @see BluetoothHidDeviceCallback#onSetReport(BluetoothDevice, byte, byte, byte[])
+     * @see BluetoothHidDeviceCallback#onIntrData(BluetoothDevice, byte, byte[])
+     */
+    public static final byte REPORT_TYPE_INPUT = (byte) 1;
+    public static final byte REPORT_TYPE_OUTPUT = (byte) 2;
+    public static final byte REPORT_TYPE_FEATURE = (byte) 3;
+
+    /**
+     * Constants representing error response for Set Report.
+     *
+     * @see BluetoothHidDeviceCallback#onSetReport(BluetoothDevice, byte, byte, byte[])
+     */
+    public static final byte ERROR_RSP_SUCCESS = (byte) 0;
+    public static final byte ERROR_RSP_NOT_READY = (byte) 1;
+    public static final byte ERROR_RSP_INVALID_RPT_ID = (byte) 2;
+    public static final byte ERROR_RSP_UNSUPPORTED_REQ = (byte) 3;
+    public static final byte ERROR_RSP_INVALID_PARAM = (byte) 4;
+    public static final byte ERROR_RSP_UNKNOWN = (byte) 14;
+
+    /**
+     * Constants representing protocol mode used set by host. Default is always
+     * {@link #PROTOCOL_REPORT_MODE} unless notified otherwise.
+     *
+     * @see BluetoothHidDeviceCallback#onSetProtocol(BluetoothDevice, byte)
+     */
+    public static final byte PROTOCOL_BOOT_MODE = (byte) 0;
+    public static final byte PROTOCOL_REPORT_MODE = (byte) 1;
+
+    private Context mContext;
+
+    private ServiceListener mServiceListener;
+
+    private volatile IBluetoothHidDevice mService;
+
+    private BluetoothAdapter mAdapter;
+
+    private static class BluetoothHidDeviceCallbackWrapper extends
+            IBluetoothHidDeviceCallback.Stub {
+
+        private BluetoothHidDeviceCallback mCallback;
+
+        public BluetoothHidDeviceCallbackWrapper(BluetoothHidDeviceCallback callback) {
+            mCallback = callback;
+        }
+
+        @Override
+        public void onAppStatusChanged(BluetoothDevice pluggedDevice,
+                BluetoothHidDeviceAppConfiguration config, boolean registered) {
+            mCallback.onAppStatusChanged(pluggedDevice, config, registered);
+        }
+
+        @Override
+        public void onConnectionStateChanged(BluetoothDevice device, int state) {
+            mCallback.onConnectionStateChanged(device, state);
+        }
+
+        @Override
+        public void onGetReport(BluetoothDevice device, byte type, byte id, int bufferSize) {
+            mCallback.onGetReport(device, type, id, bufferSize);
+        }
+
+        @Override
+        public void onSetReport(BluetoothDevice device, byte type, byte id, byte[] data) {
+            mCallback.onSetReport(device, type, id, data);
+        }
+
+        @Override
+        public void onSetProtocol(BluetoothDevice device, byte protocol) {
+            mCallback.onSetProtocol(device, protocol);
+        }
+
+        @Override
+        public void onIntrData(BluetoothDevice device, byte reportId, byte[] data) {
+            mCallback.onIntrData(device, reportId, data);
+        }
+
+        @Override
+        public void onVirtualCableUnplug(BluetoothDevice device) {
+            mCallback.onVirtualCableUnplug(device);
+        }
+    }
+
+    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+            new IBluetoothStateChangeCallback.Stub() {
+
+                public void onBluetoothStateChange(boolean up) {
+                    Log.d(TAG, "onBluetoothStateChange: up=" + up);
+                    synchronized (mConnection) {
+                        if (up) {
+                            try {
+                                if (mService == null) {
+                                    Log.d(TAG, "Binding HID Device service...");
+                                    doBind();
+                                }
+                            } catch (IllegalStateException e) {
+                                Log.e(TAG,
+                                        "onBluetoothStateChange: could not bind to HID Dev "
+                                                + "service: ", e);
+                            } catch (SecurityException e) {
+                                Log.e(TAG,
+                                        "onBluetoothStateChange: could not bind to HID Dev "
+                                                + "service: ", e);
+                            }
+                        } else {
+                            Log.d(TAG, "Unbinding service...");
+                            doUnbind();
+                        }
+                    }
+                }
+            };
+
+    private final ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            Log.d(TAG, "onServiceConnected()");
+            mService = IBluetoothHidDevice.Stub.asInterface(service);
+            if (mServiceListener != null) {
+                mServiceListener.onServiceConnected(BluetoothProfile.HID_DEVICE,
+                        BluetoothHidDevice.this);
+            }
+        }
+        public void onServiceDisconnected(ComponentName className) {
+            Log.d(TAG, "onServiceDisconnected()");
+            mService = null;
+            if (mServiceListener != null) {
+                mServiceListener.onServiceDisconnected(BluetoothProfile.HID_DEVICE);
+            }
+        }
+    };
+
+    BluetoothHidDevice(Context context, ServiceListener listener) {
+        Log.v(TAG, "BluetoothHidDevice");
+
+        mContext = context;
+        mServiceListener = listener;
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (RemoteException e) {
+                e.printStackTrace();
+            }
+        }
+
+        doBind();
+    }
+
+    boolean doBind() {
+        Intent intent = new Intent(IBluetoothHidDevice.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
+            Log.e(TAG, "Could not bind to Bluetooth HID Device Service with " + intent);
+            return false;
+        }
+        Log.d(TAG, "Bound to HID Device Service");
+        return true;
+    }
+
+    void doUnbind() {
+        Log.d(TAG, "Unbinding HidDevService");
+        if (mService != null) {
+            mService = null;
+            try {
+                mContext.unbindService(mConnection);
+            } catch (IllegalArgumentException e) {
+                Log.e(TAG, "Unable to unbind HidDevService", e);
+            }
+        }
+    }
+
+    void close() {
+        Log.v(TAG, "close()");
+
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (RemoteException e) {
+                e.printStackTrace();
+            }
+        }
+
+        synchronized (mConnection) {
+            doUnbind();
+        }
+        mServiceListener = null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<BluetoothDevice> getConnectedDevices() {
+        Log.v(TAG, "getConnectedDevices()");
+
+        final IBluetoothHidDevice service = mService;
+        if (service != null) {
+            try {
+                return service.getConnectedDevices();
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+
+        return new ArrayList<BluetoothDevice>();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+        Log.v(TAG, "getDevicesMatchingConnectionStates(): states=" + Arrays.toString(states));
+
+        final IBluetoothHidDevice service = mService;
+        if (service != null) {
+            try {
+                return service.getDevicesMatchingConnectionStates(states);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+
+        return new ArrayList<BluetoothDevice>();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int getConnectionState(BluetoothDevice device) {
+        Log.v(TAG, "getConnectionState(): device=" + device);
+
+        final IBluetoothHidDevice service = mService;
+        if (service != null) {
+            try {
+                return service.getConnectionState(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+
+        return STATE_DISCONNECTED;
+    }
+
+    /**
+     * Registers application to be used for HID device. Connections to HID
+     * Device are only possible when application is registered. Only one
+     * application can be registered at time. When no longer used, application
+     * should be unregistered using
+     * {@link #unregisterApp(BluetoothHidDeviceAppConfiguration)}.
+     * The registration status should be tracked by the application by handling callback from
+     * BluetoothHidDeviceCallback#onAppStatusChanged. The app registration status is not related
+     * to the return value of this method.
+     *
+     * @param sdp {@link BluetoothHidDeviceAppSdpSettings} object of HID Device SDP record.
+     * The HID Device SDP record is required.
+     * @param inQos {@link BluetoothHidDeviceAppQosSettings} object of Incoming QoS Settings.
+     * The Incoming QoS Settings is not required. Use null or default
+     * BluetoothHidDeviceAppQosSettings.Builder for default values.
+     * @param outQos {@link BluetoothHidDeviceAppQosSettings} object of Outgoing QoS Settings.
+     * The Outgoing QoS Settings is not required. Use null or default
+     * BluetoothHidDeviceAppQosSettings.Builder for default values.
+     * @param callback {@link BluetoothHidDeviceCallback} object to which callback messages will be
+     * sent.
+     * The BluetoothHidDeviceCallback object is required.
+     * @return true if the command is successfully sent; otherwise false.
+     */
+    public boolean registerApp(BluetoothHidDeviceAppSdpSettings sdp,
+            BluetoothHidDeviceAppQosSettings inQos, BluetoothHidDeviceAppQosSettings outQos,
+            BluetoothHidDeviceCallback callback) {
+        Log.v(TAG, "registerApp(): sdp=" + sdp + " inQos=" + inQos + " outQos=" + outQos
+                + " callback=" + callback);
+
+        boolean result = false;
+
+        if (sdp == null || callback == null) {
+            return false;
+        }
+
+        final IBluetoothHidDevice service = mService;
+        if (service != null) {
+            try {
+                BluetoothHidDeviceAppConfiguration config =
+                        new BluetoothHidDeviceAppConfiguration();
+                BluetoothHidDeviceCallbackWrapper cbw =
+                        new BluetoothHidDeviceCallbackWrapper(callback);
+                result = service.registerApp(config, sdp, inQos, outQos, cbw);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+
+        return result;
+    }
+
+    /**
+     * Unregisters application. Active connection will be disconnected and no
+     * new connections will be allowed until registered again using
+     * {@link #registerApp
+     * (BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceAppQosSettings,
+     * BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceCallback)}
+     * The registration status should be tracked by the application by handling callback from
+     * BluetoothHidDeviceCallback#onAppStatusChanged. The app registration status is not related
+     * to the return value of this method.
+     *
+     * @param config {@link BluetoothHidDeviceAppConfiguration} object as obtained from {@link
+     * BluetoothHidDeviceCallback#onAppStatusChanged(BluetoothDevice,
+     * BluetoothHidDeviceAppConfiguration,
+     * boolean)}
+     * @return true if the command is successfully sent; otherwise false.
+     */
+    public boolean unregisterApp(BluetoothHidDeviceAppConfiguration config) {
+        Log.v(TAG, "unregisterApp()");
+
+        boolean result = false;
+
+        final IBluetoothHidDevice service = mService;
+        if (service != null) {
+            try {
+                result = service.unregisterApp(config);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+
+        return result;
+    }
+
+    /**
+     * Sends report to remote host using interrupt channel.
+     *
+     * @param id Report Id, as defined in descriptor. Can be 0 in case Report Id are not defined in
+     * descriptor.
+     * @param data Report data, not including Report Id.
+     * @return true if the command is successfully sent; otherwise false.
+     */
+    public boolean sendReport(BluetoothDevice device, int id, byte[] data) {
+        boolean result = false;
+
+        final IBluetoothHidDevice service = mService;
+        if (service != null) {
+            try {
+                result = service.sendReport(device, id, data);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+
+        return result;
+    }
+
+    /**
+     * Sends report to remote host as reply for GET_REPORT request from
+     * {@link BluetoothHidDeviceCallback#onGetReport(BluetoothDevice, byte, byte, int)}.
+     *
+     * @param type Report Type, as in request.
+     * @param id Report Id, as in request.
+     * @param data Report data, not including Report Id.
+     * @return true if the command is successfully sent; otherwise false.
+     */
+    public boolean replyReport(BluetoothDevice device, byte type, byte id, byte[] data) {
+        Log.v(TAG, "replyReport(): device=" + device + " type=" + type + " id=" + id);
+
+        boolean result = false;
+
+        final IBluetoothHidDevice service = mService;
+        if (service != null) {
+            try {
+                result = service.replyReport(device, type, id, data);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+
+        return result;
+    }
+
+    /**
+     * Sends error handshake message as reply for invalid SET_REPORT request
+     * from {@link BluetoothHidDeviceCallback#onSetReport(BluetoothDevice, byte, byte, byte[])}.
+     *
+     * @param error Error to be sent for SET_REPORT via HANDSHAKE.
+     * @return true if the command is successfully sent; otherwise false.
+     */
+    public boolean reportError(BluetoothDevice device, byte error) {
+        Log.v(TAG, "reportError(): device=" + device + " error=" + error);
+
+        boolean result = false;
+
+        final IBluetoothHidDevice service = mService;
+        if (service != null) {
+            try {
+                result = service.reportError(device, error);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+
+        return result;
+    }
+
+    /**
+     * Sends Virtual Cable Unplug to currently connected host.
+     *
+     * @return
+     */
+    public boolean unplug(BluetoothDevice device) {
+        Log.v(TAG, "unplug(): device=" + device);
+
+        boolean result = false;
+
+        final IBluetoothHidDevice service = mService;
+        if (service != null) {
+            try {
+                result = service.unplug(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+
+        return result;
+    }
+
+    /**
+     * Initiates connection to host which is currently paired with this device.
+     * If the application is not registered, #connect(BluetoothDevice) will fail.
+     * The connection state should be tracked by the application by handling callback from
+     * BluetoothHidDeviceCallback#onConnectionStateChanged. The connection state is not related
+     * to the return value of this method.
+     *
+     * @return true if the command is successfully sent; otherwise false.
+     */
+    public boolean connect(BluetoothDevice device) {
+        Log.v(TAG, "connect(): device=" + device);
+
+        boolean result = false;
+
+        final IBluetoothHidDevice service = mService;
+        if (service != null) {
+            try {
+                result = service.connect(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+
+        return result;
+    }
+
+    /**
+     * Disconnects from currently connected host.
+     * The connection state should be tracked by the application by handling callback from
+     * BluetoothHidDeviceCallback#onConnectionStateChanged. The connection state is not related
+     * to the return value of this method.
+     *
+     * @return true if the command is successfully sent; otherwise false.
+     */
+    public boolean disconnect(BluetoothDevice device) {
+        Log.v(TAG, "disconnect(): device=" + device);
+
+        boolean result = false;
+
+        final IBluetoothHidDevice service = mService;
+        if (service != null) {
+            try {
+                result = service.disconnect(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+
+        return result;
+    }
+}
diff --git a/core/java/android/bluetooth/BluetoothHidDeviceAppConfiguration.java b/core/java/android/bluetooth/BluetoothHidDeviceAppConfiguration.java
index 05ba64e..d1efa2d 100644
--- a/core/java/android/bluetooth/BluetoothHidDeviceAppConfiguration.java
+++ b/core/java/android/bluetooth/BluetoothHidDeviceAppConfiguration.java
@@ -21,7 +21,16 @@
 
 import java.util.Random;
 
-/** @hide */
+/**
+ * Represents the app configuration for a Bluetooth HID Device application.
+ *
+ * The app needs a BluetoothHidDeviceAppConfiguration token to unregister
+ * the Bluetooth HID Device service.
+ *
+ * {@see BluetoothHidDevice}
+ *
+ * {@hide}
+ */
 public final class BluetoothHidDeviceAppConfiguration implements Parcelable {
     private final long mHash;
 
@@ -49,19 +58,19 @@
     }
 
     public static final Parcelable.Creator<BluetoothHidDeviceAppConfiguration> CREATOR =
-        new Parcelable.Creator<BluetoothHidDeviceAppConfiguration>() {
+            new Parcelable.Creator<BluetoothHidDeviceAppConfiguration>() {
 
-        @Override
-        public BluetoothHidDeviceAppConfiguration createFromParcel(Parcel in) {
-            long hash = in.readLong();
-            return new BluetoothHidDeviceAppConfiguration(hash);
-        }
+                @Override
+                public BluetoothHidDeviceAppConfiguration createFromParcel(Parcel in) {
+                    long hash = in.readLong();
+                    return new BluetoothHidDeviceAppConfiguration(hash);
+                }
 
-        @Override
-        public BluetoothHidDeviceAppConfiguration[] newArray(int size) {
-            return new BluetoothHidDeviceAppConfiguration[size];
-        }
-    };
+                @Override
+                public BluetoothHidDeviceAppConfiguration[] newArray(int size) {
+                    return new BluetoothHidDeviceAppConfiguration[size];
+                }
+            };
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
diff --git a/core/java/android/bluetooth/BluetoothHidDeviceAppQosSettings.java b/core/java/android/bluetooth/BluetoothHidDeviceAppQosSettings.java
index 0d6530c..881ae98 100644
--- a/core/java/android/bluetooth/BluetoothHidDeviceAppQosSettings.java
+++ b/core/java/android/bluetooth/BluetoothHidDeviceAppQosSettings.java
@@ -19,27 +19,49 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import java.util.Random;
-
-/** @hide */
+/**
+ * Represents the Quality of Service (QoS) settings for a Bluetooth HID Device
+ * application.
+ *
+ * The BluetoothHidDevice framework will update the L2CAP QoS settings for the
+ * app during registration.
+ *
+ * {@see BluetoothHidDevice}
+ *
+ * {@hide}
+ */
 public final class BluetoothHidDeviceAppQosSettings implements Parcelable {
 
-    final public int serviceType;
-    final public int tokenRate;
-    final public int tokenBucketSize;
-    final public int peakBandwidth;
-    final public int latency;
-    final public int delayVariation;
+    public final int serviceType;
+    public final int tokenRate;
+    public final int tokenBucketSize;
+    public final int peakBandwidth;
+    public final int latency;
+    public final int delayVariation;
 
-    final static public int SERVICE_NO_TRAFFIC = 0x00;
-    final static public int SERVICE_BEST_EFFORT = 0x01;
-    final static public int SERVICE_GUARANTEED = 0x02;
+    public static final int SERVICE_NO_TRAFFIC = 0x00;
+    public static final int SERVICE_BEST_EFFORT = 0x01;
+    public static final int SERVICE_GUARANTEED = 0x02;
 
-    final static public int MAX = (int) 0xffffffff;
+    public static final int MAX = (int) 0xffffffff;
 
+    /**
+     * Create a BluetoothHidDeviceAppQosSettings object for the Bluetooth L2CAP channel.
+     * The QoS Settings is optional.
+     * Recommended to use BluetoothHidDeviceAppQosSettings.Builder.
+     * {@see <a href="https://www.bluetooth.com/specifications/profiles-overview">
+     *     https://www.bluetooth.com/specifications/profiles-overview
+     *     </a>
+     *     Bluetooth HID Specfication v1.1.1 Section 5.2 and Appendix D }
+     * @param serviceType L2CAP service type
+     * @param tokenRate L2CAP token rate
+     * @param tokenBucketSize L2CAP token bucket size
+     * @param peakBandwidth L2CAP peak bandwidth
+     * @param latency L2CAP latency
+     * @param delayVariation L2CAP delay variation
+     */
     public BluetoothHidDeviceAppQosSettings(int serviceType, int tokenRate, int tokenBucketSize,
-            int peakBandwidth,
-            int latency, int delayVariation) {
+            int peakBandwidth, int latency, int delayVariation) {
         this.serviceType = serviceType;
         this.tokenRate = tokenRate;
         this.tokenBucketSize = tokenBucketSize;
@@ -52,7 +74,12 @@
     public boolean equals(Object o) {
         if (o instanceof BluetoothHidDeviceAppQosSettings) {
             BluetoothHidDeviceAppQosSettings qos = (BluetoothHidDeviceAppQosSettings) o;
-            return false;
+            return this.serviceType == qos.serviceType
+                    && this.tokenRate == qos.tokenRate
+                    && this.tokenBucketSize == qos.tokenBucketSize
+                    && this.peakBandwidth == qos.peakBandwidth
+                    && this.latency == qos.latency
+                    && this.delayVariation == qos.delayVariation;
         }
         return false;
     }
@@ -63,21 +90,25 @@
     }
 
     public static final Parcelable.Creator<BluetoothHidDeviceAppQosSettings> CREATOR =
-        new Parcelable.Creator<BluetoothHidDeviceAppQosSettings>() {
+            new Parcelable.Creator<BluetoothHidDeviceAppQosSettings>() {
 
-        @Override
-        public BluetoothHidDeviceAppQosSettings createFromParcel(Parcel in) {
+                @Override
+                public BluetoothHidDeviceAppQosSettings createFromParcel(Parcel in) {
 
-            return new BluetoothHidDeviceAppQosSettings(in.readInt(), in.readInt(), in.readInt(),
-                    in.readInt(),
-                    in.readInt(), in.readInt());
-        }
+                    return new BluetoothHidDeviceAppQosSettings(
+                            in.readInt(),
+                            in.readInt(),
+                            in.readInt(),
+                            in.readInt(),
+                            in.readInt(),
+                            in.readInt());
+                }
 
-        @Override
-        public BluetoothHidDeviceAppQosSettings[] newArray(int size) {
-            return new BluetoothHidDeviceAppQosSettings[size];
-        }
-    };
+                @Override
+                public BluetoothHidDeviceAppQosSettings[] newArray(int size) {
+                    return new BluetoothHidDeviceAppQosSettings[size];
+                }
+            };
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
@@ -89,9 +120,91 @@
         out.writeInt(delayVariation);
     }
 
+    /** @return an int array representation of this instance */
     public int[] toArray() {
         return new int[] {
                 serviceType, tokenRate, tokenBucketSize, peakBandwidth, latency, delayVariation
         };
     }
+
+    /**
+     * A helper to build the BluetoothHidDeviceAppQosSettings object.
+     */
+    public static class Builder {
+        // Optional parameters - initialized to default values
+        private int mServiceType = SERVICE_BEST_EFFORT;
+        private int mTokenRate = 0;
+        private int mTokenBucketSize = 0;
+        private int mPeakBandwidth = 0;
+        private int mLatency = MAX;
+        private int mDelayVariation = MAX;
+
+        /**
+         * Set the service type.
+         * @param val service type. Should be one of {SERVICE_NO_TRAFFIC, SERVICE_BEST_EFFORT,
+         * SERVICE_GUARANTEED}, with SERVICE_BEST_EFFORT being the default one.
+         * @return BluetoothHidDeviceAppQosSettings Builder with specified service type.
+         */
+        public Builder serviceType(int val) {
+            mServiceType = val;
+            return this;
+        }
+        /**
+         * Set the token rate.
+         * @param val token rate
+         * @return BluetoothHidDeviceAppQosSettings Builder with specified token rate.
+         */
+        public Builder tokenRate(int val) {
+            mTokenRate = val;
+            return this;
+        }
+
+        /**
+         * Set the bucket size.
+         * @param val bucket size
+         * @return BluetoothHidDeviceAppQosSettings Builder with specified bucket size.
+         */
+        public Builder tokenBucketSize(int val) {
+            mTokenBucketSize = val;
+            return this;
+        }
+
+        /**
+         * Set the peak bandwidth.
+         * @param val peak bandwidth
+         * @return BluetoothHidDeviceAppQosSettings Builder with specified peak bandwidth.
+         */
+        public Builder peakBandwidth(int val) {
+            mPeakBandwidth = val;
+            return this;
+        }
+        /**
+         * Set the latency.
+         * @param val latency
+         * @return BluetoothHidDeviceAppQosSettings Builder with specified latency.
+         */
+        public Builder latency(int val) {
+            mLatency = val;
+            return this;
+        }
+
+        /**
+         * Set the delay variation.
+         * @param val delay variation
+         * @return BluetoothHidDeviceAppQosSettings Builder with specified delay variation.
+         */
+        public Builder delayVariation(int val) {
+            mDelayVariation = val;
+            return this;
+        }
+
+        /**
+         * Build the BluetoothHidDeviceAppQosSettings object.
+         * @return BluetoothHidDeviceAppQosSettings object with current settings.
+         */
+        public BluetoothHidDeviceAppQosSettings build() {
+            return new BluetoothHidDeviceAppQosSettings(mServiceType, mTokenRate, mTokenBucketSize,
+                    mPeakBandwidth, mLatency, mDelayVariation);
+        }
+    }
 }
diff --git a/core/java/android/bluetooth/BluetoothHidDeviceAppSdpSettings.java b/core/java/android/bluetooth/BluetoothHidDeviceAppSdpSettings.java
index f9a2245..4669637 100644
--- a/core/java/android/bluetooth/BluetoothHidDeviceAppSdpSettings.java
+++ b/core/java/android/bluetooth/BluetoothHidDeviceAppSdpSettings.java
@@ -19,17 +19,40 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import java.util.Random;
+import java.util.Arrays;
 
-/** @hide */
+/**
+ * Represents the Service Discovery Protocol (SDP) settings for a Bluetooth
+ * HID Device application.
+ *
+ * The BluetoothHidDevice framework adds the SDP record during app
+ * registration, so that the Android device can be discovered as a Bluetooth
+ * HID Device.
+ *
+ * {@see BluetoothHidDevice}
+ *
+ * {@hide}
+ */
 public final class BluetoothHidDeviceAppSdpSettings implements Parcelable {
 
-    final public String name;
-    final public String description;
-    final public String provider;
-    final public byte subclass;
-    final public byte[] descriptors;
+    public final String name;
+    public final String description;
+    public final String provider;
+    public final byte subclass;
+    public final byte[] descriptors;
 
+    /**
+     * Create a BluetoothHidDeviceAppSdpSettings object for the Bluetooth SDP record.
+     * @param name Name of this Bluetooth HID device. Maximum length is 50 bytes.
+     * @param description Description for this Bluetooth HID device. Maximum length is 50 bytes.
+     * @param provider Provider of this Bluetooth HID device. Maximum length is 50 bytes.
+     * @param subclass Subclass of this Bluetooth HID device.
+     * See <a href="www.usb.org/developers/hidpage/HID1_11.pdf">
+     *     www.usb.org/developers/hidpage/HID1_11.pdf Section 4.2</a>
+     * @param descriptors Descriptors of this Bluetooth HID device.
+     * See <a href="www.usb.org/developers/hidpage/HID1_11.pdf">
+     *     www.usb.org/developers/hidpage/HID1_11.pdf Chapter 6</a> Maximum length is 2048 bytes.
+     */
     public BluetoothHidDeviceAppSdpSettings(String name, String description, String provider,
             byte subclass, byte[] descriptors) {
         this.name = name;
@@ -43,7 +66,11 @@
     public boolean equals(Object o) {
         if (o instanceof BluetoothHidDeviceAppSdpSettings) {
             BluetoothHidDeviceAppSdpSettings sdp = (BluetoothHidDeviceAppSdpSettings) o;
-            return false;
+            return this.name.equals(sdp.name)
+                    && this.description.equals(sdp.description)
+                    && this.provider.equals(sdp.provider)
+                    && this.subclass == sdp.subclass
+                    && Arrays.equals(this.descriptors, sdp.descriptors);
         }
         return false;
     }
@@ -54,20 +81,24 @@
     }
 
     public static final Parcelable.Creator<BluetoothHidDeviceAppSdpSettings> CREATOR =
-        new Parcelable.Creator<BluetoothHidDeviceAppSdpSettings>() {
+            new Parcelable.Creator<BluetoothHidDeviceAppSdpSettings>() {
 
-        @Override
-        public BluetoothHidDeviceAppSdpSettings createFromParcel(Parcel in) {
+                @Override
+                public BluetoothHidDeviceAppSdpSettings createFromParcel(Parcel in) {
 
-            return new BluetoothHidDeviceAppSdpSettings(in.readString(), in.readString(),
-                    in.readString(), in.readByte(), in.createByteArray());
-        }
+                    return new BluetoothHidDeviceAppSdpSettings(
+                            in.readString(),
+                            in.readString(),
+                            in.readString(),
+                            in.readByte(),
+                            in.createByteArray());
+                }
 
-        @Override
-        public BluetoothHidDeviceAppSdpSettings[] newArray(int size) {
-            return new BluetoothHidDeviceAppSdpSettings[size];
-        }
-    };
+                @Override
+                public BluetoothHidDeviceAppSdpSettings[] newArray(int size) {
+                    return new BluetoothHidDeviceAppSdpSettings[size];
+                }
+            };
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
diff --git a/core/java/android/bluetooth/BluetoothHidDeviceCallback.java b/core/java/android/bluetooth/BluetoothHidDeviceCallback.java
index f519776..5ccda0d 100644
--- a/core/java/android/bluetooth/BluetoothHidDeviceCallback.java
+++ b/core/java/android/bluetooth/BluetoothHidDeviceCallback.java
@@ -18,31 +18,37 @@
 
 import android.util.Log;
 
-/** @hide */
+/**
+ * The template class that applications use to call callback functions on
+ * events from the HID host. Callback functions are wrapped in this class and
+ * registered to the Android system during app registration.
+ *
+ * {@see BluetoothHidDevice}
+ *
+ * {@hide}
+ */
 public abstract class BluetoothHidDeviceCallback {
 
-    private static final String TAG = BluetoothHidDeviceCallback.class.getSimpleName();
+    private static final String TAG = "BluetoothHidDevCallback";
 
     /**
      * Callback called when application registration state changes. Usually it's
      * called due to either
-     * {@link BluetoothHidDevice#registerApp(String, String, String, byte, byte[],
-     * BluetoothHidDeviceCallback)}
+     * {@link BluetoothHidDevice#registerApp
+     * (String, String, String, byte, byte[], BluetoothHidDeviceCallback)}
      * or
      * {@link BluetoothHidDevice#unregisterApp(BluetoothHidDeviceAppConfiguration)}
      * , but can be also unsolicited in case e.g. Bluetooth was turned off in
      * which case application is unregistered automatically.
      *
-     * @param pluggedDevice {@link BluetoothDevice} object which represents host
-     *            that currently has Virtual Cable established with device. Only
-     *            valid when application is registered, can be <code>null</code>
-     *            .
-     * @param config {@link BluetoothHidDeviceAppConfiguration} object which
-     *            represents token required to unregister application using
-     *            {@link BluetoothHidDevice#unregisterApp(BluetoothHidDeviceAppConfiguration)}
-     *            .
-     * @param registered <code>true</code> if application is registered,
-     *            <code>false</code> otherwise.
+     * @param pluggedDevice {@link BluetoothDevice} object which represents host that currently has
+     * Virtual Cable established with device. Only valid when application is registered, can be
+     * <code>null</code>.
+     * @param config {@link BluetoothHidDeviceAppConfiguration} object which represents token
+     * required to unregister application using
+     * {@link BluetoothHidDevice#unregisterApp(BluetoothHidDeviceAppConfiguration)}.
+     * @param registered <code>true</code> if application is registered, <code>false</code>
+     * otherwise.
      */
     public void onAppStatusChanged(BluetoothDevice pluggedDevice,
             BluetoothHidDeviceAppConfiguration config, boolean registered) {
@@ -55,8 +61,8 @@
      * Application can assume than Virtual Cable is established when called with
      * {@link BluetoothProfile#STATE_CONNECTED} <code>state</code>.
      *
-     * @param device {@link BluetoothDevice} object representing host device
-     *            which connection state was changed.
+     * @param device {@link BluetoothDevice} object representing host device which connection state
+     * was changed.
      * @param state Connection state as defined in {@link BluetoothProfile}.
      */
     public void onConnectionStateChanged(BluetoothDevice device, int state) {
@@ -69,10 +75,9 @@
      * {@link BluetoothHidDevice#replyReport(BluetoothDevice, byte, byte, byte[])}.
      *
      * @param type Requested Report Type.
-     * @param id Requested Report Id, can be 0 if no Report Id are defined in
-     *            descriptor.
-     * @param bufferSize Requested buffer size, application shall respond with
-     *            at least given number of bytes.
+     * @param id Requested Report Id, can be 0 if no Report Id are defined in descriptor.
+     * @param bufferSize Requested buffer size, application shall respond with at least given number
+     * of bytes.
      */
     public void onGetReport(BluetoothDevice device, byte type, byte id, int bufferSize) {
         Log.d(TAG, "onGetReport: device=" + device + " type=" + type + " id=" + id + " bufferSize="
@@ -82,7 +87,7 @@
     /**
      * Callback called when SET_REPORT is received from remote host. In case
      * received data are invalid, application shall respond with
-     * {@link BluetoothHidDevice#reportError(BluetoothDevice)}.
+     * {@link BluetoothHidDevice#reportError(BluetoothDevice, byte)}.
      *
      * @param type Report Type.
      * @param id Report Id.
diff --git a/core/java/android/bluetooth/BluetoothHidHost.java b/core/java/android/bluetooth/BluetoothHidHost.java
new file mode 100644
index 0000000..8ad0f9d
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothHidHost.java
@@ -0,0 +1,742 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * This class provides the public APIs to control the Bluetooth Input
+ * Device Profile.
+ *
+ * <p>BluetoothHidHost is a proxy object for controlling the Bluetooth
+ * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
+ * the BluetoothHidHost proxy object.
+ *
+ * <p>Each method is protected with its appropriate permission.
+ *
+ * @hide
+ */
+public final class BluetoothHidHost implements BluetoothProfile {
+    private static final String TAG = "BluetoothHidHost";
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false;
+
+    /**
+     * Intent used to broadcast the change in connection state of the Input
+     * Device profile.
+     *
+     * <p>This intent will have 3 extras:
+     * <ul>
+     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * </ul>
+     *
+     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
+     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+     * receive.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_CONNECTION_STATE_CHANGED =
+            "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
+
+    /**
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PROTOCOL_MODE_CHANGED =
+            "android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED";
+
+    /**
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_HANDSHAKE =
+            "android.bluetooth.input.profile.action.HANDSHAKE";
+
+    /**
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_REPORT =
+            "android.bluetooth.input.profile.action.REPORT";
+
+    /**
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_VIRTUAL_UNPLUG_STATUS =
+            "android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS";
+
+    /**
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_IDLE_TIME_CHANGED =
+            "android.bluetooth.input.profile.action.IDLE_TIME_CHANGED";
+
+    /**
+     * Return codes for the connect and disconnect Bluez / Dbus calls.
+     *
+     * @hide
+     */
+    public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000;
+
+    /**
+     * @hide
+     */
+    public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001;
+
+    /**
+     * @hide
+     */
+    public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002;
+
+    /**
+     * @hide
+     */
+    public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003;
+
+    /**
+     * @hide
+     */
+    public static final int INPUT_OPERATION_SUCCESS = 5004;
+
+    /**
+     * @hide
+     */
+    public static final int PROTOCOL_REPORT_MODE = 0;
+
+    /**
+     * @hide
+     */
+    public static final int PROTOCOL_BOOT_MODE = 1;
+
+    /**
+     * @hide
+     */
+    public static final int PROTOCOL_UNSUPPORTED_MODE = 255;
+
+    /*  int reportType, int reportType, int bufferSize */
+    /**
+     * @hide
+     */
+    public static final byte REPORT_TYPE_INPUT = 1;
+
+    /**
+     * @hide
+     */
+    public static final byte REPORT_TYPE_OUTPUT = 2;
+
+    /**
+     * @hide
+     */
+    public static final byte REPORT_TYPE_FEATURE = 3;
+
+    /**
+     * @hide
+     */
+    public static final int VIRTUAL_UNPLUG_STATUS_SUCCESS = 0;
+
+    /**
+     * @hide
+     */
+    public static final int VIRTUAL_UNPLUG_STATUS_FAIL = 1;
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_PROTOCOL_MODE =
+            "android.bluetooth.BluetoothHidHost.extra.PROTOCOL_MODE";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_REPORT_TYPE =
+            "android.bluetooth.BluetoothHidHost.extra.REPORT_TYPE";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_REPORT_ID =
+            "android.bluetooth.BluetoothHidHost.extra.REPORT_ID";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_REPORT_BUFFER_SIZE =
+            "android.bluetooth.BluetoothHidHost.extra.REPORT_BUFFER_SIZE";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_REPORT = "android.bluetooth.BluetoothHidHost.extra.REPORT";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_STATUS = "android.bluetooth.BluetoothHidHost.extra.STATUS";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_VIRTUAL_UNPLUG_STATUS =
+            "android.bluetooth.BluetoothHidHost.extra.VIRTUAL_UNPLUG_STATUS";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_IDLE_TIME =
+            "android.bluetooth.BluetoothHidHost.extra.IDLE_TIME";
+
+    private Context mContext;
+    private ServiceListener mServiceListener;
+    private BluetoothAdapter mAdapter;
+    private volatile IBluetoothHidHost mService;
+
+    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+            new IBluetoothStateChangeCallback.Stub() {
+                public void onBluetoothStateChange(boolean up) {
+                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
+                    if (!up) {
+                        if (VDBG) Log.d(TAG, "Unbinding service...");
+                        synchronized (mConnection) {
+                            try {
+                                mService = null;
+                                mContext.unbindService(mConnection);
+                            } catch (Exception re) {
+                                Log.e(TAG, "", re);
+                            }
+                        }
+                    } else {
+                        synchronized (mConnection) {
+                            try {
+                                if (mService == null) {
+                                    if (VDBG) Log.d(TAG, "Binding service...");
+                                    doBind();
+                                }
+                            } catch (Exception re) {
+                                Log.e(TAG, "", re);
+                            }
+                        }
+                    }
+                }
+            };
+
+    /**
+     * Create a BluetoothHidHost proxy object for interacting with the local
+     * Bluetooth Service which handles the InputDevice profile
+     */
+    /*package*/ BluetoothHidHost(Context context, ServiceListener l) {
+        mContext = context;
+        mServiceListener = l;
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (RemoteException e) {
+                Log.e(TAG, "", e);
+            }
+        }
+
+        doBind();
+    }
+
+    boolean doBind() {
+        Intent intent = new Intent(IBluetoothHidHost.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
+            Log.e(TAG, "Could not bind to Bluetooth HID Service with " + intent);
+            return false;
+        }
+        return true;
+    }
+
+    /*package*/ void close() {
+        if (VDBG) log("close()");
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (Exception e) {
+                Log.e(TAG, "", e);
+            }
+        }
+
+        synchronized (mConnection) {
+            if (mService != null) {
+                try {
+                    mService = null;
+                    mContext.unbindService(mConnection);
+                } catch (Exception re) {
+                    Log.e(TAG, "", re);
+                }
+            }
+        }
+        mServiceListener = null;
+    }
+
+    /**
+     * Initiate connection to a profile of the remote bluetooth device.
+     *
+     * <p> The system supports connection to multiple input devices.
+     *
+     * <p> This API returns false in scenarios like the profile on the
+     * device is already connected or Bluetooth is not turned on.
+     * When this API returns true, it is guaranteed that
+     * connection state intent for the profile will be broadcasted with
+     * the state. Users can get the connection state of the profile
+     * from this intent.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error, true otherwise
+     * @hide
+     */
+    public boolean connect(BluetoothDevice device) {
+        if (DBG) log("connect(" + device + ")");
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return service.connect(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Initiate disconnection from a profile
+     *
+     * <p> This API will return false in scenarios like the profile on the
+     * Bluetooth device is not in connected state etc. When this API returns,
+     * true, it is guaranteed that the connection state change
+     * intent will be broadcasted with the state. Users can get the
+     * disconnection state of the profile from this intent.
+     *
+     * <p> If the disconnection is initiated by a remote device, the state
+     * will transition from {@link #STATE_CONNECTED} to
+     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
+     * host (local) device the state will transition from
+     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
+     * state {@link #STATE_DISCONNECTED}. The transition to
+     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
+     * two scenarios.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error, true otherwise
+     * @hide
+     */
+    public boolean disconnect(BluetoothDevice device) {
+        if (DBG) log("disconnect(" + device + ")");
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return service.disconnect(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<BluetoothDevice> getConnectedDevices() {
+        if (VDBG) log("getConnectedDevices()");
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled()) {
+            try {
+                return service.getConnectedDevices();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return new ArrayList<BluetoothDevice>();
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return new ArrayList<BluetoothDevice>();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+        if (VDBG) log("getDevicesMatchingStates()");
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled()) {
+            try {
+                return service.getDevicesMatchingConnectionStates(states);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return new ArrayList<BluetoothDevice>();
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return new ArrayList<BluetoothDevice>();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int getConnectionState(BluetoothDevice device) {
+        if (VDBG) log("getState(" + device + ")");
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return service.getConnectionState(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return BluetoothProfile.STATE_DISCONNECTED;
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return BluetoothProfile.STATE_DISCONNECTED;
+    }
+
+    /**
+     * Set priority of the profile
+     *
+     * <p> The device should already be paired.
+     * Priority can be one of {@link #PRIORITY_ON} or
+     * {@link #PRIORITY_OFF},
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Paired bluetooth device
+     * @param priority
+     * @return true if priority is set, false on error
+     * @hide
+     */
+    public boolean setPriority(BluetoothDevice device, int priority) {
+        if (DBG) log("setPriority(" + device + ", " + priority + ")");
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            if (priority != BluetoothProfile.PRIORITY_OFF
+                    && priority != BluetoothProfile.PRIORITY_ON) {
+                return false;
+            }
+            try {
+                return service.setPriority(device, priority);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Get the priority of the profile.
+     *
+     * <p> The priority can be any of:
+     * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
+     * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     *
+     * @param device Bluetooth device
+     * @return priority of the device
+     * @hide
+     */
+    public int getPriority(BluetoothDevice device) {
+        if (VDBG) log("getPriority(" + device + ")");
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return service.getPriority(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return BluetoothProfile.PRIORITY_OFF;
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return BluetoothProfile.PRIORITY_OFF;
+    }
+
+    private final ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) Log.d(TAG, "Proxy object connected");
+            mService = IBluetoothHidHost.Stub.asInterface(Binder.allowBlocking(service));
+
+            if (mServiceListener != null) {
+                mServiceListener.onServiceConnected(BluetoothProfile.HID_HOST,
+                        BluetoothHidHost.this);
+            }
+        }
+
+        public void onServiceDisconnected(ComponentName className) {
+            if (DBG) Log.d(TAG, "Proxy object disconnected");
+            mService = null;
+            if (mServiceListener != null) {
+                mServiceListener.onServiceDisconnected(BluetoothProfile.HID_HOST);
+            }
+        }
+    };
+
+    private boolean isEnabled() {
+        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
+    }
+
+    private static boolean isValidDevice(BluetoothDevice device) {
+        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
+    }
+
+    /**
+     * Initiate virtual unplug for a HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error, true otherwise
+     * @hide
+     */
+    public boolean virtualUnplug(BluetoothDevice device) {
+        if (DBG) log("virtualUnplug(" + device + ")");
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return service.virtualUnplug(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+
+    }
+
+    /**
+     * Send Get_Protocol_Mode command to the connected HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error, true otherwise
+     * @hide
+     */
+    public boolean getProtocolMode(BluetoothDevice device) {
+        if (VDBG) log("getProtocolMode(" + device + ")");
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return service.getProtocolMode(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Send Set_Protocol_Mode command to the connected HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error, true otherwise
+     * @hide
+     */
+    public boolean setProtocolMode(BluetoothDevice device, int protocolMode) {
+        if (DBG) log("setProtocolMode(" + device + ")");
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return service.setProtocolMode(device, protocolMode);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Send Get_Report command to the connected HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @param reportType Report type
+     * @param reportId Report ID
+     * @param bufferSize Report receiving buffer size
+     * @return false on immediate error, true otherwise
+     * @hide
+     */
+    public boolean getReport(BluetoothDevice device, byte reportType, byte reportId,
+            int bufferSize) {
+        if (VDBG) {
+            log("getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId
+                    + "bufferSize=" + bufferSize);
+        }
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return service.getReport(device, reportType, reportId, bufferSize);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Send Set_Report command to the connected HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @param reportType Report type
+     * @param report Report receiving buffer size
+     * @return false on immediate error, true otherwise
+     * @hide
+     */
+    public boolean setReport(BluetoothDevice device, byte reportType, String report) {
+        if (VDBG) log("setReport(" + device + "), reportType=" + reportType + " report=" + report);
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return service.setReport(device, reportType, report);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Send Send_Data command to the connected HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @param report Report to send
+     * @return false on immediate error, true otherwise
+     * @hide
+     */
+    public boolean sendData(BluetoothDevice device, String report) {
+        if (DBG) log("sendData(" + device + "), report=" + report);
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return service.sendData(device, report);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Send Get_Idle_Time command to the connected HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error, true otherwise
+     * @hide
+     */
+    public boolean getIdleTime(BluetoothDevice device) {
+        if (DBG) log("getIdletime(" + device + ")");
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return service.getIdleTime(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Send Set_Idle_Time command to the connected HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @param idleTime Idle time to be set on HID Device
+     * @return false on immediate error, true otherwise
+     * @hide
+     */
+    public boolean setIdleTime(BluetoothDevice device, byte idleTime) {
+        if (DBG) log("setIdletime(" + device + "), idleTime=" + idleTime);
+        final IBluetoothHidHost service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return service.setIdleTime(device, idleTime);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    private static void log(String msg) {
+        Log.d(TAG, msg);
+    }
+}
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
deleted file mode 100644
index a5a0243..0000000
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ /dev/null
@@ -1,726 +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.
- */
-
-package android.bluetooth;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * This class provides the public APIs to control the Bluetooth Input
- * Device Profile.
- *
- *<p>BluetoothInputDevice is a proxy object for controlling the Bluetooth
- * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
- * the BluetoothInputDevice proxy object.
- *
- *<p>Each method is protected with its appropriate permission.
- *@hide
- */
-public final class BluetoothInputDevice implements BluetoothProfile {
-    private static final String TAG = "BluetoothInputDevice";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /**
-     * Intent used to broadcast the change in connection state of the Input
-     * Device profile.
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     *
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
-     * receive.
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-        "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
-
-    /**
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_PROTOCOL_MODE_CHANGED =
-        "android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED";
-
-    /**
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_HANDSHAKE =
-        "android.bluetooth.input.profile.action.HANDSHAKE";
-
-    /**
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_REPORT =
-        "android.bluetooth.input.profile.action.REPORT";
-
-    /**
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_VIRTUAL_UNPLUG_STATUS =
-        "android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS";
-
-    /**
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_IDLE_TIME_CHANGED =
-        "android.bluetooth.input.profile.action.IDLE_TIME_CHANGED";
-
-    /**
-     * Return codes for the connect and disconnect Bluez / Dbus calls.
-     * @hide
-     */
-    public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000;
-
-    /**
-     * @hide
-     */
-    public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001;
-
-    /**
-     * @hide
-     */
-    public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002;
-
-    /**
-     * @hide
-     */
-    public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003;
-
-    /**
-     * @hide
-     */
-    public static final int INPUT_OPERATION_SUCCESS = 5004;
-
-    /**
-     * @hide
-     */
-    public static final int PROTOCOL_REPORT_MODE = 0;
-
-    /**
-     * @hide
-     */
-    public static final int PROTOCOL_BOOT_MODE = 1;
-
-    /**
-     * @hide
-     */
-    public static final int PROTOCOL_UNSUPPORTED_MODE = 255;
-
-    /*  int reportType, int reportType, int bufferSize */
-    /**
-     * @hide
-     */
-    public static final byte REPORT_TYPE_INPUT = 1;
-
-    /**
-     * @hide
-     */
-    public static final byte REPORT_TYPE_OUTPUT = 2;
-
-    /**
-     * @hide
-     */
-    public static final byte REPORT_TYPE_FEATURE = 3;
-
-    /**
-     * @hide
-     */
-    public static final int VIRTUAL_UNPLUG_STATUS_SUCCESS = 0;
-
-    /**
-     * @hide
-     */
-    public static final int VIRTUAL_UNPLUG_STATUS_FAIL = 1;
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_PROTOCOL_MODE = "android.bluetooth.BluetoothInputDevice.extra.PROTOCOL_MODE";
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_REPORT_TYPE = "android.bluetooth.BluetoothInputDevice.extra.REPORT_TYPE";
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_REPORT_ID = "android.bluetooth.BluetoothInputDevice.extra.REPORT_ID";
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_REPORT_BUFFER_SIZE = "android.bluetooth.BluetoothInputDevice.extra.REPORT_BUFFER_SIZE";
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_REPORT = "android.bluetooth.BluetoothInputDevice.extra.REPORT";
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_STATUS = "android.bluetooth.BluetoothInputDevice.extra.STATUS";
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_VIRTUAL_UNPLUG_STATUS = "android.bluetooth.BluetoothInputDevice.extra.VIRTUAL_UNPLUG_STATUS";
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_IDLE_TIME = "android.bluetooth.BluetoothInputDevice.extra.IDLE_TIME";
-
-    private Context mContext;
-    private ServiceListener mServiceListener;
-    private BluetoothAdapter mAdapter;
-    private IBluetoothInputDevice mService;
-
-    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
-            new IBluetoothStateChangeCallback.Stub() {
-                public void onBluetoothStateChange(boolean up) {
-                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
-                    if (!up) {
-                        if (VDBG) Log.d(TAG,"Unbinding service...");
-                        synchronized (mConnection) {
-                            try {
-                                mService = null;
-                                mContext.unbindService(mConnection);
-                            } catch (Exception re) {
-                                Log.e(TAG,"",re);
-                            }
-                        }
-                    } else {
-                        synchronized (mConnection) {
-                            try {
-                                if (mService == null) {
-                                    if (VDBG) Log.d(TAG,"Binding service...");
-                                    doBind();
-                                }
-                            } catch (Exception re) {
-                                Log.e(TAG,"",re);
-                            }
-                        }
-                    }
-                }
-        };
-
-    /**
-     * Create a BluetoothInputDevice proxy object for interacting with the local
-     * Bluetooth Service which handles the InputDevice profile
-     *
-     */
-    /*package*/ BluetoothInputDevice(Context context, ServiceListener l) {
-        mContext = context;
-        mServiceListener = l;
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
-
-        IBluetoothManager mgr = mAdapter.getBluetoothManager();
-        if (mgr != null) {
-            try {
-                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
-            } catch (RemoteException e) {
-                Log.e(TAG,"",e);
-            }
-        }
-
-        doBind();
-    }
-
-    boolean doBind() {
-        Intent intent = new Intent(IBluetoothInputDevice.class.getName());
-        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
-        intent.setComponent(comp);
-        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                android.os.Process.myUserHandle())) {
-            Log.e(TAG, "Could not bind to Bluetooth HID Service with " + intent);
-            return false;
-        }
-        return true;
-    }
-
-    /*package*/ void close() {
-        if (VDBG) log("close()");
-        IBluetoothManager mgr = mAdapter.getBluetoothManager();
-        if (mgr != null) {
-            try {
-                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
-            } catch (Exception e) {
-                Log.e(TAG,"",e);
-            }
-        }
-
-        synchronized (mConnection) {
-            if (mService != null) {
-                try {
-                    mService = null;
-                    mContext.unbindService(mConnection);
-                } catch (Exception re) {
-                    Log.e(TAG,"",re);
-                }
-           }
-        }
-        mServiceListener = null;
-    }
-
-    /**
-     * Initiate connection to a profile of the remote bluetooth device.
-     *
-     * <p> The system supports connection to multiple input devices.
-     *
-     * <p> This API returns false in scenarios like the profile on the
-     * device is already connected or Bluetooth is not turned on.
-     * When this API returns true, it is guaranteed that
-     * connection state intent for the profile will be broadcasted with
-     * the state. Users can get the connection state of the profile
-     * from this intent.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
-     * @hide
-     */
-    public boolean connect(BluetoothDevice device) {
-        if (DBG) log("connect(" + device + ")");
-        if (mService != null && isEnabled() && isValidDevice(device)) {
-            try {
-                return mService.connect(device);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return false;
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return false;
-    }
-
-    /**
-     * Initiate disconnection from a profile
-     *
-     * <p> This API will return false in scenarios like the profile on the
-     * Bluetooth device is not in connected state etc. When this API returns,
-     * true, it is guaranteed that the connection state change
-     * intent will be broadcasted with the state. Users can get the
-     * disconnection state of the profile from this intent.
-     *
-     * <p> If the disconnection is initiated by a remote device, the state
-     * will transition from {@link #STATE_CONNECTED} to
-     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
-     * host (local) device the state will transition from
-     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
-     * state {@link #STATE_DISCONNECTED}. The transition to
-     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
-     * two scenarios.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
-     * @hide
-     */
-    public boolean disconnect(BluetoothDevice device) {
-        if (DBG) log("disconnect(" + device + ")");
-        if (mService != null && isEnabled() && isValidDevice(device)) {
-            try {
-                return mService.disconnect(device);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return false;
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return false;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public List<BluetoothDevice> getConnectedDevices() {
-        if (VDBG) log("getConnectedDevices()");
-        if (mService != null && isEnabled()) {
-            try {
-                return mService.getConnectedDevices();
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return new ArrayList<BluetoothDevice>();
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return new ArrayList<BluetoothDevice>();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        if (VDBG) log("getDevicesMatchingStates()");
-        if (mService != null && isEnabled()) {
-            try {
-                return mService.getDevicesMatchingConnectionStates(states);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return new ArrayList<BluetoothDevice>();
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return new ArrayList<BluetoothDevice>();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public int getConnectionState(BluetoothDevice device) {
-        if (VDBG) log("getState(" + device + ")");
-        if (mService != null && isEnabled() && isValidDevice(device)) {
-            try {
-                return mService.getConnectionState(device);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return BluetoothProfile.STATE_DISCONNECTED;
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return BluetoothProfile.STATE_DISCONNECTED;
-    }
-
-    /**
-     * Set priority of the profile
-     *
-     * <p> The device should already be paired.
-     *  Priority can be one of {@link #PRIORITY_ON} or
-     * {@link #PRIORITY_OFF},
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission.
-     *
-     * @param device Paired bluetooth device
-     * @param priority
-     * @return true if priority is set, false on error
-     * @hide
-     */
-    public boolean setPriority(BluetoothDevice device, int priority) {
-        if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        if (mService != null && isEnabled() && isValidDevice(device)) {
-            if (priority != BluetoothProfile.PRIORITY_OFF &&
-                priority != BluetoothProfile.PRIORITY_ON) {
-              return false;
-            }
-            try {
-                return mService.setPriority(device, priority);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return false;
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return false;
-    }
-
-    /**
-     * Get the priority of the profile.
-     *
-     * <p> The priority can be any of:
-     * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
-     * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
-     * @param device Bluetooth device
-     * @return priority of the device
-     * @hide
-     */
-    public int getPriority(BluetoothDevice device) {
-        if (VDBG) log("getPriority(" + device + ")");
-        if (mService != null && isEnabled() && isValidDevice(device)) {
-            try {
-                return mService.getPriority(device);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return BluetoothProfile.PRIORITY_OFF;
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return BluetoothProfile.PRIORITY_OFF;
-    }
-
-    private final ServiceConnection mConnection = new ServiceConnection() {
-        public void onServiceConnected(ComponentName className, IBinder service) {
-            if (DBG) Log.d(TAG, "Proxy object connected");
-            mService = IBluetoothInputDevice.Stub.asInterface(Binder.allowBlocking(service));
-
-            if (mServiceListener != null) {
-                mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, BluetoothInputDevice.this);
-            }
-        }
-        public void onServiceDisconnected(ComponentName className) {
-            if (DBG) Log.d(TAG, "Proxy object disconnected");
-            mService = null;
-            if (mServiceListener != null) {
-                mServiceListener.onServiceDisconnected(BluetoothProfile.INPUT_DEVICE);
-            }
-        }
-    };
-
-    private boolean isEnabled() {
-       if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
-       return false;
-    }
-
-    private boolean isValidDevice(BluetoothDevice device) {
-       if (device == null) return false;
-
-       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-       return false;
-    }
-
-
-    /**
-     * Initiate virtual unplug for a HID input device.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
-     * @hide
-     */
-    public boolean virtualUnplug(BluetoothDevice device) {
-        if (DBG) log("virtualUnplug(" + device + ")");
-        if (mService != null && isEnabled() && isValidDevice(device)) {
-            try {
-                return mService.virtualUnplug(device);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return false;
-            }
-        }
-
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return false;
-
-    }
-
-    /**
-    * Send Get_Protocol_Mode command to the connected HID input device.
-    *
-    * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
-    *
-    * @param device Remote Bluetooth Device
-    * @return false on immediate error,
-    *true otherwise
-    * @hide
-    */
-    public boolean getProtocolMode(BluetoothDevice device) {
-        if (VDBG) log("getProtocolMode(" + device + ")");
-        if (mService != null && isEnabled() && isValidDevice(device)) {
-            try {
-                return mService.getProtocolMode(device);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return false;
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-            return false;
-    }
-
-    /**
-     * Send Set_Protocol_Mode command to the connected HID input device.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
-     * @hide
-     */
-    public boolean setProtocolMode(BluetoothDevice device, int protocolMode) {
-        if (DBG) log("setProtocolMode(" + device + ")");
-        if (mService != null && isEnabled() && isValidDevice(device)) {
-            try {
-                return mService.setProtocolMode(device, protocolMode);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return false;
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return false;
-    }
-
-    /**
-     * Send Get_Report command to the connected HID input device.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
-     *
-     * @param device Remote Bluetooth Device
-     * @param reportType Report type
-     * @param reportId Report ID
-     * @param bufferSize Report receiving buffer size
-     * @return false on immediate error,
-     *               true otherwise
-     * @hide
-     */
-    public boolean getReport(BluetoothDevice device, byte reportType, byte reportId, int bufferSize) {
-        if (VDBG) log("getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId + "bufferSize=" + bufferSize);
-        if (mService != null && isEnabled() && isValidDevice(device)) {
-            try {
-                return mService.getReport(device, reportType, reportId, bufferSize);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return false;
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return false;
-    }
-
-    /**
-     * Send Set_Report command to the connected HID input device.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
-     *
-     * @param device Remote Bluetooth Device
-     * @param reportType Report type
-     * @param report Report receiving buffer size
-     * @return false on immediate error,
-     *               true otherwise
-     * @hide
-     */
-    public boolean setReport(BluetoothDevice device, byte reportType, String report) {
-        if (VDBG) log("setReport(" + device + "), reportType=" + reportType + " report=" + report);
-        if (mService != null && isEnabled() && isValidDevice(device)) {
-            try {
-                return mService.setReport(device, reportType, report);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return false;
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return false;
-    }
-
-    /**
-     * Send Send_Data command to the connected HID input device.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
-     *
-     * @param device Remote Bluetooth Device
-     * @param report Report to send
-     * @return false on immediate error,
-     *               true otherwise
-     * @hide
-     */
-    public boolean sendData(BluetoothDevice device, String report) {
-        if (DBG) log("sendData(" + device + "), report=" + report);
-        if (mService != null && isEnabled() && isValidDevice(device)) {
-            try {
-                return mService.sendData(device, report);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return false;
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return false;
-    }
-
-    /**
-     * Send Get_Idle_Time command to the connected HID input device.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
-     * @hide
-     */
-    public boolean getIdleTime(BluetoothDevice device) {
-        if (DBG) log("getIdletime(" + device + ")");
-        if (mService != null && isEnabled() && isValidDevice(device)) {
-            try {
-                return mService.getIdleTime(device);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return false;
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return false;
-    }
-
-    /**
-     * Send Set_Idle_Time command to the connected HID input device.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
-     *
-     * @param device Remote Bluetooth Device
-     * @param idleTime Idle time to be set on HID Device
-     * @return false on immediate error,
-     *               true otherwise
-     * @hide
-     */
-    public boolean setIdleTime(BluetoothDevice device, byte idleTime) {
-        if (DBG) log("setIdletime(" + device + "), idleTime=" + idleTime);
-        if (mService != null && isEnabled() && isValidDevice(device)) {
-            try {
-                return mService.setIdleTime(device, idleTime);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return false;
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return false;
-    }
-
-    private static void log(String msg) {
-      Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothInputHost.java b/core/java/android/bluetooth/BluetoothInputHost.java
deleted file mode 100644
index 68d105f..0000000
--- a/core/java/android/bluetooth/BluetoothInputHost.java
+++ /dev/null
@@ -1,558 +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.bluetooth;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @hide
- */
-public final class BluetoothInputHost implements BluetoothProfile {
-
-    private static final String TAG = BluetoothInputHost.class.getSimpleName();
-
-    /**
-     * Intent used to broadcast the change in connection state of the Input
-     * Host profile.
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     *
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
-     * receive.
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-        "android.bluetooth.inputhost.profile.action.CONNECTION_STATE_CHANGED";
-
-    /**
-     * Constants representing device subclass.
-     *
-     * @see #registerApp(String, String, String, byte, byte[],
-     *      BluetoothHidDeviceCallback)
-     */
-    public static final byte SUBCLASS1_NONE = (byte) 0x00;
-    public static final byte SUBCLASS1_KEYBOARD = (byte) 0x40;
-    public static final byte SUBCLASS1_MOUSE = (byte) 0x80;
-    public static final byte SUBCLASS1_COMBO = (byte) 0xC0;
-
-    public static final byte SUBCLASS2_UNCATEGORIZED = (byte) 0x00;
-    public static final byte SUBCLASS2_JOYSTICK = (byte) 0x01;
-    public static final byte SUBCLASS2_GAMEPAD = (byte) 0x02;
-    public static final byte SUBCLASS2_REMOTE_CONTROL = (byte) 0x03;
-    public static final byte SUBCLASS2_SENSING_DEVICE = (byte) 0x04;
-    public static final byte SUBCLASS2_DIGITIZER_TABLED = (byte) 0x05;
-    public static final byte SUBCLASS2_CARD_READER = (byte) 0x06;
-
-    /**
-     * Constants representing report types.
-     *
-     * @see BluetoothHidDeviceCallback#onGetReport(byte, byte, int)
-     * @see BluetoothHidDeviceCallback#onSetReport(byte, byte, byte[])
-     * @see BluetoothHidDeviceCallback#onIntrData(byte, byte[])
-     */
-    public static final byte REPORT_TYPE_INPUT = (byte) 1;
-    public static final byte REPORT_TYPE_OUTPUT = (byte) 2;
-    public static final byte REPORT_TYPE_FEATURE = (byte) 3;
-
-    /**
-     * Constants representing error response for Set Report.
-     *
-     * @see BluetoothHidDeviceCallback#onSetReport(byte, byte, byte[])
-     */
-    public static final byte ERROR_RSP_SUCCESS = (byte) 0;
-    public static final byte ERROR_RSP_NOT_READY = (byte) 1;
-    public static final byte ERROR_RSP_INVALID_RPT_ID = (byte) 2;
-    public static final byte ERROR_RSP_UNSUPPORTED_REQ = (byte) 3;
-    public static final byte ERROR_RSP_INVALID_PARAM = (byte) 4;
-    public static final byte ERROR_RSP_UNKNOWN = (byte) 14;
-
-    /**
-     * Constants representing protocol mode used set by host. Default is always
-     * {@link #PROTOCOL_REPORT_MODE} unless notified otherwise.
-     *
-     * @see BluetoothHidDeviceCallback#onSetProtocol(byte)
-     */
-    public static final byte PROTOCOL_BOOT_MODE = (byte) 0;
-    public static final byte PROTOCOL_REPORT_MODE = (byte) 1;
-
-    private Context mContext;
-
-    private ServiceListener mServiceListener;
-
-    private IBluetoothInputHost mService;
-
-    private BluetoothAdapter mAdapter;
-
-    private static class BluetoothHidDeviceCallbackWrapper extends IBluetoothHidDeviceCallback.Stub {
-
-        private BluetoothHidDeviceCallback mCallback;
-
-        public BluetoothHidDeviceCallbackWrapper(BluetoothHidDeviceCallback callback) {
-            mCallback = callback;
-        }
-
-        @Override
-        public void onAppStatusChanged(BluetoothDevice pluggedDevice,
-                BluetoothHidDeviceAppConfiguration config, boolean registered) {
-            mCallback.onAppStatusChanged(pluggedDevice, config, registered);
-        }
-
-        @Override
-        public void onConnectionStateChanged(BluetoothDevice device, int state) {
-            mCallback.onConnectionStateChanged(device, state);
-        }
-
-        @Override
-        public void onGetReport(BluetoothDevice device, byte type, byte id, int bufferSize) {
-            mCallback.onGetReport(device, type, id, bufferSize);
-        }
-
-        @Override
-        public void onSetReport(BluetoothDevice device, byte type, byte id, byte[] data) {
-            mCallback.onSetReport(device, type, id, data);
-        }
-
-        @Override
-        public void onSetProtocol(BluetoothDevice device, byte protocol) {
-            mCallback.onSetProtocol(device, protocol);
-        }
-
-        @Override
-        public void onIntrData(BluetoothDevice device, byte reportId, byte[] data) {
-            mCallback.onIntrData(device, reportId, data);
-        }
-
-        @Override
-        public void onVirtualCableUnplug(BluetoothDevice device) {
-            mCallback.onVirtualCableUnplug(device);
-        }
-    }
-
-    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
-        new IBluetoothStateChangeCallback.Stub() {
-
-        public void onBluetoothStateChange(boolean up) {
-            Log.d(TAG, "onBluetoothStateChange: up=" + up);
-            synchronized (mConnection) {
-                if (!up) {
-                    Log.d(TAG,"Unbinding service...");
-                    if (mService != null) {
-                        mService = null;
-                        try {
-                            mContext.unbindService(mConnection);
-                        } catch (IllegalArgumentException e) {
-                            Log.e(TAG,"onBluetoothStateChange: could not unbind service:", e);
-                        }
-                    }
-                } else {
-                    try {
-                        if (mService == null) {
-                            Log.d(TAG,"Binding HID Device service...");
-                            doBind();
-                        }
-                    } catch (IllegalStateException e) {
-                        Log.e(TAG,"onBluetoothStateChange: could not bind to HID Dev service: ", e);
-                    } catch (SecurityException e) {
-                        Log.e(TAG,"onBluetoothStateChange: could not bind to HID Dev service: ", e);
-                    }
-                }
-            }
-        }
-    };
-
-    private ServiceConnection mConnection = new ServiceConnection() {
-
-        public void onServiceConnected(ComponentName className, IBinder service) {
-            Log.d(TAG, "onServiceConnected()");
-
-            mService = IBluetoothInputHost.Stub.asInterface(service);
-
-            if (mServiceListener != null) {
-                mServiceListener.onServiceConnected(BluetoothProfile.INPUT_HOST,
-                    BluetoothInputHost.this);
-            }
-        }
-
-        public void onServiceDisconnected(ComponentName className) {
-            Log.d(TAG, "onServiceDisconnected()");
-
-            mService = null;
-
-            if (mServiceListener != null) {
-                mServiceListener.onServiceDisconnected(BluetoothProfile.INPUT_HOST);
-            }
-        }
-    };
-
-    BluetoothInputHost(Context context, ServiceListener listener) {
-        Log.v(TAG, "BluetoothInputHost");
-
-        mContext = context;
-        mServiceListener = listener;
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
-
-        IBluetoothManager mgr = mAdapter.getBluetoothManager();
-        if (mgr != null) {
-            try {
-                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
-            } catch (RemoteException e) {
-                e.printStackTrace();
-            }
-        }
-
-        doBind();
-    }
-
-    boolean doBind() {
-        Intent intent = new Intent(IBluetoothInputHost.class.getName());
-        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
-        intent.setComponent(comp);
-        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                android.os.Process.myUserHandle())) {
-            Log.e(TAG, "Could not bind to Bluetooth HID Device Service with " + intent);
-            return false;
-        }
-        Log.d(TAG, "Bound to HID Device Service");
-        return true;
-    }
-
-    void close() {
-        Log.v(TAG, "close()");
-
-        IBluetoothManager mgr = mAdapter.getBluetoothManager();
-        if (mgr != null) {
-            try {
-                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
-            } catch (RemoteException e) {
-                e.printStackTrace();
-            }
-        }
-
-        synchronized (mConnection) {
-            if (mService != null) {
-                mService = null;
-                try {
-                    mContext.unbindService(mConnection);
-                } catch (IllegalArgumentException e) {
-                    Log.e(TAG,"close: could not unbind HID Dev service: ", e);
-                }
-           }
-        }
-
-        mServiceListener = null;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public List<BluetoothDevice> getConnectedDevices() {
-        Log.v(TAG, "getConnectedDevices()");
-
-        if (mService != null) {
-            try {
-                return mService.getConnectedDevices();
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString());
-            }
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-
-        return new ArrayList<BluetoothDevice>();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        Log.v(TAG, "getDevicesMatchingConnectionStates(): states=" + Arrays.toString(states));
-
-        if (mService != null) {
-            try {
-                return mService.getDevicesMatchingConnectionStates(states);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString());
-            }
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-
-        return new ArrayList<BluetoothDevice>();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public int getConnectionState(BluetoothDevice device) {
-        Log.v(TAG, "getConnectionState(): device=" + device);
-
-        if (mService != null) {
-            try {
-                return mService.getConnectionState(device);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString());
-            }
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-
-        return STATE_DISCONNECTED;
-    }
-
-    /**
-     * Registers application to be used for HID device. Connections to HID
-     * Device are only possible when application is registered. Only one
-     * application can be registered at time. When no longer used, application
-     * should be unregistered using
-     * {@link #unregisterApp(BluetoothHidDeviceAppConfiguration)}.
-     *
-     * @param sdp {@link BluetoothHidDeviceAppSdpSettings} object of
-     *             HID Device SDP record.
-     * @param inQos {@link BluetoothHidDeviceAppQosSettings} object of
-     *             Incoming QoS Settings.
-     * @param outQos {@link BluetoothHidDeviceAppQosSettings} object of
-     *             Outgoing QoS Settings.
-     * @param callback {@link BluetoothHidDeviceCallback} object to which
-     *            callback messages will be sent.
-     * @return
-     */
-    public boolean registerApp(BluetoothHidDeviceAppSdpSettings sdp,
-            BluetoothHidDeviceAppQosSettings inQos, BluetoothHidDeviceAppQosSettings outQos,
-            BluetoothHidDeviceCallback callback) {
-        Log.v(TAG, "registerApp(): sdp=" + sdp + " inQos=" + inQos + " outQos=" + outQos
-                + " callback=" + callback);
-
-        boolean result = false;
-
-        if (sdp == null || callback == null) {
-            return false;
-        }
-
-        if (mService != null) {
-            try {
-                BluetoothHidDeviceAppConfiguration config =
-                    new BluetoothHidDeviceAppConfiguration();
-                BluetoothHidDeviceCallbackWrapper cbw =
-                    new BluetoothHidDeviceCallbackWrapper(callback);
-                result = mService.registerApp(config, sdp, inQos, outQos, cbw);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString());
-            }
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-
-        return result;
-    }
-
-    /**
-     * Unregisters application. Active connection will be disconnected and no
-     * new connections will be allowed until registered again using
-     * {@link #registerApp(String, String, String, byte, byte[], BluetoothHidDeviceCallback)}
-     *
-     * @param config {@link BluetoothHidDeviceAppConfiguration} object as
-     *            obtained from
-     *            {@link BluetoothHidDeviceCallback#onAppStatusChanged(BluetoothDevice,
-     *            BluetoothHidDeviceAppConfiguration, boolean)}
-     *
-     * @return
-     */
-    public boolean unregisterApp(BluetoothHidDeviceAppConfiguration config) {
-        Log.v(TAG, "unregisterApp()");
-
-        boolean result = false;
-
-        if (mService != null) {
-            try {
-                result = mService.unregisterApp(config);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString());
-            }
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-
-        return result;
-    }
-
-    /**
-     * Sends report to remote host using interrupt channel.
-     *
-     * @param id Report Id, as defined in descriptor. Can be 0 in case Report Id
-     *            are not defined in descriptor.
-     * @param data Report data, not including Report Id.
-     * @return
-     */
-    public boolean sendReport(BluetoothDevice device, int id, byte[] data) {
-        boolean result = false;
-
-        if (mService != null) {
-            try {
-                result = mService.sendReport(device, id, data);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString());
-            }
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-
-        return result;
-    }
-
-    /**
-     * Sends report to remote host as reply for GET_REPORT request from
-     * {@link BluetoothHidDeviceCallback#onGetReport(BluetoothDevice, byte, byte, int)}.
-     *
-     * @param type Report Type, as in request.
-     * @param id Report Id, as in request.
-     * @param data Report data, not including Report Id.
-     * @return
-     */
-    public boolean replyReport(BluetoothDevice device, byte type, byte id, byte[] data) {
-        Log.v(TAG, "replyReport(): device=" + device + " type=" + type + " id=" + id);
-
-        boolean result = false;
-
-        if (mService != null) {
-            try {
-                result = mService.replyReport(device, type, id, data);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString());
-            }
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-
-        return result;
-    }
-
-    /**
-     * Sends error handshake message as reply for invalid SET_REPORT request
-     * from {@link BluetoothHidDeviceCallback#onSetReport(BluetoothDevice, byte, byte, byte[])}.
-     *
-     * @param error Error to be sent for SET_REPORT via HANDSHAKE.
-     * @return
-     */
-    public boolean reportError(BluetoothDevice device, byte error) {
-        Log.v(TAG, "reportError(): device=" + device + " error=" + error);
-
-        boolean result = false;
-
-        if (mService != null) {
-            try {
-                result = mService.reportError(device, error);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString());
-            }
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-
-        return result;
-    }
-
-    /**
-     * Sends Virtual Cable Unplug to currently connected host.
-     *
-     * @return
-     */
-    public boolean unplug(BluetoothDevice device) {
-        Log.v(TAG, "unplug(): device=" + device);
-
-        boolean result = false;
-
-        if (mService != null) {
-            try {
-                result = mService.unplug(device);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString());
-            }
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-
-        return result;
-    }
-
-    /**
-     * Initiates connection to host which currently has Virtual Cable
-     * established with device.
-     *
-     * @return
-     */
-    public boolean connect(BluetoothDevice device) {
-        Log.v(TAG, "connect(): device=" + device);
-
-        boolean result = false;
-
-        if (mService != null) {
-            try {
-                result = mService.connect(device);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString());
-            }
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-
-        return result;
-    }
-
-    /**
-     * Disconnects from currently connected host.
-     *
-     * @return
-     */
-    public boolean disconnect(BluetoothDevice device) {
-        Log.v(TAG, "disconnect(): device=" + device);
-
-        boolean result = false;
-
-        if (mService != null) {
-            try {
-                result = mService.disconnect(device);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString());
-            }
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-
-        return result;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothInputStream.java b/core/java/android/bluetooth/BluetoothInputStream.java
index 03af953..8eb79b2 100644
--- a/core/java/android/bluetooth/BluetoothInputStream.java
+++ b/core/java/android/bluetooth/BluetoothInputStream.java
@@ -51,15 +51,14 @@
      * stream is detected or an exception is thrown.
      *
      * @return the byte read or -1 if the end of stream has been reached.
-     * @throws IOException
-     *             if the stream is closed or another IOException occurs.
+     * @throws IOException if the stream is closed or another IOException occurs.
      * @since Android 1.5
      */
     public int read() throws IOException {
-        byte b[] = new byte[1];
+        byte[] b = new byte[1];
         int ret = mSocket.read(b, 0, 1);
         if (ret == 1) {
-            return (int)b[0] & 0xff;
+            return (int) b[0] & 0xff;
         } else {
             return -1;
         }
@@ -69,21 +68,14 @@
      * Reads at most {@code length} bytes from this stream and stores them in
      * the byte array {@code b} starting at {@code offset}.
      *
-     * @param b
-     *            the byte array in which to store the bytes read.
-     * @param offset
-     *            the initial position in {@code buffer} to store the bytes
-     *            read from this stream.
-     * @param length
-     *            the maximum number of bytes to store in {@code b}.
-     * @return the number of bytes actually read or -1 if the end of the stream
-     *         has been reached.
-     * @throws IndexOutOfBoundsException
-     *             if {@code offset < 0} or {@code length < 0}, or if
-     *             {@code offset + length} is greater than the length of
-     *             {@code b}.
-     * @throws IOException
-     *             if the stream is closed or another IOException occurs.
+     * @param b the byte array in which to store the bytes read.
+     * @param offset the initial position in {@code buffer} to store the bytes read from this
+     * stream.
+     * @param length the maximum number of bytes to store in {@code b}.
+     * @return the number of bytes actually read or -1 if the end of the stream has been reached.
+     * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code length < 0}, or if {@code
+     * offset + length} is greater than the length of {@code b}.
+     * @throws IOException if the stream is closed or another IOException occurs.
      * @since Android 1.5
      */
     public int read(byte[] b, int offset, int length) throws IOException {
diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java
index bacce80..7e3bb05 100644
--- a/core/java/android/bluetooth/BluetoothManager.java
+++ b/core/java/android/bluetooth/BluetoothManager.java
@@ -86,17 +86,16 @@
      *
      * @param device Remote bluetooth device.
      * @param profile GATT or GATT_SERVER
-     * @return State of the profile connection. One of
-     *         {@link BluetoothProfile#STATE_CONNECTED}, {@link BluetoothProfile#STATE_CONNECTING},
-     *         {@link BluetoothProfile#STATE_DISCONNECTED},
-     *         {@link BluetoothProfile#STATE_DISCONNECTING}
+     * @return State of the profile connection. One of {@link BluetoothProfile#STATE_CONNECTED},
+     * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_DISCONNECTED},
+     * {@link BluetoothProfile#STATE_DISCONNECTING}
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public int getConnectionState(BluetoothDevice device, int profile) {
-        if (DBG) Log.d(TAG,"getConnectionState()");
+        if (DBG) Log.d(TAG, "getConnectionState()");
 
         List<BluetoothDevice> connectedDevices = getConnectedDevices(profile);
-        for(BluetoothDevice connectedDevice : connectedDevices) {
+        for (BluetoothDevice connectedDevice : connectedDevices) {
             if (device.equals(connectedDevice)) {
                 return BluetoothProfile.STATE_CONNECTED;
             }
@@ -120,7 +119,7 @@
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public List<BluetoothDevice> getConnectedDevices(int profile) {
-        if (DBG) Log.d(TAG,"getConnectedDevices");
+        if (DBG) Log.d(TAG, "getConnectedDevices");
         if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) {
             throw new IllegalArgumentException("Profile not supported: " + profile);
         }
@@ -133,16 +132,15 @@
             if (iGatt == null) return connectedDevices;
 
             connectedDevices = iGatt.getDevicesMatchingConnectionStates(
-                new int[] { BluetoothProfile.STATE_CONNECTED });
+                    new int[]{BluetoothProfile.STATE_CONNECTED});
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
         }
 
         return connectedDevices;
     }
 
     /**
-     *
      * Get a list of devices that match any of the given connection
      * states.
      *
@@ -155,15 +153,14 @@
      * to know the state of the local adapter.
      *
      * @param profile GATT or GATT_SERVER
-     * @param states Array of states. States can be one of
-     *        {@link BluetoothProfile#STATE_CONNECTED}, {@link BluetoothProfile#STATE_CONNECTING},
-     *        {@link BluetoothProfile#STATE_DISCONNECTED},
-     *        {@link BluetoothProfile#STATE_DISCONNECTING},
+     * @param states Array of states. States can be one of {@link BluetoothProfile#STATE_CONNECTED},
+     * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_DISCONNECTED},
+     * {@link BluetoothProfile#STATE_DISCONNECTING},
      * @return List of devices. The list will be empty on error.
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int profile, int[] states) {
-        if (DBG) Log.d(TAG,"getDevicesMatchingConnectionStates");
+        if (DBG) Log.d(TAG, "getDevicesMatchingConnectionStates");
 
         if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) {
             throw new IllegalArgumentException("Profile not supported: " + profile);
@@ -177,7 +174,7 @@
             if (iGatt == null) return devices;
             devices = iGatt.getDevicesMatchingConnectionStates(states);
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
         }
 
         return devices;
@@ -189,14 +186,15 @@
      * as the results of any other GATT server operations.
      * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer
      * to conduct GATT server operations.
+     *
      * @param context App context
      * @param callback GATT server callback handler that will receive asynchronous callbacks.
      * @return BluetoothGattServer instance
      */
     public BluetoothGattServer openGattServer(Context context,
-                                              BluetoothGattServerCallback callback) {
+            BluetoothGattServerCallback callback) {
 
-        return (openGattServer (context, callback, BluetoothDevice.TRANSPORT_AUTO));
+        return (openGattServer(context, callback, BluetoothDevice.TRANSPORT_AUTO));
     }
 
     /**
@@ -205,16 +203,17 @@
      * as the results of any other GATT server operations.
      * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer
      * to conduct GATT server operations.
+     *
      * @param context App context
      * @param callback GATT server callback handler that will receive asynchronous callbacks.
-     * @param transport preferred transport for GATT connections to remote dual-mode devices
-     *             {@link BluetoothDevice#TRANSPORT_AUTO} or
-     *             {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
+     * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
+     * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
+     * BluetoothDevice#TRANSPORT_LE}
      * @return BluetoothGattServer instance
      * @hide
      */
     public BluetoothGattServer openGattServer(Context context,
-                                              BluetoothGattServerCallback callback,int transport) {
+            BluetoothGattServerCallback callback, int transport) {
         if (context == null || callback == null) {
             throw new IllegalArgumentException("null parameter: " + context + " " + callback);
         }
@@ -229,11 +228,11 @@
                 Log.e(TAG, "Fail to get GATT Server connection");
                 return null;
             }
-            BluetoothGattServer mGattServer = new BluetoothGattServer(iGatt,transport);
+            BluetoothGattServer mGattServer = new BluetoothGattServer(iGatt, transport);
             Boolean regStatus = mGattServer.registerCallback(callback);
-            return regStatus? mGattServer : null;
+            return regStatus ? mGattServer : null;
         } catch (RemoteException e) {
-            Log.e(TAG,"",e);
+            Log.e(TAG, "", e);
             return null;
         }
     }
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
index 2e73051..5b55b23 100644
--- a/core/java/android/bluetooth/BluetoothMap.java
+++ b/core/java/android/bluetooth/BluetoothMap.java
@@ -16,19 +16,23 @@
 
 package android.bluetooth;
 
-import java.util.List;
-import java.util.ArrayList;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.os.*;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
 import android.util.Log;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * This class provides the APIs to control the Bluetooth MAP
  * Profile.
- *@hide
+ *
+ * @hide
  */
 public final class BluetoothMap implements BluetoothProfile {
 
@@ -37,49 +41,49 @@
     private static final boolean VDBG = false;
 
     public static final String ACTION_CONNECTION_STATE_CHANGED =
-        "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED";
+            "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED";
 
-    private IBluetoothMap mService;
+    private volatile IBluetoothMap mService;
     private final Context mContext;
     private ServiceListener mServiceListener;
     private BluetoothAdapter mAdapter;
 
     /** There was an error trying to obtain the state */
-    public static final int STATE_ERROR        = -1;
+    public static final int STATE_ERROR = -1;
 
     public static final int RESULT_FAILURE = 0;
     public static final int RESULT_SUCCESS = 1;
     /** Connection canceled before completion. */
     public static final int RESULT_CANCELED = 2;
 
-    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
             new IBluetoothStateChangeCallback.Stub() {
                 public void onBluetoothStateChange(boolean up) {
                     if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
                     if (!up) {
-                        if (VDBG) Log.d(TAG,"Unbinding service...");
+                        if (VDBG) Log.d(TAG, "Unbinding service...");
                         synchronized (mConnection) {
                             try {
                                 mService = null;
                                 mContext.unbindService(mConnection);
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     } else {
                         synchronized (mConnection) {
                             try {
                                 if (mService == null) {
-                                    if (VDBG) Log.d(TAG,"Binding service...");
+                                    if (VDBG) Log.d(TAG, "Binding service...");
                                     doBind();
                                 }
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     }
                 }
-        };
+            };
 
     /**
      * Create a BluetoothMap proxy object.
@@ -94,7 +98,7 @@
             try {
                 mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (RemoteException e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
         doBind();
@@ -132,7 +136,7 @@
             try {
                 mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (Exception e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -142,7 +146,7 @@
                     mService = null;
                     mContext.unbindService(mConnection);
                 } catch (Exception re) {
-                    Log.e(TAG,"",re);
+                    Log.e(TAG, "", re);
                 }
             }
         }
@@ -151,15 +155,19 @@
 
     /**
      * Get the current state of the BluetoothMap service.
-     * @return One of the STATE_ return codes, or STATE_ERROR if this proxy
-     *         object is currently not connected to the Map service.
+     *
+     * @return One of the STATE_ return codes, or STATE_ERROR if this proxy object is currently not
+     * connected to the Map service.
      */
     public int getState() {
         if (VDBG) log("getState()");
-        if (mService != null) {
+        final IBluetoothMap service = mService;
+        if (service != null) {
             try {
-                return mService.getState();
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.getState();
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -169,16 +177,19 @@
 
     /**
      * Get the currently connected remote Bluetooth device (PCE).
-     * @return The remote Bluetooth device, or null if not in connected or
-     *         connecting state, or if this proxy object is not connected to
-     *         the Map service.
+     *
+     * @return The remote Bluetooth device, or null if not in connected or connecting state, or if
+     * this proxy object is not connected to the Map service.
      */
     public BluetoothDevice getClient() {
         if (VDBG) log("getClient()");
-        if (mService != null) {
+        final IBluetoothMap service = mService;
+        if (service != null) {
             try {
-                return mService.getClient();
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.getClient();
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -193,10 +204,13 @@
      */
     public boolean isConnected(BluetoothDevice device) {
         if (VDBG) log("isConnected(" + device + ")");
-        if (mService != null) {
+        final IBluetoothMap service = mService;
+        if (service != null) {
             try {
-                return mService.isConnected(device);
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.isConnected(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -217,21 +231,20 @@
      * Initiate disconnect.
      *
      * @param device Remote Bluetooth Device
-     * @return false on error,
-     *               true otherwise
+     * @return false on error, true otherwise
      */
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) log("disconnect(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothMap service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.disconnect(device);
+                return service.disconnect(device);
             } catch (RemoteException e) {
-              Log.e(TAG, Log.getStackTraceString(new Throwable()));
-              return false;
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -240,18 +253,19 @@
      * This is a simple heuristic that tries to guess if a device with the
      * given class bits might support Map. It is not accurate for all
      * devices. It tries to err on the side of false positives.
+     *
      * @return True if this device might support Map.
      */
     public static boolean doesClassMatchSink(BluetoothClass btClass) {
         // TODO optimize the rule
         switch (btClass.getDeviceClass()) {
-        case BluetoothClass.Device.COMPUTER_DESKTOP:
-        case BluetoothClass.Device.COMPUTER_LAPTOP:
-        case BluetoothClass.Device.COMPUTER_SERVER:
-        case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
-            return true;
-        default:
-            return false;
+            case BluetoothClass.Device.COMPUTER_DESKTOP:
+            case BluetoothClass.Device.COMPUTER_LAPTOP:
+            case BluetoothClass.Device.COMPUTER_SERVER:
+            case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
+                return true;
+            default:
+                return false;
         }
     }
 
@@ -262,15 +276,16 @@
      */
     public List<BluetoothDevice> getConnectedDevices() {
         if (DBG) log("getConnectedDevices()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothMap service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getConnectedDevices();
+                return service.getConnectedDevices();
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
@@ -281,15 +296,16 @@
      */
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         if (DBG) log("getDevicesMatchingStates()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothMap service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getDevicesMatchingConnectionStates(states);
+                return service.getDevicesMatchingConnectionStates(states);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
@@ -300,16 +316,16 @@
      */
     public int getConnectionState(BluetoothDevice device) {
         if (DBG) log("getConnectionState(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothMap service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getConnectionState(device);
+                return service.getConnectionState(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.STATE_DISCONNECTED;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return BluetoothProfile.STATE_DISCONNECTED;
     }
 
@@ -317,7 +333,7 @@
      * Set priority of the profile
      *
      * <p> The device should already be paired.
-     *  Priority can be one of {@link #PRIORITY_ON} or
+     * Priority can be one of {@link #PRIORITY_ON} or
      * {@link #PRIORITY_OFF},
      *
      * @param device Paired bluetooth device
@@ -326,20 +342,20 @@
      */
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
-            if (priority != BluetoothProfile.PRIORITY_OFF &&
-                priority != BluetoothProfile.PRIORITY_ON) {
-              return false;
+        final IBluetoothMap service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            if (priority != BluetoothProfile.PRIORITY_OFF
+                    && priority != BluetoothProfile.PRIORITY_ON) {
+                return false;
             }
             try {
-                return mService.setPriority(device, priority);
+                return service.setPriority(device, priority);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -355,16 +371,16 @@
      */
     public int getPriority(BluetoothDevice device) {
         if (VDBG) log("getPriority(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothMap service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getPriority(device);
+                return service.getPriority(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return PRIORITY_OFF;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return PRIORITY_OFF;
     }
 
@@ -376,6 +392,7 @@
                 mServiceListener.onServiceConnected(BluetoothProfile.MAP, BluetoothMap.this);
             }
         }
+
         public void onServiceDisconnected(ComponentName className) {
             if (DBG) log("Proxy object disconnected");
             mService = null;
@@ -389,18 +406,14 @@
         Log.d(TAG, msg);
     }
 
-   private boolean isEnabled() {
+    private boolean isEnabled() {
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
         if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) return true;
         log("Bluetooth is Not enabled");
         return false;
     }
-    private boolean isValidDevice(BluetoothDevice device) {
-       if (device == null) return false;
-
-       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-       return false;
+    private static boolean isValidDevice(BluetoothDevice device) {
+        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
     }
 
-
 }
diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java
index ccab3cd..af3b662 100644
--- a/core/java/android/bluetooth/BluetoothMapClient.java
+++ b/core/java/android/bluetooth/BluetoothMapClient.java
@@ -59,7 +59,7 @@
     public static final String EXTRA_SENDER_CONTACT_NAME =
             "android.bluetooth.mapmce.profile.extra.SENDER_CONTACT_NAME";
 
-    private IBluetoothMapClient mService;
+    private volatile IBluetoothMapClient mService;
     private final Context mContext;
     private ServiceListener mServiceListener;
     private BluetoothAdapter mAdapter;
@@ -72,7 +72,7 @@
     /** Connection canceled before completion. */
     public static final int RESULT_CANCELED = 2;
 
-    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
             new IBluetoothStateChangeCallback.Stub() {
                 public void onBluetoothStateChange(boolean up) {
                     if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
@@ -176,9 +176,10 @@
      */
     public boolean isConnected(BluetoothDevice device) {
         if (VDBG) Log.d(TAG, "isConnected(" + device + ")");
-        if (mService != null) {
+        final IBluetoothMapClient service = mService;
+        if (service != null) {
             try {
-                return mService.isConnected(device);
+                return service.isConnected(device);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -195,9 +196,10 @@
      */
     public boolean connect(BluetoothDevice device) {
         if (DBG) Log.d(TAG, "connect(" + device + ")" + "for MAPS MCE");
-        if (mService != null) {
+        final IBluetoothMapClient service = mService;
+        if (service != null) {
             try {
-                return mService.connect(device);
+                return service.connect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -216,15 +218,15 @@
      */
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) Log.d(TAG, "disconnect(" + device + ")");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothMapClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.disconnect(device);
+                return service.disconnect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -236,15 +238,16 @@
     @Override
     public List<BluetoothDevice> getConnectedDevices() {
         if (DBG) Log.d(TAG, "getConnectedDevices()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothMapClient service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getConnectedDevices();
+                return service.getConnectedDevices();
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return new ArrayList<>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<>();
     }
 
@@ -256,15 +259,16 @@
     @Override
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         if (DBG) Log.d(TAG, "getDevicesMatchingStates()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothMapClient service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getDevicesMatchingConnectionStates(states);
+                return service.getDevicesMatchingConnectionStates(states);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return new ArrayList<>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<>();
     }
 
@@ -276,16 +280,16 @@
     @Override
     public int getConnectionState(BluetoothDevice device) {
         if (DBG) Log.d(TAG, "getConnectionState(" + device + ")");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothMapClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getConnectionState(device);
+                return service.getConnectionState(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.STATE_DISCONNECTED;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return BluetoothProfile.STATE_DISCONNECTED;
     }
 
@@ -300,20 +304,20 @@
      */
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) Log.d(TAG, "setPriority(" + device + ", " + priority + ")");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
-            if (priority != BluetoothProfile.PRIORITY_OFF &&
-                    priority != BluetoothProfile.PRIORITY_ON) {
+        final IBluetoothMapClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            if (priority != BluetoothProfile.PRIORITY_OFF
+                    && priority != BluetoothProfile.PRIORITY_ON) {
                 return false;
             }
             try {
-                return mService.setPriority(device, priority);
+                return service.setPriority(device, priority);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -329,16 +333,16 @@
      */
     public int getPriority(BluetoothDevice device) {
         if (VDBG) Log.d(TAG, "getPriority(" + device + ")");
-        if (mService != null && isEnabled() &&
-                isValidDevice(device)) {
+        final IBluetoothMapClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getPriority(device);
+                return service.getPriority(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return PRIORITY_OFF;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return PRIORITY_OFF;
     }
 
@@ -347,19 +351,20 @@
      *
      * Send an SMS message to either the contacts primary number or the telephone number specified.
      *
-     * @param device          Bluetooth device
-     * @param contacts        Uri[] of the contacts
-     * @param message         Message to be sent
-     * @param sentIntent      intent issued when message is sent
+     * @param device Bluetooth device
+     * @param contacts Uri[] of the contacts
+     * @param message Message to be sent
+     * @param sentIntent intent issued when message is sent
      * @param deliveredIntent intent issued when message is delivered
      * @return true if the message is enqueued, false on error
      */
     public boolean sendMessage(BluetoothDevice device, Uri[] contacts, String message,
             PendingIntent sentIntent, PendingIntent deliveredIntent) {
         if (DBG) Log.d(TAG, "sendMessage(" + device + ", " + contacts + ", " + message);
-        if (mService != null && isEnabled() && isValidDevice(device)) {
+        final IBluetoothMapClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.sendMessage(device, contacts, message, sentIntent, deliveredIntent);
+                return service.sendMessage(device, contacts, message, sentIntent, deliveredIntent);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return false;
@@ -376,9 +381,10 @@
      */
     public boolean getUnreadMessages(BluetoothDevice device) {
         if (DBG) Log.d(TAG, "getUnreadMessages(" + device + ")");
-        if (mService != null && isEnabled() && isValidDevice(device)) {
+        final IBluetoothMapClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getUnreadMessages(device);
+                return service.getUnreadMessages(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return false;
@@ -393,7 +399,7 @@
             mService = IBluetoothMapClient.Stub.asInterface(service);
             if (mServiceListener != null) {
                 mServiceListener.onServiceConnected(BluetoothProfile.MAP_CLIENT,
-                    BluetoothMapClient.this);
+                        BluetoothMapClient.this);
             }
         }
 
@@ -413,12 +419,8 @@
         return false;
     }
 
-    private boolean isValidDevice(BluetoothDevice device) {
-        if (device == null) return false;
-
-        if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-        return false;
+    private static boolean isValidDevice(BluetoothDevice device) {
+        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
     }
 
-
 }
diff --git a/core/java/android/bluetooth/BluetoothMasInstance.java b/core/java/android/bluetooth/BluetoothMasInstance.java
index 4459e2c..7a31328 100644
--- a/core/java/android/bluetooth/BluetoothMasInstance.java
+++ b/core/java/android/bluetooth/BluetoothMasInstance.java
@@ -36,7 +36,7 @@
     @Override
     public boolean equals(Object o) {
         if (o instanceof BluetoothMasInstance) {
-            return mId == ((BluetoothMasInstance)o).mId;
+            return mId == ((BluetoothMasInstance) o).mId;
         }
         return false;
     }
@@ -48,25 +48,28 @@
 
     @Override
     public String toString() {
-        return Integer.toString(mId) + ":" + mName + ":" + mChannel + ":" +
-                Integer.toHexString(mMsgTypes);
+        return Integer.toString(mId) + ":" + mName + ":" + mChannel + ":"
+                + Integer.toHexString(mMsgTypes);
     }
 
+    @Override
     public int describeContents() {
         return 0;
     }
 
     public static final Parcelable.Creator<BluetoothMasInstance> CREATOR =
             new Parcelable.Creator<BluetoothMasInstance>() {
-        public BluetoothMasInstance createFromParcel(Parcel in) {
-            return new BluetoothMasInstance(in.readInt(), in.readString(),
-                    in.readInt(), in.readInt());
-        }
-        public BluetoothMasInstance[] newArray(int size) {
-            return new BluetoothMasInstance[size];
-        }
-    };
+                public BluetoothMasInstance createFromParcel(Parcel in) {
+                    return new BluetoothMasInstance(in.readInt(), in.readString(),
+                            in.readInt(), in.readInt());
+                }
 
+                public BluetoothMasInstance[] newArray(int size) {
+                    return new BluetoothMasInstance[size];
+                }
+            };
+
+    @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mId);
         out.writeString(mName);
@@ -75,10 +78,10 @@
     }
 
     public static final class MessageType {
-        public static final int EMAIL    = 0x01;
-        public static final int SMS_GSM  = 0x02;
+        public static final int EMAIL = 0x01;
+        public static final int SMS_GSM = 0x02;
         public static final int SMS_CDMA = 0x04;
-        public static final int MMS      = 0x08;
+        public static final int MMS = 0x08;
     }
 
     public int getId() {
diff --git a/core/java/android/bluetooth/BluetoothOutputStream.java b/core/java/android/bluetooth/BluetoothOutputStream.java
index 117dd47..dfec4e1 100644
--- a/core/java/android/bluetooth/BluetoothOutputStream.java
+++ b/core/java/android/bluetooth/BluetoothOutputStream.java
@@ -44,15 +44,13 @@
      * Writes a single byte to this stream. Only the least significant byte of
      * the integer {@code oneByte} is written to the stream.
      *
-     * @param oneByte
-     *            the byte to be written.
-     * @throws IOException
-     *             if an error occurs while writing to this stream.
+     * @param oneByte the byte to be written.
+     * @throws IOException if an error occurs while writing to this stream.
      * @since Android 1.0
      */
     public void write(int oneByte) throws IOException {
-        byte b[] = new byte[1];
-        b[0] = (byte)oneByte;
+        byte[] b = new byte[1];
+        b[0] = (byte) oneByte;
         mSocket.write(b, 0, 1);
     }
 
@@ -60,19 +58,12 @@
      * Writes {@code count} bytes from the byte array {@code buffer} starting
      * at position {@code offset} to this stream.
      *
-     * @param b
-     *            the buffer to be written.
-     * @param offset
-     *            the start position in {@code buffer} from where to get bytes.
-     * @param count
-     *            the number of bytes from {@code buffer} to write to this
-     *            stream.
-     * @throws IOException
-     *             if an error occurs while writing to this stream.
-     * @throws IndexOutOfBoundsException
-     *             if {@code offset < 0} or {@code count < 0}, or if
-     *             {@code offset + count} is bigger than the length of
-     *             {@code buffer}.
+     * @param b the buffer to be written.
+     * @param offset the start position in {@code buffer} from where to get bytes.
+     * @param count the number of bytes from {@code buffer} to write to this stream.
+     * @throws IOException if an error occurs while writing to this stream.
+     * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code count < 0}, or if {@code
+     * offset + count} is bigger than the length of {@code buffer}.
      * @since Android 1.0
      */
     public void write(byte[] b, int offset, int count) throws IOException {
@@ -84,15 +75,16 @@
         }
         mSocket.write(b, offset, count);
     }
+
     /**
      * Wait until the data in sending queue is emptied. A polling version
      * for flush implementation. Use it to ensure the writing data afterwards will
      * be packed in the new RFCOMM frame.
-     * @throws IOException
-     *             if an i/o error occurs.
+     *
+     * @throws IOException if an i/o error occurs.
      * @since Android 4.2.3
      */
-    public void flush()  throws IOException {
+    public void flush() throws IOException {
         mSocket.flush();
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 2a026a9..866b063 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -34,12 +34,13 @@
  * This class provides the APIs to control the Bluetooth Pan
  * Profile.
  *
- *<p>BluetoothPan is a proxy object for controlling the Bluetooth
+ * <p>BluetoothPan is a proxy object for controlling the Bluetooth
  * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
  * the BluetoothPan proxy object.
  *
- *<p>Each method is protected with its appropriate permission.
- *@hide
+ * <p>Each method is protected with its appropriate permission.
+ *
+ * @hide
  */
 public final class BluetoothPan implements BluetoothProfile {
     private static final String TAG = "BluetoothPan";
@@ -52,11 +53,11 @@
      *
      * <p>This intent will have 4 extras:
      * <ul>
-     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     *   <li> {@link #EXTRA_LOCAL_ROLE} - Which local role the remote device is
-     *   bound to. </li>
+     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * <li> {@link #EXTRA_LOCAL_ROLE} - Which local role the remote device is
+     * bound to. </li>
      * </ul>
      *
      * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -70,7 +71,7 @@
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_CONNECTION_STATE_CHANGED =
-        "android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED";
+            "android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED";
 
     /**
      * Extra for {@link #ACTION_CONNECTION_STATE_CHANGED} intent
@@ -94,6 +95,7 @@
 
     /**
      * Return codes for the connect and disconnect Bluez / Dbus calls.
+     *
      * @hide
      */
     public static final int PAN_DISCONNECT_FAILED_NOT_CONNECTED = 1000;
@@ -121,12 +123,11 @@
     private Context mContext;
     private ServiceListener mServiceListener;
     private BluetoothAdapter mAdapter;
-    private IBluetoothPan mPanService;
+    private volatile IBluetoothPan mPanService;
 
     /**
      * Create a BluetoothPan proxy object for interacting with the local
      * Bluetooth Service which handles the Pan profile
-     *
      */
     /*package*/ BluetoothPan(Context context, ServiceListener l) {
         mContext = context;
@@ -135,7 +136,7 @@
         try {
             mAdapter.getBluetoothManager().registerStateChangeCallback(mStateChangeCallback);
         } catch (RemoteException re) {
-            Log.w(TAG,"Unable to register BluetoothStateChangeCallback",re);
+            Log.w(TAG, "Unable to register BluetoothStateChangeCallback", re);
         }
         if (VDBG) Log.d(TAG, "BluetoothPan() call bindService");
         doBind();
@@ -161,7 +162,7 @@
             try {
                 mgr.unregisterStateChangeCallback(mStateChangeCallback);
             } catch (RemoteException re) {
-                Log.w(TAG,"Unable to unregister BluetoothStateChangeCallback",re);
+                Log.w(TAG, "Unable to unregister BluetoothStateChangeCallback", re);
             }
         }
 
@@ -171,7 +172,7 @@
                     mPanService = null;
                     mContext.unbindService(mConnection);
                 } catch (Exception re) {
-                    Log.e(TAG,"",re);
+                    Log.e(TAG, "", re);
                 }
             }
         }
@@ -182,38 +183,41 @@
         close();
     }
 
-    final private IBluetoothStateChangeCallback mStateChangeCallback = new IBluetoothStateChangeCallback.Stub() {
+    private final IBluetoothStateChangeCallback mStateChangeCallback =
+            new IBluetoothStateChangeCallback.Stub() {
 
-        @Override
-        public void onBluetoothStateChange(boolean on) {
-            // Handle enable request to bind again.
-            Log.d(TAG, "onBluetoothStateChange on: " + on);
-            if (on) {
-                try {
-                    if (mPanService == null) {
-                        if (VDBG) Log.d(TAG, "onBluetoothStateChange calling doBind()");
-                        doBind();
-                    }
+                @Override
+                public void onBluetoothStateChange(boolean on) {
+                    // Handle enable request to bind again.
+                    Log.d(TAG, "onBluetoothStateChange on: " + on);
+                    if (on) {
+                        try {
+                            if (mPanService == null) {
+                                if (VDBG) Log.d(TAG, "onBluetoothStateChange calling doBind()");
+                                doBind();
+                            }
 
-                } catch (IllegalStateException e) {
-                    Log.e(TAG,"onBluetoothStateChange: could not bind to PAN service: ", e);
+                        } catch (IllegalStateException e) {
+                            Log.e(TAG, "onBluetoothStateChange: could not bind to PAN service: ",
+                                    e);
 
-                } catch (SecurityException e) {
-                    Log.e(TAG,"onBluetoothStateChange: could not bind to PAN service: ", e);
-                }
-            } else {
-                if (VDBG) Log.d(TAG,"Unbinding service...");
-                synchronized (mConnection) {
-                    try {
-                        mPanService = null;
-                        mContext.unbindService(mConnection);
-                    } catch (Exception re) {
-                        Log.e(TAG,"",re);
+                        } catch (SecurityException e) {
+                            Log.e(TAG, "onBluetoothStateChange: could not bind to PAN service: ",
+                                    e);
+                        }
+                    } else {
+                        if (VDBG) Log.d(TAG, "Unbinding service...");
+                        synchronized (mConnection) {
+                            try {
+                                mPanService = null;
+                                mContext.unbindService(mConnection);
+                            } catch (Exception re) {
+                                Log.e(TAG, "", re);
+                            }
+                        }
                     }
                 }
-            }
-        }
-    };
+            };
 
     /**
      * Initiate connection to a profile of the remote bluetooth device.
@@ -229,22 +233,21 @@
      * permission.
      *
      * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
+     * @return false on immediate error, true otherwise
      * @hide
      */
     public boolean connect(BluetoothDevice device) {
         if (DBG) log("connect(" + device + ")");
-        if (mPanService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothPan service = mPanService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mPanService.connect(device);
+                return service.connect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -270,83 +273,87 @@
      * permission.
      *
      * @param device Remote Bluetooth Device
-     * @return false on immediate error,
-     *               true otherwise
+     * @return false on immediate error, true otherwise
      * @hide
      */
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) log("disconnect(" + device + ")");
-        if (mPanService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothPan service = mPanService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mPanService.disconnect(device);
+                return service.disconnect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public List<BluetoothDevice> getConnectedDevices() {
         if (VDBG) log("getConnectedDevices()");
-        if (mPanService != null && isEnabled()) {
+        final IBluetoothPan service = mPanService;
+        if (service != null && isEnabled()) {
             try {
-                return mPanService.getConnectedDevices();
+                return service.getConnectedDevices();
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         if (VDBG) log("getDevicesMatchingStates()");
-        if (mPanService != null && isEnabled()) {
+        final IBluetoothPan service = mPanService;
+        if (service != null && isEnabled()) {
             try {
-                return mPanService.getDevicesMatchingConnectionStates(states);
+                return service.getDevicesMatchingConnectionStates(states);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public int getConnectionState(BluetoothDevice device) {
         if (VDBG) log("getState(" + device + ")");
-        if (mPanService != null && isEnabled()
-            && isValidDevice(device)) {
+        final IBluetoothPan service = mPanService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mPanService.getConnectionState(device);
+                return service.getConnectionState(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.STATE_DISCONNECTED;
             }
         }
-        if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return BluetoothProfile.STATE_DISCONNECTED;
     }
 
     public void setBluetoothTethering(boolean value) {
         if (DBG) log("setBluetoothTethering(" + value + ")");
-
-        if (mPanService != null && isEnabled()) {
+        final IBluetoothPan service = mPanService;
+        if (service != null && isEnabled()) {
             try {
-                mPanService.setBluetoothTethering(value);
+                service.setBluetoothTethering(value);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
             }
@@ -355,10 +362,10 @@
 
     public boolean isTetheringOn() {
         if (VDBG) log("isTetheringOn()");
-
-        if (mPanService != null && isEnabled()) {
+        final IBluetoothPan service = mPanService;
+        if (service != null && isEnabled()) {
             try {
-                return mPanService.isTetheringOn();
+                return service.isTetheringOn();
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
             }
@@ -370,12 +377,12 @@
         public void onServiceConnected(ComponentName className, IBinder service) {
             if (DBG) Log.d(TAG, "BluetoothPAN Proxy object connected");
             mPanService = IBluetoothPan.Stub.asInterface(Binder.allowBlocking(service));
-
             if (mServiceListener != null) {
                 mServiceListener.onServiceConnected(BluetoothProfile.PAN,
-                                                    BluetoothPan.this);
+                        BluetoothPan.this);
             }
         }
+
         public void onServiceDisconnected(ComponentName className) {
             if (DBG) Log.d(TAG, "BluetoothPAN Proxy object disconnected");
             mPanService = null;
@@ -386,18 +393,14 @@
     };
 
     private boolean isEnabled() {
-       if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
-       return false;
+        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
     }
 
-    private boolean isValidDevice(BluetoothDevice device) {
-       if (device == null) return false;
-
-       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-       return false;
+    private static boolean isValidDevice(BluetoothDevice device) {
+        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
     }
 
     private static void log(String msg) {
-      Log.d(TAG, msg);
+        Log.d(TAG, msg);
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index dc01fc7..a1a9347 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -16,12 +16,13 @@
 
 package android.bluetooth;
 
+import android.annotation.SdkConstant;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.os.RemoteException;
 import android.os.IBinder;
+import android.os.RemoteException;
 import android.util.Log;
 
 /**
@@ -53,34 +54,32 @@
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
 
-    /** int extra for PBAP_STATE_CHANGED_ACTION */
-    public static final String PBAP_STATE =
-        "android.bluetooth.pbap.intent.PBAP_STATE";
-    /** int extra for PBAP_STATE_CHANGED_ACTION */
-    public static final String PBAP_PREVIOUS_STATE =
-        "android.bluetooth.pbap.intent.PBAP_PREVIOUS_STATE";
-
-    /** Indicates the state of a pbap connection state has changed.
-     *  This intent will always contain PBAP_STATE, PBAP_PREVIOUS_STATE and
-     *  BluetoothIntent.ADDRESS extras.
+    /**
+     * Intent used to broadcast the change in connection state of the PBAP
+     * profile.
+     *
+     * <p>This intent will have 3 extras:
+     * <ul>
+     * <li> {@link BluetoothProfile#EXTRA_STATE} - The current state of the profile. </li>
+     * <li> {@link BluetoothProfile#EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * </ul>
+     * <p>{@link BluetoothProfile#EXTRA_STATE} or {@link BluetoothProfile#EXTRA_PREVIOUS_STATE}
+     *  can be any of {@link BluetoothProfile#STATE_DISCONNECTED},
+     *  {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED},
+     *  {@link BluetoothProfile#STATE_DISCONNECTING}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+     * receive.
      */
-    public static final String PBAP_STATE_CHANGED_ACTION =
-        "android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED";
+    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_CONNECTION_STATE_CHANGED =
+            "android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED";
 
-    private IBluetoothPbap mService;
+    private volatile IBluetoothPbap mService;
     private final Context mContext;
     private ServiceListener mServiceListener;
     private BluetoothAdapter mAdapter;
 
-    /** There was an error trying to obtain the state */
-    public static final int STATE_ERROR        = -1;
-    /** No client currently connected */
-    public static final int STATE_DISCONNECTED = 0;
-    /** Connection attempt in progress */
-    public static final int STATE_CONNECTING   = 1;
-    /** Client is currently connected */
-    public static final int STATE_CONNECTED    = 2;
-
     public static final int RESULT_FAILURE = 0;
     public static final int RESULT_SUCCESS = 1;
     /** Connection canceled before completion. */
@@ -109,34 +108,34 @@
         public void onServiceDisconnected();
     }
 
-    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
             new IBluetoothStateChangeCallback.Stub() {
                 public void onBluetoothStateChange(boolean up) {
                     if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
                     if (!up) {
-                        if (VDBG) Log.d(TAG,"Unbinding service...");
+                        if (VDBG) Log.d(TAG, "Unbinding service...");
                         synchronized (mConnection) {
                             try {
                                 mService = null;
                                 mContext.unbindService(mConnection);
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     } else {
                         synchronized (mConnection) {
                             try {
                                 if (mService == null) {
-                                    if (VDBG) Log.d(TAG,"Binding service...");
+                                    if (VDBG) Log.d(TAG, "Binding service...");
                                     doBind();
                                 }
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     }
                 }
-        };
+            };
 
     /**
      * Create a BluetoothPbap proxy object.
@@ -150,7 +149,7 @@
             try {
                 mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (RemoteException e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
         doBind();
@@ -188,7 +187,7 @@
             try {
                 mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (Exception e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -198,7 +197,7 @@
                     mService = null;
                     mContext.unbindService(mConnection);
                 } catch (Exception re) {
-                    Log.e(TAG,"",re);
+                    Log.e(TAG, "", re);
                 }
             }
         }
@@ -207,34 +206,41 @@
 
     /**
      * Get the current state of the BluetoothPbap service.
-     * @return One of the STATE_ return codes, or STATE_ERROR if this proxy
-     *         object is currently not connected to the Pbap service.
+     *
+     * @return One of the STATE_ return codes, or {@link BluetoothProfile#STATE_DISCONNECTED}
+     * if this proxy object is currently not connected to the Pbap service.
      */
     public int getState() {
         if (VDBG) log("getState()");
-        if (mService != null) {
+        final IBluetoothPbap service = mService;
+        if (service != null) {
             try {
-                return mService.getState();
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.getState();
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) log(Log.getStackTraceString(new Throwable()));
         }
-        return BluetoothPbap.STATE_ERROR;
+        return BluetoothProfile.STATE_DISCONNECTED;
     }
 
     /**
      * Get the currently connected remote Bluetooth device (PCE).
-     * @return The remote Bluetooth device, or null if not in connected or
-     *         connecting state, or if this proxy object is not connected to
-     *         the Pbap service.
+     *
+     * @return The remote Bluetooth device, or null if not in connected or connecting state, or if
+     * this proxy object is not connected to the Pbap service.
      */
     public BluetoothDevice getClient() {
         if (VDBG) log("getClient()");
-        if (mService != null) {
+        final IBluetoothPbap service = mService;
+        if (service != null) {
             try {
-                return mService.getClient();
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.getClient();
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -249,10 +255,13 @@
      */
     public boolean isConnected(BluetoothDevice device) {
         if (VDBG) log("isConnected(" + device + ")");
-        if (mService != null) {
+        final IBluetoothPbap service = mService;
+        if (service != null) {
             try {
-                return mService.isConnected(device);
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.isConnected(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -267,11 +276,14 @@
      */
     public boolean disconnect() {
         if (DBG) log("disconnect()");
-        if (mService != null) {
+        final IBluetoothPbap service = mService;
+        if (service != null) {
             try {
-                mService.disconnect();
+                service.disconnect();
                 return true;
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -284,18 +296,19 @@
      * This is a simple heuristic that tries to guess if a device with the
      * given class bits might support PBAP. It is not accurate for all
      * devices. It tries to err on the side of false positives.
+     *
      * @return True if this device might support PBAP.
      */
     public static boolean doesClassMatchSink(BluetoothClass btClass) {
         // TODO optimize the rule
         switch (btClass.getDeviceClass()) {
-        case BluetoothClass.Device.COMPUTER_DESKTOP:
-        case BluetoothClass.Device.COMPUTER_LAPTOP:
-        case BluetoothClass.Device.COMPUTER_SERVER:
-        case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
-            return true;
-        default:
-            return false;
+            case BluetoothClass.Device.COMPUTER_DESKTOP:
+            case BluetoothClass.Device.COMPUTER_LAPTOP:
+            case BluetoothClass.Device.COMPUTER_SERVER:
+            case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
+                return true;
+            default:
+                return false;
         }
     }
 
@@ -307,6 +320,7 @@
                 mServiceListener.onServiceConnected(BluetoothPbap.this);
             }
         }
+
         public void onServiceDisconnected(ComponentName className) {
             if (DBG) log("Proxy object disconnected");
             mService = null;
diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java
index 9f00e1a..01b3f6e 100644
--- a/core/java/android/bluetooth/BluetoothPbapClient.java
+++ b/core/java/android/bluetooth/BluetoothPbapClient.java
@@ -16,20 +16,22 @@
 
 package android.bluetooth;
 
-import java.util.List;
-import java.util.ArrayList;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.os.RemoteException;
 import android.os.Binder;
 import android.os.IBinder;
+import android.os.RemoteException;
 import android.util.Log;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * This class provides the APIs to control the Bluetooth PBAP Client Profile.
- *@hide
+ *
+ * @hide
  */
 public final class BluetoothPbapClient implements BluetoothProfile {
 
@@ -38,22 +40,22 @@
     private static final boolean VDBG = false;
 
     public static final String ACTION_CONNECTION_STATE_CHANGED =
-        "android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED";
+            "android.bluetooth.pbapclient.profile.action.CONNECTION_STATE_CHANGED";
 
-    private IBluetoothPbapClient mService;
+    private volatile IBluetoothPbapClient mService;
     private final Context mContext;
     private ServiceListener mServiceListener;
     private BluetoothAdapter mAdapter;
 
     /** There was an error trying to obtain the state */
-    public static final int STATE_ERROR        = -1;
+    public static final int STATE_ERROR = -1;
 
     public static final int RESULT_FAILURE = 0;
     public static final int RESULT_SUCCESS = 1;
     /** Connection canceled before completion. */
     public static final int RESULT_CANCELED = 2;
 
-    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
             new IBluetoothStateChangeCallback.Stub() {
                 public void onBluetoothStateChange(boolean up) {
                     if (DBG) {
@@ -61,14 +63,14 @@
                     }
                     if (!up) {
                         if (VDBG) {
-                            Log.d(TAG,"Unbinding service...");
+                            Log.d(TAG, "Unbinding service...");
                         }
                         synchronized (mConnection) {
                             try {
                                 mService = null;
                                 mContext.unbindService(mConnection);
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     } else {
@@ -76,17 +78,17 @@
                             try {
                                 if (mService == null) {
                                     if (VDBG) {
-                                        Log.d(TAG,"Binding service...");
+                                        Log.d(TAG, "Binding service...");
                                     }
                                     doBind();
                                 }
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     }
                 }
-        };
+            };
 
     /**
      * Create a BluetoothPbapClient proxy object.
@@ -103,7 +105,7 @@
             try {
                 mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (RemoteException e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
         doBind();
@@ -141,7 +143,7 @@
             try {
                 mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (Exception e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -151,7 +153,7 @@
                     mService = null;
                     mContext.unbindService(mConnection);
                 } catch (Exception re) {
-                    Log.e(TAG,"",re);
+                    Log.e(TAG, "", re);
                 }
             }
         }
@@ -163,23 +165,24 @@
      * Upon successful connection to remote PBAP server the Client will
      * attempt to automatically download the users phonebook and call log.
      *
-     * @param device    a remote device we want connect to
-     * @return <code>true</code> if command has been issued successfully;
-     *         <code>false</code> otherwise;
+     * @param device a remote device we want connect to
+     * @return <code>true</code> if command has been issued successfully; <code>false</code>
+     * otherwise;
      */
     public boolean connect(BluetoothDevice device) {
         if (DBG) {
             log("connect(" + device + ") for PBAP Client.");
         }
-        if (mService != null && isEnabled() && isValidDevice(device)) {
+        final IBluetoothPbapClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.connect(device);
+                return service.connect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mService == null) {
+        if (service == null) {
             Log.w(TAG, "Proxy not attached to service");
         }
         return false;
@@ -189,23 +192,23 @@
      * Initiate disconnect.
      *
      * @param device Remote Bluetooth Device
-     * @return false on error,
-     *               true otherwise
+     * @return false on error, true otherwise
      */
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) {
-            log("disconnect(" + device + ")" + new Exception() );
+            log("disconnect(" + device + ")" + new Exception());
         }
-        if (mService != null && isEnabled() && isValidDevice(device)) {
+        final IBluetoothPbapClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                mService.disconnect(device);
+                service.disconnect(device);
                 return true;
             } catch (RemoteException e) {
-              Log.e(TAG, Log.getStackTraceString(new Throwable()));
-              return false;
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return false;
             }
         }
-        if (mService == null) {
+        if (service == null) {
             Log.w(TAG, "Proxy not attached to service");
         }
         return false;
@@ -222,15 +225,16 @@
         if (DBG) {
             log("getConnectedDevices()");
         }
-        if (mService != null && isEnabled()) {
+        final IBluetoothPbapClient service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getConnectedDevices();
+                return service.getConnectedDevices();
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) {
+        if (service == null) {
             Log.w(TAG, "Proxy not attached to service");
         }
         return new ArrayList<BluetoothDevice>();
@@ -246,15 +250,16 @@
         if (DBG) {
             log("getDevicesMatchingStates()");
         }
-        if (mService != null && isEnabled()) {
+        final IBluetoothPbapClient service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getDevicesMatchingConnectionStates(states);
+                return service.getDevicesMatchingConnectionStates(states);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) {
+        if (service == null) {
             Log.w(TAG, "Proxy not attached to service");
         }
         return new ArrayList<BluetoothDevice>();
@@ -270,15 +275,16 @@
         if (DBG) {
             log("getConnectionState(" + device + ")");
         }
-        if (mService != null && isEnabled() && isValidDevice(device)) {
+        final IBluetoothPbapClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getConnectionState(device);
+                return service.getConnectionState(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.STATE_DISCONNECTED;
             }
         }
-        if (mService == null) {
+        if (service == null) {
             Log.w(TAG, "Proxy not attached to service");
         }
         return BluetoothProfile.STATE_DISCONNECTED;
@@ -291,9 +297,11 @@
             }
             mService = IBluetoothPbapClient.Stub.asInterface(Binder.allowBlocking(service));
             if (mServiceListener != null) {
-                mServiceListener.onServiceConnected(BluetoothProfile.PBAP_CLIENT, BluetoothPbapClient.this);
+                mServiceListener.onServiceConnected(BluetoothProfile.PBAP_CLIENT,
+                        BluetoothPbapClient.this);
             }
         }
+
         public void onServiceDisconnected(ComponentName className) {
             if (DBG) {
                 log("Proxy object disconnected");
@@ -318,45 +326,39 @@
         return false;
     }
 
-    private boolean isValidDevice(BluetoothDevice device) {
-       if (device == null) {
-           return false;
-       }
-       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
-           return true;
-       }
-       return false;
+    private static boolean isValidDevice(BluetoothDevice device) {
+        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
     }
 
     /**
      * Set priority of the profile
      *
      * <p> The device should already be paired.
-     *  Priority can be one of {@link #PRIORITY_ON} or
+     * Priority can be one of {@link #PRIORITY_ON} or
      * {@link #PRIORITY_OFF},
      *
      * @param device Paired bluetooth device
-     * @param priority
+     * @param priority Priority of this profile
      * @return true if priority is set, false on error
      */
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) {
             log("setPriority(" + device + ", " + priority + ")");
         }
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
-            if (priority != BluetoothProfile.PRIORITY_OFF &&
-                priority != BluetoothProfile.PRIORITY_ON) {
-              return false;
+        final IBluetoothPbapClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            if (priority != BluetoothProfile.PRIORITY_OFF
+                    && priority != BluetoothProfile.PRIORITY_ON) {
+                return false;
             }
             try {
-                return mService.setPriority(device, priority);
+                return service.setPriority(device, priority);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mService == null) {
+        if (service == null) {
             Log.w(TAG, "Proxy not attached to service");
         }
         return false;
@@ -376,15 +378,16 @@
         if (VDBG) {
             log("getPriority(" + device + ")");
         }
-        if (mService != null && isEnabled() && isValidDevice(device)) {
+        final IBluetoothPbapClient service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getPriority(device);
+                return service.getPriority(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return PRIORITY_OFF;
             }
         }
-        if (mService == null) {
+        if (service == null) {
             Log.w(TAG, "Proxy not attached to service");
         }
         return PRIORITY_OFF;
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index c5b58e9..46a230b 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -46,14 +46,14 @@
      * Bluetooth device.
      */
     public static final String EXTRA_PREVIOUS_STATE =
-        "android.bluetooth.profile.extra.PREVIOUS_STATE";
+            "android.bluetooth.profile.extra.PREVIOUS_STATE";
 
     /** The profile is in disconnected state */
-    public static final int STATE_DISCONNECTED  = 0;
+    public static final int STATE_DISCONNECTED = 0;
     /** The profile is in connecting state */
-    public static final int STATE_CONNECTING    = 1;
+    public static final int STATE_CONNECTING = 1;
     /** The profile is in connected state */
-    public static final int STATE_CONNECTED     = 2;
+    public static final int STATE_CONNECTED = 2;
     /** The profile is in disconnecting state */
     public static final int STATE_DISCONNECTING = 3;
 
@@ -73,19 +73,22 @@
     public static final int HEALTH = 3;
 
     /**
-     * Input Device Profile
+     * HID Host
+     *
      * @hide
      */
-    public static final int INPUT_DEVICE = 4;
+    public static final int HID_HOST = 4;
 
     /**
      * PAN Profile
+     *
      * @hide
      */
     public static final int PAN = 5;
 
     /**
      * PBAP
+     *
      * @hide
      */
     public static final int PBAP = 6;
@@ -93,15 +96,16 @@
     /**
      * GATT
      */
-    static public final int GATT = 7;
+    public static final int GATT = 7;
 
     /**
      * GATT_SERVER
      */
-    static public final int GATT_SERVER = 8;
+    public static final int GATT_SERVER = 8;
 
     /**
      * MAP Profile
+     *
      * @hide
      */
     public static final int MAP = 9;
@@ -114,43 +118,50 @@
 
     /**
      * A2DP Sink Profile
+     *
      * @hide
      */
     public static final int A2DP_SINK = 11;
 
     /**
      * AVRCP Controller Profile
+     *
      * @hide
      */
     public static final int AVRCP_CONTROLLER = 12;
 
     /**
      * Headset Client - HFP HF Role
+     *
      * @hide
      */
     public static final int HEADSET_CLIENT = 16;
 
     /**
      * PBAP Client
+     *
      * @hide
      */
     public static final int PBAP_CLIENT = 17;
 
     /**
      * MAP Messaging Client Equipment (MCE)
+     *
      * @hide
      */
     public static final int MAP_CLIENT = 18;
 
     /**
-     * Input Host
+     * HID Device
+     *
      * @hide
      */
-    static public final int INPUT_HOST = 19;
+    public static final int HID_DEVICE = 19;
 
     /**
      * Max profile ID. This value should be updated whenever a new profile is added to match
      * the largest value assigned to a profile.
+     *
      * @hide
      */
     public static final int MAX_PROFILE_ID = 19;
@@ -158,13 +169,15 @@
     /**
      * Default priority for devices that we try to auto-connect to and
      * and allow incoming connections for the profile
+     *
      * @hide
      **/
     public static final int PRIORITY_AUTO_CONNECT = 1000;
 
     /**
-     *  Default priority for devices that allow incoming
+     * Default priority for devices that allow incoming
      * and outgoing connections for the profile
+     *
      * @hide
      **/
     public static final int PRIORITY_ON = 100;
@@ -172,14 +185,16 @@
     /**
      * Default priority for devices that does not allow incoming
      * connections and outgoing connections for the profile.
+     *
      * @hide
      **/
     public static final int PRIORITY_OFF = 0;
 
     /**
      * Default priority when not set or when the device is unpaired
+     *
      * @hide
-     * */
+     */
     public static final int PRIORITY_UNDEFINED = -1;
 
     /**
@@ -199,9 +214,8 @@
      * <p> If none of the devices match any of the given states,
      * an empty list will be returned.
      *
-     * @param states Array of states. States can be one of
-     *              {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
-     *              {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
+     * @param states Array of states. States can be one of {@link #STATE_CONNECTED}, {@link
+     * #STATE_CONNECTING}, {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
      * @return List of devices. The list will be empty on error.
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
@@ -211,9 +225,8 @@
      * Get the current connection state of the profile
      *
      * @param device Remote bluetooth device.
-     * @return State of the profile connection. One of
-     *               {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
-     *               {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
+     * @return State of the profile connection. One of {@link #STATE_CONNECTED}, {@link
+     * #STATE_CONNECTING}, {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public int getConnectionState(BluetoothDevice device);
@@ -226,18 +239,18 @@
         /**
          * Called to notify the client when the proxy object has been
          * connected to the service.
-         * @param profile - One of {@link #HEALTH}, {@link #HEADSET} or
-         *                  {@link #A2DP}
-         * @param proxy - One of {@link BluetoothHealth}, {@link BluetoothHeadset} or
-         *                {@link BluetoothA2dp}
+         *
+         * @param profile - One of {@link #HEALTH}, {@link #HEADSET} or {@link #A2DP}
+         * @param proxy - One of {@link BluetoothHealth}, {@link BluetoothHeadset} or {@link
+         * BluetoothA2dp}
          */
         public void onServiceConnected(int profile, BluetoothProfile proxy);
 
         /**
          * Called to notify the client that this proxy object has been
          * disconnected from the service.
-         * @param profile - One of {@link #HEALTH}, {@link #HEADSET} or
-         *                  {@link #A2DP}
+         *
+         * @param profile - One of {@link #HEALTH}, {@link #HEADSET} or {@link #A2DP}
          */
         public void onServiceDisconnected(int profile);
     }
diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java
index 89c1bf8..4848162 100644
--- a/core/java/android/bluetooth/BluetoothSap.java
+++ b/core/java/android/bluetooth/BluetoothSap.java
@@ -16,19 +16,18 @@
 
 package android.bluetooth;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.os.RemoteException;
 import android.os.Binder;
 import android.os.IBinder;
-import android.os.ServiceManager;
+import android.os.RemoteException;
 import android.util.Log;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * This class provides the APIs to control the Bluetooth SIM
  * Access Profile (SAP).
@@ -38,6 +37,7 @@
  * the BluetoothSap proxy object.
  *
  * <p>Each method is protected with its appropriate permission.
+ *
  * @hide
  */
 public final class BluetoothSap implements BluetoothProfile {
@@ -51,9 +51,9 @@
      *
      * <p>This intent will have 4 extras:
      * <ul>
-     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
      * </ul>
      *
      * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -62,62 +62,66 @@
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
      * receive.
+     *
      * @hide
      */
     public static final String ACTION_CONNECTION_STATE_CHANGED =
-        "android.bluetooth.sap.profile.action.CONNECTION_STATE_CHANGED";
+            "android.bluetooth.sap.profile.action.CONNECTION_STATE_CHANGED";
 
-    private IBluetoothSap mService;
+    private volatile IBluetoothSap mService;
     private final Context mContext;
     private ServiceListener mServiceListener;
     private BluetoothAdapter mAdapter;
 
     /**
      * There was an error trying to obtain the state.
+     *
      * @hide
      */
     public static final int STATE_ERROR = -1;
 
     /**
      * Connection state change succceeded.
+     *
      * @hide
      */
     public static final int RESULT_SUCCESS = 1;
 
     /**
      * Connection canceled before completion.
+     *
      * @hide
      */
     public static final int RESULT_CANCELED = 2;
 
-    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
             new IBluetoothStateChangeCallback.Stub() {
                 public void onBluetoothStateChange(boolean up) {
                     if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
                     if (!up) {
-                        if (VDBG) Log.d(TAG,"Unbinding service...");
+                        if (VDBG) Log.d(TAG, "Unbinding service...");
                         synchronized (mConnection) {
                             try {
                                 mService = null;
                                 mContext.unbindService(mConnection);
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     } else {
                         synchronized (mConnection) {
                             try {
                                 if (mService == null) {
-                                    if (VDBG) Log.d(TAG,"Binding service...");
+                                    if (VDBG) Log.d(TAG, "Binding service...");
                                     doBind();
                                 }
                             } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                                Log.e(TAG, "", re);
                             }
                         }
                     }
                 }
-        };
+            };
 
     /**
      * Create a BluetoothSap proxy object.
@@ -132,7 +136,7 @@
             try {
                 mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (RemoteException e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
         doBind();
@@ -163,6 +167,7 @@
      * Other public functions of BluetoothSap will return default error
      * results once close() has been called. Multiple invocations of close()
      * are ok.
+     *
      * @hide
      */
     public synchronized void close() {
@@ -171,7 +176,7 @@
             try {
                 mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
             } catch (Exception e) {
-                Log.e(TAG,"",e);
+                Log.e(TAG, "", e);
             }
         }
 
@@ -181,7 +186,7 @@
                     mService = null;
                     mContext.unbindService(mConnection);
                 } catch (Exception re) {
-                    Log.e(TAG,"",re);
+                    Log.e(TAG, "", re);
                 }
             }
         }
@@ -190,16 +195,20 @@
 
     /**
      * Get the current state of the BluetoothSap service.
-     * @return One of the STATE_ return codes, or STATE_ERROR if this proxy
-     *         object is currently not connected to the Sap service.
+     *
+     * @return One of the STATE_ return codes, or STATE_ERROR if this proxy object is currently not
+     * connected to the Sap service.
      * @hide
      */
     public int getState() {
         if (VDBG) log("getState()");
-        if (mService != null) {
+        final IBluetoothSap service = mService;
+        if (service != null) {
             try {
-                return mService.getState();
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.getState();
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -209,17 +218,20 @@
 
     /**
      * Get the currently connected remote Bluetooth device (PCE).
-     * @return The remote Bluetooth device, or null if not in connected or
-     *         connecting state, or if this proxy object is not connected to
-     *         the Sap service.
+     *
+     * @return The remote Bluetooth device, or null if not in connected or connecting state, or if
+     * this proxy object is not connected to the Sap service.
      * @hide
      */
     public BluetoothDevice getClient() {
         if (VDBG) log("getClient()");
-        if (mService != null) {
+        final IBluetoothSap service = mService;
+        if (service != null) {
             try {
-                return mService.getClient();
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.getClient();
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -231,14 +243,18 @@
      * Returns true if the specified Bluetooth device is connected.
      * Returns false if not connected, or if this proxy object is not
      * currently connected to the Sap service.
+     *
      * @hide
      */
     public boolean isConnected(BluetoothDevice device) {
         if (VDBG) log("isConnected(" + device + ")");
-        if (mService != null) {
+        final IBluetoothSap service = mService;
+        if (service != null) {
             try {
-                return mService.isConnected(device);
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+                return service.isConnected(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
         } else {
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -249,6 +265,7 @@
     /**
      * Initiate connection. Initiation of outgoing connections is not
      * supported for SAP server.
+     *
      * @hide
      */
     public boolean connect(BluetoothDevice device) {
@@ -260,22 +277,21 @@
      * Initiate disconnect.
      *
      * @param device Remote Bluetooth Device
-     * @return false on error,
-     *               true otherwise
+     * @return false on error, true otherwise
      * @hide
      */
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) log("disconnect(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothSap service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.disconnect(device);
+                return service.disconnect(device);
             } catch (RemoteException e) {
-              Log.e(TAG, Log.getStackTraceString(new Throwable()));
-              return false;
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -287,15 +303,16 @@
      */
     public List<BluetoothDevice> getConnectedDevices() {
         if (DBG) log("getConnectedDevices()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothSap service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getConnectedDevices();
+                return service.getConnectedDevices();
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
@@ -307,15 +324,16 @@
      */
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         if (DBG) log("getDevicesMatchingStates()");
-        if (mService != null && isEnabled()) {
+        final IBluetoothSap service = mService;
+        if (service != null && isEnabled()) {
             try {
-                return mService.getDevicesMatchingConnectionStates(states);
+                return service.getDevicesMatchingConnectionStates(states);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
@@ -327,16 +345,16 @@
      */
     public int getConnectionState(BluetoothDevice device) {
         if (DBG) log("getConnectionState(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothSap service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getConnectionState(device);
+                return service.getConnectionState(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.STATE_DISCONNECTED;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return BluetoothProfile.STATE_DISCONNECTED;
     }
 
@@ -352,20 +370,20 @@
      */
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
-            if (priority != BluetoothProfile.PRIORITY_OFF &&
-                priority != BluetoothProfile.PRIORITY_ON) {
-              return false;
+        final IBluetoothSap service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            if (priority != BluetoothProfile.PRIORITY_OFF
+                    && priority != BluetoothProfile.PRIORITY_ON) {
+                return false;
             }
             try {
-                return mService.setPriority(device, priority);
+                return service.setPriority(device, priority);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -378,20 +396,20 @@
      */
     public int getPriority(BluetoothDevice device) {
         if (VDBG) log("getPriority(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        final IBluetoothSap service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getPriority(device);
+                return service.getPriority(device);
             } catch (RemoteException e) {
                 Log.e(TAG, Log.getStackTraceString(new Throwable()));
                 return PRIORITY_OFF;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
         return PRIORITY_OFF;
     }
 
-    private ServiceConnection mConnection = new ServiceConnection() {
+    private final ServiceConnection mConnection = new ServiceConnection() {
         public void onServiceConnected(ComponentName className, IBinder service) {
             if (DBG) log("Proxy object connected");
             mService = IBluetoothSap.Stub.asInterface(Binder.allowBlocking(service));
@@ -399,6 +417,7 @@
                 mServiceListener.onServiceConnected(BluetoothProfile.SAP, BluetoothSap.this);
             }
         }
+
         public void onServiceDisconnected(ComponentName className) {
             if (DBG) log("Proxy object disconnected");
             mService = null;
@@ -415,19 +434,15 @@
     private boolean isEnabled() {
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
 
-        if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON)
+        if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) {
             return true;
+        }
         log("Bluetooth is Not enabled");
         return false;
     }
 
-    private boolean isValidDevice(BluetoothDevice device) {
-       if (device == null)
-           return false;
-
-       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress()))
-           return true;
-       return false;
+    private static boolean isValidDevice(BluetoothDevice device) {
+        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
     }
 
 }
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index 4860c93..58d090d 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -75,12 +75,13 @@
 
     /**
      * Construct a socket for incoming connections.
-     * @param type    type of socket
-     * @param auth    require the remote device to be authenticated
+     *
+     * @param type type of socket
+     * @param auth require the remote device to be authenticated
      * @param encrypt require the connection to be encrypted
-     * @param port    remote port
-     * @throws IOException On error, for example Bluetooth not available, or
-     *                     insufficient privileges
+     * @param port remote port
+     * @throws IOException On error, for example Bluetooth not available, or insufficient
+     * privileges
      */
     /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port)
             throws IOException {
@@ -93,14 +94,15 @@
 
     /**
      * Construct a socket for incoming connections.
-     * @param type    type of socket
-     * @param auth    require the remote device to be authenticated
+     *
+     * @param type type of socket
+     * @param auth require the remote device to be authenticated
      * @param encrypt require the connection to be encrypted
-     * @param port    remote port
-     * @param mitm    enforce man-in-the-middle protection for authentication.
+     * @param port remote port
+     * @param mitm enforce man-in-the-middle protection for authentication.
      * @param min16DigitPin enforce a minimum length of 16 digits for a sec mode 2 connection
-     * @throws IOException On error, for example Bluetooth not available, or
-     *                     insufficient privileges
+     * @throws IOException On error, for example Bluetooth not available, or insufficient
+     * privileges
      */
     /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port,
             boolean mitm, boolean min16DigitPin)
@@ -108,19 +110,20 @@
         mChannel = port;
         mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port, null, mitm,
                 min16DigitPin);
-        if(port == BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
+        if (port == BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
             mSocket.setExcludeSdp(true);
         }
     }
 
     /**
      * Construct a socket for incoming connections.
-     * @param type    type of socket
-     * @param auth    require the remote device to be authenticated
+     *
+     * @param type type of socket
+     * @param auth require the remote device to be authenticated
      * @param encrypt require the connection to be encrypted
-     * @param uuid    uuid
-     * @throws IOException On error, for example Bluetooth not available, or
-     *                     insufficient privileges
+     * @param uuid uuid
+     * @throws IOException On error, for example Bluetooth not available, or insufficient
+     * privileges
      */
     /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, ParcelUuid uuid)
             throws IOException {
@@ -136,9 +139,9 @@
      * <p>Once this call returns, it can be called again to accept subsequent
      * incoming connections.
      * <p>{@link #close} can be used to abort this call from another thread.
+     *
      * @return a connected {@link BluetoothSocket}
-     * @throws IOException on error, for example this call was aborted, or
-     *                     timeout
+     * @throws IOException on error, for example this call was aborted, or timeout
      */
     public BluetoothSocket accept() throws IOException {
         return accept(-1);
@@ -150,9 +153,9 @@
      * <p>Once this call returns, it can be called again to accept subsequent
      * incoming connections.
      * <p>{@link #close} can be used to abort this call from another thread.
+     *
      * @return a connected {@link BluetoothSocket}
-     * @throws IOException on error, for example this call was aborted, or
-     *                     timeout
+     * @throws IOException on error, for example this call was aborted, or timeout
      */
     public BluetoothSocket accept(int timeout) throws IOException {
         return mSocket.accept(timeout);
@@ -174,16 +177,19 @@
         mSocket.close();
     }
 
-    /*package*/ synchronized void setCloseHandler(Handler handler, int message) {
+    /*package*/
+    synchronized void setCloseHandler(Handler handler, int message) {
         mHandler = handler;
         mMessage = message;
     }
-    /*package*/ void setServiceName(String ServiceName) {
-        mSocket.setServiceName(ServiceName);
+
+    /*package*/ void setServiceName(String serviceName) {
+        mSocket.setServiceName(serviceName);
     }
 
     /**
      * Returns the channel on which this socket is bound.
+     *
      * @hide
      */
     public int getChannel() {
@@ -199,10 +205,10 @@
          *       The bind operation should be conducted through this class
          *       and the resulting port should be kept in mChannel, and
          *       not set from BluetoothAdapter. */
-        if(mSocket != null) {
-            if(mSocket.getPort() != newChannel) {
-                Log.w(TAG,"The port set is different that the underlying port. mSocket.getPort(): "
-                            + mSocket.getPort() + " requested newChannel: " + newChannel);
+        if (mSocket != null) {
+            if (mSocket.getPort() != newChannel) {
+                Log.w(TAG, "The port set is different that the underlying port. mSocket.getPort(): "
+                        + mSocket.getPort() + " requested newChannel: " + newChannel);
             }
         }
         mChannel = newChannel;
@@ -212,19 +218,16 @@
     public String toString() {
         StringBuilder sb = new StringBuilder();
         sb.append("ServerSocket: Type: ");
-        switch(mSocket.getConnectionType()) {
-            case BluetoothSocket.TYPE_RFCOMM:
-            {
+        switch (mSocket.getConnectionType()) {
+            case BluetoothSocket.TYPE_RFCOMM: {
                 sb.append("TYPE_RFCOMM");
                 break;
             }
-            case BluetoothSocket.TYPE_L2CAP:
-            {
+            case BluetoothSocket.TYPE_L2CAP: {
                 sb.append("TYPE_L2CAP");
                 break;
             }
-            case BluetoothSocket.TYPE_SCO:
-            {
+            case BluetoothSocket.TYPE_SCO: {
                 sb.append("TYPE_SCO");
                 break;
             }
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 6bf6aa0..0569913 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -16,25 +16,23 @@
 
 package android.bluetooth;
 
-import android.os.ParcelUuid;
+import android.net.LocalSocket;
 import android.os.ParcelFileDescriptor;
+import android.os.ParcelUuid;
 import android.os.RemoteException;
 import android.util.Log;
 
-import java.io.BufferedInputStream;
 import java.io.Closeable;
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.util.Arrays;
 import java.util.Locale;
 import java.util.UUID;
-import android.net.LocalSocket;
 
-import java.nio.Buffer;
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
 /**
  * A connected or connecting Bluetooth socket.
  *
@@ -106,9 +104,9 @@
 
     /*package*/ static final int SEC_FLAG_ENCRYPT = 1;
     /*package*/ static final int SEC_FLAG_AUTH = 1 << 1;
-    /*package*/ static final int BTSOCK_FLAG_NO_SDP  = 1 << 2;
-    /*package*/ static final int SEC_FLAG_AUTH_MITM  = 1 << 3;
-    /*package*/ static final int SEC_FLAG_AUTH_16_DIGIT  = 1 << 4;
+    /*package*/ static final int BTSOCK_FLAG_NO_SDP = 1 << 2;
+    /*package*/ static final int SEC_FLAG_AUTH_MITM = 1 << 3;
+    /*package*/ static final int SEC_FLAG_AUTH_16_DIGIT = 1 << 4;
 
     private final int mType;  /* one of TYPE_RFCOMM etc */
     private BluetoothDevice mDevice;    /* remote device */
@@ -128,9 +126,9 @@
     private int mPort;  /* RFCOMM channel or L2CAP psm */
     private int mFd;
     private String mServiceName;
-    private static int PROXY_CONNECTION_TIMEOUT = 5000;
+    private static final int PROXY_CONNECTION_TIMEOUT = 5000;
 
-    private static int SOCK_SIGNAL_SIZE = 20;
+    private static final int SOCK_SIGNAL_SIZE = 20;
 
     private ByteBuffer mL2capBuffer = null;
     private int mMaxTxPacketSize = 0; // The l2cap maximum packet size supported by the peer.
@@ -151,15 +149,16 @@
 
     /**
      * Construct a BluetoothSocket.
-     * @param type    type of socket
-     * @param fd      fd to use for connected socket, or -1 for a new socket
-     * @param auth    require the remote device to be authenticated
+     *
+     * @param type type of socket
+     * @param fd fd to use for connected socket, or -1 for a new socket
+     * @param auth require the remote device to be authenticated
      * @param encrypt require the connection to be encrypted
-     * @param device  remote device that this socket can connect to
-     * @param port    remote port
-     * @param uuid    SDP uuid
-     * @throws IOException On error, for example Bluetooth not available, or
-     *                     insufficient privileges
+     * @param device remote device that this socket can connect to
+     * @param port remote port
+     * @param uuid SDP uuid
+     * @throws IOException On error, for example Bluetooth not available, or insufficient
+     * privileges
      */
     /*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt,
             BluetoothDevice device, int port, ParcelUuid uuid) throws IOException {
@@ -168,21 +167,22 @@
 
     /**
      * Construct a BluetoothSocket.
-     * @param type    type of socket
-     * @param fd      fd to use for connected socket, or -1 for a new socket
-     * @param auth    require the remote device to be authenticated
+     *
+     * @param type type of socket
+     * @param fd fd to use for connected socket, or -1 for a new socket
+     * @param auth require the remote device to be authenticated
      * @param encrypt require the connection to be encrypted
-     * @param device  remote device that this socket can connect to
-     * @param port    remote port
-     * @param uuid    SDP uuid
-     * @param mitm    enforce man-in-the-middle protection.
+     * @param device remote device that this socket can connect to
+     * @param port remote port
+     * @param uuid SDP uuid
+     * @param mitm enforce man-in-the-middle protection.
      * @param min16DigitPin enforce a minimum length of 16 digits for a sec mode 2 connection
-     * @throws IOException On error, for example Bluetooth not available, or
-     *                     insufficient privileges
+     * @throws IOException On error, for example Bluetooth not available, or insufficient
+     * privileges
      */
     /*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt,
             BluetoothDevice device, int port, ParcelUuid uuid, boolean mitm, boolean min16DigitPin)
-                    throws IOException {
+            throws IOException {
         if (VDBG) Log.d(TAG, "Creating new BluetoothSocket of type: " + type);
         if (type == BluetoothSocket.TYPE_RFCOMM && uuid == null && fd == -1
                 && port != BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
@@ -190,9 +190,11 @@
                 throw new IOException("Invalid RFCOMM channel: " + port);
             }
         }
-        if (uuid != null)
+        if (uuid != null) {
             mUuid = uuid;
-        else mUuid = new ParcelUuid(new UUID(0, 0));
+        } else {
+            mUuid = new ParcelUuid(new UUID(0, 0));
+        }
         mType = type;
         mAuth = auth;
         mAuthMitm = mitm;
@@ -214,6 +216,7 @@
         mInputStream = new BluetoothInputStream(this);
         mOutputStream = new BluetoothOutputStream(this);
     }
+
     private BluetoothSocket(BluetoothSocket s) {
         if (VDBG) Log.d(TAG, "Creating new Private BluetoothSocket of type: " + s.mType);
         mUuid = s.mUuid;
@@ -231,12 +234,13 @@
         mAuthMitm = s.mAuthMitm;
         mMin16DigitPin = s.mMin16DigitPin;
     }
-    private BluetoothSocket acceptSocket(String RemoteAddr) throws IOException {
+
+    private BluetoothSocket acceptSocket(String remoteAddr) throws IOException {
         BluetoothSocket as = new BluetoothSocket(this);
         as.mSocketState = SocketState.CONNECTED;
         FileDescriptor[] fds = mSocket.getAncillaryFileDescriptors();
         if (DBG) Log.d(TAG, "socket fd passed by stack fds: " + Arrays.toString(fds));
-        if(fds == null || fds.length != 1) {
+        if (fds == null || fds.length != 1) {
             Log.e(TAG, "socket fd passed from stack failed, fds: " + Arrays.toString(fds));
             as.close();
             throw new IOException("bt socket acept failed");
@@ -246,20 +250,22 @@
         as.mSocket = LocalSocket.createConnectedLocalSocket(fds[0]);
         as.mSocketIS = as.mSocket.getInputStream();
         as.mSocketOS = as.mSocket.getOutputStream();
-        as.mAddress = RemoteAddr;
-        as.mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(RemoteAddr);
+        as.mAddress = remoteAddr;
+        as.mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(remoteAddr);
         return as;
     }
+
     /**
      * Construct a BluetoothSocket from address. Used by native code.
-     * @param type    type of socket
-     * @param fd      fd to use for connected socket, or -1 for a new socket
-     * @param auth    require the remote device to be authenticated
+     *
+     * @param type type of socket
+     * @param fd fd to use for connected socket, or -1 for a new socket
+     * @param auth require the remote device to be authenticated
      * @param encrypt require the connection to be encrypted
      * @param address remote device that this socket can connect to
-     * @param port    remote port
-     * @throws IOException On error, for example Bluetooth not available, or
-     *                     insufficient privileges
+     * @param port remote port
+     * @throws IOException On error, for example Bluetooth not available, or insufficient
+     * privileges
      */
     private BluetoothSocket(int type, int fd, boolean auth, boolean encrypt, String address,
             int port) throws IOException {
@@ -275,23 +281,30 @@
             super.finalize();
         }
     }
+
     private int getSecurityFlags() {
         int flags = 0;
-        if(mAuth)
+        if (mAuth) {
             flags |= SEC_FLAG_AUTH;
-        if(mEncrypt)
+        }
+        if (mEncrypt) {
             flags |= SEC_FLAG_ENCRYPT;
-        if(mExcludeSdp)
+        }
+        if (mExcludeSdp) {
             flags |= BTSOCK_FLAG_NO_SDP;
-        if(mAuthMitm)
+        }
+        if (mAuthMitm) {
             flags |= SEC_FLAG_AUTH_MITM;
-        if(mMin16DigitPin)
+        }
+        if (mMin16DigitPin) {
             flags |= SEC_FLAG_AUTH_16_DIGIT;
+        }
         return flags;
     }
 
     /**
      * Get the remote device this socket is connecting, or connected, to.
+     *
      * @return remote device
      */
     public BluetoothDevice getRemoteDevice() {
@@ -303,6 +316,7 @@
      * <p>The input stream will be returned even if the socket is not yet
      * connected, but operations on that stream will throw IOException until
      * the associated socket is connected.
+     *
      * @return InputStream
      */
     public InputStream getInputStream() throws IOException {
@@ -314,6 +328,7 @@
      * <p>The output stream will be returned even if the socket is not yet
      * connected, but operations on that stream will throw IOException until
      * the associated socket is connected.
+     *
      * @return OutputStream
      */
     public OutputStream getOutputStream() throws IOException {
@@ -323,8 +338,8 @@
     /**
      * Get the connection status of this socket, ie, whether there is an active connection with
      * remote device.
-     * @return true if connected
-     *         false if not connected
+     *
+     * @return true if connected false if not connected
      */
     public boolean isConnected() {
         return mSocketState == SocketState.CONNECTED;
@@ -349,6 +364,7 @@
      * {@link BluetoothAdapter#cancelDiscovery()} even if it
      * did not directly request a discovery, just to be sure.
      * <p>{@link #close} can be used to abort this call from another thread.
+     *
      * @throws IOException on error, for example connection failure
      */
     public void connect() throws IOException {
@@ -359,10 +375,9 @@
             IBluetooth bluetoothProxy =
                     BluetoothAdapter.getDefaultAdapter().getBluetoothService(null);
             if (bluetoothProxy == null) throw new IOException("Bluetooth is off");
-            mPfd = bluetoothProxy.connectSocket(mDevice, mType,
+            mPfd = bluetoothProxy.getSocketManager().connectSocket(mDevice, mType,
                     mUuid, mPort, getSecurityFlags());
-            synchronized(this)
-            {
+            synchronized (this) {
                 if (DBG) Log.d(TAG, "connect(), SocketState: " + mSocketState + ", mPfd: " + mPfd);
                 if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
                 if (mPfd == null) throw new IOException("bt socket connect failed");
@@ -372,14 +387,15 @@
                 mSocketOS = mSocket.getOutputStream();
             }
             int channel = readInt(mSocketIS);
-            if (channel <= 0)
+            if (channel <= 0) {
                 throw new IOException("bt socket connect failed");
+            }
             mPort = channel;
             waitSocketSignal(mSocketIS);
-            synchronized(this)
-            {
-                if (mSocketState == SocketState.CLOSED)
+            synchronized (this) {
+                if (mSocketState == SocketState.CLOSED) {
                     throw new IOException("bt socket closed");
+                }
                 mSocketState = SocketState.CONNECTED;
             }
         } catch (RemoteException e) {
@@ -401,7 +417,7 @@
             return -1;
         }
         try {
-            mPfd = bluetoothProxy.createSocketChannel(mType, mServiceName,
+            mPfd = bluetoothProxy.getSocketManager().createSocketChannel(mType, mServiceName,
                     mUuid, mPort, getSecurityFlags());
         } catch (RemoteException e) {
             Log.e(TAG, Log.getStackTraceString(new Throwable()));
@@ -410,11 +426,12 @@
 
         // read out port number
         try {
-            synchronized(this) {
-                if (DBG) Log.d(TAG, "bindListen(), SocketState: " + mSocketState + ", mPfd: " +
-                                mPfd);
-                if(mSocketState != SocketState.INIT) return EBADFD;
-                if(mPfd == null) return -1;
+            synchronized (this) {
+                if (DBG) {
+                    Log.d(TAG, "bindListen(), SocketState: " + mSocketState + ", mPfd: " + mPfd);
+                }
+                if (mSocketState != SocketState.INIT) return EBADFD;
+                if (mPfd == null) return -1;
                 FileDescriptor fd = mPfd.getFileDescriptor();
                 if (fd == null) {
                     Log.e(TAG, "bindListen(), null file descriptor");
@@ -429,9 +446,10 @@
             }
             if (DBG) Log.d(TAG, "bindListen(), readInt mSocketIS: " + mSocketIS);
             int channel = readInt(mSocketIS);
-            synchronized(this) {
-                if(mSocketState == SocketState.INIT)
+            synchronized (this) {
+                if (mSocketState == SocketState.INIT) {
                     mSocketState = SocketState.LISTENING;
+                }
             }
             if (DBG) Log.d(TAG, "channel: " + channel);
             if (mPort <= -1) {
@@ -455,19 +473,21 @@
 
     /*package*/ BluetoothSocket accept(int timeout) throws IOException {
         BluetoothSocket acceptedSocket;
-        if (mSocketState != SocketState.LISTENING)
+        if (mSocketState != SocketState.LISTENING) {
             throw new IOException("bt socket is not in listen state");
-        if(timeout > 0) {
+        }
+        if (timeout > 0) {
             Log.d(TAG, "accept() set timeout (ms):" + timeout);
-           mSocket.setSoTimeout(timeout);
+            mSocket.setSoTimeout(timeout);
         }
         String RemoteAddr = waitSocketSignal(mSocketIS);
-        if(timeout > 0)
+        if (timeout > 0) {
             mSocket.setSoTimeout(0);
-        synchronized(this)
-        {
-            if (mSocketState != SocketState.LISTENING)
+        }
+        synchronized (this) {
+            if (mSocketState != SocketState.LISTENING) {
                 throw new IOException("bt socket is not in listen state");
+            }
             acceptedSocket = acceptSocket(RemoteAddr);
             //quick drop the reference of the file handle
         }
@@ -478,12 +498,13 @@
         if (VDBG) Log.d(TAG, "available: " + mSocketIS);
         return mSocketIS.available();
     }
+
     /**
      * Wait until the data in sending queue is emptied. A polling version
      * for flush implementation. Used to ensure the writing data afterwards will
      * be packed in new RFCOMM frame.
-     * @throws IOException
-     *             if an i/o error occurs.
+     *
+     * @throws IOException if an i/o error occurs.
      */
     /*package*/ void flush() throws IOException {
         if (mSocketOS == null) throw new IOException("flush is called on null OutputStream");
@@ -494,11 +515,12 @@
     /*package*/ int read(byte[] b, int offset, int length) throws IOException {
         int ret = 0;
         if (VDBG) Log.d(TAG, "read in:  " + mSocketIS + " len: " + length);
-        if(mType == TYPE_L2CAP)
-        {
+        if (mType == TYPE_L2CAP) {
             int bytesToRead = length;
-            if (VDBG) Log.v(TAG, "l2cap: read(): offset: " + offset + " length:" + length
-                    + "mL2capBuffer= " + mL2capBuffer);
+            if (VDBG) {
+                Log.v(TAG, "l2cap: read(): offset: " + offset + " length:" + length
+                        + "mL2capBuffer= " + mL2capBuffer);
+            }
             if (mL2capBuffer == null) {
                 createL2capRxBuffer();
             }
@@ -511,16 +533,19 @@
             if (bytesToRead > mL2capBuffer.remaining()) {
                 bytesToRead = mL2capBuffer.remaining();
             }
-            if(VDBG) Log.v(TAG, "get(): offset: " + offset
-                    + " bytesToRead: " + bytesToRead);
+            if (VDBG) {
+                Log.v(TAG, "get(): offset: " + offset
+                        + " bytesToRead: " + bytesToRead);
+            }
             mL2capBuffer.get(b, offset, bytesToRead);
             ret = bytesToRead;
-        }else {
+        } else {
             if (VDBG) Log.v(TAG, "default: read(): offset: " + offset + " length:" + length);
             ret = mSocketIS.read(b, offset, length);
         }
-        if (ret < 0)
+        if (ret < 0) {
             throw new IOException("bt socket closed, read return: " + ret);
+        }
         if (VDBG) Log.d(TAG, "read out:  " + mSocketIS + " ret: " + ret);
         return ret;
     }
@@ -532,48 +557,49 @@
         //      splitting the write into multiple smaller writes.
         //      Rfcomm uses dynamic allocation, and should not have any bindings
         //      to the actual message length.
-            if (VDBG) Log.d(TAG, "write: " + mSocketOS + " length: " + length);
-            if (mType == TYPE_L2CAP) {
-                if(length <= mMaxTxPacketSize) {
-                    mSocketOS.write(b, offset, length);
-                } else {
-                    if(DBG) Log.w(TAG, "WARNING: Write buffer larger than L2CAP packet size!\n"
+        if (VDBG) Log.d(TAG, "write: " + mSocketOS + " length: " + length);
+        if (mType == TYPE_L2CAP) {
+            if (length <= mMaxTxPacketSize) {
+                mSocketOS.write(b, offset, length);
+            } else {
+                if (DBG) {
+                    Log.w(TAG, "WARNING: Write buffer larger than L2CAP packet size!\n"
                             + "Packet will be divided into SDU packets of size "
                             + mMaxTxPacketSize);
-                    int tmpOffset = offset;
-                    int bytesToWrite = length;
-                    while (bytesToWrite > 0) {
-                        int tmpLength = (bytesToWrite > mMaxTxPacketSize)
-                                ? mMaxTxPacketSize
-                                : bytesToWrite;
-                        mSocketOS.write(b, tmpOffset, tmpLength);
-                        tmpOffset += tmpLength;
-                        bytesToWrite -= tmpLength;
-                    }
                 }
-            } else {
-                mSocketOS.write(b, offset, length);
+                int tmpOffset = offset;
+                int bytesToWrite = length;
+                while (bytesToWrite > 0) {
+                    int tmpLength = (bytesToWrite > mMaxTxPacketSize)
+                            ? mMaxTxPacketSize
+                            : bytesToWrite;
+                    mSocketOS.write(b, tmpOffset, tmpLength);
+                    tmpOffset += tmpLength;
+                    bytesToWrite -= tmpLength;
+                }
             }
-            // There is no good way to confirm since the entire process is asynchronous anyway
-            if (VDBG) Log.d(TAG, "write out: " + mSocketOS + " length: " + length);
-            return length;
+        } else {
+            mSocketOS.write(b, offset, length);
+        }
+        // There is no good way to confirm since the entire process is asynchronous anyway
+        if (VDBG) Log.d(TAG, "write out: " + mSocketOS + " length: " + length);
+        return length;
     }
 
     @Override
     public void close() throws IOException {
-        Log.d(TAG, "close() this: " + this + ", channel: " + mPort +
-            ", mSocketIS: " + mSocketIS + ", mSocketOS: " + mSocketOS +
-            "mSocket: " + mSocket + ", mSocketState: " + mSocketState);
-        if(mSocketState == SocketState.CLOSED)
+        Log.d(TAG, "close() this: " + this + ", channel: " + mPort + ", mSocketIS: " + mSocketIS
+                + ", mSocketOS: " + mSocketOS + "mSocket: " + mSocket + ", mSocketState: "
+                + mSocketState);
+        if (mSocketState == SocketState.CLOSED) {
             return;
-        else
-        {
-            synchronized(this)
-            {
-                 if(mSocketState == SocketState.CLOSED)
+        } else {
+            synchronized (this) {
+                if (mSocketState == SocketState.CLOSED) {
                     return;
-                 mSocketState = SocketState.CLOSED;
-                 if(mSocket != null) {
+                }
+                mSocketState = SocketState.CLOSED;
+                if (mSocket != null) {
                     if (DBG) Log.d(TAG, "Closing mSocket: " + mSocket);
                     mSocket.shutdownInput();
                     mSocket.shutdownOutput();
@@ -584,7 +610,7 @@
                     mPfd.close();
                     mPfd = null;
                 }
-           }
+            }
         }
     }
 
@@ -599,9 +625,10 @@
      * Get the maximum supported Transmit packet size for the underlying transport.
      * Use this to optimize the writes done to the output socket, to avoid sending
      * half full packets.
+     *
      * @return the maximum supported Transmit packet size for the underlying transport.
      */
-    public int getMaxTransmitPacketSize(){
+    public int getMaxTransmitPacketSize() {
         return mMaxTxPacketSize;
     }
 
@@ -610,14 +637,16 @@
      * Use this to optimize the reads done on the input stream, as any call to read
      * will return a maximum of this amount of bytes - or for some transports a
      * multiple of this value.
+     *
      * @return the maximum supported Receive packet size for the underlying transport.
      */
-    public int getMaxReceivePacketSize(){
+    public int getMaxReceivePacketSize() {
         return mMaxRxPacketSize;
     }
 
     /**
      * Get the type of the underlying connection.
+     *
      * @return one of {@link #TYPE_RFCOMM}, {@link #TYPE_SCO} or {@link #TYPE_L2CAP}
      */
     public int getConnectionType() {
@@ -627,67 +656,77 @@
     /**
      * Change if a SDP entry should be automatically created.
      * Must be called before calling .bind, for the call to have any effect.
-     * @param mExcludeSdp <li>TRUE  - do not auto generate SDP record.
-     *                    <li>FALSE - default - auto generate SPP SDP record.
+     *
+     * @param excludeSdp <li>TRUE - do not auto generate SDP record. <li>FALSE - default - auto
+     * generate SPP SDP record.
      * @hide
      */
     public void setExcludeSdp(boolean excludeSdp) {
-        this.mExcludeSdp = excludeSdp;
+        mExcludeSdp = excludeSdp;
     }
 
-    private String convertAddr(final byte[] addr)  {
+    private String convertAddr(final byte[] addr) {
         return String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X",
-                addr[0] , addr[1], addr[2], addr[3] , addr[4], addr[5]);
+                addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
     }
+
     private String waitSocketSignal(InputStream is) throws IOException {
-        byte [] sig = new byte[SOCK_SIGNAL_SIZE];
+        byte[] sig = new byte[SOCK_SIGNAL_SIZE];
         int ret = readAll(is, sig);
-        if (VDBG) Log.d(TAG, "waitSocketSignal read " + SOCK_SIGNAL_SIZE +
-                " bytes signal ret: " + ret);
+        if (VDBG) {
+            Log.d(TAG, "waitSocketSignal read " + SOCK_SIGNAL_SIZE + " bytes signal ret: " + ret);
+        }
         ByteBuffer bb = ByteBuffer.wrap(sig);
         /* the struct in native is decorated with __attribute__((packed)), hence this is possible */
         bb.order(ByteOrder.nativeOrder());
         int size = bb.getShort();
-        if(size != SOCK_SIGNAL_SIZE)
+        if (size != SOCK_SIGNAL_SIZE) {
             throw new IOException("Connection failure, wrong signal size: " + size);
-        byte [] addr = new byte[6];
+        }
+        byte[] addr = new byte[6];
         bb.get(addr);
         int channel = bb.getInt();
         int status = bb.getInt();
         mMaxTxPacketSize = (bb.getShort() & 0xffff); // Convert to unsigned value
         mMaxRxPacketSize = (bb.getShort() & 0xffff); // Convert to unsigned value
         String RemoteAddr = convertAddr(addr);
-        if (VDBG) Log.d(TAG, "waitSocketSignal: sig size: " + size + ", remote addr: "
-                + RemoteAddr + ", channel: " + channel + ", status: " + status
-                + " MaxRxPktSize: " + mMaxRxPacketSize + " MaxTxPktSize: " + mMaxTxPacketSize);
-        if(status != 0)
+        if (VDBG) {
+            Log.d(TAG, "waitSocketSignal: sig size: " + size + ", remote addr: "
+                    + RemoteAddr + ", channel: " + channel + ", status: " + status
+                    + " MaxRxPktSize: " + mMaxRxPacketSize + " MaxTxPktSize: " + mMaxTxPacketSize);
+        }
+        if (status != 0) {
             throw new IOException("Connection failure, status: " + status);
+        }
         return RemoteAddr;
     }
 
-    private void createL2capRxBuffer(){
-        if(mType == TYPE_L2CAP) {
+    private void createL2capRxBuffer() {
+        if (mType == TYPE_L2CAP) {
             // Allocate the buffer to use for reads.
-            if(VDBG) Log.v(TAG, "  Creating mL2capBuffer: mMaxPacketSize: " + mMaxRxPacketSize);
+            if (VDBG) Log.v(TAG, "  Creating mL2capBuffer: mMaxPacketSize: " + mMaxRxPacketSize);
             mL2capBuffer = ByteBuffer.wrap(new byte[mMaxRxPacketSize]);
-            if(VDBG) Log.v(TAG, "mL2capBuffer.remaining()" + mL2capBuffer.remaining());
+            if (VDBG) Log.v(TAG, "mL2capBuffer.remaining()" + mL2capBuffer.remaining());
             mL2capBuffer.limit(0); // Ensure we do a real read at the first read-request
-            if(VDBG) Log.v(TAG, "mL2capBuffer.remaining() after limit(0):" +
-                    mL2capBuffer.remaining());
+            if (VDBG) {
+                Log.v(TAG, "mL2capBuffer.remaining() after limit(0):" + mL2capBuffer.remaining());
+            }
         }
     }
 
     private int readAll(InputStream is, byte[] b) throws IOException {
         int left = b.length;
-        while(left > 0) {
+        while (left > 0) {
             int ret = is.read(b, b.length - left, left);
-            if(ret <= 0)
-                 throw new IOException("read failed, socket might closed or timeout, read ret: "
-                         + ret);
+            if (ret <= 0) {
+                throw new IOException("read failed, socket might closed or timeout, read ret: "
+                        + ret);
+            }
             left -= ret;
-            if(left != 0)
-                Log.w(TAG, "readAll() looping, read partial size: " + (b.length - left) +
-                            ", expect size: " + b.length);
+            if (left != 0) {
+                Log.w(TAG, "readAll() looping, read partial size: " + (b.length - left)
+                        + ", expect size: " + b.length);
+            }
         }
         return b.length;
     }
@@ -704,7 +743,7 @@
     private int fillL2capRxBuffer() throws IOException {
         mL2capBuffer.rewind();
         int ret = mSocketIS.read(mL2capBuffer.array());
-        if(ret == -1) {
+        if (ret == -1) {
             // reached end of stream - return -1
             mL2capBuffer.limit(0);
             return -1;
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 243579a..76cb3f5 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -25,9 +25,10 @@
 import java.util.UUID;
 
 /**
-* Static helper methods and constants to decode the ParcelUuid of remote devices.
-*  @hide
-*/
+ * Static helper methods and constants to decode the ParcelUuid of remote devices.
+ *
+ * @hide
+ */
 public final class BluetoothUuid {
 
     /* See Bluetooth Assigned Numbers document - SDP section, to get the values of UUIDs
@@ -76,9 +77,9 @@
             ParcelUuid.fromString("00001133-0000-1000-8000-00805F9B34FB");
     public static final ParcelUuid MAS =
             ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB");
-  public static final ParcelUuid SAP =
+    public static final ParcelUuid SAP =
             ParcelUuid.fromString("0000112D-0000-1000-8000-00805F9B34FB");
-			
+
     public static final ParcelUuid BASE_UUID =
             ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
 
@@ -90,8 +91,8 @@
     public static final int UUID_BYTES_128_BIT = 16;
 
     public static final ParcelUuid[] RESERVED_UUIDS = {
-        AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
-        ObexObjectPush, PANU, NAP, MAP, MNS, MAS, SAP};
+            AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
+            ObexObjectPush, PANU, NAP, MAP, MNS, MAS, SAP};
 
     public static boolean isAudioSource(ParcelUuid uuid) {
         return uuid.equals(AudioSource);
@@ -136,15 +137,19 @@
     public static boolean isBnep(ParcelUuid uuid) {
         return uuid.equals(BNEP);
     }
+
     public static boolean isMap(ParcelUuid uuid) {
         return uuid.equals(MAP);
     }
+
     public static boolean isMns(ParcelUuid uuid) {
         return uuid.equals(MNS);
     }
+
     public static boolean isMas(ParcelUuid uuid) {
         return uuid.equals(MAS);
     }
+
     public static boolean isSap(ParcelUuid uuid) {
         return uuid.equals(SAP);
     }
@@ -156,13 +161,15 @@
      * @param uuid
      */
     public static boolean isUuidPresent(ParcelUuid[] uuidArray, ParcelUuid uuid) {
-        if ((uuidArray == null || uuidArray.length == 0) && uuid == null)
+        if ((uuidArray == null || uuidArray.length == 0) && uuid == null) {
             return true;
+        }
 
-        if (uuidArray == null)
+        if (uuidArray == null) {
             return false;
+        }
 
-        for (ParcelUuid element: uuidArray) {
+        for (ParcelUuid element : uuidArray) {
             if (element.equals(uuid)) return true;
         }
         return false;
@@ -173,21 +180,20 @@
      *
      * @param uuidA - List of ParcelUuids
      * @param uuidB - List of ParcelUuids
-     *
      */
     public static boolean containsAnyUuid(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
         if (uuidA == null && uuidB == null) return true;
 
         if (uuidA == null) {
-            return uuidB.length == 0 ? true : false;
+            return uuidB.length == 0;
         }
 
         if (uuidB == null) {
-            return uuidA.length == 0 ? true : false;
+            return uuidA.length == 0;
         }
 
-        HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid> (Arrays.asList(uuidA));
-        for (ParcelUuid uuid: uuidB) {
+        HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid>(Arrays.asList(uuidA));
+        for (ParcelUuid uuid : uuidB) {
             if (uuidSet.contains(uuid)) return true;
         }
         return false;
@@ -199,19 +205,18 @@
      *
      * @param uuidA - Array of ParcelUuidsA
      * @param uuidB - Array of ParcelUuidsB
-     *
      */
     public static boolean containsAllUuids(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
         if (uuidA == null && uuidB == null) return true;
 
         if (uuidA == null) {
-            return uuidB.length == 0 ? true : false;
+            return uuidB.length == 0;
         }
 
         if (uuidB == null) return true;
 
-        HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid> (Arrays.asList(uuidA));
-        for (ParcelUuid uuid: uuidB) {
+        HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid>(Arrays.asList(uuidA));
+        for (ParcelUuid uuid : uuidB) {
             if (!uuidSet.contains(uuid)) return false;
         }
         return true;
@@ -221,13 +226,14 @@
      * Extract the Service Identifier or the actual uuid from the Parcel Uuid.
      * For example, if 0000110B-0000-1000-8000-00805F9B34FB is the parcel Uuid,
      * this function will return 110B
+     *
      * @param parcelUuid
      * @return the service identifier.
      */
     public static int getServiceIdentifierFromParcelUuid(ParcelUuid parcelUuid) {
         UUID uuid = parcelUuid.getUuid();
-        long value = (uuid.getMostSignificantBits() & 0x0000FFFF00000000L) >>> 32;
-        return (int)value;
+        long value = (uuid.getMostSignificantBits() & 0xFFFFFFFF00000000L) >>> 32;
+        return (int) value;
     }
 
     /**
@@ -244,8 +250,8 @@
             throw new IllegalArgumentException("uuidBytes cannot be null");
         }
         int length = uuidBytes.length;
-        if (length != UUID_BYTES_16_BIT && length != UUID_BYTES_32_BIT &&
-                length != UUID_BYTES_128_BIT) {
+        if (length != UUID_BYTES_16_BIT && length != UUID_BYTES_32_BIT
+                && length != UUID_BYTES_128_BIT) {
             throw new IllegalArgumentException("uuidBytes length invalid - " + length);
         }
 
@@ -264,7 +270,7 @@
             shortUuid = uuidBytes[0] & 0xFF;
             shortUuid += (uuidBytes[1] & 0xFF) << 8;
         } else {
-            shortUuid = uuidBytes[0] & 0xFF ;
+            shortUuid = uuidBytes[0] & 0xFF;
             shortUuid += (uuidBytes[1] & 0xFF) << 8;
             shortUuid += (uuidBytes[2] & 0xFF) << 16;
             shortUuid += (uuidBytes[3] & 0xFF) << 24;
@@ -275,8 +281,8 @@
     }
 
     /**
-     * Parse UUID to bytes. The returned value is shortest representation, a 16-bit, 32-bit or 128-bit UUID,
-     * Note returned value is little endian (Bluetooth).
+     * Parse UUID to bytes. The returned value is shortest representation, a 16-bit, 32-bit or
+     * 128-bit UUID, Note returned value is little endian (Bluetooth).
      *
      * @param uuid uuid to parse.
      * @return shortest representation of {@code uuid} as bytes.
@@ -290,18 +296,18 @@
         if (is16BitUuid(uuid)) {
             byte[] uuidBytes = new byte[UUID_BYTES_16_BIT];
             int uuidVal = getServiceIdentifierFromParcelUuid(uuid);
-            uuidBytes[0] = (byte)(uuidVal & 0xFF);
-            uuidBytes[1] = (byte)((uuidVal & 0xFF00) >> 8);
+            uuidBytes[0] = (byte) (uuidVal & 0xFF);
+            uuidBytes[1] = (byte) ((uuidVal & 0xFF00) >> 8);
             return uuidBytes;
         }
 
         if (is32BitUuid(uuid)) {
             byte[] uuidBytes = new byte[UUID_BYTES_32_BIT];
             int uuidVal = getServiceIdentifierFromParcelUuid(uuid);
-            uuidBytes[0] = (byte)(uuidVal & 0xFF);
-            uuidBytes[1] = (byte)((uuidVal & 0xFF00) >> 8);
-            uuidBytes[2] = (byte)((uuidVal & 0xFF0000) >> 16);
-            uuidBytes[3] = (byte)((uuidVal & 0xFF000000) >> 24);
+            uuidBytes[0] = (byte) (uuidVal & 0xFF);
+            uuidBytes[1] = (byte) ((uuidVal & 0xFF00) >> 8);
+            uuidBytes[2] = (byte) ((uuidVal & 0xFF0000) >> 16);
+            uuidBytes[3] = (byte) ((uuidVal & 0xFF000000) >> 24);
             return uuidBytes;
         }
 
diff --git a/core/java/android/bluetooth/OobData.java b/core/java/android/bluetooth/OobData.java
index 9e87230..d632572 100644
--- a/core/java/android/bluetooth/OobData.java
+++ b/core/java/android/bluetooth/OobData.java
@@ -19,8 +19,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import android.util.Log;
-
 /**
  * Out Of Band Data for Bluetooth device pairing.
  *
@@ -30,13 +28,13 @@
  * @hide
  */
 public class OobData implements Parcelable {
-    private byte[] leBluetoothDeviceAddress;
-    private byte[] securityManagerTk;
-    private byte[] leSecureConnectionsConfirmation;
-    private byte[] leSecureConnectionsRandom;
+    private byte[] mLeBluetoothDeviceAddress;
+    private byte[] mSecurityManagerTk;
+    private byte[] mLeSecureConnectionsConfirmation;
+    private byte[] mLeSecureConnectionsRandom;
 
     public byte[] getLeBluetoothDeviceAddress() {
-        return leBluetoothDeviceAddress;
+        return mLeBluetoothDeviceAddress;
     }
 
     /**
@@ -45,11 +43,11 @@
      * a detailed description.
      */
     public void setLeBluetoothDeviceAddress(byte[] leBluetoothDeviceAddress) {
-        this.leBluetoothDeviceAddress = leBluetoothDeviceAddress;
+        mLeBluetoothDeviceAddress = leBluetoothDeviceAddress;
     }
 
     public byte[] getSecurityManagerTk() {
-        return securityManagerTk;
+        return mSecurityManagerTk;
     }
 
     /**
@@ -58,48 +56,50 @@
      * Part A 1.8 for a detailed description.
      */
     public void setSecurityManagerTk(byte[] securityManagerTk) {
-        this.securityManagerTk = securityManagerTk;
+        mSecurityManagerTk = securityManagerTk;
     }
 
     public byte[] getLeSecureConnectionsConfirmation() {
-        return leSecureConnectionsConfirmation;
+        return mLeSecureConnectionsConfirmation;
     }
 
     public void setLeSecureConnectionsConfirmation(byte[] leSecureConnectionsConfirmation) {
-        this.leSecureConnectionsConfirmation = leSecureConnectionsConfirmation;
+        mLeSecureConnectionsConfirmation = leSecureConnectionsConfirmation;
     }
 
     public byte[] getLeSecureConnectionsRandom() {
-        return leSecureConnectionsRandom;
+        return mLeSecureConnectionsRandom;
     }
 
     public void setLeSecureConnectionsRandom(byte[] leSecureConnectionsRandom) {
-        this.leSecureConnectionsRandom = leSecureConnectionsRandom;
+        mLeSecureConnectionsRandom = leSecureConnectionsRandom;
     }
 
-    public OobData() { }
+    public OobData() {
+    }
 
     private OobData(Parcel in) {
-        leBluetoothDeviceAddress = in.createByteArray();
-        securityManagerTk = in.createByteArray();
-        leSecureConnectionsConfirmation = in.createByteArray();
-        leSecureConnectionsRandom = in.createByteArray();
+        mLeBluetoothDeviceAddress = in.createByteArray();
+        mSecurityManagerTk = in.createByteArray();
+        mLeSecureConnectionsConfirmation = in.createByteArray();
+        mLeSecureConnectionsRandom = in.createByteArray();
     }
 
+    @Override
     public int describeContents() {
         return 0;
     }
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeByteArray(leBluetoothDeviceAddress);
-        out.writeByteArray(securityManagerTk);
-        out.writeByteArray(leSecureConnectionsConfirmation);
-        out.writeByteArray(leSecureConnectionsRandom);
+        out.writeByteArray(mLeBluetoothDeviceAddress);
+        out.writeByteArray(mSecurityManagerTk);
+        out.writeByteArray(mLeSecureConnectionsConfirmation);
+        out.writeByteArray(mLeSecureConnectionsRandom);
     }
 
-    public static final Parcelable.Creator<OobData> CREATOR
-            = new Parcelable.Creator<OobData>() {
+    public static final Parcelable.Creator<OobData> CREATOR =
+            new Parcelable.Creator<OobData>() {
         public OobData createFromParcel(Parcel in) {
             return new OobData(in);
         }
@@ -108,4 +108,4 @@
             return new OobData[size];
         }
     };
-}
\ No newline at end of file
+}
diff --git a/core/java/android/bluetooth/SdpMasRecord.java b/core/java/android/bluetooth/SdpMasRecord.java
index fa164c0..72d4938 100644
--- a/core/java/android/bluetooth/SdpMasRecord.java
+++ b/core/java/android/bluetooth/SdpMasRecord.java
@@ -26,38 +26,41 @@
     private final int mSupportedFeatures;
     private final int mSupportedMessageTypes;
     private final String mServiceName;
+
+    /** Message type */
     public static final class MessageType {
-        public static final int EMAIL    = 0x01;
-        public static final int SMS_GSM  = 0x02;
+        public static final int EMAIL = 0x01;
+        public static final int SMS_GSM = 0x02;
         public static final int SMS_CDMA = 0x04;
-        public static final int MMS      = 0x08;
+        public static final int MMS = 0x08;
     }
 
-    public SdpMasRecord(int mas_instance_id,
-                                 int l2cap_psm,
-                                 int rfcomm_channel_number,
-                                 int profile_version,
-                                 int supported_features,
-                                 int supported_message_types,
-                                 String service_name){
-        this.mMasInstanceId = mas_instance_id;
-        this.mL2capPsm = l2cap_psm;
-        this.mRfcommChannelNumber = rfcomm_channel_number;
-        this.mProfileVersion = profile_version;
-        this.mSupportedFeatures = supported_features;
-        this.mSupportedMessageTypes = supported_message_types;
-        this.mServiceName = service_name;
+    public SdpMasRecord(int masInstanceId,
+            int l2capPsm,
+            int rfcommChannelNumber,
+            int profileVersion,
+            int supportedFeatures,
+            int supportedMessageTypes,
+            String serviceName) {
+        mMasInstanceId = masInstanceId;
+        mL2capPsm = l2capPsm;
+        mRfcommChannelNumber = rfcommChannelNumber;
+        mProfileVersion = profileVersion;
+        mSupportedFeatures = supportedFeatures;
+        mSupportedMessageTypes = supportedMessageTypes;
+        mServiceName = serviceName;
     }
 
-    public SdpMasRecord(Parcel in){
-        this.mMasInstanceId = in.readInt();
-        this.mL2capPsm = in.readInt();
-        this.mRfcommChannelNumber = in.readInt();
-        this.mProfileVersion = in.readInt();
-        this.mSupportedFeatures = in.readInt();
-        this.mSupportedMessageTypes = in.readInt();
-        this.mServiceName = in.readString();
+    public SdpMasRecord(Parcel in) {
+        mMasInstanceId = in.readInt();
+        mL2capPsm = in.readInt();
+        mRfcommChannelNumber = in.readInt();
+        mProfileVersion = in.readInt();
+        mSupportedFeatures = in.readInt();
+        mSupportedMessageTypes = in.readInt();
+        mServiceName = in.readString();
     }
+
     @Override
     public int describeContents() {
         // TODO Auto-generated method stub
@@ -87,50 +90,49 @@
     public int getSupportedMessageTypes() {
         return mSupportedMessageTypes;
     }
-    
+
     public boolean msgSupported(int msg) {
         return (mSupportedMessageTypes & msg) != 0;
     }
-    
+
     public String getServiceName() {
         return mServiceName;
     }
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-
-        dest.writeInt(this.mMasInstanceId);
-        dest.writeInt(this.mL2capPsm);
-        dest.writeInt(this.mRfcommChannelNumber);
-        dest.writeInt(this.mProfileVersion);
-        dest.writeInt(this.mSupportedFeatures);
-        dest.writeInt(this.mSupportedMessageTypes);
-        dest.writeString(this.mServiceName);
-
+        dest.writeInt(mMasInstanceId);
+        dest.writeInt(mL2capPsm);
+        dest.writeInt(mRfcommChannelNumber);
+        dest.writeInt(mProfileVersion);
+        dest.writeInt(mSupportedFeatures);
+        dest.writeInt(mSupportedMessageTypes);
+        dest.writeString(mServiceName);
     }
+
     @Override
-    public String toString(){
+    public String toString() {
         String ret = "Bluetooth MAS SDP Record:\n";
 
-        if(mMasInstanceId != -1){
+        if (mMasInstanceId != -1) {
             ret += "Mas Instance Id: " + mMasInstanceId + "\n";
         }
-        if(mRfcommChannelNumber != -1){
+        if (mRfcommChannelNumber != -1) {
             ret += "RFCOMM Chan Number: " + mRfcommChannelNumber + "\n";
         }
-        if(mL2capPsm != -1){
+        if (mL2capPsm != -1) {
             ret += "L2CAP PSM: " + mL2capPsm + "\n";
         }
-        if(mServiceName != null){
+        if (mServiceName != null) {
             ret += "Service Name: " + mServiceName + "\n";
         }
-        if(mProfileVersion != -1){
+        if (mProfileVersion != -1) {
             ret += "Profile version: " + mProfileVersion + "\n";
         }
-        if(mSupportedMessageTypes != -1){
+        if (mSupportedMessageTypes != -1) {
             ret += "Supported msg types: " + mSupportedMessageTypes + "\n";
         }
-        if(mSupportedFeatures != -1){
+        if (mSupportedFeatures != -1) {
             ret += "Supported features: " + mSupportedFeatures + "\n";
         }
         return ret;
@@ -140,6 +142,7 @@
         public SdpMasRecord createFromParcel(Parcel in) {
             return new SdpMasRecord(in);
         }
+
         public SdpRecord[] newArray(int size) {
             return new SdpRecord[size];
         }
diff --git a/core/java/android/bluetooth/SdpMnsRecord.java b/core/java/android/bluetooth/SdpMnsRecord.java
index c02bb5a..a781d5d 100644
--- a/core/java/android/bluetooth/SdpMnsRecord.java
+++ b/core/java/android/bluetooth/SdpMnsRecord.java
@@ -25,25 +25,26 @@
     private final int mProfileVersion;
     private final String mServiceName;
 
-    public SdpMnsRecord(int l2cap_psm,
-            int rfcomm_channel_number,
-            int profile_version,
-            int supported_features,
-            String service_name){
-        this.mL2capPsm = l2cap_psm;
-        this.mRfcommChannelNumber = rfcomm_channel_number;
-        this.mSupportedFeatures = supported_features;
-        this.mServiceName = service_name;
-        this.mProfileVersion = profile_version;
+    public SdpMnsRecord(int l2capPsm,
+            int rfcommChannelNumber,
+            int profileVersion,
+            int supportedFeatures,
+            String serviceName) {
+        mL2capPsm = l2capPsm;
+        mRfcommChannelNumber = rfcommChannelNumber;
+        mSupportedFeatures = supportedFeatures;
+        mServiceName = serviceName;
+        mProfileVersion = profileVersion;
     }
 
-    public SdpMnsRecord(Parcel in){
-           this.mRfcommChannelNumber = in.readInt();
-           this.mL2capPsm = in.readInt();
-           this.mServiceName = in.readString();
-           this.mSupportedFeatures = in.readInt();
-           this.mProfileVersion = in.readInt();
+    public SdpMnsRecord(Parcel in) {
+        mRfcommChannelNumber = in.readInt();
+        mL2capPsm = in.readInt();
+        mServiceName = in.readString();
+        mSupportedFeatures = in.readInt();
+        mProfileVersion = in.readInt();
     }
+
     @Override
     public int describeContents() {
         // TODO Auto-generated method stub
@@ -80,23 +81,23 @@
         dest.writeInt(mProfileVersion);
     }
 
-    public String toString(){
+    public String toString() {
         String ret = "Bluetooth MNS SDP Record:\n";
 
-        if(mRfcommChannelNumber != -1){
+        if (mRfcommChannelNumber != -1) {
             ret += "RFCOMM Chan Number: " + mRfcommChannelNumber + "\n";
         }
-        if(mL2capPsm != -1){
+        if (mL2capPsm != -1) {
             ret += "L2CAP PSM: " + mL2capPsm + "\n";
         }
-        if(mServiceName != null){
+        if (mServiceName != null) {
             ret += "Service Name: " + mServiceName + "\n";
         }
-        if(mSupportedFeatures != -1){
+        if (mSupportedFeatures != -1) {
             ret += "Supported features: " + mSupportedFeatures + "\n";
         }
-        if(mProfileVersion != -1){
-            ret += "Profile_version: " + mProfileVersion+"\n";
+        if (mProfileVersion != -1) {
+            ret += "Profile_version: " + mProfileVersion + "\n";
         }
         return ret;
     }
@@ -105,6 +106,7 @@
         public SdpMnsRecord createFromParcel(Parcel in) {
             return new SdpMnsRecord(in);
         }
+
         public SdpMnsRecord[] newArray(int size) {
             return new SdpMnsRecord[size];
         }
diff --git a/core/java/android/bluetooth/SdpOppOpsRecord.java b/core/java/android/bluetooth/SdpOppOpsRecord.java
index e0e4007..e30745b8 100644
--- a/core/java/android/bluetooth/SdpOppOpsRecord.java
+++ b/core/java/android/bluetooth/SdpOppOpsRecord.java
@@ -14,14 +14,15 @@
 */
 package android.bluetooth;
 
-import java.util.Arrays;
-
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.Arrays;
+
 /**
  * Data representation of a Object Push Profile Server side SDP record.
  */
+
 /** @hide */
 public class SdpOppOpsRecord implements Parcelable {
 
@@ -34,11 +35,11 @@
     public SdpOppOpsRecord(String serviceName, int rfcommChannel,
             int l2capPsm, int version, byte[] formatsList) {
         super();
-        this.mServiceName = serviceName;
-        this.mRfcommChannel = rfcommChannel;
-        this.mL2capPsm = l2capPsm;
-        this.mProfileVersion = version;
-        this.mFormatsList = formatsList;
+        mServiceName = serviceName;
+        mRfcommChannel = rfcommChannel;
+        mL2capPsm = l2capPsm;
+        mProfileVersion = version;
+        mFormatsList = formatsList;
     }
 
     public String getServiceName() {
@@ -67,18 +68,18 @@
         return 0;
     }
 
-    public SdpOppOpsRecord(Parcel in){
-        this.mRfcommChannel = in.readInt();
-        this.mL2capPsm = in.readInt();
-        this.mProfileVersion = in.readInt();
-        this.mServiceName = in.readString();
+    public SdpOppOpsRecord(Parcel in) {
+        mRfcommChannel = in.readInt();
+        mL2capPsm = in.readInt();
+        mProfileVersion = in.readInt();
+        mServiceName = in.readString();
         int arrayLength = in.readInt();
-        if(arrayLength > 0) {
+        if (arrayLength > 0) {
             byte[] bytes = new byte[arrayLength];
             in.readByteArray(bytes);
-            this.mFormatsList = bytes;
+            mFormatsList = bytes;
         } else {
-            this.mFormatsList = null;
+            mFormatsList = null;
         }
     }
 
@@ -88,7 +89,7 @@
         dest.writeInt(mL2capPsm);
         dest.writeInt(mProfileVersion);
         dest.writeString(mServiceName);
-        if(mFormatsList!= null && mFormatsList.length > 0) {
+        if (mFormatsList != null && mFormatsList.length > 0) {
             dest.writeInt(mFormatsList.length);
             dest.writeByteArray(mFormatsList);
         } else {
@@ -96,7 +97,8 @@
         }
     }
 
-    public String toString(){
+    @Override
+    public String toString() {
         StringBuilder sb = new StringBuilder("Bluetooth OPP Server SDP Record:\n");
         sb.append("  RFCOMM Chan Number: ").append(mRfcommChannel);
         sb.append("\n  L2CAP PSM: ").append(mL2capPsm);
@@ -110,6 +112,7 @@
         public SdpOppOpsRecord createFromParcel(Parcel in) {
             return new SdpOppOpsRecord(in);
         }
+
         public SdpOppOpsRecord[] newArray(int size) {
             return new SdpOppOpsRecord[size];
         }
diff --git a/core/java/android/bluetooth/SdpPseRecord.java b/core/java/android/bluetooth/SdpPseRecord.java
index 2c159cc..72249d0 100644
--- a/core/java/android/bluetooth/SdpPseRecord.java
+++ b/core/java/android/bluetooth/SdpPseRecord.java
@@ -27,28 +27,29 @@
     private final int mSupportedRepositories;
     private final String mServiceName;
 
-    public SdpPseRecord(int l2cap_psm,
-            int rfcomm_channel_number,
-            int profile_version,
-            int supported_features,
-            int supported_repositories,
-            String service_name){
-        this.mL2capPsm = l2cap_psm;
-        this.mRfcommChannelNumber = rfcomm_channel_number;
-        this.mProfileVersion = profile_version;
-        this.mSupportedFeatures = supported_features;
-        this.mSupportedRepositories = supported_repositories;
-        this.mServiceName = service_name;
+    public SdpPseRecord(int l2capPsm,
+            int rfcommChannelNumber,
+            int profileVersion,
+            int supportedFeatures,
+            int supportedRepositories,
+            String serviceName) {
+        mL2capPsm = l2capPsm;
+        mRfcommChannelNumber = rfcommChannelNumber;
+        mProfileVersion = profileVersion;
+        mSupportedFeatures = supportedFeatures;
+        mSupportedRepositories = supportedRepositories;
+        mServiceName = serviceName;
     }
 
-    public SdpPseRecord(Parcel in){
-           this.mRfcommChannelNumber = in.readInt();
-           this.mL2capPsm = in.readInt();
-           this.mProfileVersion = in.readInt();
-           this.mSupportedFeatures = in.readInt();
-           this.mSupportedRepositories = in.readInt();
-           this.mServiceName = in.readString();
+    public SdpPseRecord(Parcel in) {
+        mRfcommChannelNumber = in.readInt();
+        mL2capPsm = in.readInt();
+        mProfileVersion = in.readInt();
+        mSupportedFeatures = in.readInt();
+        mSupportedRepositories = in.readInt();
+        mServiceName = in.readString();
     }
+
     @Override
     public int describeContents() {
         // TODO Auto-generated method stub
@@ -78,6 +79,7 @@
     public int getSupportedRepositories() {
         return mSupportedRepositories;
     }
+
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mRfcommChannelNumber);
@@ -89,25 +91,26 @@
 
     }
 
-    public String toString(){
+    @Override
+    public String toString() {
         String ret = "Bluetooth MNS SDP Record:\n";
 
-        if(mRfcommChannelNumber != -1){
+        if (mRfcommChannelNumber != -1) {
             ret += "RFCOMM Chan Number: " + mRfcommChannelNumber + "\n";
         }
-        if(mL2capPsm != -1){
+        if (mL2capPsm != -1) {
             ret += "L2CAP PSM: " + mL2capPsm + "\n";
         }
-        if(mProfileVersion != -1){
+        if (mProfileVersion != -1) {
             ret += "profile version: " + mProfileVersion + "\n";
         }
-        if(mServiceName != null){
+        if (mServiceName != null) {
             ret += "Service Name: " + mServiceName + "\n";
         }
-        if(mSupportedFeatures != -1){
+        if (mSupportedFeatures != -1) {
             ret += "Supported features: " + mSupportedFeatures + "\n";
         }
-        if(mSupportedRepositories != -1){
+        if (mSupportedRepositories != -1) {
             ret += "Supported repositories: " + mSupportedRepositories + "\n";
         }
 
@@ -118,6 +121,7 @@
         public SdpPseRecord createFromParcel(Parcel in) {
             return new SdpPseRecord(in);
         }
+
         public SdpPseRecord[] newArray(int size) {
             return new SdpPseRecord[size];
         }
diff --git a/core/java/android/bluetooth/SdpRecord.java b/core/java/android/bluetooth/SdpRecord.java
index 6f1065e..730862e 100644
--- a/core/java/android/bluetooth/SdpRecord.java
+++ b/core/java/android/bluetooth/SdpRecord.java
@@ -21,7 +21,7 @@
 import java.util.Arrays;
 
 /** @hide */
-public class SdpRecord implements Parcelable{
+public class SdpRecord implements Parcelable {
 
     private final byte[] mRawData;
     private final int mRawSize;
@@ -32,15 +32,15 @@
                 + ", rawSize=" + mRawSize + "]";
     }
 
-    public SdpRecord(int size_record, byte[] record){
-        this.mRawData = record;
-        this.mRawSize = size_record;
+    public SdpRecord(int sizeRecord, byte[] record) {
+        mRawData = record;
+        mRawSize = sizeRecord;
     }
 
-    public SdpRecord(Parcel in){
-        this.mRawSize = in.readInt();
-        this.mRawData = new byte[mRawSize];
-        in.readByteArray(this.mRawData);
+    public SdpRecord(Parcel in) {
+        mRawSize = in.readInt();
+        mRawData = new byte[mRawSize];
+        in.readByteArray(mRawData);
 
     }
 
@@ -51,11 +51,12 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(this.mRawSize);
-        dest.writeByteArray(this.mRawData);
+        dest.writeInt(mRawSize);
+        dest.writeByteArray(mRawData);
 
 
     }
+
     public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
         public SdpRecord createFromParcel(Parcel in) {
             return new SdpRecord(in);
diff --git a/core/java/android/bluetooth/SdpSapsRecord.java b/core/java/android/bluetooth/SdpSapsRecord.java
index 84a29b9..a1e2f7b 100644
--- a/core/java/android/bluetooth/SdpSapsRecord.java
+++ b/core/java/android/bluetooth/SdpSapsRecord.java
@@ -25,23 +25,21 @@
     private final int mProfileVersion;
     private final String mServiceName;
 
-    public SdpSapsRecord(int rfcomm_channel_number,
-            int profile_version,
-            String service_name) {
-        this.mRfcommChannelNumber = rfcomm_channel_number;
-        this.mProfileVersion = profile_version;
-        this.mServiceName = service_name;
+    public SdpSapsRecord(int rfcommChannelNumber, int profileVersion, String serviceName) {
+        mRfcommChannelNumber = rfcommChannelNumber;
+        mProfileVersion = profileVersion;
+        mServiceName = serviceName;
     }
 
     public SdpSapsRecord(Parcel in) {
-        this.mRfcommChannelNumber = in.readInt();
-        this.mProfileVersion = in.readInt();
-        this.mServiceName = in.readString();
+        mRfcommChannelNumber = in.readInt();
+        mProfileVersion = in.readInt();
+        mServiceName = in.readString();
     }
 
     @Override
     public int describeContents() {
-         return 0;
+        return 0;
     }
 
     public int getRfcommCannelNumber() {
@@ -58,9 +56,9 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(this.mRfcommChannelNumber);
-        dest.writeInt(this.mProfileVersion);
-        dest.writeString(this.mServiceName);
+        dest.writeInt(mRfcommChannelNumber);
+        dest.writeInt(mProfileVersion);
+        dest.writeString(mServiceName);
 
     }
 
@@ -84,6 +82,7 @@
         public SdpSapsRecord createFromParcel(Parcel in) {
             return new SdpSapsRecord(in);
         }
+
         public SdpRecord[] newArray(int size) {
             return new SdpRecord[size];
         }
diff --git a/core/java/android/bluetooth/UidTraffic.java b/core/java/android/bluetooth/UidTraffic.java
index 78013cc..cef362b 100644
--- a/core/java/android/bluetooth/UidTraffic.java
+++ b/core/java/android/bluetooth/UidTraffic.java
@@ -20,6 +20,7 @@
 
 /**
  * Record of data traffic (in bytes) by an application identified by its UID.
+ *
  * @hide
  */
 public class UidTraffic implements Cloneable, Parcelable {
@@ -90,11 +91,8 @@
 
     @Override
     public String toString() {
-        return "UidTraffic{" +
-                "mAppUid=" + mAppUid +
-                ", mRxBytes=" + mRxBytes +
-                ", mTxBytes=" + mTxBytes +
-                '}';
+        return "UidTraffic{mAppUid=" + mAppUid + ", mRxBytes=" + mRxBytes + ", mTxBytes="
+                + mTxBytes + '}';
     }
 
     public static final Creator<UidTraffic> CREATOR = new Creator<UidTraffic>() {
diff --git a/core/java/android/bluetooth/le/AdvertiseCallback.java b/core/java/android/bluetooth/le/AdvertiseCallback.java
index 706f469..4fa8c4f 100644
--- a/core/java/android/bluetooth/le/AdvertiseCallback.java
+++ b/core/java/android/bluetooth/le/AdvertiseCallback.java
@@ -58,7 +58,7 @@
      * that the advertising has been started successfully.
      *
      * @param settingsInEffect The actual settings used for advertising, which may be different from
-     *            what has been requested.
+     * what has been requested.
      */
     public void onStartSuccess(AdvertiseSettings settingsInEffect) {
     }
@@ -67,7 +67,7 @@
      * Callback when advertising could not be started.
      *
      * @param errorCode Error code (see ADVERTISE_FAILED_* constants) for advertising start
-     *            failures.
+     * failures.
      */
     public void onStartFailure(int errorCode) {
     }
diff --git a/core/java/android/bluetooth/le/AdvertiseData.java b/core/java/android/bluetooth/le/AdvertiseData.java
index bde2d2f..b65c31d1d 100644
--- a/core/java/android/bluetooth/le/AdvertiseData.java
+++ b/core/java/android/bluetooth/le/AdvertiseData.java
@@ -118,11 +118,12 @@
             return false;
         }
         AdvertiseData other = (AdvertiseData) obj;
-        return Objects.equals(mServiceUuids, other.mServiceUuids) &&
-                BluetoothLeUtils.equals(mManufacturerSpecificData, other.mManufacturerSpecificData) &&
-                BluetoothLeUtils.equals(mServiceData, other.mServiceData) &&
-                        mIncludeDeviceName == other.mIncludeDeviceName &&
-                        mIncludeTxPowerLevel == other.mIncludeTxPowerLevel;
+        return Objects.equals(mServiceUuids, other.mServiceUuids)
+                && BluetoothLeUtils.equals(mManufacturerSpecificData,
+                    other.mManufacturerSpecificData)
+                && BluetoothLeUtils.equals(mServiceData, other.mServiceData)
+                && mIncludeDeviceName == other.mIncludeDeviceName
+                && mIncludeTxPowerLevel == other.mIncludeTxPowerLevel;
     }
 
     @Override
@@ -160,12 +161,12 @@
 
     public static final Parcelable.Creator<AdvertiseData> CREATOR =
             new Creator<AdvertiseData>() {
-            @Override
+                @Override
                 public AdvertiseData[] newArray(int size) {
                     return new AdvertiseData[size];
                 }
 
-            @Override
+                @Override
                 public AdvertiseData createFromParcel(Parcel in) {
                     Builder builder = new Builder();
                     ArrayList<ParcelUuid> uuids = in.createTypedArrayList(ParcelUuid.CREATOR);
@@ -222,7 +223,7 @@
          * @param serviceDataUuid 16-bit UUID of the service the data is associated with
          * @param serviceData Service data
          * @throws IllegalArgumentException If the {@code serviceDataUuid} or {@code serviceData} is
-         *             empty.
+         * empty.
          */
         public Builder addServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) {
             if (serviceDataUuid == null || serviceData == null) {
@@ -242,8 +243,8 @@
          *
          * @param manufacturerId Manufacturer ID assigned by Bluetooth SIG.
          * @param manufacturerSpecificData Manufacturer specific data
-         * @throws IllegalArgumentException If the {@code manufacturerId} is negative or
-         *             {@code manufacturerSpecificData} is null.
+         * @throws IllegalArgumentException If the {@code manufacturerId} is negative or {@code
+         * manufacturerSpecificData} is null.
          */
         public Builder addManufacturerData(int manufacturerId, byte[] manufacturerSpecificData) {
             if (manufacturerId < 0) {
diff --git a/core/java/android/bluetooth/le/AdvertiseSettings.java b/core/java/android/bluetooth/le/AdvertiseSettings.java
index 62c68a4..35e232c7 100644
--- a/core/java/android/bluetooth/le/AdvertiseSettings.java
+++ b/core/java/android/bluetooth/le/AdvertiseSettings.java
@@ -86,7 +86,7 @@
     private AdvertiseSettings(Parcel in) {
         mAdvertiseMode = in.readInt();
         mAdvertiseTxPowerLevel = in.readInt();
-        mAdvertiseConnectable = in.readInt() != 0 ? true : false;
+        mAdvertiseConnectable = in.readInt() != 0;
         mAdvertiseTimeoutMillis = in.readInt();
     }
 
@@ -121,9 +121,9 @@
     @Override
     public String toString() {
         return "Settings [mAdvertiseMode=" + mAdvertiseMode
-             + ", mAdvertiseTxPowerLevel=" + mAdvertiseTxPowerLevel
-             + ", mAdvertiseConnectable=" + mAdvertiseConnectable
-             + ", mAdvertiseTimeoutMillis=" + mAdvertiseTimeoutMillis + "]";
+                + ", mAdvertiseTxPowerLevel=" + mAdvertiseTxPowerLevel
+                + ", mAdvertiseConnectable=" + mAdvertiseConnectable
+                + ", mAdvertiseTimeoutMillis=" + mAdvertiseTimeoutMillis + "]";
     }
 
     @Override
@@ -141,12 +141,12 @@
 
     public static final Parcelable.Creator<AdvertiseSettings> CREATOR =
             new Creator<AdvertiseSettings>() {
-            @Override
+                @Override
                 public AdvertiseSettings[] newArray(int size) {
                     return new AdvertiseSettings[size];
                 }
 
-            @Override
+                @Override
                 public AdvertiseSettings createFromParcel(Parcel in) {
                     return new AdvertiseSettings(in);
                 }
@@ -164,10 +164,10 @@
         /**
          * Set advertise mode to control the advertising power and latency.
          *
-         * @param advertiseMode Bluetooth LE Advertising mode, can only be one of
-         *            {@link AdvertiseSettings#ADVERTISE_MODE_LOW_POWER},
-         *            {@link AdvertiseSettings#ADVERTISE_MODE_BALANCED}, or
-         *            {@link AdvertiseSettings#ADVERTISE_MODE_LOW_LATENCY}.
+         * @param advertiseMode Bluetooth LE Advertising mode, can only be one of {@link
+         * AdvertiseSettings#ADVERTISE_MODE_LOW_POWER},
+         * {@link AdvertiseSettings#ADVERTISE_MODE_BALANCED},
+         * or {@link AdvertiseSettings#ADVERTISE_MODE_LOW_LATENCY}.
          * @throws IllegalArgumentException If the advertiseMode is invalid.
          */
         public Builder setAdvertiseMode(int advertiseMode) {
@@ -183,10 +183,10 @@
          * Set advertise TX power level to control the transmission power level for the advertising.
          *
          * @param txPowerLevel Transmission power of Bluetooth LE Advertising, can only be one of
-         *            {@link AdvertiseSettings#ADVERTISE_TX_POWER_ULTRA_LOW},
-         *            {@link AdvertiseSettings#ADVERTISE_TX_POWER_LOW},
-         *            {@link AdvertiseSettings#ADVERTISE_TX_POWER_MEDIUM} or
-         *            {@link AdvertiseSettings#ADVERTISE_TX_POWER_HIGH}.
+         * {@link AdvertiseSettings#ADVERTISE_TX_POWER_ULTRA_LOW}, {@link
+         * AdvertiseSettings#ADVERTISE_TX_POWER_LOW},
+         * {@link AdvertiseSettings#ADVERTISE_TX_POWER_MEDIUM}
+         * or {@link AdvertiseSettings#ADVERTISE_TX_POWER_HIGH}.
          * @throws IllegalArgumentException If the {@code txPowerLevel} is invalid.
          */
         public Builder setTxPowerLevel(int txPowerLevel) {
@@ -201,8 +201,8 @@
         /**
          * Set whether the advertisement type should be connectable or non-connectable.
          *
-         * @param connectable Controls whether the advertisment type will be connectable (true)
-         *                    or non-connectable (false).
+         * @param connectable Controls whether the advertisment type will be connectable (true) or
+         * non-connectable (false).
          */
         public Builder setConnectable(boolean connectable) {
             mConnectable = connectable;
@@ -211,14 +211,15 @@
 
         /**
          * Limit advertising to a given amount of time.
-         * @param timeoutMillis Advertising time limit. May not exceed 180000 milliseconds.
-         *                       A value of 0 will disable the time limit.
+         *
+         * @param timeoutMillis Advertising time limit. May not exceed 180000 milliseconds. A value
+         * of 0 will disable the time limit.
          * @throws IllegalArgumentException If the provided timeout is over 180000 ms.
          */
         public Builder setTimeout(int timeoutMillis) {
             if (timeoutMillis < 0 || timeoutMillis > LIMITED_ADVERTISING_MAX_MILLIS) {
                 throw new IllegalArgumentException("timeoutMillis invalid (must be 0-"
-                                    + LIMITED_ADVERTISING_MAX_MILLIS + " milliseconds)");
+                        + LIMITED_ADVERTISING_MAX_MILLIS + " milliseconds)");
             }
             mTimeoutMillis = timeoutMillis;
             return this;
diff --git a/core/java/android/bluetooth/le/AdvertisingSet.java b/core/java/android/bluetooth/le/AdvertisingSet.java
index 1bc211c..1df35e1 100644
--- a/core/java/android/bluetooth/le/AdvertisingSet.java
+++ b/core/java/android/bluetooth/le/AdvertisingSet.java
@@ -19,7 +19,6 @@
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.IBluetoothGatt;
 import android.bluetooth.IBluetoothManager;
-import android.bluetooth.le.IAdvertisingSetCallback;
 import android.os.RemoteException;
 import android.util.Log;
 
@@ -37,23 +36,23 @@
 public final class AdvertisingSet {
     private static final String TAG = "AdvertisingSet";
 
-    private final IBluetoothGatt gatt;
-    private int advertiserId;
+    private final IBluetoothGatt mGatt;
+    private int mAdvertiserId;
 
     /* package */ AdvertisingSet(int advertiserId,
-                                 IBluetoothManager bluetoothManager) {
-        this.advertiserId = advertiserId;
+            IBluetoothManager bluetoothManager) {
+        mAdvertiserId = advertiserId;
 
         try {
-          this.gatt = bluetoothManager.getBluetoothGatt();
+            mGatt = bluetoothManager.getBluetoothGatt();
         } catch (RemoteException e) {
-          Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
-          throw new IllegalStateException("Failed to get Bluetooth");
+            Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
+            throw new IllegalStateException("Failed to get Bluetooth");
         }
     }
 
     /* package */ void setAdvertiserId(int advertiserId) {
-      this.advertiserId = advertiserId;
+        mAdvertiserId = advertiserId;
     }
 
     /**
@@ -63,18 +62,17 @@
      * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
      *
      * @param enable whether the advertising should be enabled (true), or disabled (false)
-     * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to
-     *                     65535 (655,350 ms)
+     * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535
+     * (655,350 ms)
      * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
-     *                     controller shall attempt to send prior to terminating the extended
-     *                     advertising, even if the duration has not expired. Valid range is
-     *                     from 1 to 255.
+     * controller shall attempt to send prior to terminating the extended advertising, even if the
+     * duration has not expired. Valid range is from 1 to 255.
      */
     public void enableAdvertising(boolean enable, int duration,
             int maxExtendedAdvertisingEvents) {
         try {
-            gatt.enableAdvertisingSet(this.advertiserId, enable, duration,
-                                      maxExtendedAdvertisingEvents);
+            mGatt.enableAdvertisingSet(mAdvertiserId, enable, duration,
+                    maxExtendedAdvertisingEvents);
         } catch (RemoteException e) {
             Log.e(TAG, "remote exception - ", e);
         }
@@ -87,15 +85,14 @@
      * <p>
      * Advertising data must be empty if non-legacy scannable advertising is used.
      *
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
-     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
-     *                     advertisement is connectable, three bytes will be added for flags. If the
-     *                     update takes place when the advertising set is enabled, the data can be
-     *                     maximum 251 bytes long.
+     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
+     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
+     * three bytes will be added for flags. If the update takes place when the advertising set is
+     * enabled, the data can be maximum 251 bytes long.
      */
     public void setAdvertisingData(AdvertiseData advertiseData) {
         try {
-            gatt.setAdvertisingData(this.advertiserId, advertiseData);
+            mGatt.setAdvertisingData(mAdvertiserId, advertiseData);
         } catch (RemoteException e) {
             Log.e(TAG, "remote exception - ", e);
         }
@@ -107,13 +104,12 @@
      * is delivered through {@code callback.onScanResponseDataSet()}.
      *
      * @param scanResponse Scan response associated with the advertisement data. Size must not
-     *                     exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
-     *                     update takes place when the advertising set is enabled, the data can be
-     *                     maximum 251 bytes long.
+     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the update takes place
+     * when the advertising set is enabled, the data can be maximum 251 bytes long.
      */
     public void setScanResponseData(AdvertiseData scanResponse) {
         try {
-            gatt.setScanResponseData(this.advertiserId, scanResponse);
+            mGatt.setScanResponseData(mAdvertiserId, scanResponse);
         } catch (RemoteException e) {
             Log.e(TAG, "remote exception - ", e);
         }
@@ -128,7 +124,7 @@
      */
     public void setAdvertisingParameters(AdvertisingSetParameters parameters) {
         try {
-            gatt.setAdvertisingParameters(this.advertiserId, parameters);
+            mGatt.setAdvertisingParameters(mAdvertiserId, parameters);
         } catch (RemoteException e) {
             Log.e(TAG, "remote exception - ", e);
         }
@@ -141,7 +137,7 @@
      */
     public void setPeriodicAdvertisingParameters(PeriodicAdvertisingParameters parameters) {
         try {
-            gatt.setPeriodicAdvertisingParameters(this.advertiserId, parameters);
+            mGatt.setPeriodicAdvertisingParameters(mAdvertiserId, parameters);
         } catch (RemoteException e) {
             Log.e(TAG, "remote exception - ", e);
         }
@@ -153,14 +149,13 @@
      * immediately, the operation status is delivered through
      * {@code callback.onPeriodicAdvertisingDataSet()}.
      *
-     * @param periodicData Periodic advertising data. Size must not exceed
-     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
-     *                     update takes place when the periodic advertising is enabled for this set,
-     *                     the data can be maximum 251 bytes long.
+     * @param periodicData Periodic advertising data. Size must not exceed {@link
+     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the update takes place when the
+     * periodic advertising is enabled for this set, the data can be maximum 251 bytes long.
      */
     public void setPeriodicAdvertisingData(AdvertiseData periodicData) {
         try {
-            gatt.setPeriodicAdvertisingData(this.advertiserId, periodicData);
+            mGatt.setPeriodicAdvertisingData(mAdvertiserId, periodicData);
         } catch (RemoteException e) {
             Log.e(TAG, "remote exception - ", e);
         }
@@ -170,11 +165,12 @@
      * Used to enable/disable periodic advertising. This method returns immediately, the operation
      * status is delivered through {@code callback.onPeriodicAdvertisingEnable()}.
      *
-     * @param enable whether the periodic advertising should be enabled (true), or disabled (false).
+     * @param enable whether the periodic advertising should be enabled (true), or disabled
+     * (false).
      */
     public void setPeriodicAdvertisingEnabled(boolean enable) {
         try {
-            gatt.setPeriodicAdvertisingEnable(this.advertiserId, enable);
+            mGatt.setPeriodicAdvertisingEnable(mAdvertiserId, enable);
         } catch (RemoteException e) {
             Log.e(TAG, "remote exception - ", e);
         }
@@ -186,11 +182,12 @@
      * should ever use it.
      *
      * This method requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} permission.
+     *
      * @hide
      */
-    public void getOwnAddress(){
+    public void getOwnAddress() {
         try {
-            gatt.getOwnAddress(this.advertiserId);
+            mGatt.getOwnAddress(mAdvertiserId);
         } catch (RemoteException e) {
             Log.e(TAG, "remote exception - ", e);
         }
@@ -201,7 +198,7 @@
      *
      * @hide
      */
-    public int getAdvertiserId(){
-      return advertiserId;
+    public int getAdvertiserId() {
+        return mAdvertiserId;
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/bluetooth/le/AdvertisingSetCallback.java b/core/java/android/bluetooth/le/AdvertisingSetCallback.java
index c3c16a4..58a3696 100644
--- a/core/java/android/bluetooth/le/AdvertisingSetCallback.java
+++ b/core/java/android/bluetooth/le/AdvertisingSetCallback.java
@@ -16,8 +16,6 @@
 
 package android.bluetooth.le;
 
-import android.bluetooth.BluetoothDevice;
-
 /**
  * Bluetooth LE advertising set callbacks, used to deliver advertising operation
  * status.
@@ -65,7 +63,8 @@
      * @param txPower tx power that will be used for this set.
      * @param status Status of the operation.
      */
-    public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower, int status) {}
+    public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower, int status) {
+    }
 
     /**
      * Callback triggered in response to {@link BluetoothLeAdvertiser#stopAdvertisingSet}
@@ -73,16 +72,19 @@
      *
      * @param advertisingSet The advertising set.
      */
-    public void onAdvertisingSetStopped(AdvertisingSet advertisingSet) {}
+    public void onAdvertisingSetStopped(AdvertisingSet advertisingSet) {
+    }
 
     /**
-     * Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertisingSet} indicating
-     * result of the operation. If status is ADVERTISE_SUCCESS, then advertising set is advertising.
+     * Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertisingSet}
+     * indicating result of the operation. If status is ADVERTISE_SUCCESS, then advertising set is
+     * advertising.
      *
      * @param advertisingSet The advertising set.
      * @param status Status of the operation.
      */
-    public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enable, int status) {}
+    public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enable, int status) {
+    }
 
     /**
      * Callback triggered in response to {@link AdvertisingSet#setAdvertisingData} indicating
@@ -91,7 +93,8 @@
      * @param advertisingSet The advertising set.
      * @param status Status of the operation.
      */
-    public void onAdvertisingDataSet(AdvertisingSet advertisingSet, int status) {}
+    public void onAdvertisingDataSet(AdvertisingSet advertisingSet, int status) {
+    }
 
     /**
      * Callback triggered in response to {@link AdvertisingSet#setAdvertisingData} indicating
@@ -100,7 +103,8 @@
      * @param advertisingSet The advertising set.
      * @param status Status of the operation.
      */
-    public void onScanResponseDataSet(AdvertisingSet advertisingSet, int status) {}
+    public void onScanResponseDataSet(AdvertisingSet advertisingSet, int status) {
+    }
 
     /**
      * Callback triggered in response to {@link AdvertisingSet#setAdvertisingParameters}
@@ -111,7 +115,8 @@
      * @param status Status of the operation.
      */
     public void onAdvertisingParametersUpdated(AdvertisingSet advertisingSet,
-                                               int txPower, int status) {}
+            int txPower, int status) {
+    }
 
     /**
      * Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingParameters}
@@ -120,9 +125,8 @@
      * @param advertisingSet The advertising set.
      * @param status Status of the operation.
      */
-    public void
-    onPeriodicAdvertisingParametersUpdated(AdvertisingSet advertisingSet,
-                                           int status) {}
+    public void onPeriodicAdvertisingParametersUpdated(AdvertisingSet advertisingSet, int status) {
+    }
 
     /**
      * Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingData}
@@ -132,7 +136,8 @@
      * @param status Status of the operation.
      */
     public void onPeriodicAdvertisingDataSet(AdvertisingSet advertisingSet,
-                                             int status) {}
+            int status) {
+    }
 
     /**
      * Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingEnabled}
@@ -142,7 +147,8 @@
      * @param status Status of the operation.
      */
     public void onPeriodicAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enable,
-                                            int status) {}
+            int status) {
+    }
 
     /**
      * Callback triggered in response to {@link AdvertisingSet#getOwnAddress()}
@@ -153,5 +159,6 @@
      * @param address advertising set bluetooth address.
      * @hide
      */
-    public void onOwnAddressRead(AdvertisingSet advertisingSet, int addressType, String address) {}
-}
\ No newline at end of file
+    public void onOwnAddressRead(AdvertisingSet advertisingSet, int addressType, String address) {
+    }
+}
diff --git a/core/java/android/bluetooth/le/AdvertisingSetParameters.java b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
index e9747d8..0c0291eb 100644
--- a/core/java/android/bluetooth/le/AdvertisingSetParameters.java
+++ b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
@@ -31,9 +31,9 @@
 public final class AdvertisingSetParameters implements Parcelable {
 
     /**
-    * Advertise on low frequency, around every 1000ms. This is the default and
-    * preferred advertising mode as it consumes the least power.
-    */
+     * Advertise on low frequency, around every 1000ms. This is the default and
+     * preferred advertising mode as it consumes the least power.
+     */
     public static final int INTERVAL_HIGH = 1600;
 
     /**
@@ -97,156 +97,174 @@
      */
     private static final int LIMITED_ADVERTISING_MAX_MILLIS = 180 * 1000;
 
-    private final boolean isLegacy;
-    private final boolean isAnonymous;
-    private final boolean includeTxPower;
-    private final int primaryPhy;
-    private final int secondaryPhy;
-    private final boolean connectable;
-    private final boolean scannable;
-    private final int interval;
-    private final int txPowerLevel;
+    private final boolean mIsLegacy;
+    private final boolean mIsAnonymous;
+    private final boolean mIncludeTxPower;
+    private final int mPrimaryPhy;
+    private final int mSecondaryPhy;
+    private final boolean mConnectable;
+    private final boolean mScannable;
+    private final int mInterval;
+    private final int mTxPowerLevel;
 
     private AdvertisingSetParameters(boolean connectable, boolean scannable, boolean isLegacy,
-                                     boolean isAnonymous, boolean includeTxPower,
-                                     int primaryPhy, int secondaryPhy,
-                                     int interval, int txPowerLevel) {
-        this.connectable = connectable;
-        this.scannable = scannable;
-        this.isLegacy = isLegacy;
-        this.isAnonymous = isAnonymous;
-        this.includeTxPower = includeTxPower;
-        this.primaryPhy = primaryPhy;
-        this.secondaryPhy = secondaryPhy;
-        this.interval = interval;
-        this.txPowerLevel = txPowerLevel;
+            boolean isAnonymous, boolean includeTxPower,
+            int primaryPhy, int secondaryPhy,
+            int interval, int txPowerLevel) {
+        mConnectable = connectable;
+        mScannable = scannable;
+        mIsLegacy = isLegacy;
+        mIsAnonymous = isAnonymous;
+        mIncludeTxPower = includeTxPower;
+        mPrimaryPhy = primaryPhy;
+        mSecondaryPhy = secondaryPhy;
+        mInterval = interval;
+        mTxPowerLevel = txPowerLevel;
     }
 
     private AdvertisingSetParameters(Parcel in) {
-        connectable = in.readInt() != 0 ? true : false;
-        scannable = in.readInt() != 0 ? true : false;
-        isLegacy = in.readInt() != 0 ? true : false;
-        isAnonymous = in.readInt() != 0 ? true : false;
-        includeTxPower = in.readInt() != 0 ? true : false;
-        primaryPhy = in.readInt();
-        secondaryPhy = in.readInt();
-        interval = in.readInt();
-        txPowerLevel = in.readInt();
+        mConnectable = in.readInt() != 0;
+        mScannable = in.readInt() != 0;
+        mIsLegacy = in.readInt() != 0;
+        mIsAnonymous = in.readInt() != 0;
+        mIncludeTxPower = in.readInt() != 0;
+        mPrimaryPhy = in.readInt();
+        mSecondaryPhy = in.readInt();
+        mInterval = in.readInt();
+        mTxPowerLevel = in.readInt();
     }
 
     /**
      * Returns whether the advertisement will be connectable.
      */
-    public boolean isConnectable() { return connectable; }
+    public boolean isConnectable() {
+        return mConnectable;
+    }
 
     /**
      * Returns whether the advertisement will be scannable.
      */
-    public boolean isScannable() { return scannable; }
+    public boolean isScannable() {
+        return mScannable;
+    }
 
     /**
      * Returns whether the legacy advertisement will be used.
      */
-    public boolean isLegacy() { return isLegacy; }
+    public boolean isLegacy() {
+        return mIsLegacy;
+    }
 
     /**
      * Returns whether the advertisement will be anonymous.
      */
-    public boolean isAnonymous() { return isAnonymous; }
+    public boolean isAnonymous() {
+        return mIsAnonymous;
+    }
 
     /**
      * Returns whether the TX Power will be included.
      */
-    public boolean includeTxPower() { return includeTxPower; }
+    public boolean includeTxPower() {
+        return mIncludeTxPower;
+    }
 
     /**
      * Returns the primary advertising phy.
      */
-    public int getPrimaryPhy() { return primaryPhy; }
+    public int getPrimaryPhy() {
+        return mPrimaryPhy;
+    }
 
     /**
      * Returns the secondary advertising phy.
      */
-    public int getSecondaryPhy() { return secondaryPhy; }
+    public int getSecondaryPhy() {
+        return mSecondaryPhy;
+    }
 
     /**
      * Returns the advertising interval.
      */
-    public int getInterval() { return interval; }
+    public int getInterval() {
+        return mInterval;
+    }
 
     /**
      * Returns the TX power level for advertising.
      */
-    public int getTxPowerLevel() { return txPowerLevel; }
+    public int getTxPowerLevel() {
+        return mTxPowerLevel;
+    }
 
     @Override
     public String toString() {
-        return "AdvertisingSetParameters [connectable=" + connectable
-             + ", isLegacy=" + isLegacy
-             + ", isAnonymous=" + isAnonymous
-             + ", includeTxPower=" + includeTxPower
-             + ", primaryPhy=" + primaryPhy
-             + ", secondaryPhy=" + secondaryPhy
-             + ", interval=" + interval
-             + ", txPowerLevel=" + txPowerLevel + "]";
+        return "AdvertisingSetParameters [connectable=" + mConnectable
+                + ", isLegacy=" + mIsLegacy
+                + ", isAnonymous=" + mIsAnonymous
+                + ", includeTxPower=" + mIncludeTxPower
+                + ", primaryPhy=" + mPrimaryPhy
+                + ", secondaryPhy=" + mSecondaryPhy
+                + ", interval=" + mInterval
+                + ", txPowerLevel=" + mTxPowerLevel + "]";
     }
 
     @Override
     public int describeContents() {
-       return 0;
+        return 0;
     }
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(connectable ? 1 : 0);
-        dest.writeInt(scannable ? 1 : 0);
-        dest.writeInt(isLegacy ? 1 : 0);
-        dest.writeInt(isAnonymous ? 1 : 0);
-        dest.writeInt(includeTxPower ? 1 : 0);
-        dest.writeInt(primaryPhy);
-        dest.writeInt(secondaryPhy);
-        dest.writeInt(interval);
-        dest.writeInt(txPowerLevel);
+        dest.writeInt(mConnectable ? 1 : 0);
+        dest.writeInt(mScannable ? 1 : 0);
+        dest.writeInt(mIsLegacy ? 1 : 0);
+        dest.writeInt(mIsAnonymous ? 1 : 0);
+        dest.writeInt(mIncludeTxPower ? 1 : 0);
+        dest.writeInt(mPrimaryPhy);
+        dest.writeInt(mSecondaryPhy);
+        dest.writeInt(mInterval);
+        dest.writeInt(mTxPowerLevel);
     }
 
     public static final Parcelable.Creator<AdvertisingSetParameters> CREATOR =
-        new Creator<AdvertisingSetParameters>() {
-          @Override
-          public AdvertisingSetParameters[] newArray(int size) {
-            return new AdvertisingSetParameters[size];
-          }
+            new Creator<AdvertisingSetParameters>() {
+                @Override
+                public AdvertisingSetParameters[] newArray(int size) {
+                    return new AdvertisingSetParameters[size];
+                }
 
-          @Override
-          public AdvertisingSetParameters createFromParcel(Parcel in) {
-            return new AdvertisingSetParameters(in);
-          }
-        };
+                @Override
+                public AdvertisingSetParameters createFromParcel(Parcel in) {
+                    return new AdvertisingSetParameters(in);
+                }
+            };
 
     /**
      * Builder class for {@link AdvertisingSetParameters}.
      */
     public static final class Builder {
-
-        private boolean connectable = false;
-        private boolean scannable = false;
-        private boolean isLegacy = false;
-        private boolean isAnonymous = false;
-        private boolean includeTxPower = false;
-        private int primaryPhy = BluetoothDevice.PHY_LE_1M;
-        private int secondaryPhy = BluetoothDevice.PHY_LE_1M;
-        private int interval = INTERVAL_LOW;
-        private int txPowerLevel = TX_POWER_MEDIUM;
+        private boolean mConnectable = false;
+        private boolean mScannable = false;
+        private boolean mIsLegacy = false;
+        private boolean mIsAnonymous = false;
+        private boolean mIncludeTxPower = false;
+        private int mPrimaryPhy = BluetoothDevice.PHY_LE_1M;
+        private int mSecondaryPhy = BluetoothDevice.PHY_LE_1M;
+        private int mInterval = INTERVAL_LOW;
+        private int mTxPowerLevel = TX_POWER_MEDIUM;
 
         /**
          * Set whether the advertisement type should be connectable or
          * non-connectable.
          * Legacy advertisements can be both connectable and scannable. Non-legacy
          * advertisements can be only scannable or only connectable.
-         * @param connectable Controls whether the advertisement type will be
-         * connectable (true) or non-connectable (false).
+         *
+         * @param connectable Controls whether the advertisement type will be connectable (true) or
+         * non-connectable (false).
          */
         public Builder setConnectable(boolean connectable) {
-            this.connectable = connectable;
+            mConnectable = connectable;
             return this;
         }
 
@@ -254,11 +272,12 @@
          * Set whether the advertisement type should be scannable.
          * Legacy advertisements can be both connectable and scannable. Non-legacy
          * advertisements can be only scannable or only connectable.
-         * @param scannable Controls whether the advertisement type will be
-         * scannable (true) or non-scannable (false).
+         *
+         * @param scannable Controls whether the advertisement type will be scannable (true) or
+         * non-scannable (false).
          */
         public Builder setScannable(boolean scannable) {
-            this.scannable = scannable;
+            mScannable = scannable;
             return this;
         }
 
@@ -269,7 +288,7 @@
          * @param isLegacy whether legacy advertising mode should be used.
          */
         public Builder setLegacyMode(boolean isLegacy) {
-            this.isLegacy = isLegacy;
+            mIsLegacy = isLegacy;
             return this;
         }
 
@@ -282,7 +301,7 @@
          * @param isAnonymous whether anonymous advertising should be used.
          */
         public Builder setAnonymous(boolean isAnonymous) {
-            this.isAnonymous = isAnonymous;
+            mIsAnonymous = isAnonymous;
             return this;
         }
 
@@ -291,11 +310,10 @@
          *
          * This is used only if legacy mode is not used.
          *
-         * @param includeTxPower whether TX power should be included in extended
-         *            header
+         * @param includeTxPower whether TX power should be included in extended header
          */
         public Builder setIncludeTxPower(boolean includeTxPower) {
-            this.includeTxPower = includeTxPower;
+            mIncludeTxPower = includeTxPower;
             return this;
         }
 
@@ -306,17 +324,17 @@
          *
          * Use {@link BluetoothAdapter#isLeCodedPhySupported} to determine if LE Coded PHY is
          * supported on this device.
-         * @param primaryPhy Primary advertising physical channel, can only be
-         *            {@link BluetoothDevice#PHY_LE_1M} or
-         *            {@link BluetoothDevice#PHY_LE_CODED}.
+         *
+         * @param primaryPhy Primary advertising physical channel, can only be {@link
+         * BluetoothDevice#PHY_LE_1M} or {@link BluetoothDevice#PHY_LE_CODED}.
          * @throws IllegalArgumentException If the primaryPhy is invalid.
          */
         public Builder setPrimaryPhy(int primaryPhy) {
-            if (primaryPhy != BluetoothDevice.PHY_LE_1M &&
-                primaryPhy != BluetoothDevice.PHY_LE_CODED) {
-               throw new IllegalArgumentException("bad primaryPhy " + primaryPhy);
+            if (primaryPhy != BluetoothDevice.PHY_LE_1M
+                    && primaryPhy != BluetoothDevice.PHY_LE_CODED) {
+                throw new IllegalArgumentException("bad primaryPhy " + primaryPhy);
             }
-            this.primaryPhy = primaryPhy;
+            mPrimaryPhy = primaryPhy;
             return this;
         }
 
@@ -329,95 +347,91 @@
          * {@link BluetoothAdapter#isLe2MPhySupported} to determine if LE Coded PHY or 2M PHY is
          * supported on this device.
          *
-         * @param secondaryPhy Secondary advertising physical channel, can only be
-         *            one of {@link BluetoothDevice#PHY_LE_1M},
-         *            {@link BluetoothDevice#PHY_LE_2M} or
-         *            {@link BluetoothDevice#PHY_LE_CODED}.
+         * @param secondaryPhy Secondary advertising physical channel, can only be one of {@link
+         * BluetoothDevice#PHY_LE_1M}, {@link BluetoothDevice#PHY_LE_2M} or {@link
+         * BluetoothDevice#PHY_LE_CODED}.
          * @throws IllegalArgumentException If the secondaryPhy is invalid.
          */
         public Builder setSecondaryPhy(int secondaryPhy) {
-            if (secondaryPhy != BluetoothDevice.PHY_LE_1M &&
-                secondaryPhy != BluetoothDevice.PHY_LE_2M &&
-                secondaryPhy != BluetoothDevice.PHY_LE_CODED) {
-               throw new IllegalArgumentException("bad secondaryPhy " + secondaryPhy);
+            if (secondaryPhy != BluetoothDevice.PHY_LE_1M
+                    && secondaryPhy != BluetoothDevice.PHY_LE_2M
+                    && secondaryPhy != BluetoothDevice.PHY_LE_CODED) {
+                throw new IllegalArgumentException("bad secondaryPhy " + secondaryPhy);
             }
-            this.secondaryPhy = secondaryPhy;
+            mSecondaryPhy = secondaryPhy;
             return this;
         }
 
         /**
          * Set advertising interval.
          *
-         * @param interval Bluetooth LE Advertising interval, in 0.625ms unit. Valid
-         *            range is from 160 (100ms) to 16777215 (10,485.759375 s).
-         *            Recommended values are:
-         *            {@link AdvertisingSetParameters#INTERVAL_LOW},
-         *            {@link AdvertisingSetParameters#INTERVAL_MEDIUM}, or
-         *            {@link AdvertisingSetParameters#INTERVAL_HIGH}.
+         * @param interval Bluetooth LE Advertising interval, in 0.625ms unit. Valid range is from
+         * 160 (100ms) to 16777215 (10,485.759375 s). Recommended values are: {@link
+         * AdvertisingSetParameters#INTERVAL_LOW}, {@link AdvertisingSetParameters#INTERVAL_MEDIUM},
+         * or {@link AdvertisingSetParameters#INTERVAL_HIGH}.
          * @throws IllegalArgumentException If the interval is invalid.
          */
         public Builder setInterval(int interval) {
             if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
-               throw new IllegalArgumentException("unknown interval " + interval);
+                throw new IllegalArgumentException("unknown interval " + interval);
             }
-            this.interval = interval;
+            mInterval = interval;
             return this;
         }
 
         /**
          * Set the transmission power level for the advertising.
-         * @param txPowerLevel Transmission power of Bluetooth LE Advertising, in
-         *             dBm. The valid range is [-127, 1] Recommended values are:
-         *             {@link AdvertisingSetParameters#TX_POWER_ULTRA_LOW},
-         *             {@link AdvertisingSetParameters#TX_POWER_LOW},
-         *             {@link AdvertisingSetParameters#TX_POWER_MEDIUM}, or
-         *             {@link AdvertisingSetParameters#TX_POWER_HIGH}.
          *
+         * @param txPowerLevel Transmission power of Bluetooth LE Advertising, in dBm. The valid
+         * range is [-127, 1] Recommended values are:
+         * {@link AdvertisingSetParameters#TX_POWER_ULTRA_LOW},
+         * {@link AdvertisingSetParameters#TX_POWER_LOW},
+         * {@link AdvertisingSetParameters#TX_POWER_MEDIUM},
+         * or {@link AdvertisingSetParameters#TX_POWER_HIGH}.
          * @throws IllegalArgumentException If the {@code txPowerLevel} is invalid.
          */
         public Builder setTxPowerLevel(int txPowerLevel) {
             if (txPowerLevel < TX_POWER_MIN || txPowerLevel > TX_POWER_MAX) {
-                throw new IllegalArgumentException("unknown txPowerLevel " +
-                                                   txPowerLevel);
+                throw new IllegalArgumentException("unknown txPowerLevel " + txPowerLevel);
             }
-            this.txPowerLevel = txPowerLevel;
+            mTxPowerLevel = txPowerLevel;
             return this;
         }
 
         /**
          * Build the {@link AdvertisingSetParameters} object.
+         *
          * @throws IllegalStateException if invalid combination of parameters is used.
          */
         public AdvertisingSetParameters build() {
-            if (isLegacy) {
-                if (isAnonymous) {
+            if (mIsLegacy) {
+                if (mIsAnonymous) {
                     throw new IllegalArgumentException("Legacy advertising can't be anonymous");
                 }
 
-                if (connectable == true && scannable == false) {
+                if (mConnectable && !mScannable) {
                     throw new IllegalStateException(
-                        "Legacy advertisement can't be connectable and non-scannable");
+                            "Legacy advertisement can't be connectable and non-scannable");
                 }
 
-                if (includeTxPower) {
+                if (mIncludeTxPower) {
                     throw new IllegalStateException(
-                        "Legacy advertising can't include TX power level in header");
+                            "Legacy advertising can't include TX power level in header");
                 }
             } else {
-                if (connectable && scannable) {
+                if (mConnectable && mScannable) {
                     throw new IllegalStateException(
-                        "Advertising can't be both connectable and scannable");
+                            "Advertising can't be both connectable and scannable");
                 }
 
-                if (isAnonymous && connectable) {
+                if (mIsAnonymous && mConnectable) {
                     throw new IllegalStateException(
-                        "Advertising can't be both connectable and anonymous");
+                            "Advertising can't be both connectable and anonymous");
                 }
             }
 
-            return new AdvertisingSetParameters(connectable, scannable, isLegacy, isAnonymous,
-                                                includeTxPower, primaryPhy,
-                                                secondaryPhy, interval, txPowerLevel);
+            return new AdvertisingSetParameters(mConnectable, mScannable, mIsLegacy, mIsAnonymous,
+                    mIncludeTxPower, mPrimaryPhy, mSecondaryPhy, mInterval, mTxPowerLevel);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index 44c2667..0fb4ba1 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -18,7 +18,6 @@
 
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothGatt;
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.IBluetoothGatt;
 import android.bluetooth.IBluetoothManager;
@@ -31,7 +30,6 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.UUID;
 
 /**
  * This class provides a way to perform Bluetooth LE advertise operations, such as starting and
@@ -117,8 +115,8 @@
                 throw new IllegalArgumentException("callback cannot be null");
             }
             boolean isConnectable = settings.isConnectable();
-            if (totalBytes(advertiseData, isConnectable) > MAX_LEGACY_ADVERTISING_DATA_BYTES ||
-                    totalBytes(scanResponse, false) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
+            if (totalBytes(advertiseData, isConnectable) > MAX_LEGACY_ADVERTISING_DATA_BYTES
+                    || totalBytes(scanResponse, false) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
                 postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE);
                 return;
             }
@@ -152,13 +150,13 @@
             int duration = 0;
             int timeoutMillis = settings.getTimeout();
             if (timeoutMillis > 0) {
-                duration = (timeoutMillis < 10) ? 1 : timeoutMillis/10;
+                duration = (timeoutMillis < 10) ? 1 : timeoutMillis / 10;
             }
 
             AdvertisingSetCallback wrapped = wrapOldCallback(callback, settings);
             mLegacyAdvertisers.put(callback, wrapped);
             startAdvertisingSet(parameters.build(), advertiseData, scanResponse, null, null,
-                                duration, 0, wrapped);
+                    duration, 0, wrapped);
         }
     }
 
@@ -166,7 +164,7 @@
         return new AdvertisingSetCallback() {
             @Override
             public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower,
-                        int status) {
+                    int status) {
                 if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
                     postStartFailure(callback, status);
                     return;
@@ -178,10 +176,10 @@
             /* Legacy advertiser is disabled on timeout */
             @Override
             public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enabled,
-                        int status) {
-                if (enabled == true) {
-                    Log.e(TAG, "Legacy advertiser should be only disabled on timeout," +
-                        " but was enabled!");
+                    int status) {
+                if (enabled) {
+                    Log.e(TAG, "Legacy advertiser should be only disabled on timeout,"
+                            + " but was enabled!");
                     return;
                 }
 
@@ -218,28 +216,28 @@
      * method returns immediately, the operation status is delivered through
      * {@code callback.onAdvertisingSetStarted()}.
      * <p>
+     *
      * @param parameters advertising set parameters.
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
-     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
-     *                     advertisement is connectable, three bytes will be added for flags.
+     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
+     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
+     * three bytes will be added for flags.
      * @param scanResponse Scan response associated with the advertisement data. Size must not
-     *                     exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
+     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
      * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
-     *                     not be started.
-     * @param periodicData Periodic advertising data. Size must not exceed
-     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
+     * not be started.
+     * @param periodicData Periodic advertising data. Size must not exceed {@link
+     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
      * @param callback Callback for advertising set.
      * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
-     *                     size, or unsupported advertising PHY is selected, or when attempt to use
-     *                     Periodic Advertising feature is made when it's not supported by the
-     *                     controller.
+     * size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
+     * feature is made when it's not supported by the controller.
      */
     public void startAdvertisingSet(AdvertisingSetParameters parameters,
-                                    AdvertiseData advertiseData, AdvertiseData scanResponse,
-                                    PeriodicAdvertisingParameters periodicParameters,
-                                    AdvertiseData periodicData, AdvertisingSetCallback callback) {
-            startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
-                            periodicData, 0, 0, callback, new Handler(Looper.getMainLooper()));
+            AdvertiseData advertiseData, AdvertiseData scanResponse,
+            PeriodicAdvertisingParameters periodicParameters,
+            AdvertiseData periodicData, AdvertisingSetCallback callback) {
+        startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
+                periodicData, 0, 0, callback, new Handler(Looper.getMainLooper()));
     }
 
     /**
@@ -247,30 +245,30 @@
      * method returns immediately, the operation status is delivered through
      * {@code callback.onAdvertisingSetStarted()}.
      * <p>
+     *
      * @param parameters advertising set parameters.
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
-     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
-     *                     advertisement is connectable, three bytes will be added for flags.
+     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
+     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
+     * three bytes will be added for flags.
      * @param scanResponse Scan response associated with the advertisement data. Size must not
-     *                     exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
+     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
      * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
-     *                     not be started.
-     * @param periodicData Periodic advertising data. Size must not exceed
-     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
+     * not be started.
+     * @param periodicData Periodic advertising data. Size must not exceed {@link
+     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
      * @param callback Callback for advertising set.
      * @param handler thread upon which the callbacks will be invoked.
      * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
-     *                     size, or unsupported advertising PHY is selected, or when attempt to use
-     *                     Periodic Advertising feature is made when it's not supported by the
-     *                     controller.
+     * size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
+     * feature is made when it's not supported by the controller.
      */
     public void startAdvertisingSet(AdvertisingSetParameters parameters,
-                                    AdvertiseData advertiseData, AdvertiseData scanResponse,
-                                    PeriodicAdvertisingParameters periodicParameters,
-                                    AdvertiseData periodicData, AdvertisingSetCallback callback,
-                                    Handler handler) {
+            AdvertiseData advertiseData, AdvertiseData scanResponse,
+            PeriodicAdvertisingParameters periodicParameters,
+            AdvertiseData periodicData, AdvertisingSetCallback callback,
+            Handler handler) {
         startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
-                            periodicData, 0, 0, callback, handler);
+                periodicData, 0, 0, callback, handler);
     }
 
     /**
@@ -278,37 +276,36 @@
      * method returns immediately, the operation status is delivered through
      * {@code callback.onAdvertisingSetStarted()}.
      * <p>
+     *
      * @param parameters advertising set parameters.
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
-     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
-     *                     advertisement is connectable, three bytes will be added for flags.
+     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
+     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
+     * three bytes will be added for flags.
      * @param scanResponse Scan response associated with the advertisement data. Size must not
-     *                     exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
+     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
      * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
-     *                     not be started.
-     * @param periodicData Periodic advertising data. Size must not exceed
-     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
-     * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to
-     *                     65535 (655,350 ms). 0 means advertising should continue until stopped.
+     * not be started.
+     * @param periodicData Periodic advertising data. Size must not exceed {@link
+     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
+     * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535
+     * (655,350 ms). 0 means advertising should continue until stopped.
      * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
-     *                     controller shall attempt to send prior to terminating the extended
-     *                     advertising, even if the duration has not expired. Valid range is
-     *                     from 1 to 255. 0 means no maximum.
+     * controller shall attempt to send prior to terminating the extended advertising, even if the
+     * duration has not expired. Valid range is from 1 to 255. 0 means no maximum.
      * @param callback Callback for advertising set.
      * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
-     *                     size, or unsupported advertising PHY is selected, or when attempt to use
-     *                     Periodic Advertising feature is made when it's not supported by the
-     *                     controller.
+     * size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
+     * feature is made when it's not supported by the controller.
      */
     public void startAdvertisingSet(AdvertisingSetParameters parameters,
-                                    AdvertiseData advertiseData, AdvertiseData scanResponse,
-                                    PeriodicAdvertisingParameters periodicParameters,
-                                    AdvertiseData periodicData, int duration,
-                                    int maxExtendedAdvertisingEvents,
-                                    AdvertisingSetCallback callback) {
+            AdvertiseData advertiseData, AdvertiseData scanResponse,
+            PeriodicAdvertisingParameters periodicParameters,
+            AdvertiseData periodicData, int duration,
+            int maxExtendedAdvertisingEvents,
+            AdvertisingSetCallback callback) {
         startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
-                            periodicData, duration, maxExtendedAdvertisingEvents, callback,
-                            new Handler(Looper.getMainLooper()));
+                periodicData, duration, maxExtendedAdvertisingEvents, callback,
+                new Handler(Looper.getMainLooper()));
     }
 
     /**
@@ -316,39 +313,39 @@
      * method returns immediately, the operation status is delivered through
      * {@code callback.onAdvertisingSetStarted()}.
      * <p>
+     *
      * @param parameters Advertising set parameters.
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
-     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
-     *                     advertisement is connectable, three bytes will be added for flags.
+     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
+     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
+     * three bytes will be added for flags.
      * @param scanResponse Scan response associated with the advertisement data. Size must not
-     *                     exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}
+     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}
      * @param periodicParameters Periodic advertisng parameters. If null, periodic advertising will
-     *                     not be started.
-     * @param periodicData Periodic advertising data. Size must not exceed
-     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}
-     * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to
-     *                     65535 (655,350 ms). 0 means advertising should continue until stopped.
+     * not be started.
+     * @param periodicData Periodic advertising data. Size must not exceed {@link
+     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}
+     * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535
+     * (655,350 ms). 0 means advertising should continue until stopped.
      * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
-     *                     controller shall attempt to send prior to terminating the extended
-     *                     advertising, even if the duration has not expired. Valid range is
-     *                     from 1 to 255. 0 means no maximum.
+     * controller shall attempt to send prior to terminating the extended advertising, even if the
+     * duration has not expired. Valid range is from 1 to 255. 0 means no maximum.
      * @param callback Callback for advertising set.
      * @param handler Thread upon which the callbacks will be invoked.
      * @throws IllegalArgumentException When any of the data parameter exceed the maximum allowable
-     *                     size, or unsupported advertising PHY is selected, or when attempt to use
-     *                     Periodic Advertising feature is made when it's not supported by the
-     *                     controller, or when maxExtendedAdvertisingEvents is used on a controller
-     *                     that doesn't support the LE Extended Advertising
+     * size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
+     * feature is made when it's not supported by the controller, or when
+     * maxExtendedAdvertisingEvents is used on a controller that doesn't support the LE Extended
+     * Advertising
      */
     public void startAdvertisingSet(AdvertisingSetParameters parameters,
-                                    AdvertiseData advertiseData, AdvertiseData scanResponse,
-                                    PeriodicAdvertisingParameters periodicParameters,
-                                    AdvertiseData periodicData, int duration,
-                                    int maxExtendedAdvertisingEvents, AdvertisingSetCallback callback,
-                                    Handler handler) {
+            AdvertiseData advertiseData, AdvertiseData scanResponse,
+            PeriodicAdvertisingParameters periodicParameters,
+            AdvertiseData periodicData, int duration,
+            int maxExtendedAdvertisingEvents, AdvertisingSetCallback callback,
+            Handler handler) {
         BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
         if (callback == null) {
-          throw new IllegalArgumentException("callback cannot be null");
+            throw new IllegalArgumentException("callback cannot be null");
         }
 
         boolean isConnectable = parameters.isConnectable();
@@ -370,7 +367,7 @@
             }
 
             if ((sphy == BluetoothDevice.PHY_LE_CODED && !supportCodedPhy)
-                || (sphy == BluetoothDevice.PHY_LE_2M && !support2MPhy)) {
+                    || (sphy == BluetoothDevice.PHY_LE_2M && !support2MPhy)) {
                 throw new IllegalArgumentException("Unsupported secondary PHY selected");
             }
 
@@ -390,20 +387,20 @@
             boolean supportPeriodic = mBluetoothAdapter.isLePeriodicAdvertisingSupported();
             if (periodicParameters != null && !supportPeriodic) {
                 throw new IllegalArgumentException(
-                    "Controller does not support LE Periodic Advertising");
+                        "Controller does not support LE Periodic Advertising");
             }
         }
 
         if (maxExtendedAdvertisingEvents < 0 || maxExtendedAdvertisingEvents > 255) {
             throw new IllegalArgumentException(
-                "maxExtendedAdvertisingEvents out of range: " + maxExtendedAdvertisingEvents);
+                    "maxExtendedAdvertisingEvents out of range: " + maxExtendedAdvertisingEvents);
         }
 
-        if (maxExtendedAdvertisingEvents != 0 &&
-            !mBluetoothAdapter.isLePeriodicAdvertisingSupported()) {
+        if (maxExtendedAdvertisingEvents != 0
+                && !mBluetoothAdapter.isLePeriodicAdvertisingSupported()) {
             throw new IllegalArgumentException(
-                "Can't use maxExtendedAdvertisingEvents with controller that don't support " +
-                "LE Extended Advertising");
+                    "Can't use maxExtendedAdvertisingEvents with controller that don't support "
+                            + "LE Extended Advertising");
         }
 
         if (duration < 0 || duration > 65535) {
@@ -412,26 +409,28 @@
 
         IBluetoothGatt gatt;
         try {
-          gatt = mBluetoothManager.getBluetoothGatt();
+            gatt = mBluetoothManager.getBluetoothGatt();
         } catch (RemoteException e) {
-          Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
-          postStartSetFailure(handler, callback, AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
-          return;
+            Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
+            postStartSetFailure(handler, callback,
+                    AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
+            return;
         }
 
         IAdvertisingSetCallback wrapped = wrap(callback, handler);
         if (mCallbackWrappers.putIfAbsent(callback, wrapped) != null) {
             throw new IllegalArgumentException(
-                "callback instance already associated with advertising");
+                    "callback instance already associated with advertising");
         }
 
         try {
             gatt.startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
-                                     periodicData, duration, maxExtendedAdvertisingEvents, wrapped);
+                    periodicData, duration, maxExtendedAdvertisingEvents, wrapped);
         } catch (RemoteException e) {
-          Log.e(TAG, "Failed to start advertising set - ", e);
-          postStartSetFailure(handler, callback, AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
-          return;
+            Log.e(TAG, "Failed to start advertising set - ", e);
+            postStartSetFailure(handler, callback,
+                    AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
+            return;
         }
     }
 
@@ -441,7 +440,7 @@
      */
     public void stopAdvertisingSet(AdvertisingSetCallback callback) {
         if (callback == null) {
-          throw new IllegalArgumentException("callback cannot be null");
+            throw new IllegalArgumentException("callback cannot be null");
         }
 
         IAdvertisingSetCallback wrapped = mCallbackWrappers.remove(callback);
@@ -453,9 +452,9 @@
         try {
             gatt = mBluetoothManager.getBluetoothGatt();
             gatt.stopAdvertisingSet(wrapped);
-       } catch (RemoteException e) {
+        } catch (RemoteException e) {
             Log.e(TAG, "Failed to stop advertising - ", e);
-       }
+        }
     }
 
     /**
@@ -489,18 +488,16 @@
             }
             // 16 bit service uuids are grouped into one field when doing advertising.
             if (num16BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD +
-                        num16BitUuids * BluetoothUuid.UUID_BYTES_16_BIT;
+                size += OVERHEAD_BYTES_PER_FIELD + num16BitUuids * BluetoothUuid.UUID_BYTES_16_BIT;
             }
             // 32 bit service uuids are grouped into one field when doing advertising.
             if (num32BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD +
-                        num32BitUuids * BluetoothUuid.UUID_BYTES_32_BIT;
+                size += OVERHEAD_BYTES_PER_FIELD + num32BitUuids * BluetoothUuid.UUID_BYTES_32_BIT;
             }
             // 128 bit service uuids are grouped into one field when doing advertising.
             if (num128BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD +
-                        num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
+                size += OVERHEAD_BYTES_PER_FIELD
+                        + num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
             }
         }
         for (ParcelUuid uuid : data.getServiceData().keySet()) {
@@ -509,8 +506,8 @@
                     + byteLength(data.getServiceData().get(uuid));
         }
         for (int i = 0; i < data.getManufacturerSpecificData().size(); ++i) {
-            size += OVERHEAD_BYTES_PER_FIELD + MANUFACTURER_SPECIFIC_DATA_LENGTH +
-                    byteLength(data.getManufacturerSpecificData().valueAt(i));
+            size += OVERHEAD_BYTES_PER_FIELD + MANUFACTURER_SPECIFIC_DATA_LENGTH
+                    + byteLength(data.getManufacturerSpecificData().valueAt(i));
         }
         if (data.getIncludeTxPowerLevel()) {
             size += OVERHEAD_BYTES_PER_FIELD + 1; // tx power level value is one byte.
@@ -539,7 +536,7 @@
                         }
 
                         AdvertisingSet advertisingSet =
-                            new AdvertisingSet(advertiserId, mBluetoothManager);
+                                new AdvertisingSet(advertiserId, mBluetoothManager);
                         mAdvertisingSets.put(advertiserId, advertisingSet);
                         callback.onAdvertisingSetStarted(advertisingSet, txPower, status);
                     }
@@ -650,13 +647,13 @@
     }
 
     private void postStartSetFailure(Handler handler, final AdvertisingSetCallback callback,
-        final int error) {
+            final int error) {
         handler.post(new Runnable() {
-              @Override
-              public void run() {
-                  callback.onAdvertisingSetStarted(null, 0, error);
-              }
-          });
+            @Override
+            public void run() {
+                callback.onAdvertisingSetStarted(null, 0, error);
+            }
+        });
     }
 
     private void postStartFailure(final AdvertiseCallback callback, final int error) {
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 1eac395..7fc79d7 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -62,8 +62,8 @@
      * error. In case of error, {@link #EXTRA_ERROR_CODE} will contain the error code and this
      * extra will not be available.
      */
-    public static final String EXTRA_LIST_SCAN_RESULT
-            = "android.bluetooth.le.extra.LIST_SCAN_RESULT";
+    public static final String EXTRA_LIST_SCAN_RESULT =
+            "android.bluetooth.le.extra.LIST_SCAN_RESULT";
 
     /**
      * Optional extra indicating the error code, if any. The error code will be one of the
@@ -74,6 +74,7 @@
     /**
      * Optional extra indicating the callback type, which will be one of
      * CALLBACK_TYPE_* constants in {@link ScanSettings}.
+     *
      * @see ScanCallback#onScanResult(int, ScanResult)
      */
     public static final String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
@@ -98,7 +99,9 @@
 
     /**
      * Start Bluetooth LE scan with default parameters and no filters. The scan results will be
-     * delivered through {@code callback}.
+     * delivered through {@code callback}. For unfiltered scans, scanning is stopped on screen
+     * off to save power. Scanning is resumed when screen is turned on again. To avoid this, use
+     * {@link #startScan(List, ScanSettings, ScanCallback)} with desired {@link ScanFilter}.
      * <p>
      * An app must hold
      * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
@@ -115,6 +118,9 @@
 
     /**
      * Start Bluetooth LE scan. The scan results will be delivered through {@code callback}.
+     * For unfiltered scans, scanning is stopped on screen off to save power. Scanning is
+     * resumed when screen is turned on again. To avoid this, do filetered scanning by
+     * using proper {@link ScanFilter}.
      * <p>
      * An app must hold
      * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
@@ -162,13 +168,13 @@
      * specify on behalf of which application(s) the work is being done.
      *
      * @param workSource {@link WorkSource} identifying the application(s) for which to blame for
-     *                   the scan.
+     * the scan.
      * @param callback Callback used to deliver scan results.
      * @hide
      */
     @SystemApi
     @RequiresPermission(allOf = {
-            Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS })
+            Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS})
     public void startScanFromSource(final WorkSource workSource, final ScanCallback callback) {
         startScanFromSource(null, new ScanSettings.Builder().build(), workSource, callback);
     }
@@ -180,22 +186,22 @@
      * @param filters {@link ScanFilter}s for finding exact BLE devices.
      * @param settings Settings for the scan.
      * @param workSource {@link WorkSource} identifying the application(s) for which to blame for
-     *                   the scan.
+     * the scan.
      * @param callback Callback used to deliver scan results.
      * @hide
      */
     @SystemApi
     @RequiresPermission(allOf = {
-            Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS })
+            Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS})
     public void startScanFromSource(List<ScanFilter> filters, ScanSettings settings,
-                                    final WorkSource workSource, final ScanCallback callback) {
+            final WorkSource workSource, final ScanCallback callback) {
         startScan(filters, settings, workSource, callback, null, null);
     }
 
     private int startScan(List<ScanFilter> filters, ScanSettings settings,
-                           final WorkSource workSource, final ScanCallback callback,
-                           final PendingIntent callbackIntent,
-                           List<List<ResultStorageDescriptor>> resultStorages) {
+            final WorkSource workSource, final ScanCallback callback,
+            final PendingIntent callbackIntent,
+            List<List<ResultStorageDescriptor>> resultStorages) {
         BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
         if (callback == null && callbackIntent == null) {
             throw new IllegalArgumentException("callback is null");
@@ -205,7 +211,8 @@
         }
         synchronized (mLeScanClients) {
             if (callback != null && mLeScanClients.containsKey(callback)) {
-                postCallbackError(callback, ScanCallback.SCAN_FAILED_ALREADY_STARTED);
+                return postCallbackErrorOrReturn(callback,
+                            ScanCallback.SCAN_FAILED_ALREADY_STARTED);
             }
             IBluetoothGatt gatt;
             try {
@@ -218,11 +225,11 @@
             }
             if (!isSettingsConfigAllowedForScan(settings)) {
                 return postCallbackErrorOrReturn(callback,
-                            ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
+                        ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
             }
             if (!isHardwareResourcesAvailableForScan(settings)) {
                 return postCallbackErrorOrReturn(callback,
-                            ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES);
+                        ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES);
             }
             if (!isSettingsAndFilterComboAllowed(settings, filters)) {
                 return postCallbackErrorOrReturn(callback,
@@ -285,7 +292,7 @@
      * will be delivered through the {@code callback}.
      *
      * @param callback Callback of the Bluetooth LE Scan, it has to be the same instance as the one
-     *            used to start scan.
+     * used to start scan.
      */
     public void flushPendingScanResults(ScanCallback callback) {
         BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
@@ -343,6 +350,7 @@
         private List<List<ResultStorageDescriptor>> mResultStorages;
 
         // mLeHandle 0: not registered
+        // -2: registration failed because app is scanning to frequently
         // -1: scan stopped or registration failed
         // > 0: registered and scan started
         private int mScannerId;
@@ -363,7 +371,7 @@
         public void startRegistration() {
             synchronized (this) {
                 // Scan stopped.
-                if (mScannerId == -1) return;
+                if (mScannerId == -1 || mScannerId == -2) return;
                 try {
                     mBluetoothGatt.registerScanner(this, mWorkSource);
                     wait(REGISTRATION_CALLBACK_TIMEOUT_MILLIS);
@@ -377,6 +385,10 @@
                     // Registration timed out or got exception, reset scannerId to -1 so no
                     // subsequent operations can proceed.
                     if (mScannerId == 0) mScannerId = -1;
+
+                    // If scanning too frequently, don't report anything to the app.
+                    if (mScannerId == -2) return;
+
                     postCallbackError(mScanCallback,
                             ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED);
                 }
@@ -418,8 +430,8 @@
          */
         @Override
         public void onScannerRegistered(int status, int scannerId) {
-            Log.d(TAG, "onScannerRegistered() - status=" + status +
-                    " scannerId=" + scannerId + " mScannerId=" + mScannerId);
+            Log.d(TAG, "onScannerRegistered() - status=" + status
+                    + " scannerId=" + scannerId + " mScannerId=" + mScannerId);
             synchronized (this) {
                 if (status == BluetoothGatt.GATT_SUCCESS) {
                     try {
@@ -436,6 +448,9 @@
                         Log.e(TAG, "fail to start le scan: " + e);
                         mScannerId = -1;
                     }
+                } else if (status == ScanCallback.SCAN_FAILED_SCANNING_TOO_FREQUENTLY) {
+                    // applicaiton was scanning too frequently
+                    mScannerId = -2;
                 } else {
                     // registration failed
                     mScannerId = -1;
@@ -480,18 +495,18 @@
         @Override
         public void onFoundOrLost(final boolean onFound, final ScanResult scanResult) {
             if (VDBG) {
-                Log.d(TAG, "onFoundOrLost() - onFound = " + onFound +
-                        " " + scanResult.toString());
+                Log.d(TAG, "onFoundOrLost() - onFound = " + onFound + " " + scanResult.toString());
             }
 
             // Check null in case the scan has been stopped
             synchronized (this) {
-                if (mScannerId <= 0)
+                if (mScannerId <= 0) {
                     return;
+                }
             }
             Handler handler = new Handler(Looper.getMainLooper());
             handler.post(new Runnable() {
-                    @Override
+                @Override
                 public void run() {
                     if (onFound) {
                         mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_FIRST_MATCH,
@@ -510,8 +525,9 @@
                 Log.d(TAG, "onScanManagerErrorCallback() - errorCode = " + errorCode);
             }
             synchronized (this) {
-                if (mScannerId <= 0)
+                if (mScannerId <= 0) {
                     return;
+                }
             }
             postCallbackError(mScanCallback, errorCode);
         }
@@ -549,11 +565,11 @@
     }
 
     private boolean isSettingsAndFilterComboAllowed(ScanSettings settings,
-                        List <ScanFilter> filterList) {
+            List<ScanFilter> filterList) {
         final int callbackType = settings.getCallbackType();
         // If onlost/onfound is requested, a non-empty filter is expected
         if ((callbackType & (ScanSettings.CALLBACK_TYPE_FIRST_MATCH
-                        | ScanSettings.CALLBACK_TYPE_MATCH_LOST)) != 0) {
+                | ScanSettings.CALLBACK_TYPE_MATCH_LOST)) != 0) {
             if (filterList == null) {
                 return false;
             }
@@ -571,8 +587,8 @@
         if ((callbackType & ScanSettings.CALLBACK_TYPE_FIRST_MATCH) != 0
                 || (callbackType & ScanSettings.CALLBACK_TYPE_MATCH_LOST) != 0) {
             // For onlost/onfound, we required hw support be available
-            return (mBluetoothAdapter.isOffloadedFilteringSupported() &&
-                    mBluetoothAdapter.isHardwareTrackingFiltersAvailable());
+            return (mBluetoothAdapter.isOffloadedFilteringSupported()
+                    && mBluetoothAdapter.isHardwareTrackingFiltersAvailable());
         }
         return true;
     }
diff --git a/core/java/android/bluetooth/le/BluetoothLeUtils.java b/core/java/android/bluetooth/le/BluetoothLeUtils.java
index c40256b..6381f55 100644
--- a/core/java/android/bluetooth/le/BluetoothLeUtils.java
+++ b/core/java/android/bluetooth/le/BluetoothLeUtils.java
@@ -92,8 +92,8 @@
 
         // Keys are guaranteed in ascending order when indices are in ascending order.
         for (int i = 0; i < array.size(); ++i) {
-            if (array.keyAt(i) != otherArray.keyAt(i) ||
-                    !Arrays.equals(array.valueAt(i), otherArray.valueAt(i))) {
+            if (array.keyAt(i) != otherArray.keyAt(i)
+                    || !Arrays.equals(array.valueAt(i), otherArray.valueAt(i))) {
                 return false;
             }
         }
@@ -128,11 +128,11 @@
     /**
      * Ensure Bluetooth is turned on.
      *
-     * @throws IllegalStateException If {@code adapter} is null or Bluetooth state is not
-     *             {@link BluetoothAdapter#STATE_ON}.
+     * @throws IllegalStateException If {@code adapter} is null or Bluetooth state is not {@link
+     * BluetoothAdapter#STATE_ON}.
      */
     static void checkAdapterStateOn(BluetoothAdapter adapter) {
-        if (adapter == null || !adapter.isLeEnabled()) {//adapter.getState() != BluetoothAdapter.STATE_ON) {
+        if (adapter == null || !adapter.isLeEnabled()) {
             throw new IllegalStateException("BT Adapter is not turned ON");
         }
     }
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java b/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
index 364b575..14ac911 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
@@ -22,8 +22,8 @@
  * Bluetooth LE periodic advertising callbacks, used to deliver periodic
  * advertising operation status.
  *
- * @see PeriodicAdvertisingManager#createSync
  * @hide
+ * @see PeriodicAdvertisingManager#createSync
  */
 public abstract class PeriodicAdvertisingCallback {
 
@@ -40,7 +40,7 @@
     public static final int SYNC_NO_RESPONSE = 1;
 
     /**
-     *  Sync failed to be established because controller can't support more syncs.
+     * Sync failed to be established because controller can't support more syncs.
      */
     public static final int SYNC_NO_RESOURCES = 2;
 
@@ -51,28 +51,31 @@
      * @param syncHandle handle used to identify this synchronization.
      * @param device remote device.
      * @param advertisingSid synchronized advertising set id.
-     * @param skip  The number of periodic advertising packets that can be skipped
-     * after a successful receive in force. @see PeriodicAdvertisingManager#createSync
-     * @param timeout Synchronization timeout for the periodic advertising in force. One
-     * unit is 10ms. @see PeriodicAdvertisingManager#createSync
+     * @param skip The number of periodic advertising packets that can be skipped after a successful
+     * receive in force. @see PeriodicAdvertisingManager#createSync
+     * @param timeout Synchronization timeout for the periodic advertising in force. One unit is
+     * 10ms. @see PeriodicAdvertisingManager#createSync
      * @param timeout
      * @param status operation status.
      */
     public void onSyncEstablished(int syncHandle, BluetoothDevice device,
-                                  int advertisingSid, int skip, int timeout,
-                                  int status) {}
+            int advertisingSid, int skip, int timeout,
+            int status) {
+    }
 
     /**
      * Callback when periodic advertising report is received.
      *
      * @param report periodic advertising report.
      */
-    public void onPeriodicAdvertisingReport(PeriodicAdvertisingReport report) {}
+    public void onPeriodicAdvertisingReport(PeriodicAdvertisingReport report) {
+    }
 
     /**
      * Callback when periodic advertising synchronization was lost.
      *
      * @param syncHandle handle used to identify this synchronization.
      */
-    public void onSyncLost(int syncHandle) {}
+    public void onSyncLost(int syncHandle) {
+    }
 }
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java b/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
index d9c2d88..0f1a8e9 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
@@ -24,6 +24,7 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.util.Log;
+
 import java.util.IdentityHashMap;
 import java.util.Map;
 
@@ -37,202 +38,207 @@
  * <p>
  * <b>Note:</b> Most of the methods here require
  * {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+ *
  * @hide
  */
 public final class PeriodicAdvertisingManager {
 
-  private static final String TAG = "PeriodicAdvertisingManager";
+    private static final String TAG = "PeriodicAdvertisingManager";
 
-  private static final int SKIP_MIN = 0;
-  private static final int SKIP_MAX = 499;
-  private static final int TIMEOUT_MIN = 10;
-  private static final int TIMEOUT_MAX = 16384;
+    private static final int SKIP_MIN = 0;
+    private static final int SKIP_MAX = 499;
+    private static final int TIMEOUT_MIN = 10;
+    private static final int TIMEOUT_MAX = 16384;
 
-  private static final int SYNC_STARTING = -1;
+    private static final int SYNC_STARTING = -1;
 
-  private final IBluetoothManager mBluetoothManager;
-  private BluetoothAdapter mBluetoothAdapter;
+    private final IBluetoothManager mBluetoothManager;
+    private BluetoothAdapter mBluetoothAdapter;
 
-  /* maps callback, to callback wrapper and sync handle */
-  Map<PeriodicAdvertisingCallback,
-      IPeriodicAdvertisingCallback /* callbackWrapper */> callbackWrappers;
+    /* maps callback, to callback wrapper and sync handle */
+    Map<PeriodicAdvertisingCallback,
+            IPeriodicAdvertisingCallback /* callbackWrapper */> mCallbackWrappers;
 
-  /**
-   * Use {@link BluetoothAdapter#getBluetoothLeScanner()} instead.
-   *
-   * @param bluetoothManager BluetoothManager that conducts overall Bluetooth Management.
-   * @hide
-   */
-  public PeriodicAdvertisingManager(IBluetoothManager bluetoothManager) {
-    mBluetoothManager = bluetoothManager;
-    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-    callbackWrappers = new IdentityHashMap<>();
-  }
-
-  /**
-   * Synchronize with periodic advertising pointed to by the {@code scanResult}.
-   * The {@code scanResult} used must contain a valid advertisingSid. First
-   * call to registerSync will use the {@code skip} and {@code timeout} provided.
-   * Subsequent calls from other apps, trying to sync with same set will reuse
-   * existing sync, thus {@code skip} and {@code timeout} values will not take
-   * effect. The values in effect will be returned in
-   * {@link PeriodicAdvertisingCallback#onSyncEstablished}.
-   *
-   * @param scanResult Scan result containing advertisingSid.
-   * @param skip The number of periodic advertising packets that can be skipped
-   * after a successful receive. Must be between 0 and 499.
-   * @param timeout Synchronization timeout for the periodic advertising. One
-   * unit is 10ms. Must be between 10 (100ms) and 16384 (163.84s).
-   * @param callback Callback used to deliver all operations status.
-   * @throws IllegalArgumentException if {@code scanResult} is null or {@code
-   * skip} is invalid or {@code timeout} is invalid or {@code callback} is null.
-   */
-  public void registerSync(ScanResult scanResult, int skip, int timeout,
-                         PeriodicAdvertisingCallback callback) {
-    registerSync(scanResult, skip, timeout, callback, null);
-  }
-
-  /**
-   * Synchronize with periodic advertising pointed to by the {@code scanResult}.
-   * The {@code scanResult} used must contain a valid advertisingSid. First
-   * call to registerSync will use the {@code skip} and {@code timeout} provided.
-   * Subsequent calls from other apps, trying to sync with same set will reuse
-   * existing sync, thus {@code skip} and {@code timeout} values will not take
-   * effect. The values in effect will be returned in
-   * {@link PeriodicAdvertisingCallback#onSyncEstablished}.
-   *
-   * @param scanResult Scan result containing advertisingSid.
-   * @param skip The number of periodic advertising packets that can be skipped
-   * after a successful receive. Must be between 0 and 499.
-   * @param timeout Synchronization timeout for the periodic advertising. One
-   * unit is 10ms. Must be between 10 (100ms) and 16384 (163.84s).
-   * @param callback Callback used to deliver all operations status.
-   * @param handler thread upon which the callbacks will be invoked.
-   * @throws IllegalArgumentException if {@code scanResult} is null or {@code
-   * skip} is invalid or {@code timeout} is invalid or {@code callback} is null.
-   */
-  public void registerSync(ScanResult scanResult, int skip, int timeout,
-                         PeriodicAdvertisingCallback callback, Handler handler) {
-    if (callback == null) {
-      throw new IllegalArgumentException("callback can't be null");
+    /**
+     * Use {@link BluetoothAdapter#getBluetoothLeScanner()} instead.
+     *
+     * @param bluetoothManager BluetoothManager that conducts overall Bluetooth Management.
+     * @hide
+     */
+    public PeriodicAdvertisingManager(IBluetoothManager bluetoothManager) {
+        mBluetoothManager = bluetoothManager;
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        mCallbackWrappers = new IdentityHashMap<>();
     }
 
-    if (scanResult == null) {
-      throw new IllegalArgumentException("scanResult can't be null");
+    /**
+     * Synchronize with periodic advertising pointed to by the {@code scanResult}.
+     * The {@code scanResult} used must contain a valid advertisingSid. First
+     * call to registerSync will use the {@code skip} and {@code timeout} provided.
+     * Subsequent calls from other apps, trying to sync with same set will reuse
+     * existing sync, thus {@code skip} and {@code timeout} values will not take
+     * effect. The values in effect will be returned in
+     * {@link PeriodicAdvertisingCallback#onSyncEstablished}.
+     *
+     * @param scanResult Scan result containing advertisingSid.
+     * @param skip The number of periodic advertising packets that can be skipped after a successful
+     * receive. Must be between 0 and 499.
+     * @param timeout Synchronization timeout for the periodic advertising. One unit is 10ms. Must
+     * be between 10 (100ms) and 16384 (163.84s).
+     * @param callback Callback used to deliver all operations status.
+     * @throws IllegalArgumentException if {@code scanResult} is null or {@code skip} is invalid or
+     * {@code timeout} is invalid or {@code callback} is null.
+     */
+    public void registerSync(ScanResult scanResult, int skip, int timeout,
+            PeriodicAdvertisingCallback callback) {
+        registerSync(scanResult, skip, timeout, callback, null);
     }
 
-    if (scanResult.getAdvertisingSid() == ScanResult.SID_NOT_PRESENT) {
-      throw new IllegalArgumentException("scanResult must contain a valid sid");
+    /**
+     * Synchronize with periodic advertising pointed to by the {@code scanResult}.
+     * The {@code scanResult} used must contain a valid advertisingSid. First
+     * call to registerSync will use the {@code skip} and {@code timeout} provided.
+     * Subsequent calls from other apps, trying to sync with same set will reuse
+     * existing sync, thus {@code skip} and {@code timeout} values will not take
+     * effect. The values in effect will be returned in
+     * {@link PeriodicAdvertisingCallback#onSyncEstablished}.
+     *
+     * @param scanResult Scan result containing advertisingSid.
+     * @param skip The number of periodic advertising packets that can be skipped after a successful
+     * receive. Must be between 0 and 499.
+     * @param timeout Synchronization timeout for the periodic advertising. One unit is 10ms. Must
+     * be between 10 (100ms) and 16384 (163.84s).
+     * @param callback Callback used to deliver all operations status.
+     * @param handler thread upon which the callbacks will be invoked.
+     * @throws IllegalArgumentException if {@code scanResult} is null or {@code skip} is invalid or
+     * {@code timeout} is invalid or {@code callback} is null.
+     */
+    public void registerSync(ScanResult scanResult, int skip, int timeout,
+            PeriodicAdvertisingCallback callback, Handler handler) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback can't be null");
+        }
+
+        if (scanResult == null) {
+            throw new IllegalArgumentException("scanResult can't be null");
+        }
+
+        if (scanResult.getAdvertisingSid() == ScanResult.SID_NOT_PRESENT) {
+            throw new IllegalArgumentException("scanResult must contain a valid sid");
+        }
+
+        if (skip < SKIP_MIN || skip > SKIP_MAX) {
+            throw new IllegalArgumentException(
+                    "timeout must be between " + TIMEOUT_MIN + " and " + TIMEOUT_MAX);
+        }
+
+        if (timeout < TIMEOUT_MIN || timeout > TIMEOUT_MAX) {
+            throw new IllegalArgumentException(
+                    "timeout must be between " + TIMEOUT_MIN + " and " + TIMEOUT_MAX);
+        }
+
+        IBluetoothGatt gatt;
+        try {
+            gatt = mBluetoothManager.getBluetoothGatt();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
+            callback.onSyncEstablished(0, scanResult.getDevice(), scanResult.getAdvertisingSid(),
+                    skip, timeout,
+                    PeriodicAdvertisingCallback.SYNC_NO_RESOURCES);
+            return;
+        }
+
+        if (handler == null) {
+            handler = new Handler(Looper.getMainLooper());
+        }
+
+        IPeriodicAdvertisingCallback wrapped = wrap(callback, handler);
+        mCallbackWrappers.put(callback, wrapped);
+
+        try {
+            gatt.registerSync(scanResult, skip, timeout, wrapped);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to register sync - ", e);
+            return;
+        }
     }
 
-    if (skip < SKIP_MIN || skip > SKIP_MAX) {
-      throw new IllegalArgumentException(
-          "timeout must be between " + TIMEOUT_MIN + " and " + TIMEOUT_MAX);
+    /**
+     * Cancel pending attempt to create sync, or terminate existing sync.
+     *
+     * @param callback Callback used to deliver all operations status.
+     * @throws IllegalArgumentException if {@code callback} is null, or not a properly registered
+     * callback.
+     */
+    public void unregisterSync(PeriodicAdvertisingCallback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback can't be null");
+        }
+
+        IBluetoothGatt gatt;
+        try {
+            gatt = mBluetoothManager.getBluetoothGatt();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
+            return;
+        }
+
+        IPeriodicAdvertisingCallback wrapper = mCallbackWrappers.remove(callback);
+        if (wrapper == null) {
+            throw new IllegalArgumentException("callback was not properly registered");
+        }
+
+        try {
+            gatt.unregisterSync(wrapper);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to cancel sync creation - ", e);
+            return;
+        }
     }
 
-    if (timeout < TIMEOUT_MIN || timeout > TIMEOUT_MAX) {
-      throw new IllegalArgumentException(
-          "timeout must be between " + TIMEOUT_MIN + " and " + TIMEOUT_MAX);
+    private IPeriodicAdvertisingCallback wrap(PeriodicAdvertisingCallback callback,
+            Handler handler) {
+        return new IPeriodicAdvertisingCallback.Stub() {
+            public void onSyncEstablished(int syncHandle, BluetoothDevice device,
+                    int advertisingSid, int skip, int timeout, int status) {
+
+                handler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        callback.onSyncEstablished(syncHandle, device, advertisingSid, skip,
+                                timeout,
+                                status);
+
+                        if (status != PeriodicAdvertisingCallback.SYNC_SUCCESS) {
+                            // App can still unregister the sync until notified it failed. Remove
+                            // callback
+                            // after app was notifed.
+                            mCallbackWrappers.remove(callback);
+                        }
+                    }
+                });
+            }
+
+            public void onPeriodicAdvertisingReport(PeriodicAdvertisingReport report) {
+                handler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        callback.onPeriodicAdvertisingReport(report);
+                    }
+                });
+            }
+
+            public void onSyncLost(int syncHandle) {
+                handler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        callback.onSyncLost(syncHandle);
+                        // App can still unregister the sync until notified it's lost.
+                        // Remove callback after app was notifed.
+                        mCallbackWrappers.remove(callback);
+                    }
+                });
+            }
+        };
     }
-
-    IBluetoothGatt gatt;
-    try {
-        gatt = mBluetoothManager.getBluetoothGatt();
-    } catch (RemoteException e) {
-        Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
-        callback.onSyncEstablished(0, scanResult.getDevice(), scanResult.getAdvertisingSid(),
-                                   skip, timeout,
-                                   PeriodicAdvertisingCallback.SYNC_NO_RESOURCES);
-        return;
-    }
-
-    if (handler == null)
-      handler = new Handler(Looper.getMainLooper());
-
-    IPeriodicAdvertisingCallback wrapped = wrap(callback, handler);
-    callbackWrappers.put(callback, wrapped);
-
-    try {
-      gatt.registerSync(scanResult, skip, timeout, wrapped);
-    } catch (RemoteException e) {
-      Log.e(TAG, "Failed to register sync - ", e);
-      return;
-    }
-  }
-
-  /**
-   * Cancel pending attempt to create sync, or terminate existing sync.
-   *
-   * @param callback Callback used to deliver all operations status.
-   * @throws IllegalArgumentException if {@code callback} is null, or not a properly
-   * registered callback.
-   */
-  public void unregisterSync(PeriodicAdvertisingCallback callback) {
-    if (callback == null) {
-      throw new IllegalArgumentException("callback can't be null");
-    }
-
-    IBluetoothGatt gatt;
-    try {
-        gatt = mBluetoothManager.getBluetoothGatt();
-    } catch (RemoteException e) {
-        Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
-        return;
-    }
-
-    IPeriodicAdvertisingCallback wrapper = callbackWrappers.remove(callback);
-    if (wrapper == null) {
-      throw new IllegalArgumentException("callback was not properly registered");
-    }
-
-    try {
-      gatt.unregisterSync(wrapper);
-    } catch (RemoteException e) {
-        Log.e(TAG, "Failed to cancel sync creation - ", e);
-        return;
-    }
-  }
-
-  private IPeriodicAdvertisingCallback wrap(PeriodicAdvertisingCallback callback, Handler handler) {
-    return new IPeriodicAdvertisingCallback.Stub() {
-      public void onSyncEstablished(int syncHandle, BluetoothDevice device,
-                                    int advertisingSid, int skip, int timeout, int status) {
-
-          handler.post(new Runnable() {
-              @Override
-              public void run() {
-                  callback.onSyncEstablished(syncHandle, device, advertisingSid, skip, timeout,
-                                             status);
-
-                  if (status != PeriodicAdvertisingCallback.SYNC_SUCCESS) {
-                      // App can still unregister the sync until notified it failed. Remove callback
-                      // after app was notifed.
-                      callbackWrappers.remove(callback);
-                  }
-              }
-          });
-      }
-
-      public void onPeriodicAdvertisingReport(PeriodicAdvertisingReport report) {
-          handler.post(new Runnable() {
-              @Override
-              public void run() {
-                callback.onPeriodicAdvertisingReport(report);
-              }
-          });
-      }
-
-      public void onSyncLost(int syncHandle) {
-          handler.post(new Runnable() {
-              @Override
-              public void run() {
-                callback.onSyncLost(syncHandle);
-                // App can still unregister the sync until notified it's lost. Remove callback after
-                // app was notifed.
-                callbackWrappers.remove(callback);
-              }
-          });
-      }
-    };
-  }
 }
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
index cf8f08f..e3a130c 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
@@ -29,29 +29,33 @@
     private static final int INTERVAL_MIN = 80;
     private static final int INTERVAL_MAX = 65519;
 
-    private final boolean includeTxPower;
-    private final int interval;
+    private final boolean mIncludeTxPower;
+    private final int mInterval;
 
     private PeriodicAdvertisingParameters(boolean includeTxPower, int interval) {
-        this.includeTxPower = includeTxPower;
-        this.interval = interval;
+        mIncludeTxPower = includeTxPower;
+        mInterval = interval;
     }
 
     private PeriodicAdvertisingParameters(Parcel in) {
-        includeTxPower = in.readInt() != 0 ? true : false;
-        interval = in.readInt();
+        mIncludeTxPower = in.readInt() != 0;
+        mInterval = in.readInt();
     }
 
     /**
      * Returns whether the TX Power will be included.
      */
-    public boolean getIncludeTxPower() { return includeTxPower; }
+    public boolean getIncludeTxPower() {
+        return mIncludeTxPower;
+    }
 
     /**
      * Returns the periodic advertising interval, in 1.25ms unit.
      * Valid values are from 80 (100ms) to 65519 (81.89875s).
      */
-    public int getInterval() { return interval; }
+    public int getInterval() {
+        return mInterval;
+    }
 
     @Override
     public int describeContents() {
@@ -60,34 +64,34 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(includeTxPower ? 1 : 0);
-        dest.writeInt(interval);
+        dest.writeInt(mIncludeTxPower ? 1 : 0);
+        dest.writeInt(mInterval);
     }
 
     public static final Parcelable
-        .Creator<PeriodicAdvertisingParameters> CREATOR =
-        new Creator<PeriodicAdvertisingParameters>() {
-            @Override
-            public PeriodicAdvertisingParameters[] newArray(int size) {
-                return new PeriodicAdvertisingParameters[size];
-            }
+            .Creator<PeriodicAdvertisingParameters> CREATOR =
+            new Creator<PeriodicAdvertisingParameters>() {
+                @Override
+                public PeriodicAdvertisingParameters[] newArray(int size) {
+                    return new PeriodicAdvertisingParameters[size];
+                }
 
-            @Override
-            public PeriodicAdvertisingParameters createFromParcel(Parcel in) {
-                return new PeriodicAdvertisingParameters(in);
-            }
-        };
+                @Override
+                public PeriodicAdvertisingParameters createFromParcel(Parcel in) {
+                    return new PeriodicAdvertisingParameters(in);
+                }
+            };
 
     public static final class Builder {
-        private boolean includeTxPower = false;
-        private int interval = INTERVAL_MAX;
+        private boolean mIncludeTxPower = false;
+        private int mInterval = INTERVAL_MAX;
 
         /**
          * Whether the transmission power level should be included in the periodic
          * packet.
          */
         public Builder setIncludeTxPower(boolean includeTxPower) {
-            this.includeTxPower = includeTxPower;
+            mIncludeTxPower = includeTxPower;
             return this;
         }
 
@@ -95,14 +99,15 @@
          * Set advertising interval for periodic advertising, in 1.25ms unit.
          * Valid values are from 80 (100ms) to 65519 (81.89875s).
          * Value from range [interval, interval+20ms] will be picked as the actual value.
+         *
          * @throws IllegalArgumentException If the interval is invalid.
          */
         public Builder setInterval(int interval) {
             if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
-                throw new IllegalArgumentException("Invalid interval (must be " + INTERVAL_MIN +
-                                                   "-" + INTERVAL_MAX + ")");
+                throw new IllegalArgumentException("Invalid interval (must be " + INTERVAL_MIN
+                        + "-" + INTERVAL_MAX + ")");
             }
-            this.interval = interval;
+            mInterval = interval;
             return this;
         }
 
@@ -110,7 +115,7 @@
          * Build the {@link AdvertisingSetParameters} object.
          */
         public PeriodicAdvertisingParameters build() {
-            return new PeriodicAdvertisingParameters(includeTxPower, interval);
+            return new PeriodicAdvertisingParameters(mIncludeTxPower, mInterval);
         }
     }
 }
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java b/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
index 51b93cb..55c3a73 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
@@ -24,6 +24,7 @@
 
 /**
  * PeriodicAdvertisingReport for Bluetooth LE synchronized advertising.
+ *
  * @hide
  */
 public final class PeriodicAdvertisingReport implements Parcelable {
@@ -39,29 +40,28 @@
      */
     public static final int DATA_INCOMPLETE_TRUNCATED = 2;
 
-    private int syncHandle;
-    private int txPower;
-    private int rssi;
-    private int dataStatus;
+    private int mSyncHandle;
+    private int mTxPower;
+    private int mRssi;
+    private int mDataStatus;
 
     // periodic advertising data.
     @Nullable
-    private ScanRecord data;
+    private ScanRecord mData;
 
     // Device timestamp when the result was last seen.
-    private long timestampNanos;
+    private long mTimestampNanos;
 
     /**
      * Constructor of periodic advertising result.
-     *
      */
     public PeriodicAdvertisingReport(int syncHandle, int txPower, int rssi,
-                                     int dataStatus, ScanRecord data) {
-        this.syncHandle = syncHandle;
-        this.txPower = txPower;
-        this.rssi = rssi;
-        this.dataStatus = dataStatus;
-        this.data = data;
+            int dataStatus, ScanRecord data) {
+        mSyncHandle = syncHandle;
+        mTxPower = txPower;
+        mRssi = rssi;
+        mDataStatus = dataStatus;
+        mData = data;
     }
 
     private PeriodicAdvertisingReport(Parcel in) {
@@ -70,25 +70,25 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(syncHandle);
-        dest.writeLong(txPower);
-        dest.writeInt(rssi);
-        dest.writeInt(dataStatus);
-        if (data != null) {
+        dest.writeInt(mSyncHandle);
+        dest.writeLong(mTxPower);
+        dest.writeInt(mRssi);
+        dest.writeInt(mDataStatus);
+        if (mData != null) {
             dest.writeInt(1);
-            dest.writeByteArray(data.getBytes());
+            dest.writeByteArray(mData.getBytes());
         } else {
             dest.writeInt(0);
         }
     }
 
     private void readFromParcel(Parcel in) {
-        syncHandle = in.readInt();
-        txPower = in.readInt();
-        rssi = in.readInt();
-        dataStatus = in.readInt();
+        mSyncHandle = in.readInt();
+        mTxPower = in.readInt();
+        mRssi = in.readInt();
+        mDataStatus = in.readInt();
         if (in.readInt() == 1) {
-            data = ScanRecord.parseFromBytes(in.createByteArray());
+            mData = ScanRecord.parseFromBytes(in.createByteArray());
         }
     }
 
@@ -101,7 +101,7 @@
      * Returns the synchronization handle.
      */
     public int getSyncHandle() {
-        return syncHandle;
+        return mSyncHandle;
     }
 
     /**
@@ -109,14 +109,14 @@
      * of 127 means information was not available.
      */
     public int getTxPower() {
-        return txPower;
+        return mTxPower;
     }
 
     /**
      * Returns the received signal strength in dBm. The valid range is [-127, 20].
      */
     public int getRssi() {
-        return rssi;
+        return mRssi;
     }
 
     /**
@@ -124,7 +124,7 @@
      * or {@link PeriodicAdvertisingReport#DATA_INCOMPLETE_TRUNCATED}.
      */
     public int getDataStatus() {
-        return dataStatus;
+        return mDataStatus;
     }
 
     /**
@@ -132,19 +132,19 @@
      */
     @Nullable
     public ScanRecord getData() {
-        return data;
+        return mData;
     }
 
     /**
      * Returns timestamp since boot when the scan record was observed.
      */
     public long getTimestampNanos() {
-        return timestampNanos;
+        return mTimestampNanos;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(syncHandle, txPower, rssi, dataStatus, data, timestampNanos);
+        return Objects.hash(mSyncHandle, mTxPower, mRssi, mDataStatus, mData, mTimestampNanos);
     }
 
     @Override
@@ -156,30 +156,31 @@
             return false;
         }
         PeriodicAdvertisingReport other = (PeriodicAdvertisingReport) obj;
-        return (syncHandle == other.syncHandle) &&
-            (txPower == other.txPower) &&
-            (rssi == other.rssi) &&
-            (dataStatus == other.dataStatus) &&
-            Objects.equals(data, other.data) &&
-            (timestampNanos == other.timestampNanos);
+        return (mSyncHandle == other.mSyncHandle)
+                && (mTxPower == other.mTxPower)
+                && (mRssi == other.mRssi)
+                && (mDataStatus == other.mDataStatus)
+                && Objects.equals(mData, other.mData)
+                && (mTimestampNanos == other.mTimestampNanos);
     }
 
     @Override
     public String toString() {
-      return "PeriodicAdvertisingReport{syncHandle=" + syncHandle +
-          ", txPower=" + txPower + ", rssi=" + rssi + ", dataStatus=" + dataStatus +
-          ", data=" + Objects.toString(data) + ", timestampNanos=" + timestampNanos + '}';
+        return "PeriodicAdvertisingReport{syncHandle=" + mSyncHandle
+                + ", txPower=" + mTxPower + ", rssi=" + mRssi + ", dataStatus=" + mDataStatus
+                + ", data=" + Objects.toString(mData) + ", timestampNanos=" + mTimestampNanos + '}';
     }
 
-    public static final Parcelable.Creator<PeriodicAdvertisingReport> CREATOR = new Creator<PeriodicAdvertisingReport>() {
-            @Override
-        public PeriodicAdvertisingReport createFromParcel(Parcel source) {
-            return new PeriodicAdvertisingReport(source);
-        }
+    public static final Parcelable.Creator<PeriodicAdvertisingReport> CREATOR =
+            new Creator<PeriodicAdvertisingReport>() {
+                @Override
+                public PeriodicAdvertisingReport createFromParcel(Parcel source) {
+                    return new PeriodicAdvertisingReport(source);
+                }
 
-            @Override
-        public PeriodicAdvertisingReport[] newArray(int size) {
-            return new PeriodicAdvertisingReport[size];
-        }
-    };
+                @Override
+                public PeriodicAdvertisingReport[] newArray(int size) {
+                    return new PeriodicAdvertisingReport[size];
+                }
+            };
 }
diff --git a/core/java/android/bluetooth/le/ResultStorageDescriptor.java b/core/java/android/bluetooth/le/ResultStorageDescriptor.java
index 748f97d..63bdf69 100644
--- a/core/java/android/bluetooth/le/ResultStorageDescriptor.java
+++ b/core/java/android/bluetooth/le/ResultStorageDescriptor.java
@@ -78,16 +78,16 @@
         mLength = in.readInt();
     }
 
-    public static final Parcelable.Creator<ResultStorageDescriptor>
-            CREATOR = new Creator<ResultStorageDescriptor>() {
-                    @Override
-                public ResultStorageDescriptor createFromParcel(Parcel source) {
-                    return new ResultStorageDescriptor(source);
-                }
+    public static final Parcelable.Creator<ResultStorageDescriptor> CREATOR =
+            new Creator<ResultStorageDescriptor>() {
+        @Override
+        public ResultStorageDescriptor createFromParcel(Parcel source) {
+            return new ResultStorageDescriptor(source);
+        }
 
-                    @Override
-                public ResultStorageDescriptor[] newArray(int size) {
-                    return new ResultStorageDescriptor[size];
-                }
-            };
+        @Override
+        public ResultStorageDescriptor[] newArray(int size) {
+            return new ResultStorageDescriptor[size];
+        }
+    };
 }
diff --git a/core/java/android/bluetooth/le/ScanCallback.java b/core/java/android/bluetooth/le/ScanCallback.java
index aff2e90..53d9310 100644
--- a/core/java/android/bluetooth/le/ScanCallback.java
+++ b/core/java/android/bluetooth/le/ScanCallback.java
@@ -46,19 +46,25 @@
 
     /**
      * Fails to start scan as it is out of hardware resources.
+     *
      * @hide
      */
     public static final int SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES = 5;
 
+    /**
+     * Fails to start scan as application tries to scan too frequently.
+     * @hide
+     */
+    public static final int SCAN_FAILED_SCANNING_TOO_FREQUENTLY = 6;
+
     static final int NO_ERROR = 0;
 
     /**
      * Callback when a BLE advertisement has been found.
      *
-     * @param callbackType Determines how this callback was triggered. Could be one of
-     *            {@link ScanSettings#CALLBACK_TYPE_ALL_MATCHES},
-     *            {@link ScanSettings#CALLBACK_TYPE_FIRST_MATCH} or
-     *            {@link ScanSettings#CALLBACK_TYPE_MATCH_LOST}
+     * @param callbackType Determines how this callback was triggered. Could be one of {@link
+     * ScanSettings#CALLBACK_TYPE_ALL_MATCHES}, {@link ScanSettings#CALLBACK_TYPE_FIRST_MATCH} or
+     * {@link ScanSettings#CALLBACK_TYPE_MATCH_LOST}
      * @param result A Bluetooth LE scan result.
      */
     public void onScanResult(int callbackType, ScanResult result) {
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index 457096b..c3fae7d 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -71,7 +71,7 @@
     private final byte[] mManufacturerDataMask;
 
     /** @hide */
-    public static final ScanFilter EMPTY = new ScanFilter.Builder().build() ;
+    public static final ScanFilter EMPTY = new ScanFilter.Builder().build();
 
 
     private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
@@ -145,70 +145,70 @@
     /**
      * A {@link android.os.Parcelable.Creator} to create {@link ScanFilter} from parcel.
      */
-    public static final Creator<ScanFilter>
-            CREATOR = new Creator<ScanFilter>() {
+    public static final Creator<ScanFilter> CREATOR =
+            new Creator<ScanFilter>() {
 
-                    @Override
-                public ScanFilter[] newArray(int size) {
-                    return new ScanFilter[size];
+        @Override
+        public ScanFilter[] newArray(int size) {
+            return new ScanFilter[size];
+        }
+
+        @Override
+        public ScanFilter createFromParcel(Parcel in) {
+            Builder builder = new Builder();
+            if (in.readInt() == 1) {
+                builder.setDeviceName(in.readString());
+            }
+            if (in.readInt() == 1) {
+                builder.setDeviceAddress(in.readString());
+            }
+            if (in.readInt() == 1) {
+                ParcelUuid uuid = in.readParcelable(ParcelUuid.class.getClassLoader());
+                builder.setServiceUuid(uuid);
+                if (in.readInt() == 1) {
+                    ParcelUuid uuidMask = in.readParcelable(
+                            ParcelUuid.class.getClassLoader());
+                    builder.setServiceUuid(uuid, uuidMask);
                 }
-
-                    @Override
-                public ScanFilter createFromParcel(Parcel in) {
-                    Builder builder = new Builder();
-                    if (in.readInt() == 1) {
-                        builder.setDeviceName(in.readString());
+            }
+            if (in.readInt() == 1) {
+                ParcelUuid servcieDataUuid =
+                        in.readParcelable(ParcelUuid.class.getClassLoader());
+                if (in.readInt() == 1) {
+                    int serviceDataLength = in.readInt();
+                    byte[] serviceData = new byte[serviceDataLength];
+                    in.readByteArray(serviceData);
+                    if (in.readInt() == 0) {
+                        builder.setServiceData(servcieDataUuid, serviceData);
+                    } else {
+                        int serviceDataMaskLength = in.readInt();
+                        byte[] serviceDataMask = new byte[serviceDataMaskLength];
+                        in.readByteArray(serviceDataMask);
+                        builder.setServiceData(
+                                servcieDataUuid, serviceData, serviceDataMask);
                     }
-                    if (in.readInt() == 1) {
-                        builder.setDeviceAddress(in.readString());
-                    }
-                    if (in.readInt() == 1) {
-                        ParcelUuid uuid = in.readParcelable(ParcelUuid.class.getClassLoader());
-                        builder.setServiceUuid(uuid);
-                        if (in.readInt() == 1) {
-                            ParcelUuid uuidMask = in.readParcelable(
-                                    ParcelUuid.class.getClassLoader());
-                            builder.setServiceUuid(uuid, uuidMask);
-                        }
-                    }
-                    if (in.readInt() == 1) {
-                        ParcelUuid servcieDataUuid =
-                                in.readParcelable(ParcelUuid.class.getClassLoader());
-                        if (in.readInt() == 1) {
-                            int serviceDataLength = in.readInt();
-                            byte[] serviceData = new byte[serviceDataLength];
-                            in.readByteArray(serviceData);
-                            if (in.readInt() == 0) {
-                                builder.setServiceData(servcieDataUuid, serviceData);
-                            } else {
-                                int serviceDataMaskLength = in.readInt();
-                                byte[] serviceDataMask = new byte[serviceDataMaskLength];
-                                in.readByteArray(serviceDataMask);
-                                builder.setServiceData(
-                                        servcieDataUuid, serviceData, serviceDataMask);
-                            }
-                        }
-                    }
-
-                    int manufacturerId = in.readInt();
-                    if (in.readInt() == 1) {
-                        int manufacturerDataLength = in.readInt();
-                        byte[] manufacturerData = new byte[manufacturerDataLength];
-                        in.readByteArray(manufacturerData);
-                        if (in.readInt() == 0) {
-                            builder.setManufacturerData(manufacturerId, manufacturerData);
-                        } else {
-                            int manufacturerDataMaskLength = in.readInt();
-                            byte[] manufacturerDataMask = new byte[manufacturerDataMaskLength];
-                            in.readByteArray(manufacturerDataMask);
-                            builder.setManufacturerData(manufacturerId, manufacturerData,
-                                    manufacturerDataMask);
-                        }
-                    }
-
-                    return builder.build();
                 }
-            };
+            }
+
+            int manufacturerId = in.readInt();
+            if (in.readInt() == 1) {
+                int manufacturerDataLength = in.readInt();
+                byte[] manufacturerData = new byte[manufacturerDataLength];
+                in.readByteArray(manufacturerData);
+                if (in.readInt() == 0) {
+                    builder.setManufacturerData(manufacturerId, manufacturerData);
+                } else {
+                    int manufacturerDataMaskLength = in.readInt();
+                    byte[] manufacturerDataMask = new byte[manufacturerDataMaskLength];
+                    in.readByteArray(manufacturerDataMask);
+                    builder.setManufacturerData(manufacturerId, manufacturerData,
+                            manufacturerDataMask);
+                }
+            }
+
+            return builder.build();
+        }
+    };
 
     /**
      * Returns the filter set the device name field of Bluetooth advertisement data.
@@ -288,7 +288,7 @@
         // Scan record is null but there exist filters on it.
         if (scanRecord == null
                 && (mDeviceName != null || mServiceUuid != null || mManufacturerData != null
-                        || mServiceData != null)) {
+                || mServiceData != null)) {
             return false;
         }
 
@@ -386,12 +386,12 @@
     @Override
     public int hashCode() {
         return Objects.hash(mDeviceName, mDeviceAddress, mManufacturerId,
-                            Arrays.hashCode(mManufacturerData),
-                            Arrays.hashCode(mManufacturerDataMask),
-                            mServiceDataUuid,
-                            Arrays.hashCode(mServiceData),
-                            Arrays.hashCode(mServiceDataMask),
-                            mServiceUuid, mServiceUuidMask);
+                Arrays.hashCode(mManufacturerData),
+                Arrays.hashCode(mManufacturerDataMask),
+                mServiceDataUuid,
+                Arrays.hashCode(mServiceData),
+                Arrays.hashCode(mServiceDataMask),
+                mServiceUuid, mServiceUuidMask);
     }
 
     @Override
@@ -403,20 +403,21 @@
             return false;
         }
         ScanFilter other = (ScanFilter) obj;
-        return Objects.equals(mDeviceName, other.mDeviceName) &&
-                Objects.equals(mDeviceAddress, other.mDeviceAddress) &&
-                mManufacturerId == other.mManufacturerId &&
-                Objects.deepEquals(mManufacturerData, other.mManufacturerData) &&
-                Objects.deepEquals(mManufacturerDataMask, other.mManufacturerDataMask) &&
-                Objects.equals(mServiceDataUuid, other.mServiceDataUuid) &&
-                Objects.deepEquals(mServiceData, other.mServiceData) &&
-                Objects.deepEquals(mServiceDataMask, other.mServiceDataMask) &&
-                Objects.equals(mServiceUuid, other.mServiceUuid) &&
-                Objects.equals(mServiceUuidMask, other.mServiceUuidMask);
+        return Objects.equals(mDeviceName, other.mDeviceName)
+                && Objects.equals(mDeviceAddress, other.mDeviceAddress)
+                && mManufacturerId == other.mManufacturerId
+                && Objects.deepEquals(mManufacturerData, other.mManufacturerData)
+                && Objects.deepEquals(mManufacturerDataMask, other.mManufacturerDataMask)
+                && Objects.equals(mServiceDataUuid, other.mServiceDataUuid)
+                && Objects.deepEquals(mServiceData, other.mServiceData)
+                && Objects.deepEquals(mServiceDataMask, other.mServiceDataMask)
+                && Objects.equals(mServiceUuid, other.mServiceUuid)
+                && Objects.equals(mServiceUuidMask, other.mServiceUuidMask);
     }
 
     /**
      * Checks if the scanfilter is empty
+     *
      * @hide
      */
     public boolean isAllFieldsEmpty() {
@@ -454,8 +455,8 @@
          * Set filter on device address.
          *
          * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
-         *            format of "01:02:03:AB:CD:EF". The device address can be validated using
-         *            {@link BluetoothAdapter#checkBluetoothAddress}.
+         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
+         * BluetoothAdapter#checkBluetoothAddress}.
          * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
          */
         public Builder setDeviceAddress(String deviceAddress) {
@@ -480,8 +481,8 @@
          * {@code serviceUuid}. Set any bit in the mask to 1 to indicate a match is needed for the
          * bit in {@code serviceUuid}, and 0 to ignore that bit.
          *
-         * @throws IllegalArgumentException If {@code serviceUuid} is {@code null} but
-         *             {@code uuidMask} is not {@code null}.
+         * @throws IllegalArgumentException If {@code serviceUuid} is {@code null} but {@code
+         * uuidMask} is not {@code null}.
          */
         public Builder setServiceUuid(ParcelUuid serviceUuid, ParcelUuid uuidMask) {
             if (mUuidMask != null && mServiceUuid == null) {
@@ -513,9 +514,9 @@
          * <p>
          * The {@code serviceDataMask} must have the same length of the {@code serviceData}.
          *
-         * @throws IllegalArgumentException If {@code serviceDataUuid} is null or
-         *             {@code serviceDataMask} is {@code null} while {@code serviceData} is not or
-         *             {@code serviceDataMask} and {@code serviceData} has different length.
+         * @throws IllegalArgumentException If {@code serviceDataUuid} is null or {@code
+         * serviceDataMask} is {@code null} while {@code serviceData} is not or {@code
+         * serviceDataMask} and {@code serviceData} has different length.
          */
         public Builder setServiceData(ParcelUuid serviceDataUuid,
                 byte[] serviceData, byte[] serviceDataMask) {
@@ -563,10 +564,9 @@
          * <p>
          * The {@code manufacturerDataMask} must have the same length of {@code manufacturerData}.
          *
-         * @throws IllegalArgumentException If the {@code manufacturerId} is invalid, or
-         *             {@code manufacturerData} is null while {@code manufacturerDataMask} is not,
-         *             or {@code manufacturerData} and {@code manufacturerDataMask} have different
-         *             length.
+         * @throws IllegalArgumentException If the {@code manufacturerId} is invalid, or {@code
+         * manufacturerData} is null while {@code manufacturerDataMask} is not, or {@code
+         * manufacturerData} and {@code manufacturerDataMask} have different length.
          */
         public Builder setManufacturerData(int manufacturerId, byte[] manufacturerData,
                 byte[] manufacturerDataMask) {
diff --git a/core/java/android/bluetooth/le/ScanRecord.java b/core/java/android/bluetooth/le/ScanRecord.java
index 914e8fd..f8aaba9 100644
--- a/core/java/android/bluetooth/le/ScanRecord.java
+++ b/core/java/android/bluetooth/le/ScanRecord.java
@@ -231,9 +231,9 @@
                     case DATA_TYPE_SERVICE_DATA_128_BIT:
                         int serviceUuidLength = BluetoothUuid.UUID_BYTES_16_BIT;
                         if (fieldType == DATA_TYPE_SERVICE_DATA_32_BIT) {
-                         serviceUuidLength = BluetoothUuid.UUID_BYTES_32_BIT;
+                            serviceUuidLength = BluetoothUuid.UUID_BYTES_32_BIT;
                         } else if (fieldType == DATA_TYPE_SERVICE_DATA_128_BIT) {
-                         serviceUuidLength = BluetoothUuid.UUID_BYTES_128_BIT;
+                            serviceUuidLength = BluetoothUuid.UUID_BYTES_128_BIT;
                         }
 
                         byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos,
@@ -247,8 +247,8 @@
                     case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
                         // The first two bytes of the manufacturer specific data are
                         // manufacturer ids in little endian.
-                        int manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8) +
-                                (scanRecord[currentPos] & 0xFF);
+                        int manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8)
+                                + (scanRecord[currentPos] & 0xFF);
                         byte[] manufacturerDataBytes = extractBytes(scanRecord, currentPos + 2,
                                 dataLength - 2);
                         manufacturerData.put(manufacturerId, manufacturerDataBytes);
@@ -276,7 +276,8 @@
     @Override
     public String toString() {
         return "ScanRecord [mAdvertiseFlags=" + mAdvertiseFlags + ", mServiceUuids=" + mServiceUuids
-                + ", mManufacturerSpecificData=" + BluetoothLeUtils.toString(mManufacturerSpecificData)
+                + ", mManufacturerSpecificData=" + BluetoothLeUtils.toString(
+                mManufacturerSpecificData)
                 + ", mServiceData=" + BluetoothLeUtils.toString(mServiceData)
                 + ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName + "]";
     }
diff --git a/core/java/android/bluetooth/le/ScanResult.java b/core/java/android/bluetooth/le/ScanResult.java
index e552398..f87a47f 100644
--- a/core/java/android/bluetooth/le/ScanResult.java
+++ b/core/java/android/bluetooth/le/ScanResult.java
@@ -98,8 +98,10 @@
      * @param scanRecord Scan record including both advertising data and scan response data.
      * @param rssi Received signal strength.
      * @param timestampNanos Timestamp at which the scan result was observed.
-     * @deprecated use {@link #ScanResult(BluetoothDevice, int, int, int, int, int, int, int, ScanRecord, long)}
+     * @deprecated use {@link #ScanResult(BluetoothDevice, int, int, int, int, int, int, int,
+     * ScanRecord, long)}
      */
+    @Deprecated
     public ScanResult(BluetoothDevice device, ScanRecord scanRecord, int rssi,
             long timestampNanos) {
         mDevice = device;
@@ -129,8 +131,8 @@
      * @param timestampNanos Timestamp at which the scan result was observed.
      */
     public ScanResult(BluetoothDevice device, int eventType, int primaryPhy, int secondaryPhy,
-                      int advertisingSid, int txPower, int rssi, int periodicAdvertisingInterval,
-                      ScanRecord scanRecord, long timestampNanos) {
+            int advertisingSid, int txPower, int rssi, int periodicAdvertisingInterval,
+            ScanRecord scanRecord, long timestampNanos) {
         mDevice = device;
         mEventType = eventType;
         mPrimaryPhy = primaryPhy;
@@ -254,7 +256,9 @@
      * Can be one of {@link BluetoothDevice#PHY_LE_1M} or
      * {@link BluetoothDevice#PHY_LE_CODED}.
      */
-    public int getPrimaryPhy() { return mPrimaryPhy; }
+    public int getPrimaryPhy() {
+        return mPrimaryPhy;
+    }
 
     /**
      * Returns the secondary Physical Layer
@@ -264,21 +268,27 @@
      * or {@link ScanResult#PHY_UNUSED} - if the advertisement
      * was not received on a secondary physical channel.
      */
-    public int getSecondaryPhy() { return mSecondaryPhy; }
+    public int getSecondaryPhy() {
+        return mSecondaryPhy;
+    }
 
     /**
      * Returns the advertising set id.
      * May return {@link ScanResult#SID_NOT_PRESENT} if
      * no set id was is present.
      */
-    public int getAdvertisingSid() { return mAdvertisingSid; }
+    public int getAdvertisingSid() {
+        return mAdvertisingSid;
+    }
 
     /**
      * Returns the transmit power in dBm.
      * Valid range is [-127, 126]. A value of {@link ScanResult#TX_POWER_NOT_PRESENT}
      * indicates that the TX power is not present.
      */
-    public int getTxPower() { return mTxPower; }
+    public int getTxPower() {
+        return mTxPower;
+    }
 
     /**
      * Returns the periodic advertising interval in units of 1.25ms.
@@ -293,9 +303,9 @@
     @Override
     public int hashCode() {
         return Objects.hash(mDevice, mRssi, mScanRecord, mTimestampNanos,
-                            mEventType, mPrimaryPhy, mSecondaryPhy,
-                            mAdvertisingSid, mTxPower,
-                            mPeriodicAdvertisingInterval);
+                mEventType, mPrimaryPhy, mSecondaryPhy,
+                mAdvertisingSid, mTxPower,
+                mPeriodicAdvertisingInterval);
     }
 
     @Override
@@ -307,34 +317,34 @@
             return false;
         }
         ScanResult other = (ScanResult) obj;
-        return Objects.equals(mDevice, other.mDevice) && (mRssi == other.mRssi) &&
-            Objects.equals(mScanRecord, other.mScanRecord) &&
-            (mTimestampNanos == other.mTimestampNanos) &&
-            mEventType == other.mEventType &&
-            mPrimaryPhy == other.mPrimaryPhy &&
-            mSecondaryPhy == other.mSecondaryPhy &&
-            mAdvertisingSid == other.mAdvertisingSid &&
-            mTxPower == other.mTxPower &&
-            mPeriodicAdvertisingInterval == other.mPeriodicAdvertisingInterval;
+        return Objects.equals(mDevice, other.mDevice) && (mRssi == other.mRssi)
+                && Objects.equals(mScanRecord, other.mScanRecord)
+                && (mTimestampNanos == other.mTimestampNanos)
+                && mEventType == other.mEventType
+                && mPrimaryPhy == other.mPrimaryPhy
+                && mSecondaryPhy == other.mSecondaryPhy
+                && mAdvertisingSid == other.mAdvertisingSid
+                && mTxPower == other.mTxPower
+                && mPeriodicAdvertisingInterval == other.mPeriodicAdvertisingInterval;
     }
 
     @Override
     public String toString() {
-      return "ScanResult{" + "device=" + mDevice + ", scanRecord=" +
-          Objects.toString(mScanRecord) + ", rssi=" + mRssi +
-          ", timestampNanos=" + mTimestampNanos + ", eventType=" + mEventType +
-          ", primaryPhy=" + mPrimaryPhy + ", secondaryPhy=" + mSecondaryPhy +
-          ", advertisingSid=" + mAdvertisingSid + ", txPower=" + mTxPower +
-          ", periodicAdvertisingInterval=" + mPeriodicAdvertisingInterval + '}';
+        return "ScanResult{" + "device=" + mDevice + ", scanRecord="
+                + Objects.toString(mScanRecord) + ", rssi=" + mRssi
+                + ", timestampNanos=" + mTimestampNanos + ", eventType=" + mEventType
+                + ", primaryPhy=" + mPrimaryPhy + ", secondaryPhy=" + mSecondaryPhy
+                + ", advertisingSid=" + mAdvertisingSid + ", txPower=" + mTxPower
+                + ", periodicAdvertisingInterval=" + mPeriodicAdvertisingInterval + '}';
     }
 
     public static final Parcelable.Creator<ScanResult> CREATOR = new Creator<ScanResult>() {
-            @Override
+        @Override
         public ScanResult createFromParcel(Parcel source) {
             return new ScanResult(source);
         }
 
-            @Override
+        @Override
         public ScanResult[] newArray(int size) {
             return new ScanResult[size];
         }
diff --git a/core/java/android/bluetooth/le/ScanSettings.java b/core/java/android/bluetooth/le/ScanSettings.java
index 36e48e9..8fdcba8 100644
--- a/core/java/android/bluetooth/le/ScanSettings.java
+++ b/core/java/android/bluetooth/le/ScanSettings.java
@@ -35,7 +35,7 @@
 
     /**
      * Perform Bluetooth LE scan in low power mode. This is the default scan mode as it consumes the
-     * least power.
+     * least power. This mode is enforced if the scanning application is not in foreground.
      */
     public static final int SCAN_MODE_LOW_POWER = 0;
 
@@ -202,8 +202,8 @@
     }
 
     private ScanSettings(int scanMode, int callbackType, int scanResultType,
-                         long reportDelayMillis, int matchMode,
-                         int numOfMatchesPerFilter, boolean legacy, int phy) {
+            long reportDelayMillis, int matchMode,
+            int numOfMatchesPerFilter, boolean legacy, int phy) {
         mScanMode = scanMode;
         mCallbackType = callbackType;
         mScanResultType = scanResultType;
@@ -221,7 +221,7 @@
         mReportDelayMillis = in.readLong();
         mMatchMode = in.readInt();
         mNumOfMatchesPerFilter = in.readInt();
-        mLegacy = in.readInt() != 0 ? true : false;
+        mLegacy = in.readInt() != 0;
         mPhy = in.readInt();
     }
 
@@ -242,18 +242,18 @@
         return 0;
     }
 
-    public static final Parcelable.Creator<ScanSettings>
-            CREATOR = new Creator<ScanSettings>() {
-                    @Override
-                public ScanSettings[] newArray(int size) {
-                    return new ScanSettings[size];
-                }
+    public static final Parcelable.Creator<ScanSettings> CREATOR =
+            new Creator<ScanSettings>() {
+        @Override
+        public ScanSettings[] newArray(int size) {
+            return new ScanSettings[size];
+        }
 
-                    @Override
-                public ScanSettings createFromParcel(Parcel in) {
-                    return new ScanSettings(in);
-                }
-            };
+        @Override
+        public ScanSettings createFromParcel(Parcel in) {
+            return new ScanSettings(in);
+        }
+    };
 
     /**
      * Builder for {@link ScanSettings}.
@@ -264,7 +264,7 @@
         private int mScanResultType = SCAN_RESULT_TYPE_FULL;
         private long mReportDelayMillis = 0;
         private int mMatchMode = MATCH_MODE_AGGRESSIVE;
-        private int mNumOfMatchesPerFilter  = MATCH_NUM_MAX_ADVERTISEMENT;
+        private int mNumOfMatchesPerFilter = MATCH_NUM_MAX_ADVERTISEMENT;
         private boolean mLegacy = true;
         private int mPhy = PHY_LE_ALL_SUPPORTED;
 
@@ -272,8 +272,7 @@
          * Set scan mode for Bluetooth LE scan.
          *
          * @param scanMode The scan mode can be one of {@link ScanSettings#SCAN_MODE_LOW_POWER},
-         *            {@link ScanSettings#SCAN_MODE_BALANCED} or
-         *            {@link ScanSettings#SCAN_MODE_LOW_LATENCY}.
+         * {@link ScanSettings#SCAN_MODE_BALANCED} or {@link ScanSettings#SCAN_MODE_LOW_LATENCY}.
          * @throws IllegalArgumentException If the {@code scanMode} is invalid.
          */
         public Builder setScanMode(int scanMode) {
@@ -301,9 +300,9 @@
 
         // Returns true if the callbackType is valid.
         private boolean isValidCallbackType(int callbackType) {
-            if (callbackType == CALLBACK_TYPE_ALL_MATCHES ||
-                    callbackType == CALLBACK_TYPE_FIRST_MATCH ||
-                    callbackType == CALLBACK_TYPE_MATCH_LOST) {
+            if (callbackType == CALLBACK_TYPE_ALL_MATCHES
+                    || callbackType == CALLBACK_TYPE_FIRST_MATCH
+                    || callbackType == CALLBACK_TYPE_MATCH_LOST) {
                 return true;
             }
             return callbackType == (CALLBACK_TYPE_FIRST_MATCH | CALLBACK_TYPE_MATCH_LOST);
@@ -312,9 +311,8 @@
         /**
          * Set scan result type for Bluetooth LE scan.
          *
-         * @param scanResultType Type for scan result, could be either
-         *            {@link ScanSettings#SCAN_RESULT_TYPE_FULL} or
-         *            {@link ScanSettings#SCAN_RESULT_TYPE_ABBREVIATED}.
+         * @param scanResultType Type for scan result, could be either {@link
+         * ScanSettings#SCAN_RESULT_TYPE_FULL} or {@link ScanSettings#SCAN_RESULT_TYPE_ABBREVIATED}.
          * @throws IllegalArgumentException If the {@code scanResultType} is invalid.
          * @hide
          */
@@ -333,8 +331,8 @@
          * Set report delay timestamp for Bluetooth LE scan.
          *
          * @param reportDelayMillis Delay of report in milliseconds. Set to 0 to be notified of
-         *            results immediately. Values &gt; 0 causes the scan results to be queued up and
-         *            delivered after the requested delay or when the internal buffers fill up.
+         * results immediately. Values &gt; 0 causes the scan results to be queued up and delivered
+         * after the requested delay or when the internal buffers fill up.
          * @throws IllegalArgumentException If {@code reportDelayMillis} &lt; 0.
          */
         public Builder setReportDelay(long reportDelayMillis) {
@@ -349,9 +347,9 @@
          * Set the number of matches for Bluetooth LE scan filters hardware match
          *
          * @param numOfMatches The num of matches can be one of
-         *              {@link ScanSettings#MATCH_NUM_ONE_ADVERTISEMENT} or
-         *              {@link ScanSettings#MATCH_NUM_FEW_ADVERTISEMENT} or
-         *              {@link ScanSettings#MATCH_NUM_MAX_ADVERTISEMENT}
+         * {@link ScanSettings#MATCH_NUM_ONE_ADVERTISEMENT}
+         * or {@link ScanSettings#MATCH_NUM_FEW_ADVERTISEMENT} or {@link
+         * ScanSettings#MATCH_NUM_MAX_ADVERTISEMENT}
          * @throws IllegalArgumentException If the {@code matchMode} is invalid.
          */
         public Builder setNumOfMatches(int numOfMatches) {
@@ -366,9 +364,8 @@
         /**
          * Set match mode for Bluetooth LE scan filters hardware match
          *
-         * @param matchMode The match mode can be one of
-         *              {@link ScanSettings#MATCH_MODE_AGGRESSIVE} or
-         *              {@link ScanSettings#MATCH_MODE_STICKY}
+         * @param matchMode The match mode can be one of {@link ScanSettings#MATCH_MODE_AGGRESSIVE}
+         * or {@link ScanSettings#MATCH_MODE_STICKY}
          * @throws IllegalArgumentException If the {@code matchMode} is invalid.
          */
         public Builder setMatchMode(int matchMode) {
@@ -402,10 +399,8 @@
          * {@link android.bluetooth.BluetoothAdapter#isLeCodedPhySupported}.
          * Selecting an unsupported phy will result in failure to start scan.
          *
-         * @param phy Can be one of
-         *   {@link BluetoothDevice#PHY_LE_1M},
-         *   {@link BluetoothDevice#PHY_LE_CODED} or
-         *   {@link ScanSettings#PHY_LE_ALL_SUPPORTED}
+         * @param phy Can be one of {@link BluetoothDevice#PHY_LE_1M}, {@link
+         * BluetoothDevice#PHY_LE_CODED} or {@link ScanSettings#PHY_LE_ALL_SUPPORTED}
          */
         public Builder setPhy(int phy) {
             mPhy = phy;
@@ -417,8 +412,8 @@
          */
         public ScanSettings build() {
             return new ScanSettings(mScanMode, mCallbackType, mScanResultType,
-                                    mReportDelayMillis, mMatchMode,
-                                    mNumOfMatchesPerFilter, mLegacy, mPhy);
+                    mReportDelayMillis, mMatchMode,
+                    mNumOfMatchesPerFilter, mLegacy, mPhy);
         }
     }
 }
diff --git a/core/java/android/bluetooth/le/TruncatedFilter.java b/core/java/android/bluetooth/le/TruncatedFilter.java
index 685b174..a753aa6 100644
--- a/core/java/android/bluetooth/le/TruncatedFilter.java
+++ b/core/java/android/bluetooth/le/TruncatedFilter.java
@@ -17,6 +17,7 @@
 package android.bluetooth.le;
 
 import android.annotation.SystemApi;
+
 import java.util.List;
 
 /**
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 86a30cf..076deab 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -280,12 +280,24 @@
 
         @Override
         public void onSuccess(PendingIntent launcher) {
-            mHandler.post(() -> mCallback.onDeviceFound(launcher.getIntentSender()));
+            Handler handler = mHandler;
+            if (handler == null) return;
+            handler.post(() -> {
+                Callback callback = mCallback;
+                if (callback == null) return;
+                callback.onDeviceFound(launcher.getIntentSender());
+            });
         }
 
         @Override
         public void onFailure(CharSequence reason) {
-            mHandler.post(() -> mCallback.onFailure(reason));
+            Handler handler = mHandler;
+            if (handler == null) return;
+            handler.post(() -> {
+                Callback callback = mCallback;
+                if (callback == null) return;
+                callback.onFailure(reason);
+            });
         }
 
         @Override
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index 58bd5cd..2629929 100644
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
@@ -17,11 +17,12 @@
 package android.content;
 
 import android.accounts.Account;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Process;
-import android.os.RemoteException;
 import android.os.Trace;
+import android.util.Log;
 
 import java.util.HashMap;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -95,6 +96,8 @@
  * </ul>
  */
 public abstract class AbstractThreadedSyncAdapter {
+    private static final String TAG = "SyncAdapter";
+
     /**
      * Kernel event log tag.  Also listed in data/etc/event-log-tags.
      * @deprecated Private constant.  May go away in the next release.
@@ -102,6 +105,8 @@
     @Deprecated
     public static final int LOG_SYNC_DETAILS = 2743;
 
+    private static final boolean ENABLE_LOG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.DEBUG);
+
     private final Context mContext;
     private final AtomicInteger mNumSyncStarts;
     private final ISyncAdapterImpl mISyncAdapterImpl;
@@ -163,71 +168,104 @@
         @Override
         public void startSync(ISyncContext syncContext, String authority, Account account,
                 Bundle extras) {
-            final SyncContext syncContextClient = new SyncContext(syncContext);
-
-            boolean alreadyInProgress;
-            // synchronize to make sure that mSyncThreads doesn't change between when we
-            // check it and when we use it
-            final Account threadsKey = toSyncKey(account);
-            synchronized (mSyncThreadLock) {
-                if (!mSyncThreads.containsKey(threadsKey)) {
-                    if (mAutoInitialize
-                            && extras != null
-                            && extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)) {
-                        try {
-                            if (ContentResolver.getIsSyncable(account, authority) < 0) {
-                                ContentResolver.setIsSyncable(account, authority, 1);
-                            }
-                        } finally {
-                            syncContextClient.onFinished(new SyncResult());
-                        }
-                        return;
-                    }
-                    SyncThread syncThread = new SyncThread(
-                            "SyncAdapterThread-" + mNumSyncStarts.incrementAndGet(),
-                            syncContextClient, authority, account, extras);
-                    mSyncThreads.put(threadsKey, syncThread);
-                    syncThread.start();
-                    alreadyInProgress = false;
-                } else {
-                    alreadyInProgress = true;
+            if (ENABLE_LOG) {
+                if (extras != null) {
+                    extras.size(); // Unparcel so its toString() will show the contents.
                 }
+                Log.d(TAG, "startSync() start " + authority + " " + account + " " + extras);
             }
+            try {
+                final SyncContext syncContextClient = new SyncContext(syncContext);
 
-            // do this outside since we don't want to call back into the syncContext while
-            // holding the synchronization lock
-            if (alreadyInProgress) {
-                syncContextClient.onFinished(SyncResult.ALREADY_IN_PROGRESS);
+                boolean alreadyInProgress;
+                // synchronize to make sure that mSyncThreads doesn't change between when we
+                // check it and when we use it
+                final Account threadsKey = toSyncKey(account);
+                synchronized (mSyncThreadLock) {
+                    if (!mSyncThreads.containsKey(threadsKey)) {
+                        if (mAutoInitialize
+                                && extras != null
+                                && extras.getBoolean(
+                                        ContentResolver.SYNC_EXTRAS_INITIALIZE, false)) {
+                            try {
+                                if (ContentResolver.getIsSyncable(account, authority) < 0) {
+                                    ContentResolver.setIsSyncable(account, authority, 1);
+                                }
+                            } finally {
+                                syncContextClient.onFinished(new SyncResult());
+                            }
+                            return;
+                        }
+                        SyncThread syncThread = new SyncThread(
+                                "SyncAdapterThread-" + mNumSyncStarts.incrementAndGet(),
+                                syncContextClient, authority, account, extras);
+                        mSyncThreads.put(threadsKey, syncThread);
+                        syncThread.start();
+                        alreadyInProgress = false;
+                    } else {
+                        if (ENABLE_LOG) {
+                            Log.d(TAG, "  alreadyInProgress");
+                        }
+                        alreadyInProgress = true;
+                    }
+                }
+
+                // do this outside since we don't want to call back into the syncContext while
+                // holding the synchronization lock
+                if (alreadyInProgress) {
+                    syncContextClient.onFinished(SyncResult.ALREADY_IN_PROGRESS);
+                }
+            } catch (RuntimeException | Error th) {
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "startSync() caught exception", th);
+                }
+                throw th;
+            } finally {
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "startSync() finishing");
+                }
             }
         }
 
         @Override
         public void cancelSync(ISyncContext syncContext) {
-            // synchronize to make sure that mSyncThreads doesn't change between when we
-            // check it and when we use it
-            SyncThread info = null;
-            synchronized (mSyncThreadLock) {
-                for (SyncThread current : mSyncThreads.values()) {
-                    if (current.mSyncContext.getSyncContextBinder() == syncContext.asBinder()) {
-                        info = current;
-                        break;
+            try {
+                // synchronize to make sure that mSyncThreads doesn't change between when we
+                // check it and when we use it
+                SyncThread info = null;
+                synchronized (mSyncThreadLock) {
+                    for (SyncThread current : mSyncThreads.values()) {
+                        if (current.mSyncContext.getSyncContextBinder() == syncContext.asBinder()) {
+                            info = current;
+                            break;
+                        }
                     }
                 }
-            }
-            if (info != null) {
-                if (mAllowParallelSyncs) {
-                    onSyncCanceled(info);
+                if (info != null) {
+                    if (ENABLE_LOG) {
+                        Log.d(TAG, "cancelSync() " + info.mAuthority + " " + info.mAccount);
+                    }
+                    if (mAllowParallelSyncs) {
+                        onSyncCanceled(info);
+                    } else {
+                        onSyncCanceled();
+                    }
                 } else {
-                    onSyncCanceled();
+                    if (ENABLE_LOG) {
+                        Log.w(TAG, "cancelSync() unknown context");
+                    }
+                }
+            } catch (RuntimeException | Error th) {
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "cancelSync() caught exception", th);
+                }
+                throw th;
+            } finally {
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "cancelSync() finishing");
                 }
             }
         }
-
-        public void initialize(Account account, String authority) throws RemoteException {
-            Bundle extras = new Bundle();
-            extras.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true);
-            startSync(null, authority, account, extras);
-        }
     }
 
     /**
@@ -256,6 +294,10 @@
         public void run() {
             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
 
+            if (ENABLE_LOG) {
+                Log.d(TAG, "Thread started");
+            }
+
             // Trace this sync instance.  Note, conceptually this should be in
             // SyncStorageEngine.insertStartSyncEvent(), but the trace functions require unique
             // threads in order to track overlapping operations, so we'll do it here for now.
@@ -265,8 +307,15 @@
             ContentProviderClient provider = null;
             try {
                 if (isCanceled()) {
+                    if (ENABLE_LOG) {
+                        Log.d(TAG, "Already canceled");
+                    }
                     return;
                 }
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "Calling onPerformSync...");
+                }
+
                 provider = mContext.getContentResolver().acquireContentProviderClient(mAuthority);
                 if (provider != null) {
                     AbstractThreadedSyncAdapter.this.onPerformSync(mAccount, mExtras,
@@ -274,10 +323,23 @@
                 } else {
                     syncResult.databaseError = true;
                 }
+
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "onPerformSync done");
+                }
+
             } catch (SecurityException e) {
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "SecurityException", e);
+                }
                 AbstractThreadedSyncAdapter.this.onSecurityException(mAccount, mExtras,
                         mAuthority, syncResult);
                 syncResult.databaseError = true;
+            } catch (RuntimeException | Error th) {
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "caught exception", th);
+                }
+                throw th;
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_SYNC_MANAGER);
 
@@ -292,6 +354,10 @@
                 synchronized (mSyncThreadLock) {
                     mSyncThreads.remove(mThreadsKey);
                 }
+
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "Thread finished");
+                }
             }
         }
 
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index 5bc1f18..9323261 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -43,6 +43,7 @@
 import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.List;
+import libcore.io.IoUtils;
 
 /**
  * Representation of a clipped data on the clipboard.
@@ -335,46 +336,46 @@
             // If this Item has a URI value, try using that.
             Uri uri = getUri();
             if (uri != null) {
-
                 // First see if the URI can be opened as a plain text stream
                 // (of any sub-type).  If so, this is the best textual
                 // representation for it.
+                final ContentResolver resolver = context.getContentResolver();
+                AssetFileDescriptor descr = null;
                 FileInputStream stream = null;
+                InputStreamReader reader = null;
                 try {
-                    // Ask for a stream of the desired type.
-                    AssetFileDescriptor descr = context.getContentResolver()
-                            .openTypedAssetFileDescriptor(uri, "text/*", null);
-                    stream = descr.createInputStream();
-                    InputStreamReader reader = new InputStreamReader(stream, "UTF-8");
-
-                    // Got it...  copy the stream into a local string and return it.
-                    StringBuilder builder = new StringBuilder(128);
-                    char[] buffer = new char[8192];
-                    int len;
-                    while ((len=reader.read(buffer)) > 0) {
-                        builder.append(buffer, 0, len);
+                    try {
+                        // Ask for a stream of the desired type.
+                        descr = resolver.openTypedAssetFileDescriptor(uri, "text/*", null);
+                    } catch (SecurityException e) {
+                        Log.w("ClipData", "Failure opening stream", e);
+                    } catch (FileNotFoundException|RuntimeException e) {
+                        // Unable to open content URI as text...  not really an
+                        // error, just something to ignore.
                     }
-                    return builder.toString();
-
-                } catch (SecurityException e) {
-                    Log.w("ClipData", "Failure opening stream", e);
-
-                } catch (FileNotFoundException e) {
-                    // Unable to open content URI as text...  not really an
-                    // error, just something to ignore.
-
-                } catch (IOException e) {
-                    // Something bad has happened.
-                    Log.w("ClipData", "Failure loading text", e);
-                    return e.toString();
-
-                } finally {
-                    if (stream != null) {
+                    if (descr != null) {
                         try {
-                            stream.close();
+                            stream = descr.createInputStream();
+                            reader = new InputStreamReader(stream, "UTF-8");
+
+                            // Got it...  copy the stream into a local string and return it.
+                            final StringBuilder builder = new StringBuilder(128);
+                            char[] buffer = new char[8192];
+                            int len;
+                            while ((len=reader.read(buffer)) > 0) {
+                                builder.append(buffer, 0, len);
+                            }
+                            return builder.toString();
                         } catch (IOException e) {
+                            // Something bad has happened.
+                            Log.w("ClipData", "Failure loading text", e);
+                            return e.toString();
                         }
                     }
+                } finally {
+                    IoUtils.closeQuietly(descr);
+                    IoUtils.closeQuietly(stream);
+                    IoUtils.closeQuietly(reader);
                 }
 
                 // If we couldn't open the URI as a stream, use the URI itself as a textual
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index a04a7b2..f8c139f 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -524,7 +524,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
@@ -579,7 +582,10 @@
         @Override
         protected void finalize() throws Throwable {
             try {
-                mCloseGuard.warnIfOpen();
+                if (mCloseGuard != null) {
+                    mCloseGuard.warnIfOpen();
+                }
+
                 close();
             } finally {
                 super.finalize();
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 309827c..9ccc552 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -2938,7 +2938,10 @@
         @Override
         protected void finalize() throws Throwable {
             try {
-                mCloseGuard.warnIfOpen();
+                if (mCloseGuard != null) {
+                    mCloseGuard.warnIfOpen();
+                }
+
                 close();
             } finally {
                 super.finalize();
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 6c62f5e..654b8da 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -34,7 +34,6 @@
 import android.annotation.UserIdInt;
 import android.app.IApplicationThread;
 import android.app.IServiceConnection;
-import android.app.Notification;
 import android.app.VrManager;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
@@ -127,8 +126,8 @@
      * File creation mode: allow all other applications to have read access to
      * the created file.
      * <p>
-     * As of {@link android.os.Build.VERSION_CODES#N} attempting to use this
-     * mode will throw a {@link SecurityException}.
+     * Starting from {@link android.os.Build.VERSION_CODES#N}, attempting to use this
+     * mode throws a {@link SecurityException}.
      *
      * @deprecated Creating world-readable files is very dangerous, and likely
      *             to cause security holes in applications. It is strongly
@@ -147,7 +146,7 @@
      * File creation mode: allow all other applications to have write access to
      * the created file.
      * <p>
-     * As of {@link android.os.Build.VERSION_CODES#N} attempting to use this
+     * Starting from {@link android.os.Build.VERSION_CODES#N}, attempting to use this
      * mode will throw a {@link SecurityException}.
      *
      * @deprecated Creating world-writable files is very dangerous, and likely
@@ -814,6 +813,9 @@
      */
     public abstract boolean deleteSharedPreferences(String name);
 
+    /** @hide */
+    public abstract void reloadSharedPreferences();
+
     /**
      * Open a private file associated with this Context's application package
      * for reading.
@@ -1127,13 +1129,47 @@
      * </ul>
      * <p>
      * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
-     * are required to read or write to the returned path; it's always
-     * accessible to the calling app. This only applies to paths generated for
-     * package name of the calling application. To access paths belonging to
-     * other packages,
-     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} and/or
-     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
+     * are required to read or write to the path that this method returns.
+     * However, starting from {@link android.os.Build.VERSION_CODES#M},
+     * to read the OBB expansion files, you must declare the
+     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission in the app manifest and ask for
+     * permission at runtime as follows:
+     * </p>
      * <p>
+     * {@code <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
+     * android:maxSdkVersion="23" />}
+     * </p>
+     * <p>
+     * Starting from {@link android.os.Build.VERSION_CODES#N},
+     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}
+     * permission is not required, so don’t ask for this
+     * permission at runtime. To handle both cases, your app must first try to read the OBB file,
+     * and if it fails, you must request
+     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission at runtime.
+     * </p>
+     *
+     * <p>
+     * The following code snippet shows how to do this:
+     * </p>
+     *
+     * <pre>
+     * File obb = new File(obb_filename);
+     * boolean open_failed = false;
+     *
+     * try {
+     *     BufferedReader br = new BufferedReader(new FileReader(obb));
+     *     open_failed = false;
+     *     ReadObbFile(br);
+     * } catch (IOException e) {
+     *     open_failed = true;
+     * }
+     *
+     * if (open_failed) {
+     *     // request READ_EXTERNAL_STORAGE permission before reading OBB file
+     *     ReadObbFileWithPermission();
+     * }
+     * </pre>
+     *
      * On devices with multiple users (as described by {@link UserManager}),
      * multiple users may share the same OBB storage location. Applications
      * should ensure that multiple instances running under different users don't
@@ -2675,8 +2711,8 @@
 
     /**
      * Similar to {@link #startService(Intent)}, but with an implicit promise that the
-     * Service will call {@link android.app.Service#startForeground(int, Notification)
-     * startForeground(int, Notification)} once it begins running.  The service is given
+     * Service will call {@link android.app.Service#startForeground(int, android.app.Notification)
+     * startForeground(int, android.app.Notification)} once it begins running.  The service is given
      * an amount of time comparable to the ANR interval to do this, otherwise the system
      * will automatically stop the service and declare the app ANR.
      *
@@ -2697,7 +2733,7 @@
      * or the service can not be found.
      *
      * @see #stopService
-     * @see android.app.Service#startForeground(int, Notification)
+     * @see android.app.Service#startForeground(int, android.app.Notification)
      */
     @Nullable
     public abstract ComponentName startForegroundService(Intent service);
@@ -2995,6 +3031,9 @@
      *  <dt> {@link #CONNECTIVITY_SERVICE} ("connection")
      *  <dd> A {@link android.net.ConnectivityManager ConnectivityManager} for
      *  handling management of network connections.
+     *  <dt> {@link #IPSEC_SERVICE} ("ipsec")
+     *  <dd> A {@link android.net.IpSecManager IpSecManager} for managing IPSec on
+     *  sockets and networks.
      *  <dt> {@link #WIFI_SERVICE} ("wifi")
      *  <dd> A {@link android.net.wifi.WifiManager WifiManager} for management of Wi-Fi
      *  connectivity.  On releases before NYC, it should only be obtained from an application
@@ -3339,7 +3378,6 @@
      * {@link android.net.IpSecManager} for encrypting Sockets or Networks with
      * IPSec.
      *
-     * @hide
      * @see #getSystemService
      */
     public static final String IPSEC_SERVICE = "ipsec";
@@ -3526,6 +3564,17 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a
+     * {@link android.telephony.euicc.EuiccManager} to manage the device eUICC (embedded SIM).
+     *
+     * @see #getSystemService
+     * @see android.telephony.euicc.EuiccManager
+     * TODO(b/35851809): Unhide this API.
+     * @hide
+     */
+    public static final String EUICC_SERVICE = "euicc_service";
+
+    /**
+     * Use with {@link #getSystemService} to retrieve a
      * {@link android.text.ClipboardManager} for accessing and modifying
      * {@link android.content.ClipboardManager} for accessing and modifying
      * the contents of the global clipboard.
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index df59f0e..a9fd58b 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -19,7 +19,6 @@
 import android.annotation.SystemApi;
 import android.app.IApplicationThread;
 import android.app.IServiceConnection;
-import android.app.Notification;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
@@ -173,6 +172,12 @@
         return mBase.getSharedPreferences(file, mode);
     }
 
+    /** @hide */
+    @Override
+    public void reloadSharedPreferences() {
+        mBase.reloadSharedPreferences();
+    }
+
     @Override
     public boolean moveSharedPreferencesFrom(Context sourceContext, String name) {
         return mBase.moveSharedPreferencesFrom(sourceContext, name);
diff --git a/core/java/android/content/ISyncAdapter.aidl b/core/java/android/content/ISyncAdapter.aidl
index dd9d14e..4660527 100644
--- a/core/java/android/content/ISyncAdapter.aidl
+++ b/core/java/android/content/ISyncAdapter.aidl
@@ -44,12 +44,4 @@
      * @param syncContext the ISyncContext that was passed to {@link #startSync}
      */
     void cancelSync(ISyncContext syncContext);
-
-    /**
-     * Initialize the SyncAdapter for this account and authority.
-     *
-     * @param account the account that should be synced
-     * @param authority the authority that should be synced
-     */
-    void initialize(in Account account, String authority);
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 1d879e9..6ed1fb7 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -16,6 +16,8 @@
 
 package android.content;
 
+import static android.content.ContentProvider.maybeAddUserId;
+
 import android.annotation.AnyRes;
 import android.annotation.BroadcastBehavior;
 import android.annotation.IntDef;
@@ -43,7 +45,7 @@
 import android.os.ShellCommand;
 import android.os.StrictMode;
 import android.os.UserHandle;
-import android.os.storage.StorageManager;
+import android.provider.ContactsContract.QuickContact;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsProvider;
 import android.provider.MediaStore;
@@ -51,7 +53,9 @@
 import android.util.ArraySet;
 import android.util.AttributeSet;
 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;
@@ -69,8 +73,6 @@
 import java.util.Objects;
 import java.util.Set;
 
-import static android.content.ContentProvider.maybeAddUserId;
-
 /**
  * An intent is an abstract description of an operation to be performed.  It
  * can be used with {@link Context#startActivity(Intent) startActivity} to
@@ -3442,11 +3444,13 @@
             "android.intent.extra.FORCE_FACTORY_RESET";
 
     /**
-     * Broadcast action: report that a settings element is being restored from backup.  The intent
-     * contains three extras: EXTRA_SETTING_NAME is a string naming the restored setting,
-     * EXTRA_SETTING_NEW_VALUE is the value being restored, and EXTRA_SETTING_PREVIOUS_VALUE
-     * is the value of that settings entry prior to the restore operation.  All of these values are
-     * represented as strings.
+     * Broadcast action: report that a settings element is being restored from backup. The intent
+     * contains four extras: EXTRA_SETTING_NAME is a string naming the restored setting,
+     * EXTRA_SETTING_NEW_VALUE is the value being restored, EXTRA_SETTING_PREVIOUS_VALUE
+     * is the value of that settings entry prior to the restore operation, and
+     * EXTRA_SETTING_RESTORED_FROM_SDK_INT is the version of the SDK that the setting has been
+     * restored from (corresponds to {@link android.os.Build.VERSION#SDK_INT}). The first three
+     * values are represented as strings, the fourth one as int.
      *
      * <p>This broadcast is sent only for settings provider entries known to require special handling
      * around restore time.  These entries are found in the BROADCAST_ON_RESTORE table within
@@ -3455,6 +3459,7 @@
      * @see #EXTRA_SETTING_NAME
      * @see #EXTRA_SETTING_PREVIOUS_VALUE
      * @see #EXTRA_SETTING_NEW_VALUE
+     * @see #EXTRA_SETTING_RESTORED_FROM_SDK_INT
      * {@hide}
      */
     public static final String ACTION_SETTING_RESTORED = "android.os.action.SETTING_RESTORED";
@@ -3465,6 +3470,8 @@
     public static final String EXTRA_SETTING_PREVIOUS_VALUE = "previous_value";
     /** {@hide} */
     public static final String EXTRA_SETTING_NEW_VALUE = "new_value";
+    /** {@hide} */
+    public static final String EXTRA_SETTING_RESTORED_FROM_SDK_INT = "restored_from_sdk_int";
 
     /**
      * Activity Action: Process a piece of text.
@@ -4765,10 +4772,21 @@
     /** {@hide} */
     public static final String EXTRA_REASON = "android.intent.extra.REASON";
 
-    /** {@hide} */
+    /**
+     * {@hide}
+     * This extra will be send together with {@link #ACTION_FACTORY_RESET}
+     */
     public static final String EXTRA_WIPE_EXTERNAL_STORAGE = "android.intent.extra.WIPE_EXTERNAL_STORAGE";
 
     /**
+     * {@hide}
+     * This extra will be set to true when the user choose to wipe the data on eSIM during factory
+     * reset for the device with eSIM. This extra will be sent together with
+     * {@link #ACTION_FACTORY_RESET}
+     */
+    public static final String EXTRA_WIPE_ESIMS = "com.android.internal.intent.extra.WIPE_ESIMS";
+
+    /**
      * Optional {@link android.app.PendingIntent} extra used to deliver the result of the SIM
      * activation request.
      * TODO: Add information about the structure and response data used with the pending intent.
@@ -9329,7 +9347,7 @@
                 for (int i=0; i<N; i++) {
                     char c = data.charAt(i);
                     if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
-                            || c == '.' || c == '-') {
+                            || (c >= '0' && c <= '9') || c == '.' || c == '-' || c == '+') {
                         continue;
                     }
                     if (c == ':' && i > 0) {
@@ -9771,6 +9789,7 @@
                 && leavingPackage) {
             switch (mAction) {
                 case ACTION_PROVIDER_CHANGED:
+                case QuickContact.ACTION_QUICK_CONTACT:
                     // Ignore actions that don't need to grant
                     break;
                 default:
diff --git a/core/java/android/content/SyncAdaptersCache.java b/core/java/android/content/SyncAdaptersCache.java
index ddbdb8a..ccd7994 100644
--- a/core/java/android/content/SyncAdaptersCache.java
+++ b/core/java/android/content/SyncAdaptersCache.java
@@ -20,6 +20,7 @@
 import android.content.pm.XmlSerializerAndParser;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.AttributeSet;
 import android.util.SparseArray;
@@ -63,7 +64,7 @@
                     sa.getString(com.android.internal.R.styleable.SyncAdapter_contentAuthority);
             final String accountType =
                     sa.getString(com.android.internal.R.styleable.SyncAdapter_accountType);
-            if (authority == null || accountType == null) {
+            if (TextUtils.isEmpty(authority) || TextUtils.isEmpty(accountType)) {
                 return null;
             }
             final boolean userVisible =
diff --git a/core/java/android/content/SyncStatusInfo.java b/core/java/android/content/SyncStatusInfo.java
index bb24ccd..abf9cc9 100644
--- a/core/java/android/content/SyncStatusInfo.java
+++ b/core/java/android/content/SyncStatusInfo.java
@@ -24,7 +24,11 @@
 
 /** @hide */
 public class SyncStatusInfo implements Parcelable {
-    static final int VERSION = 2;
+    private static final String TAG = "Sync";
+
+    static final int VERSION = 4;
+
+    private static final int MAX_EVENT_COUNT = 10;
 
     public final int authorityId;
     public long totalElapsedTime;
@@ -47,7 +51,8 @@
   // no race conditions when accessing this list
   private ArrayList<Long> periodicSyncTimes;
 
-    private static final String TAG = "Sync";
+    private final ArrayList<Long> mLastEventTimes = new ArrayList<>();
+    private final ArrayList<String> mLastEvents = new ArrayList<>();
 
     public SyncStatusInfo(int authorityId) {
         this.authorityId = authorityId;
@@ -92,6 +97,12 @@
         } else {
             parcel.writeInt(-1);
         }
+        parcel.writeInt(mLastEventTimes.size());
+        for (int i = 0; i < mLastEventTimes.size(); i++) {
+            parcel.writeLong(mLastEventTimes.get(i));
+            parcel.writeString(mLastEvents.get(i));
+        }
+        parcel.writeInt(numSourcePeriodic);
     }
 
     public SyncStatusInfo(Parcel parcel) {
@@ -117,15 +128,34 @@
         if (version == 1) {
             periodicSyncTimes = null;
         } else {
-            int N = parcel.readInt();
-            if (N < 0) {
+            final int count = parcel.readInt();
+            if (count < 0) {
                 periodicSyncTimes = null;
             } else {
                 periodicSyncTimes = new ArrayList<Long>();
-                for (int i=0; i<N; i++) {
+                for (int i = 0; i < count; i++) {
                     periodicSyncTimes.add(parcel.readLong());
                 }
             }
+            if (version >= 3) {
+                mLastEventTimes.clear();
+                mLastEvents.clear();
+                final int nEvents = parcel.readInt();
+                for (int i = 0; i < nEvents; i++) {
+                    mLastEventTimes.add(parcel.readLong());
+                    mLastEvents.add(parcel.readString());
+                }
+            }
+        }
+        if (version < 4) {
+            // Before version 4, numSourcePeriodic wasn't persisted.
+            numSourcePeriodic = numSyncs - numSourceLocal - numSourcePoll - numSourceServer
+                    - numSourceUser;
+            if (numSourcePeriodic < 0) { // Sanity check.
+                numSourcePeriodic = 0;
+            }
+        } else {
+            numSourcePeriodic = parcel.readInt();
         }
     }
 
@@ -149,6 +179,8 @@
         if (other.periodicSyncTimes != null) {
             periodicSyncTimes = new ArrayList<Long>(other.periodicSyncTimes);
         }
+        mLastEventTimes.addAll(other.mLastEventTimes);
+        mLastEvents.addAll(other.mLastEvents);
     }
 
     public void setPeriodicSyncTime(int index, long when) {
@@ -172,6 +204,31 @@
         }
     }
 
+    /** */
+    public void addEvent(String message) {
+        if (mLastEventTimes.size() >= MAX_EVENT_COUNT) {
+            mLastEventTimes.remove(MAX_EVENT_COUNT - 1);
+            mLastEvents.remove(MAX_EVENT_COUNT - 1);
+        }
+        mLastEventTimes.add(0, System.currentTimeMillis());
+        mLastEvents.add(0, message);
+    }
+
+    /** */
+    public int getEventCount() {
+        return mLastEventTimes.size();
+    }
+
+    /** */
+    public long getEventTime(int i) {
+        return mLastEventTimes.get(i);
+    }
+
+    /** */
+    public String getEvent(int i) {
+        return mLastEvents.get(i);
+    }
+
     public static final Creator<SyncStatusInfo> CREATOR = new Creator<SyncStatusInfo>() {
         public SyncStatusInfo createFromParcel(Parcel in) {
             return new SyncStatusInfo(in);
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 9a01476..8659140 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -20,7 +20,6 @@
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.content.res.Configuration.NativeConfig;
-import android.content.res.TypedArray;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Printer;
@@ -28,8 +27,6 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
-import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
-
 /**
  * Information you can retrieve about a particular application
  * activity or receiver. This corresponds to information collected
@@ -441,6 +438,7 @@
      * @hide
      */
     public static final int FLAG_SUPPORTS_PICTURE_IN_PICTURE = 0x400000;
+
     /**
      * @hide Bit in {@link #flags}: If set, this component will only be seen
      * by the system user.  Only works with broadcast receivers.  Set from the
@@ -978,20 +976,12 @@
      * Returns true if the activity's orientation is fixed.
      * @hide
      */
-    public boolean isFixedOrientation() {
+    boolean isFixedOrientation() {
         return isFixedOrientationLandscape() || isFixedOrientationPortrait()
                 || screenOrientation == SCREEN_ORIENTATION_LOCKED;
     }
 
     /**
-     * Returns true if the specified orientation is considered fixed.
-     * @hide
-     */
-    static public boolean isFixedOrientation(int orientation) {
-        return isFixedOrientationLandscape(orientation) || isFixedOrientationPortrait(orientation);
-    }
-
-    /**
      * Returns true if the activity's orientation is fixed to landscape.
      * @hide
      */
@@ -1170,25 +1160,6 @@
         dest.writeFloat(maxAspectRatio);
     }
 
-    /**
-     * Determines whether the {@link Activity} is considered translucent or floating.
-     * @hide
-     */
-    public static boolean isTranslucentOrFloating(TypedArray attributes) {
-        final boolean isTranslucent =
-                attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent,
-                        false);
-        final boolean isSwipeToDismiss = !attributes.hasValue(
-                com.android.internal.R.styleable.Window_windowIsTranslucent)
-                && attributes.getBoolean(
-                        com.android.internal.R.styleable.Window_windowSwipeToDismiss, false);
-        final boolean isFloating =
-                attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating,
-                        false);
-
-        return isFloating || isTranslucent || isSwipeToDismiss;
-    }
-
     public static final Parcelable.Creator<ActivityInfo> CREATOR
             = new Parcelable.Creator<ActivityInfo>() {
         public ActivityInfo createFromParcel(Parcel source) {
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 06f7916..70af021 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -688,6 +688,10 @@
      * Cycles do not exist because they are illegal and screened for during installation.
      *
      * May be null if no splits are installed, or if no dependencies exist between them.
+     *
+     * NOTE: Any change to the way split dependencies are stored must update the logic that
+     *       creates the class loader context for dexopt (DexoptUtils#getClassLoaderContexts).
+     *
      * @hide
      */
     public SparseArray<int[]> splitDependencies;
diff --git a/core/java/android/content/pm/IDexModuleRegisterCallback.aidl b/core/java/android/content/pm/IDexModuleRegisterCallback.aidl
new file mode 100644
index 0000000..4af6999
--- /dev/null
+++ b/core/java/android/content/pm/IDexModuleRegisterCallback.aidl
@@ -0,0 +1,28 @@
+/*
+** 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.content.pm;
+
+import android.os.Bundle;
+
+/**
+ * Callback for registering a dex module with the Package Manager.
+ *
+ * @hide
+ */
+oneway interface IDexModuleRegisterCallback {
+    void onDexModuleRegistered(in String dexModulePath, in boolean success, in String message);
+}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index e8e0eb3..c9afd6b 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -25,6 +25,7 @@
 import android.content.pm.ChangedPackages;
 import android.content.pm.InstantAppInfo;
 import android.content.pm.FeatureInfo;
+import android.content.pm.IDexModuleRegisterCallback;
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageDeleteObserver;
@@ -71,7 +72,7 @@
     String[] currentToCanonicalPackageNames(in String[] names);
     String[] canonicalToCurrentPackageNames(in String[] names);
 
-    PermissionInfo getPermissionInfo(String name, int flags);
+    PermissionInfo getPermissionInfo(String name, String packageName, int flags);
 
     ParceledListSlice queryPermissionsByGroup(String group, int flags);
 
@@ -468,19 +469,51 @@
      * Notify the package manager that a list of dex files have been loaded.
      *
      * @param loadingPackageName the name of the package who performs the load
-     * @param dexPats the list of the dex files paths that have been loaded
+     * @param classLoadersNames the names of the class loaders present in the loading chain. The
+     *    list encodes the class loader chain in the natural order. The first class loader has
+     *    the second one as its parent and so on. The dex files present in the class path of the
+     *    first class loader will be recorded in the usage file.
+     * @param classPaths the class paths corresponding to the class loaders names from
+     *     {@param classLoadersNames}. The the first element corresponds to the first class loader
+     *     and so on. A classpath is represented as a list of dex files separated by
+     *     {@code File.pathSeparator}.
+     *     The dex files found in the first class path will be recorded in the usage file.
      * @param loaderIsa the ISA of the loader process
      */
-    oneway void notifyDexLoad(String loadingPackageName, in List<String> dexPaths,
-            String loaderIsa);
+    oneway void notifyDexLoad(String loadingPackageName, in List<String> classLoadersNames,
+            in List<String> classPaths, String loaderIsa);
 
     /**
-     * Ask the package manager to perform a dex-opt for the given reason. The package
-     * manager will map the reason to a compiler filter according to the current system
-     * configuration.
+     * Register an application dex module with the package manager.
+     * The package manager will keep track of the given module for future optimizations.
+     *
+     * Dex module optimizations will disable the classpath checking at runtime. The client bares
+     * the responsibility to ensure that the static assumptions on classes in the optimized code
+     * hold at runtime (e.g. there's no duplicate classes in the classpath).
+     *
+     * Note that the package manager already keeps track of dex modules loaded with
+     * {@link dalvik.system.DexClassLoader} and {@link dalvik.system.PathClassLoader}.
+     * This can be called for an eager registration.
+     *
+     * The call might take a while and the results will be posted on the main thread, using
+     * the given callback.
+     *
+     * If the module is intended to be shared with other apps, make sure that the file
+     * permissions allow for it.
+     * If at registration time the permissions allow for others to read it, the module would
+     * be marked as a shared module which might undergo a different optimization strategy.
+     * (usually shared modules will generated larger optimizations artifacts,
+     * taking more disk space).
+     *
+     * @param packageName the package name to which the dex module belongs
+     * @param dexModulePath the absolute path of the dex module.
+     * @param isSharedModule whether or not the module is intended to be used by other apps.
+     * @param callback if not null,
+     *   {@link android.content.pm.IDexModuleRegisterCallback.IDexModuleRegisterCallback#onDexModuleRegistered}
+     *   will be called once the registration finishes.
      */
-    boolean performDexOpt(String packageName, boolean checkProfiles,
-            int compileReason, boolean force, boolean bootComplete);
+     oneway void registerDexModule(in String packageName, in String dexModulePath,
+             in boolean isSharedModule, IDexModuleRegisterCallback callback);
 
     /**
      * Ask the package manager to perform a dex-opt with the given compiler filter.
@@ -489,7 +522,7 @@
      *       definite state.
      */
     boolean performDexOptMode(String packageName, boolean checkProfiles,
-            String targetCompilerFilter, boolean force, boolean bootComplete);
+            String targetCompilerFilter, boolean force, boolean bootComplete, String splitName);
 
     /**
      * Ask the package manager to perform a dex-opt with the given compiler filter on the
diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java
index 358787e..e9c9588 100644
--- a/core/java/android/content/pm/LauncherActivityInfo.java
+++ b/core/java/android/content/pm/LauncherActivityInfo.java
@@ -20,12 +20,10 @@
 import android.content.Context;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
-import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.DisplayMetrics;
-import android.util.Log;
 
 /**
  * A representation of an activity that can belong to this user or a managed
@@ -173,12 +171,6 @@
     public Drawable getBadgedIcon(int density) {
         Drawable originalIcon = getIcon(density);
 
-        if (originalIcon instanceof BitmapDrawable) {
-            // TODO: Go through LauncherAppsService
-            return mPm.getUserBadgedIcon(originalIcon, mUser);
-        } else {
-            Log.e(TAG, "Unable to create badged icon for " + mActivityInfo);
-        }
-        return originalIcon;
+        return mPm.getUserBadgedIcon(originalIcon, mUser);
     }
 }
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index ed41e79..aa9562f 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -608,15 +608,15 @@
     }
 
     /**
-     * Get {@link ApplicationInfo} for a profile
+     * Returns {@link ApplicationInfo} about an application installed for a specific user profile.
      *
      * @param packageName The package name of the application
      * @param flags Additional option flags {@link PackageManager#getApplicationInfo}
      * @param user The UserHandle of the profile.
      *
-     * @return An {@link ApplicationInfo} containing information about the package or
-     *         null if the package isn't installed for the given user, or the target user
-     *         is not enabled.
+     * @return {@link ApplicationInfo} containing information about the package. Returns
+     *         {@code null} if the package isn't installed for the given profile, or the profile
+     *         isn't enabled.
      */
     public ApplicationInfo getApplicationInfo(@NonNull String packageName,
             @ApplicationInfoFlags int flags, @NonNull UserHandle user)
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 7f3f35f..2add9a3b 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -24,6 +24,7 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.app.ActivityManager;
+import android.app.AppGlobals;
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.pm.PackageManager.InstallReason;
@@ -1355,6 +1356,17 @@
          * if unavailable.
          */
         public @Nullable Bitmap getAppIcon() {
+            if (appIcon == null) {
+                // Icon may have been omitted for calls that return bulk session
+                // lists, so try fetching the specific icon.
+                try {
+                    final SessionInfo info = AppGlobals.getPackageManager().getPackageInstaller()
+                            .getSessionInfo(sessionId);
+                    appIcon = (info != null) ? info.appIcon : null;
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
+            }
             return appIcon;
         }
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index be2cd10..06dbc0b 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1898,6 +1898,14 @@
     public static final String FEATURE_VULKAN_HARDWARE_VERSION = "android.hardware.vulkan.version";
 
     /**
+     * The device includes broadcast radio tuner.
+     *
+     * @hide FutureFeature
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_RADIO = "android.hardware.radio";
+
+    /**
      * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device includes an accelerometer.
      */
@@ -2031,6 +2039,15 @@
             "android.hardware.telephony.carrierlock";
 
     /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device
+     * supports embedded subscriptions on eUICCs.
+     * TODO(b/35851809): Make this public.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_TELEPHONY_EUICC = "android.hardware.telephony.euicc";
+
+    /**
      * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device supports connecting to USB devices
      * as the USB host.
@@ -2267,6 +2284,14 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device supports Wi-Fi Passpoint.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_WIFI_PASSPOINT = "android.hardware.wifi.passpoint";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: This is a device dedicated to showing UI
      * on a vehicle headunit. A headunit here is defined to be inside a
      * vehicle that may or may not be moving. A headunit uses either a
@@ -2312,6 +2337,18 @@
     public static final String FEATURE_EMBEDDED = "android.hardware.type.embedded";
 
     /**
+     * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: This is a device dedicated to be primarily used
+     * with keyboard, mouse or touchpad. This includes traditional desktop
+     * computers, laptops and variants such as convertibles or detachables.
+     * Due to the larger screen, the device will most likely use the
+     * {@link #FEATURE_FREEFORM_WINDOW_MANAGEMENT} feature as well.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_PC = "android.hardware.type.pc";
+
+    /**
      * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
      * The device supports printing.
      */
@@ -5731,4 +5768,46 @@
      * @hide
      */
     public abstract String getInstantAppAndroidId(String packageName, @NonNull UserHandle user);
+
+    /**
+     * Callback use to notify the callers of module registration that the operation
+     * has finished.
+     *
+     * @hide
+     */
+    public static abstract class DexModuleRegisterCallback {
+        public abstract void onDexModuleRegistered(String dexModulePath, boolean success,
+                String message);
+    }
+
+    /**
+     * Register an application dex module with the package manager.
+     * The package manager will keep track of the given module for future optimizations.
+     *
+     * Dex module optimizations will disable the classpath checking at runtime. The client bares
+     * the responsibility to ensure that the static assumptions on classes in the optimized code
+     * hold at runtime (e.g. there's no duplicate classes in the classpath).
+     *
+     * Note that the package manager already keeps track of dex modules loaded with
+     * {@link dalvik.system.DexClassLoader} and {@link dalvik.system.PathClassLoader}.
+     * This can be called for an eager registration.
+     *
+     * The call might take a while and the results will be posted on the main thread, using
+     * the given callback.
+     *
+     * If the module is intended to be shared with other apps, make sure that the file
+     * permissions allow for it.
+     * If at registration time the permissions allow for others to read it, the module would
+     * be marked as a shared module which might undergo a different optimization strategy.
+     * (usually shared modules will generated larger optimizations artifacts,
+     * taking more disk space).
+     *
+     * @param dexModulePath the absolute path of the dex module.
+     * @param callback if not null, {@link DexModuleRegisterCallback#onDexModuleRegistered} will
+     *                 be called once the registration finishes.
+     *
+     * @hide
+     */
+    public abstract void registerDexModule(String dexModulePath,
+            @Nullable DexModuleRegisterCallback callback);
 }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c67376c..bcba938e 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -40,7 +40,7 @@
 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
 import static android.os.Build.VERSION_CODES.O;
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
-import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
 
 import android.annotation.IntRange;
 import android.annotation.NonNull;
@@ -200,6 +200,8 @@
     // Temporary workaround; allow meta-data to expose components to instant apps
     private static final String META_DATA_INSTANT_APPS = "instantapps.clients.allowed";
 
+    private static final String METADATA_MAX_ASPECT_RATIO = "android.max_aspect";
+
     /**
      * Bit mask of all the valid bits that can be set in recreateOnConfigChanges.
      * @hide
@@ -3639,6 +3641,7 @@
 
         final int innerDepth = parser.getDepth();
         int type;
+
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                 && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
@@ -3815,6 +3818,10 @@
             }
         }
 
+        // Must be ran after the entire {@link ApplicationInfo} has been fully processed and after
+        // every activity info has had a chance to set it from its attributes.
+        setMaxAspectRatio(owner);
+
         modifySharedLibrariesForBackwardCompatibility(owner);
 
         if (hasDomainURLs(owner)) {
@@ -4258,7 +4265,12 @@
                 a.info.flags |= FLAG_ALWAYS_FOCUSABLE;
             }
 
-            setActivityMaxAspectRatio(a.info, sa, owner);
+            if (sa.hasValue(R.styleable.AndroidManifestActivity_maxAspectRatio)
+                    && sa.getType(R.styleable.AndroidManifestActivity_maxAspectRatio)
+                    == TypedValue.TYPE_FLOAT) {
+                a.setMaxAspectRatio(sa.getFloat(R.styleable.AndroidManifestActivity_maxAspectRatio,
+                        0 /*default*/));
+            }
 
             a.info.lockTaskLaunchMode =
                     sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0);
@@ -4271,7 +4283,7 @@
                 sa.getString(R.styleable.AndroidManifestActivity_enableVrMode);
 
             a.info.rotationAnimation =
-                sa.getInt(R.styleable.AndroidManifestActivity_rotationAnimation, ROTATION_ANIMATION_ROTATE);
+                sa.getInt(R.styleable.AndroidManifestActivity_rotationAnimation, ROTATION_ANIMATION_UNSPECIFIED);
 
             a.info.colorMode = sa.getInt(R.styleable.AndroidManifestActivity_colorMode,
                     ActivityInfo.COLOR_MODE_DEFAULT);
@@ -4496,28 +4508,40 @@
         }
     }
 
-    private void setActivityMaxAspectRatio(ActivityInfo aInfo, TypedArray sa, Package owner) {
-        if (aInfo.resizeMode == RESIZE_MODE_RESIZEABLE
-                || aInfo.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
-            // Resizeable activities can be put in any aspect ratio.
-            aInfo.maxAspectRatio = 0;
-            return;
-        }
-
+    /**
+     * Sets every the max aspect ratio of every child activity that doesn't already have an aspect
+     * ratio set.
+     */
+    private void setMaxAspectRatio(Package owner) {
         // Default to (1.86) 16.7:9 aspect ratio for pre-O apps and unset for O and greater.
         // NOTE: 16.7:9 was the max aspect ratio Android devices can support pre-O per the CDD.
-        float defaultMaxAspectRatio = owner.applicationInfo.targetSdkVersion < O
+        float maxAspectRatio = owner.applicationInfo.targetSdkVersion < O
                 ? DEFAULT_PRE_O_MAX_ASPECT_RATIO : 0;
-        if (owner.applicationInfo.maxAspectRatio != 0 ) {
+
+        if (owner.applicationInfo.maxAspectRatio != 0) {
             // Use the application max aspect ration as default if set.
-            defaultMaxAspectRatio = owner.applicationInfo.maxAspectRatio;
+            maxAspectRatio = owner.applicationInfo.maxAspectRatio;
+        } else if (owner.mAppMetaData != null
+                && owner.mAppMetaData.containsKey(METADATA_MAX_ASPECT_RATIO)) {
+            maxAspectRatio = owner.mAppMetaData.getFloat(METADATA_MAX_ASPECT_RATIO, maxAspectRatio);
         }
 
-        aInfo.maxAspectRatio = sa.getFloat(
-                R.styleable.AndroidManifestActivity_maxAspectRatio, defaultMaxAspectRatio);
-        if (aInfo.maxAspectRatio < 1.0f && aInfo.maxAspectRatio != 0) {
-            // Ignore any value lesser than 1.0.
-            aInfo.maxAspectRatio = 0;
+        for (Activity activity : owner.activities) {
+            // If the max aspect ratio for the activity has already been set, skip.
+            if (activity.hasMaxAspectRatio()) {
+                continue;
+            }
+
+            // By default we prefer to use a values defined on the activity directly than values
+            // defined on the application. We do not check the styled attributes on the activity
+            // as it would have already been set when we processed the activity. We wait to process
+            // the meta data here since this method is called at the end of processing the
+            // application and all meta data is guaranteed.
+            final float activityAspectRatio = activity.metaData != null
+                    ? activity.metaData.getFloat(METADATA_MAX_ASPECT_RATIO, maxAspectRatio)
+                    : maxAspectRatio;
+
+            activity.setMaxAspectRatio(activityAspectRatio);
         }
     }
 
@@ -4658,6 +4682,7 @@
         info.windowLayout = target.info.windowLayout;
         info.resizeMode = target.info.resizeMode;
         info.maxAspectRatio = target.info.maxAspectRatio;
+
         info.encryptionAware = info.directBootAware = target.info.directBootAware;
 
         Activity a = new Activity(mParseActivityAliasArgs, info);
@@ -6940,6 +6965,11 @@
 
     public final static class Activity extends Component<ActivityIntentInfo> implements Parcelable {
         public final ActivityInfo info;
+        private boolean mHasMaxAspectRatio;
+
+        private boolean hasMaxAspectRatio() {
+            return mHasMaxAspectRatio;
+        }
 
         public Activity(final ParseComponentArgs args, final ActivityInfo _info) {
             super(args, _info);
@@ -6952,6 +6982,23 @@
             info.packageName = packageName;
         }
 
+
+        private void setMaxAspectRatio(float maxAspectRatio) {
+            if (info.resizeMode == RESIZE_MODE_RESIZEABLE
+                    || info.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
+                // Resizeable activities can be put in any aspect ratio.
+                return;
+            }
+
+            if (maxAspectRatio < 1.0f && maxAspectRatio != 0) {
+                // Ignore any value lesser than 1.0.
+                return;
+            }
+
+            info.maxAspectRatio = maxAspectRatio;
+            mHasMaxAspectRatio = true;
+        }
+
         public String toString() {
             StringBuilder sb = new StringBuilder(128);
             sb.append("Activity{");
@@ -6971,11 +7018,13 @@
         public void writeToParcel(Parcel dest, int flags) {
             super.writeToParcel(dest, flags);
             dest.writeParcelable(info, flags | Parcelable.PARCELABLE_ELIDE_DUPLICATES);
+            dest.writeBoolean(mHasMaxAspectRatio);
         }
 
         private Activity(Parcel in) {
             super(in);
             info = in.readParcelable(Object.class.getClassLoader());
+            mHasMaxAspectRatio = in.readBoolean();
 
             for (ActivityIntentInfo aii : intents) {
                 aii.activity = this;
diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java
index c0b82b4..61b0eb0 100644
--- a/core/java/android/content/pm/ShortcutManager.java
+++ b/core/java/android/content/pm/ShortcutManager.java
@@ -36,161 +36,72 @@
 import java.util.List;
 
 /**
- * The ShortcutManager manages an app's <em>shortcuts</em>. Shortcuts provide users
- * with quick access to activities other than an app's main activity in the currently-active
- * launcher.  For example,
- * an email app may publish the "compose new email" action, which will directly open the
- * compose activity.  The {@link ShortcutInfo} class contains information about each of the
- * shortcuts themselves.
+ * The ShortcutManager manages an app's <em>shortcuts</em>. Shortcuts provide users with quick
+ * access to activities other than an app's main activity in the currently-active launcher, provided
+ * that the launcher supports app shortcuts.  For example, an email app may publish the "compose new
+ * email" action, which will directly open the compose activity.  The {@link ShortcutInfo} class
+ * contains information about each of the shortcuts themselves.
  *
- * <h3>Static Shortcuts and Dynamic Shortcuts</h3>
+ * <p>This page discusses the implementation details of the <code>ShortcutManager</code> class. For
+ * guidance on performing operations on app shortcuts within your app, see the
+ * <a href="/guide/topics/ui/shortcuts.html">App Shortcuts</a> feature guide.
  *
- * <p>
- * There are several different types of shortcuts:
+ * <h3>Shortcut characteristics</h3>
  *
- * <ul>
- * <li><p>Static shortcuts are declared in a resource XML file, which is referenced in the publisher
- * app's <code>AndroidManifest.xml</code> file. These shortcuts are visually associated with an
- * app's launcher icon.
- * <p>Static shortcuts are published when an app is installed, and the details of these shortcuts
- * change when an app is upgraded with an updated XML file. Static shortcuts are immutable, and
- * their definitions, such as icons and labels, cannot be changed dynamically without upgrading the
- * publisher app.</li>
+ * This section describes in-depth details about each shortcut type's usage and availability.
  *
- * <li>Dynamic shortcuts are published at runtime using this class's APIs. These shortcuts are
- * visually associated with an app's launcher icon. Apps can publish, update, and remove dynamic
- * shortcuts at runtime.
- * </ul>
+ * <p class="note"><b>Important security note:</b> All shortcut information is stored in
+ * <a href="/training/articles/direct-boot.html">credential encrypted storage</a>, so your app
+ * cannot access a user's shortcuts until after they've unlocked the device.
  *
- * <p>Only main activities&mdash;activities that handle the {@code MAIN} action and the
- * {@code LAUNCHER} category&mdash;can have shortcuts.
- * If an app has multiple main activities, these activities have different sets
- * of shortcuts.
+ * <h4>Static and dynamic shortcuts</h4>
  *
  * <p>Static shortcuts and dynamic shortcuts are shown in a supported launcher when the user
- * long-presses on an app's launcher icon. Note that the actual gesture may be different
- * depending on the launcher app.
+ * performs a specific gesture. On currently-supported launchers, the gesture is a long-press on the
+ * app's launcher icon, but the actual gesture may be different on other launcher apps.
  *
- * <p>Each launcher icon can have at most {@link #getMaxShortcutCountPerActivity()} number of
- * static and dynamic shortcuts combined.
+ * <p>The {@link LauncherApps} class provides APIs for launcher apps to access shortcuts.
  *
+ * <h4>Pinned shortcuts</h4>
  *
- * <h3>Pinning Shortcuts</h3>
+ * <p>Because pinned shortcuts appear in the launcher itself, they're always visible. A pinned
+ * shortcut is removed from the launcher only in the following situations:
+ * <ul>
+ *     <li>The user removes it.
+ *     <li>The publisher app associated with the shortcut is uninstalled.
+ *     <li>The user performs the clear data action on the publisher app from the device's
+ *     <b>Settings</b> app.
+ * </ul>
  *
- * <p>Apps running in the foreground can also <em>pin</em> shortcuts at runtime, subject to user
- * permission, using this class's APIs. Each pinned shortcut is a copy of a static shortcut or a
- * dynamic shortcut. Although users can pin a shortcut multiple times, the system calls the pinning
- * API only once to complete the pinning process. Unlike static and dynamic shortcuts, pinned
- * shortcuts appear as separate icons, visually distinct from the app's launcher icon, in the
- * launcher. There is no limit to the number of pinned shortcuts that an app can create.
+ * <p>Because the system performs
+ * <a href="/guide/topics/ui/shortcuts.html#backup-and-restore">backup and restore</a> on pinned
+ * shortcuts automatically, these shortcuts' IDs should contain either stable, constant strings or
+ * server-side identifiers, rather than identifiers generated locally that might not make sense on
+ * other devices.
  *
- * <p>Pinned shortcuts <strong>cannot</strong> be removed by publisher apps. They're removed only
- * when the user removes them, when the publisher app is uninstalled, or when the user performs the
- * clear data action on the publisher app from the device's <b>Settings</b> app.
+ * <h3>Shortcut display order</h3>
  *
- * <p>However, the publisher app can <em>disable</em> pinned shortcuts so they cannot be started.
- * See the following sections for details.
+ * <p>When the launcher displays an app's shortcuts, they should appear in the following order:
  *
- * <h3>Updating and Disabling Shortcuts</h3>
+ * <ul>
+ *   <li>Static shortcuts (if {@link ShortcutInfo#isDeclaredInManifest()} is {@code true}),
+ *   and then show dynamic shortcuts (if {@link ShortcutInfo#isDynamic()} is {@code true}).
+ *   <li>Within each shortcut type (static and dynamic), sort the shortcuts in order of increasing
+ *   rank according to {@link ShortcutInfo#getRank()}.
+ * </ul>
  *
- * <p>When a dynamic shortcut is pinned, even when the publisher removes it as a dynamic shortcut,
- * the pinned shortcut will still be visible and launchable.  This allows an app to have
- * more than {@link #getMaxShortcutCountPerActivity()} number of shortcuts.
+ * <p>Shortcut ranks are non-negative, sequential integers that determine the order in which
+ * shortcuts appear, assuming that the shortcuts are all in the same category. You can update ranks
+ * of existing shortcuts when you call {@link #updateShortcuts(List)},
+ * {@link #addDynamicShortcuts(List)}, or {@link #setDynamicShortcuts(List)}.
  *
- * <p>For example, suppose {@link #getMaxShortcutCountPerActivity()} is 5:
- * <ol>
- *     <li>A chat app publishes 5 dynamic shortcuts for the 5 most recent
- *     conversations (c1, c2, ..., c5).
+ * <p class="note"><b>Note:</b> Ranks are auto-adjusted so that they're unique for each type of
+ * shortcut (static or dynamic). For example, if there are 3 dynamic shortcuts with ranks 0, 1 and
+ * 2, adding another dynamic shortcut with a rank of 1 represents a request to place this shortcut
+ * at the second position. In response, the third and fourth shortcuts move closer to the bottom of
+ * the shortcut list, with their ranks changing to 2 and 3, respectively.
  *
- *     <li>The user pins all 5 of the shortcuts.
- *
- *     <li>Later, the user has started 3 additional conversations (c6, c7, and c8),
- *     so the publisher app
- *     re-publishes its dynamic shortcuts.  The new dynamic shortcut list is:
- *     c4, c5, ..., c8.
- *     The publisher app has to remove c1, c2, and c3 because it can't have more than
- *     5 dynamic shortcuts.
- *
- *     <li>However, even though c1, c2, and c3 are no longer dynamic shortcuts, the pinned
- *     shortcuts for these conversations are still available and launchable.
- *
- *     <li>At this point, the user can access a total of 8 shortcuts that link to activities in
- *     the publisher app, including the 3 pinned
- *     shortcuts, even though an app can have at most 5 dynamic shortcuts.
- *
- *     <li>The app can use {@link #updateShortcuts(List)} to update <em>any</em> of the existing
- *     8 shortcuts, when, for example, the chat peers' icons have changed.
- * </ol>
- * The {@link #addDynamicShortcuts(List)} and {@link #setDynamicShortcuts(List)} methods
- * can also be used
- * to update existing shortcuts with the same IDs, but they <b>cannot</b> be used
- * for updating non-dynamic, pinned shortcuts because these two methods try to convert the given
- * lists of shortcuts to dynamic shortcuts.
- *
- *
- * <h4>Disabling Static Shortcuts</h4>
- * <p>When an app is upgraded and the new version
- * no longer uses a static shortcut that appeared in the previous version, this deprecated
- * shortcut isn't published as a static shortcut.
- *
- * <p>If the deprecated shortcut is pinned, then the pinned shortcut will remain on the launcher,
- * but it's disabled automatically. When a pinned shortcut is disabled, this class's APIs cannot
- * update it.
- *
- * <h4>Disabling Dynamic Shortcuts</h4>
- * Sometimes pinned shortcuts become obsolete and may not be usable.  For example, a pinned shortcut
- * to a group chat becomes unusable when the associated group chat is deleted.  In cases like this,
- * apps should use {@link #disableShortcuts(List)}, which removes the specified dynamic
- * shortcuts and also makes any specified pinned shortcuts un-launchable.
- * The {@link #disableShortcuts(List, CharSequence)} method can also be used to disable shortcuts
- * and show users a custom error message when they attempt to launch the disabled shortcuts.
- *
- *
- * <h3>Publishing Static Shortcuts</h3>
- *
- * <p>
- * In order to add static shortcuts to your app, first add
- * {@code <meta-data android:name="android.app.shortcuts" />} to your main activity in
- * AndroidManifest.xml:
- * <pre>
- *&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
- *             package="com.example.myapplication"&gt;
- *  &lt;application ... &gt;
- *    &lt;activity android:name="Main"&gt;
- *      &lt;intent-filter&gt;
- *        &lt;action android:name="android.intent.action.MAIN" /&gt;
- *        &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
- *      &lt;/intent-filter&gt;
- *      <strong>&lt;meta-data android:name="android.app.shortcuts"
- *                 android:resource="@xml/shortcuts" /&gt;</strong>
- *    &lt;/activity&gt;
- *  &lt;/application&gt;
- *&lt;/manifest&gt;
- * </pre>
- *
- * Then, define your app's static shortcuts in the <code>res/xml/shortcuts.xml</code>
- * file:
- * <pre>
- *&lt;shortcuts xmlns:android="http://schemas.android.com/apk/res/android"&gt;
- *  &lt;shortcut
- *    android:shortcutId="compose"
- *    android:enabled="true"
- *    android:icon="@drawable/compose_icon"
- *    android:shortcutShortLabel="@string/compose_shortcut_short_label1"
- *    android:shortcutLongLabel="@string/compose_shortcut_long_label1"
- *    android:shortcutDisabledMessage="@string/compose_disabled_message1"&gt;
- *    &lt;intent
- *      android:action="android.intent.action.VIEW"
- *      android:targetPackage="com.example.myapplication"
- *      android:targetClass="com.example.myapplication.ComposeActivity" /&gt;
- *    &lt;!-- If your shortcut is associated with multiple intents, include them
- *         here. The last intent in the list is what the user sees when they
- *         launch this shortcut. --&gt;
- *    &lt;categories android:name="android.shortcut.conversation" /&gt;
- *  &lt;/shortcut&gt;
- *  &lt;!-- Specify more shortcuts here. --&gt;
- *&lt;/shortcuts&gt;
- * </pre>
+ * <h3>Options for static shortcuts</h3>
  *
  * The following list includes descriptions for the different attributes within a static shortcut:
  * <dl>
@@ -236,9 +147,10 @@
  *   {@code android:action} is mandatory.
  *   See <a href="{@docRoot}guide/topics/ui/settings.html#Intents">Using intents</a> for the
  *   other supported tags.
- *   You can provide multiple intents for a single shortcut so that the last defined activity is launched
- *   with the other activities in the <a href="/guide/components/tasks-and-back-stack.html">back stack</a>.
- *   See {@link android.app.TaskStackBuilder} for details.
+ *   <p>You can provide multiple intents for a single shortcut so that the last defined activity is
+ *   launched with the other activities in the
+ *   <a href="/guide/components/tasks-and-back-stack.html">back stack</a>. See
+ *   {@link android.app.TaskStackBuilder} for details.
  *   <p><b>Note:</b> String resources may not be used within an {@code <intent>} element.
  *   </dd>
  *   <dt>{@code categories}</dt>
@@ -247,337 +159,92 @@
  *   </dd>
  * </dl>
  *
- * <h3>Publishing Dynamic Shortcuts</h3>
+ * <h3>Updating shortcuts</h3>
  *
- * <p>
- * Apps can publish dynamic shortcuts with {@link #setDynamicShortcuts(List)}
- * or {@link #addDynamicShortcuts(List)}.  The {@link #updateShortcuts(List)} method can also be
- * used to update existing, mutable shortcuts.
- * Use {@link #removeDynamicShortcuts(List)} or {@link #removeAllDynamicShortcuts()} to remove
- * dynamic shortcuts.
- *
- * <p>The following code snippet shows how to create a single dynamic shortcut:
- * <pre>
- *ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
- *
- *ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "id1")
- *    .setShortLabel("Web site")
- *    .setLongLabel("Open the web site")
- *    .setIcon(Icon.createWithResource(context, R.drawable.icon_website))
- *    .setIntent(new Intent(Intent.ACTION_VIEW,
- *                   Uri.parse("https://www.mysite.example.com/")))
- *    .build();
- *
- *shortcutManager.setDynamicShortcuts(Arrays.asList(shortcut));
- * </pre>
- *
- * <h3>Publishing Pinned Shortcuts</h3>
- *
- * <p>Apps can pin an existing shortcut (either static or dynamic) or an entirely new shortcut to a
- * supported launcher programatically using {@link #requestPinShortcut(ShortcutInfo, IntentSender)}.
- * You pass two arguments into this method:
- *
- * <ul>
- *   <li>A {@link ShortcutInfo} object &ndash; If the shortcut already exists, this object should
- *   contain only the shortcut's ID. Otherwise, the new {@link ShortcutInfo} object must contain an
- *   ID, an intent, and a short label for the new shortcut.
- *   <li><p>A {@link android.app.PendingIntent} object &ndash; This intent represents the callback
- *   that your app receives if the shortcut is successfully pinned to the device's launcher.
- *   <p><b>Note:</b> If the user doesn't allow the shortcut to be pinned to the launcher, the
- *   pinning process fails, and the {@link Intent} object that is passed into this
- *   {@link android.app.PendingIntent} object isn't executed.
- *   <div class="note"><p><b>Note:</b> Due to background execution limits introduced in Android
- *   {@link VERSION_CODES#O}, it's best to use a
- *   <a href="{@docRoot}guide/components/broadcasts.html#manifest-declared_receivers">
- *   manifest-declared receiver</a> to receive a callback.
- *   <p>Also, to prevent other apps from invoking the receiver, add the attribute assignment
- *   <code>android:exported="false"</code> to the receiver's manifest entry.</p></div>
- * </ul>
- *
- * The following code snippet shows how to pin a single shortcut that already exists and is enabled:
- *
- * <pre>
- *ShortcutManager mShortcutManager =
- *        context.getSystemService(ShortcutManager.class);
- *
- *if (mShortcutManager.isRequestPinShortcutSupported()) {
- *
- *    // This example defines a new shortcut; that is, this shortcut hasn't
- *    // been published before.
- *    ShortcutInfo pinShortcutInfo = new ShortcutInfo.Builder()
- *            .setIcon(myIcon)
- *            .setShortLabel("My awesome shortcut")
- *            .setIntent(myIntent)
- *            .build();
- *
- *    PendingIntent resultPendingIntent = null;
- *
- *    // Create the following Intent and PendingIntent objects only if your app
- *    // needs to be notified that the user allowed the shortcut to be pinned.
- *    // Use a boolean value, such as "appNeedsNotifying", to define this behavior.
- *    if (appNeedsNotifying) {
- *        // We assume here the app has a manifest-declared receiver "MyReceiver".
- *        Intent pinnedShortcutCallbackIntent = new Intent(context, MyReceiver.class);
- *
- *        // Configure the intent so that your app's broadcast receiver gets
- *        // the callback successfully.
- *        PendingIntent successCallback = PendingIntent.createBroadcast(context, 0,
- *                pinnedShortcutCallbackIntent);
- *
- *        resultPendingIntent = successCallback.getIntentSender();
- *    }
- *
- *    mShortcutManager.requestPinShortcut(pinShortcutInfo, resultPendingIntent);
- *}
- * </pre>
- *
- * <p class="note"><strong>Note:</strong> As you add logic in your app to make requests to pin
- * shortcuts, keep in mind that not all launchers support pinning of shortcuts. To determine whether
- * your app can complete this process on a particular device, check the return value of
- * {@link #isRequestPinShortcutSupported()}. Based on this return value, you might decide to hide
- * the option in your app that allows users to pin a shortcut.
- *
- * <p class="note"><strong>Note:</strong> See also the support library APIs
- * {@link android.support.v4.content.pm.ShortcutManagerCompat#isRequestPinShortcutSupported(
- * Context)} and
- * {@link android.support.v4.content.pm.ShortcutManagerCompat#requestPinShortcut(
- * Context, ShortcutInfoCompat, IntentSender)}, which works on Android versions lower than
- * {@link VERSION_CODES#O} by falling back to the deprecated private intent
- * {@code com.android.launcher.action.INSTALL_SHORTCUT}.
- *
- * <h4>Custom Activity for Pinning Shortcuts</h4>
- *
- * <p>You can also create a specialized activity that helps users create shortcuts, complete with
- * custom options and a confirmation button. In your app's manifest file, add
- * {@link Intent#ACTION_CREATE_SHORTCUT} to the activity's <code>&lt;intent-filter&gt;</code>
- * element, as shown in the following snippet:
- *
- * <pre>
- *&lt;manifest&gt;
- *    ...
- *    &lt;application&gt;
- *        &lt;activity android:name="com.example.MyCustomPromptToPinShortcut" ... &gt;
- *            &lt;intent-filter
- *                    action android:name="android.intent.action.ACTION_CREATE_SHORTCUT"&gt;
- *            ...
- *            &lt;/intent-filter&gt;
- *        &lt;/activity&gt;
- *        ...
- *    &lt;/application&gt;
- *&lt;/manifest&gt;
- * </pre>
- *
- * <p>When you use this specialized activity in your app, the following sequence of steps takes
- * place:</p>
- *
+ * <p>As an example, suppose {@link #getMaxShortcutCountPerActivity()} is 5:
  * <ol>
- *   <li>The user attempts to create a shortcut, triggering the system to start the specialized
- *   activity.</li>
- *   <li>The user sets options for the shortcut.</li>
- *   <li>The user selects the confirmation button, allowing your app to create the shortcut using
- *   the {@link #createShortcutResultIntent(ShortcutInfo)} method. This method returns an
- *   {@link Intent}, which your app relays back to the previously-executing activity using
- *   {@link Activity#setResult(int)}.</li>
- *   <li>Your app calls {@link Activity#finish()} on the activity used for creating the customized
- *   shortcut.</li>
+ *     <li>A chat app publishes 5 dynamic shortcuts for the 5 most recent
+ *     conversations (c1, c2, ..., c5).
+ *
+ *     <li>The user pins all 5 of the shortcuts.
+ *
+ *     <li>Later, the user has started 3 additional conversations (c6, c7, and c8),
+ *     so the publisher app
+ *     re-publishes its dynamic shortcuts.  The new dynamic shortcut list is:
+ *     c4, c5, ..., c8.
+ *     The publisher app has to remove c1, c2, and c3 because it can't have more than
+ *     5 dynamic shortcuts.
+ *
+ *     <li>However, even though c1, c2, and c3 are no longer dynamic shortcuts, the pinned
+ *     shortcuts for these conversations are still available and launchable.
+ *
+ *     <li>At this point, the user can access a total of 8 shortcuts that link to activities in
+ *     the publisher app, including the 3 pinned shortcuts, even though an app can have at most 5
+ *     dynamic shortcuts.
+ *
+ *     <li>The app can use {@link #updateShortcuts(List)} to update <em>any</em> of the existing
+ *     8 shortcuts, when, for example, the chat peers' icons have changed.
+ *     <p>The {@link #addDynamicShortcuts(List)} and {@link #setDynamicShortcuts(List)} methods
+ *     can also be used to update existing shortcuts with the same IDs, but they <b>cannot</b> be
+ *     used for updating non-dynamic, pinned shortcuts because these 2 methods try to convert the
+ *     given lists of shortcuts to dynamic shortcuts.
  * </ol>
  *
- * <h3>Shortcut Intents</h3>
+ * <h3>Shortcut intents</h3>
+ *
  * <p>
  * Dynamic shortcuts can be published with any set of {@link Intent#addFlags Intent} flags.
  * Typically, {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} is specified, possibly along with other
  * flags; otherwise, if the app is already running, the app is simply brought to
  * the foreground, and the target activity may not appear.
  *
- * <p>The {@link ShortcutInfo.Builder#setIntents(Intent[])} method can be used instead of
- * {@link ShortcutInfo.Builder#setIntent(Intent)} with {@link android.app.TaskStackBuilder}
- * in order to launch an activity with other activities in the back stack.
- * When the user selects a shortcut to load an activity with a back stack,
- * then presses the back key, a parent activity from the same app will be shown
- * instead of the user being navigated back to the launcher.
- *
- * <p>Static shortcuts can also have multiple intents to achieve the same effect.
- * In order to associate multiple {@link Intent} objects with a shortcut, simply list multiple
- * <code>&lt;intent&gt;</code> elements within a single <code>&lt;shortcut&gt;</code> element.
- * The last intent specifies what the user sees when they launch a shortcut.
- *
  * <p>Static shortcuts <b>cannot</b> have custom intent flags.
  * The first intent of a static shortcut will always have {@link Intent#FLAG_ACTIVITY_NEW_TASK}
- * and {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} set.
- * This means, when the app is already running, all the existing activities will be
- * destroyed when a static shortcut is launched.
- * If this behavior is not desirable, you can use a <em>trampoline activity</em>,
- * or an invisible activity that starts another activity in {@link Activity#onCreate},
- * then calls {@link Activity#finish()}.
- * The first activity should include an attribute setting
- * of {@code android:taskAffinity=""} in the app's <code>AndroidManifest.xml</code>
- * file, and the intent within the static shortcut should point at this first activity.
+ * and {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} set. This means, when the app is already running, all
+ * the existing activities in your app will be destroyed when a static shortcut is launched.
+ * If this behavior is not desirable, you can use a <em>trampoline activity</em>, or an invisible
+ * activity that starts another activity in {@link Activity#onCreate}, then calls
+ * {@link Activity#finish()}:
+ * <ol>
+ *     <li>In the <code>AndroidManifest.xml</code> file, the trampoline activity should include the
+ *     attribute assignment {@code android:taskAffinity=""}.
+ *     <li>In the shortcuts resource file, the intent within the static shortcut should point at
+ *     the trampoline activity.
+ * </ol>
  *
+ * <h3>Handling system locale changes</h3>
  *
- * <h3>Showing New Information in a Shortcut</h3>
- * <p>
- * In order to avoid confusion, you should not use {@link #updateShortcuts(List)} to update
- * a shortcut so that it contains conceptually different information.
+ * <p>Apps should update dynamic and pinned shortcuts when the system locale changes using the
+ * {@link Intent#ACTION_LOCALE_CHANGED} broadcast. When the system locale changes,
+ * <a href="/guide/topics/ui/shortcuts.html#rate-limit">rate limiting</a> is reset, so even
+ * background apps can add and update dynamic shortcuts until the rate limit is reached again.
  *
- * <p>For example, a phone app may publish the most frequently called contact as a dynamic
- * shortcut.  Over time, this contact may change. When it does, the app should
- * represent the changed contact with a new shortcut that contains a different ID, using either
- * {@link #setDynamicShortcuts(List)} or {@link #addDynamicShortcuts(List)}, rather than updating
- * the existing shortcut with {@link #updateShortcuts(List)}.
- * This is because when the shortcut is pinned, changing
- * it to reference a different contact will likely confuse the user.
+ * <h3>Shortcut limits</h3>
  *
- * <p>On the other hand, when the
- * contact's information has changed, such as the name or picture, the app should
- * use {@link #updateShortcuts(List)} so that the pinned shortcut is updated too.
+ * <p>Only main activities&mdash;activities that handle the {@code MAIN} action and the
+ * {@code LAUNCHER} category&mdash;can have shortcuts. If an app has multiple main activities, you
+ * need to define the set of shortcuts for <em>each</em> activity.
  *
+ * <p>Each launcher icon can have at most {@link #getMaxShortcutCountPerActivity()} number of
+ * static and dynamic shortcuts combined. There is no limit to the number of pinned shortcuts that
+ * an app can create.
  *
- * <h3>Shortcut Display Order</h3>
- * When the launcher displays the shortcuts that are associated with a particular launcher icon,
- * the shortcuts should appear in the following order:
- * <ul>
- *   <li>First show static shortcuts
- *   (if {@link ShortcutInfo#isDeclaredInManifest()} is {@code true}),
- *   and then show dynamic shortcuts (if {@link ShortcutInfo#isDynamic()} is {@code true}).
- *   <li>Within each category of shortcuts (static and dynamic), sort the shortcuts in order
- *   of increasing rank according to {@link ShortcutInfo#getRank()}.
- * </ul>
- * <p>Shortcut ranks are non-negative, sequential integers
- * that determine the order in which shortcuts appear, assuming that the shortcuts are all in
- * the same category.
- * Ranks of existing shortcuts can be updated with
- * {@link #updateShortcuts(List)}. You can also use {@link #addDynamicShortcuts(List)} and
- * {@link #setDynamicShortcuts(List)}.
+ * <p>When a dynamic shortcut is pinned, even when the publisher removes it as a dynamic shortcut,
+ * the pinned shortcut is still visible and launchable.  This allows an app to have more than
+ * {@link #getMaxShortcutCountPerActivity()} number of shortcuts.
  *
- * <p>Ranks are auto-adjusted so that they're unique for each target activity in each category
- * (static or dynamic).  For example, if there are 3 dynamic shortcuts with ranks 0, 1 and 2,
- * adding another dynamic shortcut with a rank of 1 represents a request to place this shortcut at
- * the second position.
- * In response, the third and fourth shortcuts move closer to the bottom of the shortcut list,
- * with their ranks changing to 2 and 3, respectively.
+ * <h4>Rate limiting</h4>
  *
- * <h3>Rate Limiting</h3>
+ * <p>When <a href="/guide/topics/ui/shortcuts.html#rate-limit">rate limiting</a> is active,
+ * {@link #isRateLimitingActive()} returns {@code true}.
  *
- * <p>
- * Calls to {@link #setDynamicShortcuts(List)}, {@link #addDynamicShortcuts(List)}, and
- * {@link #updateShortcuts(List)} may be rate-limited when called by <em>background apps</em>, or
- * apps with no foreground activity or service.  When you attempt to call these methods
- * from a background app after exceeding the rate limit, these APIs return {@code false}.
- *
- * <p>Apps with a foreground activity or service are not rate-limited.
- *
- * <p>Rate-limiting is reset upon certain events, so that even background apps
- * can call these APIs until the rate limit is reached again.
- * These events include the following:
+ * <p>Rate limiting is reset upon certain events, so even background apps can call these APIs until
+ * the rate limit is reached again. These events include the following:
  * <ul>
  *   <li>An app comes to the foreground.
  *   <li>The system locale changes.
  *   <li>The user performs the <strong>inline reply</strong> action on a notification.
  * </ul>
- *
- * <p>When rate-limiting is active, {@link #isRateLimitingActive()} returns {@code true}.
- *
- * <h4>Resetting rate-limiting for testing</h4>
- *
- * <p>
- * If your app is rate-limited during development or testing, you can use the
- * <strong>Reset ShortcutManager rate-limiting</strong> development option or
- * the following {@code adb} command to reset it:
- * <pre class="no-pretty-print">
- *$ adb shell cmd shortcut reset-throttling [ --user USER-ID ]
- * </pre>
- *
- * <h3>Handling System Locale Changes</h3>
- *
- * <p>
- * Apps should update dynamic and pinned shortcuts when the system locale changes
- * using the {@link Intent#ACTION_LOCALE_CHANGED} broadcast.
- *
- * <p>When the system locale changes, rate-limiting is reset, so even background apps
- * can add and update dynamic shortcuts until the rate limit is reached again.
- *
- *
- * <h3>Backup and Restore</h3>
- *
- * <p>
- * When an app has the {@code android:allowBackup="true"} attribute assignment included
- * in its <code>AndroidManifest.xml</code> file, pinned shortcuts are
- * backed up automatically and are restored when the user sets up a new device.
- *
- * <h4>Categories of shortcuts that are backed up</h4>
- *
- * <ul>
- *  <li>Pinned shortcuts are backed up.  Bitmap icons are not backed up by the system,
- *  so launcher apps should back them up and restore them so that the user still sees icons
- *  for pinned shortcuts on the launcher.  Apps can always use
- *  {@link #updateShortcuts(List)} to re-publish icons.
- *
- *  <li>Static shortcuts aren't backed up, but when an app is re-installed on a new
- *  device, they are re-published from the <code>AndroidManifest.xml</code> file.
- *
- *  <li>Dynamic shortcuts <b>aren't</b> backed up.
- * </ul>
- *
- * <p>Because dynamic shortcuts are not restored, it is recommended that apps check
- * currently-published dynamic shortcuts using {@link #getDynamicShortcuts()}
- * each time they are launched, and they should re-publish
- * dynamic shortcuts when necessary.
- *
- * <pre>
- *public class MainActivity extends Activity {
- *    public void onCreate(Bundle savedInstanceState) {
- *        super.onCreate(savedInstanceState);
- *        ShortcutManager shortcutManager =
- *                getSystemService(ShortcutManager.class);
- *
- *        if (shortcutManager.getDynamicShortcuts().size() == 0) {
- *            // Application restored. Need to re-publish dynamic shortcuts.
- *            if (shortcutManager.getPinnedShortcuts().size() > 0) {
- *                // Pinned shortcuts have been restored. Use
- *                // updateShortcuts() to make sure they contain
- *                // up-to-date information.
- *            }
- *        }
- *    }
- *    // ...
- *}
- * </pre>
- *
- *
- * <h4>Backup/restore and shortcut IDs</h4>
- * <p>
- * Because pinned shortcuts are backed up and restored on new devices, shortcut IDs
- * should contain either stable, constant strings or server-side identifiers,
- * rather than identifiers generated locally that might not make sense on other devices.
- *
- *
- * <h3>Report Shortcut Usage and Prediction</h3>
- * <p>
- * Launcher apps may be capable of predicting which shortcuts will most likely be
- * used at a given time by examining the shortcut usage history data.
- *
- * <p>In order to provide launchers with such data, publisher apps should
- * report the shortcuts that are used with {@link #reportShortcutUsed(String)}
- * when a shortcut is selected,
- * <b>or when an action equivalent to a shortcut is taken by the user even if it wasn't started
- * with the shortcut</b>.
- *
- * <p>For example, suppose a navigation app supports "navigate to work" as a shortcut.
- * It should then report when the user selects this shortcut <b>and</b> when the user chooses
- * to navigate to work within the app itself.
- * This helps the launcher app
- * learn that the user wants to navigate to work at a certain time every
- * weekday, and it can then show this shortcut in a suggestion list at the right time.
- *
- * <h3>Launcher API</h3>
- *
- * The {@link LauncherApps} class provides APIs for launcher apps to access shortcuts.
- *
- *
- * <h3>Direct Boot and Shortcuts</h3>
- *
- * All shortcut information is stored in credential encrypted storage, so no shortcuts can be
- * accessed when the user is locked.
  */
 @SystemService(Context.SHORTCUT_SERVICE)
 public class ShortcutManager {
diff --git a/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl b/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
index 3c3b84d..9490e27 100644
--- a/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
+++ b/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
@@ -25,4 +25,5 @@
  */
 oneway interface IRuntimePermissionPresenter {
     void getAppPermissions(String packageName, in RemoteCallback callback);
+    void revokeRuntimePermission(String packageName, String permissionName);
 }
diff --git a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
index 6d55d2f..02d0a6d 100644
--- a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
+++ b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.content.pm.ApplicationInfo;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -31,6 +30,7 @@
 import android.os.RemoteException;
 import android.permissionpresenterservice.RuntimePermissionPresenterService;
 import android.util.Log;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.SomeArgs;
 
@@ -118,6 +118,22 @@
         mRemoteService.processMessage(message);
     }
 
+    /**
+     * Revoke the permission {@code permissionName} for app {@code packageName}
+     *
+     * @param packageName The package for which to revoke
+     * @param permissionName The permission to revoke
+     */
+    public void revokeRuntimePermission(String packageName, String permissionName) {
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = packageName;
+        args.arg2 = permissionName;
+
+        Message message = mRemoteService.obtainMessage(
+                RemoteService.MSG_REVOKE_APP_PERMISSIONS, args);
+        mRemoteService.processMessage(message);
+    }
+
     private static final class RemoteService
             extends Handler implements ServiceConnection {
         private static final long UNBIND_TIMEOUT_MILLIS = 10000;
@@ -125,6 +141,7 @@
         public static final int MSG_GET_APP_PERMISSIONS = 1;
         public static final int MSG_GET_APPS_USING_PERMISSIONS = 2;
         public static final int MSG_UNBIND = 3;
+        public static final int MSG_REVOKE_APP_PERMISSIONS = 4;
 
         private final Object mLock = new Object();
 
@@ -231,6 +248,25 @@
                         mRemoteInstance = null;
                     }
                 } break;
+
+                case MSG_REVOKE_APP_PERMISSIONS: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    final String packageName = (String) args.arg1;
+                    final String permissionName = (String) args.arg2;
+                    args.recycle();
+                    final IRuntimePermissionPresenter remoteInstance;
+                    synchronized (mLock) {
+                        remoteInstance = mRemoteInstance;
+                    }
+                    if (remoteInstance == null) {
+                        return;
+                    }
+                    try {
+                        remoteInstance.revokeRuntimePermission(packageName, permissionName);
+                    } catch (RemoteException re) {
+                        Log.e(TAG, "Error getting app permissions", re);
+                    }
+                } break;
             }
 
             synchronized (mLock) {
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 88c1627..f7cccd5 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -16,35 +16,33 @@
 
 package android.content.res;
 
-import android.graphics.Point;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ActivityInfo.Config;
 import android.graphics.Rect;
-import android.util.DisplayMetrics;
-import android.view.Display;
+import android.os.Build;
+import android.os.LocaleList;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
 import android.view.DisplayInfo;
+import android.view.View;
+
 import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
 
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ActivityInfo.Config;
-import android.os.Build;
-import android.os.LocaleList;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.view.View;
-
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Locale;
 
+
 /**
  * This class describes all device configuration information that can
  * impact the resources the application retrieves.  This includes both
@@ -1277,7 +1275,7 @@
             changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
             setAppBounds(delta.appBounds);
         }
-        if (delta.assetsSeq != ASSETS_SEQ_UNDEFINED) {
+        if (delta.assetsSeq != ASSETS_SEQ_UNDEFINED && delta.assetsSeq != assetsSeq) {
             changed |= ActivityInfo.CONFIG_ASSETS_PATHS;
             assetsSeq = delta.assetsSeq;
         }
@@ -1320,7 +1318,19 @@
      * PackageManager.ActivityInfo.CONFIG_LAYOUT_DIRECTION}.
      */
     public int diff(Configuration delta) {
-        return diff(delta, false /* compareUndefined */);
+        return diff(delta, false /* compareUndefined */, false /* publicOnly */);
+    }
+
+    /**
+     * Returns the diff against the provided {@link Configuration} excluding values that would
+     * publicly be equivalent, such as appBounds.
+     * @param delta {@link Configuration} to compare to.
+     *
+     * TODO(b/36812336): Remove once appBounds has been moved out of Configuration.
+     * {@hide}
+     */
+    public int diffPublicOnly(Configuration delta) {
+        return diff(delta, false /* compareUndefined */, true /* publicOnly */);
     }
 
     /**
@@ -1328,7 +1338,7 @@
      *
      * @hide
      */
-    public int diff(Configuration delta, boolean compareUndefined) {
+    public int diff(Configuration delta, boolean compareUndefined, boolean publicOnly) {
         int changed = 0;
         if ((compareUndefined || delta.fontScale > 0) && fontScale != delta.fontScale) {
             changed |= ActivityInfo.CONFIG_FONT_SCALE;
@@ -1426,7 +1436,9 @@
         // Make sure that one of the values is not null and that they are not equal.
         if ((compareUndefined || delta.appBounds != null)
                 && appBounds != delta.appBounds
-                && (appBounds == null || !appBounds.equals(delta.appBounds))) {
+                && (appBounds == null || (!publicOnly && !appBounds.equals(delta.appBounds))
+                        || (publicOnly && (appBounds.width() != delta.appBounds.width()
+                                || appBounds.height() != delta.appBounds.height())))) {
             changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
         }
 
@@ -1650,7 +1662,24 @@
         n = this.densityDpi - that.densityDpi;
         if (n != 0) return n;
         n = this.assetsSeq - that.assetsSeq;
-        //if (n != 0) return n;
+        if (n != 0) return n;
+
+        if (this.appBounds == null && that.appBounds != null) {
+            return 1;
+        } else if (this.appBounds != null && that.appBounds == null) {
+            return -1;
+        } else if (this.appBounds != null && that.appBounds != null) {
+            n = this.appBounds.left - that.appBounds.left;
+            if (n != 0) return n;
+            n = this.appBounds.top - that.appBounds.top;
+            if (n != 0) return n;
+            n = this.appBounds.right - that.appBounds.right;
+            if (n != 0) return n;
+            n = this.appBounds.bottom - that.appBounds.bottom;
+            if (n != 0) return n;
+        }
+
+        // if (n != 0) return n;
         return n;
     }
 
@@ -1818,9 +1847,11 @@
     }
 
     /**
-     * Return whether the screen has a wide color gamut.
+     * Return whether the screen has a wide color gamut and wide color gamut rendering
+     * is supported by this device.
      *
-     * @return true if the screen has a wide color gamut, false otherwise
+     * @return true if the screen has a wide color gamut and wide color gamut rendering
+     * is supported, false otherwise
      */
     public boolean isScreenWideColorGamut() {
         return (colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK) == COLOR_MODE_WIDE_COLOR_GAMUT_YES;
@@ -2265,6 +2296,7 @@
     private static final String XML_ATTR_NAVIGATION = "nav";
     private static final String XML_ATTR_NAVIGATION_HIDDEN = "navHid";
     private static final String XML_ATTR_ORIENTATION = "ori";
+    private static final String XML_ATTR_ROTATION = "rot";
     private static final String XML_ATTR_SCREEN_LAYOUT = "scrLay";
     private static final String XML_ATTR_COLOR_MODE = "clrMod";
     private static final String XML_ATTR_UI_MODE = "ui";
diff --git a/core/java/android/hardware/LegacySensorManager.java b/core/java/android/hardware/LegacySensorManager.java
index f5cf3f7..098121d 100644
--- a/core/java/android/hardware/LegacySensorManager.java
+++ b/core/java/android/hardware/LegacySensorManager.java
@@ -204,7 +204,7 @@
     }
 
     private static final class LegacyListener implements SensorEventListener {
-        private float mValues[] = new float[6];
+        private float[] mValues = new float[6];
         private SensorListener mTarget;
         private int mSensors;
         private final LmsFilter mYawfilter = new LmsFilter();
@@ -256,7 +256,7 @@
         }
 
         public void onSensorChanged(SensorEvent event) {
-            final float v[] = mValues;
+            final float[] v = mValues;
             v[0] = event.values[0];
             v[1] = event.values[1];
             v[2] = event.values[2];
@@ -264,10 +264,10 @@
             int legacyType = getLegacySensorType(type);
             mapSensorDataToWindow(legacyType, v, LegacySensorManager.getRotation());
             if (type == Sensor.TYPE_ORIENTATION) {
-                if ((mSensors & SensorManager.SENSOR_ORIENTATION_RAW)!=0) {
+                if ((mSensors & SensorManager.SENSOR_ORIENTATION_RAW) != 0) {
                     mTarget.onSensorChanged(SensorManager.SENSOR_ORIENTATION_RAW, v);
                 }
-                if ((mSensors & SensorManager.SENSOR_ORIENTATION)!=0) {
+                if ((mSensors & SensorManager.SENSOR_ORIENTATION) != 0) {
                     v[0] = mYawfilter.filter(event.timestamp, v[0]);
                     mTarget.onSensorChanged(SensorManager.SENSOR_ORIENTATION, v);
                 }
@@ -317,7 +317,7 @@
                 switch (sensor) {
                     case SensorManager.SENSOR_ACCELEROMETER:
                     case SensorManager.SENSOR_MAGNETIC_FIELD:
-                        values[0] =-y;
+                        values[0] = -y;
                         values[1] = x;
                         values[2] = z;
                         break;
@@ -337,15 +337,15 @@
                 switch (sensor) {
                     case SensorManager.SENSOR_ACCELEROMETER:
                     case SensorManager.SENSOR_MAGNETIC_FIELD:
-                        values[0] =-x;
-                        values[1] =-y;
+                        values[0] = -x;
+                        values[1] = -y;
                         values[2] = z;
                         break;
                     case SensorManager.SENSOR_ORIENTATION:
                     case SensorManager.SENSOR_ORIENTATION_RAW:
                         values[0] = (x >= 180) ? (x - 180) : (x + 180);
-                        values[1] =-y;
-                        values[2] =-z;
+                        values[1] = -y;
+                        values[2] = -z;
                         break;
                 }
             }
@@ -369,10 +369,11 @@
     private static final class LmsFilter {
         private static final int SENSORS_RATE_MS = 20;
         private static final int COUNT = 12;
-        private static final float PREDICTION_RATIO = 1.0f/3.0f;
-        private static final float PREDICTION_TIME = (SENSORS_RATE_MS*COUNT/1000.0f)*PREDICTION_RATIO;
-        private float mV[] = new float[COUNT*2];
-        private long mT[] = new long[COUNT*2];
+        private static final float PREDICTION_RATIO = 1.0f / 3.0f;
+        private static final float PREDICTION_TIME =
+                (SENSORS_RATE_MS * COUNT / 1000.0f) * PREDICTION_RATIO;
+        private float[] mV = new float[COUNT * 2];
+        private long[] mT = new long[COUNT * 2];
         private int mIndex;
 
         public LmsFilter() {
@@ -383,9 +384,9 @@
             float v = in;
             final float ns = 1.0f / 1000000000.0f;
             float v1 = mV[mIndex];
-            if ((v-v1) > 180) {
+            if ((v - v1) > 180) {
                 v -= 360;
-            } else if ((v1-v) > 180) {
+            } else if ((v1 - v) > 180) {
                 v += 360;
             }
             /* Manage the circular buffer, we write the data twice spaced
@@ -393,40 +394,43 @@
              * when it's full
              */
             mIndex++;
-            if (mIndex >= COUNT*2)
+            if (mIndex >= COUNT * 2) {
                 mIndex = COUNT;
+            }
             mV[mIndex] = v;
             mT[mIndex] = time;
-            mV[mIndex-COUNT] = v;
-            mT[mIndex-COUNT] = time;
+            mV[mIndex - COUNT] = v;
+            mT[mIndex - COUNT] = time;
 
             float A, B, C, D, E;
             float a, b;
             int i;
 
             A = B = C = D = E = 0;
-            for (i=0 ; i<COUNT-1 ; i++) {
+            for (i = 0; i < COUNT - 1; i++) {
                 final int j = mIndex - 1 - i;
                 final float Z = mV[j];
-                final float T = (mT[j]/2 + mT[j+1]/2 - time)*ns;
-                float dT = (mT[j] - mT[j+1])*ns;
+                final float T = (mT[j] / 2 + mT[j + 1] / 2 - time) * ns;
+                float dT = (mT[j] - mT[j + 1]) * ns;
                 dT *= dT;
-                A += Z*dT;
-                B += T*(T*dT);
-                C +=   (T*dT);
-                D += Z*(T*dT);
+                A += Z * dT;
+                B += T * (T * dT);
+                C += (T * dT);
+                D += Z * (T * dT);
                 E += dT;
             }
-            b = (A*B + C*D) / (E*B + C*C);
-            a = (E*b - A) / C;
-            float f = b + PREDICTION_TIME*a;
+            b = (A * B + C * D) / (E * B + C * C);
+            a = (E * b - A) / C;
+            float f = b + PREDICTION_TIME * a;
 
             // Normalize
             f *= (1.0f / 360.0f);
-            if (((f>=0)?f:-f) >= 0.5f)
-                f = f - (float)Math.ceil(f + 0.5f) + 1.0f;
-            if (f < 0)
+            if (((f >= 0) ? f : -f) >= 0.5f) {
+                f = f - (float) Math.ceil(f + 0.5f) + 1.0f;
+            }
+            if (f < 0) {
                 f += 1.0f;
+            }
             f *= 360.0f;
             return f;
         }
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index f02e484..7fb0c89 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -794,12 +794,12 @@
             1, // SENSOR_TYPE_PICK_UP_GESTURE
             1, // SENSOR_TYPE_WRIST_TILT_GESTURE
             1, // SENSOR_TYPE_DEVICE_ORIENTATION
-            16,// SENSOR_TYPE_POSE_6DOF
+            16, // SENSOR_TYPE_POSE_6DOF
             1, // SENSOR_TYPE_STATIONARY_DETECT
             1, // SENSOR_TYPE_MOTION_DETECT
             1, // SENSOR_TYPE_HEART_BEAT
             2, // SENSOR_TYPE_DYNAMIC_SENSOR_META
-            16,// skip over additional sensor info type
+            16, // skip over additional sensor info type
             1, // SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT
             6, // SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED
     };
@@ -857,8 +857,8 @@
     static int getMaxLengthValuesArray(Sensor sensor, int sdkLevel) {
         // RotationVector length has changed to 3 to 5 for API level 18
         // Set it to 3 for backward compatibility.
-        if (sensor.mType == Sensor.TYPE_ROTATION_VECTOR &&
-                sdkLevel <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+        if (sensor.mType == Sensor.TYPE_ROTATION_VECTOR
+                && sdkLevel <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
             return 3;
         }
         int offset = sensor.mType;
@@ -1033,9 +1033,9 @@
      * Returns true if the sensor is a wake-up sensor.
      * <p>
      * <b>Application Processor Power modes</b> <p>
-     * Application Processor(AP), is the processor on which applications run.  When no wake lock is held
-     * and the user is not interacting with the device, this processor can enter a “Suspend” mode,
-     * reducing the power consumption by 10 times or more.
+     * Application Processor(AP), is the processor on which applications run.  When no wake lock is
+     * held and the user is not interacting with the device, this processor can enter a “Suspend”
+     * mode, reducing the power consumption by 10 times or more.
      * </p>
      * <p>
      * <b>Non-wake-up sensors</b> <p>
@@ -1232,6 +1232,6 @@
      */
     private void setUuid(long msb, long lsb) {
         // TODO(b/29547335): Rename this method to setId.
-        mId = (int)msb;
+        mId = (int) msb;
     }
 }
diff --git a/core/java/android/hardware/SensorAdditionalInfo.java b/core/java/android/hardware/SensorAdditionalInfo.java
index ea1d01b..7c876cf 100644
--- a/core/java/android/hardware/SensorAdditionalInfo.java
+++ b/core/java/android/hardware/SensorAdditionalInfo.java
@@ -189,8 +189,18 @@
      */
     public static final int TYPE_MAGNETIC_FIELD_CALIBRATION = 0x30004;
 
+    /**
+     * Custom sensor info: array of float values interpreted by sensor based on the type
+     * Any type between TYPE_CUSTOM_INFO <= info_type < TYPE_DEBUG_INFO may be
+     * used to send custom sensor info.
+     * @hide
+     */
+    public static final int TYPE_CUSTOM_INFO = 0x10000000;
+    /** @hide */
+    public static final int TYPE_DEBUG_INFO  = 0x40000000;
+
     SensorAdditionalInfo(
-            Sensor aSensor, int aType, int aSerial, int [] aIntValues, float [] aFloatValues) {
+            Sensor aSensor, int aType, int aSerial, int[] aIntValues, float[] aFloatValues) {
         sensor = aSensor;
         type = aType;
         serial = aSerial;
@@ -211,4 +221,13 @@
                 null, TYPE_LOCAL_GEOMAGNETIC_FIELD, 0,
                 null, new float[] { strength, declination, inclination});
     }
+    /** @hide */
+    public static SensorAdditionalInfo createCustomInfo(Sensor aSensor, int type, float[] data) {
+        if (type < TYPE_CUSTOM_INFO || type >= TYPE_DEBUG_INFO || aSensor == null) {
+            throw new IllegalArgumentException(
+                    "invalid parameter(s): type: " + type + "; sensor: " + aSensor);
+        }
+
+        return new SensorAdditionalInfo(aSensor, type, 0, null, data);
+    }
 }
diff --git a/core/java/android/hardware/SensorDirectChannel.java b/core/java/android/hardware/SensorDirectChannel.java
index bd7f9cf..36607c9 100644
--- a/core/java/android/hardware/SensorDirectChannel.java
+++ b/core/java/android/hardware/SensorDirectChannel.java
@@ -212,7 +212,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index c0bca97e..bbd04a3 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -207,8 +207,8 @@
      *          timestamp = event.timestamp;
      *          float[] deltaRotationMatrix = new float[9];
      *          SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
-     *          // User code should concatenate the delta rotation we computed with the current rotation
-     *          // in order to get the updated rotation.
+     *          // User code should concatenate the delta rotation we computed with the current
+     *          // rotation in order to get the updated rotation.
      *          // rotationCurrent = rotationCurrent * deltaRotationMatrix;
      *     }
      * </pre>
@@ -244,21 +244,22 @@
      *  <h4>{@link android.hardware.Sensor#TYPE_GRAVITY Sensor.TYPE_GRAVITY}:</h4>
      *  <p>A three dimensional vector indicating the direction and magnitude of gravity.  Units
      *  are m/s^2. The coordinate system is the same as is used by the acceleration sensor.</p>
-     *  <p><b>Note:</b> When the device is at rest, the output of the gravity sensor should be identical
-     *  to that of the accelerometer.</p>
+     *  <p><b>Note:</b> When the device is at rest, the output of the gravity sensor should be
+     *  identical to that of the accelerometer.</p>
      *
-     *  <h4>{@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION Sensor.TYPE_LINEAR_ACCELERATION}:</h4>
-     *  A three dimensional vector indicating acceleration along each device axis, not including
-     *  gravity.  All values have units of m/s^2.  The coordinate system is the same as is used by the
-     *  acceleration sensor.
+     *  <h4>
+     *  {@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION Sensor.TYPE_LINEAR_ACCELERATION}:
+     *  </h4> A three dimensional vector indicating acceleration along each device axis, not
+     *  including gravity. All values have units of m/s^2.  The coordinate system is the same as is
+     *  used by the acceleration sensor.
      *  <p>The output of the accelerometer, gravity and  linear-acceleration sensors must obey the
      *  following relation:</p>
-     *   <p><ul>acceleration = gravity + linear-acceleration</ul></p>
+     *  <p><ul>acceleration = gravity + linear-acceleration</ul></p>
      *
      *  <h4>{@link android.hardware.Sensor#TYPE_ROTATION_VECTOR Sensor.TYPE_ROTATION_VECTOR}:</h4>
-     *  <p>The rotation vector represents the orientation of the device as a combination of an <i>angle</i>
-     *  and an <i>axis</i>, in which the device has rotated through an angle &#952 around an axis
-     *  &lt;x, y, z>.</p>
+     *  <p>The rotation vector represents the orientation of the device as a combination of an
+     *  <i>angle</i> and an <i>axis</i>, in which the device has rotated through an angle &#952
+     *  around an axis &lt;x, y, z>.</p>
      *  <p>The three elements of the rotation vector are
      *  &lt;x*sin(&#952/2), y*sin(&#952/2), z*sin(&#952/2)>, such that the magnitude of the rotation
      *  vector is equal to sin(&#952/2), and the direction of the rotation vector is equal to the
diff --git a/core/java/android/hardware/SensorListener.java b/core/java/android/hardware/SensorListener.java
index c71e968..e2033b6 100644
--- a/core/java/android/hardware/SensorListener.java
+++ b/core/java/android/hardware/SensorListener.java
@@ -19,8 +19,8 @@
 /**
  * Used for receiving notifications from the SensorManager when
  * sensor values have changed.
- * 
- * @deprecated Use 
+ *
+ * @deprecated Use
  * {@link android.hardware.SensorEventListener SensorEventListener} instead.
  */
 @Deprecated
@@ -36,7 +36,7 @@
      * <p><u>Definition of the coordinate system used below.</u><p>
      * <p>The X axis refers to the screen's horizontal axis
      * (the small edge in portrait mode, the long edge in landscape mode) and
-     * points to the right. 
+     * points to the right.
      * <p>The Y axis refers to the screen's vertical axis and points towards
      * the top of the screen (the origin is in the lower-left corner).
      * <p>The Z axis points toward the sky when the device is lying on its back
@@ -44,18 +44,18 @@
      * <p> <b>IMPORTANT NOTE:</b> The axis <b><u>are swapped</u></b> when the
      * device's screen orientation changes. To access the unswapped values,
      * use indices 3, 4 and 5 in values[].
-     * 
+     *
      * <p>{@link android.hardware.SensorManager#SENSOR_ORIENTATION SENSOR_ORIENTATION},
      * {@link android.hardware.SensorManager#SENSOR_ORIENTATION_RAW SENSOR_ORIENTATION_RAW}:<p>
      *  All values are angles in degrees.
-     * 
+     *
      * <p>values[0]: Azimuth, rotation around the Z axis (0<=azimuth<360).
      * 0 = North, 90 = East, 180 = South, 270 = West
-     * 
+     *
      * <p>values[1]: Pitch, rotation around X axis (-180<=pitch<=180), with positive
      * values when the z-axis moves toward the y-axis.
      *
-     * <p>values[2]: Roll, rotation around Y axis (-90<=roll<=90), with positive values 
+     * <p>values[2]: Roll, rotation around Y axis (-90<=roll<=90), with positive values
      * when the z-axis moves toward the x-axis.
      *
      * <p>Note that this definition of yaw, pitch and roll is different from the
@@ -64,17 +64,17 @@
      *
      * <p>{@link android.hardware.SensorManager#SENSOR_ACCELEROMETER SENSOR_ACCELEROMETER}:<p>
      *  All values are in SI units (m/s^2) and measure contact forces.
-     *  
-     *  <p>values[0]: force applied by the device on the x-axis 
-     *  <p>values[1]: force applied by the device on the y-axis 
+     *
+     *  <p>values[0]: force applied by the device on the x-axis
+     *  <p>values[1]: force applied by the device on the y-axis
      *  <p>values[2]: force applied by the device on the z-axis
-     *  
+     *
      *  <p><u>Examples</u>:
      *    <li>When the device is pushed on its left side toward the right, the
      *    x acceleration value is negative (the device applies a reaction force
      *    to the push toward the left)</li>
-     *    
-     *    <li>When the device lies flat on a table, the acceleration value is 
+     *
+     *    <li>When the device lies flat on a table, the acceleration value is
      *    {@link android.hardware.SensorManager#STANDARD_GRAVITY -STANDARD_GRAVITY},
      *    which correspond to the force the device applies on the table in reaction
      *    to gravity.</li>
@@ -83,7 +83,7 @@
      *  All values are in micro-Tesla (uT) and measure the ambient magnetic
      *  field in the X, Y and -Z axis.
      *  <p><b><u>Note:</u></b> the magnetic field's Z axis is inverted.
-     *  
+     *
      * @param sensor The ID of the sensor being monitored
      * @param values The new values for the sensor.
      */
@@ -97,5 +97,5 @@
      * @param sensor The ID of the sensor being monitored
      * @param accuracy The new accuracy of this sensor.
      */
-    public void onAccuracyChanged(int sensor, int accuracy);    
+    public void onAccuracyChanged(int sensor, int accuracy);
 }
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 4bc62b1..35aaf78 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -83,7 +83,7 @@
     /** @hide */
     protected static final String TAG = "SensorManager";
 
-    private static final float[] mTempMatrix = new float[16];
+    private static final float[] sTempMatrix = new float[16];
 
     // Cached lists of sensors by type.  Guarded by mSensorListByType.
     private final SparseArray<List<Sensor>> mSensorListByType =
@@ -188,7 +188,7 @@
      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
      */
     @Deprecated
-    public static final int SENSOR_MAX = ((SENSOR_ALL + 1)>>1);
+    public static final int SENSOR_MAX = ((SENSOR_ALL + 1) >> 1);
 
 
     /**
@@ -425,8 +425,9 @@
                 } else {
                     list = new ArrayList<Sensor>();
                     for (Sensor i : fullList) {
-                        if (i.getType() == type)
+                        if (i.getType() == type) {
                             list.add(i);
+                        }
                     }
                 }
                 list = Collections.unmodifiableList(list);
@@ -461,8 +462,9 @@
         } else {
             List<Sensor> list = new ArrayList();
             for (Sensor i : fullList) {
-                if (i.getType() == type)
+                if (i.getType() == type) {
                     list.add(i);
+                }
             }
             return Collections.unmodifiableList(list);
         }
@@ -490,10 +492,11 @@
         // For the following sensor types, return a wake-up sensor. These types are by default
         // defined as wake-up sensors. For the rest of the SDK defined sensor types return a
         // non_wake-up version.
-        if (type == Sensor.TYPE_PROXIMITY || type == Sensor.TYPE_SIGNIFICANT_MOTION ||
-                type == Sensor.TYPE_TILT_DETECTOR || type == Sensor.TYPE_WAKE_GESTURE ||
-                type == Sensor.TYPE_GLANCE_GESTURE || type == Sensor.TYPE_PICK_UP_GESTURE ||
-                type == Sensor.TYPE_WRIST_TILT_GESTURE || type == Sensor.TYPE_DYNAMIC_SENSOR_META) {
+        if (type == Sensor.TYPE_PROXIMITY || type == Sensor.TYPE_SIGNIFICANT_MOTION
+                || type == Sensor.TYPE_TILT_DETECTOR || type == Sensor.TYPE_WAKE_GESTURE
+                || type == Sensor.TYPE_GLANCE_GESTURE || type == Sensor.TYPE_PICK_UP_GESTURE
+                || type == Sensor.TYPE_WRIST_TILT_GESTURE
+                || type == Sensor.TYPE_DYNAMIC_SENSOR_META) {
             wakeUpSensor = true;
         }
 
@@ -509,12 +512,12 @@
      * <p>
      * For example,
      * <ul>
-     *     <li>getDefaultSensor({@link Sensor#TYPE_ACCELEROMETER}, true) returns a wake-up accelerometer
-     *     sensor if it exists. </li>
-     *     <li>getDefaultSensor({@link Sensor#TYPE_PROXIMITY}, false) returns a non wake-up proximity
-     *     sensor if it exists. </li>
-     *     <li>getDefaultSensor({@link Sensor#TYPE_PROXIMITY}, true) returns a wake-up proximity sensor
-     *     which is the same as the Sensor returned by {@link #getDefaultSensor(int)}. </li>
+     *     <li>getDefaultSensor({@link Sensor#TYPE_ACCELEROMETER}, true) returns a wake-up
+     *     accelerometer sensor if it exists. </li>
+     *     <li>getDefaultSensor({@link Sensor#TYPE_PROXIMITY}, false) returns a non wake-up
+     *     proximity sensor if it exists. </li>
+     *     <li>getDefaultSensor({@link Sensor#TYPE_PROXIMITY}, true) returns a wake-up proximity
+     *     sensor which is the same as the Sensor returned by {@link #getDefaultSensor(int)}. </li>
      * </ul>
      * </p>
      * <p class="note">
@@ -532,8 +535,9 @@
     public Sensor getDefaultSensor(int type, boolean wakeUp) {
         List<Sensor> l = getSensorList(type);
         for (Sensor sensor : l) {
-            if (sensor.isWakeUpSensor() == wakeUp)
+            if (sensor.isWakeUpSensor() == wakeUp) {
                 return sensor;
+            }
         }
         return null;
     }
@@ -842,8 +846,8 @@
      * @return <code>true</code> if the sensor is supported and successfully enabled.
      * @see #registerListener(SensorEventListener, Sensor, int, int)
      */
-    public boolean registerListener(SensorEventListener listener, Sensor sensor, int samplingPeriodUs,
-            int maxReportLatencyUs, Handler handler) {
+    public boolean registerListener(SensorEventListener listener, Sensor sensor,
+            int samplingPeriodUs, int maxReportLatencyUs, Handler handler) {
         int delayUs = getDelay(samplingPeriodUs);
         return registerListenerImpl(listener, sensor, delayUs, handler, maxReportLatencyUs, 0);
     }
@@ -894,8 +898,9 @@
      * to free up resource in sensor system associated with the direct channel.
      *
      * @param mem A {@link android.os.MemoryFile} shared memory object.
-     * @return A {@link android.hardware.SensorDirectChannel} object if successful, null otherwise.
+     * @return A {@link android.hardware.SensorDirectChannel} object.
      * @throws NullPointerException when mem is null.
+     * @throws UncheckedIOException if not able to create channel.
      * @see SensorDirectChannel#close()
      * @see #configureDirectChannel(SensorDirectChannel, Sensor, int)
      */
@@ -916,9 +921,9 @@
      * to free up resource in sensor system associated with the direct channel.
      *
      * @param mem A {@link android.hardware.HardwareBuffer} shared memory object.
-     * @return A {@link android.hardware.SensorDirectChannel} object if successful,
-     *         null otherwise.
+     * @return A {@link android.hardware.SensorDirectChannel} object.
      * @throws NullPointerException when mem is null.
+     * @throws UncheckedIOException if not able to create channel.
      * @see SensorDirectChannel#close()
      * @see #configureDirectChannel(SensorDirectChannel, Sensor, int)
      */
@@ -952,7 +957,7 @@
      * Used for receiving notifications from the SensorManager when dynamic sensors are connected or
      * disconnected.
      */
-    public static abstract class DynamicSensorCallback {
+    public abstract static class DynamicSensorCallback {
         /**
          * Called when there is a dynamic sensor being connected to the system.
          *
@@ -1179,7 +1184,7 @@
         float Ay = gravity[1];
         float Az = gravity[2];
 
-        final float normsqA = (Ax*Ax + Ay*Ay + Az*Az);
+        final float normsqA = (Ax * Ax + Ay * Ay + Az * Az);
         final float g = 9.81f;
         final float freeFallGravitySquared = 0.01f * g * g;
         if (normsqA < freeFallGravitySquared) {
@@ -1190,10 +1195,10 @@
         final float Ex = geomagnetic[0];
         final float Ey = geomagnetic[1];
         final float Ez = geomagnetic[2];
-        float Hx = Ey*Az - Ez*Ay;
-        float Hy = Ez*Ax - Ex*Az;
-        float Hz = Ex*Ay - Ey*Ax;
-        final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz);
+        float Hx = Ey * Az - Ez * Ay;
+        float Hy = Ez * Ax - Ex * Az;
+        float Hz = Ex * Ay - Ey * Ax;
+        final float normH = (float) Math.sqrt(Hx * Hx + Hy * Hy + Hz * Hz);
 
         if (normH < 0.1f) {
             // device is close to free fall (or in space?), or close to
@@ -1204,13 +1209,13 @@
         Hx *= invH;
         Hy *= invH;
         Hz *= invH;
-        final float invA = 1.0f / (float)Math.sqrt(Ax*Ax + Ay*Ay + Az*Az);
+        final float invA = 1.0f / (float) Math.sqrt(Ax * Ax + Ay * Ay + Az * Az);
         Ax *= invA;
         Ay *= invA;
         Az *= invA;
-        final float Mx = Ay*Hz - Az*Hy;
-        final float My = Az*Hx - Ax*Hz;
-        final float Mz = Ax*Hy - Ay*Hx;
+        final float Mx = Ay * Hz - Az * Hy;
+        final float My = Az * Hx - Ax * Hz;
+        final float Mz = Ax * Hy - Ay * Hx;
         if (R != null) {
             if (R.length == 9) {
                 R[0] = Hx;     R[1] = Hy;     R[2] = Hz;
@@ -1227,17 +1232,17 @@
             // compute the inclination matrix by projecting the geomagnetic
             // vector onto the Z (gravity) and X (horizontal component
             // of geomagnetic vector) axes.
-            final float invE = 1.0f / (float)Math.sqrt(Ex*Ex + Ey*Ey + Ez*Ez);
-            final float c = (Ex*Mx + Ey*My + Ez*Mz) * invE;
-            final float s = (Ex*Ax + Ey*Ay + Ez*Az) * invE;
+            final float invE = 1.0f / (float) Math.sqrt(Ex * Ex + Ey * Ey + Ez * Ez);
+            final float c = (Ex * Mx + Ey * My + Ez * Mz) * invE;
+            final float s = (Ex * Ax + Ey * Ay + Ez * Az) * invE;
             if (I.length == 9) {
                 I[0] = 1;     I[1] = 0;     I[2] = 0;
                 I[3] = 0;     I[4] = c;     I[5] = s;
-                I[6] = 0;     I[7] =-s;     I[8] = c;
+                I[6] = 0;     I[7] = -s;     I[8] = c;
             } else if (I.length == 16) {
                 I[0] = 1;     I[1] = 0;     I[2] = 0;
                 I[4] = 0;     I[5] = c;     I[6] = s;
-                I[8] = 0;     I[9] =-s;     I[10]= c;
+                I[8] = 0;     I[9] = -s;     I[10] = c;
                 I[3] = I[7] = I[11] = I[12] = I[13] = I[14] = 0;
                 I[15] = 1;
             }
@@ -1261,9 +1266,9 @@
      */
     public static float getInclination(float[] I) {
         if (I.length == 9) {
-            return (float)Math.atan2(I[5], I[4]);
+            return (float) Math.atan2(I[5], I[4]);
         } else {
-            return (float)Math.atan2(I[6], I[5]);
+            return (float) Math.atan2(I[6], I[5]);
         }
     }
 
@@ -1342,17 +1347,16 @@
      * @see #getRotationMatrix(float[], float[], float[], float[])
      */
 
-    public static boolean remapCoordinateSystem(float[] inR, int X, int Y,
-            float[] outR)
-    {
+    public static boolean remapCoordinateSystem(float[] inR, int X, int Y, float[] outR) {
         if (inR == outR) {
-            final float[] temp = mTempMatrix;
-            synchronized(temp) {
+            final float[] temp = sTempMatrix;
+            synchronized (temp) {
                 // we don't expect to have a lot of contention
                 if (remapCoordinateSystemImpl(inR, X, Y, temp)) {
                     final int size = outR.length;
-                    for (int i=0 ; i<size ; i++)
+                    for (int i = 0; i < size; i++) {
                         outR[i] = temp[i];
+                    }
                     return true;
                 }
             }
@@ -1360,9 +1364,7 @@
         return remapCoordinateSystemImpl(inR, X, Y, outR);
     }
 
-    private static boolean remapCoordinateSystemImpl(float[] inR, int X, int Y,
-            float[] outR)
-    {
+    private static boolean remapCoordinateSystemImpl(float[] inR, int X, int Y, float[] outR) {
         /*
          * X and Y define a rotation matrix 'r':
          *
@@ -1375,14 +1377,18 @@
          */
 
         final int length = outR.length;
-        if (inR.length != length)
+        if (inR.length != length) {
             return false;   // invalid parameter
-        if ((X & 0x7C)!=0 || (Y & 0x7C)!=0)
+        }
+        if ((X & 0x7C) != 0 || (Y & 0x7C) != 0) {
             return false;   // invalid parameter
-        if (((X & 0x3)==0) || ((Y & 0x3)==0))
+        }
+        if (((X & 0x3) == 0) || ((Y & 0x3) == 0)) {
             return false;   // no axis specified
-        if ((X & 0x3) == (Y & 0x3))
+        }
+        if ((X & 0x3) == (Y & 0x3)) {
             return false;   // same axis specified
+        }
 
         // Z is "the other" axis, its sign is either +/- sign(X)*sign(Y)
         // this can be calculated by exclusive-or'ing X and Y; except for
@@ -1390,28 +1396,29 @@
         int Z = X ^ Y;
 
         // extract the axis (remove the sign), offset in the range 0 to 2.
-        final int x = (X & 0x3)-1;
-        final int y = (Y & 0x3)-1;
-        final int z = (Z & 0x3)-1;
+        final int x = (X & 0x3) - 1;
+        final int y = (Y & 0x3) - 1;
+        final int z = (Z & 0x3) - 1;
 
         // compute the sign of Z (whether it needs to be inverted)
-        final int axis_y = (z+1)%3;
-        final int axis_z = (z+2)%3;
-        if (((x^axis_y)|(y^axis_z)) != 0)
+        final int axis_y = (z + 1) % 3;
+        final int axis_z = (z + 2) % 3;
+        if (((x ^ axis_y) | (y ^ axis_z)) != 0) {
             Z ^= 0x80;
+        }
 
-        final boolean sx = (X>=0x80);
-        final boolean sy = (Y>=0x80);
-        final boolean sz = (Z>=0x80);
+        final boolean sx = (X >= 0x80);
+        final boolean sy = (Y >= 0x80);
+        final boolean sz = (Z >= 0x80);
 
         // Perform R * r, in avoiding actual muls and adds.
-        final int rowLength = ((length==16)?4:3);
-        for (int j=0 ; j<3 ; j++) {
-            final int offset = j*rowLength;
-            for (int i=0 ; i<3 ; i++) {
-                if (x==i)   outR[offset+i] = sx ? -inR[offset+0] : inR[offset+0];
-                if (y==i)   outR[offset+i] = sy ? -inR[offset+1] : inR[offset+1];
-                if (z==i)   outR[offset+i] = sz ? -inR[offset+2] : inR[offset+2];
+        final int rowLength = ((length == 16) ? 4 : 3);
+        for (int j = 0; j < 3; j++) {
+            final int offset = j * rowLength;
+            for (int i = 0; i < 3; i++) {
+                if (x == i)   outR[offset + i] = sx ? -inR[offset + 0] : inR[offset + 0];
+                if (y == i)   outR[offset + i] = sy ? -inR[offset + 1] : inR[offset + 1];
+                if (z == i)   outR[offset + i] = sz ? -inR[offset + 2] : inR[offset + 2];
             }
         }
         if (length == 16) {
@@ -1465,7 +1472,7 @@
      * @see #getRotationMatrix(float[], float[], float[], float[])
      * @see GeomagneticField
      */
-    public static float[] getOrientation(float[] R, float values[]) {
+    public static float[] getOrientation(float[] R, float[] values) {
         /*
          * 4x4 (length=16) case:
          *   /  R[ 0]   R[ 1]   R[ 2]   0  \
@@ -1480,13 +1487,13 @@
          *
          */
         if (R.length == 9) {
-            values[0] = (float)Math.atan2(R[1], R[4]);
-            values[1] = (float)Math.asin(-R[7]);
-            values[2] = (float)Math.atan2(-R[6], R[8]);
+            values[0] = (float) Math.atan2(R[1], R[4]);
+            values[1] = (float) Math.asin(-R[7]);
+            values[2] = (float) Math.atan2(-R[6], R[8]);
         } else {
-            values[0] = (float)Math.atan2(R[1], R[5]);
-            values[1] = (float)Math.asin(-R[9]);
-            values[2] = (float)Math.atan2(-R[8], R[10]);
+            values[0] = (float) Math.atan2(R[1], R[5]);
+            values[1] = (float) Math.asin(-R[9]);
+            values[2] = (float) Math.atan2(-R[8], R[10]);
         }
 
         return values;
@@ -1523,7 +1530,7 @@
      */
     public static float getAltitude(float p0, float p) {
         final float coef = 1.0f / 5.255f;
-        return 44330.0f * (1.0f - (float)Math.pow(p/p0, coef));
+        return 44330.0f * (1.0f - (float) Math.pow(p / p0, coef));
     }
 
     /** Helper function to compute the angle change between two rotation matrices.
@@ -1556,12 +1563,13 @@
      *        (in radians) is stored
      */
 
-    public static void getAngleChange( float[] angleChange, float[] R, float[] prevR) {
-        float rd1=0,rd4=0, rd6=0,rd7=0, rd8=0;
-        float ri0=0,ri1=0,ri2=0,ri3=0,ri4=0,ri5=0,ri6=0,ri7=0,ri8=0;
-        float pri0=0, pri1=0, pri2=0, pri3=0, pri4=0, pri5=0, pri6=0, pri7=0, pri8=0;
+    public static void getAngleChange(float[] angleChange, float[] R, float[] prevR) {
+        float rd1 = 0, rd4 = 0, rd6 = 0, rd7 = 0, rd8 = 0;
+        float ri0 = 0, ri1 = 0, ri2 = 0, ri3 = 0, ri4 = 0, ri5 = 0, ri6 = 0, ri7 = 0, ri8 = 0;
+        float pri0 = 0, pri1 = 0, pri2 = 0, pri3 = 0, pri4 = 0;
+        float pri5 = 0, pri6 = 0, pri7 = 0, pri8 = 0;
 
-        if(R.length == 9) {
+        if (R.length == 9) {
             ri0 = R[0];
             ri1 = R[1];
             ri2 = R[2];
@@ -1571,7 +1579,7 @@
             ri6 = R[6];
             ri7 = R[7];
             ri8 = R[8];
-        } else if(R.length == 16) {
+        } else if (R.length == 16) {
             ri0 = R[0];
             ri1 = R[1];
             ri2 = R[2];
@@ -1583,7 +1591,7 @@
             ri8 = R[10];
         }
 
-        if(prevR.length == 9) {
+        if (prevR.length == 9) {
             pri0 = prevR[0];
             pri1 = prevR[1];
             pri2 = prevR[2];
@@ -1593,7 +1601,7 @@
             pri6 = prevR[6];
             pri7 = prevR[7];
             pri8 = prevR[8];
-        } else if(prevR.length == 16) {
+        } else if (prevR.length == 16) {
             pri0 = prevR[0];
             pri1 = prevR[1];
             pri2 = prevR[2];
@@ -1614,9 +1622,9 @@
         rd7 = pri2 * ri1 + pri5 * ri4 + pri8 * ri7; //rd[2][1]
         rd8 = pri2 * ri2 + pri5 * ri5 + pri8 * ri8; //rd[2][2]
 
-        angleChange[0] = (float)Math.atan2(rd1, rd4);
-        angleChange[1] = (float)Math.asin(-rd7);
-        angleChange[2] = (float)Math.atan2(-rd6, rd8);
+        angleChange[0] = (float) Math.atan2(rd1, rd4);
+        angleChange[1] = (float) Math.asin(-rd7);
+        angleChange[2] = (float) Math.atan2(-rd6, rd8);
 
     }
 
@@ -1649,8 +1657,8 @@
         if (rotationVector.length >= 4) {
             q0 = rotationVector[3];
         } else {
-            q0 = 1 - q1*q1 - q2*q2 - q3*q3;
-            q0 = (q0 > 0) ? (float)Math.sqrt(q0) : 0;
+            q0 = 1 - q1 * q1 - q2 * q2 - q3 * q3;
+            q0 = (q0 > 0) ? (float) Math.sqrt(q0) : 0;
         }
 
         float sq_q1 = 2 * q1 * q1;
@@ -1663,7 +1671,7 @@
         float q2_q3 = 2 * q2 * q3;
         float q1_q0 = 2 * q1 * q0;
 
-        if(R.length == 9) {
+        if (R.length == 9) {
             R[0] = 1 - sq_q2 - sq_q3;
             R[1] = q1_q2 - q3_q0;
             R[2] = q1_q3 + q2_q0;
@@ -1706,8 +1714,8 @@
         if (rv.length >= 4) {
             Q[0] = rv[3];
         } else {
-            Q[0] = 1 - rv[0]*rv[0] - rv[1]*rv[1] - rv[2]*rv[2];
-            Q[0] = (Q[0] > 0) ? (float)Math.sqrt(Q[0]) : 0;
+            Q[0] = 1 - rv[0] * rv[0] - rv[1] * rv[1] - rv[2] * rv[2];
+            Q[0] = (Q[0] > 0) ? (float) Math.sqrt(Q[0]) : 0;
         }
         Q[1] = rv[0];
         Q[2] = rv[1];
@@ -1799,7 +1807,7 @@
      */
     @SystemApi
     public boolean initDataInjection(boolean enable) {
-          return initDataInjectionImpl(enable);
+        return initDataInjectionImpl(enable);
     }
 
     /**
@@ -1845,9 +1853,9 @@
         }
         int expectedNumValues = Sensor.getMaxLengthValuesArray(sensor, Build.VERSION_CODES.M);
         if (values.length != expectedNumValues) {
-            throw new  IllegalArgumentException ("Wrong number of values for sensor " +
-                    sensor.getName() + " actual=" + values.length + " expected=" +
-                                                  expectedNumValues);
+            throw new  IllegalArgumentException("Wrong number of values for sensor "
+                    + sensor.getName() + " actual=" + values.length + " expected="
+                    + expectedNumValues);
         }
         if (accuracy < SENSOR_STATUS_NO_CONTACT || accuracy > SENSOR_STATUS_ACCURACY_HIGH) {
             throw new IllegalArgumentException("Invalid sensor accuracy");
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 0dab5d7..1174cb6 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -28,10 +28,11 @@
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
-import dalvik.system.CloseGuard;
 
 import com.android.internal.annotations.GuardedBy;
 
+import dalvik.system.CloseGuard;
+
 import java.io.IOException;
 import java.io.UncheckedIOException;
 import java.lang.ref.WeakReference;
@@ -40,7 +41,6 @@
 import java.util.List;
 import java.util.Map;
 
-
 /**
  * Sensor manager implementation that communicates with the built-in
  * system sensors.
@@ -68,7 +68,7 @@
             long nativeInstance, int channelHandle, int sensorHandle, int rate);
 
     private static native int nativeSetOperationParameter(
-            long nativeInstance, int type, float[] floatValues, int[] intValues);
+            long nativeInstance, int handle, int type, float[] floatValues, int[] intValues);
 
     private static final Object sLock = new Object();
     @GuardedBy("sLock")
@@ -101,7 +101,7 @@
 
     /** {@hide} */
     public SystemSensorManager(Context context, Looper mainLooper) {
-        synchronized(sLock) {
+        synchronized (sLock) {
             if (!sNativeClassInited) {
                 sNativeClassInited = true;
                 nativeClassInit();
@@ -114,7 +114,7 @@
         mNativeInstance = nativeCreate(context.getOpPackageName());
 
         // initialize the sensor list
-        for (int index = 0;;++index) {
+        for (int index = 0;; ++index) {
             Sensor sensor = new Sensor();
             if (!nativeGetSensorAtIndex(mNativeInstance, sensor, index)) break;
             mFullSensorsList.add(sensor);
@@ -157,9 +157,9 @@
             return false;
         }
         if (mSensorListeners.size() >= MAX_LISTENER_COUNT) {
-            throw new IllegalStateException("register failed, " +
-                "the sensor listeners size has exceeded the maximum limit " +
-                MAX_LISTENER_COUNT);
+            throw new IllegalStateException("register failed, "
+                + "the sensor listeners size has exceeded the maximum limit "
+                + MAX_LISTENER_COUNT);
         }
 
         // Invariants to preserve:
@@ -170,9 +170,10 @@
             SensorEventQueue queue = mSensorListeners.get(listener);
             if (queue == null) {
                 Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
-                final String fullClassName = listener.getClass().getEnclosingClass() != null ?
-                    listener.getClass().getEnclosingClass().getName() :
-                    listener.getClass().getName();
+                final String fullClassName =
+                        listener.getClass().getEnclosingClass() != null
+                            ? listener.getClass().getEnclosingClass().getName()
+                            : listener.getClass().getName();
                 queue = new SensorEventQueue(listener, looper, this, fullClassName);
                 if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
                     queue.dispose();
@@ -221,17 +222,18 @@
         if (sensor.getReportingMode() != Sensor.REPORTING_MODE_ONE_SHOT) return false;
 
         if (mTriggerListeners.size() >= MAX_LISTENER_COUNT) {
-            throw new IllegalStateException("request failed, " +
-                    "the trigger listeners size has exceeded the maximum limit " +
-                    MAX_LISTENER_COUNT);
+            throw new IllegalStateException("request failed, "
+                    + "the trigger listeners size has exceeded the maximum limit "
+                    + MAX_LISTENER_COUNT);
         }
 
         synchronized (mTriggerListeners) {
             TriggerEventQueue queue = mTriggerListeners.get(listener);
             if (queue == null) {
-                final String fullClassName = listener.getClass().getEnclosingClass() != null ?
-                    listener.getClass().getEnclosingClass().getName() :
-                    listener.getClass().getName();
+                final String fullClassName =
+                        listener.getClass().getEnclosingClass() != null
+                            ? listener.getClass().getEnclosingClass().getName()
+                            : listener.getClass().getName();
                 queue = new TriggerEventQueue(listener, mMainLooper, this, fullClassName);
                 if (!queue.addSensor(sensor, 0, 0)) {
                     queue.dispose();
@@ -336,27 +338,27 @@
         mHandleToSensor.remove(sensor.getHandle());
 
         if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
-            synchronized(mTriggerListeners) {
+            synchronized (mTriggerListeners) {
                 HashMap<TriggerEventListener, TriggerEventQueue> triggerListeners =
-                    new HashMap<TriggerEventListener, TriggerEventQueue>(mTriggerListeners);
+                        new HashMap<TriggerEventListener, TriggerEventQueue>(mTriggerListeners);
 
-                for (TriggerEventListener l: triggerListeners.keySet()) {
-                    if (DEBUG_DYNAMIC_SENSOR){
-                        Log.i(TAG, "removed trigger listener" + l.toString() +
-                                   " due to sensor disconnection");
+                for (TriggerEventListener l : triggerListeners.keySet()) {
+                    if (DEBUG_DYNAMIC_SENSOR) {
+                        Log.i(TAG, "removed trigger listener" + l.toString()
+                                + " due to sensor disconnection");
                     }
                     cancelTriggerSensorImpl(l, sensor, true);
                 }
             }
         } else {
-            synchronized(mSensorListeners) {
+            synchronized (mSensorListeners) {
                 HashMap<SensorEventListener, SensorEventQueue> sensorListeners =
-                    new HashMap<SensorEventListener, SensorEventQueue>(mSensorListeners);
+                        new HashMap<SensorEventListener, SensorEventQueue>(mSensorListeners);
 
                 for (SensorEventListener l: sensorListeners.keySet()) {
-                    if (DEBUG_DYNAMIC_SENSOR){
-                        Log.i(TAG, "removed event listener" + l.toString() +
-                                   " due to sensor disconnection");
+                    if (DEBUG_DYNAMIC_SENSOR) {
+                        Log.i(TAG, "removed event listener" + l.toString()
+                                + " due to sensor disconnection");
                     }
                     unregisterListenerImpl(l, sensor);
                 }
@@ -365,7 +367,7 @@
     }
 
     private void updateDynamicSensorList() {
-        synchronized(mFullDynamicSensorsList) {
+        synchronized (mFullDynamicSensorsList) {
             if (mDynamicSensorListDirty) {
                 List<Sensor> list = new ArrayList<>();
                 nativeGetDynamicSensors(mNativeInstance, list);
@@ -488,15 +490,15 @@
 
         int i = 0, j = 0;
         while (true) {
-            if (j < oldList.size() && ( i >= newList.size() ||
-                    newList.get(i).getHandle() > oldList.get(j).getHandle()) ) {
+            if (j < oldList.size() && (i >= newList.size()
+                    || newList.get(i).getHandle() > oldList.get(j).getHandle())) {
                 changed = true;
                 if (removed != null) {
                     removed.add(oldList.get(j));
                 }
                 ++j;
-            } else if (i < newList.size() && ( j >= oldList.size() ||
-                    newList.get(i).getHandle() < oldList.get(j).getHandle())) {
+            } else if (i < newList.size() && (j >= oldList.size()
+                    || newList.get(i).getHandle() < oldList.get(j).getHandle())) {
                 changed = true;
                 if (added != null) {
                     added.add(newList.get(i));
@@ -505,8 +507,8 @@
                     updated.add(newList.get(i));
                 }
                 ++i;
-            } else if (i < newList.size() && j < oldList.size() &&
-                    newList.get(i).getHandle() == oldList.get(j).getHandle()) {
+            } else if (i < newList.size() && j < oldList.size()
+                    && newList.get(i).getHandle() == oldList.get(j).getHandle()) {
                 if (updated != null) {
                     updated.add(oldList.get(j));
                 }
@@ -623,7 +625,7 @@
      * associated with any listener and there is one InjectEventQueue associated with a
      * SensorManager instance.
      */
-    private static abstract class BaseEventQueue {
+    private abstract static class BaseEventQueue {
         private static native long nativeInitBaseEventQueue(long nativeManager,
                 WeakReference<BaseEventQueue> eventQWeak, MessageQueue msgQ,
                 String packageName, int mode, String opPackageName);
@@ -633,9 +635,9 @@
         private static native void nativeDestroySensorEventQueue(long eventQ);
         private static native int nativeFlushSensor(long eventQ);
         private static native int nativeInjectSensorData(long eventQ, int handle,
-                float[] values,int accuracy, long timestamp);
+                float[] values, int accuracy, long timestamp);
 
-        private long nSensorEventQueue;
+        private long mNativeSensorEventQueue;
         private final SparseBooleanArray mActiveSensors = new SparseBooleanArray();
         protected final SparseIntArray mSensorAccuracies = new SparseIntArray();
         private final CloseGuard mCloseGuard = CloseGuard.get();
@@ -646,7 +648,7 @@
 
         BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) {
             if (packageName == null) packageName = "";
-            nSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance,
+            mNativeSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance,
                     new WeakReference<>(this), looper.getQueue(),
                     packageName, mode, manager.mContext.getOpPackageName());
             mCloseGuard.open("dispose");
@@ -668,17 +670,17 @@
             addSensorEvent(sensor);
             if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) {
                 // Try continuous mode if batching fails.
-                if (maxBatchReportLatencyUs == 0 ||
-                    maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
-                  removeSensor(sensor, false);
-                  return false;
+                if (maxBatchReportLatencyUs == 0
+                        || maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
+                    removeSensor(sensor, false);
+                    return false;
                 }
             }
             return true;
         }
 
         public boolean removeAllSensors() {
-            for (int i=0 ; i<mActiveSensors.size(); i++) {
+            for (int i = 0; i < mActiveSensors.size(); i++) {
                 if (mActiveSensors.valueAt(i) == true) {
                     int handle = mActiveSensors.keyAt(i);
                     Sensor sensor = mManager.mHandleToSensor.get(handle);
@@ -706,8 +708,8 @@
         }
 
         public int flush() {
-            if (nSensorEventQueue == 0) throw new NullPointerException();
-            return nativeFlushSensor(nSensorEventQueue);
+            if (mNativeSensorEventQueue == 0) throw new NullPointerException();
+            return nativeFlushSensor(mNativeSensorEventQueue);
         }
 
         public boolean hasSensors() {
@@ -731,29 +733,30 @@
                 }
                 mCloseGuard.close();
             }
-            if (nSensorEventQueue != 0) {
-                nativeDestroySensorEventQueue(nSensorEventQueue);
-                nSensorEventQueue = 0;
+            if (mNativeSensorEventQueue != 0) {
+                nativeDestroySensorEventQueue(mNativeSensorEventQueue);
+                mNativeSensorEventQueue = 0;
             }
         }
 
         private int enableSensor(
                 Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
-            if (nSensorEventQueue == 0) throw new NullPointerException();
+            if (mNativeSensorEventQueue == 0) throw new NullPointerException();
             if (sensor == null) throw new NullPointerException();
-            return nativeEnableSensor(nSensorEventQueue, sensor.getHandle(), rateUs,
+            return nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs,
                     maxBatchReportLatencyUs);
         }
 
         protected int injectSensorDataBase(int handle, float[] values, int accuracy,
                                            long timestamp) {
-            return nativeInjectSensorData(nSensorEventQueue, handle, values, accuracy, timestamp);
+            return nativeInjectSensorData(
+                    mNativeSensorEventQueue, handle, values, accuracy, timestamp);
         }
 
         private int disableSensor(Sensor sensor) {
-            if (nSensorEventQueue == 0) throw new NullPointerException();
+            if (mNativeSensorEventQueue == 0) throw new NullPointerException();
             if (sensor == null) throw new NullPointerException();
-            return nativeDisableSensor(nSensorEventQueue, sensor.getHandle());
+            return nativeDisableSensor(mNativeSensorEventQueue, sensor.getHandle());
         }
         protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy,
                 long timestamp);
@@ -840,7 +843,7 @@
                     // sensor disconnected
                     return;
                 }
-                ((SensorEventListener2)mListener).onFlushCompleted(sensor);
+                ((SensorEventListener2) mListener).onFlushCompleted(sensor);
             }
             return;
         }
@@ -858,7 +861,7 @@
                 }
                 SensorAdditionalInfo info =
                         new SensorAdditionalInfo(sensor, type, serial, intValues, floatValues);
-                ((SensorEventCallback)mListener).onSensorAdditionalInfo(info);
+                ((SensorEventCallback) mListener).onSensorAdditionalInfo(info);
             }
         }
     }
@@ -930,8 +933,8 @@
             super(looper, manager, OPERATING_MODE_DATA_INJECTION, packageName);
         }
 
-        int injectSensorData(int handle, float[] values,int accuracy, long timestamp) {
-             return injectSensorDataBase(handle, values, accuracy, timestamp);
+        int injectSensorData(int handle, float[] values, int accuracy, long timestamp) {
+            return injectSensorDataBase(handle, values, accuracy, timestamp);
         }
 
         @SuppressWarnings("unused")
@@ -956,7 +959,10 @@
     }
 
     protected boolean setOperationParameterImpl(SensorAdditionalInfo parameter) {
+        int handle = -1;
+        if (parameter.sensor != null) handle = parameter.sensor.getHandle();
         return nativeSetOperationParameter(
-                mNativeInstance, parameter.type, parameter.floatValues, parameter.intValues) == 0;
+                mNativeInstance, handle,
+                parameter.type, parameter.floatValues, parameter.intValues) == 0;
     }
 }
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 63eedf5..55343a2 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -73,8 +73,10 @@
      * Create a request suitable for still image capture. Specifically, this
      * means prioritizing image quality over frame rate. These requests would
      * commonly be used with the {@link CameraCaptureSession#capture} method.
-     * This template is guaranteed to be supported on all camera devices.
-     *
+     * This template is guaranteed to be supported on all camera devices except
+     * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices
+     * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
+     * BACKWARD_COMPATIBLE}.
      * @see #createCaptureRequest
      */
     public static final int TEMPLATE_STILL_CAPTURE = 2;
@@ -84,7 +86,10 @@
      * that a stable frame rate is used, and post-processing is set for
      * recording quality. These requests would commonly be used with the
      * {@link CameraCaptureSession#setRepeatingRequest} method.
-     * This template is guaranteed to be supported on all camera devices.
+     * This template is guaranteed to be supported on all camera devices except
+     * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices
+     * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
+     * BACKWARD_COMPATIBLE}.
      *
      * @see #createCaptureRequest
      */
@@ -98,7 +103,10 @@
      * {@link #TEMPLATE_RECORD} is is in use with {@link CameraCaptureSession#setRepeatingRequest}.
      * This template is guaranteed to be supported on all camera devices except
      * legacy devices ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
-     * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY})
+     * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}) and
+     * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices
+     * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
+     * BACKWARD_COMPATIBLE}.
      *
      * @see #createCaptureRequest
      */
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 1b150bf..90bf896 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -16,28 +16,29 @@
 
 package android.hardware.camera2;
 
-import android.annotation.RequiresPermission;
-import android.annotation.SystemService;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemService;
 import android.content.Context;
-import android.hardware.ICameraService;
-import android.hardware.ICameraServiceListener;
 import android.hardware.CameraInfo;
 import android.hardware.CameraStatus;
+import android.hardware.ICameraService;
+import android.hardware.ICameraServiceListener;
 import android.hardware.camera2.impl.CameraMetadataNative;
 import android.hardware.camera2.legacy.CameraDeviceUserShim;
 import android.hardware.camera2.legacy.LegacyMetadataMapper;
-import android.os.IBinder;
 import android.os.Binder;
 import android.os.DeadObjectException;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
-import android.util.Log;
+import android.os.SystemProperties;
 import android.util.ArrayMap;
+import android.util.Log;
 
 import java.util.ArrayList;
 
@@ -210,7 +211,9 @@
     public CameraCharacteristics getCameraCharacteristics(@NonNull String cameraId)
             throws CameraAccessException {
         CameraCharacteristics characteristics = null;
-
+        if (CameraManagerGlobal.sCameraServiceDisabled) {
+            throw new IllegalArgumentException("No cameras available on device");
+        }
         synchronized (mLock) {
             /*
              * Get the camera characteristics from the camera service directly if it supports it,
@@ -462,6 +465,9 @@
                         "Handler argument is null, but no looper exists in the calling thread");
             }
         }
+        if (CameraManagerGlobal.sCameraServiceDisabled) {
+            throw new IllegalArgumentException("No cameras available on device");
+        }
 
         openCameraDeviceUserAsync(cameraId, callback, handler, clientUid);
     }
@@ -507,6 +513,9 @@
      */
     public void setTorchMode(@NonNull String cameraId, boolean enabled)
             throws CameraAccessException {
+        if (CameraManagerGlobal.sCameraServiceDisabled) {
+            throw new IllegalArgumentException("No cameras available on device");
+        }
         CameraManagerGlobal.get().setTorchMode(cameraId, enabled);
     }
 
@@ -745,6 +754,9 @@
         private CameraManagerGlobal() {
         }
 
+        public static final boolean sCameraServiceDisabled =
+                SystemProperties.getBoolean("config.disable_cameraservice", false);
+
         public static CameraManagerGlobal get() {
             return gCameraManager;
         }
@@ -764,7 +776,7 @@
         public ICameraService getCameraService() {
             synchronized(mLock) {
                 connectCameraServiceLocked();
-                if (mCameraService == null) {
+                if (mCameraService == null && !sCameraServiceDisabled) {
                     Log.e(TAG, "Camera service is unavailable");
                 }
                 return mCameraService;
@@ -779,7 +791,7 @@
          */
         private void connectCameraServiceLocked() {
             // Only reconnect if necessary
-            if (mCameraService != null) return;
+            if (mCameraService != null || sCameraServiceDisabled) return;
 
             Log.i(TAG, "Connecting to camera service");
 
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index b3938cb..c7654c9 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -158,7 +158,7 @@
     }
 
     @Override
-    public synchronized int capture(CaptureRequest request, CaptureCallback callback,
+    public int capture(CaptureRequest request, CaptureCallback callback,
             Handler handler) throws CameraAccessException {
         if (request == null) {
             throw new IllegalArgumentException("request must not be null");
@@ -169,21 +169,23 @@
             throw new IllegalArgumentException("capture request was created for another session");
         }
 
-        checkNotClosed();
+        synchronized (mDeviceImpl.mInterfaceLock) {
+            checkNotClosed();
 
-        handler = checkHandler(handler, callback);
+            handler = checkHandler(handler, callback);
 
-        if (DEBUG) {
-            Log.v(TAG, mIdString + "capture - request " + request + ", callback " + callback +
-                    " handler " + handler);
+            if (DEBUG) {
+                Log.v(TAG, mIdString + "capture - request " + request + ", callback " + callback +
+                        " handler " + handler);
+            }
+
+            return addPendingSequence(mDeviceImpl.capture(request,
+                    createCaptureCallbackProxy(handler, callback), mDeviceHandler));
         }
-
-        return addPendingSequence(mDeviceImpl.capture(request,
-                createCaptureCallbackProxy(handler, callback), mDeviceHandler));
     }
 
     @Override
-    public synchronized int captureBurst(List<CaptureRequest> requests, CaptureCallback callback,
+    public int captureBurst(List<CaptureRequest> requests, CaptureCallback callback,
             Handler handler) throws CameraAccessException {
         if (requests == null) {
             throw new IllegalArgumentException("Requests must not be null");
@@ -203,22 +205,24 @@
             }
         }
 
-        checkNotClosed();
+        synchronized (mDeviceImpl.mInterfaceLock) {
+            checkNotClosed();
 
-        handler = checkHandler(handler, callback);
+            handler = checkHandler(handler, callback);
 
-        if (DEBUG) {
-            CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
-            Log.v(TAG, mIdString + "captureBurst - requests " + Arrays.toString(requestArray) +
-                    ", callback " + callback + " handler " + handler);
+            if (DEBUG) {
+                CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
+                Log.v(TAG, mIdString + "captureBurst - requests " + Arrays.toString(requestArray) +
+                        ", callback " + callback + " handler " + handler);
+            }
+
+            return addPendingSequence(mDeviceImpl.captureBurst(requests,
+                    createCaptureCallbackProxy(handler, callback), mDeviceHandler));
         }
-
-        return addPendingSequence(mDeviceImpl.captureBurst(requests,
-                createCaptureCallbackProxy(handler, callback), mDeviceHandler));
     }
 
     @Override
-    public synchronized int setRepeatingRequest(CaptureRequest request, CaptureCallback callback,
+    public int setRepeatingRequest(CaptureRequest request, CaptureCallback callback,
             Handler handler) throws CameraAccessException {
         if (request == null) {
             throw new IllegalArgumentException("request must not be null");
@@ -226,21 +230,23 @@
             throw new IllegalArgumentException("repeating reprocess requests are not supported");
         }
 
-        checkNotClosed();
+        synchronized (mDeviceImpl.mInterfaceLock) {
+            checkNotClosed();
 
-        handler = checkHandler(handler, callback);
+            handler = checkHandler(handler, callback);
 
-        if (DEBUG) {
-            Log.v(TAG, mIdString + "setRepeatingRequest - request " + request + ", callback " +
-                    callback + " handler" + " " + handler);
+            if (DEBUG) {
+                Log.v(TAG, mIdString + "setRepeatingRequest - request " + request + ", callback " +
+                        callback + " handler" + " " + handler);
+            }
+
+            return addPendingSequence(mDeviceImpl.setRepeatingRequest(request,
+                    createCaptureCallbackProxy(handler, callback), mDeviceHandler));
         }
-
-        return addPendingSequence(mDeviceImpl.setRepeatingRequest(request,
-                createCaptureCallbackProxy(handler, callback), mDeviceHandler));
     }
 
     @Override
-    public synchronized int setRepeatingBurst(List<CaptureRequest> requests,
+    public int setRepeatingBurst(List<CaptureRequest> requests,
             CaptureCallback callback, Handler handler) throws CameraAccessException {
         if (requests == null) {
             throw new IllegalArgumentException("requests must not be null");
@@ -255,34 +261,39 @@
             }
         }
 
-        checkNotClosed();
+        synchronized (mDeviceImpl.mInterfaceLock) {
+            checkNotClosed();
 
-        handler = checkHandler(handler, callback);
+            handler = checkHandler(handler, callback);
 
-        if (DEBUG) {
-            CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
-            Log.v(TAG, mIdString + "setRepeatingBurst - requests " + Arrays.toString(requestArray) +
-                    ", callback " + callback + " handler" + "" + handler);
+            if (DEBUG) {
+                CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
+                Log.v(TAG, mIdString + "setRepeatingBurst - requests " +
+                        Arrays.toString(requestArray) + ", callback " + callback +
+                        " handler" + "" + handler);
+            }
+
+            return addPendingSequence(mDeviceImpl.setRepeatingBurst(requests,
+                    createCaptureCallbackProxy(handler, callback), mDeviceHandler));
         }
-
-        return addPendingSequence(mDeviceImpl.setRepeatingBurst(requests,
-                createCaptureCallbackProxy(handler, callback), mDeviceHandler));
     }
 
     @Override
-    public synchronized void stopRepeating() throws CameraAccessException {
-        checkNotClosed();
+    public void stopRepeating() throws CameraAccessException {
+        synchronized (mDeviceImpl.mInterfaceLock) {
+            checkNotClosed();
 
-        if (DEBUG) {
-            Log.v(TAG, mIdString + "stopRepeating");
+            if (DEBUG) {
+                Log.v(TAG, mIdString + "stopRepeating");
+            }
+
+            mDeviceImpl.stopRepeating();
         }
-
-        mDeviceImpl.stopRepeating();
     }
 
     @Override
     public void abortCaptures() throws CameraAccessException {
-        synchronized (this) {
+        synchronized (mDeviceImpl.mInterfaceLock) {
             checkNotClosed();
 
             if (DEBUG) {
@@ -296,13 +307,9 @@
 
             mAborting = true;
             mAbortDrainer.taskStarted();
-        }
 
-        synchronized (mDeviceImpl.mInterfaceLock) {
-            synchronized (this) {
-                mDeviceImpl.flush();
-                // The next BUSY -> IDLE set of transitions will mark the end of the abort.
-            }
+            mDeviceImpl.flush();
+            // The next BUSY -> IDLE set of transitions will mark the end of the abort.
         }
     }
 
@@ -332,7 +339,7 @@
      */
     @Override
     public void replaceSessionClose() {
-        synchronized (this) {
+        synchronized (mDeviceImpl.mInterfaceLock) {
             /*
              * In order for creating new sessions to be fast, the new session should be created
              * before the old session is closed.
@@ -357,13 +364,13 @@
             // configuration for the new session. If it was already called, then we don't care,
             // since it won't get called again.
             mSkipUnconfigure = true;
+            close();
         }
-        close();
     }
 
     @Override
     public void close() {
-        synchronized (this) {
+        synchronized (mDeviceImpl.mInterfaceLock) {
             if (mClosed) {
                 if (DEBUG) Log.v(TAG, mIdString + "close - reentering");
                 return;
@@ -372,45 +379,42 @@
             if (DEBUG) Log.v(TAG, mIdString + "close - first time");
 
             mClosed = true;
-        }
 
-        synchronized (mDeviceImpl.mInterfaceLock) {
-            synchronized (this) {
-                /*
-                 * Flush out any repeating request. Since camera is closed, no new requests
-                 * can be queued, and eventually the entire request queue will be drained.
-                 *
-                 * If the camera device was already closed, short circuit and do nothing; since
-                 * no more internal device callbacks will fire anyway.
-                 *
-                 * Otherwise, once stopRepeating is done, wait for camera to idle, then unconfigure
-                 * the camera. Once that's done, fire #onClosed.
-                 */
-                try {
-                    mDeviceImpl.stopRepeating();
-                } catch (IllegalStateException e) {
-                    // OK: Camera device may already be closed, nothing else to do
+            /*
+             * Flush out any repeating request. Since camera is closed, no new requests
+             * can be queued, and eventually the entire request queue will be drained.
+             *
+             * If the camera device was already closed, short circuit and do nothing; since
+             * no more internal device callbacks will fire anyway.
+             *
+             * Otherwise, once stopRepeating is done, wait for camera to idle, then unconfigure
+             * the camera. Once that's done, fire #onClosed.
+             */
+            try {
+                mDeviceImpl.stopRepeating();
+            } catch (IllegalStateException e) {
+                // OK: Camera device may already be closed, nothing else to do
 
-                    // TODO: Fire onClosed anytime we get the device onClosed or the ISE?
-                    // or just suppress the ISE only and rely onClosed.
-                    // Also skip any of the draining work if this is already closed.
+                // TODO: Fire onClosed anytime we get the device onClosed or the ISE?
+                // or just suppress the ISE only and rely onClosed.
+                // Also skip any of the draining work if this is already closed.
 
-                    // Short-circuit; queue callback immediately and return
-                    mStateCallback.onClosed(this);
-                    return;
-                } catch (CameraAccessException e) {
-                    // OK: close does not throw checked exceptions.
-                    Log.e(TAG, mIdString + "Exception while stopping repeating: ", e);
+                // Short-circuit; queue callback immediately and return
+                mStateCallback.onClosed(this);
+                return;
+            } catch (CameraAccessException e) {
+                // OK: close does not throw checked exceptions.
+                Log.e(TAG, mIdString + "Exception while stopping repeating: ", e);
 
-                    // TODO: call onError instead of onClosed if this happens
-                }
+                // TODO: call onError instead of onClosed if this happens
             }
-        }
 
-        synchronized (this) {
             // If no sequences are pending, fire #onClosed immediately
             mSequenceDrainer.beginDrain();
         }
+        if (mInput != null) {
+            mInput.release();
+        }
     }
 
     /**
@@ -552,6 +556,8 @@
     @Override
     public CameraDeviceImpl.StateCallbackKK getDeviceStateCallback() {
         final CameraCaptureSession session = this;
+        final Object interfaceLock = mDeviceImpl.mInterfaceLock;
+
 
         return new CameraDeviceImpl.StateCallbackKK() {
             private boolean mBusy = false;
@@ -588,7 +594,7 @@
                 boolean isAborting;
                 if (DEBUG) Log.v(TAG, mIdString + "onIdle");
 
-                synchronized (session) {
+                synchronized (interfaceLock) {
                     isAborting = mAborting;
                 }
 
@@ -606,7 +612,7 @@
                 if (mBusy && isAborting) {
                     mAbortDrainer.taskFinished();
 
-                    synchronized (session) {
+                    synchronized (interfaceLock) {
                         mAborting = false;
                     }
                 }
@@ -729,7 +735,7 @@
         @Override
         public void onDrained() {
             if (DEBUG) Log.v(TAG, mIdString + "onAbortDrained");
-            synchronized (CameraCaptureSessionImpl.this) {
+            synchronized (mDeviceImpl.mInterfaceLock) {
                 /*
                  * Any queued aborts have now completed.
                  *
@@ -757,7 +763,6 @@
             // Take device lock before session lock so that we can call back into device
             // without causing a deadlock
             synchronized (mDeviceImpl.mInterfaceLock) {
-                synchronized (CameraCaptureSessionImpl.this) {
                 /*
                  * The device is now IDLE, and has settled. It will not transition to
                  * ACTIVE or BUSY again by itself.
@@ -766,33 +771,31 @@
                  *
                  * This operation is idempotent; a session will not be closed twice.
                  */
-                    if (DEBUG)
-                        Log.v(TAG, mIdString + "Session drain complete, skip unconfigure: " +
-                                mSkipUnconfigure);
+                if (DEBUG)
+                    Log.v(TAG, mIdString + "Session drain complete, skip unconfigure: " +
+                            mSkipUnconfigure);
 
-                    // Fast path: A new capture session has replaced this one; don't wait for idle
-                    // as we won't get state updates any more anyway.
-                    if (mSkipUnconfigure) {
-                        return;
-                    }
+                // Fast path: A new capture session has replaced this one; don't wait for idle
+                // as we won't get state updates any more anyway.
+                if (mSkipUnconfigure) {
+                    return;
+                }
 
-                    // Final slow path: unconfigure the camera, no session has replaced us and
-                    // everything is idle.
-                    try {
-                        // begin transition to unconfigured
-                        mDeviceImpl.configureStreamsChecked(/*inputConfig*/null, /*outputs*/null,
-                                /*operatingMode*/ ICameraDeviceUser.NORMAL_MODE);
-                    } catch (CameraAccessException e) {
-                        // OK: do not throw checked exceptions.
-                        Log.e(TAG, mIdString + "Exception while unconfiguring outputs: ", e);
+                // Final slow path: unconfigure the camera, no session has replaced us and
+                // everything is idle.
+                try {
+                    // begin transition to unconfigured
+                    mDeviceImpl.configureStreamsChecked(/*inputConfig*/null, /*outputs*/null,
+                            /*operatingMode*/ ICameraDeviceUser.NORMAL_MODE);
+                } catch (CameraAccessException e) {
+                    // OK: do not throw checked exceptions.
+                    Log.e(TAG, mIdString + "Exception while unconfiguring outputs: ", e);
 
-                        // TODO: call onError instead of onClosed if this happens
-                    } catch (IllegalStateException e) {
-                        // Camera is already closed, so nothing left to do
-                        if (DEBUG) Log.v(TAG, mIdString +
-                                "Camera was already closed or busy, skipping unconfigure");
-                    }
-
+                    // TODO: call onError instead of onClosed if this happens
+                } catch (IllegalStateException e) {
+                    // Camera is already closed, so nothing left to do
+                    if (DEBUG) Log.v(TAG, mIdString +
+                            "Camera was already closed or busy, skipping unconfigure");
                 }
             }
         }
diff --git a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
index 15dbf26..fec7fd9 100644
--- a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
@@ -96,6 +96,9 @@
         CaptureRequest.Builder singleTargetRequestBuilder = new CaptureRequest.Builder(
                 requestMetadata, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
 
+        // Carry over userTag, as native metadata doesn't have this field.
+        singleTargetRequestBuilder.setTag(request.getTag());
+
         // Overwrite the capture intent to make sure a good value is set.
         Iterator<Surface> iterator = outputSurfaces.iterator();
         Surface firstSurface = iterator.next();
@@ -118,6 +121,7 @@
             requestMetadata = new CameraMetadataNative(request.getNativeCopy());
             doubleTargetRequestBuilder = new CaptureRequest.Builder(
                     requestMetadata, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
+            doubleTargetRequestBuilder.setTag(request.getTag());
             doubleTargetRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
                     CaptureRequest.CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
             doubleTargetRequestBuilder.addTarget(firstSurface);
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index dbe1394..00e047d 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -1112,6 +1112,8 @@
                 return ImageFormat.DEPTH_POINT_CLOUD;
             case HAL_PIXEL_FORMAT_Y16:
                 return ImageFormat.DEPTH16;
+            case HAL_PIXEL_FORMAT_RAW16:
+                return ImageFormat.RAW_DEPTH;
             case ImageFormat.JPEG:
                 throw new IllegalArgumentException(
                         "ImageFormat.JPEG is an unknown internal format");
@@ -1179,6 +1181,8 @@
                 return HAL_PIXEL_FORMAT_BLOB;
             case ImageFormat.DEPTH16:
                 return HAL_PIXEL_FORMAT_Y16;
+            case ImageFormat.RAW_DEPTH:
+                return HAL_PIXEL_FORMAT_RAW16;
             default:
                 return format;
         }
@@ -1220,6 +1224,7 @@
                 return HAL_DATASPACE_V0_JFIF;
             case ImageFormat.DEPTH_POINT_CLOUD:
             case ImageFormat.DEPTH16:
+            case ImageFormat.RAW_DEPTH:
                 return HAL_DATASPACE_DEPTH;
             default:
                 return HAL_DATASPACE_UNKNOWN;
@@ -1609,6 +1614,8 @@
                 return "DEPTH16";
             case ImageFormat.DEPTH_POINT_CLOUD:
                 return "DEPTH_POINT_CLOUD";
+            case ImageFormat.RAW_DEPTH:
+                return "RAW_DEPTH";
             case ImageFormat.PRIVATE:
                 return "PRIVATE";
             default:
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 6a02b6b..bda8039 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -256,6 +256,15 @@
      */
     public static final int VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH = 1 << 6;
 
+    /**
+     * Virtual display flag: Indicates that the orientation of this display device is coupled to
+     * the rotation of its associated logical display.
+     *
+     * @see #createVirtualDisplay
+     * @hide
+     */
+    public static final int VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT = 1 << 7;
+
     /** @hide */
     public DisplayManager(Context context) {
         mContext = context;
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index bdb278b..4586316 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -34,6 +34,11 @@
     InputDevice getInputDevice(int deviceId);
     int[] getInputDeviceIds();
 
+    // Enable/disable input device.
+    boolean isInputDeviceEnabled(int deviceId);
+    void enableInputDevice(int deviceId);
+    void disableInputDevice(int deviceId);
+
     // Reports whether the hardware supports the given keys; returns true if successful
     boolean hasKeys(int deviceId, int sourceMask, in int[] keyCodes, out boolean[] keyExists);
 
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 5149e93..4898c1a 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -16,8 +16,6 @@
 
 package android.hardware.input;
 
-import com.android.internal.os.SomeArgs;
-
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
@@ -32,10 +30,10 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.Vibrator;
-import android.os.VibrationEffect;
 import android.os.ServiceManager.ServiceNotFoundException;
+import android.os.SystemClock;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.util.Log;
@@ -47,6 +45,8 @@
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodSubtype;
 
+import com.android.internal.os.SomeArgs;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -319,6 +319,62 @@
     }
 
     /**
+     * Returns true if an input device is enabled. Should return true for most
+     * situations. Some system apps may disable an input device, for
+     * example to prevent unwanted touch events.
+     *
+     * @param id The input device Id.
+     *
+     * @hide
+     */
+    public boolean isInputDeviceEnabled(int id) {
+        try {
+            return mIm.isInputDeviceEnabled(id);
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Could not check enabled status of input device with id = " + id);
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Enables an InputDevice.
+     * <p>
+     * Requires {@link android.Manifest.permissions.DISABLE_INPUT_DEVICE}.
+     * </p>
+     *
+     * @param id The input device Id.
+     *
+     * @hide
+     */
+    public void enableInputDevice(int id) {
+        try {
+            mIm.enableInputDevice(id);
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Could not enable input device with id = " + id);
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Disables an InputDevice.
+     * <p>
+     * Requires {@link android.Manifest.permissions.DISABLE_INPUT_DEVICE}.
+     * </p>
+     *
+     * @param id The input device Id.
+     *
+     * @hide
+     */
+    public void disableInputDevice(int id) {
+        try {
+            mIm.disableInputDevice(id);
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Could not disable input device with id = " + id);
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Registers an input device listener to receive notifications about when
      * input devices are added, removed or changed.
      *
diff --git a/core/java/android/hardware/radio/IRadioService.aidl b/core/java/android/hardware/radio/IRadioService.aidl
new file mode 100644
index 0000000..9a157d1
--- /dev/null
+++ b/core/java/android/hardware/radio/IRadioService.aidl
@@ -0,0 +1,31 @@
+/**
+ * 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.hardware.radio;
+
+import android.hardware.radio.ITuner;
+import android.hardware.radio.ITunerCallback;
+import android.hardware.radio.RadioManager;
+
+/**
+ * API to the broadcast radio service.
+ *
+ * {@hide}
+ */
+interface IRadioService {
+    ITuner openTuner(int moduleId, in RadioManager.BandConfig bandConfig, boolean withAudio,
+            in ITunerCallback callback);
+}
diff --git a/core/java/android/hardware/radio/ITuner.aidl b/core/java/android/hardware/radio/ITuner.aidl
new file mode 100644
index 0000000..1fc71e0
--- /dev/null
+++ b/core/java/android/hardware/radio/ITuner.aidl
@@ -0,0 +1,89 @@
+/**
+ * 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.hardware.radio;
+
+import android.hardware.radio.RadioManager;
+
+/** {@hide} */
+interface ITuner {
+    void close();
+
+    /**
+     * @throws IllegalArgumentException if config is not valid or null
+     */
+    void setConfiguration(in RadioManager.BandConfig config);
+
+    RadioManager.BandConfig getConfiguration();
+
+    /**
+     * @throws IllegalStateException if tuner was opened without audio
+     */
+    void setMuted(boolean mute);
+
+    boolean isMuted();
+
+    /**
+     * @throws IllegalStateException if called out of sequence
+     */
+    void step(boolean directionDown, boolean skipSubChannel);
+
+    /**
+     * @throws IllegalStateException if called out of sequence
+     */
+    void scan(boolean directionDown, boolean skipSubChannel);
+
+    /**
+     * @throws IllegalArgumentException if invalid arguments are passed
+     * @throws IllegalStateException if called out of sequence
+     */
+    void tune(int channel, int subChannel);
+
+    /**
+     * @throws IllegalStateException if called out of sequence
+     */
+    void cancel();
+
+    RadioManager.ProgramInfo getProgramInformation();
+
+    /**
+     * @returns {@code true} if the scan was properly scheduled,
+     *          {@code false} if the scan feature is unavailable
+     */
+    boolean startBackgroundScan();
+
+    /**
+     * @returns the list, or null if scan is in progress
+     * @throws IllegalArgumentException if invalid arguments are passed
+     * @throws IllegalStateException if the scan has not been started, client may
+     *         call startBackgroundScan to fix this.
+     */
+    List<RadioManager.ProgramInfo> getProgramList(String filter);
+
+    /**
+     * @throws IllegalStateException if the switch is not supported at current
+     *         configuration.
+     */
+    boolean isAnalogForced();
+
+    /**
+     * @throws IllegalStateException if the switch is not supported at current
+     *         configuration.
+     */
+    void setAnalogForced(boolean isForced);
+
+    boolean isAntennaConnected();
+}
diff --git a/core/java/android/hardware/radio/ITunerCallback.aidl b/core/java/android/hardware/radio/ITunerCallback.aidl
new file mode 100644
index 0000000..b32c683
--- /dev/null
+++ b/core/java/android/hardware/radio/ITunerCallback.aidl
@@ -0,0 +1,26 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio;
+
+import android.hardware.radio.RadioManager;
+
+/** {@hide} */
+oneway interface ITunerCallback {
+    void onError(int status);
+    void onConfigurationChanged(in RadioManager.BandConfig config);
+    void onProgramInfoChanged(in RadioManager.ProgramInfo info);
+}
diff --git a/core/java/android/hardware/radio/RadioManager.aidl b/core/java/android/hardware/radio/RadioManager.aidl
new file mode 100644
index 0000000..0f0ec84
--- /dev/null
+++ b/core/java/android/hardware/radio/RadioManager.aidl
@@ -0,0 +1,23 @@
+/**
+ * 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.hardware.radio;
+
+/** @hide */
+parcelable RadioManager.ProgramInfo;
+
+/** @hide */
+parcelable RadioManager.BandConfig;
diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java
index 24bb524..20292f7 100644
--- a/core/java/android/hardware/radio/RadioManager.java
+++ b/core/java/android/hardware/radio/RadioManager.java
@@ -16,12 +16,21 @@
 
 package android.hardware.radio;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.content.Context;
 import android.os.Handler;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.ServiceManager.ServiceNotFoundException;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Log;
+
 import java.util.List;
 import java.util.Arrays;
 
@@ -35,6 +44,7 @@
 @SystemApi
 @SystemService(Context.RADIO_SERVICE)
 public class RadioManager {
+    private static final String TAG = "RadioManager";
 
     /** Method return status: successful operation */
     public static final int STATUS_OK = 0;
@@ -110,10 +120,12 @@
         private final int mNumAudioSources;
         private final boolean mIsCaptureSupported;
         private final BandDescriptor[] mBands;
+        private final boolean mIsBgScanSupported;
+        private final String mVendorExension;
 
         ModuleProperties(int id, int classId, String implementor, String product, String version,
                 String serial, int numTuners, int numAudioSources, boolean isCaptureSupported,
-                BandDescriptor[] bands) {
+                BandDescriptor[] bands, boolean isBgScanSupported, String vendorExension) {
             mId = id;
             mClassId = classId;
             mImplementor = implementor;
@@ -124,6 +136,8 @@
             mNumAudioSources = numAudioSources;
             mIsCaptureSupported = isCaptureSupported;
             mBands = bands;
+            mIsBgScanSupported = isBgScanSupported;
+            mVendorExension = vendorExension;
         }
 
 
@@ -198,6 +212,35 @@
             return mIsCaptureSupported;
         }
 
+        /**
+         * {@code true} if the module supports background scanning. At the given time it may not
+         * be available though, see {@link RadioTuner#startBackgroundScan()}.
+         *
+         * @return {@code true} if background scanning is supported (not necessary available
+         * at a given time), {@code false} otherwise.
+         *
+         * @hide FutureFeature
+         */
+        public boolean isBackgroundScanningSupported() {
+            return mIsBgScanSupported;
+        }
+
+        /**
+         * Opaque vendor-specific string, passed from HAL without changes.
+         * Format of this string can vary across vendors.
+         *
+         * It may be used for extra features, that's not supported by a platform,
+         * for example: "preset-slots=6;ultra-hd-capable=false".
+         *
+         * Client application MUST verify vendor/product name from the
+         * ModuleProperties class before doing any interpretation of this value.
+         *
+         * @hide FutureFeature
+         */
+        public @NonNull String getVendorExension() {
+            return mVendorExension == null ? "" : mVendorExension;
+        }
+
         /** List of descriptors for all bands supported by this module.
          * @return an array of {@link BandDescriptor}.
          */
@@ -220,6 +263,8 @@
             for (int i = 0; i < tmp.length; i++) {
                 mBands[i] = (BandDescriptor) tmp[i];
             }
+            mIsBgScanSupported = in.readInt() == 1;
+            mVendorExension = in.readString();
         }
 
         public static final Parcelable.Creator<ModuleProperties> CREATOR
@@ -245,6 +290,8 @@
             dest.writeInt(mNumAudioSources);
             dest.writeInt(mIsCaptureSupported ? 1 : 0);
             dest.writeParcelableArray(mBands, flags);
+            dest.writeInt(mIsBgScanSupported ? 1 : 0);
+            dest.writeString(mVendorExension);
         }
 
         @Override
@@ -260,6 +307,7 @@
                     + ", mNumTuners=" + mNumTuners
                     + ", mNumAudioSources=" + mNumAudioSources
                     + ", mIsCaptureSupported=" + mIsCaptureSupported
+                    + ", mIsBgScanSupported=" + mIsBgScanSupported
                     + ", mBands=" + Arrays.toString(mBands) + "]";
         }
 
@@ -277,6 +325,8 @@
             result = prime * result + mNumAudioSources;
             result = prime * result + (mIsCaptureSupported ? 1 : 0);
             result = prime * result + Arrays.hashCode(mBands);
+            result = prime * result + (mIsBgScanSupported ? 1 : 0);
+            result = prime * result + ((mVendorExension == null) ? 0 : mVendorExension.hashCode());
             return result;
         }
 
@@ -319,6 +369,10 @@
                 return false;
             if (!Arrays.equals(mBands, other.getBands()))
                 return false;
+            if (mIsBgScanSupported != other.isBackgroundScanningSupported())
+                return false;
+            if (!TextUtils.equals(mVendorExension, other.mVendorExension))
+                return false;
             return true;
         }
     }
@@ -334,6 +388,9 @@
         private final int mSpacing;
 
         BandDescriptor(int region, int type, int lowerLimit, int upperLimit, int spacing) {
+            if (type != BAND_AM && type != BAND_FM && type != BAND_FM_HD && type != BAND_AM_HD) {
+                throw new IllegalArgumentException("Unsupported band: " + type);
+            }
             mRegion = region;
             mType = type;
             mLowerLimit = lowerLimit;
@@ -387,10 +444,28 @@
             mSpacing = in.readInt();
         }
 
+        private static int lookupTypeFromParcel(Parcel in) {
+            int pos = in.dataPosition();
+            in.readInt();  // skip region
+            int type = in.readInt();
+            in.setDataPosition(pos);
+            return type;
+        }
+
         public static final Parcelable.Creator<BandDescriptor> CREATOR
                 = new Parcelable.Creator<BandDescriptor>() {
             public BandDescriptor createFromParcel(Parcel in) {
-                return new BandDescriptor(in);
+                int type = lookupTypeFromParcel(in);
+                switch (type) {
+                    case BAND_FM:
+                    case BAND_FM_HD:
+                        return new FmBandDescriptor(in);
+                    case BAND_AM:
+                    case BAND_AM_HD:
+                        return new AmBandDescriptor(in);
+                    default:
+                        throw new IllegalArgumentException("Unsupported band: " + type);
+                }
             }
 
             public BandDescriptor[] newArray(int size) {
@@ -719,7 +794,17 @@
         public static final Parcelable.Creator<BandConfig> CREATOR
                 = new Parcelable.Creator<BandConfig>() {
             public BandConfig createFromParcel(Parcel in) {
-                return new BandConfig(in);
+                int type = BandDescriptor.lookupTypeFromParcel(in);
+                switch (type) {
+                    case BAND_FM:
+                    case BAND_FM_HD:
+                        return new FmBandConfig(in);
+                    case BAND_AM:
+                    case BAND_AM_HD:
+                        return new AmBandConfig(in);
+                    default:
+                        throw new IllegalArgumentException("Unsupported band: " + type);
+                }
             }
 
             public BandConfig[] newArray(int size) {
@@ -1139,23 +1224,32 @@
      * {@link RadioTuner#getProgramInformation(RadioManager.ProgramInfo[])} */
     public static class ProgramInfo implements Parcelable {
 
+        // sourced from hardware/interfaces/broadcastradio/1.1/types.hal
+        private final static int FLAG_LIVE = 1 << 0;
+        private final static int FLAG_MUTED = 1 << 1;
+
         private final int mChannel;
         private final int mSubChannel;
         private final boolean mTuned;
         private final boolean mStereo;
         private final boolean mDigital;
+        private final int mFlags;
         private final int mSignalStrength;
         private final RadioMetadata mMetadata;
+        private final String mVendorExension;
 
         ProgramInfo(int channel, int subChannel, boolean tuned, boolean stereo,
-                boolean digital, int signalStrength, RadioMetadata metadata) {
+                boolean digital, int signalStrength, RadioMetadata metadata, int flags,
+                String vendorExension) {
             mChannel = channel;
             mSubChannel = subChannel;
             mTuned = tuned;
             mStereo = stereo;
             mDigital = digital;
+            mFlags = flags;
             mSignalStrength = signalStrength;
             mMetadata = metadata;
+            mVendorExension = vendorExension;
         }
 
         /** Main channel expressed in units according to band type.
@@ -1189,6 +1283,30 @@
         public boolean isDigital() {
             return mDigital;
         }
+
+        /**
+         * {@code true} if the program is currently playing live stream.
+         * This may result in a slightly altered reception parameters,
+         * usually targetted at reduced latency.
+         *
+         * @hide FutureFeature
+         */
+        public boolean isLive() {
+            return (mFlags & FLAG_LIVE) != 0;
+        }
+
+        /**
+         * {@code true} if radio stream is not playing, ie. due to bad reception
+         * conditions or buffering. In this state volume knob MAY be disabled to
+         * prevent user increasing volume too much.
+         * It does NOT mean the user has muted audio.
+         *
+         * @hide FutureFeature
+         */
+        public boolean isMuted() {
+            return (mFlags & FLAG_MUTED) != 0;
+        }
+
         /** Signal strength indicator from 0 (no signal) to 100 (excellent)
          * @return the signal strength indication.
          */
@@ -1203,6 +1321,22 @@
             return mMetadata;
         }
 
+        /**
+         * Opaque vendor-specific string, passed from HAL without changes.
+         * Format of this string can vary across vendors.
+         *
+         * It may be used for extra features, that's not supported by a platform,
+         * for example: "paid-service=true;bitrate=320kbps".
+         *
+         * Client application MUST verify vendor/product name from the
+         * ModuleProperties class before doing any interpretation of this value.
+         *
+         * @hide FutureFeature
+         */
+        public @NonNull String getVendorExension() {
+            return mVendorExension == null ? "" : mVendorExension;
+        }
+
         private ProgramInfo(Parcel in) {
             mChannel = in.readInt();
             mSubChannel = in.readInt();
@@ -1215,6 +1349,8 @@
             } else {
                 mMetadata = null;
             }
+            mFlags = in.readInt();
+            mVendorExension = in.readString();
         }
 
         public static final Parcelable.Creator<ProgramInfo> CREATOR
@@ -1242,6 +1378,8 @@
                 dest.writeByte((byte)1);
                 mMetadata.writeToParcel(dest, flags);
             }
+            dest.writeInt(mFlags);
+            dest.writeString(mVendorExension);
         }
 
         @Override
@@ -1253,7 +1391,7 @@
         public String toString() {
             return "ProgramInfo [mChannel=" + mChannel + ", mSubChannel=" + mSubChannel
                     + ", mTuned=" + mTuned + ", mStereo=" + mStereo + ", mDigital=" + mDigital
-                    + ", mSignalStrength=" + mSignalStrength
+                    + ", mFlags=" + mFlags + ", mSignalStrength=" + mSignalStrength
                     + ((mMetadata == null) ? "" : (", mMetadata=" + mMetadata.toString()))
                     + "]";
         }
@@ -1267,8 +1405,10 @@
             result = prime * result + (mTuned ? 1 : 0);
             result = prime * result + (mStereo ? 1 : 0);
             result = prime * result + (mDigital ? 1 : 0);
+            result = prime * result + mFlags;
             result = prime * result + mSignalStrength;
             result = prime * result + ((mMetadata == null) ? 0 : mMetadata.hashCode());
+            result = prime * result + ((mVendorExension == null) ? 0 : mVendorExension.hashCode());
             return result;
         }
 
@@ -1289,6 +1429,8 @@
                 return false;
             if (mDigital != other.isDigital())
                 return false;
+            if (mFlags != other.mFlags)
+                return false;
             if (mSignalStrength != other.getSignalStrength())
                 return false;
             if (mMetadata == null) {
@@ -1296,6 +1438,8 @@
                     return false;
             } else if (!mMetadata.equals(other.getMetadata()))
                 return false;
+            if (!TextUtils.equals(mVendorExension, other.mVendorExension))
+                return false;
             return true;
         }
     }
@@ -1332,23 +1476,47 @@
     public RadioTuner openTuner(int moduleId, BandConfig config, boolean withAudio,
             RadioTuner.Callback callback, Handler handler) {
         if (callback == null) {
-            return null;
+            throw new IllegalArgumentException("callback must not be empty");
         }
-        RadioModule module = new RadioModule(moduleId, config, withAudio, callback, handler);
-        if (module != null) {
-            if (!module.initCheck()) {
-                module = null;
+
+        if (mService != null) {
+            Log.d(TAG, "Opening tuner...");
+
+            ITuner tuner;
+            ITunerCallback halCallback = new TunerCallbackAdapter(callback, handler);
+            try {
+                tuner = mService.openTuner(moduleId, config, withAudio, halCallback);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
             }
+            if (tuner == null) {
+                Log.e(TAG, "Failed to open tuner");
+                return null;
+            }
+            return new TunerAdapter(tuner);
         }
+
+        RadioModule module = new RadioModule(moduleId, config, withAudio, callback, handler);
+        if (!module.initCheck()) {
+            Log.e(TAG, "Failed to open tuner");
+            module = null;
+        }
+
         return (RadioTuner)module;
     }
 
-    private final Context mContext;
+    @NonNull private final Context mContext;
+    // TODO(b/36863239): NonNull when transitioned from native service
+    @Nullable private final IRadioService mService;
 
     /**
      * @hide
      */
-    public RadioManager(Context context) {
+    public RadioManager(@NonNull Context context) throws ServiceNotFoundException {
         mContext = context;
+
+        boolean isServiceJava = SystemProperties.getBoolean("config.enable_java_radio", false);
+        mService = isServiceJava ? IRadioService.Stub.asInterface(
+                ServiceManager.getServiceOrThrow(Context.RADIO_SERVICE)) : null;
     }
 }
diff --git a/core/java/android/hardware/radio/RadioModule.java b/core/java/android/hardware/radio/RadioModule.java
index 8964893..c0df0f3 100644
--- a/core/java/android/hardware/radio/RadioModule.java
+++ b/core/java/android/hardware/radio/RadioModule.java
@@ -79,8 +79,14 @@
 
     public native int getProgramInformation(RadioManager.ProgramInfo[] info);
 
+    public native boolean startBackgroundScan();
+
     public native @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter);
 
+    public native boolean isAnalogForced();
+
+    public native void setAnalogForced(boolean isForced);
+
     public native boolean isAntennaConnected();
 
     public native boolean hasControl();
diff --git a/core/java/android/hardware/radio/RadioTuner.java b/core/java/android/hardware/radio/RadioTuner.java
index c8034eb..6e1232d 100644
--- a/core/java/android/hardware/radio/RadioTuner.java
+++ b/core/java/android/hardware/radio/RadioTuner.java
@@ -212,6 +212,23 @@
     public abstract int getProgramInformation(RadioManager.ProgramInfo[] info);
 
     /**
+     * Initiates a background scan to update internally cached program list.
+     *
+     * It may not be necessary to initiate the scan explicitly - the scan MAY be performed on boot.
+     *
+     * The operation is asynchronous and {@link Callback} backgroundScanComplete or onError will
+     * be called if the return value of this call was {@code true}. As result of this call
+     * programListChanged may be triggered (if the scanned list differs).
+     *
+     * @return {@code true} if the scan was properly scheduled, {@code false} if the scan feature
+     * is unavailable; ie. temporarily due to ongoing foreground playback in single-tuner device
+     * or permanently if the feature is not supported
+     * (see ModuleProperties#isBackgroundScanningSupported()).
+     * @hide FutureFeature
+     */
+    public abstract boolean startBackgroundScan();
+
+    /**
      * Get the list of discovered radio stations.
      *
      * To get the full list, set filter to null or empty string. Otherwise, client application
@@ -219,13 +236,40 @@
      *
      * @param filter vendor-specific selector for radio stations.
      * @return a list of radio stations.
-     * @throws IllegalStateException if the scan is in progress or has not been started.
+     * @throws IllegalStateException if the scan is in progress or has not been started,
+     *         startBackgroundScan() call may fix it.
      * @throws IllegalArgumentException if the filter argument is not valid.
      * @hide FutureFeature
      */
     public abstract @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter);
 
     /**
+     * Checks, if the analog playback is forced, see setAnalogForced.
+     *
+     * @throws IllegalStateException if the switch is not supported at current
+     *         configuration.
+     * @return {@code true} if analog is forced, {@code false} otherwise.
+     * @hide FutureFeature
+     */
+    public abstract boolean isAnalogForced();
+
+    /**
+     * Forces the analog playback for the supporting radio technology.
+     *
+     * User may disable digital playback for FM HD Radio or hybrid FM/DAB with
+     * this option. This is purely user choice, ie. does not reflect digital-
+     * analog handover managed from the HAL implementation side.
+     *
+     * Some radio technologies may not support this, ie. DAB.
+     *
+     * @param isForced {@code true} to force analog, {@code false} for a default behaviour.
+     * @throws IllegalStateException if the switch is not supported at current
+     *         configuration.
+     * @hide FutureFeature
+     */
+    public abstract void setAnalogForced(boolean isForced);
+
+    /**
      * Get current antenna connection state for current configuration.
      * Only valid if a configuration has been applied.
      * @return {@code true} if the antenna is connected, {@code false} otherwise.
@@ -317,6 +361,32 @@
          * with control set to {@code true}.
          */
         public void onControlChanged(boolean control) {}
+
+        /**
+         * onBackgroundScanAvailabilityChange() is called when background scan
+         * feature becomes available or not.
+         *
+         * @param isAvailable true, if the tuner turned temporarily background-
+         *                    capable, false in the other case.
+         * @hide FutureFeature
+         */
+        public void onBackgroundScanAvailabilityChange(boolean isAvailable) {}
+
+        /**
+         * Called when a background scan completes successfully.
+         *
+         * @hide FutureFeature
+         */
+        public void onBackgroundScanComplete() {}
+
+        /**
+         * Called when available program list changed.
+         *
+         * Use getProgramList() to get the actual list.
+         *
+         * @hide FutureFeature
+         */
+        public void onProgramListChanged() {}
     }
 
 }
diff --git a/core/java/android/hardware/radio/TunerAdapter.java b/core/java/android/hardware/radio/TunerAdapter.java
new file mode 100644
index 0000000..a457494
--- /dev/null
+++ b/core/java/android/hardware/radio/TunerAdapter.java
@@ -0,0 +1,233 @@
+/**
+ * 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.hardware.radio;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * Implements the RadioTuner interface by forwarding calls to radio service.
+ */
+class TunerAdapter extends RadioTuner {
+    private static final String TAG = "radio.TunerAdapter";
+
+    @NonNull private final ITuner mTuner;
+    private boolean mIsClosed = false;
+
+    TunerAdapter(ITuner tuner) {
+        if (tuner == null) {
+            throw new NullPointerException();
+        }
+        mTuner = tuner;
+    }
+
+    @Override
+    public void close() {
+        synchronized (mTuner) {
+            if (mIsClosed) {
+                Log.d(TAG, "Tuner is already closed");
+                return;
+            }
+            mIsClosed = true;
+        }
+        try {
+            mTuner.close();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception trying to close tuner", e);
+        }
+    }
+
+    @Override
+    public int setConfiguration(RadioManager.BandConfig config) {
+        try {
+            mTuner.setConfiguration(config);
+            return RadioManager.STATUS_OK;
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Can't set configuration", e);
+            return RadioManager.STATUS_BAD_VALUE;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+    }
+
+    @Override
+    public int getConfiguration(RadioManager.BandConfig[] config) {
+        if (config == null || config.length != 1) {
+            throw new IllegalArgumentException("The argument must be an array of length 1");
+        }
+        try {
+            config[0] = mTuner.getConfiguration();
+            return RadioManager.STATUS_OK;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+    }
+
+    @Override
+    public int setMute(boolean mute) {
+        try {
+            mTuner.setMuted(mute);
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't set muted", e);
+            return RadioManager.STATUS_ERROR;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+        return RadioManager.STATUS_OK;
+    }
+
+    @Override
+    public boolean getMute() {
+        try {
+            return mTuner.isMuted();
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return true;
+        }
+    }
+
+    @Override
+    public int step(int direction, boolean skipSubChannel) {
+        try {
+            mTuner.step(direction == RadioTuner.DIRECTION_DOWN, skipSubChannel);
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't step", e);
+            return RadioManager.STATUS_INVALID_OPERATION;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+        return RadioManager.STATUS_OK;
+    }
+
+    @Override
+    public int scan(int direction, boolean skipSubChannel) {
+        try {
+            mTuner.scan(direction == RadioTuner.DIRECTION_DOWN, skipSubChannel);
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't scan", e);
+            return RadioManager.STATUS_INVALID_OPERATION;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+        return RadioManager.STATUS_OK;
+    }
+
+    @Override
+    public int tune(int channel, int subChannel) {
+        try {
+            mTuner.tune(channel, subChannel);
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't tune", e);
+            return RadioManager.STATUS_INVALID_OPERATION;
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Can't tune", e);
+            return RadioManager.STATUS_BAD_VALUE;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+        return RadioManager.STATUS_OK;
+    }
+
+    @Override
+    public int cancel() {
+        try {
+            mTuner.cancel();
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't cancel", e);
+            return RadioManager.STATUS_INVALID_OPERATION;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+        return RadioManager.STATUS_OK;
+    }
+
+    @Override
+    public int getProgramInformation(RadioManager.ProgramInfo[] info) {
+        if (info == null || info.length != 1) {
+            throw new IllegalArgumentException("The argument must be an array of length 1");
+        }
+        try {
+            info[0] = mTuner.getProgramInformation();
+            return RadioManager.STATUS_OK;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+    }
+
+    @Override
+    public boolean startBackgroundScan() {
+        try {
+            return mTuner.startBackgroundScan();
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
+    }
+
+    @Override
+    public @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter) {
+        try {
+            return mTuner.getProgramList(filter);
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
+    }
+
+    @Override
+    public boolean isAnalogForced() {
+        try {
+            return mTuner.isAnalogForced();
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
+    }
+
+    @Override
+    public void setAnalogForced(boolean isForced) {
+        try {
+            mTuner.setAnalogForced(isForced);
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
+    }
+
+    @Override
+    public boolean isAntennaConnected() {
+        try {
+            return mTuner.isAntennaConnected();
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
+    }
+
+    @Override
+    public boolean hasControl() {
+        // TODO(b/36863239): forward to mTuner
+        throw new RuntimeException("Not implemented");
+    }
+}
diff --git a/core/java/android/hardware/radio/TunerCallbackAdapter.java b/core/java/android/hardware/radio/TunerCallbackAdapter.java
new file mode 100644
index 0000000..ba85017
--- /dev/null
+++ b/core/java/android/hardware/radio/TunerCallbackAdapter.java
@@ -0,0 +1,54 @@
+/**
+ * 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.hardware.radio;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.Looper;
+
+/**
+ * Implements the ITunerCallback interface by forwarding calls to RadioTuner.Callback.
+ */
+class TunerCallbackAdapter extends ITunerCallback.Stub {
+    @NonNull private final RadioTuner.Callback mCallback;
+    @NonNull private final Handler mHandler;
+
+    TunerCallbackAdapter(@NonNull RadioTuner.Callback callback, @Nullable Handler handler) {
+        mCallback = callback;
+        if (handler == null) {
+            mHandler = new Handler(Looper.getMainLooper());
+        } else {
+            mHandler = handler;
+        }
+    }
+
+    @Override
+    public void onError(int status) {
+        mHandler.post(() -> mCallback.onError(status));
+    }
+
+    @Override
+    public void onConfigurationChanged(RadioManager.BandConfig config) {
+        mHandler.post(() -> mCallback.onConfigurationChanged(config));
+    }
+
+    @Override
+    public void onProgramInfoChanged(RadioManager.ProgramInfo info) {
+        mHandler.post(() -> mCallback.onProgramInfoChanged(info));
+    }
+}
diff --git a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
index ad20ce5..160376b 100644
--- a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
+++ b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
@@ -341,7 +341,8 @@
               }
           }
         }
-        Slog.w(TAG, "No Enrollment application supports the given keyphrase/locale");
+        Slog.w(TAG, "No enrollment application supports the given keyphrase/locale: '"
+                + keyphrase + "'/" + locale);
         return null;
     }
 
diff --git a/core/java/android/hardware/usb/UsbDeviceConnection.java b/core/java/android/hardware/usb/UsbDeviceConnection.java
index 7a0272d..9b5d0d3 100644
--- a/core/java/android/hardware/usb/UsbDeviceConnection.java
+++ b/core/java/android/hardware/usb/UsbDeviceConnection.java
@@ -349,7 +349,9 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
         } finally {
             super.finalize();
         }
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 33a92fd..d73d3d8 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -316,10 +316,13 @@
      * @return HashMap containing all connected USB devices.
      */
     public HashMap<String,UsbDevice> getDeviceList() {
+        HashMap<String,UsbDevice> result = new HashMap<String,UsbDevice>();
+        if (mService == null) {
+            return result;
+        }
         Bundle bundle = new Bundle();
         try {
             mService.getDeviceList(bundle);
-            HashMap<String,UsbDevice> result = new HashMap<String,UsbDevice>();
             for (String name : bundle.keySet()) {
                 result.put(name, (UsbDevice)bundle.get(name));
             }
@@ -361,6 +364,9 @@
      * @return list of USB accessories, or null if none are attached.
      */
     public UsbAccessory[] getAccessoryList() {
+        if (mService == null) {
+            return null;
+        }
         try {
             UsbAccessory accessory = mService.getCurrentAccessory();
             if (accessory == null) {
@@ -397,6 +403,9 @@
      * @return true if caller has permission
      */
     public boolean hasPermission(UsbDevice device) {
+        if (mService == null) {
+            return false;
+        }
         try {
             return mService.hasDevicePermission(device);
         } catch (RemoteException e) {
@@ -414,6 +423,9 @@
      * @return true if caller has permission
      */
     public boolean hasPermission(UsbAccessory accessory) {
+        if (mService == null) {
+            return false;
+        }
         try {
             return mService.hasAccessoryPermission(accessory);
         } catch (RemoteException e) {
@@ -531,6 +543,9 @@
      * {@hide}
      */
     public boolean isFunctionEnabled(String function) {
+        if (mService == null) {
+            return false;
+        }
         try {
             return mService.isFunctionEnabled(function);
         } catch (RemoteException e) {
@@ -588,6 +603,9 @@
      * @hide
      */
     public UsbPort[] getPorts() {
+        if (mService == null) {
+            return null;
+        }
         try {
             return mService.getPorts();
         } catch (RemoteException e) {
@@ -636,6 +654,7 @@
         Preconditions.checkNotNull(port, "port must not be null");
         UsbPort.checkRoles(powerRole, dataRole);
 
+        Log.d(TAG, "setPortRoles Package:" + mContext.getPackageName());
         try {
             mService.setPortRoles(port.getId(), powerRole, dataRole);
         } catch (RemoteException e) {
diff --git a/core/java/android/hardware/usb/UsbPort.java b/core/java/android/hardware/usb/UsbPort.java
index fea730e..afdb202 100644
--- a/core/java/android/hardware/usb/UsbPort.java
+++ b/core/java/android/hardware/usb/UsbPort.java
@@ -65,6 +65,18 @@
     public static final int MODE_DUAL = Constants.PortMode.DRP;
 
     /**
+     * Mode bit: This USB port can support USB Type-C Audio accessory.
+     */
+    public static final int MODE_AUDIO_ACCESSORY =
+            android.hardware.usb.V1_1.Constants.PortMode_1_1.AUDIO_ACCESSORY;
+
+    /**
+     * Mode bit: This USB port can support USB Type-C debug accessory.
+     */
+    public static final int MODE_DEBUG_ACCESSORY =
+            android.hardware.usb.V1_1.Constants.PortMode_1_1.DEBUG_ACCESSORY;
+
+    /**
      * Power role: This USB port does not have a power role.
      */
     public static final int POWER_ROLE_NONE = Constants.PortPowerRole.NONE;
@@ -135,9 +147,9 @@
      * in a bit-field.
      *
      * @param powerRole The desired power role: {@link UsbPort#POWER_ROLE_SOURCE}
-     * or {@link UsbPort#POWER_ROLE_SINK}, or 0 if no power role.
-     * @param dataRole The desired data role: {@link UsbPort#DATA_ROLE_HOST}
-     * or {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if no data role.
+     *                  or {@link UsbPort#POWER_ROLE_SINK}, or 0 if no power role.
+     * @param dataRole  The desired data role: {@link UsbPort#DATA_ROLE_HOST}
+     *                  or {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if no data role.
      * @hide
      */
     public static int combineRolesAsBit(int powerRole, int dataRole) {
@@ -148,18 +160,31 @@
 
     /** @hide */
     public static String modeToString(int mode) {
-        switch (mode) {
-            case MODE_NONE:
-                return "none";
-            case MODE_DFP:
-                return "dfp";
-            case MODE_UFP:
-                return "ufp";
-            case MODE_DUAL:
-                return "dual";
-            default:
-                return Integer.toString(mode);
+        StringBuilder modeString = new StringBuilder();
+        if (mode == MODE_NONE) {
+            return "none";
         }
+
+        if ((mode & MODE_DUAL) == MODE_DUAL) {
+            modeString.append("dual, ");
+        } else {
+            if ((mode & MODE_DFP) == MODE_DFP) {
+                modeString.append("dfp, ");
+            } else if ((mode & MODE_UFP) == MODE_UFP) {
+                modeString.append("ufp, ");
+            }
+        }
+        if ((mode & MODE_AUDIO_ACCESSORY) == MODE_AUDIO_ACCESSORY) {
+            modeString.append("audio_acc, ");
+        }
+        if ((mode & MODE_DEBUG_ACCESSORY) == MODE_DEBUG_ACCESSORY) {
+            modeString.append("debug_acc, ");
+        }
+
+        if (modeString.length() == 0) {
+            return Integer.toString(mode);
+        }
+        return modeString.substring(0, modeString.length() - 2);
     }
 
     /** @hide */
@@ -240,6 +265,13 @@
         Preconditions.checkArgumentInRange(dataRole, DATA_ROLE_NONE, DATA_ROLE_DEVICE, "dataRole");
     }
 
+    /** @hide */
+    public boolean isModeSupported(int mode) {
+        if ((mSupportedModes & mode) == mode) return true;
+        return false;
+    }
+
+
     @Override
     public String toString() {
         return "UsbPort{id=" + mId + ", supportedModes=" + modeToString(mSupportedModes) + "}";
@@ -258,16 +290,16 @@
 
     public static final Parcelable.Creator<UsbPort> CREATOR =
             new Parcelable.Creator<UsbPort>() {
-        @Override
-        public UsbPort createFromParcel(Parcel in) {
-            String id = in.readString();
-            int supportedModes = in.readInt();
-            return new UsbPort(id, supportedModes);
-        }
+                @Override
+                public UsbPort createFromParcel(Parcel in) {
+                    String id = in.readString();
+                    int supportedModes = in.readInt();
+                    return new UsbPort(id, supportedModes);
+                }
 
-        @Override
-        public UsbPort[] newArray(int size) {
-            return new UsbPort[size];
-        }
-    };
+                @Override
+                public UsbPort[] newArray(int size) {
+                    return new UsbPort[size];
+                }
+            };
 }
diff --git a/core/java/android/hardware/usb/UsbRequest.java b/core/java/android/hardware/usb/UsbRequest.java
index 90990b7..2e8f8e1 100644
--- a/core/java/android/hardware/usb/UsbRequest.java
+++ b/core/java/android/hardware/usb/UsbRequest.java
@@ -118,7 +118,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index ed223d1..d2e3510 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -16,10 +16,6 @@
 
 package android.inputmethodservice;
 
-import com.android.internal.os.HandlerCaller;
-import com.android.internal.os.SomeArgs;
-import com.android.internal.view.IInputMethodSession;
-
 import android.content.Context;
 import android.graphics.Rect;
 import android.os.Bundle;
@@ -34,9 +30,13 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.CursorAnchorInfo;
 import android.view.inputmethod.ExtractedText;
 import android.view.inputmethod.InputMethodSession;
-import android.view.inputmethod.CursorAnchorInfo;
+
+import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.SomeArgs;
+import com.android.internal.view.IInputMethodSession;
 
 class IInputMethodSessionWrapper extends IInputMethodSession.Stub
         implements HandlerCaller.Callback {
@@ -218,7 +218,7 @@
         }
 
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             if (mInputMethodSession == null) {
                 // The session has been finished.
                 finishInputEvent(event, false);
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index d914823..6bf1425 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -619,6 +619,35 @@
      */
     public static final int NETID_UNSET = 0;
 
+    /**
+     * Private DNS Mode values.
+     *
+     * The "private_dns_mode" global setting stores a String value which is
+     * expected to be one of the following.
+     */
+
+    /**
+     * @hide
+     */
+    public static final String PRIVATE_DNS_MODE_OFF = "off";
+    /**
+     * @hide
+     */
+    public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic";
+    /**
+     * @hide
+     */
+    public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname";
+    /**
+     * The default Private DNS mode.
+     *
+     * This may change from release to release or may become dependent upon
+     * the capabilities of the underlying platform.
+     *
+     * @hide
+     */
+    public static final String PRIVATE_DNS_DEFAULT_MODE = PRIVATE_DNS_MODE_OPPORTUNISTIC;
+
     private final IConnectivityManager mService;
     /**
      * A kludge to facilitate static access where a Context pointer isn't available, like in the
@@ -835,6 +864,29 @@
     }
 
     /**
+     * Checks if a VPN app supports always-on mode.
+     *
+     * In order to support the always-on feature, an app has to
+     * <ul>
+     *     <li>target {@link VERSION_CODES#N API 24} or above, and
+     *     <li>not opt out through the {@link VpnService#SERVICE_META_DATA_SUPPORTS_ALWAYS_ON}
+     *         meta-data field.
+     * </ul>
+     *
+     * @param userId The identifier of the user for whom the VPN app is installed.
+     * @param vpnPackage The canonical package name of the VPN app.
+     * @return {@code true} if and only if the VPN app exists and supports always-on mode.
+     * @hide
+     */
+    public boolean isAlwaysOnVpnPackageSupportedForUser(int userId, @Nullable String vpnPackage) {
+        try {
+            return mService.isAlwaysOnVpnPackageSupported(userId, vpnPackage);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Configures an always-on VPN connection through a specific application.
      * This connection is automatically granted and persisted after a reboot.
      *
@@ -1102,6 +1154,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.LOCAL_MAC_ADDRESS)
     public String getCaptivePortalServerUrl() {
         try {
             return mService.getCaptivePortalServerUrl();
@@ -2060,15 +2113,30 @@
      * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
      * due to device configuration.
      *
+     * <p>If this app does not have permission to use this API, it will always
+     * return false rather than throw an exception.</p>
+     *
+     * <p>If the device has a hotspot provisioning app, the caller is required to hold the
+     * {@link android.Manifest.permission.TETHER_PRIVILEGED} permission.</p>
+     *
+     * <p>Otherwise, this method requires the caller to hold the ability to modify system
+     * settings as determined by {@link android.provider.Settings.System#canWrite}.</p>
+     *
      * @return a boolean - {@code true} indicating Tethering is supported.
      *
      * {@hide}
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    @RequiresPermission(anyOf = {android.Manifest.permission.TETHER_PRIVILEGED,
+            android.Manifest.permission.WRITE_SETTINGS})
     public boolean isTetheringSupported() {
+        String pkgName = mContext.getOpPackageName();
         try {
-            return mService.isTetheringSupported();
+            return mService.isTetheringSupported(pkgName);
+        } catch (SecurityException e) {
+            // This API is not available to this caller, but for backward-compatibility
+            // this will just return false instead of throwing.
+            return false;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2098,6 +2166,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
     public void startTethering(int type, boolean showProvisioningUi,
             final OnStartTetheringCallback callback) {
         startTethering(type, showProvisioningUi, callback, null);
diff --git a/core/java/android/net/ConnectivityMetricsEvent.java b/core/java/android/net/ConnectivityMetricsEvent.java
index 46bb346..394ac42 100644
--- a/core/java/android/net/ConnectivityMetricsEvent.java
+++ b/core/java/android/net/ConnectivityMetricsEvent.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+
 import com.android.internal.util.BitUtils;
 
 /**
@@ -80,7 +81,7 @@
         StringBuilder buffer = new StringBuilder("ConnectivityMetricsEvent(");
         buffer.append(String.format("%tT.%tL", timestamp, timestamp));
         if (netId != 0) {
-            buffer.append(", ").append(netId);
+            buffer.append(", ").append("netId=").append(netId);
         }
         if (ifname != null) {
             buffer.append(", ").append(ifname);
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 27729dc..a6fe738 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -75,7 +75,7 @@
 
     int getLastTetherError(String iface);
 
-    boolean isTetheringSupported();
+    boolean isTetheringSupported(String callerPkg);
 
     void startTethering(int type, in ResultReceiver receiver, boolean showProvisioningUi,
             String callerPkg);
@@ -123,6 +123,7 @@
     VpnInfo[] getAllVpnInfo();
 
     boolean updateLockdownVpn();
+    boolean isAlwaysOnVpnPackageSupported(int userId, String packageName);
     boolean setAlwaysOnVpnPackage(int userId, String packageName, boolean lockdown);
     String getAlwaysOnVpnPackage(int userId);
 
diff --git a/core/java/android/net/IIpConnectivityMetrics.aidl b/core/java/android/net/IIpConnectivityMetrics.aidl
index 6f07b31..aeaf09d 100644
--- a/core/java/android/net/IIpConnectivityMetrics.aidl
+++ b/core/java/android/net/IIpConnectivityMetrics.aidl
@@ -30,11 +30,11 @@
     int logEvent(in ConnectivityMetricsEvent event);
 
     /**
-     * At most one callback can be registered (by DevicePolicyManager).
+     * Callback can be registered by DevicePolicyManager or NetworkWatchlistService only.
      * @return status {@code true} if registering/unregistering of the callback was successful,
      *         {@code false} otherwise (might happen if IIpConnectivityMetrics is not available,
      *         if it happens make sure you call it when the service is up in the caller)
      */
-    boolean registerNetdEventCallback(in INetdEventCallback callback);
-    boolean unregisterNetdEventCallback();
+    boolean addNetdEventCallback(in int callerType, in INetdEventCallback callback);
+    boolean removeNetdEventCallback(in int callerType);
 }
diff --git a/core/java/android/net/INetdEventCallback.aidl b/core/java/android/net/INetdEventCallback.aidl
index 49436be..1fd9423 100644
--- a/core/java/android/net/INetdEventCallback.aidl
+++ b/core/java/android/net/INetdEventCallback.aidl
@@ -19,6 +19,10 @@
 /** {@hide} */
 oneway interface INetdEventCallback {
 
+    // Possible addNetdEventCallback callers.
+    const int CALLBACK_CALLER_DEVICE_POLICY = 0;
+    const int CALLBACK_CALLER_NETWORK_WATCHLIST = 1;
+
     /**
      * Reports a single DNS lookup function call.
      * This method must not block or perform long-running operations.
diff --git a/core/java/android/net/IpSecAlgorithm.java b/core/java/android/net/IpSecAlgorithm.java
index 5ae3400..d6e62cf 100644
--- a/core/java/android/net/IpSecAlgorithm.java
+++ b/core/java/android/net/IpSecAlgorithm.java
@@ -15,22 +15,25 @@
  */
 package android.net;
 
+import android.annotation.NonNull;
 import android.annotation.StringDef;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
+
 import com.android.internal.util.HexDump;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
 
 /**
- * IpSecAlgorithm specifies a single algorithm that can be applied to an IpSec Transform. Refer to
- * RFC 4301.
+ * This class represents a single algorithm that can be used by an {@link IpSecTransform}.
  *
- * @hide
+ * @see <a href="https://tools.ietf.org/html/rfc4301">RFC 4301, Security Architecture for the
+ * Internet Protocol</a>
  */
 public final class IpSecAlgorithm implements Parcelable {
-
     /**
      * AES-CBC Encryption/Ciphering Algorithm.
      *
@@ -39,16 +42,16 @@
     public static final String CRYPT_AES_CBC = "cbc(aes)";
 
     /**
-     * MD5 HMAC Authentication/Integrity Algorithm. This algorithm is not recommended for use in new
-     * applications and is provided for legacy compatibility with 3gpp infrastructure.
+     * MD5 HMAC Authentication/Integrity Algorithm. <b>This algorithm is not recommended for use in
+     * new applications and is provided for legacy compatibility with 3gpp infrastructure.</b>
      *
      * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 128.
      */
     public static final String AUTH_HMAC_MD5 = "hmac(md5)";
 
     /**
-     * SHA1 HMAC Authentication/Integrity Algorithm. This algorithm is not recommended for use in
-     * new applications and is provided for legacy compatibility with 3gpp infrastructure.
+     * SHA1 HMAC Authentication/Integrity Algorithm. <b>This algorithm is not recommended for use in
+     * new applications and is provided for legacy compatibility with 3gpp infrastructure.</b>
      *
      * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 160.
      */
@@ -67,20 +70,35 @@
      * <p>Valid truncation lengths are multiples of 8 bits from 192 to (default) 384.
      */
     public static final String AUTH_HMAC_SHA384 = "hmac(sha384)";
+
     /**
-     * SHA512 HMAC Authentication/Integrity Algorithm
+     * SHA512 HMAC Authentication/Integrity Algorithm.
      *
      * <p>Valid truncation lengths are multiples of 8 bits from 256 to (default) 512.
      */
     public static final String AUTH_HMAC_SHA512 = "hmac(sha512)";
 
+    /**
+     * AES-GCM Authentication/Integrity + Encryption/Ciphering Algorithm.
+     *
+     * <p>Valid lengths for keying material are {160, 224, 288}.
+     *
+     * <p>As per <a href="https://tools.ietf.org/html/rfc4106#section-8.1">RFC4106 (Section
+     * 8.1)</a>, keying material consists of a 128, 192, or 256 bit AES key followed by a 32-bit
+     * salt. RFC compliance requires that the salt must be unique per invocation with the same key.
+     *
+     * <p>Valid ICV (truncation) lengths are {64, 96, 128}.
+     */
+    public static final String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";
+
     /** @hide */
     @StringDef({
         CRYPT_AES_CBC,
         AUTH_HMAC_MD5,
         AUTH_HMAC_SHA1,
         AUTH_HMAC_SHA256,
-        AUTH_HMAC_SHA512
+        AUTH_HMAC_SHA512,
+        AUTH_CRYPT_AES_GCM
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface AlgorithmName {}
@@ -90,48 +108,47 @@
     private final int mTruncLenBits;
 
     /**
-     * Specify a IpSecAlgorithm of one of the supported types including the truncation length of the
-     * algorithm
+     * Creates an IpSecAlgorithm of one of the supported types. Supported algorithm names are
+     * defined as constants in this class.
      *
-     * @param algorithm type for IpSec.
-     * @param key non-null Key padded to a multiple of 8 bits.
+     * @param algorithm name of the algorithm.
+     * @param key key padded to a multiple of 8 bits.
      */
-    public IpSecAlgorithm(String algorithm, byte[] key) {
+    public IpSecAlgorithm(@AlgorithmName String algorithm, @NonNull byte[] key) {
         this(algorithm, key, key.length * 8);
     }
 
     /**
-     * Specify a IpSecAlgorithm of one of the supported types including the truncation length of the
-     * algorithm
+     * Creates an IpSecAlgorithm of one of the supported types. Supported algorithm names are
+     * defined as constants in this class.
      *
-     * @param algoName precise name of the algorithm to be used.
-     * @param key non-null Key padded to a multiple of 8 bits.
-     * @param truncLenBits the number of bits of output hash to use; only meaningful for
-     *     Authentication.
+     * <p>This constructor only supports algorithms that use a truncation length. i.e.
+     * Authentication and Authenticated Encryption algorithms.
+     *
+     * @param algorithm name of the algorithm.
+     * @param key key padded to a multiple of 8 bits.
+     * @param truncLenBits number of bits of output hash to use.
      */
-    public IpSecAlgorithm(@AlgorithmName String algoName, byte[] key, int truncLenBits) {
-        if (!isTruncationLengthValid(algoName, truncLenBits)) {
+    public IpSecAlgorithm(@AlgorithmName String algorithm, @NonNull byte[] key, int truncLenBits) {
+        if (!isTruncationLengthValid(algorithm, truncLenBits)) {
             throw new IllegalArgumentException("Unknown algorithm or invalid length");
         }
-        mName = algoName;
+        mName = algorithm;
         mKey = key.clone();
         mTruncLenBits = Math.min(truncLenBits, key.length * 8);
     }
 
-    /** Retrieve the algorithm name */
+    /** Get the algorithm name */
     public String getName() {
         return mName;
     }
 
-    /** Retrieve the key for this algorithm */
+    /** Get the key for this algorithm */
     public byte[] getKey() {
         return mKey.clone();
     }
 
-    /**
-     * Retrieve the truncation length, in bits, for the key in this algo. By default this will be
-     * the length in bits of the key.
-     */
+    /** Get the truncation length of this algorithm, in bits */
     public int getTruncationLengthBits() {
         return mTruncLenBits;
     }
@@ -180,6 +197,8 @@
                 return (truncLenBits >= 192 && truncLenBits <= 384);
             case AUTH_HMAC_SHA512:
                 return (truncLenBits >= 256 && truncLenBits <= 512);
+            case AUTH_CRYPT_AES_GCM:
+                return (truncLenBits == 64 || truncLenBits == 96 || truncLenBits == 128);
             default:
                 return false;
         }
@@ -197,4 +216,12 @@
                 .append("}")
                 .toString();
     }
+
+    /** package */
+    static boolean equals(IpSecAlgorithm lhs, IpSecAlgorithm rhs) {
+        if (lhs == null || rhs == null) return (lhs == rhs);
+        return (lhs.mName.equals(rhs.mName)
+                && Arrays.equals(lhs.mKey, rhs.mKey)
+                && lhs.mTruncLenBits == rhs.mTruncLenBits);
+    }
 };
diff --git a/core/java/android/net/IpSecConfig.java b/core/java/android/net/IpSecConfig.java
index 5a5c740..e6cd3fc 100644
--- a/core/java/android/net/IpSecConfig.java
+++ b/core/java/android/net/IpSecConfig.java
@@ -17,105 +17,192 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.util.Log;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
 
-/** @hide */
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * This class encapsulates all the configuration parameters needed to create IPsec transforms and
+ * policies.
+ *
+ * @hide
+ */
 public final class IpSecConfig implements Parcelable {
     private static final String TAG = "IpSecConfig";
 
-    //MODE_TRANSPORT or MODE_TUNNEL
-    int mode;
+    // MODE_TRANSPORT or MODE_TUNNEL
+    private int mMode = IpSecTransform.MODE_TRANSPORT;
 
-    // For tunnel mode
-    InetAddress localAddress;
+    // Needs to be valid only for tunnel mode
+    // Preventing this from being null simplifies Java->Native binder
+    private String mLocalAddress = "";
 
-    InetAddress remoteAddress;
+    // Preventing this from being null simplifies Java->Native binder
+    private String mRemoteAddress = "";
 
-    // Limit selection by network interface
-    Network network;
+    // The underlying Network that represents the "gateway" Network
+    // for outbound packets. It may also be used to select packets.
+    private Network mNetwork;
 
+    /**
+     * This class captures the parameters that specifically apply to inbound or outbound traffic.
+     */
     public static class Flow {
         // Minimum requirements for identifying a transform
         // SPI identifying the IPsec flow in packet processing
         // and a remote IP address
-        int spiResourceId;
+        private int mSpiResourceId = IpSecManager.INVALID_RESOURCE_ID;
 
         // Encryption Algorithm
-        IpSecAlgorithm encryption;
+        private IpSecAlgorithm mEncryption;
 
         // Authentication Algorithm
-        IpSecAlgorithm authentication;
+        private IpSecAlgorithm mAuthentication;
+
+        // Authenticated Encryption Algorithm
+        private IpSecAlgorithm mAuthenticatedEncryption;
 
         @Override
         public String toString() {
             return new StringBuilder()
-                    .append("{spiResourceId=")
-                    .append(spiResourceId)
-                    .append(", encryption=")
-                    .append(encryption)
-                    .append(", authentication=")
-                    .append(authentication)
+                    .append("{mSpiResourceId=")
+                    .append(mSpiResourceId)
+                    .append(", mEncryption=")
+                    .append(mEncryption)
+                    .append(", mAuthentication=")
+                    .append(mAuthentication)
+                    .append(", mAuthenticatedEncryption=")
+                    .append(mAuthenticatedEncryption)
                     .append("}")
                     .toString();
         }
+
+        static boolean equals(IpSecConfig.Flow lhs, IpSecConfig.Flow rhs) {
+            if (lhs == null || rhs == null) return (lhs == rhs);
+            return (lhs.mSpiResourceId == rhs.mSpiResourceId
+                    && IpSecAlgorithm.equals(lhs.mEncryption, rhs.mEncryption)
+                    && IpSecAlgorithm.equals(lhs.mAuthentication, rhs.mAuthentication));
+        }
     }
 
-    final Flow[] flow = new Flow[] {new Flow(), new Flow()};
+    private final Flow[] mFlow = new Flow[] {new Flow(), new Flow()};
 
     // For tunnel mode IPv4 UDP Encapsulation
     // IpSecTransform#ENCAP_ESP_*, such as ENCAP_ESP_OVER_UDP_IKE
-    int encapType;
-    int encapLocalPortResourceId;
-    int encapRemotePort;
+    private int mEncapType = IpSecTransform.ENCAP_NONE;
+    private int mEncapSocketResourceId = IpSecManager.INVALID_RESOURCE_ID;
+    private int mEncapRemotePort;
 
     // An interval, in seconds between the NattKeepalive packets
-    int nattKeepaliveInterval;
+    private int mNattKeepaliveInterval;
+
+    /** Set the mode for this IPsec transform */
+    public void setMode(int mode) {
+        mMode = mode;
+    }
+
+    /** Set the local IP address for Tunnel mode */
+    public void setLocalAddress(String localAddress) {
+        if (localAddress == null) {
+            throw new IllegalArgumentException("localAddress may not be null!");
+        }
+        mLocalAddress = localAddress;
+    }
+
+    /** Set the remote IP address for this IPsec transform */
+    public void setRemoteAddress(String remoteAddress) {
+        if (remoteAddress == null) {
+            throw new IllegalArgumentException("remoteAddress may not be null!");
+        }
+        mRemoteAddress = remoteAddress;
+    }
+
+    /** Set the SPI for a given direction by resource ID */
+    public void setSpiResourceId(int direction, int resourceId) {
+        mFlow[direction].mSpiResourceId = resourceId;
+    }
+
+    /** Set the encryption algorithm for a given direction */
+    public void setEncryption(int direction, IpSecAlgorithm encryption) {
+        mFlow[direction].mEncryption = encryption;
+    }
+
+    /** Set the authentication algorithm for a given direction */
+    public void setAuthentication(int direction, IpSecAlgorithm authentication) {
+        mFlow[direction].mAuthentication = authentication;
+    }
+
+    /** Set the authenticated encryption algorithm for a given direction */
+    public void setAuthenticatedEncryption(int direction, IpSecAlgorithm authenticatedEncryption) {
+        mFlow[direction].mAuthenticatedEncryption = authenticatedEncryption;
+    }
+
+    public void setNetwork(Network network) {
+        mNetwork = network;
+    }
+
+    public void setEncapType(int encapType) {
+        mEncapType = encapType;
+    }
+
+    public void setEncapSocketResourceId(int resourceId) {
+        mEncapSocketResourceId = resourceId;
+    }
+
+    public void setEncapRemotePort(int port) {
+        mEncapRemotePort = port;
+    }
+
+    public void setNattKeepaliveInterval(int interval) {
+        mNattKeepaliveInterval = interval;
+    }
 
     // Transport or Tunnel
     public int getMode() {
-        return mode;
+        return mMode;
     }
 
-    public InetAddress getLocalAddress() {
-        return localAddress;
+    public String getLocalAddress() {
+        return mLocalAddress;
     }
 
     public int getSpiResourceId(int direction) {
-        return flow[direction].spiResourceId;
+        return mFlow[direction].mSpiResourceId;
     }
 
-    public InetAddress getRemoteAddress() {
-        return remoteAddress;
+    public String getRemoteAddress() {
+        return mRemoteAddress;
     }
 
     public IpSecAlgorithm getEncryption(int direction) {
-        return flow[direction].encryption;
+        return mFlow[direction].mEncryption;
     }
 
     public IpSecAlgorithm getAuthentication(int direction) {
-        return flow[direction].authentication;
+        return mFlow[direction].mAuthentication;
+    }
+
+    public IpSecAlgorithm getAuthenticatedEncryption(int direction) {
+        return mFlow[direction].mAuthenticatedEncryption;
     }
 
     public Network getNetwork() {
-        return network;
+        return mNetwork;
     }
 
     public int getEncapType() {
-        return encapType;
+        return mEncapType;
     }
 
-    public int getEncapLocalResourceId() {
-        return encapLocalPortResourceId;
+    public int getEncapSocketResourceId() {
+        return mEncapSocketResourceId;
     }
 
     public int getEncapRemotePort() {
-        return encapRemotePort;
+        return mEncapRemotePort;
     }
 
     public int getNattKeepaliveInterval() {
-        return nattKeepaliveInterval;
+        return mNattKeepaliveInterval;
     }
 
     // Parcelable Methods
@@ -127,82 +214,76 @@
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        // TODO: Use a byte array or other better method for storing IPs that can also include scope
-        out.writeString((localAddress != null) ? localAddress.getHostAddress() : null);
-        // TODO: Use a byte array or other better method for storing IPs that can also include scope
-        out.writeString((remoteAddress != null) ? remoteAddress.getHostAddress() : null);
-        out.writeParcelable(network, flags);
-        out.writeInt(flow[IpSecTransform.DIRECTION_IN].spiResourceId);
-        out.writeParcelable(flow[IpSecTransform.DIRECTION_IN].encryption, flags);
-        out.writeParcelable(flow[IpSecTransform.DIRECTION_IN].authentication, flags);
-        out.writeInt(flow[IpSecTransform.DIRECTION_OUT].spiResourceId);
-        out.writeParcelable(flow[IpSecTransform.DIRECTION_OUT].encryption, flags);
-        out.writeParcelable(flow[IpSecTransform.DIRECTION_OUT].authentication, flags);
-        out.writeInt(encapType);
-        out.writeInt(encapLocalPortResourceId);
-        out.writeInt(encapRemotePort);
+        out.writeInt(mMode);
+        out.writeString(mLocalAddress);
+        out.writeString(mRemoteAddress);
+        out.writeParcelable(mNetwork, flags);
+        out.writeInt(mFlow[IpSecTransform.DIRECTION_IN].mSpiResourceId);
+        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mEncryption, flags);
+        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mAuthentication, flags);
+        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mAuthenticatedEncryption, flags);
+        out.writeInt(mFlow[IpSecTransform.DIRECTION_OUT].mSpiResourceId);
+        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mEncryption, flags);
+        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication, flags);
+        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mAuthenticatedEncryption, flags);
+        out.writeInt(mEncapType);
+        out.writeInt(mEncapSocketResourceId);
+        out.writeInt(mEncapRemotePort);
+        out.writeInt(mNattKeepaliveInterval);
     }
 
-    // Package Private: Used by the IpSecTransform.Builder;
-    // there should be no public constructor for this object
-    IpSecConfig() {}
-
-    private static InetAddress readInetAddressFromParcel(Parcel in) {
-        String addrString = in.readString();
-        if (addrString == null) {
-            return null;
-        }
-        try {
-            return InetAddress.getByName(addrString);
-        } catch (UnknownHostException e) {
-            Log.wtf(TAG, "Invalid IpAddress " + addrString);
-            return null;
-        }
-    }
+    @VisibleForTesting
+    public IpSecConfig() {}
 
     private IpSecConfig(Parcel in) {
-        localAddress = readInetAddressFromParcel(in);
-        remoteAddress = readInetAddressFromParcel(in);
-        network = (Network) in.readParcelable(Network.class.getClassLoader());
-        flow[IpSecTransform.DIRECTION_IN].spiResourceId = in.readInt();
-        flow[IpSecTransform.DIRECTION_IN].encryption =
+        mMode = in.readInt();
+        mLocalAddress = in.readString();
+        mRemoteAddress = in.readString();
+        mNetwork = (Network) in.readParcelable(Network.class.getClassLoader());
+        mFlow[IpSecTransform.DIRECTION_IN].mSpiResourceId = in.readInt();
+        mFlow[IpSecTransform.DIRECTION_IN].mEncryption =
                 (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
-        flow[IpSecTransform.DIRECTION_IN].authentication =
+        mFlow[IpSecTransform.DIRECTION_IN].mAuthentication =
                 (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
-        flow[IpSecTransform.DIRECTION_OUT].spiResourceId = in.readInt();
-        flow[IpSecTransform.DIRECTION_OUT].encryption =
+        mFlow[IpSecTransform.DIRECTION_IN].mAuthenticatedEncryption =
                 (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
-        flow[IpSecTransform.DIRECTION_OUT].authentication =
+        mFlow[IpSecTransform.DIRECTION_OUT].mSpiResourceId = in.readInt();
+        mFlow[IpSecTransform.DIRECTION_OUT].mEncryption =
                 (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
-        encapType = in.readInt();
-        encapLocalPortResourceId = in.readInt();
-        encapRemotePort = in.readInt();
+        mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication =
+                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
+        mFlow[IpSecTransform.DIRECTION_OUT].mAuthenticatedEncryption =
+                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
+        mEncapType = in.readInt();
+        mEncapSocketResourceId = in.readInt();
+        mEncapRemotePort = in.readInt();
+        mNattKeepaliveInterval = in.readInt();
     }
 
     @Override
     public String toString() {
         StringBuilder strBuilder = new StringBuilder();
         strBuilder
-                .append("{mode=")
-                .append(mode == IpSecTransform.MODE_TUNNEL ? "TUNNEL" : "TRANSPORT")
-                .append(", localAddress=")
-                .append(localAddress)
-                .append(", remoteAddress=")
-                .append(remoteAddress)
-                .append(", network=")
-                .append(network)
-                .append(", encapType=")
-                .append(encapType)
-                .append(", encapLocalPortResourceId=")
-                .append(encapLocalPortResourceId)
-                .append(", encapRemotePort=")
-                .append(encapRemotePort)
-                .append(", nattKeepaliveInterval=")
-                .append(nattKeepaliveInterval)
-                .append(", flow[OUT]=")
-                .append(flow[IpSecTransform.DIRECTION_OUT])
-                .append(", flow[IN]=")
-                .append(flow[IpSecTransform.DIRECTION_IN])
+                .append("{mMode=")
+                .append(mMode == IpSecTransform.MODE_TUNNEL ? "TUNNEL" : "TRANSPORT")
+                .append(", mLocalAddress=")
+                .append(mLocalAddress)
+                .append(", mRemoteAddress=")
+                .append(mRemoteAddress)
+                .append(", mNetwork=")
+                .append(mNetwork)
+                .append(", mEncapType=")
+                .append(mEncapType)
+                .append(", mEncapSocketResourceId=")
+                .append(mEncapSocketResourceId)
+                .append(", mEncapRemotePort=")
+                .append(mEncapRemotePort)
+                .append(", mNattKeepaliveInterval=")
+                .append(mNattKeepaliveInterval)
+                .append(", mFlow[OUT]=")
+                .append(mFlow[IpSecTransform.DIRECTION_OUT])
+                .append(", mFlow[IN]=")
+                .append(mFlow[IpSecTransform.DIRECTION_IN])
                 .append("}");
 
         return strBuilder.toString();
@@ -218,4 +299,23 @@
                     return new IpSecConfig[size];
                 }
             };
+
+    @VisibleForTesting
+    /** Equals method used for testing */
+    public static boolean equals(IpSecConfig lhs, IpSecConfig rhs) {
+        if (lhs == null || rhs == null) return (lhs == rhs);
+        return (lhs.mMode == rhs.mMode
+                && lhs.mLocalAddress.equals(rhs.mLocalAddress)
+                && lhs.mRemoteAddress.equals(rhs.mRemoteAddress)
+                && ((lhs.mNetwork != null && lhs.mNetwork.equals(rhs.mNetwork))
+                        || (lhs.mNetwork == rhs.mNetwork))
+                && lhs.mEncapType == rhs.mEncapType
+                && lhs.mEncapSocketResourceId == rhs.mEncapSocketResourceId
+                && lhs.mEncapRemotePort == rhs.mEncapRemotePort
+                && lhs.mNattKeepaliveInterval == rhs.mNattKeepaliveInterval
+                && IpSecConfig.Flow.equals(lhs.mFlow[IpSecTransform.DIRECTION_OUT],
+                        rhs.mFlow[IpSecTransform.DIRECTION_OUT])
+                && IpSecConfig.Flow.equals(lhs.mFlow[IpSecTransform.DIRECTION_IN],
+                        rhs.mFlow[IpSecTransform.DIRECTION_IN]));
+    }
 }
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
index 2f791e1..a9e60ec 100644
--- a/core/java/android/net/IpSecManager.java
+++ b/core/java/android/net/IpSecManager.java
@@ -19,13 +19,18 @@
 
 import android.annotation.NonNull;
 import android.annotation.SystemService;
+import android.annotation.TestApi;
 import android.content.Context;
 import android.os.Binder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.util.AndroidException;
 import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
 import dalvik.system.CloseGuard;
+
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.net.DatagramSocket;
@@ -33,20 +38,28 @@
 import java.net.Socket;
 
 /**
- * This class contains methods for managing IPsec sessions, which will perform kernel-space
- * encryption and decryption of socket or Network traffic.
+ * This class contains methods for managing IPsec sessions. Once configured, the kernel will apply
+ * confidentiality (encryption) and integrity (authentication) to IP traffic.
  *
- * @hide
+ * <p>Note that not all aspects of IPsec are permitted by this API. Applications may create
+ * transport mode security associations and apply them to individual sockets. Applications looking
+ * to create a VPN should use {@link VpnService}.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc4301">RFC 4301, Security Architecture for the
+ * Internet Protocol</a>
  */
 @SystemService(Context.IPSEC_SERVICE)
 public final class IpSecManager {
     private static final String TAG = "IpSecManager";
 
     /**
-     * The Security Parameter Index, SPI, 0 indicates an unknown or invalid index.
+     * The Security Parameter Index (SPI) 0 indicates an unknown or invalid index.
      *
      * <p>No IPsec packet may contain an SPI of 0.
+     *
+     * @hide
      */
+    @TestApi
     public static final int INVALID_SECURITY_PARAMETER_INDEX = 0;
 
     /** @hide */
@@ -60,10 +73,12 @@
     public static final int INVALID_RESOURCE_ID = 0;
 
     /**
-     * Indicates that the combination of remote InetAddress and SPI was non-unique for a given
-     * request. If encountered, selection of a new SPI is required before a transform may be
-     * created. Note, this should happen very rarely if the SPI is chosen to be sufficiently random
-     * or reserved using reserveSecurityParameterIndex.
+     * Thrown to indicate that a requested SPI is in use.
+     *
+     * <p>The combination of remote {@code InetAddress} and SPI must be unique across all apps on
+     * one device. If this error is encountered, a new SPI is required before a transform may be
+     * created. This error can be avoided by calling {@link
+     * IpSecManager#reserveSecurityParameterIndex}.
      */
     public static final class SpiUnavailableException extends AndroidException {
         private final int mSpi;
@@ -72,24 +87,26 @@
          * Construct an exception indicating that a transform with the given SPI is already in use
          * or otherwise unavailable.
          *
-         * @param msg Description indicating the colliding SPI
+         * @param msg description indicating the colliding SPI
          * @param spi the SPI that could not be used due to a collision
          */
         SpiUnavailableException(String msg, int spi) {
-            super(msg + "(spi: " + spi + ")");
+            super(msg + " (spi: " + spi + ")");
             mSpi = spi;
         }
 
-        /** Retrieve the SPI that caused a collision */
+        /** Get the SPI that caused a collision. */
         public int getSpi() {
             return mSpi;
         }
     }
 
     /**
-     * Indicates that the requested system resource for IPsec, such as a socket or other system
-     * resource is unavailable. If this exception is thrown, try releasing allocated objects of the
-     * type requested.
+     * Thrown to indicate that an IPsec resource is unavailable.
+     *
+     * <p>This could apply to resources such as sockets, {@link SecurityParameterIndex}, {@link
+     * IpSecTransform}, or other system resources. If this exception is thrown, users should release
+     * allocated objects of the type requested.
      */
     public static final class ResourceUnavailableException extends AndroidException {
 
@@ -100,6 +117,13 @@
 
     private final IIpSecService mService;
 
+    /**
+     * This class represents a reserved SPI.
+     *
+     * <p>Objects of this type are used to track reserved security parameter indices. They can be
+     * obtained by calling {@link IpSecManager#reserveSecurityParameterIndex} and must be released
+     * by calling {@link #close()} when they are no longer needed.
+     */
     public static final class SecurityParameterIndex implements AutoCloseable {
         private final IIpSecService mService;
         private final InetAddress mRemoteAddress;
@@ -107,7 +131,7 @@
         private int mSpi = INVALID_SECURITY_PARAMETER_INDEX;
         private int mResourceId;
 
-        /** Return the underlying SPI held by this object */
+        /** Get the underlying SPI held by this object. */
         public int getSpi() {
             return mSpi;
         }
@@ -129,8 +153,9 @@
             mCloseGuard.close();
         }
 
+        /** Check that the SPI was closed properly. */
         @Override
-        protected void finalize() {
+        protected void finalize() throws Throwable {
             if (mCloseGuard != null) {
                 mCloseGuard.warnIfOpen();
             }
@@ -184,19 +209,20 @@
         }
 
         /** @hide */
-        int getResourceId() {
+        @VisibleForTesting
+        public int getResourceId() {
             return mResourceId;
         }
     }
 
     /**
-     * Reserve an SPI for traffic bound towards the specified remote address.
+     * Reserve a random SPI for traffic bound to or from the specified remote address.
      *
      * <p>If successful, this SPI is guaranteed available until released by a call to {@link
      * SecurityParameterIndex#close()}.
      *
      * @param direction {@link IpSecTransform#DIRECTION_IN} or {@link IpSecTransform#DIRECTION_OUT}
-     * @param remoteAddress address of the remote. SPIs must be unique for each remoteAddress.
+     * @param remoteAddress address of the remote. SPIs must be unique for each remoteAddress
      * @return the reserved SecurityParameterIndex
      * @throws ResourceUnavailableException indicating that too many SPIs are currently allocated
      *     for this user
@@ -216,17 +242,18 @@
     }
 
     /**
-     * Reserve an SPI for traffic bound towards the specified remote address.
+     * Reserve the requested SPI for traffic bound to or from the specified remote address.
      *
      * <p>If successful, this SPI is guaranteed available until released by a call to {@link
      * SecurityParameterIndex#close()}.
      *
      * @param direction {@link IpSecTransform#DIRECTION_IN} or {@link IpSecTransform#DIRECTION_OUT}
-     * @param remoteAddress address of the remote. SPIs must be unique for each remoteAddress.
-     * @param requestedSpi the requested SPI, or '0' to allocate a random SPI.
+     * @param remoteAddress address of the remote. SPIs must be unique for each remoteAddress
+     * @param requestedSpi the requested SPI, or '0' to allocate a random SPI
      * @return the reserved SecurityParameterIndex
      * @throws ResourceUnavailableException indicating that too many SPIs are currently allocated
      *     for this user
+     * @throws SpiUnavailableException indicating that the requested SPI could not be reserved
      */
     public SecurityParameterIndex reserveSecurityParameterIndex(
             int direction, InetAddress remoteAddress, int requestedSpi)
@@ -238,16 +265,28 @@
     }
 
     /**
-     * Apply an active Transport Mode IPsec Transform to a stream socket to perform IPsec
-     * encapsulation of the traffic flowing between the socket and the remote InetAddress of that
-     * transform. For security reasons, attempts to send traffic to any IP address other than the
-     * address associated with that transform will throw an IOException. In addition, if the
-     * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to
-     * send() or receive() until the transform is removed from the socket by calling {@link
-     * #removeTransportModeTransform(Socket, IpSecTransform)};
+     * Apply an IPsec transform to a stream socket.
+     *
+     * <p>This applies transport mode encapsulation to the given socket. Once applied, I/O on the
+     * socket will be encapsulated according to the parameters of the {@code IpSecTransform}. When
+     * the transform is removed from the socket by calling {@link #removeTransportModeTransform},
+     * unprotected traffic can resume on that socket.
+     *
+     * <p>For security reasons, the destination address of any traffic on the socket must match the
+     * remote {@code  InetAddress} of the {@code IpSecTransform}. Attempts to send traffic to any
+     * other IP address will result in an IOException. In addition, reads and writes on the socket
+     * will throw IOException if the user deactivates the transform (by calling {@link
+     * IpSecTransform#close()}) without calling {@link #removeTransportModeTransform}.
+     *
+     * <h4>Rekey Procedure</h4> <p>When applying a new tranform to a socket, the previous transform
+     * will be removed. However, inbound traffic on the old transform will continue to be decrypted
+     * until that transform is deallocated by calling {@link IpSecTransform#close()}. This overlap
+     * allows rekey procedures where both transforms are valid until both endpoints are using the
+     * new transform and all in-flight packets have been received.
      *
      * @param socket a stream socket
-     * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform.
+     * @param transform a transport mode {@code IpSecTransform}
+     * @throws IOException indicating that the transform could not be applied
      * @hide
      */
     public void applyTransportModeTransform(Socket socket, IpSecTransform transform)
@@ -258,16 +297,28 @@
     }
 
     /**
-     * Apply an active Transport Mode IPsec Transform to a datagram socket to perform IPsec
-     * encapsulation of the traffic flowing between the socket and the remote InetAddress of that
-     * transform. For security reasons, attempts to send traffic to any IP address other than the
-     * address associated with that transform will throw an IOException. In addition, if the
-     * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to
-     * send() or receive() until the transform is removed from the socket by calling {@link
-     * #removeTransportModeTransform(DatagramSocket, IpSecTransform)};
+     * Apply an IPsec transform to a datagram socket.
+     *
+     * <p>This applies transport mode encapsulation to the given socket. Once applied, I/O on the
+     * socket will be encapsulated according to the parameters of the {@code IpSecTransform}. When
+     * the transform is removed from the socket by calling {@link #removeTransportModeTransform},
+     * unprotected traffic can resume on that socket.
+     *
+     * <p>For security reasons, the destination address of any traffic on the socket must match the
+     * remote {@code InetAddress} of the {@code IpSecTransform}. Attempts to send traffic to any
+     * other IP address will result in an IOException. In addition, reads and writes on the socket
+     * will throw IOException if the user deactivates the transform (by calling {@link
+     * IpSecTransform#close()}) without calling {@link #removeTransportModeTransform}.
+     *
+     * <h4>Rekey Procedure</h4> <p>When applying a new tranform to a socket, the previous transform
+     * will be removed. However, inbound traffic on the old transform will continue to be decrypted
+     * until that transform is deallocated by calling {@link IpSecTransform#close()}. This overlap
+     * allows rekey procedures where both transforms are valid until both endpoints are using the
+     * new transform and all in-flight packets have been received.
      *
      * @param socket a datagram socket
-     * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform.
+     * @param transform a transport mode {@code IpSecTransform}
+     * @throws IOException indicating that the transform could not be applied
      * @hide
      */
     public void applyTransportModeTransform(DatagramSocket socket, IpSecTransform transform)
@@ -278,16 +329,28 @@
     }
 
     /**
-     * Apply an active Transport Mode IPsec Transform to a stream socket to perform IPsec
-     * encapsulation of the traffic flowing between the socket and the remote InetAddress of that
-     * transform. For security reasons, attempts to send traffic to any IP address other than the
-     * address associated with that transform will throw an IOException. In addition, if the
-     * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to
-     * send() or receive() until the transform is removed from the socket by calling {@link
-     * #removeTransportModeTransform(FileDescriptor, IpSecTransform)};
+     * Apply an IPsec transform to a socket.
+     *
+     * <p>This applies transport mode encapsulation to the given socket. Once applied, I/O on the
+     * socket will be encapsulated according to the parameters of the {@code IpSecTransform}. When
+     * the transform is removed from the socket by calling {@link #removeTransportModeTransform},
+     * unprotected traffic can resume on that socket.
+     *
+     * <p>For security reasons, the destination address of any traffic on the socket must match the
+     * remote {@code InetAddress} of the {@code IpSecTransform}. Attempts to send traffic to any
+     * other IP address will result in an IOException. In addition, reads and writes on the socket
+     * will throw IOException if the user deactivates the transform (by calling {@link
+     * IpSecTransform#close()}) without calling {@link #removeTransportModeTransform}.
+     *
+     * <h4>Rekey Procedure</h4> <p>When applying a new tranform to a socket, the previous transform
+     * will be removed. However, inbound traffic on the old transform will continue to be decrypted
+     * until that transform is deallocated by calling {@link IpSecTransform#close()}. This overlap
+     * allows rekey procedures where both transforms are valid until both endpoints are using the
+     * new transform and all in-flight packets have been received.
      *
      * @param socket a socket file descriptor
-     * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform.
+     * @param transform a transport mode {@code IpSecTransform}
+     * @throws IOException indicating that the transform could not be applied
      */
     public void applyTransportModeTransform(FileDescriptor socket, IpSecTransform transform)
             throws IOException {
@@ -316,6 +379,7 @@
      * Applications should probably not use this API directly. Instead, they should use {@link
      * VpnService} to provide VPN capability in a more generic fashion.
      *
+     * TODO: Update javadoc for tunnel mode APIs at the same time the APIs are re-worked.
      * @param net a {@link Network} that will be tunneled via IP Sec.
      * @param transform an {@link IpSecTransform}, which must be an active Tunnel Mode transform.
      * @hide
@@ -323,14 +387,19 @@
     public void applyTunnelModeTransform(Network net, IpSecTransform transform) {}
 
     /**
-     * Remove a transform from a given stream socket. Once removed, traffic on the socket will not
-     * be encypted. This allows sockets that have been used for IPsec to be reclaimed for
-     * communication in the clear in the event socket reuse is desired. This operation will succeed
-     * regardless of the underlying state of a transform. If a transform is removed, communication
-     * on all sockets to which that transform was applied will fail until this method is called.
+     * Remove an IPsec transform from a stream socket.
      *
-     * @param socket a socket that previously had a transform applied to it.
+     * <p>Once removed, traffic on the socket will not be encrypted. This operation will succeed
+     * regardless of the state of the transform. Removing a transform from a socket allows the
+     * socket to be reused for communication in the clear.
+     *
+     * <p>If an {@code IpSecTransform} object applied to this socket was deallocated by calling
+     * {@link IpSecTransform#close()}, then communication on the socket will fail until this method
+     * is called.
+     *
+     * @param socket a socket that previously had a transform applied to it
      * @param transform the IPsec Transform that was previously applied to the given socket
+     * @throws IOException indicating that the transform could not be removed from the socket
      * @hide
      */
     public void removeTransportModeTransform(Socket socket, IpSecTransform transform)
@@ -341,14 +410,19 @@
     }
 
     /**
-     * Remove a transform from a given datagram socket. Once removed, traffic on the socket will not
-     * be encypted. This allows sockets that have been used for IPsec to be reclaimed for
-     * communication in the clear in the event socket reuse is desired. This operation will succeed
-     * regardless of the underlying state of a transform. If a transform is removed, communication
-     * on all sockets to which that transform was applied will fail until this method is called.
+     * Remove an IPsec transform from a datagram socket.
      *
-     * @param socket a socket that previously had a transform applied to it.
+     * <p>Once removed, traffic on the socket will not be encrypted. This operation will succeed
+     * regardless of the state of the transform. Removing a transform from a socket allows the
+     * socket to be reused for communication in the clear.
+     *
+     * <p>If an {@code IpSecTransform} object applied to this socket was deallocated by calling
+     * {@link IpSecTransform#close()}, then communication on the socket will fail until this method
+     * is called.
+     *
+     * @param socket a socket that previously had a transform applied to it
      * @param transform the IPsec Transform that was previously applied to the given socket
+     * @throws IOException indicating that the transform could not be removed from the socket
      * @hide
      */
     public void removeTransportModeTransform(DatagramSocket socket, IpSecTransform transform)
@@ -359,14 +433,19 @@
     }
 
     /**
-     * Remove a transform from a given stream socket. Once removed, traffic on the socket will not
-     * be encypted. This allows sockets that have been used for IPsec to be reclaimed for
-     * communication in the clear in the event socket reuse is desired. This operation will succeed
-     * regardless of the underlying state of a transform. If a transform is removed, communication
-     * on all sockets to which that transform was applied will fail until this method is called.
+     * Remove an IPsec transform from a socket.
      *
-     * @param socket a socket file descriptor that previously had a transform applied to it.
+     * <p>Once removed, traffic on the socket will not be encrypted. This operation will succeed
+     * regardless of the state of the transform. Removing a transform from a socket allows the
+     * socket to be reused for communication in the clear.
+     *
+     * <p>If an {@code IpSecTransform} object applied to this socket was deallocated by calling
+     * {@link IpSecTransform#close()}, then communication on the socket will fail until this method
+     * is called.
+     *
+     * @param socket a socket that previously had a transform applied to it
      * @param transform the IPsec Transform that was previously applied to the given socket
+     * @throws IOException indicating that the transform could not be removed from the socket
      */
     public void removeTransportModeTransform(FileDescriptor socket, IpSecTransform transform)
             throws IOException {
@@ -375,7 +454,7 @@
         }
     }
 
-    /* Call down to activate a transform */
+    /* Call down to remove a transform */
     private void removeTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) {
         try {
             mService.removeTransportModeTransform(pfd, transform.getResourceId());
@@ -390,6 +469,7 @@
      * all traffic that cannot be routed to the Tunnel's outbound interface. If that interface is
      * lost, all traffic will drop.
      *
+     * TODO: Update javadoc for tunnel mode APIs at the same time the APIs are re-worked.
      * @param net a network that currently has transform applied to it.
      * @param transform a Tunnel Mode IPsec Transform that has been previously applied to the given
      *     network
@@ -398,11 +478,18 @@
     public void removeTunnelModeTransform(Network net, IpSecTransform transform) {}
 
     /**
-     * Class providing access to a system-provided UDP Encapsulation Socket, which may be used for
-     * IKE signalling as well as for inbound and outbound UDP encapsulated IPsec traffic.
+     * This class provides access to a UDP encapsulation Socket.
      *
-     * <p>The socket provided by this class cannot be re-bound or closed via the inner
-     * FileDescriptor. Instead, disposing of this socket requires a call to close().
+     * <p>{@code UdpEncapsulationSocket} wraps a system-provided datagram socket intended for IKEv2
+     * signalling and UDP encapsulated IPsec traffic. Instances can be obtained by calling {@link
+     * IpSecManager#openUdpEncapsulationSocket}. The provided socket cannot be re-bound by the
+     * caller. The caller should not close the {@code FileDescriptor} returned by {@link
+     * #getSocket}, but should use {@link #close} instead.
+     *
+     * <p>Allowing the user to close or unbind a UDP encapsulation socket could impact the traffic
+     * of the next user who binds to that port. To prevent this scenario, these sockets are held
+     * open by the system so that they may only be closed by calling {@link #close} or when the user
+     * process exits.
      */
     public static final class UdpEncapsulationSocket implements AutoCloseable {
         private final ParcelFileDescriptor mPfd;
@@ -436,7 +523,7 @@
             mCloseGuard.open("constructor");
         }
 
-        /** Access the inner UDP Encapsulation Socket */
+        /** Get the wrapped socket. */
         public FileDescriptor getSocket() {
             if (mPfd == null) {
                 return null;
@@ -444,22 +531,19 @@
             return mPfd.getFileDescriptor();
         }
 
-        /** Retrieve the port number of the inner encapsulation socket */
+        /** Get the bound port of the wrapped socket. */
         public int getPort() {
             return mPort;
         }
 
-        @Override
         /**
-         * Release the resources that have been reserved for this Socket.
+         * Close this socket.
          *
-         * <p>This method closes the underlying socket, reducing a user's allocated sockets in the
-         * system. This must be done as part of cleanup following use of a socket. Failure to do so
-         * will cause the socket to count against a total allocation limit for IpSec and eventually
-         * fail due to resource limits.
-         *
-         * @param fd a file descriptor previously returned as a UDP Encapsulation socket.
+         * <p>This closes the wrapped socket. Open encapsulation sockets count against a user's
+         * resource limits, and forgetting to close them eventually will result in {@link
+         * ResourceUnavailableException} being thrown.
          */
+        @Override
         public void close() throws IOException {
             try {
                 mService.closeUdpEncapsulationSocket(mResourceId);
@@ -476,6 +560,7 @@
             mCloseGuard.close();
         }
 
+        /** Check that the socket was closed properly. */
         @Override
         protected void finalize() throws Throwable {
             if (mCloseGuard != null) {
@@ -485,27 +570,21 @@
         }
 
         /** @hide */
-        int getResourceId() {
+        @VisibleForTesting
+        public int getResourceId() {
             return mResourceId;
         }
     };
 
     /**
-     * Open a socket that is bound to a free UDP port on the system.
+     * Open a socket for UDP encapsulation and bind to the given port.
      *
-     * <p>By binding in this manner and holding the FileDescriptor, the socket cannot be un-bound by
-     * the caller. This provides safe access to a socket on a port that can later be used as a UDP
-     * Encapsulation port.
+     * <p>See {@link UdpEncapsulationSocket} for the proper way to close the returned socket.
      *
-     * <p>This socket reservation works in conjunction with IpSecTransforms, which may re-use the
-     * socket port. Explicitly opening this port is only necessary if communication is desired on
-     * that port.
-     *
-     * @param port a local UDP port to be reserved for UDP Encapsulation. is provided, then this
-     *     method will bind to the specified port or fail. To retrieve the port number, call {@link
-     *     android.system.Os#getsockname(FileDescriptor)}.
-     * @return a {@link UdpEncapsulationSocket} that is bound to the requested port for the lifetime
-     *     of the object.
+     * @param port a local UDP port
+     * @return a socket that is bound to the given port
+     * @throws IOException indicating that the socket could not be opened or bound
+     * @throws ResourceUnavailableException indicating that too many encapsulation sockets are open
      */
     // Returning a socket in this fashion that has been created and bound by the system
     // is the only safe way to ensure that a socket is both accessible to the user and
@@ -525,17 +604,16 @@
     }
 
     /**
-     * Open a socket that is bound to a port selected by the system.
+     * Open a socket for UDP encapsulation.
      *
-     * <p>By binding in this manner and holding the FileDescriptor, the socket cannot be un-bound by
-     * the caller. This provides safe access to a socket on a port that can later be used as a UDP
-     * Encapsulation port.
+     * <p>See {@link UdpEncapsulationSocket} for the proper way to close the returned socket.
      *
-     * <p>This socket reservation works in conjunction with IpSecTransforms, which may re-use the
-     * socket port. Explicitly opening this port is only necessary if communication is desired on
-     * that port.
+     * <p>The local port of the returned socket can be obtained by calling {@link
+     * UdpEncapsulationSocket#getPort()}.
      *
-     * @return a {@link UdpEncapsulationSocket} that is bound to an arbitrarily selected port
+     * @return a socket that is bound to a local port
+     * @throws IOException indicating that the socket could not be opened or bound
+     * @throws ResourceUnavailableException indicating that too many encapsulation sockets are open
      */
     // Returning a socket in this fashion that has been created and bound by the system
     // is the only safe way to ensure that a socket is both accessible to the user and
@@ -548,7 +626,7 @@
     }
 
     /**
-     * Retrieve an instance of an IpSecManager within you application context
+     * Construct an instance of IpSecManager within an application context.
      *
      * @param context the application context for this manager
      * @hide
diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java
index cfbac58b..cda4ec7 100644
--- a/core/java/android/net/IpSecTransform.java
+++ b/core/java/android/net/IpSecTransform.java
@@ -26,38 +26,41 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Log;
+
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
+
 import dalvik.system.CloseGuard;
+
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.net.InetAddress;
 
 /**
- * This class represents an IpSecTransform, which encapsulates both properties and state of IPsec.
+ * This class represents an IPsec transform, which comprises security associations in one or both
+ * directions.
  *
- * <p>IpSecTransforms must be built from an IpSecTransform.Builder, and they must persist throughout
- * the lifetime of the underlying transform. If a transform object leaves scope, the underlying
- * transform may be disabled automatically, with likely undesirable results.
+ * <p>Transforms are created using {@link IpSecTransform.Builder}. Each {@code IpSecTransform}
+ * object encapsulates the properties and state of an inbound and outbound IPsec security
+ * association. That includes, but is not limited to, algorithm choice, key material, and allocated
+ * system resources.
  *
- * <p>An IpSecTransform may either represent a tunnel mode transform that operates on a wide array
- * of traffic or may represent a transport mode transform operating on a Socket or Sockets.
- *
- * @hide
+ * @see <a href="https://tools.ietf.org/html/rfc4301">RFC 4301, Security Architecture for the
+ * Internet Protocol</a>
  */
 public final class IpSecTransform implements AutoCloseable {
     private static final String TAG = "IpSecTransform";
 
     /**
-     * For direction-specific attributes of an IpSecTransform, indicates that an attribute applies
-     * to traffic towards the host.
+     * For direction-specific attributes of an {@link IpSecTransform}, indicates that an attribute
+     * applies to traffic towards the host.
      */
     public static final int DIRECTION_IN = 0;
 
     /**
-     * For direction-specific attributes of an IpSecTransform, indicates that an attribute applies
-     * to traffic from the host.
+     * For direction-specific attributes of an {@link IpSecTransform}, indicates that an attribute
+     * applies to traffic from the host.
      */
     public static final int DIRECTION_OUT = 1;
 
@@ -67,25 +70,25 @@
     public @interface TransformDirection {}
 
     /** @hide */
-    public static final int MODE_TUNNEL = 0;
+    public static final int MODE_TRANSPORT = 0;
 
     /** @hide */
-    public static final int MODE_TRANSPORT = 1;
+    public static final int MODE_TUNNEL = 1;
 
     /** @hide */
     public static final int ENCAP_NONE = 0;
 
     /**
-     * IpSec traffic will be encapsulated within a UDP header with an additional 8-byte header pad
-     * (of '0'-value bytes) that prevents traffic from being interpreted as IKE or as ESP over UDP.
+     * IPsec traffic will be encapsulated within UDP, but with 8 zero-value bytes between the UDP
+     * header and payload. This prevents traffic from being interpreted as ESP or IKEv2.
      *
      * @hide
      */
     public static final int ENCAP_ESPINUDP_NON_IKE = 1;
 
     /**
-     * IpSec traffic will be encapsulated within UDP as per <a
-     * href="https://tools.ietf.org/html/rfc3948">RFC3498</a>.
+     * IPsec traffic will be encapsulated within UDP as per
+     * <a href="https://tools.ietf.org/html/rfc3948">RFC 3498</a>.
      *
      * @hide
      */
@@ -112,7 +115,11 @@
         return IIpSecService.Stub.asInterface(b);
     }
 
-    private void checkResultStatusAndThrow(int status)
+    /**
+     * Checks the result status and throws an appropriate exception if
+     * the status is not Status.OK.
+     */
+    private void checkResultStatus(int status)
             throws IOException, IpSecManager.ResourceUnavailableException,
                     IpSecManager.SpiUnavailableException {
         switch (status) {
@@ -140,7 +147,7 @@
                 IpSecTransformResponse result =
                         svc.createTransportModeTransform(mConfig, new Binder());
                 int status = result.status;
-                checkResultStatusAndThrow(status);
+                checkResultStatus(status);
                 mResourceId = result.resourceId;
 
                 /* Keepalive will silently fail if not needed by the config; but, if needed and
@@ -160,13 +167,14 @@
     }
 
     /**
-     * Deactivate an IpSecTransform and free all resources for that transform that are managed by
-     * the system for this Transform.
+     * Deactivate this {@code IpSecTransform} and free allocated resources.
      *
-     * <p>Deactivating a transform while it is still applied to any Socket will result in sockets
-     * refusing to send or receive data. This method will silently succeed if the specified
-     * transform has already been removed; thus, it is always safe to attempt cleanup when a
-     * transform is no longer needed.
+     * <p>Deactivating a transform while it is still applied to a socket will result in errors on
+     * that socket. Make sure to remove transforms by calling {@link
+     * IpSecManager#removeTransportModeTransform}. Note, removing an {@code IpSecTransform} from a
+     * socket will not deactivate it (because one transform may be applied to multiple sockets).
+     *
+     * <p>It is safe to call this method on a transform that has already been deactivated.
      */
     public void close() {
         Log.d(TAG, "Removing Transform with Id " + mResourceId);
@@ -192,6 +200,7 @@
         }
     }
 
+    /** Check that the transform was closed properly. */
     @Override
     protected void finalize() throws Throwable {
         if (mCloseGuard != null) {
@@ -242,162 +251,142 @@
 
     /* Package */
     void startKeepalive(Context c) {
-        // FIXME: NO_KEEPALIVE needs to be a constant
-        if (mConfig.getNattKeepaliveInterval() == 0) {
-            return;
-        }
-
-        ConnectivityManager cm =
-                (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
-
-        if (mKeepalive != null) {
-            Log.wtf(TAG, "Keepalive already started for this IpSecTransform.");
-            return;
-        }
-
-        synchronized (mKeepaliveSyncLock) {
-            mKeepalive =
-                    cm.startNattKeepalive(
-                            mConfig.getNetwork(),
-                            mConfig.getNattKeepaliveInterval(),
-                            mKeepaliveCallback,
-                            mConfig.getLocalAddress(),
-                            0x1234, /* FIXME: get the real port number again,
-                                    which we need to retrieve from the provided
-                                    EncapsulationSocket, and which isn't currently
-                                    stashed in IpSecConfig */
-                            mConfig.getRemoteAddress());
-            try {
-                // FIXME: this is still a horrible way to fudge the synchronous callback
-                mKeepaliveSyncLock.wait(2000);
-            } catch (InterruptedException e) {
-            }
-        }
-        if (mKeepaliveStatus != ConnectivityManager.PacketKeepalive.SUCCESS) {
-            throw new UnsupportedOperationException("Packet Keepalive cannot be started");
+        if (mConfig.getNattKeepaliveInterval() != 0) {
+            Log.wtf(TAG, "Keepalive not yet supported.");
         }
     }
 
-    /* Package */
-    int getResourceId() {
+    /** @hide */
+    @VisibleForTesting
+    public int getResourceId() {
         return mResourceId;
     }
 
     /* Package */
     void stopKeepalive() {
-        if (mKeepalive == null) {
-            return;
-        }
-        mKeepalive.stop();
-        synchronized (mKeepaliveSyncLock) {
-            if (mKeepaliveStatus == ConnectivityManager.PacketKeepalive.SUCCESS) {
-                try {
-                    mKeepaliveSyncLock.wait(2000);
-                } catch (InterruptedException e) {
-                }
-            }
-        }
+        return;
     }
 
     /**
-     * Builder object to facilitate the creation of IpSecTransform objects.
-     *
-     * <p>Apply additional properties to the transform and then call a build() method to return an
-     * IpSecTransform object.
-     *
-     * @see Builder#buildTransportModeTransform(InetAddress)
+     * This class is used to build {@link IpSecTransform} objects.
      */
     public static class Builder {
         private Context mContext;
         private IpSecConfig mConfig;
 
         /**
-         * Add an encryption algorithm to the transform for the given direction.
+         * Set the encryption algorithm for the given direction.
          *
-         * <p>If encryption is set for a given direction without also providing an SPI for that
-         * direction, creation of an IpSecTransform will fail upon calling a build() method.
+         * <p>If encryption is set for a direction without also providing an SPI for that direction,
+         * creation of an {@code IpSecTransform} will fail when attempting to build the transform.
          *
-         * @param direction either {@link #DIRECTION_IN or #DIRECTION_OUT}
+         * <p>Encryption is mutually exclusive with authenticated encryption.
+         *
+         * @param direction either {@link #DIRECTION_IN} or {@link #DIRECTION_OUT}
          * @param algo {@link IpSecAlgorithm} specifying the encryption to be applied.
          */
         public IpSecTransform.Builder setEncryption(
                 @TransformDirection int direction, IpSecAlgorithm algo) {
-            mConfig.flow[direction].encryption = algo;
+            // TODO: throw IllegalArgumentException if algo is not an encryption algorithm.
+            mConfig.setEncryption(direction, algo);
             return this;
         }
 
         /**
-         * Add an authentication/integrity algorithm to the transform.
+         * Set the authentication (integrity) algorithm for the given direction.
          *
-         * <p>If authentication is set for a given direction without also providing an SPI for that
-         * direction, creation of an IpSecTransform will fail upon calling a build() method.
+         * <p>If authentication is set for a direction without also providing an SPI for that
+         * direction, creation of an {@code IpSecTransform} will fail when attempting to build the
+         * transform.
          *
-         * @param direction either {@link #DIRECTION_IN or #DIRECTION_OUT}
+         * <p>Authentication is mutually exclusive with authenticated encryption.
+         *
+         * @param direction either {@link #DIRECTION_IN} or {@link #DIRECTION_OUT}
          * @param algo {@link IpSecAlgorithm} specifying the authentication to be applied.
          */
         public IpSecTransform.Builder setAuthentication(
                 @TransformDirection int direction, IpSecAlgorithm algo) {
-            mConfig.flow[direction].authentication = algo;
+            // TODO: throw IllegalArgumentException if algo is not an authentication algorithm.
+            mConfig.setAuthentication(direction, algo);
             return this;
         }
 
         /**
-         * Set the SPI, which uniquely identifies a particular IPsec session from others. Because
-         * IPsec operates at the IP layer, this 32-bit identifier uniquely identifies packets to a
-         * given destination address.
+         * Set the authenticated encryption algorithm for the given direction.
          *
-         * <p>Care should be chosen when selecting an SPI to ensure that is is as unique as
-         * possible. To reserve a value call {@link IpSecManager#reserveSecurityParameterIndex(int,
-         * InetAddress, int)}. Otherwise, SPI collisions would prevent a transform from being
-         * activated. IpSecManager#reserveSecurityParameterIndex(int, InetAddres$s, int)}.
+         * <p>If an authenticated encryption algorithm is set for a given direction without also
+         * providing an SPI for that direction, creation of an {@code IpSecTransform} will fail when
+         * attempting to build the transform.
          *
-         * <p>Unless an SPI is set for a given direction, traffic in that direction will be
-         * sent/received without any IPsec applied.
+         * <p>The Authenticated Encryption (AE) class of algorithms are also known as Authenticated
+         * Encryption with Associated Data (AEAD) algorithms, or Combined mode algorithms (as
+         * referred to in <a href="https://tools.ietf.org/html/rfc4301">RFC 4301</a>).
          *
-         * @param direction either {@link #DIRECTION_IN or #DIRECTION_OUT}
+         * <p>Authenticated encryption is mutually exclusive with encryption and authentication.
+         *
+         * @param direction either {@link #DIRECTION_IN} or {@link #DIRECTION_OUT}
+         * @param algo {@link IpSecAlgorithm} specifying the authenticated encryption algorithm to
+         *     be applied.
+         */
+        public IpSecTransform.Builder setAuthenticatedEncryption(
+                @TransformDirection int direction, IpSecAlgorithm algo) {
+            mConfig.setAuthenticatedEncryption(direction, algo);
+            return this;
+        }
+
+        /**
+         * Set the SPI for the given direction.
+         *
+         * <p>Because IPsec operates at the IP layer, this 32-bit identifier uniquely identifies
+         * packets to a given destination address. To prevent SPI collisions, values should be
+         * reserved by calling {@link IpSecManager#reserveSecurityParameterIndex}.
+         *
+         * <p>If the SPI and algorithms are omitted for one direction, traffic in that direction
+         * will not be encrypted or authenticated.
+         *
+         * @param direction either {@link #DIRECTION_IN} or {@link #DIRECTION_OUT}
          * @param spi a unique {@link IpSecManager.SecurityParameterIndex} to identify transformed
          *     traffic
          */
         public IpSecTransform.Builder setSpi(
                 @TransformDirection int direction, IpSecManager.SecurityParameterIndex spi) {
-            // TODO: convert to using the resource Id of the SPI. Then build() can validate
-            // the owner in the IpSecService
-            mConfig.flow[direction].spiResourceId = spi.getResourceId();
+            mConfig.setSpiResourceId(direction, spi.getResourceId());
             return this;
         }
 
         /**
-         * Specify the network on which this transform will emit its traffic; (otherwise it will
-         * emit on the default network).
+         * Set the {@link Network} which will carry tunneled traffic.
          *
-         * <p>Restricts the transformed traffic to a particular {@link Network}. This is required in
-         * tunnel mode.
+         * <p>Restricts the transformed traffic to a particular {@link Network}. This is required
+         * for tunnel mode, otherwise tunneled traffic would be sent on the default network.
          *
          * @hide
          */
         @SystemApi
         public IpSecTransform.Builder setUnderlyingNetwork(Network net) {
-            mConfig.network = net;
+            mConfig.setNetwork(net);
             return this;
         }
 
         /**
-         * Add UDP encapsulation to an IPv4 transform
+         * Add UDP encapsulation to an IPv4 transform.
          *
-         * <p>This option allows IPsec traffic to pass through NAT. Refer to RFC 3947 and 3948 for
-         * details on how UDP should be applied to IPsec.
+         * <p>This allows IPsec traffic to pass through a NAT.
          *
-         * @param localSocket a {@link IpSecManager.UdpEncapsulationSocket} for sending and
-         *     receiving encapsulating traffic.
-         * @param remotePort the UDP port number of the remote that will send and receive
-         *     encapsulated traffic. In the case of IKE, this is likely port 4500.
+         * @see <a href="https://tools.ietf.org/html/rfc3948">RFC 3948, UDP Encapsulation of IPsec
+         * ESP Packets</a>
+         * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.23">RFC 7296 section 2.23,
+         * NAT Traversal of IKEv2</a>
+         *
+         * @param localSocket a socket for sending and receiving encapsulated traffic
+         * @param remotePort the UDP port number of the remote host that will send and receive
+         *     encapsulated traffic. In the case of IKEv2, this should be port 4500.
          */
         public IpSecTransform.Builder setIpv4Encapsulation(
                 IpSecManager.UdpEncapsulationSocket localSocket, int remotePort) {
-            // TODO: check encap type is valid.
-            mConfig.encapType = ENCAP_ESPINUDP;
-            mConfig.encapLocalPortResourceId = localSocket.getResourceId();
-            mConfig.encapRemotePort = remotePort;
+            mConfig.setEncapType(ENCAP_ESPINUDP);
+            mConfig.setEncapSocketResourceId(localSocket.getResourceId());
+            mConfig.setEncapRemotePort(remotePort);
             return this;
         }
 
@@ -405,53 +394,47 @@
         // TODO: Probably a better exception to throw for NATTKeepalive failure
         // TODO: Specify the needed NATT keepalive permission.
         /**
-         * Send a NATT Keepalive packet with a given maximum interval. This will create an offloaded
-         * request to do power-efficient NATT Keepalive. If NATT keepalive is requested but cannot
-         * be activated, then the transform will fail to activate and throw an IOException.
+         * Set NAT-T keepalives to be sent with a given interval.
          *
-         * @param intervalSeconds the maximum number of seconds between keepalive packets, no less
-         *     than 20s and no more than 3600s.
+         * <p>This will set power-efficient keepalive packets to be sent by the system. If NAT-T
+         * keepalive is requested but cannot be activated, then creation of an {@link
+         * IpSecTransform} will fail when calling the build method.
+         *
+         * @param intervalSeconds the maximum number of seconds between keepalive packets. Must be
+         *     between 20s and 3600s.
+         *
          * @hide
          */
         @SystemApi
         public IpSecTransform.Builder setNattKeepalive(int intervalSeconds) {
-            mConfig.nattKeepaliveInterval = intervalSeconds;
+            mConfig.setNattKeepaliveInterval(intervalSeconds);
             return this;
         }
 
         /**
-         * Build and return an active {@link IpSecTransform} object as a Transport Mode Transform.
-         * Some parameters have interdependencies that are checked at build time. If a well-formed
-         * transform cannot be created from the supplied parameters, this method will throw an
-         * Exception.
+         * Build a transport mode {@link IpSecTransform}.
          *
-         * <p>Upon a successful return from this call, the provided IpSecTransform will be active
-         * and may be applied to sockets. If too many IpSecTransform objects are active for a given
-         * user this operation will fail and throw ResourceUnavailableException. To avoid these
-         * exceptions, unused Transform objects must be cleaned up by calling {@link
-         * IpSecTransform#close()} when they are no longer needed.
+         * <p>This builds and activates a transport mode transform. Note that an active transform
+         * will not affect any network traffic until it has been applied to one or more sockets.
          *
-         * @param remoteAddress the {@link InetAddress} that, when matched on traffic to/from this
-         *     socket will cause the transform to be applied.
-         *     <p>Note that an active transform will not impact any network traffic until it has
-         *     been applied to one or more Sockets. Calling this method is a necessary precondition
-         *     for applying it to a socket, but is not sufficient to actually apply IPsec.
+         * @see IpSecManager#applyTransportModeTransform
+         *
+         * @param remoteAddress the remote {@code InetAddress} of traffic on sockets that will use
+         *     this transform
          * @throws IllegalArgumentException indicating that a particular combination of transform
-         *     properties is invalid.
-         * @throws IpSecManager.ResourceUnavailableException in the event that no more Transforms
-         *     may be allocated
-         * @throws SpiUnavailableException if the SPI collides with an existing transform
-         *     (unlikely).
-         * @throws ResourceUnavailableException if the current user currently has exceeded the
-         *     number of allowed active transforms.
+         *     properties is invalid
+         * @throws IpSecManager.ResourceUnavailableException indicating that too many transforms are
+         *     active
+         * @throws IpSecManager.SpiUnavailableException indicating the rare case where an SPI
+         *     collides with an existing transform
+         * @throws IOException indicating other errors
          */
         public IpSecTransform buildTransportModeTransform(InetAddress remoteAddress)
                 throws IpSecManager.ResourceUnavailableException,
                         IpSecManager.SpiUnavailableException, IOException {
-            //FIXME: argument validation here
-            //throw new IllegalArgumentException("Natt Keepalive requires UDP Encapsulation");
-            mConfig.mode = MODE_TRANSPORT;
-            mConfig.remoteAddress = remoteAddress;
+            mConfig.setMode(MODE_TRANSPORT);
+            mConfig.setRemoteAddress(remoteAddress.getHostAddress());
+            // FIXME: modifying a builder after calling build can change the built transform.
             return new IpSecTransform(mContext, mConfig).activate();
         }
 
@@ -472,30 +455,21 @@
                 InetAddress localAddress, InetAddress remoteAddress) {
             //FIXME: argument validation here
             //throw new IllegalArgumentException("Natt Keepalive requires UDP Encapsulation");
-            mConfig.localAddress = localAddress;
-            mConfig.remoteAddress = remoteAddress;
-            mConfig.mode = MODE_TUNNEL;
+            mConfig.setLocalAddress(localAddress.getHostAddress());
+            mConfig.setRemoteAddress(remoteAddress.getHostAddress());
+            mConfig.setMode(MODE_TUNNEL);
             return new IpSecTransform(mContext, mConfig);
         }
 
         /**
-         * Create a new IpSecTransform.Builder to construct an IpSecTransform
+         * Create a new IpSecTransform.Builder.
          *
-         * @param context current Context
+         * @param context current context
          */
         public Builder(@NonNull Context context) {
             Preconditions.checkNotNull(context);
             mContext = context;
             mConfig = new IpSecConfig();
         }
-
-        /**
-         * Return an {@link IpSecConfig} object for testing purposes.
-         * @hide
-         */
-        @VisibleForTesting
-        public IpSecConfig getIpSecConfig() {
-            return mConfig;
-        }
     }
 }
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 1bb0fbb..4e474c8 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -18,14 +18,13 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.net.ProxyInfo;
-import android.os.Parcelable;
 import android.os.Parcel;
+import android.os.Parcelable;
 import android.text.TextUtils;
 
-import java.net.InetAddress;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
+import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -71,8 +70,23 @@
      * @hide
      */
     public static class CompareResult<T> {
-        public List<T> removed = new ArrayList<T>();
-        public List<T> added = new ArrayList<T>();
+        public final List<T> removed = new ArrayList<T>();
+        public final List<T> added = new ArrayList<T>();
+
+        public CompareResult() {}
+
+        public CompareResult(Collection<T> oldItems, Collection<T> newItems) {
+            if (oldItems != null) {
+                removed.addAll(oldItems);
+            }
+            if (newItems != null) {
+                for (T newItem : newItems) {
+                    if (!removed.remove(newItem)) {
+                        added.add(newItem);
+                    }
+                }
+            }
+        }
 
         @Override
         public String toString() {
@@ -504,11 +518,22 @@
     }
 
     /**
+     * Make sure this LinkProperties instance contains routes that cover the local subnet
+     * of its link addresses. Add any route that is missing.
+     * @hide
+     */
+    public void ensureDirectlyConnectedRoutes() {
+        for (LinkAddress addr: mLinkAddresses) {
+            addRoute(new RouteInfo(addr, null, mIfaceName));
+        }
+    }
+
+    /**
      * Returns all the routes on this link and all the links stacked above it.
      * @hide
      */
     public List<RouteInfo> getAllRoutes() {
-        List<RouteInfo> routes = new ArrayList();
+        List<RouteInfo> routes = new ArrayList<>();
         routes.addAll(mRoutes);
         for (LinkProperties stacked: mStackedLinks.values()) {
             routes.addAll(stacked.getAllRoutes());
@@ -658,9 +683,9 @@
      */
     public boolean hasIPv4Address() {
         for (LinkAddress address : mLinkAddresses) {
-          if (address.getAddress() instanceof Inet4Address) {
-            return true;
-          }
+            if (address.getAddress() instanceof Inet4Address) {
+                return true;
+            }
         }
         return false;
     }
@@ -700,9 +725,9 @@
      */
     public boolean hasIPv4DefaultRoute() {
         for (RouteInfo r : mRoutes) {
-          if (r.isIPv4Default()) {
-            return true;
-          }
+            if (r.isIPv4Default()) {
+                return true;
+            }
         }
         return false;
     }
@@ -715,9 +740,9 @@
      */
     public boolean hasIPv6DefaultRoute() {
         for (RouteInfo r : mRoutes) {
-          if (r.isIPv6Default()) {
-            return true;
-          }
+            if (r.isIPv6Default()) {
+                return true;
+            }
         }
         return false;
     }
@@ -730,9 +755,9 @@
      */
     public boolean hasIPv4DnsServer() {
         for (InetAddress ia : mDnses) {
-          if (ia instanceof Inet4Address) {
-            return true;
-          }
+            if (ia instanceof Inet4Address) {
+                return true;
+            }
         }
         return false;
     }
@@ -745,9 +770,9 @@
      */
     public boolean hasIPv6DnsServer() {
         for (InetAddress ia : mDnses) {
-          if (ia instanceof Inet6Address) {
-            return true;
-          }
+            if (ia instanceof Inet6Address) {
+                return true;
+            }
         }
         return false;
     }
@@ -990,17 +1015,8 @@
          * are in target but not in mLinkAddresses are placed in the
          * addedAddresses.
          */
-        CompareResult<LinkAddress> result = new CompareResult<LinkAddress>();
-        result.removed = new ArrayList<LinkAddress>(mLinkAddresses);
-        result.added.clear();
-        if (target != null) {
-            for (LinkAddress newAddress : target.getLinkAddresses()) {
-                if (! result.removed.remove(newAddress)) {
-                    result.added.add(newAddress);
-                }
-            }
-        }
-        return result;
+        return new CompareResult<>(mLinkAddresses,
+                target != null ? target.getLinkAddresses() : null);
     }
 
     /**
@@ -1019,18 +1035,7 @@
          * are in target but not in mDnses are placed in the
          * addedAddresses.
          */
-        CompareResult<InetAddress> result = new CompareResult<InetAddress>();
-
-        result.removed = new ArrayList<InetAddress>(mDnses);
-        result.added.clear();
-        if (target != null) {
-            for (InetAddress newAddress : target.getDnsServers()) {
-                if (! result.removed.remove(newAddress)) {
-                    result.added.add(newAddress);
-                }
-            }
-        }
-        return result;
+        return new CompareResult<>(mDnses, target != null ? target.getDnsServers() : null);
     }
 
     /**
@@ -1048,18 +1053,7 @@
          * leaving the routes that are different. And route address which
          * are in target but not in mRoutes are placed in added.
          */
-        CompareResult<RouteInfo> result = new CompareResult<RouteInfo>();
-
-        result.removed = getAllRoutes();
-        result.added.clear();
-        if (target != null) {
-            for (RouteInfo r : target.getAllRoutes()) {
-                if (! result.removed.remove(r)) {
-                    result.added.add(r);
-                }
-            }
-        }
-        return result;
+        return new CompareResult<>(getAllRoutes(), target != null ? target.getAllRoutes() : null);
     }
 
     /**
@@ -1077,18 +1071,8 @@
          * leaving the interface names that are different. And interface names which
          * are in target but not in this are placed in added.
          */
-        CompareResult<String> result = new CompareResult<String>();
-
-        result.removed = getAllInterfaceNames();
-        result.added.clear();
-        if (target != null) {
-            for (String r : target.getAllInterfaceNames()) {
-                if (! result.removed.remove(r)) {
-                    result.added.add(r);
-                }
-            }
-        }
-        return result;
+        return new CompareResult<>(getAllInterfaceNames(),
+                target != null ? target.getAllInterfaceNames() : null);
     }
 
 
diff --git a/core/java/android/net/LocalSocketImpl.java b/core/java/android/net/LocalSocketImpl.java
index 05c8afb..6e4a231 100644
--- a/core/java/android/net/LocalSocketImpl.java
+++ b/core/java/android/net/LocalSocketImpl.java
@@ -16,18 +16,18 @@
 
 package android.net;
 
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.InputStream;
-import java.io.FileDescriptor;
-import java.net.SocketOptions;
-
 import android.system.ErrnoException;
+import android.system.Int32Ref;
 import android.system.Os;
 import android.system.OsConstants;
 import android.system.StructLinger;
 import android.system.StructTimeval;
-import android.util.MutableInt;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.SocketOptions;
 
 /**
  * Socket implementation used for android.net.LocalSocket and
@@ -62,7 +62,7 @@
             FileDescriptor myFd = fd;
             if (myFd == null) throw new IOException("socket closed");
 
-            MutableInt avail = new MutableInt(0);
+            Int32Ref avail = new Int32Ref(0);
             try {
                 Os.ioctlInt(myFd, OsConstants.FIONREAD, avail);
             } catch (ErrnoException e) {
@@ -167,7 +167,7 @@
             if (myFd == null) throw new IOException("socket closed");
 
             // Loop until the output buffer is empty.
-            MutableInt pending = new MutableInt(0);
+            Int32Ref pending = new Int32Ref(0);
             while (true) {
                 try {
                     // See linux/net/unix/af_unix.c
diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java
new file mode 100644
index 0000000..f6a69ba
--- /dev/null
+++ b/core/java/android/net/MacAddress.java
@@ -0,0 +1,274 @@
+/*
+ * 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.net;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.BitUtils;
+
+import java.util.Arrays;
+import java.util.Random;
+import java.util.StringJoiner;
+
+/**
+ * Represents a mac address.
+ *
+ * @hide
+ */
+public final class MacAddress implements Parcelable {
+
+    private static final int ETHER_ADDR_LEN = 6;
+    private static final byte[] ETHER_ADDR_BROADCAST = addr(0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
+
+    /** The broadcast mac address.  */
+    public static final MacAddress BROADCAST_ADDRESS = new MacAddress(ETHER_ADDR_BROADCAST);
+
+    /** The zero mac address. */
+    public static final MacAddress ALL_ZEROS_ADDRESS = new MacAddress(0);
+
+    /** Represents categories of mac addresses. */
+    public enum MacAddressType {
+        UNICAST,
+        MULTICAST,
+        BROADCAST;
+    }
+
+    private static final long VALID_LONG_MASK = BROADCAST_ADDRESS.mAddr;
+    private static final long LOCALLY_ASSIGNED_MASK = new MacAddress("2:0:0:0:0:0").mAddr;
+    private static final long MULTICAST_MASK = new MacAddress("1:0:0:0:0:0").mAddr;
+    private static final long OUI_MASK = new MacAddress("ff:ff:ff:0:0:0").mAddr;
+    private static final long NIC_MASK = new MacAddress("0:0:0:ff:ff:ff").mAddr;
+    private static final MacAddress BASE_ANDROID_MAC = new MacAddress("da:a1:19:0:0:0");
+
+    // Internal representation of the mac address as a single 8 byte long.
+    // The encoding scheme sets the two most significant bytes to 0. The 6 bytes of the
+    // mac address are encoded in the 6 least significant bytes of the long, where the first
+    // byte of the array is mapped to the 3rd highest logical byte of the long, the second
+    // byte of the array is mapped to the 4th highest logical byte of the long, and so on.
+    private final long mAddr;
+
+    private MacAddress(long addr) {
+        mAddr = addr;
+    }
+
+    /** Creates a MacAddress for the given byte representation. */
+    public MacAddress(byte[] addr) {
+        this(longAddrFromByteAddr(addr));
+    }
+
+    /** Creates a MacAddress for the given string representation. */
+    public MacAddress(String addr) {
+        this(longAddrFromByteAddr(byteAddrFromStringAddr(addr)));
+    }
+
+    /** Returns the MacAddressType of this MacAddress. */
+    public MacAddressType addressType() {
+        if (equals(BROADCAST_ADDRESS)) {
+            return MacAddressType.BROADCAST;
+        }
+        if (isMulticastAddress()) {
+            return MacAddressType.MULTICAST;
+        }
+        return MacAddressType.UNICAST;
+    }
+
+    /** Returns true if this MacAddress corresponds to a multicast address. */
+    public boolean isMulticastAddress() {
+        return (mAddr & MULTICAST_MASK) != 0;
+    }
+
+    /** Returns true if this MacAddress corresponds to a locally assigned address. */
+    public boolean isLocallyAssigned() {
+        return (mAddr & LOCALLY_ASSIGNED_MASK) != 0;
+    }
+
+    /** Returns a byte array representation of this MacAddress. */
+    public byte[] toByteArray() {
+        return byteAddrFromLongAddr(mAddr);
+    }
+
+    @Override
+    public String toString() {
+        return stringAddrFromByteAddr(byteAddrFromLongAddr(mAddr));
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) ((mAddr >> 32) ^ mAddr);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return (o instanceof MacAddress) && ((MacAddress) o).mAddr == mAddr;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeLong(mAddr);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<MacAddress> CREATOR =
+            new Parcelable.Creator<MacAddress>() {
+                public MacAddress createFromParcel(Parcel in) {
+                    return new MacAddress(in.readLong());
+                }
+
+                public MacAddress[] newArray(int size) {
+                    return new MacAddress[size];
+                }
+            };
+
+    /** Return true if the given byte array is not null and has the length of a mac address. */
+    public static boolean isMacAddress(byte[] addr) {
+        return addr != null && addr.length == ETHER_ADDR_LEN;
+    }
+
+    /**
+     * Return the MacAddressType of the mac address represented by the given byte array,
+     * or null if the given byte array does not represent an mac address.
+     */
+    public static MacAddressType macAddressType(byte[] addr) {
+        if (!isMacAddress(addr)) {
+            return null;
+        }
+        return new MacAddress(addr).addressType();
+    }
+
+    /** DOCME */
+    public static byte[] byteAddrFromStringAddr(String addr) {
+        if (addr == null) {
+            throw new IllegalArgumentException("cannot convert the null String");
+        }
+        String[] parts = addr.split(":");
+        if (parts.length != ETHER_ADDR_LEN) {
+            throw new IllegalArgumentException(addr + " was not a valid MAC address");
+        }
+        byte[] bytes = new byte[ETHER_ADDR_LEN];
+        for (int i = 0; i < ETHER_ADDR_LEN; i++) {
+            int x = Integer.valueOf(parts[i], 16);
+            if (x < 0 || 0xff < x) {
+                throw new IllegalArgumentException(addr + "was not a valid MAC address");
+            }
+            bytes[i] = (byte) x;
+        }
+        return bytes;
+    }
+
+    /** DOCME */
+    public static String stringAddrFromByteAddr(byte[] addr) {
+        if (!isMacAddress(addr)) {
+            return null;
+        }
+        StringJoiner j = new StringJoiner(":");
+        for (byte b : addr) {
+            j.add(Integer.toHexString(BitUtils.uint8(b)));
+        }
+        return j.toString();
+    }
+
+    /** @hide */
+    public static byte[] byteAddrFromLongAddr(long addr) {
+        byte[] bytes = new byte[ETHER_ADDR_LEN];
+        int index = ETHER_ADDR_LEN;
+        while (index-- > 0) {
+            bytes[index] = (byte) addr;
+            addr = addr >> 8;
+        }
+        return bytes;
+    }
+
+    /** @hide */
+    public static long longAddrFromByteAddr(byte[] addr) {
+        if (!isMacAddress(addr)) {
+            throw new IllegalArgumentException(
+                    Arrays.toString(addr) + " was not a valid MAC address");
+        }
+        long longAddr = 0;
+        for (byte b : addr) {
+            longAddr = (longAddr << 8) + BitUtils.uint8(b);
+        }
+        return longAddr;
+    }
+
+    /** @hide */
+    public static long longAddrFromStringAddr(String addr) {
+        if (addr == null) {
+            throw new IllegalArgumentException("cannot convert the null String");
+        }
+        String[] parts = addr.split(":");
+        if (parts.length != ETHER_ADDR_LEN) {
+            throw new IllegalArgumentException(addr + " was not a valid MAC address");
+        }
+        long longAddr = 0;
+        int index = ETHER_ADDR_LEN;
+        while (index-- > 0) {
+            int x = Integer.valueOf(parts[index], 16);
+            if (x < 0 || 0xff < x) {
+                throw new IllegalArgumentException(addr + "was not a valid MAC address");
+            }
+            longAddr = x + (longAddr << 8);
+        }
+        return longAddr;
+    }
+
+    /** @hide */
+    public static String stringAddrFromLongAddr(long addr) {
+        addr = Long.reverseBytes(addr) >> 16;
+        StringJoiner j = new StringJoiner(":");
+        for (int i = 0; i < ETHER_ADDR_LEN; i++) {
+            j.add(Integer.toHexString((byte) addr));
+            addr = addr >> 8;
+        }
+        return j.toString();
+    }
+
+    /**
+     * Returns a randomely generated mac address with the Android OUI value "DA-A1-19".
+     * The locally assigned bit is always set to 1.
+     */
+    public static MacAddress getRandomAddress() {
+        return getRandomAddress(BASE_ANDROID_MAC, new Random());
+    }
+
+    /**
+     * Returns a randomely generated mac address using the given Random object and the same
+     * OUI values as the given MacAddress. The locally assigned bit is always set to 1.
+     */
+    public static MacAddress getRandomAddress(MacAddress base, Random r) {
+        long longAddr = (base.mAddr & OUI_MASK) | (NIC_MASK & r.nextLong()) | LOCALLY_ASSIGNED_MASK;
+        return new MacAddress(longAddr);
+    }
+
+    // Convenience function for working around the lack of byte literals.
+    private static byte[] addr(int... in) {
+        if (in.length != ETHER_ADDR_LEN) {
+            throw new IllegalArgumentException(Arrays.toString(in)
+                    + " was not an array with length equal to " + ETHER_ADDR_LEN);
+        }
+        byte[] out = new byte[ETHER_ADDR_LEN];
+        for (int i = 0; i < ETHER_ADDR_LEN; i++) {
+            out[i] = (byte) in[i];
+        }
+        return out;
+    }
+}
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 3c868c3..903b602 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -16,14 +16,14 @@
 
 package android.net;
 
-import android.os.Parcelable;
 import android.os.Parcel;
+import android.os.Parcelable;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
 
-import libcore.net.http.Dns;
-import libcore.net.http.HttpURLConnectionFactory;
+import com.android.okhttp.internalandroidapi.Dns;
+import com.android.okhttp.internalandroidapi.HttpURLConnectionFactory;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -34,11 +34,12 @@
 import java.net.Socket;
 import java.net.SocketAddress;
 import java.net.SocketException;
-import java.net.UnknownHostException;
 import java.net.URL;
 import java.net.URLConnection;
+import java.net.UnknownHostException;
 import java.util.Arrays;
 import java.util.concurrent.TimeUnit;
+
 import javax.net.SocketFactory;
 
 /**
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 4bb8844..ee75fd4 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -16,6 +16,8 @@
 
 package android.net;
 
+import android.annotation.IntDef;
+import android.net.ConnectivityManager.NetworkCallback;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -23,19 +25,30 @@
 import com.android.internal.util.BitUtils;
 import com.android.internal.util.Preconditions;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
 import java.util.StringJoiner;
 
 /**
- * This class represents the capabilities of a network.  This is used both to specify
- * needs to {@link ConnectivityManager} and when inspecting a network.
- *
- * Note that this replaces the old {@link ConnectivityManager#TYPE_MOBILE} method
- * of network selection.  Rather than indicate a need for Wi-Fi because an application
- * needs high bandwidth and risk obsolescence when a new, fast network appears (like LTE),
- * the application should specify it needs high bandwidth.  Similarly if an application
- * needs an unmetered network for a bulk transfer it can specify that rather than assuming
- * all cellular based connections are metered and all Wi-Fi based connections are not.
+ * Representation of the capabilities of a network. This object serves two
+ * purposes:
+ * <ul>
+ * <li>An expression of the current capabilities of an active network, typically
+ * expressed through
+ * {@link NetworkCallback#onCapabilitiesChanged(Network, NetworkCapabilities)}
+ * or {@link ConnectivityManager#getNetworkCapabilities(Network)}.
+ * <li>An expression of the future capabilities of a desired network, typically
+ * expressed through {@link NetworkRequest}.
+ * </ul>
+ * <p>
+ * This replaces the old {@link ConnectivityManager#TYPE_MOBILE} method of
+ * network selection. Rather than indicate a need for Wi-Fi because an
+ * application needs high bandwidth and risk obsolescence when a new, fast
+ * network appears (like LTE), the application should specify it needs high
+ * bandwidth. Similarly if an application needs an unmetered network for a bulk
+ * transfer it can specify that rather than assuming all cellular based
+ * connections are metered and all Wi-Fi based connections are not.
  */
 public final class NetworkCapabilities implements Parcelable {
     private static final String TAG = "NetworkCapabilities";
@@ -77,6 +90,32 @@
      */
     private long mNetworkCapabilities;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "NET_CAPABILITY_" }, value = {
+            NET_CAPABILITY_MMS,
+            NET_CAPABILITY_SUPL,
+            NET_CAPABILITY_DUN,
+            NET_CAPABILITY_FOTA,
+            NET_CAPABILITY_IMS,
+            NET_CAPABILITY_CBS,
+            NET_CAPABILITY_WIFI_P2P,
+            NET_CAPABILITY_IA,
+            NET_CAPABILITY_RCS,
+            NET_CAPABILITY_XCAP,
+            NET_CAPABILITY_EIMS,
+            NET_CAPABILITY_NOT_METERED,
+            NET_CAPABILITY_INTERNET,
+            NET_CAPABILITY_NOT_RESTRICTED,
+            NET_CAPABILITY_TRUSTED,
+            NET_CAPABILITY_NOT_VPN,
+            NET_CAPABILITY_VALIDATED,
+            NET_CAPABILITY_CAPTIVE_PORTAL,
+            NET_CAPABILITY_NOT_ROAMING,
+            NET_CAPABILITY_FOREGROUND,
+    })
+    public @interface NetCapability { }
+
     /**
      * Indicates this is a network that has the ability to reach the
      * carrier's MMSC for sending and receiving MMS messages.
@@ -190,11 +229,16 @@
     public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17;
 
     /**
+     * Indicates that this network is not roaming.
+     */
+    public static final int NET_CAPABILITY_NOT_ROAMING = 18;
+
+    /**
      * Indicates that this network is available for use by apps, and not a network that is being
      * kept up in the background to facilitate fast network switching.
      * @hide
      */
-    public static final int NET_CAPABILITY_FOREGROUND = 18;
+    public static final int NET_CAPABILITY_FOREGROUND = 19;
 
     private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
     private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_FOREGROUND;
@@ -209,6 +253,7 @@
             (1 << NET_CAPABILITY_TRUSTED) |
             (1 << NET_CAPABILITY_VALIDATED) |
             (1 << NET_CAPABILITY_CAPTIVE_PORTAL) |
+            (1 << NET_CAPABILITY_NOT_ROAMING) |
             (1 << NET_CAPABILITY_FOREGROUND);
 
     /**
@@ -260,11 +305,11 @@
      * Multiple capabilities may be applied sequentially.  Note that when searching
      * for a network to satisfy a request, all capabilities requested must be satisfied.
      *
-     * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added.
+     * @param capability the capability to be added.
      * @return This NetworkCapabilities instance, to facilitate chaining.
      * @hide
      */
-    public NetworkCapabilities addCapability(int capability) {
+    public NetworkCapabilities addCapability(@NetCapability int capability) {
         if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
             throw new IllegalArgumentException("NetworkCapability out of range");
         }
@@ -275,11 +320,11 @@
     /**
      * Removes (if found) the given capability from this {@code NetworkCapability} instance.
      *
-     * @param capability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed.
+     * @param capability the capability to be removed.
      * @return This NetworkCapabilities instance, to facilitate chaining.
      * @hide
      */
-    public NetworkCapabilities removeCapability(int capability) {
+    public NetworkCapabilities removeCapability(@NetCapability int capability) {
         if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
             throw new IllegalArgumentException("NetworkCapability out of range");
         }
@@ -288,23 +333,46 @@
     }
 
     /**
-     * Gets all the capabilities set on this {@code NetworkCapability} instance.
+     * Sets (or clears) the given capability on this {@link NetworkCapabilities}
+     * instance.
      *
-     * @return an array of {@code NetworkCapabilities.NET_CAPABILITY_*} values
-     *         for this instance.
      * @hide
      */
-    public int[] getCapabilities() {
+    public NetworkCapabilities setCapability(@NetCapability int capability, boolean value) {
+        if (value) {
+            addCapability(capability);
+        } else {
+            removeCapability(capability);
+        }
+        return this;
+    }
+
+    /**
+     * Gets all the capabilities set on this {@code NetworkCapability} instance.
+     *
+     * @return an array of capability values for this instance.
+     * @hide
+     */
+    public @NetCapability int[] getCapabilities() {
         return BitUtils.unpackBits(mNetworkCapabilities);
     }
 
     /**
+     * Sets all the capabilities set on this {@code NetworkCapability} instance.
+     *
+     * @hide
+     */
+    public void setCapabilities(@NetCapability int[] capabilities) {
+        mNetworkCapabilities = BitUtils.packBits(capabilities);
+    }
+
+    /**
      * Tests for the presence of a capabilitity on this instance.
      *
-     * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for.
+     * @param capability the capabilities to be tested for.
      * @return {@code true} if set on this instance.
      */
-    public boolean hasCapability(int capability) {
+    public boolean hasCapability(@NetCapability int capability) {
         if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
             return false;
         }
@@ -385,6 +453,19 @@
      */
     private long mTransportTypes;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "TRANSPORT_" }, value = {
+            TRANSPORT_CELLULAR,
+            TRANSPORT_WIFI,
+            TRANSPORT_BLUETOOTH,
+            TRANSPORT_ETHERNET,
+            TRANSPORT_VPN,
+            TRANSPORT_WIFI_AWARE,
+            TRANSPORT_LOWPAN,
+    })
+    public @interface Transport { }
+
     /**
      * Indicates this network uses a Cellular transport.
      */
@@ -426,7 +507,7 @@
     public static final int MAX_TRANSPORT = TRANSPORT_LOWPAN;
 
     /** @hide */
-    public static boolean isValidTransport(int transportType) {
+    public static boolean isValidTransport(@Transport int transportType) {
         return (MIN_TRANSPORT <= transportType) && (transportType <= MAX_TRANSPORT);
     }
 
@@ -449,11 +530,11 @@
      * to be selected.  This is logically different than
      * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
      *
-     * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be added.
+     * @param transportType the transport type to be added.
      * @return This NetworkCapabilities instance, to facilitate chaining.
      * @hide
      */
-    public NetworkCapabilities addTransportType(int transportType) {
+    public NetworkCapabilities addTransportType(@Transport int transportType) {
         checkValidTransportType(transportType);
         mTransportTypes |= 1 << transportType;
         setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
@@ -463,11 +544,11 @@
     /**
      * Removes (if found) the given transport from this {@code NetworkCapability} instance.
      *
-     * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be removed.
+     * @param transportType the transport type to be removed.
      * @return This NetworkCapabilities instance, to facilitate chaining.
      * @hide
      */
-    public NetworkCapabilities removeTransportType(int transportType) {
+    public NetworkCapabilities removeTransportType(@Transport int transportType) {
         checkValidTransportType(transportType);
         mTransportTypes &= ~(1 << transportType);
         setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
@@ -475,23 +556,46 @@
     }
 
     /**
-     * Gets all the transports set on this {@code NetworkCapability} instance.
+     * Sets (or clears) the given transport on this {@link NetworkCapabilities}
+     * instance.
      *
-     * @return an array of {@code NetworkCapabilities.TRANSPORT_*} values
-     *         for this instance.
      * @hide
      */
-    public int[] getTransportTypes() {
+    public NetworkCapabilities setTransportType(@Transport int transportType, boolean value) {
+        if (value) {
+            addTransportType(transportType);
+        } else {
+            removeTransportType(transportType);
+        }
+        return this;
+    }
+
+    /**
+     * Gets all the transports set on this {@code NetworkCapability} instance.
+     *
+     * @return an array of transport type values for this instance.
+     * @hide
+     */
+    public @Transport int[] getTransportTypes() {
         return BitUtils.unpackBits(mTransportTypes);
     }
 
     /**
+     * Sets all the transports set on this {@code NetworkCapability} instance.
+     *
+     * @hide
+     */
+    public void setTransportTypes(@Transport int[] transportTypes) {
+        mTransportTypes = BitUtils.packBits(transportTypes);
+    }
+
+    /**
      * Tests for the presence of a transport on this instance.
      *
-     * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be tested for.
+     * @param transportType the transport type to be tested for.
      * @return {@code true} if set on this instance.
      */
-    public boolean hasTransport(int transportType) {
+    public boolean hasTransport(@Transport int transportType) {
         return isValidTransport(transportType) && ((mTransportTypes & (1 << transportType)) != 0);
     }
 
@@ -510,12 +614,18 @@
     }
 
     /**
+     * Value indicating that link bandwidth is unspecified.
+     * @hide
+     */
+    public static final int LINK_BANDWIDTH_UNSPECIFIED = 0;
+
+    /**
      * Passive link bandwidth.  This is a rough guide of the expected peak bandwidth
      * for the first hop on the given transport.  It is not measured, but may take into account
      * link parameters (Radio technology, allocated channels, etc).
      */
-    private int mLinkUpBandwidthKbps;
-    private int mLinkDownBandwidthKbps;
+    private int mLinkUpBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
+    private int mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
 
     /**
      * Sets the upstream bandwidth for this network in Kbps.  This always only refers to
@@ -532,8 +642,9 @@
      * @param upKbps the estimated first hop upstream (device to network) bandwidth.
      * @hide
      */
-    public void setLinkUpstreamBandwidthKbps(int upKbps) {
+    public NetworkCapabilities setLinkUpstreamBandwidthKbps(int upKbps) {
         mLinkUpBandwidthKbps = upKbps;
+        return this;
     }
 
     /**
@@ -561,8 +672,9 @@
      * @param downKbps the estimated first hop downstream (network to device) bandwidth.
      * @hide
      */
-    public void setLinkDownstreamBandwidthKbps(int downKbps) {
+    public NetworkCapabilities setLinkDownstreamBandwidthKbps(int downKbps) {
         mLinkDownBandwidthKbps = downKbps;
+        return this;
     }
 
     /**
@@ -589,6 +701,20 @@
         return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
                 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
     }
+    /** @hide */
+    public static int minBandwidth(int a, int b) {
+        if (a == LINK_BANDWIDTH_UNSPECIFIED)  {
+            return b;
+        } else if (b == LINK_BANDWIDTH_UNSPECIFIED) {
+            return a;
+        } else {
+            return Math.min(a, b);
+        }
+    }
+    /** @hide */
+    public static int maxBandwidth(int a, int b) {
+        return Math.max(a, b);
+    }
 
     private NetworkSpecifier mNetworkSpecifier = null;
 
@@ -669,8 +795,9 @@
      * @param signalStrength the bearer-specific signal strength.
      * @hide
      */
-    public void setSignalStrength(int signalStrength) {
+    public NetworkCapabilities setSignalStrength(int signalStrength) {
         mSignalStrength = signalStrength;
+        return this;
     }
 
     /**
@@ -896,7 +1023,7 @@
     /**
      * @hide
      */
-    public static String capabilityNamesOf(int[] capabilities) {
+    public static String capabilityNamesOf(@NetCapability int[] capabilities) {
         StringJoiner joiner = new StringJoiner("|");
         if (capabilities != null) {
             for (int c : capabilities) {
@@ -909,7 +1036,7 @@
     /**
      * @hide
      */
-    public static String capabilityNameOf(int capability) {
+    public static String capabilityNameOf(@NetCapability int capability) {
         switch (capability) {
             case NET_CAPABILITY_MMS:            return "MMS";
             case NET_CAPABILITY_SUPL:           return "SUPL";
@@ -929,6 +1056,7 @@
             case NET_CAPABILITY_NOT_VPN:        return "NOT_VPN";
             case NET_CAPABILITY_VALIDATED:      return "VALIDATED";
             case NET_CAPABILITY_CAPTIVE_PORTAL: return "CAPTIVE_PORTAL";
+            case NET_CAPABILITY_NOT_ROAMING:    return "NOT_ROAMING";
             case NET_CAPABILITY_FOREGROUND:     return "FOREGROUND";
             default:                            return Integer.toString(capability);
         }
@@ -937,7 +1065,7 @@
     /**
      * @hide
      */
-    public static String transportNamesOf(int[] types) {
+    public static String transportNamesOf(@Transport int[] types) {
         StringJoiner joiner = new StringJoiner("|");
         if (types != null) {
             for (int t : types) {
@@ -950,14 +1078,14 @@
     /**
      * @hide
      */
-    public static String transportNameOf(int transport) {
+    public static String transportNameOf(@Transport int transport) {
         if (!isValidTransport(transport)) {
             return "UNKNOWN";
         }
         return TRANSPORT_NAMES[transport];
     }
 
-    private static void checkValidTransportType(int transport) {
+    private static void checkValidTransportType(@Transport int transport) {
         Preconditions.checkArgument(
                 isValidTransport(transport), "Invalid TransportType " + transport);
     }
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index 0775bda..df404b7 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -189,7 +189,8 @@
 
         String subscriberId = null;
         String networkId = null;
-        boolean roaming = false;
+        boolean roaming = !state.networkCapabilities.hasCapability(
+                NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
         boolean metered = !state.networkCapabilities.hasCapability(
                 NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
 
@@ -203,7 +204,6 @@
             }
 
             subscriberId = state.subscriberId;
-            roaming = state.networkInfo.isRoaming();
 
         } else if (type == TYPE_WIFI) {
             if (state.networkId != null) {
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 84c32be..d554938 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -307,11 +307,17 @@
     }
 
     /**
-     * Indicates whether the device is currently roaming on this network.
-     * When {@code true}, it suggests that use of data on this network
-     * may incur extra costs.
+     * Indicates whether the device is currently roaming on this network. When
+     * {@code true}, it suggests that use of data on this network may incur
+     * extra costs.
+     *
      * @return {@code true} if roaming is in effect, {@code false} otherwise.
+     * @deprecated Callers should switch to checking
+     *             {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING}
+     *             instead, since that handles more complex situations, such as
+     *             VPNs.
      */
+    @Deprecated
     public boolean isRoaming() {
         synchronized (this) {
             return mIsRoaming;
@@ -320,6 +326,7 @@
 
     /** {@hide} */
     @VisibleForTesting
+    @Deprecated
     public void setRoaming(boolean isRoaming) {
         synchronized (this) {
             mIsRoaming = isRoaming;
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 95a8bb4..25b1705 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -155,14 +155,13 @@
          * Add the given capability requirement to this builder.  These represent
          * the requested network's required capabilities.  Note that when searching
          * for a network to satisfy a request, all capabilities requested must be
-         * satisfied.  See {@link NetworkCapabilities} for {@code NET_CAPABILITY_*}
-         * definitions.
+         * satisfied.
          *
-         * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to add.
+         * @param capability The capability to add.
          * @return The builder to facilitate chaining
          *         {@code builder.addCapability(...).addCapability();}.
          */
-        public Builder addCapability(int capability) {
+        public Builder addCapability(@NetworkCapabilities.NetCapability int capability) {
             mNetworkCapabilities.addCapability(capability);
             return this;
         }
@@ -170,10 +169,10 @@
         /**
          * Removes (if found) the given capability from this builder instance.
          *
-         * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to remove.
+         * @param capability The capability to remove.
          * @return The builder to facilitate chaining.
          */
-        public Builder removeCapability(int capability) {
+        public Builder removeCapability(@NetworkCapabilities.NetCapability int capability) {
             mNetworkCapabilities.removeCapability(capability);
             return this;
         }
@@ -208,13 +207,12 @@
          * Adds the given transport requirement to this builder.  These represent
          * the set of allowed transports for the request.  Only networks using one
          * of these transports will satisfy the request.  If no particular transports
-         * are required, none should be specified here.  See {@link NetworkCapabilities}
-         * for {@code TRANSPORT_*} definitions.
+         * are required, none should be specified here.
          *
-         * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to add.
+         * @param transportType The transport type to add.
          * @return The builder to facilitate chaining.
          */
-        public Builder addTransportType(int transportType) {
+        public Builder addTransportType(@NetworkCapabilities.Transport int transportType) {
             mNetworkCapabilities.addTransportType(transportType);
             return this;
         }
@@ -222,10 +220,10 @@
         /**
          * Removes (if found) the given transport from this builder instance.
          *
-         * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to remove.
+         * @param transportType The transport type to remove.
          * @return The builder to facilitate chaining.
          */
-        public Builder removeTransportType(int transportType) {
+        public Builder removeTransportType(@NetworkCapabilities.Transport int transportType) {
             mNetworkCapabilities.removeTransportType(transportType);
             return this;
         }
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 0780af6..171adc0 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -677,36 +677,33 @@
             entry.tag = left.tag[i];
             entry.metered = left.metered[i];
             entry.roaming = left.roaming[i];
+            entry.rxBytes = left.rxBytes[i];
+            entry.rxPackets = left.rxPackets[i];
+            entry.txBytes = left.txBytes[i];
+            entry.txPackets = left.txPackets[i];
+            entry.operations = left.operations[i];
 
             // find remote row that matches, and subtract
             final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag,
                     entry.metered, entry.roaming, i);
-            if (j == -1) {
-                // newly appearing row, return entire value
-                entry.rxBytes = left.rxBytes[i];
-                entry.rxPackets = left.rxPackets[i];
-                entry.txBytes = left.txBytes[i];
-                entry.txPackets = left.txPackets[i];
-                entry.operations = left.operations[i];
-            } else {
-                // existing row, subtract remote value
-                entry.rxBytes = left.rxBytes[i] - right.rxBytes[j];
-                entry.rxPackets = left.rxPackets[i] - right.rxPackets[j];
-                entry.txBytes = left.txBytes[i] - right.txBytes[j];
-                entry.txPackets = left.txPackets[i] - right.txPackets[j];
-                entry.operations = left.operations[i] - right.operations[j];
+            if (j != -1) {
+                // Found matching row, subtract remote value.
+                entry.rxBytes -= right.rxBytes[j];
+                entry.rxPackets -= right.rxPackets[j];
+                entry.txBytes -= right.txBytes[j];
+                entry.txPackets -= right.txPackets[j];
+                entry.operations -= right.operations[j];
+            }
 
-                if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0
-                        || entry.txPackets < 0 || entry.operations < 0) {
-                    if (observer != null) {
-                        observer.foundNonMonotonic(left, i, right, j, cookie);
-                    }
-                    entry.rxBytes = Math.max(entry.rxBytes, 0);
-                    entry.rxPackets = Math.max(entry.rxPackets, 0);
-                    entry.txBytes = Math.max(entry.txBytes, 0);
-                    entry.txPackets = Math.max(entry.txPackets, 0);
-                    entry.operations = Math.max(entry.operations, 0);
+            if (entry.isNegative()) {
+                if (observer != null) {
+                    observer.foundNonMonotonic(left, i, right, j, cookie);
                 }
+                entry.rxBytes = Math.max(entry.rxBytes, 0);
+                entry.rxPackets = Math.max(entry.rxPackets, 0);
+                entry.txBytes = Math.max(entry.txBytes, 0);
+                entry.txPackets = Math.max(entry.txPackets, 0);
+                entry.operations = Math.max(entry.operations, 0);
             }
 
             result.addValues(entry);
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index caf7982..0d2fcd0 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -18,8 +18,8 @@
 
 import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
 import static android.net.ConnectivityManager.TYPE_ETHERNET;
-import static android.net.ConnectivityManager.TYPE_PROXY;
 import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.ConnectivityManager.TYPE_PROXY;
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
 import static android.net.ConnectivityManager.TYPE_WIMAX;
@@ -34,8 +34,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.BackupUtils;
+import android.util.Log;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 
 import java.io.ByteArrayOutputStream;
@@ -52,14 +52,18 @@
  * @hide
  */
 public class NetworkTemplate implements Parcelable {
+    private static final String TAG = "NetworkTemplate";
+
     /**
      * Current Version of the Backup Serializer.
      */
     private static final int BACKUP_VERSION = 1;
 
     public static final int MATCH_MOBILE_ALL = 1;
+    /** @deprecated don't use this any more */
     @Deprecated
     public static final int MATCH_MOBILE_3G_LOWER = 2;
+    /** @deprecated don't use this any more */
     @Deprecated
     public static final int MATCH_MOBILE_4G = 3;
     public static final int MATCH_WIFI = 4;
@@ -69,9 +73,26 @@
     public static final int MATCH_BLUETOOTH = 8;
     public static final int MATCH_PROXY = 9;
 
+    private static boolean isKnownMatchRule(final int rule) {
+        switch (rule) {
+            case MATCH_MOBILE_ALL:
+            case MATCH_MOBILE_3G_LOWER:
+            case MATCH_MOBILE_4G:
+            case MATCH_WIFI:
+            case MATCH_ETHERNET:
+            case MATCH_MOBILE_WILDCARD:
+            case MATCH_WIFI_WILDCARD:
+            case MATCH_BLUETOOTH:
+            case MATCH_PROXY:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
     private static boolean sForceAllNetworkTypes = false;
 
-    @VisibleForTesting
     public static void forceAllNetworkTypes() {
         sForceAllNetworkTypes = true;
     }
@@ -180,6 +201,11 @@
         mSubscriberId = subscriberId;
         mMatchSubscriberIds = matchSubscriberIds;
         mNetworkId = networkId;
+
+        if (!isKnownMatchRule(matchRule)) {
+            Log.e(TAG, "Unknown network template rule " + matchRule
+                    + " will not match any identity.");
+        }
     }
 
     private NetworkTemplate(Parcel in) {
@@ -294,7 +320,9 @@
             case MATCH_PROXY:
                 return matchesProxy(ident);
             default:
-                throw new IllegalArgumentException("unknown network template");
+                // We have no idea what kind of network template we are, so we
+                // just claim not to match anything.
+                return false;
         }
     }
 
@@ -428,7 +456,7 @@
             case MATCH_PROXY:
                 return "PROXY";
             default:
-                return "UNKNOWN";
+                return "UNKNOWN(" + matchRule + ")";
         }
     }
 
@@ -496,6 +524,11 @@
         String subscriberId = BackupUtils.readString(in);
         String networkId = BackupUtils.readString(in);
 
+        if (!isKnownMatchRule(matchRule)) {
+            throw new BackupUtils.BadVersionException(
+                    "Restored network template contains unknown match rule " + matchRule);
+        }
+
         return new NetworkTemplate(matchRule, subscriberId, networkId);
     }
 }
diff --git a/core/java/android/net/OWNERS b/core/java/android/net/OWNERS
index 0f1e259..d1ce60e 100644
--- a/core/java/android/net/OWNERS
+++ b/core/java/android/net/OWNERS
@@ -1,6 +1,6 @@
 ek@google.com
 hugobenichi@google.com
-jsharkey@google.com
+jsharkey@android.com
 lorenzo@google.com
 satk@google.com
 silberst@google.com
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index 2d9860c..185b181 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -28,8 +28,6 @@
 import android.content.Intent;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.net.Network;
-import android.net.NetworkUtils;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -99,7 +97,7 @@
  *       shut down the tunnel gracefully.</li>
  * </ol>
  *
- * <p>Services extended this class need to be declared with appropriate
+ * <p>Services extending this class need to be declared with an appropriate
  * permission and intent filter. Their access must be secured by
  * {@link android.Manifest.permission#BIND_VPN_SERVICE} permission, and
  * their intent filter must match {@link #SERVICE_INTERFACE} action. Here
@@ -112,6 +110,13 @@
  *     &lt;/intent-filter&gt;
  * &lt;/service&gt;</pre>
  *
+ * <p> The Android system starts a VPN in the background by calling
+ * {@link android.content.Context#startService startService()}. In Android 8.0
+ * (API level 26) and higher, the system places VPN apps on the temporary
+ * whitelist for a short period so the app can start in the background. The VPN
+ * app must promote itself to the foreground after it's launched or the system
+ * will shut down the app.
+ *
  * @see Builder
  */
 public class VpnService extends Service {
@@ -124,6 +129,36 @@
     public static final String SERVICE_INTERFACE = VpnConfig.SERVICE_INTERFACE;
 
     /**
+     * Key for boolean meta-data field indicating whether this VpnService supports always-on mode.
+     *
+     * <p>For a VPN app targeting {@link android.os.Build.VERSION_CODES#N API 24} or above, Android
+     * provides users with the ability to set it as always-on, so that VPN connection is
+     * persisted after device reboot and app upgrade. Always-on VPN can also be enabled by device
+     * owner and profile owner apps through
+     * {@link android.app.admin.DevicePolicyManager#setAlwaysOnVpnPackage}.
+     *
+     * <p>VPN apps not supporting this feature should opt out by adding this meta-data field to the
+     * {@code VpnService} component of {@code AndroidManifest.xml}. In case there is more than one
+     * {@code VpnService} component defined in {@code AndroidManifest.xml}, opting out any one of
+     * them will opt out the entire app. For example,
+     * <pre> {@code
+     * <service android:name=".ExampleVpnService"
+     *         android:permission="android.permission.BIND_VPN_SERVICE">
+     *     <intent-filter>
+     *         <action android:name="android.net.VpnService"/>
+     *     </intent-filter>
+     *     <meta-data android:name="android.net.VpnService.SUPPORTS_ALWAYS_ON"
+     *             android:value=false/>
+     * </service>
+     * } </pre>
+     *
+     * <p>This meta-data field defaults to {@code true} if absent. It will only have effect on
+     * {@link android.os.Build.VERSION_CODES#O_MR1} or higher.
+     */
+    public static final String SERVICE_META_DATA_SUPPORTS_ALWAYS_ON =
+            "android.net.VpnService.SUPPORTS_ALWAYS_ON";
+
+    /**
      * Use IConnectivityManager since those methods are hidden and not
      * available in ConnectivityManager.
      */
diff --git a/core/java/android/net/metrics/ConnectStats.java b/core/java/android/net/metrics/ConnectStats.java
index 30b2656..b320b75 100644
--- a/core/java/android/net/metrics/ConnectStats.java
+++ b/core/java/android/net/metrics/ConnectStats.java
@@ -20,6 +20,7 @@
 import android.system.OsConstants;
 import android.util.IntArray;
 import android.util.SparseIntArray;
+
 import com.android.internal.util.BitUtils;
 import com.android.internal.util.TokenBucket;
 
@@ -43,6 +44,8 @@
     public final TokenBucket mLatencyTb;
     /** Maximum number of latency values recorded. */
     public final int mMaxLatencyRecords;
+    /** Total count of events */
+    public int eventCount = 0;
     /** Total count of successful connects. */
     public int connectCount = 0;
     /** Total count of successful connects done in blocking mode. */
@@ -57,12 +60,15 @@
         mMaxLatencyRecords = maxLatencyRecords;
     }
 
-    public void addEvent(int errno, int latencyMs, String ipAddr) {
+    boolean addEvent(int errno, int latencyMs, String ipAddr) {
+        eventCount++;
         if (isSuccess(errno)) {
             countConnect(errno, ipAddr);
             countLatency(errno, latencyMs);
+            return true;
         } else {
             countError(errno);
+            return false;
         }
     }
 
@@ -101,7 +107,7 @@
         return (errno == 0) || isNonBlocking(errno);
     }
 
-    private static boolean isNonBlocking(int errno) {
+    static boolean isNonBlocking(int errno) {
         // On non-blocking TCP sockets, connect() immediately returns EINPROGRESS.
         // On non-blocking TCP sockets that are connecting, connect() immediately returns EALREADY.
         return (errno == EINPROGRESS) || (errno == EALREADY);
@@ -113,10 +119,12 @@
 
     @Override
     public String toString() {
-        StringBuilder builder = new StringBuilder("ConnectStats(").append(netId).append(", ");
+        StringBuilder builder =
+                new StringBuilder("ConnectStats(").append("netId=").append(netId).append(", ");
         for (int t : BitUtils.unpackBits(transports)) {
             builder.append(NetworkCapabilities.transportNameOf(t)).append(", ");
         }
+        builder.append(String.format("%d events, ", eventCount));
         builder.append(String.format("%d success, ", connectCount));
         builder.append(String.format("%d blocking, ", connectBlockingCount));
         builder.append(String.format("%d IPv6 dst", ipv6ConnectCount));
diff --git a/core/java/android/net/metrics/DefaultNetworkEvent.java b/core/java/android/net/metrics/DefaultNetworkEvent.java
index 28cf42f..8ff8e4f 100644
--- a/core/java/android/net/metrics/DefaultNetworkEvent.java
+++ b/core/java/android/net/metrics/DefaultNetworkEvent.java
@@ -16,91 +16,78 @@
 
 package android.net.metrics;
 
+import static android.net.ConnectivityManager.NETID_UNSET;
+
 import android.net.NetworkCapabilities;
-import android.os.Parcel;
-import android.os.Parcelable;
+
+import com.android.internal.util.BitUtils;
+
+import java.util.StringJoiner;
 
 /**
  * An event recorded by ConnectivityService when there is a change in the default network.
  * {@hide}
  */
-public final class DefaultNetworkEvent implements Parcelable {
-    // The ID of the network that has become the new default or NETID_UNSET if none.
-    public final int netId;
-    // The list of transport types of the new default network, for example TRANSPORT_WIFI, as
-    // defined in NetworkCapabilities.java.
-    public final int[] transportTypes;
-    // The ID of the network that was the default before or NETID_UNSET if none.
-    public final int prevNetId;
-    // Whether the previous network had IPv4/IPv6 connectivity.
-    public final boolean prevIPv4;
-    public final boolean prevIPv6;
+public class DefaultNetworkEvent {
 
-    public DefaultNetworkEvent(int netId, int[] transportTypes,
-                int prevNetId, boolean prevIPv4, boolean prevIPv6) {
-        this.netId = netId;
-        this.transportTypes = transportTypes;
-        this.prevNetId = prevNetId;
-        this.prevIPv4 = prevIPv4;
-        this.prevIPv6 = prevIPv6;
+    // The creation time in milliseconds of this DefaultNetworkEvent.
+    public final long creationTimeMs;
+    // The network ID of the network or NETID_UNSET if none.
+    public int netId = NETID_UNSET;
+    // The list of transport types, as defined in NetworkCapabilities.java.
+    public int transports;
+    // The list of transport types of the last previous default network.
+    public int previousTransports;
+    // Whether the network has IPv4/IPv6 connectivity.
+    public boolean ipv4;
+    public boolean ipv6;
+    // The initial network score when this network became the default network.
+    public int initialScore;
+    // The initial network score when this network stopped being the default network.
+    public int finalScore;
+    // The total duration in milliseconds this network was the default network.
+    public long durationMs;
+    // The total duration in milliseconds this network was the default network and was validated.
+    public long validatedMs;
+
+    public DefaultNetworkEvent(long timeMs) {
+        creationTimeMs = timeMs;
     }
 
-    private DefaultNetworkEvent(Parcel in) {
-        this.netId = in.readInt();
-        this.transportTypes = in.createIntArray();
-        this.prevNetId = in.readInt();
-        this.prevIPv4 = (in.readByte() > 0);
-        this.prevIPv6 = (in.readByte() > 0);
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(netId);
-        out.writeIntArray(transportTypes);
-        out.writeInt(prevNetId);
-        out.writeByte(prevIPv4 ? (byte) 1 : (byte) 0);
-        out.writeByte(prevIPv6 ? (byte) 1 : (byte) 0);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
+    /** Update the durationMs of this DefaultNetworkEvent for the given current time. */
+    public void updateDuration(long timeMs) {
+        durationMs = timeMs - creationTimeMs;
     }
 
     @Override
     public String toString() {
-      String prevNetwork = String.valueOf(prevNetId);
-      String newNetwork = String.valueOf(netId);
-      if (prevNetId != 0) {
-          prevNetwork += ":" + ipSupport();
-      }
-      if (netId != 0) {
-          newNetwork += ":" + NetworkCapabilities.transportNamesOf(transportTypes);
-      }
-      return String.format("DefaultNetworkEvent(%s -> %s)", prevNetwork, newNetwork);
+        StringJoiner j = new StringJoiner(", ", "DefaultNetworkEvent(", ")");
+        j.add("netId=" + netId);
+        for (int t : BitUtils.unpackBits(transports)) {
+            j.add(NetworkCapabilities.transportNameOf(t));
+        }
+        j.add("ip=" + ipSupport());
+        if (initialScore > 0) {
+            j.add("initial_score=" + initialScore);
+        }
+        if (finalScore > 0) {
+            j.add("final_score=" + finalScore);
+        }
+        j.add(String.format("duration=%.0fs", durationMs / 1000.0));
+        j.add(String.format("validation=%4.1f%%", (validatedMs * 100.0) / durationMs));
+        return j.toString();
     }
 
     private String ipSupport() {
-        if (prevIPv4 && prevIPv6) {
-            return "DUAL";
+        if (ipv4 && ipv6) {
+            return "IPv4v6";
         }
-        if (prevIPv6) {
+        if (ipv6) {
             return "IPv6";
         }
-        if (prevIPv4) {
+        if (ipv4) {
             return "IPv4";
         }
         return "NONE";
     }
-
-    public static final Parcelable.Creator<DefaultNetworkEvent> CREATOR
-        = new Parcelable.Creator<DefaultNetworkEvent>() {
-        public DefaultNetworkEvent createFromParcel(Parcel in) {
-            return new DefaultNetworkEvent(in);
-        }
-
-        public DefaultNetworkEvent[] newArray(int size) {
-            return new DefaultNetworkEvent[size];
-        }
-    };
 }
diff --git a/core/java/android/net/metrics/DnsEvent.java b/core/java/android/net/metrics/DnsEvent.java
index a4970e4..5aa705b 100644
--- a/core/java/android/net/metrics/DnsEvent.java
+++ b/core/java/android/net/metrics/DnsEvent.java
@@ -17,11 +17,13 @@
 package android.net.metrics;
 
 import android.net.NetworkCapabilities;
-import java.util.Arrays;
+
 import com.android.internal.util.BitUtils;
 
+import java.util.Arrays;
+
 /**
- * A DNS event recorded by NetdEventListenerService.
+ * A batch of DNS events recorded by NetdEventListenerService for a specific network.
  * {@hide}
  */
 final public class DnsEvent {
@@ -38,6 +40,8 @@
     // the eventTypes, returnCodes, and latenciesMs arrays have the same length and the i-th event
     // is spread across the three array at position i.
     public int eventCount;
+    // The number of successful DNS queries recorded.
+    public int successCount;
     // The types of DNS queries as defined in INetdEventListener.
     public byte[] eventTypes;
     // Current getaddrinfo codes go from 1 to EAI_MAX = 15. gethostbyname returns errno, but there
@@ -54,10 +58,11 @@
         latenciesMs = new int[initialCapacity];
     }
 
-    public void addResult(byte eventType, byte returnCode, int latencyMs) {
+    boolean addResult(byte eventType, byte returnCode, int latencyMs) {
+        boolean isSuccess = (returnCode == 0);
         if (eventCount >= SIZE_LIMIT) {
             // TODO: implement better rate limiting that does not biases metrics.
-            return;
+            return isSuccess;
         }
         if (eventCount == eventTypes.length) {
             resize((int) (1.4 * eventCount));
@@ -66,6 +71,10 @@
         returnCodes[eventCount] = returnCode;
         latenciesMs[eventCount] = latencyMs;
         eventCount++;
+        if (isSuccess) {
+            successCount++;
+        }
+        return isSuccess;
     }
 
     public void resize(int newLength) {
@@ -76,10 +85,13 @@
 
     @Override
     public String toString() {
-        StringBuilder builder = new StringBuilder("DnsEvent(").append(netId).append(", ");
+        StringBuilder builder =
+                new StringBuilder("DnsEvent(").append("netId=").append(netId).append(", ");
         for (int t : BitUtils.unpackBits(transports)) {
             builder.append(NetworkCapabilities.transportNameOf(t)).append(", ");
         }
-        return builder.append(eventCount).append(" events)").toString();
+        builder.append(String.format("%d events, ", eventCount));
+        builder.append(String.format("%d success)", successCount));
+        return builder.toString();
     }
 }
diff --git a/core/java/android/net/metrics/NetworkEvent.java b/core/java/android/net/metrics/NetworkEvent.java
index 4df3bf0..1999e78 100644
--- a/core/java/android/net/metrics/NetworkEvent.java
+++ b/core/java/android/net/metrics/NetworkEvent.java
@@ -60,29 +60,25 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface EventType {}
 
-    public final int netId;
     public final @EventType int eventType;
     public final long durationMs;
 
-    public NetworkEvent(int netId, @EventType int eventType, long durationMs) {
-        this.netId = netId;
+    public NetworkEvent(@EventType int eventType, long durationMs) {
         this.eventType = eventType;
         this.durationMs = durationMs;
     }
 
-    public NetworkEvent(int netId, @EventType int eventType) {
-        this(netId, eventType, 0);
+    public NetworkEvent(@EventType int eventType) {
+        this(eventType, 0);
     }
 
     private NetworkEvent(Parcel in) {
-        netId = in.readInt();
         eventType = in.readInt();
         durationMs = in.readLong();
     }
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(netId);
         out.writeInt(eventType);
         out.writeLong(durationMs);
     }
@@ -105,8 +101,8 @@
 
     @Override
     public String toString() {
-        return String.format("NetworkEvent(%d, %s, %dms)",
-                netId, Decoder.constants.get(eventType), durationMs);
+        return String.format("NetworkEvent(%s, %dms)",
+                Decoder.constants.get(eventType), durationMs);
     }
 
     final static class Decoder {
diff --git a/core/java/android/net/metrics/NetworkMetrics.java b/core/java/android/net/metrics/NetworkMetrics.java
new file mode 100644
index 0000000..2b662a0
--- /dev/null
+++ b/core/java/android/net/metrics/NetworkMetrics.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics;
+
+import android.net.NetworkCapabilities;
+
+import com.android.internal.util.BitUtils;
+import com.android.internal.util.TokenBucket;
+
+import java.util.StringJoiner;
+
+/**
+ * A class accumulating network metrics received from Netd regarding dns queries and
+ * connect() calls on a given network.
+ *
+ * This class also accumulates running sums of dns and connect latency stats and
+ * error counts for bug report logging.
+ *
+ * @hide
+ */
+public class NetworkMetrics {
+
+    private static final int INITIAL_DNS_BATCH_SIZE = 100;
+    private static final int CONNECT_LATENCY_MAXIMUM_RECORDS = 20000;
+
+    // The network id of the Android Network.
+    public final int netId;
+    // The transport types bitmap of the Android Network, as defined in NetworkCapabilities.java.
+    public final long transports;
+    // Accumulated metrics for connect events.
+    public final ConnectStats connectMetrics;
+    // Accumulated metrics for dns events.
+    public final DnsEvent dnsMetrics;
+    // Running sums of latencies and error counts for connect and dns events.
+    public final Summary summary;
+    // Running sums of the most recent latencies and error counts for connect and dns events.
+    // Starts null until some events are accumulated.
+    // Allows to collect periodic snapshot of the running summaries for a given network.
+    public Summary pendingSummary;
+
+    public NetworkMetrics(int netId, long transports, TokenBucket tb) {
+        this.netId = netId;
+        this.transports = transports;
+        this.connectMetrics =
+                new ConnectStats(netId, transports, tb, CONNECT_LATENCY_MAXIMUM_RECORDS);
+        this.dnsMetrics = new DnsEvent(netId, transports, INITIAL_DNS_BATCH_SIZE);
+        this.summary = new Summary(netId, transports);
+    }
+
+    /**
+     * Get currently pending Summary statistics, if any, for this NetworkMetrics, merge them
+     * into the long running Summary statistics of this NetworkMetrics, and also clear them.
+     */
+    public Summary getPendingStats() {
+        Summary s = pendingSummary;
+        pendingSummary = null;
+        if (s != null) {
+            summary.merge(s);
+        }
+        return s;
+    }
+
+    /** Accumulate a dns query result reported by netd. */
+    public void addDnsResult(int eventType, int returnCode, int latencyMs) {
+        if (pendingSummary == null) {
+            pendingSummary = new Summary(netId, transports);
+        }
+        boolean isSuccess = dnsMetrics.addResult((byte) eventType, (byte) returnCode, latencyMs);
+        pendingSummary.dnsLatencies.count(latencyMs);
+        pendingSummary.dnsErrorRate.count(isSuccess ? 0 : 1);
+    }
+
+    /** Accumulate a connect query result reported by netd. */
+    public void addConnectResult(int error, int latencyMs, String ipAddr) {
+        if (pendingSummary == null) {
+            pendingSummary = new Summary(netId, transports);
+        }
+        boolean isSuccess = connectMetrics.addEvent(error, latencyMs, ipAddr);
+        pendingSummary.connectErrorRate.count(isSuccess ? 0 : 1);
+        if (ConnectStats.isNonBlocking(error)) {
+            pendingSummary.connectLatencies.count(latencyMs);
+        }
+    }
+
+    /** Represents running sums for dns and connect average error counts and average latencies. */
+    public static class Summary {
+
+        public final int netId;
+        public final long transports;
+        // DNS latencies measured in milliseconds.
+        public final Metrics dnsLatencies = new Metrics();
+        // DNS error rate measured in percentage points.
+        public final Metrics dnsErrorRate = new Metrics();
+        // Blocking connect latencies measured in milliseconds.
+        public final Metrics connectLatencies = new Metrics();
+        // Blocking and non blocking connect error rate measured in percentage points.
+        public final Metrics connectErrorRate = new Metrics();
+
+        public Summary(int netId, long transports) {
+            this.netId = netId;
+            this.transports = transports;
+        }
+
+        void merge(Summary that) {
+            dnsLatencies.merge(that.dnsLatencies);
+            dnsErrorRate.merge(that.dnsErrorRate);
+            connectLatencies.merge(that.connectLatencies);
+            connectErrorRate.merge(that.connectErrorRate);
+        }
+
+        @Override
+        public String toString() {
+            StringJoiner j = new StringJoiner(", ", "{", "}");
+            j.add("netId=" + netId);
+            for (int t : BitUtils.unpackBits(transports)) {
+                j.add(NetworkCapabilities.transportNameOf(t));
+            }
+            j.add(String.format("dns avg=%dms max=%dms err=%.1f%% tot=%d",
+                    (int) dnsLatencies.average(), (int) dnsLatencies.max,
+                    100 * dnsErrorRate.average(), dnsErrorRate.count));
+            j.add(String.format("connect avg=%dms max=%dms err=%.1f%% tot=%d",
+                    (int) connectLatencies.average(), (int) connectLatencies.max,
+                    100 * connectErrorRate.average(), connectErrorRate.count));
+            return j.toString();
+        }
+    }
+
+    /** Tracks a running sum and returns the average of a metric. */
+    static class Metrics {
+        public double sum;
+        public double max = Double.MIN_VALUE;
+        public int count;
+
+        void merge(Metrics that) {
+            this.count += that.count;
+            this.sum += that.sum;
+            this.max = Math.max(this.max, that.max);
+        }
+
+        void count(double value) {
+            count++;
+            sum += value;
+            max = Math.max(max, value);
+        }
+
+        double average() {
+            double a = sum / (double) count;
+            if (Double.isNaN(a)) {
+                a = 0;
+            }
+            return a;
+        }
+    }
+}
diff --git a/core/java/android/net/metrics/WakeupEvent.java b/core/java/android/net/metrics/WakeupEvent.java
new file mode 100644
index 0000000..af9a73c
--- /dev/null
+++ b/core/java/android/net/metrics/WakeupEvent.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.metrics;
+
+import android.net.MacAddress;
+
+import java.util.StringJoiner;
+
+/**
+ * An event logged when NFLOG notifies userspace of a wakeup packet for
+ * watched interfaces.
+ * {@hide}
+ */
+public class WakeupEvent {
+    public String iface;
+    public int uid;
+    public int ethertype;
+    public MacAddress dstHwAddr;
+    public String srcIp;
+    public String dstIp;
+    public int ipNextHeader;
+    public int srcPort;
+    public int dstPort;
+    public long timestampMs;
+
+    @Override
+    public String toString() {
+        StringJoiner j = new StringJoiner(", ", "WakeupEvent(", ")");
+        j.add(String.format("%tT.%tL", timestampMs, timestampMs));
+        j.add(iface);
+        j.add("uid: " + Integer.toString(uid));
+        j.add("eth=0x" + Integer.toHexString(ethertype));
+        j.add("dstHw=" + dstHwAddr);
+        if (ipNextHeader > 0) {
+            j.add("ipNxtHdr=" + ipNextHeader);
+            j.add("srcIp=" + srcIp);
+            j.add("dstIp=" + dstIp);
+            if (srcPort > -1) {
+                j.add("srcPort=" + srcPort);
+            }
+            if (dstPort > -1) {
+                j.add("dstPort=" + dstPort);
+            }
+        }
+        return j.toString();
+    }
+}
diff --git a/core/java/android/net/metrics/WakeupStats.java b/core/java/android/net/metrics/WakeupStats.java
new file mode 100644
index 0000000..23c1f20
--- /dev/null
+++ b/core/java/android/net/metrics/WakeupStats.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics;
+
+import android.os.Process;
+import android.os.SystemClock;
+import android.util.SparseIntArray;
+
+import java.util.StringJoiner;
+
+/**
+ * An event logged per interface and that aggregates WakeupEvents for that interface.
+ * {@hide}
+ */
+public class WakeupStats {
+
+    private static final int NO_UID = -1;
+
+    public final long creationTimeMs = SystemClock.elapsedRealtime();
+    public final String iface;
+
+    public long totalWakeups = 0;
+    public long rootWakeups = 0;
+    public long systemWakeups = 0;
+    public long nonApplicationWakeups = 0;
+    public long applicationWakeups = 0;
+    public long noUidWakeups = 0;
+    public long durationSec = 0;
+
+    public long l2UnicastCount = 0;
+    public long l2MulticastCount = 0;
+    public long l2BroadcastCount = 0;
+
+    public final SparseIntArray ethertypes = new SparseIntArray();
+    public final SparseIntArray ipNextHeaders = new SparseIntArray();
+
+    public WakeupStats(String iface) {
+        this.iface = iface;
+    }
+
+    /** Update durationSec with current time. */
+    public void updateDuration() {
+        durationSec = (SystemClock.elapsedRealtime() - creationTimeMs) / 1000;
+    }
+
+    /** Update wakeup counters for the given WakeupEvent. */
+    public void countEvent(WakeupEvent ev) {
+        totalWakeups++;
+        switch (ev.uid) {
+            case Process.ROOT_UID:
+                rootWakeups++;
+                break;
+            case Process.SYSTEM_UID:
+                systemWakeups++;
+                break;
+            case NO_UID:
+                noUidWakeups++;
+                break;
+            default:
+                if (ev.uid >= Process.FIRST_APPLICATION_UID) {
+                    applicationWakeups++;
+                } else {
+                    nonApplicationWakeups++;
+                }
+                break;
+        }
+
+        switch (ev.dstHwAddr.addressType()) {
+            case UNICAST:
+                l2UnicastCount++;
+                break;
+            case MULTICAST:
+                l2MulticastCount++;
+                break;
+            case BROADCAST:
+                l2BroadcastCount++;
+                break;
+            default:
+                break;
+        }
+
+        increment(ethertypes, ev.ethertype);
+        if (ev.ipNextHeader >= 0) {
+            increment(ipNextHeaders, ev.ipNextHeader);
+        }
+    }
+
+    @Override
+    public String toString() {
+        updateDuration();
+        StringJoiner j = new StringJoiner(", ", "WakeupStats(", ")");
+        j.add(iface);
+        j.add("" + durationSec + "s");
+        j.add("total: " + totalWakeups);
+        j.add("root: " + rootWakeups);
+        j.add("system: " + systemWakeups);
+        j.add("apps: " + applicationWakeups);
+        j.add("non-apps: " + nonApplicationWakeups);
+        j.add("no uid: " + noUidWakeups);
+        j.add(String.format("l2 unicast/multicast/broadcast: %d/%d/%d",
+                l2UnicastCount, l2MulticastCount, l2BroadcastCount));
+        for (int i = 0; i < ethertypes.size(); i++) {
+            int eth = ethertypes.keyAt(i);
+            int count = ethertypes.valueAt(i);
+            j.add(String.format("ethertype 0x%x: %d", eth, count));
+        }
+        for (int i = 0; i < ipNextHeaders.size(); i++) {
+            int proto = ipNextHeaders.keyAt(i);
+            int count = ipNextHeaders.valueAt(i);
+            j.add(String.format("ipNxtHdr %d: %d", proto, count));
+        }
+        return j.toString();
+    }
+
+    private static void increment(SparseIntArray counters, int key) {
+        int newcount = counters.get(key, 0) + 1;
+        counters.put(key, newcount);
+    }
+}
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index 1e41eea..535bf67 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -21,25 +21,24 @@
 import static com.android.internal.util.Preconditions.checkStringNotEmpty;
 
 import android.annotation.SdkConstant;
-import android.annotation.SystemService;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemService;
 import android.content.Context;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
-import android.os.RemoteException;
 import android.os.Messenger;
-import android.text.TextUtils;
+import android.os.RemoteException;
 import android.util.Log;
 import android.util.SparseArray;
 
-import java.util.concurrent.CountDownLatch;
-
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.Protocol;
 
+import java.util.concurrent.CountDownLatch;
+
 /**
  * The Network Service Discovery Manager class provides the API to discover services
  * on a network. As an example, if device A and device B are connected over a Wi-Fi
@@ -244,7 +243,7 @@
         return name;
     }
 
-    private static int FIRST_LISTENER_KEY = 1;
+    private static final int FIRST_LISTENER_KEY = 1;
 
     private final INsdManager mService;
     private final Context mContext;
@@ -278,6 +277,7 @@
     @VisibleForTesting
     public void disconnect() {
         mAsyncChannel.disconnect();
+        mHandler.getLooper().quitSafely();
     }
 
     /**
@@ -650,7 +650,7 @@
 
     private static void checkServiceInfo(NsdServiceInfo serviceInfo) {
         checkNotNull(serviceInfo, "NsdServiceInfo cannot be null");
-        checkStringNotEmpty(serviceInfo.getServiceName(),"Service name cannot be empty");
+        checkStringNotEmpty(serviceInfo.getServiceName(), "Service name cannot be empty");
         checkStringNotEmpty(serviceInfo.getServiceType(), "Service type cannot be empty");
     }
 }
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index c5b0d2b..4160ed7 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -201,7 +201,7 @@
      * New in version 22:
      *   - BLE scan result background count, BLE unoptimized scan time
      */
-    static final String CHECKIN_VERSION = "23";
+    static final String CHECKIN_VERSION = "24";
 
     /**
      * Old version, we hit 9 and ran out of room, need to remove.
@@ -1219,6 +1219,7 @@
 
         // Platform-level low power state stats
         public String statPlatformIdleState;
+        public String statSubsystemPowerState;
 
         public HistoryStepDetails() {
             clear();
@@ -1250,6 +1251,7 @@
             out.writeInt(statSoftIrqTime);
             out.writeInt(statIdlTime);
             out.writeString(statPlatformIdleState);
+            out.writeString(statSubsystemPowerState);
         }
 
         public void readFromParcel(Parcel in) {
@@ -1271,6 +1273,7 @@
             statSoftIrqTime = in.readInt();
             statIdlTime = in.readInt();
             statPlatformIdleState = in.readString();
+            statSubsystemPowerState = in.readString();
         }
     }
 
@@ -5564,6 +5567,10 @@
                         pw.print(", PlatformIdleStat ");
                         pw.print(rec.stepDetails.statPlatformIdleState);
                         pw.println();
+
+                        pw.print(", SubsystemPowerState ");
+                        pw.print(rec.stepDetails.statSubsystemPowerState);
+                        pw.println();
                     } else {
                         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
                         pw.print(HISTORY_DATA); pw.print(",0,Dcpu=");
@@ -5599,6 +5606,13 @@
                         pw.print(',');
                         if (rec.stepDetails.statPlatformIdleState != null) {
                             pw.print(rec.stepDetails.statPlatformIdleState);
+                            if (rec.stepDetails.statSubsystemPowerState != null) {
+                                pw.print(',');
+                            }
+                        }
+
+                        if (rec.stepDetails.statSubsystemPowerState != null) {
+                            pw.print(rec.stepDetails.statSubsystemPowerState);
                         }
                         pw.println();
                     }
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 44e6f1b..3c1d83c 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -16,22 +16,25 @@
 
 package android.os;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.util.ExceptionUtils;
 import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.util.FastPrintWriter;
-import com.android.internal.util.FunctionalUtils;
 import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
 import com.android.internal.util.FunctionalUtils.ThrowingSupplier;
 
 import libcore.io.IoUtils;
+import libcore.util.NativeAllocationRegistry;
 
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Modifier;
+import java.util.ArrayList;
 
 /**
  * Base class for a remotable object, the core part of a lightweight
@@ -89,6 +92,20 @@
      */
     private static volatile TransactionTracker sTransactionTracker = null;
 
+    /**
+     * Guestimate of native memory associated with a Binder.
+     */
+    private static final int NATIVE_ALLOCATION_SIZE = 500;
+
+    private static native long getNativeFinalizer();
+
+    // Use a Holder to allow static initialization of Binder in the boot image, and
+    // possibly to avoid some initialization ordering issues.
+    private static class NoImagePreloadHolder {
+        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+                Binder.class.getClassLoader(), getNativeFinalizer(), NATIVE_ALLOCATION_SIZE);
+    }
+
     // Transaction tracking code.
 
     /**
@@ -187,8 +204,11 @@
         }
     }
 
-    /* mObject is used by native code, do not remove or rename */
-    private long mObject;
+    /**
+     * Raw native pointer to JavaBBinderHolder object. Owned by this Java object. Not null.
+     */
+    private final long mObject;
+
     private IInterface mOwner;
     private String mDescriptor;
 
@@ -200,7 +220,7 @@
      * then its own pid is returned.
      */
     public static final native int getCallingPid();
-    
+
     /**
      * Return the Linux uid assigned to the process that sent you the
      * current transaction that is being processed.  This uid can be used with
@@ -218,7 +238,7 @@
      * with their own uid.  If the current thread is not currently executing an
      * incoming transaction, then its own UserHandle is returned.
      */
-    public static final UserHandle getCallingUserHandle() {
+    public static final @NonNull UserHandle getCallingUserHandle() {
         return UserHandle.of(UserHandle.getUserId(getCallingUid()));
     }
 
@@ -261,7 +281,7 @@
      *
      * @hide
      */
-    public static final void withCleanCallingIdentity(ThrowingRunnable action) {
+    public static final void withCleanCallingIdentity(@NonNull ThrowingRunnable action) {
         long callingIdentity = clearCallingIdentity();
         Throwable throwableToPropagate = null;
         try {
@@ -285,7 +305,7 @@
      *
      * @hide
      */
-    public static final <T> T withCleanCallingIdentity(ThrowingSupplier<T> action) {
+    public static final <T> T withCleanCallingIdentity(@NonNull ThrowingSupplier<T> action) {
         long callingIdentity = clearCallingIdentity();
         Throwable throwableToPropagate = null;
         try {
@@ -333,7 +353,7 @@
      * it needs to.
      */
     public static final native void flushPendingCommands();
-    
+
     /**
      * Add the calling thread to the IPC thread pool.  This function does
      * not return until the current process is exiting.
@@ -359,7 +379,8 @@
      * Default constructor initializes the object.
      */
     public Binder() {
-        init();
+        mObject = getNativeBBinderHolder();
+        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject);
 
         if (FIND_POTENTIAL_LEAKS) {
             final Class<? extends Binder> klass = getClass();
@@ -370,22 +391,22 @@
             }
         }
     }
-    
+
     /**
      * Convenience method for associating a specific interface with the Binder.
      * After calling, queryLocalInterface() will be implemented for you
      * to return the given owner IInterface when the corresponding
      * descriptor is requested.
      */
-    public void attachInterface(IInterface owner, String descriptor) {
+    public void attachInterface(@Nullable IInterface owner, @Nullable String descriptor) {
         mOwner = owner;
         mDescriptor = descriptor;
     }
-    
+
     /**
      * Default implementation returns an empty interface name.
      */
-    public String getInterfaceDescriptor() {
+    public @Nullable String getInterfaceDescriptor() {
         return mDescriptor;
     }
 
@@ -406,13 +427,13 @@
     public boolean isBinderAlive() {
         return true;
     }
-    
+
     /**
      * Use information supplied to attachInterface() to return the
      * associated IInterface if it matches the requested
      * descriptor.
      */
-    public IInterface queryLocalInterface(String descriptor) {
+    public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
         if (mDescriptor.equals(descriptor)) {
             return mOwner;
         }
@@ -438,8 +459,20 @@
      * to override this to do the appropriate unmarshalling of transactions.
      *
      * <p>If you want to call this, call transact().
+     *
+     * @param code The action to perform.  This should
+     * be a number between {@link #FIRST_CALL_TRANSACTION} and
+     * {@link #LAST_CALL_TRANSACTION}.
+     * @param data Marshalled data being received from the caller.
+     * @param reply If the caller is expecting a result back, it should be marshalled
+     * in to here.
+     * @param flags Additional operation flags.  Either 0 for a normal
+     * RPC, or {@link #FLAG_ONEWAY} for a one-way RPC.
+     *
+     * @return Return true on a successful call; returning false is generally used to
+     * indicate that you did not understand the transaction code.
      */
-    protected boolean onTransact(int code, Parcel data, Parcel reply,
+    protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply,
             int flags) throws RemoteException {
         if (code == INTERFACE_TRANSACTION) {
             reply.writeString(getInterfaceDescriptor());
@@ -495,7 +528,7 @@
      * Implemented to call the more convenient version
      * {@link #dump(FileDescriptor, PrintWriter, String[])}.
      */
-    public void dump(FileDescriptor fd, String[] args) {
+    public void dump(@NonNull FileDescriptor fd, @Nullable String[] args) {
         FileOutputStream fout = new FileOutputStream(fd);
         PrintWriter pw = new FastPrintWriter(fout);
         try {
@@ -531,7 +564,7 @@
      * Like {@link #dump(FileDescriptor, String[])}, but ensures the target
      * executes asynchronously.
      */
-    public void dumpAsync(final FileDescriptor fd, final String[] args) {
+    public void dumpAsync(@NonNull final FileDescriptor fd, @Nullable final String[] args) {
         final FileOutputStream fout = new FileOutputStream(fd);
         final PrintWriter pw = new FastPrintWriter(fout);
         Thread thr = new Thread("Binder.dumpAsync") {
@@ -554,7 +587,8 @@
      * closed for you after you return.
      * @param args additional arguments to the dump request.
      */
-    protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
+    protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
+            @Nullable String[] args) {
     }
 
     /**
@@ -567,9 +601,10 @@
      * @throws RemoteException
      * @hide
      */
-    public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
-            String[] args, ShellCallback callback,
-            ResultReceiver resultReceiver) throws RemoteException {
+    public void shellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+            @Nullable FileDescriptor err,
+            @NonNull String[] args, @Nullable ShellCallback callback,
+            @NonNull ResultReceiver resultReceiver) throws RemoteException {
         onShellCommand(in, out, err, args, callback, resultReceiver);
     }
 
@@ -581,8 +616,10 @@
      * Consider using {@link ShellCommand} to help in the implementation.</p>
      * @hide
      */
-    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
-            String[] args, ShellCallback callback, ResultReceiver resultReceiver) throws RemoteException {
+    public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+            @Nullable FileDescriptor err,
+            @NonNull String[] args, @Nullable ShellCallback callback,
+            @NonNull ResultReceiver resultReceiver) throws RemoteException {
         FileOutputStream fout = new FileOutputStream(err != null ? err : out);
         PrintWriter pw = new FastPrintWriter(fout);
         pw.println("No shell command implementation.");
@@ -594,7 +631,7 @@
      * Default implementation rewinds the parcels and calls onTransact.  On
      * the remote side, transact calls into the binder to do the IPC.
      */
-    public final boolean transact(int code, Parcel data, Parcel reply,
+    public final boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply,
             int flags) throws RemoteException {
         if (false) Log.v("Binder", "Transact: " + code + " to " + this);
 
@@ -607,27 +644,19 @@
         }
         return r;
     }
-    
+
     /**
      * Local implementation is a no-op.
      */
-    public void linkToDeath(DeathRecipient recipient, int flags) {
+    public void linkToDeath(@NonNull DeathRecipient recipient, int flags) {
     }
 
     /**
      * Local implementation is a no-op.
      */
-    public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
+    public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags) {
         return true;
     }
-    
-    protected void finalize() throws Throwable {
-        try {
-            destroyBinder();
-        } finally {
-            super.finalize();
-        }
-    }
 
     static void checkParcel(IBinder obj, int code, Parcel parcel, String msg) {
         if (CHECK_PARCEL_SIZE && parcel.dataSize() >= 800*1024) {
@@ -652,8 +681,8 @@
         }
     }
 
-    private native final void init();
-    private native final void destroyBinder();
+    private static native long getNativeBBinderHolder();
+    private static native long getFinalizer();
 
     // Entry point from android_util_Binder.cpp's onTransact
     private boolean execTransact(int code, long dataObj, long replyObj,
@@ -714,10 +743,214 @@
     }
 }
 
+/**
+ * Java proxy for a native IBinder object.
+ * Allocated and constructed by the native javaObjectforIBinder function. Never allocated
+ * directly from Java code.
+ */
 final class BinderProxy implements IBinder {
+    // See android_util_Binder.cpp for the native half of this.
+
     // Assume the process-wide default value when created
     volatile boolean mWarnOnBlocking = Binder.sWarnOnBlocking;
 
+    /*
+     * Map from longs to BinderProxy, retaining only a WeakReference to the BinderProxies.
+     * We roll our own only because we need to lazily remove WeakReferences during accesses
+     * to avoid accumulating junk WeakReference objects. WeakHashMap isn't easily usable
+     * because we want weak values, not keys.
+     * Our hash table is never resized, but the number of entries is unlimited;
+     * performance degrades as occupancy increases significantly past MAIN_INDEX_SIZE.
+     * Not thread-safe. Client ensures there's a single access at a time.
+     */
+    private static final class ProxyMap {
+        private static final int LOG_MAIN_INDEX_SIZE = 8;
+        private static final int MAIN_INDEX_SIZE = 1 <<  LOG_MAIN_INDEX_SIZE;
+        private static final int MAIN_INDEX_MASK = MAIN_INDEX_SIZE - 1;
+
+        /**
+         * We next warn when we exceed this bucket size.
+         */
+        private int mWarnBucketSize = 20;
+
+        /**
+         * Increment mWarnBucketSize by WARN_INCREMENT each time we warn.
+         */
+        private static final int WARN_INCREMENT = 10;
+
+        /**
+         * Hash function tailored to native pointers.
+         * Returns a value < MAIN_INDEX_SIZE.
+         */
+        private static int hash(long arg) {
+            return ((int) ((arg >> 2) ^ (arg >> (2 + LOG_MAIN_INDEX_SIZE)))) & MAIN_INDEX_MASK;
+        }
+
+        /**
+         * Return the total number of pairs in the map.
+         */
+        int size() {
+            int size = 0;
+            for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) {
+                if (a != null) {
+                    size += a.size();
+                }
+            }
+            return size;
+        }
+
+        /**
+         * Remove ith entry from the hash bucket indicated by hash.
+         */
+        private void remove(int hash, int index) {
+            Long[] keyArray = mMainIndexKeys[hash];
+            ArrayList<WeakReference<BinderProxy>> valueArray = mMainIndexValues[hash];
+            int size = valueArray.size();  // KeyArray may have extra elements.
+            // Move last entry into empty slot, and truncate at end.
+            if (index != size - 1) {
+                keyArray[index] = keyArray[size - 1];
+                valueArray.set(index, valueArray.get(size - 1));
+            }
+            valueArray.remove(size - 1);
+            // Just leave key array entry; it's unused. We only trust the valueArray size.
+        }
+
+        /**
+         * Look up the supplied key. If we have a non-cleared entry for it, return it.
+         */
+        BinderProxy get(long key) {
+            int myHash = hash(key);
+            Long[] keyArray = mMainIndexKeys[myHash];
+            if (keyArray == null) {
+                return null;
+            }
+            ArrayList<WeakReference<BinderProxy>> valueArray = mMainIndexValues[myHash];
+            int bucketSize = valueArray.size();
+            for (int i = 0; i < bucketSize; ++i) {
+                long foundKey = keyArray[i];
+                if (key == foundKey) {
+                    WeakReference<BinderProxy> wr = valueArray.get(i);
+                    BinderProxy bp = wr.get();
+                    if (bp != null) {
+                        return bp;
+                    } else {
+                        remove(myHash, i);
+                        return null;
+                    }
+                }
+            }
+            return null;
+        }
+
+        private int mRandom;  // A counter used to generate a "random" index. World's 2nd worst RNG.
+
+        /**
+         * Add the key-value pair to the map.
+         * Requires that the indicated key is not already in the map.
+         */
+        void set(long key, @NonNull BinderProxy value) {
+            int myHash = hash(key);
+            ArrayList<WeakReference<BinderProxy>> valueArray = mMainIndexValues[myHash];
+            if (valueArray == null) {
+                valueArray = mMainIndexValues[myHash] = new ArrayList<>();
+                mMainIndexKeys[myHash] = new Long[1];
+            }
+            int size = valueArray.size();
+            WeakReference<BinderProxy> newWr = new WeakReference<>(value);
+            // First look for a cleared reference.
+            // This ensures that ArrayList size is bounded by the maximum occupancy of
+            // that bucket.
+            for (int i = 0; i < size; ++i) {
+                if (valueArray.get(i).get() == null) {
+                    valueArray.set(i, newWr);
+                    Long[] keyArray = mMainIndexKeys[myHash];
+                    keyArray[i] = key;
+                    if (i < size - 1) {
+                        // "Randomly" check one of the remaining entries in [i+1, size), so that
+                        // needlessly long buckets are eventually pruned.
+                        int rnd = Math.floorMod(++mRandom, size - (i + 1));
+                        if (valueArray.get(i + 1 + rnd).get() == null) {
+                            remove(myHash, i + 1 + rnd);
+                        }
+                    }
+                    return;
+                }
+            }
+            valueArray.add(size, newWr);
+            Long[] keyArray = mMainIndexKeys[myHash];
+            if (keyArray.length == size) {
+                // size >= 1, since we initially allocated one element
+                Long[] newArray = new Long[size + size / 2 + 2];
+                System.arraycopy(keyArray, 0, newArray, 0, size);
+                newArray[size] = key;
+                mMainIndexKeys[myHash] = newArray;
+            } else {
+                keyArray[size] = key;
+            }
+            if (size >= mWarnBucketSize) {
+                Log.v(Binder.TAG, "BinderProxy map growth! bucket size = " + size
+                        + " total = " + size());
+                mWarnBucketSize += WARN_INCREMENT;
+            }
+        }
+
+        // Corresponding ArrayLists in the following two arrays always have the same size.
+        // They contain no empty entries. However WeakReferences in the values ArrayLists
+        // may have been cleared.
+
+        // mMainIndexKeys[i][j] corresponds to mMainIndexValues[i].get(j) .
+        // The values ArrayList has the proper size(), the corresponding keys array
+        // is always at least the same size, but may be larger.
+        // If either a particular keys array, or the corresponding values ArrayList
+        // are null, then they both are.
+        private final Long[][] mMainIndexKeys = new Long[MAIN_INDEX_SIZE][];
+        private final ArrayList<WeakReference<BinderProxy>>[] mMainIndexValues =
+                new ArrayList[MAIN_INDEX_SIZE];
+    }
+
+    private static ProxyMap sProxyMap = new ProxyMap();
+
+    /**
+     * Return a BinderProxy for IBinder.
+     * This method is thread-hostile!  The (native) caller serializes getInstance() calls using
+     * gProxyLock.
+     * If we previously returned a BinderProxy bp for the same iBinder, and bp is still
+     * in use, then we return the same bp.
+     *
+     * @param nativeData C++ pointer to (possibly still empty) BinderProxyNativeData.
+     * Takes ownership of nativeData iff <result>.mNativeData == nativeData.  Caller will usually
+     * delete nativeData if that's not the case.
+     * @param iBinder C++ pointer to IBinder. Does not take ownership of referenced object.
+     */
+    private static BinderProxy getInstance(long nativeData, long iBinder) {
+        BinderProxy result = sProxyMap.get(iBinder);
+        if (result == null) {
+            result = new BinderProxy(nativeData);
+            sProxyMap.set(iBinder, result);
+        }
+        return result;
+    }
+
+    private BinderProxy(long nativeData) {
+        mNativeData = nativeData;
+        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeData);
+    }
+
+    /**
+     * Guestimate of native memory associated with a BinderProxy.
+     * This includes the underlying IBinder, associated DeathRecipientList, and KeyedVector
+     * that points back to us. We guess high since it includes a GlobalRef, which
+     * may be in short supply.
+     */
+    private static final int NATIVE_ALLOCATION_SIZE = 1000;
+
+    // Use a Holder to allow static initialization of BinderProxy in the boot image, and
+    // to avoid some initialization ordering issues.
+    private static class NoImagePreloadHolder {
+        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+                BinderProxy.class.getClassLoader(), getNativeFinalizer(), NATIVE_ALLOCATION_SIZE);
+    }
+
     public native boolean pingBinder();
     public native boolean isBinderAlive();
 
@@ -753,6 +986,7 @@
         }
     }
 
+    private static native long getNativeFinalizer();
     public native String getInterfaceDescriptor() throws RemoteException;
     public native boolean transactNative(int code, Parcel data, Parcel reply,
             int flags) throws RemoteException;
@@ -773,7 +1007,7 @@
             reply.recycle();
         }
     }
-    
+
     public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -807,21 +1041,6 @@
         }
     }
 
-    BinderProxy() {
-        mSelf = new WeakReference(this);
-    }
-    
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            destroy();
-        } finally {
-            super.finalize();
-        }
-    }
-    
-    private native final void destroy();
-    
     private static final void sendDeathNotice(DeathRecipient recipient) {
         if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
         try {
@@ -832,8 +1051,10 @@
                     exc);
         }
     }
-    
-    final private WeakReference mSelf;
-    private long mObject;
-    private long mOrgue;
+
+    /**
+     * C++ pointer to BinderProxyNativeData. That consists of strong pointers to the
+     * native IBinder object, and a DeathRecipientList.
+     */
+    private final long mNativeData;
 }
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index 9b5ff29..ec01364 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -260,6 +260,19 @@
     }
 
     /**
+     * Return the size of {@link #mParcelledData} in bytes if available, otherwise {@code 0}.
+     *
+     * @hide
+     */
+    public int getSize() {
+        if (mParcelledData != null) {
+            return mParcelledData.dataSize();
+        } else {
+            return 0;
+        }
+    }
+
+    /**
      * Reports whether the bundle contains any parcelled file descriptors.
      */
     public boolean hasFileDescriptors() {
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 55b6dc8..3286e6e 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -16,13 +16,22 @@
 
 package android.os;
 
-import com.android.internal.util.FastPrintWriter;
-import com.android.internal.util.TypedProperties;
-
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.AppGlobals;
 import android.content.Context;
 import android.util.Log;
 
+import com.android.internal.util.FastPrintWriter;
+import com.android.internal.util.Preconditions;
+import com.android.internal.util.TypedProperties;
+
+import dalvik.system.VMDebug;
+
+import org.apache.harmony.dalvik.ddmc.Chunk;
+import org.apache.harmony.dalvik.ddmc.ChunkHandler;
+import org.apache.harmony.dalvik.ddmc.DdmServer;
+
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
@@ -31,22 +40,15 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.Reader;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.lang.annotation.Target;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.harmony.dalvik.ddmc.Chunk;
-import org.apache.harmony.dalvik.ddmc.ChunkHandler;
-import org.apache.harmony.dalvik.ddmc.DdmServer;
-
-import dalvik.bytecode.OpcodeInfo;
-import dalvik.system.VMDebug;
-
 
 /**
  * Provides various debugging methods for Android applications, including
@@ -744,6 +746,7 @@
             dest.writeInt(dalvikPrivateClean);
             dest.writeInt(dalvikSharedClean);
             dest.writeInt(dalvikSwappedOut);
+            dest.writeInt(dalvikSwappedOutPss);
             dest.writeInt(nativePss);
             dest.writeInt(nativeSwappablePss);
             dest.writeInt(nativePrivateDirty);
@@ -751,6 +754,7 @@
             dest.writeInt(nativePrivateClean);
             dest.writeInt(nativeSharedClean);
             dest.writeInt(nativeSwappedOut);
+            dest.writeInt(nativeSwappedOutPss);
             dest.writeInt(otherPss);
             dest.writeInt(otherSwappablePss);
             dest.writeInt(otherPrivateDirty);
@@ -771,6 +775,7 @@
             dalvikPrivateClean = source.readInt();
             dalvikSharedClean = source.readInt();
             dalvikSwappedOut = source.readInt();
+            dalvikSwappedOutPss = source.readInt();
             nativePss = source.readInt();
             nativeSwappablePss = source.readInt();
             nativePrivateDirty = source.readInt();
@@ -778,6 +783,7 @@
             nativePrivateClean = source.readInt();
             nativeSharedClean = source.readInt();
             nativeSwappedOut = source.readInt();
+            nativeSwappedOutPss = source.readInt();
             otherPss = source.readInt();
             otherSwappablePss = source.readInt();
             otherPrivateDirty = source.readInt();
@@ -1942,13 +1948,7 @@
      */
     @Deprecated
     public static class InstructionCount {
-        private static final int NUM_INSTR =
-            OpcodeInfo.MAXIMUM_PACKED_VALUE + 1;
-
-        private int[] mCounts;
-
         public InstructionCount() {
-            mCounts = new int[NUM_INSTR];
         }
 
         /**
@@ -1958,13 +1958,7 @@
          * @return true if counting was started
          */
         public boolean resetAndStart() {
-            try {
-                VMDebug.startInstructionCounting();
-                VMDebug.resetInstructionCount();
-            } catch (UnsupportedOperationException uoe) {
-                return false;
-            }
-            return true;
+            return false;
         }
 
         /**
@@ -1972,13 +1966,7 @@
          * counting process.
          */
         public boolean collect() {
-            try {
-                VMDebug.stopInstructionCounting();
-                VMDebug.getInstructionCount(mCounts);
-            } catch (UnsupportedOperationException uoe) {
-                return false;
-            }
-            return true;
+            return false;
         }
 
         /**
@@ -1986,13 +1974,7 @@
          * all threads).
          */
         public int globalTotal() {
-            int count = 0;
-
-            for (int i = 0; i < NUM_INSTR; i++) {
-                count += mCounts[i];
-            }
-
-            return count;
+            return 0;
         }
 
         /**
@@ -2000,15 +1982,7 @@
          * executed globally.
          */
         public int globalMethodInvocations() {
-            int count = 0;
-
-            for (int i = 0; i < NUM_INSTR; i++) {
-                if (OpcodeInfo.isInvoke(i)) {
-                    count += mCounts[i];
-                }
-            }
-
-            return count;
+            return 0;
         }
     }
 
@@ -2266,13 +2240,26 @@
     }
 
     /**
-     * Append the stack traces of a given native process to a specified file.
+     * Append the Java stack traces of a given native process to a specified file.
+     *
      * @param pid pid to dump.
      * @param file path of file to append dump to.
      * @param timeoutSecs time to wait in seconds, or 0 to wait forever.
      * @hide
      */
-    public static native void dumpNativeBacktraceToFileTimeout(int pid, String file, int timeoutSecs);
+    public static native boolean dumpJavaBacktraceToFileTimeout(int pid, String file,
+                                                                int timeoutSecs);
+
+    /**
+     * Append the native stack traces of a given process to a specified file.
+     *
+     * @param pid pid to dump.
+     * @param file path of file to append dump to.
+     * @param timeoutSecs time to wait in seconds, or 0 to wait forever.
+     * @hide
+     */
+    public static native boolean dumpNativeBacktraceToFileTimeout(int pid, String file,
+                                                                  int timeoutSecs);
 
     /**
      * Get description of unreachable native memory.
@@ -2352,4 +2339,24 @@
     public static String getCaller() {
         return getCaller(Thread.currentThread().getStackTrace(), 0);
     }
+
+    /**
+     * Attach a library as a jvmti agent to the current runtime.
+     *
+     * @param library library containing the agent
+     * @param options options passed to the agent
+     *
+     * @throws IOException If the agent could not be attached
+     */
+    public static void attachJvmtiAgent(@NonNull String library, @Nullable String options)
+            throws IOException {
+        Preconditions.checkNotNull(library);
+        Preconditions.checkArgument(!library.contains("="));
+
+        if (options == null) {
+            VMDebug.attachAgent(library);
+        } else {
+            VMDebug.attachAgent(library + "=" + options);
+        }
+    }
 }
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 50b4f8c..56d6e0a 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -369,11 +369,11 @@
      * constraints remain.
      *
      * @param minCount Always keep at least this many files.
-     * @param minAge Always keep files younger than this age.
+     * @param minAgeMs Always keep files younger than this age, in milliseconds.
      * @return if any files were deleted.
      */
-    public static boolean deleteOlderFiles(File dir, int minCount, long minAge) {
-        if (minCount < 0 || minAge < 0) {
+    public static boolean deleteOlderFiles(File dir, int minCount, long minAgeMs) {
+        if (minCount < 0 || minAgeMs < 0) {
             throw new IllegalArgumentException("Constraints must be positive or 0");
         }
 
@@ -393,9 +393,9 @@
         for (int i = minCount; i < files.length; i++) {
             final File file = files[i];
 
-            // Keep files newer than minAge
+            // Keep files newer than minAgeMs
             final long age = System.currentTimeMillis() - file.lastModified();
-            if (age > minAge) {
+            if (age > minAgeMs) {
                 if (file.delete()) {
                     Log.d(TAG, "Deleted old file " + file);
                     deleted = true;
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index f9eaba9..07c6055 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -35,23 +35,12 @@
     private static final String TAG = "GraphicsEnvironment";
     private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
 
-    public static void setupGraphicsEnvironment(Context context) {
-        chooseDriver(context);
-
-        // Now that we've figured out which driver to use for this process, load and initialize it.
-        // This can take multiple frame periods, and it would otherwise happen as part of the first
-        // frame, increasing first-frame latency. Starting it here, as a low-priority background
-        // thread, means that it's usually done long before we start drawing the first frame,
-        // without significantly disrupting other activity launch work.
-        Thread eglInitThread = new Thread(
-                () -> {
-                    EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
-                },
-                "EGL Init");
-        eglInitThread.start();
-    }
-
-    private static void chooseDriver(Context context) {
+    /**
+     * Choose whether the current process should use the builtin or an updated driver.
+     *
+     * @hide
+     */
+    public static void chooseDriver(Context context) {
         String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
         if (driverPackageName == null || driverPackageName.isEmpty()) {
             return;
@@ -101,6 +90,27 @@
         setDriverPath(paths);
     }
 
+    /**
+     * Start a background thread to initialize EGL.
+     *
+     * Initializing EGL involves loading and initializing the graphics driver. Some drivers take
+     * several 10s of milliseconds to do this, so doing it on-demand when an app tries to render
+     * its first frame adds directly to user-visible app launch latency. By starting it earlier
+     * on a separate thread, it can usually be finished well before the UI is ready to be drawn.
+     *
+     * Should only be called after chooseDriver().
+     *
+     * @hide
+     */
+    public static void earlyInitEGL() {
+        Thread eglInitThread = new Thread(
+                () -> {
+                    EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
+                },
+                "EGL Init");
+        eglInitThread.start();
+    }
+
     private static String chooseAbi(ApplicationInfo ai) {
         String isa = VMRuntime.getCurrentInstructionSet();
         if (ai.primaryCpuAbi != null &&
diff --git a/core/java/android/os/HidlSupport.java b/core/java/android/os/HidlSupport.java
index 7dec4d7..3544ea1 100644
--- a/core/java/android/os/HidlSupport.java
+++ b/core/java/android/os/HidlSupport.java
@@ -156,4 +156,27 @@
         // Should not reach here.
         throw new UnsupportedOperationException();
     }
+
+    /**
+     * Test that two interfaces are equal. This is the Java equivalent to C++
+     * interfacesEqual function.
+     * This essentially calls .equals on the internal binder objects (via Binder()).
+     * - If both interfaces are proxies, asBinder() returns a {@link HwRemoteBinder}
+     *   object, and they are compared in {@link HwRemoteBinder#equals}.
+     * - If both interfaces are stubs, asBinder() returns the object itself. By default,
+     *   auto-generated IFoo.Stub does not override equals(), but an implementation can
+     *   optionally override it, and {@code interfacesEqual} will use it here.
+     */
+    public static boolean interfacesEqual(IHwInterface lft, Object rgt) {
+        if (lft == rgt) {
+            return true;
+        }
+        if (lft == null || rgt == null) {
+            return false;
+        }
+        if (!(rgt instanceof IHwInterface)) {
+            return false;
+        }
+        return Objects.equals(lft.asBinder(), ((IHwInterface) rgt).asBinder());
+    }
 }
diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java
index 270e63f..5e2a081 100644
--- a/core/java/android/os/HwBinder.java
+++ b/core/java/android/os/HwBinder.java
@@ -16,10 +16,10 @@
 
 package android.os;
 
-import java.util.ArrayList;
-import java.util.NoSuchElementException;
 import libcore.util.NativeAllocationRegistry;
 
+import java.util.NoSuchElementException;
+
 /** @hide */
 public abstract class HwBinder implements IHwBinder {
     private static final String TAG = "HwBinder";
@@ -46,9 +46,16 @@
     public native final void registerService(String serviceName)
         throws RemoteException;
 
-    public static native final IHwBinder getService(
+    public static final IHwBinder getService(
             String iface,
             String serviceName)
+        throws RemoteException, NoSuchElementException {
+        return getService(iface, serviceName, false /* retry */);
+    }
+    public static native final IHwBinder getService(
+            String iface,
+            String serviceName,
+            boolean retry)
         throws RemoteException, NoSuchElementException;
 
     public static native final void configureRpcThreadpool(
diff --git a/core/java/android/os/HwBlob.java b/core/java/android/os/HwBlob.java
index 88226f0a..5e9b9ae3 100644
--- a/core/java/android/os/HwBlob.java
+++ b/core/java/android/os/HwBlob.java
@@ -43,6 +43,18 @@
     public native final double getDouble(long offset);
     public native final String getString(long offset);
 
+    /**
+      The copyTo... methods copy the blob's data, starting from the given
+      byte offset, into the array. A total of "size" _elements_ are copied.
+     */
+    public native final void copyToBoolArray(long offset, boolean[] array, int size);
+    public native final void copyToInt8Array(long offset, byte[] array, int size);
+    public native final void copyToInt16Array(long offset, short[] array, int size);
+    public native final void copyToInt32Array(long offset, int[] array, int size);
+    public native final void copyToInt64Array(long offset, long[] array, int size);
+    public native final void copyToFloatArray(long offset, float[] array, int size);
+    public native final void copyToDoubleArray(long offset, double[] array, int size);
+
     public native final void putBool(long offset, boolean x);
     public native final void putInt8(long offset, byte x);
     public native final void putInt16(long offset, short x);
@@ -52,6 +64,14 @@
     public native final void putDouble(long offset, double x);
     public native final void putString(long offset, String x);
 
+    public native final void putBoolArray(long offset, boolean[] x);
+    public native final void putInt8Array(long offset, byte[] x);
+    public native final void putInt16Array(long offset, short[] x);
+    public native final void putInt32Array(long offset, int[] x);
+    public native final void putInt64Array(long offset, long[] x);
+    public native final void putFloatArray(long offset, float[] x);
+    public native final void putDoubleArray(long offset, double[] x);
+
     public native final void putBlob(long offset, HwBlob blob);
 
     public native final long handle();
diff --git a/core/java/android/os/HwRemoteBinder.java b/core/java/android/os/HwRemoteBinder.java
index 2f89ce6..a07e42c 100644
--- a/core/java/android/os/HwRemoteBinder.java
+++ b/core/java/android/os/HwRemoteBinder.java
@@ -63,4 +63,9 @@
     }
 
     private long mNativeContext;
+
+    @Override
+    public final native boolean equals(Object other);
+    @Override
+    public final native int hashCode();
 }
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index f762a05..20d8276 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -16,6 +16,9 @@
 
 package android.os;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
 import java.io.FileDescriptor;
 
 /**
@@ -166,7 +169,7 @@
     /**
      * Get the canonical name of the interface supported by this binder.
      */
-    public String getInterfaceDescriptor() throws RemoteException;
+    public @Nullable String getInterfaceDescriptor() throws RemoteException;
 
     /**
      * Check to see if the object still exists.
@@ -192,7 +195,7 @@
      * to instantiate a proxy class to marshall calls through
      * the transact() method.
      */
-    public IInterface queryLocalInterface(String descriptor);
+    public @Nullable IInterface queryLocalInterface(@NonNull String descriptor);
 
     /**
      * Print the object's state into the given stream.
@@ -200,7 +203,7 @@
      * @param fd The raw file descriptor that the dump is being sent to.
      * @param args additional arguments to the dump request.
      */
-    public void dump(FileDescriptor fd, String[] args) throws RemoteException;
+    public void dump(@NonNull FileDescriptor fd, @Nullable String[] args) throws RemoteException;
 
     /**
      * Like {@link #dump(FileDescriptor, String[])} but always executes
@@ -210,7 +213,8 @@
      * @param fd The raw file descriptor that the dump is being sent to.
      * @param args additional arguments to the dump request.
      */
-    public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException;
+    public void dumpAsync(@NonNull FileDescriptor fd, @Nullable String[] args)
+            throws RemoteException;
 
     /**
      * Execute a shell command on this object.  This may be performed asynchrously from the caller;
@@ -224,9 +228,10 @@
      * @param resultReceiver Called when the command has finished executing, with the result code.
      * @hide
      */
-    public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
-            String[] args, ShellCallback shellCallback,
-            ResultReceiver resultReceiver) throws RemoteException;
+    public void shellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+            @Nullable FileDescriptor err,
+            @NonNull String[] args, @Nullable ShellCallback shellCallback,
+            @NonNull ResultReceiver resultReceiver) throws RemoteException;
 
     /**
      * Perform a generic operation with the object.
@@ -241,8 +246,12 @@
      * null if you are not interested in the return value.
      * @param flags Additional operation flags.  Either 0 for a normal
      * RPC, or {@link #FLAG_ONEWAY} for a one-way RPC.
+     *
+     * @return Returns the result from {@link Binder#onTransact}.  A successful call
+     * generally returns true; false generally means the transaction code was not
+     * understood.
      */
-    public boolean transact(int code, Parcel data, Parcel reply, int flags)
+    public boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags)
         throws RemoteException;
 
     /**
@@ -271,7 +280,7 @@
      * 
      * @see #unlinkToDeath
      */
-    public void linkToDeath(DeathRecipient recipient, int flags)
+    public void linkToDeath(@NonNull DeathRecipient recipient, int flags)
             throws RemoteException;
 
     /**
@@ -292,5 +301,5 @@
      * exception will <em>not</em> be thrown, and you will receive a false
      * return value instead.
      */
-    public boolean unlinkToDeath(DeathRecipient recipient, int flags);
+    public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags);
 }
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index b63e302..66e16a6 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -104,11 +104,6 @@
     void setIPv6AddrGenMode(String iface, int mode);
 
     /**
-     * Enables or enables IPv6 ND offload.
-     */
-    void setInterfaceIpv6NdOffload(String iface, boolean enable);
-
-    /**
      * Add the specified route to the interface.
      */
     void addRoute(int netId, in RouteInfo route);
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index e426356..6746120 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -35,6 +35,10 @@
      * DO NOT MOVE - UserManager.h depends on the ordering of this function.
      */
     int getCredentialOwnerProfile(int userHandle);
+    int getProfileParentId(int userHandle);
+    /*
+     * END OF DO NOT MOVE
+     */
 
     UserInfo createUser(in String name, int flags);
     UserInfo createProfileForUser(in String name, int flags, int userHandle,
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index e20113e..571fbcd 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -295,6 +295,7 @@
     private static native long nativeWriteFileDescriptor(long nativePtr, FileDescriptor val);
 
     private static native byte[] nativeCreateByteArray(long nativePtr);
+    private static native boolean nativeReadByteArray(long nativePtr, byte[] dest, int destLen);
     private static native byte[] nativeReadBlob(long nativePtr);
     @FastNative
     private static native int nativeReadInt(long nativePtr);
@@ -2211,11 +2212,8 @@
      * given byte array.
      */
     public final void readByteArray(byte[] val) {
-        // TODO: make this a native method to avoid the extra copy.
-        byte[] ba = createByteArray();
-        if (ba.length == val.length) {
-           System.arraycopy(ba, 0, val, 0, ba.length);
-        } else {
+        boolean valid = nativeReadByteArray(mNativePtr, val, (val != null) ? val.length : 0);
+        if (!valid) {
             throw new RuntimeException("bad array lengths");
         }
     }
diff --git a/core/java/android/os/ParcelFileDescriptor.aidl b/core/java/android/os/ParcelFileDescriptor.aidl
index 5857aae..6bbd99e 100644
--- a/core/java/android/os/ParcelFileDescriptor.aidl
+++ b/core/java/android/os/ParcelFileDescriptor.aidl
@@ -17,4 +17,4 @@
 
 package android.os;
 
-parcelable ParcelFileDescriptor;
+parcelable ParcelFileDescriptor cpp_header "android/os/parcel_file_descriptor.h";
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index c091420..7f588ad 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -737,7 +737,9 @@
     private void closeWithStatus(int status, String msg) {
         if (mClosed) return;
         mClosed = true;
-        mGuard.close();
+        if (mGuard != null) {
+            mGuard.close();
+        }
         // Status MUST be sent before closing actual descriptor
         writeCommStatusAndClose(status, msg);
         IoUtils.closeQuietly(mFd);
diff --git a/core/java/android/os/ParcelUuid.aidl b/core/java/android/os/ParcelUuid.aidl
index f7e080a..6f36297 100644
--- a/core/java/android/os/ParcelUuid.aidl
+++ b/core/java/android/os/ParcelUuid.aidl
@@ -16,4 +16,4 @@
 
 package android.os;
 
-parcelable ParcelUuid;
+parcelable ParcelUuid cpp_header "android/os/parcel_uuid.h";
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index ae0b885..0874d93 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -19,8 +19,8 @@
 import android.annotation.TestApi;
 import android.system.Os;
 import android.system.OsConstants;
-import android.util.Log;
 import android.webkit.WebViewZygote;
+
 import dalvik.system.VMRuntime;
 
 /**
@@ -151,6 +151,9 @@
      */
     public static final int OTA_UPDATE_UID = 1061;
 
+    /** {@hide} */
+    public static final int NOBODY_UID = 9999;
+
     /**
      * Defines the start of a range of UIDs (and GIDs), going from this
      * number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
@@ -386,6 +389,12 @@
      **/
     public static final int THREAD_GROUP_TOP_APP = 5;
 
+    /**
+     * Thread group for RT app.
+     * @hide
+     **/
+    public static final int THREAD_GROUP_RT_APP = 6;
+
     public static final int SIGNAL_QUIT = 3;
     public static final int SIGNAL_KILL = 9;
     public static final int SIGNAL_USR1 = 10;
@@ -417,7 +426,7 @@
      * 
      * When invokeWith is not null, the process will be started as a fresh app
      * and not a zygote fork. Note that this is only allowed for uid 0 or when
-     * debugFlags contains DEBUG_ENABLE_DEBUGGER.
+     * runtimeFlags contains DEBUG_ENABLE_DEBUGGER.
      *
      * @param processClass The class to use as the process's main entry
      *                     point.
@@ -425,7 +434,7 @@
      * @param uid The user-id under which the process will run.
      * @param gid The group-id under which the process will run.
      * @param gids Additional group-ids associated with the process.
-     * @param debugFlags Additional flags.
+     * @param runtimeFlags Additional flags for the runtime.
      * @param targetSdkVersion The target SDK version for the app.
      * @param seInfo null-ok SELinux information for the new process.
      * @param abi non-null the ABI this app should be started with.
@@ -442,7 +451,7 @@
     public static final ProcessStartResult start(final String processClass,
                                   final String niceName,
                                   int uid, int gid, int[] gids,
-                                  int debugFlags, int mountExternal,
+                                  int runtimeFlags, int mountExternal,
                                   int targetSdkVersion,
                                   String seInfo,
                                   String abi,
@@ -451,7 +460,7 @@
                                   String invokeWith,
                                   String[] zygoteArgs) {
         return zygoteProcess.start(processClass, niceName, uid, gid, gids,
-                    debugFlags, mountExternal, targetSdkVersion, seInfo,
+                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
     }
 
@@ -459,7 +468,7 @@
     public static final ProcessStartResult startWebView(final String processClass,
                                   final String niceName,
                                   int uid, int gid, int[] gids,
-                                  int debugFlags, int mountExternal,
+                                  int runtimeFlags, int mountExternal,
                                   int targetSdkVersion,
                                   String seInfo,
                                   String abi,
@@ -468,7 +477,7 @@
                                   String invokeWith,
                                   String[] zygoteArgs) {
         return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids,
-                    debugFlags, mountExternal, targetSdkVersion, seInfo,
+                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
     }
 
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index db9f28b..673a8ba 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -22,20 +22,26 @@
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
-import android.os.UserManager;
+import android.provider.Settings;
+import android.telephony.euicc.EuiccManager;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Display;
 import android.view.WindowManager;
 
+import com.android.internal.logging.MetricsLogger;
+
 import libcore.io.Streams;
 
-import java.io.ByteArrayInputStream;
 import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -46,22 +52,19 @@
 import java.io.RandomAccessFile;
 import java.security.GeneralSecurityException;
 import java.security.PublicKey;
-import java.security.Signature;
 import java.security.SignatureException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Locale;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import java.util.zip.ZipInputStream;
 
-import com.android.internal.logging.MetricsLogger;
-
 import sun.security.pkcs.PKCS7;
 import sun.security.pkcs.SignerInfo;
 
@@ -84,11 +87,19 @@
     /** Send progress to listeners no more often than this (in ms). */
     private static final long PUBLISH_PROGRESS_INTERVAL_MS = 500;
 
+    private static final long DEFAULT_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 30000L; // 30 s
+
+    private static final long MIN_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 5000L; // 5 s
+
+    private static final long MAX_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 60000L; // 60 s
+
     /** 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_PREFIX = "last_";
+    private static final String ACTION_EUICC_FACTORY_RESET =
+            "com.android.internal.action.EUICC_FACTORY_RESET";
 
     /**
      * The recovery image uses this file to identify the location (i.e. blocks)
@@ -673,18 +684,26 @@
      */
     public static void rebootWipeUserData(Context context) throws IOException {
         rebootWipeUserData(context, false /* shutdown */, context.getPackageName(),
-                false /* force */);
+                false /* force */, false /* wipeEuicc */);
     }
 
     /** {@hide} */
     public static void rebootWipeUserData(Context context, String reason) throws IOException {
-        rebootWipeUserData(context, false /* shutdown */, reason, false /* force */);
+        rebootWipeUserData(context, false /* shutdown */, reason, false /* force */,
+                false /* wipeEuicc */);
     }
 
     /** {@hide} */
     public static void rebootWipeUserData(Context context, boolean shutdown)
             throws IOException {
-        rebootWipeUserData(context, shutdown, context.getPackageName(), false /* force */);
+        rebootWipeUserData(context, shutdown, context.getPackageName(), false /* force */,
+                false /* wipeEuicc */);
+    }
+
+    /** {@hide} */
+    public static void rebootWipeUserData(Context context, boolean shutdown, String reason,
+            boolean force) throws IOException {
+        rebootWipeUserData(context, shutdown, reason, force, false /* wipeEuicc */);
     }
 
     /**
@@ -701,6 +720,7 @@
      * @param reason    the reason for the wipe that is visible in the logs
      * @param force     whether the {@link UserManager.DISALLOW_FACTORY_RESET} user restriction
      *                  should be ignored
+     * @param wipeEuicc whether wipe the euicc data
      *
      * @throws IOException  if writing the recovery command file
      * fails, or if the reboot itself fails.
@@ -709,7 +729,7 @@
      * @hide
      */
     public static void rebootWipeUserData(Context context, boolean shutdown, String reason,
-            boolean force) throws IOException {
+            boolean force, boolean wipeEuicc) throws IOException {
         UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
         if (!force && um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) {
             throw new SecurityException("Wiping data is not allowed for this user.");
@@ -731,6 +751,8 @@
         // Block until the ordered broadcast has completed.
         condition.block();
 
+        wipeEuiccData(context, wipeEuicc);
+
         String shutdownArg = null;
         if (shutdown) {
             shutdownArg = "--shutdown_after";
@@ -745,6 +767,91 @@
         bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg);
     }
 
+    private static void wipeEuiccData(Context context, final boolean isWipeEuicc) {
+        ContentResolver cr = context.getContentResolver();
+        if (Settings.Global.getInt(cr, Settings.Global.EUICC_PROVISIONED, 0) == 0) {
+            // If the eUICC isn't provisioned, there's no reason to either wipe or retain profiles,
+            // as there's nothing to wipe nor retain.
+            Log.d(TAG, "Skipping eUICC wipe/retain as it is not provisioned");
+            return;
+        }
+
+        EuiccManager euiccManager = (EuiccManager) context.getSystemService(
+                Context.EUICC_SERVICE);
+        if (euiccManager != null && euiccManager.isEnabled()) {
+            CountDownLatch euiccFactoryResetLatch = new CountDownLatch(1);
+
+            BroadcastReceiver euiccWipeFinishReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    if (ACTION_EUICC_FACTORY_RESET.equals(intent.getAction())) {
+                        if (getResultCode() != EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
+                            int detailedCode = intent.getIntExtra(
+                                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0);
+                            if (isWipeEuicc) {
+                                Log.e(TAG, "Error wiping euicc data, Detailed code = "
+                                        + detailedCode);
+                            } else {
+                                Log.e(TAG, "Error retaining euicc data, Detailed code = "
+                                        + detailedCode);
+                            }
+                        } else {
+                            if (isWipeEuicc) {
+                                Log.d(TAG, "Successfully wiped euicc data.");
+                            } else {
+                                Log.d(TAG, "Successfully retained euicc data.");
+                            }
+                        }
+                        euiccFactoryResetLatch.countDown();
+                    }
+                }
+            };
+
+            Intent intent = new Intent(ACTION_EUICC_FACTORY_RESET);
+            intent.setPackage("android");
+            PendingIntent callbackIntent = PendingIntent.getBroadcastAsUser(
+                    context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT, UserHandle.SYSTEM);
+            IntentFilter filterConsent = new IntentFilter();
+            filterConsent.addAction(ACTION_EUICC_FACTORY_RESET);
+            HandlerThread euiccHandlerThread = new HandlerThread("euiccWipeFinishReceiverThread");
+            euiccHandlerThread.start();
+            Handler euiccHandler = new Handler(euiccHandlerThread.getLooper());
+            context.getApplicationContext()
+                    .registerReceiver(euiccWipeFinishReceiver, filterConsent, null, euiccHandler);
+            if (isWipeEuicc) {
+                euiccManager.eraseSubscriptions(callbackIntent);
+            } else {
+                euiccManager.retainSubscriptionsForFactoryReset(callbackIntent);
+            }
+            try {
+                long waitingTimeMillis = Settings.Global.getLong(
+                        context.getContentResolver(),
+                        Settings.Global.EUICC_FACTORY_RESET_TIMEOUT_MILLIS,
+                        DEFAULT_EUICC_FACTORY_RESET_TIMEOUT_MILLIS);
+                if (waitingTimeMillis < MIN_EUICC_FACTORY_RESET_TIMEOUT_MILLIS) {
+                    waitingTimeMillis = MIN_EUICC_FACTORY_RESET_TIMEOUT_MILLIS;
+                } else if (waitingTimeMillis > MAX_EUICC_FACTORY_RESET_TIMEOUT_MILLIS) {
+                    waitingTimeMillis = MAX_EUICC_FACTORY_RESET_TIMEOUT_MILLIS;
+                }
+                if (!euiccFactoryResetLatch.await(waitingTimeMillis, TimeUnit.MILLISECONDS)) {
+                    if (isWipeEuicc) {
+                        Log.e(TAG, "Timeout wiping eUICC data.");
+                    } else {
+                        Log.e(TAG, "Timeout retaining eUICC data.");
+                    }
+                }
+                context.getApplicationContext().unregisterReceiver(euiccWipeFinishReceiver);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                if (isWipeEuicc) {
+                    Log.e(TAG, "Wiping eUICC data interrupted", e);
+                } else {
+                    Log.e(TAG, "Retaining eUICC data interrupted", e);
+                }
+            }
+        }
+    }
+
     /** {@hide} */
     public static void rebootPromptAndWipeUserData(Context context, String reason)
             throws IOException {
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
index 2281fb6..b9b9a18 100644
--- a/core/java/android/os/RemoteCallbackList.java
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -19,6 +19,7 @@
 import android.util.ArrayMap;
 import android.util.Slog;
 
+import java.io.PrintWriter;
 import java.util.function.Consumer;
 
 /**
@@ -399,6 +400,13 @@
         }
     }
 
+    /** @hide */
+    public void dump(PrintWriter pw, String prefix) {
+        pw.print(prefix); pw.print("callbacks: "); pw.println(mCallbacks.size());
+        pw.print(prefix); pw.print("killed: "); pw.println(mKilled);
+        pw.print(prefix); pw.print("broadcasts count: "); pw.println(mBroadcastCount);
+    }
+
     private void logExcessiveCallbacks() {
         final long size = mCallbacks.size();
         final long TOO_MANY = 3000;
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 8632194..4f6d322 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -16,6 +16,8 @@
 
 package android.os;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.util.Log;
 import android.util.MutableInt;
 
@@ -43,17 +45,12 @@
 
     public static final int PROP_VALUE_MAX = 91;
 
+    @GuardedBy("sChangeCallbacks")
     private static final ArrayList<Runnable> sChangeCallbacks = new ArrayList<Runnable>();
 
     @GuardedBy("sRoReads")
-    private static final HashMap<String, MutableInt> sRoReads;
-    static {
-        if (TRACK_KEY_ACCESS) {
-            sRoReads = new HashMap<>();
-        } else {
-            sRoReads = null;
-        }
-    }
+    private static final HashMap<String, MutableInt> sRoReads =
+            TRACK_KEY_ACCESS ? new HashMap<>() : null;
 
     private static void onKeyAccess(String key) {
         if (!TRACK_KEY_ACCESS) return;
@@ -85,77 +82,96 @@
     private static native void native_report_sysprop_change();
 
     /**
-     * Get the value for the given key.
-     * @return an empty string if the key isn't found
+     * Get the String value for the given {@code key}.
+     *
+     * @param key the key to lookup
+     * @return an empty string if the {@code key} isn't found
      */
-    public static String get(String key) {
+    @NonNull
+    public static String get(@NonNull String key) {
         if (TRACK_KEY_ACCESS) onKeyAccess(key);
         return native_get(key);
     }
 
     /**
-     * Get the value for the given key.
-     * @return if the key isn't found, return def if it isn't null, or an empty string otherwise
+     * Get the String value for the given {@code key}.
+     *
+     * @param key the key to lookup
+     * @param def the default value in case the property is not set or empty
+     * @return if the {@code key} isn't found, return {@code def} if it isn't null, or an empty
+     * string otherwise
      */
-    public static String get(String key, String def) {
+    @NonNull
+    public static String get(@NonNull String key, @Nullable String def) {
         if (TRACK_KEY_ACCESS) onKeyAccess(key);
         return native_get(key, def);
     }
 
     /**
-     * Get the value for the given key, and return as an integer.
+     * Get the value for the given {@code key}, and return as an integer.
+     *
      * @param key the key to lookup
      * @param def a default value to return
      * @return the key parsed as an integer, or def if the key isn't found or
      *         cannot be parsed
      */
-    public static int getInt(String key, int def) {
+    public static int getInt(@NonNull String key, int def) {
         if (TRACK_KEY_ACCESS) onKeyAccess(key);
         return native_get_int(key, def);
     }
 
     /**
-     * Get the value for the given key, and return as a long.
+     * Get the value for the given {@code key}, and return as a long.
+     *
      * @param key the key to lookup
      * @param def a default value to return
      * @return the key parsed as a long, or def if the key isn't found or
      *         cannot be parsed
      */
-    public static long getLong(String key, long def) {
+    public static long getLong(@NonNull String key, long def) {
         if (TRACK_KEY_ACCESS) onKeyAccess(key);
         return native_get_long(key, def);
     }
 
     /**
-     * Get the value for the given key, returned as a boolean.
+     * Get the value for the given {@code key}, returned as a boolean.
      * Values 'n', 'no', '0', 'false' or 'off' are considered false.
      * Values 'y', 'yes', '1', 'true' or 'on' are considered true.
      * (case sensitive).
      * If the key does not exist, or has any other value, then the default
      * result is returned.
+     *
      * @param key the key to lookup
      * @param def a default value to return
      * @return the key parsed as a boolean, or def if the key isn't found or is
      *         not able to be parsed as a boolean.
      */
-    public static boolean getBoolean(String key, boolean def) {
+    public static boolean getBoolean(@NonNull String key, boolean def) {
         if (TRACK_KEY_ACCESS) onKeyAccess(key);
         return native_get_boolean(key, def);
     }
 
     /**
-     * Set the value for the given key.
-     * @throws IllegalArgumentException if the value exceeds 92 characters
+     * Set the value for the given {@code key} to {@code val}.
+     *
+     * @throws IllegalArgumentException if the {@code val} exceeds 91 characters
      */
-    public static void set(String key, String val) {
-        if (val != null && val.length() > PROP_VALUE_MAX) {
-            throw newValueTooLargeException(key, val);
+    public static void set(@NonNull String key, @Nullable String val) {
+        if (val != null && !val.startsWith("ro.") && val.length() > PROP_VALUE_MAX) {
+            throw new IllegalArgumentException("value of system property '" + key
+                    + "' is longer than " + PROP_VALUE_MAX + " characters: " + val);
         }
         if (TRACK_KEY_ACCESS) onKeyAccess(key);
         native_set(key, val);
     }
 
-    public static void addChangeCallback(Runnable callback) {
+    /**
+     * Add a callback that will be run whenever any system property changes.
+     *
+     * @param callback The {@link Runnable} that should be executed when a system property
+     * changes.
+     */
+    public static void addChangeCallback(@NonNull Runnable callback) {
         synchronized (sChangeCallbacks) {
             if (sChangeCallbacks.size() == 0) {
                 native_add_change_callback();
@@ -164,7 +180,8 @@
         }
     }
 
-    static void callChangeCallbacks() {
+    @SuppressWarnings("unused")  // Called from native code.
+    private static void callChangeCallbacks() {
         synchronized (sChangeCallbacks) {
             //Log.i("foo", "Calling " + sChangeCallbacks.size() + " change callbacks!");
             if (sChangeCallbacks.size() == 0) {
@@ -177,11 +194,6 @@
         }
     }
 
-    private static IllegalArgumentException newValueTooLargeException(String key, String value) {
-        return new IllegalArgumentException("value of system property '" + key + "' is longer than "
-                + PROP_VALUE_MAX + " characters: " + value);
-    }
-
     /*
      * Notifies listeners that a system property has changed
      */
diff --git a/core/java/android/os/TokenWatcher.java b/core/java/android/os/TokenWatcher.java
index 9b3a2d6..00333dad 100644
--- a/core/java/android/os/TokenWatcher.java
+++ b/core/java/android/os/TokenWatcher.java
@@ -16,17 +16,23 @@
 
 package android.os;
 
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.WeakHashMap;
-import java.util.Set;
 import android.util.Log;
 
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.WeakHashMap;
+
 /**
- * Helper class that helps you use IBinder objects as reference counted
- * tokens.  IBinders make good tokens because we find out when they are
- * removed
+ * A TokenWatcher watches a collection of {@link IBinder}s. IBinders are added
+ * to the collection by calling {@link #acquire}, and removed by calling {@link
+ * #release}. IBinders are also implicitly removed when they become weakly
+ * reachable. Each IBinder may be added at most once.
  *
+ * The {@link #acquired} method is invoked by posting to the specified handler
+ * whenever the size of the watched collection becomes nonzero.  The {@link
+ * #released} method is invoked on the specified handler whenever the size of
+ * the watched collection becomes zero.
  */
 public abstract class TokenWatcher
 {
@@ -59,15 +65,23 @@
      * Record that this token has been acquired.  When acquire is called, and
      * the current count is 0, the acquired method is called on the given
      * handler.
-     * 
-     * @param token An IBinder object.  If this token has already been acquired,
-     *              no action is taken.
+     *
+     * Note that the same {@code token} can only be acquired once. If this
+     * {@code token} has already been acquired, no action is taken. The first
+     * subsequent call to {@link #release} will release this {@code token}
+     * immediately.
+     *
+     * @param token An IBinder object.
      * @param tag   A string used by the {@link #dump} method for debugging,
      *              to see who has references.
      */
     public void acquire(IBinder token, String tag)
     {
         synchronized (mTokens) {
+            if (mTokens.containsKey(token)) {
+                return;
+            }
+
             // explicitly checked to avoid bogus sendNotification calls because
             // of the WeakHashMap and the GC
             int oldSize = mTokens.size();
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index 6c01b36..fa96dd3 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -16,6 +16,8 @@
 
 package android.os;
 
+import com.android.internal.os.Zygote;
+
 import dalvik.annotation.optimization.FastNative;
 
 /**
@@ -94,6 +96,8 @@
     // Must be volatile to avoid word tearing.
     private static volatile long sEnabledTags = TRACE_TAG_NOT_READY;
 
+    private static int sZygoteDebugFlags = 0;
+
     private static native long nativeGetEnabledTags();
     private static native void nativeSetAppTracingAllowed(boolean allowed);
     private static native void nativeSetTracingEnabled(boolean allowed);
@@ -118,9 +122,10 @@
         // The system provides ordering through a priority level.  Callbacks made through
         // SystemProperties.addChangeCallback currently have a negative priority, while
         // our native code is using a priority of zero.
-        SystemProperties.addChangeCallback(new Runnable() {
-            @Override public void run() {
-                cacheEnabledTags();
+        SystemProperties.addChangeCallback(() -> {
+            cacheEnabledTags();
+            if ((sZygoteDebugFlags & Zygote.DEBUG_JAVA_DEBUGGABLE) != 0) {
+                traceCounter(TRACE_TAG_ALWAYS, "java_debuggable", 1);
             }
         });
     }
@@ -201,8 +206,9 @@
      *
      * @hide
      */
-    public static void setTracingEnabled(boolean enabled) {
+    public static void setTracingEnabled(boolean enabled, int debugFlags) {
         nativeSetTracingEnabled(enabled);
+        sZygoteDebugFlags = debugFlags;
 
         // Setting whether tracing is enabled may change the tags, so we update the cached tags
         // here.
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 6a4fef2..4c04f78 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -27,6 +27,8 @@
  * Representation of a user on the device.
  */
 public final class UserHandle implements Parcelable {
+    // NOTE: keep logic in sync with system/core/libcutils/multiuser.c
+
     /**
      * @hide Range of uids allocated for a user.
      */
@@ -88,6 +90,19 @@
      */
     public static final boolean MU_ENABLED = true;
 
+    /** @hide */
+    public static final int ERR_GID = -1;
+    /** @hide */
+    public static final int AID_ROOT = android.os.Process.ROOT_UID;
+    /** @hide */
+    public static final int AID_APP_START = android.os.Process.FIRST_APPLICATION_UID;
+    /** @hide */
+    public static final int AID_APP_END = android.os.Process.LAST_APPLICATION_UID;
+    /** @hide */
+    public static final int AID_SHARED_GID_START = android.os.Process.FIRST_SHARED_APPLICATION_GID;
+    /** @hide */
+    public static final int AID_CACHE_GID_START = android.os.Process.FIRST_APPLICATION_CACHE_GID;
+
     final int mHandle;
 
     /**
@@ -192,13 +207,20 @@
         return getUid(userId, Process.SHARED_USER_GID);
     }
 
-    /**
-     * Returns the shared app gid for a given uid or appId.
-     * @hide
-     */
-    public static int getSharedAppGid(int id) {
-        return Process.FIRST_SHARED_APPLICATION_GID + (id % PER_USER_RANGE)
-                - Process.FIRST_APPLICATION_UID;
+    /** @hide */
+    public static int getSharedAppGid(int uid) {
+        return getSharedAppGid(getUserId(uid), getAppId(uid));
+    }
+
+    /** @hide */
+    public static int getSharedAppGid(int userId, int appId) {
+        if (appId >= AID_APP_START && appId <= AID_APP_END) {
+            return (appId - AID_APP_START) + AID_SHARED_GID_START;
+        } else if (appId >= AID_ROOT && appId <= AID_APP_START) {
+            return appId;
+        } else {
+            return -1;
+        }
     }
 
     /**
@@ -214,13 +236,18 @@
         return appId;
     }
 
-    /**
-     * Returns the cache GID for a given UID or appId.
-     * @hide
-     */
-    public static int getCacheAppGid(int id) {
-        return Process.FIRST_APPLICATION_CACHE_GID + (id % PER_USER_RANGE)
-                - Process.FIRST_APPLICATION_UID;
+    /** @hide */
+    public static int getCacheAppGid(int uid) {
+        return getCacheAppGid(getUserId(uid), getAppId(uid));
+    }
+
+    /** @hide */
+    public static int getCacheAppGid(int userId, int appId) {
+        if (appId >= AID_APP_START && appId <= AID_APP_END) {
+            return getUid(userId, (appId - AID_APP_START) + AID_CACHE_GID_START);
+        } else {
+            return -1;
+        }
     }
 
     /**
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a7fc2e7..794b3ba 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -303,10 +303,12 @@
     public static final String DISALLOW_DEBUGGING_FEATURES = "no_debugging_features";
 
     /**
-     * Specifies if a user is disallowed from configuring VPN.
-     * The default value is <code>false</code>.
-     * This restriction has an effect in a managed profile only from
-     * {@link android.os.Build.VERSION_CODES#M}
+     * Specifies if a user is disallowed from configuring a VPN. The default value is
+     * <code>false</code>. This restriction has an effect when set by device owners and, in Android
+     * 6.0 ({@linkplain android.os.Build.VERSION_CODES#M API level 23}) or higher, profile owners.
+     * <p>This restriction also prevents VPNs from starting. However, in Android 7.0
+     * ({@linkplain android.os.Build.VERSION_CODES#N API level 24}) or higher, the system does
+     * start always-on VPNs created by the device or profile owner.
      *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
@@ -389,10 +391,13 @@
     public static final String DISALLOW_ADD_MANAGED_PROFILE = "no_add_managed_profile";
 
     /**
-     * Specifies if a user is disallowed from disabling application verification.
-     * Starting from {@link android.os.Build.VERSION_CODES#O}, application verification
-     * is enforced across all users on the device if a profile owner or device owner sets
-     * this restriction to <code>true</code>. The default value is <code>false</code>.
+     * Specifies if a user is disallowed from disabling application verification. The default
+     * value is <code>false</code>.
+     *
+     * <p>In Android 8.0 ({@linkplain android.os.Build.VERSION_CODES#O API level 26}) and higher,
+     * this is a global user restriction. If a device owner or profile owner sets this restriction,
+     * the system enforces app verification across all users on the device. Running in earlier
+     * Android versions, this restriction affects only the profile that sets it.
      *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
@@ -901,11 +906,8 @@
      * @return the user name
      */
     public String getUserName() {
-        try {
-            return mService.getUserInfo(getUserHandle()).name;
-        } catch (RemoteException re) {
-            throw re.rethrowFromSystemServer();
-        }
+        UserInfo user = getUserInfo(getUserHandle());
+        return user == null ? "" : user.name;
     }
 
     /**
@@ -1458,7 +1460,7 @@
             user = mService.createUser(name, flags);
             // TODO: Keep this in sync with
             // UserManagerService.LocalService.createUserEvenWhenDisallowed
-            if (user != null && !user.isAdmin()) {
+            if (user != null && !user.isAdmin() && !user.isDemo()) {
                 mService.setUserRestriction(DISALLOW_SMS, true, user.id);
                 mService.setUserRestriction(DISALLOW_OUTGOING_CALLS, true, user.id);
             }
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 6aa601a..fe9e8c6 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -16,7 +16,7 @@
 
 package android.os;
 
-import android.hardware.vibrator.V1_0.Constants.Effect;
+import android.hardware.vibrator.V1_1.Constants.Effect_1_1;
 
 import java.util.Arrays;
 
@@ -41,7 +41,7 @@
      * @see #get(int)
      * @hide
      */
-    public static final int EFFECT_CLICK = Effect.CLICK;
+    public static final int EFFECT_CLICK = Effect_1_1.CLICK;
 
     /**
      * A double click effect.
@@ -49,7 +49,14 @@
      * @see #get(int)
      * @hide
      */
-    public static final int EFFECT_DOUBLE_CLICK = Effect.DOUBLE_CLICK;
+    public static final int EFFECT_DOUBLE_CLICK = Effect_1_1.DOUBLE_CLICK;
+
+    /**
+     * A tick effect.
+     * @see #get(int)
+     * @hide
+     */
+    public static final int EFFECT_TICK = Effect_1_1.TICK;
 
     /** @hide to prevent subclassing from outside of the framework */
     public VibrationEffect() { }
@@ -382,9 +389,14 @@
 
         @Override
         public void validate() {
-            if (mEffectId != EFFECT_CLICK) {
-                throw new IllegalArgumentException(
-                        "Unknown prebaked effect type (value=" + mEffectId + ")");
+            switch (mEffectId) {
+                case EFFECT_CLICK:
+                case EFFECT_DOUBLE_CLICK:
+                case EFFECT_TICK:
+                    break;
+                default:
+                    throw new IllegalArgumentException(
+                            "Unknown prebaked effect type (value=" + mEffectId + ")");
             }
         }
 
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 8208438..670f794 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -19,9 +19,12 @@
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
 import android.util.Log;
+import android.util.Slog;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.Zygote;
 import com.android.internal.util.Preconditions;
+
 import java.io.BufferedWriter;
 import java.io.DataInputStream;
 import java.io.IOException;
@@ -172,7 +175,7 @@
      *
      * When invokeWith is not null, the process will be started as a fresh app
      * and not a zygote fork. Note that this is only allowed for uid 0 or when
-     * debugFlags contains DEBUG_ENABLE_DEBUGGER.
+     * runtimeFlags contains DEBUG_ENABLE_DEBUGGER.
      *
      * @param processClass The class to use as the process's main entry
      *                     point.
@@ -180,7 +183,7 @@
      * @param uid The user-id under which the process will run.
      * @param gid The group-id under which the process will run.
      * @param gids Additional group-ids associated with the process.
-     * @param debugFlags Additional flags.
+     * @param runtimeFlags Additional flags.
      * @param targetSdkVersion The target SDK version for the app.
      * @param seInfo null-ok SELinux information for the new process.
      * @param abi non-null the ABI this app should be started with.
@@ -195,7 +198,7 @@
     public final Process.ProcessStartResult start(final String processClass,
                                                   final String niceName,
                                                   int uid, int gid, int[] gids,
-                                                  int debugFlags, int mountExternal,
+                                                  int runtimeFlags, int mountExternal,
                                                   int targetSdkVersion,
                                                   String seInfo,
                                                   String abi,
@@ -205,7 +208,7 @@
                                                   String[] zygoteArgs) {
         try {
             return startViaZygote(processClass, niceName, uid, gid, gids,
-                    debugFlags, mountExternal, targetSdkVersion, seInfo,
+                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
         } catch (ZygoteStartFailedEx ex) {
             Log.e(LOG_TAG,
@@ -316,7 +319,7 @@
      * @param gid a POSIX gid that the new process shuold setgid() to
      * @param gids null-ok; a list of supplementary group IDs that the
      * new process should setgroup() to.
-     * @param debugFlags Additional flags.
+     * @param runtimeFlags Additional flags for the runtime.
      * @param targetSdkVersion The target SDK version for the app.
      * @param seInfo null-ok SELinux information for the new process.
      * @param abi the ABI the process should use.
@@ -330,7 +333,7 @@
                                                       final String niceName,
                                                       final int uid, final int gid,
                                                       final int[] gids,
-                                                      int debugFlags, int mountExternal,
+                                                      int runtimeFlags, int mountExternal,
                                                       int targetSdkVersion,
                                                       String seInfo,
                                                       String abi,
@@ -346,33 +349,7 @@
         argsForZygote.add("--runtime-args");
         argsForZygote.add("--setuid=" + uid);
         argsForZygote.add("--setgid=" + gid);
-        if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {
-            argsForZygote.add("--enable-jni-logging");
-        }
-        if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
-            argsForZygote.add("--enable-safemode");
-        }
-        if ((debugFlags & Zygote.DEBUG_ENABLE_JDWP) != 0) {
-            argsForZygote.add("--enable-jdwp");
-        }
-        if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
-            argsForZygote.add("--enable-checkjni");
-        }
-        if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {
-            argsForZygote.add("--generate-debug-info");
-        }
-        if ((debugFlags & Zygote.DEBUG_ALWAYS_JIT) != 0) {
-            argsForZygote.add("--always-jit");
-        }
-        if ((debugFlags & Zygote.DEBUG_NATIVE_DEBUGGABLE) != 0) {
-            argsForZygote.add("--native-debuggable");
-        }
-        if ((debugFlags & Zygote.DEBUG_JAVA_DEBUGGABLE) != 0) {
-            argsForZygote.add("--java-debuggable");
-        }
-        if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
-            argsForZygote.add("--enable-assert");
-        }
+        argsForZygote.add("--runtime-flags=" + runtimeFlags);
         if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
             argsForZygote.add("--mount-external-default");
         } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
@@ -487,8 +464,8 @@
      * Instructs the zygote to pre-load the classes and native libraries at the given paths
      * for the specified abi. Not all zygotes support this function.
      */
-    public void preloadPackageForAbi(String packagePath, String libsPath, String cacheKey,
-                                     String abi) throws ZygoteStartFailedEx, IOException {
+    public boolean preloadPackageForAbi(String packagePath, String libsPath, String cacheKey,
+                                        String abi) throws ZygoteStartFailedEx, IOException {
         synchronized(mLock) {
             ZygoteState state = openZygoteSocketIfNeeded(abi);
             state.writer.write("4");
@@ -507,6 +484,8 @@
             state.writer.newLine();
 
             state.writer.flush();
+
+            return (state.inputStream.readInt() == 0);
         }
     }
 
@@ -529,4 +508,27 @@
             return (state.inputStream.readInt() == 0);
         }
     }
+
+    /**
+     * Try connecting to the Zygote over and over again until we hit a time-out.
+     * @param socketName The name of the socket to connect to.
+     */
+    public static void waitForConnectionToZygote(String socketName) {
+        for (int n = 20; n >= 0; n--) {
+            try {
+                final ZygoteState zs = ZygoteState.connect(socketName);
+                zs.close();
+                return;
+            } catch (IOException ioe) {
+                Log.w(LOG_TAG,
+                        "Got error connecting to zygote, retrying. msg= " + ioe.getMessage());
+            }
+
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ie) {
+            }
+        }
+        Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket " + socketName);
+    }
 }
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 92f7f31..50855bb 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -293,7 +293,7 @@
     ParcelFileDescriptor openProxyFileDescriptor(int mountPointId, int fileId, int mode) = 74;
     long getCacheQuotaBytes(String volumeUuid, int uid) = 75;
     long getCacheSizeBytes(String volumeUuid, int uid) = 76;
-    long getAllocatableBytes(String volumeUuid, int flags) = 77;
-    void allocateBytes(String volumeUuid, long bytes, int flags) = 78;
+    long getAllocatableBytes(String volumeUuid, int flags, String callingPackage) = 77;
+    void allocateBytes(String volumeUuid, long bytes, int flags, String callingPackage) = 78;
     void secdiscard(in String path) = 79;
 }
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index f42edcd..f2aa113 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1181,7 +1181,7 @@
      *
      * @hide
      */
-    public long getStorageCacheBytes(File path) {
+    public long getStorageCacheBytes(File path, @AllocateFlags int flags) {
         final long cachePercent = Settings.Global.getInt(mResolver,
                 Settings.Global.SYS_STORAGE_CACHE_PERCENTAGE, DEFAULT_CACHE_PERCENTAGE);
         final long cacheBytes = (path.getTotalSpace() * cachePercent) / 100;
@@ -1189,7 +1189,16 @@
         final long maxCacheBytes = Settings.Global.getLong(mResolver,
                 Settings.Global.SYS_STORAGE_CACHE_MAX_BYTES, DEFAULT_CACHE_MAX_BYTES);
 
-        return Math.min(cacheBytes, maxCacheBytes);
+        final long result = Math.min(cacheBytes, maxCacheBytes);
+        if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) {
+            return 0;
+        } else if ((flags & StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED) != 0) {
+            return 0;
+        } else if ((flags & StorageManager.FLAG_ALLOCATE_DEFY_HALF_RESERVED) != 0) {
+            return result / 2;
+        } else {
+            return result;
+        }
     }
 
     /**
@@ -1645,17 +1654,26 @@
     public static final int FLAG_ALLOCATE_AGGRESSIVE = 1 << 0;
 
     /**
-     * Flag indicating that a disk space allocation request should defy any
-     * reserved disk space.
+     * Flag indicating that a disk space allocation request should be allowed to
+     * clear up to all reserved disk space.
      *
      * @hide
      */
-    public static final int FLAG_ALLOCATE_DEFY_RESERVED = 1 << 1;
+    public static final int FLAG_ALLOCATE_DEFY_ALL_RESERVED = 1 << 1;
+
+    /**
+     * Flag indicating that a disk space allocation request should be allowed to
+     * clear up to half of all reserved disk space.
+     *
+     * @hide
+     */
+    public static final int FLAG_ALLOCATE_DEFY_HALF_RESERVED = 1 << 2;
 
     /** @hide */
     @IntDef(flag = true, value = {
             FLAG_ALLOCATE_AGGRESSIVE,
-            FLAG_ALLOCATE_DEFY_RESERVED,
+            FLAG_ALLOCATE_DEFY_ALL_RESERVED,
+            FLAG_ALLOCATE_DEFY_HALF_RESERVED,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface AllocateFlags {}
@@ -1711,7 +1729,8 @@
     public long getAllocatableBytes(@NonNull UUID storageUuid,
             @RequiresPermission @AllocateFlags int flags) throws IOException {
         try {
-            return mStorageManager.getAllocatableBytes(convert(storageUuid), flags);
+            return mStorageManager.getAllocatableBytes(convert(storageUuid), flags,
+                    mContext.getOpPackageName());
         } catch (ParcelableException e) {
             e.maybeRethrow(IOException.class);
             throw new RuntimeException(e);
@@ -1768,7 +1787,8 @@
     public void allocateBytes(@NonNull UUID storageUuid, @BytesLong long bytes,
             @RequiresPermission @AllocateFlags int flags) throws IOException {
         try {
-            mStorageManager.allocateBytes(convert(storageUuid), bytes, flags);
+            mStorageManager.allocateBytes(convert(storageUuid), bytes, flags,
+                    mContext.getOpPackageName());
         } catch (ParcelableException e) {
             e.maybeRethrow(IOException.class);
         } catch (RemoteException e) {
diff --git a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
index 344d947..2931627f 100644
--- a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
+++ b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
@@ -20,7 +20,6 @@
 import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.permission.IRuntimePermissionPresenter;
 import android.content.pm.permission.RuntimePermissionPresentationInfo;
 import android.content.pm.permission.RuntimePermissionPresenter;
@@ -30,6 +29,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteCallback;
+
 import com.android.internal.os.SomeArgs;
 
 import java.util.List;
@@ -72,6 +72,16 @@
      */
     public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(String packageName);
 
+    /**
+     * Revoke the permission {@code permissionName} for app {@code packageName}
+     *
+     * @param packageName The package for which to revoke
+     * @param permissionName The permission to revoke
+     *
+     * @hide
+     */
+    public abstract void onRevokeRuntimePermission(String packageName, String permissionName);
+
     @Override
     public final IBinder onBind(Intent intent) {
         return new IRuntimePermissionPresenter.Stub() {
@@ -83,12 +93,22 @@
                 mHandler.obtainMessage(MyHandler.MSG_GET_APP_PERMISSIONS,
                         args).sendToTarget();
             }
+
+            @Override
+            public void revokeRuntimePermission(String packageName, String permissionName) {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = packageName;
+                args.arg2 = permissionName;
+                mHandler.obtainMessage(MyHandler.MSG_REVOKE_APP_PERMISSION,
+                        args).sendToTarget();
+            }
         };
     }
 
     private final class MyHandler extends Handler {
         public static final int MSG_GET_APP_PERMISSIONS = 1;
         public static final int MSG_GET_APPS_USING_PERMISSIONS = 2;
+        public static final int MSG_REVOKE_APP_PERMISSION = 3;
 
         public MyHandler(Looper looper) {
             super(looper, null, false);
@@ -113,6 +133,14 @@
                         callback.sendResult(null);
                     }
                 } break;
+                case MSG_REVOKE_APP_PERMISSION: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    String packageName = (String) args.arg1;
+                    String permissionName = (String) args.arg2;
+                    args.recycle();
+
+                    onRevokeRuntimePermission(packageName, permissionName);
+                } break;
             }
         }
     }
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 2179bd4..4306bc4 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -934,6 +934,7 @@
      * @param singleLineTitle set {@code true} if the title should be constrained to one line
      */
     public void setSingleLineTitle(boolean singleLineTitle) {
+        mHasSingleLineTitleAttr = true;
         mSingleLineTitle = singleLineTitle;
         notifyChanged();
     }
diff --git a/core/java/android/provider/AlarmClock.java b/core/java/android/provider/AlarmClock.java
index d921ed4..f903012 100644
--- a/core/java/android/provider/AlarmClock.java
+++ b/core/java/android/provider/AlarmClock.java
@@ -82,7 +82,8 @@
      * If neither of the above are given then:
      * <ul>
      * <li>If exactly one active alarm exists, it is dismissed.
-     * <li>If more than one active alarm exists, the user is prompted to choose the alarm to dismiss.
+     * <li>If more than one active alarm exists, the user is prompted to choose the alarm to
+     * dismiss.
      * </ul>
      * </p><p>
      * If the extra {@link #EXTRA_ALARM_SEARCH_MODE} is used, and the search results contain two or
@@ -104,8 +105,7 @@
      * @see #EXTRA_ALARM_SEARCH_MODE
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_DISMISS_ALARM =
-            "android.intent.action.DISMISS_ALARM";
+    public static final String ACTION_DISMISS_ALARM = "android.intent.action.DISMISS_ALARM";
 
     /**
      * Activity Action: Snooze a currently ringing alarm.
@@ -124,8 +124,7 @@
      * @see #EXTRA_ALARM_SNOOZE_DURATION
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_SNOOZE_ALARM =
-            "android.intent.action.SNOOZE_ALARM";
+    public static final String ACTION_SNOOZE_ALARM = "android.intent.action.SNOOZE_ALARM";
 
     /**
      * Activity Action: Set a timer.
@@ -155,6 +154,16 @@
     public static final String ACTION_SET_TIMER = "android.intent.action.SET_TIMER";
 
     /**
+     * Activity Action: Dismiss timers.
+     * <p>
+     * Dismiss all currently expired timers. If there are no expired timers, then this is a no-op.
+     * </p>
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_DISMISS_TIMER = "android.intent.action.DISMISS_TIMER";
+
+    /**
      * Activity Action: Show the timers.
      * <p>
      * This action opens the timers page.
@@ -200,8 +209,7 @@
      * @see #ALARM_SEARCH_MODE_LABEL
      * @see #ACTION_DISMISS_ALARM
      */
-    public static final String EXTRA_ALARM_SEARCH_MODE =
-        "android.intent.extra.alarm.SEARCH_MODE";
+    public static final String EXTRA_ALARM_SEARCH_MODE = "android.intent.extra.alarm.SEARCH_MODE";
 
     /**
      * Search for the alarm that is most closely matched by the search parameters
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
old mode 100755
new mode 100644
index a82127c..df944fd
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -194,6 +194,24 @@
             "android.settings.AIRPLANE_MODE_SETTINGS";
 
     /**
+     * Activity Action: Show mobile data usage list.
+     * <p>
+     * Input: {@link EXTRA_NETWORK_TEMPLATE} and {@link EXTRA_SUB_ID} should be included to specify
+     * how and what mobile data statistics should be collected.
+     * <p>
+     * Output: Nothing
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_MOBILE_DATA_USAGE =
+            "android.settings.MOBILE_DATA_USAGE";
+
+    /** @hide */
+    public static final String EXTRA_NETWORK_TEMPLATE = "network_template";
+    /** @hide */
+    public static final String EXTRA_SUB_ID = "sub_id";
+
+    /**
      * Activity Action: Modify Airplane mode settings using a voice command.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you safeguard against this.
@@ -410,6 +428,21 @@
             "android.settings.BLUETOOTH_SETTINGS";
 
     /**
+     * Activity Action: Show settings to allow configuration of Assist Gesture.
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you
+     * safeguard against this.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_ASSIST_GESTURE_SETTINGS =
+            "android.settings.ASSIST_GESTURE_SETTINGS";
+
+    /**
      * Activity Action: Show settings to allow configuration of cast endpoints.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
@@ -1422,10 +1455,10 @@
      * to the caller package.
      *
      * <p>
-     * <b>NOTE: </b> applications should call
+     * <b>NOTE: </b> Applications should call
      * {@link android.view.autofill.AutofillManager#hasEnabledAutofillServices()} and
-     * {@link android.view.autofill.AutofillManager#isAutofillSupported()} first, and only
-     * broadcast this intent if they return {@code false} and {@code true} respectively.
+     * {@link android.view.autofill.AutofillManager#isAutofillSupported()}, and only use this action
+     * to start an activity if they return {@code false} and {@code true} respectively.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_REQUEST_SET_AUTOFILL_SERVICE =
@@ -1734,6 +1767,10 @@
             return true;
         }
 
+        public int getCurrentGeneration() {
+            return mCurrentGeneration;
+        }
+
         private int readCurrentGeneration() {
             try {
                 return mArray.get(mIndex);
@@ -1779,6 +1816,12 @@
                 return mContentProvider;
             }
         }
+
+        public void clearProviderForTest() {
+            synchronized (mLock) {
+                mContentProvider = null;
+            }
+        }
     }
 
     // Thread-safe.
@@ -1836,6 +1879,7 @@
 
         public String getStringForUser(ContentResolver cr, String name, final int userHandle) {
             final boolean isSelf = (userHandle == UserHandle.myUserId());
+            int currentGeneration = -1;
             if (isSelf) {
                 synchronized (NameValueCache.this) {
                     if (mGenerationTracker != null) {
@@ -1849,6 +1893,9 @@
                         } else if (mValues.containsKey(name)) {
                             return mValues.get(name);
                         }
+                        if (mGenerationTracker != null) {
+                            currentGeneration = mGenerationTracker.getCurrentGeneration();
+                        }
                     }
                 }
             } else {
@@ -1939,7 +1986,10 @@
                                         });
                                     }
                                 }
-                                mValues.put(name, value);
+                                if (mGenerationTracker != null && currentGeneration ==
+                                        mGenerationTracker.getCurrentGeneration()) {
+                                    mValues.put(name, value);
+                                }
                             }
                         } else {
                             if (LOCAL_LOGV) Log.i(TAG, "call-query of user " + userHandle
@@ -1980,7 +2030,10 @@
 
                 String value = c.moveToNext() ? c.getString(0) : null;
                 synchronized (NameValueCache.this) {
-                    mValues.put(name, value);
+                    if(mGenerationTracker != null &&
+                            currentGeneration == mGenerationTracker.getCurrentGeneration()) {
+                        mValues.put(name, value);
+                    }
                 }
                 if (LOCAL_LOGV) {
                     Log.v(TAG, "cache miss [" + mUri.getLastPathSegment() + "]: " +
@@ -1994,6 +2047,16 @@
                 if (c != null) c.close();
             }
         }
+
+        public void clearGenerationTrackerForTest() {
+            synchronized (NameValueCache.this) {
+                if (mGenerationTracker != null) {
+                    mGenerationTracker.destroy();
+                }
+                mValues.clear();
+                mGenerationTracker = null;
+            }
+        }
     }
 
     /**
@@ -2182,6 +2245,12 @@
             outKeySet.addAll(MOVED_TO_GLOBAL);
         }
 
+        /** @hide */
+        public static void clearProviderForTest() {
+            sProviderHolder.clearProviderForTest();
+            sNameValueCache.clearGenerationTrackerForTest();
+        }
+
         /**
          * Look up a name in the database.
          * @param resolver to access the database with
@@ -4595,6 +4664,12 @@
             outKeySet.addAll(MOVED_TO_GLOBAL);
         }
 
+        /** @hide */
+        public static void clearProviderForTest() {
+            sProviderHolder.clearProviderForTest();
+            sNameValueCache.clearGenerationTrackerForTest();
+        }
+
         /**
          * Look up a name in the database.
          * @param resolver to access the database with
@@ -6472,6 +6547,12 @@
         public static final String DOZE_PULSE_ON_PICK_UP = "doze_pulse_on_pick_up";
 
         /**
+         * Whether the device should pulse on long press gesture.
+         * @hide
+         */
+        public static final String DOZE_PULSE_ON_LONG_PRESS = "doze_pulse_on_long_press";
+
+        /**
          * Whether the device should pulse on double tap gesture.
          * @hide
          */
@@ -6755,6 +6836,21 @@
                 "camera_double_twist_to_flip_enabled";
 
         /**
+         * Whether or not the smart camera lift trigger that launches the camera when the user moves
+         * the phone into a position for taking photos should be enabled.
+         *
+         * @hide
+         */
+        public static final String CAMERA_LIFT_TRIGGER_ENABLED = "camera_lift_trigger_enabled";
+
+        /**
+         * The default enable state of the camera lift trigger.
+         *
+         * @hide
+         */
+        public static final int CAMERA_LIFT_TRIGGER_ENABLED_DEFAULT = 1;
+
+        /**
          * Whether the assist gesture should be enabled.
          *
          * @hide
@@ -6769,6 +6865,29 @@
         public static final String ASSIST_GESTURE_SENSITIVITY = "assist_gesture_sensitivity";
 
         /**
+         * Whether the assist gesture should silence alerts.
+         *
+         * @hide
+         */
+        public static final String ASSIST_GESTURE_SILENCE_ALERTS_ENABLED =
+                "assist_gesture_silence_alerts_enabled";
+
+        /**
+         * Whether the assist gesture should wake the phone.
+         *
+         * @hide
+         */
+        public static final String ASSIST_GESTURE_WAKE_ENABLED =
+                "assist_gesture_wake_enabled";
+
+        /**
+         * Whether Assist Gesture Deferred Setup has been completed
+         *
+         * @hide
+         */
+        public static final String ASSIST_GESTURE_SETUP_COMPLETE = "assist_gesture_setup_complete";
+
+        /**
          * Control whether Night display is currently activated.
          * @hide
          */
@@ -6908,6 +7027,16 @@
                 "automatic_storage_manager_last_run";
 
         /**
+         * If the automatic storage manager has been disabled by policy. Note that this doesn't
+         * mean that the automatic storage manager is prevented from being re-enabled -- this only
+         * means that it was turned off by policy at least once.
+         *
+         * @hide
+         */
+        public static final String AUTOMATIC_STORAGE_MANAGER_TURNED_OFF_BY_POLICY =
+                "automatic_storage_manager_turned_off_by_policy";
+
+        /**
          * Whether SystemUI navigation keys is enabled.
          * @hide
          */
@@ -6963,6 +7092,12 @@
         public static final String NOTIFICATION_BADGING = "notification_badging";
 
         /**
+         * Comma separated list of QS tiles that have been auto-added already.
+         * @hide
+         */
+        public static final String QS_AUTO_ADDED_TILES = "qs_auto_tiles";
+
+        /**
          * This are the settings to be backed up.
          *
          * NOTE: Settings are backed up and restored in the order they appear
@@ -7043,8 +7178,6 @@
             NIGHT_DISPLAY_CUSTOM_END_TIME,
             NIGHT_DISPLAY_COLOR_TEMPERATURE,
             NIGHT_DISPLAY_AUTO_MODE,
-            NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
-            NIGHT_DISPLAY_ACTIVATED,
             SYNC_PARENT_SOUNDS,
             CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
             CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
@@ -7057,8 +7190,16 @@
             AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
             ASSIST_GESTURE_ENABLED,
             ASSIST_GESTURE_SENSITIVITY,
+            ASSIST_GESTURE_SETUP_COMPLETE,
+            ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,
+            ASSIST_GESTURE_WAKE_ENABLED,
             VR_DISPLAY_MODE,
-            NOTIFICATION_BADGING
+            NOTIFICATION_BADGING,
+            QS_AUTO_ADDED_TILES,
+            SCREENSAVER_ENABLED,
+            SCREENSAVER_COMPONENTS,
+            SCREENSAVER_ACTIVATE_ON_DOCK,
+            SCREENSAVER_ACTIVATE_ON_SLEEP,
         };
 
         /**
@@ -7389,6 +7530,13 @@
         public static final String AIRPLANE_MODE_TOGGLEABLE_RADIOS = "airplane_mode_toggleable_radios";
 
         /**
+         * An integer representing the Bluetooth Class of Device (CoD).
+         *
+         * @hide
+         */
+        public static final String BLUETOOTH_CLASS_OF_DEVICE = "bluetooth_class_of_device";
+
+        /**
          * A Long representing a bitmap of profiles that should be disabled when bluetooth starts.
          * See {@link android.bluetooth.BluetoothProfile}.
          * {@hide}
@@ -7640,6 +7788,31 @@
        public static final String FORCE_ALLOW_ON_EXTERNAL = "force_allow_on_external";
 
         /**
+         * The default SM-DP+ configured for this device.
+         *
+         * <p>An SM-DP+ is used by an LPA (see {@link android.service.euicc.EuiccService}) to
+         * download profiles. If this value is set, the LPA will query this server for any profiles
+         * available to this device. If any are available, they may be downloaded during device
+         * provisioning or in settings without needing the user to enter an activation code.
+         *
+         * @see android.service.euicc.EuiccService
+         * @hide
+         *
+         * TODO(b/35851809): Make this a SystemApi.
+         */
+        public static final String DEFAULT_SM_DP_PLUS = "default_sm_dp_plus";
+
+        /**
+         * Whether any profile has ever been downloaded onto a eUICC on the device.
+         *
+         * <p>Used to hide eUICC UI from users who have never made use of it and would only be
+         * confused by seeing references to it in settings.
+         * (0 = false, 1 = true)
+         * @hide
+         */
+        public static final String EUICC_PROVISIONED = "euicc_provisioned";
+
+        /**
          * Whether any activity can be resized. When this is true, any
          * activity, regardless of manifest values, can be resized for multi-window.
          * (0 = false, 1 = true)
@@ -9002,6 +9175,22 @@
          */
         public static final String DEFAULT_DNS_SERVER = "default_dns_server";
 
+        /**
+         * The requested Private DNS mode (string), and an accompanying specifier (string).
+         *
+         * Currently, the specifier holds the chosen provider name when the mode requests
+         * a specific provider. It may be used to store the provider name even when the
+         * mode changes so that temporarily disabling and re-enabling the specific
+         * provider mode does not necessitate retyping the provider hostname.
+         *
+         * @hide
+         */
+        public static final String PRIVATE_DNS_MODE = "private_dns_mode";
+        /**
+         * @hide
+         */
+        public static final String PRIVATE_DNS_SPECIFIER = "private_dns_specifier";
+
         /** {@hide} */
         public static final String
                 BLUETOOTH_HEADSET_PRIORITY_PREFIX = "bluetooth_headset_priority_";
@@ -9142,6 +9331,23 @@
         public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants";
 
         /**
+         * Battery anomaly detection specific settings
+         * This is encoded as a key=value list, separated by commas. Ex:
+         *
+         * "anomaly_detection_enabled=true,wakelock_threshold=2000"
+         *
+         * The following keys are supported:
+         *
+         * <pre>
+         * anomaly_detection_enabled       (boolean)
+         * wakelock_enabled                (boolean)
+         * wakelock_threshold              (long)
+         * </pre>
+         * @hide
+         */
+        public static final String ANOMALY_DETECTION_CONSTANTS = "anomaly_detection_constants";
+
+        /**
          * App standby (app idle) specific settings.
          * This is encoded as a key=value list, separated by commas. Ex:
          *
@@ -9326,7 +9532,7 @@
          * Get the key that retrieves a bluetooth Input Device's priority.
          * @hide
          */
-        public static final String getBluetoothInputDevicePriorityKey(String address) {
+        public static final String getBluetoothHidHostPriorityKey(String address) {
             return BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT);
         }
 
@@ -9758,7 +9964,8 @@
         public static final String REQUIRE_PASSWORD_TO_DECRYPT = "require_password_to_decrypt";
 
         /**
-         * Whether the Volte is enabled
+         * Whether the Volte is enabled. If this setting is not set then we use the Carrier Config
+         * value {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
          * <p>
          * Type: int (0 for false, 1 for true)
          * @hide
@@ -9929,22 +10136,6 @@
         public static final String DEVICE_DEMO_MODE = "device_demo_mode";
 
         /**
-         * Retail mode specific settings. This is encoded as a key=value list, separated by commas.
-         * Ex: "user_inactivity_timeout_ms=30000,warning_dialog_timeout_ms=10000". The following
-         * keys are supported:
-         *
-         * <pre>
-         * user_inactivity_timeout_ms  (long)
-         * warning_dialog_timeout_ms   (long)
-         * </pre>
-         * <p>
-         * Type: string
-         *
-         * @hide
-         */
-        public static final String RETAIL_DEMO_MODE_CONSTANTS = "retail_demo_mode_constants";
-
-        /**
          * Indicates the maximum time that an app is blocked for the network rules to get updated.
          *
          * Type: long
@@ -9990,6 +10181,23 @@
                 "location_settings_link_to_permissions_enabled";
 
         /**
+         * Flag to enable use of RefactoredBackupManagerService.
+         *
+         * @hide
+         */
+        public static final String BACKUP_REFACTORED_SERVICE_DISABLED =
+            "backup_refactored_service_disabled";
+
+        /**
+         * Flag to set the waiting time for euicc factory reset inside System > Settings
+         * Type: long
+         *
+         * @hide
+         */
+        public static final String EUICC_FACTORY_RESET_TIMEOUT_MILLIS =
+                "euicc_factory_reset_timeout_millis";
+
+        /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
          *
@@ -10024,7 +10232,9 @@
             DOCK_AUDIO_MEDIA_ENABLED,
             ENCODED_SURROUND_OUTPUT,
             LOW_POWER_MODE_TRIGGER_LEVEL,
-            BLUETOOTH_ON
+            BLUETOOTH_ON,
+            PRIVATE_DNS_MODE,
+            PRIVATE_DNS_SPECIFIER
         };
 
         private static final ContentProviderHolder sProviderHolder =
@@ -10049,6 +10259,12 @@
             outKeySet.addAll(MOVED_TO_SECURE);
         }
 
+        /** @hide */
+        public static void clearProviderForTest() {
+            sProviderHolder.clearProviderForTest();
+            sNameValueCache.clearGenerationTrackerForTest();
+        }
+
         /**
          * Look up a name in the database.
          * @param resolver to access the database with
@@ -10506,7 +10722,7 @@
         /**
          * The maximum allowed notification enqueue rate in Hertz.
          *
-         * Should be a float, and includes both posts and updates.
+         * Should be a float, and includes updates only.
          * @hide
          */
         public static final String MAX_NOTIFICATION_ENQUEUE_RATE = "max_notification_enqueue_rate";
@@ -10569,6 +10785,13 @@
          */
         public static final String ENABLE_CACHE_QUOTA_CALCULATION =
                 "enable_cache_quota_calculation";
+
+        /**
+         * Whether the Deletion Helper no threshold toggle is available.
+         * @hide
+         */
+        public static final String ENABLE_DELETION_HELPER_NO_THRESHOLD_TOGGLE =
+                "enable_deletion_helper_no_threshold_toggle";
     }
 
     /**
diff --git a/core/java/android/security/IKeystoreService.aidl b/core/java/android/security/IKeystoreService.aidl
index bfc8636c..42282ac 100644
--- a/core/java/android/security/IKeystoreService.aidl
+++ b/core/java/android/security/IKeystoreService.aidl
@@ -48,7 +48,7 @@
     byte[] sign(String name, in byte[] data);
     int verify(String name, in byte[] data, in byte[] signature);
     byte[] get_pubkey(String name);
-    int grant(String name, int granteeUid);
+    String grant(String name, int granteeUid);
     int ungrant(String name, int granteeUid);
     long getmtime(String name, int uid);
     int duplicate(String srcKey, int srcUid, String destKey, int destUid);
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index a80ef03..53b49f0 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -179,11 +179,18 @@
  * should not contain fields for username, password, and credit card information. The reason for
  * this rule is that a malicious app could draft a view structure where the credit card fields
  * are not visible, so when the user selects a dataset from the username UI, the credit card info is
- * released to the application without the user knowledge. Similar, it's recommended to always
+ * released to the application without the user knowledge. Similarly, it's recommended to always
  * protect a dataset that contains sensitive information by requiring dataset authentication
- * (see {@link Dataset.Builder#setAuthentication(android.content.IntentSender)}).
+ * (see {@link Dataset.Builder#setAuthentication(android.content.IntentSender)}), and to include
+ * info about the "primary" field of the partition in the custom presentation for "secondary"
+ * fields &mdash; that would prevent a malicious app from getting the "primary" fields without the
+ * user realizing they're being released (for example, a malicious app could have fields for a
+ * credit card number, verification code, and expiration date crafted in a way that just the latter
+ * is visible; by explicitly indicating the expiration date is related to a given credit card
+ * number, the service would be providing a visual clue for the users to check what would be
+ * released upon selecting that field).
  *
- * <p>When the service detects that a screen have multiple partitions, it should return a
+ * <p>When the service detects that a screen has multiple partitions, it should return a
  * {@link FillResponse} with just the datasets for the partition that originated the request (i.e.,
  * the partition that has the {@link android.app.assist.AssistStructure.ViewNode} whose
  * {@link android.app.assist.AssistStructure.ViewNode#isFocused()} returns {@code true}); then if
@@ -236,6 +243,36 @@
  * <p>When the service returns multiple {@link FillResponse}, the last one overrides the previous;
  * that's why the {@link SaveInfo} in the 2nd request above has the info for both partitions.
  *
+ * <h3>Package verification</h3>
+ *
+ * <p>When autofilling app-specific data (like username and password), the service must verify
+ * the authenticity of the request by obtaining all signing certificates of the app being
+ * autofilled, and only fulfilling the request when they match the values that were
+ * obtained when the data was first saved &mdash; such verification is necessary to avoid phishing
+ * attempts by apps that were sideloaded in the device with the same package name of another app.
+ * Here's an example on how to achieve that by hashing the signing certificates:
+ *
+ * <pre class="prettyprint">
+ * private String getCertificatesHash(String packageName) throws Exception {
+ *   PackageManager pm = mContext.getPackageManager();
+ *   PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+ *   ArrayList<String> hashes = new ArrayList<>(info.signatures.length);
+ *   for (Signature sig : info.signatures) {
+ *     byte[] cert = sig.toByteArray();
+ *     MessageDigest md = MessageDigest.getInstance("SHA-256");
+ *     md.update(cert);
+ *     hashes.add(toHexString(md.digest()));
+ *   }
+ *   Collections.sort(hashes);
+ *   StringBuilder hash = new StringBuilder();
+ *   for (int i = 0; i < hashes.size(); i++) {
+ *     hash.append(hashes.get(i));
+ *   }
+ *   return hash.toString();
+ * }
+ *
+ * </pre>
+ *
  * <h3>Ignoring views</h3>
  *
  * <p>If the service find views that cannot be autofilled (for example, a text field representing
@@ -243,6 +280,76 @@
  * calling {@link FillResponse.Builder#setIgnoredIds(AutofillId...)} so the system does not trigger
  * a new {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} when these views are
  * focused.
+ *
+ * <h3>Web security</h3>
+ *
+ * <p>When handling autofill requests that represent web pages (typically
+ * view structures whose root's {@link android.app.assist.AssistStructure.ViewNode#getClassName()}
+ * is a {@link android.webkit.WebView}), the service should take the following steps to verify if
+ * the structure can be autofilled with the data associated with the app requesting it:
+ *
+ * <ol>
+ *   <li>Use the {@link android.app.assist.AssistStructure.ViewNode#getWebDomain()} to get the
+ *       source of the document.
+ *   <li>Get the canonical domain using the
+ *       <a href="https://publicsuffix.org/>Public Suffix List</a> (see example below).
+ *   <li>Use <a href="https://developers.google.com/digital-asset-links/">Digital Asset Links</a>
+ *       to obtain the package name and certificate fingerprint of the package corresponding to
+ *       the canonical domain.
+ *   <li>Make sure the certificate fingerprint matches the value returned by Package Manager
+ *       (see "Package verification" section above).
+ * </ol>
+ *
+ * <p>Here's an example on how to get the canonical domain using
+ * <a href="https://github.com/google/guava">Guava</a>:
+ *
+ * <pre class="prettyprint">
+ * private static String getCanonicalDomain(String domain) {
+ *   InternetDomainName idn = InternetDomainName.from(domain);
+ *   while (!idn.isTopPrivateDomain() && idn != null) {
+ *     idn = idn.parent();
+ *   }
+ *   return idn == null ? null : idn.toString();
+ * }
+ * </pre>
+ *
+ * <p>If the association between the web domain and app package cannot be verified through the steps
+ * above, the service can still autofill the app, but it should warn the user about the potential
+ * data leakage first, and askfor the user to confirm. For example, the service could:
+ *
+ * <ol>
+ *   <li>Create a dataset that requires
+ *       {@link Dataset.Builder#setAuthentication(android.content.IntentSender) authentication} to
+ *       unlock.
+ *   <li>Include the web domain in the custom presentation for the
+ *       {@link Dataset.Builder#setValue(AutofillId, AutofillValue, android.widget.RemoteViews)
+ *       dataset value}.
+ *   <li>When the user select that dataset, show a disclaimer dialog explaining that the app is
+ *       requesting credentials for a web domain, but the service could not verify if the app owns
+ *       that domain. If the user agrees, then the service can unlock the dataset.
+ *   <li>Similarly, when adding a {@link SaveInfo} object for the request, the service should
+ *       include the above disclaimer in the {@link SaveInfo.Builder#setDescription(CharSequence)}.
+ * </ol>
+ *
+ * <p>This same procedure could also be used when the autofillable data is contained inside an
+ * {@code IFRAME}, in which case the WebView generates a new autofill context when a node inside
+ * the {@code IFRAME} is focused, which the root node containing the {@code IFRAME}'s {@code src}
+ * attribute on {@link android.app.assist.AssistStructure.ViewNode#getWebDomain()}. A typical and
+ * legitimate use case for this scenario is a financial app that allows the user
+ * to login on different bank accounts. For example, a financial app {@code my_financial_app} could
+ * use a WebView that loads contents from {@code banklogin.my_financial_app.com}, which contains an
+ * {@code IFRAME} node whose {@code src} attribute is {@code login.some_bank.com}. When fulfilling
+ * that request, the service could add an
+ * {@link Dataset.Builder#setAuthentication(android.content.IntentSender) authenticated dataset}
+ * whose presentation displays "Username for some_bank.com" and
+ * "Password for some_bank.com". Then when the user taps one of these options, the service
+ * shows the disclaimer dialog explaining that selecting that option would release the
+ * {@code login.some_bank.com} credentials to the {@code my_financial_app}; if the user agrees,
+ * then the service returns an unlocked dataset with the {@code some_bank.com} credentials.
+ *
+ * <p><b>Note:</b> The autofill service could also whitelist well-known browser apps and skip the
+ * verifications above, as long as the service can verify the authenticity of the browser app by
+ * checking its signing certificate.
  */
 public abstract class AutofillService extends Service {
     private static final String TAG = "AutofillService";
@@ -387,7 +494,7 @@
      * {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)})
      * to notify the result of the request.
      *
-     * <p><b>NOTE: </b>to retrieve the actual value of the field, the service should call
+     * <p><b>Note:</b> To retrieve the actual value of the field, the service should call
      * {@link android.app.assist.AssistStructure.ViewNode#getAutofillValue()}; if it calls
      * {@link android.app.assist.AssistStructure.ViewNode#getText()} or other methods, there is no
      * guarantee such method will return the most recent value of the field.
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index e13fdf6..80ef3aa 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -205,6 +205,13 @@
         /**
          * Adds a new {@link Dataset} to this response.
          *
+         * <p><b>Note: </b> the total number of datasets is limited by the Binder transaction size,
+         * so it's recommended to keep it small (in the range of 10-20 at most) and use pagination
+         * by adding a fake
+         * {@link Dataset.Builder#setAuthentication(IntentSender) authenticated dataset}
+         * at the end with a presentation string like "Next 10" that would return a new
+         * {@link FillResponse} with the next 10 datasets, and so on.
+         *
          * @return This builder.
          */
         public @NonNull Builder addDataset(@Nullable Dataset dataset) {
diff --git a/core/java/android/service/euicc/EuiccProfileInfo.java b/core/java/android/service/euicc/EuiccProfileInfo.java
new file mode 100644
index 0000000..ba6c9a2
--- /dev/null
+++ b/core/java/android/service/euicc/EuiccProfileInfo.java
@@ -0,0 +1,84 @@
+/*
+ * 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.service.euicc;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.UiccAccessRule;
+import android.text.TextUtils;
+
+/**
+ * Information about an embedded profile (subscription) on an eUICC.
+ *
+ * @hide
+ *
+ * TODO(b/35851809): Make this a SystemApi.
+ */
+public final class EuiccProfileInfo implements Parcelable {
+
+    /** The iccid of the subscription. */
+    public final String iccid;
+
+    /**
+     * Optional access rules defining which apps can manage this subscription. If unset, only the
+     * platform can manage it.
+     */
+    public final @Nullable UiccAccessRule[] accessRules;
+
+    /** An optional nickname for the subscription. */
+    public final @Nullable String nickname;
+
+    public static final Creator<EuiccProfileInfo> CREATOR = new Creator<EuiccProfileInfo>() {
+        @Override
+        public EuiccProfileInfo createFromParcel(Parcel in) {
+            return new EuiccProfileInfo(in);
+        }
+
+        @Override
+        public EuiccProfileInfo[] newArray(int size) {
+            return new EuiccProfileInfo[size];
+        }
+    };
+
+    public EuiccProfileInfo(String iccid, @Nullable UiccAccessRule[] accessRules,
+            @Nullable String nickname) {
+        if (!TextUtils.isDigitsOnly(iccid)) {
+            throw new IllegalArgumentException("iccid contains invalid characters: " + iccid);
+        }
+        this.iccid = iccid;
+        this.accessRules = accessRules;
+        this.nickname = nickname;
+    }
+
+    private EuiccProfileInfo(Parcel in) {
+        iccid = in.readString();
+        accessRules = in.createTypedArray(UiccAccessRule.CREATOR);
+        nickname = in.readString();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(iccid);
+        dest.writeTypedArray(accessRules, flags);
+        dest.writeString(nickname);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java
new file mode 100644
index 0000000..0c2e4b7
--- /dev/null
+++ b/core/java/android/service/euicc/EuiccService.java
@@ -0,0 +1,523 @@
+/*
+ * 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.service.euicc;
+
+import android.annotation.CallSuper;
+import android.annotation.Nullable;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.telephony.euicc.DownloadableSubscription;
+import android.telephony.euicc.EuiccInfo;
+import android.util.ArraySet;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Service interface linking the system with an eUICC local profile assistant (LPA) application.
+ *
+ * <p>An LPA consists of two separate components (which may both be implemented in the same APK):
+ * the LPA backend, and the LPA UI or LUI.
+ *
+ * <p>To implement the LPA backend, you must extend this class and declare this service in your
+ * manifest file. The service must require the
+ * {@link android.Manifest.permission#BIND_EUICC_SERVICE} permission and include an intent filter
+ * with the {@link #EUICC_SERVICE_INTERFACE} action. The priority of the intent filter must be set
+ * to a non-zero value in case multiple implementations are present on the device. For example:
+ *
+ * <pre>{@code
+ * <service android:name=".MyEuiccService"
+ *          android:permission="android.permission.BIND_EUICC_SERVICE">
+ *     <intent-filter android:priority="100">
+ *         <action android:name="android.service.euicc.EuiccService" />
+ *     </intent-filter>
+ * </service>
+ * }</pre>
+ *
+ * <p>To implement the LUI, you must provide an activity for the following actions:
+ *
+ * <ul>
+ * <li>{@link #ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS}
+ * <li>{@link #ACTION_PROVISION_EMBEDDED_SUBSCRIPTION}
+ * </ul>
+ *
+ * <p>As with the service, each activity must require the
+ * {@link android.Manifest.permission#BIND_EUICC_SERVICE} permission. Each should have an intent
+ * filter with the appropriate action, the {@link #CATEGORY_EUICC_UI} category, and a non-zero
+ * priority.
+ *
+ * TODO(b/35851809): Make this a SystemApi.
+ * @hide
+ */
+public abstract class EuiccService extends Service {
+    /** Action which must be included in this service's intent filter. */
+    public static final String EUICC_SERVICE_INTERFACE = "android.service.euicc.EuiccService";
+
+    /** Category which must be defined to all UI actions, for efficient lookup. */
+    public static final String CATEGORY_EUICC_UI = "android.service.euicc.category.EUICC_UI";
+
+    // LUI actions. These are passthroughs of the corresponding EuiccManager actions.
+
+    /** @see android.telephony.euicc.EuiccManager#ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS */
+    public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS =
+            "android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
+    /** @see android.telephony.euicc.EuiccManager#ACTION_PROVISION_EMBEDDED_SUBSCRIPTION */
+    public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION =
+            "android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
+
+    // LUI resolution actions. These are called by the platform to resolve errors in situations that
+    // require user interaction.
+    // TODO(b/33075886): Define extras for any input parameters to these dialogs once they are
+    // more scoped out.
+    /** Alert the user that this action will result in an active SIM being deactivated. */
+    public static final String ACTION_RESOLVE_DEACTIVATE_SIM =
+            "android.service.euicc.action.RESOLVE_DEACTIVATE_SIM";
+    /**
+     * Alert the user about a download/switch being done for an app that doesn't currently have
+     * carrier privileges.
+     */
+    public static final String ACTION_RESOLVE_NO_PRIVILEGES =
+            "android.service.euicc.action.RESOLVE_NO_PRIVILEGES";
+
+    /** Intent extra set for resolution requests containing the package name of the calling app. */
+    public static final String EXTRA_RESOLUTION_CALLING_PACKAGE =
+            "android.service.euicc.extra.RESOLUTION_CALLING_PACKAGE";
+
+    /** Result code for a successful operation. */
+    public static final int RESULT_OK = 0;
+    /** Result code indicating that an active SIM must be deactivated to perform the operation. */
+    public static final int RESULT_MUST_DEACTIVATE_SIM = -1;
+    // New predefined codes should have negative values.
+
+    /** Start of implementation-specific error results. */
+    public static final int RESULT_FIRST_USER = 1;
+
+    /**
+     * List of all valid resolution actions for validation purposes.
+     * @hide
+     */
+    public static final ArraySet<String> RESOLUTION_ACTIONS;
+    static {
+        RESOLUTION_ACTIONS = new ArraySet<>();
+        RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM);
+        RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES);
+    }
+
+    /** Boolean extra for resolution actions indicating whether the user granted consent. */
+    public static final String RESOLUTION_EXTRA_CONSENT = "consent";
+
+    private final IEuiccService.Stub mStubWrapper;
+
+    private ThreadPoolExecutor mExecutor;
+
+    public EuiccService() {
+        mStubWrapper = new IEuiccServiceWrapper();
+    }
+
+    @Override
+    @CallSuper
+    public void onCreate() {
+        super.onCreate();
+        // We use a oneway AIDL interface to avoid blocking phone process binder threads on IPCs to
+        // an external process, but doing so means the requests are serialized by binder, which is
+        // not desired. Spin up a background thread pool to allow requests to be parallelized.
+        // TODO(b/38206971): Consider removing this if basic card-level functions like listing
+        // profiles are moved to the platform.
+        mExecutor = new ThreadPoolExecutor(
+                4 /* corePoolSize */,
+                4 /* maxPoolSize */,
+                30, TimeUnit.SECONDS, /* keepAliveTime */
+                new LinkedBlockingQueue<>(), /* workQueue */
+                new ThreadFactory() {
+                    private final AtomicInteger mCount = new AtomicInteger(1);
+
+                    @Override
+                    public Thread newThread(Runnable r) {
+                        return new Thread(r, "EuiccService #" + mCount.getAndIncrement());
+                    }
+                }
+        );
+        mExecutor.allowCoreThreadTimeOut(true);
+    }
+
+    @Override
+    @CallSuper
+    public void onDestroy() {
+        mExecutor.shutdownNow();
+        super.onDestroy();
+    }
+
+    /**
+     * If overriding this method, call through to the super method for any unknown actions.
+     * {@inheritDoc}
+     */
+    @Override
+    @CallSuper
+    public IBinder onBind(Intent intent) {
+        return mStubWrapper;
+    }
+
+    /**
+     * Return the EID of the eUICC.
+     *
+     * @param slotId ID of the SIM slot being queried. This is currently not populated but is here
+     *     to future-proof the APIs.
+     * @return the EID.
+     * @see android.telephony.euicc.EuiccManager#getEid
+     */
+    // TODO(b/36260308): Update doc when we have multi-SIM support.
+    public abstract String onGetEid(int slotId);
+
+    /**
+     * Populate {@link DownloadableSubscription} metadata for the given downloadable subscription.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @param subscription A subscription whose metadata needs to be populated.
+     * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the
+     *     eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM)}
+     *     should be returned to allow the user to consent to this operation first.
+     * @return The result of the operation.
+     * @see android.telephony.euicc.EuiccManager#getDownloadableSubscriptionMetadata
+     */
+    public abstract GetDownloadableSubscriptionMetadataResult onGetDownloadableSubscriptionMetadata(
+            int slotId, DownloadableSubscription subscription, boolean forceDeactivateSim);
+
+    /**
+     * Return metadata for subscriptions which are available for download for this device.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the
+     *     eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM)}
+     *     should be returned to allow the user to consent to this operation first.
+     * @return The result of the list operation.
+     * @see android.telephony.euicc.EuiccManager#getDefaultDownloadableSubscriptionList
+     */
+    public abstract GetDefaultDownloadableSubscriptionListResult
+            onGetDefaultDownloadableSubscriptionList(int slotId, boolean forceDeactivateSim);
+
+    /**
+     * Download the given subscription.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @param subscription The subscription to download.
+     * @param switchAfterDownload If true, the subscription should be enabled upon successful
+     *     download.
+     * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the
+     *     eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM}
+     *     should be returned to allow the user to consent to this operation first.
+     * @return the result of the download operation. May be one of the predefined {@code RESULT_}
+     *     constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
+     * @see android.telephony.euicc.EuiccManager#downloadSubscription
+     */
+    public abstract int onDownloadSubscription(int slotId,
+            DownloadableSubscription subscription, boolean switchAfterDownload,
+            boolean forceDeactivateSim);
+
+    /**
+     * Return a list of all @link EuiccProfileInfo}s.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @return The result of the operation.
+     * @see android.telephony.SubscriptionManager#getAvailableSubscriptionInfoList
+     * @see android.telephony.SubscriptionManager#getAccessibleSubscriptionInfoList
+     */
+    public abstract GetEuiccProfileInfoListResult onGetEuiccProfileInfoList(int slotId);
+
+    /**
+     * Return info about the eUICC chip/device.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @return the {@link EuiccInfo} for the eUICC chip/device.
+     * @see android.telephony.euicc.EuiccManager#getEuiccInfo
+     */
+    public abstract EuiccInfo onGetEuiccInfo(int slotId);
+
+    /**
+     * Delete the given subscription.
+     *
+     * <p>If the subscription is currently active, it should be deactivated first (equivalent to a
+     * physical SIM being ejected).
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @param iccid the ICCID of the subscription to delete.
+     * @return the result of the delete operation. May be one of the predefined {@code RESULT_}
+     *     constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
+     * @see android.telephony.euicc.EuiccManager#deleteSubscription
+     */
+    public abstract int onDeleteSubscription(int slotId, String iccid);
+
+    /**
+     * Switch to the given subscription.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @param iccid the ICCID of the subscription to enable. May be null, in which case the current
+     *     profile should be deactivated and no profile should be activated to replace it - this is
+     *     equivalent to a physical SIM being ejected.
+     * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the
+     *     eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM}
+     *     should be returned to allow the user to consent to this operation first.
+     * @return the result of the switch operation. May be one of the predefined {@code RESULT_}
+     *     constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
+     * @see android.telephony.euicc.EuiccManager#switchToSubscription
+     */
+    public abstract int onSwitchToSubscription(int slotId, @Nullable String iccid,
+            boolean forceDeactivateSim);
+
+    /**
+     * Update the nickname of the given subscription.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @param iccid the ICCID of the subscription to update.
+     * @param nickname the new nickname to apply.
+     * @return the result of the update operation. May be one of the predefined {@code RESULT_}
+     *     constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
+     * @see android.telephony.euicc.EuiccManager#updateSubscriptionNickname
+     */
+    public abstract int onUpdateSubscriptionNickname(int slotId, String iccid,
+            String nickname);
+
+    /**
+     * Erase all of the subscriptions on the device.
+     *
+     * <p>This is intended to be used for device resets. As such, the reset should be performed even
+     * if an active SIM must be deactivated in order to access the eUICC.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @return the result of the erase operation. May be one of the predefined {@code RESULT_}
+     *     constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
+     * @see android.telephony.euicc.EuiccManager#eraseSubscriptions
+     */
+    public abstract int onEraseSubscriptions(int slotId);
+
+    /**
+     * Ensure that subscriptions will be retained on the next factory reset.
+     *
+     * <p>Called directly before a factory reset. Assumes that a normal factory reset will lead to
+     * profiles being erased on first boot (to cover fastboot/recovery wipes), so the implementation
+     * should persist some bit that will remain accessible after the factory reset to bypass this
+     * flow when this method is called.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @return the result of the operation. May be one of the predefined {@code RESULT_} constants
+     *     or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
+     */
+    public abstract int onRetainSubscriptionsForFactoryReset(int slotId);
+
+    /**
+     * Wrapper around IEuiccService that forwards calls to implementations of {@link EuiccService}.
+     */
+    private class IEuiccServiceWrapper extends IEuiccService.Stub {
+        @Override
+        public void downloadSubscription(int slotId, DownloadableSubscription subscription,
+                boolean switchAfterDownload, boolean forceDeactivateSim,
+                IDownloadSubscriptionCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    int result = EuiccService.this.onDownloadSubscription(
+                            slotId, subscription, switchAfterDownload, forceDeactivateSim);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void getEid(int slotId, IGetEidCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    String eid = EuiccService.this.onGetEid(slotId);
+                    try {
+                        callback.onSuccess(eid);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void getDownloadableSubscriptionMetadata(int slotId,
+                DownloadableSubscription subscription,
+                boolean forceDeactivateSim,
+                IGetDownloadableSubscriptionMetadataCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    GetDownloadableSubscriptionMetadataResult result =
+                            EuiccService.this.onGetDownloadableSubscriptionMetadata(
+                                    slotId, subscription, forceDeactivateSim);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void getDefaultDownloadableSubscriptionList(int slotId, boolean forceDeactivateSim,
+                IGetDefaultDownloadableSubscriptionListCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    GetDefaultDownloadableSubscriptionListResult result =
+                            EuiccService.this.onGetDefaultDownloadableSubscriptionList(
+                                    slotId, forceDeactivateSim);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void getEuiccProfileInfoList(int slotId, IGetEuiccProfileInfoListCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    GetEuiccProfileInfoListResult result =
+                            EuiccService.this.onGetEuiccProfileInfoList(slotId);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void getEuiccInfo(int slotId, IGetEuiccInfoCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    EuiccInfo euiccInfo = EuiccService.this.onGetEuiccInfo(slotId);
+                    try {
+                        callback.onSuccess(euiccInfo);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+
+        }
+
+        @Override
+        public void deleteSubscription(int slotId, String iccid,
+                IDeleteSubscriptionCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    int result = EuiccService.this.onDeleteSubscription(slotId, iccid);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void switchToSubscription(int slotId, String iccid, boolean forceDeactivateSim,
+                ISwitchToSubscriptionCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    int result =
+                            EuiccService.this.onSwitchToSubscription(
+                                    slotId, iccid, forceDeactivateSim);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void updateSubscriptionNickname(int slotId, String iccid, String nickname,
+                IUpdateSubscriptionNicknameCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    int result =
+                            EuiccService.this.onUpdateSubscriptionNickname(slotId, iccid, nickname);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void eraseSubscriptions(int slotId, IEraseSubscriptionsCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    int result = EuiccService.this.onEraseSubscriptions(slotId);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void retainSubscriptionsForFactoryReset(int slotId,
+                IRetainSubscriptionsForFactoryResetCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    int result = EuiccService.this.onRetainSubscriptionsForFactoryReset(slotId);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+    }
+}
diff --git a/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.aidl b/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.aidl
new file mode 100644
index 0000000..c2636a1
--- /dev/null
+++ b/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.service.euicc;
+
+parcelable GetDefaultDownloadableSubscriptionListResult;
diff --git a/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java b/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java
new file mode 100644
index 0000000..5a24492
--- /dev/null
+++ b/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java
@@ -0,0 +1,98 @@
+/*
+ * 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.service.euicc;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.euicc.DownloadableSubscription;
+
+/**
+ * Result of a {@link EuiccService#onGetDefaultDownloadableSubscriptionList} operation.
+ * @hide
+ *
+ * TODO(b/35851809): Make this a SystemApi.
+ */
+public final class GetDefaultDownloadableSubscriptionListResult implements Parcelable {
+
+    public static final Creator<GetDefaultDownloadableSubscriptionListResult> CREATOR =
+            new Creator<GetDefaultDownloadableSubscriptionListResult>() {
+        @Override
+        public GetDefaultDownloadableSubscriptionListResult createFromParcel(Parcel in) {
+            return new GetDefaultDownloadableSubscriptionListResult(in);
+        }
+
+        @Override
+        public GetDefaultDownloadableSubscriptionListResult[] newArray(int size) {
+            return new GetDefaultDownloadableSubscriptionListResult[size];
+        }
+    };
+
+    /**
+     * Result of the operation.
+     *
+     * <p>May be one of the predefined {@code RESULT_} constants in EuiccService or any
+     * implementation-specific code starting with {@link EuiccService#RESULT_FIRST_USER}.
+     */
+    public final int result;
+
+    /**
+     * The available {@link DownloadableSubscription}s (with filled-in metadata).
+     *
+     * <p>Only non-null if {@link #result} is {@link EuiccService#RESULT_OK}.
+     */
+    @Nullable
+    public final DownloadableSubscription[] subscriptions;
+
+    /**
+     * Construct a new {@link GetDefaultDownloadableSubscriptionListResult}.
+     *
+     * @param result Result of the operation. May be one of the predefined {@code RESULT_} constants
+     *     in EuiccService or any implementation-specific code starting with
+     *     {@link EuiccService#RESULT_FIRST_USER}.
+     * @param subscriptions The available subscriptions. Should only be provided if the result is
+     *     {@link EuiccService#RESULT_OK}.
+     */
+    public GetDefaultDownloadableSubscriptionListResult(int result,
+            @Nullable DownloadableSubscription[] subscriptions) {
+        this.result = result;
+        if (this.result == EuiccService.RESULT_OK) {
+            this.subscriptions = subscriptions;
+        } else {
+            if (subscriptions != null) {
+                throw new IllegalArgumentException(
+                        "Error result with non-null subscriptions: " + result);
+            }
+            this.subscriptions = null;
+        }
+    }
+
+    private GetDefaultDownloadableSubscriptionListResult(Parcel in) {
+        this.result = in.readInt();
+        this.subscriptions = in.createTypedArray(DownloadableSubscription.CREATOR);
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(result);
+        dest.writeTypedArray(subscriptions, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.aidl b/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.aidl
new file mode 100644
index 0000000..791ad9b
--- /dev/null
+++ b/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.service.euicc;
+
+parcelable GetDownloadableSubscriptionMetadataResult;
diff --git a/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java b/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java
new file mode 100644
index 0000000..de8a307
--- /dev/null
+++ b/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java
@@ -0,0 +1,98 @@
+/*
+ * 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.service.euicc;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.euicc.DownloadableSubscription;
+
+/**
+ * Result of a {@link EuiccService#onGetDownloadableSubscriptionMetadata} operation.
+ * @hide
+ *
+ * TODO(b/35851809): Make this a SystemApi.
+ */
+public final class GetDownloadableSubscriptionMetadataResult implements Parcelable {
+
+    public static final Creator<GetDownloadableSubscriptionMetadataResult> CREATOR =
+            new Creator<GetDownloadableSubscriptionMetadataResult>() {
+        @Override
+        public GetDownloadableSubscriptionMetadataResult createFromParcel(Parcel in) {
+            return new GetDownloadableSubscriptionMetadataResult(in);
+        }
+
+        @Override
+        public GetDownloadableSubscriptionMetadataResult[] newArray(int size) {
+            return new GetDownloadableSubscriptionMetadataResult[size];
+        }
+    };
+
+    /**
+     * Result of the operation.
+     *
+     * <p>May be one of the predefined {@code RESULT_} constants in EuiccService or any
+     * implementation-specific code starting with {@link EuiccService#RESULT_FIRST_USER}.
+     */
+    public final int result;
+
+    /**
+     * The {@link DownloadableSubscription} with filled-in metadata.
+     *
+     * <p>Only non-null if {@link #result} is {@link EuiccService#RESULT_OK}.
+     */
+    @Nullable
+    public final DownloadableSubscription subscription;
+
+    /**
+     * Construct a new {@link GetDownloadableSubscriptionMetadataResult}.
+     *
+     * @param result Result of the operation. May be one of the predefined {@code RESULT_} constants
+     *     in EuiccService or any implementation-specific code starting with
+     *     {@link EuiccService#RESULT_FIRST_USER}.
+     * @param subscription The subscription with filled-in metadata. Should only be provided if the
+     *     result is {@link EuiccService#RESULT_OK}.
+     */
+    public GetDownloadableSubscriptionMetadataResult(int result,
+            @Nullable DownloadableSubscription subscription) {
+        this.result = result;
+        if (this.result == EuiccService.RESULT_OK) {
+            this.subscription = subscription;
+        } else {
+            if (subscription != null) {
+                throw new IllegalArgumentException(
+                        "Error result with non-null subscription: " + result);
+            }
+            this.subscription = null;
+        }
+    }
+
+    private GetDownloadableSubscriptionMetadataResult(Parcel in) {
+        this.result = in.readInt();
+        this.subscription = in.readTypedObject(DownloadableSubscription.CREATOR);
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(result);
+        dest.writeTypedObject(this.subscription, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/GetEuiccProfileInfoListResult.aidl b/core/java/android/service/euicc/GetEuiccProfileInfoListResult.aidl
new file mode 100644
index 0000000..6003b79
--- /dev/null
+++ b/core/java/android/service/euicc/GetEuiccProfileInfoListResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.service.euicc;
+
+parcelable GetEuiccProfileInfoListResult;
diff --git a/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java b/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java
new file mode 100644
index 0000000..7ad8488
--- /dev/null
+++ b/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java
@@ -0,0 +1,104 @@
+/*
+ * 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.service.euicc;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Result of a {@link EuiccService#onGetEuiccProfileInfoList} operation.
+ * @hide
+ *
+ * TODO(b/35851809): Make this a SystemApi.
+ */
+public final class GetEuiccProfileInfoListResult implements Parcelable {
+
+    public static final Creator<GetEuiccProfileInfoListResult> CREATOR =
+            new Creator<GetEuiccProfileInfoListResult>() {
+                @Override
+                public GetEuiccProfileInfoListResult createFromParcel(Parcel in) {
+                    return new GetEuiccProfileInfoListResult(in);
+                }
+
+                @Override
+                public GetEuiccProfileInfoListResult[] newArray(int size) {
+                    return new GetEuiccProfileInfoListResult[size];
+                }
+            };
+
+    /**
+     * Result of the operation.
+     *
+     * <p>May be one of the predefined {@code RESULT_} constants in EuiccService or any
+     * implementation-specific code starting with {@link EuiccService#RESULT_FIRST_USER}.
+     */
+    public final int result;
+
+    /** The profile list (only upon success). */
+    @Nullable
+    public final EuiccProfileInfo[] profiles;
+
+    /** Whether the eUICC is removable. */
+    public final boolean isRemovable;
+
+    /**
+     * Construct a new {@link GetEuiccProfileInfoListResult}.
+     *
+     * @param result Result of the operation. May be one of the predefined {@code RESULT_} constants
+     *     in EuiccService or any implementation-specific code starting with
+     *     {@link EuiccService#RESULT_FIRST_USER}.
+     * @param profiles the list of profiles. Should only be provided if the result is
+     *     {@link EuiccService#RESULT_OK}.
+     * @param isRemovable whether the eUICC in this slot is removable. If true, the profiles
+     *     returned here will only be considered accessible as long as this eUICC is present.
+     *     Otherwise, they will remain accessible until the next time a response with isRemovable
+     *     set to false is returned.
+     */
+    public GetEuiccProfileInfoListResult(
+            int result, @Nullable EuiccProfileInfo[] profiles, boolean isRemovable) {
+        this.result = result;
+        this.isRemovable = isRemovable;
+        if (this.result == EuiccService.RESULT_OK) {
+            this.profiles = profiles;
+        } else {
+            if (profiles != null) {
+                throw new IllegalArgumentException(
+                        "Error result with non-null profiles: " + result);
+            }
+            this.profiles = null;
+        }
+
+    }
+
+    private GetEuiccProfileInfoListResult(Parcel in) {
+        this.result = in.readInt();
+        this.profiles = in.createTypedArray(EuiccProfileInfo.CREATOR);
+        this.isRemovable = in.readBoolean();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(result);
+        dest.writeTypedArray(profiles, flags);
+        dest.writeBoolean(isRemovable);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/service/euicc/IDeleteSubscriptionCallback.aidl b/core/java/android/service/euicc/IDeleteSubscriptionCallback.aidl
new file mode 100644
index 0000000..4667066
--- /dev/null
+++ b/core/java/android/service/euicc/IDeleteSubscriptionCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.euicc;
+
+/** @hide */
+oneway interface IDeleteSubscriptionCallback {
+    void onComplete(int result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl b/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl
new file mode 100644
index 0000000..6893c85
--- /dev/null
+++ b/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.euicc;
+
+/** @hide */
+oneway interface IDownloadSubscriptionCallback {
+    void onComplete(int result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IEraseSubscriptionsCallback.aidl b/core/java/android/service/euicc/IEraseSubscriptionsCallback.aidl
new file mode 100644
index 0000000..c975f18
--- /dev/null
+++ b/core/java/android/service/euicc/IEraseSubscriptionsCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.euicc;
+
+/** @hide */
+oneway interface IEraseSubscriptionsCallback {
+    void onComplete(int result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IEuiccService.aidl b/core/java/android/service/euicc/IEuiccService.aidl
new file mode 100644
index 0000000..e10dd8c
--- /dev/null
+++ b/core/java/android/service/euicc/IEuiccService.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.euicc;
+
+import android.service.euicc.IDeleteSubscriptionCallback;
+import android.service.euicc.IDownloadSubscriptionCallback;
+import android.service.euicc.IEraseSubscriptionsCallback;
+import android.service.euicc.IGetDefaultDownloadableSubscriptionListCallback;
+import android.service.euicc.IGetDownloadableSubscriptionMetadataCallback;
+import android.service.euicc.IGetEidCallback;
+import android.service.euicc.IGetEuiccInfoCallback;
+import android.service.euicc.IGetEuiccProfileInfoListCallback;
+import android.service.euicc.IRetainSubscriptionsForFactoryResetCallback;
+import android.service.euicc.ISwitchToSubscriptionCallback;
+import android.service.euicc.IUpdateSubscriptionNicknameCallback;
+import android.telephony.euicc.DownloadableSubscription;
+
+/** @hide */
+oneway interface IEuiccService {
+    void downloadSubscription(int slotId, in DownloadableSubscription subscription,
+            boolean switchAfterDownload, boolean forceDeactivateSim,
+            in IDownloadSubscriptionCallback callback);
+    void getDownloadableSubscriptionMetadata(int slotId, in DownloadableSubscription subscription,
+            boolean forceDeactivateSim, in IGetDownloadableSubscriptionMetadataCallback callback);
+    void getEid(int slotId, in IGetEidCallback callback);
+    void getEuiccProfileInfoList(int slotId, in IGetEuiccProfileInfoListCallback callback);
+    void getDefaultDownloadableSubscriptionList(int slotId, boolean forceDeactivateSim,
+            in IGetDefaultDownloadableSubscriptionListCallback callback);
+    void getEuiccInfo(int slotId, in IGetEuiccInfoCallback callback);
+    void deleteSubscription(int slotId, String iccid, in IDeleteSubscriptionCallback callback);
+    void switchToSubscription(int slotId, String iccid, boolean forceDeactivateSim,
+            in ISwitchToSubscriptionCallback callback);
+    void updateSubscriptionNickname(int slotId, String iccid, String nickname,
+            in IUpdateSubscriptionNicknameCallback callback);
+    void eraseSubscriptions(int slotId, in IEraseSubscriptionsCallback callback);
+    void retainSubscriptionsForFactoryReset(
+            int slotId, in IRetainSubscriptionsForFactoryResetCallback callback);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl b/core/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl
new file mode 100644
index 0000000..0c5a0c6
--- /dev/null
+++ b/core/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.euicc;
+
+import android.service.euicc.GetDefaultDownloadableSubscriptionListResult;
+
+/** @hide */
+oneway interface IGetDefaultDownloadableSubscriptionListCallback {
+    void onComplete(in GetDefaultDownloadableSubscriptionListResult result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl b/core/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl
new file mode 100644
index 0000000..3353061
--- /dev/null
+++ b/core/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.euicc;
+
+import android.service.euicc.GetDownloadableSubscriptionMetadataResult;
+
+/** @hide */
+oneway interface IGetDownloadableSubscriptionMetadataCallback {
+    void onComplete(in GetDownloadableSubscriptionMetadataResult result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IGetEidCallback.aidl b/core/java/android/service/euicc/IGetEidCallback.aidl
new file mode 100644
index 0000000..35ee9c2
--- /dev/null
+++ b/core/java/android/service/euicc/IGetEidCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.euicc;
+
+/** @hide */
+oneway interface IGetEidCallback {
+    void onSuccess(String eid);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IGetEuiccInfoCallback.aidl b/core/java/android/service/euicc/IGetEuiccInfoCallback.aidl
new file mode 100644
index 0000000..6d28148
--- /dev/null
+++ b/core/java/android/service/euicc/IGetEuiccInfoCallback.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.euicc;
+
+import android.telephony.euicc.EuiccInfo;
+
+/** @hide */
+oneway interface IGetEuiccInfoCallback {
+    void onSuccess(in EuiccInfo euiccInfo);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl b/core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl
new file mode 100644
index 0000000..761ec1f
--- /dev/null
+++ b/core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.euicc;
+
+import android.service.euicc.GetEuiccProfileInfoListResult;
+
+/** @hide */
+oneway interface IGetEuiccProfileInfoListCallback {
+    void onComplete(in GetEuiccProfileInfoListResult result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl b/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl
new file mode 100644
index 0000000..1276830
--- /dev/null
+++ b/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.euicc;
+
+/** @hide */
+oneway interface IRetainSubscriptionsForFactoryResetCallback {
+    void onComplete(int result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl b/core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl
new file mode 100644
index 0000000..0f91a6b
--- /dev/null
+++ b/core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.euicc;
+
+/** @hide */
+oneway interface ISwitchToSubscriptionCallback {
+    void onComplete(int result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl b/core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl
new file mode 100644
index 0000000..6666933
--- /dev/null
+++ b/core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.euicc;
+
+/** @hide */
+oneway interface IUpdateSubscriptionNicknameCallback {
+    void onComplete(int result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/gatekeeper/GateKeeperResponse.java b/core/java/android/service/gatekeeper/GateKeeperResponse.java
index 287dc76..9b52934 100644
--- a/core/java/android/service/gatekeeper/GateKeeperResponse.java
+++ b/core/java/android/service/gatekeeper/GateKeeperResponse.java
@@ -106,6 +106,8 @@
             if (mPayload != null) {
                 dest.writeInt(mPayload.length);
                 dest.writeByteArray(mPayload);
+            } else {
+                dest.writeInt(0);
             }
         }
     }
diff --git a/core/java/android/service/gatekeeper/IGateKeeperService.aidl b/core/java/android/service/gatekeeper/IGateKeeperService.aidl
index 6db2110..abc6466 100644
--- a/core/java/android/service/gatekeeper/IGateKeeperService.aidl
+++ b/core/java/android/service/gatekeeper/IGateKeeperService.aidl
@@ -78,4 +78,10 @@
      * @param uid the Android user id.
      */
     void clearSecureUserId(int uid);
+
+    /**
+     * Notifies gatekeeper that device setup has been completed and any potentially still existing
+     * state from before a factory reset can be cleaned up (if it has not been already).
+     */
+    void reportDeviceSetupComplete();
 }
diff --git a/core/java/android/service/oemlock/IOemLockService.aidl b/core/java/android/service/oemlock/IOemLockService.aidl
index 2c606f9..682e7ee 100644
--- a/core/java/android/service/oemlock/IOemLockService.aidl
+++ b/core/java/android/service/oemlock/IOemLockService.aidl
@@ -27,4 +27,8 @@
 
     void setOemUnlockAllowedByUser(boolean allowed);
     boolean isOemUnlockAllowedByUser();
+
+    boolean canUserAllowOemUnlock();
+    boolean isOemUnlockAllowed();
+    boolean isDeviceOemUnlocked();
 }
diff --git a/core/java/android/service/oemlock/OemLockManager.java b/core/java/android/service/oemlock/OemLockManager.java
index e2ade87..3a56d9f 100644
--- a/core/java/android/service/oemlock/OemLockManager.java
+++ b/core/java/android/service/oemlock/OemLockManager.java
@@ -88,7 +88,8 @@
      *
      * All actors involved must agree for OEM unlock to be possible.
      *
-     * @param unlocked Whether the device should be made OEM unlocked.
+     * @param allowed Whether the device should be allowed to be unlocked.
+     * @throws SecurityException if the user is not allowed to unlock the device.
      *
      * @see #isOemUnlockAllowedByUser()
      */
@@ -115,4 +116,48 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Returns whether all parties other than the user allow OEM unlock meaning the user can
+     * directly control whether or not the device can be OEM unlocked.
+     *
+     * If this is true, {@link #isOemUnlockAllowedByUser} is the same as {@link #isOemUnlockAllowed}
+     *
+     * @return Whether the user can directly control whether the device can be OEM unlocked.
+     *
+     * @hide
+     */
+    public boolean canUserAllowOemUnlock() {
+        try {
+            return mService.canUserAllowOemUnlock();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @return Whether the bootloader is able to OEM unlock the device.
+     *
+     * @hide
+     */
+    public boolean isOemUnlockAllowed() {
+        try {
+            return mService.isOemUnlockAllowed();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @return Whether the device has been OEM unlocked by the bootloader.
+     *
+     * @hide
+     */
+    public boolean isDeviceOemUnlocked() {
+        try {
+            return mService.isDeviceOemUnlocked();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl b/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl
index 626b408..31352f1 100644
--- a/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl
+++ b/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl
@@ -36,5 +36,6 @@
     void setOemUnlockEnabled(boolean enabled);
     boolean getOemUnlockEnabled();
     int getFlashLockState();
+    boolean hasFrpCredentialHandle();
 }
 
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 479c9e2..fbc6fc6 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -262,7 +262,8 @@
      * @param keyphrase The keyphrase that's being used, for example "Hello Android".
      * @param locale The locale for which the enrollment needs to be performed.
      * @param callback The callback to notify of detection events.
-     * @return An always-on hotword detector for the given keyphrase and locale.
+     * @return An always-on hotword detector for the given keyphrase and locale. Is null if the
+     * keyphrase and locale is not supported.
      */
     public final AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(
             String keyphrase, Locale locale, AlwaysOnHotwordDetector.Callback callback) {
@@ -272,8 +273,10 @@
         synchronized (mLock) {
             // Allow only one concurrent recognition via the APIs.
             safelyShutdownHotwordDetector();
-            mHotwordDetector = new AlwaysOnHotwordDetector(keyphrase, locale, callback,
-                    mKeyphraseEnrollmentInfo, mInterface, mSystemService);
+            if (isKeyphraseAndLocaleSupportedForHotword(keyphrase, locale)) {
+                mHotwordDetector = new AlwaysOnHotwordDetector(keyphrase, locale, callback,
+                        mKeyphraseEnrollmentInfo, mInterface, mSystemService);
+            }
         }
         return mHotwordDetector;
     }
@@ -287,6 +290,20 @@
         return mKeyphraseEnrollmentInfo;
     }
 
+    /**
+      * 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
+      */
+    public final boolean isKeyphraseAndLocaleSupportedForHotword(String keyphrase, Locale locale) {
+        if (mKeyphraseEnrollmentInfo == null) {
+            return false;
+        }
+        return mKeyphraseEnrollmentInfo.getKeyphraseMetadata(keyphrase, locale) != null;
+    }
+
     private void safelyShutdownHotwordDetector() {
         try {
             synchronized (mLock) {
diff --git a/core/java/android/service/vr/IVrListener.aidl b/core/java/android/service/vr/IVrListener.aidl
index afb13d3..acca3fa 100644
--- a/core/java/android/service/vr/IVrListener.aidl
+++ b/core/java/android/service/vr/IVrListener.aidl
@@ -20,5 +20,5 @@
 
 /** @hide */
 oneway interface IVrListener {
-    void focusedActivityChanged(in ComponentName component);
+    void focusedActivityChanged(in ComponentName component, boolean running2dInVr, int pid);
 }
diff --git a/core/java/android/service/vr/VrListenerService.java b/core/java/android/service/vr/VrListenerService.java
index 5da4560..fa3d065 100644
--- a/core/java/android/service/vr/VrListenerService.java
+++ b/core/java/android/service/vr/VrListenerService.java
@@ -70,8 +70,10 @@
 
     private final IVrListener.Stub mBinder = new IVrListener.Stub() {
         @Override
-        public void focusedActivityChanged(ComponentName component) {
-            mHandler.obtainMessage(MSG_ON_CURRENT_VR_ACTIVITY_CHANGED, component).sendToTarget();
+        public void focusedActivityChanged(
+                ComponentName component, boolean running2dInVr, int pid) {
+            mHandler.obtainMessage(MSG_ON_CURRENT_VR_ACTIVITY_CHANGED, running2dInVr ? 1 : 0,
+                    pid, component).sendToTarget();
         }
     };
 
@@ -84,7 +86,8 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MSG_ON_CURRENT_VR_ACTIVITY_CHANGED: {
-                    VrListenerService.this.onCurrentVrActivityChanged((ComponentName) msg.obj);
+                    VrListenerService.this.onCurrentVrActivityChanged(
+                            (ComponentName) msg.obj, msg.arg1 == 1, msg.arg2);
                 } break;
             }
         }
@@ -120,6 +123,29 @@
     }
 
     /**
+     * An extended version of onCurrentVrActivityChanged
+     *
+     * <p>This will be called when this service is initially bound, but is not
+     * guaranteed to be called before onUnbind.  In general, this is intended to be used to
+     * determine when user focus has transitioned between two VR activities, or between a
+     * VR activity and a 2D activity. This should be overridden instead of the above
+     * onCurrentVrActivityChanged as that version is deprecated.</p>
+     *
+     * @param component the {@link ComponentName} of the VR activity or the 2D intent.
+     * @param running2dInVr true if the component is a 2D component.
+     * @param pid the process the component is running in.
+     *
+     * @see android.app.Activity#setVrModeEnabled
+     * @see android.R.attr#enableVrMode
+     * @hide
+     */
+    public void onCurrentVrActivityChanged(
+            ComponentName component, boolean running2dInVr, int pid) {
+        // Override to implement. Default to old behaviour of sending null for 2D.
+        onCurrentVrActivityChanged(running2dInVr ? null : component);
+    }
+
+    /**
      * Checks if the given component is enabled in user settings.
      *
      * <p>If this component is not enabled in the user's settings, it will not be started when
diff --git a/core/java/android/service/wallpaper/IWallpaperConnection.aidl b/core/java/android/service/wallpaper/IWallpaperConnection.aidl
index f9c5aaa..3c3ef0c 100644
--- a/core/java/android/service/wallpaper/IWallpaperConnection.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperConnection.aidl
@@ -18,6 +18,7 @@
 
 import android.os.ParcelFileDescriptor;
 import android.service.wallpaper.IWallpaperEngine;
+import android.app.WallpaperColors;
 
 /**
  * @hide
@@ -26,4 +27,5 @@
 	void attachEngine(IWallpaperEngine engine);
 	void engineShown(IWallpaperEngine engine);
     ParcelFileDescriptor setWallpaper(String name);
+    void onWallpaperColorsChanged(in WallpaperColors colors);
 }
diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
index de527e9..fb6f637 100644
--- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
@@ -30,5 +30,6 @@
     void dispatchPointer(in MotionEvent event);
     void dispatchWallpaperCommand(String action, int x, int y,
             int z, in Bundle extras);
-	void destroy();
+    void requestWallpaperColors();
+    void destroy();
 }
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 6bbb0ff..5ef60a5 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -16,24 +16,20 @@
 
 package android.service.wallpaper;
 
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.util.MergedConfiguration;
-import android.view.WindowInsets;
-
-import com.android.internal.R;
-import com.android.internal.os.HandlerCaller;
-import com.android.internal.view.BaseIWindow;
-import com.android.internal.view.BaseSurfaceHolder;
-
+import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.app.Service;
+import android.app.WallpaperColors;
 import android.app.WallpaperManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
 import android.os.Bundle;
@@ -42,6 +38,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.util.Log;
+import android.util.MergedConfiguration;
 import android.view.Display;
 import android.view.Gravity;
 import android.view.IWindowSession;
@@ -53,9 +50,14 @@
 import android.view.SurfaceHolder;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.WindowInsets;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 
+import com.android.internal.os.HandlerCaller;
+import com.android.internal.view.BaseIWindow;
+import com.android.internal.view.BaseSurfaceHolder;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -103,6 +105,7 @@
     private static final int MSG_WINDOW_RESIZED = 10030;
     private static final int MSG_WINDOW_MOVED = 10035;
     private static final int MSG_TOUCH_EVENT = 10040;
+    private static final int MSG_REQUEST_WALLPAPER_COLORS = 10050;
     
     private final ArrayList<Engine> mActiveEngines
             = new ArrayList<Engine>();
@@ -266,7 +269,7 @@
             }
 
             @Override
-            public void onInputEvent(InputEvent event) {
+            public void onInputEvent(InputEvent event, int displayId) {
                 boolean handled = false;
                 try {
                     if (event instanceof MotionEvent
@@ -542,7 +545,38 @@
          */
         public void onSurfaceDestroyed(SurfaceHolder holder) {
         }
-        
+
+        /**
+         * Notifies the engine that wallpaper colors changed significantly.
+         * This will trigger a {@link #onComputeWallpaperColors()} call.
+         * @hide
+         */
+        public void invalidateColors() {
+            try {
+                mConnection.onWallpaperColorsChanged(onComputeWallpaperColors());
+            } catch (RemoteException e) {
+                Log.w(TAG, "Can't invalidate wallpaper colors because " +
+                        "wallpaper connection was lost", e);
+            }
+        }
+
+        /**
+         * Notifies the system about what colors the wallpaper is using.
+         * You might return null if no color information is available at the moment. In that case
+         * you might want to call {@link #invalidateColors()} in a near future.
+         * <p>
+         * The simplest way of creating A {@link android.app.WallpaperColors} object is by using
+         * {@link android.app.WallpaperColors#fromBitmap(Bitmap)} or
+         * {@link android.app.WallpaperColors#fromDrawable(Drawable)}, but you can also specify
+         * your main colors and dark text support explicitly using one of the constructors.
+         *
+         * @return Wallpaper colors.
+         * @hide
+         */
+        public @Nullable WallpaperColors onComputeWallpaperColors() {
+            return null;
+        }
+
         protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
             out.print(prefix); out.print("mInitializing="); out.print(mInitializing);
                     out.print(" mDestroyed="); out.println(mDestroyed);
@@ -1161,6 +1195,11 @@
             }
         }
 
+        public void requestWallpaperColors() {
+            Message msg = mCaller.obtainMessage(MSG_REQUEST_WALLPAPER_COLORS);
+            mCaller.sendMessage(msg);
+        }
+
         public void destroy() {
             Message msg = mCaller.obtainMessage(DO_DETACH);
             mCaller.sendMessage(msg);
@@ -1236,6 +1275,16 @@
                     }
                     ev.recycle();
                 } break;
+                case MSG_REQUEST_WALLPAPER_COLORS: {
+                    if (mConnection == null) {
+                        break;
+                    }
+                    try {
+                        mConnection.onWallpaperColorsChanged(mEngine.onComputeWallpaperColors());
+                    } catch (RemoteException e) {
+                        // Connection went away, nothing to do in here.
+                    }
+                } break;
                 default :
                     Log.w(TAG, "Unknown message type " + message.what);
             }
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index 6208c53..c7a5fce 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -491,8 +491,6 @@
      * An index is associated to each block (which will be used by display lists),
      * this class simply invalidates the index of blocks overlapping a modification.
      *
-     * This method is package private and not private so that it can be tested.
-     *
      * @param startLine the first line of the range of modified lines
      * @param endLine the last line of the range, possibly equal to startLine, lower
      * than getLineCount()
@@ -613,16 +611,20 @@
     }
 
     /**
-     * This package private method is used for test purposes only
+     * This method is used for test purposes only.
      * @hide
      */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    public void setBlocksDataForTest(int[] blockEndLines, int[] blockIndices, int numberOfBlocks) {
+    public void setBlocksDataForTest(int[] blockEndLines, int[] blockIndices, int numberOfBlocks,
+            int totalLines) {
         mBlockEndLines = new int[blockEndLines.length];
         mBlockIndices = new int[blockIndices.length];
         System.arraycopy(blockEndLines, 0, mBlockEndLines, 0, blockEndLines.length);
         System.arraycopy(blockIndices, 0, mBlockIndices, 0, blockIndices.length);
         mNumberOfBlocks = numberOfBlocks;
+        while (mInts.size() < totalLines) {
+            mInts.insertAt(mInts.size(), new int[COLUMNS_NORMAL]);
+        }
     }
 
     /**
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 756e9a0..e4ed62a 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -16,6 +16,8 @@
 
 package android.text;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Paint.FontMetricsInt;
@@ -28,6 +30,8 @@
 
 import com.android.internal.util.ArrayUtils;
 
+import java.util.ArrayList;
+
 /**
  * Represents a line of styled text, for measuring in visual order and
  * for rendering.
@@ -58,7 +62,9 @@
     // Additional width of whitespace for justification. This value is per whitespace, thus
     // the line width will increase by mAddedWidth x (number of stretchable whitespaces).
     private float mAddedWidth;
+
     private final TextPaint mWorkPaint = new TextPaint();
+    private final TextPaint mActivePaint = new TextPaint();
     private final SpanSet<MetricAffectingSpan> mMetricAffectingSpanSpanSet =
             new SpanSet<MetricAffectingSpan>(MetricAffectingSpan.class);
     private final SpanSet<CharacterStyle> mCharacterStyleSpanSet =
@@ -66,6 +72,9 @@
     private final SpanSet<ReplacementSpan> mReplacementSpanSpanSet =
             new SpanSet<ReplacementSpan>(ReplacementSpan.class);
 
+    private final UnderlineInfo mUnderlineInfo = new UnderlineInfo();
+    private final ArrayList<UnderlineInfo> mUnderlines = new ArrayList();
+
     private static final TextLine[] sCached = new TextLine[3];
 
     /**
@@ -695,6 +704,36 @@
         fmi.leading = Math.max(fmi.leading, previousLeading);
     }
 
+    private static void drawUnderline(TextPaint wp, Canvas c, int color, float thickness,
+            float xleft, float xright, float baseline) {
+        final float underlineTop = baseline + wp.baselineShift + wp.getUnderlinePosition();
+
+        final int previousColor = wp.getColor();
+        final Paint.Style previousStyle = wp.getStyle();
+        final boolean previousAntiAlias = wp.isAntiAlias();
+
+        wp.setStyle(Paint.Style.FILL);
+        wp.setAntiAlias(true);
+
+        wp.setColor(color);
+        c.drawRect(xleft, underlineTop, xright, underlineTop + thickness, wp);
+
+        wp.setStyle(previousStyle);
+        wp.setColor(previousColor);
+        wp.setAntiAlias(previousAntiAlias);
+    }
+
+    private float getRunAdvance(TextPaint wp, int start, int end, int contextStart, int contextEnd,
+            boolean runIsRtl, int offset) {
+        if (mCharsValid) {
+            return wp.getRunAdvance(mChars, start, end, contextStart, contextEnd, runIsRtl, offset);
+        } else {
+            final int delta = mStart;
+            return wp.getRunAdvance(mText, delta + start, delta + end,
+                    delta + contextStart, delta + contextEnd, runIsRtl, delta + offset);
+        }
+    }
+
     /**
      * Utility function for measuring and rendering text.  The text must
      * not include a tab.
@@ -711,13 +750,15 @@
      * @param fmi receives metrics information, can be null
      * @param needWidth true if the width of the run is needed
      * @param offset the offset for the purpose of measuring
+     * @param underlines the list of locations and paremeters for drawing underlines
      * @return the signed width of the run based on the run direction; only
      * valid if needWidth is true
      */
     private float handleText(TextPaint wp, int start, int end,
             int contextStart, int contextEnd, boolean runIsRtl,
             Canvas c, float x, int top, int y, int bottom,
-            FontMetricsInt fmi, boolean needWidth, int offset) {
+            FontMetricsInt fmi, boolean needWidth, int offset,
+            @Nullable ArrayList<UnderlineInfo> underlines) {
 
         wp.setWordSpacing(mAddedWidth);
         // Get metrics first (even for empty strings or "0" width runs)
@@ -725,28 +766,26 @@
             expandMetricsFromPaint(fmi, wp);
         }
 
-        int runLen = end - start;
         // No need to do anything if the run width is "0"
-        if (runLen == 0) {
+        if (end == start) {
             return 0f;
         }
 
-        float ret = 0;
+        float totalWidth = 0;
 
-        if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor != 0 || runIsRtl))) {
-            if (mCharsValid) {
-                ret = wp.getRunAdvance(mChars, start, end, contextStart, contextEnd,
-                        runIsRtl, offset);
-            } else {
-                int delta = mStart;
-                ret = wp.getRunAdvance(mText, delta + start, delta + end,
-                        delta + contextStart, delta + contextEnd, runIsRtl, delta + offset);
-            }
+        final int numUnderlines = underlines == null ? 0 : underlines.size();
+        if (needWidth || (c != null && (wp.bgColor != 0 || numUnderlines != 0 || runIsRtl))) {
+            totalWidth = getRunAdvance(wp, start, end, contextStart, contextEnd, runIsRtl, offset);
         }
 
         if (c != null) {
+            final float leftX, rightX;
             if (runIsRtl) {
-                x -= ret;
+                leftX = x - totalWidth;
+                rightX = x;
+            } else {
+                leftX = x;
+                rightX = x + totalWidth;
             }
 
             if (wp.bgColor != 0) {
@@ -755,36 +794,50 @@
 
                 wp.setColor(wp.bgColor);
                 wp.setStyle(Paint.Style.FILL);
-                c.drawRect(x, top, x + ret, bottom, wp);
+                c.drawRect(leftX, top, rightX, bottom, wp);
 
                 wp.setStyle(previousStyle);
                 wp.setColor(previousColor);
             }
 
-            if (wp.underlineColor != 0) {
-                // kStdUnderline_Offset = 1/9, defined in SkTextFormatParams.h
-                float underlineTop = y + wp.baselineShift + (1.0f / 9.0f) * wp.getTextSize();
+            if (numUnderlines != 0) {
+                for (int i = 0; i < numUnderlines; i++) {
+                    final UnderlineInfo info = underlines.get(i);
 
-                int previousColor = wp.getColor();
-                Paint.Style previousStyle = wp.getStyle();
-                boolean previousAntiAlias = wp.isAntiAlias();
+                    final int underlineStart = Math.max(info.start, start);
+                    final int underlineEnd = Math.min(info.end, offset);
+                    float underlineStartAdvance = getRunAdvance(
+                            wp, start, end, contextStart, contextEnd, runIsRtl, underlineStart);
+                    float underlineEndAdvance = getRunAdvance(
+                            wp, start, end, contextStart, contextEnd, runIsRtl, underlineEnd);
+                    final float underlineXLeft, underlineXRight;
+                    if (runIsRtl) {
+                        underlineXLeft = rightX - underlineEndAdvance;
+                        underlineXRight = rightX - underlineStartAdvance;
+                    } else {
+                        underlineXLeft = leftX + underlineStartAdvance;
+                        underlineXRight = leftX + underlineEndAdvance;
+                    }
 
-                wp.setStyle(Paint.Style.FILL);
-                wp.setAntiAlias(true);
-
-                wp.setColor(wp.underlineColor);
-                c.drawRect(x, underlineTop, x + ret, underlineTop + wp.underlineThickness, wp);
-
-                wp.setStyle(previousStyle);
-                wp.setColor(previousColor);
-                wp.setAntiAlias(previousAntiAlias);
+                    // Theoretically, there could be cases where both Paint's and TextPaint's
+                    // setUnderLineText() are called. For backward compatibility, we need to draw
+                    // both underlines, the one with custom color first.
+                    if (info.underlineColor != 0) {
+                        drawUnderline(wp, c, info.underlineColor, info.underlineThickness,
+                                underlineXLeft, underlineXRight, y);
+                    }
+                    if (info.isUnderlineText) {
+                        drawUnderline(wp, c, wp.getColor(), ((Paint) wp).getUnderlineThickness(),
+                                underlineXLeft, underlineXRight, y);
+                    }
+                }
             }
 
             drawTextRun(c, wp, start, end, contextStart, contextEnd, runIsRtl,
-                    x, y + wp.baselineShift);
+                    leftX, y + wp.baselineShift);
         }
 
-        return runIsRtl ? -ret : ret;
+        return runIsRtl ? -totalWidth : totalWidth;
     }
 
     /**
@@ -864,6 +917,37 @@
         return result;
     }
 
+    private static final class UnderlineInfo {
+        public boolean isUnderlineText;
+        public int underlineColor;
+        public float underlineThickness;
+        public int start = -1;
+        public int end = -1;
+
+        public boolean hasUnderline() {
+            return isUnderlineText || underlineColor != 0;
+        }
+
+        // Copies the info, but not the start and end range.
+        public UnderlineInfo copyInfo() {
+            final UnderlineInfo copy = new UnderlineInfo();
+            copy.isUnderlineText = isUnderlineText;
+            copy.underlineColor = underlineColor;
+            copy.underlineThickness = underlineThickness;
+            return copy;
+        }
+    }
+
+    private void extractUnderlineInfo(@NonNull TextPaint paint, @NonNull UnderlineInfo info) {
+        info.isUnderlineText = paint.isUnderlineText();
+        if (info.isUnderlineText) {
+            paint.setUnderlineText(false);
+        }
+        info.underlineColor = paint.underlineColor;
+        info.underlineThickness = paint.underlineThickness;
+        paint.setUnderlineText(0, 0.0f);
+    }
+
     /**
      * Utility function for handling a unidirectional run.  The run must not
      * contain tabs but can contain styles.
@@ -894,7 +978,7 @@
 
         // Case of an empty line, make sure we update fmi according to mPaint
         if (start == measureLimit) {
-            TextPaint wp = mWorkPaint;
+            final TextPaint wp = mWorkPaint;
             wp.set(mPaint);
             if (fmi != null) {
                 expandMetricsFromPaint(fmi, wp);
@@ -903,11 +987,11 @@
         }
 
         if (mSpanned == null) {
-            TextPaint wp = mWorkPaint;
+            final TextPaint wp = mWorkPaint;
             wp.set(mPaint);
             wp.setHyphenEdit(adjustHyphenEdit(start, limit, wp.getHyphenEdit()));
             return handleText(wp, start, limit, start, limit, runIsRtl, c, x, top,
-                    y, bottom, fmi, needWidth, measureLimit);
+                    y, bottom, fmi, needWidth, measureLimit, null);
         }
 
         mMetricAffectingSpanSpanSet.init(mSpanned, mStart + start, mStart + limit);
@@ -920,7 +1004,7 @@
         // for the run bounds.
         final float originalX = x;
         for (int i = start, inext; i < measureLimit; i = inext) {
-            TextPaint wp = mWorkPaint;
+            final TextPaint wp = mWorkPaint;
             wp.set(mPaint);
 
             inext = mMetricAffectingSpanSpanSet.getNextTransition(mStart + i, mStart + limit) -
@@ -934,7 +1018,7 @@
                 // empty by construction. This special case in getSpans() explains the >= & <= tests
                 if ((mMetricAffectingSpanSpanSet.spanStarts[j] >= mStart + mlimit) ||
                         (mMetricAffectingSpanSpanSet.spanEnds[j] <= mStart + i)) continue;
-                MetricAffectingSpan span = mMetricAffectingSpanSpanSet.spans[j];
+                final MetricAffectingSpan span = mMetricAffectingSpanSpanSet.spans[j];
                 if (span instanceof ReplacementSpan) {
                     replacement = (ReplacementSpan)span;
                 } else {
@@ -950,26 +1034,68 @@
                 continue;
             }
 
+            final TextPaint activePaint = mActivePaint;
+            activePaint.set(mPaint);
+            int activeStart = i;
+            int activeEnd = mlimit;
+            final UnderlineInfo underlineInfo = mUnderlineInfo;
+            mUnderlines.clear();
             for (int j = i, jnext; j < mlimit; j = jnext) {
                 jnext = mCharacterStyleSpanSet.getNextTransition(mStart + j, mStart + inext) -
                         mStart;
-                int offset = Math.min(jnext, mlimit);
 
+                final int offset = Math.min(jnext, mlimit);
                 wp.set(mPaint);
                 for (int k = 0; k < mCharacterStyleSpanSet.numberOfSpans; k++) {
                     // Intentionally using >= and <= as explained above
                     if ((mCharacterStyleSpanSet.spanStarts[k] >= mStart + offset) ||
                             (mCharacterStyleSpanSet.spanEnds[k] <= mStart + j)) continue;
 
-                    CharacterStyle span = mCharacterStyleSpanSet.spans[k];
+                    final CharacterStyle span = mCharacterStyleSpanSet.spans[k];
                     span.updateDrawState(wp);
                 }
 
-                wp.setHyphenEdit(adjustHyphenEdit(j, jnext, wp.getHyphenEdit()));
+                extractUnderlineInfo(wp, underlineInfo);
 
-                x += handleText(wp, j, jnext, i, inext, runIsRtl, c, x,
-                        top, y, bottom, fmi, needWidth || jnext < measureLimit, offset);
+                if (j == i) {
+                    // First chunk of text. We can't handle it yet, since we may need to merge it
+                    // with the next chunk. So we just save the TextPaint for future comparisons
+                    // and use.
+                    activePaint.set(wp);
+                } else if (!wp.hasEqualAttributes(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.
+                    activePaint.setHyphenEdit(adjustHyphenEdit(
+                            activeStart, activeEnd, mPaint.getHyphenEdit()));
+                    x += handleText(activePaint, activeStart, activeEnd, i, inext, runIsRtl, c, x,
+                            top, y, bottom, fmi, needWidth || activeEnd < measureLimit,
+                            Math.min(activeEnd, mlimit), mUnderlines);
+
+                    activeStart = j;
+                    activePaint.set(wp);
+                    mUnderlines.clear();
+                } else {
+                    // The present TextPaint is substantially equal to the last TextPaint except
+                    // perhaps for underlines. We just need to expand the active piece of text to
+                    // include the present chunk, which we always do anyway. We don't need to save
+                    // wp to activePaint, since they are already equal.
+                }
+
+                activeEnd = jnext;
+                if (underlineInfo.hasUnderline()) {
+                    final UnderlineInfo copy = underlineInfo.copyInfo();
+                    copy.start = j;
+                    copy.end = jnext;
+                    mUnderlines.add(copy);
+                }
             }
+            // Handle the final piece of text.
+            activePaint.setHyphenEdit(adjustHyphenEdit(
+                    activeStart, activeEnd, mPaint.getHyphenEdit()));
+            x += handleText(activePaint, activeStart, activeEnd, i, inext, runIsRtl, c, x,
+                    top, y, bottom, fmi, needWidth || activeEnd < measureLimit,
+                    Math.min(activeEnd, mlimit), mUnderlines);
         }
 
         return x - originalX;
diff --git a/core/java/android/text/TextPaint.java b/core/java/android/text/TextPaint.java
index 4f8cff0..5234fa9 100644
--- a/core/java/android/text/TextPaint.java
+++ b/core/java/android/text/TextPaint.java
@@ -17,6 +17,7 @@
 package android.text;
 
 import android.annotation.ColorInt;
+import android.annotation.NonNull;
 import android.graphics.Paint;
 
 /**
@@ -40,7 +41,7 @@
     @ColorInt
     public int underlineColor = 0;
     /**
-     * Defined as a multiplier of the default underline thickness. Use 1.0f for default thickness.
+     * Thickness of the underline, in pixels.
      * @hide
      */
     public float underlineThickness;
@@ -74,6 +75,24 @@
     }
 
     /**
+     * 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
@@ -83,4 +102,16 @@
         underlineColor = color;
         underlineThickness = thickness;
     }
+
+    /**
+     * @hide
+     */
+    @Override
+    public float getUnderlineThickness() {
+        if (underlineColor != 0) { // Return custom thickness only if underline color is set.
+            return underlineThickness;
+        } else {
+            return super.getUnderlineThickness();
+        }
+    }
 }
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 585f882..3baadd4 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -1943,6 +1943,16 @@
         return charSequence;
     }
 
+    /**
+     * Prepends {@code start} and appends {@code end} to a given {@link StringBuilder}
+     *
+     * @hide
+     */
+    public static void wrap(StringBuilder builder, String start, String end) {
+        builder.insert(0, start);
+        builder.append(end);
+    }
+
     private static Object sLock = new Object();
 
     private static char[] sTemp = null;
diff --git a/core/java/android/util/AtomicFile.java b/core/java/android/util/AtomicFile.java
index 2f1abe9..0122e49 100644
--- a/core/java/android/util/AtomicFile.java
+++ b/core/java/android/util/AtomicFile.java
@@ -202,6 +202,15 @@
     }
 
     /**
+     * @hide
+     * Checks if the original or backup file exists.
+     * @return whether the original or backup file exists.
+     */
+    public boolean exists() {
+        return mBaseName.exists() || mBackupName.exists();
+    }
+
+    /**
      * Gets the last modified time of the atomic file.
      * {@hide}
      *
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index 951aa8d..0299865 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -30,8 +30,9 @@
 /**
  * API for sending log output.
  *
- * <p>Generally, use the Log.v() Log.d() Log.i() Log.w() and Log.e()
- * methods.
+ * <p>Generally, you should use the {@link #v Log.v()}, {@link #d Log.d()},
+ * {@link #i Log.i()}, {@link #w Log.w()}, and {@link #e Log.e()} methods to write logs.
+ * You can then <a href="{@docRoot}studio/debug/am-logcat.html">view the logs in logcat</a>.
  *
  * <p>The order in terms of verbosity, from least to most is
  * ERROR, WARN, INFO, DEBUG, VERBOSE.  Verbose should never be compiled
@@ -391,7 +392,7 @@
         // and the length of the tag.
         // Note: we implicitly accept possible truncation for Modified-UTF8 differences. It
         //       is too expensive to compute that ahead of time.
-        int bufferSize = NoPreloadHolder.LOGGER_ENTRY_MAX_PAYLOAD  // Base.
+        int bufferSize = PreloadHolder.LOGGER_ENTRY_MAX_PAYLOAD    // Base.
                 - 2                                                // Two terminators.
                 - (tag != null ? tag.length() : 0)                 // Tag length.
                 - 32;                                              // Some slack.
@@ -428,10 +429,10 @@
     }
 
     /**
-     * NoPreloadHelper class. Caches the LOGGER_ENTRY_MAX_PAYLOAD value to avoid
+     * PreloadHelper class. Caches the LOGGER_ENTRY_MAX_PAYLOAD value to avoid
      * a JNI call during logging.
      */
-    static class NoPreloadHolder {
+    static class PreloadHolder {
         public final static int LOGGER_ENTRY_MAX_PAYLOAD =
                 logger_entry_max_payload_native();
     }
diff --git a/core/java/android/util/MathUtils.java b/core/java/android/util/MathUtils.java
index 5c718f1..e865b6e 100644
--- a/core/java/android/util/MathUtils.java
+++ b/core/java/android/util/MathUtils.java
@@ -16,8 +16,6 @@
 
 package android.util;
 
-import java.util.Random;
-
 /**
  * A class that contains utility methods related to numbers.
  *
@@ -181,7 +179,7 @@
     }
 
     public static float map(float minStart, float minStop, float maxStart, float maxStop, float value) {
-        return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
+        return maxStart + (maxStop - maxStart) * ((value - minStart) / (minStop - minStart));
     }
 
     /**
diff --git a/core/java/android/util/MemoryIntArray.java b/core/java/android/util/MemoryIntArray.java
index 589edbc..bf33519 100644
--- a/core/java/android/util/MemoryIntArray.java
+++ b/core/java/android/util/MemoryIntArray.java
@@ -158,7 +158,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             IoUtils.closeQuietly(this);
         } finally {
             super.finalize();
diff --git a/core/java/android/util/MergedConfiguration.java b/core/java/android/util/MergedConfiguration.java
index 68d0309..ae66050 100644
--- a/core/java/android/util/MergedConfiguration.java
+++ b/core/java/android/util/MergedConfiguration.java
@@ -161,6 +161,21 @@
         return "{mGlobalConfig=" + mGlobalConfig + " mOverrideConfig=" + mOverrideConfig + "}";
     }
 
+    @Override
+    public int hashCode() {
+        return mMergedConfig.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (!(that instanceof MergedConfiguration)) {
+            return false;
+        }
+
+        if (that == this) return true;
+        return mMergedConfig.equals(((MergedConfiguration) that).mMergedConfig);
+    }
+
     public void dump(PrintWriter pw, String prefix) {
         pw.println(prefix + "mGlobalConfig=" + mGlobalConfig);
         pw.println(prefix + "mOverrideConfig=" + mOverrideConfig);
diff --git a/core/java/android/util/MutableBoolean.java b/core/java/android/util/MutableBoolean.java
new file mode 100644
index 0000000..ed837ab
--- /dev/null
+++ b/core/java/android/util/MutableBoolean.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ */
+public final class MutableBoolean {
+    public boolean value;
+
+    public MutableBoolean(boolean value) {
+        this.value = value;
+    }
+}
diff --git a/core/java/android/util/MutableByte.java b/core/java/android/util/MutableByte.java
new file mode 100644
index 0000000..cc6b00a
--- /dev/null
+++ b/core/java/android/util/MutableByte.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ */
+public final class MutableByte {
+    public byte value;
+
+    public MutableByte(byte value) {
+        this.value = value;
+    }
+}
diff --git a/core/java/android/util/MutableChar.java b/core/java/android/util/MutableChar.java
new file mode 100644
index 0000000..9a2e2bc
--- /dev/null
+++ b/core/java/android/util/MutableChar.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ */
+public final class MutableChar {
+    public char value;
+
+    public MutableChar(char value) {
+        this.value = value;
+    }
+}
diff --git a/core/java/android/util/MutableDouble.java b/core/java/android/util/MutableDouble.java
new file mode 100644
index 0000000..bd7329a
--- /dev/null
+++ b/core/java/android/util/MutableDouble.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ */
+public final class MutableDouble {
+    public double value;
+
+    public MutableDouble(double value) {
+        this.value = value;
+    }
+}
diff --git a/core/java/android/util/MutableFloat.java b/core/java/android/util/MutableFloat.java
new file mode 100644
index 0000000..e6f2d7d
--- /dev/null
+++ b/core/java/android/util/MutableFloat.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ */
+public final class MutableFloat {
+    public float value;
+
+    public MutableFloat(float value) {
+        this.value = value;
+    }
+}
diff --git a/core/java/android/util/MutableShort.java b/core/java/android/util/MutableShort.java
new file mode 100644
index 0000000..48fb232
--- /dev/null
+++ b/core/java/android/util/MutableShort.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ */
+public final class MutableShort {
+    public short value;
+
+    public MutableShort(short value) {
+        this.value = value;
+    }
+}
diff --git a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
index 0216a07..a9ccae1 100644
--- a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
+++ b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
@@ -17,6 +17,7 @@
 package android.util.apk;
 
 import android.system.ErrnoException;
+import android.system.Os;
 import android.system.OsConstants;
 import android.util.ArrayMap;
 import android.util.Pair;
@@ -59,9 +60,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import libcore.io.Libcore;
-import libcore.io.Os;
-
 /**
  * APK Signature Scheme v2 verifier.
  *
@@ -994,8 +992,7 @@
      * {@link DataSource#feedIntoMessageDigests(MessageDigest[], long, int) feedIntoMessageDigests}.
      */
     private static final class MemoryMappedFileDataSource implements DataSource {
-        private static final Os OS = Libcore.os;
-        private static final long MEMORY_PAGE_SIZE_BYTES = OS.sysconf(OsConstants._SC_PAGESIZE);
+        private static final long MEMORY_PAGE_SIZE_BYTES = Os.sysconf(OsConstants._SC_PAGESIZE);
 
         private final FileDescriptor mFd;
         private final long mFilePosition;
@@ -1041,7 +1038,7 @@
             long mmapRegionSize = size + dataStartOffsetInMmapRegion;
             long mmapPtr = 0;
             try {
-                mmapPtr = OS.mmap(
+                mmapPtr = Os.mmap(
                         0, // let the OS choose the start address of the region in memory
                         mmapRegionSize,
                         OsConstants.PROT_READ,
@@ -1066,7 +1063,7 @@
             } finally {
                 if (mmapPtr != 0) {
                     try {
-                        OS.munmap(mmapPtr, mmapRegionSize);
+                        Os.munmap(mmapPtr, mmapRegionSize);
                     } catch (ErrnoException ignored) {}
                 }
             }
diff --git a/core/java/android/util/proto/ProtoOutputStream.java b/core/java/android/util/proto/ProtoOutputStream.java
index 480abc1..9afa56d 100644
--- a/core/java/android/util/proto/ProtoOutputStream.java
+++ b/core/java/android/util/proto/ProtoOutputStream.java
@@ -24,7 +24,6 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
-import java.util.List;
 
 /**
  * Class to write to a protobuf stream.
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 1b74c13..45fa561 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_ACCESSIBLE_CLICKABLE_SPAN;
+import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_REQUESTED_KEY;
 import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY;
 
 import android.graphics.Point;
@@ -34,13 +35,17 @@
 import android.text.style.AccessibilityClickableSpan;
 import android.text.style.ClickableSpan;
 import android.util.LongSparseArray;
+import android.util.Slog;
 import android.view.View.AttachInfo;
 import android.view.accessibility.AccessibilityInteractionClient;
+import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeProvider;
+import android.view.accessibility.AccessibilityRequestPreparer;
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
 
 import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.SomeArgs;
 
 import java.util.ArrayList;
@@ -61,11 +66,24 @@
  */
 final class AccessibilityInteractionController {
 
+    private static final String LOG_TAG = "AccessibilityInteractionController";
+
+    // Debugging flag
     private static final boolean ENFORCE_NODE_TREE_CONSISTENT = false;
 
+    // Constants for readability
+    private static final boolean IGNORE_REQUEST_PREPARERS = true;
+    private static final boolean CONSIDER_REQUEST_PREPARERS = false;
+
+    // If an app holds off accessibility for longer than this, the hold-off is canceled to prevent
+    // accessibility from hanging
+    private static final long REQUEST_PREPARER_TIMEOUT_MS = 500;
+
     private final ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
         new ArrayList<AccessibilityNodeInfo>();
 
+    private final Object mLock = new Object();
+
     private final Handler mHandler;
 
     private final ViewRootImpl mViewRootImpl;
@@ -76,6 +94,8 @@
 
     private final int mMyProcessId;
 
+    private final AccessibilityManager mA11yManager;
+
     private final ArrayList<View> mTempArrayList = new ArrayList<View>();
 
     private final Point mTempPoint = new Point();
@@ -85,6 +105,13 @@
 
     private AddNodeInfosForViewId mAddNodeInfosForViewId;
 
+    @GuardedBy("mLock")
+    private int mNumActiveRequestPreparers;
+    @GuardedBy("mLock")
+    private List<MessageHolder> mMessagesWaitingForRequestPreparer;
+    @GuardedBy("mLock")
+    private int mActiveRequestPreparerId;
+
     public AccessibilityInteractionController(ViewRootImpl viewRootImpl) {
         Looper looper =  viewRootImpl.mHandler.getLooper();
         mMyLooperThreadId = looper.getThread().getId();
@@ -92,18 +119,23 @@
         mHandler = new PrivateHandler(looper);
         mViewRootImpl = viewRootImpl;
         mPrefetcher = new AccessibilityNodePrefetcher();
+        mA11yManager = mViewRootImpl.mContext.getSystemService(AccessibilityManager.class);
     }
 
-    private void scheduleMessage(Message message, int interrogatingPid, long interrogatingTid) {
-        // If the interrogation is performed by the same thread as the main UI
-        // thread in this process, set the message as a static reference so
-        // after this call completes the same thread but in the interrogating
-        // client can handle the message to generate the result.
-        if (interrogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) {
-            AccessibilityInteractionClient.getInstanceForThread(
-                    interrogatingTid).setSameThreadMessage(message);
-        } else {
-            mHandler.sendMessage(message);
+    private void scheduleMessage(Message message, int interrogatingPid, long interrogatingTid,
+            boolean ignoreRequestPreparers) {
+        if (ignoreRequestPreparers
+                || !holdOffMessageIfNeeded(message, interrogatingPid, interrogatingTid)) {
+            // If the interrogation is performed by the same thread as the main UI
+            // thread in this process, set the message as a static reference so
+            // after this call completes the same thread but in the interrogating
+            // client can handle the message to generate the result.
+            if (interrogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) {
+                AccessibilityInteractionClient.getInstanceForThread(
+                        interrogatingTid).setSameThreadMessage(message);
+            } else {
+                mHandler.sendMessage(message);
+            }
         }
     }
 
@@ -121,11 +153,11 @@
             long accessibilityNodeId, Region interactiveRegion, int interactionId,
             IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
             long interrogatingTid, MagnificationSpec spec, Bundle arguments) {
-        Message message = mHandler.obtainMessage();
+        final Message message = mHandler.obtainMessage();
         message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID;
         message.arg1 = flags;
 
-        SomeArgs args = SomeArgs.obtain();
+        final SomeArgs args = SomeArgs.obtain();
         args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
         args.argi2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId);
         args.argi3 = interactionId;
@@ -135,7 +167,141 @@
         args.arg4 = arguments;
         message.obj = args;
 
-        scheduleMessage(message, interrogatingPid, interrogatingTid);
+        scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
+    }
+
+    /**
+     * Check if this message needs to be held off while the app prepares to meet either this
+     * request, or a request ahead of it.
+     *
+     * @param originalMessage The message to be processed
+     * @param callingPid The calling process id
+     * @param callingTid The calling thread id
+     *
+     * @return {@code true} if the message is held off and will be processed later, {@code false} if
+     *         the message should be posted.
+     */
+    private boolean holdOffMessageIfNeeded(
+            Message originalMessage, int callingPid, long callingTid) {
+        synchronized (mLock) {
+            // If a request is already pending, queue this request for when it's finished
+            if (mNumActiveRequestPreparers != 0) {
+                queueMessageToHandleOncePrepared(originalMessage, callingPid, callingTid);
+                return true;
+            }
+
+            // Currently the only message that can hold things off is findByA11yId with extra data.
+            if (originalMessage.what
+                    != PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID) {
+                return false;
+            }
+            SomeArgs originalMessageArgs = (SomeArgs) originalMessage.obj;
+            Bundle requestArguments = (Bundle) originalMessageArgs.arg4;
+            if (requestArguments == null) {
+                return false;
+            }
+
+            // If nothing it registered for this view, nothing to do
+            int accessibilityViewId = originalMessageArgs.argi1;
+            final List<AccessibilityRequestPreparer> preparers =
+                    mA11yManager.getRequestPreparersForAccessibilityId(accessibilityViewId);
+            if (preparers == null) {
+                return false;
+            }
+
+            // If the bundle doesn't request the extra data, nothing to do
+            final String extraDataKey = requestArguments.getString(EXTRA_DATA_REQUESTED_KEY);
+            if (extraDataKey == null) {
+                return false;
+            }
+
+            // Send the request to the AccessibilityRequestPreparers on the UI thread
+            mNumActiveRequestPreparers = preparers.size();
+            for (int i = 0; i < preparers.size(); i++) {
+                final Message requestPreparerMessage = mHandler.obtainMessage(
+                        PrivateHandler.MSG_PREPARE_FOR_EXTRA_DATA_REQUEST);
+                final SomeArgs requestPreparerArgs = SomeArgs.obtain();
+                // virtualDescendentId
+                requestPreparerArgs.argi1 =
+                        (originalMessageArgs.argi2 == AccessibilityNodeInfo.UNDEFINED_ITEM_ID)
+                        ? AccessibilityNodeProvider.HOST_VIEW_ID : originalMessageArgs.argi2;
+                requestPreparerArgs.arg1 = preparers.get(i);
+                requestPreparerArgs.arg2 = extraDataKey;
+                requestPreparerArgs.arg3 = requestArguments;
+                Message preparationFinishedMessage = mHandler.obtainMessage(
+                        PrivateHandler.MSG_APP_PREPARATION_FINISHED);
+                preparationFinishedMessage.arg1 = ++mActiveRequestPreparerId;
+                requestPreparerArgs.arg4 = preparationFinishedMessage;
+
+                requestPreparerMessage.obj = requestPreparerArgs;
+                scheduleMessage(requestPreparerMessage, callingPid, callingTid,
+                        IGNORE_REQUEST_PREPARERS);
+                mHandler.obtainMessage(PrivateHandler.MSG_APP_PREPARATION_TIMEOUT);
+                mHandler.sendEmptyMessageDelayed(PrivateHandler.MSG_APP_PREPARATION_TIMEOUT,
+                        REQUEST_PREPARER_TIMEOUT_MS);
+            }
+
+            // Set the initial request aside
+            queueMessageToHandleOncePrepared(originalMessage, callingPid, callingTid);
+            return true;
+        }
+    }
+
+    private void prepareForExtraDataRequestUiThread(Message message) {
+        SomeArgs args = (SomeArgs) message.obj;
+        final int virtualDescendantId = args.argi1;
+        final AccessibilityRequestPreparer preparer = (AccessibilityRequestPreparer) args.arg1;
+        final String extraDataKey = (String) args.arg2;
+        final Bundle requestArguments = (Bundle) args.arg3;
+        final Message preparationFinishedMessage = (Message) args.arg4;
+
+        preparer.onPrepareExtraData(virtualDescendantId, extraDataKey,
+                requestArguments, preparationFinishedMessage);
+    }
+
+    private void queueMessageToHandleOncePrepared(Message message, int interrogatingPid,
+            long interrogatingTid) {
+        if (mMessagesWaitingForRequestPreparer == null) {
+            mMessagesWaitingForRequestPreparer = new ArrayList<>(1);
+        }
+        MessageHolder messageHolder =
+                new MessageHolder(message, interrogatingPid, interrogatingTid);
+        mMessagesWaitingForRequestPreparer.add(messageHolder);
+    }
+
+    private void requestPreparerDoneUiThread(Message message) {
+        synchronized (mLock) {
+            if (message.arg1 != mActiveRequestPreparerId) {
+                Slog.e(LOG_TAG, "Surprising AccessibilityRequestPreparer callback (likely late)");
+                return;
+            }
+            mNumActiveRequestPreparers--;
+            if (mNumActiveRequestPreparers <= 0) {
+                mHandler.removeMessages(PrivateHandler.MSG_APP_PREPARATION_TIMEOUT);
+                scheduleAllMessagesWaitingForRequestPreparerLocked();
+            }
+        }
+    }
+
+    private void requestPreparerTimeoutUiThread() {
+        synchronized (mLock) {
+            Slog.e(LOG_TAG, "AccessibilityRequestPreparer timed out");
+            scheduleAllMessagesWaitingForRequestPreparerLocked();
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void scheduleAllMessagesWaitingForRequestPreparerLocked() {
+        int numMessages = mMessagesWaitingForRequestPreparer.size();
+        for (int i = 0; i < numMessages; i++) {
+            MessageHolder request = mMessagesWaitingForRequestPreparer.get(i);
+            scheduleMessage(request.mMessage, request.mInterrogatingPid,
+                    request.mInterrogatingTid,
+                    (i == 0) /* the app is ready for the first request */);
+        }
+        mMessagesWaitingForRequestPreparer.clear();
+        mNumActiveRequestPreparers = 0; // Just to be safe - should be unnecessary
+        mActiveRequestPreparerId = -1;
     }
 
     private void findAccessibilityNodeInfoByAccessibilityIdUiThread(Message message) {
@@ -193,7 +359,7 @@
         args.arg4 = interactiveRegion;
         message.obj = args;
 
-        scheduleMessage(message, interrogatingPid, interrogatingTid);
+        scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
     }
 
     private void findAccessibilityNodeInfosByViewIdUiThread(Message message) {
@@ -259,7 +425,7 @@
         args.arg4 = interactiveRegion;
         message.obj = args;
 
-        scheduleMessage(message, interrogatingPid, interrogatingTid);
+        scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
     }
 
     private void findAccessibilityNodeInfosByTextUiThread(Message message) {
@@ -347,7 +513,7 @@
 
         message.obj = args;
 
-        scheduleMessage(message, interrogatingPid, interrogatingTid);
+        scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
     }
 
     private void findFocusUiThread(Message message) {
@@ -442,7 +608,7 @@
 
         message.obj = args;
 
-        scheduleMessage(message, interrogatingPid, interrogatingTid);
+        scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
     }
 
     private void focusSearchUiThread(Message message) {
@@ -501,7 +667,7 @@
 
         message.obj = args;
 
-        scheduleMessage(message, interrogatingPid, interrogatingTid);
+        scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
     }
 
     private void performAccessibilityActionUiThread(Message message) {
@@ -787,7 +953,7 @@
             AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider();
             // Determine if we'll be populating extra data
             final String extraDataRequested = (arguments == null) ? null
-                    : arguments.getString(AccessibilityNodeInfo.EXTRA_DATA_REQUESTED_KEY);
+                    : arguments.getString(EXTRA_DATA_REQUESTED_KEY);
             if (provider == null) {
                 AccessibilityNodeInfo root = view.createAccessibilityNodeInfo();
                 if (root != null) {
@@ -1115,6 +1281,9 @@
         private static final int MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT = 4;
         private static final int MSG_FIND_FOCUS = 5;
         private static final int MSG_FOCUS_SEARCH = 6;
+        private static final int MSG_PREPARE_FOR_EXTRA_DATA_REQUEST = 7;
+        private static final int MSG_APP_PREPARATION_FINISHED = 8;
+        private static final int MSG_APP_PREPARATION_TIMEOUT = 9;
 
         public PrivateHandler(Looper looper) {
             super(looper);
@@ -1136,6 +1305,12 @@
                     return "MSG_FIND_FOCUS";
                 case MSG_FOCUS_SEARCH:
                     return "MSG_FOCUS_SEARCH";
+                case MSG_PREPARE_FOR_EXTRA_DATA_REQUEST:
+                    return "MSG_PREPARE_FOR_EXTRA_DATA_REQUEST";
+                case MSG_APP_PREPARATION_FINISHED:
+                    return "MSG_APP_PREPARATION_FINISHED";
+                case MSG_APP_PREPARATION_TIMEOUT:
+                    return "MSG_APP_PREPARATION_TIMEOUT";
                 default:
                     throw new IllegalArgumentException("Unknown message type: " + type);
             }
@@ -1163,6 +1338,15 @@
                 case MSG_FOCUS_SEARCH: {
                     focusSearchUiThread(message);
                 } break;
+                case MSG_PREPARE_FOR_EXTRA_DATA_REQUEST: {
+                    prepareForExtraDataRequestUiThread(message);
+                } break;
+                case MSG_APP_PREPARATION_FINISHED: {
+                    requestPreparerDoneUiThread(message);
+                } break;
+                case MSG_APP_PREPARATION_TIMEOUT: {
+                    requestPreparerTimeoutUiThread();
+                } break;
                 default:
                     throw new IllegalArgumentException("Unknown message type: " + type);
             }
@@ -1191,4 +1375,16 @@
             return false;
         }
     }
+
+    private static final class MessageHolder {
+        final Message mMessage;
+        final int mInterrogatingPid;
+        final long mInterrogatingTid;
+
+        MessageHolder(Message message, int interrogatingPid, long interrogatingTid) {
+            mMessage = message;
+            mInterrogatingPid = interrogatingPid;
+            mInterrogatingTid = interrogatingTid;
+        }
+    }
 }
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 3e9fab1..9778893 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -21,6 +21,7 @@
 import android.annotation.IntDef;
 import android.annotation.RequiresPermission;
 import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
@@ -854,6 +855,9 @@
 
     /**
      * Returns whether this display can be used to display wide color gamut content.
+     * This does not necessarily mean the device itself can render wide color gamut
+     * content. To ensure wide color gamut content can be produced, refer to
+     * {@link Configuration#isScreenWideColorGamut()}.
      */
     public boolean isWideColorGamut() {
         synchronized (this) {
@@ -1118,6 +1122,15 @@
     }
 
     /**
+     * Returns true if the display may be in a reduced operating mode while in the
+     * specified display power state.
+     * @hide
+     */
+    public static boolean isDozeState(int state) {
+        return state == STATE_DOZE || state == STATE_DOZE_SUSPEND;
+    }
+
+    /**
      * A mode supported by a given display.
      *
      * @see Display#getSupportedModes()
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index 48e5ca9..21b72f3 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -193,6 +193,8 @@
     private View findNextUserSpecifiedFocus(ViewGroup root, View focused, int direction) {
         // check for user specified next focus
         View userSetNextFocus = focused.findUserSetNextFocus(root, direction);
+        View cycleCheck = userSetNextFocus;
+        boolean cycleStep = true; // we want the first toggle to yield false
         while (userSetNextFocus != null) {
             if (userSetNextFocus.isFocusable()
                     && userSetNextFocus.getVisibility() == View.VISIBLE
@@ -201,6 +203,14 @@
                 return userSetNextFocus;
             }
             userSetNextFocus = userSetNextFocus.findUserSetNextFocus(root, direction);
+            if (cycleStep = !cycleStep) {
+                cycleCheck = cycleCheck.findUserSetNextFocus(root, direction);
+                if (cycleCheck == userSetNextFocus) {
+                    // found a cycle, user-specified focus forms a loop and none of the views
+                    // are currently focusable.
+                    break;
+                }
+            }
         }
         return null;
     }
@@ -520,7 +530,7 @@
      * axis distances.  Warning: this fudge factor is finely tuned, be sure to
      * run all focus tests if you dare tweak it.
      */
-    int getWeightedDistanceFor(int majorAxisDistance, int minorAxisDistance) {
+    long getWeightedDistanceFor(long majorAxisDistance, long minorAxisDistance) {
         return 13 * majorAxisDistance * majorAxisDistance
                 + minorAxisDistance * minorAxisDistance;
     }
diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java
index 2f87d2e..c431323 100644
--- a/core/java/android/view/HapticFeedbackConstants.java
+++ b/core/java/android/view/HapticFeedbackConstants.java
@@ -29,12 +29,12 @@
      * in an action being performed.
      */
     public static final int LONG_PRESS = 0;
-    
+
     /**
      * The user has pressed on a virtual on-screen key.
      */
     public static final int VIRTUAL_KEY = 1;
-    
+
     /**
      * The user has pressed a soft keyboard key.
      */
@@ -57,24 +57,31 @@
     public static final int CONTEXT_CLICK = 6;
 
     /**
-     * This is a private constant.  Feel free to renumber as desired.
+     * The user has released a virtual or software keyboard key.
      * @hide
      */
-    public static final int SAFE_MODE_DISABLED = 10000;
-    
+    public static final int VIRTUAL_KEY_RELEASE = 7;
+
     /**
+     * The user has performed a selection/insertion handle move on text field.
+     * @hide
+     */
+    public static final int TEXT_HANDLE_MOVE = 8;
+
+    /**
+     * The phone has booted with safe mode enabled.
      * This is a private constant.  Feel free to renumber as desired.
      * @hide
      */
     public static final int SAFE_MODE_ENABLED = 10001;
-    
+
     /**
      * Flag for {@link View#performHapticFeedback(int, int)
      * View.performHapticFeedback(int, int)}: Ignore the setting in the
      * view for whether to perform haptic feedback, do it always.
      */
     public static final int FLAG_IGNORE_VIEW_SETTING = 0x0001;
-    
+
     /**
      * Flag for {@link View#performHapticFeedback(int, int)
      * View.performHapticFeedback(int, int)}: Ignore the global setting
diff --git a/core/java/android/view/IWallpaperVisibilityListener.aidl b/core/java/android/view/IWallpaperVisibilityListener.aidl
new file mode 100644
index 0000000..349f984
--- /dev/null
+++ b/core/java/android/view/IWallpaperVisibilityListener.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+/**
+ * Listener to be invoked when wallpaper visibility changes.
+ * {@hide}
+ */
+oneway interface IWallpaperVisibilityListener {
+    /**
+     * Method that will be invoked when wallpaper becomes visible or hidden.
+     * @param visible True if wallpaper is being displayed; false otherwise.
+     * @param displayId The id of the display where wallpaper visibility changed.
+     */
+    void onWallpaperVisibilityChanged(boolean visible, int displayId);
+}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 58a6a5e..e576a0f 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -29,6 +29,7 @@
 import android.graphics.GraphicBuffer;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.Bundle;
 import android.os.IRemoteCallback;
 import android.os.ParcelFileDescriptor;
@@ -38,6 +39,7 @@
 import android.view.IOnKeyguardExitResult;
 import android.view.IPinnedStackListener;
 import android.view.IRotationWatcher;
+import android.view.IWallpaperVisibilityListener;
 import android.view.IWindowSession;
 import android.view.IWindowSessionCallback;
 import android.view.KeyEvent;
@@ -255,6 +257,19 @@
     Bitmap screenshotWallpaper();
 
     /**
+     * Registers a wallpaper visibility listener.
+     * @return Current visibility.
+     */
+    boolean registerWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
+        int displayId);
+
+    /**
+     * Remove a visibility watcher that was added using registerWallpaperVisibilityListener.
+     */
+    void unregisterWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
+        int displayId);
+
+    /**
      * Used only for assist -- request a screenshot of the current application.
      */
     boolean requestAssistScreenshot(IAssistScreenshotReceiver receiver);
@@ -377,4 +392,9 @@
      * associated with that InputConsumer.
      */
     boolean destroyInputConsumer(String name);
+
+    /**
+     * Return the touch region for the current IME window, or an empty region if there is none.
+     */
+    Region getCurrentImeTouchRegion();
 }
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index ea2434e..15be2b0 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -16,6 +16,8 @@
 
 package android.view;
 
+import android.annotation.RequiresPermission;
+import android.annotation.TestApi;
 import android.content.Context;
 import android.hardware.input.InputDeviceIdentifier;
 import android.hardware.input.InputManager;
@@ -768,6 +770,37 @@
     }
 
     /**
+     * Returns true if input device is enabled.
+     * @return Whether the input device is enabled.
+     * @hide
+     */
+    public boolean isEnabled() {
+        return InputManager.getInstance().isInputDeviceEnabled(mId);
+    }
+
+    /**
+     * Enables the input device.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE)
+    @TestApi
+    public void enable() {
+        InputManager.getInstance().enableInputDevice(mId);
+    }
+
+    /**
+     * Disables the input device.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE)
+    @TestApi
+    public void disable() {
+        InputManager.getInstance().disableInputDevice(mId);
+    }
+
+    /**
      * Reports whether the device has a built-in microphone.
      * @return Whether the device has a built-in microphone.
      */
diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java
index 20ab539..c566a65 100644
--- a/core/java/android/view/InputEventReceiver.java
+++ b/core/java/android/view/InputEventReceiver.java
@@ -111,9 +111,10 @@
      * to indicate whether the event was handled.  No new input events will be received
      * until {@link #finishInputEvent} is called.
      *
+     * @param displayId The display id on which input event triggered.
      * @param event The input event that was received.
      */
-    public void onInputEvent(InputEvent event) {
+    public void onInputEvent(InputEvent event, int displayId) {
         finishInputEvent(event, false);
     }
 
@@ -180,9 +181,9 @@
 
     // Called from native code.
     @SuppressWarnings("unused")
-    private void dispatchInputEvent(int seq, InputEvent event) {
+    private void dispatchInputEvent(int seq, InputEvent event, int displayId) {
         mSeqMap.put(event.getSequenceNumber(), seq);
-        onInputEvent(event);
+        onInputEvent(event, displayId);
     }
 
     // Called from native code.
diff --git a/core/java/android/view/KeyboardShortcutGroup.java b/core/java/android/view/KeyboardShortcutGroup.java
index 78f0b30..52e9832 100644
--- a/core/java/android/view/KeyboardShortcutGroup.java
+++ b/core/java/android/view/KeyboardShortcutGroup.java
@@ -19,6 +19,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -58,6 +59,7 @@
      * @param isSystemGroup Set this to {@code true} if this is s system group.
      * @hide
      */
+    @TestApi
     public KeyboardShortcutGroup(@Nullable CharSequence label,
             @NonNull List<KeyboardShortcutInfo> items, boolean isSystemGroup) {
         mLabel = label;
@@ -70,6 +72,7 @@
      * @param isSystemGroup Set this to {@code true} if this is s system group.
      * @hide
      */
+    @TestApi
     public KeyboardShortcutGroup(@Nullable CharSequence label, boolean isSystemGroup) {
         this(label, Collections.<KeyboardShortcutInfo>emptyList(), isSystemGroup);
     }
@@ -96,6 +99,7 @@
     }
 
     /** @hide **/
+    @TestApi
     public boolean isSystemGroup() {
         return mSystemGroup;
     }
@@ -123,11 +127,11 @@
 
     public static final Creator<KeyboardShortcutGroup> CREATOR =
             new Creator<KeyboardShortcutGroup>() {
-        public KeyboardShortcutGroup createFromParcel(Parcel source) {
-            return new KeyboardShortcutGroup(source);
-        }
-        public KeyboardShortcutGroup[] newArray(int size) {
-            return new KeyboardShortcutGroup[size];
-        }
-    };
+                public KeyboardShortcutGroup createFromParcel(Parcel source) {
+                    return new KeyboardShortcutGroup(source);
+                }
+                public KeyboardShortcutGroup[] newArray(int size) {
+                    return new KeyboardShortcutGroup[size];
+                }
+            };
 }
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index 20f7ace..5804560 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -19,6 +19,7 @@
 import android.annotation.Nullable;
 import android.app.Notification;
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Outline;
 import android.graphics.Rect;
@@ -27,6 +28,7 @@
 import android.widget.ImageView;
 import android.widget.RemoteViews;
 
+import com.android.internal.R;
 import com.android.internal.widget.CachingIconView;
 
 import java.util.ArrayList;
@@ -52,9 +54,13 @@
     private int mIconColor;
     private int mOriginalNotificationColor;
     private boolean mExpanded;
+    private boolean mShowExpandButtonAtEnd;
     private boolean mShowWorkBadgeAtEnd;
     private Drawable mBackground;
     private int mHeaderBackgroundHeight;
+    private boolean mEntireHeaderClickable;
+    private boolean mExpandOnlyOnButton;
+    private boolean mAcceptAllTouches;
 
     ViewOutlineProvider mProvider = new ViewOutlineProvider() {
         @Override
@@ -65,7 +71,6 @@
             }
         }
     };
-    private boolean mAcceptAllTouches;
 
     public NotificationHeaderView(Context context) {
         this(context, null);
@@ -81,12 +86,12 @@
 
     public NotificationHeaderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        mChildMinWidth = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_header_shrink_min_width);
-        mContentEndMargin = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_content_margin_end);
-        mHeaderBackgroundHeight = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_header_background_height);
+        Resources res = getResources();
+        mChildMinWidth = res.getDimensionPixelSize(R.dimen.notification_header_shrink_min_width);
+        mContentEndMargin = res.getDimensionPixelSize(R.dimen.notification_content_margin_end);
+        mHeaderBackgroundHeight = res.getDimensionPixelSize(
+                R.dimen.notification_header_background_height);
+        mEntireHeaderClickable = res.getBoolean(R.bool.config_notificationHeaderClickableForExpand);
     }
 
     @Override
@@ -147,8 +152,9 @@
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         int left = getPaddingStart();
+        int end = getMeasuredWidth();
         int childCount = getChildCount();
-        int ownHeight = getHeight() - getPaddingTop() - getPaddingBottom();
+        int ownHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
         for (int i = 0; i < childCount; i++) {
             View child = getChildAt(i);
             if (child.getVisibility() == GONE) {
@@ -162,13 +168,17 @@
             int bottom = top + childHeight;
             int layoutLeft = left;
             int layoutRight = right;
+            if (child == mExpandButton && mShowExpandButtonAtEnd) {
+                layoutRight = end - mContentEndMargin;
+                end = layoutLeft = layoutRight - child.getMeasuredWidth();
+            }
             if (child == mProfileBadge) {
                 int paddingEnd = getPaddingEnd();
                 if (mShowWorkBadgeAtEnd) {
                     paddingEnd = mContentEndMargin;
                 }
-                layoutRight = getWidth() - paddingEnd;
-                layoutLeft = layoutRight - child.getMeasuredWidth();
+                layoutRight = end - paddingEnd;
+                end = layoutLeft = layoutRight - child.getMeasuredWidth();
             }
             if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
                 int ltrLeft = layoutLeft;
@@ -265,13 +275,11 @@
         int drawableId;
         int contentDescriptionId;
         if (mExpanded) {
-            drawableId = com.android.internal.R.drawable.ic_collapse_notification;
-            contentDescriptionId
-                    = com.android.internal.R.string.expand_button_content_description_expanded;
+            drawableId = R.drawable.ic_collapse_notification;
+            contentDescriptionId = R.string.expand_button_content_description_expanded;
         } else {
-            drawableId = com.android.internal.R.drawable.ic_expand_notification;
-            contentDescriptionId
-                    = com.android.internal.R.string.expand_button_content_description_collapsed;
+            drawableId = R.drawable.ic_expand_notification;
+            contentDescriptionId = R.string.expand_button_content_description_collapsed;
         }
         mExpandButton.setImageDrawable(getContext().getDrawable(drawableId));
         mExpandButton.setColorFilter(mOriginalNotificationColor);
@@ -285,6 +293,18 @@
         }
     }
 
+    /**
+     * Sets whether or not the expand button appears at the end of the NotificationHeaderView. If
+     * both this and {@link #setShowWorkBadgeAtEnd(boolean)} have been set to true, then the
+     * expand button will appear closer to the end than the work badge.
+     */
+    public void setShowExpandButtonAtEnd(boolean showExpandButtonAtEnd) {
+        if (showExpandButtonAtEnd != mShowExpandButtonAtEnd) {
+            setClipToPadding(!showExpandButtonAtEnd);
+            mShowExpandButtonAtEnd = showExpandButtonAtEnd;
+        }
+    }
+
     public View getWorkProfileIcon() {
         return mProfileBadge;
     }
@@ -296,6 +316,7 @@
     public class HeaderTouchListener implements View.OnTouchListener {
 
         private final ArrayList<Rect> mTouchRects = new ArrayList<>();
+        private Rect mExpandButtonRect;
         private int mTouchSlop;
         private boolean mTrackGesture;
         private float mDownX;
@@ -306,8 +327,8 @@
 
         public void bindTouchRects() {
             mTouchRects.clear();
-            addRectAroundViewView(mIcon);
-            addRectAroundViewView(mExpandButton);
+            addRectAroundView(mIcon);
+            mExpandButtonRect = addRectAroundView(mExpandButton);
             addWidthRect();
             mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
         }
@@ -321,9 +342,10 @@
             mTouchRects.add(r);
         }
 
-        private void addRectAroundViewView(View view) {
+        private Rect addRectAroundView(View view) {
             final Rect r = getRectAroundView(view);
             mTouchRects.add(r);
+            return r;
         }
 
         private Rect getRectAroundView(View view) {
@@ -376,6 +398,9 @@
             if (mAcceptAllTouches) {
                 return true;
             }
+            if (mExpandOnlyOnButton) {
+                return mExpandButtonRect.contains((int) x, (int) y);
+            }
             for (int i = 0; i < mTouchRects.size(); i++) {
                 Rect r = mTouchRects.get(i);
                 if (r.contains((int) x, (int) y)) {
@@ -412,8 +437,21 @@
         return mTouchListener.isInside(x, y);
     }
 
+    /**
+     * Sets whether or not all touches to this header view will register as a click. Note that
+     * if the config value for {@code config_notificationHeaderClickableForExpand} is {@code true},
+     * then calling this method with {@code false} will not override that configuration.
+     */
     @RemotableViewMethod
     public void setAcceptAllTouches(boolean acceptAllTouches) {
-        mAcceptAllTouches = acceptAllTouches;
+        mAcceptAllTouches = mEntireHeaderClickable || acceptAllTouches;
+    }
+
+    /**
+     * Sets whether only the expand icon itself should serve as the expand target.
+     */
+    @RemotableViewMethod
+    public void setExpandOnlyOnButton(boolean expandOnlyOnButton) {
+        mExpandOnlyOnButton = expandOnlyOnButton;
     }
 }
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 22329f4..1a2968f 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -65,7 +65,8 @@
     private static native void nativeSetSize(long nativeObject, int w, int h);
     private static native void nativeSetTransparentRegionHint(long nativeObject, Region region);
     private static native void nativeSetAlpha(long nativeObject, float alpha);
-    private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx, float dsdy, float dtdy);
+    private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx,
+            float dtdy, float dsdy);
     private static native void nativeSetFlags(long nativeObject, int flags, int mask);
     private static native void nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b);
     private static native void nativeSetFinalCrop(long nativeObject, int l, int t, int r, int b);
@@ -272,6 +273,15 @@
     public static final int POWER_MODE_DOZE_SUSPEND = 3;
 
     /**
+     * A value for windowType used to indicate that the window should be omitted from screenshots
+     * and display mirroring. A temporary workaround until we express such things with
+     * the hierarchy.
+     * TODO: b/64227542
+     * @hide
+     */
+    public static final int WINDOW_TYPE_DONT_SCREENSHOT = 441731;
+
+    /**
      * Create a surface with a name.
      * <p>
      * The surface creation flags specify what kind of surface to create and
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index b035b7f..cac27af 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -491,10 +491,10 @@
         if (myHeight <= 0) myHeight = getHeight();
 
         final boolean formatChanged = mFormat != mRequestedFormat;
-        final boolean creating = (mSurfaceControl == null || formatChanged)
+        final boolean visibleChanged = mVisible != mRequestedVisible;
+        final boolean creating = (mSurfaceControl == null || formatChanged || visibleChanged)
                 && mRequestedVisible;
         final boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight;
-        final boolean visibleChanged = mVisible != mRequestedVisible;
         final boolean windowVisibleChanged = mWindowVisibility != mLastWindowVisibility;
         boolean redrawNeeded = false;
 
@@ -729,7 +729,7 @@
                 mLocation[1] = getHeight();
 
                 mScreenRect.set(mWindowSpaceLeft, mWindowSpaceTop,
-                        mLocation[0], mLocation[1]);
+                        mWindowSpaceLeft + mLocation[0], mWindowSpaceTop + mLocation[1]);
 
                 if (mTranslator != null) {
                     mTranslator.translateRectInAppWindowToScreen(mScreenRect);
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index a140f28..489de56 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -29,6 +29,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemProperties;
 import android.os.Trace;
 import android.util.Log;
 import android.view.Surface.OutOfResourcesException;
@@ -188,6 +189,11 @@
     public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY =
             "debug.hwui.show_non_rect_clip";
 
+    static {
+        // Try to check OpenGL support early if possible.
+        isAvailable();
+    }
+
     /**
      * A process can set this flag to false to prevent the use of threaded
      * rendering.
@@ -227,8 +233,7 @@
         sTrimForeground = true;
     }
 
-    private static native boolean nSupportsOpenGL();
-    private static boolean sSupportsOpenGL = nSupportsOpenGL();
+    private static Boolean sSupportsOpenGL;
 
     /**
      * Indicates whether threaded rendering is available under any form for
@@ -238,7 +243,24 @@
      *         false otherwise
      */
     public static boolean isAvailable() {
-        return sSupportsOpenGL;
+        if (sSupportsOpenGL != null) {
+            return sSupportsOpenGL.booleanValue();
+        }
+        if (SystemProperties.getInt("ro.kernel.qemu", 0) == 0) {
+            // Device is not an emulator.
+            sSupportsOpenGL = true;
+            return true;
+        }
+        int qemu_gles = SystemProperties.getInt("qemu.gles", -1);
+        if (qemu_gles == -1) {
+            // In this case, the value of the qemu.gles property is not ready
+            // because the SurfaceFlinger service may not start at this point.
+            return false;
+        }
+        // In the emulator this property will be set > 0 when OpenGL ES 2.0 is
+        // enabled, 0 otherwise. On old emulator versions it will be undefined.
+        sSupportsOpenGL = qemu_gles > 0;
+        return sSupportsOpenGL.booleanValue();
     }
 
     /**
@@ -336,7 +358,6 @@
     private long mNativeProxy;
     private boolean mInitialized = false;
     private RenderNode mRootNode;
-    private Choreographer mChoreographer;
     private boolean mRootNodeNeedsUpdate;
 
     private boolean mEnabled;
@@ -405,8 +426,6 @@
     /**
      * Indicates whether threaded rendering is currently requested but not
      * necessarily enabled yet.
-     *
-     * @return True to request threaded rendering, false otherwise.
      */
     void setRequested(boolean requested) {
         mRequested = requested;
@@ -582,6 +601,13 @@
     }
 
     /**
+     * Enable/disable wide gamut rendering on this renderer.
+     */
+    void setWideGamut(boolean wideGamut) {
+        nSetWideGamut(mNativeProxy, wideGamut);
+    }
+
+    /**
      * Gets the current width of the surface. This is the width that the surface
      * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
      *
@@ -918,11 +944,11 @@
             if (mInitialized) return;
             mInitialized = true;
             mAppContext = context.getApplicationContext();
-            initSched(context, renderProxy);
+            initSched(renderProxy);
             initGraphicsStats();
         }
 
-        private void initSched(Context context, long renderProxy) {
+        private void initSched(long renderProxy) {
             try {
                 int tid = nGetRenderThreadTid(renderProxy);
                 ActivityManager.getService().setRenderThread(tid);
@@ -995,6 +1021,7 @@
     private static native void nSetLightCenter(long nativeProxy,
             float lightX, float lightY, float lightZ);
     private static native void nSetOpaque(long nativeProxy, boolean opaque);
+    private static native void nSetWideGamut(long nativeProxy, boolean wideGamut);
     private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
     private static native void nDestroy(long nativeProxy, long rootRenderNode);
     private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4882165..47e8b58 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -724,6 +724,8 @@
  * @attr ref android.R.styleable#View_nextFocusUp
  * @attr ref android.R.styleable#View_onClick
  * @attr ref android.R.styleable#View_padding
+ * @attr ref android.R.styleable#View_paddingHorizontal
+ * @attr ref android.R.styleable#View_paddingVertical
  * @attr ref android.R.styleable#View_paddingBottom
  * @attr ref android.R.styleable#View_paddingLeft
  * @attr ref android.R.styleable#View_paddingRight
@@ -2108,8 +2110,6 @@
 
     private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
 
-    SendViewStateChangedAccessibilityEvent mSendViewStateChangedAccessibilityEvent;
-
     /**
      * The view's tag.
      * {@hide}
@@ -11162,11 +11162,21 @@
         if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) {
             return;
         }
-        if (mSendViewStateChangedAccessibilityEvent == null) {
-            mSendViewStateChangedAccessibilityEvent =
-                    new SendViewStateChangedAccessibilityEvent();
+        // If this is a live region, we should send a subtree change event
+        // from this view immediately. Otherwise, we can let it propagate up.
+        if (getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE) {
+            final AccessibilityEvent event = AccessibilityEvent.obtain();
+            event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+            event.setContentChangeTypes(changeType);
+            sendAccessibilityEventUnchecked(event);
+        } else if (mParent != null) {
+            try {
+                mParent.notifySubtreeAccessibilityStateChanged(this, this, changeType);
+            } catch (AbstractMethodError e) {
+                Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                        " does not fully implement ViewParent", e);
+            }
         }
-        mSendViewStateChangedAccessibilityEvent.runOrPost(changeType);
     }
 
     /**
@@ -13271,7 +13281,7 @@
                 // about in case nothing has focus.  even if this specific view
                 // isn't focusable, it may contain something that is, so let
                 // the root view try to give this focus if nothing else does.
-                if ((mParent != null)) {
+                if ((mParent != null) && (mBottom > mTop) && (mRight > mLeft)) {
                     mParent.focusableViewAvailable(this);
                 }
             }
@@ -25897,8 +25907,8 @@
          * </p>
          * <p>
          * The default implementation behaves as
-         * {@link View#addExtraDataToAccessibilityNodeInfo(AccessibilityNodeInfo, int) for
-         * the case where no accessibility delegate is set.
+         * {@link View#addExtraDataToAccessibilityNodeInfo(AccessibilityNodeInfo, String, Bundle)
+         * for the case where no accessibility delegate is set.
          * </p>
          *
          * @param host The View hosting the delegate. Never {@code null}.
@@ -26006,79 +26016,6 @@
         }
     }
 
-    private class SendViewStateChangedAccessibilityEvent implements Runnable {
-        private int mChangeTypes = 0;
-        private boolean mPosted;
-        private boolean mPostedWithDelay;
-        private long mLastEventTimeMillis;
-
-        @Override
-        public void run() {
-            mPosted = false;
-            mPostedWithDelay = false;
-            mLastEventTimeMillis = SystemClock.uptimeMillis();
-            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-                final AccessibilityEvent event = AccessibilityEvent.obtain();
-                event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
-                event.setContentChangeTypes(mChangeTypes);
-                sendAccessibilityEventUnchecked(event);
-            }
-            mChangeTypes = 0;
-        }
-
-        public void runOrPost(int changeType) {
-            mChangeTypes |= changeType;
-
-            // If this is a live region or the child of a live region, collect
-            // all events from this frame and send them on the next frame.
-            if (inLiveRegion()) {
-                // If we're already posted with a delay, remove that.
-                if (mPostedWithDelay) {
-                    removeCallbacks(this);
-                    mPostedWithDelay = false;
-                }
-                // Only post if we're not already posted.
-                if (!mPosted) {
-                    post(this);
-                    mPosted = true;
-                }
-                return;
-            }
-
-            if (mPosted) {
-                return;
-            }
-
-            final long timeSinceLastMillis = SystemClock.uptimeMillis() - mLastEventTimeMillis;
-            final long minEventIntevalMillis =
-                    ViewConfiguration.getSendRecurringAccessibilityEventsInterval();
-            if (timeSinceLastMillis >= minEventIntevalMillis) {
-                removeCallbacks(this);
-                run();
-            } else {
-                postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
-                mPostedWithDelay = true;
-            }
-        }
-    }
-
-    private boolean inLiveRegion() {
-        if (getAccessibilityLiveRegion() != View.ACCESSIBILITY_LIVE_REGION_NONE) {
-            return true;
-        }
-
-        ViewParent parent = getParent();
-        while (parent instanceof View) {
-            if (((View) parent).getAccessibilityLiveRegion()
-                    != View.ACCESSIBILITY_LIVE_REGION_NONE) {
-                return true;
-            }
-            parent = parent.getParent();
-        }
-
-        return false;
-    }
-
     /**
      * Dump all private flags in readable format, useful for documentation and
      * sanity checking.
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 66df335..ecdfa3f 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3565,7 +3565,8 @@
         // If this is a live region, we should send a subtree change event
         // from this view. Otherwise, we can let it propagate up.
         if (getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE) {
-            notifyViewAccessibilityStateChangedIfNeeded(changeType);
+            notifyViewAccessibilityStateChangedIfNeeded(
+                    AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
         } else if (mParent != null) {
             try {
                 mParent.notifySubtreeAccessibilityStateChanged(this, source, changeType);
@@ -7608,6 +7609,16 @@
      * See
      * {@link android.R.styleable#ViewGroup_MarginLayout ViewGroup Margin Layout Attributes}
      * for a list of all child view attributes that this class supports.
+     *
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_margin
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginHorizontal
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginVertical
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginLeft
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginTop
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginRight
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginBottom
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd
      */
     public static class MarginLayoutParams extends ViewGroup.LayoutParams {
         /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index fd950db..7ace841 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -35,6 +35,7 @@
 import android.content.ClipData;
 import android.content.ClipDescription;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
@@ -961,8 +962,13 @@
                 final boolean hasSurfaceInsets = insets.left != 0 || insets.right != 0
                         || insets.top != 0 || insets.bottom != 0;
                 final boolean translucent = attrs.format != PixelFormat.OPAQUE || hasSurfaceInsets;
+                final boolean wideGamut =
+                        mContext.getResources().getConfiguration().isScreenWideColorGamut()
+                        && attrs.getColorMode() == ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT;
+
                 mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent,
                         attrs.getTitle().toString());
+                mAttachInfo.mThreadedRenderer.setWideGamut(wideGamut);
                 if (mAttachInfo.mThreadedRenderer != null) {
                     mAttachInfo.mHardwareAccelerated =
                             mAttachInfo.mHardwareAccelerationRequested = true;
@@ -1898,14 +1904,16 @@
                         + " outsets=" + mPendingOutsets.toShortString()
                         + " surface=" + mSurface);
 
-                final Configuration pendingMergedConfig =
-                        mPendingMergedConfiguration.getMergedConfiguration();
-                if (pendingMergedConfig.seq != 0) {
+                // If the pending {@link MergedConfiguration} handed back from
+                // {@link #relayoutWindow} does not match the one last reported,
+                // WindowManagerService has reported back a frame from a configuration not yet
+                // handled by the client. In this case, we need to accept the configuration so we
+                // do not lay out and draw with the wrong configuration.
+                if (!mPendingMergedConfiguration.equals(mLastReportedMergedConfiguration)) {
                     if (DEBUG_CONFIGURATION) Log.v(mTag, "Visible with new config: "
-                            + pendingMergedConfig);
+                            + mPendingMergedConfiguration.getMergedConfiguration());
                     performConfigurationChange(mPendingMergedConfiguration, !mFirst,
                             INVALID_DISPLAY /* same display */);
-                    pendingMergedConfig.seq = 0;
                     updatedConfiguration = true;
                 }
 
@@ -3590,6 +3598,13 @@
                 mView.setLayoutDirection(currentLayoutDirection);
             }
             mView.dispatchConfigurationChanged(config);
+
+            // We could have gotten this {@link Configuration} update after we called
+            // {@link #performTraversals} with an older {@link Configuration}. As a result, our
+            // window frame may be stale. We must ensure the next pass of {@link #performTraversals}
+            // catches this.
+            mForceNextWindowRelayout = true;
+            requestLayout();
         }
     }
 
@@ -3751,10 +3766,10 @@
                     SomeArgs args = (SomeArgs) msg.obj;
 
                     final int displayId = args.argi3;
-                    final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
+                    MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
                     final boolean displayChanged = mDisplay.getDisplayId() != displayId;
 
-                    if (mergedConfiguration != null) {
+                    if (!mLastReportedMergedConfiguration.equals(mergedConfiguration)) {
                         // If configuration changed - notify about that and, maybe, about move to
                         // display.
                         performConfigurationChange(mergedConfiguration, false /* force */,
@@ -6088,7 +6103,7 @@
         if (params != null) {
             if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params);
         }
-        mPendingMergedConfiguration.getMergedConfiguration().seq = 0;
+
         //Log.d(mTag, ">>>>>> CALLING relayout");
         if (params != null && mOrigWindowType != params.type) {
             // For compatibility with old apps, don't crash here.
@@ -6741,7 +6756,7 @@
         }
 
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             enqueueInputEvent(event, this, 0, true);
         }
 
@@ -7072,6 +7087,14 @@
         if (mView == null || mStopped || mPausedForTransition) {
             return false;
         }
+
+        // Immediately flush pending content changed event (if any) to preserve event order
+        if (event.getEventType() != AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
+                && mSendWindowContentChangedAccessibilityEvent != null
+                && mSendWindowContentChangedAccessibilityEvent.mSource != null) {
+            mSendWindowContentChangedAccessibilityEvent.removeCallbacksAndRun();
+        }
+
         // Intercept accessibility focus events fired by virtual nodes to keep
         // track of accessibility focus position in such nodes.
         final int eventType = event.getEventType();
@@ -7881,23 +7904,46 @@
 
         @Override
         public void run() {
+            // Protect against re-entrant code and attempt to do the right thing in the case that
+            // we're multithreaded.
+            View source = mSource;
+            mSource = null;
+            if (source == null) {
+                Log.e(TAG, "Accessibility content change has no source");
+                return;
+            }
             // The accessibility may be turned off while we were waiting so check again.
             if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                 mLastEventTimeMillis = SystemClock.uptimeMillis();
                 AccessibilityEvent event = AccessibilityEvent.obtain();
                 event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
                 event.setContentChangeTypes(mChangeTypes);
-                mSource.sendAccessibilityEventUnchecked(event);
+                source.sendAccessibilityEventUnchecked(event);
             } else {
                 mLastEventTimeMillis = 0;
             }
             // In any case reset to initial state.
-            mSource.resetSubtreeAccessibilityStateChanged();
-            mSource = null;
+            source.resetSubtreeAccessibilityStateChanged();
             mChangeTypes = 0;
         }
 
         public void runOrPost(View source, int changeType) {
+            if (mHandler.getLooper() != Looper.myLooper()) {
+                CalledFromWrongThreadException e = new CalledFromWrongThreadException("Only the "
+                        + "original thread that created a view hierarchy can touch its views.");
+                // TODO: Throw the exception
+                Log.e(TAG, "Accessibility content change on non-UI thread. Future Android "
+                        + "versions will throw an exception.", e);
+                // Attempt to recover. This code does not eliminate the thread safety issue, but
+                // it should force any issues to happen near the above log.
+                mHandler.removeCallbacks(this);
+                if (mSource != null) {
+                    // Dispatch whatever was pending. It's still possible that the runnable started
+                    // just before we removed the callbacks, and bad things will happen, but at
+                    // least they should happen very close to the logged error.
+                    run();
+                }
+            }
             if (mSource != null) {
                 // If there is no common predecessor, then mSource points to
                 // a removed view, hence in this case always prefer the source.
@@ -7912,11 +7958,15 @@
             final long minEventIntevalMillis =
                     ViewConfiguration.getSendRecurringAccessibilityEventsInterval();
             if (timeSinceLastMillis >= minEventIntevalMillis) {
-                mSource.removeCallbacks(this);
-                run();
+                removeCallbacksAndRun();
             } else {
-                mSource.postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
+                mHandler.postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
             }
         }
+
+        public void removeCallbacksAndRun() {
+            mHandler.removeCallbacks(this);
+            run();
+        }
     }
 }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 4060b9a..d60ba16 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
@@ -27,6 +28,7 @@
 import android.content.pm.ActivityInfo;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -169,6 +171,18 @@
      */
     public void requestAppKeyboardShortcuts(final KeyboardShortcutsReceiver receiver, int deviceId);
 
+    /**
+     * Return the touch region for the current IME window, or an empty region if there is none.
+     *
+     * @return The region of the IME that is accepting touch inputs, or null if there is no IME, no
+     *         region or there was an error.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
+    public Region getCurrentImeTouchRegion();
+
     public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
         /**
          * X position for this window.  With the default gravity it is ignored.
@@ -1391,6 +1405,14 @@
         public static final int PRIVATE_FLAG_TASK_SNAPSHOT = 0x00080000;
 
         /**
+         * Indicates that this window is the rounded corners overlay present on some
+         * devices this means that it will be excluded from: screenshots,
+         * screen magnification, and mirroring.
+         * @hide
+         */
+        public static final int PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY = 0x00100000;
+
+        /**
          * Control flags that are private to the platform.
          * @hide
          */
@@ -1722,6 +1744,13 @@
         public float buttonBrightness = BRIGHTNESS_OVERRIDE_NONE;
 
         /**
+         * Unspecified value for {@link #rotationAnimation} indicating
+         * a lack of preference.
+         * @hide
+         */
+        public static final int ROTATION_ANIMATION_UNSPECIFIED = -1;
+
+        /**
          * Value for {@link #rotationAnimation} which specifies that this
          * window will visually rotate in or out following a rotation.
          */
@@ -2087,6 +2116,7 @@
             out.writeInt(needsMenuKey);
             out.writeInt(accessibilityIdOfAnchor);
             TextUtils.writeToParcel(accessibilityTitle, out, parcelableFlags);
+            out.writeInt(mColorMode);
             out.writeLong(hideTimeoutMilliseconds);
         }
 
@@ -2141,6 +2171,7 @@
             needsMenuKey = in.readInt();
             accessibilityIdOfAnchor = in.readInt();
             accessibilityTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+            mColorMode = in.readInt();
             hideTimeoutMilliseconds = in.readLong();
         }
 
@@ -2186,6 +2217,8 @@
         @TestApi
         public static final int ACCESSIBILITY_TITLE_CHANGED = 1 << 25;
         /** {@hide} */
+        public static final int COLOR_MODE_CHANGED = 1 << 26;
+        /** {@hide} */
         public static final int EVERYTHING_CHANGED = 0xffffffff;
 
         // internal buffer to backup/restore parameters under compatibility mode.
@@ -2363,6 +2396,11 @@
                 changes |= ACCESSIBILITY_TITLE_CHANGED;
             }
 
+            if (mColorMode != o.mColorMode) {
+                mColorMode = o.mColorMode;
+                changes |= COLOR_MODE_CHANGED;
+            }
+
             // This can't change, it's only set at window creation time.
             hideTimeoutMilliseconds = o.hideTimeoutMilliseconds;
 
@@ -2554,5 +2592,16 @@
             encoder.addProperty("type", type);
             encoder.addProperty("flags", flags);
         }
+
+        /**
+         * @hide
+         * @return True if the layout parameters will cause the window to cover the full screen;
+         *         false otherwise.
+         */
+        public boolean isFullscreen() {
+            return x == 0 && y == 0
+                    && width == WindowManager.LayoutParams.MATCH_PARENT
+                    && height == WindowManager.LayoutParams.MATCH_PARENT;
+        }
     }
 }
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index c7e8dee..cca66d6 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -605,9 +605,10 @@
     public void setStoppedState(IBinder token, boolean stopped) {
         synchronized (mLock) {
             int count = mViews.size();
-            for (int i = 0; i < count; i++) {
+            for (int i = count - 1; i >= 0; i--) {
                 if (token == null || mParams.get(i).token == token) {
                     ViewRootImpl root = mRoots.get(i);
+                    // Client might remove the view by "stopped" event.
                     root.setWindowStopped(stopped);
                 }
             }
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index c1b8f04..a8722f1 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.graphics.Region;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -145,4 +146,13 @@
     public Display getDefaultDisplay() {
         return mContext.getDisplay();
     }
+
+    @Override
+    public Region getCurrentImeTouchRegion() {
+        try {
+            return WindowManagerGlobal.getWindowManagerService().getCurrentImeTouchRegion();
+        } catch (RemoteException e) {
+        }
+        return null;
+    }
 }
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index 55aed52..98f8dc8 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -229,6 +229,11 @@
     public abstract boolean isKeyguardGoingAway();
 
     /**
+    * @return Whether the keyguard is showing and not occluded.
+    */
+    public abstract boolean isKeyguardShowingAndNotOccluded();
+
+    /**
      * Gets the frame of a window given its token.
      *
      * @param token The token.
@@ -342,4 +347,11 @@
      * Requests the window manager to recompute the windows for accessibility.
      */
     public abstract void computeWindowsForAccessibility();
+
+    /**
+     * Called after virtual display Id is updated by
+     * {@link com.android.server.vr.Vr2dDisplay} with a specific
+     * {@param vr2dDisplayId}.
+     */
+    public abstract void setVr2dDisplayId(int vr2dDisplayId);
 }
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 13ffeec..49b7ed8 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
@@ -149,6 +150,11 @@
     public final static int PRESENCE_INTERNAL = 1 << 0;
     public final static int PRESENCE_EXTERNAL = 1 << 1;
 
+    // Navigation bar position values
+    int NAV_BAR_LEFT = 1 << 0;
+    int NAV_BAR_RIGHT = 1 << 1;
+    int NAV_BAR_BOTTOM = 1 << 2;
+
     public final static boolean WATCH_POINTER = false;
 
     /**
@@ -611,7 +617,16 @@
          * 2. motionEvent will be recycled after onPointerEvent returns so if it is needed later a
          * copy() must be made and the copy must be recycled.
          **/
-        public void onPointerEvent(MotionEvent motionEvent);
+        void onPointerEvent(MotionEvent motionEvent);
+
+        /**
+         * @see #onPointerEvent(MotionEvent)
+         **/
+        default void onPointerEvent(MotionEvent motionEvent, int displayId) {
+            if (displayId == DEFAULT_DISPLAY) {
+                onPointerEvent(motionEvent);
+            }
+        }
     }
 
     /** Window has been added to the screen. */
@@ -1311,6 +1326,14 @@
     public boolean isScreenOn();
 
     /**
+     * @return whether the device is currently allowed to animate.
+     *
+     * Note: this can be true even if it is not appropriate to animate for reasons that are outside
+     *       of the policy's authority.
+     */
+    boolean okToAnimate();
+
+    /**
      * Tell the policy that the lid switch has changed state.
      * @param whenNanos The time when the change occurred in uptime nanoseconds.
      * @param lidOpen True if the lid is now open.
@@ -1667,6 +1690,14 @@
     public boolean isNavBarForcedShownLw(WindowState win);
 
     /**
+     * @return The side of the screen where navigation bar is positioned.
+     * @see #NAV_BAR_LEFT
+     * @see #NAV_BAR_RIGHT
+     * @see #NAV_BAR_BOTTOM
+     */
+    int getNavBarPosition();
+
+    /**
      * Calculates the insets for the areas that could never be removed in Honeycomb, i.e. system
      * bar or button bar. See {@link #getNonDecorDisplayWidth}.
      *
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index eecfdca..9dd0fb0 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -21,6 +21,8 @@
 import android.text.TextUtils;
 import android.util.Pools.SynchronizedPool;
 
+import com.android.internal.util.BitUtils;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -851,6 +853,22 @@
         return mContentChangeTypes;
     }
 
+    private static String contentChangeTypesToString(int types) {
+        return BitUtils.flagsToString(types, AccessibilityEvent::singleContentChangeTypeToString);
+    }
+
+    private static String singleContentChangeTypeToString(int type) {
+        switch (type) {
+            case CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION: {
+                return "CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION";
+            }
+            case CONTENT_CHANGE_TYPE_SUBTREE: return "CONTENT_CHANGE_TYPE_SUBTREE";
+            case CONTENT_CHANGE_TYPE_TEXT: return "CONTENT_CHANGE_TYPE_TEXT";
+            case CONTENT_CHANGE_TYPE_UNDEFINED: return "CONTENT_CHANGE_TYPE_UNDEFINED";
+            default: return Integer.toHexString(type);
+        }
+    }
+
     /**
      * Sets the bit mask of node tree changes signaled by an
      * {@link #TYPE_WINDOW_CONTENT_CHANGED} event.
@@ -1109,7 +1127,7 @@
         record.mParcelableData = parcel.readParcelable(null);
         parcel.readList(record.mText, null);
         record.mSourceWindowId = parcel.readInt();
-        record.mSourceNode = parcel.readParcelable(null);
+        record.mSourceNodeId = parcel.readLong();
         record.mSealed = (parcel.readInt() == 1);
     }
 
@@ -1161,10 +1179,7 @@
         parcel.writeParcelable(record.mParcelableData, flags);
         parcel.writeList(record.mText);
         parcel.writeInt(record.mSourceWindowId);
-        // create copy of the node here because the node would be recycled just after it is written
-        // to parcel
-        parcel.writeParcelable(record.mSourceNode != null ?
-                AccessibilityNodeInfo.obtain(record.mSourceNode) : null, flags);
+        parcel.writeLong(record.mSourceNodeId);
         parcel.writeInt(record.mSealed ? 1 : 0);
     }
 
@@ -1186,11 +1201,10 @@
         builder.append(super.toString());
         if (DEBUG) {
             builder.append("\n");
-            builder.append("; ContentChangeTypes: ").append(mContentChangeTypes);
+            builder.append("; ContentChangeTypes: ").append(
+                    contentChangeTypesToString(mContentChangeTypes));
             builder.append("; sourceWindowId: ").append(mSourceWindowId);
-            if (mSourceNode != null) {
-                builder.append("; mSourceNodeId: ").append(mSourceNode.getSourceNodeId());
-            }
+            builder.append("; mSourceNodeId: ").append(mSourceNodeId);
             for (int i = 0; i < getRecordCount(); i++) {
                 final AccessibilityRecord record = getRecord(i);
                 builder.append("  Record ");
@@ -1239,183 +1253,13 @@
         while (eventType != 0) {
             final int eventTypeFlag = 1 << Integer.numberOfTrailingZeros(eventType);
             eventType &= ~eventTypeFlag;
-            switch (eventTypeFlag) {
-                case TYPE_VIEW_CLICKED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_CLICKED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_LONG_CLICKED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_LONG_CLICKED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_SELECTED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_SELECTED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_FOCUSED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_FOCUSED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_TEXT_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_TEXT_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_WINDOW_STATE_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_WINDOW_STATE_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_HOVER_ENTER: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_HOVER_ENTER");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_HOVER_EXIT: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_HOVER_EXIT");
-                    eventTypeCount++;
-                } break;
-                case TYPE_NOTIFICATION_STATE_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_NOTIFICATION_STATE_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_TOUCH_EXPLORATION_GESTURE_START: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_TOUCH_EXPLORATION_GESTURE_START");
-                    eventTypeCount++;
-                } break;
-                case TYPE_TOUCH_EXPLORATION_GESTURE_END: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_TOUCH_EXPLORATION_GESTURE_END");
-                    eventTypeCount++;
-                } break;
-                case TYPE_WINDOW_CONTENT_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_WINDOW_CONTENT_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_TEXT_SELECTION_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_TEXT_SELECTION_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_SCROLLED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_SCROLLED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_ANNOUNCEMENT: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_ANNOUNCEMENT");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_ACCESSIBILITY_FOCUSED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY");
-                    eventTypeCount++;
-                } break;
-                case TYPE_GESTURE_DETECTION_START: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_GESTURE_DETECTION_START");
-                    eventTypeCount++;
-                } break;
-                case TYPE_GESTURE_DETECTION_END: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_GESTURE_DETECTION_END");
-                    eventTypeCount++;
-                } break;
-                case TYPE_TOUCH_INTERACTION_START: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_TOUCH_INTERACTION_START");
-                    eventTypeCount++;
-                } break;
-                case TYPE_TOUCH_INTERACTION_END: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_TOUCH_INTERACTION_END");
-                    eventTypeCount++;
-                } break;
-                case TYPE_WINDOWS_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_WINDOWS_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_CONTEXT_CLICKED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_CONTEXT_CLICKED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_ASSIST_READING_CONTEXT: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_ASSIST_READING_CONTEXT");
-                    eventTypeCount++;
-                } break;
+
+            if (eventTypeCount > 0) {
+                builder.append(", ");
             }
+            builder.append(singleEventTypeToString(eventTypeFlag));
+
+            eventTypeCount++;
         }
         if (eventTypeCount > 1) {
             builder.insert(0, '[');
@@ -1424,6 +1268,43 @@
         return builder.toString();
     }
 
+    private static String singleEventTypeToString(int eventType) {
+        switch (eventType) {
+            case TYPE_VIEW_CLICKED: return "TYPE_VIEW_CLICKED";
+            case TYPE_VIEW_LONG_CLICKED: return "TYPE_VIEW_LONG_CLICKED";
+            case TYPE_VIEW_SELECTED: return "TYPE_VIEW_SELECTED";
+            case TYPE_VIEW_FOCUSED: return "TYPE_VIEW_FOCUSED";
+            case TYPE_VIEW_TEXT_CHANGED: return "TYPE_VIEW_TEXT_CHANGED";
+            case TYPE_WINDOW_STATE_CHANGED: return "TYPE_WINDOW_STATE_CHANGED";
+            case TYPE_VIEW_HOVER_ENTER: return "TYPE_VIEW_HOVER_ENTER";
+            case TYPE_VIEW_HOVER_EXIT: return "TYPE_VIEW_HOVER_EXIT";
+            case TYPE_NOTIFICATION_STATE_CHANGED: return "TYPE_NOTIFICATION_STATE_CHANGED";
+            case TYPE_TOUCH_EXPLORATION_GESTURE_START: {
+                return "TYPE_TOUCH_EXPLORATION_GESTURE_START";
+            }
+            case TYPE_TOUCH_EXPLORATION_GESTURE_END: return "TYPE_TOUCH_EXPLORATION_GESTURE_END";
+            case TYPE_WINDOW_CONTENT_CHANGED: return "TYPE_WINDOW_CONTENT_CHANGED";
+            case TYPE_VIEW_TEXT_SELECTION_CHANGED: return "TYPE_VIEW_TEXT_SELECTION_CHANGED";
+            case TYPE_VIEW_SCROLLED: return "TYPE_VIEW_SCROLLED";
+            case TYPE_ANNOUNCEMENT: return "TYPE_ANNOUNCEMENT";
+            case TYPE_VIEW_ACCESSIBILITY_FOCUSED: return "TYPE_VIEW_ACCESSIBILITY_FOCUSED";
+            case TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
+                return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED";
+            }
+            case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: {
+                return "TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY";
+            }
+            case TYPE_GESTURE_DETECTION_START: return "TYPE_GESTURE_DETECTION_START";
+            case TYPE_GESTURE_DETECTION_END: return "TYPE_GESTURE_DETECTION_END";
+            case TYPE_TOUCH_INTERACTION_START: return "TYPE_TOUCH_INTERACTION_START";
+            case TYPE_TOUCH_INTERACTION_END: return "TYPE_TOUCH_INTERACTION_END";
+            case TYPE_WINDOWS_CHANGED: return "TYPE_WINDOWS_CHANGED";
+            case TYPE_VIEW_CONTEXT_CLICKED: return "TYPE_VIEW_CONTEXT_CLICKED";
+            case TYPE_ASSIST_READING_CONTEXT: return "TYPE_ASSIST_READING_CONTEXT";
+            default: return Integer.toHexString(eventType);
+        }
+    }
+
     /**
      * @see Parcelable.Creator
      */
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index bdadcc7..69892d9 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -25,6 +25,7 @@
 import android.annotation.SdkConstant;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.annotation.TestApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -42,6 +43,7 @@
 import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.IWindow;
 import android.view.View;
 
@@ -145,6 +147,11 @@
             mServicesStateChangeListeners = new ArrayMap<>();
 
     /**
+     * Map from a view's accessibility id to the list of request preparers set for that view
+     */
+    private SparseArray<List<AccessibilityRequestPreparer>> mRequestPreparerLists;
+
+    /**
      * Listener for the system accessibility state. To listen for changes to the
      * accessibility state on the device, implement this interface and register
      * it with the system by calling {@link #addAccessibilityStateChangeListener}.
@@ -697,6 +704,58 @@
     }
 
     /**
+     * Registers a {@link AccessibilityRequestPreparer}.
+     * @hide
+     */
+    @TestApi
+    public void addAccessibilityRequestPreparer(AccessibilityRequestPreparer preparer) {
+        if (mRequestPreparerLists == null) {
+            mRequestPreparerLists = new SparseArray<>(1);
+        }
+        int id = preparer.getView().getAccessibilityViewId();
+        List<AccessibilityRequestPreparer> requestPreparerList = mRequestPreparerLists.get(id);
+        if (requestPreparerList == null) {
+            requestPreparerList = new ArrayList<>(1);
+            mRequestPreparerLists.put(id, requestPreparerList);
+        }
+        requestPreparerList.add(preparer);
+    }
+
+    /**
+     * Unregisters a {@link AccessibilityRequestPreparer}.
+     * @hide
+     */
+    @TestApi
+    public void removeAccessibilityRequestPreparer(AccessibilityRequestPreparer preparer) {
+        if (mRequestPreparerLists == null) {
+            return;
+        }
+        int viewId = preparer.getView().getAccessibilityViewId();
+        List<AccessibilityRequestPreparer> requestPreparerList = mRequestPreparerLists.get(viewId);
+        if (requestPreparerList != null) {
+            requestPreparerList.remove(preparer);
+            if (requestPreparerList.isEmpty()) {
+                mRequestPreparerLists.remove(viewId);
+            }
+        }
+    }
+
+    /**
+     * Get the preparers that are registered for an accessibility ID
+     *
+     * @param id The ID of interest
+     * @return The list of preparers, or {@code null} if there are none.
+     *
+     * @hide
+     */
+    public List<AccessibilityRequestPreparer> getRequestPreparersForAccessibilityId(int id) {
+        if (mRequestPreparerLists == null) {
+            return null;
+        }
+        return mRequestPreparerLists.get(id);
+    }
+
+    /**
      * Registers a {@link HighTextContrastChangeListener} for changes in
      * the global high text contrast state of the system.
      *
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 5148d92..82a6de7 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -16,6 +16,9 @@
 
 package android.view.accessibility;
 
+import static com.android.internal.util.BitUtils.bitAt;
+import static com.android.internal.util.BitUtils.isBitSet;
+
 import static java.util.Collections.EMPTY_LIST;
 
 import android.accessibilityservice.AccessibilityService;
@@ -41,10 +44,12 @@
 import android.view.View;
 
 import com.android.internal.R;
+import com.android.internal.util.CollectionUtils;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -85,7 +90,6 @@
     /** @hide */
     public static final int UNDEFINED_SELECTION_INDEX = -1;
 
-    /* Special IDs for node source IDs */
     /** @hide */
     public static final int UNDEFINED_ITEM_ID = Integer.MAX_VALUE;
 
@@ -636,7 +640,6 @@
      * Bits that provide the id of a virtual descendant of a view.
      */
     private static final long VIRTUAL_DESCENDANT_ID_MASK = 0xffffffff00000000L;
-
     /**
      * Bit shift of {@link #VIRTUAL_DESCENDANT_ID_MASK} to get to the id for a
      * virtual descendant of a view. Such a descendant does not exist in the view
@@ -692,6 +695,8 @@
     private static final SynchronizedPool<AccessibilityNodeInfo> sPool =
             new SynchronizedPool<>(MAX_POOL_SIZE);
 
+    private static final AccessibilityNodeInfo DEFAULT = new AccessibilityNodeInfo();
+
     private boolean mSealed;
 
     // Data.
@@ -1068,11 +1073,7 @@
      * Gets the actions that can be performed on the node.
      */
     public List<AccessibilityAction> getActionList() {
-        if (mActions == null) {
-            return Collections.emptyList();
-        }
-
-        return mActions;
+        return CollectionUtils.emptyIfNull(mActions);
     }
 
     /**
@@ -3050,127 +3051,227 @@
      */
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeInt(isSealed() ? 1 : 0);
-        parcel.writeLong(mSourceNodeId);
-        parcel.writeInt(mWindowId);
-        parcel.writeLong(mParentNodeId);
-        parcel.writeLong(mLabelForId);
-        parcel.writeLong(mLabeledById);
-        parcel.writeLong(mTraversalBefore);
-        parcel.writeLong(mTraversalAfter);
-
-        parcel.writeInt(mConnectionId);
-
-        final LongArray childIds = mChildNodeIds;
-        if (childIds == null) {
-            parcel.writeInt(0);
-        } else {
-            final int childIdsSize = childIds.size();
-            parcel.writeInt(childIdsSize);
-            for (int i = 0; i < childIdsSize; i++) {
-                parcel.writeLong(childIds.get(i));
-            }
+        // Write bit set of indices of fields with values differing from default
+        long nonDefaultFields = 0;
+        int fieldIndex = 0; // index of the current field
+        if (isSealed() != DEFAULT.isSealed()) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mSourceNodeId != DEFAULT.mSourceNodeId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mWindowId != DEFAULT.mWindowId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mParentNodeId != DEFAULT.mParentNodeId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mLabelForId != DEFAULT.mLabelForId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mLabeledById != DEFAULT.mLabeledById) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mTraversalBefore != DEFAULT.mTraversalBefore) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mTraversalAfter != DEFAULT.mTraversalAfter) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mConnectionId != DEFAULT.mConnectionId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mChildNodeIds, DEFAULT.mChildNodeIds)) {
+            nonDefaultFields |= bitAt(fieldIndex);
         }
+        fieldIndex++;
+        if (!Objects.equals(mBoundsInParent, DEFAULT.mBoundsInParent)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mBoundsInScreen, DEFAULT.mBoundsInScreen)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mActions, DEFAULT.mActions)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mMaxTextLength != DEFAULT.mMaxTextLength) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mMovementGranularities != DEFAULT.mMovementGranularities) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (mBooleanProperties != DEFAULT.mBooleanProperties) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mPackageName, DEFAULT.mPackageName)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mClassName, DEFAULT.mClassName)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mText, DEFAULT.mText)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mHintText, DEFAULT.mHintText)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mError, DEFAULT.mError)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mContentDescription, DEFAULT.mContentDescription)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mViewIdResourceName, DEFAULT.mViewIdResourceName)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (mTextSelectionStart != DEFAULT.mTextSelectionStart) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (mTextSelectionEnd != DEFAULT.mTextSelectionEnd) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (mInputType != DEFAULT.mInputType) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mLiveRegion != DEFAULT.mLiveRegion) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mDrawingOrderInParent != DEFAULT.mDrawingOrderInParent) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mExtraDataKeys, DEFAULT.mExtraDataKeys)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mExtras, DEFAULT.mExtras)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mRangeInfo, DEFAULT.mRangeInfo)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mCollectionInfo, DEFAULT.mCollectionInfo)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mCollectionItemInfo, DEFAULT.mCollectionItemInfo)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        int totalFields = fieldIndex;
+        parcel.writeLong(nonDefaultFields);
 
-        parcel.writeInt(mBoundsInParent.top);
-        parcel.writeInt(mBoundsInParent.bottom);
-        parcel.writeInt(mBoundsInParent.left);
-        parcel.writeInt(mBoundsInParent.right);
+        fieldIndex = 0;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(isSealed() ? 1 : 0);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mSourceNodeId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mWindowId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mParentNodeId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mLabelForId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mLabeledById);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mTraversalBefore);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mTraversalAfter);
 
-        parcel.writeInt(mBoundsInScreen.top);
-        parcel.writeInt(mBoundsInScreen.bottom);
-        parcel.writeInt(mBoundsInScreen.left);
-        parcel.writeInt(mBoundsInScreen.right);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mConnectionId);
 
-        if (mActions != null && !mActions.isEmpty()) {
-            final int actionCount = mActions.size();
-
-            int nonLegacyActionCount = 0;
-            int defaultLegacyStandardActions = 0;
-            for (int i = 0; i < actionCount; i++) {
-                AccessibilityAction action = mActions.get(i);
-                if (isDefaultLegacyStandardAction(action)) {
-                    defaultLegacyStandardActions |= action.getId();
-                } else {
-                    nonLegacyActionCount++;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            final LongArray childIds = mChildNodeIds;
+            if (childIds == null) {
+                parcel.writeInt(0);
+            } else {
+                final int childIdsSize = childIds.size();
+                parcel.writeInt(childIdsSize);
+                for (int i = 0; i < childIdsSize; i++) {
+                    parcel.writeLong(childIds.get(i));
                 }
             }
-            parcel.writeInt(defaultLegacyStandardActions);
-            parcel.writeInt(nonLegacyActionCount);
+        }
 
-            for (int i = 0; i < actionCount; i++) {
-                AccessibilityAction action = mActions.get(i);
-                if (!isDefaultLegacyStandardAction(action)) {
-                    parcel.writeInt(action.getId());
-                    parcel.writeCharSequence(action.getLabel());
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            parcel.writeInt(mBoundsInParent.top);
+            parcel.writeInt(mBoundsInParent.bottom);
+            parcel.writeInt(mBoundsInParent.left);
+            parcel.writeInt(mBoundsInParent.right);
+        }
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            parcel.writeInt(mBoundsInScreen.top);
+            parcel.writeInt(mBoundsInScreen.bottom);
+            parcel.writeInt(mBoundsInScreen.left);
+            parcel.writeInt(mBoundsInScreen.right);
+        }
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            if (mActions != null && !mActions.isEmpty()) {
+                final int actionCount = mActions.size();
+
+                int nonLegacyActionCount = 0;
+                int defaultLegacyStandardActions = 0;
+                for (int i = 0; i < actionCount; i++) {
+                    AccessibilityAction action = mActions.get(i);
+                    if (isDefaultLegacyStandardAction(action)) {
+                        defaultLegacyStandardActions |= action.getId();
+                    } else {
+                        nonLegacyActionCount++;
+                    }
                 }
+                parcel.writeInt(defaultLegacyStandardActions);
+                parcel.writeInt(nonLegacyActionCount);
+
+                for (int i = 0; i < actionCount; i++) {
+                    AccessibilityAction action = mActions.get(i);
+                    if (!isDefaultLegacyStandardAction(action)) {
+                        parcel.writeInt(action.getId());
+                        parcel.writeCharSequence(action.getLabel());
+                    }
+                }
+            } else {
+                parcel.writeInt(0);
+                parcel.writeInt(0);
             }
-        } else {
-            parcel.writeInt(0);
-            parcel.writeInt(0);
         }
 
-        parcel.writeInt(mMaxTextLength);
-        parcel.writeInt(mMovementGranularities);
-        parcel.writeInt(mBooleanProperties);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mMaxTextLength);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mMovementGranularities);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mBooleanProperties);
 
-        parcel.writeCharSequence(mPackageName);
-        parcel.writeCharSequence(mClassName);
-        parcel.writeCharSequence(mText);
-        parcel.writeCharSequence(mHintText);
-        parcel.writeCharSequence(mError);
-        parcel.writeCharSequence(mContentDescription);
-        parcel.writeString(mViewIdResourceName);
-
-        parcel.writeInt(mTextSelectionStart);
-        parcel.writeInt(mTextSelectionEnd);
-        parcel.writeInt(mInputType);
-        parcel.writeInt(mLiveRegion);
-        parcel.writeInt(mDrawingOrderInParent);
-        if (mExtraDataKeys != null) {
-            parcel.writeInt(1);
-            parcel.writeStringList(mExtraDataKeys);
-        } else {
-            parcel.writeInt(0);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mPackageName);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mClassName);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mText);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mHintText);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mError);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            parcel.writeCharSequence(mContentDescription);
         }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeString(mViewIdResourceName);
 
-        if (mExtras != null) {
-            parcel.writeInt(1);
-            parcel.writeBundle(mExtras);
-        } else {
-            parcel.writeInt(0);
-        }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mTextSelectionStart);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mTextSelectionEnd);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mInputType);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mLiveRegion);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mDrawingOrderInParent);
 
-        if (mRangeInfo != null) {
-            parcel.writeInt(1);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeStringList(mExtraDataKeys);
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeBundle(mExtras);
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
             parcel.writeInt(mRangeInfo.getType());
             parcel.writeFloat(mRangeInfo.getMin());
             parcel.writeFloat(mRangeInfo.getMax());
             parcel.writeFloat(mRangeInfo.getCurrent());
-        } else {
-            parcel.writeInt(0);
         }
 
-        if (mCollectionInfo != null) {
-            parcel.writeInt(1);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
             parcel.writeInt(mCollectionInfo.getRowCount());
             parcel.writeInt(mCollectionInfo.getColumnCount());
             parcel.writeInt(mCollectionInfo.isHierarchical() ? 1 : 0);
             parcel.writeInt(mCollectionInfo.getSelectionMode());
-        } else {
-            parcel.writeInt(0);
         }
 
-        if (mCollectionItemInfo != null) {
-            parcel.writeInt(1);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
             parcel.writeInt(mCollectionItemInfo.getRowIndex());
             parcel.writeInt(mCollectionItemInfo.getRowSpan());
             parcel.writeInt(mCollectionItemInfo.getColumnIndex());
             parcel.writeInt(mCollectionItemInfo.getColumnSpan());
             parcel.writeInt(mCollectionItemInfo.isHeading() ? 1 : 0);
             parcel.writeInt(mCollectionItemInfo.isSelected() ? 1 : 0);
-        } else {
-            parcel.writeInt(0);
+        }
+
+        if (DEBUG) {
+            fieldIndex--;
+            if (totalFields != fieldIndex) {
+                throw new IllegalStateException("Number of fields mismatch: " + totalFields
+                        + " vs " + fieldIndex);
+            }
         }
 
         // Since instances of this class are fetched via synchronous i.e. blocking
@@ -3203,12 +3304,12 @@
         mContentDescription = other.mContentDescription;
         mViewIdResourceName = other.mViewIdResourceName;
 
+        if (mActions != null) mActions.clear();
         final ArrayList<AccessibilityAction> otherActions = other.mActions;
         if (otherActions != null && otherActions.size() > 0) {
             if (mActions == null) {
                 mActions = new ArrayList(otherActions);
             } else {
-                mActions.clear();
                 mActions.addAll(other.mActions);
             }
         }
@@ -3217,12 +3318,13 @@
         mMaxTextLength = other.mMaxTextLength;
         mMovementGranularities = other.mMovementGranularities;
 
+
+        if (mChildNodeIds != null) mChildNodeIds.clear();
         final LongArray otherChildNodeIds = other.mChildNodeIds;
         if (otherChildNodeIds != null && otherChildNodeIds.size() > 0) {
             if (mChildNodeIds == null) {
                 mChildNodeIds = otherChildNodeIds.clone();
             } else {
-                mChildNodeIds.clear();
                 mChildNodeIds.addAll(otherChildNodeIds);
             }
         }
@@ -3232,17 +3334,18 @@
         mInputType = other.mInputType;
         mLiveRegion = other.mLiveRegion;
         mDrawingOrderInParent = other.mDrawingOrderInParent;
+
         mExtraDataKeys = other.mExtraDataKeys;
 
-        if (other.mExtras != null) {
-            mExtras = new Bundle(other.mExtras);
-        } else {
-            mExtras = null;
-        }
+        mExtras = other.mExtras != null ? new Bundle(other.mExtras) : null;
+
+        if (mRangeInfo != null) mRangeInfo.recycle();
         mRangeInfo = (other.mRangeInfo != null)
                 ? RangeInfo.obtain(other.mRangeInfo) : null;
+        if (mCollectionInfo != null) mCollectionInfo.recycle();
         mCollectionInfo = (other.mCollectionInfo != null)
                 ? CollectionInfo.obtain(other.mCollectionInfo) : null;
+        if (mCollectionItemInfo != null) mCollectionItemInfo.recycle();
         mCollectionItemInfo =  (other.mCollectionItemInfo != null)
                 ? CollectionItemInfo.obtain(other.mCollectionItemInfo) : null;
     }
@@ -3253,103 +3356,117 @@
      * @param parcel A parcel containing the state of a {@link AccessibilityNodeInfo}.
      */
     private void initFromParcel(Parcel parcel) {
-        final boolean sealed = (parcel.readInt()  == 1);
-        mSourceNodeId = parcel.readLong();
-        mWindowId = parcel.readInt();
-        mParentNodeId = parcel.readLong();
-        mLabelForId = parcel.readLong();
-        mLabeledById = parcel.readLong();
-        mTraversalBefore = parcel.readLong();
-        mTraversalAfter = parcel.readLong();
+        // Bit mask of non-default-valued field indices
+        long nonDefaultFields = parcel.readLong();
+        int fieldIndex = 0;
+        final boolean sealed = isBitSet(nonDefaultFields, fieldIndex++)
+                ? (parcel.readInt() == 1)
+                : DEFAULT.mSealed;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mSourceNodeId = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mWindowId = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mParentNodeId = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mLabelForId = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mLabeledById = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mTraversalBefore = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mTraversalAfter = parcel.readLong();
 
-        mConnectionId = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mConnectionId = parcel.readInt();
 
-        final int childrenSize = parcel.readInt();
-        if (childrenSize <= 0) {
-            mChildNodeIds = null;
-        } else {
-            mChildNodeIds = new LongArray(childrenSize);
-            for (int i = 0; i < childrenSize; i++) {
-                final long childId = parcel.readLong();
-                mChildNodeIds.add(childId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            final int childrenSize = parcel.readInt();
+            if (childrenSize <= 0) {
+                mChildNodeIds = null;
+            } else {
+                mChildNodeIds = new LongArray(childrenSize);
+                for (int i = 0; i < childrenSize; i++) {
+                    final long childId = parcel.readLong();
+                    mChildNodeIds.add(childId);
+                }
             }
         }
 
-        mBoundsInParent.top = parcel.readInt();
-        mBoundsInParent.bottom = parcel.readInt();
-        mBoundsInParent.left = parcel.readInt();
-        mBoundsInParent.right = parcel.readInt();
-
-        mBoundsInScreen.top = parcel.readInt();
-        mBoundsInScreen.bottom = parcel.readInt();
-        mBoundsInScreen.left = parcel.readInt();
-        mBoundsInScreen.right = parcel.readInt();
-
-        final int legacyStandardActions = parcel.readInt();
-        addLegacyStandardActions(legacyStandardActions);
-        final int nonLegacyActionCount = parcel.readInt();
-        for (int i = 0; i < nonLegacyActionCount; i++) {
-            final AccessibilityAction action = new AccessibilityAction(
-                    parcel.readInt(), parcel.readCharSequence());
-            addActionUnchecked(action);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            mBoundsInParent.top = parcel.readInt();
+            mBoundsInParent.bottom = parcel.readInt();
+            mBoundsInParent.left = parcel.readInt();
+            mBoundsInParent.right = parcel.readInt();
         }
 
-        mMaxTextLength = parcel.readInt();
-        mMovementGranularities = parcel.readInt();
-        mBooleanProperties = parcel.readInt();
-
-        mPackageName = parcel.readCharSequence();
-        mClassName = parcel.readCharSequence();
-        mText = parcel.readCharSequence();
-        mHintText = parcel.readCharSequence();
-        mError = parcel.readCharSequence();
-        mContentDescription = parcel.readCharSequence();
-        mViewIdResourceName = parcel.readString();
-
-        mTextSelectionStart = parcel.readInt();
-        mTextSelectionEnd = parcel.readInt();
-
-        mInputType = parcel.readInt();
-        mLiveRegion = parcel.readInt();
-        mDrawingOrderInParent = parcel.readInt();
-
-        if (parcel.readInt() == 1) {
-            mExtraDataKeys = parcel.createStringArrayList();
-        } else {
-            mExtraDataKeys = null;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            mBoundsInScreen.top = parcel.readInt();
+            mBoundsInScreen.bottom = parcel.readInt();
+            mBoundsInScreen.left = parcel.readInt();
+            mBoundsInScreen.right = parcel.readInt();
         }
 
-        if (parcel.readInt() == 1) {
-            mExtras = parcel.readBundle();
-        } else {
-            mExtras = null;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            final int legacyStandardActions = parcel.readInt();
+            addLegacyStandardActions(legacyStandardActions);
+            final int nonLegacyActionCount = parcel.readInt();
+            for (int i = 0; i < nonLegacyActionCount; i++) {
+                final AccessibilityAction action = new AccessibilityAction(
+                        parcel.readInt(), parcel.readCharSequence());
+                addActionUnchecked(action);
+            }
         }
 
-        if (parcel.readInt() == 1) {
-            mRangeInfo = RangeInfo.obtain(
-                    parcel.readInt(),
-                    parcel.readFloat(),
-                    parcel.readFloat(),
-                    parcel.readFloat());
-        }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mMaxTextLength = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mMovementGranularities = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mBooleanProperties = parcel.readInt();
 
-        if (parcel.readInt() == 1) {
-            mCollectionInfo = CollectionInfo.obtain(
-                    parcel.readInt(),
-                    parcel.readInt(),
-                    parcel.readInt() == 1,
-                    parcel.readInt());
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mPackageName = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mClassName = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mText = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mHintText = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mError = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            mContentDescription = parcel.readCharSequence();
         }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mViewIdResourceName = parcel.readString();
 
-        if (parcel.readInt() == 1) {
-            mCollectionItemInfo = CollectionItemInfo.obtain(
-                    parcel.readInt(),
-                    parcel.readInt(),
-                    parcel.readInt(),
-                    parcel.readInt(),
-                    parcel.readInt() == 1,
-                    parcel.readInt() == 1);
-        }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mTextSelectionStart = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mTextSelectionEnd = parcel.readInt();
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mInputType = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mLiveRegion = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mDrawingOrderInParent = parcel.readInt();
+
+        mExtraDataKeys = isBitSet(nonDefaultFields, fieldIndex++)
+                ? parcel.createStringArrayList()
+                : null;
+
+        mExtras = isBitSet(nonDefaultFields, fieldIndex++)
+                ? parcel.readBundle()
+                : null;
+
+        if (mRangeInfo != null) mRangeInfo.recycle();
+        mRangeInfo = isBitSet(nonDefaultFields, fieldIndex++)
+                ? RangeInfo.obtain(
+                        parcel.readInt(),
+                        parcel.readFloat(),
+                        parcel.readFloat(),
+                        parcel.readFloat())
+                : null;
+
+        if (mCollectionInfo != null) mCollectionInfo.recycle();
+        mCollectionInfo = isBitSet(nonDefaultFields, fieldIndex++)
+                ? CollectionInfo.obtain(
+                        parcel.readInt(),
+                        parcel.readInt(),
+                        parcel.readInt() == 1,
+                        parcel.readInt())
+                : null;
+
+        if (mCollectionItemInfo != null) mCollectionItemInfo.recycle();
+        mCollectionItemInfo = isBitSet(nonDefaultFields, fieldIndex++)
+                ? CollectionItemInfo.obtain(
+                        parcel.readInt(),
+                        parcel.readInt(),
+                        parcel.readInt(),
+                        parcel.readInt(),
+                        parcel.readInt() == 1,
+                        parcel.readInt() == 1)
+                : null;
 
         mSealed = sealed;
     }
@@ -3358,50 +3475,7 @@
      * Clears the state of this instance.
      */
     private void clear() {
-        mSealed = false;
-        mSourceNodeId = UNDEFINED_NODE_ID;
-        mParentNodeId = UNDEFINED_NODE_ID;
-        mLabelForId = UNDEFINED_NODE_ID;
-        mLabeledById = UNDEFINED_NODE_ID;
-        mTraversalBefore = UNDEFINED_NODE_ID;
-        mTraversalAfter = UNDEFINED_NODE_ID;
-        mWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
-        mConnectionId = UNDEFINED_CONNECTION_ID;
-        mMaxTextLength = -1;
-        mMovementGranularities = 0;
-        if (mChildNodeIds != null) {
-            mChildNodeIds.clear();
-        }
-        mBoundsInParent.set(0, 0, 0, 0);
-        mBoundsInScreen.set(0, 0, 0, 0);
-        mBooleanProperties = 0;
-        mDrawingOrderInParent = 0;
-        mExtraDataKeys = null;
-        mPackageName = null;
-        mClassName = null;
-        mText = null;
-        mHintText = null;
-        mError = null;
-        mContentDescription = null;
-        mViewIdResourceName = null;
-        removeAllActions();
-        mTextSelectionStart = UNDEFINED_SELECTION_INDEX;
-        mTextSelectionEnd = UNDEFINED_SELECTION_INDEX;
-        mInputType = InputType.TYPE_NULL;
-        mLiveRegion = View.ACCESSIBILITY_LIVE_REGION_NONE;
-        mExtras = null;
-        if (mRangeInfo != null) {
-            mRangeInfo.recycle();
-            mRangeInfo = null;
-        }
-        if (mCollectionInfo != null) {
-            mCollectionInfo.recycle();
-            mCollectionInfo = null;
-        }
-        if (mCollectionItemInfo != null) {
-            mCollectionItemInfo.recycle();
-            mCollectionItemInfo = null;
-        }
+        init(DEFAULT);
     }
 
     private static boolean isDefaultLegacyStandardAction(AccessibilityAction action) {
diff --git a/core/java/android/view/accessibility/AccessibilityNodeProvider.java b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
index 722b659..73733a0 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeProvider.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
@@ -76,7 +76,7 @@
 
     /**
      * Returns an {@link AccessibilityNodeInfo} representing a virtual view,
-     * i.e. a descendant of the host View, with the given <code>virtualViewId</code>
+     * such as a descendant of the host View, with the given <code>virtualViewId</code>
      * or the host View itself if <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}.
      * <p>
      * A virtual descendant is an imaginary View that is reported as a part of the view
@@ -123,7 +123,7 @@
     }
 
     /**
-     * Performs an accessibility action on a virtual view, i.e. a descendant of the
+     * Performs an accessibility action on a virtual view, such as a descendant of the
      * host View, with the given <code>virtualViewId</code> or the host View itself
      * if <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}.
      *
@@ -160,7 +160,7 @@
     }
 
     /**
-     * Find the virtual view, i.e. a descendant of the host View, that has the
+     * Find the virtual view, such as a descendant of the host View, that has the
      * specified focus type.
      *
      * @param focus The focus to find. One of
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index 3f1fece..02b6185 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -16,6 +16,7 @@
 
 package android.view.accessibility;
 
+import android.annotation.Nullable;
 import android.os.Parcelable;
 import android.view.View;
 
@@ -90,7 +91,7 @@
 
     int mAddedCount= UNDEFINED;
     int mRemovedCount = UNDEFINED;
-    AccessibilityNodeInfo mSourceNode;
+    long mSourceNodeId = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
     int mSourceWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
 
     CharSequence mClassName;
@@ -116,7 +117,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void setSource(View source) {
-        setSource(source, UNDEFINED);
+        setSource(source, AccessibilityNodeProvider.HOST_VIEW_ID);
     }
 
     /**
@@ -133,46 +134,28 @@
      * @param root The root of the virtual subtree.
      * @param virtualDescendantId The id of the virtual descendant.
      */
-    public void setSource(View root, int virtualDescendantId) {
+    public void setSource(@Nullable View root, int virtualDescendantId) {
         enforceNotSealed();
         boolean important = true;
+        int rootViewId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
         mSourceWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
-        clearSourceNode();
         if (root != null) {
-            if (virtualDescendantId == View.NO_ID
-                    || virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID
-                    || virtualDescendantId == AccessibilityNodeProvider.HOST_VIEW_ID) {
-                important = root.isImportantForAccessibility();
-                mSourceNode = root.createAccessibilityNodeInfo();
-            } else {
-                AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
-                if (provider != null) {
-                    mSourceNode = provider.createAccessibilityNodeInfo(virtualDescendantId);
-                }
-            }
-
+            important = root.isImportantForAccessibility();
+            rootViewId = root.getAccessibilityViewId();
             mSourceWindowId = root.getAccessibilityWindowId();
         }
         setBooleanProperty(PROPERTY_IMPORTANT_FOR_ACCESSIBILITY, important);
+        mSourceNodeId = AccessibilityNodeInfo.makeNodeId(rootViewId, virtualDescendantId);
     }
 
     /**
-     * Set the source directly to an AccessibilityNodeInfo rather than indirectly via a View
+     * Set the source node ID directly
      *
-     * @param info The source
-     *
+     * @param sourceNodeId The source node Id
      * @hide
      */
-    public void setSource(AccessibilityNodeInfo info) {
-        enforceNotSealed();
-        clearSourceNode();
-        mSourceWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
-        if (info != null) {
-            mSourceNode = AccessibilityNodeInfo.obtain(info);
-            setBooleanProperty(PROPERTY_IMPORTANT_FOR_ACCESSIBILITY,
-                    mSourceNode.isImportantForAccessibility());
-            mSourceWindowId = info.getWindowId();
-        }
+    public void setSourceNodeId(long sourceNodeId) {
+        mSourceNodeId = sourceNodeId;
     }
 
     /**
@@ -186,11 +169,15 @@
      */
     public AccessibilityNodeInfo getSource() {
         enforceSealed();
-        if (mSourceNode != null) {
-            return AccessibilityNodeInfo.obtain(mSourceNode);
+        if ((mConnectionId == UNDEFINED)
+                || (mSourceWindowId == AccessibilityWindowInfo.UNDEFINED_WINDOW_ID)
+                || (AccessibilityNodeInfo.getAccessibilityViewId(mSourceNodeId)
+                        == AccessibilityNodeInfo.UNDEFINED_ITEM_ID)) {
+            return null;
         }
-
-        return null;
+        AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+        return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, mSourceWindowId,
+                mSourceNodeId, false, GET_SOURCE_PREFETCH_FLAGS, null);
     }
 
     /**
@@ -336,6 +323,20 @@
     }
 
     /**
+     * Sets if the source is important for accessibility.
+     *
+     * @param importantForAccessibility True if the source is important for accessibility,
+     *                                  false otherwise.
+     *
+     * @throws IllegalStateException If called from an AccessibilityService.
+     * @hide
+     */
+    public void setImportantForAccessibility(boolean importantForAccessibility) {
+        enforceNotSealed();
+        setBooleanProperty(PROPERTY_IMPORTANT_FOR_ACCESSIBILITY, importantForAccessibility);
+    }
+
+    /**
      * Gets the number of items that can be visited.
      *
      * @return The number of items.
@@ -647,7 +648,7 @@
      * @hide
      */
     public long getSourceNodeId() {
-        return mSourceNode != null ? mSourceNode.getSourceNodeId() : UNDEFINED;
+        return mSourceNodeId;
     }
 
     /**
@@ -661,9 +662,6 @@
     public void setConnectionId(int connectionId) {
         enforceNotSealed();
         mConnectionId = connectionId;
-        if (mSourceNode != null) {
-            mSourceNode.setConnectionId(mConnectionId);
-        }
     }
 
     /**
@@ -675,9 +673,6 @@
      */
     public void setSealed(boolean sealed) {
         mSealed = sealed;
-        if (mSourceNode != null) {
-            mSourceNode.setSealed(sealed);
-        }
     }
 
     /**
@@ -816,9 +811,7 @@
         mParcelableData = record.mParcelableData;
         mText.addAll(record.mText);
         mSourceWindowId = record.mSourceWindowId;
-        if (record.mSourceNode != null) {
-            mSourceNode = AccessibilityNodeInfo.obtain(record.mSourceNode);
-        }
+        mSourceNodeId = record.mSourceNodeId;
         mConnectionId = record.mConnectionId;
     }
 
@@ -843,19 +836,11 @@
         mBeforeText = null;
         mParcelableData = null;
         mText.clear();
-        clearSourceNode();
-        mSourceWindowId = UNDEFINED;
+        mSourceNodeId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
+        mSourceWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
         mConnectionId = UNDEFINED;
     }
 
-    private void clearSourceNode() {
-        if (mSourceNode != null) {
-            mSourceNode.recycle();
-            mSourceNode = null;
-        }
-
-    }
-
     @Override
     public String toString() {
         StringBuilder builder = new StringBuilder();
diff --git a/core/java/android/view/accessibility/AccessibilityRequestPreparer.java b/core/java/android/view/accessibility/AccessibilityRequestPreparer.java
new file mode 100644
index 0000000..c032390
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityRequestPreparer.java
@@ -0,0 +1,125 @@
+/*
+ * 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.accessibility;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Message;
+import android.view.View;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+
+/**
+ * Object responsible to ensuring that a {@link View} is prepared to meet a synchronous request for
+ * accessibility data.
+ * <p>
+ * Because accessibility requests arrive to {@link View}s synchronously on the UI thread, a View
+ * that requires information from other processes can struggle to meet those requests. Registering
+ * an instance of this class with {@link AccessibilityManager} allows a View to be notified when
+ * a request is about to be made, and to asynchronously inform the accessibility system when it is
+ * ready to meet the request.
+ * <p>
+ * <strong>Note:</strong> This class should only be needed in exceptional situations where a
+ * {@link View} cannot otherwise synchronously meet the request for accessibility data.
+ * @hide
+ */
+@TestApi
+public abstract class AccessibilityRequestPreparer {
+    public static final int REQUEST_TYPE_EXTRA_DATA = 0x00000001;
+
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                REQUEST_TYPE_EXTRA_DATA
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RequestTypes {}
+
+    private final WeakReference<View> mViewRef;
+    private final int mRequestTypes;
+
+    /**
+     * @param view The view whose requests need preparation. It must be attached to a
+     * window. This object will retain a weak reference to this view, and will unregister itself
+     * from AccessibilityManager if the view is detached from a window. It will not re-register
+     * itself.
+     * @param requestTypes The types of requests that require preparation. Different types may
+     * be ORed together.
+     *
+     * @throws IllegalStateException if the view is not attached to a window.
+     */
+    public AccessibilityRequestPreparer(View view, @RequestTypes int requestTypes) {
+        if (!view.isAttachedToWindow()) {
+            throw new IllegalStateException("View must be attached to a window");
+        }
+        mViewRef = new WeakReference<>(view);
+        mRequestTypes = requestTypes;
+        view.addOnAttachStateChangeListener(new ViewAttachStateListener());
+    }
+
+    /**
+     * Callback to allow preparation for filling extra data. Only called back if
+     * REQUEST_TYPE_EXTRA_DATA is requested.
+     *
+     * @param virtualViewId The ID of a virtual child node, if the {@link View} for this preparer
+     * supports virtual descendents, or {@link AccessibilityNodeProvider#HOST_VIEW_ID}
+     * if the request is for the view itself.
+     * @param extraDataKey The extra data key for the request
+     * @param args The arguments for the request
+     * @param preparationFinishedMessage A message that must be sent to its target when preparations
+     * are complete.
+     *
+     * @see View#addExtraDataToAccessibilityNodeInfo(AccessibilityNodeInfo, String, Bundle)
+     * @see AccessibilityDelegate#addExtraDataToAccessibilityNodeInfo(View, AccessibilityNodeInfo,
+     * String, Bundle)
+     * @see AccessibilityNodeProvider#addExtraDataToAccessibilityNodeInfo(
+     * int, AccessibilityNodeInfo, String, Bundle)
+     */
+    public abstract void onPrepareExtraData(int virtualViewId, String extraDataKey,
+            Bundle args, Message preparationFinishedMessage);
+
+    /**
+     * Get the view this object was created with.
+     *
+     * @return The view this object was created with, or {@code null} if the weak reference held
+     * to the view is no longer valid.
+     */
+    public @Nullable View getView() {
+        return mViewRef.get();
+    }
+
+    private class ViewAttachStateListener implements View.OnAttachStateChangeListener {
+        @Override
+        public void onViewAttachedToWindow(View v) {
+        }
+
+        @Override
+        public void onViewDetachedFromWindow(View v) {
+            Context context = v.getContext();
+            if (context != null) {
+                context.getSystemService(AccessibilityManager.class)
+                        .removeAccessibilityRequestPreparer(AccessibilityRequestPreparer.this);
+            }
+            v.removeOnAttachStateChangeListener(this);
+        }
+    }
+}
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 5b04f41..15c18ac 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -51,10 +51,68 @@
 import java.util.List;
 import java.util.Objects;
 
+// TODO: use java.lang.ref.Cleaner once Android supports Java 9
+import sun.misc.Cleaner;
+
 /**
- * App entry point to the Autofill Framework.
+ * The {@link AutofillManager} provides ways for apps and custom views to integrate with the
+ * Autofill Framework lifecycle.
  *
- * <p>It is safe to call into this from any thread.
+ * <p>The autofill lifecycle starts with the creation of an autofill context associated with an
+ * activity context; the autofill context is created when one of the following methods is called for
+ * the first time in an activity context, and the current user has an enabled autofill service:
+ *
+ * <ul>
+ *   <li>{@link #notifyViewEntered(View)}
+ *   <li>{@link #notifyViewEntered(View, int, Rect)}
+ *   <li>{@link #requestAutofill(View)}
+ * </ul>
+ *
+ * <p>Tipically, the context is automatically created when the first view of the activity is
+ * focused because {@code View.onFocusChanged()} indirectly calls
+ * {@link #notifyViewEntered(View)}. App developers can call {@link #requestAutofill(View)} to
+ * explicitly create it (for example, a custom view developer could offer a contextual menu action
+ * in a text-field view to let users manually request autofill).
+ *
+ * <p>After the context is created, the Android System creates a {@link android.view.ViewStructure}
+ * that represents the view hierarchy by calling
+ * {@link View#dispatchProvideAutofillStructure(android.view.ViewStructure, int)} in the root views
+ * of all application windows. By default, {@code dispatchProvideAutofillStructure()} results in
+ * subsequent calls to {@link View#onProvideAutofillStructure(android.view.ViewStructure, int)} and
+ * {@link View#onProvideAutofillVirtualStructure(android.view.ViewStructure, int)} for each view in
+ * the hierarchy.
+ *
+ * <p>The resulting {@link android.view.ViewStructure} is then passed to the autofill service, which
+ * parses it looking for views that can be autofilled. If the service finds such views, it returns
+ * a data structure to the Android System containing the following optional info:
+ *
+ * <ul>
+ *   <li>Datasets used to autofill subsets of views in the activity.
+ *   <li>Id of views that the service can save their values for future autofilling.
+ * </ul>
+ *
+ * <p>When the service returns datasets, the Android System displays an autofill dataset picker
+ * UI affordance associated with the view, when the view is focused on and is part of a dataset.
+ * The application can be notified when the affordance is shown by registering an
+ * {@link AutofillCallback} through {@link #registerCallback(AutofillCallback)}. When the user
+ * selects a dataset from the affordance, all views present in the dataset are autofilled, through
+ * calls to {@link View#autofill(AutofillValue)} or {@link View#autofill(SparseArray)}.
+ *
+ * <p>When the service returns ids of savable views, the Android System keeps track of changes
+ * made to these views, so they can be used to determine if the autofill save UI is shown later.
+ *
+ * <p>The context is then finished when one of the following occurs:
+ *
+ * <ul>
+ *   <li>{@link #commit()} is called or all savable views are gone.
+ *   <li>{@link #cancel()} is called.
+ * </ul>
+ *
+ * <p>Finally, after the autofill context is commited (i.e., not cancelled), the Android System
+ * shows a save UI affordance if the value of savable views have changed. If the user selects the
+ * option to Save, the current value of the views is then sent to the autofill service.
+ *
+ * <p>It is safe to call into its methods from any thread.
  */
 @SystemService(Context.AUTOFILL_MANAGER_SERVICE)
 public final class AutofillManager {
@@ -170,6 +228,9 @@
     private IAutoFillManagerClient mServiceClient;
 
     @GuardedBy("mLock")
+    private Cleaner mServiceClientCleaner;
+
+    @GuardedBy("mLock")
     private AutofillCallback mCallback;
 
     private final Context mContext;
@@ -671,8 +732,13 @@
     /**
      * Called to indicate the current autofill context should be commited.
      *
-     * <p>For example, when a virtual view is rendering an {@code HTML} page with a form, it should
-     * call this method after the form is submitted and another page is rendered.
+     * <p>This method is typically called by {@link View Views} that manage virtual views; for
+     * example, when the view is rendering an {@code HTML} page with a form and virtual views
+     * that represent the HTML elements, it should call this method after the form is submitted and
+     * another page is rendered.
+     *
+     * <p><b>Note:</b> This method does not need to be called on regular application lifecycle
+     * methods such as {@link android.app.Activity#finish()}.
      */
     public void commit() {
         if (!hasAutofillFeature()) {
@@ -690,8 +756,13 @@
     /**
      * Called to indicate the current autofill context should be cancelled.
      *
-     * <p>For example, when a virtual view is rendering an {@code HTML} page with a form, it should
-     * call this method if the user does not post the form but moves to another form in this page.
+     * <p>This method is typically called by {@link View Views} that manage virtual views; for
+     * example, when the view is rendering an {@code HTML} page with a form and virtual views
+     * that represent the HTML elements, it should call this method if the user does not post the
+     * form but moves to another form in this page.
+     *
+     * <p><b>Note:</b> This method does not need to be called on regular application lifecycle
+     * methods such as {@link android.app.Activity#finish()}.
      */
     public void cancel() {
         if (!hasAutofillFeature()) {
@@ -741,7 +812,8 @@
     }
 
     /**
-     * Returns {@code true} if Autofill is supported for this user.
+     * Returns {@code true} if autofill is supported by the current device and
+     * is supported for this user.
      *
      * <p>Autofill is typically supported, but it could be unsupported in cases like:
      * <ol>
@@ -892,10 +964,19 @@
         if (mServiceClient == null) {
             mServiceClient = new AutofillManagerClient(this);
             try {
-                final int flags = mService.addClient(mServiceClient, mContext.getUserId());
+                final int userId = mContext.getUserId();
+                final int flags = mService.addClient(mServiceClient, userId);
                 mEnabled = (flags & FLAG_ADD_CLIENT_ENABLED) != 0;
                 sDebug = (flags & FLAG_ADD_CLIENT_DEBUG) != 0;
                 sVerbose = (flags & FLAG_ADD_CLIENT_VERBOSE) != 0;
+                final IAutoFillManager service = mService;
+                final IAutoFillManagerClient serviceClient = mServiceClient;
+                mServiceClientCleaner = Cleaner.create(this, () -> {
+                    try {
+                        service.removeClient(serviceClient, userId);
+                    } catch (RemoteException e) {
+                    }
+                });
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1002,6 +1083,10 @@
             if (resetClient) {
                 // Reset connection to system
                 mServiceClient = null;
+                if (mServiceClientCleaner != null) {
+                    mServiceClientCleaner.clean();
+                    mServiceClientCleaner = null;
+                }
             }
         }
     }
@@ -1461,10 +1546,10 @@
     }
 
     /**
-     * Callback for auto-fill related events.
+     * Callback for autofill related events.
      *
      * <p>Typically used for applications that display their own "auto-complete" views, so they can
-     * enable / disable such views when the auto-fill UI affordance is shown / hidden.
+     * enable / disable such views when the autofill UI affordance is shown / hidden.
      */
     public abstract static class AutofillCallback {
 
@@ -1474,7 +1559,7 @@
         public @interface AutofillEventType {}
 
         /**
-         * The auto-fill input UI affordance associated with the view was shown.
+         * The autofill input UI affordance associated with the view was shown.
          *
          * <p>If the view provides its own auto-complete UI affordance and its currently shown, it
          * should be hidden upon receiving this event.
@@ -1482,7 +1567,7 @@
         public static final int EVENT_INPUT_SHOWN = 1;
 
         /**
-         * The auto-fill input UI affordance associated with the view was hidden.
+         * The autofill input UI affordance associated with the view was hidden.
          *
          * <p>If the view provides its own auto-complete UI affordance that was hidden upon a
          * {@link #EVENT_INPUT_SHOWN} event, it could be shown again now.
@@ -1490,7 +1575,7 @@
         public static final int EVENT_INPUT_HIDDEN = 2;
 
         /**
-         * The auto-fill input UI affordance associated with the view won't be shown because
+         * The autofill input UI affordance associated with the view isn't shown because
          * autofill is not available.
          *
          * <p>If the view provides its own auto-complete UI affordance but was not displaying it
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index 627afa7..7f2c080 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -32,6 +32,7 @@
 interface IAutoFillManager {
     // Returns flags: FLAG_ADD_CLIENT_ENABLED | FLAG_ADD_CLIENT_DEBUG | FLAG_ADD_CLIENT_VERBOSE
     int addClient(in IAutoFillManagerClient client, int userId);
+    void removeClient(in IAutoFillManagerClient client, int userId);
     int startSession(IBinder activityToken, in IBinder appCallback, in AutofillId autoFillId,
             in Rect bounds, in AutofillValue value, int userId, boolean hasCallback, int flags,
             String packageName);
diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
index 2e2056c..779eefb 100644
--- a/core/java/android/view/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -29,6 +29,8 @@
 import com.android.internal.textservice.ITextServicesManager;
 import com.android.internal.textservice.ITextServicesSessionListener;
 
+import dalvik.system.CloseGuard;
+
 import java.util.LinkedList;
 import java.util.Queue;
 
@@ -98,7 +100,7 @@
     private final SpellCheckerSessionListener mSpellCheckerSessionListener;
     private final SpellCheckerSessionListenerImpl mSpellCheckerSessionListenerImpl;
 
-    private boolean mIsUsed;
+    private final CloseGuard mGuard = CloseGuard.get();
 
     /** Handler that will execute the main tasks */
     private final Handler mHandler = new Handler() {
@@ -128,8 +130,9 @@
         mSpellCheckerSessionListenerImpl = new SpellCheckerSessionListenerImpl(mHandler);
         mInternalListener = new InternalListener(mSpellCheckerSessionListenerImpl);
         mTextServicesManager = tsm;
-        mIsUsed = true;
         mSpellCheckerSessionListener = listener;
+
+        mGuard.open("finishSession");
     }
 
     /**
@@ -160,7 +163,7 @@
      * checker.
      */
     public void close() {
-        mIsUsed = false;
+        mGuard.close();
         try {
             mSpellCheckerSessionListenerImpl.close();
             mTextServicesManager.finishSpellCheckerService(mSpellCheckerSessionListenerImpl);
@@ -542,11 +545,14 @@
 
     @Override
     protected void finalize() throws Throwable {
-        super.finalize();
-        if (mIsUsed) {
-            Log.e(TAG, "SpellCheckerSession was not finished properly." +
-                    "You should call finishSession() when you finished to use a spell checker.");
-            close();
+        try {
+            // Note that mGuard will be null if the constructor threw.
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+                close();
+            }
+        } finally {
+            super.finalize();
         }
     }
 
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index dda5df6..a0b4a03 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -31,15 +31,15 @@
 import android.graphics.Picture;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.net.http.SslCertificate;
 import android.net.Uri;
+import android.net.http.SslCertificate;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.StrictMode;
 import android.os.RemoteException;
+import android.os.StrictMode;
 import android.print.PrintDocumentAdapter;
 import android.security.KeyChain;
 import android.util.AttributeSet;
@@ -49,10 +49,10 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewStructure;
 import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.ViewHierarchyEncoder;
+import android.view.ViewStructure;
 import android.view.ViewTreeObserver;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -1621,6 +1621,25 @@
     }
 
     /**
+     * Starts Safe Browsing initialization. This should only be called once.
+     * @param context is the activity context the WebView will be used in.
+     * @param callback will be called with the value true if initialization is
+     * successful. The callback will be run on the UI thread.
+     * @hide
+     */
+    public static void initSafeBrowsing(Context context, ValueCallback<Boolean> callback) {
+        getFactory().getStatics().initSafeBrowsing(context, callback);
+    }
+
+    /**
+     * Shuts down Safe Browsing. This should only be called once.
+     * @hide
+     */
+    public static void shutdownSafeBrowsing() {
+        getFactory().getStatics().shutdownSafeBrowsing();
+    }
+
+    /**
      * Gets the WebBackForwardList for this WebView. This contains the
      * back/forward list for use in querying each item in the history stack.
      * This is a copy of the private WebBackForwardList so it contains only a
@@ -1939,12 +1958,12 @@
      * messages to a certain target origin. See
      * <a href="https://html.spec.whatwg.org/multipage/comms.html#posting-messages">
      * HTML5 spec</a> for how target origin can be used.
+     * <p>
+     * A target origin can be set as a wildcard ("*"). However this is not recommended.
+     * See the page above for security issues.
      *
      * @param message the WebMessage
-     * @param targetOrigin the target origin. This is the origin of the page
-     *          that is intended to receive the message. For best security
-     *          practices, the user should not specify a wildcard (*) when
-     *          specifying the origin.
+     * @param targetOrigin the target origin.
      */
     public void postWebMessage(WebMessage message, Uri targetOrigin) {
         checkThread();
@@ -2648,6 +2667,18 @@
      * understood by the {@link android.service.autofill.AutofillService} implementations:
      *
      * <ol>
+     *   <li>Only the HTML nodes inside a {@code FORM} are generated.
+     *   <li>The source of the HTML is set using {@link ViewStructure#setWebDomain(String)} in the
+     *   node representing the WebView.
+     *   <li>If a web page has multiple {@code FORM}s, only the data for the current form is
+     *   represented&mdash;if the user taps a field from another form, then the current autofill
+     *   context is canceled (by calling {@link android.view.autofill.AutofillManager#cancel()} and
+     *   a new context is created for that {@code FORM}.
+     *   <li>Similarly, if the page has {@code IFRAME} nodes, they are not initially represented in
+     *   the view structure until the user taps a field from a {@code FORM} inside the
+     *   {@code IFRAME}, in which case it would be treated the same way as multiple forms described
+     *   above, except that the {@link ViewStructure#setWebDomain(String) web domain} of the
+     *   {@code FORM} contains the {@code src} attribute from the {@code IFRAME} node.
      *   <li>If the Android SDK provides a similar View, then should be set with the
      *   fully-qualified class name of such view.
      *   <li>The W3C autofill field ({@code autocomplete} tag attribute) maps to
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 71db6b1..1b6b392 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -107,6 +107,7 @@
     // error for namespace lookup
     public static final int LIBLOAD_FAILED_TO_FIND_NAMESPACE = 10;
 
+
     private static String getWebViewPreparationErrorReason(int error) {
         switch (error) {
             case LIBLOAD_FAILED_WAITING_FOR_RELRO:
@@ -119,10 +120,7 @@
         return "Unknown";
     }
 
-    /**
-     * @hide
-     */
-    public static class MissingWebViewPackageException extends AndroidRuntimeException {
+    private static class MissingWebViewPackageException extends Exception {
         public MissingWebViewPackageException(String message) { super(message); }
         public MissingWebViewPackageException(Exception e) { super(e); }
     }
@@ -184,11 +182,16 @@
             return LIBLOAD_WRONG_PACKAGE_NAME;
         }
 
-        int loadNativeRet = loadNativeLibrary(clazzLoader, packageInfo);
-        // If we failed waiting for relro we want to return that fact even if we successfully load
-        // the relro file.
-        if (loadNativeRet == LIBLOAD_SUCCESS) return response.status;
-        return loadNativeRet;
+        try {
+            int loadNativeRet = loadNativeLibrary(clazzLoader, packageInfo);
+            // If we failed waiting for relro we want to return that fact even if we successfully
+            // load the relro file.
+            if (loadNativeRet == LIBLOAD_SUCCESS) return response.status;
+            return loadNativeRet;
+        } catch (MissingWebViewPackageException e) {
+            Log.e(LOGTAG, "Couldn't load native library: " + e);
+            return LIBLOAD_FAILED_TO_LOAD_LIBRARY;
+        }
     }
 
     static WebViewFactoryProvider getProvider() {
@@ -259,7 +262,8 @@
     }
 
     // Throws MissingWebViewPackageException on failure
-    private static void verifyPackageInfo(PackageInfo chosen, PackageInfo toUse) {
+    private static void verifyPackageInfo(PackageInfo chosen, PackageInfo toUse)
+            throws MissingWebViewPackageException {
         if (!chosen.packageName.equals(toUse.packageName)) {
             throw new MissingWebViewPackageException("Failed to verify WebView provider, "
                     + "packageName mismatch, expected: "
@@ -285,7 +289,8 @@
      * required values from the donor package. If the ApplicationInfo is for a full WebView,
      * leave it alone. Throws MissingWebViewPackageException if the donor is missing.
      */
-    private static void fixupStubApplicationInfo(ApplicationInfo ai, PackageManager pm) {
+    private static void fixupStubApplicationInfo(ApplicationInfo ai, PackageManager pm)
+            throws MissingWebViewPackageException {
         String donorPackageName = null;
         if (ai.metaData != null) {
             donorPackageName = ai.metaData.getString("com.android.webview.WebViewDonorPackage");
@@ -318,7 +323,7 @@
         }
     }
 
-    private static Context getWebViewContextAndSetProvider() {
+    private static Context getWebViewContextAndSetProvider() throws MissingWebViewPackageException {
         Application initialApplication = AppGlobals.getInitialApplication();
         try {
             WebViewProviderResponse response = null;
@@ -549,10 +554,10 @@
         return prepareWebViewInSystemServer(nativeLibs);
     }
 
-    // throws MissingWebViewPackageException
     private static String getLoadFromApkPath(String apkPath,
                                              String[] abiList,
-                                             String nativeLibFileName) {
+                                             String nativeLibFileName)
+            throws MissingWebViewPackageException {
         // Search the APK for a native library conforming to a listed ABI.
         try (ZipFile z = new ZipFile(apkPath)) {
             for (String abi : abiList) {
@@ -569,8 +574,8 @@
         return "";
     }
 
-    // throws MissingWebViewPackageException
-    private static String[] getWebViewNativeLibraryPaths(PackageInfo packageInfo) {
+    private static String[] getWebViewNativeLibraryPaths(PackageInfo packageInfo)
+            throws MissingWebViewPackageException {
         ApplicationInfo ai = packageInfo.applicationInfo;
         final String NATIVE_LIB_FILE_NAME = getWebViewLibrary(ai);
 
@@ -695,7 +700,8 @@
     }
 
     // Assumes that we have waited for relro creation
-    private static int loadNativeLibrary(ClassLoader clazzLoader, PackageInfo packageInfo) {
+    private static int loadNativeLibrary(ClassLoader clazzLoader, PackageInfo packageInfo)
+            throws MissingWebViewPackageException {
         if (!sAddressSpaceReserved) {
             Log.e(LOGTAG, "can't load with relro file; address space not reserved");
             return LIBLOAD_ADDRESS_SPACE_NOT_RESERVED;
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
index 8359a10..00fdac8 100644
--- a/core/java/android/webkit/WebViewFactoryProvider.java
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -74,6 +74,22 @@
          * {@link android.webkit.WebChromeClient.FileChooserParams#parseResult(int, Intent)}
          */
         Uri[] parseFileChooserResult(int resultCode, Intent intent);
+
+        /**
+         * Implement the API method
+         * {@link android.webkit.WebView#initSafeBrowsing(Context , ValueCallback<Boolean>)}
+         * @hide
+         */
+        default void initSafeBrowsing(Context context, ValueCallback<Boolean> callback) {
+        }
+
+        /**
+         * Implement the API method
+         * {@link android.webkit.WebView#shutdownSafeBrowsing()}
+         * @hide
+         */
+        default void shutdownSafeBrowsing() {
+        }
     }
 
     Statics getStatics();
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
index b519ec9..0204dff 100644
--- a/core/java/android/webkit/WebViewZygote.java
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -218,7 +218,7 @@
             final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
                     TextUtils.join(File.pathSeparator, zipPaths);
 
-            waitForZygote();
+            ZygoteProcess.waitForConnectionToZygote(WEBVIEW_ZYGOTE_SOCKET);
 
             Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath);
             sZygote.preloadPackageForAbi(zip, librarySearchPath, sPackageCacheKey,
@@ -228,25 +228,4 @@
             sZygote = null;
         }
     }
-
-    /**
-     * Wait until a connection to the Zygote can be established.
-     */
-    private static void waitForZygote() {
-        while (true) {
-            try {
-                final ZygoteProcess.ZygoteState zs =
-                        ZygoteProcess.ZygoteState.connect(WEBVIEW_ZYGOTE_SOCKET);
-                zs.close();
-                break;
-            } catch (IOException ioe) {
-                Log.w(LOGTAG, "Got error connecting to zygote, retrying. msg= " + ioe.getMessage());
-            }
-
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException ie) {
-            }
-        }
-    }
 }
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index 98d8a13..f9f5901 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -59,7 +59,8 @@
     // Time it will take in ms for a pulled glow to decay to partial strength before release
     private static final int PULL_DECAY_TIME = 2000;
 
-    private static final float MAX_ALPHA = 0.5f;
+    private static final float MAX_ALPHA = 0.15f;
+    private static final float GLOW_ALPHA_START = .09f;
 
     private static final float MAX_GLOW_SCALE = 2.f;
 
@@ -75,6 +76,7 @@
     private static final double ANGLE = Math.PI / 6;
     private static final float SIN = (float) Math.sin(ANGLE);
     private static final float COS = (float) Math.cos(ANGLE);
+    private static final float RADIUS_FACTOR = 0.6f;
 
     private float mGlowAlpha;
     private float mGlowScaleY;
@@ -134,10 +136,10 @@
      * @param height Effect height in pixels
      */
     public void setSize(int width, int height) {
-        final float r = width * 0.75f / SIN;
+        final float r = width * RADIUS_FACTOR / SIN;
         final float y = COS * r;
         final float h = r - y;
-        final float or = height * 0.75f / SIN;
+        final float or = height * RADIUS_FACTOR / SIN;
         final float oy = COS * or;
         final float oh = or - oy;
 
@@ -272,7 +274,7 @@
 
         // The glow depends more on the velocity, and therefore starts out
         // nearly invisible.
-        mGlowAlphaStart = 0.3f;
+        mGlowAlphaStart = GLOW_ALPHA_START;
         mGlowScaleYStart = Math.max(mGlowScaleY, 0.f);
 
 
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 45e5f8a..6374aa2 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3909,25 +3909,30 @@
             menu.removeItem(TextView.ID_ASSIST);
             final TextClassification textClassification =
                     getSelectionActionModeHelper().getTextClassification();
-            if (textClassification != null) {
-                final Drawable icon = textClassification.getIcon();
-                final CharSequence label = textClassification.getLabel();
-                final OnClickListener onClickListener =
-                        textClassification.getOnClickListener();
-                final Intent intent = textClassification.getIntent();
-                if ((icon != null || !TextUtils.isEmpty(label))
-                        && (onClickListener != null || intent != null)) {
-                    menu.add(TextView.ID_ASSIST, TextView.ID_ASSIST, MENU_ITEM_ORDER_ASSIST, label)
-                            .setIcon(icon)
-                            .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
-                    mMetricsLogger.write(
-                            new LogMaker(MetricsEvent.TEXT_SELECTION_MENU_ITEM_ASSIST)
-                                    .setType(MetricsEvent.TYPE_OPEN)
-                                    .setSubtype(textClassification.getLogType()));
-                }
+            if (canAssist()) {
+                menu.add(TextView.ID_ASSIST, TextView.ID_ASSIST, MENU_ITEM_ORDER_ASSIST,
+                        textClassification.getLabel())
+                        .setIcon(textClassification.getIcon())
+                        .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+                mMetricsLogger.write(
+                        new LogMaker(MetricsEvent.TEXT_SELECTION_MENU_ITEM_ASSIST)
+                                .setType(MetricsEvent.TYPE_OPEN)
+                                .setSubtype(textClassification.getLogType()));
             }
         }
 
+        private boolean canAssist() {
+            final TextClassification textClassification =
+                    getSelectionActionModeHelper().getTextClassification();
+            return mTextView.isDeviceProvisioned()
+                    && textClassification != null
+                    && (textClassification.getIcon() != null
+                            || !TextUtils.isEmpty(textClassification.getLabel()))
+                    && (textClassification.getOnClickListener() != null
+                            || (textClassification.getIntent() != null
+                                    && mTextView.getContext().canStartActivityForResult()));
+        }
+
         @Override
         public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
             getSelectionActionModeHelper().onSelectionAction();
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index aa6ffce..6e62351 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -99,6 +99,26 @@
      */
     private static final int MAX_NESTED_VIEWS = 10;
 
+    // The unique identifiers for each custom {@link Action}.
+    private static final int SET_ON_CLICK_PENDING_INTENT_TAG = 1;
+    private static final int REFLECTION_ACTION_TAG = 2;
+    private static final int SET_DRAWABLE_PARAMETERS_TAG = 3;
+    private static final int VIEW_GROUP_ACTION_ADD_TAG = 4;
+    private static final int SET_REFLECTION_ACTION_WITHOUT_PARAMS_TAG = 5;
+    private static final int SET_EMPTY_VIEW_ACTION_TAG = 6;
+    private static final int VIEW_GROUP_ACTION_REMOVE_TAG = 7;
+    private static final int SET_PENDING_INTENT_TEMPLATE_TAG = 8;
+    private static final int SET_ON_CLICK_FILL_IN_INTENT_TAG = 9;
+    private static final int SET_REMOTE_VIEW_ADAPTER_INTENT_TAG = 10;
+    private static final int TEXT_VIEW_DRAWABLE_ACTION_TAG = 11;
+    private static final int BITMAP_REFLECTION_ACTION_TAG = 12;
+    private static final int TEXT_VIEW_SIZE_ACTION_TAG = 13;
+    private static final int VIEW_PADDING_ACTION_TAG = 14;
+    private static final int SET_REMOTE_VIEW_ADAPTER_LIST_TAG = 15;
+    private static final int TEXT_VIEW_DRAWABLE_COLOR_FILTER_ACTION_TAG = 17;
+    private static final int SET_REMOTE_INPUTS_ACTION_TAG = 18;
+    private static final int LAYOUT_PARAM_ACTION_TAG = 19;
+
     /**
      * Application that hosts the remote views.
      *
@@ -179,6 +199,22 @@
     }
 
     /**
+     * Reduces all images and ensures that they are all below the given sizes.
+     *
+     * @param maxWidth the maximum width allowed
+     * @param maxHeight the maximum height allowed
+     *
+     * @hide
+     */
+    public void reduceImageSizes(int maxWidth, int maxHeight) {
+        ArrayList<Bitmap> cache = mBitmapCache.mBitmaps;
+        for (int i = 0; i < cache.size(); i++) {
+            Bitmap bitmap = cache.get(i);
+            cache.set(i, Icon.scaleDownIfNecessary(bitmap, maxWidth, maxHeight));
+        }
+    }
+
+    /**
      * Handle with care!
      */
     static class MutablePair<F, S> {
@@ -441,8 +477,6 @@
         int viewId;
         int emptyViewId;
 
-        public final static int TAG = 6;
-
         SetEmptyView(int viewId, int emptyViewId) {
             this.viewId = viewId;
             this.emptyViewId = emptyViewId;
@@ -454,7 +488,7 @@
         }
 
         public void writeToParcel(Parcel out, int flags) {
-            out.writeInt(TAG);
+            out.writeInt(SET_EMPTY_VIEW_ACTION_TAG);
             out.writeInt(this.viewId);
             out.writeInt(this.emptyViewId);
         }
@@ -489,7 +523,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(SET_ON_CLICK_FILL_IN_INTENT_TAG);
             dest.writeInt(viewId);
             fillInIntent.writeToParcel(dest, 0 /* no flags */);
         }
@@ -555,8 +589,6 @@
         }
 
         Intent fillInIntent;
-
-        public final static int TAG = 9;
     }
 
     private class SetPendingIntentTemplate extends Action {
@@ -571,7 +603,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(SET_PENDING_INTENT_TEMPLATE_TAG);
             dest.writeInt(viewId);
             pendingIntentTemplate.writeToParcel(dest, 0 /* no flags */);
         }
@@ -632,8 +664,6 @@
         }
 
         PendingIntent pendingIntentTemplate;
-
-        public final static int TAG = 8;
     }
 
     private class SetRemoteViewsAdapterList extends Action {
@@ -656,7 +686,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(SET_REMOTE_VIEW_ADAPTER_LIST_TAG);
             dest.writeInt(viewId);
             dest.writeInt(viewTypeCount);
 
@@ -715,7 +745,6 @@
 
         int viewTypeCount;
         ArrayList<RemoteViews> list;
-        public final static int TAG = 15;
     }
 
     private class SetRemoteViewsAdapterIntent extends Action {
@@ -730,7 +759,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(SET_REMOTE_VIEW_ADAPTER_INTENT_TAG);
             dest.writeInt(viewId);
             intent.writeToParcel(dest, flags);
         }
@@ -782,8 +811,6 @@
 
         Intent intent;
         boolean isAsync = false;
-
-        public final static int TAG = 10;
     }
 
     /**
@@ -807,7 +834,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(SET_ON_CLICK_PENDING_INTENT_TAG);
             dest.writeInt(viewId);
 
             // We use a flag to indicate whether the parcel contains a valid object.
@@ -860,8 +887,6 @@
         }
 
         PendingIntent pendingIntent;
-
-        public final static int TAG = 1;
     }
 
     private static Rect getSourceBounds(View v) {
@@ -997,7 +1022,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(SET_DRAWABLE_PARAMETERS_TAG);
             dest.writeInt(viewId);
             dest.writeInt(targetBackground ? 1 : 0);
             dest.writeInt(alpha);
@@ -1048,15 +1073,11 @@
         int colorFilter;
         PorterDuff.Mode filterMode;
         int level;
-
-        public final static int TAG = 3;
     }
 
     private final class ReflectionActionWithoutParams extends Action {
         final String methodName;
 
-        public final static int TAG = 5;
-
         ReflectionActionWithoutParams(int viewId, String methodName) {
             this.viewId = viewId;
             this.methodName = methodName;
@@ -1068,7 +1089,7 @@
         }
 
         public void writeToParcel(Parcel out, int flags) {
-            out.writeInt(TAG);
+            out.writeInt(SET_REFLECTION_ACTION_WITHOUT_PARAMS_TAG);
             out.writeInt(this.viewId);
             out.writeString(this.methodName);
         }
@@ -1192,7 +1213,7 @@
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(BITMAP_REFLECTION_ACTION_TAG);
             dest.writeInt(viewId);
             dest.writeString(methodName);
             dest.writeInt(bitmapId);
@@ -1214,16 +1235,12 @@
         public String getActionName() {
             return "BitmapReflectionAction";
         }
-
-        public final static int TAG = 12;
     }
 
     /**
      * Base class for the reflection actions.
      */
     private final class ReflectionAction extends Action {
-        static final int TAG = 2;
-
         static final int BOOLEAN = 1;
         static final int BYTE = 2;
         static final int SHORT = 3;
@@ -1330,7 +1347,7 @@
         }
 
         public void writeToParcel(Parcel out, int flags) {
-            out.writeInt(TAG);
+            out.writeInt(REFLECTION_ACTION_TAG);
             out.writeInt(this.viewId);
             out.writeString(this.methodName);
             out.writeInt(this.type);
@@ -1555,137 +1572,222 @@
     }
 
     /**
-     * Equivalent to calling {@link ViewGroup#addView(View)} after inflating the
-     * given {@link RemoteViews}, or calling {@link ViewGroup#removeAllViews()}
-     * when null. This allows users to build "nested" {@link RemoteViews}.
+     * ViewGroup methods that are related to adding Views.
      */
-    private class ViewGroupAction extends Action {
-        public ViewGroupAction(int viewId, RemoteViews nestedViews) {
+    private class ViewGroupActionAdd extends Action {
+        private RemoteViews mNestedViews;
+        private int mIndex;
+
+        ViewGroupActionAdd(int viewId, RemoteViews nestedViews) {
+            this(viewId, nestedViews, -1 /* index */);
+        }
+
+        ViewGroupActionAdd(int viewId, RemoteViews nestedViews, int index) {
             this.viewId = viewId;
-            this.nestedViews = nestedViews;
+            mNestedViews = nestedViews;
+            mIndex = index;
             if (nestedViews != null) {
                 configureRemoteViewsAsChild(nestedViews);
             }
         }
 
-        ViewGroupAction(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info, int depth) {
+        ViewGroupActionAdd(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info,
+                int depth) {
             viewId = parcel.readInt();
-            boolean nestedViewsNull = parcel.readInt() == 0;
-            if (!nestedViewsNull) {
-                nestedViews = new RemoteViews(parcel, bitmapCache, info, depth);
-            } else {
-                nestedViews = null;
-            }
+            mIndex = parcel.readInt();
+            mNestedViews = new RemoteViews(parcel, bitmapCache, info, depth);
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(VIEW_GROUP_ACTION_ADD_TAG);
             dest.writeInt(viewId);
-            if (nestedViews != null) {
-                dest.writeInt(1);
-                nestedViews.writeToParcel(dest, flags);
-            } else {
-                // signifies null
-                dest.writeInt(0);
-            }
+            dest.writeInt(mIndex);
+            mNestedViews.writeToParcel(dest, flags);
         }
 
         @Override
         public boolean hasSameAppInfo(ApplicationInfo parentInfo) {
-            return nestedViews != null
-                    && nestedViews.mApplication.packageName.equals(parentInfo.packageName)
-                    && nestedViews.mApplication.uid == parentInfo.uid;
+            return mNestedViews.mApplication.packageName.equals(parentInfo.packageName)
+                    && mNestedViews.mApplication.uid == parentInfo.uid;
         }
 
         @Override
         public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
             final Context context = root.getContext();
             final ViewGroup target = root.findViewById(viewId);
-            if (target == null) return;
-            if (nestedViews != null) {
-                // Inflate nested views and add as children
-                target.addView(nestedViews.apply(context, target, handler));
-            } else {
-                // Clear all children when nested views omitted
-                target.removeAllViews();
+
+            if (target == null) {
+                return;
             }
+
+            // Inflate nested views and add as children
+            target.addView(mNestedViews.apply(context, target, handler), mIndex);
         }
 
         @Override
         public Action initActionAsync(ViewTree root, ViewGroup rootParent, OnClickHandler handler) {
             // In the async implementation, update the view tree so that subsequent calls to
-            // findViewById return the currect view.
+            // findViewById return the current view.
             root.createTree();
             ViewTree target = root.findViewTreeById(viewId);
             if ((target == null) || !(target.mRoot instanceof ViewGroup)) {
                 return ACTION_NOOP;
             }
             final ViewGroup targetVg = (ViewGroup) target.mRoot;
-            if (nestedViews == null) {
-                // Clear all children when nested views omitted
-                target.mChildren = null;
-                return new RuntimeAction() {
-                    @Override
-                    public void apply(View root, ViewGroup rootParent, OnClickHandler handler)
-                            throws ActionException {
-                        targetVg.removeAllViews();
-                    }
-                };
-            } else {
-                // Inflate nested views and perform all the async tasks for the child remoteView.
-                final Context context = root.mRoot.getContext();
-                final AsyncApplyTask task = nestedViews.getAsyncApplyTask(
-                        context, targetVg, null, handler);
-                final ViewTree tree = task.doInBackground();
-                if (tree == null) {
-                    throw new ActionException(task.mError);
-                }
 
-                // Update the global view tree, so that next call to findViewTreeById
-                // goes through the subtree as well.
-                target.addChild(tree);
+            // Inflate nested views and perform all the async tasks for the child remoteView.
+            final Context context = root.mRoot.getContext();
+            final AsyncApplyTask task = mNestedViews.getAsyncApplyTask(
+                    context, targetVg, null, handler);
+            final ViewTree tree = task.doInBackground();
 
-                return new RuntimeAction() {
-
-                    @Override
-                    public void apply(View root, ViewGroup rootParent, OnClickHandler handler) throws ActionException {
-                        task.onPostExecute(tree);
-                        targetVg.addView(task.mResult);
-                    }
-                };
+            if (tree == null) {
+                throw new ActionException(task.mError);
             }
+
+            // Update the global view tree, so that next call to findViewTreeById
+            // goes through the subtree as well.
+            target.addChild(tree, mIndex);
+
+            return new RuntimeAction() {
+                @Override
+                public void apply(View root, ViewGroup rootParent, OnClickHandler handler)
+                        throws ActionException {
+                    task.onPostExecute(tree);
+                    targetVg.addView(task.mResult, mIndex);
+                }
+            };
         }
 
         @Override
         public void updateMemoryUsageEstimate(MemoryUsageCounter counter) {
-            if (nestedViews != null) {
-                counter.increment(nestedViews.estimateMemoryUsage());
-            }
+            counter.increment(mNestedViews.estimateMemoryUsage());
         }
 
         @Override
         public void setBitmapCache(BitmapCache bitmapCache) {
-            if (nestedViews != null) {
-                nestedViews.setBitmapCache(bitmapCache);
-            }
+            mNestedViews.setBitmapCache(bitmapCache);
         }
 
-        public String getActionName() {
-            return "ViewGroupAction" + (nestedViews == null ? "Remove" : "Add");
-        }
-
+        @Override
         public int mergeBehavior() {
             return MERGE_APPEND;
         }
 
         @Override
         public boolean prefersAsyncApply() {
-            return nestedViews != null && nestedViews.prefersAsyncApply();
+            return mNestedViews.prefersAsyncApply();
         }
 
-        RemoteViews nestedViews;
 
-        public final static int TAG = 4;
+        @Override
+        public String getActionName() {
+            return "ViewGroupActionAdd";
+        }
+    }
+
+    /**
+     * ViewGroup methods related to removing child views.
+     */
+    private class ViewGroupActionRemove extends Action {
+        /**
+         * Id that indicates that all child views of the affected ViewGroup should be removed.
+         *
+         * <p>Using -2 because the default id is -1. This avoids accidentally matching that.
+         */
+        private static final int REMOVE_ALL_VIEWS_ID = -2;
+
+        private int mViewIdToKeep;
+
+        ViewGroupActionRemove(int viewId) {
+            this(viewId, REMOVE_ALL_VIEWS_ID);
+        }
+
+        ViewGroupActionRemove(int viewId, int viewIdToKeep) {
+            this.viewId = viewId;
+            mViewIdToKeep = viewIdToKeep;
+        }
+
+        ViewGroupActionRemove(Parcel parcel) {
+            viewId = parcel.readInt();
+            mViewIdToKeep = parcel.readInt();
+        }
+
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(VIEW_GROUP_ACTION_REMOVE_TAG);
+            dest.writeInt(viewId);
+            dest.writeInt(mViewIdToKeep);
+        }
+
+        @Override
+        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
+            final ViewGroup target = root.findViewById(viewId);
+
+            if (target == null) {
+                return;
+            }
+
+            if (mViewIdToKeep == REMOVE_ALL_VIEWS_ID) {
+                target.removeAllViews();
+                return;
+            }
+
+            removeAllViewsExceptIdToKeep(target);
+        }
+
+        @Override
+        public Action initActionAsync(ViewTree root, ViewGroup rootParent, OnClickHandler handler) {
+            // In the async implementation, update the view tree so that subsequent calls to
+            // findViewById return the current view.
+            root.createTree();
+            ViewTree target = root.findViewTreeById(viewId);
+
+            if ((target == null) || !(target.mRoot instanceof ViewGroup)) {
+                return ACTION_NOOP;
+            }
+
+            final ViewGroup targetVg = (ViewGroup) target.mRoot;
+
+            // Clear all children when nested views omitted
+            target.mChildren = null;
+            return new RuntimeAction() {
+                @Override
+                public void apply(View root, ViewGroup rootParent, OnClickHandler handler)
+                        throws ActionException {
+                    if (mViewIdToKeep == REMOVE_ALL_VIEWS_ID) {
+                        targetVg.removeAllViews();
+                        return;
+                    }
+
+                    removeAllViewsExceptIdToKeep(targetVg);
+                }
+            };
+        }
+
+        /**
+         * Iterates through the children in the given ViewGroup and removes all the views that
+         * do not have an id of {@link #mViewIdToKeep}.
+         */
+        private void removeAllViewsExceptIdToKeep(ViewGroup viewGroup) {
+            // Otherwise, remove all the views that do not match the id to keep.
+            int index = viewGroup.getChildCount() - 1;
+            while (index >= 0) {
+                if (viewGroup.getChildAt(index).getId() != mViewIdToKeep) {
+                    viewGroup.removeViewAt(index);
+                }
+                index--;
+            }
+        }
+
+        @Override
+        public String getActionName() {
+            return "ViewGroupActionRemove";
+        }
+
+        @Override
+        public int mergeBehavior() {
+            return MERGE_APPEND;
+        }
     }
 
     /**
@@ -1740,7 +1842,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(TEXT_VIEW_DRAWABLE_ACTION_TAG);
             dest.writeInt(viewId);
             dest.writeInt(isRelative ? 1 : 0);
             dest.writeInt(useIcons ? 1 : 0);
@@ -1850,8 +1952,6 @@
 
         boolean drawablesLoaded = false;
         Drawable id1, id2, id3, id4;
-
-        public final static int TAG = 11;
     }
 
     /**
@@ -1871,7 +1971,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(TEXT_VIEW_SIZE_ACTION_TAG);
             dest.writeInt(viewId);
             dest.writeInt(units);
             dest.writeFloat(size);
@@ -1890,8 +1990,6 @@
 
         int units;
         float size;
-
-        public final static int TAG = 13;
     }
 
     /**
@@ -1915,7 +2013,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(VIEW_PADDING_ACTION_TAG);
             dest.writeInt(viewId);
             dest.writeInt(left);
             dest.writeInt(top);
@@ -1935,8 +2033,6 @@
         }
 
         int left, top, right, bottom;
-
-        public final static int TAG = 14;
     }
 
     /**
@@ -1968,7 +2064,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(LAYOUT_PARAM_ACTION_TAG);
             dest.writeInt(viewId);
             dest.writeInt(property);
             dest.writeInt(value);
@@ -2021,8 +2117,6 @@
 
         int property;
         int value;
-
-        public final static int TAG = 19;
     }
 
     /**
@@ -2057,7 +2151,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(TEXT_VIEW_DRAWABLE_COLOR_FILTER_ACTION_TAG);
             dest.writeInt(viewId);
             dest.writeInt(isRelative ? 1 : 0);
             dest.writeInt(index);
@@ -2090,8 +2184,6 @@
         final int index;
         final int color;
         final PorterDuff.Mode mode;
-
-        public final static int TAG = 17;
     }
 
     /**
@@ -2110,14 +2202,14 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(SET_REMOTE_INPUTS_ACTION_TAG);
             dest.writeInt(viewId);
             dest.writeTypedArray(remoteInputs, flags);
         }
 
         @Override
         public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
-            final TextView target = (TextView) root.findViewById(viewId);
+            final View target = root.findViewById(viewId);
             if (target == null) return;
 
             target.setTagInternal(R.id.remote_input_tag, remoteInputs);
@@ -2128,7 +2220,6 @@
         }
 
         final Parcelable[] remoteInputs;
-        public final static int TAG = 18;
     }
 
     /**
@@ -2271,56 +2362,59 @@
                 for (int i=0; i<count; i++) {
                     int tag = parcel.readInt();
                     switch (tag) {
-                        case SetOnClickPendingIntent.TAG:
+                        case SET_ON_CLICK_PENDING_INTENT_TAG:
                             mActions.add(new SetOnClickPendingIntent(parcel));
                             break;
-                        case SetDrawableParameters.TAG:
+                        case SET_DRAWABLE_PARAMETERS_TAG:
                             mActions.add(new SetDrawableParameters(parcel));
                             break;
-                        case ReflectionAction.TAG:
+                        case REFLECTION_ACTION_TAG:
                             mActions.add(new ReflectionAction(parcel));
                             break;
-                        case ViewGroupAction.TAG:
-                            mActions.add(new ViewGroupAction(parcel, mBitmapCache, mApplication,
+                        case VIEW_GROUP_ACTION_ADD_TAG:
+                            mActions.add(new ViewGroupActionAdd(parcel, mBitmapCache, mApplication,
                                     depth));
                             break;
-                        case ReflectionActionWithoutParams.TAG:
+                        case VIEW_GROUP_ACTION_REMOVE_TAG:
+                            mActions.add(new ViewGroupActionRemove(parcel));
+                            break;
+                        case SET_REFLECTION_ACTION_WITHOUT_PARAMS_TAG:
                             mActions.add(new ReflectionActionWithoutParams(parcel));
                             break;
-                        case SetEmptyView.TAG:
+                        case SET_EMPTY_VIEW_ACTION_TAG:
                             mActions.add(new SetEmptyView(parcel));
                             break;
-                        case SetPendingIntentTemplate.TAG:
+                        case SET_PENDING_INTENT_TEMPLATE_TAG:
                             mActions.add(new SetPendingIntentTemplate(parcel));
                             break;
-                        case SetOnClickFillInIntent.TAG:
+                        case SET_ON_CLICK_FILL_IN_INTENT_TAG:
                             mActions.add(new SetOnClickFillInIntent(parcel));
                             break;
-                        case SetRemoteViewsAdapterIntent.TAG:
+                        case SET_REMOTE_VIEW_ADAPTER_INTENT_TAG:
                             mActions.add(new SetRemoteViewsAdapterIntent(parcel));
                             break;
-                        case TextViewDrawableAction.TAG:
+                        case TEXT_VIEW_DRAWABLE_ACTION_TAG:
                             mActions.add(new TextViewDrawableAction(parcel));
                             break;
-                        case TextViewSizeAction.TAG:
+                        case TEXT_VIEW_SIZE_ACTION_TAG:
                             mActions.add(new TextViewSizeAction(parcel));
                             break;
-                        case ViewPaddingAction.TAG:
+                        case VIEW_PADDING_ACTION_TAG:
                             mActions.add(new ViewPaddingAction(parcel));
                             break;
-                        case BitmapReflectionAction.TAG:
+                        case BITMAP_REFLECTION_ACTION_TAG:
                             mActions.add(new BitmapReflectionAction(parcel));
                             break;
-                        case SetRemoteViewsAdapterList.TAG:
+                        case SET_REMOTE_VIEW_ADAPTER_LIST_TAG:
                             mActions.add(new SetRemoteViewsAdapterList(parcel));
                             break;
-                        case TextViewDrawableColorFilterAction.TAG:
+                        case TEXT_VIEW_DRAWABLE_COLOR_FILTER_ACTION_TAG:
                             mActions.add(new TextViewDrawableColorFilterAction(parcel));
                             break;
-                        case SetRemoteInputsAction.TAG:
+                        case SET_REMOTE_INPUTS_ACTION_TAG:
                             mActions.add(new SetRemoteInputsAction(parcel));
                             break;
-                        case LayoutParamAction.TAG:
+                        case LAYOUT_PARAM_ACTION_TAG:
                             mActions.add(new LayoutParamAction(parcel));
                             break;
                         default:
@@ -2471,7 +2565,23 @@
      * @param nestedView {@link RemoteViews} that describes the child.
      */
     public void addView(int viewId, RemoteViews nestedView) {
-        addAction(new ViewGroupAction(viewId, nestedView));
+        addAction(nestedView == null
+                ? new ViewGroupActionRemove(viewId)
+                : new ViewGroupActionAdd(viewId, nestedView));
+    }
+
+    /**
+     * Equivalent to calling {@link ViewGroup#addView(View, int)} after inflating the
+     * given {@link RemoteViews}.
+     *
+     * @param viewId The id of the parent {@link ViewGroup} to add the child into.
+     * @param nestedView {@link RemoveViews} of the child to add.
+     * @param index The position at which to add the child.
+     *
+     * @hide
+     */
+    public void addView(int viewId, RemoteViews nestedView, int index) {
+        addAction(new ViewGroupActionAdd(viewId, nestedView, index));
     }
 
     /**
@@ -2481,7 +2591,20 @@
      *            children from.
      */
     public void removeAllViews(int viewId) {
-        addAction(new ViewGroupAction(viewId, null));
+        addAction(new ViewGroupActionRemove(viewId));
+    }
+
+    /**
+     * Removes all views in the {@link ViewGroup} specified by the {@code viewId} except for any
+     * child that has the {@code viewIdToKeep} as its id.
+     *
+     * @param viewId The id of the parent {@link ViewGroup} to remove children from.
+     * @param viewIdToKeep The id of a child that should not be removed.
+     *
+     * @hide
+     */
+    public void removeAllViewsExceptId(int viewId, int viewIdToKeep) {
+        addAction(new ViewGroupActionRemove(viewId, viewIdToKeep));
     }
 
     /**
@@ -3654,8 +3777,8 @@
      * and can be searched.
      */
     private static class ViewTree {
+        private static final int INSERT_AT_END_INDEX = -1;
         private View mRoot;
-
         private ArrayList<ViewTree> mChildren;
 
         private ViewTree(View root) {
@@ -3708,11 +3831,26 @@
         }
 
         public void addChild(ViewTree child) {
+            addChild(child, INSERT_AT_END_INDEX);
+        }
+
+        /**
+         * Adds the given {@link ViewTree} as a child at the given index.
+         *
+         * @param index The position at which to add the child or -1 to add last.
+         */
+        public void addChild(ViewTree child, int index) {
             if (mChildren == null) {
                 mChildren = new ArrayList<>();
             }
             child.createTree();
-            mChildren.add(child);
+
+            if (index == INSERT_AT_END_INDEX) {
+                mChildren.add(child);
+                return;
+            }
+
+            mChildren.add(index, child);
         }
 
         private void addViewChild(View v) {
diff --git a/core/java/android/widget/TextInputTimePickerView.java b/core/java/android/widget/TextInputTimePickerView.java
index 11b7514d..0cf8faa 100644
--- a/core/java/android/widget/TextInputTimePickerView.java
+++ b/core/java/android/widget/TextInputTimePickerView.java
@@ -17,6 +17,7 @@
 package android.widget;
 
 import android.content.Context;
+import android.os.LocaleList;
 import android.text.Editable;
 import android.text.InputFilter;
 import android.text.TextWatcher;
@@ -141,6 +142,9 @@
                 new InputFilter.LengthFilter(maxCharLength)});
         mMinuteEditText.setFilters(new InputFilter[] {
                 new InputFilter.LengthFilter(maxCharLength)});
+        final LocaleList locales = mContext.getResources().getConfiguration().getLocales();
+        mHourEditText.setImeHintLocales(locales);
+        mMinuteEditText.setImeHintLocales(locales);
     }
 
     boolean validateInput() {
diff --git a/core/java/com/android/internal/alsa/AlsaCardsParser.java b/core/java/com/android/internal/alsa/AlsaCardsParser.java
index 17e8c9c..5b92a17 100644
--- a/core/java/com/android/internal/alsa/AlsaCardsParser.java
+++ b/core/java/com/android/internal/alsa/AlsaCardsParser.java
@@ -49,7 +49,7 @@
 
         public AlsaCardRecord() {}
 
-        public boolean parse(String line, int lineIndex) {
+        private boolean parse(String line, int lineIndex) {
             int tokenIndex = 0;
             int delimIndex = 0;
 
@@ -258,7 +258,7 @@
     //
     // Logging
     //
-    public void Log(String heading) {
+    private void Log(String heading) {
         if (DEBUG) {
             Slog.i(TAG, heading);
             for (AlsaCardRecord cardRec : mCardRecords) {
@@ -267,7 +267,7 @@
         }
     }
 
-    static public void LogDevices(String caption, ArrayList<AlsaCardRecord> deviceList) {
+    static private void LogDevices(String caption, ArrayList<AlsaCardRecord> deviceList) {
         Slog.d(TAG, caption + " ----------------");
         int listIndex = 0;
         for (AlsaCardRecord device : deviceList) {
diff --git a/core/java/com/android/internal/alsa/AlsaDevicesParser.java b/core/java/com/android/internal/alsa/AlsaDevicesParser.java
index 5203723..7cdd897 100644
--- a/core/java/com/android/internal/alsa/AlsaDevicesParser.java
+++ b/core/java/com/android/internal/alsa/AlsaDevicesParser.java
@@ -155,6 +155,7 @@
 
             switch (mDeviceType) {
             case kDeviceType_Unknown:
+            default:
                 sb.append(" N/A");
                 break;
             case kDeviceType_Audio:
@@ -170,6 +171,7 @@
 
             switch (mDeviceDir) {
             case kDeviceDir_Unknown:
+            default:
                 sb.append(" N/A");
                 break;
             case kDeviceDir_Capture:
@@ -282,7 +284,7 @@
     //
     // Loging
     //
-    public void Log(String heading) {
+    private void Log(String heading) {
         if (DEBUG) {
             Slog.i(TAG, heading);
             for (AlsaDeviceRecord deviceRecord : mDeviceRecords) {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index ece4981..54afc95 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -69,7 +69,10 @@
 import android.view.animation.Interpolator;
 import android.widget.AbsListView;
 import android.widget.BaseAdapter;
+import android.widget.LinearLayout;
 import android.widget.ListView;
+import android.widget.Space;
+
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.ResolverActivity.TargetInfo;
@@ -1412,6 +1415,10 @@
                 } else {
                     lp.height = v.getMeasuredHeight();
                 }
+                if (i != (mColumnCount - 1)) {
+                    row.addView(new Space(ChooserActivity.this),
+                            new LinearLayout.LayoutParams(0, 0, 1));
+                }
             }
 
             // Pre-measure so we can scale later.
@@ -1439,13 +1446,34 @@
             if (startType == ChooserListAdapter.TARGET_SERVICE) {
                 holder.row.setBackgroundColor(
                         getColor(R.color.chooser_service_row_background_color));
+                int nextStartType = mChooserListAdapter.getPositionTargetType(
+                        getFirstRowPosition(rowPosition + 1));
+                int serviceSpacing = holder.row.getContext().getResources()
+                        .getDimensionPixelSize(R.dimen.chooser_service_spacing);
+                int top = rowPosition == 0 ? serviceSpacing : 0;
+                if (nextStartType != ChooserListAdapter.TARGET_SERVICE) {
+                    setVertPadding(holder, top, serviceSpacing);
+                } else {
+                    setVertPadding(holder, top, 0);
+                }
             } else {
                 holder.row.setBackgroundColor(Color.TRANSPARENT);
+                int lastStartType = mChooserListAdapter.getPositionTargetType(
+                        getFirstRowPosition(rowPosition - 1));
+                if (lastStartType == ChooserListAdapter.TARGET_SERVICE || rowPosition == 0) {
+                    int serviceSpacing = holder.row.getContext().getResources()
+                            .getDimensionPixelSize(R.dimen.chooser_service_spacing);
+                    setVertPadding(holder, serviceSpacing, 0);
+                } else {
+                    setVertPadding(holder, 0, 0);
+                }
             }
 
             final int oldHeight = holder.row.getLayoutParams().height;
+            int measuredRowHeight = holder.measuredRowHeight + holder.row.getPaddingTop()
+                    + holder.row.getPaddingBottom();
             holder.row.getLayoutParams().height = Math.max(1,
-                    (int) (holder.measuredRowHeight * getRowScale(rowPosition)));
+                    (int) (measuredRowHeight * getRowScale(rowPosition)));
             if (holder.row.getLayoutParams().height != oldHeight) {
                 holder.row.requestLayout();
             }
@@ -1457,11 +1485,16 @@
                     holder.itemIndices[i] = start + i;
                     mChooserListAdapter.bindView(holder.itemIndices[i], v);
                 } else {
-                    v.setVisibility(View.GONE);
+                    v.setVisibility(View.INVISIBLE);
                 }
             }
         }
 
+        private void setVertPadding(RowViewHolder holder, int top, int bottom) {
+            holder.row.setPadding(holder.row.getPaddingLeft(), top,
+                    holder.row.getPaddingRight(), bottom);
+        }
+
         int getFirstRowPosition(int row) {
             final int callerCount = mChooserListAdapter.getCallerTargetCount();
             final int callerRows = (int) Math.ceil((float) callerCount / mColumnCount);
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 35d4ba8..7a119b4 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -48,4 +48,6 @@
     void setUserRestrictions(in Bundle restrictions, IBinder token, int userHandle);
     void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, in String[] exceptionPackages);
     void removeUser(int userHandle);
+
+    boolean isOperationActive(int code, int uid, String packageName);
 }
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 04f7c76..a44fd67 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -130,7 +130,7 @@
     long getAwakeTimePlugged();
 
     void noteBleScanStarted(in WorkSource ws, boolean isUnoptimized);
-    void noteBleScanStopped(in WorkSource ws);
+    void noteBleScanStopped(in WorkSource ws, boolean isUnoptimized);
     void noteResetBleScan();
     void noteBleScanResults(in WorkSource ws, int numNewResults);
 
diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl
index 81ea191..36e4c1c6 100644
--- a/core/java/com/android/internal/app/IMediaContainerService.aidl
+++ b/core/java/com/android/internal/app/IMediaContainerService.aidl
@@ -27,9 +27,6 @@
 
     PackageInfoLite getMinimalPackageInfo(String packagePath, int flags, String abiOverride);
     ObbInfo getObbInfo(String filename);
-    long calculateDirectorySize(String directory);
-    /** Return file system stats: [0] is total bytes, [1] is available bytes */
-    long[] getFileSystemStats(String path);
     void clearDirectory(String directory);
     long calculateInstalledSize(String packagePath, boolean isForwardLocked, String abiOverride);
 }
diff --git a/core/java/com/android/internal/app/ISoundTriggerService.aidl b/core/java/com/android/internal/app/ISoundTriggerService.aidl
index f4c18c3..1bee692 100644
--- a/core/java/com/android/internal/app/ISoundTriggerService.aidl
+++ b/core/java/com/android/internal/app/ISoundTriggerService.aidl
@@ -16,6 +16,7 @@
 
 package com.android.internal.app;
 
+import android.app.PendingIntent;
 import android.hardware.soundtrigger.IRecognitionStatusCallback;
 import android.hardware.soundtrigger.SoundTrigger;
 import android.os.ParcelUuid;
@@ -26,7 +27,6 @@
  */
 interface ISoundTriggerService {
 
-
     SoundTrigger.GenericSoundModel getSoundModel(in ParcelUuid soundModelId);
 
     void updateSoundModel(in SoundTrigger.GenericSoundModel soundModel);
@@ -36,8 +36,17 @@
     int startRecognition(in ParcelUuid soundModelId, in IRecognitionStatusCallback callback,
          in SoundTrigger.RecognitionConfig config);
 
-    /**
-     * Stops recognition.
-     */
     int stopRecognition(in ParcelUuid soundModelId, in IRecognitionStatusCallback callback);
+
+    int loadGenericSoundModel(in SoundTrigger.GenericSoundModel soundModel);
+    int loadKeyphraseSoundModel(in SoundTrigger.KeyphraseSoundModel soundModel);
+
+    int startRecognitionForIntent(in ParcelUuid soundModelId, in PendingIntent callbackIntent,
+         in SoundTrigger.RecognitionConfig config);
+
+    int stopRecognitionForIntent(in ParcelUuid soundModelId);
+
+    int unloadSoundModel(in ParcelUuid soundModelId);
+
+    boolean isRecognitionActive(in ParcelUuid parcelUuid);
 }
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 0b27c60..398d087 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -16,16 +16,14 @@
 
 package com.android.internal.app;
 
-import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
-
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.admin.DevicePolicyManager;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -34,8 +32,12 @@
 import android.util.Slog;
 import android.widget.Toast;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.util.List;
 
+import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
+
 /**
  * This is used in conjunction with
  * {@link DevicePolicyManager#addCrossProfileIntentFilter} to enable intents to
@@ -51,15 +53,17 @@
     public static String FORWARD_INTENT_TO_MANAGED_PROFILE
             = "com.android.internal.app.ForwardIntentToManagedProfile";
 
+    private Injector mInjector;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        Intent intentReceived = getIntent();
+        mInjector = createInjector();
 
+        Intent intentReceived = getIntent();
         String className = intentReceived.getComponent().getClassName();
         final int targetUserId;
         final int userMessageId;
-
         if (className.equals(FORWARD_INTENT_TO_PARENT)) {
             userMessageId = com.android.internal.R.string.forward_intent_to_owner;
             targetUserId = getProfileParent();
@@ -76,17 +80,12 @@
             finish();
             return;
         }
-        Intent newIntent = new Intent(intentReceived);
-        newIntent.setComponent(null);
-        // Apps should not be allowed to target a specific package in the target user.
-        newIntent.setPackage(null);
-        newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
-                |Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
-        int callingUserId = getUserId();
 
-        if (canForward(newIntent, targetUserId)) {
+        final int callingUserId = getUserId();
+        final Intent newIntent = canForward(intentReceived, targetUserId);
+        if (newIntent != null) {
             if (Intent.ACTION_CHOOSER.equals(newIntent.getAction())) {
-                Intent innerIntent = (Intent) newIntent.getParcelableExtra(Intent.EXTRA_INTENT);
+                Intent innerIntent = newIntent.getParcelableExtra(Intent.EXTRA_INTENT);
                 // At this point, innerIntent is not null. Otherwise, canForward would have returned
                 // false.
                 innerIntent.prepareToLeaveUser(callingUserId);
@@ -94,15 +93,18 @@
                 newIntent.prepareToLeaveUser(callingUserId);
             }
 
-            final android.content.pm.ResolveInfo ri = getPackageManager().resolveActivityAsUser(
-                        newIntent, MATCH_DEFAULT_ONLY, targetUserId);
+            final android.content.pm.ResolveInfo ri =
+                    mInjector.getPackageManager().resolveActivityAsUser(
+                            newIntent,
+                            MATCH_DEFAULT_ONLY,
+                            targetUserId);
 
             // Don't show the disclosure if next activity is ResolverActivity or ChooserActivity
             // as those will already have shown work / personal as neccesary etc.
             final boolean shouldShowDisclosure = ri == null || ri.activityInfo == null ||
                     !"android".equals(ri.activityInfo.packageName) ||
                     !(ResolverActivity.class.getName().equals(ri.activityInfo.name)
-                    || ChooserActivity.class.getName().equals(ri.activityInfo.name));
+                            || ChooserActivity.class.getName().equals(ri.activityInfo.name));
 
             try {
                 startActivityAsCaller(newIntent, null, false, targetUserId);
@@ -126,44 +128,56 @@
                 Toast.makeText(this, getString(userMessageId), Toast.LENGTH_LONG).show();
             }
         } else {
-            Slog.wtf(TAG, "the intent: " + newIntent + " cannot be forwarded from user "
+            Slog.wtf(TAG, "the intent: " + intentReceived + " cannot be forwarded from user "
                     + callingUserId + " to user " + targetUserId);
         }
         finish();
     }
 
-    boolean canForward(Intent intent, int targetUserId)  {
-        IPackageManager ipm = AppGlobals.getPackageManager();
-        if (Intent.ACTION_CHOOSER.equals(intent.getAction())) {
+    /**
+     * Check whether the intent can be forwarded to target user. Return the intent used for
+     * forwarding if it can be forwarded, {@code null} otherwise.
+     */
+    Intent canForward(Intent incomingIntent, int targetUserId)  {
+        Intent forwardIntent = new Intent(incomingIntent);
+        forwardIntent.addFlags(
+                Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
+        sanitizeIntent(forwardIntent);
+
+        Intent intentToCheck = forwardIntent;
+        if (Intent.ACTION_CHOOSER.equals(forwardIntent.getAction())) {
             // The EXTRA_INITIAL_INTENTS may not be allowed to be forwarded.
-            if (intent.hasExtra(Intent.EXTRA_INITIAL_INTENTS)) {
+            if (forwardIntent.hasExtra(Intent.EXTRA_INITIAL_INTENTS)) {
                 Slog.wtf(TAG, "An chooser intent with extra initial intents cannot be forwarded to"
                         + " a different user");
-                return false;
+                return null;
             }
-            if (intent.hasExtra(Intent.EXTRA_REPLACEMENT_EXTRAS)) {
+            if (forwardIntent.hasExtra(Intent.EXTRA_REPLACEMENT_EXTRAS)) {
                 Slog.wtf(TAG, "A chooser intent with replacement extras cannot be forwarded to a"
                         + " different user");
-                return false;
+                return null;
             }
-            intent = (Intent) intent.getParcelableExtra(Intent.EXTRA_INTENT);
-            if (intent == null) {
+            intentToCheck = forwardIntent.getParcelableExtra(Intent.EXTRA_INTENT);
+            if (intentToCheck == null) {
                 Slog.wtf(TAG, "Cannot forward a chooser intent with no extra "
                         + Intent.EXTRA_INTENT);
-                return false;
+                return null;
             }
         }
-        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
-        if (intent.getSelector() != null) {
-            intent = intent.getSelector();
+        if (forwardIntent.getSelector() != null) {
+            intentToCheck = forwardIntent.getSelector();
         }
+        String resolvedType = intentToCheck.resolveTypeIfNeeded(getContentResolver());
+        sanitizeIntent(intentToCheck);
         try {
-            return ipm.canForwardTo(intent, resolvedType, getUserId(),
-                    targetUserId);
+            if (mInjector.getIPackageManager().
+                    canForwardTo(intentToCheck, resolvedType, getUserId(), targetUserId)) {
+                return forwardIntent;
+            }
         } catch (RemoteException e) {
             Slog.e(TAG, "PackageManagerService is dead?");
-            return false;
         }
+        return null;
     }
 
     /**
@@ -174,8 +188,7 @@
      * on the device.
      */
     private int getManagedProfile() {
-        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
-        List<UserInfo> relatedUsers = userManager.getProfiles(UserHandle.myUserId());
+        List<UserInfo> relatedUsers = mInjector.getUserManager().getProfiles(UserHandle.myUserId());
         for (UserInfo userInfo : relatedUsers) {
             if (userInfo.isManagedProfile()) return userInfo.id;
         }
@@ -189,8 +202,7 @@
      * no parent.
      */
     private int getProfileParent() {
-        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
-        UserInfo parent = userManager.getProfileParent(UserHandle.myUserId());
+        UserInfo parent = mInjector.getUserManager().getProfileParent(UserHandle.myUserId());
         if (parent == null) {
             Slog.wtf(TAG, FORWARD_INTENT_TO_PARENT
                     + " has been called, but there is no parent");
@@ -198,4 +210,44 @@
         }
         return parent.id;
     }
+
+    /**
+     * Sanitize the intent in place.
+     */
+    private void sanitizeIntent(Intent intent) {
+        // Apps should not be allowed to target a specific package/ component in the target user.
+        intent.setPackage(null);
+        intent.setComponent(null);
+    }
+
+    @VisibleForTesting
+    protected Injector createInjector() {
+        return new InjectorImpl();
+    }
+
+    private class InjectorImpl implements Injector {
+
+        @Override
+        public IPackageManager getIPackageManager() {
+            return AppGlobals.getPackageManager();
+        }
+
+        @Override
+        public UserManager getUserManager() {
+            return getSystemService(UserManager.class);
+        }
+
+        @Override
+        public PackageManager getPackageManager() {
+            return IntentForwarderActivity.this.getPackageManager();
+        }
+    }
+
+    public interface Injector {
+        IPackageManager getIPackageManager();
+
+        UserManager getUserManager();
+
+        PackageManager getPackageManager();
+    }
 }
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialog.java b/core/java/com/android/internal/app/MediaRouteChooserDialog.java
index 47d2a9c..7108d14 100644
--- a/core/java/com/android/internal/app/MediaRouteChooserDialog.java
+++ b/core/java/com/android/internal/app/MediaRouteChooserDialog.java
@@ -24,6 +24,7 @@
 import android.media.MediaRouter.RouteInfo;
 import android.os.Bundle;
 import android.text.TextUtils;
+import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -130,7 +131,8 @@
 
         // Must be called after setContentView.
         getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
-                R.drawable.ic_media_route_off_holo_dark);
+                isLightTheme(getContext()) ? R.drawable.ic_media_route_off_holo_light
+                    : R.drawable.ic_media_route_off_holo_dark);
 
         mAdapter = new RouteAdapter(getContext());
         mListView = (ListView)findViewById(R.id.media_route_list);
@@ -176,6 +178,12 @@
         }
     }
 
+    static boolean isLightTheme(Context context) {
+        TypedValue value = new TypedValue();
+        return context.getTheme().resolveAttribute(R.attr.isLightTheme, value, true)
+                && value.data != 0;
+    }
+
     private final class RouteAdapter extends ArrayAdapter<MediaRouter.RouteInfo>
             implements ListView.OnItemClickListener {
         private final LayoutInflater mInflater;
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
index 237feed..3cbc9ea 100644
--- a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
+++ b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
@@ -43,8 +43,12 @@
      * </p>
      */
     public MediaRouteChooserDialogFragment() {
+        int theme = MediaRouteChooserDialog.isLightTheme(getContext())
+                ? android.R.style.Theme_DeviceDefault_Light_Dialog
+                : android.R.style.Theme_DeviceDefault_Dialog;
+
         setCancelable(true);
-        setStyle(STYLE_NORMAL, android.R.style.Theme_DeviceDefault_Dialog);
+        setStyle(STYLE_NORMAL, theme);
     }
 
     public int getRouteTypes() {
diff --git a/core/java/com/android/internal/app/MediaRouteControllerDialog.java b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
index 5ce3e54..635a868 100644
--- a/core/java/com/android/internal/app/MediaRouteControllerDialog.java
+++ b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
@@ -142,7 +142,11 @@
                     @Override
                     public void onClick(DialogInterface dialogInterface, int id) {
                         if (mRoute.isSelected()) {
-                            mRouter.getDefaultRoute().select();
+                            if (mRoute.isBluetooth()) {
+                                mRouter.getDefaultRoute().select();
+                            } else {
+                                mRouter.getFallbackRoute().select();
+                            }
                         }
                         dismiss();
                     }
diff --git a/core/java/com/android/internal/app/MediaRouteDialogPresenter.java b/core/java/com/android/internal/app/MediaRouteDialogPresenter.java
index fad7fd4..bb2d7fa 100644
--- a/core/java/com/android/internal/app/MediaRouteDialogPresenter.java
+++ b/core/java/com/android/internal/app/MediaRouteDialogPresenter.java
@@ -71,16 +71,18 @@
         final MediaRouter router = (MediaRouter)context.getSystemService(
                 Context.MEDIA_ROUTER_SERVICE);
 
+        int theme = MediaRouteChooserDialog.isLightTheme(context)
+                ? android.R.style.Theme_DeviceDefault_Light_Dialog
+                : android.R.style.Theme_DeviceDefault_Dialog;
+
         MediaRouter.RouteInfo route = router.getSelectedRoute();
         if (route.isDefault() || !route.matchesTypes(routeTypes)) {
-            final MediaRouteChooserDialog d = new MediaRouteChooserDialog(
-                    context, android.R.style.Theme_DeviceDefault_Dialog);
+            final MediaRouteChooserDialog d = new MediaRouteChooserDialog(context, theme);
             d.setRouteTypes(routeTypes);
             d.setExtendedSettingsClickListener(extendedSettingsClickListener);
             return d;
         } else {
-            MediaRouteControllerDialog d = new MediaRouteControllerDialog(
-                    context, android.R.style.Theme_DeviceDefault_Dialog);
+            MediaRouteControllerDialog d = new MediaRouteControllerDialog(context, theme);
             return d;
         }
     }
diff --git a/core/java/com/android/internal/app/NightDisplayController.java b/core/java/com/android/internal/app/NightDisplayController.java
index bb54085..860c5c4 100644
--- a/core/java/com/android/internal/app/NightDisplayController.java
+++ b/core/java/com/android/internal/app/NightDisplayController.java
@@ -182,6 +182,10 @@
             throw new IllegalArgumentException("Invalid autoMode: " + autoMode);
         }
 
+        if (getAutoMode() != autoMode) {
+            Secure.putLongForUser(mContext.getContentResolver(),
+                    Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, -1L, mUserId);
+        }
         return Secure.putIntForUser(mContext.getContentResolver(),
                 Secure.NIGHT_DISPLAY_AUTO_MODE, autoMode, mUserId);
     }
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 9c6f1d0..5c1bafd 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1681,7 +1681,14 @@
         // We assume that at this point we've already filtered out the only intent for a different
         // targetUserId which we're going to use.
         private void addResolveInfo(DisplayResolveInfo dri) {
-            if (dri.mResolveInfo.targetUserId == UserHandle.USER_CURRENT) {
+            if (dri != null && dri.mResolveInfo != null
+                    && dri.mResolveInfo.targetUserId == UserHandle.USER_CURRENT) {
+                // Checks if this info is already listed in display.
+                for (DisplayResolveInfo existingInfo : mDisplayList) {
+                    if (resolveInfoMatch(dri.mResolveInfo, existingInfo.mResolveInfo)) {
+                        return;
+                    }
+                }
                 mDisplayList.add(dri);
             }
         }
diff --git a/core/java/com/android/internal/app/ResolverComparator.java b/core/java/com/android/internal/app/ResolverComparator.java
index 54b9cd8..a0f58a9 100644
--- a/core/java/com/android/internal/app/ResolverComparator.java
+++ b/core/java/com/android/internal/app/ResolverComparator.java
@@ -553,7 +553,9 @@
                 Log.e(TAG, "Error in Predict: " + e);
             }
         }
-        mAfterCompute.afterCompute();
+        if (mAfterCompute != null) {
+            mAfterCompute.afterCompute();
+        }
     }
 
     // adds select prob as the default values, according to a pre-trained Logistic Regression model.
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 5ab17e44..2ab2d20 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -30,6 +30,7 @@
 import android.content.pm.ResolveInfo;
 import android.os.RemoteException;
 import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.lang.InterruptedException;
@@ -55,7 +56,11 @@
     private static final String TAG = "ResolverListController";
     private static final boolean DEBUG = false;
 
+    Object mLock = new Object();
+
+    @GuardedBy("mLock")
     private ResolverComparator mResolverComparator;
+    private boolean isComputed = false;
 
     public ResolverListController(
             Context context,
@@ -68,6 +73,10 @@
         mLaunchedFromUid = launchedFromUid;
         mTargetIntent = targetIntent;
         mReferrerPackage = referrerPackage;
+        synchronized (mLock) {
+            mResolverComparator =
+                    new ResolverComparator(mContext, mTargetIntent, mReferrerPackage, null);
+        }
     }
 
     @VisibleForTesting
@@ -232,25 +241,29 @@
     @VisibleForTesting
     @WorkerThread
     public void sort(List<ResolverActivity.ResolvedComponentInfo> inputList) {
-        final CountDownLatch finishComputeSignal = new CountDownLatch(1);
-        ComputeCallback callback = new ComputeCallback(finishComputeSignal);
-        if (mResolverComparator == null) {
-            mResolverComparator =
-                    new ResolverComparator(mContext, mTargetIntent, mReferrerPackage, callback);
-        } else {
-            mResolverComparator.setCallBack(callback);
-        }
-        try {
-            long beforeRank = System.currentTimeMillis();
-            mResolverComparator.compute(inputList);
-            finishComputeSignal.await();
-            Collections.sort(inputList, mResolverComparator);
-            long afterRank = System.currentTimeMillis();
-            if (DEBUG) {
-                Log.d(TAG, "Time Cost: " + Long.toString(afterRank - beforeRank));
+        synchronized (mLock) {
+            if (mResolverComparator == null) {
+                Log.d(TAG, "Comparator has already been destroyed; skipped.");
+                return;
             }
-        } catch (InterruptedException e) {
-            Log.e(TAG, "Compute & Sort was interrupted: " + e);
+            final CountDownLatch finishComputeSignal = new CountDownLatch(1);
+            ComputeCallback callback = new ComputeCallback(finishComputeSignal);
+            mResolverComparator.setCallBack(callback);
+            try {
+                long beforeRank = System.currentTimeMillis();
+                if (!isComputed) {
+                    mResolverComparator.compute(inputList);
+                    finishComputeSignal.await();
+                    isComputed = true;
+                }
+                Collections.sort(inputList, mResolverComparator);
+                long afterRank = System.currentTimeMillis();
+                if (DEBUG) {
+                    Log.d(TAG, "Time Cost: " + Long.toString(afterRank - beforeRank));
+                }
+            } catch (InterruptedException e) {
+                Log.e(TAG, "Compute & Sort was interrupted: " + e);
+            }
         }
     }
 
@@ -271,27 +284,36 @@
 
     @VisibleForTesting
     public float getScore(ResolverActivity.DisplayResolveInfo target) {
-        if (mResolverComparator == null) {
-            return 0.0f;
+        synchronized (mLock) {
+            if (mResolverComparator == null) {
+                return 0.0f;
+            }
+            return mResolverComparator.getScore(target.getResolvedComponentName());
         }
-        return mResolverComparator.getScore(target.getResolvedComponentName());
     }
 
     public void updateModel(ComponentName componentName) {
-        if (mResolverComparator != null) {
-            mResolverComparator.updateModel(componentName);
+        synchronized (mLock) {
+            if (mResolverComparator != null) {
+                mResolverComparator.updateModel(componentName);
+            }
         }
     }
 
     public void updateChooserCounts(String packageName, int userId, String action) {
-        if (mResolverComparator != null) {
-            mResolverComparator.updateChooserCounts(packageName, userId, action);
+        synchronized (mLock) {
+            if (mResolverComparator != null) {
+                mResolverComparator.updateChooserCounts(packageName, userId, action);
+            }
         }
     }
 
     public void destroy() {
-        if (mResolverComparator != null) {
-            mResolverComparator.destroy();
+        synchronized (mLock) {
+            if (mResolverComparator != null) {
+                mResolverComparator.destroy();
+            }
+            mResolverComparator = null;
         }
     }
 }
diff --git a/core/java/com/android/internal/backup/package.html b/core/java/com/android/internal/backup/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/backup/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/car/ICarServiceHelper.aidl b/core/java/com/android/internal/car/ICarServiceHelper.aidl
new file mode 100644
index 0000000..9ee330b
--- /dev/null
+++ b/core/java/com/android/internal/car/ICarServiceHelper.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.car;
+
+/**
+ * Helper API for car service. Only for itneraction between system server and car service.
+ * @hide
+ */
+interface ICarServiceHelper {
+}
diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java
new file mode 100644
index 0000000..ef98a5e9
--- /dev/null
+++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.internal.colorextraction;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.colorextraction.types.ExtractionType;
+import com.android.internal.colorextraction.types.Tonal;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * Class to process wallpaper colors and generate a tonal palette based on them.
+ */
+public class ColorExtractor implements WallpaperManager.OnColorsChangedListener {
+
+    public static final int TYPE_NORMAL = 0;
+    public static final int TYPE_DARK = 1;
+    public static final int TYPE_EXTRA_DARK = 2;
+    private static final int[] sGradientTypes = new int[]{TYPE_NORMAL, TYPE_DARK, TYPE_EXTRA_DARK};
+
+    private static final String TAG = "ColorExtractor";
+    private static final boolean DEBUG = false;
+
+    protected final SparseArray<GradientColors[]> mGradientColors;
+    private final ArrayList<WeakReference<OnColorsChangedListener>> mOnColorsChangedListeners;
+    private final Context mContext;
+    private final ExtractionType mExtractionType;
+    protected WallpaperColors mSystemColors;
+    protected WallpaperColors mLockColors;
+
+    public ColorExtractor(Context context) {
+        this(context, new Tonal(context));
+    }
+
+    @VisibleForTesting
+    public ColorExtractor(Context context, ExtractionType extractionType) {
+        mContext = context;
+        mExtractionType = extractionType;
+
+        mGradientColors = new SparseArray<>();
+        for (int which : new int[] { WallpaperManager.FLAG_LOCK, WallpaperManager.FLAG_SYSTEM}) {
+            GradientColors[] colors = new GradientColors[sGradientTypes.length];
+            mGradientColors.append(which, colors);
+            for (int type : sGradientTypes) {
+                colors[type] = new GradientColors();
+            }
+        }
+
+        mOnColorsChangedListeners = new ArrayList<>();
+        GradientColors[] systemColors = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
+        GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK);
+
+        WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class);
+        if (wallpaperManager == null) {
+            Log.w(TAG, "Can't listen to color changes!");
+        } else {
+            wallpaperManager.addOnColorsChangedListener(this);
+
+            // Initialize all gradients with the current colors
+            Trace.beginSection("ColorExtractor#getWallpaperColors");
+            mSystemColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+            mLockColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_LOCK);
+            Trace.endSection();
+        }
+
+        // Initialize all gradients with the current colors
+        extractInto(mSystemColors,
+                systemColors[TYPE_NORMAL],
+                systemColors[TYPE_DARK],
+                systemColors[TYPE_EXTRA_DARK]);
+        extractInto(mLockColors,
+                lockColors[TYPE_NORMAL],
+                lockColors[TYPE_DARK],
+                lockColors[TYPE_EXTRA_DARK]);
+    }
+
+    /**
+     * Retrieve gradient colors for a specific wallpaper.
+     *
+     * @param which FLAG_LOCK or FLAG_SYSTEM
+     * @return colors
+     */
+    @NonNull
+    public GradientColors getColors(int which) {
+        return getColors(which, TYPE_DARK);
+    }
+
+    /**
+     * Get current gradient colors for one of the possible gradient types
+     *
+     * @param which FLAG_LOCK or FLAG_SYSTEM
+     * @param type TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK
+     * @return colors
+     */
+    @NonNull
+    public GradientColors getColors(int which, int type) {
+        if (type != TYPE_NORMAL && type != TYPE_DARK && type != TYPE_EXTRA_DARK) {
+            throw new IllegalArgumentException(
+                    "type should be TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK");
+        }
+        if (which != WallpaperManager.FLAG_LOCK && which != WallpaperManager.FLAG_SYSTEM) {
+            throw new IllegalArgumentException("which should be FLAG_SYSTEM or FLAG_NORMAL");
+        }
+        return mGradientColors.get(which)[type];
+    }
+
+    /**
+     * Get the last available WallpaperColors without forcing new extraction.
+     *
+     * @param which FLAG_LOCK or FLAG_SYSTEM
+     * @return Last cached colors
+     */
+    @Nullable
+    public WallpaperColors getWallpaperColors(int which) {
+        if (which == WallpaperManager.FLAG_LOCK) {
+            return mLockColors;
+        } else if (which == WallpaperManager.FLAG_SYSTEM) {
+            return mSystemColors;
+        } else {
+            throw new IllegalArgumentException("Invalid value for which: " + which);
+        }
+    }
+
+    @Override
+    public void onColorsChanged(WallpaperColors colors, int which) {
+        if (DEBUG) {
+            Log.d(TAG, "New wallpaper colors for " + which + ": " + colors);
+        }
+        boolean changed = false;
+        if ((which & WallpaperManager.FLAG_LOCK) != 0) {
+            mLockColors = colors;
+            GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK);
+            extractInto(colors, lockColors[TYPE_NORMAL], lockColors[TYPE_DARK],
+                    lockColors[TYPE_EXTRA_DARK]);
+            changed = true;
+        }
+        if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
+            mSystemColors = colors;
+            GradientColors[] systemColors = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
+            extractInto(colors, systemColors[TYPE_NORMAL], systemColors[TYPE_DARK],
+                    systemColors[TYPE_EXTRA_DARK]);
+            changed = true;
+        }
+
+        if (changed) {
+            triggerColorsChanged(which);
+        }
+    }
+
+    protected void triggerColorsChanged(int which) {
+        ArrayList<WeakReference<OnColorsChangedListener>> references =
+                new ArrayList<>(mOnColorsChangedListeners);
+        final int size = references.size();
+        for (int i = 0; i < size; i++) {
+            final WeakReference<OnColorsChangedListener> weakReference = references.get(i);
+            final OnColorsChangedListener listener = weakReference.get();
+            if (listener == null) {
+                mOnColorsChangedListeners.remove(weakReference);
+            } else {
+                listener.onColorsChanged(this, which);
+            }
+        }
+    }
+
+    private void extractInto(WallpaperColors inWallpaperColors,
+            GradientColors outGradientColorsNormal, GradientColors outGradientColorsDark,
+            GradientColors outGradientColorsExtraDark) {
+        mExtractionType.extractInto(inWallpaperColors, outGradientColorsNormal,
+                outGradientColorsDark, outGradientColorsExtraDark);
+    }
+
+    public void destroy() {
+        WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class);
+        if (wallpaperManager != null) {
+            wallpaperManager.removeOnColorsChangedListener(this);
+        }
+    }
+
+    public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener) {
+        mOnColorsChangedListeners.add(new WeakReference<>(listener));
+    }
+
+    public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener listener) {
+        ArrayList<WeakReference<OnColorsChangedListener>> references =
+                new ArrayList<>(mOnColorsChangedListeners);
+        final int size = references.size();
+        for (int i = 0; i < size; i++) {
+            final WeakReference<OnColorsChangedListener> weakReference = references.get(i);
+            if (weakReference.get() == listener) {
+                mOnColorsChangedListeners.remove(weakReference);
+                break;
+            }
+        }
+    }
+
+    public static class GradientColors {
+        private int mMainColor;
+        private int mSecondaryColor;
+        private boolean mSupportsDarkText;
+
+        public void setMainColor(int mainColor) {
+            mMainColor = mainColor;
+        }
+
+        public void setSecondaryColor(int secondaryColor) {
+            mSecondaryColor = secondaryColor;
+        }
+
+        public void setSupportsDarkText(boolean supportsDarkText) {
+            mSupportsDarkText = supportsDarkText;
+        }
+
+        public void set(GradientColors other) {
+            mMainColor = other.mMainColor;
+            mSecondaryColor = other.mSecondaryColor;
+            mSupportsDarkText = other.mSupportsDarkText;
+        }
+
+        public int getMainColor() {
+            return mMainColor;
+        }
+
+        public int getSecondaryColor() {
+            return mSecondaryColor;
+        }
+
+        public boolean supportsDarkText() {
+            return mSupportsDarkText;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == null || o.getClass() != getClass()) {
+                return false;
+            }
+            GradientColors other = (GradientColors) o;
+            return other.mMainColor == mMainColor &&
+                    other.mSecondaryColor == mSecondaryColor &&
+                    other.mSupportsDarkText == mSupportsDarkText;
+        }
+
+        @Override
+        public int hashCode() {
+            int code = mMainColor;
+            code = 31 * code + mSecondaryColor;
+            code = 31 * code + (mSupportsDarkText ? 0 : 1);
+            return code;
+        }
+
+        @Override
+        public String toString() {
+            return "GradientColors(" + Integer.toHexString(mMainColor) + ", "
+                    + Integer.toHexString(mSecondaryColor) + ")";
+        }
+    }
+
+    public interface OnColorsChangedListener {
+        void onColorsChanged(ColorExtractor colorExtractor, int which);
+    }
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/colorextraction/drawable/GradientDrawable.java b/core/java/com/android/internal/colorextraction/drawable/GradientDrawable.java
new file mode 100644
index 0000000..500c028
--- /dev/null
+++ b/core/java/com/android/internal/colorextraction/drawable/GradientDrawable.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.internal.colorextraction.drawable;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.RadialGradient;
+import android.graphics.Rect;
+import android.graphics.Shader;
+import android.graphics.Xfermode;
+import android.graphics.drawable.Drawable;
+import android.view.animation.DecelerateInterpolator;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.graphics.ColorUtils;
+
+/**
+ * Draws a gradient based on a Palette
+ */
+public class GradientDrawable extends Drawable {
+    private static final String TAG = "GradientDrawable";
+
+    private static final float CENTRALIZED_CIRCLE_1 = -2;
+    private static final int GRADIENT_RADIUS = 480; // in dp
+    private static final long COLOR_ANIMATION_DURATION = 2000;
+
+    private int mAlpha = 255;
+
+    private float mDensity;
+    private final Paint mPaint;
+    private final Rect mWindowBounds;
+    private final Splat mSplat;
+
+    private int mMainColor;
+    private int mSecondaryColor;
+    private ValueAnimator mColorAnimation;
+
+    public GradientDrawable(@NonNull Context context) {
+        mDensity = context.getResources().getDisplayMetrics().density;
+        mSplat = new Splat(0.50f, 1.00f, GRADIENT_RADIUS, CENTRALIZED_CIRCLE_1);
+        mWindowBounds = new Rect();
+
+        mPaint = new Paint();
+        mPaint.setStyle(Paint.Style.FILL);
+    }
+
+    public void setColors(@NonNull ColorExtractor.GradientColors colors) {
+        setColors(colors.getMainColor(), colors.getSecondaryColor(), true);
+    }
+
+    public void setColors(@NonNull ColorExtractor.GradientColors colors, boolean animated) {
+        setColors(colors.getMainColor(), colors.getSecondaryColor(), animated);
+    }
+
+    public void setColors(int mainColor, int secondaryColor, boolean animated) {
+        if (mainColor == mMainColor && secondaryColor == mSecondaryColor) {
+            return;
+        }
+
+        if (mColorAnimation != null && mColorAnimation.isRunning()) {
+            mColorAnimation.cancel();
+        }
+
+        if (animated) {
+            final int mainFrom = mMainColor;
+            final int secFrom = mSecondaryColor;
+
+            ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+            anim.setDuration(COLOR_ANIMATION_DURATION);
+            anim.addUpdateListener(animation -> {
+                float ratio = (float) animation.getAnimatedValue();
+                mMainColor = ColorUtils.blendARGB(mainFrom, mainColor, ratio);
+                mSecondaryColor = ColorUtils.blendARGB(secFrom, secondaryColor, ratio);
+                buildPaints();
+                invalidateSelf();
+            });
+            anim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation, boolean isReverse) {
+                    if (mColorAnimation == animation) {
+                        mColorAnimation = null;
+                    }
+                }
+            });
+            anim.setInterpolator(new DecelerateInterpolator());
+            anim.start();
+            mColorAnimation = anim;
+        } else {
+            mMainColor = mainColor;
+            mSecondaryColor = secondaryColor;
+            buildPaints();
+            invalidateSelf();
+        }
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        if (alpha != mAlpha) {
+            mAlpha = alpha;
+            mPaint.setAlpha(mAlpha);
+            invalidateSelf();
+        }
+    }
+
+    @Override
+    public int getAlpha() {
+        return mAlpha;
+    }
+
+    @Override
+    public void setXfermode(@Nullable Xfermode mode) {
+        mPaint.setXfermode(mode);
+        invalidateSelf();
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter colorFilter) {
+        mPaint.setColorFilter(colorFilter);
+    }
+
+    @Override
+    public ColorFilter getColorFilter() {
+        return mPaint.getColorFilter();
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.TRANSLUCENT;
+    }
+
+    public void setScreenSize(int width, int height) {
+        mWindowBounds.set(0, 0, width, height);
+        setBounds(0, 0, width, height);
+        buildPaints();
+    }
+
+    private void buildPaints() {
+        Rect bounds = mWindowBounds;
+        if (bounds.width() == 0) {
+            return;
+        }
+
+        float w = bounds.width();
+        float h = bounds.height();
+
+        float x = mSplat.x * w;
+        float y = mSplat.y * h;
+
+        float radius = mSplat.radius * mDensity;
+
+        // When we have only a single alpha gradient, we increase quality
+        // (avoiding banding) by merging the background solid color into
+        // the gradient directly
+        RadialGradient radialGradient = new RadialGradient(x, y, radius,
+                mSecondaryColor, mMainColor, Shader.TileMode.CLAMP);
+        mPaint.setShader(radialGradient);
+    }
+
+    @Override
+    public void draw(@NonNull Canvas canvas) {
+        Rect bounds = mWindowBounds;
+        if (bounds.width() == 0) {
+            throw new IllegalStateException("You need to call setScreenSize before drawing.");
+        }
+
+        // Splat each gradient
+        float w = bounds.width();
+        float h = bounds.height();
+
+        float x = mSplat.x * w;
+        float y = mSplat.y * h;
+
+        float radius = Math.max(w, h);
+        canvas.drawRect(x - radius, y - radius, x + radius, y + radius, mPaint);
+    }
+
+    @VisibleForTesting
+    public int getMainColor() {
+        return mMainColor;
+    }
+
+    @VisibleForTesting
+    public int getSecondaryColor() {
+        return mSecondaryColor;
+    }
+
+    static final class Splat {
+        final float x;
+        final float y;
+        final float radius;
+        final float colorIndex;
+
+        Splat(float x, float y, float radius, float colorIndex) {
+            this.x = x;
+            this.y = y;
+            this.radius = radius;
+            this.colorIndex = colorIndex;
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/colorextraction/types/ExtractionType.java b/core/java/com/android/internal/colorextraction/types/ExtractionType.java
new file mode 100644
index 0000000..7000e79
--- /dev/null
+++ b/core/java/com/android/internal/colorextraction/types/ExtractionType.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.internal.colorextraction.types;
+
+import android.app.WallpaperColors;
+
+import com.android.internal.colorextraction.ColorExtractor;
+
+/**
+ * Interface to allow various color extraction implementations.
+ */
+public interface ExtractionType {
+
+    /**
+     * Executes color extraction by reading WallpaperColors and setting
+     * main and secondary colors on GradientColors.
+     *
+     * Extraction is expected to happen with 3 different gradient types:
+     *     Normal, with the main extracted colors
+     *     Dark, with extra contrast
+     *     ExtraDark, for places where GAR is mandatory, like the emergency dialer
+     *
+     * @param inWallpaperColors where to read from
+     * @param outGradientColorsNormal object that should receive normal colors
+     * @param outGradientColorsDark object that should receive dark colors
+     * @param outGradientColorsExtraDark object that should receive extra dark colors
+     */
+    void extractInto(WallpaperColors inWallpaperColors,
+            ColorExtractor.GradientColors outGradientColorsNormal,
+            ColorExtractor.GradientColors outGradientColorsDark,
+            ColorExtractor.GradientColors outGradientColorsExtraDark);
+}
diff --git a/core/java/com/android/internal/colorextraction/types/Tonal.java b/core/java/com/android/internal/colorextraction/types/Tonal.java
new file mode 100644
index 0000000..dbc086c
--- /dev/null
+++ b/core/java/com/android/internal/colorextraction/types/Tonal.java
@@ -0,0 +1,600 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.internal.colorextraction.types;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.WallpaperColors;
+import android.content.Context;
+import android.graphics.Color;
+import android.util.Log;
+import android.util.MathUtils;
+import android.util.Range;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.graphics.ColorUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Implementation of tonal color extraction
+ */
+public class Tonal implements ExtractionType {
+    private static final String TAG = "Tonal";
+
+    // Used for tonal palette fitting
+    private static final float FIT_WEIGHT_H = 1.0f;
+    private static final float FIT_WEIGHT_S = 1.0f;
+    private static final float FIT_WEIGHT_L = 10.0f;
+
+    private static final boolean DEBUG = true;
+
+    public static final int MAIN_COLOR_LIGHT = 0xffe0e0e0;
+    public static final int SECONDARY_COLOR_LIGHT = 0xff9e9e9e;
+    public static final int MAIN_COLOR_DARK = 0xff212121;
+    public static final int SECONDARY_COLOR_DARK = 0xff000000;
+
+    private final TonalPalette mGreyPalette;
+    private final ArrayList<TonalPalette> mTonalPalettes;
+    private final ArrayList<ColorRange> mBlacklistedColors;
+
+    // Temporary variable to avoid allocations
+    private float[] mTmpHSL = new float[3];
+
+    public Tonal(Context context) {
+
+        ConfigParser parser = new ConfigParser(context);
+        mTonalPalettes = parser.getTonalPalettes();
+        mBlacklistedColors = parser.getBlacklistedColors();
+
+        mGreyPalette = mTonalPalettes.get(0);
+        mTonalPalettes.remove(0);
+    }
+
+    /**
+     * Grab colors from WallpaperColors and set them into GradientColors.
+     * Also applies the default gradient in case extraction fails.
+     *
+     * @param inWallpaperColors Input.
+     * @param outColorsNormal Colors for normal theme.
+     * @param outColorsDark Colors for dar theme.
+     * @param outColorsExtraDark Colors for extra dark theme.
+     */
+    public void extractInto(@Nullable WallpaperColors inWallpaperColors,
+            @NonNull GradientColors outColorsNormal, @NonNull GradientColors outColorsDark,
+            @NonNull GradientColors outColorsExtraDark) {
+        boolean success = runTonalExtraction(inWallpaperColors, outColorsNormal, outColorsDark,
+                outColorsExtraDark);
+        if (!success) {
+            applyFallback(inWallpaperColors, outColorsNormal, outColorsDark, outColorsExtraDark);
+        }
+    }
+
+    /**
+     * Grab colors from WallpaperColors and set them into GradientColors.
+     *
+     * @param inWallpaperColors Input.
+     * @param outColorsNormal Colors for normal theme.
+     * @param outColorsDark Colors for dar theme.
+     * @param outColorsExtraDark Colors for extra dark theme.
+     * @return True if succeeded or false if failed.
+     */
+    private boolean runTonalExtraction(@Nullable WallpaperColors inWallpaperColors,
+            @NonNull GradientColors outColorsNormal, @NonNull GradientColors outColorsDark,
+            @NonNull GradientColors outColorsExtraDark) {
+
+        if (inWallpaperColors == null) {
+            return false;
+        }
+
+        final List<Color> mainColors = inWallpaperColors.getMainColors();
+        final int mainColorsSize = mainColors.size();
+        final boolean supportsDarkText = (inWallpaperColors.getColorHints() &
+                WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
+
+        if (mainColorsSize == 0) {
+            return false;
+        }
+        // Tonal is not really a sort, it takes a color from the extracted
+        // palette and finds a best fit amongst a collection of pre-defined
+        // palettes. The best fit is tweaked to be closer to the source color
+        // and replaces the original palette
+
+        // Get the most preeminent, non-blacklisted color.
+        Color bestColor = null;
+        final float[] hsl = new float[3];
+        for (int i = 0; i < mainColorsSize; i++) {
+            final Color color = mainColors.get(i);
+            final int colorValue = color.toArgb();
+            ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue),
+                    Color.blue(colorValue), hsl);
+
+            // Stop when we find a color that meets our criteria
+            if (!isBlacklisted(hsl)) {
+                bestColor = color;
+                break;
+            }
+        }
+
+        // Fail if not found
+        if (bestColor == null) {
+            return false;
+        }
+
+        int colorValue = bestColor.toArgb();
+        ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue), Color.blue(colorValue),
+                hsl);
+
+        // The Android HSL definition requires the hue to go from 0 to 360 but
+        // the Material Tonal Palette defines hues from 0 to 1.
+        hsl[0] /= 360f;
+
+        // Find the palette that contains the closest color
+        TonalPalette palette = findTonalPalette(hsl[0], hsl[1]);
+        if (palette == null) {
+            Log.w(TAG, "Could not find a tonal palette!");
+            return false;
+        }
+
+        // Figure out what's the main color index in the optimal palette
+        int fitIndex = bestFit(palette, hsl[0], hsl[1], hsl[2]);
+        if (fitIndex == -1) {
+            Log.w(TAG, "Could not find best fit!");
+            return false;
+        }
+
+        // Generate the 10 colors palette by offsetting each one of them
+        float[] h = fit(palette.h, hsl[0], fitIndex,
+                Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY);
+        float[] s = fit(palette.s, hsl[1], fitIndex, 0.0f, 1.0f);
+        float[] l = fit(palette.l, hsl[2], fitIndex, 0.0f, 1.0f);
+
+        if (DEBUG) {
+            StringBuilder builder = new StringBuilder("Tonal Palette - index: " + fitIndex +
+                    ". Main color: " + Integer.toHexString(getColorInt(fitIndex, h, s, l)) +
+                    "\nColors: ");
+
+            for (int i=0; i < h.length; i++) {
+                builder.append(Integer.toHexString(getColorInt(i, h, s, l)));
+                if (i < h.length - 1) {
+                    builder.append(", ");
+                }
+            }
+            Log.d(TAG, builder.toString());
+        }
+
+        int primaryIndex = fitIndex;
+        int mainColor = getColorInt(primaryIndex, h, s, l);
+
+        // We might want use the fallback in case the extracted color is brighter than our
+        // light fallback or darker than our dark fallback.
+        ColorUtils.colorToHSL(mainColor, mTmpHSL);
+        final float mainLuminosity = mTmpHSL[2];
+        ColorUtils.colorToHSL(MAIN_COLOR_LIGHT, mTmpHSL);
+        final float lightLuminosity = mTmpHSL[2];
+        if (mainLuminosity > lightLuminosity) {
+            return false;
+        }
+        ColorUtils.colorToHSL(MAIN_COLOR_DARK, mTmpHSL);
+        final float darkLuminosity = mTmpHSL[2];
+        if (mainLuminosity < darkLuminosity) {
+            return false;
+        }
+
+        // Normal colors:
+        // best fit + a 2 colors offset
+        outColorsNormal.setMainColor(mainColor);
+        int secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2);
+        outColorsNormal.setSecondaryColor(getColorInt(secondaryIndex, h, s, l));
+
+        // Dark colors:
+        // Stops at 4th color, only lighter if dark text is supported
+        if (supportsDarkText) {
+            primaryIndex = h.length - 1;
+        } else if (fitIndex < 2) {
+            primaryIndex = 0;
+        } else {
+            primaryIndex = Math.min(fitIndex, 3);
+        }
+        secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2);
+        outColorsDark.setMainColor(getColorInt(primaryIndex, h, s, l));
+        outColorsDark.setSecondaryColor(getColorInt(secondaryIndex, h, s, l));
+
+        // Extra Dark:
+        // Stay close to dark colors until dark text is supported
+        if (supportsDarkText) {
+            primaryIndex = h.length - 1;
+        } else if (fitIndex < 2) {
+            primaryIndex = 0;
+        } else {
+            primaryIndex = 2;
+        }
+        secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2);
+        outColorsExtraDark.setMainColor(getColorInt(primaryIndex, h, s, l));
+        outColorsExtraDark.setSecondaryColor(getColorInt(secondaryIndex, h, s, l));
+
+        outColorsNormal.setSupportsDarkText(supportsDarkText);
+        outColorsDark.setSupportsDarkText(supportsDarkText);
+        outColorsExtraDark.setSupportsDarkText(supportsDarkText);
+
+        if (DEBUG) {
+            Log.d(TAG, "Gradients: \n\tNormal " + outColorsNormal + "\n\tDark " + outColorsDark
+                    + "\n\tExtra dark: " + outColorsExtraDark);
+        }
+
+        return true;
+    }
+
+    private void applyFallback(@Nullable WallpaperColors inWallpaperColors,
+            GradientColors outColorsNormal, GradientColors outColorsDark,
+            GradientColors outColorsExtraDark) {
+        applyFallback(inWallpaperColors, outColorsNormal);
+        applyFallback(inWallpaperColors, outColorsDark);
+        applyFallback(inWallpaperColors, outColorsExtraDark);
+    }
+
+    /**
+     * Sets the gradient to the light or dark fallbacks based on the current wallpaper colors.
+     *
+     * @param inWallpaperColors Colors to read.
+     * @param outGradientColors Destination.
+     */
+    public static void applyFallback(@Nullable WallpaperColors inWallpaperColors,
+            @NonNull GradientColors outGradientColors) {
+        boolean light = inWallpaperColors != null
+                && (inWallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT)
+                != 0;
+        int innerColor = light ? MAIN_COLOR_LIGHT : MAIN_COLOR_DARK;
+        int outerColor = light ? SECONDARY_COLOR_LIGHT : SECONDARY_COLOR_DARK;
+
+        outGradientColors.setMainColor(innerColor);
+        outGradientColors.setSecondaryColor(outerColor);
+        outGradientColors.setSupportsDarkText(light);
+    }
+
+    private int getColorInt(int fitIndex, float[] h, float[] s, float[] l) {
+        mTmpHSL[0] = fract(h[fitIndex]) * 360.0f;
+        mTmpHSL[1] = s[fitIndex];
+        mTmpHSL[2] = l[fitIndex];
+        return ColorUtils.HSLToColor(mTmpHSL);
+    }
+
+    /**
+     * Checks if a given color exists in the blacklist
+     * @param hsl float array with 3 components (H 0..360, S 0..1 and L 0..1)
+     * @return true if color should be avoided
+     */
+    private boolean isBlacklisted(float[] hsl) {
+        for (int i = mBlacklistedColors.size() - 1; i >= 0; i--) {
+            ColorRange badRange = mBlacklistedColors.get(i);
+            if (badRange.containsColor(hsl[0], hsl[1], hsl[2])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Offsets all colors by a delta, clamping values that go beyond what's
+     * supported on the color space.
+     * @param data what you want to fit
+     * @param v how big should be the offset
+     * @param index which index to calculate the delta against
+     * @param min minimum accepted value (clamp)
+     * @param max maximum accepted value (clamp)
+     * @return new shifted palette
+     */
+    private static float[] fit(float[] data, float v, int index, float min, float max) {
+        float[] fitData = new float[data.length];
+        float delta = v - data[index];
+
+        for (int i = 0; i < data.length; i++) {
+            fitData[i] = MathUtils.constrain(data[i] + delta, min, max);
+        }
+
+        return fitData;
+    }
+
+    /**
+     * Finds the closest color in a palette, given another HSL color
+     *
+     * @param palette where to search
+     * @param h hue
+     * @param s saturation
+     * @param l lightness
+     * @return closest index or -1 if palette is empty.
+     */
+    private static int bestFit(@NonNull TonalPalette palette, float h, float s, float l) {
+        int minErrorIndex = -1;
+        float minError = Float.POSITIVE_INFINITY;
+
+        for (int i = 0; i < palette.h.length; i++) {
+            float error =
+                    FIT_WEIGHT_H * Math.abs(h - palette.h[i])
+                            + FIT_WEIGHT_S * Math.abs(s - palette.s[i])
+                            + FIT_WEIGHT_L * Math.abs(l - palette.l[i]);
+            if (error < minError) {
+                minError = error;
+                minErrorIndex = i;
+            }
+        }
+
+        return minErrorIndex;
+    }
+
+    @VisibleForTesting
+    public List<ColorRange> getBlacklistedColors() {
+        return mBlacklistedColors;
+    }
+
+    @Nullable
+    private TonalPalette findTonalPalette(float h, float s) {
+        // Fallback to a grey palette if the color is too desaturated.
+        // This avoids hue shifts.
+        if (s < 0.05f) {
+            return mGreyPalette;
+        }
+
+        TonalPalette best = null;
+        float error = Float.POSITIVE_INFINITY;
+
+        final int tonalPalettesCount = mTonalPalettes.size();
+        for (int i = 0; i < tonalPalettesCount; i++) {
+            final TonalPalette candidate = mTonalPalettes.get(i);
+
+            if (h >= candidate.minHue && h <= candidate.maxHue) {
+                best = candidate;
+                break;
+            }
+
+            if (candidate.maxHue > 1.0f && h >= 0.0f && h <= fract(candidate.maxHue)) {
+                best = candidate;
+                break;
+            }
+
+            if (candidate.minHue < 0.0f && h >= fract(candidate.minHue) && h <= 1.0f) {
+                best = candidate;
+                break;
+            }
+
+            if (h <= candidate.minHue && candidate.minHue - h < error) {
+                best = candidate;
+                error = candidate.minHue - h;
+            } else if (h >= candidate.maxHue && h - candidate.maxHue < error) {
+                best = candidate;
+                error = h - candidate.maxHue;
+            } else if (candidate.maxHue > 1.0f && h >= fract(candidate.maxHue)
+                    && h - fract(candidate.maxHue) < error) {
+                best = candidate;
+                error = h - fract(candidate.maxHue);
+            } else if (candidate.minHue < 0.0f && h <= fract(candidate.minHue)
+                    && fract(candidate.minHue) - h < error) {
+                best = candidate;
+                error = fract(candidate.minHue) - h;
+            }
+        }
+
+        return best;
+    }
+
+    private static float fract(float v) {
+        return v - (float) Math.floor(v);
+    }
+
+    static class TonalPalette {
+        final float[] h;
+        final float[] s;
+        final float[] l;
+        final float minHue;
+        final float maxHue;
+
+        TonalPalette(float[] h, float[] s, float[] l) {
+            if (h.length != s.length || s.length != l.length) {
+                throw new IllegalArgumentException("All arrays should have the same size. h: "
+                        + Arrays.toString(h) + " s: " + Arrays.toString(s) + " l: "
+                        + Arrays.toString(l));
+            }
+            this.h = h;
+            this.s = s;
+            this.l = l;
+
+            float minHue = Float.POSITIVE_INFINITY;
+            float maxHue = Float.NEGATIVE_INFINITY;
+
+            for (float v : h) {
+                minHue = Math.min(v, minHue);
+                maxHue = Math.max(v, maxHue);
+            }
+
+            this.minHue = minHue;
+            this.maxHue = maxHue;
+        }
+    }
+
+    /**
+     * Representation of an HSL color range.
+     * <ul>
+     * <li>hsl[0] is Hue [0 .. 360)</li>
+     * <li>hsl[1] is Saturation [0...1]</li>
+     * <li>hsl[2] is Lightness [0...1]</li>
+     * </ul>
+     */
+    @VisibleForTesting
+    public static class ColorRange {
+        private Range<Float> mHue;
+        private Range<Float> mSaturation;
+        private Range<Float> mLightness;
+
+        public ColorRange(Range<Float> hue, Range<Float> saturation, Range<Float> lightness) {
+            mHue = hue;
+            mSaturation = saturation;
+            mLightness = lightness;
+        }
+
+        public boolean containsColor(float h, float s, float l) {
+            if (!mHue.contains(h)) {
+                return false;
+            } else if (!mSaturation.contains(s)) {
+                return false;
+            } else if (!mLightness.contains(l)) {
+                return false;
+            }
+            return true;
+        }
+
+        public float[] getCenter() {
+            return new float[] {
+                    mHue.getLower() + (mHue.getUpper() - mHue.getLower()) / 2f,
+                    mSaturation.getLower() + (mSaturation.getUpper() - mSaturation.getLower()) / 2f,
+                    mLightness.getLower() + (mLightness.getUpper() - mLightness.getLower()) / 2f
+            };
+        }
+
+        @Override
+        public String toString() {
+            return String.format("H: %s, S: %s, L %s", mHue, mSaturation, mLightness);
+        }
+    }
+
+    @VisibleForTesting
+    public static class ConfigParser {
+        private final ArrayList<TonalPalette> mTonalPalettes;
+        private final ArrayList<ColorRange> mBlacklistedColors;
+
+        public ConfigParser(Context context) {
+            mTonalPalettes = new ArrayList<>();
+            mBlacklistedColors = new ArrayList<>();
+
+            // Load all palettes and the blacklist from an XML.
+            try {
+                XmlPullParser parser = context.getResources().getXml(R.xml.color_extraction);
+                int eventType = parser.getEventType();
+                while (eventType != XmlPullParser.END_DOCUMENT) {
+                    if (eventType == XmlPullParser.START_DOCUMENT ||
+                            eventType == XmlPullParser.END_TAG) {
+                        // just skip
+                    } else if (eventType == XmlPullParser.START_TAG) {
+                        String tagName = parser.getName();
+                        if (tagName.equals("palettes")) {
+                            parsePalettes(parser);
+                        } else if (tagName.equals("blacklist")) {
+                            parseBlacklist(parser);
+                        }
+                    } else {
+                        throw new XmlPullParserException("Invalid XML event " + eventType + " - "
+                                + parser.getName(), parser, null);
+                    }
+                    eventType = parser.next();
+                }
+            } catch (XmlPullParserException | IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public ArrayList<TonalPalette> getTonalPalettes() {
+            return mTonalPalettes;
+        }
+
+        public ArrayList<ColorRange> getBlacklistedColors() {
+            return mBlacklistedColors;
+        }
+
+        private void parseBlacklist(XmlPullParser parser)
+                throws XmlPullParserException, IOException {
+            parser.require(XmlPullParser.START_TAG, null, "blacklist");
+            while (parser.next() != XmlPullParser.END_TAG) {
+                if (parser.getEventType() != XmlPullParser.START_TAG) {
+                    continue;
+                }
+                String name = parser.getName();
+                // Starts by looking for the entry tag
+                if (name.equals("range")) {
+                    mBlacklistedColors.add(readRange(parser));
+                    parser.next();
+                } else {
+                    throw new XmlPullParserException("Invalid tag: " + name, parser, null);
+                }
+            }
+        }
+
+        private ColorRange readRange(XmlPullParser parser)
+                throws XmlPullParserException, IOException {
+            parser.require(XmlPullParser.START_TAG, null, "range");
+            float[] h = readFloatArray(parser.getAttributeValue(null, "h"));
+            float[] s = readFloatArray(parser.getAttributeValue(null, "s"));
+            float[] l = readFloatArray(parser.getAttributeValue(null, "l"));
+
+            if (h == null || s == null || l == null) {
+                throw new XmlPullParserException("Incomplete range tag.", parser, null);
+            }
+
+            return new ColorRange(new Range<>(h[0], h[1]), new Range<>(s[0], s[1]),
+                    new Range<>(l[0], l[1]));
+        }
+
+        private void parsePalettes(XmlPullParser parser)
+                throws XmlPullParserException, IOException {
+            parser.require(XmlPullParser.START_TAG, null, "palettes");
+            while (parser.next() != XmlPullParser.END_TAG) {
+                if (parser.getEventType() != XmlPullParser.START_TAG) {
+                    continue;
+                }
+                String name = parser.getName();
+                // Starts by looking for the entry tag
+                if (name.equals("palette")) {
+                    mTonalPalettes.add(readPalette(parser));
+                    parser.next();
+                } else {
+                    throw new XmlPullParserException("Invalid tag: " + name);
+                }
+            }
+        }
+
+        private TonalPalette readPalette(XmlPullParser parser)
+                throws XmlPullParserException, IOException {
+            parser.require(XmlPullParser.START_TAG, null, "palette");
+
+            float[] h = readFloatArray(parser.getAttributeValue(null, "h"));
+            float[] s = readFloatArray(parser.getAttributeValue(null, "s"));
+            float[] l = readFloatArray(parser.getAttributeValue(null, "l"));
+
+            if (h == null || s == null || l == null) {
+                throw new XmlPullParserException("Incomplete range tag.", parser, null);
+            }
+
+            return new TonalPalette(h, s, l);
+        }
+
+        private float[] readFloatArray(String attributeValue)
+                throws IOException, XmlPullParserException {
+            String[] tokens = attributeValue.replaceAll(" ", "").replaceAll("\n", "").split(",");
+            float[] numbers = new float[tokens.length];
+            for (int i = 0; i < tokens.length; i++) {
+                numbers[i] = Float.parseFloat(tokens[i]);
+            }
+            return numbers;
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index 79544df..ebea1a4 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -27,6 +27,7 @@
 import android.database.MatrixCursor.RowBuilder;
 import android.graphics.Point;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.CancellationSignal;
 import android.os.FileObserver;
 import android.os.FileUtils;
@@ -156,11 +157,17 @@
         if (visibleFolder != null) {
             assert (visibleFolder.isDirectory());
 
-            final ContentResolver resolver = getContext().getContentResolver();
-            final Uri uri = MediaStore.Files.getDirectoryUri("external");
-            ContentValues values = new ContentValues();
-            values.put(MediaStore.Files.FileColumns.DATA, visibleFolder.getAbsolutePath());
-            resolver.insert(uri, values);
+            final long token = Binder.clearCallingIdentity();
+
+            try {
+                final ContentResolver resolver = getContext().getContentResolver();
+                final Uri uri = MediaStore.Files.getDirectoryUri("external");
+                ContentValues values = new ContentValues();
+                values.put(MediaStore.Files.FileColumns.DATA, visibleFolder.getAbsolutePath());
+                resolver.insert(uri, values);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
     }
 
@@ -214,22 +221,28 @@
         // They should be all null or not null at the same time. File#renameTo() doesn't work across
         // volumes so an exception will be thrown before calling this method.
         if (oldVisibleFile != null && newVisibleFile != null) {
-            final ContentResolver resolver = getContext().getContentResolver();
-            final Uri externalUri = newVisibleFile.isDirectory()
-                    ? MediaStore.Files.getDirectoryUri("external")
-                    : MediaStore.Files.getContentUri("external");
+            final long token = Binder.clearCallingIdentity();
 
-            ContentValues values = new ContentValues();
-            values.put(MediaStore.Files.FileColumns.DATA, newVisibleFile.getAbsolutePath());
+            try {
+                final ContentResolver resolver = getContext().getContentResolver();
+                final Uri externalUri = newVisibleFile.isDirectory()
+                        ? MediaStore.Files.getDirectoryUri("external")
+                        : MediaStore.Files.getContentUri("external");
 
-            // Logic borrowed from MtpDatabase.
-            // note - we are relying on a special case in MediaProvider.update() to update
-            // the paths for all children in the case where this is a directory.
-            final String path = oldVisibleFile.getAbsolutePath();
-            resolver.update(externalUri,
-                    values,
-                    "_data LIKE ? AND lower(_data)=lower(?)",
-                    new String[] { path, path });
+                ContentValues values = new ContentValues();
+                values.put(MediaStore.Files.FileColumns.DATA, newVisibleFile.getAbsolutePath());
+
+                // Logic borrowed from MtpDatabase.
+                // note - we are relying on a special case in MediaProvider.update() to update
+                // the paths for all children in the case where this is a directory.
+                final String path = oldVisibleFile.getAbsolutePath();
+                resolver.update(externalUri,
+                        values,
+                        "_data LIKE ? AND lower(_data)=lower(?)",
+                        new String[]{path, path});
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
     }
 
@@ -253,23 +266,29 @@
             throws FileNotFoundException {
         // visibleFolder is null if we're removing a document from external thumb drive or SD card.
         if (visibleFile != null) {
-            final ContentResolver resolver = getContext().getContentResolver();
-            final Uri externalUri = MediaStore.Files.getContentUri("external");
+            final long token = Binder.clearCallingIdentity();
 
-            // Remove media store entries for any files inside this directory, using
-            // path prefix match. Logic borrowed from MtpDatabase.
-            if (isFolder) {
-                final String path = visibleFile.getAbsolutePath() + "/";
+            try {
+                final ContentResolver resolver = getContext().getContentResolver();
+                final Uri externalUri = MediaStore.Files.getContentUri("external");
+
+                // Remove media store entries for any files inside this directory, using
+                // path prefix match. Logic borrowed from MtpDatabase.
+                if (isFolder) {
+                    final String path = visibleFile.getAbsolutePath() + "/";
+                    resolver.delete(externalUri,
+                            "_data LIKE ?1 AND lower(substr(_data,1,?2))=lower(?3)",
+                            new String[]{path + "%", Integer.toString(path.length()), path});
+                }
+
+                // Remove media store entry for this exact file.
+                final String path = visibleFile.getAbsolutePath();
                 resolver.delete(externalUri,
-                        "_data LIKE ?1 AND lower(substr(_data,1,?2))=lower(?3)",
-                        new String[] { path + "%", Integer.toString(path.length()), path });
+                        "_data LIKE ?1 AND lower(_data)=lower(?2)",
+                        new String[]{path, path});
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
-
-            // Remove media store entry for this exact file.
-            final String path = visibleFile.getAbsolutePath();
-            resolver.delete(externalUri,
-                    "_data LIKE ?1 AND lower(_data)=lower(?2)",
-                    new String[] { path, path });
         }
     }
 
diff --git a/core/java/com/android/internal/graphics/ColorUtils.java b/core/java/com/android/internal/graphics/ColorUtils.java
index 6c1efa4..8b2a2dc 100644
--- a/core/java/com/android/internal/graphics/ColorUtils.java
+++ b/core/java/com/android/internal/graphics/ColorUtils.java
@@ -106,6 +106,31 @@
     }
 
     /**
+     * Calculates the minimum alpha value which can be applied to {@code background} so that would
+     * have a contrast value of at least {@code minContrastRatio} when alpha blended to
+     * {@code foreground}.
+     *
+     * @param foreground       the foreground color
+     * @param background       the background color, opacity will be ignored
+     * @param minContrastRatio the minimum contrast ratio
+     * @return the alpha value in the range 0-255, or -1 if no value could be calculated
+     */
+    public static int calculateMinimumBackgroundAlpha(@ColorInt int foreground,
+            @ColorInt int background, float minContrastRatio) {
+        // Ignore initial alpha that the background might have since this is
+        // what we're trying to calculate.
+        background = setAlphaComponent(background, 255);
+        final int leastContrastyColor = setAlphaComponent(foreground, 255);
+        return binaryAlphaSearch(foreground, background, minContrastRatio, (fg, bg, alpha) -> {
+            int testBackground = blendARGB(leastContrastyColor, bg, alpha/255f);
+            // Float rounding might set this alpha to something other that 255,
+            // raising an exception in calculateContrast.
+            testBackground = setAlphaComponent(testBackground, 255);
+            return calculateContrast(fg, testBackground);
+        });
+    }
+
+    /**
      * Calculates the minimum alpha value which can be applied to {@code foreground} so that would
      * have a contrast value of at least {@code minContrastRatio} when compared to
      * {@code background}.
@@ -122,14 +147,33 @@
                     + Integer.toHexString(background));
         }
 
+        ContrastCalculator contrastCalculator = (fg, bg, alpha) -> {
+            int testForeground = setAlphaComponent(fg, alpha);
+            return calculateContrast(testForeground, bg);
+        };
+
         // First lets check that a fully opaque foreground has sufficient contrast
-        int testForeground = setAlphaComponent(foreground, 255);
-        double testRatio = calculateContrast(testForeground, background);
+        double testRatio = contrastCalculator.calculateContrast(foreground, background, 255);
         if (testRatio < minContrastRatio) {
             // Fully opaque foreground does not have sufficient contrast, return error
             return -1;
         }
+        foreground = setAlphaComponent(foreground, 255);
+        return binaryAlphaSearch(foreground, background, minContrastRatio, contrastCalculator);
+    }
 
+    /**
+     * Calculates the alpha value using binary search based on a given contrast evaluation function
+     * and target contrast that needs to be satisfied.
+     *
+     * @param foreground         the foreground color
+     * @param background         the opaque background color
+     * @param minContrastRatio   the minimum contrast ratio
+     * @param calculator function that calculates contrast
+     * @return the alpha value in the range 0-255, or -1 if no value could be calculated
+     */
+    private static int binaryAlphaSearch(@ColorInt int foreground, @ColorInt int background,
+            float minContrastRatio, ContrastCalculator calculator) {
         // Binary search to find a value with the minimum value which provides sufficient contrast
         int numIterations = 0;
         int minAlpha = 0;
@@ -139,9 +183,8 @@
                 (maxAlpha - minAlpha) > MIN_ALPHA_SEARCH_PRECISION) {
             final int testAlpha = (minAlpha + maxAlpha) / 2;
 
-            testForeground = setAlphaComponent(foreground, testAlpha);
-            testRatio = calculateContrast(testForeground, background);
-
+            final double testRatio = calculator.calculateContrast(foreground, background,
+                    testAlpha);
             if (testRatio < minContrastRatio) {
                 minAlpha = testAlpha;
             } else {
@@ -615,4 +658,8 @@
         return result;
     }
 
+    private interface ContrastCalculator {
+        double calculateContrast(int foreground, int background, int alpha);
+    }
+
 }
\ No newline at end of file
diff --git a/core/java/com/android/internal/graphics/palette/ColorCutQuantizer.java b/core/java/com/android/internal/graphics/palette/ColorCutQuantizer.java
index 2d0ad66..9ac753b 100644
--- a/core/java/com/android/internal/graphics/palette/ColorCutQuantizer.java
+++ b/core/java/com/android/internal/graphics/palette/ColorCutQuantizer.java
@@ -61,7 +61,7 @@
  * This means that the color space is divided into distinct colors, rather than representative
  * colors.
  */
-final class ColorCutQuantizer {
+final class ColorCutQuantizer implements Quantizer {
 
     private static final String LOG_TAG = "ColorCutQuantizer";
     private static final boolean LOG_TIMINGS = false;
@@ -73,22 +73,22 @@
     private static final int QUANTIZE_WORD_WIDTH = 5;
     private static final int QUANTIZE_WORD_MASK = (1 << QUANTIZE_WORD_WIDTH) - 1;
 
-    final int[] mColors;
-    final int[] mHistogram;
-    final List<Swatch> mQuantizedColors;
-    final TimingLogger mTimingLogger;
-    final Palette.Filter[] mFilters;
+    int[] mColors;
+    int[] mHistogram;
+    List<Swatch> mQuantizedColors;
+    TimingLogger mTimingLogger;
+    Palette.Filter[] mFilters;
 
     private final float[] mTempHsl = new float[3];
 
     /**
-     * Constructor.
+     * Execute color quantization.
      *
      * @param pixels histogram representing an image's pixel data
      * @param maxColors The maximum number of colors that should be in the result palette.
      * @param filters Set of filters to use in the quantization stage
      */
-    ColorCutQuantizer(final int[] pixels, final int maxColors, final Palette.Filter[] filters) {
+    public void quantize(final int[] pixels, final int maxColors, final Palette.Filter[] filters) {
         mTimingLogger = LOG_TIMINGS ? new TimingLogger(LOG_TAG, "Creation") : null;
         mFilters = filters;
 
@@ -160,7 +160,7 @@
     /**
      * @return the list of quantized colors
      */
-    List<Swatch> getQuantizedColors() {
+    public List<Swatch> getQuantizedColors() {
         return mQuantizedColors;
     }
 
@@ -376,7 +376,9 @@
             for (int i = mLowerIndex, count = 0; i <= mUpperIndex; i++)  {
                 count += hist[colors[i]];
                 if (count >= midPoint) {
-                    return i;
+                    // we never want to split on the upperIndex, as this will result in the same
+                    // box
+                    return Math.min(mUpperIndex - 1, i);
                 }
             }
 
diff --git a/core/java/com/android/internal/graphics/palette/Palette.java b/core/java/com/android/internal/graphics/palette/Palette.java
index 9f1504a..a4f9a59 100644
--- a/core/java/com/android/internal/graphics/palette/Palette.java
+++ b/core/java/com/android/internal/graphics/palette/Palette.java
@@ -613,6 +613,8 @@
         private final List<Palette.Filter> mFilters = new ArrayList<>();
         private Rect mRegion;
 
+        private Quantizer mQuantizer;
+
         /**
          * Construct a new {@link Palette.Builder} using a source {@link Bitmap}
          */
@@ -726,6 +728,18 @@
         }
 
         /**
+         * Set a specific quantization algorithm. {@link ColorCutQuantizer} will
+         * be used if unspecified.
+         *
+         * @param quantizer Quantizer implementation.
+         */
+        @NonNull
+        public Palette.Builder setQuantizer(Quantizer quantizer) {
+            mQuantizer = quantizer;
+            return this;
+        }
+
+        /**
          * Set a region of the bitmap to be used exclusively when calculating the palette.
          * <p>This only works when the original input is a {@link Bitmap}.</p>
          *
@@ -818,17 +832,19 @@
                 }
 
                 // Now generate a quantizer from the Bitmap
-                final ColorCutQuantizer quantizer = new ColorCutQuantizer(
-                        getPixelsFromBitmap(bitmap),
-                        mMaxColors,
-                        mFilters.isEmpty() ? null : mFilters.toArray(new Palette.Filter[mFilters.size()]));
+                if (mQuantizer == null) {
+                    mQuantizer = new ColorCutQuantizer();
+                }
+                mQuantizer.quantize(getPixelsFromBitmap(bitmap),
+                            mMaxColors, mFilters.isEmpty() ? null :
+                            mFilters.toArray(new Palette.Filter[mFilters.size()]));
 
                 // If created a new bitmap, recycle it
                 if (bitmap != mBitmap) {
                     bitmap.recycle();
                 }
 
-                swatches = quantizer.getQuantizedColors();
+                swatches = mQuantizer.getQuantizedColors();
 
                 if (logger != null) {
                     logger.addSplit("Color quantization completed");
diff --git a/core/java/com/android/internal/graphics/palette/Quantizer.java b/core/java/com/android/internal/graphics/palette/Quantizer.java
new file mode 100644
index 0000000..db60f2e
--- /dev/null
+++ b/core/java/com/android/internal/graphics/palette/Quantizer.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.internal.graphics.palette;
+
+import java.util.List;
+
+/**
+ * Definition of an algorithm that receives pixels and outputs a list of colors.
+ */
+public interface Quantizer {
+    void quantize(final int[] pixels, final int maxColors, final Palette.Filter[] filters);
+    List<Palette.Swatch> getQuantizedColors();
+}
diff --git a/core/java/com/android/internal/graphics/palette/VariationalKMeansQuantizer.java b/core/java/com/android/internal/graphics/palette/VariationalKMeansQuantizer.java
new file mode 100644
index 0000000..b035535
--- /dev/null
+++ b/core/java/com/android/internal/graphics/palette/VariationalKMeansQuantizer.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.internal.graphics.palette;
+
+import android.util.Log;
+
+import com.android.internal.graphics.ColorUtils;
+import com.android.internal.ml.clustering.KMeans;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * A quantizer that uses k-means
+ */
+public class VariationalKMeansQuantizer implements Quantizer {
+
+    private static final String TAG = "KMeansQuantizer";
+    private static final boolean DEBUG = false;
+
+    /**
+     * Clusters closer than this value will me merged.
+     */
+    private final float mMinClusterSqDistance;
+
+    /**
+     * K-means can get stuck in local optima, this can be avoided by
+     * repeating it and getting the "best" execution.
+     */
+    private final int mInitializations;
+
+    /**
+     * Initialize KMeans with a fixed random state to have
+     * consistent results across multiple runs.
+     */
+    private final KMeans mKMeans = new KMeans(new Random(0), 30, 0);
+
+    private List<Palette.Swatch> mQuantizedColors;
+
+    public VariationalKMeansQuantizer() {
+        this(0.25f /* cluster distance */);
+    }
+
+    public VariationalKMeansQuantizer(float minClusterDistance) {
+        this(minClusterDistance, 1 /* initializations */);
+    }
+
+    public VariationalKMeansQuantizer(float minClusterDistance, int initializations) {
+        mMinClusterSqDistance = minClusterDistance * minClusterDistance;
+        mInitializations = initializations;
+    }
+
+    /**
+     * K-Means quantizer.
+     *
+     * @param pixels Pixels to quantize.
+     * @param maxColors Maximum number of clusters to extract.
+     * @param filters Colors that should be ignored
+     */
+    @Override
+    public void quantize(int[] pixels, int maxColors, Palette.Filter[] filters) {
+        // Start by converting all colors to HSL.
+        // HLS is way more meaningful for clustering than RGB.
+        final float[] hsl = {0, 0, 0};
+        final float[][] hslPixels = new float[pixels.length][3];
+        for (int i = 0; i < pixels.length; i++) {
+            ColorUtils.colorToHSL(pixels[i], hsl);
+            // Normalize hue so all values go from 0 to 1.
+            hslPixels[i][0] = hsl[0] / 360f;
+            hslPixels[i][1] = hsl[1];
+            hslPixels[i][2] = hsl[2];
+        }
+
+        final List<KMeans.Mean> optimalMeans = getOptimalKMeans(maxColors, hslPixels);
+
+        // Ideally we should run k-means again to merge clusters but it would be too expensive,
+        // instead we just merge all clusters that are closer than a threshold.
+        for (int i = 0; i < optimalMeans.size(); i++) {
+            KMeans.Mean current = optimalMeans.get(i);
+            float[] currentCentroid = current.getCentroid();
+            for (int j = i + 1; j < optimalMeans.size(); j++) {
+                KMeans.Mean compareTo = optimalMeans.get(j);
+                float[] compareToCentroid = compareTo.getCentroid();
+                float sqDistance = KMeans.sqDistance(currentCentroid, compareToCentroid);
+                // Merge them
+                if (sqDistance < mMinClusterSqDistance) {
+                    optimalMeans.remove(compareTo);
+                    current.getItems().addAll(compareTo.getItems());
+                    for (int k = 0; k < currentCentroid.length; k++) {
+                        currentCentroid[k] += (compareToCentroid[k] - currentCentroid[k]) / 2.0;
+                    }
+                    j--;
+                }
+            }
+        }
+
+        // Convert data to final format, de-normalizing the hue.
+        mQuantizedColors = new ArrayList<>();
+        for (KMeans.Mean mean : optimalMeans) {
+            if (mean.getItems().size() == 0) {
+                continue;
+            }
+            float[] centroid = mean.getCentroid();
+            mQuantizedColors.add(new Palette.Swatch(new float[]{
+                    centroid[0] * 360f,
+                    centroid[1],
+                    centroid[2]
+            }, mean.getItems().size()));
+        }
+    }
+
+    private List<KMeans.Mean> getOptimalKMeans(int k, float[][] inputData) {
+        List<KMeans.Mean> optimal = null;
+        double optimalScore = -Double.MAX_VALUE;
+        int runs = mInitializations;
+        while (runs > 0) {
+            if (DEBUG) {
+                Log.d(TAG, "k-means run: " + runs);
+            }
+            List<KMeans.Mean> means = mKMeans.predict(k, inputData);
+            double score = KMeans.score(means);
+            if (optimal == null || score > optimalScore) {
+                if (DEBUG) {
+                    Log.d(TAG, "\tnew optimal score: " + score);
+                }
+                optimalScore = score;
+                optimal = means;
+            }
+            runs--;
+        }
+
+        return optimal;
+    }
+
+    @Override
+    public List<Palette.Swatch> getQuantizedColors() {
+        return mQuantizedColors;
+    }
+}
diff --git a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
index ddf07f4..1811800c 100644
--- a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
+++ b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
@@ -20,6 +20,7 @@
 
 import android.content.Context;
 import android.os.Build;
+import android.os.SystemProperties;
 import android.provider.Settings;
 import android.text.TextUtils;
 
@@ -35,6 +36,7 @@
         return pulseOnNotificationEnabled(user)
                 || pulseOnPickupEnabled(user)
                 || pulseOnDoubleTapEnabled(user)
+                || pulseOnLongPressEnabled(user)
                 || alwaysOnEnabled(user);
     }
 
@@ -52,8 +54,8 @@
     }
 
     public boolean pulseOnPickupEnabled(int user) {
-        return boolSettingDefaultOn(Settings.Secure.DOZE_PULSE_ON_PICK_UP, user)
-                && pulseOnPickupAvailable();
+        boolean settingEnabled = boolSettingDefaultOn(Settings.Secure.DOZE_PULSE_ON_PICK_UP, user);
+        return (settingEnabled || alwaysOnEnabled(user)) && pulseOnPickupAvailable();
     }
 
     public boolean pulseOnPickupAvailable() {
@@ -61,6 +63,10 @@
                 && ambientDisplayAvailable();
     }
 
+    public boolean pulseOnPickupCanBeModified(int user) {
+        return !alwaysOnEnabled(user);
+    }
+
     public boolean pulseOnDoubleTapEnabled(int user) {
         return boolSettingDefaultOn(Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP, user)
                 && pulseOnDoubleTapAvailable();
@@ -74,24 +80,54 @@
         return mContext.getResources().getString(R.string.config_dozeDoubleTapSensorType);
     }
 
+    public String longPressSensorType() {
+        return mContext.getResources().getString(R.string.config_dozeLongPressSensorType);
+    }
+
+    public boolean pulseOnLongPressEnabled(int user) {
+        return pulseOnLongPressAvailable() && boolSettingDefaultOff(
+                Settings.Secure.DOZE_PULSE_ON_LONG_PRESS, user);
+    }
+
+    private boolean pulseOnLongPressAvailable() {
+        return !TextUtils.isEmpty(longPressSensorType());
+    }
+
     public boolean alwaysOnEnabled(int user) {
-        return boolSettingDefaultOff(Settings.Secure.DOZE_ALWAYS_ON, user)
-                && alwaysOnAvailable();
+        return boolSettingDefaultOn(Settings.Secure.DOZE_ALWAYS_ON, user) && alwaysOnAvailable()
+                && !accessibilityInversionEnabled(user);
     }
 
     public boolean alwaysOnAvailable() {
-        // Does not work properly yet.
-        return false;
+        return (alwaysOnDisplayDebuggingEnabled() || alwaysOnDisplayAvailable())
+                && ambientDisplayAvailable();
+    }
+
+    public boolean alwaysOnAvailableForUser(int user) {
+        return alwaysOnAvailable() && !accessibilityInversionEnabled(user);
     }
 
     public String ambientDisplayComponent() {
         return mContext.getResources().getString(R.string.config_dozeComponent);
     }
 
+    public boolean accessibilityInversionEnabled(int user) {
+        return boolSettingDefaultOff(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, user);
+    }
+
     private boolean ambientDisplayAvailable() {
         return !TextUtils.isEmpty(ambientDisplayComponent());
     }
 
+    private boolean alwaysOnDisplayAvailable() {
+        return mContext.getResources().getBoolean(R.bool.config_dozeAlwaysOnDisplayAvailable);
+    }
+
+    private boolean alwaysOnDisplayDebuggingEnabled() {
+        return SystemProperties.getBoolean("debug.doze.aod", false) && Build.IS_DEBUGGABLE;
+    }
+
+
     private boolean boolSettingDefaultOn(String name, int user) {
         return boolSetting(name, user, 1);
     }
diff --git a/core/java/com/android/internal/inputmethod/package.html b/core/java/com/android/internal/inputmethod/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/logging/package.html b/core/java/com/android/internal/logging/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/logging/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/ml/clustering/KMeans.java b/core/java/com/android/internal/ml/clustering/KMeans.java
new file mode 100644
index 0000000..4d5b333
--- /dev/null
+++ b/core/java/com/android/internal/ml/clustering/KMeans.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.internal.ml.clustering;
+
+import android.annotation.NonNull;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Simple K-Means implementation
+ */
+public class KMeans {
+
+    private static final boolean DEBUG = false;
+    private static final String TAG = "KMeans";
+    private final Random mRandomState;
+    private final int mMaxIterations;
+    private float mSqConvergenceEpsilon;
+
+    public KMeans() {
+        this(new Random());
+    }
+
+    public KMeans(Random random) {
+        this(random, 30 /* maxIterations */, 0.005f /* convergenceEpsilon */);
+    }
+    public KMeans(Random random, int maxIterations, float convergenceEpsilon) {
+        mRandomState = random;
+        mMaxIterations = maxIterations;
+        mSqConvergenceEpsilon = convergenceEpsilon * convergenceEpsilon;
+    }
+
+    /**
+     * Runs k-means on the input data (X) trying to find k means.
+     *
+     * K-Means is known for getting stuck into local optima, so you might
+     * want to run it multiple time and argmax on {@link KMeans#score(List)}
+     *
+     * @param k The number of points to return.
+     * @param inputData Input data.
+     * @return An array of k Means, each representing a centroid and data points that belong to it.
+     */
+    public List<Mean> predict(final int k, final float[][] inputData) {
+        checkDataSetSanity(inputData);
+        int dimension = inputData[0].length;
+
+        final ArrayList<Mean> means = new ArrayList<>();
+        for (int i = 0; i < k; i++) {
+            Mean m = new Mean(dimension);
+            for (int j = 0; j < dimension; j++) {
+                m.mCentroid[j] = mRandomState.nextFloat();
+            }
+            means.add(m);
+        }
+
+        // Iterate until we converge or run out of iterations
+        boolean converged = false;
+        for (int i = 0; i < mMaxIterations; i++) {
+            converged = step(means, inputData);
+            if (converged) {
+                if (DEBUG) Log.d(TAG, "Converged at iteration: " + i);
+                break;
+            }
+        }
+        if (!converged && DEBUG) Log.d(TAG, "Did not converge");
+
+        return means;
+    }
+
+    /**
+     * Score calculates the inertia between means.
+     * This can be considered as an E step of an EM algorithm.
+     *
+     * @param means Means to use when calculating score.
+     * @return The score
+     */
+    public static double score(@NonNull List<Mean> means) {
+        double score = 0;
+        final int meansSize = means.size();
+        for (int i = 0; i < meansSize; i++) {
+            Mean mean = means.get(i);
+            for (int j = 0; j < meansSize; j++) {
+                Mean compareTo = means.get(j);
+                if (mean == compareTo) {
+                    continue;
+                }
+                double distance = Math.sqrt(sqDistance(mean.mCentroid, compareTo.mCentroid));
+                score += distance;
+            }
+        }
+        return score;
+    }
+
+    @VisibleForTesting
+    public void checkDataSetSanity(float[][] inputData) {
+        if (inputData == null) {
+            throw new IllegalArgumentException("Data set is null.");
+        } else if (inputData.length == 0) {
+            throw new IllegalArgumentException("Data set is empty.");
+        } else if (inputData[0] == null) {
+            throw new IllegalArgumentException("Bad data set format.");
+        }
+
+        final int dimension = inputData[0].length;
+        final int length = inputData.length;
+        for (int i = 1; i < length; i++) {
+            if (inputData[i] == null || inputData[i].length != dimension) {
+                throw new IllegalArgumentException("Bad data set format.");
+            }
+        }
+    }
+
+    /**
+     * K-Means iteration.
+     *
+     * @param means Current means
+     * @param inputData Input data
+     * @return True if data set converged
+     */
+    private boolean step(final ArrayList<Mean> means, final float[][] inputData) {
+
+        // Clean up the previous state because we need to compute
+        // which point belongs to each mean again.
+        for (int i = means.size() - 1; i >= 0; i--) {
+            final Mean mean = means.get(i);
+            mean.mClosestItems.clear();
+        }
+        for (int i = inputData.length - 1; i >= 0; i--) {
+            final float[] current = inputData[i];
+            final Mean nearest = nearestMean(current, means);
+            nearest.mClosestItems.add(current);
+        }
+
+        boolean converged = true;
+        // Move each mean towards the nearest data set points
+        for (int i = means.size() - 1; i >= 0; i--) {
+            final Mean mean = means.get(i);
+            if (mean.mClosestItems.size() == 0) {
+                continue;
+            }
+
+            // Compute the new mean centroid:
+            //   1. Sum all all points
+            //   2. Average them
+            final float[] oldCentroid = mean.mCentroid;
+            mean.mCentroid = new float[oldCentroid.length];
+            for (int j = 0; j < mean.mClosestItems.size(); j++) {
+                // Update each centroid component
+                for (int p = 0; p < mean.mCentroid.length; p++) {
+                    mean.mCentroid[p] += mean.mClosestItems.get(j)[p];
+                }
+            }
+            for (int j = 0; j < mean.mCentroid.length; j++) {
+                mean.mCentroid[j] /= mean.mClosestItems.size();
+            }
+
+            // We converged if the centroid didn't move for any of the means.
+            if (sqDistance(oldCentroid, mean.mCentroid) > mSqConvergenceEpsilon) {
+                converged = false;
+            }
+        }
+        return converged;
+    }
+
+    @VisibleForTesting
+    public static Mean nearestMean(float[] point, List<Mean> means) {
+        Mean nearest = null;
+        float nearestDistance = Float.MAX_VALUE;
+
+        final int meanCount = means.size();
+        for (int i = 0; i < meanCount; i++) {
+            Mean next = means.get(i);
+            // We don't need the sqrt when comparing distances in euclidean space
+            // because they exist on both sides of the equation and cancel each other out.
+            float nextDistance = sqDistance(point, next.mCentroid);
+            if (nextDistance < nearestDistance) {
+                nearest = next;
+                nearestDistance = nextDistance;
+            }
+        }
+        return nearest;
+    }
+
+    @VisibleForTesting
+    public static float sqDistance(float[] a, float[] b) {
+        float dist = 0;
+        final int length = a.length;
+        for (int i = 0; i < length; i++) {
+            dist += (a[i] - b[i]) * (a[i] - b[i]);
+        }
+        return dist;
+    }
+
+    /**
+     * Definition of a mean, contains a centroid and points on its cluster.
+     */
+    public static class Mean {
+        float[] mCentroid;
+        final ArrayList<float[]> mClosestItems = new ArrayList<>();
+
+        public Mean(int dimension) {
+            mCentroid = new float[dimension];
+        }
+
+        public Mean(float ...centroid) {
+            mCentroid = centroid;
+        }
+
+        public float[] getCentroid() {
+            return mCentroid;
+        }
+
+        public List<float[]> getItems() {
+            return mClosestItems;
+        }
+
+        @Override
+        public String toString() {
+            return "Mean(centroid: " + Arrays.toString(mCentroid) + ", size: "
+                    + mClosestItems.size() + ")";
+        }
+    }
+}
diff --git a/core/java/com/android/internal/net/OWNERS b/core/java/com/android/internal/net/OWNERS
index 7cb32ff..e2064a8 100644
--- a/core/java/com/android/internal/net/OWNERS
+++ b/core/java/com/android/internal/net/OWNERS
@@ -2,5 +2,5 @@
 
 ek@google.com
 hugobenichi@google.com
-jsharkey@google.com
+jsharkey@android.com
 lorenzo@google.com
diff --git a/core/java/com/android/internal/notification/SystemNotificationChannels.java b/core/java/com/android/internal/notification/SystemNotificationChannels.java
index d327180..d64c9a1 100644
--- a/core/java/com/android/internal/notification/SystemNotificationChannels.java
+++ b/core/java/com/android/internal/notification/SystemNotificationChannels.java
@@ -132,10 +132,12 @@
                 context.getString(R.string.notification_channel_usb),
                 NotificationManager.IMPORTANCE_MIN));
 
-        channelsList.add(new NotificationChannel(
+        NotificationChannel foregroundChannel = new NotificationChannel(
                 FOREGROUND_SERVICE,
                 context.getString(R.string.notification_channel_foreground_service),
-                NotificationManager.IMPORTANCE_LOW));
+                NotificationManager.IMPORTANCE_LOW);
+        foregroundChannel.setBlockableSystem(true);
+        channelsList.add(foregroundChannel);
 
         nm.createNotificationChannels(channelsList);
     }
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index f3632f0..f085e29 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -840,7 +840,10 @@
             if (sipper.shouldHide) {
                 if (sipper.drainType != BatterySipper.DrainType.OVERCOUNTED
                         && sipper.drainType != BatterySipper.DrainType.SCREEN
-                        && sipper.drainType != BatterySipper.DrainType.UNACCOUNTED) {
+                        && sipper.drainType != BatterySipper.DrainType.UNACCOUNTED
+                        && sipper.drainType != BatterySipper.DrainType.BLUETOOTH
+                        && sipper.drainType != BatterySipper.DrainType.WIFI
+                        && sipper.drainType != BatterySipper.DrainType.IDLE) {
                     // Don't add it if it is overcounted, unaccounted or screen
                     proportionalSmearPowerMah += sipper.totalPowerMah;
                 }
@@ -861,19 +864,19 @@
      * time.
      */
     public void smearScreenBatterySipper(List<BatterySipper> sippers, BatterySipper screenSipper) {
-        final long rawRealtimeMs = SystemClock.elapsedRealtime();
         long totalActivityTimeMs = 0;
         final SparseLongArray activityTimeArray = new SparseLongArray();
         for (int i = 0, size = sippers.size(); i < size; i++) {
             final BatteryStats.Uid uid = sippers.get(i).uidObj;
             if (uid != null) {
-                final long timeMs = getForegroundActivityTotalTimeMs(uid, rawRealtimeMs);
+                final long timeMs = getProcessForegroundTimeMs(uid,
+                        BatteryStats.STATS_SINCE_CHARGED);
                 activityTimeArray.put(uid.getUid(), timeMs);
                 totalActivityTimeMs += timeMs;
             }
         }
 
-        if (totalActivityTimeMs >= 10 * DateUtils.MINUTE_IN_MILLIS) {
+        if (screenSipper != null && totalActivityTimeMs >= 10 * DateUtils.MINUTE_IN_MILLIS) {
             final double screenPowerMah = screenSipper.totalPowerMah;
             for (int i = 0, size = sippers.size(); i < size; i++) {
                 final BatterySipper sipper = sippers.get(i);
@@ -936,17 +939,42 @@
         return false;
     }
 
+    public long convertUsToMs(long timeUs) {
+        return timeUs / 1000;
+    }
+
+    public long convertMsToUs(long timeMs) {
+        return timeMs * 1000;
+    }
+
     @VisibleForTesting
-    public long getForegroundActivityTotalTimeMs(BatteryStats.Uid uid, long rawRealtimeMs) {
+    public long getForegroundActivityTotalTimeUs(BatteryStats.Uid uid, long rawRealtimeUs) {
         final BatteryStats.Timer timer = uid.getForegroundActivityTimer();
         if (timer != null) {
-            return timer.getTotalTimeLocked(rawRealtimeMs, BatteryStats.STATS_SINCE_CHARGED);
+            return timer.getTotalTimeLocked(rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED);
         }
 
         return 0;
     }
 
     @VisibleForTesting
+    public long getProcessForegroundTimeMs(BatteryStats.Uid uid, int which) {
+        final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime());
+        final int foregroundTypes[] = {BatteryStats.Uid.PROCESS_STATE_TOP};
+
+        long timeUs = 0;
+        for (int type : foregroundTypes) {
+            final long localTime = uid.getProcessStateTime(type, rawRealTimeUs, which);
+            timeUs += localTime;
+        }
+
+        // Return the min value of STATE_TOP time and foreground activity time, since both of these
+        // time have some errors.
+        return convertUsToMs(
+                Math.min(timeUs, getForegroundActivityTotalTimeUs(uid, rawRealTimeUs)));
+    }
+
+    @VisibleForTesting
     public void setPackageManager(PackageManager packageManager) {
         mPackageManager = packageManager;
     }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 235ebc8..3bb20b4 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -171,6 +171,7 @@
 
     public interface PlatformIdleStateCallback {
         public String getPlatformLowPowerStats();
+        public String getSubsystemLowPowerStats();
     }
 
     private final PlatformIdleStateCallback mPlatformIdleStateCallback;
@@ -2878,6 +2879,12 @@
                         mPlatformIdleStateCallback.getPlatformLowPowerStats();
                 if (DEBUG) Slog.i(TAG, "WRITE PlatformIdleState:" +
                         mCurHistoryStepDetails.statPlatformIdleState);
+
+                mCurHistoryStepDetails.statSubsystemPowerState =
+                        mPlatformIdleStateCallback.getSubsystemLowPowerStats();
+                if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" +
+                        mCurHistoryStepDetails.statSubsystemPowerState);
+
             }
             computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails);
             if (includeStepDetails != 0) {
@@ -3590,7 +3597,12 @@
     }
 
     public void noteUidProcessStateLocked(int uid, int state) {
-        uid = mapUid(uid);
+        int parentUid = mapUid(uid);
+        if (uid != parentUid) {
+            // Isolated UIDs process state is already rolled up into parent, so no need to track
+            // Otherwise the parent's process state will get downgraded incorrectly
+            return;
+        }
         getUidStatsLocked(uid).updateUidProcessStateLocked(state);
     }
 
@@ -4845,7 +4857,7 @@
         }
     }
 
-    private void noteBluetoothScanStoppedLocked(int uid) {
+    private void noteBluetoothScanStoppedLocked(int uid, boolean isUnoptimized) {
         uid = mapUid(uid);
         final long elapsedRealtime = mClocks.elapsedRealtime();
         final long uptime = mClocks.uptimeMillis();
@@ -4857,13 +4869,13 @@
             addHistoryRecordLocked(elapsedRealtime, uptime);
             mBluetoothScanTimer.stopRunningLocked(elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime);
+        getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime, isUnoptimized);
     }
 
-    public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws) {
+    public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
         final int N = ws.size();
         for (int i = 0; i < N; i++) {
-            noteBluetoothScanStoppedLocked(ws.get(i));
+            noteBluetoothScanStoppedLocked(ws.get(i), isUnoptimized);
         }
     }
 
@@ -6114,14 +6126,11 @@
             }
         }
 
-        public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs) {
+        public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) {
             if (mBluetoothScanTimer != null) {
                 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs);
             }
-            // In the ble code, a scan cannot change types and nested starts are not possible.
-            // So if an unoptimizedScan is running, it is now being stopped.
-            if (mBluetoothUnoptimizedScanTimer != null
-                    && mBluetoothUnoptimizedScanTimer.isRunningLocked()) {
+            if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) {
                 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs);
             }
         }
@@ -6546,9 +6555,12 @@
          * inactive so can be dropped.
          */
         @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-        public boolean reset() {
+        public boolean reset(long uptime, long realtime) {
             boolean active = false;
 
+            mOnBatteryBackgroundTimeBase.init(uptime, realtime);
+            mOnBatteryScreenOffBackgroundTimeBase.init(uptime, realtime);
+
             if (mWifiRunningTimer != null) {
                 active |= !mWifiRunningTimer.reset(false);
                 active |= mWifiRunning;
@@ -6734,11 +6746,6 @@
             mLastStepUserTime = mLastStepSystemTime = 0;
             mCurStepUserTime = mCurStepSystemTime = 0;
 
-            mOnBatteryBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000,
-                    mBsi.mClocks.uptimeMillis() * 1000);
-            mOnBatteryScreenOffBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000,
-                    mBsi.mClocks.uptimeMillis() * 1000);
-
             if (!active) {
                 if (mWifiRunningTimer != null) {
                     mWifiRunningTimer.detach();
@@ -9330,7 +9337,7 @@
         mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0;
 
         for (int i=0; i<mUidStats.size(); i++) {
-            if (mUidStats.valueAt(i).reset()) {
+            if (mUidStats.valueAt(i).reset(uptimeMillis * 1000, elapsedRealtimeMillis * 1000)) {
                 mUidStats.remove(mUidStats.keyAt(i));
                 i--;
             }
diff --git a/core/java/com/android/internal/os/KernelCpuSpeedReader.java b/core/java/com/android/internal/os/KernelCpuSpeedReader.java
index 9c7debb..ae13ea4 100644
--- a/core/java/com/android/internal/os/KernelCpuSpeedReader.java
+++ b/core/java/com/android/internal/os/KernelCpuSpeedReader.java
@@ -15,13 +15,12 @@
  */
 package com.android.internal.os;
 
+import android.system.Os;
 import android.text.TextUtils;
 import android.os.StrictMode;
 import android.system.OsConstants;
 import android.util.Slog;
 
-import libcore.io.Libcore;
-
 import java.io.BufferedReader;
 import java.io.FileReader;
 import java.io.IOException;
@@ -53,7 +52,7 @@
                 cpuNumber);
         mLastSpeedTimes = new long[numSpeedSteps];
         mDeltaSpeedTimes = new long[numSpeedSteps];
-        long jiffyHz = Libcore.os.sysconf(OsConstants._SC_CLK_TCK);
+        long jiffyHz = Os.sysconf(OsConstants._SC_CLK_TCK);
         mJiffyMillis = 1000/jiffyHz;
     }
 
diff --git a/core/java/com/android/internal/os/KernelMemoryBandwidthStats.java b/core/java/com/android/internal/os/KernelMemoryBandwidthStats.java
index aa56e93..15a5e3e 100644
--- a/core/java/com/android/internal/os/KernelMemoryBandwidthStats.java
+++ b/core/java/com/android/internal/os/KernelMemoryBandwidthStats.java
@@ -1,6 +1,7 @@
 package com.android.internal.os;
 
 import android.os.StrictMode;
+import android.os.SystemClock;
 import android.text.TextUtils;
 import android.util.LongSparseLongArray;
 import android.util.Slog;
@@ -37,6 +38,8 @@
             return;
         }
 
+        final long startTime = SystemClock.uptimeMillis();
+
         StrictMode.ThreadPolicy policy = StrictMode.allowThreadDiskReads();
         try (BufferedReader reader = new BufferedReader(new FileReader(mSysfsFile))) {
             parseStats(reader);
@@ -50,6 +53,11 @@
         } finally {
             StrictMode.setThreadPolicy(policy);
         }
+
+        final long readTime = SystemClock.uptimeMillis() - startTime;
+        if (DEBUG || readTime > 100) {
+            Slog.w(TAG, "Reading memory bandwidth file took " + readTime + "ms");
+        }
     }
 
     @VisibleForTesting
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index 8036f257..7178ec7 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -16,6 +16,7 @@
 package com.android.internal.os;
 
 import android.os.Process;
+import android.os.SystemClock;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -66,6 +67,7 @@
         byte[] buffer = new byte[32*1024];
         int len;
         boolean wakeup_sources;
+        final long startTime = SystemClock.uptimeMillis();
 
         try {
             FileInputStream is;
@@ -90,6 +92,11 @@
             return null;
         }
 
+        final long readTime = SystemClock.uptimeMillis() - startTime;
+        if (readTime > 100) {
+            Slog.w(TAG, "Reading wakelock stats took " + readTime + "ms");
+        }
+
         if (len > 0) {
             if (len >= buffer.length) {
                 Slog.wtf(TAG, "Kernel wake locks exceeded buffer size " + buffer.length);
diff --git a/core/java/com/android/internal/os/LoggingPrintStream.java b/core/java/com/android/internal/os/LoggingPrintStream.java
index f14394a..d27874c 100644
--- a/core/java/com/android/internal/os/LoggingPrintStream.java
+++ b/core/java/com/android/internal/os/LoggingPrintStream.java
@@ -28,12 +28,15 @@
 import java.util.Formatter;
 import java.util.Locale;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  * A print stream which logs output line by line.
  *
  * {@hide}
  */
-abstract class LoggingPrintStream extends PrintStream {
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+public abstract class LoggingPrintStream extends PrintStream {
 
     private final StringBuilder builder = new StringBuilder();
 
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index e46dfc4..bf31c7d 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -22,6 +22,7 @@
 import android.os.Process;
 import android.os.StrictMode;
 import android.os.SystemClock;
+import android.system.Os;
 import android.system.OsConstants;
 import android.util.Slog;
 
@@ -294,7 +295,7 @@
 
     public ProcessCpuTracker(boolean includeThreads) {
         mIncludeThreads = includeThreads;
-        long jiffyHz = Libcore.os.sysconf(OsConstants._SC_CLK_TCK);
+        long jiffyHz = Os.sysconf(OsConstants._SC_CLK_TCK);
         mJiffyMillis = 1000/jiffyHz;
     }
 
diff --git a/core/java/com/android/internal/os/RoSystemProperties.java b/core/java/com/android/internal/os/RoSystemProperties.java
index 1d26df0..89a4e17 100644
--- a/core/java/com/android/internal/os/RoSystemProperties.java
+++ b/core/java/com/android/internal/os/RoSystemProperties.java
@@ -33,6 +33,8 @@
     // ------ ro.config.* -------- //
     public static final boolean CONFIG_LOW_RAM =
             SystemProperties.getBoolean("ro.config.low_ram", false);
+    public static final boolean CONFIG_SMALL_BATTERY =
+            SystemProperties.getBoolean("ro.config.small_battery", false);
 
     // ------ ro.fw.* ------------ //
     public static final boolean FW_SYSTEM_USER_SPLIT =
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index f4be128..66475e4 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -31,6 +31,7 @@
 import com.android.internal.logging.AndroidConfig;
 import com.android.server.NetworkManagementSocketTagger;
 import dalvik.system.VMRuntime;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.TimeZone;
@@ -228,8 +229,8 @@
      * @param argv Argument vector for main()
      * @param classLoader the classLoader to load {@className} with
      */
-    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
-            throws Zygote.MethodAndArgsCaller {
+    private static Runnable findStaticMain(String className, String[] argv,
+            ClassLoader classLoader) {
         Class<?> cl;
 
         try {
@@ -263,7 +264,7 @@
          * clears up all the stack frames that were required in setting
          * up the process.
          */
-        throw new Zygote.MethodAndArgsCaller(m, argv);
+        return new MethodAndArgsCaller(m, argv);
     }
 
     public static final void main(String[] argv) {
@@ -286,8 +287,8 @@
         if (DEBUG) Slog.d(TAG, "Leaving RuntimeInit!");
     }
 
-    protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
-            throws Zygote.MethodAndArgsCaller {
+    protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
+            ClassLoader classLoader) {
         // If the application calls System.exit(), terminate the process
         // immediately without running any shutdown hooks.  It is not possible to
         // shutdown an Android application gracefully.  Among other things, the
@@ -300,20 +301,13 @@
         VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
         VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
 
-        final Arguments args;
-        try {
-            args = new Arguments(argv);
-        } catch (IllegalArgumentException ex) {
-            Slog.e(TAG, ex.getMessage());
-            // let the process exit
-            return;
-        }
+        final Arguments args = new Arguments(argv);
 
         // The end of of the RuntimeInit event (see #zygoteInit).
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
         // Remaining arguments are passed to the start class's static main
-        invokeStaticMain(args.startClass, args.startArgs, classLoader);
+        return findStaticMain(args.startClass, args.startArgs, classLoader);
     }
 
     /**
@@ -422,4 +416,37 @@
             System.arraycopy(args, curArg, startArgs, 0, startArgs.length);
         }
     }
+
+    /**
+     * Helper class which holds a method and arguments and can call them. This is used as part of
+     * a trampoline to get rid of the initial process setup stack frames.
+     */
+    static class MethodAndArgsCaller implements Runnable {
+        /** method to call */
+        private final Method mMethod;
+
+        /** argument array */
+        private final String[] mArgs;
+
+        public MethodAndArgsCaller(Method method, String[] args) {
+            mMethod = method;
+            mArgs = args;
+        }
+
+        public void run() {
+            try {
+                mMethod.invoke(null, new Object[] { mArgs });
+            } catch (IllegalAccessException ex) {
+                throw new RuntimeException(ex);
+            } catch (InvocationTargetException ex) {
+                Throwable cause = ex.getCause();
+                if (cause instanceof RuntimeException) {
+                    throw (RuntimeException) cause;
+                } else if (cause instanceof Error) {
+                    throw (Error) cause;
+                }
+                throw new RuntimeException(ex);
+            }
+        }
+    }
 }
diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java
index e28079f..7f46a0c 100644
--- a/core/java/com/android/internal/os/WebViewZygoteInit.java
+++ b/core/java/com/android/internal/os/WebViewZygoteInit.java
@@ -26,6 +26,7 @@
 import android.webkit.WebViewFactory;
 import android.webkit.WebViewFactoryProvider;
 
+import java.io.DataOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
@@ -68,8 +69,7 @@
         }
 
         @Override
-        protected boolean handlePreloadPackage(String packagePath, String libsPath,
-                                               String cacheKey) {
+        protected void handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
             Log.i(TAG, "Beginning package preload");
             // Ask ApplicationLoaders to create and cache a classloader for the WebView APK so that
             // our children will reuse the same classloader instead of creating their own.
@@ -87,19 +87,28 @@
             // Once we have the classloader, look up the WebViewFactoryProvider implementation and
             // call preloadInZygote() on it to give it the opportunity to preload the native library
             // and perform any other initialisation work that should be shared among the children.
+            boolean preloadSucceeded = false;
             try {
                 Class<WebViewFactoryProvider> providerClass =
                         WebViewFactory.getWebViewProviderClass(loader);
                 Object result = providerClass.getMethod("preloadInZygote").invoke(null);
-                if (!((Boolean)result).booleanValue()) {
+                preloadSucceeded = ((Boolean) result).booleanValue();
+                if (!preloadSucceeded) {
                     Log.e(TAG, "preloadInZygote returned false");
                 }
             } catch (ClassNotFoundException | NoSuchMethodException | SecurityException |
                      IllegalAccessException | InvocationTargetException e) {
                 Log.e(TAG, "Exception while preloading package", e);
             }
+
+            try {
+                DataOutputStream socketOut = getSocketOutputStream();
+                socketOut.writeInt(preloadSucceeded ? 1 : 0);
+            } catch (IOException ioe) {
+                throw new IllegalStateException("Error writing to command socket", ioe);
+            }
+
             Log.i(TAG, "Package preload done");
-            return false;
         }
     }
 
@@ -113,16 +122,23 @@
             throw new RuntimeException("Failed to setpgid(0,0)", ex);
         }
 
+        final Runnable caller;
         try {
             sServer.registerServerSocket("webview_zygote");
-            sServer.runSelectLoop(TextUtils.join(",", Build.SUPPORTED_ABIS));
-            sServer.closeServerSocket();
-        } catch (Zygote.MethodAndArgsCaller caller) {
-            caller.run();
+            // The select loop returns early in the child process after a fork and
+            // loops forever in the zygote.
+            caller = sServer.runSelectLoop(TextUtils.join(",", Build.SUPPORTED_ABIS));
         } catch (RuntimeException e) {
             Log.e(TAG, "Fatal exception:", e);
+            throw e;
+        } finally {
+            sServer.closeServerSocket();
         }
 
-        System.exit(0);
+        // We're in the child process and have exited the select loop. Proceed to execute the
+        // command.
+        if (caller != null) {
+            caller.run();
+        }
     }
 }
diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java
index 608bc9f..89328b2 100644
--- a/core/java/com/android/internal/os/WrapperInit.java
+++ b/core/java/com/android/internal/os/WrapperInit.java
@@ -25,7 +25,6 @@
 import android.system.StructCapUserHeader;
 import android.util.BootTimingsTraceLog;
 import android.util.Slog;
-import com.android.internal.os.Zygote.MethodAndArgsCaller;
 import dalvik.system.VMRuntime;
 import java.io.DataOutputStream;
 import java.io.FileDescriptor;
@@ -61,37 +60,35 @@
      * @param args The command-line arguments.
      */
     public static void main(String[] args) {
-        try {
-            // Parse our mandatory arguments.
-            int fdNum = Integer.parseInt(args[0], 10);
-            int targetSdkVersion = Integer.parseInt(args[1], 10);
+        // Parse our mandatory arguments.
+        int fdNum = Integer.parseInt(args[0], 10);
+        int targetSdkVersion = Integer.parseInt(args[1], 10);
 
-            // Tell the Zygote what our actual PID is (since it only knows about the
-            // wrapper that it directly forked).
-            if (fdNum != 0) {
-                try {
-                    FileDescriptor fd = new FileDescriptor();
-                    fd.setInt$(fdNum);
-                    DataOutputStream os = new DataOutputStream(new FileOutputStream(fd));
-                    os.writeInt(Process.myPid());
-                    os.close();
-                    IoUtils.closeQuietly(fd);
-                } catch (IOException ex) {
-                    Slog.d(TAG, "Could not write pid of wrapped process to Zygote pipe.", ex);
-                }
+        // Tell the Zygote what our actual PID is (since it only knows about the
+        // wrapper that it directly forked).
+        if (fdNum != 0) {
+            try {
+                FileDescriptor fd = new FileDescriptor();
+                fd.setInt$(fdNum);
+                DataOutputStream os = new DataOutputStream(new FileOutputStream(fd));
+                os.writeInt(Process.myPid());
+                os.close();
+                IoUtils.closeQuietly(fd);
+            } catch (IOException ex) {
+                Slog.d(TAG, "Could not write pid of wrapped process to Zygote pipe.", ex);
             }
-
-            // Mimic system Zygote preloading.
-            ZygoteInit.preload(new BootTimingsTraceLog("WrapperInitTiming",
-                    Trace.TRACE_TAG_DALVIK));
-
-            // Launch the application.
-            String[] runtimeArgs = new String[args.length - 2];
-            System.arraycopy(args, 2, runtimeArgs, 0, runtimeArgs.length);
-            WrapperInit.wrapperInit(targetSdkVersion, runtimeArgs);
-        } catch (Zygote.MethodAndArgsCaller caller) {
-            caller.run();
         }
+
+        // Mimic system Zygote preloading.
+        ZygoteInit.preload(new BootTimingsTraceLog("WrapperInitTiming",
+                Trace.TRACE_TAG_DALVIK));
+
+        // Launch the application.
+        String[] runtimeArgs = new String[args.length - 2];
+        System.arraycopy(args, 2, runtimeArgs, 0, runtimeArgs.length);
+        Runnable r = wrapperInit(targetSdkVersion, runtimeArgs);
+
+        r.run();
     }
 
     /**
@@ -142,8 +139,7 @@
      * @param targetSdkVersion target SDK version
      * @param argv arg strings
      */
-    private static void wrapperInit(int targetSdkVersion, String[] argv)
-            throws Zygote.MethodAndArgsCaller {
+    private static Runnable wrapperInit(int targetSdkVersion, String[] argv) {
         if (RuntimeInit.DEBUG) {
             Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from wrapper");
         }
@@ -165,7 +161,7 @@
 
         // Perform the same initialization that would happen after the Zygote forks.
         Zygote.nativePreApplicationInit();
-        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
+        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
     }
 
     /**
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 91d9d1e..3ee8b47 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -28,7 +28,7 @@
 /** @hide */
 public final class Zygote {
     /*
-    * Bit values for "debugFlags" argument.  The definitions are duplicated
+    * Bit values for "runtimeFlags" argument.  The definitions are duplicated
     * in the native code.
     */
 
@@ -51,6 +51,11 @@
     /** Make the code Java debuggable by turning off some optimizations. */
     public static final int DEBUG_JAVA_DEBUGGABLE = 1 << 8;
 
+    /** Turn off the verifier. */
+    public static final int DISABLE_VERIFIER = 1 << 9;
+    /** Only use oat files located in /system. Otherwise use dex/jar/apk . */
+    public static final int ONLY_USE_SYSTEM_OAT_FILES = 1 << 10;
+
     /** No external storage should be mounted. */
     public static final int MOUNT_EXTERNAL_NONE = 0;
     /** Default external storage should be mounted. */
@@ -75,7 +80,7 @@
      * fork()ing and and before spawning any threads.
      * @param gids null-ok; a list of UNIX gids that the new process should
      * setgroups() to after fork and before spawning any threads.
-     * @param debugFlags bit flags that enable debugging features.
+     * @param runtimeFlags bit flags that enable ART features.
      * @param rlimits null-ok an array of rlimit tuples, with the second
      * dimension having a length of 3 and representing
      * (resource, rlim_cur, rlim_max). These are set via the posix
@@ -96,18 +101,18 @@
      * @return 0 if this is the child, pid of the child
      * if this is the parent, or -1 on error.
      */
-    public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
+    public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
           int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
           int[] fdsToIgnore, String instructionSet, String appDataDir) {
         VM_HOOKS.preFork();
         // Resets nice priority for zygote process.
         resetNicePriority();
         int pid = nativeForkAndSpecialize(
-                  uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
+                  uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                   fdsToIgnore, instructionSet, appDataDir);
         // Enable tracing as soon as possible for the child process.
         if (pid == 0) {
-            Trace.setTracingEnabled(true);
+            Trace.setTracingEnabled(true, runtimeFlags);
 
             // Note that this event ends at the end of handleChildProc,
             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
@@ -116,7 +121,7 @@
         return pid;
     }
 
-    native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int debugFlags,
+    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, String instructionSet, String appDataDir);
 
@@ -137,7 +142,7 @@
      * fork()ing and and before spawning any threads.
      * @param gids null-ok; a list of UNIX gids that the new process should
      * setgroups() to after fork and before spawning any threads.
-     * @param debugFlags bit flags that enable debugging features.
+     * @param runtimeFlags bit flags that enable ART features.
      * @param rlimits null-ok an array of rlimit tuples, with the second
      * dimension having a length of 3 and representing
      * (resource, rlim_cur, rlim_max). These are set via the posix
@@ -148,22 +153,22 @@
      * @return 0 if this is the child, pid of the child
      * if this is the parent, or -1 on error.
      */
-    public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
+    public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
             int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
         VM_HOOKS.preFork();
         // Resets nice priority for zygote process.
         resetNicePriority();
         int pid = nativeForkSystemServer(
-                uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
+                uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities);
         // Enable tracing as soon as we enter the system_server.
         if (pid == 0) {
-            Trace.setTracingEnabled(true);
+            Trace.setTracingEnabled(true, runtimeFlags);
         }
         VM_HOOKS.postForkCommon();
         return pid;
     }
 
-    native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,
+    native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
             int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
 
     /**
@@ -177,9 +182,9 @@
      */
     native protected static void nativeUnmountStorageOnInit();
 
-    private static void callPostForkChildHooks(int debugFlags, boolean isSystemServer,
+    private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemServer,
             String instructionSet) {
-        VM_HOOKS.postForkChild(debugFlags, isSystemServer, instructionSet);
+        VM_HOOKS.postForkChild(runtimeFlags, isSystemServer, instructionSet);
     }
 
     /**
@@ -221,39 +226,4 @@
             command.append(" '").append(arg.replace("'", "'\\''")).append("'");
         }
     }
-
-    /**
-     * Helper exception class which holds a method and arguments and
-     * can call them. This is used as part of a trampoline to get rid of
-     * the initial process setup stack frames.
-     */
-    public static class MethodAndArgsCaller extends Exception
-            implements Runnable {
-        /** method to call */
-        private final Method mMethod;
-
-        /** argument array */
-        private final String[] mArgs;
-
-        public MethodAndArgsCaller(Method method, String[] args) {
-            mMethod = method;
-            mArgs = args;
-        }
-
-        public void run() {
-            try {
-                mMethod.invoke(null, new Object[] { mArgs });
-            } catch (IllegalAccessException ex) {
-                throw new RuntimeException(ex);
-            } catch (InvocationTargetException ex) {
-                Throwable cause = ex.getCause();
-                if (cause instanceof RuntimeException) {
-                    throw (RuntimeException) cause;
-                } else if (cause instanceof Error) {
-                    throw (Error) cause;
-                }
-                throw new RuntimeException(ex);
-            }
-        }
-    }
 }
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 05f43e4..0bb7326 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -30,7 +30,6 @@
 import android.net.LocalSocket;
 import android.os.FactoryTest;
 import android.os.Process;
-import android.os.SELinux;
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.system.ErrnoException;
@@ -42,14 +41,13 @@
 import java.io.ByteArrayInputStream;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
+import java.io.EOFException;
 import java.io.FileDescriptor;
-import java.io.FileOutputStream;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
-import java.io.PrintStream;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
-import java.util.Arrays;
 import libcore.io.IoUtils;
 
 /**
@@ -73,6 +71,7 @@
     private final BufferedReader mSocketReader;
     private final Credentials peer;
     private final String abiList;
+    private boolean isEof;
 
     /**
      * Constructs instance from connected socket.
@@ -99,6 +98,8 @@
             Log.e(TAG, "Cannot read peer credentials", ex);
             throw ex;
         }
+
+        isEof = false;
     }
 
     /**
@@ -111,21 +112,14 @@
     }
 
     /**
-     * Reads one start command from the command socket. If successful,
-     * a child is forked and a {@link Zygote.MethodAndArgsCaller}
-     * exception is thrown in that child while in the parent process,
-     * the method returns normally. On failure, the child is not
-     * spawned and messages are printed to the log and stderr. Returns
-     * a boolean status value indicating whether an end-of-file on the command
-     * socket has been encountered.
+     * Reads one start command from the command socket. If successful, a child is forked and a
+     * {@code Runnable} that calls the childs main method (or equivalent) is returned in the child
+     * process. {@code null} is always returned in the parent process (the zygote).
      *
-     * @return false if command socket should continue to be read from, or
-     * true if an end-of-file has been encountered.
-     * @throws Zygote.MethodAndArgsCaller trampoline to invoke main()
-     * method in child process
+     * If the client closes the socket, an {@code EOF} condition is set, which callers can test
+     * for by calling {@code ZygoteConnection.isClosedByPeer}.
      */
-    boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {
-
+    Runnable processOneCommand(ZygoteServer zygoteServer) {
         String args[];
         Arguments parsedArgs = null;
         FileDescriptor[] descriptors;
@@ -134,130 +128,120 @@
             args = readArgumentList();
             descriptors = mSocket.getAncillaryFileDescriptors();
         } catch (IOException ex) {
-            Log.w(TAG, "IOException on command socket " + ex.getMessage());
-            closeSocket();
-            return true;
+            throw new IllegalStateException("IOException on command socket", ex);
         }
 
+        // readArgumentList returns null only when it has reached EOF with no available
+        // data to read. This will only happen when the remote socket has disconnected.
         if (args == null) {
-            // EOF reached.
-            closeSocket();
-            return true;
-        }
-
-        /** the stderr of the most recent request, if avail */
-        PrintStream newStderr = null;
-
-        if (descriptors != null && descriptors.length >= 3) {
-            newStderr = new PrintStream(
-                    new FileOutputStream(descriptors[2]));
+            isEof = true;
+            return null;
         }
 
         int pid = -1;
         FileDescriptor childPipeFd = null;
         FileDescriptor serverPipeFd = null;
 
-        try {
-            parsedArgs = new Arguments(args);
+        parsedArgs = new Arguments(args);
 
-            if (parsedArgs.abiListQuery) {
-                return handleAbiListQuery();
-            }
+        if (parsedArgs.abiListQuery) {
+            handleAbiListQuery();
+            return null;
+        }
 
-            if (parsedArgs.preloadDefault) {
-                return handlePreload();
-            }
+        if (parsedArgs.preloadDefault) {
+            handlePreload();
+            return null;
+        }
 
-            if (parsedArgs.preloadPackage != null) {
-                return handlePreloadPackage(parsedArgs.preloadPackage,
-                        parsedArgs.preloadPackageLibs, parsedArgs.preloadPackageCacheKey);
-            }
+        if (parsedArgs.preloadPackage != null) {
+            handlePreloadPackage(parsedArgs.preloadPackage, parsedArgs.preloadPackageLibs,
+                    parsedArgs.preloadPackageCacheKey);
+            return null;
+        }
 
-            if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) {
-                throw new ZygoteSecurityException("Client may not specify capabilities: " +
-                        "permitted=0x" + Long.toHexString(parsedArgs.permittedCapabilities) +
-                        ", effective=0x" + Long.toHexString(parsedArgs.effectiveCapabilities));
-            }
+        if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) {
+            throw new ZygoteSecurityException("Client may not specify capabilities: " +
+                    "permitted=0x" + Long.toHexString(parsedArgs.permittedCapabilities) +
+                    ", effective=0x" + Long.toHexString(parsedArgs.effectiveCapabilities));
+        }
 
-            applyUidSecurityPolicy(parsedArgs, peer);
-            applyInvokeWithSecurityPolicy(parsedArgs, peer);
+        applyUidSecurityPolicy(parsedArgs, peer);
+        applyInvokeWithSecurityPolicy(parsedArgs, peer);
 
-            applyDebuggerSystemProperty(parsedArgs);
-            applyInvokeWithSystemProperty(parsedArgs);
+        applyDebuggerSystemProperty(parsedArgs);
+        applyInvokeWithSystemProperty(parsedArgs);
 
-            int[][] rlimits = null;
+        int[][] rlimits = null;
 
-            if (parsedArgs.rlimits != null) {
-                rlimits = parsedArgs.rlimits.toArray(intArray2d);
-            }
+        if (parsedArgs.rlimits != null) {
+            rlimits = parsedArgs.rlimits.toArray(intArray2d);
+        }
 
-            int[] fdsToIgnore = null;
+        int[] fdsToIgnore = null;
 
-            if (parsedArgs.invokeWith != null) {
+        if (parsedArgs.invokeWith != null) {
+            try {
                 FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
                 childPipeFd = pipeFds[1];
                 serverPipeFd = pipeFds[0];
                 Os.fcntlInt(childPipeFd, F_SETFD, 0);
-                fdsToIgnore = new int[] { childPipeFd.getInt$(), serverPipeFd.getInt$() };
+                fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()};
+            } catch (ErrnoException errnoEx) {
+                throw new IllegalStateException("Unable to set up pipe for invoke-with", errnoEx);
             }
-
-            /**
-             * In order to avoid leaking descriptors to the Zygote child,
-             * the native code must close the two Zygote socket descriptors
-             * in the child process before it switches from Zygote-root to
-             * the UID and privileges of the application being launched.
-             *
-             * In order to avoid "bad file descriptor" errors when the
-             * two LocalSocket objects are closed, the Posix file
-             * descriptors are released via a dup2() call which closes
-             * the socket and substitutes an open descriptor to /dev/null.
-             */
-
-            int [] fdsToClose = { -1, -1 };
-
-            FileDescriptor fd = mSocket.getFileDescriptor();
-
-            if (fd != null) {
-                fdsToClose[0] = fd.getInt$();
-            }
-
-            fd = zygoteServer.getServerSocketFileDescriptor();
-
-            if (fd != null) {
-                fdsToClose[1] = fd.getInt$();
-            }
-
-            fd = null;
-
-            pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
-                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
-                    parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
-                    parsedArgs.appDataDir);
-        } catch (ErrnoException ex) {
-            logAndPrintError(newStderr, "Exception creating pipe", ex);
-        } catch (IllegalArgumentException ex) {
-            logAndPrintError(newStderr, "Invalid zygote arguments", ex);
-        } catch (ZygoteSecurityException ex) {
-            logAndPrintError(newStderr,
-                    "Zygote security policy prevents request: ", ex);
         }
 
+        /**
+         * In order to avoid leaking descriptors to the Zygote child,
+         * the native code must close the two Zygote socket descriptors
+         * in the child process before it switches from Zygote-root to
+         * the UID and privileges of the application being launched.
+         *
+         * In order to avoid "bad file descriptor" errors when the
+         * two LocalSocket objects are closed, the Posix file
+         * descriptors are released via a dup2() call which closes
+         * the socket and substitutes an open descriptor to /dev/null.
+         */
+
+        int [] fdsToClose = { -1, -1 };
+
+        FileDescriptor fd = mSocket.getFileDescriptor();
+
+        if (fd != null) {
+            fdsToClose[0] = fd.getInt$();
+        }
+
+        fd = zygoteServer.getServerSocketFileDescriptor();
+
+        if (fd != null) {
+            fdsToClose[1] = fd.getInt$();
+        }
+
+        fd = null;
+
+        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
+                parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
+                parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
+                parsedArgs.appDataDir);
+
         try {
             if (pid == 0) {
                 // in child
+                zygoteServer.setForkChild();
+
                 zygoteServer.closeServerSocket();
                 IoUtils.closeQuietly(serverPipeFd);
                 serverPipeFd = null;
-                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
 
-                // should never get here, the child is expected to either
-                // throw Zygote.MethodAndArgsCaller or exec().
-                return true;
+                return handleChildProc(parsedArgs, descriptors, childPipeFd);
             } else {
-                // in parent...pid of < 0 means failure
+                // In the parent. A pid < 0 indicates a failure and will be handled in
+                // handleParentProc.
                 IoUtils.closeQuietly(childPipeFd);
                 childPipeFd = null;
-                return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
+                handleParentProc(pid, descriptors, serverPipeFd);
+                return null;
             }
         } finally {
             IoUtils.closeQuietly(childPipeFd);
@@ -265,15 +249,13 @@
         }
     }
 
-    private boolean handleAbiListQuery() {
+    private void handleAbiListQuery() {
         try {
             final byte[] abiListBytes = abiList.getBytes(StandardCharsets.US_ASCII);
             mSocketOutStream.writeInt(abiListBytes.length);
             mSocketOutStream.write(abiListBytes);
-            return false;
         } catch (IOException ioe) {
-            Log.e(TAG, "Error writing to command socket", ioe);
-            return true;
+            throw new IllegalStateException("Error writing to command socket", ioe);
         }
     }
 
@@ -283,7 +265,7 @@
      * if no preload was initiated. The latter implies that the zygote is not configured to load
      * resources lazy or that the zygote has already handled a previous request to handlePreload.
      */
-    private boolean handlePreload() {
+    private void handlePreload() {
         try {
             if (isPreloadComplete()) {
                 mSocketOutStream.writeInt(1);
@@ -291,11 +273,8 @@
                 preload();
                 mSocketOutStream.writeInt(0);
             }
-
-            return false;
         } catch (IOException ioe) {
-            Log.e(TAG, "Error writing to command socket", ioe);
-            return true;
+            throw new IllegalStateException("Error writing to command socket", ioe);
         }
     }
 
@@ -307,7 +286,11 @@
         return ZygoteInit.isPreloadComplete();
     }
 
-    protected boolean handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
+    protected DataOutputStream getSocketOutputStream() {
+        return mSocketOutStream;
+    }
+
+    protected void handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
         throw new RuntimeException("Zyogte does not support package preloading");
     }
 
@@ -323,6 +306,10 @@
         }
     }
 
+    boolean isClosedByPeer() {
+        return isEof;
+    }
+
     /**
      * Handles argument parsing for args related to the zygote spawner.
      *
@@ -363,11 +350,9 @@
         int[] gids;
 
         /**
-         * From --enable-jdwp, --enable-checkjni, --enable-assert,
-         * --enable-safemode, --generate-debug-info, --enable-jni-logging,
-         * --java-debuggable, and --native-debuggable.
+         * From --runtime-flags.
          */
-        int debugFlags;
+        int runtimeFlags;
 
         /** From --mount-external */
         int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
@@ -483,26 +468,11 @@
                     targetSdkVersionSpecified = true;
                     targetSdkVersion = Integer.parseInt(
                             arg.substring(arg.indexOf('=') + 1));
-                } else if (arg.equals("--enable-jdwp")) {
-                    debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
-                } else if (arg.equals("--enable-safemode")) {
-                    debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
-                } else if (arg.equals("--enable-checkjni")) {
-                    debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
-                } else if (arg.equals("--generate-debug-info")) {
-                    debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
-                } else if (arg.equals("--always-jit")) {
-                    debugFlags |= Zygote.DEBUG_ALWAYS_JIT;
-                } else if (arg.equals("--native-debuggable")) {
-                    debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;
-                } else if (arg.equals("--java-debuggable")) {
-                    debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
-                } else if (arg.equals("--enable-jni-logging")) {
-                    debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
-                } else if (arg.equals("--enable-assert")) {
-                    debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
                 } else if (arg.equals("--runtime-args")) {
                     seenRuntimeArgs = true;
+                } else if (arg.startsWith("--runtime-flags=")) {
+                    runtimeFlags = Integer.parseInt(
+                            arg.substring(arg.indexOf('=') + 1));
                 } else if (arg.startsWith("--seinfo=")) {
                     if (seInfoSpecified) {
                         throw new IllegalArgumentException(
@@ -718,7 +688,7 @@
      */
     public static void applyDebuggerSystemProperty(Arguments args) {
         if (RoSystemProperties.DEBUGGABLE) {
-            args.debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
+            args.runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
         }
     }
 
@@ -740,7 +710,7 @@
         int peerUid = peer.getUid();
 
         if (args.invokeWith != null && peerUid != 0 &&
-            (args.debugFlags & Zygote.DEBUG_ENABLE_JDWP) == 0) {
+            (args.runtimeFlags & Zygote.DEBUG_ENABLE_JDWP) == 0) {
             throw new ZygoteSecurityException("Peer is permitted to specify an"
                     + "explicit invoke-with wrapper command only for debuggable"
                     + "applications.");
@@ -770,15 +740,9 @@
      * @param parsedArgs non-null; zygote args
      * @param descriptors null-ok; new file descriptors for stdio if available.
      * @param pipeFd null-ok; pipe for communication back to Zygote.
-     * @param newStderr null-ok; stream to use for stderr until stdio
-     * is reopened.
-     *
-     * @throws Zygote.MethodAndArgsCaller on success to
-     * trampoline to code that invokes static main.
      */
-    private void handleChildProc(Arguments parsedArgs,
-            FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
-            throws Zygote.MethodAndArgsCaller {
+    private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
+            FileDescriptor pipeFd) {
         /**
          * By the time we get here, the native code has closed the two actual Zygote
          * socket connections, and substituted /dev/null in their place.  The LocalSocket
@@ -795,7 +759,6 @@
                 for (FileDescriptor fd: descriptors) {
                     IoUtils.closeQuietly(fd);
                 }
-                newStderr = System.err;
             } catch (ErrnoException ex) {
                 Log.e(TAG, "Error reopening stdio", ex);
             }
@@ -812,9 +775,12 @@
                     parsedArgs.niceName, parsedArgs.targetSdkVersion,
                     VMRuntime.getCurrentInstructionSet(),
                     pipeFd, parsedArgs.remainingArgs);
+
+            // Should not get here.
+            throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
         } else {
-            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
-                    parsedArgs.remainingArgs, null /* classLoader */);
+            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
+                    null /* classLoader */);
         }
     }
 
@@ -826,13 +792,8 @@
      * @param descriptors null-ok; file descriptors for child's new stdio if
      * specified.
      * @param pipeFd null-ok; pipe for communication with child.
-     * @param parsedArgs non-null; zygote args
-     * @return true for "exit command loop" and false for "continue command
-     * loop"
      */
-    private boolean handleParentProc(int pid,
-            FileDescriptor[] descriptors, FileDescriptor pipeFd, Arguments parsedArgs) {
-
+    private void handleParentProc(int pid, FileDescriptor[] descriptors, FileDescriptor pipeFd) {
         if (pid > 0) {
             setChildPgid(pid);
         }
@@ -924,11 +885,8 @@
             mSocketOutStream.writeInt(pid);
             mSocketOutStream.writeBoolean(usingWrapper);
         } catch (IOException ex) {
-            Log.e(TAG, "Error writing to command socket", ex);
-            return true;
+            throw new IllegalStateException("Error writing to command socket", ex);
         }
-
-        return false;
     }
 
     private void setChildPgid(int pid) {
@@ -944,20 +902,4 @@
                 + "normal if peer is not in our session");
         }
     }
-
-    /**
-     * Logs an error message and prints it to the specified stream, if
-     * provided
-     *
-     * @param newStderr null-ok; a standard error stream
-     * @param message non-null; error message
-     * @param ex null-ok an exception
-     */
-    private static void logAndPrintError (PrintStream newStderr,
-            String message, Throwable ex) {
-        Log.e(TAG, message, ex);
-        if (newStderr != null) {
-            newStderr.println(message + (ex == null ? "" : ex));
-        }
-    }
 }
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index c8c7ed9..3cda820 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -24,7 +24,6 @@
 import android.icu.impl.CacheValue;
 import android.icu.text.DecimalFormatSymbols;
 import android.icu.util.ULocale;
-import android.net.LocalServerSocket;
 import android.opengl.EGL14;
 import android.os.Build;
 import android.os.IInstalld;
@@ -133,6 +132,9 @@
         bootTimingsTraceLog.traceBegin("PreloadResources");
         preloadResources();
         bootTimingsTraceLog.traceEnd(); // PreloadResources
+        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
+        nativePreloadAppProcessHALs();
+        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
         Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
         preloadOpenGL();
         Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
@@ -185,6 +187,8 @@
         System.loadLibrary("jnigraphics");
     }
 
+    native private static void nativePreloadAppProcessHALs();
+
     private static void preloadOpenGL() {
         String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
         if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) &&
@@ -447,10 +451,7 @@
     /**
      * Finish remaining work for the newly forked system server process.
      */
-    private static void handleSystemServerProcess(
-            ZygoteConnection.Arguments parsedArgs)
-            throws Zygote.MethodAndArgsCaller {
-
+    private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
         // set umask to 0077 so new files and directories will default to owner-only permissions.
         Os.umask(S_IRWXG | S_IRWXO);
 
@@ -496,6 +497,8 @@
             WrapperInit.execApplication(parsedArgs.invokeWith,
                     parsedArgs.niceName, parsedArgs.targetSdkVersion,
                     VMRuntime.getCurrentInstructionSet(), null, args);
+
+            throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
         } else {
             ClassLoader cl = null;
             if (systemServerClasspath != null) {
@@ -507,7 +510,7 @@
             /*
              * Pass the remaining arguments to SystemServer.
              */
-            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
+            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
         }
 
         /* should never reach here */
@@ -543,13 +546,14 @@
         for (String classPathElement : classPathElements) {
             // System server is fully AOTed and never profiled
             // for profile guided compilation.
-            // TODO: Make this configurable between INTERPRET_ONLY, SPEED, SPACE and EVERYTHING?
+            String systemServerFilter = SystemProperties.get(
+                    "dalvik.vm.systemservercompilerfilter", "speed");
 
             int dexoptNeeded;
             try {
                 dexoptNeeded = DexFile.getDexOptNeeded(
-                    classPathElement, instructionSet, "speed",
-                    false /* newProfile */, false /* downgrade */);
+                    classPathElement, instructionSet, systemServerFilter,
+                    null /* classLoaderContext */, false /* newProfile */, false /* downgrade */);
             } catch (FileNotFoundException ignored) {
                 // Do not add to the classpath.
                 Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
@@ -567,13 +571,13 @@
                 final String packageName = "*";
                 final String outputPath = null;
                 final int dexFlags = 0;
-                final String compilerFilter = "speed";
+                final String compilerFilter = systemServerFilter;
                 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
                 final String seInfo = null;
                 try {
                     installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
                             instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
-                            uuid, sharedLibraries, seInfo);
+                            uuid, sharedLibraries, seInfo, false /* downgrade */);
                 } catch (RemoteException | ServiceSpecificException e) {
                     // Ignore (but log), we need this on the classpath for fallback mode.
                     Log.w(TAG, "Failed compiling classpath element for system server: "
@@ -589,10 +593,13 @@
     }
 
     /**
-     * Prepare the arguments and fork for the system server process.
+     * Prepare the arguments and forks for the system server process.
+     *
+     * Returns an {@code Runnable} that provides an entrypoint into system_server code in the
+     * child process, and {@code null} in the parent.
      */
-    private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
-            throws Zygote.MethodAndArgsCaller, RuntimeException {
+    private static Runnable forkSystemServer(String abiList, String socketName,
+            ZygoteServer zygoteServer) {
         long capabilities = posixCapabilitiesAsBits(
             OsConstants.CAP_IPC_LOCK,
             OsConstants.CAP_KILL,
@@ -642,7 +649,7 @@
             pid = Zygote.forkSystemServer(
                     parsedArgs.uid, parsedArgs.gid,
                     parsedArgs.gids,
-                    parsedArgs.debugFlags,
+                    parsedArgs.runtimeFlags,
                     null,
                     parsedArgs.permittedCapabilities,
                     parsedArgs.effectiveCapabilities);
@@ -657,10 +664,10 @@
             }
 
             zygoteServer.closeServerSocket();
-            handleSystemServerProcess(parsedArgs);
+            return handleSystemServerProcess(parsedArgs);
         }
 
-        return true;
+        return null;
     }
 
     /**
@@ -691,6 +698,7 @@
             throw new RuntimeException("Failed to setpgid(0,0)", ex);
         }
 
+        final Runnable caller;
         try {
             // Report Zygote start time to tron unless it is a runtime restart
             if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
@@ -749,7 +757,7 @@
             bootTimingsTraceLog.traceEnd(); // ZygoteInit
             // Disable tracing so that forked processes do not inherit stale tracing tags from
             // Zygote.
-            Trace.setTracingEnabled(false);
+            Trace.setTracingEnabled(false, 0);
 
             // Zygote process unmounts root storage spaces.
             Zygote.nativeUnmountStorageOnInit();
@@ -760,19 +768,32 @@
             ZygoteHooks.stopZygoteNoThreadCreation();
 
             if (startSystemServer) {
-                startSystemServer(abiList, socketName, zygoteServer);
+                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
+
+                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
+                // child (system_server) process.
+                if (r != null) {
+                    r.run();
+                    return;
+                }
             }
 
             Log.i(TAG, "Accepting command socket connections");
-            zygoteServer.runSelectLoop(abiList);
 
-            zygoteServer.closeServerSocket();
-        } catch (Zygote.MethodAndArgsCaller caller) {
-            caller.run();
+            // The select loop returns early in the child process after a fork and
+            // loops forever in the zygote.
+            caller = zygoteServer.runSelectLoop(abiList);
         } catch (Throwable ex) {
             Log.e(TAG, "System zygote died with exception", ex);
-            zygoteServer.closeServerSocket();
             throw ex;
+        } finally {
+            zygoteServer.closeServerSocket();
+        }
+
+        // We're in the child process and have exited the select loop. Proceed to execute the
+        // command.
+        if (caller != null) {
+            caller.run();
         }
     }
 
@@ -790,21 +811,7 @@
     private static void waitForSecondaryZygote(String socketName) {
         String otherZygoteName = Process.ZYGOTE_SOCKET.equals(socketName) ?
                 Process.SECONDARY_ZYGOTE_SOCKET : Process.ZYGOTE_SOCKET;
-        while (true) {
-            try {
-                final ZygoteProcess.ZygoteState zs =
-                        ZygoteProcess.ZygoteState.connect(otherZygoteName);
-                zs.close();
-                break;
-            } catch (IOException ioe) {
-                Log.w(TAG, "Got error connecting to zygote, retrying. msg= " + ioe.getMessage());
-            }
-
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException ie) {
-            }
-        }
+        ZygoteProcess.waitForConnectionToZygote(otherZygoteName);
     }
 
     static boolean isPreloadComplete() {
@@ -830,8 +837,7 @@
      * @param targetSdkVersion target SDK version
      * @param argv arg strings
      */
-    public static final void zygoteInit(int targetSdkVersion, String[] argv,
-            ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
+    public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
         if (RuntimeInit.DEBUG) {
             Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
         }
@@ -841,7 +847,7 @@
 
         RuntimeInit.commonInit();
         ZygoteInit.nativeZygoteInit();
-        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
+        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
     }
 
     private static final native void nativeZygoteInit();
diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java
index 126d9e7..8baa15a 100644
--- a/core/java/com/android/internal/os/ZygoteServer.java
+++ b/core/java/com/android/internal/os/ZygoteServer.java
@@ -25,6 +25,7 @@
 import android.system.StructPollfd;
 import android.util.Log;
 
+import android.util.Slog;
 import java.io.IOException;
 import java.io.FileDescriptor;
 import java.util.ArrayList;
@@ -45,9 +46,18 @@
 
     private LocalServerSocket mServerSocket;
 
+    /**
+     * Set by the child process, immediately after a call to {@code Zygote.forkAndSpecialize}.
+     */
+    private boolean mIsForkChild;
+
     ZygoteServer() {
     }
 
+    void setForkChild() {
+        mIsForkChild = true;
+    }
+
     /**
      * Registers a server socket for zygote command connections
      *
@@ -129,11 +139,8 @@
      * Runs the zygote process's select loop. Accepts new connections as
      * they happen, and reads commands from connections one spawn-request's
      * worth at a time.
-     *
-     * @throws Zygote.MethodAndArgsCaller in a child process when a main()
-     * should be executed.
      */
-    void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
+    Runnable runSelectLoop(String abiList) {
         ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
         ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
 
@@ -156,15 +163,62 @@
                 if ((pollFds[i].revents & POLLIN) == 0) {
                     continue;
                 }
+
                 if (i == 0) {
                     ZygoteConnection newPeer = acceptCommandPeer(abiList);
                     peers.add(newPeer);
                     fds.add(newPeer.getFileDesciptor());
                 } else {
-                    boolean done = peers.get(i).runOnce(this);
-                    if (done) {
-                        peers.remove(i);
-                        fds.remove(i);
+                    try {
+                        ZygoteConnection connection = peers.get(i);
+                        final Runnable command = connection.processOneCommand(this);
+
+                        if (mIsForkChild) {
+                            // We're in the child. We should always have a command to run at this
+                            // stage if processOneCommand hasn't called "exec".
+                            if (command == null) {
+                                throw new IllegalStateException("command == null");
+                            }
+
+                            return command;
+                        } else {
+                            // We're in the server - we should never have any commands to run.
+                            if (command != null) {
+                                throw new IllegalStateException("command != null");
+                            }
+
+                            // We don't know whether the remote side of the socket was closed or
+                            // not until we attempt to read from it from processOneCommand. This shows up as
+                            // a regular POLLIN event in our regular processing loop.
+                            if (connection.isClosedByPeer()) {
+                                connection.closeSocket();
+                                peers.remove(i);
+                                fds.remove(i);
+                            }
+                        }
+                    } catch (Exception e) {
+                        if (!mIsForkChild) {
+                            // We're in the server so any exception here is one that has taken place
+                            // pre-fork while processing commands or reading / writing from the
+                            // control socket. Make a loud noise about any such exceptions so that
+                            // we know exactly what failed and why.
+
+                            Slog.e(TAG, "Exception executing zygote command: ", e);
+
+                            // Make sure the socket is closed so that the other end knows immediately
+                            // that something has gone wrong and doesn't time out waiting for a
+                            // response.
+                            ZygoteConnection conn = peers.remove(i);
+                            conn.closeSocket();
+
+                            fds.remove(i);
+                        } else {
+                            // We're in the child so any exception caught here has happened post
+                            // fork and before we execute ActivityThread.main (or any other main()
+                            // method). Log the details of the exception and bring down the process.
+                            Log.e(TAG, "Caught post-fork exception in child process.", e);
+                            throw e;
+                        }
                     }
                 }
             }
diff --git a/core/java/com/android/internal/os/package.html b/core/java/com/android/internal/os/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/os/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index 3f35c91..69184c3 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -64,6 +64,11 @@
     void onStartedWakingUp();
 
     /**
+     * Called when the device has finished waking up.
+     */
+    void onFinishedWakingUp();
+
+    /**
      * Called when the device screen is turning on.
      */
     void onScreenTurningOn(IKeyguardDrawnCallback callback);
@@ -74,6 +79,11 @@
     void onScreenTurnedOn();
 
     /**
+     * Called when the screen starts turning off.
+     */
+    void onScreenTurningOff();
+
+    /**
      * Called when the screen has turned off.
      */
     void onScreenTurnedOff();
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 8fe9100..544afd9 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -3103,12 +3103,29 @@
     }
 
     /**
+     * Check if Setup or Post-Setup update is completed on TV
+     * @return true if completed
+     */
+    private boolean isTvUserSetupComplete() {
+        boolean isTvSetupComplete = Settings.Secure.getInt(getContext().getContentResolver(),
+                Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
+        isTvSetupComplete &= Settings.Secure.getInt(getContext().getContentResolver(),
+                Settings.Secure.TV_USER_SETUP_COMPLETE, 0) != 0;
+        return isTvSetupComplete;
+    }
+
+    /**
      * Helper method for adding launch-search to most applications. Opens the
      * search window using default settings.
      *
      * @return true if search window opened
      */
     private boolean launchDefaultSearch(KeyEvent event) {
+        if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)
+                && !isTvUserSetupComplete()) {
+            // If we are in Setup or Post-Setup update mode on TV, consume the search key
+            return false;
+        }
         boolean result;
         final Callback cb = getCallback();
         if (cb == null || isDestroyed()) {
diff --git a/core/java/com/android/internal/policy/PipSnapAlgorithm.java b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
index 95d714f..749d00c1 100644
--- a/core/java/com/android/internal/policy/PipSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
@@ -49,9 +49,6 @@
     // Allows snapping on the long edge in each orientation and magnets towards corners
     private static final int SNAP_MODE_LONG_EDGE_MAGNET_CORNERS = 4;
 
-    // The friction multiplier to control how slippery the PIP is when flung
-    private static final float SCROLL_FRICTION_MULTIPLIER = 8f;
-
     // Threshold to magnet to a corner
     private static final float CORNER_MAGNET_THRESHOLD = 0.3f;
 
@@ -64,8 +61,8 @@
     private final float mDefaultSizePercent;
     private final float mMinAspectRatioForMinSize;
     private final float mMaxAspectRatioForMinSize;
+    private final int mFlingDeceleration;
 
-    private Scroller mScroller;
     private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
 
     private final int mMinimizedVisibleSize;
@@ -81,6 +78,8 @@
         mMaxAspectRatioForMinSize = res.getFloat(
                 com.android.internal.R.dimen.config_pictureInPictureAspectRatioLimitForMinSize);
         mMinAspectRatioForMinSize = 1f / mMaxAspectRatioForMinSize;
+        mFlingDeceleration = mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.pip_fling_deceleration);
         onConfigurationChanged();
     }
 
@@ -107,20 +106,97 @@
      * those for the given {@param stackBounds}.
      */
     public Rect findClosestSnapBounds(Rect movementBounds, Rect stackBounds, float velocityX,
-            float velocityY) {
-        final Rect finalStackBounds = new Rect(stackBounds);
-        if (mScroller == null) {
-            final ViewConfiguration viewConfig = ViewConfiguration.get(mContext);
-            mScroller = new Scroller(mContext);
-            mScroller.setFriction(viewConfig.getScrollFriction() * SCROLL_FRICTION_MULTIPLIER);
+            float velocityY, Point dragStartPosition) {
+        final Rect intersectStackBounds = new Rect(stackBounds);
+        final Point intersect = getEdgeIntersect(stackBounds, movementBounds, velocityX, velocityY,
+                dragStartPosition);
+        intersectStackBounds.offsetTo(intersect.x, intersect.y);
+        return findClosestSnapBounds(movementBounds, intersectStackBounds);
+    }
+
+    /**
+     * @return The point along the {@param movementBounds} that the PIP would intersect with based
+     *         on the provided {@param velX}, {@param velY} along with the position of the PIP when
+     *         the gesture started, {@param dragStartPosition}.
+     */
+    public Point getEdgeIntersect(Rect stackBounds, Rect movementBounds, float velX, float velY,
+            Point dragStartPosition) {
+        final boolean isLandscape = mOrientation == Configuration.ORIENTATION_LANDSCAPE;
+        final int x = stackBounds.left;
+        final int y = stackBounds.top;
+
+        // Find the line of movement the PIP is on. Line defined by: y = slope * x + yIntercept
+        final float slope = velY / velX; // slope = rise / run
+        final float yIntercept = y - slope * x; // rearrange line equation for yIntercept
+        // The PIP can have two intercept points:
+        // 1) Where the line intersects with one of the edges of the screen (vertical line)
+        Point vertPoint = new Point();
+        // 2) Where the line intersects with the top or bottom of the screen (horizontal line)
+        Point horizPoint = new Point();
+
+        // Find the vertical line intersection, x will be one of the edges
+        vertPoint.x = velX > 0 ? movementBounds.right : movementBounds.left;
+        // Sub in x in our line equation to determine y position
+        vertPoint.y = findY(slope, yIntercept, vertPoint.x);
+
+        // Find the horizontal line intersection, y will be the top or bottom of the screen
+        horizPoint.y = velY > 0 ? movementBounds.bottom : movementBounds.top;
+        // Sub in y in our line equation to determine x position
+        horizPoint.x = findX(slope, yIntercept, horizPoint.y);
+
+        // Now pick one of these points -- first determine if we're flinging along the current edge.
+        // Only fling along current edge if it's a direction with space for the PIP to move to
+        int maxDistance;
+        if (isLandscape) {
+            maxDistance = velX > 0
+                    ? movementBounds.right - stackBounds.left
+                    : stackBounds.left - movementBounds.left;
+        } else {
+            maxDistance = velY > 0
+                    ? movementBounds.bottom - stackBounds.top
+                    : stackBounds.top - movementBounds.top;
         }
-        mScroller.fling(stackBounds.left, stackBounds.top,
-                (int) velocityX, (int) velocityY,
-                movementBounds.left, movementBounds.right,
-                movementBounds.top, movementBounds.bottom);
-        finalStackBounds.offsetTo(mScroller.getFinalX(), mScroller.getFinalY());
-        mScroller.abortAnimation();
-        return findClosestSnapBounds(movementBounds, finalStackBounds);
+        if (maxDistance > 0) {
+            // Only fling along the current edge if the start and end point are on the same side
+            final int startPoint = isLandscape ? dragStartPosition.y : dragStartPosition.x;
+            final int endPoint = isLandscape ? horizPoint.y : horizPoint.x;
+            final int center = movementBounds.centerX();
+            if ((startPoint < center && endPoint < center)
+                    || (startPoint > center && endPoint > center)) {
+                // We are flinging along the current edge, figure out how far it should travel
+                // based on velocity and assumed deceleration.
+                int distance = (int) (0 - Math.pow(isLandscape ? velX : velY, 2))
+                        / (2 * mFlingDeceleration);
+                distance = Math.min(distance, maxDistance);
+                // Adjust the point for the distance
+                if (isLandscape) {
+                    horizPoint.x = stackBounds.left + (velX > 0 ? distance : -distance);
+                } else {
+                    horizPoint.y = stackBounds.top + (velY > 0 ? distance : -distance);
+                }
+                return horizPoint;
+            }
+        }
+        // If we're not flinging along the current edge, find the closest point instead.
+        final double distanceVert = Math.hypot(vertPoint.x - x, vertPoint.y - y);
+        final double distanceHoriz = Math.hypot(horizPoint.x - x, horizPoint.y - y);
+        // Ensure that we're actually going somewhere
+        if (distanceVert == 0) {
+            return horizPoint;
+        }
+        if (distanceHoriz == 0) {
+            return vertPoint;
+        }
+        // Otherwise use the closest point
+        return Math.abs(distanceVert) > Math.abs(distanceHoriz) ? horizPoint : vertPoint;
+    }
+
+    private int findY(float slope, float yIntercept, float x) {
+        return (int) ((slope * x) + yIntercept);
+    }
+
+    private int findX(float slope, float yIntercept, float y) {
+        return (int) ((y - yIntercept) / slope);
     }
 
     /**
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 7d9538f..6f54b0c 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -114,5 +114,7 @@
     void addQsTile(in ComponentName tile);
     void remQsTile(in ComponentName tile);
     void clickQsTile(in ComponentName tile);
-    void handleSystemNavigationKey(in int key);
+    void handleSystemKey(in int key);
+
+    void showShutdownUi(boolean isReboot, String reason);
 }
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 20db499..22eef07 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -75,5 +75,5 @@
     void addTile(in ComponentName tile);
     void remTile(in ComponentName tile);
     void clickTile(in ComponentName tile);
-    void handleSystemNavigationKey(in int key);
+    void handleSystemKey(in int key);
 }
diff --git a/core/java/com/android/internal/statusbar/package.html b/core/java/com/android/internal/statusbar/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/util/BitUtils.java b/core/java/com/android/internal/util/BitUtils.java
index 1b354d0..ba80aea 100644
--- a/core/java/com/android/internal/util/BitUtils.java
+++ b/core/java/com/android/internal/util/BitUtils.java
@@ -18,12 +18,14 @@
 package com.android.internal.util;
 
 import android.annotation.Nullable;
+import android.text.TextUtils;
 
 import libcore.util.Objects;
 
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.UUID;
+import java.util.function.IntFunction;
 
 /**
  * A utility class for handling unsigned integers and unsigned arithmetics, as well as syntactic
@@ -91,6 +93,10 @@
         return s & 0xffff;
     }
 
+    public static int uint16(byte hi, byte lo) {
+        return ((hi & 0xff) << 8) | (lo & 0xff);
+    }
+
     public static long uint32(int i) {
         return i & 0xffffffffL;
     }
@@ -124,4 +130,26 @@
         buffer.put(bytes);
         buffer.position(original);
     }
+
+    public static boolean isBitSet(long flags, int bitIndex) {
+        return (flags & bitAt(bitIndex)) != 0;
+    }
+
+    public static long bitAt(int bitIndex) {
+        return 1L << bitIndex;
+    }
+
+    public static String flagsToString(int flags, IntFunction<String> getFlagName) {
+        StringBuilder builder = new StringBuilder();
+        int count = 0;
+        while (flags != 0) {
+            final int flag = 1 << Integer.numberOfTrailingZeros(flags);
+            flags &= ~flag;
+            if (count > 0) builder.append(", ");
+            builder.append(getFlagName.apply(flag));
+            count++;
+        }
+        TextUtils.wrap(builder, "[", "]");
+        return builder.toString();
+    }
 }
diff --git a/core/java/com/android/internal/util/RingBuffer.java b/core/java/com/android/internal/util/RingBuffer.java
new file mode 100644
index 0000000..ad84353
--- /dev/null
+++ b/core/java/com/android/internal/util/RingBuffer.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import static com.android.internal.util.Preconditions.checkArgumentPositive;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+
+/**
+ * A simple ring buffer structure with bounded capacity backed by an array.
+ * Events can always be added at the logical end of the buffer. If the buffer is
+ * full, oldest events are dropped when new events are added.
+ * {@hide}
+ */
+public class RingBuffer<T> {
+
+    // Array for storing events.
+    private final T[] mBuffer;
+    // Cursor keeping track of the logical end of the array. This cursor never
+    // wraps and instead keeps track of the total number of append() operations.
+    private long mCursor = 0;
+
+    public RingBuffer(Class<T> c, int capacity) {
+        checkArgumentPositive(capacity, "A RingBuffer cannot have 0 capacity");
+        // Java cannot create generic arrays without a runtime hint.
+        mBuffer = (T[]) Array.newInstance(c, capacity);
+    }
+
+    public int size() {
+        return (int) Math.min(mBuffer.length, (long) mCursor);
+    }
+
+    public void append(T t) {
+        mBuffer[indexOf(mCursor++)] = t;
+    }
+
+    public T[] toArray() {
+        // Only generic way to create a T[] from another T[]
+        T[] out = Arrays.copyOf(mBuffer, size(), (Class<T[]>) mBuffer.getClass());
+        // Reverse iteration from youngest event to oldest event.
+        long inCursor = mCursor - 1;
+        int outIdx = out.length - 1;
+        while (outIdx >= 0) {
+            out[outIdx--] = (T) mBuffer[indexOf(inCursor--)];
+        }
+        return out;
+    }
+
+    private int indexOf(long cursor) {
+        return (int) Math.abs(cursor % mBuffer.length);
+    }
+}
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 8d9630f..e5ad1f4 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -804,7 +804,7 @@
 
                 /** State that processed the message */
                 State msgProcessedState = null;
-                if (mIsConstructionCompleted) {
+                if (mIsConstructionCompleted || (mMsg.what == SM_QUIT_CMD)) {
                     /** Normal path */
                     msgProcessedState = processMsg(msg);
                 } else if (!mIsConstructionCompleted && (mMsg.what == SM_INIT_CMD)
diff --git a/core/java/com/android/internal/util/WakeupMessage.java b/core/java/com/android/internal/util/WakeupMessage.java
index 46098c5..70b6f96 100644
--- a/core/java/com/android/internal/util/WakeupMessage.java
+++ b/core/java/com/android/internal/util/WakeupMessage.java
@@ -47,17 +47,19 @@
     protected final int mCmd, mArg1, mArg2;
     @VisibleForTesting
     protected final Object mObj;
+    private final Runnable mRunnable;
     private boolean mScheduled;
 
     public WakeupMessage(Context context, Handler handler,
             String cmdName, int cmd, int arg1, int arg2, Object obj) {
-        mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+        mAlarmManager = getAlarmManager(context);
         mHandler = handler;
         mCmdName = cmdName;
         mCmd = cmd;
         mArg1 = arg1;
         mArg2 = arg2;
         mObj = obj;
+        mRunnable = null;
     }
 
     public WakeupMessage(Context context, Handler handler, String cmdName, int cmd, int arg1) {
@@ -73,6 +75,21 @@
         this(context, handler, cmdName, cmd, 0, 0, null);
     }
 
+    public WakeupMessage(Context context, Handler handler, String cmdName, Runnable runnable) {
+        mAlarmManager = getAlarmManager(context);
+        mHandler = handler;
+        mCmdName = cmdName;
+        mCmd = 0;
+        mArg1 = 0;
+        mArg2 = 0;
+        mObj = null;
+        mRunnable = runnable;
+    }
+
+    private static AlarmManager getAlarmManager(Context context) {
+        return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+    }
+
     /**
      * Schedule the message to be delivered at the time in milliseconds of the
      * {@link android.os.SystemClock#elapsedRealtime SystemClock.elapsedRealtime()} clock and wakeup
@@ -107,7 +124,12 @@
             mScheduled = false;
         }
         if (stillScheduled) {
-            Message msg = mHandler.obtainMessage(mCmd, mArg1, mArg2, mObj);
+            Message msg;
+            if (mRunnable == null) {
+                msg = mHandler.obtainMessage(mCmd, mArg1, mArg2, mObj);
+            } else {
+                msg = Message.obtain(mHandler, mRunnable);
+            }
             mHandler.dispatchMessage(msg);
             msg.recycle();
         }
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index b8c062e..ee16ab6 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -28,7 +28,7 @@
     boolean getBoolean(in String key, in boolean defaultValue, in int userId);
     long getLong(in String key, in long defaultValue, in int userId);
     String getString(in String key, in String defaultValue, in int userId);
-    void setLockCredential(in String credential, int type, in String savedCredential, int userId);
+    void setLockCredential(in String credential, int type, in String savedCredential, int requestedQuality, int userId);
     void resetKeyStore(int userId);
     VerifyCredentialResponse checkCredential(in String credential, int type, int userId,
             in ICheckCredentialProgressCallback progressCallback);
@@ -49,6 +49,7 @@
     long addEscrowToken(in byte[] token, int userId);
     boolean removeEscrowToken(long handle, int userId);
     boolean isEscrowTokenActive(long handle, int userId);
-    boolean setLockCredentialWithToken(String credential, int type, long tokenHandle, in byte[] token, int userId);
+    boolean setLockCredentialWithToken(String credential, int type, long tokenHandle,
+            in byte[] token, int requestedQuality, int userId);
     void unlockUserWithToken(long tokenHandle, in byte[] token, int userId);
 }
diff --git a/core/java/com/android/internal/widget/ImageFloatingTextView.java b/core/java/com/android/internal/widget/ImageFloatingTextView.java
index 6b53368..31b167d 100644
--- a/core/java/com/android/internal/widget/ImageFloatingTextView.java
+++ b/core/java/com/android/internal/widget/ImageFloatingTextView.java
@@ -22,6 +22,7 @@
 import android.text.Layout;
 import android.text.StaticLayout;
 import android.text.TextUtils;
+import android.text.method.TransformationMethod;
 import android.util.AttributeSet;
 import android.view.RemotableViewMethod;
 import android.widget.RemoteViews;
@@ -68,7 +69,12 @@
     protected Layout makeSingleLayout(int wantWidth, BoringLayout.Metrics boring, int ellipsisWidth,
             Layout.Alignment alignment, boolean shouldEllipsize,
             TextUtils.TruncateAt effectiveEllipsize, boolean useSaved) {
-        CharSequence text = getText() == null ? "" : getText();
+        TransformationMethod transformationMethod = getTransformationMethod();
+        CharSequence text = getText();
+        if (transformationMethod != null) {
+            text = transformationMethod.getTransformation(text, this);
+        }
+        text = text == null ? "" : text;
         StaticLayout.Builder builder = StaticLayout.Builder.obtain(text, 0, text.length(),
                 getPaint(), wantWidth)
                 .setAlignment(alignment)
diff --git a/core/java/com/android/internal/widget/LinearLayoutManager.java b/core/java/com/android/internal/widget/LinearLayoutManager.java
index d82c746..0000a74 100644
--- a/core/java/com/android/internal/widget/LinearLayoutManager.java
+++ b/core/java/com/android/internal/widget/LinearLayoutManager.java
@@ -168,10 +168,6 @@
     /**
      * Constructor used when layout manager is set in XML by RecyclerView attribute
      * "layoutManager". Defaults to vertical orientation.
-     *
-     * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_android_orientation
-     * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_reverseLayout
-     * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_stackFromEnd
      */
     public LinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 0aba9c2..53a9654 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -27,6 +27,7 @@
 import android.content.Context;
 import android.content.pm.UserInfo;
 import android.os.AsyncTask;
+import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -34,6 +35,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.IStorageManager;
@@ -65,6 +67,8 @@
 
     private static final String TAG = "LockPatternUtils";
     private static final boolean DEBUG = false;
+    private static final boolean FRP_CREDENTIAL_ENABLED =
+            Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.frpcredential.enable", false);
 
     /**
      * The key to identify when the lock pattern enabled flag is being accessed for legacy reasons.
@@ -112,6 +116,11 @@
 
     public static final int CREDENTIAL_TYPE_PASSWORD = 2;
 
+    /**
+     * Special user id for triggering the FRP verification flow.
+     */
+    public static final int USER_FRP = UserHandle.USER_NULL + 1;
+
     @Deprecated
     public final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
     public final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
@@ -295,24 +304,39 @@
     }
 
     public void reportFailedPasswordAttempt(int userId) {
+        if (userId == USER_FRP && frpCredentialEnabled()) {
+            return;
+        }
         getDevicePolicyManager().reportFailedPasswordAttempt(userId);
         getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
     }
 
     public void reportSuccessfulPasswordAttempt(int userId) {
+        if (userId == USER_FRP && frpCredentialEnabled()) {
+            return;
+        }
         getDevicePolicyManager().reportSuccessfulPasswordAttempt(userId);
         getTrustManager().reportUnlockAttempt(true /* authenticated */, userId);
     }
 
     public void reportPasswordLockout(int timeoutMs, int userId) {
+        if (userId == USER_FRP && frpCredentialEnabled()) {
+            return;
+        }
         getTrustManager().reportUnlockLockout(timeoutMs, userId);
     }
 
     public int getCurrentFailedPasswordAttempts(int userId) {
+        if (userId == USER_FRP && frpCredentialEnabled()) {
+            return 0;
+        }
         return getDevicePolicyManager().getCurrentFailedPasswordAttempts(userId);
     }
 
     public int getMaximumFailedPasswordsForWipe(int userId) {
+        if (userId == USER_FRP && frpCredentialEnabled()) {
+            return 0;
+        }
         return getDevicePolicyManager().getMaximumFailedPasswordsForWipe(
                 null /* componentName */, userId);
     }
@@ -539,6 +563,14 @@
     }
 
     /**
+     * Records that the user has chosen a pattern at some time, even if the pattern is
+     * currently cleared.
+     */
+    public void reportPatternWasChosen(int userId) {
+        setBoolean(PATTERN_EVER_CHOSEN_KEY, true, userId);
+    }
+
+    /**
      * Used by device policy manager to validate the current password
      * information it has.
      */
@@ -578,7 +610,7 @@
 
         try{
             getLockSettings().setLockCredential(null, CREDENTIAL_TYPE_NONE, savedCredential,
-                    userHandle);
+                    DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle);
         } catch (RemoteException e) {
             // well, we tried...
         }
@@ -616,8 +648,12 @@
         boolean disabledByDefault = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_disableLockscreenByDefault);
         boolean isSystemUser = UserManager.isSplitSystemUser() && userId == UserHandle.USER_SYSTEM;
+        UserInfo userInfo = getUserManager().getUserInfo(userId);
+        boolean isDemoUser = UserManager.isDeviceInDemoMode(mContext) && userInfo != null
+                && userInfo.isDemo();
         return getBoolean(DISABLE_LOCKSCREEN_KEY, false, userId)
-                || (disabledByDefault && !isSystemUser);
+                || (disabledByDefault && !isSystemUser)
+                || isDemoUser;
     }
 
     /**
@@ -643,7 +679,7 @@
 
             setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId);
             getLockSettings().setLockCredential(patternToString(pattern), CREDENTIAL_TYPE_PATTERN,
-                    savedPattern, userId);
+                    savedPattern, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId);
 
             // Update the device encryption password.
             if (userId == UserHandle.USER_SYSTEM
@@ -656,7 +692,7 @@
                 }
             }
 
-            setBoolean(PATTERN_EVER_CHOSEN_KEY, true, userId);
+            reportPatternWasChosen(userId);
             onAfterChangingPassword(userId);
         } catch (RemoteException re) {
             Log.e(TAG, "Couldn't save lock pattern " + re);
@@ -757,10 +793,10 @@
      * password.
      * @param password The password to save
      * @param savedPassword The previously saved lock password, or null if none
-     * @param quality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
+     * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
      * @param userHandle The userId of the user to change the password for
      */
-    public void saveLockPassword(String password, String savedPassword, int quality,
+    public void saveLockPassword(String password, String savedPassword, int requestedQuality,
             int userHandle) {
         try {
             if (password == null || password.length() < MIN_LOCK_PASSWORD_SIZE) {
@@ -769,9 +805,9 @@
             }
 
             final int computedQuality = PasswordMetrics.computeForPassword(password).quality;
-            setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality), userHandle);
+            setLong(PASSWORD_TYPE_KEY, Math.max(requestedQuality, computedQuality), userHandle);
             getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword,
-                    userHandle);
+                    requestedQuality, userHandle);
 
             updateEncryptionPasswordIfNeeded(password, computedQuality, userHandle);
             updatePasswordHistory(password, userHandle);
@@ -1125,6 +1161,10 @@
         }
     }
 
+    public boolean isVisiblePatternEverChosen(int userId) {
+        return getString(Settings.Secure.LOCK_PATTERN_VISIBLE, userId) != null;
+    }
+
     /**
      * Set whether the visible password is enabled for cryptkeeper screen.
      */
@@ -1252,6 +1292,10 @@
         return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true, userId);
     }
 
+    public boolean isPowerButtonInstantlyLocksEverChosen(int userId) {
+        return getString(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, userId) != null;
+    }
+
     public void setEnabledTrustAgents(Collection<ComponentName> activeTrustAgents, int userId) {
         StringBuilder sb = new StringBuilder();
         for (ComponentName cn : activeTrustAgents) {
@@ -1458,12 +1502,13 @@
                 }
 
                 final int computedQuality = PasswordMetrics.computeForPassword(credential).quality;
+                int quality = Math.max(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
+                        computedQuality);
                 if (!getLockSettings().setLockCredentialWithToken(credential, type, tokenHandle,
-                        token, userId)) {
+                        token, quality, userId)) {
                     return false;
                 }
-                setLong(PASSWORD_TYPE_KEY, Math.max(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
-                        computedQuality), userId);
+                setLong(PASSWORD_TYPE_KEY, quality, userId);
 
                 updateEncryptionPasswordIfNeeded(credential, computedQuality, userId);
                 updatePasswordHistory(credential, userId);
@@ -1472,7 +1517,8 @@
                     throw new IllegalArgumentException("password must be emtpy for NONE type");
                 }
                 if (!getLockSettings().setLockCredentialWithToken(null, CREDENTIAL_TYPE_NONE,
-                        tokenHandle, token, userId)) {
+                        tokenHandle, token, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+                        userId)) {
                     return false;
                 }
                 setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
@@ -1672,7 +1718,19 @@
         setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1L, UserHandle.USER_SYSTEM);
     }
 
+    public void disableSyntheticPassword() {
+        setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0L, UserHandle.USER_SYSTEM);
+    }
+
     public boolean isSyntheticPasswordEnabled() {
         return getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM) != 0;
     }
+
+    public static boolean userOwnsFrpCredential(UserInfo info) {
+        return info != null && info.isPrimary() && info.isAdmin() && frpCredentialEnabled();
+    }
+
+    public static boolean frpCredentialEnabled() {
+        return FRP_CREDENTIAL_ENABLED;
+    }
 }
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index cc1c65e..32a7a2d 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -39,6 +39,7 @@
 import android.util.AttributeSet;
 import android.util.IntArray;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.DisplayListCanvas;
 import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
@@ -54,7 +55,6 @@
 import com.android.internal.R;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -1340,8 +1340,7 @@
 
     private final class PatternExploreByTouchHelper extends ExploreByTouchHelper {
         private Rect mTempRect = new Rect();
-        private HashMap<Integer, VirtualViewContainer> mItems = new HashMap<Integer,
-                VirtualViewContainer>();
+        private final SparseArray<VirtualViewContainer> mItems = new SparseArray<>();
 
         class VirtualViewContainer {
             public VirtualViewContainer(CharSequence description) {
@@ -1352,6 +1351,9 @@
 
         public PatternExploreByTouchHelper(View forView) {
             super(forView);
+            for (int i = VIRTUAL_BASE_VIEW_ID; i < VIRTUAL_BASE_VIEW_ID + 9; i++) {
+                mItems.put(i, new VirtualViewContainer(getTextForVirtualView(i)));
+            }
         }
 
         @Override
@@ -1369,10 +1371,6 @@
                 return;
             }
             for (int i = VIRTUAL_BASE_VIEW_ID; i < VIRTUAL_BASE_VIEW_ID + 9; i++) {
-                if (!mItems.containsKey(i)) {
-                    VirtualViewContainer item = new VirtualViewContainer(getTextForVirtualView(i));
-                    mItems.put(i, item);
-                }
                 // Add all views. As views are added to the pattern, we remove them
                 // from notification by making them non-clickable below.
                 virtualViewIds.add(i);
@@ -1383,9 +1381,9 @@
         protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
             if (DEBUG_A11Y) Log.v(TAG, "onPopulateEventForVirtualView(" + virtualViewId + ")");
             // Announce this view
-            if (mItems.containsKey(virtualViewId)) {
-                CharSequence contentDescription = mItems.get(virtualViewId).description;
-                event.getText().add(contentDescription);
+            VirtualViewContainer container = mItems.get(virtualViewId);
+            if (container != null) {
+                event.getText().add(container.description);
             }
         }
 
diff --git a/core/java/com/android/internal/widget/MediaNotificationView.java b/core/java/com/android/internal/widget/MediaNotificationView.java
index bbebcc2..7609b67 100644
--- a/core/java/com/android/internal/widget/MediaNotificationView.java
+++ b/core/java/com/android/internal/widget/MediaNotificationView.java
@@ -33,13 +33,13 @@
 @RemoteViews.RemoteView
 public class MediaNotificationView extends FrameLayout {
 
-    private final int mSmallImageSize;
     private final int mNotificationContentMarginEnd;
     private final int mNotificationContentImageMarginEnd;
     private ImageView mRightIcon;
     private View mActions;
     private View mHeader;
     private View mMainColumn;
+    private int mImagePushIn;
 
     public MediaNotificationView(Context context) {
         this(context, null);
@@ -62,6 +62,7 @@
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         int mode = MeasureSpec.getMode(widthMeasureSpec);
         boolean reMeasure = false;
+        mImagePushIn = 0;
         if (hasIcon && mode != MeasureSpec.UNSPECIFIED) {
             int size = MeasureSpec.getSize(widthMeasureSpec);
             size = size - mActions.getMeasuredWidth();
@@ -70,14 +71,15 @@
             int imageEndMargin = layoutParams.getMarginEnd();
             size -= imageEndMargin;
             int fullHeight = getMeasuredHeight();
-            if (size < fullHeight) {
-                size = mSmallImageSize;
-            } else {
+            if (size > fullHeight) {
                 size = fullHeight;
+            } else if (size < fullHeight) {
+                size = Math.max(0, size);
+                mImagePushIn = fullHeight - size;
             }
-            if (layoutParams.width != size || layoutParams.height != size) {
-                layoutParams.width = size;
-                layoutParams.height = size;
+            if (layoutParams.width != fullHeight || layoutParams.height != fullHeight) {
+                layoutParams.width = fullHeight;
+                layoutParams.height = fullHeight;
                 mRightIcon.setLayoutParams(layoutParams);
                 reMeasure = true;
             }
@@ -111,6 +113,15 @@
         }
     }
 
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        if (mImagePushIn > 0) {
+            mRightIcon.layout(mRightIcon.getLeft() + mImagePushIn, mRightIcon.getTop(),
+                    mRightIcon.getRight()  + mImagePushIn, mRightIcon.getBottom());
+        }
+    }
+
     private void resetHeaderIndention() {
         if (mHeader.getPaddingEnd() != mNotificationContentMarginEnd) {
             mHeader.setPaddingRelative(mHeader.getPaddingStart(),
@@ -130,8 +141,6 @@
     public MediaNotificationView(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        mSmallImageSize = context.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.media_notification_expanded_image_small_size);
         mNotificationContentMarginEnd = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.notification_content_margin_end);
         mNotificationContentImageMarginEnd = context.getResources().getDimensionPixelSize(
diff --git a/core/java/com/android/internal/widget/VerifyCredentialResponse.java b/core/java/com/android/internal/widget/VerifyCredentialResponse.java
index 48109ca..ad6020c 100644
--- a/core/java/com/android/internal/widget/VerifyCredentialResponse.java
+++ b/core/java/com/android/internal/widget/VerifyCredentialResponse.java
@@ -18,6 +18,8 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.service.gatekeeper.GateKeeperResponse;
+import android.util.Slog;
 
 /**
  * Response object for a ILockSettings credential verification request.
@@ -32,6 +34,7 @@
     public static final VerifyCredentialResponse OK = new VerifyCredentialResponse();
     public static final VerifyCredentialResponse ERROR
             = new VerifyCredentialResponse(RESPONSE_ERROR, 0, null);
+    private static final String TAG = "VerifyCredentialResponse";
 
     private int mResponseCode;
     private byte[] mPayload;
@@ -123,4 +126,29 @@
     private void setPayload(byte[] payload) {
         mPayload = payload;
     }
+
+    public VerifyCredentialResponse stripPayload() {
+        return new VerifyCredentialResponse(mResponseCode, mTimeout, new byte[0]);
+    }
+
+    public static VerifyCredentialResponse fromGateKeeperResponse(
+            GateKeeperResponse gateKeeperResponse) {
+        VerifyCredentialResponse response;
+        int responseCode = gateKeeperResponse.getResponseCode();
+        if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
+            response = new VerifyCredentialResponse(gateKeeperResponse.getTimeout());
+        } else if (responseCode == GateKeeperResponse.RESPONSE_OK) {
+            byte[] token = gateKeeperResponse.getPayload();
+            if (token == null) {
+                // something's wrong if there's no payload with a challenge
+                Slog.e(TAG, "verifyChallenge response had no associated payload");
+                response = VerifyCredentialResponse.ERROR;
+            } else {
+                response = new VerifyCredentialResponse(token);
+            }
+        } else {
+            response = VerifyCredentialResponse.ERROR;
+        }
+        return response;
+    }
 }
diff --git a/core/java/com/android/internal/widget/package.html b/core/java/com/android/internal/widget/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/widget/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/server/BootReceiver.java b/core/java/com/android/server/BootReceiver.java
index 37d0991..18990cf 100644
--- a/core/java/com/android/server/BootReceiver.java
+++ b/core/java/com/android/server/BootReceiver.java
@@ -143,7 +143,6 @@
         try {
             return FileUtils.readTextFile(lastHeaderFile, 0, null);
         } catch (IOException e) {
-            Slog.e(TAG, "Error reading " + lastHeaderFile, e);
             return null;
         }
     }
@@ -444,6 +443,7 @@
             String currentPass = "";
             boolean foundTreeOptimization = false;
             boolean foundQuotaFix = false;
+            boolean foundTimestampAdjustment = false;
             boolean foundOtherFix = false;
             String otherFixLine = null;
             for (int i = startLineNumber; i < endLineNumber; i++) {
@@ -476,6 +476,16 @@
                     }
                 } else if (line.startsWith("Update quota info") && currentPass.equals("5")) {
                     // follows "[QUOTA WARNING]", ignore
+                } else if (line.startsWith("Timestamp(s) on inode") &&
+                        line.contains("beyond 2310-04-04 are likely pre-1970") &&
+                        currentPass.equals("1")) {
+                    Slog.i(TAG, "fs_stat, partition:" + partition + " found timestamp adjustment:"
+                            + line);
+                    // followed by next line, "Fix? yes"
+                    if (lines[i + 1].contains("Fix? yes")) {
+                        i++;
+                    }
+                    foundTimestampAdjustment = true;
                 } else {
                     line = line.trim();
                     // ignore empty msg or any msg before Pass 1
@@ -486,15 +496,17 @@
                     }
                 }
             }
-            if (!foundOtherFix && foundTreeOptimization && foundQuotaFix) {
-                // not a real fix, so clear it.
-                Slog.i(TAG, "fs_stat, partition:" + partition +
-                        " quota fix due to tree optimization");
-                stat &= ~FS_STAT_FS_FIXED;
-            } else {
+            if (foundOtherFix) {
                 if (otherFixLine != null) {
                     Slog.i(TAG, "fs_stat, partition:" + partition + " fix:" + otherFixLine);
                 }
+            } else if (foundQuotaFix && !foundTreeOptimization) {
+                Slog.i(TAG, "fs_stat, got quota fix without tree optimization, partition:" +
+                        partition);
+            } else if ((foundTreeOptimization && foundQuotaFix) || foundTimestampAdjustment) {
+                // not a real fix, so clear it.
+                Slog.i(TAG, "fs_stat, partition:" + partition + " fix ignored");
+                stat &= ~FS_STAT_FS_FIXED;
             }
         }
         return stat;
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index abd6278..bc86ddd 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -18,10 +18,6 @@
         "-Wunused",
         "-Wunreachable-code",
 
-        // necessary for Clang as the GL bindings need to turn
-        // off a GCC warning that Clang doesn't know.
-        "-Wno-unknown-pragmas",
-
         // TODO: Linear blending should be enabled by default, but we are
         // TODO: making it an opt-in while it's a work in progress
         //"-DANDROID_ENABLE_LINEAR_BLENDING",
@@ -188,6 +184,7 @@
         "com_android_internal_os_FuseAppLoop.cpp",
         "com_android_internal_os_PathClassLoaderFactory.cpp",
         "com_android_internal_os_Zygote.cpp",
+        "com_android_internal_os_ZygoteInit.cpp",
         "com_android_internal_util_VirtualRefBasePtr.cpp",
         "com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp",
         "hwbinder/EphemeralStorage.cpp",
@@ -231,6 +228,7 @@
         "libutils",
         "libbinder",
         "libui",
+        "libgraphicsenv",
         "libgui",
         "libsensor",
         "libinput",
@@ -290,13 +288,4 @@
         // GraphicsJNI.h includes hwui headers
         "libhwui",
     ],
-
-    product_variables: {
-        debuggable: {
-            cflags: ["-D__ANDROID_DEBUGGABLE__"]
-        },
-        treble: {
-            cflags: ["-D__ANDROID_TREBLE__"]
-        },
-    },
 }
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 6d5d71c..8b6fc59 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -19,6 +19,8 @@
 #define LOG_NDEBUG 1
 
 #include <android_runtime/AndroidRuntime.h>
+
+#include <android-base/properties.h>
 #include <binder/IBinder.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -47,8 +49,8 @@
 #include <string>
 #include <vector>
 
-
 using namespace android;
+using android::base::GetProperty;
 
 extern int register_android_os_Binder(JNIEnv* env);
 extern int register_android_os_Process(JNIEnv* env);
@@ -206,6 +208,7 @@
 extern int register_com_android_internal_os_FuseAppLoop(JNIEnv* env);
 extern int register_com_android_internal_os_PathClassLoaderFactory(JNIEnv* env);
 extern int register_com_android_internal_os_Zygote(JNIEnv *env);
+extern int register_com_android_internal_os_ZygoteInit(JNIEnv *env);
 extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
 
 static AndroidRuntime* gCurRuntime = NULL;
@@ -245,7 +248,7 @@
         methods, NELEM(methods));
 }
 
-int register_com_android_internal_os_ZygoteInit(JNIEnv* env)
+int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
 {
     const JNINativeMethod methods[] = {
         { "nativeZygoteInit", "()V",
@@ -265,8 +268,6 @@
         mArgBlockLength(argBlockLength)
 {
     SkGraphics::Init();
-    // There is also a global font cache, but its budget is specified by
-    // SK_DEFAULT_FONT_CACHE_COUNT_LIMIT and SK_DEFAULT_FONT_CACHE_LIMIT.
 
     // Pre-allocate enough space to hold a fair number of options.
     mOptions.setCapacity(20);
@@ -277,7 +278,6 @@
 
 AndroidRuntime::~AndroidRuntime()
 {
-    SkGraphics::Term();
 }
 
 /*
@@ -392,17 +392,6 @@
     return false;
 }
 
-// Convenience wrapper over the property API that returns an
-// std::string.
-std::string getProperty(const char* key, const char* defaultValue) {
-    std::vector<char> temp(PROPERTY_VALUE_MAX);
-    const int len = property_get(key, &temp[0], defaultValue);
-    if (len < 0) {
-        return "";
-    }
-    return std::string(&temp[0], len);
-}
-
 /*
  * Read the persistent locale. Inspects the following system properties
  * (in order) and returns the first non-empty property in the list :
@@ -419,15 +408,15 @@
  */
 const std::string readLocale()
 {
-    const std::string locale = getProperty("persist.sys.locale", "");
+    const std::string locale = GetProperty("persist.sys.locale", "");
     if (!locale.empty()) {
         return locale;
     }
 
-    const std::string language = getProperty("persist.sys.language", "");
+    const std::string language = GetProperty("persist.sys.language", "");
     if (!language.empty()) {
-        const std::string country = getProperty("persist.sys.country", "");
-        const std::string variant = getProperty("persist.sys.localevar", "");
+        const std::string country = GetProperty("persist.sys.country", "");
+        const std::string variant = GetProperty("persist.sys.localevar", "");
 
         std::string out = language;
         if (!country.empty()) {
@@ -441,15 +430,15 @@
         return out;
     }
 
-    const std::string productLocale = getProperty("ro.product.locale", "");
+    const std::string productLocale = GetProperty("ro.product.locale", "");
     if (!productLocale.empty()) {
         return productLocale;
     }
 
     // If persist.sys.locale and ro.product.locale are missing,
     // construct a locale value from the individual locale components.
-    const std::string productLanguage = getProperty("ro.product.locale.language", "en");
-    const std::string productRegion = getProperty("ro.product.locale.region", "US");
+    const std::string productLanguage = GetProperty("ro.product.locale.language", "en");
+    const std::string productRegion = GetProperty("ro.product.locale.region", "US");
 
     return productLanguage + "-" + productRegion;
 }
@@ -649,7 +638,7 @@
     char cpuAbiListBuf[sizeof("--cpu-abilist=") + PROPERTY_VALUE_MAX];
     char methodTraceFileBuf[sizeof("-Xmethod-trace-file:") + PROPERTY_VALUE_MAX];
     char methodTraceFileSizeBuf[sizeof("-Xmethod-trace-file-size:") + PROPERTY_VALUE_MAX];
-    char fingerprintBuf[sizeof("-Xfingerprint:") + PROPERTY_VALUE_MAX];
+    std::string fingerprintBuf;
 
     bool checkJni = false;
     property_get("dalvik.vm.checkjni", propBuf, "");
@@ -964,8 +953,15 @@
     /*
      * Retrieve the build fingerprint and provide it to the runtime. That way, ANR dumps will
      * contain the fingerprint and can be parsed.
+     * Fingerprints are potentially longer than PROPERTY_VALUE_MAX, so parseRuntimeOption() cannot
+     * be used here.
+     * Do not ever re-assign fingerprintBuf as its c_str() value is stored in mOptions.
      */
-    parseRuntimeOption("ro.build.fingerprint", fingerprintBuf, "-Xfingerprint:");
+    std::string fingerprint = GetProperty("ro.build.fingerprint", "");
+    if (!fingerprint.empty()) {
+        fingerprintBuf = "-Xfingerprint:" + fingerprint;
+        addOption(fingerprintBuf.c_str());
+    }
 
     initArgs.version = JNI_VERSION_1_4;
     initArgs.options = mOptions.editArray();
@@ -1310,7 +1306,7 @@
 
 static const RegJNIRec gRegJNI[] = {
     REG_JNI(register_com_android_internal_os_RuntimeInit),
-    REG_JNI(register_com_android_internal_os_ZygoteInit),
+    REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
     REG_JNI(register_android_os_SystemClock),
     REG_JNI(register_android_util_EventLog),
     REG_JNI(register_android_util_Log),
@@ -1412,6 +1408,7 @@
     REG_JNI(register_android_os_MemoryFile),
     REG_JNI(register_com_android_internal_os_PathClassLoaderFactory),
     REG_JNI(register_com_android_internal_os_Zygote),
+    REG_JNI(register_com_android_internal_os_ZygoteInit),
     REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
     REG_JNI(register_android_hardware_Camera),
     REG_JNI(register_android_hardware_camera2_CameraMetadata),
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index b171a7e..b03c346 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -278,9 +278,7 @@
     if (!localBitmap->valid()) return nullptr;
 
     SkPixelRef& pixelRef = localBitmap->bitmap();
-    pixelRef.lockPixels();
     if (!pixelRef.pixels()) {
-        pixelRef.unlockPixels();
         return nullptr;
     }
     pixelRef.ref();
@@ -298,7 +296,6 @@
 
     SkPixelRef& pixelRef = localBitmap->bitmap();
     pixelRef.notifyPixelsChanged();
-    pixelRef.unlockPixels();
     pixelRef.unref();
     return true;
 }
@@ -331,11 +328,12 @@
     uint64_t* d = (uint64_t*)dst;
 
     for (int i = 0; i < width; i++) {
-        const float* color = SkColor4f::FromColor(*src++).vec();
+        const SkColor4f color = SkColor4f::FromColor(*src++);
         uint16_t* scratch = reinterpret_cast<uint16_t*>(d++);
-        for (int i = 0; i < 4; ++i) {
-            scratch[i] = SkFloatToHalf(color[i]);
-        }
+        scratch[0] = SkFloatToHalf(color.fR);
+        scratch[1] = SkFloatToHalf(color.fG);
+        scratch[2] = SkFloatToHalf(color.fB);
+        scratch[3] = SkFloatToHalf(color.fA);
     }
 }
 
@@ -438,7 +436,6 @@
 
 bool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int srcStride,
         int x, int y, int width, int height, const SkBitmap& dstBitmap) {
-    SkAutoLockPixels alp(dstBitmap);
     void* dst = dstBitmap.getPixels();
     FromColorProc proc = ChooseFromColorProc(dstBitmap);
 
@@ -755,31 +752,54 @@
 
 static bool bitmapCopyTo(SkBitmap* dst, SkColorType dstCT, const SkBitmap& src,
         SkBitmap::Allocator* alloc) {
+    LOG_ALWAYS_FATAL_IF(kIndex_8_SkColorType == dstCT &&
+            kIndex_8_SkColorType != src.colorType(), "Error, cannot copyTo kIndex8.");
+
+    SkPixmap srcPM;
+    if (!src.peekPixels(&srcPM)) {
+        return false;
+    }
+
+    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(), srcPM.ctable());
+                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;
+    }
+
+    if (!dst->setInfo(dstInfo)) {
+        return false;
+    }
+    if (!dst->tryAllocPixels(alloc, srcPM.ctable())) {
+        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 == src.colorType() && kAlpha_8_SkColorType != dstCT) {
-        SkAutoPixmapUnlock srcUnlocker;
-        if (!src.requestLock(&srcUnlocker)) {
-            return false;
-        }
-        SkPixmap srcPixmap = srcUnlocker.pixmap();
-
-        SkImageInfo dstInfo = src.info().makeColorType(dstCT);
-        if (dstCT == kRGBA_F16_SkColorType) {
-             dstInfo = dstInfo.makeColorSpace(SkColorSpace::MakeSRGBLinear());
-        }
-        if (!dst->setInfo(dstInfo)) {
-            return false;
-        }
-        if (!dst->tryAllocPixels(alloc, nullptr)) {
-            return false;
-        }
-
+    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 = srcPixmap.addr8(0, y);
+                    const uint8_t* srcRow = srcPM.addr8(0, y);
                     uint32_t* dstRow = dst->getAddr32(0, y);
                     ToColor_SA8(dstRow, srcRow, src.width(), nullptr);
                 }
@@ -794,7 +814,7 @@
             }
             case kRGBA_F16_SkColorType: {
                for (int y = 0; y < src.height(); y++) {
-                   const uint8_t* srcRow = srcPixmap.addr8(0, y);
+                   const uint8_t* srcRow = srcPM.addr8(0, y);
                    void* dstRow = dst->getAddr(0, y);
                    ToF16_SA8(dstRow, srcRow, src.width());
                }
@@ -805,7 +825,25 @@
         }
     }
 
-    return src.copyTo(dst, dstCT, alloc);
+    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);
 }
 
 static jobject Bitmap_copy(JNIEnv* env, jobject, jlong srcHandle,
@@ -1074,7 +1112,7 @@
         return NULL;
     }
 
-    SkColorTable* ctable = NULL;
+    sk_sp<SkColorTable> ctable = NULL;
     if (colorType == kIndex_8_SkColorType) {
         int count = p->readInt32();
         if (count < 0 || count > 256) {
@@ -1088,7 +1126,7 @@
             if (src == NULL) {
                 return NULL;
             }
-            ctable = new SkColorTable(src, count);
+            ctable = SkColorTable::Make(src, count);
         }
     }
 
@@ -1097,7 +1135,6 @@
     android::Parcel::ReadableBlob blob;
     android::status_t status = p->readBlob(size, &blob);
     if (status) {
-        SkSafeUnref(ctable);
         doThrowRE(env, "Could not read bitmap blob.");
         return NULL;
     }
@@ -1118,15 +1155,13 @@
         if (dupFd < 0) {
             ALOGE("Error allocating dup fd. Error:%d", errno);
             blob.release();
-            SkSafeUnref(ctable);
             doThrowRE(env, "Could not allocate dup blob fd.");
             return NULL;
         }
 
         // Map the pixels in place and take ownership of the ashmem region.
         nativeBitmap = sk_sp<Bitmap>(GraphicsJNI::mapAshmemBitmap(env, bitmap.get(),
-                ctable, dupFd, const_cast<void*>(blob.data()), size, !isMutable));
-        SkSafeUnref(ctable);
+                ctable.get(), dupFd, const_cast<void*>(blob.data()), size, !isMutable));
         if (!nativeBitmap) {
             close(dupFd);
             blob.release();
@@ -1152,15 +1187,12 @@
 
         // Copy the pixels into a new buffer.
         nativeBitmap = Bitmap::allocateHeapBitmap(bitmap.get(), ctable);
-        SkSafeUnref(ctable);
         if (!nativeBitmap) {
             blob.release();
             doThrowRE(env, "Could not allocate java pixel ref.");
             return NULL;
         }
-        bitmap->lockPixels();
         memcpy(bitmap->getPixels(), blob.data(), size);
-        bitmap->unlockPixels();
 
         // Release the blob handle.
         blob.release();
@@ -1211,7 +1243,6 @@
 
     if (bitmap.colorType() == kIndex_8_SkColorType) {
         // The bitmap needs to be locked to access its color table.
-        SkAutoLockPixels alp(bitmap);
         SkColorTable* ctable = bitmap.getColorTable();
         if (ctable != NULL) {
             int count = ctable->count();
@@ -1258,14 +1289,12 @@
         return JNI_FALSE;
     }
 
-    bitmap.lockPixels();
     const void* pSrc =  bitmap.getPixels();
     if (pSrc == NULL) {
         memset(blob.data(), 0, size);
     } else {
         memcpy(blob.data(), pSrc, size);
     }
-    bitmap.unlockPixels();
 
     blob.release();
     return JNI_TRUE;
@@ -1355,7 +1384,6 @@
         jint x, jint y) {
     SkBitmap bitmap;
     reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap);
-    SkAutoLockPixels alp(bitmap);
 
     ToColorProc proc = ChooseToColorProc(bitmap);
     if (NULL == proc) {
@@ -1387,7 +1415,6 @@
         jint x, jint y, jint width, jint height) {
     SkBitmap bitmap;
     reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap);
-    SkAutoLockPixels alp(bitmap);
 
     ToColorProc proc = ChooseToColorProc(bitmap);
     if (NULL == proc) {
@@ -1436,7 +1463,6 @@
     SkBitmap bitmap;
     reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap);
     SkColor color = static_cast<SkColor>(colorHandle);
-    SkAutoLockPixels alp(bitmap);
     if (NULL == bitmap.getPixels()) {
         return;
     }
@@ -1473,7 +1499,6 @@
                                       jlong bitmapHandle, jobject jbuffer) {
     SkBitmap bitmap;
     reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap);
-    SkAutoLockPixels alp(bitmap);
     const void* src = bitmap.getPixels();
 
     if (NULL != src) {
@@ -1488,7 +1513,6 @@
                                         jlong bitmapHandle, jobject jbuffer) {
     SkBitmap bitmap;
     reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap);
-    SkAutoLockPixels alp(bitmap);
     void* dst = bitmap.getPixels();
 
     if (NULL != dst) {
@@ -1523,9 +1547,6 @@
         return JNI_FALSE;
     }
 
-    SkAutoLockPixels alp0(bm0);
-    SkAutoLockPixels alp1(bm1);
-
     // if we can't load the pixels, return false
     if (NULL == bm0.getPixels() || NULL == bm1.getPixels()) {
         return JNI_FALSE;
@@ -1593,7 +1614,7 @@
 
     SkBitmap result;
     HeapAllocator allocator;
-    if (!src.copyTo(&result, hwuiBitmap.info().colorType(), &allocator)) {
+    if (!bitmapCopyTo(&result, hwuiBitmap.info().colorType(), src, &allocator)) {
         doThrowRE(env, "Could not copy a hardware bitmap.");
         return NULL;
     }
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index c5bd7a5..8b2a50d 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -195,13 +195,8 @@
             return false;
         }
 
-        mBitmap->reconfigure(info, bitmap->rowBytes(), ctable);
-        mBitmap->ref();
-        bitmap->setPixelRef(mBitmap)->unref();
-
-        // since we're already allocated, we lockPixels right away
-        // HeapAllocator behaves this way too
-        bitmap->lockPixels();
+        mBitmap->reconfigure(info, bitmap->rowBytes(), sk_ref_sp(ctable));
+        bitmap->setPixelRef(sk_ref_sp(mBitmap), 0, 0);
         return true;
     }
 
diff --git a/core/jni/android/graphics/ColorFilter.cpp b/core/jni/android/graphics/ColorFilter.cpp
index 5553a3e..4b6578b 100644
--- a/core/jni/android/graphics/ColorFilter.cpp
+++ b/core/jni/android/graphics/ColorFilter.cpp
@@ -30,9 +30,12 @@
 
 class SkColorFilterGlue {
 public:
-    static void SafeUnref(JNIEnv* env, jobject clazz, jlong skFilterHandle) {
-        SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(skFilterHandle);
-        SkSafeUnref(filter);
+    static void SafeUnref(SkShader* shader) {
+        SkSafeUnref(shader);
+    }
+
+    static jlong GetNativeFinalizer(JNIEnv*, jobject) {
+        return static_cast<jlong>(reinterpret_cast<uintptr_t>(&SafeUnref));
     }
 
     static jlong CreatePorterDuffFilter(JNIEnv* env, jobject, jint srcColor, jint modeHandle) {
@@ -57,7 +60,7 @@
 };
 
 static const JNINativeMethod colorfilter_methods[] = {
-    {"nSafeUnref", "(J)V", (void*) SkColorFilterGlue::SafeUnref}
+    {"nativeGetFinalizer", "()J", (void*) SkColorFilterGlue::GetNativeFinalizer }
 };
 
 static const JNINativeMethod porterduff_methods[] = {
diff --git a/core/jni/android/graphics/GraphicBuffer.cpp b/core/jni/android/graphics/GraphicBuffer.cpp
index 73e53c6..1017cba 100644
--- a/core/jni/android/graphics/GraphicBuffer.cpp
+++ b/core/jni/android/graphics/GraphicBuffer.cpp
@@ -18,6 +18,7 @@
 
 #include "jni.h"
 #include "JNIHelp.h"
+#include <inttypes.h>
 
 #include "android_os_Parcel.h"
 #include "GraphicBuffer.h"
@@ -27,6 +28,8 @@
 
 #include <binder/Parcel.h>
 
+#include <log/log.h>
+
 #include <ui/GraphicBuffer.h>
 #include <ui/PixelFormat.h>
 
@@ -90,9 +93,15 @@
 class GraphicBufferWrapper {
 public:
     explicit GraphicBufferWrapper(const sp<GraphicBuffer>& buffer): buffer(buffer) {
+        LOG_ALWAYS_FATAL_IF(buffer == nullptr, "creating a null GraphicBuffer");
+    }
+    const sp<GraphicBuffer>& get() const {
+        return buffer;
     }
 
-    sp<GraphicBuffer> buffer;
+private:
+    // make sure this is immutable
+    sp<GraphicBuffer> const buffer;
 };
 
 // ----------------------------------------------------------------------------
@@ -102,6 +111,8 @@
 static jlong android_graphics_GraphicBuffer_wrap(JNIEnv* env, jobject clazz,
         jlong unwrapped) {
     sp<GraphicBuffer> b(reinterpret_cast<GraphicBuffer*>(unwrapped));
+    LOG_ALWAYS_FATAL_IF(b == nullptr,
+            "*** android_graphics_GraphicBuffer_wrap() invalid state, b is null, unwrapped=%#" PRIx64, unwrapped);
     GraphicBufferWrapper* wrapper = new GraphicBufferWrapper(b);
     return reinterpret_cast<jlong>(wrapper);
 }
@@ -159,7 +170,7 @@
         return JNI_FALSE;
     }
 
-    sp<GraphicBuffer> buffer(wrapper->buffer);
+    sp<GraphicBuffer> buffer(wrapper->get());
 
     Rect rect(Rect::EMPTY_RECT);
     if (dirtyRect) {
@@ -217,7 +228,7 @@
     nativeCanvas->setBitmap(SkBitmap());
 
     if (wrapper) {
-        status_t status = wrapper->buffer->unlock();
+        status_t status = wrapper->get()->unlock();
         return status == 0 ? JNI_TRUE : JNI_FALSE;
     }
 
@@ -230,11 +241,12 @@
 
 static void android_graphics_GraphicBuffer_write(JNIEnv* env, jobject clazz,
         jlong wrapperHandle, jobject dest) {
+
     GraphicBufferWrapper* wrapper =
                 reinterpret_cast<GraphicBufferWrapper*>(wrapperHandle);
     Parcel* parcel = parcelForJavaObject(env, dest);
     if (parcel) {
-        parcel->write(*wrapper->buffer);
+        parcel->write(*wrapper->get());
     }
 }
 
@@ -260,7 +272,7 @@
         jlong nativeObject = env->GetLongField(obj, gGraphicBufferClassInfo.mNativeObject);
         GraphicBufferWrapper* wrapper = (GraphicBufferWrapper*) nativeObject;
         if (wrapper != NULL) {
-            sp<GraphicBuffer> buffer(wrapper->buffer);
+            sp<GraphicBuffer> buffer(wrapper->get());
             return buffer;
         }
     }
@@ -271,7 +283,7 @@
     GraphicBufferWrapper* wrapper = new GraphicBufferWrapper(buffer);
     jobject obj = env->NewObject(gGraphicBufferClassInfo.mClass,
             gGraphicBufferClassInfo.mConstructorMethodID, buffer->getWidth(), buffer->getHeight(),
-            buffer->getPixelFormat(), buffer->getUsage(), reinterpret_cast<jlong>(wrapper));
+            buffer->getPixelFormat(), (jint)buffer->getUsage(), reinterpret_cast<jlong>(wrapper));
     return obj;
 }
 
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index f581e20..36ebcd7 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -456,15 +456,11 @@
     // attempting to compute our own.
     const size_t rowBytes = bitmap->rowBytes();
 
-    auto wrapper = new android::Bitmap(addr, fd, size, info, rowBytes, ctable);
+    auto wrapper = new android::Bitmap(addr, fd, size, info, rowBytes, sk_ref_sp(ctable));
     wrapper->getSkBitmap(bitmap);
     if (readOnly) {
         bitmap->pixelRef()->setImmutable();
     }
-    // since we're already allocated, we lockPixels right away
-    // HeapAllocator behaves this way too
-    bitmap->lockPixels();
-
     return wrapper;
 }
 
@@ -614,7 +610,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 bool HeapAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
-    mStorage = android::Bitmap::allocateHeapBitmap(bitmap, ctable);
+    mStorage = android::Bitmap::allocateHeapBitmap(bitmap, sk_ref_sp(ctable));
     return !!mStorage;
 }
 
@@ -662,20 +658,18 @@
         // storage needs
         mRecycledBitmap->reconfigure(
                 mRecycledBitmap->info().makeColorSpace(bitmap->refColorSpace()),
-                rowBytes, ctable);
+                rowBytes, sk_ref_sp(ctable));
 
         // Give the bitmap the same pixelRef as mRecycledBitmap.
         // skbug.com/4538: We also need to make sure that the rowBytes on the pixel ref
         //                 match the rowBytes on the bitmap.
         bitmap->setInfo(bitmap->info(), rowBytes);
-        mRecycledBitmap->ref();
-        bitmap->setPixelRef(mRecycledBitmap)->unref();
+        bitmap->setPixelRef(sk_ref_sp(mRecycledBitmap), 0, 0);
 
         // Make sure that the recycled bitmap has the correct alpha type.
         mRecycledBitmap->setAlphaType(bitmap->alphaType());
 
         bitmap->notifyPixelsChanged();
-        bitmap->lockPixels();
         mNeedsCopy = false;
 
         // TODO: If the dimensions of the SkBitmap are smaller than those of
@@ -723,7 +717,7 @@
 }
 
 bool AshmemPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
-    mStorage = android::Bitmap::allocateAshmemBitmap(bitmap, ctable);
+    mStorage = android::Bitmap::allocateAshmemBitmap(bitmap, sk_ref_sp(ctable));
     return !!mStorage;
 }
 
diff --git a/core/jni/android/graphics/Movie.h b/core/jni/android/graphics/Movie.h
index c0fbe4f..736890d 100644
--- a/core/jni/android/graphics/Movie.h
+++ b/core/jni/android/graphics/Movie.h
@@ -10,8 +10,9 @@
 #ifndef Movie_DEFINED
 #define Movie_DEFINED
 
-#include "SkRefCnt.h"
+#include "SkBitmap.h"
 #include "SkCanvas.h"
+#include "SkRefCnt.h"
 
 class SkStreamRewindable;
 
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index 5f803da..f04abec 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -63,14 +63,17 @@
 static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jobject jbitmap,
         jint tileModeX, jint tileModeY) {
     const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
-    SkBitmap bitmap;
+    sk_sp<SkImage> image;
     if (jbitmap) {
         // Only pass a valid SkBitmap object to the constructor if the Bitmap exists. Otherwise,
         // we'll pass an empty SkBitmap to avoid crashing/excepting for compatibility.
-        android::bitmap::toBitmap(env, jbitmap).getSkBitmapForShaders(&bitmap);
+        image = android::bitmap::toBitmap(env, jbitmap).makeImage();
     }
 
-    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+    if (!image.get()) {
+        SkBitmap bitmap;
+        image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+    }
     sk_sp<SkShader> baseShader = image->makeShader(
             (SkShader::TileMode)tileModeX, (SkShader::TileMode)tileModeY);
 
diff --git a/core/jni/android/graphics/pdf/PdfRenderer.cpp b/core/jni/android/graphics/pdf/PdfRenderer.cpp
index b5a4b20..95cdbb5 100644
--- a/core/jni/android/graphics/pdf/PdfRenderer.cpp
+++ b/core/jni/android/graphics/pdf/PdfRenderer.cpp
@@ -83,8 +83,6 @@
     SkBitmap skBitmap;
     GraphicsJNI::getSkBitmap(env, jbitmap, &skBitmap);
 
-    SkAutoLockPixels alp(skBitmap);
-
     const int stride = skBitmap.width() * 4;
 
     FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(skBitmap.width(), skBitmap.height(),
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 825c19f..79cc1e6 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -716,7 +716,6 @@
     int err = checkFormat(colorType, internalformat, type);
     if (err)
         return err;
-    bitmap.lockPixels();
     const int w = bitmap.width();
     const int h = bitmap.height();
     const void* p = bitmap.getPixels();
@@ -743,7 +742,6 @@
         glTexImage2D(target, level, internalformat, w, h, border, internalformat, type, p);
     }
 error:
-    bitmap.unlockPixels();
     return err;
 }
 
@@ -762,12 +760,10 @@
     int err = checkFormat(colorType, format, type);
     if (err)
         return err;
-    bitmap.lockPixels();
     const int w = bitmap.width();
     const int h = bitmap.height();
     const void* p = bitmap.getPixels();
     glTexSubImage2D(target, level, xoffset, yoffset, w, h, format, type, p);
-    bitmap.unlockPixels();
     return 0;
 }
 
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 18f3177..09e37e1 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -40,6 +40,7 @@
 #include "android_view_InputChannel.h"
 #include "android_view_KeyEvent.h"
 
+#include "android-base/stringprintf.h"
 #include "nativebridge/native_bridge.h"
 #include "nativeloader/native_loader.h"
 
@@ -265,6 +266,8 @@
 
 // ------------------------------------------------------------------------
 
+static thread_local std::string g_error_msg;
+
 static jlong
 loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName,
         jobject messageQueue, jstring internalDataDir, jstring obbDir,
@@ -277,7 +280,6 @@
     ScopedUtfChars pathStr(env, path);
     std::unique_ptr<NativeCode> code;
     bool needs_native_bridge = false;
-    std::string error_msg;
 
     void* handle = OpenNativeLibrary(env,
                                      sdkVersion,
@@ -285,12 +287,12 @@
                                      classLoader,
                                      libraryPath,
                                      &needs_native_bridge,
-                                     &error_msg);
+                                     &g_error_msg);
 
     if (handle == nullptr) {
         ALOGW("NativeActivity LoadNativeLibrary(\"%s\") failed: %s",
               pathStr.c_str(),
-              error_msg.c_str());
+              g_error_msg.c_str());
         return 0;
     }
 
@@ -306,19 +308,22 @@
     env->ReleaseStringUTFChars(funcName, funcStr);
 
     if (code->createActivityFunc == NULL) {
-        ALOGW("ANativeActivity_onCreate not found");
+        g_error_msg = needs_native_bridge ? NativeBridgeGetError() : dlerror();
+        ALOGW("ANativeActivity_onCreate not found: %s", g_error_msg.c_str());
         return 0;
     }
 
     code->messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueue);
     if (code->messageQueue == NULL) {
-        ALOGW("Unable to retrieve native MessageQueue");
+        g_error_msg = "Unable to retrieve native MessageQueue";
+        ALOGW("%s", g_error_msg.c_str());
         return 0;
     }
 
     int msgpipe[2];
     if (pipe(msgpipe)) {
-        ALOGW("could not create pipe: %s", strerror(errno));
+        g_error_msg = android::base::StringPrintf("could not create pipe: %s", strerror(errno));
+        ALOGW("%s", g_error_msg.c_str());
         return 0;
     }
     code->mainWorkRead = msgpipe[0];
@@ -334,7 +339,8 @@
 
     code->ANativeActivity::callbacks = &code->callbacks;
     if (env->GetJavaVM(&code->vm) < 0) {
-        ALOGW("NativeActivity GetJavaVM failed");
+        g_error_msg = "NativeActivity GetJavaVM failed";
+        ALOGW("%s", g_error_msg.c_str());
         return 0;
     }
     code->env = env;
@@ -381,7 +387,9 @@
 }
 
 static jstring getDlError_native(JNIEnv* env, jobject clazz) {
-  return env->NewStringUTF(dlerror());
+  jstring result = env->NewStringUTF(g_error_msg.c_str());
+  g_error_msg.clear();
+  return result;
 }
 
 static void
diff --git a/core/jni/android_app_admin_SecurityLog.cpp b/core/jni/android_app_admin_SecurityLog.cpp
index 5c45b4b..b3bcaa0 100644
--- a/core/jni/android_app_admin_SecurityLog.cpp
+++ b/core/jni/android_app_admin_SecurityLog.cpp
@@ -14,183 +14,26 @@
  * limitations under the License.
  */
 
-#include <fcntl.h>
-
-#include <nativehelper/JNIHelp.h>
-#include "core_jni_helpers.h"
-#include "jni.h"
+#include <log/log_id.h>
 #include <private/android_logger.h>
 
-// The size of the tag number comes out of the payload size.
-#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t))
+#include <nativehelper/JNIHelp.h>
+#include "jni.h"
+
+#include "core_jni_helpers.h"
+#include "eventlog_helper.h"
 
 namespace android {
 
-static jclass gCollectionClass;
-static jmethodID gCollectionAddID;
-
-static jclass gEventClass;
-static jmethodID gEventInitID;
-
-static jclass gIntegerClass;
-static jfieldID gIntegerValueID;
-
-static jclass gLongClass;
-static jfieldID gLongValueID;
-
-static jclass gFloatClass;
-static jfieldID gFloatValueID;
-
-static jclass gStringClass;
-
+constexpr char kSecurityLogEventClass[] = "android/app/admin/SecurityLog$SecurityEvent";
+template class EventLogHelper<log_id_t::LOG_ID_SECURITY, kSecurityLogEventClass>;
+using SLog = EventLogHelper<log_id_t::LOG_ID_SECURITY, kSecurityLogEventClass>;
 
 static jboolean android_app_admin_SecurityLog_isLoggingEnabled(JNIEnv* env,
                                                     jobject /* clazz */) {
     return (bool)__android_log_security();
 }
 
-static jint android_app_admin_SecurityLog_writeEvent_String(JNIEnv* env,
-                                                    jobject /* clazz */,
-                                                    jint tag, jstring value) {
-    uint8_t buf[MAX_EVENT_PAYLOAD];
-
-    // Don't throw NPE -- I feel like it's sort of mean for a logging function
-    // to be all crashy if you pass in NULL -- but make the NULL value explicit.
-    const char *str = value != NULL ? env->GetStringUTFChars(value, NULL) : "NULL";
-    uint32_t len = strlen(str);
-    size_t max = sizeof(buf) - sizeof(len) - 2;  // Type byte, final newline
-    if (len > max) len = max;
-
-    buf[0] = EVENT_TYPE_STRING;
-    memcpy(&buf[1], &len, sizeof(len));
-    memcpy(&buf[1 + sizeof(len)], str, len);
-    buf[1 + sizeof(len) + len] = '\n';
-
-    if (value != NULL) env->ReleaseStringUTFChars(value, str);
-    return __android_log_security_bwrite(tag, buf, 2 + sizeof(len) + len);
-}
-
-static jint android_app_admin_SecurityLog_writeEvent_Array(JNIEnv* env, jobject clazz,
-                                                   jint tag, jobjectArray value) {
-    if (value == NULL) {
-        return android_app_admin_SecurityLog_writeEvent_String(env, clazz, tag, NULL);
-    }
-
-    uint8_t buf[MAX_EVENT_PAYLOAD];
-    const size_t max = sizeof(buf) - 1;  // leave room for final newline
-    size_t pos = 2;  // Save room for type tag & array count
-
-    jsize copied = 0, num = env->GetArrayLength(value);
-    for (; copied < num && copied < 255; ++copied) {
-        jobject item = env->GetObjectArrayElement(value, copied);
-        if (item == NULL || env->IsInstanceOf(item, gStringClass)) {
-            if (pos + 1 + sizeof(jint) > max) break;
-            const char *str = item != NULL ? env->GetStringUTFChars((jstring) item, NULL) : "NULL";
-            jint len = strlen(str);
-            if (pos + 1 + sizeof(len) + len > max) len = max - pos - 1 - sizeof(len);
-            buf[pos++] = EVENT_TYPE_STRING;
-            memcpy(&buf[pos], &len, sizeof(len));
-            memcpy(&buf[pos + sizeof(len)], str, len);
-            pos += sizeof(len) + len;
-            if (item != NULL) env->ReleaseStringUTFChars((jstring) item, str);
-        } else if (env->IsInstanceOf(item, gIntegerClass)) {
-            jint intVal = env->GetIntField(item, gIntegerValueID);
-            if (pos + 1 + sizeof(intVal) > max) break;
-            buf[pos++] = EVENT_TYPE_INT;
-            memcpy(&buf[pos], &intVal, sizeof(intVal));
-            pos += sizeof(intVal);
-        } else if (env->IsInstanceOf(item, gLongClass)) {
-            jlong longVal = env->GetLongField(item, gLongValueID);
-            if (pos + 1 + sizeof(longVal) > max) break;
-            buf[pos++] = EVENT_TYPE_LONG;
-            memcpy(&buf[pos], &longVal, sizeof(longVal));
-            pos += sizeof(longVal);
-        } else if (env->IsInstanceOf(item, gFloatClass)) {
-            jfloat floatVal = env->GetFloatField(item, gFloatValueID);
-            if (pos + 1 + sizeof(floatVal) > max) break;
-            buf[pos++] = EVENT_TYPE_FLOAT;
-            memcpy(&buf[pos], &floatVal, sizeof(floatVal));
-            pos += sizeof(floatVal);
-        } else {
-            jniThrowException(env,
-                    "java/lang/IllegalArgumentException",
-                    "Invalid payload item type");
-            return -1;
-        }
-        env->DeleteLocalRef(item);
-    }
-
-    buf[0] = EVENT_TYPE_LIST;
-    buf[1] = copied;
-    buf[pos++] = '\n';
-    return __android_log_security_bwrite(tag, buf, pos);
-}
-
-static void readEvents(JNIEnv* env, int loggerMode, jlong startTime, jobject out) {
-    struct logger_list *logger_list;
-    if (startTime) {
-        logger_list = android_logger_list_alloc_time(loggerMode,
-                log_time(startTime / NS_PER_SEC, startTime % NS_PER_SEC), 0);
-    } else {
-        logger_list = android_logger_list_alloc(loggerMode, 0, 0);
-    }
-    if (!logger_list) {
-        jniThrowIOException(env, errno);
-        return;
-    }
-
-    if (!android_logger_open(logger_list, LOG_ID_SECURITY)) {
-        jniThrowIOException(env, errno);
-        android_logger_list_free(logger_list);
-        return;
-    }
-
-    while (1) {
-        log_msg log_msg;
-        int ret = android_logger_list_read(logger_list, &log_msg);
-
-        if (ret == 0) {
-            break;
-        }
-        if (ret < 0) {
-            if (ret == -EINTR) {
-                continue;
-            }
-            if (ret == -EINVAL) {
-                jniThrowException(env, "java/io/IOException", "Event too short");
-            } else if (ret != -EAGAIN) {
-                jniThrowIOException(env, -ret);  // Will throw on return
-            }
-            break;
-        }
-
-        if (log_msg.id() != LOG_ID_SECURITY) {
-            continue;
-        }
-
-        jsize len = ret;
-        jbyteArray array = env->NewByteArray(len);
-        if (array == NULL) {
-            break;
-        }
-
-        jbyte *bytes = env->GetByteArrayElements(array, NULL);
-        memcpy(bytes, log_msg.buf, len);
-        env->ReleaseByteArrayElements(array, bytes, 0);
-
-        jobject event = env->NewObject(gEventClass, gEventInitID, array);
-        if (event == NULL) {
-            break;
-        }
-
-        env->CallBooleanMethod(out, gCollectionAddID, event);
-        env->DeleteLocalRef(event);
-        env->DeleteLocalRef(array);
-    }
-
-    android_logger_list_close(logger_list);
-}
-
 static void android_app_admin_SecurityLog_readEvents(JNIEnv* env, jobject /* clazz */,
                                              jobject out) {
 
@@ -198,7 +41,7 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, out);
+    SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, out);
 }
 
 static void android_app_admin_SecurityLog_readEventsSince(JNIEnv* env, jobject /* clazz */,
@@ -209,7 +52,7 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, timestamp, out);
+    SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, timestamp, out);
 }
 
 static void android_app_admin_SecurityLog_readPreviousEvents(JNIEnv* env, jobject /* clazz */,
@@ -219,7 +62,7 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_PSTORE, 0, out);
+    SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_PSTORE, 0, out);
 }
 
 static void android_app_admin_SecurityLog_readEventsOnWrapping(JNIEnv* env, jobject /* clazz */,
@@ -229,7 +72,8 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, timestamp, out);
+    SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, timestamp,
+            out);
 }
 
 /*
@@ -243,11 +87,11 @@
     },
     { "writeEvent",
       "(ILjava/lang/String;)I",
-      (void*) android_app_admin_SecurityLog_writeEvent_String
+      (void*) SLog::writeEventString
     },
     { "writeEvent",
       "(I[Ljava/lang/Object;)I",
-      (void*) android_app_admin_SecurityLog_writeEvent_Array
+      (void*) SLog::writeEventArray
     },
     { "readEvents",
       "(Ljava/util/Collection;)V",
@@ -267,41 +111,8 @@
     },
 };
 
-static struct { const char *name; jclass *clazz; } gClasses[] = {
-    { "android/app/admin/SecurityLog$SecurityEvent", &gEventClass },
-    { "java/lang/Integer", &gIntegerClass },
-    { "java/lang/Long", &gLongClass },
-    { "java/lang/Float", &gFloatClass },
-    { "java/lang/String", &gStringClass },
-    { "java/util/Collection", &gCollectionClass },
-};
-
-static struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = {
-    { &gIntegerClass, "value", "I", &gIntegerValueID },
-    { &gLongClass, "value", "J", &gLongValueID },
-    { &gFloatClass, "value", "F", &gFloatValueID },
-};
-
-static struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = {
-    { &gEventClass, "<init>", "([B)V", &gEventInitID },
-    { &gCollectionClass, "add", "(Ljava/lang/Object;)Z", &gCollectionAddID },
-};
-
 int register_android_app_admin_SecurityLog(JNIEnv* env) {
-    for (int i = 0; i < NELEM(gClasses); ++i) {
-        jclass clazz = FindClassOrDie(env, gClasses[i].name);
-        *gClasses[i].clazz = MakeGlobalRefOrDie(env, clazz);
-    }
-
-    for (int i = 0; i < NELEM(gFields); ++i) {
-        *gFields[i].id = GetFieldIDOrDie(env,
-                *gFields[i].c, gFields[i].name, gFields[i].ft);
-    }
-
-    for (int i = 0; i < NELEM(gMethods); ++i) {
-        *gMethods[i].id = GetMethodIDOrDie(env,
-                *gMethods[i].c, gMethods[i].name, gMethods[i].mt);
-    }
+    SLog::Init(env);
 
     return RegisterMethodsOrDie(
             env,
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 253daaa..c0f719e 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -28,6 +28,7 @@
 #include "SkDrawFilter.h"
 #include "SkGraphics.h"
 #include "SkRegion.h"
+#include "SkVertices.h"
 
 namespace android {
 
@@ -311,15 +312,15 @@
 }
 
 static void drawVertices(JNIEnv* env, jobject, jlong canvasHandle,
-                         jint modeHandle, jint vertexCount,
+                         jint modeHandle, jint floatCount,
                          jfloatArray jverts, jint vertIndex,
                          jfloatArray jtexs, jint texIndex,
                          jintArray jcolors, jint colorIndex,
                          jshortArray jindices, jint indexIndex,
                          jint indexCount, jlong paintHandle) {
-    AutoJavaFloatArray  vertA(env, jverts, vertIndex + vertexCount);
-    AutoJavaFloatArray  texA(env, jtexs, texIndex + vertexCount);
-    AutoJavaIntArray    colorA(env, jcolors, colorIndex + vertexCount);
+    AutoJavaFloatArray  vertA(env, jverts, vertIndex + floatCount);
+    AutoJavaFloatArray  texA(env, jtexs, texIndex + floatCount);
+    AutoJavaIntArray    colorA(env, jcolors, colorIndex + floatCount);
     AutoJavaShortArray  indexA(env, jindices, indexIndex + indexCount);
 
     const float* verts = vertA.ptr() + vertIndex;
@@ -334,10 +335,15 @@
         indices = (const uint16_t*)(indexA.ptr() + indexIndex);
     }
 
-    SkCanvas::VertexMode mode = static_cast<SkCanvas::VertexMode>(modeHandle);
+    int vertexCount = floatCount >> 1;  // 2 floats per SkPoint
+    SkVertices::VertexMode mode = static_cast<SkVertices::VertexMode>(modeHandle);
     const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
-    get_canvas(canvasHandle)->drawVertices(mode, vertexCount, verts, texs, colors,
-                                           indices, indexCount, *paint);
+    get_canvas(canvasHandle)->drawVertices(SkVertices::MakeCopy(mode, vertexCount,
+                                           reinterpret_cast<const SkPoint*>(verts),
+                                           reinterpret_cast<const SkPoint*>(texs),
+                                           reinterpret_cast<const SkColor*>(colors),
+                                           indexCount, indices).get(),
+                                           SkBlendMode::kModulate, *paint);
 }
 
 static void drawNinePatch(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
diff --git a/core/jni/android_hardware_Radio.cpp b/core/jni/android_hardware_Radio.cpp
index 18cf8ca..39e615c 100644
--- a/core/jni/android_hardware_Radio.cpp
+++ b/core/jni/android_hardware_Radio.cpp
@@ -325,13 +325,16 @@
 
     ALOGV("%s channel %d tuned %d", __FUNCTION__, nProgramInfo->channel, nProgramInfo->tuned);
 
+    int flags = 0;  // TODO(b/32621193): pass from the HAL
+    jstring jVendorExension = env->NewStringUTF("");  // TODO(b/32621193): pass from the HAL
     *jProgramInfo = env->NewObject(gRadioProgramInfoClass, gRadioProgramInfoCstor,
                                   nProgramInfo->channel, nProgramInfo->sub_channel,
                                   nProgramInfo->tuned, nProgramInfo->stereo,
                                   nProgramInfo->digital, nProgramInfo->signal_strength,
-                                  jMetadata);
+                                  jMetadata, flags, jVendorExension);
 
     env->DeleteLocalRef(jMetadata);
+    env->DeleteLocalRef(jVendorExension);
     return (jint)RADIO_STATUS_OK;
 }
 
@@ -443,19 +446,22 @@
         jstring jProduct = env->NewStringUTF(nModules[i].product);
         jstring jVersion = env->NewStringUTF(nModules[i].version);
         jstring jSerial = env->NewStringUTF(nModules[i].serial);
+        bool isBgscanSupported = false;  // TODO(b/32621193): pass from the HAL
+        jstring jVendorExension = env->NewStringUTF("");  // TODO(b/32621193): pass from the HAL
         jobject jModule = env->NewObject(gModulePropertiesClass, gModulePropertiesCstor,
                                                nModules[i].handle, nModules[i].class_id,
                                                jImplementor, jProduct, jVersion, jSerial,
                                                nModules[i].num_tuners,
                                                nModules[i].num_audio_sources,
                                                nModules[i].supports_capture,
-                                               jBands);
+                                               jBands, isBgscanSupported, jVendorExension);
 
         env->DeleteLocalRef(jImplementor);
         env->DeleteLocalRef(jProduct);
         env->DeleteLocalRef(jVersion);
         env->DeleteLocalRef(jSerial);
         env->DeleteLocalRef(jBands);
+        env->DeleteLocalRef(jVendorExension);
         if (jModule == NULL) {
             continue;
         }
@@ -882,7 +888,7 @@
     jclass modulePropertiesClass = FindClassOrDie(env, kModulePropertiesClassPathName);
     gModulePropertiesClass = MakeGlobalRefOrDie(env, modulePropertiesClass);
     gModulePropertiesCstor = GetMethodIDOrDie(env, modulePropertiesClass, "<init>",
-            "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIZ[Landroid/hardware/radio/RadioManager$BandDescriptor;)V");
+            "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIZ[Landroid/hardware/radio/RadioManager$BandDescriptor;ZLjava/lang/String;)V");
 
     jclass bandDescriptorClass = FindClassOrDie(env, kRadioBandDescriptorClassPathName);
     gRadioBandDescriptorClass = MakeGlobalRefOrDie(env, bandDescriptorClass);
@@ -932,7 +938,7 @@
     jclass programInfoClass = FindClassOrDie(env, kRadioProgramInfoClassPathName);
     gRadioProgramInfoClass = MakeGlobalRefOrDie(env, programInfoClass);
     gRadioProgramInfoCstor = GetMethodIDOrDie(env, programInfoClass, "<init>",
-            "(IIZZZILandroid/hardware/radio/RadioMetadata;)V");
+            "(IIZZZILandroid/hardware/radio/RadioMetadata;ILjava/lang/String;)V");
 
     jclass metadataClass = FindClassOrDie(env, kRadioMetadataClassPathName);
     gRadioMetadataClass = MakeGlobalRefOrDie(env, metadataClass);
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index 60ac74c..5b327d4 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -270,7 +270,7 @@
 }
 
 static jint nativeSetOperationParameter(JNIEnv *_env, jclass _this, jlong sensorManager,
-        jint type, jfloatArray floats, jintArray ints) {
+        jint handle, jint type, jfloatArray floats, jintArray ints) {
     SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
     Vector<float> floatVector;
     Vector<int32_t> int32Vector;
@@ -285,7 +285,7 @@
         _env->GetIntArrayRegion(ints, 0, _env->GetArrayLength(ints), int32Vector.editArray());
     }
 
-    return mgr->setOperationParameter(type, floatVector, int32Vector);
+    return mgr->setOperationParameter(handle, type, floatVector, int32Vector);
 }
 
 //----------------------------------------------------------------------------
@@ -512,7 +512,7 @@
             (void*)nativeConfigDirectChannel },
 
     {"nativeSetOperationParameter",
-            "(JI[F[I)I",
+            "(JII[F[I)I",
             (void*)nativeSetOperationParameter },
 };
 
diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
index 040981d..fad5b0e 100644
--- a/core/jni/android_hardware_camera2_CameraMetadata.cpp
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -442,10 +442,12 @@
 
         if (threadRet != 0) {
             close(writeFd);
+            close(readFd);
 
             jniThrowExceptionFmt(env, "java/io/IOException",
                     "Failed to create thread for writing (errno = %#x, message = '%s')",
                     threadRet, strerror(threadRet));
+            return;
         }
     }
 
@@ -476,6 +478,8 @@
         } else if (!logLine.isEmpty()) {
             ALOGD("%s", logLine.string());
         }
+
+        close(readFd);
     }
 
     int res;
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index c8eef7f..1628220 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -23,13 +23,13 @@
 #include <vector>
 #include <cmath>
 
+#include <android-base/properties.h>
 #include <utils/Log.h>
 #include <utils/Errors.h>
 #include <utils/StrongPointer.h>
 #include <utils/RefBase.h>
 #include <utils/Vector.h>
 #include <utils/String8.h>
-#include <cutils/properties.h>
 #include <system/camera_metadata.h>
 #include <camera/CameraMetadata.h>
 #include <img_utils/DngUtils.h>
@@ -50,6 +50,7 @@
 
 using namespace android;
 using namespace img_utils;
+using android::base::GetProperty;
 
 #define BAIL_IF_INVALID_RET_BOOL(expr, jnienv, tagId, writer) \
     if ((expr) != OK) { \
@@ -1237,26 +1238,24 @@
 
     {
         // make
-        char manufacturer[PROPERTY_VALUE_MAX];
-
         // Use "" to represent unknown make as suggested in TIFF/EP spec.
-        property_get("ro.product.manufacturer", manufacturer, "");
-        uint32_t count = static_cast<uint32_t>(strlen(manufacturer)) + 1;
+        std::string manufacturer = GetProperty("ro.product.manufacturer", "");
+        uint32_t count = static_cast<uint32_t>(manufacturer.size()) + 1;
 
         BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_MAKE, count,
-                reinterpret_cast<uint8_t*>(manufacturer), TIFF_IFD_0), env, TAG_MAKE, writer);
+                reinterpret_cast<const uint8_t*>(manufacturer.c_str()), TIFF_IFD_0), env, TAG_MAKE,
+                writer);
     }
 
     {
         // model
-        char model[PROPERTY_VALUE_MAX];
-
         // Use "" to represent unknown model as suggested in TIFF/EP spec.
-        property_get("ro.product.model", model, "");
-        uint32_t count = static_cast<uint32_t>(strlen(model)) + 1;
+        std::string model = GetProperty("ro.product.model", "");
+        uint32_t count = static_cast<uint32_t>(model.size()) + 1;
 
         BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_MODEL, count,
-                reinterpret_cast<uint8_t*>(model), TIFF_IFD_0), env, TAG_MODEL, writer);
+                reinterpret_cast<const uint8_t*>(model.c_str()), TIFF_IFD_0), env, TAG_MODEL,
+                writer);
     }
 
     {
@@ -1277,11 +1276,11 @@
 
     {
         // software
-        char software[PROPERTY_VALUE_MAX];
-        property_get("ro.build.fingerprint", software, "");
-        uint32_t count = static_cast<uint32_t>(strlen(software)) + 1;
+        std::string software = GetProperty("ro.build.fingerprint", "");
+        uint32_t count = static_cast<uint32_t>(software.size()) + 1;
         BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_SOFTWARE, count,
-                reinterpret_cast<uint8_t*>(software), TIFF_IFD_0), env, TAG_SOFTWARE, writer);
+                reinterpret_cast<const uint8_t*>(software.c_str()), TIFF_IFD_0), env, TAG_SOFTWARE,
+                writer);
     }
 
     if (nativeContext->hasCaptureTime()) {
@@ -1613,20 +1612,15 @@
 
     {
         // Setup unique camera model tag
-        char model[PROPERTY_VALUE_MAX];
-        property_get("ro.product.model", model, "");
+        std::string model = GetProperty("ro.product.model", "");
+        std::string manufacturer = GetProperty("ro.product.manufacturer", "");
+        std::string brand = GetProperty("ro.product.brand", "");
 
-        char manufacturer[PROPERTY_VALUE_MAX];
-        property_get("ro.product.manufacturer", manufacturer, "");
-
-        char brand[PROPERTY_VALUE_MAX];
-        property_get("ro.product.brand", brand, "");
-
-        String8 cameraModel(model);
+        String8 cameraModel(model.c_str());
         cameraModel += "-";
-        cameraModel += manufacturer;
+        cameraModel += manufacturer.c_str();
         cameraModel += "-";
-        cameraModel += brand;
+        cameraModel += brand.c_str();
 
         BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_UNIQUECAMERAMODEL, cameraModel.size() + 1,
                 reinterpret_cast<const uint8_t*>(cameraModel.string()), TIFF_IFD_0), env,
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 609111e..954e46e 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -1761,6 +1761,14 @@
     return nativeToJavaStatus(AudioSystem::systemReady());
 }
 
+static jfloat
+android_media_AudioSystem_getStreamVolumeDB(JNIEnv *env, jobject thiz,
+                                            jint stream, jint index, jint device)
+{
+    return (jfloat)AudioSystem::getStreamVolumeDB((audio_stream_type_t)stream,
+                                                  (int)index,
+                                                  (audio_devices_t)device);
+}
 
 // ----------------------------------------------------------------------------
 
@@ -1814,6 +1822,7 @@
     {"native_register_recording_callback", "()V",
                                     (void *)android_media_AudioSystem_registerRecordingCallback},
     {"systemReady", "()I", (void *)android_media_AudioSystem_systemReady},
+    {"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB},
 };
 
 
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
index 6163588..a9d75fd 100644
--- a/core/jni/android_opengl_EGL14.cpp
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -17,7 +17,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include "jni.h"
diff --git a/core/jni/android_opengl_EGLExt.cpp b/core/jni/android_opengl_EGLExt.cpp
index df1aa20..75a25fe 100644
--- a/core/jni/android_opengl_EGLExt.cpp
+++ b/core/jni/android_opengl_EGLExt.cpp
@@ -17,7 +17,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include "jni.h"
diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp
index 6d4f6ec..ee5b594 100644
--- a/core/jni/android_opengl_GLES10.cpp
+++ b/core/jni/android_opengl_GLES10.cpp
@@ -18,7 +18,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <GLES/gl.h>
diff --git a/core/jni/android_opengl_GLES10Ext.cpp b/core/jni/android_opengl_GLES10Ext.cpp
index e630cfca..da7d0f0 100644
--- a/core/jni/android_opengl_GLES10Ext.cpp
+++ b/core/jni/android_opengl_GLES10Ext.cpp
@@ -18,7 +18,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <GLES/gl.h>
diff --git a/core/jni/android_opengl_GLES11.cpp b/core/jni/android_opengl_GLES11.cpp
index ab9cbb1..391ae53 100644
--- a/core/jni/android_opengl_GLES11.cpp
+++ b/core/jni/android_opengl_GLES11.cpp
@@ -18,7 +18,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <GLES/gl.h>
diff --git a/core/jni/android_opengl_GLES11Ext.cpp b/core/jni/android_opengl_GLES11Ext.cpp
index 8f71a6d..09dce32 100644
--- a/core/jni/android_opengl_GLES11Ext.cpp
+++ b/core/jni/android_opengl_GLES11Ext.cpp
@@ -18,7 +18,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <GLES/gl.h>
diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp
index f83d204..99922cf 100644
--- a/core/jni/android_opengl_GLES20.cpp
+++ b/core/jni/android_opengl_GLES20.cpp
@@ -18,7 +18,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <GLES2/gl2.h>
diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp
index b649daf..adc635e 100644
--- a/core/jni/android_opengl_GLES30.cpp
+++ b/core/jni/android_opengl_GLES30.cpp
@@ -18,7 +18,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <GLES3/gl3.h>
diff --git a/core/jni/android_opengl_GLES31.cpp b/core/jni/android_opengl_GLES31.cpp
index 07d920f..512f562 100644
--- a/core/jni/android_opengl_GLES31.cpp
+++ b/core/jni/android_opengl_GLES31.cpp
@@ -17,7 +17,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <stdint.h>
diff --git a/core/jni/android_opengl_GLES31Ext.cpp b/core/jni/android_opengl_GLES31Ext.cpp
index 723dd4c..5543fca 100644
--- a/core/jni/android_opengl_GLES31Ext.cpp
+++ b/core/jni/android_opengl_GLES31Ext.cpp
@@ -17,7 +17,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <GLES3/gl31.h>
diff --git a/core/jni/android_opengl_GLES32.cpp b/core/jni/android_opengl_GLES32.cpp
index 62a6e6c..2f1e31e 100644
--- a/core/jni/android_opengl_GLES32.cpp
+++ b/core/jni/android_opengl_GLES32.cpp
@@ -17,7 +17,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <stdint.h>
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index fdbb1ed..5272af5 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -33,12 +33,14 @@
 #include <string>
 
 #include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
 #include <debuggerd/client.h>
 #include <log/log.h>
 #include <utils/misc.h>
 #include <utils/String8.h>
 
-#include "JNIHelp.h"
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedUtfChars.h>
 #include "jni.h"
 #include <memtrack/memtrack.h>
 #include <memunreachable/memunreachable.h>
@@ -717,7 +719,7 @@
         return;
     }
 
-    int fd = open("/proc/meminfo", O_RDONLY);
+    int fd = open("/proc/meminfo", O_RDONLY | O_CLOEXEC);
 
     if (fd < 0) {
         ALOGW("Unable to open /proc/meminfo: %s\n", strerror(errno));
@@ -1038,30 +1040,34 @@
     ALOGD("Native heap dump complete.\n");
 }
 
-static void android_os_Debug_dumpNativeBacktraceToFileTimeout(JNIEnv* env, jobject clazz,
-    jint pid, jstring fileName, jint timeoutSecs)
-{
-    if (fileName == NULL) {
-        jniThrowNullPointerException(env, "file == null");
-        return;
-    }
-    const jchar* str = env->GetStringCritical(fileName, 0);
-    String8 fileName8;
-    if (str) {
-        fileName8 = String8(reinterpret_cast<const char16_t*>(str),
-                            env->GetStringLength(fileName));
-        env->ReleaseStringCritical(fileName, str);
+static bool dumpTraces(JNIEnv* env, jint pid, jstring fileName, jint timeoutSecs,
+                       DebuggerdDumpType dumpType) {
+    const ScopedUtfChars fileNameChars(env, fileName);
+    if (fileNameChars.c_str() == nullptr) {
+        return false;
     }
 
-    int fd = open(fileName8.string(), O_CREAT | O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_APPEND, 0666);
+    android::base::unique_fd fd(open(fileNameChars.c_str(),
+                                     O_CREAT | O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_APPEND,
+                                     0666));
     if (fd < 0) {
-        fprintf(stderr, "Can't open %s: %s\n", fileName8.string(), strerror(errno));
-        return;
+        fprintf(stderr, "Can't open %s: %s\n", fileNameChars.c_str(), strerror(errno));
+        return false;
     }
 
-    dump_backtrace_to_file_timeout(pid, kDebuggerdNativeBacktrace, timeoutSecs, fd);
+    return (dump_backtrace_to_file_timeout(pid, dumpType, timeoutSecs, fd) == 0);
+}
 
-    close(fd);
+static jboolean android_os_Debug_dumpJavaBacktraceToFileTimeout(JNIEnv* env, jobject clazz,
+        jint pid, jstring fileName, jint timeoutSecs) {
+    const bool ret =  dumpTraces(env, pid, fileName, timeoutSecs, kDebuggerdJavaBacktrace);
+    return ret ? JNI_TRUE : JNI_FALSE;
+}
+
+static jboolean android_os_Debug_dumpNativeBacktraceToFileTimeout(JNIEnv* env, jobject clazz,
+        jint pid, jstring fileName, jint timeoutSecs) {
+    const bool ret = dumpTraces(env, pid, fileName, timeoutSecs, kDebuggerdNativeBacktrace);
+    return ret ? JNI_TRUE : JNI_FALSE;
 }
 
 static jstring android_os_Debug_getUnreachableMemory(JNIEnv* env, jobject clazz,
@@ -1104,7 +1110,9 @@
             (void*)android_os_Debug_getProxyObjectCount },
     { "getBinderDeathObjectCount", "()I",
             (void*)android_os_Debug_getDeathObjectCount },
-    { "dumpNativeBacktraceToFileTimeout", "(ILjava/lang/String;I)V",
+    { "dumpJavaBacktraceToFileTimeout", "(ILjava/lang/String;I)Z",
+            (void*)android_os_Debug_dumpJavaBacktraceToFileTimeout },
+    { "dumpNativeBacktraceToFileTimeout", "(ILjava/lang/String;I)Z",
             (void*)android_os_Debug_dumpNativeBacktraceToFileTimeout },
     { "getUnreachableMemory", "(IZ)Ljava/lang/String;",
             (void*)android_os_Debug_getUnreachableMemory },
diff --git a/core/jni/android_os_GraphicsEnvironment.cpp b/core/jni/android_os_GraphicsEnvironment.cpp
index 399dec8..f749488 100644
--- a/core/jni/android_os_GraphicsEnvironment.cpp
+++ b/core/jni/android_os_GraphicsEnvironment.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "GraphicsEnvironment"
 
-#include <ui/GraphicsEnv.h>
+#include <graphicsenv/GraphicsEnv.h>
 #include <nativehelper/ScopedUtfChars.h>
 #include "core_jni_helpers.h"
 
diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp
index 59ca050..08d9527 100644
--- a/core/jni/android_os_HwBinder.cpp
+++ b/core/jni/android_os_HwBinder.cpp
@@ -35,6 +35,7 @@
 #include <hidl/HidlTransportSupport.h>
 #include <hwbinder/ProcessState.h>
 #include <nativehelper/ScopedLocalRef.h>
+#include <nativehelper/ScopedUtfChars.h>
 #include <vintf/parse_string.h>
 #include <utils/misc.h>
 
@@ -261,14 +262,9 @@
         JNIEnv *env,
         jobject thiz,
         jstring serviceNameObj) {
-    if (serviceNameObj == NULL) {
-        jniThrowException(env, "java/lang/NullPointerException", NULL);
-        return;
-    }
-
-    const char *serviceName = env->GetStringUTFChars(serviceNameObj, NULL);
-    if (serviceName == NULL) {
-        return;  // XXX exception already pending?
+    ScopedUtfChars str(env, serviceNameObj);
+    if (str.c_str() == nullptr) {
+        return;  // NPE will be pending.
     }
 
     sp<hardware::IBinder> binder = JHwBinder::GetNativeBinder(env, thiz);
@@ -284,15 +280,12 @@
         return;
     }
 
-    Return<bool> ret = manager->add(serviceName, base);
-
-    env->ReleaseStringUTFChars(serviceNameObj, serviceName);
-    serviceName = NULL;
+    Return<bool> ret = manager->add(str.c_str(), base);
 
     bool ok = ret.isOk() && ret;
 
     if (ok) {
-        LOG(INFO) << "Starting thread pool.";
+        LOG(INFO) << "HwBinder: Starting thread pool for " << str.c_str();
         ::android::hardware::ProcessState::self()->startThreadPool();
     }
 
@@ -303,87 +296,31 @@
         JNIEnv *env,
         jclass /* clazzObj */,
         jstring ifaceNameObj,
-        jstring serviceNameObj) {
+        jstring serviceNameObj,
+        jboolean retry) {
 
     using ::android::hidl::base::V1_0::IBase;
-    using ::android::hidl::manager::V1_0::IServiceManager;
+    using ::android::hardware::details::getRawServiceInternal;
 
-    if (ifaceNameObj == NULL) {
-        jniThrowException(env, "java/lang/NullPointerException", NULL);
-        return NULL;
-    }
-    if (serviceNameObj == NULL) {
-        jniThrowException(env, "java/lang/NullPointerException", NULL);
-        return NULL;
+    std::string ifaceName;
+    {
+        ScopedUtfChars str(env, ifaceNameObj);
+        if (str.c_str() == nullptr) {
+            return nullptr;  // NPE will be pending.
+        }
+        ifaceName = str.c_str();
     }
 
-    auto manager = hardware::defaultServiceManager();
-
-    if (manager == nullptr) {
-        LOG(ERROR) << "Could not get hwservicemanager.";
-        signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
-        return NULL;
+    std::string serviceName;
+    {
+        ScopedUtfChars str(env, serviceNameObj);
+        if (str.c_str() == nullptr) {
+            return nullptr;  // NPE will be pending.
+        }
+        serviceName = str.c_str();
     }
 
-    const char *ifaceNameCStr = env->GetStringUTFChars(ifaceNameObj, NULL);
-    if (ifaceNameCStr == NULL) {
-        return NULL; // XXX exception already pending?
-    }
-    std::string ifaceName(ifaceNameCStr);
-    env->ReleaseStringUTFChars(ifaceNameObj, ifaceNameCStr);
-    ::android::hardware::hidl_string ifaceNameHStr;
-    ifaceNameHStr.setToExternal(ifaceName.c_str(), ifaceName.size());
-
-    const char *serviceNameCStr = env->GetStringUTFChars(serviceNameObj, NULL);
-    if (serviceNameCStr == NULL) {
-        return NULL; // XXX exception already pending?
-    }
-    std::string serviceName(serviceNameCStr);
-    env->ReleaseStringUTFChars(serviceNameObj, serviceNameCStr);
-    ::android::hardware::hidl_string serviceNameHStr;
-    serviceNameHStr.setToExternal(serviceName.c_str(), serviceName.size());
-
-    LOG(INFO) << "Looking for service "
-              << ifaceName
-              << "/"
-              << serviceName;
-
-    Return<IServiceManager::Transport> transportRet =
-            manager->getTransport(ifaceNameHStr, serviceNameHStr);
-
-    if (!transportRet.isOk()) {
-        signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
-        return NULL;
-    }
-
-    IServiceManager::Transport transport = transportRet;
-
-#ifdef __ANDROID_TREBLE__
-#ifdef __ANDROID_DEBUGGABLE__
-    const char* testingOverride = std::getenv("TREBLE_TESTING_OVERRIDE");
-    const bool vintfLegacy = (transport == IServiceManager::Transport::EMPTY)
-            && testingOverride && !strcmp(testingOverride, "true");
-#else // __ANDROID_TREBLE__ but not __ANDROID_DEBUGGABLE__
-    const bool vintfLegacy = false;
-#endif // __ANDROID_DEBUGGABLE__
-#else // not __ANDROID_TREBLE__
-    const bool vintfLegacy = (transport == IServiceManager::Transport::EMPTY);
-#endif // __ANDROID_TREBLE__";
-
-    if (transport != IServiceManager::Transport::HWBINDER && !vintfLegacy) {
-        LOG(ERROR) << "service " << ifaceName << " declares transport method "
-                   << toString(transport) << " but framework expects hwbinder.";
-        signalExceptionForError(env, NAME_NOT_FOUND, true /* canThrowRemoteException */);
-        return NULL;
-    }
-
-    Return<sp<hidl::base::V1_0::IBase>> ret = manager->get(ifaceNameHStr, serviceNameHStr);
-
-    if (!ret.isOk()) {
-        signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
-        return NULL;
-    }
-
+    sp<IBase> ret = getRawServiceInternal(ifaceName, serviceName, retry /* retry */, false /* getStub */);
     sp<hardware::IBinder> service = hardware::toBinder<hidl::base::V1_0::IBase>(ret);
 
     if (service == NULL) {
@@ -391,13 +328,14 @@
         return NULL;
     }
 
-    LOG(INFO) << "Starting thread pool.";
+    LOG(INFO) << "HwBinder: Starting thread pool for " << serviceName << "::" << ifaceName;
     ::android::hardware::ProcessState::self()->startThreadPool();
 
     return JHwRemoteBinder::NewObject(env, service);
 }
 
-void JHwBinder_native_configureRpcThreadpool(jlong maxThreads, jboolean callerWillJoin) {
+void JHwBinder_native_configureRpcThreadpool(JNIEnv *, jclass,
+        jlong maxThreads, jboolean callerWillJoin) {
     CHECK(maxThreads > 0);
     ProcessState::self()->setThreadPoolConfiguration(maxThreads, callerWillJoin /*callerJoinsPool*/);
 }
@@ -406,7 +344,7 @@
     IPCThreadState::self()->joinThreadPool();
 }
 
-static void JHwBinder_report_sysprop_change(JNIEnv /**env*/, jobject /*clazz*/)
+static void JHwBinder_report_sysprop_change(JNIEnv * /*env*/, jclass /*clazz*/)
 {
     report_sysprop_change();
 }
@@ -422,7 +360,7 @@
     { "registerService", "(Ljava/lang/String;)V",
         (void *)JHwBinder_native_registerService },
 
-    { "getService", "(Ljava/lang/String;Ljava/lang/String;)L" PACKAGE_PATH "/IHwBinder;",
+    { "getService", "(Ljava/lang/String;Ljava/lang/String;Z)L" PACKAGE_PATH "/IHwBinder;",
         (void *)JHwBinder_native_getService },
 
     { "configureRpcThreadpool", "(JZ)V",
diff --git a/core/jni/android_os_HwBlob.cpp b/core/jni/android_os_HwBlob.cpp
index 40d49b7..bb916d2 100644
--- a/core/jni/android_os_HwBlob.cpp
+++ b/core/jni/android_os_HwBlob.cpp
@@ -26,6 +26,7 @@
 #include <android_runtime/AndroidRuntime.h>
 #include <hidl/Status.h>
 #include <nativehelper/ScopedLocalRef.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
 
 #include "core_jni_helpers.h"
 
@@ -60,12 +61,12 @@
         JNIEnv *env, jobject thiz, const sp<JHwBlob> &context) {
     sp<JHwBlob> old = (JHwBlob *)env->GetLongField(thiz, gFields.contextID);
 
-    if (context != NULL) {
-        context->incStrong(NULL /* id */);
+    if (context != nullptr) {
+        context->incStrong(nullptr /* id */);
     }
 
-    if (old != NULL) {
-        old->decStrong(NULL /* id */);
+    if (old != nullptr) {
+        old->decStrong(nullptr /* id */);
     }
 
     env->SetLongField(thiz, gFields.contextID, (long)context.get());
@@ -150,6 +151,10 @@
     return mBuffer;
 }
 
+void *JHwBlob::data() {
+    return mBuffer;
+}
+
 size_t JHwBlob::size() const {
     return mSize;
 }
@@ -242,8 +247,8 @@
 static void releaseNativeContext(void *nativeContext) {
     sp<JHwBlob> parcel = (JHwBlob *)nativeContext;
 
-    if (parcel != NULL) {
-        parcel->decStrong(NULL /* id */);
+    if (parcel != nullptr) {
+        parcel->decStrong(nullptr /* id */);
     }
 }
 
@@ -313,6 +318,82 @@
     return env->NewStringUTF(s->c_str());
 }
 
+#define DEFINE_BLOB_ARRAY_COPIER(Suffix,Type,NewType)                          \
+static void JHwBlob_native_copyTo ## Suffix ## Array(                          \
+        JNIEnv *env,                                                           \
+        jobject thiz,                                                          \
+        jlong offset,                                                          \
+        Type ## Array array,                                                   \
+        jint size) {                                                           \
+    if (array == nullptr) {                                                    \
+        jniThrowException(env, "java/lang/NullPointerException", nullptr);     \
+        return;                                                                \
+    }                                                                          \
+                                                                               \
+    if (env->GetArrayLength(array) < size) {                                   \
+        signalExceptionForError(env, BAD_VALUE);                               \
+        return;                                                                \
+    }                                                                          \
+                                                                               \
+    sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);                   \
+                                                                               \
+    if ((offset + size * sizeof(Type)) > blob->size()) {                       \
+        signalExceptionForError(env, -ERANGE);                                 \
+        return;                                                                \
+    }                                                                          \
+                                                                               \
+    env->Set ## NewType ## ArrayRegion(                                        \
+            array,                                                             \
+            0 /* start */,                                                     \
+            size,                                                              \
+            reinterpret_cast<const Type *>(                                    \
+                static_cast<const uint8_t *>(blob->data()) + offset));         \
+}
+
+DEFINE_BLOB_ARRAY_COPIER(Int8,jbyte,Byte)
+DEFINE_BLOB_ARRAY_COPIER(Int16,jshort,Short)
+DEFINE_BLOB_ARRAY_COPIER(Int32,jint,Int)
+DEFINE_BLOB_ARRAY_COPIER(Int64,jlong,Long)
+DEFINE_BLOB_ARRAY_COPIER(Float,jfloat,Float)
+DEFINE_BLOB_ARRAY_COPIER(Double,jdouble,Double)
+
+static void JHwBlob_native_copyToBoolArray(
+        JNIEnv *env,
+        jobject thiz,
+        jlong offset,
+        jbooleanArray array,
+        jint size) {
+    if (array == nullptr) {
+        jniThrowException(env, "java/lang/NullPointerException", nullptr);
+        return;
+    }
+
+    if (env->GetArrayLength(array) < size) {
+        signalExceptionForError(env, BAD_VALUE);
+        return;
+    }
+
+    sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
+
+    if ((offset + size * sizeof(bool)) > blob->size()) {
+        signalExceptionForError(env, -ERANGE);
+        return;
+    }
+
+    const bool *src =
+        reinterpret_cast<const bool *>(
+                static_cast<const uint8_t *>(blob->data()) + offset);
+
+    jboolean *dst = env->GetBooleanArrayElements(array, nullptr /* isCopy */);
+
+    for (jint i = 0; i < size; ++i) {
+        dst[i] = src[i];
+    }
+
+    env->ReleaseBooleanArrayElements(array, dst, 0 /* mode */);
+    dst = nullptr;
+}
+
 #define DEFINE_BLOB_PUTTER(Suffix,Type)                                        \
 static void JHwBlob_native_put ## Suffix(                                      \
         JNIEnv *env, jobject thiz, jlong offset, Type x) {                     \
@@ -375,6 +456,59 @@
     blob->putBlob(offset + hidl_string::kOffsetOfBuffer, subBlob);
 }
 
+#define DEFINE_BLOB_ARRAY_PUTTER(Suffix,Type,NewType)                          \
+static void JHwBlob_native_put ## Suffix ## Array(                             \
+        JNIEnv *env, jobject thiz, jlong offset, Type ## Array array) {        \
+    Scoped ## NewType ## ArrayRO autoArray(env, array);                        \
+                                                                               \
+    if (array == nullptr) {                                                    \
+        /* NullpointerException already pending */                             \
+        return;                                                                \
+    }                                                                          \
+                                                                               \
+    sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);                   \
+                                                                               \
+    status_t err = blob->write(                                                \
+            offset, autoArray.get(), autoArray.size() * sizeof(Type));         \
+                                                                               \
+    if (err != OK) {                                                           \
+        signalExceptionForError(env, err);                                     \
+    }                                                                          \
+}
+
+DEFINE_BLOB_ARRAY_PUTTER(Int8,jbyte,Byte)
+DEFINE_BLOB_ARRAY_PUTTER(Int16,jshort,Short)
+DEFINE_BLOB_ARRAY_PUTTER(Int32,jint,Int)
+DEFINE_BLOB_ARRAY_PUTTER(Int64,jlong,Long)
+DEFINE_BLOB_ARRAY_PUTTER(Float,jfloat,Float)
+DEFINE_BLOB_ARRAY_PUTTER(Double,jdouble,Double)
+
+static void JHwBlob_native_putBoolArray(
+        JNIEnv *env, jobject thiz, jlong offset, jbooleanArray array) {
+    ScopedBooleanArrayRO autoArray(env, array);
+
+    if (array == nullptr) {
+        /* NullpointerException already pending */
+        return;
+    }
+
+    sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
+
+    if ((offset + autoArray.size() * sizeof(bool)) > blob->size()) {
+        signalExceptionForError(env, -ERANGE);
+        return;
+    }
+
+    const jboolean *src = autoArray.get();
+
+    bool *dst = reinterpret_cast<bool *>(
+            static_cast<uint8_t *>(blob->data()) + offset);
+
+    for (size_t i = 0; i < autoArray.size(); ++i) {
+        dst[i] = src[i];
+    }
+}
+
 static void JHwBlob_native_putBlob(
         JNIEnv *env, jobject thiz, jlong offset, jobject blobObj) {
     if (blobObj == nullptr) {
@@ -413,6 +547,14 @@
     { "getDouble", "(J)D", (void *)JHwBlob_native_getDouble },
     { "getString", "(J)Ljava/lang/String;", (void *)JHwBlob_native_getString },
 
+    { "copyToBoolArray", "(J[ZI)V", (void *)JHwBlob_native_copyToBoolArray },
+    { "copyToInt8Array", "(J[BI)V", (void *)JHwBlob_native_copyToInt8Array },
+    { "copyToInt16Array", "(J[SI)V", (void *)JHwBlob_native_copyToInt16Array },
+    { "copyToInt32Array", "(J[II)V", (void *)JHwBlob_native_copyToInt32Array },
+    { "copyToInt64Array", "(J[JI)V", (void *)JHwBlob_native_copyToInt64Array },
+    { "copyToFloatArray", "(J[FI)V", (void *)JHwBlob_native_copyToFloatArray },
+    { "copyToDoubleArray", "(J[DI)V", (void *)JHwBlob_native_copyToDoubleArray },
+
     { "putBool", "(JZ)V", (void *)JHwBlob_native_putBool },
     { "putInt8", "(JB)V", (void *)JHwBlob_native_putInt8 },
     { "putInt16", "(JS)V", (void *)JHwBlob_native_putInt16 },
@@ -422,6 +564,14 @@
     { "putDouble", "(JD)V", (void *)JHwBlob_native_putDouble },
     { "putString", "(JLjava/lang/String;)V", (void *)JHwBlob_native_putString },
 
+    { "putBoolArray", "(J[Z)V", (void *)JHwBlob_native_putBoolArray },
+    { "putInt8Array", "(J[B)V", (void *)JHwBlob_native_putInt8Array },
+    { "putInt16Array", "(J[S)V", (void *)JHwBlob_native_putInt16Array },
+    { "putInt32Array", "(J[I)V", (void *)JHwBlob_native_putInt32Array },
+    { "putInt64Array", "(J[J)V", (void *)JHwBlob_native_putInt64Array },
+    { "putFloatArray", "(J[F)V", (void *)JHwBlob_native_putFloatArray },
+    { "putDoubleArray", "(J[D)V", (void *)JHwBlob_native_putDoubleArray },
+
     { "putBlob", "(JL" PACKAGE_PATH "/HwBlob;)V",
         (void *)JHwBlob_native_putBlob },
 
diff --git a/core/jni/android_os_HwBlob.h b/core/jni/android_os_HwBlob.h
index 39393cb..6b1db63 100644
--- a/core/jni/android_os_HwBlob.h
+++ b/core/jni/android_os_HwBlob.h
@@ -50,6 +50,8 @@
             size_t offset, const android::hardware::hidl_string **s) const;
 
     const void *data() const;
+    void *data();
+
     size_t size() const;
 
     status_t putBlob(size_t offset, const sp<JHwBlob> &blob);
diff --git a/core/jni/android_os_HwRemoteBinder.cpp b/core/jni/android_os_HwRemoteBinder.cpp
index cf59a56a..ca5e1e4 100644
--- a/core/jni/android_os_HwRemoteBinder.cpp
+++ b/core/jni/android_os_HwRemoteBinder.cpp
@@ -22,9 +22,13 @@
 
 #include "android_os_HwParcel.h"
 
-#include <nativehelper/JNIHelp.h>
+#include <android/hidl/base/1.0/IBase.h>
+#include <android/hidl/base/1.0/BpHwBase.h>
+#include <android/hidl/base/1.0/BnHwBase.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <hidl/Status.h>
+#include <hidl/HidlTransportSupport.h>
+#include <nativehelper/JNIHelp.h>
 #include <nativehelper/ScopedUtfChars.h>
 #include <nativehelper/ScopedLocalRef.h>
 
@@ -413,6 +417,44 @@
     return res;
 }
 
+static sp<hidl::base::V1_0::IBase> toIBase(JNIEnv* env, jclass hwRemoteBinderClazz, jobject jbinder)
+{
+    if (jbinder == nullptr) {
+        return nullptr;
+    }
+    if (!env->IsInstanceOf(jbinder, hwRemoteBinderClazz)) {
+        return nullptr;
+    }
+    sp<JHwRemoteBinder> context = JHwRemoteBinder::GetNativeContext(env, jbinder);
+    sp<hardware::IBinder> cbinder = context->getBinder();
+    return hardware::fromBinder<hidl::base::V1_0::IBase, hidl::base::V1_0::BpHwBase,
+                                hidl::base::V1_0::BnHwBase>(cbinder);
+}
+
+// equals iff other is also a non-null android.os.HwRemoteBinder object
+// and getBinder() returns the same object.
+// In particular, if other is an android.os.HwBinder object (for stubs) then
+// it returns false.
+static jboolean JHwRemoteBinder_equals(JNIEnv* env, jobject thiz, jobject other)
+{
+    if (env->IsSameObject(thiz, other)) {
+        return true;
+    }
+    if (other == NULL) {
+        return false;
+    }
+
+    ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, CLASS_PATH));
+
+    return hardware::interfacesEqual(toIBase(env, clazz.get(), thiz), toIBase(env, clazz.get(), other));
+}
+
+static jint JHwRemoteBinder_hashCode(JNIEnv* env, jobject thiz) {
+    jlong longHash = reinterpret_cast<jlong>(
+            JHwRemoteBinder::GetNativeContext(env, thiz)->getBinder().get());
+    return static_cast<jint>(longHash ^ (longHash >> 32)); // See Long.hashCode()
+}
+
 static JNINativeMethod gMethods[] = {
     { "native_init", "()J", (void *)JHwRemoteBinder_native_init },
 
@@ -430,6 +472,11 @@
     {"unlinkToDeath",
         "(Landroid/os/IHwBinder$DeathRecipient;)Z",
         (void*)JHwRemoteBinder_unlinkToDeath},
+
+    {"equals", "(Ljava/lang/Object;)Z",
+        (void*)JHwRemoteBinder_equals},
+
+    {"hashCode", "()I", (void*)JHwRemoteBinder_hashCode},
 };
 
 namespace android {
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 8941002..fc8b8f3 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -164,8 +164,8 @@
     }
 }
 
-static void android_os_Parcel_writeNative(JNIEnv* env, jclass clazz, jlong nativePtr, jobject data,
-                                          jint offset, jint length)
+static void android_os_Parcel_writeByteArray(JNIEnv* env, jclass clazz, jlong nativePtr,
+                                             jobject data, jint offset, jint length)
 {
     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
     if (parcel == NULL) {
@@ -346,6 +346,28 @@
     return ret;
 }
 
+static jboolean android_os_Parcel_readByteArray(JNIEnv* env, jclass clazz, jlong nativePtr,
+                                                jobject dest, jint destLen)
+{
+    jboolean ret = JNI_FALSE;
+    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+    if (parcel == NULL) {
+        return ret;
+    }
+
+    int32_t len = parcel->readInt32();
+    if (len >= 0 && len <= (int32_t)parcel->dataAvail() && len == destLen) {
+        jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)dest, 0);
+        if (ar) {
+            const void* data = parcel->readInplace(len);
+            memcpy(ar, data, len);
+            env->ReleasePrimitiveArrayCritical((jarray)dest, ar, 0);
+            ret = JNI_TRUE;
+        }
+    }
+    return ret;
+}
+
 static jbyteArray android_os_Parcel_readBlob(JNIEnv* env, jclass clazz, jlong nativePtr)
 {
     jbyteArray ret = NULL;
@@ -757,7 +779,7 @@
     // @FastNative
     {"nativeRestoreAllowFds",     "(JZ)V", (void*)android_os_Parcel_restoreAllowFds},
 
-    {"nativeWriteByteArray",      "(J[BII)V", (void*)android_os_Parcel_writeNative},
+    {"nativeWriteByteArray",      "(J[BII)V", (void*)android_os_Parcel_writeByteArray},
     {"nativeWriteBlob",           "(J[BII)V", (void*)android_os_Parcel_writeBlob},
     // @FastNative
     {"nativeWriteInt",            "(JI)V", (void*)android_os_Parcel_writeInt},
@@ -772,6 +794,7 @@
     {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)J", (void*)android_os_Parcel_writeFileDescriptor},
 
     {"nativeCreateByteArray",     "(J)[B", (void*)android_os_Parcel_createByteArray},
+    {"nativeReadByteArray",       "(J[BI)Z", (void*)android_os_Parcel_readByteArray},
     {"nativeReadBlob",            "(J)[B", (void*)android_os_Parcel_readBlob},
     // @FastNative
     {"nativeReadInt",             "(J)I", (void*)android_os_Parcel_readInt},
diff --git a/core/jni/android_os_SystemProperties.cpp b/core/jni/android_os_SystemProperties.cpp
index 8844fb0..a94cac0 100644
--- a/core/jni/android_os_SystemProperties.cpp
+++ b/core/jni/android_os_SystemProperties.cpp
@@ -17,188 +17,109 @@
 
 #define LOG_TAG "SysPropJNI"
 
+#include "android-base/logging.h"
+#include "android-base/properties.h"
 #include "cutils/properties.h"
 #include "utils/misc.h"
 #include <utils/Log.h>
 #include "jni.h"
 #include "core_jni_helpers.h"
 #include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
+#include <nativehelper/ScopedUtfChars.h>
 
 namespace android
 {
 
-static jstring SystemProperties_getSS(JNIEnv *env, jobject clazz,
-                                      jstring keyJ, jstring defJ)
-{
-    int len;
-    const char* key;
-    char buf[PROPERTY_VALUE_MAX];
-    jstring rvJ = NULL;
+namespace {
 
-    if (keyJ == NULL) {
-        jniThrowNullPointerException(env, "key must not be null.");
-        goto error;
-    }
-
-    key = env->GetStringUTFChars(keyJ, NULL);
-
-    len = property_get(key, buf, "");
-    if ((len <= 0) && (defJ != NULL)) {
-        rvJ = defJ;
-    } else if (len >= 0) {
-        rvJ = env->NewStringUTF(buf);
-    } else {
-        rvJ = env->NewStringUTF("");
-    }
-
-    env->ReleaseStringUTFChars(keyJ, key);
-
-error:
-    return rvJ;
-}
-
-static jstring SystemProperties_getS(JNIEnv *env, jobject clazz,
-                                      jstring keyJ)
-{
-    return SystemProperties_getSS(env, clazz, keyJ, NULL);
-}
-
-static jint SystemProperties_get_int(JNIEnv *env, jobject clazz,
-                                      jstring keyJ, jint defJ)
-{
-    int len;
-    const char* key;
-    char buf[PROPERTY_VALUE_MAX];
-    char* end;
-    jint result = defJ;
-
-    if (keyJ == NULL) {
-        jniThrowNullPointerException(env, "key must not be null.");
-        goto error;
-    }
-
-    key = env->GetStringUTFChars(keyJ, NULL);
-
-    len = property_get(key, buf, "");
-    if (len > 0) {
-        result = strtol(buf, &end, 0);
-        if (end == buf) {
-            result = defJ;
+template <typename T, typename Handler>
+T ConvertKeyAndForward(JNIEnv *env, jstring keyJ, T defJ, Handler handler) {
+    std::string key;
+    {
+        // Scope the String access. If the handler can throw an exception,
+        // releasing the string characters late would trigger an abort.
+        ScopedUtfChars key_utf(env, keyJ);
+        if (key_utf.c_str() == nullptr) {
+            return defJ;
         }
+        key = key_utf.c_str();  // This will make a copy, but we can't avoid
+                                // with the existing interface in
+                                // android::base.
     }
-
-    env->ReleaseStringUTFChars(keyJ, key);
-
-error:
-    return result;
+    return handler(key, defJ);
 }
 
-static jlong SystemProperties_get_long(JNIEnv *env, jobject clazz,
-                                      jstring keyJ, jlong defJ)
+jstring SystemProperties_getSS(JNIEnv *env, jclass clazz, jstring keyJ,
+                               jstring defJ)
 {
-    int len;
-    const char* key;
-    char buf[PROPERTY_VALUE_MAX];
-    char* end;
-    jlong result = defJ;
-
-    if (keyJ == NULL) {
-        jniThrowNullPointerException(env, "key must not be null.");
-        goto error;
-    }
-
-    key = env->GetStringUTFChars(keyJ, NULL);
-
-    len = property_get(key, buf, "");
-    if (len > 0) {
-        result = strtoll(buf, &end, 0);
-        if (end == buf) {
-            result = defJ;
+    // Using ConvertKeyAndForward is sub-optimal for copying the key string,
+    // but improves reuse and reasoning over code.
+    auto handler = [&](const std::string& key, jstring defJ) {
+        std::string prop_val = android::base::GetProperty(key, "");
+        if (!prop_val.empty()) {
+            return env->NewStringUTF(prop_val.c_str());
+        };
+        if (defJ != nullptr) {
+            return defJ;
         }
-    }
-
-    env->ReleaseStringUTFChars(keyJ, key);
-
-error:
-    return result;
+        // This function is specified to never return null (or have an
+        // exception pending).
+        return env->NewStringUTF("");
+    };
+    return ConvertKeyAndForward(env, keyJ, defJ, handler);
 }
 
-static jboolean SystemProperties_get_boolean(JNIEnv *env, jobject clazz,
-                                      jstring keyJ, jboolean defJ)
+jstring SystemProperties_getS(JNIEnv *env, jclass clazz, jstring keyJ)
 {
-    int len;
-    const char* key;
-    char buf[PROPERTY_VALUE_MAX];
-    jboolean result = defJ;
+    return SystemProperties_getSS(env, clazz, keyJ, nullptr);
+}
 
-    if (keyJ == NULL) {
-        jniThrowNullPointerException(env, "key must not be null.");
-        goto error;
-    }
+template <typename T>
+T SystemProperties_get_integral(JNIEnv *env, jclass, jstring keyJ,
+                                       T defJ)
+{
+    auto handler = [](const std::string& key, T defV) {
+        return android::base::GetIntProperty<T>(key, defV);
+    };
+    return ConvertKeyAndForward(env, keyJ, defJ, handler);
+}
 
-    key = env->GetStringUTFChars(keyJ, NULL);
+jboolean SystemProperties_get_boolean(JNIEnv *env, jclass, jstring keyJ,
+                                      jboolean defJ)
+{
+    auto handler = [](const std::string& key, jboolean defV) -> jboolean {
+        bool result = android::base::GetBoolProperty(key, defV);
+        return result ? JNI_TRUE : JNI_FALSE;
+    };
+    return ConvertKeyAndForward(env, keyJ, defJ, handler);
+}
 
-    len = property_get(key, buf, "");
-    if (len == 1) {
-        char ch = buf[0];
-        if (ch == '0' || ch == 'n')
-            result = false;
-        else if (ch == '1' || ch == 'y')
-            result = true;
-    } else if (len > 1) {
-         if (!strcmp(buf, "no") || !strcmp(buf, "false") || !strcmp(buf, "off")) {
-            result = false;
-        } else if (!strcmp(buf, "yes") || !strcmp(buf, "true") || !strcmp(buf, "on")) {
-            result = true;
+void SystemProperties_set(JNIEnv *env, jobject clazz, jstring keyJ,
+                          jstring valJ)
+{
+    auto handler = [&](const std::string& key, bool) {
+        std::string val;
+        if (valJ != nullptr) {
+            ScopedUtfChars key_utf(env, valJ);
+            val = key_utf.c_str();
         }
-    }
-
-    env->ReleaseStringUTFChars(keyJ, key);
-
-error:
-    return result;
-}
-
-static void SystemProperties_set(JNIEnv *env, jobject clazz,
-                                      jstring keyJ, jstring valJ)
-{
-    int err;
-    const char* key;
-    const char* val;
-
-    if (keyJ == NULL) {
-        jniThrowNullPointerException(env, "key must not be null.");
-        return ;
-    }
-    key = env->GetStringUTFChars(keyJ, NULL);
-
-    if (valJ == NULL) {
-        val = "";       /* NULL pointer not allowed here */
-    } else {
-        val = env->GetStringUTFChars(valJ, NULL);
-    }
-
-    err = property_set(key, val);
-
-    env->ReleaseStringUTFChars(keyJ, key);
-
-    if (valJ != NULL) {
-        env->ReleaseStringUTFChars(valJ, val);
-    }
-
-    if (err < 0) {
+        return android::base::SetProperty(key, val);
+    };
+    if (!ConvertKeyAndForward(env, keyJ, true, handler)) {
+        // Must have been a failure in SetProperty.
         jniThrowException(env, "java/lang/RuntimeException",
                           "failed to set system property");
     }
 }
 
-static JavaVM* sVM = NULL;
-static jclass sClazz = NULL;
-static jmethodID sCallChangeCallbacks;
+JavaVM* sVM = nullptr;
+jclass sClazz = nullptr;
+jmethodID sCallChangeCallbacks;
 
-static void do_report_sysprop_change() {
+void do_report_sysprop_change() {
     //ALOGI("Java SystemProperties: VM=%p, Clazz=%p", sVM, sClazz);
-    if (sVM != NULL && sClazz != NULL) {
+    if (sVM != nullptr && sClazz != nullptr) {
         JNIEnv* env;
         if (sVM->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0) {
             //ALOGI("Java SystemProperties: calling %p", sCallChangeCallbacks);
@@ -207,47 +128,49 @@
     }
 }
 
-static void SystemProperties_add_change_callback(JNIEnv *env, jobject clazz)
+void SystemProperties_add_change_callback(JNIEnv *env, jobject clazz)
 {
     // This is called with the Java lock held.
-    if (sVM == NULL) {
+    if (sVM == nullptr) {
         env->GetJavaVM(&sVM);
     }
-    if (sClazz == NULL) {
+    if (sClazz == nullptr) {
         sClazz = (jclass) env->NewGlobalRef(clazz);
         sCallChangeCallbacks = env->GetStaticMethodID(sClazz, "callChangeCallbacks", "()V");
         add_sysprop_change_callback(do_report_sysprop_change, -10000);
     }
 }
 
-static void SystemProperties_report_sysprop_change(JNIEnv /**env*/, jobject /*clazz*/)
+void SystemProperties_report_sysprop_change(JNIEnv /**env*/, jobject /*clazz*/)
 {
     report_sysprop_change();
 }
 
-static const JNINativeMethod method_table[] = {
-    { "native_get", "(Ljava/lang/String;)Ljava/lang/String;",
-      (void*) SystemProperties_getS },
-    { "native_get", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
-      (void*) SystemProperties_getSS },
-    { "native_get_int", "(Ljava/lang/String;I)I",
-      (void*) SystemProperties_get_int },
-    { "native_get_long", "(Ljava/lang/String;J)J",
-      (void*) SystemProperties_get_long },
-    { "native_get_boolean", "(Ljava/lang/String;Z)Z",
-      (void*) SystemProperties_get_boolean },
-    { "native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
-      (void*) SystemProperties_set },
-    { "native_add_change_callback", "()V",
-      (void*) SystemProperties_add_change_callback },
-    { "native_report_sysprop_change", "()V",
-      (void*) SystemProperties_report_sysprop_change },
-};
+}  // namespace
 
 int register_android_os_SystemProperties(JNIEnv *env)
 {
-    return RegisterMethodsOrDie(env, "android/os/SystemProperties", method_table,
-                                NELEM(method_table));
+    const JNINativeMethod method_table[] = {
+        { "native_get", "(Ljava/lang/String;)Ljava/lang/String;",
+          (void*) SystemProperties_getS },
+        { "native_get",
+          "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
+          (void*) SystemProperties_getSS },
+        { "native_get_int", "(Ljava/lang/String;I)I",
+          (void*) SystemProperties_get_integral<jint> },
+        { "native_get_long", "(Ljava/lang/String;J)J",
+          (void*) SystemProperties_get_integral<jlong> },
+        { "native_get_boolean", "(Ljava/lang/String;Z)Z",
+          (void*) SystemProperties_get_boolean },
+        { "native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
+          (void*) SystemProperties_set },
+        { "native_add_change_callback", "()V",
+          (void*) SystemProperties_add_change_callback },
+        { "native_report_sysprop_change", "()V",
+          (void*) SystemProperties_report_sysprop_change },
+    };
+    return RegisterMethodsOrDie(env, "android/os/SystemProperties",
+                                method_table, NELEM(method_table));
 }
 
 };
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
index 7ec4b8e..5ef2a9e 100644
--- a/core/jni/android_os_VintfObject.cpp
+++ b/core/jni/android_os_VintfObject.cpp
@@ -56,7 +56,7 @@
 }
 
 template<typename T>
-static void tryAddSchema(const T* object, const XmlConverter<T>& converter,
+static void tryAddSchema(const std::shared_ptr<const T>& object, const XmlConverter<T>& converter,
         const std::string& description,
         std::vector<std::string>* cStrings) {
     if (object == nullptr) {
@@ -66,7 +66,7 @@
     }
 }
 
-static void tryAddHalNamesAndVersions(const HalManifest *manifest,
+static void tryAddHalNamesAndVersions(const std::shared_ptr<const HalManifest>& manifest,
         const std::string& description,
         std::set<std::string> *output) {
     if (manifest == nullptr) {
@@ -119,7 +119,7 @@
 }
 
 static jstring android_os_VintfObject_getSepolicyVersion(JNIEnv* env, jclass) {
-    const HalManifest *manifest = VintfObject::GetDeviceHalManifest();
+    std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest();
     if (manifest == nullptr || manifest->type() != SchemaType::DEVICE) {
         LOG(WARNING) << __FUNCTION__ << "Cannot get device manifest";
         return nullptr;
@@ -129,7 +129,7 @@
 }
 
 static jobject android_os_VintfObject_getVndkSnapshots(JNIEnv* env, jclass) {
-    const HalManifest *manifest = VintfObject::GetFrameworkHalManifest();
+    std::shared_ptr<const HalManifest> manifest = VintfObject::GetFrameworkHalManifest();
     if (manifest == nullptr || manifest->type() != SchemaType::FRAMEWORK) {
         LOG(WARNING) << __FUNCTION__ << "Cannot get framework manifest";
         return nullptr;
diff --git a/core/jni/android_os_VintfRuntimeInfo.cpp b/core/jni/android_os_VintfRuntimeInfo.cpp
index 19220cf0..9379ea6 100644
--- a/core/jni/android_os_VintfRuntimeInfo.cpp
+++ b/core/jni/android_os_VintfRuntimeInfo.cpp
@@ -29,28 +29,33 @@
 using vintf::RuntimeInfo;
 using vintf::VintfObject;
 
-#define MAP_STRING_METHOD(javaMethod, cppString)                                       \
+#define MAP_STRING_METHOD(javaMethod, cppString, flags)                                \
     static jstring android_os_VintfRuntimeInfo_##javaMethod(JNIEnv* env, jclass clazz) \
     {                                                                                  \
-        const RuntimeInfo *info = VintfObject::GetRuntimeInfo();                       \
+        std::shared_ptr<const RuntimeInfo> info = VintfObject::GetRuntimeInfo(         \
+                false /* skipCache */, flags);                                         \
         if (info == nullptr) return nullptr;                                           \
         return env->NewStringUTF((cppString).c_str());                                 \
     }                                                                                  \
 
-MAP_STRING_METHOD(getCpuInfo, info->cpuInfo());
-MAP_STRING_METHOD(getOsName, info->osName());
-MAP_STRING_METHOD(getNodeName, info->nodeName());
-MAP_STRING_METHOD(getOsRelease, info->osRelease());
-MAP_STRING_METHOD(getOsVersion, info->osVersion());
-MAP_STRING_METHOD(getHardwareId, info->hardwareId());
-MAP_STRING_METHOD(getKernelVersion, vintf::to_string(info->kernelVersion()));
-MAP_STRING_METHOD(getBootAvbVersion, vintf::to_string(info->bootAvbVersion()));
-MAP_STRING_METHOD(getBootVbmetaAvbVersion, vintf::to_string(info->bootVbmetaAvbVersion()));
+MAP_STRING_METHOD(getCpuInfo, info->cpuInfo(), RuntimeInfo::FetchFlag::CPU_INFO);
+MAP_STRING_METHOD(getOsName, info->osName(), RuntimeInfo::FetchFlag::CPU_VERSION);
+MAP_STRING_METHOD(getNodeName, info->nodeName(), RuntimeInfo::FetchFlag::CPU_VERSION);
+MAP_STRING_METHOD(getOsRelease, info->osRelease(), RuntimeInfo::FetchFlag::CPU_VERSION);
+MAP_STRING_METHOD(getOsVersion, info->osVersion(), RuntimeInfo::FetchFlag::CPU_VERSION);
+MAP_STRING_METHOD(getHardwareId, info->hardwareId(), RuntimeInfo::FetchFlag::CPU_VERSION);
+MAP_STRING_METHOD(getKernelVersion, vintf::to_string(info->kernelVersion()),
+                  RuntimeInfo::FetchFlag::CPU_VERSION);
+MAP_STRING_METHOD(getBootAvbVersion, vintf::to_string(info->bootAvbVersion()),
+                  RuntimeInfo::FetchFlag::AVB);
+MAP_STRING_METHOD(getBootVbmetaAvbVersion, vintf::to_string(info->bootVbmetaAvbVersion()),
+                  RuntimeInfo::FetchFlag::AVB);
 
 
 static jlong android_os_VintfRuntimeInfo_getKernelSepolicyVersion(JNIEnv *env, jclass clazz)
 {
-    const RuntimeInfo *info = VintfObject::GetRuntimeInfo();
+    std::shared_ptr<const RuntimeInfo> info = VintfObject::GetRuntimeInfo(
+        false /* skipCache */, RuntimeInfo::FetchFlag::POLICYVERS);
     if (info == nullptr) return 0;
     return static_cast<jlong>(info->kernelSepolicyVersion());
 }
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 5b0f776..560c384 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -20,8 +20,7 @@
 #include "android_os_Parcel.h"
 #include "android_util_Binder.h"
 
-#include <nativehelper/JNIHelp.h>
-
+#include <atomic>
 #include <fcntl.h>
 #include <inttypes.h>
 #include <stdio.h>
@@ -44,8 +43,9 @@
 #include <utils/SystemClock.h>
 #include <utils/threads.h>
 
-#include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/JNIHelp.h>
 #include <nativehelper/ScopedLocalRef.h>
+#include <nativehelper/ScopedUtfChars.h>
 
 #include "core_jni_helpers.h"
 
@@ -97,14 +97,11 @@
 {
     // Class state.
     jclass mClass;
-    jmethodID mConstructor;
+    jmethodID mGetInstance;
     jmethodID mSendDeathNotice;
 
     // Object state.
-    jfieldID mObject;
-    jfieldID mSelf;
-    jfieldID mOrgue;
-
+    jfieldID mNativeData;  // Field holds native pointer to BinderProxyNativeData.
 } gBinderProxyOffsets;
 
 static struct class_offsets_t
@@ -133,24 +130,58 @@
     jmethodID mCallback;
 } gStrictModeCallbackOffsets;
 
-// ****************************************************************************
-// ****************************************************************************
-// ****************************************************************************
-
-static volatile int32_t gNumRefsCreated = 0;
-static volatile int32_t gNumProxyRefs = 0;
-static volatile int32_t gNumLocalRefs = 0;
-static volatile int32_t gNumDeathRefs = 0;
-
-static void incRefsCreated(JNIEnv* env)
+static struct thread_dispatch_offsets_t
 {
-    int old = android_atomic_inc(&gNumRefsCreated);
-    if (old == 200) {
-        android_atomic_and(0, &gNumRefsCreated);
-        env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
-                gBinderInternalOffsets.mForceGc);
+    // Class state.
+    jclass mClass;
+    jmethodID mDispatchUncaughtException;
+    jmethodID mCurrentThread;
+} gThreadDispatchOffsets;
+
+// ****************************************************************************
+// ****************************************************************************
+// ****************************************************************************
+
+static constexpr int32_t PROXY_WARN_INTERVAL = 5000;
+static constexpr uint32_t GC_INTERVAL = 1000;
+
+// Protected by gProxyLock. We warn if this gets too large.
+static int32_t gNumProxies = 0;
+static int32_t gProxiesWarned = 0;
+
+// Number of GlobalRefs held by JavaBBinders.
+static std::atomic<uint32_t> gNumLocalRefsCreated(0);
+static std::atomic<uint32_t> gNumLocalRefsDeleted(0);
+// Number of GlobalRefs held by JavaDeathRecipients.
+static std::atomic<uint32_t> gNumDeathRefsCreated(0);
+static std::atomic<uint32_t> gNumDeathRefsDeleted(0);
+
+// We collected after creating this many refs.
+static std::atomic<uint32_t> gCollectedAtRefs(0);
+
+// Garbage collect if we've allocated at least GC_INTERVAL refs since the last time.
+// TODO: Consider removing this completely. We should no longer be generating GlobalRefs
+// that are reclaimed as a result of GC action.
+__attribute__((no_sanitize("unsigned-integer-overflow")))
+static void gcIfManyNewRefs(JNIEnv* env)
+{
+    uint32_t totalRefs = gNumLocalRefsCreated.load(std::memory_order_relaxed)
+            + gNumDeathRefsCreated.load(std::memory_order_relaxed);
+    uint32_t collectedAtRefs = gCollectedAtRefs.load(memory_order_relaxed);
+    // A bound on the number of threads that can have incremented gNum...RefsCreated before the
+    // following check is executed. Effectively a bound on #threads. Almost any value will do.
+    static constexpr uint32_t MAX_RACING = 100000;
+
+    if (totalRefs - (collectedAtRefs + GC_INTERVAL) /* modular arithmetic! */ < MAX_RACING) {
+        // Recently passed next GC interval.
+        if (gCollectedAtRefs.compare_exchange_strong(collectedAtRefs,
+                collectedAtRefs + GC_INTERVAL, std::memory_order_relaxed)) {
+            ALOGV("Binder forcing GC at %u created refs", totalRefs);
+            env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
+                    gBinderInternalOffsets.mForceGc);
+        }  // otherwise somebody else beat us to it.
     } else {
-        ALOGV("Now have %d binder ops", old);
+        ALOGV("Now have %d binder ops", totalRefs - collectedAtRefs);
     }
 }
 
@@ -166,69 +197,93 @@
     return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
 }
 
+// Report a java.lang.Error (or subclass). This will terminate the runtime by
+// calling FatalError with a message derived from the given error.
+static void report_java_lang_error_fatal_error(JNIEnv* env, jthrowable error,
+        const char* msg)
+{
+    // Report an error: reraise the exception and ask the runtime to abort.
+
+    // Try to get the exception string. Sometimes logcat isn't available,
+    // so try to add it to the abort message.
+    std::string exc_msg = "(Unknown exception message)";
+    {
+        ScopedLocalRef<jclass> exc_class(env, env->GetObjectClass(error));
+        jmethodID method_id = env->GetMethodID(exc_class.get(), "toString",
+                "()Ljava/lang/String;");
+        ScopedLocalRef<jstring> jstr(
+                env,
+                reinterpret_cast<jstring>(
+                        env->CallObjectMethod(error, method_id)));
+        env->ExceptionClear();  // Just for good measure.
+        if (jstr.get() != nullptr) {
+            ScopedUtfChars jstr_utf(env, jstr.get());
+            if (jstr_utf.c_str() != nullptr) {
+                exc_msg = jstr_utf.c_str();
+            } else {
+                env->ExceptionClear();
+            }
+        }
+    }
+
+    env->Throw(error);
+    ALOGE("java.lang.Error thrown during binder transaction (stack trace follows) : ");
+    env->ExceptionDescribe();
+
+    std::string error_msg = base::StringPrintf(
+            "java.lang.Error thrown during binder transaction: %s",
+            exc_msg.c_str());
+    env->FatalError(error_msg.c_str());
+}
+
+// Report a java.lang.Error (or subclass). This will terminate the runtime, either by
+// the uncaught exception handler, or explicitly by calling
+// report_java_lang_error_fatal_error.
+static void report_java_lang_error(JNIEnv* env, jthrowable error, const char* msg)
+{
+    // Try to run the uncaught exception machinery.
+    jobject thread = env->CallStaticObjectMethod(gThreadDispatchOffsets.mClass,
+            gThreadDispatchOffsets.mCurrentThread);
+    if (thread != nullptr) {
+        env->CallVoidMethod(thread, gThreadDispatchOffsets.mDispatchUncaughtException,
+                error);
+        // Should not return here, unless more errors occured.
+    }
+    // Some error occurred that meant that either dispatchUncaughtException could not be
+    // called or that it had an error itself (as this should be unreachable under normal
+    // conditions). As the binder code cannot handle Errors, attempt to log the error and
+    // abort.
+    env->ExceptionClear();
+    report_java_lang_error_fatal_error(env, error, msg);
+}
+
 static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
 {
     env->ExceptionClear();
 
-    jstring tagstr = env->NewStringUTF(LOG_TAG);
-    jstring msgstr = NULL;
-    if (tagstr != NULL) {
-        msgstr = env->NewStringUTF(msg);
+    ScopedLocalRef<jstring> tagstr(env, env->NewStringUTF(LOG_TAG));
+    ScopedLocalRef<jstring> msgstr(env);
+    if (tagstr != nullptr) {
+        msgstr.reset(env->NewStringUTF(msg));
     }
 
-    if ((tagstr == NULL) || (msgstr == NULL)) {
+    if ((tagstr != nullptr) && (msgstr != nullptr)) {
+        env->CallStaticIntMethod(gLogOffsets.mClass, gLogOffsets.mLogE,
+                tagstr.get(), msgstr.get(), excep);
+        if (env->ExceptionCheck()) {
+            // Attempting to log the failure has failed.
+            ALOGW("Failed trying to log exception, msg='%s'\n", msg);
+            env->ExceptionClear();
+        }
+    } else {
         env->ExceptionClear();      /* assume exception (OOM?) was thrown */
         ALOGE("Unable to call Log.e()\n");
         ALOGE("%s", msg);
-        goto bail;
-    }
-
-    env->CallStaticIntMethod(
-        gLogOffsets.mClass, gLogOffsets.mLogE, tagstr, msgstr, excep);
-    if (env->ExceptionCheck()) {
-        /* attempting to log the failure has failed */
-        ALOGW("Failed trying to log exception, msg='%s'\n", msg);
-        env->ExceptionClear();
     }
 
     if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
-        /*
-         * It's an Error: Reraise the exception and ask the runtime to abort.
-         */
-
-        // Try to get the exception string. Sometimes logcat isn't available,
-        // so try to add it to the abort message.
-        std::string exc_msg = "(Unknown exception message)";
-        {
-            ScopedLocalRef<jclass> exc_class(env, env->GetObjectClass(excep));
-            jmethodID method_id = env->GetMethodID(exc_class.get(),
-                                                   "toString",
-                                                   "()Ljava/lang/String;");
-            ScopedLocalRef<jstring> jstr(
-                    env,
-                    reinterpret_cast<jstring>(
-                            env->CallObjectMethod(excep, method_id)));
-            env->ExceptionClear();  // Just for good measure.
-            if (jstr.get() != nullptr) {
-                ScopedUtfChars jstr_utf(env, jstr.get());
-                exc_msg = jstr_utf.c_str();
-            }
-        }
-
-        env->Throw(excep);
-        ALOGE("java.lang.Error thrown during binder transaction (stack trace follows) : ");
-        env->ExceptionDescribe();
-
-        std::string error_msg = base::StringPrintf(
-                "java.lang.Error thrown during binder transaction: %s",
-                exc_msg.c_str());
-        env->FatalError(error_msg.c_str());
+        report_java_lang_error(env, excep, msg);
     }
-
-bail:
-    /* discard local refs created for us by VM */
-    env->DeleteLocalRef(tagstr);
-    env->DeleteLocalRef(msgstr);
 }
 
 class JavaBBinderHolder;
@@ -236,12 +291,12 @@
 class JavaBBinder : public BBinder
 {
 public:
-    JavaBBinder(JNIEnv* env, jobject object)
+    JavaBBinder(JNIEnv* env, jobject /* Java Binder */ object)
         : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
     {
         ALOGV("Creating JavaBBinder %p\n", this);
-        android_atomic_inc(&gNumLocalRefs);
-        incRefsCreated(env);
+        gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);
+        gcIfManyNewRefs(env);
     }
 
     bool    checkSubclass(const void* subclassID) const
@@ -258,7 +313,7 @@
     virtual ~JavaBBinder()
     {
         ALOGV("Destroying JavaBBinder %p\n", this);
-        android_atomic_dec(&gNumLocalRefs);
+        gNumLocalRefsDeleted.fetch_add(1, memory_order_relaxed);
         JNIEnv* env = javavm_to_jnienv(mVM);
         env->DeleteGlobalRef(mObject);
     }
@@ -280,14 +335,11 @@
             code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
 
         if (env->ExceptionCheck()) {
-            jthrowable excep = env->ExceptionOccurred();
-            report_exception(env, excep,
+            ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
+            report_exception(env, excep.get(),
                 "*** Uncaught remote exception!  "
                 "(Exceptions are not yet supported across processes.)");
             res = JNI_FALSE;
-
-            /* clean up JNI local ref -- we don't return to Java code */
-            env->DeleteLocalRef(excep);
         }
 
         // Check if the strict mode state changed while processing the
@@ -299,11 +351,9 @@
         }
 
         if (env->ExceptionCheck()) {
-            jthrowable excep = env->ExceptionOccurred();
-            report_exception(env, excep,
+            ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
+            report_exception(env, excep.get(),
                 "*** Uncaught exception in onBinderStrictModePolicyChange");
-            /* clean up JNI local ref -- we don't return to Java code */
-            env->DeleteLocalRef(excep);
         }
 
         // Need to always call through the native implementation of
@@ -325,12 +375,12 @@
 
 private:
     JavaVM* const   mVM;
-    jobject const   mObject;
+    jobject const   mObject;  // GlobalRef to Java Binder
 };
 
 // ----------------------------------------------------------------------------
 
-class JavaBBinderHolder : public RefBase
+class JavaBBinderHolder
 {
 public:
     sp<JavaBBinder> get(JNIEnv* env, jobject obj)
@@ -395,8 +445,8 @@
         LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
         list->add(this);
 
-        android_atomic_inc(&gNumDeathRefs);
-        incRefsCreated(env);
+        gNumDeathRefsCreated.fetch_add(1, std::memory_order_relaxed);
+        gcIfManyNewRefs(env);
     }
 
     void binderDied(const wp<IBinder>& who)
@@ -446,9 +496,8 @@
         if (mObject != NULL) {
             result = env->IsSameObject(obj, mObject);
         } else {
-            jobject me = env->NewLocalRef(mObjectWeak);
-            result = env->IsSameObject(obj, me);
-            env->DeleteLocalRef(me);
+            ScopedLocalRef<jobject> me(env, env->NewLocalRef(mObjectWeak));
+            result = env->IsSameObject(obj, me.get());
         }
         return result;
     }
@@ -477,7 +526,7 @@
     virtual ~JavaDeathRecipient()
     {
         //ALOGI("Removing death ref: recipient=%p\n", mObject);
-        android_atomic_dec(&gNumDeathRefs);
+        gNumDeathRefsDeleted.fetch_add(1, std::memory_order_relaxed);
         JNIEnv* env = javavm_to_jnienv(mVM);
         if (mObject != NULL) {
             env->DeleteGlobalRef(mObject);
@@ -488,8 +537,8 @@
 
 private:
     JavaVM* const mVM;
-    jobject mObject;
-    jweak mObjectWeak; // will be a weak ref to the same VM-side DeathRecipient after binderDied()
+    jobject mObject;  // Initial strong ref to Java-side DeathRecipient. Cleared on binderDied().
+    jweak mObjectWeak; // Weak ref to the same Java-side DeathRecipient after binderDied().
     wp<DeathRecipientList> mList;
 };
 
@@ -554,21 +603,40 @@
 
 namespace android {
 
-static void proxy_cleanup(const void* id, void* obj, void* cleanupCookie)
-{
-    android_atomic_dec(&gNumProxyRefs);
-    JNIEnv* env = javavm_to_jnienv((JavaVM*)cleanupCookie);
-    env->DeleteGlobalRef((jobject)obj);
+// We aggregate native pointer fields for BinderProxy in a single object to allow
+// management with a single NativeAllocationRegistry, and to reduce the number of JNI
+// Java field accesses. This costs us some extra indirections here.
+struct BinderProxyNativeData {
+    // Both fields are constant and not null once javaObjectForIBinder returns this as
+    // part of a BinderProxy.
+
+    // The native IBinder proxied by this BinderProxy.
+    sp<IBinder> mObject;
+
+    // Death recipients for mObject. Reference counted only because DeathRecipients
+    // hold a weak reference that can be temporarily promoted.
+    sp<DeathRecipientList> mOrgue;  // Death recipients for mObject.
+};
+
+BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
+    return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData);
 }
 
-static Mutex mProxyLock;
+static Mutex gProxyLock;
 
+// We may cache a single BinderProxyNativeData node to avoid repeat allocation.
+// All fields are null. Protected by gProxyLock.
+static BinderProxyNativeData *gNativeDataCache;
+
+// If the argument is a JavaBBinder, return the Java object that was used to create it.
+// Otherwise return a BinderProxy for the IBinder. If a previous call was passed the
+// same IBinder, and the original BinderProxy is still alive, return the same BinderProxy.
 jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
 {
     if (val == NULL) return NULL;
 
     if (val->checkSubclass(&gBinderOffsets)) {
-        // One of our own!
+        // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
         jobject object = static_cast<JavaBBinder*>(val.get())->object();
         LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
         return object;
@@ -576,44 +644,33 @@
 
     // For the rest of the function we will hold this lock, to serialize
     // looking/creation/destruction of Java proxies for native Binder proxies.
-    AutoMutex _l(mProxyLock);
+    AutoMutex _l(gProxyLock);
 
-    // Someone else's...  do we know about it?
-    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
-    if (object != NULL) {
-        jobject res = jniGetReferent(env, object);
-        if (res != NULL) {
-            ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
-            return res;
-        }
-        LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
-        android_atomic_dec(&gNumProxyRefs);
-        val->detachObject(&gBinderProxyOffsets);
-        env->DeleteGlobalRef(object);
+    BinderProxyNativeData* nativeData = gNativeDataCache;
+    if (nativeData == nullptr) {
+        nativeData = new BinderProxyNativeData();
     }
-
-    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
-    if (object != NULL) {
-        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
-        // The proxy holds a reference to the native object.
-        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
-        val->incStrong((void*)javaObjectForIBinder);
-
-        // The native object needs to hold a weak reference back to the
-        // proxy, so we can retrieve the same proxy if it is still active.
-        jobject refObject = env->NewGlobalRef(
-                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
-        val->attachObject(&gBinderProxyOffsets, refObject,
-                jnienv_to_javavm(env), proxy_cleanup);
-
-        // Also remember the death recipients registered on this proxy
-        sp<DeathRecipientList> drl = new DeathRecipientList;
-        drl->incStrong((void*)javaObjectForIBinder);
-        env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
-
-        // Note that a new object reference has been created.
-        android_atomic_inc(&gNumProxyRefs);
-        incRefsCreated(env);
+    // gNativeDataCache is now logically empty.
+    jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
+            gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
+    if (env->ExceptionCheck()) {
+        gNativeDataCache = nativeData;
+        return NULL;
+    }
+    BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
+    if (actualNativeData == nativeData) {
+        // New BinderProxy; we still have exclusive access.
+        nativeData->mOrgue = new DeathRecipientList;
+        nativeData->mObject = val;
+        gNativeDataCache = nullptr;
+        ++gNumProxies;
+        if (++gNumProxies >= gProxiesWarned + PROXY_WARN_INTERVAL) {
+            ALOGW("Unexpectedly many live BinderProxies: %d\n", gNumProxies);
+            gProxiesWarned = gNumProxies;
+        }
+    } else {
+        // nativeData wasn't used. Reuse it the next time.
+        gNativeDataCache = nativeData;
     }
 
     return object;
@@ -623,15 +680,16 @@
 {
     if (obj == NULL) return NULL;
 
+    // Instance of Binder?
     if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
         JavaBBinderHolder* jbh = (JavaBBinderHolder*)
             env->GetLongField(obj, gBinderOffsets.mObject);
-        return jbh != NULL ? jbh->get(env, obj) : NULL;
+        return jbh->get(env, obj);
     }
 
+    // Instance of BinderProxy?
     if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
-        return (IBinder*)
-            env->GetLongField(obj, gBinderProxyOffsets.mObject);
+        return getBPNativeData(env, obj)->mObject;
     }
 
     ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
@@ -824,35 +882,21 @@
     IPCThreadState::self()->flushCommands();
 }
 
-static void android_os_Binder_init(JNIEnv* env, jobject obj)
+static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
 {
     JavaBBinderHolder* jbh = new JavaBBinderHolder();
-    if (jbh == NULL) {
-        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
-        return;
-    }
-    ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
-    jbh->incStrong((void*)android_os_Binder_init);
-    env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
+    return (jlong) jbh;
 }
 
-static void android_os_Binder_destroyBinder(JNIEnv* env, jobject obj)
+static void Binder_destroy(void* rawJbh)
 {
-    JavaBBinderHolder* jbh = (JavaBBinderHolder*)
-        env->GetLongField(obj, gBinderOffsets.mObject);
-    if (jbh != NULL) {
-        env->SetLongField(obj, gBinderOffsets.mObject, 0);
-        ALOGV("Java Binder %p: removing ref on holder %p", obj, jbh);
-        jbh->decStrong((void*)android_os_Binder_init);
-    } else {
-        // Encountering an uninitialized binder is harmless.  All it means is that
-        // the Binder was only partially initialized when its finalizer ran and called
-        // destroyBinder().  The Binder could be partially initialized for several reasons.
-        // For example, a Binder subclass constructor might have thrown an exception before
-        // it could delegate to its superclass's constructor.  Consequently init() would
-        // not have been called and the holder pointer would remain NULL.
-        ALOGV("Java Binder %p: ignoring uninitialized binder", obj);
-    }
+    JavaBBinderHolder* jbh = (JavaBBinderHolder*) rawJbh;
+    ALOGV("Java Binder: deleting holder %p", jbh);
+    delete jbh;
+}
+
+JNIEXPORT jlong JNICALL android_os_Binder_getNativeFinalizer(JNIEnv*, jclass) {
+    return (jlong) Binder_destroy;
 }
 
 static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz)
@@ -871,8 +915,8 @@
     { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
     { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
     { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
-    { "init", "()V", (void*)android_os_Binder_init },
-    { "destroyBinder", "()V", (void*)android_os_Binder_destroyBinder },
+    { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
+    { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
     { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
 };
 
@@ -899,17 +943,18 @@
 
 jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
 {
-    return gNumLocalRefs;
+    return gNumLocalRefsCreated - gNumLocalRefsDeleted;
 }
 
 jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
 {
-    return gNumProxyRefs;
+    AutoMutex _l(gProxyLock);
+    return gNumProxies;
 }
 
 jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
 {
-    return gNumDeathRefs;
+    return gNumDeathRefsCreated - gNumDeathRefsDeleted;
 }
 
 }
@@ -944,8 +989,8 @@
 
 static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
 {
-    ALOGV("Gc has executed, clearing binder ops");
-    android_atomic_and(0, &gNumRefsCreated);
+    ALOGV("Gc has executed, updating Refs count at GC");
+    gCollectedAtRefs = gNumLocalRefsCreated + gNumDeathRefsCreated;
 }
 
 // ----------------------------------------------------------------------------
@@ -979,8 +1024,7 @@
 
 static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
 {
-    IBinder* target = (IBinder*)
-        env->GetLongField(obj, gBinderProxyOffsets.mObject);
+    IBinder* target = getBPNativeData(env, obj)->mObject.get();
     if (target == NULL) {
         return JNI_FALSE;
     }
@@ -990,7 +1034,7 @@
 
 static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
 {
-    IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject);
+    IBinder* target = getBPNativeData(env, obj)->mObject.get();
     if (target != NULL) {
         const String16& desc = target->getInterfaceDescriptor();
         return env->NewString(reinterpret_cast<const jchar*>(desc.string()),
@@ -1003,8 +1047,7 @@
 
 static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
 {
-    IBinder* target = (IBinder*)
-        env->GetLongField(obj, gBinderProxyOffsets.mObject);
+    IBinder* target = getBPNativeData(env, obj)->mObject.get();
     if (target == NULL) {
         return JNI_FALSE;
     }
@@ -1126,8 +1169,7 @@
         return JNI_FALSE;
     }
 
-    IBinder* target = (IBinder*)
-        env->GetLongField(obj, gBinderProxyOffsets.mObject);
+    IBinder* target = getBPNativeData(env, obj)->mObject.get();
     if (target == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
         return JNI_FALSE;
@@ -1177,18 +1219,13 @@
         return;
     }
 
-    IBinder* target = (IBinder*)
-        env->GetLongField(obj, gBinderProxyOffsets.mObject);
-    if (target == NULL) {
-        ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
-        assert(false);
-    }
+    BinderProxyNativeData *nd = getBPNativeData(env, obj);
+    IBinder* target = nd->mObject.get();
 
     LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
 
     if (!target->localBinder()) {
-        DeathRecipientList* list = (DeathRecipientList*)
-                env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
+        DeathRecipientList* list = nd->mOrgue.get();
         sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
         status_t err = target->linkToDeath(jdr, NULL, flags);
         if (err != NO_ERROR) {
@@ -1209,8 +1246,8 @@
         return res;
     }
 
-    IBinder* target = (IBinder*)
-        env->GetLongField(obj, gBinderProxyOffsets.mObject);
+    BinderProxyNativeData* nd = getBPNativeData(env, obj);
+    IBinder* target = nd->mObject.get();
     if (target == NULL) {
         ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
         return JNI_FALSE;
@@ -1222,8 +1259,7 @@
         status_t err = NAME_NOT_FOUND;
 
         // If we find the matching recipient, proceed to unlink using that
-        DeathRecipientList* list = (DeathRecipientList*)
-                env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
+        DeathRecipientList* list = nd->mOrgue.get();
         sp<JavaDeathRecipient> origJDR = list->find(recipient);
         LOGDEATH("   unlink found list %p and JDR %p", list, origJDR.get());
         if (origJDR != NULL) {
@@ -1249,25 +1285,21 @@
     return res;
 }
 
-static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj)
+static void BinderProxy_destroy(void* rawNativeData)
 {
     // Don't race with construction/initialization
-    AutoMutex _l(mProxyLock);
+    AutoMutex _l(gProxyLock);
 
-    IBinder* b = (IBinder*)
-            env->GetLongField(obj, gBinderProxyOffsets.mObject);
-    DeathRecipientList* drl = (DeathRecipientList*)
-            env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
-
-    LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
-    if (b != nullptr) {
-        env->SetLongField(obj, gBinderProxyOffsets.mObject, 0);
-        env->SetLongField(obj, gBinderProxyOffsets.mOrgue, 0);
-        drl->decStrong((void*)javaObjectForIBinder);
-        b->decStrong((void*)javaObjectForIBinder);
-    }
-
+    BinderProxyNativeData * nativeData = (BinderProxyNativeData *) rawNativeData;
+    LOGDEATH("Destroying BinderProxy: binder=%p drl=%p\n",
+            nativeData->mObject.get(), nativeData->mOrgue.get());
+    delete nativeData;
     IPCThreadState::self()->flushCommands();
+    --gNumProxies;
+}
+
+JNIEXPORT jlong JNICALL android_os_BinderProxy_getNativeFinalizer(JNIEnv*, jclass) {
+    return (jlong) BinderProxy_destroy;
 }
 
 // ----------------------------------------------------------------------------
@@ -1280,7 +1312,7 @@
     {"transactNative",      "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
     {"linkToDeath",         "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
     {"unlinkToDeath",       "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
-    {"destroy",             "()V", (void*)android_os_BinderProxy_destroy},
+    {"getNativeFinalizer",  "()J", (void*)android_os_BinderProxy_getNativeFinalizer},
 };
 
 const char* const kBinderProxyPathName = "android/os/BinderProxy";
@@ -1292,14 +1324,11 @@
 
     clazz = FindClassOrDie(env, kBinderProxyPathName);
     gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
-    gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
+    gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
+            "(JJ)Landroid/os/BinderProxy;");
     gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
             "(Landroid/os/IBinder$DeathRecipient;)V");
-
-    gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
-    gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
-                                                "Ljava/lang/ref/WeakReference;");
-    gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
+    gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
 
     clazz = FindClassOrDie(env, "java/lang/Class");
     gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
@@ -1337,5 +1366,12 @@
     gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
             "onBinderStrictModePolicyChange", "(I)V");
 
+    clazz = FindClassOrDie(env, "java/lang/Thread");
+    gThreadDispatchOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
+    gThreadDispatchOffsets.mDispatchUncaughtException = GetMethodIDOrDie(env, clazz,
+            "dispatchUncaughtException", "(Ljava/lang/Throwable;)V");
+    gThreadDispatchOffsets.mCurrentThread = GetStaticMethodIDOrDie(env, clazz, "currentThread",
+            "()Ljava/lang/Thread;");
+
     return 0;
 }
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index 9fd7c40..3b5a144 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -14,214 +14,20 @@
  * limitations under the License.
  */
 
-#include <fcntl.h>
-
-#include <log/log_event_list.h>
-
-#include <log/log.h>
+#include <android-base/macros.h>
+#include <log/log_id.h>
 
 #include <nativehelper/JNIHelp.h>
-#include "core_jni_helpers.h"
 #include "jni.h"
 
-#define UNUSED  __attribute__((__unused__))
+#include "core_jni_helpers.h"
+#include "eventlog_helper.h"
 
 namespace android {
 
-static jclass gCollectionClass;
-static jmethodID gCollectionAddID;
-
-static jclass gEventClass;
-static jmethodID gEventInitID;
-
-static jclass gIntegerClass;
-static jfieldID gIntegerValueID;
-
-static jclass gLongClass;
-static jfieldID gLongValueID;
-
-static jclass gFloatClass;
-static jfieldID gFloatValueID;
-
-static jclass gStringClass;
-
-/*
- * In class android.util.EventLog:
- *  static native int writeEvent(int tag, int value)
- */
-static jint android_util_EventLog_writeEvent_Integer(JNIEnv* env UNUSED,
-                                                     jobject clazz UNUSED,
-                                                     jint tag, jint value)
-{
-    android_log_event_list ctx(tag);
-    ctx << (int32_t)value;
-    return ctx.write();
-}
-
-/*
- * In class android.util.EventLog:
- *  static native int writeEvent(long tag, long value)
- */
-static jint android_util_EventLog_writeEvent_Long(JNIEnv* env UNUSED,
-                                                  jobject clazz UNUSED,
-                                                  jint tag, jlong value)
-{
-    android_log_event_list ctx(tag);
-    ctx << (int64_t)value;
-    return ctx.write();
-}
-
-/*
- * In class android.util.EventLog:
- *  static native int writeEvent(long tag, float value)
- */
-static jint android_util_EventLog_writeEvent_Float(JNIEnv* env UNUSED,
-                                                  jobject clazz UNUSED,
-                                                  jint tag, jfloat value)
-{
-    android_log_event_list ctx(tag);
-    ctx << (float)value;
-    return ctx.write();
-}
-
-/*
- * In class android.util.EventLog:
- *  static native int writeEvent(int tag, String value)
- */
-static jint android_util_EventLog_writeEvent_String(JNIEnv* env,
-                                                    jobject clazz UNUSED,
-                                                    jint tag, jstring value) {
-    android_log_event_list ctx(tag);
-    // Don't throw NPE -- I feel like it's sort of mean for a logging function
-    // to be all crashy if you pass in NULL -- but make the NULL value explicit.
-    if (value != NULL) {
-        const char *str = env->GetStringUTFChars(value, NULL);
-        ctx << str;
-        env->ReleaseStringUTFChars(value, str);
-    } else {
-        ctx << "NULL";
-    }
-    return ctx.write();
-}
-
-/*
- * In class android.util.EventLog:
- *  static native int writeEvent(long tag, Object... value)
- */
-static jint android_util_EventLog_writeEvent_Array(JNIEnv* env, jobject clazz,
-                                                   jint tag, jobjectArray value) {
-    android_log_event_list ctx(tag);
-
-    if (value == NULL) {
-        ctx << "[NULL]";
-        return ctx.write();
-    }
-
-    jsize copied = 0, num = env->GetArrayLength(value);
-    for (; copied < num && copied < 255; ++copied) {
-        if (ctx.status()) break;
-        jobject item = env->GetObjectArrayElement(value, copied);
-        if (item == NULL) {
-            ctx << "NULL";
-        } else if (env->IsInstanceOf(item, gStringClass)) {
-            const char *str = env->GetStringUTFChars((jstring) item, NULL);
-            ctx << str;
-            env->ReleaseStringUTFChars((jstring) item, str);
-        } else if (env->IsInstanceOf(item, gIntegerClass)) {
-            ctx << (int32_t)env->GetIntField(item, gIntegerValueID);
-        } else if (env->IsInstanceOf(item, gLongClass)) {
-            ctx << (int64_t)env->GetLongField(item, gLongValueID);
-        } else if (env->IsInstanceOf(item, gFloatClass)) {
-            ctx << (float)env->GetFloatField(item, gFloatValueID);
-        } else {
-            jniThrowException(env,
-                    "java/lang/IllegalArgumentException",
-                    "Invalid payload item type");
-            return -1;
-        }
-        env->DeleteLocalRef(item);
-    }
-    return ctx.write();
-}
-
-static void readEvents(JNIEnv* env, int loggerMode, jintArray tags, jlong startTime, jobject out) {
-    struct logger_list *logger_list;
-    if (startTime) {
-        logger_list = android_logger_list_alloc_time(loggerMode,
-                log_time(startTime / NS_PER_SEC, startTime % NS_PER_SEC), 0);
-    } else {
-        logger_list = android_logger_list_alloc(loggerMode, 0, 0);
-    }
-    if (!logger_list) {
-        jniThrowIOException(env, errno);
-        return;
-    }
-
-    if (!android_logger_open(logger_list, LOG_ID_EVENTS)) {
-        jniThrowIOException(env, errno);
-        android_logger_list_free(logger_list);
-        return;
-    }
-
-    jsize tagLength = env->GetArrayLength(tags);
-    jint *tagValues = env->GetIntArrayElements(tags, NULL);
-
-    while (1) {
-        log_msg log_msg;
-        int ret = android_logger_list_read(logger_list, &log_msg);
-
-        if (ret == 0) {
-            break;
-        }
-        if (ret < 0) {
-            if (ret == -EINTR) {
-                continue;
-            }
-            if (ret == -EINVAL) {
-                jniThrowException(env, "java/io/IOException", "Event too short");
-            } else if (ret != -EAGAIN) {
-                jniThrowIOException(env, -ret);  // Will throw on return
-            }
-            break;
-        }
-
-        if (log_msg.id() != LOG_ID_EVENTS) {
-            continue;
-        }
-
-        int32_t tag = * (int32_t *) log_msg.msg();
-
-        int found = 0;
-        for (int i = 0; !found && i < tagLength; ++i) {
-            found = (tag == tagValues[i]);
-        }
-
-        if (found) {
-            jsize len = ret;
-            jbyteArray array = env->NewByteArray(len);
-            if (array == NULL) {
-                break;
-            }
-
-            jbyte *bytes = env->GetByteArrayElements(array, NULL);
-            memcpy(bytes, log_msg.buf, len);
-            env->ReleaseByteArrayElements(array, bytes, 0);
-
-            jobject event = env->NewObject(gEventClass, gEventInitID, array);
-            if (event == NULL) {
-                break;
-            }
-
-            env->CallBooleanMethod(out, gCollectionAddID, event);
-            env->DeleteLocalRef(event);
-            env->DeleteLocalRef(array);
-        }
-    }
-
-    android_logger_list_close(logger_list);
-
-    env->ReleaseIntArrayElements(tags, tagValues, 0);
-}
+constexpr char kEventLogEventClass[] = "android/util/EventLog$Event";
+template class EventLogHelper<log_id_t::LOG_ID_EVENTS, kEventLogEventClass>;
+using ELog = EventLogHelper<log_id_t::LOG_ID_EVENTS, kEventLogEventClass>;
 
 /*
  * In class android.util.EventLog:
@@ -229,7 +35,7 @@
  *
  *  Reads events from the event log
  */
-static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz UNUSED,
+static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz ATTRIBUTE_UNUSED,
                                              jintArray tags,
                                              jobject out) {
 
@@ -238,7 +44,7 @@
         return;
     }
 
-    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, tags, 0, out);
+    ELog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, tags, 0, out);
  }
 /*
  * In class android.util.EventLog:
@@ -246,7 +52,7 @@
  *
  *  Reads events from the event log, blocking until events after timestamp are to be overwritten.
  */
-static void android_util_EventLog_readEventsOnWrapping(JNIEnv* env, jobject clazz UNUSED,
+static void android_util_EventLog_readEventsOnWrapping(JNIEnv* env, jobject clazz ATTRIBUTE_UNUSED,
                                              jintArray tags,
                                              jlong timestamp,
                                              jobject out) {
@@ -254,8 +60,8 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP,
-            tags, timestamp, out);
+    ELog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, tags,
+            timestamp, out);
 }
 
 /*
@@ -263,17 +69,11 @@
  */
 static const JNINativeMethod gRegisterMethods[] = {
     /* name, signature, funcPtr */
-    { "writeEvent", "(II)I", (void*) android_util_EventLog_writeEvent_Integer },
-    { "writeEvent", "(IJ)I", (void*) android_util_EventLog_writeEvent_Long },
-    { "writeEvent", "(IF)I", (void*) android_util_EventLog_writeEvent_Float },
-    { "writeEvent",
-      "(ILjava/lang/String;)I",
-      (void*) android_util_EventLog_writeEvent_String
-    },
-    { "writeEvent",
-      "(I[Ljava/lang/Object;)I",
-      (void*) android_util_EventLog_writeEvent_Array
-    },
+    { "writeEvent", "(II)I", (void*) ELog::writeEventInteger },
+    { "writeEvent", "(IJ)I", (void*) ELog::writeEventLong },
+    { "writeEvent", "(IF)I", (void*) ELog::writeEventFloat },
+    { "writeEvent", "(ILjava/lang/String;)I", (void*) ELog::writeEventString },
+    { "writeEvent", "(I[Ljava/lang/Object;)I", (void*) ELog::writeEventArray },
     { "readEvents",
       "([ILjava/util/Collection;)V",
       (void*) android_util_EventLog_readEvents
@@ -284,41 +84,8 @@
     },
 };
 
-static struct { const char *name; jclass *clazz; } gClasses[] = {
-    { "android/util/EventLog$Event", &gEventClass },
-    { "java/lang/Integer", &gIntegerClass },
-    { "java/lang/Long", &gLongClass },
-    { "java/lang/Float", &gFloatClass },
-    { "java/lang/String", &gStringClass },
-    { "java/util/Collection", &gCollectionClass },
-};
-
-static struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = {
-    { &gIntegerClass, "value", "I", &gIntegerValueID },
-    { &gLongClass, "value", "J", &gLongValueID },
-    { &gFloatClass, "value", "F", &gFloatValueID },
-};
-
-static struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = {
-    { &gEventClass, "<init>", "([B)V", &gEventInitID },
-    { &gCollectionClass, "add", "(Ljava/lang/Object;)Z", &gCollectionAddID },
-};
-
 int register_android_util_EventLog(JNIEnv* env) {
-    for (int i = 0; i < NELEM(gClasses); ++i) {
-        jclass clazz = FindClassOrDie(env, gClasses[i].name);
-        *gClasses[i].clazz = MakeGlobalRefOrDie(env, clazz);
-    }
-
-    for (int i = 0; i < NELEM(gFields); ++i) {
-        *gFields[i].id = GetFieldIDOrDie(env,
-                *gFields[i].c, gFields[i].name, gFields[i].ft);
-    }
-
-    for (int i = 0; i < NELEM(gMethods); ++i) {
-        *gMethods[i].id = GetMethodIDOrDie(env,
-                *gMethods[i].c, gMethods[i].name, gMethods[i].mt);
-    }
+    ELog::Init(env);
 
     return RegisterMethodsOrDie(
             env,
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index c04c339..550c44d 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -218,7 +218,7 @@
         strcpy(cmdline, "unknown");
 
         sprintf(proc_path, "/proc/%d/cmdline", pid);
-        fd = open(proc_path, O_RDONLY);
+        fd = open(proc_path, O_RDONLY | O_CLOEXEC);
         if (fd >= 0) {
             int rc = read(fd, cmdline, sizeof(cmdline)-1);
             cmdline[rc] = 0;
@@ -356,6 +356,7 @@
         case SP_FOREGROUND:
         case SP_AUDIO_APP:
         case SP_AUDIO_SYS:
+        case SP_RT_APP:
             filename = "/dev/cpuset/foreground/cpus";
             break;
         case SP_TOP_APP:
@@ -553,7 +554,7 @@
         return false;
     }
 
-    int fd = open(text, O_WRONLY);
+    int fd = open(text, O_WRONLY | O_CLOEXEC);
     if (fd >= 0) {
         sprintf(text, "%" PRId32, pid);
         write(fd, text, strlen(text));
@@ -601,7 +602,7 @@
 
 static jlong getFreeMemoryImpl(const char* const sums[], const size_t sumsLen[], size_t num)
 {
-    int fd = open("/proc/meminfo", O_RDONLY);
+    int fd = open("/proc/meminfo", O_RDONLY | O_CLOEXEC);
 
     if (fd < 0) {
         ALOGW("Unable to open /proc/meminfo");
@@ -714,7 +715,7 @@
         sizesArray[i] = 0;
     }
 
-    int fd = open(file.string(), O_RDONLY);
+    int fd = open(file.string(), O_RDONLY | O_CLOEXEC);
 
     if (fd >= 0) {
         const size_t BUFFER_SIZE = 2048;
@@ -1021,7 +1022,7 @@
         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
         return JNI_FALSE;
     }
-    int fd = open(file8, O_RDONLY);
+    int fd = open(file8, O_RDONLY | O_CLOEXEC);
 
     if (fd < 0) {
         if (kDebugProc) {
@@ -1161,7 +1162,7 @@
         char data[PATH_MAX];
         snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
 
-        int fd = open(path, O_RDONLY);
+        int fd = open(path, O_RDONLY | O_CLOEXEC);
         if (fd < 0) {
             continue;
         }
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index 31e954b..c457ab0 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -233,8 +233,9 @@
     for (;;) {
         uint32_t seq;
         InputEvent* inputEvent;
+        int32_t displayId;
         status_t status = mInputConsumer.consume(&mInputEventFactory,
-                consumeBatches, frameTime, &seq, &inputEvent);
+                consumeBatches, frameTime, &seq, &inputEvent, &displayId);
         if (status) {
             if (status == WOULD_BLOCK) {
                 if (!skipCallbacks && !mBatchedInputEventPending
@@ -311,7 +312,8 @@
                     ALOGD("channel '%s' ~ Dispatching input event.", getInputChannelName());
                 }
                 env->CallVoidMethod(receiverObj.get(),
-                        gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj);
+                        gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj,
+                        displayId);
                 if (env->ExceptionCheck()) {
                     ALOGE("Exception dispatching input event.");
                     skipCallbacks = true;
@@ -417,7 +419,7 @@
 
     gInputEventReceiverClassInfo.dispatchInputEvent = GetMethodIDOrDie(env,
             gInputEventReceiverClassInfo.clazz,
-            "dispatchInputEvent", "(ILandroid/view/InputEvent;)V");
+            "dispatchInputEvent", "(ILandroid/view/InputEvent;I)V");
     gInputEventReceiverClassInfo.dispatchBatchedInputEventPending = GetMethodIDOrDie(env,
             gInputEventReceiverClassInfo.clazz, "dispatchBatchedInputEventPending", "()V");
 
diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp
index 420ff2a..58ccef18 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -39,6 +39,8 @@
 
 // Log debug messages about the dispatch cycle.
 static const bool kDebugDispatchCycle = false;
+// Display id for default(primary) display.
+static const int32_t kDefaultDisplayId = 0;
 
 static struct {
     jclass clazz;
@@ -136,6 +138,7 @@
         publishedSeq = mNextPublishedSeq++;
         status_t status = mInputPublisher.publishMotionEvent(publishedSeq,
                 event->getDeviceId(), event->getSource(),
+                kDefaultDisplayId /* TODO(multi-display): propagate display id */,
                 event->getAction(), event->getActionButton(), event->getFlags(),
                 event->getEdgeFlags(), event->getMetaState(), event->getButtonState(),
                 event->getXOffset(), event->getYOffset(),
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index ec3e06c..215a00e 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -135,6 +135,7 @@
         case PublicFormat::DEPTH16:
             return HAL_PIXEL_FORMAT_Y16;
         case PublicFormat::RAW_SENSOR:
+        case PublicFormat::RAW_DEPTH:
             return HAL_PIXEL_FORMAT_RAW16;
         default:
             // Most formats map 1:1
@@ -149,6 +150,7 @@
             return HAL_DATASPACE_V0_JFIF;
         case PublicFormat::DEPTH_POINT_CLOUD:
         case PublicFormat::DEPTH16:
+        case PublicFormat::RAW_DEPTH:
             return HAL_DATASPACE_DEPTH;
         case PublicFormat::RAW_SENSOR:
         case PublicFormat::RAW_PRIVATE:
@@ -182,8 +184,12 @@
             // Enums overlap in both name and value
             return static_cast<PublicFormat>(format);
         case HAL_PIXEL_FORMAT_RAW16:
-            // Name differs, though value is the same
-            return PublicFormat::RAW_SENSOR;
+            switch (dataSpace) {
+                case HAL_DATASPACE_DEPTH:
+                  return PublicFormat::RAW_DEPTH;
+                default:
+                  return PublicFormat::RAW_SENSOR;
+            }
         case HAL_PIXEL_FORMAT_RAW_OPAQUE:
             // Name differs, though value is the same
             return PublicFormat::RAW_PRIVATE;
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 19fa25e..2bf8d930 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -167,7 +167,7 @@
             buffer->getWidth(),
             buffer->getHeight(),
             buffer->getPixelFormat(),
-            buffer->getUsage(),
+            (jint)buffer->getUsage(),
             (jlong)buffer.get());
 }
 
@@ -222,11 +222,20 @@
             return NULL;
         }
     }
+
+    sk_sp<SkColorSpace> colorSpace;
+    if (screenshot->getDataSpace() == HAL_DATASPACE_DISPLAY_P3) {
+        colorSpace = SkColorSpace::MakeRGB(
+                SkColorSpace::kSRGB_RenderTargetGamma, SkColorSpace::kDCIP3_D65_Gamut);
+    } else {
+        colorSpace = SkColorSpace::MakeSRGB();
+    }
+
     SkImageInfo screenshotInfo = SkImageInfo::Make(screenshot->getWidth(),
                                                    screenshot->getHeight(),
                                                    colorType,
                                                    alphaType,
-                                                   GraphicsJNI::defaultColorSpace());
+                                                   colorSpace);
 
     const size_t rowBytes =
             screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat());
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index a635269..46b0a79 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -581,18 +581,6 @@
     mObserver->decStrong(nullptr);
 }
 
-static jboolean android_view_ThreadedRenderer_supportsOpenGL(JNIEnv* env, jobject clazz) {
-    char prop[PROPERTY_VALUE_MAX];
-    if (property_get("ro.kernel.qemu", prop, NULL) == 0) {
-        // not in the emulator
-        return JNI_TRUE;
-    }
-    // In the emulator this property will be set > 0 when OpenGL ES 2.0 is
-    // enabled, 0 otherwise. On old emulator versions it will be undefined.
-    property_get("qemu.gles", prop, "0");
-    return atoi(prop) > 0 ? JNI_TRUE : JNI_FALSE;
-}
-
 static void android_view_ThreadedRenderer_rotateProcessStatsBuffer(JNIEnv* env, jobject clazz) {
     RenderProxy::rotateProcessStatsBuffer();
 }
@@ -693,6 +681,12 @@
     proxy->setOpaque(opaque);
 }
 
+static void android_view_ThreadedRenderer_setWideGamut(JNIEnv* env, jobject clazz,
+        jlong proxyPtr, jboolean wideGamut) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    proxy->setWideGamut(wideGamut);
+}
+
 static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
         jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize) {
     LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE,
@@ -983,7 +977,6 @@
 const char* const kClassPathName = "android/view/ThreadedRenderer";
 
 static const JNINativeMethod gMethods[] = {
-    { "nSupportsOpenGL", "()Z", (void*) android_view_ThreadedRenderer_supportsOpenGL },
     { "nRotateProcessStatsBuffer", "()V", (void*) android_view_ThreadedRenderer_rotateProcessStatsBuffer },
     { "nSetProcessStatsBuffer", "(I)V", (void*) android_view_ThreadedRenderer_setProcessStatsBuffer },
     { "nGetRenderThreadTid", "(J)I", (void*) android_view_ThreadedRenderer_getRenderThreadTid },
@@ -999,6 +992,7 @@
     { "nSetup", "(JFII)V", (void*) android_view_ThreadedRenderer_setup },
     { "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter },
     { "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
+    { "nSetWideGamut", "(JZ)V", (void*) android_view_ThreadedRenderer_setWideGamut },
     { "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
     { "nDestroy", "(JJ)V", (void*) android_view_ThreadedRenderer_destroy },
     { "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode },
diff --git a/core/jni/com_android_internal_os_FuseAppLoop.cpp b/core/jni/com_android_internal_os_FuseAppLoop.cpp
index 2d5026f..8837df5 100644
--- a/core/jni/com_android_internal_os_FuseAppLoop.cpp
+++ b/core/jni/com_android_internal_os_FuseAppLoop.cpp
@@ -142,14 +142,14 @@
 }
 
 void com_android_internal_os_FuseAppLoop_replyLookup(
-        JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong inode, jint size) {
+        JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong inode, jlong size) {
     if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyLookup(unique, inode, size)) {
         reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
     }
 }
 
 void com_android_internal_os_FuseAppLoop_replyGetAttr(
-        JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong inode, jint size) {
+        JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong inode, jlong size) {
     if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyGetAttr(
             unique, inode, size, S_IFREG | 0777)) {
         reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 914688e..b08f031 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -477,7 +477,7 @@
 
 // Utility routine to fork zygote and specialize the child process.
 static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
-                                     jint debug_flags, jobjectArray javaRlimits,
+                                     jint runtime_flags, jobjectArray javaRlimits,
                                      jlong permittedCapabilities, jlong effectiveCapabilities,
                                      jint mount_external,
                                      jstring java_se_info, jstring java_se_name,
@@ -658,7 +658,7 @@
 
     UnsetSigChldHandler();
 
-    env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
+    env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
                               is_system_server, instructionSet);
     if (env->ExceptionCheck()) {
       RuntimeAbort(env, __LINE__, "Error calling post fork hooks.");
@@ -700,7 +700,7 @@
 
 static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
         JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
-        jint debug_flags, jobjectArray rlimits,
+        jint runtime_flags, jobjectArray rlimits,
         jint mount_external, jstring se_info, jstring se_name,
         jintArray fdsToClose,
         jintArray fdsToIgnore,
@@ -744,17 +744,17 @@
     // available.
     capabilities &= GetEffectiveCapabilityMask(env);
 
-    return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
+    return ForkAndSpecializeCommon(env, uid, gid, gids, runtime_flags,
             rlimits, capabilities, capabilities, mount_external, se_info,
             se_name, false, fdsToClose, fdsToIgnore, instructionSet, appDataDir);
 }
 
 static jint com_android_internal_os_Zygote_nativeForkSystemServer(
         JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
-        jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
+        jint runtime_flags, jobjectArray rlimits, jlong permittedCapabilities,
         jlong effectiveCapabilities) {
   pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
-                                      debug_flags, rlimits,
+                                      runtime_flags, rlimits,
                                       permittedCapabilities, effectiveCapabilities,
                                       MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
                                       NULL, NULL, NULL);
diff --git a/core/jni/com_android_internal_os_ZygoteInit.cpp b/core/jni/com_android_internal_os_ZygoteInit.cpp
new file mode 100644
index 0000000..258a55c
--- /dev/null
+++ b/core/jni/com_android_internal_os_ZygoteInit.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Zygote"
+
+#include <ui/GraphicBufferMapper.h>
+
+#include "core_jni_helpers.h"
+
+namespace {
+
+void android_internal_os_ZygoteInit_nativePreloadAppProcessHALs(JNIEnv* env, jclass) {
+    android::GraphicBufferMapper::preloadHal();
+    // Add preloading here for other HALs that are (a) always passthrough, and
+    // (b) loaded by most app processes.
+}
+
+const JNINativeMethod gMethods[] = {
+    { "nativePreloadAppProcessHALs", "()V",
+      (void*)android_internal_os_ZygoteInit_nativePreloadAppProcessHALs },
+};
+
+}  // anonymous namespace
+
+namespace android {
+
+int register_com_android_internal_os_ZygoteInit(JNIEnv* env) {
+    return RegisterMethodsOrDie(env, "com/android/internal/os/ZygoteInit",
+            gMethods, NELEM(gMethods));
+}
+
+}  // namespace android
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index d6692ad..940ac22 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -45,7 +45,6 @@
 static jfieldID gDisplay_EGLDisplayFieldID;
 static jfieldID gContext_EGLContextFieldID;
 static jfieldID gSurface_EGLSurfaceFieldID;
-static jfieldID gSurface_NativePixelRefFieldID;
 static jfieldID gConfig_EGLConfigFieldID;
 
 static inline EGLDisplay getDisplay(JNIEnv* env, jobject o) {
@@ -84,7 +83,6 @@
 
     jclass surface_class = _env->FindClass("com/google/android/gles_jni/EGLSurfaceImpl");
     gSurface_EGLSurfaceFieldID = _env->GetFieldID(surface_class, "mEGLSurface", "J");
-    gSurface_NativePixelRefFieldID = _env->GetFieldID(surface_class, "mNativePixelRef", "J");
 }
 
 static const jint gNull_attrib_base[] = {EGL_NONE};
@@ -398,15 +396,6 @@
     }
     EGLDisplay dpy = getDisplay(_env, display);
     EGLSurface sur = getSurface(_env, surface);
-
-    if (sur) {
-        SkPixelRef* ref = (SkPixelRef*)(_env->GetLongField(surface,
-                gSurface_NativePixelRefFieldID));
-        if (ref) {
-            ref->unlockPixels();
-            SkSafeUnref(ref);
-        }
-    }
     return EglBoolToJBool(eglDestroySurface(dpy, sur));
 }
 
diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp
index ac23eca..40ff7e4 100644
--- a/core/jni/com_google_android_gles_jni_GLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp
@@ -18,7 +18,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include "jni.h"
diff --git a/core/jni/eventlog_helper.h b/core/jni/eventlog_helper.h
new file mode 100644
index 0000000..3a05195
--- /dev/null
+++ b/core/jni/eventlog_helper.h
@@ -0,0 +1,272 @@
+/*
+ * 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.
+ */
+
+#ifndef FRAMEWORKS_BASE_CORE_JNI_EVENTLOG_HELPER_H_
+#define FRAMEWORKS_BASE_CORE_JNI_EVENTLOG_HELPER_H_
+
+#include <memory>
+
+#include <fcntl.h>
+
+#include <android-base/macros.h>
+#include <log/log_event_list.h>
+
+#include <log/log.h>
+
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
+#include <nativehelper/ScopedUtfChars.h>
+#include "core_jni_helpers.h"
+#include "jni.h"
+
+namespace android {
+
+template <log_id_t LogID, const char* EventClassDescriptor>
+class EventLogHelper {
+public:
+    static void Init(JNIEnv* env) {
+        struct { const char *name; jclass *clazz; } gClasses[] = {
+                { EventClassDescriptor, &gEventClass },
+                { "java/lang/Integer", &gIntegerClass },
+                { "java/lang/Long", &gLongClass },
+                { "java/lang/Float", &gFloatClass },
+                { "java/lang/String", &gStringClass },
+                { "java/util/Collection", &gCollectionClass },
+        };
+        struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = {
+                { &gIntegerClass, "value", "I", &gIntegerValueID },
+                { &gLongClass, "value", "J", &gLongValueID },
+                { &gFloatClass, "value", "F", &gFloatValueID },
+        };
+        struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = {
+                { &gEventClass, "<init>", "([B)V", &gEventInitID },
+                { &gCollectionClass, "add", "(Ljava/lang/Object;)Z", &gCollectionAddID },
+        };
+
+        for (size_t i = 0; i < NELEM(gClasses); ++i) {
+            ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, gClasses[i].name));
+            *gClasses[i].clazz = MakeGlobalRefOrDie(env, clazz.get());
+        }
+        for (size_t i = 0; i < NELEM(gFields); ++i) {
+            *gFields[i].id = GetFieldIDOrDie(env,
+                    *gFields[i].c, gFields[i].name, gFields[i].ft);
+        }
+
+        for (size_t i = 0; i < NELEM(gMethods); ++i) {
+            *gMethods[i].id = GetMethodIDOrDie(env,
+                    *gMethods[i].c, gMethods[i].name, gMethods[i].mt);
+        }
+    }
+
+    static jint writeEventInteger(JNIEnv* env ATTRIBUTE_UNUSED, jobject clazz ATTRIBUTE_UNUSED,
+            jint tag, jint value) {
+        android_log_event_list ctx(tag);
+        ctx << (int32_t)value;
+        return ctx.write(LogID);
+    }
+    static jint writeEventLong(JNIEnv* env ATTRIBUTE_UNUSED, jobject clazz ATTRIBUTE_UNUSED,
+            jint tag, jlong value) {
+        android_log_event_list ctx(tag);
+        ctx << (int64_t)value;
+        return ctx.write(LogID);
+    }
+    static jint writeEventFloat(JNIEnv* env ATTRIBUTE_UNUSED, jobject clazz ATTRIBUTE_UNUSED,
+            jint tag, jfloat value) {
+        android_log_event_list ctx(tag);
+        ctx << (float)value;
+        return ctx.write(LogID);
+    }
+    static jint writeEventString(JNIEnv* env, jobject clazz ATTRIBUTE_UNUSED, jint tag,
+            jstring value) {
+        android_log_event_list ctx(tag);
+        // Don't throw NPE -- I feel like it's sort of mean for a logging function
+        // to be all crashy if you pass in NULL -- but make the NULL value explicit.
+        ctx << (value != nullptr ? ScopedUtfChars(env, value).c_str() : "NULL");
+        return ctx.write(LogID);
+    }
+    static jint writeEventArray(JNIEnv* env, jobject clazz ATTRIBUTE_UNUSED, jint tag,
+            jobjectArray value) {
+        android_log_event_list ctx(tag);
+
+        if (value == nullptr) {
+            ctx << "[NULL]";
+            return ctx.write(LogID);
+        }
+
+        jsize copied = 0, num = env->GetArrayLength(value);
+        for (; copied < num && copied < 255; ++copied) {
+            if (ctx.status()) break;
+            ScopedLocalRef<jobject> item(env, env->GetObjectArrayElement(value, copied));
+            if (item == nullptr) {
+                ctx << "NULL";
+            } else if (env->IsInstanceOf(item.get(), gStringClass)) {
+                ctx << ScopedUtfChars(env, (jstring) item.get()).c_str();
+            } else if (env->IsInstanceOf(item.get(), gIntegerClass)) {
+                ctx << (int32_t)env->GetIntField(item.get(), gIntegerValueID);
+            } else if (env->IsInstanceOf(item.get(), gLongClass)) {
+                ctx << (int64_t)env->GetLongField(item.get(), gLongValueID);
+            } else if (env->IsInstanceOf(item.get(), gFloatClass)) {
+                ctx << (float)env->GetFloatField(item.get(), gFloatValueID);
+            } else {
+                jniThrowException(env,
+                        "java/lang/IllegalArgumentException",
+                        "Invalid payload item type");
+                return -1;
+            }
+        }
+        return ctx.write(LogID);
+    }
+
+    static void readEvents(JNIEnv* env, int loggerMode, jlong startTime, jobject out) {
+        readEvents(env, loggerMode, nullptr, startTime, out);
+    }
+
+    static void readEvents(JNIEnv* env, int loggerMode, jintArray jTags, jlong startTime,
+            jobject out) {
+        std::unique_ptr<struct logger_list, decltype(&android_logger_list_close)> logger_list(
+                nullptr, android_logger_list_close);
+        if (startTime) {
+            logger_list.reset(android_logger_list_alloc_time(loggerMode,
+                    log_time(startTime / NS_PER_SEC, startTime % NS_PER_SEC), 0));
+        } else {
+            logger_list.reset(android_logger_list_alloc(loggerMode, 0, 0));
+        }
+        if (!logger_list) {
+            jniThrowIOException(env, errno);
+            return;
+        }
+
+        if (!android_logger_open(logger_list.get(), LogID)) {
+            jniThrowIOException(env, errno);
+            return;
+        }
+
+        ScopedIntArrayRO tags(env);
+        if (jTags != nullptr) {
+            tags.reset(jTags);
+        }
+
+        while (1) {
+            log_msg log_msg;
+            int ret = android_logger_list_read(logger_list.get(), &log_msg);
+
+            if (ret == 0) {
+                return;
+            }
+            if (ret < 0) {
+                if (ret == -EINTR) {
+                    continue;
+                }
+                if (ret == -EINVAL) {
+                    jniThrowException(env, "java/io/IOException", "Event too short");
+                } else if (ret != -EAGAIN) {
+                    jniThrowIOException(env, -ret);  // Will throw on return
+                }
+                return;
+            }
+
+            if (log_msg.id() != LogID) {
+                continue;
+            }
+
+            int32_t tag = * (int32_t *) log_msg.msg();
+
+            if (jTags != nullptr) {
+                bool found = false;
+                for (size_t i = 0; !found && i < tags.size(); ++i) {
+                    found = (tag == tags[i]);
+                }
+                if (!found) {
+                    continue;
+                }
+            }
+
+            jsize len = ret;
+            ScopedLocalRef<jbyteArray> array(env, env->NewByteArray(len));
+            if (array == nullptr) {
+                return;
+            }
+
+            {
+                ScopedByteArrayRW bytes(env, array.get());
+                memcpy(bytes.get(), log_msg.buf, len);
+            }
+
+            ScopedLocalRef<jobject> event(env,
+                    env->NewObject(gEventClass, gEventInitID, array.get()));
+            if (event == nullptr) {
+                return;
+            }
+
+            env->CallBooleanMethod(out, gCollectionAddID, event.get());
+            if (env->ExceptionCheck() == JNI_TRUE) {
+                return;
+            }
+        }
+    }
+
+private:
+    static jclass gCollectionClass;
+    static jmethodID gCollectionAddID;
+
+    static jclass gEventClass;
+    static jmethodID gEventInitID;
+
+    static jclass gIntegerClass;
+    static jfieldID gIntegerValueID;
+
+    static jclass gLongClass;
+    static jfieldID gLongValueID;
+
+    static jclass gFloatClass;
+    static jfieldID gFloatValueID;
+
+    static jclass gStringClass;
+};
+
+// Explicit instantiation declarations.
+template <log_id_t LogID, const char* EventClassDescriptor>
+jclass EventLogHelper<LogID, EventClassDescriptor>::gCollectionClass;
+template <log_id_t LogID, const char* EventClassDescriptor>
+jmethodID EventLogHelper<LogID, EventClassDescriptor>::gCollectionAddID;
+
+template <log_id_t LogID, const char* EventClassDescriptor>
+jclass EventLogHelper<LogID, EventClassDescriptor>::gEventClass;
+template <log_id_t LogID, const char* EventClassDescriptor>
+jmethodID EventLogHelper<LogID, EventClassDescriptor>::gEventInitID;
+
+template <log_id_t LogID, const char* EventClassDescriptor>
+jclass EventLogHelper<LogID, EventClassDescriptor>::gIntegerClass;
+template <log_id_t LogID, const char* EventClassDescriptor>
+jfieldID EventLogHelper<LogID, EventClassDescriptor>::gIntegerValueID;
+
+template <log_id_t LogID, const char* EventClassDescriptor>
+jclass EventLogHelper<LogID, EventClassDescriptor>::gLongClass;
+template <log_id_t LogID, const char* EventClassDescriptor>
+jfieldID EventLogHelper<LogID, EventClassDescriptor>::gLongValueID;
+
+template <log_id_t LogID, const char* EventClassDescriptor>
+jclass EventLogHelper<LogID, EventClassDescriptor>::gFloatClass;
+template <log_id_t LogID, const char* EventClassDescriptor>
+jfieldID EventLogHelper<LogID, EventClassDescriptor>::gFloatValueID;
+
+template <log_id_t LogID, const char* EventClassDescriptor>
+jclass EventLogHelper<LogID, EventClassDescriptor>::gStringClass;
+
+}  // namespace android
+
+#endif  // FRAMEWORKS_BASE_CORE_JNI_EVENTLOG_HELPER_H_
diff --git a/core/jni/hwbinder/EphemeralStorage.cpp b/core/jni/hwbinder/EphemeralStorage.cpp
index 4996bc8..3b18f2b 100644
--- a/core/jni/hwbinder/EphemeralStorage.cpp
+++ b/core/jni/hwbinder/EphemeralStorage.cpp
@@ -111,6 +111,7 @@
                 break;                                                         \
             }
 
+__attribute__((no_sanitize("unsigned-integer-overflow")))
 void EphemeralStorage::release(JNIEnv *env) {
     for (size_t i = mItems.size(); i--;) {
         const Item &item = mItems[i];
diff --git a/core/jni/include/android_runtime/android_view_Surface.h b/core/jni/include/android_runtime/android_view_Surface.h
index 2641ab8..36487b3 100644
--- a/core/jni/include/android_runtime/android_view_Surface.h
+++ b/core/jni/include/android_runtime/android_view_Surface.h
@@ -53,6 +53,7 @@
     RGBA_1010102      = 0x2b,
     JPEG              = 0x100,
     DEPTH_POINT_CLOUD = 0x101,
+    RAW_DEPTH         = 0x1002, // @hide
     YV12              = 0x32315659,
     Y8                = 0x20203859, // @hide
     Y16               = 0x20363159, // @hide
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 2042bf62..0ee71bd 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -22,7 +22,6 @@
 import "frameworks/base/libs/incident/proto/android/privacy.proto";
 import "frameworks/base/core/proto/android/service/appwidget.proto";
 import "frameworks/base/core/proto/android/service/battery.proto";
-import "frameworks/base/core/proto/android/service/graphicsstats.proto";
 import "frameworks/base/core/proto/android/service/fingerprint.proto";
 import "frameworks/base/core/proto/android/service/diskstats.proto";
 import "frameworks/base/core/proto/android/service/netstats.proto";
@@ -66,5 +65,4 @@
     android.service.notification.NotificationServiceDumpProto notification = 3004;
     android.service.pm.PackageServiceDumpProto package = 3008;
     android.service.power.PowerServiceDumpProto power = 3009;
-    android.service.GraphicsStatsServiceDumpProto graphicsstats = 3005;
 }
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index e212c43..fa645f4 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -315,7 +315,6 @@
     SettingProto boot_count = 270;
     SettingProto safe_boot_disallowed = 271;
     SettingProto device_demo_mode = 272;
-    SettingProto retail_demo_mode_constants = 273;
     SettingProto database_downgrade_reason = 274;
     SettingProto contacts_database_wal_enabled = 275;
     SettingProto multi_sim_voice_call_subscription = 276;
diff --git a/core/proto/android/service/graphicsstats.proto b/core/proto/android/service/graphicsstats.proto
index 6dbfe48..b8679b0 100644
--- a/core/proto/android/service/graphicsstats.proto
+++ b/core/proto/android/service/graphicsstats.proto
@@ -20,6 +20,7 @@
 
 option java_multiple_files = true;
 option java_outer_classname = "GraphicsStatsServiceProto";
+option optimize_for = LITE_RUNTIME;
 
 message GraphicsStatsServiceDumpProto {
     repeated GraphicsStatsProto stats = 1;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9a4d63c..e1318c3 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -182,15 +182,23 @@
     <protected-broadcast
         android:name="android.bluetooth.a2dp-sink.profile.action.AUDIO_CONFIG_CHANGED" />
     <protected-broadcast
+        android:name="android.bluetooth.avrcp-controller.profile.action.BROWSE_CONNECTION_STATE_CHANGED" />
+    <protected-broadcast
         android:name="android.bluetooth.avrcp-controller.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
+        android:name="android.bluetooth.avrcp-controller.profile.action.FOLDER_LIST" />
+    <protected-broadcast
+        android:name="android.bluetooth.avrcp-controller.profile.action.TRACK_EVENT" />
+    <protected-broadcast
         android:name="android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
+        android:name="android.bluetooth.input.profile.action.IDLE_TIME_CHANGED" />
+    <protected-broadcast
         android:name="android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED" />
     <protected-broadcast
         android:name="android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS" />
     <protected-broadcast
-        android:name="android.bluetooth.inputhost.profile.action.CONNECTION_STATE_CHANGED" />
+        android:name="android.bluetooth.hiddevice.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
         android:name="android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.CONNECTION_STATE_CHANGED" />
@@ -203,8 +211,8 @@
         android:name="com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_DELIVERY" />
     <protected-broadcast
         android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" />
-    <protected-broadcast android:name="android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED" />
+    <protected-broadcast android:name="android.bluetooth.pbapclient.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.sap.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.btopp.intent.action.INCOMING_FILE_NOTIFICATION" />
     <protected-broadcast android:name="android.btopp.intent.action.USER_CONFIRMATION_TIMEOUT" />
@@ -304,6 +312,7 @@
     <protected-broadcast android:name="com.android.server.WifiManager.action.DEVICE_IDLE" />
     <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED" />
     <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED" />
+    <protected-broadcast android:name="com.android.internal.action.EUICC_FACTORY_RESET" />
     <protected-broadcast android:name="com.android.server.usb.ACTION_OPEN_IN_APPS" />
     <protected-broadcast android:name="com.android.server.am.DELETE_DUMPHEAP" />
     <protected-broadcast android:name="com.android.server.net.action.SNOOZE_WARNING" />
@@ -1684,6 +1693,20 @@
     <permission android:name="android.permission.BIND_IMS_SERVICE"
         android:protectionLevel="signature|privileged" />
 
+    <!-- Allows an application to manage embedded subscriptions (those on a eUICC) through
+         EuiccManager APIs.
+         <p>Protection level: signature|privileged|development
+         TODO(b/35851809): Mark this as a SystemApi and remove com. prefix.
+         @hide -->
+    <permission android:name="com.android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
+                android:protectionLevel="signature|privileged|development" />
+
+    <!-- Must be required by an EuiccService to ensure that only the system can bind to it.
+         <p>Protection level: signature
+         TODO(b/35851809): Mark this as a SystemApi and remove com. prefix.
+         @hide -->
+    <permission android:name="com.android.permission.BIND_EUICC_SERVICE"
+                android:protectionLevel="signature" />
 
     <!-- ================================== -->
     <!-- Permissions for sdcard interaction -->
@@ -1893,6 +1916,11 @@
         android:description="@string/permdesc_useDataInBackground"
         android:protectionLevel="signature" />
 
+    <!-- @hide Allows an application to set display offsets for the screen.
+         This permission is not available to third party applications. -->
+    <permission android:name="android.permission.SET_DISPLAY_OFFSET"
+        android:protectionLevel="signature|privileged" />
+
     <!-- Allows a companion app to run in the background.
          <p>Protection level: normal
     -->
@@ -2753,6 +2781,13 @@
     <permission android:name="android.permission.ACCESS_INPUT_FLINGER"
         android:protectionLevel="signature" />
 
+    <!-- Allows an application to disable/enable input devices.
+         Could be used to prevent unwanted touch events
+         on a touchscreen, for example during swimming or rain.
+         @hide -->
+    <permission android:name="com.android.permission.DISABLE_INPUT_DEVICE"
+        android:protectionLevel="signature" />
+
     <!-- Allows an application to configure and connect to Wifi displays
          @hide -->
     <permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY"
@@ -3144,6 +3179,11 @@
     <permission android:name="android.permission.MANAGE_NOTIFICATIONS"
                 android:protectionLevel="signature" />
 
+    <!-- Allows notifications to be colorized
+         <p>Not for use by third-party applications. @hide -->
+    <permission android:name="android.permission.USE_COLORIZED_NOTIFICATIONS"
+                android:protectionLevel="signature|setup" />
+
     <!-- Allows access to keyguard secure storage.  Only allowed for system processes.
         @hide -->
     <permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE"
@@ -3764,6 +3804,14 @@
         <service android:name="com.android.server.PreloadsFileCacheExpirationJobService"
                  android:permission="android.permission.BIND_JOB_SERVICE" >
         </service>
+
+        <service android:name="com.android.server.camera.CameraStatsJobService"
+                 android:permission="android.permission.BIND_JOB_SERVICE" >
+        </service>
+
+        <service android:name="com.android.server.timezone.TimeZoneUpdateIdler"
+                 android:permission="android.permission.BIND_JOB_SERVICE" >
+        </service>
     </application>
 
 </manifest>
diff --git a/core/res/res/anim/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml
index b07f470..bea0ee5 100644
--- a/core/res/res/anim/task_close_enter.xml
+++ b/core/res/res/anim/task_close_enter.xml
@@ -18,7 +18,7 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal">
+        android:shareInterpolator="false" android:zAdjustment="normal">
 
     <alpha android:fromAlpha="0.6" android:toAlpha="1.0"
             android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml
index d23c74f..b6a0807 100644
--- a/core/res/res/anim/task_close_exit.xml
+++ b/core/res/res/anim/task_close_exit.xml
@@ -18,7 +18,7 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
+        android:shareInterpolator="false" android:zAdjustment="top">
 
     <alpha android:fromAlpha="1.0" android:toAlpha="0"
             android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
diff --git a/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_alpha.png
deleted file mode 100644
index e0a2ba1..0000000
--- a/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_dark.png b/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_dark.png
new file mode 100644
index 0000000..8ad305d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_light.png b/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_light.png
new file mode 100644
index 0000000..887fde4
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_alpha.png
deleted file mode 100644
index d37e8ee..0000000
--- a/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_dark.png b/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_dark.png
new file mode 100644
index 0000000..5739df7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_light.png b/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_light.png
new file mode 100644
index 0000000..58c344a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_alpha.png
deleted file mode 100644
index 0c604d9..0000000
--- a/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_dark.png
new file mode 100644
index 0000000..ac699cf
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_light.png
new file mode 100644
index 0000000..84c5a11
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_alpha.png
deleted file mode 100644
index 2c3f4ff..0000000
--- a/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_dark.png
new file mode 100644
index 0000000..372ab35
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_light.png
new file mode 100644
index 0000000..7fc993d6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_alpha.png
deleted file mode 100644
index 991c50e..0000000
--- a/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_dark.png
new file mode 100644
index 0000000..3261626
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_light.png
new file mode 100644
index 0000000..36adcd0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_alpha.png
deleted file mode 100644
index 05fb919..0000000
--- a/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_dark.png
new file mode 100644
index 0000000..9fbc9b0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_light.png
new file mode 100644
index 0000000..086aefe
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/toast_frame.9.png b/core/res/res/drawable-hdpi/toast_frame.9.png
deleted file mode 100644
index a804a8a..0000000
--- a/core/res/res/drawable-hdpi/toast_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/toast_frame.9.png b/core/res/res/drawable-ldpi/toast_frame.9.png
deleted file mode 100644
index e64dc75..0000000
--- a/core/res/res/drawable-ldpi/toast_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_disabled_mtrl_dark.png b/core/res/res/drawable-mdpi/ic_media_route_disabled_mtrl_dark.png
new file mode 100644
index 0000000..4446ea4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_disabled_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_disabled_mtrl_light.png b/core/res/res/drawable-mdpi/ic_media_route_disabled_mtrl_light.png
new file mode 100644
index 0000000..4d790c6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_disabled_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_off_mtrl_dark.png b/core/res/res/drawable-mdpi/ic_media_route_off_mtrl_dark.png
new file mode 100644
index 0000000..c401dc0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_off_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_off_mtrl_light.png b/core/res/res/drawable-mdpi/ic_media_route_off_mtrl_light.png
new file mode 100644
index 0000000..e24d58650
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_off_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_0_mtrl_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_0_mtrl_dark.png
new file mode 100644
index 0000000..5a9fea0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_0_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_0_mtrl_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_0_mtrl_light.png
new file mode 100644
index 0000000..3029695
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_0_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_1_mtrl_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_1_mtrl_dark.png
new file mode 100644
index 0000000..d8d0b7b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_1_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_1_mtrl_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_1_mtrl_light.png
new file mode 100644
index 0000000..868c7f4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_1_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_2_mtrl_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_2_mtrl_dark.png
new file mode 100644
index 0000000..83a1b69
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_2_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_2_mtrl_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_2_mtrl_light.png
new file mode 100644
index 0000000..269ee8e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_2_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_mtrl_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_mtrl_dark.png
new file mode 100644
index 0000000..9f3d12e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_mtrl_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_mtrl_light.png
new file mode 100644
index 0000000..ca865f2
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/toast_frame.9.png b/core/res/res/drawable-mdpi/toast_frame.9.png
deleted file mode 100644
index 778e4e6..0000000
--- a/core/res/res/drawable-mdpi/toast_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_disabled_mtrl_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_disabled_mtrl_dark.png
new file mode 100644
index 0000000..c4dc132
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_disabled_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_disabled_mtrl_light.png b/core/res/res/drawable-xhdpi/ic_media_route_disabled_mtrl_light.png
new file mode 100644
index 0000000..b14617c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_disabled_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_off_mtrl_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_off_mtrl_dark.png
new file mode 100644
index 0000000..bb30773
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_off_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_off_mtrl_light.png b/core/res/res/drawable-xhdpi/ic_media_route_off_mtrl_light.png
new file mode 100644
index 0000000..a05d7d7
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_off_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_0_mtrl_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_0_mtrl_dark.png
new file mode 100644
index 0000000..8690cf4
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_0_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_0_mtrl_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_0_mtrl_light.png
new file mode 100644
index 0000000..2cf94ce
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_0_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_1_mtrl_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_1_mtrl_dark.png
new file mode 100644
index 0000000..e3fd200
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_1_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_1_mtrl_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_1_mtrl_light.png
new file mode 100644
index 0000000..0af22be
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_1_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_2_mtrl_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_2_mtrl_dark.png
new file mode 100644
index 0000000..6cb970c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_2_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_2_mtrl_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_2_mtrl_light.png
new file mode 100644
index 0000000..9577e7b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_2_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_mtrl_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_mtrl_dark.png
new file mode 100644
index 0000000..8290b98
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_mtrl_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_mtrl_light.png
new file mode 100644
index 0000000..abdecfb
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/toast_frame.9.png b/core/res/res/drawable-xhdpi/toast_frame.9.png
deleted file mode 100644
index 77e69c7..0000000
--- a/core/res/res/drawable-xhdpi/toast_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_disabled_mtrl_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_mtrl_dark.png
new file mode 100644
index 0000000..fdb2121
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_disabled_mtrl_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_mtrl_light.png
new file mode 100644
index 0000000..9ce7e3a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_off_mtrl_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_off_mtrl_dark.png
new file mode 100644
index 0000000..e8601ce
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_off_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_off_mtrl_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_off_mtrl_light.png
new file mode 100644
index 0000000..34928d7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_off_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_0_mtrl_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_mtrl_dark.png
new file mode 100644
index 0000000..23d8ba8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_0_mtrl_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_mtrl_light.png
new file mode 100644
index 0000000..ef5039c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_1_mtrl_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_mtrl_dark.png
new file mode 100644
index 0000000..4c0f0e0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_1_mtrl_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_mtrl_light.png
new file mode 100644
index 0000000..8cd82da
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_2_mtrl_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_mtrl_dark.png
new file mode 100644
index 0000000..ecfe346
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_2_mtrl_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_mtrl_light.png
new file mode 100644
index 0000000..d25288d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_mtrl_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_mtrl_dark.png
new file mode 100644
index 0000000..8e47095
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_mtrl_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_mtrl_light.png
new file mode 100644
index 0000000..4b64a48
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/toast_frame.9.png b/core/res/res/drawable-xxhdpi/toast_frame.9.png
deleted file mode 100644
index edecb63..0000000
--- a/core/res/res/drawable-xxhdpi/toast_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ic_lock_bugreport.xml b/core/res/res/drawable/ic_lock_bugreport.xml
index b0c32e0..5501254 100644
--- a/core/res/res/drawable/ic_lock_bugreport.xml
+++ b/core/res/res/drawable/ic_lock_bugreport.xml
@@ -1,7 +1,7 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
+    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
 
@@ -14,12 +14,12 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32dp"
-        android:height="32dp"
+        android:width="24.0dp"
+        android:height="24.0dp"
         android:viewportWidth="24.0"
         android:viewportHeight="24.0"
         android:tint="?attr/colorControlNormal">
     <path
-        android:fillColor="@color/white"
-        android:pathData="M20.0,8.0l-2.8,0.0c-0.5,-0.8 -1.1,-1.5 -1.8,-2.0L17.0,4.4L15.6,3.0l-2.2,2.2C13.0,5.1 12.5,5.0 12.0,5.0s-1.0,0.1 -1.4,0.2L8.4,3.0L7.0,4.4L8.6,6.0C7.9,6.5 7.3,7.2 6.8,8.0L4.0,8.0l0.0,2.0l2.1,0.0C6.0,10.3 6.0,10.7 6.0,11.0l0.0,1.0L4.0,12.0l0.0,2.0l2.0,0.0l0.0,1.0c0.0,0.3 0.0,0.7 0.1,1.0L4.0,16.0l0.0,2.0l2.8,0.0c1.0,1.8 3.0,3.0 5.2,3.0s4.2,-1.2 5.2,-3.0L20.0,18.0l0.0,-2.0l-2.1,0.0c0.1,-0.3 0.1,-0.7 0.1,-1.0l0.0,-1.0l2.0,0.0l0.0,-2.0l-2.0,0.0l0.0,-1.0c0.0,-0.3 0.0,-0.7 -0.1,-1.0L20.0,10.0L20.0,8.0zM14.0,16.0l-4.0,0.0l0.0,-2.0l4.0,0.0L14.0,16.0zM14.0,12.0l-4.0,0.0l0.0,-2.0l4.0,0.0L14.0,12.0z"/>
+        android:fillColor="#FF000000"
+        android:pathData="M20.0,8.0l-2.81,0.0a5.985,5.985 0.0,0.0 0.0,-1.82 -1.96l0.93,-0.93a0.99,0.996 0.0,1.0 0.0,-1.41 -1.41l-1.47,1.47C12.96,5.06 12.49,5.0 12.0,5.0s-0.9,0.06 -1.4,0.17L9.12,3.7a0.99,0.996 0.0,1.0 0.0,-1.41 1.41l0.9,0.92C7.88,6.55 7.26,7.22 6.81,8.0L4.0,8.0c-0.55,0.0 -1.0,0.45 -1.0,1.0s0.45,1.0 1.0,1.0l2.09,0.0c0.0,0.33 0.0,0.66 -0.09,1.0l0.0,1.0L4.0,12.0c-0.55,0.0 -1.0,0.45 -1.0,1.0s0.45,1.0 1.0,1.0l2.0,0.0l0.0,1.0c0.0,0.3 0.0,0.6 0.09,1.0L4.0,16.0c-0.55,0.0 -1.0,0.45 -1.0,1.0s0.45,1.0 1.0,1.0l2.81,0.0c1.04,1.79 2.97,3.0 5.19,3.0s4.15,-1.21 5.19,-3.0L20.0,18.0c0.55,0.0 1.0,-0.45 1.0,-1.0s-0.45,-1.0 -1.0,-1.0l-2.09,0.0c0.05,-0.3 0.09,-0.6 0.09,-1.0l0.0,-1.0l2.0,0.0c0.55,0.0 1.0,-0.45 1.0,-1.0s-0.45,-1.0 -1.0,-1.0l-2.0,0.0l0.0,-1.0c0.0,-0.34 -0.04,-0.67 -0.09,-1.0L20.0,10.0c0.55,0.0 1.0,-0.45 1.0,-1.0s-0.45,-1.0 -1.0,-1.0zm-6.0,8.0l-4.0,0.0l0.0,-2.0l4.0,0.0l0.0,2.0zm0.0,-4.0l-4.0,0.0l0.0,-2.0l4.0,0.0l0.0,2.0z"/>
 </vector>
diff --git a/core/res/res/drawable/ic_lock_power_off.xml b/core/res/res/drawable/ic_lock_power_off.xml
index babd1be..7e5676bd 100644
--- a/core/res/res/drawable/ic_lock_power_off.xml
+++ b/core/res/res/drawable/ic_lock_power_off.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -16,10 +16,13 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="24.0dp"
         android:height="24.0dp"
-        android:viewportHeight="24.0"
         android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
         android:tint="?attr/colorControlNormal">
     <path
         android:fillColor="#FF000000"
-        android:pathData="M13.0,3.0l-2.0,0.0l0.0,10.0l2.0,0.0L13.0,3.0zm4.83,2.17l-1.42,1.42C17.99,7.86 19.0,9.81 19.0,12.0c0.0,3.87 -3.13,7.0 -7.0,7.0s-7.0,-3.13 -7.0,-7.0c0.0,-2.19 1.01,-4.14 2.58,-5.42L6.17,5.17C4.23,6.82 3.0,9.26 3.0,12.0c0.0,4.97 4.03,9.0 9.0,9.0s9.0,-4.03 9.0,-9.0c0.0,-2.74 -1.23,-5.18 -3.17,-6.83z"/>
+        android:pathData="M12.0,3.0c-0.6,0.0 -1.0,0.4 -1.0,1.0l0.0,8.0c0.0,0.6 0.4,1.0 1.0,1.0s1.0,-0.4 1.0,-1.0L13.0,4.0c0.0,-0.6 -0.4,-1.0 -1.0,-1.0z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M17.1,5.9c-0.4,0.4 -0.4,1.0 0.0,1.4 1.3,1.4 2.1,3.4 1.8,5.6 -0.4,3.2 -3.0,5.7 -6.2,6.1 -4.0,0.4 -7.7,-2.9 -7.7,-7.0 0.0,-1.0 0.7,-3.5 1.9,-4.0 0.4,-0.4 0.4,-1.0 0.0,-1.4 -0.4,-0.4 -1.0,-0.4 -1.4,0.0C4.0,7.4 3.1,9.5 3.0,11.7c-0.1,4.9 3.8,9.1 8.7,9.3 5.0,0.2 9.3,-3.9 9.3,-9.0 0.0,-2.4 -0.9,-4.5 -2.4,-6.1 -0.4,-0.4 -1.1,-0.4 -1.5,0.0z"/>
 </vector>
diff --git a/core/res/res/drawable/ic_media_route_connecting_material.xml b/core/res/res/drawable/ic_media_route_connecting_material_dark.xml
similarity index 100%
rename from core/res/res/drawable/ic_media_route_connecting_material.xml
rename to core/res/res/drawable/ic_media_route_connecting_material_dark.xml
diff --git a/core/res/res/drawable/ic_media_route_connecting_material.xml b/core/res/res/drawable/ic_media_route_connecting_material_light.xml
similarity index 100%
copy from core/res/res/drawable/ic_media_route_connecting_material.xml
copy to core/res/res/drawable/ic_media_route_connecting_material_light.xml
diff --git a/core/res/res/drawable/ic_media_route_material.xml b/core/res/res/drawable/ic_media_route_material.xml
deleted file mode 100644
index 3e3f388..0000000
--- a/core/res/res/drawable/ic_media_route_material.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_checked="true" android:state_enabled="true"
-        android:drawable="@android:drawable/ic_media_route_connecting_material" />
-    <item android:state_activated="true" android:state_enabled="true">
-        <bitmap android:src="@android:drawable/ic_media_route_on_mtrl_alpha"
-            android:tint="?attr/colorControlNormal" />
-    </item>
-    <item android:state_enabled="true">
-        <bitmap android:src="@android:drawable/ic_media_route_off_mtrl_alpha"
-            android:tint="?attr/colorControlNormal" />
-    </item>
-    <item>
-        <bitmap android:src="@android:drawable/ic_media_route_disabled_mtrl_alpha"
-            android:tint="?attr/colorControlNormal" />
-    </item>
-</selector>
diff --git a/core/res/res/drawable/ic_media_route_material_dark.xml b/core/res/res/drawable/ic_media_route_material_dark.xml
new file mode 100644
index 0000000..eb26ac8
--- /dev/null
+++ b/core/res/res/drawable/ic_media_route_material_dark.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_enabled="true"
+        android:drawable="@android:drawable/ic_media_route_connecting_material_dark" />
+    <item android:state_activated="true" android:state_enabled="true">
+        <bitmap android:src="@android:drawable/ic_media_route_on_mtrl_alpha"
+            android:tint="?attr/colorControlNormal" />
+    </item>
+    <item android:state_enabled="true">
+        <bitmap android:src="@android:drawable/ic_media_route_off_mtrl_alpha"
+            android:tint="?attr/colorControlNormal" />
+    </item>
+    <item>
+        <bitmap android:src="@android:drawable/ic_media_route_disabled_mtrl_alpha"
+            android:tint="?attr/colorControlNormal" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/ic_media_route_material_light.xml b/core/res/res/drawable/ic_media_route_material_light.xml
new file mode 100644
index 0000000..37bbf14
--- /dev/null
+++ b/core/res/res/drawable/ic_media_route_material_light.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_enabled="true"
+        android:drawable="@android:drawable/ic_media_route_connecting_material_light" />
+    <item android:state_activated="true" android:state_enabled="true">
+        <bitmap android:src="@android:drawable/ic_media_route_on_mtrl_alpha"
+            android:tint="?attr/colorControlNormal" />
+    </item>
+    <item android:state_enabled="true">
+        <bitmap android:src="@android:drawable/ic_media_route_off_mtrl_alpha"
+            android:tint="?attr/colorControlNormal" />
+    </item>
+    <item>
+        <bitmap android:src="@android:drawable/ic_media_route_disabled_mtrl_alpha"
+            android:tint="?attr/colorControlNormal" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/ic_reply_notification.xml b/core/res/res/drawable/ic_reply_notification.xml
new file mode 100644
index 0000000..88b8c5b
--- /dev/null
+++ b/core/res/res/drawable/ic_reply_notification.xml
@@ -0,0 +1,27 @@
+<!--
+  ~ 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="10dp"
+        android:height="10dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M10.0,9.0L10.0,5.0l-7.0,7.0 7.0,7.0l0.0,-4.1c5.0,0.0 8.5,1.6 11.0,5.1 -1.0,-5.0 -4.0,-10.0 -11.0,-11.0z"/>
+    <path
+        android:pathData="M0 0h24v24H0z"
+        android:fillColor="#00000000"/>
+</vector>
diff --git a/core/res/res/drawable/ic_restart.xml b/core/res/res/drawable/ic_restart.xml
index 47ac483..30d98a5 100644
--- a/core/res/res/drawable/ic_restart.xml
+++ b/core/res/res/drawable/ic_restart.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -16,13 +16,13 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="24.0dp"
         android:height="24.0dp"
-        android:viewportHeight="24.0"
         android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
         android:tint="?attr/colorControlNormal">
     <path
         android:fillColor="#FF000000"
-        android:pathData="M12.0,4.0L12.0,1.0L8.0,5.0l4.0,4.0L12.0,6.0c3.9,0.0 7.0,3.1 7.0,7.0c0.0,3.9 -3.1,7.0 -7.0,7.0l0.0,2.0c5.0,0.0 9.0,-4.0 9.0,-9.0C21.0,8.0 17.0,4.0 12.0,4.0z"/>
+        android:pathData="M10.61,17.83C7.97,17.2 6.0,14.83 6.0,12.0c0.0,-0.71 0.11,-1.34 0.35,-1.93c0.2,-0.51 -0.05,-1.09 -0.56,-1.3c-0.52,-0.21 -1.1,0.05 -1.3,0.56C4.16,10.16 4.0,11.03 4.0,12.0c0.0,3.87 2.76,7.1 6.42,7.84c0.3,0.06 0.58,-0.19 0.58,-0.5l0.0,-1.03C11.0,18.08 10.83,17.88 10.61,17.83z"/>
     <path
         android:fillColor="#FF000000"
-        android:pathData="M5.0,12.9C5.0,11.0 5.8,9.2 7.2,7.9L5.8,6.4C4.0,8.1 3.0,10.5 3.0,12.9c0.0,4.0 2.7,7.6 6.5,8.7l0.5,-1.9C7.1,18.8 5.0,16.1 5.0,12.9z"/>
+        android:pathData="M12.01,4.0L12.01,1.9c0.0,-0.45 -0.54,-0.67 -0.86,-0.36L7.77,4.93c-0.39,0.39 -0.39,1.02 0.0,1.41l3.39,3.39c0.31,0.31 0.85,0.09 0.85,-0.35L12.01,6.0C15.32,6.01 18.0,8.69 18.0,12.0c0.0,2.83 -1.97,5.2 -4.61,5.83C13.17,17.88 13.0,18.08 13.0,18.31l0.0,1.03c0.0,0.31 0.28,0.56 0.58,0.5C17.24,19.1 20.0,15.87 20.0,12.0C20.0,7.59 16.42,4.01 12.01,4.0z"/>
 </vector>
diff --git a/core/res/res/drawable/notification_reply_background.xml b/core/res/res/drawable/notification_reply_background.xml
new file mode 100644
index 0000000..08e22f2
--- /dev/null
+++ b/core/res/res/drawable/notification_reply_background.xml
@@ -0,0 +1,24 @@
+<!--
+  ~ Copyright (C) 2017 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+    <solid
+        android:color="#ff757575"/>
+    <size
+        android:width="16dp"
+        android:height="16dp"/>
+</shape>
diff --git a/core/res/res/drawable/toast_frame.xml b/core/res/res/drawable/toast_frame.xml
new file mode 100644
index 0000000..d57bd6a
--- /dev/null
+++ b/core/res/res/drawable/toast_frame.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <!-- background is material_grey_200 with .9 alpha -->
+    <solid android:color="#E6EEEEEE" />
+    <corners android:radius="22dp" />
+</shape>
+
diff --git a/core/res/res/layout/chooser_row.xml b/core/res/res/layout/chooser_row.xml
index 9baa32c..6c1271d 100644
--- a/core/res/res/layout/chooser_row.xml
+++ b/core/res/res/layout/chooser_row.xml
@@ -18,11 +18,9 @@
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
               android:orientation="horizontal"
-              android:layout_width="match_parent" android:layout_height="wrap_content"
-              android:minHeight="80dp"
+              android:layout_width="match_parent"
+              android:layout_height="100dp"
               android:gravity="start|top"
-              android:paddingTop="8dp"
-              android:paddingBottom="8dp"
               android:paddingStart="@dimen/chooser_grid_padding"
               android:paddingEnd="@dimen/chooser_grid_padding"
               android:weightSum="4">
diff --git a/core/res/res/layout/notification_material_media_action.xml b/core/res/res/layout/notification_material_media_action.xml
index 19a6f84..900ca2d 100644
--- a/core/res/res/layout/notification_material_media_action.xml
+++ b/core/res/res/layout/notification_material_media_action.xml
@@ -15,11 +15,12 @@
   ~ limitations under the License
   -->
 
-<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
+<ImageButton
+    xmlns:android="http://schemas.android.com/apk/res/android"
     style="@android:style/Widget.Material.Button.Borderless.Small"
     android:id="@+id/action0"
-    android:layout_width="48dp"
-    android:layout_height="48dp"
+    android:layout_width="@dimen/media_notification_action_button_size"
+    android:layout_height="@dimen/media_notification_action_button_size"
     android:paddingBottom="8dp"
     android:paddingTop="8dp"
     android:paddingStart="8dp"
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 5a2bf4e..f0c980c 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -28,15 +28,15 @@
         android:id="@+id/icon"
         android:layout_width="?attr/notificationHeaderIconSize"
         android:layout_height="?attr/notificationHeaderIconSize"
-        android:layout_marginEnd="3dp"
+        android:layout_marginEnd="@dimen/notification_header_icon_margin_end"
         />
     <TextView
         android:id="@+id/app_name_text"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textAppearance="?attr/notificationHeaderTextAppearance"
-        android:layout_marginStart="3dp"
-        android:layout_marginEnd="2dp"
+        android:layout_marginStart="@dimen/notification_header_app_name_margin_start"
+        android:layout_marginEnd="@dimen/notification_header_separating_margin"
         android:singleLine="true"
         />
     <TextView
@@ -44,8 +44,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textAppearance="?attr/notificationHeaderTextAppearance"
-        android:layout_marginStart="2dp"
-        android:layout_marginEnd="2dp"
+        android:layout_marginStart="@dimen/notification_header_separating_margin"
+        android:layout_marginEnd="@dimen/notification_header_separating_margin"
         android:text="@string/notification_header_divider_symbol"
         android:visibility="gone"/>
     <TextView
@@ -53,8 +53,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textAppearance="?attr/notificationHeaderTextAppearance"
-        android:layout_marginStart="2dp"
-        android:layout_marginEnd="2dp"
+        android:layout_marginStart="@dimen/notification_header_separating_margin"
+        android:layout_marginEnd="@dimen/notification_header_separating_margin"
         android:visibility="gone"
         android:singleLine="true"/>
     <TextView
@@ -62,8 +62,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textAppearance="?attr/notificationHeaderTextAppearance"
-        android:layout_marginStart="2dp"
-        android:layout_marginEnd="2dp"
+        android:layout_marginStart="@dimen/notification_header_separating_margin"
+        android:layout_marginEnd="@dimen/notification_header_separating_margin"
         android:text="@string/notification_header_divider_symbol"
         android:singleLine="true"
         android:visibility="gone"/>
@@ -73,8 +73,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center"
-        android:layout_marginStart="2dp"
-        android:layout_marginEnd="2dp"
+        android:layout_marginStart="@dimen/notification_header_separating_margin"
+        android:layout_marginEnd="@dimen/notification_header_separating_margin"
         android:showRelative="true"
         android:singleLine="true"
         android:visibility="gone" />
@@ -82,21 +82,22 @@
         android:id="@+id/chronometer"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginStart="2dp"
-        android:layout_marginEnd="2dp"
+        android:layout_marginStart="@dimen/notification_header_separating_margin"
+        android:layout_marginEnd="@dimen/notification_header_separating_margin"
         android:layout="@layout/notification_template_part_chronometer"
         android:visibility="gone"
         />
     <com.android.internal.widget.NotificationExpandButton
         android:id="@+id/expand_button"
         android:background="@null"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:paddingTop="1dp"
+        android:layout_width="@dimen/notification_header_expand_icon_size"
+        android:layout_height="@dimen/notification_header_expand_icon_size"
+        android:paddingTop="@dimen/notification_expand_button_padding_top"
         android:visibility="gone"
         android:contentDescription="@string/expand_button_content_description_collapsed"
         />
-    <ImageView android:id="@+id/profile_badge"
+    <ImageView
+        android:id="@+id/profile_badge"
         android:layout_width="@dimen/notification_badge_size"
         android:layout_height="@dimen/notification_badge_size"
         android:layout_gravity="center"
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index ccd26fb..353a1a5 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -15,12 +15,12 @@
   ~ limitations under the License
   -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/status_bar_latest_event_content"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:tag="base"
-    >
+    android:tag="base" >
     <include layout="@layout/notification_template_header" />
     <LinearLayout
         android:id="@+id/notification_main_column"
@@ -31,19 +31,14 @@
         android:layout_marginEnd="@dimen/notification_content_margin_end"
         android:layout_marginTop="@dimen/notification_content_margin_top"
         android:layout_marginBottom="@dimen/notification_content_margin_bottom"
-        android:orientation="vertical"
-        >
+        android:orientation="vertical" >
         <include layout="@layout/notification_template_part_line1" />
         <include layout="@layout/notification_template_text" />
+        <include
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/notification_progress_bar_height"
+            android:layout_marginTop="@dimen/notification_progress_margin_top"
+            layout="@layout/notification_template_progress" />
     </LinearLayout>
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom"
-        android:layout_marginStart="@dimen/notification_content_margin_start"
-        android:layout_marginBottom="15dp"
-        android:layout_marginEnd="@dimen/notification_content_margin_end" >
-        <include layout="@layout/notification_template_progress" />
-    </FrameLayout>
     <include layout="@layout/notification_template_right_icon" />
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_big_base.xml b/core/res/res/layout/notification_template_material_big_base.xml
index 8b0b476..6b1049a 100644
--- a/core/res/res/layout/notification_template_material_big_base.xml
+++ b/core/res/res/layout/notification_template_material_big_base.xml
@@ -20,51 +20,42 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:tag="big"
-    >
+    android:tag="big" >
     <LinearLayout
             android:id="@+id/notification_action_list_margin_target"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginBottom="@dimen/notification_action_list_height"
-            android:orientation="vertical"
-            >
+            android:orientation="vertical" >
         <FrameLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_gravity="top"
-            >
+            android:layout_gravity="top" >
             <include layout="@layout/notification_template_header" />
             <LinearLayout
                 android:id="@+id/notification_main_column"
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_gravity="top"
+                android:layout_height="wrap_content"
                 android:layout_marginStart="@dimen/notification_content_margin_start"
                 android:layout_marginEnd="@dimen/notification_content_margin_end"
                 android:layout_marginTop="@dimen/notification_content_margin_top"
                 android:layout_marginBottom="@dimen/notification_content_margin_bottom"
-                android:orientation="vertical"
-                >
+                android:orientation="vertical" >
                 <include layout="@layout/notification_template_part_line1" />
                 <include layout="@layout/notification_template_text" />
+                <include
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/notification_progress_bar_height"
+                    android:layout_marginTop="@dimen/notification_progress_margin_top"
+                    layout="@layout/notification_template_progress" />
             </LinearLayout>
-            <FrameLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_gravity="bottom"
-                android:layout_marginStart="@dimen/notification_content_margin_start"
-                android:layout_marginBottom="15dp"
-                android:layout_marginEnd="@dimen/notification_content_margin_end">
-                <include layout="@layout/notification_template_progress" />
-            </FrameLayout>
             <include layout="@layout/notification_template_right_icon" />
         </FrameLayout>
-        <ViewStub android:layout="@layout/notification_material_reply_text"
-                android:id="@+id/notification_material_reply_container"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-        />
+        <ViewStub
+            android:layout="@layout/notification_material_reply_text"
+            android:id="@+id/notification_material_reply_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
     </LinearLayout>
     <include layout="@layout/notification_material_action_list" />
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_big_media.xml b/core/res/res/layout/notification_template_material_big_media.xml
index 532f28e..cc4dd387 100644
--- a/core/res/res/layout/notification_template_material_big_media.xml
+++ b/core/res/res/layout/notification_template_material_big_media.xml
@@ -16,7 +16,8 @@
   -->
 
 <!-- Layout for the expanded media notification -->
-<com.android.internal.widget.MediaNotificationView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.internal.widget.MediaNotificationView
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/status_bar_latest_event_content"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
@@ -32,7 +33,7 @@
     />
     <include layout="@layout/notification_template_header"
         android:layout_width="match_parent"
-        android:layout_height="53dp"
+        android:layout_height="@dimen/media_notification_header_height"
         android:layout_gravity="start"/>
     <LinearLayout
         android:layout_width="match_parent"
@@ -55,15 +56,9 @@
         </LinearLayout>
         <LinearLayout
             android:id="@+id/media_actions"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="-21dp"
-            android:paddingStart="8dp"
-            android:paddingBottom="12dp"
-            android:gravity="top"
             android:orientation="horizontal"
             android:layoutDirection="ltr"
-            >
+            style="@style/NotificationMediaActionContainer" >
             <!-- media buttons will be added here -->
         </LinearLayout>
     </LinearLayout>
diff --git a/core/res/res/layout/notification_template_material_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml
index 1aca99f..0cfe689 100644
--- a/core/res/res/layout/notification_template_material_big_text.xml
+++ b/core/res/res/layout/notification_template_material_big_text.xml
@@ -55,6 +55,7 @@
                 android:singleLine="false"
                 android:gravity="top"
                 android:visibility="gone"
+                android:textAlignment="viewStart"
                 />
         </LinearLayout>
 
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index 4be53e0..2c69b90 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -31,8 +31,8 @@
         android:scaleType="centerCrop"
     />
     <include layout="@layout/notification_template_header"
-        android:layout_width="fill_parent"
-        android:layout_height="53dp" />
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/media_notification_header_height" />
     <LinearLayout
         android:id="@+id/notification_main_column"
         android:layout_width="match_parent"
@@ -61,7 +61,7 @@
             android:layout_height="wrap_content"
             android:layout_gravity="bottom|end"
             android:layout_marginStart="10dp"
-            android:layout_marginBottom="12dp"
+            android:layout_marginBottom="@dimen/media_notification_actions_padding_bottom"
             android:layoutDirection="ltr"
             android:orientation="horizontal"
             >
diff --git a/core/res/res/layout/notification_template_part_line1.xml b/core/res/res/layout/notification_template_part_line1.xml
index 308b30f..ca35de3 100644
--- a/core/res/res/layout/notification_template_part_line1.xml
+++ b/core/res/res/layout/notification_template_part_line1.xml
@@ -28,6 +28,7 @@
         android:singleLine="true"
         android:ellipsize="marquee"
         android:fadingEdge="horizontal"
+        android:textAlignment="viewStart"
         />
     <TextView android:id="@+id/text_line_1"
         android:textAppearance="@style/TextAppearance.Material.Notification"
diff --git a/core/res/res/layout/notification_template_progressbar.xml b/core/res/res/layout/notification_template_progressbar.xml
index 61480b8..98e2c03 100644
--- a/core/res/res/layout/notification_template_progressbar.xml
+++ b/core/res/res/layout/notification_template_progressbar.xml
@@ -18,6 +18,6 @@
 <ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@android:id/progress"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
+    android:layout_height="@dimen/notification_progress_bar_height"
     style="@style/Widget.Material.Light.ProgressBar.Horizontal"
     />
diff --git a/core/res/res/layout/notification_template_right_icon.xml b/core/res/res/layout/notification_template_right_icon.xml
index 65a5015..d379256 100644
--- a/core/res/res/layout/notification_template_right_icon.xml
+++ b/core/res/res/layout/notification_template_right_icon.xml
@@ -15,13 +15,29 @@
   ~ limitations under the License
   -->
 
-<ImageView android:id="@+id/right_icon" xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="40dp"
-    android:layout_height="40dp"
-    android:layout_marginEnd="@dimen/notification_content_margin_end"
-    android:layout_marginTop="36dp"
-    android:layout_gravity="top|end"
-    android:scaleType="centerCrop"
-    />
-
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:id="@+id/right_icon_container"
+             android:layout_width="wrap_content"
+             android:layout_height="wrap_content"
+             android:layout_gravity="top|end">
+    <ImageView android:id="@+id/right_icon"
+               android:layout_width="@dimen/notification_right_icon_size"
+               android:layout_height="@dimen/notification_right_icon_size"
+               android:layout_gravity="top|end"
+               android:layout_marginTop="36dp"
+               android:layout_marginEnd="@dimen/notification_content_margin_end"
+               android:scaleType="centerCrop"
+               android:importantForAccessibility="no" />
+    <ImageButton android:id="@+id/reply_icon_action"
+               android:layout_width="16dp"
+               android:layout_height="16dp"
+               android:layout_gravity="top|end"
+               android:layout_marginTop="64dp"
+               android:layout_marginEnd="12dp"
+               android:background="@drawable/notification_reply_background"
+               android:src="@drawable/ic_reply_notification"
+               android:scaleType="center"
+               android:contentDescription="@string/notification_reply_button_accessibility"
+               visiblity="gone"/>
+</FrameLayout>
 
diff --git a/core/res/res/layout/notification_template_text.xml b/core/res/res/layout/notification_template_text.xml
index 20c2896..68f34c8 100644
--- a/core/res/res/layout/notification_template_text.xml
+++ b/core/res/res/layout/notification_template_text.xml
@@ -24,5 +24,6 @@
     android:fadingEdge="horizontal"
     android:gravity="top"
     android:singleLine="true"
+    android:textAlignment="viewStart"
     android:textAppearance="@style/TextAppearance.Material.Notification"
     />
diff --git a/core/res/res/layout/resolve_grid_item.xml b/core/res/res/layout/resolve_grid_item.xml
index 305c8b0..71c153f 100644
--- a/core/res/res/layout/resolve_grid_item.xml
+++ b/core/res/res/layout/resolve_grid_item.xml
@@ -18,10 +18,9 @@
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
               android:orientation="vertical"
-              android:layout_width="0dp"
+              android:layout_width="76dp"
               android:layout_height="wrap_content"
-              android:layout_weight="1"
-              android:minWidth="80dp"
+              android:minHeight="100dp"
               android:gravity="center"
               android:paddingTop="8dp"
               android:paddingBottom="8dp"
@@ -49,7 +48,7 @@
     <TextView android:id="@android:id/text1"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
-              android:layout_marginTop="8dp"
+              android:layout_marginTop="4dp"
               android:layout_marginLeft="4dp"
               android:layout_marginRight="4dp"
               android:textAppearance="?attr/textAppearanceSmall"
diff --git a/core/res/res/layout/shutdown_dialog.xml b/core/res/res/layout/shutdown_dialog.xml
new file mode 100644
index 0000000..398bfb1
--- /dev/null
+++ b/core/res/res/layout/shutdown_dialog.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:gravity="center_horizontal" >
+
+    <Space
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="6" />
+
+    <TextView
+        android:id="@id/text1"
+        android:layout_width="wrap_content"
+        android:layout_height="32dp"
+        android:text="@string/shutdown_progress"
+        android:textDirection="locale"
+        android:textSize="24sp"
+        android:textAppearance="?attr/textAppearanceLarge"
+        android:gravity="center"
+        android:layout_marginBottom="24dp"
+        android:fontFamily="@string/config_headlineFontFamily"/>
+
+    <ProgressBar
+        android:id="@id/progress"
+        android:layout_width="30dp"
+        android:layout_height="30dp"
+        style="?attr/progressBarStyleLarge" />
+
+    <Space
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="10" />
+
+</LinearLayout>
diff --git a/core/res/res/layout/transient_notification.xml b/core/res/res/layout/transient_notification.xml
index daa9faf..db586ec 100644
--- a/core/res/res/layout/transient_notification.xml
+++ b/core/res/res/layout/transient_notification.xml
@@ -29,11 +29,11 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_weight="1"
+        android:layout_marginHorizontal="24dp"
+        android:layout_marginVertical="15dp"
         android:layout_gravity="center_horizontal"
         android:textAppearance="@style/TextAppearance.Toast"
-        android:textColor="@color/bright_foreground_dark"
-        android:shadowColor="#BB000000"
-        android:shadowRadius="2.75"
+        android:textColor="@color/primary_text_default_material_light"
         />
 
 </LinearLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index cbc9a05..eda2910 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Soek vir diens"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-oproepe"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra jou diensverskaffer eers om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan."</item>
+    <item msgid="3910386316304772394">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra eers jou diensverskaffer om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan. (Foutkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Registreer by jou diensverskaffer"</item>
+    <item msgid="7472393097168811593">"Registreer by jou diensverskaffer (foutkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Stembystand"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Sluit nou"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Inhoud versteek"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Inhoud word versteek volgens beleid"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Nuwe kennisgewing"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuele sleutelbord"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fisieke sleutelbord"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Sekuriteit"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Opletberigte"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Kleinhandeldemonstrasie"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-verbinding"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Programme wat op die agtergrond loop"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> loop tans op die agtergrond"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> programme loop tans op die agtergrond"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Programme wat batterykrag gebruik"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> gebruik tans batterykrag"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> programme gebruik tans batterykrag"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tik vir besonderhede oor battery- en datagebruik"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Veiligmodus"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Oop Wi-Fi-netwerke beskikbaar</item>
       <item quantity="one">Oop Wi-Fi-netwerk beskikbaar</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Koppel aan oop Wi-Fi-netwerk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Koppel tans aan oop Wi‑Fi-netwerk"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Aan Wi-Fi-netwerk gekoppel"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kon nie aan Wi-Fi-netwerk koppel nie"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerke te sien"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koppel"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle netwerke"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Meld aan by Wi-Fi-netwerk"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Meld by netwerk aan"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB vir MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Gekoppel aan \'n USB-toebehoorsel"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tik vir meer opsies."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analoë oudiobykomstigheid bespeur"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Die aangehegde toestel is nie met hierdie foon versoenbaar nie. Tik om meer te wete te kom."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ontfouter gekoppel"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tik om USB-ontfouting te deaktiveer."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Kies om USB-ontfouting te deaktiveer."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Gekoppel aan <xliff:g id="SESSION">%s</xliff:g>. Tik om die netwerk te bestuur."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Altydaan-VPN koppel tans..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Altydaan-VPN gekoppel"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Altydaan-VPN is ontkoppel"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Ontkoppel van altyd-aan-VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Altydaan-VPN-fout"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Tik om op te stel"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Verander netwerk- of VPN-instellings"</string>
     <string name="upload_file" msgid="2897957172366730416">"Kies lêer"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Geen lêer gekies nie"</string>
     <string name="reset" msgid="2448168080964209908">"Stel terug"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tik om motormodus te verlaat."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Verbinding of Wi-Fi-warmkol aktief"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tik om op te stel."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Verbinding is gedeaktiveer"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontak jou administrateur vir besonderhede"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Terug"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Volgende"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Slaan oor"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Ontspeld"</string>
     <string name="app_info" msgid="6856026610594615344">"Programinligting"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Stel toestel terug?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Tik om toestel terug te stel"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Begin tans demonstrasie …"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Stel toestel tans terug …"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Stel toestel terug?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Jy sal enige veranderinge verloor en die demonstrasie sal oor <xliff:g id="TIMEOUT">%1$s</xliff:g> sekondes weer begin …"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Kanselleer"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Stel nou terug"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Het <xliff:g id="LABEL">%1$s</xliff:g> gedeaktiveer"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konferensie-oproep"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Nutswenk"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Ontruim kusgebiede en riviergebiede dadelik en gaan na \'n veiliger plek, soos \'n hoogliggende omgewing."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Bly kalm en soek skuiling naby."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Noodboodskappetoets"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Antwoord"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM word nie toegelaat nie"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM is nie opgestel nie"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 0f2652b..14fb6bb 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"አገልግሎት ፍለጋ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"የWi-Fi ጥሪ ማድረጊያ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ መጠየቅ አለብዎት። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ።"</item>
+    <item msgid="3910386316304772394">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ መጠየቅ አለብዎት። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ። (የስህተት ኮድ፦ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"የአገልግሎት አቅራቢዎ ጋር ይመዝገቡ"</item>
+    <item msgid="7472393097168811593">"ከእርስዎ አገልግሎት አቅራቢ ጋር ይመዝገቡ (ስህተት ኮድ፦ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"የድምጽ እርዳታ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"አሁን ቆልፍ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"ይዘቶች ተደብቀዋል"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ይዘቶች በመመሪያ ተደብቀዋል"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"አዲስ ማሳወቂያ"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ምናባዊ የቁልፍ ሰሌዳ"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"አካላዊ ቁልፍ ሰሌዳ"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"ደህንነት"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ማንቂያዎች"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"የችርቻሮ ማሳያ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"የዩኤስቢ ግንኙነት"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"በጀርባ ውስጥ የሚያሄዱ መተግበሪያዎች"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> በጀርባ ውስጥ እያሄደ ነው"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> መተግበሪያዎች በጀርባ ውስጥ እያሄዱ ነው"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ባትሪ በመፍጀት ላይ ያሉ መተግበሪያዎች"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ባትሪ እየተጠቀመ ነው"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> መተግበሪያዎች ባትሪ እየተጠቀሙ ነው"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"በባትሪ እና ውሂብ አጠቃቀም ላይ ዝርዝሮችን ለማግኘት መታ ያድርጉ"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>፣ <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"የሚያስተማምን ሁነታ"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="one">የሚገኙ የWi-Fi አውታረ መረቦችን ክፈት</item>
       <item quantity="other">የሚገኙ የWi-Fi አውታረ መረቦችን ክፈት</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"ከክፍት የWi‑Fi አውታረ መረብ ጋር ያገናኙ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ከክፍት የWi‑Fi አውታረ መረብ ጋር በመገናኘት ላይ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"ከWi‑Fi አውታረ መረብ ጋር ተገናኝቷል"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ከWi‑Fi አውታረ መረብ ጋር መገናኘት አልተቻለም"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ሁሉንም አውታረ መረቦችን ለማየት መታ ያድርጉ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"አገናኝ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ሁሉም አውታረ መረቦች"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ወደ Wi-Fi አውታረ መረብ በመለያ ግባ"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ወደ አውታረ መረብ በመለያ ይግቡ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"ዩኤስቢ ለMIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"ለUSB ተቀጥላ ተያይዟል"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ለተጨማሪ አማራጮች መታ ያድርጉ።"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"የአናሎግ ኦዲዮ ረዳት እንዳለ ተደርሶበታል"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"ዓባሪ የተያያዘው መሣሪያ ከዚህ ስልክ ጋር ተኳዃኝ አይደለም። የበለጠ ለመረዳት መታ ያድርጉ።"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB አድስ ተያይዟል"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"የዩኤስቢ ማረሚያን ለማሰናከል መታ ያድርጉ።"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ማረሚያ ላለማንቃት ምረጥ።"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"ለ<xliff:g id="SESSION">%s</xliff:g> የተገናኘ። አውታረመረቡን ለማደራጀት ሁለቴ ንካ።"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"ሁልጊዜ የበራ VPN በመገናኘት ላይ…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"ሁልጊዜ የበራ VPN ተገናኝቷል"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"ሁልጊዜ የበራ የVPN ግንኙነት ተቋርጧል"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"ሁልጊዜ ከበራ ቪፒኤን ጋር ግንኙነት ተቋርጧል"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"ሁልጊዜ የበራ VPN ስህተት"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"ለማዋቀር መታ ያድርጉ"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"የአውታረ መረብ ወይም የቪፒኤን ቅንብሮችን ይቀይሩ"</string>
     <string name="upload_file" msgid="2897957172366730416">"ፋይል ምረጥ"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"ምንም ፋይል አልተመረጠም"</string>
     <string name="reset" msgid="2448168080964209908">"ዳግም አስጀምር"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"ከመኪና ሁነታ ለመውጣት መታ ያድርጉ።"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"መሰካት ወይም ገባሪ ድረስ ነጥብ"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"ለማዋቀር መታ ያድርጉ።"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"እንደ ሞደም መሰካት ተሰናክሏል"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ለዝርዝሮች የእርስዎን አስተዳዳሪ ያነጋግሩ"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ተመለስ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ቀጥሎ"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ዝለል"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"ንቀል"</string>
     <string name="app_info" msgid="6856026610594615344">"የመተግበሪያ መረጃ"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"መሣሪያ ዳግም ይጀመር?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"መሣሪያን ዳግም ለማስጀመር መታ ያድርጉ"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ማሳያን በማስጀመር ላይ…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"መሣሪያን ዳግም በማስጀመር ላይ…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"መሣሪያ ዳግም ይጀመር?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"ማንኛቸውም ለውጦች ይጠፋሉ፣ እና ማሳያው በ<xliff:g id="TIMEOUT">%1$s</xliff:g> ሰከንዶች ውስጥ እንደገና ይጀምራል…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"ይቅር"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"አሁን ዳግም አስጀምር"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> ተሰናክሏል"</string>
     <string name="conference_call" msgid="3751093130790472426">"የስብሰባ ጥሪ"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"የመሣሪያ ጥቆማ"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ወዲያውኑ ከባህር ዳርቻ አካባቢዎች እና የወንዝ ዳርቻ አካባቢዎች ይውጡና እንደ ከፍ ያለ መሬት ያሉ ከአደጋ የተሻለ ደህንነት ወዳቸው ቦታዎች ይሂዱ።"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ረጋ ይበሉና በአቅራቢያ ያለ መጠለያ ይፈልጉ።"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"የአስቸኳይ አደጋ መልእክቶች ሙከራ"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"ምላሽ ስጥ"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"ሲም አይፈቀድም"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"ሲም አልቀረበም"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index f3f59d3..45e604b 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -135,10 +135,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"البحث عن خدمة"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"‏الاتصال عبر Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"‏لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذا الجهاز، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات."</item>
+    <item msgid="3910386316304772394">"‏لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذه الخدمة، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات. (رمز الخطأ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"التسجيل لدى مشغّل شبكة الجوّال"</item>
+    <item msgid="7472393097168811593">"التسجيل لدى مشغِّل شبكة الجوّال (رمز الخطأ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -155,7 +155,7 @@
     <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: لم تتم إعادة التوجيه"</string>
     <string name="fcComplete" msgid="3118848230966886575">"اكتمل كود الميزة."</string>
     <string name="fcError" msgid="3327560126588500777">"حدثت مشكلة بالاتصال أو أن كود الميزة غير صحيح."</string>
-    <string name="httpErrorOk" msgid="1191919378083472204">"موافق"</string>
+    <string name="httpErrorOk" msgid="1191919378083472204">"حسنًا"</string>
     <string name="httpError" msgid="7956392511146698522">"حدث خطأ في الشبكة."</string>
     <string name="httpErrorLookup" msgid="4711687456111963163">"‏تعذر العثور على عنوان URL."</string>
     <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"نظام مصادقة الموقع غير معتمد."</string>
@@ -258,8 +258,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"المساعد الصوتي"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"قفل الآن"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"المحتويات مخفية"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"تم إخفاء المحتويات بواسطة السياسة"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"إشعار جديد"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"لوحة المفاتيح الافتراضية"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"لوحة المفاتيح الفعلية"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"الأمان"</string>
@@ -275,9 +274,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"التنبيهات"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"عرض توضيحي لبائع التجزئة"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"‏اتصال USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"التطبيقات التي تعمل في الخلفية"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"جارٍ تشغيل <xliff:g id="APP_NAME">%1$s</xliff:g> في الخلفية"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"جارٍ تشغيل <xliff:g id="NUMBER">%1$d</xliff:g> تطبيق في الخلفية"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"التطبيقات التي تستهلك البطارية"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"يستخدم تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> البطارية"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"تستخدم <xliff:g id="NUMBER">%1$d</xliff:g> من التطبيقات البطارية"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"انقر للحصول على تفاصيل حول البطارية واستخدام البيانات"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>، <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"الوضع الآمن"</string>
@@ -1036,7 +1035,7 @@
     <string name="VideoView_error_title" msgid="3534509135438353077">"مشكلة في الفيديو"</string>
     <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"عذرًا، هذا الفيديو غير صالح للبث على هذا الجهاز."</string>
     <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"لا يمكنك تشغيل هذا الفيديو."</string>
-    <string name="VideoView_error_button" msgid="2822238215100679592">"موافق"</string>
+    <string name="VideoView_error_button" msgid="2822238215100679592">"حسنًا"</string>
     <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>، <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="noon" msgid="7245353528818587908">"الظهر"</string>
     <string name="Noon" msgid="3342127745230013127">"الظهر"</string>
@@ -1070,9 +1069,9 @@
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"ليست هناك سعة تخزينية كافية للنظام. تأكد من أنه لديك مساحة خالية تبلغ ٢٥٠ ميغابايت وأعد التشغيل."</string>
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> قيد التشغيل"</string>
     <string name="app_running_notification_text" msgid="1197581823314971177">"انقر للحصول على مزيد من المعلومات أو لإيقاف التطبيق."</string>
-    <string name="ok" msgid="5970060430562524910">"موافق"</string>
+    <string name="ok" msgid="5970060430562524910">"حسنًا"</string>
     <string name="cancel" msgid="6442560571259935130">"إلغاء"</string>
-    <string name="yes" msgid="5362982303337969312">"موافق"</string>
+    <string name="yes" msgid="5362982303337969312">"حسنًا"</string>
     <string name="no" msgid="5141531044935541497">"إلغاء"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"تنبيه"</string>
     <string name="loading" msgid="7933681260296021180">"جارٍ التحميل…"</string>
@@ -1194,6 +1193,13 @@
       <item quantity="other">‏تتوفر شبكات Wi-Fi مفتوحة</item>
       <item quantity="one">‏تتوفر شبكة Wi-Fi واحدة مفتوحة</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"‏الاتصال بشبكة Wi-Fi المفتوحة"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"‏جارٍ الاتصال بشبكة Wi-Fi المفتوحة"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"‏تم الاتصال بشبكة Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"‏تعذَّر الاتصال بشبكة Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"انقر للاطلاع على جميع الشبكات"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"اتصال"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"جميع الشبكات"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"‏تسجيل الدخول إلى شبكة Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"تسجيل الدخول إلى الشبكة"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1259,13 +1265,13 @@
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"انقر لإعداده."</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"تعيين الوقت"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"تعيين التاريخ"</string>
-    <string name="date_time_set" msgid="5777075614321087758">"تعيين"</string>
+    <string name="date_time_set" msgid="5777075614321087758">"ضبط"</string>
     <string name="date_time_done" msgid="2507683751759308828">"تم"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"جديد: "</font></string>
     <string name="perms_description_app" msgid="5139836143293299417">"يقدمه <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="no_permissions" msgid="7283357728219338112">"لا أذونات مطلوبة"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"قد يكلفك هذا مالاً."</string>
-    <string name="dlg_ok" msgid="7376953167039865701">"موافق"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"حسنًا"</string>
     <string name="usb_charging_notification_title" msgid="6895185153353640787">"‏يتم استخدام الاتصال عبر USB لشحن هذا الجهاز"</string>
     <string name="usb_supplying_notification_title" msgid="5310642257296510271">"‏يتم استخدام الاتصال عبر USB لإمداد الجهاز المتصل بالطاقة"</string>
     <string name="usb_mtp_notification_title" msgid="8396264943589760855">"‏USB لنقل الملفات"</string>
@@ -1273,6 +1279,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"‏USB لـ MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"‏الاتصال بجهاز USB ملحق"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"انقر للحصول على المزيد من الخيارات."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"تم اكتشاف ملحق صوتي تناظري"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"الجهاز الذي تم توصيله بالهاتف غير متوافق معه. انقر للحصول على المزيد من المعلومات."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏تم توصيل تصحيح أخطاء USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"‏انقر لتعطيل تصحيح أخطاء USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‏اختيار تعطيل تصحيح أخطاء USB."</string>
@@ -1378,9 +1386,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"تم الاتصال بـ <xliff:g id="SESSION">%s</xliff:g>. انقر لإدارة الشبكة."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"‏جارٍ الاتصال بشبكة افتراضية خاصة (VPN) دائمة التشغيل..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"‏تم الاتصال بشبكة افتراضية خاصة (VPN) دائمة التشغيل"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"‏تم فصل الشبكة الافتراضية الخاصة (VPN) دائمة التشغيل"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"‏تم قطع الاتصال بالشبكة الافتراضية الخاصة (VPN) التي يتم تشغيلها دائمًا"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"‏خطأ بشبكة افتراضية خاصة (VPN) دائمة التشغيل"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"انقر للإعداد."</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"‏تغيير إعدادات الشبكة أو الشبكة الافتراضية الخاصة (VPN)"</string>
     <string name="upload_file" msgid="2897957172366730416">"اختيار ملف"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"لم يتم اختيار أي ملف"</string>
     <string name="reset" msgid="2448168080964209908">"إعادة تعيين"</string>
@@ -1389,8 +1397,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"انقر للخروج من وضع السيارة."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"النطاق أو نقطة الاتصال نشطة"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"انقر للإعداد."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"تم تعطيل التوصيل"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"اتصل بالمشرف للحصول على التفاصيل"</string>
     <string name="back_button_label" msgid="2300470004503343439">"رجوع"</string>
     <string name="next_button_label" msgid="1080555104677992408">"التالي"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"تخطي"</string>
@@ -1477,7 +1483,7 @@
     <string name="data_usage_limit_body" msgid="291731708279614081">"توقفت البيانات مؤقتًا لاستكمال الدورة"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"‏تم تجاوز حد بيانات شبكات 2G-3G"</string>
     <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"‏تم تجاوز حد بيانات 4G"</string>
-    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"تم تجاوز حد بيانات الجوال"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"تم تجاوز حد بيانات الجوّال"</string>
     <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"‏تم تجاوز حد بيانات شبكة Wi-Fi"</string>
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> فوق الحد المعين."</string>
     <string name="data_usage_restricted_title" msgid="5965157361036321914">"تم تقييد بيانات الخلفية"</string>
@@ -1855,14 +1861,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"إزالة تثبيت"</string>
     <string name="app_info" msgid="6856026610594615344">"معلومات عن التطبيق"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"هل تريد إعادة تعيين الجهاز؟"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"انقر لإعادة تعيين الجهاز"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"جارٍ بدء العرض التوضيحي…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"جارٍ إعادة تعيين الجهاز…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"هل تريد إعادة تعيين الجهاز؟"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"ستفقد أي تغييرات وسيبدأ العرض التوضيحي مرة أخرى خلال <xliff:g id="TIMEOUT">%1$s</xliff:g> من الثواني…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"إلغاء"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"إعادة التعيين الآن"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"تم تعطيل <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"مكالمة جماعية"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"تلميح"</string>
@@ -1910,6 +1910,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"يُرجى النزوح في الحال من المناطق الساحلية وضفاف النهر إلى مكان أكثر أمانًا مثل الأراضي المرتفعة."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"يُرجى الثبات والبحث عن ملاذ بالجوار."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"اختبار رسائل الطوارئ"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"الرد"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"‏غير مسموح باستخدام SIM"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"‏لم يتم تقديم SIM"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 75fe7f4..97bcd6d 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Xidmət axtarılır"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi zəngi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi üzərindən zəng etmək və mesaj göndərmək üçün ilk öncə operatordan bu xidməti ayarlamağı tələb edin. Sonra Ayarlardan Wi-Fi çağrısını aktivləşdirin."</item>
+    <item msgid="3910386316304772394">"Zəng etmək və Wi-Fi üzərindən mesaj göndərmək üçün əvvəlcə operatordan bu cihazı quraşdırmağı tələb edin. Sonra Ayarlardan Wi-Fi zəngini deaktiv edin. (Xəta kodu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Operatorla qeydiyyatdan keçin"</item>
+    <item msgid="7472393097168811593">"Operator ilə qeydiyyatdan keçin (Xəta kodu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Səs Yardımçısı"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"İndi kilidləyin"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Məzmun gizlidir"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Məzmun siyasət tərəfindən gizlədilib"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Yeni bildiriş"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtual klaviatura"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fiziki klaviatura"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Təhlükəsizlik"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Siqnallar"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Pərakəndə demo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB əlaqə"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Arxa fonda işləyən tətbiqlər"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> arxa fonda işləyir"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> tətbiq arxa fonda işləyir"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Batareyadan istifadə edən tətbiqlər"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> batareyadan istifadə edir"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> tətbiq batareyadan istifadə edir"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Batareya və data istifadəsi haqqında ətraflı məlumat üçün klikləyin"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Təhlükəsiz rejim"</string>
@@ -275,7 +274,7 @@
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktlar"</string>
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"kontaktlarınıza daxil olun"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Yer"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"bu cihazın məkanını əldə edin"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"cihazın yerini bilmək"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Təqvim"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"təqvimə daxil olun"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Əlçatan açıq Wi-Fi şəbəkələri</item>
       <item quantity="one">Əlçatan açıq Wi-Fi şəbəkəsi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Açıq Wi‑Fi şəbəkəsinə qoşulun"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Açıq Wi‑Fi şəbəkəsinə qoşulur"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi şəbəkəsinə qoşuldu"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi şəbəkəsinə qoşulmaq mümkün deyil"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Bütün şəbəkələri görmək üçün klikləyin"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Qoşulun"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Bütün Şəbəkələr"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi şəbəkəsinə daxil ol"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Şəbəkəyə daxil olun"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI üçün USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB aksesuara qoşuldu"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Əlavə seçimlər üçün tıklayın."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analoq audio aksesuar aşkarlandı"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Əlavə edilən cihaz bu telefonla uyğun deyil. Ətraflı məlumat üçün klikləyin."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB sazlama qoşuludur"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB debaqı deaktivasiya etmək üçün tıklayın."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USb debaqı deaktivasiya etməyi seçin."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> sessiyaya qoşulun. Şəbəkəni idarə etmək üçün tıklayın."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Həmişə aktiv VPN bağlanır..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPN bağlantısı həmişə aktiv"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Həmişə aktiv VPN bağlantısı kəsildi"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Həmişə aktiv VPN bağlantısı kəsildi"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Həmişə aktiv VPN xətası"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Quraşdırmaq üçün tıklayın"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Şəbəkə və ya VPN ayarlarını dəyişin"</string>
     <string name="upload_file" msgid="2897957172366730416">"Fayl seçin"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Heç bir fayl seçilməyib"</string>
     <string name="reset" msgid="2448168080964209908">"Sıfırlayın"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Avtomobil rejimindən çıxmaq üçün tıklayın."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tezerinq və ya hotspot aktivdir"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Quraşdırmaq üçün tıklayın."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Birləşmə deaktivdir"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Məlumat üçün adminlə əlaqə saxlayın"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Geri"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Növbəti"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Keç"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Çıxarın"</string>
     <string name="app_info" msgid="6856026610594615344">"Tətbiq məlumatı"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Cihaz sıfırlansın?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Cihazı sıfırlamaq üçün tıklayın"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Demo başlayır…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Cihaz sıfırlanır…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Cihaz sıfırlansın?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Hər hansı dəyişikliyi itirəcəksiniz və demo <xliff:g id="TIMEOUT">%1$s</xliff:g> saniyəyə yenidən başlayacaq…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Ləğv edin"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"İndi sıfırlayın"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> deaktiv edildi"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konfrans Zəngi"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Tooltip"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Dərhal sahil bölgələrindən və çay kənarı ərazilərdən daha təhlükəsiz yüksək yerlərə evakuasiya edin."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Sakit qalın və yaxınlıqda sığınacaq axtarın."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Təcili mesaj testi"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Cavablayın"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-ə icazə verilmir"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM təmin edilməyib"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 8828633..6203907 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -90,17 +90,23 @@
     <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ID pozivaoca podrazumevano nije ograničen. Sledeći poziv: Nije ograničen."</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Usluga nije dobavljena."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Ne možete da promenite podešavanje ID-a korisnika."</string>
-    <string name="RestrictedOnData" msgid="8653794784690065540">"Usluga za podatke je blokirana."</string>
-    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Usluga za hitne slučajeve je blokirana."</string>
-    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Glasovna usluga je blokirana."</string>
-    <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Sve glasovne usluge su blokirane."</string>
-    <string name="RestrictedOnSms" msgid="8314352327461638897">"SMS usluga je blokirana."</string>
-    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Glasovna usluga/usluga prenosa podataka su blokirane."</string>
-    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Glasovna usluga i SMS usluga su blokirane."</string>
-    <string name="RestrictedOnAll" msgid="5643028264466092821">"Sve glasovne i SMS usluge, kao i usluge prenosa podataka su blokirane."</string>
+    <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Nema usluge prenosa podataka"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Nema usluge za hitne pozive"</string>
+    <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Nema glasovne usluge"</string>
+    <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nema glasovne usluge/usluge za hitne pozive"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Mobilni operater je privremeno suspendovao uslugu prenosa podataka na ovoj lokaciji"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Mobilni operater je privremeno suspendovao hitne pozive na ovoj lokaciji"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Mobilni operater je privremeno suspendovao glasovne pozive na ovoj lokaciji"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Mobilni operater je privremeno suspendovao glasovne i hitne pozive na ovoj lokaciji"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Povezivanje sa mrežom nije uspelo"</string>
-    <!-- no translation found for NetworkPreferenceSwitchSummary (4164230263214915351) -->
-    <skip />
+    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Da biste poboljšali prijem, probajte da promenite izabrani tip u odeljku Sistem &gt; Mreža i internet &gt; Mobilne mreže &gt; Željeni tip mreže."</string>
+    <string name="notification_channel_network_alert" msgid="4427736684338074967">"Obaveštenja"</string>
+    <string name="notification_channel_call_forward" msgid="2419697808481833249">"Preusmeravanje poziva"</string>
+    <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Režim za hitan povratni poziv"</string>
+    <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Obaveštenja za mobilne podatke"</string>
+    <string name="notification_channel_sms" msgid="3441746047346135073">"SMS-ovi"</string>
+    <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Poruke govorne pošte"</string>
+    <string name="notification_channel_wfc" msgid="2130802501654254801">"Pozivanje preko Wi-Fi mreže"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Korisnik zahteva POTPUN režim TTY"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Korisnik zahteva PRENOS ZVUKA za režim TTY"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Korisnik zahteva PRENOS GLASA za režim TTY"</string>
@@ -140,8 +146,7 @@
   </string-array>
     <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>
-    <!-- no translation found for wfc_mode_cellular_preferred_summary (1988279625335345908) -->
-    <skip />
+    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Želim mobilne podatke"</string>
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Samo Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije prosleđeno"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -180,18 +185,16 @@
       <item quantity="other">Instalirani su autoriteti za izdavanje sertifikata</item>
     </plurals>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Od strane nepoznate treće strane"</string>
-    <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Od strane administratora profila za posao"</string>
+    <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"Od strane administratora profila za Work"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Od strane <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="work_profile_deleted" msgid="5005572078641980632">"Poslovni profil je izbrisan"</string>
-    <string name="work_profile_deleted_description" msgid="6305147513054341102">"Poslovni profil je izbrisan jer nedostaje administratorska aplikacija."</string>
-    <string name="work_profile_deleted_details" msgid="226615743462361248">"Administratorska aplikacija poslovnog profila nedostaje ili je oštećena. Zbog toga su vaš poslovni profil i povezani podaci izbrisani. Obratite se administratoru za pomoć."</string>
-    <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Profil za Work više nije dostupan na ovom uređaju."</string>
-    <!-- no translation found for network_logging_notification_title (6399790108123704477) -->
-    <skip />
-    <!-- no translation found for network_logging_notification_text (7930089249949354026) -->
-    <skip />
+    <string name="work_profile_deleted_description" msgid="1100529432509639864">"Profil za Work je izbrisan jer nedostaje aplikacija za administratore"</string>
+    <string name="work_profile_deleted_details" msgid="6307630639269092360">"Aplikacija za administratore na profilu za Work nedostaje ili je oštećena. Zbog toga su profil za Work i povezani podaci izbrisani. Obratite se administratoru za pomoć."</string>
+    <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Profil za Work više nije dostupan na ovom uređaju"</string>
+    <string name="network_logging_notification_title" msgid="6399790108123704477">"Uređajem se upravlja"</string>
+    <string name="network_logging_notification_text" msgid="7930089249949354026">"Organizacija upravlja ovim uređajem i može da nadgleda mrežni saobraćaj. Dodirnite za detalje."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Uređaj će biti obrisan"</string>
-    <string name="factory_reset_message" msgid="4905025204141900666">"Administratorskoj aplikaciji nedostaju neke komponente ili je oštećena i ne može da se koristi. Uređaj će sada biti obrisan. Obratite se administratoru za pomoć."</string>
+    <string name="factory_reset_message" msgid="7972496262232832457">"Ne možete da koristite ovu aplikaciju za administratore. Uređaj će sada biti obrisan.\n\nAko imate pitanja, kontaktirajte administratora organizacije."</string>
     <string name="me" msgid="6545696007631404292">"Ja"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opcije za tablet"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"Opcije za TV"</string>
@@ -260,11 +263,17 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ažuriranja"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status mreže"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Obaveštenja u vezi sa mrežom"</string>
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Mreža je dostupna"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Status VPN-a"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administriranje uređaja"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Obaveštenja"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Režim demonstracije za maloprodajne objekte"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
+    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacije pokrenute u pozadini"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> radi u pozadini"</string>
+    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Aplikacije (<xliff:g id="NUMBER">%1$d</xliff:g>) su pokrenute u pozadini"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
+    <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Bezbedni režim"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android sistem"</string>
     <string name="user_owner_label" msgid="1119010402169916617">"Pređi na Lični profil"</string>
@@ -287,15 +296,13 @@
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"upućuje telefonske pozive i upravlja njima"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"Senzori za telo"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"pristupa podacima senzora o vitalnim funkcijama"</string>
-    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Preuzima sadržaj prozora"</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"da preuzima sadržaj prozora"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Proverava sadržaj prozora sa kojim ostvarujete interakciju."</string>
-    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Uključi Istraživanja dodirom"</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"da uključi Istraživanja dodirom"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"Stavke koje dodirnete će biti izgovorene naglas, a možete da se krećete po ekranu pokretima."</string>
-    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Uključi poboljšanu pristupačnost veba"</string>
-    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Mogu da se instaliraju skripte da bi sadržaj aplikacija bio pristupačniji."</string>
-    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Prati tekst koji unosite"</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"da prati tekst koji unosite"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Obuhvata lične podatke kao što su brojevi kreditnih kartica i lozinke."</string>
-    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Upravljaj uvećanjem prikaza"</string>
+    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"da upravlja uvećanjem prikaza"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Upravlja nivoom zumiranja prikaza i određivanjem položaja."</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Obavljanje pokreta"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Može da dodiruje, lista, skuplja prikaz i obavlja druge pokrete."</string>
@@ -413,8 +420,8 @@
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Dozvoljava aplikaciji da pristupa funkcijama telefona na uređaju. Ova dozvola omogućava aplikaciji da utvrdi broj telefona i ID-ove uređaja, zatim da li je poziv aktivan, kao i broj daljinskog uređaja sa kojim je uspostavljen poziv."</string>
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"preusmeravanje poziva preko sistema"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Dozvoljava aplikaciji da preusmerava pozive preko sistema da bi poboljšala doživljaj pozivanja."</string>
-    <string name="permlab_readPhoneNumber" msgid="6421295519255154171">"čitanje broja telefona"</string>
-    <string name="permdesc_readPhoneNumber" msgid="9135856402838173711">"Dozvoljava aplikaciji da pristupa broju telefona na uređaju."</string>
+    <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"čitanje brojeva telefona"</string>
+    <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"Dozvoljava aplikaciji da pristupa brojevima telefona na uređaju."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"sprečavanje prelaska tableta u stanje spavanja"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"sprečavanje TV-a da pređe u stanje spavanja"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"sprečavanje prelaska telefona u stanje spavanja"</string>
@@ -487,6 +494,7 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Vremensko ograničenje za otisak prsta je isteklo. Probajte ponovo."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Radnja sa otiskom prsta je otkazana."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Previše pokušaja. Probajte ponovo kasnije."</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Previše pokušaja. Senzor za otisak prsta je onemogućen."</string>
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Probajte ponovo."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
@@ -554,7 +562,7 @@
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Dozvoljava aplikaciji da čita i upisuje konfiguraciju podešavanja Ne uznemiravaj."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Podešavanje pravila za lozinku"</string>
     <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontroliše dužinu i znakove dozvoljene u lozinkama i PIN-ovima za zaključavanje ekrana."</string>
-    <string name="policylab_watchLogin" msgid="914130646942199503">"Nadgledanje pokušaja otključavanja ekrana"</string>
+    <string name="policylab_watchLogin" msgid="5091404125971980158">"Nadgledajte pokušaje otključavanja ekrana"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Prati broj netačno unetih lozinki prilikom otključavanja ekrana i zaključava tablet ili briše podatke sa tableta ako je netačna lozinka uneta previše puta."</string>
     <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Nadgleda broj netačnih lozinki koje unesete pri otključavanju ekrana i zaključava TV ili briše sve podatke sa njega ako se unese previše netačnih lozinki."</string>
     <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Prati broj netačno unetih lozinki pri otključavanju ekrana i zaključava telefon ili briše sve podatke sa telefona ako je netačna lozinka uneta previše puta."</string>
@@ -841,7 +849,7 @@
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"dodavanje govorne pošte"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Dozvoljava aplikaciji da dodaje poruke u prijemno sanduče govorne pošte."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"izmena dozvola za geografske lokacije Pregledača"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Dozvoljava aplikaciji da izmeni dozvole Pregledača za utvrđivanje geografske lokacije. Zlonamerne aplikacije to mogu da zloupotrebe i iskoriste za slanje informacija o lokaciji nasumičnim veb sajtovima."</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Dozvoljava aplikaciji da izmeni dozvole Pregledača za utvrđivanje geografske lokacije. Zlonamerne aplikacije to mogu da zloupotrebe i iskoriste za slanje informacija o lokaciji nasumičnim veb-sajtovima."</string>
     <string name="save_password_message" msgid="767344687139195790">"Želite li da pregledač zapamti ovu lozinku?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Ne sada"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Zapamti"</string>
@@ -990,8 +998,7 @@
     <string name="selectTextMode" msgid="1018691815143165326">"Izaberi tekst"</string>
     <string name="undo" msgid="7905788502491742328">"Opozovi"</string>
     <string name="redo" msgid="7759464876566803888">"Ponovi"</string>
-    <!-- no translation found for autofill (3035779615680565188) -->
-    <skip />
+    <string name="autofill" msgid="3035779615680565188">"Automatsko popunjavanje"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Izbor teksta"</string>
     <string name="addToDictionary" msgid="4352161534510057874">"Dodaj u rečnik"</string>
     <string name="deleteText" msgid="6979668428458199034">"Izbriši"</string>
@@ -999,8 +1006,8 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Radnje u vezi sa tekstom"</string>
     <string name="email" msgid="4560673117055050403">"Pošalji imejl"</string>
     <string name="dial" msgid="4204975095406423102">"Pozovi"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Pregledaj"</string>
+    <string name="map" msgid="6068210738233985748">"Mape"</string>
+    <string name="browse" msgid="6993590095938149861">"Pregledač"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Memorijski prostor je na izmaku"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke sistemske funkcije možda ne funkcionišu"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nema dovoljno memorijskog prostora za sistem. Uverite se da imate 250 MB slobodnog prostora i ponovo pokrenite."</string>
@@ -1043,7 +1050,7 @@
     <string name="noApplications" msgid="2991814273936504689">"Nijedna aplikacija ne može da obavlja ovu radnju."</string>
     <string name="aerr_application" msgid="250320989337856518">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> je zaustavljena"</string>
     <string name="aerr_process" msgid="6201597323218674729">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> je zaustavljen"</string>
-    <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> se stalno zaustavlja"</string>
+    <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> se stalno zaustavlja(ju)"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> se stalno zaustavlja"</string>
     <string name="aerr_restart" msgid="7581308074153624475">"Ponovo otvori aplikaciju"</string>
     <string name="aerr_report" msgid="5371800241488400617">"Pošaljite povratne informacije"</string>
@@ -1114,6 +1121,16 @@
     <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Zvuci alarma"</string>
     <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Zvuci obaveštenja"</string>
     <string name="ringtone_unknown" msgid="3914515995813061520">"Nepoznato"</string>
+    <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
+      <item quantity="one">Wi-Fi mreže su dostupne</item>
+      <item quantity="few">Wi-Fi mreže su dostupne</item>
+      <item quantity="other">Wi-Fi mreže su dostupne</item>
+    </plurals>
+    <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
+      <item quantity="one">Otvorene Wi-Fi mreže su dostupne</item>
+      <item quantity="few">Otvorene Wi-Fi mreže su dostupne</item>
+      <item quantity="other">Otvorene Wi-Fi mreže su dostupne</item>
+    </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavljivanje na Wi-Fi mrežu"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijavite se na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1123,7 +1140,13 @@
     <string name="network_switch_metered" msgid="4671730921726992671">"Prešli ste na tip mreže <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
     <string name="network_switch_metered_detail" msgid="5325661434777870353">"Uređaj koristi tip mreže <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kada tip mreže <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu. Možda će se naplaćivati troškovi."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"Prešli ste sa tipa mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na tip mreže <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <!-- no translation found for network_switch_type_name:0 (3979506840912951943) -->
+  <string-array name="network_switch_type_name">
+    <item msgid="3979506840912951943">"mobilni podaci"</item>
+    <item msgid="75483255295529161">"Wi-Fi"</item>
+    <item msgid="6862614801537202646">"Bluetooth"</item>
+    <item msgid="5447331121797802871">"Eternet"</item>
+    <item msgid="8257233890381651999">"VPN"</item>
+  </string-array>
     <string name="network_switch_type_name_unknown" msgid="4552612897806660656">"nepoznat tip mreže"</string>
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nije moguće povezati sa Wi-Fi mrežom"</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ima lošu internet vezu."</string>
@@ -1187,13 +1210,15 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB za MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Povezano sa USB dodatkom"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Dodirnite za još opcija."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Dodatna oprema za audio sadržaj nije podržana"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Dodirnite za više informacija"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka sa USB-a je uspostavljeno"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Dodirnite da biste onemogućili otklanjanje grešaka sa USB-a."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izaberite da biste onemogućili otklanjanja grešaka sa USB-a."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Izveštaj o grešci se generiše…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite li da podelite izveštaj o grešci?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deli se izveštaj o grešci…"</string>
-    <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"IT administrator je zatražio izveštaj o grešci radi lakšeg rešavanja problema u vezi sa ovim uređajem. Aplikacije i podaci mogu da se dele."</string>
+    <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"Administrator je zatražio izveštaj o grešci radi lakšeg rešavanja problema u vezi sa ovim uređajem. Aplikacije i podaci mogu da se dele."</string>
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DELI"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODBIJ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Promenite tastaturu"</string>
@@ -1203,8 +1228,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dodirnite da biste izabrali jezik i raspored"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Aplikacija <xliff:g id="NAME">%s</xliff:g> se prikazuje preko drugih aplikacija"</string>
-    <string name="alert_windows_notification_title" msgid="4532185840598192445">"Aplik. <xliff:g id="NAME">%s</xliff:g> se prikazuje preko drugih aplik."</string>
+    <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> se prikazuje preko drugih aplik."</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ako ne želite ovu funkciju za <xliff:g id="NAME">%s</xliff:g>, dodirnite da biste otvorili podešavanja i isključili je."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ISKLJUČI"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> se priprema"</string>
@@ -1223,7 +1250,7 @@
     <string name="ext_media_nomedia_notification_message" msgid="6471542972147056586">"Uređaj <xliff:g id="NAME">%s</xliff:g> je uklonjen; umetnite novi"</string>
     <string name="ext_media_unmounting_notification_title" msgid="640674168454809372">"<xliff:g id="NAME">%s</xliff:g> se još uvek izbacuje…"</string>
     <string name="ext_media_unmounting_notification_message" msgid="4182843895023357756">"Ne uklanjajte"</string>
-    <string name="ext_media_init_action" msgid="7952885510091978278">"Podesi"</string>
+    <string name="ext_media_init_action" msgid="7952885510091978278">"Aktiviraj"</string>
     <string name="ext_media_unmount_action" msgid="1121883233103278199">"Izbaci"</string>
     <string name="ext_media_browse_action" msgid="8322172381028546087">"Istraži"</string>
     <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> nedostaje"</string>
@@ -1296,7 +1323,7 @@
     <string name="vpn_lockdown_config" msgid="5099330695245008680">"Dodirnite da biste podesili"</string>
     <string name="upload_file" msgid="2897957172366730416">"Odaberi datoteku"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nije izabrana nijedna datoteka"</string>
-    <string name="reset" msgid="2448168080964209908">"Ponovo postavi"</string>
+    <string name="reset" msgid="2448168080964209908">"Resetuj"</string>
     <string name="submit" msgid="1602335572089911941">"Pošalji"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Režim rada u automobilu je omogućen"</string>
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Dodirnite da biste izašli iz režima rada u automobilu."</string>
@@ -1330,7 +1357,7 @@
     <string name="sync_really_delete" msgid="2572600103122596243">"Izbriši stavke"</string>
     <string name="sync_undo_deletes" msgid="2941317360600338602">"Opozovi brisanja"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"Ne radi ništa za sada"</string>
-    <string name="choose_account_label" msgid="5655203089746423927">"Izbor naloga"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"Izaberite nalog"</string>
     <string name="add_account_label" msgid="2935267344849993553">"Dodaj nalog"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Dodaj nalog"</string>
     <string name="number_picker_increment_button" msgid="2412072272832284313">"Povećavanje"</string>
@@ -1380,8 +1407,7 @@
     <string name="data_usage_warning_body" msgid="6660692274311972007">"Dodirnite za potrošnju i podešavanja."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Nema više 2G-3G podataka"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Nema više 4G podataka"</string>
-    <!-- no translation found for data_usage_mobile_limit_title (6561099244084267376) -->
-    <skip />
+    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Dostigli ste ograničenje podataka"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Nema više Wi-Fi podataka"</string>
     <string name="data_usage_limit_body" msgid="291731708279614081">"Potrošili ste podatke za ovaj mesec"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Prekoračen prenos 2G-3G podataka"</string>
@@ -1480,18 +1506,21 @@
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Ukloni"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Želite da pojačate zvuk iznad preporučenog nivoa?\n\nSlušanje glasne muzike duže vreme može da vam ošteti sluh."</string>
-    <string name="accessibility_shortcut_warning_dialog_title" msgid="5998592821749881862">"Prečica za pristupačnost je UKLJUČENA"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="2987297770937717543">"Uključite ili isključite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tako što ćete istovremeno zadržati oba dugmeta za jačinu zvuka 3 sekunde.\n\nMožete da promenite uslugu u odeljku Podešavanja &gt; Pristupačnost."</string>
-    <string name="disable_accessibility_shortcut" msgid="3683951963271793789">"Isključi prečicu"</string>
-    <string name="leave_accessibility_shortcut_on" msgid="8762106842437042969">"Ostavi uključeno"</string>
+    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Želite li da koristite prečicu za pristupačnost?"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Kada je prečica uključena, pritisnite oba dugmeta za jačinu zvuka da biste pokrenuli funkciju pristupačnosti.\n\n Aktuelna funkcija pristupačnosti:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Možete da promenite funkciju u odeljku Podešavanja &gt; Pristupačnost."</string>
+    <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Isključi prečicu"</string>
+    <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Koristi prečicu"</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_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>
     <string name="user_switched" msgid="3768006783166984410">"Aktuelni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Prebacivanje na <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="user_logging_out_message" msgid="8939524935808875155">"Odjavljuje se <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="2716755460376028154">"Vlasnik"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Greška"</string>
-    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Administrator nije dozvolio ovu promenu"</string>
+    <string name="error_message_change_not_allowed" msgid="1238035947357923497">"Administrator nije dozvolio ovu promenu"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nije pronađena nijedna aplikacija koja bi mogla da obavi ovu radnju"</string>
     <string name="revoke" msgid="5404479185228271586">"Opozovi"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1583,7 +1612,7 @@
     <string name="reason_service_unavailable" msgid="7824008732243903268">"Usluga štampanja nije omogućena"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"Usluga <xliff:g id="NAME">%s</xliff:g> je instalirana"</string>
     <string name="print_service_installed_message" msgid="5897362931070459152">"Dodirnite da biste omogućili"</string>
-    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Unesite PIN administratora"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"Unesite PIN administratora"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Unesite PIN"</string>
     <string name="restr_pin_incorrect" msgid="8571512003955077924">"Netačno"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuelni PIN"</string>
@@ -1612,17 +1641,17 @@
     <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> na poslu"</string>
     <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3. poslovni imejl <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="lock_to_app_toast" msgid="7693684144593484">"Da biste otkačili ovaj ekran, dodirnite i zadržite Nazad i Pregled."</string>
-    <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacija je zakačena: otkačinjanje nije dozvoljeno na ovom uređaju."</string>
+    <string name="lock_to_app_toast" msgid="6820571533009838261">"Da biste otkačili ovaj ekran, dodirnite i zadržite dugmad Nazad i Pregled"</string>
+    <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Ova aplikacija ne može da se otkači"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"Ekran je zakačen"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran je otkačen"</string>
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Traži PIN pre otkačinjanja"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Traži šablon za otključavanje pre otkačinjanja"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Traži lozinku pre otkačinjanja"</string>
-    <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalirao je vaš administrator"</string>
-    <string name="package_updated_device_owner" msgid="8856631322440187071">"Ažurirao je administrator"</string>
-    <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisao je vaš admiistrator"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"Da bi produžila vreme trajanja baterije, ušteda baterije smanjuje performanse uređaja i ograničava vibraciju, usluge lokacije i većinu pozadinskih podataka. Imejl, razmena poruka i druge aplikacije koje se oslanjaju na sinhronizaciju možda neće da se ažuriraju ako ih ne otvorite.\n\nUšteda baterije se automatski isključuje kada se uređaj puni."</string>
+    <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalirao je administrator"</string>
+    <string name="package_updated_device_owner" msgid="1847154566357862089">"Ažurirao je administrator"</string>
+    <string name="package_deleted_device_owner" msgid="2307122077550236438">"Izbrisao je administrator"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"Da bi produžila vreme trajanja baterije, ušteda baterije smanjuje performanse uređaja i ograničava vibraciju, usluge lokacije i većinu pozadinskih podataka. Imejl, razmena poruka i druge aplikacije koje se oslanjaju na sinhronizaciju neće se ažurirati dok ih ne otvorite.\n\nUšteda baterije se automatski isključuje kada se uređaj puni."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Da bi se smanjila potrošnja podataka, Ušteda podataka sprečava neke aplikacije da šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može da pristupa podacima, ali će to činiti ređe. Na primer, slike se neće prikazivati dok ih ne dodirnete."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Uključiti Uštedu podataka?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Uključi"</string>
@@ -1703,7 +1732,7 @@
       <item quantity="few">Izabrane su <xliff:g id="COUNT_1">%1$d</xliff:g> stavke</item>
       <item quantity="other">Izabrano je <xliff:g id="COUNT_1">%1$d</xliff:g> stavki</item>
     </plurals>
-    <string name="default_notification_channel_label" msgid="6950908610709016902">"Razno"</string>
+    <string name="default_notification_channel_label" msgid="5929663562028088222">"Nekategorizovano"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Vi podešavate važnost ovih obaveštenja."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ovo je važno zbog ljudi koji učestvuju."</string>
     <string name="user_creation_account_exists" msgid="1942606193570143289">"Želite li da dozvolite aplikaciji <xliff:g id="APP">%1$s</xliff:g> da napravi novog korisnika za <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
@@ -1715,8 +1744,8 @@
     <string name="language_picker_section_all" msgid="3097279199511617537">"Svi jezici"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"Svi regioni"</string>
     <string name="locale_search_menu" msgid="2560710726687249178">"Pretraži"</string>
-    <string name="work_mode_off_title" msgid="8954725060677558855">"Režim za Work je ISKLJUČEN"</string>
-    <string name="work_mode_off_message" msgid="3286169091278094476">"Dozvoljava profilu za Work da funkcioniše, uključujući aplikacije, sinhronizaciju u pozadini i srodne funkcije."</string>
+    <string name="work_mode_off_title" msgid="2615362773958585967">"Uključiti režim za Work?"</string>
+    <string name="work_mode_off_message" msgid="2961559609199223594">"Ovo će uključiti profil za Work, uključujući aplikacije, sinhronizaciju u pozadini i srodne funkcije."</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"Uključi"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Imate nove poruke"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Otvorite aplikaciju za SMS da biste pregledali"</string>
@@ -1759,22 +1788,33 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Unesite vreme"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Pređite u režim unosa teksta radi unosa vremena."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Pređite u režim sata radi unosa vremena."</string>
-    <!-- no translation found for autofill_picker_accessibility_title (8469043291648711535) -->
-    <skip />
-    <string name="autofill_save_title" msgid="7081244500504163245">"Želite li da sačuvate u: <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
-    <string name="autofill_save_title_with_type" msgid="4977385733042555659">"Želite li da sačuvate stavku <xliff:g id="TYPE">%1$s</xliff:g> u: <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+    <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opcije automatskog popunjavanja"</string>
+    <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"Sačuvajte za automatsko popunjavanje"</string>
+    <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Sadržaj ne može automatski da se popuni"</string>
+    <string name="autofill_picker_no_suggestions" msgid="3908514303773350735">"Nema automatski popunjenih predloga"</string>
+    <plurals name="autofill_picker_some_suggestions" formatted="false" msgid="5506565809835815274">
+      <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> automatski popunjen predlog</item>
+      <item quantity="few"><xliff:g id="COUNT">%1$s</xliff:g> automatski popunjena predloga</item>
+      <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> automatski popunjenih predloga</item>
+    </plurals>
+    <string name="autofill_save_title" msgid="3345527308992082601">"Želite li da sačuvate u: &lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_type" msgid="8637809388029313305">"Želite li da sačuvate stavku <xliff:g id="TYPE">%1$s</xliff:g> u: &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"Želite li da sačuvate stavke <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> u: &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"Želite li da sačuvate stavke <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g> u: &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt;?"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"Sačuvaj"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"Ne, hvala"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"lozinka"</string>
     <string name="autofill_save_type_address" msgid="4936707762193009542">"adresa"</string>
     <string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kreditna kartica"</string>
-    <!-- no translation found for etws_primary_default_message_earthquake (5541962250262769193) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_tsunami (1887685943498368548) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_earthquake_and_tsunami (998797956848445862) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_test (2709597093560037455) -->
-    <skip />
+    <string name="autofill_save_type_username" msgid="239040540379769562">"korisničko ime"</string>
+    <string name="autofill_save_type_email_address" msgid="5752949432129262174">"imejl adresa"</string>
+    <string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Ostanite mirni i potražite sklonište u okolini."</string>
+    <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Odmah se sklonite iz priobalnih regiona i oblasti pored reka na neko bezbednije mesto, na primer, na neko uzvišenje."</string>
+    <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Ostanite mirni i potražite sklonište u okolini."</string>
+    <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Testiranje poruka u hitnim slučajevima"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
+    <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM kartica nije dozvoljena"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM kartica nije podešena"</string>
+    <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM kartica nije dozvoljena"</string>
+    <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefon nije dozvoljen"</string>
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index d12a104..db163bf 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="byteShort" msgid="8340973892742019101">"B"</string>
+    <string name="byteShort" msgid="8340973892742019101">"б"</string>
     <string name="kilobyteShort" msgid="7542884022844556968">"КБ"</string>
     <string name="megabyteShort" msgid="6355851576770428922">"Мб"</string>
     <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
@@ -91,17 +91,23 @@
     <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Налады ідэнтыфікатару АВН па змаўчанні: не абмяжавана. Наступны выклік: не абмежавана"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Служба не прадастаўляецца."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Вы не можаце змяніць налады ідэнтыфікатара абанента, якi тэлефануе."</string>
-    <string name="RestrictedOnData" msgid="8653794784690065540">"Служба дадзеных блакуецца."</string>
-    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Аварыйная служба блакуецца."</string>
-    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Галасавая служба заблакаваная."</string>
-    <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Усе галасавыя службы заблакаваны."</string>
-    <string name="RestrictedOnSms" msgid="8314352327461638897">"Служба SMS заблакаваная."</string>
-    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Службы перадачы голаса/дадзеных заблакаваны."</string>
-    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Службы перадачы голаса і SMS заблакаваныя."</string>
-    <string name="RestrictedOnAll" msgid="5643028264466092821">"Усе службы перадачы дадзеных, галасавыя і SMS-службы заблакаваны."</string>
+    <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Няма сэрвісу перадачы даных"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Няма сэрвісу экстранных выклікаў"</string>
+    <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Няма сэрвісу галасавых выклікаў"</string>
+    <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Няма сэрвісу галасавых / экстранных выклікаў"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Ваш аператар часова прыпыніў працу сэрвісу перадачы даных у гэтым месцы"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Ваш аператар часова прыпыніў працу сэрвісу экстранных выклікаў у гэтым месцы"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Ваш аператар часова прыпыніў працу сэрвісу галасавых выклікаў у гэтым месцы"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Ваш аператар часова прыпыніў працу сэрвісу галасавых і экстранных выклікаў у гэтым месцы"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Немагчыма падключыцца да сеткі"</string>
-    <!-- no translation found for NetworkPreferenceSwitchSummary (4164230263214915351) -->
-    <skip />
+    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Каб палепшыць якасць прыёму, паспрабуйце змяніць тып, выбраны ў меню \"Сістэма &gt; Сетка і інтэрнэт &gt; Мабільныя сеткі &gt; Прыярытэтны тып сеткі\"."</string>
+    <string name="notification_channel_network_alert" msgid="4427736684338074967">"Абвесткі"</string>
+    <string name="notification_channel_call_forward" msgid="2419697808481833249">"Пераадрасацыя выкліку"</string>
+    <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Рэжым экстраннага зваротнага выкліку"</string>
+    <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Абвесткі пра мабільныя даныя"</string>
+    <string name="notification_channel_sms" msgid="3441746047346135073">"SMS-паведамленні"</string>
+    <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Паведамленні галасавой пошты"</string>
+    <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi-тэлефанія"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Аднарангавая прылада запытала рэжым TTY FULL"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Аднарангавая прылада запытала рэжым TTY НСО"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Аднарангавая прылада запытала рэжым TTY VCO"</string>
@@ -141,8 +147,7 @@
   </string-array>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Выкл."</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Прыярытэт Wi-Fi"</string>
-    <!-- no translation found for wfc_mode_cellular_preferred_summary (1988279625335345908) -->
-    <skip />
+    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Прыярытэт мабільнай сеткі"</string>
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Толькі Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не пераадрасоўваецца"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -182,18 +187,16 @@
       <item quantity="other">Усталяваны цэнтры сертыфікацыі</item>
     </plurals>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Невядомая трэцяя асоба"</string>
-    <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Адміністратар вашага працоўнага профілю"</string>
+    <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"Адміністратар вашага працоўнага профілю"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="work_profile_deleted" msgid="5005572078641980632">"Рабочы профіль выдалены"</string>
-    <string name="work_profile_deleted_description" msgid="6305147513054341102">"Рабочы профіль выдалены з-за адсутнасці праграмы адміністравання."</string>
-    <string name="work_profile_deleted_details" msgid="226615743462361248">"Праграма для адміністравання рабочага профілю адсутнічае або пашкоджана. У выніку гэтага ваш рабочы профіль і звязаныя з ім даныя былі выдаленыя. Звярніцеся па дапамогу да адміністратара."</string>
-    <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Ваш працоўны профіль больш не даступны на гэтай прыладзе."</string>
-    <!-- no translation found for network_logging_notification_title (6399790108123704477) -->
-    <skip />
-    <!-- no translation found for network_logging_notification_text (7930089249949354026) -->
-    <skip />
+    <string name="work_profile_deleted_description" msgid="1100529432509639864">"Працоўны профіль выдалены з-за адсутнасці праграмы адміністратара"</string>
+    <string name="work_profile_deleted_details" msgid="6307630639269092360">"Праграма адміністратара для працоўнага профілю адсутнічае або пашкоджана. У выніку гэтага ваш працоўны профіль і звязаныя з ім даныя былі выдалены. Звярніцеся па дапамогу да адміністратара."</string>
+    <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Ваш працоўны профіль больш не даступны на гэтай прыладзе"</string>
+    <string name="network_logging_notification_title" msgid="6399790108123704477">"Прылада знаходзіцца пад кіраваннем"</string>
+    <string name="network_logging_notification_text" msgid="7930089249949354026">"Ваша арганізацыя кіруе гэтай прыладай і можа сачыць за сеткавым трафікам. Дакраніцеся для атрымання дадатковай інфармацыі."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Даныя вашай прылады будуць сцерты"</string>
-    <string name="factory_reset_message" msgid="4905025204141900666">"Праграма для адміністравання не можа быць выкарыстана, таму што ў яе адсутнічаюць кампаненты або яна пашкоджана. Зараз даныя вашай прылады будуць сцерты. Звярніцеся па дапамогу да адміністратара."</string>
+    <string name="factory_reset_message" msgid="7972496262232832457">"Немагчыма выкарыстоўваць праграму адміністратара. Зараз звесткі на вашай прыладзе будуць выдалены.\n\nКалі ў вас ёсць пытанні, звярніцеся да адміністратара вашай арганізацыі."</string>
     <string name="me" msgid="6545696007631404292">"Я"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Параметры планшэта"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"Параметры ТБ"</string>
@@ -244,7 +247,7 @@
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Бязгучны рэжым"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Гук выкл."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Гук уключаны"</string>
-    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Рэжым \"У самалёце\""</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Рэжым палёту"</string>
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Уключаны рэжым \"У самалёце\""</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Рэжым \"У самалёце\" адключаны"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Налады"</string>
@@ -263,11 +266,17 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Абнаўленні"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Стан сеткі"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Абвесткі сеткі"</string>
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Сетка даступная"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Стан VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Адміністраванне прылады"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Абвесткi"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Дэманстрацыйны рэжым для пунктаў продажу"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Падключэнне USB"</string>
+    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Праграмы, якія працуюць у фонавым рэжыме"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> працуе ў фонавым рэжыме"</string>
+    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Праграмы (<xliff:g id="NUMBER">%1$d</xliff:g>) працуюць у фонавым рэжыме"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Дакраніцеся, каб даведацца пра выкарыстанне трафіка і акумулятара"</string>
+    <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Бяспечны рэжым"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Сістэма Android"</string>
     <string name="user_owner_label" msgid="1119010402169916617">"Пераключыцца на асабісты"</string>
@@ -290,14 +299,12 @@
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"рабіць тэлефонныя выклікі і кіраваць імі"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"Датчыкі цела"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"атрымліваць з датчыка даныя асноўных фізіялагічных паказчыкаў"</string>
-    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Атрымайце змесцiва акна"</string>
-    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Вывучыце змесцiва акна, з якiм вы працуеце."</string>
-    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Уключыце Explore by Touch"</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_desc_canRequestTouchExploration" msgid="7543249041581408313">"Элементы, да якіх дакрануліся, будуць агучаны, а экранам можна даследаваць пры дапамозе жэстаў."</string>
-    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Уключыце паляпшэнне вэб-даступнасці"</string>
-    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Сцэнарыi могуць быць усталяваны, каб зрабіць змесцiва прыкладання больш даступным."</string>
-    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Глядзiце, што набiраеце"</string>
-    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Уключае ў сябе асабістыя дадзеныя, такія як нумары крэдытных карт і паролі."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Праглядаць тэкст, які вы набіраеце"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"У тым ліку асабістыя даныя, такія як нумары крэдытных карт і паролі."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Кіраваць павелічэннем дысплэя"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Кіраваць маштабам дысплэя і пазіцыянаваннем."</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Выконваць жэсты"</string>
@@ -416,8 +423,8 @@
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Дазваляе прыкладанням атрымлiваць доступ да функцый тэлефона на прыладзе. Дзякуючы гэтаму дазволу прыкладанне можа вызначаць iдэнтыфiкатары нумару тэлефона i прылады, незалежна ад таго, цi актыўны выклiк, i аддалены нумар, на якi робiцца выклiк."</string>
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"перанакіраванне выклікаў праз сістэму"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Дазваляе праграме перанакіроўваць выклікі праз сістэму ў мэтах паляпшэння выклікаў."</string>
-    <string name="permlab_readPhoneNumber" msgid="6421295519255154171">"чытаць нумар тэлефона"</string>
-    <string name="permdesc_readPhoneNumber" msgid="9135856402838173711">"Праграма зможа атрымліваць доступ да тэлефоннага нумара прылады."</string>
+    <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"счытваць нумары тэлефонаў"</string>
+    <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"Дазваляе праграме атрымліваць доступ да нумароў тэлефонаў на прыладзе."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"прадухіліць планшэт ад пераходу ў рэжым сну"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"прадухіленне пераходу тэлевізара ў рэжым сну"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"забараняць тэлефону пераходзіць ў рэжым сну"</string>
@@ -490,6 +497,7 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Час чакання адбіткаў пальцаў выйшаў. Паспрабуйце яшчэ раз."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Аперацыя з адбіткамі пальцаў скасавана."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Занадта шмат спроб. Паспрабуйце яшчэ раз пазней."</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Занадта шмат спроб. Сканер адбіткаў пальцаў адключаны."</string>
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Паспрабуйце яшчэ раз."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
@@ -557,7 +565,7 @@
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Дазваляе праграме чытаць і выконваць запіс у канфігурацыю рэжыму «Не турбаваць»."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Устанавіць правілы паролю"</string>
     <string name="policydesc_limitPassword" msgid="2502021457917874968">"Кіраваць даўжынёй і сімваламі, дазволенымі пры ўводзе пароляў і PIN-кодаў блакіроўкі экрана."</string>
-    <string name="policylab_watchLogin" msgid="914130646942199503">"Сачыць за спробамі разблакоўкі экрана"</string>
+    <string name="policylab_watchLogin" msgid="5091404125971980158">"Сачыць за спробамі разблакіроўкі экрана"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Сачыць за колькасцю няправільных набраных пароляў падчас разблакоўкі экрана і блакаваць планшэт або сціраць усе дадзеныя на ім, калі няправільны пароль набраны занадта шмат разоў."</string>
     <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Сачыць за колькасцю няправільна набраных пароляў падчас разблакіроўкі экрана і блакіраваць тэлевізар або сціраць усе даныя на ім, калі няправільны пароль набраны занадта шмат разоў."</string>
     <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Сачыць за колькасцю няправільных набраных пароляў падчас разблакоўкі экрана і блакаваць тяэлефон або сціраць усе дадзеныя на ім, калі набрана занадта шмат няправільных пароляў."</string>
@@ -1010,17 +1018,16 @@
     <string name="selectTextMode" msgid="1018691815143165326">"Выбраць тэкст"</string>
     <string name="undo" msgid="7905788502491742328">"Адрабіць"</string>
     <string name="redo" msgid="7759464876566803888">"Узнавіць"</string>
-    <!-- no translation found for autofill (3035779615680565188) -->
-    <skip />
+    <string name="autofill" msgid="3035779615680565188">"Аўтазапаўненне"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Вылучэнне тэксту"</string>
     <string name="addToDictionary" msgid="4352161534510057874">"Дадаць у слоўнік"</string>
     <string name="deleteText" msgid="6979668428458199034">"Выдалiць"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Метад уводу"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Дзеянні з тэкстам"</string>
     <string name="email" msgid="4560673117055050403">"Электронная пошта"</string>
-    <string name="dial" msgid="4204975095406423102">"Патэлефанаваць"</string>
-    <string name="map" msgid="5441053548030107189">"Карта"</string>
-    <string name="browse" msgid="6079864138582486027">"Праглядзець"</string>
+    <string name="dial" msgid="4204975095406423102">"Тэлефон"</string>
+    <string name="map" msgid="6068210738233985748">"Карты"</string>
+    <string name="browse" msgid="6993590095938149861">"Браўзер"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Месца для захавання на зыходзе"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Некаторыя сістэмныя функцыі могуць не працаваць"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Не хапае сховішча для сістэмы. Пераканайцеся, што ў вас ёсць 250 МБ свабоднага месца, і перазапусціце."</string>
@@ -1061,7 +1068,7 @@
     <string name="chooseActivity" msgid="7486876147751803333">"Выберыце дзеянне"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Выберыце прыкладанне для USB-прылады"</string>
     <string name="noApplications" msgid="2991814273936504689">"Няма прыкладанняў, якія могуць выконваць гэты працэс."</string>
-    <string name="aerr_application" msgid="250320989337856518">"Праграма <xliff:g id="APPLICATION">%1$s</xliff:g> спынілася"</string>
+    <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g>: збой у рабоце"</string>
     <string name="aerr_process" msgid="6201597323218674729">"Працэс <xliff:g id="PROCESS">%1$s</xliff:g> спыніўся"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> шматразова спыняе працу"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> шматразова спыняе працу"</string>
@@ -1134,6 +1141,18 @@
     <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Гукі будзільніка"</string>
     <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Гукі апавяшчэнняў"</string>
     <string name="ringtone_unknown" msgid="3914515995813061520">"Невядома"</string>
+    <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
+      <item quantity="one">сетка Wi-Fi даступная</item>
+      <item quantity="few">сеткі Wi-Fi даступныя</item>
+      <item quantity="many">сетак Wi-Fi даступна</item>
+      <item quantity="other">сеткі Wi-Fi даступна</item>
+    </plurals>
+    <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
+      <item quantity="one">адкрытая сетка Wi-Fi даступная</item>
+      <item quantity="few">адкрытыя сеткі Wi-Fi даступныя</item>
+      <item quantity="many">адкрытых сетак Wi-Fi даступна</item>
+      <item quantity="other">адкрытай сеткі Wi-Fi даступна</item>
+    </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Уваход у сетку Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Увайдзіце ў сетку"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1143,7 +1162,13 @@
     <string name="network_switch_metered" msgid="4671730921726992671">"Выкананы пераход да <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
     <string name="network_switch_metered_detail" msgid="5325661434777870353">"Прылада выкарыстоўвае <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, калі ў <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> няма доступу да інтэрнэту. Можа спаганяцца дадатковая плата."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"Выкананы пераход з <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> да <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <!-- no translation found for network_switch_type_name:0 (3979506840912951943) -->
+  <string-array name="network_switch_type_name">
+    <item msgid="3979506840912951943">"мабільная перадача даных"</item>
+    <item msgid="75483255295529161">"Wi-Fi"</item>
+    <item msgid="6862614801537202646">"Bluetooth"</item>
+    <item msgid="5447331121797802871">"Ethernet"</item>
+    <item msgid="8257233890381651999">"VPN"</item>
+  </string-array>
     <string name="network_switch_type_name_unknown" msgid="4552612897806660656">"невядомы тып сеткі"</string>
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Немагчыма падключыцца да Wi-Fi"</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" дрэннае падключэнне да Інтэрнэту."</string>
@@ -1207,13 +1232,15 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB для MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Падключаны да USB-прылады"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Дакраніцеся, каб атрымаць іншыя параметры."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аксесуар аўдыя не падтрымліваецца"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Націсніце, каб атрымаць дадатковую інфармацыю"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Адладка па USB падключана"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Дакраніцеся, каб адключыць адладку па USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Выберыце, каб адключыць адладку USB."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Стварэнне справаздачы пра памылку…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Падзяліцца справаздачай пра памылку?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Перадача справаздачы пра памылку..."</string>
-    <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"ІТ-адміністратар запытаў справаздачу пра памылку для яе ліквідацыі на гэтай прыладзе. Можа адбыцца абагуленне праграм і даных."</string>
+    <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"Ваш адміністратар запытаў справаздачу пра памылку для яе ліквідацыі на гэтай прыладзе. Звесткі праграм і даныя могуць быць абагулены."</string>
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"АБАГУЛІЦЬ"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"АДХІЛІЦЬ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Змяніць клавіятуру"</string>
@@ -1223,8 +1250,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Дакраніцеся, каб выбраць мову і раскладку"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШ\'ЫЬЭЮЯ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> паказваецца паверх іншых праграм"</string>
-    <string name="alert_windows_notification_title" msgid="4532185840598192445">"<xliff:g id="NAME">%s</xliff:g> паказв. паверх інш. праграм."</string>
+    <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> паказв. паверх іншых праграм"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Калі вы не хочаце, каб праграма <xliff:g id="NAME">%s</xliff:g> выкарыстоўвала гэту функцыю, дакраніцеся, каб адкрыць налады і адключыць гэта."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"АДКЛЮЧЫЦЬ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Падрыхтоўка <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1401,8 +1430,7 @@
     <string name="data_usage_warning_body" msgid="6660692274311972007">"Прагляд выкарыстання і налад."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Дасягнуты ліміт трафіку 2G-3G"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Дасягнуты ліміт трафіку 4G"</string>
-    <!-- no translation found for data_usage_mobile_limit_title (6561099244084267376) -->
-    <skip />
+    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Дасягн. ліміт маб. перад. даных"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Дасягн. ліміт перад. даных Wi-Fi"</string>
     <string name="data_usage_limit_body" msgid="291731708279614081">"Перад.даных спын. да канца цыкла"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Перавышаны ліміт 2G-3G"</string>
@@ -1501,18 +1529,21 @@
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Выдалiць"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Павялiчыць гук вышэй рэкамендаванага ўзроўню?\n\nДоўгае праслухоўванне музыкi на вялiкай гучнасцi можа пашкодзiць ваш слых."</string>
-    <string name="accessibility_shortcut_warning_dialog_title" msgid="5998592821749881862">"Камбінацыя хуткага доступу для спецыяльных магчымасцей АКТЫВАВАНА"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="2987297770937717543">"Уключайце ці адключайце <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, утрымліваючы абедзве кнопкі рэгулявання гучнасці націснутымі на працягу 3 секунд.\n\nВы можаце змяніць сэрвіс у меню \"Налады &gt; Спецыяльныя магчымасці\"."</string>
-    <string name="disable_accessibility_shortcut" msgid="3683951963271793789">"Дэактываваць камбінацыю хуткага доступу"</string>
-    <string name="leave_accessibility_shortcut_on" msgid="8762106842437042969">"Пакінуць актываванай"</string>
+    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Выкарыстоўваць камбінацыю хуткага доступу для спецыяльных магчымасцей?"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Калі камбінацыя хуткага доступу ўключана, вы можаце націснуць абедзве кнопкі гучнасці і ўтрымліваць іх 3 секунды, каб уключыць функцыю спецыяльных магчымасцей.\n\n Бягучая функцыя спецыяльных магчымасцей:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Вы можаце змяніць гэту функцыю ў меню \"Налады &gt; Спецыяльныя магчымасці\"."</string>
+    <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Дэактываваць камбінацыю хуткага доступу"</string>
+    <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Выкарыстоўваць камбінацыю хуткага доступу"</string>
     <string name="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_button_prompt_text" msgid="4234556536456854251">"Выберыце функцыю для выкарыстання пры націску кнопкі \"Спецыяльныя магчымасці\":"</string>
+    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Каб змяняць функцыі, краніце і ўтрымлівайце кнопку \"Спецыяльныя магчымасці\"."</string>
+    <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Павелічэнне"</string>
     <string name="user_switched" msgid="3768006783166984410">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Пераход да <xliff:g id="NAME">%1$s</xliff:g>..."</string>
     <string name="user_logging_out_message" msgid="8939524935808875155">"<xliff:g id="NAME">%1$s</xliff:g> выходзіць з сістэмы…"</string>
     <string name="owner_name" msgid="2716755460376028154">"Уладальнік"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Памылка"</string>
-    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Ваш адміністратар не дазваляе гэту змену"</string>
+    <string name="error_message_change_not_allowed" msgid="1238035947357923497">"Ваш адміністратар не дазваляе гэту змену"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Прыкладанне для гэтага дзеяння не знойдзенае"</string>
     <string name="revoke" msgid="5404479185228271586">"Ануляваць"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1604,7 +1635,7 @@
     <string name="reason_service_unavailable" msgid="7824008732243903268">"Служба друку не ўключана"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"Усталявана служба <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="print_service_installed_message" msgid="5897362931070459152">"Краніце, каб уключыць"</string>
-    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Увядзіце PIN-код адміністратара"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"Увядзіце PIN-код адміністратара"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Увядзіце PIN-код"</string>
     <string name="restr_pin_incorrect" msgid="8571512003955077924">"Няправільны"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Бягучы PIN-код"</string>
@@ -1634,16 +1665,16 @@
     <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (праца)"</string>
     <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"Другая праца <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"Трэцяя праца <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="lock_to_app_toast" msgid="7693684144593484">"Каб адмацаваць гэты экран, дакраніцеся і ўтрымлівайце кнопкі \"Назад\" і \"Агляд\"."</string>
-    <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Праграма замацавана: адмацаванне на гэтай прыладзе не дапускаецца."</string>
+    <string name="lock_to_app_toast" msgid="6820571533009838261">"Каб адмацаваць гэты экран, краніце і ўтрымлівайце кнопкі \"Назад\" і \"Агляд\""</string>
+    <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Гэту праграму нельга адмацаваць"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"Экран замацаваны"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"Экран адмацаваны"</string>
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Запытваць PIN-код перад адмацаваннем"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Запытваць узор разблакіроўкі перад адмацаваннем"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запытваць пароль перад адмацаваннем"</string>
-    <string name="package_installed_device_owner" msgid="8420696545959087545">"Усталявана вашым адміністратарам"</string>
-    <string name="package_updated_device_owner" msgid="8856631322440187071">"Абноўлена вашым адміністратарам"</string>
-    <string name="package_deleted_device_owner" msgid="7650577387493101353">"Выдалена вашым адміністратарам"</string>
+    <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" msgid="1960431123816253034">"Каб падоўжыць час працы акумулятара, у рэжыме эканоміі зараду памяншаецца прадукцыйнасць вашай прылады, абмяжоўваецца выкарыстанне вібрацыі, службаў вызначэння месцазнаходжання і большасці задач фонавай перадачы даных. Электронная пошта, абмен паведамленнямі і іншыя праграмы, якія выкарыстоўваюць сінхранізацыю, могуць не абнаўляцца, пакуль вы іх не адкрыеце.\n\nРэжым эканоміі зараду адключаецца аўтаматычна, калі прылада зараджаецца."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Каб паменшыць выкарыстанне даных, Эканомія трафіку не дазваляе некаторым праграмам адпраўляць ці атрымліваць даныя ў фонавым рэжыме. Праграма, якую вы зараз выкарыстоўваеце, можа атрымліваць доступ да даных, але можа рабіць гэта радзей. Гэта можа азначаць, напрыклад, што відарысы не паказваюцца, пакуль вы не дакраняцеся да іх."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Уключыць Эканомію трафіка?"</string>
@@ -1734,7 +1765,7 @@
       <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="default_notification_channel_label" msgid="6950908610709016902">"Рознае"</string>
+    <string name="default_notification_channel_label" msgid="5929663562028088222">"Некатэгарызаванае"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Вы задалі важнасць гэтых апавяшчэнняў."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Гэта важна, бо з гэтым звязаны пэўныя людзі."</string>
     <string name="user_creation_account_exists" msgid="1942606193570143289">"Дазволіць <xliff:g id="APP">%1$s</xliff:g> стварыць новага Карыстальніка з уліковым запісам <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
@@ -1746,8 +1777,8 @@
     <string name="language_picker_section_all" msgid="3097279199511617537">"Усе мовы"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"Усе рэгіёны"</string>
     <string name="locale_search_menu" msgid="2560710726687249178">"Шукаць"</string>
-    <string name="work_mode_off_title" msgid="8954725060677558855">"Рэжым працы АДКЛЮЧАНЫ"</string>
-    <string name="work_mode_off_message" msgid="3286169091278094476">"Дазволіць функцыянаванне працоўнага профілю, у тым ліку праграм, фонавай сінхранізацыі і звязаных з імі функцый."</string>
+    <string name="work_mode_off_title" msgid="2615362773958585967">"Уключыць працоўны рэжым?"</string>
+    <string name="work_mode_off_message" msgid="2961559609199223594">"Гэта прывядзе да ўключэння вашага працоўнага профілю, у тым ліку праграм, фонавай сінхранізацыі і звязаных з імі функцый"</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"Уключыць"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"У вас ёсць новыя паведамленні"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Праглядзець праз праграму для SMS"</string>
@@ -1783,29 +1814,41 @@
     <string name="app_category_productivity" msgid="3742083261781538852">"Прадукцыйнасць"</string>
     <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Сховішча на прыладзе"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"Адладка USB"</string>
-    <string name="time_picker_hour_label" msgid="2979075098868106450">"гадзіна"</string>
+    <string name="time_picker_hour_label" msgid="2979075098868106450">"гадз"</string>
     <string name="time_picker_minute_label" msgid="5168864173796598399">"хвіліна"</string>
     <string name="time_picker_header_text" msgid="143536825321922567">"Задаць час"</string>
     <string name="time_picker_input_error" msgid="7574999942502513765">"Увядзіце дапушчальны час"</string>
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Увядзіце час"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Пераключыцца на рэжым тэксту пры ўводзе часу."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Пераключыцца на рэжым гадзінніка пры ўводзе часу."</string>
-    <!-- no translation found for autofill_picker_accessibility_title (8469043291648711535) -->
-    <skip />
-    <string name="autofill_save_title" msgid="7081244500504163245">"Захаваць у <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
-    <string name="autofill_save_title_with_type" msgid="4977385733042555659">"Захаваць наступнае: <xliff:g id="TYPE">%1$s</xliff:g> у <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+    <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Параметры аўтазапаўнення"</string>
+    <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"Захаваць для аўтазапаўнення"</string>
+    <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Для гэтага змесціва аўтазапаўненне немагчымае"</string>
+    <string name="autofill_picker_no_suggestions" msgid="3908514303773350735">"Няма прапаноў аўтазапаўнення"</string>
+    <plurals name="autofill_picker_some_suggestions" formatted="false" msgid="5506565809835815274">
+      <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> прапанова аўтазапаўнення</item>
+      <item quantity="few"><xliff:g id="COUNT">%1$s</xliff:g> прапановы аўтазапаўнення</item>
+      <item quantity="many"><xliff:g id="COUNT">%1$s</xliff:g> прапаноў аўтазапаўнення</item>
+      <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> прапановы аўтазапаўнення</item>
+    </plurals>
+    <string name="autofill_save_title" msgid="3345527308992082601">"Захаваць у &lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_type" msgid="8637809388029313305">"Захаваць <xliff:g id="TYPE">%1$s</xliff:g> у &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"Захаваць <xliff:g id="TYPE_0">%1$s</xliff:g> і <xliff:g id="TYPE_1">%2$s</xliff:g> у &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"Захаваць <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> і <xliff:g id="TYPE_2">%3$s</xliff:g> у &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt;?"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"Захаваць"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"Не, дзякуй"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"пароль"</string>
     <string name="autofill_save_type_address" msgid="4936707762193009542">"адрас"</string>
     <string name="autofill_save_type_credit_card" msgid="7127694776265563071">"крэдытная картка"</string>
-    <!-- no translation found for etws_primary_default_message_earthquake (5541962250262769193) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_tsunami (1887685943498368548) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_earthquake_and_tsunami (998797956848445862) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_test (2709597093560037455) -->
-    <skip />
+    <string name="autofill_save_type_username" msgid="239040540379769562">"карыстальнік"</string>
+    <string name="autofill_save_type_email_address" msgid="5752949432129262174">"адрас электроннай пошты"</string>
+    <string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Заставайцеся спакойнымі і пашукайце прытулак паблізу."</string>
+    <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Неадкладна эвакуіруйцеся з прыбярэжных раёнаў у больш бяспечнае месца, напрыклад на ўзвышша."</string>
+    <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Заставайцеся спакойнымі і пашукайце прытулак паблізу."</string>
+    <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Праверка экстранных паведамленняў"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
+    <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-карта не дапускаецца"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-карты няма"</string>
+    <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM-карта не дапускаецца"</string>
+    <string name="mmcc_illegal_me" msgid="4438696681169345015">"Тэлефон не дапускаецца"</string>
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 3433064..6c9b8d6 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Търси се покритие"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Обаждания през Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките."</item>
+    <item msgid="3910386316304772394">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо, помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките. (Код на грешката: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Регистриране с оператора ви"</item>
+    <item msgid="7472393097168811593">"Регистриране с оператора ви (код на грешката: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Гласова помощ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Заключване сега"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Скрито съдържание"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Съдържанието е скрито чрез правило"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Ново известие"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуална клавиатура"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Физическа клавиатура"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Сигурност"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Сигнали"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Демонстрационен режим за магазини"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB връзка"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Приложения, работещи на заден план"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> се изпълнява на заден план"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> приложения работят на заден план"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Приложения, използващи батерията"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> използва батерията"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> приложения използват батерията"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Докоснете за информация относно използването на батерията и преноса на данни"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Безопасен режим"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Има достъпни отворени Wi-Fi мрежи</item>
       <item quantity="one">Има достъпна отворена Wi-Fi мрежа</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Свързване с отворена Wi‑Fi мрежа"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Установява се връзка с отворена Wi‑Fi мрежа"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Установихте връзка с Wi-Fi мрежата"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не можа да се установи връзка с Wi‑Fi мрежата"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Докоснете, за да видите всички мрежи"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Свързване"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Всички мрежи"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Влизане в Wi-Fi мрежа"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Вход в мрежата"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB за MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Установена е връзка с аксесоар за USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Докоснете за още опции."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Открит е аналогов аудиоаксесоар"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Свързаното устройство не е съвместимо с този телефон. Докоснете, за да научите повече."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отстраняване на грешки през USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Докоснете, за да деактивирате отстраняването на грешки през USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете, за да деактивирате отстраняването на грешки през USB."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Свързана с/ъс <xliff:g id="SESSION">%s</xliff:g>. Докоснете, за да управлявате мрежата."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Установява се връзка с винаги включената виртуална частна мрежа (VPN)…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Установена е връзка с винаги включената виртуална частна мрежа (VPN)"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Няма връзка с винаги включената виртуална частна мрежа (VPN)"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Връзката с винаги включената VPN е прекратена"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Грешка във винаги включената виртуална частна мрежа (VPN)"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Докоснете, за да настроите"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Промяна на настройките за мрежата или VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Избор на файл"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Няма избран файл"</string>
     <string name="reset" msgid="2448168080964209908">"Повторно задаване"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Докоснете, за да излезете от моторежима."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Има активна споделена връзка или безжична точка за достъп"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Докоснете, за да настроите."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Функцията за тетъринг е деактивирана"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Свържете се с администратора си за подробности"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Напред"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Пропускане"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Освобождаване"</string>
     <string name="app_info" msgid="6856026610594615344">"Информация за приложението"</string>
     <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Да се нулира ли устройството?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Докоснете, за да нулирате устройството"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Демонстрацията се стартира…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Устройството се нулира…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Да се нулира ли устройството?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Ще загубите всички промени и демонстрацията ще започне отново след <xliff:g id="TIMEOUT">%1$s</xliff:g> секунди…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Отказ"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Нулиране сега"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g>: Деактивирано"</string>
     <string name="conference_call" msgid="3751093130790472426">"Конферентно обаждане"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Подсказка"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Евакуирайте се незабавно от крайбрежните и крайречните региони на по-безопасно място – например такова с по-високо надморско равнище."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Запазете спокойствие и потърсете убежище в района."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Тест за спешни съобщения"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Отговор"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM картата не е разрешена"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM картата не е обезпечена"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index d09191b..540af9c 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -45,7 +45,7 @@
     <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"ভয়েসমেল"</string>
     <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
     <string name="mmiError" msgid="5154499457739052907">"সংযোগ সমস্যা বা অবৈধ MMI কোড৷"</string>
-    <string name="mmiFdnError" msgid="5224398216385316471">"নির্দিষ্ট নম্বরে ডায়ালযোগ্য হিসাবে প্রক্রিয়াটি সীমিত করা হয়েছে৷"</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"নির্দিষ্ট নম্বরে ডায়ালযোগ্য হিসেবে প্রক্রিয়াটি সীমিত করা হয়েছে৷"</string>
     <string name="mmiErrorWhileRoaming" msgid="762488890299284230">"আপনি রোমিংয়ে থাকাকালীন আপনার ফোন থেকে \'কল ফরওয়ার্ড করার সেটিংস\' পরিবর্তন করা যাবে না৷"</string>
     <string name="serviceEnabled" msgid="8147278346414714315">"পরিষেবা সক্ষম করা ছিল৷"</string>
     <string name="serviceEnabledFor" msgid="6856228140453471041">"এর জন্য পরিষেবার সক্ষম করা ছিল:"</string>
@@ -96,12 +96,12 @@
     <string name="RestrictedStateContent" msgid="4278821484643362350">"সাময়িকভাবে মোবাইল নেটওয়ার্ক আপনার অবস্থানে এই পরিষেবা দিচ্ছে না"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"নেটওয়ার্কের সিগন্যাল নেই"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"রিসেপশন উন্নত করতে সিস্টেম &gt; নেটওয়ার্ক এবং ইন্টারনেট &gt; মোবাইল নেটওয়ার্ক &gt; পছন্দের নেটওয়ার্কের ধরণ এ গিয়ে নির্বাচিত নেটওয়ার্কের ধরণ পরিবর্তন করে দেখুন।"</string>
-    <string name="notification_channel_network_alert" msgid="4427736684338074967">"সতর্কবার্তা"</string>
+    <string name="notification_channel_network_alert" msgid="4427736684338074967">"সতর্কতা"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"কল ফরওয়ার্ড করা"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"জরুরি কলব্যাক মোড"</string>
     <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"মোবাইল ডেটার সতর্কবার্তা"</string>
-    <string name="notification_channel_sms" msgid="3441746047346135073">"এসএমএস বার্তা"</string>
-    <string name="notification_channel_voice_mail" msgid="3954099424160511919">"ভয়েসমেল বার্তা"</string>
+    <string name="notification_channel_sms" msgid="3441746047346135073">"এসএমএস মেসেজ"</string>
+    <string name="notification_channel_voice_mail" msgid="3954099424160511919">"ভয়েসমেল মেসেজ"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"ওয়াই-ফাই কলিং"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"পির TTY মোড FULL অনুরোধ করেছে"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"পির TTY মোড HCO অনুরোধ করেছে"</string>
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"পরিষেবা অনুসন্ধান করা হচ্ছে"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ওয়াই-ফাই কলিং"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"ওয়াই-ফাই এর মাধ্যমে কল করতে ও বার্তা পাঠাতে, প্রথমে আপনার পরিষেবা প্রদানকারীকে এই পরিষেবার সেট আপ করার বিষয়ে জিজ্ঞাসা করুন। তারপরে আবার সেটিংস থেকে ওয়াই-ফাই কলিং চালু করুন।"</item>
+    <item msgid="3910386316304772394">"ওয়াই-ফাই এর মাধ্যমে কল করতে ও মেসেজ পাঠাতে, প্রথমে আপনার পরিষেবা প্রদানকারীকে এই পরিষেবার সেট-আপ করতে বলুন। তারপর আবার সেটিংস থেকে ওয়াই-ফাই কলিং চালু করুন। (ত্রুটি কোড: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"আপনার পরিষেবা প্রদানকারীকে নথিভুক্ত করুন"</item>
+    <item msgid="7472393097168811593">"আপনার পরিষেবা প্রদানকারীর সাথে রেজিস্টার করুন (ত্রুটি কোড: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -154,8 +154,8 @@
     <string name="httpErrorOk" msgid="1191919378083472204">"ঠিক আছে"</string>
     <string name="httpError" msgid="7956392511146698522">"একটি নেটওয়ার্ক ত্রুটি ঘটেছে৷"</string>
     <string name="httpErrorLookup" msgid="4711687456111963163">"URL খুঁজে পাওয়া যায়নি৷"</string>
-    <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"এই সাইট প্রমাণীকরণ স্কীমটি সমর্থিত নয়৷"</string>
-    <string name="httpErrorAuth" msgid="1435065629438044534">"প্রমাণীকরণ করা যায়নি৷"</string>
+    <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"এই সাইট যাচাইকরণ স্কীমটি সমর্থিত নয়৷"</string>
+    <string name="httpErrorAuth" msgid="1435065629438044534">"যাচাইকরণ করা যায়নি৷"</string>
     <string name="httpErrorProxyAuth" msgid="1788207010559081331">"প্রক্সী সার্ভারের মাধ্যমে প্রমাণীকরণ ব্যর্থ হয়েছে৷"</string>
     <string name="httpErrorConnect" msgid="8714273236364640549">"সার্ভারের সাথে সংযোগ স্থাপন করা যায়নি৷"</string>
     <string name="httpErrorIO" msgid="2340558197489302188">"সার্ভারের সাথে যোগাযোগ করা যায়নি৷ পরে আবার চেষ্টা করুন৷"</string>
@@ -171,10 +171,10 @@
     <string name="contentServiceSync" msgid="8353523060269335667">"সিঙ্ক"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"সিঙ্ক"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"অনেকগুলি <xliff:g id="CONTENT_TYPE">%s</xliff:g> মুছে ফেলা হয়েছে৷"</string>
-    <string name="low_memory" product="tablet" msgid="6494019234102154896">"ট্যাবলেটের সঞ্চয়স্থানে আর জায়গা খালি নেই৷ স্থান খালি করতে কিছু ফাইল মুছে দিন৷"</string>
-    <string name="low_memory" product="watch" msgid="4415914910770005166">"ঘড়ির সঞ্চয়স্থানে আর জায়গা খালি নেই৷ স্থান খালি করতে কিছু ফাইল মুছে দিন৷"</string>
-    <string name="low_memory" product="tv" msgid="516619861191025923">"টিভির সঞ্চয়স্থান পূর্ণ হয়েছে৷ স্থান মুক্ত করতে কিছু ফাইল মুছে ফেলুন৷"</string>
-    <string name="low_memory" product="default" msgid="3475999286680000541">"ফোনের সঞ্চয়স্থানে আর জায়গা খালি নেই৷ স্থান খালি করতে কিছু ফাইল মুছে দিন৷"</string>
+    <string name="low_memory" product="tablet" msgid="6494019234102154896">"ট্যাবলেটের স্টোরেজে আর জায়গা খালি নেই৷ জায়গা খালি করতে কিছু ফাইল মুছে দিন৷"</string>
+    <string name="low_memory" product="watch" msgid="4415914910770005166">"ঘড়ির স্টোরেজে আর জায়গা খালি নেই৷ জায়গা খালি করতে কিছু ফাইল মুছে দিন৷"</string>
+    <string name="low_memory" product="tv" msgid="516619861191025923">"টিভির স্টোরেজ পূর্ণ হয়েছে। জায়গা খালি করতে কিছু ফাইল মুছে ফেলুন৷"</string>
+    <string name="low_memory" product="default" msgid="3475999286680000541">"ফোনের স্টোরেজে আর জায়গা খালি নেই৷ জায়গা খালি করতে কিছু ফাইল মুছে দিন৷"</string>
     <plurals name="ssl_ca_cert_warning" formatted="false" msgid="5106721205300213569">
       <item quantity="one">টি শংসাপত্রের কর্তৃপক্ষকে ইনস্টল করা হয়েছে</item>
       <item quantity="other">টি শংসাপত্রের কর্তৃপক্ষকে ইনস্টল করা হয়েছে</item>
@@ -189,7 +189,7 @@
     <string name="network_logging_notification_title" msgid="6399790108123704477">"ডিভাইসটি পরিচালনা করা হচ্ছে"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"আপনার প্রতিষ্ঠান এই ডিভাইসটি পরিচালনা করে এবং এটির নেটওয়ার্ক ট্রাফিকের উপরে নজর রাখতে পারে। বিশদ বিবরণের জন্য ট্যাপ করুন।,"</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"আপনার ডিভাইসটি মুছে ফেলা হবে"</string>
-    <string name="factory_reset_message" msgid="7972496262232832457">"প্রশাসক অ্যাপটি ব্যবহার করা যাবে না। আপনার ডিভাইসে থাকা সবকিছু এখন মুছে ফেলা হবে।\n\nকোনো প্রশ্ন থাকলে আপনার প্রতিষ্ঠানের প্রশাসকের সাথে যোগাযোগ করুন।"</string>
+    <string name="factory_reset_message" msgid="7972496262232832457">"প্রশাসক অ্যাপটি ব্যবহার করা যাবে না। আপনার ডিভাইসে থাকা সবকিছু এখন মুছে ফেলা হবে।\n\nকোনও প্রশ্ন থাকলে আপনার প্রতিষ্ঠানের প্রশাসকের সাথে যোগাযোগ করুন।"</string>
     <string name="me" msgid="6545696007631404292">"আমাকে"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ট্যাবলেট বিকল্পগুলি"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"টিভি বিকল্পগুলি"</string>
@@ -226,14 +226,14 @@
     <string name="global_action_emergency" msgid="7112311161137421166">"জরুরী"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"ত্রুটির প্রতিবেদন"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ত্রুটির অভিযোগ করুন"</string>
-    <string name="bugreport_message" msgid="398447048750350456">"এটি একটি ই-মেল বার্তা পাঠানোর জন্য আপনার ডিভাইসের বর্তমান অবস্থা সম্পর্কে তথ্য সংগ্রহ করবে৷ ত্রুটির প্রতিবেদন শুরুর সময় থেকে এটি পাঠানোর জন্য প্রস্তুত হতে কিছুটা সময় নেবে; দয়া করে ধৈর্য রাখুন৷"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"এটি একটি ই-মেল মেসেজ পাঠানোর জন্য আপনার ডিভাইসের বর্তমান অবস্থা সম্পর্কে তথ্য সংগ্রহ করবে৷ ত্রুটির প্রতিবেদন শুরুর সময় থেকে এটি পাঠানোর জন্য প্রস্তুত হতে কিছুটা সময় নেবে; অনুগ্রহ করে ধৈর্য রাখুন৷"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ইন্টারেক্টিভ প্রতিবেদন"</string>
-    <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"বেশিরভাগ পরিস্থিতিতে এটিকে ব্যবহার করুন৷ এটি আপনাকে প্রতিবেদনের কাজ কতটা হয়েছে তার উপর নজর রাখতে দেয়, সমস্যাটির সম্পর্কে আরো অনেক কিছু লিখতে দেয় এবং স্ক্রীনশটগুলি নিতে দেয়৷ এটি হয়ত প্রতিবেদন করতে খুব বেশি সময় নেয় এমনকি কম-ব্যবহৃত বিভাগগুলি সরিয়ে দিতে পারে৷"</string>
+    <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"বেশিরভাগ পরিস্থিতিতে এটিকে ব্যবহার করুন৷ এটি আপনাকে প্রতিবেদনের কাজ কতটা হয়েছে তার উপর নজর রাখতে দেয়, সমস্যাটির সম্পর্কে আরও অনেক কিছু লিখতে দেয় এবং স্ক্রীনশটগুলি নিতে দেয়৷ এটি হয়ত প্রতিবেদন করতে খুব বেশি সময় নেয় এমনকি কম-ব্যবহৃত বিভাগগুলি সরিয়ে দিতে পারে৷"</string>
     <string name="bugreport_option_full_title" msgid="6354382025840076439">"সম্পূর্ণ প্রতিবেদন"</string>
-    <string name="bugreport_option_full_summary" msgid="7210859858969115745">"যখন আপনার ডিভাইসটি প্রতিক্রিয়াবিহীন থাকে বা খুবই ধীর চলে বা যখন আপনার সমস্ত প্রতিবেদন বিভাগগুলির প্রয়োজন হয় তখন ন্যূনতম সিস্টেম হস্তক্ষেপের জন্য এই বিকল্পটি ব্যবহার করুন৷ আপনাকে আরো বিশদ বিবরণ প্রবেশ করানোর বা অতিরিক্ত স্ক্রীনশর্ট নেওয়ার মঞ্জুরি দেয় না৷"</string>
+    <string name="bugreport_option_full_summary" msgid="7210859858969115745">"যখন আপনার ডিভাইসটি প্রতিক্রিয়াবিহীন থাকে বা খুবই ধীর চলে বা যখন আপনার সমস্ত প্রতিবেদন বিভাগগুলির প্রয়োজন হয় তখন ন্যূনতম সিস্টেম হস্তক্ষেপের জন্য এই বিকল্পটি ব্যবহার করুন৷ আপনাকে আরও বিশদ বিবরণ প্রবেশ করানোর বা অতিরিক্ত স্ক্রীনশর্ট নেওয়ার মঞ্জুরি দেয় না৷"</string>
     <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
-      <item quantity="one"><xliff:g id="NUMBER_1">%d</xliff:g> সেকেন্ডের মধ্যে ত্রুটির প্রতিবেদনের জন্য স্ক্রীনশট নেওয়া হচ্ছে৷</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> সেকেন্ডের মধ্যে ত্রুটির প্রতিবেদনের জন্য স্ক্রীনশট নেওয়া হচ্ছে৷</item>
+      <item quantity="one"><xliff:g id="NUMBER_1">%d</xliff:g> সেকেন্ডের মধ্যে ত্রুটির প্রতিবেদনের জন্য স্ক্রিনশট নেওয়া হচ্ছে৷</item>
+      <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> সেকেন্ডের মধ্যে ত্রুটির প্রতিবেদনের জন্য স্ক্রিনশট নেওয়া হচ্ছে৷</item>
     </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"নীরব মোড"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"শব্দ বন্ধ করা আছে"</string>
@@ -246,26 +246,25 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ভয়েস সহায়তা"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"এখনই লক করুন"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"৯৯৯+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"লুকানো বিষয়বস্তু"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"নীতির কারণে সামগ্রী লুকানো আছে"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"নতুন বিজ্ঞপ্তি"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ভার্চুয়াল কীবোর্ড"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ফিজিক্যাল কীবোর্ড"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"নিরাপত্তা"</string>
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"গাড়ি মোড"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"অ্যাকাউন্টের স্থিতি"</string>
-    <string name="notification_channel_developer" msgid="7579606426860206060">"বিকাশকারী সম্পর্কিত বার্তা"</string>
+    <string name="notification_channel_developer" msgid="7579606426860206060">"ডেভেলপার সম্পর্কিত মেসেজ"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"আপডেটগুলি"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"নেটওয়ার্কের স্থিতি"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"নেটওয়ার্ক সক্রান্ত অ্যালার্ট"</string>
     <string name="notification_channel_network_available" msgid="4531717914138179517">"নেটওয়ার্ক পাওয়া যাচ্ছে"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN এর স্থিতি"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"ডিভাইস প্রশাসন"</string>
-    <string name="notification_channel_alerts" msgid="4496839309318519037">"সতর্কতাগুলি"</string>
+    <string name="notification_channel_alerts" msgid="4496839309318519037">"সতর্কতা"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"খুচরা বিক্রয়ের ডেমো"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB সংযোগ"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"পটভূমিতে অ্যাপ চালু আছে"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"পটভূমিতে <xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপ চালু আছে"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"পটভূমিতে <xliff:g id="NUMBER">%1$d</xliff:g>টি অ্যাপ চালু আছে"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"কিছু অ্যাপ ব্যাটারি ব্যবহার করছে"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপটি ব্যাটারি ব্যবহার করছে"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g>টি অ্যাপ ব্যাটারি ব্যবহার করছে"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ব্যাটারি এবং ডেটার ব্যবহারের বিশদ বিবরণের জন্য ট্যাপ করুন"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"নিরাপদ মোড"</string>
@@ -280,7 +279,7 @@
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"আপনার ক্যালেন্ডারে অ্যাক্সেস"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"এসএমএসগুলি পাঠাতে এবং দেখতে"</string>
-    <string name="permgrouplab_storage" msgid="1971118770546336966">"সঞ্চয়স্থান"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"স্টোরেজ"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"আপনার ডিভাইসে ফটো, মিডিয়া এবং ফাইলগুলিতে অ্যাক্সেস"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"মাইক্রোফোন"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"অডিও রেকর্ড"</string>
@@ -290,7 +289,7 @@
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"ফোন কলগুলি এবং পরিচালনা"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"বডি সেন্সরগুলি"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"আপনার অত্যাবশ্যক লক্ষণগুলির সম্পর্কে সেন্সর ডেটা অ্যাক্সেস করে"</string>
-    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"উইন্ডোর সামগ্রী পুনরুদ্ধার করে"</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_desc_canRequestTouchExploration" msgid="7543249041581408313">"যে আইটেমগুলিতে আলতো চেপেছেন সেগুলি সশব্দে বলবে এবং ইঙ্গিতগুলি ব্যবহার করে স্ক্রীন অন্বেষণ করা যাবে৷"</string>
@@ -313,25 +312,25 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"শর্টকাটগুলি আনইনস্টল করে"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"অ্যাপ্লিকেশানটিকে ব্যবহারকারীর হস্তক্ষেপ ছাড়াই হোমস্ক্রীণের শর্টকাটগুলি সরানোর অনুমতি দেয়৷"</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"আউটগোয়িং কলগুলি পুনঃচালিত করুন"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"অ্যাপ্লিকেশানকে কল চলাকালীন অন্য একটি নম্বরে কল পুনঃনির্দেশ বা কলটি একসথে বন্ধ করার সাথে ডায়াল করা নম্বরটি দেখতে দেয়৷"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"অ্যাপ্লিকেশনকে কল চলাকালীন অন্য একটি নম্বরে কল পুনঃনির্দেশ বা কলটি একসথে বন্ধ করার সাথে ডায়াল করা নম্বরটি দেখতে দেয়৷"</string>
     <string name="permlab_answerPhoneCalls" msgid="4077162841226223337">"ফোন কলের উত্তর দিতে দিন"</string>
     <string name="permdesc_answerPhoneCalls" msgid="2901889867993572266">"অ্যাপটিকে ইনকামিং ফোন কলের উত্তর দিতে দেয়।"</string>
-    <string name="permlab_receiveSms" msgid="8673471768947895082">"পাঠ্য বার্তা পান (SMS)"</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"টেক্সট মেসেজ পান (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"অ্যাপ্লিকেশানটিকে এসএমএস প্রাপ্ত করার এবং প্রক্রিয়া করার অনুমতি দেয়৷ এর মানে হল অ্যাপ্লিকেশানটি আপনার ডিভাইস থেকে পাঠানো বার্তাগুলিকে পর্যবেক্ষণ করতে পারে এবং মুছতে পারে সেগুলিকে আপনাকে না দেখিয়ে৷"</string>
-    <string name="permlab_receiveMms" msgid="1821317344668257098">"পাঠ্য বার্তা পান (MMS)"</string>
-    <string name="permdesc_receiveMms" msgid="533019437263212260">"অ্যাপ্লিকেশানটিকে MMS বার্তা প্রাপ্ত করার এবং প্রক্রিয়া করার অনুমতি দেয়৷ এর মানে হল অ্যাপ্লিকেশানটি আপনার ডিভাইস থেকে পাঠানো বার্তাগুলিকে পর্যবেক্ষণ করতে পারে এবং মুছতে পারে সেগুলিকে আপনাকে না দেখিয়ে৷"</string>
-    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"সেল সম্প্রচার বার্তা পড়ুন"</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"টেক্সট মেসেজ পান (MMS)"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"অ্যাপ্লিকেশানটিকে MMS মেসেজ প্রাপ্ত করার এবং প্রক্রিয়া করার অনুমতি দেয়৷ এর মানে হল অ্যাপ্লিকেশানটি আপনার ডিভাইস থেকে পাঠানো মেসেজগুলিকে পর্যবেক্ষণ করতে পারে এবং মুছতে পারে সেগুলিকে আপনাকে না দেখিয়ে৷"</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"সেল সম্প্রচার মেসেজ পড়ুন"</string>
     <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"আপনার ডিভাইস দ্বারা প্রাপ্ত সেল সম্প্রচার পড়তে অ্যাপ্লিকেশানটিকে অনুমতি দেয়৷ কয়েকটি স্থানে আপনাকে জরুরি অবস্থার জন্য সতর্ক করতে জরুরি সতর্কতাগুলি বিতরণ করা হয়৷ যখন একটি জরুরি সেল সম্প্রচার প্রাপ্ত হয় তখন ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার ডিভাইসের কার্য সম্পাদনা বা কার্যকলাপে প্রতিবন্ধকতার সৃষ্টি করতে পারে৷"</string>
-    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"গ্রাহক হিসাবে নেওয়া ফিডগুলি পড়ে"</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"গ্রাহক হিসেবে নেওয়া ফিডগুলি পড়ে"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"অ্যাপ্লিকেশানকে বর্তমানে সিঙ্ক করা ফিডগুলির সম্পর্কে বিবরণ পেতে দেয়৷"</string>
     <string name="permlab_sendSms" msgid="7544599214260982981">"SMS পাঠানো ও দেখা,আপনি কি পরিচিতি কে এগুলি করার অনুমতি দেবেন?"</string>
-    <string name="permdesc_sendSms" msgid="7094729298204937667">"অ্যাপ্লিকেশানটিকে এসএমএসগুলি পাঠাতে অনুমতি দেয়৷ এর জন্য অপ্রত্যাশিত চার্জ কাটা হতে পারে৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার নিশ্চিতকরণ ছাড়া বার্তা পাঠানোর মাধ্যমে আপনাকে অর্থ চার্জ করতে পারে৷"</string>
-    <string name="permlab_readSms" msgid="8745086572213270480">"আপনার পাঠ্য বার্তা পড়ুন (SMS বা MMS)"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"এই অ্যাপটি আপনার ট্যাবলেটে সংরক্ষিত সমস্ত SMS (পাঠ্য) বার্তা পড়তে পারে৷"</string>
-    <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"এই অ্যাপটি আপনার টিভিতে সংরক্ষিত সমস্ত SMS (পাঠ্য) বার্তা পড়তে পারে৷"</string>
-    <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"এই অ্যাপটি আপনার ফোনে সংরক্ষিত সমস্ত SMS (পাঠ্য) বার্তা পড়তে পারে৷"</string>
-    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"পাঠ্য বার্তা পান (WAP)"</string>
-    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"অ্যাপ্লিকেশানটিকে WAP বার্তা প্রাপ্ত করার এবং প্রক্রিয়া করার অনুমতি দেয়৷ এর মানে হল অ্যাপ্লিকেশানটি আপনার ডিভাইস থেকে পাঠানো বার্তাগুলিকে পর্যবেক্ষণ করতে পারে এবং মুছতে পারে সেগুলিকে আপনাকে না দেখিয়ে৷"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"অ্যাপ্লিকেশানটিকে এসএমএসগুলি পাঠাতে অনুমতি দেয়৷ এর জন্য অপ্রত্যাশিত চার্জ কাটা হতে পারে৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার নিশ্চিতকরণ ছাড়া মেসেজ পাঠানোর মাধ্যমে আপনাকে অর্থ চার্জ করতে পারে৷"</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"আপনার টেক্সট মেসেজ পড়ুন (SMS বা MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"এই অ্যাপটি আপনার ট্যাবলেটে স্টোর করা সমস্ত SMS (টেক্সট) মেসেজ পড়তে পারে৷"</string>
+    <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"এই অ্যাপটি আপনার টিভিতে স্টোর করা সমস্ত SMS (টেক্সট) মেসেজ পড়তে পারে৷"</string>
+    <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"এই অ্যাপটি আপনার ফোনে স্টোর করা সমস্ত SMS (টেক্সট) মেসেজ পড়তে পারে৷"</string>
+    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"টেক্সট মেসেজ পান (WAP)"</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"অ্যাপ্লিকেশানটিকে WAP মেসেজ প্রাপ্ত করার এবং প্রক্রিয়া করার অনুমতি দেয়৷ এর মানে হল অ্যাপ্লিকেশানটি আপনার ডিভাইস থেকে পাঠানো মেসেজগুলিকে পর্যবেক্ষণ করতে পারে এবং মুছতে পারে সেগুলিকে আপনাকে না দেখিয়ে৷"</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"চলমান অ্যাপ্লিকেশান উদ্ধার করে"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"বর্তমানে ও সাম্প্রতিককালের সক্রিয় ক্রিয়াগুলি সম্বন্ধে তথ্য পুনরুদ্ধার করতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷ এছাড়া এটি ডিভাইসটিতে কোন অ্যাপ্লিকেশানগুলি ব্যবহৃত হচ্ছে তার বিষয়ে তথ্য খুঁজে বের করতে অ্যাপ্লিকেশানটিকে মঞ্জুর করতে পারে৷"</string>
     <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"প্রোফাইল এবং ডিভাইস মালিকদের পরিচালনা করুন"</string>
@@ -357,21 +356,21 @@
     <string name="permlab_writeSettings" msgid="2226195290955224730">"সিস্টেম সেটিংস পরিবর্তন করুন"</string>
     <string name="permdesc_writeSettings" msgid="7775723441558907181">"অ্যাপ্লিকেশানকে সিস্টেমের সেটিংস ডেটা সংশোধন করতে দেয়৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার সিস্টেমের কনফিগারেশন নষ্ট করতে পারে৷"</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"প্রারম্ভেই চালান"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"অ্যাপ্লিকেশানকে সিস্টেম বুট হওযার পরে নিজেথেকে শুরু হওয়ার অনুমতি দেয়৷ এটির ফলে আপনার ট্যাবলেট চালু হতে আরো বেশি সময় নিতে পারে এবং অ্যাপ্লিকেশানটিকে সারাক্ষণ চালু রেখে আপনার ট্যাবলেটের সমগ্রিক গতীশীলতাকে ধীর করে৷"</string>
-    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"অ্যাপ্লিকেশানকে সিস্টেম বুট হওযার পরে নিজেথেকে শুরু হওয়ার অনুমতি দেয়৷ এটির ফলে আপনার ফোন চালু হতে আরো বেশি সময় নিতে পারে এবং অ্যাপ্লিকেশানটিকে সারাক্ষণ চালু রেখে আপনার টিভির সামগ্রিক গতীশীলতাকে ধীর করে৷"</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"অ্যাপ্লিকেশানকে সিস্টেম বুট হওযার পরে নিজেথেকে শুরু হওয়ার অনুমতি দেয়৷ এটির ফলে আপনার ফোন চালু হতে আরো বেশি সময় নিতে পারে এবং অ্যাপ্লিকেশানটিকে সারাক্ষণ চালু রেখে আপনার ফোনের সমগ্রিক গতীশীলতাকে ধীর করে৷"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"অ্যাপ্লিকেশানকে সিস্টেম বুট হওযার পরে নিজেথেকে শুরু হওয়ার অনুমতি দেয়৷ এটির ফলে আপনার ট্যাবলেট চালু হতে আরও বেশি সময় নিতে পারে এবং অ্যাপ্লিকেশানটিকে সারাক্ষণ চালু রেখে আপনার ট্যাবলেটের সমগ্রিক গতীশীলতাকে ধীর করে৷"</string>
+    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"অ্যাপ্লিকেশানকে সিস্টেম বুট হওযার পরে নিজেথেকে শুরু হওয়ার অনুমতি দেয়৷ এটির ফলে আপনার ফোন চালু হতে আরও বেশি সময় নিতে পারে এবং অ্যাপ্লিকেশানটিকে সারাক্ষণ চালু রেখে আপনার টিভির সামগ্রিক গতীশীলতাকে ধীর করে৷"</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"অ্যাপ্লিকেশানকে সিস্টেম বুট হওযার পরে নিজেথেকে শুরু হওয়ার অনুমতি দেয়৷ এটির ফলে আপনার ফোন চালু হতে আরও বেশি সময় নিতে পারে এবং অ্যাপ্লিকেশানটিকে সারাক্ষণ চালু রেখে আপনার ফোনের সমগ্রিক গতীশীলতাকে ধীর করে৷"</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"স্টিকি সম্প্রচার পাঠায়"</string>
     <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"স্টিকি সম্প্রচারগুলি পাঠাতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে, যা সম্প্রচার শেষ হয়ে যাওয়ার পরও উপলব্ধ থাকে৷ খুব বেশি পরিমাণে ব্যবহার করার ফলে ট্যাবলেটটিকে ধীরগতির করে দিতে পারে অথবা খুব বেশি পরিমাণ মেমরি ব্যবহারের ফলে এটি যথাযথভাবে কাজ নাও করতে পারে৷"</string>
     <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"অ্যাপ্লিকেশানটিকে স্টিকি সম্প্রচারগুলি পাঠানোর অনুমতি দেয়, যা সম্প্রচার শেষ হওয়ার পরেও থাকে৷ অত্যধিক ব্যবহার টিভিকে ধীর বা ভারসাম্যহীন করে দিতে পারে খুব বেশি মেমোরি ব্যবহারের ফলেই এটি হয়ে থাকে৷"</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"স্টিকি সম্প্রচারগুলি পাঠাতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে, যা সম্প্রচার শেষ হয়ে যাওয়ার পরও উপলব্ধ থাকে৷ খুব বেশি পরিমাণে ব্যবহার করার ফলে ফোনটিকে ধীরগতির করে দিতে পারে অথবা খুব বেশি পরিমাণ মেমরি ব্যবহারের ফলে এটি যথাযথভাবে কাজ নাও করতে পারে৷"</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"আপনার পরিচিতিগুলি পড়ুন"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"অ্যাপ্লিকেশানটিকে আপনি নির্দিষ্ট একজন স্বতন্ত্র ব্যক্তির সঙ্গে ফ্রিকোয়েন্সি দিয়ে কল, ইমেল বা যোগাযোগ করেছেন তা সহ আপনার ট্যাবলেটে সঞ্চিত পরিচিতিগুলি সম্পর্কে ডেটা পড়তে অনুমতি দেয়৷ এই অনুমতি অ্যাপ্লিকেশানগুলিকে আপনার পরিচিতি ডেটা সংরক্ষণ করতে দেয় এবং ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনাকে না জানিয়ে পরিচিতি ডেটা শেয়ার করতে পারে৷"</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"অ্যাপ্লিকেশনটিকে আপনি নির্দিষ্ট একজন স্বতন্ত্র ব্যক্তির সঙ্গে ফ্রিকোয়েন্সি দিয়ে কল, ইমেল বা যোগাযোগ করেছেন তা সহ আপনার ট্যাবলেটে সঞ্চিত পরিচিতিগুলি সম্পর্কে ডেটা পড়তে অনুমতি দেয়৷ এই অনুমতি অ্যাপ্লিকেশনগুলিকে আপনার পরিচিতি ডেটা সংরক্ষণ করতে দেয় এবং ক্ষতিকারক অ্যাপ্লিকেশনগুলি আপনাকে না জানিয়ে পরিচিতি ডেটা ভাগ করতে পারে৷"</string>
     <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"অ্যাপ্লিকেশানটিকে কোনো বিশেষ ব্যক্তির সাথে আপনি কত ঘন ঘন কল, ইমেল বা অন্যভাবে যোগাযোগ করেন সেইরূপ তথ্য সমেত আপনার টিভিতে সংরক্ষিত পরিচিতিগুলির সম্পর্কে ডেটা পড়ার অনুমতি দেয়৷ এই অনুমতিটি অ্যাপ্লিকেশানগুলিকে আপনার পরিচিতি ডেটা সংরক্ষণ করার অনুমতি দেয়, এবং ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার অজান্তে পরিচিতি ডেটা শেয়ার করতে পারে৷"</string>
-    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"অ্যাপ্লিকেশানটিকে আপনি নির্দিষ্ট একজন স্বতন্ত্র ব্যক্তির সঙ্গে ফ্রিকোয়েন্সি দিয়ে কল, ইমেল বা যোগাযোগ করেছেন তা সহ আপনার ফোনে সঞ্চিত পরিচিতিগুলি সম্পর্কে ডেটা পড়তে অনুমতি দেয়৷ এই অনুমতি অ্যাপ্লিকেশানগুলিকে আপনার পরিচিতি ডেটা সংরক্ষণ করতে দেয় এবং ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনাকে না জানিয়ে পরিচিতি ডেটা শেয়ার করতে পারে৷"</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"অ্যাপ্লিকেশনটিকে আপনি নির্দিষ্ট একজন স্বতন্ত্র ব্যক্তির সঙ্গে ফ্রিকোয়েন্সি দিয়ে কল, ইমেল বা যোগাযোগ করেছেন তা সহ আপনার ফোনে সঞ্চিত পরিচিতিগুলি সম্পর্কে ডেটা পড়তে অনুমতি দেয়৷ এই অনুমতি অ্যাপ্লিকেশনগুলিকে আপনার পরিচিতি ডেটা সংরক্ষণ করতে দেয় এবং ক্ষতিকারক অ্যাপ্লিকেশনগুলি আপনাকে না জানিয়ে পরিচিতি ডেটা ভাগ করতে পারে৷"</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"আপনার পরিচিতিগুলি সংশোধন করুন"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"অ্যাপ্লিকেশানটিকে আপনি নির্দিষ্ট একজন পরিচিতির সঙ্গে যে ফ্রিকোয়েন্সিতে কল, ইমেল বা যোগাযোগ করেছেন তা সহ আপনার ট্যাবলেটে সঞ্চিত পরিচিতিগুলি সম্পর্কে ডেটা পরিবর্তন করতে অনুমতি দেয়৷ এই অনুমতি অ্যাপ্লিকেশানগুলিকে আপনার পরিচিতি ডেটা মুছতে দেয়৷"</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"অ্যাপ্লিকেশনটিকে আপনি নির্দিষ্ট একজন পরিচিতির সঙ্গে যে ফ্রিকোয়েন্সিতে কল, ইমেল বা যোগাযোগ করেছেন তা সহ আপনার ট্যাবলেটে সঞ্চিত পরিচিতিগুলি সম্পর্কে ডেটা পরিবর্তন করতে অনুমতি দেয়৷ এই অনুমতি অ্যাপ্লিকেশনগুলিকে আপনার পরিচিতি ডেটা মুছতে দেয়৷"</string>
     <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"অ্যাপ্লিকেশানটিকে কোনো বিশেষ পরিচিতির সাথে আপনি কত ঘন ঘন কল, ইমেল বা অন্যভাবে যোগাযোগ করেন সেইরূপ তথ্য সমেত আপনার টিভিতে সংরক্ষিত পরিচিতিগুলির সম্পর্কে ডেটা পড়ার অনুমতি দেয়৷ এই অনুমতিটি অ্যাপ্লিকেশানগুলিকে পরিচিতির ডেটা মোছার অনুমতি দেয়৷"</string>
-    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"অ্যাপ্লিকেশানটিকে আপনি নির্দিষ্ট একজন পরিচিতির সঙ্গে যে ফ্রিকোয়েন্সিতে কল, ইমেল বা যোগাযোগ করেছেন তা সহ আপনার ফোনে সঞ্চিত পরিচিতিগুলি সম্পর্কে ডেটা পরিবর্তন করতে অনুমতি দেয়৷ এই অনুমতি অ্যাপ্লিকেশানগুলিকে আপনার পরিচিতি ডেটা মুছতে দেয়৷"</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"অ্যাপ্লিকেশনটিকে আপনি নির্দিষ্ট একজন পরিচিতির সঙ্গে যে ফ্রিকোয়েন্সিতে কল, ইমেল বা যোগাযোগ করেছেন তা সহ আপনার ফোনে সঞ্চিত পরিচিতিগুলি সম্পর্কে ডেটা পরিবর্তন করতে অনুমতি দেয়৷ এই অনুমতি অ্যাপ্লিকেশনগুলিকে আপনার পরিচিতি ডেটা মুছতে দেয়৷"</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"কল লগ পড়ুন"</string>
     <string name="permdesc_readCallLog" msgid="3204122446463552146">"এই অ্যাপটি আপনার কলের ইতিহাস পড়তে পারে৷"</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"কল লগ লিখুন"</string>
@@ -385,29 +384,29 @@
     <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"এই অ্যাপটি আপনার টিভিতে সংরক্ষিত সমস্ত ক্যালেন্ডার ইভেন্ট পড়তে এবং আপনার ক্যালেন্ডারের ডেটা শেয়ার বা সংরক্ষণ করতে পারে৷"</string>
     <string name="permdesc_readCalendar" product="default" msgid="4373978642145196715">"এই অ্যাপটি আপনার ফোনে সংরক্ষিত সমস্ত ক্যালেন্ডার ইভেন্ট পড়তে এবং আপনার ক্যালেন্ডারের ডেটা শেয়ার বা সংরক্ষণ করতে পারে৷"</string>
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"ক্যালেন্ডারে ইভেন্ট যোগ বা পরিবর্তন করে এবং মালিকদের অজ্ঞাতেই অতিথিদের ইমেল পাঠায়"</string>
-    <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"এই অ্যাপটি আপনার ট্যাবলেটে ক্যালেন্ডার ইভেন্টগুলি যোগ করতে, সরাতে বা পরিবর্তিত করতে পারে৷ এই অ্যাপটি বার্তা পাঠাতে পারে যা ক্যালেন্ডারের মাললিকের থেকে এসেছে বলে মনে হয় বা ইভেন্টগুলিকে তাদের মালিকদের না জানিয়েই পরিবর্তিত করতে পারে৷"</string>
-    <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"এই অ্যাপটি আপনার টিভিতে ক্যালেন্ডার ইভেন্টগুলি যোগ করতে, সরাতে বা পরিবর্তিত করতে পারে৷ এই অ্যাপটি বার্তা পাঠাতে পারে যা ক্যালেন্ডারের মাললিকের থেকে এসেছে বলে মনে হয় বা ইভেন্টগুলিকে তাদের মালিকদের না জানিয়েই পরিবর্তিত করতে পারে৷"</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"এই অ্যাপটি আপনার ফোনে ক্যালেন্ডার ইভেন্টগুলি যোগ করতে, সরাতে বা পরিবর্তিত করতে পারে৷ এই অ্যাপটি বার্তা পাঠাতে পারে যা ক্যালেন্ডারের মাললিকের থেকে এসেছে বলে মনে হয় বা ইভেন্টগুলিকে তাদের মালিকদের না জানিয়েই পরিবর্তিত করতে পারে৷"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"এই অ্যাপটি আপনার ট্যাবলেটে ক্যালেন্ডার ইভেন্টগুলি যোগ করতে, সরাতে বা পরিবর্তিত করতে পারে৷ এই অ্যাপটি মেসেজ পাঠাতে পারে যা ক্যালেন্ডারের মাললিকের থেকে এসেছে বলে মনে হয় বা ইভেন্টগুলিকে তাদের মালিকদের না জানিয়েই পরিবর্তিত করতে পারে৷"</string>
+    <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"এই অ্যাপটি আপনার টিভিতে ক্যালেন্ডার ইভেন্টগুলি যোগ করতে, সরাতে বা পরিবর্তিত করতে পারে৷ এই অ্যাপটি মেসেজ পাঠাতে পারে যা ক্যালেন্ডারের মাললিকের থেকে এসেছে বলে মনে হয় বা ইভেন্টগুলিকে তাদের মালিকদের না জানিয়েই পরিবর্তিত করতে পারে৷"</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"এই অ্যাপটি আপনার ফোনে ক্যালেন্ডার ইভেন্টগুলি যোগ করতে, সরাতে বা পরিবর্তিত করতে পারে৷ এই অ্যাপটি মেসেজ পাঠাতে পারে যা ক্যালেন্ডারের মাললিকের থেকে এসেছে বলে মনে হয় বা ইভেন্টগুলিকে তাদের মালিকদের না জানিয়েই পরিবর্তিত করতে পারে৷"</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"অতিরিক্ত অবস্থান প্রদানকারী কমান্ডগুলি অ্যাক্সেস করে"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"অবস্থানের সাথে সম্পর্কিত তথ্য প্রদানকারীর অতিরিক্ত কম্যান্ডগুলিকে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷ এটি অ্যাপ্লিকেশানটিকে GPS অথবা অন্যান্য অবস্থান নির্ণয়ের সাথে সম্পর্কিত উৎসগুলির ক্রিয়াপ্রণালীর নিয়ন্ত্রণকে মঞ্জুর করতে পারে৷"</string>
     <string name="permlab_accessFineLocation" msgid="251034415460950944">"সুনির্দিষ্ট অবস্থান (GPS এবং নেটওয়ার্ক-ভিত্তিক) অ্যাক্সেস করুন"</string>
-    <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"মোবাইল টাওয়ার এবং ওয়াই-ফাই নেটওয়ার্কগুলির মত নেটওয়ার্ক অবস্থান উৎসগুলি বা GPS এর উপর ভিত্তি করে এই অ্যাপটি আপনার অবস্থান সনাক্ত করতে পারে৷ এই অবস্থান পরিষেবাগুলি অবশ্যই চালু রাখতে হবে এবং অ্যাপটি যাতে সেগুলি ব্যবহার করতে পারে সেজন্য সেগুলিকে আপনার ফোনে উপলব্ধ করে রাখতে হবে৷ এর জন্য অতিরিক্ত ব্যাটারি খরচ হতে পারে৷"</string>
+    <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"মোবাইল টাওয়ার এবং ওয়াই-ফাই নেটওয়ার্কগুলির মত নেটওয়ার্ক লোকেশন উৎসগুলি বা GPS এর উপর ভিত্তি করে এই অ্যাপটি আপনার লোকেশন সনাক্ত করতে পারে৷ এই লোকেশন পরিষেবাগুলি অবশ্যই চালু রাখতে হবে এবং অ্যাপটি যাতে সেগুলি ব্যবহার করতে পারে সেজন্য সেগুলিকে আপনার ফোনে উপলব্ধ করে রাখতে হবে৷ এর জন্য অতিরিক্ত ব্যাটারি খরচ হতে পারে৷"</string>
     <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"আনুমানিক অবস্থান (নেটওয়ার্ক-ভিত্তিক) অ্যাক্সেস করুন"</string>
-    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"মোবাইল টাওয়ার এবং ওয়াই-ফাই নেটওয়ার্কগুলির মত নেটওয়ার্ক উৎসগুলির উপর ভিত্তি করে এই অ্যাপটি আপনার অবস্থান সনাক্ত করতে পারে৷ এই অবস্থান পরিষেবাগুলি অবশ্যই চালু রাখতে হবে এবং অ্যাপটি যাতে সেগুলি ব্যবহার করতে পারে সেজন্য সেগুলিকে আপনার ট্যাবলেটে উপলব্ধ করে রাখতে হবে৷"</string>
-    <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"মোবাইল টাওয়ার এবং ওয়াই-ফাই নেটওয়ার্কগুলির মত নেটওয়ার্কের উৎসগুলির উপর ভিত্তি করে এই অ্যাপটি আপনার অবস্থান সনাক্ত করতে পারে৷ এই অবস্থান পরিষেবাগুলি অবশ্যই চালু রাখতে হবে এবং অ্যাপটি যাতে সেগুলি ব্যবহার করতে পারে সেজন্য সেগুলিকে আপনার টিভিতে উপলব্ধ করে রাখতে হবে৷"</string>
-    <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"মোবাইল টাওয়ার এবং ওয়াই-ফাই নেটওয়ার্কগুলির মত নেটওয়ার্ক উৎসগুলির উপর ভিত্তি করে এই অ্যাপটি আপনার অবস্থান সনাক্ত করতে পারে৷ এই অবস্থান পরিষেবাগুলি অবশ্যই চালু রাখতে হবে এবং অ্যাপটি যাতে সেগুলি ব্যবহার করতে পারে সেজন্য সেগুলিকে আপনার ফোনে উপলব্ধ করে রাখতে হবে৷"</string>
+    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"মোবাইল টাওয়ার এবং ওয়াই-ফাই নেটওয়ার্কগুলির মত নেটওয়ার্ক উৎসগুলির উপর ভিত্তি করে এই অ্যাপটি আপনার লোকেশন সনাক্ত করতে পারে৷ এই লোকেশন পরিষেবাগুলি অবশ্যই চালু রাখতে হবে এবং অ্যাপটি যাতে সেগুলি ব্যবহার করতে পারে সেইজন্য সেগুলিকে আপনার ট্যাবলেটে উপলব্ধ করে রাখতে হবে৷"</string>
+    <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"মোবাইল টাওয়ার এবং ওয়াই-ফাই নেটওয়ার্কগুলির মত নেটওয়ার্কের উৎসগুলির উপর ভিত্তি করে এই অ্যাপটি আপনার লোকেশন সনাক্ত করতে পারে৷ এই লোকেশন পরিষেবাগুলি অবশ্যই চালু রাখতে হবে এবং অ্যাপটি যাতে সেগুলি ব্যবহার করতে পারে সেজন্য সেগুলিকে আপনার টিভিতে উপলব্ধ করে রাখতে হবে৷"</string>
+    <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"মোবাইল টাওয়ার এবং ওয়াই-ফাই নেটওয়ার্কগুলির মত নেটওয়ার্ক উৎসগুলির উপর ভিত্তি করে এই অ্যাপটি আপনার লোকেশন সনাক্ত করতে পারে৷ এই লোকেশন পরিষেবাগুলি অবশ্যই চালু রাখতে হবে এবং অ্যাপটি যাতে সেগুলি ব্যবহার করতে পারে সেজন্য সেগুলিকে আপনার ফোনে উপলব্ধ করে রাখতে হবে৷"</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"আপনার অডিও সেটিংস পরিবর্তন করে"</string>
-    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"ভলিউম এবং যেখানে স্পিকার আউটপুট সামগ্রী হিসাবে ব্যবহৃত হয় সেই সব ক্ষেত্রে গ্লোবাল অডিও সেটিংসের সংশোধন করতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷"</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"ভলিউম এবং যেখানে স্পিকার আউটপুট হিসাবে ব্যবহৃত হয় সেই সব ক্ষেত্রে গ্লোবাল অডিও সেটিংসের সংশোধন করতে অ্যাপ্লিকেশনটিকে মঞ্জুর করে৷"</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"অডিও রেকর্ড"</string>
     <string name="permdesc_recordAudio" msgid="4245930455135321433">"এই অ্যাপটি মাইক্রোফোন ব্যবহার করে যে কোনো সময় অডিও রেকর্ড করতে পারে৷"</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"সিম এ আদেশগুলি পাঠান"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"অ্যাপ্লিকেশানটিকে সিম কার্ডে কমান্ডগুলি পাঠানোর অনুমতি দেয়৷ এটি খুবই বিপজ্জনক৷"</string>
     <string name="permlab_camera" msgid="3616391919559751192">"ছবি এবং ভিডিও তোলে"</string>
     <string name="permdesc_camera" msgid="5392231870049240670">"এই অ্যাপটি যে কোনো সময় ক্যামেরা ব্যবহার করে ছবি তুলতে বা ভিডিও রেকর্ড করতে পারে৷"</string>
-    <string name="permlab_vibrate" msgid="7696427026057705834">"কম্পন নিয়ন্ত্রণ করুন"</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"ভাইব্রেশন নিয়ন্ত্রণ করুন"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"অ্যাপ্লিকেশানকে কম্পক নিয়ন্ত্রণ করতে দেয়৷"</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"সরাসরি ফোন নম্বরগুলিতে কল করে"</string>
-    <string name="permdesc_callPhone" msgid="3740797576113760827">"অ্যাপ্লিকেশানটিকে আপনার হস্তক্ষেপ ছাড়াই ফোন নম্বরগুলিতে কল করতে মঞ্জুর করে৷ এটি অপ্রত্যাশিত পরিমাণ খরচা বা কলের কারণ হতে পারে৷ মনে রাখবেন, এটি অ্যাপ্লিকেশানটির দ্বারা জরুরি নম্বরগুলিতে কল করাকে অনুমতি দেয় না৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার সম্মতি ছাড়াই কল করার ফলে আপনাকে অহেতুক অর্থ প্রদান করতে হতে পারে৷"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"অ্যাপ্লিকেশানটিকে আপনার হস্তক্ষেপ ছাড়াই ফোন নম্বরগুলিতে কল করতে মঞ্জুর করে৷ এটি অপ্রত্যাশিত পরিমাণ খরচা বা কলের কারণ হতে পারে৷ মনে রাখবেন, এটি অ্যাপ্লিকেশানটির দ্বারা জরুরি নম্বরগুলিতে কল করাকে অনুমতি দেয় না৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার সম্মতি ছাড়াই কল করার ফলে আপনাকে অহেতুক পেমেন্ট করতে হতে পারে৷"</string>
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS পরিষেবাতে অ্যাক্সেস"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"আপনার হস্তক্ষেপ ছাড়াই কল করতে অ্যাপ্লিকেশানটিকে IMS পরিষেবা ব্যবহারের অনুমতি দিন৷"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ফোনের স্থিতি এবং পরিচয় পড়ুন"</string>
@@ -521,7 +520,7 @@
     <string name="permlab_bind_connection_service" msgid="3557341439297014940">"টেলিফোন পরিষেবার সাথে ইন্টারঅ্যাক্ট করুন"</string>
     <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"কল করা/গ্রহণ করার জন্য অ্যাপ্লিকেশনটিকে টেলিফোন পরিষেবার সাথে ইন্টার‌্যাক্ট করার অনুমতি দেয়।"</string>
     <string name="permlab_control_incall_experience" msgid="9061024437607777619">"কলে-থাকা এক ব্যবহারকারী অভিজ্ঞতা সরবরাহ করুন"</string>
-    <string name="permdesc_control_incall_experience" msgid="915159066039828124">"অ্যাপ্লিকেশানটিকে কলে-থাকা এক ব্যবহারকারী অভিজ্ঞতা সরবরাহের অনুমতি দেয়।"</string>
+    <string name="permdesc_control_incall_experience" msgid="915159066039828124">"অ্যাপ্লিকেশনটিকে কলে-থাকা এক ব্যবহারকারী অভিজ্ঞতা সরবরাহের অনুমতি দেয়।"</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"তারিখ অনুযায়ী নেটওয়ার্কের ব্যবহার পড়ে"</string>
     <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"অ্যাপ্লিকেশানটিকে নিদিষ্ট নেটওয়ার্ক এবং অ্যাপ্লিকেশানগুলির জন্য পূর্বের নেটওয়ার্কের ব্যবহার পড়তে দেয়৷"</string>
     <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"নেটওয়ার্ক নীতি পরিচালনা করে"</string>
@@ -576,11 +575,11 @@
     <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"সতর্কীকরণ ছাড়াই এই টিভিতে থাকা ব্যাবহারকার্রী ডেটা মুছে ফেলে৷"</string>
     <string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"সতর্কীকরণ ছাড়াই এই ফোনে থাকা ব্যাবহারকার্রী ডেটা মুছে ফেলে৷"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"ডিভাইসের বৈশ্বিক প্রক্সী সেট করে"</string>
-    <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"নীতিযখন নীতি সক্ষম করা হয় তখন ডিভাইসের বৈশ্বিক প্রক্সী ব্যবহার করা হবে সেই হিসাবে সেট করে৷ শুধুমাত্র ডিভাইসের মালিক বৈশ্বিক প্রক্সী সেট করতে পারেন৷"</string>
+    <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"নীতিযখন নীতি সক্ষম করা হয় তখন ডিভাইসের বৈশ্বিক প্রক্সী ব্যবহার করা হবে সেই হিসেবে সেট করে৷ শুধুমাত্র ডিভাইসের মালিক বৈশ্বিক প্রক্সী সেট করতে পারেন৷"</string>
     <string name="policylab_expirePassword" msgid="5610055012328825874">"স্ক্রিন লক করার জন্য পাসওয়ার্ডের মেয়াদ শেষ হওয়ার সময় সেট করে"</string>
     <string name="policydesc_expirePassword" msgid="5367525762204416046">"স্ক্রিন লক করার পাসওয়ার্ড কত ঘন ঘন পরিবর্তন করা আবশ্যক তা পরিবর্তন করুন৷"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"সঞ্চয়স্থানের এনক্রিপশান সেট করে"</string>
-    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"এই সঞ্চিত অ্যাপ্লিকেশান ডেটা এনক্রিপ্ট করা দরকার৷"</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"এই সঞ্চিত অ্যাপ্লিকেশন ডেটা এনক্রিপ্ট করা দরকার৷"</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"ক্যামেরাগুলি অক্ষম করে"</string>
     <string name="policydesc_disableCamera" msgid="2306349042834754597">"সমস্ত ডিভাইসের ক্যামেরার ব্যবহার আটকায়৷"</string>
     <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"কিছু স্ক্রিন লক বৈশিষ্ট্য অক্ষম করুন"</string>
@@ -748,9 +747,9 @@
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করে আপনার আনলক প্যাটার্ন অঙ্কিত করেছেন৷ আপনি <xliff:g id="NUMBER_1">%2$d</xliff:g>টি অসফল প্রচেষ্টার পরে, আপনাকে Google এ প্রবেশ করে আপনার ট্যাবলেট আনলক করার কথা বলা হবে৷\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ড পরে আবার চেষ্টা করুন৷"</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করে আপনার আনলক প্যাটার্ন অঙ্কিত করেছেন৷ আপনি <xliff:g id="NUMBER_1">%2$d</xliff:g>টি অসফল প্রচেষ্টার পরে, আপনাকে Google এ প্রবেশ করে আপনার টিভি আনলক করার কথা বলা হবে৷\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ড পরে আবার চেষ্টা করুন৷"</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করে আপনার আনলক প্যাটার্ন অঙ্কিত করেছেন৷ আপনি <xliff:g id="NUMBER_1">%2$d</xliff:g>টি অসফল প্রচেষ্টার পরে, আপনাকে Google এ প্রবেশ করে আপনার ফোন আনলক করার কথা বলা হবে৷\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ড পরে আবার চেষ্টা করুন৷"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন৷ আরো <xliff:g id="NUMBER_1">%2$d</xliff:g>টি অসফল চেষ্টার পরে, ট্যাবলেটটি ফ্যাক্টরী ডিফল্টে রিসেট হবে এবং ব্যবহারকারীর সমস্ত ডেটা মুছে যাবে৷"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন৷ আরও <xliff:g id="NUMBER_1">%2$d</xliff:g>টি অসফল চেষ্টার পরে, ট্যাবলেটটি ফ্যাক্টরী ডিফল্টে রিসেট হবে এবং ব্যবহারকারীর সমস্ত ডেটা মুছে যাবে৷"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করে টিভি আনলক করার চেষ্টা করেছেন৷ <xliff:g id="NUMBER_1">%2$d</xliff:g>টি অসফল প্রচেষ্টার পরে, আপনার টিভি ফ্যাক্টরি ডিফল্টে পুনঃসেট হবে এবং সমস্ত ব্যবহারকারীর ডেটা মুছে যাবে৷"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করে ফোনটি আনলক করার চেষ্টা করেছেন৷ আরো <xliff:g id="NUMBER_1">%2$d</xliff:g>টি অসফল চেষ্টার পরে, ফোনটি ফ্যাক্টরী ডিফল্টে রিসেট হবে এবং ব্যবহারকারীর সমস্ত ডেটা মুছে যাবে৷"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করে ফোনটি আনলক করার চেষ্টা করেছেন৷ আরও <xliff:g id="NUMBER_1">%2$d</xliff:g>টি অসফল চেষ্টার পরে, ফোনটি ফ্যাক্টরী ডিফল্টে রিসেট হবে এবং ব্যবহারকারীর সমস্ত ডেটা মুছে যাবে৷"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুল করে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন৷ ট্যাবলেটটি এখন ফ্যাক্টরী ডিফল্টে রিসেট হবে৷"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুল করে টিভি আনলক করার চেষ্টা করেছেন৷ টিভি এখন ফ্যাক্টরি ডিফল্টে পুনঃসেট হবে৷"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুল করে ফোনটি আনলক করার চেষ্টা করেছেন৷ ফোনটি এখন ফ্যাক্টরী ডিফল্টে রিসেট হবে৷"</string>
@@ -761,9 +760,9 @@
     <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"আনলক করতে আপনার Google অ্যাকাউন্টের মাধ্যমে প্রবেশ করুন৷"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"ব্যবহারকারীনাম (ইমেল)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"পাসওয়ার্ড"</string>
-    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"প্রবেশ করুন"</string>
-    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"অবৈধ ব্যবহারকারী নাম অথবা পাসওয়ার্ড৷"</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"আপনার ব্যবহারকারী নাম অথবা পাসওয়ার্ড ভুলে গেছেন?\n"<b>"google.com/accounts/recovery"</b>" এ যান৷"</string>
+    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"সাইন-ইন করুন"</string>
+    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"অবৈধ ইউজারনেম অথবা পাসওয়ার্ড৷"</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"আপনার ইউজারনেম অথবা পাসওয়ার্ড ভুলে গেছেন?\n"<b>"google.com/accounts/recovery"</b>" এ যান৷"</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"পরীক্ষা করা হচ্ছে..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"আনলক করুন"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"শব্দ চালু আছে"</string>
@@ -805,7 +804,7 @@
     <string name="factorytest_failed" msgid="5410270329114212041">"ফ্যাক্টরী পরীক্ষা ব্যর্থ হয়েছে"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST ক্রিয়াটি শুধুমাত্র /system/app এ ইনস্টল থাকা প্যাকেজগুলি সমর্থন করে৷"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"এমন কোনো প্যাকেজ খুঁজে পাওয়া যায়নি যা FACTORY_TEST ক্রিয়া প্রদান করে৷"</string>
-    <string name="factorytest_reboot" msgid="6320168203050791643">"পুনরায় চালু করুন"</string>
+    <string name="factorytest_reboot" msgid="6320168203050791643">"রিবুট করুন"</string>
     <string name="js_dialog_title" msgid="1987483977834603872">"\"<xliff:g id="TITLE">%s</xliff:g>\" পৃষ্ঠা অনুসারে:"</string>
     <string name="js_dialog_title_default" msgid="6961903213729667573">"জাভাস্ক্রিপ্ট"</string>
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"বেরিয়ে যাওয়া নিশ্চিত করুন"</string>
@@ -835,13 +834,13 @@
     <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"আপনার ওয়েব বুকমার্কগুলি এবং ইতিহাস পড়ুন"</string>
     <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"অ্যাপ্লিকেশানটিকে ব্রাউজার দ্বারা ঘুরে দেখা সমস্ত URL এর ইতিহাস এবং ব্রাউজারের বুকমার্কগুলি পড়ার অনুমতি দেয়৷ দ্রষ্টব্য: এই অনুমতিটি তৃতীয় পক্ষের ব্রাউজার বা ওয়েব ব্রাউজিং ক্ষমতা সহ অন্যান্য অ্যাপ্লিকেশানগুলিতে জারি করা সম্ভব নাও হতে পারে৷"</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"ওয়েব বুকমার্কগুলি এবং ইতিহাস লিখুন"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"অ্যাপ্লিকেশানটিকে আপনার ট্যাবলেটে সঞ্চিত ব্রাউজারের ইতিহাস বা বুকমার্কগুলি পরিবর্তন করতে দেয়৷ এটি অ্যাপ্লিকেশানটিকে ব্রাউজার ডেটা মুছে দিতে বা পরিবর্তন করতে দেয়৷ দ্রষ্টব্য: এই অনুমতি তৃতীয় পক্ষের ব্রাউজারগুলির বা ওয়েব ব্রাউজিং ক্ষমতা সম্পন্ন অন্যান্য অ্যাপ্লিকেশানগুলি দ্বারা বলবৎ নাও হতে পারে৷"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"অ্যাপ্লিকেশনটিকে আপনার ট্যাবলেটে সঞ্চিত ব্রাউজারের ইতিহাস বা বুকমার্কগুলি পরিবর্তন করতে দেয়৷ এটি অ্যাপ্লিকেশনটিকে ব্রাউজার ডেটা মুছে দিতে বা পরিবর্তন করতে দেয়৷ দ্রষ্টব্য: এই অনুমতি তৃতীয় পক্ষের ব্রাউজারগুলির বা ওয়েব ব্রাউজিং ক্ষমতা সম্পন্ন অন্যান্য অ্যাপ্লিকেশনগুলি দ্বারা বলবৎ নাও হতে পারে৷"</string>
     <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"অ্যাপ্লিকেশানকে আপনার টিভিতে সংরক্ষিত ব্রাউজারের ইতিহাস বা বুকমার্কগুলি সংশোধন করার অনুমতি দেয়৷ এটি অ্যাপ্লিকেশানটিকে ব্রাউজারের ডেটা মোছার বা সংশোধন করার অনুমতি দেয়৷ দ্রষ্টব্য: তৃতীয়-পক্ষের ব্রাউজার বা অন্য ওয়েব ব্রাউজিং করার সক্ষমতা রয়েছে এমন অন্য অ্যাপ্লিকেশানগুলির অনুসারে প্রয়োগ হতে পারে৷"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"অ্যাপ্লিকেশানটিকে আপনার ফোনে সঞ্চিত ব্রাউজারের ইতিহাস বা বুকমার্কগুলি পরিবর্তন করতে দেয়৷ এটি অ্যাপ্লিকেশানটিকে ব্রাউজার ডেটা মুছে দিতে বা পরিবর্তন করতে দেয়৷ দ্রষ্টব্য: এই অনুমতি তৃতীয় পক্ষের ব্রাউজারগুলির বা ওয়েব ব্রাউজিং ক্ষমতা সম্পন্ন অন্যান্য অ্যাপ্লিকেশানগুলি দ্বারা বলবৎ নাও হতে পারে৷"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"অ্যাপ্লিকেশনটিকে আপনার ফোনে সঞ্চিত ব্রাউজারের ইতিহাস বা বুকমার্কগুলি পরিবর্তন করতে দেয়৷ এটি অ্যাপ্লিকেশনটিকে ব্রাউজার ডেটা মুছে দিতে বা পরিবর্তন করতে দেয়৷ দ্রষ্টব্য: এই অনুমতি তৃতীয় পক্ষের ব্রাউজারগুলির বা ওয়েব ব্রাউজিং ক্ষমতা সম্পন্ন অন্যান্য অ্যাপ্লিকেশনগুলি দ্বারা বলবৎ নাও হতে পারে৷"</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"একটি অ্যালার্ম সেট করুন"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"অ্যাপ্লিকেশানকে একটি ইনস্টল থাকা অ্যালার্ম অ্যাপ্লিকেশানে একটি অ্যালার্ম সেট করতে দেয়৷ কিছু অ্যালার্ম ঘড়ি অ্যাপ্লিকেশানগুলিতে ভবিষ্যতে এটি লাগু নাও হতে পারে৷"</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"ভয়েসমেল যোগ করে"</string>
-    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"অ্যাপ্লিকেশানকে আপনার ভয়েসমেইল ইনবক্সে বার্তা যোগ করার অনুমতি দেয়৷"</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"অ্যাপ্লিকেশানকে আপনার ভয়েসমেইল ইনবক্সে মেসেজ যোগ করার অনুমতি দেয়৷"</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ব্রাউজারের ভূঅবস্থানিক অনুমতিগুলি সংশোধন করে"</string>
     <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"অ্যাপ্লিকেশানকে ব্রাউজারের ভূঅবস্থানিক অনুমতি সংশোধন করতে দেয়৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি নির্বিচারে ওয়েব সাইটগুলিতে অবস্থানের ডেটা পাঠানো সক্ষম করতে এটি ব্যবহার করতে পারে৷"</string>
     <string name="save_password_message" msgid="767344687139195790">"আপনি কি ব্রাউজারে এই পাসওয়ার্ডটি মনে রাখতে চান?"</string>
@@ -850,14 +849,14 @@
     <string name="save_password_never" msgid="8274330296785855105">"কখনই নয়"</string>
     <string name="open_permission_deny" msgid="7374036708316629800">"এই পৃষ্ঠাটি খোলার জন্য আপনার কাছে অনুমতি নেই৷"</string>
     <string name="text_copied" msgid="4985729524670131385">"ক্লিপবোর্ডে পাঠ্য অনুলিপি করা হয়েছে৷"</string>
-    <string name="more_item_label" msgid="4650918923083320495">"আরো"</string>
+    <string name="more_item_label" msgid="4650918923083320495">"আরও"</string>
     <string name="prepend_shortcut_label" msgid="2572214461676015642">"মেনু+"</string>
     <string name="menu_space_shortcut_label" msgid="2410328639272162537">"স্পেস"</string>
     <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
     <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"মুছুন"</string>
-    <string name="search_go" msgid="8298016669822141719">"অনুসন্ধান করুন"</string>
+    <string name="search_go" msgid="8298016669822141719">"খুঁজুন"</string>
     <string name="search_hint" msgid="1733947260773056054">"অনুসন্ধান..."</string>
-    <string name="searchview_description_search" msgid="6749826639098512120">"অনুসন্ধান করুন"</string>
+    <string name="searchview_description_search" msgid="6749826639098512120">"খুঁজুন"</string>
     <string name="searchview_description_query" msgid="5911778593125355124">"অনুসন্ধান ক্যোয়ারী"</string>
     <string name="searchview_description_clear" msgid="1330281990951833033">"ক্যোয়ারী সাফ করুন"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"ক্যোয়ারী জমা দিন"</string>
@@ -964,15 +963,15 @@
     <string name="Midnight" msgid="5630806906897892201">"মধ্যরাত্রি"</string>
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
-    <string name="selectAll" msgid="6876518925844129331">"সবগুলি নির্বাচন করুন"</string>
+    <string name="selectAll" msgid="6876518925844129331">"সবগুলি বেছে নিন"</string>
     <string name="cut" msgid="3092569408438626261">"কাটুন"</string>
     <string name="copy" msgid="2681946229533511987">"অনুলিপি"</string>
-    <string name="paste" msgid="5629880836805036433">"আটকান"</string>
-    <string name="paste_as_plain_text" msgid="5427792741908010675">"প্লেইন টেক্সট হিসাবে আটকান"</string>
+    <string name="paste" msgid="5629880836805036433">"পেস্ট করুন"</string>
+    <string name="paste_as_plain_text" msgid="5427792741908010675">"প্লেন টেক্সট হিসাবে পেস্ট করুন"</string>
     <string name="replace" msgid="5781686059063148930">"প্রতিস্থাপন করুন..."</string>
     <string name="delete" msgid="6098684844021697789">"মুছুন"</string>
     <string name="copyUrl" msgid="2538211579596067402">"URL কপি করুন"</string>
-    <string name="selectTextMode" msgid="1018691815143165326">"পাঠ্য নির্বাচন করুন"</string>
+    <string name="selectTextMode" msgid="1018691815143165326">"পাঠ্য বেছে নিন"</string>
     <string name="undo" msgid="7905788502491742328">"পূর্বাবস্থায় ফিরুন"</string>
     <string name="redo" msgid="7759464876566803888">"আবার করুন"</string>
     <string name="autofill" msgid="3035779615680565188">"আপনাআপনি পূরণ হতে দিন"</string>
@@ -985,11 +984,11 @@
     <string name="dial" msgid="4204975095406423102">"ফোন করুন"</string>
     <string name="map" msgid="6068210738233985748">"মানচিত্র"</string>
     <string name="browse" msgid="6993590095938149861">"ব্রাউজার"</string>
-    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"সঞ্চয়স্থান পূর্ণ হতে চলেছে"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"স্টোরেজ পূর্ণ হতে চলেছে"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"কিছু কিছু সিস্টেম ক্রিয়াকলাপ কাজ নাও করতে পারে"</string>
-    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"সিস্টেমের জন্য যথেষ্ট সঞ্চয়স্থান নেই৷ আপনার কাছে ২৫০MB ফাঁকা স্থান রয়েছে কিনা সে বিষয়ে নিশ্চিত হওয়ার পর আবার চালু করুন৷"</string>
+    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"সিস্টেমের জন্য যথেষ্ট স্টোরেজ নেই৷ আপনার কাছে ২৫০এমবি ফাঁকা স্থান রয়েছে কিনা সে বিষয়ে নিশ্চিত হন এবং সিস্টেম চালু করুন৷"</string>
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> চলছে"</string>
-    <string name="app_running_notification_text" msgid="1197581823314971177">"আরো তথ্যের জন্য বা অ্যাপ্লিকেশানটি বন্ধ করতে আলতো চাপুন।"</string>
+    <string name="app_running_notification_text" msgid="1197581823314971177">"আরও তথ্যের জন্য বা অ্যাপ্লিকেশানটি বন্ধ করতে আলতো চাপুন।"</string>
     <string name="ok" msgid="5970060430562524910">"ঠিক আছে"</string>
     <string name="cancel" msgid="6442560571259935130">"বাতিল করুন"</string>
     <string name="yes" msgid="5362982303337969312">"ঠিক আছে"</string>
@@ -1013,8 +1012,8 @@
     <string name="whichSendToApplication" msgid="8272422260066642057">"এটি ব্যবহার করে পাঠান"</string>
     <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"%1$s ব্যবহার করে পাঠান"</string>
     <string name="whichSendToApplicationLabel" msgid="8878962419005813500">"পাঠান"</string>
-    <string name="whichHomeApplication" msgid="4307587691506919691">"একটি হোম অ্যাপ্লিকেশন নির্বাচন করুন"</string>
-    <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"হোম হিসাবে %1$s ব্যবহার করুন"</string>
+    <string name="whichHomeApplication" msgid="4307587691506919691">"একটি হোম অ্যাপ্লিকেশন বেছে নিন"</string>
+    <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"হোম হিসেবে %1$s ব্যবহার করুন"</string>
     <string name="whichHomeApplicationLabel" msgid="809529747002918649">"ছবি তুলুন"</string>
     <string name="whichImageCaptureApplication" msgid="3680261417470652882">"এই দিয়ে ছবি তুলুন"</string>
     <string name="whichImageCaptureApplicationNamed" msgid="8619384150737825003">"%1$s দিয়ে ছবি তুলুন"</string>
@@ -1056,7 +1055,7 @@
     <string name="smv_process" msgid="5120397012047462446">"প্রক্রিয়াটি <xliff:g id="PROCESS">%1$s</xliff:g> তার স্ব-প্রয়োগ করা কঠোর মোড নীতি লঙ্ঘন করেছে৷"</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"Android আপগ্রেড করা হচ্ছে..."</string>
     <string name="android_start_title" msgid="8418054686415318207">"Android চালু হচ্ছে…"</string>
-    <string name="android_upgrading_fstrim" msgid="8036718871534640010">"সঞ্চয়স্থান অপ্টিমাইজ করা হচ্ছে৷"</string>
+    <string name="android_upgrading_fstrim" msgid="8036718871534640010">"স্টোরেজ অপ্টিমাইজ করা হচ্ছে৷"</string>
     <string name="android_upgrading_notification_title" msgid="8428357096969413169">"Android আপডেট সম্পন্ন করা হচ্ছে…"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"আপগ্রেড সম্পন্ন না হওয়া পর্যন্ত কিছু অ্যাপ্লিকেশান সঠিকভাবে কাজ নাও করতে পারে"</string>
     <string name="app_upgrading_toast" msgid="3008139776215597053">"<xliff:g id="APPLICATION">%1$s</xliff:g> আপগ্রেড করা হচ্ছে…"</string>
@@ -1073,7 +1072,7 @@
     <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> শুরু করুন"</string>
     <string name="new_app_description" msgid="1932143598371537340">"সংরক্ষণ না করেই পুরোনো অ্যাপ্লিকেশানটি বন্ধ করুন৷"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> মেমরি সীমা অতিক্রম করেছে"</string>
-    <string name="dump_heap_notification_detail" msgid="6901391084243999274">"অনেক ডাটা সংগ্রহ করা হয়েছে; শেয়ার করার জন্য আলতো চাপুন"</string>
+    <string name="dump_heap_notification_detail" msgid="6901391084243999274">"অনেক ডেটা সংগ্রহ করা হয়েছে; শেয়ার করার জন্য ট্যাপ করুন"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"হিপ ডাম্প শেয়ার করবেন?"</string>
     <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> প্রক্রিয়াটি তার <xliff:g id="SIZE">%2$s</xliff:g> এর মেমরি সীমা অতিক্রম করেছে৷ তার বিকাশকারীর সাথে শেয়ার করার জন্য একটি হিপ ডাম্প উপলব্ধ৷ সতর্কতা অবলম্বন করুন: এই হিপ ডাম্পে অ্যাপ্লিকেশানটির অ্যাক্সেস আছে এমন আপনার যেকোন ব্যক্তিগত তথ্য থাকতে পারে৷"</string>
     <string name="sendText" msgid="5209874571959469142">"পাঠ্যের জন্য একটি কাজ বেছে নিন"</string>
@@ -1106,8 +1105,15 @@
       <item quantity="one">খোলা ওয়াই-ফাই নেটওয়ার্কগুলি উপলব্ধ রয়েছে</item>
       <item quantity="other">খোলা ওয়াই-ফাই নেটওয়ার্কগুলি উপলব্ধ রয়েছে</item>
     </plurals>
-    <string name="wifi_available_sign_in" msgid="9157196203958866662">"ওয়াই-ফাই নেটওয়ার্কে প্রবেশ করুন"</string>
-    <string name="network_available_sign_in" msgid="1848877297365446605">"নেটওয়ার্কে প্রবেশ করুন"</string>
+    <string name="wifi_available_title" msgid="3817100557900599505">"উন্মুক্ত ওয়াই-ফাই নেটওয়ার্কে সংযোগ করুন"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"উন্মুক্ত ওয়াই-ফাই নেটওয়ার্কে সংযোগ করা হচ্ছে"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"উন্মুক্ত ওয়াই-ফাই নেটওয়ার্কে সংযুক্ত করা হয়েছে"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ওয়াই-ফাই নেটওয়ার্কে সংযোগ করা গেল না"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"সমস্ত নেটওয়ার্ক দেখতে ট্যাপ করুন"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"সংযুক্ত করুন"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"সমস্ত নেটওয়ার্ক"</string>
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"ওয়াই-ফাই নেটওয়ার্কে সাইন-ইন করুন"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"নেটওয়ার্কে সাইন-ইন করুন"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_no_internet" msgid="8451173622563841546">"ওয়াই-ফাই -তে কোনো ইন্টারনেট অ্যাক্সেস নেই"</string>
@@ -1146,10 +1152,10 @@
     <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ফোনটি যখন <xliff:g id="DEVICE_NAME">%1$s</xliff:g> এ সংযুক্ত হবে তখন এটি ওয়াই-ফাই থেকে সাময়িকভাবে সংযোগ বিচ্ছিন্ন হবে"</string>
     <string name="select_character" msgid="3365550120617701745">"অক্ষর ঢোকান"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"এসএমএস পাঠানো হচ্ছে"</string>
-    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; অনেকগুলি এসএমএস পাঠাচ্ছে৷ আপনি কি এই অ্যাপ্লিকেশানটিকে বার্তা পাঠানো চালিয়ে যাওয়ার অনুমতি দিতে চান?"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; অনেকগুলি এসএমএস পাঠাচ্ছে৷ আপনি কি এই অ্যাপ্লিকেশানটিকে মেসেজ পাঠানো চালিয়ে যাওয়ার অনুমতি দিতে চান?"</string>
     <string name="sms_control_yes" msgid="3663725993855816807">"অনুমতি দিন"</string>
     <string name="sms_control_no" msgid="625438561395534982">"আস্বীকার করুন"</string>
-    <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; এ একটি বার্তা পাঠাতে চায়৷"</string>
+    <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; এ একটি মেসেজ পাঠাতে চায়৷"</string>
     <string name="sms_short_code_details" msgid="5873295990846059400">"এটির জন্য আপনার মোবাইল অ্যাকাউন্টে "<b>"চার্জ বহন করতে হতে পারে"</b>"।"</string>
     <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"এর ফলে আপনার মোবাইল অ্যাকাউন্টে চার্জ লাগতে পারে।"</b></string>
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"পাঠান"</string>
@@ -1163,7 +1169,7 @@
     <string name="sim_done_button" msgid="827949989369963775">"সম্পন্ন হয়েছে"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"সিম কার্ড যোগ করা হয়েছে"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"মোবাইল নেটওয়ার্ক অ্যাক্সেস করতে আপনার ডিভাইসটি পুনর্সূচনা করুন৷"</string>
-    <string name="sim_restart_button" msgid="4722407842815232347">"পুনর্সূচনা"</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"রিস্টার্ট করুন"</string>
     <string name="carrier_app_dialog_message" msgid="7066156088266319533">"যাতে আপনার নতুন সিম সঠিকভাবে কাজ করে, তার জন্য আপনাকে আপনার পরিষেবা প্রদানকারীর থেকে একটি অ্যাপ্লিকেশান ইনস্টল করতে এবং খুলতে হবে৷"</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"অ্যাপ্লিকেশানটি পান"</string>
     <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"এখনই নয়"</string>
@@ -1184,7 +1190,9 @@
     <string name="usb_ptp_notification_title" msgid="1347328437083192112">"ফটো স্থানান্তরের জন্য USB"</string>
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI এর জন্য USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"একটি USB যন্ত্রাংশতে সংযুক্ত হয়েছে"</string>
-    <string name="usb_notification_message" msgid="3370903770828407960">"আরো বিকল্পের জন্য আলতো চাপুন৷"</string>
+    <string name="usb_notification_message" msgid="3370903770828407960">"আরও বিকল্পের জন্য আলতো চাপুন৷"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"অ্যানালগ অডিও অ্যাক্সেসরি শনাক্ত করা হয়েছে"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"সংযুক্ত ডিভাইসটি এই ফোনের সাথে ব্যবহার করা যাবে না। আরও জানতে ট্যাপ করুন।"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ডিবাগিং সংযুক্ত হয়েছে"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ডিবাগিং অক্ষম করতে আলতো চাপুন৷"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ডিবাগিং অক্ষম করতে বেছে নিন।"</string>
@@ -1196,9 +1204,9 @@
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"অস্বীকার করুন"</string>
     <string name="select_input_method" msgid="8547250819326693584">"কীবোর্ড পরিবর্তন করুন"</string>
     <string name="show_ime" msgid="2506087537466597099">"ফিজিক্যাল কীবোর্ড সক্রিয় থাকার সময় এটিকে স্ক্রীনে রাখুন"</string>
-    <string name="hardware" msgid="194658061510127999">"ভার্চুয়াল কীবোর্ড দেখান"</string>
+    <string name="hardware" msgid="194658061510127999">"ভার্চুয়াল কীবোর্ড দেখুন"</string>
     <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"ফিজিক্যাল কীবোর্ড কনফিগার করুন"</string>
-    <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ভাষা এবং লেআউট নির্বাচন করুন আলতো চাপ দিন"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ভাষা এবং লেআউট বেছে নিন আলতো চাপ দিন"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"অন্যান্য অ্যাপের উপরে দেখুন"</string>
@@ -1212,10 +1220,10 @@
     <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"ফটো এবং মিডিয়া ট্রান্সফার"</string>
     <string name="ext_media_unmountable_notification_title" msgid="8295123366236989588">"<xliff:g id="NAME">%s</xliff:g> ত্রুটিপূর্ণ"</string>
     <string name="ext_media_unmountable_notification_message" msgid="2343202057122495773">"<xliff:g id="NAME">%s</xliff:g> ত্রুটিপূর্ণ৷ ঠিক করতে আলতো চাপুন৷"</string>
-    <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> ত্রুটিপূর্ণ। মেরামত করতে নির্বাচন করুন।"</string>
+    <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> ত্রুটিপূর্ণ। মেরামত করতে বেছে নিন।"</string>
     <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"<xliff:g id="NAME">%s</xliff:g> অসমর্থিত"</string>
     <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"এই ডিভাইসটি <xliff:g id="NAME">%s</xliff:g> সমর্থন করে না। কোনো সমর্থিত ফর্ম্যাটে সেট আপ করতে আলতো চাপুন।"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"এই ডিভাইসটি <xliff:g id="NAME">%s</xliff:g> সমর্থন করে না। কোনো সমর্থিত ফর্ম্যাটে সেট আপ করতে চাইলে নির্বাচন করুন।"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"এই ডিভাইসটি <xliff:g id="NAME">%s</xliff:g> সমর্থন করে না। কোনো সমর্থিত ফর্ম্যাটে সেট আপ করতে চাইলে বেছে নিন।"</string>
     <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> অপ্রত্যাশিতভাবে মুছে ফেলা হয়েছে"</string>
     <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"ডেটা যাতে হারিয়ে না যায় তার জন্য সরানোর আগে <xliff:g id="NAME">%s</xliff:g> আনমাউন্ট করুন"</string>
     <string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"<xliff:g id="NAME">%s</xliff:g> সরানো হয়েছে"</string>
@@ -1255,10 +1263,10 @@
     <string name="permdesc_requestDeletePackages" msgid="3406172963097595270">"একটি অ্যাপ্লিকেশানকে প্যাকেজগুলি মুছে দেওয়ার অনুরোধ জানাতে দেয়৷"</string>
     <string name="permlab_requestIgnoreBatteryOptimizations" msgid="8021256345643918264">"ব্যাটারি অপ্টিমাইজেশন উপেক্ষা করার জন্য অনুমতি চাওয়া"</string>
     <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="8359147856007447638">"কোনো অ্যাপের জন্য ব্যাটারি অপ্টিমাইজেশন উপেক্ষা করতে সেটিকে অনুমতির চাওয়ার মঞ্জুরি দেয়৷"</string>
-    <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"জুম নিয়ন্ত্রণের জন্য দুবার আলতো চাপুন"</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"জুম নিয়ন্ত্রণের জন্য দুবার ট্যাপ করুন"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"উইজেট যোগ করা যায়নি৷"</string>
     <string name="ime_action_go" msgid="8320845651737369027">"যান"</string>
-    <string name="ime_action_search" msgid="658110271822807811">"অনুসন্ধান করুন"</string>
+    <string name="ime_action_search" msgid="658110271822807811">"খুঁজুন"</string>
     <string name="ime_action_send" msgid="2316166556349314424">"পাঠান"</string>
     <string name="ime_action_next" msgid="3138843904009813834">"পরবর্তী"</string>
     <string name="ime_action_done" msgid="8971516117910934605">"সম্পন্ন হয়েছে"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> তে সংযুক্ত হয়েছে৷ নেটওয়ার্ক পরিচালনা করতে আলতো চাপুন৷"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"সর্বদা-চালু VPN সংযুক্ত হচ্ছে..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"সর্বদা-চালু VPN সংযুক্ত হয়েছে"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"সর্বদা-চালু VPN এর সংযোগ বিচ্ছিন্ন হয়েছে"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"সবসময়-চালু VPN এর সংযোগ বিচ্ছিন্ন আছে"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"সর্বদা-চালু VPN ত্রুটি"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"সেট আপ করতে আলতো চাপুন"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"নেটওয়ার্ক অথবা VPN সেটিংস পরিবর্তন করুন"</string>
     <string name="upload_file" msgid="2897957172366730416">"ফাইল বেছে নিন"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"কোনো ফাইল নির্বাচন করা হয়নি"</string>
     <string name="reset" msgid="2448168080964209908">"আবার সেট করুন"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"গাড়ি মোড থেকে প্রস্থান করতে আলতো চাপুন৷"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"টিথারিং বা হটস্পট সক্রিয় আছে"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"সেট আপ করার জন্য আলতো চাপুন৷"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"টিথারিং অক্ষম করা আছে"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"বিশদ বিবরণের জন্য প্রশাসকের সাথে যোগাযোগ করুন"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ফিরুন"</string>
     <string name="next_button_label" msgid="1080555104677992408">"পরবর্তী"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"এড়িয়ে যান"</string>
@@ -1366,15 +1372,15 @@
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"আনলক করতে সোয়াইপ করুন৷"</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"হোম এ নেভিগেট করুন"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"উপরের দিকে নেভিগেট করুন"</string>
-    <string name="action_menu_overflow_description" msgid="2295659037509008453">"আরো বিকল্প"</string>
+    <string name="action_menu_overflow_description" msgid="2295659037509008453">"আরও বিকল্প"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <string name="storage_internal" msgid="3570990907910199483">"অভ্যন্তরীণ শেয়ার করা সঞ্চয়স্থান"</string>
+    <string name="storage_internal" msgid="3570990907910199483">"ইন্টারনাল শেয়ার করা স্টোরেজ"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD কার্ড"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD কার্ড"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB ড্রাইভ"</string>
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB ড্রাইভ"</string>
-    <string name="storage_usb" msgid="3017954059538517278">"USB সঞ্চয়স্থান"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"USB স্টোরেজ"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"সম্পাদনা করুন"</string>
     <string name="data_usage_warning_title" msgid="3620440638180218181">"ডেটা ব্যবহারের সতর্কতা"</string>
     <string name="data_usage_warning_body" msgid="6660692274311972007">"ব্যবহার এবং সেটিংস দেখতে আলতো চাপুন৷"</string>
@@ -1390,7 +1396,7 @@
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"নির্দিষ্ট সীমার থেকে <xliff:g id="SIZE">%s</xliff:g> বেশি৷"</string>
     <string name="data_usage_restricted_title" msgid="5965157361036321914">"পটভূমি ডেটা সীমিত করা আছে"</string>
     <string name="data_usage_restricted_body" msgid="469866376337242726">"সীমাবদ্ধতা সরাতে আলতো চাপুন৷"</string>
-    <string name="ssl_certificate" msgid="6510040486049237639">"নিরাপত্তার শংসাপত্র"</string>
+    <string name="ssl_certificate" msgid="6510040486049237639">"নিরাপত্তার সার্টিফিকেট"</string>
     <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"শংসাপত্রটি বৈধ৷"</string>
     <string name="issued_to" msgid="454239480274921032">"এর জন্য ইস্যু করা হয়েছে:"</string>
     <string name="common_name" msgid="2233209299434172646">"প্রচলিত নাম:"</string>
@@ -1458,11 +1464,11 @@
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"পিন কোডগুলি মিলছে না"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"বিভিন্ন প্যাটার্নের সাহায্যে খুব বেশি বার প্রচেষ্টা করা হয়ে গেছে"</string>
     <string name="kg_login_instructions" msgid="1100551261265506448">"আনলক করতে আপনার Google অ্যাকাউন্টের মাধ্যমে প্রবেশ করুন৷"</string>
-    <string name="kg_login_username_hint" msgid="5718534272070920364">"ব্যবহারকারী নাম (ইমেল)"</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"ইউজারনেম (ইমেল)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"পাসওয়ার্ড"</string>
-    <string name="kg_login_submit_button" msgid="5355904582674054702">"প্রবেশ করুন"</string>
-    <string name="kg_login_invalid_input" msgid="5754664119319872197">"অবৈধ ব্যবহারকারী নাম অথবা পাসওয়ার্ড৷"</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"আপনার ব্যবহারকারী নাম অথবা পাসওয়ার্ড ভুলে গেছেন?\n"<b>"google.com/accounts/recovery"</b>" এ যান৷"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"সাইন-ইন করুন"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"অবৈধ ইউজারনেম অথবা পাসওয়ার্ড৷"</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"আপনার ইউজারনেম অথবা পাসওয়ার্ড ভুলে গেছেন?\n"<b>"google.com/accounts/recovery"</b>" এ যান৷"</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"অ্যাকাউন্ট পরীক্ষা করা হচ্ছে..."</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"আপনি আপনার পিন টাইপ করতে <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করেছেন৷ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"আপনি আপনার পাসওয়ার্ড <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল টাইপ করেছেন৷ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
@@ -1480,7 +1486,7 @@
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"সরান"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"প্রস্তাবিত স্তরের চেয়ে বেশি উঁচুতে ভলিউম বাড়াবেন?\n\nউঁচু ভলিউমে বেশি সময় ধরে কিছু শুনলে আপনার শ্রবনশক্তির ক্ষতি হতে পারে।"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"অ্যাক্সেসযোগ্যতা শর্টকাট ব্যবহার করবেন?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"শর্টকাটটি চালু থাকলে দুটি ভলিউম বোতাম একসাথে ৩ সেকেন্ড টিপে ধরে রাখলে একটি অ্যাক্সেসযোগ্যতা বৈশিষ্ট্য চালু হবে।\n\n বর্তমান অ্যাক্সেসযোগ্যতা বৈশিষ্ট্য:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n আপনি এই বৈশিষ্ট্যটি সেটিংস &gt; অ্যাক্সেসযোগ্যতাতে গিয়ে পরিবর্তন করতে পারবেন।"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"শর্টকাটটি চালু থাকলে দুটি ভলিউম বোতাম একসাথে ৩ সেকেন্ড টিপে ধরে রাখলে একটি অ্যাকসেসিবিলিটি বৈশিষ্ট্য চালু হবে।\n\n বর্তমান অ্যাকসেসিবিলিটি বৈশিষ্ট্য:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n আপনি এই বৈশিষ্ট্যটি সেটিংস &gt; অ্যাকসেসিবিলিটিতে গিয়ে পরিবর্তন করতে পারবেন।"</string>
     <string name="disable_accessibility_shortcut" msgid="627625354248453445">"শর্টকাট বন্ধ করুন"</string>
     <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"শর্টকাট ব্যবহার করুন"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"অ্যাক্সেসযোগ্যতা শর্টকাট <xliff:g id="SERVICE_NAME">%1$s</xliff:g> কে চালু করেছে"</string>
@@ -1490,7 +1496,7 @@
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"বড় করে দেখা"</string>
     <string name="user_switched" msgid="3768006783166984410">"বর্তমান ব্যবহারকারী <xliff:g id="NAME">%1$s</xliff:g>৷"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> নামের ব্যবহারকারীতে যাচ্ছে…"</string>
-    <string name="user_logging_out_message" msgid="8939524935808875155">"<xliff:g id="NAME">%1$s</xliff:g>কে লগ আউট করা হচ্ছে..."</string>
+    <string name="user_logging_out_message" msgid="8939524935808875155">"<xliff:g id="NAME">%1$s</xliff:g>কে লগ-আউট করা হচ্ছে..."</string>
     <string name="owner_name" msgid="2716755460376028154">"মালিক"</string>
     <string name="error_message_title" msgid="4510373083082500195">"ত্রুটি"</string>
     <string name="error_message_change_not_allowed" msgid="1238035947357923497">"এই পরিবর্তনটি আপনার প্রশাসক দ্বারা অনুমোদিত নয়"</string>
@@ -1577,10 +1583,10 @@
     <string name="mediasize_japanese_kahu" msgid="6872696027560065173">"Kahu"</string>
     <string name="mediasize_japanese_kaku2" msgid="2359077233775455405">"Kaku2"</string>
     <string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string>
-    <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"অজানা প্রতিকৃতি"</string>
-    <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"অজানা ভূদৃশ্য"</string>
+    <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"অজানা পোর্ট্রেট"</string>
+    <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"অজানা ল্যান্ডস্কেপ"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"বাতিল করা হয়েছে"</string>
-    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"সামগ্রী লেখায় ত্রুটি হয়েছে"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"কন্টেন্ট লেখায় ত্রুটি হয়েছে"</string>
     <string name="reason_unknown" msgid="6048913880184628119">"অজানা"</string>
     <string name="reason_service_unavailable" msgid="7824008732243903268">"প্রিন্ট পরিষেবা সক্ষম করা নেই"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> পরিষেবা ইনস্টল হয়েছে"</string>
@@ -1599,16 +1605,16 @@
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"পরে আবার চেষ্টা করুন"</string>
-    <string name="immersive_cling_title" msgid="8394201622932303336">"পূর্ণ স্ক্রীণে দেখা হচ্ছে"</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"পূর্ণ স্ক্রিনে দেখা হচ্ছে"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"প্রস্থান করতে উপর থেকে নীচের দিকে সোয়াইপ করুন"</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"বুঝেছি"</string>
     <string name="done_label" msgid="2093726099505892398">"সম্পন্ন হয়েছে"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"বৃত্তাকার ঘণ্টা নির্বাচকের স্লাইডার"</string>
     <string name="minute_picker_description" msgid="8606010966873791190">"বৃত্তাকার মিনিট নির্বাচকের স্লাইডার"</string>
-    <string name="select_hours" msgid="6043079511766008245">"ঘণ্টা নির্বাচন করুন"</string>
-    <string name="select_minutes" msgid="3974345615920336087">"মিনিট নির্বাচন করুন"</string>
-    <string name="select_day" msgid="7774759604701773332">"মাস এবং দিন নির্বাচন করুন"</string>
-    <string name="select_year" msgid="7952052866994196170">"বছর নির্বাচন করুন"</string>
+    <string name="select_hours" msgid="6043079511766008245">"ঘণ্টা বেছে নিন"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"মিনিট বেছে নিন"</string>
+    <string name="select_day" msgid="7774759604701773332">"মাস এবং দিন বেছে নিন"</string>
+    <string name="select_year" msgid="7952052866994196170">"বছর বেছে নিন"</string>
     <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> মুছে ফেলা হয়েছে"</string>
     <string name="managed_profile_label_badge" msgid="2355652472854327647">"কর্মক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"দ্বিতীয় কার্যক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string>
@@ -1623,8 +1629,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" msgid="1960431123816253034">"ব্যাটরির লাইফ উন্নত করতে সহায়তা করতে, ব্যাটারি সাশ্রয়কারী আপনার ডিভাইসের কার্যসম্পাদনা হ্রাস করে এবং কম্পন, অবস্থান পরিষেবাগুলি এবং অধিকাংশ ব্যাকগ্রাউন্ড ডেটা সীমিত করে৷ ইমেল, মেসেজিং এবং অন্যান্য অ্যাপ্লিকেশনগুলিকে যেগুলি সিঙ্কের উপর নির্ভর করে সেগুলিকে আপনি না খোলা পর্যন্ত নাও আপডেট হতে পারে৷\n\nআপনার ডিভাইসটিকে যখন চার্জ করা হয় তখন ব্যাটারি সাশ্রয়কারী স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যায়৷"</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"ডেটার ব্যবহার কমাতে সহায়তা করার জন্য, ডেটা সেভার পটভূমিতে কিছু অ্যাপ্লিকেশানকে ডেটা পাঠাতে বা গ্রহণ করতে বাধা দেয়৷ আপনি বর্তমানে এমন একটি অ্যাপ্লিকেশান ব্যবহার করছেন যেটি ডেটা অ্যাক্সেস করতে পারে, তবে সেটি কমই করে৷ এর ফলে যা হতে পারে, উদাহরণস্বরূপ, আপনি ছবিগুলিতে আলতো চাপ না দেওয়া পর্যন্ত সেগুলি প্রদর্শিত হবে না৷"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"ব্যাটরির লাইফ উন্নত করতে, ব্যাটারি সাশ্রয়কারী আপনার ডিভাইসের কার্যসম্পাদনা হ্রাস করে এবং কম্পন, লোকেশন পরিষেবাগুলি এবং অধিকাংশ ব্যাকগ্রাউন্ড ডেটা সীমিত করে৷ ইমেল, মেসেজিং এবং অন্যান্য অ্যাপ্লিকেশনগুলিকে যেগুলি সিঙ্কের উপর নির্ভর করে সেগুলিকে আপনি না খোলা পর্যন্ত নাও আপডেট হতে পারে৷\n\nআপনার ডিভাইসটিকে যখন চার্জ করা হয় তখন ব্যাটারি সাশ্রয়কারী নিজে থেকে বন্ধ হয়ে যায়৷"</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"ডেটার ব্যবহার কমাতে সহায়তা করার জন্য, ডেটা সেভার পটভূমিতে কিছু অ্যাপ্লিকেশনকে ডেটা পাঠাতে বা গ্রহণ করতে বাধা দেয়৷ আপনি বর্তমানে এমন একটি অ্যাপ্লিকেশন ব্যবহার করছেন যেটি ডেটা অ্যাক্সেস করতে পারে, তবে সেটি কমই করে৷ এর ফলে যা হতে পারে, উদাহরণস্বরূপ, আপনি ছবিগুলিতে আলতো চাপ না দেওয়া পর্যন্ত সেগুলি প্রদর্শিত হবে না৷"</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"ডেটা সেভার চালু করবেন?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"চালু করুন"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
@@ -1680,13 +1686,13 @@
     <string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS অনুরোধটিকে নতুন USSD অনুরোধে রুপান্তরিত করা হয়েছে৷"</string>
     <string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS অনুরোধটিকে নতুন SS অনুরোধে রুপান্তরিত করা হয়েছে৷"</string>
     <string name="notification_work_profile_content_description" msgid="4600554564103770764">"কর্মস্থলের প্রোফাইল"</string>
-    <string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"প্রসারিত করুন"</string>
+    <string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"বড় করুন"</string>
     <string name="expand_button_content_description_expanded" msgid="8520652707158554895">"সঙ্কুচিত করুন"</string>
     <string name="expand_action_accessibility" msgid="5307730695723718254">"টগল সম্প্রসারণ"</string>
     <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB পেরিফেরাল পোর্ট"</string>
     <string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
     <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB পেরিফেরাল পোর্ট"</string>
-    <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"আরো বিকল্প"</string>
+    <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"আরও বিকল্প"</string>
     <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"ওভারফ্লো বন্ধ করুন"</string>
     <string name="maximize_button_text" msgid="7543285286182446254">"বড় করুন"</string>
     <string name="close_button_text" msgid="3937902162644062866">"বন্ধ করুন"</string>
@@ -1706,11 +1712,11 @@
     <string name="language_picker_section_suggested" msgid="8414489646861640885">"প্রস্তাবিত"</string>
     <string name="language_picker_section_all" msgid="3097279199511617537">"সকল ভাষা"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"সমস্ত অঞ্চল"</string>
-    <string name="locale_search_menu" msgid="2560710726687249178">"অনুসন্ধান করুন"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"খুঁজুন"</string>
     <string name="work_mode_off_title" msgid="2615362773958585967">"কর্মস্থলের মোড চালু করবেন?"</string>
     <string name="work_mode_off_message" msgid="2961559609199223594">"এটি অ্যাপ, পটভূমি সিঙ্ক, এবং সম্পর্কিত বৈশিষ্ট্যগুলি সহ কর্মস্থলের প্রোফাইলটিকে চালু করবে"</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"চালু করুন"</string>
-    <string name="new_sms_notification_title" msgid="8442817549127555977">"আপনার নতুন বার্তা আছে"</string>
+    <string name="new_sms_notification_title" msgid="8442817549127555977">"আপনার নতুন মেসেজ আছে"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"দেখার জন্য SMS অ্যাপ্লিকেশান খুলুন"</string>
     <string name="user_encrypted_title" msgid="9054897468831672082">"কিছু ক্রিয়াকলাপ সীমিত হতে পারে"</string>
     <string name="user_encrypted_message" msgid="4923292604515744267">"আনলক করতে আলতো চাপ দিন"</string>
@@ -1721,28 +1727,22 @@
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ফাইলগুলি দেখতে আলতো চাপ দিন"</string>
     <string name="pin_target" msgid="3052256031352291362">"পিন করুন"</string>
     <string name="unpin_target" msgid="3556545602439143442">"আনপিন করুন"</string>
-    <string name="app_info" msgid="6856026610594615344">"অ্যাপ্লিকেশানের তথ্য"</string>
+    <string name="app_info" msgid="6856026610594615344">"অ্যাপের তথ্য"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"ডিভাইস আবার সেট করবেন?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"ডিভাইসটিকে আবার সেট করতে আলতো চাপুন"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ডেমো শুরু করা হচ্ছে…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"ডিভাইস আবার সেট করা হচ্ছে…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"ডিভাইস আবার সেট করবেন?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"আপনার করা যে কোনো পরিবর্তন মুছে যাবে এবং <xliff:g id="TIMEOUT">%1$s</xliff:g> সেকেন্ডের মধ্যে ডেমো আবার শুরু হবে…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"বাতিল করুন"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"এখনই আবার সেট করুন"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"অক্ষম করা <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"কনফারেন্স কল"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"টুলটিপ"</string>
     <string name="app_category_game" msgid="5431836943981492993">"গেম্স"</string>
-    <string name="app_category_audio" msgid="1659853108734301647">"সঙ্গীত ও অডিও"</string>
+    <string name="app_category_audio" msgid="1659853108734301647">"মিউজিক ও অডিও"</string>
     <string name="app_category_video" msgid="2728726078629384196">"চলচ্চিত্র ও ভিডিওগুলি"</string>
-    <string name="app_category_image" msgid="4867854544519846048">"ফটো ও চিত্রগুলি"</string>
+    <string name="app_category_image" msgid="4867854544519846048">"ফটো ও ছবিগুলি"</string>
     <string name="app_category_social" msgid="5842783057834965912">"সামাজিক ও যোগাযোগ"</string>
     <string name="app_category_news" msgid="7496506240743986873">"খবর ও পত্রিকাগুলি"</string>
     <string name="app_category_maps" msgid="5878491404538024367">"মানচিত্র ও নেভিগেশান"</string>
     <string name="app_category_productivity" msgid="3742083261781538852">"উৎপাদনশীলতা"</string>
-    <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"ডিভাইসের সঞ্চয়স্থান"</string>
+    <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"ডিভাইসের স্টোরেজ"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"USB ডিবাগিং"</string>
     <string name="time_picker_hour_label" msgid="2979075098868106450">"ঘন্টা"</string>
     <string name="time_picker_minute_label" msgid="5168864173796598399">"মিনিট"</string>
@@ -1752,7 +1752,7 @@
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"সময় ইনপুট দেওয়ার জন্য পাঠ্য ইনপুট মোডে যান।"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"সময় ইনপুট দেওয়ার জন্য ঘড়ি মোডে যান।"</string>
     <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"আপনাআপনি পূরণ করার বিকল্পগুলি"</string>
-    <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"স্বতঃপূর্ণর জন্য সংরক্ষণ করুন"</string>
+    <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"স্বতঃপূরণের জন্য সেভ করুন"</string>
     <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"বিষয়বস্তুগুলি অটো-ফিল করা যাবে না"</string>
     <string name="autofill_picker_no_suggestions" msgid="3908514303773350735">"স্বতঃপূর্ণ করার প্রস্তাবনা নেই"</string>
     <plurals name="autofill_picker_some_suggestions" formatted="false" msgid="5506565809835815274">
@@ -1763,7 +1763,7 @@
     <string name="autofill_save_title_with_type" msgid="8637809388029313305">"<xliff:g id="TYPE">%1$s</xliff:g> কে &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt;এ সংরক্ষণ করবেন?"</string>
     <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"<xliff:g id="TYPE_0">%1$s</xliff:g> এবং <xliff:g id="TYPE_1">%2$s</xliff:g> কে &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt; এ সংরক্ষণ করবেন?"</string>
     <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, এবং <xliff:g id="TYPE_2">%3$s</xliff:g> কে &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt; এ সংরক্ষণ করবেন?"</string>
-    <string name="autofill_save_yes" msgid="6398026094049005921">"সংরক্ষণ করুন"</string>
+    <string name="autofill_save_yes" msgid="6398026094049005921">"সেভ করুন"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"না থাক"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"পাসওয়ার্ড"</string>
     <string name="autofill_save_type_address" msgid="4936707762193009542">"ঠিকানা"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"উপকূলবর্তী এবং নদীর পাশের অঞ্চল থেকে অবিলম্বে উঁচু কোনো জায়গার দিকে যান।"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"শান্ত থাকুন, আশেপাশে আশ্রয় খুঁজুন।"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"বিপদকালীন বার্তাগুলির পরীক্ষা"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"উত্তর দিন"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"সিম অনুমোদিত নয়"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"সিম প্রস্তুত নয়"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 92294dc..63a3945 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -28,15 +28,15 @@
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dana"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> sati"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> sat"</string>
+    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d i <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
+    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d i <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
     <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> sati"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> sat <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> sat <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
+    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h i <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
+    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h i <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
     <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
+    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min i <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
+    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min i <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
     <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Bez naslova&gt;"</string>
@@ -90,17 +90,23 @@
     <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Prikaz ID-a pozivaoca u zadanim postavkama nije zabranjen. Sljedeći poziv: nije zabranjen"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Uslugu nije moguće koristiti."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Ne možete promijeniti postavke ID-a pozivaoca."</string>
-    <string name="RestrictedOnData" msgid="8653794784690065540">"Usluga prijenosa podataka je blokirana."</string>
-    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Hitni pozivi su blokirani."</string>
-    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Govorne usluge su blokirane."</string>
-    <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Sve govorne usluge su blokirane."</string>
-    <string name="RestrictedOnSms" msgid="8314352327461638897">"SMS usluga je blokirana."</string>
-    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Blokirane su govorne usluge i usluge prijenosa podataka."</string>
-    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Blokirane su govorne/SMS usluge."</string>
-    <string name="RestrictedOnAll" msgid="5643028264466092821">"Blokirane su sve govorne i SMS usluge te usluge prijenosa podataka."</string>
+    <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Nema usluge prijenosa mobilnih podataka"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Nema usluge za hitne slučajeve"</string>
+    <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Nema usluge govornih poziva"</string>
+    <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nema govornih/hitnih usluga"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Vaš operater je privremeno obustavio uslugu prijenosa mobilnih podataka na ovoj lokaciji"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Vaš operater je privremeno obustavio hite pozive na ovoj lokaciji"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Vaš operater je privremeno obustavio govorne pozive na ovoj lokaciji"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Vaš operater je na ovoj lokaciji privremeno obustavio govorne i hitne pozive."</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nije moguće dosegnuti mrežu"</string>
-    <!-- no translation found for NetworkPreferenceSwitchSummary (4164230263214915351) -->
-    <skip />
+    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Za poboljšanje prijema, pokušajte promijeniti tip odabran u meniju Sistem &gt; Mreža i internet &gt; Mobilne mreže &gt; Preferirani tip mreže."</string>
+    <string name="notification_channel_network_alert" msgid="4427736684338074967">"Upozorenja"</string>
+    <string name="notification_channel_call_forward" msgid="2419697808481833249">"Preusmjeravanje poziva"</string>
+    <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Način rada za hitni povratni poziv"</string>
+    <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Upozorenja za mobilne podatke"</string>
+    <string name="notification_channel_sms" msgid="3441746047346135073">"SMS poruke"</string>
+    <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Poruke govorne pošte"</string>
+    <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi pozivanje"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Ravnopravni uređaj zatražio TTY PUNI način rada"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Ravnopravni uređaj zatražio TTY HCO način rada"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Ravnopravni uređaj zatražio TTY VCO način rada"</string>
@@ -140,8 +146,7 @@
   </string-array>
     <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>
-    <!-- no translation found for wfc_mode_cellular_preferred_summary (1988279625335345908) -->
-    <skip />
+    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferira se mobilna mreža"</string>
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Samo Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije proslijeđen"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -180,18 +185,16 @@
       <item quantity="other">Instalirane su ustanove za izdavanje certifikata</item>
     </plurals>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Od nepoznate treće strane"</string>
-    <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"od strane administratora vašeg profila za posao"</string>
+    <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"Administrator vašeg radnog profila"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Od <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="work_profile_deleted" msgid="5005572078641980632">"Poslovni profil je obrisan"</string>
-    <string name="work_profile_deleted_description" msgid="6305147513054341102">"Poslovni profil je obrisan jer nedostaje aplikacija administratora."</string>
-    <string name="work_profile_deleted_details" msgid="226615743462361248">"Aplikacija administratora za poslovni profil nedostaje ili je neispravna. Zbog toga su vaš poslovni profil i vezani podaci obrisani. Za pomoć se obratite administratoru."</string>
-    <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Profil za posao više nije dostupan na ovom uređaju."</string>
-    <!-- no translation found for network_logging_notification_title (6399790108123704477) -->
-    <skip />
-    <!-- no translation found for network_logging_notification_text (7930089249949354026) -->
-    <skip />
+    <string name="work_profile_deleted_description" msgid="1100529432509639864">"Radni profil je izbrisan jer nedostaje aplikacija administratora"</string>
+    <string name="work_profile_deleted_details" msgid="6307630639269092360">"Nedostaje aplikacija administratora za radni profil ili je neispravna. Zbog toga su vaš radni profil i povezani podaci izbrisani. Obratite administratoru za pomoć."</string>
+    <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Radni profil više nije dostupan na ovom uređaju"</string>
+    <string name="network_logging_notification_title" msgid="6399790108123704477">"Uređajem se upravlja."</string>
+    <string name="network_logging_notification_text" msgid="7930089249949354026">"Vaša organizacija upravlja ovim uređajem i može pratiti mrežni saobraćaj. Dodirnite za detalje."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Uređaj će biti izbrisan"</string>
-    <string name="factory_reset_message" msgid="4905025204141900666">"Aplikaciji administratora nedostaju komponente ili je neispravna, i ne može se koristiti. Vaš uređaj će sada biti izbrisan. Za pomoć se obratite administratoru."</string>
+    <string name="factory_reset_message" msgid="7972496262232832457">"Nije moguće koristiti aplikaciju administratora. Potpuno će se izbrisati podaci na vašem uređaju.\n\nAko imate pitanja, obratite se administratoru vaše organizacije."</string>
     <string name="me" msgid="6545696007631404292">"Ja"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opcije tableta"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"Opcije za TV"</string>
@@ -208,7 +211,7 @@
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"Priprema za ažuriranje..."</string>
     <string name="reboot_to_update_package" msgid="3871302324500927291">"Obrađuje se paket ažuriranja..."</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"Ponovno se pokreće..."</string>
-    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Vraćanje na tvorničke postavke"</string>
+    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Vraćanje na fabričke postavke"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"Ponovno se pokreće..."</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"Gašenje u toku…"</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Vaš tablet će se isključiti."</string>
@@ -225,7 +228,7 @@
     <string name="global_actions" product="default" msgid="2406416831541615258">"Opcije telefona"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Zaključavanje ekrana"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"Isključi telefon"</string>
-    <string name="global_action_emergency" msgid="7112311161137421166">"Hitni slučaj"</string>
+    <string name="global_action_emergency" msgid="7112311161137421166">"Hitno"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Izvještaj o greškama"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Kreirajte izvještaj o greškama"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ovim će se prikupljati informacije o trenutnom stanju uređaja, koji će biti poslani kao poruka e-pošte. Može malo potrajati dok se izvještaj o greškama ne kreira i bude spreman za slanje. Budite strpljivi."</string>
@@ -260,11 +263,17 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ažuriranja"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status mreže"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Mrežna upozorenja"</string>
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Mreža je dostupna"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Status VPN-a"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administracija uređaja"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozorenja"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Promotivna demonstracija u maloprodaji"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
+    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacije koje rade u pozadini"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je pokrenuta u pozadini"</string>
+    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Broj aplikacija koje rade u pozadini: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dodirnite za detalje o potrošnji baterije i prijenosa podataka"</string>
+    <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android sistem"</string>
     <string name="user_owner_label" msgid="1119010402169916617">"Prebacite se na lični"</string>
@@ -287,15 +296,13 @@
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"poziva i upravlja pozivima"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"Tjelesni senzori"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"pristupa podacima senzora o vašim vitalnim funkcijama"</string>
-    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Ponovo prikaži sadržaj prozora"</string>
-    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Istražite sadržaj prozora koji trenutno koristite."</string>
-    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Uključite Istraživanje dodirom"</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Preuzima sadržaj prozora"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Pregleda sadržaj prozora koji trenutno koristite."</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Uključi opciju Istraživanje dodirom"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"Stavke koje dodirnete bit će izgovorene naglas, a ekran možete istraživati koristeći pokrete."</string>
-    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Uključite poboljšanu web pristupačnost"</string>
-    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Možda će biti instalirana skripta kako bi sadržaj aplikacije bio dostupniji."</string>
-    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Obratite pažnju na tekst koji tipkate"</string>
-    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Uključuje lične podatke kao što su brojevi kreditnih kartica i lozinke."</string>
-    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kontroliranje uvećanja prikaza na ekranu"</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Prati tekst koji unosite"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Obuhvata lične podatke kao što su brojevi kreditnih kartica i lozinke."</string>
+    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kontrolira uvećanje prikaza na ekranu"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolira stepen uvećanja prikaza na ekranu i podešavanje položaja."</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Praviti pokrete"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Može dodirivati, prevlačiti, hvatati prstima i praviti druge pokrete."</string>
@@ -403,7 +410,7 @@
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Omogućava aplikaciji slanje naredbi na SIM. Ovo je vrlo opasno."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"snimanje slika i videozapisa"</string>
     <string name="permdesc_camera" msgid="5392231870049240670">"Ova aplikacija može slikati fotografije i snimati videozapise koristeći kameru bilo kada."</string>
-    <string name="permlab_vibrate" msgid="7696427026057705834">"kontrola vibriranja"</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"kontrola vibracije"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"Dozvoljava aplikaciji upravljanje vibracijom."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"izravno zvanje telefonskih brojeva"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"Omogućava aplikaciji pozivanje telefonskih brojeva bez vašeg angažiranja. Ovo može uzrokovati neočekivane troškove ili pozive. Imajte na umu da ovo ne daje aplikaciji mogućnost pozivanja brojeva za hitne slučajeve. Zlonamjerne aplikacije vam mogu napraviti neočekivane troškove kroz vršenje poziva bez vašeg znanja."</string>
@@ -413,8 +420,8 @@
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Omogućava aplikaciji pristup telefonskim funkcijama uređaja. Ova dozvola omogućava aplikaciji određivanje telefonskog i identifikacionog broja uređaja, bez obzira da li je poziv aktivan i da li je uspostavljena veza sa pozivanim brojem."</string>
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"usmjeravanje poziva preko sistema"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Dopušta aplikaciji da pozive usmjeri preko sistema radi poboljšanja iskustva pozivanja."</string>
-    <string name="permlab_readPhoneNumber" msgid="6421295519255154171">"čitanje telefonskog broja"</string>
-    <string name="permdesc_readPhoneNumber" msgid="9135856402838173711">"Dopušta aplikaciji pristup telefonskom broju telefona."</string>
+    <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"čitanje telefonskih brojeva"</string>
+    <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"Dozvoljava aplikaciji pristup telefonskim brojevima uređaja."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"sprečavanje tableta da uđe u režim mirovanja"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"spriječi ulazak TV-a u režim mirovanja"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"sprečavanje telefona da uđe u režim mirovanja"</string>
@@ -440,7 +447,7 @@
     <string name="permlab_accessNetworkState" msgid="4951027964348974773">"prikaz mrežnih veza"</string>
     <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Omogućava aplikaciji pregled informacija o mrežnim vezama, npr. koje mreže postoje i koje su povezane."</string>
     <string name="permlab_createNetworkSockets" msgid="7934516631384168107">"ima potpuni pristup mreži"</string>
-    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Omogućava aplikaciji kreiranje spojnih tačaka sa mrežom i korištenje prilagođenih mrežnih protokola. Preglednik i druge aplikacije omogućavaju slanje podataka na internet, tako da ova dozvola nije potrebna za vršenje te radnje."</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Omogućava aplikaciji kreiranje spojnih tačaka sa mrežom i korištenje prilagođenih mrežnih protokola. Preglednik i druge aplikacije omogućavaju slanje podataka na internet, tako da ovo odobrenje nije potrebno za vršenje te radnje."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"izmjene povezivanja na mrežu"</string>
     <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Dozvoljava aplikaciji izmjenu stanja mrežne povezanosti."</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"izmjene podijeljenog povezivanja"</string>
@@ -487,6 +494,7 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Vremensko ograničenje za otisak prsta je isteklo. Pokušajte ponovo."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Radnja sa otiskom prsta je otkazana."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Previše pokušaja. Senzor za otisak prsta je onemogućen."</string>
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Pokušajte ponovo."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
@@ -554,7 +562,7 @@
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Omogućava aplikaciji da čita i upisuje konfiguraciju opcije Ne ometaj."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Postavljanje pravila za lozinke"</string>
     <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolira dužinu i znakove koji su dozvoljeni u lozinkama za zaključavanje ekrana i PIN kodovima."</string>
-    <string name="policylab_watchLogin" msgid="914130646942199503">"Prati pokušaje otključavanja ekrana"</string>
+    <string name="policylab_watchLogin" msgid="5091404125971980158">"Prati pokušaje otključavanja ekrana"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Prati broj pogrešno unijetih lozinki prilikom otključavanja ekrana i zaključava tablet ili briše sve podatke s njega ukoliko se previše puta unese pogrešna lozinka."</string>
     <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Prati koliko puta je lozinka neispravno otkucana prilikom otključavanja ekrana i zaključaj TV ili izbriši sve podatke s TV-a ako se lozinka neispravno ukuca previše puta."</string>
     <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Prati broj pogrešno unesenih lozinki prilikom otključavanja ekrana i zaključava telefon ili briše sve podatke s telefona ukoliko se previše puta unese pogrešna lozinka."</string>
@@ -645,14 +653,14 @@
     <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
     <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Poslovni mobilni"</string>
     <string name="phoneTypeWorkPager" msgid="649938731231157056">"Poslovni pejdžer"</string>
-    <string name="phoneTypeAssistant" msgid="5596772636128562884">"Pomoćnik"</string>
+    <string name="phoneTypeAssistant" msgid="5596772636128562884">"Asistent"</string>
     <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
     <string name="eventTypeCustom" msgid="7837586198458073404">"Prilagođeno"</string>
     <string name="eventTypeBirthday" msgid="2813379844211390740">"Rođendan"</string>
     <string name="eventTypeAnniversary" msgid="3876779744518284000">"Godišnjica"</string>
     <string name="eventTypeOther" msgid="7388178939010143077">"Ostalo"</string>
     <string name="emailTypeCustom" msgid="8525960257804213846">"Prilagođeno"</string>
-    <string name="emailTypeHome" msgid="449227236140433919">"Kućni"</string>
+    <string name="emailTypeHome" msgid="449227236140433919">"Privatna"</string>
     <string name="emailTypeWork" msgid="3548058059601149973">"Posao"</string>
     <string name="emailTypeOther" msgid="2923008695272639549">"Ostalo"</string>
     <string name="emailTypeMobile" msgid="119919005321166205">"Mobilni"</string>
@@ -678,7 +686,7 @@
     <string name="orgTypeOther" msgid="3951781131570124082">"Ostalo"</string>
     <string name="orgTypeCustom" msgid="225523415372088322">"Prilagođeno"</string>
     <string name="relationTypeCustom" msgid="3542403679827297300">"Prilagođeno"</string>
-    <string name="relationTypeAssistant" msgid="6274334825195379076">"Pomoćnik"</string>
+    <string name="relationTypeAssistant" msgid="6274334825195379076">"Asistent"</string>
     <string name="relationTypeBrother" msgid="8757913506784067713">"Brat"</string>
     <string name="relationTypeChild" msgid="1890746277276881626">"Dijete"</string>
     <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Nevjenčani partner"</string>
@@ -712,7 +720,7 @@
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Pritisnite dugme Meni kako biste otključali uređaj ili obavili hitni poziv."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Pritisnite dugme Meni za otključavanje uređaja."</string>
     <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Nacrtajte uzorak za otključavanje"</string>
-    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Hitni slučaj"</string>
+    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Hitno"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Povratak na poziv"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Ispravno!"</string>
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Pokušajte ponovo"</string>
@@ -840,8 +848,8 @@
     <string name="permdesc_setAlarm" msgid="316392039157473848">"Dozvoljava aplikaciji postavljanje alarma u instaliranom budilniku. Moguće je da neki budilnici neće primijeniti ovu funkciju."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"dodavanje govorne pošte"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Dozvoljava aplikaciji dodavanje poruka u vašu ulaznu govornu poštu."</string>
-    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"izmjena geolokacijskih dozvola preglednika"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Dozvoljava aplikaciji mijenjanje geolokacijskih dozvola pretraživača. Zlonamjerne aplikacije mogu to iskoristiti i dozvoliti slanje informacija o lokaciji proizvoljnim web stranicama."</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"izmjena geolokacijskih odobrenja preglednika"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Dozvoljava aplikaciji mijenjanje geolokacijskih odobrenja preglednika. Zlonamjerne aplikacije mogu to iskoristiti i dozvoliti slanje informacija o lokaciji proizvoljnim web lokcacijama."</string>
     <string name="save_password_message" msgid="767344687139195790">"Želite li da preglednik zapamti ovu lozinku?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Ne sada"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Zapamti"</string>
@@ -853,9 +861,9 @@
     <string name="menu_space_shortcut_label" msgid="2410328639272162537">"razmak"</string>
     <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"potvrdi"</string>
     <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"izbriši"</string>
-    <string name="search_go" msgid="8298016669822141719">"Traži"</string>
+    <string name="search_go" msgid="8298016669822141719">"Pretraži"</string>
     <string name="search_hint" msgid="1733947260773056054">"Pretraži..."</string>
-    <string name="searchview_description_search" msgid="6749826639098512120">"Traži"</string>
+    <string name="searchview_description_search" msgid="6749826639098512120">"Pretraživanje"</string>
     <string name="searchview_description_query" msgid="5911778593125355124">"Upit za pretragu"</string>
     <string name="searchview_description_clear" msgid="1330281990951833033">"Obriši upit"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Potvrditi upit"</string>
@@ -882,7 +890,7 @@
     <string name="minute" msgid="9148878657703769868">"minuta"</string>
     <string name="minutes" msgid="5646001005827034509">"minute"</string>
     <string name="second" msgid="3184235808021478">"sekunda"</string>
-    <string name="seconds" msgid="3161515347216589235">"sekunde"</string>
+    <string name="seconds" msgid="3161515347216589235">"s"</string>
     <string name="week" msgid="5617961537173061583">"sedmica"</string>
     <string name="weeks" msgid="6509623834583944518">"sedmice"</string>
     <string name="year" msgid="4001118221013892076">"godina"</string>
@@ -990,17 +998,16 @@
     <string name="selectTextMode" msgid="1018691815143165326">"Odaberi tekst"</string>
     <string name="undo" msgid="7905788502491742328">"Vrati"</string>
     <string name="redo" msgid="7759464876566803888">"Ponovo uradi"</string>
-    <!-- no translation found for autofill (3035779615680565188) -->
-    <skip />
+    <string name="autofill" msgid="3035779615680565188">"Automatsko popunjavanje"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Odabir teksta"</string>
     <string name="addToDictionary" msgid="4352161534510057874">"Dodaj u rječnik"</string>
     <string name="deleteText" msgid="6979668428458199034">"Izbriši"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Način unosa"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Akcije za tekst"</string>
     <string name="email" msgid="4560673117055050403">"E-pošta"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Pretraži"</string>
+    <string name="dial" msgid="4204975095406423102">"Pozovi"</string>
+    <string name="map" msgid="6068210738233985748">"Mape"</string>
+    <string name="browse" msgid="6993590095938149861">"Preglednik"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ponestaje prostora za pohranu"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke funkcije sistema možda neće raditi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nema dovoljno prostora za sistem. Obezbijedite 250MB slobodnog prostora i ponovo pokrenite uređaj."</string>
@@ -1096,7 +1103,7 @@
     <string name="dump_heap_text" msgid="4809417337240334941">"Proces <xliff:g id="PROC">%1$s</xliff:g> je premašio ograničenje procesne memorije od <xliff:g id="SIZE">%2$s</xliff:g>. Snimak dinamičkog dijela memorije vam je dostupan i možete ga dijeliti sa njegovim programerom. Budite oprezni: ovaj snimak dinamičkog dijela memorije može sadržavati vaše lične podatke kojima aplikacija ima pristup."</string>
     <string name="sendText" msgid="5209874571959469142">"Biranje akcije za tekst"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Jačina zvuka zvona"</string>
-    <string name="volume_music" msgid="5421651157138628171">"Jačina zvuka za medijske sadržaje"</string>
+    <string name="volume_music" msgid="5421651157138628171">"Jačina zvuka medija"</string>
     <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Medijski sadržaj se reproducira preko Bluetooth veze"</string>
     <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Postavljena nečujna melodija zvona"</string>
     <string name="volume_call" msgid="3941680041282788711">"Jačina zvuka tokom poziva"</string>
@@ -1107,17 +1114,27 @@
     <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Jačina zvuka za Bluetooth vezu"</string>
     <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Jačina zvuka melodije"</string>
     <string name="volume_icon_description_incall" msgid="8890073218154543397">"Jačina zvuka tokom poziva"</string>
-    <string name="volume_icon_description_media" msgid="4217311719665194215">"Jačina zvuka za medijske sadržaje"</string>
+    <string name="volume_icon_description_media" msgid="4217311719665194215">"Jačina zvuka medija"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Jačina zvuka za obavještenja"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Zadana melodija zvona"</string>
     <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Zadano (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
     <string name="ringtone_silent" msgid="7937634392408977062">"Bez zvuka"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Melodije zvona"</string>
-    <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Zvuci alarma"</string>
-    <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Zvuci obavještenja"</string>
+    <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Zvukovi alarma"</string>
+    <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Zvukovi obavještenja"</string>
     <string name="ringtone_unknown" msgid="3914515995813061520">"Nepoznato"</string>
+    <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
+      <item quantity="one">Wi-Fi mreže su dostupne</item>
+      <item quantity="few">Wi-Fi mreže su dostupne</item>
+      <item quantity="other">Wi-Fi mreže su dostupne</item>
+    </plurals>
+    <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
+      <item quantity="one">Otvorene Wi-Fi mreže su dostupne</item>
+      <item quantity="few">Otvorene Wi-Fi mreže su dostupne</item>
+      <item quantity="other">Otvorene Wi-Fi mreže su dostupne</item>
+    </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavljivanje na Wi-Fi mrežu"</string>
-    <string name="network_available_sign_in" msgid="1848877297365446605">"Prijavite se na mrežu"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_no_internet" msgid="8451173622563841546">"Wi-Fi nema pristup Internetu"</string>
@@ -1125,7 +1142,13 @@
     <string name="network_switch_metered" msgid="4671730921726992671">"Prebačeno na: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
     <string name="network_switch_metered_detail" msgid="5325661434777870353">"Kada na uređaju <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu, koristi se <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Moguća je naplata usluge."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"Prebačeno iz mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> u <xliff:g id="NEW_NETWORK">%2$s</xliff:g> mrežu"</string>
-    <!-- no translation found for network_switch_type_name:0 (3979506840912951943) -->
+  <string-array name="network_switch_type_name">
+    <item msgid="3979506840912951943">"mobilni podaci"</item>
+    <item msgid="75483255295529161">"Wi-Fi"</item>
+    <item msgid="6862614801537202646">"Bluetooth"</item>
+    <item msgid="5447331121797802871">"Ethernet"</item>
+    <item msgid="8257233890381651999">"VPN"</item>
+  </string-array>
     <string name="network_switch_type_name_unknown" msgid="4552612897806660656">"nepoznata vrsta mreže"</string>
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Problem prilikom spajanja na Wi-Fi mrežu"</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ima lošu internet vezu."</string>
@@ -1142,7 +1165,7 @@
     <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Pozivnica poslana"</string>
     <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Poziv za povezivanje"</string>
     <string name="wifi_p2p_from_message" msgid="570389174731951769">"Pošiljalac:"</string>
-    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Primalac:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Prima:"</string>
     <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Unesite potrebni PIN:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Tablet će privremeno prekinuti Wi-Fi vezu dok bude povezan s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
@@ -1178,10 +1201,10 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Postavljanje vremena"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Postavljanje datuma"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Postaviti"</string>
-    <string name="date_time_done" msgid="2507683751759308828">"Završeno"</string>
+    <string name="date_time_done" msgid="2507683751759308828">"Gotovo"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"NOVO: "</font></string>
     <string name="perms_description_app" msgid="5139836143293299417">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> omogućava."</string>
-    <string name="no_permissions" msgid="7283357728219338112">"Nisu potrebne dozvole"</string>
+    <string name="no_permissions" msgid="7283357728219338112">"Nisu potrebna odobrenja"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"ovo se možda dodatno plaća"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"Uredu"</string>
     <string name="usb_charging_notification_title" msgid="6895185153353640787">"Ovaj uređaj se puni preko USB-a"</string>
@@ -1191,6 +1214,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB za MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Uspostavljena veza sa USB pohranom"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Dodirnite za više opcija."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio pribor nije podržan"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Dodirnite za više informacija"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka putem uređaja spojenog na USB je uspostavljeno"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Dodirnite da onemogućite otklanjanje grešaka putem uređaja spojenog na USB."</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
@@ -1198,18 +1223,20 @@
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Prijem izvještaja o grešci..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Podijeliti izvještaj o grešci?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Dijeljenje izvještaja o grešci..."</string>
-    <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Vaš IT administrator je zatražio izvještaj o grešci kako bi pomogao u rješavanju problema ovog uređaja. Aplikacije i podaci se mogu dijeliti."</string>
+    <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"Vaš administrator je zatražio izvještaj o greškama kako bi pomogao u rješavanju problema ovog uređaja. Moguće je dijeljenje aplikacija i podataka."</string>
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PODIJELI"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODBACI"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Promijeni tastaturu"</string>
     <string name="show_ime" msgid="2506087537466597099">"Prikaži na ekranu dok je fizička tastatura aktivna"</string>
-    <string name="hardware" msgid="194658061510127999">"Prikaži virtualnu tastaturu"</string>
+    <string name="hardware" msgid="194658061510127999">"Prikaz virtuelne tastature"</string>
     <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfiguriraj fizičku tastaturu"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dodirnite za odabir jezika i rasporeda"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Aplikacija <xliff:g id="NAME">%s</xliff:g> prekriva ostale aplikacije"</string>
-    <string name="alert_windows_notification_title" msgid="4532185840598192445">"Aplikacija <xliff:g id="NAME">%s</xliff:g> prekriva ostale aplikacije."</string>
+    <string name="alert_windows_notification_title" msgid="3697657294867638947">"Aplikacija <xliff:g id="NAME">%s</xliff:g> prekriva druge apl."</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da otvorite postavke i isključite je."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ISKLJUČI"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Priprema se <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1264,7 +1291,7 @@
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"Dodirnite dvaput za kontrolu uvećanja"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Dodavanje vidžeta nije uspjelo."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Počni"</string>
-    <string name="ime_action_search" msgid="658110271822807811">"Traži"</string>
+    <string name="ime_action_search" msgid="658110271822807811">"Pretraži"</string>
     <string name="ime_action_send" msgid="2316166556349314424">"Poslati"</string>
     <string name="ime_action_next" msgid="3138843904009813834">"Naprijed"</string>
     <string name="ime_action_done" msgid="8971516117910934605">"Gotovo"</string>
@@ -1301,7 +1328,7 @@
     <string name="vpn_lockdown_config" msgid="5099330695245008680">"Dodirnite za postavke"</string>
     <string name="upload_file" msgid="2897957172366730416">"Odabir fajla"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nije izabran nijedan fajl"</string>
-    <string name="reset" msgid="2448168080964209908">"Ponovno pokretanje"</string>
+    <string name="reset" msgid="2448168080964209908">"Vraćanje na zadano"</string>
     <string name="submit" msgid="1602335572089911941">"Potvrdi"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Način rada u autu omogućen"</string>
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Dodirnite za izlaz iz načina rada u automobilu"</string>
@@ -1336,7 +1363,7 @@
     <string name="sync_undo_deletes" msgid="2941317360600338602">"Poništiti brisanje"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"Ne radi ništa za sada"</string>
     <string name="choose_account_label" msgid="5655203089746423927">"Odaberite račun"</string>
-    <string name="add_account_label" msgid="2935267344849993553">"Dodajte račun"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"Dodaj račun"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Dodajte račun"</string>
     <string name="number_picker_increment_button" msgid="2412072272832284313">"Povećaj"</string>
     <string name="number_picker_decrement_button" msgid="476050778386779067">"Smanji"</string>
@@ -1382,11 +1409,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB pohrana"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"Uredi"</string>
     <string name="data_usage_warning_title" msgid="3620440638180218181">"Upozorenje o prijenosu podataka"</string>
-    <string name="data_usage_warning_body" msgid="6660692274311972007">"Dodirnite za prikaz upotrebe i postavki."</string>
+    <string name="data_usage_warning_body" msgid="6660692274311972007">"Dodirnite za prikaz potrošnje i postavki."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Dostignut limit za 2G-3G podatke"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Dostignut limit za 4G podatke"</string>
-    <!-- no translation found for data_usage_mobile_limit_title (6561099244084267376) -->
-    <skip />
+    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Dostignut limit za mob. podatke"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Dostignut limit Wi-Fi podataka"</string>
     <string name="data_usage_limit_body" msgid="291731708279614081">"Podaci pauz. za ostatak ciklusa"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Premašeni 2G-3G podaci"</string>
@@ -1429,9 +1455,9 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Bežični prikaz"</string>
-    <string name="media_route_button_content_description" msgid="591703006349356016">"Prebacuj"</string>
+    <string name="media_route_button_content_description" msgid="591703006349356016">"Emitiranje"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"Poveži na uređaj"</string>
-    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Prebaci ekran na uređaj"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Emitiranje ekrana na uređaj"</string>
     <string name="media_route_chooser_searching" msgid="4776236202610828706">"Traženje uređajā…"</string>
     <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Postavke"</string>
     <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Prekini vezu"</string>
@@ -1486,18 +1512,21 @@
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Ukloni"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Želite li pojačati zvuk iznad preporučenog nivoa?\n\nDužim slušanjem glasnog zvuka možete oštetiti sluh."</string>
-    <string name="accessibility_shortcut_warning_dialog_title" msgid="5998592821749881862">"Prečica za pristupačnost je UKLJUČENA"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="2987297770937717543">"Držite oba dugmeta za podešavanje jačine zvuka 3 sekunde da uključite ili isključite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>.\n\nUslugu možete promijeniti ako odete u Postavke &gt; Pristupačnost."</string>
-    <string name="disable_accessibility_shortcut" msgid="3683951963271793789">"Isključi prečicu"</string>
-    <string name="leave_accessibility_shortcut_on" msgid="8762106842437042969">"Ostavi uključeno"</string>
+    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Želite li koristiti Prečicu za pristupačnost?"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Kada je prečica uključena, pritiskom na oba dugmeta za podešavanje jačine zvuka u trajanju od 3 sekunde pokrenut će se funkcija za pristupačnost.\n\n Trenutna funkcija za pristupačnost je:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Funkciju možete promijeniti ako odete u Postavke &gt; Pristupačnost."</string>
+    <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Isključi prečicu"</string>
+    <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Koristi prečicu"</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_button_prompt_text" msgid="4234556536456854251">"Izaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
+    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Da promijenite funkcije, dodirnite i držite dugme Pristupačnost."</string>
+    <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Uvećanje"</string>
     <string name="user_switched" msgid="3768006783166984410">"Trenutni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>..."</string>
     <string name="user_logging_out_message" msgid="8939524935808875155">"Odjava korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="2716755460376028154">"Vlasnik"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Greška"</string>
-    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Promjenu ne dopušta vaš administrator"</string>
+    <string name="error_message_change_not_allowed" msgid="1238035947357923497">"Vaš administrator ne dozvoljava ovu promjenu"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nije pronađena aplikacija koja će upravljati ovom akcijom."</string>
     <string name="revoke" msgid="5404479185228271586">"Opozovi"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1589,7 +1618,7 @@
     <string name="reason_service_unavailable" msgid="7824008732243903268">"Usluga štampanja nije omogućena."</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"Usluga <xliff:g id="NAME">%s</xliff:g> je instalirana"</string>
     <string name="print_service_installed_message" msgid="5897362931070459152">"Dodirnite da omogućite"</string>
-    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Unesite administratorski PIN"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"Upišite PIN kôd administratora"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Unesite PIN"</string>
     <string name="restr_pin_incorrect" msgid="8571512003955077924">"Netačno"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Trenutni PIN"</string>
@@ -1606,8 +1635,8 @@
     <string name="restr_pin_try_later" msgid="973144472490532377">"Pokušajte ponovo kasnije."</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"Prikazuje se cijeli ekran"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"Da izađete, prevucite nadolje odozgo."</string>
-    <string name="immersive_cling_positive" msgid="5016839404568297683">"Jasno mi je"</string>
-    <string name="done_label" msgid="2093726099505892398">"Završeno"</string>
+    <string name="immersive_cling_positive" msgid="5016839404568297683">"Razumijem"</string>
+    <string name="done_label" msgid="2093726099505892398">"Gotovo"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"Kružni klizač za odabir sata"</string>
     <string name="minute_picker_description" msgid="8606010966873791190">"Kružni klizač za minute"</string>
     <string name="select_hours" msgid="6043079511766008245">"Odaberite sat"</string>
@@ -1618,17 +1647,17 @@
     <string name="managed_profile_label_badge" msgid="2355652472854327647">"Poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="lock_to_app_toast" msgid="7693684144593484">"Da biste otkačili ovaj ekran, dodirnite i držite dugme Nazad i Pregled."</string>
-    <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacija je prikačena. Na ovom uređaju nije dozvoljeno otkačivanje."</string>
+    <string name="lock_to_app_toast" msgid="6820571533009838261">"Da otkačite ovaj ekran, dodirnite i držite dugmad Nazad i Pregled."</string>
+    <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Ova aplikacija se ne može otkačiti"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"Ekran je zakačen"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran je otkačen"</string>
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Traži PIN prije nego se otkači"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Traži uzorak za otključavanje prije nego se otkači"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Traži lozinku prije nego se otkači"</string>
-    <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalirao administrator"</string>
-    <string name="package_updated_device_owner" msgid="8856631322440187071">"Ažurirao administrator"</string>
-    <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisao administrator"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se trajanje baterije produžilo, opcija za štednju baterije minimizira rad uređaja i ograničava vibriranje, usluge lokacije i većinu prijenosa podataka u pozadini. E-pošta, poruke i druge aplikacije koje se oslanjaju na sinhronizaciju ne mogu biti ažurirane dok ih ne otvorite.\n\nŠtednja baterije se automatski isključi prilikom punjenja uređaja."</string>
+    <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalirao je vaš administrator"</string>
+    <string name="package_updated_device_owner" msgid="1847154566357862089">"Ažurirao je vaš administrator"</string>
+    <string name="package_deleted_device_owner" msgid="2307122077550236438">"Izbrisao je vaš administrator"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se produžilo trajanje baterije, opcija za uštedu baterije minimizira rad uređaja i ograničava vibraciju, usluge lokacije i većinu prijenosa podataka u pozadini. E-pošta, poruke i druge aplikacije koje se oslanjaju na sinhronizaciju ne mogu se ažurirati dok ih ne otvorite.\n\nUšteda baterije se automatski isključuje prilikom punjenja uređaja."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Da bi se smanjio prijenos podataka, usluga Ušteda podataka sprečava da neke aplikacije šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može pristupiti podacima, ali se to može desiti rjeđe. To može značiti, naprimjer, da se slike ne prikazuju sve dok ih ne dodirnete."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Uključiti Uštedu podataka?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Uključi"</string>
@@ -1709,7 +1738,7 @@
       <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke su odabrane</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> stavki je odabrano</item>
     </plurals>
-    <string name="default_notification_channel_label" msgid="6950908610709016902">"Razno"</string>
+    <string name="default_notification_channel_label" msgid="5929663562028088222">"Nije kategorizirano"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Vi određujete značaj ovih obavještenja."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ovo je značajno zbog osoba koje su uključene."</string>
     <string name="user_creation_account_exists" msgid="1942606193570143289">"Da li dozvoljavate aplikaciji <xliff:g id="APP">%1$s</xliff:g> da kreira novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
@@ -1721,8 +1750,8 @@
     <string name="language_picker_section_all" msgid="3097279199511617537">"Svi jezici"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"Sve regije"</string>
     <string name="locale_search_menu" msgid="2560710726687249178">"Pretraga"</string>
-    <string name="work_mode_off_title" msgid="8954725060677558855">"Radni način rada je ISKLJUČEN"</string>
-    <string name="work_mode_off_message" msgid="3286169091278094476">"Omogući radnom profilu da funkcionira, uključujući aplikacije, sinhronizaciju u pozadini i povezane funkcije."</string>
+    <string name="work_mode_off_title" msgid="2615362773958585967">"Želite uključiti radni način?"</string>
+    <string name="work_mode_off_message" msgid="2961559609199223594">"Ovim će se uključiti vaš radni profil, uključujući aplikacije, sinhronizacija u pozadini i povezane funkcije"</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"Uključi"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Imate nove poruke"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Otvorite SMS aplikaciju da biste pregledali poruke"</string>
@@ -1760,27 +1789,38 @@
     <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"Otklanjanje grešaka putem uređaja spojenog na USB"</string>
     <string name="time_picker_hour_label" msgid="2979075098868106450">"sat"</string>
     <string name="time_picker_minute_label" msgid="5168864173796598399">"minuta"</string>
-    <string name="time_picker_header_text" msgid="143536825321922567">"Postavite vrijeme"</string>
+    <string name="time_picker_header_text" msgid="143536825321922567">"Postavljanje vremena"</string>
     <string name="time_picker_input_error" msgid="7574999942502513765">"Unesite ispravno vrijeme"</string>
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Upišite vrijeme"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Prebacite u način unosa teksta za unos vremena."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Prebacite u način rada kao sat za unos vremena."</string>
-    <!-- no translation found for autofill_picker_accessibility_title (8469043291648711535) -->
-    <skip />
-    <string name="autofill_save_title" msgid="7081244500504163245">"Želite li sačuvati u: <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
-    <string name="autofill_save_title_with_type" msgid="4977385733042555659">"Želite li sačuvati stavku <xliff:g id="TYPE">%1$s</xliff:g> u: <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+    <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opcije za automatsko popunjavanje"</string>
+    <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"Sačuvaj za automatsko popunjavanje"</string>
+    <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Sadržaje nije moguće automatski popuniti"</string>
+    <string name="autofill_picker_no_suggestions" msgid="3908514303773350735">"Nema prijedloga za automatsko popunjavanje"</string>
+    <plurals name="autofill_picker_some_suggestions" formatted="false" msgid="5506565809835815274">
+      <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> prijedlog za automatsko popunjavanje</item>
+      <item quantity="few"><xliff:g id="COUNT">%1$s</xliff:g> prijedloga za automatsko popunjavanje</item>
+      <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> prijedloga za automatsko popunjavanje</item>
+    </plurals>
+    <string name="autofill_save_title" msgid="3345527308992082601">"Želite li sačuvati u &lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_type" msgid="8637809388029313305">"Želite li da se <xliff:g id="TYPE">%1$s</xliff:g> sačuva u &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"Želite li da se <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> sačuvaju u &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"Želite li da se <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, i <xliff:g id="TYPE_2">%3$s</xliff:g> sačuvaju &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt;?"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"Sačuvaj"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"Ne, hvala"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"lozinka"</string>
     <string name="autofill_save_type_address" msgid="4936707762193009542">"adresa"</string>
     <string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kreditna kartica"</string>
-    <!-- no translation found for etws_primary_default_message_earthquake (5541962250262769193) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_tsunami (1887685943498368548) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_earthquake_and_tsunami (998797956848445862) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_test (2709597093560037455) -->
-    <skip />
+    <string name="autofill_save_type_username" msgid="239040540379769562">"korisničko ime"</string>
+    <string name="autofill_save_type_email_address" msgid="5752949432129262174">"adresa e-pošte"</string>
+    <string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Ostanite smireni i potražite sklonište u blizini."</string>
+    <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Odmah se evakuirajte iz priobalnih područja i područja oko rijeka na sigurnije mjesto kao što su viši predjeli."</string>
+    <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Ostanite smireni i potražite sklonište u blizini."</string>
+    <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test poruka za hitne slučajeve"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
+    <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM kartica nije dozvoljena"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM kartica nije dodijeljena"</string>
+    <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM kartica nije dozvoljena"</string>
+    <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefon nije dozvoljen"</string>
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index c216e10..b1d8794 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -131,17 +131,17 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"S\'està cercant el servei"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Trucades per Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi des de Configuració."</item>
+    <item msgid="3910386316304772394">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi a Configuració. (Codi d\'error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Registra\'t amb el teu operador de telefonia mòbil"</item>
+    <item msgid="7472393097168811593">"Registra\'t amb el teu operador de telefonia mòbil (codi d\'error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
     <item msgid="4397097370387921767">"Trucada de Wi-Fi de: %s"</item>
   </string-array>
     <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_wifi_preferred_summary" msgid="1994113411286935263">"Preferència per a la Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferència per a dades mòbils"</string>
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Només Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: no s\'ha desviat"</string>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. per veu"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloqueja ara"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"+999"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Contingut amagat"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contingut amagat de conformitat amb la política"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Notificació nova"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclat virtual"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teclat físic"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Seguretat"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertes"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demostració comercial"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Connexió USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplicacions que s\'estan executant en segon pla"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> s\'està executant en segon pla"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicacions s\'estan executant en segon pla"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplicacions que consumeixen bateria"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> està consumint bateria"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicacions estan consumint bateria"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Toca per obtenir informació sobre l\'ús de dades i de bateria"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode segur"</string>
@@ -1084,13 +1083,13 @@
     <string name="volume_call" msgid="3941680041282788711">"Volum en trucada"</string>
     <string name="volume_bluetooth_call" msgid="2002891926351151534">"Volum en trucada Bluetooth"</string>
     <string name="volume_alarm" msgid="1985191616042689100">"Volum de l\'alarma"</string>
-    <string name="volume_notification" msgid="2422265656744276715">"Volum de notificació"</string>
+    <string name="volume_notification" msgid="2422265656744276715">"Volum de notificacions"</string>
     <string name="volume_unknown" msgid="1400219669770445902">"Volum"</string>
     <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Volum de Bluetooth"</string>
     <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Volum del so"</string>
     <string name="volume_icon_description_incall" msgid="8890073218154543397">"Volum de trucada"</string>
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volum de multimèdia"</string>
-    <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volum de notificació"</string>
+    <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volum de notificacions"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"So predeterminat"</string>
     <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Predeterminat (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
     <string name="ringtone_silent" msgid="7937634392408977062">"Cap"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Xarxes Wi-Fi obertes disponibles</item>
       <item quantity="one">Xarxa Wi-Fi oberta disponible</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connecta\'t a una xarxa Wi-Fi oberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"S\'està connectant a una xarxa Wi-Fi oberta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"S\'ha connectat a la xarxa Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"No s\'ha pogut connectar a una xarxa Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca per veure totes les xarxes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connecta"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Totes les xarxes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inicia la sessió a la xarxa Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Inicia la sessió a la xarxa"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB per a MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connectat a un accessori USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Toca per veure més opcions."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"S\'ha detectat un accessori d\'àudio analògic"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"El dispositiu connectat no és compatible amb aquest telèfon. Toca per obtenir més informació."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuració USB activada"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Toca per desactivar la depuració USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecciona per desactivar la depuració USB"</string>
@@ -1195,7 +1203,7 @@
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTEIX"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"REBUTJA"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Canvia el teclat"</string>
-    <string name="show_ime" msgid="2506087537466597099">"El deixa a la pantalla mentre el teclat físic està actiu"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Mantén-lo a la pantalla mentre el teclat físic està actiu"</string>
     <string name="hardware" msgid="194658061510127999">"Mostra el teclat virtual"</string>
     <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configura el teclat físic"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toca per seleccionar l\'idioma i el disseny"</string>
@@ -1281,7 +1289,7 @@
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fons de pantalla"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Canvia el fons de pantalla"</string>
     <string name="notification_listener_binding_label" msgid="2014162835481906429">"Oient de notificacions"</string>
-    <string name="vr_listener_binding_label" msgid="4316591939343607306">"Processador de RV"</string>
+    <string name="vr_listener_binding_label" msgid="4316591939343607306">"Processador d\'RV"</string>
     <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Proveïdor de condicions"</string>
     <string name="notification_ranker_binding_label" msgid="774540592299064747">"Servei de classificació de notificacions"</string>
     <string name="vpn_title" msgid="19615213552042827">"VPN activada"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Connectat a <xliff:g id="SESSION">%s</xliff:g>. Pica per gestionar la xarxa."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"T\'estàs connectant a la VPN sempre activada…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Estàs connectat a la VPN sempre activada"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"La VPN sempre activada està desconnectada"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"S\'ha desconnectat de la VPN sempre activada"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Error de la VPN sempre activada"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Toca per configurar"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Canvia la configuració de la xarxa o de la VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Tria un fitxer"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"No s\'ha escollit cap fitxer"</string>
     <string name="reset" msgid="2448168080964209908">"Restableix"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Toca per sortir del mode de cotxe."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Compartició de xarxa o punt d\'accés Wi-Fi activat"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Toca per configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"La compartició de xarxa està desactivada"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacta amb el teu administrador per obtenir més informació"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Enrere"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Següent"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Omet"</string>
@@ -1454,7 +1460,7 @@
     <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Codi PIN incorrecte."</string>
     <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Escriu un PIN que tingui de 4 a 8 números."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"El codi PUK ha de tenir 8 números."</string>
-    <string name="kg_invalid_puk" msgid="3638289409676051243">"Torna a introduir el codi PUK correcte. Els intents repetits faran que es desactivi la SIM de manera permanent."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Torna a introduir el codi PUK correcte. Els intents repetits faran que es desactivi la SIM permanentment."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Els codis PIN no coincideixen"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Massa intents incorrectes"</string>
     <string name="kg_login_instructions" msgid="1100551261265506448">"Per desbloquejar el telèfon, inicia la sessió amb el compte de Google."</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"No fixis"</string>
     <string name="app_info" msgid="6856026610594615344">"Informació de l\'aplicació"</string>
     <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Vols restablir el dispositiu?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Toca per restablir el dispositiu"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"S\'està iniciant la demostració…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"S\'està restablint el dispositiu…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Vols restablir el dispositiu?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Perdràs els canvis, i la demostració tornarà a començar d\'aquí a <xliff:g id="TIMEOUT">%1$s</xliff:g> segons…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Cancel·la"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Restableix ara"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> s\'ha desactivat"</string>
     <string name="conference_call" msgid="3751093130790472426">"Conferència"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Descripció emergent"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Abandona immediatament les regions costaneres i riberenques, i cerca un lloc més segur, com ara un terreny elevat."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantén la calma i busca refugi a prop."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Prova de missatges d\'emergència"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Respon"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM no compatible"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM no proporcionada"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 4d80182..9003a1d 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -133,10 +133,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Vyhledávání služby"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Volání přes Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Chcete-li volat a odesílat textové zprávy přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení."</item>
+    <item msgid="3910386316304772394">"Chcete-li volat a odesílat SMS přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení. (Kód chyby: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Registrace u operátora"</item>
+    <item msgid="7472393097168811593">"Zaregistrujte se u operátora (Kód chyby: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -252,8 +252,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Hlas. asistence"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zamknout"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Skrytý obsah"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Obsah skrytý zásadami"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Nové oznámení"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuální klávesnice"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fyzická klávesnice"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Zabezpečení"</string>
@@ -269,9 +268,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozornění"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Prodejní ukázka"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Připojení USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikace běžící na pozadí"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> běží na pozadí"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Aplikace (<xliff:g id="NUMBER">%1$d</xliff:g>) běží na pozadí"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikace spotřebovávají baterii"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> využívá baterii"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Aplikace (<xliff:g id="NUMBER">%1$d</xliff:g>) využívají baterii"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Klepnutím zobrazíte podrobnosti o využití baterie a dat"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Nouzový režim"</string>
@@ -1110,7 +1109,7 @@
     <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Než spustíte novou aplikaci, je třeba zastavit jinou spuštěnou aplikaci."</string>
     <string name="old_app_action" msgid="493129172238566282">"Návrat do aplikace <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
     <string name="old_app_description" msgid="2082094275580358049">"Nespouštět novou aplikaci."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Spustit aplikaci <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+    <string name="new_app_action" msgid="5472756926945440706">"Do aplikace <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="1932143598371537340">"Zastavit starou aplikaci bez uložení."</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"Proces <xliff:g id="PROC">%1$s</xliff:g> překročil limit paměti"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Byl shromážděn výpis haldy, klepnutím jej můžete sdílet"</string>
@@ -1150,6 +1149,13 @@
       <item quantity="other">K dispozici jsou veřejné sítě Wi-Fi</item>
       <item quantity="one">K dispozici je veřejná síť Wi-Fi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Připojení k otevřené síti Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Připojování k otevřené síti Wi-Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Připojeno k síti Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Připojení k síti Wi-Fi se nezdařilo"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všechny sítě"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Připojit"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Všechny sítě"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Přihlásit se k síti Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Přihlásit se k síti"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1229,6 +1235,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB v režimu MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Připojeno k perifernímu zařízení USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Klepnutím zobrazíte další možnosti."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Bylo zjištěno analogové zvukové příslušenství"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Připojené zařízení není s tímto telefonem kompatibilní. Klepnutím zobrazíte další informace."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes USB připojeno"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Klepnutím zakážete ladění USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vyberte, chcete-li zakázat ladění USB."</string>
@@ -1334,9 +1342,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Připojeno k relaci <xliff:g id="SESSION">%s</xliff:g>. Klepnutím můžete síť spravovat."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Připojování k trvalé síti VPN…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Je připojena trvalá síť VPN"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Trvalá síť VPN je odpojena"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Odpojeno od trvalé sítě VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Chyba trvalé sítě VPN"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Klepnutím přejděte do Nastavení"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Změňte síť nebo nastavení VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Zvolit soubor"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Není vybrán žádný soubor"</string>
     <string name="reset" msgid="2448168080964209908">"Resetovat"</string>
@@ -1345,8 +1353,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Klepnutím ukončíte režim V autě."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Sdílené připojení nebo hotspot je aktivní."</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Klepnutím zahájíte nastavení."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering je zakázán"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"O podrobnosti požádejte administrátora"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Zpět"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Další"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Přeskočit"</string>
@@ -1787,16 +1793,10 @@
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Klepnutím zobrazíte soubory"</string>
     <string name="pin_target" msgid="3052256031352291362">"Připnout"</string>
     <string name="unpin_target" msgid="3556545602439143442">"Odepnout"</string>
-    <string name="app_info" msgid="6856026610594615344">"Informace o aplikaci"</string>
+    <string name="app_info" msgid="6856026610594615344">"O aplikaci"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Resetovat zařízení?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Zařízení resetujete klepnutím"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Spouštění ukázky…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Resetování zařízení…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Resetovat zařízení?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Ztratíte všechny provedené změny a ukázka se za <xliff:g id="TIMEOUT">%1$s</xliff:g> s spustí znovu…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Zrušit"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Resetovat"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> – zakázáno"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konferenční hovor"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Popisek"</string>
@@ -1842,6 +1842,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Z pobřežních oblastí a okolí řek se co nejrychleji přesuňte do většího bezpečí (například na výše položené místo)."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Zachovejte klid a přesuňte se na bezpečné místo v okolí."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test nouzových zpráv"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Odpovědět"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM karta není povolena"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM karta není poskytována"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 2fc542b..9c1d3b8 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Søger efter tjeneste"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Opkald via Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Hvis du vil foretage opkald og sende beskeder via Wi-Fi, skal du først anmode dit mobilselskab om at konfigurere denne tjeneste. Derefter skal du slå Wi-Fi-opkald til igen fra Indstillinger."</item>
+    <item msgid="3910386316304772394">"Hvis du vil foretage opkald og sende beskeder via Wi-Fi, skal du først anmode dit mobilselskab om at konfigurere denne tjeneste. Derefter skal du aktivere Wi-Fi-opkald igen fra Indstillinger. (Fejlkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Registrer dig hos dit mobilselskab"</item>
+    <item msgid="7472393097168811593">"Registrer dig hos dit mobilselskab (fejlkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Taleassistent"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lås nu"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Indholdet er skjult"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Indholdet er skjult af politikken"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Ny underretning"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuelt tastatur"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fysisk tastatur"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Sikkerhed"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Underretninger"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo til udstilling i butik"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-forbindelse"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps, der kører i baggrunden"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> kører i baggrunden"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps kører i baggrunden"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps, der bruger batteri"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> bruger batteri"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps bruger batteri"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tryk for at se oplysninger om batteri- og dataforbrug"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Sikker tilstand"</string>
@@ -783,7 +782,7 @@
     <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Brugervælger"</string>
     <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
     <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
-    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Mediekontrolelementer"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Mediestyring"</string>
     <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Omrokering af widgets er påbegyndt."</string>
     <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Omrokering af widgets er afsluttet."</string>
     <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widgetten <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> er slettet."</string>
@@ -1106,6 +1105,13 @@
       <item quantity="one">Åbne Wi-Fi-netværk er tilgængelige</item>
       <item quantity="other">Åbne Wi-Fi-netværk er tilgængelige</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Opret forbindelse til et åbent Wi-Fi-netværk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Opretter forbindelse til et åbent Wi‑Fi-netværk"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Forbundet til Wi-Fi-netværket"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Der kan ikke oprettes forbindelse til Wi-Fi-netværket"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryk for at se alle netværk"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Opret forbindelse"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle netværk"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Log ind på Wi-Fi-netværk"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Log ind på netværk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1178,13 +1184,15 @@
     <string name="no_permissions" msgid="7283357728219338112">"Der kræves ingen tilladelser"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"dette kan koste dig penge"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
-    <string name="usb_charging_notification_title" msgid="6895185153353640787">"USB, der oplader denne enhed"</string>
+    <string name="usb_charging_notification_title" msgid="6895185153353640787">"USB oplader denne enhed"</string>
     <string name="usb_supplying_notification_title" msgid="5310642257296510271">"USB, der leverer strøm til den tilsluttede enhed"</string>
     <string name="usb_mtp_notification_title" msgid="8396264943589760855">"USB til filoverførsel"</string>
     <string name="usb_ptp_notification_title" msgid="1347328437083192112">"USB til billedoverførsel"</string>
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB til MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tilsluttet et USB-ekstraudstyr"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tryk for at se flere muligheder."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Der blev registreret et analogt lydtilbehør"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Den tilsluttede enhed er ikke kompatibel med denne telefon. Tryk for at få flere oplysninger."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning er tilsluttet"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tryk for at deaktivere fejlretning via USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vælg for at deaktivere USB-fejlretning."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Forbundet til <xliff:g id="SESSION">%s</xliff:g>. Tryk for at administrere netværket."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Opretter forbindelse til konstant VPN…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Konstant VPN er forbundet"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Forbindelsen til konstant VPN er afbrudt"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Forbindelsen til konstant VPN blev afbrudt"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Fejl i konstant VPN"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Tryk for at konfigurere"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Skift netværks- eller VPN-indstillinger"</string>
     <string name="upload_file" msgid="2897957172366730416">"Vælg fil"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Ingen fil er valgt"</string>
     <string name="reset" msgid="2448168080964209908">"Nulstil"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tryk for at afslutte biltilstand."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Netdeling eller hotspot er aktivt"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tryk for at konfigurere"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Netdeling er deaktiveret"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakt din administrator for at få oplysninger"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Tilbage"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Næste"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Spring over"</string>
@@ -1721,16 +1727,10 @@
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tryk for at se filer"</string>
     <string name="pin_target" msgid="3052256031352291362">"Fastgør"</string>
     <string name="unpin_target" msgid="3556545602439143442">"Frigør"</string>
-    <string name="app_info" msgid="6856026610594615344">"Oplysninger om appen"</string>
+    <string name="app_info" msgid="6856026610594615344">"Appinfo"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Vil du nulstille enheden?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Tryk for at nulstille enheden"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Starter demoen…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Nulstiller enheden…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Vil du nulstille enheden?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Du mister alle ændringer, og demoen starter igen om <xliff:g id="TIMEOUT">%1$s</xliff:g> sekunder…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Annuller"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Nulstil nu"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> – deaktiveret"</string>
     <string name="conference_call" msgid="3751093130790472426">"Telefonmøde"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Værktøjstip"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Forlad omgående kyst- og flodområder, og søg mod et mere sikkert sted, f.eks. et højere terræn."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Bevar roen, og søg ly i nærheden."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test af nødbeskeder"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Svar"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-kortet har ikke adgangstilladelse"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-kortet er ikke aktiveret"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 69d344b..269342c 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Suche nach Dienst"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Anrufe über WLAN"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann erneut über die Einstellungen."</item>
+    <item msgid="3910386316304772394">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann noch einmal über die Einstellungen. (Fehlercode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Registriere dich bei deinem Mobilfunkanbieter."</item>
+    <item msgid="7472393097168811593">"Registriere dich bei deinem Mobilfunkanbieter (Fehlercode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Sprachassistent"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Jetzt sperren"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Inhalte ausgeblendet"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Inhalte aufgrund der Richtlinien ausgeblendet"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Neue Benachrichtigung"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Bildschirmtastatur"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Physische Tastatur"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Sicherheit"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Warnmeldungen"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo für Einzelhandel"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-Verbindung"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps, die im Hintergrund ausgeführt werden"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> wird im Hintergrund ausgeführt"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> Apps werden im Hintergrund ausgeführt"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Strom verbrauchende Apps"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> verbraucht Strom"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> Apps verbrauchen Strom"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Für Details zur Akku- und Datennutzung tippen"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Abgesicherter Modus"</string>
@@ -1099,13 +1098,20 @@
     <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Benachrichtigungstöne"</string>
     <string name="ringtone_unknown" msgid="3914515995813061520">"Unbekannt"</string>
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
-      <item quantity="other">WLANe verfügbar</item>
+      <item quantity="other">WLANs verfügbar</item>
       <item quantity="one">WLAN verfügbar</item>
     </plurals>
     <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
-      <item quantity="other">Verfügbare WLANe öffnen</item>
+      <item quantity="other">Verfügbare WLANs öffnen</item>
       <item quantity="one">Verfügbares WLAN öffnen</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Mit offenem WLAN verbinden"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Verbindung mit offenem WLAN wird hergestellt"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Mit WLAN verbunden"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"WLAN-Verbindung konnte nicht hergestellt werden"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tippen, um alle Netzwerke zu sehen"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinden"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle Netzwerke"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"In WLAN anmelden"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Im Netzwerk anmelden"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB für MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Mit USB-Zubehör verbunden"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Für weitere Optionen tippen."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analoges Audiozubehör erkannt"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Das angeschlossene Gerät ist nicht mit diesem Smartphone kompatibel. Für weitere Informationen tippen."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging aktiviert"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Zum Deaktivieren von USB-Debugging tippen"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB-Debugging deaktivieren: auswählen"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Verbunden mit <xliff:g id="SESSION">%s</xliff:g>. Zum Verwalten des Netzwerks tippen"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Verbindung zu durchgehend aktivem VPN wird hergestellt…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Mit durchgehend aktivem VPN verbunden"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Verbindung zu durchgehend aktivem VPN getrennt"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Verbindung mit dauerhaft aktivem VPN getrennt"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Durchgehend aktives VPN – Verbindungsfehler"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Zum Einrichten tippen"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Netzwerk- oder VPN-Einstellungen ändern"</string>
     <string name="upload_file" msgid="2897957172366730416">"Datei auswählen"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Keine ausgewählt"</string>
     <string name="reset" msgid="2448168080964209908">"Zurücksetzen"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Zum Beenden des Automodus tippen."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering oder Hotspot aktiv"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Zum Einrichten tippen."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering ist deaktiviert"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Bitte wende dich für weitere Informationen an den Administrator"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Zurück"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Weiter"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Überspringen"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Markierung entfernen"</string>
     <string name="app_info" msgid="6856026610594615344">"App-Informationen"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Gerät zurücksetzen?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Zum Zurücksetzen des Geräts tippen"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Demo wird gestartet…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Gerät wird zurückgesetzt…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Gerät zurücksetzen?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Alle Änderungen gehen verloren und Demo wird in <xliff:g id="TIMEOUT">%1$s</xliff:g> Sekunden neu gestartet…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Abbrechen"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Jetzt zurücksetzen"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> deaktiviert"</string>
     <string name="conference_call" msgid="3751093130790472426">"Telefonkonferenz"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Kurzinfo"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Verlasse so schnell wie möglich Flussufer und Küstengebiete und suche in einer höher gelegenen Umgebung Schutz."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Bleibe ruhig und suche in der Nähe Schutz."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test der Notfallwarnungen"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Antworten"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-Karte nicht zulässig"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM nicht eingerichtet"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 466c9fa..d8abf8a 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -54,7 +54,7 @@
     <string name="serviceErased" msgid="1288584695297200972">"Η διαγραφή ήταν επιτυχής."</string>
     <string name="passwordIncorrect" msgid="7612208839450128715">"Λανθασμένος κωδικός πρόσβασης."</string>
     <string name="mmiComplete" msgid="8232527495411698359">"Το MMI ολοκληρώθηκε."</string>
-    <string name="badPin" msgid="9015277645546710014">"Ο παλιός αριθμός PIN που πληκτρολογήσατε είναι λάθος."</string>
+    <string name="badPin" msgid="9015277645546710014">"Το παλιό PIN που πληκτρολογήσατε είναι λάθος."</string>
     <string name="badPuk" msgid="5487257647081132201">"Ο κωδικός PUK που πληκτρολογήσατε είναι λάθος."</string>
     <string name="mismatchPin" msgid="609379054496863419">"Οι αριθμοί PIN που πληκτρολογήσατε δεν ταιριάζουν."</string>
     <string name="invalidPin" msgid="3850018445187475377">"Πληκτρολογήστε έναν αριθμό PIN μεγέθους 4 έως 8 αριθμών."</string>
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Αναζήτηση υπηρεσιών"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Κλήση Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά τη λειτουργία κλήσεων μέσω Wi-Fi από τις Ρυθμίσεις."</item>
+    <item msgid="3910386316304772394">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά την Κλήση Wi-Fi από τις Ρυθμίσεις. (Κωδικός σφάλματος: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Εγγραφείτε μέσω της εταιρείας κινητής τηλεφωνίας"</item>
+    <item msgid="7472393097168811593">"Εγγραφείτε μέσω της εταιρείας κινητής τηλεφωνίας που χρησιμοποιείτε (Κωδικός σφάλματος: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Φων.υποβοηθ."</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Κλείδωμα τώρα"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Κρυφό περιεχόμενο"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Το περιεχόμενο είναι κρυφό βάσει πολιτικής"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Νέα ειδοποίηση"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Εικονικό πληκτρολόγιο"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Φυσικό πληκτρολόγιο"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Ασφάλεια"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ειδοποιήσεις"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Επίδειξη λιανικής"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Σύνδεση USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Εφαρμογές που εκτελούνται στο παρασκήνιο"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> εκτελείται στο παρασκήνιο"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> εφαρμογές εκτελούνται στο παρασκήνιο"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Εφαρμογές που καταναλώνουν μπαταρία"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> χρησιμοποιεί μπαταρία"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> εφαρμογές χρησιμοποιούν μπαταρία"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Πατήστε για λεπτομέρειες σχετικά με τη χρήση μπαταρίας και δεδομένων"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Ασφαλής λειτουργία"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Υπάρχουν διαθέσιμα ανοικτά δίκτυα Wi-Fi</item>
       <item quantity="one">Υπάρχει διαθέσιμο ανοικτό δίκτυο Wi-Fi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Σύνδεση σε ανοιχτό δίκτυο Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Σύνδεση σε ανοιχτό δίκτυο Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ολοκληρώθηκε η σύνδεση στο δίκτυο Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Δεν ήταν δυνατή η σύνδεση σε δίκτυο Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Πατήστε για να δείτε όλα τα δίκτυα"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Σύνδεση"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Όλα τα δίκτυα"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Συνδεθείτε στο δίκτυο Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Σύνδεση στο δίκτυο"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB για MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Σύνδεση σε αξεσουάρ USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Πατήστε για περισσότερες επιλογές."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Εντοπίστηκε αναλογικό αξεσουάρ ήχου"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Η συνδεδεμένη συσκευή δεν είναι συμβατή με αυτό το τηλέφωνο. Πατήστε για να μάθετε περισσότερα."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Πατήστε για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Επιλογή για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Συνδέθηκε με <xliff:g id="SESSION">%s</xliff:g>. Πατήστε για να διαχειριστείτε το δίκτυο."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Σύνδεση πάντα ενεργοποιημένου VPN…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Έχει συνδεθεί πάντα ενεργοποιημένο VPN"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Το πάντα ενεργοποιημένο VPN αποσυνδέθηκε"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Αποσύνδεση από μονίμως ενεργό VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Σφάλμα πάντα ενεργοποιημένου VPN"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Πατήστε για ρύθμιση"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Αλλαγή δικτύου ή ρυθμίσεις VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Επιλογή αρχείου"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Δεν επιλέχθηκε κανένα αρχείο."</string>
     <string name="reset" msgid="2448168080964209908">"Επαναφορά"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Πατήστε για έξοδο από τη λειτουργία αυτοκινήτου."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Πρόσδεση ή σύνδεση σημείου πρόσβασης ενεργή"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Πατήστε για ρύθμιση."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Η σύνδεση είναι απενεργοποιημένη"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Επικοινωνήστε με τον διαχειριστή σας για λεπτομέρειες"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Πίσω"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Επόμενο"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Παράλειψη"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Ξεκαρφίτσωμα"</string>
     <string name="app_info" msgid="6856026610594615344">"Πληροφορίες εφαρμογής"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Να γίνει επαναφορά της συσκευής;"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Πατήστε για επαναφορά της συσκευής"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Έναρξη επίδειξης…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Επαναφορά συσκευής…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Να γίνει επαναφορά της συσκευής;"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Τυχόν αλλαγές που πραγματοποιήσατε θα χαθούν και η επίδειξη θα ξεκινήσει ξανά σε <xliff:g id="TIMEOUT">%1$s</xliff:g> δευτερόλεπτα…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Ακύρωση"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Επαναφορά τώρα"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Απενεργοποιημένο <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Κλήση συνδιάσκεψης"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Επεξήγηση εργαλείου"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Εκκενώστε αμέσως τις παράκτιες περιοχές και τις περιοχές δίπλα σε ποτάμια και μετακινηθείτε σε ένα ασφαλέστερο μέρος, όπως περιοχές με υψόμετρο."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Μείνετε ψύχραιμοι και αναζητήστε κάποιο κοντινό καταφύγιο."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Δοκιμαστικό μήνυμα έκτακτης ανάγκης"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Απάντηση"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Η κάρτα SIM δεν επιτρέπεται"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Δεν παρέχεται κάρτα SIM"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index afc977a..8bbf74a 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+    <item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Register with your operator"</item>
+    <item msgid="7472393097168811593">"Register with your operator (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Contents hidden"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contents hidden by policy"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"New notification"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtual keyboard"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Physical keyboard"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Security"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Retail demo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB connection"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps running in background"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running in the background"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are running in the background"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps consuming battery"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tap for details on battery and data usage"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Open Wi-Fi networks available</item>
       <item quantity="one">Open Wi-Fi network available</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connect to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connecting to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connected to Wi‑Fi network"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Could not connect to Wi‑Fi network"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"All Networks"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Sign in to a Wi-Fi network"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB for MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tap for more options."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analogue audio accessory detected"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"The attached device is not compatible with this phone. Tap to learn more."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tap to disable USB debugging."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Connected to <xliff:g id="SESSION">%s</xliff:g>. Tap to manage the network."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Always-on VPN connecting…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Always-on VPN connected"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Always-on VPN disconnected"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Disconnected from always-on VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Always-on VPN error"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Tap to set up"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Change network or VPN settings"</string>
     <string name="upload_file" msgid="2897957172366730416">"Choose file"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"No file chosen"</string>
     <string name="reset" msgid="2448168080964209908">"Reset"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tap to exit car mode."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Back"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Next"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Skip"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Unpin"</string>
     <string name="app_info" msgid="6856026610594615344">"App info"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Reset device?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Tap to reset device"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Starting demo…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Resetting device…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Reset device?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"You\'ll lose any changes and the demo will start again in <xliff:g id="TIMEOUT">%1$s</xliff:g> seconds…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Cancel"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Reset now"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Disabled <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Conference Call"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Tooltip"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacuate immediately from coastal regions and riverside areas to a safer place such as high ground."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Stay calm and seek shelter nearby."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Emergency messages test"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Reply"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM not allowed"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM not provisioned"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index afc977a..8bbf74a 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+    <item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Register with your operator"</item>
+    <item msgid="7472393097168811593">"Register with your operator (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Contents hidden"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contents hidden by policy"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"New notification"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtual keyboard"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Physical keyboard"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Security"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Retail demo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB connection"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps running in background"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running in the background"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are running in the background"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps consuming battery"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tap for details on battery and data usage"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Open Wi-Fi networks available</item>
       <item quantity="one">Open Wi-Fi network available</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connect to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connecting to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connected to Wi‑Fi network"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Could not connect to Wi‑Fi network"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"All Networks"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Sign in to a Wi-Fi network"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB for MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tap for more options."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analogue audio accessory detected"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"The attached device is not compatible with this phone. Tap to learn more."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tap to disable USB debugging."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Connected to <xliff:g id="SESSION">%s</xliff:g>. Tap to manage the network."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Always-on VPN connecting…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Always-on VPN connected"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Always-on VPN disconnected"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Disconnected from always-on VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Always-on VPN error"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Tap to set up"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Change network or VPN settings"</string>
     <string name="upload_file" msgid="2897957172366730416">"Choose file"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"No file chosen"</string>
     <string name="reset" msgid="2448168080964209908">"Reset"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tap to exit car mode."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Back"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Next"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Skip"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Unpin"</string>
     <string name="app_info" msgid="6856026610594615344">"App info"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Reset device?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Tap to reset device"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Starting demo…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Resetting device…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Reset device?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"You\'ll lose any changes and the demo will start again in <xliff:g id="TIMEOUT">%1$s</xliff:g> seconds…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Cancel"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Reset now"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Disabled <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Conference Call"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Tooltip"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacuate immediately from coastal regions and riverside areas to a safer place such as high ground."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Stay calm and seek shelter nearby."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Emergency messages test"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Reply"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM not allowed"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM not provisioned"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index afc977a..8bbf74a 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+    <item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Register with your operator"</item>
+    <item msgid="7472393097168811593">"Register with your operator (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Contents hidden"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contents hidden by policy"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"New notification"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtual keyboard"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Physical keyboard"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Security"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Retail demo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB connection"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps running in background"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running in the background"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are running in the background"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps consuming battery"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are using battery"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tap for details on battery and data usage"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Open Wi-Fi networks available</item>
       <item quantity="one">Open Wi-Fi network available</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connect to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connecting to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connected to Wi‑Fi network"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Could not connect to Wi‑Fi network"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"All Networks"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Sign in to a Wi-Fi network"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB for MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tap for more options."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analogue audio accessory detected"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"The attached device is not compatible with this phone. Tap to learn more."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tap to disable USB debugging."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Connected to <xliff:g id="SESSION">%s</xliff:g>. Tap to manage the network."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Always-on VPN connecting…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Always-on VPN connected"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Always-on VPN disconnected"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Disconnected from always-on VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Always-on VPN error"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Tap to set up"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Change network or VPN settings"</string>
     <string name="upload_file" msgid="2897957172366730416">"Choose file"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"No file chosen"</string>
     <string name="reset" msgid="2448168080964209908">"Reset"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tap to exit car mode."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Back"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Next"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Skip"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Unpin"</string>
     <string name="app_info" msgid="6856026610594615344">"App info"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Reset device?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Tap to reset device"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Starting demo…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Resetting device…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Reset device?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"You\'ll lose any changes and the demo will start again in <xliff:g id="TIMEOUT">%1$s</xliff:g> seconds…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Cancel"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Reset now"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Disabled <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Conference Call"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Tooltip"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacuate immediately from coastal regions and riverside areas to a safer place such as high ground."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Stay calm and seek shelter nearby."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Emergency messages test"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Reply"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM not allowed"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM not provisioned"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 4808a7a..99c1e4f 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servicio"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Llamada por Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para realizar llamadas o enviar mensajes por Wi-Fi, primero solicítale al proveedor que instale el servicio. Luego, vuelve a activar las llamadas por Wi-Fi desde Configuración."</item>
+    <item msgid="3910386316304772394">"Para hacer llamadas y enviar mensajes mediante Wi-Fi, solicítale a tu proveedor que configure este servicio. Luego, vuelve a activar la Llamada con Wi-Fi en Configuración. (código de error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Regístrate con tu proveedor."</item>
+    <item msgid="7472393097168811593">"Regístrate con tu proveedor (código de error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear ahora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Contenidos ocultos"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenido oculto debido a la política"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Notificación nueva"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclado virtual"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teclado físico"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Seguridad"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo para punto de venta"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Conexión USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps que se ejecutan en segundo plano"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando en segundo plano"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps se están ejecutando en segundo plano"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps que consumen batería"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> está consumiendo batería"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps están consumiendo batería"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Presiona para obtener información sobre el uso de datos y de la batería"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Abrir redes de Wi-Fi disponibles</item>
       <item quantity="one">Abrir red de Wi-Fi disponible</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectarse a una red Wi-Fi abierta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectándose a una red Wi-Fi abierta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Se conectó a la red Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"No fue posible conectarse a la red Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Presiona para ver todas las redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas las redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Accede a una red Wi-Fi."</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Acceder a la red"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Presiona para ver más opciones."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Se detectó un accesorio de audio analógico"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"El dispositivo adjunto no es compatible con este teléfono. Presiona para obtener más información."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración por USB conectada"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Presiona para inhabilitar la depuración por USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para desactivar la depuración por USB"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Conectado a <xliff:g id="SESSION">%s</xliff:g>. Pulsa para gestionar la red."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Estableciendo conexión con la VPN siempre activada..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Se estableció conexión con la VPN siempre activada."</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Se desconectó la VPN siempre activada"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Desconectado de la VPN siempre activa"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Se produjo un error al establecer conexión con la VPN siempre activada."</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Presiona para configurar"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Cambiar configuración de red o VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Elegir archivo"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"No se seleccionó un archivo."</string>
     <string name="reset" msgid="2448168080964209908">"Restablecer"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Presiona para salir del modo auto."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Anclaje a red o zona activa conectados"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Presiona para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Se inhabilitó la conexión mediante dispositivo portátil"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Para obtener más información, comunícate con el administrador"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Atrás"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Siguiente"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Omitir"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"No fijar"</string>
     <string name="app_info" msgid="6856026610594615344">"Información de apps"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"¿Deseas restablecer el dispositivo?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Presiona para restablecer el dispositivo"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Iniciando demostración…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Restableciendo dispositivo…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"¿Deseas restablecer el dispositivo?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Se perderán los cambios y la demostración volverá a iniciarse en <xliff:g id="TIMEOUT">%1$s</xliff:g> segundos…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Cancelar"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Restablecer ahora"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Se inhabilitó <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Conferencia"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Información sobre la herramienta"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacúa inmediatamente las regiones costeras y ribereñas en busca de un lugar seguro, como un terreno elevado."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantén la calma y busca un refugio cercano."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Prueba de mensajes de emergencia"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Responder"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM no permitida"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM no provista"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 651c5fe..d5216a9 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servicio"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Llamadas Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para hacer llamadas y enviar mensajes por Wi-Fi, debes pedir antes a tu operador que configure este servicio. Una vez hecho esto, vuelva a activar las llamadas Wi-Fi en Ajustes."</item>
+    <item msgid="3910386316304772394">"Para hacer llamadas y enviar mensajes por Wi-Fi, pide antes a tu operador que configure este servicio. Una vez hecho esto, vuelva a activar la llamada por Wi-Fi en Ajustes. (Código de error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Regístrate con tu operador"</item>
+    <item msgid="7472393097168811593">"Regístrate con tu operador (código de error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -142,7 +142,7 @@
   </string-array>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desactivado"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferir Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferencia a datos móviles"</string>
+    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferir datos móviles"</string>
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Solo conexión Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: No desviada"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear ahora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt; 999"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Contenidos ocultos"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenidos ocultos por política"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Notificación nueva"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclado virtual"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teclado físico"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Seguridad"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo para tiendas"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Conexión USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplicaciones que se están ejecutando en segundo plano"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando en segundo plano"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicaciones se están ejecutando en segundo plano"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplicaciones que consumen batería"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> está usando la batería"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicaciones están usando la batería"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Toca para ver información detallada sobre el uso de datos y de la batería"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
@@ -530,12 +529,12 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permite que la aplicación modifique cómo se registra el uso de red en relación con las aplicaciones. Las aplicaciones normales no deben usar este permiso."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"acceder a las notificaciones"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permite que la aplicación recupere, examine y borre notificaciones, incluidas las que han publicado otras aplicaciones."</string>
-    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"enlazar con un servicio de detector de notificaciones"</string>
-    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite enlazar con la interfaz de nivel superior de un servicio de detector de notificaciones. No debe ser necesario para las aplicaciones normales."</string>
-    <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"enlazar con un servicio de proveedor de condiciones"</string>
-    <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Permite enlazar con la interfaz de nivel superior de un servicio de proveedor de condiciones. Las aplicaciones normales no deberían necesitar este permiso."</string>
-    <string name="permlab_bindDreamService" msgid="4153646965978563462">"enlazar con un servicio de salvapantallas"</string>
-    <string name="permdesc_bindDreamService" msgid="7325825272223347863">"Permite enlazar con la interfaz de nivel superior de un servicio de salvapantallas. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"vincular con un servicio de detector de notificaciones"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite vincular con la interfaz de nivel superior de un servicio de detector de notificaciones. No debe ser necesario para las aplicaciones normales."</string>
+    <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"vincular con un servicio de proveedor de condiciones"</string>
+    <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Permite vincular con la interfaz de nivel superior de un servicio de proveedor de condiciones. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_bindDreamService" msgid="4153646965978563462">"vincular con un servicio de salvapantallas"</string>
+    <string name="permdesc_bindDreamService" msgid="7325825272223347863">"Permite vincular con la interfaz de nivel superior de un servicio de salvapantallas. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"ejecutar la aplicación de configuración proporcionada por el operador"</string>
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite ejecutar la aplicación de configuración proporcionada por el operador. No debe ser necesario para aplicaciones normales."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"detectar cambios en el estado de la red"</string>
@@ -548,10 +547,10 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permite que esta aplicación reciba información sobre las transferencias actuales de Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"quitar certificados DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Permite a una aplicación eliminar los certificados DRM. Las aplicaciones normales no deberí­an necesitar este permiso."</string>
-    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"enlazar con el servicio de mensajería de un operador"</string>
-    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Permite enlazar con la interfaz de nivel superior del servicio de mensajería de un operador. Las aplicaciones normales no deberían necesitar este permiso."</string>
-    <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"enlazar con servicios de operador"</string>
-    <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"Permite enlazar con servicios de operador. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"vincular con el servicio de mensajería de un operador"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Permite vincular con la interfaz de nivel superior del servicio de mensajería de un operador. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"vincular con servicios de operador"</string>
+    <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"Permite vincular con servicios de operador. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_access_notification_policy" msgid="4247510821662059671">"acceso a No molestar"</string>
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permite que la aplicación lea y modifique la configuración de No molestar."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecimiento de reglas de contraseña"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Redes Wi-Fi abiertas disponibles</item>
       <item quantity="one">Red Wi-Fi abierta disponible</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectarse a una red Wi-Fi abierta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectándose a una red Wi-Fi abierta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectado a la red Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"No se ha podido conectar a la red Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas las redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas las redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Iniciar sesión en red Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Iniciar sesión en la red"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Toca para ver más opciones."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Se ha detectado un accesorio de audio analógico"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"El dispositivo adjunto no es compatible con este teléfono. Toca para obtener más información."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB habilitada"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Toca para inhabilitar la depuración USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para inhabilitar la depuración USB"</string>
@@ -1195,7 +1203,7 @@
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTIR"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RECHAZAR"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Cambiar teclado"</string>
-    <string name="show_ime" msgid="2506087537466597099">"Debe seguir en pantalla mientras el teclado físico esté activo"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Sigue en pantalla mientras el teclado físico está activo"</string>
     <string name="hardware" msgid="194658061510127999">"Mostrar teclado virtual"</string>
     <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configura el teclado físico"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toca para seleccionar el idioma y el diseño"</string>
@@ -1217,7 +1225,7 @@
     <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"El dispositivo no admite este medio externo (<xliff:g id="NAME">%s</xliff:g>). Toca para configurarlo con un formato admitido."</string>
     <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"El dispositivo no admite esta <xliff:g id="NAME">%s</xliff:g>. Selecciónala para configurarla en un formato admitido."</string>
     <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"Extracción inesperada de <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"Desactiva tu <xliff:g id="NAME">%s</xliff:g> antes de extraer la unidad para evitar pérdidas de datos"</string>
+    <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"Desconecta tu <xliff:g id="NAME">%s</xliff:g> antes de extraer la unidad para evitar pérdidas de datos"</string>
     <string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"Tu <xliff:g id="NAME">%s</xliff:g> se ha extraído"</string>
     <string name="ext_media_nomedia_notification_message" msgid="6471542972147056586">"Tu <xliff:g id="NAME">%s</xliff:g> se ha extraído: inserta otra unidad"</string>
     <string name="ext_media_unmounting_notification_title" msgid="640674168454809372">"Expulsando <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Conectado a <xliff:g id="SESSION">%s</xliff:g>. Toca para administrar la red."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Conectando VPN siempre activada…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPN siempre activada conectada"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"VPN siempre activada desconectada"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Desconectado de VPN siempre activada"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Error de VPN siempre activada"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Toca para configurar"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Cambiar ajustes de red o VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Seleccionar archivo"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Archivo no seleccionado"</string>
     <string name="reset" msgid="2448168080964209908">"Restablecer"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Toca para salir del modo coche."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Compartir conexión/Zona Wi-Fi activada"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Toca para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"La conexión compartida está inhabilitada"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ponte en contacto con el administrador para obtener más información"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Atrás"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Siguiente"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Saltar"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"No fijar"</string>
     <string name="app_info" msgid="6856026610594615344">"Información de la aplicación"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"¿Restablecer el dispositivo?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Toca para restablecer el dispositivo"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Iniciando demostración…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Restableciendo dispositivo…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"¿Restablecer el dispositivo?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Se perderán todos los cambios y la demostración volverá a empezar en <xliff:g id="TIMEOUT">%1$s</xliff:g> segundos…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Cancelar"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Restablecer ahora"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> inhabilitado"</string>
     <string name="conference_call" msgid="3751093130790472426">"Conferencia"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Descripción emergente"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Aléjate inmediatamente de las zonas costeras y situadas junto a un río para dirigirte hacia un lugar más seguro, por ejemplo, un terreno elevado."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantén la calma y busca refugio en algún lugar cercano."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Prueba de mensajes de emergencia"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Responder"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM no compatible"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM no proporcionada"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 3c85958..14debb2 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Teenuse otsimine"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"WiFi-kõned"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Üle WiFi-võrgu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse."</item>
+    <item msgid="3910386316304772394">"WiFi-võrgu kaudu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse. (Veakood: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Registreeruge operaatori juures"</item>
+    <item msgid="7472393097168811593">"Registreerige operaatori juures (veakood: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Häälabi"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lukusta kohe"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Sisu on peidetud"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Sisu on eeskirjadega peidetud"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Uus märguanne"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuaalne klaviatuur"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Füüsiline klaviatuur"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Turvalisus"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Teatised"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Poedemo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-ühendus"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Rakendusi käitatakse taustal"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> käitatakse taustal"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> rakendust käitatakse taustal"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Rakendused kasutavad akutoidet"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> kasutab akutoidet"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> rakendust kasutab akutoidet"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Aku ja andmekasutuse üksikasjade nägemiseks puudutage"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Turvarežiim"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Avatud WiFi-võrgud on saadaval</item>
       <item quantity="one">Avatud WiFi-võrk on saadaval</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Looge ühendus avatud WiFi-võrguga"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ühenduse loomine avatud WiFi-võrguga"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ühendatud WiFi-võrguga"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"WiFi-võrguga ei õnnestunud ühendust luua"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Puudutage kõikide võrkude nägemiseks"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ühenda"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Kõik võrgud"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Logi sisse WiFi-võrku"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Võrku sisselogimine"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1129,7 +1135,7 @@
     <string name="wifi_connect_alert_message" msgid="6451273376815958922">"Rakendus %1$s soovib luua ühenduse WiFi-võrguga %2$s"</string>
     <string name="wifi_connect_default_application" msgid="7143109390475484319">"Rakendus"</string>
     <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"WiFi Direct"</string>
-    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Käivitage WiFi otseühendus. See lülitab välja WiFi kliendi/leviala."</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Käivitage WiFi otseühendus. See lülitab välja WiFi kliendi/kuumkoha."</string>
     <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"WiFi otseühenduse käivitamine ebaõnnestus."</string>
     <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"WiFi Direct on sees"</string>
     <string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"Puudutage seadete nägemiseks"</string>
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI jaoks"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ühendatud USB-lisaseadmega"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Puudutage lisavalikute nägemiseks."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Tuvastati analoogne helitarvik"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Ühendatud seade ei ühildu selle telefoniga. Puudutage lisateabe saamiseks."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-silumine ühendatud"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Puudutage USB-silumise keelamiseks."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Valige USB silumise keelamiseks"</string>
@@ -1290,19 +1298,17 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Ühendatud seansiga <xliff:g id="SESSION">%s</xliff:g>. Koputage võrgu haldamiseks"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Ühendamine alati sees VPN-iga …"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Ühendatud alati sees VPN-iga"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Alati sees VPN pole ühendatud"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Ühendus alati sisselülitatud VPN-iga katkestati"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Alati sees VPN-i viga"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Puudutage seadistamiseks"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Vahetage võrku või muutke VPN-i seadeid"</string>
     <string name="upload_file" msgid="2897957172366730416">"Valige fail"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Ühtegi faili pole valitud"</string>
     <string name="reset" msgid="2448168080964209908">"Lähtesta"</string>
     <string name="submit" msgid="1602335572089911941">"Saada"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Autorežiim lubatud"</string>
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Puudutage autorežiimist väljumiseks."</string>
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Jagamine või tööpunkt on aktiivne"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Jagamine või kuumkoht on aktiivne"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Puudutage seadistamiseks."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Jagamine on keelatud"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Lisateabe saamiseks võtke ühendust oma administraatoriga"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Tagasi"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Järgmine"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Jäta vahele"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Vabasta"</string>
     <string name="app_info" msgid="6856026610594615344">"Rakenduse teave"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Kas soovite seadme lähtestada?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Puudutage seadme lähtestamiseks"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Demo käivitamine …"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Seadme lähtestamine …"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Kas soovite seadme lähtestada?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Kõik muudatused lähevad kaotsi ja demo käivitub uuesti <xliff:g id="TIMEOUT">%1$s</xliff:g> sekundi möödudes …"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Tühista"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Lähtesta kohe"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Keelatud <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konverentskõne"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Tööriistavihje"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evakueeruge ranniku ja jõekallaste piirkondadest viivitamatult ohutusse kohta, näiteks kõrgematesse kohtadesse."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Jääge rahulikuks ja otsige lähedusest peavarju."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Hädaabisõnumite test"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Vasta"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-kaart pole lubatud"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-kaart on ettevalmistamata"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 696101c..ee688fc 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Zerbitzu bila"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi bidezko deiak"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean."</item>
+    <item msgid="3910386316304772394">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean. (Errore-kodea: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Erregistratu operadorearekin"</item>
+    <item msgid="7472393097168811593">"Erregistratu operadorearekin (Errore-kodea: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ahots-laguntza"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Blokeatu"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Edukiak ezkutatuta daude"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Gidalerro batzuk ezkutatu dira, gidalerroei jarraikiz"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Jakinarazpen berria"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teklatu birtuala"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teklatu fisikoa"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Segurtasuna"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Abisuak"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Saltzaileentzako demoa"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB konexioa"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikazioak exekutatzen ari dira atzeko planoan"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> exekutatzen ari da atzeko planoan"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> exekutatzen ari dira atzeko planoan"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Bateria kontsumitzen ari diren aplikazioak"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ari da bateria erabiltzen"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikazio ari dira bateria erabiltzen"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Sakatu bateria eta datuen erabilerari buruzko xehetasunak ikusteko"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modu segurua"</string>
@@ -588,7 +587,7 @@
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Etxekoa"</item>
     <item msgid="869923650527136615">"Mugikorra"</item>
-    <item msgid="7897544654242874543">"Lanekoa"</item>
+    <item msgid="7897544654242874543">"Lantokia"</item>
     <item msgid="1103601433382158155">"Laneko faxa"</item>
     <item msgid="1735177144948329370">"Etxeko faxa"</item>
     <item msgid="603878674477207394">"Bilagailua"</item>
@@ -597,24 +596,24 @@
   </string-array>
   <string-array name="emailAddressTypes">
     <item msgid="8073994352956129127">"Etxekoa"</item>
-    <item msgid="7084237356602625604">"Lanekoa"</item>
+    <item msgid="7084237356602625604">"Lantokia"</item>
     <item msgid="1112044410659011023">"Beste bat"</item>
     <item msgid="2374913952870110618">"Pertsonalizatua"</item>
   </string-array>
   <string-array name="postalAddressTypes">
     <item msgid="6880257626740047286">"Etxekoa"</item>
-    <item msgid="5629153956045109251">"Lanekoa"</item>
+    <item msgid="5629153956045109251">"Lantokia"</item>
     <item msgid="4966604264500343469">"Beste bat"</item>
     <item msgid="4932682847595299369">"Pertsonalizatua"</item>
   </string-array>
   <string-array name="imAddressTypes">
     <item msgid="1738585194601476694">"Etxekoa"</item>
-    <item msgid="1359644565647383708">"Lanekoa"</item>
+    <item msgid="1359644565647383708">"Lantokia"</item>
     <item msgid="7868549401053615677">"Beste bat"</item>
     <item msgid="3145118944639869809">"Pertsonalizatua"</item>
   </string-array>
   <string-array name="organizationTypes">
-    <item msgid="7546335612189115615">"Lanekoa"</item>
+    <item msgid="7546335612189115615">"Lantokia"</item>
     <item msgid="4378074129049520373">"Beste bat"</item>
     <item msgid="3455047468583965104">"Pertsonalizatua"</item>
   </string-array>
@@ -631,7 +630,7 @@
     <string name="phoneTypeCustom" msgid="1644738059053355820">"Pertsonalizatua"</string>
     <string name="phoneTypeHome" msgid="2570923463033985887">"Etxekoa"</string>
     <string name="phoneTypeMobile" msgid="6501463557754751037">"Mugikorra"</string>
-    <string name="phoneTypeWork" msgid="8863939667059911633">"Lanekoa"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"Lantokia"</string>
     <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Laneko faxa"</string>
     <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Etxeko faxa"</string>
     <string name="phoneTypePager" msgid="7582359955394921732">"Bilagailua"</string>
@@ -655,16 +654,16 @@
     <string name="eventTypeOther" msgid="7388178939010143077">"Beste bat"</string>
     <string name="emailTypeCustom" msgid="8525960257804213846">"Pertsonalizatua"</string>
     <string name="emailTypeHome" msgid="449227236140433919">"Etxekoa"</string>
-    <string name="emailTypeWork" msgid="3548058059601149973">"Lanekoa"</string>
+    <string name="emailTypeWork" msgid="3548058059601149973">"Lantokia"</string>
     <string name="emailTypeOther" msgid="2923008695272639549">"Beste bat"</string>
     <string name="emailTypeMobile" msgid="119919005321166205">"Mugikorra"</string>
     <string name="postalTypeCustom" msgid="8903206903060479902">"Pertsonalizatua"</string>
     <string name="postalTypeHome" msgid="8165756977184483097">"Etxekoa"</string>
-    <string name="postalTypeWork" msgid="5268172772387694495">"Lanekoa"</string>
+    <string name="postalTypeWork" msgid="5268172772387694495">"Lantokia"</string>
     <string name="postalTypeOther" msgid="2726111966623584341">"Beste bat"</string>
     <string name="imTypeCustom" msgid="2074028755527826046">"Pertsonalizatua"</string>
     <string name="imTypeHome" msgid="6241181032954263892">"Orri nagusia"</string>
-    <string name="imTypeWork" msgid="1371489290242433090">"Lanekoa"</string>
+    <string name="imTypeWork" msgid="1371489290242433090">"Lantokia"</string>
     <string name="imTypeOther" msgid="5377007495735915478">"Beste bat"</string>
     <string name="imProtocolCustom" msgid="6919453836618749992">"Pertsonalizatua"</string>
     <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
@@ -676,7 +675,7 @@
     <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
     <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
-    <string name="orgTypeWork" msgid="29268870505363872">"Lanekoa"</string>
+    <string name="orgTypeWork" msgid="29268870505363872">"Lantokia"</string>
     <string name="orgTypeOther" msgid="3951781131570124082">"Bestelakoa"</string>
     <string name="orgTypeCustom" msgid="225523415372088322">"Pertsonalizatua"</string>
     <string name="relationTypeCustom" msgid="3542403679827297300">"Pertsonalizatua"</string>
@@ -696,7 +695,7 @@
     <string name="relationTypeSpouse" msgid="394136939428698117">"Ezkonlaguna"</string>
     <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Pertsonalizatua"</string>
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Etxekoa"</string>
-    <string name="sipAddressTypeWork" msgid="6920725730797099047">"Lanekoa"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"Lantokia"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Beste bat"</string>
     <string name="quick_contacts_not_available" msgid="746098007828579688">"Ez da kontaktua ikusteko aplikaziorik aurkitu."</string>
     <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Idatzi PIN kodea"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Wi-Fi sare irekiak erabilgarri</item>
       <item quantity="one">Wi-Fi sare irekia erabilgarri</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Konektatu Wi‑Fi sare irekira"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Wi‑Fi sare irekira konektatzen"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi sare irekira konektatuta"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Ezin izan da konektatu Wi‑Fi sare irekira"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Sakatu hau sare guztiak ikusteko"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Konektatu"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Sare guztiak"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Hasi saioa Wi-Fi sarean"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Hasi saioa sarean"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI modurako USBa"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB osagarri batera konektatuta"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Sakatu aukera gehiago ikusteko."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Audio-osagarri analogiko bat hauteman da"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Erantsitako gailua ez da telefono honekin bateragarria. Sakatu informazio gehiago lortzeko."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB arazketa konektatuta"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Sakatu USB arazketa desgaitzeko."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Hautatu USB arazketa desgaitzeko."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> saiora konektatuta. Sakatu sarea kudeatzeko."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Beti aktibatuta dagoen VPNa konektatzen…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Beti aktibatuta dagoen VPNa konektatu da"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Deskonektatu egin da beti aktibatuta dagoen VPN konexioa"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Beti aktibatuta dagoen VPN sarea deskonektatuta dago"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Beti aktibatuta dagoen VPN errorea"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Konfiguratzeko, sakatu hau"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Aldatu sarearen edo VPN sarearen ezarpenak"</string>
     <string name="upload_file" msgid="2897957172366730416">"Aukeratu fitxategia"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Ez da fitxategirik aukeratu"</string>
     <string name="reset" msgid="2448168080964209908">"Berrezarri"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Sakatu auto modutik irteteko."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Konexioa partekatzea edo sare publikoa aktibo"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Sakatu konfiguratzeko."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Desgaituta dago konexioa partekatzeko aukera"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Xehetasunak lortzeko, jarri administratzailearekin harremanetan"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Atzera"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Hurrengoa"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Saltatu"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Kendu aingura"</string>
     <string name="app_info" msgid="6856026610594615344">"Aplikazioari buruzko informazioa"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Gailua berrezarri nahi duzu?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Gailua berrezartzeko, sakatu hau"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Demoa abiarazten…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Gailua berrezartzen…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Gailua berrezarri nahi duzu?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Aldaketak galduko dituzu eta <xliff:g id="TIMEOUT">%1$s</xliff:g> segundo barru hasiko da berriro demoa…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Utzi"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Berrezarri"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> desgaituta dago"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konferentzia-deia"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Aholkua"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Ebakuatu kostaldeak eta ibaialdeak berehala eta joan toki seguru batera, adibidez, toki garai batera."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Ez larritu eta bilatu babesleku bat inguruan."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Larrialdi-mezuen proba"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Erantzun"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Ez da onartzen SIM txartela"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Ez dago SIM txartelik"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 7fcad41..d492087 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"جستجوی سرویس"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"‏تماس از طریق Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"‏برای برقراری تماس و ارسال پیام از طریق Wi-Fi، ابتدا از شرکت مخابراتی‌تان درخواست کنید این سرویس را راه‌اندازی کند. سپس دوباره از تنظیمات، تماس Wi-Fi را روشن کنید."</item>
+    <item msgid="3910386316304772394">"‏برای برقراری تماس و ارسال پیام ازطریق Wi-Fi، ابتدا از شرکت مخابراتی خود بخواهید این سرویس را تنظیم کند. سپس در «تنظیمات»۷ دوباره «تماس ازطریق Wi-Fi» را روشن کنید. (کد خطا: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"ثبت‌نام با شرکت مخابراتی شما"</item>
+    <item msgid="7472393097168811593">"ازطریق شرکت مخابراتی‌تان ثبت‌نام کنید (کد خطا: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"دستیار صوتی"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"اکنون قفل شود"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"۹۹۹+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"محتواها پنهان هستند"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"محتوا بر اساس خط‌مشی پنهان شده است"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"اعلان جدید"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"صفحه‌‌کلید مجازی"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"صفحه‌کلید فیزیکی"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"امنیت"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"هشدارها"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"نمونه برای خرده‌فروشان"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"‏اتصال USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"برنامه‌هایی که در پس‌زمینه اجرا می‌شوند"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> در پس‌زمینه درحال اجرا شدن است"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> برنامه در پس‌زمینه درحال اجرا شدن هستند"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"برنامه‌های مصرف‌کننده باتری"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> درحال استفاده کردن از باتری است"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> برنامه درحال استفاده کردن از باتری هستند"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"برای جزئیات مربوط به مصرف باتری و داده، ضربه بزنید"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>، <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"حالت ایمن"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="one">‏شبکه Wi-Fi باز در دسترس</item>
       <item quantity="other">‏شبکه‌ Wi-Fi باز در دسترس</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"‏اتصال به شبکه Wi‑Fi باز"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"‏درحال اتصال به شبکه Wi‑Fi باز"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"‏به شبکه Wi‑Fi متصل شد"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"‏به شبکه Wi-Fi متصل نشد"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"برای دیدن همه شبکه‌ها ضربه بزنید"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"اتصال"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"همه شبکه‌ها"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"‏ورود به شبکه Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ورود به سیستم شبکه"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"‏USB برای MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"‏به یک وسیله جانبی USB وصل شده است"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"برای گزینه‌های بیشتر ضربه بزنید."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"لوازم جانبی صوتی آنالوگ شناسایی شد"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"دستگاه متصل‌شده با این تلفن سازگار نیست. روی اطلاعات بیشتر، ضربه بزنید."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏اشکال‌زدایی USB متصل شد"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"‏برای غیرفعال کردن اشکال‌زدایی USB ضربه بزنید."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‏انتخاب کنید تا رفع عیب USB غیرفعال شود."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"به <xliff:g id="SESSION">%s</xliff:g> متصل شد. برای مدیریت شبکه ضربه بزنید."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"‏در حال اتصال VPN همیشه فعال…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"‏VPN همیشه فعال متصل شد"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"‏ارتباط VPN همیشه روشن قطع شد"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"‏ارتباط VPN همیشه روشن قطع شد"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"‏خطای VPN همیشه فعال"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"برای راه‌اندازی ضربه بزنید"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"‏تغییر شبکه یا تنظیمات VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"انتخاب فایل"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"هیچ فایلی انتخاب نشد"</string>
     <string name="reset" msgid="2448168080964209908">"بازنشانی"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"برای خروج از حالت خودرو ضربه بزنید."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"اتصال داده با سیم یا نقطه اتصال فعال"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"برای راه‌اندازی ضربه بزنید."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"اتصال به اینترنت با تلفن همراه غیرفعال شده است"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"برای جزئیات، با سرپرستتان تماس بگیرید"</string>
     <string name="back_button_label" msgid="2300470004503343439">"برگشت"</string>
     <string name="next_button_label" msgid="1080555104677992408">"بعدی"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"پرش"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"برداشتن پین"</string>
     <string name="app_info" msgid="6856026610594615344">"اطلاعات برنامه"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"دستگاه بازنشانی شود؟"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"برای بازنشانی دستگاه، ضربه بزنید"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"در حال شروع نسخه نمایشی…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"در حال بازنشانی دستگاه…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"دستگاه بازنشانی شود؟"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"همه تغییرات را از دست خواهید داد و نسخه نمایشی دوباره تا <xliff:g id="TIMEOUT">%1$s</xliff:g> ثانیه دیگر شروع می‌شود…‏"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"لغو"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"بازنشانی در این لحظه"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> غیرفعال شد"</string>
     <string name="conference_call" msgid="3751093130790472426">"تماس کنفرانسی"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"نکته‌ابزار"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"فوراً مناطق ساحلی و محدوده رودخانه را ترک کنید و به جایی امن، مثل ارتفاعات بروید."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"آرام باشید و پناهگاهی در این اطراف پیدا کنید."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"آزمایش پیام‌های اضطراری"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"پاسخ"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"سیم‌کارت مجاز نیست"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"سیم‌کارت مجوز لازم را ندارد"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index dc38a7a..55a42d4 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Etsitään signaalia"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-puhelut"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa."</item>
+    <item msgid="3910386316304772394">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa. (Virhekoodi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Rekisteröidy operaattorisi asiakkaaksi."</item>
+    <item msgid="7472393097168811593">"Rekisteröidy operaattorin asiakkaaksi (virhekoodi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ääniapuri"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lukitse nyt"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Sisältö piilotettu"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Sisältö on piilotettu käytännön perusteella."</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Uusi ilmoitus"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuaalinen näppäimistö"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fyysinen näppäimistö"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Tietosuoja"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ilmoitukset"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Esittelytila"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-yhteys"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Sovelluksia käynnissä taustalla"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> on käynnissä taustalla"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> sovellusta on käynnissä taustalla."</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Akkua kuluttavat sovellukset"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> käyttää akkua."</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> sovellusta käyttää akkua."</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Katso lisätietoja akun ja datan käytöstä napauttamalla."</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Suojattu tila"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Avoimia Wi-Fi-verkkoja käytettävissä</item>
       <item quantity="one">Avoin Wi-Fi-verkko käytettävissä</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Yhdistä avoimeen Wi‑Fi-verkkoon"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Yhdistetään avoimeen Wi‑Fi-verkkoon"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Yhdistetty Wi-Fi-verkkoon"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi-verkkoon yhdistäminen epäonnistui"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Napauta, niin näet kaikki verkot."</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Yhdistä"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Kaikki verkot"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Kirjaudu Wi-Fi-verkkoon"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Kirjaudu verkkoon"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1128,7 +1134,7 @@
     <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Sallitaanko yhteys?"</string>
     <string name="wifi_connect_alert_message" msgid="6451273376815958922">"Sovellus %1$s yrittää yhdistää Wi-Fi-verkkoon %2$s."</string>
     <string name="wifi_connect_default_application" msgid="7143109390475484319">"Sovellus"</string>
-    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Suora Wi-Fi-yhteys"</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
     <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Käynnistä suora Wi-Fi-yhteys. Wi-Fi-asiakas/-hotspot poistetaan käytöstä."</string>
     <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Suoran Wi-Fi-yhteyden käynnistäminen epäonnistui."</string>
     <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct on käytössä"</string>
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB on MIDI-tilassa"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Liitetty USB-laitteeseen"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Näet lisää vaihtoehtoja napauttamalla."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analoginen äänilaite havaittu"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Liitetty laite ei ole yhteensopiva puhelimen kanssa. Napauta, niin näet lisätietoja."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-vianetsintä yhdistetty"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Poista USB-vianetsintä käytöstä napauttamalla."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Poista USB-vianetsintä käytöstä valitsemalla tämä."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Yhdistetty: <xliff:g id="SESSION">%s</xliff:g>. Hallinnoi verkkoa napauttamalla."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Yhdistetään aina käytössä olevaan VPN-verkkoon..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Yhdistetty aina käytössä olevaan VPN-verkkoon"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Aina käytössä olevan VPN:n yhteys on katkaistu"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Yhteys aina päällä olevaan VPN:ään katkennut"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Aina käytössä oleva VPN: virhe"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Määritä koskettamalla."</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Muuta verkko- tai VPN-asetuksia"</string>
     <string name="upload_file" msgid="2897957172366730416">"Valitse tiedosto"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Ei valittua tiedostoa"</string>
     <string name="reset" msgid="2448168080964209908">"Palauta"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Poistu autotilasta napauttamalla."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Internetin jakaminen tai yhteyspiste käytössä"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Määritä napauttamalla."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Yhteyden jakaminen poistettu käytöstä"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kysy lisätietoja järjestelmänvalvojalta."</string>
     <string name="back_button_label" msgid="2300470004503343439">"Takaisin"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Seuraava"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Ohita"</string>
@@ -1422,7 +1428,7 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Järjestelmä"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-ääni"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Langaton näyttö"</string>
-    <string name="media_route_button_content_description" msgid="591703006349356016">"Lähetä"</string>
+    <string name="media_route_button_content_description" msgid="591703006349356016">"Suoratoisto"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"Yhdistä laitteeseen"</string>
     <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Lähetä näyttö laitteeseen"</string>
     <string name="media_route_chooser_searching" msgid="4776236202610828706">"Etsitään laitteita…"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Irrota"</string>
     <string name="app_info" msgid="6856026610594615344">"Sovelluksen tiedot"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Palautetaanko laitteen tehdasasetukset?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Palauta laite napauttamalla"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Aloitetaan esittelyä…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Palautetaan asetuksia…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Palautetaanko laitteen tehdasasetukset?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Muutokset poistetaan ja esittely aloitetaan uudelleen <xliff:g id="TIMEOUT">%1$s</xliff:g> sekunnin kuluttua…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Peruuta"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Palauta nyt"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> ei ole käytössä."</string>
     <string name="conference_call" msgid="3751093130790472426">"Puhelinneuvottelu"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Työkaluvinkki"</string>
@@ -1745,7 +1745,7 @@
     <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Laitteen tallennustila"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"USB-vianetsintä"</string>
     <string name="time_picker_hour_label" msgid="2979075098868106450">"tunti"</string>
-    <string name="time_picker_minute_label" msgid="5168864173796598399">"minuutti"</string>
+    <string name="time_picker_minute_label" msgid="5168864173796598399">"minuutit"</string>
     <string name="time_picker_header_text" msgid="143536825321922567">"Aseta aika"</string>
     <string name="time_picker_input_error" msgid="7574999942502513765">"Anna kelvollinen aika."</string>
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Kirjoita aika"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Siirry heti rannikkoalueilta ja jokien varsilta korkeampiin tai muuten turvallisempiin paikkoihin."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Pysy rauhallisena ja hakeudu lähimpään suojapaikkaan."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Hätäilmoitustesti"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Vastaa"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-kortti estetty"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-kortti ei käyttäjien hallinnassa"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 491fe66..29d1671 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Recherche des services disponibles"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Appels Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
+    <item msgid="3910386316304772394">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres. (Code d\'erreur : <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Inscrivez-vous auprès de votre fournisseur de services"</item>
+    <item msgid="7472393097168811593">"Inscrivez-vous auprès de votre fournisseur de services (code d\'erreur : <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. vocale"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Verrouiller"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Contenus masqués"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenu masqué conformément aux politiques"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Nouvelle notification"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Clavier virtuel"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Clavier physique"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Sécurité"</string>
@@ -263,12 +262,12 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertes"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Démo en magasin"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Connexion USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Applications qui fonctionnent en arrière-plan"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> fonctionne en arrière-plan"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> applications fonctionnent en arrière-plan"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Applications qui sollicitent la pile"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> sollicite la pile"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> applications sollicitent la pile"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Touchez pour afficher des détails sur l\'utilisation de la pile et des données"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
-    <string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
+    <string name="safeMode" msgid="2788228061547930246">"Mode sans échec"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Système Android"</string>
     <string name="user_owner_label" msgid="1119010402169916617">"Passer au profil personnel"</string>
     <string name="managed_profile_label" msgid="5289992269827577857">"Passer au profil professionnel"</string>
@@ -855,9 +854,9 @@
     <string name="menu_space_shortcut_label" msgid="2410328639272162537">"espace"</string>
     <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"entrée"</string>
     <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"suppr"</string>
-    <string name="search_go" msgid="8298016669822141719">"Recherche"</string>
+    <string name="search_go" msgid="8298016669822141719">"Rechercher"</string>
     <string name="search_hint" msgid="1733947260773056054">"Recherche en cours..."</string>
-    <string name="searchview_description_search" msgid="6749826639098512120">"Recherche"</string>
+    <string name="searchview_description_search" msgid="6749826639098512120">"Rechercher"</string>
     <string name="searchview_description_query" msgid="5911778593125355124">"Requête de recherche"</string>
     <string name="searchview_description_clear" msgid="1330281990951833033">"Effacer la requête"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Envoyer la requête"</string>
@@ -1093,7 +1092,7 @@
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume des notifications"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Sonnerie par défaut"</string>
     <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Défaut (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
-    <string name="ringtone_silent" msgid="7937634392408977062">"Aucun"</string>
+    <string name="ringtone_silent" msgid="7937634392408977062">"Aucun(e)"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Sonneries"</string>
     <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Sons d\'alarme"</string>
     <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Sons de notification"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="one">Réseau Wi-Fi ouvert à proximité</item>
       <item quantity="other">Réseaux Wi-Fi ouverts à proximité</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connectez-vous pour ouvrir un réseau Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connexion en cours au réseau Wi-Fi ouvert…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connecté au réseau Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Impossible de se connecter au réseau Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Touchez pour afficher tous les réseaux"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connexion"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tous les réseaux"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Connectez-vous au réseau Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Connectez-vous au réseau"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB pour MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connecté à un accessoire USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Touchez pour afficher plus d\'options."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Un accessoire audio analogique a été détecté"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"L\'appareil connecté n\'est pas compatible avec ce téléphone. Touchez ici en savoir plus."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Touchez pour désactiver le débogage USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
@@ -1258,7 +1266,7 @@
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"Appuyer deux fois pour régler le zoom"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Impossible d\'ajouter le widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Aller"</string>
-    <string name="ime_action_search" msgid="658110271822807811">"Recherche"</string>
+    <string name="ime_action_search" msgid="658110271822807811">"Rechercher"</string>
     <string name="ime_action_send" msgid="2316166556349314424">"Envoyer"</string>
     <string name="ime_action_next" msgid="3138843904009813834">"Suivante"</string>
     <string name="ime_action_done" msgid="8971516117910934605">"Terminé"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Connecté à <xliff:g id="SESSION">%s</xliff:g>. Appuyez ici pour gérer le réseau."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"RPV permanent en cours de connexion…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"RPV permanent connecté"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"RPV permanent déconnecté"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Déconnecté du RPV permanent"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Erreur du RPV permanent"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Touchez pour configurer"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Modifier les paramètres réseau ou RPV"</string>
     <string name="upload_file" msgid="2897957172366730416">"Choisir un fichier"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Aucun fichier sélectionné"</string>
     <string name="reset" msgid="2448168080964209908">"Réinitialiser"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Touchez pour quitter le mode Voiture."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Partage de connexion ou point d\'accès sans fil activé"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Touchez pour configurer."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Le partage de connexion est désactivé"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Communiquez avec votre administrateur pour obtenir plus de détails"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Précédent"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Suivante"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Passer"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Annuler l\'épinglage"</string>
     <string name="app_info" msgid="6856026610594615344">"Détails de l\'application"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Réinitialiser l\'appareil?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Touchez pour réinitialiser l\'appareil"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Démarrage de la démonstration en cours…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Réinitialisation de l\'appareil en cours…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Réinitialiser l\'appareil?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Vous perdrez vos modifications, et la démo recommencera dans <xliff:g id="TIMEOUT">%1$s</xliff:g> secondes…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Annuler"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Réinitialiser maintenant"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Désactivé : <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Conférence téléphonique"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Infobulle"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Évacuez immédiatement les zones côtières et les rives des fleuves, et réfugiez-vous dans un endroit plus sécuritaire, comme un terrain surélevé."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Restez calme et cherchez un abri à proximité."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test de messages d\'urgence"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Répondre"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Carte SIM non autorisée"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Carte SIM non configurée"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index a77ba4e..6aa85ec 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Recherche des services disponibles"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Appels Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Pour effectuer des appels et envoyer des messages via le Wi-Fi, demandez tout d\'abord à votre opérateur de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
+    <item msgid="3910386316304772394">"Pour passer des appels et envoyer des messages via le Wi-Fi, demandez d\'abord à votre opérateur de configurer ce service. Ensuite, réactivez les appels Wi-Fi dans les paramètres. (Code d\'erreur : <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Inscrivez-vous auprès de votre opérateur."</item>
+    <item msgid="7472393097168811593">"Enregistrez-vous auprès de votre opérateur (Code d\'erreur : <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Assistance vocale"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Verrouiller"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Contenus masqués"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenu masqué conformément aux règles"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Nouvelle notification"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Clavier virtuel"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Clavier physique"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Sécurité"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertes"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Démonstration en magasin"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Connexion USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Applications en cours d\'exécution en arrière-plan"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> s\'exécute en arrière-plan"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> applications s\'exécutent en arrière-plan"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Applications utilisant la batterie"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> utilise la batterie"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> applications utilisent la batterie"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Appuyer pour obtenir des informations sur l\'utilisation de la batterie et des données"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="one">Réseau Wi-Fi ouvert disponible</item>
       <item quantity="other">Réseaux Wi-Fi ouverts disponibles</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Se connecter pour ouvrir le réseau Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connexion pour ouvrir un réseau Wi-Fi…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connecté au réseau Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Impossible de se connecter au réseau Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Appuyer pour afficher tous les réseaux"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Se connecter"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tous les réseaux"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Connectez-vous au réseau Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Se connecter au réseau"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB en mode MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connecté à un accessoire USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"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>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Appuyez ici pour désactiver le débogage USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Connecté à <xliff:g id="SESSION">%s</xliff:g>. Appuyez ici pour gérer le réseau."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"VPN permanent en cours de connexion…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPN permanent connecté"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"VPN permanent déconnecté"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Déconnecté du VPN permanent"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Erreur du VPN permanent"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Appuyer pour configurer"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Modifier les paramètres réseau ou VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Sélectionner un fichier"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Aucun fichier sélectionné"</string>
     <string name="reset" msgid="2448168080964209908">"Réinitialiser"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Appuyez ici pour quitter le mode Voiture."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Partage de connexion ou point d\'accès sans fil activé"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Appuyez ici pour configurer."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Le partage de connexion est désactivé"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Pour en savoir plus, contactez votre administrateur"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Retour"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Suivant"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Ignorer"</string>
@@ -1382,7 +1388,7 @@
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Limite de données 4G atteinte"</string>
     <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Limite données mobiles atteinte"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Limite données Wi-Fi atteinte"</string>
-    <string name="data_usage_limit_body" msgid="291731708279614081">"Données suspend. pour reste cycle"</string>
+    <string name="data_usage_limit_body" msgid="291731708279614081">"Données suspendues jusqu\'à la fin du cycle"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Quota de données 2G-3G dépassé"</string>
     <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Quota de données 4G dépassé"</string>
     <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Quota utilisation données dépassé"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Retirer"</string>
     <string name="app_info" msgid="6856026610594615344">"Infos sur l\'appli"</string>
     <string name="negative_duration" msgid="5688706061127375131">"− <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Réinitialiser l\'appareil ?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Appuyer pour réinitialiser l\'appareil"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Lancement de la démo…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Réinitialisation…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Réinitialiser l\'appareil ?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Vous perdrez vos modifications, et la démo recommencera dans <xliff:g id="TIMEOUT">%1$s</xliff:g> secondes…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Annuler"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Réinitialiser maintenant"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Élément \"<xliff:g id="LABEL">%1$s</xliff:g>\" désactivé"</string>
     <string name="conference_call" msgid="3751093130790472426">"Conférence téléphonique"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Info-bulle"</string>
@@ -1744,8 +1744,8 @@
     <string name="app_category_productivity" msgid="3742083261781538852">"Productivité"</string>
     <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Mémoire de l\'appareil"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"Débogage USB"</string>
-    <string name="time_picker_hour_label" msgid="2979075098868106450">"heure"</string>
-    <string name="time_picker_minute_label" msgid="5168864173796598399">"minute"</string>
+    <string name="time_picker_hour_label" msgid="2979075098868106450">"heures"</string>
+    <string name="time_picker_minute_label" msgid="5168864173796598399">"minutes"</string>
     <string name="time_picker_header_text" msgid="143536825321922567">"Définir l\'heure"</string>
     <string name="time_picker_input_error" msgid="7574999942502513765">"Veuillez indiquer une heure valide"</string>
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Indiquez l\'heure"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Évacuez immédiatement les zones côtières et les berges des fleuves, et réfugiez-vous dans un endroit plus sûr, comme un terrain surélevé."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Restez calme et cherchez un abri à proximité."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test de messages d\'urgence"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Répondre"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Carte SIM non autorisée"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Carte SIM non configurée"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 73f82b11..cfa0a25 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -68,8 +68,8 @@
     </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
-    <string name="ClipMmi" msgid="6952821216480289285">"ID de chamada entrante"</string>
-    <string name="ClirMmi" msgid="7784673673446833091">"ID de chamada saínte"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"Identificador de chamada entrante"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"Identificador de chamada saínte"</string>
     <string name="ColpMmi" msgid="3065121483740183974">"ID de liña conectada"</string>
     <string name="ColrMmi" msgid="4996540314421889589">"Restrición de ID de liña conectada"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Desvío de chamadas"</string>
@@ -83,22 +83,22 @@
     <string name="RuacMmi" msgid="7827887459138308886">"Rexeitamento de chamadas molestas non desexadas"</string>
     <string name="CndMmi" msgid="3116446237081575808">"Entrega de número de chamada entrante"</string>
     <string name="DndMmi" msgid="1265478932418334331">"Non molestar"</string>
-    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"De forma predeterminada, restrínxese o ID de chamada. Próxima chamada: restrinxido."</string>
-    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"De forma predeterminada, restrínxese o ID de chamada. Próxima chamada: non restrinxido."</string>
-    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"De forma predeterminada, non se restrinxe o ID de chamada. Próxima chamada: restrinxido."</string>
-    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"De forma predeterminada, non se restrinxe o ID de chamada. Próxima chamada: non restrinxido."</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"O valor predeterminado do identificador de chamada é restrinxido. Próxima chamada: restrinxido"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"O valor predeterminado do identificador de chamada é restrinxido. Próxima chamada: non restrinxido"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"O valor predeterminado do identificador de chamada é non restrinxido. Próxima chamada: restrinxido"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"O valor predeterminado do identificador de chamada é restrinxido. Próxima chamada: non restrinxido"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Servizo non ofrecido."</string>
-    <string name="CLIRPermanent" msgid="3377371145926835671">"Non podes cambiar a configuración do ID de chamada."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"Non podes cambiar a configuración do identificador de chamada."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Non hai servizo de datos"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Non se poden realizar chamadas de emerxencia"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Non se poden realizar chamadas de urxencia"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Non hai servizo de chamadas de voz"</string>
-    <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Non hai servizo de chamadas de emerxencia nin de voz"</string>
+    <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Non hai servizo de chamadas de urxencia nin de voz"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"A rede de telefonía móbil non ofrece o servizo na túa localización temporalmente"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Non se pode conectar coa rede"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Para mellorar a recepción, proba a cambiar o tipo seleccionado en Sistema &gt; Rede e Internet &gt; Redes de telefonía móbil &gt; Tipo de rede preferido."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Desvío de chamadas"</string>
-    <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modo de devolución de chamadas de emerxencia"</string>
+    <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modo de devolución de chamadas de urxencia"</string>
     <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Alertas de datos móbiles"</string>
     <string name="notification_channel_sms" msgid="3441746047346135073">"Mensaxes SMS"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mensaxes de correo de voz"</string>
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servizo"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas por wifi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro pídelle ao teu operador que configure este servizo. A continuación, activa de novo as chamadas wifi en Configuración."</item>
+    <item msgid="3910386316304772394">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro solicítalle ao operador que configure este servizo. Despois, activa de novo as chamadas por wifi en Configuración. (Código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Rexístrate co teu operador"</item>
+    <item msgid="7472393097168811593">"Rexístrate co teu operador (código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -202,7 +202,7 @@
     <string name="silent_mode_silent" msgid="319298163018473078">"Timbre desactivado"</string>
     <string name="silent_mode_vibrate" msgid="7072043388581551395">"Timbre en vibración"</string>
     <string name="silent_mode_ring" msgid="8592241816194074353">"Timbre activado"</string>
-    <string name="reboot_to_update_title" msgid="6212636802536823850">"Actualización do sistema de Android"</string>
+    <string name="reboot_to_update_title" msgid="6212636802536823850">"Actualización do sistema Android"</string>
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"Preparando para actualizar…"</string>
     <string name="reboot_to_update_package" msgid="3871302324500927291">"Procesando paquete de actualización…"</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"Reiniciando..."</string>
@@ -223,7 +223,7 @@
     <string name="global_actions" product="default" msgid="2406416831541615258">"Opcións de teléfono"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Bloqueo de pantalla"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"Apagar"</string>
-    <string name="global_action_emergency" msgid="7112311161137421166">"Emerxencias"</string>
+    <string name="global_action_emergency" msgid="7112311161137421166">"Urxencias"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Informe de erros"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Crear informe de erros"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Este informe recompilará información acerca do estado actual do teu dispositivo para enviala en forma de mensaxe de correo electrónico. O informe de erros tardará un pouco en completarse desde o seu inicio ata que estea preparado para enviarse, polo que che recomendamos que teñas paciencia."</string>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Contido oculto"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Ocultouse contido por causa da política"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Notificación nova"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclado virtual"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teclado físico"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Seguranza"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demostración comercial"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"conexión USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplicacións que se executan en segundo plano"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Estase executando en segundo plano a aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Estanse executando en segundo plano <xliff:g id="NUMBER">%1$d</xliff:g> aplicacións"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplicacións que consumen batería"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"A aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> está consumindo batería"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicacións están consumindo batería"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Toca para obter información sobre o uso de datos e a batería"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
@@ -321,7 +320,7 @@
     <string name="permlab_receiveMms" msgid="1821317344668257098">"recibir mensaxes de texto (MMS)"</string>
     <string name="permdesc_receiveMms" msgid="533019437263212260">"Permite á aplicación recibir e procesar mensaxes MMS. Isto significa que a aplicación pode supervisar ou eliminar mensaxes enviadas ao teu dispositivo sen mostrarchas."</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ler mensaxes de difusión móbil"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite á aplicación ler mensaxes de difusión móbil recibidas polo teu dispositivo. As alertas de difusión móbil entréganse nalgunhas situacións para avisar de situacións de emerxencia. É posible que aplicacións maliciosas afecten ao rendemento ou funcionamento do teu dispositivo cando se recibe unha difusión móbil de emerxencia."</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite á aplicación ler mensaxes de difusión móbil recibidas polo teu dispositivo. As alertas de difusión móbil envíanse nalgunhas localizacións para avisar de situacións de urxencia. É posible que aplicacións maliciosas afecten ao rendemento ou funcionamento do teu dispositivo cando se recibe unha difusión móbil de urxencia."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ler feeds subscritos"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permite á aplicación obter detalles acerca dos feeds sincronizados actualmente."</string>
     <string name="permlab_sendSms" msgid="7544599214260982981">"enviar e consultar mensaxes de SMS"</string>
@@ -388,7 +387,7 @@
     <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"Esta aplicación pode engadir, quitar ou cambiar eventos do calendario almacenados na túa tableta. Tamén pode enviar mensaxes que parezan dos propietarios do calendario e cambiar eventos sen comunicárllelo aos propietarios."</string>
     <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"Esta aplicación pode engadir, quitar ou cambiar eventos do calendario almacenados na túa televisión. Tamén pode enviar mensaxes que parezan dos propietarios do calendario e cambiar eventos sen comunicárllelo aos propietarios."</string>
     <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"Esta aplicación pode engadir, quitar ou cambiar eventos do calendario almacenados no teu teléfono. Tamén pode enviar mensaxes que parezan dos propietarios do calendario e cambiar eventos sen comunicárllelo aos propietarios."</string>
-    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"acceder a comandos adicionais do provedor de situación"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"acceder a comandos adicionais do provedor de localización"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite á aplicación acceder a comandos adicionais de fornecedor de localizacións. É posible que isto provoque que a aplicación interfira co funcionamento do GPS ou doutras fontes da localización."</string>
     <string name="permlab_accessFineLocation" msgid="251034415460950944">"acceder á localización precisa (baseada no GPS e na rede)"</string>
     <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"Esta aplicación pode obter a túa localización a partir do GPS ou de fontes de localización de rede como torres de telecomunicacións e redes wifi. Para que a aplicación poida utilizar os servizos de localización, deben estar activados e dispoñibles no teu teléfono. Ten en conta que con esta acción pode aumentar o consumo de batería."</string>
@@ -407,7 +406,7 @@
     <string name="permlab_vibrate" msgid="7696427026057705834">"controlar a vibración"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"Permite á aplicación controlar o vibrador."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"chamar directamente aos números de teléfono"</string>
-    <string name="permdesc_callPhone" msgid="3740797576113760827">"Permite á aplicación chamar a números de teléfono sen a túa intervención. Esta acción pode implicar chamadas ou custos inesperados. Ten en conta que isto non permite á aplicación chamar a números de emerxencia. É posible que aplicacións maliciosas che custen diñeiro debido á realización de chamadas sen a túa confirmación."</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Permite á aplicación chamar a números de teléfono sen a túa intervención. Esta acción pode implicar chamadas ou custos inesperados. Ten en conta que isto non permite á aplicación chamar a números de urxencia. É posible que aplicacións maliciosas che custen diñeiro debido á realización de chamadas sen a túa confirmación."</string>
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"acceso ao servizo de chamadas de IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Permite que a aplicación use o servizo de IMS para facer chamadas sen a túa intervención."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ler o estado e a identidade do teléfono"</string>
@@ -586,7 +585,7 @@
     <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Desactivar algunhas funcións de bloqueo da pantalla"</string>
     <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"Impide o uso dalgunhas funcións de bloqueo da pantalla."</string>
   <string-array name="phoneTypes">
-    <item msgid="8901098336658710359">"Particular"</item>
+    <item msgid="8901098336658710359">"Casa"</item>
     <item msgid="869923650527136615">"Móbil"</item>
     <item msgid="7897544654242874543">"Traballo"</item>
     <item msgid="1103601433382158155">"Fax do traballo"</item>
@@ -596,7 +595,7 @@
     <item msgid="9192514806975898961">"Personalizado"</item>
   </string-array>
   <string-array name="emailAddressTypes">
-    <item msgid="8073994352956129127">"Particular"</item>
+    <item msgid="8073994352956129127">"Casa"</item>
     <item msgid="7084237356602625604">"Traballo"</item>
     <item msgid="1112044410659011023">"Outros"</item>
     <item msgid="2374913952870110618">"Personalizado"</item>
@@ -608,7 +607,7 @@
     <item msgid="4932682847595299369">"Personalizado"</item>
   </string-array>
   <string-array name="imAddressTypes">
-    <item msgid="1738585194601476694">"Particular"</item>
+    <item msgid="1738585194601476694">"Casa"</item>
     <item msgid="1359644565647383708">"Traballo"</item>
     <item msgid="7868549401053615677">"Outros"</item>
     <item msgid="3145118944639869809">"Personalizado"</item>
@@ -629,7 +628,7 @@
     <item msgid="1648797903785279353">"Jabber"</item>
   </string-array>
     <string name="phoneTypeCustom" msgid="1644738059053355820">"Personalizado"</string>
-    <string name="phoneTypeHome" msgid="2570923463033985887">"Particular"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"Casa"</string>
     <string name="phoneTypeMobile" msgid="6501463557754751037">"Móbil"</string>
     <string name="phoneTypeWork" msgid="8863939667059911633">"Traballo"</string>
     <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Fax do traballo"</string>
@@ -654,16 +653,16 @@
     <string name="eventTypeAnniversary" msgid="3876779744518284000">"Aniversario"</string>
     <string name="eventTypeOther" msgid="7388178939010143077">"Outros"</string>
     <string name="emailTypeCustom" msgid="8525960257804213846">"Personalizado"</string>
-    <string name="emailTypeHome" msgid="449227236140433919">"Particular"</string>
+    <string name="emailTypeHome" msgid="449227236140433919">"Casa"</string>
     <string name="emailTypeWork" msgid="3548058059601149973">"Traballo"</string>
     <string name="emailTypeOther" msgid="2923008695272639549">"Outro"</string>
     <string name="emailTypeMobile" msgid="119919005321166205">"Móbil"</string>
     <string name="postalTypeCustom" msgid="8903206903060479902">"Personalizado"</string>
-    <string name="postalTypeHome" msgid="8165756977184483097">"Particular"</string>
+    <string name="postalTypeHome" msgid="8165756977184483097">"Casa"</string>
     <string name="postalTypeWork" msgid="5268172772387694495">"Traballo"</string>
     <string name="postalTypeOther" msgid="2726111966623584341">"Outro"</string>
     <string name="imTypeCustom" msgid="2074028755527826046">"Personalizado"</string>
-    <string name="imTypeHome" msgid="6241181032954263892">"Particular"</string>
+    <string name="imTypeHome" msgid="6241181032954263892">"Casa"</string>
     <string name="imTypeWork" msgid="1371489290242433090">"Traballo"</string>
     <string name="imTypeOther" msgid="5377007495735915478">"Outro"</string>
     <string name="imProtocolCustom" msgid="6919453836618749992">"Personalizado"</string>
@@ -686,16 +685,16 @@
     <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Parella de feito"</string>
     <string name="relationTypeFather" msgid="5228034687082050725">"Pai"</string>
     <string name="relationTypeFriend" msgid="7313106762483391262">"Amigo/a"</string>
-    <string name="relationTypeManager" msgid="6365677861610137895">"Xestor"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Xefe/a"</string>
     <string name="relationTypeMother" msgid="4578571352962758304">"Nai"</string>
-    <string name="relationTypeParent" msgid="4755635567562925226">"Pai ou nai"</string>
-    <string name="relationTypePartner" msgid="7266490285120262781">"Socio"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"Pai/nai"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"Socio/a"</string>
     <string name="relationTypeReferredBy" msgid="101573059844135524">"Recomendado por"</string>
     <string name="relationTypeRelative" msgid="1799819930085610271">"Parente"</string>
     <string name="relationTypeSister" msgid="1735983554479076481">"Irmá"</string>
     <string name="relationTypeSpouse" msgid="394136939428698117">"Cónxuxe"</string>
     <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Personalizado"</string>
-    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Particular"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Casa"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Traballo"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Outro"</string>
     <string name="quick_contacts_not_available" msgid="746098007828579688">"Non se atopou ningunha aplicación para ver este contacto."</string>
@@ -708,13 +707,13 @@
     <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Escribe o PIN para desbloquear"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Código PIN incorrecto"</string>
     <string name="keyguard_label_text" msgid="861796461028298424">"Para desbloquear, preme Menú e, a continuación, 0."</string>
-    <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Número de emerxencia"</string>
+    <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Número de urxencia"</string>
     <string name="lockscreen_carrier_default" msgid="6169005837238288522">"Sen servizo"</string>
     <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Pantalla bloqueada"</string>
-    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Preme Menú para desbloquear ou realizar unha chamada de emerxencia."</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Preme Menú para desbloquear ou realizar unha chamada de urxencia."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Preme Menú para desbloquear."</string>
     <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Crea o padrón de desbloqueo"</string>
-    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Emerxencia"</string>
+    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Urxencia"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Volver á chamada"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Correcto!"</string>
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Téntao de novo"</string>
@@ -736,7 +735,7 @@
     <string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"Deter"</string>
     <string name="lockscreen_transport_rew_description" msgid="6944412838651990410">"Rebobinar"</string>
     <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Avance rápido"</string>
-    <string name="emergency_calls_only" msgid="6733978304386365407">"Só chamadas de emerxencia"</string>
+    <string name="emergency_calls_only" msgid="6733978304386365407">"Só chamadas de urxencia"</string>
     <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Bloqueada pola rede"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"A tarxeta SIM está bloqueada con código PUK."</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulta a guía do usuario ou ponte en contacto co servizo de asistencia ao cliente."</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Abrir redes wifi dispoñibles</item>
       <item quantity="one">Abrir rede wifi dispoñible</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conéctate a unha rede wifi aberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectándose á rede wifi aberta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectouse á rede wifi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Non se puido conectar á rede wifi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas as redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inicia sesión na rede wifi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Inicia sesión na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1178,13 +1184,15 @@
     <string name="no_permissions" msgid="7283357728219338112">"Non é necesario ningún permiso"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"é posible que teñas que pagar"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"Aceptar"</string>
-    <string name="usb_charging_notification_title" msgid="6895185153353640787">"O USB está cargando este dispositivo"</string>
+    <string name="usb_charging_notification_title" msgid="6895185153353640787">"Cargando este dispositivo por USB"</string>
     <string name="usb_supplying_notification_title" msgid="5310642257296510271">"O USB está proporcionando enerxía ao dispositivo conectado"</string>
     <string name="usb_mtp_notification_title" msgid="8396264943589760855">"USB para transferencia de ficheiros"</string>
     <string name="usb_ptp_notification_title" msgid="1347328437083192112">"USB para transferencia de fotos"</string>
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Toca para ver máis opcións."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Detectouse un accesorio de audio analóxico"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"O dispositivo conectado non é compatible con este teléfono. Toca para obter máis información."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB conectada"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Toca para desactivar a depuración de erros de USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecciona a opción para desactivar a depuración de USB."</string>
@@ -1262,7 +1270,7 @@
     <string name="ime_action_send" msgid="2316166556349314424">"Enviar"</string>
     <string name="ime_action_next" msgid="3138843904009813834">"Seguinte"</string>
     <string name="ime_action_done" msgid="8971516117910934605">"Feito"</string>
-    <string name="ime_action_previous" msgid="1443550039250105948">"Ant"</string>
+    <string name="ime_action_previous" msgid="1443550039250105948">"Ant."</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Executar"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"Marcar número\nutilizando o <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"Crear contacto\na partir de <xliff:g id="NUMBER">%s</xliff:g>"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Conectado a <xliff:g id="SESSION">%s</xliff:g>. Toca aquí para xestionar a rede."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"VPN sempre activada conectándose..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPN sempre activada conectada"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Desconectouse a VPN sempre activada"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Desconectácheste da VPN sempre activada"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Erro na VPN sempre activada"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Tocar para configurar"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Cambia a configuración da rede ou da VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Escoller un ficheiro"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Non se seleccionou ningún ficheiro"</string>
     <string name="reset" msgid="2448168080964209908">"Restablecer"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Toca para saír do modo de coche."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Conexión compartida ou zona wifi activada"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tocar para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"A conexión compartida está desactivada"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacta co administrador para obter información"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Volver"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Seguinte"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Omitir"</string>
@@ -1380,9 +1386,9 @@
     <string name="data_usage_warning_body" msgid="6660692274311972007">"Toca para uso e configuración."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Límite de datos de 2G-3G acadado"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Límite de datos de 4G acadado"</string>
-    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Límite de datos móbiles acadado"</string>
+    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Alcanzouse o límite de datos móbiles"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Límite de datos da wifi acadado"</string>
-    <string name="data_usage_limit_body" msgid="291731708279614081">"Datos pausados para o ciclo"</string>
+    <string name="data_usage_limit_body" msgid="291731708279614081">"Datos pausados para o resto do ciclo"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Límite de datos 2G-3G superado"</string>
     <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Límite de datos 4G superado"</string>
     <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Límite de datos móbiles superado"</string>
@@ -1428,7 +1434,7 @@
     <string name="media_route_chooser_searching" msgid="4776236202610828706">"Buscando dispositivos…"</string>
     <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Configuración"</string>
     <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Desconectar"</string>
-    <string name="media_route_status_scanning" msgid="7279908761758293783">"Analizando..."</string>
+    <string name="media_route_status_scanning" msgid="7279908761758293783">"Explorando..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Conectando..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Dispoñible"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Non dispoñibles"</string>
@@ -1721,16 +1727,10 @@
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Toca para ver os ficheiros"</string>
     <string name="pin_target" msgid="3052256031352291362">"Fixar"</string>
     <string name="unpin_target" msgid="3556545602439143442">"Soltar"</string>
-    <string name="app_info" msgid="6856026610594615344">"Información de aplicacións"</string>
+    <string name="app_info" msgid="6856026610594615344">"Info. da aplicación"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Queres restablecer o dispositivo?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Toca aquí para restablecer o dispositivo"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Iniciando demostración…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Restablecendo dispositivo…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Queres restablecer o dispositivo?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Perderás os cambios que fixeses e a demostración volverá comezar en <xliff:g id="TIMEOUT">%1$s</xliff:g> segundos…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Cancelar"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Restablecer agora"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Desactivouse <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Conferencia telefónica"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Cadro de información"</string>
@@ -1749,7 +1749,7 @@
     <string name="time_picker_header_text" msgid="143536825321922567">"Definir hora"</string>
     <string name="time_picker_input_error" msgid="7574999942502513765">"Introduce unha hora válida"</string>
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Escribe a hora"</string>
-    <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Cambia ao modo de entrada de texto para introducir a hora."</string>
+    <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Cambia ao modo de introdución de texto para introducir a hora."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Cambiar ao modo de reloxo para introducir a hora."</string>
     <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opcións de autocompletar"</string>
     <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"Garda a información no servizo Autocompletar"</string>
@@ -1773,7 +1773,8 @@
     <string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Mantén a calma e busca refuxio cerca."</string>
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Abandona de inmediato rexións costeiras e situadas na beira de ríos para dirixirte a un lugar máis seguro, como un terreo elevado."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantén a calma e busca refuxio cerca."</string>
-    <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Proba de mensaxes de emerxencia"</string>
+    <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Proba de mensaxes de urxencia"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Responder"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Non se admite a tarxeta SIM"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Non se introduciu ningunha tarxeta SIM"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 20215c1b..3695340 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -35,10 +35,10 @@
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> કલાક <xliff:g id="MINUTES">%2$d</xliff:g> મિનિટ"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> મિનિટ"</string>
     <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> મિનિટ"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> મિનિટ <xliff:g id="SECONDS">%2$d</xliff:g> સેકંડ"</string>
+    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> મિનિટ <xliff:g id="SECONDS">%2$d</xliff:g> સેકન્ડ"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> મિ <xliff:g id="SECONDS">%2$d</xliff:g> સે"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> સેકંડ"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> સેકંડ"</string>
+    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> સેકન્ડ"</string>
+    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> સેકન્ડ"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;અનામાંકિત&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(કોઈ ફોન નંબર નથી)"</string>
     <string name="unknownName" msgid="6867811765370350269">"અજાણ્યું"</string>
@@ -60,11 +60,11 @@
     <string name="invalidPin" msgid="3850018445187475377">"એક પિન લખો જે 4 થી 8 સંખ્યાનો છે."</string>
     <string name="invalidPuk" msgid="8761456210898036513">"એક PUK લખો કે જે 8 અંક કે તેથી લાંબો હોય."</string>
     <string name="needPuk" msgid="919668385956251611">"તમારો સિમ કાર્ડ, PUK-લૉક કરેલ છે. તેને અનલૉક કરવા માટે PUK કોડ લખો."</string>
-    <string name="needPuk2" msgid="4526033371987193070">"SIM કાર્ડને અનાવરોધિત કરવા માટે PUK2 લખો."</string>
-    <string name="enablePin" msgid="209412020907207950">"અસફળ, SIM/RUIM લૉક સક્ષમ કરો."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"સિમ કાર્ડને અનાવરોધિત કરવા માટે PUK2 લખો."</string>
+    <string name="enablePin" msgid="209412020907207950">"અસફળ, સિમ/RUIM લૉક સક્ષમ કરો."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
-      <item quantity="one">SIM લૉક થાય તે પહેલાં તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયત્ન બાકી છે.</item>
-      <item quantity="other">SIM લૉક થાય તે પહેલાં તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયત્ન બાકી છે.</item>
+      <item quantity="one">સિમ લૉક થાય તે પહેલાં તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયત્ન બાકી છે.</item>
+      <item quantity="other">સિમ લૉક થાય તે પહેલાં તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયત્ન બાકી છે.</item>
     </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
@@ -131,22 +131,22 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"સેવા શોધી રહ્યું છે"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"વાઇ-ફાઇ કૉલિંગ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"વાઇ-ફાઇ પર કૉલ્સ કરવા અને સંદેશા મોકલવા માટે, પહેલાં તમારા કૅરીઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી વાઇ-ફાઇ કૉલિંગ ચાલુ કરો."</item>
+    <item msgid="3910386316304772394">"વાઇ-ફાઇ પરથી કૉલ કરવા અને સંદેશા મોકલવા માટે પહેલાં તમારા કૅરિઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી વાઇ-ફાઇ કૉલિંગ ફરીથી ચાલુ કરો. (ભૂલ કોડ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"તમારા કેરીઅર સાથે નોંધણી કરો"</item>
+    <item msgid="7472393097168811593">"તમારા કૅરિઅર સાથે નોંધણી કરો (ભૂલ કોડ: <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>
     <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_wifi_preferred_summary" msgid="1994113411286935263">"વાઇ-ફાઇ પસંદ કર્યું"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"મોબાઇલને પસંદગી"</string>
-    <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"ફક્ત Wi-Fi"</string>
+    <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"ફક્ત વાઇ-ફાઇ"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ફોરવર્ડ કર્યો નથી"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
-    <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="TIME_DELAY">{2}</xliff:g> સેકંડ પછી <xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
+    <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="TIME_DELAY">{2}</xliff:g> સેકન્ડ પછી <xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
     <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ફોરવર્ડ કર્યો નથી"</string>
     <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ફોરવર્ડ કર્યો નથી"</string>
     <string name="fcComplete" msgid="3118848230966886575">"સુવિધા કોડ પૂર્ણ."</string>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"વૉઇસ સહાય"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"હવે લૉક કરો"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"સામગ્રીઓ છુપાવેલ છે"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"નીતિ દ્વારા સામગ્રી છુપાવાઈ"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"નવું નોટિફિકેશન"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"વર્ચ્યુઅલ કીબોર્ડ"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ભૌતિક કીબોર્ડ"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"સુરક્ષા"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ચેતવણીઓ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"રિટેલ ડેમો"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB કનેક્શન"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"પૃષ્ઠભૂમિમાં ચાલી રહેલ ઍપ્લિકેશનો"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> પૃષ્ઠભૂમિમાં ચાલી રહી છે"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ઍપ્લિકેશન પૃષ્ઠભૂમિમાં ચાલી રહી છે"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ઍપ બૅટરીનો વપરાશ કરી રહ્યાં છે"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> બૅટરીનો ઉપયોગ કરી રહ્યું છે"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ઍપ બૅટરીનો ઉપયોગ કરી રહ્યાં છે"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"બૅટરી અને ડેટા વપરાશ વિશેની વિગતો માટે ટૅપ કરો"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"સુરક્ષિત મોડ"</string>
@@ -281,11 +280,11 @@
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS સંદેશા મોકલવાની અને જોવાની"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"સ્ટોરેજ"</string>
-    <string name="permgroupdesc_storage" msgid="637758554581589203">"તમારા ઉપકરણ પર ફોટા, મીડિયા અને ફાઇલો ઍક્સેસ કરવાની"</string>
+    <string name="permgroupdesc_storage" msgid="637758554581589203">"તમારા ઉપકરણ પર ફોટો, મીડિયા અને ફાઇલો ઍક્સેસ કરવાની"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"માઇક્રોફોન"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ઑડિઓ રેકોર્ડ કરવાની"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"કૅમેરો"</string>
-    <string name="permgroupdesc_camera" msgid="3250611594678347720">"ચિત્રો લેવાની અને વિડિઓ રેકોર્ડ કરવાની"</string>
+    <string name="permgroupdesc_camera" msgid="3250611594678347720">"ચિત્રો લેવાની અને વીડિઓ રેકોર્ડ કરવાની"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"ફોન"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"ફોન કૉલ કરો અને સંચાલિત કરો"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"બોડી સેન્સર્સ"</string>
@@ -341,7 +340,7 @@
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"કાર મોડ સક્ષમ કરો"</string>
     <string name="permdesc_enableCarMode" msgid="4853187425751419467">"એપ્લિકેશનને કાર મોડ સક્ષમ કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"અન્ય ઍપ્લિકેશનો બંધ કરો"</string>
-    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"એપ્લિકેશનને અન્ય ઍપ્લિકેશનોની પૃષ્ઠભૂમિ પ્રક્રિયા સમાપ્ત કરવાની મંજૂરી આપે છે. આનાથી અન્ય ઍપ્લિકેશનો ચાલવાથી બંધ થઈ શકે છે."</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"એપ્લિકેશનને અન્ય ઍપ્લિકેશનોની બૅકગ્રાઉન્ડ પ્રક્રિયા સમાપ્ત કરવાની મંજૂરી આપે છે. આનાથી અન્ય ઍપ્લિકેશનો ચાલવાથી બંધ થઈ શકે છે."</string>
     <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"આ ઍપ્લિકેશન, અન્ય ઍપ્લિકેશનોની ટોચ પર દેખાઈ શકે છે"</string>
     <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"આ ઍપ્લિકેશન, અન્ય ઍપ્લિકેશોની ટોચ પર અથવા સ્ક્રીનના અન્ય ભાગોમાં દેખાઈ શકે છે. આ સામાન્ય ઍપ્લિકેશન વપરાશમાં હસ્તક્ષેપ કરી શકે છે અને અન્ય ઍપ્લિકેશનોની દેખાવાની રીતને બદલી શકે છે."</string>
     <string name="permlab_runInBackground" msgid="7365290743781858803">"પૃષ્ઠભૂમિમાં ચલાવો"</string>
@@ -391,17 +390,17 @@
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"વધારાના સ્થાન પ્રદાતા આદેશોને ઍક્સેસ કરો"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"એપ્લિકેશનને વધારાના સ્થાન પ્રદાતા આદેશોને ઍક્સેસ કરવાની મંજૂરી આપે છે. આ એપ્લિકેશનને GPS અથવા અન્ય સ્થાન સ્રોતોના ઓપરેશનમાં દખલ કરવાની મંજૂરી આપી શકે છે."</string>
     <string name="permlab_accessFineLocation" msgid="251034415460950944">"નિશ્ચિત સ્થાન ઍક્સેસ કરો (GPS અને નેટવર્ક-આધારિત)"</string>
-    <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"આ ઍપ્લિકેશન, GPS અથવા સેલ ટાવર્સ અને Wi-Fi નેટવર્ક્સ જેવા નેટવર્ક સ્રોતોના આધારે તમારું સ્થાન મેળવી શકે છે. ઍપ્લિકેશન દ્વારા આ સ્થાન સેવાઓનો ઉપયોગ કરવામાં સમર્થ થવા માટે તમારા ફોન પર આ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે. આ બૅટરી વપરાશ વધારી શકે છે."</string>
+    <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"આ ઍપ્લિકેશન, GPS અથવા સેલ ટાવર્સ અને વાઇ-ફાઇ નેટવર્ક્સ જેવા નેટવર્ક સ્રોતોના આધારે તમારું સ્થાન મેળવી શકે છે. ઍપ્લિકેશન દ્વારા આ સ્થાન સેવાઓનો ઉપયોગ કરવામાં સમર્થ થવા માટે તમારા ફોન પર આ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે. આ બૅટરી વપરાશ વધારી શકે છે."</string>
     <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"અંદાજિત સ્થાન ઍક્સેસ કરો (નેટવર્ક-આધારિત)"</string>
-    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"આ ઍપ્લિકેશન, સેલ ટાવર્સ અને Wi-Fi નેટવર્ક્સ જેવા નેટવર્ક સ્રોતોના આધારે તમારું સ્થાન મેળવી શકે છે. ઍપ્લિકેશન દ્વારા આ સ્થાન સેવાઓનો ઉપયોગ કરવામાં સમર્થ થવા માટે તમારા ટેબ્લેટ પર આ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે."</string>
-    <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"આ ઍપ્લિકેશન, સેલ ટાવર્સ અને Wi-Fi નેટવર્ક્સ જેવા નેટવર્ક સ્રોતોના આધારે તમારું સ્થાન મેળવી શકે છે. ઍપ્લિકેશન દ્વારા આ સ્થાન સેવાઓનો ઉપયોગ કરવામાં સમર્થ થવા માટે તમારા ટીવી પર આ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે."</string>
-    <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"આ ઍપ્લિકેશન, સેલ ટાવર્સ અને Wi-Fi નેટવર્ક્સ જેવા નેટવર્ક સ્રોતોના આધારે તમારું સ્થાન મેળવી શકે છે. ઍપ્લિકેશન દ્વારા આ સ્થાન સેવાઓનો ઉપયોગ કરવામાં સમર્થ થવા માટે તમારા ફોન પર આ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે."</string>
+    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"આ ઍપ્લિકેશન, સેલ ટાવર્સ અને વાઇ-ફાઇ નેટવર્ક્સ જેવા નેટવર્ક સ્રોતોના આધારે તમારું સ્થાન મેળવી શકે છે. ઍપ્લિકેશન દ્વારા આ સ્થાન સેવાઓનો ઉપયોગ કરવામાં સમર્થ થવા માટે તમારા ટેબ્લેટ પર આ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે."</string>
+    <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"આ ઍપ્લિકેશન, સેલ ટાવર્સ અને વાઇ-ફાઇ નેટવર્ક્સ જેવા નેટવર્ક સ્રોતોના આધારે તમારું સ્થાન મેળવી શકે છે. ઍપ્લિકેશન દ્વારા આ સ્થાન સેવાઓનો ઉપયોગ કરવામાં સમર્થ થવા માટે તમારા ટીવી પર આ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે."</string>
+    <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"આ ઍપ્લિકેશન, સેલ ટાવર્સ અને વાઇ-ફાઇ નેટવર્ક્સ જેવા નેટવર્ક સ્રોતોના આધારે તમારું સ્થાન મેળવી શકે છે. ઍપ્લિકેશન દ્વારા આ સ્થાન સેવાઓનો ઉપયોગ કરવામાં સમર્થ થવા માટે તમારા ફોન પર આ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"તમારી ઑડિઓ સેટિંગ્સ બદલો"</string>
-    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"એપ્લિકેશનને વૈશ્વિક ઑડિઓ સેટિંગ્સને સંશોધિત કરવાની મંજૂરી આપે છે, જેમ કે વોલ્યુમ અને આઉટપુટ માટે કયા સ્પીકરનો ઉપયોગ કરવો."</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"એપ્લિકેશનને વૈશ્વિક ઑડિઓ સેટિંગ્સને સંશોધિત કરવાની મંજૂરી આપે છે, જેમ કે વૉલ્યૂમ અને આઉટપુટ માટે કયા સ્પીકરનો ઉપયોગ કરવો."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ઑડિઓ રેકોર્ડ કરવાની"</string>
     <string name="permdesc_recordAudio" msgid="4245930455135321433">"આ ઍપ્લિકેશન, માઇક્રોફોનનો ઉપયોગ કરીને કોઈપણ સમયે ઑડિઓ રેકોર્ડ કરી શકે છે."</string>
-    <string name="permlab_sim_communication" msgid="2935852302216852065">"SIM ને આદેશો મોકલો"</string>
-    <string name="permdesc_sim_communication" msgid="5725159654279639498">"એપ્લિકેશનને SIM પરા આદેશો મોકલવાની મંજૂરી આપે છે. આ ખૂબ જ ખતરનાક છે."</string>
+    <string name="permlab_sim_communication" msgid="2935852302216852065">"સિમ ને આદેશો મોકલો"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"એપ્લિકેશનને સિમ પરા આદેશો મોકલવાની મંજૂરી આપે છે. આ ખૂબ જ ખતરનાક છે."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"ચિત્રો અને વિડિઓઝ લો"</string>
     <string name="permdesc_camera" msgid="5392231870049240670">"આ ઍપ્લિકેશન, કૅમેરાનો ઉપયોગ કરીને કોઈપણ સમયે ચિત્રો લઈ અને વિડિઓઝ રેકોર્ડ કરી શકે છે."</string>
     <string name="permlab_vibrate" msgid="7696427026057705834">"વાઇબ્રેશન નિયંત્રિત કરો"</string>
@@ -446,18 +445,18 @@
     <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"એપ્લિકેશનને નેટવર્ક કનેક્ટિવિટીની સ્થિતિ બદલવાની મંજૂરી આપે છે."</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"ટિથર કરેલ કનેક્ટિવિટી બદલો"</string>
     <string name="permdesc_changeTetherState" msgid="1524441344412319780">"એપ્લિકેશનને ટિથર્ડ નેટવર્ક કનેક્ટિવિટીની સ્થિતિ બદલવાની મંજૂરી આપે છે."</string>
-    <string name="permlab_accessWifiState" msgid="5202012949247040011">"Wi-Fi કનેક્શન્સ જુઓ"</string>
-    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"એપ્લિકેશનને Wi-Fi નેટવર્કિંગ વિશેની માહિતી જોવાની મંજૂરી આપે છે, જેમ કે Wi-Fi સક્ષમ છે કે કેમ અને કનેક્ટ થયેલ Wi-Fi ઉપકરણોના નામ."</string>
-    <string name="permlab_changeWifiState" msgid="6550641188749128035">"Wi-Fi થી કનેક્ટ અને ડિસ્કનેક્ટ કરો"</string>
-    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"એપ્લિકેશનને Wi-Fi ઍક્સેસ બિંદુઓથી કનેક્ટ થવા અને ડિસ્કનેક્ટ થવાની અને Wi-Fi નેટવર્ક્સ માટે ઉપકરણ ગોઠવણી પર ફેરફારો કરવાની મંજૂરી આપે છે."</string>
-    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi મલ્ટિકાસ્ટ રિસેપ્શનને મંજૂરી આપો"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"એપ્લિકેશનને ફક્ત તમારા ટેબ્લેટ પર નહીં, પણ મલ્ટિકાસ્ટ સરનામાંનો ઉપયોગ કરીને Wi-Fi નેટવર્ક પરના તમામ ઉપકરણોને મોકલાયેલ પૅકેટ્સ પ્રાપ્ત કરવાની મંજૂરી આપે છે. તે બિન-મલ્ટિકાસ્ટ મોડ કરતાં વધુ પાવર વાપરે છે."</string>
-    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"એપ્લિકેશનને ફક્ત તમારા ટીવી પર નહીં, પણ મલ્ટિકાસ્ટ સરનામાંનો ઉપયોગ કરીને Wi-Fi નેટવર્ક પરના તમામ ઉપકરણોને મોકલાયેલ પૅકેટ્સ પ્રાપ્ત કરવાની મંજૂરી આપે છે. તે બિન-મલ્ટિકાસ્ટ મોડ કરતાં વધુ પાવર વાપરે છે."</string>
-    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"એપ્લિકેશનને ફક્ત તમારા ફોન પર નહીં, પણ મલ્ટિકાસ્ટ સરનામાંનો ઉપયોગ કરીને Wi-Fi નેટવર્ક પર તમામ ઉપકરણોને મોકલાયેલ પૅકેટ્સ પ્રાપ્ત કરવાની મંજૂરી આપે છે. તે બિન-મલ્ટિકાસ્ટ મોડ કરતાં વધુ પાવર વાપરે છે."</string>
-    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"Bluetooth સેટિંગ્સ ઍક્સેસ કરો"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"એપ્લિકેશનને સ્થાનિક Bluetooth ટેબ્લેટ ગોઠવવાની અને રિમોટ ઉપકરણો શોધવા અને તેમની સાથે જોડી કરવાની મંજૂરી આપે છે."</string>
-    <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"એપ્લિકેશનને સ્થાનિક Bluetooth ટીવી ગોઠવવાની અને રિમોટ ઉપકરણો શોધવા અને તેમની સાથે જોડી કરવાની મંજૂરી આપે છે."</string>
-    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"એપ્લિકેશનને સ્થાનિક Bluetooth ફોન ગોઠવવાની અને રિમોટ ઉપકરણો શોધવા અને તેમની સાથે જોડી કરવાની મંજૂરી આપે છે."</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"વાઇ-ફાઇ કનેક્શન્સ જુઓ"</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"એપ્લિકેશનને વાઇ-ફાઇ નેટવર્કિંગ વિશેની માહિતી જોવાની મંજૂરી આપે છે, જેમ કે વાઇ-ફાઇ સક્ષમ છે કે કેમ અને કનેક્ટ થયેલ વાઇ-ફાઇ ઉપકરણોના નામ."</string>
+    <string name="permlab_changeWifiState" msgid="6550641188749128035">"વાઇ-ફાઇ થી કનેક્ટ અને ડિસ્કનેક્ટ કરો"</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"એપ્લિકેશનને વાઇ-ફાઇ ઍક્સેસ બિંદુઓથી કનેક્ટ થવા અને ડિસ્કનેક્ટ થવાની અને વાઇ-ફાઇ નેટવર્ક્સ માટે ઉપકરણ ગોઠવણી પર ફેરફારો કરવાની મંજૂરી આપે છે."</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"વાઇ-ફાઇ મલ્ટિકાસ્ટ રિસેપ્શનને મંજૂરી આપો"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"એપ્લિકેશનને ફક્ત તમારા ટેબ્લેટ પર નહીં, પણ મલ્ટિકાસ્ટ સરનામાંનો ઉપયોગ કરીને વાઇ-ફાઇ નેટવર્ક પરના તમામ ઉપકરણોને મોકલાયેલ પૅકેટ્સ પ્રાપ્ત કરવાની મંજૂરી આપે છે. તે બિન-મલ્ટિકાસ્ટ મોડ કરતાં વધુ પાવર વાપરે છે."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"એપ્લિકેશનને ફક્ત તમારા ટીવી પર નહીં, પણ મલ્ટિકાસ્ટ સરનામાંનો ઉપયોગ કરીને વાઇ-ફાઇ નેટવર્ક પરના તમામ ઉપકરણોને મોકલાયેલ પૅકેટ્સ પ્રાપ્ત કરવાની મંજૂરી આપે છે. તે બિન-મલ્ટિકાસ્ટ મોડ કરતાં વધુ પાવર વાપરે છે."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"એપ્લિકેશનને ફક્ત તમારા ફોન પર નહીં, પણ મલ્ટિકાસ્ટ સરનામાંનો ઉપયોગ કરીને વાઇ-ફાઇ નેટવર્ક પર તમામ ઉપકરણોને મોકલાયેલ પૅકેટ્સ પ્રાપ્ત કરવાની મંજૂરી આપે છે. તે બિન-મલ્ટિકાસ્ટ મોડ કરતાં વધુ પાવર વાપરે છે."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"બ્લૂટૂથ સેટિંગ્સ ઍક્સેસ કરો"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"એપ્લિકેશનને સ્થાનિક બ્લૂટૂથ ટેબ્લેટ ગોઠવવાની અને રિમોટ ઉપકરણો શોધવા અને તેમની સાથે જોડી કરવાની મંજૂરી આપે છે."</string>
+    <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"એપ્લિકેશનને સ્થાનિક બ્લૂટૂથ ટીવી ગોઠવવાની અને રિમોટ ઉપકરણો શોધવા અને તેમની સાથે જોડી કરવાની મંજૂરી આપે છે."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"એપ્લિકેશનને સ્થાનિક બ્લૂટૂથ ફોન ગોઠવવાની અને રિમોટ ઉપકરણો શોધવા અને તેમની સાથે જોડી કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_accessWimaxState" msgid="4195907010610205703">"WiMAX થી કનેક્ટ અને ડિસ્કનેક્ટ કરો"</string>
     <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"એપ્લિકેશનને WiMAX સક્ષમ છે કે કેમ અને કનેક્ટ થયેલ છે તે કોઈપણ WiMAX નેટવર્ક્સ વિશેની માહિતી નિર્ધારિત કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_changeWimaxState" msgid="340465839241528618">"WiMAX સ્થિતિ બદલો"</string>
@@ -465,9 +464,9 @@
     <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"ટીવીને WiMAX નેટવર્ક્સ પર કનેક્ટ કરવાની અને ટીવીને તેનાથી ડિસ્કનેક્ટ કરવાની મંજૂરી એપ્લિકેશનને આપે છે."</string>
     <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"ફોનને WiMAX નેટવર્ક્સ પર કનેક્ટ કરવાની અને ફોનને તેનાથી ડિસ્કનેક્ટ કરવાની મંજૂરી એપ્લિકેશનને આપે છે."</string>
     <string name="permlab_bluetooth" msgid="6127769336339276828">"બ્લૂટૂથ ઉપકરણો સાથે જોડાણ બનાવો"</string>
-    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"એપ્લિકેશનને ટેબ્લેટ પર Bluetooth ની ગોઠવણી જોવાની અને જોડી કરેલ ઉપકરણો સાથે કનેક્શન્સ કરવાની અને સ્વીકારવાની મંજૂરી આપે છે."</string>
-    <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"એપ્લિકેશનને ટીવી પર Bluetooth ની ગોઠવણી જોવાની અને જોડી કરેલ ઉપકરણો સાથે કનેક્શન્સ કરવાની અને સ્વીકારવાની મંજૂરી આપે છે."</string>
-    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"એપ્લિકેશનને ફોન પર Bluetooth ની ગોઠવણી જોવાની અને જોડી કરેલ ઉપકરણો સાથે કનેક્શન્સ કરવાની અને સ્વીકારવાની મંજૂરી આપે છે."</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"એપ્લિકેશનને ટેબ્લેટ પર બ્લૂટૂથ ની ગોઠવણી જોવાની અને જોડી કરેલ ઉપકરણો સાથે કનેક્શન્સ કરવાની અને સ્વીકારવાની મંજૂરી આપે છે."</string>
+    <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"એપ્લિકેશનને ટીવી પર બ્લૂટૂથ ની ગોઠવણી જોવાની અને જોડી કરેલ ઉપકરણો સાથે કનેક્શન્સ કરવાની અને સ્વીકારવાની મંજૂરી આપે છે."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"એપ્લિકેશનને ફોન પર બ્લૂટૂથ ની ગોઠવણી જોવાની અને જોડી કરેલ ઉપકરણો સાથે કનેક્શન્સ કરવાની અને સ્વીકારવાની મંજૂરી આપે છે."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"નિઅર ફીલ્ડ કમ્યુનિકેશન નિયંત્રિત કરો"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"ઍપ્લિકેશનને નિઅર ફીલ્ડ કમ્યુનિકેશન (NFC) ટૅગ, કાર્ડ અને રીડર સાથે સંચાર કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"તમારું સ્ક્રીન લૉક અક્ષમ કરો"</string>
@@ -510,8 +509,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"એપ્લિકેશનને SD કાર્ડ પર લખવાની મંજૂરી આપે છે."</string>
     <string name="permlab_use_sip" msgid="2052499390128979920">"SIP કૉલ્સ કરો/પ્રાપ્ત કરો"</string>
     <string name="permdesc_use_sip" msgid="2297804849860225257">"એપ્લિકેશનને SIP કૉલ્સ કરવા અને પ્રાપ્ત કરવાની મંજૂરી આપે છે."</string>
-    <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"નવા ટેલિકોમ SIM કનેક્શન્સની નોંધણી કરો"</string>
-    <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"એપ્લિકેશનને નવા ટેલિકોમ SIM કનેક્શન્સની નોંધણી કરવાની મંજૂરી આપે છે."</string>
+    <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"નવા ટેલિકોમ સિમ કનેક્શન્સની નોંધણી કરો"</string>
+    <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"એપ્લિકેશનને નવા ટેલિકોમ સિમ કનેક્શન્સની નોંધણી કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_register_call_provider" msgid="108102120289029841">"નવા ટેલિકોમ કનેક્શન્સની નોંધણી કરો"</string>
     <string name="permdesc_register_call_provider" msgid="7034310263521081388">"એપ્લિકેશનને નવા ટેલિકોમ કનેક્શન્સની નોંધણી કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_connection_manager" msgid="1116193254522105375">"ટેલિકોમ કનેક્શન્સ સંચાલિત કરો"</string>
@@ -883,7 +882,7 @@
     <string name="minute" msgid="9148878657703769868">"મિનિટ"</string>
     <string name="minutes" msgid="5646001005827034509">"મિનિટ"</string>
     <string name="second" msgid="3184235808021478">"સે"</string>
-    <string name="seconds" msgid="3161515347216589235">"સેકંડ"</string>
+    <string name="seconds" msgid="3161515347216589235">"સેકન્ડ"</string>
     <string name="week" msgid="5617961537173061583">"અઠવાડિયું"</string>
     <string name="weeks" msgid="6509623834583944518">"અઠવાડિયા"</string>
     <string name="year" msgid="4001118221013892076">"વર્ષ"</string>
@@ -954,8 +953,8 @@
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> વર્ષમાં</item>
     </plurals>
     <string name="VideoView_error_title" msgid="3534509135438353077">"વિડિઓમાં સમસ્યા"</string>
-    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"આ ઉપકરણ પર સ્ટ્રીમ કરવા માટે આ વિડિઓ માન્ય નથી."</string>
-    <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"આ વિડિઓ ચલાવી શકતાં નથી."</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"આ ઉપકરણ પર સ્ટ્રીમ કરવા માટે આ વીડિઓ માન્ય નથી."</string>
+    <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"આ વીડિઓ ચલાવી શકતાં નથી."</string>
     <string name="VideoView_error_button" msgid="2822238215100679592">"ઓકે"</string>
     <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="noon" msgid="7245353528818587908">"બપોરે"</string>
@@ -1079,17 +1078,17 @@
     <string name="sendText" msgid="5209874571959469142">"ટેક્સ્ટ માટે ક્રિયા પસંદ કરો"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"રિંગર વૉલ્યૂમ"</string>
     <string name="volume_music" msgid="5421651157138628171">"મીડિયા વૉલ્યૂમ"</string>
-    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Bluetooth મારફતે ચાલી રહ્યું છે"</string>
+    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"બ્લૂટૂથ મારફતે ચાલી રહ્યું છે"</string>
     <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"સાઇલેન્ટ રિંગટોન સેટ કરી"</string>
     <string name="volume_call" msgid="3941680041282788711">"ઇન-કૉલ વૉલ્યૂમ"</string>
-    <string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetooth ઇન-કૉલ વોલ્યુમ"</string>
+    <string name="volume_bluetooth_call" msgid="2002891926351151534">"બ્લૂટૂથ ઇન-કૉલ વૉલ્યૂમ"</string>
     <string name="volume_alarm" msgid="1985191616042689100">"એલાર્મ વૉલ્યૂમ"</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_bluetooth" msgid="6538894177255964340">"બ્લૂટૂથ વૉલ્યૂમ"</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="ringtone_default" msgid="3789758980357696936">"ડિફોલ્ટ રિંગટોન"</string>
     <string name="ringtone_default_with_actual" msgid="1767304850491060581">"ડિફૉલ્ટ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
@@ -1099,39 +1098,46 @@
     <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"સૂચના ધ્વનિઓ"</string>
     <string name="ringtone_unknown" msgid="3914515995813061520">"અજાણી"</string>
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
-      <item quantity="one">Wi-Fi નેટવર્ક્સ ઉપલબ્ધ</item>
-      <item quantity="other">Wi-Fi નેટવર્ક્સ ઉપલબ્ધ</item>
+      <item quantity="one">વાઇ-ફાઇ નેટવર્ક્સ ઉપલબ્ધ</item>
+      <item quantity="other">વાઇ-ફાઇ નેટવર્ક્સ ઉપલબ્ધ</item>
     </plurals>
     <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
-      <item quantity="one">ખુલ્લા Wi-Fi નેટવર્ક્સ ઉપલબ્ધ છે</item>
-      <item quantity="other">ખુલ્લા Wi-Fi નેટવર્ક્સ ઉપલબ્ધ છે</item>
+      <item quantity="one">ખુલ્લા વાઇ-ફાઇ નેટવર્ક્સ ઉપલબ્ધ છે</item>
+      <item quantity="other">ખુલ્લા વાઇ-ફાઇ નેટવર્ક્સ ઉપલબ્ધ છે</item>
     </plurals>
-    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi નેટવર્ક પર સાઇન ઇન કરો"</string>
+    <string name="wifi_available_title" msgid="3817100557900599505">"ખુલ્લા વાઇ-ફાઇ નેટવર્ક સાથે કનેક્ટ કરો"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ખુલ્લા વાઇ-ફાઇ નેટવર્ક સાથે કનેક્ટ કરી રહ્યાં છીએ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"વાઇ-ફાઇ નેટવર્ક સાથે કનેક્ટ કર્યુ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"વાઇ-ફાઇ નેટવર્ક સાથે કનેક્ટ કરી શકાયું નથી"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"બધા નેટવર્ક જોવા ટૅપ કરો"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"કનેક્ટ કરો"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"બધા નેટવર્ક"</string>
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"વાઇ-ફાઇ નેટવર્ક પર સાઇન ઇન કરો"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"નેટવર્ક પર સાઇન ઇન કરો"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8451173622563841546">"Wi-Fi ને કોઈ ઇન્ટરનેટ ઍક્સેસ નથી"</string>
+    <string name="wifi_no_internet" msgid="8451173622563841546">"વાઇ-ફાઇ ને કોઈ ઇન્ટરનેટ ઍક્સેસ નથી"</string>
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"વિકલ્પો માટે ટૅપ કરો"</string>
     <string name="network_switch_metered" msgid="4671730921726992671">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> પર સ્વિચ કર્યું"</string>
     <string name="network_switch_metered_detail" msgid="5325661434777870353">"જ્યારે <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> પાસે કોઈ ઇન્ટરનેટ ઍક્સેસ ન હોય ત્યારે ઉપકરણ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> નો ઉપયોગ કરે છે. શુલ્ક લાગુ થઈ શકે છે."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> પરથી <xliff:g id="NEW_NETWORK">%2$s</xliff:g> પર સ્વિચ કર્યું"</string>
   <string-array name="network_switch_type_name">
     <item msgid="3979506840912951943">"મોબાઇલ ડેટા"</item>
-    <item msgid="75483255295529161">"Wi-Fi"</item>
-    <item msgid="6862614801537202646">"Bluetooth"</item>
+    <item msgid="75483255295529161">"વાઇ-ફાઇ"</item>
+    <item msgid="6862614801537202646">"બ્લૂટૂથ"</item>
     <item msgid="5447331121797802871">"ઇથરનેટ"</item>
     <item msgid="8257233890381651999">"VPN"</item>
   </string-array>
     <string name="network_switch_type_name_unknown" msgid="4552612897806660656">"અજાણ્યો નેટવર્ક પ્રકાર"</string>
-    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi સાથે કનેક્ટ કરી શકાયું નથી"</string>
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"વાઇ-ફાઇ સાથે કનેક્ટ કરી શકાયું નથી"</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" નબળું ઇન્ટરનેટ કનેક્શન ધરાવે છે."</string>
     <string name="wifi_connect_alert_title" msgid="8455846016001810172">"કનેક્શનની મંજૂરી આપીએ?"</string>
     <string name="wifi_connect_alert_message" msgid="6451273376815958922">"%1$s ઍપ્લિકેશન Wifi નેટવર્ક %2$s થી કનેક્ટ થવા માગે છે"</string>
     <string name="wifi_connect_default_application" msgid="7143109390475484319">"ઍપ્લિકેશન"</string>
-    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
-    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Direct પ્રારંભ કરો. આ Wi-Fi ક્લાઇન્ટ/હોટસ્પોટને બંધ કરશે."</string>
-    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct પ્રારંભ કરી શકાયું નથી."</string>
-    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct ચાલુ છે"</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"વાઇ-ફાઇ ડાઇરેક્ટ"</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"વાઇ-ફાઇ ડાઇરેક્ટ પ્રારંભ કરો. આ વાઇ-ફાઇ ક્લાઇન્ટ/હોટસ્પોટને બંધ કરશે."</string>
+    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"વાઇ-ફાઇ ડાઇરેક્ટ પ્રારંભ કરી શકાયું નથી."</string>
+    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"વાઇ-ફાઇ ડાઇરેક્ટ ચાલુ છે"</string>
     <string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"સેટિંગ્સ માટે ટૅપ કરો"</string>
     <string name="accept" msgid="1645267259272829559">"સ્વીકારો"</string>
     <string name="decline" msgid="2112225451706137894">"નકારો"</string>
@@ -1141,9 +1147,9 @@
     <string name="wifi_p2p_to_message" msgid="248968974522044099">"પ્રતિ:"</string>
     <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"આવશ્યક પિન લખો:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"પિન:"</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"ટેબ્લેટ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> થી કનેક્ટ હોય તે વખતે Wi-Fi થી અસ્થાયી રૂપે ડિસ્કનેક્ટ કરવામાં આવશે"</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"ટીવી <xliff:g id="DEVICE_NAME">%1$s</xliff:g> થી કનેક્ટ હોય તે વખતે Wi-Fi થી અસ્થાયી રૂપે ડિસ્કનેક્ટ કરવામાં આવશે"</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ફોન <xliff:g id="DEVICE_NAME">%1$s</xliff:g> થી કનેક્ટ હોય તે વખતે Wi-Fi થી અસ્થાયી રૂપે ડિસ્કનેક્ટ કરવામાં આવશે"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"ટેબ્લેટ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> થી કનેક્ટ હોય તે વખતે વાઇ-ફાઇ થી અસ્થાયી રૂપે ડિસ્કનેક્ટ કરવામાં આવશે"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"ટીવી <xliff:g id="DEVICE_NAME">%1$s</xliff:g> થી કનેક્ટ હોય તે વખતે વાઇ-ફાઇ થી અસ્થાયી રૂપે ડિસ્કનેક્ટ કરવામાં આવશે"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ફોન <xliff:g id="DEVICE_NAME">%1$s</xliff:g> થી કનેક્ટ હોય તે વખતે વાઇ-ફાઇ થી અસ્થાયી રૂપે ડિસ્કનેક્ટ કરવામાં આવશે"</string>
     <string name="select_character" msgid="3365550120617701745">"અક્ષર શામેલ કરો"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"SMS સંદેશા મોકલી રહ્યું છે"</string>
     <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; મોટા પ્રમાણમાં SMS સંદેશા મોકલી રહ્યું છે. શું તમે સંદેશા મોકલવાનું ચાલુ રાખવા માટે આ એપ્લિકેશનને મંજૂરી આપવા માગો છો?"</string>
@@ -1163,11 +1169,11 @@
     <string name="sim_done_button" msgid="827949989369963775">"થઈ ગયું"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"સિમ કાર્ડ ઉમેર્યો"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"મોબાઇલ નેટવર્કને ઍક્સેસ કરવા માટે તમારા ઉપકરણને પુનઃપ્રારંભ કરો."</string>
-    <string name="sim_restart_button" msgid="4722407842815232347">"પુનઃપ્રારંભ કરો"</string>
-    <string name="carrier_app_dialog_message" msgid="7066156088266319533">"તમારું નવું SIM ઠીકથી કામ કરે તે માટે, તમને તમારા કેરીઅર પરથી ઍપ્લિકેશન ઇન્સ્ટૉલ કરીને ખોલવી પડશે."</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"રિસ્ટાર્ટ કરો"</string>
+    <string name="carrier_app_dialog_message" msgid="7066156088266319533">"તમારું નવું સિમ ઠીકથી કામ કરે તે માટે, તમને તમારા કેરીઅર પરથી ઍપ્લિકેશન ઇન્સ્ટૉલ કરીને ખોલવી પડશે."</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"ઍપ્લિકેશન મેળવો"</string>
     <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"હમણાં નહીં"</string>
-    <string name="carrier_app_notification_title" msgid="8921767385872554621">"નવું SIM દાખલ કર્યું"</string>
+    <string name="carrier_app_notification_title" msgid="8921767385872554621">"નવું સિમ દાખલ કર્યું"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"તેને સેટ કરવા માટે ટૅપ કરો"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"સમય સેટ કરો"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"તારીખ સેટ કરો"</string>
@@ -1181,10 +1187,12 @@
     <string name="usb_charging_notification_title" msgid="6895185153353640787">"આ ઉપકરણને USB થી ચાર્જ કરે છે"</string>
     <string name="usb_supplying_notification_title" msgid="5310642257296510271">"જોડાયેલ ઉપકરણ માટે USB પાવર પૂરો પાડે છે"</string>
     <string name="usb_mtp_notification_title" msgid="8396264943589760855">"ફાઇલ ટ્રાન્સફર માટે USB"</string>
-    <string name="usb_ptp_notification_title" msgid="1347328437083192112">"ફોટા ટ્રાન્સફર માટે USB"</string>
+    <string name="usb_ptp_notification_title" msgid="1347328437083192112">"ફોટો ટ્રાન્સફર માટે USB"</string>
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI માટે USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ઍક્સેસરીથી કનેક્ટ થયાં"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"વધુ વિકલ્પો માટે ટૅપ કરો."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"એનાલોગ ઑડિઓ ઍક્સેસરી મળી"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"જોડેલ ઉપકરણ આ ફોન સાથે સુસંગત નથી. વધુ જાણવા માટે ટૅપ કરો."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ડીબગિંગ કનેક્ટ થયું."</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ડીબગિંગ અક્ષમ કરવા માટે ટૅપ કરો."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ડિબગીંગને અક્ષમ કરવા માટે પસંદ કરો."</string>
@@ -1209,7 +1217,7 @@
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> ને તૈયાર કરી રહ્યું છે"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"ભૂલો માટે તપાસી રહ્યું છે"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"નવું <xliff:g id="NAME">%s</xliff:g> મળ્યું"</string>
-    <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"ફોટા અને મીડિયા સ્થાનાંતરિત કરવા માટે"</string>
+    <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"ફોટો અને મીડિયા ટ્રાન્સફર કરવા માટે"</string>
     <string name="ext_media_unmountable_notification_title" msgid="8295123366236989588">"દૂષિત <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_message" msgid="2343202057122495773">"<xliff:g id="NAME">%s</xliff:g> દૂષિત છે. ઠીક કરવા માટે ટૅપ કરો."</string>
     <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> દૂષિત છે. સુધારવા માટે પસંદ કરો."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> થી કનેક્ટ થયાં. નેટવર્કને સંચાલિત કરવા માટે ટૅપ કરો."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"હંમેશા-ચાલુ VPN કનેક્ટ થઈ રહ્યું છે…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"હંમેશા-ચાલુ VPN કનેક્ટ થયું"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"હંમેશાં-ચાલુ VPN ડિસ્કનેક્ટ થયું"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"હંમેશાં-ચાલુ VPN થી ડિસ્કનેક્ટ થયું"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"હંમેશાં ચાલુ VPN ભૂલ"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"સેટ કરવા માટે ટૅપ કરો"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"નેટવર્ક અથવા VPN સેટિંગ્સ બદલો"</string>
     <string name="upload_file" msgid="2897957172366730416">"ફાઇલ પસંદ કરો"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"કોઈ ફાઇલ પસંદ કરેલી નથી"</string>
     <string name="reset" msgid="2448168080964209908">"ફરીથી સેટ કરો"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"કાર મોડથી બહાર નીકળવા માટે ટૅપ કરો."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ટિથરિંગ અથવા હૉટસ્પૉટ સક્રિય"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"સેટ કરવા માટે ટૅપ કરો."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ટિથરિંગ અક્ષમ કરેલ છે"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"વિગતો માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો"</string>
     <string name="back_button_label" msgid="2300470004503343439">"પાછળ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"આગલું"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"છોડો"</string>
@@ -1381,12 +1387,12 @@
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"2G-3G ડેટા મર્યાદા પર પહોંચ્યાં"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"4G ડેટા મર્યાદા સુધી પહોંચ્યાં"</string>
     <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"મોબાઇલ ડેટાની મર્યાદા આવી ગઈ"</string>
-    <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Wi-Fi ડેટા સીમા પર પહોંચ્યાં"</string>
+    <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"વાઇ-ફાઇ ડેટા સીમા પર પહોંચ્યાં"</string>
     <string name="data_usage_limit_body" msgid="291731708279614081">"બાકીના ચક્ર માટે ડેટા થોભાવ્યો"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G ડેટા મર્યાદા ઓળંગાઈ"</string>
     <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G ડેટા મર્યાદા ઓળંગાઈ"</string>
     <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"મોબાઇલ ડેટા મર્યાદા ઓળંગાઈ"</string>
-    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi ડેટા મર્યાદા ઓળંગાઈ"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"વાઇ-ફાઇ ડેટા મર્યાદા ઓળંગાઈ"</string>
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"ઉલ્લેખિત મર્યાદાથી <xliff:g id="SIZE">%s</xliff:g> વધુ."</string>
     <string name="data_usage_restricted_title" msgid="5965157361036321914">"બૅકગ્રાઉન્ડ ડેટા પ્રતિબંધિત"</string>
     <string name="data_usage_restricted_body" msgid="469866376337242726">"પ્રતિબંધ દૂર કરવા માટે ટૅપ કરો."</string>
@@ -1420,7 +1426,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"સ્પીકર્સ ડૉક કરો"</string>
     <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"સિસ્ટમ"</string>
-    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth ઑડિઓ"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"બ્લૂટૂથ ઑડિઓ"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"વાયરલેસ ડિસ્પ્લે"</string>
     <string name="media_route_button_content_description" msgid="591703006349356016">"કાસ્ટ કરો"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"ઉપકરણ સાથે કનેક્ટ કરો"</string>
@@ -1447,14 +1453,14 @@
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"સિમ પિન દાખલ કરો"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"પિન દાખલ કરો"</string>
     <string name="kg_password_instructions" msgid="5753646556186936819">"પાસવર્ડ દાખલ કરો"</string>
-    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM હવે અક્ષમ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. વિગતો માટે કેરીઅરનો સંપર્ક કરો."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"સિમ હવે અક્ષમ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. વિગતો માટે કેરીઅરનો સંપર્ક કરો."</string>
     <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"જોઈતો પિન કોડ દાખલ કરો"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"જોઈતા પિન કોડની પુષ્ટિ કરો"</string>
     <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">"PUK કોડ 8 નંબર્સનો હોવો જોઈએ."</string>
-    <string name="kg_invalid_puk" msgid="3638289409676051243">"સાચો PUK કોડ ફરીથી દાખલ કરો. પુનરાવર્તિત પ્રયાસો SIM ને કાયમી રીતે અક્ષમ કરશે."</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>
     <string name="kg_login_instructions" msgid="1100551261265506448">"અનલૉક કરવા માટે, તમારા Google એકાઉન્ટથી સાઇન ઇન કરો."</string>
@@ -1599,7 +1605,7 @@
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"પછી ફરી પ્રયાસ કરો"</string>
-    <string name="immersive_cling_title" msgid="8394201622932303336">"પૂર્ણ સ્ક્રીન જોઈ રહ્યાં છે"</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"પૂર્ણ સ્ક્રીન પર જુવો"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"બહાર નીકળવા માટે, ટોચ પરથી નીચે સ્વાઇપ કરો."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"સમજાઈ ગયું"</string>
     <string name="done_label" msgid="2093726099505892398">"થઈ ગયું"</string>
@@ -1623,7 +1629,7 @@
     <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" msgid="1960431123816253034">"બૅટરી આવરદા વધુ સારી કરવામાં સહાય માટે, બૅટરી સેવર તમારા ઉપકરણના પ્રદર્શનને ઘટાડે છે અને વાઇબ્રેશન, સ્થાન સેવાઓ અને મોટાભાગના પૃષ્ઠભૂમિ ડેટાને સીમિત કરે છે. ઇમેઇલ, મેસેજિંગ અને અન્ય ઍપ્લિકેશનો જે સમન્વયન પર આધાર રાખે છે તે તમે તેમને ખોલશો નહીં ત્યાં સુધી અપડેટ થઈ શકતી નથી.\n\nજ્યારે તમારું ઉપકરણ ચાર્જ થઈ રહ્યું હોય ત્યારે બૅટરી સેવર આપમેળે બંધ થઈ જાય છે."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"બૅટરી આવરદા વધુ સારી કરવામાં સહાય માટે, બૅટરી સેવર તમારા ઉપકરણના પ્રદર્શનને ઘટાડે છે અને વાઇબ્રેશન, સ્થાન સેવાઓ અને મોટાભાગના બૅકગ્રાઉન્ડ ડેટાને સીમિત કરે છે. ઇમેઇલ, મેસેજિંગ અને અન્ય ઍપ્લિકેશનો જે સમન્વયન પર આધાર રાખે છે તે તમે તેમને ખોલશો નહીં ત્યાં સુધી અપડેટ થઈ શકતી નથી.\n\nજ્યારે તમારું ઉપકરણ ચાર્જ થઈ રહ્યું હોય ત્યારે બૅટરી સેવર આપમેળે બંધ થઈ જાય છે."</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>
@@ -1723,21 +1729,15 @@
     <string name="unpin_target" msgid="3556545602439143442">"અનપિન કરો"</string>
     <string name="app_info" msgid="6856026610594615344">"ઍપ્લિકેશન માહિતી"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"ઉપકરણ ફરીથી સેટ કરીએ?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"ઉપકરણને ફરીથી સેટ કરવા માટે ટૅપ કરો"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ડેમો પ્રારંભ કરી રહ્યાં છે…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"ઉપકરણ ફરીથી સેટ કરી રહ્યાં છે…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"ઉપકરણ ફરીથી સેટ કરીએ?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"તમે કોઈપણ ફેરફારો ગુમાવશો અને ડેમો <xliff:g id="TIMEOUT">%1$s</xliff:g> સેકન્ડમાં ફરી શરૂ થશે…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"રદ કરો"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"હમણાં ફરીથી સેટ કરો"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> અક્ષમ કર્યું"</string>
     <string name="conference_call" msgid="3751093130790472426">"કોન્ફરન્સ કૉલ"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"ટૂલટિપ"</string>
     <string name="app_category_game" msgid="5431836943981492993">"રમતો"</string>
     <string name="app_category_audio" msgid="1659853108734301647">"સંગીત અને ઑડિઓ"</string>
-    <string name="app_category_video" msgid="2728726078629384196">"મૂવી અને વિડિઓ"</string>
-    <string name="app_category_image" msgid="4867854544519846048">"ફોટા અને છબીઓ"</string>
+    <string name="app_category_video" msgid="2728726078629384196">"મૂવી અને વીડિઓ"</string>
+    <string name="app_category_image" msgid="4867854544519846048">"ફોટો અને છબીઓ"</string>
     <string name="app_category_social" msgid="5842783057834965912">"સામાજિક અને સંચાર"</string>
     <string name="app_category_news" msgid="7496506240743986873">"સમાચાર અને સામાયિકો"</string>
     <string name="app_category_maps" msgid="5878491404538024367">"નકશા અને નેવિગેશન"</string>
@@ -1764,7 +1764,7 @@
     <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"<xliff:g id="TYPE_0">%1$s</xliff:g> અને <xliff:g id="TYPE_1">%2$s</xliff:g>ને &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt;માં સાચવીએ?"</string>
     <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> અને <xliff:g id="TYPE_2">%3$s</xliff:g>ને &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt;માં સાચવીએ?"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"સાચવો"</string>
-    <string name="autofill_save_no" msgid="2625132258725581787">"નહીં આભાર"</string>
+    <string name="autofill_save_no" msgid="2625132258725581787">"ના, આભાર"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"પાસવર્ડ"</string>
     <string name="autofill_save_type_address" msgid="4936707762193009542">"સરનામું"</string>
     <string name="autofill_save_type_credit_card" msgid="7127694776265563071">"ક્રેડિટ કાર્ડ"</string>
@@ -1774,9 +1774,10 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"દરિયાકિનારાના પ્રદેશો તથા નદીકાંઠાના વિસ્તારો ખાલી કરીને તાત્કાલિક સુરક્ષિત ઊંચા સ્થાન પર જાઓ."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"શાંત રહો અને નજીકમાં આશ્રય લો."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"કટોકટી સંદેશાઓનું પરીક્ષણ"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"જવાબ આપો"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
-    <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM મંજૂર નથી"</string>
+    <string name="mmcc_authentication_reject" msgid="7729819349669603406">"સિમ મંજૂર નથી"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIMની જોગવાઈ કરી નથી"</string>
-    <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM મંજૂર નથી"</string>
+    <string name="mmcc_illegal_ms" msgid="2769452751852211112">"સિમ મંજૂર નથી"</string>
     <string name="mmcc_illegal_me" msgid="4438696681169345015">"ફોન મંજૂર નથી"</string>
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 2f757d7..023a7dd 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="byteShort" msgid="8340973892742019101">"B"</string>
-    <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
-    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
-    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="kilobyteShort" msgid="7542884022844556968">"केबी"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"एमबी"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"जीबी"</string>
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
@@ -56,12 +56,12 @@
     <string name="mmiComplete" msgid="8232527495411698359">"MMI पूर्ण."</string>
     <string name="badPin" msgid="9015277645546710014">"आपके द्वारा लिखा गया पुराना पिन सही नहीं है."</string>
     <string name="badPuk" msgid="5487257647081132201">"आपके द्वारा लिखा गया PUK सही नहीं है."</string>
-    <string name="mismatchPin" msgid="609379054496863419">"आपके द्वारा लिखे गए पिन का मिलान नहीं होता."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"आपने जो पिन लिखे हैं उसका मिलान नहीं होता."</string>
     <string name="invalidPin" msgid="3850018445187475377">"कोई ऐसा पिन लिखें, जिसमें 4 से 8 अंक हों."</string>
     <string name="invalidPuk" msgid="8761456210898036513">"ऐसा PUK लिखें जो 8 अंकों या अधिक का हो."</string>
     <string name="needPuk" msgid="919668385956251611">"आपका सिम कार्ड PUK लॉक किया गया है. इसे अनलॉक करने के लिए PUK कोड लिखें."</string>
     <string name="needPuk2" msgid="4526033371987193070">"सिम कार्ड अनब्‍लॉक करने के लिए PUK2 लिखें."</string>
-    <string name="enablePin" msgid="209412020907207950">"असफल, सिम//RUIM लॉक सक्षम करें."</string>
+    <string name="enablePin" msgid="209412020907207950">"नहीं हो सका, सिम//RUIM लॉक चालू करें."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
       <item quantity="one">सिम के लॉक हो जाने से पहले आपके पास <xliff:g id="NUMBER_1">%d</xliff:g> प्रयास शेष हैं.</item>
       <item quantity="other">सिम के लॉक हो जाने से पहले आपके पास <xliff:g id="NUMBER_1">%d</xliff:g> प्रयास शेष हैं.</item>
@@ -93,24 +93,24 @@
     <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"कोई भी आपातकालीन कॉलिंग नहीं है"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"कोई वॉइस सेवा नहीं है"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"कोई वॉइस/आपातकालीन सेवा नहीं है"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"आपके स्थान के मोबाइल नेटवर्क की ओर से इस समय ऑफ़र नहीं किया जा रहा है"</string>
+    <string name="RestrictedStateContent" msgid="4278821484643362350">"मोबाइल नेटवर्क आपके जगह पर इस समय यह सेवाएं नहीं दे पा रहा"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"नेटवर्क तक नहीं पहुंच पा रहे हैं"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"रिसेप्शन बेहतर करने के लिए, सिस्टम &gt; नेटवर्क और इंटरनेट &gt; मोबाइल नेटवर्क &gt; पसंदीदा नेटवर्क प्रकार पर जाकर, चुना गया प्रकार बदलकर देखें."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"सूचनाएं"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"कॉल को दूसरे नंबर पर भेजना"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"आपातकालीन कॉलबैक मोड"</string>
     <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"मोबाइल डेटा सूचनाएं"</string>
-    <string name="notification_channel_sms" msgid="3441746047346135073">"SMS संदेश"</string>
+    <string name="notification_channel_sms" msgid="3441746047346135073">"मैसेज (एसएमएस)"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"वॉइसमेल संदेश"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"वाई-फ़ाई कॉलिंग"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"पीयर ने टेलीटाइपराइटर (TTY) मोड फ़ुल का अनुरोध किया"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"पीयर ने टेलीटाइपराइटर (TTY) मोड एचसीओ (HCO) का अनुरोध किया"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"पीयर ने टेलीटाइपराइटर (TTY) मोड वीसीअो (VCO) का अनुरोध किया"</string>
     <string name="peerTtyModeOff" msgid="3280819717850602205">"पीयर ने टेलीटाइपराइटर (TTY) मोड बंद का अनुरोध किया"</string>
-    <string name="serviceClassVoice" msgid="1258393812335258019">"ध्‍वनि"</string>
+    <string name="serviceClassVoice" msgid="1258393812335258019">"आवाज़"</string>
     <string name="serviceClassData" msgid="872456782077937893">"डेटा"</string>
     <string name="serviceClassFAX" msgid="5566624998840486475">"फ़ैक्स"</string>
-    <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
+    <string name="serviceClassSMS" msgid="2015460373701527489">"मैसेज (एसएमएस)"</string>
     <string name="serviceClassDataAsync" msgid="4523454783498551468">"Async"</string>
     <string name="serviceClassDataSync" msgid="7530000519646054776">"समन्वयन"</string>
     <string name="serviceClassPacket" msgid="6991006557993423453">"पैकेट"</string>
@@ -128,13 +128,13 @@
     <string name="roamingText10" msgid="3992906999815316417">"रोमिंग - आंशिक सेवा कार्यक्षमता"</string>
     <string name="roamingText11" msgid="4154476854426920970">"रोमिंग बैनर चालू"</string>
     <string name="roamingText12" msgid="1189071119992726320">"रोमिंग बैनर बंद"</string>
-    <string name="roamingTextSearching" msgid="8360141885972279963">"सेवा खोज रहा है"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"नेटवर्क खोज रहा है"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"वाई-फ़ाई कॉलिंग"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"वाई-फ़ाई से फ़ोन करने और मैसेज भेजने के लिए, सबसे पहले अपनी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से इस सेवा को सेट अप करने के लिए कहें. उसके बाद सेटिंग से वाई-फ़ाई कॉलिंग को फिर से चालू करें."</item>
+    <item msgid="3910386316304772394">"वाई-फ़ाई से फ़ोन करने और मैसेज भेजने के लिए, सबसे पहले अपनी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से इस सेवा को सेट अप करने के लिए कहें. उसके बाद सेटिंग से वाई-फ़ाई कॉलिंग को फिर से चालू करें. (गड़बड़ी कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"मोबाइल और इंटरनेट सेवा देने वाली कंपनी में रजिस्टर करें"</item>
+    <item msgid="7472393097168811593">"अपनी मोबाइल और इंटरनेट सेवा देने वाली कंपनी के साथ रजिस्टर करें (गड़बड़ी कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -153,17 +153,17 @@
     <string name="fcError" msgid="3327560126588500777">"कनेक्‍शन समस्‍या या अमान्‍य सुविधा कोड."</string>
     <string name="httpErrorOk" msgid="1191919378083472204">"ठीक है"</string>
     <string name="httpError" msgid="7956392511146698522">"कोई नेटवर्क गड़बड़ी हुई थी."</string>
-    <string name="httpErrorLookup" msgid="4711687456111963163">"URL नहीं मिल सका."</string>
+    <string name="httpErrorLookup" msgid="4711687456111963163">"यूआरएल नहीं मिल सका."</string>
     <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"साइट प्रमाणीकरण योजना समर्थित नहीं है."</string>
     <string name="httpErrorAuth" msgid="1435065629438044534">"प्रमाणीकृत नहीं किया जा सका."</string>
     <string name="httpErrorProxyAuth" msgid="1788207010559081331">"प्रॉक्‍सी सर्वर द्वारा प्रमाणीकरण असफल था."</string>
     <string name="httpErrorConnect" msgid="8714273236364640549">"सर्वर से कनेक्ट नहीं किया जा सका."</string>
     <string name="httpErrorIO" msgid="2340558197489302188">"सर्वर से संचार नहीं किया जा सका. बाद में पुन: प्रयास करें."</string>
     <string name="httpErrorTimeout" msgid="4743403703762883954">"सर्वर से कनेक्‍शन का समय समाप्त हुआ."</string>
-    <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"पेज में कई सर्वर रीडायरेक्‍ट हैं."</string>
+    <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"पेज में कई ऐसे कई वेबलिंक हैं जो दूसरे सर्वर पर ले जाते हैं."</string>
     <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"प्रोटोकॉल समर्थित नहीं है."</string>
     <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"सुरक्षित कनेक्शन स्थापित नहीं किया जा सका."</string>
-    <string name="httpErrorBadUrl" msgid="3636929722728881972">"URL अमान्‍य होने के कारण पेज नहीं खोला जा सका."</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"यूआरएल गलत होने की वजह से पेज नहीं खोला जा सका."</string>
     <string name="httpErrorFile" msgid="2170788515052558676">"फ़ाइल पर नहीं पहुंचा जा सका."</string>
     <string name="httpErrorFileNotFound" msgid="6203856612042655084">"अनुरोधित फ़ाइल नहीं मिल सकी."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"बहुत सारे अनुरोधों का संसाधन हो रहा है. बाद में पुन: प्रयास करें."</string>
@@ -171,13 +171,13 @@
     <string name="contentServiceSync" msgid="8353523060269335667">"समन्वयन"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"समन्वयन"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"बहुत से <xliff:g id="CONTENT_TYPE">%s</xliff:g> हटाए जाते हैं."</string>
-    <string name="low_memory" product="tablet" msgid="6494019234102154896">"टेबलेट मेमोरी भर गया है. स्‍थान खाली करने के लिए कुछ फ़ाइलें हटाएं."</string>
-    <string name="low_memory" product="watch" msgid="4415914910770005166">"घड़ी मेमोरी भर गया है. स्‍थान खाली करने के लिए कुछ फ़ाइलें हटाएं."</string>
-    <string name="low_memory" product="tv" msgid="516619861191025923">"टीवी की मेमोरी पूरी हो गई है. स्‍थान खाली करने के लिए कुछ फ़ाइलें हटाएं."</string>
-    <string name="low_memory" product="default" msgid="3475999286680000541">"फ़ोन मेमोरी भर गया है. स्‍थान खाली करने के लिए कुछ फ़ाइलें हटाएं."</string>
+    <string name="low_memory" product="tablet" msgid="6494019234102154896">"टैबलेट की मेमोरी भर गई है. जगह खाली करने के लिए कुछ फ़ाइलें मिटाएं."</string>
+    <string name="low_memory" product="watch" msgid="4415914910770005166">"घड़ी की मेमोरी भर गई है. स्‍थान खाली करने के लिए कुछ फ़ाइलें मिटाएं."</string>
+    <string name="low_memory" product="tv" msgid="516619861191025923">"टीवी की मेमोरी भर गई है. जगह खाली करने के लिए कुछ फ़ाइलें मिटाएं."</string>
+    <string name="low_memory" product="default" msgid="3475999286680000541">"फ़ोन मेमोरी भर गयी है. जगह खाली करने के लिए कुछ फ़ाइलें मिटाएं."</string>
     <plurals name="ssl_ca_cert_warning" formatted="false" msgid="5106721205300213569">
-      <item quantity="one">प्रमाणपत्र प्राधिकरण इंस्टॉल किए हुए हैं</item>
-      <item quantity="other">प्रमाणपत्र प्राधिकरण इंस्टॉल किए हुए हैं</item>
+      <item quantity="one">प्रमाणपत्र अनुमतियों को इंस्टॉल किया गया</item>
+      <item quantity="other">प्रमाणपत्र अनुमतियों को इंस्टॉल किया गया</item>
     </plurals>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"किसी अज्ञात तृतीय पक्ष के द्वारा"</string>
     <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"आपकी कार्य प्रोफ़ाइल का व्यवस्थापक करता है"</string>
@@ -191,7 +191,7 @@
     <string name="factory_reset_warning" msgid="5423253125642394387">"आपके डिवाइस को मिटा दिया जाएगा"</string>
     <string name="factory_reset_message" msgid="7972496262232832457">"व्यवस्थापक ऐप्लिकेशन का उपयोग नहीं किया जा सकता. अब आपके डिवाइस को मिटा दिया जाएगा.\n\nअगर आप सवाल पूछना चाहते हैं, तो अपने संगठन के व्यवस्थापक से संपर्क करें."</string>
     <string name="me" msgid="6545696007631404292">"मैं"</string>
-    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"टेबलेट विकल्‍प"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"टैबलेट विकल्‍प"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"टीवी के विकल्‍प"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"फ़ोन विकल्‍प"</string>
     <string name="silent_mode" msgid="7167703389802618663">"साइलेंट मोड (खामोश)"</string>
@@ -200,16 +200,16 @@
     <string name="screen_lock" msgid="799094655496098153">"स्‍क्रीन लॉक"</string>
     <string name="power_off" msgid="4266614107412865048">"पावर बंद"</string>
     <string name="silent_mode_silent" msgid="319298163018473078">"रिंगर बंद"</string>
-    <string name="silent_mode_vibrate" msgid="7072043388581551395">"रिंगर कंपन"</string>
+    <string name="silent_mode_vibrate" msgid="7072043388581551395">"रिंगर कंपन (वाइब्रेशन)"</string>
     <string name="silent_mode_ring" msgid="8592241816194074353">"रिंगर चालू"</string>
-    <string name="reboot_to_update_title" msgid="6212636802536823850">"Android सिस्टम से संबद्ध नई जानकारी"</string>
+    <string name="reboot_to_update_title" msgid="6212636802536823850">"Android सिस्टम उपडेट हो रहा है"</string>
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"अपडेट करने के लिए तैयार हो रहा है…"</string>
     <string name="reboot_to_update_package" msgid="3871302324500927291">"अपडेट पैकेज को संसाधित कर रहा है…"</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"पुन: प्रारंभ हो रहा है…"</string>
     <string name="reboot_to_reset_title" msgid="4142355915340627490">"फ़ैक्टरी डेटा रीसेट"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"पुन: प्रारंभ हो रहा है…"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"शट डाउन हो रहा है..."</string>
-    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"आपकी टेबलेट शट डाउन हो जाएगी."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"आपकी टैबलेट शट डाउन हो जाएगी."</string>
     <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"आपका टीवी बंद हो जाएगा."</string>
     <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"आपकी घड़ी बंद हो जाएगी."</string>
     <string name="shutdown_confirm" product="default" msgid="649792175242821353">"आपका फ़ोन शट डाउन हो जाएगा."</string>
@@ -218,22 +218,22 @@
     <string name="reboot_safemode_confirm" msgid="55293944502784668">"क्या आप सुरक्षित मोड में रीबूट करना चाहते हैं? इससे आपके इंस्टॉल किए हुए सभी तृतीय पक्ष ऐप्स  अक्षम हो जाएंगे. जब आप फिर से रीबूट करेंगे तो वे पुनर्स्थापित हो जाएंगे."</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"हाल के"</string>
     <string name="no_recent_tasks" msgid="8794906658732193473">"कोई हाल ही के ऐप्स  नहीं."</string>
-    <string name="global_actions" product="tablet" msgid="408477140088053665">"टेबलेट विकल्‍प"</string>
+    <string name="global_actions" product="tablet" msgid="408477140088053665">"टैबलेट विकल्‍प"</string>
     <string name="global_actions" product="tv" msgid="7240386462508182976">"टीवी के विकल्‍प"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"फ़ोन विकल्‍प"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"स्‍क्रीन लॉक"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"पावर बंद"</string>
     <string name="global_action_emergency" msgid="7112311161137421166">"आपातकाल"</string>
-    <string name="global_action_bug_report" msgid="7934010578922304799">"बग रिपोर्ट"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"बग रिपोर्ट प्राप्त करें"</string>
-    <string name="bugreport_message" msgid="398447048750350456">"ईमेल संदेश के रूप में भेजने के लिए, इसके द्वारा आपके डिवाइस की वर्तमान स्थिति के बारे में जानकारी एकत्र की जाएगी. बग रिपोर्ट प्रारंभ करने से लेकर भेजने के लिए तैयार होने तक कुछ समय लगेगा; कृपया धैर्य रखें."</string>
+    <string name="global_action_bug_report" msgid="7934010578922304799">"गड़बड़ी की रिपोर्ट"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"गड़बड़ी की रिपोर्ट लें"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"इससे ईमेल भेजने के लिए, आपके डिवाइस की मौजूदा स्थिति से जुड़ी जानकारी इकट्ठा की जाएगी. गड़बड़ी की रिपोर्ट बनना शुरू होने से लेकर भेजने के लिए तैयार होने तक कुछ समय लगेगा; कृपया इंतज़ार करें."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"सहभागी रिपोर्ट"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"अधिकांश परिस्थितियों में इसका उपयोग करें. यह आपको रिपोर्ट की प्रगति ट्रैक करने देता है, समस्या के बारे में अधिक विवरण डालने देता है और स्क्रीनशॉट लेने देता है. यह आपको ऐसे कम उपयोग किए गए अनुभाग मिटाने दे सकता है जिनकी रिपोर्ट करने में अधिक समय लगता है."</string>
     <string name="bugreport_option_full_title" msgid="6354382025840076439">"पूर्ण रिपोर्ट"</string>
     <string name="bugreport_option_full_summary" msgid="7210859858969115745">"जब आपका डिवाइस ठीक से काम नहीं कर रहा हो या बहुत धीमा हो या जब आपको रिपोर्ट के सभी भागों की ज़रूरत हो, तो सिस्टम से कम से कम रोक-टोक के लिए इस विकल्प का इस्तेमाल करें. यह आपको ज़्यादा जानकारी डालने या अतिरिक्त स्क्रीनशॉट लेने नहीं देता."</string>
     <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
-      <item quantity="one">बग रिपोर्ट के लिए <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में स्‍क्रीनशॉट लिया जा रहा है.</item>
-      <item quantity="other">बग रिपोर्ट के लिए <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में स्‍क्रीनशॉट लिया जा रहा है.</item>
+      <item quantity="one">गड़बड़ी की रिपोर्ट के लिए <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में स्‍क्रीनशॉट लिया जा रहा है.</item>
+      <item quantity="other">गड़बड़ी की रिपोर्ट के लिए <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में स्‍क्रीनशॉट लिया जा रहा है.</item>
     </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"साइलेंट मोड (खामोश)"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ध्‍वनि बंद है"</string>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"आवाज़ से डिवाइस का इस्तेमाल"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"अभी लॉक करें"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"छिपी हुई सामग्री"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"सामग्री पॉलिसी के द्वारा छिपी हुई है"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"नई सूचना"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"वर्चुअल कीबोर्ड"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"भौतिक कीबोर्ड"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"सुरक्षा"</string>
@@ -263,10 +262,10 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"सूचनाएं"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"खुदरा डेमो"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB कनेक्शन"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"बैकग्राउंड में चल रहे ऐप्लिकेशन"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> बैकग्राउंड में चल रहा है"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ऐप्लिकेशन बैकग्राउंड में चल रहे हैं"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"बैटरी और डेटा खर्च की जानकारी के लिए टैप करें"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"बैटरी की खपत करने वाले ऐप"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> बैटरी का इस्तेमाल कर रहा है"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ऐप बैटरी का इस्तेमाल कर रहे हैं"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"बैटरी और डेटा खर्च की जानकारी के लिए छूएं"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android सिस्‍टम"</string>
@@ -274,12 +273,12 @@
     <string name="managed_profile_label" msgid="5289992269827577857">"कार्य प्रोफ़ाइल में स्विच करें"</string>
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"संपर्क"</string>
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"अपने संपर्कों को ऐक्सेस करने की"</string>
-    <string name="permgrouplab_location" msgid="7275582855722310164">"स्थान"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"इस डिवाइस के स्थान को ऐक्सेस करने"</string>
+    <string name="permgrouplab_location" msgid="7275582855722310164">"जगह"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"इस डिवाइस की जगह तक पहुंचने दें"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"कैलेंडर"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"अपने कैलेंडर को ऐक्सेस करने"</string>
-    <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
-    <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS संदेश भेजें और देखने की"</string>
+    <string name="permgrouplab_sms" msgid="228308803364967808">"मैसेज (एसएमएस)"</string>
+    <string name="permgroupdesc_sms" msgid="4656988620100940350">"मैसेज (एसएमएस) भेजें और देखें"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"मेमोरी"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"अपने डिवाइस पर मौजूद फ़ोटो, मीडिया और फ़ाइलें ऐक्सेस करने की"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"माइक्रोफ़ोन"</string>
@@ -296,49 +295,49 @@
     <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"टैप किए गए आइटम ज़ोर से बोले जाएंगे और स्क्रीन को जेस्चर के ज़रिए एक्सप्लोर किया जा सकता है."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"आपके द्वारा लिखे हुए लेख को ध्यान से देखें"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"क्रेडिट कार्ड नंबर और पासवर्ड जैसा व्यक्तिगत डेटा शामिल होता है."</string>
-    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"प्रदर्शन आवर्धन नियंत्रित करें"</string>
-    <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"प्रदर्शन का ज़ूम स्‍तर और स्‍थिति निर्धारण नियंत्रित करें."</string>
+    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"डिसप्ले को बड़ा-छोटा करने की सुविधा को नियंत्रित करें"</string>
+    <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"डिसप्ले के ज़ूम का स्‍तर और पोज़िशनिंग नियंत्रित करें."</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"जेस्चर करें"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"इस सेवा के ज़रिए टैप, स्वाइप, पिंच और बाकी जेस्चर किए जा सकते हैं."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"फ़िंगरप्रिंट जेस्चर"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"डिवाइस फ़िंगरप्रिंट सेंसर पर किए गए जेस्चर कैप्चर किए जा सकते हैं."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"स्टेटस बार को अक्षम करें या बदलें"</string>
-    <string name="permdesc_statusBar" msgid="8434669549504290975">"ऐप को, स्टेटस बार को अक्षम करने या सिस्‍टम आइकन को जोड़ने या निकालने की अनुमति देता है."</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"ऐप को, स्टेटस बार को बंद करने या सिस्‍टम आइकॉन को जोड़ने और निकालने की अनुमति देता है."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"स्टेटस बार को रहने दें"</string>
     <string name="permdesc_statusBarService" msgid="716113660795976060">"ऐप को स्टेटस बार बने रहने की अनुमति देता है."</string>
     <string name="permlab_expandStatusBar" msgid="1148198785937489264">"स्टेटस बार खोलकर बड़ा करें/छोटा करें"</string>
     <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"ऐप को, स्टेटस बार खोलकर बड़ा करने या उसे छोटा करने की अनुमति देता है."</string>
     <string name="permlab_install_shortcut" msgid="4279070216371564234">"शॉर्टकट इंस्‍टॉल करें"</string>
-    <string name="permdesc_install_shortcut" msgid="8341295916286736996">"एप्‍लिकेशन को उपयोगकर्ता के हस्‍तक्षेप के बिना होमस्‍क्रीन शॉर्टकट जोड़ने की अनुमति देता है."</string>
+    <string name="permdesc_install_shortcut" msgid="8341295916286736996">"एप्‍लिकेशन को उपयोगकर्ता की रोक के बिना होमस्‍क्रीन शॉर्टकट जोड़ने की अनुमति देता है."</string>
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"शॉर्टकट अनइंस्टॉल करें"</string>
-    <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"एप्‍लिकेशन को उपयोगकर्ता के हस्‍तक्षेप के बिना होमस्‍क्रीन शॉर्टकट निकालने की अनुमति देता है."</string>
+    <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"एप्‍लिकेशन को उपयोगकर्ता की रोक के बिना होमस्‍क्रीन शॉर्टकट निकालने की अनुमति देता है."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"किया जाने वाला कॉल (आउटगोइंग) कहीं और भेजें"</string>
     <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"एेप कॉल को किसी और नंबर पर भेजने या कॉल को पूरी तरह रद्द करने के विकल्प के साथ, किए गए कॉल (आउटगोइंग) के नंबर को देख सकता है."</string>
     <string name="permlab_answerPhoneCalls" msgid="4077162841226223337">"फ़ोन कॉल का जवाब दें"</string>
     <string name="permdesc_answerPhoneCalls" msgid="2901889867993572266">"ऐप्लिकेशन को किसी इनकमिंग फ़ोन कॉल का जवाब देने देती है."</string>
-    <string name="permlab_receiveSms" msgid="8673471768947895082">"लेख संदेश (SMS) प्राप्त करें"</string>
-    <string name="permdesc_receiveSms" msgid="6424387754228766939">"ऐप्स  को SMS संदेशों को प्राप्‍त और संसाधित करने देता है. इसका अर्थ है कि ऐप्स  आपके डिवाइस पर भेजे गए संदेशों की निगरानी आपको दिखाए बिना कर सकता है और उन्‍हें हटा सकता है."</string>
-    <string name="permlab_receiveMms" msgid="1821317344668257098">"लेख संदेश (MMS) प्राप्त करें"</string>
-    <string name="permdesc_receiveMms" msgid="533019437263212260">"ऐप्स  को MMS संदेशों को प्राप्‍त और संसाधित करने देता है. इसका अर्थ है कि ऐप्स  आपके डिवाइस पर भेजे गए संदेशों की निगरानी आपको दिखाए बिना कर सकता है और उन्‍हें हटा सकता है."</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"मैसेज (एसएमएस) पाएं"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"ऐप को मैसेज (एसएमएस) को प्राप्‍त और संसाधित करने देता है. इसका अर्थ है कि ऐप आपके डिवाइस पर भेजे गए संदेशों की निगरानी आपको दिखाए बिना कर सकता है और उन्‍हें हटा सकता है."</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"मैसेज (एमएमएस) पाएं"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"ऐप को मल्टीमीडिया मैसेज (एमएमएस) को पाने और उन पर कार्रवाई करने देता है. इसका मतलब है कि ऐप आपके डिवाइस पर भेजे गए मैसेज की निगरानी आपको दिखाए बिना कर सकता है और उन्‍हें हटा सकता है."</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"सेल ब्रॉडकास्ट (CBC) मैसेज पढ़ें"</string>
     <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ऐप को, वो सेल ब्रॉडकास्ट (CBC) मैसेज पढ़ने देता है जो आपके डिवाइस को मिले हैं. सेल ब्रॉडकास्ट (CBC) अलर्ट कुछ स्थानों (लोकेशन) पर आपको आपातकालीन स्‍थितियों की चेतावनी देने के लिए दिए जाते हैं. आपातकालीन सेल ब्रॉडकास्ट (CBC) मिलने पर, धोखा देने वाले ऐप आपके डिवाइस के परफ़ॉर्मेंस या कार्यवाही में दखल दे सकते हैं."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"सदस्यता-प्राप्त फ़ीड पढ़ें"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ऐप्स को वर्तमान में समन्वयित फ़ीड के बारे में विवरण प्राप्त करने देता है."</string>
-    <string name="permlab_sendSms" msgid="7544599214260982981">"SMS संदेश भेजें और देखें"</string>
-    <string name="permdesc_sendSms" msgid="7094729298204937667">"ऐप्स  को SMS संदेशों को भेजने देता है. इसके परिणामस्वरूप अप्रत्‍याशित शुल्‍क लागू हो सकते हैं. दुर्भावनापूर्ण ऐप्स  आपकी पुष्टि के बिना संदेश भेजकर आपका धन व्‍यय कर सकते हैं."</string>
-    <string name="permlab_readSms" msgid="8745086572213270480">"अपने लेख संदेश (SMS या MMS) पढ़ें"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"यह ऐप्लिकेशन आपके टैबलेट पर संग्रहित सभी SMS (लेख) संदेश पढ़ सकता है."</string>
-    <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"यह ऐप्लिकेशन आपके टीवी पर संग्रहित सभी SMS (लेख) संदेश पढ़ सकता है."</string>
-    <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"यह ऐप्लिकेशन आपके फ़ोन पर संग्रहित सभी SMS (लेख) संदेश पढ़ सकता है."</string>
+    <string name="permlab_sendSms" msgid="7544599214260982981">"मैसेज (एमएमएस) भेजें और देखें"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"ऐप को मैसेज (एसएमएस) भेजने देता है. इसकी वजह से उम्मीद से ज़्यादा शुल्‍क लग सकते हैं. धोखा देने वाले ऐप आपकी पुष्टि के बिना मैसेज भेजकर आपका पैसा खर्च करवा सकते हैं."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"अपने मैसेज (एसएमएस या एमएमएस) पढ़ें"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"यह ऐप आपके टैबलेट पर सहेजे गए सभी मैसेज (एसएमएस) पढ़ सकता है."</string>
+    <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"यह ऐप आपके टीवी पर सहेजे गए सभी मैसेज (एसएमएस) पढ़ सकता है."</string>
+    <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"यह ऐप आपके फ़ोन पर सहेजे गए सभी मैसेज (एसएमएस) पढ़ सकता है."</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"लेख संदेश (WAP) प्राप्त करें"</string>
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"ऐप्स  को WAP संदेशों को प्राप्‍त और संसाधित करने देता है. इस अनुमति में आपको भेजे गए संदेशों की निगरानी आपको दिखाए बिना करने और हटाने की क्षमता शामिल है."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"चल रहे ऐप्स पुनर्प्राप्त करें"</string>
-    <string name="permdesc_getTasks" msgid="7454215995847658102">"ऐप्स  को वर्तमान में और हाल ही में चल रहे कार्यों के बारे में जानकारी को पुन: प्राप्‍त करने देता है. इससे ऐप्स  डिवाइस पर उपयोग किए गए ऐप्स  के बारे में जानकारी खोज सकता है."</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"ऐप को माजूदा समय में और हाल ही में चल रही कार्रवाइयों के बारे में जानकारी निकालने देता है. इससे ऐप डिवाइस पर इस्तेमाल किए गए ऐप के बारे में जानकारी खोज सकता है."</string>
     <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"प्रोफ़ाइल और डिवाइस स्‍वामियों को प्रबंधित करें"</string>
     <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"ऐप्‍स को प्रोफ़ाइल स्‍वामी और डिवाइस स्‍वामी सेट करने दें."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"चल रहे ऐप्स पुन: क्रमित करें"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"ऐप्स  को कार्यों को अग्रभूमि और पृष्‍ठभूमि पर ले जाने देता है. ऐप्स  आपके इनपुट के बिना यह कर सकता है."</string>
-    <string name="permlab_enableCarMode" msgid="5684504058192921098">"कार मोड सक्षम करें"</string>
+    <string name="permlab_enableCarMode" msgid="5684504058192921098">"कार मोड चालू करें"</string>
     <string name="permdesc_enableCarMode" msgid="4853187425751419467">"ऐप्स  को कार मोड सक्षम करने देता है."</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"अन्‍य ऐप्स बंद करें"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"ऐप्स  को अन्‍य ऐप्स की पृष्ठभूमि प्रक्रियाओं को समाप्त करने देता है. यह अन्य ऐप्स  का चलना रोक सकता है."</string>
@@ -349,27 +348,27 @@
     <string name="permlab_useDataInBackground" msgid="8694951340794341809">"बैकग्राउंड में डेटा का उपयोग करता है"</string>
     <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"यह ऐप बैकग्राउंड में डेटा का उपयोग कर सकता है. इससे डेटा का उपयोग बढ़ सकता है."</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"ऐप्स को हमेशा चलने वाला बनाएं"</string>
-    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"ऐप्स को मेमोरी में स्‍वयं के कुछ हिस्सों को लगातार बनाने की अनुमति देता है. यह अन्‍य ऐप्स  के लिए उपलब्‍ध स्‍मृति को सीमित कर टेबलेट को धीमा कर सकता है."</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"ऐप्स को मेमोरी में स्‍वयं के कुछ हिस्सों को लगातार बनाने की अनुमति देता है. यह अन्‍य ऐप्स  के लिए उपलब्‍ध स्‍मृति को सीमित कर टैबलेट को धीमा कर सकता है."</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"ऐप को मेमोरी में स्‍वयं के दीर्घस्थायी भाग बनाने देती है. इससे अन्‍य ऐप्‍स के लिए उपलब्‍ध मेमोरी सीमित हो सकती है जिससे टीवी धीमा हो सकता है."</string>
     <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ऐप्स को मेमोरी में स्‍वयं के कुछ हिस्सों को लगातार बनाने देता है. यह अन्‍य ऐप्स  के लिए उपलब्‍ध स्‍मृति को सीमित कर फ़ोन को धीमा कर सकता है."</string>
-    <string name="permlab_getPackageSize" msgid="7472921768357981986">"ऐप्स  मेमोरी स्थान मापें"</string>
-    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"ऐप्स  को उसका कोड, डेटा, और संचय आकारों को प्राप्त करने देता है"</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"पता करें कि ऐप मेमोरी में कितनी जगह है"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"ऐप को उसका कोड, डेटा, और कैश मेमोरी के आकारों को फिर से पाने देता है"</string>
     <string name="permlab_writeSettings" msgid="2226195290955224730">"सिस्‍टम सेटिंग बदलें"</string>
     <string name="permdesc_writeSettings" msgid="7775723441558907181">"ऐप्स  को सिस्टम सेटिंग डेटा संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स  आपके सिस्टम के कॉन्फ़िगरेशन को दूषित कर सकते हैं."</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"प्रारंभ होने पर चलाएं"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"ऐप्स  को सिस्टम द्वारा बूटिंग पूर्ण करते ही स्वतः आरंभ करने देता है. इससे टेबलेट को आरंभ होने में अधिक समय लग सकता है और ऐप्स  को निरंतर चलाकर संपूर्ण टेबलेट को धीमा करने देता है."</string>
-    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"ऐप्‍स को सिस्‍टम का बूट होना पूर्ण होते ही स्‍वत: प्रारंभ होने देती है. इससे टीवी को प्रारंभ होने में अधिक समय लग सकता है और ऐप के हमेशा चलने से संपूर्ण टैबलेट धीमा हो सकता है."</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"ऐप्स  को सिस्टम द्वारा बूटिंग पूर्ण करते ही स्वतः प्रारंभ होने देता है. इससे फ़ोन को प्रारंभ होने में अधिक समय लग सकता है और ऐप्स  के निरंतर चलते रहने से संपूर्ण फ़ोन प्रक्रियाएं धीमी हो सकती हैं."</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"ऐप्स  को सिस्टम द्वारा बूटिंग पूर्ण करते ही स्वतः आरंभ करने देता है. इससे टैबलेट को आरंभ होने में अधिक समय लग सकता है और ऐप्स  को निरंतर चलाकर संपूर्ण टैबलेट को धीमा करने देता है."</string>
+    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"सिस्‍टम के चालू होते ही ऐप को अपने आप शुरू होने देती है. इससे टीवी को चालू होने में ज़्यादा समय लग सकता है और ऐप के लगातार चलते रहने से पूरा टैबलेट धीमा हो सकता है."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"सिस्‍टम के चालू होते ही ऐप को अपने आप शुरू होने देती है. इससे फ़ोन को चालू होने में ज़्यादा समय लग सकता है और ऐप के लगातार चलते रहने से पूरा फ़ोन धीमा हो सकता है."</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"स्टिकी प्रसारण भेजें"</string>
-    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"ऐप्स को स्‍टिकी प्रसारण भेजने देता है, जो प्रसारण समाप्त होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, टेबलेट की बहुत अधिक मेमोरी का उपयोग करके उसे धीमा या अस्‍थिर कर सकता है."</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"ऐप्स को स्‍टिकी प्रसारण भेजने देता है, जो प्रसारण समाप्त होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, टैबलेट की बहुत अधिक मेमोरी का उपयोग करके उसे धीमा या अस्‍थिर कर सकता है."</string>
     <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"ऐप को स्‍िटकी प्रसारण भेजने देती है, जो प्रसारण बंद होने के बाद भी बने रहते हैं. अत्‍यधिक उपयोग से टीवी धीमा या अस्‍थिर हो सकता है जिससे वह बहुत सारी मेमोरी का उपयोग कर सकता है."</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"ऐप्स को स्‍टिकी प्रसारण भेजने देता है, जो प्रसारण समाप्त होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, फ़ोन की बहुत अधिक मेमोरी का उपयोग करके उसे धीमा या अस्‍थिर कर सकता है."</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"अपने संपर्क पढ़ें"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"ऐप्स  को आपके टेबलेट में संग्रहित संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से डॉयलॉग करने की आवृत्ति को पढ़ने देता है. यह अनुमति ऐप्स  को आपके संपर्क डेटा को सहेजने देती है, और दुर्भावनापूर्ण ऐप्स  आपकी जानकारी के बिना संपर्क डेटा को साझा कर सकते हैं."</string>
-    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"ऐप को आपके टीवी पर संग्रहित आपके संपर्कों का डेटा पढ़ने देती है, जिसमें आपके द्वारा विशिष्‍ट व्‍यक्‍तियों को कॉल करने, ईमेल भेजने या उनसे संचार करने की आवृत्‍ति भी शामिल होती है. यह अनुमति ऐप्‍स को आपका संपर्क डेटा सहेजने देती है और दुर्भावनापूर्ण ऐप्‍स संपर्क डेटा को आपकी जानकारी के बिना साझा कर सकते हैं."</string>
-    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"ऐप्स  को आपके फ़ोन में संग्रहित संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से डॉयलॉग करने की आवृत्ति को पढ़ने देता है. यह अनुमति ऐप्स  को आपके संपर्क डेटा को सहेजने देती है, और दुर्भावनापूर्ण ऐप्स  आपकी जानकारी के बिना संपर्क डेटा को साझा कर सकते हैं."</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"ऐप को आपके टैबलेट पर मौजूद आपके संपर्कों का डेटा पढ़ने देती है, जिसमें ये भी शामिल है कि आपने कुछ ख़ास लोगों से कितनी बार कॉल, ईमेल, या कुछ और तरीकों से बातचीत की. यह अनुमति ऐप को आपका संपर्क डेटा सेव करने देती है और धोखा देने वाले ऐप संपर्क डेटा को आपकी जानकारी के बिना शेयर कर सकते हैं."</string>
+    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"ऐप को आपके टीवी पर मौजूद आपके संपर्कों का डेटा पढ़ने देती है, जिसमें ये भी शामिल है कि आपने कुछ ख़ास लोगों से कितनी बार कॉल, ईमेल, या कुछ और तरीकों से बातचीत की. यह अनुमति ऐप को आपका संपर्क डेटा सेव करने देती है और धोखा देने वाले ऐप संपर्क डेटा को आपकी जानकारी के बिना शेयर कर सकते हैं."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"ऐप को आपके फ़ोन पर मौजूद आपके संपर्कों का डेटा पढ़ने देती है, जिसमें ये भी शामिल है कि आपने कुछ ख़ास लोगों से कितनी बार कॉल, ईमेल, या कुछ और तरीकों से बातचीत की. यह अनुमति ऐप को आपका संपर्क डेटा सेव करने देती है और धोखा देने वाले ऐप, संपर्क डेटा को आपकी जानकारी के बिना शेयर कर सकते हैं."</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"अपने संपर्क बदलें"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"ऐप्स  को आपके टेबलेट में संग्रहित संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से डॉयलॉग करने की आवृत्ति को संशोधित करने देता है. यह अनुमति ऐप्स  को आपके संपर्क डेटा को हटाने देती है."</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"ऐप्स  को आपके टैबलेट में संग्रहित संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से डॉयलॉग करने की आवृत्ति को संशोधित करने देता है. यह अनुमति ऐप्स  को आपके संपर्क डेटा को हटाने देती है."</string>
     <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"ऐप को आपके टीवी पर संग्रहित आपके संपर्कों के बारे में संग्रहित डेटा में बदलाव करने देती है, जिसमें आपके द्वारा विशिष्‍ट व्‍यक्‍तियों को कॉल करने, ईमेल भेजने या अन्‍य तरीकों से संचार किए जाने की आवृत्‍ति भी शामिल है. यह अनुमति ऐप्‍स को संपर्क डेटा हटाने देती है."</string>
     <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"ऐप्स  को आपके फ़ोन में संग्रहित संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से डॉयलॉग करने की आवृत्ति को संशोधित करने देता है. यह अनुमति ऐप्स  को आपके संपर्क डेटा को हटाने देती है."</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"कॉल लॉग पढ़ें"</string>
@@ -378,33 +377,33 @@
     <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"एेप को आने वाला कॉल (इनकमिंग) और किया जाने वाला कॉल (आउटगोइंग) डेटा सहित, आपके टैबलेट के कॉल लॉग को बदलने की अनुमति देता है. धोखा देने वाले एेप, इसका इस्तेमाल करके आपके कॉल लॉग को मिटा या बदल सकते हैं."</string>
     <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"एेप को आने वाला कॉल (इनकमिंग) और किया जाने वाला कॉल (आउटगोइंग) डेटा सहित, आपके टीवी के कॉल लॉग को बदलने की अनुमति देता है. धोखा देने वाले एेप, इसका इस्तेमाल करके आपके कॉल लॉग को मिटा या बदल सकते हैं."</string>
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"एेप को आने वाला कॉल (इनकमिंग) और किया जाने वाला कॉल (आउटगोइंग) डेटा सहित, आपके फ़ोन के कॉल लॉग को बदलने की अनुमति देता है. धोखा देने वाले एेप, इसका इस्तेमाल करके आपके कॉल लॉग को मिटा या बदल सकते हैं."</string>
-    <string name="permlab_bodySensors" msgid="4683341291818520277">"शरीर संवेदक एक्सेस करें (जैसे हृदय गति मॉनीटर)"</string>
-    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ऐप को आपकी शारीरिक स्‍थिति, जैसे आपकी हृदय गति पर नज़र रखने वाले संवेदकों का डेटा एक्‍सेस करने देती है."</string>
+    <string name="permlab_bodySensors" msgid="4683341291818520277">"शरीर के लिए बने सेंसर (जैसे हृदय गति मॉनीटर) को एक्सेस करें"</string>
+    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ऐप को आपकी शारीरिक स्‍थिति, जैसे आपकी हृदय गति पर नज़र रखने वाले सेंसर के डेटा तक पहुंचने देती है."</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"कैलेंडर इवेंट और विवरण पढ़ें"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"यह ऐप्लिकेशन आपके टैबलेट पर संग्रहित सभी कैलेंडर इवेंट पढ़ सकता है और आपका कैलेंडर डेटा साझा कर सकता है या सहेज सकता है."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"यह ऐप्लिकेशन आपके टीवी पर संग्रहित सभी कैलेंडर इवेंट पढ़ सकता है और आपका कैलेंडर डेटा साझा कर सकता है या सहेज सकता है."</string>
     <string name="permdesc_readCalendar" product="default" msgid="4373978642145196715">"यह ऐप्लिकेशन आपके फ़ोन पर संग्रहित सभी कैलेंडर इवेंट पढ़ सकता है और आपका कैलेंडर डेटा साझा कर सकता है या सहेज सकता है."</string>
-    <string name="permlab_writeCalendar" msgid="8438874755193825647">"अपनी जानकारी के बि‍ना कैलेंडर इवेंट जोड़ें या संशोधि‍त करें और अति‍थि‍यों को ईमेल भेजें"</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"आपकी जानकारी के बि‍ना कैलेंडर इवेंट जोड़ें या उनमें बदलाव करें और अति‍थि‍यों को ईमेल भेजें"</string>
     <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"यह ऐप्लिकेशन आपके टैबलेट पर मौजूद कैलेंडर इवेंट जोड़, निकाल या बदल सकता है. यह ऐप्लिकेशन ऐसे संदेश भेज सकता है जो कैलेंडर स्वामियों से आए हुए लग सकते हैं या यह स्वामियों को सूचित किए बिना इवेंट में बदलाव कर सकता है."</string>
     <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"यह ऐप्लिकेशन आपके टीवी पर मौजूद कैलेंडर इवेंट जोड़, निकाल या बदल सकता है. यह ऐप्लिकेशन ऐसे संदेश भेज सकता है जो कैलेंडर स्वामियों से आए हुए लग सकते हैं या यह स्वामियों को सूचित किए बिना इवेंट में बदलाव कर सकता है."</string>
     <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"यह ऐप्लिकेशन आपके फ़ोन पर मौजूद कैलेंडर इवेंट जोड़, निकाल या बदल सकता है. यह ऐप्लिकेशन ऐसे संदेश भेज सकता है जो कैलेंडर स्वामियों से आए हुए लग सकते हैं या यह स्वामियों को सूचित किए बिना इवेंट में बदलाव कर सकता है."</string>
-    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"कुछ और जगह बताने वाले आदेशों का एक्सेस"</string>
-    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ऐप को कुछ और जगह बताने वाले आदेशों का एक्सेस देता है. इससे ऐप GPS या और स्‍थान स्रोतों के काम में रोक-टोक कर सकता है."</string>
-    <string name="permlab_accessFineLocation" msgid="251034415460950944">"सटीक स्थान एक्सेस करें (GPS और नेटवर्क-आधारित)"</string>
-    <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"यह ऐप्लिकेशन सेल टॉवर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क स्रोतों या GPS के आधार पर आपका स्थान पता कर सकता है. ये स्थान सेवाएं आपके फ़ोन पर चालू और उपलब्ध होनी चाहिए ताकि ऐप्लिकेशन उनका उपयोग कर सके. इससे बैटरी की खपत बढ़ सकती है."</string>
-    <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"अनुमानित स्थान एक्सेस करें (नेटवर्क-आधारित)"</string>
-    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"यह ऐप्लिकेशन सेल टॉवर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क स्रोतों के आधार पर आपका स्थान पता कर सकता है. ये स्थान सेवाएं आपके टैबलेट पर चालू और उपलब्ध होनी चाहिए ताकि ऐप्लिकेशन उनका उपयोग कर सके."</string>
-    <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"यह ऐप्लिकेशन सेल टॉवर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क स्रोतों के आधार पर आपका स्थान पता कर सकता है. ये स्थान सेवाएं आपके टीवी पर चालू और उपलब्ध होनी चाहिए ताकि ऐप्लिकेशन उनका उपयोग कर सके."</string>
-    <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"यह ऐप्लिकेशन सेल टॉवर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क स्रोतों के आधार पर आपका स्थान पता कर सकता है. ये स्थान सेवाएं आपके फ़ोन पर चालू और उपलब्ध होनी चाहिए ताकि ऐप्लिकेशन उनका उपयोग कर सके."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"कुछ और जगह बताने वाले आदेशों तक पहुंच"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ऐप को कुछ और जगह की जानकारी देने वाले आदेशों की पहुंच पाने देता है. इससे ऐप जीपीएस या जगह की जानकारी देने वाले दूसरे स्रोतों के काम में रोक-टोक कर सकता है."</string>
+    <string name="permlab_accessFineLocation" msgid="251034415460950944">"सटीक जगह की जानकारी लेने दें (जीपीएस और नेटवर्क-आधारित)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"यह ऐप सेल टावर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क स्रोतों या जीपीएस के आधार पर आपकी जगह पता कर सकता है. जगह की जानकारी आपके फ़ोन पर चालू और मौजूद होनी चाहिए ताकि ऐप उनका इस्तेमाल कर सके. इससे ज़्यादा बैटरी खर्च हो सकती है."</string>
+    <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"अनुमानित जगह की पहुंच दें (नेटवर्क-आधारित)"</string>
+    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"यह ऐप सेल टावर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क के स्रोतों के आधार पर आपकी जगह का पता कर सकता है. ये जगह की जानकारी आपके टैबलेट पर चालू और मौजूद होनी चाहिए ताकि ऐप उनका इस्तेमाल कर सके."</string>
+    <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"यह ऐप सेल टावर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क के स्रोतों के आधार पर आपकी जगह का पता कर सकता है. ये जगह की जानकारी आपके टीवी पर चालू और मौजूद होनी चाहिए ताकि ऐप उनका इस्तेमाल कर सके."</string>
+    <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"यह ऐप सेल टावर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क के स्रोतों के आधार पर आपकी जगह का पता कर सकता है. ये जगह की जानकारी आपके फ़ोन पर चालू और मौजूद होनी चाहिए ताकि ऐप उनका इस्तेमाल कर सके."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"अपनी ऑडियो सेटिंग बदलें"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"ऐप्स  को वैश्विक ऑडियो सेटिंग, जैसे वॉल्‍यूम और कौन-सा स्पीकर आउटपुट के लिए उपयोग किया गया, संशोधित करने देता है."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ऑडियो रिकॉर्ड करने"</string>
     <string name="permdesc_recordAudio" msgid="4245930455135321433">"यह ऐप्लिकेशन किसी भी समय माइक्रोफ़ोन का उपयोग करके ऑडियो रिकॉर्ड कर सकता है."</string>
-    <string name="permlab_sim_communication" msgid="2935852302216852065">"SIM पर आदेश भेजें"</string>
-    <string name="permdesc_sim_communication" msgid="5725159654279639498">"ऐप्स को सिम में आदेश भेजने देती है. यह बहुत ही खतरनाक है."</string>
+    <string name="permlab_sim_communication" msgid="2935852302216852065">"सिम पर निर्देश भेजें"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"ऐप को सिम पर निर्देश भेजने देती है. यह बहुत ही खतरनाक है."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"चित्र और वीडियो लें"</string>
     <string name="permdesc_camera" msgid="5392231870049240670">"यह ऐप्लिकेशन किसी भी समय कैमरे का उपयोग करके चित्र ले सकता है और वीडियो रिकॉर्ड कर सकता है."</string>
-    <string name="permlab_vibrate" msgid="7696427026057705834">"कंपन नियंत्रित करें"</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"कंपन (वाइब्रेशन) को नियंत्रित करें"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"ऐप्स को कंपनकर्ता नियंत्रित करने देता है."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"फ़ोन नंबर पर सीधे कॉल करें"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"ऐप्स  को आपके हस्‍तक्षेप के बिना फ़ोन नंबर पर कॉल करने देता है. इसके परिणाम अप्रत्‍याशित शुल्‍क या कॉल हो सकते हैं. ध्यान दें कि यह ऐप्स  को आपातकालीन नंबर पर कॉल नहीं करने देता. दुर्भावनापूर्ण ऐप्स  आपकी पुष्टि के बिना कॉल करके आपका धन व्‍यय कर सकते हैं."</string>
@@ -415,15 +414,15 @@
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"सिस्टम के माध्यम से कॉल रूट करें"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"कॉल करने के अनुभव को बेहतर बनाने के लिए ऐप्लिकेशन को सिस्टम के माध्यम से उसके कॉल रूट करने देती है."</string>
     <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"फ़ोन नंबर पढ़ना"</string>
-    <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"ऐप्लिकेशन को डिवाइस के फ़ोन नंबर एक्सेस करने देती है."</string>
-    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"टेबलेट को सोने (कम बैटरी मोड) से रोकें"</string>
+    <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"ऐप को डिवाइस के फ़ोन नंबर का इस्तेमाल करने देती है."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"टैबलेट को सोने (कम बैटरी मोड) से रोकें"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"टीवी को सोने (कम बैटरी मोड) से रोकें"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"टीवी को सोने (कम बैटरी मोड) से रोकें"</string>
-    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ऐप्स  को टेबलेट को प्रयोग में नहीं हो जाने से रोकता है."</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ऐप्स  को टैबलेट को प्रयोग में नहीं हो जाने से रोकता है."</string>
     <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"ऐप को टीवी को सोने (कम बैटरी मोड) से रोकने की अनुमति देता है."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"ऐप्स  को फ़ोन को प्रयोग में नहीं होने से रोकता है."</string>
     <string name="permlab_transmitIr" msgid="7545858504238530105">"इंफ़्रारेड संचारित करें"</string>
-    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"ऐप्लिकेशन को टेबलेट के इंफ़्रारेड ट्रांसमीटर का उपयोग करने देती है."</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"ऐप्लिकेशन को टैबलेट के इंफ़्रारेड ट्रांसमीटर का उपयोग करने देती है."</string>
     <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"ऐप को टीवी के इंफ़्रारेड ट्रांसमीटर का उपयोग करने देती है."</string>
     <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"ऐप्लिकेशन को फ़ोन के इंफ़्रारेड ट्रांसमीटर का उपयोग करने देती है."</string>
     <string name="permlab_setWallpaper" msgid="6627192333373465143">"वॉलपेपर सेट करें"</string>
@@ -431,41 +430,41 @@
     <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"अपने वॉलपेपर का आकार एडजस्ट करें"</string>
     <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"ऐप्स को सिस्‍टम वॉलपेपर आकार संकेत सेट करने देता है."</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"समय क्षेत्र सेट करें"</string>
-    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"ऐप्स को टेबलेट का समय क्षेत्र बदलने देता है."</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"ऐप्स को टैबलेट का समय क्षेत्र बदलने देता है."</string>
     <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"ऐप को टीवी का समय क्षेत्र बदलने देती है."</string>
-    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"ऐप्स को टेबलेट का समय क्षेत्र बदलने देता है."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"ऐप्स को टैबलेट का समय क्षेत्र बदलने देता है."</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"डिवाइस पर खाते ढूंढें"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"ऐप्स  को टेबलेट द्वारा ज्ञात खातों की सूची प्राप्‍त करने देता है. इसमें वे खाते शामिल हो सकते हैं जिन्‍हें आपके द्वारा इंस्‍टॉल किए गए ऐप्स  ने बनाया है."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"ऐप्स  को टैबलेट द्वारा ज्ञात खातों की सूची प्राप्‍त करने देता है. इसमें वे खाते शामिल हो सकते हैं जिन्‍हें आपके द्वारा इंस्‍टॉल किए गए ऐप्स  ने बनाया है."</string>
     <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"ऐप को टीवी द्वारा ज्ञात खातों की सूची प्राप्‍त करने देती है. इसमें आपके द्वारा इंस्‍टॉल किए गए ऐप्‍लिकेशन के द्वारा बनाए गए खाते शामिल हो सकते हैं."</string>
     <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"ऐप्स  को फ़ोन द्वारा ज्ञात खातों की सूची प्राप्‍त करने देता है. इसमें वे खाते शामिल हो सकते हैं जिन्‍हें आपके द्वारा इंस्‍टॉल किए गए ऐप्स  ने बनाया है."</string>
     <string name="permlab_accessNetworkState" msgid="4951027964348974773">"नेटवर्क कनेक्‍शन देखें"</string>
-    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"ऐप्स  को नेटवर्क कनेक्‍शन के बारे में जानकारी देखने देता है जैसे कौन से नेटवर्क मौजूद हैं और कनेक्‍ट हैं."</string>
-    <string name="permlab_createNetworkSockets" msgid="7934516631384168107">"पूर्ण नेटवर्क एक्सेस पाएं"</string>
-    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"ऐप्स  को नेटवर्क सॉकेट बनाने और कस्‍टम नेटवर्क प्रोटोकॉल का उपयोग करने देता है. ब्राउज़र और अन्‍य ऐप्स  इंटरनेट को डेटा भेजने के साधन उपलब्‍ध कराते हैं, ताकि इंटरनेट को डेटा भेजने के लिए इस अनुमति की आवश्‍यकता नहीं हो."</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"ऐप को नेटवर्क कनेक्‍शन के बारे में जानकारी देखने देता है, जैसे कौन से नेटवर्क मौजूद हैं और कनेक्‍ट हैं."</string>
+    <string name="permlab_createNetworkSockets" msgid="7934516631384168107">"नेटवर्क को पूरी तरह इस्तेमाल करें"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"ऐप को नेटवर्क सॉकेट बनाने और मन मुताबिक नेटवर्क प्रोटोकॉल का इस्तेमाल करने देता है. ब्राउज़र और अन्‍य ऐप से इंटरनेट को डेटा भेजने के तरीके मिलते हैं, ताकि इंटरनेट को डेटा भेजने के लिए इस अनुमति की ज़रुरत न पड़े."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"नेटवर्क कनेक्‍टिविटी बदलें"</string>
     <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"ऐप्स  को नेटवर्क कनेक्टिविटी की स्थिति बदलने देता है."</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"टेदर की गई कनेक्‍टिविटी बदलें"</string>
     <string name="permdesc_changeTetherState" msgid="1524441344412319780">"ऐप्स को टेदर की गई नेटवर्क कनेक्‍टिविटी की स्‍थिति बदलने देता है."</string>
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"वाई-फ़ाई  कनेक्‍शन देखें"</string>
-    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"ऐप्स  को वाई-फ़ाई  नेटवर्क के बारे में जानकारी, जैसे WI-Fi सक्षम है या नहीं और कनेक्‍ट किए गए वाई-फ़ाई  डिवाइस के नाम, देखने देता है."</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"ऐप को वाई-फ़ाई नेटवर्क के बारे में जानकारी, जैसे WI-Fi चालू है या नहीं और कनेक्‍ट किए गए वाई-फ़ाई डिवाइस के नाम, देखने देता है."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"वाई-फ़ाई  से कनेक्‍ट और डिस्‍कनेक्‍ट करें"</string>
     <string name="permdesc_changeWifiState" msgid="7137950297386127533">"ऐप्स  को वाई-फ़ाई  पहुंच बिंदुओं से कनेक्ट और डिसकनेक्ट करने और वाई-फ़ाई  नेटवर्क के लिए डिवाइस कॉन्फ़िगरेशन में परिवर्तन करने देता है."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"वाई-फ़ाई  मल्‍टीकास्‍ट प्राप्ति को अनुमति दें"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"ऐप्स  को वाई-फ़ाई  नेटवर्क पर मल्टीकास्ट पते के उपयोग से केवल आपके टेबलेट पर ही नहीं, बल्कि सभी डिवाइस पर भेजे गए पैकेट प्राप्‍त करने देता है. यह गैर-मल्टीकास्ट मोड से अधिक पावर का उपयोग करता है."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"ऐप्स  को वाई-फ़ाई  नेटवर्क पर मल्टीकास्ट पते के उपयोग से केवल आपके टैबलेट पर ही नहीं, बल्कि सभी डिवाइस पर भेजे गए पैकेट प्राप्‍त करने देता है. यह गैर-मल्टीकास्ट मोड से अधिक पावर का उपयोग करता है."</string>
     <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"ऐप को मल्‍टीकास्‍ट पतों का उपयोग करके ना केवल आपके टीवी को, बल्‍कि वाई-फ़ाई पर मौजूद सभी डिवाइसों को पैकेट भेजने और प्राप्‍त करने देती है. इसमें गैर-मल्‍टीकास्‍ट मोड की अपेक्षा अधिक पावर का उपयोग होता है."</string>
     <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"ऐप्स  को वाई-फ़ाई  नेटवर्क पर मल्टीकास्ट पते के उपयोग से केवल आपके फ़ोन पर ही नहीं, बल्कि सभी डिवाइस पर भेजे गए पैकेट प्राप्‍त करने देता है. यह गैर-मल्टीकास्ट मोड से अधिक पावर का उपयोग करता है."</string>
     <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"ब्लूटूथ सेटिंग पर पहुंचें"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"किसी ऐप्स को स्‍थानीय ब्लूटूथ टेबलेट कॉन्‍फ़िगर करने की और रिमोट डिवाइस के साथ खोजने और युग्‍मित करने देता है."</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"किसी ऐप्स को स्‍थानीय ब्लूटूथ टैबलेट कॉन्‍फ़िगर करने की और रिमोट डिवाइस के साथ खोजने और युग्‍मित करने देता है."</string>
     <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"ऐप को स्‍थानीय ब्‍लूटूथ टीवी कॉन्‍फ़िगर करने देती है और दूरस्‍थ डिवाइसों को खोजने और उनसे युग्‍मित करने देती है."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"ऐप्स को स्‍थानीय ब्लूटूथ फ़ोन कॉन्‍फ़िगर करने देता है, और रिमोट डिवाइस के साथ खोजने और युग्‍मित करने देता है."</string>
     <string name="permlab_accessWimaxState" msgid="4195907010610205703">"WiMAX से कनेक्ट और डिसकनेक्ट करें"</string>
-    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"ऐप्स  को WiMAX सक्षम है या नहीं और कनेक्‍ट किए गए किसी WiMAX नेटवर्क के बारे में जानकारी निर्धारित करने देता है."</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"ऐप को तय करने देता है कि WiMAX चालू है या नहीं और कनेक्‍ट किए गए किसी WiMAX नेटवर्क के बारे में जानकारी लेने देता है."</string>
     <string name="permlab_changeWimaxState" msgid="340465839241528618">"WiMAX स्‍थिति बदलें"</string>
-    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"ऐप्स को WiMAX नेटवर्क से टेबलेट को कनेक्‍ट और डिस्‍कनेक्‍ट करने देता है."</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"ऐप्स को WiMAX नेटवर्क से टैबलेट को कनेक्‍ट और डिस्‍कनेक्‍ट करने देता है."</string>
     <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"ऐप को, टीवी को WiMAX नेटवर्कों से कनेक्‍ट करने और उनसे डिस्‍कनेक्‍ट करने देती है."</string>
     <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"ऐप्स को WiMAX नेटवर्क से फ़ोन को कनेक्‍ट और डिस्‍कनेक्‍ट करने देता है."</string>
     <string name="permlab_bluetooth" msgid="6127769336339276828">"ब्लूटूथ डिवाइस को दूसरे डिवाइस से जोड़ें"</string>
-    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"ऐप्स को टेबलेट पर ब्लूटूथ का कॉन्‍फ़िगरेशन देखने, और युग्‍मित डिवाइस के साथ कनेक्‍शन बनाने और स्‍वीकार करने देता है."</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"ऐप्स को टैबलेट पर ब्लूटूथ का कॉन्‍फ़िगरेशन देखने, और युग्‍मित डिवाइस के साथ कनेक्‍शन बनाने और स्‍वीकार करने देता है."</string>
     <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"ऐप को टीवी पर ब्‍लूटूथ का कॉन्‍फ़िगरेशन देखने देती है और युग्‍मित डिवाइसों के साथ कनेक्‍शन बनाने और स्‍वीकार करने देती है."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"ऐप्स को फ़ोन पर ब्लूटूथ का कॉन्‍फ़िगरेशन देखने, और युग्‍मित डिवाइस के साथ कनेक्‍शन बनाने और स्‍वीकार करने देता है."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"नियर फ़ील्‍ड कम्‍यूनिकेशन नियंत्रित करें"</string>
@@ -493,7 +492,7 @@
     <string name="fingerprint_name_template" msgid="5870957565512716938">"अंगुली <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
-    <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"फ़िंगरप्रिंट आइकन"</string>
+    <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"फ़िंगरप्रिंट आइकॉन"</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"समन्वयन सेटिंग पढ़ें"</string>
     <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ऐप्स  को किसी खाते की समन्वयन सेटिंग पढ़ने देता है. उदाहरण के लिए, इससे यह निर्धारित किया जा सकता है कि लोग ऐप्स  किसी खाते के साथ समन्‍वयित है या नहीं."</string>
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"समन्‍वयन बंद या चालू टॉगल करें"</string>
@@ -504,36 +503,36 @@
     <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"अपने SD कार्ड की सामग्री पढ़ें"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"एप्‍लिकेशन को आपके USB मेमोरी की सामग्री पढ़ने की अनुमति देता है."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"एप्‍लिकेशन को आपके SD कार्ड की सामग्री पढ़ने की अनुमति देता है."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"अपने USB मेमोरी की सामग्री बदलें या हटाएं"</string>
-    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"अपने SD कार्ड की सामग्री बदलें या हटाएं"</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"अपने USB मेमोरी की सामग्री बदलें या मिटाएं"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"अपने SD कार्ड की सामग्री बदलें या मिटाएं"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"ऐप्स को USB मेमोरी में लिखने देता है."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"ऐप्स  को SD कार्ड पर लिखने देता है."</string>
     <string name="permlab_use_sip" msgid="2052499390128979920">"SIP कॉल करें/प्राप्‍त करें"</string>
     <string name="permdesc_use_sip" msgid="2297804849860225257">"ऐप्स को SIP कॉल करने और प्राप्‍त करने देती है."</string>
-    <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"नए टेलिकॉम सिम कनेक्‍शन पंजीकृत करें"</string>
+    <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"नए टेलिकॉम सिम कनेक्‍शन रजिस्टर करें"</string>
     <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"ऐप को नए टेलिकॉम सिम कनेक्‍शन पंजीकृत करने देती है."</string>
-    <string name="permlab_register_call_provider" msgid="108102120289029841">"नए टेलिकॉम कनेक्‍शन पंजीकृत करें"</string>
+    <string name="permlab_register_call_provider" msgid="108102120289029841">"नए टेलिकॉम कनेक्‍शन रजिस्टर करें"</string>
     <string name="permdesc_register_call_provider" msgid="7034310263521081388">"ऐप को नए टेलिकॉम कनेक्शन पंजीकृत करने देती है."</string>
     <string name="permlab_connection_manager" msgid="1116193254522105375">"टेलीकॉम कनेक्शन प्रबंधित करें"</string>
     <string name="permdesc_connection_manager" msgid="5925480810356483565">"ऐप को टेलीकॉम कनेक्शन प्रबंधित करने देती है."</string>
     <string name="permlab_bind_incall_service" msgid="6773648341975287125">"इन-कॉल स्क्रीन से सहभागिता करें"</string>
-    <string name="permdesc_bind_incall_service" msgid="8343471381323215005">"ऐप्स को यह नियंत्रित करने देती है कि उपयोगकर्ता को इन-कॉल स्क्रीन कब और कैसी दिखाई देती है."</string>
+    <string name="permdesc_bind_incall_service" msgid="8343471381323215005">"ऐप को यह नियंत्रित करने देती है कि उपयोगकर्ता को इन-कॉल स्क्रीन कब और कैसी दिखाई देती है."</string>
     <string name="permlab_bind_connection_service" msgid="3557341439297014940">"टेलीफ़ोनी सेवाओं के साथ सहभागिता करें"</string>
     <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"कॉल करने/प्राप्‍त करने के लिए ऐप्स को टेलीफ़ोनी सेवा के साथ सहभागिता करने दें."</string>
-    <string name="permlab_control_incall_experience" msgid="9061024437607777619">"इन कॉल उपयोगकर्ता अनुभव प्रदान करना"</string>
-    <string name="permdesc_control_incall_experience" msgid="915159066039828124">"ऐप्स को इन कॉल उपयोगकर्ता अनुभव लेने देती है."</string>
+    <string name="permlab_control_incall_experience" msgid="9061024437607777619">"इन कॉल उपयोगकर्ता अनुभव लें"</string>
+    <string name="permdesc_control_incall_experience" msgid="915159066039828124">"ऐप को इन कॉल उपयोगकर्ता अनुभव लेने देती है."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"ऐतिहासिक नेटवर्क उपयोग पढें"</string>
     <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"किसी ऐप्स  को विशिष्ट नेटवर्क और ऐप्स के लिए ऐतिहासिक नेटवर्क उपयोग को पढ़ने देता है."</string>
     <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"नेटवर्क नीति प्रबंधित करें"</string>
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"ऐप्स को नेटवर्क नीतियां प्रबंधित करने और ऐप्स-विशिष्‍ट नियमों को परिभाषित करने देता है."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"नेटवर्क उपयोग हिसाब बदलें"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"ऐप्स  को यह संशोधित करने देता है कि ऐप्स की तुलना में नेटवर्क उपयोग का मूल्यांकन कैसे किया जाता है. सामान्‍य ऐप्स द्वारा उपयोग करने के लिए नहीं."</string>
-    <string name="permlab_accessNotifications" msgid="7673416487873432268">"नोटिफ़िकेशन तक पहुंचें"</string>
-    <string name="permdesc_accessNotifications" msgid="458457742683431387">"ऐप्स  को नोटिफ़िकेशन को प्राप्त करने, जांच करने, और साफ़ करने देता है, जिनमें अन्य ऐप्स  के द्वारा पोस्ट की गई सूचनाएं भी शामिल हैं."</string>
-    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"नोटिफ़िकेशन श्रवणकर्ता सेवा से जुड़ें"</string>
-    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"धारक को नोटिफ़िकेशन श्रवणकर्ता सेवा के शीर्ष स्तरीय इंटरफ़ेस से जुड़ने देती है. सामान्य ऐप्स  के लिए कभी भी आवश्यक नहीं होनी चाहिए."</string>
-    <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"किसी स्थिति प्रदाता सेवा से आबद्ध हों"</string>
-    <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"धारक को किसी स्थिति प्रदाता सेवा के शीर्ष-स्तर के इंटरफ़ेस से आबद्ध होने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+    <string name="permlab_accessNotifications" msgid="7673416487873432268">"सूचना तक पहुंचें"</string>
+    <string name="permdesc_accessNotifications" msgid="458457742683431387">"ऐप को सूचना पाने, जांच करने और साफ़ करने देता है, जिनमें अन्य ऐप के ज़रिए पोस्ट की गई सूचनाएं भी शामिल हैं."</string>
+    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"सूचना श्रवणकर्ता सेवा से जुड़ें"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"उपयोगकर्ता को सूचना सुनने वाली सेवा के सबसे बेहतर इंटरफ़ेस से जुड़ने देती है. सामान्य ऐप के लिए कभी भी इसकी ज़रुरत नहीं होगी."</string>
+    <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"किसी शर्तें लागू करने वाली (कंडीशन प्रोवाइडर) सेवा से जुड़ें"</string>
+    <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"उपयोगकर्ता को किसी शर्तें लागू करने वाले (कंडीशन प्रोवाइडर) सबसे बढ़िया इंटरफ़ेस से जोड़ता है. सामान्‍य ऐप के लिए इसकी कभी ज़रूरत नहीं होती."</string>
     <string name="permlab_bindDreamService" msgid="4153646965978563462">"भावी सेवा से आबद्ध करें"</string>
     <string name="permdesc_bindDreamService" msgid="7325825272223347863">"धारक को किसी भावी सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य ऐप्स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"मोबाइल और इंटरनेट सेवा देने वाली कंपनी से पाया गया कॉन्फ़िगरेशन ऐप शुरु करें."</string>
@@ -552,23 +551,23 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"उपयोगकर्ता को किसी मोबाइल और इंटरनेट सेवा देने वाली कंपनी की मैसेज सेवा के सबसे बढ़िया इंटरफ़ेस से जोड़ता है. सामान्‍य ऐप के लिए इसकी कभी ज़रूरत नहीं होती."</string>
     <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"किसी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से जुड़ें"</string>
     <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"उपयोगकर्ता को किसी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से जोड़ता है. सामान्‍य ऐप के लिए इसकी कभी ज़रूरत नहीं होती."</string>
-    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"परेशान न करें को ऐक्सेस करें"</string>
+    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"\'परेशान न करें\' को ऐक्सेस करें"</string>
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"ऐप को परेशान न करें कॉन्फ़िगरेशन पढ़ने और लिखने देती है."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करें"</string>
     <string name="policydesc_limitPassword" msgid="2502021457917874968">"स्‍क्रीन लॉक पासवर्ड तथा पिन की लंबाई और उसमें अनुमत वर्णों को नियंत्रित करें."</string>
     <string name="policylab_watchLogin" msgid="5091404125971980158">"स्क्रीन अनलॉक करने की कोशिशों की निगरानी करें"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"स्‍क्रीन को अनलॉक करते समय गलत लिखे गए पासवर्ड की संख्‍या पर निगरानी करें, और बहुत अधिक बार गलत पासवर्ड लिखे जाने पर टेबलेट लॉक करें या टेबलेट का संपूर्ण डेटा मिटाएं."</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"स्‍क्रीन को अनलॉक करते समय गलत लिखे गए पासवर्ड की संख्‍या पर निगरानी करें, और बहुत अधिक बार गलत पासवर्ड लिखे जाने पर टैबलेट लॉक करें या टैबलेट का संपूर्ण डेटा मिटाएं."</string>
     <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"स्‍क्रीन को अनलॉक करते समय गलत तरीके से लिखे गए पासवर्ड पर नज़र रखें और यदि बहुत अधिक गलत पासवर्ड लिखे जाते हैं तो टीवी को लॉक करें या टीवी का सभी डेटा मिटा दें."</string>
     <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"गलत लिखे गए पासवर्ड की संख्‍या पर निगरानी करें. स्क्रीन अनलॉक करते समय, बहुत अधिक बार गलत पासवर्ड लिखे जाने पर फ़ोन लॉक करें या फ़ोन का संपूर्ण डेटा मिटाएं."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"स्‍क्रीन को अनलॉक करते समय गलत तरीके से लिखे गए पासवर्ड पर नज़र रखें और यदि बार बार अधिक पासवर्ड लिखे जाते हैं तो टैबलेट को लॉक करें या इस उपयोगकर्ता का सभी डेटा मिटा दें."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"स्‍क्रीन को अनलॉक करते समय गलत तरीके से लिखे गए पासवर्ड पर नज़र रखें यदि बार बार गलत पासवर्ड लिखे जाने पर टीवी को लॉक करें या इस उपयोगकर्ता का सभी डेटा मिटा दें."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"स्‍क्रीन को अनलॉक करते समय गलत तरीके से लिखे गए पासवर्ड पर नज़र रखें और यदि बार बार गलत पासवर्ड लिखे जाते हैं तो फ़ोन को लॉक करें या इस उपयोगकर्ता का सभी डेटा मिटा दें."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"स्‍क्रीन का लॉक खोलते समय गलत तरीके से लिखे गए पासवर्ड पर नज़र रखें, और अगर बार-बार अधिक पासवर्ड लिखे जाते हैं तो टैबलेट को लॉक करें या इस उपयोगकर्ता का सभी डेटा मिटा दें."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"स्‍क्रीन का लॉक खोलते समय गलत तरीके से लिखे गए पासवर्ड पर नज़र रखें, और अगर बार-बार गलत पासवर्ड लिखा जाता है तो टीवी को लॉक करें या इस उपयोगकर्ता का सभी डेटा मिटा दें."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"स्‍क्रीनका लॉक खोलते समय गलत तरीके से लिखे गए पासवर्ड पर नज़र रखें, और अगर बार-बार गलत पासवर्ड लिखा जाता है तो फ़ोन को लॉक करें या इस उपयोगकर्ता का सभी डेटा मिटा दें."</string>
     <string name="policylab_resetPassword" msgid="4934707632423915395">"स्‍क्रीन लॉक बदलें"</string>
     <string name="policydesc_resetPassword" msgid="1278323891710619128">"स्‍क्रीन लॉक को बदलें."</string>
     <string name="policylab_forceLock" msgid="2274085384704248431">"स्‍क्रीन लॉक करें"</string>
     <string name="policydesc_forceLock" msgid="1141797588403827138">"नियंत्रित करें कि स्‍क्रीन कैसे और कब लॉक हो."</string>
-    <string name="policylab_wipeData" msgid="3910545446758639713">"सभी डेटा हटाएं"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"फ़ैक्टरी डेटा रीसेट करके, चेतावनी दिए बिना टेबलेट का डेटा मिटाएं."</string>
+    <string name="policylab_wipeData" msgid="3910545446758639713">"सभी डेटा मिटाएं"</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"फ़ैक्टरी डेटा रीसेट करके, चेतावनी दिए बिना टैबलेट का डेटा मिटाएं."</string>
     <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"फ़ैक्‍टरी डेटा रीसेट करके, चेतावनी दिए बिना टीवी का डेटा मिटाएं."</string>
     <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"फ़ैक्‍टरी डेटा रीसेट करके, चेतावनी दिए बिना फ़ोन का डेटा मिटाएं."</string>
     <string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"उपयोगकर्ता डेटा मिटाएं"</string>
@@ -576,10 +575,10 @@
     <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"इस टीवी पर मौजूद इस उपयोगकर्ता का डेटा बिना चेतावनी के मिटा दें."</string>
     <string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"इस फ़ोन पर मौजूद इस उपयोगकर्ता का डेटा बिना चेतावनी के मिटा दें."</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"डिवाइस वैश्विक प्रॉक्‍सी सेट करें"</string>
-    <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"नीति सक्षम होने के दौरान डिवाइस वैश्विक प्रॉक्‍सी सेट करें. केवल डिवाइस स्‍वामी ही वैश्‍विक प्रॉक्‍सी सेट कर सकता है."</string>
+    <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"नीति चालू होने के दौरान इस्तेमाल करने के लिए डिवाइस ग्लोबल प्रॉक्‍सी सेट करें. केवल डिवाइस का मालिक ही ग्लोबल प्रॉक्‍सी सेट कर सकता है."</string>
     <string name="policylab_expirePassword" msgid="5610055012328825874">"स्‍क्रीन लॉक पासवर्ड समाप्‍ति सेट करें"</string>
     <string name="policydesc_expirePassword" msgid="5367525762204416046">"यह बदलें कि स्‍क्रीन लॉक पासवर्ड, पिन या पैटर्न को कितने समय में बदला जाना चाहिए."</string>
-    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"मेमोरी एन्‍क्रिप्‍शन सेट करें"</string>
+    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"मेमोरी को सुरक्षित करने का तरीका सेट करें"</string>
     <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"संग्रहित ऐप्स डेटा को एन्क्रिप्ट किया जाना आवश्‍यक है."</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"कैमरों को अक्षम करें"</string>
     <string name="policydesc_disableCamera" msgid="2306349042834754597">"सभी डिवाइस कैमरों का उपयोग रोकें."</string>
@@ -593,7 +592,7 @@
     <item msgid="1735177144948329370">"घर का फ़ैक्स"</item>
     <item msgid="603878674477207394">"पेजर"</item>
     <item msgid="1650824275177931637">"अन्य"</item>
-    <item msgid="9192514806975898961">"कस्टम"</item>
+    <item msgid="9192514806975898961">"अपने मुताबिक बदलें"</item>
   </string-array>
   <string-array name="emailAddressTypes">
     <item msgid="8073994352956129127">"घर"</item>
@@ -605,7 +604,7 @@
     <item msgid="6880257626740047286">"घर"</item>
     <item msgid="5629153956045109251">"कार्यालय"</item>
     <item msgid="4966604264500343469">"अन्य"</item>
-    <item msgid="4932682847595299369">"कस्टम"</item>
+    <item msgid="4932682847595299369">"अपने मुताबिक बदलें"</item>
   </string-array>
   <string-array name="imAddressTypes">
     <item msgid="1738585194601476694">"घर"</item>
@@ -648,7 +647,7 @@
     <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"कार्यालय का मोबाइल"</string>
     <string name="phoneTypeWorkPager" msgid="649938731231157056">"कार्यालय का पेजर"</string>
     <string name="phoneTypeAssistant" msgid="5596772636128562884">"सहायक"</string>
-    <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
+    <string name="phoneTypeMms" msgid="7254492275502768992">"मल्टीमीडिया मैसेज (एमएमएस)"</string>
     <string name="eventTypeCustom" msgid="7837586198458073404">"कस्टम"</string>
     <string name="eventTypeBirthday" msgid="2813379844211390740">"जन्‍मदिन"</string>
     <string name="eventTypeAnniversary" msgid="3876779744518284000">"वर्षगांठ"</string>
@@ -707,12 +706,12 @@
     <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"अनलॉक करने के लिए पासवर्ड लिखें"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"अनलॉक करने के लिए पिन लिखें"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"गलत पिन कोड."</string>
-    <string name="keyguard_label_text" msgid="861796461028298424">"अनलॉक करने के लिए, मेनू दबाएं और फिर 0 दबाएं."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"लॉक खोलने के लिए, मेन्यू दबाएं और फिर 0 दबाएं."</string>
     <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"आपातकालीन नंबर"</string>
     <string name="lockscreen_carrier_default" msgid="6169005837238288522">"कोई सेवा नहीं"</string>
     <string name="lockscreen_screen_locked" msgid="7288443074806832904">"स्‍क्रीन लॉक की गई है."</string>
-    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"अनलॉक करने के लिए मेनू दबाएं या आपातलकालीन कॉल करें."</string>
-    <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"अनलॉक करने के लिए मेनू दबाएं."</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"लॉक खोलने के लिए मेन्यू दबाएं या आपातलकालीन कॉल करें."</string>
+    <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"लॉक खोलने के लिए मेन्यू दबाएं."</string>
     <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"अनलॉक करने के लिए आकार आरेखित करें"</string>
     <string name="lockscreen_emergency_call" msgid="5298642613417801888">"आपातकाल"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"कॉल पर वापस लौटें"</string>
@@ -722,13 +721,13 @@
     <string name="lockscreen_storage_locked" msgid="9167551160010625200">"सभी सुविधाओं और डेटा के लिए अनलॉक करें"</string>
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"मालिक का चेहरा पहचानकर अनलॉक करने की तय सीमा खत्म हो गई"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"कोई सिम कार्ड नहीं है"</string>
-    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"टेबलेट में कोई सिम कार्ड नहीं है."</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"टैबलेट में कोई सिम कार्ड नहीं है."</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"टीवी में कोई SIM कार्ड नहीं है."</string>
     <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"फ़ोन में कोई सिम कार्ड नहीं है."</string>
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"कोई सिमकार्ड डालें."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"सिम कार्ड गुम है या पढ़ने योग्‍य नहीं है. कोई सिम कार्ड डालें."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"अनुपयोगी सिम कार्ड."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"आपका सिम कार्ड स्‍थायी रूप से अक्षम कर दिया गया है.\n दूसरे सिम कार्ड के लिए अपने वायरलेस सेवा प्रदाता से संपर्क करें."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"आपका सिम कार्ड हमेशा के लिए बंद कर दिया गया है.\n दूसरे सिम कार्ड के लिए अपने वायरलेस सेवा देने वाले से संपर्क करें."</string>
     <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"पिछला ट्रैक"</string>
     <string name="lockscreen_transport_next_description" msgid="573285210424377338">"अगला ट्रैक"</string>
     <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"रोकें"</string>
@@ -739,31 +738,31 @@
     <string name="emergency_calls_only" msgid="6733978304386365407">"केवल आपातकालीन कॉल"</string>
     <string name="lockscreen_network_locked_message" msgid="143389224986028501">"नेटवर्क लॉक किया गया"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"सिम कार्ड PUK-लॉक किया हुआ है."</string>
-    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"कृपया उपयोगकर्ता मार्गदर्शिका देखें या ग्राहक सहायता से संपर्क करें."</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"कृपया उपयोग के लिए गाइड देखें या ग्राहक सहायता से संपर्क करें."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"सिम कार्ड लॉक किया गया है."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"सिम कार्ड अनलॉक कर रहा है…"</string>
     <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"आपने अपना अनलॉक आकार <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत बनाया है. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"आपने अपना पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से लिखा है. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
     <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"आपने अपना पिन <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से लिखा है. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में फिर से प्रयास करें."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"आपने अपना अनलॉक आकार <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत बनाया है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने Google साइन-इन का उपयोग करके आपके टेबलेट को अनलॉक करने को कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"आपने अपना अनलॉक आकार <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत बनाया है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने Google साइन-इन का उपयोग करके आपके टैबलेट को अनलॉक करने को कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"आपने अपना अनलॉक पैटन <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से बनाया है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने टीवी को अपने Google साइन-इन का उपयोग करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"आपने अपना अनलॉक आकार <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत बनाया है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने Google साइन-इन का उपयोग करके आपके फ़ोन को अनलॉक करने को कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"आप गलत तरीके से टेबलेट को अनलॉक करने का प्रयास <xliff:g id="NUMBER_0">%1$d</xliff:g> बार कर चुके हैं. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल प्रयास के बाद, टेबलेट फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"आपने टीवी को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से प्रयास किया है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल प्रयासों के बाद, टीवी को फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट कर दिया जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"आप गलत तरीके से फ़ोन को अनलॉक करने का प्रयास <xliff:g id="NUMBER_0">%1$d</xliff:g> बार कर चुके हैं. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल प्रयास के बाद, फ़ोन फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"आप टेबलेट को गलत तरीके से <xliff:g id="NUMBER">%d</xliff:g> बार अनलॉक करने का प्रयास कर चुके हैं. टेबलेट अब फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"आप टैबलेट का लॉक खोलने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश कर चुके हैं. <xliff:g id="NUMBER_1">%2$d</xliff:g> बार और गलत कोशिश करने पर, टैबलेट फ़ैक्ट्री डिफ़ॉल्ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"आपने टीवी का लॉक खोलने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश की है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और बार गलत कोशिश करने पर, टीवी को फ़ैक्ट्री डिफ़ॉल्‍ट पर रीसेट कर दिया जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"आप फ़ोन का लॉक खोलने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश कर चुके हैं. <xliff:g id="NUMBER_1">%2$d</xliff:g> बार और गलत कोशिश करने पर, फ़ोन फ़ैक्ट्री डिफ़ॉल्ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"आप टैबलेट को गलत तरीके से <xliff:g id="NUMBER">%d</xliff:g> बार अनलॉक करने का प्रयास कर चुके हैं. टैबलेट अब फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"आपने टीवी को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से प्रयास किया है. अब टीवी को फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट कर दिया जाएगा."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"आप फ़ोन को गलत तरीके से <xliff:g id="NUMBER">%d</xliff:g> बार अनलॉक करने का प्रयास कर चुके हैं. फ़ोन अब फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"आकार भूल गए?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"खाता अनलॉक"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"बहुत अधिक आकार प्रयास"</string>
-    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"अनलॉक करने के लिए, अपने Google खाते से प्रवेश करें."</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"अनलॉक करने के लिए, अपने Google खाते से साइन इन करें."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"उपयोगकर्ता नाम (ईमेल)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"पासवर्ड"</string>
-    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"प्रवेश करें"</string>
-    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"अमान्य उपयोगकर्ता नाम या पासवर्ड."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"अपना उपयोगकर्ता नाम या पासवर्ड भूल गए?\n"<b>"google.com/accounts/recovery"</b>" पर जाएं."</string>
+    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"साइन इन करें"</string>
+    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"उपयोगकर्ता नाम या पासवर्ड गलत है."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"अपना उपयोगकर्ता नाम या पासवर्ड भूल गए?\n "<b>"google.com/accounts/recovery"</b>" पर जाएं."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"जांच रहा है…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"अनलॉक करें"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ध्‍वनि चालू करें"</string>
@@ -780,14 +779,14 @@
     <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"अनलॉक क्षेत्र को विस्तृत कर दिया गया."</string>
     <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"अनलॉक क्षेत्र को संक्षिप्त कर दिया गया."</string>
     <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> विजेट."</string>
-    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"उपयोगकर्ता चयनकर्ता"</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"उपयोगकर्ता चुनने वाला"</string>
     <string name="keyguard_accessibility_status" msgid="8008264603935930611">"स्थिति"</string>
     <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"कैमरा"</string>
     <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"मीडिया नियंत्रण"</string>
     <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"विजेट फिर से क्रमित करना प्रारंभ."</string>
     <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"विजेट फिर से क्रमित करना समाप्त."</string>
     <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"विजेट <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> को हटा दिया गया."</string>
-    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"अनलॉक क्षेत्र विस्तृत करें."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"अनलॉक क्षेत्र का विस्तार करें."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"स्लाइड अनलॉक."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"आकार अनलॉक."</string>
     <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"मालिक का चेहरा पहचानकर अनलॉक करें."</string>
@@ -803,7 +802,7 @@
     <string name="granularity_label_link" msgid="5815508880782488267">"लिंक"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"पंक्ति"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"फ़ैक्‍ट्री परीक्षण विफल"</string>
-    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST क्रिया केवल /system/app में इंस्‍टॉल किए गए पैकेज के लिए समर्थित है."</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST का काम केवल /system/app में इंस्‍टॉल किए गए पैकेज के लिए ही हो सकता है."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"ऐसा कोई पैकेज नहीं मिला था जो FACTORY_TEST कार्रवाई प्रदान करता हो."</string>
     <string name="factorytest_reboot" msgid="6320168203050791643">"रीबूट करें"</string>
     <string name="js_dialog_title" msgid="1987483977834603872">"\'<xliff:g id="TITLE">%s</xliff:g>\' पर यह पेज दर्शाता है:"</string>
@@ -813,7 +812,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_address_name_separator" msgid="6350145154779706772">" "</string>
@@ -833,45 +832,45 @@
     <string name="autofill_area" msgid="3547409050889952423">"क्षेत्र"</string>
     <string name="autofill_emirate" msgid="2893880978835698818">"अमीरात"</string>
     <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"अपने वेब बुकमार्क और इतिहास पढ़ें"</string>
-    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"ऐप्स  को ब्राउज़र द्वारा विज़िट किए गए सभी URL के इतिहास, और सभी ब्राउज़र बुकमार्क पढ़ने देता है. ध्‍यान दें: यह अनुमति तृतीय-पक्ष ब्राउज़र या वेब ब्राउज़िंग क्षमताओं वाले अन्‍य ऐप्स  द्वारा लागू नहीं की जा सकती."</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"ऐप को ब्राउज़र के ज़रिये देखे गए सभी यूआरएल के इतिहास, और ब्राउज़र के सभी बुकमार्क पढ़ने देता है. ध्‍यान दें: हो सकता है कि यह अनुमति तीसरे-पक्ष के ब्राउज़र या वेब ब्राउज़िंग की सुविधा वाले अन्य ऐप के ज़रिये लागू न की जाए."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"वेब बुकमार्क और इतिहास लिखें"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"ऐप्स  को आपके टेबलेट में संग्रहित ब्राउज़र के इतिहास या बुकमार्क को संशोधित करने देता है. इससे ऐप्स  ब्राउज़र डेटा को मिटा सकता है या संशोधित कर सकता है. ध्‍यान दें: यह अनुमति तृतीय-पक्ष ब्राउज़र या वेब ब्राउज़िंग क्षमताओं वाले अन्‍य ऐप्स  द्वारा लागू नहीं की जा सकती."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"ऐप्स  को आपके टैबलेट में संग्रहित ब्राउज़र के इतिहास या बुकमार्क को संशोधित करने देता है. इससे ऐप्स  ब्राउज़र डेटा को मिटा सकता है या संशोधित कर सकता है. ध्‍यान दें: यह अनुमति तृतीय-पक्ष ब्राउज़र या वेब ब्राउज़िंग क्षमताओं वाले अन्‍य ऐप्स  द्वारा लागू नहीं की जा सकती."</string>
     <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"ऐप को आपके टीवी पर संग्रहित ब्राउज़र के इतिहास या बुकमार्क में बदलाव करने देती है. इससे ऐप को ब्राउज़र डेटा में बदलाव करने या उसे हटाने की अनुमति मिल सकती है. ध्‍यान दें: यह अनुमति वेब ब्राउज़िंग क्षमताओं वाले तृतीय-पक्ष ब्राउज़र या अन्‍य ऐप्‍लिकेशन द्वारा लागू नहीं की जा सकती है."</string>
     <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"ऐप्स  को आपके फ़ोन में संग्रहित ब्राउज़र के इतिहास या बुकमार्क को संशोधित करने देता है. इससे ऐप्स  ब्राउज़र डेटा को मिटा सकता है या संशोधित कर सकता है. ध्‍यान दें: यह अनुमति तृतीय-पक्ष ब्राउज़र या वेब ब्राउज़िंग क्षमताओं वाले अन्‍य ऐप्स  द्वारा लागू नहीं की जा सकती."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"अलार्म सेट करें"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"ऐप्स को इंस्‍टॉल किए गए अलार्म घड़ी ऐप्स में अलार्म सेट करने देता है. हो सकता है कुछ अलार्म घड़ी ऐप्स में यह सुविधा न हो."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"ध्‍वनिमेल जोड़ें"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"ऐप्स  को आपके ध्‍वनिमेल इनबॉक्‍स में संदेश जोड़ने देता है."</string>
-    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ब्राउज़र भौगोलिक-स्थान अनुमतियों को बदलें"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"ऐप्स को ब्राउज़र के भौगोलिक-स्‍थान की अनुमतियां संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स इसका उपयोग एकपक्षीय वेबसाइट को स्‍थान जानकारी भेजने में कर सकते हैं."</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ब्राउज़र की जगह से जुड़ी अनुमतियों को बदलें"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"ऐप को ब्राउज़र की जगह से जुड़ी अनुमतियों को बदलने देता है. धोखा देने वाले ऐप इसका इस्तेमाल गलत वेबसाइट को जगह की जानकारी भेजने में कर सकते हैं."</string>
     <string name="save_password_message" msgid="767344687139195790">"क्‍या आप चाहते हैं कि ब्राउज़र पासवर्ड को याद रखे?"</string>
-    <string name="save_password_notnow" msgid="6389675316706699758">"अभी नहीं"</string>
+    <string name="save_password_notnow" msgid="6389675316706699758">"रद्द करें"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"याद रखें"</string>
     <string name="save_password_never" msgid="8274330296785855105">"कभी नहीं"</string>
     <string name="open_permission_deny" msgid="7374036708316629800">"आपके पास इस पेज को खोलने की अनुमति नहीं है."</string>
     <string name="text_copied" msgid="4985729524670131385">"लेख को क्‍लिपबोर्ड पर कॉपी किया गया."</string>
     <string name="more_item_label" msgid="4650918923083320495">"अधिक"</string>
-    <string name="prepend_shortcut_label" msgid="2572214461676015642">"मेनू+"</string>
+    <string name="prepend_shortcut_label" msgid="2572214461676015642">"मेन्यू+"</string>
     <string name="menu_space_shortcut_label" msgid="2410328639272162537">"space"</string>
     <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
-    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"हटाएं"</string>
-    <string name="search_go" msgid="8298016669822141719">"खोजें"</string>
-    <string name="search_hint" msgid="1733947260773056054">"खोजें…"</string>
-    <string name="searchview_description_search" msgid="6749826639098512120">"खोजें"</string>
-    <string name="searchview_description_query" msgid="5911778593125355124">"खोज क्वेरी"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"मिटाएं"</string>
+    <string name="search_go" msgid="8298016669822141719">"सर्च करें"</string>
+    <string name="search_hint" msgid="1733947260773056054">"सर्च करें…"</string>
+    <string name="searchview_description_search" msgid="6749826639098512120">"सर्च करें"</string>
+    <string name="searchview_description_query" msgid="5911778593125355124">"सर्च क्वेरी"</string>
     <string name="searchview_description_clear" msgid="1330281990951833033">"क्‍वेरी साफ़ करें"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"क्वेरी सबमिट करें"</string>
-    <string name="searchview_description_voice" msgid="2453203695674994440">"बोलकर खोजें"</string>
-    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"स्‍पर्श के द्वारा अन्‍वेषण करें सक्षम करें?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्‍पर्श के द्वारा अन्‍वेषण करें सक्षम करना चाहती है. स्‍पर्श के द्वारा अन्‍वेष करें चालू होने पर, आप अपनी अंगुली के नीचे क्या है उसका विवरण सुन सकते हैं या देख सकते हैं या टेबलेट से डॉयलॉग करने के लिए जेस्‍चर निष्‍पादित कर सकते हैं."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्‍पर्श के द्वारा अन्‍वेषण करें सक्षम करना चाहती है. स्‍पर्श के द्वारा अन्‍वेष करें चालू होने पर, आप अपनी अंगुली के नीचे क्या है उसका विवरण सुन सकते हैं या देख सकते हैं या फ़ोन से डॉयलॉग करने के लिए जेस्‍चर निष्‍पादित कर सकते हैं."</string>
+    <string name="searchview_description_voice" msgid="2453203695674994440">"बोलकर सर्च करें"</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"छूकर, उससे जुड़ी जानकारी सुनना चालू करें?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> छूकर, उससे जुड़ी जानकारी सुनना चालू करना चाहती है. छूकर, उससे जुड़ी जानकारी सुनना चालू होने पर, जो भी आपकी उंगली के नीचे है आप उसकी जानकारी सुन या देख सकते हैं या टैबलेट के ज़रिये बातचीत करने के लिए हाथ के जेश्चर (स्पर्श) का इस्तेमाल कर सकते हैं."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> छूकर, उससे जुड़ी जानकारी सुनना चालू करना चाहती है. छूकर, उससे जुड़ी जानकारी सुनना चालू होने पर, जो भी आपकी उंगली के नीचे है आप उसकी जानकारी सुन या देख सकते हैं या फ़ोन के ज़रिये बातचीत करने के लिए हाथ के जेश्चर (स्पर्श) का इस्तेमाल कर सकते हैं."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 माह पहले"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 माह से पहले"</string>
     <plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
       <item quantity="one">पिछले <xliff:g id="COUNT_1">%d</xliff:g> दिनों में</item>
       <item quantity="other">पिछले <xliff:g id="COUNT_1">%d</xliff:g> दिनों में</item>
     </plurals>
-    <string name="last_month" msgid="3959346739979055432">"पिछला माह"</string>
+    <string name="last_month" msgid="3959346739979055432">"पिछला महीना"</string>
     <string name="older" msgid="5211975022815554840">"इससे पुराना"</string>
     <string name="preposition_for_date" msgid="9093949757757445117">"<xliff:g id="DATE">%s</xliff:g> को"</string>
     <string name="preposition_for_time" msgid="5506831244263083793">"<xliff:g id="TIME">%s</xliff:g> पर"</string>
@@ -970,59 +969,59 @@
     <string name="paste" msgid="5629880836805036433">"चिपकाएं"</string>
     <string name="paste_as_plain_text" msgid="5427792741908010675">"सादे पाठ के रूप में चिपकाएं"</string>
     <string name="replace" msgid="5781686059063148930">"बदलें•"</string>
-    <string name="delete" msgid="6098684844021697789">"हटाएं"</string>
-    <string name="copyUrl" msgid="2538211579596067402">"URL को कॉपी करें"</string>
+    <string name="delete" msgid="6098684844021697789">"मिटाएं"</string>
+    <string name="copyUrl" msgid="2538211579596067402">"यूआरएल को कॉपी करें"</string>
     <string name="selectTextMode" msgid="1018691815143165326">"लेख को चुनें"</string>
     <string name="undo" msgid="7905788502491742328">"वापस लाएं"</string>
     <string name="redo" msgid="7759464876566803888">"फिर से करें"</string>
     <string name="autofill" msgid="3035779615680565188">"ऑटोमैटिक भरना"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"लेख चयन"</string>
     <string name="addToDictionary" msgid="4352161534510057874">"शब्दकोश में जोड़ें"</string>
-    <string name="deleteText" msgid="6979668428458199034">"हटाएं"</string>
+    <string name="deleteText" msgid="6979668428458199034">"मिटाएं"</string>
     <string name="inputMethod" msgid="1653630062304567879">"इनपुट विधि"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"लेख क्रियाएं"</string>
     <string name="email" msgid="4560673117055050403">"ईमेल करें"</string>
     <string name="dial" msgid="4204975095406423102">"फ़ोन"</string>
     <string name="map" msgid="6068210738233985748">"मानचित्र"</string>
     <string name="browse" msgid="6993590095938149861">"ब्राउज़र"</string>
-    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"मेमोरी स्‍थान समाप्‍त हो रहा है"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"मेमोरी में जगह नहीं बची है"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"हो सकता है कुछ सिस्टम फ़ंक्शन कार्य न करें"</string>
-    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"सिस्टम के लिए पर्याप्त मेमोरी नहीं है. सुनिश्चित करें कि आपके पास 250MB का खाली स्थान है और फिर से प्रारंभ करें."</string>
+    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"सिस्टम के लिए ज़रूरी मेमोरी नहीं है. पक्का करें कि आपके पास 250एमबी की खाली जगह है और फिर से शुरू करें."</string>
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> चल रहा है"</string>
-    <string name="app_running_notification_text" msgid="1197581823314971177">"अधिक जानकारी के लिए या ऐप्लिकेशन रोकने के लिए टैप करें."</string>
+    <string name="app_running_notification_text" msgid="1197581823314971177">"अधिक जानकारी के लिए या ऐप्लिकेशन को रोकने के लिए छूएं."</string>
     <string name="ok" msgid="5970060430562524910">"ठीक है"</string>
-    <string name="cancel" msgid="6442560571259935130">"अभी नहीं"</string>
+    <string name="cancel" msgid="6442560571259935130">"रद्द करें"</string>
     <string name="yes" msgid="5362982303337969312">"ठीक है"</string>
-    <string name="no" msgid="5141531044935541497">"अभी नहीं"</string>
+    <string name="no" msgid="5141531044935541497">"रद्द करें"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"ध्यान दें"</string>
     <string name="loading" msgid="7933681260296021180">"लोड हो रहे हैं..."</string>
     <string name="capital_on" msgid="1544682755514494298">"ऑन"</string>
     <string name="capital_off" msgid="6815870386972805832">"बंद"</string>
-    <string name="whichApplication" msgid="4533185947064773386">"इसका उपयोग करके क्रिया पूर्ण करें"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"इसका इस्तेमाल करके कार्रवाई को पूरा करें"</string>
     <string name="whichApplicationNamed" msgid="8260158865936942783">"%1$s का उपयोग करके कार्रवाई पूर्ण करें"</string>
     <string name="whichApplicationLabel" msgid="7425855495383818784">"कार्रवाई पूर्ण करें"</string>
     <string name="whichViewApplication" msgid="3272778576700572102">"इसमें खोलें"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s में खोलें"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"खोलें"</string>
-    <string name="whichEditApplication" msgid="144727838241402655">"इसके द्वारा संपादित करें"</string>
-    <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s से संपादित करें"</string>
-    <string name="whichEditApplicationLabel" msgid="7183524181625290300">"संपादित करें"</string>
+    <string name="whichEditApplication" msgid="144727838241402655">"इसके ज़रिये बदलाव करें"</string>
+    <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s की मदद से बदलाव करें"</string>
+    <string name="whichEditApplicationLabel" msgid="7183524181625290300">"बदलाव करें"</string>
     <string name="whichSendApplication" msgid="6902512414057341668">"इससे साझा करें"</string>
     <string name="whichSendApplicationNamed" msgid="2799370240005424391">"%1$s से साझा करें"</string>
     <string name="whichSendApplicationLabel" msgid="4579076294675975354">"साझा करें"</string>
     <string name="whichSendToApplication" msgid="8272422260066642057">"इसका उपयोग करके भेजें"</string>
     <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"%1$s का उपयोग करके भेजें"</string>
     <string name="whichSendToApplicationLabel" msgid="8878962419005813500">"भेजें"</string>
-    <string name="whichHomeApplication" msgid="4307587691506919691">"होम ऐप्स चुनें"</string>
-    <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"होम के रूप में %1$s का उपयोग करें"</string>
+    <string name="whichHomeApplication" msgid="4307587691506919691">"होम ऐप चुनें"</string>
+    <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"होम पेज के के तौर पर %1$s का इस्तेमाल करें"</string>
     <string name="whichHomeApplicationLabel" msgid="809529747002918649">"चित्र कैप्चर करें"</string>
     <string name="whichImageCaptureApplication" msgid="3680261417470652882">"चित्र को इसके साथ कैप्चर करें"</string>
     <string name="whichImageCaptureApplicationNamed" msgid="8619384150737825003">"%1$s के साथ चित्र कैप्चर करें"</string>
     <string name="whichImageCaptureApplicationLabel" msgid="6390303445371527066">"चित्र कैप्चर करें"</string>
-    <string name="alwaysUse" msgid="4583018368000610438">"इस क्रिया के लिए डिफ़ॉल्‍ट रूप से उपयोग करें."</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"इस कार्रवाई के लिए डिफ़ॉल्‍ट के तौर पर इस्तेमाल करें"</string>
     <string name="use_a_different_app" msgid="8134926230585710243">"किसी भिन्न ऐप्स का उपयोग करें"</string>
-    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"सिस्‍टम सेटिंग &gt; Apps &gt; डाउनलोड किए गए में डिफ़ॉल्‍ट साफ करें."</string>
-    <string name="chooseActivity" msgid="7486876147751803333">"कोई क्रिया चुनें"</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"सिस्‍टम सेटिंग और डाउनलोड किए गए एेप में डिफ़ॉल्‍ट साफ़ करें."</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"कोई कार्रवाई चुनें"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"USB डिवाइस के लिए कोई ऐप्स  चुनें"</string>
     <string name="noApplications" msgid="2991814273936504689">"कोई भी ऐप्स यह कार्यवाही नहीं कर सकता."</string>
     <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> रुक गया है"</string>
@@ -1044,12 +1043,12 @@
     <string name="report" msgid="4060218260984795706">"रिपोर्ट करें"</string>
     <string name="wait" msgid="7147118217226317732">"प्रतीक्षा करें"</string>
     <string name="webpage_unresponsive" msgid="3272758351138122503">"पेज प्रतिसाद नहीं दे रहा है.\n\nक्‍या आप इसे बंद करना चाहते हैं?"</string>
-    <string name="launch_warning_title" msgid="1547997780506713581">"एप्‍लि. रीडायरेक्‍ट किया गया"</string>
+    <string name="launch_warning_title" msgid="1547997780506713581">"ऐप को दूसरे वेबलिंक पर लॉन्च किया गया"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> अभी चल रहा है."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> को वास्‍तविक रूप से लॉन्‍च किया गया था."</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"स्केल"</string>
     <string name="screen_compat_mode_show" msgid="4013878876486655892">"हमेशा दिखाएं"</string>
-    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"इसे सिस्‍टम सेटिंग &gt; Apps &gt; डाउनलोड किए गए में पुन: सक्षम करें."</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"इसे सिस्‍टम सेटिंग &gt; ऐप &gt; डाउनलोड किए गए में फिर से चालू करें."</string>
     <string name="unsupported_display_size_message" msgid="6545327290756295232">"<xliff:g id="APP_NAME">%1$s</xliff:g> वर्तमान स्क्रीन के आकार की सेटिंग का समर्थन नहीं करता है और अनपेक्षित रूप से व्यवहार कर सकता है."</string>
     <string name="unsupported_display_size_show" msgid="7969129195360353041">"हमेशा दिखाएं"</string>
     <string name="smv_application" msgid="3307209192155442829">"ऐप्स <xliff:g id="APPLICATION">%1$s</xliff:g> (प्रक्रिया <xliff:g id="PROCESS">%2$s</xliff:g>) ने उसकी स्‍वयं लागू होने वाली StrictMode नीति का उल्‍लंघन किया है."</string>
@@ -1058,7 +1057,7 @@
     <string name="android_start_title" msgid="8418054686415318207">"Android प्रारंभ हो रहा है…"</string>
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"मेमोरी ऑप्‍टिमाइज़ हो रही है."</string>
     <string name="android_upgrading_notification_title" msgid="8428357096969413169">"Android अपडेट समाप्त हो रहा है…"</string>
-    <string name="android_upgrading_notification_body" msgid="5761201379457064286">"जब तक अपग्रेड पूरा नहीं हो जाता, तब तक संभव है कि कुछ ऐप्लिकेशन ठीक से कार्य ना करें"</string>
+    <string name="android_upgrading_notification_body" msgid="5761201379457064286">"जब तक अपग्रेड पूरा नहीं हो जाता, हो सकता है कि तब तक कुछ ऐप्लिकेशन ठीक से काम ना करें"</string>
     <string name="app_upgrading_toast" msgid="3008139776215597053">"<xliff:g id="APPLICATION">%1$s</xliff:g> अपग्रेड हो रहा है…"</string>
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> में से <xliff:g id="NUMBER_0">%1$d</xliff:g> ऐप्स  अनुकूलित हो रहा है."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> तैयार हो रहा है."</string>
@@ -1070,13 +1069,13 @@
     <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"दूसरा ऐप्स  पहले से चल रहा है जिसे किसी नए ऐप्स को प्रारंभ करने के पहले बंद किया जाना आवश्‍यक है."</string>
     <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> पर वापस लौटें"</string>
     <string name="old_app_description" msgid="2082094275580358049">"नया ऐप्स प्रारंभ न करें."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> प्रारंभ करें"</string>
+    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> शुरू करें"</string>
     <string name="new_app_description" msgid="1932143598371537340">"पुराने ऐप्स को बिना सहेजे बंद करें."</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> मेमोरी सीमा को पार कर गई है"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"हीप डंप का संग्रह कर लिया गया है; शेयर करने के लिए टैप करें"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"हीप डंप साझा करें?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"प्रक्रिया <xliff:g id="PROC">%1$s</xliff:g> इसकी <xliff:g id="SIZE">%2$s</xliff:g> की मेमोरी की सीमा को पार कर गई है. इसके डेवलपर से साझा करने के लिए एक हीप डंप आपके लिए उपलब्ध है. सावधान रहें: इस हीप डंप में आपकी ऐसी कोई भी व्यक्तिगत जानकारी हो सकती है जिस पर ऐप्लिकेशन की ऐक्सेस हो."</string>
-    <string name="sendText" msgid="5209874571959469142">"लेख के लिए किसी क्रिया को चुनें"</string>
+    <string name="dump_heap_text" msgid="4809417337240334941">"यह प्रक्रिया <xliff:g id="PROC">%1$s</xliff:g> इसकी <xliff:g id="SIZE">%2$s</xliff:g> की मेमोरी की सीमा को पार कर गई है. एक हीप डंप मौजूद है जिसे आप इसके डेवलपर से शेयर कर सकते हैं. सावधान रहें: इस हीप डंप में आपकी ऐसी कोई भी निजी जानकारी हो सकती है जिस पर ऐप्लिकेशन की पहुंच हो."</string>
+    <string name="sendText" msgid="5209874571959469142">"मैसेज करने के लिए कोई कार्रवाई चुनें"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"रिंगर वॉल्‍यूम"</string>
     <string name="volume_music" msgid="5421651157138628171">"मीडिया वॉल्‍यूम"</string>
     <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"ब्लूटूथ द्वारा चलाया जा रहा है"</string>
@@ -1084,19 +1083,19 @@
     <string name="volume_call" msgid="3941680041282788711">"कॉल के दौरान वॉल्‍यूम"</string>
     <string name="volume_bluetooth_call" msgid="2002891926351151534">"ब्लूटूथ कॉल के दौरान वॉल्‍यूम"</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">"ब्लूटूथ वॉल्‍यूम"</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>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"रिंगटोन"</string>
     <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"अलार्म ध्वनियां"</string>
-    <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"नोटिफ़िकेशन ध्‍वनि"</string>
+    <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"सूचना की आवाज़"</string>
     <string name="ringtone_unknown" msgid="3914515995813061520">"अज्ञात"</string>
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">वाई-फ़ाई नेटवर्क उपलब्‍ध</item>
@@ -1106,14 +1105,21 @@
       <item quantity="one">खुले वाई-फ़ाई नेटवर्क उपलब्‍ध</item>
       <item quantity="other">खुले वाई-फ़ाई नेटवर्क उपलब्‍ध</item>
     </plurals>
-    <string name="wifi_available_sign_in" msgid="9157196203958866662">"वाई-फ़ाई  नेटवर्क में प्रवेश करें"</string>
-    <string name="network_available_sign_in" msgid="1848877297365446605">"नेटवर्क में प्रवेश करें"</string>
+    <string name="wifi_available_title" msgid="3817100557900599505">"खुले वाई-फ़ाई नेटवर्क से कनेक्ट करें"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"खुले वाई-फ़ाई नेटवर्क से कनेक्ट हो रहा है"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"वाई-फ़ाई नेटवर्क से कनेक्‍ट हो गया है"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"वाई-फ़ाई  नेटवर्क से कनेक्‍ट नहीं हो सका"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सभी नेटवर्क देखने के लिए यहां पर टैप करें"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"कनेक्ट करें"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"सभी नेटवर्क"</string>
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"वाई-फ़ाई  नेटवर्क में साइन इन करें"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"नेटवर्क में साइन इन करें"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_no_internet" msgid="8451173622563841546">"वाई-फ़ाई में कोई इंटरनेट ऐक्‍सेस नहीं है"</string>
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"विकल्पों के लिए टैप करें"</string>
     <string name="network_switch_metered" msgid="4671730921726992671">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> पर ले जाया गया"</string>
-    <string name="network_switch_metered_detail" msgid="5325661434777870353">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> में कोई इंटरनेट एक्‍सेस नहीं होने पर डिवाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> का उपयोग करता है. शुल्क लिया जा सकता है."</string>
+    <string name="network_switch_metered_detail" msgid="5325661434777870353">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> में कोई इंटरनेट की सुविधा नहीं होने पर डिवाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> का इस्तेमाल करता है. इसके लिए शुल्क लिया जा सकता है."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> से <xliff:g id="NEW_NETWORK">%2$s</xliff:g> पर ले जाया गया"</string>
   <string-array name="network_switch_type_name">
     <item msgid="3979506840912951943">"मोबाइल डेटा"</item>
@@ -1129,7 +1135,7 @@
     <string name="wifi_connect_alert_message" msgid="6451273376815958922">"%1$s ऐप्‍लिकेशन %2$s वाई-फ़ाई नेटवर्क से कनेक्‍ट करना चाहता है"</string>
     <string name="wifi_connect_default_application" msgid="7143109390475484319">"ऐप्लिकेशन"</string>
     <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"वाई-फ़ाई डायरेक्ट"</string>
-    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"वाई-फ़ाई  डायरेक्ट प्रारंभ करें. इससे वाई-फ़ाई  क्‍लाइंट/हॉटस्पॉट कार्यवाही बंद हो जाएगी."</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"वाई-फ़ाई डायरेक्ट चालू करें. इससे वाई-फ़ाई क्‍लाइंट/हॉटस्पॉट कार्यवाही बंद हो जाएगी."</string>
     <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"वाई-फ़ाई  डायरेक्ट प्रारंभ नहीं किया जा सका."</string>
     <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"वाई-फ़ाई डायरेक्ट चालू है"</string>
     <string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"सेटिंग के लिए टैप करें"</string>
@@ -1141,38 +1147,38 @@
     <string name="wifi_p2p_to_message" msgid="248968974522044099">"प्रति:"</string>
     <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"आवश्‍यक पिन लिखें:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"पिन:"</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> से कनेक्ट रहने पर टेबलेट वाई-फ़ाई  से अस्थायी रूप से डिसकनेक्ट हो जाएगा"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> से कनेक्ट रहने पर टैबलेट वाई-फ़ाई  से अस्थायी रूप से डिसकनेक्ट हो जाएगा"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"जब टीवी <xliff:g id="DEVICE_NAME">%1$s</xliff:g> से कनेक्‍ट होगा तब वह वाई-फ़ाई से अस्‍थायी रूप से डिस्‍कनेक्‍ट हो जाएगा"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"फ़ोन <xliff:g id="DEVICE_NAME">%1$s</xliff:g> से कनेक्ट रहते समय वाई-फ़ाई  से अस्थायी रूप से डिसकनेक्ट हो जाएगा"</string>
     <string name="select_character" msgid="3365550120617701745">"वर्ण सम्‍मिलित करें"</string>
-    <string name="sms_control_title" msgid="7296612781128917719">"SMS संदेश भेज रहा है"</string>
-    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; बड़ी संख्या में SMS संदेश भेज रहा है. क्या आप इस ऐप्स  को संदेश भेजना जारी रखने देना चाहते हैं?"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"मैसेज (एसएमएस) भेज रहा है"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; बड़ी संख्या में मैसेज (एसएमएस) भेज रहा है. क्या आप इस ऐप को मैसेज भेजना जारी रखने देना चाहते हैं?"</string>
     <string name="sms_control_yes" msgid="3663725993855816807">"अनुमति दें"</string>
     <string name="sms_control_no" msgid="625438561395534982">"अस्वीकार करें"</string>
     <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;, &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; पर संदेश भेजना चाहता है."</string>
     <string name="sms_short_code_details" msgid="5873295990846059400">"इससे आपके मोबाइल खाते पर "<b>"शुल्क लग सकता है"</b>"."</string>
     <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"इससे आपके मोबाइल खाते पर शुल्क लगेगा."</b></string>
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"भेजें"</string>
-    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"अभी नहीं"</string>
+    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"रद्द करें"</string>
     <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"मेरी पसंद को याद रखें"</string>
     <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"आप इसे बाद में सेटिंग &gt; ऐप्स  में बदल सकते हैं"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"हमेशा अनुमति दें"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"कभी भी अनुमति न दें"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"सिमकार्ड निकाला गया"</string>
     <string name="sim_removed_message" msgid="2333164559970958645">"मान्‍य सि‍म कार्ड डालकर पुन: प्रारंभ करने तक मोबाइल नेटवर्क अनुपलब्‍ध रहेगा."</string>
-    <string name="sim_done_button" msgid="827949989369963775">"पूर्ण"</string>
+    <string name="sim_done_button" msgid="827949989369963775">"हो गया"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"सिम कार्ड जोड़ा गया"</string>
-    <string name="sim_added_message" msgid="6599945301141050216">"मोबाइल नेटवर्क पर पहुंचने के लिए अपना डिवाइस पुन: प्रारंभ करें."</string>
-    <string name="sim_restart_button" msgid="4722407842815232347">"पुन: प्रारंभ करें"</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"मोबाइल नेटवर्क की पहुंच पाने लिए अपना डिवाइस फिर से चालू करें."</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"फिर से शुरू करें"</string>
     <string name="carrier_app_dialog_message" msgid="7066156088266319533">"आपका नया SIM ठीक से काम करे, इसके लिए आपको अपनी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से कोई ऐप इंस्टॉल करना होगा और उसे खोलना होगा."</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"ऐप प्राप्त करें"</string>
-    <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"अभी नहीं"</string>
+    <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"रद्द करें"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"नई SIM डाली गई"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"इसे सेट करने के लिए टैप करें"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"समय सेट करें"</string>
-    <string name="date_picker_dialog_title" msgid="5879450659453782278">"दिनांक सेट करें"</string>
+    <string name="date_picker_dialog_title" msgid="5879450659453782278">"तारीख सेट करें"</string>
     <string name="date_time_set" msgid="5777075614321087758">"सेट करें"</string>
-    <string name="date_time_done" msgid="2507683751759308828">"पूर्ण"</string>
+    <string name="date_time_done" msgid="2507683751759308828">"हो गया"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"नया: "</font></string>
     <string name="perms_description_app" msgid="5139836143293299417">"<xliff:g id="APP_NAME">%1$s</xliff:g> द्वारा प्रदत्त."</string>
     <string name="no_permissions" msgid="7283357728219338112">"किसी अनुमति की आवश्‍यकता नहीं है"</string>
@@ -1184,14 +1190,16 @@
     <string name="usb_ptp_notification_title" msgid="1347328437083192112">"फ़ोटो स्‍थानांतरण के लिए USB"</string>
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI के लिए USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB सहायक सामग्री से कनेक्‍ट कि‍या गया"</string>
-    <string name="usb_notification_message" msgid="3370903770828407960">"अधिक विकल्पों के लिए टैप करें."</string>
+    <string name="usb_notification_message" msgid="3370903770828407960">"ज़्यादा विकल्पों के लिए टैप करें."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"एनालॉग ऑडियो एक्सेसरी का पता चला"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"अटैच किया गया डिवाइस इस फ़ोन से संगत नहीं है. अधिक जानने के लिए टैप करें."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग कनेक्ट किया गया"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB डीबग करना अक्षम करने के लिए टैप करें."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डीबग करना अक्षम करने के लिए चुनें."</string>
-    <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"बग रिपोर्ट प्राप्त की जा रही है…"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग रिपोर्ट साझा करें?"</string>
-    <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"बग रिपोर्ट साझा की जा रही है…"</string>
-    <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"आपके व्यवस्थापक ने इस डिवाइस के समस्या निवारण में सहायता के लिए एक बग रिपोर्ट का अनुरोध किया है. ऐप्लिकेशन और डेटा साझा किए जा सकते हैं."</string>
+    <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"गड़बड़ी की रिपोर्ट ली जा रही है…"</string>
+    <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"गड़बड़ी की रिपोर्ट शेयर करें?"</string>
+    <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"गड़बड़ी की रिपोर्ट शेयर की जा रही है…"</string>
+    <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"आपके एडमिन ने इस डिवाइस की समस्या को हल करने में सहायता के लिए एक गड़बड़ी की रिपोर्ट का अनुरोध किया है. ऐप्लिकेशन और डेटा शेयर किए जा सकते हैं."</string>
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"साझा करें"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"अस्वीकार करें"</string>
     <string name="select_input_method" msgid="8547250819326693584">"कीबोर्ड बदलें"</string>
@@ -1201,7 +1209,7 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"भाषा और लेआउट चुनने के लिए टैप करें"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"दूसरे ऐप्लिकेशन के ऊपर दिखाएं"</string>
+    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"दूसरे ऐप के ऊपर दिखाएं"</string>
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> अन्य ऐप्लिकेशन के ऊपर दिखाई दे रहा है"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> अन्य ऐप पर दिखाई दे रहा है"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"अगर आप नहीं चाहते कि <xliff:g id="NAME">%s</xliff:g> इस सुविधा का उपयोग करे, तो सेटिंग खोलने और उसे बंद करने के लिए टैप करें."</string>
@@ -1232,7 +1240,7 @@
     <string name="ext_media_move_success_title" msgid="8575300932957954671">"ले जाना पूर्ण हुआ"</string>
     <string name="ext_media_move_success_message" msgid="4199002148206265426">"डेटा को <xliff:g id="NAME">%s</xliff:g> पर ले जाया गया"</string>
     <string name="ext_media_move_failure_title" msgid="7613189040358789908">"डेटा नहीं ले जाया जा सका"</string>
-    <string name="ext_media_move_failure_message" msgid="1978096440816403360">"डेटा मूल स्‍थान पर छूट गया है"</string>
+    <string name="ext_media_move_failure_message" msgid="1978096440816403360">"डेटा शुरुआती जगह पर छूट गया है"</string>
     <string name="ext_media_status_removed" msgid="6576172423185918739">"निकाल दिया गया"</string>
     <string name="ext_media_status_unmounted" msgid="2551560878416417752">"निकाला गया"</string>
     <string name="ext_media_status_checking" msgid="6193921557423194949">"जांच की जा रही है..."</string>
@@ -1258,17 +1266,17 @@
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"ज़ूम नियंत्रण के लिए दो बार टैप करें"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"विजेट नहीं जोड़ा जा सका."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"जाएं"</string>
-    <string name="ime_action_search" msgid="658110271822807811">"खोजें"</string>
+    <string name="ime_action_search" msgid="658110271822807811">"सर्च करें"</string>
     <string name="ime_action_send" msgid="2316166556349314424">"भेजें"</string>
     <string name="ime_action_next" msgid="3138843904009813834">"आगे"</string>
-    <string name="ime_action_done" msgid="8971516117910934605">"पूर्ण"</string>
-    <string name="ime_action_previous" msgid="1443550039250105948">"पिछला"</string>
+    <string name="ime_action_done" msgid="8971516117910934605">"हो गया"</string>
+    <string name="ime_action_previous" msgid="1443550039250105948">"पीछे जाएं"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"निष्‍पादित करें"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"<xliff:g id="NUMBER">%s</xliff:g> के उपयोग द्वारा \n नंबर डायल करें"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g> का उपयोग करके\n संपर्क बनाएं"</string>
-    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"निम्‍न एक या अधिक ऐप्स अभी और भविष्‍य में आपके खाते में पहुंच की अनुमति का अनुरोध करते हैं."</string>
-    <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"क्या आप इस अनुरोध को अनुमति देना चाहते हैं?"</string>
-    <string name="grant_permissions_header_text" msgid="6874497408201826708">"पहुंच अनुरोध"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"इनमें से एक या अधिक ऐप, अभी और आने वाले समय में आपके खाते तक पहुंचने की अनुमति चाहते हैं."</string>
+    <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"क्या आप इस अनुरोध की अनुमति देना चाहते हैं?"</string>
+    <string name="grant_permissions_header_text" msgid="6874497408201826708">"पहुंच पाने का अनुरोध"</string>
     <string name="allow" msgid="7225948811296386551">"अनुमति दें"</string>
     <string name="deny" msgid="2081879885755434506">"अस्वीकारें"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"अनुमति अनुरोधित"</string>
@@ -1280,19 +1288,19 @@
     <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>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"सूचना को सुनने की सुविधा"</string>
     <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR श्रोता"</string>
     <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"स्थिति प्रदाता"</string>
-    <string name="notification_ranker_binding_label" msgid="774540592299064747">"नोटिफ़िकेशन रैंकर सेवा"</string>
+    <string name="notification_ranker_binding_label" msgid="774540592299064747">"सूचना रैंकर सेवा"</string>
     <string name="vpn_title" msgid="19615213552042827">"VPN सक्रिय"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN को <xliff:g id="APP">%s</xliff:g> द्वारा सक्रिय किया गया है"</string>
     <string name="vpn_text" msgid="1610714069627824309">"नेटवर्क प्रबंधित करने के लिए टैप करें."</string>
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> से कनेक्‍ट किया गया. नेटवर्क प्रबंधित करने के लिए टैप करें."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"हमेशा-चालू VPN कनेक्ट हो रहा है…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"हमेशा-चालू VPN कनेक्ट है"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"हमेशा-चालू VPN डिस्‍कनेक्‍ट है"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"हमेशा चालू रहने वाले VPN से डिसकनेक्ट किया गया"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"हमेशा-चालू VPN गड़बड़ी"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"सेट करने के लिए टैप करें"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"नेटवर्क या VPN सेटिंग बदलें"</string>
     <string name="upload_file" msgid="2897957172366730416">"फ़ाइल चुनें"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"कोई फ़ाइल चुनी नहीं गई"</string>
     <string name="reset" msgid="2448168080964209908">"रीसेट करें"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"कार मोड से बाहर निकलने के लिए टैप करें."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग या हॉटस्‍पॉट सक्रिय"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करने के लिए टैप करें."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग अक्षम है"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"जानकारी के लिए अपने व्यवस्थापक से संपर्क करें"</string>
     <string name="back_button_label" msgid="2300470004503343439">"वापस जाएं"</string>
     <string name="next_button_label" msgid="1080555104677992408">"आगे"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"अभी नहीं"</string>
@@ -1312,22 +1318,22 @@
       <item quantity="one"><xliff:g id="TOTAL">%d</xliff:g> में से <xliff:g id="INDEX">%d</xliff:g></item>
       <item quantity="other"><xliff:g id="TOTAL">%d</xliff:g> में से <xliff:g id="INDEX">%d</xliff:g></item>
     </plurals>
-    <string name="action_mode_done" msgid="7217581640461922289">"पूर्ण"</string>
+    <string name="action_mode_done" msgid="7217581640461922289">"हो गया"</string>
     <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB मेमोरी मिटाया जा रहा है…"</string>
     <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD कार्ड मिटाया जा रहा है…"</string>
     <string name="share" msgid="1778686618230011964">"साझा करें"</string>
     <string name="find" msgid="4808270900322985960">"ढूंढें"</string>
-    <string name="websearch" msgid="4337157977400211589">"वेब खोज"</string>
+    <string name="websearch" msgid="4337157977400211589">"वेब सर्च"</string>
     <string name="find_next" msgid="5742124618942193978">"आगे ढूंढें"</string>
     <string name="find_previous" msgid="2196723669388360506">"पिछला ढूंढें"</string>
-    <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> की ओर से स्‍थान अनुरोध"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"स्‍थान अनुरोध"</string>
+    <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> ने जगह का अनुरोध किया गया है"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"जगह का अनुरोध किया जा रहा है"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) द्वारा अनुरोधित"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"हां"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"नहीं"</string>
     <string name="sync_too_many_deletes" msgid="5296321850662746890">"हटाने की सीमा पार हो गई"</string>
     <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> खाते के <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> आइटम हटा दिए गए हैं. आप क्‍या करना चाहते हैं?"</string>
-    <string name="sync_really_delete" msgid="2572600103122596243">"आइटम हटाएं"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"आइटम मिटाएं"</string>
     <string name="sync_undo_deletes" msgid="2941317360600338602">"हटाए गए को वापस लाएं"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"फिलहाल कुछ न करें"</string>
     <string name="choose_account_label" msgid="5655203089746423927">"खाता चुनें"</string>
@@ -1352,9 +1358,9 @@
     <string name="date_picker_prev_month_button" msgid="2858244643992056505">"पिछला महीना"</string>
     <string name="date_picker_next_month_button" msgid="5559507736887605055">"अगला महीना"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
-    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"अभी नहीं"</string>
-    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"हटाएं"</string>
-    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"पूर्ण"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"रद्द करें"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"मिटाएं"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"हो गया"</string>
     <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mode change"</string>
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
@@ -1364,9 +1370,9 @@
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> के साथ साझा करें"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"स्लाइडिंग हैंडल. दबाकर रखें."</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"अनलॉक करने के लिए स्‍वाइप करें."</string>
-    <string name="action_bar_home_description" msgid="5293600496601490216">"होम पर नेविगेट करें"</string>
-    <string name="action_bar_up_description" msgid="2237496562952152589">"ऊपर नेविगेट करें"</string>
-    <string name="action_menu_overflow_description" msgid="2295659037509008453">"अधिक विकल्प"</string>
+    <string name="action_bar_home_description" msgid="5293600496601490216">"होम पेज पर जाएं"</string>
+    <string name="action_bar_up_description" msgid="2237496562952152589">"ऊपर जाएं"</string>
+    <string name="action_menu_overflow_description" msgid="2295659037509008453">"ज़्यादा विकल्प"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
     <string name="storage_internal" msgid="3570990907910199483">"आंतरिक साझा मेमोरी"</string>
@@ -1375,7 +1381,7 @@
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB डिस्‍क"</string>
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB डिस्‍क"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB मेमोरी"</string>
-    <string name="extract_edit_menu_button" msgid="8940478730496610137">"संपादित करें"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"बदलाव करें"</string>
     <string name="data_usage_warning_title" msgid="3620440638180218181">"डेटा खर्च की चेतावनी"</string>
     <string name="data_usage_warning_body" msgid="6660692274311972007">"उपयोग व सेटिंग देखने हेतु टैप करें."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"2G-3G डेटा सीमा पूर्ण हो गई"</string>
@@ -1413,7 +1419,7 @@
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"हमेशा"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"केवल एक बार"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s कार्य प्रोफ़ाइल का समर्थन नहीं करता"</string>
-    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"टेबलेट"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"टैबलेट"</string>
     <string name="default_audio_route_name" product="tv" msgid="9158088547603019321">"टीवी"</string>
     <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"फ़ोन"</string>
     <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"हेडफ़ोन"</string>
@@ -1421,7 +1427,7 @@
     <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"सिस्‍टम"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"ब्लूटूथ ऑडियो"</string>
-    <string name="wireless_display_route_description" msgid="9070346425023979651">"वायरलेस प्रदर्शन"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"वायरलेस डिसप्ले"</string>
     <string name="media_route_button_content_description" msgid="591703006349356016">"कास्ट करें"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"डिवाइस से कनेक्ट करें"</string>
     <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"स्क्रीन को डिवाइस में कास्ट करें"</string>
@@ -1457,45 +1463,45 @@
     <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>
-    <string name="kg_login_instructions" msgid="1100551261265506448">"अनलॉक करने के लिए, अपने Google खाते से प्रवेश करें."</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"अनलॉक करने के लिए, अपने Google खाते से साइन इन करें."</string>
     <string name="kg_login_username_hint" msgid="5718534272070920364">"उपयोगकर्ता नाम (ईमेल)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"पासवर्ड"</string>
-    <string name="kg_login_submit_button" msgid="5355904582674054702">"प्रवेश करें"</string>
-    <string name="kg_login_invalid_input" msgid="5754664119319872197">"अमान्य उपयोगकर्ता नाम या पासवर्ड."</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"साइन इन करें"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"उपयोगकर्ता नाम या पासवर्ड गलत है"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"अपना उपयोगकर्ता नाम या पासवर्ड भूल गए?\n "<b>"google.com/accounts/recovery"</b>" पर जाएं."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"खाते की जांच की जा रही है…"</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"आप अपना PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से लिख चुके हैं. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"आप अपना पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से लिख चुके हैं. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"आपने अपना अनलॉक आकार <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से आरेखित किया है. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"आप टेबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल प्रयासों के बाद, टेबलेट फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"आपने टीवी को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से प्रयास किया है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल प्रयासों के बाद, टीवी को फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट कर दिया जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"आप फ़ोन को अनलॉक करने के लिए <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="2072996269148483637">"आप टेबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. टेबलेट अब फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"आप टैबलेट का लॉक खोलने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश कर चुके हैं. <xliff:g id="NUMBER_1">%2$d</xliff:g> बार और गलत कोशिश करने पर, टैबलेट फ़ैक्ट्री डिफ़ॉल्ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"आप टीवी का लॉक खोलने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश कर चुके हैं. <xliff:g id="NUMBER_1">%2$d</xliff:g> बार और गलत कोशिश करने पर टीवी को फ़ैक्ट्री डिफ़ॉल्‍ट पर रीसेट कर दिया जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"आप फ़ोन का लॉक खोलने के लिए <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="2072996269148483637">"आप टैबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. टैबलेट अब फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"आपने टीवी को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से प्रयास किया है. अब टीवी को फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट कर दिया जाएगा."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"आप फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. फ़ोन अब फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"आपने अपने अनलॉक आकार को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने टेबलेट को किसी ईमेल खाते के उपयोग से अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"आपने अपने अनलॉक आकार को <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="tv" msgid="4224651132862313471">"आपने अपने लॉक खोलने के पैटर्न को <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="1437638152015574839">"आपने अपने अनलॉक आकार को <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_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"निकालें"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"वॉल्यूम को सुझाए गए स्तर से ऊपर बढ़ाएं?\n\nअत्यधिक वॉल्यूम पर अधिक समय तक सुनने से आपकी सुनने की क्षमता को नुकसान हो सकता है."</string>
-    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"एक्सेस-योग्यता शॉर्टकट का उपयोग करना चाहते हैं?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"इस शॉर्टकट के चालू होने पर, दोनों वॉल्यूम बटनों को 3 सेकंड तक दबाने से एक्सेस-योग्यता सुविधा शुरू हो जाएगी.\n\n अभी वाली एक्सेस-योग्यता सुविधा:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n आप इस सुविधा को सेटिंग &gt; एक्सेस-योग्यता पर जाकर बदल सकते हैं."</string>
+    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"सुलभता शॉर्टकट का इस्तेमाल करना चाहते हैं?"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"इस शॉर्टकट के चालू होने पर, दोनों वॉल्यूम बटनों को 3 सेकंड तक दबाने से सुलभता सुविधा शुरू हो जाएगी.\n\n मौजूदा सुलभता सुविधा:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n आप इस सुविधा को सेटिंग &gt; सुलभता पर जाकर बदल सकते हैं."</string>
     <string name="disable_accessibility_shortcut" msgid="627625354248453445">"शॉर्टकट बंद करें"</string>
     <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"शॉर्टकट का उपयोग करें"</string>
-    <string name="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_button_prompt_text" msgid="4234556536456854251">"एक्सेस-योग्यता बटन पर टैप करते समय उपयोग की जाने वाली सुविधा चुनें:"</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_button_prompt_text" msgid="4234556536456854251">"सुलभता बटन पर टैप करते समय इस्तेमाल की जाने वाली सुविधा चुनें:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"सुविधाओं में बदलाव करने के लिए, सुलभता बटन को दबाकर रखें."</string>
-    <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"आवर्धन"</string>
-    <string name="user_switched" msgid="3768006783166984410">"वर्तमान उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"बड़ा करें"</string>
+    <string name="user_switched" msgid="3768006783166984410">"मौजूदा उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> पर स्विच किया जा रहा है…"</string>
     <string name="user_logging_out_message" msgid="8939524935808875155">"<xliff:g id="NAME">%1$s</xliff:g> द्वारा प्रस्‍थान किया जा रहा है…"</string>
     <string name="owner_name" msgid="2716755460376028154">"स्वामी"</string>
     <string name="error_message_title" msgid="4510373083082500195">"गड़बड़ी"</string>
     <string name="error_message_change_not_allowed" msgid="1238035947357923497">"आपका व्यवस्थापक इस बदलाव की अनुमति नहीं देता"</string>
     <string name="app_not_found" msgid="3429141853498927379">"इस कार्यवाही को प्रबंधित करने के लिए कोई ऐप्स  नहीं मिला"</string>
-    <string name="revoke" msgid="5404479185228271586">"निरस्‍त करें"</string>
+    <string name="revoke" msgid="5404479185228271586">"रद्द करें"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
     <string name="mediasize_iso_a1" msgid="3333060421529791786">"ISO A1"</string>
     <string name="mediasize_iso_a2" msgid="3097535991925798280">"ISO A2"</string>
@@ -1584,7 +1590,7 @@
     <string name="reason_unknown" msgid="6048913880184628119">"अज्ञात"</string>
     <string name="reason_service_unavailable" msgid="7824008732243903268">"प्रिंट सेवा सक्षम नहीं है"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> सेवा इंस्टॉल की गई"</string>
-    <string name="print_service_installed_message" msgid="5897362931070459152">"सक्षम करने के लिए टैप करें"</string>
+    <string name="print_service_installed_message" msgid="5897362931070459152">"चालू करने के लिए टैप करें"</string>
     <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"व्यवस्थापक पिन डालें"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN डालें"</string>
     <string name="restr_pin_incorrect" msgid="8571512003955077924">"गलत"</string>
@@ -1592,17 +1598,17 @@
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"नया पिन"</string>
     <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"नए पिन की दुबारा पूछें"</string>
     <string name="restr_pin_create_pin" msgid="8017600000263450337">"प्रतिबंधों को बदलने के लिए PIN बनाएं"</string>
-    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN मिलान नहीं करते हैं. फिर से प्रयास करें."</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN मेल नहीं खाते हैं. फिर से कोशिश करें."</string>
     <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN बहुत छोटा है. कम से कम 4 अंकों का होना चाहिए."</string>
     <plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
       <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> सेकंड में पुन: प्रयास करें</item>
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> सेकंड में पुन: प्रयास करें</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"बाद में फिर से प्रयास करें"</string>
-    <string name="immersive_cling_title" msgid="8394201622932303336">"पूर्ण स्क्रीन में देखें"</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"पूरे स्क्रीन पर देखें"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"बाहर निकलने के लिए, ऊपर से नीचे स्वा‍इप करें."</string>
-    <string name="immersive_cling_positive" msgid="5016839404568297683">"समझ लिया"</string>
-    <string name="done_label" msgid="2093726099505892398">"पूर्ण"</string>
+    <string name="immersive_cling_positive" msgid="5016839404568297683">"ठीक है"</string>
+    <string name="done_label" msgid="2093726099505892398">"हो गया"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"घंटो का चक्राकार स्लाइडर"</string>
     <string name="minute_picker_description" msgid="8606010966873791190">"मिनटों का चक्राकार स्लाइडर"</string>
     <string name="select_hours" msgid="6043079511766008245">"घंटे चुनें"</string>
@@ -1623,8 +1629,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" msgid="1960431123816253034">"बैटरी लाइफ़ बेहतर बनाने में सहायता के लिए, बैटरी सेवर आपके डिवाइस के प्रदर्शन को कम कर देता है और कंपन, स्‍थान सेवाओं और अधिकांश पृष्‍ठभूमि डेटा को सीमित कर देता है. हो सकता है कि ईमेल, संदेश सेवा और सिंक पर आधारित अन्‍य ऐप्‍स तब तक ना खुलें जब तक कि आप उन्‍हें नहीं खोलते.\n\nजब आपका डिवाइस चार्ज हो रहा होता है तो बैटरी सेवर अपने आप बंद हो जाता है."</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"डेटा खर्च, कम करने के लिए डेटा सेवर कुछ ऐप को बैकग्राउंड में डेटा भेजने या पाने से रोकता है. आप फ़िलहाल जिस एेप का इस्तेमाल कर रहे हैं वह डेटा एक्सेस कर सकता है, लेकिन ऐसा कभी-कभी ही हो पाएगा. उदाहरण के लिए, इसका मतलब है कि इमेज तब तक दिखाई नहीं देंगी जब तक कि आप उन्हें टैप नहीं करते."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"बैटरी लाइफ़ को बेहतर बनाने में मदद करने के लिए, बैटरी सेवर आपके डिवाइस के प्रदर्शन को कम कर देता है और कंपन (वाइब्रेशन), स्‍थान सेवाओं और ज़्यादातर बैकग्राउंड डेटा को सीमित कर देता है. हो सकता है कि ईमेल, मैसेज सेवा और सिंक पर आधारित अन्‍य ऐप तब तक ना खुलें जब तक कि आप उन्‍हें नहीं खोलते.\n\nजब आपका डिवाइस चार्ज हो रहा होता है तो बैटरी सेवर अपने आप बंद हो जाता है."</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"डेटा खर्च, कम करने के लिए डेटा सेवर कुछ ऐप को बैकग्राउंड में डेटा भेजने या पाने से रोकता है. आप फ़िलहाल जिस एेप का इस्तेमाल कर रहे हैं वह डेटा तक पहुंच सकता है, लेकिन ऐसा कभी-कभी ही हो पाएगा. उदाहरण के लिए, इसे समझिये कि तस्वीर तब तक दिखाई नहीं देंगी जब तक कि आप उन्हें टैप नहीं करते."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"डेटा बचाने की सेटिंग चालू करें?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"चालू करें"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
@@ -1664,7 +1670,7 @@
     <string name="zen_mode_forever" msgid="1916263162129197274">"जब तक कि आप परेशान ना करें को बंद नहीं कर देते"</string>
     <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"जब तक कि आप परेशान ना करें को बंद नहीं कर देते"</string>
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
-    <string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त करें"</string>
+    <string name="toolbar_collapse_description" msgid="2821479483960330739">"छोटा करें"</string>
     <string name="zen_mode_feature_name" msgid="5254089399895895004">"परेशान ना करें"</string>
     <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"बंद रहने का समय"</string>
     <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"सप्ताह की रात"</string>
@@ -1680,13 +1686,13 @@
     <string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS अनुरोध को USSD अनुरोध में बदल दिया गया है."</string>
     <string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS अनुरोध को नए SS अनुरोध में बदल दिया गया है."</string>
     <string name="notification_work_profile_content_description" msgid="4600554564103770764">"कार्य प्रोफ़ाइल"</string>
-    <string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"विस्तृत करें"</string>
-    <string name="expand_button_content_description_expanded" msgid="8520652707158554895">"संक्षिप्त करें"</string>
+    <string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"विस्तार करें"</string>
+    <string name="expand_button_content_description_expanded" msgid="8520652707158554895">"छोटा करें"</string>
     <string name="expand_action_accessibility" msgid="5307730695723718254">"टॉगल विस्तार"</string>
     <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB पेरिफ़ेरल पोर्ट"</string>
     <string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
     <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB पेरिफ़ेरल पोर्ट"</string>
-    <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"अधिक विकल्प"</string>
+    <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"ज़्यादा विकल्प"</string>
     <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"ओवरफ़्लो बंद करें"</string>
     <string name="maximize_button_text" msgid="7543285286182446254">"बड़ा करें"</string>
     <string name="close_button_text" msgid="3937902162644062866">"बंद करें"</string>
@@ -1696,22 +1702,22 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> चयनित</item>
     </plurals>
     <string name="default_notification_channel_label" msgid="5929663562028088222">"अवर्गीकृत"</string>
-    <string name="importance_from_user" msgid="7318955817386549931">"आपने इन नोटिफ़िकेशन का महत्व सेट किया है."</string>
+    <string name="importance_from_user" msgid="7318955817386549931">"आपने इन सूचनाओं की अहमियत सेट की है."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"यह मौजूद व्यक्तियों के कारण महत्वपूर्ण है."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के द्वारा एक नया उपयोगकर्ता बनाने दें?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के द्वारा एक नया उपयोगकर्ता बनाने दें (इस खाते वाला एक उपयोगकर्ता पहले से मौजूद है) ?"</string>
+    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के ज़रिये एक नया उपयोगकर्ता बनाने दें?"</string>
+    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के ज़रिये एक नया उपयोगकर्ता बनाने दें (इस खाते वाले एक उपयोगकर्ता पहले से मौजूद हैं)?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"भाषा जोड़ें"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"क्षेत्र प्राथमिकता"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"भाषा का नाम लिखें"</string>
     <string name="language_picker_section_suggested" msgid="8414489646861640885">"सुझाए गए"</string>
     <string name="language_picker_section_all" msgid="3097279199511617537">"सभी भाषाएं"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"सभी क्षेत्र"</string>
-    <string name="locale_search_menu" msgid="2560710726687249178">"खोजें"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"सर्च करें"</string>
     <string name="work_mode_off_title" msgid="2615362773958585967">"कार्य मोड चालू करें?"</string>
     <string name="work_mode_off_message" msgid="2961559609199223594">"इससे आपकी कार्य प्रोफ़ाइल चालू हो जाएगी, जिसमें ऐप्लिकेशन, बैकग्राउंड सिंक और संबंधित सुविधाएं शामिल हैं"</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"चालू करें"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"आपके पास नए संदेश हैं"</string>
-    <string name="new_sms_notification_content" msgid="7002938807812083463">"देखने के लिए SMS ऐप खोलें"</string>
+    <string name="new_sms_notification_content" msgid="7002938807812083463">"देखने के लिए मैसेज (एसएमएस) ऐप खोलें"</string>
     <string name="user_encrypted_title" msgid="9054897468831672082">"कुछ कार्य क्षमताएं सीमित हो सकती हैं"</string>
     <string name="user_encrypted_message" msgid="4923292604515744267">"अनलॉक करने के लिए टैप करें"</string>
     <string name="user_encrypted_detail" msgid="5708447464349420392">"उपयोगकर्ता डेटा लॉक किया गया"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"अनपिन करें"</string>
     <string name="app_info" msgid="6856026610594615344">"ऐप की जानकारी"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"डिवाइस रीसेट करें?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"डिवाइस को रीसेट करने के लिए टैप करें"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"डेमो प्रारंभ हो रहा है…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"डिवाइस पुन: रीसेट कर रहा है…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"डिवाइस रीसेट करें?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"आपके सभी बदलाव खो जाएंगे और डेमो <xliff:g id="TIMEOUT">%1$s</xliff:g> सेकंड में फिर से शुरू हो जाएगा…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"अभी नहीं"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"अभी रीसेट करें"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"अक्षम <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"कॉन्फ़्रेंस कॉल"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"टूलटिप"</string>
@@ -1752,28 +1752,29 @@
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"समय इनपुट के लिए लेख इनपुट मोड पर जाएं."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"समय इनपुट के लिए घड़ी मोड पर जाएं."</string>
     <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"ऑटोमैटिक भरने के विकल्प"</string>
-    <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"ऑटोमैटिक भरने के लिए सहेजें"</string>
+    <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"अपने आप भरने के लिए सेव करें"</string>
     <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"सामग्रियां ऑटोमैटिक रूप से भरी जा सकती हैं"</string>
     <string name="autofill_picker_no_suggestions" msgid="3908514303773350735">"ऑटोमैटिक भरने का कोई सुझाव नहीं"</string>
     <plurals name="autofill_picker_some_suggestions" formatted="false" msgid="5506565809835815274">
       <item quantity="one">ऑटोमैटिक भरने के <xliff:g id="COUNT">%1$s</xliff:g> सुझाव</item>
       <item quantity="other">ऑटोमैटिक भरने के <xliff:g id="COUNT">%1$s</xliff:g> सुझाव</item>
     </plurals>
-    <string name="autofill_save_title" msgid="3345527308992082601">"&lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt; में सहेजें?"</string>
-    <string name="autofill_save_title_with_type" msgid="8637809388029313305">"<xliff:g id="TYPE">%1$s</xliff:g> को &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt; में सहेजें?"</string>
-    <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"<xliff:g id="TYPE_0">%1$s</xliff:g> और <xliff:g id="TYPE_1">%2$s</xliff:g> को &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt; में सहेजें?"</string>
-    <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> और <xliff:g id="TYPE_2">%3$s</xliff:g> को &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt; में सहेजें?"</string>
-    <string name="autofill_save_yes" msgid="6398026094049005921">"सहेजें"</string>
+    <string name="autofill_save_title" msgid="3345527308992082601">"&lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt; में सेव करें?"</string>
+    <string name="autofill_save_title_with_type" msgid="8637809388029313305">"<xliff:g id="TYPE">%1$s</xliff:g> को &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt; में सेव करें?"</string>
+    <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"<xliff:g id="TYPE_0">%1$s</xliff:g> और <xliff:g id="TYPE_1">%2$s</xliff:g> को &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt; में सेव करें?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> और <xliff:g id="TYPE_2">%3$s</xliff:g> को &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt; में सेव करें?"</string>
+    <string name="autofill_save_yes" msgid="6398026094049005921">"सेव करें"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"नहीं, धन्यवाद"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"पासवर्ड"</string>
     <string name="autofill_save_type_address" msgid="4936707762193009542">"पता"</string>
     <string name="autofill_save_type_credit_card" msgid="7127694776265563071">"क्रेडिट कार्ड"</string>
-    <string name="autofill_save_type_username" msgid="239040540379769562">"उपयोगकर्ता नाम"</string>
+    <string name="autofill_save_type_username" msgid="239040540379769562">"उपयोगकर्ता का नाम"</string>
     <string name="autofill_save_type_email_address" msgid="5752949432129262174">"ईमेल पता"</string>
-    <string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"शांत रहें और आस-पास शरण स्थल खोजें."</string>
+    <string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"शांत रहें और आस-पास शरण लेने की जगह तलाशें."</string>
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"तटीय क्षेत्रों और नदी के किनारे वाले क्षेत्रों को जल्द से जल्द खाली करके किसी सुरक्षित ऊंची जगह पर चले जाएं."</string>
-    <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"शांत रहें और आस-पास आश्रय खोजें."</string>
+    <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"शांत रहें और आस-पास शरण लेने की जगह तलाशें."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"आपातकालीन संदेश परीक्षण"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"जवाब दें"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM की अनुमति नहीं है"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM का प्रावधान नहीं किया गया है"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 3695c67..867d310 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -132,10 +132,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pretraživanje usluge"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi pozivi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Da biste telefonirali i slali pozive putem Wi-Fi-ja, morate tražiti od mobilnog operatera da vam postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u Postavkama."</item>
+    <item msgid="3910386316304772394">"Da biste telefonirali i slali poruke putem Wi-Fi-ja, od mobilnog operatera morate tražiti da postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u postavkama. (Kôd pogreške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Registrirajte se kod mobilnog operatera"</item>
+    <item msgid="7472393097168811593">"Registrirajte se kod mobilnog operatera (kôd pogreške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -249,8 +249,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Glasovna pomoć"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zaključaj sada"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Sadržaj je skriven"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Sadržaj je skriven prema pravilima"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Nova obavijest"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtualna tipkovnica"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fizička tipkovnica"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Sigurnost"</string>
@@ -266,9 +265,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozorenja"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Prodajni demo-način"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Izvođenje aplikacija u pozadini"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> izvodi se u pozadini"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Aplikacije koje se izvode u pozadini: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikacije troše bateriju"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> koristi bateriju"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Broj aplikacija koje koriste bateriju: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dodirnite da biste vidjeli pojedinosti o potrošnji baterije i podatkovnom prometu"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string>
@@ -278,7 +277,7 @@
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakti"</string>
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"pristupati vašim kontaktima"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"pristup lokaciji ovog uređaja"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"pristupiti lokaciji ovog uređaja"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"pristupati kalendaru"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -1128,6 +1127,13 @@
       <item quantity="few">Dostupne su otvorene Wi-Fi mreže</item>
       <item quantity="other">Dostupne su otvorene Wi-Fi mreže</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Povezivanje s otvorenom Wi‑Fi mrežom"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Povezivanje s otvorenom Wi‑Fi mrežom"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Povezano s Wi-Fi mrežom"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nije uspjelo povezivanje s Wi-Fi mrežom"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite za prikaz svih mreža"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Sve mreže"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijava na Wi-Fi mrežu"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1207,8 +1213,10 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB za MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Spojen na USB pribor"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Dodirnite za više opcija."</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"Priključen je alat za otklanjanje pogrešaka USB-om"</string>
-    <string name="adb_active_notification_message" msgid="4948470599328424059">"Dodirnite da biste onemogućili otklanjanje pogrešaka putem USB-a."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Otkriven je analogni audiododatak"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Priključeni uređaj nije kompatibilan s ovim telefonom. Dodirnite da biste saznali više."</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"Priključen je alat za otklanjanje pogrešaka putem USB-a"</string>
+    <string name="adb_active_notification_message" msgid="4948470599328424059">"Dodirnite da biste takvo otklanjanje onemogućili."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Odaberite da biste onemogućili rješavanje programske pogreške na USB-u."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Izrada izvješća o programskoj pogrešci…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite li podijeliti izvješće o programskoj pogrešci?"</string>
@@ -1312,9 +1320,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Povezan sa sesijom <xliff:g id="SESSION">%s</xliff:g>. Dotaknite za upravljanje mrežom."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Povezivanje s uvijek uključenom VPN mrežom…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Povezan s uvijek uključenom VPN mrežom"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Prekinuta je veza s uvijek uključenom VPN mrežom"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Prekinuta je veza s uvijek uključenim VPN-om"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Pogreška uvijek uključene VPN mreže"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Dodirnite za postavljanje"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Promijenite mrežu ili postavke VPN-a"</string>
     <string name="upload_file" msgid="2897957172366730416">"Odaberite datoteku"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nema odabranih datoteka"</string>
     <string name="reset" msgid="2448168080964209908">"Ponovo postavi"</string>
@@ -1323,8 +1331,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Dodirnite da biste napustili način rada u automobilu."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Ograničenje ili aktivan hotspot"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite da biste postavili."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Modemsko je povezivanje onemogućeno"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Obratite se administratoru da biste saznali pojedinosti"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Natrag"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Dalje"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Preskoči"</string>
@@ -1403,9 +1409,9 @@
     <string name="data_usage_warning_body" msgid="6660692274311972007">"Dodirnite za upotrebu i postavke"</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Dost. ogr. 2G–3G prijenosa pod."</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Dost. ogr. 4G prijenosa podataka"</string>
-    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Dosegnuto je ograničenje mobilnog podatkovnog prometa"</string>
+    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Dosegnuto je ograničenje za mob. podatkovni promet"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Dost. ogr. Wi-Fi prijenosa pod."</string>
-    <string name="data_usage_limit_body" msgid="291731708279614081">"Podaci su pauz. za ostatak cikl."</string>
+    <string name="data_usage_limit_body" msgid="291731708279614081">"Podaci su pauzirani do kraja ciklusa"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Prekoračeno ograničenje 2G-3G"</string>
     <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Prekoračeno je ograničenje 4G podataka"</string>
     <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Prekoračeno je ograničenje za podatke na mobilnom uređaju"</string>
@@ -1648,7 +1654,7 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Ažurirao administrator"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Izbrisao administrator"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se produljilo trajanje baterije, ušteda baterije smanjuje performanse uređaja i ograničava vibraciju, usluge lokacije i većinu pozadinskih radnji. Aplikacije za e-poštu, slanje poruka i druge aplikacije koje se oslanjaju na sinkronizaciju možda se neće ažurirati ako ih ne otvorite.\n\nUšteda baterije isključuje se automatski dok se uređaj puni."</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"Da bi se smanjio podatkovni promet, Ušteda podataka onemogućuje nekim aplikacijama slanje ili primanje podataka u pozadini. Aplikacija koju trenutačno upotrebljavate može pristupiti podacima, no možda će to činiti rjeđe. To može značiti da se, na primjer, slike neće prikazivati dok ih ne dodirnete."</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"Da bi se smanjio podatkovni promet, Štednja podatkovnog prometa onemogućuje nekim aplikacijama slanje ili primanje podataka u pozadini. Aplikacija koju trenutačno upotrebljavate može pristupiti podacima, no možda će to činiti rjeđe. To može značiti da se, na primjer, slike neće prikazivati dok ih ne dodirnete."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Uključiti Uštedu podataka?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Uključi"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
@@ -1756,14 +1762,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Otkvači"</string>
     <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Želite li vratiti uređaj na zadano?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Dodirnite za vraćanje uređaja na zadano"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Pokretanje demo-načina..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Vraćanje uređaja na zadano…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Želite li vratiti uređaj na zadano?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Sve će se promjene izbrisati, a demonstracija će se ponovo pokrenuti za <xliff:g id="TIMEOUT">%1$s</xliff:g> s…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Odustani"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Vrati na zadano sada"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> – onemogućeno"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konferencijski poziv"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Opis"</string>
@@ -1808,6 +1808,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Odmah se evakuirajte s obalnih područja i područja uz rijeku na sigurnije mjesto, primjerice povišeno područje."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Ostanite mirni i potražite sklonište u blizini."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test hitnih poruka"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Odgovori"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM nije dopušten"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Ne pruža se usluga za SIM"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 7e71104..f2c4ea0 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Szolgáltatás keresése"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-hívás"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Ha Wi-Fi-n szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután a Beállítások menüben kapcsolhatja be újra a Wi-Fi-hívást."</item>
+    <item msgid="3910386316304772394">"Ha Wi-Fi-hálózaton szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután kapcsolja be újra a Wi-Fi-hívást a Beállításokban. (Hibakód: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Regisztráljon a szolgáltatójánál"</item>
+    <item msgid="7472393097168811593">"Regisztráljon a szolgáltatójánál (hibakód: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Hangsegéd"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zárolás most"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Tartalom elrejtve"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"A tartalom irányelv miatt elrejtve"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Új értesítés"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuális billentyűzet"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fizikai billentyűzet"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Biztonság"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Értesítések"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Kiskereskedelmi bemutató"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-kapcsolat"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"A háttérben még futnak alkalmazások"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> a háttérben fut"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> alkalmazás még fut a háttérben"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Akkumulátort használó alkalmazások"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás használja az akkumulátort"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> alkalmazás használja az akkumulátort"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Koppintson az akkumulátor- és adathasználat részleteinek megtekintéséhez"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Biztonsági üzemmód"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Nyílt Wi-Fi hálózatok érhetők el</item>
       <item quantity="one">Nyílt Wi-Fi hálózat érhető el</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Nyílt Wi-Fi-hálózathoz kapcsolódhat"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Kapcsolódás nyílt Wi‑Fi-hálózathoz…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Sikeres kapcsolódás a Wi-Fi-hálózathoz"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nem sikerült kapcsolódni a Wi‑Fi-hálózathoz"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Koppintással megjelenítheti az összes hálózatot"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kapcsolódás"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Összes hálózat"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Bejelentkezés Wi-Fi hálózatba"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Bejelentkezés a hálózatba"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI-hez"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Csatlakoztatva egy USB-kiegészítőhöz"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Koppintson a további beállítások megjelenítéséhez."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analóg audiotartozék észlelve"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"A csatlakoztatott eszköz nem kompatibilis ezzel a telefonnal. További információért koppintson ide."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hibakereső csatlakoztatva"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Koppintson az USB fejlesztő mód kikapcsolásához."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Válassza ezt az USB hibakeresés kikapcsolásához."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Csatlakozva ide: <xliff:g id="SESSION">%s</xliff:g>. Érintse meg a hálózat kezeléséhez."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Csatlakozás a mindig bekapcsolt VPN-hez..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Csatlakozva a mindig bekapcsolt VPN-hez"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Kapcsolat bontva a mindig bekapcsolt VPN-nel"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Mindig bekapcsolt állapotú VPN-ről leválasztva"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Hiba a mindig bekapcsolt VPN-nel"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Koppintson ide a beállításhoz"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Hálózati vagy VPN-beállítások módosítása"</string>
     <string name="upload_file" msgid="2897957172366730416">"Fájl kiválasztása"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nincs fájl kiválasztva"</string>
     <string name="reset" msgid="2448168080964209908">"Alaphelyzet"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Koppintson az autós üzemmódból való kilépéshez."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Megosztás vagy aktív hotspot"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Koppintson a beállításhoz."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Az internetmegosztás le van tiltva"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"A részletekért forduljon rendszergazdájához"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Vissza"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Tovább"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Kihagyás"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Feloldás"</string>
     <string name="app_info" msgid="6856026610594615344">"Alkalmazásinformáció"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Visszaállítja eszközét?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Koppintson az eszköz visszaállítása érdekében"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Bemutató indítása…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Eszköz visszaállítása…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Visszaállítja eszközét?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"A módosítások elvesznek, és a bemutató újra elindul <xliff:g id="TIMEOUT">%1$s</xliff:g> másodperc múlva…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Mégse"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Visszaállítás most"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"A(z) <xliff:g id="LABEL">%1$s</xliff:g> letiltva"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konferenciahívás"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Elemleírás"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Azonnal meneküljön biztonságosabb helyre a tengerparti, illetve folyóparti területekről, például valamilyen magaslatra."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Őrizze meg nyugalmát, és keressen menedéket a közelben."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Vészhelyzetben küldött üzenetek tesztelése"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Válasz"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"A SIM-kártya nem engedélyezett"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Nem engedélyezett SIM-kártya"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 14c0451..d94895f 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -107,7 +107,7 @@
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Բաժանորդի սարքում ընտրված է հեռատիպի HCO ռեժիմը"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Բաժանորդի սարքում ընտրված է հեռատիպի VCO ռեժիմը"</string>
     <string name="peerTtyModeOff" msgid="3280819717850602205">"Բաժանորդի սարքում ընտրված է հեռատիպի ԱՆՋԱՏ ռեժիմը"</string>
-    <string name="serviceClassVoice" msgid="1258393812335258019">"Ձայնային"</string>
+    <string name="serviceClassVoice" msgid="1258393812335258019">"Ձայնային կապ"</string>
     <string name="serviceClassData" msgid="872456782077937893">"Տվյալներ"</string>
     <string name="serviceClassFAX" msgid="5566624998840486475">"Ֆաքս"</string>
     <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Ծառայության որոնում..."</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Զանգեր Wi-Fi-ի միջոցով"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ ծառայությունը կարգավորելու համար: Ապա նորից միացրեք Wi-Fi զանգերը Կարգավորումներում:"</item>
+    <item msgid="3910386316304772394">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ այս ծառայությունը կարգավորելու համար: Այնուհետև նորից միացրեք «Զանգեր Wi-Fi-ի միջոցով» ընտրանքը Կարգավորումներից: (Սխալի կոդ՝ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Գրանցվեք օպերատորի մոտ"</item>
+    <item msgid="7472393097168811593">"Գրանցվեք ձեր օպերատորի միջոցով (Սխալի կոդ` <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ձայնային օգնութ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Կողպել հիմա"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Բովանդակությունը թաքցված է"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Բովանդակությունը թաքցվել է ըստ քաղաքականության"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Նոր ծանուցում"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Վիրտուալ ստեղնաշար"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Ֆիզիկական ստեղնաշար"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Անվտանգություն"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ծանուցումներ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Խանութի ցուցադրական ռեժիմ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB կապակցում"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Ֆոնային ռեժիմում աշխատող հավելվածներ"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ն աշխատում է ֆոնային ռեժիմում"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> հավելված աշխատում են ֆոնում"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Մարտկոցի լիցքը ծախսող հավելվածներ"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"«<xliff:g id="APP_NAME">%1$s</xliff:g>» հավելվածը ծախսում է մարտկոցի լիցքը"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> հավելված ծախսում է մարտկոցի լիցքը"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Հպեք՝ մարտկոցի և թրաֆիկի մանրամասները տեսնելու համար"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Անվտանգ ռեժիմ"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="one">Հասանելի են չպաշտպանված Wi-Fi ցանցեր</item>
       <item quantity="other">Հասանելի են չպաշտպանված Wi-Fi ցանցեր</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Միացեք բաց Wi‑Fi ցանցին"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Միացում բաց Wi‑Fi ցանցին"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Միացել է Wi‑Fi ցանցին"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Չհաջողվեց միանալ Wi‑Fi ցանցին"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Հպեք՝ բոլոր ցանցերը տեսնելու համար"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Միանալ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Բոլոր ցանցերը"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Մուտք գործեք Wi-Fi ցանց"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Մուտք գործեք ցանց"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI-ի USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Կապակցված է USB լրասարքի"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Հպեք՝ լրացուցիչ ընտրանքների համար:"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Հայտնաբերված է անալոգային աուդիո լրասարք"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Միացված սարքը համատեղելի չէ այս հեռախոսի հետ: Հպեք` ավելին իմանալու համար:"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB վրիպազերծումը միացված է"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Հպեք՝ USB վրիպազերծումն անջատելու համար:"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Ընտրել` USB կարգաբերումը կասեցնելու համար:"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Կապակացված է <xliff:g id="SESSION">%s</xliff:g>-ին: Սեղմեք` ցանցը կառավարելու համար:"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Միշտ-միացված VPN-ը կապվում է..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Միշտ-առցանց VPN-ը կապակցված է"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"«Միշտ միացված VPN»-ն անջատված է"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Անջատված է միշտ միացված VPN ցանցից"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"VPN սխալը միշտ միացված"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Հպեք՝ կարգավորելու համար"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Փոխել ցանցը կամ VPN-ի կարգավորումները"</string>
     <string name="upload_file" msgid="2897957172366730416">"Ընտրել ֆայլը"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Ոչ մի ֆայլ չի ընտրված"</string>
     <string name="reset" msgid="2448168080964209908">"Վերակայել"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Հպեք` մեքենայի ռեժիմից դուրս գալու համար:"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Մոդեմի ռեժիմը միացված է"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Հպեք՝ կարգավորելու համար:"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Մոդեմի ռեժիմն անջատված է"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Մանրամասների համար դիմեք ձեր ադմինիստրատորին"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Հետ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Հաջորդը"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Բաց թողնել"</string>
@@ -1698,8 +1704,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Չդասակարգված"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Դուք սահմանել եք այս ծանուցումների կարևորությունը:"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Կարևոր է, քանի որ որոշակի մարդիկ են ներգրավված:"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Թույլ տա՞լ <xliff:g id="APP">%1$s</xliff:g> հավելվածին <xliff:g id="ACCOUNT">%2$s</xliff:g> հաշվով նոր Օտատեր ստեղծել:"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Թույլ տա՞լ <xliff:g id="APP">%1$s</xliff:g> հավելվածին <xliff:g id="ACCOUNT">%2$s</xliff:g> հաշվով նոր Օտատեր ստեղծել (նման հաշվով Օտատեր արդեն գոյություն ունի):"</string>
+    <string name="user_creation_account_exists" msgid="1942606193570143289">"Թույլ տա՞լ <xliff:g id="APP">%1$s</xliff:g> հավելվածին <xliff:g id="ACCOUNT">%2$s</xliff:g> հաշվով նոր Օգտատեր ստեղծել:"</string>
+    <string name="user_creation_adding" msgid="4482658054622099197">"Թույլ տա՞լ <xliff:g id="APP">%1$s</xliff:g> հավելվածին <xliff:g id="ACCOUNT">%2$s</xliff:g> հաշվով նոր Օգտատեր ստեղծել (նման հաշվով Օգտատեր արդեն գոյություն ունի):"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Ավելացնել լեզու"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Նախընտրելի տարածաշրջան"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Մուտքագրեք լեզուն"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Ապամրացնել"</string>
     <string name="app_info" msgid="6856026610594615344">"Հավելվածի տվյալներ"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Վերակայե՞լ սարքը:"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Հպեք՝ սարքը վերակայելու համար"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Ցուցադրական օգտատերը գործարկվում է…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Սարաքը վերակայվում է…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Վերակայե՞լ սարքը:"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Կատարված փոփոխությունները չեն պահվի, իսկ ցուցադրական նյութը կրկին կգործարկվի <xliff:g id="TIMEOUT">%1$s</xliff:g> վայրկյանից…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Չեղարկել"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Վերակայել հիմա"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Անջատած <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Կոնֆերանս զանգ"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Հուշակ"</string>
@@ -1759,10 +1759,10 @@
       <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> ինքնալցման առաջարկ</item>
       <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> ինքնալցման առաջարկ</item>
     </plurals>
-    <string name="autofill_save_title" msgid="3345527308992082601">"Պահե՞լ &lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt;-ում:"</string>
-    <string name="autofill_save_title_with_type" msgid="8637809388029313305">"Պահե՞լ <xliff:g id="TYPE">%1$s</xliff:g>-ը &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt;-ում:"</string>
-    <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"Պահե՞լ <xliff:g id="TYPE_0">%1$s</xliff:g>-ը և <xliff:g id="TYPE_1">%2$s</xliff:g>-ը &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt;-ում:"</string>
-    <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"Պահե՞լ <xliff:g id="TYPE_0">%1$s</xliff:g>-ը, <xliff:g id="TYPE_1">%2$s</xliff:g>-ը և <xliff:g id="TYPE_2">%3$s</xliff:g>-ը &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt;-ում:"</string>
+    <string name="autofill_save_title" msgid="3345527308992082601">"Պահե՞լ &lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt; ծառայությունում"</string>
+    <string name="autofill_save_title_with_type" msgid="8637809388029313305">"Պահե՞լ <xliff:g id="TYPE">%1$s</xliff:g>ը &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt; ծառայությունում"</string>
+    <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"Պահե՞լ <xliff:g id="TYPE_0">%1$s</xliff:g>ն ու <xliff:g id="TYPE_1">%2$s</xliff:g>ը &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt; ծառայությունում"</string>
+    <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"Պահե՞լ <xliff:g id="TYPE_0">%1$s</xliff:g>ը, <xliff:g id="TYPE_1">%2$s</xliff:g>ն ու <xliff:g id="TYPE_2">%3$s</xliff:g>ը &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt; ծառայությունում"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"Պահել"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"Ոչ"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"գաղտնաբառ"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Ափամերձ և գետափնյա տարածքներից անմիջապես էվակուացվեք դեպի ավելի ապահով վայրեր (օրինակ՝ բարձրադիր գոտիներ):"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Պահպանեք հանգստությունը և մոտակայքում ապաստարան փնտրեք:"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Արտակարգ իրավիճակների հաղորդագրությունների թեստ"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Պատասխանել"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM քարտի օգտագործումն արգելված է"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM քարտը նախապատրաստված չէ"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 998daa6..0d4f8c5 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Mencari layanan"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Panggilan Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Untuk melakukan panggilan telepon dan mengirim pesan melalui Wi-Fi, terlebih dahulu minta operator untuk menyiapkan layanan ini. Lalu, aktifkan lagi panggilan telepon Wi-Fi dari Setelan."</item>
+    <item msgid="3910386316304772394">"Untuk menelepon dan mengirim pesan melalui Wi-Fi, tanyalah ke operator Anda terlebih dahulu untuk menyiapkan layanan ini. Kemudian, aktifkan kembali panggilan Wi-Fi dari Setelan. (Kode error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Harap daftarkan ke operator"</item>
+    <item msgid="7472393097168811593">"Daftarkan ke operator (Kode error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -163,7 +163,7 @@
     <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Laman ini berisi terlalu banyak pengalihan server."</string>
     <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Protokol tidak didukung."</string>
     <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Tidak dapat membuat sambungan aman."</string>
-    <string name="httpErrorBadUrl" msgid="3636929722728881972">"Tidak dapat membuka laman karena URL tidak valid."</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"Tidak dapat membuka halaman karena URL tidak valid."</string>
     <string name="httpErrorFile" msgid="2170788515052558676">"Tidak dapat mengakses file."</string>
     <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Tidak dapat menemukan file yang diminta."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Terlalu banyak permintaan yang diproses. Coba lagi nanti."</string>
@@ -198,7 +198,7 @@
     <string name="turn_on_radio" msgid="3912793092339962371">"Hidupkan nirkabel"</string>
     <string name="turn_off_radio" msgid="8198784949987062346">"Matikan nirkabel"</string>
     <string name="screen_lock" msgid="799094655496098153">"Kunci layar"</string>
-    <string name="power_off" msgid="4266614107412865048">"Matikan daya"</string>
+    <string name="power_off" msgid="4266614107412865048">"Matikan perangkat"</string>
     <string name="silent_mode_silent" msgid="319298163018473078">"Pendering mati"</string>
     <string name="silent_mode_vibrate" msgid="7072043388581551395">"Pendering bergetar"</string>
     <string name="silent_mode_ring" msgid="8592241816194074353">"Pendering nyala"</string>
@@ -222,7 +222,7 @@
     <string name="global_actions" product="tv" msgid="7240386462508182976">"Opsi TV"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"Opsi telepon"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Kunci layar"</string>
-    <string name="global_action_power_off" msgid="4471879440839879722">"Matikan daya"</string>
+    <string name="global_action_power_off" msgid="4471879440839879722">"Matikan perangkat"</string>
     <string name="global_action_emergency" msgid="7112311161137421166">"Darurat"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Laporan bug"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Ambil laporan bug"</string>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Bantuan Suara"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Kunci sekarang"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Konten tersembunyi"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Konten disembunyikan menurut kebijakan"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Notifikasi baru"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Keyboard virtual"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Keyboard fisik"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Keamanan"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Notifikasi"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo promo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Sambungan USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikasi yang sedang berjalan di latar belakang"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang berjalan di latar belakang"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikasi sedang berjalan di latar belakang"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikasi yang menggunakan baterai"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang menggunakan baterai"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikasi sedang meggunakan baterai"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tap untuk melihat detail penggunaan baterai dan data"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode aman"</string>
@@ -811,7 +810,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Konfirmasi Navigasi"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Keluar dari Laman ini"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Tetap di Laman ini"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nYakin ingin beranjak dari laman ini?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nYakin ingin beranjak dari halaman ini?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Konfirmasi"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Kiat: Ketuk dua kali untuk memperbesar dan memperkecil."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"IsiOtomatis"</string>
@@ -848,7 +847,7 @@
     <string name="save_password_notnow" msgid="6389675316706699758">"Tidak sekarang"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Ingat"</string>
     <string name="save_password_never" msgid="8274330296785855105">"Jangan"</string>
-    <string name="open_permission_deny" msgid="7374036708316629800">"Anda tidak memiliki izin untuk membuka laman ini."</string>
+    <string name="open_permission_deny" msgid="7374036708316629800">"Anda tidak memiliki izin untuk membuka halaman ini."</string>
     <string name="text_copied" msgid="4985729524670131385">"Teks disalin ke papan klip."</string>
     <string name="more_item_label" msgid="4650918923083320495">"Lainnya"</string>
     <string name="prepend_shortcut_label" msgid="2572214461676015642">"Menu+"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Jaringan Wi-Fi terbuka tersedia</item>
       <item quantity="one">Jaringan Wi-Fi terbuka tersedia</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Hubungkan ke jaringan Wi-Fi terbuka"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Menghubungkan ke jaringan Wi-Fi terbuka"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Terhubung ke jaringan Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Tidak dapat menghubungkan ke jaringan Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap untuk melihat semua jaringan"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Hubungkan"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Semua Jaringan"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Masuk ke jaringan Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Masuk ke jaringan"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,8 +1191,10 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB untuk MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tersambung ke aksesori USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Ketuk untuk opsi lainnya."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Aksesori audio analog terdeteksi"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Perangkat yang terpasang tidak kompatibel dengan ponsel ini. Tap untuk mempelajari lebih lanjut."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB terhubung"</string>
-    <string name="adb_active_notification_message" msgid="4948470599328424059">"Ketuk untuk menonaktifkan debug USB."</string>
+    <string name="adb_active_notification_message" msgid="4948470599328424059">"Tap untuk menonaktifkan debug USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk menonaktifkan debugging USB."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Mengambil laporan bug…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Bagikan laporan bug?"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Tersambung ke <xliff:g id="SESSION">%s</xliff:g>. Ketuk untuk mengelola jaringan."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Menyambungkan VPN selalu aktif..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPN selalu aktif tersambung"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"VPN selalu aktif terputus"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Terputus dari VPN yang selalu aktif"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Kesalahan VPN selalu aktif"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Ketuk untuk menyiapkan"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Ubah setelan jaringan atau VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Pilih file"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Tidak ada file yang dipilih"</string>
     <string name="reset" msgid="2448168080964209908">"Setel ulang"</string>
@@ -1301,13 +1309,11 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Ketuk untuk keluar dari mode mobil."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering (Penambatan) atau hotspot aktif"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Ketuk untuk menyiapkan."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering dinonaktifkan"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi admin untuk mengetahui detailnya"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Kembali"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Selanjutnya"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Lewati"</string>
     <string name="no_matches" msgid="8129421908915840737">"Tidak ada kecocokan"</string>
-    <string name="find_on_page" msgid="1946799233822820384">"Temukan pada laman"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"Temukan pada halaman"</string>
     <plurals name="matches_found" formatted="false" msgid="1210884353962081884">
       <item quantity="other"><xliff:g id="INDEX">%d</xliff:g> dari <xliff:g id="TOTAL">%d</xliff:g></item>
       <item quantity="one">1 kecocokan</item>
@@ -1433,7 +1439,7 @@
     <string name="media_route_status_available" msgid="6983258067194649391">"Tersedia"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Tidak tersedia"</string>
     <string name="media_route_status_in_use" msgid="4533786031090198063">"Sedang digunakan"</string>
-    <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Layar Bawaan"</string>
+    <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Layar Built-In"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Layar HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Hamparan #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
@@ -1600,7 +1606,7 @@
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Coba lagi nanti"</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"Melihat layar penuh"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"Untuk keluar, gesek ke bawah dari atas."</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"Untuk keluar, geser layar ke bawah dari atas."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"Mengerti"</string>
     <string name="done_label" msgid="2093726099505892398">"Selesai"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"Penggeser putar jam"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Lepas pin"</string>
     <string name="app_info" msgid="6856026610594615344">"Info aplikasi"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Setel ulang perangkat?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Ketuk untuk menyetel ulang perangkat"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Memulai demo..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Menyetel ulang perangkat..."</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Setel ulang perangkat?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Perubahan yang dibuat akan hilang dan demo akan dimulai lagi dalam <xliff:g id="TIMEOUT">%1$s</xliff:g> detik…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Batal"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Setel ulang sekarang"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> dinonaktifkan"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konferensi Telepon"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Keterangan alat"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evakuasi segera dari daerah pesisir dan area tepi sungai ke tempat yang lebih aman seperti dataran tinggi."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Tetap tenang dan cari tempat berlindung terdekat."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Tes pesan darurat"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Balas"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM tidak diizinkan"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM tidak di-provisioning"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 9e71625..869780c 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Leitar að þjónustu"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi símtöl"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum."</item>
+    <item msgid="3910386316304772394">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum. (Villukóði: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Skráðu þig hjá símafyrirtækinu"</item>
+    <item msgid="7472393097168811593">"Skráðu þig hjá símafyrirtækinu (Villukóði: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Raddaðstoð"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Læsa núna"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Innihald falið"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Efni falið með reglu"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Ný tilkynning"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Sýndarlyklaborð"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Vélbúnaðarlyklaborð"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Öryggi"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Tilkynningar"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Kynningarútgáfa fyrir verslanir"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-tenging"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Forrit sem keyra í bakgrunni"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> keyrir í bakgrunni"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> forrit keyra í bakgrunni"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Forrit sem nota rafhlöðuorku"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> notar rafhlöðuorku"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> forrit nota rafhlöðuorku"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Ýttu til að fá upplýsingar um rafhlöðu- og gagnanotkun"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Örugg stilling"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="one">Opin Wi-Fi net í boði</item>
       <item quantity="other">Opin Wi-Fi net í boði</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Tengjast opnu Wi-Fi neti"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Tengist opnu Wi‑Fi neti"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Tengt við Wi‑Fi net"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Ekki hægt að tengjast Wi-Fi neti"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ýttu til að sjá öll netkerfi"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Tengjast"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Öll netkerfi"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Skrá inn á Wi-Fi net"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Skrá inn á net"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB fyrir MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tengt við USB-aukabúnað"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Ýttu til að sjá fleiri valkosti."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Hliðrænn hljóðaukabúnaður greindist"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Tengda tækið er ekki samhæft við þennan síma. Ýttu til að fá frekari upplýsingar."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-villuleit tengd"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Ýttu til að slökkva á USB-villuleit."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Veldu til að gera USB-villuleit óvirka."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Tengt við <xliff:g id="SESSION">%s</xliff:g>. Ýttu til að hafa umsjón með netinu."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Sívirkt VPN tengist…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Sívirkt VPN tengt"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Sívirkt VPN aftengt"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Aftengt frá sívirku VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Villa í sívirku VPN"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Ýttu til að setja upp"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Breyta stillingum netkerfis eða VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Velja skrá"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Engin skrá valin"</string>
     <string name="reset" msgid="2448168080964209908">"Endurstilla"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Ýttu til að fara úr bílastillingu."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Kveikt á tjóðrun eða aðgangsstað"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Ýttu til að setja upp."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Slökkt er á tjóðrun"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hafðu samband við kerfisstjórann til að fá upplýsingar"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Til baka"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Áfram"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Sleppa"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Losa"</string>
     <string name="app_info" msgid="6856026610594615344">"Forritsupplýsingar"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Endurstilla tækið?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Ýttu til að endurstilla tækið"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Byrjar kynningu…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Endurstillir tækið…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Endurstilla tækið?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Þú glatar öllum breytingum og kynningin byrjar aftur eftir <xliff:g id="TIMEOUT">%1$s</xliff:g> sekúndur…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Hætta við"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Endurstilla núna"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Slökkt <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Símafundur"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Ábending"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Fólk sem statt er á strandsvæðum eða við ár á tafarlaust að leita öryggis á svæðum sem eru í meiri hæð yfir sjávarmáli."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Sýndu stillingu og leitaðu skjóls."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Prófun neyðarskilaboða"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Svara"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-kort er ekki leyft"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-korti ekki úthlutað"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 11c866d..2acfb0b 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Ricerca servizio"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chiamate Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Per effettuare chiamate e inviare messaggi tramite Wi-Fi, è necessario prima chiedere all\'operatore telefonico di attivare il servizio. Successivamente, riattiva le chiamate Wi-Fi dalle Impostazioni."</item>
+    <item msgid="3910386316304772394">"Per effettuare chiamate e inviare messaggi tramite Wi-Fi, chiedi prima al tuo operatore di impostare questo servizio. Dopodiché, attiva di nuovo la funzione Chiamate Wi-Fi nelle impostazioni. (Codice di errore: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Registrati con il tuo operatore"</item>
+    <item msgid="7472393097168811593">"Registra con il tuo operatore (codice di errore: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Blocca ora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Contenuti nascosti"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenuti nascosti in base alle norme"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Nuova notifica"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Tastiera virtuale"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Tastiera fisica"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Sicurezza"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Avvisi"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo retail"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Connessione USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"App in esecuzione in background"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> è in esecuzione in background"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> app sono in esecuzione in background"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"App che consumano la batteria"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> sta consumando la batteria"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> app stanno consumando la batteria"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tocca per conoscere i dettagli sull\'utilizzo dei dati e della batteria"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modalità provvisoria"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Apri reti Wi-Fi disponibili</item>
       <item quantity="one">Apri rete Wi-Fi disponibile</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Stabilisci la connessione per aprire la rete Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connessione per aprire la rete Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connessione alla rete Wi-Fi stabilita"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Impossibile connettersi alla rete Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tocca per vedere tutte le reti"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connetti"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tutte le reti"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Accedi a rete Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Accedi alla rete"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB per la modalità MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Collegato a un accessorio USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tocca per altre opzioni."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Accessorio audio analogico rilevato"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Il dispositivo collegato non è compatibile con questo telefono. Tocca per avere ulteriori informazioni."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debug USB collegato"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tocca per disattivare il debug USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleziona per disattivare il debug USB."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Collegata a <xliff:g id="SESSION">%s</xliff:g>. Tocca per gestire la rete."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Connessione a VPN sempre attiva…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPN sempre attiva connessa"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"VPN sempre attiva disconnessa"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Disconnesso da VPN sempre attiva"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Errore VPN sempre attiva"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Tocca per configurare"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Cambia le impostazioni VPN o di rete"</string>
     <string name="upload_file" msgid="2897957172366730416">"Scegli file"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nessun file è stato scelto"</string>
     <string name="reset" msgid="2448168080964209908">"Reimposta"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tocca per uscire dalla modalità automobile."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering oppure hotspot attivo"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tocca per impostare."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering disattivato"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contatta il tuo amministratore per avere informazioni dettagliate"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Indietro"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Avanti"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Ignora"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Sblocca"</string>
     <string name="app_info" msgid="6856026610594615344">"Informazioni app"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Ripristinare il dispositivo?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Tocca per ripristinare il dispositivo"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Avvio della demo…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Ripristino del dispositivo…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Ripristinare il dispositivo?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Perderai tutte le modifiche e la demo verrà riavviata tra <xliff:g id="TIMEOUT">%1$s</xliff:g> secondi…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Annulla"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Ripristina ora"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Widget <xliff:g id="LABEL">%1$s</xliff:g> disattivato"</string>
     <string name="conference_call" msgid="3751093130790472426">"Audioconferenza"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Descrizione comando"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacuare immediatamente le zone costiere e in riva ai fiumi e recarsi in un luogo più sicuro, ad esempio un\'altura."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantieni la calma e cerca riparo nelle vicinanze."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Testo messaggi di emergenza"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Rispondi"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Scheda SIM non consentita"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Scheda SIM non predisposta"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index b9b5cf9..bcf3498 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -133,10 +133,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"מחפש שירות"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"‏שיחות ב-Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"‏כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב התקשרות Wi-Fi מ\'הגדרות\'."</item>
+    <item msgid="3910386316304772394">"‏כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב שיחות Wi-Fi ב\'הגדרות\'. (קוד שגיאה: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"הירשם אצל הספק"</item>
+    <item msgid="7472393097168811593">"יש להירשם אצל הספק (קוד שגיאה: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -252,8 +252,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"נעל עכשיו"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"התוכן מוסתר"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"התוכן מוסתר על ידי המדיניות"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"הודעה חדשה"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"מקלדת וירטואלית"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"מקלדת פיזית"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"אבטחה"</string>
@@ -269,9 +268,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"התראות"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"הדגמה לקמעונאים"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"‏חיבור USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"אפליקציות שפועלות ברקע"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> פועלת ברקע"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> אפליקציות פועלות ברקע"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"אפליקציות שמרוקנות את הסוללה"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> משתמשת בסוללה"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> אפליקציות משתמשות בסוללה"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"הקש לקבלת פרטים על צריכה של נתונים וסוללה"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>, <xliff:g id="LEFT_SIDE">%1$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"מצב בטוח"</string>
@@ -432,7 +431,7 @@
     <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"מאפשרת לאפליקציה להשתמש במשדר האינפרה-אדום של הטאבלט."</string>
     <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"מאפשרת לאפליקציה להשתמש במשדר האינפא-האדום של הטלוויזיה."</string>
     <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"מאפשרת לאפליקציה להשתמש במשדר האינפרא-אדום של הטלפון."</string>
-    <string name="permlab_setWallpaper" msgid="6627192333373465143">"הגדר טפט"</string>
+    <string name="permlab_setWallpaper" msgid="6627192333373465143">"הגדרת טפט"</string>
     <string name="permdesc_setWallpaper" msgid="7373447920977624745">"מאפשר לאפליקציה להגדיר את טפט המערכת."</string>
     <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"התאמת גודל הטפט שלך"</string>
     <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"מאפשר לאפליקציה להגדיר את סמני הגודל של טפט המערכת."</string>
@@ -818,7 +817,7 @@
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"צא מדף זה"</string>
     <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="save_password_label" msgid="6860261758665825069">"אישור"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"טיפ: הקש פעמיים כדי להגדיל ולהקטין."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"מילוי אוטומטי"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"הגדר מילוי אוטומטי"</string>
@@ -860,9 +859,9 @@
     <string name="prepend_shortcut_label" msgid="2572214461676015642">"תפריט+"</string>
     <string name="menu_space_shortcut_label" msgid="2410328639272162537">"רווח"</string>
     <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"Enter"</string>
-    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"מחק"</string>
-    <string name="search_go" msgid="8298016669822141719">"חפש"</string>
-    <string name="search_hint" msgid="1733947260773056054">"חפש…"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"מחיקה"</string>
+    <string name="search_go" msgid="8298016669822141719">"חיפוש"</string>
+    <string name="search_hint" msgid="1733947260773056054">"חיפוש…"</string>
     <string name="searchview_description_search" msgid="6749826639098512120">"חיפוש"</string>
     <string name="searchview_description_query" msgid="5911778593125355124">"שאילתת חיפוש"</string>
     <string name="searchview_description_clear" msgid="1330281990951833033">"נקה שאילתה"</string>
@@ -1010,7 +1009,7 @@
     <string name="paste" msgid="5629880836805036433">"הדבק"</string>
     <string name="paste_as_plain_text" msgid="5427792741908010675">"הדבק כטקסט פשוט"</string>
     <string name="replace" msgid="5781686059063148930">"החלף..."</string>
-    <string name="delete" msgid="6098684844021697789">"מחק"</string>
+    <string name="delete" msgid="6098684844021697789">"מחיקה"</string>
     <string name="copyUrl" msgid="2538211579596067402">"העתק כתובת אתר"</string>
     <string name="selectTextMode" msgid="1018691815143165326">"בחר טקסט"</string>
     <string name="undo" msgid="7905788502491742328">"ביטול"</string>
@@ -1018,7 +1017,7 @@
     <string name="autofill" msgid="3035779615680565188">"מילוי אוטומטי"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"בחירת טקסט"</string>
     <string name="addToDictionary" msgid="4352161534510057874">"הוסף למילון"</string>
-    <string name="deleteText" msgid="6979668428458199034">"מחק"</string>
+    <string name="deleteText" msgid="6979668428458199034">"מחיקה"</string>
     <string name="inputMethod" msgid="1653630062304567879">"שיטת קלט"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"פעולות טקסט"</string>
     <string name="email" msgid="4560673117055050403">"אימייל"</string>
@@ -1046,7 +1045,7 @@
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"פתח"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"ערוך באמצעות"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"‏ערוך באמצעות %1$s"</string>
-    <string name="whichEditApplicationLabel" msgid="7183524181625290300">"ערוך"</string>
+    <string name="whichEditApplicationLabel" msgid="7183524181625290300">"עריכה"</string>
     <string name="whichSendApplication" msgid="6902512414057341668">"שתף באמצעות"</string>
     <string name="whichSendApplicationNamed" msgid="2799370240005424391">"‏שתף באמצעות %1$s"</string>
     <string name="whichSendApplicationLabel" msgid="4579076294675975354">"שתף"</string>
@@ -1150,6 +1149,13 @@
       <item quantity="other">‏יש רשתות Wi-Fi פתוחות וזמינות</item>
       <item quantity="one">‏יש רשת Wi-Fi פתוחה וזמינה</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"‏התחברות לרשת Wi‑Fi פתוחה"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"‏מתחבר לרשת Wi‑Fi פתוחה"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"‏מחובר לרשת Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"‏לא ניתן היה להתחבר לרשת Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"יש להקיש כדי לראות את כל הרשתות"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"התחבר"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"כל הרשתות"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"‏היכנס לרשת Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"היכנס לרשת"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1207,7 +1213,7 @@
     <string name="sim_done_button" msgid="827949989369963775">"סיום"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"‏כרטיס ה-SIM נוסף"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"הפעל מחדש את המכשיר כדי לגשת אל הרשת הסלולרית."</string>
-    <string name="sim_restart_button" msgid="4722407842815232347">"הפעל מחדש"</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"הפעלה מחדש"</string>
     <string name="carrier_app_dialog_message" msgid="7066156088266319533">"‏כדי שה-SIM החדש שלך יפעל כראוי, תצטרך להתקין אפליקציה מהספק ולפתוח אותה."</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"קבל את האפליקציה"</string>
     <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"לא עכשיו"</string>
@@ -1229,8 +1235,10 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"‏USB ל-MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"‏מחובר לאביזר USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"הקש לקבלת אפשרויות נוספות."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"המכשיר זיהה התקן אודיו אנלוגי"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"ההתקן שחיברת לא תואם לטלפון הזה. הקש למידע נוסף."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏ניפוי באגים של USB מחובר"</string>
-    <string name="adb_active_notification_message" msgid="4948470599328424059">"‏הקש כדי להשבית ניפוי באגים של USB."</string>
+    <string name="adb_active_notification_message" msgid="4948470599328424059">"‏יש להקיש כדי להשבית ניפוי באגים של USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‏בחר להשבית ניפוי באגים ב-USB."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"עיבוד דוח על באג..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"האם לשתף דוח על באג?"</string>
@@ -1239,7 +1247,7 @@
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"שתף"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"לא, אין מצב"</string>
     <string name="select_input_method" msgid="8547250819326693584">"שינוי מקלדת"</string>
-    <string name="show_ime" msgid="2506087537466597099">"תישאר במסך בזמן שהמקלדת הפיזית פעילה"</string>
+    <string name="show_ime" msgid="2506087537466597099">"להשאיר במסך בזמן שהמקלדת הפיזית פעילה"</string>
     <string name="hardware" msgid="194658061510127999">"הצג מקלדת וירטואלית"</string>
     <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"הגדרת מקלדת פיזית"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"הקש כדי לבחור שפה ופריסה"</string>
@@ -1302,7 +1310,7 @@
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"הקש פעמיים לבקרת מרחק מתצוגה"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"‏לא ניתן להוסיף widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"התחל"</string>
-    <string name="ime_action_search" msgid="658110271822807811">"חפש"</string>
+    <string name="ime_action_search" msgid="658110271822807811">"חיפוש"</string>
     <string name="ime_action_send" msgid="2316166556349314424">"שלח"</string>
     <string name="ime_action_next" msgid="3138843904009813834">"הבא"</string>
     <string name="ime_action_done" msgid="8971516117910934605">"סיום"</string>
@@ -1334,9 +1342,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"מחובר אל <xliff:g id="SESSION">%s</xliff:g>. הקש כדי לנהל את הרשת."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"‏ה-VPN שמופעל תמיד, מתחבר..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"‏ה-VPN שפועל תמיד, מחובר"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"‏חיבור תמידי ל-VPN מנותק"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"‏אין חיבור ל-VPN שפועל כל הזמן"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"‏שגיאת VPN שמופעל תמיד"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"הקש כדי להגדיר"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"‏רוצה לשנות את הגדרות הרשת או הגדרות ה-VPN?"</string>
     <string name="upload_file" msgid="2897957172366730416">"בחר קובץ"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"לא נבחר קובץ"</string>
     <string name="reset" msgid="2448168080964209908">"איפוס"</string>
@@ -1345,8 +1353,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"הקש כדי לצאת ממצב מכונית."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"שיתוף אינטרנט פעיל"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"הקש כדי להגדיר."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"שיתוף האינטרנט בין ניידים מושבת"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"לפרטים, יש לפנות למנהל המערכת"</string>
     <string name="back_button_label" msgid="2300470004503343439">"הקודם"</string>
     <string name="next_button_label" msgid="1080555104677992408">"הבא"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"דילוג"</string>
@@ -1399,7 +1405,7 @@
     <string name="date_picker_next_month_button" msgid="5559507736887605055">"החודש הבא"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ביטול"</string>
-    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"מחק"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"מחיקה"</string>
     <string name="keyboardview_keycode_done" msgid="1992571118466679775">"סיום"</string>
     <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"שינוי מצב"</string>
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
@@ -1421,7 +1427,7 @@
     <string name="storage_usb_drive" msgid="6261899683292244209">"‏כונן USB"</string>
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"‏כונן USB של <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb" msgid="3017954059538517278">"‏אחסון USB"</string>
-    <string name="extract_edit_menu_button" msgid="8940478730496610137">"ערוך"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"עריכה"</string>
     <string name="data_usage_warning_title" msgid="3620440638180218181">"התראה על שימוש בנתונים"</string>
     <string name="data_usage_warning_body" msgid="6660692274311972007">"הקש כדי להציג נתוני שימוש והגדרות."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"‏הגעת למגבלת הנתונים של 2G-3G"</string>
@@ -1541,7 +1547,7 @@
     <string name="error_message_title" msgid="4510373083082500195">"שגיאה"</string>
     <string name="error_message_change_not_allowed" msgid="1238035947357923497">"מנהל המערכת שלך אינו מתיר שינוי זה"</string>
     <string name="app_not_found" msgid="3429141853498927379">"לא נמצאה אפליקציה שתומכת בפעולה זו"</string>
-    <string name="revoke" msgid="5404479185228271586">"בטל"</string>
+    <string name="revoke" msgid="5404479185228271586">"ביטול"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
     <string name="mediasize_iso_a1" msgid="3333060421529791786">"ISO A1"</string>
     <string name="mediasize_iso_a2" msgid="3097535991925798280">"ISO A2"</string>
@@ -1789,14 +1795,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"בטל הצמדה"</string>
     <string name="app_info" msgid="6856026610594615344">"פרטי אפליקציה"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"האם לאפס את המכשיר?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"הקש כדי לאפס את המכשיר"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"מתחיל בהדגמה…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"מאפס את המכשיר…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"האם לאפס את המכשיר?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"תאבד את כל השינויים וההדגמה תתחיל שוב בעוד <xliff:g id="TIMEOUT">%1$s</xliff:g> שניות…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"ביטול"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"אפס עכשיו"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> הושבת"</string>
     <string name="conference_call" msgid="3751093130790472426">"שיחת ועידה"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"הסבר קצר"</string>
@@ -1831,7 +1831,7 @@
     <string name="autofill_save_title_with_type" msgid="8637809388029313305">"‏האם לשמור <xliff:g id="TYPE">%1$s</xliff:g> בשירות &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt;?"</string>
     <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"‏האם לשמור <xliff:g id="TYPE_0">%1$s</xliff:g> ו<xliff:g id="TYPE_1">%2$s</xliff:g> בשירות &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt;?"</string>
     <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"‏האם לשמור <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ו<xliff:g id="TYPE_2">%3$s</xliff:g> בשירות &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt;?"</string>
-    <string name="autofill_save_yes" msgid="6398026094049005921">"שמור"</string>
+    <string name="autofill_save_yes" msgid="6398026094049005921">"שמירה"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"לא, תודה"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"סיסמה"</string>
     <string name="autofill_save_type_address" msgid="4936707762193009542">"כתובת"</string>
@@ -1842,6 +1842,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"יש להתפנות מיידית מאזורים הסמוכים לחופים ולנהרות למקום בטוח יותר, כגון שטח גבוה יותר."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"הישאר רגוע וחפש מחסה בקרבת מקום."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"בדיקה של הודעות חירום"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"השב"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"‏כרטיס ה-SIM לא מורשה"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"‏כרטיס ה-SIM לא מזוהה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 408b3b3..3ffccd1 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"サービスを検索中"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi通話"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社にWi-Fiサービスを申し込んだ上で、設定画面でWi-Fi発信を再度ONにしてください。"</item>
+    <item msgid="3910386316304772394">"Wi-Fi 経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社に Wi-Fi サービスを申し込んだ上で、設定画面で Wi-Fi 通話を再度 ON にしてください(エラーコード: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"携帯通信会社に登録してください"</item>
+    <item msgid="7472393097168811593">"携帯通信会社に登録してください(エラーコード: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"音声アシスト"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"今すぐロック"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"コンテンツが非表示"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ポリシーによって非表示になっているコンテンツ"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"新しい通知"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"仮想キーボード"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"物理キーボード"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"セキュリティ"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"通知"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"販売店デモ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB 接続"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"バックグラウンドで実行中のアプリ"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」がバックグラウンドで実行中です"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> 個のアプリがバックグラウンドで実行中です"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"アプリが電池を消費しています"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」が電池を使用しています"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> 個のアプリが電池を使用しています"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"タップして電池やデータの使用量を確認"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>、<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"セーフモード"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">複数のWi-Fiオープンネットワークが利用できます</item>
       <item quantity="one">Wi-Fiオープンネットワークが利用できます</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Wi-Fi オープン ネットワークに接続"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Wi-Fi オープン ネットワークに接続しています"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi-Fi ネットワークに接続しました"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ネットワークに接続できませんでした"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"すべてのネットワークを表示するにはタップします"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"接続"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"すべてのネットワーク"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fiネットワークにログイン"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ネットワークにログインしてください"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USBをMIDIに使用"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USBアクセサリを接続しました"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"タップしてその他のオプションを表示します。"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"アナログのオーディオ アクセサリを検出"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"接続したデバイスはこのスマートフォンと互換性がありません。タップすると、詳細を確認できます。"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"タップして USB デバッグを無効にします。"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USBデバッグを無効にする場合に選択します。"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g>に接続しました。ネットワークを管理するにはタップしてください。"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"VPNに常時接続しています…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPNに常時接続しました"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"常時接続 VPN の接続を解除しました"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"常時接続 VPN から切断されました"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"常時接続VPNのエラー"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"設定するにはタップします"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"ネットワークまたは VPN の設定を変更できます"</string>
     <string name="upload_file" msgid="2897957172366730416">"ファイルを選択"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"ファイルが選択されていません"</string>
     <string name="reset" msgid="2448168080964209908">"リセット"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"タップして運転モードを終了します。"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"テザリングまたはアクセスポイントが有効です"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"タップしてセットアップします。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"テザリングは無効に設定されています"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"詳しくは、管理者にお問い合わせください"</string>
     <string name="back_button_label" msgid="2300470004503343439">"戻る"</string>
     <string name="next_button_label" msgid="1080555104677992408">"次へ"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"スキップ"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"固定を解除"</string>
     <string name="app_info" msgid="6856026610594615344">"アプリ情報"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"端末をリセットしますか?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"端末をリセットするにはタップしてください"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"デモを開始しています…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"端末をリセットしています…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"端末をリセットしますか?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"変更が失われ、<xliff:g id="TIMEOUT">%1$s</xliff:g> 秒後にデモがもう一度開始されます…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"キャンセル"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"今すぐリセット"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"停止済みの「<xliff:g id="LABEL">%1$s</xliff:g>」"</string>
     <string name="conference_call" msgid="3751093130790472426">"グループ通話"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"ツールチップ"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"沿岸部の方はただちに高台へ避難してください"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"強い揺れと津波に注意してください"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"テスト用緊急速報メール"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"返信"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM 使用不可"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM には対応していません"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 6308818..d3f86f8 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"სერვისის ძიება"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"დარეკვა Wi-Fi-ს მეშვეობით"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi-ს მეშვეობით ზარების განხორციელების ან შეტყობინების გაგზავნისათვის, პირველ რიგში დაეკითხეთ თქვენს ოპერატორს აღნიშნულ მომსახურებაზე. შემდეგ ხელახლა ჩართეთ Wi-Fi ზარები პარამეტრებიდან."</item>
+    <item msgid="3910386316304772394">"Wi-Fi-ს მეშვეობით ზარების განსახორციელებლად ან შეტყობინებების გასაგზავნად, პირველ რიგში, ამ სერვისის გააქტიურება თქვენს ოპერატორს უნდა თხოვოთ. შემდეგ კი ხელახლა ჩართეთ Wi-Fi დარეკვა პარამეტრებიდან. (შეცდომის კოდი: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"დაარეგისტრირეთ თქვენი ოპერატორი"</item>
+    <item msgid="7472393097168811593">"თქვენს ოპერატორთან რეგისტრირება (შეცდომის კოდი: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ხმოვანი ასისტ."</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ახლა ჩაკეტვა"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"შიგთავსი დამალულია"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"შიგთავსი დამალულია წესების შესაბამისად"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"ახალი შეტყობინება"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ვირტუალური კლავიატურა"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ფიზიკური კლავიატურა"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"უსაფრთხოება"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"გაფრთხილებები"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"დემო-რეჟიმი საცალო მოვაჭრეებისთვის"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB კავშირი"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ფონურ რეჟიმში გაშვებული აპები"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> გაშვებულია ფონურ რეჟიმში"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"ფონურ რეჟიმში გაშვებულია <xliff:g id="NUMBER">%1$d</xliff:g> აპი"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ბატარეის მხარჯავი აპები"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> იყენებს ბატარეას"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"ბატარეას <xliff:g id="NUMBER">%1$d</xliff:g> აპი იყენებს"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"შეეხეთ ბატარეისა და მონაცემების მოხმარების შესახებ დეტალური ინფორმაციისთვის"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"უსაფრთხო რეჟიმი"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">ხელმისაწვდომია ღია Wi-Fi ქსელები</item>
       <item quantity="one">ხელმისაწვდომია ღია Wi-Fi ქსელი</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"დაუკავშირდით ღია Wi‑Fi ქსელს"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"მიმდინარეობს ღია Wi‑Fi ქსელთან დაკავშირება"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi ქსელთან დაკავშირება წარმატებით მოხერხდა"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ქსელთან დაკავშირება ვერ მოხერხდა"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"შეეხეთ ყველა ქსელის სანახავად"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"დაკავშირება"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ყველა ქსელი"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ქსელთან დაკავშირება"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ქსელში შესვლა"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI-სთვის"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"დაკავშირებულია USB აქსესუართან"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"შეეხეთ დამატებითი ვარიანტების სანახავად."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"აღმოჩენილია ანალოგური აუდიო აქსესუარი"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"მიერთებული მოწყობილობა არაა თავსებადი ამ ტელეფონთან. მეტის გასაგებად, შეეხეთ."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB გამართვა შეერთებულია"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"შეეხეთ USB-გამართვის გასათიშად."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"მონიშნეთ რათა შეწყვიტოთ USB-ის გამართვა"</string>
@@ -1290,19 +1298,17 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"მიერთებულია <xliff:g id="SESSION">%s</xliff:g>-ზე. შეეხეთ ქსელის სამართავად."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"მიმდინარეობს მუდმივად ჩართული VPN-ის მიერთება…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"მუდმივად ჩართული VPN-ის მიერთებულია"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"მუდმივად ჩართული VPN გათიშულია"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"გათიშულია მუდმივად ჩართული VPN-იდან"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"შეცდომა მუდამ VPN-ზე"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"შეეხეთ დასაყენებლად"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"შეცვალეთ ქსელი ან VPN-ის პარამეტრები"</string>
     <string name="upload_file" msgid="2897957172366730416">"ფაილის არჩევა"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"ფაილი არჩეული არ არის"</string>
     <string name="reset" msgid="2448168080964209908">"საწყისზე დაბრუნება"</string>
     <string name="submit" msgid="1602335572089911941">"გაგზავნა"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"მანქანის რეჟიმი ჩართულია"</string>
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"შეეხეთ მანქანის რეჟიმიდან გამოსასვლელად."</string>
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ინტერნეტის მიერთება ან უსადენო ქსელი აქტიურია."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"ტეტერინგი ან უსადენო ქსელი აქტიურია"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"შეეხეთ დასაყენებლად."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ტეტერინგი გათიშულია"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"დამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს"</string>
     <string name="back_button_label" msgid="2300470004503343439">"უკან"</string>
     <string name="next_button_label" msgid="1080555104677992408">"მომდევნო"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"გამოტოვება"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"ჩამაგრების მოხსნა"</string>
     <string name="app_info" msgid="6856026610594615344">"აპის შესახებ"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"გსურთ მოწყობილობის გადაყენება?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"შეეხეთ მოწყობილობის გადასაყენებლად"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"მიმდინარეობს დემონსტრაციის დაწყება…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"მიმდინარეობს მოწყობილობის გადაყენება…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"გსურთ მოწყობილობის გადაყენება?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"შეტანილი ცვლილებები დაიკარგება, ხოლო დემონსტრაცია ხელახლა <xliff:g id="TIMEOUT">%1$s</xliff:g> წამში დაიწყება…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"გაუქმება"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"ახლავე გადაყენება"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"გათიშული <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"საკონფერენციო ზარი"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"მინიშნება"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"დაუყოვნებლივ გადაინაცვლეთ სანაპირო რეგიონებიდან და მდინარისპირა ტერიტორიებიდან უსაფრთხო ადგილზე (მაგალითად, შემაღლებულ ადგილზე)."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"შეინარჩუნეთ სიმშვიდე და იპოვეთ ახლომდებარე თავშესაფარი."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"სატესტო საგანგებო შეტყობინება"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"პასუხი"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM ბარათი დაუშვებელია"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM ბარათი უზრუნველყოფილი არ არის"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index c74ecef..b1fabbd 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Қызметті іздеу"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi қоңыраулары"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi арқылы қоңырау шалу және хабарларды жіберу үшін алдымен жабдықтаушыңыздан осы қызметті орнатуды сұраңыз. Содан кейін Параметрлерден Wi-Fi қоңырау шалуын іске қосыңыз."</item>
+    <item msgid="3910386316304772394">"Wi-Fi арқылы қоңырау шалу немесе хабарлар жіберу үшін, алдымен операторыңыздан құрылғыны реттеуді сұраңыз. Содан кейін \"Параметрлер\" бөлімінен Wi-Fi қоңырауларын қайта қосыңыз. (Қате коды: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Жабдықтаушыңыз арқылы тіркелу"</item>
+    <item msgid="7472393097168811593">"Оператор арқылы тіркеліңіз (қате коды: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Дауыс көмекшісі"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Қазір бекіту"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Мазмұн жасырылған"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Мазмұн саясатқа сай жасырылған"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Жаңа хабарландыру"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуалды пернетақта"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Қатты пернетақта"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Қауіпсіздік"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Дабылдар"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Бөлшек саудаға арналған демо нұсқасы"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB байланысы"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Фонда жұмыс істеп тұрған қолданбалар"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> фонда жұмыс істеп тұр"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> қолданба фонда жұмыс істеп тұр"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Батареяны пайдаланып жатқан қолданбалар"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> батареяны пайдалануда"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> қолданба батареяны пайдалануда"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Батарея мен деректер трафигі туралы білу үшін түртіңіз"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Қауіпсіз режим"</string>
@@ -657,7 +656,7 @@
     <string name="emailTypeHome" msgid="449227236140433919">"Үй"</string>
     <string name="emailTypeWork" msgid="3548058059601149973">"Жұмыс"</string>
     <string name="emailTypeOther" msgid="2923008695272639549">"Басқа"</string>
-    <string name="emailTypeMobile" msgid="119919005321166205">"Ұялы"</string>
+    <string name="emailTypeMobile" msgid="119919005321166205">"Мобильдік"</string>
     <string name="postalTypeCustom" msgid="8903206903060479902">"Арнаулы"</string>
     <string name="postalTypeHome" msgid="8165756977184483097">"Үй"</string>
     <string name="postalTypeWork" msgid="5268172772387694495">"Жұмыс"</string>
@@ -973,7 +972,7 @@
     <string name="delete" msgid="6098684844021697789">"Жою"</string>
     <string name="copyUrl" msgid="2538211579596067402">"URL мекенжайын көшіру"</string>
     <string name="selectTextMode" msgid="1018691815143165326">"Мәтінді бөлектеу"</string>
-    <string name="undo" msgid="7905788502491742328">"Кері қайтару"</string>
+    <string name="undo" msgid="7905788502491742328">"Қайтару"</string>
     <string name="redo" msgid="7759464876566803888">"Қайтару"</string>
     <string name="autofill" msgid="3035779615680565188">"Aвтотолтыру"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Мәтін таңдау"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Ашық Wi-Fi желілері қол жетімді</item>
       <item quantity="one">Ашық Wi-Fi желісі қол жетімді</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Ашық Wi‑Fi желісіне қосылу"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ашық Wi‑Fi желісіне қосылуда"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi желісіне қосылды"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi желісіне қосылмады"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Барлық желілерді көру үшін түртіңіз"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Қосылу"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Барлық желілер"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi желісіне кіру"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Желіге кіру"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,7 +1191,9 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI режиміне арналған USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB жабдығына қосылған"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Қосымша опциялар үшін түртіңіз."</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB жөндеу қосылған"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Аналогтық аудиожабдық анықталды"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Жалғанған құрылғы бұл телефонмен үйлесімсіз. Қосымша ақпарат алу үшін түртіңіз."</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB түзетуі қосылған"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB түзетуін өшіру үшін түртіңіз."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB түзетуін өшіру үшін таңдаңыз."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Қате туралы есеп алынуда…"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> жүйесіне жалғанған. Желіні басқару үшін түріңіз."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Әрқашан қосылған ВЖЖ жалғануда…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Әрқашан қосылған ВЖЖ жалғанған"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Әрқашан қосулы VPN желісі ажыратылды"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Әрқашан қосулы VPN желісінен ажырады"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Әрқашан қосылған ВЖЖ қателігі"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Реттеу үшін түртіңіз"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Желіні не VPN параметрлерін өзгерту"</string>
     <string name="upload_file" msgid="2897957172366730416">"Файлды таңдау"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Ешқандай файл таңдалмаған"</string>
     <string name="reset" msgid="2448168080964209908">"Қайта реттеу"</string>
@@ -1301,11 +1309,9 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Автокөлік режимінен шығу үшін түртіңіз."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Тетеринг немесе хотспот қосулы"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Реттеу үшін түртіңіз."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Тетеринг өшірілді"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Мәліметтерді әкімшіден алыңыз"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Артқа"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Келесі"</string>
-    <string name="skip_button_label" msgid="1275362299471631819">"Аттап өту"</string>
+    <string name="skip_button_label" msgid="1275362299471631819">"Өткізіп жіберу"</string>
     <string name="no_matches" msgid="8129421908915840737">"Сәйкес табылмады"</string>
     <string name="find_on_page" msgid="1946799233822820384">"Беттен табу"</string>
     <plurals name="matches_found" formatted="false" msgid="1210884353962081884">
@@ -1382,7 +1388,7 @@
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"4G деректер шегіне жеттіңіз"</string>
     <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Мобильдік деректер шегіне жетті"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Wi-Fi деректер шегіне жеттіңіз"</string>
-    <string name="data_usage_limit_body" msgid="291731708279614081">"Циклдің қал. бөл. үшін дер. кід."</string>
+    <string name="data_usage_limit_body" msgid="291731708279614081">"Дерек тасымалы кідіртілді"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2Г-3Г дерекқор шектеуінен асып кетті"</string>
     <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4Ш дерекқор шектеуінен асып кетті"</string>
     <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Ұялы дерекқор шектеуінен асып кетті"</string>
@@ -1661,8 +1667,8 @@
     </plurals>
     <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> дейін"</string>
     <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> дейін (келесі дабыл)"</string>
-    <string name="zen_mode_forever" msgid="1916263162129197274">"Өшірмейінше мазаламау"</string>
-    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Өшірмейінше мазаламау"</string>
+    <string name="zen_mode_forever" msgid="1916263162129197274">"\"Мазаламау\" режимін өшіргенше"</string>
+    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"\"Мазаламау\" режимін өшіргенше"</string>
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Тасалау"</string>
     <string name="zen_mode_feature_name" msgid="5254089399895895004">"Мазаламау"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Босату"</string>
     <string name="app_info" msgid="6856026610594615344">"Қолданба ақпараты"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Құрылғыны бастапқы күйге қайтару керек пе?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Құрылғыны бастапқы күйге келтіру үшін түртіңіз"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Демо нұсқасы іске қосылуда..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Құрылғы бастапқы күйге қайтарылуда..."</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Құрылғыны басқапқы күйге қайтару керек пе?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Барлық өзгеріс жоғалады және демо нұсқасы <xliff:g id="TIMEOUT">%1$s</xliff:g> секундтан кейін қайта қосылады…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Бас тарту"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Қазір бастапқы күйге қайтару"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> өшірулі"</string>
     <string name="conference_call" msgid="3751093130790472426">"Конференциялық қоңырау"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Қалқыма сөзкөмек"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Жағалау аймақтан биіктеу қауіпсіз жерге дереу көшіңіз."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Сабыр сақтап, жақын жерден баспана іздеңіз."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Төтенше хабарлар сынағы"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Жауап"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM картасына рұқсат етілмеген"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM картасы белсендірілмеген"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 36d7c5a..62d09bf 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"​ស្វែង​រក​សេវាកម្ម"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ការហៅតាម Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"ដើម្បីធ្វើការហៅ និងផ្ញើសារតាម Wi-Fi ដំបូងឡើយអ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនរបស់អ្នកដំឡើងសេវាកម្មនេះសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតចេញពីការកំណត់។"</item>
+    <item msgid="3910386316304772394">"ដើម្បីហៅទូរសព្ទ និងផ្ញើសារតាម Wi-Fi អ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនបម្រើសេវាទូរសព្ទរបស់អ្នកដំឡើងសេវាកម្មនេះជាមុនសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតនៅក្នុងការកំណត់។ (លេខកូដបញ្ហា៖ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"ចុះឈ្មោះជាមួយក្រុមហ៊ុនរបស់អ្នក"</item>
+    <item msgid="7472393097168811593">"ចុះឈ្មោះ​ជាមួយ​ក្រុមហ៊ុន​បម្រើសេវា​ទូរសព្ទរបស់អ្នក (លេខកូដ​មានបញ្ហា៖ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ជំនួយសម្លេង"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ចាក់សោ​ឥឡូវនេះ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"បាន​លាក់​មាតិកា"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"មាតិកាត្រូវបានលាក់ដោយផ្អែកលើគោលការណ៍"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"ការជូនដំណឹងថ្មី"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ក្ដារ​ចុច​និម្មិត"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ក្ដារចុច​រូបវន្ត"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"សុវត្ថិភាព"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ការ​ជូនដំណឹង"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"របៀបដាក់បង្ហាញក្នុងហាង"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"ការ​តភ្ជាប់ USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"កម្មវិធីដែលកំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"កម្មវិធី <xliff:g id="NUMBER">%1$d</xliff:g> កំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"កម្មវិធីដែល​កំពុងប្រើថ្ម"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងប្រើថ្ម"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"កម្មវិធីចំនួន <xliff:g id="NUMBER">%1$d</xliff:g> កំពុងប្រើថ្ម"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ចុចដើម្បីមើលព័ត៌មានលម្អិតអំពីការប្រើប្រាស់ទិន្នន័យ និងថ្ម"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"របៀប​​​សុវត្ថិភាព"</string>
@@ -1108,6 +1107,13 @@
       <item quantity="other">បើកបណ្តាញ Wi-Fi ដែលមាន</item>
       <item quantity="one">បើកបណ្តាញ Wi-Fi ដែលមាន</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"ភ្ជាប់ទៅបណ្តាញ Wi‑Fi ចំហ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"កំពុងភ្ជាប់ទៅបណ្តាញ Wi‑Fi ចំហ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"បានភ្ជាប់ទៅបណ្តាញ Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"មិនអាចភ្ជាប់ទៅបណ្តាញ Wi‑Fi បានទេ"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ចុចដើម្បីមើលបណ្តាញទាំងអស់"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ភ្ជាប់"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"បណ្តាញទាំងអស់"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ចូល​បណ្ដាញ​វ៉ាយហ្វាយ"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ចូលទៅបណ្តាញ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1187,8 +1193,10 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB សម្រាប់ MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"បាន​ភ្ជាប់​ឧបករណ៍​យូអេសប៊ី"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ប៉ះសម្រាប់ជម្រើសជាច្រើនទៀត"</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"បាន​ភ្ជាប់​ការ​កែ​កំហុស​យូអេសប៊ី"</string>
-    <string name="adb_active_notification_message" msgid="4948470599328424059">"ប៉ះដើម្បីបិទដំណើរការកែកំហុសយូអេសប៊ី"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"បាន​រកឃើញ​គ្រឿង​បរិក្ខារ​សំឡេង​អាណាឡូក"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"ឧបករណ៍​ដែលភ្ជាប់​មក​ជាមួយ​មិនត្រូវគ្នា​ជាមួយ​ទូរសព្ទ​នេះទេ។ ចុច​ដើម្បី​ស្វែងយល់​បន្ថែម។"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"បាន​ភ្ជាប់​ការ​កែ​កំហុស​ USB"</string>
+    <string name="adb_active_notification_message" msgid="4948470599328424059">"ប៉ះដើម្បីបិទដំណើរការកែកំហុស USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ជ្រើស​ ដើម្បី​បិទ​ការ​កែ​កំហុស​យូអេសប៊ី។"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"កំពុងទទួលយករបាយការណ៍កំហុស…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ចែករំលែករបាយការណ៍កំហុសឬ?"</string>
@@ -1292,9 +1300,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"បាន​ភ្ជាប់​ទៅ <xliff:g id="SESSION">%s</xliff:g> ។ ប៉ះ ដើម្បី​គ្រប់គ្រង​បណ្ដាញ។"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"បើក​ការ​តភ្ជាប់ VPN ជា​និច្ច..។"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"ភ្ជាប់ VPN ជា​និច្ច"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"បានផ្តាច់ VPN ដែលបើកជានិច្ច"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"បានផ្ដាច់ពី VPN បើកជានិច្ច"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"បើក​កំហុស VPN ជា​និច្ច"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"ប៉ះដើម្បីដំឡើង"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"ប្ដូរការកំណត់បណ្ដាញ ឬការកំណត់ VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"ជ្រើស​​ឯកសារ"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"គ្មាន​ឯកសារ​បាន​ជ្រើស"</string>
     <string name="reset" msgid="2448168080964209908">"កំណត់​ឡើងវិញ"</string>
@@ -1303,8 +1311,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"ប៉ះដើម្បីចាកចេញពីរបៀបរថយន្ត"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ភ្ជាប់ ឬ​ហតស្ពត​សកម្ម"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"ប៉ះដើម្បីកំណត់"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ការភ្ជាប់​ត្រូវបានបិទ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ទាក់ទងអ្នកគ្រប់គ្រង​របស់អ្នកសម្រាប់​ព័ត៌មានលម្អិត"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ថយក្រោយ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"បន្ទាប់​"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"រំលង"</string>
@@ -1725,14 +1731,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"មិនខ្ទាស់"</string>
     <string name="app_info" msgid="6856026610594615344">"ព័ត៌មាន​កម្មវិធី"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"កំណត់ឧបករណ៍ឡើងវិញឬ?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"ប៉ះដើម្បីកំណត់ឧបករណ៍ឡើងវិញ"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"កំពុងចាប់ផ្តើមការបង្ហាញសាកល្បង…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"កំពុងកំណត់ឧបករណ៍ឡើងវិញ…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"កំណត់ឧបករណ៍ឡើងវិញឬ?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"អ្នកនឹងបាត់បង់ការផ្លាស់ប្តូរណាមួយ ហើយការបង្ហាញសាកល្បងនឹងចាប់ផ្តើមម្តងទៀតក្នុងរយៈពេល <xliff:g id="TIMEOUT">%1$s</xliff:g> វិនាទីទៀត…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"បោះបង់"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"កំណត់ឡើងវិញឥឡូវនេះ"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> ដែលបានបិទដំណើរការ"</string>
     <string name="conference_call" msgid="3751093130790472426">"ការហៅជាក្រុម"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"ផ្ទាំងលោត"</string>
@@ -1776,6 +1776,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ភៀសខ្លួនជាបន្ទាន់ពីតំបន់ឆ្នេរ និងតំបន់តាមមាត់ទន្លេទៅកាន់កន្លែងដែលមានសុវត្ថិភាពជាងនេះ ដូចជាទីទួលណាមួយ។"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"សូមរក្សាភាពស្ងប់ស្ងាត់ ហើយស្វែងរកជម្រកសុវត្ថិភាពដែលនៅជិត។"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"សារសាកល្បងពេលមានអាសន្ន"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"ឆ្លើយតប"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"មិន​អនុញ្ញាត​សីុមកាត​ទេ"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"សីុម​មិន​ត្រូវបាន​ផ្តល់ជូន​ទេ"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 8b71aec..65efb56 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"ಸೇವೆ ಹುಡುಕಲಾಗುತ್ತಿದೆ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"ವೈ-ಫೈ ಬಳಸಿಕೊಂಡು ಕರೆ ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಮೊದಲು ಈ ಸಾಧನವನ್ನು ಹೊಂದಿಸಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ತದನಂತರ ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಮತ್ತೆ ವೈ-ಫೈ ಆನ್‌ ಮಾಡಿ."</item>
+    <item msgid="3910386316304772394">"ವೈ-ಫೈ ಮೂಲಕ ಕರೆಗಳನ್ನು ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಈ ಸೇವೆಯನ್ನು ಹೊಂದಿಸಲು ಮೊದಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ಆ ನಂತರ ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಂದ ವೈ-ಫೈ ಕರೆಮಾಡುವಿಕೆಯನ್ನು ಅನ್ನು ಆನ್ ಮಾಡಿ. (ದೋಷ ಕೋಡ್: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"ನಿಮ್ಮ ವಾಹಕದಲ್ಲಿ ನೋಂದಾಯಿಸಿಕೊಳ್ಳಿ"</item>
+    <item msgid="7472393097168811593">"ನಿಮ್ಮ ವಾಹಕದ ಜೊತೆಗೆ ನೋಂದಾಯಿಸಿಕೊಳ್ಳಿ (ದೋಷ ಕೋಡ್: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ಈಗ ಲಾಕ್ ಮಾಡಿ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"ವಿಷಯಗಳನ್ನು ಮರೆಮಾಡಲಾಗಿದೆ"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ನೀತಿಯಿಂದ ಮರೆಮಾಡಲಾಗಿರುವ ವಿಷಯಗಳು"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"ಹೊಸ ಅಧಿಸೂಚನೆ"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ವರ್ಚುಯಲ್ ಕೀಬೋರ್ಡ್"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್‌"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"ಭದ್ರತೆ"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ಎಚ್ಚರಿಕೆಗಳು"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"ರಿಟೇಲ್ ಡೆಮೋ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB ಸಂಪರ್ಕ"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿವೆ"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"ಹಿನ್ನೆಲೆಯಲ್ಲಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ರನ್ ಆಗುತ್ತಿದೆ"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿವೆ"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಬ್ಯಾಟರಿಯನ್ನು ಉಪಯೋಗಿಸುತ್ತಿವೆ"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಬಳಸುತ್ತಿದೆ"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಬ್ಯಾಟರಿ ಬಳಸುತ್ತಿವೆ"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ಬ್ಯಾಟರಿ,ಡೇಟಾ ಬಳಕೆಯ ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"ಸುರಕ್ಷಿತ ಮೋಡ್"</string>
@@ -275,7 +274,7 @@
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"ಸಂಪರ್ಕಗಳು"</string>
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ನಿಮ್ಮ ಸಂಪರ್ಕಗಳನ್ನು ಪ್ರವೇಶಿಸಲು"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"ಸ್ಥಳ"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"ಈ ಸಾಧನದ ಸ್ಥಳ ಪ್ರವೇಶಿಸಲು"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"ಈ ಸಾಧನದ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ಕ್ಯಾಲೆಂಡರ್"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಲು"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -297,7 +296,7 @@
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"ನೀವು ಟೈಪ್ ಮಾಡುವ ಪಠ್ಯವನ್ನು ಗಮನಿಸುತ್ತದೆ"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ಸಂಖ್ಯೆಗಳು ಮತ್ತು ಪಾಸ್‌ವರ್ಡ್‌ಗಳಂತಹ ವೈಯಕ್ತಿಕ ಡೇಟಾವನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"ಡಿಸ್‌ಪ್ಲೇ ವರ್ಧಕ ನಿಯಂತ್ರಿಸುತ್ತದೆ"</string>
-    <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ಪ್ರದರ್ಶನದ ಝೂಮ್ ಮಟ್ಟ ಮತ್ತು ಸ್ಥಳ ನಿರ್ಧಾರವನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
+    <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ಪ್ರದರ್ಶನದ ಝೂಮ್ ಮಟ್ಟ ಮತ್ತು ಸ್ಥಾನ ನಿರ್ಧಾರವನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ಗೆಸ್ಚರ್‌ಗಳನ್ನು ಮಾಡಿ"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ಟ್ಯಾಪ್ ಮಾಡಬಹುದು, ಸ್ವೈಪ್ ಮಾಡಬಹುದು, ಪಿಂಚ್ ಮಾಡಬಹುದು ಮತ್ತು ಇತರ ಗೆಸ್ಚರ್‌ಗಳನ್ನು ಮಾಡಬಹುದು."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್‌ ಸೂಚಕಗಳು"</string>
@@ -310,7 +309,7 @@
     <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ವಿಸ್ತರಿಸಲು ಅಥವಾ ಸಂಕುಚಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_install_shortcut" msgid="4279070216371564234">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಿ"</string>
     <string name="permdesc_install_shortcut" msgid="8341295916286736996">"ಬಳಕೆದಾರರ ಮಧ್ಯಸ್ಥಿಕೆ ಇಲ್ಲದೆಯೇ ಹೋಮ್‌ಸ್ಕ್ರೀನ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಸೇರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
-    <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಅಸ್ಥಾಪಿಸಿ"</string>
+    <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"ಬಳಕೆದಾರರ ಮಧ್ಯಸ್ಥಿಕೆ ಇಲ್ಲದೆಯೇ ಹೋಮ್‌ಸ್ಕ್ರೀನ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ತೆಗೆದುಹಾಕಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"ಹೊರಹೋಗುವ ಕರೆಗಳ ಮಾರ್ಗ ಬದಲಿಸಿ"</string>
     <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"ಬೇರೊಂದು ಸಂಖ್ಯೆಗೆ ಕರೆಯನ್ನು ಮರುನಿರ್ದೇಶಿಸಲು ಆಯ್ಕೆಯ ಜೊತೆಗೆ ಹೊರ ಹೋಗುವ ಕರೆಯ ಸಮಯದಲ್ಲಿ ಡಯಲ್‌ ಮಾಡಿದ ಸಂಖ್ಯೆಯನ್ನು ನೋಡಲು ಅಪ್ಲಿಕೇಶನ್‌‌ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string>
@@ -759,11 +758,11 @@
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"ಖಾತೆ ಅನ್‌ಲಾಕ್"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"ಹಲವಾರು ಪ್ಯಾಟರ್ನ್ ಪ್ರಯತ್ನಗಳು"</string>
     <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"ಅನ್‍ಲಾಕ್ ಮಾಡಲು, ನಿಮ್ಮ Google ಖಾತೆ ಬಳಸಿಕೊಂಡು ಸೈನ್ ಇನ್ ಮಾಡಿ."</string>
-    <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"ಬಳಕೆದಾರಹೆಸರು (ಇಮೇಲ್)"</string>
+    <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"ಬಳಕೆದಾರರಹೆಸರು (ಇಮೇಲ್)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"ಪಾಸ್‌ವರ್ಡ್"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ಸೈನ್‌ ಇನ್‌"</string>
-    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"ಅಮಾನ್ಯ ಬಳಕೆದಾರಹೆಸರು ಅಥವಾ ಪಾಸ್‌ವರ್ಡ್."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"ನಿಮ್ಮ ಬಳಕೆದಾರಹೆಸರು ಅಥವಾ ಪಾಸ್‍ವರ್ಡ್ ಮರೆತಿರುವಿರಾ?\n"<b>"google.com/accounts/recovery"</b>" ಗೆ ಭೇಟಿ ನೀಡಿ."</string>
+    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"ಅಮಾನ್ಯ ಬಳಕೆದಾರರಹೆಸರು ಅಥವಾ ಪಾಸ್‌ವರ್ಡ್."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"ನಿಮ್ಮ ಬಳಕೆದಾರರಹೆಸರು ಅಥವಾ ಪಾಸ್‍ವರ್ಡ್ ಮರೆತಿರುವಿರಾ?\n"<b>"google.com/accounts/recovery"</b>" ಗೆ ಭೇಟಿ ನೀಡಿ."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"ಅನ್‌ಲಾಕ್"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ಧ್ವನಿ ಆನ್ ಮಾಡಿ"</string>
@@ -1013,7 +1012,7 @@
     <string name="whichSendToApplication" msgid="8272422260066642057">"ಇದನ್ನು ಬಳಸಿಕೊಂಡು ಕಳುಹಿಸಿ"</string>
     <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"%1$s ಬಳಸಿಕೊಂಡು ಕಳುಹಿಸಿ"</string>
     <string name="whichSendToApplicationLabel" msgid="8878962419005813500">"ಕಳುಹಿಸು"</string>
-    <string name="whichHomeApplication" msgid="4307587691506919691">"ಮುಖಪುಟ‌ ಅಪ್ಲಿಕೇಶನ್‌  ಆಯ್ಕೆಮಾಡಿ"</string>
+    <string name="whichHomeApplication" msgid="4307587691506919691">"ಮುಖಪುಟ‌ ಅಪ್ಲಿಕೇಶನ್‌ ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"ಮುಖಪುಟ‌ ಎಂಬಂತೆ %1$s ಅನ್ನು ಬಳಸಿ"</string>
     <string name="whichHomeApplicationLabel" msgid="809529747002918649">"ಚಿತ್ರ ಕ್ಯಾಪ್ಚರ್ ಮಾಡಿ"</string>
     <string name="whichImageCaptureApplication" msgid="3680261417470652882">"ಇದರ ಜೊತೆಗೆ ಚಿತ್ರ ಕ್ಯಾಪ್ಚರ್ ಮಾಡಿ"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="one">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿವೆ</item>
       <item quantity="other">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿವೆ</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಿಸಿ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗುತ್ತಿದೆ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ಎಲ್ಲಾ ನೆಟ್‌ವರ್ಕ್‌ಗಳನ್ನು ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ಸಂಪರ್ಕಿಸಿ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ಎಲ್ಲಾ ನೆಟ್‌ವರ್ಕ್‌ಗಳು"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ವೈ-ಫೈ ನೆಟ್‍ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI ಗೆ USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ಪರಿಕರಕ್ಕೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗೆ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"ಅನ್‌ಲಾಗ್ ಆಡಿಯೋ ಪರಿಕರ ಪತ್ತೆಯಾಗಿದೆ"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"ಲಗತ್ತಿಸಲಾದ ಸಾಧನವು ಈ ಫೋನಿನೊಂದಿಗೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ಡೀಬಗಿಂಗ್‌‌ ಸಂಪರ್ಕ"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ."</string>
@@ -1220,10 +1228,10 @@
     <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"ಡೇಟಾ ನಷ್ಟವನ್ನು ತಪ್ಪಿಸಲು ತೆಗೆದುಹಾಕುವುದಕ್ಕೂ ಮುನ್ನ <xliff:g id="NAME">%s</xliff:g> ಅಳವಡಿಕೆಯನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
     <string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"<xliff:g id="NAME">%s</xliff:g> ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
     <string name="ext_media_nomedia_notification_message" msgid="6471542972147056586">"<xliff:g id="NAME">%s</xliff:g> ತೆಗೆದುಹಾಕಲಾಗಿದೆ; ಹೊಸದನ್ನು ಸೇರಿಸಿ"</string>
-    <string name="ext_media_unmounting_notification_title" msgid="640674168454809372">"<xliff:g id="NAME">%s</xliff:g> ಇನ್ನೂ ಎಜೆಕ್ಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
+    <string name="ext_media_unmounting_notification_title" msgid="640674168454809372">"<xliff:g id="NAME">%s</xliff:g> ಇನ್ನೂ ಇಜೆಕ್ಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
     <string name="ext_media_unmounting_notification_message" msgid="4182843895023357756">"ತೆಗೆದುಹಾಕಬೇಡಿ"</string>
     <string name="ext_media_init_action" msgid="7952885510091978278">"ಹೊಂದಿಸು"</string>
-    <string name="ext_media_unmount_action" msgid="1121883233103278199">"ಎಜೆಕ್ಟ್"</string>
+    <string name="ext_media_unmount_action" msgid="1121883233103278199">"ಇಜೆಕ್ಟ್"</string>
     <string name="ext_media_browse_action" msgid="8322172381028546087">"ಎಕ್ಸ್‌ಪ್ಲೋರ್‌‌"</string>
     <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ಕಾಣೆಯಾಗಿದೆ"</string>
     <string name="ext_media_missing_message" msgid="5761133583368750174">"ಈ ಸಾಧನವನ್ನು ಮರುಸೇರಿಸಿ"</string>
@@ -1234,14 +1242,14 @@
     <string name="ext_media_move_failure_title" msgid="7613189040358789908">"ಡೇಟಾ ಸರಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
     <string name="ext_media_move_failure_message" msgid="1978096440816403360">"ಮೂಲ ಸ್ಥಳದಲ್ಲಿ ಡೇಟಾ ಉಳಿದಿದೆ"</string>
     <string name="ext_media_status_removed" msgid="6576172423185918739">"ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
-    <string name="ext_media_status_unmounted" msgid="2551560878416417752">"ಎಜೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
+    <string name="ext_media_status_unmounted" msgid="2551560878416417752">"ಇಜೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="ext_media_status_checking" msgid="6193921557423194949">"ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="ext_media_status_mounted" msgid="7253821726503179202">"ಸಿದ್ಧವಾಗಿದೆ"</string>
     <string name="ext_media_status_mounted_ro" msgid="8020978752406021015">"ಓದಲು ಮಾತ್ರ"</string>
     <string name="ext_media_status_bad_removal" msgid="8395398567890329422">"ಅಪಾಯಕರವಾಗಿ ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
     <string name="ext_media_status_unmountable" msgid="805594039236667894">"ದೋಷಪೂರಿತವಾಗಿದೆ"</string>
     <string name="ext_media_status_unsupported" msgid="4691436711745681828">"ಬೆಂಬಲಿತವಾಗಿಲ್ಲ"</string>
-    <string name="ext_media_status_ejecting" msgid="5463887263101234174">"ಎಜೆಕ್ಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
+    <string name="ext_media_status_ejecting" msgid="5463887263101234174">"ಇಜೆಕ್ಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
     <string name="ext_media_status_formatting" msgid="1085079556538644861">"ಸ್ವರೂಪಗೊಳಿಸುವಿಕೆ..."</string>
     <string name="ext_media_status_missing" msgid="5638633895221670766">"ಸೇರಿಸಲಾಗಿಲ್ಲ"</string>
     <string name="activity_list_empty" msgid="1675388330786841066">"ಯಾವುದೇ ಹೊಂದಾಣಿಕೆಯ ಚಟುವಟಿಕೆಗಳು ಕಂಡುಬಂದಿಲ್ಲ."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ. ನೆಟ್‍ವರ್ಕ್ ನಿರ್ವಹಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"ಯಾವಾಗಲೂ-ಆನ್ VPN ಸಂಪರ್ಕಗೊಳ್ಳುತ್ತಿದೆ…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"ಯಾವಾಗಲೂ-ಆನ್ VPN ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"ಯಾವಾಗಲೂ-ಆನ್ VPN ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"ಯಾವಾಗಲೂ ಆನ್ ಆಗಿರುವ VPN ನಿಂದ ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"ಯಾವಾಗಲೂ-ಆನ್ VPN ದೋಷ"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"ನೆಟ್‌ವರ್ಕ್‌ ಅಥವಾ VPN ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಿ"</string>
     <string name="upload_file" msgid="2897957172366730416">"ಫೈಲ್ ಆಯ್ಕೆಮಾಡು"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"ಯಾವುದೇ ಫೈಲ್ ಆಯ್ಕೆ ಮಾಡಿಲ್ಲ"</string>
     <string name="reset" msgid="2448168080964209908">"ಮರುಹೊಂದಿಸು"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"ಕಾರು ಮೋಡ್‍ನಿಂದ ನಿರ್ಗಮಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ಟೆಥರಿಂಗ್ ಅಥವಾ ಹಾಟ್‌ಸ್ಪಾಟ್ ಸಕ್ರಿಯವಾಗಿದೆ"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ಟೆಥರಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ಹಿಂದೆ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ಮುಂದಿನದು"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ಸ್ಕಿಪ್‌"</string>
@@ -1458,11 +1464,11 @@
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ಪಿನ್‌ ಕೋಡ್‍ಗಳು ಹೊಂದಾಣಿಕೆಯಾಗುತ್ತಿಲ್ಲ"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ಹಲವಾರು ಪ್ಯಾಟರ್ನ್ ಪ್ರಯತ್ನಗಳು"</string>
     <string name="kg_login_instructions" msgid="1100551261265506448">"ಅನ್‍ಲಾಕ್ ಮಾಡಲು, ನಿಮ್ಮ Google ಖಾತೆ ಬಳಸಿಕೊಂಡು ಸೈನ್ ಇನ್ ಮಾಡಿ."</string>
-    <string name="kg_login_username_hint" msgid="5718534272070920364">"ಬಳಕೆದಾರಹೆಸರು (ಇಮೇಲ್)"</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"ಬಳಕೆದಾರರಹೆಸರು (ಇಮೇಲ್)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"ಪಾಸ್‌ವರ್ಡ್"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
-    <string name="kg_login_invalid_input" msgid="5754664119319872197">"ಅಮಾನ್ಯ ಬಳಕೆದಾರಹೆಸರು ಅಥವಾ ಪಾಸ್‍ವರ್ಡ್."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ನಿಮ್ಮ ಬಳಕೆದಾರಹೆಸರು ಅಥವಾ ಪಾಸ್‍ವರ್ಡ್ ಮರೆತಿರುವಿರಾ?\n"<b>"google.com/accounts/recovery"</b>" ಗೆ ಭೇಟಿ ನೀಡಿ."</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"ಅಮಾನ್ಯ ಬಳಕೆದಾರರಹೆಸರು ಅಥವಾ ಪಾಸ್‍ವರ್ಡ್."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ನಿಮ್ಮ ಬಳಕೆದಾರರಹೆಸರು ಅಥವಾ ಪಾಸ್‍ವರ್ಡ್ ಮರೆತಿರುವಿರಾ?\n"<b>"google.com/accounts/recovery"</b>" ಗೆ ಭೇಟಿ ನೀಡಿ."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"ಖಾತೆಯನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ…"</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ನಿಮ್ಮ ಪಿನ್‌ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"ನಿಮ್ಮ ಪಾಸ್‍‍ವರ್ಡ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
@@ -1577,7 +1583,7 @@
     <string name="mediasize_japanese_kahu" msgid="6872696027560065173">"Kahu"</string>
     <string name="mediasize_japanese_kaku2" msgid="2359077233775455405">"Kaku2"</string>
     <string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string>
-    <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"ಅಪರಿಚಿತ ಪೋಟ್ರೇಟ್"</string>
+    <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"ಅಪರಿಚಿತ ಪೋರ್ಟ್ರೇಟ್"</string>
     <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"ಅಪರಿಚಿತ ಲ್ಯಾಂಡ್‌ಸ್ಕೇಪ್"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ರದ್ದುಮಾಡಲಾಗಿದೆ"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"ವಿಷಯವನ್ನು ಬರೆಯುವಲ್ಲಿ ದೋಷ ಎದುರಾಗಿದೆ"</string>
@@ -1621,7 +1627,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ಅನ್‌ಪಿನ್ ಮಾಡಲು ಅನ್‌ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಕೇಳಿ"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ಅನ್‌ಪಿನ್ ಮಾಡಲು ಪಾಸ್‌ವರ್ಡ್ ಕೇಳು"</string>
     <string name="package_installed_device_owner" msgid="6875717669960212648">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಸ್ಥಾಪಿಸಿದ್ದಾರೆ"</string>
-    <string name="package_updated_device_owner" msgid="1847154566357862089">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಅಪ್‌ಡೇಟ್ ಮಾಡಿದ್ದಾರೆ"</string>
+    <string name="package_updated_device_owner" msgid="1847154566357862089">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರಿಂದ ಅಪ್‌ಡೇಟ್ ಮಾಡಲ್ಪಟ್ಟಿದೆ"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಅಳಿಸಿದ್ದಾರೆ"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"ಬ್ಯಾಟರಿಯ ಬಾಳಿಕೆಯನ್ನು ಸುಧಾರಿಸುವ ನಿಟ್ಟಿನಲ್ಲಿ, ಬ್ಯಾಟರಿ ಉಳಿಕೆಯು ನಿಮ್ಮ ಸಾಧನದ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ ಮತ್ತು ವೈಬ್ರೇಷನ್, ಸ್ಥಳ ಸೇವೆಗಳು ಹಾಗೂ ಹೆಚ್ಚಿನ ಹಿನ್ನೆಲೆ ಡೇಟಾವನ್ನು ಮಿತಿಗೊಳಿಸುತ್ತದೆ. ಸಿಂಕ್ ಮಾಡುವಿಕೆಯನ್ನು ಅವಲಂಬಿಸಿರುವ ಇಮೇಲ್, ಸಂದೇಶ ಕಳುಹಿಸುವಿಕೆ ಮತ್ತು ಇತರ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ನೀವು ತೆರೆಯದ ಹೊರತು ಅಪ್‌ಡೇಟ್‌ ಆಗುವುದಿಲ್ಲ.\n\nನಿಮ್ಮ ಸಾಧನವು ಚಾರ್ಜ್ ಆಗುತ್ತಿರುವಾಗ ಬ್ಯಾಟರಿ ಉಳಿಕೆಯು ಆಫ್ ಆಗುತ್ತದೆ."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"ಡೇಟಾ ಬಳಕೆ ಕಡಿಮೆ ಮಾಡುವ ನಿಟ್ಟಿನಲ್ಲಿ, ಡೇಟಾ ಸೇವರ್ ಕೆಲವು ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಡೇಟಾ ಕಳುಹಿಸುವುದನ್ನು ಅಥವಾ ಸ್ವೀಕರಿಸುವುದನ್ನು ತಡೆಯುತ್ತದೆ. ನೀವು ಪ್ರಸ್ತುತ ಬಳಸುತ್ತಿರುವ ಅಪ್ಲಿಕೇಶನ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು ಆದರೆ ಪದೇ ಪದೇ ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ. ಇದರರ್ಥ, ಉದಾಹರಣೆಗೆ, ನೀವು ಅವುಗಳನ್ನು ಟ್ಯಾಪ್ ಮಾಡುವವರೆಗೆ ಆ ಚಿತ್ರಗಳು ಕಾಣಿಸಿಕೊಳ್ಳುವುದಿಲ್ಲ."</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"ಅನ್‌ಪಿನ್"</string>
     <string name="app_info" msgid="6856026610594615344">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"ಸಾಧನವನ್ನು ಮರುಹೊಂದಿಸುವುದೇ?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"ಸಾಧನ ಮರುಹೊಂದಿಸಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ಡೆಮೋ ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"ಸಾಧನ ಮರುಹೊಂದಿಸಲಾಗುತ್ತಿದೆ..."</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"ಸಾಧನವನ್ನು ಮರುಹೊಂದಿಸುವುದೇ?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"ನೀವು ಯಾವುದೇ ಬದಲಾವಣೆಗಳನ್ನು ಕಳೆದುಕೊಳ್ಳುತ್ತೀರಿ ಮತ್ತು <xliff:g id="TIMEOUT">%1$s</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಡೆಮೋ ಮತ್ತೆ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ..."</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"ರದ್ದುಮಾಡಿ"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"ಈಗಲೇ ಮರುಹೊಂದಿಸು"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="conference_call" msgid="3751093130790472426">"ಕಾನ್ಫರೆನ್ಸ್ ಕರೆ"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"ಟೂಲ್‌ಟಿಪ್"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ಕರಾವಳಿ ಪ್ರದೇಶಗಳು ಮತ್ತು ನದಿ ತೀರಗಳಿಂದ ತಕ್ಷಣವೇ ಎತ್ತರದ ಪ್ರದೇಶಗಳಂತಹ ಸುರಕ್ಷಿತ ಸ್ಥಳಕ್ಕೆ ಹೋಗಿ."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ಶಾಂತರಾಗಿರಿ ಮತ್ತು ಸಮೀಪದಲ್ಲೆಲ್ಲಾದರೂ ಆಶ್ರಯ ಪಡೆದುಕೊಳ್ಳಿ."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"ತುರ್ತು ಸಂದೇಶಗಳ ಪರೀಕ್ಷೆ"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"ಪ್ರತ್ಯುತ್ತರ"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"ಸಿಮ್‌ಗೆ ಅನುಮತಿಯಿಲ್ಲ"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"ಸಿಮ್ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index fd56280..6f59df6 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"서비스 검색 중"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 통화"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 이 기능을 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다."</item>
+    <item msgid="3910386316304772394">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 서비스를 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다. (오류 코드: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"이동통신사에 등록"</item>
+    <item msgid="7472393097168811593">"이동통신사에 등록하세요(오류 코드: <xliff:g id="CODE">%1$s</xliff:g>)."</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -206,7 +206,7 @@
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"업데이트 준비 중…"</string>
     <string name="reboot_to_update_package" msgid="3871302324500927291">"업데이트 패키지 처리 중…"</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"다시 시작하는 중..."</string>
-    <string name="reboot_to_reset_title" msgid="4142355915340627490">"공장 초기화"</string>
+    <string name="reboot_to_reset_title" msgid="4142355915340627490">"초기화"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"다시 시작하는 중..."</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"종료 중..."</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"태블릿이 종료됩니다."</string>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"음성 지원"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"지금 잠그기"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"숨겨진 콘텐츠"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"콘텐츠가 정책에 의해 숨겨졌습니다."</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"새 알림"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"가상 키보드"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"물리적 키보드"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"보안"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"알림"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"소매 데모"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB 연결"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"백그라운드에서 실행 중인 앱"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱이 백그라운드에서 실행 중"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g>개의 앱이 백그라운드에서 실행 중"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"배터리를 소모하는 앱"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 배터리 사용 중"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"앱 <xliff:g id="NUMBER">%1$d</xliff:g>개에서 배터리 사용 중"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"탭하여 배터리 및 데이터 사용량 확인"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"안전 모드"</string>
@@ -280,7 +279,7 @@
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"캘린더에 액세스"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS 메시지 전송 및 보기"</string>
-    <string name="permgrouplab_storage" msgid="1971118770546336966">"저장"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"저장용량"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"기기 사진, 미디어, 파일 액세스"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"마이크"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"오디오 녹음"</string>
@@ -364,11 +363,11 @@
     <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"앱이 브로드캐스트가 끝난 후에 남은 브로드캐스트를 보낼 수 있도록 허용합니다. 앱을 지나치게 사용하면 태블릿에서 메모리를 너무 많이 사용하도록 하여 속도를 저하시키거나 불안정하게 만들 수 있습니다."</string>
     <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"앱이 브로드캐스트가 끝난 후에도 흥미로운 브로드캐스트를 보낼 수 있도록 허용합니다. 이 기능을 과도하게 사용하면 메모리 사용량이 많아져 TV 속도가 저하되거나 성능이 불안정해질 수 있습니다."</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"앱이 브로드캐스트가 끝난 후에 남은 브로드캐스트를 보낼 수 있도록 허용합니다. 앱을 지나치게 사용하면 휴대전화에서 메모리를 너무 많이 사용하도록 하여 속도를 저하시키거나 불안정하게 만들 수 있습니다."</string>
-    <string name="permlab_readContacts" msgid="8348481131899886131">"주소록 읽기"</string>
+    <string name="permlab_readContacts" msgid="8348481131899886131">"연락처 읽기"</string>
     <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"특정인과 전화, 이메일 또는 기타 수단으로 연락한 빈도를 포함하여 사용자 태블릿에 저장된 연락처에 대한 데이터를 앱이 읽도록 허용합니다. 이 권한을 사용하면 앱이 연락처 데이터를 저장할 수 있으며, 악성 앱이 사용자 모르게 연락처 데이터를 공유할 수도 있습니다."</string>
     <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"앱이 특정 연락처와 통화를 하거나 이메일을 주고받거나 다른 방법으로 연락한 횟수를 포함하여 TV에 저장된 연락처 관련 데이터를 읽을 수 있도록 허용합니다. 이 경우 앱이 연락처 데이터를 저장할 수 있으며 악성 앱이 사용자 몰래 연락처 데이터에 공유할 수도 있습니다."</string>
     <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"특정인과 전화, 이메일 또는 기타 수단으로 연락한 빈도를 포함하여 사용자 휴대전화에 저장된 연락처에 대한 데이터를 앱이 읽도록 허용합니다. 이 권한을 사용하면 앱이 연락처 데이터를 저장할 수 있으며, 악성 앱이 사용자 모르게 연락처 데이터를 공유할 수도 있습니다."</string>
-    <string name="permlab_writeContacts" msgid="5107492086416793544">"주소록 수정"</string>
+    <string name="permlab_writeContacts" msgid="5107492086416793544">"연락처 수정"</string>
     <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"특정인과 전화, 이메일 또는 기타 수단으로 연락한 빈도를 포함하여 사용자 태블릿에 저장된 연락처에 대한 데이터를 앱이 수정할 수 있도록 허용합니다. 이 권한을 사용하면 앱이 연락처 데이터를 삭제할 수 있습니다."</string>
     <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"앱이 특정 연락처와 통화를 하거나 이메일을 주고받거나 다른 수단으로 연락한 횟수를 포함하여 TV에 저장된 연락처 관련 데이터를 수정할 수 있도록 허용합니다. 이 경우 앱이 연락처 데이터를 삭제할 수 있습니다."</string>
     <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"특정인과 전화, 이메일 또는 기타 수단으로 연락한 빈도를 포함하여 사용자 휴대전화에 저장된 연락처에 대한 데이터를 앱이 수정할 수 있도록 허용합니다. 이 권한을 사용하면 앱이 연락처 데이터를 삭제할 수 있습니다."</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">개방형 Wi-Fi 네트워크 사용 가능</item>
       <item quantity="one">개방형 Wi-Fi 네트워크 사용 가능</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"공개 Wi‑Fi 네트워크에 연결"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"공개 Wi‑Fi 네트워크에 연결 중"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi 네트워크에 연결됨"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi 네트워크에 연결할 수 없음"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"모든 네트워크를 보려면 탭하세요."</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"연결"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"모든 네트워크"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi 네트워크에 로그인"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"네트워크에 로그인"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI용 USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB 액세서리에 연결됨"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"옵션을 더 보려면 탭하세요."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"아날로그 오디오 액세서리가 감지됨"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"연결된 기기가 이 휴대전화와 호환되지 않습니다. 자세히 알아보려면 탭하세요."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB 디버깅을 사용하지 않으려면 탭하세요."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB 디버깅을 사용하지 않으려면 선택합니다."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g>에 연결되어 있습니다. 네트워크를 관리하려면 누르세요."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"연결 유지 VPN에 연결하는 중…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"연결 유지 VPN에 연결됨"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"연결 유지 VPN 연결 해제됨"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"연결 유지 VPN 연결이 해제됨"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"연결 유지 VPN 오류"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"탭하여 설정"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"네트워크 또는 VPN 설정 변경"</string>
     <string name="upload_file" msgid="2897957172366730416">"파일 선택"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"파일을 선택하지 않았습니다."</string>
     <string name="reset" msgid="2448168080964209908">"초기화"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"운전 모드를 종료하려면 탭하세요."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"테더링 또는 핫스팟 사용"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"설정하려면 탭하세요."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"테더링이 사용 중지됨"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"자세한 정보는 관리자에게 문의하세요."</string>
     <string name="back_button_label" msgid="2300470004503343439">"뒤로"</string>
     <string name="next_button_label" msgid="1080555104677992408">"다음"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"건너뛰기"</string>
@@ -1624,7 +1630,7 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"관리자에 의해 업데이트되었습니다."</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"관리자에 의해 삭제되었습니다."</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"배터리 수명 개선을 위해, 배터리 세이버는 기기의 성능을 줄이고 진동, 위치 서비스 및 대부분의 백그라운드 데이터를 제한합니다. 이메일, 메시지 및 동기화에 의존하는 기타 앱은 앱을 열 때까지 업데이트되지 않을 수 있습니다.\n\n배터리 세이버는 기기를 충전 중일 때는 자동으로 사용 중지됩니다."</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"데이터 사용량을 줄이기 위해 데이터 절약 모드는 일부 앱이 백그라운드에서 데이터를 전송하거나 수신하지 못하도록 합니다. 현재 사용 중인 앱에서 데이터에 액세스할 수 있지만 빈도가 줄어듭니다. 즉, 예를 들어 이미지를 탭하기 전에는 이미지가 표시되지 않습니다."</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"데이터 사용량을 줄이기 위해 데이터 절약 모드는 일부 앱이 백그라운드에서 데이터를 전송하거나 수신하지 못하도록 합니다. 현재 사용 중인 앱에서 데이터에 액세스할 수 있지만 빈도가 줄어듭니다. 예를 들면, 이미지를 탭하기 전에는 이미지가 표시되지 않습니다."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"데이터 절약 모드를 사용할까요?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"사용 설정"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"고정 해제"</string>
     <string name="app_info" msgid="6856026610594615344">"앱 정보"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"기기를 초기화하시겠습니까?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"기기를 초기화하려면 탭하세요."</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"데모 시작 중..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"기기 초기화 중..."</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"기기를 초기화하시겠습니까?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"변경사항이 사라지며 데모가 <xliff:g id="TIMEOUT">%1$s</xliff:g>초 후에 시작됩니다."</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"취소"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"지금 초기화"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> 사용 중지됨"</string>
     <string name="conference_call" msgid="3751093130790472426">"다자간 통화"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"도움말"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"즉시 해안 지대나 강가에서 떨어져 고지대 등 안전한 장소로 대피하세요."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"침착하게 가까운 대피소를 찾으세요."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"긴급 메시지 테스트"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"답장"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM이 허용되지 않음"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM이 프로비저닝되지 않음"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 7c4c1fa..a983446 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Кызмат изделүүдө"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Чалуу"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз."</item>
+    <item msgid="3910386316304772394">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде байланыш операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз. (Ката коду: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Операторуңузга катталыңыз"</item>
+    <item msgid="7472393097168811593">"Операторуңузга катталыңыз (Ката коду: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Үн жардамчысы"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Азыр кулпулоо"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Мазмундар жашырылган"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Тийиштүү саясат боюнча жашырылган мазмундар"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Жаңы эскертме"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуалдык баскычтоп"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Аппараттык баскычтоп"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Коопсуздук"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Эскертүүлөр"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Чекене соода дүкөнү үчүн демо режим"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB аркылуу туташуу"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Фондо иштеп жаткан колдонмолор"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу фондо иштеп жатат"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> колдонмо фондо иштөөдө"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Колдонмолор батареяңызды коротууда"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу батареяны пайдаланып жатат"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> колдонмо батареяны пайдаланып жатат"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Батареянын кубаты жана трафиктин көлөмү жөнүндө билүү үчүн таптап коюңуз"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Коопсуз режим"</string>
@@ -490,7 +489,7 @@
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Аракеттер өтө көп болду. Кийинчерээк кайра аракет кылыңыз."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Өтө көп жолу аракет жасадыңыз. Манжа изинин сенсору өчүрүлдү."</string>
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Кайра бир аракеттениңиз."</string>
-    <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g> манжасы"</string>
+    <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g>-манжа"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Манжа изинин сөлөкөтү"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Ачык Wi-Fi тармагы жеткиликтүү</item>
       <item quantity="one">Ачык Wi-Fi тармагы жеткиликтүү</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Ачык Wi‑Fi тармагына туташуу"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ачык Wi‑Fi тармагына туташууда"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ачык Wi‑Fi тармагына туташты"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi-Fi тармагына туташпай калды"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Бардык тармактарды көрүү үчүн басыңыз"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Туташуу"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Бардык тармактар"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi түйүнүнө кирүү"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Тармакка кирүү"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI үчүн USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB аксессуарга байланышты"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Кошумча параметрлерди ачуу үчүн таптап коюңуз."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Аналогдук аудио жабдуу табылды"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Тиркелген түзмөк бул телефонго шайкеш келбейт. Көбүрөөк маалымат алуу үчүн таптап коюңуз."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Мүчүлүштүктөрдү USB аркылуу оңдоо иштетилген"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Мүчүлштктрдү USB аркл оңдну өчр үчн тийп коюңуз."</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
@@ -1291,9 +1299,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> сеансына туташуу ишке ашты. Желенин параметрлерин өзгөртүү үчүн бул жерди басыңыз."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Дайым иштеген VPN туташууда…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Дайым иштеген VPN туташтырылды"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Дайым иштеген VPN ажыратылды"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Ар дайым иштеген VPN\'ден ажыратуу"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Дайым иштеген VPN\'де ката кетти"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Жөндөө үчүн таптаңыз"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Тармакты же VPN жөндөөлөрүн өзгөртүү"</string>
     <string name="upload_file" msgid="2897957172366730416">"Файл тандоо"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Эч файл тандалган жок"</string>
     <string name="reset" msgid="2448168080964209908">"Баштапкы абалга келтирүү"</string>
@@ -1302,8 +1310,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Унаа режиминен чыгуу үчүн таптап коюңуз."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Жалгаштыруу же хотспот жандырылган"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Жөндөө үчүн таптап коюңуз."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Жалгаштыруу функциясы өчүрүлгөн"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Кеңири маалымат үчүн администраторуңузга кайрылыңыз"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Артка"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Кийинки"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Өткөрүп жиберүү"</string>
@@ -1383,7 +1389,7 @@
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"4G дайындар чегине жетти"</string>
     <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Мобилдик трафик чегине жетти"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Wi-Fi дайындар чегине жетти"</string>
-    <string name="data_usage_limit_body" msgid="291731708279614081">"Калган мерчимде дайындар бир азга токтотулду"</string>
+    <string name="data_usage_limit_body" msgid="291731708279614081">"Маалымат алмашуу токтотулду"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G трафик чектен ашты"</string>
     <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G трафик чектен ашты"</string>
     <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Мобилдик трафик чегинен ашты"</string>
@@ -1601,7 +1607,7 @@
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Кийинчерээк кайталаңыз"</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"Толук экран режими"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"Чыгуу үчүн, жогурдан төмөн сүрүңүз."</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"Чыгуу үчүн экранды ылдый сүрүп коюңуз."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"Түшүндүм"</string>
     <string name="done_label" msgid="2093726099505892398">"Даяр"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"Саат жебеси"</string>
@@ -1724,14 +1730,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Кадоодон алып коюу"</string>
     <string name="app_info" msgid="6856026610594615344">"Колдонмо тууралуу"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Түзмөк баштапкы абалга келтирилсинби?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Түзмөктү баштапкы абалга келтирүү үчүн таптап коюңуз"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Демо режим башталууда…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Түзмөк баштапкы абалга келтирилүүдө…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Түзмөк баштапкы абалга келтирилсинби?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Бардык өзгөртүүлөр жоголуп, демо режим <xliff:g id="TIMEOUT">%1$s</xliff:g> секунддан кийин кайра башталат…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Жокко чыгаруу"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Баштапкы абалга келтирүү"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> өчүрүлдү"</string>
     <string name="conference_call" msgid="3751093130790472426">"Конференц чалуу"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Калкып чыгуучу кеңеш"</string>
@@ -1775,6 +1775,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Деңиз жана дарыя жээгинде жайгашкан аймактардан бийик тоо сыяктуу коопсуз жерге тезинен чыгып кетиңиз."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Эс алып, жакын жерден калканч издеңиз."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Өзгөчө кырдаалда жөнөтүлүүчү билдирүүлөрдү сыноо"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Жооп берүү"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM картаны колдонууга тыюу салынган"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM карта таанылган жок"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 390a60d..0d105d3 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"ຊອກຫາບໍລິການ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ການ​ໂທ Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"ເພື່ອ​ໂທ ແລະ​ສົ່ງ​ຂໍ້​ຄວາມ​ຢູ່​ເທິງ Wi-Fi, ກ່ອນ​ອື່ນ​ໝົດ​ໃຫ້​ຖ້າມ​ຜູ້​ໃຫ້​ບໍ​ລິ​ການ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ ເພື່ອ​ຕັ້ງ​ການ​ບໍ​ລິ​ການ​ນີ້. ຈາກນັ້ນ​ເປີດການ​ໂທ Wi-Fi ອີກ​ຈາກ​ການ​ຕັ້ງ​ຄ່າ."</item>
+    <item msgid="3910386316304772394">"ເພື່ອໂທ ແລະ ສົ່ງຂໍ້ຄວາມຜ່ານ Wi-Fi, ໃຫ້ແຈ້ງໃຫ້ຜູ້ໃຫ້ບໍລິການຂອງທ່ານຕັ້ງບໍລິການນີ້. ຈາກນັ້ນເປີດໃຊ້ການໂທ Wi-Fi ອີກຄັ້ງຈາກການຕັ້ງຄ່າ. (ລະຫັດຂໍ້ຜິດພາດ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"ລົງ​ທະ​ບຽນ​ກັບ​ຜູ້​ໃຫ້​ບໍ​ລິ​ການ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ"</item>
+    <item msgid="7472393097168811593">"ລົງທະບຽນກັບຜູ້ໃຫ້ບໍລິການຂອງທ່ານ (ລະຫັດຂໍ້ຜິດພາດ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ຊ່ວຍ​ເຫຼືອ​ທາງ​ສຽງ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ລັອກ​ດຽວ​ນີ້"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"ເນື້ອຫາ​ຖືກ​ເຊື່ອງ​ໄວ້"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ເນື້ອຫາຖືກເຊື່ອງຕາມນະໂຍບາຍ"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"ການແຈ້ງເຕືອນໃໝ່"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ແປ້ນພິມສະເໝືອນ"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ແປ້ນພິມພາຍນອກ"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"ຄວາມປອດໄພ"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ການເຕືອນ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"ເດໂມສຳລັບຮ້ານຂາຍ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"ການເຊື່ອມຕໍ່ USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ແອັບທີ່ກຳລັງເຮັດວຽກໃນພື້ນຫຼັງ"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງເຮັດວຽກໃນພື້ນຫຼັງ"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"ແອັບ <xliff:g id="NUMBER">%1$d</xliff:g> ແອັບກຳລັງເຮັດວຽກໃນພື້ນຫຼັງ"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ແອັບທີ່ກຳລັງໃຊ້ແບັດເຕີຣີ"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງໃຊ້ແບັດເຕີຣີຢູ່"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ແອັບກຳລັງໃຊ້ແບັດເຕີຣີຢູ່"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ແຕະເພື່ອເບິ່ງລາຍລະອຽດການນຳໃຊ້ແບັດເຕີຣີ ແລະ ອິນເຕີເນັດ"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
@@ -275,7 +274,7 @@
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"ລາຍຊື່"</string>
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ເຂົ້າ​ຫາ​ລາຍ​ຊື່​ຂອງ​ທ່ານ"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"ສະ​ຖານ​ທີ່"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"ເຂົ້າເຖິງທີ່ຕັ້ງອຸປະກອນນີ້"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"ເຂົ້າເຖິງຂໍ້ມູນສະຖານທີ່ຂອງອຸປະກອນນີ້"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ປະຕິທິນ"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ເຂົ້າ​ຫາ​ປະ​ຕິ​ທິນ​ຂອງ​ທ່ານ"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">ເປີດເຄືອຂ່າຍ Wi-Fi  ທີ່ມີໃຫ້</item>
       <item quantity="one">ເປີດເຄືອຂ່າຍ Wi-Fi  ທີ່ມີໃຫ້</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"ເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ແບບເປີດ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ກຳລັງເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"ເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ແລ້ວ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ບໍ່ສາມາດເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ໄດ້"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ແຕະເພື່ອເບິ່ງເຄືອຂ່າຍທັງໝົດ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ເຊື່ອມ​ຕໍ່"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ເຄືອຂ່າຍທັງໝົດ"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ເຂົ້າສູ່ລະບົບເຄືອຂ່າຍ Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ລົງຊື່ເຂົ້າເຄືອຂ່າຍ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,7 +1191,9 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB ສຳ​ລັບ MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"ເຊື່ອມຕໍ່ກັບອຸປະກອນເສີມ USB ແລ້ວ"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ແຕະເພື່ອເບິ່ງຕົວເລືອກເພີ່ມເຕີມ."</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"ເຊື່ອມຕໍ່ການດີບັ໊ກຜ່ານ USB ແລ້ວ"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"ກວດພົບອຸປະກອນເສີມສຽງ"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"ອຸປະກອນທີ່ເຊື່ອມຕໍ່ນັ້ນບໍ່ສາມາດໃຊ້ຮ່ວມກັບໂທລະສັບນີ້ໄດ້. ແຕະເພື່ອສຶກສາເພີ່ມເຕີມ."</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"ເຊື່ອມຕໍ່ການດີບັກຜ່ານ USB ແລ້ວ"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"ແຕະເພື່ອປິດການດີບັກຜ່ານ USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ເລືອກເພື່ອປິດການດີບັ໊ກຜ່ານ USB."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ກຳລັງຂໍລາຍງານຂໍ້ຜິດພາດ…"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"ເຊື່ອມຕໍ່ກັບ <xliff:g id="SESSION">%s</xliff:g> ແລ້ວ. ແຕະເພື່ອຈັດການເຄືອຂ່າຍ."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"ກຳລັງເຊື່ອມຕໍ່ Always-on VPN…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"ເຊື່ອມຕໍ່ VPN ແບບເປີດຕະຫຼອດເວລາແລ້ວ"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"ຕັດການເຊື່ອມຕໍ່ VPN ແບບເປີດໃຊ້ຕະຫຼອດເວລາແລ້ວ"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"ຕັດການເຊື່ອມຕໍ່ຈາກ VPN ແບບເປີດຕະຫຼອດແລ້ວ"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"VPN ແບບເປີດຕະຫຼອດເກີດຄວາມຜິດພາດ"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"ແຕະເພື່ອຕັ້ງຄ່າ"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"ປ່ຽນການຕັ້ງຄ່າເຄືອຂ່າຍ ຫຼື ການຕັ້ງຄ່າ VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"ເລືອກໄຟລ໌"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"ບໍ່ໄດ້ເລືອກໄຟລ໌ເທື່ອ"</string>
     <string name="reset" msgid="2448168080964209908">"ຣີເຊັດ"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"ແຕະເພື່ອອອກຈາກໂໝດລົດ."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ເປີດ​ການ​ປ່ອຍ​ສັນຍານ ຫຼື​ຮັອດສະປອດ​ແລ້ວ"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"ແຕະເພື່ອຕັ້ງຄ່າ."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ການປ່ອຍສັນຍານຖືກປິດໄວ້"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບລາຍລະອຽດ"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ກັບຄືນ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ຕໍ່ໄປ"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ຂ້າມ"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"ຖອນປັກໝຸດ"</string>
     <string name="app_info" msgid="6856026610594615344">"ຂໍ້ມູນແອັບ"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"ຣີເຊັດອຸປະກອນບໍ?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"ແຕະເພື່ອຣີເຊັດອຸປະກອນ"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ກຳລັງເລີ່ມເດໂມ…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"ກຳລັງຣີເຊັດອຸປະກອນ…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"ຣີເຊັດອຸປະກອນບໍ?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"ທ່ານຈະສູນເສຍການປ່ຽນແປງ ແລະ ເດໂມຈະເລີ່ມອີກຄັ້ງໃນອີກ <xliff:g id="TIMEOUT">%1$s</xliff:g> ວິນາທີ…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"ຍົກເລີກ"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"ຣີເຊັດດຽວນີ້"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"ປິດການນຳໃຊ້ <xliff:g id="LABEL">%1$s</xliff:g> ແລ້ວ"</string>
     <string name="conference_call" msgid="3751093130790472426">"ການປະຊຸມສາຍ"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"ຄຳອະທິບາຍເຄື່ອງມື"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ອົບພະຍົບອອກຈາກເຂດຊາຍຝັ່ງທະເລ ແລະ ບໍລິເວນແມ່ນ້ຳໄປບ່ອນທີ່ປອດໄພກວ່າ ເຊັ່ນ: ບ່ອນສູງ ໂດຍທັນທີ."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ໃຈເຢັນໆ ແລະ ຊອກຫາບ່ອນພັກຢູ່ໃກ້ໆ."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"ທົດສອບຂໍ້ຄວາມສຸກເສີນ"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"ຕອບກັບ"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ SIM"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"ບໍ່ມີການນຳໃຊ້ SIM"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 4b2699a..420edcc 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -133,10 +133,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Ieškoma paslaugos"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"„Wi-Fi“ skambinimas"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Jei norite skambinti ir siųsti pranešimus „Wi-Fi“ ryšiu, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite skambinimą „Wi-Fi“ ryšiu „Nustatymų“ skiltyje."</item>
+    <item msgid="3910386316304772394">"Jei norite skambinti ir siųsti pranešimus naudodami „Wi-Fi“, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite „Wi-Fi“ skambinimą skiltyje „Nustatymai“. (Klaidos kodas: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Užregistruokite pas operatorių"</item>
+    <item msgid="7472393097168811593">"Užregistruokite pas operatorių (klaidos kodas: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -252,8 +252,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Užrakinti dabar"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Turinys paslėptas"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Turinys paslėptas vadovaujantis politika"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Naujas pranešimas"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtualioji klaviatūra"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fizinė klaviatūra"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Sauga"</string>
@@ -269,9 +268,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Įspėjimai"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstracinė versija mažmenininkams"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB jungtis"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Programos, veikiančios fone"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ veikia fone"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Programos (<xliff:g id="NUMBER">%1$d</xliff:g>) veikia fone"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Programos, naudojančios akumuliatoriaus energiją"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ naudoja akumuliatoriaus energiją"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Programų, naudojančių akumuliatoriaus energiją: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Palieskite ir sužinokite išsamios informacijos apie akumuliatoriaus bei duomenų naudojimą"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Saugos režimas"</string>
@@ -1150,6 +1149,13 @@
       <item quantity="many">Pasiekiami atvirieji „Wi-Fi“ tinklai</item>
       <item quantity="other">Pasiekiami atvirieji „Wi-Fi“ tinklai</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Prisijunkite prie atviro „Wi‑Fi“ tinklo"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Prisijungiama prie atviro „Wi‑Fi“ tinklo"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Prisijungta prie „Wi-Fi“ tinklo"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nepavyko prisijungti prie „Wi‑Fi“ tinklo"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Palieskite, jei norite matyti visus tinklus"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Prisijungti"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Visi tinklai"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prisijungti prie „Wi-Fi“ tinklo"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prisijungti prie tinklo"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1229,6 +1235,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB (MIDI)"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Prijungta prie USB priedo"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Palieskite, kad būtų rodoma daugiau parinkčių."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Aptiktas analoginis garso priedas"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Prijungtas įrenginys nesuderinamas su šiuo telefonu. Palieskite, kad sužinotumėte daugiau."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB derinimas prijungtas"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Palieskite, kad išjungtumėte USB derinimą."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pasirinkite, kas išjungtumėte USB derinimą."</string>
@@ -1334,9 +1342,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Prisijungta prie <xliff:g id="SESSION">%s</xliff:g>. Jei norite valdyti tinklą, palieskite."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Prisijungiama prie visada įjungto VPN…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Prisijungta prie visada įjungto VPN"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Visada įjungtas VPN atjungtas"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Atsijungta nuo visada įjungto VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Visada įjungto VPN klaida"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Palieskite, kad nustatytumėte"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Keiskite tinklo arba VPN nustatymus"</string>
     <string name="upload_file" msgid="2897957172366730416">"Pasirinkti failą"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nepasirinktas joks failas"</string>
     <string name="reset" msgid="2448168080964209908">"Atstatyti"</string>
@@ -1345,8 +1353,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Palieskite, kad išeitumėte iš automobilio režimo."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Susietas ar aktyvus"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Palieskite, kad nustatytumėte."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Įrenginio kaip modemo naudojimas išjungtas"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Jei reikia išsamios informacijos, susisiekite su administratoriumi"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Atgal"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Kitas"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Praleisti"</string>
@@ -1789,14 +1795,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Atsegti"</string>
     <string name="app_info" msgid="6856026610594615344">"Programos informacija"</string>
     <string name="negative_duration" msgid="5688706061127375131">"–<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Iš naujo nustatyti įrenginį?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Palieskite, kad iš naujo nustatytumėte įrenginį"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Paleidžiama demonstracinė versija…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Įrenginys nustatomas iš naujo…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Iš naujo nustatyti įrenginį?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Prarasite visus pakeitimus, o demonstracinė versija bus paleista iš naujo po <xliff:g id="TIMEOUT">%1$s</xliff:g> sek…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Atšaukti"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Nustatyti iš naujo dabar"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Išj. valdiklis „<xliff:g id="LABEL">%1$s</xliff:g>“"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konferencinis skambutis"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Patarimas"</string>
@@ -1842,6 +1842,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Nedelsdami pasitraukite nuo pakrančių ir paupių. Eikite į saugią vietą, pvz., vietą, kuri yra aukštai."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Nesijaudinkite ir ieškokite prieglobsčio netoliese."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Kritinės padėties pranešimo bandymas"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Atsakyti"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM kortelė neleidžiama"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM kortelė neteikiama"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index bbffbf82..0216e37f 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -132,10 +132,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pakalpojuma meklēšana"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi zvani"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoru iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus."</item>
+    <item msgid="3910386316304772394">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoram iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus. (Kļūdas kods: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Reģistrēt to pie sava mobilo sakaru operatora"</item>
+    <item msgid="7472393097168811593">"Reģistrējieties pie sava mobilo sakaru operatora (kļūdas kods: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -249,8 +249,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Balss palīgs"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloķēt tūlīt"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"Pārsniedz"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Saturs paslēpts"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Saskaņā ar politiku saturs ir paslēpts."</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Jauns paziņojums"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuālā tastatūra"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fiziskā tastatūra"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Drošība"</string>
@@ -266,9 +265,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Brīdinājumi"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstrācijas versija veikaliem"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB savienojums"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Lietotnes, kas darbojas fonā"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> darbojas fonā"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> lietotnes darbojas fonā"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Lietotnes, kas patērē akumulatora jaudu"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> izmanto akumulatoru"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> lietotne(-es) izmanto akumulatoru"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Pieskarieties, lai skatītu detalizētu informāciju par akumulatora un datu lietojumu"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Drošais režīms"</string>
@@ -1128,6 +1127,13 @@
       <item quantity="one">Ir pieejami atvērti Wi-Fi tīkli</item>
       <item quantity="other">Ir pieejami atvērti Wi-Fi tīkli</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Savienojuma izveide ar atvērtu Wi-Fi tīklu"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Notiek savienojuma izveide ar atvērtu Wi-Fi tīklu"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ir izveidots savienojums ar Wi-Fi tīklu"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nevarēja izveidot savienojumu ar Wi‑Fi tīklu"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Pieskarieties, lai skatītu visus tīklus"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Izveidot savienojumu"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Visi tīkli"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Pierakstieties Wi-Fi tīklā"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Pierakstīšanās tīklā"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1207,6 +1213,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB savienojums MIDI režīmā"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ir izveidots savienojums ar USB piederumu."</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Pieskarieties, lai skatītu citas iespējas."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Konstatēts analogs audio piederums"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Pievienotā ierīce nav saderīga ar šo tālruni. Pieskarieties, lai uzzinātu vairāk."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB atkļūdošana ir pievienota."</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Pieskarieties, lai atspējotu USB atkļūdošanu."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Atlasiet, lai atspējotu USB atkļūdošanu."</string>
@@ -1312,9 +1320,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Ir izveidots savienojums ar: <xliff:g id="SESSION">%s</xliff:g>. Pieskarieties, lai pārvaldītu tīklu."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Notiek savienojuma izveide ar vienmēr ieslēgtu VPN…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Izveidots savienojums ar vienmēr ieslēgtu VPN."</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Vienmēr ieslēgts VPN ir atvienots"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Pārtraukts savienojums ar vienmēr ieslēgtu VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Kļūda saistībā ar vienmēr ieslēgtu VPN"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Pieskarieties, lai iestatītu."</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Mainiet tīkla vai VPN iestatījumus"</string>
     <string name="upload_file" msgid="2897957172366730416">"Izvēlēties failu"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Neviens fails nav izvēlēts"</string>
     <string name="reset" msgid="2448168080964209908">"Atiestatīt"</string>
@@ -1323,8 +1331,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Pieskarieties, lai izietu no automašīnas režīma."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Piesaiste vai tīklājs ir aktīvs."</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Pieskarieties, lai iestatītu."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Piesaiste ir atspējota"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Lai iegūtu detalizētu informāciju, sazinieties ar savu administratoru."</string>
     <string name="back_button_label" msgid="2300470004503343439">"Atpakaļ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Tālāk"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Izlaist"</string>
@@ -1756,14 +1762,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Atspraust"</string>
     <string name="app_info" msgid="6856026610594615344">"Lietotnes informācija"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Vai atiestatīt ierīci?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Pieskarieties, lai atiestatītu ierīci"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Notiek demonstrācijas palaišana..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Notiek ierīces atiestatīšana..."</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Vai atiestatīt ierīci?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Pēc <xliff:g id="TIMEOUT">%1$s</xliff:g> sekundēm zaudēsiet visas izmaiņas un tiks atkārtoti palaista demonstrācija..."</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Atcelt"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Atiestatīt tūlīt"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> atspējots"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konferences zvans"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Rīka padoms"</string>
@@ -1808,6 +1808,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Nekavējoties pametiet piekrastes un upju zonas un dodieties uz drošākām (piemēram, augstākām) vietām."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Saglabājiet mieru un meklējiet tuvumā patvērumu."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Ārkārtas ziņojuma pārbaude"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Atbildēt"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM karti nav atļauts izmantot"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM karte netiek nodrošināta"</string>
diff --git a/core/res/res/values-mcc001-mnc01-af/strings.xml b/core/res/res/values-mcc001-mnc01-af/strings.xml
new file mode 100644
index 0000000..e251b61
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-af/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Foon nie toegelaat nie MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-am/strings.xml b/core/res/res/values-mcc001-mnc01-am/strings.xml
new file mode 100644
index 0000000..c5cc421
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-am/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"ስልክ አይፈቀድም MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-ar/strings.xml b/core/res/res/values-mcc001-mnc01-ar/strings.xml
new file mode 100644
index 0000000..ae68ed4
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-ar/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"‏غير مسموح باستخدام الهاتف MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-az/strings.xml b/core/res/res/values-mcc001-mnc01-az/strings.xml
new file mode 100644
index 0000000..7ac0613
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-az/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"MM#6 telefonu dəstəklənmir"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-bg/strings.xml b/core/res/res/values-mcc001-mnc01-bg/strings.xml
new file mode 100644
index 0000000..b311679
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-bg/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Телефонът не е разрешен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-bn/strings.xml b/core/res/res/values-mcc001-mnc01-bn/strings.xml
new file mode 100644
index 0000000..095f8c7
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-bn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"ফোন অনুমোদিত নয় MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-ca/strings.xml b/core/res/res/values-mcc001-mnc01-ca/strings.xml
new file mode 100644
index 0000000..cfdaf3e
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-ca/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telèfon no compatible MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-cs/strings.xml b/core/res/res/values-mcc001-mnc01-cs/strings.xml
new file mode 100644
index 0000000..4a7f221
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-cs/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefon není povolen (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-da/strings.xml b/core/res/res/values-mcc001-mnc01-da/strings.xml
new file mode 100644
index 0000000..6a7a5c8
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-da/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefonen har ikke adgangstilladelse MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-de/strings.xml b/core/res/res/values-mcc001-mnc01-de/strings.xml
new file mode 100644
index 0000000..25b6bd1
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-de/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Smartphone nicht zulässig MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-el/strings.xml b/core/res/res/values-mcc001-mnc01-el/strings.xml
new file mode 100644
index 0000000..ae6b17a
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-el/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-en-rAU/strings.xml b/core/res/res/values-mcc001-mnc01-en-rAU/strings.xml
new file mode 100644
index 0000000..231b858
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-en-rAU/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-en-rGB/strings.xml b/core/res/res/values-mcc001-mnc01-en-rGB/strings.xml
new file mode 100644
index 0000000..231b858
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-en-rGB/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-en-rIN/strings.xml b/core/res/res/values-mcc001-mnc01-en-rIN/strings.xml
new file mode 100644
index 0000000..231b858
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-en-rIN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-es-rUS/strings.xml b/core/res/res/values-mcc001-mnc01-es-rUS/strings.xml
new file mode 100644
index 0000000..059c64a
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-es-rUS/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-es/strings.xml b/core/res/res/values-mcc001-mnc01-es/strings.xml
new file mode 100644
index 0000000..059c64a
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-es/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-et/strings.xml b/core/res/res/values-mcc001-mnc01-et/strings.xml
new file mode 100644
index 0000000..62ff8ec
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-et/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefon pole lubatud MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-eu/strings.xml b/core/res/res/values-mcc001-mnc01-eu/strings.xml
new file mode 100644
index 0000000..2140993
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-eu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefonoa ez da onartzen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-fa/strings.xml b/core/res/res/values-mcc001-mnc01-fa/strings.xml
new file mode 100644
index 0000000..3d1acdb
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-fa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"‏تلفن مجاز نیست MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-fi/strings.xml b/core/res/res/values-mcc001-mnc01-fi/strings.xml
new file mode 100644
index 0000000..1c75bb6
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-fi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Puhelin estetty MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-fr-rCA/strings.xml b/core/res/res/values-mcc001-mnc01-fr-rCA/strings.xml
new file mode 100644
index 0000000..dbb6052
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-fr-rCA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-fr/strings.xml b/core/res/res/values-mcc001-mnc01-fr/strings.xml
new file mode 100644
index 0000000..dbb6052
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-fr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-gl/strings.xml b/core/res/res/values-mcc001-mnc01-gl/strings.xml
new file mode 100644
index 0000000..a9cd85e
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-gl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Non se admite o teléfono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-gu/strings.xml b/core/res/res/values-mcc001-mnc01-gu/strings.xml
new file mode 100644
index 0000000..f7c3285
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-gu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"MM#6 ફોનની મંજૂરી નથી"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-hi/strings.xml b/core/res/res/values-mcc001-mnc01-hi/strings.xml
new file mode 100644
index 0000000..ff6fed8
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-hi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"फ़ोन की इजाज़त नहीं है MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-hr/strings.xml b/core/res/res/values-mcc001-mnc01-hr/strings.xml
new file mode 100644
index 0000000..a3b89c9
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-hr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefon nije dopušten MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-hu/strings.xml b/core/res/res/values-mcc001-mnc01-hu/strings.xml
new file mode 100644
index 0000000..e591979
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-hu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"A telefon nem engedélyezett (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-hy/strings.xml b/core/res/res/values-mcc001-mnc01-hy/strings.xml
new file mode 100644
index 0000000..90a840c
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-hy/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-in/strings.xml b/core/res/res/values-mcc001-mnc01-in/strings.xml
new file mode 100644
index 0000000..1496178
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-in/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Ponsel tidak diizinkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-is/strings.xml b/core/res/res/values-mcc001-mnc01-is/strings.xml
new file mode 100644
index 0000000..cb33a8c
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-is/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Sími ekki leyfður MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-it/strings.xml b/core/res/res/values-mcc001-mnc01-it/strings.xml
new file mode 100644
index 0000000..ce902c7
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-it/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefono non consentito MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-iw/strings.xml b/core/res/res/values-mcc001-mnc01-iw/strings.xml
new file mode 100644
index 0000000..2f0eec8
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-iw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"‏הטלפון לא מורשה MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-ja/strings.xml b/core/res/res/values-mcc001-mnc01-ja/strings.xml
new file mode 100644
index 0000000..6661e5f
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-ja/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"電話は許可されていません(MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-ka/strings.xml b/core/res/res/values-mcc001-mnc01-ka/strings.xml
new file mode 100644
index 0000000..3d8e1b2
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-ka/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"ტელეფონი დაუშვებელია MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-kk/strings.xml b/core/res/res/values-mcc001-mnc01-kk/strings.xml
new file mode 100644
index 0000000..ba210c2
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-kk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Телефон пайдалануға болмайды MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-km/strings.xml b/core/res/res/values-mcc001-mnc01-km/strings.xml
new file mode 100644
index 0000000..2ee5b75
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-km/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-kn/strings.xml b/core/res/res/values-mcc001-mnc01-kn/strings.xml
new file mode 100644
index 0000000..de459a2
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-kn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"ಫೋನ್ MM#6 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-ko/strings.xml b/core/res/res/values-mcc001-mnc01-ko/strings.xml
new file mode 100644
index 0000000..39b839b
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-ko/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"전화가 허용되지 않음 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-ky/strings.xml b/core/res/res/values-mcc001-mnc01-ky/strings.xml
new file mode 100644
index 0000000..28a2fd0
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-ky/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Телефонду колдонууга тыюу салынган MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-lo/strings.xml b/core/res/res/values-mcc001-mnc01-lo/strings.xml
new file mode 100644
index 0000000..ca560ce4
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-lo/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-lt/strings.xml b/core/res/res/values-mcc001-mnc01-lt/strings.xml
new file mode 100644
index 0000000..29f1433
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-lt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefonas neleidžiamas (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-lv/strings.xml b/core/res/res/values-mcc001-mnc01-lv/strings.xml
new file mode 100644
index 0000000..0e97385
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-lv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Tālruni nav atļauts izmantot: MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-mk/strings.xml b/core/res/res/values-mcc001-mnc01-mk/strings.xml
new file mode 100644
index 0000000..f488183
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-mk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Телефонот не е дозволен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-ml/strings.xml b/core/res/res/values-mcc001-mnc01-ml/strings.xml
new file mode 100644
index 0000000..20392b6
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-ml/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"ഫോൺ അനുവദനീയമല്ല MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-mn/strings.xml b/core/res/res/values-mcc001-mnc01-mn/strings.xml
new file mode 100644
index 0000000..164462b
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-mn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Утсыг зөвшөөрөөгүй MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-mr/strings.xml b/core/res/res/values-mcc001-mnc01-mr/strings.xml
new file mode 100644
index 0000000..564573b
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-mr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"फोन MM#6 ला अनुमती देत नाही"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-ms/strings.xml b/core/res/res/values-mcc001-mnc01-ms/strings.xml
new file mode 100644
index 0000000..1399187
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-ms/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefon tidak dibenarkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-my/strings.xml b/core/res/res/values-mcc001-mnc01-my/strings.xml
new file mode 100644
index 0000000..39fa0e3
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-my/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-nb/strings.xml b/core/res/res/values-mcc001-mnc01-nb/strings.xml
new file mode 100644
index 0000000..0d46cee
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-nb/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefonen er ikke tillatt, MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-ne/strings.xml b/core/res/res/values-mcc001-mnc01-ne/strings.xml
new file mode 100644
index 0000000..469aaa8
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-ne/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"फोनलाई अनुमति छैन MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-nl/strings.xml b/core/res/res/values-mcc001-mnc01-nl/strings.xml
new file mode 100644
index 0000000..adf5d3a
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-nl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefoon niet toegestaan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-pa/strings.xml b/core/res/res/values-mcc001-mnc01-pa/strings.xml
new file mode 100644
index 0000000..3531088
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-pa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"ਫ਼ੋਨ ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-pl/strings.xml b/core/res/res/values-mcc001-mnc01-pl/strings.xml
new file mode 100644
index 0000000..1ee5497
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-pl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"MM#6 – telefon niedozwolony"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-pt-rBR/strings.xml b/core/res/res/values-mcc001-mnc01-pt-rBR/strings.xml
new file mode 100644
index 0000000..4eeb835
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-pt-rBR/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-pt-rPT/strings.xml b/core/res/res/values-mcc001-mnc01-pt-rPT/strings.xml
new file mode 100644
index 0000000..9de5a17
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-pt-rPT/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telemóvel não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-pt/strings.xml b/core/res/res/values-mcc001-mnc01-pt/strings.xml
new file mode 100644
index 0000000..4eeb835
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-pt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-ro/strings.xml b/core/res/res/values-mcc001-mnc01-ro/strings.xml
new file mode 100644
index 0000000..67f05da
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-ro/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefonul nu este permis MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-ru/strings.xml b/core/res/res/values-mcc001-mnc01-ru/strings.xml
new file mode 100644
index 0000000..59a0f40
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-ru/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Звонки запрещены (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-si/strings.xml b/core/res/res/values-mcc001-mnc01-si/strings.xml
new file mode 100644
index 0000000..bf48fd0d
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-si/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-sk/strings.xml b/core/res/res/values-mcc001-mnc01-sk/strings.xml
new file mode 100644
index 0000000..8c23a50
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-sk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefón nie je povolený (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-sl/strings.xml b/core/res/res/values-mcc001-mnc01-sl/strings.xml
new file mode 100644
index 0000000..ef0e4f7
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-sl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefon ni dovoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-sq/strings.xml b/core/res/res/values-mcc001-mnc01-sq/strings.xml
new file mode 100644
index 0000000..57cd6ab
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-sq/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefoni nuk lejohet MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-sr/strings.xml b/core/res/res/values-mcc001-mnc01-sr/strings.xml
new file mode 100644
index 0000000..a7ef974ac
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-sr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Телефон није дозвољен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-sv/strings.xml b/core/res/res/values-mcc001-mnc01-sv/strings.xml
new file mode 100644
index 0000000..dc903f6
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-sv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Mobil tillåts inte MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-sw/strings.xml b/core/res/res/values-mcc001-mnc01-sw/strings.xml
new file mode 100644
index 0000000..c09faee
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-sw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Simu hairuhusiwi MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-ta/strings.xml b/core/res/res/values-mcc001-mnc01-ta/strings.xml
new file mode 100644
index 0000000..0621e7c
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-ta/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"ஃபோன் அனுமதிக்கப்படவில்லை MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-te/strings.xml b/core/res/res/values-mcc001-mnc01-te/strings.xml
new file mode 100644
index 0000000..9e0a1fc
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-te/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-th/strings.xml b/core/res/res/values-mcc001-mnc01-th/strings.xml
new file mode 100644
index 0000000..f16f43f
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-th/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-tl/strings.xml b/core/res/res/values-mcc001-mnc01-tl/strings.xml
new file mode 100644
index 0000000..aa15f0e
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-tl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Hindi pinapahintulutan ang telepono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-tr/strings.xml b/core/res/res/values-mcc001-mnc01-tr/strings.xml
new file mode 100644
index 0000000..7d0c4c2
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-tr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Telefona izin verilmiyor MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-uk/strings.xml b/core/res/res/values-mcc001-mnc01-uk/strings.xml
new file mode 100644
index 0000000..d791af4
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-uk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Телефон заборонено (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-ur/strings.xml b/core/res/res/values-mcc001-mnc01-ur/strings.xml
new file mode 100644
index 0000000..3329702
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-ur/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"‏فون کی اجازت نہیں ہے MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-uz/strings.xml b/core/res/res/values-mcc001-mnc01-uz/strings.xml
new file mode 100644
index 0000000..73ac1c0
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-uz/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Chaqiruvlar taqiqlangan (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-vi/strings.xml b/core/res/res/values-mcc001-mnc01-vi/strings.xml
new file mode 100644
index 0000000..e9362de
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-vi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Không cho phép điện thoại MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-zh-rCN/strings.xml b/core/res/res/values-mcc001-mnc01-zh-rCN/strings.xml
new file mode 100644
index 0000000..c9abc9b
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-zh-rCN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"不受允许的手机 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-zh-rHK/strings.xml b/core/res/res/values-mcc001-mnc01-zh-rHK/strings.xml
new file mode 100644
index 0000000..375fe31
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-zh-rHK/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"不允許手機 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-zh-rTW/strings.xml b/core/res/res/values-mcc001-mnc01-zh-rTW/strings.xml
new file mode 100644
index 0000000..5700f01
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-zh-rTW/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"不支援的手機 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01-zu/strings.xml b/core/res/res/values-mcc001-mnc01-zu/strings.xml
new file mode 100644
index 0000000..b31303f
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01-zu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="2238090225563073546">"Ifoni ayivunyelwe MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc001-mnc01/strings.xml b/core/res/res/values-mcc001-mnc01/strings.xml
new file mode 100644
index 0000000..96af975
--- /dev/null
+++ b/core/res/res/values-mcc001-mnc01/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
+</resources>
diff --git a/core/res/res/values-mcc262-mnc02/strings.xml b/core/res/res/values-mcc262-mnc02/strings.xml
new file mode 100644
index 0000000..2b89401
--- /dev/null
+++ b/core/res/res/values-mcc262-mnc02/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2017, 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.
+ */
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+     <!-- Do not translate. Template for showing mobile network operator name while WFC is active -->
+     <string-array name="wfcSpnFormats">
+         <item>%s</item>
+         <item>%s Wi-Fi Calling</item>
+     </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc220/config.xml b/core/res/res/values-mcc302-mnc220/config.xml
index 422f7c9..9a3d736 100644
--- a/core/res/res/values-mcc302-mnc220/config.xml
+++ b/core/res/res/values-mcc302-mnc220/config.xml
@@ -38,19 +38,13 @@
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.telusmobility.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin</item>
-        <item>NTP_SERVER=north-america.pool.ntp.org</item>
-        <item>SUPL_MODE=1</item>
         <item>SUPL_VER=0x20000</item>
-        <item>LPP_PROFILE=2</item>
-        <item>NMEA_PROVIDER=0</item>
-        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
-        <item>ERR_ESTIMATE=0</item>
-        <item>INTERMEDIATE_POS=0</item>
-        <item>GPS_LOCK=0</item>
+        <item>SUPL_MODE=1</item>
         <item>SUPL_ES=0</item>
+        <item>LPP_PROFILE=3</item>
+        <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>GPS_LOCK=0</item>
     </string-array>
 
 </resources>
diff --git a/core/res/res/values-mcc302-mnc221/config.xml b/core/res/res/values-mcc302-mnc221/config.xml
index 1444250..007fd04 100644
--- a/core/res/res/values-mcc302-mnc221/config.xml
+++ b/core/res/res/values-mcc302-mnc221/config.xml
@@ -36,19 +36,13 @@
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.telusmobility.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin</item>
-        <item>NTP_SERVER=north-america.pool.ntp.org</item>
-        <item>SUPL_MODE=1</item>
         <item>SUPL_VER=0x20000</item>
-        <item>LPP_PROFILE=2</item>
-        <item>NMEA_PROVIDER=0</item>
-        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
-        <item>ERR_ESTIMATE=0</item>
-        <item>INTERMEDIATE_POS=0</item>
-        <item>GPS_LOCK=0</item>
+        <item>SUPL_MODE=1</item>
         <item>SUPL_ES=0</item>
+        <item>LPP_PROFILE=3</item>
+        <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>GPS_LOCK=0</item>
     </string-array>
 
 </resources>
diff --git a/core/res/res/values-mcc302-mnc370-af/strings.xml b/core/res/res/values-mcc302-mnc370-af/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-af/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-am/strings.xml b/core/res/res/values-mcc302-mnc370-am/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-am/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ar/strings.xml b/core/res/res/values-mcc302-mnc370-ar/strings.xml
new file mode 100644
index 0000000..f1c8176
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ar/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"‏%s مع Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-az/strings.xml b/core/res/res/values-mcc302-mnc370-az/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-az/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-bg/strings.xml b/core/res/res/values-mcc302-mnc370-bg/strings.xml
new file mode 100644
index 0000000..b3a9589
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-bg/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi от %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-bn/strings.xml b/core/res/res/values-mcc302-mnc370-bn/strings.xml
new file mode 100644
index 0000000..efd9b4b
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-bn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s ওয়াই-ফাই"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ca/strings.xml b/core/res/res/values-mcc302-mnc370-ca/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ca/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-cs/strings.xml b/core/res/res/values-mcc302-mnc370-cs/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-cs/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-da/strings.xml b/core/res/res/values-mcc302-mnc370-da/strings.xml
new file mode 100644
index 0000000..709530c
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-da/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi fra %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-de/strings.xml b/core/res/res/values-mcc302-mnc370-de/strings.xml
new file mode 100644
index 0000000..6aa7643
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-de/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"WLAN: %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-el/strings.xml b/core/res/res/values-mcc302-mnc370-el/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-el/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-en-rAU/strings.xml b/core/res/res/values-mcc302-mnc370-en-rAU/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-en-rAU/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-en-rGB/strings.xml b/core/res/res/values-mcc302-mnc370-en-rGB/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-en-rGB/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-en-rIN/strings.xml b/core/res/res/values-mcc302-mnc370-en-rIN/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-en-rIN/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-es-rUS/strings.xml b/core/res/res/values-mcc302-mnc370-es-rUS/strings.xml
new file mode 100644
index 0000000..5ba6413
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-es-rUS/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-es/strings.xml b/core/res/res/values-mcc302-mnc370-es/strings.xml
new file mode 100644
index 0000000..5ba6413
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-es/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-et/strings.xml b/core/res/res/values-mcc302-mnc370-et/strings.xml
new file mode 100644
index 0000000..648544d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-et/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s WiFi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-eu/strings.xml b/core/res/res/values-mcc302-mnc370-eu/strings.xml
new file mode 100644
index 0000000..960e1e5
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-eu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi sarea"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-fa/strings.xml b/core/res/res/values-mcc302-mnc370-fa/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-fa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-fi/strings.xml b/core/res/res/values-mcc302-mnc370-fi/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-fi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-fr-rCA/strings.xml b/core/res/res/values-mcc302-mnc370-fr-rCA/strings.xml
new file mode 100644
index 0000000..5ba6413
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-fr-rCA/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-fr/strings.xml b/core/res/res/values-mcc302-mnc370-fr/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-fr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-gl/strings.xml b/core/res/res/values-mcc302-mnc370-gl/strings.xml
new file mode 100644
index 0000000..b644471
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-gl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wifi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-gu/strings.xml b/core/res/res/values-mcc302-mnc370-gu/strings.xml
new file mode 100644
index 0000000..d869bcb
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-gu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s વાઇ-ફાઇ"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-hi/strings.xml b/core/res/res/values-mcc302-mnc370-hi/strings.xml
new file mode 100644
index 0000000..3521dd4
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-hi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s वाई-फ़ाई"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-hr/strings.xml b/core/res/res/values-mcc302-mnc370-hr/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-hr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-hu/strings.xml b/core/res/res/values-mcc302-mnc370-hu/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-hu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-hy/strings.xml b/core/res/res/values-mcc302-mnc370-hy/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-hy/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-in/strings.xml b/core/res/res/values-mcc302-mnc370-in/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-in/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-is/strings.xml b/core/res/res/values-mcc302-mnc370-is/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-is/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-it/strings.xml b/core/res/res/values-mcc302-mnc370-it/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-it/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-iw/strings.xml b/core/res/res/values-mcc302-mnc370-iw/strings.xml
new file mode 100644
index 0000000..90b73ad
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-iw/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"‎%s‎"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ja/strings.xml b/core/res/res/values-mcc302-mnc370-ja/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ja/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ka/strings.xml b/core/res/res/values-mcc302-mnc370-ka/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ka/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-kk/strings.xml b/core/res/res/values-mcc302-mnc370-kk/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-kk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-km/strings.xml b/core/res/res/values-mcc302-mnc370-km/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-km/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-kn/strings.xml b/core/res/res/values-mcc302-mnc370-kn/strings.xml
new file mode 100644
index 0000000..636eb01
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-kn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s ವೈ-ಫೈ"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ko/strings.xml b/core/res/res/values-mcc302-mnc370-ko/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ko/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ky/strings.xml b/core/res/res/values-mcc302-mnc370-ky/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ky/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-lo/strings.xml b/core/res/res/values-mcc302-mnc370-lo/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-lo/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-lt/strings.xml b/core/res/res/values-mcc302-mnc370-lt/strings.xml
new file mode 100644
index 0000000..95746fb
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-lt/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"„%s“ „Wi-Fi“"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-lv/strings.xml b/core/res/res/values-mcc302-mnc370-lv/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-lv/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-mk/strings.xml b/core/res/res/values-mcc302-mnc370-mk/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-mk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ml/strings.xml b/core/res/res/values-mcc302-mnc370-ml/strings.xml
new file mode 100644
index 0000000..810b72c
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ml/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s വൈഫൈ"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-mn/strings.xml b/core/res/res/values-mcc302-mnc370-mn/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-mn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-mr/strings.xml b/core/res/res/values-mcc302-mnc370-mr/strings.xml
new file mode 100644
index 0000000..4b03333
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-mr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s वाय-फाय"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ms/strings.xml b/core/res/res/values-mcc302-mnc370-ms/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ms/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-my/strings.xml b/core/res/res/values-mcc302-mnc370-my/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-my/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-nb/strings.xml b/core/res/res/values-mcc302-mnc370-nb/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-nb/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ne/strings.xml b/core/res/res/values-mcc302-mnc370-ne/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ne/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-nl/strings.xml b/core/res/res/values-mcc302-mnc370-nl/strings.xml
new file mode 100644
index 0000000..0366335
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-nl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wifi via %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-pa/strings.xml b/core/res/res/values-mcc302-mnc370-pa/strings.xml
new file mode 100644
index 0000000..5d3f7ae
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-pa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s ਵਾਈ-ਫਾਈ"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-pl/strings.xml b/core/res/res/values-mcc302-mnc370-pl/strings.xml
new file mode 100644
index 0000000..f359c03
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-pl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi – %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-pt-rBR/strings.xml b/core/res/res/values-mcc302-mnc370-pt-rBR/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-pt-rBR/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-pt-rPT/strings.xml b/core/res/res/values-mcc302-mnc370-pt-rPT/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-pt-rPT/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-pt/strings.xml b/core/res/res/values-mcc302-mnc370-pt/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-pt/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ro/strings.xml b/core/res/res/values-mcc302-mnc370-ro/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ro/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ru/strings.xml b/core/res/res/values-mcc302-mnc370-ru/strings.xml
new file mode 100644
index 0000000..5fdf802
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ru/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Сеть Wi-Fi \"%s\""</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-si/strings.xml b/core/res/res/values-mcc302-mnc370-si/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-si/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sk/strings.xml b/core/res/res/values-mcc302-mnc370-sk/strings.xml
new file mode 100644
index 0000000..6a3e8c7
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi‑Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sl/strings.xml b/core/res/res/values-mcc302-mnc370-sl/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sq/strings.xml b/core/res/res/values-mcc302-mnc370-sq/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sq/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sr/strings.xml b/core/res/res/values-mcc302-mnc370-sr/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sv/strings.xml b/core/res/res/values-mcc302-mnc370-sv/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sv/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sw/strings.xml b/core/res/res/values-mcc302-mnc370-sw/strings.xml
new file mode 100644
index 0000000..8c1c887
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sw/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi ya %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ta/strings.xml b/core/res/res/values-mcc302-mnc370-ta/strings.xml
new file mode 100644
index 0000000..5807593
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ta/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s வைஃபை"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-te/strings.xml b/core/res/res/values-mcc302-mnc370-te/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-te/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-th/strings.xml b/core/res/res/values-mcc302-mnc370-th/strings.xml
new file mode 100644
index 0000000..fa5ff47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-th/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi ของ %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-tl/strings.xml b/core/res/res/values-mcc302-mnc370-tl/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-tl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-tr/strings.xml b/core/res/res/values-mcc302-mnc370-tr/strings.xml
new file mode 100644
index 0000000..2f9ff04
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-tr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s kablosuz"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-uk/strings.xml b/core/res/res/values-mcc302-mnc370-uk/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-uk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ur/strings.xml b/core/res/res/values-mcc302-mnc370-ur/strings.xml
new file mode 100644
index 0000000..81d2888
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ur/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"‎%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-uz/strings.xml b/core/res/res/values-mcc302-mnc370-uz/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-uz/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-vi/strings.xml b/core/res/res/values-mcc302-mnc370-vi/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-vi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-zh-rCN/strings.xml b/core/res/res/values-mcc302-mnc370-zh-rCN/strings.xml
new file mode 100644
index 0000000..a89f6a2
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-zh-rCN/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s WLAN"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-zh-rHK/strings.xml b/core/res/res/values-mcc302-mnc370-zh-rHK/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-zh-rHK/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-zh-rTW/strings.xml b/core/res/res/values-mcc302-mnc370-zh-rTW/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-zh-rTW/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-zu/strings.xml b/core/res/res/values-mcc302-mnc370-zu/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-zu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370/config.xml b/core/res/res/values-mcc302-mnc370/config.xml
index 4876a8ae..28cca62 100644
--- a/core/res/res/values-mcc302-mnc370/config.xml
+++ b/core/res/res/values-mcc302-mnc370/config.xml
@@ -35,23 +35,17 @@
     -->
     <integer name="config_mobile_mtu">1410</integer>
 
-  <!-- Values for GPS configuration (Rogers) -->
+    <!-- Values for GPS configuration (Rogers) -->
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.google.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin</item>
-        <item>NTP_SERVER=north-america.pool.ntp.org</item>
-        <item>SUPL_MODE=1</item>
         <item>SUPL_VER=0x20000</item>
-        <item>LPP_PROFILE=2</item>
-        <item>NMEA_PROVIDER=0</item>
-        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
-        <item>ERR_ESTIMATE=0</item>
-        <item>INTERMEDIATE_POS=0</item>
-        <item>GPS_LOCK=0</item>
+        <item>SUPL_MODE=1</item>
         <item>SUPL_ES=0</item>
+        <item>LPP_PROFILE=2</item>
+        <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>GPS_LOCK=0</item>
     </string-array>
 
 </resources>
diff --git a/core/res/res/values-mcc302-mnc370/strings.xml b/core/res/res/values-mcc302-mnc370/strings.xml
new file mode 100644
index 0000000..f5b8496
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Template for showing mobile network operator name while WFC is active -->
+    <string-array name="wfcSpnFormats">
+        <item>%s</item>
+        <item>%s Wi-Fi</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc610/config.xml b/core/res/res/values-mcc302-mnc610/config.xml
index 8ac8f4c..232f149 100644
--- a/core/res/res/values-mcc302-mnc610/config.xml
+++ b/core/res/res/values-mcc302-mnc610/config.xml
@@ -26,18 +26,13 @@
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.google.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin</item>
-        <item>NTP_SERVER=north-america.pool.ntp.org</item>
-        <item>SUPL_MODE=1</item>
         <item>SUPL_VER=0x20000</item>
-        <item>LPP_PROFILE=2</item>
-        <item>NMEA_PROVIDER=0</item>
-        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
-        <item>ERR_ESTIMATE=0</item>
-        <item>INTERMEDIATE_POS=0</item>
-        <item>GPS_LOCK=0</item>
+        <item>SUPL_MODE=1</item>
         <item>SUPL_ES=0</item>
+        <item>LPP_PROFILE=2</item>
+        <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>GPS_LOCK=0</item>
     </string-array>
+
 </resources>
diff --git a/core/res/res/values-mcc302-mnc640/config.xml b/core/res/res/values-mcc302-mnc640/config.xml
index cba8eed..1d2e625 100644
--- a/core/res/res/values-mcc302-mnc640/config.xml
+++ b/core/res/res/values-mcc302-mnc640/config.xml
@@ -22,18 +22,13 @@
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.google.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin</item>
-        <item>NTP_SERVER=north-america.pool.ntp.org</item>
-        <item>SUPL_MODE=1</item>
         <item>SUPL_VER=0x20000</item>
-        <item>LPP_PROFILE=2</item>
-        <item>NMEA_PROVIDER=0</item>
-        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
-        <item>ERR_ESTIMATE=0</item>
-        <item>INTERMEDIATE_POS=0</item>
-        <item>GPS_LOCK=0</item>
+        <item>SUPL_MODE=1</item>
         <item>SUPL_ES=0</item>
+        <item>LPP_PROFILE=2</item>
+        <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>GPS_LOCK=0</item>
     </string-array>
+
 </resources>
diff --git a/core/res/res/values-mcc302-mnc720-af/strings.xml b/core/res/res/values-mcc302-mnc720-af/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-af/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-am/strings.xml b/core/res/res/values-mcc302-mnc720-am/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-am/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ar/strings.xml b/core/res/res/values-mcc302-mnc720-ar/strings.xml
new file mode 100644
index 0000000..869678f
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ar/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"‏%s مع Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-az/strings.xml b/core/res/res/values-mcc302-mnc720-az/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-az/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-bg/strings.xml b/core/res/res/values-mcc302-mnc720-bg/strings.xml
new file mode 100644
index 0000000..890f19b
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-bg/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi от %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-bn/strings.xml b/core/res/res/values-mcc302-mnc720-bn/strings.xml
new file mode 100644
index 0000000..543ec7a
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-bn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s ওয়াই-ফাই"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ca/strings.xml b/core/res/res/values-mcc302-mnc720-ca/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ca/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-cs/strings.xml b/core/res/res/values-mcc302-mnc720-cs/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-cs/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-da/strings.xml b/core/res/res/values-mcc302-mnc720-da/strings.xml
new file mode 100644
index 0000000..483dee5
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-da/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi fra %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-de/strings.xml b/core/res/res/values-mcc302-mnc720-de/strings.xml
new file mode 100644
index 0000000..825fa00
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-de/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"WLAN: %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-el/strings.xml b/core/res/res/values-mcc302-mnc720-el/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-el/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-en-rAU/strings.xml b/core/res/res/values-mcc302-mnc720-en-rAU/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-en-rAU/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-en-rGB/strings.xml b/core/res/res/values-mcc302-mnc720-en-rGB/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-en-rGB/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-en-rIN/strings.xml b/core/res/res/values-mcc302-mnc720-en-rIN/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-en-rIN/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-es-rUS/strings.xml b/core/res/res/values-mcc302-mnc720-es-rUS/strings.xml
new file mode 100644
index 0000000..c8c4c5e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-es-rUS/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-es/strings.xml b/core/res/res/values-mcc302-mnc720-es/strings.xml
new file mode 100644
index 0000000..c8c4c5e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-es/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-et/strings.xml b/core/res/res/values-mcc302-mnc720-et/strings.xml
new file mode 100644
index 0000000..3e5a7ef
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-et/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s WiFi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-eu/strings.xml b/core/res/res/values-mcc302-mnc720-eu/strings.xml
new file mode 100644
index 0000000..802df65
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-eu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi sarea"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-fa/strings.xml b/core/res/res/values-mcc302-mnc720-fa/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-fa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-fi/strings.xml b/core/res/res/values-mcc302-mnc720-fi/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-fi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-fr-rCA/strings.xml b/core/res/res/values-mcc302-mnc720-fr-rCA/strings.xml
new file mode 100644
index 0000000..c8c4c5e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-fr-rCA/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-fr/strings.xml b/core/res/res/values-mcc302-mnc720-fr/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-fr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-gl/strings.xml b/core/res/res/values-mcc302-mnc720-gl/strings.xml
new file mode 100644
index 0000000..d3a9055
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-gl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wifi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-gu/strings.xml b/core/res/res/values-mcc302-mnc720-gu/strings.xml
new file mode 100644
index 0000000..a64474c9
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-gu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s વાઇ-ફાઇ"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-hi/strings.xml b/core/res/res/values-mcc302-mnc720-hi/strings.xml
new file mode 100644
index 0000000..9a10eed
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-hi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s वाई-फ़ाई"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-hr/strings.xml b/core/res/res/values-mcc302-mnc720-hr/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-hr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-hu/strings.xml b/core/res/res/values-mcc302-mnc720-hu/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-hu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-hy/strings.xml b/core/res/res/values-mcc302-mnc720-hy/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-hy/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-in/strings.xml b/core/res/res/values-mcc302-mnc720-in/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-in/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-is/strings.xml b/core/res/res/values-mcc302-mnc720-is/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-is/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-it/strings.xml b/core/res/res/values-mcc302-mnc720-it/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-it/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-iw/strings.xml b/core/res/res/values-mcc302-mnc720-iw/strings.xml
new file mode 100644
index 0000000..d0a799f
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-iw/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"‎%s‎"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ja/strings.xml b/core/res/res/values-mcc302-mnc720-ja/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ja/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ka/strings.xml b/core/res/res/values-mcc302-mnc720-ka/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ka/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-kk/strings.xml b/core/res/res/values-mcc302-mnc720-kk/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-kk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-km/strings.xml b/core/res/res/values-mcc302-mnc720-km/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-km/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-kn/strings.xml b/core/res/res/values-mcc302-mnc720-kn/strings.xml
new file mode 100644
index 0000000..6438ffb
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-kn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s ವೈ-ಫೈ"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ko/strings.xml b/core/res/res/values-mcc302-mnc720-ko/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ko/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ky/strings.xml b/core/res/res/values-mcc302-mnc720-ky/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ky/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-lo/strings.xml b/core/res/res/values-mcc302-mnc720-lo/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-lo/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-lt/strings.xml b/core/res/res/values-mcc302-mnc720-lt/strings.xml
new file mode 100644
index 0000000..2d3b87a
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-lt/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"„%s“ „Wi-Fi“"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-lv/strings.xml b/core/res/res/values-mcc302-mnc720-lv/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-lv/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-mk/strings.xml b/core/res/res/values-mcc302-mnc720-mk/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-mk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ml/strings.xml b/core/res/res/values-mcc302-mnc720-ml/strings.xml
new file mode 100644
index 0000000..325b5db
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ml/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s വൈഫൈ"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-mn/strings.xml b/core/res/res/values-mcc302-mnc720-mn/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-mn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-mr/strings.xml b/core/res/res/values-mcc302-mnc720-mr/strings.xml
new file mode 100644
index 0000000..9708843
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-mr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s वाय-फाय"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ms/strings.xml b/core/res/res/values-mcc302-mnc720-ms/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ms/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-my/strings.xml b/core/res/res/values-mcc302-mnc720-my/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-my/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-nb/strings.xml b/core/res/res/values-mcc302-mnc720-nb/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-nb/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ne/strings.xml b/core/res/res/values-mcc302-mnc720-ne/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ne/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-nl/strings.xml b/core/res/res/values-mcc302-mnc720-nl/strings.xml
new file mode 100644
index 0000000..4c5cadd
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-nl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wifi via %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-pa/strings.xml b/core/res/res/values-mcc302-mnc720-pa/strings.xml
new file mode 100644
index 0000000..acf2655
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-pa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s ਵਾਈ-ਫਾਈ"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-pl/strings.xml b/core/res/res/values-mcc302-mnc720-pl/strings.xml
new file mode 100644
index 0000000..4e78857
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-pl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi – %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-pt-rBR/strings.xml b/core/res/res/values-mcc302-mnc720-pt-rBR/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-pt-rBR/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-pt-rPT/strings.xml b/core/res/res/values-mcc302-mnc720-pt-rPT/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-pt-rPT/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-pt/strings.xml b/core/res/res/values-mcc302-mnc720-pt/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-pt/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ro/strings.xml b/core/res/res/values-mcc302-mnc720-ro/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ro/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ru/strings.xml b/core/res/res/values-mcc302-mnc720-ru/strings.xml
new file mode 100644
index 0000000..b88013b
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ru/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Сеть Wi-Fi \"%s\""</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-si/strings.xml b/core/res/res/values-mcc302-mnc720-si/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-si/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sk/strings.xml b/core/res/res/values-mcc302-mnc720-sk/strings.xml
new file mode 100644
index 0000000..e7411be
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi‑Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sl/strings.xml b/core/res/res/values-mcc302-mnc720-sl/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sq/strings.xml b/core/res/res/values-mcc302-mnc720-sq/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sq/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sr/strings.xml b/core/res/res/values-mcc302-mnc720-sr/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sv/strings.xml b/core/res/res/values-mcc302-mnc720-sv/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sv/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sw/strings.xml b/core/res/res/values-mcc302-mnc720-sw/strings.xml
new file mode 100644
index 0000000..ee780df
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sw/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi ya %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ta/strings.xml b/core/res/res/values-mcc302-mnc720-ta/strings.xml
new file mode 100644
index 0000000..61c8b84
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ta/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s வைஃபை"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-te/strings.xml b/core/res/res/values-mcc302-mnc720-te/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-te/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-th/strings.xml b/core/res/res/values-mcc302-mnc720-th/strings.xml
new file mode 100644
index 0000000..d536f45
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-th/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi ของ %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-tl/strings.xml b/core/res/res/values-mcc302-mnc720-tl/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-tl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-tr/strings.xml b/core/res/res/values-mcc302-mnc720-tr/strings.xml
new file mode 100644
index 0000000..e41287a
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-tr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s kablosuz"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-uk/strings.xml b/core/res/res/values-mcc302-mnc720-uk/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-uk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ur/strings.xml b/core/res/res/values-mcc302-mnc720-ur/strings.xml
new file mode 100644
index 0000000..566f852
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ur/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"‎%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-uz/strings.xml b/core/res/res/values-mcc302-mnc720-uz/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-uz/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-vi/strings.xml b/core/res/res/values-mcc302-mnc720-vi/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-vi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-zh-rCN/strings.xml b/core/res/res/values-mcc302-mnc720-zh-rCN/strings.xml
new file mode 100644
index 0000000..c5526b2
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-zh-rCN/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s WLAN"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-zh-rHK/strings.xml b/core/res/res/values-mcc302-mnc720-zh-rHK/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-zh-rHK/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-zh-rTW/strings.xml b/core/res/res/values-mcc302-mnc720-zh-rTW/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-zh-rTW/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-zu/strings.xml b/core/res/res/values-mcc302-mnc720-zu/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-zu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720/config.xml b/core/res/res/values-mcc302-mnc720/config.xml
index dff3678..c322bb9 100644
--- a/core/res/res/values-mcc302-mnc720/config.xml
+++ b/core/res/res/values-mcc302-mnc720/config.xml
@@ -37,23 +37,17 @@
     -->
     <integer name="config_mobile_mtu">1430</integer>
 
-  <!-- Values for GPS configuration (Rogers) -->
+    <!-- Values for GPS configuration (Rogers) -->
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.google.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin</item>
-        <item>NTP_SERVER=north-america.pool.ntp.org</item>
-        <item>SUPL_MODE=1</item>
         <item>SUPL_VER=0x20000</item>
-        <item>LPP_PROFILE=2</item>
-        <item>NMEA_PROVIDER=0</item>
-        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
-        <item>ERR_ESTIMATE=0</item>
-        <item>INTERMEDIATE_POS=0</item>
-        <item>GPS_LOCK=0</item>
+        <item>SUPL_MODE=1</item>
         <item>SUPL_ES=0</item>
+        <item>LPP_PROFILE=2</item>
+        <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>GPS_LOCK=0</item>
     </string-array>
 
 </resources>
diff --git a/core/res/res/values-mcc302-mnc720/strings.xml b/core/res/res/values-mcc302-mnc720/strings.xml
new file mode 100644
index 0000000..f5b8496
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Template for showing mobile network operator name while WFC is active -->
+    <string-array name="wfcSpnFormats">
+        <item>%s</item>
+        <item>%s Wi-Fi</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc030-af/strings.xml b/core/res/res/values-mcc310-mnc030-af/strings.xml
index 0b666c2..1b6eec8 100644
--- a/core/res/res/values-mcc310-mnc030-af/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-af/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM is nie opgestel nie MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM word nie toegelaat nie MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Foon nie toegelaat nie MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-am/strings.xml b/core/res/res/values-mcc310-mnc030-am/strings.xml
index 08c5e329..9e10ee2 100644
--- a/core/res/res/values-mcc310-mnc030-am/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-am/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"ሲም አልቀረበም MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"ሲም አይፈቀድም MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ስልክ አይፈቀድም MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ar/strings.xml b/core/res/res/values-mcc310-mnc030-ar/strings.xml
index 5d6a53d..51db337 100644
--- a/core/res/res/values-mcc310-mnc030-ar/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ar/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"‏لم يتم توفير SIM ‏MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"‏غير مسموح باستخدام الهاتف MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-az/strings.xml b/core/res/res/values-mcc310-mnc030-az/strings.xml
index 194d189..3946a0f 100644
--- a/core/res/res/values-mcc310-mnc030-az/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-az/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM MM#2 təmin etmir"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM MM#3 dəstəkləmir"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"MM#6 telefonu dəstəklənmir"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-bg/strings.xml b/core/res/res/values-mcc310-mnc030-bg/strings.xml
index a7c014a..336a890 100644
--- a/core/res/res/values-mcc310-mnc030-bg/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-bg/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM картата не е обезпечена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM картата не е разрешена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Телефонът не е разрешен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-bn/strings.xml b/core/res/res/values-mcc310-mnc030-bn/strings.xml
new file mode 100644
index 0000000..f4ad84e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc030-bn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"সিমের অনুমতি নেই MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ফোন অনুমোদিত নয় MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc030-ca/strings.xml b/core/res/res/values-mcc310-mnc030-ca/strings.xml
index af25f9b..1e4a752 100644
--- a/core/res/res/values-mcc310-mnc030-ca/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ca/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"La SIM no està proporcionada a MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"La SIM no és compatible a MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telèfon no compatible MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-cs/strings.xml b/core/res/res/values-mcc310-mnc030-cs/strings.xml
index ee0f90c..e5c0cf2 100644
--- a/core/res/res/values-mcc310-mnc030-cs/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-cs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM karta není poskytována (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM karta není povolena (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefon není povolen (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-da/strings.xml b/core/res/res/values-mcc310-mnc030-da/strings.xml
index 8539f7a..dab4912 100644
--- a/core/res/res/values-mcc310-mnc030-da/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-da/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kort leveres ikke MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kort er ikke tilladt MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefonen har ikke adgangstilladelse MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-de/strings.xml b/core/res/res/values-mcc310-mnc030-de/strings.xml
index ad797b5..d3ff1164 100644
--- a/core/res/res/values-mcc310-mnc030-de/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-de/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-Karte nicht eingerichtet MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-Karte nicht zulässig MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Smartphone nicht zulässig MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-el/strings.xml b/core/res/res/values-mcc310-mnc030-el/strings.xml
index 62aa97f..22afb5f 100644
--- a/core/res/res/values-mcc310-mnc030-el/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-el/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Δεν παρέχεται κάρτα SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc030-en-rAU/strings.xml
index 1a50ac6..c604346 100644
--- a/core/res/res/values-mcc310-mnc030-en-rAU/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-en-rAU/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc030-en-rGB/strings.xml
index 1a50ac6..c604346 100644
--- a/core/res/res/values-mcc310-mnc030-en-rGB/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-en-rGB/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc030-en-rIN/strings.xml
index 1a50ac6..c604346 100644
--- a/core/res/res/values-mcc310-mnc030-en-rIN/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-en-rIN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc030-es-rUS/strings.xml
index 87226ac..42426cb 100644
--- a/core/res/res/values-mcc310-mnc030-es-rUS/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-es-rUS/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM no provista MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM no permitida MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-es/strings.xml b/core/res/res/values-mcc310-mnc030-es/strings.xml
index c13f5f8..ea3224d 100644
--- a/core/res/res/values-mcc310-mnc030-es/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-es/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM no proporcionada (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM no admitida (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-et/strings.xml b/core/res/res/values-mcc310-mnc030-et/strings.xml
index 07229ab..fbcaa30 100644
--- a/core/res/res/values-mcc310-mnc030-et/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-et/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kaart on ette valmistamata MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kaart pole lubatud MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefon pole lubatud MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-eu/strings.xml b/core/res/res/values-mcc310-mnc030-eu/strings.xml
index 024fbab..4053e48 100644
--- a/core/res/res/values-mcc310-mnc030-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-eu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Ez dago SIM txartelik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Ez da onartzen SIM txartela MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-fa/strings.xml b/core/res/res/values-mcc310-mnc030-fa/strings.xml
index e754032..01b0ad3 100644
--- a/core/res/res/values-mcc310-mnc030-fa/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-fa/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"‏سیم‌کارت مجاز نیست MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-fi/strings.xml b/core/res/res/values-mcc310-mnc030-fi/strings.xml
index 3b9c2ab..8e948c6 100644
--- a/core/res/res/values-mcc310-mnc030-fi/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-fi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kortti estetty MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc030-fr-rCA/strings.xml
index 31644b7..0e4f55d 100644
--- a/core/res/res/values-mcc310-mnc030-fr-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-fr-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Carte SIM non configurée, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Carte SIM non autorisée, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-fr/strings.xml b/core/res/res/values-mcc310-mnc030-fr/strings.xml
index 9c690e7..2f001db 100644
--- a/core/res/res/values-mcc310-mnc030-fr/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-fr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Carte SIM non provisionnée MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Carte SIM non autorisée MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-gl/strings.xml b/core/res/res/values-mcc310-mnc030-gl/strings.xml
index 59be216..fe18f6e 100644
--- a/core/res/res/values-mcc310-mnc030-gl/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-gl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Non se admite a tarxeta SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Non se admite o teléfono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-gu/strings.xml b/core/res/res/values-mcc310-mnc030-gu/strings.xml
index ac57a85..2cd3d2d 100644
--- a/core/res/res/values-mcc310-mnc030-gu/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-gu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIMને MM#2ની જોગવાઈ નથી"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"MM#6 ફોનની મંજૂરી નથી"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-hi/strings.xml b/core/res/res/values-mcc310-mnc030-hi/strings.xml
index 244d175..a3315a8 100644
--- a/core/res/res/values-mcc310-mnc030-hi/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-hi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM काम नहीं कर रहा है MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM की अनुमति नहीं है MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"फ़ोन की इजाज़त नहीं है MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-hr/strings.xml b/core/res/res/values-mcc310-mnc030-hr/strings.xml
index a37043c..a938a55 100644
--- a/core/res/res/values-mcc310-mnc030-hr/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-hr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Ne pruža se usluga za SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM nije dopušten MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefon nije dopušten MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-hu/strings.xml b/core/res/res/values-mcc310-mnc030-hu/strings.xml
index b26b2b2..b28ce8e 100644
--- a/core/res/res/values-mcc310-mnc030-hu/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-hu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Nem engedélyezett SIM-kártya (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"A SIM-kártya nem engedélyezett (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-hy/strings.xml b/core/res/res/values-mcc310-mnc030-hy/strings.xml
index 0d052f3..34cd04e 100644
--- a/core/res/res/values-mcc310-mnc030-hy/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-hy/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-in/strings.xml b/core/res/res/values-mcc310-mnc030-in/strings.xml
index f8f6613..b2a94b9 100644
--- a/core/res/res/values-mcc310-mnc030-in/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-in/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM tidak di-provisioning MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM tidak diizinkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Ponsel tidak diizinkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-is/strings.xml b/core/res/res/values-mcc310-mnc030-is/strings.xml
index 1033965..008de9d 100644
--- a/core/res/res/values-mcc310-mnc030-is/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-is/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-korti ekki úthlutað MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kort ekki leyft MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Sími ekki leyfður MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-it/strings.xml b/core/res/res/values-mcc310-mnc030-it/strings.xml
index fb74a97..1b17cff2 100644
--- a/core/res/res/values-mcc310-mnc030-it/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-it/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Scheda SIM non predisposta MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Scheda SIM non consentita MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefono non consentito MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-iw/strings.xml b/core/res/res/values-mcc310-mnc030-iw/strings.xml
index 50bd517..c5350b8 100644
--- a/core/res/res/values-mcc310-mnc030-iw/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-iw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"‏הטלפון לא מורשה MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ja/strings.xml b/core/res/res/values-mcc310-mnc030-ja/strings.xml
index 78cd78c..56fa5dd 100644
--- a/core/res/res/values-mcc310-mnc030-ja/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ja/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM には対応していません(MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM は許可されていません(MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"電話は許可されていません(MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ka/strings.xml b/core/res/res/values-mcc310-mnc030-ka/strings.xml
index 04d6a7d..abcaa99 100644
--- a/core/res/res/values-mcc310-mnc030-ka/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ka/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM ბარათი დაუშვებელია (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ტელეფონი დაუშვებელია MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-kk/strings.xml b/core/res/res/values-mcc310-mnc030-kk/strings.xml
index aad588c..b84e25f 100644
--- a/core/res/res/values-mcc310-mnc030-kk/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-kk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM картасы қарастырылмаған MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM картасына рұқсат етілмеген MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Телефон пайдалануға болмайды MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-km/strings.xml b/core/res/res/values-mcc310-mnc030-km/strings.xml
index bd999274..284310a 100644
--- a/core/res/res/values-mcc310-mnc030-km/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-km/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"ស៊ីមកាត​មិនត្រូវបាន​ផ្ដល់ជូនទេ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាត​ទេ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-kn/strings.xml b/core/res/res/values-mcc310-mnc030-kn/strings.xml
index 39e9b070..402d9be 100644
--- a/core/res/res/values-mcc310-mnc030-kn/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-kn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ಫೋನ್ MM#6 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ko/strings.xml b/core/res/res/values-mcc310-mnc030-ko/strings.xml
index 67e45b0..f9b2e5c 100644
--- a/core/res/res/values-mcc310-mnc030-ko/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ko/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM이 프로비저닝되지 않음 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM이 허용되지 않음 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ky/strings.xml b/core/res/res/values-mcc310-mnc030-ky/strings.xml
index 837ff98..a0c42fe 100644
--- a/core/res/res/values-mcc310-mnc030-ky/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ky/strings.xml
@@ -20,6 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM картаны колдонууга тыюу салынган MM#3"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM карта таанылган жок (MM#2)"</string>
+    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Телефонду колдонууга тыюу салынган MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-lo/strings.xml b/core/res/res/values-mcc310-mnc030-lo/strings.xml
index b41bf91..f8f57c4 100644
--- a/core/res/res/values-mcc310-mnc030-lo/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-lo/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-lt/strings.xml b/core/res/res/values-mcc310-mnc030-lt/strings.xml
index 59c66be..2060253 100644
--- a/core/res/res/values-mcc310-mnc030-lt/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-lt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM kortelė neteikiama (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM kortelė neleidžiama (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefonas neleidžiamas (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-lv/strings.xml b/core/res/res/values-mcc310-mnc030-lv/strings.xml
index 685c9b8..dd8e155 100644
--- a/core/res/res/values-mcc310-mnc030-lv/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-lv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM karte netiek nodrošināta: MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM karti nav atļauts izmantot: MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Tālruni nav atļauts izmantot: MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-mk/strings.xml b/core/res/res/values-mcc310-mnc030-mk/strings.xml
index ce24e25..3fa9acb 100644
--- a/core/res/res/values-mcc310-mnc030-mk/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-mk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Не е обезбедена SIM-картичка, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Не е дозволена SIM-картичка, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Телефонот не е дозволен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ml/strings.xml b/core/res/res/values-mcc310-mnc030-ml/strings.xml
index bc87cbd..cd69a85 100644
--- a/core/res/res/values-mcc310-mnc030-ml/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ml/strings.xml
@@ -20,6 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
+    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ഫോൺ അനുവദനീയമല്ല MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-mn/strings.xml b/core/res/res/values-mcc310-mnc030-mn/strings.xml
index 6ff2d5e..5bbbe1a 100644
--- a/core/res/res/values-mcc310-mnc030-mn/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-mn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Утсыг зөвшөөрөөгүй MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-mr/strings.xml b/core/res/res/values-mcc310-mnc030-mr/strings.xml
index afc40a1..56afb10 100644
--- a/core/res/res/values-mcc310-mnc030-mr/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-mr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"फोन MM#6 ला अनुमती देत नाही"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ms/strings.xml b/core/res/res/values-mcc310-mnc030-ms/strings.xml
index 9a54b04..2bcfc77 100644
--- a/core/res/res/values-mcc310-mnc030-ms/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ms/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM tidak diperuntukkan MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM tidak dibenarkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefon tidak dibenarkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-my/strings.xml b/core/res/res/values-mcc310-mnc030-my/strings.xml
index 79a0791..7e8894e 100644
--- a/core/res/res/values-mcc310-mnc030-my/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-my/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-nb/strings.xml b/core/res/res/values-mcc310-mnc030-nb/strings.xml
index 7c06dba..267353e 100644
--- a/core/res/res/values-mcc310-mnc030-nb/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-nb/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kortet er ikke klargjort, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kortet er ikke tillatt, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefonen er ikke tillatt, MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ne/strings.xml b/core/res/res/values-mcc310-mnc030-ne/strings.xml
index 3ef06ab..dd07fc9 100644
--- a/core/res/res/values-mcc310-mnc030-ne/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ne/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM को प्रावधान छैन MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM लाई अनुमति छैन MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"फोनलाई अनुमति छैन MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-nl/strings.xml b/core/res/res/values-mcc310-mnc030-nl/strings.xml
index 861385d1..52b52d6 100644
--- a/core/res/res/values-mcc310-mnc030-nl/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-nl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Simkaart niet geregistreerd MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Simkaart niet toegestaan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefoon niet toegestaan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-pa/strings.xml b/core/res/res/values-mcc310-mnc030-pa/strings.xml
new file mode 100644
index 0000000..cefd738
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc030-pa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ਫ਼ੋਨ ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc030-pl/strings.xml b/core/res/res/values-mcc310-mnc030-pl/strings.xml
index 84ff351..fa5720a 100644
--- a/core/res/res/values-mcc310-mnc030-pl/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-pl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"MM#2 – karta SIM nieobsługiwana"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"MM#3 – niedozwolona karta SIM"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"MM#6 – telefon niedozwolony"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc030-pt-rBR/strings.xml
index 2679f93..663261c 100644
--- a/core/res/res/values-mcc310-mnc030-pt-rBR/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-pt-rBR/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc030-pt-rPT/strings.xml
index 2679f93..602b59e 100644
--- a/core/res/res/values-mcc310-mnc030-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-pt-rPT/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telemóvel não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-pt/strings.xml b/core/res/res/values-mcc310-mnc030-pt/strings.xml
index 2679f93..663261c 100644
--- a/core/res/res/values-mcc310-mnc030-pt/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-pt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ro/strings.xml b/core/res/res/values-mcc310-mnc030-ro/strings.xml
index 5bae0c0..77d374c 100644
--- a/core/res/res/values-mcc310-mnc030-ro/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ro/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Cardul SIM nu este activat MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Cardul SIM nu este permis MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefonul nu este permis MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ru/strings.xml b/core/res/res/values-mcc310-mnc030-ru/strings.xml
index 658badf..c2ca9d3 100644
--- a/core/res/res/values-mcc310-mnc030-ru/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ru/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-карта не активирована (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Использование SIM-карты запрещено (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Звонки запрещены (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-si/strings.xml b/core/res/res/values-mcc310-mnc030-si/strings.xml
index 635ffa4..9b9b1b7 100644
--- a/core/res/res/values-mcc310-mnc030-si/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-si/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM MM#3 ඉඩ නොදේ"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-sk/strings.xml b/core/res/res/values-mcc310-mnc030-sk/strings.xml
index 2a046b6..968fd2d 100644
--- a/core/res/res/values-mcc310-mnc030-sk/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-sk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM karta nie je k dispozícii – MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM karta je zakázaná – MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefón nie je povolený (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-sl/strings.xml b/core/res/res/values-mcc310-mnc030-sl/strings.xml
index 7321e4d..dcbf3e2 100644
--- a/core/res/res/values-mcc310-mnc030-sl/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-sl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Kartica SIM ni omogočena za uporabo MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Kartica SIM ni dovoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefon ni dovoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-sq/strings.xml b/core/res/res/values-mcc310-mnc030-sq/strings.xml
index e553f01..4ea64fd 100644
--- a/core/res/res/values-mcc310-mnc030-sq/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-sq/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Karta SIM nuk është dhënë MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Karta SIM nuk lejohet MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefoni nuk lejohet MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-sr/strings.xml b/core/res/res/values-mcc310-mnc030-sr/strings.xml
index 945e2fc..2f36c77 100644
--- a/core/res/res/values-mcc310-mnc030-sr/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-sr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM картица није подешена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Телефон није дозвољен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-sv/strings.xml b/core/res/res/values-mcc310-mnc030-sv/strings.xml
index 5f0cc46..bac0d61 100644
--- a/core/res/res/values-mcc310-mnc030-sv/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-sv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kort tillhandahålls inte MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kort tillåts inte MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Mobil tillåts inte MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-sw/strings.xml b/core/res/res/values-mcc310-mnc030-sw/strings.xml
index fbd2076..c26e864 100644
--- a/core/res/res/values-mcc310-mnc030-sw/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-sw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM haitumiki MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM hairuhusiwi MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Simu hairuhusiwi MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ta/strings.xml b/core/res/res/values-mcc310-mnc030-ta/strings.xml
index 6fc3df6..661c813 100644
--- a/core/res/res/values-mcc310-mnc030-ta/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ta/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"சிம் அமைக்கப்படவில்லை MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ஃபோன் அனுமதிக்கப்படவில்லை MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-te/strings.xml b/core/res/res/values-mcc310-mnc030-te/strings.xml
new file mode 100644
index 0000000..12a0d70
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc030-te/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM MM#2ని సక్రియం చేయలేదు"</string>
+    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM MM#3ని అనుమతించలేదు"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc030-th/strings.xml b/core/res/res/values-mcc310-mnc030-th/strings.xml
index 9a8ee74..d4b2dc4 100644
--- a/core/res/res/values-mcc310-mnc030-th/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-th/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"ไม่มีการจัดสรรซิม MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-tl/strings.xml b/core/res/res/values-mcc310-mnc030-tl/strings.xml
index 6408f4e..41d3924 100644
--- a/core/res/res/values-mcc310-mnc030-tl/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-tl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Hindi na-provision ang SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Hindi pinapahintulutan ang SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Hindi pinapahintulutan ang telepono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-tr/strings.xml b/core/res/res/values-mcc310-mnc030-tr/strings.xml
index 361ee9c..aab27e2 100644
--- a/core/res/res/values-mcc310-mnc030-tr/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-tr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM MM#3\'e izin vermiyor"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Telefona izin verilmiyor MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-uk/strings.xml b/core/res/res/values-mcc310-mnc030-uk/strings.xml
index efee94e..9e0cd4c 100644
--- a/core/res/res/values-mcc310-mnc030-uk/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-uk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-карту не надано (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-карта заборонена (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Телефон заборонено (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-ur/strings.xml b/core/res/res/values-mcc310-mnc030-ur/strings.xml
index a0e5fd6..e704516 100644
--- a/core/res/res/values-mcc310-mnc030-ur/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-ur/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"‏SIM کی اجازت نہیں ہے MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"‏فون کی اجازت نہیں ہے MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-uz/strings.xml b/core/res/res/values-mcc310-mnc030-uz/strings.xml
index 7eb641a..c7ae871 100644
--- a/core/res/res/values-mcc310-mnc030-uz/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-uz/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Chaqiruvlar taqiqlangan (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-vi/strings.xml b/core/res/res/values-mcc310-mnc030-vi/strings.xml
index 362ee6a..bd87e0d 100644
--- a/core/res/res/values-mcc310-mnc030-vi/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-vi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM không được cấp phép MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM không được phép MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Không cho phép điện thoại MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc030-zh-rCN/strings.xml
index efa43f5..441eb3f 100644
--- a/core/res/res/values-mcc310-mnc030-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-zh-rCN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"未配置的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"不被允许的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"不受允许的手机 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc030-zh-rHK/strings.xml
index c163544..7f3a94c4 100644
--- a/core/res/res/values-mcc310-mnc030-zh-rHK/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-zh-rHK/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc030-zh-rTW/strings.xml
index c163544..a4baf62 100644
--- a/core/res/res/values-mcc310-mnc030-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-zh-rTW/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"不支援的手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-zu/strings.xml b/core/res/res/values-mcc310-mnc030-zu/strings.xml
index 720fa82..0142a35 100644
--- a/core/res/res/values-mcc310-mnc030-zu/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-zu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"I-SIM ayinikezelwe MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1930079814544869756">"I-SIM ayivunyelwe MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2995576894416087107">"Ifoni ayivunyelwe MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030/strings.xml b/core/res/res/values-mcc310-mnc030/strings.xml
index a3fea29..6a404d5 100644
--- a/core/res/res/values-mcc310-mnc030/strings.xml
+++ b/core/res/res/values-mcc310-mnc030/strings.xml
@@ -20,4 +20,5 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string>
     <string name="mmcc_illegal_ms">SIM not allowed MM#3</string>
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc150-af/strings.xml b/core/res/res/values-mcc310-mnc150-af/strings.xml
new file mode 100644
index 0000000..bfc24ab
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-af/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Foon nie toegelaat nie MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-am/strings.xml b/core/res/res/values-mcc310-mnc150-am/strings.xml
new file mode 100644
index 0000000..c75ae67
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-am/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"ስልክ አይፈቀድም MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-ar/strings.xml b/core/res/res/values-mcc310-mnc150-ar/strings.xml
new file mode 100644
index 0000000..a3a5d85
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-ar/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"‏غير مسموح باستخدام الهاتف MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-az/strings.xml b/core/res/res/values-mcc310-mnc150-az/strings.xml
new file mode 100644
index 0000000..4c7a339
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-az/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"MM#6 telefonu dəstəklənmir"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-bg/strings.xml b/core/res/res/values-mcc310-mnc150-bg/strings.xml
new file mode 100644
index 0000000..70445e1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-bg/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Телефонът не е разрешен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-bn/strings.xml b/core/res/res/values-mcc310-mnc150-bn/strings.xml
new file mode 100644
index 0000000..25dc744
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-bn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"ফোন অনুমোদিত নয় MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-ca/strings.xml b/core/res/res/values-mcc310-mnc150-ca/strings.xml
new file mode 100644
index 0000000..836aab0
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-ca/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telèfon no compatible MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-cs/strings.xml b/core/res/res/values-mcc310-mnc150-cs/strings.xml
new file mode 100644
index 0000000..f31b34e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-cs/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefon není povolen (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-da/strings.xml b/core/res/res/values-mcc310-mnc150-da/strings.xml
new file mode 100644
index 0000000..1213be0
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-da/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefonen har ikke adgangstilladelse MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-de/strings.xml b/core/res/res/values-mcc310-mnc150-de/strings.xml
new file mode 100644
index 0000000..7fdf306
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-de/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Smartphone nicht zulässig MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-el/strings.xml b/core/res/res/values-mcc310-mnc150-el/strings.xml
new file mode 100644
index 0000000..9dfeb6c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-el/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc150-en-rAU/strings.xml
new file mode 100644
index 0000000..afeb95e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-en-rAU/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc150-en-rGB/strings.xml
new file mode 100644
index 0000000..afeb95e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-en-rGB/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc150-en-rIN/strings.xml
new file mode 100644
index 0000000..afeb95e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-en-rIN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc150-es-rUS/strings.xml
new file mode 100644
index 0000000..4ed5253
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-es-rUS/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-es/strings.xml b/core/res/res/values-mcc310-mnc150-es/strings.xml
new file mode 100644
index 0000000..4ed5253
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-es/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-et/strings.xml b/core/res/res/values-mcc310-mnc150-et/strings.xml
new file mode 100644
index 0000000..6cb111e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-et/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefon pole lubatud MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-eu/strings.xml b/core/res/res/values-mcc310-mnc150-eu/strings.xml
new file mode 100644
index 0000000..a38ed44d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-eu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefonoa ez da onartzen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-fa/strings.xml b/core/res/res/values-mcc310-mnc150-fa/strings.xml
new file mode 100644
index 0000000..bb52d79
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-fa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"‏تلفن مجاز نیست MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-fi/strings.xml b/core/res/res/values-mcc310-mnc150-fi/strings.xml
new file mode 100644
index 0000000..d1eff31
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-fi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Puhelin estetty MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc150-fr-rCA/strings.xml
new file mode 100644
index 0000000..335a0e8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-fr-rCA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-fr/strings.xml b/core/res/res/values-mcc310-mnc150-fr/strings.xml
new file mode 100644
index 0000000..335a0e8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-fr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-gl/strings.xml b/core/res/res/values-mcc310-mnc150-gl/strings.xml
new file mode 100644
index 0000000..23faa0641
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-gl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Non se admite o teléfono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-gu/strings.xml b/core/res/res/values-mcc310-mnc150-gu/strings.xml
new file mode 100644
index 0000000..95f89a0
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-gu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"MM#6 ફોનની મંજૂરી નથી"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-hi/strings.xml b/core/res/res/values-mcc310-mnc150-hi/strings.xml
new file mode 100644
index 0000000..1b88f5b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-hi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"फ़ोन की इजाज़त नहीं है MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-hr/strings.xml b/core/res/res/values-mcc310-mnc150-hr/strings.xml
new file mode 100644
index 0000000..85bc29b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-hr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefon nije dopušten MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-hu/strings.xml b/core/res/res/values-mcc310-mnc150-hu/strings.xml
new file mode 100644
index 0000000..e741ab3
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-hu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"A telefon nem engedélyezett (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-hy/strings.xml b/core/res/res/values-mcc310-mnc150-hy/strings.xml
new file mode 100644
index 0000000..c6ec7d3
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-hy/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-in/strings.xml b/core/res/res/values-mcc310-mnc150-in/strings.xml
new file mode 100644
index 0000000..8a4fb2a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-in/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Ponsel tidak diizinkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-is/strings.xml b/core/res/res/values-mcc310-mnc150-is/strings.xml
new file mode 100644
index 0000000..3c1a883
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-is/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Sími ekki leyfður MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-it/strings.xml b/core/res/res/values-mcc310-mnc150-it/strings.xml
new file mode 100644
index 0000000..1fed454
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-it/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefono non consentito MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-iw/strings.xml b/core/res/res/values-mcc310-mnc150-iw/strings.xml
new file mode 100644
index 0000000..f5e73d5
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-iw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"‏הטלפון לא מורשה MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-ja/strings.xml b/core/res/res/values-mcc310-mnc150-ja/strings.xml
new file mode 100644
index 0000000..9b4a071
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-ja/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"電話は許可されていません(MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-ka/strings.xml b/core/res/res/values-mcc310-mnc150-ka/strings.xml
new file mode 100644
index 0000000..5387ec5
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-ka/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"ტელეფონი დაუშვებელია MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-kk/strings.xml b/core/res/res/values-mcc310-mnc150-kk/strings.xml
new file mode 100644
index 0000000..b8b20fd
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-kk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Телефон пайдалануға болмайды MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-km/strings.xml b/core/res/res/values-mcc310-mnc150-km/strings.xml
new file mode 100644
index 0000000..032f361
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-km/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-kn/strings.xml b/core/res/res/values-mcc310-mnc150-kn/strings.xml
new file mode 100644
index 0000000..629d8b8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-kn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"ಫೋನ್ MM#6 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-ko/strings.xml b/core/res/res/values-mcc310-mnc150-ko/strings.xml
new file mode 100644
index 0000000..94314c4
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-ko/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"전화가 허용되지 않음 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-ky/strings.xml b/core/res/res/values-mcc310-mnc150-ky/strings.xml
new file mode 100644
index 0000000..238bef7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-ky/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Телефонду колдонууга тыюу салынган MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-lo/strings.xml b/core/res/res/values-mcc310-mnc150-lo/strings.xml
new file mode 100644
index 0000000..fb7fcc2
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-lo/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-lt/strings.xml b/core/res/res/values-mcc310-mnc150-lt/strings.xml
new file mode 100644
index 0000000..59fa06a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-lt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefonas neleidžiamas (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-lv/strings.xml b/core/res/res/values-mcc310-mnc150-lv/strings.xml
new file mode 100644
index 0000000..c1021d7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-lv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Tālruni nav atļauts izmantot: MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-mk/strings.xml b/core/res/res/values-mcc310-mnc150-mk/strings.xml
new file mode 100644
index 0000000..934e03c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-mk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Телефонот не е дозволен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-ml/strings.xml b/core/res/res/values-mcc310-mnc150-ml/strings.xml
new file mode 100644
index 0000000..4efb94b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-ml/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"ഫോൺ അനുവദനീയമല്ല MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-mn/strings.xml b/core/res/res/values-mcc310-mnc150-mn/strings.xml
new file mode 100644
index 0000000..4a56ecf
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-mn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Утсыг зөвшөөрөөгүй MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-mr/strings.xml b/core/res/res/values-mcc310-mnc150-mr/strings.xml
new file mode 100644
index 0000000..3797f53
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-mr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"फोन MM#6 ला अनुमती देत नाही"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-ms/strings.xml b/core/res/res/values-mcc310-mnc150-ms/strings.xml
new file mode 100644
index 0000000..7fe8b74
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-ms/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefon tidak dibenarkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-my/strings.xml b/core/res/res/values-mcc310-mnc150-my/strings.xml
new file mode 100644
index 0000000..c1b0918
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-my/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-nb/strings.xml b/core/res/res/values-mcc310-mnc150-nb/strings.xml
new file mode 100644
index 0000000..a792c97
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-nb/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefonen er ikke tillatt, MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-ne/strings.xml b/core/res/res/values-mcc310-mnc150-ne/strings.xml
new file mode 100644
index 0000000..bc94555
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-ne/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"फोनलाई अनुमति छैन MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-nl/strings.xml b/core/res/res/values-mcc310-mnc150-nl/strings.xml
new file mode 100644
index 0000000..219c0c3
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-nl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefoon niet toegestaan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-pa/strings.xml b/core/res/res/values-mcc310-mnc150-pa/strings.xml
new file mode 100644
index 0000000..18216f3
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-pa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"ਫ਼ੋਨ ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-pl/strings.xml b/core/res/res/values-mcc310-mnc150-pl/strings.xml
new file mode 100644
index 0000000..a696993a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-pl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"MM#6 – telefon niedozwolony"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc150-pt-rBR/strings.xml
new file mode 100644
index 0000000..1163c91
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-pt-rBR/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc150-pt-rPT/strings.xml
new file mode 100644
index 0000000..13bcac8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-pt-rPT/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telemóvel não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-pt/strings.xml b/core/res/res/values-mcc310-mnc150-pt/strings.xml
new file mode 100644
index 0000000..1163c91
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-pt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-ro/strings.xml b/core/res/res/values-mcc310-mnc150-ro/strings.xml
new file mode 100644
index 0000000..200b59d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-ro/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefonul nu este permis MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-ru/strings.xml b/core/res/res/values-mcc310-mnc150-ru/strings.xml
new file mode 100644
index 0000000..7118395
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-ru/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Звонки запрещены (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-si/strings.xml b/core/res/res/values-mcc310-mnc150-si/strings.xml
new file mode 100644
index 0000000..c198a38
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-si/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-sk/strings.xml b/core/res/res/values-mcc310-mnc150-sk/strings.xml
new file mode 100644
index 0000000..0a0d119
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-sk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefón nie je povolený (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-sl/strings.xml b/core/res/res/values-mcc310-mnc150-sl/strings.xml
new file mode 100644
index 0000000..cebc04a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-sl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefon ni dovoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-sq/strings.xml b/core/res/res/values-mcc310-mnc150-sq/strings.xml
new file mode 100644
index 0000000..2daf805
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-sq/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefoni nuk lejohet MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-sr/strings.xml b/core/res/res/values-mcc310-mnc150-sr/strings.xml
new file mode 100644
index 0000000..40ac0c2
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-sr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Телефон није дозвољен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-sv/strings.xml b/core/res/res/values-mcc310-mnc150-sv/strings.xml
new file mode 100644
index 0000000..5f1a340
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-sv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Mobil tillåts inte MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-sw/strings.xml b/core/res/res/values-mcc310-mnc150-sw/strings.xml
new file mode 100644
index 0000000..db3201d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-sw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Simu hairuhusiwi MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-ta/strings.xml b/core/res/res/values-mcc310-mnc150-ta/strings.xml
new file mode 100644
index 0000000..6177db2
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-ta/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"ஃபோன் அனுமதிக்கப்படவில்லை MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-te/strings.xml b/core/res/res/values-mcc310-mnc150-te/strings.xml
new file mode 100644
index 0000000..e8bb029
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-te/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-th/strings.xml b/core/res/res/values-mcc310-mnc150-th/strings.xml
new file mode 100644
index 0000000..e047ebe
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-th/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-tl/strings.xml b/core/res/res/values-mcc310-mnc150-tl/strings.xml
new file mode 100644
index 0000000..550acde
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-tl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Hindi pinapahintulutan ang telepono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-tr/strings.xml b/core/res/res/values-mcc310-mnc150-tr/strings.xml
new file mode 100644
index 0000000..60615bb
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-tr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Telefona izin verilmiyor MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-uk/strings.xml b/core/res/res/values-mcc310-mnc150-uk/strings.xml
new file mode 100644
index 0000000..b709f6e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-uk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Телефон заборонено (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-ur/strings.xml b/core/res/res/values-mcc310-mnc150-ur/strings.xml
new file mode 100644
index 0000000..fe29e15
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-ur/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"‏فون کی اجازت نہیں ہے MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-uz/strings.xml b/core/res/res/values-mcc310-mnc150-uz/strings.xml
new file mode 100644
index 0000000..e1372d1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-uz/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Chaqiruvlar taqiqlangan (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-vi/strings.xml b/core/res/res/values-mcc310-mnc150-vi/strings.xml
new file mode 100644
index 0000000..85a7c62
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-vi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Không cho phép điện thoại MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc150-zh-rCN/strings.xml
new file mode 100644
index 0000000..9319941
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-zh-rCN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"不受允许的手机 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc150-zh-rHK/strings.xml
new file mode 100644
index 0000000..092d780
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-zh-rHK/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"不允許手機 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc150-zh-rTW/strings.xml
new file mode 100644
index 0000000..f8d43ed
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-zh-rTW/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"不支援的手機 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150-zu/strings.xml b/core/res/res/values-mcc310-mnc150-zu/strings.xml
new file mode 100644
index 0000000..4d0f31d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150-zu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="5207603948149789531">"Ifoni ayivunyelwe MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc150/strings.xml b/core/res/res/values-mcc310-mnc150/strings.xml
new file mode 100644
index 0000000..96af975
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc150/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc170-af/strings.xml b/core/res/res/values-mcc310-mnc170-af/strings.xml
index 4256d3a..00c2835 100644
--- a/core/res/res/values-mcc310-mnc170-af/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-af/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM is nie opgestel nie MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM word nie toegelaat nie MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Foon nie toegelaat nie MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-am/strings.xml b/core/res/res/values-mcc310-mnc170-am/strings.xml
index 311d9e1..961fa69 100644
--- a/core/res/res/values-mcc310-mnc170-am/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-am/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"ሲም አልቀረበም MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"ሲም አይፈቀድም MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ስልክ አይፈቀድም MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ar/strings.xml b/core/res/res/values-mcc310-mnc170-ar/strings.xml
index a80ff2e2..3ad58f5 100644
--- a/core/res/res/values-mcc310-mnc170-ar/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ar/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"‏لم يتم توفير SIM ‏MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"‏غير مسموح باستخدام الهاتف MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-az/strings.xml b/core/res/res/values-mcc310-mnc170-az/strings.xml
index a690668..43491fa 100644
--- a/core/res/res/values-mcc310-mnc170-az/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-az/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM MM#2 təmin etmir"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM MM#3 dəstəkləmir"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"MM#6 telefonu dəstəklənmir"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-bg/strings.xml b/core/res/res/values-mcc310-mnc170-bg/strings.xml
index 1158b3b..b93c5c1 100644
--- a/core/res/res/values-mcc310-mnc170-bg/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-bg/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM картата не е обезпечена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM картата не е разрешена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Телефонът не е разрешен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-bn/strings.xml b/core/res/res/values-mcc310-mnc170-bn/strings.xml
new file mode 100644
index 0000000..1c22bc1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc170-bn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"সিমের অনুমতি নেই MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ফোন অনুমোদিত নয় MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc170-ca/strings.xml b/core/res/res/values-mcc310-mnc170-ca/strings.xml
index 9abeeb7..c82d5a5 100644
--- a/core/res/res/values-mcc310-mnc170-ca/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ca/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"La SIM no està proporcionada a MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"La SIM no és compatible a MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telèfon no compatible MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-cs/strings.xml b/core/res/res/values-mcc310-mnc170-cs/strings.xml
index 2d4d2fb..2443292 100644
--- a/core/res/res/values-mcc310-mnc170-cs/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-cs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM karta není poskytována (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM karta není povolena (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefon není povolen (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-da/strings.xml b/core/res/res/values-mcc310-mnc170-da/strings.xml
index ae2155fa..98ab336 100644
--- a/core/res/res/values-mcc310-mnc170-da/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-da/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kort leveres ikke MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kort er ikke tilladt MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefonen har ikke adgangstilladelse MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-de/strings.xml b/core/res/res/values-mcc310-mnc170-de/strings.xml
index f7c5eec..f3c0b9a 100644
--- a/core/res/res/values-mcc310-mnc170-de/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-de/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-Karte nicht eingerichtet MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-Karte nicht zulässig MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Smartphone nicht zulässig MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-el/strings.xml b/core/res/res/values-mcc310-mnc170-el/strings.xml
index 68b7008..42000eb 100644
--- a/core/res/res/values-mcc310-mnc170-el/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-el/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Δεν παρέχεται κάρτα SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc170-en-rAU/strings.xml
index fd16620..d389436 100644
--- a/core/res/res/values-mcc310-mnc170-en-rAU/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-en-rAU/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc170-en-rGB/strings.xml
index fd16620..d389436 100644
--- a/core/res/res/values-mcc310-mnc170-en-rGB/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-en-rGB/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc170-en-rIN/strings.xml
index fd16620..d389436 100644
--- a/core/res/res/values-mcc310-mnc170-en-rIN/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-en-rIN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc170-es-rUS/strings.xml
index 50d3c12..c794ad8 100644
--- a/core/res/res/values-mcc310-mnc170-es-rUS/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-es-rUS/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM no provista MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM no permitida MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-es/strings.xml b/core/res/res/values-mcc310-mnc170-es/strings.xml
index 7191d04..5e0852a 100644
--- a/core/res/res/values-mcc310-mnc170-es/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-es/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM no proporcionada (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM no admitida (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-et/strings.xml b/core/res/res/values-mcc310-mnc170-et/strings.xml
index 7159bf9..24a004f 100644
--- a/core/res/res/values-mcc310-mnc170-et/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-et/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kaart on ette valmistamata MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kaart pole lubatud MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefon pole lubatud MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-eu/strings.xml b/core/res/res/values-mcc310-mnc170-eu/strings.xml
index 797f988..4f7b0d1 100644
--- a/core/res/res/values-mcc310-mnc170-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-eu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Ez dago SIM txartelik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Ez da onartzen SIM txartela MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-fa/strings.xml b/core/res/res/values-mcc310-mnc170-fa/strings.xml
index 968f952..1a516c4 100644
--- a/core/res/res/values-mcc310-mnc170-fa/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-fa/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"‏سیم‌کارت مجاز نیست MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-fi/strings.xml b/core/res/res/values-mcc310-mnc170-fi/strings.xml
index c0523f4..e638085 100644
--- a/core/res/res/values-mcc310-mnc170-fi/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-fi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kortti estetty MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc170-fr-rCA/strings.xml
index 5600fa4..3b87213 100644
--- a/core/res/res/values-mcc310-mnc170-fr-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-fr-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Carte SIM non configurée, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Carte SIM non autorisée, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-fr/strings.xml b/core/res/res/values-mcc310-mnc170-fr/strings.xml
index 73b4f0e..0f6adf0 100644
--- a/core/res/res/values-mcc310-mnc170-fr/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-fr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Carte SIM non provisionnée MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Carte SIM non autorisée MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-gl/strings.xml b/core/res/res/values-mcc310-mnc170-gl/strings.xml
index fe13211..a2513d2 100644
--- a/core/res/res/values-mcc310-mnc170-gl/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-gl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Non se admite a tarxeta SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Non se admite o teléfono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-gu/strings.xml b/core/res/res/values-mcc310-mnc170-gu/strings.xml
index 60eba5b..adf23e4 100644
--- a/core/res/res/values-mcc310-mnc170-gu/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-gu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIMને MM#2ની જોગવાઈ નથી"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"MM#6 ફોનની મંજૂરી નથી"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-hi/strings.xml b/core/res/res/values-mcc310-mnc170-hi/strings.xml
index eb350b0..134dbc1 100644
--- a/core/res/res/values-mcc310-mnc170-hi/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-hi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM काम नहीं कर रहा है MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM की अनुमति नहीं है MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"फ़ोन की इजाज़त नहीं है MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-hr/strings.xml b/core/res/res/values-mcc310-mnc170-hr/strings.xml
index d5cf025..e640ae5 100644
--- a/core/res/res/values-mcc310-mnc170-hr/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-hr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Ne pruža se usluga za SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM nije dopušten MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefon nije dopušten MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-hu/strings.xml b/core/res/res/values-mcc310-mnc170-hu/strings.xml
index e05e700..8d6dd9f 100644
--- a/core/res/res/values-mcc310-mnc170-hu/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-hu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Nem engedélyezett SIM-kártya (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"A SIM-kártya nem engedélyezett (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-hy/strings.xml b/core/res/res/values-mcc310-mnc170-hy/strings.xml
index 90a5f6d..3c30292 100644
--- a/core/res/res/values-mcc310-mnc170-hy/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-hy/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-in/strings.xml b/core/res/res/values-mcc310-mnc170-in/strings.xml
index fc1bd0a..51a82df 100644
--- a/core/res/res/values-mcc310-mnc170-in/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-in/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM tidak di-provisioning MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM tidak diizinkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Ponsel tidak diizinkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-is/strings.xml b/core/res/res/values-mcc310-mnc170-is/strings.xml
index eef786c..e9c6d48 100644
--- a/core/res/res/values-mcc310-mnc170-is/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-is/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-korti ekki úthlutað MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kort ekki leyft MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Sími ekki leyfður MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-it/strings.xml b/core/res/res/values-mcc310-mnc170-it/strings.xml
index eaf0abc..8e97b1b 100644
--- a/core/res/res/values-mcc310-mnc170-it/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-it/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Scheda SIM non predisposta MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Scheda SIM non consentita MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefono non consentito MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-iw/strings.xml b/core/res/res/values-mcc310-mnc170-iw/strings.xml
index edee703..cd818d6 100644
--- a/core/res/res/values-mcc310-mnc170-iw/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-iw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"‏הטלפון לא מורשה MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ja/strings.xml b/core/res/res/values-mcc310-mnc170-ja/strings.xml
index 6942641..b019dd1 100644
--- a/core/res/res/values-mcc310-mnc170-ja/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ja/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM には対応していません(MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM は許可されていません(MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"電話は許可されていません(MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ka/strings.xml b/core/res/res/values-mcc310-mnc170-ka/strings.xml
index 6f6c4aa..fe5bc11 100644
--- a/core/res/res/values-mcc310-mnc170-ka/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ka/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM ბარათი დაუშვებელია (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ტელეფონი დაუშვებელია MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-kk/strings.xml b/core/res/res/values-mcc310-mnc170-kk/strings.xml
index 210fb31..2f24d65 100644
--- a/core/res/res/values-mcc310-mnc170-kk/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-kk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM картасы қарастырылмаған MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM картасына рұқсат етілмеген MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Телефон пайдалануға болмайды MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-km/strings.xml b/core/res/res/values-mcc310-mnc170-km/strings.xml
index 79acf48..4a121e4 100644
--- a/core/res/res/values-mcc310-mnc170-km/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-km/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-kn/strings.xml b/core/res/res/values-mcc310-mnc170-kn/strings.xml
index e11523b..5bd7f17 100644
--- a/core/res/res/values-mcc310-mnc170-kn/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-kn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ಫೋನ್ MM#6 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ko/strings.xml b/core/res/res/values-mcc310-mnc170-ko/strings.xml
index 22d7e35..783e7d5 100644
--- a/core/res/res/values-mcc310-mnc170-ko/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ko/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM이 프로비저닝되지 않음 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM이 허용되지 않음 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ky/strings.xml b/core/res/res/values-mcc310-mnc170-ky/strings.xml
index 988c40a..4c09085 100644
--- a/core/res/res/values-mcc310-mnc170-ky/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ky/strings.xml
@@ -20,6 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM картаны колдонууга тыюу салынган MM#3"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM карта таанылган жок (MM#2)"</string>
+    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Телефонду колдонууга тыюу салынган MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-lo/strings.xml b/core/res/res/values-mcc310-mnc170-lo/strings.xml
index 3073000..e0a7379 100644
--- a/core/res/res/values-mcc310-mnc170-lo/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-lo/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-lt/strings.xml b/core/res/res/values-mcc310-mnc170-lt/strings.xml
index 127e69f..25698a9 100644
--- a/core/res/res/values-mcc310-mnc170-lt/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-lt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM kortelė neteikiama (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM kortelė neleidžiama (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefonas neleidžiamas (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-lv/strings.xml b/core/res/res/values-mcc310-mnc170-lv/strings.xml
index da2ff7c..6bb0838 100644
--- a/core/res/res/values-mcc310-mnc170-lv/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-lv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM karte netiek nodrošināta: MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM karti nav atļauts izmantot: MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Tālruni nav atļauts izmantot: MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-mk/strings.xml b/core/res/res/values-mcc310-mnc170-mk/strings.xml
index 3bc8194..de6ac62 100644
--- a/core/res/res/values-mcc310-mnc170-mk/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-mk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Не е обезбедена SIM-картичка, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Не е дозволена SIM-картичка, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Телефонот не е дозволен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ml/strings.xml b/core/res/res/values-mcc310-mnc170-ml/strings.xml
index 8d36412..4bfdffc 100644
--- a/core/res/res/values-mcc310-mnc170-ml/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ml/strings.xml
@@ -20,6 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
+    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ഫോൺ അനുവദനീയമല്ല MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-mn/strings.xml b/core/res/res/values-mcc310-mnc170-mn/strings.xml
index 59f24ec..6e5cfc3 100644
--- a/core/res/res/values-mcc310-mnc170-mn/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-mn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Утсыг зөвшөөрөөгүй MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-mr/strings.xml b/core/res/res/values-mcc310-mnc170-mr/strings.xml
index 938207c..a2fe305 100644
--- a/core/res/res/values-mcc310-mnc170-mr/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-mr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"फोन MM#6 ला अनुमती देत नाही"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ms/strings.xml b/core/res/res/values-mcc310-mnc170-ms/strings.xml
index 36be774..698c5d7 100644
--- a/core/res/res/values-mcc310-mnc170-ms/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ms/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM tidak diperuntukkan MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM tidak dibenarkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefon tidak dibenarkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-my/strings.xml b/core/res/res/values-mcc310-mnc170-my/strings.xml
index 61f1a67..6c2be32 100644
--- a/core/res/res/values-mcc310-mnc170-my/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-my/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-nb/strings.xml b/core/res/res/values-mcc310-mnc170-nb/strings.xml
index 3f213da..3a404b8 100644
--- a/core/res/res/values-mcc310-mnc170-nb/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-nb/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kortet er ikke klargjort, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kortet er ikke tillatt, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefonen er ikke tillatt, MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ne/strings.xml b/core/res/res/values-mcc310-mnc170-ne/strings.xml
index d7febc4..65c01a1 100644
--- a/core/res/res/values-mcc310-mnc170-ne/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ne/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM को प्रावधान छैन MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM लाई अनुमति छैन MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"फोनलाई अनुमति छैन MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-nl/strings.xml b/core/res/res/values-mcc310-mnc170-nl/strings.xml
index b1f9ba8..bdfb53a 100644
--- a/core/res/res/values-mcc310-mnc170-nl/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-nl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Simkaart niet geregistreerd MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Simkaart niet toegestaan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefoon niet toegestaan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-pa/strings.xml b/core/res/res/values-mcc310-mnc170-pa/strings.xml
new file mode 100644
index 0000000..6cdf639
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc170-pa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ਫ਼ੋਨ ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc170-pl/strings.xml b/core/res/res/values-mcc310-mnc170-pl/strings.xml
index d1ecd5d..41100a4 100644
--- a/core/res/res/values-mcc310-mnc170-pl/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-pl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"MM#2 – karta SIM nieobsługiwana"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"MM#3 – niedozwolona karta SIM"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"MM#6 – telefon niedozwolony"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc170-pt-rBR/strings.xml
index fc31e9e..fcffa16 100644
--- a/core/res/res/values-mcc310-mnc170-pt-rBR/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-pt-rBR/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc170-pt-rPT/strings.xml
index fc31e9e..7d43bf3 100644
--- a/core/res/res/values-mcc310-mnc170-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-pt-rPT/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telemóvel não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-pt/strings.xml b/core/res/res/values-mcc310-mnc170-pt/strings.xml
index fc31e9e..fcffa16 100644
--- a/core/res/res/values-mcc310-mnc170-pt/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-pt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ro/strings.xml b/core/res/res/values-mcc310-mnc170-ro/strings.xml
index 1ee5080..7c2c09e 100644
--- a/core/res/res/values-mcc310-mnc170-ro/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ro/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Cardul SIM nu este activat MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Cardul SIM nu este permis MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefonul nu este permis MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ru/strings.xml b/core/res/res/values-mcc310-mnc170-ru/strings.xml
index 0e00909..3b457da 100644
--- a/core/res/res/values-mcc310-mnc170-ru/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ru/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-карта не активирована (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Использование SIM-карты запрещено (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Звонки запрещены (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-si/strings.xml b/core/res/res/values-mcc310-mnc170-si/strings.xml
index bbd1e4c..61e0143 100644
--- a/core/res/res/values-mcc310-mnc170-si/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-si/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM MM#3 ඉඩ නොදේ"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-sk/strings.xml b/core/res/res/values-mcc310-mnc170-sk/strings.xml
index e5f9376..cf71dd3 100644
--- a/core/res/res/values-mcc310-mnc170-sk/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-sk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM karta nie je k dispozícii – MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM karta je zakázaná – MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefón nie je povolený (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-sl/strings.xml b/core/res/res/values-mcc310-mnc170-sl/strings.xml
index 2d4c7dd..2e600ac 100644
--- a/core/res/res/values-mcc310-mnc170-sl/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-sl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Kartica SIM ni omogočena za uporabo MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Kartica SIM ni dovoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefon ni dovoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-sq/strings.xml b/core/res/res/values-mcc310-mnc170-sq/strings.xml
index df5b537..0b22ca2 100644
--- a/core/res/res/values-mcc310-mnc170-sq/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-sq/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Karta SIM nuk është dhënë MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Karta SIM nuk lejohet MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefoni nuk lejohet MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-sr/strings.xml b/core/res/res/values-mcc310-mnc170-sr/strings.xml
index 6bfbbb2..42057fe 100644
--- a/core/res/res/values-mcc310-mnc170-sr/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-sr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM картица није подешена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Телефон није дозвољен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-sv/strings.xml b/core/res/res/values-mcc310-mnc170-sv/strings.xml
index 1a28db1..c609747 100644
--- a/core/res/res/values-mcc310-mnc170-sv/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-sv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kort tillhandahålls inte MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kort tillåts inte MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Mobil tillåts inte MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-sw/strings.xml b/core/res/res/values-mcc310-mnc170-sw/strings.xml
index 0852115..7727944 100644
--- a/core/res/res/values-mcc310-mnc170-sw/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-sw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM haitumiki MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM hairuhusiwi MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Simu hairuhusiwi MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ta/strings.xml b/core/res/res/values-mcc310-mnc170-ta/strings.xml
index 0277cc2..cde140f 100644
--- a/core/res/res/values-mcc310-mnc170-ta/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ta/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"சிம் அமைக்கப்படவில்லை MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ஃபோன் அனுமதிக்கப்படவில்லை MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-te/strings.xml b/core/res/res/values-mcc310-mnc170-te/strings.xml
new file mode 100644
index 0000000..a088bb0
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc170-te/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM MM#2ని సక్రియం చేయలేదు"</string>
+    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM MM#3ని అనుమతించలేదు"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc170-th/strings.xml b/core/res/res/values-mcc310-mnc170-th/strings.xml
index e5d02c8..ad5f5dc 100644
--- a/core/res/res/values-mcc310-mnc170-th/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-th/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"ไม่มีการจัดสรรซิม MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-tl/strings.xml b/core/res/res/values-mcc310-mnc170-tl/strings.xml
index e285759..187593a 100644
--- a/core/res/res/values-mcc310-mnc170-tl/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-tl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Hindi na-provision ang SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Hindi pinapahintulutan ang SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Hindi pinapahintulutan ang telepono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-tr/strings.xml b/core/res/res/values-mcc310-mnc170-tr/strings.xml
index b5102ef..e4a9255 100644
--- a/core/res/res/values-mcc310-mnc170-tr/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-tr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM MM#3\'e izin vermiyor"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Telefona izin verilmiyor MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-uk/strings.xml b/core/res/res/values-mcc310-mnc170-uk/strings.xml
index 37e3118..89ad9b3 100644
--- a/core/res/res/values-mcc310-mnc170-uk/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-uk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-карту не надано (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-карта заборонена (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Телефон заборонено (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-ur/strings.xml b/core/res/res/values-mcc310-mnc170-ur/strings.xml
index ea8b93e..50cd57e 100644
--- a/core/res/res/values-mcc310-mnc170-ur/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-ur/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"‏SIM کی اجازت نہیں ہے MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"‏فون کی اجازت نہیں ہے MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-uz/strings.xml b/core/res/res/values-mcc310-mnc170-uz/strings.xml
index 0bb3f52..9bfecfd 100644
--- a/core/res/res/values-mcc310-mnc170-uz/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-uz/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Chaqiruvlar taqiqlangan (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-vi/strings.xml b/core/res/res/values-mcc310-mnc170-vi/strings.xml
index a37f48f..ad87648 100644
--- a/core/res/res/values-mcc310-mnc170-vi/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-vi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM không được cấp phép MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM không được phép MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Không cho phép điện thoại MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc170-zh-rCN/strings.xml
index f072b28..de68fe1 100644
--- a/core/res/res/values-mcc310-mnc170-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-zh-rCN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"未配置的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"不被允许的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"不受允许的手机 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc170-zh-rHK/strings.xml
index db14b90..5fd10b3 100644
--- a/core/res/res/values-mcc310-mnc170-zh-rHK/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-zh-rHK/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc170-zh-rTW/strings.xml
index db14b90..cb19625 100644
--- a/core/res/res/values-mcc310-mnc170-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-zh-rTW/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"不支援的手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-zu/strings.xml b/core/res/res/values-mcc310-mnc170-zu/strings.xml
index 282f403..26890e4e 100644
--- a/core/res/res/values-mcc310-mnc170-zu/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-zu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"I-SIM ayinikezelwe MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1130721094178658338">"I-SIM ayivunyelwe MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3173546391131606065">"Ifoni ayivunyelwe MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170/strings.xml b/core/res/res/values-mcc310-mnc170/strings.xml
index a3fea29..6a404d5 100644
--- a/core/res/res/values-mcc310-mnc170/strings.xml
+++ b/core/res/res/values-mcc310-mnc170/strings.xml
@@ -20,4 +20,5 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string>
     <string name="mmcc_illegal_ms">SIM not allowed MM#3</string>
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc260-af/strings.xml b/core/res/res/values-mcc310-mnc260-af/strings.xml
deleted file mode 100644
index ee051c5..0000000
--- a/core/res/res/values-mcc310-mnc260-af/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra jou diensverskaffer eers om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registreer by jou diensverskaffer"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-oproep"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-am/strings.xml b/core/res/res/values-mcc310-mnc260-am/strings.xml
deleted file mode 100644
index 74f711a..0000000
--- a/core/res/res/values-mcc310-mnc260-am/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ መጠየቅ አለብዎት። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ።"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"የአገልግሎት አቅራቢዎ ጋር ይመዝገቡ"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"የ%s Wi-Fi ጥሪ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ar/strings.xml b/core/res/res/values-mcc310-mnc260-ar/strings.xml
deleted file mode 100644
index 5a84295..0000000
--- a/core/res/res/values-mcc310-mnc260-ar/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"‏لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذا الجهاز، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"التسجيل لدى مشغّل شبكة الجوّال"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"‏%s جارٍ الاتصال عبر Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-az/strings.xml b/core/res/res/values-mcc310-mnc260-az/strings.xml
deleted file mode 100644
index 32d21c5..0000000
--- a/core/res/res/values-mcc310-mnc260-az/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi üzərindən zəng etmək və mesaj göndərmək üçün ilk öncə operatordan bu xidməti ayarlamağı tələb edin. Sonra Ayarlardan Wi-Fi çağrısını aktivləşdirin."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Operatorla qeydiyyatdan keçin"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Zəngi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc260-b+sr+Latn/strings.xml
deleted file mode 100644
index 6750940..0000000
--- a/core/res/res/values-mcc310-mnc260-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrujte se kod mobilnog operatera"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi pozivanje preko operatera %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-be/strings.xml b/core/res/res/values-mcc310-mnc260-be/strings.xml
deleted file mode 100644
index 497366b..0000000
--- a/core/res/res/values-mcc310-mnc260-be/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Каб рабіць выклікі і адпраўляць паведамленні па Wi-Fi, спачатку папрасіце свайго аператара наладзіць гэту паслугу. Затым зноў уключыце Wi-Fi-тэлефанію ў меню Налады."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Зарэгіструйцеся ў свайго аператара"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi-тэлефанія %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-bg/strings.xml b/core/res/res/values-mcc310-mnc260-bg/strings.xml
deleted file mode 100644
index a6711208..0000000
--- a/core/res/res/values-mcc310-mnc260-bg/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Регистриране с оператора ви"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s – обаждания през Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-bn/strings.xml b/core/res/res/values-mcc310-mnc260-bn/strings.xml
deleted file mode 100644
index 67955d5..0000000
--- a/core/res/res/values-mcc310-mnc260-bn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi এর মাধ্যমে কল করতে ও বার্তা পাঠাতে, প্রথমে আপনার পরিষেবা প্রদানকারীকে এই পরিষেবার সেট আপ করার বিষয়ে জিজ্ঞাসা করুন। তারপরে আবার সেটিংস থেকে Wi-Fi কলিং চালু করুন।"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"আপনার পরিষেবা প্রদানকারীকে নথিভুক্ত করুন"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi কলিং"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-bs/strings.xml b/core/res/res/values-mcc310-mnc260-bs/strings.xml
deleted file mode 100644
index 64e4862..0000000
--- a/core/res/res/values-mcc310-mnc260-bs/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Da biste pozivali i slali poruke preko Wi-Fi-ja, prvo zatražite od operatera da postavi tu uslugu. Potom u Postavkama ponovo uključite Wi-Fi pozivanje."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrirajte se kod svog operatera"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi pozivanje preko operatera %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ca/strings.xml b/core/res/res/values-mcc310-mnc260-ca/strings.xml
deleted file mode 100644
index 8ce8dc8..0000000
--- a/core/res/res/values-mcc310-mnc260-ca/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi des de Configuració."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registra\'t amb el teu operador de telefonia mòbil"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Trucada de Wi-Fi de: %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-cs/strings.xml b/core/res/res/values-mcc310-mnc260-cs/strings.xml
deleted file mode 100644
index 61ba268..0000000
--- a/core/res/res/values-mcc310-mnc260-cs/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Chcete-li volat a odesílat textové zprávy přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrace u operátora"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Volání přes Wi-Fi: %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-da/strings.xml b/core/res/res/values-mcc310-mnc260-da/strings.xml
deleted file mode 100644
index 0c612e5..0000000
--- a/core/res/res/values-mcc310-mnc260-da/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Hvis du vil foretage opkald og sende beskeder via Wi-Fi, skal du først anmode dit mobilselskab om at konfigurere denne tjeneste. Derefter skal du slå Wi-Fi-opkald til igen fra Indstillinger."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrer dig hos dit mobilselskab"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-opkald"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-de/strings.xml b/core/res/res/values-mcc310-mnc260-de/strings.xml
deleted file mode 100644
index b9cbb48..0000000
--- a/core/res/res/values-mcc310-mnc260-de/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann erneut über die Einstellungen."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registriere dich bei deinem Mobilfunkanbieter."</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Anrufe über WLAN"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-el/strings.xml b/core/res/res/values-mcc310-mnc260-el/strings.xml
deleted file mode 100644
index b4cd123..0000000
--- a/core/res/res/values-mcc310-mnc260-el/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά τη λειτουργία κλήσεων μέσω Wi-Fi από τις Ρυθμίσεις."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Εγγραφείτε μέσω της εταιρείας κινητής τηλεφωνίας"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Κλήση Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc260-en-rAU/strings.xml
deleted file mode 100644
index 1d300ea..0000000
--- a/core/res/res/values-mcc310-mnc260-en-rAU/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Register with your operator"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Calling"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc260-en-rGB/strings.xml
deleted file mode 100644
index 1d300ea..0000000
--- a/core/res/res/values-mcc310-mnc260-en-rGB/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Register with your operator"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Calling"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc260-en-rIN/strings.xml
deleted file mode 100644
index 1d300ea..0000000
--- a/core/res/res/values-mcc310-mnc260-en-rIN/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Register with your operator"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Calling"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc260-es-rUS/strings.xml
deleted file mode 100644
index 6398c02..0000000
--- a/core/res/res/values-mcc310-mnc260-es-rUS/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Para realizar llamadas o enviar mensajes por Wi-Fi, primero solicítale al proveedor que instale el servicio. Luego, vuelve a activar las llamadas por Wi-Fi desde Configuración."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Regístrate con tu proveedor."</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Llamada por Wi-Fi de %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-es/strings.xml b/core/res/res/values-mcc310-mnc260-es/strings.xml
deleted file mode 100644
index e959116..0000000
--- a/core/res/res/values-mcc310-mnc260-es/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Para hacer llamadas y enviar mensajes por Wi-Fi, debes pedir antes a tu operador que configure este servicio. Una vez hecho esto, vuelva a activar las llamadas Wi-Fi en Ajustes."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Regístrate con tu operador"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Llamada Wi-Fi de %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-et/strings.xml b/core/res/res/values-mcc310-mnc260-et/strings.xml
deleted file mode 100644
index 2310130..0000000
--- a/core/res/res/values-mcc310-mnc260-et/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Üle WiFi-võrgu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registreeruge operaatori juures"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s WiFi kaudu helistamine"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-eu/strings.xml b/core/res/res/values-mcc310-mnc260-eu/strings.xml
deleted file mode 100644
index 8fb03d4..0000000
--- a/core/res/res/values-mcc310-mnc260-eu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Erregistratu operadorearekin"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi bidezko deiak"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-fa/strings.xml b/core/res/res/values-mcc310-mnc260-fa/strings.xml
deleted file mode 100644
index 659a0dd..0000000
--- a/core/res/res/values-mcc310-mnc260-fa/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"‏برای برقراری تماس و ارسال پیام از طریق Wi-Fi، ابتدا از شرکت مخابراتی‌تان درخواست کنید این سرویس را راه‌اندازی کند. سپس دوباره از تنظیمات، تماس Wi-Fi را روشن کنید."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"ثبت نام با شرکت مخابراتی شما"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"‏تماس ‪%s Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-fi/strings.xml b/core/res/res/values-mcc310-mnc260-fi/strings.xml
deleted file mode 100644
index 1eecb61..0000000
--- a/core/res/res/values-mcc310-mnc260-fi/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Rekisteröidy operaattorisi asiakkaaksi."</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi-puhelut: %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc260-fr-rCA/strings.xml
deleted file mode 100644
index c767039..0000000
--- a/core/res/res/values-mcc310-mnc260-fr-rCA/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Inscrivez-vous auprès de votre fournisseur de services"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Appels Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-fr/strings.xml b/core/res/res/values-mcc310-mnc260-fr/strings.xml
deleted file mode 100644
index 1de93ca..0000000
--- a/core/res/res/values-mcc310-mnc260-fr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Pour effectuer des appels et envoyer des messages via le Wi-Fi, demandez tout d\'abord à votre opérateur de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Inscrivez-vous auprès de votre opérateur."</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Appels Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-gl/strings.xml b/core/res/res/values-mcc310-mnc260-gl/strings.xml
deleted file mode 100644
index 2747ab3..0000000
--- a/core/res/res/values-mcc310-mnc260-gl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro pídelle ao teu operador que configure este servizo. A continuación, activa de novo as chamadas wifi en Configuración."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Rexístrate co teu operador"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Chamadas wifi de %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-gu/strings.xml b/core/res/res/values-mcc310-mnc260-gu/strings.xml
deleted file mode 100644
index d02d5ad..0000000
--- a/core/res/res/values-mcc310-mnc260-gu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi પર કૉલ્સ કરવા અને સંદેશા મોકલવા માટે, પહેલા તમારા કેરીઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી Wi-Fi કૉલિંગ ચાલુ કરો."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"તમારા કેરીઅર સાથે નોંધણી કરો"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi કૉલિંગ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hi/strings.xml b/core/res/res/values-mcc310-mnc260-hi/strings.xml
deleted file mode 100644
index a19f51a..0000000
--- a/core/res/res/values-mcc310-mnc260-hi/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट करने के लिए कहें. उसके बाद सेटिंग से पुन: वाई-फ़ाई कॉलिंग चालू करें."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"अपने वाहक के साथ पंजीकृत करें"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s वाई-फ़ाई कॉलिंग"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hr/strings.xml b/core/res/res/values-mcc310-mnc260-hr/strings.xml
deleted file mode 100644
index dc48a1e..0000000
--- a/core/res/res/values-mcc310-mnc260-hr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Da biste telefonirali i slali pozive putem Wi-Fi-ja, morate tražiti od mobilnog operatera da vam postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u Postavkama."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrirajte se kod mobilnog operatera"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi pozivanje"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hu/strings.xml b/core/res/res/values-mcc310-mnc260-hu/strings.xml
deleted file mode 100644
index ef6a2fc..0000000
--- a/core/res/res/values-mcc310-mnc260-hu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Ha Wi-Fi-n szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután a Beállítások menüben kapcsolhatja be újra a Wi-Fi-hívást."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Regisztráljon a szolgáltatójánál"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-hívás"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hy/strings.xml b/core/res/res/values-mcc310-mnc260-hy/strings.xml
deleted file mode 100644
index 0a37df2..0000000
--- a/core/res/res/values-mcc310-mnc260-hy/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ ծառայությունը կարգավորելու համար: Ապա նորից միացրեք Wi-Fi զանգերը Կարգավորումներում:"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Գրանցվեք օպերատորի մոտ"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi զանգեր"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-in/strings.xml b/core/res/res/values-mcc310-mnc260-in/strings.xml
deleted file mode 100644
index 4da068e..0000000
--- a/core/res/res/values-mcc310-mnc260-in/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Untuk melakukan panggilan telepon dan mengirim pesan melalui Wi-Fi, terlebih dahulu minta operator untuk menyiapkan layanan ini. Lalu, aktifkan lagi panggilan telepon Wi-Fi dari Setelan."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Harap daftarkan ke operator"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Panggilan Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-is/strings.xml b/core/res/res/values-mcc310-mnc260-is/strings.xml
deleted file mode 100644
index 1fd14d4..0000000
--- a/core/res/res/values-mcc310-mnc260-is/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Skráðu þig hjá símafyrirtækinu"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi símtöl"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-it/strings.xml b/core/res/res/values-mcc310-mnc260-it/strings.xml
deleted file mode 100644
index 6a7dec5..0000000
--- a/core/res/res/values-mcc310-mnc260-it/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Per effettuare chiamate e inviare messaggi tramite Wi-Fi, è necessario prima chiedere all\'operatore telefonico di attivare il servizio. Successivamente, riattiva le chiamate Wi-Fi dalle Impostazioni."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrati con il tuo operatore"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Chiamata Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-iw/strings.xml b/core/res/res/values-mcc310-mnc260-iw/strings.xml
deleted file mode 100644
index 1bcce94..0000000
--- a/core/res/res/values-mcc310-mnc260-iw/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"‏כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב התקשרות Wi-Fi מ\'הגדרות\'."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"הירשם אצל הספק"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"‏שיחות Wi-Fi של %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ja/strings.xml b/core/res/res/values-mcc310-mnc260-ja/strings.xml
deleted file mode 100644
index 05a333b..0000000
--- a/core/res/res/values-mcc310-mnc260-ja/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社にWi-Fiサービスを申し込んだ上で、設定画面でWi-Fi発信を再度ONにしてください。"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"携帯通信会社に登録してください"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi通話(%s)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ka/strings.xml b/core/res/res/values-mcc310-mnc260-ka/strings.xml
deleted file mode 100644
index dbb2822..0000000
--- a/core/res/res/values-mcc310-mnc260-ka/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi-ს მეშვეობით ზარების განხორციელების ან შეტყობინების გაგზავნისათვის, პირველ რიგში დაეკითხეთ თქვენს ოპერატორს აღნიშნულ მომსახურებაზე. შემდეგ ხელახლა ჩართეთ Wi-Fi ზარები პარამეტრებიდან."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"დაარეგისტრირეთ თქვენი ოპერატორი"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s დარეკვა Wi-Fi-ს მეშვეობით"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-kk/strings.xml b/core/res/res/values-mcc310-mnc260-kk/strings.xml
deleted file mode 100644
index 80eebfc..0000000
--- a/core/res/res/values-mcc310-mnc260-kk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi арқылы қоңырау шалу және хабарларды жіберу үшін алдымен жабдықтаушыңыздан осы қызметті орнатуды сұраңыз. Содан кейін Параметрлерден Wi-Fi қоңырау шалуын іске қосыңыз."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Жабдықтаушыңыз арқылы тіркелу"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi арқылы қоңырау шалу"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-km/strings.xml b/core/res/res/values-mcc310-mnc260-km/strings.xml
deleted file mode 100644
index e3cd1b2..0000000
--- a/core/res/res/values-mcc310-mnc260-km/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"ដើម្បីធ្វើការហៅ និងផ្ញើសារតាម Wi-Fi ដំបូងឡើយអ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនរបស់អ្នកដំឡើងសេវាកម្មនេះសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតចេញពីការកំណត់។"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"ចុះឈ្មោះជាមួយក្រុមហ៊ុនរបស់អ្នក"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"ការហៅតាមរយៈ Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-kn/strings.xml b/core/res/res/values-mcc310-mnc260-kn/strings.xml
deleted file mode 100644
index 0a9d58d..0000000
--- a/core/res/res/values-mcc310-mnc260-kn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi ಬಳಸಿಕೊಂಡು ಕರೆ ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಮೊದಲು ಈ ಸಾಧನವನ್ನು ಹೊಂದಿಸಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ತದನಂತರ ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಮತ್ತೆ Wi-Fi ಆನ್‌ ಮಾಡಿ."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"ನಿಮ್ಮ ವಾಹಕದಲ್ಲಿ ನೋಂದಾಯಿಸಿಕೊಳ್ಳಿ"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi ಕರೆ ಮಾಡುವಿಕೆ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ko/strings.xml b/core/res/res/values-mcc310-mnc260-ko/strings.xml
deleted file mode 100644
index 5581235..0000000
--- a/core/res/res/values-mcc310-mnc260-ko/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 이 기능을 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"이동통신사에 등록"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi 통화"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ky/strings.xml b/core/res/res/values-mcc310-mnc260-ky/strings.xml
deleted file mode 100644
index 775542d..0000000
--- a/core/res/res/values-mcc310-mnc260-ky/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Операторуңузга катталыңыз"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Чалуу"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-lo/strings.xml b/core/res/res/values-mcc310-mnc260-lo/strings.xml
deleted file mode 100644
index 49f79016..0000000
--- a/core/res/res/values-mcc310-mnc260-lo/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"ເພື່ອ​ໂທ ແລະ​ສົ່ງ​ຂໍ້​ຄວາມ​ຢູ່​ເທິງ Wi-Fi, ກ່ອນ​ອື່ນ​ໝົດ​ໃຫ້​ຖ້າມ​ຜູ້​ໃຫ້​ບໍ​ລິ​ການ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ ເພື່ອ​ຕັ້ງ​ການ​ບໍ​ລິ​ການ​ນີ້. ຈາກນັ້ນ​ເປີດການ​ໂທ Wi-Fi ອີກ​ຈາກ​ການ​ຕັ້ງ​ຄ່າ."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"ລົງ​ທະ​ບຽນ​ກັບ​ຜູ້​ໃຫ້​ບໍ​ລິ​ການ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"ການ​ໂທ %s Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-lt/strings.xml b/core/res/res/values-mcc310-mnc260-lt/strings.xml
deleted file mode 100644
index 4c3ebb7..0000000
--- a/core/res/res/values-mcc310-mnc260-lt/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Jei norite skambinti ir siųsti pranešimus „Wi-Fi“ ryšiu, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite skambinimą „Wi-Fi“ ryšiu „Nustatymų“ skiltyje."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Užregistruokite pas operatorių"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"„%s“ „Wi-Fi“ skambinimas"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-lv/strings.xml b/core/res/res/values-mcc310-mnc260-lv/strings.xml
deleted file mode 100644
index 23d8ca0..0000000
--- a/core/res/res/values-mcc310-mnc260-lv/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoru iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Reģistrēt to pie sava mobilo sakaru operatora"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi zvani"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-mk/strings.xml b/core/res/res/values-mcc310-mnc260-mk/strings.xml
deleted file mode 100644
index 878b7af..0000000
--- a/core/res/res/values-mcc310-mnc260-mk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"За повикување и испраќање пораки преку Wi-Fi, прво побарајте од операторот да ви ја постави оваа услуга. Потоа повторно вклучете повикување преку Wi-Fi во Поставки."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Регистрирајте се со операторот"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Повикување преку Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ml/strings.xml b/core/res/res/values-mcc310-mnc260-ml/strings.xml
deleted file mode 100644
index a94680d..0000000
--- a/core/res/res/values-mcc310-mnc260-ml/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"വൈഫൈ വഴി കോളുകൾ വിളിക്കാനും സന്ദേശങ്ങൾ അയയ്‌ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"നിങ്ങളുടെ കാരിയറിൽ രജിസ്റ്റർ ചെയ്യുക"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s വൈഫൈ കോളിംഗ്"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-mn/strings.xml b/core/res/res/values-mcc310-mnc260-mn/strings.xml
deleted file mode 100644
index 4c97e2e..0000000
--- a/core/res/res/values-mcc310-mnc260-mn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi-аар дуудлага хийх болон мессеж илгээхээр бол эхлээд оператороосоо энэ төхөөрөмжийг тохируулж өгөхийг хүсээрэй. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаагаарай."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Операторт бүртгүүлэх"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Дуудлага"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-mr/strings.xml b/core/res/res/values-mcc310-mnc260-mr/strings.xml
deleted file mode 100644
index 06eceff..0000000
--- a/core/res/res/values-mcc310-mnc260-mr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठविण्यासाठी, प्रथम आपल्या वाहकास ही सेवा सेट करण्यास सांगा. नंतर सेटिंग्जमधून पुन्हा वाय-फाय कॉलिंग चालू करा."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"आपल्या वाहकासह नोंदणी करा"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s वाय-फाय कॉलिंग"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ms/strings.xml b/core/res/res/values-mcc310-mnc260-ms/strings.xml
deleted file mode 100644
index dafb3bd..0000000
--- a/core/res/res/values-mcc310-mnc260-ms/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, mula-mula minta pembawa anda untuk menyediakan perkhidmatan ini. Kemudian hidupkan panggilan Wi-Fi semula daripada Tetapan."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Daftar dengan pembawa anda"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Panggilan Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-my/strings.xml b/core/res/res/values-mcc310-mnc260-my/strings.xml
deleted file mode 100644
index 25ea191..0000000
--- a/core/res/res/values-mcc310-mnc260-my/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"ဝိုင်ဖိုင်သုံး၍ ဖုန်းခေါ်ဆိုရန်နှင့် မက်စေ့ဂျ်များပို့ရန်၊ ဤဝန်ဆောင်မှုအား စတင်သုံးနိုင်ရန်အတွက် သင့် မိုဘိုင်းဝန်ဆောင်မှုအား ဦးစွာမေးမြန်းပါ။ ထို့နောက် ဆက်တင်မှတဆင့် ဝိုင်ဖိုင် ခေါ်ဆိုမှုအား ထပ်ဖွင့်ပါ။"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"သင့် မိုဘိုင်းဝန်ဆောင်မှုဖြင့် မှတ်ပုံတင်ရန်"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s ဝိုင်ဖိုင် ခေါ်ဆိုမှု"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-nb/strings.xml b/core/res/res/values-mcc310-mnc260-nb/strings.xml
deleted file mode 100644
index 9918996..0000000
--- a/core/res/res/values-mcc310-mnc260-nb/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"For å ringe og sende meldinger over Wi-Fi må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrer deg hos operatøren din"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-anrop"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ne/strings.xml b/core/res/res/values-mcc310-mnc260-ne/strings.xml
deleted file mode 100644
index 6fb7b50..0000000
--- a/core/res/res/values-mcc310-mnc260-ne/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi बाट कल गर्न र सन्देशहरू पठाउन, सबभन्दा पहिला यो सेवा सेटअप गर्न तपाईँको वाहकलाई भन्नुहोस्। त्यसपछि फेरि सेटिङहरूबाट Wi-Fi कलिङ सक्रिय पार्नुहोस्।"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"तपाईँको वाहकसँग दर्ता गर्नुहोस्"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi कलिङ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-nl/strings.xml b/core/res/res/values-mcc310-mnc260-nl/strings.xml
deleted file mode 100644
index ac4961c..0000000
--- a/core/res/res/values-mcc310-mnc260-nl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via \'Instellingen\'."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registreren bij je provider"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Bellen via wifi van %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pa/strings.xml b/core/res/res/values-mcc310-mnc260-pa/strings.xml
deleted file mode 100644
index 0026681..0000000
--- a/core/res/res/values-mcc310-mnc260-pa/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi ਤੇ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਲਈ, ਪਹਿਲਾਂ ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਇਹ ਸੇਵਾ ਸੈਟ ਅਪ ਕਰਨ ਲਈ ਕਹੋ। ਫਿਰ ਸੈਟਿੰਗਾਂ ਵਿੱਚੋਂ Wi-Fi ਕਾਲਿੰਗ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰੋ।"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਰਜਿਸਟਰ ਕਰੋ"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi ਕਾਲਿੰਗ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pl/strings.xml b/core/res/res/values-mcc310-mnc260-pl/strings.xml
deleted file mode 100644
index b7f512d..0000000
--- a/core/res/res/values-mcc310-mnc260-pl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Zarejestruj u operatora"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Połączenia przez Wi-Fi (%s)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml
deleted file mode 100644
index bad49c3..0000000
--- a/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Faça registro na sua operadora"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s chamada Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc260-pt-rPT/strings.xml
deleted file mode 100644
index 18e3801..0000000
--- a/core/res/res/values-mcc310-mnc260-pt-rPT/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. Em seguida, nas Definições, ative novamente as chamadas por Wi-Fi."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registar-se junto do seu operador"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Chamadas por Wi-Fi da %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pt/strings.xml b/core/res/res/values-mcc310-mnc260-pt/strings.xml
deleted file mode 100644
index bad49c3..0000000
--- a/core/res/res/values-mcc310-mnc260-pt/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Faça registro na sua operadora"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s chamada Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ro/strings.xml b/core/res/res/values-mcc310-mnc260-ro/strings.xml
deleted file mode 100644
index 6b865a2..0000000
--- a/core/res/res/values-mcc310-mnc260-ro/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Pentru a apela și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Înregistrați-vă la operatorul dvs."</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Apelare prin Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ru/strings.xml b/core/res/res/values-mcc310-mnc260-ru/strings.xml
deleted file mode 100644
index 829c477..0000000
--- a/core/res/res/values-mcc310-mnc260-ru/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо сначала обратиться к оператору связи и подключить эту услугу. После этого вы сможете снова выбрать этот параметр в настройках."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Укажите оператора и зарегистрируйтесь"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Звонки по Wi-Fi (%s)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-si/strings.xml b/core/res/res/values-mcc310-mnc260-si/strings.xml
deleted file mode 100644
index de00901..0000000
--- a/core/res/res/values-mcc310-mnc260-si/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්‍රියාත්මක කරන්න."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"ඔබගේ වාහකය සමඟ ලියාපදිංචි වන්න"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi අමතමින්"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sk/strings.xml b/core/res/res/values-mcc310-mnc260-sk/strings.xml
deleted file mode 100644
index eb8b5f8..0000000
--- a/core/res/res/values-mcc310-mnc260-sk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrujte sa so svojím operátorom"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Volanie siete Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sl/strings.xml b/core/res/res/values-mcc310-mnc260-sl/strings.xml
deleted file mode 100644
index ae30c5a..0000000
--- a/core/res/res/values-mcc310-mnc260-sl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registracija pri operaterju"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Klicanje prek Wi-Fi-ja (%s)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sq/strings.xml b/core/res/res/values-mcc310-mnc260-sq/strings.xml
deleted file mode 100644
index 84ac153..0000000
--- a/core/res/res/values-mcc310-mnc260-sq/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Për të bërë telefonata dhe për të dërguar mesazhe me Wi-Fi, në fillim kërkoji operatorit celular ta konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi, nga Cilësimet."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Regjistrohu me operatorin tënd celular"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Telefonatat me Wi-Fi nga %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sr/strings.xml b/core/res/res/values-mcc310-mnc260-sr/strings.xml
deleted file mode 100644
index 92c6f35..0000000
--- a/core/res/res/values-mcc310-mnc260-sr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Региструјте се код мобилног оператера"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi позивање преко оператера %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sv/strings.xml b/core/res/res/values-mcc310-mnc260-sv/strings.xml
deleted file mode 100644
index 632a2ce..0000000
--- a/core/res/res/values-mcc310-mnc260-sv/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrera dig hos operatören"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-samtal"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sw/strings.xml b/core/res/res/values-mcc310-mnc260-sw/strings.xml
deleted file mode 100644
index eecf6d2..0000000
--- a/core/res/res/values-mcc310-mnc260-sw/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako asanidi huduma hii kwanza. Kisha uwashe tena upigaji simu kwa Wi-Fi kutoka kwenye Mipangilio."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Jisajili na mtoa huduma wako"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Upigaji Simu kwa Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ta/strings.xml b/core/res/res/values-mcc310-mnc260-ta/strings.xml
deleted file mode 100644
index 144bc95..0000000
--- a/core/res/res/values-mcc310-mnc260-ta/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"வைஃபை மூலம் அழைக்க மற்றும் செய்திகள் அனுப்ப, முதலில் மொபைல் நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும்."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"உங்கள் மொபைல் நிறுவனத்தில் பதிவுசெய்யவும்"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s வைஃபை அழைப்பு"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-te/strings.xml b/core/res/res/values-mcc310-mnc260-te/strings.xml
deleted file mode 100644
index ef94c4c..0000000
--- a/core/res/res/values-mcc310-mnc260-te/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fiలో కాల్‌లు చేయడం మరియు సందేశాలు పంపడం కోసం ముందుగా ఈ సేవను సెటప్ చేయడానికి మీ క్యారియర్‌ను అడగండి. ఆపై సెట్టింగ్‌ల నుండి మళ్లీ Wi-Fi కాలింగ్‌ను ఆన్ చేయండి."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"మీ క్యారియర్‌తో నమోదు చేయండి"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi కాలింగ్"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-th/strings.xml b/core/res/res/values-mcc310-mnc260-th/strings.xml
deleted file mode 100644
index dd026cc..0000000
--- a/core/res/res/values-mcc310-mnc260-th/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"ลงทะเบียนกับผู้ให้บริการ"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"กำลังเรียก Wi-Fi ของ %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-tl/strings.xml b/core/res/res/values-mcc310-mnc260-tl/strings.xml
deleted file mode 100644
index 5557835..0000000
--- a/core/res/res/values-mcc310-mnc260-tl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Upang tumawag at magpadala ng mga mensahe sa pamamagitan ng Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay muling i-on ang pagtawag sa Wi-Fi mula sa Mga Setting."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Magparehistro sa iyong carrier"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Pagtawag sa Pamamagitan ng Wi-Fi ng %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-tr/strings.xml b/core/res/res/values-mcc310-mnc260-tr/strings.xml
deleted file mode 100644
index 7cfd9c1..0000000
--- a/core/res/res/values-mcc310-mnc260-tr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Kablosuz ağ üzerinden telefon etmek ve ileti göndermek için ilk önce operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra tekrar Ayarlar\'dan Kablosuz çağrı özelliğini açın."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Operatörünüze kaydolun"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Kablosuz Çağrı"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-uk/strings.xml b/core/res/res/values-mcc310-mnc260-uk/strings.xml
deleted file mode 100644
index 0c21309..0000000
--- a/core/res/res/values-mcc310-mnc260-uk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спочатку попросіть свого оператора налаштувати цю послугу. Після цього ввімкніть дзвінки через Wi-Fi у налаштуваннях."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Зареєструйтеся в оператора"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Дзвінок через Wi-Fi від оператора %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ur/strings.xml b/core/res/res/values-mcc310-mnc260-ur/strings.xml
deleted file mode 100644
index 5e93fa7..0000000
--- a/core/res/res/values-mcc310-mnc260-ur/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"‏Wi-Fi سے کالز کرنے اور پیغامات بھیجنے کیلئے، پہلے اپنے کیریئر سے اس سروس کو ترتیب دینے کیلئے کہیں۔ پھر ترتیبات سے دوبارہ Wi-Fi کالنگ آن کریں۔"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"اپنے کیریئر کے ساتھ رجسٹر کریں"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"‏‎%s Wi-Fi کالنگ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-uz/strings.xml b/core/res/res/values-mcc310-mnc260-uz/strings.xml
deleted file mode 100644
index 19c8f2e..0000000
--- a/core/res/res/values-mcc310-mnc260-uz/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Mobil operatoringiz yordamida ro‘yxatdan o‘ting"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi qo‘ng‘iroqlar"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-vi/strings.xml b/core/res/res/values-mcc310-mnc260-vi/strings.xml
deleted file mode 100644
index 7b249c8..0000000
--- a/core/res/res/values-mcc310-mnc260-vi/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Đăng ký với nhà cung cấp dịch vụ của bạn"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Gọi điện qua Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc260-zh-rCN/strings.xml
deleted file mode 100644
index 7624e91..0000000
--- a/core/res/res/values-mcc310-mnc260-zh-rCN/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能。"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"向您的运营商注册"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s WLAN 通话功能"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc260-zh-rHK/strings.xml
deleted file mode 100644
index 1aea15a..0000000
--- a/core/res/res/values-mcc310-mnc260-zh-rHK/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"如要透過 Wi-Fi 撥打電話及傳送訊息,請先向您的流動網絡供應商要求設定此服務。然後再次在「設定」中開啟 Wi-Fi 通話。"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"向您的流動網絡供應商註冊"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi 通話"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc260-zh-rTW/strings.xml
deleted file mode 100644
index b0c7834..0000000
--- a/core/res/res/values-mcc310-mnc260-zh-rTW/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"如要透過 Wi-FI 撥打電話及傳送訊息,請先要求您的行動通訊業者開通這項服務,然後再到「設定」啟用 Wi-Fi 通話功能。"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"向您的行動通訊業者註冊"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi 通話"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zu/strings.xml b/core/res/res/values-mcc310-mnc260-zu/strings.xml
deleted file mode 100644
index cc32b1e..0000000
--- a/core/res/res/values-mcc310-mnc260-zu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-FI, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le divayisi. Bese uvula ukushaya kwe-Wi-FI futhi kusukela kuzilungiselelo."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Bhalisa ngenkampani yakho yenethiwekhi"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s ukushaya kwe-Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-af/strings.xml b/core/res/res/values-mcc310-mnc280-af/strings.xml
index a761881..b143077 100644
--- a/core/res/res/values-mcc310-mnc280-af/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-af/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM is nie opgestel nie MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM word nie toegelaat nie MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Foon nie toegelaat nie MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-am/strings.xml b/core/res/res/values-mcc310-mnc280-am/strings.xml
index 6750a71..ffbb1cc 100644
--- a/core/res/res/values-mcc310-mnc280-am/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-am/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"ሲም አልቀረበም MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"ሲም አይፈቀድም MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ስልክ አይፈቀድም MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ar/strings.xml b/core/res/res/values-mcc310-mnc280-ar/strings.xml
index a77d78e..c7c03a5 100644
--- a/core/res/res/values-mcc310-mnc280-ar/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ar/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"‏لم يتم توفير SIM ‏MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"‏غير مسموح باستخدام الهاتف MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-az/strings.xml b/core/res/res/values-mcc310-mnc280-az/strings.xml
index b7ee114..7fb788a 100644
--- a/core/res/res/values-mcc310-mnc280-az/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-az/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM MM#2 təmin etmir"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM MM#3 dəstəkləmir"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"MM#6 telefonu dəstəklənmir"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-bg/strings.xml b/core/res/res/values-mcc310-mnc280-bg/strings.xml
index a320898..7b0fac1 100644
--- a/core/res/res/values-mcc310-mnc280-bg/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-bg/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM картата не е обезпечена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM картата не е разрешена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Телефонът не е разрешен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-bn/strings.xml b/core/res/res/values-mcc310-mnc280-bn/strings.xml
new file mode 100644
index 0000000..ae0eaea
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc280-bn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"সিমের অনুমতি নেই MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ফোন অনুমোদিত নয় MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc280-ca/strings.xml b/core/res/res/values-mcc310-mnc280-ca/strings.xml
index 9a9e309..061c74c 100644
--- a/core/res/res/values-mcc310-mnc280-ca/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ca/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"La SIM no està proporcionada a MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"La SIM no és compatible a MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telèfon no compatible MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-cs/strings.xml b/core/res/res/values-mcc310-mnc280-cs/strings.xml
index 99e2bdb..422d205 100644
--- a/core/res/res/values-mcc310-mnc280-cs/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-cs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM karta není poskytována (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM karta není povolena (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefon není povolen (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-da/strings.xml b/core/res/res/values-mcc310-mnc280-da/strings.xml
index 4f444a1..180c523 100644
--- a/core/res/res/values-mcc310-mnc280-da/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-da/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kort leveres ikke MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kort er ikke tilladt MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefonen har ikke adgangstilladelse MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-de/strings.xml b/core/res/res/values-mcc310-mnc280-de/strings.xml
index 063c75b..0ca30c9 100644
--- a/core/res/res/values-mcc310-mnc280-de/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-de/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-Karte nicht eingerichtet MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-Karte nicht zulässig MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Smartphone nicht zulässig MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-el/strings.xml b/core/res/res/values-mcc310-mnc280-el/strings.xml
index 1161a7d..494e53b 100644
--- a/core/res/res/values-mcc310-mnc280-el/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-el/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Δεν παρέχεται κάρτα SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc280-en-rAU/strings.xml
index e9c9eba..c7e6a34 100644
--- a/core/res/res/values-mcc310-mnc280-en-rAU/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-en-rAU/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc280-en-rGB/strings.xml
index e9c9eba..c7e6a34 100644
--- a/core/res/res/values-mcc310-mnc280-en-rGB/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-en-rGB/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc280-en-rIN/strings.xml
index e9c9eba..c7e6a34 100644
--- a/core/res/res/values-mcc310-mnc280-en-rIN/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-en-rIN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc280-es-rUS/strings.xml
index 86ad4fd..00feb92 100644
--- a/core/res/res/values-mcc310-mnc280-es-rUS/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-es-rUS/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM no provista MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM no permitida MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-es/strings.xml b/core/res/res/values-mcc310-mnc280-es/strings.xml
index 2c7aa93..27945c8 100644
--- a/core/res/res/values-mcc310-mnc280-es/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-es/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM no proporcionada (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM no admitida (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-et/strings.xml b/core/res/res/values-mcc310-mnc280-et/strings.xml
index 7305d18..aa127fa 100644
--- a/core/res/res/values-mcc310-mnc280-et/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-et/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kaart on ette valmistamata MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kaart pole lubatud MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefon pole lubatud MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-eu/strings.xml b/core/res/res/values-mcc310-mnc280-eu/strings.xml
index 3c7296d..eec8d90 100644
--- a/core/res/res/values-mcc310-mnc280-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-eu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Ez dago SIM txartelik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Ez da onartzen SIM txartela MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-fa/strings.xml b/core/res/res/values-mcc310-mnc280-fa/strings.xml
index cd7ce85..219299c 100644
--- a/core/res/res/values-mcc310-mnc280-fa/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-fa/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"‏سیم‌کارت مجاز نیست MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-fi/strings.xml b/core/res/res/values-mcc310-mnc280-fi/strings.xml
index b2ccc50..a21613f 100644
--- a/core/res/res/values-mcc310-mnc280-fi/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-fi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kortti estetty MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc280-fr-rCA/strings.xml
index 29bb9a0..c5f913f 100644
--- a/core/res/res/values-mcc310-mnc280-fr-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-fr-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Carte SIM non configurée, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Carte SIM non autorisée, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-fr/strings.xml b/core/res/res/values-mcc310-mnc280-fr/strings.xml
index ce2f931..5b6ec9d 100644
--- a/core/res/res/values-mcc310-mnc280-fr/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-fr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Carte SIM non provisionnée MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Carte SIM non autorisée MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-gl/strings.xml b/core/res/res/values-mcc310-mnc280-gl/strings.xml
index e941341..0a05c51 100644
--- a/core/res/res/values-mcc310-mnc280-gl/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-gl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Non se admite a tarxeta SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Non se admite o teléfono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-gu/strings.xml b/core/res/res/values-mcc310-mnc280-gu/strings.xml
index a3763be..382ce7e 100644
--- a/core/res/res/values-mcc310-mnc280-gu/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-gu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIMને MM#2ની જોગવાઈ નથી"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"MM#6 ફોનની મંજૂરી નથી"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-hi/strings.xml b/core/res/res/values-mcc310-mnc280-hi/strings.xml
index ce866af..57218a3 100644
--- a/core/res/res/values-mcc310-mnc280-hi/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-hi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM काम नहीं कर रहा है MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM की अनुमति नहीं है MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"फ़ोन की इजाज़त नहीं है MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-hr/strings.xml b/core/res/res/values-mcc310-mnc280-hr/strings.xml
index 0021474..e6f9abd 100644
--- a/core/res/res/values-mcc310-mnc280-hr/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-hr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Ne pruža se usluga za SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM nije dopušten MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefon nije dopušten MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-hu/strings.xml b/core/res/res/values-mcc310-mnc280-hu/strings.xml
index 864faff..e673aea 100644
--- a/core/res/res/values-mcc310-mnc280-hu/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-hu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Nem engedélyezett SIM-kártya (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"A SIM-kártya nem engedélyezett (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-hy/strings.xml b/core/res/res/values-mcc310-mnc280-hy/strings.xml
index 6d027c3..b9f59e0 100644
--- a/core/res/res/values-mcc310-mnc280-hy/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-hy/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-in/strings.xml b/core/res/res/values-mcc310-mnc280-in/strings.xml
index a4f3486..23e60fa 100644
--- a/core/res/res/values-mcc310-mnc280-in/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-in/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM tidak di-provisioning MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM tidak diizinkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Ponsel tidak diizinkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-is/strings.xml b/core/res/res/values-mcc310-mnc280-is/strings.xml
index 30bbea4..56034d0 100644
--- a/core/res/res/values-mcc310-mnc280-is/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-is/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-korti ekki úthlutað MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kort ekki leyft MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Sími ekki leyfður MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-it/strings.xml b/core/res/res/values-mcc310-mnc280-it/strings.xml
index f83921b..b3d34cf 100644
--- a/core/res/res/values-mcc310-mnc280-it/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-it/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Scheda SIM non predisposta MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Scheda SIM non consentita MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefono non consentito MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-iw/strings.xml b/core/res/res/values-mcc310-mnc280-iw/strings.xml
index f3f87ff..4966a98 100644
--- a/core/res/res/values-mcc310-mnc280-iw/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-iw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"‏הטלפון לא מורשה MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ja/strings.xml b/core/res/res/values-mcc310-mnc280-ja/strings.xml
index a1cfd8b..463fc2e 100644
--- a/core/res/res/values-mcc310-mnc280-ja/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ja/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM には対応していません(MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM は許可されていません(MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"電話は許可されていません(MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ka/strings.xml b/core/res/res/values-mcc310-mnc280-ka/strings.xml
index 91c434f..942944f 100644
--- a/core/res/res/values-mcc310-mnc280-ka/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ka/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM ბარათი დაუშვებელია (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ტელეფონი დაუშვებელია MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-kk/strings.xml b/core/res/res/values-mcc310-mnc280-kk/strings.xml
index 44440d3..3559ee0 100644
--- a/core/res/res/values-mcc310-mnc280-kk/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-kk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM картасы қарастырылмаған MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM картасына рұқсат етілмеген MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Телефон пайдалануға болмайды MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-km/strings.xml b/core/res/res/values-mcc310-mnc280-km/strings.xml
index a016601..69777dc 100644
--- a/core/res/res/values-mcc310-mnc280-km/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-km/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-kn/strings.xml b/core/res/res/values-mcc310-mnc280-kn/strings.xml
index 1d9e353..3028b6f 100644
--- a/core/res/res/values-mcc310-mnc280-kn/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-kn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ಫೋನ್ MM#6 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ko/strings.xml b/core/res/res/values-mcc310-mnc280-ko/strings.xml
index e7bb9bb..d6ff696 100644
--- a/core/res/res/values-mcc310-mnc280-ko/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ko/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM이 프로비저닝되지 않음 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM이 허용되지 않음 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ky/strings.xml b/core/res/res/values-mcc310-mnc280-ky/strings.xml
index 4d364d8..9ecbcf2 100644
--- a/core/res/res/values-mcc310-mnc280-ky/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ky/strings.xml
@@ -20,6 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM картаны колдонууга тыюу салынган MM#3"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM карта таанылган жок (MM#2)"</string>
+    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Телефонду колдонууга тыюу салынган MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-lo/strings.xml b/core/res/res/values-mcc310-mnc280-lo/strings.xml
index 9415089..f72ece1 100644
--- a/core/res/res/values-mcc310-mnc280-lo/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-lo/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-lt/strings.xml b/core/res/res/values-mcc310-mnc280-lt/strings.xml
index b5ff1b9..80257df 100644
--- a/core/res/res/values-mcc310-mnc280-lt/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-lt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM kortelė neteikiama (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM kortelė neleidžiama (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefonas neleidžiamas (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-lv/strings.xml b/core/res/res/values-mcc310-mnc280-lv/strings.xml
index 4034bc1..f6bb072 100644
--- a/core/res/res/values-mcc310-mnc280-lv/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-lv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM karte netiek nodrošināta: MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM karti nav atļauts izmantot: MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Tālruni nav atļauts izmantot: MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-mk/strings.xml b/core/res/res/values-mcc310-mnc280-mk/strings.xml
index a93cb79..f9a7d91 100644
--- a/core/res/res/values-mcc310-mnc280-mk/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-mk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Не е обезбедена SIM-картичка, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Не е дозволена SIM-картичка, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Телефонот не е дозволен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ml/strings.xml b/core/res/res/values-mcc310-mnc280-ml/strings.xml
index d14743b8..9f8eee6 100644
--- a/core/res/res/values-mcc310-mnc280-ml/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ml/strings.xml
@@ -20,6 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
+    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ഫോൺ അനുവദനീയമല്ല MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-mn/strings.xml b/core/res/res/values-mcc310-mnc280-mn/strings.xml
index 54b8190..2b9d814 100644
--- a/core/res/res/values-mcc310-mnc280-mn/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-mn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Утсыг зөвшөөрөөгүй MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-mr/strings.xml b/core/res/res/values-mcc310-mnc280-mr/strings.xml
index cb343cb..fbf98fb 100644
--- a/core/res/res/values-mcc310-mnc280-mr/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-mr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"फोन MM#6 ला अनुमती देत नाही"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ms/strings.xml b/core/res/res/values-mcc310-mnc280-ms/strings.xml
index 27da747..d140049 100644
--- a/core/res/res/values-mcc310-mnc280-ms/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ms/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM tidak diperuntukkan MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM tidak dibenarkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefon tidak dibenarkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-my/strings.xml b/core/res/res/values-mcc310-mnc280-my/strings.xml
index 40cdc63..c4ba718 100644
--- a/core/res/res/values-mcc310-mnc280-my/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-my/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-nb/strings.xml b/core/res/res/values-mcc310-mnc280-nb/strings.xml
index 7666c3e..c9eece5 100644
--- a/core/res/res/values-mcc310-mnc280-nb/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-nb/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kortet er ikke klargjort, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kortet er ikke tillatt, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefonen er ikke tillatt, MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ne/strings.xml b/core/res/res/values-mcc310-mnc280-ne/strings.xml
index 8735605..2108eda 100644
--- a/core/res/res/values-mcc310-mnc280-ne/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ne/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM को प्रावधान छैन MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM लाई अनुमति छैन MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"फोनलाई अनुमति छैन MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-nl/strings.xml b/core/res/res/values-mcc310-mnc280-nl/strings.xml
index 7d7bfa7..f6c0e0b 100644
--- a/core/res/res/values-mcc310-mnc280-nl/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-nl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Simkaart niet geregistreerd MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Simkaart niet toegestaan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefoon niet toegestaan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-pa/strings.xml b/core/res/res/values-mcc310-mnc280-pa/strings.xml
new file mode 100644
index 0000000..3ac0638
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc280-pa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ਫ਼ੋਨ ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc280-pl/strings.xml b/core/res/res/values-mcc310-mnc280-pl/strings.xml
index 52410f4..ee33cf6 100644
--- a/core/res/res/values-mcc310-mnc280-pl/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-pl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"MM#2 – karta SIM nieobsługiwana"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"MM#3 – niedozwolona karta SIM"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"MM#6 – telefon niedozwolony"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc280-pt-rBR/strings.xml
index 03d0efb..f7fb684 100644
--- a/core/res/res/values-mcc310-mnc280-pt-rBR/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-pt-rBR/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc280-pt-rPT/strings.xml
index 03d0efb..1a64f5c 100644
--- a/core/res/res/values-mcc310-mnc280-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-pt-rPT/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telemóvel não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-pt/strings.xml b/core/res/res/values-mcc310-mnc280-pt/strings.xml
index 03d0efb..f7fb684 100644
--- a/core/res/res/values-mcc310-mnc280-pt/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-pt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ro/strings.xml b/core/res/res/values-mcc310-mnc280-ro/strings.xml
index d60ea0c..5ed83b3 100644
--- a/core/res/res/values-mcc310-mnc280-ro/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ro/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Cardul SIM nu este activat MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Cardul SIM nu este permis MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefonul nu este permis MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ru/strings.xml b/core/res/res/values-mcc310-mnc280-ru/strings.xml
index 308c353..c9e22bb 100644
--- a/core/res/res/values-mcc310-mnc280-ru/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ru/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-карта не активирована (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Использование SIM-карты запрещено (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Звонки запрещены (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-si/strings.xml b/core/res/res/values-mcc310-mnc280-si/strings.xml
index 5bd6d1f..fa5b3c0 100644
--- a/core/res/res/values-mcc310-mnc280-si/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-si/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM MM#3 ඉඩ නොදේ"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-sk/strings.xml b/core/res/res/values-mcc310-mnc280-sk/strings.xml
index 4098ac7..b116331 100644
--- a/core/res/res/values-mcc310-mnc280-sk/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-sk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM karta nie je k dispozícii – MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM karta je zakázaná – MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefón nie je povolený (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-sl/strings.xml b/core/res/res/values-mcc310-mnc280-sl/strings.xml
index faa78ad..1a75b94 100644
--- a/core/res/res/values-mcc310-mnc280-sl/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-sl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Kartica SIM ni omogočena za uporabo MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Kartica SIM ni dovoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefon ni dovoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-sq/strings.xml b/core/res/res/values-mcc310-mnc280-sq/strings.xml
index 48fba2d..54072e2 100644
--- a/core/res/res/values-mcc310-mnc280-sq/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-sq/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Karta SIM nuk është dhënë MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Karta SIM nuk lejohet MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefoni nuk lejohet MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-sr/strings.xml b/core/res/res/values-mcc310-mnc280-sr/strings.xml
index 30c9df3..f4591b6 100644
--- a/core/res/res/values-mcc310-mnc280-sr/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-sr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM картица није подешена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Телефон није дозвољен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-sv/strings.xml b/core/res/res/values-mcc310-mnc280-sv/strings.xml
index cb5b9f32..294d762 100644
--- a/core/res/res/values-mcc310-mnc280-sv/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-sv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kort tillhandahålls inte MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kort tillåts inte MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Mobil tillåts inte MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-sw/strings.xml b/core/res/res/values-mcc310-mnc280-sw/strings.xml
index 15a1a36..4912340 100644
--- a/core/res/res/values-mcc310-mnc280-sw/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-sw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM haitumiki MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM hairuhusiwi MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Simu hairuhusiwi MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ta/strings.xml b/core/res/res/values-mcc310-mnc280-ta/strings.xml
index c3911d4..35cc649 100644
--- a/core/res/res/values-mcc310-mnc280-ta/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ta/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"சிம் அமைக்கப்படவில்லை MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ஃபோன் அனுமதிக்கப்படவில்லை MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-te/strings.xml b/core/res/res/values-mcc310-mnc280-te/strings.xml
new file mode 100644
index 0000000..75d5b73
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc280-te/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM MM#2ని సక్రియం చేయలేదు"</string>
+    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM MM#3ని అనుమతించలేదు"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc280-th/strings.xml b/core/res/res/values-mcc310-mnc280-th/strings.xml
index 9810ba6..2312bb4 100644
--- a/core/res/res/values-mcc310-mnc280-th/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-th/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"ไม่มีการจัดสรรซิม MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-tl/strings.xml b/core/res/res/values-mcc310-mnc280-tl/strings.xml
index 600ad05..8c05e82 100644
--- a/core/res/res/values-mcc310-mnc280-tl/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-tl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Hindi na-provision ang SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Hindi pinapahintulutan ang SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Hindi pinapahintulutan ang telepono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-tr/strings.xml b/core/res/res/values-mcc310-mnc280-tr/strings.xml
index ea90bdb..4e9cc2c 100644
--- a/core/res/res/values-mcc310-mnc280-tr/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-tr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM MM#3\'e izin vermiyor"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Telefona izin verilmiyor MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-uk/strings.xml b/core/res/res/values-mcc310-mnc280-uk/strings.xml
index 68a34fd..aa500d6 100644
--- a/core/res/res/values-mcc310-mnc280-uk/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-uk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-карту не надано (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-карта заборонена (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Телефон заборонено (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-ur/strings.xml b/core/res/res/values-mcc310-mnc280-ur/strings.xml
index d61a5dc..b0d842a 100644
--- a/core/res/res/values-mcc310-mnc280-ur/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-ur/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"‏SIM کی اجازت نہیں ہے MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"‏فون کی اجازت نہیں ہے MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-uz/strings.xml b/core/res/res/values-mcc310-mnc280-uz/strings.xml
index 324d364..9110cfc 100644
--- a/core/res/res/values-mcc310-mnc280-uz/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-uz/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Chaqiruvlar taqiqlangan (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-vi/strings.xml b/core/res/res/values-mcc310-mnc280-vi/strings.xml
index 6806e39..444f882 100644
--- a/core/res/res/values-mcc310-mnc280-vi/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-vi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM không được cấp phép MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM không được phép MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Không cho phép điện thoại MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc280-zh-rCN/strings.xml
index add3f920..aa85594 100644
--- a/core/res/res/values-mcc310-mnc280-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-zh-rCN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"未配置的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"不被允许的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"不受允许的手机 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc280-zh-rHK/strings.xml
index 856297c..c986d5d 100644
--- a/core/res/res/values-mcc310-mnc280-zh-rHK/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-zh-rHK/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc280-zh-rTW/strings.xml
index 856297c..720d097 100644
--- a/core/res/res/values-mcc310-mnc280-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-zh-rTW/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"不支援的手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-zu/strings.xml b/core/res/res/values-mcc310-mnc280-zu/strings.xml
index 6c5147c..a198302 100644
--- a/core/res/res/values-mcc310-mnc280-zu/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-zu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"I-SIM ayinikezelwe MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="5562215652599183258">"I-SIM ayivunyelwe MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="822496463303720579">"Ifoni ayivunyelwe MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280/strings.xml b/core/res/res/values-mcc310-mnc280/strings.xml
index a3fea29..6a404d5 100644
--- a/core/res/res/values-mcc310-mnc280/strings.xml
+++ b/core/res/res/values-mcc310-mnc280/strings.xml
@@ -20,4 +20,5 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string>
     <string name="mmcc_illegal_ms">SIM not allowed MM#3</string>
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc380-bn/strings.xml b/core/res/res/values-mcc310-mnc380-bn/strings.xml
new file mode 100644
index 0000000..38ba93b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc380-bn/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"সিমের অনুমতি নেই MM#3"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc380-ky/strings.xml b/core/res/res/values-mcc310-mnc380-ky/strings.xml
index eb81f69..de6916f 100644
--- a/core/res/res/values-mcc310-mnc380-ky/strings.xml
+++ b/core/res/res/values-mcc310-mnc380-ky/strings.xml
@@ -20,6 +20,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM картаны колдонууга тыюу салынган MM#3"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM карта таанылган жок (MM#2)"</string>
+    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc380-ml/strings.xml b/core/res/res/values-mcc310-mnc380-ml/strings.xml
index a0a84d9..f986a99 100644
--- a/core/res/res/values-mcc310-mnc380-ml/strings.xml
+++ b/core/res/res/values-mcc310-mnc380-ml/strings.xml
@@ -20,6 +20,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
+    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc380-pa/strings.xml b/core/res/res/values-mcc310-mnc380-pa/strings.xml
new file mode 100644
index 0000000..342c08e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc380-pa/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc380-te/strings.xml b/core/res/res/values-mcc310-mnc380-te/strings.xml
new file mode 100644
index 0000000..cfc800e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc380-te/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM MM#2ని సక్రియం చేయలేదు"</string>
+    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM MM#3ని అనుమతించలేదు"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc410-af/strings.xml b/core/res/res/values-mcc310-mnc410-af/strings.xml
index 81688f1..7aea163 100644
--- a/core/res/res/values-mcc310-mnc410-af/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-af/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM is nie opgestel nie MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM word nie toegelaat nie MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Foon nie toegelaat nie MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-am/strings.xml b/core/res/res/values-mcc310-mnc410-am/strings.xml
index 176a628d..b5f5356 100644
--- a/core/res/res/values-mcc310-mnc410-am/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-am/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"ሲም አልቀረበም MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"ሲም አይፈቀድም MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ስልክ አይፈቀድም MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ar/strings.xml b/core/res/res/values-mcc310-mnc410-ar/strings.xml
index 884e18e..829ea43 100644
--- a/core/res/res/values-mcc310-mnc410-ar/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ar/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"‏لم يتم توفير SIM ‏MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"‏غير مسموح باستخدام الهاتف MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-az/strings.xml b/core/res/res/values-mcc310-mnc410-az/strings.xml
index 178451c..497f37a 100644
--- a/core/res/res/values-mcc310-mnc410-az/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-az/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM MM#2 təmin etmir"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM MM#3 dəstəkləmir"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"MM#6 telefonu dəstəklənmir"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-bg/strings.xml b/core/res/res/values-mcc310-mnc410-bg/strings.xml
index fc6f3e5..9ea8ddf 100644
--- a/core/res/res/values-mcc310-mnc410-bg/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-bg/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM картата не е обезпечена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM картата не е разрешена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Телефонът не е разрешен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-bn/strings.xml b/core/res/res/values-mcc310-mnc410-bn/strings.xml
new file mode 100644
index 0000000..8fe788b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc410-bn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"সিমের অনুমতি নেই MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ফোন অনুমোদিত নয় MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc410-ca/strings.xml b/core/res/res/values-mcc310-mnc410-ca/strings.xml
index 19ab945b..2827e20 100644
--- a/core/res/res/values-mcc310-mnc410-ca/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ca/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"La SIM no està proporcionada a MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"La SIM no és compatible a MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telèfon no compatible MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-cs/strings.xml b/core/res/res/values-mcc310-mnc410-cs/strings.xml
index 3e36325..22610b0 100644
--- a/core/res/res/values-mcc310-mnc410-cs/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-cs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM karta není poskytována (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM karta není povolena (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefon není povolen (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-da/strings.xml b/core/res/res/values-mcc310-mnc410-da/strings.xml
index e99ab57..38c47b3 100644
--- a/core/res/res/values-mcc310-mnc410-da/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-da/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kort leveres ikke MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kort er ikke tilladt MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefonen har ikke adgangstilladelse MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-de/strings.xml b/core/res/res/values-mcc310-mnc410-de/strings.xml
index c5f64f4a..ed8cd5d 100644
--- a/core/res/res/values-mcc310-mnc410-de/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-de/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-Karte nicht eingerichtet MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-Karte nicht zulässig MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Smartphone nicht zulässig MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-el/strings.xml b/core/res/res/values-mcc310-mnc410-el/strings.xml
index 128d1bf..9c9bafa 100644
--- a/core/res/res/values-mcc310-mnc410-el/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-el/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Δεν παρέχεται κάρτα SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc410-en-rAU/strings.xml
index eb56351..5258201 100644
--- a/core/res/res/values-mcc310-mnc410-en-rAU/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-en-rAU/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc410-en-rGB/strings.xml
index eb56351..5258201 100644
--- a/core/res/res/values-mcc310-mnc410-en-rGB/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-en-rGB/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc410-en-rIN/strings.xml
index eb56351..5258201 100644
--- a/core/res/res/values-mcc310-mnc410-en-rIN/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-en-rIN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc410-es-rUS/strings.xml
index 85b0344..d9748af 100644
--- a/core/res/res/values-mcc310-mnc410-es-rUS/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-es-rUS/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM no provista MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM no permitida MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-es/strings.xml b/core/res/res/values-mcc310-mnc410-es/strings.xml
index 248069e..0459bbb 100644
--- a/core/res/res/values-mcc310-mnc410-es/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-es/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM no proporcionada (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM no admitida (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-et/strings.xml b/core/res/res/values-mcc310-mnc410-et/strings.xml
index 6ef7802..02f60b3 100644
--- a/core/res/res/values-mcc310-mnc410-et/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-et/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kaart on ette valmistamata MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kaart pole lubatud MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefon pole lubatud MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-eu/strings.xml b/core/res/res/values-mcc310-mnc410-eu/strings.xml
index 966511b..ef42cb9 100644
--- a/core/res/res/values-mcc310-mnc410-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-eu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Ez dago SIM txartelik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Ez da onartzen SIM txartela MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-fa/strings.xml b/core/res/res/values-mcc310-mnc410-fa/strings.xml
index 82f6272..e9dcc07 100644
--- a/core/res/res/values-mcc310-mnc410-fa/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-fa/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"‏سیم‌کارت مجاز نیست MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-fi/strings.xml b/core/res/res/values-mcc310-mnc410-fi/strings.xml
index c5a4ef6..38485c3 100644
--- a/core/res/res/values-mcc310-mnc410-fi/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-fi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kortti estetty MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc410-fr-rCA/strings.xml
index cec2491..fe8c960 100644
--- a/core/res/res/values-mcc310-mnc410-fr-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-fr-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Carte SIM non configurée, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Carte SIM non autorisée, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-fr/strings.xml b/core/res/res/values-mcc310-mnc410-fr/strings.xml
index f715e71..c0fb381 100644
--- a/core/res/res/values-mcc310-mnc410-fr/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-fr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Carte SIM non provisionnée MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Carte SIM non autorisée MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-gl/strings.xml b/core/res/res/values-mcc310-mnc410-gl/strings.xml
index c3aba8e..56ce287 100644
--- a/core/res/res/values-mcc310-mnc410-gl/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-gl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Non se admite a tarxeta SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Non se admite o teléfono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-gu/strings.xml b/core/res/res/values-mcc310-mnc410-gu/strings.xml
index 26898f4..0637f9e 100644
--- a/core/res/res/values-mcc310-mnc410-gu/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-gu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIMને MM#2ની જોગવાઈ નથી"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"MM#6 ફોનની મંજૂરી નથી"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-hi/strings.xml b/core/res/res/values-mcc310-mnc410-hi/strings.xml
index a01845a..3b574c3 100644
--- a/core/res/res/values-mcc310-mnc410-hi/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-hi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM काम नहीं कर रहा है MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM की अनुमति नहीं है MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"फ़ोन की इजाज़त नहीं है MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-hr/strings.xml b/core/res/res/values-mcc310-mnc410-hr/strings.xml
index 47062c4..0ee4ae6 100644
--- a/core/res/res/values-mcc310-mnc410-hr/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-hr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Ne pruža se usluga za SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM nije dopušten MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefon nije dopušten MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-hu/strings.xml b/core/res/res/values-mcc310-mnc410-hu/strings.xml
index 194d865..8abc27d 100644
--- a/core/res/res/values-mcc310-mnc410-hu/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-hu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Nem engedélyezett SIM-kártya (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"A SIM-kártya nem engedélyezett (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-hy/strings.xml b/core/res/res/values-mcc310-mnc410-hy/strings.xml
index 85129cc..79bc531 100644
--- a/core/res/res/values-mcc310-mnc410-hy/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-hy/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-in/strings.xml b/core/res/res/values-mcc310-mnc410-in/strings.xml
index c065221..5750563 100644
--- a/core/res/res/values-mcc310-mnc410-in/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-in/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM tidak di-provisioning MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM tidak diizinkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Ponsel tidak diizinkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-is/strings.xml b/core/res/res/values-mcc310-mnc410-is/strings.xml
index a40a643..a786285 100644
--- a/core/res/res/values-mcc310-mnc410-is/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-is/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-korti ekki úthlutað MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kort ekki leyft MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Sími ekki leyfður MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-it/strings.xml b/core/res/res/values-mcc310-mnc410-it/strings.xml
index ab5c731..135d39d 100644
--- a/core/res/res/values-mcc310-mnc410-it/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-it/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Scheda SIM non predisposta MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Scheda SIM non consentita MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefono non consentito MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-iw/strings.xml b/core/res/res/values-mcc310-mnc410-iw/strings.xml
index b675f64..8e505a9 100644
--- a/core/res/res/values-mcc310-mnc410-iw/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-iw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"‏הטלפון לא מורשה MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ja/strings.xml b/core/res/res/values-mcc310-mnc410-ja/strings.xml
index 1961a75b..e0e98e3 100644
--- a/core/res/res/values-mcc310-mnc410-ja/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ja/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM には対応していません(MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM は許可されていません(MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"電話は許可されていません(MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ka/strings.xml b/core/res/res/values-mcc310-mnc410-ka/strings.xml
index 5216e8f..63af51c 100644
--- a/core/res/res/values-mcc310-mnc410-ka/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ka/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM ბარათი დაუშვებელია (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ტელეფონი დაუშვებელია MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-kk/strings.xml b/core/res/res/values-mcc310-mnc410-kk/strings.xml
index 137c73a..5a52be2 100644
--- a/core/res/res/values-mcc310-mnc410-kk/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-kk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM картасы қарастырылмаған MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM картасына рұқсат етілмеген MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Телефон пайдалануға болмайды MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-km/strings.xml b/core/res/res/values-mcc310-mnc410-km/strings.xml
index 94babe1..809ffd1 100644
--- a/core/res/res/values-mcc310-mnc410-km/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-km/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-kn/strings.xml b/core/res/res/values-mcc310-mnc410-kn/strings.xml
index b003dcc..40d05d4 100644
--- a/core/res/res/values-mcc310-mnc410-kn/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-kn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ಫೋನ್ MM#6 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ko/strings.xml b/core/res/res/values-mcc310-mnc410-ko/strings.xml
index 7824d1e6..dc1a9a5 100644
--- a/core/res/res/values-mcc310-mnc410-ko/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ko/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM이 프로비저닝되지 않음 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM이 허용되지 않음 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ky/strings.xml b/core/res/res/values-mcc310-mnc410-ky/strings.xml
index 66cc98e..05314ed 100644
--- a/core/res/res/values-mcc310-mnc410-ky/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ky/strings.xml
@@ -20,6 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM картаны колдонууга тыюу салынган MM#3"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM карта таанылган жок (MM#2)"</string>
+    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Телефонду колдонууга тыюу салынган MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-lo/strings.xml b/core/res/res/values-mcc310-mnc410-lo/strings.xml
index 9684e7a7..9e095ba 100644
--- a/core/res/res/values-mcc310-mnc410-lo/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-lo/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-lt/strings.xml b/core/res/res/values-mcc310-mnc410-lt/strings.xml
index c4a646a..72b9a08 100644
--- a/core/res/res/values-mcc310-mnc410-lt/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-lt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM kortelė neteikiama (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM kortelė neleidžiama (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefonas neleidžiamas (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-lv/strings.xml b/core/res/res/values-mcc310-mnc410-lv/strings.xml
index e95d62b..e3c04f8 100644
--- a/core/res/res/values-mcc310-mnc410-lv/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-lv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM karte netiek nodrošināta: MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM karti nav atļauts izmantot: MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Tālruni nav atļauts izmantot: MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-mk/strings.xml b/core/res/res/values-mcc310-mnc410-mk/strings.xml
index 76bba96..d34261d 100644
--- a/core/res/res/values-mcc310-mnc410-mk/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-mk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Не е обезбедена SIM-картичка, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Не е дозволена SIM-картичка, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Телефонот не е дозволен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ml/strings.xml b/core/res/res/values-mcc310-mnc410-ml/strings.xml
index 03a4b7a..474814d 100644
--- a/core/res/res/values-mcc310-mnc410-ml/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ml/strings.xml
@@ -20,6 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
+    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ഫോൺ അനുവദനീയമല്ല MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-mn/strings.xml b/core/res/res/values-mcc310-mnc410-mn/strings.xml
index 2667aab..70cc206 100644
--- a/core/res/res/values-mcc310-mnc410-mn/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-mn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Утсыг зөвшөөрөөгүй MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-mr/strings.xml b/core/res/res/values-mcc310-mnc410-mr/strings.xml
index e7b0644..db40711 100644
--- a/core/res/res/values-mcc310-mnc410-mr/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-mr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"फोन MM#6 ला अनुमती देत नाही"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ms/strings.xml b/core/res/res/values-mcc310-mnc410-ms/strings.xml
index 85b8621..b896e67 100644
--- a/core/res/res/values-mcc310-mnc410-ms/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ms/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM tidak diperuntukkan MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM tidak dibenarkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefon tidak dibenarkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-my/strings.xml b/core/res/res/values-mcc310-mnc410-my/strings.xml
index faa80ec..07a2967 100644
--- a/core/res/res/values-mcc310-mnc410-my/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-my/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-nb/strings.xml b/core/res/res/values-mcc310-mnc410-nb/strings.xml
index 79be7af..4f6e125 100644
--- a/core/res/res/values-mcc310-mnc410-nb/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-nb/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kortet er ikke klargjort, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kortet er ikke tillatt, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefonen er ikke tillatt, MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ne/strings.xml b/core/res/res/values-mcc310-mnc410-ne/strings.xml
index e270c7c..65adf0b 100644
--- a/core/res/res/values-mcc310-mnc410-ne/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ne/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM को प्रावधान छैन MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM लाई अनुमति छैन MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"फोनलाई अनुमति छैन MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-nl/strings.xml b/core/res/res/values-mcc310-mnc410-nl/strings.xml
index 2995beb..7da7fab 100644
--- a/core/res/res/values-mcc310-mnc410-nl/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-nl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Simkaart niet geregistreerd MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Simkaart niet toegestaan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefoon niet toegestaan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-pa/strings.xml b/core/res/res/values-mcc310-mnc410-pa/strings.xml
new file mode 100644
index 0000000..dd44bed
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc410-pa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ਫ਼ੋਨ ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc410-pl/strings.xml b/core/res/res/values-mcc310-mnc410-pl/strings.xml
index 8677ad6..f74650f 100644
--- a/core/res/res/values-mcc310-mnc410-pl/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-pl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"MM#2 – karta SIM nieobsługiwana"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"MM#3 – niedozwolona karta SIM"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"MM#6 – telefon niedozwolony"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc410-pt-rBR/strings.xml
index 4f41e5e..f6bfc67 100644
--- a/core/res/res/values-mcc310-mnc410-pt-rBR/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-pt-rBR/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc410-pt-rPT/strings.xml
index 4f41e5e..5457416 100644
--- a/core/res/res/values-mcc310-mnc410-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-pt-rPT/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telemóvel não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-pt/strings.xml b/core/res/res/values-mcc310-mnc410-pt/strings.xml
index 4f41e5e..f6bfc67 100644
--- a/core/res/res/values-mcc310-mnc410-pt/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-pt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ro/strings.xml b/core/res/res/values-mcc310-mnc410-ro/strings.xml
index fea0609..0fc9400 100644
--- a/core/res/res/values-mcc310-mnc410-ro/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ro/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Cardul SIM nu este activat MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Cardul SIM nu este permis MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefonul nu este permis MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ru/strings.xml b/core/res/res/values-mcc310-mnc410-ru/strings.xml
index a00e59c..8702e83 100644
--- a/core/res/res/values-mcc310-mnc410-ru/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ru/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-карта не активирована (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Использование SIM-карты запрещено (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Звонки запрещены (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-si/strings.xml b/core/res/res/values-mcc310-mnc410-si/strings.xml
index 8f66f3d..cddc168 100644
--- a/core/res/res/values-mcc310-mnc410-si/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-si/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM MM#3 ඉඩ නොදේ"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-sk/strings.xml b/core/res/res/values-mcc310-mnc410-sk/strings.xml
index e4d4bc6..354b138 100644
--- a/core/res/res/values-mcc310-mnc410-sk/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-sk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM karta nie je k dispozícii – MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM karta je zakázaná – MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefón nie je povolený (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-sl/strings.xml b/core/res/res/values-mcc310-mnc410-sl/strings.xml
index 2d03b04..d65d619 100644
--- a/core/res/res/values-mcc310-mnc410-sl/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-sl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Kartica SIM ni omogočena za uporabo MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Kartica SIM ni dovoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefon ni dovoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-sq/strings.xml b/core/res/res/values-mcc310-mnc410-sq/strings.xml
index 51626d7..95ec705 100644
--- a/core/res/res/values-mcc310-mnc410-sq/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-sq/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Karta SIM nuk është dhënë MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Karta SIM nuk lejohet MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefoni nuk lejohet MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-sr/strings.xml b/core/res/res/values-mcc310-mnc410-sr/strings.xml
index b4a9006..66fe4e7 100644
--- a/core/res/res/values-mcc310-mnc410-sr/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-sr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM картица није подешена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Телефон није дозвољен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-sv/strings.xml b/core/res/res/values-mcc310-mnc410-sv/strings.xml
index c270b04..77e0829 100644
--- a/core/res/res/values-mcc310-mnc410-sv/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-sv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kort tillhandahålls inte MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kort tillåts inte MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Mobil tillåts inte MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-sw/strings.xml b/core/res/res/values-mcc310-mnc410-sw/strings.xml
index a6e6018..50c2e74 100644
--- a/core/res/res/values-mcc310-mnc410-sw/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-sw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM haitumiki MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM hairuhusiwi MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Simu hairuhusiwi MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ta/strings.xml b/core/res/res/values-mcc310-mnc410-ta/strings.xml
index 4ac46ce..61f922d 100644
--- a/core/res/res/values-mcc310-mnc410-ta/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ta/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"சிம் அமைக்கப்படவில்லை MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ஃபோன் அனுமதிக்கப்படவில்லை MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-te/strings.xml b/core/res/res/values-mcc310-mnc410-te/strings.xml
new file mode 100644
index 0000000..133b332
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc410-te/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM MM#2ని సక్రియం చేయలేదు"</string>
+    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM MM#3ని అనుమతించలేదు"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc410-th/strings.xml b/core/res/res/values-mcc310-mnc410-th/strings.xml
index cf51029..0b728bf 100644
--- a/core/res/res/values-mcc310-mnc410-th/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-th/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"ไม่มีการจัดสรรซิม MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-tl/strings.xml b/core/res/res/values-mcc310-mnc410-tl/strings.xml
index b2aa68a..3bf972d 100644
--- a/core/res/res/values-mcc310-mnc410-tl/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-tl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Hindi na-provision ang SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Hindi pinapahintulutan ang SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Hindi pinapahintulutan ang telepono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-tr/strings.xml b/core/res/res/values-mcc310-mnc410-tr/strings.xml
index 9e5c38e..34ce123 100644
--- a/core/res/res/values-mcc310-mnc410-tr/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-tr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM MM#3\'e izin vermiyor"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Telefona izin verilmiyor MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-uk/strings.xml b/core/res/res/values-mcc310-mnc410-uk/strings.xml
index 5d74f80..9d8ccb2 100644
--- a/core/res/res/values-mcc310-mnc410-uk/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-uk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-карту не надано (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-карта заборонена (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Телефон заборонено (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-ur/strings.xml b/core/res/res/values-mcc310-mnc410-ur/strings.xml
index 8cf16e4..0a0032c 100644
--- a/core/res/res/values-mcc310-mnc410-ur/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-ur/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"‏SIM کی اجازت نہیں ہے MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"‏فون کی اجازت نہیں ہے MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-uz/strings.xml b/core/res/res/values-mcc310-mnc410-uz/strings.xml
index 4618525..fdfad9b 100644
--- a/core/res/res/values-mcc310-mnc410-uz/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-uz/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Chaqiruvlar taqiqlangan (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-vi/strings.xml b/core/res/res/values-mcc310-mnc410-vi/strings.xml
index e6fc334..77cff43 100644
--- a/core/res/res/values-mcc310-mnc410-vi/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-vi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM không được cấp phép MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM không được phép MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Không cho phép điện thoại MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc410-zh-rCN/strings.xml
index a00316a..ec8d371 100644
--- a/core/res/res/values-mcc310-mnc410-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-zh-rCN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"未配置的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"不被允许的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"不受允许的手机 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc410-zh-rHK/strings.xml
index 66a622e..7f54efb 100644
--- a/core/res/res/values-mcc310-mnc410-zh-rHK/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-zh-rHK/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc410-zh-rTW/strings.xml
index 66a622e..a0aaaa5 100644
--- a/core/res/res/values-mcc310-mnc410-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-zh-rTW/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"不支援的手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-zu/strings.xml b/core/res/res/values-mcc310-mnc410-zu/strings.xml
index a52049f..67cc1ac 100644
--- a/core/res/res/values-mcc310-mnc410-zu/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-zu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"I-SIM ayinikezelwe MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="1593063035884873292">"I-SIM ayivunyelwe MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4477688981805467729">"Ifoni ayivunyelwe MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410/strings.xml b/core/res/res/values-mcc310-mnc410/strings.xml
index a3fea29..6a404d5 100644
--- a/core/res/res/values-mcc310-mnc410/strings.xml
+++ b/core/res/res/values-mcc310-mnc410/strings.xml
@@ -20,4 +20,5 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string>
     <string name="mmcc_illegal_ms">SIM not allowed MM#3</string>
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-af/strings.xml b/core/res/res/values-mcc310-mnc560-af/strings.xml
index ecbb954..87f698c 100644
--- a/core/res/res/values-mcc310-mnc560-af/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-af/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM is nie opgestel nie MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM word nie toegelaat nie MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Foon nie toegelaat nie MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-am/strings.xml b/core/res/res/values-mcc310-mnc560-am/strings.xml
index 297c059..c1f8350 100644
--- a/core/res/res/values-mcc310-mnc560-am/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-am/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"ሲም አልቀረበም MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"ሲም አይፈቀድም MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ስልክ አይፈቀድም MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ar/strings.xml b/core/res/res/values-mcc310-mnc560-ar/strings.xml
index 12a06fa..d5c684f 100644
--- a/core/res/res/values-mcc310-mnc560-ar/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ar/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"‏لم يتم توفير SIM ‏MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"‏غير مسموح باستخدام الهاتف MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-az/strings.xml b/core/res/res/values-mcc310-mnc560-az/strings.xml
index 9acc2c1..1edff5e 100644
--- a/core/res/res/values-mcc310-mnc560-az/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-az/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM MM#2 təmin etmir"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM MM#3 dəstəkləmir"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"MM#6 telefonu dəstəklənmir"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-bg/strings.xml b/core/res/res/values-mcc310-mnc560-bg/strings.xml
index 49c2d2f..98c362d 100644
--- a/core/res/res/values-mcc310-mnc560-bg/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-bg/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM картата не е обезпечена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM картата не е разрешена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Телефонът не е разрешен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-bn/strings.xml b/core/res/res/values-mcc310-mnc560-bn/strings.xml
new file mode 100644
index 0000000..989da8d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc560-bn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"সিমের অনুমতি নেই MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ফোন অনুমোদিত নয় MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc560-ca/strings.xml b/core/res/res/values-mcc310-mnc560-ca/strings.xml
index 1eac589..00fc4ed 100644
--- a/core/res/res/values-mcc310-mnc560-ca/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ca/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"La SIM no està proporcionada a MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"La SIM no és compatible a MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telèfon no compatible MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-cs/strings.xml b/core/res/res/values-mcc310-mnc560-cs/strings.xml
index 4701f99..9a68265 100644
--- a/core/res/res/values-mcc310-mnc560-cs/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-cs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM karta není poskytována (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM karta není povolena (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefon není povolen (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-da/strings.xml b/core/res/res/values-mcc310-mnc560-da/strings.xml
index 2c63d87..857e040 100644
--- a/core/res/res/values-mcc310-mnc560-da/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-da/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kort leveres ikke MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kort er ikke tilladt MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefonen har ikke adgangstilladelse MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-de/strings.xml b/core/res/res/values-mcc310-mnc560-de/strings.xml
index e8fec2c..a5d594b 100644
--- a/core/res/res/values-mcc310-mnc560-de/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-de/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-Karte nicht eingerichtet MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-Karte nicht zulässig MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Smartphone nicht zulässig MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-el/strings.xml b/core/res/res/values-mcc310-mnc560-el/strings.xml
index efd81f7..803ecdd 100644
--- a/core/res/res/values-mcc310-mnc560-el/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-el/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Δεν παρέχεται κάρτα SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc560-en-rAU/strings.xml
index c218c64..d24a056 100644
--- a/core/res/res/values-mcc310-mnc560-en-rAU/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-en-rAU/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc560-en-rGB/strings.xml
index c218c64..d24a056 100644
--- a/core/res/res/values-mcc310-mnc560-en-rGB/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-en-rGB/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc560-en-rIN/strings.xml
index c218c64..d24a056 100644
--- a/core/res/res/values-mcc310-mnc560-en-rIN/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-en-rIN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc560-es-rUS/strings.xml
index 62d61ba..52b2554 100644
--- a/core/res/res/values-mcc310-mnc560-es-rUS/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-es-rUS/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM no provista MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM no permitida MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-es/strings.xml b/core/res/res/values-mcc310-mnc560-es/strings.xml
index dbd71d5..8fb818b 100644
--- a/core/res/res/values-mcc310-mnc560-es/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-es/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM no proporcionada (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM no admitida (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-et/strings.xml b/core/res/res/values-mcc310-mnc560-et/strings.xml
index b269ace..1bb5bd5 100644
--- a/core/res/res/values-mcc310-mnc560-et/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-et/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kaart on ette valmistamata MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kaart pole lubatud MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefon pole lubatud MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-eu/strings.xml b/core/res/res/values-mcc310-mnc560-eu/strings.xml
index cee0106..1fd51a9 100644
--- a/core/res/res/values-mcc310-mnc560-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-eu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Ez dago SIM txartelik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Ez da onartzen SIM txartela MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-fa/strings.xml b/core/res/res/values-mcc310-mnc560-fa/strings.xml
index b4683c7..d2c8c41 100644
--- a/core/res/res/values-mcc310-mnc560-fa/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-fa/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"‏سیم‌کارت مجاز نیست MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-fi/strings.xml b/core/res/res/values-mcc310-mnc560-fi/strings.xml
index 54c80ed..fc7629d 100644
--- a/core/res/res/values-mcc310-mnc560-fi/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-fi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kortti estetty MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc560-fr-rCA/strings.xml
index 8b6c4ec..246b434 100644
--- a/core/res/res/values-mcc310-mnc560-fr-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-fr-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Carte SIM non configurée, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Carte SIM non autorisée, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-fr/strings.xml b/core/res/res/values-mcc310-mnc560-fr/strings.xml
index b52eaf7..9601bc5bd 100644
--- a/core/res/res/values-mcc310-mnc560-fr/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-fr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Carte SIM non provisionnée MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Carte SIM non autorisée MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-gl/strings.xml b/core/res/res/values-mcc310-mnc560-gl/strings.xml
index a8c04d2..1f78daa 100644
--- a/core/res/res/values-mcc310-mnc560-gl/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-gl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Non se admite a tarxeta SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Non se admite o teléfono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-gu/strings.xml b/core/res/res/values-mcc310-mnc560-gu/strings.xml
index c3892da..f14a72b 100644
--- a/core/res/res/values-mcc310-mnc560-gu/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-gu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIMને MM#2ની જોગવાઈ નથી"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"MM#6 ફોનની મંજૂરી નથી"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-hi/strings.xml b/core/res/res/values-mcc310-mnc560-hi/strings.xml
index 4e07e4f..7c52266 100644
--- a/core/res/res/values-mcc310-mnc560-hi/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-hi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM काम नहीं कर रहा है MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM की अनुमति नहीं है MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"फ़ोन की इजाज़त नहीं है MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-hr/strings.xml b/core/res/res/values-mcc310-mnc560-hr/strings.xml
index dc6653e..f51599c 100644
--- a/core/res/res/values-mcc310-mnc560-hr/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-hr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Ne pruža se usluga za SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM nije dopušten MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefon nije dopušten MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-hu/strings.xml b/core/res/res/values-mcc310-mnc560-hu/strings.xml
index 1a7a6b3..f23dd04 100644
--- a/core/res/res/values-mcc310-mnc560-hu/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-hu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Nem engedélyezett SIM-kártya (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"A SIM-kártya nem engedélyezett (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-hy/strings.xml b/core/res/res/values-mcc310-mnc560-hy/strings.xml
index c398877..072c0c5 100644
--- a/core/res/res/values-mcc310-mnc560-hy/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-hy/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-in/strings.xml b/core/res/res/values-mcc310-mnc560-in/strings.xml
index c3c7df3..9b56660 100644
--- a/core/res/res/values-mcc310-mnc560-in/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-in/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM tidak di-provisioning MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM tidak diizinkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Ponsel tidak diizinkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-is/strings.xml b/core/res/res/values-mcc310-mnc560-is/strings.xml
index 4a59abd..3ae1361 100644
--- a/core/res/res/values-mcc310-mnc560-is/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-is/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-korti ekki úthlutað MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kort ekki leyft MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Sími ekki leyfður MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-it/strings.xml b/core/res/res/values-mcc310-mnc560-it/strings.xml
index d2c966c..201e5b3 100644
--- a/core/res/res/values-mcc310-mnc560-it/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-it/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Scheda SIM non predisposta MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Scheda SIM non consentita MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefono non consentito MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-iw/strings.xml b/core/res/res/values-mcc310-mnc560-iw/strings.xml
index 68f0aa9..168f5ea 100644
--- a/core/res/res/values-mcc310-mnc560-iw/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-iw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"‏הטלפון לא מורשה MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ja/strings.xml b/core/res/res/values-mcc310-mnc560-ja/strings.xml
index 0429996..244c93a 100644
--- a/core/res/res/values-mcc310-mnc560-ja/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ja/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM には対応していません(MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM は許可されていません(MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"電話は許可されていません(MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ka/strings.xml b/core/res/res/values-mcc310-mnc560-ka/strings.xml
index b0371f0..c89674b 100644
--- a/core/res/res/values-mcc310-mnc560-ka/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ka/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM ბარათი დაუშვებელია (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ტელეფონი დაუშვებელია MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-kk/strings.xml b/core/res/res/values-mcc310-mnc560-kk/strings.xml
index 2015f8c..33aa902 100644
--- a/core/res/res/values-mcc310-mnc560-kk/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-kk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM картасы қарастырылмаған MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM картасына рұқсат етілмеген MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Телефон пайдалануға болмайды MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-km/strings.xml b/core/res/res/values-mcc310-mnc560-km/strings.xml
index a13ca7d..b01e283 100644
--- a/core/res/res/values-mcc310-mnc560-km/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-km/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-kn/strings.xml b/core/res/res/values-mcc310-mnc560-kn/strings.xml
index da75904..0879d4d 100644
--- a/core/res/res/values-mcc310-mnc560-kn/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-kn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ಫೋನ್ MM#6 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ko/strings.xml b/core/res/res/values-mcc310-mnc560-ko/strings.xml
index ee71a09c..74d6064 100644
--- a/core/res/res/values-mcc310-mnc560-ko/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ko/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM이 프로비저닝되지 않음 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM이 허용되지 않음 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ky/strings.xml b/core/res/res/values-mcc310-mnc560-ky/strings.xml
index 00fc1c4..75e4794 100644
--- a/core/res/res/values-mcc310-mnc560-ky/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ky/strings.xml
@@ -20,6 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM картаны колдонууга тыюу салынган MM#3"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM карта таанылган жок (MM#2)"</string>
+    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Телефонду колдонууга тыюу салынган MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-lo/strings.xml b/core/res/res/values-mcc310-mnc560-lo/strings.xml
index 702470e..9244031 100644
--- a/core/res/res/values-mcc310-mnc560-lo/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-lo/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-lt/strings.xml b/core/res/res/values-mcc310-mnc560-lt/strings.xml
index c3c5a9e..8ced4c0 100644
--- a/core/res/res/values-mcc310-mnc560-lt/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-lt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM kortelė neteikiama (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM kortelė neleidžiama (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefonas neleidžiamas (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-lv/strings.xml b/core/res/res/values-mcc310-mnc560-lv/strings.xml
index dcf7805..fc565d6 100644
--- a/core/res/res/values-mcc310-mnc560-lv/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-lv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM karte netiek nodrošināta: MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM karti nav atļauts izmantot: MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Tālruni nav atļauts izmantot: MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-mk/strings.xml b/core/res/res/values-mcc310-mnc560-mk/strings.xml
index cf0ae7e..6d159f4 100644
--- a/core/res/res/values-mcc310-mnc560-mk/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-mk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Не е обезбедена SIM-картичка, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Не е дозволена SIM-картичка, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Телефонот не е дозволен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ml/strings.xml b/core/res/res/values-mcc310-mnc560-ml/strings.xml
index 379d438..859e887 100644
--- a/core/res/res/values-mcc310-mnc560-ml/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ml/strings.xml
@@ -20,6 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
+    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ഫോൺ അനുവദനീയമല്ല MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-mn/strings.xml b/core/res/res/values-mcc310-mnc560-mn/strings.xml
index 0bf1599..1d01e8c 100644
--- a/core/res/res/values-mcc310-mnc560-mn/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-mn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Утсыг зөвшөөрөөгүй MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-mr/strings.xml b/core/res/res/values-mcc310-mnc560-mr/strings.xml
index 69e81ad..8a737e4 100644
--- a/core/res/res/values-mcc310-mnc560-mr/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-mr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"फोन MM#6 ला अनुमती देत नाही"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ms/strings.xml b/core/res/res/values-mcc310-mnc560-ms/strings.xml
index cd0aed7..3c5c712 100644
--- a/core/res/res/values-mcc310-mnc560-ms/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ms/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM tidak diperuntukkan MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM tidak dibenarkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefon tidak dibenarkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-my/strings.xml b/core/res/res/values-mcc310-mnc560-my/strings.xml
index 58fba87..00600be 100644
--- a/core/res/res/values-mcc310-mnc560-my/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-my/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-nb/strings.xml b/core/res/res/values-mcc310-mnc560-nb/strings.xml
index bc90ae1..ce9dd874 100644
--- a/core/res/res/values-mcc310-mnc560-nb/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-nb/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kortet er ikke klargjort, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kortet er ikke tillatt, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefonen er ikke tillatt, MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ne/strings.xml b/core/res/res/values-mcc310-mnc560-ne/strings.xml
index 75c493d..923db94 100644
--- a/core/res/res/values-mcc310-mnc560-ne/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ne/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM को प्रावधान छैन MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM लाई अनुमति छैन MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"फोनलाई अनुमति छैन MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-nl/strings.xml b/core/res/res/values-mcc310-mnc560-nl/strings.xml
index 7241627..eadbb84 100644
--- a/core/res/res/values-mcc310-mnc560-nl/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-nl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Simkaart niet geregistreerd MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Simkaart niet toegestaan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefoon niet toegestaan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-pa/strings.xml b/core/res/res/values-mcc310-mnc560-pa/strings.xml
new file mode 100644
index 0000000..3c48708
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc560-pa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ਫ਼ੋਨ ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc560-pl/strings.xml b/core/res/res/values-mcc310-mnc560-pl/strings.xml
index f844db6..0f4b474 100644
--- a/core/res/res/values-mcc310-mnc560-pl/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-pl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"MM#2 – karta SIM nieobsługiwana"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"MM#3 – niedozwolona karta SIM"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"MM#6 – telefon niedozwolony"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc560-pt-rBR/strings.xml
index 4c10ef9..fba400c 100644
--- a/core/res/res/values-mcc310-mnc560-pt-rBR/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-pt-rBR/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc560-pt-rPT/strings.xml
index 4c10ef9..991627c 100644
--- a/core/res/res/values-mcc310-mnc560-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-pt-rPT/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telemóvel não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-pt/strings.xml b/core/res/res/values-mcc310-mnc560-pt/strings.xml
index 4c10ef9..fba400c 100644
--- a/core/res/res/values-mcc310-mnc560-pt/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-pt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ro/strings.xml b/core/res/res/values-mcc310-mnc560-ro/strings.xml
index e24b74c..1e6c63a 100644
--- a/core/res/res/values-mcc310-mnc560-ro/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ro/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Cardul SIM nu este activat MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Cardul SIM nu este permis MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefonul nu este permis MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ru/strings.xml b/core/res/res/values-mcc310-mnc560-ru/strings.xml
index 35bf36f..948c8c8 100644
--- a/core/res/res/values-mcc310-mnc560-ru/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ru/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-карта не активирована (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Использование SIM-карты запрещено (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Звонки запрещены (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-si/strings.xml b/core/res/res/values-mcc310-mnc560-si/strings.xml
index 4c60ce4..b65d067 100644
--- a/core/res/res/values-mcc310-mnc560-si/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-si/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM MM#3 ඉඩ නොදේ"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-sk/strings.xml b/core/res/res/values-mcc310-mnc560-sk/strings.xml
index ad4aba4..cae65ff 100644
--- a/core/res/res/values-mcc310-mnc560-sk/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-sk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM karta nie je k dispozícii – MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM karta je zakázaná – MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefón nie je povolený (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-sl/strings.xml b/core/res/res/values-mcc310-mnc560-sl/strings.xml
index 7855987..15c495e 100644
--- a/core/res/res/values-mcc310-mnc560-sl/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-sl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Kartica SIM ni omogočena za uporabo MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Kartica SIM ni dovoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefon ni dovoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-sq/strings.xml b/core/res/res/values-mcc310-mnc560-sq/strings.xml
index 527430e..a554e81 100644
--- a/core/res/res/values-mcc310-mnc560-sq/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-sq/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Karta SIM nuk është dhënë MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Karta SIM nuk lejohet MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefoni nuk lejohet MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-sr/strings.xml b/core/res/res/values-mcc310-mnc560-sr/strings.xml
index ec5a2b6..3a2d6c0 100644
--- a/core/res/res/values-mcc310-mnc560-sr/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-sr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM картица није подешена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Телефон није дозвољен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-sv/strings.xml b/core/res/res/values-mcc310-mnc560-sv/strings.xml
index d113989..ef712b4 100644
--- a/core/res/res/values-mcc310-mnc560-sv/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-sv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kort tillhandahålls inte MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kort tillåts inte MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Mobil tillåts inte MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-sw/strings.xml b/core/res/res/values-mcc310-mnc560-sw/strings.xml
index 4e3df8b..2f989a7 100644
--- a/core/res/res/values-mcc310-mnc560-sw/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-sw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM haitumiki MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM hairuhusiwi MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Simu hairuhusiwi MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ta/strings.xml b/core/res/res/values-mcc310-mnc560-ta/strings.xml
index 78f8243..dc98cca 100644
--- a/core/res/res/values-mcc310-mnc560-ta/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ta/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"சிம் அமைக்கப்படவில்லை MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ஃபோன் அனுமதிக்கப்படவில்லை MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-te/strings.xml b/core/res/res/values-mcc310-mnc560-te/strings.xml
new file mode 100644
index 0000000..f5e09ba
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc560-te/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM MM#2ని సక్రియం చేయలేదు"</string>
+    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM MM#3ని అనుమతించలేదు"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc560-th/strings.xml b/core/res/res/values-mcc310-mnc560-th/strings.xml
index 7896973..881f797 100644
--- a/core/res/res/values-mcc310-mnc560-th/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-th/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"ไม่มีการจัดสรรซิม MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-tl/strings.xml b/core/res/res/values-mcc310-mnc560-tl/strings.xml
index ac87cb5..2e32d53 100644
--- a/core/res/res/values-mcc310-mnc560-tl/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-tl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Hindi na-provision ang SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Hindi pinapahintulutan ang SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Hindi pinapahintulutan ang telepono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-tr/strings.xml b/core/res/res/values-mcc310-mnc560-tr/strings.xml
index 5ea1d80..2b41e2c 100644
--- a/core/res/res/values-mcc310-mnc560-tr/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-tr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM MM#3\'e izin vermiyor"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Telefona izin verilmiyor MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-uk/strings.xml b/core/res/res/values-mcc310-mnc560-uk/strings.xml
index 7ee6b88..bd75240 100644
--- a/core/res/res/values-mcc310-mnc560-uk/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-uk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-карту не надано (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-карта заборонена (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Телефон заборонено (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-ur/strings.xml b/core/res/res/values-mcc310-mnc560-ur/strings.xml
index 609d3e8..c8c20d6 100644
--- a/core/res/res/values-mcc310-mnc560-ur/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-ur/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"‏SIM کی اجازت نہیں ہے MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"‏فون کی اجازت نہیں ہے MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-uz/strings.xml b/core/res/res/values-mcc310-mnc560-uz/strings.xml
index 4157041..92b86e1 100644
--- a/core/res/res/values-mcc310-mnc560-uz/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-uz/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Chaqiruvlar taqiqlangan (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-vi/strings.xml b/core/res/res/values-mcc310-mnc560-vi/strings.xml
index b2284e1..7023d51 100644
--- a/core/res/res/values-mcc310-mnc560-vi/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-vi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM không được cấp phép MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM không được phép MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Không cho phép điện thoại MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc560-zh-rCN/strings.xml
index 050ea01..bf168bd 100644
--- a/core/res/res/values-mcc310-mnc560-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-zh-rCN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"未配置的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"不被允许的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"不受允许的手机 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc560-zh-rHK/strings.xml
index 43cfc01..ea8dcab 100644
--- a/core/res/res/values-mcc310-mnc560-zh-rHK/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-zh-rHK/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc560-zh-rTW/strings.xml
index 43cfc01..3674ee2 100644
--- a/core/res/res/values-mcc310-mnc560-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-zh-rTW/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"不支援的手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-zu/strings.xml b/core/res/res/values-mcc310-mnc560-zu/strings.xml
index e1b7abb..7b17fed 100644
--- a/core/res/res/values-mcc310-mnc560-zu/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-zu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"I-SIM ayinikezelwe MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2519618694918727742">"I-SIM ayivunyelwe MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7030488670186895244">"Ifoni ayivunyelwe MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560/strings.xml b/core/res/res/values-mcc310-mnc560/strings.xml
index a3fea29..6a404d5 100644
--- a/core/res/res/values-mcc310-mnc560/strings.xml
+++ b/core/res/res/values-mcc310-mnc560/strings.xml
@@ -20,4 +20,5 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string>
     <string name="mmcc_illegal_ms">SIM not allowed MM#3</string>
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-af/strings.xml b/core/res/res/values-mcc310-mnc950-af/strings.xml
index 19ae78d..95b73b91 100644
--- a/core/res/res/values-mcc310-mnc950-af/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-af/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM is nie opgestel nie MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM word nie toegelaat nie MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Foon nie toegelaat nie MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-am/strings.xml b/core/res/res/values-mcc310-mnc950-am/strings.xml
index e81745d..ca5d603 100644
--- a/core/res/res/values-mcc310-mnc950-am/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-am/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"ሲም አልቀረበም MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"ሲም አይፈቀድም MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ስልክ አይፈቀድም MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ar/strings.xml b/core/res/res/values-mcc310-mnc950-ar/strings.xml
index 1aab01c..bc2248b 100644
--- a/core/res/res/values-mcc310-mnc950-ar/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ar/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"‏لم يتم توفير SIM ‏MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"‏غير مسموح باستخدام الهاتف MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-az/strings.xml b/core/res/res/values-mcc310-mnc950-az/strings.xml
index 26d91ef..ceb15ea 100644
--- a/core/res/res/values-mcc310-mnc950-az/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-az/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM MM#2 təmin etmir"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM MM#3 dəstəkləmir"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"MM#6 telefonu dəstəklənmir"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-bg/strings.xml b/core/res/res/values-mcc310-mnc950-bg/strings.xml
index 761b439..5342fa8 100644
--- a/core/res/res/values-mcc310-mnc950-bg/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-bg/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM картата не е обезпечена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM картата не е разрешена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Телефонът не е разрешен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-bn/strings.xml b/core/res/res/values-mcc310-mnc950-bn/strings.xml
new file mode 100644
index 0000000..d12c75a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc950-bn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"সিমের অনুমতি নেই MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ফোন অনুমোদিত নয় MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc950-ca/strings.xml b/core/res/res/values-mcc310-mnc950-ca/strings.xml
index 9b77ce7..adb12e8 100644
--- a/core/res/res/values-mcc310-mnc950-ca/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ca/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"La SIM no està proporcionada a MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"La SIM no és compatible a MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telèfon no compatible MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-cs/strings.xml b/core/res/res/values-mcc310-mnc950-cs/strings.xml
index 3f8b8aa..49cc25f 100644
--- a/core/res/res/values-mcc310-mnc950-cs/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-cs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM karta není poskytována (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM karta není povolena (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefon není povolen (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-da/strings.xml b/core/res/res/values-mcc310-mnc950-da/strings.xml
index 6cd8306..e63a586 100644
--- a/core/res/res/values-mcc310-mnc950-da/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-da/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kort leveres ikke MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kort er ikke tilladt MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefonen har ikke adgangstilladelse MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-de/strings.xml b/core/res/res/values-mcc310-mnc950-de/strings.xml
index 70e3068..60d81e6 100644
--- a/core/res/res/values-mcc310-mnc950-de/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-de/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-Karte nicht eingerichtet MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-Karte nicht zulässig MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Smartphone nicht zulässig MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-el/strings.xml b/core/res/res/values-mcc310-mnc950-el/strings.xml
index 1a2542c..bffaa00 100644
--- a/core/res/res/values-mcc310-mnc950-el/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-el/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Δεν παρέχεται κάρτα SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc950-en-rAU/strings.xml
index 7ef6605..d2d137c 100644
--- a/core/res/res/values-mcc310-mnc950-en-rAU/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-en-rAU/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc950-en-rGB/strings.xml
index 7ef6605..d2d137c 100644
--- a/core/res/res/values-mcc310-mnc950-en-rGB/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-en-rGB/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc950-en-rIN/strings.xml
index 7ef6605..d2d137c 100644
--- a/core/res/res/values-mcc310-mnc950-en-rIN/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-en-rIN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc950-es-rUS/strings.xml
index 31a863c..d194180 100644
--- a/core/res/res/values-mcc310-mnc950-es-rUS/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-es-rUS/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM no provista MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM no permitida MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-es/strings.xml b/core/res/res/values-mcc310-mnc950-es/strings.xml
index ba8c78b..bbb0acf 100644
--- a/core/res/res/values-mcc310-mnc950-es/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-es/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM no proporcionada (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM no admitida (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-et/strings.xml b/core/res/res/values-mcc310-mnc950-et/strings.xml
index 013243a..14b4d45 100644
--- a/core/res/res/values-mcc310-mnc950-et/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-et/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kaart on ette valmistamata MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kaart pole lubatud MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefon pole lubatud MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-eu/strings.xml b/core/res/res/values-mcc310-mnc950-eu/strings.xml
index 097e423..2e33d02 100644
--- a/core/res/res/values-mcc310-mnc950-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-eu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Ez dago SIM txartelik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Ez da onartzen SIM txartela MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-fa/strings.xml b/core/res/res/values-mcc310-mnc950-fa/strings.xml
index 3281bb5..f889d5e 100644
--- a/core/res/res/values-mcc310-mnc950-fa/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-fa/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"‏سیم‌کارت مجاز نیست MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-fi/strings.xml b/core/res/res/values-mcc310-mnc950-fi/strings.xml
index 01e04f7..846ee78 100644
--- a/core/res/res/values-mcc310-mnc950-fi/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-fi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kortti estetty MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc950-fr-rCA/strings.xml
index a310f82..08a3e55 100644
--- a/core/res/res/values-mcc310-mnc950-fr-rCA/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-fr-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Carte SIM non configurée, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Carte SIM non autorisée, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-fr/strings.xml b/core/res/res/values-mcc310-mnc950-fr/strings.xml
index 7b0fb2c..a0f6016 100644
--- a/core/res/res/values-mcc310-mnc950-fr/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-fr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Carte SIM non provisionnée MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Carte SIM non autorisée MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-gl/strings.xml b/core/res/res/values-mcc310-mnc950-gl/strings.xml
index 55ff461..e771683 100644
--- a/core/res/res/values-mcc310-mnc950-gl/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-gl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Non se admite a tarxeta SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Non se admite o teléfono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-gu/strings.xml b/core/res/res/values-mcc310-mnc950-gu/strings.xml
index a6e1a83..9f4596b 100644
--- a/core/res/res/values-mcc310-mnc950-gu/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-gu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIMને MM#2ની જોગવાઈ નથી"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"MM#6 ફોનની મંજૂરી નથી"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-hi/strings.xml b/core/res/res/values-mcc310-mnc950-hi/strings.xml
index 41b9bc9..e71aa25 100644
--- a/core/res/res/values-mcc310-mnc950-hi/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-hi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM काम नहीं कर रहा है MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM की अनुमति नहीं है MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"फ़ोन की इजाज़त नहीं है MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-hr/strings.xml b/core/res/res/values-mcc310-mnc950-hr/strings.xml
index 1c39a09..c7f6b22 100644
--- a/core/res/res/values-mcc310-mnc950-hr/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-hr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Ne pruža se usluga za SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM nije dopušten MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefon nije dopušten MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-hu/strings.xml b/core/res/res/values-mcc310-mnc950-hu/strings.xml
index 6b8ee76..22b5e9b 100644
--- a/core/res/res/values-mcc310-mnc950-hu/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-hu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Nem engedélyezett SIM-kártya (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"A SIM-kártya nem engedélyezett (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-hy/strings.xml b/core/res/res/values-mcc310-mnc950-hy/strings.xml
index 63dfa46..5136640 100644
--- a/core/res/res/values-mcc310-mnc950-hy/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-hy/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-in/strings.xml b/core/res/res/values-mcc310-mnc950-in/strings.xml
index a7c0232..bb9e380 100644
--- a/core/res/res/values-mcc310-mnc950-in/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-in/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM tidak di-provisioning MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM tidak diizinkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Ponsel tidak diizinkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-is/strings.xml b/core/res/res/values-mcc310-mnc950-is/strings.xml
index ceee15a..d8b847f 100644
--- a/core/res/res/values-mcc310-mnc950-is/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-is/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-korti ekki úthlutað MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kort ekki leyft MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Sími ekki leyfður MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-it/strings.xml b/core/res/res/values-mcc310-mnc950-it/strings.xml
index 21e2a4a..bf6d8bb 100644
--- a/core/res/res/values-mcc310-mnc950-it/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-it/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Scheda SIM non predisposta MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Scheda SIM non consentita MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefono non consentito MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-iw/strings.xml b/core/res/res/values-mcc310-mnc950-iw/strings.xml
index 041408f..fd0ac8fc 100644
--- a/core/res/res/values-mcc310-mnc950-iw/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-iw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"‏הטלפון לא מורשה MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ja/strings.xml b/core/res/res/values-mcc310-mnc950-ja/strings.xml
index 97f697e..4224a8a 100644
--- a/core/res/res/values-mcc310-mnc950-ja/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ja/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM には対応していません(MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM は許可されていません(MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"電話は許可されていません(MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ka/strings.xml b/core/res/res/values-mcc310-mnc950-ka/strings.xml
index 4d8c8a8..0cbd72c 100644
--- a/core/res/res/values-mcc310-mnc950-ka/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ka/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM ბარათი დაუშვებელია (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ტელეფონი დაუშვებელია MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-kk/strings.xml b/core/res/res/values-mcc310-mnc950-kk/strings.xml
index 899a9a2..271083a 100644
--- a/core/res/res/values-mcc310-mnc950-kk/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-kk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM картасы қарастырылмаған MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM картасына рұқсат етілмеген MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Телефон пайдалануға болмайды MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-km/strings.xml b/core/res/res/values-mcc310-mnc950-km/strings.xml
index 3c80d9f..d5a98d5 100644
--- a/core/res/res/values-mcc310-mnc950-km/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-km/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-kn/strings.xml b/core/res/res/values-mcc310-mnc950-kn/strings.xml
index 1c7ab20..f15aec8 100644
--- a/core/res/res/values-mcc310-mnc950-kn/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-kn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ಫೋನ್ MM#6 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ko/strings.xml b/core/res/res/values-mcc310-mnc950-ko/strings.xml
index 2419c2a..96c9b62 100644
--- a/core/res/res/values-mcc310-mnc950-ko/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ko/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM이 프로비저닝되지 않음 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM이 허용되지 않음 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ky/strings.xml b/core/res/res/values-mcc310-mnc950-ky/strings.xml
index fb7efbb..f8c7313 100644
--- a/core/res/res/values-mcc310-mnc950-ky/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ky/strings.xml
@@ -20,6 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM картаны колдонууга тыюу салынган MM#3"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM карта таанылган жок (MM#2)"</string>
+    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Телефонду колдонууга тыюу салынган MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-lo/strings.xml b/core/res/res/values-mcc310-mnc950-lo/strings.xml
index b69536f..38f82b4 100644
--- a/core/res/res/values-mcc310-mnc950-lo/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-lo/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-lt/strings.xml b/core/res/res/values-mcc310-mnc950-lt/strings.xml
index 8ef0869..4c51da7 100644
--- a/core/res/res/values-mcc310-mnc950-lt/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-lt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM kortelė neteikiama (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM kortelė neleidžiama (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefonas neleidžiamas (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-lv/strings.xml b/core/res/res/values-mcc310-mnc950-lv/strings.xml
index 2a491c0..0ed0ae7 100644
--- a/core/res/res/values-mcc310-mnc950-lv/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-lv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM karte netiek nodrošināta: MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM karti nav atļauts izmantot: MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Tālruni nav atļauts izmantot: MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-mk/strings.xml b/core/res/res/values-mcc310-mnc950-mk/strings.xml
index a1da44b..375b09a 100644
--- a/core/res/res/values-mcc310-mnc950-mk/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-mk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Не е обезбедена SIM-картичка, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Не е дозволена SIM-картичка, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Телефонот не е дозволен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ml/strings.xml b/core/res/res/values-mcc310-mnc950-ml/strings.xml
index 4a04194..b1defa6 100644
--- a/core/res/res/values-mcc310-mnc950-ml/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ml/strings.xml
@@ -20,6 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
+    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ഫോൺ അനുവദനീയമല്ല MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-mn/strings.xml b/core/res/res/values-mcc310-mnc950-mn/strings.xml
index 2d4b5f53..e8ef11c 100644
--- a/core/res/res/values-mcc310-mnc950-mn/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-mn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Утсыг зөвшөөрөөгүй MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-mr/strings.xml b/core/res/res/values-mcc310-mnc950-mr/strings.xml
index eca7dca..088d800 100644
--- a/core/res/res/values-mcc310-mnc950-mr/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-mr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"फोन MM#6 ला अनुमती देत नाही"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ms/strings.xml b/core/res/res/values-mcc310-mnc950-ms/strings.xml
index 4f5c781..bb4600d 100644
--- a/core/res/res/values-mcc310-mnc950-ms/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ms/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM tidak diperuntukkan MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM tidak dibenarkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefon tidak dibenarkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-my/strings.xml b/core/res/res/values-mcc310-mnc950-my/strings.xml
index ecf9f61..ed581ef 100644
--- a/core/res/res/values-mcc310-mnc950-my/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-my/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-nb/strings.xml b/core/res/res/values-mcc310-mnc950-nb/strings.xml
index 907482e..5134e7d 100644
--- a/core/res/res/values-mcc310-mnc950-nb/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-nb/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kortet er ikke klargjort, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kortet er ikke tillatt, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefonen er ikke tillatt, MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ne/strings.xml b/core/res/res/values-mcc310-mnc950-ne/strings.xml
index 380f01c..0b3c815 100644
--- a/core/res/res/values-mcc310-mnc950-ne/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ne/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM को प्रावधान छैन MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM लाई अनुमति छैन MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"फोनलाई अनुमति छैन MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-nl/strings.xml b/core/res/res/values-mcc310-mnc950-nl/strings.xml
index a01896c..d1e39df 100644
--- a/core/res/res/values-mcc310-mnc950-nl/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-nl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Simkaart niet geregistreerd MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Simkaart niet toegestaan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefoon niet toegestaan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-pa/strings.xml b/core/res/res/values-mcc310-mnc950-pa/strings.xml
new file mode 100644
index 0000000..05ef594
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc950-pa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ਫ਼ੋਨ ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc950-pl/strings.xml b/core/res/res/values-mcc310-mnc950-pl/strings.xml
index ce40c22..ab6e8fb 100644
--- a/core/res/res/values-mcc310-mnc950-pl/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-pl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"MM#2 – karta SIM nieobsługiwana"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"MM#3 – niedozwolona karta SIM"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"MM#6 – telefon niedozwolony"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc950-pt-rBR/strings.xml
index 1f89e47..83c84ce 100644
--- a/core/res/res/values-mcc310-mnc950-pt-rBR/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-pt-rBR/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc950-pt-rPT/strings.xml
index 1f89e47..7b657fd 100644
--- a/core/res/res/values-mcc310-mnc950-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-pt-rPT/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telemóvel não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-pt/strings.xml b/core/res/res/values-mcc310-mnc950-pt/strings.xml
index 1f89e47..83c84ce 100644
--- a/core/res/res/values-mcc310-mnc950-pt/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-pt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ro/strings.xml b/core/res/res/values-mcc310-mnc950-ro/strings.xml
index 7fb3f2e..e51800b 100644
--- a/core/res/res/values-mcc310-mnc950-ro/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ro/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Cardul SIM nu este activat MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Cardul SIM nu este permis MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefonul nu este permis MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ru/strings.xml b/core/res/res/values-mcc310-mnc950-ru/strings.xml
index 16deeed..1dbdd7b 100644
--- a/core/res/res/values-mcc310-mnc950-ru/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ru/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-карта не активирована (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Использование SIM-карты запрещено (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Звонки запрещены (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-si/strings.xml b/core/res/res/values-mcc310-mnc950-si/strings.xml
index dd512d9..bb0f22f 100644
--- a/core/res/res/values-mcc310-mnc950-si/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-si/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM MM#3 ඉඩ නොදේ"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-sk/strings.xml b/core/res/res/values-mcc310-mnc950-sk/strings.xml
index 6a8e6f0..7bba3ae 100644
--- a/core/res/res/values-mcc310-mnc950-sk/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-sk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM karta nie je k dispozícii – MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM karta je zakázaná – MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefón nie je povolený (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-sl/strings.xml b/core/res/res/values-mcc310-mnc950-sl/strings.xml
index 391ee78..cd08650 100644
--- a/core/res/res/values-mcc310-mnc950-sl/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-sl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Kartica SIM ni omogočena za uporabo MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Kartica SIM ni dovoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefon ni dovoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-sq/strings.xml b/core/res/res/values-mcc310-mnc950-sq/strings.xml
index ebc978c..8230755 100644
--- a/core/res/res/values-mcc310-mnc950-sq/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-sq/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Karta SIM nuk është dhënë MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Karta SIM nuk lejohet MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefoni nuk lejohet MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-sr/strings.xml b/core/res/res/values-mcc310-mnc950-sr/strings.xml
index 4f3f86f..cac39e2 100644
--- a/core/res/res/values-mcc310-mnc950-sr/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-sr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM картица није подешена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Телефон није дозвољен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-sv/strings.xml b/core/res/res/values-mcc310-mnc950-sv/strings.xml
index 4739f06..7ac957d 100644
--- a/core/res/res/values-mcc310-mnc950-sv/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-sv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kort tillhandahålls inte MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kort tillåts inte MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Mobil tillåts inte MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-sw/strings.xml b/core/res/res/values-mcc310-mnc950-sw/strings.xml
index 903b4a5..8967e18 100644
--- a/core/res/res/values-mcc310-mnc950-sw/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-sw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM haitumiki MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM hairuhusiwi MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Simu hairuhusiwi MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ta/strings.xml b/core/res/res/values-mcc310-mnc950-ta/strings.xml
index 8838aed7..35a7202 100644
--- a/core/res/res/values-mcc310-mnc950-ta/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ta/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"சிம் அமைக்கப்படவில்லை MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ஃபோன் அனுமதிக்கப்படவில்லை MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-te/strings.xml b/core/res/res/values-mcc310-mnc950-te/strings.xml
new file mode 100644
index 0000000..4611a72
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc950-te/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM MM#2ని సక్రియం చేయలేదు"</string>
+    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM MM#3ని అనుమతించలేదు"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc950-th/strings.xml b/core/res/res/values-mcc310-mnc950-th/strings.xml
index 3feb1f6..d8c61dd 100644
--- a/core/res/res/values-mcc310-mnc950-th/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-th/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"ไม่มีการจัดสรรซิม MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-tl/strings.xml b/core/res/res/values-mcc310-mnc950-tl/strings.xml
index 55e0bfd..66f686c 100644
--- a/core/res/res/values-mcc310-mnc950-tl/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-tl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Hindi na-provision ang SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Hindi pinapahintulutan ang SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Hindi pinapahintulutan ang telepono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-tr/strings.xml b/core/res/res/values-mcc310-mnc950-tr/strings.xml
index 7a274a4..54e8e7d 100644
--- a/core/res/res/values-mcc310-mnc950-tr/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-tr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM MM#3\'e izin vermiyor"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Telefona izin verilmiyor MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-uk/strings.xml b/core/res/res/values-mcc310-mnc950-uk/strings.xml
index bf5e6411..be0cd2b 100644
--- a/core/res/res/values-mcc310-mnc950-uk/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-uk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-карту не надано (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-карта заборонена (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Телефон заборонено (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-ur/strings.xml b/core/res/res/values-mcc310-mnc950-ur/strings.xml
index 35857cd..7b925c4 100644
--- a/core/res/res/values-mcc310-mnc950-ur/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-ur/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"‏SIM کی اجازت نہیں ہے MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"‏فون کی اجازت نہیں ہے MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-uz/strings.xml b/core/res/res/values-mcc310-mnc950-uz/strings.xml
index e31c7b6..99ac738 100644
--- a/core/res/res/values-mcc310-mnc950-uz/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-uz/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Chaqiruvlar taqiqlangan (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-vi/strings.xml b/core/res/res/values-mcc310-mnc950-vi/strings.xml
index b9360b5..829a4dc 100644
--- a/core/res/res/values-mcc310-mnc950-vi/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-vi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM không được cấp phép MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM không được phép MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Không cho phép điện thoại MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc950-zh-rCN/strings.xml
index 3b4ba0a..240dd0b 100644
--- a/core/res/res/values-mcc310-mnc950-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-zh-rCN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"未配置的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"不被允许的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"不受允许的手机 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc950-zh-rHK/strings.xml
index 763e498..97a13bc 100644
--- a/core/res/res/values-mcc310-mnc950-zh-rHK/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-zh-rHK/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc950-zh-rTW/strings.xml
index 763e498..934aea0 100644
--- a/core/res/res/values-mcc310-mnc950-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-zh-rTW/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"不支援的手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-zu/strings.xml b/core/res/res/values-mcc310-mnc950-zu/strings.xml
index 1c29754..9dc4403 100644
--- a/core/res/res/values-mcc310-mnc950-zu/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-zu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"I-SIM ayinikezelwe MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2418195136279399212">"I-SIM ayivunyelwe MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8920048244573695129">"Ifoni ayivunyelwe MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950/strings.xml b/core/res/res/values-mcc310-mnc950/strings.xml
index a3fea29..6a404d5 100644
--- a/core/res/res/values-mcc310-mnc950/strings.xml
+++ b/core/res/res/values-mcc310-mnc950/strings.xml
@@ -20,4 +20,5 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string>
     <string name="mmcc_illegal_ms">SIM not allowed MM#3</string>
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-af/strings.xml b/core/res/res/values-mcc311-mnc180-af/strings.xml
index ead8992..73c9a6c 100644
--- a/core/res/res/values-mcc311-mnc180-af/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-af/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM is nie opgestel nie MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM word nie toegelaat nie MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Foon nie toegelaat nie MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-am/strings.xml b/core/res/res/values-mcc311-mnc180-am/strings.xml
index a7d0d1d..935312e 100644
--- a/core/res/res/values-mcc311-mnc180-am/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-am/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"ሲም አልቀረበም MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"ሲም አይፈቀድም MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ስልክ አይፈቀድም MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ar/strings.xml b/core/res/res/values-mcc311-mnc180-ar/strings.xml
index f5412bd..cdb14c5 100644
--- a/core/res/res/values-mcc311-mnc180-ar/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ar/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"‏لم يتم توفير SIM ‏MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"‏غير مسموح باستخدام الهاتف MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-az/strings.xml b/core/res/res/values-mcc311-mnc180-az/strings.xml
index c2c06be..7471fca 100644
--- a/core/res/res/values-mcc311-mnc180-az/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-az/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM MM#2 təmin etmir"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM MM#3 dəstəkləmir"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"MM#6 telefonu dəstəklənmir"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-bg/strings.xml b/core/res/res/values-mcc311-mnc180-bg/strings.xml
index faf5a42..542557e 100644
--- a/core/res/res/values-mcc311-mnc180-bg/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-bg/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM картата не е обезпечена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM картата не е разрешена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Телефонът не е разрешен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-bn/strings.xml b/core/res/res/values-mcc311-mnc180-bn/strings.xml
new file mode 100644
index 0000000..59d1624
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc180-bn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"সিমের জন্য প্রস্তুত নয় MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="97745044956236881">"সিমের অনুমতি নেই MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ফোন অনুমোদিত নয় MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc180-ca/strings.xml b/core/res/res/values-mcc311-mnc180-ca/strings.xml
index e33a901..505f396 100644
--- a/core/res/res/values-mcc311-mnc180-ca/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ca/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"La SIM no està proporcionada a MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"La SIM no és compatible a MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telèfon no compatible MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-cs/strings.xml b/core/res/res/values-mcc311-mnc180-cs/strings.xml
index 653a55a..29c8fdf 100644
--- a/core/res/res/values-mcc311-mnc180-cs/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-cs/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM karta není poskytována (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM karta není povolena (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefon není povolen (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-da/strings.xml b/core/res/res/values-mcc311-mnc180-da/strings.xml
index 04c89a5..6fadac1 100644
--- a/core/res/res/values-mcc311-mnc180-da/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-da/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kort leveres ikke MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kort er ikke tilladt MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefonen har ikke adgangstilladelse MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-de/strings.xml b/core/res/res/values-mcc311-mnc180-de/strings.xml
index 8fef081..714eac9 100644
--- a/core/res/res/values-mcc311-mnc180-de/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-de/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-Karte nicht eingerichtet MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-Karte nicht zulässig MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Smartphone nicht zulässig MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-el/strings.xml b/core/res/res/values-mcc311-mnc180-el/strings.xml
index 795f48f..2e29b12 100644
--- a/core/res/res/values-mcc311-mnc180-el/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-el/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Δεν παρέχεται κάρτα SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-en-rAU/strings.xml b/core/res/res/values-mcc311-mnc180-en-rAU/strings.xml
index 9c972bc..b284371 100644
--- a/core/res/res/values-mcc311-mnc180-en-rAU/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-en-rAU/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-en-rGB/strings.xml b/core/res/res/values-mcc311-mnc180-en-rGB/strings.xml
index 9c972bc..b284371 100644
--- a/core/res/res/values-mcc311-mnc180-en-rGB/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-en-rGB/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-en-rIN/strings.xml b/core/res/res/values-mcc311-mnc180-en-rIN/strings.xml
index 9c972bc..b284371 100644
--- a/core/res/res/values-mcc311-mnc180-en-rIN/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-en-rIN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM not provisioned MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM not allowed MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Phone not allowed MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-es-rUS/strings.xml b/core/res/res/values-mcc311-mnc180-es-rUS/strings.xml
index 694cd76..cb06a6e 100644
--- a/core/res/res/values-mcc311-mnc180-es-rUS/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-es-rUS/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM no provista MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM no permitida MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-es/strings.xml b/core/res/res/values-mcc311-mnc180-es/strings.xml
index 605e314..6368483 100644
--- a/core/res/res/values-mcc311-mnc180-es/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-es/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM no proporcionada (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM no admitida (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Teléfono no admitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-et/strings.xml b/core/res/res/values-mcc311-mnc180-et/strings.xml
index 39dfa1b..142824f 100644
--- a/core/res/res/values-mcc311-mnc180-et/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-et/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kaart on ette valmistamata MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kaart pole lubatud MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefon pole lubatud MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-eu/strings.xml b/core/res/res/values-mcc311-mnc180-eu/strings.xml
index 84732c9..4bb3cd3 100644
--- a/core/res/res/values-mcc311-mnc180-eu/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-eu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Ez dago SIM txartelik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Ez da onartzen SIM txartela MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-fa/strings.xml b/core/res/res/values-mcc311-mnc180-fa/strings.xml
index 902d821..3354859 100644
--- a/core/res/res/values-mcc311-mnc180-fa/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-fa/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"‏سیم‌کارت مجاز نیست MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"‏تلفن مجاز نیست MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-fi/strings.xml b/core/res/res/values-mcc311-mnc180-fi/strings.xml
index 004e645..c66d593 100644
--- a/core/res/res/values-mcc311-mnc180-fi/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-fi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kortti estetty MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Puhelin estetty MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-fr-rCA/strings.xml b/core/res/res/values-mcc311-mnc180-fr-rCA/strings.xml
index c0aaf99..b17c342 100644
--- a/core/res/res/values-mcc311-mnc180-fr-rCA/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-fr-rCA/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Carte SIM non configurée, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Carte SIM non autorisée, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-fr/strings.xml b/core/res/res/values-mcc311-mnc180-fr/strings.xml
index b9adf79..0cc7264 100644
--- a/core/res/res/values-mcc311-mnc180-fr/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-fr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Carte SIM non provisionnée MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Carte SIM non autorisée MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Téléphone non autorisé MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-gl/strings.xml b/core/res/res/values-mcc311-mnc180-gl/strings.xml
index cb59c97..8acb5c1 100644
--- a/core/res/res/values-mcc311-mnc180-gl/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-gl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Non se admite a tarxeta SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Non se admite o teléfono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-gu/strings.xml b/core/res/res/values-mcc311-mnc180-gu/strings.xml
index 556416e..529491e 100644
--- a/core/res/res/values-mcc311-mnc180-gu/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-gu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIMને MM#2ની જોગવાઈ નથી"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"MM#6 ફોનની મંજૂરી નથી"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-hi/strings.xml b/core/res/res/values-mcc311-mnc180-hi/strings.xml
index da1f9e1..69303e7 100644
--- a/core/res/res/values-mcc311-mnc180-hi/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-hi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM काम नहीं कर रहा है MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM की अनुमति नहीं है MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"फ़ोन की इजाज़त नहीं है MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-hr/strings.xml b/core/res/res/values-mcc311-mnc180-hr/strings.xml
index a1f0b0e..84d36b7 100644
--- a/core/res/res/values-mcc311-mnc180-hr/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-hr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Ne pruža se usluga za SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM nije dopušten MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefon nije dopušten MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-hu/strings.xml b/core/res/res/values-mcc311-mnc180-hu/strings.xml
index 917c2ee9..5d3507d 100644
--- a/core/res/res/values-mcc311-mnc180-hu/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-hu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Nem engedélyezett SIM-kártya (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"A SIM-kártya nem engedélyezett (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"A telefon nem engedélyezett (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-hy/strings.xml b/core/res/res/values-mcc311-mnc180-hy/strings.xml
index a832d02..aeaaeb9 100644
--- a/core/res/res/values-mcc311-mnc180-hy/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-hy/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-in/strings.xml b/core/res/res/values-mcc311-mnc180-in/strings.xml
index bdc8d20..8a96e4c 100644
--- a/core/res/res/values-mcc311-mnc180-in/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-in/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM tidak di-provisioning MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM tidak diizinkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Ponsel tidak diizinkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-is/strings.xml b/core/res/res/values-mcc311-mnc180-is/strings.xml
index 35966f7..bd6223b 100644
--- a/core/res/res/values-mcc311-mnc180-is/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-is/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-korti ekki úthlutað MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kort ekki leyft MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Sími ekki leyfður MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-it/strings.xml b/core/res/res/values-mcc311-mnc180-it/strings.xml
index 25f301b..7757a25 100644
--- a/core/res/res/values-mcc311-mnc180-it/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-it/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Scheda SIM non predisposta MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Scheda SIM non consentita MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefono non consentito MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-iw/strings.xml b/core/res/res/values-mcc311-mnc180-iw/strings.xml
index c6bdc14..dbb180b 100644
--- a/core/res/res/values-mcc311-mnc180-iw/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-iw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"‏הטלפון לא מורשה MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ja/strings.xml b/core/res/res/values-mcc311-mnc180-ja/strings.xml
index 6d30808..3defd2e 100644
--- a/core/res/res/values-mcc311-mnc180-ja/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ja/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM には対応していません(MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM は許可されていません(MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"電話は許可されていません(MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ka/strings.xml b/core/res/res/values-mcc311-mnc180-ka/strings.xml
index b86ce07..2fa76c4 100644
--- a/core/res/res/values-mcc311-mnc180-ka/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ka/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM ბარათი დაუშვებელია (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ტელეფონი დაუშვებელია MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-kk/strings.xml b/core/res/res/values-mcc311-mnc180-kk/strings.xml
index 539fbe4..91fd767 100644
--- a/core/res/res/values-mcc311-mnc180-kk/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-kk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM картасы қарастырылмаған MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM картасына рұқсат етілмеген MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Телефон пайдалануға болмайды MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-km/strings.xml b/core/res/res/values-mcc311-mnc180-km/strings.xml
index 970532e..c2f29a5 100644
--- a/core/res/res/values-mcc311-mnc180-km/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-km/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-kn/strings.xml b/core/res/res/values-mcc311-mnc180-kn/strings.xml
index 53a0419..08568fa 100644
--- a/core/res/res/values-mcc311-mnc180-kn/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-kn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ಫೋನ್ MM#6 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ko/strings.xml b/core/res/res/values-mcc311-mnc180-ko/strings.xml
index 01d6fec..b9bd3c8 100644
--- a/core/res/res/values-mcc311-mnc180-ko/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ko/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM이 프로비저닝되지 않음 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM이 허용되지 않음 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"전화가 허용되지 않음 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ky/strings.xml b/core/res/res/values-mcc311-mnc180-ky/strings.xml
index d8d58d9..305d81e 100644
--- a/core/res/res/values-mcc311-mnc180-ky/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ky/strings.xml
@@ -20,6 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM картаны колдонууга тыюу салынган MM#3"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM карта таанылган жок (MM#2)"</string>
+    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM картаны колдонууга тыюу салынган (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Телефонду колдонууга тыюу салынган MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-lo/strings.xml b/core/res/res/values-mcc311-mnc180-lo/strings.xml
index 5cbd1c8..f662b44 100644
--- a/core/res/res/values-mcc311-mnc180-lo/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-lo/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-lt/strings.xml b/core/res/res/values-mcc311-mnc180-lt/strings.xml
index 40a7e4a..fbffbae 100644
--- a/core/res/res/values-mcc311-mnc180-lt/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-lt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM kortelė neteikiama (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM kortelė neleidžiama (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefonas neleidžiamas (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-lv/strings.xml b/core/res/res/values-mcc311-mnc180-lv/strings.xml
index 74b6818..747b5ea 100644
--- a/core/res/res/values-mcc311-mnc180-lv/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-lv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM karte netiek nodrošināta: MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM karti nav atļauts izmantot: MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Tālruni nav atļauts izmantot: MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-mk/strings.xml b/core/res/res/values-mcc311-mnc180-mk/strings.xml
index 7db80fa..9077dc2 100644
--- a/core/res/res/values-mcc311-mnc180-mk/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-mk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Не е обезбедена SIM-картичка, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Не е дозволена SIM-картичка, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Телефонот не е дозволен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ml/strings.xml b/core/res/res/values-mcc311-mnc180-ml/strings.xml
index c31b9a7..fc23728 100644
--- a/core/res/res/values-mcc311-mnc180-ml/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ml/strings.xml
@@ -20,6 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"സിം MM#2 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
+    <string name="mmcc_illegal_ms" msgid="97745044956236881">"സിം MM#3 അനുവദിച്ചിട്ടില്ല"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ഫോൺ അനുവദനീയമല്ല MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-mn/strings.xml b/core/res/res/values-mcc311-mnc180-mn/strings.xml
index 1be055c..4960154 100644
--- a/core/res/res/values-mcc311-mnc180-mn/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-mn/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Утсыг зөвшөөрөөгүй MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-mr/strings.xml b/core/res/res/values-mcc311-mnc180-mr/strings.xml
index f8e08ae..f6886fe 100644
--- a/core/res/res/values-mcc311-mnc180-mr/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-mr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"फोन MM#6 ला अनुमती देत नाही"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ms/strings.xml b/core/res/res/values-mcc311-mnc180-ms/strings.xml
index 305a10d..222d346 100644
--- a/core/res/res/values-mcc311-mnc180-ms/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ms/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM tidak diperuntukkan MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM tidak dibenarkan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefon tidak dibenarkan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-my/strings.xml b/core/res/res/values-mcc311-mnc180-my/strings.xml
index 306c0dd..d68c8ba 100644
--- a/core/res/res/values-mcc311-mnc180-my/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-my/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-nb/strings.xml b/core/res/res/values-mcc311-mnc180-nb/strings.xml
index e1296f4..d2c4758 100644
--- a/core/res/res/values-mcc311-mnc180-nb/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-nb/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kortet er ikke klargjort, MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kortet er ikke tillatt, MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefonen er ikke tillatt, MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ne/strings.xml b/core/res/res/values-mcc311-mnc180-ne/strings.xml
index 6177a83..f98b5b5 100644
--- a/core/res/res/values-mcc311-mnc180-ne/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ne/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM को प्रावधान छैन MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM लाई अनुमति छैन MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"फोनलाई अनुमति छैन MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-nl/strings.xml b/core/res/res/values-mcc311-mnc180-nl/strings.xml
index 3f12e64..fbfd787 100644
--- a/core/res/res/values-mcc311-mnc180-nl/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-nl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Simkaart niet geregistreerd MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Simkaart niet toegestaan MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefoon niet toegestaan MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-pa/strings.xml b/core/res/res/values-mcc311-mnc180-pa/strings.xml
new file mode 100644
index 0000000..3e69e8b
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc180-pa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"ਸਿਮ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="97745044956236881">"ਸਿਮ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ਫ਼ੋਨ ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc180-pl/strings.xml b/core/res/res/values-mcc311-mnc180-pl/strings.xml
index 0744491..296000e3 100644
--- a/core/res/res/values-mcc311-mnc180-pl/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-pl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"MM#2 – karta SIM nieobsługiwana"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"MM#3 – niedozwolona karta SIM"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"MM#6 – telefon niedozwolony"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-pt-rBR/strings.xml b/core/res/res/values-mcc311-mnc180-pt-rBR/strings.xml
index c4d2240..637a91c 100644
--- a/core/res/res/values-mcc311-mnc180-pt-rBR/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-pt-rBR/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-pt-rPT/strings.xml b/core/res/res/values-mcc311-mnc180-pt-rPT/strings.xml
index c4d2240..7938a5f 100644
--- a/core/res/res/values-mcc311-mnc180-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-pt-rPT/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telemóvel não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-pt/strings.xml b/core/res/res/values-mcc311-mnc180-pt/strings.xml
index c4d2240..637a91c 100644
--- a/core/res/res/values-mcc311-mnc180-pt/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-pt/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM não aprovisionado MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM não permitido MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Smartphone não permitido MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ro/strings.xml b/core/res/res/values-mcc311-mnc180-ro/strings.xml
index 68cab29..c5126e7 100644
--- a/core/res/res/values-mcc311-mnc180-ro/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ro/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Cardul SIM nu este activat MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Cardul SIM nu este permis MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefonul nu este permis MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ru/strings.xml b/core/res/res/values-mcc311-mnc180-ru/strings.xml
index 90a3a09..a6f6785 100644
--- a/core/res/res/values-mcc311-mnc180-ru/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ru/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-карта не активирована (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Использование SIM-карты запрещено (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Звонки запрещены (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-si/strings.xml b/core/res/res/values-mcc311-mnc180-si/strings.xml
index 1907d3e..b9ef425 100644
--- a/core/res/res/values-mcc311-mnc180-si/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-si/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM MM#3 ඉඩ නොදේ"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-sk/strings.xml b/core/res/res/values-mcc311-mnc180-sk/strings.xml
index a456431..ecd9222 100644
--- a/core/res/res/values-mcc311-mnc180-sk/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-sk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM karta nie je k dispozícii – MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM karta je zakázaná – MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefón nie je povolený (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-sl/strings.xml b/core/res/res/values-mcc311-mnc180-sl/strings.xml
index 454a1cd..33d9621 100644
--- a/core/res/res/values-mcc311-mnc180-sl/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-sl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Kartica SIM ni omogočena za uporabo MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Kartica SIM ni dovoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefon ni dovoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-sq/strings.xml b/core/res/res/values-mcc311-mnc180-sq/strings.xml
index 23da1a3..b5b28fa 100644
--- a/core/res/res/values-mcc311-mnc180-sq/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-sq/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Karta SIM nuk është dhënë MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Karta SIM nuk lejohet MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefoni nuk lejohet MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-sr/strings.xml b/core/res/res/values-mcc311-mnc180-sr/strings.xml
index 182a7bc..e8b6017 100644
--- a/core/res/res/values-mcc311-mnc180-sr/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-sr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM картица није подешена MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Телефон није дозвољен MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-sv/strings.xml b/core/res/res/values-mcc311-mnc180-sv/strings.xml
index fee7a1f..9ca48e0c 100644
--- a/core/res/res/values-mcc311-mnc180-sv/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-sv/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kort tillhandahålls inte MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kort tillåts inte MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Mobil tillåts inte MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-sw/strings.xml b/core/res/res/values-mcc311-mnc180-sw/strings.xml
index e49b3d1..5b76485 100644
--- a/core/res/res/values-mcc311-mnc180-sw/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-sw/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM haitumiki MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM hairuhusiwi MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Simu hairuhusiwi MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ta/strings.xml b/core/res/res/values-mcc311-mnc180-ta/strings.xml
index 6c11c4f..9242b4d 100644
--- a/core/res/res/values-mcc311-mnc180-ta/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ta/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"சிம் அமைக்கப்படவில்லை MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ஃபோன் அனுமதிக்கப்படவில்லை MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-te/strings.xml b/core/res/res/values-mcc311-mnc180-te/strings.xml
new file mode 100644
index 0000000..90fe4ca
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc180-te/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM MM#2ని సక్రియం చేయలేదు"</string>
+    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM MM#3ని అనుమతించలేదు"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc180-th/strings.xml b/core/res/res/values-mcc311-mnc180-th/strings.xml
index be4b08e..d587bcd 100644
--- a/core/res/res/values-mcc311-mnc180-th/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-th/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"ไม่มีการจัดสรรซิม MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-tl/strings.xml b/core/res/res/values-mcc311-mnc180-tl/strings.xml
index 6aacf16..963db42 100644
--- a/core/res/res/values-mcc311-mnc180-tl/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-tl/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Hindi na-provision ang SIM MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"Hindi pinapahintulutan ang SIM MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Hindi pinapahintulutan ang telepono MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-tr/strings.xml b/core/res/res/values-mcc311-mnc180-tr/strings.xml
index cf4fd77..28280f0 100644
--- a/core/res/res/values-mcc311-mnc180-tr/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-tr/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM MM#3\'e izin vermiyor"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Telefona izin verilmiyor MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-uk/strings.xml b/core/res/res/values-mcc311-mnc180-uk/strings.xml
index fae40ac..00b22d9 100644
--- a/core/res/res/values-mcc311-mnc180-uk/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-uk/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-карту не надано (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-карта заборонена (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Телефон заборонено (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-ur/strings.xml b/core/res/res/values-mcc311-mnc180-ur/strings.xml
index ebceb5e..a9685c4 100644
--- a/core/res/res/values-mcc311-mnc180-ur/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-ur/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"‏SIM کی اجازت نہیں ہے MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"‏فون کی اجازت نہیں ہے MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-uz/strings.xml b/core/res/res/values-mcc311-mnc180-uz/strings.xml
index ebcdd3b..c6f9b37 100644
--- a/core/res/res/values-mcc311-mnc180-uz/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-uz/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Chaqiruvlar taqiqlangan (MM#6)"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-vi/strings.xml b/core/res/res/values-mcc311-mnc180-vi/strings.xml
index 0d7ff96..b5a6567 100644
--- a/core/res/res/values-mcc311-mnc180-vi/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-vi/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM không được cấp phép MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM không được phép MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Không cho phép điện thoại MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-zh-rCN/strings.xml b/core/res/res/values-mcc311-mnc180-zh-rCN/strings.xml
index d8ff182..cd27edf 100644
--- a/core/res/res/values-mcc311-mnc180-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-zh-rCN/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"未配置的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"不被允许的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"不受允许的手机 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-zh-rHK/strings.xml b/core/res/res/values-mcc311-mnc180-zh-rHK/strings.xml
index 14332bf..9f2f8b9 100644
--- a/core/res/res/values-mcc311-mnc180-zh-rHK/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-zh-rHK/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM 卡不允許 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"不允許手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-zh-rTW/strings.xml b/core/res/res/values-mcc311-mnc180-zh-rTW/strings.xml
index 775a70b..9336296 100644
--- a/core/res/res/values-mcc311-mnc180-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-zh-rTW/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"未佈建的 SIM 卡 MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"不支援的 SIM 卡 MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"不支援的手機 MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-zu/strings.xml b/core/res/res/values-mcc311-mnc180-zu/strings.xml
index a66760f..5708a22 100644
--- a/core/res/res/values-mcc311-mnc180-zu/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-zu/strings.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"I-SIM ayinikezelwe MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="97745044956236881">"I-SIM ayivunyelwe MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="5766888847785331904">"Ifoni ayivunyelwe MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180/strings.xml b/core/res/res/values-mcc311-mnc180/strings.xml
index a3fea29..6a404d5 100644
--- a/core/res/res/values-mcc311-mnc180/strings.xml
+++ b/core/res/res/values-mcc311-mnc180/strings.xml
@@ -20,4 +20,5 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string>
     <string name="mmcc_illegal_ms">SIM not allowed MM#3</string>
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
 </resources>
diff --git a/core/res/res/values-mcc312-mnc670-af/strings.xml b/core/res/res/values-mcc312-mnc670-af/strings.xml
new file mode 100644
index 0000000..8884326
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-af/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Foon nie toegelaat nie MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-am/strings.xml b/core/res/res/values-mcc312-mnc670-am/strings.xml
new file mode 100644
index 0000000..26c082b
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-am/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"ስልክ አይፈቀድም MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-ar/strings.xml b/core/res/res/values-mcc312-mnc670-ar/strings.xml
new file mode 100644
index 0000000..133e2b0
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-ar/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"‏غير مسموح باستخدام الهاتف MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-az/strings.xml b/core/res/res/values-mcc312-mnc670-az/strings.xml
new file mode 100644
index 0000000..80a1926
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-az/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"MM#6 telefonu dəstəklənmir"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-bg/strings.xml b/core/res/res/values-mcc312-mnc670-bg/strings.xml
new file mode 100644
index 0000000..98a60c5
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-bg/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Телефонът не е разрешен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-bn/strings.xml b/core/res/res/values-mcc312-mnc670-bn/strings.xml
new file mode 100644
index 0000000..6b5a1d0
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-bn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"ফোন অনুমোদিত নয় MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-ca/strings.xml b/core/res/res/values-mcc312-mnc670-ca/strings.xml
new file mode 100644
index 0000000..adaa2ba
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-ca/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telèfon no compatible MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-cs/strings.xml b/core/res/res/values-mcc312-mnc670-cs/strings.xml
new file mode 100644
index 0000000..b88b619
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-cs/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefon není povolen (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-da/strings.xml b/core/res/res/values-mcc312-mnc670-da/strings.xml
new file mode 100644
index 0000000..50fdbd4
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-da/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefonen har ikke adgangstilladelse MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-de/strings.xml b/core/res/res/values-mcc312-mnc670-de/strings.xml
new file mode 100644
index 0000000..18b33e5
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-de/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Smartphone nicht zulässig MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-el/strings.xml b/core/res/res/values-mcc312-mnc670-el/strings.xml
new file mode 100644
index 0000000..22ea1db
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-el/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-en-rAU/strings.xml b/core/res/res/values-mcc312-mnc670-en-rAU/strings.xml
new file mode 100644
index 0000000..3eb880a
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-en-rAU/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-en-rGB/strings.xml b/core/res/res/values-mcc312-mnc670-en-rGB/strings.xml
new file mode 100644
index 0000000..3eb880a
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-en-rGB/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-en-rIN/strings.xml b/core/res/res/values-mcc312-mnc670-en-rIN/strings.xml
new file mode 100644
index 0000000..3eb880a
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-en-rIN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-es-rUS/strings.xml b/core/res/res/values-mcc312-mnc670-es-rUS/strings.xml
new file mode 100644
index 0000000..89b28f5
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-es-rUS/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-es/strings.xml b/core/res/res/values-mcc312-mnc670-es/strings.xml
new file mode 100644
index 0000000..89b28f5
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-es/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-et/strings.xml b/core/res/res/values-mcc312-mnc670-et/strings.xml
new file mode 100644
index 0000000..1ed4b41
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-et/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefon pole lubatud MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-eu/strings.xml b/core/res/res/values-mcc312-mnc670-eu/strings.xml
new file mode 100644
index 0000000..8f0daba
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-eu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefonoa ez da onartzen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-fa/strings.xml b/core/res/res/values-mcc312-mnc670-fa/strings.xml
new file mode 100644
index 0000000..bd87bdf
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-fa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"‏تلفن مجاز نیست MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-fi/strings.xml b/core/res/res/values-mcc312-mnc670-fi/strings.xml
new file mode 100644
index 0000000..5ec33a3
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-fi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Puhelin estetty MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-fr-rCA/strings.xml b/core/res/res/values-mcc312-mnc670-fr-rCA/strings.xml
new file mode 100644
index 0000000..2110dda
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-fr-rCA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-fr/strings.xml b/core/res/res/values-mcc312-mnc670-fr/strings.xml
new file mode 100644
index 0000000..2110dda
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-fr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-gl/strings.xml b/core/res/res/values-mcc312-mnc670-gl/strings.xml
new file mode 100644
index 0000000..dc66c1d
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-gl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Non se admite o teléfono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-gu/strings.xml b/core/res/res/values-mcc312-mnc670-gu/strings.xml
new file mode 100644
index 0000000..bc0db0b
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-gu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"MM#6 ફોનની મંજૂરી નથી"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-hi/strings.xml b/core/res/res/values-mcc312-mnc670-hi/strings.xml
new file mode 100644
index 0000000..1db4db2
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-hi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"फ़ोन की इजाज़त नहीं है MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-hr/strings.xml b/core/res/res/values-mcc312-mnc670-hr/strings.xml
new file mode 100644
index 0000000..e3b49c9
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-hr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefon nije dopušten MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-hu/strings.xml b/core/res/res/values-mcc312-mnc670-hu/strings.xml
new file mode 100644
index 0000000..85b947c
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-hu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"A telefon nem engedélyezett (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-hy/strings.xml b/core/res/res/values-mcc312-mnc670-hy/strings.xml
new file mode 100644
index 0000000..bc39d50
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-hy/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-in/strings.xml b/core/res/res/values-mcc312-mnc670-in/strings.xml
new file mode 100644
index 0000000..0f526dd
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-in/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Ponsel tidak diizinkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-is/strings.xml b/core/res/res/values-mcc312-mnc670-is/strings.xml
new file mode 100644
index 0000000..cad2282
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-is/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Sími ekki leyfður MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-it/strings.xml b/core/res/res/values-mcc312-mnc670-it/strings.xml
new file mode 100644
index 0000000..1763bdc
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-it/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefono non consentito MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-iw/strings.xml b/core/res/res/values-mcc312-mnc670-iw/strings.xml
new file mode 100644
index 0000000..a042e10
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-iw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"‏הטלפון לא מורשה MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-ja/strings.xml b/core/res/res/values-mcc312-mnc670-ja/strings.xml
new file mode 100644
index 0000000..c5de3af
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-ja/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"電話は許可されていません(MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-ka/strings.xml b/core/res/res/values-mcc312-mnc670-ka/strings.xml
new file mode 100644
index 0000000..a2c7b8a
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-ka/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"ტელეფონი დაუშვებელია MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-kk/strings.xml b/core/res/res/values-mcc312-mnc670-kk/strings.xml
new file mode 100644
index 0000000..1ac2314
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-kk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Телефон пайдалануға болмайды MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-km/strings.xml b/core/res/res/values-mcc312-mnc670-km/strings.xml
new file mode 100644
index 0000000..8786411
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-km/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-kn/strings.xml b/core/res/res/values-mcc312-mnc670-kn/strings.xml
new file mode 100644
index 0000000..581fe17
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-kn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"ಫೋನ್ MM#6 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-ko/strings.xml b/core/res/res/values-mcc312-mnc670-ko/strings.xml
new file mode 100644
index 0000000..fcd98f9
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-ko/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"전화가 허용되지 않음 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-ky/strings.xml b/core/res/res/values-mcc312-mnc670-ky/strings.xml
new file mode 100644
index 0000000..ed830f6
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-ky/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Телефонду колдонууга тыюу салынган MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-lo/strings.xml b/core/res/res/values-mcc312-mnc670-lo/strings.xml
new file mode 100644
index 0000000..04bb1c9
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-lo/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-lt/strings.xml b/core/res/res/values-mcc312-mnc670-lt/strings.xml
new file mode 100644
index 0000000..c416a9a
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-lt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefonas neleidžiamas (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-lv/strings.xml b/core/res/res/values-mcc312-mnc670-lv/strings.xml
new file mode 100644
index 0000000..dfed609
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-lv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Tālruni nav atļauts izmantot: MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-mk/strings.xml b/core/res/res/values-mcc312-mnc670-mk/strings.xml
new file mode 100644
index 0000000..0bf51cc
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-mk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Телефонот не е дозволен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-ml/strings.xml b/core/res/res/values-mcc312-mnc670-ml/strings.xml
new file mode 100644
index 0000000..78dc1ec
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-ml/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"ഫോൺ അനുവദനീയമല്ല MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-mn/strings.xml b/core/res/res/values-mcc312-mnc670-mn/strings.xml
new file mode 100644
index 0000000..682cf86
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-mn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Утсыг зөвшөөрөөгүй MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-mr/strings.xml b/core/res/res/values-mcc312-mnc670-mr/strings.xml
new file mode 100644
index 0000000..b9dd523
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-mr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"फोन MM#6 ला अनुमती देत नाही"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-ms/strings.xml b/core/res/res/values-mcc312-mnc670-ms/strings.xml
new file mode 100644
index 0000000..3e807a0
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-ms/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefon tidak dibenarkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-my/strings.xml b/core/res/res/values-mcc312-mnc670-my/strings.xml
new file mode 100644
index 0000000..292e8db
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-my/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-nb/strings.xml b/core/res/res/values-mcc312-mnc670-nb/strings.xml
new file mode 100644
index 0000000..431fda6
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-nb/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefonen er ikke tillatt, MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-ne/strings.xml b/core/res/res/values-mcc312-mnc670-ne/strings.xml
new file mode 100644
index 0000000..ce2ce77
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-ne/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"फोनलाई अनुमति छैन MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-nl/strings.xml b/core/res/res/values-mcc312-mnc670-nl/strings.xml
new file mode 100644
index 0000000..d7eb032
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-nl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefoon niet toegestaan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-pa/strings.xml b/core/res/res/values-mcc312-mnc670-pa/strings.xml
new file mode 100644
index 0000000..6b98d49
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-pa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"ਫ਼ੋਨ ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-pl/strings.xml b/core/res/res/values-mcc312-mnc670-pl/strings.xml
new file mode 100644
index 0000000..dd39c79
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-pl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"MM#6 – telefon niedozwolony"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-pt-rBR/strings.xml b/core/res/res/values-mcc312-mnc670-pt-rBR/strings.xml
new file mode 100644
index 0000000..bb58d18
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-pt-rBR/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-pt-rPT/strings.xml b/core/res/res/values-mcc312-mnc670-pt-rPT/strings.xml
new file mode 100644
index 0000000..f04d740
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-pt-rPT/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telemóvel não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-pt/strings.xml b/core/res/res/values-mcc312-mnc670-pt/strings.xml
new file mode 100644
index 0000000..bb58d18
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-pt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-ro/strings.xml b/core/res/res/values-mcc312-mnc670-ro/strings.xml
new file mode 100644
index 0000000..3129943
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-ro/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefonul nu este permis MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-ru/strings.xml b/core/res/res/values-mcc312-mnc670-ru/strings.xml
new file mode 100644
index 0000000..46080e0
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-ru/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Звонки запрещены (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-si/strings.xml b/core/res/res/values-mcc312-mnc670-si/strings.xml
new file mode 100644
index 0000000..6fdac6b
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-si/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-sk/strings.xml b/core/res/res/values-mcc312-mnc670-sk/strings.xml
new file mode 100644
index 0000000..c717019
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-sk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefón nie je povolený (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-sl/strings.xml b/core/res/res/values-mcc312-mnc670-sl/strings.xml
new file mode 100644
index 0000000..15c7670
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-sl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefon ni dovoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-sq/strings.xml b/core/res/res/values-mcc312-mnc670-sq/strings.xml
new file mode 100644
index 0000000..5c97026
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-sq/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefoni nuk lejohet MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-sr/strings.xml b/core/res/res/values-mcc312-mnc670-sr/strings.xml
new file mode 100644
index 0000000..9fdf70d
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-sr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Телефон није дозвољен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-sv/strings.xml b/core/res/res/values-mcc312-mnc670-sv/strings.xml
new file mode 100644
index 0000000..0f9d454
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-sv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Mobil tillåts inte MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-sw/strings.xml b/core/res/res/values-mcc312-mnc670-sw/strings.xml
new file mode 100644
index 0000000..e2c461e
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-sw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Simu hairuhusiwi MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-ta/strings.xml b/core/res/res/values-mcc312-mnc670-ta/strings.xml
new file mode 100644
index 0000000..2c56a7e
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-ta/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"ஃபோன் அனுமதிக்கப்படவில்லை MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-te/strings.xml b/core/res/res/values-mcc312-mnc670-te/strings.xml
new file mode 100644
index 0000000..f9bd60a
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-te/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-th/strings.xml b/core/res/res/values-mcc312-mnc670-th/strings.xml
new file mode 100644
index 0000000..b144ca3
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-th/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-tl/strings.xml b/core/res/res/values-mcc312-mnc670-tl/strings.xml
new file mode 100644
index 0000000..79b88ec
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-tl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Hindi pinapahintulutan ang telepono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-tr/strings.xml b/core/res/res/values-mcc312-mnc670-tr/strings.xml
new file mode 100644
index 0000000..1e3dcea
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-tr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Telefona izin verilmiyor MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-uk/strings.xml b/core/res/res/values-mcc312-mnc670-uk/strings.xml
new file mode 100644
index 0000000..d2dd817
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-uk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Телефон заборонено (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-ur/strings.xml b/core/res/res/values-mcc312-mnc670-ur/strings.xml
new file mode 100644
index 0000000..f7ef38c
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-ur/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"‏فون کی اجازت نہیں ہے MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-uz/strings.xml b/core/res/res/values-mcc312-mnc670-uz/strings.xml
new file mode 100644
index 0000000..4bf0f74
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-uz/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Chaqiruvlar taqiqlangan (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-vi/strings.xml b/core/res/res/values-mcc312-mnc670-vi/strings.xml
new file mode 100644
index 0000000..4bae4af
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-vi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Không cho phép điện thoại MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-zh-rCN/strings.xml b/core/res/res/values-mcc312-mnc670-zh-rCN/strings.xml
new file mode 100644
index 0000000..317531a
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-zh-rCN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"不受允许的手机 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-zh-rHK/strings.xml b/core/res/res/values-mcc312-mnc670-zh-rHK/strings.xml
new file mode 100644
index 0000000..bef6362
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-zh-rHK/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"不允許手機 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-zh-rTW/strings.xml b/core/res/res/values-mcc312-mnc670-zh-rTW/strings.xml
new file mode 100644
index 0000000..1fa82ed
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-zh-rTW/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"不支援的手機 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670-zu/strings.xml b/core/res/res/values-mcc312-mnc670-zu/strings.xml
new file mode 100644
index 0000000..35c2cbf
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670-zu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="3649306773478362802">"Ifoni ayivunyelwe MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc670/strings.xml b/core/res/res/values-mcc312-mnc670/strings.xml
new file mode 100644
index 0000000..96af975
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc670/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-af/strings.xml b/core/res/res/values-mcc313-mnc100-af/strings.xml
new file mode 100644
index 0000000..7645fc8
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-af/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Foon nie toegelaat nie MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-am/strings.xml b/core/res/res/values-mcc313-mnc100-am/strings.xml
new file mode 100644
index 0000000..b76ed04
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-am/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"ስልክ አይፈቀድም MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-ar/strings.xml b/core/res/res/values-mcc313-mnc100-ar/strings.xml
new file mode 100644
index 0000000..640fb8a
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-ar/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"‏غير مسموح باستخدام الهاتف MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-az/strings.xml b/core/res/res/values-mcc313-mnc100-az/strings.xml
new file mode 100644
index 0000000..44796df
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-az/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"MM#6 telefonu dəstəklənmir"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-bg/strings.xml b/core/res/res/values-mcc313-mnc100-bg/strings.xml
new file mode 100644
index 0000000..8c946ed
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-bg/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Телефонът не е разрешен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-bn/strings.xml b/core/res/res/values-mcc313-mnc100-bn/strings.xml
new file mode 100644
index 0000000..5292241
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-bn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"ফোন অনুমোদিত নয় MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-ca/strings.xml b/core/res/res/values-mcc313-mnc100-ca/strings.xml
new file mode 100644
index 0000000..f6846cb
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-ca/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telèfon no compatible MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-cs/strings.xml b/core/res/res/values-mcc313-mnc100-cs/strings.xml
new file mode 100644
index 0000000..4e57d15
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-cs/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefon není povolen (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-da/strings.xml b/core/res/res/values-mcc313-mnc100-da/strings.xml
new file mode 100644
index 0000000..c00d95c
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-da/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefonen har ikke adgangstilladelse MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-de/strings.xml b/core/res/res/values-mcc313-mnc100-de/strings.xml
new file mode 100644
index 0000000..df08b13
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-de/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Smartphone nicht zulässig MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-el/strings.xml b/core/res/res/values-mcc313-mnc100-el/strings.xml
new file mode 100644
index 0000000..0fcb42e
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-el/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Το τηλέφωνο δεν επιτρέπεται MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-en-rAU/strings.xml b/core/res/res/values-mcc313-mnc100-en-rAU/strings.xml
new file mode 100644
index 0000000..f1a3611
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-en-rAU/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-en-rGB/strings.xml b/core/res/res/values-mcc313-mnc100-en-rGB/strings.xml
new file mode 100644
index 0000000..f1a3611
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-en-rGB/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-en-rIN/strings.xml b/core/res/res/values-mcc313-mnc100-en-rIN/strings.xml
new file mode 100644
index 0000000..f1a3611
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-en-rIN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Phone not allowed MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-es-rUS/strings.xml b/core/res/res/values-mcc313-mnc100-es-rUS/strings.xml
new file mode 100644
index 0000000..122d4b9
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-es-rUS/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-es/strings.xml b/core/res/res/values-mcc313-mnc100-es/strings.xml
new file mode 100644
index 0000000..122d4b9
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-es/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Teléfono no admitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-et/strings.xml b/core/res/res/values-mcc313-mnc100-et/strings.xml
new file mode 100644
index 0000000..83cfbaf
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-et/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefon pole lubatud MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-eu/strings.xml b/core/res/res/values-mcc313-mnc100-eu/strings.xml
new file mode 100644
index 0000000..028ca37
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-eu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefonoa ez da onartzen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-fa/strings.xml b/core/res/res/values-mcc313-mnc100-fa/strings.xml
new file mode 100644
index 0000000..f29da6b
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-fa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"‏تلفن مجاز نیست MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-fi/strings.xml b/core/res/res/values-mcc313-mnc100-fi/strings.xml
new file mode 100644
index 0000000..f64a38a
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-fi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Puhelin estetty MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-fr-rCA/strings.xml b/core/res/res/values-mcc313-mnc100-fr-rCA/strings.xml
new file mode 100644
index 0000000..89c50ea
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-fr-rCA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-fr/strings.xml b/core/res/res/values-mcc313-mnc100-fr/strings.xml
new file mode 100644
index 0000000..89c50ea
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-fr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Téléphone non autorisé MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-gl/strings.xml b/core/res/res/values-mcc313-mnc100-gl/strings.xml
new file mode 100644
index 0000000..04390a0
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-gl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Non se admite o teléfono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-gu/strings.xml b/core/res/res/values-mcc313-mnc100-gu/strings.xml
new file mode 100644
index 0000000..6291d57
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-gu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"MM#6 ફોનની મંજૂરી નથી"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-hi/strings.xml b/core/res/res/values-mcc313-mnc100-hi/strings.xml
new file mode 100644
index 0000000..f31e6bf
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-hi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"फ़ोन की इजाज़त नहीं है MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-hr/strings.xml b/core/res/res/values-mcc313-mnc100-hr/strings.xml
new file mode 100644
index 0000000..290e92b
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-hr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefon nije dopušten MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-hu/strings.xml b/core/res/res/values-mcc313-mnc100-hu/strings.xml
new file mode 100644
index 0000000..31605dd
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-hu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"A telefon nem engedélyezett (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-hy/strings.xml b/core/res/res/values-mcc313-mnc100-hy/strings.xml
new file mode 100644
index 0000000..62acde3
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-hy/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Հեռախոսի օգտագործումն արգելված է (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-in/strings.xml b/core/res/res/values-mcc313-mnc100-in/strings.xml
new file mode 100644
index 0000000..d95657f
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-in/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Ponsel tidak diizinkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-is/strings.xml b/core/res/res/values-mcc313-mnc100-is/strings.xml
new file mode 100644
index 0000000..3ad7b3c
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-is/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Sími ekki leyfður MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-it/strings.xml b/core/res/res/values-mcc313-mnc100-it/strings.xml
new file mode 100644
index 0000000..1d3deeb
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-it/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefono non consentito MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-iw/strings.xml b/core/res/res/values-mcc313-mnc100-iw/strings.xml
new file mode 100644
index 0000000..383e3d1
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-iw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"‏הטלפון לא מורשה MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-ja/strings.xml b/core/res/res/values-mcc313-mnc100-ja/strings.xml
new file mode 100644
index 0000000..6a89e3d
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-ja/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"電話は許可されていません(MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-ka/strings.xml b/core/res/res/values-mcc313-mnc100-ka/strings.xml
new file mode 100644
index 0000000..a063fc4
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-ka/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"ტელეფონი დაუშვებელია MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-kk/strings.xml b/core/res/res/values-mcc313-mnc100-kk/strings.xml
new file mode 100644
index 0000000..0562a2f
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-kk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Телефон пайдалануға болмайды MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-km/strings.xml b/core/res/res/values-mcc313-mnc100-km/strings.xml
new file mode 100644
index 0000000..74e607b
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-km/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"មិន​អនុញ្ញាត​ចំពោះ​ទូរសព្ទ​ទេ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-kn/strings.xml b/core/res/res/values-mcc313-mnc100-kn/strings.xml
new file mode 100644
index 0000000..e287270
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-kn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"ಫೋನ್ MM#6 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-ko/strings.xml b/core/res/res/values-mcc313-mnc100-ko/strings.xml
new file mode 100644
index 0000000..fbe222b
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-ko/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"전화가 허용되지 않음 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-ky/strings.xml b/core/res/res/values-mcc313-mnc100-ky/strings.xml
new file mode 100644
index 0000000..8c08c4f
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-ky/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Телефонду колдонууга тыюу салынган MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-lo/strings.xml b/core/res/res/values-mcc313-mnc100-lo/strings.xml
new file mode 100644
index 0000000..793b87b
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-lo/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ໂທລະສັບ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-lt/strings.xml b/core/res/res/values-mcc313-mnc100-lt/strings.xml
new file mode 100644
index 0000000..5edc6bf
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-lt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefonas neleidžiamas (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-lv/strings.xml b/core/res/res/values-mcc313-mnc100-lv/strings.xml
new file mode 100644
index 0000000..de1ad9c
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-lv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Tālruni nav atļauts izmantot: MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-mk/strings.xml b/core/res/res/values-mcc313-mnc100-mk/strings.xml
new file mode 100644
index 0000000..0b403e9
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-mk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Телефонот не е дозволен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-ml/strings.xml b/core/res/res/values-mcc313-mnc100-ml/strings.xml
new file mode 100644
index 0000000..1adc455
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-ml/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"ഫോൺ അനുവദനീയമല്ല MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-mn/strings.xml b/core/res/res/values-mcc313-mnc100-mn/strings.xml
new file mode 100644
index 0000000..5d5fbff
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-mn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Утсыг зөвшөөрөөгүй MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-mr/strings.xml b/core/res/res/values-mcc313-mnc100-mr/strings.xml
new file mode 100644
index 0000000..32c6946
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-mr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"फोन MM#6 ला अनुमती देत नाही"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-ms/strings.xml b/core/res/res/values-mcc313-mnc100-ms/strings.xml
new file mode 100644
index 0000000..ebd1724
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-ms/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefon tidak dibenarkan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-my/strings.xml b/core/res/res/values-mcc313-mnc100-my/strings.xml
new file mode 100644
index 0000000..7de66f7
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-my/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"ဖုန်းကို ခွင့်မပြုပါ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-nb/strings.xml b/core/res/res/values-mcc313-mnc100-nb/strings.xml
new file mode 100644
index 0000000..84a7582
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-nb/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefonen er ikke tillatt, MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-ne/strings.xml b/core/res/res/values-mcc313-mnc100-ne/strings.xml
new file mode 100644
index 0000000..0fb9d64
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-ne/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"फोनलाई अनुमति छैन MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-nl/strings.xml b/core/res/res/values-mcc313-mnc100-nl/strings.xml
new file mode 100644
index 0000000..14e940d
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-nl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefoon niet toegestaan MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-pa/strings.xml b/core/res/res/values-mcc313-mnc100-pa/strings.xml
new file mode 100644
index 0000000..87b2e47
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-pa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"ਫ਼ੋਨ ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-pl/strings.xml b/core/res/res/values-mcc313-mnc100-pl/strings.xml
new file mode 100644
index 0000000..7df915c
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-pl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"MM#6 – telefon niedozwolony"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-pt-rBR/strings.xml b/core/res/res/values-mcc313-mnc100-pt-rBR/strings.xml
new file mode 100644
index 0000000..f80f618
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-pt-rBR/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-pt-rPT/strings.xml b/core/res/res/values-mcc313-mnc100-pt-rPT/strings.xml
new file mode 100644
index 0000000..35d4f58
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-pt-rPT/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telemóvel não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-pt/strings.xml b/core/res/res/values-mcc313-mnc100-pt/strings.xml
new file mode 100644
index 0000000..f80f618
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-pt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Smartphone não permitido MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-ro/strings.xml b/core/res/res/values-mcc313-mnc100-ro/strings.xml
new file mode 100644
index 0000000..57a455d
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-ro/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefonul nu este permis MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-ru/strings.xml b/core/res/res/values-mcc313-mnc100-ru/strings.xml
new file mode 100644
index 0000000..8edec35
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-ru/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Звонки запрещены (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-si/strings.xml b/core/res/res/values-mcc313-mnc100-si/strings.xml
new file mode 100644
index 0000000..9493af0b
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-si/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-sk/strings.xml b/core/res/res/values-mcc313-mnc100-sk/strings.xml
new file mode 100644
index 0000000..04a1a08
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-sk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefón nie je povolený (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-sl/strings.xml b/core/res/res/values-mcc313-mnc100-sl/strings.xml
new file mode 100644
index 0000000..e59c833
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-sl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefon ni dovoljen MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-sq/strings.xml b/core/res/res/values-mcc313-mnc100-sq/strings.xml
new file mode 100644
index 0000000..237a4a4
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-sq/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefoni nuk lejohet MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-sr/strings.xml b/core/res/res/values-mcc313-mnc100-sr/strings.xml
new file mode 100644
index 0000000..6d6c310
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-sr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Телефон није дозвољен MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-sv/strings.xml b/core/res/res/values-mcc313-mnc100-sv/strings.xml
new file mode 100644
index 0000000..145a960
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-sv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Mobil tillåts inte MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-sw/strings.xml b/core/res/res/values-mcc313-mnc100-sw/strings.xml
new file mode 100644
index 0000000..a7574fb
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-sw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Simu hairuhusiwi MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-ta/strings.xml b/core/res/res/values-mcc313-mnc100-ta/strings.xml
new file mode 100644
index 0000000..7ef5ea9
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-ta/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"ஃபோன் அனுமதிக்கப்படவில்லை MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-te/strings.xml b/core/res/res/values-mcc313-mnc100-te/strings.xml
new file mode 100644
index 0000000..8908fb7
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-te/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"ఫోన్ అనుమతించబడదు MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-th/strings.xml b/core/res/res/values-mcc313-mnc100-th/strings.xml
new file mode 100644
index 0000000..e562744
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-th/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"ไม่อนุญาตให้ใช้โทรศัพท์ MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-tl/strings.xml b/core/res/res/values-mcc313-mnc100-tl/strings.xml
new file mode 100644
index 0000000..6da1dbd
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-tl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Hindi pinapahintulutan ang telepono MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-tr/strings.xml b/core/res/res/values-mcc313-mnc100-tr/strings.xml
new file mode 100644
index 0000000..7200666
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-tr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Telefona izin verilmiyor MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-uk/strings.xml b/core/res/res/values-mcc313-mnc100-uk/strings.xml
new file mode 100644
index 0000000..833f9b1
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-uk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Телефон заборонено (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-ur/strings.xml b/core/res/res/values-mcc313-mnc100-ur/strings.xml
new file mode 100644
index 0000000..d670d0e
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-ur/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"‏فون کی اجازت نہیں ہے MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-uz/strings.xml b/core/res/res/values-mcc313-mnc100-uz/strings.xml
new file mode 100644
index 0000000..202a30c
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-uz/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Chaqiruvlar taqiqlangan (MM#6)"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-vi/strings.xml b/core/res/res/values-mcc313-mnc100-vi/strings.xml
new file mode 100644
index 0000000..6a8c752
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-vi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Không cho phép điện thoại MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-zh-rCN/strings.xml b/core/res/res/values-mcc313-mnc100-zh-rCN/strings.xml
new file mode 100644
index 0000000..056a75a
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-zh-rCN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"不受允许的手机 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-zh-rHK/strings.xml b/core/res/res/values-mcc313-mnc100-zh-rHK/strings.xml
new file mode 100644
index 0000000..db85730
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-zh-rHK/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"不允許手機 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-zh-rTW/strings.xml b/core/res/res/values-mcc313-mnc100-zh-rTW/strings.xml
new file mode 100644
index 0000000..c907e39
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-zh-rTW/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"不支援的手機 MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100-zu/strings.xml b/core/res/res/values-mcc313-mnc100-zu/strings.xml
new file mode 100644
index 0000000..1794f82
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100-zu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** 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="mmcc_illegal_me" msgid="7320955531336937252">"Ifoni ayivunyelwe MM#6"</string>
+</resources>
diff --git a/core/res/res/values-mcc313-mnc100/strings.xml b/core/res/res/values-mcc313-mnc100/strings.xml
new file mode 100644
index 0000000..96af975
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="mmcc_illegal_me">Phone not allowed MM#6</string>
+</resources>
diff --git a/core/res/res/values-mcc404/config.xml b/core/res/res/values-mcc404/config.xml
index 6b77e9c..4cadef7 100644
--- a/core/res/res/values-mcc404/config.xml
+++ b/core/res/res/values-mcc404/config.xml
@@ -20,4 +20,6 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Whether camera shutter sound is forced or not  (country specific). -->
     <bool name="config_camera_sound_forced">true</bool>
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">true</bool>
 </resources>
diff --git a/core/res/res/values-mcc505-mnc01/config.xml b/core/res/res/values-mcc505-mnc01/config.xml
index ff06585..5a5b8f7 100644
--- a/core/res/res/values-mcc505-mnc01/config.xml
+++ b/core/res/res/values-mcc505-mnc01/config.xml
@@ -31,15 +31,6 @@
       <item>9</item>
     </integer-array>
 
-    <!-- String containing the apn value for tethering.  May be overriden by secure settings
-         TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
-         Or string format of ApnSettingV3.
-         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string-array translatable="false" name="config_tether_apndata">
-      <item>Telstra Tethering,telstra.internet,,,,,,,,,505,01,,DUN</item>
-    </string-array>
-
     <!--Thresholds for LTE dbm in status bar-->
     <integer-array translatable="false" name="config_lteDbmThresholds">
         <item>-140</item>    <!-- SIGNAL_STRENGTH_NONE_OR_UNKNOWN -->
diff --git a/core/res/res/values-mcc724/config.xml b/core/res/res/values-mcc724/config.xml
new file mode 100644
index 0000000..98f70d5
--- /dev/null
+++ b/core/res/res/values-mcc724/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index d1b3916..b88d1b9 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Пребарување за услуга"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Повикување преку Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"За повикување и испраќање пораки преку Wi-Fi, прво побарајте од операторот да ви ја постави оваа услуга. Потоа повторно вклучете повикување преку Wi-Fi во Поставки."</item>
+    <item msgid="3910386316304772394">"За да воспоставувате повици и да испраќате пораки преку Wi-Fi, прво побарајте од операторот да ја постави услугава. Потоа, вклучете ја повторно „Повикување преку Wi-Fi“ во „Поставки“. (Код за грешка: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Регистрирајте се со операторот"</item>
+    <item msgid="7472393097168811593">"Регистрирајте се кај операторот (Код на грешка: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Гласовна помош"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Заклучи сега"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Содржините се скриени"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Содржините се скриени поради политиката"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Ново известување"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуелна тастатура"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Физичка тастатура"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Безбедност"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Предупредувања"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Демонстрација за малопродажба"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-врска"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Апликациите се извршуваат во заднина"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> се извршува во заднина"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> апликации се извршуваат во заднина"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Апликации што ја трошат батеријата"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> користи батерија"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> апликации користат батерија"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Допрете за детали за батеријата и потрошениот сообраќај"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Безбеден режим"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="one">Отворени Wi-Fi мрежи се достапни</item>
       <item quantity="other">Отворени Wi-Fi мрежи се достапни</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Поврзете се на отворена Wi‑Fi-мрежа"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Поврзување на отворена Wi‑Fi-мрежа"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Се поврзавте на Wi‑Fi-мрежа"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не можеше да се поврзе на Wi‑Fi-мрежа"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Допрете за да ги видите сите мрежи"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Поврзете се"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Сите мрежи"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Најавете се на мрежа на Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Најавете се на мрежа"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB за МИДИ"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Поврзан со USB додаток"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Допрете за повеќе опции."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Откриен е аналоген аудиододаток"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Приложениот уред не е компатибилен со телефонов. Допрете за да дознаете повеќе."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Поврзано е отстранување грешки преку USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Допрете за да се оневозможи отстранувањето грешки преку USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете за да се оневозможи отстранување грешки на USB."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Поврзани сте на <xliff:g id="SESSION">%s</xliff:g>. Допрете за да управувате со мрежата."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Поврзување со секогаш вклучена VPN..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Поврзани со секогаш вклучена VPN"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Секогаш вклучената VPN е неповрзана"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Исклучено од секогаш вклучената VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Грешка на секогаш вклучена VPN"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Допрете за да поставите"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Променете ја мрежата или поставките за VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Избери датотека"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Не е избрана датотека"</string>
     <string name="reset" msgid="2448168080964209908">"Ресетирај"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Допрете за да излезете од автомобилски режим."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Поврзувањето или точката на пристап се активни"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Допрете за поставување."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Врзувањето е оневозможено"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Контактирајте со администраторот за детали"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Следно"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Прескокни"</string>
@@ -1725,14 +1731,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Откачете"</string>
     <string name="app_info" msgid="6856026610594615344">"Информации за апликација"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Да се ресетира уредот?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Допрете за да го ресетирате уредот"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Се вклучува демонстрацијата…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Се ресетира уредот…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Да се ресетира уредот?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Ќе ги изгубите измените и демонстрацијата ќе започне повторно по <xliff:g id="TIMEOUT">%1$s</xliff:g> секунди…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Откажи"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Ресетирај сега"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Оневозможен <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Конференциски повик"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Совет за алатка"</string>
@@ -1766,7 +1766,7 @@
     <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"Да се зачуваат <xliff:g id="TYPE_0">%1$s</xliff:g> и <xliff:g id="TYPE_1">%2$s</xliff:g> во &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt;?"</string>
     <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"Да се зачуваат <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> и <xliff:g id="TYPE_2">%3$s</xliff:g> во &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt;?"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"Зачувај"</string>
-    <string name="autofill_save_no" msgid="2625132258725581787">"Не, благодарам"</string>
+    <string name="autofill_save_no" msgid="2625132258725581787">"Не, фала"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"лозинка"</string>
     <string name="autofill_save_type_address" msgid="4936707762193009542">"адреса"</string>
     <string name="autofill_save_type_credit_card" msgid="7127694776265563071">"кредитна картичка"</string>
@@ -1776,6 +1776,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Итна евакуација од крајбрежните региони и областите покрај реки на побезбедно место, како на пр., терени на повисока надморска височина."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Бидете смирени и побарајте засолниште во близина."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Тестирање пораки за итни случаи"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Одговори"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Не е дозволена SIM-картичка"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Не е обезбедена SIM-картичка"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 41b073d..dcb2bba 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"സേവനത്തിനായി തിരയുന്നു"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"വൈഫൈ കോളിംഗ്"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"വൈഫൈ വഴി കോളുകൾ വിളിക്കാനും സന്ദേശങ്ങൾ അയയ്‌ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക."</item>
+    <item msgid="3910386316304772394">"വൈഫൈ വഴി കോളുകൾ ചെയ്യാനും സന്ദേശങ്ങൾ അയയ്‌ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക. (പിശക് കോഡ്: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"നിങ്ങളുടെ കാരിയറിൽ രജിസ്റ്റർ ചെയ്യുക"</item>
+    <item msgid="7472393097168811593">"നിങ്ങളുടെ കാരിയറുമായി രജിസ്‌റ്റർ ചെയ്യുക (പിശക് കോഡ്: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"വോയ്‌സ് സഹായം"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ഇപ്പോൾ ലോക്കുചെയ്യുക"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"കോൺടാക്‌റ്റുകൾ മറച്ചു"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"നയം അനുസരിച്ച് ഉള്ളടക്കം മറച്ചിരിക്കുന്നു"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"പുതിയ അറിയിപ്പ്"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"വെർച്വൽ കീബോർഡ്"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"കീബോർഡ്"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"സുരക്ഷ"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"അലേർട്ടുകൾ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"റീട്ടെയിൽ ഡെമോ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB കണക്ഷൻ"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ആപ്പുകൾ പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുന്നു"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുന്നു"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ആപ്പുകൾ പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുന്നു"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ആപ്പുകൾ ബാറ്ററി ഉപയോഗിക്കുന്നു"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ബാറ്ററി ഉപയോഗിക്കുന്നു"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ആപ്പുകൾ ബാറ്ററി ഉപയോഗിക്കുന്നു"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ബാറ്ററി, ഡാറ്റ ഉപയോഗം എന്നിവയുടെ വിശദാംശങ്ങളറിയാൻ ടാപ്പുചെയ്യുക"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"സുരക്ഷിത മോഡ്"</string>
@@ -1031,7 +1030,7 @@
     <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> നിലയ്ക്കുന്നത് തുടരുന്നു"</string>
     <string name="aerr_restart" msgid="7581308074153624475">"ആപ്പ് വീണ്ടും തുറക്കുക"</string>
     <string name="aerr_report" msgid="5371800241488400617">"ഫീഡ്‌ബാക്ക് അയയ്‌ക്കുക"</string>
-    <string name="aerr_close" msgid="2991640326563991340">"അടയ്‌ക്കുക"</string>
+    <string name="aerr_close" msgid="2991640326563991340">"അവസാനിപ്പിക്കുക"</string>
     <string name="aerr_mute" msgid="1974781923723235953">"ഉപകരണം പുനഃരാരംഭിക്കുന്നത് വരെ മ്യൂട്ടുചെയ്യുക"</string>
     <string name="aerr_wait" msgid="3199956902437040261">"കാത്തിരിക്കുക"</string>
     <string name="aerr_close_app" msgid="3269334853724920302">"ആപ്പ് അടയ്‌ക്കുക"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">ലഭ്യമായ വൈഫൈ നെറ്റ്‌വർക്കുകൾ തുറക്കുക</item>
       <item quantity="one">ലഭ്യമായ വൈഫൈ നെറ്റ്‌വർക്ക് തുറക്കുക</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"ലഭ്യമായ വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് കണക്റ്റുചെയ്യുക"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ലഭ്യമായ വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് കണക്റ്റുചെയ്യുന്നു"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് കണക്റ്റു‌ചെയ്‌‌തു"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"വൈ-ഫൈ നെറ്റ്‌വർക്കിലേക്ക് കണക്‌റ്റുചെയ്യാനായില്ല"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"എല്ലാ നെറ്റ്‌വർക്കുകളും കാണാൻ ടാപ്പുചെയ്യുക"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"കണക്റ്റുചെയ്യുക"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"എല്ലാ നെറ്റ്‌വർക്കുകളും"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1178,14 +1184,16 @@
     <string name="no_permissions" msgid="7283357728219338112">"അനുമതികളൊന്നും ആവശ്യമില്ല"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"ഇത് നിങ്ങൾക്ക് പണച്ചെലവിനിടയാക്കാം"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"ശരി"</string>
-    <string name="usb_charging_notification_title" msgid="6895185153353640787">"ഈ ഉപകരണം USB ചാർജുചെയ്യുന്നു"</string>
+    <string name="usb_charging_notification_title" msgid="6895185153353640787">"USB ഈ ഉപകരണം ചാർജജ് ചെയ്യുന്നു"</string>
     <string name="usb_supplying_notification_title" msgid="5310642257296510271">"ഘടിപ്പിച്ചിട്ടുള്ള ഉപകരണത്തിന് USB വൈദ്യുതി നൽകുന്നു"</string>
     <string name="usb_mtp_notification_title" msgid="8396264943589760855">"ഫയൽ കൈമാറ്റത്തിനുള്ള USB"</string>
     <string name="usb_ptp_notification_title" msgid="1347328437083192112">"ഫോട്ടോ കൈമാറ്റത്തിനായുള്ള USB"</string>
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI-യ്‌ക്കായുള്ള USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"ഒരു USB ആക്‌സസ്സറി കണക്റ്റുചെയ്‌തു"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"കൂടുതൽ ഓപ്ഷനുകൾക്ക് ടാപ്പുചെയ്യുക."</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ഡീബഗ്ഗിംഗ് കണക്‌റ്റുചെയ്‌തു"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"അനലോഗ് ഓഡിയോ ആക്‌സസറി കണ്ടെത്തി"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"അറ്റാച്ചുചെയ്‌ത ഉപകരണം ഈ ഫോണിന് അനുയോജ്യമല്ല. കൂടുതലറിയാൻ ടാപ്പുചെയ്യുക."</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ഡീബഗ്ഗിംഗ് കണക്റ്റ് ചെയ്തു"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ഡീബഗ്ഗിംഗ് പ്രവർത്തനരഹിതമാക്കാൻ ടാപ്പുചെയ്യുക."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ഡീബഗ്ഗുചെയ്യൽ പ്രവർത്തനരഹിതമാക്കാൻ തിരഞ്ഞെടുക്കുക."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ബഗ് റിപ്പോർട്ട് എടുക്കുന്നു…"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> എന്ന സെഷനിലേക്ക് കണക്റ്റുചെയ്തു. നെറ്റ്‌വർക്ക് മാനേജുചെയ്യാൻ ടാപ്പുചെയ്യുക."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"എല്ലായ്‌പ്പോഴും ഓണായിരിക്കുന്ന VPN കണക്റ്റുചെയ്യുന്നു…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"എല്ലായ്‌പ്പോഴും ഓണായിരിക്കുന്ന VPN കണക്റ്റുചെയ്‌തു"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"\'എല്ലായ്‌പ്പോഴും ഓണായിരിക്കുന്ന VPN\' വിച്ഛേദിച്ചു"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"എപ്പോഴും ഓണായിരിക്കുന്ന VPN-ൽ നിന്ന് വിച്ഛേദിച്ചു"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"എല്ലായ്‌പ്പോഴും ഓണായിരിക്കുന്ന VPN പിശക്"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"സജ്ജമാക്കാൻ ടാപ്പുചെയ്യുക"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"നെറ്റ്‍വര്‍ക്ക് അല്ലെങ്കിൽ VPN ക്രമീകരണം മാറ്റുക"</string>
     <string name="upload_file" msgid="2897957172366730416">"ഫയല്‍‌ തിരഞ്ഞെടുക്കുക"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"ഫയലൊന്നും തിരഞ്ഞെടുത്തില്ല"</string>
     <string name="reset" msgid="2448168080964209908">"പുനഃസജ്ജമാക്കുക"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"കാർ മോഡിൽ നിന്ന് പുറത്തുകടക്കാൻ ടാപ്പുചെയ്യുക."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ടെതറിംഗ് അല്ലെങ്കിൽ ഹോട്ട്സ്‌പോട്ട് സജീവമാണ്"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"സജ്ജമാക്കാൻ ടാപ്പുചെയ്യുക."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ടെതറിംഗ് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"വിശദവിവരങ്ങൾക്ക് നിങ്ങളുടെ അഡ്മിനെ ബന്ധപ്പെടുക"</string>
     <string name="back_button_label" msgid="2300470004503343439">"മടങ്ങുക"</string>
     <string name="next_button_label" msgid="1080555104677992408">"അടുത്തത്"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ഒഴിവാക്കുക"</string>
@@ -1422,7 +1428,7 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"സിസ്റ്റം"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"ബ്ലൂടൂത്ത് ഓഡിയോ"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"വയർലെസ് ഡിസ്‌പ്ലേ"</string>
-    <string name="media_route_button_content_description" msgid="591703006349356016">"കാസ്‌റ്റുചെയ്യുക"</string>
+    <string name="media_route_button_content_description" msgid="591703006349356016">"കാസ്‌റ്റ് ചെയ്യുക"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"ഉപകരണത്തിലേക്ക് കണക്റ്റുചെയ്യുക"</string>
     <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"സ്‌ക്രീൻ ഉപകരണത്തിലേക്ക് കാസ്റ്റുചെയ്യുക"</string>
     <string name="media_route_chooser_searching" msgid="4776236202610828706">"ഉപകരണങ്ങൾക്കായി തിരയുന്നു…"</string>
@@ -1689,7 +1695,7 @@
     <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"കൂടുതൽ‍ ഓപ്ഷനുകള്‍"</string>
     <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"ഓവർഫ്ലോ അടയ്‌ക്കുക"</string>
     <string name="maximize_button_text" msgid="7543285286182446254">"വലുതാക്കുക"</string>
-    <string name="close_button_text" msgid="3937902162644062866">"അടയ്‌ക്കുക"</string>
+    <string name="close_button_text" msgid="3937902162644062866">"അവസാനിപ്പിക്കുക"</string>
     <string name="notification_messaging_title_template" msgid="3452480118762691020">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
     <plurals name="selected_count" formatted="false" msgid="7187339492915744615">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> തിരഞ്ഞെടുത്തു</item>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"അൺപിൻ ചെയ്യുക"</string>
     <string name="app_info" msgid="6856026610594615344">"ആപ്പ് വിവരം"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"ഉപകരണം പുനക്രമീകരിക്കണോ?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"ഉപകരണം പുനക്രമീകരിക്കാൻ ടാപ്പുചെയ്യുക"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ഡെമോ ആരംഭിക്കുന്നു…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"ഉപകരണം പുനക്രമീകരിക്കുന്നു…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"ഉപകരണം പുനക്രമീകരിക്കണോ?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"മാറ്റങ്ങളെല്ലാം നിങ്ങൾക്ക് നഷ്ടപ്പെടും, <xliff:g id="TIMEOUT">%1$s</xliff:g> സെക്കൻഡിൽ ഡെമോ വീണ്ടും തുടങ്ങും…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"റദ്ദാക്കുക"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"ഇപ്പോൾ പുനക്രമീകരിക്കുക"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> പ്രവർത്തനരഹിതമാക്കി"</string>
     <string name="conference_call" msgid="3751093130790472426">"കോൺഫറൻസ് കോൾ"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"ടൂൾ ടിപ്പ്"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"തീരപ്രദേശങ്ങളിൽ നിന്നും നദിക്കരകളിൽ നിന്നും ആളുകളെ ഉടനടി ഒഴിപ്പിച്ച് ഉയർന്ന ഭൂമിയിൽ എത്തിക്കുക."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"പരിഭ്രമിക്കാതിരിക്കുക, അടുത്തുള്ള അഭയകേന്ദ്രം തേടുക."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"അടിയന്തര സന്ദേശ ടെസ്റ്റ്"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"മറുപടി നൽകുക"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM അനുവദനീയമല്ല"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM പ്രൊവിഷൻ ചെയ്തിട്ടില്ല"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index cd561a7..01f0c52 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Үйлчилгээг хайж байна…"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi-аар дуудлага хийх болон мессеж илгээхээр бол эхлээд оператороосоо энэ төхөөрөмжийг тохируулж өгөхийг хүсээрэй. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаагаарай."</item>
+    <item msgid="3910386316304772394">"Wi-Fi-аар дуудлага хийх, мессеж илгээх бол эхлээд оператор компаниасаа энэ үйлчилгээг тохируулж өгөхийг хүснэ үү. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаана уу. (Алдааны код: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Операторт бүртгүүлэх"</item>
+    <item msgid="7472393097168811593">"Оператор компаниар бүртгүүлэх (Алдааны код: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Дуут туслах"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Одоо түгжих"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Контентыг нуусан"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Удирдамжийн дагуу нуусан агуулга"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Шинэ мэдэгдэл"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуал гар"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Бодит гар"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Аюулгүй байдал"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Сануулга"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Жижиглэнгийн жишээ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB холболт"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Цаана ажиллаж буй апп"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> ард ажиллаж байна"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> апп цаана ажиллаж байна"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Апп батерей ашиглаж байна"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> батерей ашиглаж байна"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> апп батерей ашиглаж байна"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Аюулгүй горим"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Нээлттэй Wi-Fi сүлжээ ашиглах боломжтой</item>
       <item quantity="one">Нээлттэй Wi-Fi сүлжээ ашиглах боломжтой</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Нээлттэй Wi‑Fi сүлжээнд холбогдох"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Нээлттэй Wi‑Fi сүлжээнд холбогдож байна"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi сүлжээнд холбогдлоо"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi сүлжээнд холбогдож чадсангүй"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Бүх сүлжээг харахын тулд товшино уу"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Холбогдох"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Бүх сүлжээ"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi сүлжээнд нэвтэрнэ үү"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Сүлжээнд нэвтэрнэ үү"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI-ийн USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB төхөөрөмжид холбогдов"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Бусад сонголтыг харахын тулд товшино уу."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Аналог аудионы дагалдах хэрэгсэл илэрсэн"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Холбосон төхөөрөмж энэ утастай тохирохгүй байна. Дэлгэрэнгүй үзэх бол товшино уу."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB дебаг холбогдсон"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB-н алдаа засварлахыг идэвхгүй болгохын тулд товшино уу."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB дебаг хийхийг идэвхгүй болгох бол сонгоно уу."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g>-д холбогдов. Сүлжээг удирдах бол товшино уу."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Байнгын VPN-д холбогдож байна..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Байнга VPN холбоотой"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Тогтмол асаалттай VPN салсан"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Тогтмол асаалттай VPN-с салсан"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Байнгын VPN алдаа"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Тохируулахын тулд товшино уу"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Сүлжээ эсвэл VPN тохиргоог өөрчлөх"</string>
     <string name="upload_file" msgid="2897957172366730416">"Файл сонгох"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Сонгосон файл байхгүй"</string>
     <string name="reset" msgid="2448168080964209908">"Бүгдийг цэвэрлэх"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Машины горимоос гарахын тулд товшино уу."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Модем болгох эсвэл идэвхтэй цэг болгох"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Тохируулахын тулд товшино уу."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Модем болгох боломжгүй байна"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Дэлгэрэнгүй мэдээлэл авахын тулд админтайгаа холбогдоно уу"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Буцах"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Дараах"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Алгасах"</string>
@@ -1721,14 +1727,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Unpin"</string>
     <string name="app_info" msgid="6856026610594615344">"Апп-н мэдээлэл"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Төхөөрөмжийг шинэчлэх үү?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Төхөөрөмжийг шинэчлэхийн тулд товшино уу"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Жишээг эхлүүлж байна…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Төхөөрөмжийг шинэчилж байна…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Төхөөрөмжийг шинэчлэх үү?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Таны хийсэн өөрчлөлтийг хадгалахгүй бөгөөд жишээ <xliff:g id="TIMEOUT">%1$s</xliff:g> секундын дотор дахин эхлэх болно..."</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Цуцлах"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Одоо шинэчлэх"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g>-г цуцалсан"</string>
     <string name="conference_call" msgid="3751093130790472426">"Хурлын дуудлага"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Зөвлөмж"</string>
@@ -1772,6 +1772,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Эргийн бүс, голын эргийн бүсээс өндөрлөг газар зэрэг аюулгүй газар руу нэн даруй шилжинэ үү."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Тайван байж, ойролцоох нуугдах газар хайна уу."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Онцгой байдлын зурвасын тест"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Хариу бичих"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM боломжгүй"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-г хийгээгүй"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 832cd44..66de97b 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -95,14 +95,14 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"व्हॉइस/आणीबाणी सेवा नाही"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"तुम्‍ही असलेल्‍या स्‍थानी मोबाइल नेटवर्क तात्‍पुरते उपलब्‍ध नाही"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"नेटवर्कवर पोहोचूू शकत नाही"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"रिसेप्शन सुधारण्यासाठी प्रणाली &gt; नेटवर्क आणि इंटरनेट &gt; मोबाइल नेटवर्क &gt; प्राधान्य दिलेला नेटवर्क प्रकार येथे निवडलेला प्रकार बदलून पहा."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"रीसेप्शन सुधारण्यासाठी सिस्टम &gt; नेटवर्क आणि इंटरनेट &gt; मोबाइल नेटवर्क &gt; अग्रमानांकित नेटवर्क प्रकार येथे निवडलेला प्रकार बदलून पहा."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"अलर्ट"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"कॉल फॉरवर्डिंग"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"इमर्जन्सी कॉलबॅक मोड"</string>
     <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"मोबाइल डेटा अलर्ट"</string>
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS संदेश"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"व्हॉइसमेल संदेश"</string>
-    <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi कॉलिंग"</string>
+    <string name="notification_channel_wfc" msgid="2130802501654254801">"वाय-फाय कॉलिंग"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"समवयस्क व्यक्तीने TTY मोड पूर्ण ची विनंती केली"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"समवयस्क व्यक्तीने TTY मोड HCO ची विनंती केली"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"समवयस्क व्यक्तीने TTY मोड VCO ची विनंती केली"</string>
@@ -131,17 +131,17 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"सेवा शोधत आहे"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"वाय-फाय कॉलिंग"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठविण्यासाठी, प्रथम आपल्या वाहकास ही सेवा सेट करण्यास सांगा. नंतर सेटिंग्जमधून पुन्हा वाय-फाय कॉलिंग चालू करा."</item>
+    <item msgid="3910386316304772394">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठवण्यासाठी आधी तुमच्या कॅरियरला ही सेवा सेट अप करण्यास सांगा. नंतर सेटिंग्जमधून वाय-फाय वापरून कॉल करणे पुन्हा चालू करा. (एरर कोड <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"आपल्या वाहकासह नोंदणी करा"</item>
+    <item msgid="7472393097168811593">"तुमच्‍या वाहकासह नोंदणी करा (एरर कोड: <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>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"बंद"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"वाय-फाय प्राधान्यकृत"</string>
+    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"वाय-फाय अग्रमानांकित"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"प्राधान्य दिलेला मोबाइल"</string>
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"केवळ वाय-फाय"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अग्रेषित केला नाही"</string>
@@ -150,11 +150,11 @@
     <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अग्रेषित केला नाही"</string>
     <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अग्रेषित केला नाही"</string>
     <string name="fcComplete" msgid="3118848230966886575">"वैशिष्ट्य कोड पूर्ण."</string>
-    <string name="fcError" msgid="3327560126588500777">"कनेक्शन समस्या किंवा अवैध वैशिष्ट्य कोड."</string>
+    <string name="fcError" msgid="3327560126588500777">"कनेक्शन समस्या किंवा अवैध फीचर कोड."</string>
     <string name="httpErrorOk" msgid="1191919378083472204">"ठीक"</string>
-    <string name="httpError" msgid="7956392511146698522">"नेटवर्क त्रुटी आली."</string>
+    <string name="httpError" msgid="7956392511146698522">"नेटवर्क एरर आली."</string>
     <string name="httpErrorLookup" msgid="4711687456111963163">"URL शोधू शकलो नाही."</string>
-    <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"साइट प्रमाणीकरण योजना समर्थित नाही."</string>
+    <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"साइट प्रमाणीकरण योजनेस सपोर्ट नाही."</string>
     <string name="httpErrorAuth" msgid="1435065629438044534">"प्रमाणीकृत करू शकलो नाही."</string>
     <string name="httpErrorProxyAuth" msgid="1788207010559081331">"प्रॉक्सी सर्व्हरद्वारे प्रमाणीकरण यशस्वी झाले."</string>
     <string name="httpErrorConnect" msgid="8714273236364640549">"सर्व्हरशी कनेक्ट करू शकलो नाही."</string>
@@ -163,11 +163,11 @@
     <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"पृष्ठामध्ये बरीच सर्व्हर पुनर्निर्देशने आहेत."</string>
     <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"प्रोटोकॉल समर्थित नाही."</string>
     <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"सुरक्षित कनेक्शन इंस्टॉल करू शकलो नाही."</string>
-    <string name="httpErrorBadUrl" msgid="3636929722728881972">"URL अवैध असल्यामुळे पृष्ठ उघडू शकलो नाही."</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"URL अवैध असल्यामुळे पेज उघडू शकलो नाही."</string>
     <string name="httpErrorFile" msgid="2170788515052558676">"फायलीवर प्रवेश करू शकलो नाही."</string>
     <string name="httpErrorFileNotFound" msgid="6203856612042655084">"विनंती केलेली फाईल शोधू शकलो नाही."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"बर्‍याच विनंत्यांवर प्रक्रिया होत आहे. नंतर पुन्हा प्रयत्न करा."</string>
-    <string name="notification_title" msgid="8967710025036163822">"<xliff:g id="ACCOUNT">%1$s</xliff:g> साठी साइन इन त्रुटी"</string>
+    <string name="notification_title" msgid="8967710025036163822">"<xliff:g id="ACCOUNT">%1$s</xliff:g> साठी साइन इन एरर"</string>
     <string name="contentServiceSync" msgid="8353523060269335667">"संकालन करा"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"संकालन करा"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"खूप <xliff:g id="CONTENT_TYPE">%s</xliff:g> हटविणे."</string>
@@ -184,12 +184,12 @@
     <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g> द्वारे"</string>
     <string name="work_profile_deleted" msgid="5005572078641980632">"कार्य प्रोफाईल हटविले"</string>
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"प्रशासक अॅप गहाळ असल्यामुळे कार्य प्रोफाइल हटवले गेले"</string>
-    <string name="work_profile_deleted_details" msgid="6307630639269092360">"कार्य प्रोफाइल प्रशासक अॅप गहाळ आहे किंवा दूषित आहे. परिणामी, आपले कार्य प्रोफाइल आणि संबंधित डेटा हटवले गेले आहेत. सहाय्यासाठी आपल्या प्रशासकाशी संपर्क साधा."</string>
+    <string name="work_profile_deleted_details" msgid="6307630639269092360">"कार्य प्रोफाइल प्रशासक अॅप गहाळ आहे किंवा करप्ट आहे. परिणामी, आपले कार्य प्रोफाइल आणि संबंधित डेटा हटवले गेले आहेत. सहाय्यासाठी आपल्या प्रशासकाशी संपर्क साधा."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"आपले कार्य प्रोफाइल आता या डिव्हाइसवर उपलब्‍ध नाही"</string>
-    <string name="network_logging_notification_title" msgid="6399790108123704477">"डीव्हाइस व्यवस्थापित केले आहे"</string>
-    <string name="network_logging_notification_text" msgid="7930089249949354026">"आपली संस्था हे डीव्हाइस व्यवस्थापित करते आणि नेटवर्क रहदारीचे निरीक्षण करू शकते. तपशीलांसाठी टॅप करा."</string>
-    <string name="factory_reset_warning" msgid="5423253125642394387">"तुमचे डीव्हाइस मिटविले जाईल"</string>
-    <string name="factory_reset_message" msgid="7972496262232832457">"हे प्रशासक अ‍ॅप वापरले जाऊ शकत नाही. तुमचे डीव्हाइस आता मिटवले जाईल.\n\nतुम्हाला प्रश्न असल्यास, तुमच्या संस्थेच्या प्रशासकाशी संपर्क साधा."</string>
+    <string name="network_logging_notification_title" msgid="6399790108123704477">"डिव्हाइस व्यवस्थापित केले आहे"</string>
+    <string name="network_logging_notification_text" msgid="7930089249949354026">"आपली संस्था हे डिव्हाइस व्यवस्थापित करते आणि नेटवर्क रहदारीचे निरीक्षण करू शकते. तपशीलांसाठी टॅप करा."</string>
+    <string name="factory_reset_warning" msgid="5423253125642394387">"तुमचे डिव्हाइस मिटविले जाईल"</string>
+    <string name="factory_reset_message" msgid="7972496262232832457">"हे प्रशासक अ‍ॅप वापरले जाऊ शकत नाही. तुमचे डिव्हाइस आता मिटवले जाईल.\n\nतुम्हाला प्रश्न असल्यास, तुमच्या संस्थेच्या प्रशासकाशी संपर्क साधा."</string>
     <string name="me" msgid="6545696007631404292">"मी"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"टॅबलेट पर्याय"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"टीव्ही पर्याय"</string>
@@ -224,13 +224,13 @@
     <string name="global_action_lock" msgid="2844945191792119712">"स्क्रीन लॉक"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"बंद"</string>
     <string name="global_action_emergency" msgid="7112311161137421166">"आणीबाणी"</string>
-    <string name="global_action_bug_report" msgid="7934010578922304799">"दोष अहवाल"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"दोष अहवाल घ्या"</string>
-    <string name="bugreport_message" msgid="398447048750350456">"ई-मेल संदेश म्हणून पाठविण्यासाठी, हे तुमच्या सद्य डीव्हाइस स्थितीविषयी माहिती संकलित करेल. दोष अहवाल सुरू करण्यापासून तो पाठविण्यापर्यंत थोडा वेळ लागेल; कृपया धीर धरा."</string>
+    <string name="global_action_bug_report" msgid="7934010578922304799">"बग रीपोर्ट"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"बग रीपोर्ट घ्या"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"ई-मेल संदेश म्हणून पाठविण्यासाठी, हे तुमच्या सद्य डिव्हाइस स्थितीविषयी माहिती संकलित करेल. बग रीपोर्ट सुरू करण्यापासून तो पाठविण्यापर्यंत थोडा वेळ लागेल; कृपया धीर धरा."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"परस्परसंवादी अहवाल"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"बहुतांश प्रसंगांमध्ये याचा वापर करा. ते आपल्याला अहवालाच्या प्रगतीचा मागोवा घेण्याची, समस्येविषयी आणखी तपाशील प्रविष्ट करण्याची आणि स्क्रीनशॉट घेण्याची अनुमती देते. ते कदाचित अहवाल देण्यासाठी बराच वेळ घेणारे कमी-वापरलेले विभाग वगळू शकते."</string>
     <string name="bugreport_option_full_title" msgid="6354382025840076439">"संपूर्ण अहवाल"</string>
-    <string name="bugreport_option_full_summary" msgid="7210859858969115745">"तुमचे डीव्हाइस प्रतिसाद देत नाही किंवा खूप धीमे असते किंवा तुम्हाला सर्व अहवाल विभागांची आवश्यकता असते तेव्हा कमीतकमी सिस्टम हस्तक्षेपासाठी या पर्यायाचा वापर करा. तुम्हाला आणखी तपशील एंटर करण्याची किंवा अतिरिक्त स्क्रीनशॉट घेण्याची अनुमती देत नाही."</string>
+    <string name="bugreport_option_full_summary" msgid="7210859858969115745">"तुमचे डिव्हाइस प्रतिसाद देत नाही किंवा खूप धीमे असते किंवा तुम्हाला सर्व अहवाल विभागांची आवश्यकता असते तेव्हा कमीतकमी सिस्टम हस्तक्षेपासाठी या पर्यायाचा वापर करा. तुम्हाला आणखी तपशील एंटर करण्याची किंवा अतिरिक्त स्क्रीनशॉट घेण्याची अनुमती देत नाही."</string>
     <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
       <item quantity="one">दोष अहवालासाठी <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदामध्‍ये स्क्रीनशॉट घेत आहे.</item>
       <item quantity="other">दोष अहवालासाठी <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदांमध्‍ये स्क्रीनशॉट घेत आहे.</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"व्हॉइस सहाय्य"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"आता लॉक करा"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"लपविलेली सामग्री"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"धोरणाद्वारे सामग्री लपविली"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"नवीन सूचना"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"व्हर्च्युअल कीबोर्ड"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"वास्तविक कीबोर्ड"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"सुरक्षितता"</string>
@@ -259,13 +258,13 @@
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"नेटवर्क सूचना"</string>
     <string name="notification_channel_network_available" msgid="4531717914138179517">"नेटवर्क उपलब्ध"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN स्थिती"</string>
-    <string name="notification_channel_device_admin" msgid="1568154104368069249">"डीव्हाइस प्रशासन"</string>
+    <string name="notification_channel_device_admin" msgid="1568154104368069249">"डिव्हाइस प्रशासन"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"सूचना"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"रीटेल डेमो"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB कनेक्‍शन"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"अॅप्‍स बॅकग्राउंडमध्‍ये चालू आहेत"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> बॅकग्राउंडमध्‍ये चालू आहे"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> अॅप्‍स बॅकग्राउंडमध्‍ये चालू आहेत"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"अॅप्‍समुळे बॅटरी संपत आहे"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> बॅटरी वापरत आहे"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> अॅप्‍स बॅटरी वापरत आहेत"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"बॅटरी आणि डेटा वापराच्‍या तपशीलांसाठी टॅप करा"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
@@ -281,7 +280,7 @@
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS संदेश पाठवणे आणि पाहणे हे"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"संचयन"</string>
-    <string name="permgroupdesc_storage" msgid="637758554581589203">"तुमच्या डीव्हाइस वरील फोटो, मीडिया आणि फायलींमध्‍ये अॅक्सेस"</string>
+    <string name="permgroupdesc_storage" msgid="637758554581589203">"तुमच्या डिव्हाइस वरील फोटो, मीडिया आणि फायलींमध्‍ये अॅक्सेस"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"मायक्रोफोन"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ऑडिओ रेकॉर्ड"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"कॅमेरा"</string>
@@ -289,21 +288,21 @@
     <string name="permgrouplab_phone" msgid="5229115638567440675">"फोन"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"फोन कॉल आणि व्यवस्थापित"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"शरीर सेन्सर"</string>
-    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"आपल्‍या महत्त्वाच्या मापनांविषयी सेन्सर डेटामध्‍ये प्रवेश करा"</string>
+    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"आपल्‍या महत्त्वाच्या मापनांविषयी सेंसर डेटा अॅक्सेस करा"</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_desc_canRequestTouchExploration" msgid="7543249041581408313">"टॅप केलेले आयटम मोठ्‍याने बोलले जातील आणि जेश्चरचा वापर करून स्क्रीन एक्सप्लोर केली जाऊ शकते."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"आपण टाइप करता त्या मजकुराचे निरीक्षण करा"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"क्रेडिट कार्ड नंबर आणि संकेतशब्‍द यासारखा वैयक्तिक डेटा समाविष्‍ट करते."</string>
-    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"प्रदर्शन विस्तृतीकरण नियंत्रित करा"</string>
+    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"डिस्प्ले मॅग्निफिकेशन नियंत्रित करा"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"प्रदर्शनाचा झूम स्तर आणि स्थिती निर्धारण नियंत्रित करा."</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"जेश्चर करा"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"टॅप, स्वाइप, पिंच आणि इतर जेश्चर करू शकते."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"फिंगरप्रिंट जेश्चर"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"डिव्‍हाइसच्‍या फिंगरप्रिंट सेंसरवर केलेले जेश्चर कॅप्‍चर करू शकते."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"स्टेटस बार अक्षम करा किंवा सुधारित करा"</string>
-    <string name="permdesc_statusBar" msgid="8434669549504290975">"स्टेटस बार अक्षम करण्यासाठी किंवा सिस्टीम चिन्हे जोडण्यासाठी आणि काढण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"स्टेटस बार अक्षम करण्यासाठी किंवा सिस्टम चिन्हे जोडण्यासाठी आणि काढण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"स्टेटस बार होऊ द्या"</string>
     <string name="permdesc_statusBarService" msgid="716113660795976060">"स्टेटस बार होण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_expandStatusBar" msgid="1148198785937489264">"स्‍टेटस बार विस्तृत करा/संकुचित करा"</string>
@@ -316,9 +315,9 @@
     <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"कॉल केला जात असताना कॉलला भिन्न नंबरवर पुनर्निर्देशित करण्‍याच्‍या किंवा संपूर्ण कॉल रद्द करण्‍याच्‍या पर्यायासह डायल केला जाणारा नंबर पाहण्‍याची अ‍ॅपला अनुमती देते"</string>
     <string name="permlab_answerPhoneCalls" msgid="4077162841226223337">"फोन कॉलचे उत्तर द्या"</string>
     <string name="permdesc_answerPhoneCalls" msgid="2901889867993572266">"येणार्‍या फोन कॉलचे उत्तर देण्यास अॅपला अनुमती देते."</string>
-    <string name="permlab_receiveSms" msgid="8673471768947895082">"मजकूर संदेश प्राप्त करा (SMS)"</string>
-    <string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS संदेश प्राप्त करण्याची आणि त्यावर प्रक्रिया करण्याची अॅप ला अनुमती देते. म्हणजेच अॅप आपल्या डिव्हाइसवर पाठविलेले संदेश आपल्याला न दर्शवता त्यांचे परीक्षण करू किंवा ते हटवू शकतो."</string>
-    <string name="permlab_receiveMms" msgid="1821317344668257098">"मजकूर संदेश प्राप्त करा (MMS)"</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"मजकूर संदेश मिळवा (SMS)"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS संदेश प्राप्त करण्याची आणि त्यावर प्रक्रिया करण्याची अॅप ला अनुमती देते. म्हणजेच अॅप आपल्या डीव्हाइसवर पाठविलेले संदेश तुम्हाला न दर्शवता त्यांचे परीक्षण करू किंवा ते हटवू शकतो."</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"मजकूर संदेश मिळवा (MMS)"</string>
     <string name="permdesc_receiveMms" msgid="533019437263212260">"MMS संदेश प्राप्त करण्यास आणि त्यावर प्रक्रिया करण्यास अॅप ला अनुमती देते. म्हणजेच अॅप आपल्या डिव्हाइसवर पाठविलेले संदेश आपल्याला न दर्शवता त्यांचे परीक्षण करू किंवा ते हटवू शकतो."</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"सेल प्रसारण संदेश वाचा"</string>
     <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"आपल्या डिव्हाइसद्वारे प्राप्त केलेले सेल प्रसारण संदेश वाचण्यासाठी अॅप ला अनुमती देते. काही स्थानांमध्ये आपल्याला आणीबाणीच्या परिस्थितीची चेतावणी देण्यासाठी सेल प्रसारण सूचना वितरीत केल्या जातात. आणीबाणी सेल प्रसारण प्राप्त होते तेव्हा आपल्या डिव्हाइसच्या कार्यप्रदर्शनात किंवा कार्यात दुर्भावनापूर्ण अॅप्स व्यत्यय आणू शकतात."</string>
@@ -327,15 +326,15 @@
     <string name="permlab_sendSms" msgid="7544599214260982981">"SMS संदेश पाठवणे आणि पाहणे"</string>
     <string name="permdesc_sendSms" msgid="7094729298204937667">"SMS संदेश पाठविण्यासाठी अॅप ला अनुमती देते. हे अनपेक्षित शुल्कामुळे होऊ शकते. दुर्भावनापूर्ण अॅप्स नी आपल्या पुष्टिकरणाशिवाय संदेश पाठवल्यामुळे आपले पैसे खर्च होऊ शकतात."</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"आपले मजकूर संदेश वाचा (SMS किंवा MMS)"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"हा अॅप आपल्या टॅब्लेटवर संचयित केलेले सर्व SMS (मजकूर) संदेश वाचू शकतो."</string>
-    <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"हा अॅप आपल्या टीव्हीवर संचयित केलेले सर्व SMS (मजकूर) संदेश वाचू शकतो."</string>
-    <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"हा अॅप आपल्या फोनवर संचयित केलेले सर्व SMS (मजकूर) संदेश वाचू शकतो."</string>
-    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"मजकूर संदेश प्राप्त करा (WAP)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"हा अॅप तुमच्या टॅब्लेटवर स्टोअर केलेले सर्व SMS (मजकूर) संदेश वाचू शकतो."</string>
+    <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"हा अॅप तुमच्या टीव्हीवर स्टोअर केलेले सर्व SMS (मजकूर) संदेश वाचू शकतो."</string>
+    <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"हा अॅप तुमच्या फोनवर स्टोअर केलेले सर्व SMS (मजकूर) संदेश वाचू शकतो."</string>
+    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"मजकूर संदेश मिळवा (WAP)"</string>
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP संदेश प्राप्त करण्यास आणि त्यावर प्रक्रिया करण्यासाठी अॅप ला अनुमती देते. ही परवानगी आपल्याला पाठविलेले संदेश आपल्याला न दर्शविता त्यांचे परीक्षण करण्याची आणि ते हटविण्याची क्षमता समाविष्ट करते."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"चालणारे अॅप्स पुनर्प्राप्त करा"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"सध्या आणि अलीकडे चालणार्‍या कार्यांविषयी माहिती पुनर्प्राप्त करण्यासाठी अॅप ला अनुमती देते. हे डिव्हाइसवर कोणते अॅप्लिकेशन वापरले जात आहेत त्याविषयी माहिती शोधण्यासाठी अॅप ला अनुमती देऊ शकतात."</string>
-    <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"प्रोफाईल आणि डीव्हाइस मालक व्यवस्थापित करा"</string>
-    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"प्रोफाईल मालक आणि डीव्हाइस मालक सेट करण्याची अॅप्सना अनुमती द्या."</string>
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"प्रोफाईल आणि डिव्हाइस मालक व्यवस्थापित करा"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"प्रोफाईल मालक आणि डिव्हाइस मालक सेट करण्याची अॅप्सना अनुमती द्या."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"चालणारे अॅप्स पुनर्क्रमित करा"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"समोर आणि पार्श्वभूमीवर कार्ये हलविण्यासाठी अॅप ला अनुमती देते. अॅप हे आपल्या इनपुटशिवाय करू शकतो."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"कार मोड सक्षम करा"</string>
@@ -343,7 +342,7 @@
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"अन्य अॅप्स बंद करा"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"अन्य अॅप्सच्या पार्श्वभूमी प्रक्रिया समाप्त करण्यासाठी अॅप ला अनुमती देते. यामुळे अन्य अॅप्स चालणे थांबू शकते."</string>
     <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"हा अॅप इतर अॅप्सच्या शीर्षस्थानी दिसू शकतो."</string>
-    <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"हा अॅप इतर अॅप्सच्या शीर्षस्थानी किंवा स्क्रीनच्या इतर भागांवर दिसू शकतो. हे सामान्य अॅप वापरात व्यत्यय आणू शकते किंवा इतर अॅप्सची प्रदर्शन पद्धत बदलू शकते."</string>
+    <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"हे अॅप इतर अॅप्सच्या शीर्षस्थानी किंवा स्क्रीनच्या इतर भागांवर दिसू शकतो. हे सामान्य अॅप वापरात व्यत्यय आणू शकते किंवा इतर अॅप्सची डिस्प्ले पद्धत बदलू शकते."</string>
     <string name="permlab_runInBackground" msgid="7365290743781858803">"पार्श्वभूमीत चालवा"</string>
     <string name="permdesc_runInBackground" msgid="7370142232209999824">"हे अॅप पार्श्वभूमीत चालू शकते. हे बॅटरी अधिक जलद संपवू शकते."</string>
     <string name="permlab_useDataInBackground" msgid="8694951340794341809">"पार्श्वभूमीत डेटा वापरा"</string>
@@ -357,9 +356,9 @@
     <string name="permlab_writeSettings" msgid="2226195290955224730">"सिस्टम सेटिंग्ज सुधारित करा"</string>
     <string name="permdesc_writeSettings" msgid="7775723441558907181">"सिस्टीमचा सेटिंग्ज डेटा सुधारित करण्यासाठी अॅप ला अनुमती देते. दुर्भावनापूर्ण अॅप्स आपल्या सिस्टीमचे कॉन्फिगरेशन दूषित करू शकतात."</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"सुरूवातीस चालवा"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"जसे सिस्टीम बूट करणे समाप्त करते तसे अॅप ला स्वतः प्रारंभ करण्यास अनुमती देते. यामुळे टॅबलेट प्रारंभ करण्यास वेळ लागू शकतो आणि नेहमी चालू राहून एकंदर टॅबलेटला धीमे करण्यास अॅप ला अनुमती देते."</string>
-    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"सिस्टीम बूट करणे समाप्त करते तसेच अॅपने स्वतः प्रारंभ करण्यास त्याला अनुमती देते. यामुळे टीव्ही प्रारंभ करण्यासाठी त्यास जास्त वेळ लागू शकतो आणि नेहमी चालू ठेवून संपूर्ण टॅबलेट धीमे करण्यासाठी अॅपला अनुमती देते."</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"जसे सिस्टीम बूट करणे समाप्त करते तसे अॅप ला स्वतः प्रारंभ करण्यास अनुमती देते. यामुळे फोन प्रारंभ करण्यास वेळ लागू शकतो आणि नेहमी चालू राहून एकंदर फोनला धीमे करण्यास अॅप ला अनुमती देते."</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"जसे सिस्टम बूट करणे समाप्त करते तसे अॅप ला स्वतः प्रारंभ करण्यास अनुमती देते. यामुळे टॅबलेट प्रारंभ करण्यास वेळ लागू शकतो आणि नेहमी चालू राहून एकंदर टॅबलेटला धीमे करण्यास अॅप ला अनुमती देते."</string>
+    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"सिस्टम बूट करणे समाप्त करते तसेच अॅपने स्वतः प्रारंभ करण्यास त्याला अनुमती देते. यामुळे टीव्ही प्रारंभ करण्यासाठी त्यास जास्त वेळ लागू शकतो आणि नेहमी चालू ठेवून संपूर्ण टॅबलेट धीमे करण्यासाठी अॅपला अनुमती देते."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"जसे सिस्टम बूट करणे समाप्त करते तसे अॅप ला स्वतः प्रारंभ करण्यास अनुमती देते. यामुळे फोन प्रारंभ करण्यास वेळ लागू शकतो आणि नेहमी चालू राहून एकंदर फोनला धीमे करण्यास अॅप ला अनुमती देते."</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"रोचक प्रसारण पाठवा"</string>
     <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"रोचक प्रसारणे पाठविण्यासाठी अॅप ला अनुमती देते, जे प्रसारण समाप्त झाल्यानंतर देखील तसेच राहते. अत्याधिक वापरामुळे बरीच मेमरी वापरली जाऊन तो टॅब्लेटला धीमा किंवा अस्थिर करू शकतो."</string>
     <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"रोचक प्रसारणे पाठविण्यास अॅपला अनुमती देते, जे प्रसारण समाप्त झाल्यानंतर तसेच रहाते. अतिरिक्त वापर टीव्ही धीमा किंवा यासाठी बरीच मेमरी वापरली जात असल्यामुळे तो अस्थिर करू शकतो."</string>
@@ -378,7 +377,7 @@
     <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, आपल्या टॅब्लेटचा कॉल लॉग सुधारित करण्यासाठी अॅप ला अनुमती देते. दुर्भावनापूर्ण अॅप्स आपला कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
     <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, आपल्या टीव्हीचा कॉल लॉग सुधारित करण्यासाठी अॅपला अनुमती देते. दुर्भावनापूर्ण अॅप्स आपला कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, आपल्या फोनचा कॉल लॉग सुधारित करण्यासाठी अॅप ला अनुमती देते. दुर्भावनापूर्ण अॅप्स आपला कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
-    <string name="permlab_bodySensors" msgid="4683341291818520277">"शरीर सेन्सरमध्ये (हृदय गती मॉनिटरसारखे) प्रवेश करा"</string>
+    <string name="permlab_bodySensors" msgid="4683341291818520277">"शरीर सेंसर (हृदय गती मॉनिटरसारखे) अॅक्सेस करा"</string>
     <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"हृदय गती सारख्या, आपल्या शारीरिक स्थितीचे नियंत्रण करणार्‍या सेन्सरवरून डेटामध्ये प्रवेश करण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"कॅलेंडर इव्हेंट आणि तपशील वाचा"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"हा अॅप आपल्या टॅब्लेटवर संचयित केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि सामायिक करू शकतो किंवा आपला कॅलेंडर डेटा जतन करू शकतो."</string>
@@ -388,30 +387,30 @@
     <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"हा अॅप आपल्या टॅब्लेटवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे संदेश पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
     <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"हा अॅप आपल्या टीव्हीवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे संदेश पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
     <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"हा अॅप आपल्या फोनवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे संदेश पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
-    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अतिरिक्त स्थान प्रदाता आदेशांवर प्रवेश करा"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अतिरिक्त स्थान प्रदाता आदेश अॅक्सेस करा"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"अ‍ॅपला अतिरिक्त स्‍थान प्रदाता आदेशावर प्रवेश करण्‍याची अनुमती देते. हे कदाचित अ‍ॅपला GPS किंवा इतर स्‍थान स्त्रोत च्या ऑपरेशनमध्‍ये हस्तक्षेप करण्‍याची अनुमती देऊ शकते."</string>
-    <string name="permlab_accessFineLocation" msgid="251034415460950944">"अचूक स्थानामध्ये (GPS आणि नेटवर्क-आधारित) प्रवेश करा"</string>
-    <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"हा अॅप सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या GPS किंवा नेटवर्क स्रोतांच्या आधारावर आपले स्थान मिळवू शकतो. या स्थान सेवा वापरण्यास सक्षम असण्यासाठी त्या आपल्या फोनवर चालू केलेल्या आणि उपलब्ध असणे आवश्यक आहे. हे बॅटरी वापर वाढवू शकते."</string>
-    <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"अंदाजे स्‍थानामध्ये (नेटवर्क-आधारित) प्रवेश करा"</string>
-    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"हा अॅप सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतांच्या आधारावर आपले स्थान मिळवू शकतो. अॅपला या स्थान सेवा वापरण्यास सक्षम असण्यासाठी आपल्या टॅॅब्लेटवर त्या चालू केलेल्या आणि उपलब्ध असणे आवश्यक आहे."</string>
-    <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"हा अॅप सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतांच्या आधारावर आपले स्थान मिळवू शकतो. अॅपला या स्थान सेवा वापरण्यास सक्षम असण्यासाठी आपल्या टीव्हीवर त्या चालू केलेल्या आणि उपलब्ध असणे आवश्यक आहे."</string>
-    <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"हा अॅप सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतांच्या आधारावर आपले स्थान मिळवू शकतो. अॅपला या स्थान सेवा वापरण्यास सक्षम असण्यासाठी आपल्या फोनवर त्या चालू केलेल्या आणि उपलब्ध असणे आवश्यक आहे."</string>
+    <string name="permlab_accessFineLocation" msgid="251034415460950944">"अचूक स्थानामध्ये (GPS आणि नेटवर्क-आधारित) अॅक्सेस करा"</string>
+    <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"हा अॅप सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या GPS किंवा नेटवर्क स्रोतांच्या आधारावर तुमचे स्थान मिळवू शकतो. या स्थान सेवा वापरण्यास सक्षम असण्यासाठी त्या तुमच्या फोनवर चालू केलेल्या आणि उपलब्ध असणे आवश्यक आहे. हे बॅटरी वापर वाढवू शकते."</string>
+    <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"अंदाजे स्‍थानामध्ये (नेटवर्क-आधारित) अॅक्सेस करा"</string>
+    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"हा अॅप सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतांच्या आधारावर तुमचे स्थान मिळवू शकतो. अॅपला या स्थान सेवा वापरण्यास सक्षम असण्यासाठी तुमच्या टॅब्लेटवर त्या चालू केलेल्या आणि उपलब्ध असणे आवश्यक आहे."</string>
+    <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"हा अॅप सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतांच्या आधारावर तुमचे स्थान मिळवू शकतो. अॅपला या स्थान सेवा वापरण्यास सक्षम असण्यासाठी तुमच्या टीव्हीवर त्या चालू केलेल्या आणि उपलब्ध असणे आवश्यक आहे."</string>
+    <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"हा अॅप सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतांच्या आधारावर तुमचे स्थान मिळवू शकतो. अॅपला या स्थान सेवा वापरण्यास सक्षम असण्यासाठी तुमच्या फोनवर त्या चालू केलेल्या आणि उपलब्ध असणे आवश्यक आहे."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"आपल्या ऑडिओ सेटिंग्ज बदला"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"व्हॉल्यूम आणि आउटपुटसाठी कोणता स्पीकर वापरला आहे यासारख्या समग्र ऑडिओ सेटिंग्ज सुधारित करण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ऑडिओ रेकॉर्ड"</string>
     <string name="permdesc_recordAudio" msgid="4245930455135321433">"हा अॅप कोणत्याही वेळी मायक्रोफोन वापरून ऑडिओ रेकॉर्ड करू शकता."</string>
-    <string name="permlab_sim_communication" msgid="2935852302216852065">"सिम वर आदेश पाठवा"</string>
-    <string name="permdesc_sim_communication" msgid="5725159654279639498">"अ‍ॅप ला सिम वर आदेश पाठविण्‍याची अनुमती देते. हे खूप धोकादायक असते."</string>
+    <string name="permlab_sim_communication" msgid="2935852302216852065">"सिम वर कमांड पाठवा"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"अ‍ॅप ला सिम वर कमांड पाठविण्‍याची अनुमती देते. हे खूप धोकादायक असते."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"चित्रे आणि व्हिडिओ घ्या"</string>
     <string name="permdesc_camera" msgid="5392231870049240670">"हा अॅप कोणत्याही वेळी कॅमेरा वापरून चित्रेे घेऊ आणि व्ह‍िडिअो रेकॉर्ड करू शकतो."</string>
     <string name="permlab_vibrate" msgid="7696427026057705834">"कंपन नियंत्रित करा"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"अॅप ला व्हायब्रेटर नियंत्रित करण्यासाठी अनुमती देते."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"फोन नंबरवर प्रत्यक्ष कॉल करा"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"आपल्या हस्तक्षेपाशिवाय फोन नंबरवर कॉल करण्यासाठी अॅप ला अनुमती देते. यामुळे अनपेक्षित शुल्क किंवा कॉल लागू शकतात. लक्षात ठेवा की हे आणीबाणीच्या नंबरवर कॉल करण्यासाठी अॅप ला अनुमती देत नाही. दुर्भावनापूर्ण अॅप्स नी आपल्या पुष्टिकरणाशिवाय कॉल केल्यामुळे आपले पैसे खर्च होऊ शकतात."</string>
-    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS कॉल सेवेमध्‍ये प्रवेश करा"</string>
+    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS कॉल सेवा अॅक्सेस करा"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"आपल्‍या हस्तक्षेपाशिवाय अ‍ॅपला कॉल करण्‍यासाठी IMS सेवा वापरण्याची अनुमती देते."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"फोन स्थिती आणि ओळख वाचा"</string>
-    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"डीव्हाइस च्या फोन वैशिष्ट्यांवर अॅक्सेस करण्यास अॅपला अनुमती देते. ही परवानगी कॉल अॅक्टिव्हेट असला किंवा नसला तरीही, फोन नंबर आणि डीव्हाइस आयडी आणि कॉलद्वारे कनेक्ट केलेला रीमोट नंबर निर्धारित करण्यासाठी अॅपला अनुमती देते."</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"डिव्हाइस च्या फोन वैशिष्ट्यांवर अॅक्सेस करण्यास अॅपला अनुमती देते. ही परवानगी कॉल अॅक्टिव्हेट असला किंवा नसला तरीही, फोन नंबर आणि डिव्हाइस आयडी आणि कॉलद्वारे कनेक्ट केलेला रीमोट नंबर निर्धारित करण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"प्रणालीच्या माध्यमातून कॉल रूट करा"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"कॉल करण्याचा अनुभव सुधारण्यासाठी अॅपला त्याचे कॉल प्रणालीच्या माध्यमातून रूट करू देते."</string>
     <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"फोन नंबर वाचा"</string>
@@ -427,9 +426,9 @@
     <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"टीव्हीचे इन्फ्रारेड ट्रान्समीटर वापरण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"अ‍ॅप ला फोनच्‍या इन्‍फ्रारेड ट्रान्‍समीटरचा वापर करण्‍याची अनुमती देते."</string>
     <string name="permlab_setWallpaper" msgid="6627192333373465143">"वॉलपेपर सेट करा"</string>
-    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"सिस्टीम वॉलपेपर सेट करण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"सिस्टम वॉलपेपर सेट करण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"आपला वॉलपेपर आकार समायोजित करा"</string>
-    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"सिस्टीम वॉलपेपर आकार सूचना सेट करण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"सिस्टम वॉलपेपर आकार सूचना सेट करण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"टाइम झोन सेट करा"</string>
     <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"टॅब्लेटचा टाइम झोन बदलण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"टीव्हीचा टाईम झोन बदलण्यासाठी अॅपला अनुमती देते."</string>
@@ -447,27 +446,27 @@
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"टिथर केलेली कनेक्टिव्हिटी बदला"</string>
     <string name="permdesc_changeTetherState" msgid="1524441344412319780">"टेदर केलेल्या नेटवर्क कनेक्टिव्हिटीची स्थिती बदलण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"वाय-फाय कनेक्शन पहा"</string>
-    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"वाय-फाय सक्षम केले आहे किंवा नाही आणि कनेक्ट केलेल्या वाय-फाय डिव्हाइसेसचे नाव यासारख्या, वाय-फाय नेटवर्किंग विषयीची माहिती पाहण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"वाय-फाय सक्षम केले आहे किंवा नाही आणि कनेक्ट केलेल्या वाय-फाय डीव्हाइसचे नाव यासारख्या, वाय-फाय नेटवर्किंग विषयीची माहिती पाहण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"वाय-फाय वरून कनेक्ट करा आणि डिस्कनेक्ट करा"</string>
-    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"वाय-फाय अॅक्सेस बिंदूंवर कनेक्ट करण्यासाठी आणि त्यावरून डिस्कनेक्ट करण्यासाठी आणि वाय-फाय नेटवर्कसाठी डीव्हाइस कॉंफिगरेशनमध्ये बदल करण्यासाठी अॅपला अनुमती देते."</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"वाय-फाय अॅक्सेस बिंदूंवर कनेक्ट करण्यासाठी आणि त्यावरून डिस्कनेक्ट करण्यासाठी आणि वाय-फाय नेटवर्कसाठी डिव्हाइस कॉंफिगरेशनमध्ये बदल करण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"वाय-फाय मल्‍टिकास्‍ट रिसेप्‍शनला अनुमती द्या"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"मल्टिकास्ट पत्ते वापरून फक्त आपल्या टॅब्लेटवर नाही, तर वाय-फाय नेटवर्कवरील सर्व डिव्हाइसेसवर पाठविलेले पॅकेट प्राप्त करण्यासाठी अॅप ला अनुमती देते. हे गैर-मल्टिकास्ट मोडपेक्षा अधिक पॉवर वापरते."</string>
-    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"केवळ आपला टीव्ही न वापरता, एकाधिक पत्ते वापरून एका वाय-फाय नेटवकवरील सर्व डिव्हाइसवर पाठविलेली पॅकेट प्राप्त करण्यासाठी अॅपला अनुमती देते."</string>
-    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"मल्टिकास्ट पत्ते वापरून फक्त आपल्या फोनवर नाही, तर वाय-फाय नेटवर्कवरील सर्व डिव्हाइसेसवर पाठविलेले पॅकेट प्राप्त करण्यासाठी अॅप ला अनुमती देते. हे गैर-मल्टिकास्ट मोडपेक्षा अधिक पॉवर वापरते."</string>
-    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"ब्लूटुथ सेटिंग्जवर प्रवेश करा"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"स्थानिक ब्लूटुथ टॅबलेट कॉन्फिगर करण्याकरिता आणि दूरस्थ डिव्हाइसेस शोधण्यासाठी आणि त्यासह जोडण्यासाठी अॅप ला अनुमती देते."</string>
-    <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"स्थानिक ब्लूटुथ टीव्ही कॉन्फिगर करण्यासाठी आणि दूरस्थ डिव्हाइसेससह शोधण्यासाठी आणि जोडण्यासाठी अॅपला अनुमती देते."</string>
-    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"स्थानिक ब्लूटुथ फोन कॉन्फिगर करण्याकरिता आणि दूरस्थ डिव्हाइसेस शोधण्यासाठी आणि त्यासह जोडण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"मल्टिकास्ट पत्ते वापरून फक्त तुमच्या टॅब्लेटवर नाही, तर वाय-फाय नेटवर्कवरील सर्व डीव्हाइसवर पाठविलेले पॅकेट प्राप्त करण्यासाठी अॅप ला अनुमती देते. हे मल्टिकास्टखेरिज इतर मोडसाठी अधिक पॉवर वापरते."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"केवळ आपला टीव्ही न वापरता, एकाधिक पत्ते वापरून एका वाय-फाय नेटवकवरील सर्व डीव्हाइसवर पाठविलेली पॅकेट प्राप्त करण्यासाठी अॅपला अनुमती देते."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"मल्टिकास्ट पत्ते वापरून फक्त तुमच्या फोनवर नाही, तर वाय-फाय नेटवर्कवरील सर्व डीव्हाइसवर पाठविलेले पॅकेट प्राप्त करण्यासाठी अॅप ला अनुमती देते. हे मल्टिकास्टखेरिज इतर मोडसाठी अधिक पॉवर वापरते."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"ब्लूटूथ सेटिंग्ज अॅक्सेस करा"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"स्थानिक ब्लूटूथ टॅबलेट कॉंफिगर करण्याकरिता आणि दूरस्थ डिव्हाइस शोधण्यासाठी आणि त्यासह जोडण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"स्थानिक ब्लूटूथ टीव्ही कॉंफिगर करण्यासाठी आणि दूरस्थ डीव्हाइससह शोधण्यासाठी आणि जोडण्यासाठी अॅपला अनुमती देते."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"स्थानिक ब्लूटूथ फोन कॉंफिगर करण्याकरिता आणि दूरस्थ डिव्हाइस शोधण्यासाठी आणि त्यासह जोडण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_accessWimaxState" msgid="4195907010610205703">"WiMAX कनेक्ट करा आणि त्यावरून डिस्कनेक्ट करा"</string>
     <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"WiMAX सक्षम केले आहे किंवा नाही आणि कनेक्ट केलेल्या कोणत्याही WiMAX नेटवर्क विषयीची माहिती निर्धारित करण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_changeWimaxState" msgid="340465839241528618">"WiMAX स्थिती बदला"</string>
     <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"WiMAX नेटवर्कवर टॅबलेट कनेक्ट करण्यास आणि त्यावरून टॅबलेट डिस्कनेक्ट करण्यास अॅप ला अनुमती देते."</string>
     <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"WiMAX नेटवर्कवरून टीव्ही कनेक्ट करण्यासाठी आणि त्यावरून टीव्ही डिस्कनेक्ट करण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"WiMAX नेटवर्कवर फोन कनेक्ट करण्यास आणि त्यावरून फोन डिस्कनेक्ट करण्यास अॅप ला अनुमती देते."</string>
-    <string name="permlab_bluetooth" msgid="6127769336339276828">"ब्लुटूथ डीव्हाइससह जोडा"</string>
-    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"टॅब्लेटवर ब्लूटुथ चे कॉन्फिगरेशन पाहण्यासाठी आणि जोडलेल्या डिव्हाइसेससह कनेक्शन करण्यासाठी आणि स्वीकारण्यासाठी, अॅप ला अनुमती देते."</string>
-    <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"टीव्हीवर ब्लूटुथचे कॉन्फिगरेशन पाहण्यासाठी आणि जोडलेल्या डिव्हाइसेससह कनेक्शन करण्यासाठी आणि स्वीकारण्यासाठी अॅपला अनुमती देते."</string>
-    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"फोनवर ब्लूटुथ चे कॉन्फिगरेशन पाहण्यासाठी आणि जोडलेल्या डिव्हाइसेससह कनेक्शन करण्यासाठी आणि स्वीकारण्यासाठी, अॅप ला अनुमती देते."</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"ब्लूटूथ डीव्हाइससह जोडा"</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"टॅबलेटवर ब्लूटूथ चे कॉंफिगरेशन पाहण्यासाठी आणि पेअर केलेल्या डीव्हाइससह कनेक्शन स्थापित करण्यासाठी आणि स्वीकारण्यासाठी, अॅप ला अनुमती देते."</string>
+    <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"टीव्हीवर ब्लूटूथचे कॉंफिगरेशन पाहण्यासाठी आणि जोडलेल्या डीव्हाइससह कनेक्शन स्थापित करण्यासाठी आणि स्वीकारण्यासाठी अॅपला अनुमती देते."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"फोनवर ब्लूटूथ चे कॉंफिगरेशन पाहण्यासाठी आणि पेअर केलेल्या डीव्हाइससह कनेक्शन स्थापित करण्यासाठी आणि स्वीकारण्यासाठी, अॅप ला अनुमती देते."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"फील्ड जवळील कम्युनिकेशन नियंत्रित करा"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"फील्ड जवळील कम्युनिकेशन (NFC) टॅग, कार्डे आणि वाचक यांच्यासह संवाद करण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"आपले स्क्रीन लॉक अक्षम करा"</string>
@@ -484,7 +483,7 @@
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"फिंगरप्रिंट हार्डवेअर उपलब्‍ध नाही."</string>
-    <string name="fingerprint_error_no_space" msgid="1055819001126053318">"फिंगरप्रिंट संचयित केले जाऊ शकत नाही. कृपया विद्यमान फिंगरप्रिंट काढा."</string>
+    <string name="fingerprint_error_no_space" msgid="1055819001126053318">"फिंगरप्रिंट स्टोअर केले जाऊ शकत नाही. कृपया विद्यमान फिंगरप्रिंट काढा."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"फिंगरप्रिंट टाइमआउट झाले. पुन्हा प्रयत्न करा."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"फिंगरप्रिंट ऑपरेशन रद्द झाले."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"खूप प्रयत्न केले. नंतर पुन्हा प्रयत्न करा."</string>
@@ -493,7 +492,7 @@
     <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g> बोट"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
-    <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"फिंगरप्रिंट चिन्ह"</string>
+    <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"फिंगरप्रिंट आयकन"</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"संकालन सेटिंग्‍ज वाचा"</string>
     <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"खात्याच्या संकालन सेटिंग्ज वाचण्यासाठी अॅप ला अनुमती देते. उदाहरणार्थ, हे खात्यासह लोकांचा अॅप संकालित केला आहे किंवा नाही हे निर्धारित करू शकते."</string>
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"संकालन चालू आणि बंद करा टॉगल करा"</string>
@@ -540,9 +539,9 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"होल्‍डरला वाहकद्वारे-प्रदान केलेल्या कॉन्फिगरेशन अ‍ॅपची विनंती करण्‍याची अनुमती देते. सामान्‍य अ‍ॅप्‍ससाठी कधीही आवश्‍यक नसावे."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"नेटवर्क स्‍थितींवरील निरीक्षणांसाठी ऐका"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"अनु्प्रयोगाला नेटवर्क स्‍थितींवरील निरीक्षणे ऐकण्‍यासाठी अनुमती देते. सामान्‍य अ‍ॅप्‍ससाठी कधीही आवश्‍यक नसावे."</string>
-    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"इनपुट डीव्हाइस कॅलिब्रेशन बदला"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"इनपुट डिव्हाइस कॅलिब्रेशन बदला"</string>
     <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"स्पर्श स्क्रीनची कॅलिब्रेशन प्राचले सुधारित करण्यासाठी अॅप ला अनुमती देते. सामान्य अॅप्स साठी कधीही आवश्यक नसते."</string>
-    <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM प्रमाणपत्रांवर प्रवेश करा"</string>
+    <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM प्रमाणपत्रे अॅक्सेस करा"</string>
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM प्रमाणपत्रांची तरतूद करण्यासाठी आणि वापरण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य अॅप्सकरिता कधीही आवश्यकता नसते."</string>
     <string name="permlab_handoverStatus" msgid="7820353257219300883">"Android बीम स्थानांतरण स्थिती प्राप्त करा"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"वर्तमान Android बीम स्थानांतरणांविषयी माहिती प्राप्त करण्यासाठी या अनुप्रयोगास अनुमती देते"</string>
@@ -552,10 +551,10 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"वाहक मेसेजिंग सेवेचा शीर्ष-स्तर इंटरफेस बाइंड करण्यासाठी होल्डरला अनुमती देतो. सामान्‍य अ‍ॅप्‍सकरिता हे कधीही आवश्‍यक नसते."</string>
     <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"वाहक सेवांवर प्रतिबद्ध करा"</string>
     <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"वाहक सेवांवर प्रतिबद्ध करण्यासाठी होल्डरला अनुमती देते. सामान्य अॅप्ससाठी कधीही आवश्यकता नसावी."</string>
-    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"व्यत्यय आणू नका मध्ये प्रवेश करा"</string>
+    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"व्यत्यय आणू नका अॅक्सेस करा"</string>
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"व्यत्यय आणू नका कॉन्फिगरेशन वाचण्यासाठी आणि लिहिण्यासाठी अॅपला अनुमती देते."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"संकेतशब्द नियम सेट करा"</string>
-    <string name="policydesc_limitPassword" msgid="2502021457917874968">"स्क्रीन लॉक संकेतशब्द आणि पिन मध्ये अनुमती दिलेली लांबी आणि वर्ण नियंत्रित करा."</string>
+    <string name="policydesc_limitPassword" msgid="2502021457917874968">"स्क्रीन लॉक पासवर्ड आणि पिन मध्ये अनुमती दिलेले लांबी आणि वर्ण नियंत्रित करा."</string>
     <string name="policylab_watchLogin" msgid="5091404125971980158">"स्क्रीन अनलॉक प्रयत्नांचे परीक्षण करा"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"टाइप केलेल्या अयोग्य संकेतशब्दांच्या अंकांचे परीक्षण करा. स्क्रीन अनलॉक केली जाते, तेव्हा टॅबलेट लॉक करा किंवा बरेच संकेतशब्द टाइप केले असल्यास टॅबलेटचा सर्व डेटा मिटवा."</string>
     <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"स्क्रीन अनलॉक करताना टाइप केलेल्या चुकीच्या संकेतशब्दांच्या संख्येचे परीक्षण करा आणि टीव्ही लॉक करा किंवा अनेक चुकीचे संकेतशब्द टाइप केले असल्यास टीव्हीचा सर्व डेटा मिटवा."</string>
@@ -575,14 +574,14 @@
     <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"कोणत्याही चेतावणी शिवाय या वापरकर्त्याचा या टॅब्लेटवरील डेटा मिटवा."</string>
     <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"कोणत्याही चेतावणी शिवाय या वापरकर्त्याचा या टीव्ही वरील डेटा मिटवा."</string>
     <string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"कोणत्याही चेतावणी शिवाय या वापरकर्त्याचा या फोनवरील डेटा मिटवा."</string>
-    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"डीव्हाइस समग्र प्रॉक्सी सेट करा"</string>
-    <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"धोरण सक्षम असताना वापरण्यासाठी डीव्हाइस समग्र प्रॉक्सी सेट करा. फक्त डीव्हाइस मालक समग्र प्रॉक्सी सेट करु शकतो."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"डिव्हाइस समग्र प्रॉक्सी सेट करा"</string>
+    <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"धोरण सक्षम असताना वापरण्यासाठी डिव्हाइस समग्र प्रॉक्सी सेट करा. फक्त डिव्हाइस मालक समग्र प्रॉक्सी सेट करु शकतो."</string>
     <string name="policylab_expirePassword" msgid="5610055012328825874">"स्क्रीन लॉक संकेतशब्द कालबाह्यता सेट करा"</string>
     <string name="policydesc_expirePassword" msgid="5367525762204416046">"लॉक-स्क्रीन संकेतशब्द किती वारंवार बदलणे आवश्यक आहे ते बदला."</string>
-    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"संचयन कूटबद्धीकरण सेट करा"</string>
-    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"संचयित अॅप डेटा कूटबद्ध केला जाणे आवश्यक आहे."</string>
+    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"स्टोरेज एंक्रिप्शन सेट करा"</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"स्टोअर केलेला अॅप डेटा एंक्रिप्ट केला जाणे आवश्यक आहे."</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"कॅमेरे अक्षम करा"</string>
-    <string name="policydesc_disableCamera" msgid="2306349042834754597">"सर्व डीव्हाइस कॅमेर्‍यांचा वापर प्रतिबंधित करा."</string>
+    <string name="policydesc_disableCamera" msgid="2306349042834754597">"सर्व डिव्हाइस कॅमेर्‍यांचा वापर प्रतिबंधित करा."</string>
     <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"काही स्क्रीन लॉक वैशिष्‍ट्ये अक्षम करा"</string>
     <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"काही स्क्रीन लॉक वैशिष्‍ट्यांचा वापर प्रतिबंधित करा."</string>
   <string-array name="phoneTypes">
@@ -647,7 +646,7 @@
     <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
     <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"कार्य मोबाईल"</string>
     <string name="phoneTypeWorkPager" msgid="649938731231157056">"कार्य पेजर"</string>
-    <string name="phoneTypeAssistant" msgid="5596772636128562884">"सहाय्यक"</string>
+    <string name="phoneTypeAssistant" msgid="5596772636128562884">"साहाय्यक"</string>
     <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
     <string name="eventTypeCustom" msgid="7837586198458073404">"सानुकूल"</string>
     <string name="eventTypeBirthday" msgid="2813379844211390740">"वाढदिवस"</string>
@@ -680,7 +679,7 @@
     <string name="orgTypeOther" msgid="3951781131570124082">"अन्य"</string>
     <string name="orgTypeCustom" msgid="225523415372088322">"सानुकूल"</string>
     <string name="relationTypeCustom" msgid="3542403679827297300">"सानुकूल"</string>
-    <string name="relationTypeAssistant" msgid="6274334825195379076">"सहाय्यक"</string>
+    <string name="relationTypeAssistant" msgid="6274334825195379076">"साहाय्यक"</string>
     <string name="relationTypeBrother" msgid="8757913506784067713">"भाऊ"</string>
     <string name="relationTypeChild" msgid="1890746277276881626">"मूल"</string>
     <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"घरातील जोडीदार"</string>
@@ -762,7 +761,7 @@
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"वापरकर्तानाव (ईमेल)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"संकेतशब्द"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"साइन इन करा"</string>
-    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"अवैध वापरकर्तानाव किंवा संकेतशब्द."</string>
+    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"अवैध वापरकर्तानाव किंवा पासवर्ड."</string>
     <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"आपले वापरकर्तानाव किंवा संकेतशब्द विसरलात?\n "<b>"google.com/accounts/recovery"</b>" ला भेट द्या."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"तपासत आहे..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"अनलॉक करा"</string>
@@ -800,7 +799,7 @@
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
     <string name="granularity_label_character" msgid="7336470535385009523">"वर्ण"</string>
     <string name="granularity_label_word" msgid="7075570328374918660">"शब्द"</string>
-    <string name="granularity_label_link" msgid="5815508880782488267">"दुवा"</string>
+    <string name="granularity_label_link" msgid="5815508880782488267">"लिंक"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"रेखा"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"फॅक्टरी चाचणी अयशस्वी"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST क्रिया फक्त /सिस्टम/अॅप मध्ये इंस्टॉल केलेल्या पॅकेजसाठी समर्थित आहे."</string>
@@ -835,9 +834,9 @@
     <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"आपले वेब बुकमार्क आणि इतिहास वाचा"</string>
     <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"ब्राउझरने भेट दिलेल्या सर्व URL चा इतिहास आणि ब्राउझरचे सर्व बुकमार्क वाचण्यास अॅप ला अनुमती देते. टीप: या परवानगीची तृतीय-पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमता असलेल्या अन्य अनुप्रयोगांद्वारे अंमलबजावणी करू शकत नाही."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"वेब बुकमार्क आणि इतिहास लिहा"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"आपल्या टॅब्लेटवर संचयित केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अॅप ला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अॅप ला अनुमती देते. टीप: ही परवानगी तृतीय पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमतांसह अन्य अनुप्रयोगांद्वारे अंमलबजावणी करण्याची टीप देऊ शकते."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"आपल्या टीव्हीवर संचयित केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अॅपला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अॅपला अनुमती देऊ शकते. टीप: या परवानगीची अंमलबजावणी वेब ब्राउझिंग क्षमता असलेल्या तृतीय-पक्ष ब्राउझरद्वारे किंवा इतर अनुप्रयोगांद्वारे केली जाऊ शकत नाही."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"आपल्या फोनवर संचयित केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अॅप ला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अॅप ला अनुमती देते. टीप: ही परवानगी तृतीय पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमतांसह अन्य अनुप्रयोगांद्वारे अंमलबजावणी करण्याची टीप देऊ शकते."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"तुमच्या टॅब्लेटवर संचयित केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अॅप ला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अॅप ला अनुमती देते. टीप: ही परवानगी तृतीय पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमतांसह अन्य अॅप्लिकेशनद्वारे अंमलबजावणी करण्याची टीप देऊ शकते."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"तुमच्या टीव्हीवर संचयित केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अॅपला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अॅपला अनुमती देऊ शकते. टीप: या परवानगीची अंमलबजावणी वेब ब्राउझिंग क्षमता असलेल्या तृतीय-पक्ष ब्राउझरद्वारे किंवा इतर अॅप्लिकेशनद्वारे केली जाऊ शकत नाही."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"तुमच्या फोनवर संचयित केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अॅप ला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अॅप ला अनुमती देते. टीप: ही परवानगी तृतीय पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमतांसह अन्य अॅप्लिकेशनद्वारे अंमलबजावणी करण्याची टीप देऊ शकते."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"अलार्म सेट करा"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"इंस्टॉल केलेल्या अलार्म घड्याळ अॅपमध्ये अलार्म सेट करण्यासाठी अॅपला अनुमती देते. काही अलार्म घड्याळ अॅप्समध्ये हे वैशिष्ट्य नसू शकते."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"व्हॉइसमेल जोडा"</string>
@@ -1015,13 +1014,13 @@
     <string name="whichSendToApplicationLabel" msgid="8878962419005813500">"पाठवा"</string>
     <string name="whichHomeApplication" msgid="4307587691506919691">"होम अ‍ॅप निवडा"</string>
     <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"होम म्हणून %1$s वापरा"</string>
-    <string name="whichHomeApplicationLabel" msgid="809529747002918649">"प्रतिमा कॅप्चर करा"</string>
-    <string name="whichImageCaptureApplication" msgid="3680261417470652882">"यासह प्रतिमा कॅप्चर करा"</string>
-    <string name="whichImageCaptureApplicationNamed" msgid="8619384150737825003">"%1$s सह प्रतिमा कॅप्चर करा"</string>
-    <string name="whichImageCaptureApplicationLabel" msgid="6390303445371527066">"प्रतिमा कॅप्चर करा"</string>
+    <string name="whichHomeApplicationLabel" msgid="809529747002918649">"इमेज कॅप्चर करा"</string>
+    <string name="whichImageCaptureApplication" msgid="3680261417470652882">"यासह इमेज कॅप्चर करा"</string>
+    <string name="whichImageCaptureApplicationNamed" msgid="8619384150737825003">"%1$s सह इमेज कॅप्चर करा"</string>
+    <string name="whichImageCaptureApplicationLabel" msgid="6390303445371527066">"इमेज कॅप्चर करा"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"या क्रियेसाठी डीफॉल्‍टनुसार वापरा."</string>
     <string name="use_a_different_app" msgid="8134926230585710243">"एक भिन्न अ‍ॅप वापरा"</string>
-    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"डाउनलोड केलेल्या सिस्टीम सेटिंग्ज &gt; Apps &gt; मधील डीफॉल्ट साफ करा."</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"डाउनलोड केलेल्या सिस्टम सेटिंग्ज &gt; Apps &gt; मधील डीफॉल्ट साफ करा."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"क्रिया निवडा"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"USB डिव्हाइससाठी अॅप निवडा"</string>
     <string name="noApplications" msgid="2991814273936504689">"कोणतेही अॅप्स ही क्रिया करू शकत नाहीत."</string>
@@ -1032,7 +1031,7 @@
     <string name="aerr_restart" msgid="7581308074153624475">"अॅप पुन्हा उघडा"</string>
     <string name="aerr_report" msgid="5371800241488400617">"अभिप्राय पाठवा"</string>
     <string name="aerr_close" msgid="2991640326563991340">"बंद करा"</string>
-    <string name="aerr_mute" msgid="1974781923723235953">"डीव्हाइस रीस्टार्ट होईपर्यंत म्युट करा"</string>
+    <string name="aerr_mute" msgid="1974781923723235953">"डिव्हाइस रीस्टार्ट होईपर्यंत म्युट करा"</string>
     <string name="aerr_wait" msgid="3199956902437040261">"प्रतीक्षा करा"</string>
     <string name="aerr_close_app" msgid="3269334853724920302">"अॅप बंद करा"</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
@@ -1049,8 +1048,8 @@
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> मूळतः लाँच केले."</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"स्केल"</string>
     <string name="screen_compat_mode_show" msgid="4013878876486655892">"नेहमी दर्शवा"</string>
-    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"सिस्टीम सेटिंग्ज &gt; Apps &gt; डाउनलोड केलेले मध्ये हे पुन्हा-सक्षम करा."</string>
-    <string name="unsupported_display_size_message" msgid="6545327290756295232">"<xliff:g id="APP_NAME">%1$s</xliff:g> वर्तमान प्रदर्शन आकार सेटिंगला समर्थन देत नाही आणि अनपेक्षित वर्तन करू शकते."</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"सिस्टम सेटिंग्ज &gt; Apps &gt; डाउनलोड केलेले मध्ये हे पुन्हा-सक्षम करा."</string>
+    <string name="unsupported_display_size_message" msgid="6545327290756295232">"<xliff:g id="APP_NAME">%1$s</xliff:g> वर्तमान डिस्प्ले आकार सेटिंगला समर्थन देत नाही आणि अनपेक्षित वर्तन करू शकते."</string>
     <string name="unsupported_display_size_show" msgid="7969129195360353041">"नेहमी दर्शवा"</string>
     <string name="smv_application" msgid="3307209192155442829">"अॅप <xliff:g id="APPLICATION">%1$s</xliff:g> (प्रक्रिया <xliff:g id="PROCESS">%2$s</xliff:g>) ने तिच्या स्वयं-लागू केलेल्या StrictMode धोरणाचे उल्लंघन केले आहे."</string>
     <string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> प्रक्रियेने तिच्या स्वतः-लागू केलेल्या StrictMode धोरणाचे उल्लंघन केले."</string>
@@ -1070,7 +1069,7 @@
     <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"आपण एक नवीन प्रारंभ करण्यापूर्वी आधीपासून चालणारा दुसरा अॅप थांबविणे आवश्यक आहे."</string>
     <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> कडे परत"</string>
     <string name="old_app_description" msgid="2082094275580358049">"नवीन अॅप प्रारंभ करू नका."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> प्रारंभ करा"</string>
+    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> सुरू करा"</string>
     <string name="new_app_description" msgid="1932143598371537340">"जतन न करता जुना अॅप थांबवा."</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ने मेमेरी मर्यादा वाढविली"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"हीप डंप संकलित केला गेला आहे; सामायिक करण्यासाठी टॅप करा"</string>
@@ -1079,14 +1078,14 @@
     <string name="sendText" msgid="5209874571959469142">"मजकुरासाठी क्रिया निवडा"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"रिंगर व्हॉल्यूम"</string>
     <string name="volume_music" msgid="5421651157138628171">"मीडिया व्हॉल्यूम"</string>
-    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"ब्लूटुथ द्वारे प्‍ले करत आहे"</string>
+    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"ब्लूटूथ द्वारे प्‍ले करत आहे"</string>
     <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"मूक रिंगटोन सेट केला"</string>
     <string name="volume_call" msgid="3941680041282788711">"कॉल-मधील व्हॉल्यूम"</string>
-    <string name="volume_bluetooth_call" msgid="2002891926351151534">"ब्लूटुथ कॉल-मधील व्हॉल्यूम"</string>
+    <string name="volume_bluetooth_call" msgid="2002891926351151534">"ब्लूटूथ कॉल-मधील व्हॉल्यूम"</string>
     <string name="volume_alarm" msgid="1985191616042689100">"अलार्म व्हॉल्यूम"</string>
     <string name="volume_notification" msgid="2422265656744276715">"सूचना व्हॉल्यूम"</string>
     <string name="volume_unknown" msgid="1400219669770445902">"व्हॉल्यूम"</string>
-    <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"ब्लूटुथ व्हॉल्यूम"</string>
+    <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"ब्लूटूथ व्हॉल्यूम"</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>
@@ -1106,19 +1105,26 @@
       <item quantity="one">खुले वाय-फाय नेटवर्क उपलब्ध</item>
       <item quantity="other">खुले वाय-फाय नेटवर्क उपलब्ध</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"खुल्या वाय-फाय नेटवर्कशी कनेक्ट करा"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"खुल्या वाय-फाय नेटवर्कशी कनेक्ट करत आहे"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"वाय-फाय नेटवर्कशी कनेक्ट केले"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"वाय-फाय नेटवर्कशी कनेक्ट करू शकत नाही"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सर्व नेटवर्क पाहण्यासाठी टॅप करा"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"कनेक्ट करा"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"सर्व नेटवर्क"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"वाय-फाय नेटवर्कमध्‍ये साइन इन करा"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"नेटवर्कवर साइन इन करा"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8451173622563841546">"वाय-फायवरून इंटरनेटवर प्रवेश नाही"</string>
+    <string name="wifi_no_internet" msgid="8451173622563841546">"वाय-फायवरून इंटरनेटवर अॅक्सेस नाही"</string>
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"पर्यायांसाठी टॅप करा"</string>
     <string name="network_switch_metered" msgid="4671730921726992671">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> वर स्विच केले"</string>
-    <string name="network_switch_metered_detail" msgid="5325661434777870353">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> कडे इंटरनेट अॅक्सेस नसताना डीव्हाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> वापरतो. शुल्क लागू शकेल."</string>
+    <string name="network_switch_metered_detail" msgid="5325661434777870353">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> कडे इंटरनेट अॅक्सेस नसताना डिव्हाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> वापरते. शुल्क लागू शकेल."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> वरून <xliff:g id="NEW_NETWORK">%2$s</xliff:g> वर स्विच केले"</string>
   <string-array name="network_switch_type_name">
     <item msgid="3979506840912951943">"मोबाइल डेटा"</item>
     <item msgid="75483255295529161">"वाय-फाय"</item>
-    <item msgid="6862614801537202646">"ब्लूटुथ"</item>
+    <item msgid="6862614801537202646">"ब्लूटूथ"</item>
     <item msgid="5447331121797802871">"इथरनेट"</item>
     <item msgid="8257233890381651999">"VPN"</item>
   </string-array>
@@ -1128,10 +1134,10 @@
     <string name="wifi_connect_alert_title" msgid="8455846016001810172">"कनेक्शनला अनुमती द्यायची?"</string>
     <string name="wifi_connect_alert_message" msgid="6451273376815958922">"%1$s अॅप्लिकेशन %2$s वायफाय नेटवर्कशी कनेक्ट करू इच्छित आहे"</string>
     <string name="wifi_connect_default_application" msgid="7143109390475484319">"अॅप्लिकेशन"</string>
-    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"वाय-फाय थेट"</string>
-    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"वाय-फाय थेट प्रारंभ करा. हे वाय-फाय क्लायंट/हॉटस्पॉट बंद करेल."</string>
-    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"वाय-फाय थेट प्रारंभ करू शकलो नाही."</string>
-    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"वाय-फाय थेट चालू आहे"</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"वाय-फाय डिरेक्ट"</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"वाय-फाय थेट सुरू करा. हे वाय-फाय क्लायंट/हॉटस्पॉट बंद करेल."</string>
+    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"वाय-फाय डिरेक्ट कनेक्ट करू शकलो नाही."</string>
+    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"वाय-फाय डिरेक्ट चालू आहे"</string>
     <string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"सेटिंग्जसाठी टॅप करा"</string>
     <string name="accept" msgid="1645267259272829559">"स्वीकार करा"</string>
     <string name="decline" msgid="2112225451706137894">"नकार द्या"</string>
@@ -1141,12 +1147,12 @@
     <string name="wifi_p2p_to_message" msgid="248968974522044099">"प्रति:"</string>
     <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"आवश्यक पिन टाइप करा:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"पिन:"</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"टॅब्‍लेट <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ला कनेक्‍ट केलेले असताना तात्‍पुरते वाय-फाय वरून डिस्‍कनेक्‍ट होईल"</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"टीव्ही <xliff:g id="DEVICE_NAME">%1$s</xliff:g> शी कनेक्ट केलेला असताना वाय-फायवरून तो तात्पुरता डिस्कनेक्ट होईल"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"टॅबलेट <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ला कनेक्‍ट केलेले असताना तात्‍पुरते वाय-फाय वरून डिस्‍कनेक्‍ट होईल"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"टीव्ही <xliff:g id="DEVICE_NAME">%1$s</xliff:g> शी कनेक्ट केलेला असताना वाय-फायवरून तात्पुरता डिस्कनेक्ट होईल"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> वर फोन कनेक्ट केलेला असताना तो वाय-फाय वरून तात्पुरता डिस्कनेक्ट केला जाईल"</string>
     <string name="select_character" msgid="3365550120617701745">"वर्ण घाला"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"SMS संदेश पाठवत आहे"</string>
-    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; मोठ्या संख्येने SMS संदेश पाठवत आहे. आपण या अॅप ला संदेश पाठविणे सुरु ठेवण्याची अनुमती देऊ इच्छिता?"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; मोठ्या संख्येने SMS संदेश पाठवत आहे. तुम्ही या अॅप ला संदेश पाठविणे सुरु ठेवण्याची अनुमती देऊ इच्छिता?"</string>
     <string name="sms_control_yes" msgid="3663725993855816807">"अनुमती द्या"</string>
     <string name="sms_control_no" msgid="625438561395534982">"नकार द्या"</string>
     <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; हा &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;वर एक संदेश पाठवू इच्छितो."</string>
@@ -1154,7 +1160,7 @@
     <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"यामुळे आपल्या मोबाईल खात्यावर शुल्क आकारले जाऊ शकते."</b></string>
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"पाठवा"</string>
     <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"रद्द करा"</string>
-    <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"माझी आवड लक्षात ठेवा"</string>
+    <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"माझी वड लक्षात ठेवा"</string>
     <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"आपण हे नंतर सेटिंग्ज आणि अॅप्स मध्ये बदलू शकता"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"नेहमी अनुमती द्या"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"कधीही अनुमती देऊ नका"</string>
@@ -1162,7 +1168,7 @@
     <string name="sim_removed_message" msgid="2333164559970958645">"आपण एक वैध सिम कार्ड घालून प्रारंभ करेपर्यंत मोबाईल नेटवर्क अनुपलब्ध असेल."</string>
     <string name="sim_done_button" msgid="827949989369963775">"पूर्ण झाले"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"सिम कार्ड जोडले"</string>
-    <string name="sim_added_message" msgid="6599945301141050216">"मोबाईल नेटवर्कवर अॅक्सेस करण्यासाठी तुमचे डीव्हाइस रीस्टार्ट करा."</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"मोबाईल नेटवर्कवर अॅक्सेस करण्यासाठी तुमचे डिव्हाइस रीस्टार्ट करा."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"रीस्टार्ट"</string>
     <string name="carrier_app_dialog_message" msgid="7066156088266319533">"आपल्या नवीन सिमने योग्यरित्या कार्य करण्यासाठी, आपल्याला अॅप इंस्टॉल करण्याची आणि तो आपल्या वाहकामधून उघडण्याची आवश्यकता असेल."</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"अ‍ॅप मिळवा"</string>
@@ -1178,19 +1184,21 @@
     <string name="no_permissions" msgid="7283357728219338112">"परवानग्या आवश्यक नाहीत"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"यासाठी आपले पैसे खर्च होऊ शकतात"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"ठीक"</string>
-    <string name="usb_charging_notification_title" msgid="6895185153353640787">"USB हे डीव्हाइस चार्ज करत आहे"</string>
+    <string name="usb_charging_notification_title" msgid="6895185153353640787">"USB हे डिव्हाइस चार्ज करत आहे"</string>
     <string name="usb_supplying_notification_title" msgid="5310642257296510271">"USB संलग्न केलेल्या डिव्हाइसला पॉवरचा पुरवठा करीत आहे"</string>
     <string name="usb_mtp_notification_title" msgid="8396264943589760855">"स्थानांतरणासाठी USB"</string>
     <string name="usb_ptp_notification_title" msgid="1347328437083192112">"फोटो स्थानांतरणासाठी USB"</string>
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI साठी USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB उपसाधनावर कनेक्ट केले"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"अधिक पर्यायांसाठी टॅप करा."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"अॅनालॉग ऑडिओ अॅक्‍सेसरी आढळली"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"या फोनसह संलग्‍न केलेले डीव्‍हाइस सुसंगत नाही. अधिक जाणून घेण्‍यासाठी टॅप करा."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग करणे कनेक्‍ट केले"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB डीबग करणे अक्षम करण्यासाठी टॅप करा."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डीबगिंग बंद करण्यासाठी निवडा."</string>
-    <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"दोष अहवाल घेत आहे..."</string>
+    <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"बग रीपोर्ट घेत आहे..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग अहवाल सामायिक करायचा?"</string>
-    <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"दोष अहवाल सामायिक करीत आहे..."</string>
+    <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"बग रीपोर्ट शेअर करत आहे..."</string>
     <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"आपल्या प्रशासकाने या डिव्हाइसचे समस्या निवारण करण्यात मदत करण्यासाठी दोष अहवालाची विनंती केली. अॅप्स आणि डेटा शेअर केले जाऊ शकतात."</string>
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"सामायिक करा"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"नकार द्या"</string>
@@ -1214,8 +1222,8 @@
     <string name="ext_media_unmountable_notification_message" msgid="2343202057122495773">"<xliff:g id="NAME">%s</xliff:g> दूषित आहे. निराकरण करण्यासाठी टॅप करा."</string>
     <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> दूषित आहे. निश्चित करण्यासाठी निवडा."</string>
     <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"<xliff:g id="NAME">%s</xliff:g> असमर्थित"</string>
-    <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"हे डीव्हाइस <xliff:g id="NAME">%s</xliff:g> ला सपोर्ट करत नाही. सपोर्ट असलेल्या फॉरमॅटमध्ये सेट करण्यासाठी टॅप करा."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"हे डीव्हाइस <xliff:g id="NAME">%s</xliff:g> ला सपोर्ट करत नाही. सपोर्ट असलेल्या फॉरमॅटमध्ये सेट करण्यासाठी निवडा."</string>
+    <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"हे डिव्हाइस <xliff:g id="NAME">%s</xliff:g> ला सपोर्ट करत नाही. सपोर्ट असलेल्या फॉरमॅटमध्ये सेट करण्यासाठी टॅप करा."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"हे डिव्हाइस <xliff:g id="NAME">%s</xliff:g> ला सपोर्ट करत नाही. सपोर्ट असलेल्या फॉरमॅटमध्ये सेट करण्यासाठी निवडा."</string>
     <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> अनपेक्षितरित्या काढले"</string>
     <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"डेटा गमावणे टाळण्‍यासाठी काढण्‍यापूर्वी <xliff:g id="NAME">%s</xliff:g> अनमाउंट करा"</string>
     <string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"<xliff:g id="NAME">%s</xliff:g> काढले"</string>
@@ -1226,7 +1234,7 @@
     <string name="ext_media_unmount_action" msgid="1121883233103278199">"बाहेर काढा"</string>
     <string name="ext_media_browse_action" msgid="8322172381028546087">"एक्सप्लोर करा"</string>
     <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> गहाळ आहे"</string>
-    <string name="ext_media_missing_message" msgid="5761133583368750174">"हे डीव्हाइस पुन्हा घाला"</string>
+    <string name="ext_media_missing_message" msgid="5761133583368750174">"हे डिव्हाइस पुन्हा घाला"</string>
     <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> हलवित आहे"</string>
     <string name="ext_media_move_title" msgid="1022809140035962662">"डेटा हलवित आहे"</string>
     <string name="ext_media_move_success_title" msgid="8575300932957954671">"हलविणे पूर्ण"</string>
@@ -1290,20 +1298,18 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> शी कनेक्ट केले. नेटवर्क व्यवस्थापित करण्यासाठी टॅप करा."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"VPN कनेक्ट करणे नेहमी-चालू…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPN कनेक्ट केलेले नेहमी-चालू"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"नेहमी-चालू असलेले VPN डिस्कनेक्ट केले"</string>
-    <string name="vpn_lockdown_error" msgid="6009249814034708175">"VPN त्रुटी नेहमी-चालू"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"सेट करण्यासाठी टॅप करा"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"कायम चालू असलेल्या VPN मधून डिस्कनेक्ट केले"</string>
+    <string name="vpn_lockdown_error" msgid="6009249814034708175">"VPN एरर नेहमी-चालू"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"नेटवर्क किंवा VPN सेटिंग्ज बदला"</string>
     <string name="upload_file" msgid="2897957172366730416">"फाईल निवडा"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"फाईल निवडली नाही"</string>
     <string name="reset" msgid="2448168080964209908">"रीसेट करा"</string>
     <string name="submit" msgid="1602335572089911941">"सबमिट करा"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"कार मोड सक्षम केला"</string>
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"कार मोडमधून बाहेर पडण्यासाठी टॅप करा."</string>
-    <string name="tethered_notification_title" msgid="3146694234398202601">"टिथरिंग किंवा हॉटस्पॉट सक्रिय"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग किंवा हॉटस्पॉट सक्रिय"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करण्यासाठी टॅप करा."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग बंद आहे"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"तपशीलांसाठी तुमच्या प्रशासकाशी संपर्क साधा"</string>
-    <string name="back_button_label" msgid="2300470004503343439">"परत"</string>
+    <string name="back_button_label" msgid="2300470004503343439">"मागे"</string>
     <string name="next_button_label" msgid="1080555104677992408">"पुढील"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"वगळा"</string>
     <string name="no_matches" msgid="8129421908915840737">"कोणत्याही जुळण्या नाहीत"</string>
@@ -1328,7 +1334,7 @@
     <string name="sync_too_many_deletes" msgid="5296321850662746890">"ओलांडलेली मर्यादा हटवा"</string>
     <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"<xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> खात्यासाठी <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> हटविलेले आयटम आहेत. आपण काय करू इच्छिता?"</string>
     <string name="sync_really_delete" msgid="2572600103122596243">"आयटम हटवा"</string>
-    <string name="sync_undo_deletes" msgid="2941317360600338602">"हटविणे पूर्ववत करा"</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="add_account_label" msgid="2935267344849993553">"एक खाते जोडा"</string>
@@ -1400,7 +1406,7 @@
     <string name="validity_period" msgid="8818886137545983110">"वैधता:"</string>
     <string name="issued_on" msgid="5895017404361397232">"रोजी जारी:"</string>
     <string name="expires_on" msgid="3676242949915959821">"रोजी मुदत संपेल:"</string>
-    <string name="serial_number" msgid="758814067660862493">"अनुक्रमांक:"</string>
+    <string name="serial_number" msgid="758814067660862493">"सीरीअल नंबर:"</string>
     <string name="fingerprints" msgid="4516019619850763049">"फिंगरप्रिंट:"</string>
     <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 फिंगरप्रिंट:"</string>
     <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 फिंगरप्रिंट:"</string>
@@ -1420,7 +1426,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"स्पीकर डॉक करा"</string>
     <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"सिस्टम"</string>
-    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"ब्लूटुथ ऑडिओ"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"ब्लूटूथ ऑडिओ"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"वायरलेस डिस्प्ले"</string>
     <string name="media_route_button_content_description" msgid="591703006349356016">"कास्‍ट करा"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"डिव्हाइसला कनेक्ट करा"</string>
@@ -1435,7 +1441,7 @@
     <string name="media_route_status_in_use" msgid="4533786031090198063">"वापरात आहे"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"अंगभूत स्क्रीन"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI स्क्रीन"</string>
-    <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"आच्छादन #<xliff:g id="ID">%1$d</xliff:g>"</string>
+    <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ओव्हरले #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", सुरक्षित"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"पॅटर्न विसरलात"</string>
@@ -1443,7 +1449,7 @@
     <string name="kg_wrong_password" msgid="2333281762128113157">"चुकीचा संकेतशब्द"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"चुकीचा पिन"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="kg_pattern_instructions" msgid="398978611683075868">"आपला पॅटर्न काढा"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"तुमचा पॅटर्न काढा"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"सिम पिन प्रविष्ट करा"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"पिन प्रविष्ट करा"</string>
     <string name="kg_password_instructions" msgid="5753646556186936819">"संकेतशब्द प्रविष्ट करा"</string>
@@ -1454,14 +1460,14 @@
     <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">"PUK कोड 8 संख्‍येचा असावा."</string>
-    <string name="kg_invalid_puk" msgid="3638289409676051243">"योग्य PUK कोड पुन्हा-प्रविष्ट करा. परत प्रयत्न करणे सिम कायमचे अक्षम करेल."</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>
     <string name="kg_login_instructions" msgid="1100551261265506448">"अनलॉक करण्यासाठी, आपल्या Google खात्यासह साइन इन करा."</string>
     <string name="kg_login_username_hint" msgid="5718534272070920364">"वापरकर्तानाव (ईमेल)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"संकेतशब्द"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"साइन इन करा"</string>
-    <string name="kg_login_invalid_input" msgid="5754664119319872197">"अवैध वापरकर्तानाव किंवा संकेतशब्द."</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"अवैध वापरकर्तानाव किंवा पासवर्ड."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"आपले वापरकर्तानाव किंवा संकेतशब्द विसरलात?\n "<b>"google.com/accounts/recovery"</b>" ला भेट द्या."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"खाते तपासत आहे…"</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"आपण आपला पिन <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने टाइप केला आहे. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
@@ -1492,7 +1498,7 @@
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> वर स्विच करत आहे…"</string>
     <string name="user_logging_out_message" msgid="8939524935808875155">"<xliff:g id="NAME">%1$s</xliff:g> लॉग आउट करीत आहे…"</string>
     <string name="owner_name" msgid="2716755460376028154">"मालक"</string>
-    <string name="error_message_title" msgid="4510373083082500195">"त्रुटी"</string>
+    <string name="error_message_title" msgid="4510373083082500195">"एरर"</string>
     <string name="error_message_change_not_allowed" msgid="1238035947357923497">"या बदलास आपल्या प्रशासकाद्वारे अनुमती नाही"</string>
     <string name="app_not_found" msgid="3429141853498927379">"ही क्रिया हाताळण्यासाठी कोणताही अॅप्लिकेशन आढळला नाही"</string>
     <string name="revoke" msgid="5404479185228271586">"मागे घ्‍या"</string>
@@ -1580,12 +1586,12 @@
     <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"अज्ञात पोट्रेट"</string>
     <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"अज्ञात लँडस्केप"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"रद्द केले"</string>
-    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"सामग्री लिहिण्‍यात त्रुटी"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"आशय लिहिण्‍यात एरर"</string>
     <string name="reason_unknown" msgid="6048913880184628119">"अज्ञात"</string>
     <string name="reason_service_unavailable" msgid="7824008732243903268">"मुद्रण सेवा सक्षम केली नाही"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> सेवा स्‍थापित केली"</string>
     <string name="print_service_installed_message" msgid="5897362931070459152">"सक्षम करण्यासाठी टॅप करा"</string>
-    <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"प्रशासक पिन प्रविष्ट करा"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"प्रशासक पिन एंटर करा"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"पिन प्रविष्ट करा"</string>
     <string name="restr_pin_incorrect" msgid="8571512003955077924">"चुकीचा"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"वर्तमान पिन"</string>
@@ -1599,7 +1605,7 @@
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"नंतर पुन्हा प्रयत्न करा"</string>
-    <string name="immersive_cling_title" msgid="8394201622932303336">"पूर्ण स्क्रीन पाहत आहात"</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"पूर्ण स्क्रीनवर पाहत आहात"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"बाहेर पडण्यासाठी, वरून खाली स्वाइप करा."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"समजले"</string>
     <string name="done_label" msgid="2093726099505892398">"पूर्ण झाले"</string>
@@ -1623,8 +1629,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" msgid="1960431123816253034">"बॅटरी लाइफ सुधारित करण्‍यासाठी, बॅटरी सेव्हर तुमच्या डीव्हाइस ची कामगिरी कमी करतो आणि कंपन, स्थान सेवा आणि बराच पार्श्वभूमी डेटा मर्यादित करतो. सिंकवर अवलंबून असणारे ईमेल, मेसेजिंग आणि इतर अ‍ॅप्स तुम्ही उघडल्याशिवाय अपडेट होऊ शकत नाहीत.\n\nतुमचे डीव्हाइस चार्ज होत असते तेव्हा बॅटरी सेव्हर आपोआप बंद होतो."</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"डेटा वापर कमी करण्यात मदत करण्यासाठी, डेटा सर्व्हर काही अॅप्सना पार्श्वभूमीमध्ये डेटा पाठविण्यास किंवा प्राप्त करण्यास प्रतिबंधित करतो. आपण सध्या वापरत असलेला अॅप डेटामध्ये प्रवेश करू शकतो परंतु तसे तो खूप कमी वेळा करू शकतो. याचा अर्थ, उदाहरणार्थ, आपण प्रतिमा टॅप करेपर्यंत त्या प्रदर्शित करणार नाहीत असा असू शकतो."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"बॅटरी लाइफ सुधारित करण्‍यासाठी, बॅटरी सेव्हर तुमच्या डिव्हाइस ची कामगिरी कमी करतो आणि कंपन, स्थान सेवा आणि बराच पार्श्वभूमी डेटा मर्यादित करतो. सिंकवर अवलंबून असणारे ईमेल, मेसेजिंग आणि इतर अ‍ॅप्स तुम्ही उघडल्याशिवाय अपडेट होऊ शकत नाहीत.\n\nतुमचे डिव्हाइस चार्ज होत असते तेव्हा बॅटरी सेव्हर आपोआप बंद होतो."</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"डेटा वापर कमी करण्यात मदत करण्यासाठी, डेटा सर्व्हर काही अॅप्सना पार्श्वभूमीमध्ये डेटा पाठविण्यास किंवा प्राप्त करण्यास प्रतिबंधित करतो. आपण सध्या वापरत असलेला अॅप डेटामध्ये प्रवेश करू शकतो परंतु तसे तो खूप कमी वेळा करू शकतो. याचा अर्थ, उदाहरणार्थ, आपण इमेज टॅप करेपर्यंत त्या प्रदर्शित करणार नाहीत असा असू शकतो."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"डेटा बचतकर्ता चालू करायचा?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"चालू करा"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
@@ -1723,26 +1729,20 @@
     <string name="unpin_target" msgid="3556545602439143442">"अनपिन करा"</string>
     <string name="app_info" msgid="6856026610594615344">"अॅप माहिती"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"डीव्हाइस रीसेट करायचे?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"डीव्हाइस रीसेट करण्यासाठी टॅप करा"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"डेमो प्रारंभ करत आहे..."</string>
-    <string name="demo_restarting_message" msgid="952118052531642451">"डीव्हाइस रीसेट करत आहे..."</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"डीव्हाइस रीसेट करायचे?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"आपण कोणतेही बदल गमवाल आणि डेमो पुन्हा <xliff:g id="TIMEOUT">%1$s</xliff:g> सेकंदांमध्ये प्रारंभ होईल..."</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"रद्द करा"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"आता रीसेट करा"</string>
+    <string name="demo_restarting_message" msgid="952118052531642451">"डिव्हाइस रीसेट करत आहे..."</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> अक्षम केले"</string>
     <string name="conference_call" msgid="3751093130790472426">"परिषद कॉल"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"टूलटिप"</string>
     <string name="app_category_game" msgid="5431836943981492993">"गेम"</string>
     <string name="app_category_audio" msgid="1659853108734301647">"संगीत आणि ऑडिओ"</string>
     <string name="app_category_video" msgid="2728726078629384196">"चित्रपट आणि व्हिडिओ"</string>
-    <string name="app_category_image" msgid="4867854544519846048">"फोटो आणि प्रतिमा"</string>
+    <string name="app_category_image" msgid="4867854544519846048">"फोटो आणि इमेज"</string>
     <string name="app_category_social" msgid="5842783057834965912">"सामाजिक आणि संप्रेषण"</string>
     <string name="app_category_news" msgid="7496506240743986873">"बातम्‍या आणि मासिके"</string>
     <string name="app_category_maps" msgid="5878491404538024367">"नकाशे आणि नेव्हिगेशन"</string>
     <string name="app_category_productivity" msgid="3742083261781538852">"उत्पादनक्षमता"</string>
-    <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"डीव्हाइस स्टोरेज"</string>
+    <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"डिव्हाइस स्टोरेज"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"USB डीबगिंग"</string>
     <string name="time_picker_hour_label" msgid="2979075098868106450">"तास"</string>
     <string name="time_picker_minute_label" msgid="5168864173796598399">"मिनिट"</string>
@@ -1763,8 +1763,8 @@
     <string name="autofill_save_title_with_type" msgid="8637809388029313305">"&lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt;मध्ये <xliff:g id="TYPE">%1$s</xliff:g> सेव्ह करायची?"</string>
     <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"&lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt;मध्ये <xliff:g id="TYPE_0">%1$s</xliff:g> आणि <xliff:g id="TYPE_1">%2$s</xliff:g> सेव्ह करायची?"</string>
     <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"&lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt;मध्ये <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> आणि <xliff:g id="TYPE_2">%3$s</xliff:g> सेव्ह करायची?"</string>
-    <string name="autofill_save_yes" msgid="6398026094049005921">"जतन करा"</string>
-    <string name="autofill_save_no" msgid="2625132258725581787">"नाही धन्यवाद"</string>
+    <string name="autofill_save_yes" msgid="6398026094049005921">"सेव्ह करा"</string>
+    <string name="autofill_save_no" msgid="2625132258725581787">"नाही, नको"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"संकेतशब्द"</string>
     <string name="autofill_save_type_address" msgid="4936707762193009542">"पत्ता"</string>
     <string name="autofill_save_type_credit_card" msgid="7127694776265563071">"क्रेडिट कार्ड"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"किनारपट्टीचे प्रदेश आणि नदीकाठची क्षेत्रे त्वरित रिकामी करून उंच मैदानासारख्या अधिक सुरक्षित ठिकाणी जा."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"शांत रहा आणि जवळपास निवारा शोधा."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"आणीबाणी संदेश चाचणी"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"प्रत्युत्तर द्या"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"सिमला अनुमती नाही"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"सिमसाठी तरतूद नाही"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index fd53735..f0368c1 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Mencari Perkhidmatan"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Panggilan Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, mula-mula minta pembawa anda untuk menyediakan perkhidmatan ini. Kemudian hidupkan panggilan Wi-Fi semula daripada Tetapan."</item>
+    <item msgid="3910386316304772394">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, minta pembawa anda menyediakan perkhidmatan ini terlebih dahulu. Kemudian, hidupkan panggilan Wi-Fi sekali lagi daripada Tetapan. (Kod ralat: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Daftar dengan pembawa anda"</item>
+    <item msgid="7472393097168811593">"Daftar dengan pembawa anda (Kod ralat: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Bantuan Suara"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Kunci sekarang"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Kandungan tersembunyi"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Kandungan disembunyikan oleh dasar"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Pemberitahuan baharu"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Papan kekunci maya"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Papan kekunci fizikal"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Keselamatan"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Makluman"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Tunjuk cara runcit"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Sambungan USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apl yang berjalan di latar belakang"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang berjalan di latar belakang"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apl sedang berjalan di latar belakang"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apl yang menggunakan bateri"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang menggunakan bateri"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apl sedang menggunakan bateri"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Ketik untuk mendapatkan butiran tentang penggunaan kuasa bateri dan data"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mod selamat"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Rangkaian Wi-Fi terbuka tersedia</item>
       <item quantity="one">Rangkaian Wi-Fi terbuka tersedia</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Sambung ke rangkaian Wi-Fi terbuka"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Menyambung ke rangkaian Wi‑Fi terbuka"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Disambungkan ke rangkaian Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Tidak dapat menyambung ke rangkaian Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ketik untuk melihat semua rangkaian"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Sambung"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Semua Rangkaian"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Log masuk ke rangkaian Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Log masuk ke rangkaian"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB untuk MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Disambungkan kepada aksesori USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Ketik untuk mendapatkan lagi pilihan."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Aksesori audio analog dikesan"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Peranti yang disambungkan tidak serasi dengan telefon ini. Ketik untuk mengetahui lebih lanjut."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Penyahpepijatan USB disambungkan"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Ketik untuk melumpuhkan penyahpepijatan USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk melumpuhkan penyahpepijatan USB."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Bersambung kepada <xliff:g id="SESSION">%s</xliff:g>. Ketik untuk mengurus rangkaian."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"VPN sentiasa hidup sedang disambungkan..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPN sentiasa hidup telah disambungkan"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"VPN sentiasa hidup diputuskan sambungannya"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Diputuskan sambungan daripada VPN sentiasa hidup"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Ralat VPN sentiasa hidup"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Ketik untuk menyediakan"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Tukar tetapan rangkaian atau VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Pilih fail"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Tiada fail dipilih"</string>
     <string name="reset" msgid="2448168080964209908">"Tetapkan semula"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Ketik untuk keluar daripada mod kereta."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Penambatan atau titik panas aktif"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Ketik untuk membuat persediaan."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Penambatan dilumpuhkan"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi pentadbir anda untuk maklumat lanjut"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Kembali"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Seterusnya"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Langkau"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Nyahsemat"</string>
     <string name="app_info" msgid="6856026610594615344">"Maklumat apl"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Tetapkan semula peranti?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Ketik untuk menetapkan semula peranti"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Memulakan tunjuk cara…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Menetapkan semula peranti…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Tetapkan semula peranti?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Anda akan kehilangan sebarang perubahan yang dibuat dan tunjuk cara akan dimulakan sekali lagi dalam masa <xliff:g id="TIMEOUT">%1$s</xliff:g> saat…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Batal"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Tetapkan semula sekarang"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> dilumpuhkan"</string>
     <string name="conference_call" msgid="3751093130790472426">"Panggilan Sidang"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Keterangan item"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Segera beredar dari kawasan pinggir laut dan tepi sungai dan berpindah ke tempat yang lebih selamat seperti kawasan tinggi."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Bertenang dan cari perlindungan di kawasan yang berdekatan."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Ujian mesej kecemasan"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Balas"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM tidak dibenarkan"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM tidak diperuntukkan"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 36f8db8..58dc084 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"ဆားဗစ်အားရှာဖွေနေသည်"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi  ခေါ်ဆိုမှု"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi သုံး၍ ဖုန်းခေါ်ဆိုရန်နှင့် မက်ဆေ့ဂျ်များပို့ရန်၊ ဤဝန်ဆောင်မှုအား စတင်သုံးနိုင်ရန်အတွက် သင့် မိုဘိုင်းဝန်ဆောင်မှုအား ဦးစွာမေးမြန်းပါ။ ထို့နောက် ဆက်တင်မှတဆင့် Wi-Fi  ခေါ်ဆိုမှုအား ထပ်ဖွင့်ပါ။"</item>
+    <item msgid="3910386316304772394">"Wi-Fi အသုံးပြု၍ ဖုန်းခေါ်ရန်နှင့် မက်ဆေ့ဂျ်ပို့ရန်အတွက် သင့်ဝန်ဆောင်မှုပေးသူကို ဤဝန်ဆောင်မှုအား သတ်မှတ်ပေးရန် ဦးစွာတောင်းဆိုပါ။ ထို့နောက် ဆက်တင်ထဲသို့ သွား၍ Wi-Fi ဖြင့် ဖုန်းခေါ်ခြင်းကို ဖွင့်ရပါမည်။ (အမှားကုဒ်- <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"သင့် မိုဘိုင်းဝန်ဆောင်မှုဖြင့် မှတ်ပုံတင်ရန်"</item>
+    <item msgid="7472393097168811593">"သင့်ဖုန်းကုမ္ပဏီနှင့် မှတ်ပုံတင်ပါ (အမှားကုဒ်− <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"အသံ အကူအညီ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ယခု သော့ပိတ်ရန်"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"၉၉၉+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"အကြောင်းအရာများ ဝှက်ထား"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"မူဝါဒမှ အကြောင်းအရာများကို ဝှက်ထားသည်"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"အကြောင်းကြားချက်အသစ်"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ပကတိအသွင်ကီးဘုတ်"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ကီးဘုတ် ခလုတ်ခုံ"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"လုံခြုံရေး"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"သတိပေးချက်များ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"လက်လီအရောင်းဆိုင် သရုပ်ပြမှု"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB ချိတ်ဆက်မှု"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"နောက်ခံတွင် ပွင့်နေသော အက်ပ်များ"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် နောက်ခံတွင် ပွင့်နေပါသည်"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"အက်ပ် <xliff:g id="NUMBER">%1$d</xliff:g> ခုသည် နောက်ခံတွင် ပွင့်နေပါသည်"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"အက်ပ်များက ဘက်ထရီကုန်စေသည်"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> က ဘက်ထရီကို အသုံးပြုနေသည်"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"အက်ပ် <xliff:g id="NUMBER">%1$d</xliff:g> ခုက ဘက်ထရီကို အသုံးပြုနေသည်"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ဘက်ထရီနှင့် ဒေတာအသုံးပြုမှု အသေးစိတ်ကို ကြည့်ရန် တို့ပါ"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>၊ <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"အန္တရာယ်ကင်းမှု စနစ်(Safe mode)"</string>
@@ -586,7 +585,7 @@
     <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"ဖန်သားပြင်သော့ခတ်နိုင်သည့်အင်္ဂါရပ် အချို့အား ပိတ်ထားပါ"</string>
     <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"ဖန်သားပြင်သော့ခတ်နိုင်သည့်အင်္ဂါရပ် အချို့ အသုံးပြုမှုအား ကာကွယ်ပါ။"</string>
   <string-array name="phoneTypes">
-    <item msgid="8901098336658710359">"ပင်မစာမျက်နှာ"</item>
+    <item msgid="8901098336658710359">"အိမ်"</item>
     <item msgid="869923650527136615">"မိုဘိုင်း"</item>
     <item msgid="7897544654242874543">"အလုပ်"</item>
     <item msgid="1103601433382158155">"အလုပ်ဖက်စ်"</item>
@@ -596,19 +595,19 @@
     <item msgid="9192514806975898961">"မိမိစိတ်ကြိုက်"</item>
   </string-array>
   <string-array name="emailAddressTypes">
-    <item msgid="8073994352956129127">"ပင်မစာမျက်နှာ"</item>
+    <item msgid="8073994352956129127">"အိမ်"</item>
     <item msgid="7084237356602625604">"အလုပ်"</item>
     <item msgid="1112044410659011023">"တခြား"</item>
     <item msgid="2374913952870110618">"မိမိစိတ်ကြိုက်"</item>
   </string-array>
   <string-array name="postalAddressTypes">
-    <item msgid="6880257626740047286">"ပင်မစာမျက်နှာ"</item>
+    <item msgid="6880257626740047286">"အိမ်"</item>
     <item msgid="5629153956045109251">"အလုပ်"</item>
     <item msgid="4966604264500343469">"တခြား"</item>
     <item msgid="4932682847595299369">"မိမိစိတ်ကြိုက်"</item>
   </string-array>
   <string-array name="imAddressTypes">
-    <item msgid="1738585194601476694">"ပင်မစာမျက်နှာ"</item>
+    <item msgid="1738585194601476694">"အိမ်"</item>
     <item msgid="1359644565647383708">"အလုပ်"</item>
     <item msgid="7868549401053615677">"တခြား"</item>
     <item msgid="3145118944639869809">"မိမိစိတ်ကြိုက်"</item>
@@ -651,7 +650,7 @@
     <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
     <string name="eventTypeCustom" msgid="7837586198458073404">"မိမိစိတ်ကြိုက်"</string>
     <string name="eventTypeBirthday" msgid="2813379844211390740">"မွေးနေ့"</string>
-    <string name="eventTypeAnniversary" msgid="3876779744518284000">"အထိမ်းအမှတ်"</string>
+    <string name="eventTypeAnniversary" msgid="3876779744518284000">"နှစ်ပတ်လည်နေ့"</string>
     <string name="eventTypeOther" msgid="7388178939010143077">"တခြား"</string>
     <string name="emailTypeCustom" msgid="8525960257804213846">"မိမိစိတ်ကြိုက်"</string>
     <string name="emailTypeHome" msgid="449227236140433919">"အိမ်"</string>
@@ -659,11 +658,11 @@
     <string name="emailTypeOther" msgid="2923008695272639549">"တခြား"</string>
     <string name="emailTypeMobile" msgid="119919005321166205">"မိုဘိုင်း"</string>
     <string name="postalTypeCustom" msgid="8903206903060479902">"မိမိစိတ်ကြိုက်"</string>
-    <string name="postalTypeHome" msgid="8165756977184483097">"ပင်မစာမျက်နှာ"</string>
+    <string name="postalTypeHome" msgid="8165756977184483097">"အိမ်"</string>
     <string name="postalTypeWork" msgid="5268172772387694495">"အလုပ်"</string>
     <string name="postalTypeOther" msgid="2726111966623584341">"တခြား"</string>
     <string name="imTypeCustom" msgid="2074028755527826046">"မိမိစိတ်ကြိုက်"</string>
-    <string name="imTypeHome" msgid="6241181032954263892">"ပင်မစာမျက်နှာ"</string>
+    <string name="imTypeHome" msgid="6241181032954263892">"အိမ်"</string>
     <string name="imTypeWork" msgid="1371489290242433090">"အလုပ်"</string>
     <string name="imTypeOther" msgid="5377007495735915478">"တခြား"</string>
     <string name="imProtocolCustom" msgid="6919453836618749992">"မိမိစိတ်ကြိုက်"</string>
@@ -695,7 +694,7 @@
     <string name="relationTypeSister" msgid="1735983554479076481">"ညီအမ"</string>
     <string name="relationTypeSpouse" msgid="394136939428698117">"အိမ်ထောင်ဖက်"</string>
     <string name="sipAddressTypeCustom" msgid="2473580593111590945">"မိမိစိတ်ကြိုက်"</string>
-    <string name="sipAddressTypeHome" msgid="6093598181069359295">"ပင်မစာမျက်နှာ"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"အိမ်"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"အလုပ်"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"တခြား"</string>
     <string name="quick_contacts_not_available" msgid="746098007828579688">"ဤအဆက်အသွယ်အား ကြည့်ရှုရန်  အပလီကေးရှင်းမတွေ့ပါ"</string>
@@ -761,7 +760,7 @@
     <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"သော့ဖွင့်ရန် Google အကောင့်ဖြင့် ဝင်ပါ"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"သုံးစွဲသူ အမှတ် (အီးမေးလ်)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"စကားဝှက်"</string>
-    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ဝင်ရန်"</string>
+    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"လက်မှတ်ထိုးဝင်ရန်"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"အသုံးပြုသူအမည် သို့မဟုတ် လျို့ဝှက် နံပါတ် မှားယွင်းနေသည်"</string>
     <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"သုံးစွဲသူ အမည် သို့ စကားဝှင်ကို မေ့နေပါသလား။ \n"<b>"google.com/accounts/recovery"</b>" ကို သွားရောက်ပါ။"</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"စစ်ဆေးနေပါသည်…"</string>
@@ -983,7 +982,7 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"စာတို လုပ်ဆောင်ချက်"</string>
     <string name="email" msgid="4560673117055050403">"အီးမေးလ်"</string>
     <string name="dial" msgid="4204975095406423102">"ဖုန်း"</string>
-    <string name="map" msgid="6068210738233985748">"မြေပုံများ"</string>
+    <string name="map" msgid="6068210738233985748">"Maps"</string>
     <string name="browse" msgid="6993590095938149861">"ဘရောင်ဇာ"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"သိမ်းဆည်သော နေရာ နည်းနေပါသည်"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"တချို့ စနစ်လုပ်ငန်းများ အလုပ် မလုပ်ခြင်း ဖြစ်နိုင်ပါသည်"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Wi-Fi ကွန်ယက်များရရှိနိုင်သည်အား ဖွင့်ပါ</item>
       <item quantity="one">Wi-Fi ကွန်ယက်ရရှိနိုင်သည်အား ဖွင့်ပါ</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"အများသုံး Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်ပါ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"အများသုံး Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်နေသည်"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်ပြီးပါပြီ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်၍ မရပါ"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ကွန်ရက်အားလုံးကို ကြည့်ရန် တို့ပါ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ချိတ်ဆက်ရန်"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ကွန်ရက်အားလုံး"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ဝိုင်ဖိုင်ကွန်ရက်သို့ လက်မှတ်ထိုးဝင်ပါ"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ကွန်ယက်သို့ လက်မှတ်ထိုးဝင်ရန်"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1178,15 +1184,17 @@
     <string name="no_permissions" msgid="7283357728219338112">"ခွင့်ပြုချက်မလိုအပ်ပါ"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"သင့်အတွက် ပိုက်ဆံကုန်ကျနိုင်ပါသည်"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"အိုကေ"</string>
-    <string name="usb_charging_notification_title" msgid="6895185153353640787">"USB ဖြင့်ဤစက်ပစ္စည်းကို အားသွင်းနေသည်"</string>
+    <string name="usb_charging_notification_title" msgid="6895185153353640787">"ဤစက်ကို USB ဖြင့် အားသွင်းနေသည်"</string>
     <string name="usb_supplying_notification_title" msgid="5310642257296510271">"ချိတ်ဆက်ထားသည့် စက်ပစ္စည်းကို USB မှတစ်ဆင့် အားသွင်းနေသည်"</string>
     <string name="usb_mtp_notification_title" msgid="8396264943589760855">"ဖိုင်လွှဲပြောင်းရန်အတွက် USB"</string>
     <string name="usb_ptp_notification_title" msgid="1347328437083192112">"ဓာတ်ပုံလွှဲပြောင်းရန်အတွက် USB"</string>
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI အတွက် USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USBတွဲဖက်ပစ္စည်းအား ချိတ်ဆက်ထားသည်"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"နောက်ထပ်ရွေးချယ်စရာများအတွက် တို့ပါ။"</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB အမှားစစ်ခြင်းအား ချိတ်ဆက်ထားသည်"</string>
-    <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ဆက်သွယ်ရေးစနစ်ကို ပိတ်ရန် တို့ပါ။"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"အန်နာလော့ အသံကိရိယာကို တွေ့ထားပါသည်"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"တပ်ဆင်ထားသော ကိရိယာကို ဤဖုန်းနှင့် တွဲသုံး၍မရပါ။ ပိုမိုလေ့လာရန် တို့ပါ။"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB အမှားရှာပြင်စနစ် ချိတ်ဆက်ထားသည်"</string>
+    <string name="adb_active_notification_message" msgid="4948470599328424059">"USB အမှားရှာပြင်စနစ် ပိတ်ရန် တို့ပါ။"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ဖြင့် အမှားရှာပြင်ခြင်းကို ပိတ်ရန် ရွေးပါ။"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ချွတ်ယွင်းချက် အစီရင်ခံစာပြုစုနေသည်..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ချွတ်ယွင်းချက် အစီရင်ခံစာကို မျှဝေမလား။"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> သို့ ချိတ်ဆက်ထားသည်။ ကွန်ရက်ကို စီမံခန့်ခွဲရန် တို့ပါ။"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"အမြဲတမ်းဖွင့်ထား VPN ဆက်သွယ်နေစဉ်…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"အမြဲတမ်းဖွင့်ထား VPN ဆက်သွယ်မှုရှိ"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"အမြဲတမ်းဖွင့်ထားရသော VPN ပြတ်တောက်နေသည်"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"အမြဲပွင့်နေသော VPN မှ ချိတ်ဆက်မှုပြုတ်သွားပါပြီ"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"အမြဲတမ်းဖွင့်ထား VPN အမှား"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"ပြင်ဆင်သတ်မှတ်ရန် တို့ပါ"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"ကွန်ရက် သို့မဟုတ် VPN ဆက်တင်များကို ပြောင်းပါ"</string>
     <string name="upload_file" msgid="2897957172366730416">"ဖိုင်ရွေးချယ်ရန်"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"မည်သည့်ဖိုင်ကိုမှမရွေးပါ"</string>
     <string name="reset" msgid="2448168080964209908">"ပြန်လည်သတ်မှတ်ရန်"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"ကားမောင်းနှင်ခြင်းမုဒ်မှ ထွက်ရန် တို့ပါ။"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"တဆင့်ပြန်လည်လွှင့်ခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"စနစ်ထည့်သွင်းရန် တို့ပါ။"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"မိုဘိုင်းဖုန်းကို မိုဒမ်အဖြစ်သုံးခြင်းအား ပိတ်ထားသည်"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"အသေးစိတ်အချက်အလက်များအတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ"</string>
     <string name="back_button_label" msgid="2300470004503343439">"နောက်သို့"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ရှေ့သို့"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ကျော်ရန်"</string>
@@ -1460,7 +1466,7 @@
     <string name="kg_login_instructions" msgid="1100551261265506448">"သော့ဖွင့်ရန် သင့်ရဲ့ Google အကောင့်ဖြင့် ဝင်ပါ"</string>
     <string name="kg_login_username_hint" msgid="5718534272070920364">"သုံးစွဲသူအမည် (အီးမေးလ်)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"စကားဝှက်"</string>
-    <string name="kg_login_submit_button" msgid="5355904582674054702">"ဝင်ပါ"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"လက်မှတ်ထိုးဝင်ရန်"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"အသုံးပြုသူ အမည် သို့  စကားဝှက်မမှန်ကန်ပါ"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"သင် သုံးစွဲသူ အမည် သို့ စကားဝှက်အားမေ့နေပါသလား။\n"<b>"google.com/accounts/recovery"</b>" သို့ သွားရောက်ပါ"</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"အကောင့်ကို စစ်ဆေးနေစဉ်..."</string>
@@ -1661,7 +1667,7 @@
     </plurals>
     <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>အထိ"</string>
     <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> အထိ (လာမည့် နှိုးစက်)"</string>
-    <string name="zen_mode_forever" msgid="1916263162129197274">"မနှောင့်ယှက်ရန် ကိုသင်ပိတ်သည်အထိ"</string>
+    <string name="zen_mode_forever" msgid="1916263162129197274">"\"မနှောင့်ယှက်ရန်\" ကို သင်ပိတ်လိုက်သည်အထိ"</string>
     <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"မနှောင့်ယှက်ရန် ကိုသင်ပိတ်သည်အထိ"</string>
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"ခေါက်ရန်"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"ဖြုတ်ပါ"</string>
     <string name="app_info" msgid="6856026610594615344">"အက်ပ်အချက်အလက်"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"စက်ပစ္စည်းကို ပြန်လည်သတ်မှတ်မလား။"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"စက်ပစ္စည်းကို ပြန်လည်သတ်မှတ်ရန် တို့ပါ"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"သရုပ်ပြချက်ကို စတင်နေသည်…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"စက်ပစ္စည်းကို ပြန်လည်သတ်မှတ်နေသည်…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"စက်ပစ္စည်းကို ပြန်လည်သတ်မှတ်မလား။"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"ပြောင်းလဲမှုများကို ဆုံးရှုံးသွားမည်ဖြစ်ပြီး သရုပ်ပြချက်သည် <xliff:g id="TIMEOUT">%1$s</xliff:g> စက္ကန့်အတွင်း ပြန်လည်စတင်ပါမည်…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"မလုပ်တော့"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"ယခုပြန်လည်သတ်မှတ်ပါ"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"ပိတ်ထားသည့် <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"လူအမြောက်အမြားတပြိုင်နက် ခေါ်ဆိုမှု"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"အကြံပြုချက်ပြ ပေါ့အပ် ဝင်းဒိုး"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ကမ်းရိုးတန်းနှင့် မြစ်ကမ်းရိုးတစ်လျှောက်ရှိ နေရာဒေသတို့မှ ချက်ချင်းထွက်ခွာပြီး ဘေးကင်းရာကုန်းမြင့်ဒေသသို့ ပြောင်းရွှေ့ပါ။"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"စိတ်ငြိမ်ငြိမ်ထားပြီး အနီးအနားတဝိုက်တွင် ခိုနားစရာ နေရာရှာပါ။"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"အရေးပေါ် မက်ဆေ့ဂျ် စမ်းသပ်မှု"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"စာပြန်ရန်"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"ဆင်းမ်ကို ခွင့်မပြုပါ"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index f6f9f3c..bf520bf 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Leter etter tjeneste"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-anrop"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"For å ringe og sende meldinger over Wi-Fi må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger."</item>
+    <item msgid="3910386316304772394">"For å ringe og sende meldinger over Wi-Fi, må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger. (Feilkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Registrer deg hos operatøren din"</item>
+    <item msgid="7472393097168811593">"Registrer deg hos operatøren din (feilkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Talehjelp"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lås nå"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Innholdet er skjult"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Innholdet er skjult i henhold til retningslinjene"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Nytt varsel"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuelt tastatur"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fysisk tastatur"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Sikkerhet"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Varsler"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Butikkdemo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-tilkobling"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apper kjører i bakgrunnen"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> kjører i bakgrunnen"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apper kjører i bakgrunnen"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apper bruker batteri"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> bruker batteri"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apper bruker batteri"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Trykk for detaljer om batteri- og databruk"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Sikkermodus"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Åpne Wi-Fi-nettverk er tilgjengelig</item>
       <item quantity="one">Åpent Wi-Fi-nettverk er tilgjengelig</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Koble til et åpent Wi‑Fi-nettverk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Kobler til åpent Wi-Fi-nettverk"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Koblet til Wi-Fi-nettverk"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kunne ikke koble til Wi-Fi-nettverket"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trykk for å se alle nettverkene"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koble til"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle nettverk"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Logg på Wi-Fi-nettverket"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Logg på nettverk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB for MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Koblet til et USB-tilbehør"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Trykk for å få flere alternativ."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analogt lydtilbehør ble oppdaget"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Den tilkoblede enheten er ikke kompatibel med denne telefonen. Trykk for å finne ut mer."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-feilsøking tilkoblet"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Trykk for å slå av feilsøking via USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Velg for å deaktivere USB-debugging."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Koblet til <xliff:g id="SESSION">%s</xliff:g>. Trykk for å administrere nettverket."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Alltid-på VPN kobler til ..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Alltid-på VPN er tilkoblet"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Alltid på-VPN er frakoblet"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Koble fra alltid på-VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Alltid-på VPN-feil"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Trykk for å konfigurere"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Endre nettverks- eller VPN-innstillingene"</string>
     <string name="upload_file" msgid="2897957172366730416">"Velg fil"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Ingen fil er valgt"</string>
     <string name="reset" msgid="2448168080964209908">"Tilbakestill"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Trykk for avslutte bilmodus."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Internettdeling eller trådløs sone er aktiv"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Trykk for å konfigurere."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Internettdeling er slått av"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ta kontakt med administratoren din for å få mer informasjon"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Tilbake"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Neste"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Hopp over"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Løsne"</string>
     <string name="app_info" msgid="6856026610594615344">"Info om appen"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Tilbakestille enheten?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Trykk for å tilbakestille enheten"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Starter demo …"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Tilbakestiller enheten …"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Tilbakestille enheten?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Du mister eventuelle endringer, og demoen starter på nytt om <xliff:g id="TIMEOUT">%1$s</xliff:g> sekunder."</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Avbryt"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Tilbakestill nå"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> er slått av"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konferansesamtale"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Verktøytips"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evakuer umiddelbart fra kyst- og elveområder til et tryggere sted, for eksempel høyt terreng."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Hold deg rolig og søk ly i nærheten."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test av nødmeldinger"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Svar"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-kortet er ikke tillatt"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-kortet er ikke klargjort"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 029957b..b7576c12 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"सेवाको खोजी गर्दै…"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi कलिङ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi बाट कल गर्न र सन्देशहरू पठाउन, सबभन्दा पहिला यो सेवा सेटअप गर्न तपाईँको वाहकलाई भन्नुहोस्। त्यसपछि फेरि सेटिङहरूबाट Wi-Fi कलिङ सक्रिय पार्नुहोस्।"</item>
+    <item msgid="3910386316304772394">"Wi-Fi मार्फत कलहरू गर्न र सन्देशहरू पठाउन सबभन्दा पहिला आफ्नो सेवा प्रदायकलाई यो सेवा सेट गर्न भन्नुहोस्। त्यसपछि सेटिङहरूबाट Wi-Fi कलिङलाई सक्रिय पार्नुहोस्। (त्रुटिसम्बन्धी कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"तपाईँको वाहकसँग दर्ता गर्नुहोस्"</item>
+    <item msgid="7472393097168811593">"आफ्नो सेवा प्रदायकमा दर्ता गर्नुहोस् (त्रुटिसम्बन्धी कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"आवाज सहायता"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"अब बन्द गर्नुहोस्"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"९९९+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"लुकेका सामाग्रीहरू"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"नीतिद्वारा लुकाइएका सामग्री"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"नयाँ सूचना"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"भर्चुअल किबोर्ड"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"वास्तविक किबोर्ड"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"सुरक्षा"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"अलर्टहरू"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"खुद्रा बिक्री सम्बन्धी डेमो"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB जडान"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"पृष्ठभूमिमा चल्ने अनुप्रयोगहरू"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> पृष्ठभूमिमा चल्दैछ"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> अनुप्रयोगहरू पृष्ठभूमिमा चल्दैछन्"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"अनुप्रयोगहरूले ब्याट्री खपत गर्दै छन्"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले ब्याट्री प्रयोग गर्दै छ"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> अनुप्रयोगहरूले ब्याट्री प्रयोग गर्दै छन्"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ब्याट्री र डेटाका प्रयोग सम्बन्धी विवरणहरूका लागि ट्याप गर्नुहोस्"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
@@ -358,7 +357,7 @@
     <string name="permdesc_writeSettings" msgid="7775723441558907181">"प्रणालीका सेटिङ डेटालाई परिवर्तन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले सायद तपाईँको प्रणालीको कन्फिगरेसनलाई क्षति पुर्‍याउन सक्छन्।"</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"स्टार्टअपमा चलाउनुहोस्"</string>
     <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"आनुप्रयोगलाई प्रणाली बुट प्रक्रिया पूर्ण हुने बितिकै आफैलाई सुरु गर्ने अनुमति दिन्छ। यसले ट्याब्लेट सुरु गर्नमा ढिला गर्न सक्दछ र अनुप्रयोगलाई समग्रमा ट्याब्लेट सधैँ चालु गरेर ढिला बनाउँदछ।"</string>
-    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"अनुप्रयोगलाई अनुमति दिन्छ प्रणालीले बुटिङ सकेपछि आफै सुरूवात हुन। यसले TV सुरू गर्न लामो समय लिन सक्छ र अनुप्रयोगहरूलाई अनुमति दिन सक्छ सँधै सञ्चालन भई समग्र रूपमा ट्याब्लेटलाई ढिलो गराएर।"</string>
+    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"अनुप्रयोगलाई अनुमति दिन्छ प्रणालीले बुटिङ सकेपछि आफै सुरुवात हुन। यसले TV सुरु गर्न लामो समय लिन सक्छ र अनुप्रयोगहरूलाई अनुमति दिन सक्छ सँधै सञ्चालन भई समग्र रूपमा ट्याब्लेटलाई ढिलो गराएर।"</string>
     <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"अनुप्रयोगलाई प्रणाली बुट गरी सकेपछि जति सक्दो चाँडो आफैंमा सुरु गर्न अनुमति दिन्छ। यसले फोन सुरु गर्नमा ढिला गर्न सक्दछ र अनप्रयोगलाई समग्रमा फोन सधैँ चालु गरेर ढिला बनाउँदछ।"</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"स्टिकि प्रसारण पठाउनुहोस्"</string>
     <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"औपचारिक प्रसारणलाई पठाउनको लागि एउटा अनुप्रयोगलाई अनुमति दिन्छ, जुन प्रसारण समाप्त भएपछि बाँकी रहन्छ। अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग गरेको कारणले ट्याब्लेटलाई ढिलो र अस्थिर बनाउन सक्छ।"</string>
@@ -1112,6 +1111,13 @@
       <item quantity="other"> खुल्ला Wi-Fi सञ्जालहरू उपलब्ध छन्</item>
       <item quantity="one">खुल्ला Wi-Fi सञ्जाल उपलब्ध छ</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"खुला Wi‑Fi नेटवर्कमा जडान गर्नुहोस्"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"खुला Wi‑Fi नेटवर्कमा जडान गर्दै"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi नेटवर्कमा जडान गरियो"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi नेटवर्कमा जडान गर्न सकिएन"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सबै नेटवर्कहरू हेर्न ट्याप गर्नुहोस्"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"जडान गर्नुहोस्"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"सबै नेटवर्कहरू"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi नेटवर्कमा साइन इन गर्नुहोस्"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"सञ्जालमा साइन इन गर्नुहोस्"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1169,7 +1175,7 @@
     <string name="sim_done_button" msgid="827949989369963775">"भयो"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"SIM कार्ड थप गरियो"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"मोबाइल नेटवर्क पहुँच गर्न तपाईँको उपकरण पुनःस्टार्ट गर्नुहोस्।"</string>
-    <string name="sim_restart_button" msgid="4722407842815232347">"पुनःस्टार्ट गर्नुहोस्"</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"पुनः सुरु गर्नुहोस्"</string>
     <string name="carrier_app_dialog_message" msgid="7066156088266319533">"तपाईंको नयाँ SIM ले राम्रोसँग काम गर्न, तपाईंले आफ्नो वाहक मार्फत अनुप्रयोग स्थापना र खोल्न आवश्यक हुनेछ।"</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"अनुप्रयोग प्राप्त गर्नुहोस्"</string>
     <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"अहिले होइन"</string>
@@ -1191,6 +1197,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI को लागि USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB सहायकमा जोडिएको छ"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"थप विकल्पहरूका लागि ट्याप गर्नुहोस्।"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"एनालग अडियोको सहायक उपकरण पत्ता लाग्यो"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"संलग्न गरिएको यन्त्र यो फोनसँग कम्प्याटिबल छैन। थप जान्न ट्याप गर्नुहोस्।"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डिबग गर्ने जडित छ"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB डिबगिङलाई असक्षम गर्न ट्याप गर्नुहोस्।"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डिबगिङलाई असक्षम पार्न ट्याप गर्नुहोस्।"</string>
@@ -1296,9 +1304,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g>सँग जोडिएको। नेटवर्क प्रबन्ध गर्न हान्नुहोस्।"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"VPN जडान सधै जोड्दै…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"सधैँ खुल्ला हुने VPN जोडिएको"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"सधैँ-सक्रिय VPN लाई विच्छेद गरियो"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"सधैँ-सक्रिय रहने VPN सेवाबाट विच्छेद गरियो"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"सधैँ भरि VPN त्रुटिमा"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"सेट अप गर्न ट्याप गर्नुहोस्"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"नेटवर्क वा VPN सम्बन्धी सेटिङहरू परिवर्तन गर्नुहोस्"</string>
     <string name="upload_file" msgid="2897957172366730416">"फाइल छान्नुहोस्"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"कुनै फाइल छानिएको छैन"</string>
     <string name="reset" msgid="2448168080964209908">"रिसेट गर्नुहोस्"</string>
@@ -1307,8 +1315,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"कार मोडबाट बाहिर निस्कन ट्याप गर्नुहोस्।"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"टेथर गर्ने वा हटस्पट सक्रिय"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"सेट अप गर्न ट्याप गर्नुहोस्।"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिङलाई असक्षम पारिएको छ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"विवरणहरूका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्"</string>
     <string name="back_button_label" msgid="2300470004503343439">"पछाडि"</string>
     <string name="next_button_label" msgid="1080555104677992408">"अर्को"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"छोड्नुहोस्"</string>
@@ -1729,14 +1735,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"अनपिन गर्नुहोस्"</string>
     <string name="app_info" msgid="6856026610594615344">"अनुप्रयोगका बारे जानकारी"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"यन्त्रलाई रिसेट गर्ने हो?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"यन्त्रलाई रिसेट गर्न ट्याप गर्नुहोस्"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"डेमो सुरु गर्दै…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"यन्त्रलाई रिसेट गर्दै…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"यन्त्रलाई रिसेट गर्ने हो?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"तपाईं सबै परिवर्तनहरू गुमाउनु हुनेछ र <xliff:g id="TIMEOUT">%1$s</xliff:g> सेकेन्डमा डेमो फेरि सुरु हुनेछ…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"रद्द गर्नुहोस्"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"अहिले रिसेट गर्नुहोस्"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> लाई असक्षम गरियो"</string>
     <string name="conference_call" msgid="3751093130790472426">"सम्मेलन कल"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"उपकरणको वर्णन"</string>
@@ -1780,6 +1780,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"तटीय क्षेत्र र नदीछेउका ठाउँहरू छाडी उच्च सतहमा अवस्थित कुनै अझ सुरक्षित ठाउँमा जानुहोस्।"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"शान्त रहनुहोस् र नजिकै आश्रयस्थल खोज्नुहोस्।"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"आपतकालीन सन्देशहरूको परीक्षण"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"जवाफ दिनुहोस्"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM लाई अनुमति छैन"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM को प्रावधान छैन"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index c2fcb3f..f18cd3b 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Service zoeken"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Bellen via wifi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via \'Instellingen\'."</item>
+    <item msgid="3910386316304772394">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via Instellingen. (Foutcode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Registreren bij je provider"</item>
+    <item msgid="7472393097168811593">"Registreer bij je provider (foutcode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Spraakassistent"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Nu vergrendelen"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Content verborgen"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Content verborgen op basis van beleid"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Nieuwe melding"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtueel toetsenbord"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fysiek toetsenbord"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Beveiliging"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Meldingen"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo voor de detailhandel"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-verbinding"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps uitgevoerd op achtergrond"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> is op de achtergrond actief"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps worden uitgevoerd op de achtergrond"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps die de batterij gebruiken"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> gebruikt de batterij"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps gebruiken de batterij"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tik voor batterij- en datagebruik"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Veilige modus"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Open wifi-netwerken beschikbaar</item>
       <item quantity="one">Open wifi-netwerk beschikbaar</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Verbinding maken met een open wifi-netwerk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Verbinding maken met een open wifi-netwerk…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Verbonden met een wifi-netwerk"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kan geen verbinding maken met het wifi-netwerk"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerken te bekijken"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinding maken"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle netwerken"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inloggen bij wifi-netwerk"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Inloggen bij netwerk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB voor MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Aangesloten op een USB-accessoire"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tik voor meer opties."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analoog audioaccessoire gedetecteerd"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Het aangesloten apparaat werkt niet met deze telefoon. Tik voor meer informatie."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-foutopsporing verbonden"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tik om USB-foutopsporing uit te schakelen."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecteer deze optie om USB-foutopsporing uit te schakelen."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Verbonden met <xliff:g id="SESSION">%s</xliff:g>. Tik om het netwerk te beheren."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Always-on VPN-verbinding maken…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Always-on VPN-verbinding"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Always-on VPN-verbinding ontkoppeld"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Verbinding met Always-on VPN verbroken"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Fout met Always-on VPN"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Tik om in te stellen"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Netwerk- of VPN-instellingen wijzigen"</string>
     <string name="upload_file" msgid="2897957172366730416">"Bestand kiezen"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Geen bestand geselecteerd"</string>
     <string name="reset" msgid="2448168080964209908">"Resetten"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tik om de automodus te sluiten."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering of hotspot actief"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tik om in te stellen."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is uitgeschakeld"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Neem contact op met je beheerder voor meer informatie"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Vorige"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Volgende"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Overslaan"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Losmaken"</string>
     <string name="app_info" msgid="6856026610594615344">"App-info"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Apparaat resetten?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Tik om apparaat te resetten"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Demo starten…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Apparaat resetten…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Apparaat resetten?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Je wijzigingen gaan verloren. De demo wordt opnieuw gestart over <xliff:g id="TIMEOUT">%1$s</xliff:g> seconden…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Annuleren"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Nu resetten"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> uitgeschakeld"</string>
     <string name="conference_call" msgid="3751093130790472426">"Telefonische vergadering"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Knopinfo"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Verlaat kustgebieden en rivieroevers onmiddellijk en zoek een hoger gelegen gebied op."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Blijf kalm en zoek onderdak in de buurt."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test voor noodberichten"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Beantwoorden"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Simkaart niet toegestaan"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Simkaart niet geregistreerd"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 599ea83..5e545ef 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -44,7 +44,7 @@
     <string name="unknownName" msgid="6867811765370350269">"ਅਗਿਆਤ"</string>
     <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"ਵੌਇਸਮੇਲ"</string>
     <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
-    <string name="mmiError" msgid="5154499457739052907">"ਕਨੈਕਸ਼ਨ ਸਮੱਸਿਆ ਜਾਂ ਅਪ੍ਰਮਾਣਿਕ MMI ਕੋਡ।"</string>
+    <string name="mmiError" msgid="5154499457739052907">"ਕਨੈਕਸ਼ਨ ਸਮੱਸਿਆ ਜਾਂ ਅਵੈਧ MMI ਕੋਡ।"</string>
     <string name="mmiFdnError" msgid="5224398216385316471">"ਓਪਰੇਸ਼ਨ ਕੇਵਲ ਫਿਕਸਡ ਡਾਇਲਿੰਗ ਨੰਬਰਾਂ ਤੱਕ ਸੀਮਿਤ ਹੈ।"</string>
     <string name="mmiErrorWhileRoaming" msgid="762488890299284230">"ਤੁਹਾਡੇ ਰੋਮਿੰਗ ਵਿੱਚ ਹੋਣ ਦੌਰਾਨ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਕਾਲ ਫਾਰਵਰਡਿੰਗ ਸੈਟਿੰਗਾਂ ਨੂੰ ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
     <string name="serviceEnabled" msgid="8147278346414714315">"ਸੇਵਾ ਅਸਮਰੱਥ ਬਣਾਈ ਗਈ ਸੀ।"</string>
@@ -52,28 +52,28 @@
     <string name="serviceDisabled" msgid="1937553226592516411">"ਸੇਵਾ ਅਸਮਰੱਥ ਬਣਾਈ ਗਈ ਹੈ।"</string>
     <string name="serviceRegistered" msgid="6275019082598102493">"ਰਜਿਸਟਰੇਸ਼ਨ ਸਫਲ ਸੀ।"</string>
     <string name="serviceErased" msgid="1288584695297200972">"ਮਿਟਾਉਣਾ ਸਫ਼ਲ ਰਿਹਾ ਸੀ।"</string>
-    <string name="passwordIncorrect" msgid="7612208839450128715">"ਗ਼ਲਤ ਪਾਸਵਰਡ।"</string>
+    <string name="passwordIncorrect" msgid="7612208839450128715">"ਗਲਤ ਪਾਸਵਰਡ।"</string>
     <string name="mmiComplete" msgid="8232527495411698359">"MMI ਪੂਰਾ।"</string>
     <string name="badPin" msgid="9015277645546710014">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤਾ ਪੁਰਾਣਾ ਪਿੰਨ ਠੀਕ ਨਹੀਂ ਹੈ।"</string>
     <string name="badPuk" msgid="5487257647081132201">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤਾ PUK ਠੀਕ ਨਹੀਂ ਹੈ।"</string>
     <string name="mismatchPin" msgid="609379054496863419">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤੇ ਪਿੰਨ ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ।"</string>
-    <string name="invalidPin" msgid="3850018445187475377">"ਇੱਕ ਪਿੰਨ ਟਾਈਪ ਕਰੋ ਜੋ 4 ਤੋਂ 8 ਨੰਬਰਾਂ ਦਾ ਹੈ।"</string>
+    <string name="invalidPin" msgid="3850018445187475377">"ਕੋਈ ਪਿੰਨ ਟਾਈਪ ਕਰੋ ਜੋ 4 ਤੋਂ 8 ਨੰਬਰਾਂ ਦਾ ਹੋਵੇ।"</string>
     <string name="invalidPuk" msgid="8761456210898036513">"ਇੱਕ PUK ਕੋਡ ਟਾਈਪ ਕਰੋ ਜੋ 8 ਜਾਂ ਵੱਧ ਸੰਖਿਆਵਾਂ ਦਾ ਹੋਵੇ।"</string>
-    <string name="needPuk" msgid="919668385956251611">"ਤੁਹਾਡਾ SIM ਕਾਰਡ PUK-ਲੌਕਡ ਹੈ। ਇਸਨੂੰ ਅਨਲੌਕ ਕਰਨ ਲਈ PUK ਕੋਡ ਟਾਈਪ ਕਰੋ।"</string>
+    <string name="needPuk" msgid="919668385956251611">"ਤੁਹਾਡਾ ਸਿਮ ਕਾਰਡ PUK-ਲੌਕਡ ਹੈ। ਇਸਨੂੰ ਅਣਲਾਕ ਕਰਨ ਲਈ PUK ਕੋਡ ਟਾਈਪ ਕਰੋ।"</string>
     <string name="needPuk2" msgid="4526033371987193070">"SIM ਕਾਰਡ ਅਨਬਲੌਕ ਕਰਨ ਲਈ PUK2 ਟਾਈਪ ਕਰੋ।"</string>
-    <string name="enablePin" msgid="209412020907207950">"ਅਸਫਲ, SIM/RUIM ਲੌਕ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ।"</string>
+    <string name="enablePin" msgid="209412020907207950">"ਅਸਫਲ, SIM/RUIM  ਲਾਕ  ਨੂੰ ਚਾਲੂ ਕਰੋ।"</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
-      <item quantity="one">ਇਸਤੋਂ ਪਹਿਲਾਂ ਕਿ SIM ਲੌਕ ਹੋਵੇ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ।</item>
-      <item quantity="other">ਇਸਤੋਂ ਪਹਿਲਾਂ ਕਿ SIM ਲੌਕ ਹੋਵੇ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ।</item>
+      <item quantity="one">ਇਸਤੋਂ ਪਹਿਲਾਂ ਕਿ SIM  ਲਾਕ  ਹੋਵੇ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ।</item>
+      <item quantity="other">ਇਸਤੋਂ ਪਹਿਲਾਂ ਕਿ SIM  ਲਾਕ  ਹੋਵੇ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ।</item>
     </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ਇਨਕਮਿੰਗ ਕਾਲਰ ਆਈ.ਡੀ."</string>
     <string name="ClirMmi" msgid="7784673673446833091">"ਆਊਟਗੋਇੰਗ ਕਾਲਰ ਆਈ.ਡੀ."</string>
-    <string name="ColpMmi" msgid="3065121483740183974">"ਕਨੈਕਟ ਕੀਤੀ ਲਾਈਨ ID"</string>
-    <string name="ColrMmi" msgid="4996540314421889589">"ਕਨੈਕਟ ਕੀਤੀ ਲਾਈਨ ID ਪ੍ਰਤਿਬੰਧ"</string>
-    <string name="CfMmi" msgid="5123218989141573515">"ਕਾਲ ਫੌਰਵਾਰਡਿੰਗ"</string>
-    <string name="CwMmi" msgid="9129678056795016867">"ਕਾਲ ਉਡੀਕ ਵਿੱਚ"</string>
+    <string name="ColpMmi" msgid="3065121483740183974">"ਕਨੈਕਟ ਕੀਤੀ ਲਾਈਨ ਆਈ.ਡੀ."</string>
+    <string name="ColrMmi" msgid="4996540314421889589">"ਕਨੈਕਟ ਕੀਤੀ ਲਾਈਨ ਆਈ.ਡੀ. ਪ੍ਰਤਿਬੰਧ"</string>
+    <string name="CfMmi" msgid="5123218989141573515">"ਕਾਲ ਫਾਰਵਰਡਿੰਗ"</string>
+    <string name="CwMmi" msgid="9129678056795016867">"ਕਾਲ ਦੀ ਉਡੀਕ"</string>
     <string name="BaMmi" msgid="455193067926770581">"ਕਾਲ ਬੈਰਿੰਗ"</string>
     <string name="PwdMmi" msgid="7043715687905254199">"ਪਾਸਵਰਡ ਬਦਲੋ"</string>
     <string name="PinMmi" msgid="3113117780361190304">"ਪਿੰਨ ਬਦਲਣਾ"</string>
@@ -89,7 +89,7 @@
     <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ਪ੍ਰਤਿਬੰਧਿਤ ਨਾ ਕਰਨ ਲਈ ਕਾਲਰ ਆਈ.ਡੀ. ਪੂਰਵ-ਨਿਰਧਾਰਤ। ਅਗਲੀ ਕਾਲ: ਪ੍ਰਤਿਬੰਧਿਤ ਨਹੀਂ"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"ਸੇਵਾ ਪ੍ਰਬੰਧਿਤ ਨਹੀਂ ਹੈ।"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"ਤੁਸੀਂ ਕਾਲਰ ਆਈ.ਡੀ. ਸੈਟਿੰਗ ਨਹੀਂ ਬਦਲ ਸਕਦੇ।"</string>
-    <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"ਕੋਈ ਡੈਟਾ ਸੇਵਾ ਨਹੀਂ"</string>
+    <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"ਕੋਈ  ਡਾਟਾ  ਸੇਵਾ ਨਹੀਂ"</string>
     <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"ਸੰਕਟਕਾਲ ਵਿੱਚ ਕੋਈ ਕਾਲ ਨਹੀਂ"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"ਕੋਈ ਆਵਾਜ਼ੀ ਸੇਵਾ ਨਹੀਂ"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ਕੋਈ ਆਵਾਜ਼ੀ/ਸੰਕਟਕਾਲੀਨ ਸੇਵਾ ਨਹੀਂ"</string>
@@ -99,7 +99,7 @@
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ਸੁਚੇਤਨਾਵਾਂ"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"ਕਾਲ ਫਾਰਵਰਡਿੰਗ"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"ਸੰਕਟਕਾਲੀਨ ਕਾਲਬੈਕ ਮੋਡ"</string>
-    <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"ਮੋਬਾਈਲ ਡੈਟਾ ਸੁਚੇਤਨਾਵਾਂ"</string>
+    <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"ਮੋਬਾਈਲ ਡਾਟਾ ਸੁਚੇਤਨਾਵਾਂ"</string>
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS ਸੁਨੇਹੇ"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"ਵੌਇਸਮੇਲ ਸੁਨੇਹੇ"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ"</string>
@@ -107,8 +107,8 @@
     <string name="peerTtyModeHco" msgid="5728602160669216784">"ਪੀਅਰ ਨੇ TTY Mode HCO ਦੀ ਬੇਨਤੀ ਕੀਤੀ"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"ਪੀਅਰ ਨੇ TTY Mode VCO ਦੀ ਬੇਨਤੀ ਕੀਤੀ"</string>
     <string name="peerTtyModeOff" msgid="3280819717850602205">"ਪੀਅਰ ਨੇ TTY Mode OFF ਦੀ ਬੇਨਤੀ ਕੀਤੀ"</string>
-    <string name="serviceClassVoice" msgid="1258393812335258019">"ਵੌਇਸ"</string>
-    <string name="serviceClassData" msgid="872456782077937893">"ਡੈਟਾ"</string>
+    <string name="serviceClassVoice" msgid="1258393812335258019">"ਅਵਾਜ਼"</string>
+    <string name="serviceClassData" msgid="872456782077937893">" ਡਾਟਾ"</string>
     <string name="serviceClassFAX" msgid="5566624998840486475">"ਫੈਕਸ"</string>
     <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
     <string name="serviceClassDataAsync" msgid="4523454783498551468">"ਅਸਿੰਕ"</string>
@@ -131,26 +131,26 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"ਸੇਵਾ ਦੀ ਖੋਜ ਕਰ ਰਿਹਾ ਹੈ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"ਵਾਈ-ਫਾਈ ਤੇ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਲਈ, ਪਹਿਲਾਂ ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਇਹ ਸੇਵਾ ਸੈਟ ਅਪ ਕਰਨ ਲਈ ਕਹੋ। ਫਿਰ ਸੈਟਿੰਗਾਂ ਵਿੱਚੋਂ ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰੋ।"</item>
+    <item msgid="3910386316304772394">"ਵਾਈ-ਫਾਈ ਤੋਂ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਦੇ ਲਈ, ਸਭ ਤੋਂ ਪਹਿਲਾਂ ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਇਸ ਸੇਵਾ ਦੀ ਸਥਾਪਨਾ ਕਰਨ ਲਈ ਕਹੋ। ਫਿਰ ਸੈਟਿੰਗਾਂ ਵਿੱਚੋਂ ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ ਨੂੰ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰੋ। (ਗੜਬੜੀ ਕੋਡ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਰਜਿਸਟਰ ਕਰੋ"</item>
+    <item msgid="7472393097168811593">"ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਪੰਜੀਕਰਨ ਕਰੋ (ਗੜਬੜ ਕੋਡ: <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>
     <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_wifi_preferred_summary" msgid="1994113411286935263">"ਤਰਜੀਹੀ ਵਾਈ-ਫਾਈ"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ਮੋਬਾਈਲ ਨੂੰ ਤਰਜੀਹ ਹੈ"</string>
-    <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"ਕੇਵਲ Wi-Fi"</string>
+    <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"ਸਿਰਫ਼ ਵਾਈ-ਫਾਈ"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ਅੱਗੇ ਨਹੀਂ ਭੇਜਿਆ ਗਿਆ"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
     <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> <xliff:g id="TIME_DELAY">{2}</xliff:g> ਸਕਿੰਟਾਂ ਬਾਅਦ"</string>
     <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ਅੱਗੇ ਨਹੀਂ ਭੇਜਿਆ ਗਿਆ"</string>
     <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ਅੱਗੇ ਨਹੀਂ ਭੇਜਿਆ ਗਿਆ"</string>
     <string name="fcComplete" msgid="3118848230966886575">"ਵਿਸ਼ੇਸ਼ਤਾ ਕੋਡ ਪੂਰਾ।"</string>
-    <string name="fcError" msgid="3327560126588500777">"ਕਨੈਕਸ਼ਨ ਸਮੱਸਿਆ ਜਾਂ ਅਪ੍ਰਮਾਣਿਕ ਵਿਸ਼ੇਸ਼ਤਾ ਕੋਡ।"</string>
+    <string name="fcError" msgid="3327560126588500777">"ਕਨੈਕਸ਼ਨ ਸਮੱਸਿਆ ਜਾਂ ਅਵੈਧ ਵਿਸ਼ੇਸ਼ਤਾ ਕੋਡ।"</string>
     <string name="httpErrorOk" msgid="1191919378083472204">"ਠੀਕ"</string>
     <string name="httpError" msgid="7956392511146698522">"ਇੱਕ ਨੈੱਟਵਰਕ ਅਸ਼ੁੱਧੀ ਹੋਈ ਸੀ।"</string>
     <string name="httpErrorLookup" msgid="4711687456111963163">"URL ਨਹੀਂ ਲੱਭ ਸਕਿਆ।"</string>
@@ -160,21 +160,21 @@
     <string name="httpErrorConnect" msgid="8714273236364640549">"ਸਰਵਰ ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string>
     <string name="httpErrorIO" msgid="2340558197489302188">"ਸਰਵਰ ਨਾਲ ਸੰਚਾਰ ਨਹੀਂ ਕਰ ਸਕਿਆ। ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="httpErrorTimeout" msgid="4743403703762883954">"ਸਰਵਰ ਨਾਲ ਕਨੈਕਸ਼ਨ ਦਾ ਸਮਾਂ ਸਮਾਪਤ ਹੋਇਆ।"</string>
-    <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"ਸਫ਼ੇ ਵਿੱਚ ਬਹੁਤ ਜ਼ਿਆਦਾ ਰੀਡਾਇਰੈਕਟ ਸ਼ਾਮਲ ਹਨ।"</string>
+    <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"ਪੰਨੇ ਵਿੱਚ ਬਹੁਤ ਜ਼ਿਆਦਾ ਰੀਡਾਇਰੈਕਟ ਸ਼ਾਮਲ ਹਨ।"</string>
     <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"ਪ੍ਰੋਟੋਕੋਲ ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ।"</string>
     <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"ਇੱਕ ਸੁਰੱਖਿਅਤ ਕਨੈਕਸ਼ਨ ਸਥਾਪਿਤ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string>
-    <string name="httpErrorBadUrl" msgid="3636929722728881972">"ਸਫ਼ਾ ਨਹੀਂ ਖੋਲ੍ਹ ਸਕਿਆ ਕਿਉਂਕਿ URL ਅਪ੍ਰਮਾਣਿਕ ਹੈ।"</string>
-    <string name="httpErrorFile" msgid="2170788515052558676">"ਫਾਈਲ ਤੱਕ ਨਹੀਂ ਪਹੁੰਚ ਸਕਿਆ।"</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"ਪੰਨਾ ਨਹੀਂ ਖੋਲ੍ਹ ਸਕਿਆ ਕਿਉਂਕਿ URL ਅਵੈਧ ਹੈ।"</string>
+    <string name="httpErrorFile" msgid="2170788515052558676">"ਫ਼ਾਈਲ ਤੱਕ ਨਹੀਂ ਪਹੁੰਚ ਸਕਿਆ।"</string>
     <string name="httpErrorFileNotFound" msgid="6203856612042655084">"ਬੇਨਤੀ ਕੀਤੀ ਫਾਈਲ ਨਹੀਂ ਲੱਭ ਸਕਿਆ।"</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਬੇਨਤੀਆਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ। ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="notification_title" msgid="8967710025036163822">"<xliff:g id="ACCOUNT">%1$s</xliff:g> ਲਈ ਸਾਈਨਇਨ ਅਸ਼ੁੱਧੀ"</string>
     <string name="contentServiceSync" msgid="8353523060269335667">"ਸਿੰਕ ਕਰੋ"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"ਸਿੰਕ ਕਰੋ"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"ਬਹੁਤ ਜ਼ਿਆਦਾ <xliff:g id="CONTENT_TYPE">%s</xliff:g> ਮਿਟਾਏ।"</string>
-    <string name="low_memory" product="tablet" msgid="6494019234102154896">"ਟੈਬਲੇਟ ਸਟੋਰੇਜ ਪੂਰੀ ਭਰੀ ਹੈ। ਸਪੇਸ ਖਾਲੀ ਕਰਨ ਲਈ ਕੁਝ ਫਾਈਲਾਂ ਮਿਟਾਓ।"</string>
-    <string name="low_memory" product="watch" msgid="4415914910770005166">"ਘੜੀ ਸਟੋਰੇਜ ਪੂਰੀ ਭਰੀ ਹੈ। ਸਪੇਸ ਖਾਲੀ ਕਰਨ ਲਈ ਕੁਝ ਫਾਈਲਾਂ ਮਿਟਾਓ।"</string>
-    <string name="low_memory" product="tv" msgid="516619861191025923">"TV ਸਟੋਰੇਜ ਪੂਰੀ ਭਰੀ ਹੈ। ਸਪੇਸ ਖਾਲੀ ਕਰਨ ਲਈ ਕੁਝ ਫਾਈਲਾਂ ਮਿਟਾਓ।"</string>
-    <string name="low_memory" product="default" msgid="3475999286680000541">"ਫੋਨ ਸਟੋਰੇਜ ਪੂਰੀ ਭਰੀ ਹੈ। ਸਪੇਸ ਖਾਲੀ ਕਰਨ ਲਈ ਕੁਝ ਫਾਈਲਾਂ ਮਿਟਾਓ।"</string>
+    <string name="low_memory" product="tablet" msgid="6494019234102154896">"ਟੈਬਲੈੱਟ ਸਟੋਰੇਜ ਪੂਰੀ ਭਰੀ ਹੈ। ਜਗ੍ਹਾ ਖਾਲੀ ਕਰਨ ਲਈ ਕੁਝ ਫ਼ਾਈਲਾਂ ਮਿਟਾਓ।"</string>
+    <string name="low_memory" product="watch" msgid="4415914910770005166">"ਘੜੀ ਸਟੋਰੇਜ ਪੂਰੀ ਭਰੀ ਹੈ। ਜਗ੍ਹਾ ਖਾਲੀ ਕਰਨ ਲਈ ਕੁਝ ਫ਼ਾਈਲਾਂ ਮਿਟਾਓ।"</string>
+    <string name="low_memory" product="tv" msgid="516619861191025923">"ਟੀਵੀ ਸਟੋਰੇਜ ਪੂਰੀ ਭਰੀ ਹੈ। ਜਗ੍ਹਾ ਖਾਲੀ ਕਰਨ ਲਈ ਕੁਝ ਫ਼ਾਈਲਾਂ ਮਿਟਾਓ।"</string>
+    <string name="low_memory" product="default" msgid="3475999286680000541">"ਫ਼ੋਨ ਸਟੋਰੇਜ ਪੂਰੀ ਭਰੀ ਹੈ। ਜਗ੍ਹਾ ਖਾਲੀ ਕਰਨ ਲਈ ਕੁਝ ਫ਼ਾਈਲਾਂ ਮਿਟਾਓ।"</string>
     <plurals name="ssl_ca_cert_warning" formatted="false" msgid="5106721205300213569">
       <item quantity="one">ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਥਾਰਿਟੀਆਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਗਈਆਂ</item>
       <item quantity="other">ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਥਾਰਿਟੀਆਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਗਈਆਂ</item>
@@ -182,58 +182,58 @@
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"ਇੱਕ ਅਗਿਆਤ ਤੀਜੀ ਪਾਰਟੀ ਵੱਲੋਂ"</string>
     <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g> ਮੁਤਾਬਕ"</string>
-    <string name="work_profile_deleted" msgid="5005572078641980632">"ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਮਿਟਾਈ ਗਈ"</string>
+    <string name="work_profile_deleted" msgid="5005572078641980632">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਮਿਟਾਈ ਗਈ"</string>
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"ਗੁੰਮਸ਼ੁਦਾ ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਦੇ ਕਾਰਨ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਮਿਟਾਇਆ ਗਿਆ"</string>
-    <string name="work_profile_deleted_details" msgid="6307630639269092360">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਜਾਂ ਤਾਂ ਗੁੰਮਸ਼ੁਦਾ ਹੈ ਜਾਂ ਖਰਾਬ ਹੈ। ਨਤੀਜੇ ਵਜੋਂ, ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਸਬੰਧਿਤ ਡੈਟਾ ਮਿਟਾਇਆ ਗਿਆ ਹੈ। ਸਹਾਇਤਾ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
+    <string name="work_profile_deleted_details" msgid="6307630639269092360">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਜਾਂ ਤਾਂ ਗੁੰਮਸ਼ੁਦਾ ਹੈ ਜਾਂ ਖਰਾਬ ਹੈ। ਨਤੀਜੇ ਵਜੋਂ, ਤੁਹਾਡੀ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਸਬੰਧਿਤ ਡਾਟਾ ਮਿਟਾਇਆ ਗਿਆ ਹੈ। ਸਹਾਇਤਾ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਹੁਣ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਨ ਅਧੀਨ ਹੈ"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"ਤੁਹਾਡਾ ਸੰਗਠਨ ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਦਾ ਹੈ ਅਤੇ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਮਿਟਾਇਆ ਜਾਏਗਾ"</string>
-    <string name="factory_reset_message" msgid="7972496262232832457">"ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਵਰਤੀ ਨਹੀਂ ਜਾ ਸਕਦੀ। ਹੁਣ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਡਾਟਾ ਮਿਟਾਇਆ ਜਾਵੇਗਾ।\n\nਜੇਕਰ ਤੁਹਾਡੇ ਕੋਲ ਕੋਈ ਸਵਾਲ ਹਨ, ਤਾਂ ਆਪਣੀ ਸੰਸਥਾ ਦੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
+    <string name="factory_reset_message" msgid="7972496262232832457">"ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਵਰਤੀ ਨਹੀਂ ਜਾ ਸਕਦੀ। ਹੁਣ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਡਾਟਾ ਮਿਟਾਇਆ ਜਾਵੇਗਾ।\n\nਜੇਕਰ ਤੁਹਾਡੇ ਕੋਲ ਕੋਈ ਸਵਾਲ ਹਨ, ਤਾਂ ਆਪਣੀ ਸੰਸਥਾ ਦੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="me" msgid="6545696007631404292">"ਮੈਂ"</string>
-    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ਟੈਬਲੇਟ ਚੋਣਾਂ"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ਟੈਬਲੈੱਟ ਵਿਕਲਪ"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"TV ਚੋਣਾਂ"</string>
-    <string name="power_dialog" product="default" msgid="1319919075463988638">"ਫੋਨ ਚੋਣਾਂ"</string>
+    <string name="power_dialog" product="default" msgid="1319919075463988638">"ਫ਼ੋਨ ਚੋਣਾਂ"</string>
     <string name="silent_mode" msgid="7167703389802618663">"ਸਾਈਲੈਂਟ ਮੋਡ"</string>
     <string name="turn_on_radio" msgid="3912793092339962371">"ਵਾਇਰਲੈਸ ਚਾਲੂ ਕਰੋ"</string>
     <string name="turn_off_radio" msgid="8198784949987062346">"ਵਾਇਰਲੈਸ ਬੰਦ ਕਰੋ"</string>
-    <string name="screen_lock" msgid="799094655496098153">"ਸਕ੍ਰੀਨ ਲੌਕ"</string>
+    <string name="screen_lock" msgid="799094655496098153">"ਸਕ੍ਰੀਨ  ਲਾਕ"</string>
     <string name="power_off" msgid="4266614107412865048">"ਪਾਵਰ ਬੰਦ"</string>
     <string name="silent_mode_silent" msgid="319298163018473078">"ਰਿੰਗਰ ਬੰਦ"</string>
     <string name="silent_mode_vibrate" msgid="7072043388581551395">"ਰਿੰਗਰ ਥਰਥਰਾਹਟ"</string>
     <string name="silent_mode_ring" msgid="8592241816194074353">"ਰਿੰਗਰ ਚਾਲੂ"</string>
-    <string name="reboot_to_update_title" msgid="6212636802536823850">"Android ਸਿਸਟਮ ਅਪਡੇਟ"</string>
-    <string name="reboot_to_update_prepare" msgid="6305853831955310890">"ਅਪਡੇਟ ਦੀ ਤਿਆਰੀ ਕਰ ਰਿਹਾ ਹੈ…"</string>
-    <string name="reboot_to_update_package" msgid="3871302324500927291">"ਅਪਡੇਟ ਪੈਕੇਜ ਦੀ ਕਾਰਵਾਈ ਕਰ ਰਿਹਾ ਹੈ..."</string>
+    <string name="reboot_to_update_title" msgid="6212636802536823850">"Android ਸਿਸਟਮ ਅੱਪਡੇਟ"</string>
+    <string name="reboot_to_update_prepare" msgid="6305853831955310890">"ਅੱਪਡੇਟ ਦੀ ਤਿਆਰੀ ਕਰ ਰਿਹਾ ਹੈ…"</string>
+    <string name="reboot_to_update_package" msgid="3871302324500927291">"ਅੱਪਡੇਟ ਪੈਕੇਜ ਦੀ ਕਾਰਵਾਈ ਕਰ ਰਿਹਾ ਹੈ..."</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"ਰੀਸਟਾਰਟ ਹੋ ਰਿਹਾ ਹੈ…"</string>
     <string name="reboot_to_reset_title" msgid="4142355915340627490">"ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"ਰੀਸਟਾਰਟ ਹੋ ਰਿਹਾ ਹੈ…"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"ਬੰਦ ਹੋ ਰਿਹਾ ਹੈ…"</string>
-    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"ਤੁਹਾਡੀ ਟੈਬਲੇਟ ਬੰਦ ਕੀਤੀ ਜਾਏਗੀ।"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਬੰਦ ਕੀਤਾ ਜਾਵੇਗਾ।"</string>
     <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"ਤੁਹਾਡਾ TV ਬੰਦ ਕੀਤਾ ਜਾਏਗਾ।"</string>
     <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"ਤੁਹਾਡੀ ਘੜੀ ਬੰਦ ਕੀਤੀ ਜਾਏਗੀ।"</string>
-    <string name="shutdown_confirm" product="default" msgid="649792175242821353">"ਤੁਹਾਡਾ ਫੋਨ ਬੰਦ ਕੀਤਾ ਜਾਏਗਾ।"</string>
+    <string name="shutdown_confirm" product="default" msgid="649792175242821353">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਬੰਦ ਕੀਤਾ ਜਾਏਗਾ।"</string>
     <string name="shutdown_confirm_question" msgid="2906544768881136183">"ਕੀ ਤੁਸੀਂ ਬੰਦ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
     <string name="reboot_safemode_title" msgid="7054509914500140361">"ਮੋਡ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ ਰੀਬੂਟ ਕਰੋ"</string>
     <string name="reboot_safemode_confirm" msgid="55293944502784668">"ਕੀ ਤੁਸੀਂ ਸੁਰੱਖਿਅਤ ਮੋਡ ਵਿੱਚ ਰੀਬੂਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਇਹ ਤੁਹਾਡੇ ਵੱਲੋਂ ਇੰਸਟੌਲ ਕੀਤੀਆਂ ਤੀਜੀ ਪਾਰਟੀ ਦੀਆਂ ਸਾਰੀਆਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾ ਦੇਵੇਗਾ। ਜਦੋਂ ਤੁਸੀਂ ਦੁਬਾਰਾ ਰੀਬੂਟ ਕਰੋਂਗੇ ਤਾਂ ਇਸਨੂੰ ਰੀਸਟੋਰ ਕੀਤਾ ਜਾਏਗਾ।"</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"ਹਾਲੀਆ"</string>
     <string name="no_recent_tasks" msgid="8794906658732193473">"ਕੋਈ ਹਾਲੀਆ ਐਪਸ ਨਹੀਂ।"</string>
-    <string name="global_actions" product="tablet" msgid="408477140088053665">"ਟੈਬਲੇਟ ਚੋਣਾਂ"</string>
+    <string name="global_actions" product="tablet" msgid="408477140088053665">"ਟੈਬਲੈੱਟ ਵਿਕਲਪ"</string>
     <string name="global_actions" product="tv" msgid="7240386462508182976">"TV ਚੋਣਾਂ"</string>
-    <string name="global_actions" product="default" msgid="2406416831541615258">"ਫੋਨ ਚੋਣਾਂ"</string>
-    <string name="global_action_lock" msgid="2844945191792119712">"ਸਕ੍ਰੀਨ ਲੌਕ"</string>
+    <string name="global_actions" product="default" msgid="2406416831541615258">"ਫ਼ੋਨ ਚੋਣਾਂ"</string>
+    <string name="global_action_lock" msgid="2844945191792119712">"ਸਕ੍ਰੀਨ  ਲਾਕ"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"ਪਾਵਰ ਬੰਦ"</string>
     <string name="global_action_emergency" msgid="7112311161137421166">"ਸੰਕਟਕਾਲ"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"ਬਗ ਰਿਪੋਰਟ"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ਬਗ ਰਿਪੋਰਟ ਲਓ"</string>
-    <string name="bugreport_message" msgid="398447048750350456">"ਇਹ ਇੱਕ ਈਮੇਲ ਸੁਨੇਹਾ ਭੇਜਣ ਲਈ, ਤੁਹਾਡੇ ਵਰਤਮਾਨ ਡੀਵਾਈਸ ਬਾਰੇ ਜਾਣਕਾਰੀ ਇਕੱਠੀ ਕਰੇਗਾ। ਬਗ ਰਿਪੋਰਟ ਸ਼ੁਰੂ ਕਰਨ ਵਿੱਚ ਥੋੜ੍ਹਾ ਸਮਾਂ ਲੱਗੇਗਾ ਜਦੋਂ ਤੱਕ ਇਹ ਭੇਜੇ ਜਾਣ ਲਈ ਤਿਆਰ ਨਾ ਹੋਵੇ, ਕਿਰਪਾ ਕਰਕੇ ਧੀਰਜ ਰੱਖੋ।"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"ਇਹ ਇੱਕ ਈਮੇਲ ਸੁਨੇਹਾ ਭੇਜਣ ਲਈ, ਤੁਹਾਡੇ ਵਰਤਮਾਨ ਡੀਵਾਈਸ ਬਾਰੇ ਜਾਣਕਾਰੀ ਇਕੱਠੀ ਕਰੇਗਾ। ਬੱਗ ਰਿਪੋਰਟ ਸ਼ੁਰੂ ਕਰਨ ਵਿੱਚ ਥੋੜ੍ਹਾ ਸਮਾਂ ਲੱਗੇਗਾ ਜਦੋਂ ਤੱਕ ਇਹ ਭੇਜੇ ਜਾਣ ਲਈ ਤਿਆਰ ਨਾ ਹੋਵੇ, ਕਿਰਪਾ ਕਰਕੇ ਧੀਰਜ ਰੱਖੋ।"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ਅੰਤਰਕਿਰਿਆਤਮਕ ਰਿਪੋਰਟ"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"ਜ਼ਿਆਦਾਤਰ ਹਾਲਾਤਾਂ ਵਿੱਚ ਇਸ ਦੀ ਵਰਤੋਂ ਕਰੋ। ਇਹ ਤੁਹਾਨੂੰ ਰਿਪੋਰਟ ਦੀ ਪ੍ਰਗਤੀ ਨੂੰ ਟਰੈਕ ਕਰਨ, ਸਮੱਸਿਆ ਬਾਰੇ ਹੋਰ ਵੇਰਵੇ ਦਾਖਲ ਕਰਨ, ਅਤੇ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈਣ ਦਿੰਦਾ ਹੈ। ਇਹ ਉਹਨਾਂ ਘੱਟ-ਵਰਤੇ ਗਏ ਕੁਝ ਭਾਗਾਂ ਨੂੰ ਨਜ਼ਰ-ਅੰਦਾਜ਼ ਕਰ ਸਕਦਾ ਹੈ ਜਿਨ੍ਹਾਂ ਦੀ ਰਿਪੋਰਟ ਕਰਨ ਵਿੱਚ ਵੱਧ ਸਮਾਂ ਲੱਗ ਸਕਦਾ ਹੈ।"</string>
     <string name="bugreport_option_full_title" msgid="6354382025840076439">"ਪੂਰੀ ਰਿਪੋਰਟ"</string>
-    <string name="bugreport_option_full_summary" msgid="7210859858969115745">"ਜਦੋਂ ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਪ੍ਰਤਿਕਿਰਿਆ ਨਾ ਕਰ ਰਿਹਾ ਹੋਵੇ ਜਾਂ ਬਹੁਤ ਹੀ ਹੌਲੀ ਹੋਵੇ, ਜਾਂ ਜਦੋਂ ਤੁਹਾਨੂੰ ਸਾਰੇ ਰਿਪੋਰਟ ਭਾਗਾਂ ਦੀ ਲੋੜ ਹੋਵੇ ਤਾਂ ਇਸ ਚੋਣ ਦੀ ਵਰਤੋਂ ਘੱਟ-ਘੱਟ ਸਿਸਟਮ ਦਖ਼ਲ ਲਈ ਕਰੋ। ਤੁਹਾਨੂੰ ਹੋਰ ਵੇਰਵੇ ਦਾਖਲ ਕਰਨ ਜਾਂ ਵਾਧੂ ਸਕ੍ਰੀਨਸ਼ਾਟ ਨਹੀਂ ਲੈਣ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="bugreport_option_full_summary" msgid="7210859858969115745">"ਜਦੋਂ ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਪ੍ਰਤਿਕਿਰਿਆ ਨਾ ਕਰ ਰਿਹਾ ਹੋਵੇ ਜਾਂ ਬਹੁਤ ਹੀ ਹੌਲੀ ਹੋਵੇ, ਜਾਂ ਜਦੋਂ ਤੁਹਾਨੂੰ ਸਾਰੇ ਰਿਪੋਰਟ ਭਾਗਾਂ ਦੀ ਲੋੜ ਹੋਵੇ ਤਾਂ ਇਸ ਚੋਣ ਦੀ ਵਰਤੋਂ ਘੱਟ-ਘੱਟ ਸਿਸਟਮ ਦਖਲ ਲਈ ਕਰੋ। ਤੁਹਾਨੂੰ ਹੋਰ ਵੇਰਵੇ ਦਾਖਲ ਕਰਨ ਜਾਂ ਵਾਧੂ ਸਕ੍ਰੀਨਸ਼ਾਟ ਨਹੀਂ ਲੈਣ ਦਿੰਦਾ ਹੈ।"</string>
     <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
-      <item quantity="one">ਬੱਗ ਰਿਪੋਰਟ ਲਈ <xliff:g id="NUMBER_1">%d</xliff:g> ਸਕਿੰਟ ਵਿੱਚ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਿਆ ਜਾ ਰਿਹਾ ਹੈ।</item>
-      <item quantity="other">ਬੱਗ ਰਿਪੋਰਟ ਲਈ <xliff:g id="NUMBER_1">%d</xliff:g> ਸਕਿੰਟ ਵਿੱਚ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਿਆ ਜਾ ਰਿਹਾ ਹੈ।</item>
+      <item quantity="one">ਬੱਗ ਰਿਪੋਰਟ ਲਈ <xliff:g id="NUMBER_1">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਿਆ ਜਾ ਰਿਹਾ ਹੈ।</item>
+      <item quantity="other">ਬੱਗ ਰਿਪੋਰਟ ਲਈ <xliff:g id="NUMBER_1">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਿਆ ਜਾ ਰਿਹਾ ਹੈ।</item>
     </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"ਸਾਈਲੈਂਟ ਮੋਡ"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ਅਵਾਜ਼ ਬੰਦ ਹੈ"</string>
@@ -244,15 +244,14 @@
     <string name="global_action_settings" msgid="1756531602592545966">"ਸੈਟਿੰਗਾਂ"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"ਸਹਾਇਤਾ ਕਰੋ"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ਅਵਾਜ਼ੀ ਸਹਾਇਕ"</string>
-    <string name="global_action_lockdown" msgid="8751542514724332873">"ਹੁਣ ਲੌਕ ਕਰੋ"</string>
+    <string name="global_action_lockdown" msgid="8751542514724332873">"ਹੁਣ  ਲਾਕ  ਕਰੋ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"ਸਮੱਗਰੀਆਂ ਲੁਕਾਈਆਂ ਗਈਆਂ"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ਨੀਤੀ ਦੁਆਰਾ ਸਮੱਗਰੀ ਲੁਕਾਈ ਗਈ"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"ਨਵੀਂ ਸੂਚਨਾ"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ਆਭਾਸੀ ਕੀ-ਬੋਰਡ"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡ"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"ਸੁਰੱਖਿਆ"</string>
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"ਕਾਰ ਮੋਡ"</string>
-    <string name="notification_channel_account" msgid="7577959168463122027">"ਖਾਤੇ ਦੀ ਅਵਸਥਾ"</string>
+    <string name="notification_channel_account" msgid="7577959168463122027">"ਖਾਤੇ ਦੀ ਸਥਿਤੀ"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"ਵਿਕਾਸਕਾਰ ਸੁਨੇਹੇ"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"ਅੱਪਡੇਟ"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ਨੈੱਟਵਰਕ ਅਵਸਥਾ"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ਸੁਚੇਤਨਾਵਾਂ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"ਪ੍ਰਚੂਨ ਸਟੋਰਾਂ ਲਈ ਡੈਮੋ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB ਕਨੈਕਸ਼ਨ"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀਆਂ ਐਪਾਂ"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀ ਹੈ"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ਐਪਾਂ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀਆਂ ਹਨ"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ਬੈਟਰੀ ਦੀ ਖਪਤ ਕਰਨ ਵਾਲੀਆਂ ਐਪਾਂ"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ਐਪਾਂ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀਆਂ ਹਨ"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ਬੈਟਰੀ ਅਤੇ ਡਾਟਾ ਵਰਤੋਂ ਸਬੰਧੀ ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"ਸੁਰੱਖਿਅਤ ਮੋਡ"</string>
@@ -275,205 +274,205 @@
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"ਸੰਪਰਕ"</string>
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ਆਪਣੇ ਸੰਪਰਕਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"ਟਿਕਾਣਾ"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"ਇਸ ਡੀਵਾਈਸ ਦੇ ਨਿਰਧਾਰਿਤ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚੋ"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"ਇਸ ਡੀਵਾਈਸ ਦੇ ਨਿਰਧਾਰਤ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚੋ"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ਕੈਲੰਡਰ"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
-    <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS ਸੁਨੇਹੇ ਭੇਜਣ ਅਤੇ ਦੇਖਣ"</string>
+    <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS ਸੁਨੇਹੇ ਭੇਜੋ ਅਤੇ ਦੇਖੋ"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"ਸਟੋਰੇਜ"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਫ਼ਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨਾ"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"ਮਾਈਕ੍ਰੋਫੋਨ"</string>
-    <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ਔਡੀਓ ਰਿਕਾਰਡ ਕਰਨ"</string>
+    <string name="permgroupdesc_microphone" msgid="4988812113943554584">" ਆਡੀਓ  ਰਿਕਾਰਡ ਕਰਨ"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"ਕੈਮਰਾ"</string>
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"ਤਸਵੀਰਾਂ ਲੈਣ ਅਤੇ ਵੀਡੀਓ ਰਿਕਾਰਡ ਕਰਨ"</string>
-    <string name="permgrouplab_phone" msgid="5229115638567440675">"ਫੋਨ"</string>
+    <string name="permgrouplab_phone" msgid="5229115638567440675">"ਫ਼ੋਨ ਕਰੋ"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"ਫ਼ੋਨ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"ਸਰੀਰ ਸੰਵੇਦਕ"</string>
-    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ਆਪਣੇ ਸਰੀਰ ਦੇ ਅਹਿਮ ਚਿੰਨ੍ਹਾਂ ਬਾਰੇ ਸੰਵੇਦਕ ਡੈਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
+    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ਆਪਣੇ ਸਰੀਰ ਦੇ ਅਹਿਮ ਚਿੰਨ੍ਹਾਂ ਬਾਰੇ ਸੰਵੇਦਕ ਡਾਟਾ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ਵਿੰਡੋ ਸਮੱਗਰੀ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਨਾ"</string>
-    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ਕਿਸੇ ਵਿੰਡੋ ਦੀ ਸਮੱਗਰੀ ਦੀ ਜਾਂਚ ਕਰਨਾ, ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਅੰਤਰਕਿਰਿਆ ਕਰ ਰਹੇ ਹੋ।"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ਇੱਕ ਵਿੰਡੋ ਦੀ ਸਮੱਗਰੀ ਦੀ ਜਾਂਚ ਕਰੋ, ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਅੰਤਰਕਿਰਿਆ ਕਰ ਰਹੇ ਹੋ"</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>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ਇਸ ਵਿੱਚ ਨਿੱਜੀ  ਡਾਟਾ  ਸ਼ਾਮਲ ਹੈ ਜਿਵੇਂ ਕ੍ਰੈਡਿਟ ਕਾਰਡ ਨੰਬਰ ਅਤੇ ਪਾਸਵਰਡ।"</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"ਡਿਸਪਲੇ ਵੱਡਦਰਸ਼ੀਕਰਨ ਨੂੰ ਕੰਟਰੋਲ ਕਰਨਾ"</string>
-    <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ਡਿਸਪਲੇ ਦੇ ਜ਼ੂਮ ਪੱਧਰ ਅਤੇ ਸਥਿਤੀ ਨੂੰ ਨਿਯੰਤ੍ਰਿਤ ਕਰੋ।"</string>
+    <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ਡਿਸਪਲੇ ਦੇ ਜ਼ੂਮ ਪੱਧਰ ਅਤੇ ਸਥਿਤੀ ਨੂੰ ਕੰਟਰੋਲ ਕਰੋ।"</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ਸੰਕੇਤ ਕਰਦੀ ਹੈ"</string>
-    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ਟੈਪ ਕਰ ਸਕਦੀ ਹੈ, ਸਵਾਈਪ ਕਰ ਸਕਦੀ ਹੈ, ਪਿੰਚ ਕਰ ਸਕਦੀ ਹੈ, ਅਤੇ ਹੋਰ ਸੰਕੇਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ਟੈਪ ਕਰ ਸਕਦੀ ਹੈ, ਸਵਾਈਪ ਕਰ ਸਕਦੀ ਹੈ, ਚੂੰਢੀ ਭਰ ਸਕਦੀ ਹੈ, ਅਤੇ ਹੋਰ ਸੰਕੇਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੰਕੇਤ"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"ਡੀਵਾਈਸਾਂ ਦੇ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ \'ਤੇ ਕੀਤੇ ਗਏ ਸੰਕੇਤਾਂ ਨੂੰ ਕੈਪਚਰ ਕਰ ਸਕਦੀ ਹੈ।"</string>
-    <string name="permlab_statusBar" msgid="7417192629601890791">"ਸਥਿਤੀ ਬਾਰ ਅਸਮਰੱਥ ਬਣਾਓ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
-    <string name="permdesc_statusBar" msgid="8434669549504290975">"ਐਪ ਨੂੰ ਸਥਿਤੀ ਬਾਰ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਉਣ ਜਾਂ ਸਿਸਟਮ ਆਈਕਨਾਂ ਨੂੰ ਜੋੜਨ ਅਤੇ ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"ਸਥਿਤੀ ਪੱਟੀ ਬੰਦ ਕਰੋ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"ਐਪ ਨੂੰ ਸਥਿਤੀ ਪੱਟੀ ਨੂੰ ਚਾਲੂ ਕਰਨ ਜਾਂ ਸਿਸਟਮ ਪ੍ਰਤੀਕਾਂ ਨੂੰ ਜੋੜਨ ਅਤੇ ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"ਸਥਿਤੀ ਪੱਟੀ ਬਣਨ ਦਿਓ"</string>
-    <string name="permdesc_statusBarService" msgid="716113660795976060">"ਐਪ ਨੂੰ ਸਥਿਤੀ ਬਾਰ ਹੋਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"ਸਥਿਤੀ ਬਾਰ ਦਾ ਵਿਸਤਾਰ/ਨਸ਼ਟ ਕਰੋ"</string>
-    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"ਐਪ ਨੂੰ ਸਥਿਤੀ ਬਾਰ ਦਾ ਵਿਸਤਾਰ ਕਰਨ ਜਾਂ ਨਸ਼ਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_install_shortcut" msgid="4279070216371564234">"ਸ਼ਾਰਟਕੱਟ ਇੰਸਟੌਲ ਕਰੋ"</string>
-    <string name="permdesc_install_shortcut" msgid="8341295916286736996">"ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਉਪਭੋਗਤਾ ਦੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਹੋਮਸਕ੍ਰੀਨ ਸ਼ਾਰਟਕੱਟ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"ਸ਼ਾਰਟਕੱਟ ਅਣਇੰਸਟੌਲ ਕਰੋ"</string>
-    <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਉਪਭੋਗਤਾ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਹੋਮਸਕ੍ਰੀਨ ਸ਼ਾਰਟਕੱਟ ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"ਐਪ ਨੂੰ ਸਥਿਤੀ ਪੱਟੀ ਹੋਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"ਸਥਿਤੀ ਪੱਟੀ ਦਾ ਵਿਸਤਾਰ/ਨਸ਼ਟ ਕਰੋ"</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"ਐਪ ਨੂੰ ਸਥਿਤੀ ਪੱਟੀ ਦਾ ਵਿਸਤਾਰ ਕਰਨ ਜਾਂ ਨਸ਼ਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_install_shortcut" msgid="4279070216371564234">"ਸ਼ਾਰਟਕੱਟ ਸਥਾਪਤ ਕਰੋ"</string>
+    <string name="permdesc_install_shortcut" msgid="8341295916286736996">"ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਵਰਤੋਂਕਾਰ ਦੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਹੋਮਸਕ੍ਰੀਨ ਸ਼ਾਰਟਕੱਟ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"ਸ਼ਾਰਟਕੱਟ ਅਣਸਥਾਪਤ ਕਰੋ"</string>
+    <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਵਰਤੋਂਕਾਰ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਹੋਮਸਕ੍ਰੀਨ ਸ਼ਾਰਟਕੱਟ ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਰੀਰੂਟ ਕਰੋ"</string>
     <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"ਐਪ ਨੂੰ ਇੱਕ ਵੱਖ ਨੰਬਰ ਨਾਲ ਕਾਲ ਰੀਡਾਇਰੈਕਟ ਕਰਨ ਜਾਂ ਕਾਲ ਨੂੰ ਪੂਰਾ ਰੋਕਣ ਦੀ ਚੋਣ ਨਾਲ ਇੱਕ ਆਊਟਗੋਇੰਗ ਕਾਲ ਦੇ ਦੌਰਾਨ ਡਾਇਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਨੰਬਰ ਦੇਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_answerPhoneCalls" msgid="4077162841226223337">"ਫ਼ੋਨ ਕਾਲਾਂ ਦਾ ਜਵਾਬ ਦਿਓ"</string>
     <string name="permdesc_answerPhoneCalls" msgid="2901889867993572266">"ਐਪ ਨੂੰ ਆਉਣ ਵਾਲੀ ਫ਼ੋਨ ਕਾਲ ਦਾ ਜਵਾਬ ਦੇਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦੀ ਹੈ।"</string>
-    <string name="permlab_receiveSms" msgid="8673471768947895082">"ਟੈਕਸਟ ਸੁਨੇਹੇ (SMS) ਪ੍ਰਾਪਤ ਕਰੋ"</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"ਲਿਖਤ ਸੁਨੇਹੇ (SMS) ਪ੍ਰਾਪਤ ਕਰੋ"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"ਐਪ ਨੂੰ SMS ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਐਪ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਤੇ ਭੇਜੇ ਗਏ ਸੁਨੇਹਿਆਂ ਨੂੰ ਤੁਹਾਨੂੰ ਦਿਖਾਏ ਬਿਨਾਂ ਨਿਰੀਖਣ ਕਰ ਸਕਦੀ ਹੈ ਜਾਂ ਮਿਟਾ ਸਕਦੀ ਹੈ।"</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"ਟੈਕਸਟ ਸੁਨੇਹੇ (MMS) ਪੜ੍ਹੋ"</string>
     <string name="permdesc_receiveMms" msgid="533019437263212260">"ਐਪ ਨੂੰ MMS ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਐਪ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਤੇ ਭੇਜੇ ਗਏ ਸੁਨੇਹਿਆਂ ਨੂੰ ਤੁਹਾਨੂੰ ਦਿਖਾਏ ਬਿਨਾਂ ਨਿਰੀਖਣ ਕਰ ਸਕਦੀ ਹੈ ਜਾਂ ਮਿਟਾ ਸਕਦੀ ਹੈ।"</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ਸੈਲ ਪ੍ਰਸਾਰਨ ਸੁਨੇਹੇ ਪੜ੍ਹੋ"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਵੱਲੋਂ ਪ੍ਰਾਪਤ ਕੀਤੇ ਸੈੱਲ ਪ੍ਰਸਾਰਣ ਸੁਨੇਹੇ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸੈੱਲ ਪ੍ਰਸਾਰਣ ਚਿਤਾਵਨੀਆਂ ਤੁਹਾਨੂੰ ਸੰਕਟਕਾਲੀਨ ਸਥਿਤੀਆਂ ਦੀ ਚਿਤਾਵਨੀ ਦੇਣ ਲਈ ਕੁਝ ਨਿਰਧਾਰਿਤ ਟਿਕਾਣਿਆਂ ਤੇ ਪ੍ਰਦਾਨ ਕੀਤੀਆਂ ਜਾਂਦੀਆਂ ਹਨ। ਖਰਾਬ ਐਪਾਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੇ ਪ੍ਰਦਰਸ਼ਨ ਜਾਂ ਓਪਰੇਸ਼ਨ ਵਿੱਚ ਵਿਘਨ ਪਾ ਸਕਦੀਆਂ ਹਨ ਜਦੋਂ ਇੱਕ ਸੰਕਟਕਾਲੀਨ ਸੈੱਲ ਪ੍ਰਸਾਰਣ ਪ੍ਰਾਪਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਵੱਲੋਂ ਪ੍ਰਾਪਤ ਕੀਤੇ ਸੈੱਲ ਪ੍ਰਸਾਰਣ ਸੁਨੇਹੇ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸੈੱਲ ਪ੍ਰਸਾਰਣ ਚਿਤਾਵਨੀਆਂ ਤੁਹਾਨੂੰ ਸੰਕਟਕਾਲੀਨ ਸਥਿਤੀਆਂ ਦੀ ਚਿਤਾਵਨੀ ਦੇਣ ਲਈ ਕੁਝ ਨਿਰਧਾਰਤ ਟਿਕਾਣਿਆਂ ਤੇ ਪ੍ਰਦਾਨ ਕੀਤੀਆਂ ਜਾਂਦੀਆਂ ਹਨ। ਖਰਾਬ ਐਪਾਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੇ ਪ੍ਰਦਰਸ਼ਨ ਜਾਂ ਓਪਰੇਸ਼ਨ ਵਿੱਚ ਵਿਘਨ ਪਾ ਸਕਦੀਆਂ ਹਨ ਜਦੋਂ ਇੱਕ ਸੰਕਟਕਾਲੀਨ ਸੈੱਲ ਪ੍ਰਸਾਰਣ ਪ੍ਰਾਪਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।"</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ਸਬਸਕ੍ਰਾਈਬ ਕੀਤੇ ਫੀਡਸ ਪੜ੍ਹੋ"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ਐਪ ਨੂੰ ਵਰਤਮਾਨ ਵਿੱਚ ਸਿੰਕ ਕੀਤੇ ਫੀਡਸ ਬਾਰੇ ਵੇਰਵੇ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_sendSms" msgid="7544599214260982981">"SMS ਸੁਨੇਹੇ ਭੇਜਣ ਅਤੇ ਦੇਖਣ"</string>
-    <string name="permdesc_sendSms" msgid="7094729298204937667">"ਐਪ ਨੂੰ SMS ਸੁਨੇਹੇ ਭੇਜਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦੇ ਸਿੱਟੇ ਵਜੋਂ ਅਕਲਪਿਤ ਖ਼ਰਚੇ ਪੈ ਸਕਦੇ ਹਨ। ਖ਼ਰਾਬ ਐਪਸ ਤੁਹਾਡੀ ਪੁਸ਼ਟੀ ਤੋਂ ਬਿਨਾਂ ਸੁਨੇਹੇ ਭੇਜ ਕੇ ਤੁਹਾਨੂੰ ਖ਼ਰਚੇ ਪਾ ਸਕਦੇ ਹਨ।"</string>
-    <string name="permlab_readSms" msgid="8745086572213270480">"ਤੁਹਾਡੇ ਟੈਕਸਟ ਸੁਨੇਹੇ (SMS ਜਾਂ MMS) ਪੜ੍ਹੋ"</string>
+    <string name="permlab_sendSms" msgid="7544599214260982981">"SMS ਸੁਨੇਹੇ ਭੇਜੋ ਅਤੇ ਦੇਖੋ"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"ਐਪ ਨੂੰ SMS ਸੁਨੇਹੇ ਭੇਜਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦੇ ਸਿੱਟੇ ਵਜੋਂ ਅਕਲਪਿਤ ਖਰਚੇ ਪੈ ਸਕਦੇ ਹਨ। ਖਰਾਬ ਐਪਾਂ ਤੁਹਾਡੀ ਪੁਸ਼ਟੀ ਤੋਂ ਬਿਨਾਂ ਸੁਨੇਹੇ ਭੇਜ ਕੇ ਤੁਹਾਨੂੰ ਖਰਚੇ ਪਾ ਸਕਦੀਆਂ ਹਨ।"</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"ਤੁਹਾਡੇ ਲਿਖਤ ਸੁਨੇਹੇ (SMS ਜਾਂ MMS) ਪੜ੍ਹੋ"</string>
     <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ SMS (ਲਿਖਤ) ਸੁਨੇਹਿਆਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ।"</string>
     <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੀਵੀ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ SMS (ਲਿਖਤ) ਸੁਨੇਹਿਆਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ।"</string>
     <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ SMS (ਲਿਖਤ) ਸੁਨੇਹਿਆਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ।"</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"ਟੈਕਸਟ ਸੁਨੇਹੇ (WAP) ਪ੍ਰਾਪਤ ਕਰੋ"</string>
-    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"ਐਪ ਨੂੰ WAP ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਅਨੁਮਤੀ ਵਿੱਚ ਸ਼ਾਮਲ ਹੈ ਐਪ ਦੀ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਤੇ ਭੇਜੇ ਗਏ ਸੁਨੇਹਿਆਂ ਨੂੰ ਤੁਹਾਨੂੰ ਦਿਖਾਏ ਬਿਨਾਂ ਨਿਰੀਖਣ ਕਰਨ ਅਤੇ ਮਿਟਾਉਣ ਦੀ ਸਮਰੱਥਾ।"</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"ਐਪ ਨੂੰ WAP ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਇਜਾਜ਼ਤ ਵਿੱਚ ਸ਼ਾਮਲ ਹੈ ਐਪ ਦੀ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਤੇ ਭੇਜੇ ਗਏ ਸੁਨੇਹਿਆਂ ਨੂੰ ਤੁਹਾਨੂੰ ਦਿਖਾਏ ਬਿਨਾਂ ਨਿਰੀਖਣ ਕਰਨ ਅਤੇ ਮਿਟਾਉਣ ਦੀ ਸਮਰੱਥਾ।"</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"ਚੱਲ ਰਹੇ ਐਪਸ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"ਐਪ ਨੂੰ ਵਰਤਮਾਨ ਵਿੱਚ ਅਤੇ ਹੁਣੇ ਜਿਹੇ ਚੱਲ ਰਹੇ ਕੰਮਾਂ ਬਾਰੇ ਵਿਸਤ੍ਰਿਤ ਜਾਣਕਾਰੀ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ ਇਸ ਬਾਰੇ ਜਾਣਕਾਰੀ ਖੋਜਣ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ ਕਿ ਡੀਵਾਈਸ ਤੇ ਕਿਹੜੀਆਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵਰਤੀਆਂ ਜਾਂਦੀਆਂ ਹਨ।"</string>
-    <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"ਪ੍ਰੋਫ਼ਾਈਲ ਅਤੇ ਡੀਵਾਈਸ ਮਾਲਕਾਂ ਨੂੰ ਵਿਵਸਥਿਤ ਕਰੋ"</string>
-    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"ਪ੍ਰੋਫ਼ਾਈਲ ਦੇ ਮਾਲਕ ਅਤੇ ਡੀਵਾਈਸ ਦੇ ਮਾਲਕ ਨੂੰ ਸੈੱਟ ਕਰਨ ਲਈ ਐਪਾਂ ਨੂੰ ਅਨੁਮਤੀ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਡੀਵਾਈਸ ਮਾਲਕਾਂ ਨੂੰ ਵਿਵਸਥਿਤ ਕਰੋ"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"ਪ੍ਰੋਫਾਈਲ ਦੇ ਮਾਲਕ ਅਤੇ ਡੀਵਾਈਸ ਦੇ ਮਾਲਕ ਨੂੰ ਸੈੱਟ ਕਰਨ ਲਈ ਐਪਾਂ ਨੂੰ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"ਚੱਲ ਰਹੇ ਐਪਸ ਨੂੰ ਦੁਬਾਰਾ ਕ੍ਰਮ ਦਿਓ"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"ਐਪ ਨੂੰ ਕੰਮਾਂ ਨੂੰ ਅਗਲੇ ਭਾਗ ਅਤੇ ਪਿਛੋਕੜ ਵਿੱਚ ਮੂਵ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਐਪ ਤੁਹਾਡੇ ਇਨਪੁਟ ਤੋਂ ਬਿਨਾਂ ਇਹ ਕਰ ਸਕਦਾ ਹੈ।"</string>
-    <string name="permlab_enableCarMode" msgid="5684504058192921098">"ਕਾਰ ਮੋਡ ਸਮਰੱਥ ਬਣਾਓ"</string>
-    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"ਐਪ ਨੂੰ ਕਾਰ ਮੋਡ ਸਮਰੱਥ ਬਣਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_enableCarMode" msgid="5684504058192921098">"ਕਾਰ ਮੋਡ ਚਾਲੂ ਕਰੋ"</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"ਐਪ ਨੂੰ ਕਾਰ ਮੋਡ ਚਾਲੂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"ਹੋਰ ਐਪਸ ਬੰਦ ਕਰੋ"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"ਐਪ ਨੂੰ ਹੋਰਾਂ ਐਪਸ ਦੀਆਂ ਪਿਛੋਕੜ ਪ੍ਰਕਿਰਿਆਵਾਂ ਖ਼ਤਮ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਨਾਲ ਹੋਰ ਚੱਲ ਰਹੇ ਐਪਸ ਰੁਕ ਸਕਦੇ ਹਨ।"</string>
     <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"ਇਹ ਐਪ ਹੋਰ ਐਪਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਵਿਖਾਈ ਦੇ ਸਕਦੀ ਹੈ"</string>
     <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"ਇਹ ਐਪ ਹੋਰ ਐਪਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਜਾਂ ਸਕ੍ਰੀਨ ਦੇ ਹੋਰ ਭਾਗਾਂ \'ਤੇ ਵਿਖਾਈ ਦੇ ਸਕਦੀ ਹੈ। ਇਹ ਸਧਾਰਨ ਐਪ ਵਰਤੋਂ ਵਿੱਚ ਵਿਘਨ ਪਾ ਸਕਦੀ ਹੈ ਅਤੇ ਹੋਰ ਐਪਾਂ ਦੇ ਵਿਖਾਈ ਦੇਣ ਦੇ ਤਰੀਕੇ ਨੂੰ ਬਦਲ ਸਕਦੀ ਹੈ।"</string>
     <string name="permlab_runInBackground" msgid="7365290743781858803">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚਲਾਓ"</string>
     <string name="permdesc_runInBackground" msgid="7370142232209999824">"ਇਹ ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਸਕਦੀ ਹੈ। ਇਸ ਨਾਲ ਬੈਟਰੀ ਵਧੇਰੇ ਤੇਜ਼ੀ ਨਾਲ ਖਤਮ ਹੋ ਸਕਦੀ ਹੈ।"</string>
-    <string name="permlab_useDataInBackground" msgid="8694951340794341809">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਡੈਟੇ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
+    <string name="permlab_useDataInBackground" msgid="8694951340794341809">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ  ਡਾਟੇ  ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"ਇਹ ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਡਾਟੇ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੀ ਹੈ। ਇਸ ਨਾਲ ਡਾਟਾ ਵਰਤੋਂ ਵਧ ਸਕਦੀ ਹੈ।"</string>
-    <string name="permlab_persistentActivity" msgid="8841113627955563938">"ਐਪ ਨੂੰ ਹਮੇਸ਼ਾਂ ਰਨ ਕਰੋ"</string>
-    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"ਐਪ ਨੂੰ ਮੈਮਰੀ ਵਿੱਚ ਖੁਦ ਦੇ ਭਾਗਾਂ ਨੂੰ ਸਥਾਈ ਬਣਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਟੈਬਲੇਟ ਨੂੰ ਹੌਲੀ ਕਰਦੇ ਹੋਏ ਹੋਰਾਂ ਐਪਸ ਤੇ ਉਪਲਬਧ ਮੈਮਰੀ ਨੂੰ ਸੀਮਿਤ ਕਰ ਸਕਦਾ ਹੈ।"</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"ਐਪ ਨੂੰ ਹਮੇਸ਼ਾਂ ਚਲਾਏ ਰੱਖੋ"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"ਐਪ ਨੂੰ ਮੈਮਰੀ ਵਿੱਚ ਖੁਦ ਦੇ ਭਾਗਾਂ ਨੂੰ ਸਥਾਈ ਬਣਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਟੈਬਲੈੱਟ ਨੂੰ ਹੌਲੀ ਕਰਦੇ ਹੋਏ ਹੋਰਾਂ ਐਪਾਂ ਲਈ ਉਪਲਬਧ ਮੈਮਰੀ ਨੂੰ ਸੀਮਿਤ ਕਰ ਸਕਦਾ ਹੈ।"</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"ਐਪ ਨੂੰ ਮੈਮਰੀ ਵਿੱਚ ਖੁਦ ਦੇ ਭਾਗਾਂ ਨੂੰ ਸਥਾਈ ਬਣਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ TV ਨੂੰ ਹੌਲੀ ਕਰਦੇ ਹੋਏ ਹੋਰਾਂ ਐਪਸ ਤੇ ਉਪਲਬਧ ਮੈਮਰੀ ਨੂੰ ਸੀਮਿਤ ਕਰ ਸਕਦਾ ਹੈ।"</string>
-    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ਐਪ ਨੂੰ ਮੈਮਰੀ ਵਿੱਚ ਖੁਦ ਦੇ ਭਾਗਾਂ ਨੂੰ ਸਥਾਈ ਬਣਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਫੋਨ ਨੂੰ ਹੌਲੀ ਕਰਦੇ ਹੋਏ ਹੋਰਾਂ ਐਪਸ ਤੇ ਉਪਲਬਧ ਮੈਮਰੀ ਨੂੰ ਸੀਮਿਤ ਕਰ ਸਕਦਾ ਹੈ।"</string>
-    <string name="permlab_getPackageSize" msgid="7472921768357981986">"ਐਪ ਸਟੋਰੇਜ ਸਪੇਸ ਮਾਪੋ"</string>
-    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"ਐਪ ਨੂੰ ਇਸਦਾ ਕੋਡ, ਡੈਟਾ ਅਤੇ ਕੈਚ ਆਕਾਰ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ਐਪ ਨੂੰ ਮੈਮਰੀ ਵਿੱਚ ਖੁਦ ਦੇ ਭਾਗਾਂ ਨੂੰ ਸਥਾਈ ਬਣਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਫ਼ੋਨ ਨੂੰ ਹੌਲੀ ਕਰਦੇ ਹੋਏ ਹੋਰਾਂ ਐਪਾਂ ਤੇ ਉਪਲਬਧ ਮੈਮਰੀ ਨੂੰ ਸੀਮਿਤ ਕਰ ਸਕਦਾ ਹੈ।"</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"ਐਪ ਸਟੋਰੇਜ ਜਗ੍ਹਾ ਮਾਪੋ"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"ਐਪ ਨੂੰ ਇਸਦਾ ਕੋਡ, ਡਾਟਾ ਅਤੇ ਕੈਸ਼ੇ ਆਕਾਰ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_writeSettings" msgid="2226195290955224730">"ਸਿਸਟਮ ਸੈਟਿੰਗਾਂ  ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
-    <string name="permdesc_writeSettings" msgid="7775723441558907181">"ਐਪ ਨੂੰ ਸਿਸਟਮ ਦੇ ਸੈਟਿੰਗਾਂ ਡੈਟਾ ਨੂੰ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਖ਼ਰਾਬ ਐਪਸ ਤੁਹਾਡੇ ਸਿਸਟਮ ਦੀ ਕੌਂਫਿਗਰੇਸ਼ਨ ਨੂੰ ਕਰਪਟ ਕਰ ਸਕਦੇ ਹਨ।"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"ਐਪ ਨੂੰ ਸਿਸਟਮ ਦੇ ਸੈਟਿੰਗਾਂ ਡਾਟਾ ਨੂੰ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਖਰਾਬ ਐਪਾਂ ਤੁਹਾਡੇ ਸਿਸਟਮ ਦੀ ਸੰਰੂਪਣ ਨੂੰ ਕਰਪਟ ਕਰ ਸਕਦੇ ਹਨ।"</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"ਚਾਲੂ ਹੋਣ ਤੇ ਚਲਾਓ"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"ਐਪ ਨੂੰ ਸਿਸਟਮ ਦੇ ਬੂਟਿੰਗ ਖ਼ਤਮ ਕਰਨ ਦੇ ਤੁਰੰਤ ਬਾਅਦ ਖੁਦ ਚਾਲੂ ਹੋਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਚਾਲੂ ਹੋਣ ਵਿੱਚ ਥੋੜ੍ਹਾ ਵੱਧ ਸਮਾਂ ਲੱਗ ਸਕਦਾ ਹੈ ਅਤੇ ਇਹ ਐਪ ਨੂੰ ਹਮੇਸ਼ਾਂ ਚਲਾ ਕੇ ਸਮੁੱਚੀ ਟੈਬਲੇਟ ਨੂੰ ਹੌਲਾ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"ਐਪ ਨੂੰ ਸਿਸਟਮ ਦੇ ਬੂਟਿੰਗ ਖ਼ਤਮ ਕਰਨ ਦੇ ਤੁਰੰਤ ਬਾਅਦ ਖੁਦ ਚਾਲੂ ਹੋਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਨਾਲ TV ਨੂੰ ਚਾਲੂ ਹੋਣ ਵਿੱਚ ਥੋੜ੍ਹਾ ਵੱਧ ਸਮਾਂ ਲੱਗ ਸਕਦਾ ਹੈ ਅਤੇ ਇਹ ਐਪ ਨੂੰ ਹਮੇਸ਼ਾਂ ਚਲਾ ਕੇ ਸਮੁੱਚੀ ਟੈਬਲੇਟ ਨੂੰ ਹੌਲਾ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"ਐਪ ਨੂੰ ਸਿਸਟਮ ਦੇ ਬੂਟਿੰਗ ਖ਼ਤਮ ਕਰਨ ਦੇ ਤੁਰੰਤ ਬਾਅਦ ਖੁਦ ਚਾਲੂ ਹੋਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਨਾਲ ਫੋਨ ਨੂੰ ਚਾਲੂ ਹੋਣ ਵਿੱਚ ਥੋੜ੍ਹਾ ਵੱਧ ਸਮਾਂ ਲੱਗ ਸਕਦਾ ਹੈ ਅਤੇ ਇਹ ਐਪ ਨੂੰ ਹਮੇਸ਼ਾਂ ਚਲਾ ਕੇ ਸਮੁੱਚੇ ਫੋਨ ਨੂੰ ਹੌਲਾ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"ਐਪ ਨੂੰ ਸਿਸਟਮ ਦੇ ਬੂਟਿੰਗ ਖਤਮ ਕਰਨ ਦੇ ਤੁਰੰਤ ਬਾਅਦ ਖੁਦ ਚਾਲੂ ਹੋਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਚਾਲੂ ਹੋਣ ਵਿੱਚ ਥੋੜ੍ਹਾ ਵੱਧ ਸਮਾਂ ਲੱਗ ਸਕਦਾ ਹੈ ਅਤੇ ਇਹ ਐਪ ਨੂੰ ਹਮੇਸ਼ਾਂ ਚਲਾ ਕੇ ਸਮੁੱਚੇ ਟੈਬਲੈੱਟ ਨੂੰ ਹੌਲਾ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"ਐਪ ਨੂੰ ਸਿਸਟਮ ਦੇ ਬੂਟਿੰਗ ਖਤਮ ਕਰਨ ਦੇ ਤੁਰੰਤ ਬਾਅਦ ਖੁਦ ਚਾਲੂ ਹੋਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਨਾਲ TV ਨੂੰ ਚਾਲੂ ਹੋਣ ਵਿੱਚ ਥੋੜ੍ਹਾ ਵੱਧ ਸਮਾਂ ਲੱਗ ਸਕਦਾ ਹੈ ਅਤੇ ਇਹ ਐਪ ਨੂੰ ਹਮੇਸ਼ਾਂ ਚਲਾ ਕੇ ਸਮੁੱਚੇ ਟੈਬਲੈੱਟ ਨੂੰ ਹੌਲਾ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"ਐਪ ਨੂੰ ਸਿਸਟਮ ਦੇ ਬੂਟਿੰਗ ਖਤਮ ਕਰਨ ਦੇ ਤੁਰੰਤ ਬਾਅਦ ਖੁਦ ਚਾਲੂ ਹੋਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਚਾਲੂ ਹੋਣ ਵਿੱਚ ਥੋੜ੍ਹਾ ਵੱਧ ਸਮਾਂ ਲੱਗ ਸਕਦਾ ਹੈ ਅਤੇ ਇਹ ਐਪ ਨੂੰ ਹਮੇਸ਼ਾਂ ਚਲਾ ਕੇ ਸਮੁੱਚੇ ਫ਼ੋਨ ਨੂੰ ਹੌਲਾ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"ਸਟਿਕੀ ਪ੍ਰਸਾਰਨ ਭੇਜੋ"</string>
-    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"ਐਪ ਨੂੰ ਸਟਿਕੀ ਪ੍ਰਸਾਰਨ ਭੇਜਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜੋ ਪ੍ਰਸਾਰਨ ਦੇ ਖ਼ਤਮ ਹੋਣ ਤੋਂ ਬਾਅਦ ਰਹਿੰਦੇ ਹਨ। ਵਾਧੂ ਵਰਤੋਂ ਟੈਬਲੇਟ ਨੂੰ ਹੌਲੀ ਜਾਂ ਬਹੁਤ ਜ਼ਿਆਦਾ ਮੈਮਰੀ ਵਰਤ ਕੇ ਇਸਨੂੰ ਅਸਥਿਰ ਬਣਾ ਸਕਦੀ ਹੈ।"</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"ਐਪ ਨੂੰ ਸਟਿਕੀ ਪ੍ਰਸਾਰਨ ਭੇਜਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜੋ ਪ੍ਰਸਾਰਨ ਦੇ ਖਤਮ ਹੋਣ ਤੋਂ ਬਾਅਦ ਰਹਿੰਦੇ ਹਨ। ਵਾਧੂ ਵਰਤੋਂ ਟੈਬਲੈੱਟ ਨੂੰ ਹੌਲੀ ਜਾਂ ਬਹੁਤ ਜ਼ਿਆਦਾ ਮੈਮਰੀ ਵਰਤ ਕੇ ਇਸਨੂੰ ਅਸਥਿਰ ਬਣਾ ਸਕਦੀ ਹੈ।"</string>
     <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"ਐਪ ਨੂੰ ਸਟਿਕੀ ਪ੍ਰਸਾਰਨ ਭੇਜਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜੋ ਪ੍ਰਸਾਰਨ ਦੇ ਖ਼ਤਮ ਹੋਣ ਤੋਂ ਬਾਅਦ ਰਹਿੰਦੇ ਹਨ। ਵਾਧੂ ਵਰਤੋਂ TV ਨੂੰ ਹੌਲੀ ਜਾਂ ਬਹੁਤ ਜ਼ਿਆਦਾ ਮੈਮਰੀ ਵਰਤ ਕੇ ਇਸਨੂੰ ਅਸਥਿਰ ਬਣਾ ਸਕਦੀ ਹੈ।"</string>
-    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"ਐਪ ਨੂੰ ਸਟਿਕੀ ਪ੍ਰਸਾਰਨ ਭੇਜਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜੋ ਪ੍ਰਸਾਰਨ ਦੇ ਖ਼ਤਮ ਹੋਣ ਤੋਂ ਬਾਅਦ ਰਹਿੰਦੇ ਹਨ। ਵਾਧੂ ਵਰਤੋਂ ਫੋਨ ਨੂੰ ਹੌਲੀ ਜਾਂ ਬਹੁਤ ਜ਼ਿਆਦਾ ਮੈਮਰੀ ਵਰਤ ਕੇ ਇਸਨੂੰ ਅਸਥਿਰ ਬਣਾ ਸਕਦੀ ਹੈ।"</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"ਐਪ ਨੂੰ ਸਟਿਕੀ ਪ੍ਰਸਾਰਨ ਭੇਜਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜੋ ਪ੍ਰਸਾਰਨ ਦੇ ਖਤਮ ਹੋਣ ਤੋਂ ਬਾਅਦ ਰਹਿੰਦੇ ਹਨ। ਵਾਧੂ ਵਰਤੋਂ ਫ਼ੋਨ ਨੂੰ ਹੌਲੀ ਜਾਂ ਬਹੁਤ ਜ਼ਿਆਦਾ ਮੈਮਰੀ ਵਰਤ ਕੇ ਇਸਨੂੰ ਅਸਥਿਰ ਬਣਾ ਸਕਦੀ ਹੈ।"</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"ਆਪਣੇ ਸੰਪਰਕ ਪੜ੍ਹੋ"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਟੈਬਲੇਟ ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡੈਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖ਼ਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ। ਇਹ ਅਨੁਮਤੀ ਐਪਸ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡੈਟਾ ਸੁਰੱਖਿਅਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ ਅਤੇ ਖ਼ਰਾਬ ਐਪਸ ਤੁਹਾਡੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਸੰਪਰਕ ਡੈਟਾ ਸ਼ੇਅਰ ਕਰ ਸਕਦੇ ਹਨ।"</string>
-    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ TV ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡੈਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖ਼ਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ। ਇਹ ਅਨੁਮਤੀ ਐਪਸ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡੈਟਾ ਸੁਰੱਖਿਅਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ ਅਤੇ ਖ਼ਰਾਬ ਐਪਸ ਤੁਹਾਡੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਸੰਪਰਕ ਡੈਟਾ ਸ਼ੇਅਰ ਕਰ ਸਕਦੇ ਹਨ।"</string>
-    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫੋਨ ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡੈਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖ਼ਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ। ਇਹ ਅਨੁਮਤੀ ਐਪਸ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡੈਟਾ ਸੁਰੱਖਿਅਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ ਅਤੇ ਖ਼ਰਾਬ ਐਪਸ ਤੁਹਾਡੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਸੰਪਰਕ ਡੈਟਾ ਸ਼ੇਅਰ ਕਰ ਸਕਦੇ ਹਨ।"</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ ਹੈ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡਾਟਾ ਰੱਖਿਅਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ ਅਤੇ ਖਰਾਬ ਐਪਾਂ ਤੁਹਾਡੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਸੰਪਰਕ ਡਾਟਾ ਸਾਂਝਾ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
+    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਟੀਵੀ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ ਹੈ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡਾਟਾ ਰੱਖਿਅਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ ਅਤੇ ਖਰਾਬ ਐਪਾਂ ਤੁਹਾਡੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਸੰਪਰਕ ਡਾਟਾ ਸਾਂਝਾ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ ਹੈ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡਾਟਾ ਰੱਖਿਅਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ ਅਤੇ ਖਰਾਬ ਐਪਾਂ ਤੁਹਾਡੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਸੰਪਰਕ ਡਾਟਾ ਸਾਂਝਾ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"ਆਪਣੇ ਸੰਪਰਕ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਟੈਬਲੇਟ ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡੈਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖ਼ਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ। ਇਹ ਅਨੁਮਤੀ ਐਪਸ ਨੂੰ ਸੰਪਰਕ ਡੈਟਾ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
-    <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ TV ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡੈਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖ਼ਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ। ਇਹ ਅਨੁਮਤੀ ਐਪਸ ਨੂੰ ਸੰਪਰਕ ਡੈਟਾ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
-    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫੋਨ ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡੈਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖ਼ਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ। ਇਹ ਅਨੁਮਤੀ ਐਪਸ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡੈਟਾ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਟੈਬਲੈੱਟ ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖ਼ਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਸੰਪਰਕ ਡਾਟਾ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
+    <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਟੀਵੀ ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖ਼ਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਸੰਪਰਕ ਡਾਟਾ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖ਼ਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡਾਟਾ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"ਕਾਲ ਲੌਗ ਪੜ੍ਹੋ"</string>
     <string name="permdesc_readCallLog" msgid="3204122446463552146">"ਇਹ ਐਪ ਤੁਹਾਡਾ ਕਾਲ ਇਤਿਹਾਸ ਪੜ੍ਹ ਸਕਦੀ ਹੈ।"</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"ਕਾਲ ਲੌਗ ਲਿਖੋ"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਟੈਬਲੇਟ ਦਾ ਕਾਲ ਲੌਗ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡੈਟਾ ਸਮੇਤ। ਖ਼ਰਾਬ ਐਪਸ ਇਸਦੀ ਵਰਤੋਂ ਤੁਹਾਡੇ ਕਾਲ ਲੌਗ ਨੂੰ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਕਰ ਸਕਦੇ ਹਨ।"</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ TV ਦਾ ਕਾਲ ਲੌਗ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡੈਟਾ ਸਮੇਤ। ਖ਼ਰਾਬ ਐਪਸ ਇਸਦੀ ਵਰਤੋਂ ਤੁਹਾਡੇ ਕਾਲ ਲੌਗ ਨੂੰ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਕਰ ਸਕਦੇ ਹਨ।"</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫੋਨ ਦਾ ਕਾਲ ਲੌਗ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡੈਟਾ ਸਮੇਤ। ਖ਼ਰਾਬ ਐਪਸ ਇਸਦੀ ਵਰਤੋਂ ਤੁਹਾਡੇ ਕਾਲ ਲੌਗ ਨੂੰ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਕਰ ਸਕਦੇ ਹਨ।"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ ਦਾ ਕਾਲ ਲੌਗ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡਾਟਾ ਸਮੇਤ। ਖਰਾਬ ਐਪਾਂ ਇਸਦੀ ਵਰਤੋਂ ਤੁਹਾਡੇ ਕਾਲ ਲੌਗ ਨੂੰ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਟੀਵੀ ਦਾ ਕਾਲ ਲੌਗ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡਾਟਾ ਸਮੇਤ। ਖਰਾਬ ਐਪਾਂ ਇਸਦੀ ਵਰਤੋਂ ਤੁਹਾਡੇ ਕਾਲ ਲੌਗ ਨੂੰ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦਾ ਕਾਲ ਲੌਗ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡਾਟਾ ਸਮੇਤ। ਖਰਾਬ ਐਪਾਂ ਇਸਦੀ ਵਰਤੋਂ ਤੁਹਾਡੇ ਕਾਲ ਲੌਗ ਨੂੰ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
     <string name="permlab_bodySensors" msgid="4683341291818520277">"ਸਰੀਰ ਸੰਵੇਦਕਾਂ \'ਤੇ ਪਹੁੰਚ ਕਰੋ (ਜਿਵੇਂ ਦਿਲ ਦੀ ਧੜਕਣ ਦੇ ਨਿਰੀਖਕ)"</string>
-    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ਐਪ ਨੂੰ ਉਹਨਾਂ ਸੰਵੇਦਕਾਂ ਦੇ ਡੈਟਾ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ ਜੋ ਤੁਹਾਡੀ ਸਰੀਰਕ ਸਥਿਤੀ ਦਾ ਨਿਰੀਖਣ ਕਰ ਸਕਦੇ ਹਨ, ਜਿਵੇਂ ਤੁਹਾਡੇ ਦਿਲ ਦੀ ਧੜਕਣ।"</string>
+    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ਐਪ ਨੂੰ ਉਹਨਾਂ ਸੰਵੇਦਕਾਂ ਦੇ ਡਾਟਾ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ ਜੋ ਤੁਹਾਡੀ ਸਰੀਰਕ ਸਥਿਤੀ ਦਾ ਨਿਰੀਖਣ ਕਰ ਸਕਦੇ ਹਨ, ਜਿਵੇਂ ਤੁਹਾਡੇ ਦਿਲ ਦੀ ਧੜਕਣ।"</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"ਕੈਲੰਡਰ ਵਰਤਾਰਿਆਂ ਅਤੇ ਵੇਰਵਿਆਂ ਨੂੰ ਪੜ੍ਹੋ"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ ਉੱਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ ਕੈਲੰਡਰ ਵਰਤਾਰਿਆਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਡੈਟੇ ਨੂੰ ਸਾਂਝਾ ਜਾਂ ਰੱਖਿਅਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
-    <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੀਵੀ ਉੱਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ ਕੈਲੰਡਰ ਵਰਤਾਰਿਆਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਡੈਟੇ ਨੂੰ ਸਾਂਝਾ ਜਾਂ ਰੱਖਿਅਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
-    <string name="permdesc_readCalendar" product="default" msgid="4373978642145196715">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਫ਼ੋਨ ਉੱਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ ਕੈਲੰਡਰ ਵਰਤਾਰਿਆਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਡੈਟੇ ਨੂੰ ਸਾਂਝਾ ਜਾਂ ਰੱਖਿਅਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
-    <string name="permlab_writeCalendar" msgid="8438874755193825647">"ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਜੋੜੋ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰੋ ਅਤੇ ਮਾਲਕ ਦੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਮਹਿਮਾਨਾਂ ਨੂੰ ਈਮੇਲ ਭੇਜੋ"</string>
-    <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਕੈਲੰਡਰ ਵਰਤਾਰਿਆਂ ਨੂੰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੀ ਹੈ, ਹਟਾ ਸਕਦੀ ਹੈ, ਜਾਂ ਬਦਲ ਸਕਦੀ ਹੈ। ਇਹ ਐਪ ਉਹਨਾਂ ਸੁਨੇਹਿਆਂ ਨੂੰ ਭੇਜ ਸਕਦੀ ਹੈ ਜੋ ਕਿ ਕੈਲੰਡਰ ਮਾਲਕਾਂ ਤੋਂ ਆਉਂਦੇ ਜਾਪ ਸਕਦੇ ਹਨ, ਜਾਂ ਉਹਨਾਂ ਦੇ ਮਾਲਕਾਂ ਨੂੰ ਸੂਚਿਤ ਕੀਤੇ ਬਿਨਾਂ ਵਰਤਾਰਿਆਂ ਨੂੰ ਬਦਲ ਸਕਦੀ ਹੈ।"</string>
-    <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੀਵੀ \'ਤੇ ਕੈਲੰਡਰ ਵਰਤਾਰਿਆਂ ਨੂੰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੀ ਹੈ, ਹਟਾ ਸਕਦੀ ਹੈ, ਜਾਂ ਬਦਲ ਸਕਦੀ ਹੈ। ਇਹ ਐਪ ਉਹਨਾਂ ਸੁਨੇਹਿਆਂ ਨੂੰ ਭੇਜ ਸਕਦੀ ਹੈ ਜੋ ਕੈਲੰਡਰ ਮਾਲਕਾਂ ਤੋਂ ਆਉਂਦੇ ਜਾਪ ਸਕਦੇ ਹਨ, ਜਾਂ ਉਹਨਾਂ ਦੇ ਮਾਲਕਾਂ ਨੂੰ ਸੂਚਿਤ ਕੀਤੇ ਬਿਨਾਂ ਵਰਤਾਰਿਆਂ ਨੂੰ ਬਦਲ ਸਕਦੀ ਹੈ।"</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਕੈਲੰਡਰ ਵਰਤਾਰਿਆਂ ਨੂੰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੀ ਹੈ, ਹਟਾ ਸਕਦੀ ਹੈ, ਜਾਂ ਬਦਲ ਸਕਦੀ ਹੈ। ਇਹ ਐਪ ਉਹਨਾਂ ਸੁਨੇਹਿਆਂ ਨੂੰ ਭੇਜ ਸਕਦੀ ਹੈ ਜੋ ਕੈਲੰਡਰ ਮਾਲਕਾਂ ਤੋਂ ਆਉਂਦੇ ਜਾਪ ਸਕਦੇ ਹਨ, ਜਾਂ ਉਹਨਾਂ ਦੇ ਮਾਲਕਾਂ ਨੂੰ ਸੂਚਿਤ ਕੀਤੇ ਬਿਨਾਂ ਵਰਤਾਰਿਆਂ ਨੂੰ ਬਦਲ ਸਕਦੀ ਹੈ।"</string>
-    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ਵਾਧੂ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਪ੍ਰਦਾਤਾ ਕਮਾਂਡਾਂ ਤੱਕ ਪਹੁੰਚ"</string>
-    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ਐਪ ਨੂੰ ਵਾਧੂ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਪ੍ਰਦਾਤਾ ਕਮਾਂਡਾਂ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ GPS ਜਾਂ ਹੋਰ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਸਰੋਤਾਂ ਦੇ ਓਪਰੇਸ਼ਨ ਵਿੱਚ ਵਿਘਨ ਪਾਉਣ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ।"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਡਾਟੇ ਨੂੰ ਸਾਂਝਾ ਜਾਂ ਰੱਖਿਅਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
+    <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੀਵੀ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਡਾਟੇ ਨੂੰ ਸਾਂਝਾ ਜਾਂ ਰੱਖਿਅਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
+    <string name="permdesc_readCalendar" product="default" msgid="4373978642145196715">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਡਾਟੇ ਨੂੰ ਸਾਂਝਾ ਜਾਂ ਰੱਖਿਅਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"ਕੈਲੰਡਰ ਇਵੈਂਟ ਸ਼ਾਮਲ ਕਰੋ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰੋ ਅਤੇ ਮਾਲਕ ਦੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਮਹਿਮਾਨਾਂ ਨੂੰ ਈਮੇਲ ਭੇਜੋ"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਨੂੰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੀ ਹੈ, ਹਟਾ ਸਕਦੀ ਹੈ, ਜਾਂ ਬਦਲ ਸਕਦੀ ਹੈ। ਇਹ ਐਪ ਉਹਨਾਂ ਸੁਨੇਹਿਆਂ ਨੂੰ ਭੇਜ ਸਕਦੀ ਹੈ ਜੋ ਕਿ ਕੈਲੰਡਰ ਮਾਲਕਾਂ ਤੋਂ ਆਉਂਦੇ ਜਾਪ ਸਕਦੇ ਹਨ, ਜਾਂ ਉਹਨਾਂ ਦੇ ਮਾਲਕਾਂ ਨੂੰ ਸੂਚਿਤ ਕੀਤੇ ਬਿਨਾਂ ਇਵੈਂਟਾਂ ਨੂੰ ਬਦਲ ਸਕਦੀ ਹੈ।"</string>
+    <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੀਵੀ \'ਤੇ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਨੂੰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੀ ਹੈ, ਹਟਾ ਸਕਦੀ ਹੈ, ਜਾਂ ਬਦਲ ਸਕਦੀ ਹੈ। ਇਹ ਐਪ ਉਹਨਾਂ ਸੁਨੇਹਿਆਂ ਨੂੰ ਭੇਜ ਸਕਦੀ ਹੈ ਜੋ ਕੈਲੰਡਰ ਮਾਲਕਾਂ ਤੋਂ ਆਉਂਦੇ ਜਾਪ ਸਕਦੇ ਹਨ, ਜਾਂ ਉਹਨਾਂ ਦੇ ਮਾਲਕਾਂ ਨੂੰ ਸੂਚਿਤ ਕੀਤੇ ਬਿਨਾਂ ਇਵੈਂਟਾਂ ਨੂੰ ਬਦਲ ਸਕਦੀ ਹੈ।"</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਨੂੰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੀ ਹੈ, ਹਟਾ ਸਕਦੀ ਹੈ, ਜਾਂ ਬਦਲ ਸਕਦੀ ਹੈ। ਇਹ ਐਪ ਉਹਨਾਂ ਸੁਨੇਹਿਆਂ ਨੂੰ ਭੇਜ ਸਕਦੀ ਹੈ ਜੋ ਕੈਲੰਡਰ ਮਾਲਕਾਂ ਤੋਂ ਆਉਂਦੇ ਜਾਪ ਸਕਦੇ ਹਨ, ਜਾਂ ਉਹਨਾਂ ਦੇ ਮਾਲਕਾਂ ਨੂੰ ਸੂਚਿਤ ਕੀਤੇ ਬਿਨਾਂ ਇਵੈਂਟਾਂ ਨੂੰ ਬਦਲ ਸਕਦੀ ਹੈ।"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ਵਾਧੂ ਟਿਕਾਣਾ ਪ੍ਰਦਾਤਾ ਕਮਾਂਡਾਂ ਤੱਕ ਪਹੁੰਚ"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ਐਪ ਨੂੰ ਵਾਧੂ ਟਿਕਾਣਾ ਪ੍ਰਦਾਤਾ ਕਮਾਂਡਾਂ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ GPS ਜਾਂ ਹੋਰ ਟਿਕਾਣਾ ਸਰੋਤਾਂ ਦੇ ਓਪਰੇਸ਼ਨ ਵਿੱਚ ਵਿਘਨ ਪਾਉਣ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ।"</string>
     <string name="permlab_accessFineLocation" msgid="251034415460950944">"ਸਟੀਕ ਟਿਕਾਣੇ \'ਤੇ ਪਹੁੰਚ ਕਰੋ (GPS ਅਤੇ ਨੈੱਟਵਰਕ-ਆਧਾਰਿਤ)"</string>
-    <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"ਇਹ ਐਪ GPS ਜਾਂ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ Wi-Fi ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ। ਐਪ ਦੁਆਰਾ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ। ਇਸ ਨਾਲ ਬੈਟਰੀ ਦੀ ਖਪਤ ਵਧ ਸਕਦੀ ਹੈ।"</string>
+    <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"ਇਹ ਐਪ GPS ਜਾਂ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ। ਐਪ ਦੁਆਰਾ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ। ਇਸ ਨਾਲ ਬੈਟਰੀ ਦੀ ਖਪਤ ਵਧ ਸਕਦੀ ਹੈ।"</string>
     <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ਅੰਦਾਜ਼ਨ ਟਿਕਾਣੇ \'ਤੇ ਪਹੁੰਚ ਕਰੋ (ਨੈੱਟਵਰਕ-ਆਧਾਰਿਤ)"</string>
-    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ Wi-Fi ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ। ਐਪ ਦੁਆਰਾ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
-    <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ Wi-Fi ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ। ਐਪ ਦੁਆਰਾ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਟੀਵੀ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
-    <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ Wi-Fi ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ। ਐਪ ਦੁਆਰਾ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
-    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ਆਪਣੀਆਂ ਔਡੀਓ ਸੈਟਿੰਗਾਂ ਬਦਲੋ"</string>
-    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"ਔਪ ਨੂੰ ਗਲੋਬਲ ਔਡੀਓ ਸੈਟਿੰਗਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ ਜਿਵੇਂ ਵੌਲਿਊਮ ਅਤੇ ਆਊਟਪੁਟ ਲਈ ਕਿਹੜਾ ਸਪੀਕਰ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ।"</string>
-    <string name="permlab_recordAudio" msgid="3876049771427466323">"ਔਡੀਓ ਰਿਕਾਰਡ ਕਰਨ"</string>
-    <string name="permdesc_recordAudio" msgid="4245930455135321433">"ਇਹ ਐਪ ਕਿਸੇ ਵੀ ਸਮੇਂ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਔਡੀਓ ਫ਼ਾਈਲ ਰਿਕਾਰਡ ਕਰ ਸਕਦੀ ਹੈ।"</string>
+    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ। ਐਪ ਦੁਆਰਾ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
+    <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ। ਐਪ ਵੱਲੋਂ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਟੀਵੀ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
+    <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ। ਐਪ ਵੱਲੋਂ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
+    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ਆਪਣੀਆਂ ਆਡੀਓ ਸੈਟਿੰਗਾਂ ਬਦਲੋ"</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"ਐਪ ਨੂੰ ਗਲੋਬਲ ਆਡੀਓ ਸੈਟਿੰਗਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ ਜਿਵੇਂ ਅਵਾਜ਼ ਅਤੇ ਆਊਟਪੁਟ ਲਈ ਕਿਹੜਾ ਸਪੀਕਰ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ।"</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">" ਆਡੀਓ  ਰਿਕਾਰਡ ਕਰਨ"</string>
+    <string name="permdesc_recordAudio" msgid="4245930455135321433">"ਇਹ ਐਪ ਕਿਸੇ ਵੀ ਸਮੇਂ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਦੀ ਵਰਤੋਂ ਕਰਕੇ  ਆਡੀਓ  ਫ਼ਾਈਲ ਰਿਕਾਰਡ ਕਰ ਸਕਦੀ ਹੈ।"</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"SIM ਨੂੰ ਕਮਾਂਡਾਂ ਭੇਜੋ"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"ਐਪ ਨੂੰ SIM ਨੂੰ ਕਮਾਂਡਾਂ ਭੇਜਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਬਹੁਤ ਘਾਤਕ ਹੈ।"</string>
     <string name="permlab_camera" msgid="3616391919559751192">"ਤਸਵੀਰਾਂ ਅਤੇ ਵੀਡੀਓ ਬਣਾਓ"</string>
     <string name="permdesc_camera" msgid="5392231870049240670">"ਇਹ ਐਪ ਕਿਸੇ ਵੀ ਸਮੇਂ ਕੈਮਰੇ ਨੂੰ ਵਰਤ ਕੇ ਤਸਵੀਰਾਂ ਖਿੱਚ ਸਕਦੀ ਹੈ ਅਤੇ ਵੀਡੀਓ ਫ਼ਾਈਲਾਂ ਰਿਕਾਰਡ ਕਰ ਸਕਦੀ ਹੈ।"</string>
     <string name="permlab_vibrate" msgid="7696427026057705834">"ਵਾਈਬ੍ਰੇਸ਼ਨ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"ਐਪ ਨੂੰ ਵਾਈਬ੍ਰੇਟਰ ਤੇ ਨਿਯੰਤਰਣ ਪਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_callPhone" msgid="3925836347681847954">"ਫੋਨ ਨੰਬਰਾਂ ਤੇ ਸਿੱਧੇ ਕਾਲ ਕਰੋ"</string>
-    <string name="permdesc_callPhone" msgid="3740797576113760827">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਫੋਨ ਨੰਬਰਾਂ ਤੇ ਕਾਲ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦੇ ਸਿੱਟੇ ਵਜੋਂ ਅਕਲਪਿਤ ਖ਼ਰਚੇ ਜਾਂ ਕਾਲਾਂ ਹੋ ਸਕਦੀਆਂ ਹਨ। ਧਿਆਨ ਦਿਓ ਕਿ ਇਹ ਐਪ ਨੂੰ ਐਮਰਜੈਂਸੀ ਨੰਬਰਾਂ ਤੇ ਕਾਲ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਦਿੰਦਾ। ਖ਼ਰਾਬ ਐਪਸ ਤੁਹਾਡੀ ਪੁਸ਼ਟੀ ਤੋਂ ਬਿਨਾਂ ਕਾਲਾਂ ਕਰਕੇ ਤੁਹਾਨੂੰ ਖ਼ਰਚੇ ਪਾ ਸਕਦੇ ਹਨ।"</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"ਫ਼ੋਨ ਨੰਬਰਾਂ ਤੇ ਸਿੱਧੇ ਕਾਲ ਕਰੋ"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਦਖਲ ਤੋਂ ਬਿਨਾਂ ਫ਼ੋਨ ਨੰਬਰਾਂ ਤੇ ਕਾਲ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦੇ ਸਿੱਟੇ ਵਜੋਂ ਅਕਲਪਿਤ ਖਰਚੇ ਜਾਂ ਕਾਲਾਂ ਹੋ ਸਕਦੀਆਂ ਹਨ। ਧਿਆਨ ਦਿਓ ਕਿ ਇਹ ਐਪ ਨੂੰ ਸੰਕਟਕਾਲੀਨ ਨੰਬਰਾਂ ਤੇ ਕਾਲ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਦਿੰਦਾ। ਖਰਾਬ ਐਪਾਂ ਤੁਹਾਡੀ ਪੁਸ਼ਟੀ ਤੋਂ ਬਿਨਾਂ ਕਾਲਾਂ ਕਰਕੇ ਤੁਹਾਨੂੰ ਖਰਚੇ ਪਾ ਸਕਦੀਆਂ ਹਨ।"</string>
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS ਕਾਲ ਸੇਵਾ ਤੱਕ ਪਹੁੰਚ"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਕਾਲਾਂ ਕਰਨ ਲਈ IMS ਸੇਵਾ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
-    <string name="permlab_readPhoneState" msgid="9178228524507610486">"ਫੋਨ ਸਥਿਤੀ ਅਤੇ ਪਛਾਣ ਪੜ੍ਹੋ"</string>
-    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ਐਪ ਨੂੰ ਡੀਵਾਈਸ ਦੀਆਂ ਫ਼ੋਨ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਅਨੁਮਤੀ ਐਪ ਨੂੰ ਫ਼ੋਨ ਨੰਬਰ ਅਤੇ ਡੀਵਾਈਸ ਆਈ.ਡੀ. ਨਿਰਧਾਰਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ, ਇੱਕ ਕਾਲ ਕਿਰਿਆਸ਼ੀਲ ਹੈ ਜਾਂ ਨਹੀਂ ਅਤੇ ਰਿਮੋਟ ਨੰਬਰ ਇੱਕ ਕਾਲ ਨਾਲ ਕਨੈਕਟ ਹੈ ਜਾਂ ਨਹੀਂ।"</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"ਫ਼ੋਨ ਸਥਿਤੀ ਅਤੇ ਪਛਾਣ ਪੜ੍ਹੋ"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ਐਪ ਨੂੰ ਡੀਵਾਈਸ ਦੀਆਂ ਫ਼ੋਨ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਇਜਾਜ਼ਤ ਐਪ ਨੂੰ ਫ਼ੋਨ ਨੰਬਰ ਅਤੇ ਡੀਵਾਈਸ ਆਈ.ਡੀ. ਨਿਰਧਾਰਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ, ਇੱਕ ਕਾਲ ਕਿਰਿਆਸ਼ੀਲ ਹੈ ਜਾਂ ਨਹੀਂ ਅਤੇ ਰਿਮੋਟ ਨੰਬਰ ਇੱਕ ਕਾਲ ਨਾਲ ਕਨੈਕਟ ਹੈ ਜਾਂ ਨਹੀਂ।"</string>
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"ਸਿਸਟਮ ਰਾਹੀਂ ਕਾਲਾਂ ਰੂਟ ਕਰੋ"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"ਕਾਲ ਕਰਨ ਦੇ ਅਨੁਭਵ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ ਐਪ ਨੂੰ ਇਸਦੀਆਂ ਕਾਲਾਂ ਨੂੰ ਸਿਸਟਮ ਰਾਹੀਂ ਰੂਟ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦੀ ਹੈ।"</string>
     <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ਫ਼ੋਨ ਨੰਬਰ ਪੜ੍ਹੋ"</string>
     <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"ਐਪ ਨੂੰ ਡੀਵਾਈਸ ਦੇ ਫ਼ੋਨ ਨੰਬਰਾਂ \'ਤੇ ਪਹੁੰਚ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦੀ ਹੈ।"</string>
-    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ਟੈਬਲੇਟ ਨੂੰ ਸਲੀਪਿੰਗ ਤੋਂ ਰੋਕੋ"</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ਟੈਬਲੈੱਟ ਨੂੰ ਸਲੀਪ ਤੇ ਜਾਣ ਤੋਂ ਰੋਕੋ"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"TV ਨੂੰ ਸਲੀਪਿੰਗ ਤੋਂ ਰੋਕੋ"</string>
-    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ਫੋਨ ਨੂੰ ਸਲੀਪਿੰਗ ਤੋਂ ਰੋਕੋ"</string>
-    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ਐਪ ਨੂੰ ਟੈਬਲੇਟ ਨੂੰ ਸਲੀਪ ਤੇ ਜਾਣ ਤੋਂ ਰੋਕਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ਫ਼ੋਨ ਨੂੰ ਸਲੀਪਿੰਗ ਤੋਂ ਰੋਕੋ"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ਐਪ ਨੂੰ ਟੈਬਲੈੱਟ ਨੂੰ ਸਲੀਪ ਤੇ ਜਾਣ ਤੋਂ ਰੋਕਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"ਐਪ ਨੂੰ TV ਨੂੰ ਸਲੀਪ ਤੇ ਜਾਣ ਤੋਂ ਰੋਕਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"ਐਪ ਨੂੰ ਫੋਨ ਨੂੰ ਸਲੀਪ ਤੇ ਜਾਣ ਤੋਂ ਰੋਕਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"ਐਪ ਨੂੰ ਫ਼ੋਨ ਨੂੰ ਸਲੀਪ ਤੇ ਜਾਣ ਤੋਂ ਰੋਕਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_transmitIr" msgid="7545858504238530105">"ਇੰਫ੍ਰਾਰੈਡ ਟ੍ਰਾਂਸਮਿਟ ਕਰੋ"</string>
-    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"ਐਪ ਨੂੰ ਟੈਬਲੇਟ ਦਾ ਇੰਫਰਾਰੈਡ ਟ੍ਰਾਂਸਮੀਟਰ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"ਐਪ ਨੂੰ ਟੈਬਲੈੱਟ ਦਾ ਇੰਫਰਾਰੈਡ ਟ੍ਰਾਂਸਮੀਟਰ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"ਐਪ ਨੂੰ TV ਦਾ ਇੰਫਰਾਰੈਡ ਟ੍ਰਾਂਸਮੀਟਰ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"ਐਪ ਨੂੰ ਫੋਨ ਦਾ ਇੰਫਰਾਰੈਡ ਟ੍ਰਾਂਸਮੀਟਰ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"ਐਪ ਨੂੰ ਫ਼ੋਨ ਦਾ ਇੰਫਰਾਰੈਡ ਟ੍ਰਾਂਸਮੀਟਰ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_setWallpaper" msgid="6627192333373465143">"ਵਾਲਪੇਪਰ ਸੈੱਟ ਕਰੋ"</string>
     <string name="permdesc_setWallpaper" msgid="7373447920977624745">"ਐਪ ਨੂੰ ਸਿਸਟਮ ਵਾਲਪੇਪਰ ਸੈਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"ਆਪਣਾ ਵਾਲਪੇਪਰ ਆਕਾਰ ਵਿਵਸਥਿਤ ਕਰੋ"</string>
     <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"ਐਪ ਨੂੰ ਸਿਸਟਮ ਵਾਲਪੇਪਰ ਆਕਾਰ ਸੰਕੇਤ ਸੈਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"ਸਮਾਂ ਜ਼ੋਨ ਸੈੱਟ ਕਰੋ"</string>
-    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"ਐਪ ਨੂੰ ਟੈਬਲੇਟ ਦਾ ਸਮਾਂ ਜ਼ੋਨ ਬਦਲਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"ਐਪ ਨੂੰ ਟੈਬਲੈੱਟ ਦਾ ਸਮਾਂ ਜ਼ੋਨ ਬਦਲਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"ਐਪ ਨੂੰ TV ਦਾ ਸਮਾਂ ਜ਼ੋਨ ਬਦਲਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"ਐਪ ਨੂੰ ਫੋਨ ਦਾ ਸਮਾਂ ਜ਼ੋਨ ਬਦਲਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"ਐਪ ਨੂੰ ਫ਼ੋਨ ਦਾ ਸਮਾਂ ਜ਼ੋਨ ਬਦਲਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"ਡੀਵਾਈਸ ਤੇ ਖਾਤੇ ਲੱਭੋ"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"ਐਪ ਨੂੰ ਟੈਬਲੇਟ ਵੱਲੋਂ ਗਿਆਤ ਖਾਤਿਆਂ ਦੀ ਸੂਚੀ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਵਿੱਚ ਤੁਹਾਡੇ ਵੱਲੋਂ ਇੰਸਟੌਲ ਕੀਤੀਆਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਬਣਾਏ ਗਏ ਕੋਈ ਵੀ ਖਾਤੇ ਸ਼ਾਮਲ ਹੋ ਸਕਦੇ ਹਨ।"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"ਐਪ ਨੂੰ ਟੈਬਲੈੱਟ ਵੱਲੋਂ ਗਿਆਤ ਖਾਤਿਆਂ ਦੀ ਸੂਚੀ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਵਿੱਚ ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਦੁਆਰਾ ਬਣਾਏ ਗਏ ਕੋਈ ਵੀ ਖਾਤੇ ਸ਼ਾਮਲ ਹੋ ਸਕਦੇ ਹਨ।"</string>
     <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"ਐਪ ਨੂੰ TV ਵੱਲੋਂ ਗਿਆਤ ਖਾਤਿਆਂ ਦੀ ਸੂਚੀ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਵਿੱਚ ਤੁਹਾਡੇ ਵੱਲੋਂ ਇੰਸਟੌਲ ਕੀਤੀਆਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਬਣਾਏ ਗਏ ਕੋਈ ਵੀ ਖਾਤੇ ਸ਼ਾਮਲ ਹੋ ਸਕਦੇ ਹਨ।"</string>
-    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"ਐਪ ਨੂੰ ਫੋਨ ਵੱਲੋਂ ਗਿਆਤ ਖਾਤਿਆਂ ਦੀ ਸੂਚੀ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਵਿੱਚ ਤੁਹਾਡੇ ਵੱਲੋਂ ਇੰਸਟੌਲ ਕੀਤੀਆਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਬਣਾਏ ਗਏ ਕੋਈ ਵੀ ਖਾਤੇ ਸ਼ਾਮਲ ਹੋ ਸਕਦੇ ਹਨ।"</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"ਐਪ ਨੂੰ ਫ਼ੋਨ ਵੱਲੋਂ ਗਿਆਤ ਖਾਤਿਆਂ ਦੀ ਸੂਚੀ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਵਿੱਚ ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਬਣਾਏ ਗਏ ਕੋਈ ਵੀ ਖਾਤੇ ਸ਼ਾਮਲ ਹੋ ਸਕਦੇ ਹਨ।"</string>
     <string name="permlab_accessNetworkState" msgid="4951027964348974773">"ਨੈੱਟਵਰਕ ਕਨੈਕਸ਼ਨ ਦੇਖੋ"</string>
     <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"ਐਪ ਨੂੰ ਨੈੱਟਵਰਕ ਕਨੈਕਸ਼ਨਾਂ ਬਾਰੇ ਜਾਣਕਾਰੀ ਦੇਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ ਜਿਵੇਂ ਕਿਹੜੇ ਨੈੱਟਵਰਕ ਮੌਜੂਦ ਹਨ ਅਤੇ ਕਨੈਕਟ ਕੀਤੇ ਹੋਏ ਹਨ।"</string>
     <string name="permlab_createNetworkSockets" msgid="7934516631384168107">"ਪੂਰੀ ਨੈੱਟਵਰਕ ਪਹੁੰਚ ਪਾਓ"</string>
-    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"ਐਪ ਨੂੰ ਨੈੱਟਵਰਕ ਸੌਕੇਟ ਬਣਾਉਣ ਅਤੇ ਕਸਟਮ ਨੈੱਟਵਰਕ ਪ੍ਰੋਟੋਕੋਲ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਬ੍ਰਾਊਜ਼ਰ ਅਤੇ ਹੋਰ ਐਪਲੀਕੇਸ਼ਨਾਂ ਇੰਟਰਨੈਟ ਨੂੰ ਡੈਟਾ ਭੇਜਣ ਲਈ ਸਾਧਨ ਮੁਹੱਈਆ ਕਰਦਾ ਹੈ, ਇਸਲਈ ਇੰਟਰਨੈਟ ਡੈਟਾ ਭੇਜਣ ਲਈ ਇਹ ਅਨੁਮਤੀ ਲੁੜੀਂਦੀ ਨਹੀਂ ਹੈ।"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"ਐਪ ਨੂੰ ਨੈੱਟਵਰਕ ਸਾਕੇਟ ਬਣਾਉਣ ਅਤੇ ਕਸਟਮ ਨੈੱਟਵਰਕ ਪ੍ਰੋਟੋਕੋਲ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਬ੍ਰਾਊਜ਼ਰ ਅਤੇ ਹੋਰ ਐਪਲੀਕੇਸ਼ਨਾਂ ਇੰਟਰਨੈੱਟ ਨੂੰ ਡਾਟਾ ਭੇਜਣ ਲਈ ਸਾਧਨ ਮੁਹੱਈਆ ਕਰਦੀਆਂ ਹਨ, ਇਸ ਲਈ ਇੰਟਰਨੈੱਟ ਡਾਟਾ ਭੇਜਣ ਲਈ ਇਹ ਅਨੁਮਤੀ ਲੋੜੀਂਦੀ ਨਹੀਂ ਹੈ।"</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"ਨੈੱਟਵਰਕ ਕਨੈਕਟੀਵਿਟੀ ਬਦਲੋ"</string>
     <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"ਐਪ ਨੂੰ ਨੈੱਟਵਰਕ ਕਨੈਕਟੀਵਿਟੀ ਦੀ ਸਥਿਤੀ ਬਦਲਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"ਟੀਥਰ ਕੀਤੀ ਕਨੈਕਟੀਵਿਟੀ ਬਦਲੋ"</string>
     <string name="permdesc_changeTetherState" msgid="1524441344412319780">"ਐਪ ਨੂੰ ਟੀਥਰ ਕੀਤੀ ਨੈੱਟਵਰਕ ਕਨੈਕਟੀਵਿਟੀ ਦੀ ਸਥਿਤੀ ਬਦਲਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_accessWifiState" msgid="5202012949247040011">"Wi-Fi ਕਨੈਕਸ਼ਨ ਦੇਖੋ"</string>
-    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"ਐਪ ਨੂੰ Wi-Fi ਨੈਟਵਰਕਿੰਗ ਬਾਰੇ ਜਾਣਕਾਰੀ ਦੇਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜਿਵੇਂ Wi-Fi ਸਮਰਥਿਤ ਹੈ ਜਾਂ ਨਹੀਂ ਅਤੇ ਕਨੈਕਟ ਕੀਤੀਆਂ Wi-Fi ਡਿਵਾਈਸਾਂ ਦਾ ਨਾਮ।"</string>
-    <string name="permlab_changeWifiState" msgid="6550641188749128035">"Wi-Fi ਤੋਂ ਕਨੈਕਟ ਅਤੇ ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"ਵਾਈ-ਫਾਈ ਕਨੈਕਸ਼ਨ ਦੇਖੋ"</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"ਐਪ ਨੂੰ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਿੰਗ ਬਾਰੇ ਜਾਣਕਾਰੀ ਦੇਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜਿਵੇਂ ਵਾਈ-ਫਾਈ ਸਮਰਥਿਤ ਹੈ ਜਾਂ ਨਹੀਂ ਅਤੇ ਕਨੈਕਟ ਕੀਤੇ ਵਾਈ-ਫਾਈ ਡੀਵਾਈਸਾਂ ਦਾ ਨਾਮ।"</string>
+    <string name="permlab_changeWifiState" msgid="6550641188749128035">"ਵਾਈ-ਫਾਈ ਤੋਂ ਕਨੈਕਟ ਅਤੇ ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
     <string name="permdesc_changeWifiState" msgid="7137950297386127533">"ਐਪ ਨੂੰ ਵਾਈ-ਫਾਈ ਪਹੁੰਚ ਬਿੰਦੂਆਂ ਤੇ ਕਨੈਕਟ ਅਤੇ ਇਹਨਾਂ ਤੋਂ ਡਿਸਕਨੈਕਟ ਕਰਨ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈਟਵਰਕਾਂ ਲਈ ਡੀਵਾਈਸ ਸੰਰੂਪਣ ਵਿੱਚ ਬਦਲਾਵ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi ਮਲਟੀਕਾਸਟ ਰਿਸੈਪਸ਼ਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"ਐਪ ਨੂੰ ਮਲਟੀਕਾਸਟ ਪਤੇ ਵਰਤਦੇ ਹੋਏ ਇੱਕ Wi-Fi ਨੈੱਟਵਰਕ ਤੇ ਸਾਰੀਆਂ ਡਿਵਾਈਸਾਂ ਤੇ ਭੇਜੇ ਗਏ ਪੈਕੇਟ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਕੇਵਲ ਤੁਹਾਡੀ ਟੈਬਲੇਟ ਨਹੀਂ। ਇਹ ਗ਼ੈਰ-ਮਲਟੀਕਾਸਟ ਮੋਡ ਦੇ ਮੁਕਾਬਲੇ ਵੱਧ ਪਾਵਰ ਵਰਤਦਾ ਹੈ।"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"ਐਪ ਨੂੰ ਮਲਟੀਕਾਸਟ ਪਤੇ ਵਰਤਦੇ ਹੋਏ ਇੱਕ Wi-Fi ਨੈੱਟਵਰਕ ਤੇ ਸਾਰੀਆਂ ਡਿਵਾਈਸਾਂ ਤੇ ਭੇਜੇ ਗਏ ਪੈਕੇਟ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਕੇਵਲ ਤੁਹਾਡਾ TV ਨਹੀਂ। ਇਹ ਗ਼ੈਰ-ਮਲਟੀਕਾਸਟ ਮੋਡ ਦੇ ਮੁਕਾਬਲੇ ਵੱਧ ਪਾਵਰ ਵਰਤਦਾ ਹੈ।"</string>
-    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"ਐਪ ਨੂੰ ਮਲਟੀਕਾਸਟ ਪਤੇ, ਵਰਤਦੇ ਹੋਏ ਇੱਕ Wi-Fi ਨੈੱਟਵਰਕ ਤੇ ਸਾਰੀਆਂ ਡਿਵਾਈਸਾਂ ਤੇ ਭੇਜੇ ਗਏ ਪੈਕੇਟ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਕੇਵਲ ਤੁਹਾਡਾ ਫੋਨ ਨਹੀਂ। ਇਹ ਗ਼ੈਰ-ਮਲਟੀਕਾਸਟ ਮੋਡ ਦੇ ਮੁਕਾਬਲੇ ਵੱਧ ਪਾਵਰ ਵਰਤਦਾ ਹੈ।"</string>
-    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"Bluetooth ਸੈਟਿੰਗਾਂ ਤੱਕ ਪਹੁੰਚ"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"ਐਪ ਨੂੰ ਸਥਾਨਕ Bluetooth ਟੈਬਲੇਟ ਨੂੰ ਕੌਂਫਿਗਰ ਕਰਨ ਅਤੇ ਰਿਮੋਟ ਡਿਵਾਈਸਾਂ ਨੂੰ ਖੋਜਣ ਅਤੇ ਉਹਨਾਂ ਨਾਲ ਪੇਅਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"ਐਪ ਨੂੰ ਸਥਾਨਕ Bluetooth TV ਨੂੰ ਕੌਂਫਿਗਰ ਕਰਨ ਅਤੇ ਰਿਮੋਟ ਡਿਵਾਈਸਾਂ ਨੂੰ ਖੋਜਣ ਅਤੇ ਉਹਨਾਂ ਨਾਲ ਪੇਅਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"ਐਪ ਨੂੰ ਸਥਾਨਕ Bluetooth ਫੋਨ ਨੂੰ ਕੌਂਫਿਗਰ ਕਰਨ ਅਤੇ ਰਿਮੋਟ ਡਿਵਾਈਸਾਂ ਨੂੰ ਖੋਜਣ ਅਤੇ ਉਹਨਾਂ ਨਾਲ ਪੇਅਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"ਵਾਈ-ਫਾਈ ਮਲਟੀਕਾਸਟ ਰਿਸੈਪਸ਼ਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"ਐਪ ਨੂੰ ਮਲਟੀਕਾਸਟ ਪਤੇ ਵਰਤਦੇ ਹੋਏ ਇੱਕ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਤੇ ਸਾਰੀਆਂ ਡੀਵਾਈਸਾਂ ਤੇ ਭੇਜੇ ਗਏ ਪੈਕੇਟ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਕੇਵਲ ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਨਹੀਂ। ਇਹ ਗੈਰ-ਮਲਟੀਕਾਸਟ ਮੋਡ ਦੇ ਮੁਕਾਬਲੇ ਵੱਧ ਪਾਵਰ ਵਰਤਦਾ ਹੈ।"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"ਐਪ ਨੂੰ ਮਲਟੀਕਾਸਟ ਪਤੇ ਵਰਤਦੇ ਹੋਏ ਇੱਕ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਤੇ ਸਾਰੇ ਡੀਵਾਈਸਾਂ ਤੇ ਭੇਜੇ ਗਏ ਪੈਕੇਟ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਸਿਰਫ਼ ਤੁਹਾਡਾ ਟੀਵੀ ਨਹੀਂ। ਇਹ ਗ਼ੈਰ-ਮਲਟੀਕਾਸਟ ਮੋਡ ਦੇ ਮੁਕਾਬਲੇ ਵੱਧ ਪਾਵਰ ਵਰਤਦਾ ਹੈ।"</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"ਐਪ ਨੂੰ ਮਲਟੀਕਾਸਟ ਪਤੇ, ਵਰਤਦੇ ਹੋਏ ਇੱਕ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਤੇ ਸਾਰੇ ਡੀਵਾਈਸਾਂ ਤੇ ਭੇਜੇ ਗਏ ਪੈਕੇਟ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਸਿਰਫ਼ ਤੁਹਾਡਾ ਫ਼ੋਨ ਨਹੀਂ। ਇਹ ਗੈਰ-ਮਲਟੀਕਾਸਟ ਮੋਡ ਦੇ ਮੁਕਾਬਲੇ ਵੱਧ ਪਾਵਰ ਵਰਤਦਾ ਹੈ।"</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"ਬਲੂਟੁੱਥ ਸੈਟਿੰਗਾਂ ਤੱਕ ਪਹੁੰਚ"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"ਐਪ ਨੂੰ ਸਥਾਨਕ ਬਲੂਟੁੱਥ ਟੈਬਲੈੱਟ ਸੰਰੂਪਣ ਕਰਨ ਅਤੇ ਰਿਮੋਟ ਡੀਵਾਈਸਾਂ ਨੂੰ ਖੋਜਣ ਅਤੇ ਉਹਨਾਂ ਨਾਲ ਜੋੜਾਬੱਧ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"ਐਪ ਨੂੰ ਸਥਾਨਕ Bluetooth ਟੀਵੀ ਦੀ ਰੂਪ-ਰੇਖਾ ਬਦਲਣ ਅਤੇ ਰਿਮੋਟ ਡਿਵਾਈਸਾਂ ਨੂੰ ਖੋਜਣ ਅਤੇ ਉਹਨਾਂ ਨਾਲ ਪੇਅਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"ਐਪ ਨੂੰ ਸਥਾਨਕ ਬਲੂਟੁੱਥ ਫ਼ੋਨ ਦੀ ਰੂਪ-ਰੇਖਾ ਬਦਲਣ ਅਤੇ ਰਿਮੋਟ ਡਿਵਾਈਸਾਂ ਨੂੰ ਖੋਜਣ ਅਤੇ ਉਹਨਾਂ ਨਾਲ ਪੇਅਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_accessWimaxState" msgid="4195907010610205703">"WiMAX ਤੋਂ ਕਨੈਕਟ ਅਤੇ ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
     <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"ਐਪ ਨੂੰ ਇਹ ਨਿਰਧਾਰਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ ਕਿ WiMAX ਸਮਰਥਿਤ ਹੈ ਜਾਂ ਨਹੀਂ ਅਤੇ ਕਿਸੇ ਵੀ  WiMAX ਨੈਟਵਰਕਾਂ ਬਾਰੇ ਜਾਣਕਾਰੀ ਜੋ ਕਨੈਕਟ ਕੀਤੇ ਹੋਏ ਹਨ।"</string>
     <string name="permlab_changeWimaxState" msgid="340465839241528618">"WiMAX ਸਥਿਤੀ ਬਦਲੋ"</string>
-    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"ਐਪ ਨੂੰ ਟੈਬਲੇਟ ਨੂੰ ਕਨੈਕਟ ਕਰਨ ਅਤੇ WiMAX ਨੈਟਵਰਕਾਂ ਤੋਂ ਟੈਬਲੇਟ ਨੂੰ ਡਿਸਕਨੈਕਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"ਐਪ ਨੂੰ ਟੈਬਲੈੱਟ ਨੂੰ ਕਨੈਕਟ ਕਰਨ ਅਤੇ WiMAX ਨੈਟਵਰਕਾਂ ਤੋਂ ਟੈਬਲੈੱਟ ਨੂੰ ਡਿਸਕਨੈਕਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"ਐਪ ਨੂੰ TV ਨੂੰ ਕਨੈਕਟ ਕਰਨ ਅਤੇ WiMAX ਨੈਟਵਰਕਾਂ ਤੋਂ TV ਨੂੰ ਡਿਸਕਨੈਕਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"ਐਪ ਨੂੰ ਫੋਨ ਨੂੰ ਕਨੈਕਟ ਕਰਨ ਅਤੇ WiMAX ਨੈਟਵਰਕਾਂ ਤੋਂ ਫੋਨ ਨੂੰ ਡਿਸਕਨੈਕਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"ਐਪ ਨੂੰ ਫ਼ੋਨ ਨੂੰ ਕਨੈਕਟ ਕਰਨ ਅਤੇ WiMAX ਨੈੱਟਵਰਕਾਂ ਤੋਂ ਫ਼ੋਨ ਨੂੰ ਡਿਸਕਨੈਕਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_bluetooth" msgid="6127769336339276828">"Bluetooth ਡਿਵਾਈਸਾਂ ਨਾਲ ਪੇਅਰ ਕਰੋ"</string>
-    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"ਐਪ ਨੂੰ ਟੈਬਲੇਟ ਤੇ Bluetooth ਦੀ ਕੌਂਫਿਗਰੇਸ਼ਨ ਦੇਖਣ, ਪੇਅਰ ਕੀਤੀਆਂ ਡਿਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਸ਼ਨ ਬਣਾਉਣ ਅਤੇ ਸਵੀਕਾਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"ਐਪ ਨੂੰ TV ਤੇ Bluetooth ਦੀ ਕੌਂਫਿਗਰੇਸ਼ਨ ਦੇਖਣ, ਪੇਅਰ ਕੀਤੀਆਂ ਡਿਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਸ਼ਨ ਬਣਾਉਣ ਅਤੇ ਸਵੀਕਾਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"ਐਪ ਨੂੰ ਫੋਨ ਤੇ Bluetooth ਦੀ ਕੌਂਫਿਗਰੇਸ਼ਨ ਦੇਖਣ, ਪੇਅਰ ਕੀਤੀਆਂ ਡਿਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਸ਼ਨ ਬਣਾਉਣ ਅਤੇ ਸਵੀਕਾਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_nfc" msgid="4423351274757876953">"ਨੀਅਰ ਫੀਲਡ ਕਮਿਊਨੀਕੇਸ਼ਨ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ"</string>
-    <string name="permdesc_nfc" msgid="7120611819401789907">"ਐਪ ਨੂੰ Near Field Communication (NFC) ਟੈਗਸ, ਕਾਰਡਾਂ ਅਤੇ ਰੀਡਰਾਂ ਨਾਲ ਸੰਚਾਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ਆਪਣਾ ਸਕ੍ਰੀਨ ਲੌਕ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
-    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"ਐਪ ਨੂੰ ਕੀਲੌਕ ਅਤੇ ਕਿਸੇ ਵੀ ਸੰਬੰਧਿਤ ਪਾਸਵਰਡ ਸੁਰੱਖਿਆ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਉਦਾਹਰਨ ਲਈ, ਫੋਨ ਇੱਕ ਇਨਕਮਿੰਗ ਫੋਨ ਕਾਲ ਪ੍ਰਾਪਤ ਕਰਨ ਵੇਲੇ ਅਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ, ਫਿਰ ਜਦੋਂ ਕਾਲ ਖ਼ਤਮ ਹੁੰਦੀ ਹੈ ਤਾਂ ਕੀਲੌਕ ਨੂੰ ਮੁੜ-ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ।"</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"ਐਪ ਨੂੰ ਟੈਬਲੈੱਟ ਤੇ ਬਲੂਟੁੱਥ ਦਾ ਸੰਰੂਪਣ ਦੇਖਣ, ਜੋੜਾਬੱਧ ਕੀਤੇ ਡੀਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਸ਼ਨ ਬਣਾਉਣ ਅਤੇ ਸਵੀਕਾਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"ਐਪ ਨੂੰ ਟੀਵੀ ਤੇ Bluetooth ਦੀ ਸੰਰੂਪਣ ਦੇਖਣ, ਜੋੜਾਬੱਧ ਕੀਤੇ ਡਿਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਸ਼ਨ ਬਣਾਉਣ ਅਤੇ ਸਵੀਕਾਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"ਐਪ ਨੂੰ ਬਲੂਟੁੱਥ ਤੇ ਬਲੂਟੁੱਥ ਦਾ ਸੰਰੂਪਣ ਦੇਖਣ, ਜੋੜਾਬੱਧ ਕੀਤੇ ਡੀਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਸ਼ਨ ਬਣਾਉਣ ਅਤੇ ਸਵੀਕਾਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"ਨਜ਼ਦੀਕੀ ਖੇਤਰ ਸੰਚਾਰ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਖੇਤਰ ਸੰਚਾਰ (NFC) ਟੈਗਾਂ, ਕਾਰਡਾਂ ਅਤੇ ਰੀਡਰਾਂ ਨਾਲ ਸੰਚਾਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ਆਪਣਾ ਸਕ੍ਰੀਨ  ਲਾਕ  ਅਸਮਰੱਥ ਬਣਾਓ"</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"ਐਪ ਨੂੰ ਕੀਲਾਕ ਅਤੇ ਕਿਸੇ ਵੀ ਸੰਬੰਧਿਤ ਪਾਸਵਰਡ ਸੁਰੱਖਿਆ ਨੂੰ ਬੰਦ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਉਦਾਹਰਨ ਲਈ, ਫ਼ੋਨ ਇੱਕ ਇਨਕਮਿੰਗ ਫ਼ੋਨ ਕਾਲ ਪ੍ਰਾਪਤ ਕਰਨ ਵੇਲੇ ਬੰਦ ਕਰਦਾ ਹੈ, ਫਿਰ ਜਦੋਂ ਕਾਲ ਖਤਮ ਹੁੰਦੀ ਹੈ ਤਾਂ ਕੀਲਾਕ ਨੂੰ ਮੁੜ-ਚਾਲੂ ਕਰਦਾ ਹੈ।"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਹਾਰਡਵੇਅਰ ਵਿਵਸਥਿਤ ਕਰੋ"</string>
-    <string name="permdesc_manageFingerprint" msgid="178208705828055464">"ਐਪ ਨੂੰ ਵਰਤੋਂ ਲਈ ਫਿੰਗਰਪ੍ਰਿੰਟ ਜੋੜਨ ਅਤੇ ਮਿਟਾਣ ਦੀਆਂ ਵਿਧੀਆਂ ਦੀ ਬੇਨਤੀ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_manageFingerprint" msgid="178208705828055464">"ਐਪ ਨੂੰ ਵਰਤੋਂ ਲਈ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸ਼ਾਮਲ ਕਰਨ ਅਤੇ ਮਿਟਾਉਣ ਦੀਆਂ ਵਿਧੀਆਂ ਦੀ ਬੇਨਤੀ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_useFingerprint" msgid="3150478619915124905">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਹਾਰਡਵੇਅਰ ਵਰਤੋ"</string>
     <string name="permdesc_useFingerprint" msgid="9165097460730684114">"ਐਪ ਨੂੰ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਫਿੰਗਰਪ੍ਰਿੰਟ ਹਾਰਡਵੇਅਰ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ"</string>
     <string name="fingerprint_acquired_partial" msgid="735082772341716043">"ਅਧੂਰਾ ਫਿੰਗਰਪ੍ਰਿਟ ਮਿਲਿਆ। ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
@@ -483,7 +482,7 @@
     <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"ਉਂਗਲ ਕਾਫ਼ੀ ਹੌਲੀ ਮੂਵ ਹੋਈ। ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਹਾਰਡਵੇਅਰ ਉਪਲਬਧ ਨਹੀਂ."</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>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"ਫਿੰਗਰ"</string>
@@ -493,14 +492,14 @@
     <string name="fingerprint_name_template" msgid="5870957565512716938">"ਉਂਗਲ <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
-    <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਆਈਕਨ"</string>
+    <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਪ੍ਰਤੀਕ"</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ਸਿੰਕ ਸੈਟਿੰਗਾਂ ਪੜ੍ਹੋ"</string>
-    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ਐਪ ਨੂੰ ਇੱਕ ਖਾਤੇ ਲਈ ਸਿੰਕ ਸੈਟਿੰਗਾਂ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਉਦਾਹਰਨ ਲਈ, ਇਹ ਨਿਰਧਾਰਿਤ ਕਰ ਸਕਦਾ ਹੈ ਕਿ People ਐਪ ਨੂੰ ਇੱਕ ਖਾਤੇ ਨਾਲ ਸਿੰਕ ਕੀਤਾ ਗਿਆ ਹੈ ਜਾਂ ਨਹੀਂ।"</string>
-    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ਸਿੰਕ ਟੌਗਲ ਚਾਲੂ ਅਤੇ ਬੰਦ"</string>
-    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ਐਪ ਨੂੰ ਇੱਕ ਖਾਤੇ ਲਈ ਸਿੰਕ ਸੈਟਿੰਗਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਉਦਾਹਰਨ ਲਈ, ਇਸਦੀ ਵਰਤੋਂ  ਇੱਕ ਖਾਤੇ ਨਾਲ People ਐਪ ਦਾ ਸਿੰਕ ਸਮਰੱਥ ਬਣਾਉਣ ਲਈ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ।"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ਐਪ ਨੂੰ ਕਿਸੇ ਖਾਤੇ ਲਈ ਸਮਕਾਲੀਕਰਨ ਸੈਟਿੰਗਾਂ ਪੜ੍ਹਨ ਦੇ ਯੋਗ ਬਣਾਉਂਦਾ ਹੈ। ਉਦਾਹਰਨ ਲਈ, ਇਹ ਪਤਾ ਕਰ ਸਕਦਾ ਹੈ ਕਿ People ਐਪ ਦਾ ਕਿਸੇ ਖਾਤੇ ਨਾਲ ਸਮਕਾਲੀਕਿਰਤ ਕੀਤਾ ਗਿਆ ਹੈ ਜਾਂ ਨਹੀਂ।"</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ਸਮਕਾਲੀਕਰਨ ਚਾਲੂ ਅਤੇ ਬੰਦ ਨੂੰ ਟੌਗਲ ਕਰੋ"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ਐਪ ਨੂੰ ਇੱਕ ਖਾਤੇ ਲਈ ਸਮਕਾਲੀਕਰਨ ਸੈਟਿੰਗਾਂ ਸੋਧਣ ਦੇ ਯੋਗ ਬਣਾਉਂਦਾ ਹੈ। ਉਦਾਹਰਨ ਲਈ, ਇਸਦੀ ਵਰਤੋਂ ਕਿਸੇ ਖਾਤੇ ਨਾਲ People ਐਪ ਦਾ ਸਮਕਾਲੀਕਰਨ ਚਾਲੂ ਕਰਨ ਲਈ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ।"</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"ਸਿੰਕ ਅੰਕੜੇ ਪੜ੍ਹੋ"</string>
-    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"ਐਪ ਨੂੰ ਇੱਕ ਖਾਤੇ ਲਈ ਸਿੰਕ ਸਟੇਟਸ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਸਿੰਕ ਇਵੈਂਟਾਂ ਦੇ ਇਤਿਹਾਸ ਅਤੇ ਕਿੰਨਾ ਡੈਟਾ ਸਿੰਕ ਕੀਤਾ ਜਾਂਦਾ ਹੈ, ਸਮੇਤ।"</string>
-    <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"ਆਪਣੀ USB ਸਟੋਰੇਜ  ਦੀਆਂ ਸਮੱਗਰੀਆਂ ਪੜ੍ਹੋ"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"ਐਪ ਨੂੰ ਇੱਕ ਖਾਤੇ ਲਈ ਸਮਕਾਲੀਕਰਨ ਸਥਿਤੀ ਪੜ੍ਹਨ ਦੇ ਯੋਗ ਬਣਾਉਂਦਾ ਹੈ, ਇਸ ਵਿੱਚ ਸਮਕਾਲੀਕਰਨ ਵਰਤਾਰਿਆਂ ਦਾ ਇਤਿਹਾਸ ਅਤੇ ਕਿੰਨੇ ਡਾਟਾ ਦਾ ਸਮਕਾਲੀਕਿਰਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ, ਵੀ ਸ਼ਾਮਲ ਹੈ।"</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"USB ਸਟੋਰੇਜ ਦੀਆਂ ਸਮੱਗਰੀਆਂ ਪੜ੍ਹੋ"</string>
     <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"ਆਪਣੇ SD ਕਾਰਡ ਦੀਆਂ ਸਮੱਗਰੀਆਂ ਪੜ੍ਹੋ"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"ਐਪ ਨੂੰ ਆਪਣੀ USB ਸਟੋਰੇਜ ਦੀਆਂ ਸਮੱਗਰੀਆਂ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ SD ਕਾਰਡ ਦੀਆਂ ਸਮੱਗਰੀਆਂ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
@@ -516,12 +515,12 @@
     <string name="permdesc_register_call_provider" msgid="7034310263521081388">"ਐਪ ਨੂੰ ਨਵੇਂ ਟੈਲੀਕੌਮ ਕਨੈਕਸ਼ਨ ਰਜਿਸਟਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_connection_manager" msgid="1116193254522105375">"ਟੈਲੀਕੌਮ ਕਨੈਕਸ਼ਨ ਵਿਵਸਥਿਤ ਕਰੋ"</string>
     <string name="permdesc_connection_manager" msgid="5925480810356483565">"ਐਪ ਨੂੰ ਟੈਲੀਕੌਮ ਕਨੈਕਸ਼ਨ ਵਿਵਸਥਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_bind_incall_service" msgid="6773648341975287125">"ਇਨ-ਕਾਲ ਸਕ੍ਰੀਨ ਨਾਲ ਇੰਟਰੈਕਟ ਕਰੋ"</string>
-    <string name="permdesc_bind_incall_service" msgid="8343471381323215005">"ਐਪ ਨੂੰ ਇਸਤੇ ਨਿਯੰਤਰਣ ਪਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ ਕਿ ਉਪਭੋਗਤਾ ਕਦੋ ਅਤੇ ਕਿਵੇਂ ਇਨ-ਕਾਲ ਸਕ੍ਰੀਨ ਦੇਖਦਾ ਹੈ।"</string>
+    <string name="permlab_bind_incall_service" msgid="6773648341975287125">"ਇਨ-ਕਾਲ ਸਕ੍ਰੀਨ ਨਾਲ ਅੰਤਰਕਿਰਿਆ ਕਰੋ"</string>
+    <string name="permdesc_bind_incall_service" msgid="8343471381323215005">"ਐਪ ਨੂੰ ਇਸਤੇ ਨਿਯੰਤਰਣ ਪਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ ਕਿ ਵਰਤੋਂਕਾਰ ਕਦੋ ਅਤੇ ਕਿਵੇਂ ਇਨ-ਕਾਲ ਸਕ੍ਰੀਨ ਦੇਖਦਾ ਹੈ।"</string>
     <string name="permlab_bind_connection_service" msgid="3557341439297014940">"ਟੈਲੀਫੋਨੀ ਸੇਵਾਵਾਂ ਨਾਲ ਇੰਟਰੈਕਟ ਕਰੋ"</string>
     <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"ਐਨ ਨੂੰ ਕਾਲਾਂ ਕਰਨ/ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਟੈਲੀਫੋਨੀ ਸੇਵਾਵਾਂ ਨਾਲ ਇੰਟਰੈਕਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_control_incall_experience" msgid="9061024437607777619">"ਇੱਕ ਇਨ-ਕਾਲ ਉਪਭੋਗਤਾ ਅਨੁਭਵ ਮੁਹੱਈਆ ਕਰੋ"</string>
-    <string name="permdesc_control_incall_experience" msgid="915159066039828124">"ਐਪ ਨੂੰ ਇੱਕ ਇਨ-ਕਾਲ ਉਪਭੋਗਤਾ ਅਨੁਭਵ ਮੁਹੱਈਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_control_incall_experience" msgid="9061024437607777619">"ਇੱਕ ਇਨ-ਕਾਲ ਵਰਤੋਂਕਾਰ ਅਨੁਭਵ ਮੁਹੱਈਆ ਕਰੋ"</string>
+    <string name="permdesc_control_incall_experience" msgid="915159066039828124">"ਐਪ ਨੂੰ ਇੱਕ ਇਨ-ਕਾਲ ਵਰਤੋਂਕਾਰ ਅਨੁਭਵ ਮੁਹੱਈਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"ਇਤਿਹਾਸਕ ਨੈੱਟਵਰਕ ਵਰਤੋਂ ਪੜ੍ਹੋ"</string>
     <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"ਐਪ ਨੂੰ ਖ਼ਾਸ ਨੈੱਟਵਰਕਾਂ ਅਤੇ ਐਪਸ ਲਈ ਇਤਿਹਾਸਕ ਨੈੱਟਵਰਕ ਵਰਤੋਂ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"ਨੈੱਟਵਰਕ ਨੀਤੀ ਵਿਵਸਥਿਤ ਕਰੋ"</string>
@@ -531,11 +530,11 @@
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"ਪਹੁੰਚ ਸੂਚਨਾਵਾਂ"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"ਐਪ ਨੂੰ ਸੂਚਨਾਵਾਂ ਨੂੰ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਨ, ਜਾਂਚ ਕਰਨ ਅਤੇ ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਹੋਰਾਂ ਐਪਸ ਵੱਲੋਂ ਪੋਸਟ ਕੀਤੀਆਂ ਸਮੇਤ।"</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"ਇੱਕ ਸੂਚਨਾ ਸੁਣਨ ਵਾਲੀ ਸੇਵਾ ਨਾਲ ਜੋੜੋ"</string>
-    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"ਹੋਲਡਰ ਨੂੰ ਇੱਕ ਸੂਚਨਾ ਸੁਣਨ ਵਾਲੀ ਸੇਵਾ ਦੇ ਉੱਚ-ਪੱਧਰ ਦੇ ਇੰਟਰਫੇਸ ਨਾਲ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਸ ਲਈ ਕਦੇ ਵੀ ਲੁੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"ਹੋਲਡਰ ਨੂੰ ਇੱਕ ਸੂਚਨਾ ਸੁਣਨ ਵਾਲੀ ਸੇਵਾ ਦੇ ਉੱਚ-ਪੱਧਰ ਦੇ ਇੰਟਰਫੇਸ ਨਾਲ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਾਂ ਲਈ ਕਦੇ ਵੀ ਲੋੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
     <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"ਇੱਕ ਸਥਿਤੀ ਪ੍ਰਦਾਤਾ ਸੇਵਾ ਨਾਲ ਜੋੜੋ"</string>
-    <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"ਹੋਲਡਰ ਨੂੰ ਇੱਕ ਸਥਿਤੀ ਪ੍ਰਦਾਤਾ ਸੇਵਾ ਦੇ ਉੱਚ-ਪੱਧਰ ਦੇ ਇੰਟਰਫੇਸ ਨਾਲ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਸ ਲਈ ਕਦੇ ਵੀ ਲੁੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
+    <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"ਧਾਰਕ ਨੂੰ ਇੱਕ ਸਥਿਤੀ ਪ੍ਰਦਾਤਾ ਸੇਵਾ ਦੇ ਉੱਚ-ਪੱਧਰ ਦੇ ਇੰਟਰਫੇਸ ਨਾਲ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਾਂ ਲਈ ਕਦੇ ਵੀ ਲੋੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
     <string name="permlab_bindDreamService" msgid="4153646965978563462">"ਇੱਕ ਡ੍ਰੀਮ ਸੇਵਾ ਨਾਲ ਜੋੜੋ"</string>
-    <string name="permdesc_bindDreamService" msgid="7325825272223347863">"ਹੋਲਡਰ ਨੂੰ ਇੱਕ ਡ੍ਰੀਮ ਸੇਵਾ ਦੇ ਉੱਚ-ਪੱਧਰ ਦੇ ਇੰਟਰਫੇਸ ਨਾਲ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਸ ਲਈ ਕਦੇ ਵੀ ਲੁੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
+    <string name="permdesc_bindDreamService" msgid="7325825272223347863">"ਹੋਲਡਰ ਨੂੰ ਇੱਕ ਡ੍ਰੀਮ ਸੇਵਾ ਦੇ ਉੱਚ-ਪੱਧਰ ਦੇ ਇੰਟਰਫੇਸ ਨਾਲ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਾਂ ਲਈ ਕਦੇ ਵੀ ਲੋੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
     <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"ਕੈਰੀਅਰ-ਵੱਲੋਂ ਮੁਹੱਈਆ ਕੀਤੇ ਕੌਂਫਿਗਰੇਸ਼ਨ ਐਪ ਦੀ ਬੇਨਤੀ ਕਰੋ"</string>
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ਹੋਲਡਰ ਨੂੰ ਕੈਰੀਅਰ-ਵੱਲੋਂ ਮੁਹੱਈਆ ਕੀਤੇ ਕੌਂਫਿਗਰੇਸ਼ਨ ਐਪ ਦੀ ਬੇਨਤੀ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਸ ਲਈ ਕਦੇ ਵੀ ਲੁੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ਨੈੱਟਵਰਕ ਸਥਿਤੀਆਂ ਤੇ ਟਿੱਪਣੀਆਂ ਸੁਣੋ"</string>
@@ -547,44 +546,44 @@
     <string name="permlab_handoverStatus" msgid="7820353257219300883">"Android ਬੀਮ ਟ੍ਰਾਂਸਫਰ ਸਥਿਤੀ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"ਇਸ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਮੌਜੂਦਾ Android Beam ਟ੍ਰਾਂਸਫਰਾਂ ਬਾਰੇ ਜਾਣਕਾਰੀ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM ਸਰਟੀਫਿਕੇਟ ਹਟਾਓ"</string>
-    <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ DRM ਸਰਟੀਫਿਕੇਟ ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਸ ਲਈ ਕਦੇ ਵੀ ਲੁੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
+    <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ DRM ਸਰਟੀਫਿਕੇਟ ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਾਂ ਲਈ ਕਦੇ ਵੀ ਲੁੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
     <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"ਇੱਕ ਕੈਰੀਅਰ ਮੈਸੇਜਿੰਗ ਸੇਵਾ ਨਾਲ ਜੋੜੋ"</string>
-    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"ਹੋਲਡਰ ਨੂੰ ਇੱਕ ਕੈਰੀਅਰ ਮੈਸੇਜਿੰਗ ਸੇਵਾ ਦੇ ਉੱਚ-ਪੱਧਰ ਦੇ ਇੰਟਰਫੇਸ ਨਾਲ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਸ ਲਈ ਕਦੇ ਵੀ ਲੁੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"ਹੋਲਡਰ ਨੂੰ ਇੱਕ ਕੈਰੀਅਰ ਮੈਸੇਜਿੰਗ ਸੇਵਾ ਦੇ ਉੱਚ-ਪੱਧਰ ਦੇ ਇੰਟਰਫੇਸ ਨਾਲ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਾਂ ਲਈ ਕਦੇ ਵੀ ਲੋੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
     <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"ਕੈਰੀਅਰ ਸੇਵਾਵਾਂ ਨਾਲ ਜੋੜੋ"</string>
     <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"ਹੋਲਡਰ ਨੂੰ ਕੈਰੀਅਰ ਸੇਵਾਵਾਂ ਨਾਲ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਸ ਲਈ ਕਦੇ ਵੀ ਲੁੜੀਂਦਾ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।"</string>
     <string name="permlab_access_notification_policy" msgid="4247510821662059671">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਤੱਕ ਪਹੁੰਚ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"ਐਪ ਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਕੌਂਫਿਗਰੇਸ਼ਨ ਨੂੰ ਪੜ੍ਹਨ ਅਤੇ ਲਿਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"ਪਾਸਵਰਡ ਨਿਯਮ ਸੈੱਟ ਕਰੋ"</string>
-    <string name="policydesc_limitPassword" msgid="2502021457917874968">"ਸਕ੍ਰੀਨ ਲੌਕ ਪਾਸਵਰਡਾਂ ਅਤੇ ਪਿੰਨ ਵਿੱਚ ਆਗਿਆ ਦਿੱਤੀ ਲੰਮਾਈ ਅਤੇ ਅੱਖਰਾਂ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ।"</string>
-    <string name="policylab_watchLogin" msgid="5091404125971980158">"ਸਕ੍ਰੀਨ ਅਨਲੌਕ ਕਰਨ ਦੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ \'ਤੇ ਨਿਗਰਾਨੀ ਰੱਖੋ"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਲੌਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗ਼ਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ ਟੈਬਲੇਟ ਨੂੰ ਲੌਕ ਕਰੋ ਜਾਂ ਟੈਬਲੇਟ ਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗ਼ਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
-    <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਲੌਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗ਼ਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ TV ਨੂੰ ਲੌਕ ਕਰੋ ਜਾਂ TV ਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗ਼ਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
-    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਲੌਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗ਼ਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ ਫੋਨ ਨੂੰ ਲੌਕ ਕਰੋ ਜਾਂ ਫੋਨ ਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗ਼ਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਲੌਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗ਼ਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ ਟੈਬਲੇਟ ਨੂੰ ਲੌਕ ਕਰੋ ਜਾਂ ਟੈਬਲੇਟ ਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗ਼ਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਲੌਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗ਼ਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ TV ਨੂੰ ਲੌਕ ਕਰੋ ਜਾਂ TV ਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗ਼ਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਲੌਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗ਼ਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ ਫੋਨ ਨੂੰ ਲੌਕ ਕਰੋ ਜਾਂ ਫੋਨ ਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗ਼ਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
-    <string name="policylab_resetPassword" msgid="4934707632423915395">"ਸਕ੍ਰੀਨ ਲੌਕ ਬਦਲੋ"</string>
-    <string name="policydesc_resetPassword" msgid="1278323891710619128">"ਸਕ੍ਰੀਨ ਲੌਕ ਬਦਲੋ।"</string>
-    <string name="policylab_forceLock" msgid="2274085384704248431">"ਸਕ੍ਰੀਨ ਲੌਕ ਕਰੋ"</string>
-    <string name="policydesc_forceLock" msgid="1141797588403827138">"ਇਸਤੇ ਨਿਯੰਤਰਣ ਪਾਓ ਕਿ ਸਕ੍ਰਿਨ ਕਿਵੇਂ ਅਤੇ ਕਦੋਂ ਲੌਕ ਹੁੰਦੀ ਹੈ।"</string>
-    <string name="policylab_wipeData" msgid="3910545446758639713">"ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"ਇੱਕ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਟੈਬਲੇਟ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
+    <string name="policydesc_limitPassword" msgid="2502021457917874968">"ਸਕ੍ਰੀਨ ਲਾਕ ਪਾਸਵਰਡਾਂ ਅਤੇ ਪਿੰਨ ਵਿੱਚ ਆਗਿਆ ਦਿੱਤੀ ਲੰਮਾਈ ਅਤੇ ਅੱਖਰਾਂ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ।"</string>
+    <string name="policylab_watchLogin" msgid="5091404125971980158">"ਸਕ੍ਰੀਨ ਅਣਲਾਕ ਕਰਨ ਦੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ \'ਤੇ ਨਿਗਰਾਨੀ ਰੱਖੋ"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਹੋਏ ਟਾਈਪ ਕੀਤੇ ਗਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ ਟੈਬਲੈੱਟ ਨੂੰ ਲਾਕ ਕਰੋ ਜਾਂ ਟੈਬਲੈੱਟ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ, ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
+    <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗ਼ਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ TV ਨੂੰ  ਲਾਕ  ਕਰੋ ਜਾਂ TV ਦਾ ਸਾਰਾ  ਡਾਟਾ  ਮਿਟਾਓ ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗ਼ਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ ਫ਼ੋਨ ਨੂੰ ਲਾਕ ਕਰੋ ਜਾਂ ਫ਼ੋਨ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਹੋਏ ਟਾਈਪ ਕੀਤੇ ਗਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ ਟੈਬਲੈੱਟ ਨੂੰ ਲਾਕ ਕਰੋ ਜਾਂ ਟੈਬਲੈੱਟ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ, ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗ਼ਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ TV ਨੂੰ  ਲਾਕ  ਕਰੋ ਜਾਂ TV ਦਾ ਸਾਰਾ  ਡਾਟਾ  ਮਿਟਾਓ ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗ਼ਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ ਫ਼ੋਨ ਨੂੰ ਲਾਕ ਕਰੋ ਜਾਂ ਫ਼ੋਨ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
+    <string name="policylab_resetPassword" msgid="4934707632423915395">"ਸਕ੍ਰੀਨ  ਲਾਕ  ਬਦਲੋ"</string>
+    <string name="policydesc_resetPassword" msgid="1278323891710619128">"ਸਕ੍ਰੀਨ  ਲਾਕ  ਬਦਲੋ।"</string>
+    <string name="policylab_forceLock" msgid="2274085384704248431">"ਸਕ੍ਰੀਨ  ਲਾਕ  ਕਰੋ"</string>
+    <string name="policydesc_forceLock" msgid="1141797588403827138">"ਇਸਤੇ ਨਿਯੰਤਰਣ ਪਾਓ ਕਿ ਸਕ੍ਰਿਨ ਕਿਵੇਂ ਅਤੇ ਕਦੋਂ  ਲਾਕ  ਹੁੰਦੀ ਹੈ।"</string>
+    <string name="policylab_wipeData" msgid="3910545446758639713">"ਸਾਰਾ  ਡਾਟਾ  ਮਿਟਾਓ"</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"ਇੱਕ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਟੈਬਲੈੱਟ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
     <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"ਇੱਕ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਟੀਵੀ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
-    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"ਇੱਕ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਫੋਨ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
-    <string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"ਉਪਭੋਗਤਾ ਡੈਟਾ ਮਿਟਾਓ"</string>
-    <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"ਬਿਨਾਂ ਚਿਤਾਵਨੀ ਦੇ ਇਸ ਟੈਬਲੇਟ ਤੇ ਮੌਜੂਦ ਇਸ ਉਪਭੋਗਤਾ ਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ।"</string>
-    <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"ਬਿਨਾਂ ਚਿਤਾਵਨੀ ਦੇ ਇਸ TV ਤੇ ਮੌਜੂਦ ਇਸ ਉਪਭੋਗਤਾ ਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ।"</string>
-    <string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"ਬਿਨਾਂ ਚਿਤਾਵਨੀ ਦੇ ਇਸ ਫੋਨ ਤੇ ਮੌਜੂਦ ਇਸ ਉਪਭੋਗਤਾ ਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ।"</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"ਇੱਕ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਫ਼ੋਨ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
+    <string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"ਉਪਭੋਗਤਾ  ਡਾਟਾ  ਮਿਟਾਓ"</string>
+    <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"ਬਿਨਾਂ ਚਿਤਾਵਨੀ ਦੇ ਇਸ ਟੈਬਲੈੱਟ ਤੇ ਮੌਜੂਦ ਇਸ ਵਰਤੋਂਕਾਰ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
+    <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"ਬਿਨਾਂ ਚਿਤਾਵਨੀ ਦੇ ਇਸ TV ਤੇ ਮੌਜੂਦ ਇਸ ਉਪਭੋਗਤਾ ਦਾ ਸਾਰਾ  ਡਾਟਾ  ਮਿਟਾਓ।"</string>
+    <string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"ਬਿਨਾਂ ਚਿਤਾਵਨੀ ਦੇ ਇਸ ਫ਼ੋਨ ਤੇ ਮੌਜੂਦ ਇਸ ਵਰਤੋਂਕਾਰ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"ਡੀਵਾਈਸ ਗਲੋਬਲ ਪ੍ਰੌਕਸੀ ਸੈੱਟ ਕਰੋ"</string>
-    <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"ਜਦੋਂ ਨੀਤੀ ਸਮਰਥਿਤ ਹੋਵੇ ਤਾਂ ਵਰਤੇ ਜਾਣ ਲਈ ਡੀਵਾਈਸ ਗਲੋਬਲ ਪ੍ਰੌਕਸੀ ਸੈੱਟ ਕਰੋ। ਕੇਵਲ ਡੀਵਾਈਸ ਮਾਲਕ ਗਲੋਬਲ ਪ੍ਰੌਕਸੀ ਸੈੱਟ ਕਰ ਸਕਦਾ ਹੈ।"</string>
-    <string name="policylab_expirePassword" msgid="5610055012328825874">"ਸਕ੍ਰੀਨ ਲੌਕ ਪਾਸਵਰਡ ਸਮਾਪਤੀ ਮਿਆਦ ਸੈੱਟ ਕਰੋ"</string>
-    <string name="policydesc_expirePassword" msgid="5367525762204416046">"ਇਸ ਵਿੱਚ ਬਦਲਾਵ ਕਰੋ ਕਿ ਸਕ੍ਰੀਨ ਲੌਕ ਪਾਸਵਰਡ, ਪਿੰਨ ਜਾਂ ਪੈਟਰਨ ਨੂੰ ਕਿੰਨੀ ਵਾਰ ਬਦਲਿਆ ਜਾਣਾ ਚਾਹੀਦਾ ਹੈ।"</string>
+    <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"ਜਦੋਂ ਨੀਤੀ ਚਾਲੂ ਹੋਵੇ ਤਾਂ ਵਰਤੇ ਜਾਣ ਲਈ ਡੀਵਾਈਸ ਗਲੋਬਲ ਪ੍ਰੌਕਸੀ ਸੈੱਟ ਕਰੋ। ਕੇਵਲ ਡੀਵਾਈਸ ਮਾਲਕ ਗਲੋਬਲ ਪ੍ਰੌਕਸੀ ਸੈੱਟ ਕਰ ਸਕਦਾ ਹੈ।"</string>
+    <string name="policylab_expirePassword" msgid="5610055012328825874">"ਸਕ੍ਰੀਨ ਲਾਕ ਪਾਸਵਰਡ ਸਮਾਪਤੀ ਮਿਆਦ ਸੈੱਟ ਕਰੋ"</string>
+    <string name="policydesc_expirePassword" msgid="5367525762204416046">"ਇਸ ਵਿੱਚ ਬਦਲਾਵ ਕਰੋ ਕਿ ਸਕ੍ਰੀਨ ਲਾਕ ਪਾਸਵਰਡ, ਪਿੰਨ ਜਾਂ ਪੈਟਰਨ ਨੂੰ ਕਿੰਨੀ ਵਾਰ ਬਦਲਿਆ ਜਾਣਾ ਚਾਹੀਦਾ ਹੈ।"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"ਸਟੋਰੇਜ ਇਨਕ੍ਰਿਪਸ਼ਨ ਸੈੱਟ ਕਰੋ"</string>
-    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"ਲੋੜ ਹੈ ਕਿ ਸਟੋਰ ਕੀਤਾ ਐਪ ਡੈਟਾ ਇਨਕ੍ਰਿਪਟ ਕੀਤਾ ਜਾਏ।"</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"ਲੋੜ ਹੈ ਕਿ ਸਟੋਰ ਕੀਤਾ ਐਪ  ਡਾਟਾ  ਇਨਕ੍ਰਿਪਟ ਕੀਤਾ ਜਾਏ।"</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"ਕੈਮਰੇ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
     <string name="policydesc_disableCamera" msgid="2306349042834754597">"ਸਾਰੇ ਡੀਵਾਈਸ ਕੈਮਰਿਆਂ ਦੀ ਵਰਤੋਂ ਰੋਕੋ।"</string>
-    <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"ਸਕ੍ਰੀਨ ਲੌਕ ਦੀਆਂ ਕੁਝ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
-    <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"ਸਕ੍ਰੀਨ ਲੌਕ ਦੀਆਂ ਕੁਝ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦੀ ਵਰਤੋਂ ਰੋਕੋ।"</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"ਸਕ੍ਰੀਨ  ਲਾਕ  ਦੀਆਂ ਕੁਝ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"ਸਕ੍ਰੀਨ  ਲਾਕ  ਦੀਆਂ ਕੁਝ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦੀ ਵਰਤੋਂ ਰੋਕੋ।"</string>
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"ਘਰ"</item>
     <item msgid="869923650527136615">"ਮੋਬਾਈਲ"</item>
@@ -593,30 +592,30 @@
     <item msgid="1735177144948329370">"ਘਰ ਦੀ ਫੈਕਸ"</item>
     <item msgid="603878674477207394">"ਪੇਜਰ"</item>
     <item msgid="1650824275177931637">"ਹੋਰ"</item>
-    <item msgid="9192514806975898961">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</item>
+    <item msgid="9192514806975898961">"ਵਿਉਂਂਤੀ"</item>
   </string-array>
   <string-array name="emailAddressTypes">
     <item msgid="8073994352956129127">"ਘਰ"</item>
     <item msgid="7084237356602625604">"ਕੰਮ"</item>
     <item msgid="1112044410659011023">"ਹੋਰ"</item>
-    <item msgid="2374913952870110618">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</item>
+    <item msgid="2374913952870110618">"ਵਿਉਂਂਤੀ"</item>
   </string-array>
   <string-array name="postalAddressTypes">
     <item msgid="6880257626740047286">"ਘਰ"</item>
     <item msgid="5629153956045109251">"ਕੰਮ"</item>
     <item msgid="4966604264500343469">"ਹੋਰ"</item>
-    <item msgid="4932682847595299369">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</item>
+    <item msgid="4932682847595299369">"ਵਿਉਂਂਤੀ"</item>
   </string-array>
   <string-array name="imAddressTypes">
     <item msgid="1738585194601476694">"ਘਰ"</item>
     <item msgid="1359644565647383708">"ਕੰਮ"</item>
     <item msgid="7868549401053615677">"ਹੋਰ"</item>
-    <item msgid="3145118944639869809">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</item>
+    <item msgid="3145118944639869809">"ਵਿਉਂਂਤੀ"</item>
   </string-array>
   <string-array name="organizationTypes">
     <item msgid="7546335612189115615">"ਕੰਮ"</item>
     <item msgid="4378074129049520373">"ਹੋਰ"</item>
-    <item msgid="3455047468583965104">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</item>
+    <item msgid="3455047468583965104">"ਵਿਉਂਂਤੀ"</item>
   </string-array>
   <string-array name="imProtocols">
     <item msgid="8595261363518459565">"AIM"</item>
@@ -628,7 +627,7 @@
     <item msgid="2506857312718630823">"ICQ"</item>
     <item msgid="1648797903785279353">"Jabber"</item>
   </string-array>
-    <string name="phoneTypeCustom" msgid="1644738059053355820">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</string>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"ਵਿਉਂਂਤੀ"</string>
     <string name="phoneTypeHome" msgid="2570923463033985887">"ਘਰ"</string>
     <string name="phoneTypeMobile" msgid="6501463557754751037">"ਮੋਬਾਈਲ"</string>
     <string name="phoneTypeWork" msgid="8863939667059911633">"ਕੰਮ"</string>
@@ -645,28 +644,28 @@
     <string name="phoneTypeRadio" msgid="4093738079908667513">"ਰੇਡੀਓ"</string>
     <string name="phoneTypeTelex" msgid="3367879952476250512">"ਟੈਲੈਕਸ"</string>
     <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
-    <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"ਦਫ਼ਤਰ ਦਾ ਮੋਬਾਈਲ"</string>
+    <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"ਕੰਮ ਦਾ ਮੋਬਾਈਲ"</string>
     <string name="phoneTypeWorkPager" msgid="649938731231157056">"ਦਫ਼ਤਰ ਦਾ ਪੇਜਰ"</string>
     <string name="phoneTypeAssistant" msgid="5596772636128562884">"ਸਹਾਇਕ"</string>
     <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
-    <string name="eventTypeCustom" msgid="7837586198458073404">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</string>
+    <string name="eventTypeCustom" msgid="7837586198458073404">"ਵਿਉਂਂਤੀ"</string>
     <string name="eventTypeBirthday" msgid="2813379844211390740">"ਜਨਮਦਿਨ"</string>
     <string name="eventTypeAnniversary" msgid="3876779744518284000">"ਵਰ੍ਹੇਗੰਢ"</string>
     <string name="eventTypeOther" msgid="7388178939010143077">"ਹੋਰ"</string>
-    <string name="emailTypeCustom" msgid="8525960257804213846">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</string>
+    <string name="emailTypeCustom" msgid="8525960257804213846">"ਵਿਉਂਂਤੀ"</string>
     <string name="emailTypeHome" msgid="449227236140433919">"ਘਰ"</string>
     <string name="emailTypeWork" msgid="3548058059601149973">"ਕੰਮ"</string>
     <string name="emailTypeOther" msgid="2923008695272639549">"ਹੋਰ"</string>
     <string name="emailTypeMobile" msgid="119919005321166205">"ਮੋਬਾਈਲ"</string>
-    <string name="postalTypeCustom" msgid="8903206903060479902">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</string>
+    <string name="postalTypeCustom" msgid="8903206903060479902">"ਵਿਉਂਂਤੀ"</string>
     <string name="postalTypeHome" msgid="8165756977184483097">"ਘਰ"</string>
     <string name="postalTypeWork" msgid="5268172772387694495">"ਕੰਮ"</string>
     <string name="postalTypeOther" msgid="2726111966623584341">"ਹੋਰ"</string>
-    <string name="imTypeCustom" msgid="2074028755527826046">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</string>
+    <string name="imTypeCustom" msgid="2074028755527826046">"ਵਿਉਂਂਤੀ"</string>
     <string name="imTypeHome" msgid="6241181032954263892">"ਘਰ"</string>
     <string name="imTypeWork" msgid="1371489290242433090">"ਕੰਮ"</string>
     <string name="imTypeOther" msgid="5377007495735915478">"ਹੋਰ"</string>
-    <string name="imProtocolCustom" msgid="6919453836618749992">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</string>
+    <string name="imProtocolCustom" msgid="6919453836618749992">"ਵਿਉਂਂਤੀ"</string>
     <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
     <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
@@ -678,8 +677,8 @@
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
     <string name="orgTypeWork" msgid="29268870505363872">"ਕੰਮ"</string>
     <string name="orgTypeOther" msgid="3951781131570124082">"ਹੋਰ"</string>
-    <string name="orgTypeCustom" msgid="225523415372088322">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</string>
-    <string name="relationTypeCustom" msgid="3542403679827297300">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</string>
+    <string name="orgTypeCustom" msgid="225523415372088322">"ਵਿਉਂਂਤੀ"</string>
+    <string name="relationTypeCustom" msgid="3542403679827297300">"ਵਿਉਂਂਤੀ"</string>
     <string name="relationTypeAssistant" msgid="6274334825195379076">"ਸਹਾਇਕ"</string>
     <string name="relationTypeBrother" msgid="8757913506784067713">"ਭਰਾ"</string>
     <string name="relationTypeChild" msgid="1890746277276881626">"ਬੱਚਾ"</string>
@@ -694,7 +693,7 @@
     <string name="relationTypeRelative" msgid="1799819930085610271">"ਰਿਸ਼ਤੇਦਾਰ"</string>
     <string name="relationTypeSister" msgid="1735983554479076481">"ਭੈਣ"</string>
     <string name="relationTypeSpouse" msgid="394136939428698117">"ਜੀਵਨਸਾਥੀ"</string>
-    <string name="sipAddressTypeCustom" msgid="2473580593111590945">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</string>
+    <string name="sipAddressTypeCustom" msgid="2473580593111590945">"ਵਿਉਂਂਤੀ"</string>
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"ਘਰ"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"ਕੰਮ"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"ਹੋਰ"</string>
@@ -704,68 +703,68 @@
     <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK ਕੋਡ"</string>
     <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"ਨਵਾਂ ਪਿੰਨ ਕੋਡ"</string>
     <string name="keyguard_password_entry_touch_hint" msgid="2644215452200037944"><font size="17">"ਪਾਸਵਰਡ ਟਾਈਪ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</font></string>
-    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"ਅਨਲੌਕ ਕਰਨ ਲਈ ਪਾਸਵਰਡ ਟਾਈਪ ਕਰੋ"</string>
-    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"ਅਨਲੌਕ ਕਰਨ ਲਈ ਪਿੰਨ ਟਾਈਪ ਕਰੋ"</string>
-    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ਗ਼ਲਤ ਪਿੰਨ ਕੋਡ।"</string>
-    <string name="keyguard_label_text" msgid="861796461028298424">"ਅਨਲੌਕ ਕਰਨ ਲਈ, ਪਹਿਲਾਂ ਮੀਨੂ ਫਿਰ 0 ਦਬਾਓ।"</string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਪਾਸਵਰਡ ਟਾਈਪ ਕਰੋ"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਪਿੰਨ ਟਾਈਪ ਕਰੋ"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ਗਲਤ ਪਿੰਨ ਕੋਡ।"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"ਅਣਲਾਕ ਕਰਨ ਲਈ, ਪਹਿਲਾਂ ਮੀਨੂ ਫਿਰ 0 ਦਬਾਓ।"</string>
     <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"ਐਮਰਜੈਂਸੀ ਨੰਬਰ"</string>
     <string name="lockscreen_carrier_default" msgid="6169005837238288522">"ਕੋਈ ਸੇਵਾ ਨਹੀਂ"</string>
-    <string name="lockscreen_screen_locked" msgid="7288443074806832904">"ਸਕ੍ਰੀਨ ਲੌਕ ਕੀਤੀ।"</string>
-    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"ਅਨਲੌਕ ਕਰਨ ਲਈ ਮੀਨੂ ਦਬਾਓ ਜਾਂ ਐਮਰਜੈਂਸੀ ਕਾਲ ਕਰੋ।"</string>
-    <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"ਅਨਲੌਕ ਕਰਨ ਲਈ ਮੀਨੂ ਦਬਾਓ।"</string>
-    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"ਅਨਲੌਕ ਕਰਨ ਲਈ ਪੈਟਰਨ ਡ੍ਰਾ ਕਰੋ"</string>
+    <string name="lockscreen_screen_locked" msgid="7288443074806832904">"ਸਕ੍ਰੀਨ  ਲਾਕ  ਕੀਤੀ।"</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਮੀਨੂ ਦਬਾਓ ਜਾਂ ਸੰਕਟਕਾਲੀਨ ਕਾਲ ਕਰੋ।"</string>
+    <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਮੀਨੂ ਦਬਾਓ।"</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਪੈਟਰਨ ਡ੍ਰਾ ਕਰੋ"</string>
     <string name="lockscreen_emergency_call" msgid="5298642613417801888">"ਸੰਕਟਕਾਲ"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"ਕਾਲ ਤੇ ਵਾਪਸ ਜਾਓ"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"ਸਹੀ!"</string>
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
-    <string name="lockscreen_storage_locked" msgid="9167551160010625200">"ਸਾਰੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਅਤੇ ਡੈਟੇ ਲਈ ਅਨਲੌਕ ਕਰੋ"</string>
-    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"ਅਧਿਕਤਮ ਚਿਹਰਾ ਅਨਲੌਕ ਕੋਸ਼ਿਸ਼ਾਂ ਵਧੀਆਂ"</string>
-    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"ਕੋਈ SIM ਕਾਰਡ ਨਹੀਂ"</string>
-    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"ਟੈਬਲੇਟ ਵਿੱਚ ਕੋਈ SIM ਕਾਰਡ ਨਹੀਂ।"</string>
-    <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"TV ਵਿੱਚ ਕੋਈ SIM ਕਾਰਡ ਨਹੀਂ।"</string>
-    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"ਫੋਨ ਵਿੱਚ ਕੋਈ SIM ਕਾਰਡ ਨਹੀਂ।"</string>
+    <string name="lockscreen_storage_locked" msgid="9167551160010625200">"ਸਾਰੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਅਤੇ ਡਾਟੇ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"ਅਧਿਕਤਮ ਚਿਹਰਾ ਅਣਲਾਕ ਕੋਸ਼ਿਸ਼ਾਂ ਵਧੀਆਂ"</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"ਕੋਈ ਸਿਮ ਕਾਰਡ ਨਹੀਂ"</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"ਟੈਬਲੈੱਟ ਵਿੱਚ ਕੋਈ ਸਿਮ ਕਾਰਡ ਨਹੀਂ ਹੈ।"</string>
+    <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"TV ਵਿੱਚ ਕੋਈ ਸਿਮ ਕਾਰਡ ਨਹੀਂ।"</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"ਫ਼ੋਨ ਵਿੱਚ ਕੋਈ ਸਿਮ ਕਾਰਡ ਮੌਜੂਦ ਨਹੀਂ।"</string>
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"ਇੱਕ SIM ਕਾਰਡ ਪਾਓ।"</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM ਕਾਰਡ ਲੁਪਤ ਹੈ ਜਾਂ ਪੜ੍ਹਨਯੋਗ ਨਹੀਂ ਹੈ। ਇੱਕ SIM ਕਾਰਡ ਪਾਓ।"</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"ਨਾਵਰਤਣਯੋਗ SIM ਕਾਰਡ।"</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"ਤੁਹਾਡਾ SIM ਕਾਰਡ ਸਥਾਈ ਤੌਰ ਤੇ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ।\n ਦੂਜੇ SIM ਕਾਰਡ ਲਈ ਆਪਣੇ ਵਾਇਰਲੈਸ ਸੇਵਾ ਪ੍ਰਦਾਤਾ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"ਤੁਹਾਡਾ ਸਿਮ ਕਾਰਡ ਸਥਾਈ ਤੌਰ \'ਤੇ ਅਯੋਗ ਬਣਾ ਦਿੱਤਾ ਗਿਆ ਹੈ।\n ਇੱਕ ਹੋਰ ਸਿਮ ਕਾਰਡ ਲਈ ਆਪਣੇ ਵਾਇਰਲੈੱਸ ਸੇਵਾ ਪ੍ਰਦਾਨਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"ਪਿਛਲਾ ਟਰੈਕ"</string>
     <string name="lockscreen_transport_next_description" msgid="573285210424377338">"ਅਗਲਾ ਟਰੈਕ"</string>
     <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"ਰੋਕੋ"</string>
     <string name="lockscreen_transport_play_description" msgid="1901258823643886401">"ਪਲੇ ਕਰੋ"</string>
     <string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"ਰੋਕੋ"</string>
     <string name="lockscreen_transport_rew_description" msgid="6944412838651990410">"ਰੀਵਾਈਂਡ ਕਰੋ"</string>
-    <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"ਅੱਗੇ ਭੇਜੋ"</string>
+    <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"ਤੇਜ਼ੀ ਨਾਲ ਅੱਗੇ ਭੇਜੋ"</string>
     <string name="emergency_calls_only" msgid="6733978304386365407">"ਕੇਵਲ ਐਮਰਜੈਂਸੀ ਕਾਲਾਂ"</string>
-    <string name="lockscreen_network_locked_message" msgid="143389224986028501">"ਨੈੱਟਵਰਕ ਲੌਕ ਕੀਤਾ"</string>
+    <string name="lockscreen_network_locked_message" msgid="143389224986028501">"ਨੈੱਟਵਰਕ  ਲਾਕ  ਕੀਤਾ"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM ਕਾਰਡ PUK-ਲੌਕਡ ਹੈ।"</string>
-    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"ਉਪਭੋਗਤਾ ਗਾਈਡ ਦੇਖੋ ਜਾਂ ਗਾਹਕ ਸੇਵਾ ਨੂੰ ਫੋਨ ਕਰੋ।"</string>
-    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM ਕਾਰਡ ਲੌਕ ਕੀਤਾ ਹੋਇਆ ਹੈ।"</string>
-    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM ਕਾਰਡ ਅਨਲੌਕ ਕਰ ਰਿਹਾ ਹੈ…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਪਾਸਵਰਡ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"ਤੁਸੀਂ ਆਪਣਾ ਪਿੰਨ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣੀ ਟੈਬਲੇਟ ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ। \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ TV ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n  <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ ਫੋਨ ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਟੈਬਲੇਟ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗੀ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, TV ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਫੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਫੋਨ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਟੌਬਲੇਟ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗੀ।"</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ TV ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਫੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਫੋਨ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"ਵਰਤੋਂਕਾਰ ਗਾਈਡ ਦੇਖੋ ਜਾਂ ਗਾਹਕ ਸੇਵਾ ਨੂੰ ਫ਼ੋਨ ਕਰੋ।"</string>
+    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM ਕਾਰਡ  ਲਾਕ  ਕੀਤਾ ਹੋਇਆ ਹੈ।"</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM ਕਾਰਡ ਅਣਲਾਕ ਕਰ ਰਿਹਾ ਹੈ…"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਉਲੀਕਿਆ ਹੈ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਪਾਸਵਰਡ ਗਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ।\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"ਤੁਸੀਂ ਆਪਣਾ ਪਿੰਨ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨ-ਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣੀ ਟੈਬਲੈੱਟ ਅਣਲਾਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ। \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨ-ਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ ਟੀਵੀ ਅਣਲਾਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ ਫ਼ੋਨ ਅਣਲਾਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਟੈਬਲੈੱਟ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਵੇਗਾ ਅਤੇ ਸਾਰਾ ਵਰਤੋਂਕਾਰ ਡਾਟਾ ਨਸ਼ਟ ਹੋ ਜਾਵੇਗਾ।"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੀਵੀ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਟੀਵੀ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਵਰਤੋਂਕਾਰ ਡਾਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਫ਼ੋਨ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਵਰਤੋਂਕਾਰ ਡਾਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਟੈਬਲੈੱਟ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਵੇਗਾ।"</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੀਵੀ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਟੀਵੀ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਫ਼ੋਨ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"ਕੀ ਪੈਟਰਨ ਭੁੱਲ ਗਏ?"</string>
-    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"ਖਾਤਾ ਅਨਲੌਕ"</string>
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"ਖਾਤਾ ਅਣਲਾਕ"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਪੈਟਰਨ ਕੋਸ਼ਿਸ਼ਾਂ"</string>
-    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"ਅਨਲੌਕ ਕਰਨ ਲਈ, ਆਪਣੇ Google ਖਾਤੇ ਨਾਲ ਸਾਈਨ ਇਨ ਕਰੋ।"</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"ਅਣਲਾਕ ਕਰਨ ਲਈ, ਆਪਣੇ Google ਖਾਤੇ ਨਾਲ ਸਾਈਨ-ਇਨ ਕਰੋ।"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"ਵਰਤੋਂਕਾਰ ਨਾਮ (ਈਮੇਲ)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"ਪਾਸਵਰਡ"</string>
-    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ਸਾਈਨ ਇਨ ਕਰੋ"</string>
-    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"ਅਪ੍ਰਮਾਣਿਕ ਵਰਤੋਂਕਾਰ ਨਾਮ ਜਾਂ ਪਾਸਵਰਡ।"</string>
+    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
+    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"ਅਵੈਧ ਵਰਤੋਂਕਾਰ ਨਾਮ ਜਾਂ ਪਾਸਵਰਡ।"</string>
     <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਵਰਤੋਂਕਾਰ ਨਾਮ ਜਾਂ ਪਾਸਵਰਡ ਭੁੱਲ ਗਏ ਹੋ?\n"<b>"google.com/accounts/recovery"</b>" ਤੇ ਜਾਓ।"</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"ਜਾਂਚ ਕਰ ਰਿਹਾ ਹੈ..."</string>
-    <string name="lockscreen_unlock_label" msgid="737440483220667054">"ਅਨਲੌਕ ਕਰੋ"</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"ਅਣਲਾਕ ਕਰੋ"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ਅਵਾਜ਼ ਚਾਲੂ"</string>
     <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ਅਵਾਜ਼ ਬੰਦ"</string>
     <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"ਪੈਟਰਨ ਚਾਲੂ ਕੀਤਾ"</string>
@@ -775,10 +774,10 @@
     <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ਪੈਟਰਨ ਪੂਰਾ ਕੀਤਾ"</string>
     <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ਪੈਟਰਨ ਖੇਤਰ।"</string>
     <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s। %3$d ਦਾ ਵਿਜੇਟ %2$d।"</string>
-    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ਵਿਜੇਟ ਜੋੜੋ।"</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ਵਿਜੇਟ ਸ਼ਾਮਲ ਕਰੋ।"</string>
     <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ਖਾਲੀ"</string>
-    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"ਅਨਲੌਕ ਖੇਤਰ ਦਾ ਵਿਸਤਾਰ ਕੀਤਾ।"</string>
-    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"ਅਨਲੌਕ ਖੇਤਰ ਨਸ਼ਟ ਕੀਤਾ।"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"ਅਣਲਾਕ ਖੇਤਰ ਦਾ ਵਿਸਤਾਰ ਕੀਤਾ।"</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"ਅਣਲਾਕ ਖੇਤਰ ਨਸ਼ਟ ਕੀਤਾ।"</string>
     <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ਵਿਜੇਟ।"</string>
     <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"ਉਪਭੋਗਤਾ ਚੋਣਕਾਰ"</string>
     <string name="keyguard_accessibility_status" msgid="8008264603935930611">"ਅਵਸਥਾ"</string>
@@ -787,12 +786,12 @@
     <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"ਵਿਜੇਟ ਨੂੰ ਪੁਨਰ ਤਰਤੀਬ ਦੇਣਾ ਸ਼ੁਰੂ ਹੋਇਆ।"</string>
     <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"ਵਿਜੇਟ ਨੂੰ ਪੁਨਰ ਤਰਤੀਬ ਦੇਣਾ ਖ਼ਤਮ ਹੋਇਆ।"</string>
     <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"ਵਿਜੇਟ <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ਮਿਟਾਇਆ।"</string>
-    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"ਅਨਲੌਕ ਖੇਤਰ ਦਾ ਵਿਸਤਾਰ ਕਰੋ।"</string>
-    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"ਅਨਲੌਕ ਸਲਾਈਡ ਕਰੋ।"</string>
-    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"ਪੈਟਰਨ ਅਨਲੌਕ।"</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ਚਿਹਰਾ ਅਨਲੌਕ।"</string>
-    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"ਪਿੰਨ ਅਨਲੌਕ।"</string>
-    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"ਪਾਸਵਰਡ ਅਨਲੌਕ।"</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"ਅਣਲਾਕ ਖੇਤਰ ਦਾ ਵਿਸਤਾਰ ਕਰੋ।"</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"ਅਣਲਾਕ ਸਲਾਈਡ ਕਰੋ।"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"ਪੈਟਰਨ ਅਣਲਾਕ।"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ਚਿਹਰਾ ਅਣਲਾਕ।"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"ਪਿੰਨ ਅਣਲਾਕ।"</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>
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
@@ -803,17 +802,17 @@
     <string name="granularity_label_link" msgid="5815508880782488267">"ਲਿੰਕ"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"ਲਾਈਨ"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"ਫੈਕਟਰੀ ਜਾਂਚ ਅਸਫਲ"</string>
-    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST ਕਿਰਿਆ ਕੇਵਲ /ਸਿਸਟਮ/ਐਪ ਵਿੱਚ ਇੰਸਟੌਲ ਕੀਤੇ ਪੈਕੇਜਾਂ ਲਈ ਸਮਰਥਿਤ ਹੈ।"</string>
-    <string name="factorytest_no_action" msgid="872991874799998561">"ਅਜਿਹਾ ਕੋਈ ਪੈਕੇਜ ਨਹੀਂ ਮਿਲਿਆ ਜੋ FACTORY_TEST ਕਿਰਿਆ ਮੁਹੱਈਆ ਕਰਦਾ ਹੈ।"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST ਕਾਰਵਾਈ ਕੇਵਲ /ਸਿਸਟਮ/ਐਪ ਵਿੱਚ ਸਥਾਪਤ ਕੀਤੇ ਪੈਕੇਜਾਂ ਲਈ ਸਮਰਥਿਤ ਹੈ।"</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"ਅਜਿਹਾ ਕੋਈ ਪੈਕੇਜ ਨਹੀਂ ਮਿਲਿਆ ਜੋ FACTORY_TEST ਕਾਰਵਾਈ ਮੁਹੱਈਆ ਕਰਦਾ ਹੈ।"</string>
     <string name="factorytest_reboot" msgid="6320168203050791643">"ਰੀਬੂਟ ਕਰੋ"</string>
     <string name="js_dialog_title" msgid="1987483977834603872">"\"<xliff:g id="TITLE">%s</xliff:g>\" ਤੇ ਸਫ਼ੇ ਦੇ ਮੁਤਾਬਕ:"</string>
     <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"ਨੈਵੀਗੇਸ਼ਨ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"ਇਹ ਸਫ਼ਾ ਛੱਡੋ"</string>
     <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="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_address_name_separator" msgid="6350145154779706772">" "</string>
@@ -823,7 +822,7 @@
     <string name="autofill_province" msgid="2231806553863422300">"ਸੂਬਾ"</string>
     <string name="autofill_postal_code" msgid="4696430407689377108">"ਡਾਕ ਕੋਡ"</string>
     <string name="autofill_state" msgid="6988894195520044613">"ਰਾਜ"</string>
-    <string name="autofill_zip_code" msgid="8697544592627322946">"ਜ਼ਿੱਪ ਕੋਡ"</string>
+    <string name="autofill_zip_code" msgid="8697544592627322946">"ਜ਼ਿਪ ਕੋਡ"</string>
     <string name="autofill_county" msgid="237073771020362891">"ਕਾਉਂਟੀ"</string>
     <string name="autofill_island" msgid="4020100875984667025">"ਟਾਪੂ"</string>
     <string name="autofill_district" msgid="8400735073392267672">"ਜ਼ਿਲ੍ਹਾ"</string>
@@ -832,18 +831,18 @@
     <string name="autofill_parish" msgid="8202206105468820057">"ਪੈਰਿਸ਼"</string>
     <string name="autofill_area" msgid="3547409050889952423">"ਖੇਤਰ"</string>
     <string name="autofill_emirate" msgid="2893880978835698818">"ਅਮੀਰਾਤ"</string>
-    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"ਆਪਣੇ ਵੈਬ ਬੁੱਕਮਾਰਕਸ ਅਤੇ ਇਤਿਹਾਸ ਪੜ੍ਹੋ"</string>
-    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"ਐਪ ਨੂੰ ਸਾਰੇ URL ਜਿਨ੍ਹਾਂ ਤੇ ਬ੍ਰਾਊਜ਼ਰ ਨੇ ਵਿਜਿਟ ਕੀਤਾ ਹੈ ਅਤੇ ਬ੍ਰਾਊਜ਼ਰ ਦੇ ਸਾਰੇ ਬੁੱਕਮਾਰਕਾਂ, ਦਾ ਇਤਿਹਾਸ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਨੋਟ: ਇਹ ਅਨੁਮਤੀ ਤੀਜੀ-ਪਾਰਟੀ ਬ੍ਰਾਊਜ਼ਰਾਂ ਜਾਂ ਵੈਬ ਬ੍ਰਾਊਜ਼ਿੰਗ ਸਮਰੱਥਾ ਵਾਲੀਆਂ ਹੋਰਾਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
-    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"ਵੈਬ ਬੁੱਕਮਾਰਕਸ ਅਤੇ ਇਤਿਹਾਸ ਲਿਖੋ"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਦਾ ਇਤਿਹਾਸ ਅਤੇ ਤੁਹਾਡੀ ਟੈਬਲੇਟ ਤੇ ਸਟੋਰ ਕੀਤੇ ਬੁੱਕਮਾਰਕਾਂ ਨੂੰ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਡੈਟਾ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ। ਨੋਟ: ਇਹ ਅਨੁਮਤੀ ਤੀਜੀ-ਪਾਰਟੀ ਬ੍ਰਾਊਜ਼ਰਾਂ ਜਾਂ ਵੈਬ ਬ੍ਰਾਊਜ਼ਿੰਗ ਸਮਰੱਥਤਾਵਂ ਵਾਲੀਆਂ ਹੋਰਾਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਦਾ ਇਤਿਹਾਸ ਅਤੇ ਤੁਹਾਡੇ TV ਤੇ ਸਟੋਰ ਕੀਤੇ ਬੁੱਕਮਾਰਕਾਂ ਨੂੰ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਡੈਟਾ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ। ਨੋਟ: ਇਹ ਅਨੁਮਤੀ ਤੀਜੀ-ਪਾਰਟੀ ਬ੍ਰਾਊਜ਼ਰਾਂ ਜਾਂ ਵੈਬ ਬ੍ਰਾਊਜ਼ਿੰਗ ਸਮਰੱਥਤਾਵਂ ਵਾਲੀਆਂ ਹੋਰਾਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਦਾ ਇਤਿਹਾਸ ਅਤੇ ਤੁਹਾਡੇ ਫੋਨ ਤੇ ਸਟੋਰ ਕੀਤੇ ਬੁੱਕਮਾਰਕਾਂ ਨੂੰ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਡੈਟਾ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ। ਨੋਟ: ਇਹ ਅਨੁਮਤੀ ਤੀਜੀ-ਪਾਰਟੀ ਬ੍ਰਾਊਜ਼ਰਾਂ ਜਾਂ ਵੈਬ ਬ੍ਰਾਊਜ਼ਿੰਗ ਸਮਰੱਥਤਾਵਂ ਵਾਲੀਆਂ ਹੋਰਾਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"ਆਪਣੇ ਵੈੱਬ ਬੁੱਕਮਾਰਕ ਅਤੇ ਇਤਿਹਾਸ ਪੜ੍ਹੋ"</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"ਐਪ ਨੂੰ ਸਾਰੇ URL ਜਿਨ੍ਹਾਂ ਤੇ ਬ੍ਰਾਊਜ਼ਰ ਨੇ ਵਿਜਿਟ ਕੀਤਾ ਹੈ ਅਤੇ ਬ੍ਰਾਊਜ਼ਰ ਦੇ ਸਾਰੇ ਬੁੱਕਮਾਰਕਾਂ, ਦਾ ਇਤਿਹਾਸ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਨੋਟ: ਇਹ ਅਨੁਮਤੀ ਤੀਜੀ-ਪਾਰਟੀ ਬ੍ਰਾਊਜ਼ਰਾਂ ਜਾਂ ਵੈੱਬ ਬ੍ਰਾਊਜ਼ਿੰਗ ਸਮਰੱਥਾ ਵਾਲੀਆਂ ਹੋਰਾਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"ਵੈੱਬ ਬੁੱਕਮਾਰਕ ਅਤੇ ਇਤਿਹਾਸ ਲਿਖੋ"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਦਾ ਇਤਿਹਾਸ ਅਤੇ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਬੁੱਕਮਾਰਕਾਂ ਨੂੰ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਡਾਟਾ ਸਾਫ਼ ਕਰਨ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ। ਨੋਟ: ਇਹ ਇਜਾਜ਼ਤ ਤੀਜੀ-ਪਾਰਟੀ ਬ੍ਰਾਊਜ਼ਰਾਂ ਜਾਂ ਵੈੱਬ ਬ੍ਰਾਊਜ਼ਿੰਗ ਸਮਰੱਥਾ ਵਾਲੀਆਂ ਹੋਰਾਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਦਾ ਇਤਿਹਾਸ ਅਤੇ ਤੁਹਾਡੇ ਟੀਵੀ ਤੇ ਸਟੋਰ ਕੀਤੇ ਬੁੱਕਮਾਰਕਾਂ ਨੂੰ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਡਾਟਾ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ। ਨੋਟ: ਇਹ ਅਨੁਮਤੀ ਤੀਜੀ-ਪਾਰਟੀ ਬ੍ਰਾਊਜ਼ਰਾਂ ਜਾਂ ਵੈੱਬ ਬ੍ਰਾਊਜ਼ਿੰਗ ਸਮਰੱਥਾ ਵਾਲੀਆਂ ਹੋਰਾਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਦਾ ਇਤਿਹਾਸ ਅਤੇ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੇ ਸਟੋਰ ਕੀਤੇ ਬੁੱਕਮਾਰਕਾਂ ਨੂੰ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਡਾਟਾ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ। ਨੋਟ: ਇਹ ਅਨੁਮਤੀ ਤੀਜੀ-ਪਾਰਟੀ ਬ੍ਰਾਊਜ਼ਰਾਂ ਜਾਂ ਵੈੱਬ ਬ੍ਰਾਊਜ਼ਿੰਗ ਸਮਰੱਥਤਾਵਂ ਵਾਲੀਆਂ ਹੋਰਾਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"ਇੱਕ ਅਲਾਰਮ ਸੈੱਟ ਕਰੋ"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"ਐਪ ਨੂੰ ਇੱਕ ਇੰਸਟੌਲ ਕੀਤੀ ਅਲਾਰਮ ਘੜੀ ਐਪ ਵਿੱਚ ਇੱਕ ਅਲਾਰਮ ਸੈਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਕੁਝ ਅਲਾਰਮ ਘੜੀ ਐਪਲ ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਲਾਗੂ ਨਹੀਂ ਵੀ ਕਰ ਸਕਦੇ।"</string>
-    <string name="permlab_addVoicemail" msgid="5525660026090959044">"ਵੌਇਸਮੇਲ ਜੋੜੋ"</string>
-    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਵੌਇਸਮੇਲ ਇਨਬੌਕਸ ਵਿੱਚ ਸੁਨੇਹੇ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ਬ੍ਰਾਊਜ਼ਰ ਜਿਓਲੋਕੇਸ਼ਨ ਅਨੁਮਤੀਆਂ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਦੀਆਂ ਜਿਓਲੋਕੇਸ਼ਨ ਅਨੁਮਤੀਆਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਖ਼ਰਾਬ ਐਪਸ ਇਸਦੀ ਵਰਤੋਂ ਆਰਬਿਟਰੇਰੀ ਵੈਬ ਸਾਈਟਾਂ ਨੂੰ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਜਾਣਕਾਰੀ ਭੇਜਣ ਦੀ ਆਗਿਆ ਦੇਣ ਲਈ ਕਰ ਸਕਦੇ ਹਨ।"</string>
+    <string name="permlab_addVoicemail" msgid="5525660026090959044">"ਵੌਇਸਮੇਲ ਸ਼ਾਮਲ ਕਰੋ"</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਵੌਇਸਮੇਲ ਇਨਬਾਕਸ ਵਿੱਚ ਸੁਨੇਹੇ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ਬ੍ਰਾਊਜ਼ਰ ਜਿਓਲੋਕੇਸ਼ਨ ਇਜਾਜ਼ਤਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਦੀਆਂ ਜਿਓਲੋਕੇਸ਼ਨ ਅਨੁਮਤੀਆਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਖਰਾਬ ਐਪਾਂ ਇਸਦੀ ਵਰਤੋਂ ਆਰਬਿਟਰੇਰੀ ਵੈੱਬ ਸਾਈਟਾਂ ਨੂੰ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਭੇਜਣ ਦੀ ਆਗਿਆ ਦੇਣ ਲਈ ਕਰ ਸਕਦੇ ਹਨ।"</string>
     <string name="save_password_message" msgid="767344687139195790">"ਕੀ ਤੁਸੀਂ ਚਾਹੁੰਦੇ ਹੋ ਕਿ ਬ੍ਰਾਊਜ਼ਰ ਇਹ ਪਾਸਵਰਡ ਯਾਦ ਰੱਖੇ?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"ਅਜੇ ਨਹੀਂ"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"ਯਾਦ ਰੱਖੋ"</string>
@@ -858,13 +857,13 @@
     <string name="search_go" msgid="8298016669822141719">"ਖੋਜੋ"</string>
     <string name="search_hint" msgid="1733947260773056054">"ਖੋਜ…"</string>
     <string name="searchview_description_search" msgid="6749826639098512120">"ਖੋਜੋ"</string>
-    <string name="searchview_description_query" msgid="5911778593125355124">"ਸਵਾਲ ਖੋਜੋ"</string>
+    <string name="searchview_description_query" msgid="5911778593125355124">"ਖੋਜ ਪੁੱਛਗਿੱਛ"</string>
     <string name="searchview_description_clear" msgid="1330281990951833033">"ਸਵਾਲ ਹਟਾਓ"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"ਸਵਾਲ ਪ੍ਰਸਤੁਤ ਕਰੋ"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"ਵੌਇਸ ਖੋਜ"</string>
-    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"ਕੀ ਐਕਸਪਲੋਰ ਬਾਇ ਟਚ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਣਾ ਹੈ?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ਐਕਪਲੋਰ ਬਾਇ ਟਚ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਣਾ ਚਾਹੁੰਦਾ ਹੈ। ਜਦੋਂ ਐਕਸਪਲੋਰ ਬਾਇ ਟਚ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ, ਤਾਂ ਤੁਸੀਂ ਇਸ ਬਾਰੇ ਵੇਰਵੇ ਸੁਣ ਜਾਂ ਦੇਖ ਸਕਦੇ ਹੋ ਤਿ ਤੁਹਾਡੀ ਉਂਗਲੀ ਦੇ ਹੇਠਾਂ ਕੀ ਹੈ ਜਾਂ ਟੈਬਲੇਟ ਨਾਲ ਇੰਟਰੈਕਟ ਕਰਨ ਲਈ ਸੰਕੇਤ ਪਰਫੌਰਮ ਕਰ ਸਕਦੇ ਹੋ।"</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ਐਕਪਲੋਰ ਬਾਇ ਟਚ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਣਾ ਚਾਹੁੰਦਾ ਹੈ। ਜਦੋਂ ਐਕਸਪਲੋਰ ਬਾਇ ਟਚ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ, ਤਾਂ ਤੁਸੀਂ ਇਸ ਬਾਰੇ ਵੇਰਵੇ ਸੁਣ ਜਾਂ ਦੇਖ ਸਕਦੇ ਹੋ ਤਿ ਤੁਹਾਡੀ ਉਂਗਲੀ ਦੇ ਹੇਠਾਂ ਕੀ ਹੈ ਜਾਂ ਫੋਨ ਨਾਲ ਇੰਟਰੈਕਟ ਕਰਨ ਲਈ ਸੰਕੇਤ ਪਰਫੌਰਮ ਕਰ ਸਕਦੇ ਹੋ।"</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"ਕੀ ਸਪੱਰਸ਼ ਰਾਹੀਂ ਪੜਚੋਲ ਕਰੋ ਨੂੰ ਚਾਲੂ ਕਰਨਾ ਹੈ?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> \'ਸਪੱਰਸ਼ ਰਾਹੀਂ ਪੜਚੋਲ\' ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਣਾ ਚਾਹੁੰਦੀ ਹੈ। ਜਦੋਂ \'ਸਪੱਰਸ਼ ਰਾਹੀਂ ਪੜਚੋਲ\' ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ, ਤਾਂ ਤੁਸੀਂ ਇਸ ਬਾਰੇ ਵੇਰਵੇ ਸੁਣ ਜਾਂ ਦੇਖ ਸਕਦੇ ਹੋ ਕਿ ਤੁਹਾਡੀ ਉਂਗਲੀ ਦੇ ਹੇਠਾਂ ਕੀ ਹੈ ਜਾਂ ਟੈਬਲੈੱਟ ਨਾਲ ਇੰਟਰੈਕਟ ਕਰਨ ਲਈ ਸੰਕੇਤਾਂ ਦੀ ਪਾਲਣਾ ਕਰ ਸਕਦੇ ਹੋ।"</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ਸਪਰਸ਼ ਰਾਹੀਂ ਪੜਚੋਲ ਕਰੋ ਨੂੰ ਚਾਲੂ ਕਰਨਾ ਚਾਹੁੰਦਾ ਹੈ। ਜਦੋਂ ਸਪਰਸ਼ ਰਾਹੀਂ ਪੜਚੋਲ ਕਰੋ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ, ਤਾਂ ਤੁਸੀਂ ਇਸ ਬਾਰੇ ਵੇਰਵੇ ਸੁਣ ਜਾਂ ਦੇਖ ਸਕਦੇ ਹੋ ਤਿ ਤੁਹਾਡੀ ਉਂਗਲੀ ਦੇ ਹੇਠਾਂ ਕੀ ਹੈ ਜਾਂ ਫ਼ੋਨ ਨਾਲ ਇੰਟਰੈਕਟ ਕਰਨ ਲਈ ਸੰਕੇਤ ਪਰਫੌਰਮ ਕਰ ਸਕਦੇ ਹੋ।"</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 ਮਹੀਨੇ ਪਹਿਲਾਂ"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 ਮਹੀਨਾ ਪਹਿਲਾਂ ਤੋਂ ਪਹਿਲਾਂ"</string>
     <plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
@@ -954,8 +953,8 @@
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ਸਾਲ ਵਿੱਚ</item>
     </plurals>
     <string name="VideoView_error_title" msgid="3534509135438353077">"ਵੀਡੀਓ ਸਮੱਸਿਆ"</string>
-    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"ਇਹ ਵੀਡੀਓ ਇਸ ਡੀਵਾਈਸ ਤੇ ਸਟ੍ਰੀਮਿੰਗ ਲਈ ਪ੍ਰਮਾਣਿਕ ਨਹੀਂ ਹੈ।"</string>
-    <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"ਇਹ ਵੀਡੀਓ ਪਲੇ ਨਹੀਂ ਕਰ ਸਕਦਾ।"</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"ਇਹ ਵੀਡੀਓ ਇਸ ਡੀਵਾਈਸ ਤੇ ਸਟ੍ਰੀਮਿੰਗ ਲਈ ਪ੍ਰਮਾਣਕ ਨਹੀਂ ਹੈ।"</string>
+    <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"ਇਹ ਵੀਡੀਓ ਪਲੇ ਨਹੀਂ ਕਰ ਸਕਦੇ।"</string>
     <string name="VideoView_error_button" msgid="2822238215100679592">"ਠੀਕ"</string>
     <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="noon" msgid="7245353528818587908">"ਦੁਪਹਿਰ"</string>
@@ -968,7 +967,7 @@
     <string name="cut" msgid="3092569408438626261">"ਕੱਟੋ"</string>
     <string name="copy" msgid="2681946229533511987">"ਕਾਪੀ ਕਰੋ"</string>
     <string name="paste" msgid="5629880836805036433">"ਪੇਸਟ ਕਰੋ"</string>
-    <string name="paste_as_plain_text" msgid="5427792741908010675">"ਸਧਾਰਨ ਲਿਖਤ ਦੇ ਤੌਰ \'ਤੇ ਪੇਸਟ ਕਰੋ"</string>
+    <string name="paste_as_plain_text" msgid="5427792741908010675">"ਸਰਲ ਲਿਖਤ ਦੇ ਤੌਰ \'ਤੇ ਪੇਸਟ ਕਰੋ"</string>
     <string name="replace" msgid="5781686059063148930">"ਬਦਲੋ…"</string>
     <string name="delete" msgid="6098684844021697789">"ਮਿਟਾਓ"</string>
     <string name="copyUrl" msgid="2538211579596067402">"URL ਕਾਪੀ ਕਰੋ"</string>
@@ -977,17 +976,17 @@
     <string name="redo" msgid="7759464876566803888">"ਮੁੜ-ਓਹੀ ਕਰੋ"</string>
     <string name="autofill" msgid="3035779615680565188">"ਆਟੋਫਿਲ"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"ਟੈਕਸਟ ਚੋਣ"</string>
-    <string name="addToDictionary" msgid="4352161534510057874">"ਸ਼ਬਦਕੋਸ਼ ਵਿੱਚ ਜੋੜੋ"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"ਸ਼ਬਦਕੋਸ਼ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="deleteText" msgid="6979668428458199034">"ਮਿਟਾਓ"</string>
-    <string name="inputMethod" msgid="1653630062304567879">"ਇਨਪੁਟ ਵਿਧੀ"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"ਇਨਪੁੱਟ ਵਿਧੀ"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"ਟੈਕਸਟ ਕਿਰਿਆਵਾਂ"</string>
     <string name="email" msgid="4560673117055050403">"ਈਮੇਲ ਕਰੋ"</string>
     <string name="dial" msgid="4204975095406423102">"ਫ਼ੋਨ ਕਰੋ"</string>
     <string name="map" msgid="6068210738233985748">"ਨਕਸ਼ੇ"</string>
     <string name="browse" msgid="6993590095938149861">"ਬ੍ਰਾਊਜ਼ਰ"</string>
-    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"ਸਟੋਰੇਜ ਸਪੇਸ ਖ਼ਤਮ ਹੋ ਰਿਹਾ ਹੈ"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"ਸਟੋਰੇਜ ਦੀ ਜਗ੍ਹਾ ਖਤਮ ਹੋ ਰਹੀ ਹੈ"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ਕੁਝ ਸਿਸਟਮ ਫੰਕਸ਼ਨ ਕੰਮ ਨਹੀਂ ਵੀ ਕਰ ਸਕਦੇ"</string>
-    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"ਸਿਸਟਮ ਲਈ ਪੂਰੀ ਸਟੋਰੇਜ ਨਹੀਂ। ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਤੁਹਾਡੇ ਕੋਲ 250MB ਖਾਲੀ ਸਪੇਸ ਹੈ ਅਤੇ ਰੀਸਟਾਰਟ ਕਰੋ।"</string>
+    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"ਸਿਸਟਮ ਲਈ ਲੋੜੀਂਦੀ ਸਟੋਰੇਜ ਨਹੀਂ ਹੈ। ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਤੁਹਾਡੇ ਕੋਲ 250MB ਖਾਲੀ ਜਗ੍ਹਾ ਹੈ ਅਤੇ ਮੁੜ-ਚਾਲੂ ਕਰੋ।"</string>
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਚੱਲ ਰਿਹਾ ਹੈ"</string>
     <string name="app_running_notification_text" msgid="1197581823314971177">"ਹੋਰ ਜਾਣਕਾਰੀ ਜਾਂ ਐਪ ਨੂੰ ਬੰਦ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="ok" msgid="5970060430562524910">"ਠੀਕ"</string>
@@ -998,14 +997,14 @@
     <string name="loading" msgid="7933681260296021180">"ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ..."</string>
     <string name="capital_on" msgid="1544682755514494298">"ਚਾਲੂ"</string>
     <string name="capital_off" msgid="6815870386972805832">"ਬੰਦ"</string>
-    <string name="whichApplication" msgid="4533185947064773386">"ਇਸਨੂੰ ਵਰਤਦੇ ਹੋਏ ਕਿਰਿਆ ਪੂਰੀ ਕਰੋ"</string>
-    <string name="whichApplicationNamed" msgid="8260158865936942783">"%1$s ਵਰਤਦੇ ਹੋਏ ਕਿਰਿਆ ਪੂਰੀ ਕਰੋ"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"ਇਸਨੂੰ ਵਰਤਦੇ ਹੋਏ ਕਾਰਵਾਈ ਪੂਰੀ ਕਰੋ"</string>
+    <string name="whichApplicationNamed" msgid="8260158865936942783">"%1$s ਵਰਤਦੇ ਹੋਏ ਕਾਰਵਾਈ ਪੂਰੀ ਕਰੋ"</string>
     <string name="whichApplicationLabel" msgid="7425855495383818784">"ਕਾਰਵਾਈ ਪੂਰੀ ਕਰੋ"</string>
     <string name="whichViewApplication" msgid="3272778576700572102">"ਨਾਲ ਖੋਲ੍ਹੋ"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s ਨਾਲ ਖੋਲ੍ਹੋ"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"ਖੋਲ੍ਹੋ"</string>
-    <string name="whichEditApplication" msgid="144727838241402655">"ਨਾਲ ਸੰਪਾਦਿਤ ਕਰੋ"</string>
-    <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s ਨਾਲ ਸੰਪਾਦਿਤ ਕਰੋ"</string>
+    <string name="whichEditApplication" msgid="144727838241402655">"ਇਸ ਨਾਲ ਸੰਪਾਦਨ ਕਰੋ"</string>
+    <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s ਨਾਲ ਸੰਪਾਦਨ ਕਰੋ"</string>
     <string name="whichEditApplicationLabel" msgid="7183524181625290300">"ਸੰਪਾਦਨ ਕਰੋ"</string>
     <string name="whichSendApplication" msgid="6902512414057341668">"ਇਸ ਨਾਲ ਸਾਂਝਾ ਕਰੋ"</string>
     <string name="whichSendApplicationNamed" msgid="2799370240005424391">"%1$s ਨਾਲ ਸਾਂਝਾ ਕਰੋ"</string>
@@ -1019,12 +1018,12 @@
     <string name="whichImageCaptureApplication" msgid="3680261417470652882">"ਇਸ ਨਾਲ ਚਿਤਰ ਕੈਪਚਰ ਕਰੋ"</string>
     <string name="whichImageCaptureApplicationNamed" msgid="8619384150737825003">"%1$s ਨਾਲ ਚਿਤਰ ਕੈਪਚਰ ਕਰੋ"</string>
     <string name="whichImageCaptureApplicationLabel" msgid="6390303445371527066">"ਚਿਤਰ ਕੈਪਚਰ ਕਰੋ"</string>
-    <string name="alwaysUse" msgid="4583018368000610438">"ਇਸ ਕਿਰਿਆ ਲਈ ਬਾਇ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਵਰਤੋ।"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"ਇਸ ਕਾਰਵਾਈ ਲਈ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਵਰਤੋ।"</string>
     <string name="use_a_different_app" msgid="8134926230585710243">"ਇੱਕ ਵੱਖਰਾ ਖਾਤਾ ਵਰਤੋ"</string>
-    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"ਸਿਸਟਮ ਸੈਟਿੰਗਾਂ &gt; ਐਪਸ &gt; ਡਾਊਨਲੋਡ ਕੀਤਿਆਂ ਵਿੱਚ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਹਟਾਓ।"</string>
-    <string name="chooseActivity" msgid="7486876147751803333">"ਇੱਕ ਕਿਰਿਆ ਚੁਣੋ"</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"ਸਿਸਟਮ ਸੈਟਿੰਗਾਂ &gt; ਐਪਾਂ &gt; ਡਾਊਨਲੋਡ ਕੀਤਿਆਂ ਵਿੱਚ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਹਟਾਓ।"</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"ਇੱਕ ਕਾਰਵਾਈ ਚੁਣੋ"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"USB ਡੀਵਾਈਸ ਲਈ ਇੱਕ ਐਪ ਚੁਣੋ"</string>
-    <string name="noApplications" msgid="2991814273936504689">"ਕੋਈ ਐਪਸ ਇਸ ਕਿਰਿਆ ਨੂੰ ਨਹੀਂ ਕਰ ਸਕਦੇ।"</string>
+    <string name="noApplications" msgid="2991814273936504689">"ਕੋਈ ਐਪਾਂ ਇਸ ਕਾਰਵਾਈ ਨੂੰ ਨਹੀਂ ਕਰ ਸਕਦੀਆਂ।"</string>
     <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> ਰੁਕ ਗਈ ਹੈ"</string>
     <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> ਰੁਕ ਗਿਆ ਹੈ"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> ਵਾਰ-ਵਾਰ ਰੁਕ ਰਹੀ ਹੈ"</string>
@@ -1049,24 +1048,24 @@
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਅਸਲ ਵਿੱਚ ਲੌਂਚ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"ਸਕੇਲ"</string>
     <string name="screen_compat_mode_show" msgid="4013878876486655892">"ਹਮੇਸ਼ਾਂ ਦਿਖਾਓ"</string>
-    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"ਸਿਸਟਮ ਸੈਟਿੰਗਾਂ &gt; ਐਪਸ &gt; ਡਾਊਨਲੋਡ ਕੀਤਿਆਂ ਵਿੱਚ ਇਸਨੂੰ ਮੁੜ-ਸਮਰੱਥ ਬਣਾਓ।"</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"ਸਿਸਟਮ ਸੈਟਿੰਗਾਂ &gt; ਐਪਾਂ &gt; ਡਾਊਨਲੋਡ ਕੀਤਿਆਂ ਵਿੱਚ ਇਸਨੂੰ ਮੁੜ-ਸਮਰੱਥ ਬਣਾਓ।"</string>
     <string name="unsupported_display_size_message" msgid="6545327290756295232">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵਰਤਮਾਨ ਡਿਸਪਲੇ ਆਕਾਰ ਸੈਟਿੰਗ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ ਹੈ ਅਤੇ ਅਣਕਿਆਸੇ ਤੌਰ \'ਤੇ ਵਿਹਾਰ ਕਰ ਸਕਦੀ ਹੈ।"</string>
-    <string name="unsupported_display_size_show" msgid="7969129195360353041">"ਹਮੇਸ਼ਾ ਵਿਖਾਓ"</string>
-    <string name="smv_application" msgid="3307209192155442829">"ਐਪ <xliff:g id="APPLICATION">%1$s</xliff:g> (ਪ੍ਰਕਿਰਿਆ<xliff:g id="PROCESS">%2$s</xliff:g>) ਨੇ ਆਪਣੀ ਖੁਦ-ਲਾਗੂ ਕੀਤੀ ਸਟ੍ਰਿਕਟਮੋਡ ਨੀਤੀ ਦੀ ਉਲੰਘਣਾ ਕੀਤੀ ਹੈ।"</string>
+    <string name="unsupported_display_size_show" msgid="7969129195360353041">"ਹਮੇਸ਼ਾ  ਦਿਖਾਓ"</string>
+    <string name="smv_application" msgid="3307209192155442829">"ਐਪ <xliff:g id="APPLICATION">%1$s</xliff:g> (ਪ੍ਰਕਿਰਿਆ <xliff:g id="PROCESS">%2$s</xliff:g>) ਨੇ ਆਪਣੀ ਖੁਦ-ਲਾਗੂ ਕੀਤੀ ਸਟ੍ਰਿਕਟਮੋਡ ਨੀਤੀ ਦੀ ਉਲੰਘਣਾ ਕੀਤੀ ਹੈ।"</string>
     <string name="smv_process" msgid="5120397012047462446">"ਪ੍ਰਕਿਰਿਆ <xliff:g id="PROCESS">%1$s</xliff:g> ਨੇ ਆਪਣੀ ਖੁਦ-ਲਾਗੂ ਕੀਤੀ ਸਟ੍ਰਿਕਟਮੋਡ ਨੀਤੀ ਦੀ ਉਲੰਘਣਾ ਕੀਤੀ ਹੈ।"</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"Android ਅਪਗ੍ਰੇਡ ਕਰ ਰਿਹਾ ਹੈ…"</string>
     <string name="android_start_title" msgid="8418054686415318207">"Android ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ…"</string>
-    <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ਸਟੋਰੇਜ ਅਨੁਕੂਲ ਕਰ ਰਿਹਾ ਹੈ।"</string>
+    <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ਸਟੋਰੇਜ ਅਨੁਕੂਲ ਹੋ ਰਹੀ ਹੈ।"</string>
     <string name="android_upgrading_notification_title" msgid="8428357096969413169">"Android ਅੱਪਡੇਟ ਮੁਕੰਮਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
-    <string name="android_upgrading_notification_body" msgid="5761201379457064286">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਕੁਝ ਐਪਾਂ ਅੱਪਗ੍ਰੇਡ ਦੇ ਪੂਰੀ ਹੋਣ ਤੱਕ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰਨ"</string>
+    <string name="android_upgrading_notification_body" msgid="5761201379457064286">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਕੁਝ ਐਪਾਂ ਅੱਪਗ੍ਰੇਡ ਪੂਰਾ ਹੋਣ ਤੱਕ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰਨ"</string>
     <string name="app_upgrading_toast" msgid="3008139776215597053">"<xliff:g id="APPLICATION">%1$s</xliff:g> ਅੱਪਗ੍ਰੇਡ ਹੋ ਰਹੀ ਹੈ…"</string>
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> <xliff:g id="NUMBER_1">%2$d</xliff:g> ਦਾ ਐਪ ਅਨੁਕੂਲ ਕਰ ਰਿਹਾ ਹੈ।"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> ਤਿਆਰ ਕਰ ਰਿਹਾ ਹੈ।"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ਐਪਸ ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ।"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"ਬੂਟ ਪੂਰਾ ਕਰ ਰਿਹਾ ਹੈ।"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> ਚੱਲ ਰਿਹਾ ਹੈ"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"ਵਾਪਸ ਐਪ \'ਤੇ ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"ਕੀ ਐਪਸ ਸਵਿਚ ਕਰਨੇ ਹਨ?"</string>
+    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"ਵਾਪਸ ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"ਕੀ ਐਪਾਂ \'ਤੇ ਸਵਿੱਚ ਕਰਨਾ ਹੈ?"</string>
     <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"ਦੂਜਾ ਐਪ ਪਹਿਲਾਂ ਹੀ ਚੱਲ ਰਿਹਾ ਹੈ, ਜਿਸਨੂੰ ਤੁਹਾਡੇ ਵੱਲੋਂ ਇੱਕ ਨਵਾਂ ਐਪ ਚਾਲੂ ਕਰ ਸਕਣ ਤੋਂ ਪਹਿਲਾਂ ਹੀ ਰੋਕਿਆ ਜਾਣਾ ਚਾਹੀਦਾ ਹੈ।"</string>
     <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> ਤੇ ਵਾਪਸ ਜਾਓ"</string>
     <string name="old_app_description" msgid="2082094275580358049">"ਨਵਾਂ ਐਪ ਚਾਲੂ ਨਾ ਕਰੋ।"</string>
@@ -1075,20 +1074,20 @@
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ਦੀ ਮੈਮਰੀ ਸੀਮਾ ਵਧ ਗਈ ਹੈ"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"ਹੀਪ ਡੰਪ ਇਕੱਤਰ ਕੀਤਾ ਗਿਆ; ਸਾਂਝਾ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ਕੀ ਹੀਪ ਡੰਪ ਸ਼ੇਅਰ ਕਰਨਾ ਹੈ?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"ਪ੍ਰਕਿਰਿਆ <xliff:g id="PROC">%1$s</xliff:g> ਦੀ ਆਪਣੀ ਪ੍ਰਕਿਰਿਆ ਮੈਮਰੀ ਸੀਮਾ<xliff:g id="SIZE">%2$s</xliff:g> ਵਧ ਗਈ ਹੈ। ਇਸਦੇ ਵਿਕਾਸਕਾਰ ਨਾਲ ਸ਼ੇਅਰ ਕਰਨ ਲਈ ਤੁਹਾਡੇ ਲਈ ਇੱਕ ਹੀਪ ਡੰਪ ਉਪਲਬਧ ਹੈ। ਸਾਵਧਾਨ ਰਹੋ: ਇਸ ਹੀਪ ਡੰਪ ਵਿੱਚ ਤੁਹਾਡੀ ਕੋਈ ਵੀ ਨਿੱਜੀ ਜਾਣਕਾਰੀ ਹੋ ਸਕਦੀ ਹੈ, ਜਿਸਤੇ ਐਪਲੀਕੇਸ਼ਨ ਦੀ ਪਹੁੰਚ ਹੈ।"</string>
-    <string name="sendText" msgid="5209874571959469142">"ਟੈਕਸਟ ਲਈ ਇੱਕ ਕਿਰਿਆ ਚੁਣੋ"</string>
+    <string name="dump_heap_text" msgid="4809417337240334941">"ਪ੍ਰਕਿਰਿਆ <xliff:g id="PROC">%1$s</xliff:g> ਦੀ ਆਪਣੀ ਪ੍ਰਕਿਰਿਆ ਮੈਮਰੀ ਸੀਮਾ <xliff:g id="SIZE">%2$s</xliff:g> ਵਧ ਗਈ ਹੈ। ਇਸਦੇ ਵਿਕਾਸਕਾਰ ਨਾਲ ਸਾਂਝਾ ਕਰਨ ਲਈ ਤੁਹਾਡੇ ਲਈ ਇੱਕ ਹੀਪ ਡੰਪ ਉਪਲਬਧ ਹੈ। ਸਾਵਧਾਨ ਰਹੋ: ਇਸ ਹੀਪ ਡੰਪ ਵਿੱਚ ਤੁਹਾਡੀ ਕੋਈ ਵੀ ਨਿੱਜੀ ਜਾਣਕਾਰੀ ਹੋ ਸਕਦੀ ਹੈ, ਜਿਸ \'ਤੇ ਐਪਲੀਕੇਸ਼ਨ ਦੀ ਪਹੁੰਚ ਹੈ।"</string>
+    <string name="sendText" msgid="5209874571959469142">"ਲਿਖਤ ਲਈ ਕੋਈ ਕਾਰਵਾਈ ਚੁਣੋ"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"ਰਿੰਗਰ ਵੌਲਿਊਮ"</string>
     <string name="volume_music" msgid="5421651157138628171">"ਮੀਡੀਆ ਵੌਲਿਊਮ"</string>
     <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Bluetooth ਰਾਹੀਂ ਪਲੇ ਕਰ ਰਿਹਾ ਹੈ"</string>
     <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"ਖਾਮੋਸ਼ ਰਿੰਗਟੋਨ ਸੈੱਟ ਕੀਤੀ"</string>
-    <string name="volume_call" msgid="3941680041282788711">"ਇਨ-ਕਾਲ ਵੌਲਿਊਮ"</string>
-    <string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetooth ਇਨ-ਕਾਲ ਵੌਲਿਊਮ"</string>
+    <string name="volume_call" msgid="3941680041282788711">"ਇਨ-ਕਾਲ ਅਵਾਜ਼"</string>
+    <string name="volume_bluetooth_call" msgid="2002891926351151534">"ਬਲੂਟੁੱਥ ਇਨ-ਕਾਲ ਅਵਾਜ਼"</string>
     <string name="volume_alarm" msgid="1985191616042689100">"ਅਲਾਰਮ ਵੌਲਿਊਮ"</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_incall" msgid="8890073218154543397">"ਕਾਲ ਅਵਾਜ਼"</string>
     <string name="volume_icon_description_media" msgid="4217311719665194215">"ਮੀਡੀਆ ਵੌਲਿਊਮ"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"ਸੂਚਨਾ ਵੌਲਿਊਮ"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਰਿੰਗਟੋਨ"</string>
@@ -1099,39 +1098,46 @@
     <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"ਸੂਚਨਾ ਧੁਨੀਆਂ"</string>
     <string name="ringtone_unknown" msgid="3914515995813061520">"ਅਗਿਆਤ"</string>
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
-      <item quantity="one">Wi-Fi ਨੈੱਟਵਰਕਸ ਉਪਲਬਧ</item>
-      <item quantity="other">Wi-Fi ਨੈੱਟਵਰਕਸ ਉਪਲਬਧ</item>
+      <item quantity="one">ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਉਪਲਬਧ</item>
+      <item quantity="other">ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਉਪਲਬਧ</item>
     </plurals>
     <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
-      <item quantity="one">ਉਪਲਬਧ Wi-Fi ਨੈੱਟਵਰਕ ਖੋਲ੍ਹੋ</item>
-      <item quantity="other">ਉਪਲਬਧ Wi-Fi ਨੈੱਟਵਰਕ ਖੋਲ੍ਹੋ</item>
+      <item quantity="one">ਉਪਲਬਧ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਖੋਲ੍ਹੋ</item>
+      <item quantity="other">ਉਪਲਬਧ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਖੋਲ੍ਹੋ</item>
     </plurals>
-    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ਨੈੱਟਵਰਕ ਵਿੱਚ ਸਾਈਨ ਇਨ ਕਰੋ"</string>
-    <string name="network_available_sign_in" msgid="1848877297365446605">"ਨੈੱਟਵਰਕ ਤੇ ਸਾਈਨ ਇਨ ਕਰੋ"</string>
+    <string name="wifi_available_title" msgid="3817100557900599505">"ਖੁੱਲ੍ਹੇ ਵਾਈ‑ਫਾਈ ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਹੋਵੋ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ਖੁੱਲ੍ਹੇ ਵਾਈ‑ਫਾਈ ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"ਵਾਈ‑ਫਾਈ ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ਵਾਈ‑ਫਾਈ ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ਸਾਰੇ ਨੈੱਟਵਰਕਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ਕਨੈਕਟ ਕਰੋ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ਸਾਰੇ ਨੈੱਟਵਰਕ"</string>
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8451173622563841546">"Wi-Fi ਦੀ ਕੋਈ ਇੰਟਰਨੈਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
+    <string name="wifi_no_internet" msgid="8451173622563841546">"ਵਾਈ-ਫਾਈ ਦੀ ਕੋਈ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"ਵਿਕਲਪਾਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="network_switch_metered" msgid="4671730921726992671">"ਬਦਲਕੇ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ਲਿਆਂਦਾ ਗਿਆ"</string>
     <string name="network_switch_metered_detail" msgid="5325661434777870353">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ਦੀ ਇੰਟਰਨੈੱਟ \'ਤੇ ਪਹੁੰਚ ਨਾ ਹੋਣ \'ਤੇ ਡੀਵਾਈਸ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ। ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ।"</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ਤੋਂ ਬਦਲਕੇ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> \'ਤੇ ਕੀਤਾ ਗਿਆ"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="3979506840912951943">"ਮੋਬਾਈਲ ਡੈਟਾ"</item>
-    <item msgid="75483255295529161">"Wi-Fi"</item>
+    <item msgid="3979506840912951943">"ਮੋਬਾਈਲ ਡਾਟਾ"</item>
+    <item msgid="75483255295529161">"ਵਾਈ-ਫਾਈ"</item>
     <item msgid="6862614801537202646">"ਬਲੂਟੁੱਥ"</item>
     <item msgid="5447331121797802871">"ਈਥਰਨੈੱਟ"</item>
     <item msgid="8257233890381651999">"VPN"</item>
   </string-array>
     <string name="network_switch_type_name_unknown" msgid="4552612897806660656">"ਇੱਕ ਅਗਿਆਤ ਨੈੱਟਵਰਕ ਕਿਸਮ"</string>
-    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕਰ ਸਕਿਆ"</string>
-    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ਇਸਦਾ ਇੱਕ ਖ਼ਰਾਬ ਇੰਟਰਨੈਟ ਕਨੈਕਸ਼ਨ ਹੈ।"</string>
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"ਵਾਈ-ਫਾਈ ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਹੋ ਸਕਿਆ"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ਇਸਦਾ ਇੱਕ ਖਰਾਬ ਇੰਟਰਨੈੱਟ ਕਨੈਕਸ਼ਨ ਹੈ।"</string>
     <string name="wifi_connect_alert_title" msgid="8455846016001810172">"ਕੀ ਕਨੈਕਸ਼ਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
-    <string name="wifi_connect_alert_message" msgid="6451273376815958922">"ਐਪਲੀਕੇਸ਼ਨ %1$s Wifi ਨੈੱਟਵਰਕ %2$s ਨਾਲ ਕਨੈਕਟ ਕਰਨਾ ਚਾਹੁੰਦਾ ਹੈ"</string>
+    <string name="wifi_connect_alert_message" msgid="6451273376815958922">"ਐਪਲੀਕੇਸ਼ਨ %1$s ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ %2$s ਨਾਲ ਕਨੈਕਟ ਕਰਨਾ ਚਾਹੁੰਦੀ ਹੈ"</string>
     <string name="wifi_connect_default_application" msgid="7143109390475484319">"ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ"</string>
-    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi ਡਾਇਰੈਕਟ"</string>
-    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi ਡਾਇਰੈਕਟ ਚਾਲੂ ਕਰੋ। ਇਹ Wi-Fi ਕਲਾਈਂਟ/ਹੌਟਸਪੌਟ ਨੂੰ ਬੰਦ ਕਰ ਦੇਵੇਗਾ।"</string>
-    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi ਡਾਇਰੈਕਟ ਚਾਲੂ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string>
-    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi ਡਾਇਰੈਕਟ ਚਾਲੂ ਹੈ।"</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"ਵਾਈ-ਫਾਈ ਡਾਇਰੈਕਟ"</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi ਡਾਇਰੈਕਟ ਚਾਲੂ ਕਰੋ। ਇਹ ਵਾਈ-ਫਾਈ ਕਲਾਇੰਟ/ਹੌਟਸਪੌਟ ਨੂੰ ਬੰਦ ਕਰ ਦੇਵੇਗਾ।"</string>
+    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"ਵਾਈ-ਫਾਈ ਡਾਇਰੈਕਟ ਚਾਲੂ ਨਹੀਂ ਹੋ ਸਕਿਆ।"</string>
+    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"ਵਾਈ-ਫਾਈ ਡਾਇਰੈਕਟ ਚਾਲੂ ਹੈ।"</string>
     <string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"ਸੈਟਿੰਗਾਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="accept" msgid="1645267259272829559">"ਸਵੀਕਾਰ ਕਰੋ"</string>
     <string name="decline" msgid="2112225451706137894">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
@@ -1141,30 +1147,30 @@
     <string name="wifi_p2p_to_message" msgid="248968974522044099">"ਵੱਲ:"</string>
     <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"ਲੋੜੀਂਦਾ ਪਿੰਨ ਟਾਈਪ ਕਰੋ:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"ਪਿੰਨ:"</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"ਟੈਬਲੇਟ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ ਤੇ Wi-Fi ਤੋਂ ਅਸਥਾਈ ਤੌਰ ਤੇ ਡਿਸਕਨੈਕਟ ਹੋ ਜਾਏਗੀ"</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"TV <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ ਤੇ Wi-Fi ਤੋਂ ਅਸਥਾਈ ਤੌਰ ਤੇ ਡਿਸਕਨੈਕਟ ਹੋ ਜਾਏਗਾ"</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ਫੋਨ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ ਤੇ Wi-Fi ਤੋਂ ਅਸਥਾਈ ਤੌਰ ਤੇ ਡਿਸਕਨੈਕਟ ਹੋ ਜਾਏਗਾ"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"ਟੈਬਲੈੱਟ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ ਤੇ ਵਾਈ-ਫਾਈ ਤੋਂ ਅਸਥਾਈ ਤੌਰ ਤੇ ਡਿਸਕਨੈਕਟ ਹੋ ਜਾਵੇਗਾ"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"TV <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ ਤੇ ਵਾਈ-ਫਾਈ ਤੋਂ ਅਸਥਾਈ ਤੌਰ ਤੇ ਡਿਸਕਨੈਕਟ ਹੋ ਜਾਏਗਾ"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ਫ਼ੋਨ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ ਤੇ ਵਾਈ-ਫਾਈ ਤੋਂ ਅਸਥਾਈ ਤੌਰ ਤੇ ਡਿਸਕਨੈਕਟ ਹੋ ਜਾਏਗਾ"</string>
     <string name="select_character" msgid="3365550120617701745">"ਅੱਖਰ ਦਾਖਲ ਕਰੋ"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"SMS ਸੁਨੇਹੇ ਭੇਜ ਰਿਹਾ ਹੈ"</string>
     <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਵੱਡੀ ਸੰਖਿਆ ਵਿੱਚ SMS ਸੁਨੇਹੇ ਭੇਜ ਰਿਹਾ ਹੈ। ਕੀ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ ਸੁਨੇਹੇ ਭੇਜਣਾ ਜਾਰੀ ਰੱਖਣ ਦੀ ਆਗਿਆ ਦੇਣਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
     <string name="sms_control_yes" msgid="3663725993855816807">"ਆਗਿਆ ਦਿਓ"</string>
     <string name="sms_control_no" msgid="625438561395534982">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
-    <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਇਹ &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; ਨੂੰ ਇੱਕ ਸੁਨੇਹਾ ਭੇਜਣਾ ਚਾਹੁੰਦਾ ਹੈ।"</string>
-    <string name="sms_short_code_details" msgid="5873295990846059400">"ਇਸ ਨਾਲ "<b>"ਤੁਹਾਡੇ ਮੋਬਾਈਲ ਖਾਤੇ ਤੇ ਖ਼ਰਚੇ"</b>" ਪੈ ਸਕਦੇ ਹਨ।"</string>
-    <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"ਇਸ ਨਾਲ ਤੁਹਾਡੇ ਮੋਬਾਈਲ ਖਾਤੇ ਤੇ ਖ਼ਰਚੇ ਪੈਣਗੇ।"</b></string>
+    <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਇਹ &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; ਨੂੰ ਇੱਕ ਸੁਨੇਹਾ ਭੇਜਣਾ ਚਾਹੁੰਦੀ ਹੈ।"</string>
+    <string name="sms_short_code_details" msgid="5873295990846059400">"ਇਸ ਨਾਲ "<b>"ਤੁਹਾਡੇ ਮੋਬਾਈਲ ਖਾਤੇ ਤੇ ਖਰਚੇ"</b>" ਪੈ ਸਕਦੇ ਹਨ।"</string>
+    <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"ਇਸ ਨਾਲ ਤੁਹਾਡੇ ਮੋਬਾਈਲ ਖਾਤੇ ਤੇ ਖਰਚੇ ਪੈਣਗੇ।"</b></string>
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"ਭੇਜੋ"</string>
     <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"ਰੱਦ ਕਰੋ"</string>
     <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"ਮੇਰੀ ਚੋਣ ਯਾਦ ਰੱਖੋ"</string>
-    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"ਤੁਸੀਂ ਇਸਨੂੰ ਬਾਅਦ ਵਿੱਚ ਸੈਟਿੰਗਾਂ &gt; ਐਪਸ ਵਿੱਚ ਬਦਲ ਸਕਦੇ ਹੋ"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"ਤੁਸੀਂ ਇਸਨੂੰ ਬਾਅਦ ਵਿੱਚ ਸੈਟਿੰਗਾਂ &gt; ਐਪਾਂ ਵਿੱਚ ਬਦਲ ਸਕਦੇ ਹੋ"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"ਹਮੇਸ਼ਾਂ ਆਗਿਆ ਦਿਓ"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"ਕਦੇ ਵੀ ਆਗਿਆ ਨਾ ਦਿਓ"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"SIM ਕਾਰਡ ਹਟਾਇਆ ਗਿਆ"</string>
-    <string name="sim_removed_message" msgid="2333164559970958645">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਅਣਉਪਲਬਧ ਹੋਵੇਗਾ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਇੱਕ ਪ੍ਰਮਾਣਿਕ SIM ਕਾਰਡ ਪਾ ਕੇ ਰੀਸਟਾਰਟ ਨਹੀਂ ਕਰਦੇ।"</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਅਣਉਪਲਬਧ ਹੋਵੇਗਾ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਇੱਕ ਵੈਧ ਸਿਮ ਕਾਰਡ ਪਾ ਕੇ ਮੁੜ-ਚਾਲੂ ਨਹੀਂ ਕਰਦੇ।"</string>
     <string name="sim_done_button" msgid="827949989369963775">"ਹੋ ਗਿਆ"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"SIM ਕਾਰਡ ਜੋੜਿਆ ਗਿਆ"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਤੱਕ ਪਹੁੰਚ ਲਈ ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਮੁੜ-ਚਾਲੂ ਕਰੋ।"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"ਰੀਸਟਾਰਟ ਕਰੋ"</string>
-    <string name="carrier_app_dialog_message" msgid="7066156088266319533">"ਤੁਹਾਡੀ ਨਵੀਂ SIM ਦੇ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਕਰਨ ਲਈ, ਤੁਹਾਨੂੰ ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਤੋਂ ਇੱਕ ਐਪ ਸਥਾਪਤ ਕਰਨ ਅਤੇ ਖੋਲ੍ਹਣ ਦੀ ਲੋੜ ਪਵੇਗੀ।"</string>
+    <string name="carrier_app_dialog_message" msgid="7066156088266319533">"ਤੁਹਾਡੀ ਨਵੀਂ ਸਿਮ ਦੇ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਕਰਨ ਲਈ, ਤੁਹਾਨੂੰ ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਤੋਂ ਇੱਕ ਐਪ ਸਥਾਪਤ ਕਰਨ ਅਤੇ ਖੋਲ੍ਹਣ ਦੀ ਲੋੜ ਪਵੇਗੀ।"</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"ਐਪ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
     <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"ਅਜੇ ਨਹੀਂ"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"ਨਵੀਂ SIM ਦਾਖਲ ਕੀਤੀ ਗਈ"</string>
@@ -1176,7 +1182,7 @@
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"ਨਵਾਂ: "</font></string>
     <string name="perms_description_app" msgid="5139836143293299417">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਮੁਹੱਈਆ ਕੀਤਾ।"</string>
     <string name="no_permissions" msgid="7283357728219338112">"ਕੋਈ ਅਨੁਮਤੀਆਂ ਲੁੜੀਂਦੀਆਂ ਨਹੀਂ"</string>
-    <string name="perm_costs_money" msgid="4902470324142151116">"ਇਸ ਨਾਲ ਤੁਹਾਨੂੰ ਖ਼ਰਚਾ ਪੈ ਸਕਦਾ ਹੈ"</string>
+    <string name="perm_costs_money" msgid="4902470324142151116">"ਇਸ ਨਾਲ ਤੁਹਾਨੂੰ ਖਰਚਾ ਪੈ ਸਕਦਾ ਹੈ"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"ਠੀਕ"</string>
     <string name="usb_charging_notification_title" msgid="6895185153353640787">"ਇਹ ਡੀਵਾਈਸ USB ਰਾਹੀਂ ਚਾਰਜ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="usb_supplying_notification_title" msgid="5310642257296510271">"ਨੱਥੀ ਕੀਤੇ ਡੀਵਾਈਸ ਨੂੰ USB ਰਾਹੀਂ ਪਾਵਰ ਮਿਲ ਰਹੀ ਹੈ"</string>
@@ -1185,8 +1191,10 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI ਲਈ USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"ਇੱਕ USB ਐਕਸੈਸਰੀ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"ਐਨਾਲੌਗ  ਆਡੀਓ  ਉਪਸਾਧਨ ਦਾ ਪਤਾ ਲੱਗਿਆ"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"ਨੱਥੀ ਕੀਤਾ ਡੀਵਾਈਸ ਇਸ ਫ਼ੋਨ ਦੇ ਅਨੁਰੂਪ ਨਹੀਂ ਹੈ। ਹੋਰ ਜਾਣਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ਡੀਬਗਿੰਗ ਕਨੈਕਟ ਕੀਤੀ"</string>
-    <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ਡੀਬੱਗਿੰਗ ਨੂੰ ਅਯੋਗ ਬਣਾਉਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+    <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ਡੀਬੱਗਿੰਗ ਬੰਦ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ਡੀਬੱਗਿੰਗ ਅਯੋਗ ਬਣਾਉਣ ਲਈ ਚੁਣੋ।"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ਬੱਗ ਰਿਪਰੋਟ ਪ੍ਰਾਪਤ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ਕੀ ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕਰਨੀ ਹੈ?"</string>
@@ -1196,15 +1204,15 @@
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ਕੀ-ਬੋਰਡ ਬਦਲੋ"</string>
     <string name="show_ime" msgid="2506087537466597099">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡ ਸਰਗਰਮ ਹੋਣ ਦੌਰਾਨ ਇਸ ਨੂੰ ਸਕ੍ਰੀਨ \'ਤੇ ਬਣਾਈ ਰੱਖੋ"</string>
-    <string name="hardware" msgid="194658061510127999">"ਆਭਾਸੀ ਕੀ-ਬੋਰਡ ਵਿਖਾਓ"</string>
-    <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡ ਦਾ ਸੰਰੂਪਣ ਕਰੋ"</string>
+    <string name="hardware" msgid="194658061510127999">"ਆਭਾਸੀ ਕੀ-ਬੋਰਡ  ਦਿਖਾਓ"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡ ਦੀ ਰੂਪ-ਰੇਖਾ ਬਦਲੋ"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ਭਾਸ਼ਾ ਅਤੇ ਖਾਕਾ ਚੁਣਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"ਦੂਜੀਆਂ ਐਪਾਂ ਦੇ ਉੱਪਰ ਪ੍ਰਦਰਸ਼ਿਤ ਕਰੋ"</string>
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> ਐਪ ਹੋਰ ਐਪਾਂ ਦੇ ਉੱਤੇ ਹੈ"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ਐਪ ਹੋਰਾਂ ਐਪਾਂ ਦੇ ਉੱਤੇ ਹੈ।"</string>
-    <string name="alert_windows_notification_message" msgid="8917232109522912560">"ਜੇ ਤੁਸੀਂ ਨਹੀਂ ਚਾਹੁੰਦੇ ਕਿ <xliff:g id="NAME">%s</xliff:g> ਐਪ ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਦੀ ਵਰਤੋਂ ਕਰੇ, ਤਾਂ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹਣ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਇਸਨੂੰ ਬੰਦ ਕਰੋ।"</string>
+    <string name="alert_windows_notification_message" msgid="8917232109522912560">"ਜੇਕਰ ਤੁਸੀਂ ਨਹੀਂ ਚਾਹੁੰਦੇ ਕਿ <xliff:g id="NAME">%s</xliff:g> ਐਪ ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਦੀ ਵਰਤੋਂ ਕਰੇ, ਤਾਂ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹਣ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਇਸਨੂੰ ਬੰਦ ਕਰੋ।"</string>
     <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ਬੰਦ ਕਰੋ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> ਤਿਆਰ ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"ਤਰੁੱਟੀਆਂ ਦੀ ਜਾਂਚ ਕਰ ਰਿਹਾ ਹੈ"</string>
@@ -1214,10 +1222,10 @@
     <string name="ext_media_unmountable_notification_message" msgid="2343202057122495773">"<xliff:g id="NAME">%s</xliff:g> ਗ਼ਲਤ ਹੈ। ਠੀਕ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> ਖਰਾਬ ਹੈ। ਠੀਕ ਕਰਨ ਲਈ ਚੁਣੋ।"</string>
     <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"ਅਸਮਰਥਿਤ <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"ਇਹ ਡੀਵਾਈਸ ਇਸ <xliff:g id="NAME">%s</xliff:g> ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦਾ ਹੈ। ਕਿਸੇ ਸਮਰਥਿਤ ਫੌਰਮੈਟ ਵਿੱਚ ਸਥਾਪਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"ਇਹ ਡੀਵਾਈਸ ਇਸ <xliff:g id="NAME">%s</xliff:g> ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦਾ ਹੈ। ਕਿਸੇ ਸਮਰਥਿਤ ਵੰਨਗੀ ਵਿੱਚ ਸਥਾਪਤ ਕਰਨ ਲਈ ਚੁਣੋ।"</string>
+    <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"ਇਹ ਡੀਵਾਈਸ ਇਸ <xliff:g id="NAME">%s</xliff:g> ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦਾ ਹੈ। ਕਿਸੇ ਸਮਰਥਿਤ ਫਾਰਮੈਟ ਵਿੱਚ ਸਥਾਪਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"ਇਹ ਡੀਵਾਈਸ ਇਸ <xliff:g id="NAME">%s</xliff:g> ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦਾ ਹੈ। ਕਿਸੇ ਸਮਰਥਿਤ ਫਾਰਮੈਟ ਵਿੱਚ ਸਥਾਪਤ ਕਰਨ ਲਈ ਚੁਣੋ।"</string>
     <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> ਨੂੰ ਅਚਨਚੇਤ ਹਟਾਇਆ ਗਿਆ"</string>
-    <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"ਡੇਟਾ ਦੇ ਨੁਕਸਾਨ ਤੋਂ ਬੱਚਣ ਲਈ ਹਟਾਉਣ ਤੋਂ ਪਹਿਲਾਂ <xliff:g id="NAME">%s</xliff:g> ਅਨਮਾਊਂਟ ਕਰੋ"</string>
+    <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">" ਡਾਟਾ  ਦੇ ਨੁਕਸਾਨ ਤੋਂ ਬੱਚਣ ਲਈ ਹਟਾਉਣ ਤੋਂ ਪਹਿਲਾਂ <xliff:g id="NAME">%s</xliff:g> ਅਨਮਾਊਂਟ ਕਰੋ"</string>
     <string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"ਹਟਾਇਆ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_nomedia_notification_message" msgid="6471542972147056586">"<xliff:g id="NAME">%s</xliff:g> ਨੂੰ ਹਟਾਇਆ ਗਿਆ, ਕੋਈ ਨਵਾਂ ਸੰਮਿਲਿਤ ਕਰੋ"</string>
     <string name="ext_media_unmounting_notification_title" msgid="640674168454809372">"ਅਜੇ ਵੀ <xliff:g id="NAME">%s</xliff:g> ਨੂੰ ਕੱਢ ਰਿਹਾ ਹੈ..."</string>
@@ -1228,11 +1236,11 @@
     <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ਲਾਪਤਾ"</string>
     <string name="ext_media_missing_message" msgid="5761133583368750174">"ਇਸ ਡੀਵਾਈਸ ਨੂੰ ਮੁੜ ਸੰਮਿਲਿਤ ਕਰੋ"</string>
     <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> ਮੂਵ ਕਰ ਰਿਹਾ ਹੈ"</string>
-    <string name="ext_media_move_title" msgid="1022809140035962662">"ਡੇਟਾ ਮੂਵ ਕਰ ਰਿਹਾ ਹੈ"</string>
+    <string name="ext_media_move_title" msgid="1022809140035962662">" ਡਾਟਾ  ਮੂਵ ਕਰ ਰਿਹਾ ਹੈ"</string>
     <string name="ext_media_move_success_title" msgid="8575300932957954671">"ਮੂਵ ਸੰਪੂਰਣ"</string>
-    <string name="ext_media_move_success_message" msgid="4199002148206265426">"ਡੇਟਾ ਨੂੰ <xliff:g id="NAME">%s</xliff:g> ਵਿੱਚ ਮੂਵ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="ext_media_move_failure_title" msgid="7613189040358789908">"ਡੇਟਾ ਨੂੰ ਮੂਵ ਨਹੀਂ ਕਰ ਸਕਿਆ"</string>
-    <string name="ext_media_move_failure_message" msgid="1978096440816403360">"ਡੇਟਾ ਮੂਲ ਸਥਾਨ \'ਤੇ ਛੱਡਿਆ ਗਿਆ"</string>
+    <string name="ext_media_move_success_message" msgid="4199002148206265426">" ਡਾਟਾ  ਨੂੰ <xliff:g id="NAME">%s</xliff:g> ਵਿੱਚ ਮੂਵ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="ext_media_move_failure_title" msgid="7613189040358789908">" ਡਾਟਾ  ਨੂੰ ਮੂਵ ਨਹੀਂ ਕਰ ਸਕਿਆ"</string>
+    <string name="ext_media_move_failure_message" msgid="1978096440816403360">" ਡਾਟਾ  ਮੂਲ ਸਥਾਨ \'ਤੇ ਛੱਡਿਆ ਗਿਆ"</string>
     <string name="ext_media_status_removed" msgid="6576172423185918739">"ਹਟਾਏ ਗਏ"</string>
     <string name="ext_media_status_unmounted" msgid="2551560878416417752">"ਹਟਾਇਆ ਗਿਆ"</string>
     <string name="ext_media_status_checking" msgid="6193921557423194949">"ਜਾਂਚ ਕਰ ਰਿਹਾ ਹੈ..."</string>
@@ -1247,16 +1255,16 @@
     <string name="activity_list_empty" msgid="1675388330786841066">"ਕੋਈ ਮੇਲ ਖਾਂਦੀਆਂ ਗਤੀਵਿਧੀਆਂ ਨਹੀਂ ਮਿਲੀਆਂ।"</string>
     <string name="permlab_route_media_output" msgid="6243022988998972085">"ਰੂਟ ਮੀਡੀਆ ਆਊਟਪੁਟ"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ ਨੂੂੰ ਹੋਰਾਂ ਬਾਹਰੀ ਡਿਵਾਈਸਾਂ ਲਈ ਮੀਡੀਆ ਆਊਟਪੁਟ ਰੂਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_readInstallSessions" msgid="3713753067455750349">"ਸਥਾਪਿਤ ਸੈਸ਼ਨਾਂ ਨੂੰ ਪੜ੍ਹੋ"</string>
-    <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਇੰਸਟੌਲ ਸੈਸ਼ਨ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਇਸਨੂੰ ਸਕਿਰਿਆ ਪੈਕੇਜ ਇੰਸਟੌਲੇਸ਼ਨਾਂ ਬਾਰੇ ਵੇਰਵੇ ਦੇਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_requestInstallPackages" msgid="5782013576218172577">"ਪੈਕੇਜ ਸਥਾਪਿਤ ਕਰਨ ਦੀ ਬੇਨਤੀ ਕਰੋ"</string>
-    <string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"ਪੈਕੇਜ ਦੀ ਸਥਾਪਨਾ ਦੀ ਬੇਨਤੀ ਕਰਨ ਲਈ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਅਨੁਮਤੀ ਦਿੰਦਾ ਹੈ"</string>
+    <string name="permlab_readInstallSessions" msgid="3713753067455750349">"ਸਥਾਪਤ ਸੈਸ਼ਨਾਂ ਨੂੰ ਪੜ੍ਹੋ"</string>
+    <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਸਥਾਪਤ ਸੈਸ਼ਨ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਇਸਨੂੰ ਕਿਰਿਆਸ਼ੀਲ ਪੈਕੇਜ ਸਥਾਪਨਾਵਾਂ ਬਾਰੇ ਵੇਰਵੇ ਦੇਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_requestInstallPackages" msgid="5782013576218172577">"ਪੈਕੇਜ ਸਥਾਪਤ ਕਰਨ ਦੀ ਬੇਨਤੀ ਕਰੋ"</string>
+    <string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"ਪੈਕੇਜ ਦੀ ਸਥਾਪਨਾ ਦੀ ਬੇਨਤੀ ਕਰਨ ਲਈ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਆਗਿਆ ਦਿੰਦਾ ਹੈ"</string>
     <string name="permlab_requestDeletePackages" msgid="1703686454657781242">"ਪੈਕੇਜਾਂ ਨੂੰ ਮਿਟਾਉਣ ਦੀ ਬੇਨਤੀ ਕਰੋ"</string>
-    <string name="permdesc_requestDeletePackages" msgid="3406172963097595270">"ਕਿਸੇ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਪੈਕੇਜਾਂ ਨੂੰ ਮਿਟਾਉਣ ਦੀ ਬੇਨਤੀ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦੀ ਹੈ।"</string>
+    <string name="permdesc_requestDeletePackages" msgid="3406172963097595270">"ਕਿਸੇ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਪੈਕੇਜਾਂ ਨੂੰ ਮਿਟਾਉਣ ਦੀ ਬੇਨਤੀ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
     <string name="permlab_requestIgnoreBatteryOptimizations" msgid="8021256345643918264">"ਬੈਟਰੀ ਸੁਯੋਗਤਾਵਾਂ ਨੂੰ ਅਣਡਿੱਠ ਕਰਨ ਲਈ ਪੁੱਛੋ"</string>
     <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="8359147856007447638">"ਕਿਸੇ ਐਪ ਨੂੰ ਉਸ ਵਾਸਤੇ ਬੈਟਰੀ ਸੁਯੋਗਤਾਵਾਂ ਨੂੰ ਅਣਡਿੱਠ ਕਰਨ ਲਈ ਇਜਾਜ਼ਤ ਵਾਸਤੇ ਪੁੱਛਣ ਲਈ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"ਜ਼ੂਮ ਕੰਟਰੋਲ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ"</string>
-    <string name="gadget_host_error_inflating" msgid="4882004314906466162">"ਵਿਜੇਟ ਨਹੀਂ ਜੋੜ ਸਕਿਆ।"</string>
+    <string name="gadget_host_error_inflating" msgid="4882004314906466162">"ਵਿਜੇਟ ਸ਼ਾਮਲ ਨਹੀਂ ਹੋ ਸਕਿਆ।"</string>
     <string name="ime_action_go" msgid="8320845651737369027">"ਜਾਓ"</string>
     <string name="ime_action_search" msgid="658110271822807811">"ਖੋਜੋ"</string>
     <string name="ime_action_send" msgid="2316166556349314424">"ਭੇਜੋ"</string>
@@ -1266,16 +1274,16 @@
     <string name="ime_action_default" msgid="2840921885558045721">"ਐਗਜੀਕਿਊਟ ਕਰੋ"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"<xliff:g id="NUMBER">%s</xliff:g> ਵਰਤਦੇ ਹੋਏ ਨੰਬਰ\n ਡਾਇਲ ਕਰੋ"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g> ਵਰਤਦੇ ਹੋਏ \nਸੰਪਰਕ ਬਣਾਓ"</string>
-    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"ਇਹ ਇੱਕ ਜਾਂ ਹੋਰ ਐਪਸ ਹੁਣ ਅਤੇ ਭਵਿੱਖ ਵਿੱਚ, ਤੁਹਾਡੇ ਖਾਤੇ ਤੱਕ ਪਹੁੰਚ ਦੀ ਅਨੁਮਤੀ ਦੀ ਬੇਨਤੀ ਕਰਦੇ ਹਨ।"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"ਇਹ ਇੱਕ ਜਾਂ ਹੋਰ ਐਪਾਂ ਹੁਣ ਅਤੇ ਭਵਿੱਖ ਵਿੱਚ, ਤੁਹਾਡੇ ਖਾਤੇ ਤੱਕ ਪਹੁੰਚ ਦੀ ਇਜਾਜ਼ਤ ਦੀ ਬੇਨਤੀ ਕਰਦੇ ਹਨ।"</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"ਕੀ ਤੁਸੀਂ ਇਹ ਬੇਨਤੀ ਮਨਜ਼ੂਰ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"ਪਹੁੰਚ ਬੇਨਤੀ"</string>
     <string name="allow" msgid="7225948811296386551">"ਆਗਿਆ ਦਿਓ"</string>
     <string name="deny" msgid="2081879885755434506">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"ਅਨੁਮਤੀ ਦੀ ਬੇਨਤੀ ਕੀਤੀ"</string>
     <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"<xliff:g id="ACCOUNT">%s</xliff:g> ਖਾਤੇ ਲਈ ਅਨੁਮਤੀ ਦੀ ਬੇਨਤੀ ਕੀਤੀ\n।"</string>
-    <string name="forward_intent_to_owner" msgid="1207197447013960896">"ਤੁਸੀਂ ਇਹ ਐਪ ਆਪਣੀ ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਦੇ ਬਾਹਰ ਵਰਤ ਰਹੇ ਹੋ"</string>
-    <string name="forward_intent_to_work" msgid="621480743856004612">"ਤੁਸੀਂ ਇਹ ਐਪ ਆਪਣੀ ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ ਵਰਤ ਰਹੇ ਹੋ"</string>
-    <string name="input_method_binding_label" msgid="1283557179944992649">"ਇਨਪੁਟ ਵਿਧੀ"</string>
+    <string name="forward_intent_to_owner" msgid="1207197447013960896">"ਤੁਸੀਂ ਇਹ ਐਪ ਆਪਣੀ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਦੇ ਬਾਹਰ ਵਰਤ ਰਹੇ ਹੋ"</string>
+    <string name="forward_intent_to_work" msgid="621480743856004612">"ਤੁਸੀਂ ਇਹ ਐਪ ਆਪਣੀ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ ਵਰਤ ਰਹੇ ਹੋ"</string>
+    <string name="input_method_binding_label" msgid="1283557179944992649">"ਇਨਪੁੱਟ ਵਿਧੀ"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"ਸਿੰਕ ਕਰੋ"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"ਪਹੁੰਚਯੋਗਤਾ"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"ਵਾਲਪੇਪਰ"</string>
@@ -1290,19 +1298,17 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ। ਨੈੱਟਵਰਕ ਦੇ ਪ੍ਰਬੰਧਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"ਹਮੇਸ਼ਾਂ-ਚਾਲੂ VPN ਕਨੈਕਟ ਕਰ ਰਿਹਾ ਹੈ..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"ਹਮੇਸ਼ਾਂ-ਚਾਲੂ VPN ਕਨੈਕਟ ਕੀਤਾ"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"ਹਮੇਸ਼ਾ-ਚਾਲੂ VPN ਡਿਸਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"ਹਮੇਸ਼ਾਂ-ਚਾਲੂ VPN ਤੋਂ ਡਿਸਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"ਹਮੇਸ਼ਾਂ-ਚਾਲੂ VPN ਅਸ਼ੁੱਧੀ"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"ਸਥਾਪਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Change network or VPN settings"</string>
     <string name="upload_file" msgid="2897957172366730416">"ਫਾਈਲ ਚੁਣੋ"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"ਕੋਈ ਫਾਈਲ ਨਹੀਂ ਚੁਣੀ ਗਈ"</string>
     <string name="reset" msgid="2448168080964209908">"ਰੀਸੈੱਟ ਕਰੋ"</string>
     <string name="submit" msgid="1602335572089911941">"ਪ੍ਰਸਤੁਤ ਕਰੋ"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"ਕਾਰ ਮੋਡ ਸਮਰਥਿਤ"</string>
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"ਕਾਰ ਮੋਡ ਤੋਂ ਬਾਹਰ ਜਾਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ਟੀਥਰਿਗ ਜਾਂ ਹੌਟਸਪੌਟ ਸਕਿਰਿਆ"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"ਟੈਦਰਿੰਗ ਜਾਂ ਹੌਟਸਪੌਟ ਕਿਰਿਆਸ਼ੀਲ"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"ਸਥਾਪਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ਟੈਦਰਿੰਗ ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ਪਿੱਛੇ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ਅੱਗੇ"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ਛੱਡੋ"</string>
@@ -1317,7 +1323,7 @@
     <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD ਕਾਰਡ ਮਿਟਾ ਰਿਹਾ ਹੈ…"</string>
     <string name="share" msgid="1778686618230011964">"ਸਾਂਝਾ ਕਰੋ"</string>
     <string name="find" msgid="4808270900322985960">"ਲੱਭੋ"</string>
-    <string name="websearch" msgid="4337157977400211589">"ਵੈਬ ਖੋਜ"</string>
+    <string name="websearch" msgid="4337157977400211589">"ਵੈੱਬ ਖੋਜ"</string>
     <string name="find_next" msgid="5742124618942193978">"ਅਗਲਾ ਲੱਭੋ"</string>
     <string name="find_previous" msgid="2196723669388360506">"ਪਿਛਲਾ ਲੱਭੋ"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> ਵੱਲੋਂ ਟਿਕਾਣਾ ਬੇਨਤੀ"</string>
@@ -1328,7 +1334,7 @@
     <string name="sync_too_many_deletes" msgid="5296321850662746890">"ਵਧੀ ਸੀਮਾ ਮਿਟਾਓ"</string>
     <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, ਖਾਤੇ <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> ਲਈ <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> ਆਈਟਮਾਂ ਮਿਟਾਈਆਂ ਗਈਆਂ ਹਨ। ਤੁਸੀਂ ਕੀ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
     <string name="sync_really_delete" msgid="2572600103122596243">"ਆਈਟਮਾਂ ਹਟਾਓ"</string>
-    <string name="sync_undo_deletes" msgid="2941317360600338602">"ਮਿਟਾਏ ਗਏ ਅਨਡੂ ਕਰੋ"</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="add_account_label" msgid="2935267344849993553">"ਇੱਕ ਖਾਤਾ ਸ਼ਾਮਲ ਕਰੋ"</string>
@@ -1356,42 +1362,42 @@
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"ਮਿਟਾਓ"</string>
     <string name="keyboardview_keycode_done" msgid="1992571118466679775">"ਹੋ ਗਿਆ"</string>
     <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ਮੋਡ ਬਦਲੋ"</string>
-    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"ਸ਼ਿਫ਼ਟ"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"ਸ਼ਿਫਟ ਕੁੰਜੀ"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"ਦਾਖਲ ਕਰੋ"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"ਇੱਕ ਐਪ ਚੁਣੋ"</string>
-    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ਨੂੰ ਲੌਂਚ ਨਹੀਂ ਕਰ ਸਕਿਆ"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ਨੂੰ ਲਾਂਚ ਨਹੀਂ ਕਰ ਸਕਿਆ"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"ਇਸ ਨਾਲ ਸਾਂਝਾ ਕਰੋ"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ਨਾਲ ਸਾਂਝਾ ਕਰੋ"</string>
-    <string name="content_description_sliding_handle" msgid="415975056159262248">"ਹੈਂਡਲ ਸਲਾਈਡ ਕਰ ਰਿਹਾ ਹੈ। ਸਪੱਰਸ਼ ਕਰੋ &amp; ਹੋਲਡ ਕਰੋ।"</string>
-    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"ਅਨਲੌਕ ਕਰਨ ਲਈ ਸਵਾਈਪ ਕਰੋ।"</string>
-    <string name="action_bar_home_description" msgid="5293600496601490216">"ਹੋਮ ਨੈਵੀਗੇਟ ਕਰੋ"</string>
-    <string name="action_bar_up_description" msgid="2237496562952152589">"ਉੱਪਰ ਨੈਵੀਗੇਟ ਕਰੋ"</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"ਹੈਂਡਲ ਸਲਾਈਡ ਕਰ ਰਿਹਾ ਹੈ। ਛੋਹਵੋ &amp; ਹੋਲਡ ਕਰੋ।"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਸਵਾਈਪ ਕਰੋ।"</string>
+    <string name="action_bar_home_description" msgid="5293600496601490216">"ਹੋਮ \'ਤੇ ਜਾਓ"</string>
+    <string name="action_bar_up_description" msgid="2237496562952152589">"ਉੱਪਰ ਜਾਓ"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"ਹੋਰ ਚੋਣਾਂ"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <string name="storage_internal" msgid="3570990907910199483">"ਅੰਦਰੂਨੀ ਸਾਂਝੀ ਕੀਤੀ ਗਈ ਸਟੋਰੇਜ"</string>
+    <string name="storage_internal" msgid="3570990907910199483">"ਅੰਦਰੂਨੀ ਸਾਂਝੀ ਕੀਤੀ ਸਟੋਰੇਜ"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD ਕਾਰਡ"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD ਕਾਰਡ"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB ਡ੍ਰਾਇਵ"</string>
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB ਡ੍ਰਾਇਵ"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB ਸਟੋਰੇਜ"</string>
-    <string name="extract_edit_menu_button" msgid="8940478730496610137">"ਸੰਪਾਦਿਤ ਕਰੋ"</string>
-    <string name="data_usage_warning_title" msgid="3620440638180218181">"ਡੈਟਾ ਵਰਤੋਂ ਚੇਤਾਵਨੀ"</string>
-    <string name="data_usage_warning_body" msgid="6660692274311972007">"ਵਰਤੋਂ ਅਤੇ ਸੈਟਿੰਗਾਂ ਨੂੰ ਵੇਖਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"2G-3G ਡੈਟਾ ਸੀਮਾ ਪੂਰੀ ਹੋ ਗਈ"</string>
-    <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"4G ਡੈਟਾ ਸੀਮਾ ਪੂਰੀ ਹੋਈ"</string>
-    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"ਮੋਬਾਈਲ ਡੈਟਾ ਸੀਮਾ ਸਮਾਪਤ ਹੋਈ"</string>
-    <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Wi-Fi ਡੈਟਾ ਸੀਮਾ ਪੂਰੀ ਹੋ ਗਈ"</string>
-    <string name="data_usage_limit_body" msgid="291731708279614081">"ਬਾਕੀ ਸਾਇਕਲ ਲਈ ਡੈਟਾ ਰੁਕ ਗਿਆ"</string>
-    <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G ਡੈਟਾ ਸੀਮਾ ਵਧ ਗਈ"</string>
-    <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G ਡੈਟਾ ਸੀਮਾ ਵਧੀ"</string>
-    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"ਮੋਬਾਈਲ ਡੈਟਾ ਦੀ ਸੀਮਾ ਵਧ ਗਈ"</string>
-    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi ਡੈਟਾ ਸੀਮਾ ਵਧ ਗਈ"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"ਸੰਪਾਦਨ ਕਰੋ"</string>
+    <string name="data_usage_warning_title" msgid="3620440638180218181">" ਡਾਟਾ  ਵਰਤੋਂ  ਚਿਤਾਵਨੀ"</string>
+    <string name="data_usage_warning_body" msgid="6660692274311972007">"ਵਰਤੋਂ ਅਤੇ ਸੈਟਿੰਗਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+    <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"2G-3G ਡਾਟਾ ਸੀਮਾ ਪੂਰੀ ਹੋ ਗਈ"</string>
+    <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"4G  ਡਾਟਾ  ਸੀਮਾ ਪੂਰੀ ਹੋਈ"</string>
+    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"ਮੋਬਾਈਲ ਡਾਟਾ ਸੀਮਾ ਸਮਾਪਤ ਹੋਈ"</string>
+    <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"ਵਾਈ-ਫਾਈ ਡਾਟਾ ਸੀਮਾ ਪੂਰੀ ਹੋ ਗਈ"</string>
+    <string name="data_usage_limit_body" msgid="291731708279614081">"ਬਾਕੀ ਸਾਇਕਲ ਲਈ  ਡਾਟਾ  ਰੁਕ ਗਿਆ"</string>
+    <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G ਡਾਟਾ ਸੀਮਾ ਵਧ ਗਈ"</string>
+    <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G  ਡਾਟਾ  ਸੀਮਾ ਵਧੀ"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"ਮੋਬਾਈਲ ਡਾਟਾ ਦੀ ਸੀਮਾ ਵਧ ਗਈ"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"ਵਾਈ-ਫਾਈ ਡਾਟਾ ਸੀਮਾ ਵਧ ਗਈ"</string>
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> ਤੋਂ ਵੱਧ ਨਿਰਦਿਸ਼ਟ ਸੀਮਾ।"</string>
-    <string name="data_usage_restricted_title" msgid="5965157361036321914">"ਪਿਛੋਕੜ ਡੈਟਾ ਪ੍ਰਤਿਬੰਧਿਤ"</string>
-    <string name="data_usage_restricted_body" msgid="469866376337242726">"ਪਾਬੰੰਦੀ ਹਟਾਉਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="ssl_certificate" msgid="6510040486049237639">"ਸੁਰੱਖਿਆ ਸਰਟੀਫਿਕੇਟ"</string>
-    <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"ਇਹ ਸਰਟੀਫਿਕੇਟ ਪ੍ਰਮਾਣਿਕ ਹੈ।"</string>
+    <string name="data_usage_restricted_title" msgid="5965157361036321914">"ਪਿਛੋਕੜ  ਡਾਟਾ  ਪ੍ਰਤਿਬੰਧਿਤ"</string>
+    <string name="data_usage_restricted_body" msgid="469866376337242726">"ਪਾਬੰਦੀ ਹਟਾਉਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+    <string name="ssl_certificate" msgid="6510040486049237639">"ਸੁਰੱਖਿਆ ਪ੍ਰਮਾਣ-ਪੱਤਰ"</string>
+    <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"ਇਹ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਵੈਧ ਹੈ।"</string>
     <string name="issued_to" msgid="454239480274921032">"ਨੂੰ ਜਾਰੀ ਕੀਤਾ ਗਿਆ:"</string>
     <string name="common_name" msgid="2233209299434172646">"ਕੌਮਨ ਨਾਮ:"</string>
     <string name="org_name" msgid="6973561190762085236">"ਕੰਪਨੀ:"</string>
@@ -1408,20 +1414,20 @@
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"ਗਤੀਵਿਧੀ ਚੁਣੋ"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"ਇਸ ਨਾਲ ਸਾਂਝਾ ਕਰੋ"</string>
     <string name="sending" msgid="3245653681008218030">"ਭੇਜ ਰਿਹਾ ਹੈ..."</string>
-    <string name="launchBrowserDefault" msgid="2057951947297614725">"ਕੀ ਬ੍ਰਾਊਜ਼ਰ ਲੌਂਚ ਕਰਨਾ ਹੈ?"</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"ਕੀ ਬ੍ਰਾਊਜ਼ਰ ਲਾਂਚ ਕਰਨਾ ਹੈ?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"ਕੀ ਕਾਲ ਸਵੀਕਾਰ ਕਰਨੀ ਹੈ?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"ਹਮੇਸ਼ਾਂ"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"ਕੇਵਲ ਇੱਕ ਵਾਰ"</string>
-    <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
-    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"ਟੈਬਲੇਟ"</string>
+    <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"ਟੈਬਲੈੱਟ"</string>
     <string name="default_audio_route_name" product="tv" msgid="9158088547603019321">"TV"</string>
-    <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"ਫੋਨ"</string>
-    <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"ਹੈਡਫੋਨ"</string>
+    <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"ਫ਼ੋਨ ਕਰੋ"</string>
+    <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"ਹੈੱਡਫ਼ੋਨ"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"ਡੌਕ ਸਪੀਕਰਸ"</string>
     <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"ਸਿਸਟਮ"</string>
-    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth ਔਡੀਓ"</string>
-    <string name="wireless_display_route_description" msgid="9070346425023979651">"ਵਾਇਰਲੈਸ ਡਿਸਪਲੇ"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth  ਆਡੀਓ"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ"</string>
     <string name="media_route_button_content_description" msgid="591703006349356016">"ਪ੍ਰਸਾਰਿਤ ਕਰੋ"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"ਡੀਵਾਈਸ ਨਾਲ ਕਨੈਕਟ ਕਰੋ"</string>
     <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"ਡੀਵਾਈਸ ਨਾਲ ਸਕ੍ਰੀਨ ਜੋੜੋ"</string>
@@ -1440,47 +1446,47 @@
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ਸੁਰੱਖਿਅਤ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ਪੈਟਰਨ ਭੁੱਲ ਗਏ"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ਗ਼ਲਤ ਪੈਟਰਨ"</string>
-    <string name="kg_wrong_password" msgid="2333281762128113157">"ਗ਼ਲਤ ਪਾਸਵਰਡ"</string>
-    <string name="kg_wrong_pin" msgid="1131306510833563801">"ਗ਼ਲਤ ਪਿੰਨ"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"ਗਲਤ ਪਾਸਵਰਡ"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"ਗਲਤ ਪਿੰਨ"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"ਆਪਣਾ ਪੈਟਰਨ ਡ੍ਰਾ ਕਰੋ"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"ਸਿਮ ਪਿੰਨ ਦਾਖਲ ਕਰੋ"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"ਪਿੰਨ ਦਾਖਲ ਕਰੋ"</string>
     <string name="kg_password_instructions" msgid="5753646556186936819">"ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ"</string>
-    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM ਹੁਣ ਅਸਮਰਥਿਤ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
-    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"ਲੋੜੀਂਦਾ ਪਿੰਨ ਕੋਡ ਦਾਖਲ ਕਰੋ"</string>
-    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"ਲੋੜੀਂਦੇ ਪਿੰਨ ਕੋਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string>
-    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM ਕਾਰਡ ਅਨਲੌਕ ਕਰ ਰਿਹਾ ਹੈ…"</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_puk_enter_puk_hint" msgid="453227143861735537">"ਸਿਮ ਹੁਣ ਬੰਦ ਕੀਤਾ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"ਇੱਛਤ ਪਿੰਨ ਕੋਡ ਦਾਖਲ ਕਰੋ"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"ਇੱਛਤ ਪਿੰਨ ਕੋਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM ਕਾਰਡ ਅਣਲਾਕ ਕਰ ਰਿਹਾ ਹੈ…"</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">"PUK ਕੋਡ 8 ਸੰਖਿਆਵਾਂ ਦਾ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।"</string>
-    <string name="kg_invalid_puk" msgid="3638289409676051243">"ਲਹੀ PUK ਕੋਡ ਮੁੜ-ਦਾਖਲ ਕਰੋ। ਦੁਹਰਾਈਆਂ ਗਈਆਂ ਕੋਸ਼ਿਸ਼ਾਂ SIM ਨੂੰ ਸਥਾਈ ਤੌਰ ਤੇ ਅਸਮਰੱਥ ਬਣਾ ਦੇਵੇਗਾ।"</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>
-    <string name="kg_login_instructions" msgid="1100551261265506448">"ਅਨਲੌਕ ਕਰਨ ਲਈ, ਆਪਣੇ Google ਖਾਤੇ ਨਾਲ ਸਾਈਨ ਇਨ ਕਰੋ।"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"ਅਣਲਾਕ ਕਰਨ ਲਈ, ਆਪਣੇ Google ਖਾਤੇ ਨਾਲ ਸਾਈਨ-ਇਨ ਕਰੋ।"</string>
     <string name="kg_login_username_hint" msgid="5718534272070920364">"ਵਰਤੋਂਕਾਰ ਨਾਮ (ਈਮੇਲ)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"ਪਾਸਵਰਡ"</string>
-    <string name="kg_login_submit_button" msgid="5355904582674054702">"ਸਾਈਨ ਇਨ ਕਰੋ"</string>
-    <string name="kg_login_invalid_input" msgid="5754664119319872197">"ਅਪ੍ਰਮਾਣਿਕ ਵਰਤੋਂਕਾਰ ਨਾਮ ਜਾਂ ਪਾਸਵਰਡ।"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"ਅਵੈਧ ਵਰਤੋਂਕਾਰ ਨਾਮ ਜਾਂ ਪਾਸਵਰਡ।"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਵਰਤੋਂਕਾਰ ਨਾਮ ਜਾਂ ਪਾਸਵਰਡ ਭੁੱਲ ਗਏ ਹੋ?\n"<b>"google.com/accounts/recovery"</b>" ਤੇ ਜਾਓ।"</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"ਖਾਤੇ ਦੀ ਜਾਂਚ ਕਰ ਰਿਹਾ ਹੈ…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ਤੁਸੀਂ ਆਪਣਾ ਪਿੰਨ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਪਾਸਵਰਡ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਟੈਬਲੇਟ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗੀ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, TV ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ਤੁਸੀਂ <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="2072996269148483637">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਟੈਬਲੇਟ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗੀ।"</string>
-    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ TV ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਫੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਫੋਨ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"ਤੁਸੀਂ <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="tv" msgid="4224651132862313471">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ TV ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ਤੁਸੀਂ <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_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ਤੁਸੀਂ ਆਪਣਾ ਪਿੰਨ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਪਾਸਵਰਡ ਗਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ।\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਉਲੀਕਿਆ ਹੈ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਟੈਬਲੈੱਟ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਵੇਗਾ ਅਤੇ ਸਾਰਾ ਵਰਤੋਂਕਾਰ ਡਾਟਾ ਨਸ਼ਟ ਹੋ ਜਾਵੇਗਾ।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੀਵੀ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਟੀਵੀ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਵਰਤੋਂਕਾਰ ਡਾਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ਤੁਸੀਂ <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="2072996269148483637">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਟੈਬਲੈੱਟ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਵੇਗਾ।"</string>
+    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੀਵੀ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਟੀਵੀ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਫ਼ੋਨ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"ਤੁਸੀਂ <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="tv" msgid="4224651132862313471">"ਤੁਸੀਂ <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="1437638152015574839">"ਤੁਸੀਂ <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_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"ਹਟਾਓ"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"ਕੀ ਵੌਲਿਊਮ ਸਿਫਾਰਿਸ਼ ਕੀਤੇ ਪੱਧਰ ਤੋਂ ਵਧਾਉਣੀ ਹੈ?\n\nਲੰਮੇ ਸਮੇਂ ਤੱਕ ਉੱਚ ਵੌਲਿਊਮ ਤੇ ਸੁਣਨ ਨਾਲ ਤੁਹਾਡੀ ਸੁਣਨ ਸ਼ਕਤੀ ਨੂੰ ਨੁਕਸਾਨ ਪਹੁੰਚ ਸਕਦਾ ਹੈ।"</string>
-    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਵਰਤੀਏ?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"ਸ਼ਾਰਟਕੱਟ ਚਾਲੂ ਹੋਣ \'ਤੇ, ਕਿਸੇ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਵੌਲਿਊਮ ਬਟਨਾਂ ਨੂੰ 3 ਸਕਿੰਟ ਲਈ ਦਬਾ ਕੇ ਰੱਖੋ।\n\n ਵਰਤਮਾਨ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾ:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ਤੁਸੀਂ ਸੈਟਿੰਗਾਂ &gt; ਪਹੁੰਚਯੋਗਤਾ ਵਿੱਚ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਬਦਲ ਸਕਦੇ ਹੋ।"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"ਕੀ ਵੌਲਿਊਮ  ਸਿਫ਼ਾਰਸ਼  ਕੀਤੇ ਪੱਧਰ ਤੋਂ ਵਧਾਉਣੀ ਹੈ?\n\nਲੰਮੇ ਸਮੇਂ ਤੱਕ ਉੱਚ ਵੌਲਿਊਮ ਤੇ ਸੁਣਨ ਨਾਲ ਤੁਹਾਡੀ ਸੁਣਨ ਸ਼ਕਤੀ ਨੂੰ ਨੁਕਸਾਨ ਪਹੁੰਚ ਸਕਦਾ ਹੈ।"</string>
+    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"ਕੀ ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਵਰਤਣਾ ਹੈ?"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"ਸ਼ਾਰਟਕੱਟ ਚਾਲੂ ਹੋਣ \'ਤੇ, ਕਿਸੇ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਅਵਾਜ਼ ਬਟਨਾਂ ਨੂੰ 3 ਸਕਿੰਟ ਲਈ ਦਬਾ ਕੇ ਰੱਖੋ।\n\n ਵਰਤਮਾਨ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾ:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ਤੁਸੀਂ ਸੈਟਿੰਗਾਂ &gt; ਪਹੁੰਚਯੋਗਤਾ ਵਿੱਚ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਬਦਲ ਸਕਦੇ ਹੋ।"</string>
     <string name="disable_accessibility_shortcut" msgid="627625354248453445">"ਸ਼ਾਰਟਕੱਟ ਬੰਦ ਕਰੋ"</string>
     <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਨੇ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕੀਤਾ"</string>
@@ -1494,7 +1500,7 @@
     <string name="owner_name" msgid="2716755460376028154">"ਮਾਲਕ"</string>
     <string name="error_message_title" msgid="4510373083082500195">"ਅਸ਼ੁੱਧੀ"</string>
     <string name="error_message_change_not_allowed" msgid="1238035947357923497">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਇਸ ਤਬਦੀਲੀ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
-    <string name="app_not_found" msgid="3429141853498927379">"ਇਸ ਕਿਰਿਆ ਨੂੰ ਸੰਭਾਲਣ ਲਈ ਕੋਈ ਐਪਲੀਕੇਸ਼ਨ ਨਹੀਂ ਮਿਲੀ।"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"ਇਸ ਕਾਰਵਾਈ ਨੂੰ ਸੰਭਾਲਣ ਲਈ ਕੋਈ ਐਪਲੀਕੇਸ਼ਨ ਨਹੀਂ ਮਿਲੀ।"</string>
     <string name="revoke" msgid="5404479185228271586">"ਰੱਦ ਕਰੋ"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
     <string name="mediasize_iso_a1" msgid="3333060421529791786">"ISO A1"</string>
@@ -1535,9 +1541,9 @@
     <string name="mediasize_na_junior_legal" msgid="3309324162155085904">"ਜੂਨੀਅਰ ਕਨੂੰਨੀ"</string>
     <string name="mediasize_na_ledger" msgid="5567030340509075333">"ਖਾਤਾ"</string>
     <string name="mediasize_na_tabloid" msgid="4571735038501661757">"ਪੱਤਰਕਾ"</string>
-    <string name="mediasize_na_index_3x5" msgid="5182901917818625126">"ਇੰਡੈਕਸ ਕਾਰਡ 3x5"</string>
-    <string name="mediasize_na_index_4x6" msgid="7687620625422312396">"ਇੰਡੈਕਸ ਕਾਰਡ 4x6"</string>
-    <string name="mediasize_na_index_5x8" msgid="8834215284646872800">"ਇੰਡੈਕਸ ਕਾਰਡ 5x8"</string>
+    <string name="mediasize_na_index_3x5" msgid="5182901917818625126">"ਕ੍ਰਮ-ਸੂਚੀ ਕਾਰਡ 3x5"</string>
+    <string name="mediasize_na_index_4x6" msgid="7687620625422312396">"ਕ੍ਰਮ-ਸੂਚੀ ਕਾਰਡ 4x6"</string>
+    <string name="mediasize_na_index_5x8" msgid="8834215284646872800">"ਕ੍ਰਮ-ਸੂਚੀ ਕਾਰਡ 5x8"</string>
     <string name="mediasize_na_monarch" msgid="213639906956550754">"ਸਮਰਾਟ"</string>
     <string name="mediasize_na_quarto" msgid="835778493593023223">"ਚੁਪੱਤਰੀ"</string>
     <string name="mediasize_na_foolscap" msgid="1573911237983677138">"Foolscap"</string>
@@ -1577,14 +1583,14 @@
     <string name="mediasize_japanese_kahu" msgid="6872696027560065173">"Kahu"</string>
     <string name="mediasize_japanese_kaku2" msgid="2359077233775455405">"Kaku2"</string>
     <string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string>
-    <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"ਅਗਿਆਤ ਤਸਵੀਰ"</string>
+    <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"ਅਗਿਆਤ ਪੋਰਟਰੇਟ"</string>
     <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"ਅਗਿਆਤ ਲੈਂਡਸਕੇਪ"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ਰੱਦ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"ਸਮੱਗਰੀ ਲਿਖਣ ਵਿੱਚ ਅਸ਼ੁੱਧੀ"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"ਸਮੱਗਰੀ ਲਿਖਣ ਵਿੱਚ ਗੜਬੜ"</string>
     <string name="reason_unknown" msgid="6048913880184628119">"ਅਗਿਆਤ"</string>
     <string name="reason_service_unavailable" msgid="7824008732243903268">"ਪ੍ਰਿੰਟ ਸੇਵਾ ਸਮਰਥਿਤ ਨਹੀਂ"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> ਸੇਵਾ ਇੰਸਟੌਲ ਕੀਤੀ"</string>
-    <string name="print_service_installed_message" msgid="5897362931070459152">"ਸਮਰੱਥ ਬਣਾਉਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="print_service_installed_message" msgid="5897362931070459152">"ਚਾਲੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"ਪ੍ਰਸ਼ਾਸਕ ਪਿੰਨ ਦਾਖਲ ਕਰੋ"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"ਪਿੰਨ ਦਾਖਲ ਕਰੋ"</string>
     <string name="restr_pin_incorrect" msgid="8571512003955077924">"ਗ਼ਲਤ"</string>
@@ -1599,8 +1605,8 @@
       <item quantity="other"> <xliff:g id="COUNT">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="immersive_cling_title" msgid="8394201622932303336">"ਪੂਰੀ ਸਕ੍ਰੀਨ ਦੇਖ ਰਿਹਾ ਹੈ"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"ਬਾਹਰ ਜਾਣ ਲਈ, ਟੌਪ ਤੋਂ ਹੇਠਾਂ ਸਵਾਈਪ ਕਰੋ।"</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"ਪੂਰੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦੇਖੋ"</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"ਬਾਹਰ ਜਾਣ ਲਈ, ਉਪਰੋਂ ਹੇਠਾਂ ਸਵਾਈਪ ਕਰੋ।"</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"ਸਮਝ ਲਿਆ"</string>
     <string name="done_label" msgid="2093726099505892398">"ਹੋ ਗਿਆ"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"ਘੰਟੇ ਸਰਕੁਲਰ ਸਲਾਈਡਰ"</string>
@@ -1618,13 +1624,13 @@
     <string name="lock_to_app_start" msgid="6643342070839862795">"ਸਕ੍ਰੀਨ ਪਿੰਨ ਕੀਤੀ"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"ਸਕ੍ਰੀਨ ਅਨਪਿਨ ਕੀਤੀ"</string>
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਿੰਨ ਮੰਗੋ"</string>
-    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ਅਨਪਿਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਅਨਲੌਕ ਪੈਟਰਨ ਵਾਸਤੇ ਪੁੱਛੋ"</string>
-    <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ਅਨਪਿਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string>
+    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਅਣਲਾਕ ਪੈਟਰਨ ਵਾਸਤੇ ਪੁੱਛੋ"</string>
+    <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string>
     <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" msgid="1960431123816253034">"ਬੈਟਰੀ ਲਾਈਫ਼ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਵਿੱਚ ਸਹਾਇਤਾ ਕਰਨ ਲਈ, ਬੈਟਰੀ ਸੇਵਰ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਦਰਸ਼ਨ ਘਟਾਉਂਦਾ ਹੈ ਅਤੇ ਵਾਈਬ੍ਰੇਸ਼ਨ, ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਅਤੇ ਜ਼ਿਆਦਾਤਰ ਪਿਛੋਕੜ ਡਾਟੇ ਨੂੰ ਸੀਮਿਤ ਕਰਦਾ ਹੈ। ਈਮੇਲ, ਸੁਨੇਹਾ ਭੇਜਣ ਅਤੇ ਹੋਰ ਐਪਾਂ, ਜੋ ਸਮਕਾਲੀਕਰਨ \'ਤੇ ਨਿਰਭਰ ਹਨ, ਉਹ ਉਦੋਂ ਤੱਕ ਅੱਪਡੇਟ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਉਹਨਾਂ ਨੂੰ ਖੋਲ੍ਹਦੇ ਨਹੀਂ।\n\nਬੈਟਰੀ ਸੇਵਰ ਆਪਣੇ-ਆਪ ਬੰਦ ਹੁੰਦਾ ਹੈ ਜਦੋਂ ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੁੰਦਾ ਹੈ।"</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"ਡਾਟਾ ਵਰਤੋਂ ਘਟਾਉਣ ਵਿੱਚ ਮਦਦ ਲਈ, ਡਾਟਾ ਸੇਵਰ ਕੁਝ ਐਪਾਂ ਨੂੰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਡਾਟਾ ਭੇਜਣ ਜਾਂ ਪ੍ਰਾਪਤ ਕਰਨ ਤੋਂ ਰੋਕਦਾ ਹੈ। ਤੁਹਾਡੇ ਵੱਲੋਂ ਵਰਤਮਾਨ ਤੌਰ \'ਤੇ ਵਰਤੀ ਜਾ ਰਹੀ ਐਪ ਡਾਟੇ \'ਤੇ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ, ਪਰ ਉਹ ਇੰਝ ਕਦੇ-ਕਦਾਈਂ ਕਰ ਸਕਦੀ ਹੈ। ਉਦਾਹਰਨ ਲਈ, ਇਸ ਦਾ ਮਤਲਬ ਇਹ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਚਿੱਤਰ ਤਦ ਤੱਕ ਨਹੀਂ ਦਿਖਾਏ ਜਾਂਦੇ, ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਉਹਨਾਂ \'ਤੇ ਟੈਪ ਨਹੀਂ ਕਰਦੇ।"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"ਬੈਟਰੀ ਲਾਈਫ਼ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਵਿੱਚ ਸਹਾਇਤਾ ਕਰਨ ਲਈ, ਬੈਟਰੀ ਸੇਵਰ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਦਰਸ਼ਨ ਘਟਾਉਂਦਾ ਹੈ ਅਤੇ ਵਾਈਬ੍ਰੇਸ਼ਨ, ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਅਤੇ ਜ਼ਿਆਦਾਤਰ ਬੈਕਗ੍ਰਾਊਂਡ ਡਾਟੇ ਨੂੰ ਸੀਮਿਤ ਕਰਦਾ ਹੈ। ਈਮੇਲ, ਸੁਨੇਹਾ ਭੇਜਣ ਅਤੇ ਹੋਰ ਐਪਾਂ, ਜੋ ਸਮਕਾਲੀਕਰਨ \'ਤੇ ਨਿਰਭਰ ਹਨ, ਉਹ ਉਦੋਂ ਤੱਕ ਅੱਪਡੇਟ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਉਹਨਾਂ ਨੂੰ ਖੋਲ੍ਹਦੇ ਨਹੀਂ।\n\nਬੈਟਰੀ ਸੇਵਰ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਬੰਦ ਹੁੰਦਾ ਹੈ ਜਦੋਂ ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੁੰਦਾ ਹੈ।"</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"ਡਾਟਾ ਵਰਤੋਂ ਘਟਾਉਣ ਵਿੱਚ ਮਦਦ ਲਈ, ਡਾਟਾ ਸੇਵਰ ਕੁਝ ਐਪਾਂ ਨੂੰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਡਾਟਾ ਭੇਜਣ ਜਾਂ ਪ੍ਰਾਪਤ ਕਰਨ ਤੋਂ ਰੋਕਦਾ ਹੈ। ਤੁਹਾਡੇ ਵੱਲੋਂ ਵਰਤਮਾਨ ਤੌਰ \'ਤੇ ਵਰਤੀ ਜਾ ਰਹੀ ਐਪ ਡਾਟਾ \'ਤੇ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ, ਪਰ ਉਹ ਇੰਝ ਕਦੇ-ਕਦਾਈਂ ਕਰ ਸਕਦੀ ਹੈ। ਉਦਾਹਰਨ ਲਈ, ਇਸ ਦਾ ਮਤਲਬ ਇਹ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਚਿੱਤਰ ਤਦ ਤੱਕ ਨਹੀਂ ਪ੍ਰਦਰਸ਼ਿਤ ਕੀਤੇ ਜਾਂਦੇ, ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਉਹਨਾਂ \'ਤੇ ਟੈਪ ਨਹੀਂ ਕਰਦੇ।"</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"ਕੀ ਡਾਟਾ ਸੇਵਰ ਚਾਲੂ ਕਰਨਾ ਹੈ?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"ਚਾਲੂ ਕਰੋ"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
@@ -1679,7 +1685,7 @@
     <string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS ਬੇਨਤੀ DIAL ਬੇਨਤੀ ਵਿੱਚ ਸੰਸ਼ੋਧਿਤ ਕੀਤੀ ਗਈ ਹੈ।"</string>
     <string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS ਬੇਨਤੀ USSD ਬੇਨਤੀ ਵਿੱਚ ਸੰਸ਼ੋਧਿਤ ਕੀਤੀ ਗਈ ਹੈ।"</string>
     <string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS ਬੇਨਤੀ ਨਵੀਂ SS ਵਿੱਚ ਸੰਸ਼ੋਧਿਤ ਕੀਤੀ ਗਈ ਹੈ।"</string>
-    <string name="notification_work_profile_content_description" msgid="4600554564103770764">"ਕੰਮ ਪ੍ਰੋਫਾਈਲ"</string>
+    <string name="notification_work_profile_content_description" msgid="4600554564103770764">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
     <string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"ਵਿਸਤਾਰ ਕਰੋ"</string>
     <string name="expand_button_content_description_expanded" msgid="8520652707158554895">"ਸੁੰਗੇੜੋ"</string>
     <string name="expand_action_accessibility" msgid="5307730695723718254">"ਟੌਗਲ ਵਿਸਤਾਰ"</string>
@@ -1699,43 +1705,37 @@
     <string name="importance_from_user" msgid="7318955817386549931">"ਤੁਸੀਂ ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਦੀ ਮਹੱਤਤਾ ਸੈੱਟ ਕੀਤੀ।"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ਇਹ ਸ਼ਾਮਲ ਲੋਕਾਂ ਦੇ ਕਾਰਨ ਮਹੱਤਵਪੂਰਨ ਹੈ।"</string>
     <string name="user_creation_account_exists" msgid="1942606193570143289">"ਕੀ <xliff:g id="APP">%1$s</xliff:g> ਨੂੰ <xliff:g id="ACCOUNT">%2$s</xliff:g> ਨਾਲ ਇੱਕ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣ ਦੀ ਮਨਜ਼ੂਰੀ ਦੇਣੀ ਹੈ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"ਕੀ <xliff:g id="APP">%1$s</xliff:g> ਨੂੰ <xliff:g id="ACCOUNT">%2$s</xliff:g> ਨਾਲ ਇੱਕ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣ ਦੀ ਮਨਜ਼ੂਰੀ ਦੇਣੀ ਹੈ (ਇਸ ਖਾਤੇ ਨਾਲ ਇੱਕ ਵਰਤੋਂਕਾਰ ਪਹਿਲਾਂ ਤੋਂ ਹੀ ਮੌਜੂਦ ਹੈ) ?"</string>
+    <string name="user_creation_adding" msgid="4482658054622099197">"ਕੀ <xliff:g id="APP">%1$s</xliff:g> ਨੂੰ <xliff:g id="ACCOUNT">%2$s</xliff:g> ਨਾਲ ਇੱਕ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ (ਇਸ ਖਾਤੇ ਨਾਲ ਇੱਕ ਵਰਤੋਂਕਾਰ ਪਹਿਲਾਂ ਤੋਂ ਹੀ ਮੌਜੂਦ ਹੈ) ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"ਇੱਕ ਭਾਸ਼ਾ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"ਖੇਤਰ ਤਰਜੀਹ"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"ਭਾਸ਼ਾ ਨਾਮ ਟਾਈਪ ਕਰੋ"</string>
     <string name="language_picker_section_suggested" msgid="8414489646861640885">"ਸੁਝਾਈਆਂ ਗਈਆਂ"</string>
     <string name="language_picker_section_all" msgid="3097279199511617537">"ਸਾਰੀਆਂ ਭਾਸ਼ਾਵਾਂ"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"ਸਾਰੇ ਖੇਤਰ"</string>
-    <string name="locale_search_menu" msgid="2560710726687249178">"ਖੋਜ"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"ਖੋਜੋ"</string>
     <string name="work_mode_off_title" msgid="2615362773958585967">"ਕੀ ਕਾਰਜ ਮੋਡ ਚਾਲੂ ਕਰੀਏ?"</string>
     <string name="work_mode_off_message" msgid="2961559609199223594">"ਇਸ ਨਾਲ ਐਪਾਂ, ਬੈਕਗ੍ਰਾਊਂਡ ਸਮਕਾਲੀਕਰਨ, ਅਤੇ ਸਬੰਧਿਤ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਸਮੇਤ ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਜਾਵੇਗਾ"</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"ਚਾਲੂ ਕਰੋ"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"ਤੁਹਾਨੂੰ ਨਵੇਂ ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਹੋਏ ਹਨ"</string>
-    <string name="new_sms_notification_content" msgid="7002938807812083463">"ਵੇਖਣ ਲਈ SMS ਐਪ ਖੋਲ੍ਹੋ"</string>
+    <string name="new_sms_notification_content" msgid="7002938807812083463">"ਦੇਖਣ ਲਈ SMS ਐਪ ਖੋਲ੍ਹੋ"</string>
     <string name="user_encrypted_title" msgid="9054897468831672082">"ਕੁਝ ਪ੍ਰਕਾਰਜਾਤਮਕਤਾ ਸੀਮਿਤ ਹੋ ਸਕਦੀ ਹੈ"</string>
-    <string name="user_encrypted_message" msgid="4923292604515744267">"ਅਨਲੌਕ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
-    <string name="user_encrypted_detail" msgid="5708447464349420392">"ਵਰਤੋਂਕਾਰ ਡੈਟਾ ਲੌਕ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="profile_encrypted_detail" msgid="3700965619978314974">"ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਲੌਕ ਕੀਤੀ ਗਈ"</string>
-    <string name="profile_encrypted_message" msgid="6964994232310195874">"ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"ਵਰਤੋਂਕਾਰ  ਡਾਟਾ   ਲਾਕ  ਕੀਤਾ ਗਿਆ"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਲਾਕ ਕੀਤੀ ਗਈ"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋਈ"</string>
-    <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ਫ਼ਾਈਲਾਂ ਵੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ਫ਼ਾਈਲਾਂ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="pin_target" msgid="3052256031352291362">"ਪਿੰਨ ਕਰੋ"</string>
     <string name="unpin_target" msgid="3556545602439143442">"ਅਨਪਿੰਨ ਕਰੋ"</string>
     <string name="app_info" msgid="6856026610594615344">"ਐਪ ਜਾਣਕਾਰੀ"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"ਕੀ ਡੀਵਾਈਸ ਮੁੜ-ਸੈੱਟ ਕਰਨਾ ਹੈ?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"ਡੀਵਾਈਸ ਮੁੜ-ਸੈੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ਡੈਮੋ ਚਾਲੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
-    <string name="demo_restarting_message" msgid="952118052531642451">"ਡੀਵਾਈਸ ਮੁੜ-ਸੈੱਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"ਕੀ ਡੀਵਾਈਸ ਮੁੜ-ਸੈੱਟ ਕਰਨਾ ਹੈ?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"ਤੁਸੀਂ ਕਿਸੇ ਵੀ ਤਬਦੀਲੀਆਂ ਨੂੰ ਗੁਆ ਬੈਠੋਂਗੇ ਅਤੇ ਡੈਮੋ <xliff:g id="TIMEOUT">%1$s</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਚਾਲੂ ਕੀਤਾ ਜਾਵੇਗਾ…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"ਰੱਦ ਕਰੋ"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"ਹੁਣੇ ਮੁੜ-ਸੈੱਟ ਕਰੋ"</string>
+    <string name="demo_restarting_message" msgid="952118052531642451">"ਡੀਵਾਈਸ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"ਕਾਨਫਰੰਸ ਕਾਲ"</string>
-    <string name="tooltip_popup_title" msgid="5253721848739260181">"ਟੂਲਟਿਪ"</string>
+    <string name="tooltip_popup_title" msgid="5253721848739260181">"ਟੂਲ-ਟਿੱਪ"</string>
     <string name="app_category_game" msgid="5431836943981492993">"ਗੇਮਾਂ"</string>
-    <string name="app_category_audio" msgid="1659853108734301647">"ਸੰਗੀਤ ਅਤੇ ਔਡੀਓ"</string>
+    <string name="app_category_audio" msgid="1659853108734301647">"ਸੰਗੀਤ ਅਤੇ  ਆਡੀਓ"</string>
     <string name="app_category_video" msgid="2728726078629384196">"ਮੂਵੀਆਂ ਅਤੇ ਵੀਡੀਓ"</string>
     <string name="app_category_image" msgid="4867854544519846048">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਚਿੱਤਰ"</string>
     <string name="app_category_social" msgid="5842783057834965912">"ਸਮਾਜਕ ਅਤੇ ਸੰਚਾਰ"</string>
@@ -1749,8 +1749,8 @@
     <string name="time_picker_header_text" msgid="143536825321922567">"ਸਮਾਂ ਸੈੱਟ ਕਰੋ"</string>
     <string name="time_picker_input_error" msgid="7574999942502513765">"ਇੱਕ ਵੈਧ ਸਮਾਂ ਦਾਖਲ ਕਰੋ"</string>
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"ਸਮਾਂ ਟਾਈਪ ਕਰੋ"</string>
-    <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"ਸਮਾਂ ਇਨਪੁੱਟ ਕਰਨ ਲਈ ਲਿਖਤ ਇਨਪੁੱਟ ਮੋਡ \'ਤੇ ਬਦਲੀ ਕਰੋ।"</string>
-    <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"ਸਮਾਂ ਇਨਪੁੱਟ ਕਰਨ ਲਈ ਘੜੀ ਮੋਡ \'ਤੇ ਬਦਲੀ ਕਰੋ।"</string>
+    <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"ਸਮਾਂ ਇਨਪੁੱਟ ਕਰਨ ਲਈ ਲਿਖਤ ਇਨਪੁੱਟ ਮੋਡ \'ਤੇ ਸਵਿੱਚ ਕਰੋ।"</string>
+    <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"ਸਮਾਂ ਇਨਪੁੱਟ ਕਰਨ ਲਈ ਘੜੀ ਮੋਡ \'ਤੇ ਸਵਿੱਚ ਕਰੋ।"</string>
     <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"ਆਟੋਫਿਲ ਵਿਕਲਪ"</string>
     <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"ਆਟੋਫਿਲ ਲਈ ਰੱਖਿਅਤ ਕਰੋ"</string>
     <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"ਸਮੱਗਰੀਆਂ ਨੂੰ ਆਟੋਫਿਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
@@ -1759,10 +1759,10 @@
       <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> ਆਟੋਫਿਲ ਸੁਝਾਅ</item>
       <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> ਆਟੋਫਿਲ ਸੁਝਾਅ</item>
     </plurals>
-    <string name="autofill_save_title" msgid="3345527308992082601">"&lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt; ਵਿੱਚ ਰੱਖਿਅਤ ਕਰੀਏ?"</string>
-    <string name="autofill_save_title_with_type" msgid="8637809388029313305">"<xliff:g id="TYPE">%1$s</xliff:g> ਨੂੰ &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt; ਵਿੱਚ ਰੱਖਿਅਤ ਕਰੀਏ?"</string>
-    <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"<xliff:g id="TYPE_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="TYPE_1">%2$s</xliff:g> ਨੂੰ &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt; ਵਿੱਚ ਰੱਖਿਅਤ ਕਰੀਏ?"</string>
-    <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, ਅਤੇ <xliff:g id="TYPE_2">%3$s</xliff:g> ਨੂੰ &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt; ਵਿੱਚ ਰੱਖਿਅਤ ਕਰੀਏ?"</string>
+    <string name="autofill_save_title" msgid="3345527308992082601">"ਕੀ &lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt; ਵਿੱਚ ਰੱਖਿਅਤ ਕਰਨਾ ਹੈ?"</string>
+    <string name="autofill_save_title_with_type" msgid="8637809388029313305">"ਕੀ <xliff:g id="TYPE">%1$s</xliff:g> ਨੂੰ &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt; ਵਿੱਚ ਰੱਖਿਅਤ ਕਰਨਾ ਹੈ?"</string>
+    <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"ਕੀ <xliff:g id="TYPE_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="TYPE_1">%2$s</xliff:g> ਨੂੰ &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt; ਵਿੱਚ ਰੱਖਿਅਤ ਕਰਨਾ ਹੈ?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"ਕੀ <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, ਅਤੇ <xliff:g id="TYPE_2">%3$s</xliff:g> ਨੂੰ &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt; ਵਿੱਚ ਰੱਖਿਅਤ ਕਰਨਾ ਹੈ?"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"ਰੱਖਿਅਤ ਕਰੋ"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"ਪਾਸਵਰਡ"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ਤੁਰੰਤ ਤੱਟੀ ਖੇਤਰਾਂ ਅਤੇ ਨਦੀ ਦੇ ਕਿਨਾਰੇ ਵਾਲੇ ਖੇਤਰਾਂ ਨੂੰ ਖਾਲੀ ਕਰ ਕੇ ਕਿਸੇ ਸੁਰੱਖਿਅਤ ਸਥਾਨ \'ਤੇ ਚਲੇ ਜਾਓ ਜਿਵੇਂ ਕਿ ਉੱਚੀ ਜ਼ਮੀਨ।"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ਸ਼ਾਂਤ ਰਹੋ ਅਤੇ ਆਸ-ਪਾਸ ਪਨਾਹ ਮੰਗੋ।"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"ਸੰਕਟਕਾਲੀਨ ਸੰਦੇਸ਼ ਟੈਸਟ"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"ਜਵਾਬ ਦਿਓ"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 9a9ae8a..a3bac5e 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -133,10 +133,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Wyszukiwanie usługi"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Połączenia przez Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach."</item>
+    <item msgid="3910386316304772394">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach. (Kod błędu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Zarejestruj u operatora"</item>
+    <item msgid="7472393097168811593">"Rejestracja u operatora (kod błędu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -252,8 +252,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asystent głosowy"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zablokuj teraz"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Treści ukryte"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Treść ukryta z powodu zasad"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Nowe powiadomienie"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Klawiatura wirtualna"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Klawiatura fizyczna"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Bezpieczeństwo"</string>
@@ -269,10 +268,10 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerty"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Tryb demo dla sklepów"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Połączenie USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacje działające w tle"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> działa w tle"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Aplikacje (<xliff:g id="NUMBER">%1$d</xliff:g>) działają w tle"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Kliknij, by wyświetlić szczegóły wykorzystania baterii i transmisji danych"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikacje zużywające baterię"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> zużywa baterię"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Liczba aplikacji zużywających baterię: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Kliknij, by wyświetlić szczegóły wykorzystania baterii i użycia danych"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Tryb awaryjny"</string>
     <string name="android_system_label" msgid="6577375335728551336">"System Android"</string>
@@ -353,7 +352,7 @@
     <string name="permlab_runInBackground" msgid="7365290743781858803">"działanie w tle"</string>
     <string name="permdesc_runInBackground" msgid="7370142232209999824">"Ta aplikacja może działać w tle. Bateria może się szybciej rozładowywać."</string>
     <string name="permlab_useDataInBackground" msgid="8694951340794341809">"transmisja danych w tle"</string>
-    <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"Ta aplikacja może przesyłać i odbierać dane w tle. Transmisja danych może się zwiększyć."</string>
+    <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"Ta aplikacja może przesyłać i odbierać dane w tle. Użycie danych może się zwiększyć."</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"sprawianie, że aplikacja jest cały czas uruchomiona"</string>
     <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Pozwala aplikacji na trwałe zapisywanie swoich fragmentów w pamięci. Może to zmniejszyć ilość pamięci dostępnej dla innych aplikacji i spowolnić działanie tabletu."</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"Pozwala aplikacji zapewnić nieusuwalność swoich fragmentów z pamięci. Może to ograniczyć ilość pamięci dostępną dla innych aplikacji i spowalniać działanie telewizora."</string>
@@ -1150,6 +1149,13 @@
       <item quantity="other">Dostępne są otwarte sieci Wi-Fi</item>
       <item quantity="one">Dostępna jest otwarta sieć Wi-Fi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Połącz się z otwartą siecią Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Łączę się z otwartą siecią Wi-Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Połączono z siecią Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nie udało się połączyć z siecią Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Kliknij, by zobaczyć wszystkie sieci"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Połącz"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Wszystkie sieci"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Zaloguj się w sieci Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Zaloguj się do sieci"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1229,6 +1235,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB w trybie MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Podłączono akcesorium USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Kliknij, by wyświetlić więcej opcji."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Wykryto analogowe urządzenie audio"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Podłączone urządzenie nie jest zgodne z tym telefonem. Kliknij, by dowiedzieć się więcej."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Kliknij, by wyłączyć debugowanie USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Wybierz, aby wyłączyć debugowanie USB."</string>
@@ -1334,9 +1342,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Nawiązano połączenie: <xliff:g id="SESSION">%s</xliff:g>. Dotknij, aby zarządzać siecią."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Łączę ze stałą siecią VPN…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Połączono ze stałą siecią VPN"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Rozłączono ze stałą siecią VPN"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Rozłączono ze stałą siecią VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Błąd stałej sieci VPN"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Kliknij, by skonfigurować"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Zmień ustawienia sieciowe lub ustawienia sieci VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Wybierz plik"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nie wybrano pliku"</string>
     <string name="reset" msgid="2448168080964209908">"Resetuj"</string>
@@ -1345,8 +1353,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Kliknij, by zakończyć tryb samochodowy."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Aktywny tethering lub punkt dostępu"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Kliknij, by skonfigurować."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering został wyłączony"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Aby uzyskać szczegółowe informacje, skontaktuj się z administratorem"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Wróć"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Dalej"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Pomiń"</string>
@@ -1422,7 +1428,7 @@
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"Dysk USB (<xliff:g id="MANUFACTURER">%s</xliff:g>)"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Nośnik USB"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"Edytuj"</string>
-    <string name="data_usage_warning_title" msgid="3620440638180218181">"Alert transmisji danych"</string>
+    <string name="data_usage_warning_title" msgid="3620440638180218181">"Alert użycia danych"</string>
     <string name="data_usage_warning_body" msgid="6660692274311972007">"Kliknij, by wyświetlić użycie i ustawienia."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Osiągnięto limit danych 2G/3G"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Osiągnięto limit danych 4G"</string>
@@ -1789,14 +1795,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Odepnij"</string>
     <string name="app_info" msgid="6856026610594615344">"O aplikacji"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Zresetować urządzenie?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Kliknij, by zresetować urządzenie"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Uruchamiam tryb demo…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Resetuję urządzenie…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Zresetować urządzenie?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Stracisz wszystkie wprowadzone zmiany, a tryb demo uruchomi się ponownie za <xliff:g id="TIMEOUT">%1$s</xliff:g> s…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Anuluj"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Resetuj teraz"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Wyłączono: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Połączenie konferencyjne"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Etykietka"</string>
@@ -1842,6 +1842,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Niezwłocznie ewakuuj się z regionów nabrzeżnych i położonych przy rzekach w bezpieczniejsze miejsce, np. na wzniesienie."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Zachowaj spokój i poszukaj schronienia w pobliżu."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test komunikatów alarmowych"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Odpowiedz"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Niedozwolona karta SIM"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Nieobsługiwana karta SIM"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index dcaac52..20fc2e5 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pesquisando serviço"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas por Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
+    <item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente a chamada no Wi-Fi nas configurações. Código de erro: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Faça registro na sua operadora"</item>
+    <item msgid="7472393097168811593">"Registre-se junto à sua operadora (Código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ajuda de voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Conteúdo oculto"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Conteúdo ocultado pela política"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Nova notificação"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclado virtual"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teclado físico"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Segurança"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstração na loja"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Conexão USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps sendo executados em segundo plano"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está sendo executado em segundo plano"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps estão sendo executados em segundo plano"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps que estão consumindo a bateria"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está consumindo a bateria"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps estão consumindo a bateria"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string>
@@ -337,7 +336,7 @@
     <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"gerenciar proprietários de perfis e de dispositivos"</string>
     <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Permitir que os apps definam os proprietários de perfis e de dispositivos."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"reordenar os apps em execução"</string>
-    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite que o app mova tarefas para o primeiro plano e o plano de fundo, sem sua intervenção."</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite que o app mova tarefas para o primeiro e o segundo plano, sem sua intervenção."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"ativar o modo carro"</string>
     <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Permite que o app ative o modo Carro."</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"fechar outros apps"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="one">Abrir redes Wi-Fi disponíveis</item>
       <item quantity="other">Abrir redes Wi-Fi disponíveis</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectar-se a uma rede Wi‑Fi aberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectando-se a uma rede Wi‑Fi aberta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectado a uma rede Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Não foi possível conectar-se à rede Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Fazer login na rede Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Fazer login na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a um acessório USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Toque para ver mais opções."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Acessório de áudio analógico detectado"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"O dispositivo anexo não é compatível com esse smartphone. Toque para saber mais."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Toque para desativar a depuração USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Conectado a <xliff:g id="SESSION">%s</xliff:g>. Toque para gerenciar a rede."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"VPN sempre ativa conectando..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPN sempre ativa conectada"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"VPN sempre ativa desconectada"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Desconectado da VPN sempre ativa"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Erro na VPN sempre ativa"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Toque para configurar"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Alterar configurações de VPN ou rede"</string>
     <string name="upload_file" msgid="2897957172366730416">"Escolher arquivo"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nenhum arquivo escolhido"</string>
     <string name="reset" msgid="2448168080964209908">"Redefinir"</string>
@@ -1301,11 +1309,9 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Toque para sair do modo carro."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Vínculo ou ponto de acesso ativo"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Voltar"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Avançar"</string>
-    <string name="skip_button_label" msgid="1275362299471631819">"Ignorar"</string>
+    <string name="skip_button_label" msgid="1275362299471631819">"Pular"</string>
     <string name="no_matches" msgid="8129421908915840737">"Não encontrado"</string>
     <string name="find_on_page" msgid="1946799233822820384">"Localizar na página"</string>
     <plurals name="matches_found" formatted="false" msgid="1210884353962081884">
@@ -1692,7 +1698,7 @@
     <string name="close_button_text" msgid="3937902162644062866">"Fechar"</string>
     <string name="notification_messaging_title_template" msgid="3452480118762691020">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
     <plurals name="selected_count" formatted="false" msgid="7187339492915744615">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionado</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
     </plurals>
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Sem classificação"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Liberar guia"</string>
     <string name="app_info" msgid="6856026610594615344">"Informações do app"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Redefinir dispositivo?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Toque para redefinir o dispositivo"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Iniciando demonstração…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Redefinindo dispositivo…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Redefinir dispositivo?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Você perderá todas as alterações. A demonstração será iniciada novamente em <xliff:g id="TIMEOUT">%1$s</xliff:g> segundos…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Cancelar"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Reiniciar agora"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Widget <xliff:g id="LABEL">%1$s</xliff:g> desativado"</string>
     <string name="conference_call" msgid="3751093130790472426">"Teleconferência"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Dica"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Saia imediatamente de regiões costeiras e áreas ribeirinhas e vá para um lugar mais seguro, como terrenos elevados."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Fique calmo e procure um abrigo por perto."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Teste de mensagens de emergência"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Responder"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM não permitido"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM não aprovisionado"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index a657720..125eb13f 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"A procurar Serviço"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. Em seguida, nas Definições, ative novamente as chamadas por Wi-Fi."</item>
+    <item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. De seguida, nas Definições, ative novamente as Chamadas Wi-Fi. (Código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Registar-se junto do seu operador"</item>
+    <item msgid="7472393097168811593">"Registar-se junto do seu operador (código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. de voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Conteúdo oculto"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Conteúdo ocultado pela política"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Nova notificação"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclado virtual"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teclado físico"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Segurança"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstração para retalho"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Ligação USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplicações em execução em segundo plano"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"A aplicação <xliff:g id="APP_NAME">%1$s</xliff:g> está a ser executada em segundo plano"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicações estão a ser executadas em segundo plano"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplicações que estão a consumir bateria"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"A aplicação <xliff:g id="APP_NAME">%1$s</xliff:g> está a consumir bateria."</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicações estão a consumir bateria."</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Toque para obter detalhes acerca da utilização da bateria e dos dados"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="one">Rede Wi-Fi aberta disponível</item>
       <item quantity="other">Redes Wi-Fi abertas disponíveis</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Ligar à rede Wi-Fi aberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"A ligar à rede Wi-Fi aberta…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ligado à rede Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Não foi possível ligar à rede Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ligar"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Iniciar sessão na rede Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Início de sessão na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ligado a um acessório USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Toque para obter mais opções."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Acessório de áudio analógico detetado"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"O dispositivo ligado não é compatível com este telemóvel. Toque para saber mais."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Toque para desativar a depuração USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração por USB."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Ligado a <xliff:g id="SESSION">%s</xliff:g>. Toque para gerir a rede."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"A ligar VPN sempre ativa..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPN sempre ativa ligada"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"VPN sempre ativa desligada"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Desligado da VPN sempre ativada"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Erro da VPN sempre ativa"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Tocar para configurar"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Alterar as notificações da rede ou da VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Escolher ficheiro"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Não foi selecionado nenhum ficheiro"</string>
     <string name="reset" msgid="2448168080964209908">"Repor"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Toque para sair do modo automóvel."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Ligação ponto a ponto ou hotspot activos"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"A ligação (à Internet) via telemóvel está desativada."</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacte o administrador para obter detalhes."</string>
     <string name="back_button_label" msgid="2300470004503343439">"Anterior"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Seguinte"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Ignorar"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Soltar"</string>
     <string name="app_info" msgid="6856026610594615344">"Informações da aplicação"</string>
     <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Pretende repor o dispositivo?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Toque para repor o dispositivo"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"A iniciar a demonstração…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"A repor o dispositivo…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Pretende repor o dispositivo?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Perderá todas as alterações e a demonstração começará novamente dentro de <xliff:g id="TIMEOUT">%1$s</xliff:g> segundos…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Cancelar"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Repor agora"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> desativado"</string>
     <string name="conference_call" msgid="3751093130790472426">"Conferência"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Sugestão"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Abandone imediatamente regiões costeiras e zonas ribeirinhas em direção a um local mais seguro, como um terreno elevado."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantenha a calma e procure abrigo nas proximidades."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Teste de mensagens de emergência"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Responder"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM não permitido"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM não ativado"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index dcaac52..20fc2e5 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pesquisando serviço"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas por Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
+    <item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente a chamada no Wi-Fi nas configurações. Código de erro: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Faça registro na sua operadora"</item>
+    <item msgid="7472393097168811593">"Registre-se junto à sua operadora (Código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ajuda de voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Conteúdo oculto"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Conteúdo ocultado pela política"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Nova notificação"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclado virtual"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teclado físico"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Segurança"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstração na loja"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Conexão USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps sendo executados em segundo plano"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está sendo executado em segundo plano"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps estão sendo executados em segundo plano"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps que estão consumindo a bateria"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está consumindo a bateria"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps estão consumindo a bateria"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string>
@@ -337,7 +336,7 @@
     <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"gerenciar proprietários de perfis e de dispositivos"</string>
     <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Permitir que os apps definam os proprietários de perfis e de dispositivos."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"reordenar os apps em execução"</string>
-    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite que o app mova tarefas para o primeiro plano e o plano de fundo, sem sua intervenção."</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite que o app mova tarefas para o primeiro e o segundo plano, sem sua intervenção."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"ativar o modo carro"</string>
     <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Permite que o app ative o modo Carro."</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"fechar outros apps"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="one">Abrir redes Wi-Fi disponíveis</item>
       <item quantity="other">Abrir redes Wi-Fi disponíveis</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectar-se a uma rede Wi‑Fi aberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectando-se a uma rede Wi‑Fi aberta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectado a uma rede Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Não foi possível conectar-se à rede Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Fazer login na rede Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Fazer login na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a um acessório USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Toque para ver mais opções."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Acessório de áudio analógico detectado"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"O dispositivo anexo não é compatível com esse smartphone. Toque para saber mais."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Toque para desativar a depuração USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Conectado a <xliff:g id="SESSION">%s</xliff:g>. Toque para gerenciar a rede."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"VPN sempre ativa conectando..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPN sempre ativa conectada"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"VPN sempre ativa desconectada"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Desconectado da VPN sempre ativa"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Erro na VPN sempre ativa"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Toque para configurar"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Alterar configurações de VPN ou rede"</string>
     <string name="upload_file" msgid="2897957172366730416">"Escolher arquivo"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nenhum arquivo escolhido"</string>
     <string name="reset" msgid="2448168080964209908">"Redefinir"</string>
@@ -1301,11 +1309,9 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Toque para sair do modo carro."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Vínculo ou ponto de acesso ativo"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Voltar"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Avançar"</string>
-    <string name="skip_button_label" msgid="1275362299471631819">"Ignorar"</string>
+    <string name="skip_button_label" msgid="1275362299471631819">"Pular"</string>
     <string name="no_matches" msgid="8129421908915840737">"Não encontrado"</string>
     <string name="find_on_page" msgid="1946799233822820384">"Localizar na página"</string>
     <plurals name="matches_found" formatted="false" msgid="1210884353962081884">
@@ -1692,7 +1698,7 @@
     <string name="close_button_text" msgid="3937902162644062866">"Fechar"</string>
     <string name="notification_messaging_title_template" msgid="3452480118762691020">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
     <plurals name="selected_count" formatted="false" msgid="7187339492915744615">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionado</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
     </plurals>
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Sem classificação"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Liberar guia"</string>
     <string name="app_info" msgid="6856026610594615344">"Informações do app"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Redefinir dispositivo?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Toque para redefinir o dispositivo"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Iniciando demonstração…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Redefinindo dispositivo…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Redefinir dispositivo?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Você perderá todas as alterações. A demonstração será iniciada novamente em <xliff:g id="TIMEOUT">%1$s</xliff:g> segundos…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Cancelar"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Reiniciar agora"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Widget <xliff:g id="LABEL">%1$s</xliff:g> desativado"</string>
     <string name="conference_call" msgid="3751093130790472426">"Teleconferência"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Dica"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Saia imediatamente de regiões costeiras e áreas ribeirinhas e vá para um lugar mais seguro, como terrenos elevados."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Fique calmo e procure um abrigo por perto."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Teste de mensagens de emergência"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Responder"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM não permitido"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM não aprovisionado"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index ed0e996..a212b1b 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -132,10 +132,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Se caută serviciul"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Apelare prin Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Pentru a apela și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări."</item>
+    <item msgid="3910386316304772394">"Pentru a efectua apeluri și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări. (Cod de eroare: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Înregistrați-vă la operatorul dvs."</item>
+    <item msgid="7472393097168811593">"Înregistrați-vă la operator (cod de eroare: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -249,8 +249,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistent vocal"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Blocați acum"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"˃999"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Conținutul este ascuns"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Conținutul este ascuns conform politicii"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Notificare nouă"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Tastatură virtuală"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Tastatură fizică"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Securitate"</string>
@@ -266,9 +265,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerte"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstrație comercială"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Conexiune USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplicațiile rulează în fundal"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> rulează în fundal"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicații rulează în fundal"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplicațiile consumă bateria"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> folosește bateria"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicații folosesc bateria"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Atingeți pentru mai multe detalii privind bateria și utilizarea datelor"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mod sigur"</string>
@@ -1128,6 +1127,13 @@
       <item quantity="other">Rețele Wi-Fi deschise disponibile</item>
       <item quantity="one">Rețea Wi-Fi deschisă disponibilă</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectați-vă la o rețea Wi‑Fi deschisă"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Se stabilește conexiunea la o rețea Wi‑Fi deschisă"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"S-a realizat conexiunea la rețeaua Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nu s-a putut stabili conexiunea la rețeaua Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Atingeți pentru a vedea toate rețelele"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectați-vă"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Toate rețelele"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Conectați-vă la rețeaua Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Conectați-vă la rețea"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1207,9 +1213,11 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"Conexiune USB pentru MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectat la un accesoriu USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Atingeți pentru mai multe opțiuni."</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"Depanarea USB este conectată"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"S-a detectat un accesoriu audio analogic"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Dispozitivul atașat nu este compatibil cu acest telefon. Atingeți pentru a afla mai multe."</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"Remedierea erorilor prin USB este conectată"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Atingeți ca să dezactivați remedierea erorilor prin USB."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selectați pentru a dezactiva depanarea USB."</string>
+    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selectați pentru a dezactiva remedierea erorilor prin USB."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Se creează un raport de eroare…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Trimiteți raportul de eroare?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Se trimite raportul de eroare…"</string>
@@ -1312,9 +1320,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Conectat la <xliff:g id="SESSION">%s</xliff:g>. Apăsați pentru a gestiona rețeaua."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Se efectuează conectarea la rețeaua VPN activată permanent…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Conectat(ă) la rețeaua VPN activată permanent"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Rețeaua VPN activată permanent a fost deconectată"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Deconectat de la rețeaua VPN activată permanent"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Eroare de rețea VPN activată permanent"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Atingeți pentru a configura"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Modificați setările de rețea sau VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Alegeți un fișier"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nu au fost găsite fișiere"</string>
     <string name="reset" msgid="2448168080964209908">"Resetați"</string>
@@ -1323,8 +1331,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Atingeți ca să ieșiți din modul Mașină."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering sau hotspot activ"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Atingeți ca să configurați."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tetheringul este dezactivat"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contactați administratorul pentru detalii"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Înapoi"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Înainte"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Omiteți"</string>
@@ -1756,14 +1762,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Anulați fixarea"</string>
     <string name="app_info" msgid="6856026610594615344">"Informații despre aplicație"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Resetați dispozitivul?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Atingeți pentru a reseta dispozitivul"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Se pornește demonstrația…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Se resetează dispozitivul…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Resetați dispozitivul?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Veți pierde toate modificările, iar demonstrația va începe din nou peste <xliff:g id="TIMEOUT">%1$s</xliff:g> secunde…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Anulați"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Resetați acum"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> a fost dezactivat"</string>
     <string name="conference_call" msgid="3751093130790472426">"Conferință telefonică"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Balon explicativ"</string>
@@ -1808,6 +1808,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Părăsiți imediat zonele de coastă și din apropierea râurilor și îndreptați-vă spre un loc mai sigur, cum ar fi o zonă aflată la înălțime."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Păstrați-vă calmul și căutați un adăpost în apropiere."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Testarea mesajelor de urgență"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Răspundeți"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Cardul SIM nu este permis"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Cardul SIM nu este activat"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 3e64fa6..224380463 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -133,10 +133,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Поиск службы"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Звонки по Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо сначала обратиться к оператору связи и подключить эту услугу. После этого вы сможете снова выбрать этот параметр в настройках."</item>
+    <item msgid="3910386316304772394">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо подключить эту услугу через оператора связи. После этого вы сможете выбрать этот параметр в настройках. Код ошибки: <xliff:g id="CODE">%1$s</xliff:g>."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Укажите оператора и зарегистрируйтесь"</item>
+    <item msgid="7472393097168811593">"Укажите оператора и зарегистрируйтесь (код ошибки: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -252,8 +252,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Аудиоподсказки"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Заблокировать"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Содержимое скрыто"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Содержимое скрыто в соответствии с заданными правилами"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Новое уведомление"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуальная клавиатура"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Физическая клавиатура"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Безопасность"</string>
@@ -269,9 +268,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Уведомления"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Деморежим для магазина"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-подключение"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Приложения, работающие в фоновом режиме"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> в фоновом режиме"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Несколько приложений (<xliff:g id="NUMBER">%1$d</xliff:g>) работает в фоновом режиме"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Приложения, расходующие заряд"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" расходует заряд"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Несколько приложений (<xliff:g id="NUMBER">%1$d</xliff:g>) расходуют заряд"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Нажмите, чтобы проверить энергопотребление и трафик"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Безопасный режим"</string>
@@ -496,7 +495,7 @@
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Слишком много попыток. Повторите позже."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Слишком много попыток. Сканер отпечатков пальцев отключен."</string>
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Повторите попытку."</string>
-    <string name="fingerprint_name_template" msgid="5870957565512716938">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
+    <string name="fingerprint_name_template" msgid="5870957565512716938">"Отпечаток <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Значок отпечатка пальца"</string>
@@ -1150,6 +1149,13 @@
       <item quantity="many">Есть открытые сети Wi-Fi</item>
       <item quantity="other">Есть открытые сети Wi-Fi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Подключитесь к открытой сети Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Подключение к открытой сети Wi‑Fi…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Подключено к сети Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не удалось подключиться к сети Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Нажмите, чтобы увидеть список сетей"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Подключиться"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Все сети"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Подключение к Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Регистрация в сети"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1229,6 +1235,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI через USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB-устройство подключено"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Нажмите, чтобы показать дополнительные параметры."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Обнаружено аналоговое аудиоустройство"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Подсоединенное устройство несовместимо с этим телефоном. Нажмите, чтобы узнать подробности."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка по USB разрешена"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Нажмите, чтобы отключить отладку по USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Нажмите, чтобы отключить отладку по USB."</string>
@@ -1334,9 +1342,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Подключено: \"<xliff:g id="SESSION">%s</xliff:g>\". Нажмите здесь, чтобы изменить настройки сети."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Подключение…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Подключено"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Отключено"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Отключено от постоянной VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Ошибка"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Нажмите, чтобы настроить"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Изменить настройки сети или VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Выбрать файл"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Не выбран файл"</string>
     <string name="reset" msgid="2448168080964209908">"Сбросить"</string>
@@ -1345,8 +1353,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Нажмите, чтобы выйти из автомобильного режима."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Включен режим модема"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Нажмите, чтобы настроить."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Включить режим модема нельзя"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Обратитесь к администратору, чтобы узнать подробности."</string>
     <string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Далее"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Пропустить"</string>
@@ -1789,14 +1795,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Открепить"</string>
     <string name="app_info" msgid="6856026610594615344">"О приложении"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Сбросить настройки устройства?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Нажмите здесь, чтобы сбросить настройки"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Запуск деморежима…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Сброс данных…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Сбросить настройки устройства?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Все изменения будут утеряны. Деморежим будет перезапущен через <xliff:g id="TIMEOUT">%1$s</xliff:g> сек."</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Отмена"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Сбросить"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Виджет <xliff:g id="LABEL">%1$s</xliff:g> отключен"</string>
     <string name="conference_call" msgid="3751093130790472426">"Конференц-связь"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Подсказка"</string>
@@ -1842,6 +1842,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Немедленно эвакуируйтесь из прибрежной зоны в более высокое место."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Сохраняйте спокойствие и поищите укрытие поблизости."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Тестовое экстренное сообщение"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Ответить"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Использование SIM-карты запрещено"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-карта не активирована"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index bf62bf8..6adfb30 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"සේවාව සඳහා සොයමින්"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi ඇමතීම"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්‍රියාත්මක කරන්න."</item>
+    <item msgid="3910386316304772394">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්‍රියාත්මක කරන්න. (දෝෂ කේතය <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"ඔබගේ වාහකය සමඟ ලියාපදිංචි වන්න"</item>
+    <item msgid="7472393097168811593">"ඔබගේ වාහකය සමඟ ලියාපදිංචි වන්න (දෝෂ කේතය: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"හඬ සහායක"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"දැන් අගුළු දමන්න"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"සැඟවුණු සම්බන්ධතා"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ප්‍රතිපත්තිය විසින් අන්තර්ගතය සඟවන ලදී"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"නව දැනුම්දීම"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"අතථ්‍ය යතුරු පුවරුව"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"භෞතික යතුරු පුවරුව"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"ආරක්ෂාව"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ඇඟවීම්"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"සිල්ලර ආදර්ශනය"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB සම්බන්ධතාවය"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"පසුබිමින් ධාවනය වන යෙදුම්"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> පසුබිමින් ධාවනය වේ"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"යෙදුම් <xliff:g id="NUMBER">%1$d</xliff:g>ක් පසුබිමින් ධාවනය වේ"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"බැටරිය භාවිත කරන යෙදුම්"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> බැටරිය භාවිත කරයි"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"යෙදුම් <xliff:g id="NUMBER">%1$d</xliff:g>ක් බැටරිය භාවිත කරයි"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"බැටරි හා දත්ත භාවිතය පිළිබඳව විස්තර සඳහා තට්ටු කරන්න"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"ආරක්‍ෂිත ආකාරය"</string>
@@ -1108,6 +1107,13 @@
       <item quantity="one">විවෘත Wi-Fi ජාල තිබේ</item>
       <item quantity="other">විවෘත Wi-Fi ජාල තිබේ</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"විවෘත Wi-Fi ජාලය වෙත සම්බන්ධ වෙන්න"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"විවෘත Wi-Fi ජාලය වෙත සම්බන්ධ වෙමින්"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi-Fi ජාලයක් වෙත සම්බන්ධ විය"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi-Fi ජාලයක් වෙත සම්බන්ධ විය නොහැකි විය"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"සියලු ජාල බැලීමට තට්ටු කරන්න"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"සම්බන්ධ කරන්න"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"සියලු ජාල"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ජාලයට පුරනය වන්න"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ජාලයට පුරනය වන්න"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1187,6 +1193,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI සඳහා USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB මෙවලමකට සම්බන්ධිතයි"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"තවත් විකල්ප සඳහා තට්ටු කරන්න."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"ප්‍රතිසම ශ්‍රව්‍ය උපාංගය අනාවරණය කර ගන්නා ලදී"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"මෙම දුරකථනය සමඟ සම්බන්ධිත උපාංගය නොගැළපෙයි. තව දැන ගැනීමට තට්ටු කරන්න."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB නිදොස්කරණය සම්බන්ධිතයි"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB නිදොස්කරණය අබල කිරීමට තට්ටු කරන්න."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB නිදොස්කරණය අබල කිරීමට තෝරන්න."</string>
@@ -1292,9 +1300,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> වෙත සම්බන්ධිතයි. ජාලය කළමනාකරණය කිරීමට තට්ටු කරන්න."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"සැමවිටම VPN සම්බන්ධ වෙමින්…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"නිරතුරුවම VPN සම්බන්ධ කර ඇත"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"සැමවිට ක්‍රියාත්මක VPN විසන්ධි කරන ලදී"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"සැම විට ක්‍රියාත්මක VPN වෙතින් විසන්ධි විය"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"සැමවිට සක්‍රිය VPN දෝෂය"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"පිහිටුවීමට තට්ටු කරන්න"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"ජාලය හෝ VPN සැකසීම් වෙනස් කරන්න"</string>
     <string name="upload_file" msgid="2897957172366730416">"ගොනුව තෝරන්න"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"ගොනුවක් තෝරාගෙන නැත"</string>
     <string name="reset" msgid="2448168080964209908">"යළි පිහිටුවන්න"</string>
@@ -1303,8 +1311,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"මෝටර් රථ ප්‍රකාරයෙන් ඉවත් වීමට තට්ටු කරන්න."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ටෙදරින් හෝ හොට්ස්පොට් සක්‍රීයයි"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"පිහිටුවීමට තට්ටු කරන්න."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ටෙදරින් අබල කර ඇත"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"විස්තර සඳහා ඔබගේ පරිපාලක අමතන්න"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ආපසු"</string>
     <string name="next_button_label" msgid="1080555104677992408">"මීලඟ"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"මඟ හරින්න"</string>
@@ -1725,14 +1731,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"ගලවන්න"</string>
     <string name="app_info" msgid="6856026610594615344">"යෙදුම් තොරතුරු"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"උපාංගය යළි සකසන්නද?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"උපාංගය යළි සැකසීමට තට්ටු කරන්න"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ආදර්ශනය ආරම්භ කරමින්..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"උපාංගය යළි සකසමින්..."</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"උපාංගය යළි සකසන්නද?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"ඔබට යම් වෙනස් කිරීම් අහිමි වනු ඇති අතර ආදර්ශනය තත්පර <xliff:g id="TIMEOUT">%1$s</xliff:g>කින් නැවත ආරම්භ වනු ඇත…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"අවලංගු කරන්න"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"දැන් යළි සකසන්න"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"අබල කළ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"සම්මන්ත්‍රණ ඇමතුම"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"මෙවලම් ඉඟිය"</string>
@@ -1776,6 +1776,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"මුහුදු බඩ ප්‍රදේශ සහ ගංඉවුරු ප්‍රදේශ සිට ඉහළ ප්‍රදේශයක් වැනි ආරක්‍ෂිත තැනකට දැන්ම යන්න."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"සන්සුන්ව ඉන්න සහ අවට ඇති නවාතැන් පහසුකම් බලන්න."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"හදිසි පණිවිඩ පරීක්ෂණය"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"පිළිතුරු දෙන්න"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM එක සඳහා ඉඩ නොදේ"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM එක සක්‍රීය කර නොමැත"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 123bc85..b716f0d 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -104,7 +104,7 @@
     <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Upozornenia na mobilné dáta"</string>
     <string name="notification_channel_sms" msgid="3441746047346135073">"Správy SMS"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Správy hlasovej schránky"</string>
-    <string name="notification_channel_wfc" msgid="2130802501654254801">"Volanie cez Wi-Fi"</string>
+    <string name="notification_channel_wfc" msgid="2130802501654254801">"Volanie cez Wi‑Fi"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Používateľ, s ktorým komunikujete, požiadal o režim FULL textového telefónu"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Používateľ, s ktorým komunikujete, požiadal o režim HCO textového telefónu"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Používateľ, s ktorým komunikujete, požiadal o režim VCO textového telefónu"</string>
@@ -131,21 +131,21 @@
     <string name="roamingText11" msgid="4154476854426920970">"Banner roamingu je zapnutý"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Banner roamingu je vypnutý"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Vyhľadávanie služby"</string>
-    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Volanie cez Wi-Fi"</string>
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Volanie cez Wi‑Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi."</item>
+    <item msgid="3910386316304772394">"Ak chcete volať a odosielať správy prostredníctvom siete Wi‑Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi‑Fi. (Kód chyby: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Registrujte sa so svojím operátorom"</item>
+    <item msgid="7472393097168811593">"Zaregistrujte sa u operátora (Kód chyby: <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>
+    <item msgid="4397097370387921767">"Volanie siete Wi‑Fi %s"</item>
   </string-array>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Vypnuté"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Uprednostniť Wi-Fi"</string>
+    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Uprednostniť Wi‑Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferujem mobilné dáta"</string>
-    <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Len Wi-Fi"</string>
+    <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Len Wi‑Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nepresmerované"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
     <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> po <xliff:g id="TIME_DELAY">{2}</xliff:g> s"</string>
@@ -252,8 +252,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Hlasový asistent"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Uzamknúť"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Skrytý obsah"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Obsah je na základe pravidiel skrytý"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Nové upozornenie"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuálna klávesnica"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fyzická klávesnica"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Zabezpečenie"</string>
@@ -269,9 +268,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozornenia"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Predajná ukážka"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Pripojenie USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikácie sú spustené na pozadí"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je spustená na pozadí"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Niekoľko aplikácií (<xliff:g id="NUMBER">%1$d</xliff:g>) je spustených na pozadí"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikácie spotrebúvajú batériu"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> používa batériu"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Aplikácie (<xliff:g id="NUMBER">%1$d</xliff:g>) používajú batériu"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Klepnutím zobrazíte podrobnosti o batérii a spotrebe dát"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Núdzový režim"</string>
@@ -397,11 +396,11 @@
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"prístup k ďalším príkazom poskytovateľa polohy"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Umožňuje aplikácii pristupovať k ďalším príkazom poskytovateľa informácií o polohe. Aplikácii to môže umožniť zasahovať do činnosti systému GPS alebo iných zdrojov informácií o polohe."</string>
     <string name="permlab_accessFineLocation" msgid="251034415460950944">"prístup k presnej polohe (pomocou GPS a siete)"</string>
-    <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"Táto aplikácia môže získať údaje o vašej polohe na základe systému GPS alebo sieťových zdrojov, ako sú mobilné veže a siete Wi-Fi. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii na telefóne. Môže to viesť k zvýšeniu spotreby batérie."</string>
+    <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"Táto aplikácia môže získať údaje o vašej polohe na základe systému GPS alebo sieťových zdrojov, ako sú mobilné veže a siete Wi‑Fi. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii na telefóne. Môže to viesť k zvýšeniu spotreby batérie."</string>
     <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"prístup k približnej polohe (pomocou siete)"</string>
-    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú mobilné veže a siete Wi-Fi. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii na tablete."</string>
-    <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú mobilné veže a siete Wi-Fi. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii na televízore."</string>
-    <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú mobilné veže a siete Wi-Fi. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii na telefóne."</string>
+    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú mobilné veže a siete Wi‑Fi. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii na tablete."</string>
+    <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú mobilné veže a siete Wi‑Fi. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii na televízore."</string>
+    <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú mobilné veže a siete Wi‑Fi. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii na telefóne."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"meniť nastavenia zvuku"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Umožňuje aplikácii upraviť globálne nastavenia zvuku, ako je hlasitosť, alebo určiť, z ktorého reproduktora bude zvuk vychádzať."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"nahrávať zvuk"</string>
@@ -452,14 +451,14 @@
     <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Umožňuje aplikácii zmeniť stav sieťového pripojenia zdieľaného pomocou tetheringu."</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"zmeniť zdieľané dátové pripojenie"</string>
     <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Umožňuje aplikácii zmeniť stav sieťového pripojenia zdieľaného pomocou tetheringu."</string>
-    <string name="permlab_accessWifiState" msgid="5202012949247040011">"zobraziť pripojenia Wi-Fi"</string>
-    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Umožňuje aplikácii zobraziť informácie o sieťach Wi-Fi. Napríklad o tom, či je sieť Wi-Fi povolená alebo názvy pripojených zariadení Wi-Fi."</string>
-    <string name="permlab_changeWifiState" msgid="6550641188749128035">"pripojiť a odpojiť od siete Wi-Fi"</string>
-    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Umožňuje aplikácii pripojiť sa na prístupové body siete Wi-Fi, odpojiť sa od nich a meniť konfiguráciu zariadení pre siete Wi-Fi."</string>
-    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"povoliť príjem Wi-Fi Multicast"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Umožňuje aplikácii prijímať pakety odoslané na všetky zariadenia v sieti Wi-Fi pomocou viacsmerových adries, nielen pomocou vášho tabletu. Spotrebuje viac energie ako režim bez viacsmerového vysielania."</string>
-    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Umožňuje aplikácii prijímať pakety odosielané na všetky zariadenia v sieti Wi-Fi pomocou viacsmerových adries (a nie iba do vášho televízora). Spotrebúva viac energie ako režim bez viacsmerového vysielania."</string>
-    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Umožňuje aplikácii prijímať pakety odoslané na všetky zariadenia v sieti Wi-Fi pomocou viacsmerových adries, nielen pomocou vášho telefónu. Spotrebuje viac energie ako režim bez viacsmerového vysielania."</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"zobraziť pripojenia Wi‑Fi"</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Umožňuje aplikácii zobraziť informácie o sieťach Wi‑Fi. Napríklad o tom, či je sieť Wi‑Fi povolená alebo názvy pripojených zariadení Wi‑Fi."</string>
+    <string name="permlab_changeWifiState" msgid="6550641188749128035">"pripojiť a odpojiť od siete Wi‑Fi"</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Umožňuje aplikácii pripojiť sa na prístupové body siete Wi‑Fi, odpojiť sa od nich a meniť konfiguráciu zariadení pre siete Wi‑Fi."</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"povoliť príjem Wi‑Fi Multicast"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Umožňuje aplikácii prijímať pakety odoslané na všetky zariadenia v sieti Wi‑Fi pomocou viacsmerových adries, nielen pomocou vášho tabletu. Spotrebuje viac energie ako režim bez viacsmerového vysielania."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Umožňuje aplikácii prijímať pakety odosielané na všetky zariadenia v sieti Wi‑Fi pomocou viacsmerových adries (a nie iba do vášho televízora). Spotrebúva viac energie ako režim bez viacsmerového vysielania."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Umožňuje aplikácii prijímať pakety odoslané na všetky zariadenia v sieti Wi‑Fi pomocou viacsmerových adries, nielen pomocou vášho telefónu. Spotrebuje viac energie ako režim bez viacsmerového vysielania."</string>
     <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"pristupovať k nastaveniam Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Umožňuje aplikácii konfigurovať miestny tablet s rozhraním Bluetooth a vyhľadávať a spárovať vzdialené zariadenia."</string>
     <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Umožňuje aplikácii konfigurovať miestny televízor s rozhraním Bluetooth, objavovať vzdialené zariadenia a párovať sa s nimi."</string>
@@ -1139,43 +1138,50 @@
     <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Zvuky upozornení"</string>
     <string name="ringtone_unknown" msgid="3914515995813061520">"Neznáme"</string>
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
-      <item quantity="few">K dispozícii sú siete Wi-Fi</item>
-      <item quantity="many">K dispozícii sú siete Wi-Fi</item>
-      <item quantity="other">K dispozícii sú siete Wi-Fi</item>
-      <item quantity="one">K dispozícii je sieť Wi-Fi</item>
+      <item quantity="few">K dispozícii sú siete Wi‑Fi</item>
+      <item quantity="many">K dispozícii sú siete Wi‑Fi</item>
+      <item quantity="other">K dispozícii sú siete Wi‑Fi</item>
+      <item quantity="one">K dispozícii je sieť Wi‑Fi</item>
     </plurals>
     <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
-      <item quantity="few">K dispozícii sú verejné siete Wi-Fi</item>
-      <item quantity="many">K dispozícii sú verejné siete Wi-Fi</item>
-      <item quantity="other">K dispozícii sú verejné siete Wi-Fi</item>
-      <item quantity="one">K dispozícii je verejná sieť Wi-Fi</item>
+      <item quantity="few">K dispozícii sú verejné siete Wi‑Fi</item>
+      <item quantity="many">K dispozícii sú verejné siete Wi‑Fi</item>
+      <item quantity="other">K dispozícii sú verejné siete Wi‑Fi</item>
+      <item quantity="one">K dispozícii je verejná sieť Wi‑Fi</item>
     </plurals>
-    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prihlásiť sa do siete Wi-Fi"</string>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Pripojenie k otvorenej sieti Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Pripája sa k otvorenej sieti Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Pripojenie k sieti Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"K sieti Wi‑Fi sa nepodarilo pripojiť"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všetky siete"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Pripojiť"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Všetky siete"</string>
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prihlásiť sa do siete Wi‑Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prihlásenie do siete"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8451173622563841546">"Sieť Wi-Fi nemá prístup k internetu"</string>
+    <string name="wifi_no_internet" msgid="8451173622563841546">"Sieť Wi‑Fi nemá prístup k internetu"</string>
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Klepnutím získate možnosti"</string>
     <string name="network_switch_metered" msgid="4671730921726992671">"Prepnuté na sieť: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
     <string name="network_switch_metered_detail" msgid="5325661434777870353">"Keď sieť <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nemá prístup k internetu, zariadenie používa sieť <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Môžu sa účtovať poplatky."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"Prepnuté zo siete <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na sieť <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
     <item msgid="3979506840912951943">"mobilné dáta"</item>
-    <item msgid="75483255295529161">"Wi-Fi"</item>
+    <item msgid="75483255295529161">"Wi‑Fi"</item>
     <item msgid="6862614801537202646">"Bluetooth"</item>
     <item msgid="5447331121797802871">"Ethernet"</item>
     <item msgid="8257233890381651999">"VPN"</item>
   </string-array>
     <string name="network_switch_type_name_unknown" msgid="4552612897806660656">"neznámy typ siete"</string>
-    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nepodarilo sa pripojiť k sieti Wi-Fi"</string>
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nepodarilo sa pripojiť k sieti Wi‑Fi"</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" má nekvalitné internetové pripojenie."</string>
     <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Povoliť pripojenie?"</string>
-    <string name="wifi_connect_alert_message" msgid="6451273376815958922">"Aplikácia %1$s sa chce pripojiť k sieti Wi-Fi %2$s"</string>
+    <string name="wifi_connect_alert_message" msgid="6451273376815958922">"Aplikácia %1$s sa chce pripojiť k sieti Wi‑Fi %2$s"</string>
     <string name="wifi_connect_default_application" msgid="7143109390475484319">"Aplikácia"</string>
-    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Priame pripojenie Wi-Fi"</string>
-    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Spustiť priame pripojenie siete Wi-Fi. Táto možnosť vypne sieť Wi-Fi v režime klient alebo hotspot."</string>
-    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Priame pripojenie siete Wi-Fi sa nepodarilo spustiť"</string>
-    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Priame pripojenie siete Wi-Fi je zapnuté"</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Priame pripojenie Wi‑Fi"</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Spustiť priame pripojenie siete Wi‑Fi. Táto možnosť vypne sieť Wi‑Fi v režime klient alebo hotspot."</string>
+    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Priame pripojenie siete Wi‑Fi sa nepodarilo spustiť"</string>
+    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Priame pripojenie siete Wi‑Fi je zapnuté"</string>
     <string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"Klepnutím zobrazíte nastavenia"</string>
     <string name="accept" msgid="1645267259272829559">"Prijať"</string>
     <string name="decline" msgid="2112225451706137894">"Odmietnuť"</string>
@@ -1185,9 +1191,9 @@
     <string name="wifi_p2p_to_message" msgid="248968974522044099">"Komu:"</string>
     <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Zadajte požadovaný kód PIN:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Tablet bude počas pripojenia k zariadeniu <xliff:g id="DEVICE_NAME">%1$s</xliff:g> od siete Wi-Fi dočasne odpojený."</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"Televízor sa počas pripojenia k zariadeniu <xliff:g id="DEVICE_NAME">%1$s</xliff:g> dočasne odpojí zo siete Wi-Fi."</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Telefón bude počas pripojenia k zariadeniu <xliff:g id="DEVICE_NAME">%1$s</xliff:g> od siete Wi-Fi dočasne odpojený."</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Tablet bude počas pripojenia k zariadeniu <xliff:g id="DEVICE_NAME">%1$s</xliff:g> od siete Wi‑Fi dočasne odpojený."</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"Televízor sa počas pripojenia k zariadeniu <xliff:g id="DEVICE_NAME">%1$s</xliff:g> dočasne odpojí zo siete Wi‑Fi."</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Telefón bude počas pripojenia k zariadeniu <xliff:g id="DEVICE_NAME">%1$s</xliff:g> od siete Wi‑Fi dočasne odpojený."</string>
     <string name="select_character" msgid="3365550120617701745">"Vkladanie znakov"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"Odosielanie správ SMS"</string>
     <string name="sms_control_message" msgid="3867899169651496433">"Aplikácia &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; posiela veľký počet správ SMS. Chcete tejto aplikácií povoliť, aby aj naďalej posielala správy?"</string>
@@ -1222,13 +1228,15 @@
     <string name="no_permissions" msgid="7283357728219338112">"Nevyžadujú sa žiadne oprávnenia."</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"môžu sa vám účtovať poplatky"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
-    <string name="usb_charging_notification_title" msgid="6895185153353640787">"Prebieha nabíjanie tohto zariadenia pomocou USB"</string>
+    <string name="usb_charging_notification_title" msgid="6895185153353640787">"Zariadenie sa nabíja cez USB"</string>
     <string name="usb_supplying_notification_title" msgid="5310642257296510271">"Prebieha nabíjanie pripojeného zariadenia pomocou USB"</string>
     <string name="usb_mtp_notification_title" msgid="8396264943589760855">"USB na prenos súborov"</string>
     <string name="usb_ptp_notification_title" msgid="1347328437083192112">"USB na prenos fotiek"</string>
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB na pripojenie zariadenia MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Pripojené k periférnemu zariadeniu USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Klepnutím zobrazíte ďalšie možnosti."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Bolo zistené analógové zvukové príslušenstvo"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Pripojené zariadenie nie je kompatibilné s týmto telefónom. Ďalšie informácie zobrazíte klepnutím."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladenie cez USB pripojené"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Klepnutím zakážete ladenie cez USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vyberte, ak chcete zakázať ladenie cez USB."</string>
@@ -1334,9 +1342,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Pripojené k relácii <xliff:g id="SESSION">%s</xliff:g>. Po klepnutí môžete sieť spravovať."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Pripájanie k vždy zapnutej sieti VPN…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Pripojenie k vždy zapnutej sieti VPN"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Vždy zapnutá sieť VPN bola odpojená"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Odpojené od vždy zapnutej siete VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Chyba vždy zapnutej siete VPN"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Klepnutím prejdete do Nastavení"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Zmeniť sieť alebo nastavenia VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Zvoliť súbor"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nie je vybratý žiadny súbor"</string>
     <string name="reset" msgid="2448168080964209908">"Obnoviť"</string>
@@ -1345,8 +1353,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Klepnutím ukončíte režim V aute."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering alebo prístupový bod je aktívny"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Klepnutím prejdete na nastavenie."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering je deaktivovaný"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"O podrobnosti požiadajte svojho správcu"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Späť"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Ďalej"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Preskočiť"</string>
@@ -1427,12 +1433,12 @@
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Bol dosiahnutý limit 2G–3G"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Bol dosiahnutý limit 4G"</string>
     <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Dosiahnutý limit mobilných dát"</string>
-    <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Bol dosiahnutý limit dát Wi-Fi"</string>
+    <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Bol dosiahnutý limit dát Wi‑Fi"</string>
     <string name="data_usage_limit_body" msgid="291731708279614081">"Údaje pre zbytok cyklu pozastavené"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G, 3G dátový limit prekročený"</string>
     <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Dátový limit 4G bol prekročený"</string>
     <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Prekroč. limit pre mobil. dáta"</string>
-    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Dát. limit Wi-Fi bol prekročený"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Dát. limit Wi‑Fi bol prekročený"</string>
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> nad stanovenou hranicou."</string>
     <string name="data_usage_restricted_title" msgid="5965157361036321914">"Dátové prenosy obmedzené"</string>
     <string name="data_usage_restricted_body" msgid="469866376337242726">"Klepnutím odstránite obmedzenie."</string>
@@ -1789,14 +1795,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Uvoľniť"</string>
     <string name="app_info" msgid="6856026610594615344">"Info o aplikácii"</string>
     <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Resetovať zariadenie?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Klepnutím resetujete zariadenie"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Spúšťa sa ukážka…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Resetuje sa zariadenie…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Resetovať zariadenie?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Prídete o všetky zmeny a ukážka sa znova spustí o <xliff:g id="TIMEOUT">%1$s</xliff:g> s…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Zrušiť"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Resetovať"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Deaktivovaná miniaplikácia <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konferenčný hovor"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Popis"</string>
@@ -1842,6 +1842,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Okamžite začnite evakuáciu z prímorských a nábrežných oblastí na bezpečnejšie miesto, napríklad do vyššie položených regiónov."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Zachovajte pokoj a vyhľadajte úkryt v okolí."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test tiesňových správ"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Odpovedať"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM karta je zakázaná"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM karta nie je k dispozícii"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 0eac889..0db6434 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -133,10 +133,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Iskanje storitve"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Klicanje prek Wi-Fi-ja"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi."</item>
+    <item msgid="3910386316304772394">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi. (Koda napake: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Registracija pri operaterju"</item>
+    <item msgid="7472393097168811593">"Registracija pri operaterju (koda napake: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -252,8 +252,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Glas. pomočnik"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zakleni zdaj"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Vsebina je skrita"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Pravilnik je skril vsebino"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Novo obvestilo"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Navidezna tipkovnica"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fizična tipkovnica"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Varnost"</string>
@@ -269,9 +268,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Opozorila"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Predstavitev za maloprodajo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Povezava USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacije se izvajajo v ozadju"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> se izvaja v ozadju"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Več aplikacij (<xliff:g id="NUMBER">%1$d</xliff:g>) se izvaja v ozadju"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikacije, ki porabljajo energijo akumulatorja"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> porablja energijo akumulatorja"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Toliko aplikacij porablja energijo akumulatorja: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dotaknite se za prikaz podrobnosti porabe akumulatorja in prenosa podatkov"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Varni način"</string>
@@ -1150,6 +1149,13 @@
       <item quantity="few">Na voljo so odprta omrežja Wi-Fi</item>
       <item quantity="other">Na voljo so odprta omrežja Wi-Fi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Vzpostavite povezavo z odprtim omrežjem Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Vzpostavljanje povezave z odprtim omrežjem Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Povezava z omrežjem Wi-Fi je vzpostavljena"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Povezave z omrežjem Wi-Fi ni bilo mogoče vzpostaviti"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dotaknite se, če si želite ogledati vsa omrežja"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Vzpostavi povezavo"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Vsa omrežja"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavite se v omrežje Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava v omrežje"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1229,6 +1235,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB za MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Priključen na dodatek USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Dotaknite se za več možnosti."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Zaznana je analogna dodatna zvočna oprema"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Priključena naprava ni združljiva s tem telefonom. Dotaknite se za več informacij."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Iskanje napak prek USB je povezano"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Dotaknite se za izklop odpravljanja napak prek USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izberite, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string>
@@ -1334,9 +1342,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Povezan z mestom <xliff:g id="SESSION">%s</xliff:g>. Tapnite za upravljanje omrežja."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Povezovanje v stalno vklopljeno navidezno zasebno omrežje ..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Vzpostavljena povezava v stalno vklopljeno navidezno zasebno omrežje"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Povezava s stalno vklopljenim VPN-jem je prekinjena"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Prekinjena povezava s stalno vklopljenim VPN-jem"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Napaka stalno vklopljenega navideznega zasebnega omrežja"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Dotaknite se, če želite nastaviti"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Spremenite omrežne nastavitve ali nastavitve omrežja VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Izberi datoteko"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nobena datoteka ni izbrana"</string>
     <string name="reset" msgid="2448168080964209908">"Ponastavi"</string>
@@ -1345,8 +1353,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Dotaknite se, če želite zapreti avtomobilski način."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Aktivna povezava z internetom ali dostopna točka sta aktivni"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Dotaknite se, če želite nastaviti."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Povezava z internetom prek mobilnega telefona je onemogočena"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Za podrobnosti se obrnite na skrbnika"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Nazaj"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Naprej"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Preskoči"</string>
@@ -1789,14 +1795,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Odpenjanje"</string>
     <string name="app_info" msgid="6856026610594615344">"Podatki o aplikaciji"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Želite ponastaviti napravo?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Dotaknite se, če želite ponastaviti napravo"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Začenjanje predstavitve …"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Ponastavljanje naprave …"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Želite ponastaviti napravo?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Morebitne spremembe bodo izgubljene in predstavitev se bo začela znova čez <xliff:g id="TIMEOUT">%1$s</xliff:g> s …"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Prekliči"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Ponastavi"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> – onemogočeno"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konferenčni klic"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Opis orodja"</string>
@@ -1842,6 +1842,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Takoj se umaknite z obalnih območij in bregov rek na varnejše mesto, na primer na višje ležeča mesta."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Ostanite mirni in poiščite zavetje v bližini."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Preskus sporočil v sili"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Odgovor"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Kartica SIM ni dovoljena"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Kartica SIM ni omogočena za uporabo"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 097a427..26714d9 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Po kërkon për shërbim"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Telefonatë me Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Për të bërë telefonata dhe për të dërguar mesazhe me Wi-Fi, në fillim kërkoji operatorit celular ta konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi, nga Cilësimet."</item>
+    <item msgid="3910386316304772394">"Për të bërë telefonata dhe për të dërguar mesazhe nëpërmjet Wi-Fi, në fillim kërkoji operatorit celular të konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi nga \"Cilësimet\". (Kodi i gabimit: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Regjistrohu me operatorin tënd celular"</item>
+    <item msgid="7472393097168811593">"Regjistrohu me operatorin tënd celular (kodi i gabimit: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ndihma zanore"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Kyç tani"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Përmbajtjet janë të fshehura"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Përmbajtja është e fshehur për shkak të politikës"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Njoftim i ri"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Tastiera virtuale"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Tastiera fizike"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Siguria"</string>
@@ -263,13 +262,13 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Sinjalizimet"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstrimi i shitjes me pakicë"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Lidhja USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacionet që ekzekutohen në sfond"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> po ekzekutohet në sfond"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikacione po ekzekutohen në sfond"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikacionet që konsumojnë baterinë"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> po përdor baterinë"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikacione po përdorin baterinë"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Trokit për detaje mbi baterinë dhe përdorimin e të dhënave"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modaliteti i sigurisë"</string>
-    <string name="android_system_label" msgid="6577375335728551336">"Sistemi \"android\""</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Sistemi Android"</string>
     <string name="user_owner_label" msgid="1119010402169916617">"Ndryshoje te \"Personale\""</string>
     <string name="managed_profile_label" msgid="5289992269827577857">"Ndryshoje te \"Puna\""</string>
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktet"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Rrjete të hapura Wi-Fi në përdorim</item>
       <item quantity="one">Rrjet i hapur Wi-Fi në përdorim</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Lidhu me rrjetin e hapur Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Po lidhet me rrjetin e hapur Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Lidhur me rrjetin e hapur Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nuk mund të lidhet me rrjetin Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trokit për të parë të gjitha rrjetet"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Lidhu"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Të gjitha rrjetet"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Identifikohu në rrjetin Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Identifikohu në rrjet"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB për MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"U lidh me një ndihmës USB-je"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Trokit për më shumë opsione."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"U zbulua aksesor i audios analoge"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Pajisja e bashkuar nuk është e pajtueshme me këtë telefon. Trokit për të mësuar më shumë."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Korrigjuesi i USB-së i lidhur"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Trokit për të çaktivizuar korrigjimin e gabimeve të USB-së."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Përzgjidhe për të çaktivizuar korrigjimin e gabimeve të USB-së"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Lidhur me <xliff:g id="SESSION">%s</xliff:g>. Trokit për të menaxhuar rrjetin."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Po lidh VPN-në për aktivizim të përhershëm…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPN e lidhur në mënyrë të përhershme"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Rrjeti VPN gjithmonë aktiv u shkëput"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Shkëputur nga VPN-ja gjithmonë e aktivizuar"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Gabimi VPN-je për aktivizimin e përhershëm"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Trokit për ta konfiguruar"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Ndrysho rrjetin ose cilësimet e VPN-së"</string>
     <string name="upload_file" msgid="2897957172366730416">"Zgjidh skedarin"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nuk u zgjodh asnjë skedar"</string>
     <string name="reset" msgid="2448168080964209908">"Rivendos"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Trokit për të dalë nga modaliteti \"në makinë\"."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Lidhja e çiftimit ose ajo e qasjes në zona publike interneti është aktive"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Trokit për ta konfiguruar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Lidhja e çiftimit është çaktivizuar"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakto me administratorin për detaje"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Prapa"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Përpara"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Kapërce"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Zhgozhdo"</string>
     <string name="app_info" msgid="6856026610594615344">"Informacioni mbi aplikacionin"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Do ta rivendosësh pajisjen?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Trokit për ta rivendosur pajisjen"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Po nis demonstrimin..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Po rivendos pajisjen…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Do ta rivendosësh pajisjen?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Do të humbasësh çdo ndryshim dhe demonstrimi do të niset përsëri për <xliff:g id="TIMEOUT">%1$s</xliff:g> sekonda…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Anulo"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Rivendos tani"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> u çaktivizua"</string>
     <string name="conference_call" msgid="3751093130790472426">"Telefonatë konferencë"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Këshilla për veglën"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evakuohu menjëherë nga rajonet bregdetare dhe zonat pranë lumenjve drejt një vendi më të sigurt, si për shembull në një terren të ngritur."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Qëndro i qetë dhe kërko strehim në afërsi."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Testim për mesazhet e urgjencës"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Përgjigju"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Karta SIM nuk lejohet"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Karta SIM nuk është dhënë"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a8fd720..d4b2e64 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -132,10 +132,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Претраживање услуге"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Позивање преко Wi-Fi-ја"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја."</item>
+    <item msgid="3910386316304772394">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја. (кôд грешке: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Региструјте се код мобилног оператера"</item>
+    <item msgid="7472393097168811593">"Региструјте се код мобилног оператера (кôд грешке: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -147,7 +147,7 @@
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Само Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Није прослеђено"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
-    <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> након <xliff:g id="TIME_DELAY">{2}</xliff:g> секунде(и)"</string>
+    <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> након <xliff:g id="TIME_DELAY">{2}</xliff:g> секунде/и"</string>
     <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Није прослеђено"</string>
     <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Није прослеђено"</string>
     <string name="fcComplete" msgid="3118848230966886575">"Кôд функције је извршен."</string>
@@ -249,8 +249,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Гласовна помоћ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Закључај одмах"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Садржај је сакривен"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Садржај је сакривен смерницама"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Ново обавештење"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуелна тастатура"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Физичка тастатура"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Безбедност"</string>
@@ -266,9 +265,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Обавештења"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Режим демонстрације за малопродајне објекте"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB веза"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Апликације покренуте у позадини"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> ради у позадини"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Апликације (<xliff:g id="NUMBER">%1$d</xliff:g>) су покренуте у позадини"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Апликације које троше батерију"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> користи батерију"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Апликације (<xliff:g id="NUMBER">%1$d</xliff:g>) користе батерију"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Додирните за детаље о батерији и потрошњи података"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Безбедни режим"</string>
@@ -745,19 +744,19 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Погледајте Кориснички водич или контактирајте Корисничку подршку."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM картица је закључана."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Откључавање SIM картице…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте неправилно нацртали шаблон за откључавање. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде(и)."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте погрешно унели лозинку. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде(и)."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте погрешно унели PIN. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде(и)."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте нетачно унели шаблон за откључавање. Након још <xliff:g id="NUMBER_1">%2$d</xliff:g> несупешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу података за пријављивање на Google.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунде(и)."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте неправилно нацртали шаблон за откључавање. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте погрешно унели лозинку. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте погрешно унели PIN. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте нетачно унели шаблон за откључавање. Након још <xliff:g id="NUMBER_1">%2$d</xliff:g> несупешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу података за пријављивање на Google.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунде/и."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Неисправно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешна(их) покушаја од вас ће бити затражено да откључате ТВ помоћу података за пријављивање на Google.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте нетачно унели шаблон за откључавање. Након још <xliff:g id="NUMBER_1">%2$d</xliff:g> несупешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу података за пријављивање на Google.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунде(и)."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте нетачно унели шаблон за откључавање. Након још <xliff:g id="NUMBER_1">%2$d</xliff:g> несупешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу података за пријављивање на Google.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунде/и."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Неправилно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Након још неуспешних покушаја (<xliff:g id="NUMBER_1">%2$d</xliff:g>) таблет ће бити ресетован на фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Покушали сте да откључате ТВ нетачно <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешна(их) покушаја ТВ ће бити ресетован на подразумевана фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Неисправно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Након још неуспешних покушаја (<xliff:g id="NUMBER_1">%2$d</xliff:g>) телефон ће бити ресетован на фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Неисправно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Таблет ће сада бити враћен на подразумевана фабричка подешавања."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Покушали сте да откључате ТВ нетачно <xliff:g id="NUMBER">%d</xliff:g> пута. ТВ ће сада бити ресетован на подразумевана фабричка подешавања."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Неисправно сте покушали да откључате телефон <xliff:g id="NUMBER">%d</xliff:g> пута. Телефон ће сада бити враћен на подразумевана фабричка подешавања."</string>
-    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Пробајте поново за <xliff:g id="NUMBER">%d</xliff:g> секунде(и)."</string>
+    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Пробајте поново за <xliff:g id="NUMBER">%d</xliff:g> секунде/и."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Заборавили сте шаблон?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Откључавање налога"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Превише покушаја уноса шаблона"</string>
@@ -889,7 +888,7 @@
     <string name="second" msgid="3184235808021478">"сек"</string>
     <string name="seconds" msgid="3161515347216589235">"сек"</string>
     <string name="week" msgid="5617961537173061583">"недеља"</string>
-    <string name="weeks" msgid="6509623834583944518">"недеље(а)"</string>
+    <string name="weeks" msgid="6509623834583944518">"недеље/а"</string>
     <string name="year" msgid="4001118221013892076">"година"</string>
     <string name="years" msgid="6881577717993213522">"годинe(а)"</string>
     <string name="now_string_shortest" msgid="8912796667087856402">"сада"</string>
@@ -1128,6 +1127,13 @@
       <item quantity="few">Отворене Wi-Fi мреже су доступне</item>
       <item quantity="other">Отворене Wi-Fi мреже су доступне</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Повежите се са отвореном Wi‑Fi мрежом"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Повезујете се са отвореном Wi‑Fi мрежом"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Повезали сте се са Wi‑Fi мрежом"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Повезивање са Wi‑Fi мрежом није успело"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Додирните да бисте видели све мреже"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Повежи"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Све мреже"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Пријављивање на Wi-Fi мрежу"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Пријавите се на мрежу"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1207,6 +1213,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB за MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Повезано са USB додатком"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Додирните за још опција."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Откривена је аналогна додатна опрема за аудио садржај"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Прикључени уређај није компатибилан са овим телефоном. Додирните да бисте сазнали више."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отклањање грешака са USB-а је омогућено"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Додирните да бисте онемогућили отклањање грешака са USB-а."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изаберите да бисте онемогућили отклањања грешака са USB-а."</string>
@@ -1312,9 +1320,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Повезано са сесијом <xliff:g id="SESSION">%s</xliff:g>. Додирните да бисте управљали мрежом."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Повезивање стално укљученог VPN-а..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Стално укључени VPN је повезан"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Веза са стално укљученим VPN-ом је прекинута"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Веза са увек укљученим VPN-ом је прекинута"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Грешка стално укљученог VPN-а"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Додирните да бисте подесили"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Промените подешавања VPN-а"</string>
     <string name="upload_file" msgid="2897957172366730416">"Одабери датотеку"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Није изабрана ниједна датотека"</string>
     <string name="reset" msgid="2448168080964209908">"Ресетуј"</string>
@@ -1323,8 +1331,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Додирните да бисте изашли из режима рада у аутомобилу."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Активно повезивање са интернетом преко мобилног уређаја или хотспот"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Додирните да бисте подесили."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Привезивање је онемогућено"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Потражите детаље од администратора"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Next"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Прескочи"</string>
@@ -1465,7 +1471,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Погрешан шаблон"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Погрешна лозинка"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Погрешан PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Пробајте поново за <xliff:g id="NUMBER">%1$d</xliff:g> секунде(и)."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Пробајте поново за <xliff:g id="NUMBER">%1$d</xliff:g> секунде/и."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Нацртајте шаблон"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Унесите PIN SIM картице"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Унесите PIN"</string>
@@ -1487,18 +1493,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Неважеће корисничко име или лозинка."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Заборавили сте корисничко име или лозинку?\nПосетите адресу "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Провера налога…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Унели сте нетачни PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде(и)."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Унели сте нетачну лозинку <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде(и)."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Нацртали сте шаблон за откључавање нетачно <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде(и)."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Унели сте нетачни PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Унели сте нетачну лозинку <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Нацртали сте шаблон за откључавање нетачно <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Покушали сте да откључате таблет нетачно <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Након још <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешна(их) покушаја таблет ће бити ресетован на фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Покушали сте да откључате ТВ нетачно <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешна(их) покушаја ТВ ће бити ресетован на подразумевана фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Покушали сте да откључате телефон нетачно <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="2072996269148483637">"Покушали сте да откључате таблет нетачно <xliff:g id="NUMBER">%d</xliff:g> пута. Таблет ће сада бити враћен на подразумевана фабричка подешавања."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Покушали сте да откључате ТВ нетачно <xliff:g id="NUMBER">%d</xliff:g> пута. ТВ ће сада бити ресетован на подразумевана фабричка подешавања."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Покушали сте да откључате телефон нетачно <xliff:g id="NUMBER">%d</xliff:g> пута. Телефон ће сада бити враћен на подразумевана фабричка подешавања."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Нацртали сте шаблон за откључавање нетачно <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу налога е-поште.\n\nПробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунде(и)."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Нацртали сте шаблон за откључавање нетачно <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="tv" msgid="4224651132862313471">"Неисправно сте нацртали шаблон за откључавање <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="1437638152015574839">"Нацртали сте шаблон за откључавање нетачно <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="1437638152015574839">"Нацртали сте шаблон за откључавање нетачно <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_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Уклони"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Желите да појачате звук изнад препорученог нивоа?\n\nСлушање гласне музике дуже време може да вам оштети слух."</string>
@@ -1756,14 +1762,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Откачи"</string>
     <string name="app_info" msgid="6856026610594615344">"Информације о апликацији"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Желите ли да ресетујете уређај?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Додирните да бисте ресетовали уређај"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Покрећемо демонстрацију..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Ресетујемо уређај..."</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Желите ли да ресетујете уређај?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Изгубићете све промене и демонстрација ће поново почети за <xliff:g id="TIMEOUT">%1$s</xliff:g> сек…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Откажи"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Ресетуј"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Виџет <xliff:g id="LABEL">%1$s</xliff:g> је онемогућен"</string>
     <string name="conference_call" msgid="3751093130790472426">"Конференцијски позив"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Објашњење"</string>
@@ -1808,6 +1808,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Одмах се склоните из приобалних региона и области поред река на неко безбедније место, на пример, на неко узвишење."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Останите мирни и потражите склониште у околини."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Тестирање порука у хитним случајевима"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Одговори"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM картица није дозвољена"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM картица није подешена"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 2ce5390..21a500c 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Söker efter tjänst"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-samtal"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar."</item>
+    <item msgid="3910386316304772394">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar. (Felkod: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Registrera dig hos operatören"</item>
+    <item msgid="7472393097168811593">"Registrera dig hos operatören (felkod: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lås nu"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Innehåll har dolts"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Innehåll har dolts p.g.a. en policy"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Ny avisering"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuellt tangentbord"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fysiskt tangentbord"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Säkerhet"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Varningar"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo för återförsäljare"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-anslutning"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Appar körs i bakgrunden"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> körs i bakgrunden"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> appar körs i bakgrunden"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Appar som drar batteri"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> drar batteri"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> appar drar batteri"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tryck för information om batteri- och dataanvändning"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Säkert läge"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Öppna Wi-Fi-nätverk är tillgängliga</item>
       <item quantity="one">Öppet Wi-Fi-nätverk är tillgängligt</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Anslut till ett öppet Wi-Fi-nätverk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ansluter till ett öppet Wi-Fi-nätverk"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ansluten till Wi-Fi-nätverket"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Det gick inte att ansluta till Wi‑Fi-nätverket"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryck för att visa alla nätverk"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Anslut"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alla nätverk"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Logga in på ett Wi-Fi-nätverk"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Logga in på nätverket"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB för MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ansluten till ett USB-tillbehör"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tryck för fler alternativ."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Ett tillbehör med analog ljudutgång hittades"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Den anslutna enheten är inte kompatibel med mobilen. Tryck här om du vill veta mer."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tryck om du vill inaktivera USB-felsökning."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Välj för att inaktivera USB-felsökning."</string>
@@ -1290,19 +1298,17 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Ansluten till <xliff:g id="SESSION">%s</xliff:g>. Knacka lätt för att hantera nätverket."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Ansluter till Always-on VPN ..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Ansluten till Always-on VPN"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Always-on VPN har kopplats från"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Frånkopplad från Always-on VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Fel på Always-on VPN"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Tryck för att konfigurera"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Ändra inställningarna för nätverk eller VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Välj fil"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Ingen fil har valts"</string>
     <string name="reset" msgid="2448168080964209908">"Återställ"</string>
     <string name="submit" msgid="1602335572089911941">"Skicka"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Billäge aktiverat"</string>
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tryck om du vill avsluta billäge."</string>
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Internetdelning eller surfpunkt aktiverad"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Internetdelning eller surfzon aktiverad"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tryck om du vill konfigurera."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Internetdelning har inaktiverats"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakta administratören om du vill veta mer"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Tillbaka"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Nästa"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Hoppa över"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Lossa"</string>
     <string name="app_info" msgid="6856026610594615344">"Info om appen"</string>
     <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Vill du återställa enheten?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Tryck om du vill återställa enheten"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Demo startas …"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Enheten återställs …"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Vill du återställa enheten?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Ändringar som du har gjort sparas inte och demon börjar om om <xliff:g id="TIMEOUT">%1$s</xliff:g> sekunder …"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Avbryt"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Återställ nu"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> har inaktiverats"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konferenssamtal"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Beskrivning"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Utrym kust- och flodområden omedelbart och förflytta er till en säkrare plats, till exempel ett högt beläget område."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Håll dig lugn och sök skydd i närheten."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test för nödmeddelanden"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Svara"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-kort tillåts inte"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-kort tillhandahålls inte"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index a85d4cb..0b70edf 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Inatafuta Huduma"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Upigaji Simu kwa Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako asanidi huduma hii kwanza. Kisha uwashe tena upigaji simu kwa Wi-Fi kutoka kwenye Mipangilio."</item>
+    <item msgid="3910386316304772394">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako aweke mipangilio ya huduma hii kwanza. Kisha uwashe tena kipengele cha kupiga simu kupitia Wi-Fi kwenye Mipangilio. (Msimbo wa hitilafu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Jisajili na mtoa huduma wako"</item>
+    <item msgid="7472393097168811593">"Jisajili na mtoa huduma wako (Msimbo wa hitilafu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
     <!-- String.format failed for translation -->
     <!-- no translation found for wfcSpnFormats:0 (6830082633573257149) -->
@@ -244,8 +244,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Usaidizi wa Sauti"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Funga sasa"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Maudhui yamefichwa"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Maudhui yamefichwa kulingana na sera"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Arifa mpya"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Kibodi pepe"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Kibodi halisi"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Usalama"</string>
@@ -261,9 +260,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Arifa"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Onyesho la duka la rejareja"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Muunganisho wa USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Programu zinatumika chinichini"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> inatumika chinichini"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Programu <xliff:g id="NUMBER">%1$d</xliff:g> zinatumika chinichini"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Programu zinazotumia betri"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> inatumia betri"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Programu <xliff:g id="NUMBER">%1$d</xliff:g> zinatumia betri"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Gonga ili upate maelezo kuhusu betri na matumizi ya data"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mtindo salama"</string>
@@ -301,7 +300,7 @@
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Ishara za alama ya kidole"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Inaweza kurekodi ishara zinazotekelezwa kwenye kitambua alama ya kidole."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"zima au rekebisha mwambaa hali"</string>
-    <string name="permdesc_statusBar" msgid="8434669549504290975">"Inaruhusu programu kulemaza upau wa hali au kuongeza na kutoa ikoni za mfumo."</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Inaruhusu programu kulemaza upau wa hali au kuongeza na kutoa aikoni za mfumo."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"kuwa sehemu ya arifa"</string>
     <string name="permdesc_statusBarService" msgid="716113660795976060">"Inaruhusu programu kuwa upau wa hali."</string>
     <string name="permlab_expandStatusBar" msgid="1148198785937489264">"panua/kunja mwambaa hali"</string>
@@ -983,7 +982,7 @@
     <string name="dial" msgid="4204975095406423102">"Simu"</string>
     <string name="map" msgid="6068210738233985748">"Ramani"</string>
     <string name="browse" msgid="6993590095938149861">"Kivinjari"</string>
-    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nafasi ya kuhafadhi inakwisha"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nafasi ya kuhifadhi inakaribia kujaa"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Baadhi ya vipengee vya mfumo huenda visifanye kazi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Hifadhi haitoshi kwa ajili ya mfumo. Hakikisha una MB 250 za nafasi ya hifadhi isiyotumika na uanzishe upya."</string>
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> inatumiwa"</string>
@@ -1071,7 +1070,7 @@
     <string name="new_app_action" msgid="5472756926945440706">"Anza <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="1932143598371537340">"Komesha programu ya zamani bila kuhifadhi."</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> imezidi kiwango cha hifadhi kinachotakikana"</string>
-    <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Imezidi kikomo cha hifadhi; gonga ili uishiriki"</string>
+    <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Imezidi kikomo cha hifadhi; gusa ili uishiriki"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Ungependa kushiriki picha ya binafsi?"</string>
     <string name="dump_heap_text" msgid="4809417337240334941">"Mchakato wa <xliff:g id="PROC">%1$s</xliff:g> umezidi kiwango kinachotakikana cha hifadhi cha <xliff:g id="SIZE">%2$s</xliff:g>. Unaweza kupata picha ya hifadhi ili uishiriki na msadini programu wa picha. Tahadhari: picha hii ya hifadhi inaweza kuwa na maelezo yako ya binafsi ambayo yanaweza kufikiwa na programu."</string>
     <string name="sendText" msgid="5209874571959469142">"Chagua kitendo kwa ajili ya maandishi"</string>
@@ -1087,7 +1086,7 @@
     <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Sauti ya Bluetooth"</string>
     <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Sauti ya toni mlio"</string>
     <string name="volume_icon_description_incall" msgid="8890073218154543397">"Sauti ya simu"</string>
-    <string name="volume_icon_description_media" msgid="4217311719665194215">"Sauti ya midia"</string>
+    <string name="volume_icon_description_media" msgid="4217311719665194215">"Sauti ya faili"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Sauti ya arifa"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Mlio chaguo-msingi"</string>
     <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Chaguo-msingi (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
@@ -1104,6 +1103,13 @@
       <item quantity="other">Fungua mitandao ya Wi-Fi inayopatikana</item>
       <item quantity="one">Fungua mtandao wa Wi-Fi unaopatikana</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Unganisha kwenye mtandao wa Wi‑Fi unaotumiwa na mtu yeyote"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Inaunganisha kwenye mtandao wa Wi‑Fi unaotumiwa na mtu yeyote"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Imeunganisha kwenye mtandao wa Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Imeshindwa kuunganisha kwenye mtandao wa Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Gonga ili uone mitandao yote"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Unganisha"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Mitandao Yote"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Ingia kwa mtandao wa Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Ingia katika mtandao"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1183,6 +1189,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB kwa ajili ya MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Imeunganishwa kwa kifuasi cha USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Gonga ili upate chaguo zaidi."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Imetambua kifaa cha sauti ya analogi"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Kifaa ulichoambatisha hakitumiki kwenye simu hii. Gonga ili upate maelezo zaidi."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Utatuaji wa USB umeunganishwa"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Gonga ili uzime utatuaji wa USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chagua ili kulemaza utatuaji USB."</string>
@@ -1288,9 +1296,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Imeunganishwa kwa <xliff:g id="SESSION">%s</xliff:g>. Gonga ili kudhibiti mtandao"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Kila mara VPN iliyowashwa inaunganishwa…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Kila mara VPN iliyowashwa imeunganishwa"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Iwe imeondoa VPN kila wakati"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Imeondolewa kwenye VPN iliyowashwa kila wakati"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Kila mara kuna hitilafu ya VPN iliyowashwa"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Gonga ili uweke mipangilio"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Badilisha mipangilio ya VPN au mtandao"</string>
     <string name="upload_file" msgid="2897957172366730416">"Chagua faili"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Hakuna faili iliyochaguliwa"</string>
     <string name="reset" msgid="2448168080964209908">"Weka upya"</string>
@@ -1299,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Gonga ili ufunge hali ya garini."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Kushiriki au kusambaza intaneti kumewashwa"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Gonga ili uweke mipangilio."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Umezima kipengele cha kusambaza mtandao"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Wasiliana na msimamizi wako ili upate maelezo zaidi"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Nyuma"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Ifuatayo"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Ruka"</string>
@@ -1378,9 +1384,9 @@
     <string name="data_usage_warning_body" msgid="6660692274311972007">"Gonga ili uangalie matumizi na mipangilio."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Kikomo data ya 2G-3G kimefikiwa"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Kikomo cha data ya 4G kimefikiwa"</string>
-    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Umefikisha kiwango cha juu kinachoruhusiwa cha matumizi ya data ya simu"</string>
+    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Umefikisha kipimo cha juu cha data"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Kikomo data ya Wi-Fi kimefikiwa"</string>
-    <string name="data_usage_limit_body" msgid="291731708279614081">"Data imesitishwa kwa mzunguko uliosalia"</string>
+    <string name="data_usage_limit_body" msgid="291731708279614081">"Matumizi ya data yamesitishwa kwa kipindi kilichosalia"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Kikomo cha data ya 2G-3G kimezidishwa"</string>
     <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Kikomo cha data cha 4G kimezidishwa"</string>
     <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Umepitisha kiwango cha data ulichoweka"</string>
@@ -1721,14 +1727,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Bandua"</string>
     <string name="app_info" msgid="6856026610594615344">"Maelezo ya programu"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Ungependa kuweka upya mipangilio ya kifaa?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Gonga ili uweke upya kifaa"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Inaanzisha onyesho..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Inaweka upya kifaa..."</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Ungependa kuweka upya mipangilio ya kifaa?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Mabadiliko yoyote hayatahifadhiwa. Onyesho litaanza tena baada ya sekunde <xliff:g id="TIMEOUT">%1$s</xliff:g>..."</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Ghairi"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Weka upya sasa"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> imezimwa"</string>
     <string name="conference_call" msgid="3751093130790472426">"Simu ya Kongamano"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Kidirisha cha vidokezo"</string>
@@ -1772,6 +1772,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Ondoka mara moja kwenye maeneo ya ufuo na mito ili uende kwenye sehemu salama kama vile milimani."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Tulia na utafute hifadhi ya karibu."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Jaribio la ujumbe wa dharura"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Jibu"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM imekataliwa"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM haikubaliwi"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index e59334b..17c7406 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -82,7 +82,7 @@
     <string name="ThreeWCMmi" msgid="9051047170321190368">"மும்முனை அழைப்பு"</string>
     <string name="RuacMmi" msgid="7827887459138308886">"விரும்பத்தகாத தொல்லைதரும் அழைப்புகளை நிராகரித்தல்"</string>
     <string name="CndMmi" msgid="3116446237081575808">"அழைப்பின் விவரங்கள்"</string>
-    <string name="DndMmi" msgid="1265478932418334331">"தொந்தரவு செய்ய வேண்டாம்"</string>
+    <string name="DndMmi" msgid="1265478932418334331">"தொந்தரவு செய்யாதே"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"அழைப்பாளர் ஐடி ஆனது வரையறுக்கப்பட்டது என்பதற்கு இயல்பாக அமைக்கப்பட்டது. அடுத்த அழைப்பு: வரையறுக்கப்பட்டது"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"அழைப்பாளர் ஐடி ஆனது வரையறுக்கப்பட்டது என்பதற்கு இயல்பாக அமைக்கப்பட்டது. அடுத்த அழைப்பு: வரையறுக்கப்படவில்லை"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"அழைப்பாளர் ஐடி ஆனது வரையறுக்கப்படவில்லை என்பதற்கு இயல்பாக அமைக்கப்பட்டது. அடுத்த அழைப்பு: வரையறுக்கப்பட்டது"</string>
@@ -99,7 +99,7 @@
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"விழிப்பூட்டல்கள்"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"அழைப்புப் பகிர்வு"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"அவசரகாலத் திரும்ப அழைக்கும் பயன்முறை"</string>
-    <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"மொபைல் தரவு விழிப்பூட்டல்கள்"</string>
+    <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"மொபைல் டேட்டா விழிப்பூட்டல்கள்"</string>
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS செய்திகள்"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"குரலஞ்சல் செய்திகள்"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"வைஃபை அழைப்பு"</string>
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"சேவையைத் தேடுகிறது"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"வைஃபை அழைப்பு"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"வைஃபை மூலம் அழைக்க மற்றும் செய்திகள் அனுப்ப, முதலில் மொபைல் நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும்."</item>
+    <item msgid="3910386316304772394">"வைஃபை மூலம் அழைக்கவும் செய்திகளை அனுப்பவும், முதலில் தொலைத்தொடர்பு நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும். (பிழைக் குறியீடு <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"உங்கள் மொபைல் நிறுவனத்தில் பதிவுசெய்யவும்"</item>
+    <item msgid="7472393097168811593">"உங்கள் தொலைத்தொடர்பு நிறுவனத்தில் பதிவுசெய்யவும் (பிழைக் குறியீடு: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"குரல் உதவி"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"இப்போது பூட்டு"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"மறைந்துள்ள உள்ளடக்கம்"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"கொள்கையின்படி உள்ளடக்கம் மறைக்கப்பட்டது"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"புதிய அறிவிப்பு"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"விர்ச்சுவல் விசைப்பலகை"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"கைமுறை விசைப்பலகை"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"பாதுகாப்பு"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"விழிப்பூட்டல்கள்"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"விற்பனையாளர் டெமோ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB இணைப்பு"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"பின்னணியில் இயங்கும் பயன்பாடுகள்"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> பின்னணியில் இயங்குகிறது"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> பயன்பாடுகள் பின்னணியில் இயங்குகின்றன"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"பேட்டரியைப் பயன்படுத்தும் பயன்பாடுகள்"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாடு பேட்டரியைப் பயன்படுத்துகிறது"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> பயன்பாடுகள் பேட்டரியைப் பயன்படுத்துகின்றன"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"பேட்டரி மற்றும் தரவு உபயோக விவரங்களைக் காண, தட்டவும்"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"பாதுகாப்பு பயன்முறை"</string>
@@ -288,7 +287,7 @@
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"படங்கள் மற்றும் வீடியோக்கள் எடுக்கலாம்"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"ஃபோன்"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"யாரையும் தொலைபேசியில் அழைக்கலாம்"</string>
-    <string name="permgrouplab_sensors" msgid="416037179223226722">"உடல் உணர்விகள்"</string>
+    <string name="permgrouplab_sensors" msgid="416037179223226722">"உடல் சென்சார்கள்"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"உங்கள் உடல் இயக்கம் பற்றி உணர்விகள் கூறும் தகவலைப் பார்க்கலாம்"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"சாளர உள்ளடக்கத்தைப் பெறும்"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"நீங்கள் பணியாற்றி கொண்டிருக்கும் சாளரத்தின் உள்ளடக்கத்தைப் பார்க்கலாம்."</string>
@@ -301,7 +300,7 @@
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"சைகைகளைச் செயல்படுத்துதல்"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"தட்டலாம், ஸ்வைப் செய்யலாம், பின்ச் செய்யலாம் மற்றும் பிற சைகைகளைச் செயல்படுத்தலாம்."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"கைரேகை சைகைகள்"</string>
-    <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"சாதனத்தின் கைரேகை உணர்வி மேல் செய்யப்படும் சைகைகளைப் படமெடுக்க முடியும்."</string>
+    <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"சாதனத்தின் கைரேகை சென்சார் மேல் செய்யப்படும் சைகைகளைப் படமெடுக்க முடியும்."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"நிலைப் பட்டியை முடக்குதல் அல்லது மாற்றுதல்"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"நிலைப் பட்டியை முடக்க அல்லது முறைமையில் ஐகான்களைச் சேர்க்க மற்றும் அகற்ற பயன்பாட்டை அனுமதிக்கிறது."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"நிலைப் பட்டியில் இருக்கும்"</string>
@@ -354,7 +353,7 @@
     <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"நினைவகத்தில் நிலையாக இருக்கும் தன்னுடைய பகுதிகளை உருவாக்கப் பயன்பாட்டை அனுமதிக்கிறது. இதனால பிற பயன்பாடுகளுக்குக் கிடைக்கும் நினைவகம் வரையறுக்கப்பட்டு, மொபைலின் வேகத்தைக் குறைக்கலாம்"</string>
     <string name="permlab_getPackageSize" msgid="7472921768357981986">"பயன்பாட்டுச் சேமிப்பு இடத்தை அளவிடல்"</string>
     <string name="permdesc_getPackageSize" msgid="3921068154420738296">"பயன்பாடு, அதன் குறியீடு, தரவு, மற்றும் தற்காலிகச் சேமிப்பு அளவுகளை மீட்டெடுக்க அனுமதிக்கிறது"</string>
-    <string name="permlab_writeSettings" msgid="2226195290955224730">"முறைமை அமைப்புகளை மாற்றுதல்"</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"சாதன அமைப்புகளை மாற்றுதல்"</string>
     <string name="permdesc_writeSettings" msgid="7775723441558907181">"முறைமையின் அமைப்பு தரவைத் திருத்த, பயன்பாட்டை அனுமதிக்கிறது. தீங்குவிளைவிக்கும் பயன்பாடுகள், முறைமையின் உள்ளமைவைச் சிதைக்கலாம்."</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"தொடக்கத்தில் இயக்குதல்"</string>
     <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"மறுஇயக்கம் முடிந்தது, விரைவில் தானாகவே தொடங்க, பயன்பாட்டை அனுமதிக்கிறது. இதனால் டேப்லெட் நீண்ட நேரம் கழித்து தொடங்கும் மற்றும் எப்போதும் இயங்குகின்ற டேப்லெட்டின் ஒட்டுமொத்தச் செயல்பாட்டையும் தாமதமாகும்."</string>
@@ -488,7 +487,7 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"கைரேகைக்கான நேரம் முடிந்தது. மீண்டும் முயலவும்."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"கைரேகை செயல்பாடு ரத்துசெய்யப்பட்டது."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"அதிகமான முயற்சிகள். பிறகு முயற்சிக்கவும்."</string>
-    <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"பலமுறை முயன்றுவிட்டீர்கள். கைரேகை உணர்வி முடக்கப்பட்டது."</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"பலமுறை முயன்றுவிட்டீர்கள். கைரேகை சென்சார் முடக்கப்பட்டது."</string>
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"மீண்டும் முயற்சிக்கவும்."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
@@ -567,7 +566,7 @@
     <string name="policydesc_resetPassword" msgid="1278323891710619128">"திரைப் பூட்டை மாற்றும்."</string>
     <string name="policylab_forceLock" msgid="2274085384704248431">"திரையைப் பூட்டு"</string>
     <string name="policydesc_forceLock" msgid="1141797588403827138">"திரை எப்படி, எப்போது பூட்டப்படுகிறது என்பதைக் கட்டுப்படுத்தலாம்."</string>
-    <string name="policylab_wipeData" msgid="3910545446758639713">"எல்லா தரவையும் அழித்தல்"</string>
+    <string name="policylab_wipeData" msgid="3910545446758639713">"எல்லா டேட்டாவையும் அழித்தல்"</string>
     <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"ஆரம்பநிலைத் தரவு மீட்டமைப்பின் மூலம் எச்சரிக்கை வழங்காமல் டேப்லெட்டின் தரவை அழிக்கலாம்."</string>
     <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"தரவின் ஆரம்பநிலை மீட்டமைப்பைச் செயற்படுத்துவதன் மூலம், எச்சரிக்கை எதுவும் செய்யாமல் டிவியின் தரவை அழிக்கிறது."</string>
     <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"ஆரம்பநிலைத் தரவு மீட்டமைப்பின் மூலம் எச்சரிக்கை வழங்காமல் மொபைலின் தரவை அழிக்கலாம்."</string>
@@ -580,7 +579,7 @@
     <string name="policylab_expirePassword" msgid="5610055012328825874">"திரைப் பூட்டு கடவுச்சொல் காலாவதி நேரத்தை அமை"</string>
     <string name="policydesc_expirePassword" msgid="5367525762204416046">"எந்த இடைவெளியில் திரைப் பூட்டின் கடவுச்சொல், பின் அல்லது வடிவம் மாற்றப்பட வேண்டும் என்பதை மாற்றும்."</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"சேமிப்பிட முறைமையாக்கலை அமை"</string>
-    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"சேமித்தப் பயன்பாட்டுத் தரவை முறைமையாக்கப்பட வேண்டும் என்பதைக் கோரலாம்."</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"சேமித்த ஆப்ஸ் டேட்டாவை முறைமையாக்கப்பட வேண்டும் என்பதைக் கோரலாம்."</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"கேமராக்களை முடக்கு"</string>
     <string name="policydesc_disableCamera" msgid="2306349042834754597">"எல்லா சாதன கேமராக்களைப் பயன்படுத்துவதையும் தடுக்கலாம்."</string>
     <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"திரைப் பூட்டின் சில அம்சங்களை முடக்குதல்"</string>
@@ -847,7 +846,7 @@
     <string name="save_password_message" msgid="767344687139195790">"இந்தக் கடவுச்சொல்லை உலாவி நினைவில்கொள்ள விரும்புகிறீர்களா?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"இப்போது இல்லை"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"நினைவில்கொள்"</string>
-    <string name="save_password_never" msgid="8274330296785855105">"எப்போதும் வேண்டாம்"</string>
+    <string name="save_password_never" msgid="8274330296785855105">"ஒருபோதும் வேண்டாம்"</string>
     <string name="open_permission_deny" msgid="7374036708316629800">"இந்தப் பக்கத்தைத் திறக்க, உங்களிடம் அனுமதி இல்லை."</string>
     <string name="text_copied" msgid="4985729524670131385">"உரை கிளிப்போர்டிற்கு நகலெடுக்கப்பட்டது."</string>
     <string name="more_item_label" msgid="4650918923083320495">"மேலும்"</string>
@@ -874,7 +873,7 @@
     <string name="last_month" msgid="3959346739979055432">"சென்ற மாதம்"</string>
     <string name="older" msgid="5211975022815554840">"பழையது"</string>
     <string name="preposition_for_date" msgid="9093949757757445117">"<xliff:g id="DATE">%s</xliff:g> அன்று"</string>
-    <string name="preposition_for_time" msgid="5506831244263083793">"<xliff:g id="TIME">%s</xliff:g> இல்"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"<xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="preposition_for_year" msgid="5040395640711867177">"<xliff:g id="YEAR">%s</xliff:g> இல்"</string>
     <string name="day" msgid="8144195776058119424">"நாள்"</string>
     <string name="days" msgid="4774547661021344602">"நாட்கள்"</string>
@@ -996,8 +995,8 @@
     <string name="no" msgid="5141531044935541497">"ரத்துசெய்"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"கவனத்திற்கு"</string>
     <string name="loading" msgid="7933681260296021180">"ஏற்றுகிறது..."</string>
-    <string name="capital_on" msgid="1544682755514494298">"இயக்கு"</string>
-    <string name="capital_off" msgid="6815870386972805832">"முடக்கு"</string>
+    <string name="capital_on" msgid="1544682755514494298">"ஆன்"</string>
+    <string name="capital_off" msgid="6815870386972805832">"ஆஃப்"</string>
     <string name="whichApplication" msgid="4533185947064773386">"இதைப் பயன்படுத்தி செயலை நிறைவுசெய்"</string>
     <string name="whichApplicationNamed" msgid="8260158865936942783">"%1$s ஐப் பயன்படுத்தி செயலை முடிக்கவும்"</string>
     <string name="whichApplicationLabel" msgid="7425855495383818784">"செயலை முடி"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">பொது வைஃபை நெட்வொர்க்குகள் உள்ளன</item>
       <item quantity="one">பொது வைஃபை நெட்வொர்க் உள்ளது</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"திறந்த வைஃபை நெட்வொர்க்குடன் இணைக்கவும்"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"திறந்த வைஃபை நெட்வொர்க்குடன் இணைக்கிறது"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"வைஃபை நெட்வொர்க்குடன் இணைக்கப்பட்டது"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"வைஃபை நெட்வொர்க்குடன் இணைக்க முடியவில்லை"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"எல்லா நெட்வொர்க்குகளையும் பார்க்க, தட்டவும்"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"இணை"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"எல்லா நெட்வொர்க்குகளும்"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"வைஃபை நெட்வொர்க்கில் உள்நுழையவும்"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"நெட்வொர்க்கில் உள்நுழையவும்"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1116,7 +1122,7 @@
     <string name="network_switch_metered_detail" msgid="5325661434777870353">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> இல் இணைய அணுகல் இல்லாததால், சாதனமானது <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ஐப் பயன்படுத்துகிறது. கட்டணங்கள் விதிக்கப்படலாம்."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> இலிருந்து <xliff:g id="NEW_NETWORK">%2$s</xliff:g>க்கு மாற்றப்பட்டது"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="3979506840912951943">"மொபைல் தரவு"</item>
+    <item msgid="3979506840912951943">"மொபைல் டேட்டா"</item>
     <item msgid="75483255295529161">"வைஃபை"</item>
     <item msgid="6862614801537202646">"புளூடூத்"</item>
     <item msgid="5447331121797802871">"ஈத்தர்நெட்"</item>
@@ -1163,7 +1169,7 @@
     <string name="sim_done_button" msgid="827949989369963775">"முடிந்தது"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"சிம் கார்டு சேர்க்கப்பட்டது"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"மொபைல் நெட்வொர்க்கை அணுக உங்கள் சாதனத்தை மறுதொடக்கம் செய்யவும்."</string>
-    <string name="sim_restart_button" msgid="4722407842815232347">"மறுதொடக்கம்"</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"மீண்டும் தொடங்கு"</string>
     <string name="carrier_app_dialog_message" msgid="7066156088266319533">"புதிய சிம் சரியாக இயங்குவதற்கு, நீங்கள் பயன்படுத்தும் மொபைல் நிறுவனத்திலிருந்து ஒரு பயன்பாட்டை நிறுவி, திறக்க வேண்டும்."</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"பயன்பாட்டைப் பெறுக"</string>
     <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"இப்போது வேண்டாம்"</string>
@@ -1185,8 +1191,10 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB, MIDIக்கு மட்டும்"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB துணைக்கருவியுடன் இணைக்கப்பட்டுள்ளது"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"மேலும் விருப்பங்களுக்கு, தட்டவும்."</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB பிழைதிருத்தம் இணைக்கப்பட்டது"</string>
-    <string name="adb_active_notification_message" msgid="4948470599328424059">"USB பிழை திருத்தத்தை முடக்க, தட்டவும்."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"அனலாக் ஆடியோ துணைக்கருவி கண்டறியப்பட்டது"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"இணைத்துள்ள சாதனமானது இந்த மொபைலுடன் இணங்கவில்லை. மேலும் அறிய, தட்டவும்."</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB பிழைத் திருத்தம் இணைக்கப்பட்டது"</string>
+    <string name="adb_active_notification_message" msgid="4948470599328424059">"USB பிழைத் திருத்தத்தை முடக்க, தட்டவும்."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB பிழைத்திருத்தத்தை முடக்க, தேர்ந்தெடுக்கவும்."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"பிழை அறிக்கையை எடுக்கிறது…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"பிழை அறிக்கையைப் பகிரவா?"</string>
@@ -1201,7 +1209,7 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"மொழியையும் தளவமைப்பையும் தேர்ந்தெடுக்க, தட்டவும்"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"பிற பயன்பாடுகளின் மேலே காட்டு"</string>
+    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"பிற ஆப்ஸின் மேலே காட்டு"</string>
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> பிற பயன்பாடுகளின் மீது தோன்றுகிறது"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> பிற ஆப்ஸின் மீது தோன்றுகிறது"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> இந்த அம்சத்தைப் பயன்படுத்த வேண்டாம் என நினைத்தால், அமைப்புகளைத் திறந்து அதை முடக்க, தட்டவும்."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> உடன் இணைக்கப்பட்டது. நெட்வொர்க்கை நிர்வகிக்க, தட்டவும்."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"எப்போதும் இயங்கும் VPN உடன் இணைக்கிறது…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"எப்போதும் இயங்கும் VPN இணைக்கப்பட்டது"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"எப்போதும் இயங்கும் VPN துண்டிக்கப்பட்டது"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"எப்போதும் இயக்கத்தில் இருக்கும்படி அமைத்த VPN இலிருந்து துண்டிக்கப்பட்டது"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"எப்போதும் இயங்கும் VPN பிழை"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"அமைக்க, தட்டவும்"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"நெட்வொர்க் அல்லது VPN அமைப்புகளை மாற்றவும்"</string>
     <string name="upload_file" msgid="2897957172366730416">"கோப்பைத் தேர்வுசெய்"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"எந்தக் கோப்பும் தேர்வுசெய்யப்படவில்லை"</string>
     <string name="reset" msgid="2448168080964209908">"மீட்டமை"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"கார் பயன்முறையிலிருந்து வெளியேற, தட்டவும்."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"டெதெரிங்/ஹாட்ஸ்பாட் இயங்குகிறது"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"அமைக்க, தட்டவும்."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"இணைப்பு முறை முடக்கப்பட்டுள்ளது"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"விவரங்களுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்"</string>
     <string name="back_button_label" msgid="2300470004503343439">"முந்தையது"</string>
     <string name="next_button_label" msgid="1080555104677992408">"அடுத்து"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"தவிர்"</string>
@@ -1380,12 +1386,12 @@
     <string name="data_usage_warning_body" msgid="6660692274311972007">"தரவு உபயோகம், அமைப்புகளைப் பார்க்க, தட்டவும்."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"2G-3G தரவு வரம்பைக் கடந்தது"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"4G தரவு வரம்பைக் கடந்தது"</string>
-    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"மொபைல் தரவு வரம்பை அடைந்தது"</string>
+    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"மொபைல் டேட்டா வரம்பை அடைந்தது"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"வைஃபை தரவு வரம்பைக் கடந்தது"</string>
     <string name="data_usage_limit_body" msgid="291731708279614081">"மீதமுள்ள சுழற்சிக்கு தரவு இடைநிறுத்தப்பட்டது"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G தரவு வரம்பு கடந்தது"</string>
     <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G தரவு வரம்பு கடந்தது"</string>
-    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"மொபைல் தரவு வரம்பு கடந்தது"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"மொபைல் டேட்டா வரம்பு கடந்தது"</string>
     <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"வைஃபை தரவு வரம்பு கடந்தது"</string>
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"குறிப்பிட்ட வரம்பைவிட <xliff:g id="SIZE">%s</xliff:g> கூடுதல்."</string>
     <string name="data_usage_restricted_title" msgid="5965157361036321914">"பின்புல வரம்பு வரையறுக்கப்பட்டது"</string>
@@ -1419,10 +1425,10 @@
     <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"ஹெட்ஃபோன்கள்"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"மொபைல் வைக்கும் கருவியின் ஸ்பீக்கர்கள்"</string>
     <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
-    <string name="default_audio_route_category_name" msgid="3722811174003886946">"அமைப்பு"</string>
+    <string name="default_audio_route_category_name" msgid="3722811174003886946">"சிஸ்டம்"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"புளூடூத் ஆடியோ"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"வயர்லெஸ் காட்சி"</string>
-    <string name="media_route_button_content_description" msgid="591703006349356016">"திரையிடு"</string>
+    <string name="media_route_button_content_description" msgid="591703006349356016">"Cast"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"சாதனத்துடன் இணைக்கவும்"</string>
     <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"ஸ்கிரீனை சாதனத்தில் திரையிடு"</string>
     <string name="media_route_chooser_searching" msgid="4776236202610828706">"சாதனங்களைத் தேடுகிறது..."</string>
@@ -1623,9 +1629,9 @@
     <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" msgid="1960431123816253034">"பேட்டரி ஆயுளை மேம்படுத்த, பேட்டரி சேமிப்பான் உங்கள் சாதனத்தின் செயல்திறனைக் குறைத்து, அதிர்வு, இடச் சேவைகள் மற்றும் பெரும்பாலான பின்புலத் தரவு போன்றவற்றைக் கட்டுப்படுத்துகிறது. ஒத்திசைவைச் சார்ந்துள்ள மின்னஞ்சல், செய்தியிடல் மற்றும் பிற பயன்பாடுகள் திறக்கும்வரை, அவை புதுப்பிக்கப்படாமல் இருக்கலாம்.\n\nஉங்கள் ஃபோன் சார்ஜ் செய்யப்படும்போது, பேட்டரி சேமிப்பான் தானாகவே முடங்கும்."</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"தரவுப் பயன்பாட்டைக் குறைப்பதற்கு உதவ, பின்புலத்தில் தரவை அனுப்புவது அல்லது பெறுவதிலிருந்து சில பயன்பாடுகளைத் தரவுச் சேமிப்பான் தடுக்கும். தற்போது பயன்படுத்தும் பயன்பாடானது தரவை அணுகலாம், ஆனால் அடிக்கடி அல்ல. எடுத்துக்காட்டாக, படங்களை நீங்கள் தட்டும் வரை, அவை காட்டப்படாது."</string>
-    <string name="data_saver_enable_title" msgid="4674073932722787417">"தரவு சேமிப்பானை இயக்கவா?"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"பேட்டரி ஆயுளை நீட்டிக்க, பேட்டரி சேமிப்பான் உங்கள் சாதனத்தின் செயல்திறனைக் குறைத்து, அதிர்வு, இடச் சேவைகள் மற்றும் பெரும்பாலான பின்புலத் தரவு போன்றவற்றைக் கட்டுப்படுத்துகிறது. ஒத்திசைவைச் சார்ந்துள்ள மின்னஞ்சல், செய்திச் சேவை மற்றும் பிற பயன்பாடுகளைத் திறக்கும்வரை, அவற்றில் புதிய தகவலைப் பார்க்க முடியாமல் போகலாம்.\n\nஉங்கள் ஃபோன் சார்ஜ் செய்யப்படும்போது, பேட்டரி சேமிப்பான் தானாகவே அணைக்கப்படும்."</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"டேட்டா பயன்பாட்டைக் குறைப்பதற்கு உதவ, பின்புலத்தில் டேட்டாவை அனுப்புவது அல்லது பெறுவதிலிருந்து சில பயன்பாடுகளை டேட்டா சேமிப்பான் தடுக்கும். தற்போது பயன்படுத்தும் பயன்பாடானது எப்போதாவது டேட்டாவை அணுகலாம். எடுத்துக்காட்டாக, படங்களை நீங்கள் தட்டும் வரை அவை காட்டப்படாது."</string>
+    <string name="data_saver_enable_title" msgid="4674073932722787417">"டேட்டா சேமிப்பானை இயக்கவா?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"இயக்கு"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d நிமிடங்களுக்கு (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> வரை)</item>
@@ -1661,11 +1667,11 @@
     </plurals>
     <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> வரை"</string>
     <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> மணி (அடுத்த அலாரம்) வரை"</string>
-    <string name="zen_mode_forever" msgid="1916263162129197274">"தொந்தரவு செய்ய வேண்டாம் என்பதை முடக்கும் வரை"</string>
-    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"தொந்தரவு செய்ய வேண்டாம் என்பதை முடக்கும் வரை"</string>
+    <string name="zen_mode_forever" msgid="1916263162129197274">"\'தொந்தரவு செய்யாதே\' என்பதை முடக்கும் வரை"</string>
+    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"\'தொந்தரவு செய்யாதே\' என்பதை முடக்கும் வரை"</string>
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"சுருக்கு"</string>
-    <string name="zen_mode_feature_name" msgid="5254089399895895004">"தொந்தரவு செய்ய வேண்டாம்"</string>
+    <string name="zen_mode_feature_name" msgid="5254089399895895004">"தொந்தரவு செய்யாதே"</string>
     <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"செயலற்ற நேரம்"</string>
     <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"வார இரவு"</string>
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"வார இறுதி"</string>
@@ -1721,20 +1727,14 @@
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"கோப்புகளைப் பார்க்க, தட்டவும்"</string>
     <string name="pin_target" msgid="3052256031352291362">"பின் செய்"</string>
     <string name="unpin_target" msgid="3556545602439143442">"பின்னை அகற்று"</string>
-    <string name="app_info" msgid="6856026610594615344">"பயன்பாட்டுத் தகவல்"</string>
+    <string name="app_info" msgid="6856026610594615344">"ஆப்ஸ் தகவல்"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"சாதனத்தை மீட்டமைக்கவா?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"சாதனத்தை மீட்டமைக்க, தட்டவும்"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"டெமோவைத் தொடங்குகிறது…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"சாதனத்தை மீட்டமைக்கிறது…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"சாதனத்தை மீட்டமைக்கவா?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"மாற்றங்கள் சேமிக்கப்படாது, <xliff:g id="TIMEOUT">%1$s</xliff:g> வினாடிகளில் டெமோ மீண்டும் தொடங்கும்…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"ரத்துசெய்"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"இப்போதே மீட்டமை"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"முடக்கப்பட்டது: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"குழு அழைப்பு"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"உதவிக்குறிப்பு"</string>
-    <string name="app_category_game" msgid="5431836943981492993">"கேம்கள்"</string>
+    <string name="app_category_game" msgid="5431836943981492993">"கேம்ஸ்"</string>
     <string name="app_category_audio" msgid="1659853108734301647">"இசையும் ஆடியோவும்"</string>
     <string name="app_category_video" msgid="2728726078629384196">"திரைப்படங்களும் வீடியோவும்"</string>
     <string name="app_category_image" msgid="4867854544519846048">"புகைப்படங்களும் படங்களும்"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"கடலோரப் பகுதிகளிலும் ஆற்றங்கரைகளிலும் வசிப்பவர்கள் உடனடியாகப் பாதுகாப்பான இடத்திற்குச் (மேட்டுப்பகுதி) செல்லவும்."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"பதட்டப்படாதீர்கள், அருகில் ஏதேனும் பாதுகாப்பான இடம் உள்ளதா எனப் பாருங்கள்."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"அவசரக் காலச் செய்திகளுக்கான சோதனை"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"பதிலளிக்கும்"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"சிம் அனுமதிக்கப்படவில்லை"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"சிம் அமைக்கப்படவில்லை"</string>
diff --git a/core/res/res/values-te-watch/strings.xml b/core/res/res/values-te-watch/strings.xml
index f729eaa..b13032f 100644
--- a/core/res/res/values-te-watch/strings.xml
+++ b/core/res/res/values-te-watch/strings.xml
@@ -20,6 +20,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="1090732262010398759">"<xliff:g id="NUMBER_1">%2$d</xliff:g>లో <xliff:g id="NUMBER_0">%1$d</xliff:g>వ అనువర్తనం."</string>
+    <string name="android_upgrading_apk" msgid="1090732262010398759">"<xliff:g id="NUMBER_1">%2$d</xliff:g>లో<xliff:g id="NUMBER_0">%1$d</xliff:g>వ యాప్."</string>
     <string name="permgrouplab_sensors" msgid="202675452368612754">"సెన్సార్‌లు"</string>
 </resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 9e28969..c012a3e 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -83,10 +83,10 @@
     <string name="RuacMmi" msgid="7827887459138308886">"అవాంఛిత అంతరాయ కాల్‌ల తిరస్కరణ"</string>
     <string name="CndMmi" msgid="3116446237081575808">"కాలింగ్ నంబర్ బట్వాడా"</string>
     <string name="DndMmi" msgid="1265478932418334331">"అంతరాయం కలిగించవద్దు"</string>
-    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"కాలర్ ID డిఫాల్ట్‌గా పరిమితానికి ఉంటుంది. తదుపరి కాల్: పరిమితం చేయబడింది"</string>
-    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"కాలర్ ID డిఫాల్ట్‌గా పరిమితానికి ఉంటుంది. తదుపరి కాల్: అపరిమితం"</string>
-    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"కాలర్ ID డిఫాల్ట్‌గా అపరిమితానికి ఉంటుంది. తదుపరి కాల్: పరిమితం చేయబడింది"</string>
-    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"కాలర్ ID డిఫాల్ట్‌గా అపరిమితానికి ఉంటుంది. తదుపరి కాల్: అపరిమితం"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"కాలర్ ID డిఫాల్ట్‌గా పరిమితానికి ఉంటుంది. తర్వాత కాల్: పరిమితం చేయబడింది"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"కాలర్ ID డిఫాల్ట్‌గా పరిమితానికి ఉంటుంది. తర్వాత కాల్: అపరిమితం"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"కాలర్ ID డిఫాల్ట్‌గా అపరిమితానికి ఉంటుంది. తర్వాత కాల్: పరిమితం చేయబడింది"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"కాలర్ ID డిఫాల్ట్‌గా అపరిమితానికి ఉంటుంది. తర్వాత కాల్: అపరిమితం"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"సేవ కేటాయించబడలేదు."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"మీరు కాలర్ ID సెట్టింగ్‌ను మార్చలేరు."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"డేటా సేవ లేదు"</string>
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"సేవ కోసం శోధిస్తోంది"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi కాలింగ్"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fiలో కాల్‌లు చేయడం మరియు సందేశాలు పంపడం కోసం ముందుగా ఈ సేవను సెటప్ చేయడానికి మీ క్యారియర్‌ను అడగండి. ఆపై సెట్టింగ్‌ల నుండి మళ్లీ Wi-Fi కాలింగ్‌ను ఆన్ చేయండి."</item>
+    <item msgid="3910386316304772394">"Wi-Fiతో కాల్‌లను చేయడానికి మరియు సందేశాలను పంపించడానికి, మొదట ఈ సేవను సెటప్ చేయాల్సిందిగా మీ క్యారియర్‌‌కి చెప్పండి. ఆ తర్వాత సెట్టింగ్‌ల నుండి Wi-Fi కాలింగ్‌ని మళ్లీ ఆన్ చేయండి. (లోపం కోడ్: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"మీ క్యారియర్‌తో నమోదు చేయండి"</item>
+    <item msgid="7472393097168811593">"మీ క్యారియర్‌తో నమోదు చేయండి (ఎర్రర్ కోడ్: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -152,7 +152,7 @@
     <string name="fcComplete" msgid="3118848230966886575">"లక్షణం కోడ్ పూర్తయింది."</string>
     <string name="fcError" msgid="3327560126588500777">"కనెక్షన్ సమస్య లేదా లక్షణం కోడ్ చెల్లదు."</string>
     <string name="httpErrorOk" msgid="1191919378083472204">"సరే"</string>
-    <string name="httpError" msgid="7956392511146698522">"నెట్‌వర్క్ లోపం ఏర్పడింది."</string>
+    <string name="httpError" msgid="7956392511146698522">"నెట్‌వర్క్ ఎర్రర్ ఏర్పడింది."</string>
     <string name="httpErrorLookup" msgid="4711687456111963163">"URLను కనుగొనడం సాధ్యపడలేదు."</string>
     <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"సైట్ ప్రామాణీకరణ స్కీమ్‌కి మద్దతు లేదు."</string>
     <string name="httpErrorAuth" msgid="1435065629438044534">"ప్రామాణీకరించడం సాధ్యపడలేదు."</string>
@@ -164,10 +164,10 @@
     <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"ప్రోటోకాల్‌కి మద్దతు లేదు."</string>
     <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"సురక్షిత కనెక్షన్‌ను వ్యవస్థాపించడం సాధ్యపడలేదు."</string>
     <string name="httpErrorBadUrl" msgid="3636929722728881972">"URL చెల్లనిది అయినందువలన పేజీని తెరవడం సాధ్యపడలేదు."</string>
-    <string name="httpErrorFile" msgid="2170788515052558676">"ఫైల్‌ను ప్రాప్యత చేయడం సాధ్యపడలేదు."</string>
+    <string name="httpErrorFile" msgid="2170788515052558676">"ఫైల్‌ను యాక్సెస్ చేయడం సాధ్యపడలేదు."</string>
     <string name="httpErrorFileNotFound" msgid="6203856612042655084">"అభ్యర్థించిన ఫైల్‌ను కనుగొనడం సాధ్యపడలేదు."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"చాలా ఎక్కువ అభ్యర్థనలు ప్రాసెస్ చేయబడుతున్నాయి. తర్వాత మళ్లీ ప్రయత్నించండి."</string>
-    <string name="notification_title" msgid="8967710025036163822">"<xliff:g id="ACCOUNT">%1$s</xliff:g>కు సైన్‌ఇన్ లోపం"</string>
+    <string name="notification_title" msgid="8967710025036163822">"<xliff:g id="ACCOUNT">%1$s</xliff:g>కు సైన్‌ఇన్ ఎర్రర్"</string>
     <string name="contentServiceSync" msgid="8353523060269335667">"సమకాలీకరణ"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"సమకాలీకరణ"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"చాలా ఎక్కువ <xliff:g id="CONTENT_TYPE">%s</xliff:g> తొలగింపులు."</string>
@@ -246,15 +246,14 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"వాయిస్ అసిస్టెంట్"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ఇప్పుడు లాక్ చేయండి"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"కంటెంట్‌లు దాచబడ్డాయి"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"విధానం ద్వారా కంటెంట్‌లు దాచబడ్డాయి"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"కొత్త నోటిఫికేషన్"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"వర్చువల్ కీబోర్డ్"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"భౌతిక కీబోర్డ్"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"భద్రత"</string>
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"కారు మోడ్"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"ఖాతా స్థితి"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"డెవలపర్ సందేశాలు"</string>
-    <string name="notification_channel_updates" msgid="4794517569035110397">"నవీకరణలు"</string>
+    <string name="notification_channel_updates" msgid="4794517569035110397">"అప్‌డేట్‌లు"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"నెట్‌వర్క్ స్థితి"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"నెట్‌వర్క్ హెచ్చరికలు"</string>
     <string name="notification_channel_network_available" msgid="4531717914138179517">"నెట్‌వర్క్ అందుబాటులో ఉంది"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"హెచ్చరికలు"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"రిటైల్ డెమో"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB కనెక్షన్"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"నేపథ్యంలో అమలు అవుతున్న ఆప్‌లు"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> నేపథ్యంలో అమలు అవుతోంది"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ఆప్‌లు నేపథ్యంలో అమలు అవుతున్నాయి"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"బ్యాటరీని ఉపయోగిస్తున్న యాప్‌లు"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> బ్యాటరీని ఉపయోగిస్తోంది"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> యాప్‌లు బ్యాటరీని ఉపయోగిస్తున్నాయి"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"బ్యాటరీ మరియు డేటా వినియోగ వివరాల కోసం నొక్కండి"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"సురక్షిత మోడ్"</string>
@@ -273,15 +272,15 @@
     <string name="user_owner_label" msgid="1119010402169916617">"వ్యక్తిగతానికి మార్చు"</string>
     <string name="managed_profile_label" msgid="5289992269827577857">"కార్యాలయానికి మార్చు"</string>
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"పరిచయాలు"</string>
-    <string name="permgroupdesc_contacts" msgid="6951499528303668046">"మీ పరిచయాలను ప్రాప్యత చేయడానికి"</string>
+    <string name="permgroupdesc_contacts" msgid="6951499528303668046">"మీ పరిచయాలను యాక్సెస్ చేయడానికి"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"స్థానం"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"ఈ పరికర స్థానాన్ని ప్రాప్యత చేయడానికి"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"ఈ పరికర స్థానాన్ని యాక్సెస్ చేయడానికి"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"క్యాలెండర్"</string>
-    <string name="permgroupdesc_calendar" msgid="3889615280211184106">"మీ క్యాలెండర్‌ను ప్రాప్యత చేయడానికి"</string>
+    <string name="permgroupdesc_calendar" msgid="3889615280211184106">"మీ క్యాలెండర్‌ను యాక్సెస్ చేయడానికి"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS సందేశాలను పంపడం మరియు వీక్షించడం"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"నిల్వ"</string>
-    <string name="permgroupdesc_storage" msgid="637758554581589203">"మీ పరికరంలోని ఫోటోలు, మీడియా మరియు ఫైల్‌లను ప్రాప్యత చేయడానికి"</string>
+    <string name="permgroupdesc_storage" msgid="637758554581589203">"మీ పరికరంలోని ఫోటోలు, మీడియా మరియు ఫైల్‌లను యాక్సెస్ చేయడానికి"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"మైక్రోఫోన్"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ఆడియోను రికార్డ్ చేయడానికి"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"కెమెరా"</string>
@@ -289,7 +288,7 @@
     <string name="permgrouplab_phone" msgid="5229115638567440675">"ఫోన్"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"ఫోన్ కాల్‌లు చేయడం మరియు నిర్వహించడం"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"శరీర సెన్సార్‌లు"</string>
-    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"మీ అత్యంత కీలకమైన గుర్తుల గురించి సెన్సార్ డేటాని ప్రాప్యత చేస్తుంది"</string>
+    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"మీ అత్యంత కీలకమైన గుర్తుల గురించి సెన్సార్ డేటాని యాక్సెస్ చేస్తుంది"</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>
@@ -303,11 +302,11 @@
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"వేలిముద్ర సంజ్ఞలు"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"పరికరాల వేలిముద్ర సెన్సార్‌లో నిర్వహించిన సంజ్ఞలను క్యాప్చర్ చేయవచ్చు."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"స్థితి బార్‌ను నిలిపివేయడం లేదా సవరించడం"</string>
-    <string name="permdesc_statusBar" msgid="8434669549504290975">"స్థితి బార్‌ను నిలిపివేయడానికి లేదా సిస్టమ్ చిహ్నాలను జోడించడానికి మరియు తీసివేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"స్థితి బార్‌ను నిలిపివేయడానికి లేదా సిస్టమ్ చిహ్నాలను జోడించడానికి మరియు తీసివేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"స్థితి పట్టీగా ఉండటం"</string>
-    <string name="permdesc_statusBarService" msgid="716113660795976060">"స్థితి బార్‌ ఉండేలా చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"స్థితి బార్‌ ఉండేలా చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_expandStatusBar" msgid="1148198785937489264">"స్థితి పట్టీని విస్తరింపజేయడం/కుదించడం"</string>
-    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"స్థితి బార్‌ను విస్తరింపజేయడానికి లేదా కుదించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"స్థితి బార్‌ను విస్తరింపజేయడానికి లేదా కుదించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_install_shortcut" msgid="4279070216371564234">"సత్వరమార్గాలను ఇన్‌స్టాల్ చేయడం"</string>
     <string name="permdesc_install_shortcut" msgid="8341295916286736996">"వినియోగదారు ప్రమేయం లేకుండానే హోమ్‌స్క్రీన్ సత్వరమార్గాలను జోడించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"సత్వరమార్గాలను అన్ఇన్‌స్టాల్ చేయడం"</string>
@@ -321,65 +320,65 @@
     <string name="permlab_receiveMms" msgid="1821317344668257098">"వచన సందేశాలను (MMS) స్వీకరించడం"</string>
     <string name="permdesc_receiveMms" msgid="533019437263212260">"MMS సందేశాలను స్వీకరించడానికి మరియు ప్రాసెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. యాప్ మీ డివైజ్‌కు పంపబడిన సందేశాలను మీకు చూపకుండానే పర్యవేక్షించగలదని లేదా తొలగించగలదని దీని అర్థం."</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"సెల్ ప్రసార సందేశాలను చదవడం"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"మీ పరికరం స్వీకరించిన సెల్ ప్రసార సందేశాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. సెల్ ప్రసార హెచ్చరికలు అత్యవసర పరిస్థితుల గురించి మిమ్మల్ని హెచ్చరించడానికి కొన్ని స్థానాల్లో అందించబడతాయి. అత్యవసర సెల్ ప్రసారం స్వీకరించినప్పుడు హానికరమైన అనువర్తనాలు మీ పరికరం యొక్క పనితీరు లేదా నిర్వహణకు అంతరాయం కలిగించవచ్చు."</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"మీ పరికరం స్వీకరించిన సెల్ ప్రసార సందేశాలను చదవడానికి యాప్‌ను అనుమతిస్తుంది. సెల్ ప్రసార హెచ్చరికలు అత్యవసర పరిస్థితుల గురించి మిమ్మల్ని హెచ్చరించడానికి కొన్ని స్థానాల్లో అందించబడతాయి. అత్యవసర సెల్ ప్రసారం స్వీకరించినప్పుడు హానికరమైన యాప్‌లు మీ పరికరం యొక్క పనితీరు లేదా నిర్వహణకు అంతరాయం కలిగించవచ్చు."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"చందా చేయబడిన ఫీడ్‌లను చదవడం"</string>
-    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ప్రస్తుతం సమకాలీకరించిన ఫీడ్‌ల గురించి వివరాలను పొందడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ప్రస్తుతం సమకాలీకరించిన ఫీడ్‌ల గురించి వివరాలను పొందడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_sendSms" msgid="7544599214260982981">"SMS సందేశాలను పంపడం మరియు వీక్షించడం"</string>
-    <string name="permdesc_sendSms" msgid="7094729298204937667">"SMS సందేశాలు పంపడానికి అనువర్తనాన్ని అనుమతిస్తుంది. దీని వలన ఊహించని ఛార్జీలు విధించబడవచ్చు. హానికరమైన అనువర్తనాలు మీ నిర్ధారణ లేకుండానే సందేశాలను పంపడం ద్వారా మీకు డబ్బు ఖర్చయ్యేలా చేయవచ్చు."</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"SMS సందేశాలు పంపడానికి యాప్‌ను అనుమతిస్తుంది. దీని వలన ఊహించని ఛార్జీలు విధించబడవచ్చు. హానికరమైన యాప్‌లు మీ నిర్ధారణ లేకుండానే సందేశాలను పంపడం ద్వారా మీకు డబ్బు ఖర్చయ్యేలా చేయవచ్చు."</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"మీ వచన సందేశాలు (SMS లేదా MMS) చదవడం"</string>
     <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"ఈ యాప్‌ మీ టాబ్లెట్‌లో నిల్వ చేసిన అన్ని SMS (వచన) సందేశాలను చదవగలదు."</string>
     <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"ఈ యాప్‌ మీ టీవీలో నిల్వ చేసిన అన్ని SMS (వచన) సందేశాలను చదవగలదు."</string>
     <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"ఈ యాప్‌ మీ ఫోన్‌లో నిల్వ చేసిన అన్ని SMS (వచన) సందేశాలను చదవగలదు."</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"వచన సందేశాలను (WAP) స్వీకరించడం"</string>
-    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP సందేశాలను స్వీకరించడానికి మరియు ప్రాసెస్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి మీకు పంపబడిన సందేశాలను మీకు చూపకుండానే పర్యవేక్షించగల లేదా తొలగించగల సామర్థ్యాన్ని కలిగి ఉంటుంది."</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP సందేశాలను స్వీకరించడానికి మరియు ప్రాసెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. ఈ అనుమతి మీకు పంపబడిన సందేశాలను మీకు చూపకుండానే పర్యవేక్షించగల లేదా తొలగించగల సామర్థ్యాన్ని కలిగి ఉంటుంది."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"అమలవుతున్న అనువర్తనాలను పునరుద్ధరించడం"</string>
-    <string name="permdesc_getTasks" msgid="7454215995847658102">"ప్రస్తుతం మరియు ఇటీవల అమలవుతున్న విధుల గురించి వివరణాత్మక సమాచారాన్ని తిరిగి పొందడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది పరికరంలో ఉపయోగించబడిన అనువర్తనాల గురించి సమాచారాన్ని కనుగొనడానికి అనువర్తనాన్ని అనుమతించవచ్చు."</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"ప్రస్తుతం మరియు ఇటీవల అమలవుతున్న విధుల గురించి వివరణాత్మక సమాచారాన్ని తిరిగి పొందడానికి యాప్‌ను అనుమతిస్తుంది. ఇది పరికరంలో ఉపయోగించబడిన యాప్‌ల గురించి సమాచారాన్ని కనుగొనడానికి యాప్‌ను అనుమతించవచ్చు."</string>
     <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"ప్రొఫైల్ మరియు పరికర యజమానులను నిర్వహించడం"</string>
     <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"ప్రొఫైల్ యజమానులను మరియు పరికరం యజమానిని సెట్ చేయడానికి అనువర్తనాలను అనుమతిస్తుంది."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"అమలవుతున్న అనువర్తనాలను మళ్లీ క్రమం చేయడం"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"విధులను ముందుకు మరియు నేపథ్యానికి తరలించడానికి యాప్‌ను అనుమతిస్తుంది. యాప్ మీ ప్రమేయం లేకుండానే దీన్ని చేయవచ్చు."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"కారు మోడ్‌ను ప్రారంభించడం"</string>
-    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"కారు మోడ్‌ను ప్రారంభించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"కారు మోడ్‌ను ప్రారంభించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"ఇతర అనువర్తనాలను మూసివేయడం"</string>
-    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"ఇతర అనువర్తనాల నేపథ్య ప్రాసెస్‌లను ముగించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. దీని వలన ఇతర అనువర్తనాలు అమలు కాకుండా ఆపివేయబడవచ్చు."</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"ఇతర యాప్‌ల నేపథ్య ప్రాసెస్‌లను ముగించడానికి యాప్‌ను అనుమతిస్తుంది. దీని వలన ఇతర యాప్‌లు అమలు కాకుండా ఆపివేయబడవచ్చు."</string>
     <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"ఈ యాప్ ఇతర యాప్‌ల పైభాగాన కనిపించగలదు"</string>
     <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"ఈ యాప్ ఇతర యాప్‌ల పైభాగాన లేదా స్క్రీన్ యొక్క ఇతర భాగాలపైన కనిపించగలదు. ఇది సాధారణ యాప్ వినియోగానికి అంతరాయం కలిగించవచ్చు మరియు ఆ ఇతర యాప్‌లు కనిపించే విధానాన్ని మార్చవచ్చు."</string>
     <string name="permlab_runInBackground" msgid="7365290743781858803">"నేపథ్యంలో అమలు చేయండి"</string>
     <string name="permdesc_runInBackground" msgid="7370142232209999824">"ఈ యాప్ నేపథ్యంలో అమలు కావచ్చు. దీని వలన ఎక్కువ బ్యాటరీ శక్తి వినియోగం కావచ్చు."</string>
     <string name="permlab_useDataInBackground" msgid="8694951340794341809">"నేపథ్యంలో డేటాను ఉపయోగించండి"</string>
     <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"ఈ యాప్ నేపథ్యంలో డేటాను ఉపయోగించవచ్చు. దీని వలన డేటా వినియోగం అధికం కావచ్చు."</string>
-    <string name="permlab_persistentActivity" msgid="8841113627955563938">"అనువర్తనాన్ని ఎల్లప్పుడూ అమలు చేయడం"</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"యాప్‌ను ఎల్లప్పుడూ అమలు చేయడం"</string>
     <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"యాప్‌, దాని భాగాలు మెమరీలో ఉండేలా చేయడానికి దానిని అనుమతిస్తుంది. ఇది ఇతర యాప్‌లకు అందుబాటులో ఉన్న మెమరీని ఆక్రమిస్తుంది, టాబ్లెట్ నెమ్మదిగా పని చేస్తుంది."</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"యాప్‌ దానిలోని కొన్ని భాగాలను మెమరీలో ఉంచడానికి దాన్ని అనుమతిస్తుంది. ఇది టీవీ నెమ్మదిగా పని చేసేలా చేస్తూ ఇతర అనువర్తనాలకు అందుబాటులో ఉన్న మెమరీని పరిమితం చేయవచ్చు."</string>
     <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"యాప్‌, దాని భాగాలు మెమరీలో ఉండేలా చేయడానికి దానిని అనుమతిస్తుంది. ఇది ఇతర యాప్‌లకు అందుబాటులో ఉన్న మెమరీని ఆక్రమిస్తుంది, ఫోన్ నెమ్మదిగా పని చేస్తుంది."</string>
-    <string name="permlab_getPackageSize" msgid="7472921768357981986">"అనువర్తన నిల్వ స్థలాన్ని అంచనా వేయడం"</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"యాప్ నిల్వ స్థలాన్ని అంచనా వేయడం"</string>
     <string name="permdesc_getPackageSize" msgid="3921068154420738296">"యాప్‌ కోడ్, డేటా మరియు కాష్ పరిమాణాలను తిరిగి పొందడానికి దాన్ని అనుమతిస్తుంది"</string>
     <string name="permlab_writeSettings" msgid="2226195290955224730">"సిస్టమ్ సెట్టింగ్‌లను సవరించడం"</string>
-    <string name="permdesc_writeSettings" msgid="7775723441558907181">"సిస్టమ్ యొక్క సెట్టింగ్‌ల డేటాను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు మీ సిస్టమ్ యొక్క కాన్ఫిగరేషన్‌ను నాశనం చేయవచ్చు."</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"సిస్టమ్ యొక్క సెట్టింగ్‌ల డేటాను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన యాప్‌లు మీ సిస్టమ్ యొక్క కాన్ఫిగరేషన్‌ను నాశనం చేయవచ్చు."</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"ప్రారంభంలో అమలు చేయడం"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"సిస్టమ్ బూటింగ్‌ను పూర్తి చేసిన వెంటనే దానికదే ప్రారంభించబడటానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది టాబ్లెట్‌ను ప్రారంభించడానికి ఎక్కువ సమయం పట్టేలా చేయవచ్చు మరియు ఎల్లప్పుడూ అమలు చేయడం ద్వారా మొత్తం టాబ్లెట్‌ను నెమ్మదిగా పని చేయడానికి అనువర్తనాన్ని అనుమతించేలా చేయవచ్చు."</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"సిస్టమ్ బూటింగ్‌ను పూర్తి చేసిన వెంటనే దానికదే ప్రారంభించబడటానికి యాప్‌ను అనుమతిస్తుంది. ఇది టాబ్లెట్‌ను ప్రారంభించడానికి ఎక్కువ సమయం పట్టేలా చేయవచ్చు మరియు ఎల్లప్పుడూ అమలు చేయడం ద్వారా మొత్తం టాబ్లెట్‌ను నెమ్మదిగా పని చేయడానికి యాప్‌ను అనుమతించేలా చేయవచ్చు."</string>
     <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"సిస్టమ్ బూటింగ్‌ను పూర్తి చేసిన వెంటనే యాప్ దానికదే ప్రారంభం కావడానికి అనుమతిస్తుంది. ఇది టీవీ ప్రారంభం కావడానికి ఎక్కువ సమయం పట్టేలా చేయవచ్చు మరియు ఎల్లప్పుడూ అమలు కావడం ద్వారా మొత్తం టాబ్లెట్ పనితీరును నెమ్మది చేయడానికి యాప్‌ను అనుమతించవచ్చు."</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"సిస్టమ్ బూటింగ్‌ను పూర్తి చేసిన వెంటనే దానికదే ప్రారంభించబడటానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది ఫోన్‌ను ప్రారంభించడానికి ఎక్కువ సమయం పట్టేలా చేయవచ్చు మరియు ఎల్లప్పుడూ అమలు చేయడం ద్వారా మొత్తం ఫోన్‌ను నెమ్మదిగా పని చేయడానికి అనువర్తనాన్ని అనుమతించేలా చేయవచ్చు."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"సిస్టమ్ బూటింగ్‌ను పూర్తి చేసిన వెంటనే దానికదే ప్రారంభించబడటానికి యాప్‌ను అనుమతిస్తుంది. ఇది ఫోన్‌ను ప్రారంభించడానికి ఎక్కువ సమయం పట్టేలా చేయవచ్చు మరియు ఎల్లప్పుడూ అమలు చేయడం ద్వారా మొత్తం ఫోన్‌ను నెమ్మదిగా పని చేయడానికి యాప్‌ను అనుమతించేలా చేయవచ్చు."</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"స్టిక్కీ ప్రసారాన్ని పంపడం"</string>
-    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"ప్రసారం ముగిసిన తర్వాత భద్రపరచబడే ప్రసారాలను పంపడానికి అనువర్తనాన్ని అనుమతిస్తుంది. అత్యధిక వినియోగం వలన టాబ్లెట్ నెమ్మదిగా పని చేయవచ్చు లేదా అధిక పరిమాణంలో మెమరీని ఉపయోగించడం వలన అస్థిరంగా మారవచ్చు."</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"ప్రసారం ముగిసిన తర్వాత భద్రపరచబడే ప్రసారాలను పంపడానికి యాప్‌ను అనుమతిస్తుంది. అత్యధిక వినియోగం వలన టాబ్లెట్ నెమ్మదిగా పని చేయవచ్చు లేదా అధిక పరిమాణంలో మెమరీని ఉపయోగించడం వలన అస్థిరంగా మారవచ్చు."</string>
     <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"ప్రసారం ముగిసిన తర్వాత భద్రపరచబడే ప్రసారాలను పంపడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఎక్కువగా వినియోగిస్తే అధిక పరిమాణంలో మెమరీని ఉపయోగించడం వలన టీవీ నెమ్మదిగా పని చేయవచ్చు లేదా అస్థిరంగా మారవచ్చు."</string>
-    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"ప్రసారం ముగిసిన తర్వాత భద్రపరచబడే ప్రసారాలను పంపడానికి అనువర్తనాన్ని అనుమతిస్తుంది. అత్యధిక వినియోగం వలన ఫోన్ నెమ్మదిగా పని చేయవచ్చు లేదా అధిక పరిమాణంలో మెమరీని ఉపయోగించడం వలన అస్థిరంగా మారవచ్చు."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"ప్రసారం ముగిసిన తర్వాత భద్రపరచబడే ప్రసారాలను పంపడానికి యాప్‌ను అనుమతిస్తుంది. అత్యధిక వినియోగం వలన ఫోన్ నెమ్మదిగా పని చేయవచ్చు లేదా అధిక పరిమాణంలో మెమరీని ఉపయోగించడం వలన అస్థిరంగా మారవచ్చు."</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"మీ పరిచయాలను చదవడం"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"మీరు నిర్దిష్ట వ్యక్తులకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ టాబ్లెట్‌లో నిల్వ చేయబడిన మీ పరిచయాల గురించి డేటాను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి మీ పరిచయ డేటాను సేవ్ చేయడానికి అనువర్తనాలను అనుమతిస్తుంది మరియు హానికరమైన అనువర్తనాలు మీకు తెలియకుండానే పరిచయ డేటాను భాగస్వామ్యం చేయవచ్చు."</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"మీరు నిర్దిష్ట వ్యక్తులకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ టాబ్లెట్‌లో నిల్వ చేయబడిన మీ పరిచయాల గురించి డేటాను చదవడానికి యాప్‌ను అనుమతిస్తుంది. ఈ అనుమతి మీ పరిచయ డేటాను సేవ్ చేయడానికి యాప్‌లను అనుమతిస్తుంది మరియు హానికరమైన యాప్‌లు మీకు తెలియకుండానే పరిచయ డేటాను షేర్ చేయవచ్చు."</string>
     <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"మీరు నిర్దిష్ట వ్యక్తులకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ టీవీలో నిల్వ చేసిన మీ పరిచయాలకు సంబంధించిన డేటాను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి మీ పరిచయ డేటాను సేవ్ చేయడానికి అనువర్తనాలను అనుమతిస్తుంది మరియు హానికరమైన అనువర్తనాలు మీకు తెలియకుండానే పరిచయ డేటాను భాగస్వామ్యం చేయవచ్చు."</string>
-    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"మీరు నిర్దిష్ట వ్యక్తులకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ ఫోన్‌లో నిల్వ చేయబడిన మీ పరిచయాల గురించి డేటాను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి మీ పరిచయ డేటాను సేవ్ చేయడానికి అనువర్తనాలను అనుమతిస్తుంది మరియు హానికరమైన అనువర్తనాలు మీకు తెలియకుండానే పరిచయ డేటాను భాగస్వామ్యం చేయవచ్చు."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"మీరు నిర్దిష్ట వ్యక్తులకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ ఫోన్‌లో నిల్వ చేయబడిన మీ పరిచయాల గురించి డేటాను చదవడానికి యాప్‌ను అనుమతిస్తుంది. ఈ అనుమతి మీ పరిచయ డేటాను సేవ్ చేయడానికి యాప్‌లను అనుమతిస్తుంది మరియు హానికరమైన యాప్‌లు మీకు తెలియకుండానే పరిచయ డేటాను షేర్ చేయవచ్చు."</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"మీ పరిచయాలను సవరించడం"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"మీరు నిర్దిష్ట పరిచయాలకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ టాబ్లెట్‌లో నిల్వ చేయబడిన మీ పరిచయాల గురించి డేటాను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి పరిచయ డేటాను తొలగించడానికి అనువర్తనాలను అనుమతిస్తుంది."</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"మీరు నిర్దిష్ట పరిచయాలకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ టాబ్లెట్‌లో నిల్వ చేయబడిన మీ పరిచయాల గురించి డేటాను సవరించడానికి యాప్‌ను అనుమతిస్తుంది. ఈ అనుమతి పరిచయ డేటాను తొలగించడానికి యాప్‌లను అనుమతిస్తుంది."</string>
     <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"మీరు నిర్దిష్ట పరిచయాలకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ టీవీలో నిల్వ చేసిన మీ పరిచయాలకు సంబంధించిన డేటాను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి పరిచయ డేటాను తొలగించడానికి అనువర్తనాలను అనుమతిస్తుంది."</string>
-    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"మీరు నిర్దిష్ట పరిచయాలకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ ఫోన్‌లో నిల్వ చేయబడిన మీ పరిచయాల గురించి డేటాను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి పరిచయ డేటాను తొలగించడానికి అనువర్తనాలను అనుమతిస్తుంది."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"మీరు నిర్దిష్ట పరిచయాలకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ ఫోన్‌లో నిల్వ చేయబడిన మీ పరిచయాల గురించి డేటాను సవరించడానికి యాప్‌ను అనుమతిస్తుంది. ఈ అనుమతి పరిచయ డేటాను తొలగించడానికి యాప్‌లను అనుమతిస్తుంది."</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"కాల్ లాగ్‌ను చదవడం"</string>
     <string name="permdesc_readCallLog" msgid="3204122446463552146">"ఈ యాప్‌ మీ కాల్ చరిత్రను చదవగలదు."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"కాల్ లాగ్‌ను వ్రాయడం"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ఇన్‌కమింగ్ మరియు అవుట్‌గోయింగ్ కాల్‌ల గురించిన డేటాతో సహా మీ టాబ్లెట్ యొక్క కాల్ లాగ్‌ను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు మీ కాల్ లాగ్‌ను ఎరేజ్ చేయడానికి లేదా సవరించడానికి దీన్ని ఉపయోగించవచ్చు."</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ఇన్‌కమింగ్ మరియు అవుట్‌గోయింగ్ కాల్‌ల గురించిన డేటాతో సహా మీ టాబ్లెట్ యొక్క కాల్ లాగ్‌ను సవరించడానికి యాప్‌ను అనుమతిస్తుంది. హానికరమైన యాప్‌లు మీ కాల్ లాగ్‌ను ఎరేజ్ చేయడానికి లేదా సవరించడానికి దీన్ని ఉపయోగించవచ్చు."</string>
     <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ఇన్‌కమింగ్ మరియు అవుట్‌గోయింగ్ కాల్‌లకు సంబంధించిన డేటాతో సహా మీ టీవీ కాల్ లాగ్‌ను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు మీ కాల్ లాగ్‌ను తీసివేయడానికి లేదా సవరించడానికి దీన్ని ఉపయోగించవచ్చు."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ఇన్‌కమింగ్ మరియు అవుట్‌గోయింగ్ కాల్‌ల గురించిన డేటాతో సహా మీ ఫోన్ యొక్క కాల్ లాగ్‌ను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు మీ కాల్ లాగ్‌ను ఎరేజ్ చేయడానికి లేదా సవరించడానికి దీన్ని ఉపయోగించవచ్చు."</string>
-    <string name="permlab_bodySensors" msgid="4683341291818520277">"శరీర సెన్సార్‌లను (గుండె స్పందన రేటు మానిటర్‌ల వంటివి) ప్రాప్యత చేయడం"</string>
-    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"మీ శారీరక పరిస్థితిని అనగా మీ గుండె స్పందన రేటు వంటి వాటిని పర్యవేక్షించే సెన్సార్‌ల నుండి డేటాను ప్రాప్యత చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ఇన్‌కమింగ్ మరియు అవుట్‌గోయింగ్ కాల్‌ల గురించిన డేటాతో సహా మీ ఫోన్ యొక్క కాల్ లాగ్‌ను సవరించడానికి యాప్‌ను అనుమతిస్తుంది. హానికరమైన యాప్‌లు మీ కాల్ లాగ్‌ను ఎరేజ్ చేయడానికి లేదా సవరించడానికి దీన్ని ఉపయోగించవచ్చు."</string>
+    <string name="permlab_bodySensors" msgid="4683341291818520277">"శరీర సెన్సార్‌లను (గుండె స్పందన రేటు మానిటర్‌ల వంటివి) యాక్సెస్ చేయండి"</string>
+    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"మీ శారీరక పరిస్థితిని అనగా మీ గుండె స్పందన రేటు వంటి వాటిని పర్యవేక్షించే సెన్సార్‌ల నుండి డేటాను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"క్యాలెండర్ ఈవెంట్‌లు మరియు వివరాలను చదవడం"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"ఈ యాప్ మీ టాబ్లెట్‌లో నిల్వ చేసిన క్యాలెండర్ ఈవెంట్‌లన్నీ చదవగలదు మరియు మీ క్యాలెండర్ డేటాను షేర్ చేయగలదు లేదా సేవ్ చేయగలదు."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"ఈ యాప్‌ మీ టీవీలో నిల్వ చేసిన క్యాలెండర్ ఈవెంట్‌లన్నీ చదవగలదు మరియు మీ క్యాలెండర్ డేటాను షేర్ చేయగలదు లేదా సేవ్ చేయగలదు."</string>
@@ -388,16 +387,16 @@
     <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"ఈ యాప్ మీ టాబ్లెట్‌లో క్యాలెండర్ ఈవెంట్‌లను జోడించగలదు, తీసివేయగలదు లేదా మార్చగలదు. ఈ యాప్ క్యాలెండర్ యజమానుల నుండి వచ్చినట్లుగా సందేశాలను పంపగలదు లేదా ఈవెంట్‌లను వాటి యజమానులకు తెలియకుండానే మార్చగలదు."</string>
     <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"ఈ యాప్ మీ టీవీలో క్యాలెండర్ ఈవెంట్‌లను జోడించగలదు, తీసివేయగలదు లేదా మార్చగలదు. ఈ యాప్ క్యాలెండర్ యజమానుల నుండి వచ్చినట్లుగా సందేశాలను పంపగలదు లేదా ఈవెంట్‌లను వాటి యజమానులకు తెలియకుండానే మార్చగలదు."</string>
     <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"ఈ యాప్ మీ ఫోన్‌లో క్యాలెండర్ ఈవెంట్‌లను జోడించగలదు, తీసివేయగలదు లేదా మార్చగలదు. ఈ యాప్ క్యాలెండర్ యజమానుల నుండి వచ్చినట్లుగా సందేశాలను పంపగలదు లేదా ఈవెంట్‌లను వాటి యజమానులకు తెలియకుండానే మార్చగలదు."</string>
-    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"అదనపు స్థాన ప్రదాత ఆదేశాలను ప్రాప్యత చేయడం"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"అదనపు స్థాన ప్రదాత ఆదేశాలను యాక్సెస్ చేయడం"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"అదనపు స్థాన ప్రదాత ఆదేశాలను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. ఇది GPS లేదా ఇతర స్థాన మూలాల నిర్వహణలో యాప్‌ ప్రమేయం ఉండేలా అనుమతించవచ్చు."</string>
-    <string name="permlab_accessFineLocation" msgid="251034415460950944">"ఖచ్చితమైన స్థానాన్ని (GPS మరియు నెట్‌వర్క్-ఆధారితం) ప్రాప్యత చేయడం"</string>
+    <string name="permlab_accessFineLocation" msgid="251034415460950944">"ఖచ్చితమైన స్థానాన్ని (GPS మరియు నెట్‌వర్క్-ఆధారితం) యాక్సెస్ చేయడం"</string>
     <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"ఈ యాప్‌ GPS ఆధారంగా లేదా సెల్ టవర్‌లు, Wi-Fi నెట్‌వర్క్‌ల వంటి నెట్‌వర్క్ స్థాన మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. యాప్‌ ఉపయోగించడానికి మీ ఫోన్‌లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి. ఇది బ్యాటరీ వినియోగాన్ని పెంచవచ్చు."</string>
-    <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ఇంచుమించు స్థానాన్ని (నెట్‌వర్క్-ఆధారితం) ప్రాప్యత చేయడం"</string>
+    <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ఇంచుమించు స్థానాన్ని (నెట్‌వర్క్-ఆధారితం) యాక్సెస్ చేయడం"</string>
     <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"ఈ యాప్‌ సెల్ టవర్‌లు మరియు Wi-Fi నెట్‌వర్క్‌ల వంటి నెట్‌వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. యాప్‌ ఉపయోగించడానికి మీ టాబ్లెట్‌లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
     <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"ఈ యాప్‌ సెల్ టవర్‌లు మరియు Wi-Fi నెట్‌వర్క్‌ల వంటి నెట్‌వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. యాప్‌ ఉపయోగించడానికి మీ టీవీలో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
     <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"ఈ యాప్‌ సెల్ టవర్‌లు మరియు Wi-Fi నెట్‌వర్క్‌ల వంటి నెట్‌వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. యాప్‌ ఉపయోగించడానికి మీ ఫోన్‌లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"మీ ఆడియో సెట్టింగ్‌లను మార్చడం"</string>
-    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"వాల్యూమ్ మరియు అవుట్‌పుట్ కోసం ఉపయోగించాల్సిన స్పీకర్ వంటి సార్వజనీన ఆడియో సెట్టింగ్‌లను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"వాల్యూమ్ మరియు అవుట్‌పుట్ కోసం ఉపయోగించాల్సిన స్పీకర్ వంటి సార్వజనీన ఆడియో సెట్టింగ్‌లను సవరించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ఆడియోను రికార్డ్ చేయడం"</string>
     <string name="permdesc_recordAudio" msgid="4245930455135321433">"ఈ యాప్ మైక్రోఫోన్‌ని ఉపయోగించి ఎప్పుడైనా ఆడియోను రికార్డ్ చేయగలదు."</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"SIMకి ఆదేశాలను పంపడం"</string>
@@ -405,75 +404,75 @@
     <string name="permlab_camera" msgid="3616391919559751192">"చిత్రాలు మరియు వీడియోలు తీయడం"</string>
     <string name="permdesc_camera" msgid="5392231870049240670">"ఈ యాప్‌ కెమెరాను ఉపయోగించి ఎప్పుడైనా చిత్రాలను తీయగలదు మరియు వీడియోలను రికార్డ్ చేయగలదు."</string>
     <string name="permlab_vibrate" msgid="7696427026057705834">"వైబ్రేషన్‌ను నియంత్రించడం"</string>
-    <string name="permdesc_vibrate" msgid="6284989245902300945">"వైబ్రేటర్‌ను నియంత్రించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"వైబ్రేటర్‌ను నియంత్రించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"నేరుగా కాల్ చేసే ఫోన్ నంబర్‌లు"</string>
-    <string name="permdesc_callPhone" msgid="3740797576113760827">"మీ ప్రమేయం లేకుండా ఫోన్ నంబర్‌లకు కాల్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. దీని వలన అనుకోని ఛార్జీలు విధించబడవచ్చు లేదా కాల్‌లు రావచ్చు. ఇది అత్యవసర నంబర్‌లకు కాల్ చేయడానికి అనువర్తనాన్ని అనుమతించదని గుర్తుంచుకోండి. హానికరమైన అనువర్తనాలు మీ నిర్ధారణ లేకుండానే కాల్‌లు చేయడం ద్వారా మీకు డబ్బు ఖర్చయ్యేలా చేయవచ్చు."</string>
-    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS కాల్ సేవ ప్రాప్యత అనుమతి"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"మీ ప్రమేయం లేకుండా ఫోన్ నంబర్‌లకు కాల్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. దీని వలన అనుకోని ఛార్జీలు విధించబడవచ్చు లేదా కాల్‌లు రావచ్చు. ఇది అత్యవసర నంబర్‌లకు కాల్ చేయడానికి యాప్‌ను అనుమతించదని గుర్తుంచుకోండి. హానికరమైన యాప్‌లు మీ నిర్ధారణ లేకుండానే కాల్‌లు చేయడం ద్వారా మీకు డబ్బు ఖర్చయ్యేలా చేయవచ్చు."</string>
+    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS కాల్ సేవ యాక్సెస్ అనుమతి"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"మీ ప్రమేయం లేకుండా కాల్‌లు చేయడం కోసం IMS సేవను ఉపయోగించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ఫోన్ స్థితి మరియు గుర్తింపుని చదవడం"</string>
-    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"పరికరం యొక్క ఫోన్ లక్షణాలను ప్రాప్యత చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి ఫోన్ నంబర్ మరియు పరికరం IDలను, కాల్ సక్రియంగా ఉందా లేదా అనే విషయాన్ని మరియు కాల్ ద్వారా కనెక్ట్ చేయబడిన రిమోట్ నంబర్‌ను కనుగొనడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"పరికరం యొక్క ఫోన్ ఫీచర్‌లను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. ఈ అనుమతి ఫోన్ నంబర్ మరియు పరికరం IDలను, కాల్ సక్రియంగా ఉందా లేదా అనే విషయాన్ని మరియు కాల్ ద్వారా కనెక్ట్ చేయబడిన రిమోట్ నంబర్‌ను కనుగొనడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"కాల్‌లను సిస్టమ్ ద్వారా వెళ్లేలా చేయి"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"కాలింగ్ అనుభవాన్ని మెరుగుపరచడం కోసం తన కాల్‌లను సిస్టమ్ ద్వారా వెళ్లేలా చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ఫోన్ నంబర్‌లను చదువు"</string>
-    <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"పరికరం యొక్క ఫోన్ నంబర్‌లను ప్రాప్యత చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"పరికరం యొక్క ఫోన్ నంబర్‌లను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"టాబ్లెట్‌ను నిద్రావస్థకు వెళ్లనీయకుండా నిరోధించడం"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"టీవీ నిద్రావస్థకు వెళ్లకుండా నిరోధించడం"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ఫోన్‌ను నిద్రావస్థకు వెళ్లనీయకుండా నిరోధించడం"</string>
-    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"నిద్రావస్థకి వెళ్లకుండా టాబ్లెట్‌ను నిరోధించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"నిద్రావస్థకి వెళ్లకుండా టాబ్లెట్‌ను నిరోధించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"టీవీ నిద్రావస్థకు వెళ్లకుండా నిరోధించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
-    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"నిద్రావస్థకి వెళ్లకుండా ఫోన్‌ను నిరోధించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"నిద్రావస్థకి వెళ్లకుండా ఫోన్‌ను నిరోధించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_transmitIr" msgid="7545858504238530105">"ఇన్‌ఫ్రారెడ్ ప్రసరణ"</string>
     <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"టాబ్లెట్ యొక్క ఇన్‌ఫ్రారెడ్ ట్రాన్స్‌మిటర్‌ను ఉపయోగించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"టీవీ ఇన్‌ఫ్రారెడ్ ట్రాన్స్‌మిటర్‌‌ని ఉపయోగించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"ఫోన్ యొక్క ఇన్‌ఫ్రారెడ్ ట్రాన్స్‌మిటర్‌ను ఉపయోగించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_setWallpaper" msgid="6627192333373465143">"వాల్‌పేపర్‌ను సెట్ చేయడం"</string>
-    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"సిస్టమ్ వాల్‌పేపర్‌ను సెట్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"సిస్టమ్ వాల్‌పేపర్‌ను సెట్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"మీ వాల్‌పేపర్ పరిమాణాన్ని సర్దుబాటు చేయడం"</string>
-    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"సిస్టమ్ వాల్‌పేపర్ పరిమాణం సూచనలను సెట్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"సిస్టమ్ వాల్‌పేపర్ పరిమాణం సూచనలను సెట్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"సమయ మండలిని సెట్ చేయడం"</string>
-    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"టాబ్లెట్ యొక్క సమయ మండలిని మార్చడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"టాబ్లెట్ యొక్క సమయ మండలిని మార్చడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"టీవీ సమయ మండలిని మార్చడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
-    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"ఫోన్ యొక్క సమయ మండలిని మార్చడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"ఫోన్ యొక్క సమయ మండలిని మార్చడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"పరికరంలో ఖాతాలను కనుగొనడం"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"టాబ్లెట్‌కు తెలిసిన ఖాతాల జాబితాను పొందడానికి అనువర్తనాన్ని అనుమతిస్తుంది. దీనిలో మీరు ఇన్‌స్టాల్ చేసిన అనువర్తనాల ద్వారా సృష్టించబడిన ఖాతాలు ఏవైనా ఉండవచ్చు."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"టాబ్లెట్‌కు తెలిసిన ఖాతాల జాబితాను పొందడానికి యాప్‌ను అనుమతిస్తుంది. దీనిలో మీరు ఇన్‌స్టాల్ చేసిన యాప్‌ల ద్వారా సృష్టించబడిన ఖాతాలు ఏవైనా ఉండవచ్చు."</string>
     <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"టీవీకి తెలిసిన ఖాతాల జాబితాను పొందడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇందులో మీరు ఇన్‌స్టాల్ చేసిన అనువర్తనాల ద్వారా సృష్టించబడిన ఖాతాలు కూడా ఉండవచ్చు."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"ఫోన్‌కు తెలిసిన ఖాతాల జాబితాను పొందడానికి అనువర్తనాన్ని అనుమతిస్తుంది. దీనిలో మీరు ఇన్‌స్టాల్ చేసిన అనువర్తనాల ద్వారా సృష్టించబడిన ఖాతాలు ఏవైనా ఉండవచ్చు."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"ఫోన్‌కు తెలిసిన ఖాతాల జాబితాను పొందడానికి యాప్‌ను అనుమతిస్తుంది. దీనిలో మీరు ఇన్‌స్టాల్ చేసిన యాప్‌ల ద్వారా సృష్టించబడిన ఖాతాలు ఏవైనా ఉండవచ్చు."</string>
     <string name="permlab_accessNetworkState" msgid="4951027964348974773">"నెట్‌వర్క్ కనెక్షన్‌లను వీక్షించడం"</string>
-    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"ఏ నెట్‌వర్క్‌లు ఉన్నాయి మరియు కనెక్ట్ చేయబడ్డాయి వంటి నెట్‌వర్క్ కనెక్షన్‌ల గురించి సమాచారాన్ని వీక్షించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"ఏ నెట్‌వర్క్‌లు ఉన్నాయి మరియు కనెక్ట్ చేయబడ్డాయి వంటి నెట్‌వర్క్ కనెక్షన్‌ల గురించి సమాచారాన్ని వీక్షించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_createNetworkSockets" msgid="7934516631384168107">"పూర్తి నెట్‌వర్క్ ప్రాప్యతను కలిగి ఉండటం"</string>
-    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"నెట్‌వర్క్ సాకెట్‌లను సృష్టించడానికి మరియు అనుకూల నెట్‌వర్క్ ప్రోటోకాల్‌లను ఉపయోగించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. బ్రౌజర్ మరియు ఇతర అనువర్తనాలు ఇంటర్నెట్‌కు డేటా పంపడానికి మార్గాలను అందిస్తాయి, కనుక ఇంటర్నెట్‌కు డేటా పంపడానికి ఈ అనుమతి అవసరం లేదు."</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"నెట్‌వర్క్ సాకెట్‌లను సృష్టించడానికి మరియు అనుకూల నెట్‌వర్క్ ప్రోటోకాల్‌లను ఉపయోగించడానికి యాప్‌ను అనుమతిస్తుంది. బ్రౌజర్ మరియు ఇతర యాప్‌లు ఇంటర్నెట్‌కు డేటా పంపడానికి మార్గాలను అందిస్తాయి, కనుక ఇంటర్నెట్‌కు డేటా పంపడానికి ఈ అనుమతి అవసరం లేదు."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"నెట్‌వర్క్ కనెక్టివిటీని మార్చడం"</string>
-    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"నెట్‌వర్క్ కనెక్టివిటీ యొక్క స్థితిని మార్చడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"నెట్‌వర్క్ కనెక్టివిటీ యొక్క స్థితిని మార్చడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"టీథర్ చేయబడిన కనెక్టివిటీని మార్చడం"</string>
-    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"టీథర్ చేసిన నెట్‌వర్క్ కనెక్టివిటీ యొక్క స్థితిని మార్చడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"టీథర్ చేసిన నెట్‌వర్క్ కనెక్టివిటీ యొక్క స్థితిని మార్చడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"Wi-Fi కనెక్షన్‌లను వీక్షించడం"</string>
     <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Wi-Fi ప్రారంభించబడిందా, లేదా మరియు కనెక్ట్ చేయబడిన Wi-Fi పరికరాల పేరు వంటి Wi-Fi నెట్‌వర్కింగ్ గురించి సమాచారాన్ని వీక్షించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"Wi-Fiకి కనెక్ట్ చేయడం మరియు దాని నుండి డిస్‌కనెక్ట్ చేయడం"</string>
-    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Wi-Fi ప్రాప్యత స్థానాలకు కనెక్ట్ చేయడానికి మరియు వాటి నుండి డిస్‌కనెక్ట్ చేయడానికి మరియు Wi-Fi నెట్‌వర్క్‌ల కోసం పరికర కాన్ఫిగరేషన్‌కు మార్పులు చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Wi-Fi యాక్సెస్ స్థానాలకు కనెక్ట్ చేయడానికి మరియు వాటి నుండి డిస్‌కనెక్ట్ చేయడానికి మరియు Wi-Fi నెట్‌వర్క్‌ల కోసం పరికర కాన్ఫిగరేషన్‌కు మార్పులు చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi Multicast స్వీకరణను అనుమతించడం"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"మల్టీక్యాస్ట్ చిరునామాలను ఉపయోగించి మీ టాబ్లెట్‌కు మాత్రమే కాకుండా Wi-Fi నెట్‌వర్క్‌లోని అన్ని పరికరాలకు పంపబడిన ప్యాకెట్‌లను స్వీకరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. మల్టీక్యాస్ట్ యేతర మోడ్ కంటే ఇది ఎక్కువ పవర్ ఉపయోగిస్తుంది."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"మల్టీక్యాస్ట్ చిరునామాలను ఉపయోగించి మీ టాబ్లెట్‌కు మాత్రమే కాకుండా Wi-Fi నెట్‌వర్క్‌లోని అన్ని పరికరాలకు పంపబడిన ప్యాకెట్‌లను స్వీకరించడానికి యాప్‌ను అనుమతిస్తుంది. మల్టీక్యాస్ట్ యేతర మోడ్ కంటే ఇది ఎక్కువ పవర్ ఉపయోగిస్తుంది."</string>
     <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"మల్టీక్యాస్ట్ చిరునామాలను ఉపయోగించి మీ టీవీకి మాత్రమే కాకుండా Wi-Fi నెట్‌వర్క్‌లోని అన్ని పరికరాలకు పంపిన ప్యాకెట్‌లను స్వీకరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది మల్టీక్యాస్ట్ యేతర మోడ్ కంటే ఎక్కువ పవర్‌ను ఉపయోగిస్తుంది."</string>
     <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"మల్టీక్యాస్ట్ చిరునామాలను ఉపయోగించి మీ ఫోన్‌కు మాత్రమే కాకుండా Wi-Fi నెట్‌వర్క్‌లోని అన్ని పరికరాలకు పంపబడిన ప్యాకెట్‌లను స్వీకరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. మల్టీక్యాస్ట్ యేతర మోడ్ కంటే ఇది ఎక్కువ పవర్ ఉపయోగిస్తుంది."</string>
-    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"బ్లూటూత్ సెట్టింగ్‌లను ప్రాప్యత చేయడం"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"స్థానిక బ్లూటూత్ టాబ్లెట్‌ను కాన్ఫిగర్ చేయడానికి మరియు రిమోట్ పరికరాలతో దాన్ని కనుగొనడానికి మరియు జత చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"బ్లూటూత్ సెట్టింగ్‌లను యాక్సెస్ చేయడం"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"స్థానిక బ్లూటూత్ టాబ్లెట్‌ను కాన్ఫిగర్ చేయడానికి మరియు రిమోట్ పరికరాలతో దాన్ని కనుగొనడానికి మరియు జత చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"స్థానిక బ్లూటూత్ టీవీని కాన్ఫిగర్ చేయడానికి మరియు రిమోట్ పరికరాలను గుర్తించి, వాటితో జత చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
-    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"స్థానిక బ్లూటూత్ ఫోన్‌ను కాన్ఫిగర్ చేయడానికి మరియు రిమోట్ పరికరాలతో దాన్ని కనుగొనడానికి మరియు జత చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"స్థానిక బ్లూటూత్ ఫోన్‌ను కాన్ఫిగర్ చేయడానికి మరియు రిమోట్ పరికరాలతో దాన్ని కనుగొనడానికి మరియు జత చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_accessWimaxState" msgid="4195907010610205703">"WiMAXకు కనెక్ట్ చేయడం మరియు దాని నుండి డిస్‌కనెక్ట్ చేయడం"</string>
-    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Wi-Fi ప్రారంభించబడిందా, లేదా మరియు కనెక్ట్ చేయబడిన WiMAX నెట్‌వర్క్‌ల గురించి సమాచారాన్ని కనుగొనడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Wi-Fi ప్రారంభించబడిందా, లేదా మరియు కనెక్ట్ చేయబడిన WiMAX నెట్‌వర్క్‌ల గురించి సమాచారాన్ని కనుగొనడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_changeWimaxState" msgid="340465839241528618">"WiMAX స్థితిని మార్చడం"</string>
     <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"WiMAX నెట్‌వర్క్‌లకు టాబ్లెట్‌ను కనెక్ట్ చేయడానికి మరియు వాటి నుండి టాబ్లెట్‌ను డిస్‌కనెక్ట్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"టీవీని WiMAX నెట్‌వర్క్‌లకు కనెక్ట్ చేయడానికి మరియు వాటి నుండి టీవీని డిస్‌కనెక్ట్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
-    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"WiMAX నెట్‌వర్క్‌లకు ఫోన్‌ను కనెక్ట్ చేయడానికి మరియు వాటి నుండి ఫోన్‌ను డిస్‌కనెక్ట్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"WiMAX నెట్‌వర్క్‌లకు ఫోన్‌ను కనెక్ట్ చేయడానికి మరియు వాటి నుండి ఫోన్‌ను డిస్‌కనెక్ట్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_bluetooth" msgid="6127769336339276828">"బ్లూటూత్ పరికరాలతో జత చేయడం"</string>
-    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"టాబ్లెట్‌లో బ్లూటూత్ యొక్క కాన్ఫిగరేషన్‌ను వీక్షించడానికి మరియు జత చేయబడిన పరికరాలతో కనెక్షన్‌లను ఏర్పాటు చేయడానికి మరియు ఆమోదించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"టాబ్లెట్‌లో బ్లూటూత్ యొక్క కాన్ఫిగరేషన్‌ను వీక్షించడానికి మరియు జత చేయబడిన పరికరాలతో కనెక్షన్‌లను ఏర్పాటు చేయడానికి మరియు ఆమోదించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"బ్లూటూత్ కాన్ఫిగరేషన్‌ను టీవీలో వీక్షించడానికి మరియు జత చేసిన పరికరాలతో కనెక్షన్‌లను ఏర్పాటు చేయడానికి మరియు ఆమోదించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
-    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"ఫోన్‌లో బ్లూటూత్ యొక్క కాన్ఫిగరేషన్‌ను వీక్షించడానికి మరియు జత చేయబడిన పరికరాలతో కనెక్షన్‌లను ఏర్పాటు చేయడానికి మరియు ఆమోదించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"ఫోన్‌లో బ్లూటూత్ యొక్క కాన్ఫిగరేషన్‌ను వీక్షించడానికి మరియు జత చేయబడిన పరికరాలతో కనెక్షన్‌లను ఏర్పాటు చేయడానికి మరియు ఆమోదించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"సమీప క్షేత్ర కమ్యూనికేషన్‌ను నియంత్రించడం"</string>
-    <string name="permdesc_nfc" msgid="7120611819401789907">"సమీప ఫీల్డ్ కమ్యూనికేషన్ (NFC) ట్యాగ్‌లు, కార్డులు మరియు రీడర్‌లతో కమ్యూనికేట్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"సమీప ఫీల్డ్ కమ్యూనికేషన్ (NFC) ట్యాగ్‌లు, కార్డులు మరియు రీడర్‌లతో కమ్యూనికేట్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"మీ స్క్రీన్ లాక్‌ను నిలిపివేయడం"</string>
-    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"కీలాక్ మరియు ఏదైనా అనుబంధించబడిన పాస్‌వర్డ్ భద్రతను నిలిపివేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఉదాహరణకు, ఇన్‌కమింగ్ ఫోన్ కాల్ వస్తున్నప్పుడు ఫోన్ కీలాక్‌ను నిలిపివేస్తుంది, ఆపై కాల్ ముగిసిన తర్వాత కీలాక్‌ను మళ్లీ ప్రారంభిస్తుంది."</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"కీలాక్ మరియు ఏదైనా అనుబంధించబడిన పాస్‌వర్డ్ భద్రతను నిలిపివేయడానికి యాప్‌ను అనుమతిస్తుంది. ఉదాహరణకు, ఇన్‌కమింగ్ ఫోన్ కాల్ వస్తున్నప్పుడు ఫోన్ కీలాక్‌ను నిలిపివేస్తుంది, ఆపై కాల్ ముగిసిన తర్వాత కీలాక్‌ను మళ్లీ ప్రారంభిస్తుంది."</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"వేలిముద్ర హార్డ్‌వేర్‌ని నిర్వహించడానికి అనుమతి"</string>
-    <string name="permdesc_manageFingerprint" msgid="178208705828055464">"వినియోగం కోసం వేలిముద్ర టెంప్లేట్‌లను జోడించే మరియు తొలగించే పద్ధతులను అమలు చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_manageFingerprint" msgid="178208705828055464">"వినియోగం కోసం వేలిముద్ర టెంప్లేట్‌లను జోడించే మరియు తొలగించే పద్ధతులను అమలు చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_useFingerprint" msgid="3150478619915124905">"వేలిముద్ర హార్డ్‌వేర్‌ని ఉపయోగించడానికి అనుమతి"</string>
     <string name="permdesc_useFingerprint" msgid="9165097460730684114">"ప్రామాణీకరణ కోసం వేలిముద్ర హార్డ్‌వేర్‌ను ఉపయోగించడానికి అనువర్తనాన్ని అనుమతిస్తుంది"</string>
     <string name="fingerprint_acquired_partial" msgid="735082772341716043">"పాక్షిక వేలిముద్ర గుర్తించబడింది. దయచేసి మళ్లీ ప్రయత్నించండి."</string>
@@ -499,15 +498,15 @@
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"సమకాలీకరణను ఆన్ మరియు ఆఫ్‌కు టోగుల్ చేయడం"</string>
     <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ఖాతా యొక్క సమకాలీకరణ సెట్టింగ్‌లను సవరించడానికి యాప్‌ను అనుమతిస్తుంది. ఉదాహరణకు, ఇది ఒక ఖాతాతో వ్యక్తుల యాప్ యొక్క సమకాలీకరణను ప్రారంభించడానికి ఉపయోగించబడవచ్చు."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"సమకాలీకరణ గణాంకాలను చదవడం"</string>
-    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"ఖాతా యొక్క సమకాలీకరణ గణాంకాలను అలాగే సమకాలీకరణ ఈవెంట్‌ల చరిత్రను మరియు ఎంత డేటా సమకాలీకరించబడింది అనేవాటిని చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"ఖాతా యొక్క సమకాలీకరణ గణాంకాలను అలాగే సమకాలీకరణ ఈవెంట్‌ల చరిత్రను మరియు ఎంత డేటా సమకాలీకరించబడింది అనేవాటిని చదవడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"మీ USB నిల్వ యొక్క కంటెంట్‌లను చదవడం"</string>
     <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"మీ SD కార్డు యొక్క కంటెంట్‌లను చదవడం"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"మీ USB నిల్వలోని కంటెంట్‌లను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"మీ SD కార్డ్‌లోని కంటెంట్‌లను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"మీ USB నిల్వ యొక్క కంటెంట్‌లను సవరించడం లేదా తొలగించడం"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"మీ SD కార్డు యొక్క కంటెంట్‌లను సవరించడం లేదా తొలగించడం"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"USB నిల్వకు వ్రాయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
-    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"SD కార్డుకి వ్రాయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"USB నిల్వకు వ్రాయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"SD కార్డుకి వ్రాయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_use_sip" msgid="2052499390128979920">"SIP కాల్‌లను చేయడానికి/స్వీకరించడానికి"</string>
     <string name="permdesc_use_sip" msgid="2297804849860225257">"SIP కాల్‌లను చేయడానికి మరియు స్వీకరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"కొత్త టెలికామ్ SIM కనెక్షన్‌లను నమోదు చేయడం"</string>
@@ -523,12 +522,12 @@
     <string name="permlab_control_incall_experience" msgid="9061024437607777619">"ఇన్-కాల్ వినియోగదారు అనుభవాన్ని అందించడం"</string>
     <string name="permdesc_control_incall_experience" msgid="915159066039828124">"ఇన్-కాల్ వినియోగదారుని అనుభవాన్ని అందించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"చారిత్రక నెట్‌వర్క్ వినియోగాన్ని చదవడం"</string>
-    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"నిర్దిష్ట నెట్‌వర్క్‌లు మరియు అనువర్తనాలు కోసం చారిత్రాత్మక నెట్‌వర్క్ వినియోగాన్ని చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"నిర్దిష్ట నెట్‌వర్క్‌లు మరియు యాప్‌ల కోసం చారిత్రాత్మక నెట్‌వర్క్ వినియోగాన్ని చదవడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"నెట్‌వర్క్ విధానాన్ని నిర్వహించడం"</string>
-    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"నెట్‌వర్క్ విధానాలను నిర్వహించడానికి మరియు అనువర్తన-నిర్దిష్ట నిబంధనలను నిర్వచించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"నెట్‌వర్క్ విధానాలను నిర్వహించడానికి మరియు యాప్-నిర్దిష్ట నిబంధనలను నిర్వచించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"నెట్‌వర్క్ వినియోగ అకౌంటింగ్‌ను సవరించడం"</string>
-    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"అనువర్తనాల్లో నెట్‌వర్క్ వినియోగం ఎలా గణించాలనే దాన్ని సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. సాధారణ అనువర్తనాల ద్వారా ఉపయోగించడానికి ఉద్దేశించినది కాదు."</string>
-    <string name="permlab_accessNotifications" msgid="7673416487873432268">"నోటిఫికేషన్‌లను ప్రాప్యత చేయడం"</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"యాప్‌లలో నెట్‌వర్క్ వినియోగం ఎలా గణించాలనే దాన్ని సవరించడానికి యాప్‌ను అనుమతిస్తుంది. సాధారణ యాప్‌ల ద్వారా ఉపయోగించడానికి ఉద్దేశించినది కాదు."</string>
+    <string name="permlab_accessNotifications" msgid="7673416487873432268">"నోటిఫికేషన్‌లను యాక్సెస్ చేయడం"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"నోటిఫికేషన్‌లను, ఇతర అనువర్తనాల ద్వారా పోస్ట్ చేయబడిన వాటిని తిరిగి పొందడానికి, పరిశీలించడానికి మరియు క్లియర్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"నోటిఫికేషన్ పరిశీలన సేవకు అనుబంధించడం"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"నోటిఫికేషన్ పరిశీలన సేవ యొక్క అగ్ర-స్థాయి ఇంటర్‌ఫేస్‌కు అనుబంధించడానికి హోల్డర్‌ను అనుమతిస్తుంది. సాధారణ అనువర్తనాల కోసం ఎప్పటికీ అవసరం ఉండకూడదు."</string>
@@ -542,7 +541,7 @@
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"నెట్‌వర్క్ పరిస్థితులపై పరిశీలనల గురించి తెలుసుకోవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. సాధారణ అనువర్తనాలకు ఎప్పటికీ అవసరం ఉండకూడదు."</string>
     <string name="permlab_setInputCalibration" msgid="4902620118878467615">"ఇన్‌పుట్ పరికరం క్రమాంకనాన్ని మార్చండి"</string>
     <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"టచ్ స్క్రీన్ యొక్క క్రమాంకన పరామితులను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. సాధారణ అనువర్తనాలకు ఎప్పటికీ అవసరం ఉండదు."</string>
-    <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM ప్రమాణపత్రాలను ప్రాప్యత చేయడం"</string>
+    <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM ప్రమాణపత్రాలను యాక్సెస్ చేయడం"</string>
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM ప్రమాణపత్రాలను కేటాయించడానికి మరియు ఉపయోగించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. సాధారణ అనువర్తనాలకు ఎప్పటికీ అవసరం ఉండదు."</string>
     <string name="permlab_handoverStatus" msgid="7820353257219300883">"Android Beam బదిలీ స్థితిని స్వీకరించడం"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"ప్రస్తుత Android Beam బదిలీలకు సంబంధించిన సమాచారాన్ని స్వీకరించడానికి ఈ అనువర్తనాన్ని అనుమతిస్తుంది"</string>
@@ -552,7 +551,7 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"క్యారియర్ సందేశ సేవ యొక్క అగ్ర-స్థాయి ఇంటర్‌ఫేస్‌కు అనుబంధించడానికి హోల్డర్‌ను అనుమతిస్తుంది. సాధారణ అనువర్తనాలకు ఎప్పటికీ అవసరం ఉండదు."</string>
     <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"క్యారియర్ సేవలకు అనుబంధించడం"</string>
     <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"క్యారియర్ సేవలకు అనుబంధించడానికి హోల్డర్‌ను అనుమతిస్తుంది. సాధారణ అనువర్తనాలకు ఎప్పటికీ అవసరం ఉండదు."</string>
-    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"అంతరాయం కలిగించవద్దు ఎంపిక ప్రాప్యత"</string>
+    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"అంతరాయం కలిగించవద్దును యాక్సెస్ చేయడం"</string>
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"అంతరాయం కలిగించవద్దు ఎంపిక కాన్ఫిగరేషన్ చదవడానికి మరియు వ్రాయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"పాస్‌వర్డ్ నియమాలను సెట్ చేయండి"</string>
     <string name="policydesc_limitPassword" msgid="2502021457917874968">"స్క్రీన్ లాక్ పాస్‌వర్డ్‌లు మరియు PINల్లో అనుమతించబడిన పొడవు మరియు అక్షరాలను నియంత్రిస్తుంది."</string>
@@ -580,7 +579,7 @@
     <string name="policylab_expirePassword" msgid="5610055012328825874">"స్క్రీన్ లాక్ పాస్‌వర్డ్ గడువు ముగింపుని సెట్ చేయండి"</string>
     <string name="policydesc_expirePassword" msgid="5367525762204416046">"స్క్రీన్ లాక్ పాస్‌వర్డ్, పిన్ లేదా నమూనాని తప్పనిసరిగా ఎంత తరచుగా మార్చాలనే దాన్ని మారుస్తుంది."</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"నిల్వ గుప్తీకరణను సెట్ చేయండి"</string>
-    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"నిల్వ చేయబడిన అనువర్తన డేటా గుప్తీకరించబడి ఉండటం అవసరం."</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"నిల్వ చేయబడిన యాప్ డేటా గుప్తీకరించబడి ఉండటం అవసరం."</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"కెమెరాలను నిలిపివేయండి"</string>
     <string name="policydesc_disableCamera" msgid="2306349042834754597">"అన్ని పరికర కెమెరాల వినియోగాన్ని నిరోధించండి."</string>
     <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"కొన్ని స్క్రీన్ లాక్ లక్షణాలు నిలిపివేయండి"</string>
@@ -728,9 +727,9 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"సిమ్ కార్డును చొప్పించండి."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"సిమ్ కార్డు లేదు లేదా చదవగలిగేలా లేదు. సిమ్ కార్డును చొప్పించండి."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"నిరుపయోగ సిమ్ కార్డు."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"మీ సిమ్ కార్డు శాశ్వతంగా నిలిపివేయబడింది.\n మరో సిమ్ కార్డు కోసం మీ వైర్‌లెస్ సేవా ప్రదాతను సంప్రదించండి."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"మీ SIM కార్డ్ శాశ్వతంగా నిలిపివేయబడింది.\n మరో SIM కార్డ్‌ని పొందడం కోసం మీ వైర్‌లెస్ సేవా ప్రదాతను సంప్రదించండి."</string>
     <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"మునుపటి ట్రాక్"</string>
-    <string name="lockscreen_transport_next_description" msgid="573285210424377338">"తదుపరి ట్రాక్"</string>
+    <string name="lockscreen_transport_next_description" msgid="573285210424377338">"తర్వాత ట్రాక్"</string>
     <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"పాజ్ చేయి"</string>
     <string name="lockscreen_transport_play_description" msgid="1901258823643886401">"ప్లే చేయి"</string>
     <string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"ఆపివేయి"</string>
@@ -833,17 +832,17 @@
     <string name="autofill_area" msgid="3547409050889952423">"ప్రాంతం"</string>
     <string name="autofill_emirate" msgid="2893880978835698818">"ఎమిరేట్"</string>
     <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"మీ వెబ్ బుక్‌మార్క్‌లు మరియు చరిత్రను చదవడం"</string>
-    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"బ్రౌజర్ సందర్శించిన అన్ని URLల చరిత్ర గురించి మరియు అన్ని బ్రౌజర్ బుక్‌మార్క్‌ల గురించి చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. గమనిక: ఈ అనుమతి మూడవ పక్షం బ్రౌజర్‌లు లేదా వెబ్ బ్రౌజింగ్ సామర్థ్యాలు గల ఇతర అనువర్తనాల ద్వారా అమలు చేయబడకపోవచ్చు."</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"బ్రౌజర్ సందర్శించిన అన్ని URLల చరిత్ర గురించి మరియు అన్ని బ్రౌజర్ బుక్‌మార్క్‌ల గురించి చదవడానికి యాప్‌ను అనుమతిస్తుంది. గమనిక: ఈ అనుమతి మూడవ పక్షం బ్రౌజర్‌లు లేదా వెబ్ బ్రౌజింగ్ సామర్థ్యాలు గల ఇతర యాప్‌ల ద్వారా అమలు చేయబడకపోవచ్చు."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"వెబ్ బుక్‌మార్క్‌లు మరియు చరిత్రను వ్రాయడం"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"మీ టాబ్లెట్‌లో నిల్వ చేయబడిన బ్రౌజర్ చరిత్రను లేదా బుక్‌మార్క్‌లను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది బ్రౌజర్ డేటాను ఎరేజ్ చేయడానికి లేదా సవరించడానికి అనువర్తనాన్ని అనుమతించవచ్చు. గమనిక: ఈ అనుమతి మూడవ పక్షం బ్రౌజర్‌లు లేదా వెబ్ బ్రౌజింగ్ సామర్థ్యాలు గల ఇతర అనువర్తనాల ద్వారా అమలు చేయబడకపోవచ్చు."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"మీ టాబ్లెట్‌లో నిల్వ చేయబడిన బ్రౌజర్ చరిత్రను లేదా బుక్‌మార్క్‌లను సవరించడానికి యాప్‌ను అనుమతిస్తుంది. ఇది బ్రౌజర్ డేటాను ఎరేజ్ చేయడానికి లేదా సవరించడానికి యాప్‌ను అనుమతించవచ్చు. గమనిక: ఈ అనుమతి మూడవ పక్షం బ్రౌజర్‌లు లేదా వెబ్ బ్రౌజింగ్ సామర్థ్యాలు గల ఇతర యాప్‌ల ద్వారా అమలు చేయబడకపోవచ్చు."</string>
     <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"మీ టీవీలో నిల్వ చేసిన బ్రౌజర్ చరిత్ర లేదా బుక్‌మార్క్‌లను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది బ్రౌజర్ డేటాను తీసివేయడానికి లేదా సవరించడానికి అనువర్తనాన్ని అనుమతించవచ్చు. గమనిక: ఈ అనుమతి మూడవ-పక్ష బ్రౌజర్‌లు లేదా వెబ్ బ్రౌజింగ్ సామర్థ్యాలు గల ఇతర అనువర్తనాల ద్వారా అమలు కాకపోవచ్చు."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"మీ ఫోన్‌లో నిల్వ చేయబడిన బ్రౌజర్ చరిత్రను లేదా బుక్‌మార్క్‌లను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది బ్రౌజర్ డేటాను ఎరేజ్ చేయడానికి లేదా సవరించడానికి అనువర్తనాన్ని అనుమతించవచ్చు. గమనిక: ఈ అనుమతి మూడవ పక్షం బ్రౌజర్‌లు లేదా వెబ్ బ్రౌజింగ్ సామర్థ్యాలు గల ఇతర అనువర్తనాల ద్వారా అమలు చేయబడకపోవచ్చు."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"మీ ఫోన్‌లో నిల్వ చేయబడిన బ్రౌజర్ చరిత్రను లేదా బుక్‌మార్క్‌లను సవరించడానికి యాప్‌ను అనుమతిస్తుంది. ఇది బ్రౌజర్ డేటాను ఎరేజ్ చేయడానికి లేదా సవరించడానికి యాప్‌ను అనుమతించవచ్చు. గమనిక: ఈ అనుమతి మూడవ పక్షం బ్రౌజర్‌లు లేదా వెబ్ బ్రౌజింగ్ సామర్థ్యాలు గల ఇతర యాప్‌ల ద్వారా అమలు చేయబడకపోవచ్చు."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"అలారం సెట్ చేయడం"</string>
-    <string name="permdesc_setAlarm" msgid="316392039157473848">"ఇన్‌స్టాల్ చేయబడిన అలారం గడియారం అనువర్తనంలో అలారంను సెట్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. కొన్ని అలారం గల గడియారం అనువర్తనాలు ఈ లక్షణాన్ని అమలు చేయకపోవచ్చు."</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"ఇన్‌స్టాల్ చేయబడిన అలారం గడియారం యాప్‌లో అలారంను సెట్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. కొన్ని అలారం గల గడియారం యాప్‌లు ఈ ఫీచర్‌ను అమలు చేయకపోవచ్చు."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"వాయిస్ మెయిల్‌ను జోడించడం"</string>
-    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"మీ వాయిస్ మెయిల్ ఇన్‌బాక్స్‌కి సందేశాలను జోడించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"మీ వాయిస్ మెయిల్ ఇన్‌బాక్స్‌కి సందేశాలను జోడించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"బ్రౌజర్ భౌగోళిక స్థానం అనుమతులను సవరించడం"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"బ్రౌజర్ యొక్క భౌగోళిక స్థానం అనుమతులను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు ఏకపక్ష వెబ్ సైట్‌లకు స్థాన సమాచారాన్ని అనుమతించడానికి దీన్ని ఉపయోగించవచ్చు."</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"బ్రౌజర్ యొక్క భౌగోళిక స్థానం అనుమతులను సవరించడానికి యాప్‌ను అనుమతిస్తుంది. హానికరమైన యాప్‌లు ఏకపక్ష వెబ్ సైట్‌లకు స్థాన సమాచారాన్ని అనుమతించడానికి దీన్ని ఉపయోగించవచ్చు."</string>
     <string name="save_password_message" msgid="767344687139195790">"మీరు బ్రౌజర్ ఈ పాస్‌వర్డ్‌ను గుర్తుపెట్టుకోవాలని కోరుకుంటున్నారా?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"ఇప్పుడు కాదు"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"గుర్తుంచుకో"</string>
@@ -855,8 +854,8 @@
     <string name="menu_space_shortcut_label" msgid="2410328639272162537">"space"</string>
     <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
     <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"delete"</string>
-    <string name="search_go" msgid="8298016669822141719">"శోధించు"</string>
-    <string name="search_hint" msgid="1733947260773056054">"శోధించు..."</string>
+    <string name="search_go" msgid="8298016669822141719">"వెతుకు"</string>
+    <string name="search_hint" msgid="1733947260773056054">"వెతుకు..."</string>
     <string name="searchview_description_search" msgid="6749826639098512120">"శోధించండి"</string>
     <string name="searchview_description_query" msgid="5911778593125355124">"ప్రశ్నను శోధించండి"</string>
     <string name="searchview_description_clear" msgid="1330281990951833033">"ప్రశ్నను క్లియర్ చేయి"</string>
@@ -991,9 +990,9 @@
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> అమలులో ఉంది"</string>
     <string name="app_running_notification_text" msgid="1197581823314971177">"మరింత సమాచారం కోసం లేదా అనువర్తనాన్ని ఆపివేయడం కోసం నొక్కండి."</string>
     <string name="ok" msgid="5970060430562524910">"సరే"</string>
-    <string name="cancel" msgid="6442560571259935130">"రద్దు చేయండి"</string>
+    <string name="cancel" msgid="6442560571259935130">"రద్దు చేయి"</string>
     <string name="yes" msgid="5362982303337969312">"సరే"</string>
-    <string name="no" msgid="5141531044935541497">"రద్దు చేయండి"</string>
+    <string name="no" msgid="5141531044935541497">"రద్దు చేయి"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"గమనిక"</string>
     <string name="loading" msgid="7933681260296021180">"లోడ్ చేస్తోంది…"</string>
     <string name="capital_on" msgid="1544682755514494298">"ఆన్‌లో ఉంది"</string>
@@ -1023,7 +1022,7 @@
     <string name="use_a_different_app" msgid="8134926230585710243">"వేరొక అనువర్తనాన్ని ఉపయోగించండి"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"సిస్టమ్ సెట్టింగ్‌లు &gt; అనువర్తనాలు &gt; డౌన్‌లోడ్ చేయబడినవిలో డిఫాల్ట్‌ను క్లియర్ చేయి."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"చర్యను ఎంచుకోండి"</string>
-    <string name="chooseUsbActivity" msgid="6894748416073583509">"USB పరికరం కోసం అనువర్తనాన్ని ఎంచుకోండి"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"USB పరికరం కోసం యాప్‌ను ఎంచుకోండి"</string>
     <string name="noApplications" msgid="2991814273936504689">"ఈ చర్యను అమలు చేయగల అనువర్తనాలు ఏవీ లేవు."</string>
     <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> ఆపివేయబడింది"</string>
     <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> ఆపివేయబడింది"</string>
@@ -1060,7 +1059,7 @@
     <string name="android_upgrading_notification_title" msgid="8428357096969413169">"Android నవీకరణను ముగిస్తోంది…"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"అప్‌గ్రేడ్ పూర్తయ్యే వరకు కొన్ని అనువర్తనాలు సరిగ్గా పని చేయకపోవచ్చు"</string>
     <string name="app_upgrading_toast" msgid="3008139776215597053">"<xliff:g id="APPLICATION">%1$s</xliff:g>ని అప్‌గ్రేడ్ చేస్తోంది…"</string>
-    <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>లో <xliff:g id="NUMBER_0">%1$d</xliff:g> అనువర్తనాన్ని అనుకూలీకరిస్తోంది."</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>లో <xliff:g id="NUMBER_0">%1$d</xliff:g> యాప్‌ను అనుకూలీకరిస్తోంది."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g>ని సిద్ధం చేస్తోంది."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"అనువర్తనాలను ప్రారంభిస్తోంది."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"బూట్‌ను ముగిస్తోంది."</string>
@@ -1069,9 +1068,9 @@
     <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"అనువర్తనాలను మార్చాలా?"</string>
     <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"మరో యాప్ ఇప్పటికే అమలవుతోంది, మీరు మరోదాన్ని ప్రారంభించడానికి ముందు అది తప్పనిసరిగా ఆపివేయబడాలి."</string>
     <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g>కు తిరిగి వెళ్లండి"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"కొత్త అనువర్తనాన్ని ప్రారంభించవద్దు."</string>
+    <string name="old_app_description" msgid="2082094275580358049">"కొత్త యాప్‌ను ప్రారంభించవద్దు."</string>
     <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g>ని ప్రారంభించండి"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"పాత అనువర్తనాన్ని సేవ్ చేయకుండానే ఆపివేయండి."</string>
+    <string name="new_app_description" msgid="1932143598371537340">"పాత యాప్‌ను సేవ్ చేయకుండానే ఆపివేయండి."</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> మెమరీ పరిమితిని మించిపోయింది"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"కుప్పలు తెప్పలుగా సేకరించబడింది; షేర్ చేయడానికి నొక్కండి"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"హీప్ డంప్‌ను భాగస్వామ్యం చేయాలా?"</string>
@@ -1106,14 +1105,21 @@
       <item quantity="other">ఓపెన్ Wi-Fi నెట్‌వర్క్‌లు అందుబాటులో ఉన్నాయి</item>
       <item quantity="one">ఓపెన్ Wi-Fi నెట్‌వర్క్ అందుబాటులో ఉంది</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"బహిరంగ Wi‑Fi నెట్‌వర్క్‌కు కనెక్ట్ చేయండి"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"బహిరంగ Wi‑Fi నెట్‌వర్క్‌కు కనెక్ట్ చేస్తోంది"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi నెట్‌వర్క్‌కు కనెక్ట్ చేయబడింది"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi నెట్‌వర్క్‌కు కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"అన్ని నెట్‌వర్క్‌లు చూడటానికి నొక్కండి"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"కనెక్ట్ చేయి"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"అన్ని నెట్‌వర్క్‌లు"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8451173622563841546">"Wi-Fiకి ఇంటర్నెట్ ప్రాప్యత లేదు"</string>
+    <string name="wifi_no_internet" msgid="8451173622563841546">"Wi-Fiకి ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"ఎంపికల కోసం నొక్కండి"</string>
     <string name="network_switch_metered" msgid="4671730921726992671">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>కి మార్చబడింది"</string>
-    <string name="network_switch_metered_detail" msgid="5325661434777870353">"పరికరం <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>కి ఇంటర్నెట్ ప్రాప్యత లేనప్పుడు <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ని ఉపయోగిస్తుంది. ఛార్జీలు వర్తించవచ్చు."</string>
+    <string name="network_switch_metered_detail" msgid="5325661434777870353">"పరికరం <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>కి ఇంటర్నెట్ యాక్సెస్ లేనప్పుడు <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ని ఉపయోగిస్తుంది. ఛార్జీలు వర్తించవచ్చు."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> నుండి <xliff:g id="NEW_NETWORK">%2$s</xliff:g>కి మార్చబడింది"</string>
   <string-array name="network_switch_type_name">
     <item msgid="3979506840912951943">"మొబైల్ డేటా"</item>
@@ -1146,7 +1152,7 @@
     <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ఫోన్ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>కి కనెక్ట్ అయినప్పుడు అది Wi-Fi నుండి తాత్కాలికంగా డిస్‌కనెక్ట్ చేయబడుతుంది"</string>
     <string name="select_character" msgid="3365550120617701745">"అక్షరాన్ని చొప్పించండి"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"SMS సందేశాలు పంపుతోంది"</string>
-    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; పెద్ద సంఖ్యలో SMS సందేశాలను పంపుతోంది. సందేశాలను పంపడం కొనసాగించడానికి మీరు ఈ అనువర్తనాన్ని అనుమతించాలనుకుంటున్నారా?"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; పెద్ద సంఖ్యలో SMS సందేశాలను పంపుతోంది. సందేశాలను పంపడం కొనసాగించడానికి మీరు ఈ యాప్‌ను అనుమతించాలనుకుంటున్నారా?"</string>
     <string name="sms_control_yes" msgid="3663725993855816807">"అనుమతిస్తున్నాను"</string>
     <string name="sms_control_no" msgid="625438561395534982">"తిరస్కరిస్తున్నాను"</string>
     <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ఒక సందేశాన్ని &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;కి పంపాలనుకుంటోంది."</string>
@@ -1162,7 +1168,7 @@
     <string name="sim_removed_message" msgid="2333164559970958645">"మీరు చెల్లుబాటు అయ్యే సిమ్ కార్డు‌ను చొప్పించి పునఃప్రారంభించే వరకు మొబైల్ నెట్‌వర్క్ అందుబాటులో ఉండదు."</string>
     <string name="sim_done_button" msgid="827949989369963775">"పూర్తయింది"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"సిమ్ కార్డు జోడించబడింది"</string>
-    <string name="sim_added_message" msgid="6599945301141050216">"మొబైల్ నెట్‌వర్క్‌ను ప్రాప్యత చేయడానికి మీ పరికరాన్ని పునఃప్రారంభించండి."</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"మొబైల్ నెట్‌వర్క్‌ను యాక్సెస్ చేయడానికి మీ పరికరాన్ని పునఃప్రారంభించండి."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"పునఃప్రారంభించు"</string>
     <string name="carrier_app_dialog_message" msgid="7066156088266319533">"మీ SIM సక్రమంగా పని చేస్తుండటానికి, మీరు మీ క్యారియర్ నుండి ఒక అనువర్తనాన్ని ఇన్‌స్టాల్ చేసుకొని, తెరవాలి."</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"అనువర్తనాన్ని పొందండి"</string>
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI కోసం USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ఉపకరణానికి కనెక్ట్ చేయబడింది"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"మరిన్ని ఎంపికల కోసం నొక్కండి."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"అనలాగ్ ఆడియో ఉపకరణం కనుగొనబడింది"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"జోడించిన పరికరం ఈ ఫోన్‌కు అనుకూలంగా లేదు. మరింత తెలుసుకోవడానికి నొక్కండి."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB డీబగ్గింగ్ కనెక్ట్ చేయబడింది"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB డీబగ్గింగ్‌ను నిలిపివేయడానికి నొక్కండి."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"డీబగ్గింగ్‌ని నిలిపివేయడానికి ఎంచుకోండి."</string>
@@ -1258,17 +1266,17 @@
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"జూమ్ నియంత్రణ కోసం రెండుసార్లు నొక్కండి"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"విడ్జెట్‌ను జోడించడం సాధ్యపడలేదు."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"వెళ్లు"</string>
-    <string name="ime_action_search" msgid="658110271822807811">"శోధించు"</string>
+    <string name="ime_action_search" msgid="658110271822807811">"వెతుకు"</string>
     <string name="ime_action_send" msgid="2316166556349314424">"పంపు"</string>
-    <string name="ime_action_next" msgid="3138843904009813834">"తదుపరి"</string>
+    <string name="ime_action_next" msgid="3138843904009813834">"తర్వాత"</string>
     <string name="ime_action_done" msgid="8971516117910934605">"పూర్తయింది"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"మునుపటి"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"అమలు చేయి"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"<xliff:g id="NUMBER">%s</xliff:g>ని ఉపయోగించి\nనంబర్ డయల్ చేయండి"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g>ని ఉపయోగించి\nపరిచయాన్ని సృష్టించండి"</string>
-    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"క్రింది ఒకటి లేదా అంతకంటే ఎక్కువ అనువర్తనాలు మీ ఖాతాను ప్రాప్యత చేయడానికి ఇప్పుడే మరియు భవిష్యత్తులో అనుమతిని అభ్యర్థించవచ్చు."</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"క్రింది ఒకటి లేదా అంతకంటే ఎక్కువ యాప్‌లు మీ ఖాతాను యాక్సెస్ చేయడానికి ఇప్పుడు మరియు భవిష్యత్తులో అనుమతిని అభ్యర్థించవచ్చు."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"మీరు ఈ అభ్యర్థనను అనుమతించాలనుకుంటున్నారా?"</string>
-    <string name="grant_permissions_header_text" msgid="6874497408201826708">"ప్రాప్యత అభ్యర్థన"</string>
+    <string name="grant_permissions_header_text" msgid="6874497408201826708">"యాక్సెస్ అభ్యర్థన"</string>
     <string name="allow" msgid="7225948811296386551">"అనుమతించండి"</string>
     <string name="deny" msgid="2081879885755434506">"తిరస్కరించండి"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"అనుమతి అభ్యర్థించబడింది"</string>
@@ -1277,7 +1285,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>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g>కు కనెక్ట్ చేయబడింది. నెట్‌వర్క్‌ను నిర్వహించడానికి నొక్కండి."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"ఎల్లప్పుడూ-ఆన్‌లో ఉండే VPN కనెక్ట్ చేయబడుతోంది…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"ఎల్లప్పుడూ-ఆన్‌లో ఉండే VPN కనెక్ట్ చేయబడింది"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"ఎల్లప్పుడూ ఆన్‌లో ఉండే VPN డిస్‌కనెక్ట్ చేయబడింది"</string>
-    <string name="vpn_lockdown_error" msgid="6009249814034708175">"ఎల్లప్పుడూ-ఆన్‌లో ఉండే VPN లోపం"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"సెటప్ చేయడానికి నొక్కండి"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"ఎల్లప్పుడూ ఆన్‌లో ఉండే VPN నుండి డిస్‌కనెక్ట్ చేయబడింది"</string>
+    <string name="vpn_lockdown_error" msgid="6009249814034708175">"ఎల్లప్పుడూ-ఆన్‌లో ఉండే VPN ఎర్రర్"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"నెట్‌వర్క్ లేదా VPN సెట్టింగ్‌లను మార్చండి"</string>
     <string name="upload_file" msgid="2897957172366730416">"ఫైల్‌ను ఎంచుకోండి"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"ఫైల్ ఎంచుకోబడలేదు"</string>
     <string name="reset" msgid="2448168080964209908">"రీసెట్ చేయి"</string>
@@ -1301,10 +1309,8 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"కారు మోడ్ నుండి నిష్క్రమించడానికి నొక్కండి."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"టీథర్ చేయబడినది లేదా హాట్‌స్పాట్ సక్రియంగా ఉండేది"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"సెటప్ చేయడానికి నొక్కండి."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"టీథెరింగ్ నిలిపివేయబడింది"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"వివరాల కోసం మీ నిర్వాహకులను సంప్రదించండి"</string>
     <string name="back_button_label" msgid="2300470004503343439">"వెనుకకు"</string>
-    <string name="next_button_label" msgid="1080555104677992408">"తదుపరి"</string>
+    <string name="next_button_label" msgid="1080555104677992408">"తర్వాత"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"దాటవేయి"</string>
     <string name="no_matches" msgid="8129421908915840737">"సరిపోలికలు లేవు"</string>
     <string name="find_on_page" msgid="1946799233822820384">"పేజీలో కనుగొనండి"</string>
@@ -1350,15 +1356,15 @@
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"సంవత్సరాన్ని పెంచండి"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"సంవత్సరాన్ని తగ్గించండి"</string>
     <string name="date_picker_prev_month_button" msgid="2858244643992056505">"మునుపటి నెల"</string>
-    <string name="date_picker_next_month_button" msgid="5559507736887605055">"తదుపరి నెల"</string>
+    <string name="date_picker_next_month_button" msgid="5559507736887605055">"తర్వాత నెల"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"రద్దు చేయి"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"తొలగించు"</string>
     <string name="keyboardview_keycode_done" msgid="1992571118466679775">"పూర్తయింది"</string>
     <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"మోడ్ మార్పు"</string>
-    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"షిఫ్ట్"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
-    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"అనువర్తనాన్ని ఎంచుకోండి"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"యాప్‌ను ఎంచుకోండి"</string>
     <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>ని ప్రారంభించడం సాధ్యపడలేదు"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"వీటితో భాగస్వామ్యం చేయండి"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>తో భాగస్వామ్యం చేయండి"</string>
@@ -1390,8 +1396,8 @@
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"పేర్కొన్న పరిమితి కంటే <xliff:g id="SIZE">%s</xliff:g> మించిపోయింది."</string>
     <string name="data_usage_restricted_title" msgid="5965157361036321914">"నేపథ్య డేటా పరిమితం చేయబడింది"</string>
     <string name="data_usage_restricted_body" msgid="469866376337242726">"నియంత్రణ తీసివేయడానికి నొక్కండి."</string>
-    <string name="ssl_certificate" msgid="6510040486049237639">"భద్రతా ప్రమాణపత్రం"</string>
-    <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"ఈ ప్రమాణపత్రం చెల్లుబాటు అవుతుంది."</string>
+    <string name="ssl_certificate" msgid="6510040486049237639">"భద్రతా సర్టిఫికెట్"</string>
+    <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"ఈ సర్టిఫికెట్ చెల్లుబాటు అవుతుంది."</string>
     <string name="issued_to" msgid="454239480274921032">"దీనికి జారీ చేయబడింది:"</string>
     <string name="common_name" msgid="2233209299434172646">"సాధారణ పేరు:"</string>
     <string name="org_name" msgid="6973561190762085236">"సంస్థ:"</string>
@@ -1479,20 +1485,20 @@
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"తీసివేయి"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"వాల్యూమ్‌ను సిఫార్సు చేయబడిన స్థాయి కంటే ఎక్కువగా పెంచాలా?\n\nసుదీర్ఘ వ్యవధుల పాటు అధిక వాల్యూమ్‌లో వినడం వలన మీ వినికిడి శక్తి దెబ్బ తినవచ్చు."</string>
-    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"ప్రాప్యత సత్వరమార్గాన్ని ఉపయోగించాలా?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"సత్వరమార్గం ఆన్‌లో ఉన్నప్పుడు, రెండు వాల్యూమ్ బటన్‌లను 3 సెకన్ల పాటు నొక్కితే ప్రాప్యత లక్షణం ప్రారంభం అవుతుంది.\n\n ప్రస్తుత ప్రాప్యత లక్షణం:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n సెట్టింగ్‌లు &gt; ప్రాప్యతలో మీరు లక్షణాన్ని మార్చవచ్చు."</string>
+    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"యాక్సెస్ సామర్థ్యం షార్ట్‌కట్‌ను ఉపయోగించాలా?"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"షార్ట్‌కట్ ఆన్‌లో ఉన్నప్పుడు, రెండు వాల్యూమ్ బటన్‌లను 3 సెకన్ల పాటు నొక్కితే యాక్సెస్ సామర్థ్య ఫీచర్ ప్రారంభం అవుతుంది.\n\n ప్రస్తుత యాక్సెస్ సామర్థ్య ఫీచర్:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n సెట్టింగ్‌లు &gt; యాక్సెస్ సామర్థ్యంలో మీరు ఫీచర్‌ను మార్చవచ్చు."</string>
     <string name="disable_accessibility_shortcut" msgid="627625354248453445">"సత్వరమార్గాన్ని ఆఫ్ చేయి"</string>
     <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"సత్వరమార్గాన్ని ఉపయోగించు"</string>
-    <string name="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_button_prompt_text" msgid="4234556536456854251">"ప్రాప్యత బటన్‌ను మీరు నొక్కినప్పుడు ఉపయోగించాల్సిన ఒక లక్షణాన్ని ఎంచుకోండి:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"లక్షణాలను మార్చడానికి, ప్రాప్యత బటన్‌ను నొక్కి &amp; పట్టుకోండి."</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_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>
     <string name="user_switched" msgid="3768006783166984410">"ప్రస్తుత వినియోగదారు <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>కి మారుస్తోంది…"</string>
     <string name="user_logging_out_message" msgid="8939524935808875155">"<xliff:g id="NAME">%1$s</xliff:g>ని లాగ్ అవుట్ చేస్తోంది…"</string>
     <string name="owner_name" msgid="2716755460376028154">"యజమాని"</string>
-    <string name="error_message_title" msgid="4510373083082500195">"లోపం"</string>
+    <string name="error_message_title" msgid="4510373083082500195">"ఎర్రర్"</string>
     <string name="error_message_change_not_allowed" msgid="1238035947357923497">"ఈ మార్పును మీ నిర్వాహకులు అనుమతించలేదు"</string>
     <string name="app_not_found" msgid="3429141853498927379">"ఈ చర్యను నిర్వహించడానికి యాప్ ఏదీ కనుగొనబడలేదు"</string>
     <string name="revoke" msgid="5404479185228271586">"ఉపసంహరించండి"</string>
@@ -1580,7 +1586,7 @@
     <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"తెలియని పొర్ట్రెయిట్"</string>
     <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"తెలియని ల్యాండ్‍స్కేప్"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"రద్దు చేయబడింది"</string>
-    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"కంటెంట్‌ను వ్రాయడంలో లోపం"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"కంటెంట్‌ను వ్రాయడంలో ఎర్రర్"</string>
     <string name="reason_unknown" msgid="6048913880184628119">"తెలియదు"</string>
     <string name="reason_service_unavailable" msgid="7824008732243903268">"ముద్రణ సేవ ప్రారంభించబడలేదు"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> సేవ ఇన్‌స్టాల్ చేయబడింది"</string>
@@ -1623,7 +1629,7 @@
     <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" msgid="1960431123816253034">"బ్యాటరీ జీవితకాలాన్ని మెరుగుపరచడంలో సహాయపడటానికి, బ్యాటరీ సేవర్ మీ పరికరం పనితీరును తగ్గిస్తుంది మరియు వైబ్రేషన్‌ను, స్థాన సేవలను మరియు అత్యధిక నేపథ్య డేటాను పరిమితం చేస్తుంది. ఇమెయిల్, మెసేజింగ్ మరియు సమకాలీకరణపై ఆధారపడే ఇతర అనువర్తనాలు మీరు వాటిని తెరిస్తే మినహా నవీకరించబడవు.\n\nమీ పరికరం ఛార్జ్ అవుతున్నప్పుడు బ్యాటరీ సేవర్ స్వయంచాలకంగా ఆఫ్ అవుతుంది."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"బ్యాటరీ జీవితకాలాన్ని మెరుగుపరచడంలో సహాయపడటానికి, బ్యాటరీ సేవర్ మీ పరికరం పనితీరును తగ్గిస్తుంది మరియు వైబ్రేషన్‌ను, స్థాన సేవలను మరియు అత్యధిక నేపథ్య డేటాను పరిమితం చేస్తుంది. ఇమెయిల్, మెసేజింగ్ మరియు సమకాలీకరణపై ఆధారపడే ఇతర యాప్‌లు మీరు వాటిని తెరిస్తే మినహా అప్‌డేట్ చేయబడవు.\n\nమీ పరికరం ఛార్జ్ అవుతున్నప్పుడు బ్యాటరీ సేవర్ స్వయంచాలకంగా ఆఫ్ అవుతుంది."</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>
@@ -1660,7 +1666,7 @@
       <item quantity="one">1 గం పాటు</item>
     </plurals>
     <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> వరకు"</string>
-    <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (తదుపరి అలారం) వరకు"</string>
+    <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (తర్వాత అలారం) వరకు"</string>
     <string name="zen_mode_forever" msgid="1916263162129197274">"మీరు అంతరాయం కలిగించవద్దు ఎంపిక ఆఫ్ చేసే వరకు"</string>
     <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"మీరు అంతరాయం కలిగించవద్దు ఎంపిక ఆఫ్ చేసే వరకు"</string>
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
@@ -1706,7 +1712,7 @@
     <string name="language_picker_section_suggested" msgid="8414489646861640885">"సూచించినవి"</string>
     <string name="language_picker_section_all" msgid="3097279199511617537">"అన్ని భాషలు"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"అన్ని ప్రాంతాలు"</string>
-    <string name="locale_search_menu" msgid="2560710726687249178">"శోధించు"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"వెతుకు"</string>
     <string name="work_mode_off_title" msgid="2615362773958585967">"కార్యాలయ మోడ్‌ని ఆన్ చేయాలా?"</string>
     <string name="work_mode_off_message" msgid="2961559609199223594">"ఇది అనువర్తనాలు, నేపథ్య సమకాలీకరణ మరియు సంబంధిత లక్షణాలతో సహా మీ కార్యాలయ ప్రొఫైల్‌ను ఆన్ చేస్తుంది"</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"ఆన్ చేయి"</string>
@@ -1721,16 +1727,10 @@
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ఫైల్‌లను వీక్షించడానికి నొక్కండి"</string>
     <string name="pin_target" msgid="3052256031352291362">"పిన్ చేయి"</string>
     <string name="unpin_target" msgid="3556545602439143442">"అన్‌‌పిన్‌ ‌చేయి"</string>
-    <string name="app_info" msgid="6856026610594615344">"అనువర్తన సమాచారం"</string>
+    <string name="app_info" msgid="6856026610594615344">"యాప్ సమాచారం"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"పరికరాన్ని రీసెట్ చేయాలా?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"పరికరాన్ని రీసెట్ చేయడానికి నొక్కండి"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"డెమోను ప్రారంభిస్తోంది..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"పరికరాన్ని రీసెట్ చేస్తోంది..."</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"పరికరాన్ని రీసెట్ చేయాలా?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"మీరు చేసిన ఏవైనా మార్పులను కోల్పోతారు మరియు డెమో <xliff:g id="TIMEOUT">%1$s</xliff:g> సెకన్లలో మళ్లీ ప్రారంభమవుతుంది…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"రద్దు చేయి"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"ఇప్పుడే రీసెట్ చేయి"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> నిలిపివేయబడింది"</string>
     <string name="conference_call" msgid="3751093130790472426">"కాన్ఫరెన్స్ కాల్"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"సాధనం చిట్కా"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"వెంటనే తీర ప్రాంతాలు మరియు నదీ పరీవాహక ప్రాంతాలను ఖాళీ చేసి మెట్ట ప్రాంతాలకు తరలి వెళ్లండి."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ప్రశాంతంగా ఉండండి మరియు దగ్గర్లో తలదాచుకోండి."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"అత్యవసర సందేశాల పరీక్ష"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"ప్రత్యుత్తరం పంపండి"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM అనుమతించబడదు"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM సక్రియం కాలేదు"</string>
diff --git a/core/res/res/values-television/config.xml b/core/res/res/values-television/config.xml
index d62b93e..cf67abf 100644
--- a/core/res/res/values-television/config.xml
+++ b/core/res/res/values-television/config.xml
@@ -39,4 +39,7 @@
 
     <!-- Whether the device uses the default focus highlight when focus state isn't specified. -->
     <bool name="config_useDefaultFocusHighlight">false</bool>
+
+    <!-- Allow SystemUI to show the shutdown dialog -->
+    <bool name="config_showSysuiShutdown">false</bool>
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 55559d3..1242826 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"กำลังค้นหาบริการ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"การโทรผ่าน Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า"</item>
+    <item msgid="3910386316304772394">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า (รหัสข้อผิดพลาด: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"ลงทะเบียนกับผู้ให้บริการ"</item>
+    <item msgid="7472393097168811593">"ลงทะเบียนกับผู้ให้บริการของคุณ (รหัสข้อผิดพลาด: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ตัวช่วยเสียง"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ล็อกเลย"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"เนื้อหาถูกซ่อนไว้"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"มีการซ่อนเนื้อหาโดยนโยบาย"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"การแจ้งเตือนใหม่"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"แป้นพิมพ์เสมือน"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"แป้นพิมพ์บนเครื่อง"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"ความปลอดภัย"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"การแจ้งเตือน"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"การสาธิตสำหรับผู้ค้าปลีก"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"การเชื่อมต่อ USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"แอปที่กำลังทำงานในเบื้องหลัง"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังทำงานในเบื้องหลัง"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"แอป <xliff:g id="NUMBER">%1$d</xliff:g> กำลังทำงานในเบื้องหลัง"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"แอปหลายแอปกำลังใช้แบตเตอรี่"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังใช้แบตเตอรี่"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"แอป <xliff:g id="NUMBER">%1$d</xliff:g> แอปกำลังใช้แบตเตอรี่"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"แตะเพื่อดูรายละเอียดเกี่ยวกับแบตเตอรี่และปริมาณการใช้อินเทอร์เน็ต"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"โหมดปลอดภัย"</string>
@@ -672,7 +671,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"แฮงเอาท์"</string>
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">" Hangouts"</string>
     <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
     <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">มีหลายเครือข่าย Wi-Fi สาธารณะที่ใช้งานได้</item>
       <item quantity="one">มี 1 เครือข่าย Wi-Fi สาธารณะที่ใช้งานได้</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"เชื่อมต่อเครือข่าย Wi‑Fi แบบเปิด"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"กำลังเชื่อมต่อเครือข่าย Wi‑Fi แบบเปิด"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"เชื่อมต่อเครือข่าย Wi-Fi แล้ว"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ไม่สามารถเชื่อมต่อเครือข่าย Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"แตะเพื่อดูเครือข่ายทั้งหมด"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"เชื่อมต่อ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"เครือข่ายทั้งหมด"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ลงชื่อเข้าใช้เครือข่าย WiFi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ลงชื่อเข้าใช้เครือข่าย"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB สำหรับ MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"เชื่อมต่อกับอุปกรณ์เสริม USB แล้ว"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"แตะเพื่อดูตัวเลือกเพิ่มเติม"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"ตรวจพบอุปกรณ์เสริมสำหรับเสียงแบบแอนะล็อก"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"อุปกรณ์ที่พ่วงไม่สามารถใช้งานร่วมกับโทรศัพท์นี้ แตะเพื่อเรียนรู้เพิ่มเติม"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่องผ่าน USB แล้ว"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"แตะเพื่อปิดใช้การแก้ไขข้อบกพร่องของ USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"เลือกเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"เชื่อมต่อกับ <xliff:g id="SESSION">%s</xliff:g> แตะเพื่อจัดการเครือข่าย"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"กำลังเชื่อมต่อ VPN แบบเปิดตลอดเวลา…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"เชื่อมต่อ VPN แบบเปิดตลอดเวลาแล้ว"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"ยกเลิกการเชื่อมต่อ VPN แบบเปิดตลอดเวลาแล้ว"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"ยกเลิกการเชื่อมต่อกับ VPN แบบเปิดตลอดเวลาแล้ว"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"ข้อผิดพลาดของ VPN แบบเปิดตลอดเวลา"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"แตะเพื่อตั้งค่า"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"เปลี่ยนเครือข่ายหรือการตั้งค่า VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"เลือกไฟล์"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"ไม่ได้เลือกไฟล์ไว้"</string>
     <string name="reset" msgid="2448168080964209908">"รีเซ็ต"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"แตะเพื่อออกจากโหมดรถยนต์"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"การปล่อยสัญญาณหรือฮอตสปอตทำงานอยู่"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"แตะเพื่อตั้งค่า"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ปิดใช้การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือแล้ว"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ติดต่อผู้ดูแลระบบเพื่อขอรายละเอียด"</string>
     <string name="back_button_label" msgid="2300470004503343439">"กลับ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ถัดไป"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ข้าม"</string>
@@ -1624,7 +1630,7 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"อัปเดตโดยผู้ดูแลระบบ"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"ลบโดยผู้ดูแลระบบ"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"เพื่อช่วยยืดอายุการใช้งานแบตเตอรี่ โหมดประหยัดแบตเตอรี่จะลดการทำงานของอุปกรณ์และจำกัดการสั่น บริการตำแหน่ง และข้อมูลแบ็กกราวด์ส่วนใหญ่ สำหรับอีเมล การรับส่งข้อความ และแอปอื่นๆ ที่ใช้การซิงค์จะไม่อัปเดตหากคุณไม่เปิดขึ้นมา\n\nโหมดประหยัดแบตเตอรี่จะปิดโดยอัตโนมัติขณะชาร์จอุปกรณ์"</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"เพื่อช่วยลดปริมาณการใช้อินเทอร์เน็ต โปรแกรมประหยัดอินเทอร์เน็ตจะช่วยป้องกันไม่ให้แอปบางส่วนส่งหรือรับข้อมูลเครือข่ายมือถือในพื้นหลัง แอปที่คุณกำลังใช้งานสามารถเข้าถึงข้อมูลเครือข่ายมือถือได้ แต่อาจไม่บ่อยเท่าเดิม ตัวอย่างเช่น ภาพต่างๆ จะไม่แสดงจนกว่าคุณจะแตะที่ภาพเหล่านั้น"</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"เพื่อช่วยลดปริมาณการใช้อินเทอร์เน็ต โปรแกรมประหยัดอินเทอร์เน็ตจะช่วยป้องกันไม่ให้บางแอปส่งหรือรับข้อมูลเครือข่ายมือถือในการทำงานเบื้องหลัง แอปที่คุณกำลังใช้งานสามารถเข้าถึงข้อมูลเครือข่ายมือถือได้ แต่อาจไม่บ่อยเท่าเดิม ตัวอย่างเช่น ภาพต่างๆ จะไม่แสดงจนกว่าคุณจะแตะที่ภาพเหล่านั้น"</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"เปิดการประหยัดอินเทอร์เน็ตไหม"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"เปิด"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"เลิกปักหมุด"</string>
     <string name="app_info" msgid="6856026610594615344">"ข้อมูลแอป"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"รีเซ็ตอุปกรณ์ไหม"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"แตะเพื่อรีเซ็ตอุปกรณ์"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"กำลังเริ่มการสาธิต…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"กำลังรีเซ็ตอุปกรณ์…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"รีเซ็ตอุปกรณ์ไหม"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"การเปลี่ยนแปลงของคุณจะหายไปและการสาธิตจะเริ่มต้นอีกครั้งใน <xliff:g id="TIMEOUT">%1$s</xliff:g> วินาที…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"ยกเลิก"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"รีเซ็ตทันที"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"ปิดใช้ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"การประชุมสาย"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"เคล็ดลับเครื่องมือ"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"อพยพออกจากจากเขตชายฝั่งทะเลและบริเวณริมแม่น้ำไปยังสถานที่ที่ปลอดภัยกว่า เช่น ที่สูง โดยทันที"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ทำใจให้สงบและหาที่กำบังในบริเวณใกล้เคียง"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"การทดสอบข้อความกรณีฉุกเฉิน"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"ตอบ"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"ไม่อนุญาตให้ใช้ซิม"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"ไม่มีการจัดสรรซิม"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 201890d8..0c50301 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Naghahanap ng Serbisyo"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Pagtawag sa pamamagitan ng Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Upang tumawag at magpadala ng mga mensahe sa pamamagitan ng Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay muling i-on ang pagtawag sa Wi-Fi mula sa Mga Setting."</item>
+    <item msgid="3910386316304772394">"Upang makatawag at makapagpadala ng mga mensahe sa Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay i-on muli ang pagtawag gamit ang Wi-Fi mula sa Mga Setting. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Magparehistro sa iyong carrier"</item>
+    <item msgid="7472393097168811593">"Iparehistro sa iyong carrier (Code ng error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"I-lock ngayon"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Nakatago ang mga content"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Itinago ang mga content alinsunod sa patakaran"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Bagong notification"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtual na keyboard"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Pisikal na keyboard"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Seguridad"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Mga Alerto"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Retail demo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Koneksyon ng USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Tumatakbo ang mga app sa background"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Tumatakbo ang <xliff:g id="APP_NAME">%1$s</xliff:g> sa background"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> (na) app ang tumatakbo sa background"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Mga app na kumokonsumo ng baterya"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Gumagamit ng baterya ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Gumagamit ng baterya ang <xliff:g id="NUMBER">%1$d</xliff:g> (na) app"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"I-tap para sa mga detalye tungkol sa paggamit ng baterya at data"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
@@ -977,7 +976,7 @@
     <string name="redo" msgid="7759464876566803888">"Gawing muli"</string>
     <string name="autofill" msgid="3035779615680565188">"I-autofill"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Pagpili ng teksto"</string>
-    <string name="addToDictionary" msgid="4352161534510057874">"Idagdag sa diksyunaryo"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"Idagdag sa diksyonaryo"</string>
     <string name="deleteText" msgid="6979668428458199034">"I-delete"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Pamamaraan ng pag-input"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Pagkilos ng teksto"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="one">Available ang mga bukas na Wi-Fi network</item>
       <item quantity="other">Available ang mga bukas na Wi-Fi network</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Kumonekta sa bukas na Wi‑Fi network"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Kumokonekta sa bukas na Wi‑Fi network"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Nakakonekta sa Wi‑Fi network"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Hindi makakonekta sa Wi‑Fi network"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"I-tap upang makita ang lahat ng network"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kumonekta"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Lahat ng Network"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Mag-sign in sa Wi-Fi network"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Mag-sign in sa network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para sa MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Nakakonekta sa isang accessory ng USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"I-tap para sa higit pang mga opsyon."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"May na-detect na analog na audio accessory"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Hindi tugma sa teleponong ito ang naka-attach na device. I-tap upang matuto pa."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Konektado ang debugging ng USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"I-tap upang i-disable ang pag-debug ng USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Piliin upang i-disable ang debugging ng USB."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Nakakonekta sa <xliff:g id="SESSION">%s</xliff:g>. Tapikin upang pamahalaan ang network."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Kumukonekta ang Always-on VPN…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Nakakonekta ang Always-on VPN"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Hindi nakakonekta ang palaging naka-on na VPN"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Nadiskonekta sa VPN na palaging naka-on"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Error sa Always-on VPN"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"I-tap upang i-set up"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Baguhin ang mga setting ng network o VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Pumili ng file"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Walang napiling file"</string>
     <string name="reset" msgid="2448168080964209908">"I-reset"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"I-tap upang lumabas sa car mode."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Pagsasama o aktibong hotspot"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"I-tap upang i-set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Naka-disable ang pag-tether"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Makipag-ugnayan sa iyong admin para sa mga detalye"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Bumalik"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Susunod"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Laktawan"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"I-unpin"</string>
     <string name="app_info" msgid="6856026610594615344">"Impormasyon ng app"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Gusto mo bang i-reset ang device?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Mag-tap upang i-reset ang device"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Sinisimulan ang demo…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Nire-reset ang device…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Gusto mo bang i-reset ang device?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Mawawala mo ang anumang mga pagbabago at magsisimulang muli ang demo pagkalipas ng <xliff:g id="TIMEOUT">%1$s</xliff:g> (na) segundo…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Kanselahin"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"I-reset ngayon"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Na-disable ang <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Conference Call"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Tooltip"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Umalis kaagad sa mga baybayin at pampang, at pumunta sa isang mas ligtas na lokasyon tulad ng isang mataas na lugar."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Manatiling kalmado at maghanap ng matutuluyan sa malapit."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Pagsubok sa mga mensaheng pang-emergency"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Tumugon"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Hindi pinahihintulutan ang SIM"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Hindi naprobisyon ang SIM"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 812ac76..393523a 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Hizmet Aranıyor"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Kablosuz Çağrı"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Kablosuz ağ üzerinden telefon etmek ve ileti göndermek için ilk önce operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra tekrar Ayarlar\'dan Kablosuz çağrı özelliğini açın."</item>
+    <item msgid="3910386316304772394">"Kablosuz ağ üzerinden telefon etmek ve mesaj göndermek için öncelikle operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra, Ayarlar\'dan Kablosuz çağrı özelliğini tekrar açın. (Hata kodu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Operatörünüze kaydolun"</item>
+    <item msgid="7472393097168811593">"Operatörünüze kaydettirin (Hata kodu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Sesli Yardım"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Şimdi kilitle"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"İçerik gizlendi"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"İçerikler politika nedeniyle gizlendi"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Yeni bildirim"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Sanal klavye"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fiziksel klavye"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Güvenlik"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Uyarılar"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Mağaza demo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB bağlantısı"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Arka planda çalışan uygulamalar"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> arka planda çalışıyor"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> uygulama arka planda çalışıyor"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Pil kullanan uygulamalar"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> pil kullanıyor"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> uygulama pil kullanıyor"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Pil ve veri kullanımı ile ilgili ayrıntılar için dokunun"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Güvenli mod"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Kullanılabilir Kablosuz ağları aç</item>
       <item quantity="one">Kullanılabilir Kablosuz ağı aç</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Açık kablosuz ağa bağlanın"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Açık kablosuz ağa bağlandı"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Kablosuz ağa bağlanıldı"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kablosuz ağa bağlanamadı"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tüm ağları görmek için dokunun"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Bağlan"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tüm Ağlar"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Kablosuz ağda oturum açın"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Ağda oturum açın"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI için USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB aksesuarına bağlandı"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Diğer seçenekler için dokunun."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analog ses aksesuarı algılandı"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Takılan cihaz bu telefonla uyumlu değil. Daha fazla bilgi edinmek için dokunun."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB hata ayıklama özelliğini devre dışı bırakmak için dokunun."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB hata ayıklamasını devre dışı bırakmak için seçin."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> oturumuna bağlı. Ağı yönetmek için dokunun."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Her zaman açık VPN\'ye bağlanılıyor…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Her zaman açık VPN\'ye bağlanıldı"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Her zaman açık VPN bağlantısı kesildi"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Her zaman açık VPN bağlantı kesildi"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Her zaman açık VPN hatası"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Ayarlamak için dokunun"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Ağ veya VPN ayarlarını değiştirin"</string>
     <string name="upload_file" msgid="2897957172366730416">"Dosya seç"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Seçili dosya yok"</string>
     <string name="reset" msgid="2448168080964209908">"Sıfırla"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Araba modundan çıkmak için dokunun."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering veya hotspot etkin"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Ayarlamak için dokunun."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering devre dışı bırakıldı"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ayrıntılı bilgi için yöneticinize başvurun"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Geri"</string>
     <string name="next_button_label" msgid="1080555104677992408">"İleri"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Atla"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Sabitlemeyi kaldır"</string>
     <string name="app_info" msgid="6856026610594615344">"Uygulama bilgileri"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Cihaz sıfırlansın mı?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Cihazı sıfırlamak için dokunun"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Demo başlatılıyor…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Cihaz sıfırlanıyor…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Cihaz sıfırlansın mı?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Değişiklikleri kaybedeceksiniz ve demo <xliff:g id="TIMEOUT">%1$s</xliff:g> saniye içinde tekrar başlayacak…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"İptal"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Şimdi sıfırla"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> devre dışı"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konferans Çağrısı"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"İpucu"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Kıyı kesimlerini ve nehir kenarlarını hemen boşaltarak yüksek yerler gibi daha güvenli bölgelere gidin."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Sakin olun ve yakınlarda sığınabileceğiniz bir yer bulun."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Acil durum mesajları testi"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Yanıtla"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM\'e izin verilmiyor"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM için temel hazırlık yapılmadı"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 7767202..298f0f4 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -133,10 +133,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Пошук служби"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Дзвінок через Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спочатку попросіть свого оператора налаштувати цю послугу. Після цього ввімкніть дзвінки через Wi-Fi у налаштуваннях."</item>
+    <item msgid="3910386316304772394">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спершу попросіть свого оператора налаштувати цю послугу. Після цього знову ввімкніть дзвінки через Wi-Fi у налаштуваннях. (Код помилки: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Зареєструйтеся в оператора"</item>
+    <item msgid="7472393097168811593">"Зареєструйтеся в оператора (код помилки: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -252,8 +252,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Голос. підказки"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Блокувати зараз"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Вміст сховано"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Вміст сховано згідно з правилом"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Нове сповіщення"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Віртуальна клавіатура"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Фізична клавіатура"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Безпека"</string>
@@ -269,9 +268,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Сповіщення"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Демо-режим для роздрібної торгівлі"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"З’єднання USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Додатки, які працюють у фоновому режимі"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> працює у фоновому режимі"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Додатки, які працюють у фоновому режимі: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Додатки, що використовують заряд акумулятора"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> використовує заряд акумулятора"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Додатків, що використовують заряд акумулятора: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Торкніться, щоб перевірити використання акумулятора й трафік"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Безп. режим"</string>
@@ -1150,6 +1149,13 @@
       <item quantity="many">Відкриті мережі Wi-Fi доступні</item>
       <item quantity="other">Відкриті мережі Wi-Fi доступні</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Під’єднайтеся до відкритої мережі Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Під’єднання до відкритої мережі Wi-Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Під’єднано до мережі Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не вдалося під’єднатися до мережі Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Торкніться, щоб побачити всі мережі"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Під’єднатися"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Усі мережі"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Вхід у мережу Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Вхід у мережу"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1229,6 +1235,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB для режиму MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Під’єднано до аксесуара USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Торкніться, щоб переглянути більше опцій."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Виявлено аналоговий аксесуар для аудіо"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Під’єднаний пристрій несумісний із цим телефоном. Торкніться, щоб дізнатися більше."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Налагодження USB завершено"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Торкніться, щоб вимкнути налагодження USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Виберіть, щоб вимкнути налагодження за USB"</string>
@@ -1334,9 +1342,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Під’єднано до <xliff:g id="SESSION">%s</xliff:g>. Торкніться, щоб керувати мережею."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Під’єднання до постійної мережі VPN…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Під’єднано до постійної мережі VPN"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Постійну мережу VPN від’єднано"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Від’єднано від постійної мережі VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Помилка постійної мережі VPN"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Торкніться, щоб налаштувати"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Змінити налаштування мережі або VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Виберіть файл"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Не вибрано файл"</string>
     <string name="reset" msgid="2448168080964209908">"Скинути"</string>
@@ -1345,8 +1353,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Торкніться, щоб вийти з режиму автомобіля."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Прив\'язка чи точка дост. активна"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Торкніться, щоб налаштувати."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Використання телефона в режимі модема вимкнено"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Щоб дізнатися більше, зв’яжіться з адміністратором"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Далі"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Пропустити"</string>
@@ -1789,14 +1795,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Відкріпити"</string>
     <string name="app_info" msgid="6856026610594615344">"Про додаток"</string>
     <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Скинути налаштування пристрою?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Торкніться, щоб скинути налаштування пристрою"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Запуск демонстрації…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Скидання налаштувань пристрою…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Скинути налаштування пристрою?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Ви втратите всі зміни, а демонстрація знову почнеться через <xliff:g id="TIMEOUT">%1$s</xliff:g> с…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Скасувати"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Скинути"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> вимкнено"</string>
     <string name="conference_call" msgid="3751093130790472426">"Конференц-виклик"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Спливаюча підказка"</string>
@@ -1842,6 +1842,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Негайно евакуюйтеся з прибережних районів і територій поблизу річок у безпечніше місце, як-от на територію на підвищенні."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Не хвилюйтеся та знайдіть прихисток поблизу."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Перевірка екстрених повідомлень"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Відповісти"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-карта заборонена"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-карту не затверджено"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 0342b8a..416ec79 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"سروس کی تلاش کر رہا ہے"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"‏Wi-Fi کالنگ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"‏Wi-Fi سے کالز کرنے اور پیغامات بھیجنے کیلئے، پہلے اپنے کیریئر سے اس سروس کو ترتیب دینے کیلئے کہیں۔ پھر ترتیبات سے دوبارہ Wi-Fi کالنگ آن کریں۔"</item>
+    <item msgid="3910386316304772394">"‏Wi-Fi سے کالز کرنے اور پیغامات بھیجنے کے لیے، پہلے اپنے کیریئر سے اس سروس کو سیٹ اپ کرنے کے لیے کہیں۔ پھر ترتیبات سے دوبارہ Wi-Fi کالنگ آن کریں۔ (خراب کوڈ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"اپنے کیریئر کے ساتھ رجسٹر کریں"</item>
+    <item msgid="7472393097168811593">"اپنے کیریئر (خرابی کا کوڈ: <xliff:g id="CODE">%1$s</xliff:g>) کے ساتھ رجسٹر کریں"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"‎%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ابھی مقفل کریں"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"‎999+‎"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"مواد مخفی ہیں"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"مواد پالیسی کے تحت مخفی ہے"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"نئی اطلاع"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ورچوئل کی بورڈ"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"فزیکل کی بورڈ"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"سیکیورٹی"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"الرٹس"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"ریٹیل ڈیمو"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"‏USB کنکشن"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ایپس پس منظر میں چل رہی ہیں"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> پس منظر میں چل رہی ہے"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ایپس پس منظر میں چل رہی ہیں"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ایپس بیٹری خرچ کر رہی ہیں"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> بیٹری کا استعمال کر رہی ہے"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ایپس بیٹری کا استعمال کر رہی ہیں"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"بیٹری اور ڈیٹا استعمال کے بارے میں تفصیلات کے لیے تھپتھپائیں"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>، <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"حفاظتی وضع"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">‏عوامی Wi-Fi نیٹ ورکس دستیاب ہیں</item>
       <item quantity="one">‏عوامی Wi-Fi نیٹ ورک دستیاب ہے</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"‏عوامی Wi‑Fi نیٹ ورک سے منسلک ہوں"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"‏عوامی Wi‑Fi نیٹ ورک سے منسلک ہو رہا ہے"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"‏عوامی Wi‑Fi نیٹ ورک سے منسلک ہو گيا"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"‏Wi‑Fi نیٹ ورک سے منسلک نہیں ہو سکا"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"تمام نیٹ ورکس دیکھنے کیلئے تھپتھپائيں"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"منسلک کریں"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"تمام نیٹ ورکس"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"‏Wi-Fi نیٹ ورک میں سائن ان کریں"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"نیٹ ورک میں سائن ان کریں"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"‏MIDI کیلئے USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"‏ایک USB لوازم سے مربوط ہے"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"مزید اختیارات کیلئے تھپتھپائیں۔"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"اینالاگ آڈیو کے لوازم کا پتہ چلا"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"منسلک آلہ اس فون کے موافق نہیں ہے۔ مزید جاننے کے لیے تھپتھپائیں۔"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏USB ڈیبگ کرنا مربوط ہو گیا"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"‏USB ڈیبگنگ کو غیر فعال کرنے کیلئے تھپتھپائیں۔"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‏USB ڈیبگ کرنے کو غیر فعال کرنے کیلئے منتخب کریں۔"</string>
@@ -1290,19 +1298,17 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> سے منسلک ہے۔ نیٹ ورک کا نظم کرنے کیلئے تھپتھپائیں۔"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"‏ہمیشہ آن VPN مربوط ہو رہا ہے…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"‏ہمیشہ آن VPN مربوط ہوگیا"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"‏ہمیشہ آن VPN غیر منسلک ہو گیا"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"‏ہمیشہ آن VPN سے غیر منسلک ہو گيا"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"‏ہمیشہ آن VPN کی خرابی"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"سیٹ اپ کرنے کیلئے تھپتھپائیں"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"‏نیٹ ورک یا VPN کی ترتیبات تبدیل کریں"</string>
     <string name="upload_file" msgid="2897957172366730416">"فائل منتخب کریں"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"کوئی فائل منتخب نہیں کی گئی"</string>
     <string name="reset" msgid="2448168080964209908">"دوبارہ ترتیب دیں"</string>
     <string name="submit" msgid="1602335572089911941">"جمع کرائیں"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"کار وضع فعال ہے"</string>
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"کار موڈ سے خارج ہونے کیلئے تھپتھپائیں۔"</string>
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ٹیتھرنگ یا ہاٹ اسپاٹ فعال"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"ٹیدرنگ یا ہاٹ اسپاٹ فعال"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"سیٹ اپ کرنے کیلئے تھپتھپائیں۔"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ربط بنانا غیر فعال ہے"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"تفصیلات کے لئے اپنے منتظم سے رابطہ کریں"</string>
     <string name="back_button_label" msgid="2300470004503343439">"واپس جائیں"</string>
     <string name="next_button_label" msgid="1080555104677992408">"اگلا"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"نظر انداز کریں"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"پن ہٹائیں"</string>
     <string name="app_info" msgid="6856026610594615344">"ایپ کی معلومات"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"آلہ ری سیٹ کریں؟"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"آلہ ری سیٹ کرنے کیلئے تھپتھپائیں"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ڈیمو شروع ہو رہا ہے…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"آلہ ری سیٹ ہو رہا ہے…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"آلہ ری سیٹ کریں؟"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"آپ کی تمام تبدیلیاں ضائع ہو جائیں گی اور ڈیمو <xliff:g id="TIMEOUT">%1$s</xliff:g> سیکنڈز میں دوبارہ شروع ہوگا…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"منسوخ کریں"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"ابھی ری سیٹ کریں"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"غیر فعال کردہ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"کانفرنس کال"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"ٹول ٹپ"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ساحلی خطوں اور دریائی کناروں کے علاقوں کو فوری طور پر خالی کر کے اونچے ٹیلے جیسے کسی زیادہ محفوظ مقام پر چلے جائیں۔"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"پُرسکون رہیں اور قریبی پناہ حاصل کریں۔"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"ایمرجنسی پیغامات کی جانچ"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"جواب دیں"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"‏SIM کی اجازت نہیں ہے"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"‏SIM فراہم کردہ نہیں ہے"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 9724c6c..4961b1e 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Xizmatlar qidirilmoqda"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi qo‘ng‘iroq"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin."</item>
+    <item msgid="3910386316304772394">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin. (Xato kodi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Mobil operatoringiz yordamida ro‘yxatdan o‘ting"</item>
+    <item msgid="7472393097168811593">"Aloqa operatoringiz bilan ro‘yxatdan o‘ting (Xato kodi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ovozli yordam"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Qulflash"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Kontent yashirildi"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Qoidaga muvofiq kontent yashirilgan"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Yangi bildirishnoma"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtual klaviatura"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Tashqi klaviatura"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Xavfsizlik"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ogohlantirishlar"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo rejim"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB orqali ulanish"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Fonda ishlayotgan ilovalar"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> orqa fonda ishlayapti"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ta ilova fonda ishlamoqda"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Batareya quvvatini sarflayotgan ilovalar"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi batareya quvvatini sarflamoqda"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ta ilova batareya quvvatini sarflamoqda"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Batareya va trafik sarfi tafsilotlari uchun ustiga bosing"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Xavfsiz usul"</string>
@@ -1007,9 +1006,9 @@
     <string name="whichEditApplication" msgid="144727838241402655">"Tahrirlash…"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"“%1$s” yordamida tahrirlash"</string>
     <string name="whichEditApplicationLabel" msgid="7183524181625290300">"Tahrirlash"</string>
-    <string name="whichSendApplication" msgid="6902512414057341668">"Baham ko‘rish"</string>
+    <string name="whichSendApplication" msgid="6902512414057341668">"Ulashish"</string>
     <string name="whichSendApplicationNamed" msgid="2799370240005424391">"“%1$s” orqali ulashish"</string>
-    <string name="whichSendApplicationLabel" msgid="4579076294675975354">"Baham ko‘rish"</string>
+    <string name="whichSendApplicationLabel" msgid="4579076294675975354">"Ulashish"</string>
     <string name="whichSendToApplication" msgid="8272422260066642057">"Ilovani tanlang"</string>
     <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"%1$s orqali yuborish"</string>
     <string name="whichSendToApplicationLabel" msgid="8878962419005813500">"Yuborish"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Ochiq Wi-Fi tarmoqlari aniqlandi</item>
       <item quantity="one">Ochiq Wi-Fi tarmog‘i aniqlandi</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Ochiq Wi‑Fi tarmoqqa ulaning"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ochiq Wi‑Fi tarmoqqa ulanilmoqda"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi tarmoqqa ulanildi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi-Fi tarmoqqa ulanib bo‘lmadi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Barcha tarmoqlarni ko‘rish uchun bosing"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ulanish"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Barcha tarmoqlar"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi tarmoqqa kirish"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Tarmoqqa kirish"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB orqali MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB jihozga ulangan"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Boshqa parametrlarini ko‘rish uchun bosing."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analogli audio uskuna aniqlandi"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Biriktirilgan qurilma mazkur telefon bilan mos emas. Batafsil axborot olish uchun bu yerga bosing."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB orqali nosozliklarni tuzatish"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Faolsizlantirish uchun bu yerga bosing."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB orqali nosozliklarni tuzatishni o‘chirib qo‘yish uchun bosing."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> ulandi. Tarmoq sozlamalarini o‘zgartirish uchun bu yerni bosing."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Ulanmoqda…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Ulandi"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Doimiy VPN o‘chirildi"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Doimiy VPN tarmoqdan uzildi"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Xato"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Sozlash uchun bosing"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Tarmoq yoki VPN sozlamalarini o‘zgartiring"</string>
     <string name="upload_file" msgid="2897957172366730416">"Faylni tanlash"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Hech qanday fayl tanlanmadi"</string>
     <string name="reset" msgid="2448168080964209908">"Asliga qaytarish"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Avtomobil rejimidan chiqish uchun bosing."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Modem rejimi yoniq"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Sozlash uchun bosing."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Modem rejimi faolsizlantirildi"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Tafsilotlari uchun administratoringizga murojaat qiling"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Orqaga"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Keyingisi"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Tashlab o‘tish"</string>
@@ -1406,7 +1412,7 @@
     <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 barmoq izi:"</string>
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Barchasini ko‘rish"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Harakat turini tanlang"</string>
-    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Baham ko‘rish"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Ulashish"</string>
     <string name="sending" msgid="3245653681008218030">"Jo‘natilmoqda…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Brauzer ishga tushirilsinmi?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Qo‘ng‘iroqni qabul qilasizmi?"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Olib tashlash"</string>
     <string name="app_info" msgid="6856026610594615344">"Ilova haqida"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Qurilma asl holatga qaytarilsinmi?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Qurilmani asl holatga qaytarish uchun bosing"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Demo boshlanmoqda…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Qurilma asl holatga qaytarilmoqda…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Qurilma asl holatga qaytarilsinmi?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Har qanday o‘zgarishlar o‘chib ketadi va demo <xliff:g id="TIMEOUT">%1$s</xliff:g> soniyadan so‘ng yana qayta ishga tushadi…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Bekor qilish"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Asl holatga qaytarish"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> vidjeti o‘chirilgan"</string>
     <string name="conference_call" msgid="3751093130790472426">"Konferens-aloqa"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Maslahat oynasi"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Qirg‘oq va daryo bo‘ylaridan yuqori tepalik kabi xavfsiz joylarga darhol evakuatsiya qiling."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Tinchlaning va yaqin-atrofdan boshpana qidiring."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Favqulodda holatlar uchun sinov xabarlari"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Javob berish"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM karta ishlatish taqiqlangan"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM karta yo‘q"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 87db26f..c37458e 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -95,7 +95,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Không có dịch vụ thoại/khẩn cấp"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Tạm thời không được cung cấp bởi mạng di động tại vị trí của bạn"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Không thể kết nối mạng"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Để cải thiện khả năng thu tín hiệu, hãy thử thay đổi loại mạng được chọn trong Hệ thống &gt; Mạng và Internet &gt; Mạng di động &gt; Loại mạng ưa thích."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Để cải thiện khả năng thu tín hiệu, hãy thử thay đổi loại mạng được chọn trong Hệ thống &gt; Mạng và Internet &gt; Mạng di động &gt; Loại mạng ưu tiên."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Thông báo"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Chuyển tiếp cuộc gọi"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Chế độ gọi lại khẩn cấp"</string>
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Đang tìm kiếm Dịch vụ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Gọi qua Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt."</item>
+    <item msgid="3910386316304772394">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt. (Mã lỗi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Đăng ký với nhà cung cấp dịch vụ của bạn"</item>
+    <item msgid="7472393097168811593">"Đăng ký với nhà cung cấp dịch vụ của bạn (Mã lỗi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Trợ lý thoại"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Khóa ngay"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Nội dung bị ẩn"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Nội dung bị ẩn theo chính sách"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Thông báo mới"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Bàn phím ảo"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Bàn phím thực"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Bảo mật"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Cảnh báo"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Giới thiệu bán lẻ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Kết nối USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Ứng dụng đang chạy trong nền"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang chạy ẩn"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ứng dụng đang chạy trong nền"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Các ứng dụng tiêu thụ pin"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang sử dụng pin"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ứng dụng đang sử dụng pin"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Nhấn để biết chi tiết về mức sử dụng dữ liệu và pin"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Chế độ an toàn"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">Mở các mạng Wi-Fi khả dụng</item>
       <item quantity="one">Mở mạng Wi-Fi khả dụng</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Kết nối với mạng Wi-Fi đang mở"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Đang kết nối với mạng Wi‑Fi đang mở"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Đã kết nối với mạng Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Không thể kết nối với mạng Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Nhấn để xem tất cả các mạng"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kết nối"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tất cả các mạng"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Đăng nhập vào mạng Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Đăng nhập vào mạng"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB cho MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Đã kết nối với phụ kiện USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Nhấn để biết thêm tùy chọn."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Đã phát hiện phụ kiện âm thanh analog"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Thiết bị được kết nối không tương thích với điện thoại này. Nhấn để tìm hiểu thêm."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Đã kết nối gỡ lỗi USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Nhấn để vô hiệu hóa gỡ lỗi USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chọn để vô hiệu hóa gỡ lỗi USB."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Đã kết nối với <xliff:g id="SESSION">%s</xliff:g>. Chạm để quản lý mạng."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Đang kết nối VPN luôn bật…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Đã kết nối VPN luôn bật"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Đã ngắt kết nối VPN luôn bật"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Đã ngắt kết nối khỏi VPN luôn bật"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Lỗi VPN luôn bật"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Nhấn để thiết lập"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Thay đổi cài đặt mạng hoặc VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Chọn tệp"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Không có tệp nào được chọn"</string>
     <string name="reset" msgid="2448168080964209908">"Đặt lại"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Nhấn để thoát khỏi chế độ trên ô tô."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Chức năng điểm truy cập Internet hoặc điểm phát sóng đang hoạt động"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Nhấn để thiết lập."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Đã tắt tính năng chia sẻ kết nối"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hãy liên hệ với quản trị viên của bạn để biết chi tiết"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Quay lại"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Tiếp theo"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Bỏ qua"</string>
@@ -1623,8 +1629,8 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Do quản trị viên của bạn cài đặt"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Do quản trị viên của bạn cập nhật"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Do quản trị viên của bạn xóa"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"Để giúp tăng tuổi thọ pin, trình tiết kiệm pin sẽ giảm hiệu suất thiết bị của bạn và hạn chế rung, dịch vụ vị trí và hầu hết dữ liệu nền. Email, nhắn tin và các ứng dụng khác dựa trên đồng bộ hóa có thể không cập nhật nếu bạn không mở chúng.\n\nTrình tiết kiệm pin tự động tắt khi thiết bị của bạn đang sạc."</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"Để giúp giảm mức sử dụng dữ liệu. Trình tiết kiệm dữ liệu chặn một số ứng dụng gửi hoặc nhận dữ liệu trong nền. Ứng dụng mà bạn hiện sử dụng có thể truy cập dữ liệu nhưng có thể thực hiện việc đó ít thường xuyên hơn. Ví như, hình ảnh sẽ không hiển thị cho đến khi bạn nhấn vào hình ảnh đó."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"Để giúp tăng thời lượng pin, trình tiết kiệm pin sẽ giảm hiệu suất thiết bị và hạn chế rung, dịch vụ vị trí và hầu hết dữ liệu nền. Ứng dụng email, nhắn tin và các ứng dụng khác dựa trên đồng bộ hóa có thể không cập nhật nếu bạn không mở.\n\nTrình tiết kiệm pin tự động tắt khi thiết bị của bạn đang sạc."</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"Để giúp giảm mức sử dụng dữ liệu, Trình tiết kiệm dữ liệu chặn một số ứng dụng gửi hoặc nhận dữ liệu trong nền. Ứng dụng mà bạn hiện sử dụng có thể truy cập dữ liệu nhưng có thể thực hiện việc đó ít thường xuyên hơn. Ví dụ: hình ảnh sẽ không hiển thị cho đến khi bạn nhấn vào hình ảnh đó."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Bật Trình tiết kiệm dữ liệu?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Bật"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Bỏ ghim"</string>
     <string name="app_info" msgid="6856026610594615344">"Thông tin ứng dụng"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Đặt lại thiết bị?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Nhấn để đặt lại thiết bị"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Đang bắt đầu bản trình diễn..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Đang đặt lại thiết bị..."</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Đặt lại thiết bị?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Bạn sẽ bị mất mọi thay đổi và bản trình diễn sẽ bắt đầu lại sau <xliff:g id="TIMEOUT">%1$s</xliff:g> giây…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Hủy"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Đặt lại ngay bây giờ"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Đã tắt <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"Cuộc gọi nhiều bên"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Chú giải công cụ"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Ngay lập tức sơ tán khỏi các vùng ven biển và khu vực ven sông để tới một nơi an toàn hơn như vùng đất cao."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Hãy bình tĩnh và tìm kiếm nơi trú ẩn gần đó."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Kiểm tra thông báo khẩn cấp"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Trả lời"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM không được cho phép"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM không được cấp phép"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index f3a5738..cc8a065 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜索服务"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"WLAN 通话"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能。"</item>
+    <item msgid="3910386316304772394">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能(错误代码:<xliff:g id="CODE">%1$s</xliff:g>)。"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"向您的运营商注册"</item>
+    <item msgid="7472393097168811593">"向您的运营商注册(错误代码:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"语音助理"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"立即锁定"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"内容已隐藏"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"内容已隐藏(根据政策规定)"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"新通知"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"虚拟键盘"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"实体键盘"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"安全性"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"提醒"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"零售演示模式"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB 连接"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"在后台运行的应用"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g>正在后台运行"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> 个应用正在后台运行"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"消耗电量的应用"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g>正在消耗电量"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> 个应用正在消耗电量"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"点按即可详细了解电量和流量消耗情况"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>、<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
@@ -873,7 +872,7 @@
     </plurals>
     <string name="last_month" msgid="3959346739979055432">"上个月"</string>
     <string name="older" msgid="5211975022815554840">"往前"</string>
-    <string name="preposition_for_date" msgid="9093949757757445117">"日期:<xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_date" msgid="9093949757757445117">"<xliff:g id="DATE">%s</xliff:g>"</string>
     <string name="preposition_for_time" msgid="5506831244263083793">"<xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="preposition_for_year" msgid="5040395640711867177">"年份:<xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"天"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">有可用的开放 WLAN 网络</item>
       <item quantity="one">有可用的开放 WLAN 网络</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"连接到开放的 WLAN 网络"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"正在连接到开放的 WLAN 网络"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"已连接到 WLAN 网络"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"无法连接到 WLAN 网络"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"点按即可查看所有网络"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"连接"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"所有网络"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"登录到WLAN网络"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"登录到网络"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1128,14 +1134,14 @@
     <string name="wifi_connect_alert_title" msgid="8455846016001810172">"要允许连接吗?"</string>
     <string name="wifi_connect_alert_message" msgid="6451273376815958922">"“%1$s”应用想要连接到 WLAN 网络“%2$s”"</string>
     <string name="wifi_connect_default_application" msgid="7143109390475484319">"一款应用"</string>
-    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"WLAN直连"</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"WLAN 直连"</string>
     <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"启动WLAN直连。此操作将会关闭WLAN客户端/热点。"</string>
     <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"无法启动WLAN直连。"</string>
     <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"已启用WLAN直连"</string>
     <string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"点按即可查看相关设置"</string>
     <string name="accept" msgid="1645267259272829559">"接受"</string>
     <string name="decline" msgid="2112225451706137894">"拒绝"</string>
-    <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"邀请已发送"</string>
+    <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"已发出邀请"</string>
     <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"连接邀请"</string>
     <string name="wifi_p2p_from_message" msgid="570389174731951769">"发件人:"</string>
     <string name="wifi_p2p_to_message" msgid="248968974522044099">"收件人:"</string>
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"正在通过 USB 连接到 MIDI 接口"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"已连接到USB配件"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"点按即可查看更多选项。"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"检测到模拟音频配件"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"连接的设备与此手机不兼容。点按即可了解详情。"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已连接到 USB 调试"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"点按即可停用 USB 调试功能。"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"选择即可停用 USB 调试功能。"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"已连接到<xliff:g id="SESSION">%s</xliff:g>。点按即可管理网络。"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"正在连接到始终开启的 VPN…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"已连接到始终开启的 VPN"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"始终开启的 VPN 已断开连接"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"始终开启的 VPN 已断开连接"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"始终开启的 VPN 出现错误"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"点按即可进行设置"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"更改网络或 VPN 设置"</string>
     <string name="upload_file" msgid="2897957172366730416">"选择文件"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"未选定任何文件"</string>
     <string name="reset" msgid="2448168080964209908">"重置"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"点按即可退出车载模式。"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"网络共享或热点已启用"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"点按即可进行设置。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"网络共享已停用"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"请与您的管理员联系以了解详情"</string>
     <string name="back_button_label" msgid="2300470004503343439">"上一步"</string>
     <string name="next_button_label" msgid="1080555104677992408">"下一步"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"跳过"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"取消固定"</string>
     <string name="app_info" msgid="6856026610594615344">"应用信息"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"要重置设备吗?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"点按即可重置设备"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"正在启动演示模式…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"正在重置设备…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"要重置设备吗?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"您将丢失所有更改,而且演示模式将在 <xliff:g id="TIMEOUT">%1$s</xliff:g> 秒后重新启动…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"取消"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"立即重置"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"已停用的<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"电话会议"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"提示"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"请立即从沿海和河滨区域撤离到高地等较安全的地方。"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"请保持冷静,并寻找附近的避难地点。"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"紧急消息测试"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"回复"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"不受允许的 SIM 卡"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"未配置的 SIM 卡"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 8ea8ee3..c592b65 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜尋服務"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 通話"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"如要透過 Wi-Fi 撥打電話及傳送訊息,請先向您的流動網絡供應商要求設定此服務。然後再次在「設定」中開啟 Wi-Fi 通話。"</item>
+    <item msgid="3910386316304772394">"如要透過 Wi-Fi 撥打電話和傳送訊息,請先向流動網絡供應商要求設定此服務,然後再次在「設定」中開啟「Wi-Fi 通話」。(錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"向您的流動網絡供應商註冊"</item>
+    <item msgid="7472393097168811593">"向您的流動網絡供應商註冊 (錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"語音助手"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"立即鎖定"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"內容已隱藏"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"已根據政策隱藏內容"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"新通知"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"虛擬鍵盤"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"實體鍵盤"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"安全性"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"通知"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"零售示範"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB 連線"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"正在背景中執行的應用程式"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在背景執行"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> 個應用程式正在背景中執行"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"耗用電量的應用程式"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在使用電量"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> 個應用程式正在使用電量"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"輕按即可查看電池和數據用量詳情"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>、<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">有可用的公開 Wi-Fi 網絡</item>
       <item quantity="one">有可用的公開 Wi-Fi 網絡</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"連線至開放的 Wi-Fi 網絡"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"正在連線至開放的 Wi-Fi 網絡"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"已連線至 Wi-Fi 網絡"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"無法連線至 Wi-Fi 網絡"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"輕按即可查看所有網絡"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"連線"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"所有網絡"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"登入 Wi-Fi 網絡"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"登入網絡"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"已連接到一個 USB 配件"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"輕按即可查看更多選項。"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"偵測到模擬音頻配件"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"連接的裝置與這部手機不兼容。輕按即可瞭解詳情。"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"輕按即可停用 USB 偵錯功能。"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取即可停用 USB 偵錯。"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"已連線至 <xliff:g id="SESSION">%s</xliff:g>,輕按一下即可管理網絡。"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"正在連線至永久連線的 VPN…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"已連線至永久連線的 VPN"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"永久連線的 VPN 已中斷"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"永遠開啟的 VPN 已中斷連線"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"永久連線的 VPN 發生錯誤"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"輕按即可設定"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"變更網絡或 VPN 設定"</string>
     <string name="upload_file" msgid="2897957172366730416">"選擇檔案"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"未選擇檔案"</string>
     <string name="reset" msgid="2448168080964209908">"重設"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"輕按即可結束車用模式。"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"已啟用網絡共享或熱點"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"輕按即可設定。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"網絡共享已停用"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"請聯絡您的管理員以瞭解詳情"</string>
     <string name="back_button_label" msgid="2300470004503343439">"返回"</string>
     <string name="next_button_label" msgid="1080555104677992408">"繼續"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"略過"</string>
@@ -1428,7 +1434,7 @@
     <string name="media_route_chooser_searching" msgid="4776236202610828706">"正在搜尋裝置…"</string>
     <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"設定"</string>
     <string name="media_route_controller_disconnect" msgid="8966120286374158649">"停止連接"</string>
-    <string name="media_route_status_scanning" msgid="7279908761758293783">"正在掃瞄…"</string>
+    <string name="media_route_status_scanning" msgid="7279908761758293783">"正在掃描…"</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"正在連線..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"可用"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"無法使用"</string>
@@ -1600,7 +1606,7 @@
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"稍後再試"</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"開啟全螢幕"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"由上往下刷退出。"</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"由頂部向下快速滑動即可退出。"</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"知道了"</string>
     <string name="done_label" msgid="2093726099505892398">"完成"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"小時環形滑桿"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"取消固定"</string>
     <string name="app_info" msgid="6856026610594615344">"應用程式資料"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"要重設裝置嗎?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"輕按即可重設裝置"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"正在開始示範…"</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"正在重設裝置…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"要重設裝置嗎?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"系統將不會儲存變更,示範將於 <xliff:g id="TIMEOUT">%1$s</xliff:g> 秒後重新開始…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"取消"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"立即重設"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"「<xliff:g id="LABEL">%1$s</xliff:g>」已停用"</string>
     <string name="conference_call" msgid="3751093130790472426">"會議通話"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"提示"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"請立即從沿海和河岸地區撤離,前往高地等較安全的地點。"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"請保持冷靜,並尋找附近的避難所。"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"緊急訊息測試"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"回覆"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"不允許使用 SIM 卡"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"無法識別 SIM 卡"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 43599e9..0eb3179 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜尋服務"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 通話"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"如要透過 Wi-FI 撥打電話及傳送訊息,請先要求你的電信業者開通這項服務,然後再到「設定」啟用 Wi-Fi 通話功能。"</item>
+    <item msgid="3910386316304772394">"如要透過 Wi-Fi 網路撥打電話及傳送訊息,請先要求電信業者為你設定這項服務,然後再次前往「設定」頁面啟用 Wi-Fi 通話功能。(錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"向你的電信業者註冊"</item>
+    <item msgid="7472393097168811593">"向你的電信業者註冊 (錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"語音小幫手"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"立即鎖定"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"超過 999"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"內容已隱藏"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"內容已依據政策隱藏"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"新通知"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"虛擬鍵盤"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"實體鍵盤"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"安全性"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"快訊"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"零售商示範模式"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB 連線"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"在背景執行的應用程式"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在背景執行"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> 個應用程式正在背景執行"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"正在耗用電量的應用程式"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在耗用電量"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> 個應用程式正在耗用電量"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"輕觸即可查看電池和數據用量詳情"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>、<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="other">有多個可用的開放 Wi-Fi 網路</item>
       <item quantity="one">有多個可用的開放 Wi-Fi 網路</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"連線至開放的 Wi‑Fi 網路"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"正在連線至開放的 Wi‑Fi 網路"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"已連線至 Wi-Fi 網路"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"無法連線至 Wi‑Fi 網路"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"輕觸即可查看所有網路"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"連線"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"所有網路"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"登入 Wi-Fi 網路"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"登入網路"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"已連接 USB 配件"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"輕觸即可查看更多選項。"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"偵測到類比音訊配件"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"此外接裝置與這支手機不相容。輕觸即可瞭解詳情。"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"輕觸即可停用 USB 偵錯功能。"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取這個選項以停用 USB 偵錯功能。"</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"已連線至 <xliff:g id="SESSION">%s</xliff:g>,輕觸一下即可管理網路。"</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"正在連線至永久連線的 VPN…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"已連線至永久連線的 VPN"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"永久連線的 VPN 已中斷連線"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"已中斷連線至永久連線的 VPN"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"永久連線的 VPN 發生錯誤"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"輕觸即可進行設定"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"變更網路或 VPN 設定"</string>
     <string name="upload_file" msgid="2897957172366730416">"選擇檔案"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"未選擇任何檔案"</string>
     <string name="reset" msgid="2448168080964209908">"重設"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"輕觸即可結束車用模式。"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"網路共用或無線基地台已啟用"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"輕觸即可進行設定。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"數據連線已停用"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"詳情請洽你的管理員"</string>
     <string name="back_button_label" msgid="2300470004503343439">"返回"</string>
     <string name="next_button_label" msgid="1080555104677992408">"繼續"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"略過"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"取消固定"</string>
     <string name="app_info" msgid="6856026610594615344">"應用程式資訊"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"要重設裝置嗎?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"輕觸即可重設裝置"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"正在啟動示範模式..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"正在重設裝置..."</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"要重設裝置嗎?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"系統不會儲存你所做的變更,示範模式將於 <xliff:g id="TIMEOUT">%1$s</xliff:g> 秒後重新開始…"</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"取消"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"立即重設"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"已停用的<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="conference_call" msgid="3751093130790472426">"電話會議"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"工具提示"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"請立即從沿海與河岸地區撤離,前往高地這類較安全的地點。"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"請保持冷靜並尋找附近的避難地點。"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"緊急訊息測試"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"回覆"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"不受允許的 SIM 卡"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"未佈建的 SIM 卡"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 961f1fa..22040d7 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -131,10 +131,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Iseshela Isevisi"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Ukushaya kwe-Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-FI, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le divayisi. Bese uvula ukushaya kwe-Wi-FI futhi kusukela kuzilungiselelo."</item>
+    <item msgid="3910386316304772394">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-Fi, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le sevisi. Bese uvula ukushaya kwe-Wi-Fi futhi kusukela kuzilungiselelo (Ikhodi yephutha: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"Bhalisa ngenkampani yakho yenethiwekhi"</item>
+    <item msgid="7472393097168811593">"Bhalisa ngenkampani yakho yenethiwekhi (Ikhodi yephutha: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -246,8 +246,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Isisekeli sezwi"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Khiya manje"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <string name="notification_hidden_text" msgid="1135169301897151909">"Okuqukethwe kufihliwe"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Okuqukethwe kufihlwe inqubomgomo"</string>
+    <string name="notification_hidden_text" msgid="6351207030447943784">"Isaziso esisha"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Ikhibhodi ebonakalayo"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Ikhibhodi ephathekayo"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Ukuphepha"</string>
@@ -263,9 +262,9 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Izexwayiso"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Idemo yokuthenga"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Ukuxhumeka kwe-USB"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Izinhlelo zokusebenza zisebenza ngasemuva"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> iyasebenza ngemuva"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> izinhlelo zokusebenza ziyasebenza ngemuva"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Izinhlelo zokusebenza ezidla ibhethri"</string>
+    <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> isebenzisa ibhethri"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> izinhlelo zokusebenza zisebenzisa ibhethri"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Thepha ngemininingwane ekusetshenzisweni kwebhethri nedatha"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Imodi ephephile"</string>
@@ -1106,6 +1105,13 @@
       <item quantity="one">Vula amanethiwekhi we-Wi-Fi atholakalayo</item>
       <item quantity="other">Vula amanethiwekhi we-Wi-Fi atholakalayo</item>
     </plurals>
+    <string name="wifi_available_title" msgid="3817100557900599505">"Xhuma kunethiwekhi evulekile ye-Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ixhuma kunethiwekhi evulekile ye-Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Kuxhumeke kunethiwekhi ye-Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Ayikwazanga ukuxhumeka kunethiwekhi ye-Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Thepha ukuze ubone onke amanethiwekhi"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Xhuma"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Onke amanethiwekhi"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Ngena ngemvume kunethiwekhi ye-Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Ngena ngemvume kunethiwekhi"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1185,6 +1191,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"I-USB ye-MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ixhunywe ku-accessory ye-USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Thepha ngezinketho eziningi."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Kutholwe isisetshenziswa se-analog yomsindo"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Idivayisi enamathiselwe kwi-imeyili ayihambisani nale foni. Thepha ukuze ufunde kabanzi."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ukulungisa iphutha le-USB kuxhunyiwe"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Thepha ukuze ukhubaze ukususa isiphazamisi se-USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Khetha ukuvimbela ukulungisa iphutha le-USB."</string>
@@ -1290,9 +1298,9 @@
     <string name="vpn_text_long" msgid="4907843483284977618">"Ixhume ku-<xliff:g id="SESSION">%s</xliff:g>. Thepha ukuphatha inethiwekhi."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"I-VPN ehlala ikhanya iyaxhuma…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"I-VPN ehlala ikhanya ixhunyiwe"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Njalo kuvuliwe i-VPN kunqamukile"</string>
+    <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Inqamukile kusuka ku-VPN njalo"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Iphutha le-VPN ehlala ikhanya"</string>
-    <string name="vpn_lockdown_config" msgid="5099330695245008680">"Thepha ukuze usethe"</string>
+    <string name="vpn_lockdown_config" msgid="8151951501116759194">"Shintsha inethiwekhi noma izilungiselelo ze-VPN"</string>
     <string name="upload_file" msgid="2897957172366730416">"Khetha ifayela"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Ayikho ifayela ekhethiwe"</string>
     <string name="reset" msgid="2448168080964209908">"Setha kabusha"</string>
@@ -1301,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Thepha ukuze uphume kumodi yemoto."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Ukusebenzisa njengemodemu noma i-hotspot ephathekayo kuvuliwe"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Thepha ukuze usethe."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Ukusebenzisa ifoni njengemodemu kukhutshaziwe"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Xhumana nomphathi wakho ukuze uthole imininingwane"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Emuva"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Okulandelayo"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Yeqa"</string>
@@ -1723,14 +1729,8 @@
     <string name="unpin_target" msgid="3556545602439143442">"Susa ukuphina"</string>
     <string name="app_info" msgid="6856026610594615344">"Ulwazi lohlelo lokusebenza"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Setha kabusha idivayisi?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Thepha ukuze usethe kabusha idivayisi"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Iqalisa i-demo..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"Isetha kabusha idivayisi..."</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Setha kabusha idivayisi?"</string>
-    <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Uzolahlekelwa inoma iluphi ushintsho futhi idemo izoqala futhi kumasekhondi angu-<xliff:g id="TIMEOUT">%1$s</xliff:g>..."</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Khansela"</string>
-    <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Setha kabusha manje"</string>
     <string name="suspended_widget_accessibility" msgid="6712143096475264190">"I-<xliff:g id="LABEL">%1$s</xliff:g> ekhutshaziwe"</string>
     <string name="conference_call" msgid="3751093130790472426">"Ikholi yengqungquthela"</string>
     <string name="tooltip_popup_title" msgid="5253721848739260181">"Ithulithiphu"</string>
@@ -1774,6 +1774,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Phuma ngokushesha kusukela kuzifunda ezingasolwandle nasezindaweni zemifula uye endaweni ephephile efana nendawo ephakeme."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Hlala ubeke umoya phansi uphinde ufune ukukhuselwa eduze."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Ukuhlolwa kwemilayezo yesimo esiphuthumayo"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Phendula"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"I-SIM ayivunyelwe"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"I-SIM ayinikezelwe"</string>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index e190bd1..5baf985 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -66,8 +66,10 @@
         <item>@drawable/ic_find_previous_material</item>
         <item>@drawable/ic_go</item>
         <item>@drawable/ic_go_search_api_material</item>
-        <item>@drawable/ic_media_route_connecting_material</item>
-        <item>@drawable/ic_media_route_material</item>
+        <item>@drawable/ic_media_route_connecting_material_dark</item>
+        <item>@drawable/ic_media_route_connecting_material_light</item>
+        <item>@drawable/ic_media_route_material_dark</item>
+        <item>@drawable/ic_media_route_material_light</item>
         <item>@drawable/ic_menu_close_clear_cancel</item>
         <item>@drawable/ic_menu_copy_material</item>
         <item>@drawable/ic_menu_cut_material</item>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8995513..e291ea6 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -296,6 +296,17 @@
          less than 0x600 -->
     <bool translatable="false" name="config_apfDrop802_3Frames">true</bool>
 
+    <!-- An array of Black listed EtherType, packets with EtherTypes within this array
+         will be dropped
+         TODO: need to put proper values, these are for testing purposes only -->
+    <integer-array translatable="false" name="config_apfEthTypeBlackList">
+        <item>0x88A2</item>
+        <item>0x88A4</item>
+        <item>0x88B8</item>
+        <item>0x88CD</item>
+        <item>0x88E3</item>
+    </integer-array>
+
     <!-- Default value for ConnectivityManager.getMultipathPreference() on metered networks. Actual
          device behaviour is controlled by Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE.
          This is the default value of that setting. -->
@@ -452,9 +463,6 @@
     <!-- Boolean indicating whether the wifi chipset has dual frequency band support -->
     <bool translatable="false" name="config_wifi_dual_band_support">false</bool>
 
-    <!-- Boolean indicating whether Hotspot 2.0/Passpoint and ANQP queries is enabled -->
-    <bool translatable="false" name="config_wifi_hotspot2_enabled">false</bool>
-
     <!-- Boolean indicating whether 802.11r Fast BSS Transition is enabled on this platform -->
     <bool translatable="false" name="config_wifi_fast_bss_transition_enabled">false</bool>
 
@@ -499,6 +507,12 @@
     <integer translatable="false" name="config_wifi_framework_SECURITY_AWARD">80</integer>
     <!-- Integer specifying the base interval in seconds for the exponential backoff scan for autojoin -->
     <integer translatable="false" name="config_wifi_framework_exponential_backoff_scan_base_interval">20</integer>
+    <!-- Integers specifying the max packet Tx/Rx rates for full scan -->
+    <integer translatable="false" name="config_wifi_framework_max_tx_rate_for_full_scan">8</integer>
+    <integer translatable="false" name="config_wifi_framework_max_rx_rate_for_full_scan">16</integer>
+    <!-- Integers specifying the min packet Tx/Rx rates in packets per second for staying on the same network -->
+    <integer translatable="false" name="config_wifi_framework_min_tx_rate_for_staying_on_network">16</integer>
+    <integer translatable="false" name="config_wifi_framework_min_rx_rate_for_staying_on_network">16</integer>
     <!-- Integer parameters of the wifi to cellular handover feature
          wifi should not stick to bad networks -->
     <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz">-82</integer>
@@ -573,6 +587,10 @@
     <!-- Boolean indicating that wifi only link configuratios that have exact same credentials (i.e PSK) -->
     <bool translatable="false" name="config_wifi_only_link_same_credential_configurations">true</bool>
 
+    <!-- Boolean indicating whether framework needs to set the tx power limit for meeting SAR requirements
+         during voice calls -->
+    <bool translatable="false" name="config_wifi_framework_enable_voice_call_sar_tx_power_limit">false</bool>
+
     <!-- Wifi driver supports batched scan -->
     <bool translatable="false" name="config_wifi_batched_scan_supported">false</bool>
 
@@ -960,15 +978,7 @@
         <item>30</item>
     </integer-array>
 
-    <!-- Vibrator pattern for feedback about booting with safe mode disabled -->
-    <integer-array name="config_safeModeDisabledVibePattern">
-        <item>0</item>
-        <item>1</item>
-        <item>20</item>
-        <item>21</item>
-    </integer-array>
-
-    <!-- Vibrator pattern for feedback about booting with safe mode disabled -->
+    <!-- Vibrator pattern for feedback about booting with safe mode enabled -->
     <integer-array name="config_safeModeEnabledVibePattern">
         <item>0</item>
         <item>1</item>
@@ -986,14 +996,6 @@
         <item>10</item>
     </integer-array>
 
-    <!-- Vibrator pattern for feedback about a context click -->
-    <integer-array name="config_contextClickVibePattern">
-        <item>0</item>
-        <item>1</item>
-        <item>20</item>
-        <item>21</item>
-    </integer-array>
-
     <bool name="config_use_strict_phone_number_comparation">false</bool>
 
     <!-- Display low battery warning when battery level dips to this value.
@@ -1493,16 +1495,16 @@
     <integer translatable="false" name="config_bluetooth_max_advertisers">0</integer>
 
     <!-- Idle current for bluetooth controller. 0 by default-->
-    <integer translatable="false" name="config_bluetooth_idle_cur_ma">1</integer>
+    <integer translatable="false" name="config_bluetooth_idle_cur_ma">0</integer>
 
     <!-- Rx current for bluetooth controller. 0 by default-->
-    <integer translatable="false" name="config_bluetooth_rx_cur_ma">2</integer>
+    <integer translatable="false" name="config_bluetooth_rx_cur_ma">0</integer>
 
     <!-- Tx current for bluetooth controller. 0 by default-->
-    <integer translatable="false" name="config_bluetooth_tx_cur_ma">3</integer>
+    <integer translatable="false" name="config_bluetooth_tx_cur_ma">0</integer>
 
     <!-- Operating volatage for bluetooth controller. 0 by default-->
-    <integer translatable="false" name="config_bluetooth_operating_voltage_mv">4</integer>
+    <integer translatable="false" name="config_bluetooth_operating_voltage_mv">0</integer>
 
     <!-- Whether supported profiles should be reloaded upon enabling bluetooth -->
     <bool name="config_bluetooth_reload_supported_profiles_when_enabled">false</bool>
@@ -1863,6 +1865,21 @@
     <!-- Type of the double tap sensor. Empty if double tap is not supported. -->
     <string name="config_dozeDoubleTapSensorType" translatable="false"></string>
 
+    <!-- Type of the long press sensor. Empty if long press is not supported. -->
+    <string name="config_dozeLongPressSensorType" translatable="false"></string>
+
+    <!-- Control whether the always on display mode is available. This should only be enabled on
+         devices where the display has be tuned to be power efficient in DOZE and/or DOZE_SUSPEND
+         states. -->
+    <bool name="config_dozeAlwaysOnDisplayAvailable">false</bool>
+
+    <!-- Whether the display blanks itself when transitioning from a doze to a non-doze state -->
+    <bool name="config_displayBlanksAfterDoze">false</bool>
+
+    <!-- True if the display hardware only has brightness buckets rather than a full range of
+         backlight values -->
+    <bool name="config_displayBrightnessBucketsInDoze">false</bool>
+
     <!-- Power Management: Specifies whether to decouple the auto-suspend state of the
          device from the display on/off state.
 
@@ -2156,10 +2173,14 @@
     <string name="config_customAdbPublicKeyConfirmationSecondaryUserComponent"
             >com.android.systemui/com.android.systemui.usb.UsbDebuggingSecondaryUserActivity</string>
 
-    <!-- Name of the CustomDialog that is used for VPN -->
-    <string name="config_customVpnConfirmDialogComponent"
+    <!-- Name of the dialog that is used to request the user's consent to VPN connection -->
+    <string name="config_customVpnConfirmDialogComponent" translatable="false"
             >com.android.vpndialogs/com.android.vpndialogs.ConfirmDialog</string>
 
+    <!-- Name of the dialog that is used to inform the user that always-on VPN is disconnected -->
+    <string name="config_customVpnAlwaysOnDisconnectedDialogComponent" translatable="false"
+            >com.android.vpndialogs/com.android.vpndialogs.AlwaysOnDisconnectedDialog</string>
+
     <!-- Apps that are authorized to access shared accounts, overridden by product overlays -->
     <string name="config_appsAuthorizedForSharedAccounts" translatable="false">;com.android.settings;</string>
 
@@ -2381,7 +2402,13 @@
 
     <bool name="config_networkSamplingWakesDevice">true</bool>
 
-    <string-array translatable="false" name="config_cdma_home_system" />
+    <!-- Home (non-roaming) values for CDMA roaming indicator.
+         Carriers can override this table by resource overlay. If not,
+         the default values come from 3GPP2 C.R1001 table
+         8.1-1. Enhanced Roaming Indicator Number Assignments -->
+    <string-array translatable="false" name="config_cdma_home_system">
+        <item>1</item>
+    </string-array>
 
     <!--From SmsMessage-->
     <!--Support decoding the user data payload as pack GSM 8-bit (a GSM alphabet
@@ -2406,9 +2433,13 @@
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.google.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>NTP_SERVER=north-america.pool.ntp.org</item>
         <item>SUPL_VER=0x20000</item>
         <item>SUPL_MODE=1</item>
+        <item>SUPL_ES=0</item>
+        <item>LPP_PROFILE=0</item>
+        <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>GPS_LOCK=0</item>
     </string-array>
 
     <!-- Sprint need a 70 ms delay for 3way call -->
@@ -2757,18 +2788,6 @@
     <!-- True if camera app should be pinned via Pinner Service -->
     <bool name="config_pinnerCameraApp">false</bool>
 
-    <!-- Component that is the default launcher when demo mode is enabled. -->
-    <string name="config_demoModeLauncherComponent">com.android.retaildemo/.DemoPlayer</string>
-
-    <!-- Hashed password (SHA-256) used to restrict carrier demo mode operation. -->
-    <string name="config_carrierDemoModePassword" translatable="false"></string>
-
-    <!-- Secure setting used to activate carrier demo mode. -->
-    <string name="config_carrierDemoModeSetting" translatable="false"></string>
-
-    <!-- List of packages to enable in carrier demo mode (comma separated). -->
-    <string name="config_carrierDemoModePackages" translatable="false"></string>
-
     <!-- Number of days preloaded file cache should be preserved on a device before it can be
          deleted -->
     <integer name="config_keepPreloadsMinDays">7</integer>
@@ -2875,6 +2894,11 @@
     <!-- TODO(b/35230407) complete the link field -->
     <bool name="config_allowEscrowTokenForTrustAgent">false</bool>
 
+    <!-- A flattened ComponentName which corresponds to the only trust agent that should be enabled
+         by default. If the default value is used, or set to an empty string, the restriction will
+         not be applied. -->
+    <string name="config_defaultTrustAgent" translatable="false"></string>
+
     <!-- Colon separated list of package names that should be granted Notification Listener access -->
     <string name="config_defaultListenerAccessPackages" translatable="false"></string>
 
@@ -2896,6 +2920,11 @@
     <!-- Whether the device uses the default focus highlight when focus state isn't specified. -->
     <bool name="config_useDefaultFocusHighlight">true</bool>
 
+    <!-- Flag indicating that the entire notification header can be clicked to expand the
+         notification. If false, then the expand icon has to be clicked in order for the expand
+         to occur. The expand button will have increased touch boundaries to accomodate this. -->
+    <bool name="config_notificationHeaderClickableForExpand">false</bool>
+
     <!-- Configuration for automotive -->
     <bool name="enable_pbap_pce_profile">false</bool>
 
@@ -2947,6 +2976,22 @@
          relative to the overall voice call stream volume [0..100] -->
     <integer name="config_inCallNotificationVolumeRelative">67</integer>
 
+    <!-- The OEM specified sensor type for the lift trigger to launch the camera app. -->
+    <integer name="config_cameraLiftTriggerSensorType">-1</integer>
+    <!-- The OEM specified sensor string type for the gesture to launch camera app, this value
+        must match the value of config_cameraLiftTriggerSensorType in OEM's HAL -->
+    <string translatable="false" name="config_cameraLiftTriggerSensorStringType"></string>
+
+    <!-- Default number of days to retain for the automatic storage manager. -->
+    <integer translatable="false" name="config_storageManagerDaystoRetainDefault">90</integer>
+
+    <!-- Name of a font family to use for headlines. If empty, falls back to platform default -->
+    <string name="config_headlineFontFamily" translatable="false"></string>
+    <!-- Name of a font family to use for headlines. Defaults to sans-serif-light -->
+    <string name="config_headlineFontFamilyLight" translatable="false">sans-serif-light</string>
+    <!-- Allows setting custom fontFeatureSettings on specific text. -->
+    <string name="config_headlineFontFeatureSettings" translatable="false"></string>
+
     <!-- An array of packages that need to be treated as type system in battery settings -->
     <string-array translatable="false" name="config_batteryPackageTypeSystem">
         <item>com.android.providers.calendar</item>
@@ -2956,4 +3001,17 @@
 
     <!-- An array of packages that need to be treated as type service in battery settings -->
     <string-array translatable="false" name="config_batteryPackageTypeService"/>
+
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">false</bool>
+
+    <!-- Enable the RingtonePickerActivity in 'com.android.providers.media'. -->
+    <bool name="config_defaultRingtonePickerEnabled">true</bool>
+
+    <!-- Allow SystemUI to show the shutdown dialog -->
+    <bool name="config_showSysuiShutdown">true</bool>
+
+    <!-- Decide whether to display 'No service' on status bar instead of 'Emergency calls only'
+         when SIM is unready. -->
+    <bool name="config_display_no_service_when_sim_unready">false</bool>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index ece0e82..b4636a6 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -30,7 +30,7 @@
          will be displayed in the app launcher and elsewhere. -->
     <dimen name="app_icon_size">48dip</dimen>
 
-    <dimen name="toast_y_offset">64dip</dimen>
+    <dimen name="toast_y_offset">24dp</dimen>
     <!-- Height of the status bar -->
     <dimen name="status_bar_height">24dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
@@ -67,6 +67,9 @@
     <!-- The amount to leave on-screen when the PIP is minimized. -->
     <dimen name="pip_minimized_visible_size">48dp</dimen>
 
+    <!-- The the PIP decelerates at while moving from a fling. -->
+    <dimen name="pip_fling_deceleration">-3000dp</dimen>
+
     <!-- Min width for a tablet device -->
     <dimen name="min_xlarge_screen_width">800dp</dimen>
 
@@ -177,6 +180,12 @@
     <!-- height of the content margin on the bottom -->
     <dimen name="notification_content_margin_bottom">16dp</dimen>
 
+    <!-- The height of the progress bar. -->
+    <dimen name="notification_progress_bar_height">15dp</dimen>
+
+    <!-- The top margin before the notification progress bar. -->
+    <dimen name="notification_progress_margin_top">8dp</dimen>
+
     <!-- height of the notification header (for icon and package name) -->
     <dimen name="notification_header_height">48dp</dimen>
 
@@ -185,20 +194,40 @@
 
     <!-- The top padding for the notification header -->
     <dimen name="notification_header_padding_top">10dp</dimen>
+
     <!-- The bottom padding for the notification header -->
     <dimen name="notification_header_padding_bottom">11dp</dimen>
 
+    <!-- The margin at the bottom of the notification header. -->
+    <dimen name="notification_header_margin_bottom">5dp</dimen>
+
+    <!-- The end margin after the application icon in the notification header -->
+    <dimen name="notification_header_icon_margin_end">3dp</dimen>
+
     <!-- size (width and height) of the icon in the notification header -->
     <dimen name="notification_header_icon_size">18dp</dimen>
 
     <!-- size (width and height) of the icon in the notification header -->
     <dimen name="notification_header_icon_size_ambient">20dp</dimen>
 
+    <!-- The margin before the start of the app name in the header. -->
+    <dimen name="notification_header_app_name_margin_start">3dp</dimen>
+
+    <!-- The margin before and after each of the items in the notification header. -->
+    <dimen name="notification_header_separating_margin">2dp</dimen>
+
+    <!-- The absolute size of the notification expand icon. -2 for wrap_content. -->
+    <dimen name="notification_header_expand_icon_size">-2px</dimen>
+
+    <!-- The top padding for the notification expand button. -->
+    <dimen name="notification_expand_button_padding_top">1dp</dimen>
+
     <!-- Height of a small notification in the status bar -->
     <dimen name="notification_min_height">92dp</dimen>
 
     <!-- The width of the big icons in notifications. -->
     <dimen name="notification_large_icon_width">64dp</dimen>
+
     <!-- The width of the big icons in notifications. -->
     <dimen name="notification_large_icon_height">64dp</dimen>
 
@@ -208,12 +237,21 @@
     <!-- The minimum height of the content if there are at least two lines or a picture-->
     <dimen name="notification_min_content_height">41dp</dimen>
 
-    <!-- The small size of the image if the height drawing doesn't work anymore -->
-    <dimen name="media_notification_expanded_image_small_size">72dp</dimen>
+    <!-- The size of the media actions in the media notification. -->
+    <dimen name="media_notification_action_button_size">48dp</dimen>
+
+    <!-- The bottom padding for the media actions container. -->
+    <dimen name="media_notification_actions_padding_bottom">12dp</dimen>
+
+    <!-- The maximum size of the image in the expanded media notification -->
+    <dimen name="media_notification_expanded_image_max_size">94dp</dimen>
 
     <!-- The maximum size of the image in the expanded media notification -->
     <dimen name="media_notification_expanded_image_margin_bottom">20dp</dimen>
 
+    <!-- The absolute height for the header in a media notification. -->
+    <dimen name="media_notification_header_height">53dp</dimen>
+
     <!-- The margin of the content to an image-->
     <dimen name="notification_content_image_margin_end">8dp</dimen>
 
@@ -492,6 +530,8 @@
     <dimen name="content_rect_bottom_clip_allowance">20dp</dimen>
 
     <dimen name="chooser_grid_padding">0dp</dimen>
+    <!-- Spacing around the background change frome service to non-service -->
+    <dimen name="chooser_service_spacing">8dp</dimen>
 
     <item type="dimen" name="aerr_padding_list_top">15dp</item>
     <item type="dimen" name="aerr_padding_list_bottom">8dp</item>
@@ -537,6 +577,21 @@
     <dimen name="item_touch_helper_swipe_escape_velocity">120dp</dimen>
     <dimen name="item_touch_helper_swipe_escape_max_velocity">800dp</dimen>
 
+    <!-- The maximum height of any image in a remote view. This is applied to all images in custom remoteviews. This value is determined by the maximum notification height -->
+    <dimen name="notification_custom_view_max_image_height">284dp</dimen>
+    <!-- The maximum height of any image in a remote view. This is applied to all images in custom remoteviews. This value is determined a maximum notification width -->
+    <dimen name="notification_custom_view_max_image_width">450dp</dimen>
+    <!-- The maximum height of a big picture in a notification. The images will be reduced to that height in case they are bigger. This value is determined by the maximum notification height -->
+    <dimen name="notification_big_picture_max_height">284dp</dimen>
+    <!-- The maximum width of a big picture in a notification. The images will be reduced to that width in case they are bigger. This value is determined by the standard panel size -->
+    <dimen name="notification_big_picture_max_width">416dp</dimen>
+    <!-- The maximum height of a image in a media notification. The images will be reduced to that height in case they are bigger. This value is determined by the expanded media template-->
+    <dimen name="notification_media_image_max_height">140dp</dimen>
+    <!-- The maximum width of a image in a media notification. The images will be reduced to that width in case they are bigger.-->
+    <dimen name="notification_media_image_max_width">280dp</dimen>
+    <!-- The size of the right icon -->
+    <dimen name="notification_right_icon_size">40dp</dimen>
+
     <!-- Max width/height of the autofill data set picker as a fraction of the screen width/height -->
     <dimen name="autofill_dataset_picker_max_size">90%</dimen>
 
diff --git a/core/res/res/values/locale_config.xml b/core/res/res/values/locale_config.xml
index ba14843..04ea077 100644
--- a/core/res/res/values/locale_config.xml
+++ b/core/res/res/values/locale_config.xml
@@ -380,7 +380,6 @@
         <item>nl-NL</item> <!-- Dutch (Netherlands) -->
         <item>nl-SR</item> <!-- Dutch (Suriname) -->
         <item>nl-SX</item> <!-- Dutch (Sint Maarten) -->
-        <item>nmg-CM</item> <!-- Kwasio (Cameroon) -->
         <item>nn-NO</item> <!-- Norwegian Nynorsk (Norway) -->
         <item>nnh-CM</item> <!-- Ngiemboon (Cameroon) -->
         <item>nus-SS</item> <!-- Nuer (South Sudan) -->
@@ -463,8 +462,6 @@
         <item>teo-KE</item> <!-- Teso (Kenya) -->
         <item>teo-UG</item> <!-- Teso (Uganda) -->
         <item>th-TH</item> <!-- Thai (Thailand) -->
-        <item>ti-ER</item> <!-- Tigrinya (Eritrea) -->
-        <item>ti-ET</item> <!-- Tigrinya (Ethiopia) -->
         <item>to-TO</item> <!-- Tongan (Tonga) -->
         <item>tr-CY</item> <!-- Turkish (Cyprus) -->
         <item>tr-TR</item> <!-- Turkish (Turkey) -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4797dd9..2329056 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -266,11 +266,11 @@
     <string name="wfcRegErrorTitle">Wi-Fi Calling</string>
     <!-- WFC Operator Error Messages showed as alerts -->
     <string-array name="wfcOperatorErrorAlertMessages">
-        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="code" example="REG09 - No 911 Address">%1$s</xliff:g>)</item>
     </string-array>
     <!-- WFC Operator Error Messages showed as notifications -->
     <string-array name="wfcOperatorErrorNotificationMessages">
-        <item>Register with your carrier</item>
+        <item>Register with your carrier (Error code: <xliff:g id="code" example="REG09 - No 911 Address">%1$s</xliff:g>)</item>
     </string-array>
     <!-- Template for showing mobile network operator name while WFC is active -->
     <string-array name="wfcSpnFormats">
@@ -591,10 +591,7 @@
     <string name="notification_header_divider_symbol_with_spaces" translatable="false">" • "</string>
 
     <!-- Text shown in place of notification contents when the notification is hidden on a secure lockscreen -->
-    <string name="notification_hidden_text">Contents hidden</string>
-
-    <!-- Text shown in place of notification contents when the notification is hidden by policy on a secure lockscreen -->
-    <string name="notification_hidden_by_policy_text">Contents hidden by policy</string>
+    <string name="notification_hidden_text">New notification</string>
 
     <!-- Text shown when viewing channel settings for notifications related to the virtual keyboard -->
     <string name="notification_channel_virtual_keyboard">Virtual keyboard</string>
@@ -644,17 +641,18 @@
     <!-- This is the label for the notification channel settings that controls the behavior
         of the notification about applications that are running in the background (that is,
         perhaps confusingly, running foreground services but not the foreground UI on the screen).
-        [CHAR LIMIT=NONE] -->
-    <string name="notification_channel_foreground_service">Apps running in background</string>
+        [CHAR LIMIT=NONE BACKUP_MESSAGE_ID=6665375982962336520] -->
+    <string name="notification_channel_foreground_service">Apps consuming battery</string>
 
-    <!-- Label for foreground service notification when one app is running. [CHAR LIMIT=NONE] -->
+    <!-- Label for foreground service notification when one app is running.
+    [CHAR LIMIT=NONE BACKUP_MESSAGE_ID=6826789589341671842] -->
     <string name="foreground_service_app_in_background"><xliff:g id="app_name">%1$s</xliff:g> is
-        running in the background</string>
+        using battery</string>
 
     <!-- Label for foreground service notification when multiple apps are running.
-        [CHAR LIMIT=NONE] -->
+        [CHAR LIMIT=NONE BACKUP_MESSAGE_ID=7150914856893450380] -->
     <string name="foreground_service_apps_in_background"><xliff:g id="number">%1$d</xliff:g> apps
-        are running in the background</string>
+        are using battery</string>
 
     <!-- Content for foreground service notification when one app is running.
         [CHAR LIMIT=NONE] -->
@@ -3003,6 +3001,21 @@
         <item quantity="other">Open Wi-Fi networks available</item>
     </plurals>
 
+    <!-- Notification title for a nearby open wireless network.-->
+    <string name="wifi_available_title">Connect to open Wi\u2011Fi network</string>
+    <!-- Notification title when the system is connecting to the specified open network. The network name is specified in the notification content. -->
+    <string name="wifi_available_title_connecting">Connecting to open Wi\u2011Fi network</string>
+    <!-- Notification title when the system has connected to the open network. The network name is specified in the notification content. -->
+    <string name="wifi_available_title_connected">Connected to Wi\u2011Fi network</string>
+    <!-- Notification title when the system failed to connect to the specified open network. -->
+    <string name="wifi_available_title_failed_to_connect">Could not connect to Wi\u2011Fi network</string>
+    <!-- Notification content when the system failed to connect to the specified open network. This informs the user that tapping on this notification will open the wifi picker. -->
+    <string name="wifi_available_content_failed_to_connect">Tap to see all networks</string>
+    <!-- Notification action name for connecting to the network specified in the notification body. -->
+    <string name="wifi_available_action_connect">Connect</string>
+    <!-- Notification action name for opening the wifi picker, showing the user all the nearby networks. -->
+    <string name="wifi_available_action_all_networks">All Networks</string>
+
     <!-- A notification is shown when a wifi captive portal network is detected.  This is the notification's title. -->
     <string name="wifi_available_sign_in">Sign in to Wi-Fi network</string>
 
@@ -3170,6 +3183,11 @@
     <string name="usb_accessory_notification_title">Connected to a USB accessory</string>
     <!-- See USB_PREFERENCES. This is the message. -->
     <string name="usb_notification_message">Tap for more options.</string>
+    <!-- USB_PREFERENCES: Notification for when a type-c USB audio accessory is attached but not supported.  This is the title -->
+    <string name="usb_unsupported_audio_accessory_title">Analog audio accessory detected</string>
+    <!-- Message of notification shown when a type-c USB audio accessory is attached but not supported. -->
+    <string name="usb_unsupported_audio_accessory_message">The attached device is not compatible with this phone. Tap to learn more.</string>
+
 
     <!-- Title of notification shown when ADB is actively connected to the phone. -->
     <string name="adb_active_notification_title">USB debugging connected</string>
@@ -3445,16 +3463,21 @@
     <!-- The text of the notification when VPN is active with a session name. -->
     <string name="vpn_text_long">Connected to <xliff:g id="session" example="office">%s</xliff:g>. Tap to manage the network.</string>
 
-    <!-- Notification title when connecting to lockdown VPN. -->
+    <!-- Notification title when connecting to always-on VPN, a VPN that's set to always stay
+         connected. -->
     <string name="vpn_lockdown_connecting">Always-on VPN connecting\u2026</string>
-    <!-- Notification title when connected to lockdown VPN. -->
+    <!-- Notification title when connected to always-on VPN, a VPN that's set to always stay
+         connected. -->
     <string name="vpn_lockdown_connected">Always-on VPN connected</string>
-    <!-- Notification title when not connected to lockdown VPN. -->
-    <string name="vpn_lockdown_disconnected">Always-on VPN disconnected</string>
-    <!-- Notification title when error connecting to lockdown VPN. -->
+    <!-- Notification title when not connected to always-on VPN, a VPN that's set to always stay
+         connected. -->
+    <string name="vpn_lockdown_disconnected">Disconnected from always-on VPN</string>
+    <!-- Notification title when error connecting to always-on VPN, a VPN that's set to always stay
+         connected. -->
     <string name="vpn_lockdown_error">Always-on VPN error</string>
-    <!-- Notification body that indicates user can touch to configure lockdown VPN connection. -->
-    <string name="vpn_lockdown_config">Tap to set up</string>
+    <!-- Notification body that indicates user can touch to configure always-on VPN, a VPN that's
+         set to always stay connected. -->
+    <string name="vpn_lockdown_config">Change network or VPN settings</string>
 
     <!-- Localized strings for WebView -->
     <!-- Label for button in a WebView that will open a chooser to choose a file to upload -->
@@ -3476,13 +3499,6 @@
     <string name="tethered_notification_title">Tethering or hotspot active</string>
     <string name="tethered_notification_message">Tap to set up.</string>
 
-    <!-- Strings for tether disabling notification -->
-    <!-- This notification is shown when tethering has been disabled on a user's device.
-    The device is managed by the user's employer. Tethering can't be turned on unless the
-    IT administrator allows it. The noun "admin" is another reference for "IT administrator." -->
-    <string name="disable_tether_notification_title">Tethering is disabled</string>
-    <string name="disable_tether_notification_message">Contact your admin for details</string>
-
     <!--  Strings for possible PreferenceActivity Back/Next buttons -->
     <string name="back_button_label">Back</string>
     <string name="next_button_label">Next</string>
@@ -4577,22 +4593,10 @@
     <!-- The representation of a time duration when negative. An example is -1:14. This can be used with a countdown timer for example.-->
     <string name="negative_duration">\u2212<xliff:g id="time" example="1:14">%1$s</xliff:g></string>
 
-    <!-- Title of notification to start a new demo session when device is in retail mode [CHAR LIMIT=NONE] -->
-    <string name="reset_retail_demo_mode_title">Reset device?</string>
-    <!-- Text of notification to start a new demo session when device is in retail mode [CHAR LIMIT=NONE] -->
-    <string name="reset_retail_demo_mode_text">Tap to reset device</string>
     <!-- Text of dialog shown when starting a demo user for the first time [CHAR LIMIT=40] -->
     <string name="demo_starting_message">Starting demo\u2026</string>
     <!-- Text of dialog shown when starting a new demo user in retail demo mode [CHAR LIMIT=40] -->
     <string name="demo_restarting_message">Resetting device\u2026</string>
-    <!-- Title of the dialog shown when user inactivity times out in retail demo mode [CHAR LIMIT=40] -->
-    <string name="demo_user_inactivity_timeout_title">Reset device?</string>
-    <!-- Warning message shown when user inactivity times out in retail demo mode [CHAR LIMIT=none] -->
-    <string name="demo_user_inactivity_timeout_countdown">You\u2019ll lose any changes and the demo will start again in <xliff:g id="timeout" example="9">%1$s</xliff:g> seconds\u2026</string>
-    <!-- Text of button to allow user to abort countdown and continue current session in retail demo mode [CHAR LIMIT=40] -->
-    <string name="demo_user_inactivity_timeout_left_button">Cancel</string>
-    <!-- Text of button to allow user to abort countdown and immediately start another session in retail demo mode [CHAR LIMIT=40] -->
-    <string name="demo_user_inactivity_timeout_right_button">Reset now</string>
 
     <!-- Accessibilty string added to a widget that has been suspended [CHAR LIMIT=20] -->
     <string name="suspended_widget_accessibility">Disabled <xliff:g id="label" example="Calendar">%1$s</xliff:g></string>
@@ -4700,6 +4704,9 @@
     <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for test -->
     <string name="etws_primary_default_message_test">Emergency messages test</string>
 
+    <!-- Content description for the reply button in the notification area [CHAR LIMIT=NONE]-->
+    <string name="notification_reply_button_accessibility">Reply</string>
+
     <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for others -->
     <string name="etws_primary_default_message_others"></string>
 
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 690b051..4b0fe3f 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -931,7 +931,7 @@
          <item name="textStyle">normal</item>
          <item name="textColor">?textColorPrimaryInverse</item>
          <item name="textColorHint">?textColorHintInverse</item>
-     </style>	
+     </style>
 
      <!-- @hide -->
      <style name="TextAppearance.SearchResult.Title">
@@ -956,7 +956,8 @@
     </style>
 
     <style name="TextAppearance.Toast">
-        <item name="fontFamily">sans-serif-condensed</item>
+        <item name="fontFamily">sans-serif</item>
+        <item name="textSize">14sp</item>
     </style>
 
     <style name="TextAppearance.Tooltip">
@@ -1492,4 +1493,15 @@
         <item name="background">@drawable/autofill_dataset_picker_background</item>
     </style>
 
+    <!-- The style for the container of media actions in a notification. -->
+    <!-- @hide -->
+    <style name="NotificationMediaActionContainer">
+        <item name="layout_width">wrap_content</item>
+        <item name="layout_height">wrap_content</item>
+        <item name="layout_marginTop">-21dp</item>
+        <item name="paddingStart">8dp</item>
+        <item name="paddingBottom">@dimen/media_notification_actions_padding_bottom</item>
+        <item name="gravity">top</item>
+    </style>
+
 </resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index ec16611..f39904d 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -1054,7 +1054,7 @@
     </style>
 
     <style name="Widget.Material.MediaRouteButton" parent ="Widget.Material.ActionButton">
-        <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_material</item>
+        <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_material_dark</item>
         <item name="contentDescription">@string/media_route_button_content_description</item>
     </style>
 
@@ -1203,7 +1203,10 @@
     <style name="Widget.Material.Light.ActionBar" parent="Widget.Material.ActionBar" />
     <style name="Widget.Material.Light.ActionBar.Solid" parent="Widget.Material.ActionBar.Solid" />
     <style name="Widget.Material.Light.FastScroll" parent="Widget.Material.FastScroll"/>
-    <style name="Widget.Material.Light.MediaRouteButton" parent="Widget.Material.MediaRouteButton" />
+
+    <style name="Widget.Material.Light.MediaRouteButton" parent ="Widget.Material.MediaRouteButton">
+        <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_material_light</item>
+    </style>
 
     <!-- Animation Styles -->
 
@@ -1290,7 +1293,7 @@
     <style name="Notification.Header" parent="">
         <item name="paddingTop">@dimen/notification_header_padding_top</item>
         <item name="paddingBottom">@dimen/notification_header_padding_bottom</item>
-        <item name="layout_marginBottom">5dp</item>
+        <item name="layout_marginBottom">@dimen/notification_header_margin_bottom</item>
         <item name="paddingStart">@dimen/notification_content_margin_start</item>
         <item name="paddingEnd">16dp</item>
     </style>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c527501..d562498 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -312,6 +312,7 @@
   <java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" />
   <java-symbol type="bool" name="config_wifi_framework_enable_associated_network_selection" />
   <java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" />
+  <java-symbol type="bool" name="config_wifi_framework_enable_voice_call_sar_tx_power_limit" />
   <java-symbol type="bool" name="config_wifi_enable_disconnection_debounce" />
   <java-symbol type="bool" name="config_wifi_revert_country_code_on_cellular_loss" />
   <java-symbol type="bool" name="config_wifi_enable_wifi_firmware_debugging" />
@@ -372,6 +373,10 @@
   <java-symbol type="integer"  name="config_wifi_tx_cur_ma" />
   <java-symbol type="integer"  name="config_wifi_operating_voltage_mv" />
   <java-symbol type="string"  name="config_wifi_framework_sap_2G_channel_list" />
+  <java-symbol type="integer" name="config_wifi_framework_max_tx_rate_for_full_scan" />
+  <java-symbol type="integer" name="config_wifi_framework_max_rx_rate_for_full_scan" />
+  <java-symbol type="integer" name="config_wifi_framework_min_tx_rate_for_staying_on_network" />
+  <java-symbol type="integer" name="config_wifi_framework_min_rx_rate_for_staying_on_network" />
 
   <java-symbol type="bool" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment" />
   <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_tx_packet_threshold" />
@@ -1162,10 +1167,6 @@
   <java-symbol type="string" name="lockscreen_transport_pause_description" />
   <java-symbol type="string" name="config_ethernet_tcp_buffers" />
   <java-symbol type="string" name="config_wifi_tcp_buffers" />
-  <java-symbol type="string" name="config_demoModeLauncherComponent" />
-  <java-symbol type="string" name="config_carrierDemoModePassword" />
-  <java-symbol type="string" name="config_carrierDemoModeSetting" />
-  <java-symbol type="string" name="config_carrierDemoModePackages" />
   <java-symbol type="string" name="demo_starting_message" />
   <java-symbol type="string" name="demo_restarting_message" />
   <java-symbol type="string" name="conference_call" />
@@ -1314,10 +1315,8 @@
   <java-symbol type="drawable" name="unlock_wave" />
   <java-symbol type="drawable" name="notification_template_icon_bg" />
   <java-symbol type="drawable" name="notification_template_icon_low_bg" />
-  <java-symbol type="drawable" name="ic_media_route_on_holo_dark" />
   <java-symbol type="drawable" name="ic_media_route_off_holo_dark" />
-  <java-symbol type="drawable" name="ic_media_route_connecting_holo_dark" />
-  <java-symbol type="drawable" name="ic_media_route_disabled_holo_dark" />
+  <java-symbol type="drawable" name="ic_media_route_off_holo_light" />
   <java-symbol type="drawable" name="cling_button" />
   <java-symbol type="drawable" name="cling_arrow_up" />
   <java-symbol type="drawable" name="cling_bg" />
@@ -1479,6 +1478,7 @@
   <java-symbol type="xml" name="global_keys" />
   <java-symbol type="xml" name="default_zen_mode_config" />
   <java-symbol type="xml" name="sms_7bit_translation_table" />
+  <java-symbol type="xml" name="color_extraction" />
 
   <java-symbol type="raw" name="color_fade_vert" />
   <java-symbol type="raw" name="color_fade_frag" />
@@ -1549,9 +1549,7 @@
   <java-symbol type="array" name="config_autoRotationTiltTolerance" />
   <java-symbol type="array" name="config_keyboardTapVibePattern" />
   <java-symbol type="array" name="config_longPressVibePattern" />
-  <java-symbol type="array" name="config_safeModeDisabledVibePattern" />
   <java-symbol type="array" name="config_safeModeEnabledVibePattern" />
-  <java-symbol type="array" name="config_contextClickVibePattern" />
   <java-symbol type="array" name="config_virtualKeyVibePattern" />
   <java-symbol type="attr" name="actionModePopupWindowStyle" />
   <java-symbol type="attr" name="dialogCustomTitleDecorLayout" />
@@ -1580,6 +1578,7 @@
   <java-symbol type="dimen" name="docked_stack_divider_insets" />
   <java-symbol type="dimen" name="docked_stack_minimize_thickness" />
   <java-symbol type="dimen" name="pip_minimized_visible_size" />
+  <java-symbol type="dimen" name="pip_fling_deceleration" />
   <java-symbol type="integer" name="config_dockedStackDividerSnapMode" />
   <java-symbol type="integer" name="config_pictureInPictureSnapMode" />
   <java-symbol type="fraction" name="docked_stack_divider_fixed_ratio" />
@@ -1745,6 +1744,7 @@
   <java-symbol type="bool" name="config_animateScreenLights" />
   <java-symbol type="bool" name="config_automatic_brightness_available" />
   <java-symbol type="bool" name="config_autoBrightnessResetAmbientLuxAfterWarmUp" />
+  <java-symbol type="bool" name="config_notificationHeaderClickableForExpand" />
   <java-symbol type="bool" name="config_dozeAfterScreenOff" />
   <java-symbol type="bool" name="config_enableActivityRecognitionHardwareOverlay" />
   <java-symbol type="bool" name="config_enableFusedLocationOverlay" />
@@ -1771,7 +1771,6 @@
   <java-symbol type="bool" name="config_supportLongPressPowerWhenNonInteractive" />
   <java-symbol type="bool" name="config_wifi_background_scan_support" />
   <java-symbol type="bool" name="config_wifi_dual_band_support" />
-  <java-symbol type="bool" name="config_wifi_hotspot2_enabled" />
   <java-symbol type="bool" name="config_wifi_fast_bss_transition_enabled" />
   <java-symbol type="bool" name="config_wimaxEnabled" />
   <java-symbol type="bool" name="show_ongoing_ime_switcher" />
@@ -1837,6 +1836,7 @@
   <java-symbol type="integer" name="config_networkWakeupPacketMark" />
   <java-symbol type="integer" name="config_networkWakeupPacketMask" />
   <java-symbol type="bool" name="config_apfDrop802_3Frames" />
+  <java-symbol type="array" name="config_apfEthTypeBlackList" />
   <java-symbol type="integer" name="config_networkMeteredMultipathPreference" />
   <java-symbol type="integer" name="config_notificationsBatteryFullARGB" />
   <java-symbol type="integer" name="config_notificationsBatteryLedOff" />
@@ -1868,6 +1868,13 @@
   <java-symbol type="layout" name="app_error_dialog" />
   <java-symbol type="plurals" name="wifi_available" />
   <java-symbol type="plurals" name="wifi_available_detailed" />
+  <java-symbol type="string" name="wifi_available_title" />
+  <java-symbol type="string" name="wifi_available_title_connecting" />
+  <java-symbol type="string" name="wifi_available_title_connected" />
+  <java-symbol type="string" name="wifi_available_title_failed_to_connect" />
+  <java-symbol type="string" name="wifi_available_content_failed_to_connect" />
+  <java-symbol type="string" name="wifi_available_action_connect" />
+  <java-symbol type="string" name="wifi_available_action_all_networks" />
   <java-symbol type="string" name="accessibility_binding_label" />
   <java-symbol type="string" name="adb_active_notification_message" />
   <java-symbol type="string" name="adb_active_notification_title" />
@@ -1957,8 +1964,6 @@
   <java-symbol type="string" name="smv_process" />
   <java-symbol type="string" name="tethered_notification_message" />
   <java-symbol type="string" name="tethered_notification_title" />
-  <java-symbol type="string" name="disable_tether_notification_message" />
-  <java-symbol type="string" name="disable_tether_notification_title" />
   <java-symbol type="string" name="adb_debugging_notification_channel_tv" />
   <java-symbol type="string" name="usb_accessory_notification_title" />
   <java-symbol type="string" name="usb_mtp_notification_title" />
@@ -1967,6 +1972,8 @@
   <java-symbol type="string" name="usb_ptp_notification_title" />
   <java-symbol type="string" name="usb_midi_notification_title" />
   <java-symbol type="string" name="usb_supplying_notification_title" />
+  <java-symbol type="string" name="usb_unsupported_audio_accessory_title" />
+  <java-symbol type="string" name="usb_unsupported_audio_accessory_message" />
   <java-symbol type="string" name="config_UsbDeviceConnectionHandling_component" />
   <java-symbol type="string" name="vpn_text" />
   <java-symbol type="string" name="vpn_text_long" />
@@ -2002,14 +2009,9 @@
   <java-symbol type="string" name="config_customAdbPublicKeyConfirmationComponent" />
   <java-symbol type="string" name="config_customAdbPublicKeyConfirmationSecondaryUserComponent" />
   <java-symbol type="string" name="config_customVpnConfirmDialogComponent" />
+  <java-symbol type="string" name="config_customVpnAlwaysOnDisconnectedDialogComponent" />
   <java-symbol type="string" name="config_defaultNetworkScorerPackageName" />
   <java-symbol type="string" name="config_persistentDataPackageName" />
-  <java-symbol type="string" name="reset_retail_demo_mode_title" />
-  <java-symbol type="string" name="reset_retail_demo_mode_text" />
-  <java-symbol type="string" name="demo_user_inactivity_timeout_title" />
-  <java-symbol type="string" name="demo_user_inactivity_timeout_countdown" />
-  <java-symbol type="string" name="demo_user_inactivity_timeout_left_button" />
-  <java-symbol type="string" name="demo_user_inactivity_timeout_right_button" />
 
   <java-symbol type="layout" name="resolver_list" />
   <java-symbol type="id" name="resolver_list" />
@@ -2522,6 +2524,8 @@
   <java-symbol type="integer" name="config_cameraLaunchGestureSensorType" />
   <java-symbol type="string" name="config_cameraLaunchGestureSensorStringType" />
   <java-symbol type="bool" name="config_cameraDoubleTapPowerGestureEnabled" />
+  <java-symbol type="integer" name="config_cameraLiftTriggerSensorType" />
+  <java-symbol type="string" name="config_cameraLiftTriggerSensorStringType" />
 
   <java-symbol type="drawable" name="platlogo_m" />
 
@@ -2544,7 +2548,6 @@
   <java-symbol type="id" name="notification_material_reply_text_3" />
 
   <java-symbol type="string" name="notification_hidden_text" />
-  <java-symbol type="string" name="notification_hidden_by_policy_text" />
   <java-symbol type="id" name="app_name_text" />
   <java-symbol type="id" name="header_text" />
   <java-symbol type="id" name="expand_button" />
@@ -2564,6 +2567,13 @@
   <java-symbol type="dimen" name="notification_content_margin_top" />
   <java-symbol type="dimen" name="notification_content_margin_bottom" />
   <java-symbol type="dimen" name="notification_header_background_height" />
+  <java-symbol type="dimen" name="notification_header_height" />
+  <java-symbol type="dimen" name="notification_header_expand_icon_size" />
+  <java-symbol type="dimen" name="notification_expand_button_padding_top" />
+  <java-symbol type="dimen" name="notification_header_icon_margin_end" />
+  <java-symbol type="dimen" name="notification_header_icon_size" />
+  <java-symbol type="dimen" name="notification_header_app_name_margin_start" />
+  <java-symbol type="dimen" name="notification_header_separating_margin" />
   <java-symbol type="string" name="default_notification_channel_label" />
   <java-symbol type="string" name="importance_from_user" />
   <java-symbol type="string" name="importance_from_person" />
@@ -2628,7 +2638,6 @@
   <java-symbol type="string" name="new_sms_notification_title" />
   <java-symbol type="string" name="new_sms_notification_content" />
 
-  <java-symbol type="dimen" name="media_notification_expanded_image_small_size" />
   <java-symbol type="dimen" name="media_notification_expanded_image_margin_bottom" />
   <java-symbol type="dimen" name="notification_content_image_margin_end" />
 
@@ -2923,14 +2932,25 @@
   <java-symbol type="style" name="AutofillDatasetPicker" />
   <java-symbol type="dimen" name="autofill_dataset_picker_max_size"/>
 
+  <java-symbol type="dimen" name="notification_big_picture_max_height"/>
+  <java-symbol type="dimen" name="notification_big_picture_max_width"/>
+  <java-symbol type="dimen" name="notification_media_image_max_width"/>
+  <java-symbol type="dimen" name="notification_media_image_max_height"/>
+  <java-symbol type="dimen" name="notification_right_icon_size"/>
+  <java-symbol type="dimen" name="notification_custom_view_max_image_height"/>
+  <java-symbol type="dimen" name="notification_custom_view_max_image_width"/>
+
   <!-- Accessibility fingerprint gestures -->
   <java-symbol type="string" name="capability_title_canCaptureFingerprintGestures" />
   <java-symbol type="string" name="capability_desc_canCaptureFingerprintGestures" />
 
   <!-- android.service.trust -->
   <java-symbol type="bool" name="config_allowEscrowTokenForTrustAgent"/>
+  <java-symbol type="string" name="config_defaultTrustAgent" />
 
   <!-- Time picker -->
+  <java-symbol type="id" name="right_icon_container"/>
+  <java-symbol type="id" name="reply_icon_action"/>
   <java-symbol type="id" name="toggle_mode"/>
   <java-symbol type="id" name="input_mode"/>
   <java-symbol type="id" name="input_header"/>
@@ -2997,13 +3017,9 @@
 
   <!-- ETWS primary messages -->
   <java-symbol type="string" name="etws_primary_default_message_earthquake" />
-
   <java-symbol type="string" name="etws_primary_default_message_tsunami" />
-
   <java-symbol type="string" name="etws_primary_default_message_earthquake_and_tsunami" />
-
   <java-symbol type="string" name="etws_primary_default_message_test" />
-
   <java-symbol type="string" name="etws_primary_default_message_others" />
 
   <java-symbol type="bool" name="config_quickSettingsSupported" />
@@ -3024,16 +3040,31 @@
 
   <java-symbol type="array" name="config_hideWhenDisabled_packageNames" />
 
+  <java-symbol type="string" name="config_dozeLongPressSensorType" />
+
   <java-symbol type="array" name="config_allowedGlobalInstantAppSettings" />
   <java-symbol type="array" name="config_allowedSystemInstantAppSettings" />
   <java-symbol type="array" name="config_allowedSecureInstantAppSettings" />
 
   <java-symbol type="bool" name="config_handleVolumeKeysInWindowManager" />
-
   <java-symbol type="integer" name="config_inCallNotificationVolumeRelative" />
+  <java-symbol type="bool" name="config_dozeAlwaysOnDisplayAvailable" />
+  <java-symbol type="bool" name="config_displayBlanksAfterDoze" />
+  <java-symbol type="bool" name="config_displayBrightnessBucketsInDoze" />
+  <java-symbol type="integer" name="config_storageManagerDaystoRetainDefault" />
+  <java-symbol type="string" name="config_headlineFontFamily" />
+  <java-symbol type="string" name="config_headlineFontFamilyLight" />
+
   <java-symbol type="drawable" name="stat_sys_vitals" />
 
+  <java-symbol type="color" name="text_color_primary" />
+
   <java-symbol type="array" name="config_batteryPackageTypeSystem" />
   <java-symbol type="array" name="config_batteryPackageTypeService" />
+  <java-symbol type="bool" name="config_showAreaUpdateInfoSettings" />
+  <java-symbol type="layout" name="shutdown_dialog" />
+  <java-symbol type="dimen" name="chooser_service_spacing" />
+  <java-symbol type="bool" name="config_showSysuiShutdown" />
 
+  <java-symbol type="bool" name="config_display_no_service_when_sim_unready" />
 </resources>
diff --git a/core/res/res/xml/color_extraction.xml b/core/res/res/xml/color_extraction.xml
new file mode 100644
index 0000000..7d52b20
--- /dev/null
+++ b/core/res/res/xml/color_extraction.xml
@@ -0,0 +1,348 @@
+<?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
+  -->
+
+<colorextraction>
+    <!-- List of material color palettes in HSL -->
+    <palettes>
+        <!-- Grey scale -->
+        <palette h="0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f"
+                 s="0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f"
+                 l="0.08f, 0.11f, 0.14901960784313725f, 0.2f, 0.2980392156862745f, 0.4f,
+                0.4980392156862745f, 0.6196078431372549f, 0.7176470588235294f,
+                0.8196078431372549f, 0.9176470588235294f, 0.9490196078431372f"/>
+        <!-- All colors -->
+        <palette h="1,1,0.991,0.991,0.9833333333333333,0,0,0,
+                0.01134380453752181,0.015625000000000003,0.024193548387096798,
+                0.027397260273972573,0.017543859649122865"
+                 s="1,1,1,1,1,1,1,0.8434782608695652,1,1,1,1,1"
+                 l="0.04,0.09,0.14,0.2,0.27450980392156865,
+                0.34901960784313724,0.4235294117647059,0.5490196078431373,
+                0.6254901960784314,0.6862745098039216,0.7568627450980392,
+                0.8568627450980393,0.9254901960784314"/>
+        <palette h="0.638,0.638,0.6385767790262171,0.6301169590643275,
+                0.6223958333333334,0.6151079136690647,0.6065400843881856,
+                0.5986964618249534,0.5910746812386157,0.5833333333333334,
+                0.5748031496062993,0.5582010582010583"
+                 s="1,1,1,1,0.9014084507042253,0.8128654970760234,
+                0.7979797979797981,0.7816593886462883,0.778723404255319,1,1,1"
+                 l="0.05,0.12,0.17450980392156862,0.2235294117647059,
+                0.2784313725490196,0.3352941176470588,0.388235294117647,
+                0.44901960784313727,0.5392156862745098,0.6509803921568628,
+                0.7509803921568627,0.8764705882352941"/>
+        <palette h="0.563,0.569,0.5666,0.5669934640522876,0.5748031496062993,
+                0.5595238095238095,0.5473118279569893,0.5393258426966292,
+                0.5315955766192734,0.524031007751938,0.5154711673699016,
+                0.508080808080808,0.5"
+                 s="1,1,1,1,1,1,1,1,1,0.8847736625514403,1,1,1"
+                 l="0.07,0.12,0.16,0.2,0.24901960784313726,
+                0.27450980392156865,0.30392156862745096,0.34901960784313724,
+                0.4137254901960784,0.47647058823529415,0.5352941176470588,
+                0.6764705882352942,0.8"/>
+        <palette h="0.508,0.511,0.508,0.508,0.5082304526748972,
+                0.5069444444444444,0.5,0.5,0.5,0.48724954462659376,
+                0.4800347222222222,0.4755134281200632,0.4724409448818897,
+                0.4671052631578947"
+                 s="1,1,1,1,1,0.8888888888888887,0.9242424242424242,1,
+                1,0.8133333333333332,0.7868852459016393,1,1,1"
+                 l="0.04,0.06,0.08,0.12,0.1588235294117647,
+                0.21176470588235297,0.25882352941176473,0.3,0.34901960784313724,
+                0.44117647058823534,0.5215686274509804,0.5862745098039216,
+                0.7509803921568627,0.8509803921568627"/>
+        <palette h="0.333,0.333,0.333,0.3333333333333333,0.3333333333333333,
+                0.34006734006734,0.34006734006734,0.34006734006734,
+                0.34259259259259256,0.3475783475783476,0.34767025089605735,
+                0.3467741935483871,0.3703703703703704"
+                 s="0.70,0.72,0.69,0.6703296703296703,0.728813559322034,
+                0.5657142857142856,0.5076923076923077,0.3944223107569721,
+                0.6206896551724138,0.8931297709923666,1,1,1"
+                 l="0.05,0.08,0.14,0.1784313725490196,0.23137254901960785,
+                0.3431372549019608,0.38235294117647056,0.49215686274509807,
+                0.6588235294117647,0.7431372549019608,0.8176470588235294,
+                0.8784313725490196,0.9294117647058824"/>
+        <palette h="0.161,0.163,0.163,0.162280701754386,0.15032679738562088,
+                0.15879265091863518,0.16236559139784948,0.17443868739205526,
+                0.17824074074074076,0.18674698795180725,0.18692449355432778,
+                0.1946778711484594,0.18604651162790695"
+                 s="1,1,1,1,1,1,1,1,1,1,1,1,1"
+                 l="0.05,0.08,0.11,0.14901960784313725,0.2,
+                0.24901960784313726,0.30392156862745096,0.3784313725490196,
+                0.4235294117647059,0.48823529411764705,0.6450980392156863,
+                0.7666666666666666,0.8313725490196078"/>
+        <palette h="0.108,0.105,0.105,0.105,0.10619469026548674,
+                0.11924686192468618,0.13046448087431692,0.14248366013071895,
+                0.1506024096385542,0.16220238095238093,0.16666666666666666,
+                0.16666666666666666,0.162280701754386,0.15686274509803924"
+                 s="1,1,1,1,1,1,1,1,1,1,1,1,1,1"
+                 l="0.17,0.22,0.28,0.35,0.44313725490196076,
+                0.46862745098039216,0.47843137254901963,0.5,0.5117647058823529,
+                0.5607843137254902,0.6509803921568628,0.7509803921568627,
+                0.8509803921568627,0.9"/>
+        <palette h="0.036,0.036,0.036,0.036,0.03561253561253561,
+                0.05098039215686275,0.07516339869281045,0.09477124183006536,
+                0.1150326797385621,0.134640522875817,0.14640522875816991,
+                0.1582397003745319,0.15773809523809523,0.15359477124183002"
+                 s="1,1,1,1,1,1,1,1,1,1,1,1,1,1"
+                 l="0.19,0.26,0.34,0.39,0.4588235294117647,0.5,0.5,0.5,
+                0.5,0.5,0.5,0.6509803921568628,0.7803921568627451,0.9"/>
+        <palette h="0.955,0.961,0.958,0.9596491228070175,0.9593837535014005,
+                0.9514767932489452,0.943859649122807,0.9396825396825397,
+                0.9395424836601307,0.9393939393939394,0.9362745098039216,
+                0.9754098360655739,0.9824561403508771"
+                 s="0.87,0.85,0.85,0.84070796460177,0.8206896551724138,
+                0.7979797979797981,0.7661290322580644,0.9051724137931036,
+                1,1,1,1,1"
+                 l="0.06,0.11,0.16,0.22156862745098038,0.2843137254901961,
+                0.388235294117647,0.48627450980392156,0.5450980392156863,
+                0.6,0.6764705882352942,0.8,0.8803921568627451,
+                0.9254901960784314"/>
+        <palette h="0.866,0.855,0.841025641025641,0.8333333333333334,
+                0.8285256410256411,0.821522309711286,0.8083333333333333,
+                0.8046594982078853,0.8005822416302766,0.7842377260981912,
+                0.7771084337349398,0.7747747747747749"
+                 s="1,1,1,1,1,1,1,1,1,
+                0.737142857142857,0.6434108527131781,0.46835443037974644"
+                 l="0.05,0.08,0.12745098039215685,0.15490196078431373,
+                0.20392156862745098,0.24901960784313726,0.3137254901960784,
+                0.36470588235294116,0.44901960784313727,0.6568627450980392,
+                0.7470588235294118,0.8450980392156863"/>
+        <palette h="0.925,0.93,0.938,0.947,0.955952380952381,
+                0.9681069958847737,0.9760479041916167,0.9873563218390804,0,0,
+                0.009057971014492771,0.026748971193415648,
+                0.041666666666666616,0.05303030303030304"
+                 s="1,1,1,1,1,0.8350515463917526,0.6929460580912863,
+                0.6387665198237885,0.6914893617021276,0.7583892617449666,
+                0.8070175438596495,0.9310344827586209,1,1"
+                 l="0.10,0.13,0.17,0.2,0.27450980392156865,
+                0.3803921568627451,0.4725490196078432,0.5549019607843138,
+                0.6313725490196078,0.707843137254902,0.7764705882352941,
+                0.8294117647058823,0.9058823529411765,0.9568627450980391"/>
+        <palette h="0.733,0.736,0.744,0.7514619883040936,0.7679738562091503,
+                0.7802083333333333,0.7844311377245509,0.796875,
+                0.8165618448637316,0.8487179487179487,0.8582375478927203,
+                0.8562091503267975,0.8666666666666667"
+                 s="1,1,1,1,1,0.8163265306122449,0.6653386454183268,
+                0.7547169811320753,0.929824561403509,0.9558823529411766,
+                0.9560439560439562,1,1"
+                 l="0.07,0.12,0.17,0.2235294117647059,0.3,
+                0.38431372549019605,0.492156862745098,0.5843137254901961,
+                0.6647058823529411,0.7333333333333334,0.8215686274509804,0.9,
+                0.9411764705882353"/>
+        <palette h="0.6666666666666666,0.6666666666666666,0.6666666666666666,
+                0.6666666666666666,0.6666666666666666,0.6666666666666666,
+                0.6666666666666666,0.6666666666666666,0.6666666666666666,
+                0.6666666666666666,0.6666666666666666"
+                 s="0.25,0.24590163934426232,0.17880794701986752,
+                0.14606741573033713,0.13761467889908252,0.14893617021276592,
+                0.16756756756756758,0.20312500000000017,0.26086956521739135,
+                0.29999999999999966,0.5000000000000004"
+                 l="0.18,0.2392156862745098,0.296078431372549,
+                0.34901960784313724,0.4274509803921569,0.5392156862745098,
+                0.6372549019607843,0.7490196078431373,0.8196078431372549,
+                0.8823529411764706,0.9372549019607843"/>
+        <palette h="0.938,0.944,0.952,0.961,0.9678571428571429,
+                0.9944812362030905,0,0,
+                0.0047348484848484815,0.00316455696202532,0,
+                0.9980392156862745,0.9814814814814816,0.9722222222222221"
+                 s="1,1,1,1,1,0.7023255813953488,0.6638655462184874,
+                0.6521739130434782,0.7719298245614035,0.8315789473684211,
+                0.6867469879518071,0.7264957264957265,0.8181818181818182,
+                0.8181818181818189"
+                 l="0.08,0.13,0.18,0.23,0.27450980392156865,
+                0.4215686274509804,
+                0.4666666666666667,0.503921568627451,0.5529411764705883,
+                0.6274509803921569,0.6745098039215687,0.7705882352941176,
+                0.892156862745098,0.9568627450980391"/>
+        <palette h="0.88,0.888,0.897,0.9052287581699346,0.9112021857923498,
+                0.9270152505446624,0.9343137254901961,0.9391534391534391,
+                0.9437984496124031,0.943661971830986,0.9438943894389439,
+                0.9426229508196722,0.9444444444444444"
+                 s="1,1,1,1,0.8133333333333332,0.7927461139896375,
+                0.7798165137614679,0.7777777777777779,0.8190476190476191,
+                0.8255813953488372,0.8211382113821142,0.8133333333333336,
+                0.8000000000000006"
+                 l="0.08,0.12,0.16,0.2,0.29411764705882354,
+                0.3784313725490196,0.42745098039215684,0.4764705882352941,
+                0.5882352941176471,0.6627450980392157,0.7588235294117647,
+                0.8529411764705882,0.9411764705882353"/>
+        <palette h="0.669,0.680,0.6884057971014492,0.6974789915966387,
+                0.7079889807162534,0.7154471544715447,0.7217741935483872,
+                0.7274143302180687,0.7272727272727273,0.7258064516129031,
+                0.7252252252252251,0.7333333333333333"
+                 s="0.81,0.81,0.8214285714285715,0.6878612716763006,
+                0.6080402010050251,0.5774647887323943,0.5391304347826086,
+                0.46724890829694316,0.4680851063829788,0.462686567164179,
+                0.45679012345678977,0.4545454545454551"
+                 l="0.12,0.16,0.2196078431372549,0.33921568627450976,
+                0.39019607843137255,0.4176470588235294,0.45098039215686275,
+                0.5509803921568628,0.6313725490196078,0.7372549019607844,
+                0.8411764705882353,0.9352941176470588"/>
+        <palette h="0.6470588235294118,0.6516666666666667,0.6464174454828661,
+                0.6441441441441442,0.6432748538011696,0.6416666666666667,
+                0.6402439024390243,0.6412429378531074,0.6435185185185186,
+                0.6428571428571429"
+                 s="0.8095238095238095,0.6578947368421053,0.5721925133689839,
+                0.5362318840579711,0.5,0.4424778761061947,0.44086021505376327,
+                0.44360902255639095,0.4499999999999997,0.4375000000000006"
+                 l="0.16470588235294117,0.2980392156862745,0.36666666666666664,
+                0.40588235294117647,0.44705882352941173,
+                0.5568627450980392,0.6352941176470588,0.7392156862745098,
+                0.8431372549019608,0.9372549019607843"/>
+        <palette h="0.469,0.46732026143790845,0.4718614718614719,
+                0.4793650793650794,0.48071625344352614,0.4829683698296837,
+                0.484375,0.4841269841269842,0.48444444444444457,
+                0.48518518518518516,0.4907407407407408"
+                 s="1,1,1,1,1,1,0.6274509803921569,0.41832669322709176,
+                0.41899441340782106,0.4128440366972478,0.4090909090909088"
+                 l="0.07,0.1,0.15098039215686274,0.20588235294117646,
+                0.2372549019607843,0.26862745098039215,0.4,0.5078431372549019,
+                0.6490196078431372,0.7862745098039216,0.9137254901960784"/>
+        <palette h="0.542,0.5444444444444444,0.5555555555555556,
+                0.5555555555555556,0.553763440860215,0.5526315789473684,
+                0.5555555555555556,0.5555555555555555,0.5555555555555556,
+                0.5512820512820514,0.5666666666666667"
+                 s="0.25,0.24590163934426232,0.19148936170212766,
+                0.1791044776119403,0.18343195266272191,0.18446601941747576,
+                0.1538461538461539,0.15625000000000003,0.15328467153284678,
+                0.15662650602409653,0.151515151515151"
+                 l="0.05,0.1196078431372549,0.1843137254901961,
+                0.2627450980392157,
+                0.33137254901960783,0.403921568627451,0.5411764705882354,
+                0.6235294117647059,0.7313725490196079,0.8372549019607843,
+                0.9352941176470588"/>
+        <palette h="0.022222222222222223,0.02469135802469136,0.031249999999999997,
+                0.03947368421052631,0.04166666666666668,
+                0.043650793650793655,0.04411764705882352,0.04166666666666652,
+                0.04444444444444459,0.05555555555555529"
+                 s="0.33333333333333337,0.2783505154639175,0.2580645161290323,
+                0.25675675675675674,0.2528735632183908,0.17500000000000002,
+                0.15315315315315312,0.15189873417721522,
+                0.15789473684210534,0.15789473684210542"
+                 l="0.08823529411764705,0.19019607843137254,0.2431372549019608,
+                0.2901960784313725,0.3411764705882353,0.47058823529411764,
+                0.5647058823529412,0.6901960784313725,0.8137254901960784,
+                0.9254901960784314"/>
+        <palette h="0.027,0.03,0.038,0.044,0.050884955752212385,
+                0.07254901960784313,0.0934640522875817,
+                0.10457516339869281,0.11699346405228758,
+                0.1255813953488372,0.1268939393939394,0.12533333333333332,
+                0.12500000000000003,0.12777777777777777"
+                 s="1,1,1,1,1,1,1,1,1,1,1,1,1,1"
+                 l="0.25,0.3,0.35,0.4,0.44313725490196076,0.5,0.5,0.5,
+                0.5,0.5784313725490196,
+                0.6549019607843137,0.7549019607843137,0.8509803921568627,
+                0.9411764705882353"/>
+    </palettes>
+    <blacklist>
+        <!-- Red -->
+        <range h="0, 20"
+               s="0.7, 1"
+               l="0.21, 0.79"/>
+        <range h="0, 20"
+               s="0.3, 0.7"
+               l="0.355, 0.653"/>
+        <!-- Red Orange -->
+        <range h="20, 40"
+               s="0.7, 1"
+               l="0.28, 0.643"/>
+        <range h="20, 40"
+               s="0.3, 0.7"
+               l="0.414, 0.561"/>
+        <range h="20, 40"
+               s="0, 3"
+               l="0.343, 0.584"/>
+        <!-- Orange -->
+        <range h="40, 60"
+               s="0.7, 1"
+               l="0.173, 0.349"/>
+        <range h="40, 60"
+               s="0.3, 0.7"
+               l="0.233, 0.427"/>
+        <range h="40, 60"
+               s="0, 0.3"
+               l="0.231, 0.484"/>
+        <!-- Yellow 60 -->
+        <range h="60, 80"
+               s="0.7, 1"
+               l="0.488, 0.737"/>
+        <range h="60, 80"
+               s="0.3, 0.7"
+               l="0.673, 0.837"/>
+        <!-- Yellow Green 80 -->
+        <range h="80, 100"
+               s="0.7, 1"
+               l="0.469, 0.61"/>
+        <!-- Yellow green 100 -->
+        <range h="100, 120"
+               s="0.7, 1"
+               l="0.388, 0.612"/>
+        <range h="100, 120"
+               s="0.3, 0.7"
+               l="0.424, 0.541"/>
+        <!-- Green -->
+        <range h="120, 140"
+               s="0.7, 1"
+               l="0.375, 0.52"/>
+        <range h="120, 140"
+               s="0.3, 0.7"
+               l="0.435, 0.524"/>
+        <!-- Green Blue 140 -->
+        <range h="140, 160"
+               s="0.7, 1"
+               l="0.496, 0.641"/>
+        <!-- Seaoam -->
+        <range h="160, 180"
+               s="0.7, 1"
+               l="0.496, 0.567"/>
+        <!-- Cyan -->
+        <range h="180, 200"
+               s="0.7, 1"
+               l="0.52, 0.729"/>
+        <!-- Blue -->
+        <range h="220, 240"
+               s="0.7, 1"
+               l="0.396, 0.571"/>
+        <range h="220, 240"
+               s="0.3, 0.7"
+               l="0.425, 0.551"/>
+        <!-- Blue Purple 240 -->
+        <range h="240, 260"
+               s="0.7, 1"
+               l="0.418, 0.639"/>
+        <range h="220, 240"
+               s="0.3, 0.7"
+               l="0.441, 0.576"/>
+        <!-- Blue Purple 260 -->
+        <range h="260, 280"
+               s="0.3, 1"
+               l="0.461, 0.553"/>
+        <!-- Fuchsia -->
+        <range h="300, 320"
+               s="0.7, 1"
+               l="0.484, 0.588"/>
+        <range h="300, 320"
+               s="0.3, 0.7"
+               l="0.48, 0.592"/>
+        <!-- Pink -->
+        <range h="320, 340"
+               s="0.7, 1"
+               l="0.466, 0.629"/>
+        <!-- Soft red -->
+        <range h="340, 360"
+               s="0.7, 1"
+               l="0.437, 0.596"/>
+    </blacklist>
+</colorextraction>
\ No newline at end of file
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 7e9f561..f5b350b 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -181,7 +181,7 @@
     <shortcode country="mk" pattern="\\d{1,6}" free="129005|122" />
 
     <!-- Mexico: 4-5 digits (not confirmed), known premium codes listed -->
-    <shortcode country="mx" pattern="\\d{4,5}" premium="53035|7766" free="46645|5050|26259|50025|50052|9963" />
+    <shortcode country="mx" pattern="\\d{4,5}" premium="53035|7766" free="46645|5050|26259|50025|50052|9963|76551" />
 
     <!-- Malaysia: 5 digits: http://www.skmm.gov.my/attachment/Consumer_Regulation/Mobile_Content_Services_FAQs.pdf -->
     <shortcode country="my" pattern="\\d{5}" premium="32298|33776" free="22099|28288" />
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java
index 31ce95e..4b32cea 100644
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java
+++ b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java
@@ -256,13 +256,13 @@
         mTestUtils.unpair(mAdapter, device);
         mTestUtils.pair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey,
                 BluetoothTestRunner.sDevicePairPin);
-        mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.INPUT_DEVICE, null);
+        mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.HID_HOST, null);
 
         for (int i = 0; i < iterations; i++) {
             mTestUtils.writeOutput("connectInput iteration " + (i + 1) + " of " + iterations);
-            mTestUtils.connectProfile(mAdapter, device, BluetoothProfile.INPUT_DEVICE,
+            mTestUtils.connectProfile(mAdapter, device, BluetoothProfile.HID_HOST,
                     String.format("connectInput(device=%s)", device));
-            mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.INPUT_DEVICE,
+            mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.HID_HOST,
                     String.format("disconnectInput(device=%s)", device));
         }
 
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
index ee15978..ada0366 100644
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
+++ b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
@@ -227,8 +227,8 @@
                 case BluetoothProfile.HEADSET:
                     mConnectionAction = BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED;
                     break;
-                case BluetoothProfile.INPUT_DEVICE:
-                    mConnectionAction = BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED;
+                case BluetoothProfile.HID_HOST:
+                    mConnectionAction = BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED;
                     break;
                 case BluetoothProfile.PAN:
                     mConnectionAction = BluetoothPan.ACTION_CONNECTION_STATE_CHANGED;
@@ -322,8 +322,8 @@
                     case BluetoothProfile.HEADSET:
                         mHeadset = (BluetoothHeadset) proxy;
                         break;
-                    case BluetoothProfile.INPUT_DEVICE:
-                        mInput = (BluetoothInputDevice) proxy;
+                    case BluetoothProfile.HID_HOST:
+                        mInput = (BluetoothHidHost) proxy;
                         break;
                     case BluetoothProfile.PAN:
                         mPan = (BluetoothPan) proxy;
@@ -342,7 +342,7 @@
                     case BluetoothProfile.HEADSET:
                         mHeadset = null;
                         break;
-                    case BluetoothProfile.INPUT_DEVICE:
+                    case BluetoothProfile.HID_HOST:
                         mInput = null;
                         break;
                     case BluetoothProfile.PAN:
@@ -362,7 +362,7 @@
     private Context mContext;
     private BluetoothA2dp mA2dp = null;
     private BluetoothHeadset mHeadset = null;
-    private BluetoothInputDevice mInput = null;
+    private BluetoothHidHost mInput = null;
     private BluetoothPan mPan = null;
 
     /**
@@ -894,7 +894,7 @@
      * @param adapter The BT adapter.
      * @param device The remote device.
      * @param profile The profile to connect. One of {@link BluetoothProfile#A2DP},
-     * {@link BluetoothProfile#HEADSET}, or {@link BluetoothProfile#INPUT_DEVICE}.
+     * {@link BluetoothProfile#HEADSET}, or {@link BluetoothProfile#HID_HOST}.
      * @param methodName The method name to printed in the logs.  If null, will be
      * "connectProfile(profile=&lt;profile&gt;, device=&lt;device&gt;)"
      */
@@ -935,8 +935,8 @@
                     assertTrue(((BluetoothA2dp)proxy).connect(device));
                 } else if (profile == BluetoothProfile.HEADSET) {
                     assertTrue(((BluetoothHeadset)proxy).connect(device));
-                } else if (profile == BluetoothProfile.INPUT_DEVICE) {
-                    assertTrue(((BluetoothInputDevice)proxy).connect(device));
+                } else if (profile == BluetoothProfile.HID_HOST) {
+                    assertTrue(((BluetoothHidHost)proxy).connect(device));
                 }
                 break;
             default:
@@ -975,7 +975,7 @@
      * @param adapter The BT adapter.
      * @param device The remote device.
      * @param profile The profile to disconnect. One of {@link BluetoothProfile#A2DP},
-     * {@link BluetoothProfile#HEADSET}, or {@link BluetoothProfile#INPUT_DEVICE}.
+     * {@link BluetoothProfile#HEADSET}, or {@link BluetoothProfile#HID_HOST}.
      * @param methodName The method name to printed in the logs.  If null, will be
      * "connectProfile(profile=&lt;profile&gt;, device=&lt;device&gt;)"
      */
@@ -1010,8 +1010,8 @@
                     assertTrue(((BluetoothA2dp)proxy).disconnect(device));
                 } else if (profile == BluetoothProfile.HEADSET) {
                     assertTrue(((BluetoothHeadset)proxy).disconnect(device));
-                } else if (profile == BluetoothProfile.INPUT_DEVICE) {
-                    assertTrue(((BluetoothInputDevice)proxy).disconnect(device));
+                } else if (profile == BluetoothProfile.HID_HOST) {
+                    assertTrue(((BluetoothHidHost)proxy).disconnect(device));
                 }
                 break;
             case BluetoothProfile.STATE_DISCONNECTED:
@@ -1237,7 +1237,7 @@
         long s = System.currentTimeMillis();
         while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
             state = mPan.getConnectionState(device);
-            if (state == BluetoothInputDevice.STATE_DISCONNECTED
+            if (state == BluetoothHidHost.STATE_DISCONNECTED
                     && (receiver.getFiredFlags() & mask) == mask) {
                 long finish = receiver.getCompletedTime();
                 if (start != -1 && finish != -1) {
@@ -1255,7 +1255,7 @@
         int firedFlags = receiver.getFiredFlags();
         removeReceiver(receiver);
         fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%s)",
-                methodName, state, BluetoothInputDevice.STATE_DISCONNECTED, firedFlags, mask));
+                methodName, state, BluetoothHidHost.STATE_DISCONNECTED, firedFlags, mask));
     }
 
     /**
@@ -1404,7 +1404,7 @@
         String[] actions = {
                 BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED,
                 BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED,
-                BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED};
+                BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED};
         ConnectProfileReceiver receiver = new ConnectProfileReceiver(device, profile,
                 expectedFlags);
         addReceiver(receiver, actions);
@@ -1443,7 +1443,7 @@
                     return mHeadset;
                 }
                 break;
-            case BluetoothProfile.INPUT_DEVICE:
+            case BluetoothProfile.HID_HOST:
                 if (mInput != null) {
                     return mInput;
                 }
@@ -1469,7 +1469,7 @@
                     sleep(POLL_TIME);
                 }
                 return mHeadset;
-            case BluetoothProfile.INPUT_DEVICE:
+            case BluetoothProfile.HID_HOST:
                 while (mInput == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
                     sleep(POLL_TIME);
                 }
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 94a515b..e127896 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1172,6 +1172,7 @@
         </activity>
         <activity android:name="com.android.internal.app.ChooserWrapperActivity"/>
         <activity android:name="com.android.internal.app.ResolverWrapperActivity"/>
+        <activity android:name="com.android.internal.app.IntentForwarderActivityTest$IntentForwarderWrapperActivity"/>
 
         <receiver android:name="android.app.activity.AbortReceiver">
             <intent-filter android:priority="1">
@@ -1309,14 +1310,16 @@
             </intent-filter>
         </activity>
 
-        <activity android:name="android.animation.BasicAnimatorActivity">
+        <activity android:name="android.animation.BasicAnimatorActivity"
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
 
-        <activity android:name="android.animation.AnimatorSetActivity">
+        <activity android:name="android.animation.AnimatorSetActivity"
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml
index ed96bc1..23d70b8 100644
--- a/core/tests/coretests/AndroidTest.xml
+++ b/core/tests/coretests/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="FrameworksCoreTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.coretests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index ac1ac19..5457713 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -18,6 +18,7 @@
 
 import static com.android.internal.util.NotificationColorUtil.satisfiesTextContrast;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
@@ -26,8 +27,6 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import com.android.internal.util.NotificationColorUtil;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -44,9 +43,51 @@
     }
 
     @Test
+    public void testColorizedByPermission() {
+        Notification n = new Notification.Builder(mContext, "test")
+                .setFlag(Notification.FLAG_CAN_COLORIZE, true)
+                .setColorized(true)
+                .build();
+        assertTrue(n.isColorized());
+
+        n = new Notification.Builder(mContext, "test")
+                .setFlag(Notification.FLAG_CAN_COLORIZE, true)
+                .build();
+        assertFalse(n.isColorized());
+
+        n = new Notification.Builder(mContext, "test")
+                .setFlag(Notification.FLAG_CAN_COLORIZE, false)
+                .setColorized(true)
+                .build();
+        assertFalse(n.isColorized());
+    }
+
+    @Test
+    public void testColorizedByForeground() {
+        Notification n = new Notification.Builder(mContext, "test")
+                .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
+                .setColorized(true)
+                .build();
+        assertTrue(n.isColorized());
+
+        n = new Notification.Builder(mContext, "test")
+                .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
+                .build();
+        assertFalse(n.isColorized());
+
+        n = new Notification.Builder(mContext, "test")
+                .setFlag(Notification.FLAG_FOREGROUND_SERVICE, false)
+                .setColorized(true)
+                .build();
+        assertFalse(n.isColorized());
+    }
+
+    @Test
     public void testColorSatisfiedWhenBgDarkTextDarker() {
         Notification.Builder builder = getMediaNotification();
-        builder.build();
+        Notification n = builder.build();
+
+        assertTrue(n.isColorized());
 
         // An initial guess where the foreground color is actually darker than an already dark bg
         int backgroundColor = 0xff585868;
@@ -58,6 +99,45 @@
         assertTrue(satisfiesTextContrast(secondaryTextColor, backgroundColor));
     }
 
+    @Test
+    public void testHasCompletedProgress_noProgress() {
+        Notification n = new Notification.Builder(mContext).build();
+
+        assertFalse(n.hasCompletedProgress());
+    }
+
+    @Test
+    public void testHasCompletedProgress_complete() {
+        Notification n = new Notification.Builder(mContext)
+                .setProgress(100, 100, true)
+                .build();
+        Notification n2 = new Notification.Builder(mContext)
+                .setProgress(10, 10, false)
+                .build();
+        assertTrue(n.hasCompletedProgress());
+        assertTrue(n2.hasCompletedProgress());
+    }
+
+    @Test
+    public void testHasCompletedProgress_notComplete() {
+        Notification n = new Notification.Builder(mContext)
+                .setProgress(100, 99, true)
+                .build();
+        Notification n2 = new Notification.Builder(mContext)
+                .setProgress(10, 4, false)
+                .build();
+        assertFalse(n.hasCompletedProgress());
+        assertFalse(n2.hasCompletedProgress());
+    }
+
+    @Test
+    public void testHasCompletedProgress_zeroMax() {
+        Notification n = new Notification.Builder(mContext)
+                .setProgress(0, 0, true)
+                .build();
+        assertFalse(n.hasCompletedProgress());
+    }
+
     private Notification.Builder getMediaNotification() {
         MediaSession session = new MediaSession(mContext, "test");
         return new Notification.Builder(mContext, "color")
diff --git a/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java b/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java
index e9e3a18e..2470e87 100644
--- a/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java
+++ b/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java
@@ -16,16 +16,14 @@
 
 package android.app.admin;
 
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import static org.junit.Assert.assertEquals;
 
 import android.os.Parcel;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 /** Unit tests for {@link PasswordMetrics}. */
 @RunWith(AndroidJUnit4.class)
@@ -43,20 +41,6 @@
         assertEquals(0, metrics.numeric);
         assertEquals(0, metrics.symbols);
         assertEquals(0, metrics.nonLetter);
-        assertTrue("default constructor does not produce default metrics", metrics.isDefault());
-    }
-
-    @Test
-    public void testIsNotDefault() {
-        final PasswordMetrics metrics = new PasswordMetrics(
-                DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, 12);
-        assertFalse("non-default metrics are repoted as default", metrics.isDefault());
-    }
-
-    @Test
-    public void testComputeForEmptyPassword() {
-        final PasswordMetrics metrics = PasswordMetrics.computeForPassword("");
-        assertTrue("empty password has default metrics", metrics.isDefault());
     }
 
     @Test
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 1ffc1b3..423d45ea 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -36,6 +36,7 @@
 import android.content.res.Resources.NotFoundException;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.FileUtils;
@@ -64,9 +65,14 @@
 import com.android.frameworks.coretests.R;
 import com.android.internal.content.PackageHelper;
 
+import dalvik.system.VMRuntime;
+
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -78,9 +84,9 @@
 
     public static final String TAG = "PackageManagerTests";
 
-    public final long MAX_WAIT_TIME = 25 * 1000;
+    public static final long MAX_WAIT_TIME = 25 * 1000;
 
-    public final long WAIT_TIME_INCR = 5 * 1000;
+    public static final long WAIT_TIME_INCR = 5 * 1000;
 
     private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec";
 
@@ -3844,6 +3850,117 @@
                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
     }
 
+    private static class TestDexModuleRegisterCallback
+            extends PackageManager.DexModuleRegisterCallback {
+        private String mDexModulePath = null;
+        private boolean mSuccess = false;
+        private String mMessage = null;
+        CountDownLatch doneSignal = new CountDownLatch(1);
+
+        @Override
+        public void onDexModuleRegistered(String dexModulePath, boolean success, String message) {
+            mDexModulePath = dexModulePath;
+            mSuccess = success;
+            mMessage = message;
+            doneSignal.countDown();
+        }
+
+        boolean waitTillDone() {
+            long startTime = System.currentTimeMillis();
+            while (System.currentTimeMillis() - startTime < MAX_WAIT_TIME) {
+                try {
+                    return doneSignal.await(MAX_WAIT_TIME, TimeUnit.MILLISECONDS);
+                } catch (InterruptedException e) {
+                    Log.i(TAG, "Interrupted during sleep", e);
+                }
+            }
+            return false;
+        }
+
+    }
+
+    // Verify that the base code path cannot be registered.
+    public void testRegisterDexModuleBaseCode() throws Exception {
+        PackageManager pm = getPm();
+        ApplicationInfo info = getContext().getApplicationInfo();
+        TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
+        pm.registerDexModule(info.getBaseCodePath(), callback);
+        assertTrue(callback.waitTillDone());
+        assertEquals(info.getBaseCodePath(), callback.mDexModulePath);
+        assertFalse("BaseCodePath should not be registered", callback.mSuccess);
+    }
+
+    // Verify thatmodules which are not own by the calling package are not registered.
+    public void testRegisterDexModuleNotOwningModule() throws Exception {
+        TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
+        String moduleBelongingToOtherPackage = "/data/user/0/com.google.android.gms/module.apk";
+        getPm().registerDexModule(moduleBelongingToOtherPackage, callback);
+        assertTrue(callback.waitTillDone());
+        assertEquals(moduleBelongingToOtherPackage, callback.mDexModulePath);
+        assertTrue(callback.waitTillDone());
+        assertFalse("Only modules belonging to the calling package can be registered",
+                callback.mSuccess);
+    }
+
+    // Verify that modules owned by the package are successfully registered.
+    public void testRegisterDexModuleSuccessfully() throws Exception {
+        ApplicationInfo info = getContext().getApplicationInfo();
+        // Copy the main apk into the data folder and use it as a "module".
+        File dexModuleDir = new File(info.dataDir, "module-dir");
+        File dexModule = new File(dexModuleDir, "module.apk");
+        try {
+            assertNotNull(FileUtils.createDir(
+                    dexModuleDir.getParentFile(), dexModuleDir.getName()));
+            Files.copy(Paths.get(info.getBaseCodePath()), dexModule.toPath(),
+                    StandardCopyOption.REPLACE_EXISTING);
+            TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
+            getPm().registerDexModule(dexModule.toString(), callback);
+            assertTrue(callback.waitTillDone());
+            assertEquals(dexModule.toString(), callback.mDexModulePath);
+            assertTrue(callback.waitTillDone());
+            assertTrue(callback.mMessage, callback.mSuccess);
+
+            // NOTE:
+            // This actually verifies internal behaviour which might change. It's not
+            // ideal but it's the best we can do since there's no other place we can currently
+            // write a better test.
+            for(String isa : getAppDexInstructionSets(info)) {
+                Files.exists(Paths.get(dexModuleDir.toString(), "oat", isa, "module.odex"));
+                Files.exists(Paths.get(dexModuleDir.toString(), "oat", isa, "module.vdex"));
+            }
+        } finally {
+            FileUtils.deleteContentsAndDir(dexModuleDir);
+        }
+    }
+
+    // If the module does not exist on disk we should get a failure.
+    public void testRegisterDexModuleNotExists() throws Exception {
+        ApplicationInfo info = getContext().getApplicationInfo();
+        String nonExistentApk = Paths.get(info.dataDir, "non-existent.apk").toString();
+        TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
+        getPm().registerDexModule(nonExistentApk, callback);
+        assertTrue(callback.waitTillDone());
+        assertEquals(nonExistentApk, callback.mDexModulePath);
+        assertTrue(callback.waitTillDone());
+        assertFalse("DexModule registration should fail", callback.mSuccess);
+    }
+
+    // Copied from com.android.server.pm.InstructionSets because we don't have access to it here.
+    private static String[] getAppDexInstructionSets(ApplicationInfo info) {
+        if (info.primaryCpuAbi != null) {
+            if (info.secondaryCpuAbi != null) {
+                return new String[] {
+                        VMRuntime.getInstructionSet(info.primaryCpuAbi),
+                        VMRuntime.getInstructionSet(info.secondaryCpuAbi) };
+            } else {
+                return new String[] {
+                        VMRuntime.getInstructionSet(info.primaryCpuAbi) };
+            }
+        }
+
+        return new String[] { VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]) };
+    }
+
     /*---------- Recommended install location tests ----*/
     /*
      * TODO's
diff --git a/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java b/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java
index 31cf515..c9db034 100644
--- a/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java
+++ b/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java
@@ -23,68 +23,29 @@
         TestSuite suite =
           new TestSuite(NewDatabasePerformanceTestSuite.class.getName());
 
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           Insert1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InsertIndexed1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           Select100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectStringComparison100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectIndex100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InnerJoin100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InnerJoinOneSide100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InnerJoinNoIndex100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectSubQIndex100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectIndexStringComparison100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectInteger100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectString100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectIntegerIndex100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectIndexString100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectStringStartsWith100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           DeleteIndexed1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           Delete1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           DeleteWhere1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           DeleteIndexWhere1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           UpdateIndexWhere1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           UpdateWhere1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InsertInteger10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InsertIntegerIndex10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InsertString10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InsertStringIndexed10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectStringStartsWith10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectStringIndexedStartsWith10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectInteger10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectIntegerIndexed10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectStringContains10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectStringIndexedContains10000.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.Insert100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.InsertIndexed100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.Select100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectStringComparison100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectIndex100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.InnerJoin100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.InnerJoinOneSide100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.InnerJoinNoIndex100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectSubQIndex100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectIndexStringComparison100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectInteger100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectString100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectIntegerIndex100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectIndexString100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectStringStartsWith100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.DeleteIndexed100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.Delete100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.DeleteWhere100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.DeleteIndexWhere100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.UpdateIndexWhere100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.UpdateWhere100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectStringContains100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectStringIndexedContains100.class);
 
         return suite;
     }
diff --git a/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java b/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
index adf88d2..f8d8e5e 100644
--- a/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
+++ b/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
@@ -19,6 +19,7 @@
 import android.content.ContentValues;
 import android.database.sqlite.SQLiteDatabase;
 import android.test.PerformanceTestCase;
+import android.util.Log;
 
 import junit.framework.TestCase;
 
@@ -31,17 +32,20 @@
  */
 
 public class NewDatabasePerformanceTests {
+    private static final String TAG = "NewDatabasePerformanceTests";
 
     // Edit this to change the test run times.  The original is 100.
-    final static int kMultiplier = 1;
+    private static final int SIZE_MULTIPLIER = 100;
 
     public static class PerformanceBase extends TestCase
     implements PerformanceTestCase {
         protected static final int CURRENT_DATABASE_VERSION = 42;
         protected SQLiteDatabase mDatabase;
         protected File mDatabaseFile;
+        private long mSetupFinishedTime;
 
         public void setUp() {
+            long setupStarted = System.currentTimeMillis();
             mDatabaseFile = new File("/sdcard", "perf_database_test.db");
             if (mDatabaseFile.exists()) {
                 mDatabaseFile.delete();
@@ -51,9 +55,14 @@
                             null);
             assertTrue(mDatabase != null);
             mDatabase.setVersion(CURRENT_DATABASE_VERSION);
+            mSetupFinishedTime = System.currentTimeMillis();
+            Log.i(TAG, "Setup for " + getClass().getSimpleName() + " took "
+                    + (mSetupFinishedTime - setupStarted) + " ms");
         }
 
         public void tearDown() {
+            long duration = System.currentTimeMillis() - mSetupFinishedTime;
+            Log.i(TAG, "Test " + getClass().getSimpleName() + " took " + duration + " ms");
             mDatabase.close();
             mDatabaseFile.delete();
         }
@@ -100,11 +109,11 @@
     }
 
     /**
-     * Test 1000 inserts.
+     * Test 100 inserts.
      */
 
-    public static class Insert1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class Insert100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
 
         private String[] statements = new String[SIZE];
 
@@ -132,11 +141,11 @@
     }
 
     /**
-     * Test 1000 inserts into an indexed table.
+     * Test 100 inserts into an indexed table.
      */
 
-    public static class InsertIndexed1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class InsertIndexed100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
 
         private String[] statements = new String[SIZE];
 
@@ -169,7 +178,8 @@
      */
 
     public static class Select100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
         private String[] where = new String[SIZE];
@@ -196,9 +206,11 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                .query("t1", COLUMNS, where[i], null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase
+                            .query("t1", COLUMNS, where[i], null, null, null, null);
+                }
             }
         }
     }
@@ -206,9 +218,9 @@
     /**
      * 100 SELECTs on a string comparison
      */
-
     public static class SelectStringComparison100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
         private String[] where = new String[SIZE];
@@ -233,9 +245,11 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                .query("t1", COLUMNS, where[i], null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase
+                            .query("t1", COLUMNS, where[i], null, null, null, null);
+                }
             }
         }
     }
@@ -243,9 +257,9 @@
     /**
      * 100 SELECTs with an index
      */
-
     public static class SelectIndex100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
         private String[] where = new String[SIZE];
@@ -273,9 +287,11 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                .query("t1", COLUMNS, where[i], null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase
+                            .query("t1", COLUMNS, where[i], null, null, null, null);
+                }
             }
         }
     }
@@ -283,9 +299,9 @@
     /**
      *  INNER JOIN without an index
      */
-
     public static class InnerJoin100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t1.a"};
 
         @Override
@@ -312,8 +328,10 @@
         }
 
         public void testRun() {
-            mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
-                    null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
+                        null, null, null, null);
+            }
         }
     }
 
@@ -322,7 +340,8 @@
      */
 
     public static class InnerJoinOneSide100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t1.a"};
 
         @Override
@@ -351,17 +370,19 @@
         }
 
         public void testRun() {
-            mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
-                    null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
+                        null, null, null, null);
+            }
         }
     }
 
     /**
      *  INNER JOIN without an index on one side
      */
-
     public static class InnerJoinNoIndex100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t1.a"};
 
         @Override
@@ -390,17 +411,19 @@
         }
 
         public void testRun() {
-            mDatabase.query("t1 INNER JOIN t2 ON t1.c = t2.c", COLUMNS, null,
-                    null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                mDatabase.query("t1 INNER JOIN t2 ON t1.c = t2.c", COLUMNS, null,
+                        null, null, null, null);
+            }
         }
     }
 
     /**
      *  100 SELECTs with subqueries. Subquery is using an index
      */
-
     public static class SelectSubQIndex100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t1.a"};
 
         private String[] where = new String[SIZE];
@@ -449,9 +472,9 @@
     /**
      *  100 SELECTs on string comparison with Index
      */
-
     public static class SelectIndexStringComparison100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
         private String[] where = new String[SIZE];
@@ -477,9 +500,11 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                .query("t1", COLUMNS, where[i], null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase
+                            .query("t1", COLUMNS, where[i], null, null, null, null);
+                }
             }
         }
     }
@@ -487,9 +512,9 @@
     /**
      *  100 SELECTs on integer
      */
-
     public static class SelectInteger100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"b"};
 
         @Override
@@ -509,8 +534,10 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+                }
             }
         }
     }
@@ -518,9 +545,9 @@
     /**
      *  100 SELECTs on String
      */
-
     public static class SelectString100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"c"};
 
         @Override
@@ -536,12 +563,13 @@
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
-
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+                }
             }
         }
     }
@@ -549,9 +577,9 @@
     /**
      *  100 SELECTs on integer with index
      */
-
     public static class SelectIntegerIndex100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"b"};
 
         @Override
@@ -572,8 +600,10 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+                }
             }
         }
     }
@@ -581,9 +611,9 @@
     /**
      *  100 SELECTs on String with index
      */
-
     public static class SelectIndexString100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"c"};
 
         @Override
@@ -600,22 +630,24 @@
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
-
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+                }
             }
         }
+
     }
 
     /**
      *  100 SELECTs on String with starts with
      */
-
     public static class SelectStringStartsWith100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"c"};
         private String[] where = new String[SIZE];
 
@@ -643,19 +675,20 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                .query("t1", COLUMNS, where[i], null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase
+                            .query("t1", COLUMNS, where[i], null, null, null, null);
+                }
             }
         }
     }
 
     /**
-     *  1000 Deletes on an indexed table
+     *  100 Deletes on an indexed table
      */
-
-    public static class DeleteIndexed1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class DeleteIndexed100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
 
         @Override
         public void setUp() {
@@ -682,11 +715,10 @@
     }
 
     /**
-     *  1000 Deletes
+     *  100 Deletes
      */
-
-    public static class Delete1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class Delete100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
 
         @Override
         public void setUp() {
@@ -712,11 +744,10 @@
     }
 
     /**
-     *  1000 DELETE's without an index with where clause
+     *  100 DELETE's without an index with where clause
      */
-
-    public static class DeleteWhere1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class DeleteWhere100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
         private String[] where = new String[SIZE];
 
         @Override
@@ -748,11 +779,10 @@
     }
 
     /**
-     *  1000 DELETE's with an index with where clause
+     * 100 DELETE's with an index with where clause
      */
-
-    public static class DeleteIndexWhere1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class DeleteIndexWhere100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
         private String[] where = new String[SIZE];
 
         @Override
@@ -785,11 +815,10 @@
     }
 
     /**
-     *  1000 update's with an index with where clause
+     * 100 update's with an index with where clause
      */
-
-    public static class UpdateIndexWhere1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class UpdateIndexWhere100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
         private String[] where = new String[SIZE];
         ContentValues[] mValues = new ContentValues[SIZE];
 
@@ -828,11 +857,10 @@
     }
 
     /**
-     *  1000 update's without an index with where clause
+     * 100 update's without an index with where clause
      */
-
-    public static class UpdateWhere1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class UpdateWhere100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
         private String[] where = new String[SIZE];
         ContentValues[] mValues = new ContentValues[SIZE];
 
@@ -869,284 +897,11 @@
     }
 
     /**
-     *  10000 inserts for an integer
+     * 100 selects for a String - contains 'e'
      */
-
-    public static class InsertInteger10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        ContentValues[] mValues = new ContentValues[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                ContentValues b = new ContentValues(1);
-                b.put("a", r);
-                mValues[i] = b;
-            }
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.insert("t1", null, mValues[i]);
-            }
-        }
-    }
-
-    /**
-     *  10000 inserts for an integer -indexed table
-     */
-
-    public static class InsertIntegerIndex10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        ContentValues[] mValues = new ContentValues[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER)");
-            mDatabase.execSQL("CREATE INDEX i1a ON t1(a)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                ContentValues b = new ContentValues(1);
-                b.put("a", r);
-                mValues[i] = b;
-            }
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.insert("t1", null, mValues[i]);
-            }
-        }
-    }
-
-    /**
-     *  10000 inserts for a String
-     */
-
-    public static class InsertString10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        ContentValues[] mValues = new ContentValues[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t1(a VARCHAR(100))");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                ContentValues b = new ContentValues(1);
-                b.put("a", numberName(r));
-                mValues[i] = b;
-            }
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.insert("t1", null, mValues[i]);
-            }
-        }
-    }
-
-    /**
-     *  10000 inserts for a String - indexed table
-     */
-
-    public static class InsertStringIndexed10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        ContentValues[] mValues = new ContentValues[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t1(a VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i1a ON t1(a)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                ContentValues b = new ContentValues(1);
-                b.put("a", numberName(r));
-                mValues[i] = b;
-            }
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.insert("t1", null, mValues[i]);
-            }
-        }
-    }
-
-
-    /**
-     *  10000 selects for a String -starts with
-     */
-
-    public static class SelectStringStartsWith10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        private static final String[] COLUMNS = {"t3.a"};
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t3(a VARCHAR(100))");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t3 VALUES('"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                where[i] = "a LIKE '" + numberName(r).substring(0, 1) + "*'";
-
-            }
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     *  10000 selects for a String - indexed table -starts with
-     */
-
-    public static class SelectStringIndexedStartsWith10000 extends
-    PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        private static final String[] COLUMNS = {"t3.a"};
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t3(a VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i3a ON t3(a)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t3 VALUES('"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                where[i] = "a LIKE '" + numberName(r).substring(0, 1) + "*'";
-
-            }
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     *  10000 selects for an integer -
-     */
-
-    public static class SelectInteger10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        private static final String[] COLUMNS = {"t4.a"};
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t4(a INTEGER)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t4 VALUES(" + r + ")");
-                int lower = i * 100;
-                int upper = (i + 10) * 100;
-                where[i] = "a >= " + lower + " AND a < " + upper;
-            }
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t4", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     *  10000 selects for an integer -indexed table
-     */
-
-    public static class SelectIntegerIndexed10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        private static final String[] COLUMNS = {"t4.a"};
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t4(a INTEGER)");
-            mDatabase.execSQL("CREATE INDEX i4a ON t4(a)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t4 VALUES(" + r + ")");
-
-                int lower = i * 100;
-                int upper = (i + 10) * 100;
-                where[i] = "a >= " + lower + " AND a < " + upper;
-            }
-
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t4", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-
-
-    /**
-     *  10000 selects for a String - contains 'e'
-     */
-
-    public static class SelectStringContains10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
+    public static class SelectStringContains100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t3.a"};
         private String[] where = new String[SIZE];
 
@@ -1171,19 +926,20 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
+                }
             }
         }
     }
 
     /**
-     *  10000 selects for a String - contains 'e'-indexed table
+     * 100 selects for a String - contains 'e'-indexed table
      */
-
-    public static class SelectStringIndexedContains10000 extends
-    PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
+    public static class SelectStringIndexedContains100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t3.a"};
         private String[] where = new String[SIZE];
 
@@ -1209,19 +965,21 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
+                }
             }
         }
     }
 
-    public static final String[] ONES =
+    static final String[] ONES =
         {"zero", "one", "two", "three", "four", "five", "six", "seven",
         "eight", "nine", "ten", "eleven", "twelve", "thirteen",
         "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
         "nineteen"};
 
-    public static final String[] TENS =
+    static final String[] TENS =
         {"", "ten", "twenty", "thirty", "forty", "fifty", "sixty",
         "seventy", "eighty", "ninety"};
 }
diff --git a/core/tests/coretests/src/android/database/process_newdb_perf_test_logs.py b/core/tests/coretests/src/android/database/process_newdb_perf_test_logs.py
new file mode 100644
index 0000000..1faeceb
--- /dev/null
+++ b/core/tests/coretests/src/android/database/process_newdb_perf_test_logs.py
@@ -0,0 +1,50 @@
+#!/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 re
+import sys
+
+def main():
+    args = sys.argv
+    if len(args) <= 1:
+        exit("Usage %s <log_file>" % args[0])
+    with open(args[1], 'r') as f:
+        all_lines = f.readlines()
+    timings = {}
+    running_sum = 0
+    for line in all_lines:
+        regex = r"NewDatabasePerformanceTests: Test (\w+) took (\d+) ms"
+        matches = re.search(regex, line)
+        if matches:
+            test_name = matches.group(1)
+            duration = int(matches.group(2))
+            if not test_name in timings:
+                timings[test_name] = []
+            timings[test_name].append(duration)
+            running_sum += duration
+        if ("TestRunner: run finished:" in line) and (running_sum > 0):
+            test_name = '*** TOTAL ALL TESTS (ms) ***'
+            if not test_name in timings:
+                timings[test_name] = []
+            timings[test_name].append(running_sum)
+            running_sum=0
+
+    for k in sorted(timings):
+        timings_ar = timings[k]
+        print "%s: %s avg: %s" % (k, timings_ar, sum(timings_ar) / float(len(timings_ar)) )
+
+if __name__ == '__main__':
+    main()
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
deleted file mode 100644
index d5f6321..0000000
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.LinkProperties.ProvisioningChange;
-import android.net.RouteInfo;
-import android.system.OsConstants;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.Suppress;
-import junit.framework.TestCase;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-
-
-public class LinkPropertiesTest extends TestCase {
-    private static InetAddress ADDRV4 = NetworkUtils.numericToInetAddress("75.208.6.1");
-    private static InetAddress ADDRV6 = NetworkUtils.numericToInetAddress(
-            "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
-    private static InetAddress DNS1 = NetworkUtils.numericToInetAddress("75.208.7.1");
-    private static InetAddress DNS2 = NetworkUtils.numericToInetAddress("69.78.7.1");
-    private static InetAddress DNS6 = NetworkUtils.numericToInetAddress("2001:4860:4860::8888");
-    private static InetAddress GATEWAY1 = NetworkUtils.numericToInetAddress("75.208.8.1");
-    private static InetAddress GATEWAY2 = NetworkUtils.numericToInetAddress("69.78.8.1");
-    private static InetAddress GATEWAY61 = NetworkUtils.numericToInetAddress("fe80::6:0000:613");
-    private static InetAddress GATEWAY62 = NetworkUtils.numericToInetAddress("fe80::6:2222");
-    private static String NAME = "qmi0";
-    private static int MTU = 1500;
-
-    private static LinkAddress LINKADDRV4 = new LinkAddress(ADDRV4, 32);
-    private static LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128);
-    private static LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64");
-
-    // TODO: replace all calls to NetworkUtils.numericToInetAddress with calls to this method.
-    private InetAddress Address(String addrString) {
-        return NetworkUtils.numericToInetAddress(addrString);
-    }
-
-    public void assertLinkPropertiesEqual(LinkProperties source, LinkProperties target) {
-        // Check implementation of equals(), element by element.
-        assertTrue(source.isIdenticalInterfaceName(target));
-        assertTrue(target.isIdenticalInterfaceName(source));
-
-        assertTrue(source.isIdenticalAddresses(target));
-        assertTrue(target.isIdenticalAddresses(source));
-
-        assertTrue(source.isIdenticalDnses(target));
-        assertTrue(target.isIdenticalDnses(source));
-
-        assertTrue(source.isIdenticalRoutes(target));
-        assertTrue(target.isIdenticalRoutes(source));
-
-        assertTrue(source.isIdenticalHttpProxy(target));
-        assertTrue(target.isIdenticalHttpProxy(source));
-
-        assertTrue(source.isIdenticalStackedLinks(target));
-        assertTrue(target.isIdenticalStackedLinks(source));
-
-        assertTrue(source.isIdenticalMtu(target));
-        assertTrue(target.isIdenticalMtu(source));
-
-        // Check result of equals().
-        assertTrue(source.equals(target));
-        assertTrue(target.equals(source));
-
-        // Check hashCode.
-        assertEquals(source.hashCode(), target.hashCode());
-    }
-
-    @SmallTest
-    public void testEqualsNull() {
-        LinkProperties source = new LinkProperties();
-        LinkProperties target = new LinkProperties();
-
-        assertFalse(source == target);
-        assertLinkPropertiesEqual(source, target);
-    }
-
-    @SmallTest
-    public void testEqualsSameOrder() {
-        try {
-            LinkProperties source = new LinkProperties();
-            source.setInterfaceName(NAME);
-            // set 2 link addresses
-            source.addLinkAddress(LINKADDRV4);
-            source.addLinkAddress(LINKADDRV6);
-            // set 2 dnses
-            source.addDnsServer(DNS1);
-            source.addDnsServer(DNS2);
-            // set 2 gateways
-            source.addRoute(new RouteInfo(GATEWAY1));
-            source.addRoute(new RouteInfo(GATEWAY2));
-            source.setMtu(MTU);
-
-            LinkProperties target = new LinkProperties();
-
-            // All fields are same
-            target.setInterfaceName(NAME);
-            target.addLinkAddress(LINKADDRV4);
-            target.addLinkAddress(LINKADDRV6);
-            target.addDnsServer(DNS1);
-            target.addDnsServer(DNS2);
-            target.addRoute(new RouteInfo(GATEWAY1));
-            target.addRoute(new RouteInfo(GATEWAY2));
-            target.setMtu(MTU);
-
-            assertLinkPropertiesEqual(source, target);
-
-            target.clear();
-            // change Interface Name
-            target.setInterfaceName("qmi1");
-            target.addLinkAddress(LINKADDRV4);
-            target.addLinkAddress(LINKADDRV6);
-            target.addDnsServer(DNS1);
-            target.addDnsServer(DNS2);
-            target.addRoute(new RouteInfo(GATEWAY1));
-            target.addRoute(new RouteInfo(GATEWAY2));
-            target.setMtu(MTU);
-            assertFalse(source.equals(target));
-
-            target.clear();
-            target.setInterfaceName(NAME);
-            // change link addresses
-            target.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress("75.208.6.2"), 32));
-            target.addLinkAddress(LINKADDRV6);
-            target.addDnsServer(DNS1);
-            target.addDnsServer(DNS2);
-            target.addRoute(new RouteInfo(GATEWAY1));
-            target.addRoute(new RouteInfo(GATEWAY2));
-            target.setMtu(MTU);
-            assertFalse(source.equals(target));
-
-            target.clear();
-            target.setInterfaceName(NAME);
-            target.addLinkAddress(LINKADDRV4);
-            target.addLinkAddress(LINKADDRV6);
-            // change dnses
-            target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2"));
-            target.addDnsServer(DNS2);
-            target.addRoute(new RouteInfo(GATEWAY1));
-            target.addRoute(new RouteInfo(GATEWAY2));
-            target.setMtu(MTU);
-            assertFalse(source.equals(target));
-
-            target.clear();
-            target.setInterfaceName(NAME);
-            target.addLinkAddress(LINKADDRV4);
-            target.addLinkAddress(LINKADDRV6);
-            target.addDnsServer(DNS1);
-            target.addDnsServer(DNS2);
-            // change gateway
-            target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2")));
-            target.addRoute(new RouteInfo(GATEWAY2));
-            target.setMtu(MTU);
-            assertFalse(source.equals(target));
-
-            target.clear();
-            target.setInterfaceName(NAME);
-            target.addLinkAddress(LINKADDRV4);
-            target.addLinkAddress(LINKADDRV6);
-            target.addDnsServer(DNS1);
-            target.addDnsServer(DNS2);
-            target.addRoute(new RouteInfo(GATEWAY1));
-            target.addRoute(new RouteInfo(GATEWAY2));
-            // change mtu
-            target.setMtu(1440);
-            assertFalse(source.equals(target));
-
-        } catch (Exception e) {
-            throw new RuntimeException(e.toString());
-            //fail();
-        }
-    }
-
-    @SmallTest
-    public void testEqualsDifferentOrder() {
-        try {
-            LinkProperties source = new LinkProperties();
-            source.setInterfaceName(NAME);
-            // set 2 link addresses
-            source.addLinkAddress(LINKADDRV4);
-            source.addLinkAddress(LINKADDRV6);
-            // set 2 dnses
-            source.addDnsServer(DNS1);
-            source.addDnsServer(DNS2);
-            // set 2 gateways
-            source.addRoute(new RouteInfo(GATEWAY1));
-            source.addRoute(new RouteInfo(GATEWAY2));
-            source.setMtu(MTU);
-
-            LinkProperties target = new LinkProperties();
-            // Exchange order
-            target.setInterfaceName(NAME);
-            target.addLinkAddress(LINKADDRV6);
-            target.addLinkAddress(LINKADDRV4);
-            target.addDnsServer(DNS2);
-            target.addDnsServer(DNS1);
-            target.addRoute(new RouteInfo(GATEWAY2));
-            target.addRoute(new RouteInfo(GATEWAY1));
-            target.setMtu(MTU);
-
-            assertLinkPropertiesEqual(source, target);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @SmallTest
-    public void testEqualsDuplicated() {
-        try {
-            LinkProperties source = new LinkProperties();
-            // set 3 link addresses, eg, [A, A, B]
-            source.addLinkAddress(LINKADDRV4);
-            source.addLinkAddress(LINKADDRV4);
-            source.addLinkAddress(LINKADDRV6);
-
-            LinkProperties target = new LinkProperties();
-            // set 3 link addresses, eg, [A, B, B]
-            target.addLinkAddress(LINKADDRV4);
-            target.addLinkAddress(LINKADDRV6);
-            target.addLinkAddress(LINKADDRV6);
-
-            assertLinkPropertiesEqual(source, target);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    private void assertAllRoutesHaveInterface(String iface, LinkProperties lp) {
-        for (RouteInfo r : lp.getRoutes()) {
-            assertEquals(iface, r.getInterface());
-        }
-    }
-
-    @SmallTest
-    public void testRouteInterfaces() {
-        LinkAddress prefix = new LinkAddress(
-            NetworkUtils.numericToInetAddress("2001:db8::"), 32);
-        InetAddress address = ADDRV6;
-
-        // Add a route with no interface to a LinkProperties with no interface. No errors.
-        LinkProperties lp = new LinkProperties();
-        RouteInfo r = new RouteInfo(prefix, address, null);
-        assertTrue(lp.addRoute(r));
-        assertEquals(1, lp.getRoutes().size());
-        assertAllRoutesHaveInterface(null, lp);
-
-        // Adding the same route twice has no effect.
-        assertFalse(lp.addRoute(r));
-        assertEquals(1, lp.getRoutes().size());
-
-        // Add a route with an interface. Expect an exception.
-        r = new RouteInfo(prefix, address, "wlan0");
-        try {
-          lp.addRoute(r);
-          fail("Adding wlan0 route to LP with no interface, expect exception");
-        } catch (IllegalArgumentException expected) {}
-
-        // Change the interface name. All the routes should change their interface name too.
-        lp.setInterfaceName("rmnet0");
-        assertAllRoutesHaveInterface("rmnet0", lp);
-
-        // Now add a route with the wrong interface. This causes an exception too.
-        try {
-          lp.addRoute(r);
-          fail("Adding wlan0 route to rmnet0 LP, expect exception");
-        } catch (IllegalArgumentException expected) {}
-
-        // If the interface name matches, the route is added.
-        r = new RouteInfo(prefix, null, "wlan0");
-        lp.setInterfaceName("wlan0");
-        lp.addRoute(r);
-        assertEquals(2, lp.getRoutes().size());
-        assertAllRoutesHaveInterface("wlan0", lp);
-
-        // Routes with null interfaces are converted to wlan0.
-        r = RouteInfo.makeHostRoute(ADDRV6, null);
-        lp.addRoute(r);
-        assertEquals(3, lp.getRoutes().size());
-        assertAllRoutesHaveInterface("wlan0", lp);
-
-        // Check comparisons work.
-        LinkProperties lp2 = new LinkProperties(lp);
-        assertAllRoutesHaveInterface("wlan0", lp);
-        assertEquals(0, lp.compareAllRoutes(lp2).added.size());
-        assertEquals(0, lp.compareAllRoutes(lp2).removed.size());
-
-        lp2.setInterfaceName("p2p0");
-        assertAllRoutesHaveInterface("p2p0", lp2);
-        assertEquals(3, lp.compareAllRoutes(lp2).added.size());
-        assertEquals(3, lp.compareAllRoutes(lp2).removed.size());
-    }
-
-    @SmallTest
-    public void testStackedInterfaces() {
-        LinkProperties rmnet0 = new LinkProperties();
-        rmnet0.setInterfaceName("rmnet0");
-        rmnet0.addLinkAddress(LINKADDRV6);
-
-        LinkProperties clat4 = new LinkProperties();
-        clat4.setInterfaceName("clat4");
-        clat4.addLinkAddress(LINKADDRV4);
-
-        assertEquals(0, rmnet0.getStackedLinks().size());
-        assertEquals(1, rmnet0.getAddresses().size());
-        assertEquals(1, rmnet0.getLinkAddresses().size());
-        assertEquals(1, rmnet0.getAllAddresses().size());
-        assertEquals(1, rmnet0.getAllLinkAddresses().size());
-
-        rmnet0.addStackedLink(clat4);
-        assertEquals(1, rmnet0.getStackedLinks().size());
-        assertEquals(1, rmnet0.getAddresses().size());
-        assertEquals(1, rmnet0.getLinkAddresses().size());
-        assertEquals(2, rmnet0.getAllAddresses().size());
-        assertEquals(2, rmnet0.getAllLinkAddresses().size());
-
-        rmnet0.addStackedLink(clat4);
-        assertEquals(1, rmnet0.getStackedLinks().size());
-        assertEquals(1, rmnet0.getAddresses().size());
-        assertEquals(1, rmnet0.getLinkAddresses().size());
-        assertEquals(2, rmnet0.getAllAddresses().size());
-        assertEquals(2, rmnet0.getAllLinkAddresses().size());
-
-        assertEquals(0, clat4.getStackedLinks().size());
-
-        // Modify an item in the returned collection to see what happens.
-        for (LinkProperties link : rmnet0.getStackedLinks()) {
-            if (link.getInterfaceName().equals("clat4")) {
-               link.setInterfaceName("newname");
-            }
-        }
-        for (LinkProperties link : rmnet0.getStackedLinks()) {
-            assertFalse("newname".equals(link.getInterfaceName()));
-        }
-
-        assertTrue(rmnet0.removeStackedLink("clat4"));
-        assertEquals(0, rmnet0.getStackedLinks().size());
-        assertEquals(1, rmnet0.getAddresses().size());
-        assertEquals(1, rmnet0.getLinkAddresses().size());
-        assertEquals(1, rmnet0.getAllAddresses().size());
-        assertEquals(1, rmnet0.getAllLinkAddresses().size());
-
-        assertFalse(rmnet0.removeStackedLink("clat4"));
-    }
-
-    private LinkAddress getFirstLinkAddress(LinkProperties lp) {
-        return lp.getLinkAddresses().iterator().next();
-    }
-
-    @SmallTest
-    public void testAddressMethods() {
-        LinkProperties lp = new LinkProperties();
-
-        // No addresses.
-        assertFalse(lp.hasIPv4Address());
-        assertFalse(lp.hasGlobalIPv6Address());
-
-        // Addresses on stacked links don't count.
-        LinkProperties stacked = new LinkProperties();
-        stacked.setInterfaceName("stacked");
-        lp.addStackedLink(stacked);
-        stacked.addLinkAddress(LINKADDRV4);
-        stacked.addLinkAddress(LINKADDRV6);
-        assertTrue(stacked.hasIPv4Address());
-        assertTrue(stacked.hasGlobalIPv6Address());
-        assertFalse(lp.hasIPv4Address());
-        assertFalse(lp.hasGlobalIPv6Address());
-        lp.removeStackedLink("stacked");
-        assertFalse(lp.hasIPv4Address());
-        assertFalse(lp.hasGlobalIPv6Address());
-
-        // Addresses on the base link.
-        // Check the return values of hasIPvXAddress and ensure the add/remove methods return true
-        // iff something changes.
-        assertEquals(0, lp.getLinkAddresses().size());
-        assertTrue(lp.addLinkAddress(LINKADDRV6));
-        assertEquals(1, lp.getLinkAddresses().size());
-        assertFalse(lp.hasIPv4Address());
-        assertTrue(lp.hasGlobalIPv6Address());
-
-        assertTrue(lp.removeLinkAddress(LINKADDRV6));
-        assertEquals(0, lp.getLinkAddresses().size());
-
-        assertTrue(lp.addLinkAddress(LINKADDRV6LINKLOCAL));
-        assertEquals(1, lp.getLinkAddresses().size());
-        assertFalse(lp.hasGlobalIPv6Address());
-
-        assertTrue(lp.addLinkAddress(LINKADDRV4));
-        assertEquals(2, lp.getLinkAddresses().size());
-        assertTrue(lp.hasIPv4Address());
-        assertFalse(lp.hasGlobalIPv6Address());
-
-        assertTrue(lp.addLinkAddress(LINKADDRV6));
-        assertEquals(3, lp.getLinkAddresses().size());
-        assertTrue(lp.hasIPv4Address());
-        assertTrue(lp.hasGlobalIPv6Address());
-
-        assertTrue(lp.removeLinkAddress(LINKADDRV6LINKLOCAL));
-        assertEquals(2, lp.getLinkAddresses().size());
-        assertTrue(lp.hasIPv4Address());
-        assertTrue(lp.hasGlobalIPv6Address());
-
-        // Adding an address twice has no effect.
-        // Removing an address that's not present has no effect.
-        assertFalse(lp.addLinkAddress(LINKADDRV4));
-        assertEquals(2, lp.getLinkAddresses().size());
-        assertTrue(lp.hasIPv4Address());
-        assertTrue(lp.removeLinkAddress(LINKADDRV4));
-        assertEquals(1, lp.getLinkAddresses().size());
-        assertFalse(lp.hasIPv4Address());
-        assertFalse(lp.removeLinkAddress(LINKADDRV4));
-        assertEquals(1, lp.getLinkAddresses().size());
-
-        // Adding an address that's already present but with different properties causes the
-        // existing address to be updated and returns true.
-        // Start with only LINKADDRV6.
-        assertEquals(1, lp.getLinkAddresses().size());
-        assertEquals(LINKADDRV6, getFirstLinkAddress(lp));
-
-        // Create a LinkAddress object for the same address, but with different flags.
-        LinkAddress deprecated = new LinkAddress(ADDRV6, 128,
-                OsConstants.IFA_F_DEPRECATED, OsConstants.RT_SCOPE_UNIVERSE);
-        assertTrue(deprecated.isSameAddressAs(LINKADDRV6));
-        assertFalse(deprecated.equals(LINKADDRV6));
-
-        // Check that adding it updates the existing address instead of adding a new one.
-        assertTrue(lp.addLinkAddress(deprecated));
-        assertEquals(1, lp.getLinkAddresses().size());
-        assertEquals(deprecated, getFirstLinkAddress(lp));
-        assertFalse(LINKADDRV6.equals(getFirstLinkAddress(lp)));
-
-        // Removing LINKADDRV6 removes deprecated, because removing addresses ignores properties.
-        assertTrue(lp.removeLinkAddress(LINKADDRV6));
-        assertEquals(0, lp.getLinkAddresses().size());
-    }
-
-    @SmallTest
-    public void testSetLinkAddresses() {
-        LinkProperties lp = new LinkProperties();
-        lp.addLinkAddress(LINKADDRV4);
-        lp.addLinkAddress(LINKADDRV6);
-
-        LinkProperties lp2 = new LinkProperties();
-        lp2.addLinkAddress(LINKADDRV6);
-
-        assertFalse(lp.equals(lp2));
-
-        lp2.setLinkAddresses(lp.getLinkAddresses());
-        assertTrue(lp.equals(lp));
-    }
-
-    @SmallTest
-    public void testIsProvisioned() {
-        LinkProperties lp4 = new LinkProperties();
-        assertFalse("v4only:empty", lp4.isProvisioned());
-        lp4.addLinkAddress(LINKADDRV4);
-        assertFalse("v4only:addr-only", lp4.isProvisioned());
-        lp4.addDnsServer(DNS1);
-        assertFalse("v4only:addr+dns", lp4.isProvisioned());
-        lp4.addRoute(new RouteInfo(GATEWAY1));
-        assertTrue("v4only:addr+dns+route", lp4.isProvisioned());
-        assertTrue("v4only:addr+dns+route", lp4.isIPv4Provisioned());
-        assertFalse("v4only:addr+dns+route", lp4.isIPv6Provisioned());
-
-        LinkProperties lp6 = new LinkProperties();
-        assertFalse("v6only:empty", lp6.isProvisioned());
-        lp6.addLinkAddress(LINKADDRV6LINKLOCAL);
-        assertFalse("v6only:fe80-only", lp6.isProvisioned());
-        lp6.addDnsServer(DNS6);
-        assertFalse("v6only:fe80+dns", lp6.isProvisioned());
-        lp6.addRoute(new RouteInfo(GATEWAY61));
-        assertFalse("v6only:fe80+dns+route", lp6.isProvisioned());
-        lp6.addLinkAddress(LINKADDRV6);
-        assertTrue("v6only:fe80+global+dns+route", lp6.isIPv6Provisioned());
-        assertTrue("v6only:fe80+global+dns+route", lp6.isProvisioned());
-        lp6.removeLinkAddress(LINKADDRV6LINKLOCAL);
-        assertFalse("v6only:global+dns+route", lp6.isIPv4Provisioned());
-        assertTrue("v6only:global+dns+route", lp6.isIPv6Provisioned());
-        assertTrue("v6only:global+dns+route", lp6.isProvisioned());
-
-        LinkProperties lp46 = new LinkProperties();
-        lp46.addLinkAddress(LINKADDRV4);
-        lp46.addLinkAddress(LINKADDRV6);
-        lp46.addDnsServer(DNS1);
-        lp46.addDnsServer(DNS6);
-        assertFalse("dualstack:missing-routes", lp46.isProvisioned());
-        lp46.addRoute(new RouteInfo(GATEWAY1));
-        assertTrue("dualstack:v4-provisioned", lp46.isIPv4Provisioned());
-        assertFalse("dualstack:v4-provisioned", lp46.isIPv6Provisioned());
-        assertTrue("dualstack:v4-provisioned", lp46.isProvisioned());
-        lp46.addRoute(new RouteInfo(GATEWAY61));
-        assertTrue("dualstack:both-provisioned", lp46.isIPv4Provisioned());
-        assertTrue("dualstack:both-provisioned", lp46.isIPv6Provisioned());
-        assertTrue("dualstack:both-provisioned", lp46.isProvisioned());
-
-        // A link with an IPv6 address and default route, but IPv4 DNS server.
-        LinkProperties mixed = new LinkProperties();
-        mixed.addLinkAddress(LINKADDRV6);
-        mixed.addDnsServer(DNS1);
-        mixed.addRoute(new RouteInfo(GATEWAY61));
-        assertFalse("mixed:addr6+route6+dns4", mixed.isIPv4Provisioned());
-        assertFalse("mixed:addr6+route6+dns4", mixed.isIPv6Provisioned());
-        assertFalse("mixed:addr6+route6+dns4", mixed.isProvisioned());
-    }
-
-    @SmallTest
-    public void testCompareProvisioning() {
-        LinkProperties v4lp = new LinkProperties();
-        v4lp.addLinkAddress(LINKADDRV4);
-        v4lp.addRoute(new RouteInfo(GATEWAY1));
-        v4lp.addDnsServer(DNS1);
-        assertTrue(v4lp.isProvisioned());
-
-        LinkProperties v4r = new LinkProperties(v4lp);
-        v4r.removeDnsServer(DNS1);
-        assertFalse(v4r.isProvisioned());
-
-        assertEquals(ProvisioningChange.STILL_NOT_PROVISIONED,
-                LinkProperties.compareProvisioning(v4r, v4r));
-        assertEquals(ProvisioningChange.LOST_PROVISIONING,
-                LinkProperties.compareProvisioning(v4lp, v4r));
-        assertEquals(ProvisioningChange.GAINED_PROVISIONING,
-                LinkProperties.compareProvisioning(v4r, v4lp));
-        assertEquals(ProvisioningChange.STILL_PROVISIONED,
-                LinkProperties.compareProvisioning(v4lp, v4lp));
-
-        // Check that losing IPv4 provisioning on a dualstack network is
-        // seen as a total loss of provisioning.
-        LinkProperties v6lp = new LinkProperties();
-        v6lp.addLinkAddress(LINKADDRV6);
-        v6lp.addRoute(new RouteInfo(GATEWAY61));
-        v6lp.addDnsServer(DNS6);
-        assertFalse(v6lp.isIPv4Provisioned());
-        assertTrue(v6lp.isIPv6Provisioned());
-        assertTrue(v6lp.isProvisioned());
-
-        LinkProperties v46lp = new LinkProperties(v6lp);
-        v46lp.addLinkAddress(LINKADDRV4);
-        v46lp.addRoute(new RouteInfo(GATEWAY1));
-        v46lp.addDnsServer(DNS1);
-        assertTrue(v46lp.isIPv4Provisioned());
-        assertTrue(v46lp.isIPv6Provisioned());
-        assertTrue(v46lp.isProvisioned());
-
-        assertEquals(ProvisioningChange.STILL_PROVISIONED,
-                LinkProperties.compareProvisioning(v4lp, v46lp));
-        assertEquals(ProvisioningChange.STILL_PROVISIONED,
-                LinkProperties.compareProvisioning(v6lp, v46lp));
-        assertEquals(ProvisioningChange.LOST_PROVISIONING,
-                LinkProperties.compareProvisioning(v46lp, v6lp));
-        assertEquals(ProvisioningChange.LOST_PROVISIONING,
-                LinkProperties.compareProvisioning(v46lp, v4lp));
-
-        // Check that losing and gaining a secondary router does not change
-        // the provisioning status.
-        LinkProperties v6lp2 = new LinkProperties(v6lp);
-        v6lp2.addRoute(new RouteInfo(GATEWAY62));
-        assertTrue(v6lp2.isProvisioned());
-
-        assertEquals(ProvisioningChange.STILL_PROVISIONED,
-                LinkProperties.compareProvisioning(v6lp2, v6lp));
-        assertEquals(ProvisioningChange.STILL_PROVISIONED,
-                LinkProperties.compareProvisioning(v6lp, v6lp2));
-    }
-
-    @SmallTest
-    @Suppress  // Failing.
-    public void testIsReachable() {
-        final LinkProperties v4lp = new LinkProperties();
-        assertFalse(v4lp.isReachable(DNS1));
-        assertFalse(v4lp.isReachable(DNS2));
-
-        // Add an on-link route, making the on-link DNS server reachable,
-        // but there is still no IPv4 address.
-        assertTrue(v4lp.addRoute(new RouteInfo(
-                new IpPrefix(NetworkUtils.numericToInetAddress("75.208.0.0"), 16))));
-        assertFalse(v4lp.isReachable(DNS1));
-        assertFalse(v4lp.isReachable(DNS2));
-
-        // Adding an IPv4 address (right now, any IPv4 address) means we use
-        // the routes to compute likely reachability.
-        assertTrue(v4lp.addLinkAddress(new LinkAddress(ADDRV4, 16)));
-        assertTrue(v4lp.isReachable(DNS1));
-        assertFalse(v4lp.isReachable(DNS2));
-
-        // Adding a default route makes the off-link DNS server reachable.
-        assertTrue(v4lp.addRoute(new RouteInfo(GATEWAY1)));
-        assertTrue(v4lp.isReachable(DNS1));
-        assertTrue(v4lp.isReachable(DNS2));
-
-        final LinkProperties v6lp = new LinkProperties();
-        final InetAddress kLinkLocalDns = NetworkUtils.numericToInetAddress("fe80::6:1");
-        final InetAddress kLinkLocalDnsWithScope = NetworkUtils.numericToInetAddress("fe80::6:2%43");
-        final InetAddress kOnLinkDns = NetworkUtils.numericToInetAddress("2001:db8:85a3::53");
-        assertFalse(v6lp.isReachable(kLinkLocalDns));
-        assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope));
-        assertFalse(v6lp.isReachable(kOnLinkDns));
-        assertFalse(v6lp.isReachable(DNS6));
-
-        // Add a link-local route, making the link-local DNS servers reachable. Because
-        // we assume the presence of an IPv6 link-local address, link-local DNS servers
-        // are considered reachable, but only those with a non-zero scope identifier.
-        assertTrue(v6lp.addRoute(new RouteInfo(
-                new IpPrefix(NetworkUtils.numericToInetAddress("fe80::"), 64))));
-        assertFalse(v6lp.isReachable(kLinkLocalDns));
-        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
-        assertFalse(v6lp.isReachable(kOnLinkDns));
-        assertFalse(v6lp.isReachable(DNS6));
-
-        // Add a link-local address--nothing changes.
-        assertTrue(v6lp.addLinkAddress(LINKADDRV6LINKLOCAL));
-        assertFalse(v6lp.isReachable(kLinkLocalDns));
-        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
-        assertFalse(v6lp.isReachable(kOnLinkDns));
-        assertFalse(v6lp.isReachable(DNS6));
-
-        // Add a global route on link, but no global address yet. DNS servers reachable
-        // via a route that doesn't require a gateway: give them the benefit of the
-        // doubt and hope the link-local source address suffices for communication.
-        assertTrue(v6lp.addRoute(new RouteInfo(
-                new IpPrefix(NetworkUtils.numericToInetAddress("2001:db8:85a3::"), 64))));
-        assertFalse(v6lp.isReachable(kLinkLocalDns));
-        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
-        assertTrue(v6lp.isReachable(kOnLinkDns));
-        assertFalse(v6lp.isReachable(DNS6));
-
-        // Add a global address; the on-link global address DNS server is (still)
-        // presumed reachable.
-        assertTrue(v6lp.addLinkAddress(new LinkAddress(ADDRV6, 64)));
-        assertFalse(v6lp.isReachable(kLinkLocalDns));
-        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
-        assertTrue(v6lp.isReachable(kOnLinkDns));
-        assertFalse(v6lp.isReachable(DNS6));
-
-        // Adding a default route makes the off-link DNS server reachable.
-        assertTrue(v6lp.addRoute(new RouteInfo(GATEWAY62)));
-        assertFalse(v6lp.isReachable(kLinkLocalDns));
-        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
-        assertTrue(v6lp.isReachable(kOnLinkDns));
-        assertTrue(v6lp.isReachable(DNS6));
-
-        // Check isReachable on stacked links. This requires that the source IP address be assigned
-        // on the interface returned by the route lookup.
-        LinkProperties stacked = new LinkProperties();
-
-        // Can't add a stacked link without an interface name.
-        stacked.setInterfaceName("v4-test0");
-        v6lp.addStackedLink(stacked);
-
-        InetAddress stackedAddress = Address("192.0.0.4");
-        LinkAddress stackedLinkAddress = new LinkAddress(stackedAddress, 32);
-        assertFalse(v6lp.isReachable(stackedAddress));
-        stacked.addLinkAddress(stackedLinkAddress);
-        assertFalse(v6lp.isReachable(stackedAddress));
-        stacked.addRoute(new RouteInfo(stackedLinkAddress));
-        assertTrue(stacked.isReachable(stackedAddress));
-        assertTrue(v6lp.isReachable(stackedAddress));
-
-        assertFalse(v6lp.isReachable(DNS1));
-        stacked.addRoute(new RouteInfo((IpPrefix) null, stackedAddress));
-        assertTrue(v6lp.isReachable(DNS1));
-    }
-}
diff --git a/core/tests/coretests/src/android/net/NetworkTest.java b/core/tests/coretests/src/android/net/NetworkTest.java
deleted file mode 100644
index 74b6d98..0000000
--- a/core/tests/coretests/src/android/net/NetworkTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import static android.test.MoreAsserts.assertNotEqual;
-
-import android.net.LocalServerSocket;
-import android.net.LocalSocket;
-import android.net.LocalSocketAddress;
-import android.net.Network;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.Inet6Address;
-import java.net.SocketException;
-
-import junit.framework.TestCase;
-
-public class NetworkTest extends TestCase {
-    final Network mNetwork = new Network(99);
-
-    @SmallTest
-    public void testBindSocketOfInvalidFdThrows() throws Exception {
-
-        final FileDescriptor fd = new FileDescriptor();
-        assertFalse(fd.valid());
-
-        try {
-            mNetwork.bindSocket(fd);
-            fail("SocketException not thrown");
-        } catch (SocketException expected) {}
-    }
-
-    @SmallTest
-    public void testBindSocketOfNonSocketFdThrows() throws Exception {
-        final File devNull = new File("/dev/null");
-        assertTrue(devNull.canRead());
-
-        final FileInputStream fis = new FileInputStream(devNull);
-        assertTrue(null != fis.getFD());
-        assertTrue(fis.getFD().valid());
-
-        try {
-            mNetwork.bindSocket(fis.getFD());
-            fail("SocketException not thrown");
-        } catch (SocketException expected) {}
-    }
-
-    @SmallTest
-    public void testBindSocketOfConnectedDatagramSocketThrows() throws Exception {
-        final DatagramSocket mDgramSocket = new DatagramSocket(0, (InetAddress) Inet6Address.ANY);
-        mDgramSocket.connect((InetAddress) Inet6Address.LOOPBACK, 53);
-        assertTrue(mDgramSocket.isConnected());
-
-        try {
-            mNetwork.bindSocket(mDgramSocket);
-            fail("SocketException not thrown");
-        } catch (SocketException expected) {}
-    }
-
-    @SmallTest
-    public void testBindSocketOfLocalSocketThrows() throws Exception {
-        final LocalSocket mLocalClient = new LocalSocket();
-        mLocalClient.bind(new LocalSocketAddress("testClient"));
-        assertTrue(mLocalClient.getFileDescriptor().valid());
-
-        try {
-            mNetwork.bindSocket(mLocalClient.getFileDescriptor());
-            fail("SocketException not thrown");
-        } catch (SocketException expected) {}
-
-        final LocalServerSocket mLocalServer = new LocalServerSocket("testServer");
-        mLocalClient.connect(mLocalServer.getLocalSocketAddress());
-        assertTrue(mLocalClient.isConnected());
-
-        try {
-            mNetwork.bindSocket(mLocalClient.getFileDescriptor());
-            fail("SocketException not thrown");
-        } catch (SocketException expected) {}
-    }
-
-    @SmallTest
-    public void testZeroIsObviousForDebugging() {
-        Network zero = new Network(0);
-        assertEquals(0, zero.hashCode());
-        assertEquals(0, zero.getNetworkHandle());
-        assertEquals("0", zero.toString());
-    }
-
-    @SmallTest
-    public void testGetNetworkHandle() {
-        Network one = new Network(1);
-        Network two = new Network(2);
-        Network three = new Network(3);
-
-        // None of the hashcodes are zero.
-        assertNotEqual(0, one.hashCode());
-        assertNotEqual(0, two.hashCode());
-        assertNotEqual(0, three.hashCode());
-
-        // All the hashcodes are distinct.
-        assertNotEqual(one.hashCode(), two.hashCode());
-        assertNotEqual(one.hashCode(), three.hashCode());
-        assertNotEqual(two.hashCode(), three.hashCode());
-
-        // None of the handles are zero.
-        assertNotEqual(0, one.getNetworkHandle());
-        assertNotEqual(0, two.getNetworkHandle());
-        assertNotEqual(0, three.getNetworkHandle());
-
-        // All the handles are distinct.
-        assertNotEqual(one.getNetworkHandle(), two.getNetworkHandle());
-        assertNotEqual(one.getNetworkHandle(), three.getNetworkHandle());
-        assertNotEqual(two.getNetworkHandle(), three.getNetworkHandle());
-
-        // The handles are not equal to the hashcodes.
-        assertNotEqual(one.hashCode(), one.getNetworkHandle());
-        assertNotEqual(two.hashCode(), two.getNetworkHandle());
-        assertNotEqual(three.hashCode(), three.getNetworkHandle());
-
-        // Adjust as necessary to test an implementation's specific constants.
-        // When running with runtest, "adb logcat -s TestRunner" can be useful.
-        assertEquals(4311403230L, one.getNetworkHandle());
-        assertEquals(8606370526L, two.getNetworkHandle());
-        assertEquals(12901337822L, three.getNetworkHandle());
-    }
-}
diff --git a/core/tests/coretests/src/android/net/StaticIpConfigurationTest.java b/core/tests/coretests/src/android/net/StaticIpConfigurationTest.java
deleted file mode 100644
index 59f780f..0000000
--- a/core/tests/coretests/src/android/net/StaticIpConfigurationTest.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.RouteInfo;
-import android.net.StaticIpConfiguration;
-import android.os.Parcel;
-
-import java.net.InetAddress;
-import java.util.HashSet;
-
-import junit.framework.TestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import static org.junit.Assert.*;
-
-
-public class StaticIpConfigurationTest extends TestCase {
-
-    private static final String ADDRSTR = "192.0.2.2/25";
-    private static final LinkAddress ADDR = new LinkAddress(ADDRSTR);
-    private static final InetAddress GATEWAY = IpAddress("192.0.2.1");
-    private static final InetAddress OFFLINKGATEWAY = IpAddress("192.0.2.129");
-    private static final InetAddress DNS1 = IpAddress("8.8.8.8");
-    private static final InetAddress DNS2 = IpAddress("8.8.4.4");
-    private static final InetAddress DNS3 = IpAddress("4.2.2.2");
-    private static final String IFACE = "eth0";
-
-    private static InetAddress IpAddress(String addr) {
-        return InetAddress.parseNumericAddress(addr);
-    }
-
-    private void checkEmpty(StaticIpConfiguration s) {
-        assertNull(s.ipAddress);
-        assertNull(s.gateway);
-        assertNull(s.domains);
-        assertEquals(0, s.dnsServers.size());
-    }
-
-    private boolean isEqual(StaticIpConfiguration s1, StaticIpConfiguration s2) {
-        return s1.equals(s2);
-    }
-
-    private void assertEquals(StaticIpConfiguration s1, StaticIpConfiguration s2) {
-        assertTrue(isEqual(s1, s2));
-    }
-
-    private void assertNotEquals(StaticIpConfiguration s1, StaticIpConfiguration s2) {
-        assertFalse(isEqual(s1, s2));
-    }
-
-    private StaticIpConfiguration makeTestObject() {
-        StaticIpConfiguration s = new StaticIpConfiguration();
-        s.ipAddress = ADDR;
-        s.gateway = GATEWAY;
-        s.dnsServers.add(DNS1);
-        s.dnsServers.add(DNS2);
-        s.dnsServers.add(DNS3);
-        s.domains = "google.com";
-        return s;
-    }
-
-    @SmallTest
-    public void testConstructor() {
-        StaticIpConfiguration s = new StaticIpConfiguration();
-        checkEmpty(s);
-    }
-
-    @SmallTest
-    public void testCopyAndClear() {
-        StaticIpConfiguration empty = new StaticIpConfiguration((StaticIpConfiguration) null);
-        checkEmpty(empty);
-
-        StaticIpConfiguration s1 = makeTestObject();
-        StaticIpConfiguration s2 = new StaticIpConfiguration(s1);
-        assertEquals(s1, s2);
-        s2.clear();
-        assertEquals(empty, s2);
-    }
-
-    @SmallTest
-    public void testHashCodeAndEquals() {
-        HashSet<Integer> hashCodes = new HashSet();
-        hashCodes.add(0);
-
-        StaticIpConfiguration s = new StaticIpConfiguration();
-        // Check that this hash code is nonzero and different from all the ones seen so far.
-        assertTrue(hashCodes.add(s.hashCode()));
-
-        s.ipAddress = ADDR;
-        assertTrue(hashCodes.add(s.hashCode()));
-
-        s.gateway = GATEWAY;
-        assertTrue(hashCodes.add(s.hashCode()));
-
-        s.dnsServers.add(DNS1);
-        assertTrue(hashCodes.add(s.hashCode()));
-
-        s.dnsServers.add(DNS2);
-        assertTrue(hashCodes.add(s.hashCode()));
-
-        s.dnsServers.add(DNS3);
-        assertTrue(hashCodes.add(s.hashCode()));
-
-        s.domains = "example.com";
-        assertTrue(hashCodes.add(s.hashCode()));
-
-        assertFalse(s.equals(null));
-        assertEquals(s, s);
-
-        StaticIpConfiguration s2 = new StaticIpConfiguration(s);
-        assertEquals(s, s2);
-
-        s.ipAddress = new LinkAddress(DNS1, 32);
-        assertNotEquals(s, s2);
-
-        s2 = new StaticIpConfiguration(s);
-        s.domains = "foo";
-        assertNotEquals(s, s2);
-
-        s2 = new StaticIpConfiguration(s);
-        s.gateway = DNS2;
-        assertNotEquals(s, s2);
-
-        s2 = new StaticIpConfiguration(s);
-        s.dnsServers.add(DNS3);
-        assertNotEquals(s, s2);
-    }
-
-    @SmallTest
-    public void testToLinkProperties() {
-        LinkProperties expected = new LinkProperties();
-        expected.setInterfaceName(IFACE);
-
-        StaticIpConfiguration s = new StaticIpConfiguration();
-        assertEquals(expected, s.toLinkProperties(IFACE));
-
-        final RouteInfo connectedRoute = new RouteInfo(new IpPrefix(ADDRSTR), null, IFACE);
-        s.ipAddress = ADDR;
-        expected.addLinkAddress(ADDR);
-        expected.addRoute(connectedRoute);
-        assertEquals(expected, s.toLinkProperties(IFACE));
-
-        s.gateway = GATEWAY;
-        RouteInfo defaultRoute = new RouteInfo(new IpPrefix("0.0.0.0/0"), GATEWAY, IFACE);
-        expected.addRoute(defaultRoute);
-        assertEquals(expected, s.toLinkProperties(IFACE));
-
-        s.gateway = OFFLINKGATEWAY;
-        expected.removeRoute(defaultRoute);
-        defaultRoute = new RouteInfo(new IpPrefix("0.0.0.0/0"), OFFLINKGATEWAY, IFACE);
-        expected.addRoute(defaultRoute);
-
-        RouteInfo gatewayRoute = new RouteInfo(new IpPrefix("192.0.2.129/32"), null, IFACE);
-        expected.addRoute(gatewayRoute);
-        assertEquals(expected, s.toLinkProperties(IFACE));
-
-        s.dnsServers.add(DNS1);
-        expected.addDnsServer(DNS1);
-        assertEquals(expected, s.toLinkProperties(IFACE));
-
-        s.dnsServers.add(DNS2);
-        s.dnsServers.add(DNS3);
-        expected.addDnsServer(DNS2);
-        expected.addDnsServer(DNS3);
-        assertEquals(expected, s.toLinkProperties(IFACE));
-
-        s.domains = "google.com";
-        expected.setDomains("google.com");
-        assertEquals(expected, s.toLinkProperties(IFACE));
-
-        s.gateway = null;
-        expected.removeRoute(defaultRoute);
-        expected.removeRoute(gatewayRoute);
-        assertEquals(expected, s.toLinkProperties(IFACE));
-
-        // Without knowing the IP address, we don't have a directly-connected route, so we can't
-        // tell if the gateway is off-link or not and we don't add a host route. This isn't a real
-        // configuration, but we should at least not crash.
-        s.gateway = OFFLINKGATEWAY;
-        s.ipAddress = null;
-        expected.removeLinkAddress(ADDR);
-        expected.removeRoute(connectedRoute);
-        expected.addRoute(defaultRoute);
-        assertEquals(expected, s.toLinkProperties(IFACE));
-    }
-
-    private StaticIpConfiguration passThroughParcel(StaticIpConfiguration s) {
-        Parcel p = Parcel.obtain();
-        StaticIpConfiguration s2 = null;
-        try {
-            s.writeToParcel(p, 0);
-            p.setDataPosition(0);
-            s2 = StaticIpConfiguration.CREATOR.createFromParcel(p);
-        } finally {
-            p.recycle();
-        }
-        assertNotNull(s2);
-        return s2;
-    }
-
-    @SmallTest
-    public void testParceling() {
-        StaticIpConfiguration s = makeTestObject();
-        StaticIpConfiguration s2 = passThroughParcel(s);
-        assertEquals(s, s2);
-    }
-}
-
diff --git a/core/tests/coretests/src/android/os/UserHandleTest.java b/core/tests/coretests/src/android/os/UserHandleTest.java
new file mode 100644
index 0000000..af559fd
--- /dev/null
+++ b/core/tests/coretests/src/android/os/UserHandleTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.os;
+
+import static android.os.UserHandle.ERR_GID;
+import static android.os.UserHandle.getAppId;
+import static android.os.UserHandle.getCacheAppGid;
+import static android.os.UserHandle.getSharedAppGid;
+import static android.os.UserHandle.getUid;
+import static android.os.UserHandle.getUserId;
+
+import static org.junit.Assert.assertEquals;
+
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class UserHandleTest {
+    // NOTE: keep logic in sync with system/core/libcutils/tests/multiuser_test.cpp
+
+    @Test
+    public void testMerge() throws Exception {
+        EXPECT_EQ(0, multiuser_get_uid(0, 0));
+        EXPECT_EQ(1000, multiuser_get_uid(0, 1000));
+        EXPECT_EQ(10000, multiuser_get_uid(0, 10000));
+        EXPECT_EQ(50000, multiuser_get_uid(0, 50000));
+        EXPECT_EQ(1000000, multiuser_get_uid(10, 0));
+        EXPECT_EQ(1001000, multiuser_get_uid(10, 1000));
+        EXPECT_EQ(1010000, multiuser_get_uid(10, 10000));
+        EXPECT_EQ(1050000, multiuser_get_uid(10, 50000));
+    }
+
+    @Test
+    public void testSplitUser() throws Exception {
+        EXPECT_EQ(0, multiuser_get_user_id(0));
+        EXPECT_EQ(0, multiuser_get_user_id(1000));
+        EXPECT_EQ(0, multiuser_get_user_id(10000));
+        EXPECT_EQ(0, multiuser_get_user_id(50000));
+        EXPECT_EQ(10, multiuser_get_user_id(1000000));
+        EXPECT_EQ(10, multiuser_get_user_id(1001000));
+        EXPECT_EQ(10, multiuser_get_user_id(1010000));
+        EXPECT_EQ(10, multiuser_get_user_id(1050000));
+    }
+
+    @Test
+    public void testSplitApp() throws Exception {
+        EXPECT_EQ(0, multiuser_get_app_id(0));
+        EXPECT_EQ(1000, multiuser_get_app_id(1000));
+        EXPECT_EQ(10000, multiuser_get_app_id(10000));
+        EXPECT_EQ(50000, multiuser_get_app_id(50000));
+        EXPECT_EQ(0, multiuser_get_app_id(1000000));
+        EXPECT_EQ(1000, multiuser_get_app_id(1001000));
+        EXPECT_EQ(10000, multiuser_get_app_id(1010000));
+        EXPECT_EQ(50000, multiuser_get_app_id(1050000));
+    }
+
+    @Test
+    public void testCache() throws Exception {
+        EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(0, 0));
+        EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(0, 1000));
+        EXPECT_EQ(20000, multiuser_get_cache_gid(0, 10000));
+        EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(0, 50000));
+        EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(10, 0));
+        EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(10, 1000));
+        EXPECT_EQ(1020000, multiuser_get_cache_gid(10, 10000));
+        EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(10, 50000));
+    }
+
+    @Test
+    public void testShared() throws Exception {
+        EXPECT_EQ(0, multiuser_get_shared_gid(0, 0));
+        EXPECT_EQ(1000, multiuser_get_shared_gid(0, 1000));
+        EXPECT_EQ(50000, multiuser_get_shared_gid(0, 10000));
+        EXPECT_EQ(ERR_GID, multiuser_get_shared_gid(0, 50000));
+        EXPECT_EQ(0, multiuser_get_shared_gid(10, 0));
+        EXPECT_EQ(1000, multiuser_get_shared_gid(10, 1000));
+        EXPECT_EQ(50000, multiuser_get_shared_gid(10, 10000));
+        EXPECT_EQ(ERR_GID, multiuser_get_shared_gid(10, 50000));
+    }
+
+    private static void EXPECT_EQ(int expected, int actual) {
+        assertEquals(expected, actual);
+    }
+
+    private static int multiuser_get_uid(int userId, int appId) {
+        return getUid(userId, appId);
+    }
+
+    private static int multiuser_get_cache_gid(int userId, int appId) {
+        return getCacheAppGid(userId, appId);
+    }
+
+    private static int multiuser_get_shared_gid(int userId, int appId) {
+        return getSharedAppGid(userId, appId);
+    }
+
+    private static int multiuser_get_user_id(int uid) {
+        return getUserId(uid);
+    }
+
+    private static int multiuser_get_app_id(int uid) {
+        return getAppId(uid);
+    }
+}
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index d875ed4..a979ac8 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -17,24 +17,25 @@
 package android.provider;
 
 import static com.google.android.collect.Sets.newHashSet;
+
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.empty;
 import static org.hamcrest.Matchers.is;
+
 import static java.lang.reflect.Modifier.isFinal;
 import static java.lang.reflect.Modifier.isPublic;
 import static java.lang.reflect.Modifier.isStatic;
 
-import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.lang.reflect.Field;
 import java.util.HashSet;
 import java.util.Set;
 
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 /** Tests that ensure appropriate settings are backed up. */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
@@ -102,6 +103,7 @@
                     Settings.Global.APP_IDLE_CONSTANTS,
                     Settings.Global.ASSISTED_GPS_ENABLED,
                     Settings.Global.AUDIO_SAFE_VOLUME_STATE,
+                    Settings.Global.BACKUP_REFACTORED_SERVICE_DISABLED,
                     Settings.Global.BATTERY_DISCHARGE_DURATION_THRESHOLD,
                     Settings.Global.BATTERY_DISCHARGE_THRESHOLD,
                     Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE,
@@ -193,6 +195,8 @@
                     Settings.Global.ENHANCED_4G_MODE_ENABLED,
                     Settings.Global.EPHEMERAL_COOKIE_MAX_SIZE_BYTES,
                     Settings.Global.ERROR_LOGCAT_PREFIX,
+                    Settings.Global.EUICC_PROVISIONED,
+                    Settings.Global.EUICC_FACTORY_RESET_TIMEOUT_MILLIS,
                     Settings.Global.FANCY_IME_ANIMATIONS,
                     Settings.Global.FORCE_ALLOW_ON_EXTERNAL,
                     Settings.Global.FSTRIM_MANDATORY_INTERVAL,
@@ -294,7 +298,6 @@
                     Settings.Global.RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS,
                     Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT,
                     Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT,
-                    Settings.Global.RETAIL_DEMO_MODE_CONSTANTS,
                     Settings.Global.SAFE_BOOT_DISALLOWED,
                     Settings.Global.SAMPLING_PROFILER_MS,
                     Settings.Global.SELINUX_STATUS,
@@ -408,10 +411,12 @@
                  Settings.Secure.AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED,
                  Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED,
                  Settings.Secure.AUTOMATIC_STORAGE_MANAGER_LAST_RUN,
+                 Settings.Secure.AUTOMATIC_STORAGE_MANAGER_TURNED_OFF_BY_POLICY,
                  Settings.Secure.BACKUP_AUTO_RESTORE,
                  Settings.Secure.BACKUP_ENABLED,
                  Settings.Secure.BACKUP_PROVISIONED,
                  Settings.Secure.BACKUP_TRANSPORT,
+                 Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED, // Candidate for backup?
                  Settings.Secure.CARRIER_APPS_HANDLED,
                  Settings.Secure.CMAS_ADDITIONAL_BROADCAST_PKG,
                  Settings.Secure.COMPLETED_CATEGORY_PREFIX,
@@ -424,6 +429,7 @@
                  Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS,
                  Settings.Secure.DISPLAY_DENSITY_FORCED,
                  Settings.Secure.DOZE_ALWAYS_ON,
+                 Settings.Secure.DOZE_PULSE_ON_LONG_PRESS,
                  Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION,
                  Settings.Secure.ENABLED_NOTIFICATION_ASSISTANT,
                  Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES,
@@ -444,17 +450,15 @@
                  Settings.Secure.MANAGED_PROFILE_CONTACT_REMOTE_SEARCH,
                  Settings.Secure.MULTI_PRESS_TIMEOUT,
                  Settings.Secure.NFC_PAYMENT_FOREGROUND,
+                 Settings.Secure.NIGHT_DISPLAY_ACTIVATED,
+                 Settings.Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
                  Settings.Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME,
                  Settings.Secure.PACKAGE_VERIFIER_STATE,
                  Settings.Secure.PACKAGE_VERIFIER_USER_CONSENT,
                  Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE,
                  Settings.Secure.PAYMENT_SERVICE_SEARCH_URI,
                  Settings.Secure.PRINT_SERVICE_SEARCH_URI,
-                 Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, // Candidate?
-                 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, // Candidate?
-                 Settings.Secure.SCREENSAVER_COMPONENTS,
                  Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT, // Candidate?
-                 Settings.Secure.SCREENSAVER_ENABLED, // Candidate?
                  Settings.Secure.SEARCH_GLOBAL_SEARCH_ACTIVITY,
                  Settings.Secure.SEARCH_MAX_RESULTS_PER_SOURCE,
                  Settings.Secure.SEARCH_MAX_RESULTS_TO_DISPLAY,
diff --git a/core/tests/coretests/src/android/text/BidiFormatterTest.java b/core/tests/coretests/src/android/text/BidiFormatterTest.java
new file mode 100644
index 0000000..14705ad
--- /dev/null
+++ b/core/tests/coretests/src/android/text/BidiFormatterTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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 android.text;
+
+import static org.junit.Assert.assertEquals;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class BidiFormatterTest {
+    private static final BidiFormatter LTR_FMT = BidiFormatter.getInstance(false /* LTR context */);
+    private static final BidiFormatter RTL_FMT = BidiFormatter.getInstance(true /* RTL context */);
+
+    private static final String EN = "abba";
+    private static final String HE = "\u05E0\u05E1";
+
+    private static final String LRM = "\u200E";
+    private static final String RLM = "\u200F";
+
+    @Test
+    public void testMarkAfter() {
+        assertEquals("uniform dir matches LTR context",
+                "", LTR_FMT.markAfter(EN, TextDirectionHeuristics.LTR));
+        assertEquals("uniform dir matches RTL context",
+                "", RTL_FMT.markAfter(HE, TextDirectionHeuristics.RTL));
+
+        assertEquals("exit dir opposite to LTR context",
+                LRM, LTR_FMT.markAfter(EN + HE, TextDirectionHeuristics.LTR));
+        assertEquals("exit dir opposite to RTL context",
+                RLM, RTL_FMT.markAfter(HE + EN, TextDirectionHeuristics.RTL));
+
+        assertEquals("overall dir (but not exit dir) opposite to LTR context",
+                LRM, LTR_FMT.markAfter(HE + EN, TextDirectionHeuristics.RTL));
+        assertEquals("overall dir (but not exit dir) opposite to RTL context",
+                RLM, RTL_FMT.markAfter(EN + HE, TextDirectionHeuristics.LTR));
+
+        assertEquals("exit dir neutral, overall dir matches LTR context",
+                "", LTR_FMT.markAfter(".", TextDirectionHeuristics.LTR));
+        assertEquals("exit dir neutral, overall dir matches RTL context",
+                "", RTL_FMT.markAfter(".", TextDirectionHeuristics.RTL));
+    }
+
+    @Test
+    public void testMarkBefore() {
+        assertEquals("uniform dir matches LTR context",
+                "", LTR_FMT.markBefore(EN, TextDirectionHeuristics.LTR));
+        assertEquals("uniform dir matches RTL context",
+                "", RTL_FMT.markBefore(HE, TextDirectionHeuristics.RTL));
+
+        assertEquals("entry dir opposite to LTR context",
+                LRM, LTR_FMT.markBefore(HE + EN, TextDirectionHeuristics.LTR));
+        assertEquals("entry dir opposite to RTL context",
+                RLM, RTL_FMT.markBefore(EN + HE, TextDirectionHeuristics.RTL));
+
+        assertEquals("overall dir (but not entry dir) opposite to LTR context",
+                LRM, LTR_FMT.markBefore(EN + HE, TextDirectionHeuristics.RTL));
+        assertEquals("overall dir (but not entry dir) opposite to RTL context",
+                RLM, RTL_FMT.markBefore(HE + EN, TextDirectionHeuristics.LTR));
+
+        assertEquals("exit dir neutral, overall dir matches LTR context",
+                "", LTR_FMT.markBefore(".", TextDirectionHeuristics.LTR));
+        assertEquals("exit dir neutral, overall dir matches RTL context",
+                "", RTL_FMT.markBefore(".", TextDirectionHeuristics.RTL));
+    }
+}
diff --git a/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java b/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
index bc9f44d..08e1b5b 100644
--- a/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
+++ b/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
@@ -67,7 +67,10 @@
     }
 
     private void update(int startLine, int endLine, int newLineCount) {
-        dl.setBlocksDataForTest(initialBlockEnds, initialBlockIndices, initialBlockEnds.length);
+        final int totalLines = initialBlockEnds[initialBlockEnds.length - 1]
+                + newLineCount - endLine + startLine;
+        dl.setBlocksDataForTest(
+                initialBlockEnds, initialBlockIndices, initialBlockEnds.length, totalLines);
         checkInvariants();
         dl.updateBlocks(startLine, endLine, newLineCount);
     }
diff --git a/core/tests/coretests/src/android/text/DynamicLayoutTest.java b/core/tests/coretests/src/android/text/DynamicLayoutTest.java
index da6dc7e..811bf2c 100644
--- a/core/tests/coretests/src/android/text/DynamicLayoutTest.java
+++ b/core/tests/coretests/src/android/text/DynamicLayoutTest.java
@@ -17,15 +17,14 @@
 package android.text;
 
 import static android.text.Layout.Alignment.ALIGN_NORMAL;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 
+import android.graphics.Canvas;
+import android.graphics.Paint;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.text.style.ReplacementSpan;
@@ -54,6 +53,16 @@
         assertNull(layout.getBlocksAlwaysNeedToBeRedrawn());
     }
 
+    private class MockReplacementSpan extends ReplacementSpan {
+        public int getSize(Paint paint, CharSequence text, int start, int end,
+                Paint.FontMetricsInt fm) {
+            return 10;
+        }
+
+        public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top,
+                int y, int bottom, Paint paint) { }
+    }
+
     @Test
     public void testGetBlocksAlwaysNeedToBeRedrawn_replacementSpan() {
         final SpannableStringBuilder builder = new SpannableStringBuilder();
@@ -66,17 +75,11 @@
         builder.append("hijk lmn\n");
         assertNull(layout.getBlocksAlwaysNeedToBeRedrawn());
 
-        ReplacementSpan mockReplacementSpan = mock(ReplacementSpan.class);
-        when(mockReplacementSpan.getSize(any(), any(), any(), any(), any()))
-            .thenReturn(10);
-        doNothing().when(mockReplacementSpan)
-            .draw(any(), any(), any(), any(), any(), any(), any(), any(), any());
-
-        builder.setSpan(mockReplacementSpan, 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+        builder.setSpan(new MockReplacementSpan(), 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
         assertNotNull(layout.getBlocksAlwaysNeedToBeRedrawn());
         assertTrue(layout.getBlocksAlwaysNeedToBeRedrawn().contains(0));
 
-        builder.setSpan(mockReplacementSpan, 9, 13, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+        builder.setSpan(new MockReplacementSpan(), 9, 13, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
         assertTrue(layout.getBlocksAlwaysNeedToBeRedrawn().contains(0));
         assertTrue(layout.getBlocksAlwaysNeedToBeRedrawn().contains(1));
 
diff --git a/core/tests/coretests/src/android/text/LayoutTest.java b/core/tests/coretests/src/android/text/LayoutTest.java
new file mode 100644
index 0000000..6d610bb
--- /dev/null
+++ b/core/tests/coretests/src/android/text/LayoutTest.java
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.text.Layout.Alignment;
+import android.text.style.StrikethroughSpan;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class LayoutTest {
+    private static final int LINE_COUNT = 5;
+    private static final int LINE_HEIGHT = 12;
+    private static final int LINE_DESCENT = 4;
+    private static final CharSequence LAYOUT_TEXT = "alwei\t;sdfs\ndf @";
+
+    private SpannableString mSpannedText;
+
+    private int mWidth;
+    private Layout.Alignment mAlign;
+    private float mSpacingMult;
+    private float mSpacingAdd;
+    private TextPaint mTextPaint;
+
+    @Before
+    public void setup() {
+        mTextPaint = new TextPaint();
+        mSpannedText = new SpannableString(LAYOUT_TEXT);
+        mSpannedText.setSpan(new StrikethroughSpan(), 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+        mWidth = 11;
+        mAlign = Alignment.ALIGN_CENTER;
+        mSpacingMult = 1;
+        mSpacingAdd = 2;
+    }
+
+    @Test
+    public void testConstructor() {
+        new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingMult, mSpacingAdd);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testConstructorNull() {
+        new MockLayout(null, null, -1, null, 0, 0);
+    }
+
+    @Test
+    public void testGetText() {
+        CharSequence text = "test case 1";
+        Layout layout = new MockLayout(text, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(text, layout.getText());
+
+        layout = new MockLayout(null, mTextPaint, mWidth, mAlign, mSpacingMult, mSpacingAdd);
+        assertNull(layout.getText());
+    }
+
+    @Test
+    public void testGetPaint() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+
+        assertSame(mTextPaint, layout.getPaint());
+
+        layout = new MockLayout(LAYOUT_TEXT, null, mWidth, mAlign, mSpacingMult, mSpacingAdd);
+        assertNull(layout.getPaint());
+    }
+
+    @Test
+    public void testGetWidth() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 10,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(10,  layout.getWidth());
+
+        layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 0, mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(0,  layout.getWidth());
+    }
+
+    @Test
+    public void testGetEllipsizedWidth() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 15,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(15, layout.getEllipsizedWidth());
+
+        layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 0, mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(0,  layout.getEllipsizedWidth());
+    }
+
+    @Test
+    public void testIncreaseWidthTo() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        int oldWidth = layout.getWidth();
+
+        layout.increaseWidthTo(oldWidth);
+        assertEquals(oldWidth, layout.getWidth());
+
+        try {
+            layout.increaseWidthTo(oldWidth - 1);
+            fail("should throw runtime exception attempted to reduce Layout width");
+        } catch (RuntimeException e) {
+        }
+
+        layout.increaseWidthTo(oldWidth + 1);
+        assertEquals(oldWidth + 1, layout.getWidth());
+    }
+
+    @Test
+    public void testGetHeight() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(60, layout.getHeight());
+    }
+
+    @Test
+    public void testGetAlignment() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertSame(mAlign, layout.getAlignment());
+
+        layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, null, mSpacingMult, mSpacingAdd);
+        assertNull(layout.getAlignment());
+    }
+
+    @Test
+    public void testGetSpacingMultiplier() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, -1, mSpacingAdd);
+        assertEquals(-1.0f, layout.getSpacingMultiplier(), 0.0f);
+
+        layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, 5, mSpacingAdd);
+        assertEquals(5.0f, layout.getSpacingMultiplier(), 0.0f);
+    }
+
+    @Test
+    public void testGetSpacingAdd() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingMult, -1);
+        assertEquals(-1.0f, layout.getSpacingAdd(), 0.0f);
+
+        layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingMult, 20);
+        assertEquals(20.0f, layout.getSpacingAdd(), 0.0f);
+    }
+
+    @Test
+    public void testGetLineBounds() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        Rect bounds = new Rect();
+
+        assertEquals(32, layout.getLineBounds(2, bounds));
+        assertEquals(0, bounds.left);
+        assertEquals(mWidth, bounds.right);
+        assertEquals(24, bounds.top);
+        assertEquals(36, bounds.bottom);
+    }
+
+    @Test
+    public void testGetLineForVertical() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(0, layout.getLineForVertical(-1));
+        assertEquals(0, layout.getLineForVertical(0));
+        assertEquals(0, layout.getLineForVertical(LINE_COUNT));
+        assertEquals(LINE_COUNT - 1, layout.getLineForVertical(1000));
+    }
+
+    @Test
+    public void testGetLineForOffset() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(0, layout.getLineForOffset(-1));
+        assertEquals(1, layout.getLineForOffset(1));
+        assertEquals(LINE_COUNT - 1, layout.getLineForOffset(LINE_COUNT - 1));
+        assertEquals(LINE_COUNT - 1, layout.getLineForOffset(1000));
+    }
+
+    @Test
+    public void testGetLineEnd() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(2, layout.getLineEnd(1));
+    }
+
+    @Test
+    public void testGetLineVisibleEnd() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+
+        assertEquals(2, layout.getLineVisibleEnd(1));
+        assertEquals(LINE_COUNT, layout.getLineVisibleEnd(LINE_COUNT - 1));
+        assertEquals(LAYOUT_TEXT.length(), layout.getLineVisibleEnd(LAYOUT_TEXT.length() - 1));
+        try {
+            layout.getLineVisibleEnd(LAYOUT_TEXT.length());
+            fail("should throw .StringIndexOutOfBoundsException here");
+        } catch (StringIndexOutOfBoundsException e) {
+        }
+    }
+
+    @Test
+    public void testGetLineBottom() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(LINE_HEIGHT, layout.getLineBottom(0));
+    }
+
+    @Test
+    public void testGetLineBaseline() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(8, layout.getLineBaseline(0));
+    }
+
+    @Test
+    public void testGetLineAscent() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(-8, layout.getLineAscent(0));
+    }
+
+    @Test
+    public void testGetParagraphAlignment() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertSame(mAlign, layout.getParagraphAlignment(0));
+
+        layout = new MockLayout(mSpannedText, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertSame(mAlign, layout.getParagraphAlignment(0));
+        assertSame(mAlign, layout.getParagraphAlignment(1));
+    }
+
+    @Test
+    public void testGetParagraphLeft() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(0, layout.getParagraphLeft(0));
+    }
+
+    @Test
+    public void testGetParagraphRight() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(mWidth, layout.getParagraphRight(0));
+    }
+
+    @Test
+    public void testIsSpanned() {
+        MockLayout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        // default is not spanned text
+        assertFalse(layout.mockIsSpanned());
+
+        // try to create a spanned text
+        layout = new MockLayout(mSpannedText, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertTrue(layout.mockIsSpanned());
+    }
+
+    private static final class MockLayout extends Layout {
+        MockLayout(CharSequence text, TextPaint paint, int width,
+                Alignment align, float spacingmult, float spacingadd) {
+            super(text, paint, width, align, spacingmult, spacingadd);
+        }
+
+        protected boolean mockIsSpanned() {
+            return super.isSpanned();
+        }
+
+        @Override
+        public int getBottomPadding() {
+            return 0;
+        }
+
+        @Override
+        public int getEllipsisCount(int line) {
+            return 0;
+        }
+
+        @Override
+        public int getEllipsisStart(int line) {
+            return 0;
+        }
+
+        @Override
+        public boolean getLineContainsTab(int line) {
+            return false;
+        }
+
+        @Override
+        public int getLineCount() {
+            return LINE_COUNT;
+        }
+
+        @Override
+        public int getLineDescent(int line) {
+            return LINE_DESCENT;
+        }
+
+        @Override
+        public Directions getLineDirections(int line) {
+            return Layout.DIRS_ALL_LEFT_TO_RIGHT;
+        }
+
+        @Override
+        public int getLineStart(int line) {
+            if (line < 0) {
+                return 0;
+            }
+            return line;
+        }
+
+        @Override
+        public int getLineTop(int line) {
+            if (line < 0) {
+                return 0;
+            }
+            return LINE_HEIGHT * (line);
+        }
+
+        @Override
+        public int getParagraphDirection(int line) {
+            return 0;
+        }
+
+        @Override
+        public int getTopPadding() {
+            return 0;
+        }
+    }
+
+    @Test
+    public void testGetLineWidth() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        for (int i = 0; i < LINE_COUNT; i++) {
+            int start = layout.getLineStart(i);
+            int end = layout.getLineEnd(i);
+            String text = LAYOUT_TEXT.toString().substring(start, end);
+            assertEquals(mTextPaint.measureText(text), layout.getLineWidth(i), 1.0f);
+        }
+    }
+
+    @Test
+    public void testGetCursorPath() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        Path path = new Path();
+        final float epsilon = 1.0f;
+        for (int i = 0; i < LINE_COUNT; i++) {
+            layout.getCursorPath(i, path, LAYOUT_TEXT);
+            RectF bounds = new RectF();
+            path.computeBounds(bounds, false);
+            assertTrue(bounds.top >= layout.getLineTop(i) - epsilon);
+            assertTrue(bounds.bottom <= layout.getLineBottom(i) + epsilon);
+        }
+    }
+
+    @Test
+    public void testDraw() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        final int width = 256;
+        final int height = 256;
+        MockCanvas c = new MockCanvas(width, height);
+        layout.draw(c);
+        List<MockCanvas.DrawCommand> drawCommands = c.getDrawCommands();
+        assertEquals(LINE_COUNT, drawCommands.size());
+        for (int i = 0; i < LINE_COUNT; i++) {
+            MockCanvas.DrawCommand drawCommand = drawCommands.get(i);
+            int start = layout.getLineStart(i);
+            int end = layout.getLineEnd(i);
+            assertEquals(LAYOUT_TEXT.toString().substring(start, end), drawCommand.text);
+            float expected_y = (i + 1) * LINE_HEIGHT - LINE_DESCENT;
+            assertEquals(expected_y, drawCommand.y, 0.0f);
+        }
+    }
+
+    private final class MockCanvas extends Canvas {
+
+        class DrawCommand {
+            public final String text;
+            public final float x;
+            public final float y;
+
+            DrawCommand(String text, float x, float y) {
+                this.text = text;
+                this.x = x;
+                this.y = y;
+            }
+        }
+
+        List<DrawCommand> mDrawCommands;
+
+        MockCanvas(int width, int height) {
+            super();
+            mDrawCommands = new ArrayList<>();
+            Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+            setBitmap(bitmap);
+        }
+
+        // Drawing text with either drawText or drawTextRun is valid; we don't care which.
+        // We also don't care which of the string representations is used.
+
+        @Override
+        public void drawText(String text, int start, int end, float x, float y, Paint p) {
+            mDrawCommands.add(new DrawCommand(text.substring(start, end), x, y));
+        }
+
+        @Override
+        public void drawText(CharSequence text, int start, int end, float x, float y, Paint p) {
+            drawText(text.toString(), start, end, x, y, p);
+        }
+
+        @Override
+        public void drawText(char[] text, int index, int count, float x, float y, Paint p) {
+            mDrawCommands.add(new DrawCommand(new String(text, index, count), x, y));
+        }
+
+        @Override
+        public void drawTextRun(CharSequence text, int start, int end, int contextStart,
+                int contextEnd, float x, float y, boolean isRtl, Paint paint) {
+            drawText(text, start, end, x, y, paint);
+        }
+
+        @Override
+        public void drawTextRun(char[] text, int index, int count, int contextIndex,
+                int contextCount, float x, float y, boolean isRtl, Paint paint) {
+            drawText(text, index, count, x, y, paint);
+        }
+
+        List<DrawCommand> getDrawCommands() {
+            return mDrawCommands;
+        }
+    }
+}
+
diff --git a/core/tests/coretests/src/android/text/SpannableStringBuilderTest.java b/core/tests/coretests/src/android/text/SpannableStringBuilderTest.java
index 1f1a689..04a486e 100644
--- a/core/tests/coretests/src/android/text/SpannableStringBuilderTest.java
+++ b/core/tests/coretests/src/android/text/SpannableStringBuilderTest.java
@@ -16,9 +16,46 @@
 
 package android.text;
 
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.text.style.BulletSpan;
+import android.text.style.QuoteSpan;
+import android.text.style.SubscriptSpan;
+import android.text.style.UnderlineSpan;
+
+import org.junit.Test;
+
 public class SpannableStringBuilderTest extends SpannableTest {
 
     protected Spannable newSpannableWithText(String text) {
         return new SpannableStringBuilder(text);
     }
+
+    @Test
+    public void testGetSpans_sortsByPriorityEvenWhenSortParamIsFalse() {
+        String text = "p_in_s";
+        SpannableStringBuilder builder = new SpannableStringBuilder(text);
+        Object first = new SubscriptSpan();
+        Object second = new UnderlineSpan();
+        Object third = new BulletSpan();
+        Object fourth = new QuoteSpan();
+
+        builder.setSpan(first, 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        builder.setSpan(second, 1, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        builder.setSpan(third, 2, text.length(), 1 << Spanned.SPAN_PRIORITY_SHIFT);
+        builder.setSpan(fourth, 0, text.length(), 2 << Spanned.SPAN_PRIORITY_SHIFT);
+
+        Object[] spans = builder.getSpans(0, text.length(), Object.class, false);
+
+        assertNotNull(spans);
+        assertEquals(4, spans.length);
+        // priority spans are first
+        assertEquals(fourth, spans[0]);
+        assertEquals(third, spans[1]);
+        // other spans should be there
+        assertEquals(second, spans[2]);
+        assertEquals(first, spans[3]);
+    }
 }
diff --git a/core/tests/coretests/src/android/text/StaticLayoutLineBreakingTest.java b/core/tests/coretests/src/android/text/StaticLayoutLineBreakingTest.java
new file mode 100644
index 0000000..2ee855e
--- /dev/null
+++ b/core/tests/coretests/src/android/text/StaticLayoutLineBreakingTest.java
@@ -0,0 +1,461 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import static org.junit.Assert.assertEquals;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.text.Layout.Alignment;
+import android.text.style.MetricAffectingSpan;
+import android.util.Log;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class StaticLayoutLineBreakingTest {
+    // Span test are currently not supported because text measurement uses the MeasuredText
+    // internal mWorkPaint instead of the provided MockTestPaint.
+    private static final boolean SPAN_TESTS_SUPPORTED = false;
+    private static final boolean DEBUG = false;
+
+    private static final float SPACE_MULTI = 1.0f;
+    private static final float SPACE_ADD = 0.0f;
+    private static final int WIDTH = 100;
+    private static final Alignment ALIGN = Alignment.ALIGN_LEFT;
+
+    private static final char SURR_FIRST = '\uD800';
+    private static final char SURR_SECOND = '\uDF31';
+
+    private static final int[] NO_BREAK = new int[] {};
+
+    private static final TextPaint sTextPaint = new MockTextPaint();
+
+    private static class MockTextPaint extends TextPaint {
+
+        @Override
+        public float getTextRunAdvances(char[] chars, int index, int count,
+                int contextIndex, int contextCount, boolean isRtl, float[] advances,
+                int advancesIndex) {
+
+            // Conditions copy pasted from Paint
+            if (chars == null) {
+                throw new IllegalArgumentException("text cannot be null");
+            }
+
+            if ((index | count | contextIndex | contextCount | advancesIndex
+                    | (index - contextIndex) | (contextCount - count)
+                    | ((contextIndex + contextCount) - (index + count))
+                    | (chars.length - (contextIndex + contextCount))
+                    | (advances == null ? 0 :
+                        (advances.length - (advancesIndex + count)))) < 0) {
+                throw new IndexOutOfBoundsException();
+            }
+
+            float res = 0.0f;
+
+            if (advances != null) {
+                for (int i = 0; i < count; i++) {
+                    float width = getCharWidth(chars[index + i]);
+                    advances[advancesIndex + i] = width;
+                    res += width;
+                }
+            }
+
+            return res;
+        }
+    }
+
+    private static float getCharWidth(char c) {
+        switch (Character.toUpperCase(c)) {
+            // Roman figures
+            case 'I': return 1.0f;
+            case 'V': return 5.0f;
+            case 'X': return 10.0f;
+            case 'L': return 50.0f;
+            case 'C': return 100.0f; // equals to WIDTH
+            case ' ': return 10.0f;
+            case '_': return 0.0f; // 0-width character
+            case SURR_FIRST: return 7.0f;
+            case SURR_SECOND: return 3.0f; // Sum of SURR_FIRST-SURR_SECOND is 10
+            default: return 10.0f;
+        }
+    }
+
+    private static StaticLayout getStaticLayout(CharSequence source, int width) {
+        return new StaticLayout(source, sTextPaint, width, ALIGN, SPACE_MULTI, SPACE_ADD, false);
+    }
+
+    private static int[] getBreaks(CharSequence source) {
+        return getBreaks(source, WIDTH);
+    }
+
+    private static int[] getBreaks(CharSequence source, int width) {
+        StaticLayout staticLayout = getStaticLayout(source, width);
+
+        int[] breaks = new int[staticLayout.getLineCount() - 1];
+        for (int line = 0; line < breaks.length; line++) {
+            breaks[line] = staticLayout.getLineEnd(line);
+        }
+        return breaks;
+    }
+
+    private static void debugLayout(CharSequence source, StaticLayout staticLayout) {
+        if (DEBUG) {
+            int count = staticLayout.getLineCount();
+            Log.i("SLLBTest", "\"" + source.toString() + "\": "
+                    + count + " lines");
+            for (int line = 0; line < count; line++) {
+                int lineStart = staticLayout.getLineStart(line);
+                int lineEnd = staticLayout.getLineEnd(line);
+                Log.i("SLLBTest", "Line " + line + " [" + lineStart + ".."
+                        + lineEnd + "]\t" + source.subSequence(lineStart, lineEnd));
+            }
+        }
+    }
+
+    private static void layout(CharSequence source, int[] breaks) {
+        layout(source, breaks, WIDTH);
+    }
+
+    private static void layout(CharSequence source, int[] breaks, int width) {
+        StaticLayout staticLayout = getStaticLayout(source, width);
+
+        debugLayout(source, staticLayout);
+
+        int lineCount = breaks.length + 1;
+        assertEquals("Number of lines", lineCount, staticLayout.getLineCount());
+
+        for (int line = 0; line < lineCount; line++) {
+            int lineStart = staticLayout.getLineStart(line);
+            int lineEnd = staticLayout.getLineEnd(line);
+
+            if (line == 0) {
+                assertEquals("Line start for first line", 0, lineStart);
+            } else {
+                assertEquals("Line start for line " + line, breaks[line - 1], lineStart);
+            }
+
+            if (line == lineCount - 1) {
+                assertEquals("Line end for last line", source.length(), lineEnd);
+            } else {
+                assertEquals("Line end for line " + line, breaks[line], lineEnd);
+            }
+        }
+    }
+
+    private static void layoutMaxLines(CharSequence source, int[] breaks, int maxLines) {
+        StaticLayout staticLayout = new StaticLayout(source, 0, source.length(), sTextPaint, WIDTH,
+                ALIGN, TextDirectionHeuristics.LTR, SPACE_MULTI, SPACE_ADD, false /* includePad */,
+                null, WIDTH, maxLines);
+
+        debugLayout(source, staticLayout);
+
+        final int lineCount = staticLayout.getLineCount();
+
+        for (int line = 0; line < lineCount; line++) {
+            int lineStart = staticLayout.getLineStart(line);
+            int lineEnd = staticLayout.getLineEnd(line);
+
+            if (line == 0) {
+                assertEquals("Line start for first line", 0, lineStart);
+            } else {
+                assertEquals("Line start for line " + line, breaks[line - 1], lineStart);
+            }
+
+            if (line == lineCount - 1 && line != breaks.length - 1) {
+                assertEquals("Line end for last line", source.length(), lineEnd);
+            } else {
+                assertEquals("Line end for line " + line, breaks[line], lineEnd);
+            }
+        }
+    }
+
+    private static final int MAX_SPAN_COUNT = 10;
+    private static final int[] sSpanStarts = new int[MAX_SPAN_COUNT];
+    private static final int[] sSpanEnds = new int[MAX_SPAN_COUNT];
+
+    private static MetricAffectingSpan getMetricAffectingSpan() {
+        return new MetricAffectingSpan() {
+            @Override
+            public void updateDrawState(TextPaint tp) { /* empty */ }
+
+            @Override
+            public void updateMeasureState(TextPaint p) { /* empty */ }
+        };
+    }
+
+    /**
+     * Replaces the "<...>" blocks by spans, assuming non overlapping, correctly defined spans
+     * @param text
+     * @return A CharSequence with '<' '>' replaced by MetricAffectingSpan
+     */
+    private static CharSequence spanify(String text) {
+        int startIndex = text.indexOf('<');
+        if (startIndex < 0) return text;
+
+        int spanCount = 0;
+        do {
+            int endIndex = text.indexOf('>');
+            if (endIndex < 0) throw new IllegalArgumentException("Unbalanced span markers");
+
+            text = text.substring(0, startIndex) + text.substring(startIndex + 1, endIndex)
+                    + text.substring(endIndex + 1);
+
+            sSpanStarts[spanCount] = startIndex;
+            sSpanEnds[spanCount] = endIndex - 2;
+            spanCount++;
+
+            startIndex = text.indexOf('<');
+        } while (startIndex >= 0);
+
+        SpannableStringBuilder result = new SpannableStringBuilder(text);
+        for (int i = 0; i < spanCount; i++) {
+            result.setSpan(getMetricAffectingSpan(), sSpanStarts[i], sSpanEnds[i],
+                    Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+        }
+        return result;
+    }
+
+    @Test
+    public void testNoLineBreak() {
+        // Width lower than WIDTH
+        layout("", NO_BREAK);
+        layout("I", NO_BREAK);
+        layout("V", NO_BREAK);
+        layout("X", NO_BREAK);
+        layout("L", NO_BREAK);
+        layout("I VILI", NO_BREAK);
+        layout("XXXX", NO_BREAK);
+        layout("LXXXX", NO_BREAK);
+
+        // Width equal to WIDTH
+        layout("C", NO_BREAK);
+        layout("LL", NO_BREAK);
+        layout("L XXXX", NO_BREAK);
+        layout("XXXXXXXXXX", NO_BREAK);
+        layout("XXX XXXXXX", NO_BREAK);
+        layout("XXX XXXX X", NO_BREAK);
+        layout("XXX XXXXX ", NO_BREAK);
+        layout(" XXXXXXXX ", NO_BREAK);
+        layout("  XX  XXX ", NO_BREAK);
+        //      0123456789
+
+        // Width greater than WIDTH, but no break
+        layout("  XX  XXX  ", NO_BREAK);
+        layout("XX XXX XXX ", NO_BREAK);
+        layout("XX XXX XXX     ", NO_BREAK);
+        layout("XXXXXXXXXX     ", NO_BREAK);
+        //      01234567890
+    }
+
+    @Test
+    public void testOneLineBreak() {
+        //      01234567890
+        layout("XX XXX XXXX", new int[] {7});
+        layout("XX XXXX XXX", new int[] {8});
+        layout("XX XXXXX XX", new int[] {9});
+        layout("XX XXXXXX X", new int[] {10});
+        //      01234567890
+        layout("XXXXXXXXXXX", new int[] {10});
+        layout("XXXXXXXXX X", new int[] {10});
+        layout("XXXXXXXX XX", new int[] {9});
+        layout("XXXXXXX XXX", new int[] {8});
+        layout("XXXXXX XXXX", new int[] {7});
+        //      01234567890
+        layout("LL LL", new int[] {3});
+        layout("LLLL", new int[] {2});
+        layout("C C", new int[] {2});
+        layout("CC", new int[] {1});
+    }
+
+    @Test
+    public void testSpaceAtBreak() {
+        //      0123456789012
+        layout("XXXX XXXXX X", new int[] {11});
+        layout("XXXXXXXXXX X", new int[] {11});
+        layout("XXXXXXXXXV X", new int[] {11});
+        layout("C X", new int[] {2});
+    }
+
+    @Test
+    public void testMultipleSpacesAtBreak() {
+        //      0123456789012
+        layout("LXX XXXX", new int[] {4});
+        layout("LXX  XXXX", new int[] {5});
+        layout("LXX   XXXX", new int[] {6});
+        layout("LXX    XXXX", new int[] {7});
+        layout("LXX     XXXX", new int[] {8});
+    }
+
+    @Test
+    public void testZeroWidthCharacters() {
+        //      0123456789012345678901234
+        layout("X_X_X_X_X_X_X_X_X_X", NO_BREAK);
+        layout("___X_X_X_X_X_X_X_X_X_X___", NO_BREAK);
+        layout("C_X", new int[] {2});
+        layout("C__X", new int[] {3});
+    }
+
+    /**
+     * Note that when the text has spans, StaticLayout does not use the provided TextPaint to
+     * measure text runs anymore. This is probably a bug.
+     * To be able to use the fake sTextPaint and make this test pass, use mPaint instead of
+     * mWorkPaint in MeasuredText#addStyleRun
+     */
+    @Test
+    public void testWithSpans() {
+        if (!SPAN_TESTS_SUPPORTED) return;
+
+        layout(spanify("<012 456 89>"), NO_BREAK);
+        layout(spanify("012 <456> 89"), NO_BREAK);
+        layout(spanify("<012> <456>< 89>"), NO_BREAK);
+        layout(spanify("<012> <456> <89>"), NO_BREAK);
+
+        layout(spanify("<012> <456> <89>012"), new int[] {8});
+        layout(spanify("<012> <456> 89<012>"), new int[] {8});
+        layout(spanify("<012> <456> <89><012>"), new int[] {8});
+        layout(spanify("<012> <456> 89 <123>"), new int[] {11});
+        layout(spanify("<012> <456> 89< 123>"), new int[] {11});
+        layout(spanify("<012> <456> <89> <123>"), new int[] {11});
+        layout(spanify("012 456 89 <LXX> XX XX"), new int[] {11, 18});
+    }
+
+    /*
+     * Adding a span to the string should not change the layout, since the metrics are unchanged.
+     */
+    @Test
+    public void testWithOneSpan() {
+        if (!SPAN_TESTS_SUPPORTED) return;
+
+        String[] texts = new String[] { "0123", "012 456", "012 456 89 123", "012 45678 012",
+                "012 456 89012 456 89012", "0123456789012" };
+
+        MetricAffectingSpan metricAffectingSpan = getMetricAffectingSpan();
+
+        for (String text : texts) {
+            // Get the line breaks without any span
+            int[] breaks = getBreaks(text);
+
+            // Add spans on all possible offsets
+            for (int spanStart = 0; spanStart < text.length(); spanStart++) {
+                for (int spanEnd = spanStart; spanEnd < text.length(); spanEnd++) {
+                    SpannableStringBuilder ssb = new SpannableStringBuilder(text);
+                    ssb.setSpan(metricAffectingSpan, spanStart, spanEnd,
+                            Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+                    layout(ssb, breaks);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testWithTwoSpans() {
+        if (!SPAN_TESTS_SUPPORTED) return;
+
+        String[] texts = new String[] { "0123", "012 456", "012 456 89 123", "012 45678 012",
+                "012 456 89012 456 89012", "0123456789012" };
+
+        MetricAffectingSpan metricAffectingSpan1 = getMetricAffectingSpan();
+        MetricAffectingSpan metricAffectingSpan2 = getMetricAffectingSpan();
+
+        for (String text : texts) {
+            // Get the line breaks without any span
+            int[] breaks = getBreaks(text);
+
+            // Add spans on all possible offsets
+            for (int spanStart1 = 0; spanStart1 < text.length(); spanStart1++) {
+                for (int spanEnd1 = spanStart1; spanEnd1 < text.length(); spanEnd1++) {
+                    SpannableStringBuilder ssb = new SpannableStringBuilder(text);
+                    ssb.setSpan(metricAffectingSpan1, spanStart1, spanEnd1,
+                            Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+
+                    for (int spanStart2 = 0; spanStart2 < text.length(); spanStart2++) {
+                        for (int spanEnd2 = spanStart2; spanEnd2 < text.length(); spanEnd2++) {
+                            ssb.setSpan(metricAffectingSpan2, spanStart2, spanEnd2,
+                                    Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+                            layout(ssb, breaks);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public static String replace(String string, char c, char r) {
+        return string.replaceAll(String.valueOf(c), String.valueOf(r));
+    }
+
+    @Test
+    public void testWithSurrogate() {
+        layout("LX" + SURR_FIRST + SURR_SECOND, NO_BREAK);
+        layout("LXXXX" + SURR_FIRST + SURR_SECOND, NO_BREAK);
+        // LXXXXI (91) + SURR_FIRST (7) fits. But we should not break the surrogate pair
+        // Bug: surrogate pair is broken, should be 6 (breaking after the 'V')
+        // Maybe not: may be ok if the second character of a pair always has a 0-width
+        layout("LXXXXI" + SURR_FIRST + SURR_SECOND, new int[] {7});
+
+        // LXXXXI (95) + SURR_SECOND (3) fits, but this is not a valid surrogate pair, breaking it
+        layout("LXXXXV" + SURR_SECOND + SURR_FIRST, new int[] {7});
+
+        layout("C" + SURR_FIRST + SURR_SECOND, new int[] {1});
+    }
+
+    @Test
+    public void testNarrowWidth() {
+        int[] widths = new int[] { 0, 4, 10 };
+        String[] texts = new String[] { "", "X", " ", "XX", " X", "XXX" };
+
+        for (String text: texts) {
+            // 15 is such that only one character will fit
+            int[] breaks = getBreaks(text, 15);
+
+            // Width under 15 should all lead to the same line break
+            for (int width: widths) {
+                layout(text, breaks, width);
+            }
+        }
+    }
+
+    @Test
+    public void testNarrowWidthZeroWidth() {
+        int[] widths = new int[] { 1, 4 };
+        for (int width: widths) {
+            layout("X.", new int[] {1}, width);
+            layout("X__", NO_BREAK, width);
+            layout("X__X", new int[] {3}, width);
+            layout("X__X_", new int[] {3}, width);
+
+            layout("_", NO_BREAK, width);
+            layout("__", NO_BREAK, width);
+            layout("_X", new int[] {1}, width);
+            layout("_X_", new int[] {1}, width);
+            layout("__X__", new int[] {2}, width);
+        }
+    }
+
+    @Test
+    public void testMaxLines() {
+        layoutMaxLines("C", NO_BREAK, 1);
+        layoutMaxLines("C C", new int[] {2}, 1);
+        layoutMaxLines("C C", new int[] {2}, 2);
+        layoutMaxLines("CC", new int[] {1}, 1);
+        layoutMaxLines("CC", new int[] {1}, 2);
+    }
+}
diff --git a/core/tests/coretests/src/android/text/StaticLayoutTest.java b/core/tests/coretests/src/android/text/StaticLayoutTest.java
index b7ca219..74a6cc6 100644
--- a/core/tests/coretests/src/android/text/StaticLayoutTest.java
+++ b/core/tests/coretests/src/android/text/StaticLayoutTest.java
@@ -17,7 +17,9 @@
 package android.text;
 
 import static android.text.Layout.Alignment.ALIGN_NORMAL;
+
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.graphics.Paint.FontMetricsInt;
 import android.support.test.filters.SmallTest;
@@ -26,15 +28,68 @@
 import android.text.method.EditorState;
 import android.util.Log;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.text.Normalizer;
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Tests StaticLayout vertical metrics behavior.
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class StaticLayoutTest {
+    private static final float SPACE_MULTI = 1.0f;
+    private static final float SPACE_ADD = 0.0f;
+    private static final int DEFAULT_OUTER_WIDTH = 150;
+
+    private static final CharSequence LAYOUT_TEXT = "CharSe\tq\nChar"
+            + "Sequence\nCharSequence\nHelllo\n, world\nLongLongLong";
+    private static final CharSequence LAYOUT_TEXT_SINGLE_LINE = "CharSequence";
+
+    private static final Alignment DEFAULT_ALIGN = Alignment.ALIGN_CENTER;
+    private static final int ELLIPSIZE_WIDTH = 8;
+
+    private StaticLayout mDefaultLayout;
+    private TextPaint mDefaultPaint;
+
+    @Before
+    public void setup() {
+        mDefaultPaint = new TextPaint();
+        mDefaultLayout = createDefaultStaticLayout();
+    }
+
+    private StaticLayout createDefaultStaticLayout() {
+        return new StaticLayout(LAYOUT_TEXT, mDefaultPaint,
+                DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+    }
+
+    @Test
+    public void testBuilder() {
+        {
+            // Obtain.
+            final StaticLayout.Builder builder = StaticLayout.Builder.obtain(LAYOUT_TEXT, 0,
+                    LAYOUT_TEXT.length(), mDefaultPaint, DEFAULT_OUTER_WIDTH);
+            final StaticLayout layout = builder.build();
+            // Check default value.
+            assertEquals(TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                    layout.getTextDirectionHeuristic());
+        }
+        {
+            // setTextDirection.
+            final StaticLayout.Builder builder = StaticLayout.Builder.obtain(LAYOUT_TEXT, 0,
+                    LAYOUT_TEXT.length(), mDefaultPaint, DEFAULT_OUTER_WIDTH);
+            builder.setTextDirection(TextDirectionHeuristics.RTL);
+            final StaticLayout layout = builder.build();
+            // Always returns TextDirectionHeuristics.FIRSTSTRONG_LTR.
+            assertEquals(TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                    layout.getTextDirectionHeuristic());
+        }
+    }
+
     /**
      * Basic test showing expected behavior and relationship between font
      * metrics and line metrics.
@@ -410,4 +465,210 @@
         state.setByString("| U+261D U+1F3FB U+261D U+1F3FB U+261D U+1F3FB");
         moveCursorToLeftCursorableOffset(state, paint);
     }
+
+    private StaticLayout createEllipsizeStaticLayout(CharSequence text,
+            TextUtils.TruncateAt ellipsize, int maxLines) {
+        return new StaticLayout(text, 0, text.length(),
+                mDefaultPaint, DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN,
+                TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                SPACE_MULTI, SPACE_ADD, true /* include pad */,
+                ellipsize,
+                ELLIPSIZE_WIDTH,
+                maxLines);
+    }
+
+    @Test
+    public void testEllipsis_singleLine() {
+        {
+            // Single line case and TruncateAt.END so that we have some ellipsis
+            StaticLayout layout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
+                    TextUtils.TruncateAt.END, 1);
+            assertTrue(layout.getEllipsisCount(0) > 0);
+        }
+        {
+            // Single line case and TruncateAt.MIDDLE so that we have some ellipsis
+            StaticLayout layout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
+                    TextUtils.TruncateAt.MIDDLE, 1);
+            assertTrue(layout.getEllipsisCount(0) > 0);
+        }
+        {
+            // Single line case and TruncateAt.END so that we have some ellipsis
+            StaticLayout layout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
+                    TextUtils.TruncateAt.END, 1);
+            assertTrue(layout.getEllipsisCount(0) > 0);
+        }
+        {
+            // Single line case and TruncateAt.MARQUEE so that we have NO ellipsis
+            StaticLayout layout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
+                    TextUtils.TruncateAt.MARQUEE, 1);
+            assertTrue(layout.getEllipsisCount(0) == 0);
+        }
+        {
+            final String text = "\u3042" // HIRAGANA LETTER A
+                    + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
+            final float textWidth = mDefaultPaint.measureText(text);
+            final int halfWidth = (int) (textWidth / 2.0f);
+            {
+                StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                        halfWidth, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                        SPACE_MULTI, SPACE_ADD, false, TextUtils.TruncateAt.END, halfWidth, 1);
+                assertTrue(layout.getEllipsisCount(0) > 0);
+                assertTrue(layout.getEllipsisStart(0) > 0);
+            }
+            {
+                StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                        halfWidth, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                        SPACE_MULTI, SPACE_ADD, false, TextUtils.TruncateAt.START, halfWidth, 1);
+                assertTrue(layout.getEllipsisCount(0) > 0);
+                assertEquals(0, mDefaultLayout.getEllipsisStart(0));
+            }
+            {
+                StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                        halfWidth, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                        SPACE_MULTI, SPACE_ADD, false, TextUtils.TruncateAt.MIDDLE, halfWidth, 1);
+                assertTrue(layout.getEllipsisCount(0) > 0);
+                assertTrue(layout.getEllipsisStart(0) > 0);
+            }
+            {
+                StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                        halfWidth, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                        SPACE_MULTI, SPACE_ADD, false, TextUtils.TruncateAt.MARQUEE, halfWidth, 1);
+                assertEquals(0, layout.getEllipsisCount(0));
+            }
+        }
+
+        {
+            // The white spaces in this text will be trailing if maxLines is larger than 1, but
+            // width of the trailing white spaces must not be ignored if ellipsis is applied.
+            final String text = "abc                                             def";
+            final float textWidth = mDefaultPaint.measureText(text);
+            final int halfWidth = (int) (textWidth / 2.0f);
+            {
+                StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                        halfWidth, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                        SPACE_MULTI, SPACE_ADD, false, TextUtils.TruncateAt.END, halfWidth, 1);
+                assertTrue(layout.getEllipsisCount(0) > 0);
+                assertTrue(layout.getEllipsisStart(0) > 0);
+            }
+        }
+
+        {
+            // 2 family emojis (11 code units + 11 code units).
+            final String text = "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66"
+                    + "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66";
+            final float textWidth = mDefaultPaint.measureText(text);
+
+            final TextUtils.TruncateAt[] kinds = {TextUtils.TruncateAt.START,
+                    TextUtils.TruncateAt.MIDDLE, TextUtils.TruncateAt.END};
+            for (final TextUtils.TruncateAt kind : kinds) {
+                for (int i = 0; i <= 8; i++) {
+                    int avail = (int) (textWidth * i / 7.0f);
+                    StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                            avail, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                            SPACE_MULTI, SPACE_ADD, false, kind, avail, 1);
+
+                    assertTrue(layout.getEllipsisCount(0) == text.length()
+                                    || layout.getEllipsisCount(0) == text.length() / 2
+                                    || layout.getEllipsisCount(0) == 0);
+                }
+            }
+        }
+    }
+
+    // String wrapper for testing not well known implementation of CharSequence.
+    private class FakeCharSequence implements CharSequence {
+        private String mStr;
+
+        FakeCharSequence(String str) {
+            mStr = str;
+        }
+
+        @Override
+        public char charAt(int index) {
+            return mStr.charAt(index);
+        }
+
+        @Override
+        public int length() {
+            return mStr.length();
+        }
+
+        @Override
+        public CharSequence subSequence(int start, int end) {
+            return mStr.subSequence(start, end);
+        }
+
+        @Override
+        public String toString() {
+            return mStr;
+        }
+    };
+
+    private List<CharSequence> buildTestCharSequences(String testString, Normalizer.Form[] forms) {
+        List<CharSequence> result = new ArrayList<>();
+
+        List<String> normalizedStrings = new ArrayList<>();
+        for (Normalizer.Form form: forms) {
+            normalizedStrings.add(Normalizer.normalize(testString, form));
+        }
+
+        for (String str: normalizedStrings) {
+            result.add(str);
+            result.add(new SpannedString(str));
+            result.add(new SpannableString(str));
+            result.add(new SpannableStringBuilder(str));  // as a GraphicsOperations implementation.
+            result.add(new FakeCharSequence(str));  // as a not well known implementation.
+        }
+        return result;
+    }
+
+    private String buildTestMessage(CharSequence seq) {
+        String normalized;
+        if (Normalizer.isNormalized(seq, Normalizer.Form.NFC)) {
+            normalized = "NFC";
+        } else if (Normalizer.isNormalized(seq, Normalizer.Form.NFD)) {
+            normalized = "NFD";
+        } else if (Normalizer.isNormalized(seq, Normalizer.Form.NFKC)) {
+            normalized = "NFKC";
+        } else if (Normalizer.isNormalized(seq, Normalizer.Form.NFKD)) {
+            normalized = "NFKD";
+        } else {
+            throw new IllegalStateException("Normalized form is not NFC/NFD/NFKC/NFKD");
+        }
+
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < seq.length(); ++i) {
+            builder.append(String.format("0x%04X ", Integer.valueOf(seq.charAt(i))));
+        }
+
+        return "testString: \"" + seq.toString() + "\"[" + builder.toString() + "]"
+                + ", class: " + seq.getClass().getName()
+                + ", Normalization: " + normalized;
+    }
+
+    @Test
+    public void testGetOffset_UNICODE_Hebrew() {
+        String testString = "\u05DE\u05E1\u05E2\u05D3\u05D4"; // Hebrew Characters
+        for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
+            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
+                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN,
+                    TextDirectionHeuristics.RTL, SPACE_MULTI, SPACE_ADD, true);
+
+            String testLabel = buildTestMessage(seq);
+
+            assertEquals(testLabel, 1, layout.getOffsetToLeftOf(0));
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(1));
+            assertEquals(testLabel, 3, layout.getOffsetToLeftOf(2));
+            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(3));
+            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(4));
+            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(5));
+
+            assertEquals(testLabel, 0, layout.getOffsetToRightOf(0));
+            assertEquals(testLabel, 0, layout.getOffsetToRightOf(1));
+            assertEquals(testLabel, 1, layout.getOffsetToRightOf(2));
+            assertEquals(testLabel, 2, layout.getOffsetToRightOf(3));
+            assertEquals(testLabel, 3, layout.getOffsetToRightOf(4));
+            assertEquals(testLabel, 4, layout.getOffsetToRightOf(5));
+        }
+    }
 }
diff --git a/core/tests/coretests/src/android/text/format/DateUtilsTest.java b/core/tests/coretests/src/android/text/format/DateUtilsTest.java
index 9271cb4..6063e1a 100644
--- a/core/tests/coretests/src/android/text/format/DateUtilsTest.java
+++ b/core/tests/coretests/src/android/text/format/DateUtilsTest.java
@@ -24,12 +24,16 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import java.util.Locale;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.text.DateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class DateUtilsTest {
@@ -103,6 +107,42 @@
         assertEquals("48h", DateUtils.formatDuration(172800000, DateUtils.LENGTH_SHORTEST));
     }
 
+    @Test
+    public void testFormatSameDayTime() {
+        // This test assumes a default DateFormat.is24Hour setting.
+        DateFormat.is24Hour = null;
+        Date date = new Date(109, 0, 19, 3, 30, 15);
+        long fixedTime = date.getTime();
+
+        int currentYear = Calendar.getInstance().get(Calendar.YEAR);
+        Date dateWithCurrentYear = new Date(currentYear - 1900, 0, 19, 3, 30, 15);
+
+        final long dayDuration = 5 * 24 * 60 * 60 * 1000;
+        assertEquals("Saturday, January 24, 2009", DateUtils.formatSameDayTime(
+                fixedTime + dayDuration, fixedTime, java.text.DateFormat.FULL,
+                java.text.DateFormat.FULL));
+        assertEquals("Jan 24, 2009", DateUtils.formatSameDayTime(fixedTime + dayDuration,
+                fixedTime, java.text.DateFormat.DEFAULT, java.text.DateFormat.FULL));
+        assertEquals("January 24, 2009", DateUtils.formatSameDayTime(fixedTime + dayDuration,
+                fixedTime, java.text.DateFormat.LONG, java.text.DateFormat.FULL));
+        assertEquals("Jan 24, 2009", DateUtils.formatSameDayTime(fixedTime + dayDuration,
+                fixedTime, java.text.DateFormat.MEDIUM, java.text.DateFormat.FULL));
+        assertEquals("1/24/09", DateUtils.formatSameDayTime(fixedTime + dayDuration,
+                fixedTime, java.text.DateFormat.SHORT, java.text.DateFormat.FULL));
+
+        final long hourDuration = 2 * 60 * 60 * 1000;
+        assertEquals("5:30:15 AM GMT+00:00", DateUtils.formatSameDayTime(fixedTime + hourDuration,
+                fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.FULL));
+        assertEquals("5:30:15 AM", DateUtils.formatSameDayTime(fixedTime + hourDuration,
+                fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.DEFAULT));
+        assertEquals("5:30:15 AM GMT+00:00", DateUtils.formatSameDayTime(fixedTime + hourDuration,
+                fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.LONG));
+        assertEquals("5:30:15 AM", DateUtils.formatSameDayTime(fixedTime + hourDuration,
+                fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.MEDIUM));
+        assertEquals("5:30 AM", DateUtils.formatSameDayTime(fixedTime + hourDuration,
+                fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.SHORT));
+    }
+
     private void setLocales(LocaleList locales) {
         final Resources systemResources = Resources.getSystem();
         final Configuration config = new Configuration(systemResources.getConfiguration());
diff --git a/core/tests/coretests/src/android/text/method/WordIteratorTest.java b/core/tests/coretests/src/android/text/method/WordIteratorTest.java
index 3499a74..d1f4f7e 100644
--- a/core/tests/coretests/src/android/text/method/WordIteratorTest.java
+++ b/core/tests/coretests/src/android/text/method/WordIteratorTest.java
@@ -21,19 +21,131 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.support.test.runner.AndroidJUnit4;
 import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.text.BreakIterator;
 import java.util.Locale;
-import org.junit.Test;
-import org.junit.runner.RunWith;
 
 // TODO(Bug: 24062099): Add more tests for non-ascii text.
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class WordIteratorTest {
 
+    private WordIterator mWordIterator = new WordIterator();
+
+    private void verifyIsWordWithSurrogate(int beginning, int end, int surrogateIndex) {
+        for (int i = beginning; i <= end; i++) {
+            if (i == surrogateIndex) continue;
+            assertEquals(beginning, mWordIterator.getBeginning(i));
+            assertEquals(end, mWordIterator.getEnd(i));
+        }
+    }
+
+    private void setCharSequence(String string) {
+        mWordIterator.setCharSequence(string, 0, string.length());
+    }
+
+    private void verifyIsWord(int beginning, int end) {
+        verifyIsWordWithSurrogate(beginning, end, -1);
+    }
+
+    private void verifyIsNotWord(int beginning, int end) {
+        for (int i = beginning; i <= end; i++) {
+            assertEquals(BreakIterator.DONE, mWordIterator.getBeginning(i));
+            assertEquals(BreakIterator.DONE, mWordIterator.getEnd(i));
+        }
+    }
+
+    @Test
+    public void testEmptyString() {
+        setCharSequence("");
+        assertEquals(BreakIterator.DONE, mWordIterator.following(0));
+        assertEquals(BreakIterator.DONE, mWordIterator.preceding(0));
+
+        assertEquals(BreakIterator.DONE, mWordIterator.getBeginning(0));
+        assertEquals(BreakIterator.DONE, mWordIterator.getEnd(0));
+    }
+
+    @Test
+    public void testOneWord() {
+        setCharSequence("I");
+        verifyIsWord(0, 1);
+
+        setCharSequence("am");
+        verifyIsWord(0, 2);
+
+        setCharSequence("zen");
+        verifyIsWord(0, 3);
+    }
+
+    @Test
+    public void testSpacesOnly() {
+        setCharSequence(" ");
+        verifyIsNotWord(0, 1);
+
+        setCharSequence(", ");
+        verifyIsNotWord(0, 2);
+
+        setCharSequence(":-)");
+        verifyIsNotWord(0, 3);
+    }
+
+    @Test
+    public void testBeginningEnd() {
+        setCharSequence("Well hello,   there! ");
+        //                  0123456789012345678901
+        verifyIsWord(0, 4);
+        verifyIsWord(5, 10);
+        verifyIsNotWord(11, 13);
+        verifyIsWord(14, 19);
+        verifyIsNotWord(20, 21);
+
+        setCharSequence("  Another - sentence");
+        //                  012345678901234567890
+        verifyIsNotWord(0, 1);
+        verifyIsWord(2, 9);
+        verifyIsNotWord(10, 11);
+        verifyIsWord(12, 20);
+
+        setCharSequence("This is \u0644\u0627 tested"); // Lama-aleph
+        //                  012345678     9     01234567
+        verifyIsWord(0, 4);
+        verifyIsWord(5, 7);
+        verifyIsWord(8, 10);
+        verifyIsWord(11, 17);
+    }
+
+    @Test
+    public void testSurrogate() {
+        final String gothicBairkan = "\uD800\uDF31";
+
+        setCharSequence("one we" + gothicBairkan + "ird word");
+        //                  012345    67         890123456
+
+        verifyIsWord(0, 3);
+        // Skip index 7 (there is no point in starting between the two surrogate characters)
+        verifyIsWordWithSurrogate(4, 11, 7);
+        verifyIsWord(12, 16);
+
+        setCharSequence("one " + gothicBairkan + "xxx word");
+        //                  0123    45         678901234
+
+        verifyIsWord(0, 3);
+        verifyIsWordWithSurrogate(4, 9, 5);
+        verifyIsWord(10, 14);
+
+        setCharSequence("one xxx" + gothicBairkan + " word");
+        //                  0123456    78         901234
+
+        verifyIsWord(0, 3);
+        verifyIsWordWithSurrogate(4, 9, 8);
+        verifyIsWord(10, 14);
+    }
+
     @Test
     public void testSetCharSequence() {
         final String text = "text";
diff --git a/core/tests/coretests/src/android/text/style/UnderlineSpanTest.java b/core/tests/coretests/src/android/text/style/UnderlineSpanTest.java
new file mode 100644
index 0000000..e5c4b82
--- /dev/null
+++ b/core/tests/coretests/src/android/text/style/UnderlineSpanTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.text.style;
+
+
+import static org.junit.Assert.assertEquals;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.StaticLayout;
+import android.text.TextPaint;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class UnderlineSpanTest {
+    private class RedUnderlineSpan extends UnderlineSpan {
+        @Override
+        public void updateDrawState(TextPaint ds) {
+            ds.setUnderlineText(android.graphics.Color.RED, 1.0f);
+        }
+    }
+
+    // Identical to the normal UnderlineSpan test, except that a subclass of UnderlineSpan is used
+    // that draws a red underline. This shouldn't affect width either.
+    @Test
+    public void testDoesntAffectWidth_colorUnderlineSubclass() {
+        // Roboto kerns between "P" and "."
+        final SpannableString text = new SpannableString("P.");
+        final float origLineWidth = textWidth(text);
+        // Underline just the "P".
+        text.setSpan(new RedUnderlineSpan(), 0, 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+        final float underlinedLineWidth = textWidth(text);
+        assertEquals(origLineWidth, underlinedLineWidth, 0.0f);
+    }
+
+    // Measures the width of some potentially-spanned text, assuming it's not too wide.
+    private float textWidth(CharSequence text) {
+        final TextPaint tp = new TextPaint();
+        tp.setTextSize(100.0f); // Large enough so that the difference in kerning is visible.
+        final int largeWidth = 10000; // Enough width so the whole text fits in one line.
+        final StaticLayout layout = StaticLayout.Builder.obtain(
+                text, 0, text.length(), tp, largeWidth).build();
+        return layout.getLineWidth(0);
+    }
+}
diff --git a/core/tests/coretests/src/android/text/util/LinkifyTest.java b/core/tests/coretests/src/android/text/util/LinkifyTest.java
index 23c34085..73ff046 100644
--- a/core/tests/coretests/src/android/text/util/LinkifyTest.java
+++ b/core/tests/coretests/src/android/text/util/LinkifyTest.java
@@ -16,6 +16,7 @@
 
 package android.text.util;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -25,15 +26,20 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.text.Spannable;
+import android.text.SpannableString;
 import android.text.method.LinkMovementMethod;
+import android.text.style.URLSpan;
+import android.util.Patterns;
 import android.widget.TextView;
 
-import java.util.Locale;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Locale;
+
 /**
  * LinkifyTest tests {@link Linkify}.
  */
@@ -98,4 +104,49 @@
         overrideConfig.setLocales(LOCALE_LIST_US);
         return mContext.createConfigurationContext(overrideConfig);
     }
+
+    @Test
+    public void testAddLinks_addsLinksWhenDefaultSchemeIsNull() {
+        Spannable spannable = new SpannableString("any https://android.com any android.com any");
+        Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, null, null, null);
+
+        URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
+        assertEquals("android.com and https://android.com should be linkified", 2, spans.length);
+        assertEquals("https://android.com", spans[0].getURL());
+        assertEquals("android.com", spans[1].getURL());
+    }
+
+    @Test
+    public void testAddLinks_addsLinksWhenSchemesArrayIsNull() {
+        Spannable spannable = new SpannableString("any https://android.com any android.com any");
+        Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, "http://", null, null);
+
+        URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
+        assertEquals("android.com and https://android.com should be linkified", 2, spans.length);
+        // expected behavior, passing null schemes array means: prepend defaultScheme to all links.
+        assertEquals("http://https://android.com", spans[0].getURL());
+        assertEquals("http://android.com", spans[1].getURL());
+    }
+
+    @Test
+    public void testAddLinks_prependsDefaultSchemeToBeginingOfLink() {
+        Spannable spannable = new SpannableString("any android.com any");
+        Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, "http://",
+                new String[] { "http://", "https://"}, null, null);
+
+        URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
+        assertEquals("android.com should be linkified", 1, spans.length);
+        assertEquals("http://android.com", spans[0].getURL());
+    }
+
+    @Test
+    public void testAddLinks_doesNotPrependSchemeIfSchemeExists() {
+        Spannable spannable = new SpannableString("any https://android.com any");
+        Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, "http://",
+                new String[] { "http://", "https://"}, null, null);
+
+        URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
+        assertEquals("android.com should be linkified", 1, spans.length);
+        assertEquals("https://android.com", spans[0].getURL());
+    }
 }
diff --git a/core/tests/coretests/src/android/transition/FadeTransitionTest.java b/core/tests/coretests/src/android/transition/FadeTransitionTest.java
index 0140a04..674b363 100644
--- a/core/tests/coretests/src/android/transition/FadeTransitionTest.java
+++ b/core/tests/coretests/src/android/transition/FadeTransitionTest.java
@@ -48,23 +48,23 @@
         View square1 = mActivity.findViewById(R.id.square1);
         Fade fadeOut = new Fade(Fade.MODE_OUT);
         TransitionLatch latch = setVisibilityInTransition(fadeOut, R.id.square1, View.INVISIBLE);
-        assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS));
+        assertTrue(latch.startLatch.await(400, TimeUnit.MILLISECONDS));
         assertEquals(View.VISIBLE, square1.getVisibility());
         waitForAnimation();
         assertFalse(square1.getTransitionAlpha() == 0 || square1.getTransitionAlpha() == 1);
-        assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS));
+        assertTrue(latch.endLatch.await(800, TimeUnit.MILLISECONDS));
         assertEquals(1.0f, square1.getTransitionAlpha());
         assertEquals(View.INVISIBLE, square1.getVisibility());
 
         Fade fadeIn = new Fade(Fade.MODE_IN);
         latch = setVisibilityInTransition(fadeIn, R.id.square1, View.VISIBLE);
-        assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS));
+        assertTrue(latch.startLatch.await(400, TimeUnit.MILLISECONDS));
         assertEquals(View.VISIBLE, square1.getVisibility());
         waitForAnimation();
         final float transitionAlpha = square1.getTransitionAlpha();
         assertTrue("expecting transitionAlpha to be between 0 and 1. Was " + transitionAlpha,
                 transitionAlpha > 0 && transitionAlpha < 1);
-        assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS));
+        assertTrue(latch.endLatch.await(800, TimeUnit.MILLISECONDS));
         assertEquals(1.0f, square1.getTransitionAlpha());
         assertEquals(View.VISIBLE, square1.getVisibility());
     }
@@ -76,14 +76,14 @@
         FadeValueCheck fadeOutValueCheck = new FadeValueCheck(square1);
         fadeOut.addListener(fadeOutValueCheck);
         TransitionLatch outLatch = setVisibilityInTransition(fadeOut, R.id.square1, View.INVISIBLE);
-        assertTrue(outLatch.startLatch.await(200, TimeUnit.MILLISECONDS));
+        assertTrue(outLatch.startLatch.await(400, TimeUnit.MILLISECONDS));
         waitForAnimation();
 
         Fade fadeIn = new Fade(Fade.MODE_IN);
         FadeValueCheck fadeInValueCheck = new FadeValueCheck(square1);
         fadeIn.addListener(fadeInValueCheck);
         TransitionLatch inLatch = setVisibilityInTransition(fadeIn, R.id.square1, View.VISIBLE);
-        assertTrue(inLatch.startLatch.await(200, TimeUnit.MILLISECONDS));
+        assertTrue(inLatch.startLatch.await(400, TimeUnit.MILLISECONDS));
 
         assertEquals(fadeOutValueCheck.pauseTransitionAlpha, fadeInValueCheck.startTransitionAlpha);
         assertTrue("expecting transitionAlpha to be between 0 and 1. Was " +
@@ -91,7 +91,7 @@
                 fadeOutValueCheck.pauseTransitionAlpha > 0 &&
                         fadeOutValueCheck.pauseTransitionAlpha < 1);
 
-        assertTrue(inLatch.endLatch.await(400, TimeUnit.MILLISECONDS));
+        assertTrue(inLatch.endLatch.await(800, TimeUnit.MILLISECONDS));
         assertEquals(1.0f, square1.getTransitionAlpha());
         assertEquals(View.VISIBLE, square1.getVisibility());
     }
@@ -109,22 +109,22 @@
         FadeValueCheck fadeInValueCheck = new FadeValueCheck(square1);
         fadeIn.addListener(fadeInValueCheck);
         TransitionLatch inLatch = setVisibilityInTransition(fadeIn, R.id.square1, View.VISIBLE);
-        assertTrue(inLatch.startLatch.await(200, TimeUnit.MILLISECONDS));
+        assertTrue(inLatch.startLatch.await(400, TimeUnit.MILLISECONDS));
         waitForAnimation();
 
         Fade fadeOut = new Fade(Fade.MODE_OUT);
         FadeValueCheck fadeOutValueCheck = new FadeValueCheck(square1);
         fadeOut.addListener(fadeOutValueCheck);
         TransitionLatch outLatch = setVisibilityInTransition(fadeOut, R.id.square1, View.INVISIBLE);
-        assertTrue(outLatch.startLatch.await(200, TimeUnit.MILLISECONDS));
+        assertTrue(outLatch.startLatch.await(400, TimeUnit.MILLISECONDS));
 
-        assertEquals(fadeOutValueCheck.pauseTransitionAlpha, fadeInValueCheck.startTransitionAlpha);
+        assertEquals(fadeInValueCheck.pauseTransitionAlpha, fadeOutValueCheck.startTransitionAlpha);
         assertTrue("expecting transitionAlpha to be between 0 and 1. Was " +
                         fadeInValueCheck.pauseTransitionAlpha,
                 fadeInValueCheck.pauseTransitionAlpha > 0 &&
                         fadeInValueCheck.pauseTransitionAlpha < 1);
 
-        assertTrue(outLatch.endLatch.await(400, TimeUnit.MILLISECONDS));
+        assertTrue(outLatch.endLatch.await(800, TimeUnit.MILLISECONDS));
         assertEquals(1.0f, square1.getTransitionAlpha());
         assertEquals(View.INVISIBLE, square1.getVisibility());
     }
diff --git a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
new file mode 100644
index 0000000..b18fa74
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+
+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.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(AndroidJUnit4.class)
+public class IntentForwarderActivityTest {
+    private static final ComponentName FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME =
+            new ComponentName(
+                    "android",
+                    IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE
+            );
+    private static final String TYPE_PLAIN_TEXT = "text/plain";
+
+    private static UserInfo MANAGED_PROFILE_INFO = new UserInfo();
+    static {
+        MANAGED_PROFILE_INFO.id = 10;
+        MANAGED_PROFILE_INFO.flags = UserInfo.FLAG_MANAGED_PROFILE;
+    }
+
+    private static UserInfo CURRENT_USER_INFO = new UserInfo();
+    static {
+        CURRENT_USER_INFO.id = UserHandle.myUserId();
+        CURRENT_USER_INFO.flags = 0;
+    }
+
+    private static IntentForwarderActivity.Injector sInjector;
+    private static ComponentName sComponentName;
+
+    @Mock private IPackageManager mIPm;
+    @Mock private PackageManager mPm;
+    @Mock private UserManager mUserManager;
+
+    @Rule
+    public ActivityTestRule<IntentForwarderWrapperActivity> mActivityRule =
+            new ActivityTestRule<>(IntentForwarderWrapperActivity.class, true, false);
+
+    private Context mContext;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mContext = InstrumentationRegistry.getTargetContext();
+        sInjector = new TestInjector();
+    }
+
+    @Test
+    public void forwardToManagedProfile_canForward_sendIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent can be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
+
+        // Managed profile exists.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        profiles.add(MANAGED_PROFILE_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
+        intent.setAction(Intent.ACTION_SEND);
+        intent.setType(TYPE_PLAIN_TEXT);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mIPm).canForwardTo(intentCaptor.capture(), eq(TYPE_PLAIN_TEXT), anyInt(), anyInt());
+        assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction());
+
+        assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction());
+        assertNotNull(activity.mStartActivityIntent);
+        assertEquals(Intent.ACTION_SEND, activity.mStartActivityIntent.getAction());
+        assertNull(activity.mStartActivityIntent.getPackage());
+        assertNull(activity.mStartActivityIntent.getComponent());
+        assertEquals(CURRENT_USER_INFO.id, activity.mStartActivityIntent.getContentUserHint());
+
+        assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn);
+    }
+
+    @Test
+    public void forwardToManagedProfile_cannotForward_sendIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent cannot be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(false);
+
+        // Managed profile exists.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        profiles.add(MANAGED_PROFILE_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        // Create ACTION_SEND intent.
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
+        intent.setAction(Intent.ACTION_SEND);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        assertNull(activity.mStartActivityIntent);
+    }
+
+    @Test
+    public void forwardToManagedProfile_noManagedProfile_sendIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent can be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), anyString(), anyInt(), anyInt())).thenReturn(true);
+
+        // Managed profile does not exist.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        // Create ACTION_SEND intent.
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
+        intent.setAction(Intent.ACTION_SEND);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        assertNull(activity.mStartActivityIntent);
+    }
+
+    @Test
+    public void forwardToManagedProfile_canForward_chooserIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent can be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
+
+        // Manage profile exists.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        profiles.add(MANAGED_PROFILE_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        // Create chooser Intent
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
+        intent.setAction(Intent.ACTION_CHOOSER);
+        Intent sendIntent = new Intent(Intent.ACTION_SEND);
+        sendIntent.setComponent(new ComponentName("xx", "yyy"));
+        sendIntent.setType(TYPE_PLAIN_TEXT);
+        intent.putExtra(Intent.EXTRA_INTENT, sendIntent);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mIPm).canForwardTo(intentCaptor.capture(), eq(TYPE_PLAIN_TEXT), anyInt(), anyInt());
+        assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction());
+
+        assertNotNull(activity.mStartActivityIntent);
+        assertEquals(Intent.ACTION_CHOOSER, activity.mStartActivityIntent.getAction());
+        assertNull(activity.mStartActivityIntent.getPackage());
+        assertNull(activity.mStartActivityIntent.getComponent());
+
+        Intent innerIntent = activity.mStartActivityIntent.getParcelableExtra(Intent.EXTRA_INTENT);
+        assertNotNull(innerIntent);
+        assertEquals(Intent.ACTION_SEND, innerIntent.getAction());
+        assertNull(innerIntent.getComponent());
+        assertNull(innerIntent.getPackage());
+        assertEquals(CURRENT_USER_INFO.id, innerIntent.getContentUserHint());
+
+        assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn);
+    }
+
+    @Test
+    public void forwardToManagedProfile_canForward_selectorIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent can be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
+
+        // Manage profile exists.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        profiles.add(MANAGED_PROFILE_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        // Create selector intent.
+        Intent intent = Intent.makeMainSelectorActivity(
+                Intent.ACTION_VIEW, Intent.CATEGORY_BROWSABLE);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mIPm).canForwardTo(
+                intentCaptor.capture(), nullable(String.class), anyInt(), anyInt());
+        assertEquals(Intent.ACTION_VIEW, intentCaptor.getValue().getAction());
+
+        assertNotNull(activity.mStartActivityIntent);
+        assertEquals(Intent.ACTION_MAIN, activity.mStartActivityIntent.getAction());
+        assertNull(activity.mStartActivityIntent.getPackage());
+        assertNull(activity.mStartActivityIntent.getComponent());
+        assertEquals(CURRENT_USER_INFO.id, activity.mStartActivityIntent.getContentUserHint());
+
+        Intent innerIntent = activity.mStartActivityIntent.getSelector();
+        assertNotNull(innerIntent);
+        assertEquals(Intent.ACTION_VIEW, innerIntent.getAction());
+        assertNull(innerIntent.getComponent());
+        assertNull(innerIntent.getPackage());
+
+        assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn);
+    }
+
+
+    public static class IntentForwarderWrapperActivity extends IntentForwarderActivity {
+        private Intent mStartActivityIntent;
+        private int mUserIdActivityLaunchedIn;
+
+        @Override
+        public void onCreate(@Nullable Bundle savedInstanceState) {
+            getIntent().setComponent(sComponentName);
+            super.onCreate(savedInstanceState);
+        }
+
+        @Override
+        protected Injector createInjector() {
+            return sInjector;
+        }
+
+        @Override
+        public void startActivityAsCaller(Intent intent, @Nullable Bundle options, boolean
+                ignoreTargetSecurity, int userId) {
+            mStartActivityIntent = intent;
+            mUserIdActivityLaunchedIn = userId;
+        }
+    }
+
+    class TestInjector implements IntentForwarderActivity.Injector {
+
+        @Override
+        public IPackageManager getIPackageManager() {
+            return mIPm;
+        }
+
+        @Override
+        public UserManager getUserManager() {
+            return mUserManager;
+        }
+
+        @Override
+        public PackageManager getPackageManager() {
+            return mPm;
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
index c539f78..c21c3be 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
@@ -217,10 +217,6 @@
         curr = 1000 * (clocks.realtime = clocks.uptime = 305);
         bi.updateTimeBasesLocked(false, false, curr, curr); // off battery
 
-        // Stop timer
-        curr = 1000 * (clocks.realtime = clocks.uptime = 409);
-        bi.noteBluetoothScanStoppedFromSourceLocked(ws);
-
         // Start timer (unoptimized)
         curr = 1000 * (clocks.realtime = clocks.uptime = 1000);
         bi.noteBluetoothScanStartedFromSourceLocked(ws, true);
@@ -233,9 +229,13 @@
         curr = 1000 * (clocks.realtime = clocks.uptime = 3004);
         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
 
-        // Stop timer
+        // Stop timer (optimized)
+        curr = 1000 * (clocks.realtime = clocks.uptime = 3409);
+        bi.noteBluetoothScanStoppedFromSourceLocked(ws, false);
+
+        // Stop timer (unoptimized)
         curr = 1000 * (clocks.realtime = clocks.uptime = 4008);
-        bi.noteBluetoothScanStoppedFromSourceLocked(ws);
+        bi.noteBluetoothScanStoppedFromSourceLocked(ws, true);
 
         // Test
         curr = 1000 * (clocks.realtime = clocks.uptime = 5000);
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHelperTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHelperTest.java
index f01c33f..e81f678 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHelperTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHelperTest.java
@@ -18,9 +18,12 @@
 package com.android.internal.os;
 
 
+import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -54,11 +57,16 @@
 @SmallTest
 public class BatteryStatsHelperTest extends TestCase {
     private static final long TIME_FOREGROUND_ACTIVITY_ZERO = 0;
-    private static final long TIME_FOREGROUND_ACTIVITY = 100 * DateUtils.MINUTE_IN_MILLIS;
+    private static final long TIME_FOREGROUND_ACTIVITY = 100 * DateUtils.MINUTE_IN_MILLIS * 1000;
+    private static final long TIME_STATE_FOREGROUND_MS = 10 * DateUtils.MINUTE_IN_MILLIS;
+    private static final long TIME_STATE_FOREGROUND_US = TIME_STATE_FOREGROUND_MS * 1000;
 
     private static final int UID = 123456;
     private static final double BATTERY_SCREEN_USAGE = 300;
     private static final double BATTERY_SYSTEM_USAGE = 600;
+    private static final double BATTERY_WIFI_USAGE = 200;
+    private static final double BATTERY_IDLE_USAGE = 600;
+    private static final double BATTERY_BLUETOOTH_USAGE = 300;
     private static final double BATTERY_OVERACCOUNTED_USAGE = 500;
     private static final double BATTERY_UNACCOUNTED_USAGE = 700;
     private static final double BATTERY_APP_USAGE = 100;
@@ -68,6 +76,12 @@
     @Mock
     private BatteryStats.Uid mUid;
     @Mock
+    private BatterySipper mWifiBatterySipper;
+    @Mock
+    private BatterySipper mBluetoothBatterySipper;
+    @Mock
+    private BatterySipper mIdleBatterySipper;
+    @Mock
     private BatterySipper mNormalBatterySipper;
     @Mock
     private BatterySipper mScreenBatterySipper;
@@ -109,6 +123,15 @@
         mUnaccountedBatterySipper.drainType = BatterySipper.DrainType.UNACCOUNTED;
         mUnaccountedBatterySipper.totalPowerMah = BATTERY_UNACCOUNTED_USAGE;
 
+        mWifiBatterySipper.drainType = BatterySipper.DrainType.WIFI;
+        mWifiBatterySipper.totalPowerMah = BATTERY_WIFI_USAGE;
+
+        mBluetoothBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH;
+        mBluetoothBatterySipper.totalPowerMah = BATTERY_BLUETOOTH_USAGE;
+
+        mIdleBatterySipper.drainType = BatterySipper.DrainType.IDLE;
+        mIdleBatterySipper.totalPowerMah = BATTERY_IDLE_USAGE;
+
         mContext = InstrumentationRegistry.getContext();
         mBatteryStatsHelper = spy(new BatteryStatsHelper(mContext));
         mBatteryStatsHelper.setPackageManager(mPackageManager);
@@ -165,6 +188,9 @@
         sippers.add(mSystemBatterySipper);
         sippers.add(mOvercountedBatterySipper);
         sippers.add(mUnaccountedBatterySipper);
+        sippers.add(mWifiBatterySipper);
+        sippers.add(mBluetoothBatterySipper);
+        sippers.add(mIdleBatterySipper);
         doReturn(true).when(mBatteryStatsHelper).isTypeSystem(mSystemBatterySipper);
         doNothing().when(mBatteryStatsHelper).smearScreenBatterySipper(any(), any());
 
@@ -219,6 +245,19 @@
         assertThat(mBatteryStatsHelper.isTypeService(mNormalBatterySipper)).isTrue();
     }
 
+    @Test
+    public void testGetProcessForegroundTimeMs_largerActivityTime_returnMinTime() {
+        doReturn(TIME_STATE_FOREGROUND_US + 500).when(mBatteryStatsHelper)
+                .getForegroundActivityTotalTimeUs(eq(mUid), anyLong());
+        doReturn(TIME_STATE_FOREGROUND_US).when(mUid).getProcessStateTime(eq(PROCESS_STATE_TOP),
+                anyLong(), anyInt());
+
+        final long time = mBatteryStatsHelper.getProcessForegroundTimeMs(mUid,
+                BatteryStats.STATS_SINCE_CHARGED);
+
+        assertThat(time).isEqualTo(TIME_STATE_FOREGROUND_MS);
+    }
+
     private BatterySipper createTestSmearBatterySipper(long activityTime, double totalPowerMah,
             int uidCode, boolean isUidNull) {
         final BatterySipper sipper = mock(BatterySipper.class);
@@ -227,8 +266,8 @@
         doReturn(uidCode).when(sipper).getUid();
         if (!isUidNull) {
             final BatteryStats.Uid uid = mock(BatteryStats.Uid.class, RETURNS_DEEP_STUBS);
-            doReturn(activityTime).when(mBatteryStatsHelper).getForegroundActivityTotalTimeMs(
-                    eq(uid), anyLong());
+            doReturn(activityTime).when(mBatteryStatsHelper).getProcessForegroundTimeMs(eq(uid),
+                    anyInt());
             doReturn(uidCode).when(uid).getUid();
             sipper.uidObj = uid;
         }
@@ -236,5 +275,4 @@
         return sipper;
     }
 
-
 }
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
index 4e8ab31..ed54f53 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
@@ -44,8 +44,6 @@
         assertEquals(101,
                 bi.getUidStats().get(UID).getBluetoothScanResultCounter()
                         .getCountLocked(STATS_SINCE_CHARGED));
-        // TODO: remove next line when Counter misreporting values when plugged-in bug is fixed.
-        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
         BatteryStats.Counter bgCntr = bi.getUidStats().get(UID).getBluetoothScanResultBgCounter();
         if (bgCntr != null) {
             assertEquals(0, bgCntr.getCountLocked(STATS_SINCE_CHARGED));
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
index af4a6d9..8fd4e31 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
@@ -400,7 +400,7 @@
         assertNotNull(sensor.getSensorBackgroundTime());
 
         // Reset the stats. Since the sensor is still running, we should still see the timer
-        bi.getUidStatsLocked(UID).reset();
+        bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000);
 
         sensor = uid.getSensorStats().get(SENSOR_ID);
         assertNotNull(sensor);
@@ -410,9 +410,111 @@
         bi.noteStopSensorLocked(UID, SENSOR_ID);
 
         // Now the sensor timer has stopped so this reset should also take out the sensor.
-        bi.getUidStatsLocked(UID).reset();
+        bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000);
 
         sensor = uid.getSensorStats().get(SENSOR_ID);
         assertNull(sensor);
     }
+
+    @SmallTest
+    public void testSensorResetTimes() throws Exception {
+        final MockClocks clocks = new MockClocks();
+        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+        final int which = BatteryStats.STATS_SINCE_CHARGED;
+        bi.mForceOnBattery = true;
+        clocks.realtime = 100; // in ms
+        clocks.uptime = 100; // in ms
+
+        // TimeBases are on for some time.
+        BatteryStatsImpl.TimeBase timeBase = bi.getOnBatteryTimeBase();
+        BatteryStatsImpl.TimeBase bgTimeBase = bi.getOnBatteryBackgroundTimeBase(UID);
+        timeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000);
+        bgTimeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000);
+        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // TimeBases are turned off
+        timeBase.setRunning(false, clocks.uptime * 1000, clocks.realtime * 1000);
+        bgTimeBase.setRunning(false, clocks.uptime * 1000, clocks.realtime * 1000);
+
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // Timer is turned on
+        bi.noteStartSensorLocked(UID, SENSOR_ID);
+
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // Timebase was off so times are all 0.
+        BatteryStats.Uid.Sensor sensor = bi.getUidStats().get(UID).getSensorStats().get(SENSOR_ID);
+        BatteryStats.Timer timer = sensor.getSensorTime();
+        BatteryStats.Timer bgTimer = sensor.getSensorBackgroundTime();
+        assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime));
+        assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // Reset the stats. Since the sensor is still running, we should still see the timer
+        // but still with 0 times.
+        bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000);
+        assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime));
+        assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // Now stop the timer. The times should still be 0.
+        bi.noteStopSensorLocked(UID, SENSOR_ID);
+        assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime));
+        assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+        // Now repeat with the TimeBases turned on the entire time.
+        timeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000);
+        bgTimeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000);
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // Timer is turned on
+        bi.noteStartSensorLocked(UID, SENSOR_ID);
+
+        clocks.realtime += 111;
+        clocks.uptime += 1111;
+
+        // Timebase and timer was on so times have increased.
+        assertEquals(111_000, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(111, timer.getTotalDurationMsLocked(clocks.realtime));
+        assertEquals(111_000, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(111, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // Reset the stats. Since the sensor is still running, we should still see the timer
+        // but with 0 times.
+        bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000);
+        assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime));
+        assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+        clocks.realtime += 112;
+        clocks.uptime += 112;
+
+        // Now stop the timer. The times should have increased since the timebase was on.
+        bi.noteStopSensorLocked(UID, SENSOR_ID);
+        assertEquals(112_000, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(112, timer.getTotalDurationMsLocked(clocks.realtime));
+        assertEquals(112_000, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(112, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/widget/ActionBarContainerTest.java b/core/tests/coretests/src/com/android/internal/widget/ActionBarContainerTest.java
index 1471796..912b7ec 100644
--- a/core/tests/coretests/src/com/android/internal/widget/ActionBarContainerTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/ActionBarContainerTest.java
@@ -60,11 +60,9 @@
         TestViewGroup viewGroup = new TestViewGroup(mContext);
         viewGroup.addView(mActionBarContainer);
 
-        ActionMode mode = mActionBarContainer.startActionModeForChild(
-                null, null, ActionMode.TYPE_FLOATING);
+        mActionBarContainer.startActionModeForChild(null, null, ActionMode.TYPE_FLOATING);
 
         // Should bubble up.
-        assertNotNull(mode);
         assertTrue(viewGroup.isStartActionModeForChildTypedCalled);
     }
 
diff --git a/core/tests/coretests/src/com/android/internal/widget/ImageFloatingTextViewTest.java b/core/tests/coretests/src/com/android/internal/widget/ImageFloatingTextViewTest.java
index a249925..1806b22 100644
--- a/core/tests/coretests/src/com/android/internal/widget/ImageFloatingTextViewTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/ImageFloatingTextViewTest.java
@@ -21,9 +21,11 @@
 import android.content.Context;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
+import android.text.Layout;
 import android.view.View.MeasureSpec;
 import android.widget.TextView;
 
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -102,6 +104,16 @@
                 + "Yada yada, yada yada. Lorem ipsum dolor sit amet.");
     }
 
+    @Test
+    public void usesTransformationMethod() {
+        mView.setSingleLine();
+        String text = "Test \n Test";
+        parametrizedTest(text);
+        Layout layout = mView.getLayout();
+        Assert.assertFalse("The transformation method wasn't used, string is still the same",
+                text.equals(layout.getText()));
+    }
+
     private void parametrizedTest(CharSequence text) {
         int heightMeasureSpec = MeasureSpec.makeMeasureSpec(500, MeasureSpec.AT_MOST);
         int widthMeasureSpec = MeasureSpec.makeMeasureSpec(500, MeasureSpec.EXACTLY);
diff --git a/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java b/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java
new file mode 100644
index 0000000..f73950a
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.os.UserHandle;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class LockPatternUtilsTest {
+
+    @Test
+    public void testUserFrp_isNotRegularUser() throws Exception {
+        assertTrue(LockPatternUtils.USER_FRP < 0);
+    }
+
+    @Test
+    public void testUserFrp_isNotAReservedSpecialUser() throws Exception {
+        assertNotEquals(UserHandle.USER_NULL, LockPatternUtils.USER_FRP);
+        assertNotEquals(UserHandle.USER_ALL, LockPatternUtils.USER_FRP);
+        assertNotEquals(UserHandle.USER_CURRENT, LockPatternUtils.USER_FRP);
+        assertNotEquals(UserHandle.USER_CURRENT_OR_SELF, LockPatternUtils.USER_FRP);
+    }
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk
index 2784193..c5e112b 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk
@@ -33,29 +33,17 @@
 	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
 
 LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
-LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\
-    -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
-
-#################################
-include $(BUILD_SYSTEM)/configure_local_jack.mk
-#################################
-
-ifdef LOCAL_JACK_ENABLED
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
-endif
 
 LOCAL_MIN_SDK_VERSION := 8
 
 include $(BUILD_PACKAGE)
 
-ifndef LOCAL_JACK_ENABLED
 $(mainDexList): $(full_classes_proguard_jar) | $(MAINDEXCLASSES)
 	$(hide) mkdir -p $(dir $@)
 	$(MAINDEXCLASSES) $< 1>$@
 	echo "com/android/multidexlegacytestapp/Test.class" >> $@
 
 $(built_dex_intermediate): $(mainDexList)
-endif
 
 ## The application with a full main dex
 include $(CLEAR_VARS)
@@ -76,26 +64,14 @@
 	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
 
 LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList2)
-LOCAL_JACK_FLAGS := -D jack.dex.output.policy=multidex -D jack.preprocessor=true\
-    -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
-
-#################################
-include $(BUILD_SYSTEM)/configure_local_jack.mk
-#################################
-
-ifdef LOCAL_JACK_ENABLED
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
-endif
 
 LOCAL_MIN_SDK_VERSION := 8
 
 include $(BUILD_PACKAGE)
 
-ifndef LOCAL_JACK_ENABLED
 $(mainDexList2): $(full_classes_proguard_jar) | $(MAINDEXCLASSES)
 	$(hide) mkdir -p $(dir $@)
 	$(MAINDEXCLASSES) $< 1>$@
 	echo "com/android/multidexlegacytestapp/Test.class" >> $@
 
 $(built_dex_intermediate): $(mainDexList2)
-endif
\ No newline at end of file
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/test.jpp b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/test.jpp
deleted file mode 100644
index a1f5656..0000000
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/test.jpp
+++ /dev/null
@@ -1,3 +0,0 @@
-test:
-  @@com.android.jack.annotations.ForceInMainDex
-  class com.android.multidexlegacytestapp.Test
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
index 1c7d807..da48df9 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
@@ -32,24 +32,12 @@
 	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
 
 LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
-LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\
-    -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
-
-#################################
-include $(BUILD_SYSTEM)/configure_local_jack.mk
-#################################
-
-ifdef LOCAL_JACK_ENABLED
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
-endif
 
 include $(BUILD_PACKAGE)
 
-ifndef LOCAL_JACK_ENABLED
 $(mainDexList): $(full_classes_proguard_jar) | $(MAINDEXCLASSES)
 	$(hide) mkdir -p $(dir $@)
 	$(MAINDEXCLASSES) $< 1>$@
 	echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
 
 $(built_dex_intermediate): $(mainDexList)
-endif
\ No newline at end of file
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/test.jpp b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/test.jpp
deleted file mode 100644
index 6d384e3..0000000
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/test.jpp
+++ /dev/null
@@ -1,3 +0,0 @@
-test:
-  @@com.android.jack.annotations.ForceInMainDex
-  class com.android.framework.multidexlegacyversionedtestapp.MultiDexUpdateTest
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
index b77cf31..02b3f53 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
@@ -32,24 +32,12 @@
 	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
 
 LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
-LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\
-    -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
-
-#################################
-include $(BUILD_SYSTEM)/configure_local_jack.mk
-#################################
-
-ifdef LOCAL_JACK_ENABLED
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
-endif
 
 include $(BUILD_PACKAGE)
 
-ifndef LOCAL_JACK_ENABLED
 $(mainDexList): $(full_classes_proguard_jar) | $(MAINDEXCLASSES)
 	$(hide) mkdir -p $(dir $@)
 	$(MAINDEXCLASSES) $< 1>$@
 	echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
 
 $(built_dex_intermediate): $(mainDexList)
-endif
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/test.jpp b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/test.jpp
deleted file mode 100644
index 6d384e3..0000000
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/test.jpp
+++ /dev/null
@@ -1,3 +0,0 @@
-test:
-  @@com.android.jack.annotations.ForceInMainDex
-  class com.android.framework.multidexlegacyversionedtestapp.MultiDexUpdateTest
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
index 3631626..4808684 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
@@ -32,25 +32,13 @@
 LOCAL_DEX_PREOPT := false
 
 LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
-LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\
-    -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
-
-#################################
-include $(BUILD_SYSTEM)/configure_local_jack.mk
-#################################
-
-ifdef LOCAL_JACK_ENABLED
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
-endif
 
 include $(BUILD_PACKAGE)
 
-ifndef LOCAL_JACK_ENABLED
 $(mainDexList): $(full_classes_proguard_jar) | $(MAINDEXCLASSES)
 	$(hide) mkdir -p $(dir $@)
 	$(MAINDEXCLASSES) $< 1>$@
 	echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
 
 $(built_dex_intermediate): $(mainDexList)
-endif
 
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/test.jpp b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/test.jpp
deleted file mode 100644
index 6d384e3..0000000
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/test.jpp
+++ /dev/null
@@ -1,3 +0,0 @@
-test:
-  @@com.android.jack.annotations.ForceInMainDex
-  class com.android.framework.multidexlegacyversionedtestapp.MultiDexUpdateTest
diff --git a/core/tests/systemproperties/run_core_systemproperties_test.sh b/core/tests/systemproperties/run_core_systemproperties_test.sh
index d39adbb..9b1fe4b 100755
--- a/core/tests/systemproperties/run_core_systemproperties_test.sh
+++ b/core/tests/systemproperties/run_core_systemproperties_test.sh
@@ -15,7 +15,7 @@
 
 if [[ $rebuild == true ]]; then
   make -j4 FrameworksCoreSystemPropertiesTests
-  TESTAPP=${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreSystemPropertiesTests.apk
+  TESTAPP=${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreSystemPropertiesTests/FrameworksCoreSystemPropertiesTests.apk
   COMMAND="adb install -r $TESTAPP"
   echo $COMMAND
   $COMMAND
diff --git a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
index 544a967..282b001 100644
--- a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
+++ b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
@@ -51,6 +51,11 @@
         value = SystemProperties.get(KEY, "default");
         assertEquals("default", value);
 
+        // null default value is the same as "".
+        SystemProperties.set(KEY, null);
+        value = SystemProperties.get(KEY, "default");
+        assertEquals("default", value);
+
         SystemProperties.set(KEY, "SA");
         value = SystemProperties.get(KEY, "default");
         assertEquals("SA", value);
@@ -62,7 +67,78 @@
         value = SystemProperties.get(KEY, "default");
         assertEquals("default", value);
 
+        // null value is the same as "".
+        SystemProperties.set(KEY, "SA");
+        SystemProperties.set(KEY, null);
+        value = SystemProperties.get(KEY, "default");
+        assertEquals("default", value);
+
         value = SystemProperties.get(KEY);
         assertEquals("", value);
     }
+
+    private static void testInt(String setVal, int defValue, int expected) {
+      SystemProperties.set(KEY, setVal);
+      int value = SystemProperties.getInt(KEY, defValue);
+      assertEquals(expected, value);
+    }
+
+    private static void testLong(String setVal, long defValue, long expected) {
+      SystemProperties.set(KEY, setVal);
+      long value = SystemProperties.getLong(KEY, defValue);
+      assertEquals(expected, value);
+    }
+
+    @SmallTest
+    public void testIntegralProperties() throws Exception {
+        testInt("", 123, 123);
+        testInt("", 0, 0);
+        testInt("", -123, -123);
+
+        testInt("123", 124, 123);
+        testInt("0", 124, 0);
+        testInt("-123", 124, -123);
+
+        testLong("", 3147483647L, 3147483647L);
+        testLong("", 0, 0);
+        testLong("", -3147483647L, -3147483647L);
+
+        testLong("3147483647", 124, 3147483647L);
+        testLong("0", 124, 0);
+        testLong("-3147483647", 124, -3147483647L);
+    }
+
+    @SmallTest
+    @SuppressWarnings("null")
+    public void testNullKey() throws Exception {
+        try {
+            SystemProperties.get(null);
+            fail("Expected NullPointerException");
+        } catch (NullPointerException npe) {
+        }
+
+        try {
+            SystemProperties.get(null, "default");
+            fail("Expected NullPointerException");
+        } catch (NullPointerException npe) {
+        }
+
+        try {
+            SystemProperties.set(null, "value");
+            fail("Expected NullPointerException");
+        } catch (NullPointerException npe) {
+        }
+
+        try {
+            SystemProperties.getInt(null, 0);
+            fail("Expected NullPointerException");
+        } catch (NullPointerException npe) {
+        }
+
+        try {
+            SystemProperties.getLong(null, 0);
+            fail("Expected NullPointerException");
+        } catch (NullPointerException npe) {
+        }
+    }
 }
diff --git a/core/tests/utiltests/AndroidManifest.xml b/core/tests/utiltests/AndroidManifest.xml
index da09894..d6384e7 100644
--- a/core/tests/utiltests/AndroidManifest.xml
+++ b/core/tests/utiltests/AndroidManifest.xml
@@ -40,6 +40,7 @@
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
     <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
+    <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/core/tests/utiltests/AndroidTest.xml b/core/tests/utiltests/AndroidTest.xml
index 9ebf568..65bb8de 100644
--- a/core/tests/utiltests/AndroidTest.xml
+++ b/core/tests/utiltests/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="FrameworksUtilTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.utiltests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/core/tests/utiltests/jni/Android.bp b/core/tests/utiltests/jni/Android.bp
index e9a4144..b0b09c2 100644
--- a/core/tests/utiltests/jni/Android.bp
+++ b/core/tests/utiltests/jni/Android.bp
@@ -17,7 +17,6 @@
     shared_libs: [

         "libcutils",

     ],

-    clang: true,

     stl: "libc++",

     srcs: [

         "registration.cpp",

diff --git a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
new file mode 100644
index 0000000..b18ee17
--- /dev/null
+++ b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.pm.UserInfo;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import android.test.mock.MockContentResolver;
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.internal.widget.ILockSettings;
+import com.android.internal.widget.LockPatternUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class LockPatternUtilsTest {
+
+    private static final int DEMO_USER_ID = 5;
+
+    private LockPatternUtils mLockPatternUtils;
+
+    private void configureTest(boolean isSecure, boolean isDemoUser, int deviceDemoMode)
+            throws Exception {
+        final Context context = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
+
+        final MockContentResolver cr = new MockContentResolver(context);
+        cr.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        when(context.getContentResolver()).thenReturn(cr);
+        Settings.Global.putInt(cr, Settings.Global.DEVICE_DEMO_MODE, deviceDemoMode);
+
+        final ILockSettings ils = Mockito.mock(ILockSettings.class);
+        when(ils.havePassword(DEMO_USER_ID)).thenReturn(isSecure);
+        when(ils.getLong("lockscreen.password_type", PASSWORD_QUALITY_UNSPECIFIED, DEMO_USER_ID))
+                .thenReturn((long) PASSWORD_QUALITY_MANAGED);
+        // TODO(b/63758238): stop spying the class under test
+        mLockPatternUtils = spy(new LockPatternUtils(context));
+        when(mLockPatternUtils.getLockSettings()).thenReturn(ils);
+
+        final UserInfo userInfo = Mockito.mock(UserInfo.class);
+        when(userInfo.isDemo()).thenReturn(isDemoUser);
+        final UserManager um = Mockito.mock(UserManager.class);
+        when(um.getUserInfo(DEMO_USER_ID)).thenReturn(userInfo);
+        when(context.getSystemService(Context.USER_SERVICE)).thenReturn(um);
+    }
+
+    @Test
+    public void isLockScreenDisabled_isDemoUser_true() throws Exception {
+        configureTest(false, true, 2);
+        assertTrue(mLockPatternUtils.isLockScreenDisabled(DEMO_USER_ID));
+    }
+
+    @Test
+    public void isLockScreenDisabled_isSecureAndDemoUser_false() throws Exception {
+        configureTest(true, true, 2);
+        assertFalse(mLockPatternUtils.isLockScreenDisabled(DEMO_USER_ID));
+    }
+
+    @Test
+    public void isLockScreenDisabled_isNotDemoUser_false() throws Exception {
+        configureTest(false, false, 2);
+        assertFalse(mLockPatternUtils.isLockScreenDisabled(DEMO_USER_ID));
+    }
+
+    @Test
+    public void isLockScreenDisabled_isNotInDemoMode_false() throws Exception {
+        configureTest(false, true, 0);
+        assertFalse(mLockPatternUtils.isLockScreenDisabled(DEMO_USER_ID));
+    }
+}
diff --git a/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java b/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java
index eb2a516..76aa93f 100644
--- a/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java
@@ -24,6 +24,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.SystemClock;
+import android.os.test.TestLooper;
 
 import android.test.suitebuilder.annotation.Suppress;
 import com.android.internal.util.State;
@@ -343,6 +344,100 @@
     }
 
     /**
+     * Tests {@link StateMachine#quitNow()} immediately after {@link StateMachine#start()}.
+     */
+    class StateMachineQuitNowAfterStartTest extends StateMachine {
+        Collection<LogRec> mLogRecs;
+
+        StateMachineQuitNowAfterStartTest(String name, Looper looper) {
+            super(name, looper);
+            mThisSm = this;
+            setDbg(DBG);
+
+            // Setup state machine with 1 state
+            addState(mS1);
+
+            // Set the initial state
+            setInitialState(mS1);
+        }
+
+        @Override
+        public void onQuitting() {
+            tlog("onQuitting");
+            addLogRec(ON_QUITTING);
+            mLogRecs = mThisSm.copyLogRecs();
+            synchronized (mThisSm) {
+                mThisSm.notifyAll();
+            }
+        }
+
+        class S1 extends State {
+            @Override
+            public void enter() {
+                tlog("S1.enter");
+                addLogRec(ENTER);
+            }
+            @Override
+            public void exit() {
+                tlog("S1.exit");
+                addLogRec(EXIT);
+            }
+            @Override
+            public boolean processMessage(Message message) {
+                switch(message.what) {
+                    // Sleep and assume the other messages will be queued up.
+                    case TEST_CMD_1: {
+                        tlog("TEST_CMD_1");
+                        sleep(500);
+                        break;
+                    }
+                    default: {
+                        tlog("default what=" + message.what);
+                        break;
+                    }
+                }
+                return HANDLED;
+            }
+        }
+
+        private StateMachineQuitNowAfterStartTest mThisSm;
+        private S1 mS1 = new S1();
+    }
+
+    /**
+     * When quitNow() is called immediately after start(), the QUIT_CMD gets processed
+     * before the INIT_CMD. This test ensures that the StateMachine can gracefully handle
+     * this sequencing of messages (QUIT before INIT).
+     */
+    @SmallTest
+    public void testStateMachineQuitNowAfterStart() throws Exception {
+        if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
+
+        TestLooper testLooper = new TestLooper();
+        StateMachineQuitNowAfterStartTest smQuitNowAfterStartTest =
+                new StateMachineQuitNowAfterStartTest(
+                        "smQuitNowAfterStartTest", testLooper.getLooper());
+        smQuitNowAfterStartTest.start();
+        smQuitNowAfterStartTest.quitNow();
+        if (smQuitNowAfterStartTest.isDbg()) tlog("testStateMachineQuitNowAfterStart E");
+
+        testLooper.dispatchAll();
+        dumpLogRecs(smQuitNowAfterStartTest.mLogRecs);
+        assertEquals(2, smQuitNowAfterStartTest.mLogRecs.size());
+
+        LogRec lr;
+        Iterator<LogRec> itr = smQuitNowAfterStartTest.mLogRecs.iterator();
+        lr = itr.next();
+        assertEquals(EXIT, lr.getInfo());
+        assertEquals(smQuitNowAfterStartTest.mS1, lr.getState());
+
+        lr = itr.next();
+        assertEquals(ON_QUITTING, lr.getInfo());
+
+        if (smQuitNowAfterStartTest.isDbg()) tlog("testStateMachineQuitNowAfterStart X");
+    }
+
+    /**
      * Test enter/exit can use transitionTo
      */
     class StateMachineEnterExitTransitionToTest extends StateMachine {
diff --git a/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java b/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java
index 7935880..734ebef 100644
--- a/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java
@@ -47,6 +47,7 @@
     private static final int TEST_ARG2 = 182;
     private static final Object TEST_OBJ = "hello";
 
+    @Mock Context mContext;
     @Mock AlarmManager mAlarmManager;
     WakeupMessage mMessage;
     // Make a spy so that we can verify calls to it
@@ -86,13 +87,12 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        Context context = mock(Context.class);
-        when(context.getSystemService(Context.ALARM_SERVICE)).thenReturn(mAlarmManager);
+        when(mContext.getSystemService(Context.ALARM_SERVICE)).thenReturn(mAlarmManager);
         // capture the listener for each AlarmManager.setExact call
         doNothing().when(mAlarmManager).setExact(anyInt(), anyLong(), any(String.class),
                 mListenerCaptor.capture(), any(Handler.class));
 
-        mMessage = new WakeupMessage(context, mHandler, TEST_CMD_NAME, TEST_CMD, TEST_ARG1,
+        mMessage = new WakeupMessage(mContext, mHandler, TEST_CMD_NAME, TEST_CMD, TEST_ARG1,
                 TEST_ARG2, TEST_OBJ);
     }
 
@@ -168,4 +168,19 @@
         verifyMessageDispatchedOnce();
     }
 
+    /**
+     * Verify that a Runnable is scheduled and dispatched.
+     */
+    @Test
+    public void scheduleRunnable() {
+        final long when = 1011;
+        final Runnable runnable = mock(Runnable.class);
+        WakeupMessage dut = new WakeupMessage(mContext, mHandler, TEST_CMD_NAME, runnable);
+        dut.schedule(when);
+        verify(mAlarmManager).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), eq(when),
+                eq(TEST_CMD_NAME), any(AlarmManager.OnAlarmListener.class), eq(mHandler));
+        mListenerCaptor.getValue().onAlarm();
+        verify(runnable, times(1)).run();
+    }
+
 }
diff --git a/data/etc/OWNERS b/data/etc/OWNERS
new file mode 100644
index 0000000..f7a3e1a
--- /dev/null
+++ b/data/etc/OWNERS
@@ -0,0 +1,7 @@
+per-file privapp-permissions-platform.xml = bpoiesz@google.com
+per-file privapp-permissions-platform.xml = fkupolov@google.com
+per-file privapp-permissions-platform.xml = hackbod@android.com
+per-file privapp-permissions-platform.xml = jsharkey@android.com
+per-file privapp-permissions-platform.xml = svetoslavganov@google.com
+per-file privapp-permissions-platform.xml = toddke@google.com
+per-file privapp-permissions-platform.xml = yamasani@google.com
diff --git a/data/etc/framework-sysconfig.xml b/data/etc/framework-sysconfig.xml
index 7fafef7..3a81c13 100644
--- a/data/etc/framework-sysconfig.xml
+++ b/data/etc/framework-sysconfig.xml
@@ -28,4 +28,6 @@
     <backup-transport-whitelisted-service
         service="android/com.android.internal.backup.LocalTransportService" />
 
+    <!-- Whitelist of bundled applications which all handle URLs to their websites by default -->
+    <app-link package="com.android.carrierdefaultapp" />
 </config>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index efed165..a79376c 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -147,6 +147,7 @@
         <permission name="android.permission.MANAGE_USERS"/>
         <permission name="android.permission.MODIFY_PHONE_STATE"/>
         <permission name="android.permission.PERFORM_CDMA_PROVISIONING"/>
+        <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
         <permission name="android.permission.READ_SEARCH_INDEXABLES"/>
         <permission name="android.permission.REBOOT"/>
@@ -163,6 +164,7 @@
         <permission name="android.permission.UPDATE_LOCK"/>
         <permission name="android.permission.WRITE_APN_SETTINGS"/>
         <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+        <permission name="com.android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
         <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
         <permission name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
     </privapp-permissions>
@@ -229,6 +231,7 @@
         <permission name="android.permission.MANAGE_FINGERPRINT"/>
         <permission name="android.permission.MANAGE_USB"/>
         <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.MANAGE_USER_OEM_UNLOCK_STATE" />
         <permission name="android.permission.MASTER_CLEAR"/>
         <permission name="android.permission.MODIFY_PHONE_STATE"/>
         <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
@@ -313,6 +316,7 @@
         <permission name="android.permission.BLUETOOTH_PRIVILEGED"/>
         <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
         <permission name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST"/>
+        <permission name="android.permission.CHANGE_OVERLAY_PACKAGES"/>
         <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
         <permission name="android.permission.CONTROL_VPN"/>
         <permission name="android.permission.DUMP"/>
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 5baa75b..76eb4e6 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -81,18 +81,60 @@
 build-one-font-module :=
 font_src_files :=
 
+################################
+# Copies the font configuration file into system/etc for the product as fonts.xml.
+# In the case where $(ADDITIONAL_FONTS_FILE) is defined, the content of $(ADDITIONAL_FONTS_FILE)
+# is added to the $(AOSP_FONTS_FILE).
+include $(CLEAR_VARS)
+
+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)
+
+include $(BUILD_PREBUILT)
 
 # Run sanity tests on fonts on checkbuild
 checkbuild: fontchain_lint
 
-FONTCHAIN_LINTER := frameworks/base/tools/fonts/fontchain_lint.py
+FONTCHAIN_LINTER := $(HOST_OUT_EXECUTABLES)/fontchain_linter
 ifeq ($(MINIMAL_FONT_FOOTPRINT),true)
 CHECK_EMOJI := false
 else
 CHECK_EMOJI := true
 endif
 
+fontchain_lint_timestamp := $(call intermediates-dir-for,PACKAGING,fontchain_lint)/stamp
+
 .PHONY: fontchain_lint
-fontchain_lint: $(FONTCHAIN_LINTER) $(TARGET_OUT)/etc/fonts.xml $(PRODUCT_OUT)/system.img
-	PYTHONPATH=$$PYTHONPATH:external/fonttools/Lib \
-	python $(FONTCHAIN_LINTER) $(TARGET_OUT) $(CHECK_EMOJI) external/unicode
+fontchain_lint: $(fontchain_lint_timestamp)
+
+fontchain_lint_deps := \
+    external/unicode/DerivedAge.txt \
+    external/unicode/emoji-data.txt \
+    external/unicode/emoji-sequences.txt \
+    external/unicode/emoji-variation-sequences.txt \
+    external/unicode/emoji-zwj-sequences.txt \
+    external/unicode/additions/emoji-data.txt \
+    external/unicode/additions/emoji-sequences.txt \
+    external/unicode/additions/emoji-zwj-sequences.txt \
+
+$(fontchain_lint_timestamp): $(FONTCHAIN_LINTER) $(TARGET_OUT)/etc/fonts.xml $(PRODUCT_OUT)/system.img $(fontchain_lint_deps)
+	@echo Running fontchain lint
+	$(FONTCHAIN_LINTER) $(TARGET_OUT) $(CHECK_EMOJI) external/unicode
+	touch $@
diff --git a/data/fonts/fonts.mk b/data/fonts/fonts.mk
index 23c54ae..e884f2f 100644
--- a/data/fonts/fonts.mk
+++ b/data/fonts/fonts.mk
@@ -14,9 +14,7 @@
 
 # Warning: this is actually a product definition, to be inherited from
 
-PRODUCT_COPY_FILES := \
-    frameworks/base/data/fonts/fonts.xml:$(TARGET_COPY_OUT_SYSTEM)/etc/fonts.xml
-
 PRODUCT_PACKAGES := \
     DroidSansMono.ttf \
-    AndroidClock.ttf
+    AndroidClock.ttf \
+    fonts.xml
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 318353f..ae93608 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -51,10 +51,13 @@
         <font weight="300" style="italic">RobotoCondensed-LightItalic.ttf</font>
         <font weight="400" style="normal">RobotoCondensed-Regular.ttf</font>
         <font weight="400" style="italic">RobotoCondensed-Italic.ttf</font>
+        <font weight="500" style="normal">RobotoCondensed-Medium.ttf</font>
+        <font weight="500" style="italic">RobotoCondensed-MediumItalic.ttf</font>
         <font weight="700" style="normal">RobotoCondensed-Bold.ttf</font>
         <font weight="700" style="italic">RobotoCondensed-BoldItalic.ttf</font>
     </family>
     <alias name="sans-serif-condensed-light" to="sans-serif-condensed" weight="300" />
+    <alias name="sans-serif-condensed-medium" to="sans-serif-condensed" weight="500" />
 
     <family name="serif">
         <font weight="400" style="normal">NotoSerif-Regular.ttf</font>
diff --git a/data/sounds/AudioTv.mk b/data/sounds/AudioTv.mk
deleted file mode 100644
index ee37cb9..0000000
--- a/data/sounds/AudioTv.mk
+++ /dev/null
@@ -1,125 +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.
-
-LOCAL_PATH := frameworks/base/data/sounds
-
-PRODUCT_COPY_FILES += \
-    $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \
-    $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \
-    $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \
-    $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \
-    $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \
-    $(LOCAL_PATH)/Alarm_Rooster_02.ogg:system/media/audio/alarms/Alarm_Rooster_02.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Argon.ogg:system/media/audio/alarms/Argon.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Barium.ogg:system/media/audio/alarms/Barium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:system/media/audio/alarms/Cesium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Fermium.ogg:system/media/audio/alarms/Fermium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Hassium.ogg:system/media/audio/alarms/Hassium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Helium.ogg:system/media/audio/alarms/Helium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Neon.ogg:system/media/audio/alarms/Neon.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Neptunium.ogg:system/media/audio/alarms/Neptunium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Nobelium.ogg:system/media/audio/alarms/Nobelium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:system/media/audio/alarms/Osmium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:system/media/audio/alarms/Platinum.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:system/media/audio/alarms/Plutonium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Promethium.ogg:system/media/audio/alarms/Promethium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Scandium.ogg:system/media/audio/alarms/Scandium.ogg \
-    $(LOCAL_PATH)/effects/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \
-    $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
-    $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
-    $(LOCAL_PATH)/effects/ogg/Effect_Tick_48k.ogg:system/media/audio/ui/Effect_Tick.ogg \
-    $(LOCAL_PATH)/effects/ogg/KeypressDelete_120_48k.ogg:system/media/audio/ui/KeypressDelete.ogg \
-    $(LOCAL_PATH)/effects/ogg/KeypressInvalid_120_48k.ogg:system/media/audio/ui/KeypressInvalid.ogg \
-    $(LOCAL_PATH)/effects/ogg/KeypressReturn_120_48k.ogg:system/media/audio/ui/KeypressReturn.ogg \
-    $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120_48k.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
-    $(LOCAL_PATH)/effects/ogg/KeypressStandard_120_48k.ogg:system/media/audio/ui/KeypressStandard.ogg \
-    $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
-    $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
-    $(LOCAL_PATH)/effects/ogg/Trusted_48k.ogg:system/media/audio/ui/Trusted.ogg \
-    $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
-    $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
-    $(LOCAL_PATH)/effects/ogg/VideoRecord_48k.ogg:system/media/audio/ui/VideoRecord.ogg \
-    $(LOCAL_PATH)/effects/ogg/VideoStop_48k.ogg:system/media/audio/ui/VideoStop.ogg \
-    $(LOCAL_PATH)/effects/ogg/WirelessChargingStarted.ogg:system/media/audio/ui/WirelessChargingStarted.ogg \
-    $(LOCAL_PATH)/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg \
-    $(LOCAL_PATH)/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg \
-    $(LOCAL_PATH)/F1_New_SMS.ogg:system/media/audio/notifications/F1_New_SMS.ogg \
-    $(LOCAL_PATH)/notifications/Aldebaran.ogg:system/media/audio/notifications/Aldebaran.ogg \
-    $(LOCAL_PATH)/notifications/Altair.ogg:system/media/audio/notifications/Altair.ogg \
-    $(LOCAL_PATH)/notifications/Antares.ogg:system/media/audio/notifications/Antares.ogg \
-    $(LOCAL_PATH)/notifications/arcturus.ogg:system/media/audio/notifications/arcturus.ogg \
-    $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
-    $(LOCAL_PATH)/notifications/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \
-    $(LOCAL_PATH)/notifications/Canopus.ogg:system/media/audio/notifications/Canopus.ogg \
-    $(LOCAL_PATH)/notifications/Castor.ogg:system/media/audio/notifications/Castor.ogg \
-    $(LOCAL_PATH)/notifications/Cricket.ogg:system/media/audio/notifications/Cricket.ogg \
-    $(LOCAL_PATH)/notifications/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \
-    $(LOCAL_PATH)/notifications/Doink.ogg:system/media/audio/notifications/Doink.ogg \
-    $(LOCAL_PATH)/notifications/Drip.ogg:system/media/audio/notifications/Drip.ogg \
-    $(LOCAL_PATH)/notifications/Electra.ogg:system/media/audio/notifications/Electra.ogg \
-    $(LOCAL_PATH)/notifications/Fomalhaut.ogg:system/media/audio/notifications/Fomalhaut.ogg \
-    $(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
-    $(LOCAL_PATH)/notifications/Merope.ogg:system/media/audio/notifications/Merope.ogg \
-    $(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Antimony.ogg:system/media/audio/notifications/Antimony.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Argon.ogg:system/media/audio/notifications/Argon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:system/media/audio/notifications/Bellatrix.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Beryllium.ogg:system/media/audio/notifications/Beryllium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \
-    $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Cobalt.ogg:system/media/audio/notifications/Cobalt.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Fluorine.ogg:system/media/audio/notifications/Fluorine.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Gallium.ogg:system/media/audio/notifications/Gallium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Helium.ogg:system/media/audio/notifications/Helium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Iridium.ogg:system/media/audio/notifications/Iridium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Krypton.ogg:system/media/audio/notifications/Krypton.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Palladium.ogg:system/media/audio/notifications/Palladium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Radon.ogg:system/media/audio/notifications/Radon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Rubidium.ogg:system/media/audio/notifications/Rubidium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Selenium.ogg:system/media/audio/notifications/Selenium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Strontium.ogg:system/media/audio/notifications/Strontium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:system/media/audio/notifications/Syrma.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:system/media/audio/notifications/Talitha.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Thallium.ogg:system/media/audio/notifications/Thallium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Xenon.ogg:system/media/audio/notifications/Xenon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Zirconium.ogg:system/media/audio/notifications/Zirconium.ogg \
-    $(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \
-    $(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \
-    $(LOCAL_PATH)/notifications/Plastic_Pipe.ogg:system/media/audio/notifications/Plastic_Pipe.ogg \
-    $(LOCAL_PATH)/notifications/regulus.ogg:system/media/audio/notifications/regulus.ogg \
-    $(LOCAL_PATH)/notifications/sirius.ogg:system/media/audio/notifications/sirius.ogg \
-    $(LOCAL_PATH)/notifications/Sirrah.ogg:system/media/audio/notifications/Sirrah.ogg \
-    $(LOCAL_PATH)/notifications/SpaceSeed.ogg:system/media/audio/notifications/SpaceSeed.ogg \
-    $(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
-    $(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
-    $(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg \
-    $(LOCAL_PATH)/notifications/vega.ogg:system/media/audio/notifications/vega.ogg
diff --git a/drm/java/android/drm/DrmManagerClient.java b/drm/java/android/drm/DrmManagerClient.java
index 5973d3e..76eab4a 100644
--- a/drm/java/android/drm/DrmManagerClient.java
+++ b/drm/java/android/drm/DrmManagerClient.java
@@ -262,7 +262,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/drm/java/android/drm/DrmUtils.java b/drm/java/android/drm/DrmUtils.java
index 2a86996..60ee6d9 100644
--- a/drm/java/android/drm/DrmUtils.java
+++ b/drm/java/android/drm/DrmUtils.java
@@ -17,6 +17,7 @@
 package android.drm;
 
 import java.io.BufferedInputStream;
+import java.io.Closeable;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -79,26 +80,16 @@
         file.delete();
     }
 
-    private static void quietlyDispose(InputStream stream) {
+    private static void quietlyDispose(Closeable closable) {
         try {
-            if (null != stream) {
-                stream.close();
+            if (null != closable) {
+                closable.close();
             }
         } catch (IOException e) {
             // no need to care, at least as of now
         }
     }
 
-    private static void quietlyDispose(OutputStream stream) {
-        try {
-            if (null != stream) {
-                stream.close();
-            }
-        } catch (IOException e) {
-            // no need to care
-        }
-    }
-
     /**
      * Gets an instance of {@link DrmUtils.ExtendedMetadataParser}, which can be used to parse
      * extended metadata embedded in DRM constraint information.
diff --git a/graphics/java/android/graphics/ColorFilter.java b/graphics/java/android/graphics/ColorFilter.java
index 0ca3729..b24b988 100644
--- a/graphics/java/android/graphics/ColorFilter.java
+++ b/graphics/java/android/graphics/ColorFilter.java
@@ -14,19 +14,22 @@
  * limitations under the License.
  */
 
-// This file was generated from the C++ include file: SkColorFilter.h
-// Any changes made to this file will be discarded by the build.
-// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, 
-// or one of the auxilary file specifications in device/tools/gluemaker.
-
 package android.graphics;
 
+import libcore.util.NativeAllocationRegistry;
+
 /**
  * A color filter can be used with a {@link Paint} to modify the color of
  * each pixel drawn with that paint. This is an abstract class that should
  * never be used directly.
  */
 public class ColorFilter {
+
+    private static class NoImagePreloadHolder {
+        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+                ColorFilter.class.getClassLoader(), nativeGetFinalizer(), 50);
+    }
+
     /**
      * @deprecated Use subclass constructors directly instead.
      */
@@ -34,9 +37,11 @@
     public ColorFilter() {}
 
     /**
-     * Holds the pointer to the native SkColorFilter instance.
+     * Current native SkColorFilter instance.
      */
     private long mNativeInstance;
+    // Runnable to do immediate destruction
+    private Runnable mCleaner;
 
     long createNativeInstance() {
         return 0;
@@ -44,35 +49,28 @@
 
     void discardNativeInstance() {
         if (mNativeInstance != 0) {
-            nSafeUnref(mNativeInstance);
+            mCleaner.run();
+            mCleaner = null;
             mNativeInstance = 0;
         }
     }
 
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            if (mNativeInstance != 0) {
-                nSafeUnref(mNativeInstance);
-            }
-            mNativeInstance = -1;
-        } finally {
-            super.finalize();
-        }
-    }
-
     /** @hide */
     public long getNativeInstance() {
-        if (mNativeInstance == -1) {
-            throw new IllegalStateException("attempting to use a finalized ColorFilter");
-        }
-
         if (mNativeInstance == 0) {
             mNativeInstance = createNativeInstance();
+
+            if (mNativeInstance != 0) {
+                // Note: we must check for null here, since it's possible for createNativeInstance()
+                // to return nullptr if the native SkColorFilter would be a no-op at draw time.
+                // See native implementations of subclass create methods for more info.
+                mCleaner = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
+                        this, mNativeInstance);
+            }
         }
         return mNativeInstance;
 
     }
 
-    static native void nSafeUnref(long native_instance);
+    private static native long nativeGetFinalizer();
 }
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index a226e85..e3527e3 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -662,6 +662,15 @@
     public static final int DEPTH_POINT_CLOUD = 0x101;
 
     /**
+     * Unprocessed implementation-dependent raw
+     * depth measurements, opaque with 16 bit
+     * samples.
+     *
+     * @hide
+     */
+    public static final int RAW_DEPTH = 0x1002;
+
+    /**
      * Android private opaque image format.
      * <p>
      * The choices of the actual format and pixel data layout are entirely up to
@@ -723,6 +732,7 @@
                 return 24;
             case FLEX_RGBA_8888:
                 return 32;
+            case RAW_DEPTH:
             case RAW_SENSOR:
                 return 16;
             case RAW10:
@@ -765,6 +775,7 @@
             case DEPTH16:
             case DEPTH_POINT_CLOUD:
             case PRIVATE:
+            case RAW_DEPTH:
                 return true;
         }
 
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index f931d21..e1eb69a 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -80,6 +80,11 @@
     private String      mFontFeatureSettings;
     private String      mFontVariationSettings;
 
+    private float mShadowLayerRadius;
+    private float mShadowLayerDx;
+    private float mShadowLayerDy;
+    private int mShadowLayerColor;
+
     private static final Object sCacheLock = new Object();
 
     /**
@@ -530,6 +535,11 @@
         setElegantTextHeight(false);
         mFontFeatureSettings = null;
         mFontVariationSettings = null;
+
+        mShadowLayerRadius = 0.0f;
+        mShadowLayerDx = 0.0f;
+        mShadowLayerDy = 0.0f;
+        mShadowLayerColor = 0;
     }
 
     /**
@@ -567,6 +577,54 @@
         mLocales = paint.mLocales;
         mFontFeatureSettings = paint.mFontFeatureSettings;
         mFontVariationSettings = paint.mFontVariationSettings;
+
+        mShadowLayerRadius = paint.mShadowLayerRadius;
+        mShadowLayerDx = paint.mShadowLayerDx;
+        mShadowLayerDy = paint.mShadowLayerDy;
+        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 */
@@ -758,6 +816,27 @@
     }
 
     /**
+     * Distance from top of the underline to the baseline. Positive values mean below the baseline.
+     * This method returns where the underline should be drawn independent of if the underlineText
+     * bit is set at the moment.
+     * @hide
+     */
+    public float getUnderlinePosition() {
+        // kStdUnderline_Offset = 1/9, defined in SkTextFormatParams.h
+        // TODO: replace with position from post and MVAR tables (b/62353930).
+        return (1.0f / 9.0f) * getTextSize();
+    }
+
+    /**
+     * @hide
+     */
+    public float getUnderlineThickness() {
+        // kStdUnderline_Thickness = 1/18, defined in SkTextFormatParams.h
+        // TODO: replace with thickness from post and MVAR tables (b/62353930).
+        return (1.0f / 18.0f) * getTextSize();
+    }
+
+    /**
      * Helper for setFlags(), setting or clearing the UNDERLINE_TEXT_FLAG bit
      *
      * @param underlineText true to set the underlineText bit in the paint's
@@ -1238,6 +1317,10 @@
      * opaque, or the alpha from the shadow color if not.
      */
     public void setShadowLayer(float radius, float dx, float dy, int shadowColor) {
+      mShadowLayerRadius = radius;
+      mShadowLayerDx = dx;
+      mShadowLayerDy = dy;
+      mShadowLayerColor = shadowColor;
       nSetShadowLayer(mNativePaint, radius, dx, dy, shadowColor);
     }
 
@@ -2798,7 +2881,7 @@
     private static native int nGetFontMetricsInt(long paintPtr,
             long typefacePtr, FontMetricsInt fmi);
 
-    
+
     // ---------------- @CriticalNative ------------------------
 
     @CriticalNative
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index 8616d58..1d0cfa5 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -289,6 +289,9 @@
     }
 
     private void updateLayerBounds(Rect bounds) {
+        if (bounds.isEmpty()) {
+            return;
+        }
         try {
             suspendChildInvalidation();
             updateLayerBoundsInternal(bounds);
@@ -1109,4 +1112,4 @@
             mCheckedStateful = false;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 8ce7ed0..c329918 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -44,6 +44,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.Arrays;
 import java.util.Objects;
 
 /**
@@ -493,7 +494,7 @@
             case TYPE_DATA:
                 return getDataLength() == otherIcon.getDataLength()
                         && getDataOffset() == otherIcon.getDataOffset()
-                        && getDataBytes() == otherIcon.getDataBytes();
+                        && Arrays.equals(getDataBytes(), otherIcon.getDataBytes());
             case TYPE_RESOURCE:
                 return getResId() == otherIcon.getResId()
                         && Objects.equals(getResPackage(), otherIcon.getResPackage());
@@ -804,6 +805,43 @@
     };
 
     /**
+     * Scale down a bitmap to a given max width and max height. The scaling will be done in a uniform way
+     * @param bitmap the bitmap to scale down
+     * @param maxWidth the maximum width allowed
+     * @param maxHeight the maximum height allowed
+     *
+     * @return the scaled bitmap if necessary or the original bitmap if no scaling was needed
+     * @hide
+     */
+    public static Bitmap scaleDownIfNecessary(Bitmap bitmap, int maxWidth, int maxHeight) {
+        int bitmapWidth = bitmap.getWidth();
+        int bitmapHeight = bitmap.getHeight();
+        if (bitmapWidth > maxWidth || bitmapHeight > maxHeight) {
+            float scale = Math.min((float) maxWidth / bitmapWidth,
+                    (float) maxHeight / bitmapHeight);
+            bitmap = Bitmap.createScaledBitmap(bitmap, (int) (scale * bitmapWidth),
+                    (int) (scale * bitmapHeight), true /* filter */);
+        }
+        return bitmap;
+    }
+
+    /**
+     * Scale down this icon to a given max width and max height.
+     * The scaling will be done in a uniform way and currently only bitmaps are supported.
+     * @param maxWidth the maximum width allowed
+     * @param maxHeight the maximum height allowed
+     *
+     * @hide
+     */
+    public void scaleDownIfNecessary(int maxWidth, int maxHeight) {
+        if (mType != TYPE_BITMAP && mType != TYPE_ADAPTIVE_BITMAP) {
+            return;
+        }
+        Bitmap bitmap = getBitmap();
+        setBitmap(scaleDownIfNecessary(bitmap, maxWidth, maxHeight));
+    }
+
+    /**
      * Implement this interface to receive a callback when
      * {@link #loadDrawableAsync(Context, OnDrawableLoadedListener, Handler) loadDrawableAsync}
      * is finished and your Drawable is ready.
diff --git a/graphics/java/android/graphics/drawable/TransitionDrawable.java b/graphics/java/android/graphics/drawable/TransitionDrawable.java
index 0122338..3dfd680 100644
--- a/graphics/java/android/graphics/drawable/TransitionDrawable.java
+++ b/graphics/java/android/graphics/drawable/TransitionDrawable.java
@@ -118,6 +118,18 @@
     }
 
     /**
+     * Show the second layer on top of the first layer immediately
+     *
+     * @hide
+     */
+    public void showSecondLayer() {
+        mAlpha = 255;
+        mReverse = false;
+        mTransitionState = TRANSITION_NONE;
+        invalidateSelf();
+    }
+
+    /**
      * Show only the first layer.
      */
     public void resetTransition() {
diff --git a/graphics/java/android/graphics/pdf/PdfDocument.java b/graphics/java/android/graphics/pdf/PdfDocument.java
index d603436..1b8336f 100644
--- a/graphics/java/android/graphics/pdf/PdfDocument.java
+++ b/graphics/java/android/graphics/pdf/PdfDocument.java
@@ -202,7 +202,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             dispose();
         } finally {
             super.finalize();
diff --git a/graphics/java/android/graphics/pdf/PdfEditor.java b/graphics/java/android/graphics/pdf/PdfEditor.java
index cd1f8de..dc4b117 100644
--- a/graphics/java/android/graphics/pdf/PdfEditor.java
+++ b/graphics/java/android/graphics/pdf/PdfEditor.java
@@ -23,6 +23,7 @@
 import android.graphics.Rect;
 import android.os.ParcelFileDescriptor;
 import android.system.ErrnoException;
+import android.system.Os;
 import android.system.OsConstants;
 import dalvik.system.CloseGuard;
 import libcore.io.IoUtils;
@@ -72,8 +73,8 @@
 
         final long size;
         try {
-            Libcore.os.lseek(input.getFileDescriptor(), 0, OsConstants.SEEK_SET);
-            size = Libcore.os.fstat(input.getFileDescriptor()).st_size;
+            Os.lseek(input.getFileDescriptor(), 0, OsConstants.SEEK_SET);
+            size = Os.fstat(input.getFileDescriptor()).st_size;
         } catch (ErrnoException ee) {
             throw new IllegalArgumentException("file descriptor not seekable");
         }
@@ -270,7 +271,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             if (mInput != null) {
                 doClose();
             }
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index 7b7a290..29e1ea0f 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -26,10 +26,10 @@
 import android.graphics.Rect;
 import android.os.ParcelFileDescriptor;
 import android.system.ErrnoException;
+import android.system.Os;
 import android.system.OsConstants;
 import com.android.internal.util.Preconditions;
 import dalvik.system.CloseGuard;
-import libcore.io.Libcore;
 
 import java.io.IOException;
 import java.lang.annotation.Retention;
@@ -154,8 +154,8 @@
 
         final long size;
         try {
-            Libcore.os.lseek(input.getFileDescriptor(), 0, OsConstants.SEEK_SET);
-            size = Libcore.os.fstat(input.getFileDescriptor()).st_size;
+            Os.lseek(input.getFileDescriptor(), 0, OsConstants.SEEK_SET);
+            size = Os.fstat(input.getFileDescriptor()).st_size;
         } catch (ErrnoException ee) {
             throw new IllegalArgumentException("file descriptor not seekable");
         }
@@ -230,7 +230,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             if (mInput != null) {
                 doClose();
             }
@@ -444,7 +447,10 @@
         @Override
         protected void finalize() throws Throwable {
             try {
-                mCloseGuard.warnIfOpen();
+                if (mCloseGuard != null) {
+                    mCloseGuard.warnIfOpen();
+                }
+
                 if (mNativePage != 0) {
                     doClose();
                 }
diff --git a/keystore/java/android/security/KeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java
index d023866..d5b34c4 100644
--- a/keystore/java/android/security/KeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/KeyPairGeneratorSpec.java
@@ -260,13 +260,13 @@
      * Example:
      *
      * <pre class="prettyprint">
-     * Calendar start = new Calendar();
-     * Calendar end = new Calendar();
-     * end.add(1, Calendar.YEAR);
+     * Calendar start = Calendar.getInstance();
+     * Calendar end = Calendar.getInstance();
+     * end.add(Calendar.YEAR, 1);
      *
      * KeyPairGeneratorSpec spec =
      *         new KeyPairGeneratorSpec.Builder(mContext).setAlias(&quot;myKey&quot;)
-     *                 .setSubject(new X500Principal(&quot;CN=myKey&quot;)).setSerial(BigInteger.valueOf(1337))
+     *                 .setSubject(new X500Principal(&quot;CN=myKey&quot;)).setSerialNumber(BigInteger.valueOf(1337))
      *                 .setStartDate(start.getTime()).setEndDate(end.getTime()).build();
      * </pre>
      *
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index bfd1422..ccf9de0 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -341,12 +341,14 @@
         }
     }
 
-    public boolean grant(String key, int uid) {
+    public String grant(String key, int uid) {
         try {
-            return mBinder.grant(key, uid) == NO_ERROR;
+            String grantAlias =  mBinder.grant(key, uid);
+            if (grantAlias == "") return null;
+            return grantAlias;
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
-            return false;
+            return null;
         }
     }
 
diff --git a/legacy-test/src/com/android/internal/util/Predicate.java b/legacy-test/src/com/android/internal/util/Predicate.java
index 1b5eaff..e87f489 100644
--- a/legacy-test/src/com/android/internal/util/Predicate.java
+++ b/legacy-test/src/com/android/internal/util/Predicate.java
@@ -27,6 +27,7 @@
  * strongly encouraged to state this fact clearly in their API documentation.
  *
  * @deprecated Use {@code java.util.function.Predicate} instead.
+ *             This must not be used outside frameworks/base/test-runner.
  */
 @Deprecated
 public interface Predicate<T> {
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index e764034..c4c14c9e 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -79,7 +79,7 @@
                 "libutils",
             ],
             shared_libs: [
-                "libz-host",
+                "libz",
             ],
         },
         windows: {
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 0782269..7a0ef2b 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -59,7 +59,6 @@
 #endif
 
 #define IDMAP_MAGIC             0x504D4449
-#define IDMAP_CURRENT_VERSION   0x00000001
 
 #define APP_PACKAGE_ID      0x7f
 #define SYS_PACKAGE_ID      0x01
@@ -246,11 +245,11 @@
     }
 
     const uint32_t version = htodl(*(reinterpret_cast<const uint32_t*>(idmap) + 1));
-    if (version != IDMAP_CURRENT_VERSION) {
+    if (version != ResTable::IDMAP_CURRENT_VERSION) {
         // We are strict about versions because files with this format are
         // auto-generated and don't need backwards compatibility.
         ALOGW("idmap: version mismatch in header (is 0x%08x, expected 0x%08x)",
-                version, IDMAP_CURRENT_VERSION);
+                version, ResTable::IDMAP_CURRENT_VERSION);
         return false;
     }
     return true;
@@ -6855,7 +6854,7 @@
 
     uint32_t* data = (uint32_t*)*outData;
     *data++ = htodl(IDMAP_MAGIC);
-    *data++ = htodl(IDMAP_CURRENT_VERSION);
+    *data++ = htodl(ResTable::IDMAP_CURRENT_VERSION);
     *data++ = htodl(targetCrc);
     *data++ = htodl(overlayCrc);
     const char* paths[] = { targetPath, overlayPath };
diff --git a/libs/androidfw/ZipUtils.cpp b/libs/androidfw/ZipUtils.cpp
index 5abfc8e..5d243da 100644
--- a/libs/androidfw/ZipUtils.cpp
+++ b/libs/androidfw/ZipUtils.cpp
@@ -20,10 +20,11 @@
 
 #define LOG_TAG "ziputil"
 
+#include "android-base/file.h"
 #include <androidfw/ZipUtils.h>
-#include <androidfw/ZipFileRO.h>
 #include <utils/Log.h>
 #include <utils/Compat.h>
+#include <ziparchive/zip_archive.h>
 
 #include <stdlib.h>
 #include <string.h>
@@ -33,211 +34,121 @@
 
 using namespace android;
 
-static inline unsigned long get4LE(const unsigned char* buf) {
-    return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
-}
-
-
-static const unsigned long kReadBufSize = 32768;
-
-/*
- * Utility function that expands zip/gzip "deflate" compressed data
- * into a buffer.
- *
- * (This is a clone of the previous function, but it takes a FILE* instead
- * of an fd.  We could pass fileno(fd) to the above, but we can run into
- * trouble when "fp" has a different notion of what fd's file position is.)
- *
- * "fp" is an open file positioned at the start of the "deflate" data
- * "buf" must hold at least "uncompressedLen" bytes.
- */
-/*static*/ template<typename T> bool inflateToBuffer(T& reader, void* buf,
-    long uncompressedLen, long compressedLen)
-{
-    bool result = false;
-
-    z_stream zstream;
-    int zerr;
-    unsigned long compRemaining;
-
-    assert(uncompressedLen >= 0);
-    assert(compressedLen >= 0);
-
-    compRemaining = compressedLen;
-
-    /*
-     * Initialize the zlib stream.
-     */
-    memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = NULL;
-    zstream.avail_in = 0;
-    zstream.next_out = (Bytef*) buf;
-    zstream.avail_out = uncompressedLen;
-    zstream.data_type = Z_UNKNOWN;
-
-    /*
-     * Use the undocumented "negative window bits" feature to tell zlib
-     * that there's no zlib header waiting for it.
-     */
-    zerr = inflateInit2(&zstream, -MAX_WBITS);
-    if (zerr != Z_OK) {
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
+// TODO: This can go away once the only remaining usage in aapt goes away.
+class FileReader : public zip_archive::Reader {
+  public:
+    FileReader(FILE* fp) : Reader(), mFp(fp), mCurrentOffset(0) {
     }
 
-    /*
-     * Loop while we have data.
-     */
-    do {
-        unsigned long getSize;
-
-        /* read as much as we can */
-        if (zstream.avail_in == 0) {
-            getSize = (compRemaining > kReadBufSize) ?
-                        kReadBufSize : compRemaining;
-            ALOGV("+++ reading %ld bytes (%ld left)\n",
-                getSize, compRemaining);
-
-            unsigned char* nextBuffer = NULL;
-            const unsigned long nextSize = reader.read(&nextBuffer, getSize);
-
-            if (nextSize < getSize || nextBuffer == NULL) {
-                ALOGD("inflate read failed (%ld vs %ld)\n", nextSize, getSize);
-                goto z_bail;
+    bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const {
+        // Data is usually requested sequentially, so this helps avoid pointless
+        // fseeks every time we perform a read. There's an impedence mismatch
+        // here because the original API was designed around pread and pwrite.
+        if (offset != mCurrentOffset) {
+            if (fseek(mFp, offset, SEEK_SET) != 0) {
+                return false;
             }
 
-            compRemaining -= nextSize;
-
-            zstream.next_in = nextBuffer;
-            zstream.avail_in = nextSize;
+            mCurrentOffset = offset;
         }
 
-        /* uncompress the data */
-        zerr = inflate(&zstream, Z_NO_FLUSH);
-        if (zerr != Z_OK && zerr != Z_STREAM_END) {
-            ALOGD("zlib inflate call failed (zerr=%d)\n", zerr);
-            goto z_bail;
+        size_t read = fread(buf, 1, len, mFp);
+        if (read != len) {
+            return false;
         }
 
-        /* output buffer holds all, so no need to write the output */
-    } while (zerr == Z_OK);
-
-    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
-
-    if ((long) zstream.total_out != uncompressedLen) {
-        ALOGW("Size mismatch on inflated file (%ld vs %ld)\n",
-            zstream.total_out, uncompressedLen);
-        goto z_bail;
+        mCurrentOffset += read;
+        return true;
     }
 
-    // success!
-    result = true;
-
-z_bail:
-    inflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-    return result;
-}
-
-class FileReader {
-public:
-   explicit FileReader(FILE* fp) :
-       mFp(fp), mReadBuf(new unsigned char[kReadBufSize])
-   {
-   }
-
-   ~FileReader() {
-       delete[] mReadBuf;
-   }
-
-   long read(unsigned char** nextBuffer, long readSize) const {
-       *nextBuffer = mReadBuf;
-       return fread(mReadBuf, 1, readSize, mFp);
-   }
-
-   FILE* mFp;
-   unsigned char* mReadBuf;
+  private:
+    FILE* mFp;
+    mutable uint32_t mCurrentOffset;
 };
 
-class FdReader {
-public:
-   explicit FdReader(int fd) :
-       mFd(fd), mReadBuf(new unsigned char[kReadBufSize])
-   {
-   }
+class FdReader : public zip_archive::Reader {
+  public:
+    explicit FdReader(int fd) : mFd(fd) {
+    }
 
-   ~FdReader() {
-       delete[] mReadBuf;
-   }
+    bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const {
+      return android::base::ReadFullyAtOffset(mFd, buf, len, static_cast<off_t>(offset));
+    }
 
-   long read(unsigned char** nextBuffer, long readSize) const {
-       *nextBuffer = mReadBuf;
-       return TEMP_FAILURE_RETRY(::read(mFd, mReadBuf, readSize));
-   }
-
-   int mFd;
-   unsigned char* mReadBuf;
+  private:
+    const int mFd;
 };
 
-class BufferReader {
-public:
-    BufferReader(void* input, size_t inputSize) :
-        mInput(reinterpret_cast<unsigned char*>(input)),
-        mInputSize(inputSize),
-        mBufferReturned(false)
-    {
+class BufferReader : public zip_archive::Reader {
+  public:
+    BufferReader(const void* input, size_t inputSize) : Reader(),
+        mInput(reinterpret_cast<const uint8_t*>(input)),
+        mInputSize(inputSize) {
     }
 
-    long read(unsigned char** nextBuffer, long /*readSize*/) {
-        if (!mBufferReturned) {
-            mBufferReturned = true;
-            *nextBuffer = mInput;
-            return mInputSize;
+    bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const {
+        if (offset + len > mInputSize) {
+            return false;
         }
 
-        *nextBuffer = NULL;
-        return 0;
+        memcpy(buf, mInput + offset, len);
+        return true;
     }
 
-    unsigned char* mInput;
+  private:
+    const uint8_t* mInput;
     const size_t mInputSize;
-    bool mBufferReturned;
+};
+
+class BufferWriter : public zip_archive::Writer {
+  public:
+    BufferWriter(void* output, size_t outputSize) : Writer(),
+        mOutput(reinterpret_cast<uint8_t*>(output)), mOutputSize(outputSize), mBytesWritten(0) {
+    }
+
+    bool Append(uint8_t* buf, size_t bufSize) override {
+        if (mBytesWritten + bufSize > mOutputSize) {
+            return false;
+        }
+
+        memcpy(mOutput + mBytesWritten, buf, bufSize);
+        mBytesWritten += bufSize;
+        return true;
+    }
+
+  private:
+    uint8_t* const mOutput;
+    const size_t mOutputSize;
+    size_t mBytesWritten;
 };
 
 /*static*/ bool ZipUtils::inflateToBuffer(FILE* fp, void* buf,
     long uncompressedLen, long compressedLen)
 {
     FileReader reader(fp);
-    return ::inflateToBuffer<FileReader>(reader, buf,
-        uncompressedLen, compressedLen);
+    BufferWriter writer(buf, uncompressedLen);
+    return (zip_archive::Inflate(reader, compressedLen, uncompressedLen, &writer, nullptr) == 0);
 }
 
 /*static*/ bool ZipUtils::inflateToBuffer(int fd, void* buf,
     long uncompressedLen, long compressedLen)
 {
     FdReader reader(fd);
-    return ::inflateToBuffer<FdReader>(reader, buf,
-        uncompressedLen, compressedLen);
+    BufferWriter writer(buf, uncompressedLen);
+    return (zip_archive::Inflate(reader, compressedLen, uncompressedLen, &writer, nullptr) == 0);
 }
 
-/*static*/ bool ZipUtils::inflateToBuffer(void* in, void* buf,
+/*static*/ bool ZipUtils::inflateToBuffer(const void* in, void* buf,
     long uncompressedLen, long compressedLen)
 {
     BufferReader reader(in, compressedLen);
-    return ::inflateToBuffer<BufferReader>(reader, buf,
-        uncompressedLen, compressedLen);
+    BufferWriter writer(buf, uncompressedLen);
+    return (zip_archive::Inflate(reader, compressedLen, uncompressedLen, &writer, nullptr) == 0);
 }
 
-
+static inline unsigned long get4LE(const unsigned char* buf) {
+    return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+}
 
 /*
  * Look at the contents of a gzip archive.  We want to know where the
@@ -275,7 +186,7 @@
     /* quick sanity checks */
     if (method == EOF || flags == EOF)
         return false;
-    if (method != ZipFileRO::kCompressDeflated)
+    if (method != kCompressDeflated)
         return false;
 
     /* skip over 4 bytes of mod time, 1 byte XFL, 1 byte OS */
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 7a6e37d..66c66c2 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -1933,6 +1933,7 @@
             void** outData, size_t* outSize) const;
 
     static const size_t IDMAP_HEADER_SIZE_BYTES = 4 * sizeof(uint32_t) + 2 * 256;
+    static const uint32_t IDMAP_CURRENT_VERSION = 0x00000001;
 
     // Retrieve idmap meta-data.
     //
diff --git a/libs/androidfw/include/androidfw/StringPiece.h b/libs/androidfw/include/androidfw/StringPiece.h
index a873d66..99b4245 100644
--- a/libs/androidfw/include/androidfw/StringPiece.h
+++ b/libs/androidfw/include/androidfw/StringPiece.h
@@ -37,6 +37,7 @@
  public:
   using const_iterator = const TChar*;
   using difference_type = size_t;
+  using size_type = size_t;
 
   // End of string marker.
   constexpr static const size_t npos = static_cast<size_t>(-1);
diff --git a/libs/androidfw/include/androidfw/ZipUtils.h b/libs/androidfw/include/androidfw/ZipUtils.h
index 55575d7..4d35e99 100644
--- a/libs/androidfw/include/androidfw/ZipUtils.h
+++ b/libs/androidfw/include/androidfw/ZipUtils.h
@@ -40,7 +40,7 @@
         long compressedLen);
     static bool inflateToBuffer(int fd, void* buf, long uncompressedLen,
         long compressedLen);
-    static bool inflateToBuffer(void *in, void* buf, long uncompressedLen,
+    static bool inflateToBuffer(const void *in, void* buf, long uncompressedLen,
         long compressedLen);
 
     /*
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index ae4eabf..303d05f 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -5,11 +5,6 @@
 
         //"hwui_bugreport_font_cache_usage",
         //"hwui_compile_for_perf",
-
-        // Enables fine-grained GLES error checking
-        // If enabled, every GLES call is wrapped & error checked
-        // Has moderate overhead
-        //"hwui_enable_opengl-validation",
     ],
 
     cflags: [
@@ -62,7 +57,7 @@
         "libskia",
         "libui",
         "libgui",
-        "libprotobuf-cpp-full",
+        "libprotobuf-cpp-lite",
         "libharfbuzz_ng",
         "libft2",
         "libminikin",
@@ -108,7 +103,6 @@
     name: "hwui_enable_opengl_validation",
     defaults: ["hwui_debug"],
     cflags: ["-DDEBUG_OPENGL=3"],
-    srcs: ["debug/wrap_gles.cpp"],
     include_dirs: ["frameworks/native/opengl/libs/GLES2"],
 }
 
@@ -147,6 +141,7 @@
         "renderstate/Scissor.cpp",
         "renderstate/Stencil.cpp",
         "renderstate/TextureState.cpp",
+        "renderthread/CacheManager.cpp",
         "renderthread/CanvasContext.cpp",
         "renderthread/OpenGLPipeline.cpp",
         "renderthread/DrawFrameTask.cpp",
@@ -242,7 +237,14 @@
 
 cc_library {
     name: "libhwui",
-    defaults: ["libhwui_defaults"],
+    defaults: [
+        "libhwui_defaults",
+
+        // Enables fine-grained GLES error checking
+        // If enabled, every GLES call is wrapped & error checked
+        // Has moderate overhead
+        "hwui_enable_opengl_validation",
+],
 }
 
 // ------------------------
@@ -264,6 +266,7 @@
 cc_defaults {
     name: "hwui_test_defaults",
     defaults: ["hwui_defaults"],
+    test_suites: ["device-tests"],
     srcs: [
         "tests/common/scenes/*.cpp",
         "tests/common/LeakChecker.cpp",
@@ -298,6 +301,7 @@
         "tests/unit/BakedOpRendererTests.cpp",
         "tests/unit/BakedOpStateTests.cpp",
         "tests/unit/BitmapTests.cpp",
+        "tests/unit/CacheManagerTests.cpp",
         "tests/unit/CanvasContextTests.cpp",
         "tests/unit/CanvasStateTests.cpp",
         "tests/unit/ClipAreaTests.cpp",
diff --git a/libs/hwui/AndroidTest.xml b/libs/hwui/AndroidTest.xml
new file mode 100644
index 0000000..eab32c5
--- /dev/null
+++ b/libs/hwui/AndroidTest.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<configuration description="Config for hwuimicro">
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="hwui_unit_tests->/data/nativetest/hwui_unit_tests" />
+        <option name="push" value="hwuimicro->/data/benchmarktest/hwuimicro" />
+        <option name="push" value="hwuimacro->/data/benchmarktest/hwuimacro" />
+    </target_preparer>
+    <option name="test-suite-tag" value="apct" />
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/nativetest" />
+        <option name="module-name" value="hwui_unit_tests" />
+    </test>
+    <test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
+        <option name="native-benchmark-device-path" value="/data/benchmarktest" />
+        <option name="benchmark-module-name" value="hwuimicro" />
+    </test>
+    <test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
+        <option name="native-benchmark-device-path" value="/data/benchmarktest" />
+        <option name="benchmark-module-name" value="hwuimacro" />
+    </test>
+</configuration>
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index d154730..df2b35b 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -32,7 +32,8 @@
 OffscreenBuffer* BakedOpRenderer::startTemporaryLayer(uint32_t width, uint32_t height) {
     LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer...");
 
-    OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height);
+    OffscreenBuffer* buffer = mRenderState.layerPool().get(
+            mRenderState, width, height, mWideColorGamut);
     startRepaintLayer(buffer, Rect(width, height));
     return buffer;
 }
@@ -103,7 +104,8 @@
 OffscreenBuffer* BakedOpRenderer::copyToLayer(const Rect& area) {
     const uint32_t width = area.getWidth();
     const uint32_t height = area.getHeight();
-    OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height);
+    OffscreenBuffer* buffer = mRenderState.layerPool().get(
+            mRenderState, width, height, mWideColorGamut);
     if (!area.isEmpty() && width != 0 && height != 0) {
         mCaches.textureState().activateTexture(0);
         mCaches.textureState().bindTexture(buffer->texture.id());
diff --git a/libs/hwui/BakedOpRenderer.h b/libs/hwui/BakedOpRenderer.h
index 4d76a3d..01ca367 100644
--- a/libs/hwui/BakedOpRenderer.h
+++ b/libs/hwui/BakedOpRenderer.h
@@ -54,12 +54,13 @@
         uint8_t spotShadowAlpha;
     };
 
-    BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque,
+    BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, bool wideColorGamut,
             const LightInfo& lightInfo)
             : mGlopReceiver(DefaultGlopReceiver)
             , mRenderState(renderState)
             , mCaches(caches)
             , mOpaque(opaque)
+            , mWideColorGamut(wideColorGamut)
             , mLightInfo(lightInfo) {
     }
 
@@ -118,6 +119,7 @@
     RenderState& mRenderState;
     Caches& mCaches;
     bool mOpaque;
+    bool mWideColorGamut;
     bool mHasDrawn = false;
 
     // render target state - setup by start/end layer/frame
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 2e9a6e8..c19c1a1 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -457,11 +457,13 @@
     return *this;
 }
 
-GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture, Matrix4& textureTransform) {
+GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture, Matrix4& textureTransform,
+        bool requiresFilter) {
     TRIGGER_STAGE(kFillStage);
     REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
 
-    mOutGlop->fill.texture = { &texture, GL_LINEAR, GL_CLAMP_TO_EDGE, &textureTransform };
+    GLenum filter = requiresFilter ? GL_LINEAR : GL_NEAREST;
+    mOutGlop->fill.texture = { &texture, filter, GL_CLAMP_TO_EDGE, &textureTransform };
 
     setFill(SK_ColorWHITE, 1.0f, SkBlendMode::kSrc, Blend::ModeOrderSwap::NoSwap,
             nullptr, nullptr);
diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h
index 87b1568..6d11da1 100644
--- a/libs/hwui/GlopBuilder.h
+++ b/libs/hwui/GlopBuilder.h
@@ -75,7 +75,8 @@
     GlopBuilder& setFillTextureLayer(GlLayer& layer, float alpha);
     // TODO: setFillLayer normally forces its own wrap & filter mode,
     // which isn't always correct.
-    GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform);
+    GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform,
+            bool requiresFilter);
 
     GlopBuilder& setTransform(const Matrix4& canvas, const int transformFlags);
 
diff --git a/libs/hwui/OpenGLReadback.cpp b/libs/hwui/OpenGLReadback.cpp
index c460c0d..19d5d9d 100644
--- a/libs/hwui/OpenGLReadback.cpp
+++ b/libs/hwui/OpenGLReadback.cpp
@@ -27,6 +27,7 @@
 #include <GLES2/gl2.h>
 #include <ui/Fence.h>
 #include <ui/GraphicBuffer.h>
+#include <gui/Surface.h>
 
 namespace android {
 namespace uirenderer {
@@ -132,8 +133,7 @@
         return CopyResult::DestinationInvalid;
     }
 
-    // TODO: Add support for RGBA_F16 destinations
-    if (bitmap->colorType() == kRGBA_F16_SkColorType) {
+    if (bitmap->colorType() == kRGBA_F16_SkColorType && !caches.extensions().hasFloatTextures()) {
         ALOGW("Can't copy surface into bitmap, RGBA_F16 config is not supported");
         return CopyResult::DestinationInvalid;
     }
@@ -144,29 +144,37 @@
         return CopyResult::UnknownError;
     }
 
-    SkAutoLockPixels alp(*bitmap);
-
     GLuint texture;
 
     GLenum format;
+    GLenum internalFormat;
     GLenum type;
 
     switch (bitmap->colorType()) {
         case kAlpha_8_SkColorType:
             format = GL_ALPHA;
+            internalFormat = GL_ALPHA;
             type = GL_UNSIGNED_BYTE;
             break;
         case kRGB_565_SkColorType:
             format = GL_RGB;
+            internalFormat = GL_RGB;
             type = GL_UNSIGNED_SHORT_5_6_5;
             break;
         case kARGB_4444_SkColorType:
             format = GL_RGBA;
+            internalFormat = GL_RGBA;
             type = GL_UNSIGNED_SHORT_4_4_4_4;
             break;
+        case kRGBA_F16_SkColorType:
+            format = GL_RGBA;
+            internalFormat = GL_RGBA16F;
+            type = GL_HALF_FLOAT;
+            break;
         case kN32_SkColorType:
         default:
             format = GL_RGBA;
+            internalFormat = GL_RGBA;
             type = GL_UNSIGNED_BYTE;
             break;
     }
@@ -185,12 +193,13 @@
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    glTexImage2D(GL_TEXTURE_2D, 0, format, destWidth, destHeight,
+    glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, destWidth, destHeight,
             0, format, type, nullptr);
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
             GL_TEXTURE_2D, texture, 0);
 
     {
+        bool requiresFilter;
         // Draw & readback
         renderState.setViewport(destWidth, destHeight);
         renderState.scissor().setEnabled(false);
@@ -208,12 +217,17 @@
             croppedTexTransform.scale(srcRect.getWidth() / sourceTexture.width(),
                     srcRect.getHeight() / sourceTexture.height(), 1);
             croppedTexTransform.multiply(sFlipV);
+            requiresFilter = srcRect.getWidth() != (float) destWidth
+                    || srcRect.getHeight() != (float) destHeight;
+        } else {
+            requiresFilter = sourceTexture.width() != (uint32_t) destWidth
+                    || sourceTexture.height() != (uint32_t) destHeight;
         }
         Glop glop;
         GlopBuilder(renderState, caches, &glop)
                 .setRoundRectClipState(nullptr)
                 .setMeshTexturedUnitQuad(nullptr)
-                .setFillExternalTexture(sourceTexture, croppedTexTransform)
+                .setFillExternalTexture(sourceTexture, croppedTexTransform, requiresFilter)
                 .setTransform(Matrix4::identity(), TransformFlags::None)
                 .setModelViewMapUnitToRect(Rect(destWidth, destHeight))
                 .build();
@@ -221,6 +235,7 @@
         ortho.loadOrtho(destWidth, destHeight);
         renderState.render(glop, ortho);
 
+        // TODO: We should convert to linear space when the target is RGBA16F
         glReadPixels(0, 0, bitmap->width(), bitmap->height(), format,
                 type, bitmap->getPixels());
     }
diff --git a/libs/hwui/OpenGLReadback.h b/libs/hwui/OpenGLReadback.h
index c9222cf..403f2e3 100644
--- a/libs/hwui/OpenGLReadback.h
+++ b/libs/hwui/OpenGLReadback.h
@@ -18,6 +18,9 @@
 
 #include "Readback.h"
 
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
 namespace android {
 namespace uirenderer {
 
diff --git a/libs/hwui/Readback.h b/libs/hwui/Readback.h
index b763953..7cf4262 100644
--- a/libs/hwui/Readback.h
+++ b/libs/hwui/Readback.h
@@ -20,10 +20,10 @@
 #include "Rect.h"
 
 #include <SkBitmap.h>
-#include <gui/Surface.h>
 
 namespace android {
 class GraphicBuffer;
+class Surface;
 namespace uirenderer {
 
 // Keep in sync with PixelCopy.java codes
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 374c1b1..d966372 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -540,12 +540,13 @@
 }
 
 // Text
-void RecordingCanvas::drawGlyphs(const uint16_t* glyphs, const float* positions, int glyphCount,
-            const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
-            float boundsRight, float boundsBottom, float totalAdvance) {
-    if (!glyphs || !positions || glyphCount <= 0 || paint.nothingToDraw()) return;
-    glyphs = refBuffer<glyph_t>(glyphs, glyphCount);
-    positions = refBuffer<float>(positions, glyphCount * 2);
+void RecordingCanvas::drawGlyphs(ReadGlyphFunc glyphFunc, int glyphCount, const SkPaint& paint,
+        float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+        float totalAdvance) {
+    if (glyphCount <= 0 || paint.nothingToDraw()) return;
+    uint16_t* glyphs = (glyph_t*)alloc().alloc<glyph_t>(glyphCount * sizeof(glyph_t));
+    float* positions = (float*)alloc().alloc<float>(2 * glyphCount * sizeof(float));
+    glyphFunc(glyphs, positions);
 
     // TODO: either must account for text shadow in bounds, or record separate ops for text shadows
     addOp(alloc().create_trivial<TextOp>(
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 44181bd2..ccdb4b0 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -168,9 +168,7 @@
     virtual void drawArc(float left, float top, float right, float bottom,
             float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) override;
     virtual void drawPath(const SkPath& path, const SkPaint& paint) override;
-    virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
-            const float* verts, const float* tex, const int* colors,
-            const uint16_t* indices, int indexCount, const SkPaint& paint) override
+    virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint& paint) override
         { /* RecordingCanvas does not support drawVertices(); ignore */ }
 
     virtual void drawVectorDrawable(VectorDrawableRoot* tree) override;
@@ -191,9 +189,8 @@
     virtual bool drawTextAbsolutePos() const override { return false; }
 
 protected:
-    virtual void drawGlyphs(const uint16_t* text, const float* positions, int count,
-            const SkPaint& paint, float x, float y,
-            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+    virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& paint, float x,
+            float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
             float totalAdvance) override;
     virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
             const SkPaint& paint, const SkPath& path, size_t start, size_t end) override;
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 3e5e3bf..623b496 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -482,7 +482,7 @@
 void SkiaCanvas::drawRect(float left, float top, float right, float bottom,
         const SkPaint& paint) {
     if (CC_UNLIKELY(paint.nothingToDraw())) return;
-    mCanvas->drawRectCoords(left, top, right, bottom, paint);
+    mCanvas->drawRect({left, top, right, bottom}, paint);
 
 }
 
@@ -521,17 +521,8 @@
     mCanvas->drawPath(path, paint);
 }
 
-void SkiaCanvas::drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
-                              const float* verts, const float* texs, const int* colors,
-                              const uint16_t* indices, int indexCount, const SkPaint& paint) {
-#ifndef SK_SCALAR_IS_FLOAT
-    SkDEBUGFAIL("SkScalar must be a float for these conversions to be valid");
-#endif
-    const int ptCount = vertexCount >> 1;
-    mCanvas->drawVertices(SkVertices::MakeCopy(vertexMode, ptCount, (SkPoint*)verts,
-                                               (SkPoint*)texs, (SkColor*)colors,
-                                               indexCount, indices),
-                          SkBlendMode::kModulate, paint);
+void SkiaCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint) {
+    mCanvas->drawVertices(vertices, mode, paint);
 }
 
 // ----------------------------------------------------------------------------
@@ -572,7 +563,7 @@
     if (colors) {
         flags |= SkVertices::kHasColors_BuilderFlag;
     }
-    SkVertices::Builder builder(SkCanvas::kTriangles_VertexMode, ptCount, indexCount, flags);
+    SkVertices::Builder builder(SkVertices::kTriangles_VertexMode, ptCount, indexCount, flags);
     memcpy(builder.positions(), vertices, ptCount * sizeof(SkPoint));
     if (colors) {
         memcpy(builder.colors(), colors, ptCount * sizeof(SkColor));
@@ -685,11 +676,10 @@
 // Canvas draw operations: Text
 // ----------------------------------------------------------------------------
 
-void SkiaCanvas::drawGlyphs(const uint16_t* text, const float* positions, int count,
-        const SkPaint& paint, float x, float y,
-        float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+void SkiaCanvas::drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& paint, float x,
+        float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
         float totalAdvance) {
-     if (!text || !positions || count <= 0 || paint.nothingToDraw()) return;
+    if (count <= 0 || paint.nothingToDraw()) return;
     // Set align to left for drawing, as we don't want individual
     // glyphs centered or right-aligned; the offset above takes
     // care of all alignment.
@@ -701,10 +691,7 @@
 
     SkTextBlobBuilder builder;
     const SkTextBlobBuilder::RunBuffer& buffer = builder.allocRunPos(paintCopy, count, &bounds);
-    // TODO: we could reduce the number of memcpy's if the this were exposed further up
-    //       in the architecture.
-    memcpy(buffer.glyphs, text, count * sizeof(uint16_t));
-    memcpy(buffer.pos, positions, (count << 1) * sizeof(float));
+    glyphFunc(buffer.glyphs, buffer.pos);
 
     sk_sp<SkTextBlob> textBlob(builder.make());
     mCanvas->drawTextBlob(textBlob, 0, 0, paintCopy);
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index aeecafa..af2c23e 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -123,9 +123,7 @@
     virtual void drawArc(float left, float top, float right, float bottom,
             float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) override;
     virtual void drawPath(const SkPath& path, const SkPaint& paint) override;
-    virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
-            const float* verts, const float* tex, const int* colors,
-            const uint16_t* indices, int indexCount, const SkPaint& paint) override;
+    virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint& paint) override;
 
     virtual void drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) override;
     virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) override;
@@ -159,9 +157,8 @@
     void reset(SkCanvas* skiaCanvas);
     void drawDrawable(SkDrawable* drawable) { mCanvas->drawDrawable(drawable); }
 
-    virtual void drawGlyphs(const uint16_t* text, const float* positions, int count,
-            const SkPaint& paint, float x, float y,
-            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+    virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& paint, float x,
+            float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
             float totalAdvance) override;
     virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
             const SkPaint& paint, const SkPath& path, size_t start, size_t end) override;
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index f6e92dc..34dddd1 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -183,18 +183,10 @@
 
 void SkiaCanvasProxy::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode,
         const SkPaint& paint) {
-    // TODO: should we pass through blendmode
     if (mFilterHwuiCalls) {
         return;
     }
-    // convert the SkPoints into floats
-    static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
-    const int floatCount = vertices->vertexCount() << 1;
-    const float* vArray = (const float*)vertices->positions();
-    const float* tArray = (const float*)vertices->texCoords();
-    const int* cArray = (const int*)vertices->colors();
-    mCanvas->drawVertices(vertices->mode(), floatCount, vArray, tArray, cArray,
-            vertices->indices(), vertices->indexCount(), paint);
+    mCanvas->drawVertices(vertices, bmode, paint);
 }
 
 sk_sp<SkSurface> SkiaCanvasProxy::onNewSurface(const SkImageInfo&, const SkSurfaceProps&) {
@@ -286,7 +278,6 @@
     GlyphIDConverter glyphs(text, byteLength, origPaint);
 
     // compute the glyph positions
-    std::unique_ptr<SkPoint[]> pointStorage(new SkPoint[glyphs.count]);
     std::unique_ptr<SkScalar[]> glyphWidths(new SkScalar[glyphs.count]);
     glyphs.paint.getTextWidths(glyphs.glyphIDs, glyphs.count << 1, glyphWidths.get());
 
@@ -320,22 +311,33 @@
         xBaseline = x;
         yBaseline = y;
     }
-    pointStorage[0].set(xBaseline, yBaseline);
-
-    // setup the remaining glyph positions
-    if (glyphs.paint.isVerticalText()) {
-        for (int i = 1; i < glyphs.count; i++) {
-            pointStorage[i].set(xBaseline, glyphWidths[i-1] + pointStorage[i-1].fY);
-        }
-    } else {
-        for (int i = 1; i < glyphs.count; i++) {
-            pointStorage[i].set(glyphWidths[i-1] + pointStorage[i-1].fX, yBaseline);
-        }
-    }
 
     static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
-    mCanvas->drawGlyphs(glyphs.glyphIDs, &pointStorage[0].fX, glyphs.count, glyphs.paint,
-                      x, y, bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
+    auto glyphFunc = [&] (uint16_t* text, float* positions) {
+        memcpy(text, glyphs.glyphIDs, glyphs.count*sizeof(uint16_t));
+        size_t posIndex = 0;
+        // setup the first glyph position
+        positions[posIndex++] = xBaseline;
+        positions[posIndex++] = yBaseline;
+        // setup the remaining glyph positions
+        if (glyphs.paint.isVerticalText()) {
+            float yPosition = yBaseline;
+            for (int i = 1; i < glyphs.count; i++) {
+                positions[posIndex++] = xBaseline;
+                yPosition += glyphWidths[i-1];
+                positions[posIndex++] = yPosition;
+            }
+        } else {
+            float xPosition = xBaseline;
+            for (int i = 1; i < glyphs.count; i++) {
+                xPosition += glyphWidths[i-1];
+                positions[posIndex++] = xPosition;
+                positions[posIndex++] = yBaseline;
+            }
+        }
+    };
+    mCanvas->drawGlyphs(glyphFunc, glyphs.count, glyphs.paint, x, y, bounds.fLeft, bounds.fTop,
+            bounds.fRight, bounds.fBottom, 0);
 }
 
 void SkiaCanvasProxy::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
@@ -345,21 +347,12 @@
 
     // convert to relative positions if necessary
     int x, y;
-    const SkPoint* posArray;
-    std::unique_ptr<SkPoint[]> pointStorage;
     if (mCanvas->drawTextAbsolutePos()) {
         x = 0;
         y = 0;
-        posArray = pos;
     } else {
         x = pos[0].fX;
         y = pos[0].fY;
-        pointStorage.reset(new SkPoint[glyphs.count]);
-        for (int i = 0; i < glyphs.count; i++) {
-            pointStorage[i].fX = pos[i].fX - x;
-            pointStorage[i].fY = pos[i].fY - y;
-        }
-        posArray = pointStorage.get();
     }
 
     // Compute conservative bounds.  If the content has already been processed
@@ -375,8 +368,19 @@
     }
 
     static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
-    mCanvas->drawGlyphs(glyphs.glyphIDs, &posArray[0].fX, glyphs.count, glyphs.paint, x, y,
-                      bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
+    auto glyphFunc = [&] (uint16_t* text, float* positions) {
+        memcpy(text, glyphs.glyphIDs, glyphs.count*sizeof(uint16_t));
+        if (mCanvas->drawTextAbsolutePos()) {
+            memcpy(positions, pos, 2*glyphs.count*sizeof(float));
+        } else {
+            for (int i = 0, posIndex = 0; i < glyphs.count; i++) {
+                positions[posIndex++] = pos[i].fX - x;
+                positions[posIndex++] = pos[i].fY - y;
+            }
+        }
+    };
+    mCanvas->drawGlyphs(glyphFunc, glyphs.count, glyphs.paint, x, y, bounds.fLeft, bounds.fTop,
+            bounds.fRight, bounds.fBottom, 0);
 }
 
 void SkiaCanvasProxy::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
@@ -456,19 +460,13 @@
     if (mFilterHwuiCalls) {
         return;
     }
-    SkPatchUtils::VertexData data;
-
     SkMatrix matrix;
     mCanvas->getMatrix(&matrix);
     SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, &matrix);
 
-    // It automatically adjusts lodX and lodY in case it exceeds the number of indices.
-    // If it fails to generate the vertices, then we do not draw.
-    if (SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(), lod.height())) {
-        this->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
-                           data.fTexCoords, data.fColors, bmode, data.fIndices, data.fIndexCount,
-                           paint);
-    }
+    mCanvas->drawVertices(SkPatchUtils::MakeVertices(cubics, colors, texCoords,
+                                                     lod.width(), lod.height()).get(),
+                          bmode, paint);
 }
 
 void SkiaCanvasProxy::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle) {
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
index 959059f..4ef31d5 100644
--- a/libs/hwui/Texture.cpp
+++ b/libs/hwui/Texture.cpp
@@ -120,6 +120,10 @@
 void Texture::upload(GLint internalFormat, uint32_t width, uint32_t height,
         GLenum format, GLenum type, const void* pixels) {
     GL_CHECKPOINT(MODERATE);
+
+    // We don't have color space information, we assume the data is gamma encoded
+    mIsLinear = false;
+
     bool needsAlloc = updateLayout(width, height, internalFormat, format, GL_TEXTURE_2D);
     if (!mId) {
         glGenTextures(1, &mId);
@@ -309,11 +313,16 @@
     bool rgba16fNeedsConversion = bitmap.colorType() == kRGBA_F16_SkColorType
             && internalFormat != GL_RGBA16F;
 
+    // RGBA16F is always linear extended sRGB
+    if (internalFormat == GL_RGBA16F) {
+        mIsLinear = true;
+    }
+
     mConnector.reset();
 
-    // RGBA16F is always extended sRGB, alpha masks don't have color profiles
+    // Alpha masks don't have color profiles
     // If an RGBA16F bitmap needs conversion, we know the target will be sRGB
-    if (internalFormat != GL_RGBA16F && internalFormat != GL_ALPHA && !rgba16fNeedsConversion) {
+    if (!mIsLinear && internalFormat != GL_ALPHA && !rgba16fNeedsConversion) {
         SkColorSpace* colorSpace = bitmap.info().colorSpace();
         // If the bitmap is sRGB we don't need conversion
         if (colorSpace != nullptr && !colorSpace->isSRGB()) {
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 55b74ed..7f742e6 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -88,7 +88,8 @@
      * The image data is undefined after calling this.
      */
     void resize(uint32_t width, uint32_t height, GLint internalFormat, GLint format) {
-        upload(internalFormat, width, height, format, GL_UNSIGNED_BYTE, nullptr);
+        upload(internalFormat, width, height, format,
+                internalFormat == GL_RGBA16F ? GL_HALF_FLOAT : GL_UNSIGNED_BYTE, nullptr);
     }
 
     /**
@@ -155,7 +156,7 @@
      * Returns true if this texture uses a linear encoding format.
      */
     constexpr bool isLinear() const {
-        return mInternalFormat == GL_RGBA16F;
+        return mIsLinear;
     }
 
     /**
@@ -219,6 +220,9 @@
     GLenum mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
     GLenum mMagFilter = GL_LINEAR;
 
+    // Indicates whether the content of the texture is in linear space
+    bool mIsLinear = false;
+
     Caches& mCaches;
 
     std::unique_ptr<ColorSpaceConnector> mConnector;
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 8823a92..f6b2912 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -491,6 +491,36 @@
     return *mCache.bitmap;
 }
 
+void Tree::updateCache(sk_sp<SkSurface> surface) {
+    if (surface.get()) {
+        mCache.surface = surface;
+    }
+    if (surface.get() || mCache.dirty) {
+        SkSurface* vdSurface = mCache.surface.get();
+        SkCanvas* canvas = vdSurface->getCanvas();
+        float scaleX = vdSurface->width() / mProperties.getViewportWidth();
+        float scaleY = vdSurface->height() / mProperties.getViewportHeight();
+        SkAutoCanvasRestore acr(canvas, true);
+        canvas->clear(SK_ColorTRANSPARENT);
+        canvas->scale(scaleX, scaleY);
+        mRootNode->draw(canvas, false);
+        mCache.dirty = false;
+        canvas->flush();
+    }
+}
+
+void Tree::draw(SkCanvas* canvas) {
+   /*
+    * TODO address the following...
+    *
+    * 1) figure out how to set path's as volatile during animation
+    * 2) if mRoot->getPaint() != null either promote to layer (during
+    *    animation) or cache in SkSurface (for static content)
+    */
+    canvas->drawImageRect(mCache.surface->makeImageSnapshot().get(),
+        mutateProperties()->getBounds(), getPaint());
+}
+
 void Tree::updateBitmapCache(Bitmap& bitmap, bool useStagingData) {
     SkBitmap outCache;
     bitmap.getSkBitmap(&outCache);
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index 729a4dd..22cfe29 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -31,6 +31,7 @@
 #include <SkPathMeasure.h>
 #include <SkRect.h>
 #include <SkShader.h>
+#include <SkSurface.h>
 
 #include <cutils/compiler.h>
 #include <stddef.h>
@@ -677,15 +678,37 @@
     // This should only be called from animations on RT
     TreeProperties* mutateProperties() { return &mProperties; }
 
+    // called from RT only
+    const TreeProperties& properties() const { return mProperties; }
+
     // This should always be called from RT.
     void markDirty() { mCache.dirty = true; }
     bool isDirty() const { return mCache.dirty; }
     bool getPropertyChangeWillBeConsumed() const { return mWillBeConsumed; }
     void setPropertyChangeWillBeConsumed(bool willBeConsumed) { mWillBeConsumed = willBeConsumed; }
 
+    // Returns true if VD cache surface is big enough. This should always be called from RT and it
+    // works with Skia pipelines only.
+    bool canReuseSurface() {
+        SkSurface* surface = mCache.surface.get();
+        return surface && surface->width() >= mProperties.getScaledWidth()
+              && surface->height() >= mProperties.getScaledHeight();
+    }
+
+    // Draws VD cache into a canvas. This should always be called from RT and it works with Skia
+    // pipelines only.
+    void draw(SkCanvas* canvas);
+
+    // Draws VD into a GPU backed surface. If canReuseSurface returns false, then "surface" must
+    // contain a new surface. This should always be called from RT and it works with Skia pipelines
+    // only.
+    void updateCache(sk_sp<SkSurface> surface);
+
 private:
     struct Cache {
-        sk_sp<Bitmap> bitmap;
+        sk_sp<Bitmap> bitmap; //used by HWUI pipeline and software
+        //TODO: use surface instead of bitmap when drawing in software canvas
+        sk_sp<SkSurface> surface; //used only by Skia pipelines
         bool dirty = true;
     };
 
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index bb1e674..6dde005 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -26,16 +26,12 @@
 #include <log/log.h>
 #include <cutils/ashmem.h>
 
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
 #include <private/gui/ComposerService.h>
 #include <binder/IServiceManager.h>
 #include <ui/PixelFormat.h>
 
 #include <SkCanvas.h>
+#include <SkImagePriv.h>
 
 namespace android {
 
@@ -51,9 +47,9 @@
 }
 
 typedef sk_sp<Bitmap> (*AllocPixeRef)(size_t allocSize, const SkImageInfo& info, size_t rowBytes,
-        SkColorTable* ctable);
+        sk_sp<SkColorTable> ctable);
 
-static sk_sp<Bitmap> allocateBitmap(SkBitmap* bitmap, SkColorTable* ctable, AllocPixeRef alloc) {
+static sk_sp<Bitmap> allocateBitmap(SkBitmap* bitmap, sk_sp<SkColorTable> ctable, AllocPixeRef alloc) {
     const SkImageInfo& info = bitmap->info();
     if (info.colorType() == kUnknown_SkColorType) {
         LOG_ALWAYS_FATAL("unknown bitmap configuration");
@@ -69,201 +65,32 @@
         return nullptr;
     }
 
-    auto wrapper = alloc(size, info, rowBytes, ctable);
+    auto wrapper = alloc(size, info, rowBytes, std::move(ctable));
     if (wrapper) {
         wrapper->getSkBitmap(bitmap);
-        // since we're already allocated, we lockPixels right away
-        // HeapAllocator behaves this way too
-        bitmap->lockPixels();
     }
     return wrapper;
 }
 
-sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
-   return allocateBitmap(bitmap, ctable, &Bitmap::allocateAshmemBitmap);
+sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(SkBitmap* bitmap, sk_sp<SkColorTable> ctable) {
+   return allocateBitmap(bitmap, std::move(ctable), &Bitmap::allocateAshmemBitmap);
 }
 
 static sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& info, size_t rowBytes,
-        SkColorTable* ctable) {
+        sk_sp<SkColorTable> ctable) {
     void* addr = calloc(size, 1);
     if (!addr) {
         return nullptr;
     }
-    return sk_sp<Bitmap>(new Bitmap(addr, size, info, rowBytes, ctable));
-}
-
-#define FENCE_TIMEOUT 2000000000
-
-// TODO: handle SRGB sanely
-static PixelFormat internalFormatToPixelFormat(GLint internalFormat) {
-    switch (internalFormat) {
-    case GL_LUMINANCE:
-        return PIXEL_FORMAT_RGBA_8888;
-    case GL_SRGB8_ALPHA8:
-        return PIXEL_FORMAT_RGBA_8888;
-    case GL_RGBA:
-        return PIXEL_FORMAT_RGBA_8888;
-    case GL_RGB:
-        return PIXEL_FORMAT_RGB_565;
-    case GL_RGBA16F:
-        return PIXEL_FORMAT_RGBA_FP16;
-    default:
-        LOG_ALWAYS_FATAL("Unsupported bitmap colorType: %d", internalFormat);
-        return PIXEL_FORMAT_UNKNOWN;
-    }
-}
-
-class AutoEglFence {
-public:
-    AutoEglFence(EGLDisplay display)
-            : mDisplay(display) {
-        fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
-    }
-
-    ~AutoEglFence() {
-        if (fence != EGL_NO_SYNC_KHR) {
-            eglDestroySyncKHR(mDisplay, fence);
-        }
-    }
-
-    EGLSyncKHR fence = EGL_NO_SYNC_KHR;
-private:
-    EGLDisplay mDisplay = EGL_NO_DISPLAY;
-};
-
-class AutoEglImage {
-public:
-    AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer)
-            : mDisplay(display) {
-        EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
-        image = eglCreateImageKHR(display, EGL_NO_CONTEXT,
-                EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
-    }
-
-    ~AutoEglImage() {
-        if (image != EGL_NO_IMAGE_KHR) {
-            eglDestroyImageKHR(mDisplay, image);
-        }
-    }
-
-    EGLImageKHR image = EGL_NO_IMAGE_KHR;
-private:
-    EGLDisplay mDisplay = EGL_NO_DISPLAY;
-};
-
-class AutoGlTexture {
-public:
-    AutoGlTexture(uirenderer::Caches& caches)
-            : mCaches(caches) {
-        glGenTextures(1, &mTexture);
-        caches.textureState().bindTexture(mTexture);
-    }
-
-    ~AutoGlTexture() {
-        mCaches.textureState().deleteTexture(mTexture);
-    }
-
-private:
-    uirenderer::Caches& mCaches;
-    GLuint mTexture = 0;
-};
-
-static bool uploadBitmapToGraphicBuffer(uirenderer::Caches& caches, SkBitmap& bitmap,
-        GraphicBuffer& buffer, GLint format, GLint type) {
-    SkAutoLockPixels alp(bitmap);
-    EGLDisplay display = eglGetCurrentDisplay();
-    LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY,
-                "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
-                uirenderer::renderthread::EglManager::eglErrorString());
-    // We use an EGLImage to access the content of the GraphicBuffer
-    // The EGL image is later bound to a 2D texture
-    EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer.getNativeBuffer();
-    AutoEglImage autoImage(display, clientBuffer);
-    if (autoImage.image == EGL_NO_IMAGE_KHR) {
-        ALOGW("Could not create EGL image, err =%s",
-                uirenderer::renderthread::EglManager::eglErrorString());
-        return false;
-    }
-    AutoGlTexture glTexture(caches);
-    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
-
-    GL_CHECKPOINT(MODERATE);
-
-    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
-            format, type, bitmap.getPixels());
-
-    GL_CHECKPOINT(MODERATE);
-
-    // The fence is used to wait for the texture upload to finish
-    // properly. We cannot rely on glFlush() and glFinish() as
-    // some drivers completely ignore these API calls
-    AutoEglFence autoFence(display);
-    if (autoFence.fence == EGL_NO_SYNC_KHR) {
-        LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError());
-        return false;
-    }
-    // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
-    // pipeline flush (similar to what a glFlush() would do.)
-    EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence,
-            EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
-    if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
-        LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError());
-        return false;
-    }
-    return true;
-}
-
-sk_sp<Bitmap> Bitmap::allocateHardwareBitmap(uirenderer::renderthread::RenderThread& renderThread,
-        SkBitmap& skBitmap) {
-    renderThread.eglManager().initialize();
-    uirenderer::Caches& caches = uirenderer::Caches::getInstance();
-
-    const SkImageInfo& info = skBitmap.info();
-    if (info.colorType() == kUnknown_SkColorType || info.colorType() == kAlpha_8_SkColorType) {
-        ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType());
-        return nullptr;
-    }
-
-    bool needSRGB = uirenderer::transferFunctionCloseToSRGB(skBitmap.info().colorSpace());
-    bool hasLinearBlending = caches.extensions().hasLinearBlending();
-    GLint format, type, internalFormat;
-    uirenderer::Texture::colorTypeToGlFormatAndType(caches, skBitmap.colorType(),
-            needSRGB && hasLinearBlending, &internalFormat, &format, &type);
-
-    PixelFormat pixelFormat = internalFormatToPixelFormat(internalFormat);
-    sp<GraphicBuffer> buffer = new GraphicBuffer(info.width(), info.height(), pixelFormat,
-            GraphicBuffer::USAGE_HW_TEXTURE |
-            GraphicBuffer::USAGE_SW_WRITE_NEVER |
-            GraphicBuffer::USAGE_SW_READ_NEVER,
-            std::string("Bitmap::allocateHardwareBitmap pid [") + std::to_string(getpid()) + "]");
-
-    status_t error = buffer->initCheck();
-    if (error < 0) {
-        ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
-        return nullptr;
-    }
-
-    SkBitmap bitmap;
-    if (CC_UNLIKELY(uirenderer::Texture::hasUnsupportedColorType(skBitmap.info(),
-            hasLinearBlending))) {
-        sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB();
-        bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasLinearBlending, std::move(sRGB));
-    } else {
-        bitmap = skBitmap;
-    }
-
-    if (!uploadBitmapToGraphicBuffer(caches, bitmap, *buffer, format, type)) {
-        return nullptr;
-    }
-    return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info()));
+    return sk_sp<Bitmap>(new Bitmap(addr, size, info, rowBytes, std::move(ctable)));
 }
 
 sk_sp<Bitmap> Bitmap::allocateHardwareBitmap(SkBitmap& bitmap) {
     return uirenderer::renderthread::RenderProxy::allocateHardwareBitmap(bitmap);
 }
 
-sk_sp<Bitmap> Bitmap::allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
-   return allocateBitmap(bitmap, ctable, &android::allocateHeapBitmap);
+sk_sp<Bitmap> Bitmap::allocateHeapBitmap(SkBitmap* bitmap, sk_sp<SkColorTable> ctable) {
+   return allocateBitmap(bitmap, std::move(ctable), &android::allocateHeapBitmap);
 }
 
 sk_sp<Bitmap> Bitmap::allocateHeapBitmap(const SkImageInfo& info) {
@@ -276,7 +103,7 @@
 }
 
 sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(size_t size, const SkImageInfo& info,
-        size_t rowBytes, SkColorTable* ctable) {
+        size_t rowBytes, sk_sp<SkColorTable> ctable) {
     // Create new ashmem region with read/write priv
     int fd = ashmem_create_region("bitmap", size);
     if (fd < 0) {
@@ -294,20 +121,18 @@
         close(fd);
         return nullptr;
     }
-    return sk_sp<Bitmap>(new Bitmap(addr, fd, size, info, rowBytes, ctable));
+    return sk_sp<Bitmap>(new Bitmap(addr, fd, size, info, rowBytes, std::move(ctable)));
 }
 
 void FreePixelRef(void* addr, void* context) {
     auto pixelRef = (SkPixelRef*) context;
-    pixelRef->unlockPixels();
     pixelRef->unref();
 }
 
 sk_sp<Bitmap> Bitmap::createFrom(const SkImageInfo& info, SkPixelRef& pixelRef) {
     pixelRef.ref();
-    pixelRef.lockPixels();
     return sk_sp<Bitmap>(new Bitmap((void*) pixelRef.pixels(), (void*) &pixelRef, FreePixelRef,
-            info, pixelRef.rowBytes(), pixelRef.colorTable()));
+            info, pixelRef.rowBytes(), sk_ref_sp(pixelRef.colorTable())));
 }
 
 sk_sp<Bitmap> Bitmap::createFrom(sp<GraphicBuffer> graphicBuffer) {
@@ -323,76 +148,87 @@
 }
 
 void Bitmap::setColorSpace(sk_sp<SkColorSpace> colorSpace) {
-    // TODO: See todo in reconfigure() below
-    SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info());
-    *myInfo = info().makeColorSpace(std::move(colorSpace));
+    mInfo = mInfo.makeColorSpace(std::move(colorSpace));
 }
 
-void Bitmap::reconfigure(const SkImageInfo& newInfo, size_t rowBytes, SkColorTable* ctable) {
-    if (kIndex_8_SkColorType != newInfo.colorType()) {
-        ctable = nullptr;
-    }
-    mRowBytes = rowBytes;
-    if (mColorTable.get() != ctable) {
-        mColorTable.reset(SkSafeRef(ctable));
-    }
-
+static SkImageInfo validateAlpha(const SkImageInfo& info) {
     // Need to validate the alpha type to filter against the color type
     // to prevent things like a non-opaque RGB565 bitmap
     SkAlphaType alphaType;
     LOG_ALWAYS_FATAL_IF(!SkColorTypeValidateAlphaType(
-            newInfo.colorType(), newInfo.alphaType(), &alphaType),
+            info.colorType(), info.alphaType(), &alphaType),
             "Failed to validate alpha type!");
+    return info.makeAlphaType(alphaType);
+}
+
+void Bitmap::reconfigure(const SkImageInfo& newInfo, size_t rowBytes, sk_sp<SkColorTable> ctable) {
+    if (kIndex_8_SkColorType != newInfo.colorType()) {
+        ctable = nullptr;
+    }
+
+    mInfo = validateAlpha(newInfo);
 
     // Dirty hack is dirty
     // TODO: Figure something out here, Skia's current design makes this
     // really hard to work with. Skia really, really wants immutable objects,
     // but with the nested-ref-count hackery going on that's just not
     // feasible without going insane trying to figure it out
-    SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info());
-    *myInfo = newInfo;
-    changeAlphaType(alphaType);
-
-    // Docs say to only call this in the ctor, but we're going to call
-    // it anyway even if this isn't always the ctor.
-    // TODO: Fix this too as part of the above TODO
-    setPreLocked(getStorage(), mRowBytes, mColorTable.get());
+    this->android_only_reset(mInfo.width(), mInfo.height(), rowBytes, std::move(ctable));
 }
 
-Bitmap::Bitmap(void* address, size_t size, const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
-            : SkPixelRef(info)
+static sk_sp<SkColorTable> sanitize(const SkImageInfo& info, sk_sp<SkColorTable> ctable) {
+    if (info.colorType() == kIndex_8_SkColorType) {
+        SkASSERT(ctable);
+        return ctable;
+    }
+    return nullptr; // drop the ctable if we're not indexed
+}
+Bitmap::Bitmap(void* address, size_t size, const SkImageInfo& info, size_t rowBytes,
+        sk_sp<SkColorTable> ctable)
+            : SkPixelRef(info.width(), info.height(), address, rowBytes,
+                    sanitize(info, std::move(ctable)))
+            , mInfo(validateAlpha(info))
             , mPixelStorageType(PixelStorageType::Heap) {
     mPixelStorage.heap.address = address;
     mPixelStorage.heap.size = size;
-    reconfigure(info, rowBytes, ctable);
 }
 
 Bitmap::Bitmap(void* address, void* context, FreeFunc freeFunc,
-                const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
-            : SkPixelRef(info)
+                const SkImageInfo& info, size_t rowBytes, sk_sp<SkColorTable> ctable)
+            : SkPixelRef(info.width(), info.height(), address, rowBytes,
+                    sanitize(info, std::move(ctable)))
+            , mInfo(validateAlpha(info))
             , mPixelStorageType(PixelStorageType::External) {
     mPixelStorage.external.address = address;
     mPixelStorage.external.context = context;
     mPixelStorage.external.freeFunc = freeFunc;
-    reconfigure(info, rowBytes, ctable);
 }
 
 Bitmap::Bitmap(void* address, int fd, size_t mappedSize,
-                const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
-            : SkPixelRef(info)
+                const SkImageInfo& info, size_t rowBytes, sk_sp<SkColorTable> ctable)
+            : SkPixelRef(info.width(), info.height(), address, rowBytes,
+                    sanitize(info, std::move(ctable)))
+            , mInfo(validateAlpha(info))
             , mPixelStorageType(PixelStorageType::Ashmem) {
     mPixelStorage.ashmem.address = address;
     mPixelStorage.ashmem.fd = fd;
     mPixelStorage.ashmem.size = mappedSize;
-    reconfigure(info, rowBytes, ctable);
 }
 
 Bitmap::Bitmap(GraphicBuffer* buffer, const SkImageInfo& info)
-        : SkPixelRef(info)
+        : SkPixelRef(info.width(), info.height(), nullptr,
+                     bytesPerPixel(buffer->getPixelFormat()) * buffer->getStride(),
+                     nullptr)
+        , mInfo(validateAlpha(info))
         , mPixelStorageType(PixelStorageType::Hardware) {
     mPixelStorage.hardware.buffer = buffer;
     buffer->incStrong(buffer);
-    mRowBytes = bytesPerPixel(buffer->getPixelFormat()) * buffer->getStride();
+    setImmutable(); // HW bitmaps are always immutable
+    if (uirenderer::Properties::isSkiaEnabled()) {
+        // TODO: add color correctness for Skia pipeline - pass null color space for now
+        mImage = SkImage::MakeFromAHardwareBuffer(reinterpret_cast<AHardwareBuffer*>(buffer),
+                mInfo.alphaType(), nullptr);
+    }
 }
 
 Bitmap::~Bitmap() {
@@ -440,17 +276,6 @@
     }
 }
 
-bool Bitmap::onNewLockPixels(LockRec* rec) {
-    rec->fPixels = getStorage();
-    rec->fRowBytes = mRowBytes;
-    rec->fColorTable = mColorTable.get();
-    return true;
-}
-
-size_t Bitmap::getAllocatedSizeInBytes() const {
-    return info().getSafeSize(mRowBytes);
-}
-
 int Bitmap::getAshmemFd() const {
     switch (mPixelStorageType) {
     case PixelStorageType::Ashmem:
@@ -478,7 +303,7 @@
         return;
     }
 
-    changeAlphaType(alphaType);
+    mInfo = mInfo.makeAlphaType(alphaType);
 }
 
 void Bitmap::getSkBitmap(SkBitmap* outBitmap) {
@@ -494,23 +319,13 @@
         uirenderer::renderthread::RenderProxy::copyGraphicBufferInto(graphicBuffer(), outBitmap);
         return;
     }
-    outBitmap->setInfo(info(), rowBytes());
-    outBitmap->setPixelRef(this);
-}
-
-void Bitmap::getSkBitmapForShaders(SkBitmap* outBitmap) {
-    if (isHardware() && uirenderer::Properties::isSkiaEnabled()) {
-        getSkBitmap(outBitmap);
-    } else {
-        outBitmap->setInfo(info(), rowBytes());
-        outBitmap->setPixelRef(this);
-        outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
-    }
+    outBitmap->setInfo(mInfo, rowBytes());
+    outBitmap->setPixelRef(sk_ref_sp(this), 0, 0);
 }
 
 void Bitmap::getBounds(SkRect* bounds) const {
     SkASSERT(bounds);
-    bounds->set(0, 0, SkIntToScalar(info().width()), SkIntToScalar(info().height()));
+    bounds->set(0, 0, SkIntToScalar(width()), SkIntToScalar(height()));
 }
 
 GraphicBuffer* Bitmap::graphicBuffer() {
@@ -520,4 +335,20 @@
     return nullptr;
 }
 
+sk_sp<SkImage> Bitmap::makeImage() {
+    sk_sp<SkImage> image = mImage;
+    if (!image) {
+        SkASSERT(!(isHardware() && uirenderer::Properties::isSkiaEnabled()));
+        SkBitmap skiaBitmap;
+        skiaBitmap.setInfo(info(), rowBytes());
+        skiaBitmap.setPixelRef(sk_ref_sp(this), 0, 0);
+        skiaBitmap.setHasHardwareMipMap(mHasHardwareMipMap);
+        // Note we don't cache in this case, because the raster image holds a pointer to this Bitmap
+        // internally and ~Bitmap won't be invoked.
+        // TODO: refactor Bitmap to not derive from SkPixelRef, which would allow caching here.
+        image = SkMakeImageFromRasterBitmap(skiaBitmap, kNever_SkCopyPixelsMode);
+    }
+    return image;
+}
+
 } // namespace android
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index da45f76..364240670 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -18,10 +18,12 @@
 #include <SkBitmap.h>
 #include <SkColorSpace.h>
 #include <SkColorTable.h>
+#include <SkImage.h>
 #include <SkImageInfo.h>
 #include <SkPixelRef.h>
 #include <cutils/compiler.h>
 #include <ui/GraphicBuffer.h>
+#include <SkImage.h>
 
 namespace android {
 
@@ -44,66 +46,54 @@
 
 class ANDROID_API Bitmap : public SkPixelRef {
 public:
-    static sk_sp<Bitmap> allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable);
+    static sk_sp<Bitmap> allocateHeapBitmap(SkBitmap* bitmap, sk_sp<SkColorTable> ctable);
     static sk_sp<Bitmap> allocateHeapBitmap(const SkImageInfo& info);
 
     static sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& bitmap);
 
-    static sk_sp<Bitmap> allocateAshmemBitmap(SkBitmap* bitmap, SkColorTable* ctable);
+    static sk_sp<Bitmap> allocateAshmemBitmap(SkBitmap* bitmap, sk_sp<SkColorTable> ctable);
     static sk_sp<Bitmap> allocateAshmemBitmap(size_t allocSize, const SkImageInfo& info,
-        size_t rowBytes, SkColorTable* ctable);
+        size_t rowBytes, sk_sp<SkColorTable> ctable);
 
     static sk_sp<Bitmap> createFrom(sp<GraphicBuffer> graphicBuffer);
 
     static sk_sp<Bitmap> createFrom(const SkImageInfo&, SkPixelRef&);
 
-    static sk_sp<Bitmap> allocateHardwareBitmap(uirenderer::renderthread::RenderThread&,
-            SkBitmap& bitmap);
-
     Bitmap(void* address, size_t allocSize, const SkImageInfo& info, size_t rowBytes,
-            SkColorTable* ctable);
+            sk_sp<SkColorTable> ctable);
     Bitmap(void* address, void* context, FreeFunc freeFunc,
-            const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
+            const SkImageInfo& info, size_t rowBytes, sk_sp<SkColorTable> ctable);
     Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info,
-            size_t rowBytes, SkColorTable* ctable);
-
-    int width() const { return info().width(); }
-    int height() const { return info().height(); }
-
-    // Can't mark as override since SkPixelRef::rowBytes isn't virtual
-    // but that's OK since we just want Bitmap to be able to rely
-    // on calling rowBytes() on an unlocked pixelref, which it will be
-    // doing on a Bitmap type, not a SkPixelRef, so static
-    // dispatching will do what we want.
-    size_t rowBytes() const { return mRowBytes; }
+            size_t rowBytes, sk_sp<SkColorTable> ctable);
+    Bitmap(GraphicBuffer* buffer, const SkImageInfo& info);
 
     int rowBytesAsPixels() const {
-        return mRowBytes >> info().shiftPerPixel();
+        return rowBytes() >> SkColorTypeShiftPerPixel(mInfo.colorType());
     }
 
-    void reconfigure(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
+    void reconfigure(const SkImageInfo& info, size_t rowBytes, sk_sp<SkColorTable> ctable);
     void reconfigure(const SkImageInfo& info);
     void setColorSpace(sk_sp<SkColorSpace> colorSpace);
     void setAlphaType(SkAlphaType alphaType);
 
     void getSkBitmap(SkBitmap* outBitmap);
 
-    // Ugly hack: in case of hardware bitmaps, it sets nullptr as pixels pointer
-    // so it would crash if anyone tries to render this bitmap.
-    void getSkBitmapForShaders(SkBitmap* outBitmap);
-
     int getAshmemFd() const;
     size_t getAllocationByteCount() const;
 
     void setHasHardwareMipMap(bool hasMipMap);
     bool hasHardwareMipMap() const;
 
-    bool isOpaque() const {return info().isOpaque(); }
-    SkColorType colorType() const { return info().colorType(); }
+    bool isOpaque() const { return mInfo.isOpaque(); }
+    SkColorType colorType() const { return mInfo.colorType(); }
+    const SkImageInfo& info() const {
+        return mInfo;
+    }
+
     void getBounds(SkRect* bounds) const;
 
     bool readyToDraw() const {
-        return this->colorType() != kIndex_8_SkColorType || mColorTable;
+        return this->colorType() != kIndex_8_SkColorType || this->colorTable();
     }
 
     bool isHardware() const {
@@ -111,19 +101,18 @@
     }
 
     GraphicBuffer* graphicBuffer();
-protected:
-    virtual bool onNewLockPixels(LockRec* rec) override;
-    virtual void onUnlockPixels() override { };
-    virtual size_t getAllocatedSizeInBytes() const override;
+
+    // makeImage creates or returns a cached SkImage. Can be invoked from UI or render thread.
+    // Caching is supported only for HW Bitmaps with skia pipeline.
+    sk_sp<SkImage> makeImage();
 private:
-    Bitmap(GraphicBuffer* buffer, const SkImageInfo& info);
     virtual ~Bitmap();
     void* getStorage() const;
 
-    PixelStorageType mPixelStorageType;
+    SkImageInfo mInfo;
 
-    size_t mRowBytes = 0;
-    sk_sp<SkColorTable> mColorTable;
+    const PixelStorageType mPixelStorageType;
+
     bool mHasHardwareMipMap = false;
 
     union {
@@ -145,6 +134,8 @@
             GraphicBuffer* buffer;
         } hardware;
     } mPixelStorage;
+
+    sk_sp<SkImage> mImage; // Cache is used only for HW Bitmaps with Skia pipeline.
 };
 
-} //namespace android
\ No newline at end of file
+} //namespace android
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index c64a89d..679cb50 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -80,13 +80,11 @@
 
 class DrawTextFunctor {
 public:
-    DrawTextFunctor(const minikin::Layout& layout, Canvas* canvas, uint16_t* glyphs, float* pos,
+    DrawTextFunctor(const minikin::Layout& layout, Canvas* canvas,
             const SkPaint& paint, float x, float y, minikin::MinikinRect& bounds,
             float totalAdvance)
         : layout(layout)
         , canvas(canvas)
-        , glyphs(glyphs)
-        , pos(pos)
         , paint(paint)
         , x(x)
         , y(y)
@@ -95,19 +93,21 @@
     }
 
     void operator()(size_t start, size_t end) {
-        if (canvas->drawTextAbsolutePos()) {
-            for (size_t i = start; i < end; i++) {
-                glyphs[i] = layout.getGlyphId(i);
-                pos[2 * i] = x + layout.getX(i);
-                pos[2 * i + 1] = y + layout.getY(i);
+        auto glyphFunc = [&] (uint16_t* text, float* positions) {
+            if (canvas->drawTextAbsolutePos()) {
+                for (size_t i = start, textIndex = 0, posIndex = 0; i < end; i++) {
+                    text[textIndex++] = layout.getGlyphId(i);
+                    positions[posIndex++] = x + layout.getX(i);
+                    positions[posIndex++] = y + layout.getY(i);
+                }
+            } else {
+                for (size_t i = start, textIndex = 0, posIndex = 0; i < end; i++) {
+                    text[textIndex++] = layout.getGlyphId(i);
+                    positions[posIndex++] = layout.getX(i);
+                    positions[posIndex++] = layout.getY(i);
+                }
             }
-        } else {
-            for (size_t i = start; i < end; i++) {
-                glyphs[i] = layout.getGlyphId(i);
-                pos[2 * i] = layout.getX(i);
-                pos[2 * i + 1] = layout.getY(i);
-            }
-        }
+        };
 
         size_t glyphCount = end - start;
 
@@ -121,26 +121,24 @@
             SkPaint outlinePaint(paint);
             simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, &outlinePaint);
             outlinePaint.setStyle(SkPaint::kStrokeAndFill_Style);
-            canvas->drawGlyphs(glyphs + start, pos + (2 * start), glyphCount, outlinePaint, x, y,
-                    bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance);
+            canvas->drawGlyphs(glyphFunc, glyphCount, outlinePaint, x, y, bounds.mLeft, bounds.mTop,
+                    bounds.mRight, bounds.mBottom, totalAdvance);
 
             // inner
             SkPaint innerPaint(paint);
             simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, &innerPaint);
             innerPaint.setStyle(SkPaint::kFill_Style);
-            canvas->drawGlyphs(glyphs + start, pos + (2 * start), glyphCount, innerPaint, x, y,
-                    bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance);
+            canvas->drawGlyphs(glyphFunc, glyphCount, innerPaint, x, y, bounds.mLeft, bounds.mTop,
+                    bounds.mRight, bounds.mBottom, totalAdvance);
         } else {
             // standard draw path
-            canvas->drawGlyphs(glyphs + start, pos + (2 * start), glyphCount, paint, x, y,
-                    bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance);
+            canvas->drawGlyphs(glyphFunc, glyphCount, paint, x, y, bounds.mLeft, bounds.mTop,
+                    bounds.mRight, bounds.mBottom, totalAdvance);
         }
     }
 private:
     const minikin::Layout& layout;
     Canvas* canvas;
-    uint16_t* glyphs;
-    float* pos;
     const SkPaint& paint;
     float x;
     float y;
@@ -156,10 +154,6 @@
     minikin::Layout layout = MinikinUtils::doLayout(
             &paint, bidiFlags, typeface, text, start, count, contextCount);
 
-    size_t nGlyphs = layout.nGlyphs();
-    std::unique_ptr<uint16_t[]> glyphs(new uint16_t[nGlyphs]);
-    std::unique_ptr<float[]> pos(new float[nGlyphs * 2]);
-
     x += MinikinUtils::xOffsetForTextAlign(&paint, layout);
 
     minikin::MinikinRect bounds;
@@ -173,8 +167,7 @@
     // care of all alignment.
     paint.setTextAlign(Paint::kLeft_Align);
 
-    DrawTextFunctor f(layout, this, glyphs.get(), pos.get(),
-            paint, x, y, bounds, layout.getAdvance());
+    DrawTextFunctor f(layout, this, paint, x, y, bounds, layout.getAdvance());
     MinikinUtils::forFontRun(layout, &paint, f);
 }
 
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 86af678..ac8a081 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -28,6 +28,7 @@
 #include <SkMatrix.h>
 
 class SkCanvasState;
+class SkVertices;
 
 namespace minikin {
     class Layout;
@@ -67,6 +68,8 @@
 };
 typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
 
+typedef std::function<void(uint16_t* text, float* positions)> ReadGlyphFunc;
+
 class Bitmap;
 class Paint;
 struct Typeface;
@@ -228,9 +231,7 @@
     virtual void drawArc(float left, float top, float right, float bottom,
             float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) = 0;
     virtual void drawPath(const SkPath& path, const SkPaint& paint) = 0;
-    virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
-                              const float* verts, const float* tex, const int* colors,
-                              const uint16_t* indices, int indexCount, const SkPaint& paint) = 0;
+    virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint& paint) = 0;
 
     // Bitmap-based
     virtual void drawBitmap(Bitmap& bitmap, float left, float top,
@@ -274,12 +275,12 @@
     void drawTextDecorations(float x, float y, float length, const SkPaint& paint);
 
     /**
+     * glyphFunc: valid only for the duration of the call and should not be cached.
      * drawText: count is of glyphs
      * totalAdvance: used to define width of text decorations (underlines, strikethroughs).
      */
-    virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int count,
-            const SkPaint& paint, float x, float y,
-            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+    virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& paint, float x,
+            float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
             float totalAdvance) = 0;
     virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
             const SkPaint& paint, const SkPath& path, size_t start, size_t end) = 0;
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
index 68a0869..975f849 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -21,7 +21,6 @@
 
 #include <SkBlurMask.h>
 #include <SkBlurMaskFilter.h>
-#include <SkGaussianEdgeShader.h>
 #include <SkPathOps.h>
 #include <SkRRectsGaussianEdgeMaskFilter.h>
 #include <SkShadowUtils.h>
@@ -137,7 +136,6 @@
 
     float ambientAlpha = (SkiaPipeline::getAmbientShadowAlpha()/255.f)*casterAlpha;
     float spotAlpha = (SkiaPipeline::getSpotShadowAlpha()/255.f)*casterAlpha;
-    const float casterZValue = casterProperties.getZ();
 
     const RevealClip& revealClip = casterProperties.getRevealClip();
     const SkPath* revealClipPath = revealClip.getPath();
@@ -178,6 +176,7 @@
     // intersect the shadow-casting path with the reveal, if present
     if (revealClipPath) {
         Op(*casterPath, *revealClipPath, kIntersect_SkPathOp, &tmpPath);
+        tmpPath.setIsVolatile(true);
         casterPath = &tmpPath;
     }
 
@@ -186,36 +185,23 @@
         SkPath clipBoundsPath;
         clipBoundsPath.addRect(casterClipRect);
         Op(*casterPath, clipBoundsPath, kIntersect_SkPathOp, &tmpPath);
+        tmpPath.setIsVolatile(true);
         casterPath = &tmpPath;
     }
     const Vector3 lightPos = SkiaPipeline::getLightCenter();
     SkPoint3 skiaLightPos = SkPoint3::Make(lightPos.x, lightPos.y, lightPos.z);
-    if (shadowMatrix.hasPerspective() || revealClipPath || clippedToBounds) {
-        std::function<SkScalar(SkScalar, SkScalar)> casterHeightFunc;
-        if (shadowMatrix.hasPerspective()) {
-            // get the matrix with the full 3D transform
-            mat4 zMatrix;
-            caster->getRenderNode()->applyViewPropertyTransforms(zMatrix, true);
-            SkScalar A = zMatrix[2];
-            SkScalar B = zMatrix[6];
-            SkScalar C = zMatrix[mat4::kTranslateZ];
-            casterHeightFunc = [A, B, C](SkScalar x, SkScalar y) {
-                return A*x + B*y + C;  // casterZValue already baked into C
-            };
-        } else {
-            casterHeightFunc = [casterZValue] (SkScalar, SkScalar) {
-                return casterZValue;
-            };
-        }
-
-        SkShadowUtils::DrawUncachedShadow(canvas, *casterPath, casterHeightFunc, skiaLightPos,
-            SkiaPipeline::getLightRadius(), ambientAlpha, spotAlpha, SK_ColorBLACK,
-            casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0);
+    SkPoint3 zParams;
+    if (shadowMatrix.hasPerspective()) {
+        // get the matrix with the full 3D transform
+        mat4 zMatrix;
+        caster->getRenderNode()->applyViewPropertyTransforms(zMatrix, true);
+        zParams = SkPoint3::Make(zMatrix[2], zMatrix[6], zMatrix[mat4::kTranslateZ]);
     } else {
-        SkShadowUtils::DrawShadow(canvas, *casterPath, casterZValue, skiaLightPos,
-            SkiaPipeline::getLightRadius(), ambientAlpha, spotAlpha, SK_ColorBLACK,
-            casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0);
+        zParams = SkPoint3::Make(0, 0, casterProperties.getZ());
     }
+    SkShadowUtils::DrawShadow(canvas, *casterPath, zParams, skiaLightPos,
+        SkiaPipeline::getLightRadius(), ambientAlpha, spotAlpha, SK_ColorBLACK,
+        casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0);
 }
 
 }; // namespace skiapipeline
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index 496f7ba..3ddc09f 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -19,6 +19,7 @@
 #include "renderthread/CanvasContext.h"
 #include "VectorDrawable.h"
 #include "DumpOpsCanvas.h"
+#include "SkiaPipeline.h"
 
 #include <SkImagePriv.h>
 
@@ -92,6 +93,8 @@
         // If any vector drawable in the display list needs update, damage the node.
         if (vectorDrawable->isDirty()) {
             isDirty = true;
+            static_cast<SkiaPipeline*>(info.canvasContext.getRenderPipeline())
+                ->getVectorDrawables()->push_back(vectorDrawable);
         }
         vectorDrawable->setPropertyChangeWillBeConsumed(true);
     }
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
index 6ee5922..66375d1 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -60,7 +60,7 @@
      * Use the linear allocator to create any SkDrawables needed by the display
      * list. This could be dangerous as these objects are ref-counted, so we
      * need to monitor that they don't extend beyond the lifetime of the class
-     * that creates them.
+     * that creates them. Allocator dtor invokes all SkDrawable dtors.
      */
     template<class T, typename... Params>
     SkDrawable* allocateDrawable(Params&&... params) {
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index ae13131..6d5ef1d 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -16,6 +16,7 @@
 
 #include "SkiaOpenGLPipeline.h"
 
+#include "hwui/Bitmap.h"
 #include "DeferredLayerUpdater.h"
 #include "GlLayer.h"
 #include "LayerDrawable.h"
@@ -60,7 +61,7 @@
         const SkRect& dirty,
         const FrameBuilder::LightGeometry& lightGeometry,
         LayerUpdateQueue* layerUpdateQueue,
-        const Rect& contentDrawBounds, bool opaque,
+        const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
         const BakedOpRenderer::LightInfo& lightInfo,
         const std::vector<sp<RenderNode>>& renderNodes,
         FrameInfoVisualizer* profiler) {
@@ -84,7 +85,8 @@
             mRenderThread.getGrContext(), renderTargetDesc, &props));
 
     SkiaPipeline::updateLighting(lightGeometry, lightInfo);
-    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, wideColorGamut,
+            contentDrawBounds, surface);
     layerUpdateQueue->clear();
 
     // Draw visual debugging features
@@ -155,7 +157,8 @@
     }
 }
 
-bool SkiaOpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) {
+bool SkiaOpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior,
+        ColorMode colorMode) {
 
     if (mEglSurface != EGL_NO_SURFACE) {
         mEglManager.destroySurface(mEglSurface);
@@ -163,7 +166,8 @@
     }
 
     if (surface) {
-        mEglSurface = mEglManager.createSurface(surface);
+        const bool wideColorGamut = colorMode == ColorMode::WideColorGamut;
+        mEglSurface = mEglManager.createSurface(surface, wideColorGamut);
     }
 
     if (mEglSurface != EGL_NO_SURFACE) {
@@ -197,6 +201,186 @@
     }
 }
 
+#define FENCE_TIMEOUT 2000000000
+
+class AutoEglFence {
+public:
+    AutoEglFence(EGLDisplay display)
+            : mDisplay(display) {
+        fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
+    }
+
+    ~AutoEglFence() {
+        if (fence != EGL_NO_SYNC_KHR) {
+            eglDestroySyncKHR(mDisplay, fence);
+        }
+    }
+
+    EGLSyncKHR fence = EGL_NO_SYNC_KHR;
+private:
+    EGLDisplay mDisplay = EGL_NO_DISPLAY;
+};
+
+class AutoEglImage {
+public:
+    AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer)
+            : mDisplay(display) {
+        EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+        image = eglCreateImageKHR(display, EGL_NO_CONTEXT,
+                EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
+    }
+
+    ~AutoEglImage() {
+        if (image != EGL_NO_IMAGE_KHR) {
+            eglDestroyImageKHR(mDisplay, image);
+        }
+    }
+
+    EGLImageKHR image = EGL_NO_IMAGE_KHR;
+private:
+    EGLDisplay mDisplay = EGL_NO_DISPLAY;
+};
+
+class AutoSkiaGlTexture {
+public:
+    AutoSkiaGlTexture() {
+        glGenTextures(1, &mTexture);
+        glBindTexture(GL_TEXTURE_2D, mTexture);
+    }
+
+    ~AutoSkiaGlTexture() {
+        glDeleteTextures(1, &mTexture);
+    }
+
+private:
+    GLuint mTexture = 0;
+};
+
+sk_sp<Bitmap> SkiaOpenGLPipeline::allocateHardwareBitmap(renderthread::RenderThread& renderThread,
+        SkBitmap& skBitmap) {
+    renderThread.eglManager().initialize();
+
+    sk_sp<GrContext> grContext = sk_ref_sp(renderThread.getGrContext());
+    const SkImageInfo& info = skBitmap.info();
+    PixelFormat pixelFormat;
+    GLint format, type;
+    bool isSupported = false;
+
+    //TODO: add support for linear blending (when ANDROID_ENABLE_LINEAR_BLENDING is defined)
+    switch (info.colorType()) {
+    case kRGBA_8888_SkColorType:
+        isSupported = true;
+    // ARGB_4444 and Index_8 are both upconverted to RGBA_8888
+    case kIndex_8_SkColorType:
+    case kARGB_4444_SkColorType:
+        pixelFormat = PIXEL_FORMAT_RGBA_8888;
+        format = GL_RGBA;
+        type = GL_UNSIGNED_BYTE;
+        break;
+    case kRGBA_F16_SkColorType:
+        isSupported = grContext->caps()->isConfigTexturable(kRGBA_half_GrPixelConfig);
+        if (isSupported) {
+            type = GL_HALF_FLOAT;
+            pixelFormat = PIXEL_FORMAT_RGBA_FP16;
+        } else {
+            type = GL_UNSIGNED_BYTE;
+            pixelFormat = PIXEL_FORMAT_RGBA_8888;
+        }
+        format = GL_RGBA;
+        break;
+    case kRGB_565_SkColorType:
+        isSupported = true;
+        pixelFormat = PIXEL_FORMAT_RGB_565;
+        format = GL_RGB;
+        type = GL_UNSIGNED_SHORT_5_6_5;
+        break;
+    case kGray_8_SkColorType:
+        isSupported = true;
+        pixelFormat = PIXEL_FORMAT_RGBA_8888;
+        format = GL_LUMINANCE;
+        type = GL_UNSIGNED_BYTE;
+        break;
+    default:
+        ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType());
+        return nullptr;
+    }
+
+    SkBitmap bitmap;
+    if (isSupported) {
+        bitmap = skBitmap;
+    } else {
+        bitmap.allocPixels(SkImageInfo::MakeN32(info.width(), info.height(), info.alphaType(),
+                nullptr));
+        bitmap.eraseColor(0);
+        if (info.colorType() == kRGBA_F16_SkColorType) {
+            // Drawing RGBA_F16 onto ARGB_8888 is not supported
+            skBitmap.readPixels(bitmap.info().makeColorSpace(SkColorSpace::MakeSRGB()),
+                    bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
+        } else {
+            SkCanvas canvas(bitmap);
+            canvas.drawBitmap(skBitmap, 0.0f, 0.0f, nullptr);
+        }
+    }
+
+    sp<GraphicBuffer> buffer = new GraphicBuffer(info.width(), info.height(), pixelFormat,
+            GraphicBuffer::USAGE_HW_TEXTURE |
+            GraphicBuffer::USAGE_SW_WRITE_NEVER |
+            GraphicBuffer::USAGE_SW_READ_NEVER,
+            std::string("Bitmap::allocateSkiaHardwareBitmap pid [") + std::to_string(getpid()) + "]");
+
+    status_t error = buffer->initCheck();
+    if (error < 0) {
+        ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
+        return nullptr;
+    }
+
+    //upload the bitmap into a texture
+    EGLDisplay display = eglGetCurrentDisplay();
+    LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY,
+                "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
+                uirenderer::renderthread::EglManager::eglErrorString());
+    // We use an EGLImage to access the content of the GraphicBuffer
+    // The EGL image is later bound to a 2D texture
+    EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer->getNativeBuffer();
+    AutoEglImage autoImage(display, clientBuffer);
+    if (autoImage.image == EGL_NO_IMAGE_KHR) {
+        ALOGW("Could not create EGL image, err =%s",
+                uirenderer::renderthread::EglManager::eglErrorString());
+        return nullptr;
+    }
+    AutoSkiaGlTexture glTexture;
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
+    GL_CHECKPOINT(MODERATE);
+
+    // glTexSubImage2D is synchronous in sense that it memcpy() from pointer that we provide.
+    // But asynchronous in sense that driver may upload texture onto hardware buffer when we first
+    // use it in drawing
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, info.width(), info.height(), format, type,
+            bitmap.getPixels());
+    GL_CHECKPOINT(MODERATE);
+
+    // The fence is used to wait for the texture upload to finish
+    // properly. We cannot rely on glFlush() and glFinish() as
+    // some drivers completely ignore these API calls
+    AutoEglFence autoFence(display);
+    if (autoFence.fence == EGL_NO_SYNC_KHR) {
+        LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError());
+        return nullptr;
+    }
+    // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
+    // pipeline flush (similar to what a glFlush() would do.)
+    EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence,
+            EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
+    if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
+        LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError());
+        return nullptr;
+    }
+
+    grContext->resetContext(kTextureBinding_GrGLBackendState);
+
+    return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info()));
+}
+
 } /* namespace skiapipeline */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
index 36685dd..aa29c8e 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
@@ -19,6 +19,9 @@
 #include "SkiaPipeline.h"
 
 namespace android {
+
+class Bitmap;
+
 namespace uirenderer {
 namespace skiapipeline {
 
@@ -32,7 +35,7 @@
     bool draw(const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
             const FrameBuilder::LightGeometry& lightGeometry,
             LayerUpdateQueue* layerUpdateQueue,
-            const Rect& contentDrawBounds, bool opaque,
+            const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
             const BakedOpRenderer::LightInfo& lightInfo,
             const std::vector< sp<RenderNode> >& renderNodes,
             FrameInfoVisualizer* profiler) override;
@@ -40,12 +43,15 @@
             FrameInfo* currentFrameInfo, bool* requireSwap) override;
     bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) override;
     DeferredLayerUpdater* createTextureLayer() override;
-    bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior) override;
+    bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior,
+            renderthread::ColorMode colorMode) override;
     void onStop() override;
     bool isSurfaceReady() override;
     bool isContextReady() override;
 
     static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor);
+    static sk_sp<Bitmap> allocateHardwareBitmap(renderthread::RenderThread& thread,
+            SkBitmap& skBitmap);
 
 private:
     renderthread::EglManager& mEglManager;
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
index a18d264..89697d7 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
@@ -63,8 +63,6 @@
     CopyResult copyResult = CopyResult::UnknownError;
     sk_sp<SkImage> image(SkImage::MakeFromAdoptedTexture(grContext.get(), textureDescription));
     if (image) {
-        SkAutoLockPixels alp(*bitmap);
-
         // convert to Skia data structures
         const SkRect bufferRect = SkRect::MakeIWH(imgWidth, imgHeight);
         SkRect skiaSrcRect = srcRect.toSkRect();
@@ -88,23 +86,17 @@
         textureMatrix.mapRect(&skiaSrcRect);
 
         if (skiaSrcRect.intersect(bufferRect)) {
-            SkPoint srcOrigin = SkPoint::Make(skiaSrcRect.fLeft, skiaSrcRect.fTop);
+            // we render in an offscreen buffer to scale and to avoid an issue b/62262733
+            // with reading incorrect data from EGLImage backed SkImage (likely a driver bug)
+            sk_sp<SkSurface> scaledSurface = SkSurface::MakeRenderTarget(
+                    grContext.get(), SkBudgeted::kYes, bitmap->info());
+            SkPaint paint;
+            paint.setBlendMode(SkBlendMode::kSrc);
+            scaledSurface->getCanvas()->drawImageRect(image, skiaSrcRect,
+                    SkRect::MakeWH(bitmap->width(), bitmap->height()), &paint);
+            image = scaledSurface->makeImageSnapshot();
 
-            // if we need to scale the result we must render to an offscreen buffer
-            if (bitmap->width() != skiaSrcRect.width()
-                    || bitmap->height() != skiaSrcRect.height()) {
-                sk_sp<SkSurface> scaledSurface = SkSurface::MakeRenderTarget(
-                        grContext.get(), SkBudgeted::kYes, bitmap->info());
-                SkPaint paint;
-                paint.setBlendMode(SkBlendMode::kSrc);
-                scaledSurface->getCanvas()->drawImageRect(image, skiaSrcRect,
-                        SkRect::MakeWH(bitmap->width(), bitmap->height()), &paint);
-                image = scaledSurface->makeImageSnapshot();
-                srcOrigin.set(0,0);
-            }
-
-            if (image->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(),
-                                  srcOrigin.fX, srcOrigin.fY)) {
+            if (image->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), 0, 0)) {
                 copyResult = CopyResult::Success;
             }
         }
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 10c1865..0bab793 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -25,6 +25,7 @@
 #include <SkPictureRecorder.h>
 #include <SkPixelSerializer.h>
 #include <SkStream.h>
+#include "VectorDrawable.h"
 
 #include <unistd.h>
 
@@ -40,15 +41,16 @@
 
 Vector3 SkiaPipeline::mLightCenter = {FLT_MIN, FLT_MIN, FLT_MIN};
 
-SkiaPipeline::SkiaPipeline(RenderThread& thread) :  mRenderThread(thread) { }
+SkiaPipeline::SkiaPipeline(RenderThread& thread) :  mRenderThread(thread) {
+    mVectorDrawables.reserve(30);
+}
 
 TaskManager* SkiaPipeline::getTaskManager() {
     return &mTaskManager;
 }
 
 void SkiaPipeline::onDestroyHardwareResources() {
-    // No need to flush the caches here. There is a timer
-    // which will flush temporary resources over time.
+    mRenderThread.cacheManager().trimStaleResources();
 }
 
 bool SkiaPipeline::pinImages(std::vector<SkImage*>& mutableImages) {
@@ -70,15 +72,18 @@
 }
 
 void SkiaPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
-        LayerUpdateQueue* layerUpdateQueue, bool opaque,
+        LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
         const BakedOpRenderer::LightInfo& lightInfo) {
     updateLighting(lightGeometry, lightInfo);
     ATRACE_NAME("draw layers");
-    renderLayersImpl(*layerUpdateQueue, opaque);
+    renderVectorDrawableCache();
+    renderLayersImpl(*layerUpdateQueue, opaque, wideColorGamut);
     layerUpdateQueue->clear();
 }
 
-void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers, bool opaque) {
+void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers,
+        bool opaque, bool wideColorGamut) {
+    // TODO: Handle wide color gamut
     // Render all layers that need to be updated, in order.
     for (size_t i = 0; i < layers.entries().size(); i++) {
         RenderNode* layerNode = layers.entries()[i].renderNode.get();
@@ -126,12 +131,13 @@
 }
 
 bool SkiaPipeline::createOrUpdateLayer(RenderNode* node,
-        const DamageAccumulator& damageAccumulator) {
+        const DamageAccumulator& damageAccumulator, bool wideColorGamut) {
     SkSurface* layer = node->getLayerSurface();
     if (!layer || layer->width() != node->getWidth() || layer->height() != node->getHeight()) {
         SkImageInfo info = SkImageInfo::MakeN32Premul(node->getWidth(), node->getHeight());
         SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
         SkASSERT(mRenderThread.getGrContext() != nullptr);
+        // TODO: Handle wide color gamut requests
         node->setLayerSurface(
                 SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes,
                         info, 0, &props));
@@ -155,11 +161,11 @@
     GrContext* context = thread.getGrContext();
     if (context) {
         ATRACE_FORMAT("Bitmap#prepareToDraw %dx%d", bitmap->width(), bitmap->height());
-        SkBitmap skiaBitmap;
-        bitmap->getSkBitmap(&skiaBitmap);
-        sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skiaBitmap, kNever_SkCopyPixelsMode);
-        SkImage_pinAsTexture(image.get(), context);
-        SkImage_unpinAsTexture(image.get(), context);
+        auto image = bitmap->makeImage();
+        if (image.get() && !bitmap->isHardware()) {
+            SkImage_pinAsTexture(image.get(), context);
+            SkImage_unpinAsTexture(image.get(), context);
+        }
     }
 }
 
@@ -176,12 +182,37 @@
     }
 };
 
+void SkiaPipeline::renderVectorDrawableCache() {
+    //render VectorDrawables into offscreen buffers
+    for (auto vd : mVectorDrawables) {
+        sk_sp<SkSurface> surface;
+        if (!vd->canReuseSurface()) {
+#ifndef ANDROID_ENABLE_LINEAR_BLENDING
+            sk_sp<SkColorSpace> colorSpace = nullptr;
+#else
+            sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
+#endif
+            int scaledWidth = SkScalarCeilToInt(vd->properties().getScaledWidth());
+            int scaledHeight = SkScalarCeilToInt(vd->properties().getScaledHeight());
+            SkImageInfo info = SkImageInfo::MakeN32(scaledWidth, scaledHeight,
+                    kPremul_SkAlphaType, colorSpace);
+            SkASSERT(mRenderThread.getGrContext() != nullptr);
+            surface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes,
+                    info);
+        }
+        vd->updateCache(surface);
+    }
+    mVectorDrawables.clear();
+}
+
 void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
-        const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds,
-        sk_sp<SkSurface> surface) {
+        const std::vector<sp<RenderNode>>& nodes, bool opaque, bool wideColorGamut,
+        const Rect &contentDrawBounds, sk_sp<SkSurface> surface) {
+
+    renderVectorDrawableCache();
 
     // draw all layers up front
-    renderLayersImpl(layers, opaque);
+    renderLayersImpl(layers, opaque, wideColorGamut);
 
     // initialize the canvas for the current frame
     SkCanvas* canvas = surface->getCanvas();
@@ -199,7 +230,7 @@
         }
     }
 
-    renderFrameImpl(layers, clip, nodes, opaque, contentDrawBounds, canvas);
+    renderFrameImpl(layers, clip, nodes, opaque, wideColorGamut, contentDrawBounds, canvas);
 
     if (skpCaptureEnabled() && recordingPicture) {
         sk_sp<SkPicture> picture = recorder->finishRecordingAsPicture();
@@ -232,8 +263,8 @@
 }
 
 void SkiaPipeline::renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip,
-        const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds,
-        SkCanvas* canvas) {
+        const std::vector<sp<RenderNode>>& nodes, bool opaque, bool wideColorGamut,
+        const Rect &contentDrawBounds, SkCanvas* canvas) {
     SkAutoCanvasRestore saver(canvas, true);
     canvas->androidFramework_setDeviceClipRestriction(clip.roundOut());
 
@@ -360,7 +391,7 @@
     // each time a pixel would have been drawn.
     // Pass true for opaque so we skip the clear - the overdrawCanvas is already zero
     // initialized.
-    renderFrameImpl(layers, clip, nodes, true, contentDrawBounds, &overdrawCanvas);
+    renderFrameImpl(layers, clip, nodes, true, false, contentDrawBounds, &overdrawCanvas);
     sk_sp<SkImage> counts = offscreen->makeImageSnapshot();
 
     // Draw overdraw colors to the canvas.  The color filter will convert counts to colors.
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index c58fedf..19ffc46 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -39,21 +39,23 @@
     void unpinImages() override;
 
     void renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
-            LayerUpdateQueue* layerUpdateQueue, bool opaque,
+            LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
             const BakedOpRenderer::LightInfo& lightInfo) override;
 
     bool createOrUpdateLayer(RenderNode* node,
-            const DamageAccumulator& damageAccumulator) override;
+            const DamageAccumulator& damageAccumulator, bool wideColorGamut) override;
 
     void renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
-            const std::vector< sp<RenderNode> >& nodes, bool opaque, const Rect &contentDrawBounds,
-            sk_sp<SkSurface> surface);
+            const std::vector< sp<RenderNode> >& nodes, bool opaque, bool wideColorGamut,
+            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);
 
-    static void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque);
+    static void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque, bool wideColorGamut);
 
     static bool skpCaptureEnabled() { return false; }
 
@@ -108,8 +110,8 @@
 
 private:
     void renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip,
-            const std::vector< sp<RenderNode> >& nodes, bool opaque, const Rect &contentDrawBounds,
-            SkCanvas* canvas);
+            const std::vector< sp<RenderNode> >& nodes, bool opaque, bool wideColorGamut,
+            const Rect &contentDrawBounds, SkCanvas* canvas);
 
     /**
      *  Debugging feature.  Draws a semi-transparent overlay on each pixel, indicating
@@ -119,8 +121,18 @@
             const std::vector< sp<RenderNode> >& nodes, const Rect &contentDrawBounds,
             sk_sp<SkSurface>);
 
+    /**
+     *  Render mVectorDrawables into offscreen buffers.
+     */
+    void renderVectorDrawableCache();
+
     TaskManager mTaskManager;
     std::vector<sk_sp<SkImage>> mPinnedImages;
+
+    /**
+     *  populated by prepareTree with dirty VDs
+     */
+    std::vector<VectorDrawableRoot*> mVectorDrawables;
     static float mLightRadius;
     static uint8_t mAmbientShadowAlpha;
     static uint8_t mSpotShadowAlpha;
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 559d268..a0cce98 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -62,6 +62,7 @@
         uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
         uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
         uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* paint) {
+    // Destructor of drawables created with allocateDrawable, will be invoked by ~LinearAllocator.
     drawDrawable(mDisplayList->allocateDrawable<AnimatedRoundRect>(left, top, right, bottom,
             rx, ry, paint));
 }
@@ -92,13 +93,14 @@
 void SkiaRecordingCanvas::drawLayer(uirenderer::DeferredLayerUpdater* layerUpdater) {
     if (layerUpdater != nullptr && layerUpdater->backingLayer() != nullptr) {
         uirenderer::Layer* layer = layerUpdater->backingLayer();
+        // Create a ref-counted drawable, which is kept alive by sk_sp in SkLiteDL.
         sk_sp<SkDrawable> drawable(new LayerDrawable(layer));
         drawDrawable(drawable.get());
     }
 }
 
 void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) {
-    // record the child node
+    // Record the child node. Drawable dtor will be invoked when mChildNodes deque is cleared.
     mDisplayList->mChildNodes.emplace_back(renderNode, asSkCanvas(), true, mCurrentBarrier);
     auto& renderNodeDrawable = mDisplayList->mChildNodes.back();
     drawDrawable(&renderNodeDrawable);
@@ -113,6 +115,7 @@
 
 void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor,
         uirenderer::GlFunctorLifecycleListener* listener) {
+    // Drawable dtor will be invoked when mChildFunctors deque is cleared.
     mDisplayList->mChildFunctors.emplace_back(functor, listener, asSkCanvas());
     drawDrawable(&mDisplayList->mChildFunctors.back());
 }
@@ -126,22 +129,7 @@
          return SkRect::MakeLargest();
      }
      virtual void onDraw(SkCanvas* canvas) override {
-         Bitmap& hwuiBitmap = mRoot->getBitmapUpdateIfDirty();
-         SkBitmap bitmap;
-         hwuiBitmap.getSkBitmap(&bitmap);
-         SkPaint* paint = mRoot->getPaint();
-         canvas->drawBitmapRect(bitmap, mRoot->mutateProperties()->getBounds(), paint);
-         /*
-          * TODO we can draw this directly but need to address the following...
-          *
-          * 1) Add drawDirect(SkCanvas*) to VectorDrawableRoot
-          * 2) fix VectorDrawable.cpp's Path::draw to not make a temporary path
-          *    so that we don't break caching
-          * 3) figure out how to set path's as volatile during animation
-          * 4) if mRoot->getPaint() != null either promote to layer (during
-          *    animation) or cache in SkSurface (for static content)
-          *
-          */
+         mRoot->draw(canvas);
      }
 
  private:
@@ -168,53 +156,47 @@
 }
 
 void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) {
-    SkBitmap skBitmap;
-    bitmap.getSkBitmap(&skBitmap);
-
-    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skBitmap, kNever_SkCopyPixelsMode);
-    if (!skBitmap.isImmutable()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    sk_sp<SkImage> image = bitmap.makeImage();
     SkPaint tmpPaint;
     mRecorder.drawImage(image, left, top, nonAAPaint(paint, &tmpPaint));
+    // 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.
+    if (!bitmap.isImmutable() && image.get() && !image->unique()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
 }
 
 void SkiaRecordingCanvas::drawBitmap(Bitmap& hwuiBitmap, const SkMatrix& matrix,
         const SkPaint* paint) {
-    SkBitmap bitmap;
-    hwuiBitmap.getSkBitmap(&bitmap);
     SkAutoCanvasRestore acr(&mRecorder, true);
     concat(matrix);
-    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
-    if (!bitmap.isImmutable()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    sk_sp<SkImage> image = hwuiBitmap.makeImage();
     SkPaint tmpPaint;
     mRecorder.drawImage(image, 0, 0, nonAAPaint(paint, &tmpPaint));
+    if (!hwuiBitmap.isImmutable() && image.get() && !image->unique()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
 }
 
 void SkiaRecordingCanvas::drawBitmap(Bitmap& hwuiBitmap, float srcLeft, float srcTop,
         float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight,
         float dstBottom, const SkPaint* paint) {
-    SkBitmap bitmap;
-    hwuiBitmap.getSkBitmap(&bitmap);
     SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom);
     SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
-    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
-    if (!bitmap.isImmutable()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    sk_sp<SkImage> image = hwuiBitmap.makeImage();
     SkPaint tmpPaint;
     mRecorder.drawImageRect(image, srcRect, dstRect, nonAAPaint(paint, &tmpPaint));
+    if (!hwuiBitmap.isImmutable() && image.get() && !image->unique() && !srcRect.isEmpty()
+            && !dstRect.isEmpty()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
 }
 
 void SkiaRecordingCanvas::drawNinePatch(Bitmap& hwuiBitmap, const Res_png_9patch& chunk,
         float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) {
-    SkBitmap bitmap;
-    hwuiBitmap.getSkBitmap(&bitmap);
-
     SkCanvas::Lattice lattice;
-    NinePatchUtils::SetLatticeDivs(&lattice, chunk, bitmap.width(), bitmap.height());
+    NinePatchUtils::SetLatticeDivs(&lattice, chunk, hwuiBitmap.width(), hwuiBitmap.height());
 
     lattice.fFlags = nullptr;
     int numFlags = 0;
@@ -231,13 +213,13 @@
 
     lattice.fBounds = nullptr;
     SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
-    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
-    if (!bitmap.isImmutable()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    sk_sp<SkImage> image = hwuiBitmap.makeImage();
 
     SkPaint tmpPaint;
     mRecorder.drawImageLattice(image.get(), lattice, dst, nonAAPaint(paint, &tmpPaint));
+    if (!hwuiBitmap.isImmutable() && image.get() && !image->unique() && !dst.isEmpty()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
 }
 
 }; // namespace skiapipeline
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index d28e605..e1ef71f7 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -66,7 +66,7 @@
         const SkRect& dirty,
         const FrameBuilder::LightGeometry& lightGeometry,
         LayerUpdateQueue* layerUpdateQueue,
-        const Rect& contentDrawBounds, bool opaque,
+        const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
         const BakedOpRenderer::LightInfo& lightInfo,
         const std::vector<sp<RenderNode>>& renderNodes,
         FrameInfoVisualizer* profiler) {
@@ -76,7 +76,8 @@
         return false;
     }
     SkiaPipeline::updateLighting(lightGeometry, lightInfo);
-    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer);
+    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, wideColorGamut,
+            contentDrawBounds, backBuffer);
     layerUpdateQueue->clear();
 
     // Draw visual debugging features
@@ -131,13 +132,15 @@
 void SkiaVulkanPipeline::onStop() {
 }
 
-bool SkiaVulkanPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) {
+bool SkiaVulkanPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior,
+        ColorMode colorMode) {
     if (mVkSurface) {
         mVkManager.destroySurface(mVkSurface);
         mVkSurface = nullptr;
     }
 
     if (surface) {
+        // TODO: handle color mode
         mVkSurface = mVkManager.createSurface(surface);
     }
 
@@ -158,6 +161,25 @@
     (*functor)(mode, nullptr);
 }
 
+sk_sp<Bitmap> SkiaVulkanPipeline::allocateHardwareBitmap(renderthread::RenderThread& renderThread,
+        SkBitmap& skBitmap) {
+    //TODO: implement this function for Vulkan pipeline
+    //code below is a hack to avoid crashing because of missing HW Bitmap support
+    sp<GraphicBuffer> buffer = new GraphicBuffer(skBitmap.info().width(), skBitmap.info().height(),
+            PIXEL_FORMAT_RGBA_8888,
+            GraphicBuffer::USAGE_HW_TEXTURE |
+            GraphicBuffer::USAGE_SW_WRITE_NEVER |
+            GraphicBuffer::USAGE_SW_READ_NEVER,
+            std::string("SkiaVulkanPipeline::allocateHardwareBitmap pid [")
+            + std::to_string(getpid()) + "]");
+    status_t error = buffer->initCheck();
+    if (error < 0) {
+        ALOGW("SkiaVulkanPipeline::allocateHardwareBitmap() failed in GraphicBuffer.create()");
+        return nullptr;
+    }
+    return sk_sp<Bitmap>(new Bitmap(buffer.get(), skBitmap.info()));
+}
+
 } /* namespace skiapipeline */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index aab1d7a..263206d 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -33,7 +33,7 @@
     bool draw(const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
             const FrameBuilder::LightGeometry& lightGeometry,
             LayerUpdateQueue* layerUpdateQueue,
-            const Rect& contentDrawBounds, bool opaque,
+            const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
             const BakedOpRenderer::LightInfo& lightInfo,
             const std::vector< sp<RenderNode> >& renderNodes,
             FrameInfoVisualizer* profiler) override;
@@ -41,12 +41,15 @@
             FrameInfo* currentFrameInfo, bool* requireSwap) override;
     bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) override;
     DeferredLayerUpdater* createTextureLayer() override;
-    bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior) override;
+    bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior,
+            renderthread::ColorMode colorMode) override;
     void onStop() override;
     bool isSurfaceReady() override;
     bool isContextReady() override;
 
     static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor);
+    static sk_sp<Bitmap> allocateHardwareBitmap(renderthread::RenderThread& thread,
+            SkBitmap& skBitmap);
 
 private:
     renderthread::VulkanManager& mVkManager;
diff --git a/libs/hwui/renderstate/OffscreenBufferPool.cpp b/libs/hwui/renderstate/OffscreenBufferPool.cpp
index a9bbb27..90b27c8 100644
--- a/libs/hwui/renderstate/OffscreenBufferPool.cpp
+++ b/libs/hwui/renderstate/OffscreenBufferPool.cpp
@@ -35,17 +35,19 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 OffscreenBuffer::OffscreenBuffer(RenderState& renderState, Caches& caches,
-        uint32_t viewportWidth, uint32_t viewportHeight)
+        uint32_t viewportWidth, uint32_t viewportHeight, bool wideColorGamut)
         : GpuMemoryTracker(GpuObjectType::OffscreenBuffer)
         , renderState(renderState)
         , viewportWidth(viewportWidth)
         , viewportHeight(viewportHeight)
-        , texture(caches) {
+        , texture(caches)
+        , wideColorGamut(wideColorGamut) {
     uint32_t width = computeIdealDimension(viewportWidth);
     uint32_t height = computeIdealDimension(viewportHeight);
     ATRACE_FORMAT("Allocate %ux%u HW Layer", width, height);
     caches.textureState().activateTexture(0);
-    texture.resize(width, height, caches.rgbaInternalFormat(), GL_RGBA);
+    texture.resize(width, height,
+            wideColorGamut ? GL_RGBA16F : caches.rgbaInternalFormat(), GL_RGBA);
     texture.blend = true;
     texture.setWrap(GL_CLAMP_TO_EDGE);
     // not setting filter on texture, since it's set when drawing, based on transform
@@ -127,7 +129,10 @@
     int deltaInt = int(lhs.width) - int(rhs.width);
     if (deltaInt != 0) return deltaInt;
 
-    return int(lhs.height) - int(rhs.height);
+    deltaInt = int(lhs.height) - int(rhs.height);
+    if (deltaInt != 0) return deltaInt;
+
+    return int(lhs.wideColorGamut) - int(rhs.wideColorGamut);
 }
 
 void OffscreenBufferPool::clear() {
@@ -139,10 +144,10 @@
 }
 
 OffscreenBuffer* OffscreenBufferPool::get(RenderState& renderState,
-        const uint32_t width, const uint32_t height) {
+        const uint32_t width, const uint32_t height, bool wideColorGamut) {
     OffscreenBuffer* layer = nullptr;
 
-    Entry entry(width, height);
+    Entry entry(width, height, wideColorGamut);
     auto iter = mPool.find(entry);
 
     if (iter != mPool.end()) {
@@ -154,7 +159,8 @@
         layer->viewportHeight = height;
         mSize -= layer->getSizeInBytes();
     } else {
-        layer = new OffscreenBuffer(renderState, Caches::getInstance(), width, height);
+        layer = new OffscreenBuffer(renderState, Caches::getInstance(),
+                width, height, wideColorGamut);
     }
 
     return layer;
@@ -174,7 +180,7 @@
         return layer;
     }
     putOrDelete(layer);
-    return get(renderState, width, height);
+    return get(renderState, width, height, layer->wideColorGamut);
 }
 
 void OffscreenBufferPool::dump() {
diff --git a/libs/hwui/renderstate/OffscreenBufferPool.h b/libs/hwui/renderstate/OffscreenBufferPool.h
index 26d4e36..d9422c9 100644
--- a/libs/hwui/renderstate/OffscreenBufferPool.h
+++ b/libs/hwui/renderstate/OffscreenBufferPool.h
@@ -43,7 +43,7 @@
 class OffscreenBuffer : GpuMemoryTracker {
 public:
     OffscreenBuffer(RenderState& renderState, Caches& caches,
-            uint32_t viewportWidth, uint32_t viewportHeight);
+            uint32_t viewportWidth, uint32_t viewportHeight, bool wideColorGamut = false);
     ~OffscreenBuffer();
 
     Rect getTextureCoordinates();
@@ -68,6 +68,8 @@
     uint32_t viewportHeight;
     Texture texture;
 
+    bool wideColorGamut = false;
+
     // Portion of layer that has been drawn to. Used to minimize drawing area when
     // drawing back to screen / parent FBO.
     Region region;
@@ -90,7 +92,7 @@
     ~OffscreenBufferPool();
 
     WARN_UNUSED_RESULT OffscreenBuffer* get(RenderState& renderState,
-            const uint32_t width, const uint32_t height);
+            const uint32_t width, const uint32_t height, bool wideColorGamut = false);
 
     WARN_UNUSED_RESULT OffscreenBuffer* resize(OffscreenBuffer* layer,
             const uint32_t width, const uint32_t height);
@@ -122,14 +124,16 @@
     struct Entry {
         Entry() {}
 
-        Entry(const uint32_t layerWidth, const uint32_t layerHeight)
+        Entry(const uint32_t layerWidth, const uint32_t layerHeight, bool wideColorGamut)
                 : width(OffscreenBuffer::computeIdealDimension(layerWidth))
-                , height(OffscreenBuffer::computeIdealDimension(layerHeight)) {}
+                , height(OffscreenBuffer::computeIdealDimension(layerHeight))
+                , wideColorGamut(wideColorGamut) {}
 
         explicit Entry(OffscreenBuffer* layer)
                 : layer(layer)
                 , width(layer->texture.width())
-                , height(layer->texture.height()) {
+                , height(layer->texture.height())
+                , wideColorGamut(layer->wideColorGamut) {
         }
 
         static int compare(const Entry& lhs, const Entry& rhs);
@@ -149,6 +153,7 @@
         OffscreenBuffer* layer = nullptr;
         uint32_t width = 0;
         uint32_t height = 0;
+        bool wideColorGamut = false;
     }; // struct Entry
 
     std::multiset<Entry> mPool;
diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h
index 787946f..4b7a865 100644
--- a/libs/hwui/renderstate/RenderState.h
+++ b/libs/hwui/renderstate/RenderState.h
@@ -45,6 +45,7 @@
 class DeferredLayerUpdater;
 
 namespace renderthread {
+class CacheManager;
 class CanvasContext;
 class RenderThread;
 }
@@ -55,6 +56,7 @@
     PREVENT_COPY_AND_ASSIGN(RenderState);
     friend class renderthread::RenderThread;
     friend class Caches;
+    friend class renderthread::CacheManager;
 public:
     void onGLContextCreated();
     void onGLContextDestroyed();
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
new file mode 100644
index 0000000..f0d6b38
--- /dev/null
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CacheManager.h"
+
+#include "Layer.h"
+#include "RenderThread.h"
+#include "renderstate/RenderState.h"
+
+#include <gui/Surface.h>
+#include <GrContextOptions.h>
+#include <math.h>
+#include <set>
+
+namespace android {
+namespace uirenderer {
+namespace renderthread {
+
+// This multiplier was selected based on historical review of cache sizes relative
+// to the screen resolution. This is meant to be a conservative default based on
+// that analysis. The 4.0f is used because the default pixel format is assumed to
+// be ARGB_8888.
+#define SURFACE_SIZE_MULTIPLIER (12.0f * 4.0f)
+#define BACKGROUND_RETENTION_PERCENTAGE (0.5f)
+
+// for super large fonts we will draw them as paths so no need to keep linearly
+// increasing the font cache size.
+#define FONT_CACHE_MIN_MB (0.5f)
+#define FONT_CACHE_MAX_MB (4.0f)
+
+CacheManager::CacheManager(const DisplayInfo& display)
+        : mMaxSurfaceArea(display.w * display.h) {
+    mVectorDrawableAtlas.reset(new VectorDrawableAtlas);
+}
+
+void CacheManager::reset(GrContext* context) {
+    if (context != mGrContext.get()) {
+        destroy();
+    }
+
+    if (context) {
+        mGrContext = sk_ref_sp(context);
+        mGrContext->getResourceCacheLimits(&mMaxResources, nullptr);
+        updateContextCacheSizes();
+    }
+}
+
+void CacheManager::destroy() {
+    // cleanup any caches here as the GrContext is about to go away...
+    mGrContext.reset(nullptr);
+    mVectorDrawableAtlas.reset(new VectorDrawableAtlas);
+}
+
+void CacheManager::updateContextCacheSizes() {
+    mMaxResourceBytes = mMaxSurfaceArea * SURFACE_SIZE_MULTIPLIER;
+    mBackgroundResourceBytes = mMaxResourceBytes * BACKGROUND_RETENTION_PERCENTAGE;
+
+    mGrContext->setResourceCacheLimits(mMaxResources, mMaxResourceBytes);
+}
+
+void CacheManager::configureContext(GrContextOptions* contextOptions) {
+    contextOptions->fAllowPathMaskCaching = true;
+
+    float screenMP = mMaxSurfaceArea / 1024.0f / 1024.0f;
+    float fontCacheMB = 0;
+    float decimalVal = std::modf(screenMP, &fontCacheMB);
+
+    // This is a basic heuristic to size the cache to a multiple of 512 KB
+    if (decimalVal > 0.8f) {
+        fontCacheMB += 1.0f;
+    } else if (decimalVal > 0.5f) {
+        fontCacheMB += 0.5f;
+    }
+
+    // set limits on min/max size of the cache
+    fontCacheMB = std::max(FONT_CACHE_MIN_MB, std::min(FONT_CACHE_MAX_MB, fontCacheMB));
+
+    // We must currently set the size of the text cache based on the size of the
+    // display even though we like to  be dynamicallysizing it to the size of the window.
+    // Skia's implementation doesn't provide a mechanism to resize the font cache due to
+    // the potential cost of recreating the glyphs.
+    contextOptions->fGlyphCacheTextureMaximumBytes = fontCacheMB * 1024 * 1024;
+}
+
+void CacheManager::trimMemory(TrimMemoryMode mode) {
+    if (!mGrContext) {
+        return;
+    }
+
+    mGrContext->flush();
+
+    switch (mode) {
+        case TrimMemoryMode::Complete:
+            mVectorDrawableAtlas.reset(new VectorDrawableAtlas);
+            mGrContext->freeGpuResources();
+            break;
+        case TrimMemoryMode::UiHidden:
+            mGrContext->purgeUnlockedResources(mMaxResourceBytes - mBackgroundResourceBytes, true);
+            break;
+    }
+}
+
+void CacheManager::trimStaleResources() {
+    if (!mGrContext) {
+        return;
+    }
+    mGrContext->flush();
+    mGrContext->purgeResourcesNotUsedInMs(std::chrono::seconds(30));
+}
+
+VectorDrawableAtlas* CacheManager::acquireVectorDrawableAtlas() {
+    LOG_ALWAYS_FATAL_IF(mVectorDrawableAtlas.get() == nullptr);
+    LOG_ALWAYS_FATAL_IF(mGrContext == nullptr);
+
+    /**
+     * TODO LIST:
+     *    1) compute the atlas based on the surfaceArea surface
+     *    2) identify a way to reuse cache entries
+     *    3) add ability to repack the cache?
+     *    4) define memory conditions where we clear the cache (e.g. surface->reset())
+     */
+
+    return mVectorDrawableAtlas.release();
+}
+void CacheManager::releaseVectorDrawableAtlas(VectorDrawableAtlas* atlas) {
+    LOG_ALWAYS_FATAL_IF(mVectorDrawableAtlas.get() != nullptr);
+    mVectorDrawableAtlas.reset(atlas);
+    mVectorDrawableAtlas->isNewAtlas = false;
+}
+
+void CacheManager::dumpMemoryUsage(String8& log, const RenderState* renderState) {
+    if (!mGrContext) {
+        log.appendFormat("No valid cache instance.\n");
+        return;
+    }
+
+    size_t bytesCached;
+    mGrContext->getResourceCacheUsage(nullptr, &bytesCached);
+
+    log.appendFormat("Caches:\n");
+    log.appendFormat("                         Current / Maximum\n");
+    log.appendFormat("  VectorDrawableAtlas  %6.2f kB / %6.2f kB (entries = %zu)\n",
+            0.0f, 0.0f, (size_t)0);
+
+    if (renderState) {
+        if (renderState->mActiveLayers.size() > 0) {
+            log.appendFormat("  Layer Info:\n");
+        }
+
+        size_t layerMemoryTotal = 0;
+        for (std::set<Layer*>::iterator it = renderState->mActiveLayers.begin();
+                it != renderState->mActiveLayers.end(); it++) {
+            const Layer* layer = *it;
+            const char* layerType = layer->getApi() == Layer::Api::OpenGL ? "GlLayer" : "VkLayer";
+            log.appendFormat("    %s size %dx%d\n", layerType,
+                    layer->getWidth(), layer->getHeight());
+            layerMemoryTotal += layer->getWidth() * layer->getHeight() * 4;
+        }
+        log.appendFormat("  Layers Total         %6.2f kB (numLayers = %zu)\n",
+                         layerMemoryTotal / 1024.0f, renderState->mActiveLayers.size());
+    }
+
+
+    log.appendFormat("Total memory usage:\n");
+    log.appendFormat("  %zu bytes, %.2f MB (%.2f MB is purgeable)\n",
+                     bytesCached, bytesCached / 1024.0f / 1024.0f,
+                     mGrContext->getResourceCachePurgeableBytes() / 1024.0f / 1024.0f);
+
+
+}
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h
new file mode 100644
index 0000000..43d58f2
--- /dev/null
+++ b/libs/hwui/renderthread/CacheManager.h
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+#ifndef CACHEMANAGER_H
+#define CACHEMANAGER_H
+
+#include <GrContext.h>
+#include <SkSurface.h>
+#include <ui/DisplayInfo.h>
+#include <utils/String8.h>
+#include <vector>
+
+namespace android {
+
+class Surface;
+
+namespace uirenderer {
+
+class RenderState;
+
+namespace renderthread {
+
+class IRenderPipeline;
+class RenderThread;
+
+struct VectorDrawableAtlas {
+    sk_sp<SkSurface> surface;
+    bool isNewAtlas = true;
+};
+
+class CacheManager {
+public:
+    enum class TrimMemoryMode {
+        Complete,
+        UiHidden
+    };
+
+    void configureContext(GrContextOptions* context);
+    void trimMemory(TrimMemoryMode mode);
+    void trimStaleResources();
+    void dumpMemoryUsage(String8& log, const RenderState* renderState = nullptr);
+
+    VectorDrawableAtlas* acquireVectorDrawableAtlas();
+    void releaseVectorDrawableAtlas(VectorDrawableAtlas*);
+
+    size_t getCacheSize() const { return mMaxResourceBytes; }
+    size_t getBackgroundCacheSize() const { return mBackgroundResourceBytes; }
+
+private:
+    friend class RenderThread;
+
+    CacheManager(const DisplayInfo& display);
+
+
+    void reset(GrContext* grContext);
+    void destroy();
+    void updateContextCacheSizes();
+
+    const size_t mMaxSurfaceArea;
+    sk_sp<GrContext> mGrContext;
+
+    int mMaxResources = 0;
+    size_t mMaxResourceBytes = 0;
+    size_t mBackgroundResourceBytes = 0;
+
+    struct PipelineProps {
+        const void* pipelineKey = nullptr;
+        size_t surfaceArea = 0;
+    };
+
+    std::unique_ptr<VectorDrawableAtlas> mVectorDrawableAtlas;
+};
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* CACHEMANAGER_H */
+
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 9c80ab3..7799248 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -186,7 +186,8 @@
 
     mNativeSurface = surface;
 
-    bool hasSurface = mRenderPipeline->setSurface(surface, mSwapBehavior);
+    ColorMode colorMode = mWideColorGamut ? ColorMode::WideColorGamut : ColorMode::Srgb;
+    bool hasSurface = mRenderPipeline->setSurface(surface, mSwapBehavior, colorMode);
 
     mFrameNumber = -1;
 
@@ -241,6 +242,10 @@
     mOpaque = opaque;
 }
 
+void CanvasContext::setWideGamut(bool wideGamut) {
+    mWideColorGamut = wideGamut;
+}
+
 bool CanvasContext::makeCurrent() {
     if (mStopped) return false;
 
@@ -416,7 +421,7 @@
     SkRect windowDirty = computeDirtyRect(frame, &dirty);
 
     bool drew = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry, &mLayerUpdateQueue,
-            mContentDrawBounds, mOpaque, mLightInfo, mRenderNodes, &(profiler()));
+            mContentDrawBounds, mOpaque, mWideColorGamut, mLightInfo, mRenderNodes, &(profiler()));
 
     waitOnFences();
 
@@ -558,7 +563,8 @@
     // purposes when the frame is actually drawn
     node->setPropertyFieldsDirty(RenderNode::GENERIC);
 
-    mRenderPipeline->renderLayers(mLightGeometry, &mLayerUpdateQueue, mOpaque, mLightInfo);
+    mRenderPipeline->renderLayers(mLightGeometry, &mLayerUpdateQueue,
+            mOpaque, mWideColorGamut, mLightInfo);
 
     node->incStrong(nullptr);
     mPrefetchedLayers.insert(node);
@@ -580,15 +586,37 @@
 }
 
 void CanvasContext::trimMemory(RenderThread& thread, int level) {
-    // No context means nothing to free
-    if (!thread.eglManager().hasEglContext()) return;
-
-    ATRACE_CALL();
-    if (level >= TRIM_MEMORY_COMPLETE) {
-        thread.renderState().flush(Caches::FlushMode::Full);
-        thread.eglManager().destroy();
-    } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
-        thread.renderState().flush(Caches::FlushMode::Moderate);
+    auto renderType = Properties::getRenderPipelineType();
+    switch (renderType) {
+        case RenderPipelineType::OpenGL: {
+            // No context means nothing to free
+            if (!thread.eglManager().hasEglContext()) return;
+            ATRACE_CALL();
+            if (level >= TRIM_MEMORY_COMPLETE) {
+                thread.renderState().flush(Caches::FlushMode::Full);
+                thread.eglManager().destroy();
+            } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
+                thread.renderState().flush(Caches::FlushMode::Moderate);
+            }
+            break;
+        }
+        case RenderPipelineType::SkiaGL:
+        case RenderPipelineType::SkiaVulkan: {
+            // No context means nothing to free
+            if (!thread.getGrContext()) return;
+            ATRACE_CALL();
+            if (level >= TRIM_MEMORY_COMPLETE) {
+                thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
+                thread.eglManager().destroy();
+                thread.vulkanManager().destroy();
+            } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
+                thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::UiHidden);
+            }
+            break;
+        }
+        default:
+            LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+            break;
     }
 }
 
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 738c091..b1f4050 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -76,7 +76,7 @@
      *  @return true if the layer has been created or updated
      */
     bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& dmgAccumulator) {
-        return mRenderPipeline->createOrUpdateLayer(node, dmgAccumulator);
+        return mRenderPipeline->createOrUpdateLayer(node, dmgAccumulator, mWideColorGamut);
     }
 
     /**
@@ -128,6 +128,7 @@
             uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
     void setLightCenter(const Vector3& lightCenter);
     void setOpaque(bool opaque);
+    void setWideGamut(bool wideGamut);
     bool makeCurrent();
     void prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
             int64_t syncQueued, RenderNode* target);
@@ -194,6 +195,8 @@
 
     void waitOnFences();
 
+    IRenderPipeline* getRenderPipeline() { return mRenderPipeline.get(); }
+
 private:
     CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
             IContextFactory* contextFactory, std::unique_ptr<IRenderPipeline> renderPipeline);
@@ -238,6 +241,7 @@
     nsecs_t mLastDropVsync = 0;
 
     bool mOpaque;
+    bool mWideColorGamut = false;
     BakedOpRenderer::LightInfo mLightInfo;
     FrameBuilder::LightGeometry mLightGeometry = { {0, 0, 0}, 0 };
 
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index ed30708..0e676ee 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -76,12 +76,17 @@
 static struct {
     bool bufferAge = false;
     bool setDamage = false;
+    bool noConfigContext = false;
+    bool pixelFormatFloat = false;
+    bool glColorSpace = false;
+    bool scRGB = false;
 } EglExtensions;
 
 EglManager::EglManager(RenderThread& thread)
         : mRenderThread(thread)
         , mEglDisplay(EGL_NO_DISPLAY)
         , mEglConfig(nullptr)
+        , mEglConfigWideGamut(nullptr)
         , mEglContext(EGL_NO_CONTEXT)
         , mPBufferSurface(EGL_NO_SURFACE)
         , mCurrentSurface(EGL_NO_SURFACE) {
@@ -116,7 +121,7 @@
         }
     }
 
-    loadConfig();
+    loadConfigs();
     createContext();
     createPBufferSurface();
     makeCurrent(mPBufferSurface);
@@ -134,7 +139,7 @@
 
         GrContextOptions options;
         options.fGpuPathRenderers &= ~GrContextOptions::GpuPathRenderers::kDistanceField;
-        options.fAllowPathMaskCaching = true;
+        mRenderThread.cacheManager().configureContext(&options);
         mRenderThread.setGrContext(GrContext::Create(GrBackend::kOpenGL_GrBackend,
                 (GrBackendContext)glInterface.get(), options));
     }
@@ -143,6 +148,7 @@
 void EglManager::initExtensions() {
     auto extensions = StringUtils::split(
             eglQueryString(mEglDisplay, EGL_EXTENSIONS));
+
     // For our purposes we don't care if EGL_BUFFER_AGE is a result of
     // EGL_EXT_buffer_age or EGL_KHR_partial_update as our usage is covered
     // under EGL_KHR_partial_update and we don't need the expanded scope
@@ -152,13 +158,22 @@
     EglExtensions.setDamage = extensions.has("EGL_KHR_partial_update");
     LOG_ALWAYS_FATAL_IF(!extensions.has("EGL_KHR_swap_buffers_with_damage"),
             "Missing required extension EGL_KHR_swap_buffers_with_damage");
+
+    EglExtensions.glColorSpace = extensions.has("EGL_KHR_gl_colorspace");
+    EglExtensions.noConfigContext = extensions.has("EGL_KHR_no_config_context");
+    EglExtensions.pixelFormatFloat = extensions.has("EGL_EXT_pixel_format_float");
+#ifdef ANDROID_ENABLE_LINEAR_BLENDING
+    EglExtensions.scRGB = extensions.has("EGL_EXT_gl_colorspace_scrgb_linear");
+#else
+    EglExtensions.scRGB = extensions.has("EGL_EXT_gl_colorspace_scrgb");
+#endif
 }
 
 bool EglManager::hasEglContext() {
     return mEglDisplay != EGL_NO_DISPLAY;
 }
 
-void EglManager::loadConfig() {
+void EglManager::loadConfigs() {
     ALOGD("Swap behavior %d", static_cast<int>(mSwapBehavior));
     EGLint swapBehavior = (mSwapBehavior == SwapBehavior::Preserved)
             ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
@@ -175,19 +190,44 @@
             EGL_NONE
     };
 
-    EGLint num_configs = 1;
-    if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, num_configs, &num_configs)
-            || num_configs != 1) {
+    EGLint numConfigs = 1;
+    if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, numConfigs, &numConfigs)
+            || numConfigs != 1) {
         if (mSwapBehavior == SwapBehavior::Preserved) {
             // Try again without dirty regions enabled
             ALOGW("Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...");
             mSwapBehavior = SwapBehavior::Discard;
-            loadConfig();
+            loadConfigs();
+            return; // the call to loadConfigs() we just made picks the wide gamut config
         } else {
             // Failed to get a valid config
             LOG_ALWAYS_FATAL("Failed to choose config, error = %s", eglErrorString());
         }
     }
+
+    if (EglExtensions.pixelFormatFloat) {
+        // If we reached this point, we have a valid swap behavior
+        EGLint attribs16F[] = {
+                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+                EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
+                EGL_RED_SIZE, 16,
+                EGL_GREEN_SIZE, 16,
+                EGL_BLUE_SIZE, 16,
+                EGL_ALPHA_SIZE, 16,
+                EGL_DEPTH_SIZE, 0,
+                EGL_STENCIL_SIZE, Stencil::getStencilSize(),
+                EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior,
+                EGL_NONE
+        };
+
+        numConfigs = 1;
+        if (!eglChooseConfig(mEglDisplay, attribs16F, &mEglConfigWideGamut, numConfigs, &numConfigs)
+                || numConfigs != 1) {
+            LOG_ALWAYS_FATAL(
+                    "Device claims wide gamut support, cannot find matching config, error = %s",
+                    eglErrorString());
+        }
+    }
 }
 
 void EglManager::createContext() {
@@ -195,7 +235,9 @@
             EGL_CONTEXT_CLIENT_VERSION, GLES_VERSION,
             EGL_NONE
     };
-    mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attribs);
+    mEglContext = eglCreateContext(mEglDisplay,
+            EglExtensions.noConfigContext ? ((EGLConfig) nullptr) : mEglConfig,
+            EGL_NO_CONTEXT, attribs);
     LOG_ALWAYS_FATAL_IF(mEglContext == EGL_NO_CONTEXT,
         "Failed to create context, error = %s", eglErrorString());
 }
@@ -210,18 +252,58 @@
     }
 }
 
-EGLSurface EglManager::createSurface(EGLNativeWindowType window) {
+EGLSurface EglManager::createSurface(EGLNativeWindowType window, bool wideColorGamut) {
     initialize();
 
+    wideColorGamut = wideColorGamut && EglExtensions.glColorSpace && EglExtensions.scRGB
+            && EglExtensions.pixelFormatFloat && EglExtensions.noConfigContext;
+
+    // The color space we want to use depends on whether linear blending is turned
+    // on and whether the app has requested wide color gamut rendering. When wide
+    // color gamut rendering is off, the app simply renders in the display's native
+    // color gamut.
+    //
+    // When wide gamut rendering is off:
+    // - Blending is done by default in gamma space, which requires using a
+    //   linear EGL color space (the GPU uses the color values as is)
+    // - If linear blending is on, we must use the sRGB EGL color space (the
+    //   GPU will perform sRGB to linear and linear to SRGB conversions before
+    //   and after blending)
+    //
+    // When wide gamut rendering is on we cannot rely on the GPU performing
+    // linear blending for us. We use two different color spaces to tag the
+    // surface appropriately for SurfaceFlinger:
+    // - Gamma blending (default) requires the use of the scRGB-nl color space
+    // - Linear blending requires the use of the scRGB color space
+
+    // Not all Android targets support the EGL_GL_COLOR_SPACE_KHR extension
+    // We insert to placeholders to set EGL_GL_COLORSPACE_KHR and its value.
+    // According to section 3.4.1 of the EGL specification, the attributes
+    // list is considered empty if the first entry is EGL_NONE
     EGLint attribs[] = {
-#ifdef ANDROID_ENABLE_LINEAR_BLENDING
-            EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR,
-            EGL_COLORSPACE, EGL_COLORSPACE_sRGB,
-#endif
+            EGL_NONE, EGL_NONE,
             EGL_NONE
     };
 
-    EGLSurface surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, window, attribs);
+    if (EglExtensions.glColorSpace) {
+        attribs[0] = EGL_GL_COLORSPACE_KHR;
+#ifdef ANDROID_ENABLE_LINEAR_BLENDING
+        if (wideColorGamut) {
+            attribs[1] = EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT;
+        } else {
+            attribs[1] = EGL_GL_COLORSPACE_SRGB_KHR;
+        }
+#else
+        if (wideColorGamut) {
+            attribs[1] = EGL_GL_COLORSPACE_SCRGB_EXT;
+        } else {
+            attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
+        }
+#endif
+    }
+
+    EGLSurface surface = eglCreateWindowSurface(mEglDisplay,
+            wideColorGamut ? mEglConfigWideGamut : mEglConfig, window, attribs);
     LOG_ALWAYS_FATAL_IF(surface == EGL_NO_SURFACE,
             "Failed to create EGLSurface for window %p, eglErr = %s",
             (void*) window, eglErrorString());
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index 0251925..2982c23 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -39,7 +39,7 @@
 
     bool hasEglContext();
 
-    EGLSurface createSurface(EGLNativeWindowType window);
+    EGLSurface createSurface(EGLNativeWindowType window, bool wideColorGamut);
     void destroySurface(EGLSurface surface);
 
     void destroy();
@@ -68,7 +68,7 @@
 
     void initExtensions();
     void createPBufferSurface();
-    void loadConfig();
+    void loadConfigs();
     void createContext();
     EGLint queryBufferAge(EGLSurface surface);
 
@@ -76,6 +76,7 @@
 
     EGLDisplay mEglDisplay;
     EGLConfig mEglConfig;
+    EGLConfig mEglConfigWideGamut;
     EGLContext mEglContext;
     EGLSurface mPBufferSurface;
 
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index 45f6718..f9b6e38 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -44,6 +44,12 @@
     Succeeded
 };
 
+enum class ColorMode {
+    Srgb,
+    WideColorGamut,
+    // Hdr
+};
+
 class Frame;
 
 class IRenderPipeline {
@@ -53,7 +59,7 @@
     virtual bool draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
             const FrameBuilder::LightGeometry& lightGeometry,
             LayerUpdateQueue* layerUpdateQueue,
-            const Rect& contentDrawBounds, bool opaque,
+            const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
             const BakedOpRenderer::LightInfo& lightInfo,
             const std::vector< sp<RenderNode> >& renderNodes,
             FrameInfoVisualizer* profiler) = 0;
@@ -61,17 +67,17 @@
             FrameInfo* currentFrameInfo, bool* requireSwap) = 0;
     virtual bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) = 0;
     virtual DeferredLayerUpdater* createTextureLayer() = 0;
-    virtual bool setSurface(Surface* window, SwapBehavior swapBehavior) = 0;
+    virtual bool setSurface(Surface* window, SwapBehavior swapBehavior, ColorMode colorMode) = 0;
     virtual void onStop() = 0;
     virtual bool isSurfaceReady() = 0;
     virtual bool isContextReady() = 0;
     virtual void onDestroyHardwareResources() = 0;
     virtual void renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
-            LayerUpdateQueue* layerUpdateQueue, bool opaque,
+            LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
             const BakedOpRenderer::LightInfo& lightInfo) = 0;
     virtual TaskManager* getTaskManager() = 0;
     virtual bool createOrUpdateLayer(RenderNode* node,
-            const DamageAccumulator& damageAccumulator) = 0;
+            const DamageAccumulator& damageAccumulator, bool wideColorGamut) = 0;
     virtual bool pinImages(std::vector<SkImage*>& mutableImages) = 0;
     virtual bool pinImages(LsaVector<sk_sp<Bitmap>>& images) = 0;
     virtual void unpinImages() = 0;
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
index e1ae585..7283eb1 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ b/libs/hwui/renderthread/OpenGLPipeline.cpp
@@ -58,7 +58,7 @@
 bool OpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
         const FrameBuilder::LightGeometry& lightGeometry,
         LayerUpdateQueue* layerUpdateQueue,
-        const Rect& contentDrawBounds, bool opaque,
+        const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
         const BakedOpRenderer::LightInfo& lightInfo,
         const std::vector< sp<RenderNode> >& renderNodes,
         FrameInfoVisualizer* profiler) {
@@ -77,7 +77,7 @@
     frameBuilder.deferRenderNodeScene(renderNodes, contentDrawBounds);
 
     BakedOpRenderer renderer(caches, mRenderThread.renderState(),
-            opaque, lightInfo);
+            opaque, wideColorGamut, lightInfo);
     frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
     ProfileRenderer profileRenderer(renderer);
     profiler->draw(profileRenderer);
@@ -146,7 +146,7 @@
     }
 }
 
-bool OpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) {
+bool OpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior, ColorMode colorMode) {
 
     if (mEglSurface != EGL_NO_SURFACE) {
         mEglManager.destroySurface(mEglSurface);
@@ -154,7 +154,8 @@
     }
 
     if (surface) {
-        mEglSurface = mEglManager.createSurface(surface);
+        const bool wideColorGamut = colorMode == ColorMode::WideColorGamut;
+        mEglSurface = mEglManager.createSurface(surface, wideColorGamut);
     }
 
     if (mEglSurface != EGL_NO_SURFACE) {
@@ -183,14 +184,14 @@
 }
 
 void OpenGLPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
-        LayerUpdateQueue* layerUpdateQueue, bool opaque,
+        LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
         const BakedOpRenderer::LightInfo& lightInfo) {
     static const std::vector< sp<RenderNode> > emptyNodeList;
     auto& caches = Caches::getInstance();
     FrameBuilder frameBuilder(*layerUpdateQueue, lightGeometry, caches);
     layerUpdateQueue->clear();
-    BakedOpRenderer renderer(caches, mRenderThread.renderState(),
-            opaque, lightInfo);
+    // TODO: Handle wide color gamut contexts
+    BakedOpRenderer renderer(caches, mRenderThread.renderState(), opaque, wideColorGamut, lightInfo);
     LOG_ALWAYS_FATAL_IF(renderer.didDraw(), "shouldn't draw in buildlayer case");
     frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
 }
@@ -204,12 +205,13 @@
 }
 
 bool OpenGLPipeline::createOrUpdateLayer(RenderNode* node,
-        const DamageAccumulator& damageAccumulator) {
+        const DamageAccumulator& damageAccumulator, bool wideColorGamut) {
     RenderState& renderState = mRenderThread.renderState();
     OffscreenBufferPool& layerPool = renderState.layerPool();
     bool transformUpdateNeeded = false;
     if (node->getLayer() == nullptr) {
-        node->setLayer(layerPool.get(renderState, node->getWidth(), node->getHeight()));
+        node->setLayer(layerPool.get(renderState,
+                node->getWidth(), node->getHeight(), wideColorGamut));
         transformUpdateNeeded = true;
     } else if (!layerMatchesWH(node->getLayer(), node->getWidth(), node->getHeight())) {
         // TODO: remove now irrelevant, currently enqueued damage (respecting damage ordering)
@@ -267,6 +269,171 @@
     thread.renderState().invokeFunctor(functor, mode, nullptr);
 }
 
+#define FENCE_TIMEOUT 2000000000
+
+class AutoEglFence {
+public:
+    AutoEglFence(EGLDisplay display)
+            : mDisplay(display) {
+        fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
+    }
+
+    ~AutoEglFence() {
+        if (fence != EGL_NO_SYNC_KHR) {
+            eglDestroySyncKHR(mDisplay, fence);
+        }
+    }
+
+    EGLSyncKHR fence = EGL_NO_SYNC_KHR;
+private:
+    EGLDisplay mDisplay = EGL_NO_DISPLAY;
+};
+
+class AutoEglImage {
+public:
+    AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer)
+            : mDisplay(display) {
+        EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+        image = eglCreateImageKHR(display, EGL_NO_CONTEXT,
+                EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
+    }
+
+    ~AutoEglImage() {
+        if (image != EGL_NO_IMAGE_KHR) {
+            eglDestroyImageKHR(mDisplay, image);
+        }
+    }
+
+    EGLImageKHR image = EGL_NO_IMAGE_KHR;
+private:
+    EGLDisplay mDisplay = EGL_NO_DISPLAY;
+};
+
+class AutoGlTexture {
+public:
+    AutoGlTexture(uirenderer::Caches& caches)
+            : mCaches(caches) {
+        glGenTextures(1, &mTexture);
+        caches.textureState().bindTexture(mTexture);
+    }
+
+    ~AutoGlTexture() {
+        mCaches.textureState().deleteTexture(mTexture);
+    }
+
+private:
+    uirenderer::Caches& mCaches;
+    GLuint mTexture = 0;
+};
+
+static bool uploadBitmapToGraphicBuffer(uirenderer::Caches& caches, SkBitmap& bitmap,
+        GraphicBuffer& buffer, GLint format, GLint type) {
+    EGLDisplay display = eglGetCurrentDisplay();
+    LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY,
+                "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
+                uirenderer::renderthread::EglManager::eglErrorString());
+    // We use an EGLImage to access the content of the GraphicBuffer
+    // The EGL image is later bound to a 2D texture
+    EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer.getNativeBuffer();
+    AutoEglImage autoImage(display, clientBuffer);
+    if (autoImage.image == EGL_NO_IMAGE_KHR) {
+        ALOGW("Could not create EGL image, err =%s",
+                uirenderer::renderthread::EglManager::eglErrorString());
+        return false;
+    }
+    AutoGlTexture glTexture(caches);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
+
+    GL_CHECKPOINT(MODERATE);
+
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
+            format, type, bitmap.getPixels());
+
+    GL_CHECKPOINT(MODERATE);
+
+    // The fence is used to wait for the texture upload to finish
+    // properly. We cannot rely on glFlush() and glFinish() as
+    // some drivers completely ignore these API calls
+    AutoEglFence autoFence(display);
+    if (autoFence.fence == EGL_NO_SYNC_KHR) {
+        LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError());
+        return false;
+    }
+    // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
+    // pipeline flush (similar to what a glFlush() would do.)
+    EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence,
+            EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
+    if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
+        LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError());
+        return false;
+    }
+    return true;
+}
+
+// TODO: handle SRGB sanely
+static PixelFormat internalFormatToPixelFormat(GLint internalFormat) {
+    switch (internalFormat) {
+    case GL_LUMINANCE:
+        return PIXEL_FORMAT_RGBA_8888;
+    case GL_SRGB8_ALPHA8:
+        return PIXEL_FORMAT_RGBA_8888;
+    case GL_RGBA:
+        return PIXEL_FORMAT_RGBA_8888;
+    case GL_RGB:
+        return PIXEL_FORMAT_RGB_565;
+    case GL_RGBA16F:
+        return PIXEL_FORMAT_RGBA_FP16;
+    default:
+        LOG_ALWAYS_FATAL("Unsupported bitmap colorType: %d", internalFormat);
+        return PIXEL_FORMAT_UNKNOWN;
+    }
+}
+
+sk_sp<Bitmap> OpenGLPipeline::allocateHardwareBitmap(RenderThread& renderThread,
+        SkBitmap& skBitmap) {
+    renderThread.eglManager().initialize();
+    uirenderer::Caches& caches = uirenderer::Caches::getInstance();
+
+    const SkImageInfo& info = skBitmap.info();
+    if (info.colorType() == kUnknown_SkColorType || info.colorType() == kAlpha_8_SkColorType) {
+        ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType());
+        return nullptr;
+    }
+
+    bool needSRGB = uirenderer::transferFunctionCloseToSRGB(skBitmap.info().colorSpace());
+    bool hasLinearBlending = caches.extensions().hasLinearBlending();
+    GLint format, type, internalFormat;
+    uirenderer::Texture::colorTypeToGlFormatAndType(caches, skBitmap.colorType(),
+            needSRGB && hasLinearBlending, &internalFormat, &format, &type);
+
+    PixelFormat pixelFormat = internalFormatToPixelFormat(internalFormat);
+    sp<GraphicBuffer> buffer = new GraphicBuffer(info.width(), info.height(), pixelFormat,
+            GraphicBuffer::USAGE_HW_TEXTURE |
+            GraphicBuffer::USAGE_SW_WRITE_NEVER |
+            GraphicBuffer::USAGE_SW_READ_NEVER,
+            std::string("Bitmap::allocateHardwareBitmap pid [") + std::to_string(getpid()) + "]");
+
+    status_t error = buffer->initCheck();
+    if (error < 0) {
+        ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
+        return nullptr;
+    }
+
+    SkBitmap bitmap;
+    if (CC_UNLIKELY(uirenderer::Texture::hasUnsupportedColorType(skBitmap.info(),
+            hasLinearBlending))) {
+        sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB();
+        bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasLinearBlending, std::move(sRGB));
+    } else {
+        bitmap = skBitmap;
+    }
+
+    if (!uploadBitmapToGraphicBuffer(caches, bitmap, *buffer, format, type)) {
+        return nullptr;
+    }
+    return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info()));
+}
+
 } /* namespace renderthread */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/renderthread/OpenGLPipeline.h b/libs/hwui/renderthread/OpenGLPipeline.h
index 6df8be4..4ca19fb 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.h
+++ b/libs/hwui/renderthread/OpenGLPipeline.h
@@ -36,7 +36,7 @@
     bool draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
             const FrameBuilder::LightGeometry& lightGeometry,
             LayerUpdateQueue* layerUpdateQueue,
-            const Rect& contentDrawBounds, bool opaque,
+            const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
             const BakedOpRenderer::LightInfo& lightInfo,
             const std::vector< sp<RenderNode> >& renderNodes,
             FrameInfoVisualizer* profiler) override;
@@ -44,23 +44,25 @@
             FrameInfo* currentFrameInfo, bool* requireSwap) override;
     bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) override;
     DeferredLayerUpdater* createTextureLayer() override;
-    bool setSurface(Surface* window, SwapBehavior swapBehavior) override;
+    bool setSurface(Surface* window, SwapBehavior swapBehavior, ColorMode colorMode) override;
     void onStop() override;
     bool isSurfaceReady() override;
     bool isContextReady() override;
     void onDestroyHardwareResources() override;
     void renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
-            LayerUpdateQueue* layerUpdateQueue, bool opaque,
+            LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
             const BakedOpRenderer::LightInfo& lightInfo) override;
     TaskManager* getTaskManager() override;
     bool createOrUpdateLayer(RenderNode* node,
-            const DamageAccumulator& damageAccumulator) override;
+            const DamageAccumulator& damageAccumulator, bool wideColorGamut) override;
     bool pinImages(std::vector<SkImage*>& mutableImages) override { return false; }
     bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override;
     void unpinImages() override;
     static void destroyLayer(RenderNode* node);
     static void prepareToDraw(const RenderThread& thread, Bitmap* bitmap);
     static void invokeFunctor(const RenderThread& thread, Functor* functor);
+    static sk_sp<Bitmap> allocateHardwareBitmap(RenderThread& thread,
+            SkBitmap& skBitmap);
 
 private:
     EglManager& mEglManager;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index d842be9..80c2955 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -228,6 +228,18 @@
     post(task);
 }
 
+CREATE_BRIDGE2(setWideGamut, CanvasContext* context, bool wideGamut) {
+    args->context->setWideGamut(args->wideGamut);
+    return nullptr;
+}
+
+void RenderProxy::setWideGamut(bool wideGamut) {
+    SETUP_TASK(setWideGamut);
+    args->context = mContext;
+    args->wideGamut = wideGamut;
+    post(task);
+}
+
 int64_t* RenderProxy::frameInfo() {
     return mDrawFrameTask.frameInfo();
 }
@@ -458,18 +470,7 @@
 }
 
 CREATE_BRIDGE2(dumpGraphicsMemory, int fd, RenderThread* thread) {
-    args->thread->jankTracker().dump(args->fd);
-
-    FILE *file = fdopen(args->fd, "a");
-    if (Caches::hasInstance()) {
-        String8 cachesLog;
-        Caches::getInstance().dumpMemoryUsage(cachesLog);
-        fprintf(file, "\nCaches:\n%s\n", cachesLog.string());
-    } else {
-        fprintf(file, "\nNo caches instance.\n");
-    }
-    fprintf(file, "\nPipeline=FrameBuilder\n");
-    fflush(file);
+    args->thread->dumpGraphicsMemory(args->fd);
     return nullptr;
 }
 
@@ -665,7 +666,7 @@
 }
 
 CREATE_BRIDGE2(allocateHardwareBitmap, RenderThread* thread, SkBitmap* bitmap) {
-    sk_sp<Bitmap> hardwareBitmap = Bitmap::allocateHardwareBitmap(*args->thread, *args->bitmap);
+    sk_sp<Bitmap> hardwareBitmap = args->thread->allocateHardwareBitmap(*args->bitmap);
     return hardwareBitmap.release();
 }
 
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 6f4e8ce..31f0ce6 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -69,7 +69,7 @@
  */
 class ANDROID_API RenderProxy {
 public:
-    ANDROID_API RenderProxy(bool translucent, RenderNode* rootNode, IContextFactory* contextFactory);
+    ANDROID_API RenderProxy(bool opaque, RenderNode* rootNode, IContextFactory* contextFactory);
     ANDROID_API virtual ~RenderProxy();
 
     // Won't take effect until next EGLSurface creation
@@ -85,6 +85,7 @@
             uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
     ANDROID_API void setLightCenter(const Vector3& lightCenter);
     ANDROID_API void setOpaque(bool opaque);
+    ANDROID_API void setWideGamut(bool wideGamut);
     ANDROID_API int64_t* frameInfo();
     ANDROID_API int syncAndDrawFrame();
     ANDROID_API void destroy();
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 1450ec9..13af2c4 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -16,8 +16,12 @@
 
 #include "RenderThread.h"
 
-#include "../renderstate/RenderState.h"
-#include "../pipeline/skia/SkiaOpenGLReadback.h"
+#include "hwui/Bitmap.h"
+#include "renderstate/RenderState.h"
+#include "renderthread/OpenGLPipeline.h"
+#include "pipeline/skia/SkiaOpenGLReadback.h"
+#include "pipeline/skia/SkiaOpenGLPipeline.h"
+#include "pipeline/skia/SkiaVulkanPipeline.h"
 #include "CanvasContext.h"
 #include "EglManager.h"
 #include "OpenGLReadback.h"
@@ -198,6 +202,45 @@
     mRenderState = new RenderState(*this);
     mJankTracker = new JankTracker(mDisplayInfo);
     mVkManager = new VulkanManager(*this);
+    mCacheManager = new CacheManager(mDisplayInfo);
+}
+
+void RenderThread::dumpGraphicsMemory(int fd) {
+    jankTracker().dump(fd);
+
+    String8 cachesOutput;
+    String8 pipeline;
+    auto renderType = Properties::getRenderPipelineType();
+    switch (renderType) {
+        case RenderPipelineType::OpenGL: {
+            if (Caches::hasInstance()) {
+                cachesOutput.appendFormat("Caches:\n");
+                Caches::getInstance().dumpMemoryUsage(cachesOutput);
+            } else {
+                cachesOutput.appendFormat("No caches instance.");
+            }
+            pipeline.appendFormat("FrameBuilder");
+            break;
+        }
+        case RenderPipelineType::SkiaGL: {
+            mCacheManager->dumpMemoryUsage(cachesOutput, mRenderState);
+            pipeline.appendFormat("Skia (OpenGL)");
+            break;
+        }
+        case RenderPipelineType::SkiaVulkan: {
+            mCacheManager->dumpMemoryUsage(cachesOutput, mRenderState);
+            pipeline.appendFormat("Skia (Vulkan)");
+            break;
+        }
+        default:
+            LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+            break;
+    }
+
+    FILE *file = fdopen(fd, "a");
+    fprintf(file, "\n%s\n", cachesOutput.string());
+    fprintf(file, "\nPipeline=%s\n", pipeline.string());
+    fflush(file);
 }
 
 Readback& RenderThread::readback() {
@@ -224,6 +267,14 @@
     return *mReadback;
 }
 
+void RenderThread::setGrContext(GrContext* context) {
+    mCacheManager->reset(context);
+    if (mGrContext.get()) {
+        mGrContext->releaseResourcesAndAbandonContext();
+    }
+    mGrContext.reset(context);
+}
+
 int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) {
     if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
         ALOGE("Display event receiver pipe was closed or an error occurred.  "
@@ -433,6 +484,22 @@
     return next;
 }
 
+sk_sp<Bitmap> RenderThread::allocateHardwareBitmap(SkBitmap& skBitmap) {
+    auto renderType = Properties::getRenderPipelineType();
+    switch (renderType) {
+        case RenderPipelineType::OpenGL:
+            return OpenGLPipeline::allocateHardwareBitmap(*this, skBitmap);
+        case RenderPipelineType::SkiaGL:
+            return skiapipeline::SkiaOpenGLPipeline::allocateHardwareBitmap(*this, skBitmap);
+        case RenderPipelineType::SkiaVulkan:
+            return skiapipeline::SkiaVulkanPipeline::allocateHardwareBitmap(*this, skBitmap);
+        default:
+            LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+            break;
+    }
+    return nullptr;
+}
+
 } /* namespace renderthread */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 9bc5985..d984257 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -20,10 +20,12 @@
 #include "RenderTask.h"
 
 #include "../JankTracker.h"
+#include "CacheManager.h"
 #include "TimeLord.h"
 
 #include <GrContext.h>
 #include <cutils/compiler.h>
+#include <SkBitmap.h>
 #include <ui/DisplayInfo.h>
 #include <utils/Looper.h>
 #include <utils/Thread.h>
@@ -33,6 +35,7 @@
 
 namespace android {
 
+class Bitmap;
 class DisplayEventReceiver;
 
 namespace uirenderer {
@@ -100,10 +103,14 @@
     const DisplayInfo& mainDisplayInfo() { return mDisplayInfo; }
 
     GrContext* getGrContext() const { return mGrContext.get(); }
-    void setGrContext(GrContext* cxt) { mGrContext.reset(cxt); }
+    void setGrContext(GrContext* cxt);
 
+    CacheManager& cacheManager() { return *mCacheManager; }
     VulkanManager& vulkanManager() { return *mVkManager; }
 
+    sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& skBitmap);
+    void dumpGraphicsMemory(int fd);
+
 protected:
     virtual bool threadLoop() override;
 
@@ -157,6 +164,7 @@
     Readback* mReadback = nullptr;
 
     sk_sp<GrContext> mGrContext;
+    CacheManager* mCacheManager;
     VulkanManager* mVkManager;
 };
 
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index c2c2f22..a745320 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -54,7 +54,8 @@
 
     auto canPresent = [](VkInstance, VkPhysicalDevice, uint32_t) { return true; };
 
-    mBackendContext.reset(GrVkBackendContext::Create(&mPresentQueueIndex, canPresent));
+    mBackendContext.reset(GrVkBackendContext::Create(vkGetInstanceProcAddr, vkGetDeviceProcAddr,
+            &mPresentQueueIndex, canPresent));
 
     // Get all the addresses of needed vulkan functions
     VkInstance instance = mBackendContext->fInstance;
diff --git a/libs/hwui/service/GraphicsStatsService.cpp b/libs/hwui/service/GraphicsStatsService.cpp
index ab6420e..978a1f3 100644
--- a/libs/hwui/service/GraphicsStatsService.cpp
+++ b/libs/hwui/service/GraphicsStatsService.cpp
@@ -19,14 +19,16 @@
 #include "JankTracker.h"
 
 #include <frameworks/base/core/proto/android/service/graphicsstats.pb.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 #include <log/log.h>
 
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <errno.h>
 #include <fcntl.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
+#include <sys/mman.h>
 
 namespace android {
 namespace uirenderer {
@@ -46,10 +48,74 @@
         const ProfileData* data);
 static void dumpAsTextToFd(service::GraphicsStatsProto* proto, int outFd);
 
+class FileDescriptor {
+public:
+    FileDescriptor(int fd) : mFd(fd) {}
+    ~FileDescriptor() {
+        if (mFd != -1) {
+            close(mFd);
+            mFd = -1;
+        }
+    }
+    bool valid() { return mFd != -1; }
+    operator int() { return mFd; }
+private:
+    int mFd;
+};
+
+class FileOutputStreamLite : public io::ZeroCopyOutputStream {
+public:
+    FileOutputStreamLite(int fd) : mCopyAdapter(fd), mImpl(&mCopyAdapter) {}
+    virtual ~FileOutputStreamLite() {}
+
+    int GetErrno() { return mCopyAdapter.mErrno; }
+
+    virtual bool Next(void** data, int* size) override {
+        return mImpl.Next(data, size);
+    }
+
+    virtual void BackUp(int count) override {
+        mImpl.BackUp(count);
+    }
+
+    virtual int64 ByteCount() const override {
+        return mImpl.ByteCount();
+    }
+
+    bool Flush() {
+        return mImpl.Flush();
+    }
+
+private:
+    struct FDAdapter : public io::CopyingOutputStream {
+        int mFd;
+        int mErrno = 0;
+
+        FDAdapter(int fd) : mFd(fd) {}
+        virtual ~FDAdapter() {}
+
+        virtual bool Write(const void* buffer, int size) override {
+            int ret;
+            while (size) {
+                ret = TEMP_FAILURE_RETRY( write(mFd, buffer, size) );
+                if (ret <= 0) {
+                    mErrno = errno;
+                    return false;
+                }
+                size -= ret;
+            }
+            return true;
+        }
+    };
+
+    FileOutputStreamLite::FDAdapter mCopyAdapter;
+    io::CopyingOutputStreamAdaptor mImpl;
+};
+
 bool GraphicsStatsService::parseFromFile(const std::string& path, service::GraphicsStatsProto* output) {
 
-    int fd = open(path.c_str(), O_RDONLY);
-    if (fd == -1) {
+    FileDescriptor fd{open(path.c_str(), O_RDONLY)};
+    if (!fd.valid()) {
         int err = errno;
         // The file not existing is normal for addToDump(), so only log if
         // we get an unexpected error
@@ -58,26 +124,41 @@
         }
         return false;
     }
-    uint32_t file_version;
-    ssize_t bytesRead = read(fd, &file_version, sHeaderSize);
-    if (bytesRead != sHeaderSize || file_version != sCurrentFileVersion) {
-        ALOGW("Failed to read '%s', bytesRead=%zd file_version=%d", path.c_str(), bytesRead,
-                file_version);
-        close(fd);
+    struct stat sb;
+    if (fstat(fd, &sb) || sb.st_size < sHeaderSize) {
+        int err = errno;
+        // The file not existing is normal for addToDump(), so only log if
+        // we get an unexpected error
+        if (err != ENOENT) {
+            ALOGW("Failed to fstat '%s', errno=%d (%s) (st_size %d)", path.c_str(), err,
+                    strerror(err), (int) sb.st_size);
+        }
+        return false;
+    }
+    void* addr = mmap(nullptr, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
+    if (!addr) {
+        int err = errno;
+        // The file not existing is normal for addToDump(), so only log if
+        // we get an unexpected error
+        if (err != ENOENT) {
+            ALOGW("Failed to mmap '%s', errno=%d (%s)", path.c_str(), err, strerror(err));
+        }
+        return false;
+    }
+    uint32_t file_version = *reinterpret_cast<uint32_t*>(addr);
+    if (file_version != sCurrentFileVersion) {
+        ALOGW("file_version mismatch! expected %d got %d", sCurrentFileVersion, file_version);
         return false;
     }
 
-    io::FileInputStream input(fd);
+    void* data = reinterpret_cast<uint8_t*>(addr) + sHeaderSize;
+    int dataSize = sb.st_size - sHeaderSize;
+    io::ArrayInputStream input{data, dataSize};
     bool success = output->ParseFromZeroCopyStream(&input);
-    if (input.GetErrno() != 0) {
-        ALOGW("Error reading from fd=%d, path='%s' err=%d (%s)",
-                fd, path.c_str(), input.GetErrno(), strerror(input.GetErrno()));
-        success = false;
-    } else if (!success) {
+    if (!success) {
         ALOGW("Parse failed on '%s' error='%s'",
                 path.c_str(), output->InitializationErrorString().c_str());
     }
-    close(fd);
     return success;
 }
 
@@ -212,7 +293,7 @@
         return;
     }
     {
-        io::FileOutputStream output(outFd);
+        FileOutputStreamLite output(outFd);
         bool success = statsProto.SerializeToZeroCopyStream(&output) && output.Flush();
         if (output.GetErrno() != 0) {
             ALOGW("Error writing to fd=%d, path='%s' err=%d (%s)",
@@ -277,11 +358,11 @@
 
 void GraphicsStatsService::finishDump(Dump* dump) {
     if (dump->type() == DumpType::Protobuf) {
-        io::FileOutputStream stream(dump->fd());
+        FileOutputStreamLite stream(dump->fd());
         dump->proto().SerializeToZeroCopyStream(&stream);
     }
     delete dump;
 }
 
 } /* namespace uirenderer */
-} /* namespace android */
\ No newline at end of file
+} /* namespace android */
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index dd45786..98d5fb3 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -365,8 +365,15 @@
         }
         auto displayList = node->getDisplayList();
         if (displayList) {
-            for (auto&& childOp : displayList->getChildren()) {
-                syncHierarchyPropertiesAndDisplayListImpl(childOp->renderNode);
+            if (displayList->isSkiaDL()) {
+                for (auto&& childDr : static_cast<skiapipeline::SkiaDisplayList*>(
+                        const_cast<DisplayList*>(displayList))->mChildNodes) {
+                    syncHierarchyPropertiesAndDisplayListImpl(childDr.getRenderNode());
+                }
+            } else {
+                for (auto&& childOp : displayList->getChildren()) {
+                    syncHierarchyPropertiesAndDisplayListImpl(childOp->renderNode);
+                }
             }
         }
     }
diff --git a/libs/hwui/tests/common/scenes/BitmapShaders.cpp b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
index a7ebb68..4797dec 100644
--- a/libs/hwui/tests/common/scenes/BitmapShaders.cpp
+++ b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
@@ -45,10 +45,8 @@
             skCanvas.drawRect(SkRect::MakeXYWH(100, 100, 100, 100), skPaint);
         });
 
-        SkBitmap bitmap;
         SkPaint paint;
-        hwuiBitmap->getSkBitmapForShaders(&bitmap);
-        sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+        sk_sp<SkImage> image = hwuiBitmap->makeImage();
         sk_sp<SkShader> repeatShader = image->makeShader(
                 SkShader::TileMode::kRepeat_TileMode,
                 SkShader::TileMode::kRepeat_TileMode,
diff --git a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
index a461426..c246eba 100644
--- a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
+++ b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
@@ -75,9 +75,7 @@
     void doFrame(int frameNr) override { }
 
     sk_sp<SkShader> createBitmapShader(Bitmap& bitmap) {
-        SkBitmap skBitmap;
-        bitmap.getSkBitmapForShaders(&skBitmap);
-        sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skBitmap, kNever_SkCopyPixelsMode);
+        sk_sp<SkImage> image = bitmap.makeImage();
         return image->makeShader(SkShader::TileMode::kClamp_TileMode,
                 SkShader::TileMode::kClamp_TileMode);
     }
diff --git a/libs/hwui/tests/microbench/FrameBuilderBench.cpp b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
index 398e7a8..a5e85df 100644
--- a/libs/hwui/tests/microbench/FrameBuilderBench.cpp
+++ b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
@@ -83,7 +83,7 @@
                     sLightGeometry, caches);
             frameBuilder.deferRenderNode(*node);
 
-            BakedOpRenderer renderer(caches, renderState, true, sLightInfo);
+            BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
             frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
             benchmark::DoNotOptimize(&renderer);
         }
@@ -142,7 +142,7 @@
                     sLightGeometry, Caches::getInstance());
             frameBuilder.deferRenderNode(*node);
 
-            BakedOpRenderer renderer(caches, renderState, true, sLightInfo);
+            BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
             frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
             benchmark::DoNotOptimize(&renderer);
         }
diff --git a/libs/hwui/tests/scripts/process_systrace.py b/libs/hwui/tests/scripts/process_systrace.py
new file mode 100755
index 0000000..f497bf5
--- /dev/null
+++ b/libs/hwui/tests/scripts/process_systrace.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+
+import codecs, httplib, json, os, urllib, shutil, subprocess, sys, argparse
+
+upstream_git = 'https://github.com/catapult-project/catapult.git'
+
+script_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
+catapult_src_dir = os.path.join(script_dir, 'catapult-upstream')
+
+parser = argparse.ArgumentParser()
+parser.add_argument('trace_file_or_dir',
+      help='Path to trace file or directory of trace files.')
+parser.add_argument('--output_file', dest='outfile', default=os.path.join(os.getcwd(), 'mapper_output.json'),
+      help='Path to output file to store results.')
+parser.add_argument('--mapper_func', dest='func', default='AvgDrawFrame',
+      help='Name of javascript mapper function in systrace_parser.html.')
+args = parser.parse_args()
+
+# Update the source if needed.
+if not os.path.exists(catapult_src_dir):
+  # Pull the latest source from the upstream git.
+  git_args = ['git', 'clone', upstream_git, catapult_src_dir]
+  p = subprocess.Popen(git_args, stdout=subprocess.PIPE, cwd=script_dir)
+  p.communicate()
+  if p.wait() != 0:
+    print 'Failed to checkout source from upstream git.'
+    sys.exit(1)
+
+mapper_func_file = os.path.join(script_dir, 'systrace_parser.html')
+path_to_process_traces = os.path.join(catapult_src_dir, 'trace_processor/bin/process_traces')
+run_command = path_to_process_traces + " --mapper_handle " + mapper_func_file + ":" + args.func + " --output_file " + args.outfile + " " + args.trace_file_or_dir
+print run_command
+sys.exit(os.system(run_command))
+
diff --git a/libs/hwui/tests/scripts/systrace_parser.html b/libs/hwui/tests/scripts/systrace_parser.html
new file mode 100644
index 0000000..4c66ae2
--- /dev/null
+++ b/libs/hwui/tests/scripts/systrace_parser.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+
+<script>
+'use strict';
+
+const RENDER_THREAD_NAME = "RenderThread";
+const UI_THREAD_NAME = "UI Thread";
+const DRAW_FRAME_SLICE_TITLE = "DrawFrame";
+const BINDER_SLICE_TITLE = "binder transaction";
+const RECORD_SLICE_TITLE = "Record View#draw()";
+const DEQUEUE_BUFFER_SLICE_TITLE = "dequeueBuffer";
+
+function getTimeInBinder(slice) {
+    if (slice.title === BINDER_SLICE_TITLE) {
+        return slice.duration;
+    }
+    let result = 0.0;
+    for (let subslice of slice.subSlices) {
+        result += getTimeInBinder(subslice);
+    }
+    return result;
+}
+
+function getTimeInDequeueBuffer(slice) {
+    if (slice.title === DEQUEUE_BUFFER_SLICE_TITLE) {
+        return slice.duration;
+    }
+    let result = 0.0;
+    for (let subslice of slice.subSlices) {
+        result += getTimeInDequeueBuffer(subslice);
+    }
+    return result;
+}
+
+tr.mre.FunctionRegistry.register(
+    function AvgDrawFrame(result, model) {
+        let canonicalUrl = model.canonicalUrl;
+
+        for (let p of model.getAllProcesses()) {
+            //calc stats for processes that have UI and render threads and at least 10 frames
+            let renderThread = p.findAtMostOneThreadNamed(RENDER_THREAD_NAME);
+            let UIThread = p.findAtMostOneThreadNamed(UI_THREAD_NAME);
+            if (renderThread && UIThread)
+            {
+                let numDrawFrames = 0;
+                let drawFramesWallDuration = 0.0;
+                let binderDuration = 0.0;
+                let dequeueBufferDuration = 0.0;
+
+                let numRecordViewDraw = 0;
+                let recordViewDrawWallDuration = 0.0;
+
+                renderThread.sliceGroup.slices.forEach(function(slice) {
+                    if (slice.title === DRAW_FRAME_SLICE_TITLE) {
+                        drawFramesWallDuration += slice.duration;
+                        numDrawFrames++;
+                        binderDuration += getTimeInBinder(slice);
+                        dequeueBufferDuration += getTimeInDequeueBuffer(slice);
+                    }
+                });
+                if (numDrawFrames < 10) continue;
+                UIThread.sliceGroup.slices.forEach(function(slice) {
+                    if (slice.title === RECORD_SLICE_TITLE) {
+                        recordViewDrawWallDuration += slice.duration;
+                        numRecordViewDraw++;
+                    }
+                });
+
+                let avgDrawFrameDuration = undefined;
+                if (numDrawFrames > 0) {
+                    avgDrawFrameDuration = (drawFramesWallDuration-dequeueBufferDuration)/numDrawFrames;
+                }
+                let avgRecordViewDrawDuration = undefined;
+                if (numRecordViewDraw > 0) {
+                    avgRecordViewDrawDuration = recordViewDrawWallDuration/numRecordViewDraw;
+                }
+
+                result.addPair('result', {
+                    canonicalUrl: canonicalUrl,
+                    processName: p.name,
+                    avgDrawFrameDuration: Number(avgDrawFrameDuration).toFixed(3),
+                    avgRecordViewDrawDuration: Number(avgRecordViewDrawDuration).toFixed(3),
+                    avgRecordAndPlay: Number(avgDrawFrameDuration+avgRecordViewDrawDuration).toFixed(3)
+                });
+            }
+        }
+    });
+
+</script>
diff --git a/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp b/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp
index c46592c..b0ef11f 100644
--- a/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp
+++ b/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp
@@ -37,7 +37,7 @@
 class ValidatingBakedOpRenderer : public BakedOpRenderer {
 public:
     ValidatingBakedOpRenderer(RenderState& renderState, std::function<void(const Glop& glop)> validator)
-            : BakedOpRenderer(Caches::getInstance(), renderState, true, sLightInfo)
+            : BakedOpRenderer(Caches::getInstance(), renderState, true, false, sLightInfo)
             , mValidator(validator) {
         mGlopReceiver = ValidatingGlopReceiver;
     }
diff --git a/libs/hwui/tests/unit/BakedOpRendererTests.cpp b/libs/hwui/tests/unit/BakedOpRendererTests.cpp
index 380062a..603599c 100644
--- a/libs/hwui/tests/unit/BakedOpRendererTests.cpp
+++ b/libs/hwui/tests/unit/BakedOpRendererTests.cpp
@@ -24,7 +24,8 @@
 const BakedOpRenderer::LightInfo sLightInfo = { 128, 128 };
 
 RENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpRenderer, startRepaintLayer_clear) {
-    BakedOpRenderer renderer(Caches::getInstance(), renderThread.renderState(), true, sLightInfo);
+    BakedOpRenderer renderer(Caches::getInstance(), renderThread.renderState(),
+            true, false, sLightInfo);
     OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 200u, 200u);
 
     layer.dirty(Rect(200, 200));
diff --git a/libs/hwui/tests/unit/BitmapTests.cpp b/libs/hwui/tests/unit/BitmapTests.cpp
index 8c7e081..ed689bd 100644
--- a/libs/hwui/tests/unit/BitmapTests.cpp
+++ b/libs/hwui/tests/unit/BitmapTests.cpp
@@ -29,16 +29,15 @@
 
 TEST(Bitmap, colorTableRefCounting) {
     const SkPMColor c[] = { SkPackARGB32(0x80, 0x80, 0, 0) };
-    SkColorTable* ctable = new SkColorTable(c, SK_ARRAY_COUNT(c));
+    sk_sp<SkColorTable> ctable = SkColorTable::Make(c, SK_ARRAY_COUNT(c));
 
     SkBitmap* bm = new SkBitmap();
     bm->allocPixels(SkImageInfo::Make(1, 1, kIndex_8_SkColorType, kPremul_SkAlphaType),
-            nullptr, ctable);
+            ctable);
     sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(bm, ctable);
     EXPECT_FALSE(ctable->unique());
     delete bm;
     bitmap.reset();
     EXPECT_TRUE(ctable->unique());
-    ctable->unref();
 }
 
diff --git a/libs/hwui/tests/unit/CacheManagerTests.cpp b/libs/hwui/tests/unit/CacheManagerTests.cpp
new file mode 100644
index 0000000..6115162
--- /dev/null
+++ b/libs/hwui/tests/unit/CacheManagerTests.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "renderthread/CacheManager.h"
+#include "renderthread/EglManager.h"
+#include "tests/common/TestUtils.h"
+
+using namespace android;
+using namespace android::uirenderer;
+using namespace android::uirenderer::renderthread;
+
+static size_t getCacheUsage(GrContext* grContext) {
+    size_t cacheUsage;
+    grContext->getResourceCacheUsage(nullptr, &cacheUsage);
+    return cacheUsage;
+}
+
+RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, trimMemory) {
+    DisplayInfo displayInfo = renderThread.mainDisplayInfo();
+    GrContext* grContext = renderThread.getGrContext();
+    ASSERT_TRUE(grContext != nullptr);
+
+    // create pairs of offscreen render targets and images until we exceed the backgroundCacheSizeLimit
+    std::vector<sk_sp<SkSurface>> surfaces;
+
+    while (getCacheUsage(grContext) <= renderThread.cacheManager().getBackgroundCacheSize()) {
+        SkImageInfo info = SkImageInfo::MakeA8(displayInfo.w, displayInfo.h);
+        sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kYes, info);
+        surface->getCanvas()->drawColor(SK_AlphaTRANSPARENT);
+
+        grContext->flush();
+
+        surfaces.push_back(surface);
+    }
+
+    ASSERT_TRUE(1 < surfaces.size());
+
+    // attempt to trim all memory while we still hold strong refs
+    renderThread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
+    ASSERT_TRUE(0 == grContext->getResourceCachePurgeableBytes());
+
+    // free the surfaces
+    for (size_t i = 0; i < surfaces.size(); i++) {
+        ASSERT_TRUE(surfaces[i]->unique());
+        surfaces[i].reset();
+    }
+
+    // verify that we have enough purgeable bytes
+    const size_t purgeableBytes = grContext->getResourceCachePurgeableBytes();
+    ASSERT_TRUE(renderThread.cacheManager().getBackgroundCacheSize() < purgeableBytes);
+
+    // UI hidden and make sure only some got purged
+    renderThread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::UiHidden);
+    ASSERT_TRUE(0 < grContext->getResourceCachePurgeableBytes());
+    ASSERT_TRUE(renderThread.cacheManager().getBackgroundCacheSize() > getCacheUsage(grContext));
+
+    // complete and make sure all get purged
+    renderThread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
+    ASSERT_TRUE(0 == grContext->getResourceCachePurgeableBytes());
+}
diff --git a/libs/hwui/tests/unit/FontRendererTests.cpp b/libs/hwui/tests/unit/FontRendererTests.cpp
index 773a7ea..ee20236 100644
--- a/libs/hwui/tests/unit/FontRendererTests.cpp
+++ b/libs/hwui/tests/unit/FontRendererTests.cpp
@@ -28,7 +28,7 @@
     return true;
 }
 
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FontRenderer, DISABLED_renderDropShadow) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FontRenderer, renderDropShadow) {
     SkPaint paint;
     paint.setTextSize(10);
     paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
diff --git a/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp b/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp
index cfe1134..f6f7337 100644
--- a/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp
+++ b/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp
@@ -50,7 +50,11 @@
 
 // No code left untested
 TEST(GraphicsStats, findRootPath) {
+#ifdef __LP64__
+    std::string expected = "/data/nativetest64/hwui_unit_tests";
+#else
     std::string expected = "/data/nativetest/hwui_unit_tests";
+#endif
     EXPECT_EQ(expected, findRootPath());
 }
 
@@ -156,4 +160,4 @@
         EXPECT_EQ(expectedCount, loadedProto.histogram().Get(i).frame_count());
         EXPECT_EQ(expectedBucket, loadedProto.histogram().Get(i).render_millis());
     }
-}
\ No newline at end of file
+}
diff --git a/libs/hwui/tests/unit/LeakCheckTests.cpp b/libs/hwui/tests/unit/LeakCheckTests.cpp
index 6c42ca1..19d7ef5 100644
--- a/libs/hwui/tests/unit/LeakCheckTests.cpp
+++ b/libs/hwui/tests/unit/LeakCheckTests.cpp
@@ -45,7 +45,7 @@
     FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100,
             sLightGeometery, Caches::getInstance());
     frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-    BakedOpRenderer renderer(caches, renderState, true, sLightInfo);
+    BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
     frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
 }
 
@@ -62,6 +62,6 @@
     FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200,
             sLightGeometery, Caches::getInstance());
     frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-    BakedOpRenderer renderer(caches, renderState, true, sLightInfo);
+    BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
     frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
 }
diff --git a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
index 6cd595a..919852f 100644
--- a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
+++ b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
@@ -41,6 +41,19 @@
     EXPECT_EQ(64u * 192u * 4u, layer.getSizeInBytes());
 }
 
+RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBuffer, constructWideColorGamut) {
+    OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 49u, 149u, true);
+    EXPECT_EQ(49u, layer.viewportWidth);
+    EXPECT_EQ(149u, layer.viewportHeight);
+
+    EXPECT_EQ(64u, layer.texture.width());
+    EXPECT_EQ(192u, layer.texture.height());
+
+    EXPECT_TRUE(layer.wideColorGamut);
+
+    EXPECT_EQ(64u * 192u * 8u, layer.getSizeInBytes());
+}
+
 RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBuffer, getTextureCoordinates) {
     OffscreenBuffer layerAligned(renderThread.renderState(), Caches::getInstance(), 256u, 256u);
     EXPECT_EQ(Rect(0, 1, 1, 0),
@@ -88,6 +101,47 @@
     EXPECT_EQ(0u, pool.getCount());
 }
 
+RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, getPutClearWideColorGamut) {
+    OffscreenBufferPool pool;
+
+    auto layer = pool.get(renderThread.renderState(), 100u, 200u, true);
+    EXPECT_EQ(100u, layer->viewportWidth);
+    EXPECT_EQ(200u, layer->viewportHeight);
+    EXPECT_TRUE(layer->wideColorGamut);
+
+    ASSERT_LT(layer->getSizeInBytes(), pool.getMaxSize());
+
+    pool.putOrDelete(layer);
+    ASSERT_EQ(layer->getSizeInBytes(), pool.getSize());
+
+    auto layer2 = pool.get(renderThread.renderState(), 102u, 202u, true);
+    EXPECT_EQ(layer, layer2) << "layer should be recycled";
+    ASSERT_EQ(0u, pool.getSize()) << "pool should have been emptied by removing only layer";
+
+    pool.putOrDelete(layer2);
+    EXPECT_EQ(1u, pool.getCount());
+    pool.clear();
+    EXPECT_EQ(0u, pool.getSize());
+    EXPECT_EQ(0u, pool.getCount());
+
+    // add non wide gamut layer
+    auto layer3 = pool.get(renderThread.renderState(), 100u, 200u);
+    EXPECT_FALSE(layer3->wideColorGamut);
+    pool.putOrDelete(layer3);
+    EXPECT_EQ(1u, pool.getCount());
+
+    auto layer4 = pool.get(renderThread.renderState(), 100u, 200u, true);
+    EXPECT_TRUE(layer4->wideColorGamut);
+    EXPECT_EQ(1u, pool.getCount());
+    ASSERT_NE(layer3, layer4);
+
+    pool.putOrDelete(layer4);
+
+    pool.clear();
+    EXPECT_EQ(0u, pool.getSize());
+    EXPECT_EQ(0u, pool.getCount());
+}
+
 RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, resize) {
     OffscreenBufferPool pool;
 
@@ -123,6 +177,43 @@
     pool.putOrDelete(layer2);
 }
 
+RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, resizeWideColorGamut) {
+    OffscreenBufferPool pool;
+
+    auto layer = pool.get(renderThread.renderState(), 64u, 64u, true);
+
+    // resize in place
+    ASSERT_EQ(layer, pool.resize(layer, 60u, 55u));
+    EXPECT_EQ(60u, layer->viewportWidth);
+    EXPECT_EQ(55u, layer->viewportHeight);
+    EXPECT_EQ(64u, layer->texture.width());
+    EXPECT_EQ(64u, layer->texture.height());
+
+    EXPECT_TRUE(layer->wideColorGamut);
+    EXPECT_EQ(64u * 64u * 8u, layer->getSizeInBytes());
+
+    // resized to use different object in pool
+    auto layer2 = pool.get(renderThread.renderState(), 128u, 128u, true);
+    pool.putOrDelete(layer2);
+    ASSERT_EQ(1u, pool.getCount());
+
+    // add a non-wide gamut layer
+    auto layer3 = pool.get(renderThread.renderState(), 128u, 128u);
+    pool.putOrDelete(layer3);
+    ASSERT_EQ(2u, pool.getCount());
+
+    ASSERT_EQ(layer2, pool.resize(layer, 120u, 125u));
+    EXPECT_EQ(120u, layer2->viewportWidth);
+    EXPECT_EQ(125u, layer2->viewportHeight);
+    EXPECT_EQ(128u, layer2->texture.width());
+    EXPECT_EQ(128u, layer2->texture.height());
+
+    EXPECT_TRUE(layer2->wideColorGamut);
+    EXPECT_EQ(128u * 128u * 8u, layer2->getSizeInBytes());
+
+    pool.putOrDelete(layer2);
+}
+
 RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, putAndDestroy) {
     OffscreenBufferPool pool;
     // layer too big to return to the pool
@@ -153,3 +244,4 @@
 
     EXPECT_EQ(0, GpuMemoryTracker::getInstanceCount(GpuObjectType::OffscreenBuffer));
 }
+
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index 686d06f..4c3e182 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -450,7 +450,7 @@
     LayerUpdateQueue layerUpdateQueue;
     layerUpdateQueue.enqueueLayerWithDamage(child.get(),
             android::uirenderer::Rect(LAYER_WIDTH, LAYER_HEIGHT));
-    SkiaPipeline::renderLayersImpl(layerUpdateQueue, true);
+    SkiaPipeline::renderLayersImpl(layerUpdateQueue, true, false);
     EXPECT_EQ(1, drawCounter);  //assert index 0 is drawn on the layer
 
     RenderNodeDrawable drawable(parent.get(), surfaceLayer1->getCanvas(), true);
diff --git a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
index dafa074..a3d5079 100644
--- a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
+++ b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
@@ -17,6 +17,7 @@
 #include "tests/common/TestUtils.h"
 
 #include <gtest/gtest.h>
+#include <SkBlurDrawLooper.h>
 #include <SkColorMatrixFilter.h>
 #include <SkColorSpace.h>
 #include <SkImagePriv.h>
@@ -106,3 +107,16 @@
     sk_sp<SkColorSpace> sRGB2 = SkColorSpace::MakeSRGB();
     ASSERT_EQ(sRGB1.get(), sRGB2.get());
 }
+
+TEST(SkiaBehavior, blurDrawLooper) {
+    sk_sp<SkDrawLooper> looper = SkBlurDrawLooper::Make(SK_ColorRED, 5.0f, 3.0f, 4.0f);
+
+    SkDrawLooper::BlurShadowRec blur;
+    bool success = looper->asABlurShadow(&blur);
+    ASSERT_TRUE(success);
+
+    ASSERT_EQ(SK_ColorRED, blur.fColor);
+    ASSERT_EQ(5.0f, blur.fSigma);
+    ASSERT_EQ(3.0f, blur.fOffset.fX);
+    ASSERT_EQ(4.0f, blur.fOffset.fY);
+}
diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
index 0aecb85..c048dda 100644
--- a/libs/hwui/tests/unit/SkiaCanvasTests.cpp
+++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
@@ -89,7 +89,6 @@
     sk_sp<Bitmap> adobeBitmap = Bitmap::allocateHeapBitmap(adobeInfo);
     SkBitmap adobeSkBitmap;
     adobeBitmap->getSkBitmap(&adobeSkBitmap);
-    adobeSkBitmap.lockPixels();
     *adobeSkBitmap.getAddr32(0, 0) = 0xFF0000F0; // Opaque, almost fully-red
 
     SkImageInfo info = adobeInfo.makeColorSpace(nullptr);
@@ -101,7 +100,6 @@
     SkiaCanvas canvas(skBitmap);
     canvas.drawBitmap(*adobeBitmap, 0, 0, nullptr);
     // The result should be fully red, since we convert to sRGB at draw time.
-    skBitmap.lockPixels();
     ASSERT_EQ(0xFF0000FF, *skBitmap.getAddr32(0, 0));
 
     // Create a software canvas with an Adobe color space.
@@ -116,7 +114,6 @@
     SkiaCanvas deferCanvas(&skCanvas, Canvas::XformToSRGB::kDefer);
     deferCanvas.drawBitmap(*adobeBitmap, 0, 0, nullptr);
     // The result should be as before, since we deferred the conversion to sRGB.
-    skBitmap.lockPixels();
     ASSERT_EQ(0xFF0000DC, *skBitmap.getAddr32(0, 0));
 
     // Test picture recording.  We will kDefer the xform at recording time, but handle it when
diff --git a/libs/hwui/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
index a895cba..b397b15 100644
--- a/libs/hwui/tests/unit/SkiaPipelineTests.cpp
+++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
@@ -51,7 +51,8 @@
     auto surface = SkSurface::MakeRasterN32Premul(1, 1);
     surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes,
+            opaque, false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
 }
 
@@ -72,10 +73,12 @@
     auto surface = SkSurface::MakeRasterN32Premul(2, 2);
     surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes,
+            true, false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, false, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes,
+            false, false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned int)SK_ColorTRANSPARENT);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN);
 }
@@ -94,7 +97,8 @@
     auto surface = SkSurface::MakeRasterN32Premul(2, 2);
     surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes,
+            true, false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
     ASSERT_EQ(TestUtils::getColor(surface, 1, 0), SK_ColorBLUE);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorRED);
@@ -135,7 +139,7 @@
     lightGeometry.center = { 0.0f, 0.0f, 0.0f };
     BakedOpRenderer::LightInfo lightInfo;
     auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
-    pipeline->renderLayers(lightGeometry, &layerUpdateQueue, opaque, lightInfo);
+    pipeline->renderLayers(lightGeometry, &layerUpdateQueue, opaque, false, lightInfo);
     ASSERT_EQ(TestUtils::getColor(surfaceLayer1, 0, 0), SK_ColorRED);
     ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 0), SK_ColorBLUE);
     ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 1), SK_ColorWHITE);
@@ -166,32 +170,38 @@
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
 
     // Single draw, should be white.
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
+            false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE);
 
     // 1 Overdraw, should be blue blended onto white.
     renderNodes.push_back(whiteNode);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
+            false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffd0d0ff);
 
     // 2 Overdraw, should be green blended onto white
     renderNodes.push_back(whiteNode);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
+            false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffd0ffd0);
 
     // 3 Overdraw, should be pink blended onto white.
     renderNodes.push_back(whiteNode);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
+            false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffffc0c0);
 
     // 4 Overdraw, should be red blended onto white.
     renderNodes.push_back(whiteNode);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
+            false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffff8080);
 
     // 5 Overdraw, should be red blended onto white.
     renderNodes.push_back(whiteNode);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
+            false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffff8080);
 }
 
@@ -278,7 +288,7 @@
     SkRect dirty = SkRect::MakeWH(800, 600);
     auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
     sk_sp<DeferLayer<DeferTestCanvas>> surface(new DeferLayer<DeferTestCanvas>());
-    pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, false, contentDrawBounds, surface);
     EXPECT_EQ(4, surface->canvas()->mDrawCounter);
 }
 
@@ -308,7 +318,7 @@
     SkRect dirty = SkRect::MakeLTRB(10, 20, 30, 40);
     auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
     sk_sp<DeferLayer<ClippedTestCanvas>> surface(new DeferLayer<ClippedTestCanvas>());
-    pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true,
+    pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, false,
             SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface);
     EXPECT_EQ(1, surface->canvas()->mDrawCounter);
 }
@@ -339,7 +349,7 @@
     SkRect dirty = SkRect::MakeLTRB(10, 10, 40, 40);
     auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
     sk_sp<DeferLayer<ClipReplaceTestCanvas>> surface(new DeferLayer<ClipReplaceTestCanvas>());
-    pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true,
+    pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, false,
             SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface);
     EXPECT_EQ(1, surface->canvas()->mDrawCounter);
 }
diff --git a/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp b/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp
index 5383e57..8312bda 100644
--- a/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp
+++ b/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp
@@ -26,7 +26,7 @@
 using namespace android;
 using namespace android::uirenderer;
 
-RENDERTHREAD_OPENGL_PIPELINE_TEST(TextDropShadowCache, DISABLED_addRemove) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(TextDropShadowCache, addRemove) {
     SkPaint paint;
     paint.setTextSize(20);
 
diff --git a/libs/hwui/tests/unit/TextureCacheTests.cpp b/libs/hwui/tests/unit/TextureCacheTests.cpp
index 72384bf..ab740dd 100644
--- a/libs/hwui/tests/unit/TextureCacheTests.cpp
+++ b/libs/hwui/tests/unit/TextureCacheTests.cpp
@@ -31,7 +31,7 @@
     SkBitmap skBitmap;
     SkImageInfo info = SkImageInfo::Make(100, 100, kN32_SkColorType, kPremul_SkAlphaType);
     skBitmap.setInfo(info);
-    sk_sp<Bitmap> hwBitmap(Bitmap::allocateHardwareBitmap(renderThread, skBitmap));
+    sk_sp<Bitmap> hwBitmap(renderThread.allocateHardwareBitmap(skBitmap));
     cache.get(hwBitmap.get());
     ASSERT_EQ(GpuMemoryTracker::getInstanceCount(GpuObjectType::Texture), initialCount + 1);
     cache.clear();
diff --git a/libs/hwui/tests/unit/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp
index 6f264e1..1c21567 100644
--- a/libs/hwui/tests/unit/VectorDrawableTests.cpp
+++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp
@@ -382,47 +382,24 @@
 
 }
 
-static SkShader* createShader(bool* isDestroyed) {
-    class TestShader : public SkShader {
-    public:
-        TestShader(bool* isDestroyed) : SkShader(), mDestroyed(isDestroyed) {
-        }
-        ~TestShader() {
-            *mDestroyed = true;
-        }
-
-        Factory getFactory() const override { return nullptr; }
-    private:
-        bool* mDestroyed;
-    };
-    return new TestShader(isDestroyed);
-}
-
 TEST(VectorDrawable, drawPathWithoutIncrementingShaderRefCount) {
     VectorDrawable::FullPath path("m1 1", 4);
     SkBitmap bitmap;
-    SkImageInfo info = SkImageInfo::Make(5, 5, kN32_SkColorType, kPremul_SkAlphaType);
-    bitmap.setInfo(info);
-    bitmap.allocPixels(info);
+    bitmap.allocN32Pixels(5, 5, false);
     SkCanvas canvas(bitmap);
 
-    bool shaderIsDestroyed = false;
-
+    sk_sp<SkShader> shader = SkShader::MakeColorShader(SK_ColorBLACK);
     // Initial ref count is 1
-    SkShader* shader = createShader(&shaderIsDestroyed);
+    EXPECT_TRUE(shader->unique());
 
     // Setting the fill gradient increments the ref count of the shader by 1
-    path.mutateStagingProperties()->setFillGradient(shader);
+    path.mutateStagingProperties()->setFillGradient(shader.get());
+    EXPECT_FALSE(shader->unique());
     path.draw(&canvas, true);
     // Resetting the fill gradient decrements the ref count of the shader by 1
     path.mutateStagingProperties()->setFillGradient(nullptr);
 
-    // Expect ref count to be 1 again, i.e. nothing else to have a ref to the shader now. Unref()
-    // again should bring the ref count to zero and consequently trigger detor.
-    shader->unref();
-
-    // Verify that detor is called.
-    EXPECT_TRUE(shaderIsDestroyed);
+    EXPECT_TRUE(shader->unique());
 }
 
 }; // namespace uirenderer
diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp
index 4991f04..ed31b12 100644
--- a/libs/input/SpriteController.cpp
+++ b/libs/input/SpriteController.cpp
@@ -220,13 +220,13 @@
 
                 if (outBuffer.width > update.state.icon.bitmap.width()) {
                     paint.setColor(0); // transparent fill color
-                    surfaceCanvas.drawRectCoords(update.state.icon.bitmap.width(), 0,
-                            outBuffer.width, update.state.icon.bitmap.height(), paint);
+                    surfaceCanvas.drawRect(SkRect::MakeLTRB(update.state.icon.bitmap.width(), 0,
+                            outBuffer.width, update.state.icon.bitmap.height()), paint);
                 }
                 if (outBuffer.height > update.state.icon.bitmap.height()) {
                     paint.setColor(0); // transparent fill color
-                    surfaceCanvas.drawRectCoords(0, update.state.icon.bitmap.height(),
-                            outBuffer.width, outBuffer.height, paint);
+                    surfaceCanvas.drawRect(SkRect::MakeLTRB(0, update.state.icon.bitmap.height(),
+                            outBuffer.width, outBuffer.height), paint);
                 }
 
                 status = surface->unlockAndPost();
@@ -405,7 +405,11 @@
 
     uint32_t dirty;
     if (icon.isValid()) {
-        icon.bitmap.copyTo(&mLocked.state.icon.bitmap, kN32_SkColorType);
+        SkBitmap* bitmapCopy = &mLocked.state.icon.bitmap;
+        if (bitmapCopy->tryAllocPixels(icon.bitmap.info().makeColorType(kN32_SkColorType))) {
+            icon.bitmap.readPixels(bitmapCopy->info(), bitmapCopy->getPixels(),
+                    bitmapCopy->rowBytes(), 0, 0);
+        }
 
         if (!mLocked.state.icon.isValid()
                 || mLocked.state.icon.hotSpotX != icon.hotSpotX
diff --git a/libs/input/SpriteController.h b/libs/input/SpriteController.h
index 7fc8d6f..31e43e9 100644
--- a/libs/input/SpriteController.h
+++ b/libs/input/SpriteController.h
@@ -65,7 +65,10 @@
 
     inline SpriteIcon copy() const {
         SkBitmap bitmapCopy;
-        bitmap.copyTo(&bitmapCopy, kN32_SkColorType);
+        if (bitmapCopy.tryAllocPixels(bitmap.info().makeColorType(kN32_SkColorType))) {
+            bitmap.readPixels(bitmapCopy.info(), bitmapCopy.getPixels(), bitmapCopy.rowBytes(),
+                    0, 0);
+        }
         return SpriteIcon(bitmapCopy, hotSpotX, hotSpotY);
     }
 
diff --git a/libs/usb/Android.bp b/libs/usb/Android.bp
new file mode 100644
index 0000000..b8f2904
--- /dev/null
+++ b/libs/usb/Android.bp
@@ -0,0 +1 @@
+subdirs = ["tests/*"]
diff --git a/libs/usb/tests/AccessoryChat/Android.bp b/libs/usb/tests/AccessoryChat/Android.bp
new file mode 100644
index 0000000..4af6274
--- /dev/null
+++ b/libs/usb/tests/AccessoryChat/Android.bp
@@ -0,0 +1 @@
+subdirs = ["accessorychat"]
diff --git a/libs/usb/tests/AccessoryChat/accessorychat/Android.bp b/libs/usb/tests/AccessoryChat/accessorychat/Android.bp
new file mode 100644
index 0000000..5613745
--- /dev/null
+++ b/libs/usb/tests/AccessoryChat/accessorychat/Android.bp
@@ -0,0 +1,30 @@
+cc_binary {
+    name: "accessorychat",
+    host_supported: true,
+
+    srcs: ["accessorychat.c"],
+    cflags: [
+        "-Werror",
+        "-Wno-unused-parameter",
+    ],
+
+    target: {
+        android: {
+            shared_libs: [
+                "libusbhost",
+                "libcutils",
+            ],
+        },
+        host: {
+            static_libs: [
+                "libusbhost",
+                "libcutils",
+            ],
+
+            cflags: ["-O0"],
+        },
+        darwin: {
+            enabled: false,
+        },
+    },
+}
diff --git a/libs/usb/tests/AccessoryChat/accessorychat/Android.mk b/libs/usb/tests/AccessoryChat/accessorychat/Android.mk
deleted file mode 100644
index 51f2111..0000000
--- a/libs/usb/tests/AccessoryChat/accessorychat/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-# Build for Linux (desktop) host
-ifeq ($(HOST_OS),linux)
-
-include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := accessorychat.c
-
-LOCAL_MODULE := accessorychat
-
-LOCAL_STATIC_LIBRARIES := libusbhost libcutils
-LOCAL_LDLIBS += -lpthread
-LOCAL_CFLAGS := -g -O0
-
-include $(BUILD_HOST_EXECUTABLE)
-
-endif
-
-# Build for device
-include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := accessorychat.c
-
-LOCAL_MODULE := accessorychat
-
-LOCAL_SHARED_LIBRARIES := libusbhost libcutils
-
-include $(BUILD_EXECUTABLE)
diff --git a/libs/usb/tests/accessorytest/Android.bp b/libs/usb/tests/accessorytest/Android.bp
new file mode 100644
index 0000000..c6340e3
--- /dev/null
+++ b/libs/usb/tests/accessorytest/Android.bp
@@ -0,0 +1,28 @@
+cc_binary_host {
+    name: "accessorytest",
+
+    srcs: [
+        "accessory.c",
+        "audio.c",
+        "hid.c",
+        "usb.c",
+    ],
+
+    static_libs: [
+        "libusbhost",
+        "libcutils",
+        "libtinyalsa",
+    ],
+    cflags: [
+        "-O0",
+        "-Wno-unused-parameter",
+        "-Werror",
+    ],
+
+    target: {
+        darwin: {
+            // Build for Linux host only
+            enabled: false,
+        },
+    },
+}
diff --git a/libs/usb/tests/accessorytest/Android.mk b/libs/usb/tests/accessorytest/Android.mk
deleted file mode 100644
index 6d9a946..0000000
--- a/libs/usb/tests/accessorytest/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-# Build for Linux host only
-ifeq ($(HOST_OS),linux)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES :=  accessory.c \
-                    audio.c     \
-                    hid.c       \
-                    usb.c
-
-LOCAL_C_INCLUDES += external/tinyalsa/include
-
-LOCAL_MODULE := accessorytest
-
-LOCAL_STATIC_LIBRARIES := libusbhost libcutils libtinyalsa
-LOCAL_LDLIBS += -lpthread
-LOCAL_CFLAGS := -g -O0
-
-include $(BUILD_HOST_EXECUTABLE)
-
-endif
diff --git a/libs/usb/tests/accessorytest/accessory.h b/libs/usb/tests/accessorytest/accessory.h
index 55c4550..e86986e 100644
--- a/libs/usb/tests/accessorytest/accessory.h
+++ b/libs/usb/tests/accessorytest/accessory.h
@@ -19,7 +19,7 @@
 
 int init_audio(unsigned int ic, unsigned int id, unsigned int oc, unsigned int od);
 void init_hid();
-void usb_run(int enable_accessory);
+void usb_run(uintptr_t enable_accessory);
 
 struct usb_device* usb_wait_for_device();
 
diff --git a/libs/usb/tests/accessorytest/hid.c b/libs/usb/tests/accessorytest/hid.c
index b70d678..283755d 100644
--- a/libs/usb/tests/accessorytest/hid.c
+++ b/libs/usb/tests/accessorytest/hid.c
@@ -139,7 +139,7 @@
 
     fprintf(stderr, "opened /dev/%s\n", name);
     pthread_t th;
-    pthread_create(&th, NULL, hid_thread, (void *)fd);
+    pthread_create(&th, NULL, hid_thread, (void *)(uintptr_t)fd);
 }
 
 static void* inotify_thread(void* arg)
diff --git a/libs/usb/tests/accessorytest/usb.c b/libs/usb/tests/accessorytest/usb.c
index ac72b35..1a161ad 100644
--- a/libs/usb/tests/accessorytest/usb.c
+++ b/libs/usb/tests/accessorytest/usb.c
@@ -219,7 +219,7 @@
     return device;
 }
 
-void usb_run(int enable_accessory) {
+void usb_run(uintptr_t enable_accessory) {
     struct usb_host_context* context = usb_host_init();
 
     usb_host_run(context, usb_device_added, usb_device_removed, NULL, (void *)enable_accessory);
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index de85c16..d24a477 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -436,8 +436,8 @@
      *     E1BC code lock       : [ 0   4ms ]  : STATE_GAL_E1BC_CODE_LOCK is set
      *     E1C 2nd code lock    : [ 0 100ms ]  : STATE_GAL_E1C_2ND_CODE_LOCK is set
      *     E1B page             : [ 0    2s ]  : STATE_GAL_E1B_PAGE_SYNC is set
-     *     Time of week decoded : [ 0 1week ]  : STATE_GAL_TOW_DECODED is set
-     *     Time of week known   : [ 0 1week ]  : STATE_GAL_TOW_KNOWN set</pre>
+     *     Time of week decoded : [ 0 1week ]  : STATE_TOW_DECODED is set
+     *     Time of week known   : [ 0 1week ]  : STATE_TOW_KNOWN set</pre>
      *
      * Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
      * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index 912551f..b2903c4 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -97,13 +97,12 @@
             CONSTELLATION_QZSS, CONSTELLATION_BEIDOU, CONSTELLATION_GALILEO})
     public @interface ConstellationType {}
 
-    /* These package private values are modified by the LocationManager class */
-    /* package */ int[] mSvidWithFlags;
-    /* package */ float[] mCn0DbHz;
-    /* package */ float[] mElevations;
-    /* package */ float[] mAzimuths;
-    /* package */ int mSvCount;
-    /* package */ float[] mCarrierFrequencies;
+    final int[] mSvidWithFlags;
+    final float[] mCn0DbHz;
+    final float[] mElevations;
+    final float[] mAzimuths;
+    final int mSvCount;
+    final float[] mCarrierFrequencies;
 
     GnssStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations,
             float[] azimuths, float[] carrierFrequencies) {
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 26ac2a2..968f596 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -74,7 +74,8 @@
             new HashMap<>();
     private final HashMap<OnNmeaMessageListener, GnssStatusListenerTransport> mGnssNmeaListeners =
             new HashMap<>();
-    private GnssStatus mGnssStatus;
+    // volatile + GnssStatus final-fields pattern to avoid a partially published object
+    private volatile GnssStatus mGnssStatus;
     private int mTimeToFirstFix;
 
     /**
@@ -1563,7 +1564,7 @@
                 float[] cn0s, float[] elevations, float[] azimuths, float[] carrierFreqs) {
             if (mGnssCallback != null) {
                 mGnssStatus = new GnssStatus(svCount, prnWithFlags, cn0s, elevations, azimuths,
-                    carrierFreqs);
+                        carrierFreqs);
 
                 Message msg = Message.obtain();
                 msg.what = GpsStatus.GPS_EVENT_SATELLITE_STATUS;
@@ -1949,7 +1950,7 @@
             status = new GpsStatus();
         }
         // When mGnssStatus is null, that means that this method is called outside
-        // onGpsStatusChanged().  Return an empty status  to maintain backwards compatibility.
+        // onGpsStatusChanged().  Return an empty status to maintain backwards compatibility.
         if (mGnssStatus != null) {
             status.setStatus(mGnssStatus, mTimeToFirstFix);
         }
diff --git a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
new file mode 100644
index 0000000..833376c
--- /dev/null
+++ b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
@@ -0,0 +1,268 @@
+/*
+ * 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.internal.location.gnssmetrics;
+
+import android.os.SystemClock;
+
+import android.util.Base64;
+import android.util.TimeUtils;
+
+import java.util.Arrays;
+
+import com.android.internal.location.nano.GnssLogsProto.GnssLog;
+
+/**
+ * GnssMetrics: Is used for logging GNSS metrics
+ * @hide
+ */
+public class GnssMetrics {
+
+  /** Default time between location fixes (in millisecs) */
+  private static final int DEFAULT_TIME_BETWEEN_FIXES_MILLISECS = 1000;
+
+  /* The time since boot when logging started */
+  private String logStartInElapsedRealTime;
+
+  /** Constructor */
+  public GnssMetrics() {
+    locationFailureStatistics = new Statistics();
+    timeToFirstFixSecStatistics = new Statistics();
+    positionAccuracyMeterStatistics = new Statistics();
+    topFourAverageCn0Statistics = new Statistics();
+    reset();
+  }
+
+  /**
+   * Logs the status of a location report received from the HAL
+   *
+   * @param isSuccessful
+   */
+  public void logReceivedLocationStatus(boolean isSuccessful) {
+    if (!isSuccessful) {
+      locationFailureStatistics.addItem(1.0);
+      return;
+    }
+    locationFailureStatistics.addItem(0.0);
+    return;
+  }
+
+  /**
+   * Logs missed reports
+   *
+   * @param desiredTimeBetweenFixesMilliSeconds
+   * @param actualTimeBetweenFixesMilliSeconds
+   */
+  public void logMissedReports(int desiredTimeBetweenFixesMilliSeconds,
+      int actualTimeBetweenFixesMilliSeconds) {
+    int numReportMissed = (actualTimeBetweenFixesMilliSeconds /
+        Math.max(DEFAULT_TIME_BETWEEN_FIXES_MILLISECS, desiredTimeBetweenFixesMilliSeconds)) - 1;
+    if (numReportMissed > 0) {
+      for (int i = 0; i < numReportMissed; i++) {
+        locationFailureStatistics.addItem(1.0);
+      }
+    }
+    return;
+  }
+
+  /**
+   * Logs time to first fix
+   *
+   * @param timeToFirstFixMilliSeconds
+   */
+  public void logTimeToFirstFixMilliSecs(int timeToFirstFixMilliSeconds) {
+    timeToFirstFixSecStatistics.addItem((double) (timeToFirstFixMilliSeconds/1000));
+    return;
+  }
+
+  /**
+   * Logs position accuracy
+   *
+   * @param positionAccuracyMeters
+   */
+  public void logPositionAccuracyMeters(float positionAccuracyMeters) {
+    positionAccuracyMeterStatistics.addItem((double) positionAccuracyMeters);
+    return;
+  }
+
+  /*
+  * Logs CN0 when at least 4 SVs are available
+  *
+  */
+  public void logCn0(float[] cn0s, int numSv) {
+    if (numSv < 4) {
+      return;
+    }
+    float[] cn0Array = Arrays.copyOf(cn0s, numSv);
+    Arrays.sort(cn0Array);
+    if (cn0Array[numSv - 4] > 0.0) {
+      double top4AvgCn0 = 0.0;
+      for (int i = numSv - 4; i < numSv; i++) {
+        top4AvgCn0 += (double) cn0Array[i];
+      }
+      top4AvgCn0 /= 4;
+      topFourAverageCn0Statistics.addItem(top4AvgCn0);
+    }
+    return;
+  }
+
+  /**
+   * Dumps GNSS metrics as a proto string
+   * @return
+   */
+  public String dumpGnssMetricsAsProtoString() {
+    GnssLog msg = new GnssLog();
+    if (locationFailureStatistics.getCount() > 0) {
+      msg.numLocationReportProcessed = locationFailureStatistics.getCount();
+      msg.percentageLocationFailure = (int) (100.0 * locationFailureStatistics.getMean());
+    }
+    if (timeToFirstFixSecStatistics.getCount() > 0) {
+      msg.numTimeToFirstFixProcessed = timeToFirstFixSecStatistics.getCount();
+      msg.meanTimeToFirstFixSecs = (int) timeToFirstFixSecStatistics.getMean();
+      msg.standardDeviationTimeToFirstFixSecs
+          = (int) timeToFirstFixSecStatistics.getStandardDeviation();
+    }
+    if (positionAccuracyMeterStatistics.getCount() > 0) {
+      msg.numPositionAccuracyProcessed = positionAccuracyMeterStatistics.getCount();
+      msg.meanPositionAccuracyMeters = (int) positionAccuracyMeterStatistics.getMean();
+      msg.standardDeviationPositionAccuracyMeters
+          = (int) positionAccuracyMeterStatistics.getStandardDeviation();
+    }
+    if (topFourAverageCn0Statistics.getCount() > 0) {
+      msg.numTopFourAverageCn0Processed = topFourAverageCn0Statistics.getCount();
+      msg.meanTopFourAverageCn0DbHz = topFourAverageCn0Statistics.getMean();
+      msg.standardDeviationTopFourAverageCn0DbHz
+          = topFourAverageCn0Statistics.getStandardDeviation();
+    }
+    String s = Base64.encodeToString(GnssLog.toByteArray(msg), Base64.DEFAULT);
+    reset();
+    return s;
+  }
+
+  /**
+   * Dumps GNSS Metrics as text
+   *
+   * @return GNSS Metrics
+   */
+  public String dumpGnssMetricsAsText() {
+    StringBuilder s = new StringBuilder();
+    s.append("GNSS_KPI_START").append('\n');
+    s.append("  KPI logging start time: ").append(logStartInElapsedRealTime).append("\n");
+    s.append("  KPI logging end time: ");
+    TimeUtils.formatDuration(SystemClock.elapsedRealtimeNanos() / 1000000L, s);
+    s.append("\n");
+    s.append("  Number of location reports: ").append(
+        locationFailureStatistics.getCount()).append("\n");
+    if (locationFailureStatistics.getCount() > 0) {
+      s.append("  Percentage location failure: ").append(
+          100.0 * locationFailureStatistics.getMean()).append("\n");
+    }
+    s.append("  Number of TTFF reports: ").append(
+        timeToFirstFixSecStatistics.getCount()).append("\n");
+    if (timeToFirstFixSecStatistics.getCount() > 0) {
+      s.append("  TTFF mean (sec): ").append(timeToFirstFixSecStatistics.getMean()).append("\n");
+      s.append("  TTFF standard deviation (sec): ").append(
+          timeToFirstFixSecStatistics.getStandardDeviation()).append("\n");
+    }
+    s.append("  Number of position accuracy reports: ").append(
+        positionAccuracyMeterStatistics.getCount()).append("\n");
+    if (positionAccuracyMeterStatistics.getCount() > 0) {
+      s.append("  Position accuracy mean (m): ").append(
+          positionAccuracyMeterStatistics.getMean()).append("\n");
+      s.append("  Position accuracy standard deviation (m): ").append(
+          positionAccuracyMeterStatistics.getStandardDeviation()).append("\n");
+    }
+    s.append("  Number of CN0 reports: ").append(
+        topFourAverageCn0Statistics.getCount()).append("\n");
+    if (topFourAverageCn0Statistics.getCount() > 0) {
+      s.append("  Top 4 Avg CN0 mean (dB-Hz): ").append(
+          topFourAverageCn0Statistics.getMean()).append("\n");
+      s.append("  Top 4 Avg CN0 standard deviation (dB-Hz): ").append(
+          topFourAverageCn0Statistics.getStandardDeviation()).append("\n");
+    }
+    s.append("GNSS_KPI_END").append("\n");
+    return s.toString();
+  }
+
+   /** Class for storing statistics */
+  private class Statistics {
+
+    /** Resets statistics */
+    public void reset() {
+      count = 0;
+      sum = 0.0;
+      sumSquare = 0.0;
+    }
+
+    /** Adds an item */
+    public void addItem(double item) {
+      count++;
+      sum += item;
+      sumSquare += item * item;
+    }
+
+    /** Returns number of items added */
+    public int getCount() {
+      return count;
+    }
+
+    /** Returns mean */
+    public double getMean() {
+      return sum/count;
+    }
+
+    /** Returns standard deviation */
+    public double getStandardDeviation() {
+      double m = sum/count;
+      m = m * m;
+      double v = sumSquare/count;
+      if (v > m) {
+        return Math.sqrt(v - m);
+      }
+      return 0;
+    }
+
+    private int count;
+    private double sum;
+    private double sumSquare;
+  }
+
+  /** Location failure statistics */
+  private Statistics locationFailureStatistics;
+
+  /** Time to first fix statistics */
+  private Statistics timeToFirstFixSecStatistics;
+
+  /** Position accuracy statistics */
+  private Statistics positionAccuracyMeterStatistics;
+
+  /** Top 4 average CN0 statistics */
+  private Statistics topFourAverageCn0Statistics;
+
+  /**
+   * Resets GNSS metrics
+   */
+  private void reset() {
+    StringBuilder s = new StringBuilder();
+    TimeUtils.formatDuration(SystemClock.elapsedRealtimeNanos() / 1000000L, s);
+    logStartInElapsedRealTime = s.toString();
+    locationFailureStatistics.reset();
+    timeToFirstFixSecStatistics.reset();
+    positionAccuracyMeterStatistics.reset();
+    topFourAverageCn0Statistics.reset();
+    return;
+  }
+}
\ No newline at end of file
diff --git a/media/java/android/media/AmrInputStream.java b/media/java/android/media/AmrInputStream.java
index fb91bbb..efaf224 100644
--- a/media/java/android/media/AmrInputStream.java
+++ b/media/java/android/media/AmrInputStream.java
@@ -25,12 +25,12 @@
 
 
 /**
- * AmrInputStream
+ * DO NOT USE
  * @hide
  */
 public final class AmrInputStream extends InputStream {
     private final static String TAG = "AmrInputStream";
-    
+
     // frame is 20 msec at 8.000 khz
     private final static int SAMPLES_PER_FRAME = 8000 * 20 / 1000;
 
@@ -51,10 +51,10 @@
     private byte[] mOneByte = new byte[1];
 
     /**
-     * Create a new AmrInputStream, which converts 16 bit PCM to AMR
-     * @param inputStream InputStream containing 16 bit PCM.
+     * DO NOT USE - use MediaCodec instead
      */
     public AmrInputStream(InputStream inputStream) {
+        Log.w(TAG, "@@@@ AmrInputStream is not a public API @@@@");
         mInputStream = inputStream;
 
         MediaFormat format  = new MediaFormat();
@@ -83,17 +83,26 @@
         mInfo = new BufferInfo();
     }
 
+    /**
+     * DO NOT USE
+     */
     @Override
     public int read() throws IOException {
         int rtn = read(mOneByte, 0, 1);
         return rtn == 1 ? (0xff & mOneByte[0]) : -1;
     }
 
+    /**
+     * DO NOT USE
+     */
     @Override
     public int read(byte[] b) throws IOException {
         return read(b, 0, b.length);
     }
 
+    /**
+     * DO NOT USE
+     */
     @Override
     public int read(byte[] b, int offset, int length) throws IOException {
         if (mCodec == null) {
@@ -131,19 +140,15 @@
                 }
             }
 
-            // now read encoded data from the encoder (blocking, since we just filled up the
-            // encoder's input with data it should be able to output at least one buffer)
-            while (true) {
-                int index = mCodec.dequeueOutputBuffer(mInfo, -1);
-                if (index >= 0) {
-                    mBufIn = mInfo.size;
-                    ByteBuffer out = mCodec.getOutputBuffer(index);
-                    out.get(mBuf, 0 /* offset */, mBufIn /* length */);
-                    mCodec.releaseOutputBuffer(index,  false /* render */);
-                    if ((mInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
-                        mSawOutputEOS = true;
-                    }
-                    break;
+            // now read encoded data from the encoder
+            int index = mCodec.dequeueOutputBuffer(mInfo, 0);
+            if (index >= 0) {
+                mBufIn = mInfo.size;
+                ByteBuffer out = mCodec.getOutputBuffer(index);
+                out.get(mBuf, 0 /* offset */, mBufIn /* length */);
+                mCodec.releaseOutputBuffer(index,  false /* render */);
+                if ((mInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+                    mSawOutputEOS = true;
                 }
             }
         }
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index c1e81c5..f403988 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -218,6 +218,7 @@
         SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_COMMUNICATION_DELAYED,SUPPRESSIBLE_NOTIFICATION);
         SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_EVENT,                SUPPRESSIBLE_NOTIFICATION);
         SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_ACCESSIBILITY,          SUPPRESSIBLE_NEVER);
+        SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION,               SUPPRESSIBLE_NEVER);
     }
 
     /**
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 20deeb16..05be088 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1501,7 +1501,9 @@
         if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADSET,"")
                 == AudioSystem.DEVICE_STATE_UNAVAILABLE &&
             AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADPHONE,"")
-                == AudioSystem.DEVICE_STATE_UNAVAILABLE) {
+                == AudioSystem.DEVICE_STATE_UNAVAILABLE &&
+            AudioSystem.getDeviceConnectionState(DEVICE_OUT_USB_HEADSET, "")
+              == AudioSystem.DEVICE_STATE_UNAVAILABLE) {
             return false;
         } else {
             return true;
@@ -3324,6 +3326,9 @@
      * The audio output device code for a wired headphone without attached microphone */
     public static final int DEVICE_OUT_WIRED_HEADPHONE = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;
     /** @hide
+     * The audio output device code for a USB headphone with attached microphone */
+    public static final int DEVICE_OUT_USB_HEADSET = AudioSystem.DEVICE_OUT_USB_HEADSET;
+    /** @hide
      * The audio output device code for generic Bluetooth SCO, for voice */
     public static final int DEVICE_OUT_BLUETOOTH_SCO = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
     /** @hide
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index 0a1de33..2b5ac5e 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -59,4 +59,15 @@
 
         int getRingerModeAffectedStreams(int streams);
     }
+
+    /**
+     * Disable or restore the ability to play audio for a given UID.
+     * When a UID isn't meant to be tracked anymore (e.g. client died), re-enable audio for this UID
+     * to prevent disabling audio for future UIDs that would reuse the same value.
+     * This operation is asynchronous.
+     * @param disable when true, prevents playback of audio streams from the given uid. If false,
+     *         restores the ability to play, or no-op if playback hadn't been disabled before.
+     * @param uid the client UID whose ability to play will be affected.
+     */
+    public abstract void disableAudioForUid(boolean disable, int uid);
 }
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 47ecf32..ea4d802 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -424,7 +424,8 @@
                                                   DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
                                                   DEVICE_OUT_BLUETOOTH_SCO_CARKIT);
     public static final int DEVICE_OUT_ALL_USB = (DEVICE_OUT_USB_ACCESSORY |
-                                                  DEVICE_OUT_USB_DEVICE);
+                                                  DEVICE_OUT_USB_DEVICE |
+                                                  DEVICE_OUT_USB_HEADSET);
     public static final int DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO = (DEVICE_OUT_AUX_LINE |
                                                                 DEVICE_OUT_HDMI_ARC |
                                                                 DEVICE_OUT_SPDIF);
@@ -486,7 +487,8 @@
                                              DEVICE_IN_DEFAULT);
     public static final int DEVICE_IN_ALL_SCO = DEVICE_IN_BLUETOOTH_SCO_HEADSET;
     public static final int DEVICE_IN_ALL_USB = (DEVICE_IN_USB_ACCESSORY |
-                                                 DEVICE_IN_USB_DEVICE);
+                                                 DEVICE_IN_USB_DEVICE |
+                                                 DEVICE_IN_USB_HEADSET);
 
     // device states, must match AudioSystem::device_connection_state
     public static final int DEVICE_STATE_UNAVAILABLE = 0;
@@ -758,6 +760,8 @@
 
     public static native int systemReady();
 
+    public static native float getStreamVolumeDB(int stream, int index, int device);
+
     // Items shared with audio service
 
     /**
@@ -799,14 +803,14 @@
         4,  // STREAM_VOICE_CALL
         7,  // STREAM_SYSTEM
         5,  // STREAM_RING
-        11, // STREAM_MUSIC
+        5, // STREAM_MUSIC
         6,  // STREAM_ALARM
         5,  // STREAM_NOTIFICATION
         7,  // STREAM_BLUETOOTH_SCO
         7,  // STREAM_SYSTEM_ENFORCED
-        11, // STREAM_DTMF
-        11, // STREAM_TTS
-        11, // STREAM_ACCESSIBILITY
+        5, // STREAM_DTMF
+        5, // STREAM_TTS
+        5, // STREAM_ACCESSIBILITY
     };
 
     public static String streamToString(int stream) {
diff --git a/media/java/android/media/IMediaRouterClient.aidl b/media/java/android/media/IMediaRouterClient.aidl
index 9640dcb..08344f1 100644
--- a/media/java/android/media/IMediaRouterClient.aidl
+++ b/media/java/android/media/IMediaRouterClient.aidl
@@ -21,4 +21,5 @@
  */
 oneway interface IMediaRouterClient {
     void onStateChanged();
+    void onRestoreRoute();
 }
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index f8f5fdf..3308fc9 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -27,6 +27,7 @@
     void unregisterClient(IMediaRouterClient client);
 
     MediaRouterClientState getState(IMediaRouterClient client);
+    boolean isPlaybackActive(IMediaRouterClient client);
 
     void setDiscoveryRequest(IMediaRouterClient client, int routeTypes, boolean activeScan);
     void setSelectedRoute(IMediaRouterClient client, String routeId, boolean explicit);
diff --git a/media/java/android/media/ImageUtils.java b/media/java/android/media/ImageUtils.java
index abf6b20..2a0e04e 100644
--- a/media/java/android/media/ImageUtils.java
+++ b/media/java/android/media/ImageUtils.java
@@ -62,6 +62,7 @@
             case ImageFormat.RAW12:
             case ImageFormat.DEPTH16:
             case ImageFormat.DEPTH_POINT_CLOUD:
+            case ImageFormat.RAW_DEPTH:
                 return 1;
             case ImageFormat.PRIVATE:
                 return 0;
@@ -103,6 +104,10 @@
             throw new IllegalArgumentException(
                     "Copy of RAW_OPAQUE format has not been implemented");
         }
+        if (src.getFormat() == ImageFormat.RAW_DEPTH) {
+            throw new IllegalArgumentException(
+                    "Copy of RAW_DEPTH format has not been implemented");
+        }
         if (!(dst.getOwner() instanceof ImageWriter)) {
             throw new IllegalArgumentException("Destination image is not from ImageWriter. Only"
                     + " the images from ImageWriter are writable");
@@ -206,6 +211,7 @@
             case PixelFormat.RGB_565:
             case ImageFormat.YUY2:
             case ImageFormat.Y16:
+            case ImageFormat.RAW_DEPTH:
             case ImageFormat.RAW_SENSOR:
             case ImageFormat.RAW_PRIVATE: // round estimate, real size is unknown
             case ImageFormat.DEPTH16:
@@ -253,6 +259,7 @@
             case ImageFormat.RAW_SENSOR:
             case ImageFormat.RAW10:
             case ImageFormat.RAW12:
+            case ImageFormat.RAW_DEPTH:
                 return new Size(image.getWidth(), image.getHeight());
             case ImageFormat.PRIVATE:
                 return new Size(0, 0);
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 2de69e7..9b74656 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -339,6 +339,12 @@
         (unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)</td>
    </tr>
    <tr>
+    <td>FLAC</td>
+    <td>Metadata blocks</td>
+    <td class=NA>Not Used</td>
+    <td class=NA>Not Used</td>
+   </tr>
+   <tr>
     <td>MPEG-4</td>
     <td>Decoder-specific information from ESDS<sup>*</sup></td>
     <td class=NA>Not Used</td>
@@ -2440,6 +2446,8 @@
             }
         };
 
+        private final Pattern zeroPattern = new Pattern(0, 0);
+
         /**
          * The pattern applicable to the protected data in each subsample.
          */
@@ -2462,7 +2470,7 @@
             key = newKey;
             iv = newIV;
             mode = newMode;
-            pattern = new Pattern(0, 0);
+            pattern = zeroPattern;
         }
 
         /**
diff --git a/media/java/android/media/MediaDescription.java b/media/java/android/media/MediaDescription.java
index 14485d3c..e6aea99 100644
--- a/media/java/android/media/MediaDescription.java
+++ b/media/java/android/media/MediaDescription.java
@@ -220,6 +220,33 @@
     }
 
     @Override
+    public boolean equals(Object o) {
+        if (o == null) {
+            return false;
+        }
+
+        if (!(o instanceof MediaDescription)){
+            return false;
+        }
+
+        final MediaDescription d = (MediaDescription) o;
+
+        if (!String.valueOf(mTitle).equals(String.valueOf(d.mTitle))) {
+            return false;
+        }
+
+        if (!String.valueOf(mSubtitle).equals(String.valueOf(d.mSubtitle))) {
+            return false;
+        }
+
+        if (!String.valueOf(mDescription).equals(String.valueOf(d.mDescription))) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
     public String toString() {
         return mTitle + ", " + mSubtitle + ", " + mDescription;
     }
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 2f48ffb..ebc4071 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -267,7 +267,7 @@
         addFileType("PDF", FILE_TYPE_PDF, "application/pdf");
         addFileType("DOC", FILE_TYPE_MS_WORD, "application/msword", MtpConstants.FORMAT_MS_WORD_DOCUMENT, true);
         addFileType("XLS", FILE_TYPE_MS_EXCEL, "application/vnd.ms-excel", MtpConstants.FORMAT_MS_EXCEL_SPREADSHEET, true);
-        addFileType("PPT", FILE_TYPE_MS_POWERPOINT, "application/mspowerpoint", MtpConstants.FORMAT_MS_POWERPOINT_PRESENTATION, true);
+        addFileType("PPT", FILE_TYPE_MS_POWERPOINT, "application/vnd.ms-powerpoint", MtpConstants.FORMAT_MS_POWERPOINT_PRESENTATION, true);
         addFileType("FLAC", FILE_TYPE_FLAC, "audio/flac", MtpConstants.FORMAT_FLAC, true);
         addFileType("ZIP", FILE_TYPE_ZIP, "application/zip");
         addFileType("MPG", FILE_TYPE_MP2PS, "video/mp2p");
diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java
index dd731df..aae1f51 100644
--- a/media/java/android/media/MediaHTTPConnection.java
+++ b/media/java/android/media/MediaHTTPConnection.java
@@ -61,9 +61,9 @@
     private final static int MAX_REDIRECTS = 20;
 
     public MediaHTTPConnection() {
-        CookieManager cookieManager = (CookieManager)CookieHandler.getDefault();
-        if (cookieManager == null) {
-            Log.w(TAG, "MediaHTTPConnection: Unexpected. No CookieManager found.");
+        CookieHandler cookieHandler = CookieHandler.getDefault();
+        if (cookieHandler == null) {
+            Log.w(TAG, "MediaHTTPConnection: Unexpected. No CookieHandler found.");
         }
 
         native_setup();
diff --git a/media/java/android/media/MediaHTTPService.java b/media/java/android/media/MediaHTTPService.java
index b678630..3a0e58a 100644
--- a/media/java/android/media/MediaHTTPService.java
+++ b/media/java/android/media/MediaHTTPService.java
@@ -41,34 +41,40 @@
         synchronized (mCookieStoreInitialized) {
             // Only need to do it once for all connections
             if ( !mCookieStoreInitialized )  {
-                CookieManager cookieManager = (CookieManager)CookieHandler.getDefault();
-                if (cookieManager == null) {
-                    cookieManager = new CookieManager();
-                    CookieHandler.setDefault(cookieManager);
-                    Log.v(TAG, "makeHTTPConnection: CookieManager created: " + cookieManager);
-                }
-                else {
-                    Log.v(TAG, "makeHTTPConnection: CookieManager(" + cookieManager + ") exists.");
+                CookieHandler cookieHandler = CookieHandler.getDefault();
+                if (cookieHandler == null) {
+                    cookieHandler = new CookieManager();
+                    CookieHandler.setDefault(cookieHandler);
+                    Log.v(TAG, "makeHTTPConnection: CookieManager created: " + cookieHandler);
+                } else {
+                    Log.v(TAG, "makeHTTPConnection: CookieHandler (" + cookieHandler + ") exists.");
                 }
 
                 // Applying the bootstrapping cookies
                 if ( mCookies != null ) {
-                    CookieStore store = cookieManager.getCookieStore();
-                    for ( HttpCookie cookie : mCookies ) {
-                        try {
-                            store.add(null, cookie);
-                        } catch ( Exception e ) {
-                            Log.v(TAG, "makeHTTPConnection: CookieStore.add" + e);
+                    if ( cookieHandler instanceof CookieManager ) {
+                        CookieManager cookieManager = (CookieManager)cookieHandler;
+                        CookieStore store = cookieManager.getCookieStore();
+                        for ( HttpCookie cookie : mCookies ) {
+                            try {
+                                store.add(null, cookie);
+                            } catch ( Exception e ) {
+                                Log.v(TAG, "makeHTTPConnection: CookieStore.add" + e);
+                            }
+                            //for extended debugging when needed
+                            //Log.v(TAG, "MediaHTTPConnection adding Cookie[" + cookie.getName() +
+                            //        "]: " + cookie);
                         }
-                        //for extended debugging when needed
-                        //Log.v(TAG, "MediaHTTPConnection adding Cookie[" + cookie.getName() +
-                        //        "]: " + cookie);
+                    } else {
+                        Log.w(TAG, "makeHTTPConnection: The installed CookieHandler is not a "
+                                + "CookieManager. Can’t add the provided cookies to the cookie "
+                                + "store.");
                     }
                 }   // mCookies
 
                 mCookieStoreInitialized = true;
 
-                Log.v(TAG, "makeHTTPConnection(" + this + "): cookieManager: " + cookieManager +
+                Log.v(TAG, "makeHTTPConnection(" + this + "): cookieHandler: " + cookieHandler +
                         " Cookies: " + mCookies);
             }   // mCookieStoreInitialized
         }   // synchronized
@@ -92,5 +98,4 @@
 
         return null;
     }
-
 }
diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java
index bdc0fda..31eb948 100644
--- a/media/java/android/media/MediaMetadata.java
+++ b/media/java/android/media/MediaMetadata.java
@@ -34,6 +34,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Set;
+import java.util.Objects;
 
 /**
  * Contains metadata about an item, such as the title, artist, etc.
@@ -616,6 +617,71 @@
             };
 
     /**
+     * Compares the contents of this object to another MediaMetadata object. It
+     * does not compare Bitmaps and Ratings as the media player can choose to
+     * forgo these fields depending on how you retrieve the MediaMetadata.
+     *
+     * @param o The Metadata object to compare this object against
+     * @return Whether or not the two objects have matching fields (excluding
+     * Bitmaps and Ratings)
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        if (!(o instanceof MediaMetadata)) {
+            return false;
+        }
+
+        final MediaMetadata m = (MediaMetadata) o;
+
+        for (int i = 0; i < METADATA_KEYS_TYPE.size(); i++) {
+            String key = METADATA_KEYS_TYPE.keyAt(i);
+            switch (METADATA_KEYS_TYPE.valueAt(i)) {
+                case METADATA_TYPE_TEXT:
+                    if (!Objects.equals(getString(key), m.getString(key))) {
+                        return false;
+                    }
+                    break;
+                case METADATA_TYPE_LONG:
+                    if (getLong(key) != m.getLong(key)) {
+                        return false;
+                    }
+                    break;
+                default:
+                    // Ignore ratings and bitmaps when comparing
+                    break;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hashCode = 17;
+
+        for (int i = 0; i < METADATA_KEYS_TYPE.size(); i++) {
+            String key = METADATA_KEYS_TYPE.keyAt(i);
+            switch (METADATA_KEYS_TYPE.valueAt(i)) {
+                case METADATA_TYPE_TEXT:
+                    hashCode = 31 * hashCode + Objects.hash(getString(key));
+                    break;
+                case METADATA_TYPE_LONG:
+                    hashCode = 31 * hashCode + Long.hashCode(getLong(key));
+                    break;
+                default:
+                    // Ignore ratings and bitmaps when comparing
+                    break;
+            }
+        }
+
+        return hashCode;
+    }
+
+    /**
      * Use to build MediaMetadata objects. The system defined metadata keys must
      * use the appropriate data type.
      */
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 5cbccea..d48c7a6 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -39,6 +39,7 @@
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.system.ErrnoException;
+import android.system.Os;
 import android.system.OsConstants;
 import android.util.Log;
 import android.util.Pair;
@@ -60,7 +61,6 @@
 import com.android.internal.util.Preconditions;
 
 import libcore.io.IoBridge;
-import libcore.io.Libcore;
 import libcore.io.Streams;
 
 import java.io.ByteArrayOutputStream;
@@ -73,6 +73,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
+import java.net.CookieHandler;
+import java.net.CookieManager;
 import java.net.HttpCookie;
 import java.net.HttpURLConnection;
 import java.net.InetSocketAddress;
@@ -1004,19 +1006,28 @@
     /**
      * Sets the data source as a content Uri.
      *
-     * @param context the Context to use when resolving the Uri
-     * @param uri the Content URI of the data you want to play
-     * @param headers the headers to be sent together with the request for the data
-     *                The headers must not include cookies. Instead, use the cookies param.
-     * @param cookies the cookies to be sent together with the request
-     * @throws IllegalStateException if it is called in an invalid state
-     * @throws NullPointerException  if context or uri is null
-     * @throws IOException           if uri has a file scheme and an I/O error occurs
+     * To provide cookies for the subsequent HTTP requests, you can install your own default cookie
+     * handler and use other variants of setDataSource APIs instead. Alternatively, you can use
+     * this API to pass the cookies as a list of HttpCookie. If the app has not installed
+     * a CookieHandler already, this API creates a CookieManager and populates its CookieStore with
+     * the provided cookies. If the app has installed its own handler already, this API requires the
+     * handler to be of CookieManager type such that the API can update the manager’s CookieStore.
      *
      * <p><strong>Note</strong> that the cross domain redirection is allowed by default,
      * but that can be changed with key/value pairs through the headers parameter with
      * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to
      * disallow or allow cross domain redirection.
+     *
+     * @param context the Context to use when resolving the Uri
+     * @param uri the Content URI of the data you want to play
+     * @param headers the headers to be sent together with the request for the data
+     *                The headers must not include cookies. Instead, use the cookies param.
+     * @param cookies the cookies to be sent together with the request
+     * @throws IllegalArgumentException if cookies are provided and the installed handler is not
+     *                                  a CookieManager
+     * @throws IllegalStateException    if it is called in an invalid state
+     * @throws NullPointerException     if context or uri is null
+     * @throws IOException              if uri has a file scheme and an I/O error occurs
      */
     public void setDataSource(@NonNull Context context, @NonNull Uri uri,
             @Nullable Map<String, String> headers, @Nullable List<HttpCookie> cookies)
@@ -1029,6 +1040,14 @@
             throw new NullPointerException("uri param can not be null.");
         }
 
+        if (cookies != null) {
+            CookieHandler cookieHandler = CookieHandler.getDefault();
+            if (cookieHandler != null && !(cookieHandler instanceof CookieManager)) {
+                throw new IllegalArgumentException("The cookie handler has to be of CookieManager "
+                        + "type when cookies are provided.");
+            }
+        }
+
         // The context and URI usually belong to the calling user. Get a resolver for that user
         // and strip out the userId from the URI if present.
         final ContentResolver resolver = context.getContentResolver();
@@ -1064,15 +1083,15 @@
     /**
      * Sets the data source as a content Uri.
      *
-     * @param context the Context to use when resolving the Uri
-     * @param uri the Content URI of the data you want to play
-     * @param headers the headers to be sent together with the request for the data
-     * @throws IllegalStateException if it is called in an invalid state
-     *
      * <p><strong>Note</strong> that the cross domain redirection is allowed by default,
      * but that can be changed with key/value pairs through the headers parameter with
      * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to
      * disallow or allow cross domain redirection.
+     *
+     * @param context the Context to use when resolving the Uri
+     * @param uri the Content URI of the data you want to play
+     * @param headers the headers to be sent together with the request for the data
+     * @throws IllegalStateException if it is called in an invalid state
      */
     public void setDataSource(@NonNull Context context, @NonNull Uri uri,
             @Nullable Map<String, String> headers)
@@ -1093,15 +1112,15 @@
     /**
      * Sets the data source (file-path or http/rtsp URL) to use.
      *
-     * @param path the path of the file, or the http/rtsp URL of the stream you want to play
-     * @throws IllegalStateException if it is called in an invalid state
-     *
      * <p>When <code>path</code> refers to a local file, the file may actually be opened by a
      * process other than the calling application.  This implies that the pathname
      * should be an absolute path (as any other process runs with unspecified current working
      * directory), and that the pathname should reference a world-readable file.
      * As an alternative, the application could first open the file for reading,
      * and then use the file descriptor form {@link #setDataSource(FileDescriptor)}.
+     *
+     * @param path the path of the file, or the http/rtsp URL of the stream you want to play
+     * @throws IllegalStateException if it is called in an invalid state
      */
     public void setDataSource(String path)
             throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
@@ -1332,7 +1351,7 @@
     private native int _getAudioStreamType() throws IllegalStateException;
 
     /**
-     * Stops playback after playback has been stopped or paused.
+     * Stops playback after playback has been started or paused.
      *
      * @throws IllegalStateException if the internal player engine has not been
      * initialized.
@@ -2810,7 +2829,7 @@
 
         final FileDescriptor dupedFd;
         try {
-            dupedFd = Libcore.os.dup(fd);
+            dupedFd = Os.dup(fd);
         } catch (ErrnoException ex) {
             Log.e(TAG, ex.getMessage(), ex);
             throw new RuntimeException(ex);
@@ -2848,7 +2867,7 @@
             private int addTrack() {
                 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
                 try {
-                    Libcore.os.lseek(dupedFd, offset2, OsConstants.SEEK_SET);
+                    Os.lseek(dupedFd, offset2, OsConstants.SEEK_SET);
                     byte[] buffer = new byte[4096];
                     for (long total = 0; total < length2;) {
                         int bytesToRead = (int) Math.min(buffer.length, length2 - total);
@@ -2872,7 +2891,7 @@
                     return MEDIA_INFO_TIMED_TEXT_ERROR;
                 } finally {
                     try {
-                        Libcore.os.close(dupedFd);
+                        Os.close(dupedFd);
                     } catch (ErrnoException e) {
                         Log.e(TAG, e.getMessage(), e);
                     }
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 91dada7..80a0315 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -88,6 +88,7 @@
         RouteInfo mBluetoothA2dpRoute;
 
         RouteInfo mSelectedRoute;
+        RouteInfo mSystemAudioRoute;
 
         final boolean mCanConfigureWifiDisplays;
         boolean mActivelyScanningWifiDisplays;
@@ -149,6 +150,7 @@
             }
 
             addRouteStatic(mDefaultAudioVideo);
+            mSystemAudioRoute = mDefaultAudioVideo;
 
             // This will select the active wifi display route if there is one.
             updateWifiDisplayStatus(mDisplayService.getWifiDisplayStatus());
@@ -197,8 +199,8 @@
                 } else {
                     name = com.android.internal.R.string.default_audio_route_name;
                 }
-                sStatic.mDefaultAudioVideo.mNameResId = name;
-                dispatchRouteChanged(sStatic.mDefaultAudioVideo);
+                mDefaultAudioVideo.mNameResId = name;
+                dispatchRouteChanged(mDefaultAudioVideo);
                 updated = true;
             }
 
@@ -207,22 +209,28 @@
             if (!TextUtils.equals(newRoutes.bluetoothName, mCurAudioRoutesInfo.bluetoothName)) {
                 mCurAudioRoutesInfo.bluetoothName = newRoutes.bluetoothName;
                 if (mCurAudioRoutesInfo.bluetoothName != null) {
-                    if (sStatic.mBluetoothA2dpRoute == null) {
-                        final RouteInfo info = new RouteInfo(sStatic.mSystemCategory);
+                    if (mBluetoothA2dpRoute == null) {
+                        // BT connected
+                        final RouteInfo info = new RouteInfo(mSystemCategory);
                         info.mName = mCurAudioRoutesInfo.bluetoothName;
-                        info.mDescription = sStatic.mResources.getText(
+                        info.mDescription = mResources.getText(
                                 com.android.internal.R.string.bluetooth_a2dp_audio_route_name);
                         info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
                         info.mDeviceType = RouteInfo.DEVICE_TYPE_BLUETOOTH;
-                        sStatic.mBluetoothA2dpRoute = info;
-                        addRouteStatic(sStatic.mBluetoothA2dpRoute);
+                        mBluetoothA2dpRoute = info;
+                        addRouteStatic(mBluetoothA2dpRoute);
+                        mSystemAudioRoute = mBluetoothA2dpRoute;
+                        selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mSystemAudioRoute, false);
                     } else {
-                        sStatic.mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.bluetoothName;
-                        dispatchRouteChanged(sStatic.mBluetoothA2dpRoute);
+                        mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.bluetoothName;
+                        dispatchRouteChanged(mBluetoothA2dpRoute);
                     }
-                } else if (sStatic.mBluetoothA2dpRoute != null) {
-                    removeRouteStatic(sStatic.mBluetoothA2dpRoute);
-                    sStatic.mBluetoothA2dpRoute = null;
+                } else if (mBluetoothA2dpRoute != null) {
+                    // BT disconnected
+                    removeRouteStatic(mBluetoothA2dpRoute);
+                    mBluetoothA2dpRoute = null;
+                    mSystemAudioRoute = mDefaultAudioVideo;
+                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mSystemAudioRoute, false);
                 }
                 updated = true;
             }
@@ -230,11 +238,13 @@
             if (mBluetoothA2dpRoute != null) {
                 final boolean a2dpEnabled = isBluetoothA2dpOn();
                 if (mSelectedRoute == mBluetoothA2dpRoute && !a2dpEnabled) {
-                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo, false);
+                    // A2DP off
+                    mSystemAudioRoute = mDefaultAudioVideo;
                     updated = true;
                 } else if ((mSelectedRoute == mDefaultAudioVideo || mSelectedRoute == null) &&
                         a2dpEnabled) {
-                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute, false);
+                    // A2DP on or BT connected
+                    mSystemAudioRoute = mBluetoothA2dpRoute;
                     updated = true;
                 }
             }
@@ -417,8 +427,6 @@
             }
             final ArrayList<MediaRouterClientState.RouteInfo> globalRoutes =
                     mClientState != null ? mClientState.routes : null;
-            final String globallySelectedRouteId = mClientState != null ?
-                    mClientState.globallySelectedRouteId : null;
 
             // Add or update routes.
             final int globalRouteCount = globalRoutes != null ? globalRoutes.size() : 0;
@@ -433,25 +441,6 @@
                 }
             }
 
-            // Synchronize state with the globally selected route.
-            if (globallySelectedRouteId != null) {
-                final RouteInfo route = findGlobalRoute(globallySelectedRouteId);
-                if (route == null) {
-                    Log.w(TAG, "Could not find new globally selected route: "
-                            + globallySelectedRouteId);
-                } else if (route != mSelectedRoute) {
-                    if (DEBUG) {
-                        Log.d(TAG, "Selecting new globally selected route: " + route);
-                    }
-                    selectRouteStatic(route.mSupportedTypes, route, false);
-                }
-            } else if (mSelectedRoute != null && mSelectedRoute.mGlobalRouteId != null) {
-                if (DEBUG) {
-                    Log.d(TAG, "Unselecting previous globally selected route: " + mSelectedRoute);
-                }
-                selectDefaultRouteStatic();
-            }
-
             // Remove defunct routes.
             outer: for (int i = mRoutes.size(); i-- > 0; ) {
                 final RouteInfo route = mRoutes.get(i);
@@ -492,7 +481,7 @@
         }
 
         RouteInfo makeGlobalRoute(MediaRouterClientState.RouteInfo globalRoute) {
-            RouteInfo route = new RouteInfo(sStatic.mSystemCategory);
+            RouteInfo route = new RouteInfo(mSystemCategory);
             route.mGlobalRouteId = globalRoute.id;
             route.mName = globalRoute.name;
             route.mDescription = globalRoute.description;
@@ -588,6 +577,17 @@
             return null;
         }
 
+        boolean isPlaybackActive() {
+            if (mClient != null) {
+                try {
+                    return mMediaRouterService.isPlaybackActive(mClient);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to retrieve playback active state.", ex);
+                }
+            }
+            return false;
+        }
+
         final class Client extends IMediaRouterClient.Stub {
             @Override
             public void onStateChanged() {
@@ -600,6 +600,19 @@
                     }
                 });
             }
+
+            @Override
+            public void onRestoreRoute() {
+                if ((mSelectedRoute != mDefaultAudioVideo && mSelectedRoute != mBluetoothA2dpRoute)
+                        || mSelectedRoute == mSystemAudioRoute) {
+                    return;
+                }
+                try {
+                    sStatic.mAudioService.setBluetoothA2dpOn(mSelectedRoute == mBluetoothA2dpRoute);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error changing Bluetooth A2DP state", e);
+                }
+            }
         }
     }
 
@@ -753,6 +766,15 @@
     }
 
     /**
+     * Returns a Bluetooth route if available, otherwise the default route.
+     * @hide
+     */
+    public RouteInfo getFallbackRoute() {
+        return (sStatic.mBluetoothA2dpRoute != null)
+                ? sStatic.mBluetoothA2dpRoute : sStatic.mDefaultAudioVideo;
+    }
+
+    /**
      * @hide for use by framework routing UI
      */
     public RouteCategory getSystemCategory() {
@@ -921,7 +943,12 @@
         Log.v(TAG, "Selecting route: " + route);
         assert(route != null);
         final RouteInfo oldRoute = sStatic.mSelectedRoute;
-        if (oldRoute == route) return;
+        boolean wasDefaultOrBluetoothRoute = (oldRoute == sStatic.mDefaultAudioVideo
+                || oldRoute == sStatic.mBluetoothA2dpRoute);
+        if (oldRoute == route
+                && (!wasDefaultOrBluetoothRoute || oldRoute == sStatic.mSystemAudioRoute)) {
+            return;
+        }
         if (!route.matchesTypes(types)) {
             Log.w(TAG, "selectRoute ignored; cannot select route with supported types " +
                     typesToString(route.getSupportedTypes()) + " into route types " +
@@ -930,10 +957,23 @@
         }
 
         final RouteInfo btRoute = sStatic.mBluetoothA2dpRoute;
-        if (btRoute != null && (types & ROUTE_TYPE_LIVE_AUDIO) != 0 &&
-                (route == btRoute || route == sStatic.mDefaultAudioVideo)) {
+        if (sStatic.isPlaybackActive() && btRoute != null && (types & ROUTE_TYPE_LIVE_AUDIO) != 0
+                && (route == btRoute || route == sStatic.mDefaultAudioVideo)) {
             try {
                 sStatic.mAudioService.setBluetoothA2dpOn(route == btRoute);
+                // TODO: Remove the following logging when no longer needed.
+                if (route != btRoute) {
+                    StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+                    StringBuffer sb = new StringBuffer();
+                    // callStack[3] is the caller of this method.
+                    for (int i = 3; i < callStack.length; i++) {
+                        StackTraceElement caller = callStack[i];
+                        sb.append(caller.getClassName() + "." + caller.getMethodName()
+                                + ":" + caller.getLineNumber()).append("  ");
+                    }
+                    Log.w(TAG, "Default route is selected while a BT route is available: pkgName="
+                            + sStatic.mPackageName + ", callers=" + sb.toString());
+                }
             } catch (RemoteException e) {
                 Log.e(TAG, "Error changing Bluetooth A2DP state", e);
             }
@@ -2020,6 +2060,11 @@
         }
 
         /** @hide */
+        public boolean isBluetooth() {
+            return this == sStatic.mBluetoothA2dpRoute;
+        }
+
+        /** @hide */
         public void select() {
             selectRouteStatic(mSupportedTypes, this, true);
         }
diff --git a/media/java/android/media/MediaRouterClientState.java b/media/java/android/media/MediaRouterClientState.java
index 34e18f6..7643924 100644
--- a/media/java/android/media/MediaRouterClientState.java
+++ b/media/java/android/media/MediaRouterClientState.java
@@ -34,20 +34,12 @@
      */
     public final ArrayList<RouteInfo> routes;
 
-    /**
-     * The id of the current globally selected route, or null if none.
-     * Globally selected routes override any other route selections that applications
-     * may have made.  Used for remote displays.
-     */
-    public String globallySelectedRouteId;
-
     public MediaRouterClientState() {
         routes = new ArrayList<RouteInfo>();
     }
 
     MediaRouterClientState(Parcel src) {
         routes = src.createTypedArrayList(RouteInfo.CREATOR);
-        globallySelectedRouteId = src.readString();
     }
 
     public RouteInfo getRoute(String id) {
@@ -69,13 +61,11 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeTypedList(routes);
-        dest.writeString(globallySelectedRouteId);
     }
 
     @Override
     public String toString() {
-        return "MediaRouterClientState{ globallySelectedRouteId="
-                + globallySelectedRouteId + ", routes=" + routes.toString() + " }";
+        return "MediaRouterClientState{ routes=" + routes.toString() + " }";
     }
 
     public static final Parcelable.Creator<MediaRouterClientState> CREATOR =
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index ddfa025..cb4e46f 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1958,7 +1958,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index dbbbfc6..26e65dd 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -57,10 +57,10 @@
  * SoundPool will automatically stop a previously playing stream based first
  * on priority and then by age within that priority. Limiting the maximum
  * number of streams helps to cap CPU loading and reducing the likelihood that
- * audio mixing will impact visuals or UI performance.</p> 
+ * audio mixing will impact visuals or UI performance.</p>
  *
  * <p>Sounds can be looped by setting a non-zero loop value. A value of -1
- * causes the sound to loop forever. In this case, the application must 
+ * causes the sound to loop forever. In this case, the application must
  * explicitly call the stop() function to stop the sound. Any other non-zero
  * value will cause the sound to repeat the specified number of times, e.g.
  * a value of 3 causes the sound to play a total of 4 times.</p>
@@ -101,7 +101,7 @@
  * <p>Note that since streams can be stopped due to resource constraints, the
  * streamID is a reference to a particular instance of a stream. If the stream
  * is stopped to allow a higher priority stream to play, the stream is no
- * longer be valid. However, the application is allowed to call methods on
+ * longer valid. However, the application is allowed to call methods on
  * the streamID without error. This may help simplify program logic since
  * the application need not concern itself with the stream lifecycle.</p>
  *
@@ -137,7 +137,7 @@
      *
      * @param maxStreams the maximum number of simultaneous streams for this
      *                   SoundPool object
-     * @param streamType the audio stream type as described in AudioManager 
+     * @param streamType the audio stream type as described in AudioManager
      *                   For example, game applications will normally use
      *                   {@link AudioManager#STREAM_MUSIC}.
      * @param srcQuality the sample-rate converter quality. Currently has no
@@ -213,7 +213,7 @@
      * "R.raw.explosion" as the resource ID. Note that this means you cannot
      * have both an "explosion.wav" and an "explosion.mp3" in the res/raw
      * directory.
-     * 
+     *
      * @param context the application context
      * @param resId the resource ID
      * @param priority the priority of the sound. Currently has no effect. Use
@@ -287,7 +287,7 @@
     /**
      * Play a sound from a sound ID.
      *
-     * Play the sound specified by the soundID. This is the value 
+     * Play the sound specified by the soundID. This is the value
      * returned by the load() function. Returns a non-zero streamID
      * if successful, zero if it fails. The streamID can be used to
      * further control playback. Note that calling play() may cause
@@ -509,7 +509,7 @@
         }
     }
 
-    private native final int _load(FileDescriptor fd, long offset, long length, int priority); 
+    private native final int _load(FileDescriptor fd, long offset, long length, int priority);
 
     private native final int native_setup(Object weakRef, int maxStreams,
             Object/*AudioAttributes*/ attributes);
diff --git a/media/java/android/media/midi/IMidiDeviceServer.aidl b/media/java/android/media/midi/IMidiDeviceServer.aidl
index fbd3510..59f0f23 100644
--- a/media/java/android/media/midi/IMidiDeviceServer.aidl
+++ b/media/java/android/media/midi/IMidiDeviceServer.aidl
@@ -24,12 +24,14 @@
     FileDescriptor openInputPort(IBinder token, int portNumber);
     FileDescriptor openOutputPort(IBinder token, int portNumber);
     void closePort(IBinder token);
-    void closeDevice();
+    oneway void closeDevice();
 
     // connects the input port pfd to the specified output port
     // Returns the PID of the called process.
     int connectPorts(IBinder token, in FileDescriptor fd, int outputPortNumber);
 
     MidiDeviceInfo getDeviceInfo();
-    void setDeviceInfo(in MidiDeviceInfo deviceInfo);
+
+    // For use by MidiService.
+    oneway void setDeviceInfo(in MidiDeviceInfo deviceInfo);
 }
diff --git a/media/java/android/media/midi/MidiDevice.java b/media/java/android/media/midi/MidiDevice.java
index f7dd0b3..a995736 100644
--- a/media/java/android/media/midi/MidiDevice.java
+++ b/media/java/android/media/midi/MidiDevice.java
@@ -103,7 +103,10 @@
         @Override
         protected void finalize() throws Throwable {
             try {
-                mGuard.warnIfOpen();
+                if (mGuard != null) {
+                    mGuard.warnIfOpen();
+                }
+
                 close();
             } finally {
                 super.finalize();
@@ -285,7 +288,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mGuard.warnIfOpen();
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/media/java/android/media/midi/MidiDeviceServer.java b/media/java/android/media/midi/MidiDeviceServer.java
index eaa8654..51d5520 100644
--- a/media/java/android/media/midi/MidiDeviceServer.java
+++ b/media/java/android/media/midi/MidiDeviceServer.java
@@ -429,7 +429,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mGuard.warnIfOpen();
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/media/java/android/media/midi/MidiInputPort.java b/media/java/android/media/midi/MidiInputPort.java
index 98ec779..a300886 100644
--- a/media/java/android/media/midi/MidiInputPort.java
+++ b/media/java/android/media/midi/MidiInputPort.java
@@ -159,7 +159,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mGuard.warnIfOpen();
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+            }
+
             // not safe to make binder calls from finalize()
             mDeviceServer = null;
             close();
diff --git a/media/java/android/media/midi/MidiOutputPort.java b/media/java/android/media/midi/MidiOutputPort.java
index ce0402c..511f6cd 100644
--- a/media/java/android/media/midi/MidiOutputPort.java
+++ b/media/java/android/media/midi/MidiOutputPort.java
@@ -145,7 +145,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mGuard.warnIfOpen();
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+            }
+
             // not safe to make binder calls from finalize()
             mDeviceServer = null;
             close();
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index dfd2bb3..1291dfb 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -43,11 +43,13 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.ViewConfiguration;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Allows interaction with media controllers, volume keys, media buttons, and
@@ -200,8 +202,7 @@
                 return;
             }
             if (mCallback != null) {
-                // We're updating the callback, clear the session from the old
-                // one.
+                // We're updating the callback, clear the session from the old one.
                 mCallback.mCallback.mSession = null;
             }
             if (handler == null) {
@@ -735,6 +736,8 @@
      */
     public abstract static class Callback {
         private MediaSession mSession;
+        private CallbackMessageHandler mHandler;
+        private boolean mMediaPlayPauseKeyPending;
 
         public Callback() {
         }
@@ -766,13 +769,41 @@
          * @return True if the event was handled, false otherwise.
          */
         public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) {
-            if (mSession != null
+            if (mSession != null && mHandler != null
                     && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) {
                 KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
                 if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) {
                     PlaybackState state = mSession.mPlaybackState;
                     long validActions = state == null ? 0 : state.getActions();
                     switch (ke.getKeyCode()) {
+                        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+                        case KeyEvent.KEYCODE_HEADSETHOOK:
+                            if (ke.getRepeatCount() > 0) {
+                                // Consider long-press as a single tap.
+                                handleMediaPlayPauseKeySingleTapIfPending();
+                            } else if (mMediaPlayPauseKeyPending) {
+                                // Consider double tap as the next.
+                                mHandler.removeMessages(CallbackMessageHandler
+                                        .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT);
+                                mMediaPlayPauseKeyPending = false;
+                                if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) {
+                                    onSkipToNext();
+                                }
+                            } else {
+                                mMediaPlayPauseKeyPending = true;
+                                mHandler.sendEmptyMessageDelayed(CallbackMessageHandler
+                                        .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT,
+                                        ViewConfiguration.getDoubleTapTimeout());
+                            }
+                            return true;
+                        default:
+                            // If another key is pressed within double tap timeout, consider the
+                            // pending play/pause as a single tap to handle media keys in order.
+                            handleMediaPlayPauseKeySingleTapIfPending();
+                            break;
+                    }
+
+                    switch (ke.getKeyCode()) {
                         case KeyEvent.KEYCODE_MEDIA_PLAY:
                             if ((validActions & PlaybackState.ACTION_PLAY) != 0) {
                                 onPlay();
@@ -815,28 +846,33 @@
                                 return true;
                             }
                             break;
-                        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
-                        case KeyEvent.KEYCODE_HEADSETHOOK:
-                            boolean isPlaying = state == null ? false
-                                    : state.getState() == PlaybackState.STATE_PLAYING;
-                            boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
-                                    | PlaybackState.ACTION_PLAY)) != 0;
-                            boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
-                                    | PlaybackState.ACTION_PAUSE)) != 0;
-                            if (isPlaying && canPause) {
-                                onPause();
-                                return true;
-                            } else if (!isPlaying && canPlay) {
-                                onPlay();
-                                return true;
-                            }
-                            break;
                     }
                 }
             }
             return false;
         }
 
+        private void handleMediaPlayPauseKeySingleTapIfPending() {
+            if (!mMediaPlayPauseKeyPending) {
+                return;
+            }
+            mMediaPlayPauseKeyPending = false;
+            mHandler.removeMessages(CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT);
+            PlaybackState state = mSession.mPlaybackState;
+            long validActions = state == null ? 0 : state.getActions();
+            boolean isPlaying = state != null
+                    && state.getState() == PlaybackState.STATE_PLAYING;
+            boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
+                        | PlaybackState.ACTION_PLAY)) != 0;
+            boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
+                        | PlaybackState.ACTION_PAUSE)) != 0;
+            if (isPlaying && canPause) {
+                onPause();
+            } else if (!isPlaying && canPlay) {
+                onPlay();
+            }
+        }
+
         /**
          * Override to handle requests to prepare playback. During the preparation, a session should
          * not hold audio focus in order to allow other sessions play seamlessly. The state of
@@ -1256,6 +1292,28 @@
                     "Description=" + mDescription +
                     ", Id=" + mId + " }";
         }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == null) {
+                return false;
+            }
+
+            if (!(o instanceof QueueItem)) {
+                return false;
+            }
+
+            final QueueItem item = (QueueItem) o;
+            if (mId != item.mId) {
+                return false;
+            }
+
+            if (!Objects.equals(mDescription, item.mDescription)) {
+                return false;
+            }
+
+            return true;
+        }
     }
 
     private static final class Command {
@@ -1294,12 +1352,14 @@
         private static final int MSG_CUSTOM_ACTION = 20;
         private static final int MSG_ADJUST_VOLUME = 21;
         private static final int MSG_SET_VOLUME = 22;
+        private static final int MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT = 23;
 
         private MediaSession.Callback mCallback;
 
         public CallbackMessageHandler(Looper looper, MediaSession.Callback callback) {
             super(looper, null, true);
             mCallback = callback;
+            mCallback.mHandler = this;
         }
 
         public void post(int what, Object obj, Bundle bundle) {
@@ -1401,6 +1461,9 @@
                         vp.onSetVolumeTo((int) msg.obj);
                     }
                     break;
+                case MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT:
+                    mCallback.handleMediaPlayPauseKeySingleTapIfPending();
+                    break;
             }
         }
     }
diff --git a/media/java/android/media/soundtrigger/SoundTriggerDetector.java b/media/java/android/media/soundtrigger/SoundTriggerDetector.java
index a48abff..7969ee7 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerDetector.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerDetector.java
@@ -138,7 +138,7 @@
         }
 
         /**
-         * Gets the raw audio that triggered the keyphrase.
+         * Gets the raw audio that triggered the detector.
          * This may be null if the trigger audio isn't available.
          * If non-null, the format of the audio can be obtained by calling
          * {@link #getCaptureAudioFormat()}.
@@ -155,6 +155,24 @@
         }
 
         /**
+         * Gets the opaque data passed from the detection engine for the event.
+         * This may be null if it was not populated by the engine, or if the data is known to
+         * contain the trigger audio.
+         *
+         * @see #getTriggerAudio
+         *
+         * @hide
+         */
+        @Nullable
+        public byte[] getData() {
+            if (!mTriggerAvailable) {
+                return mData;
+            } else {
+                return null;
+            }
+        }
+
+        /**
          * Gets the session ID to start a capture from the DSP.
          * This may be null if streaming capture isn't possible.
          * If non-null, the format of the audio that can be captured can be
diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java
index 7f8140a..92ffae0 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerManager.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerManager.java
@@ -15,7 +15,9 @@
  */
 
 package android.media.soundtrigger;
+import static android.hardware.soundtrigger.SoundTrigger.STATUS_ERROR;
 
+import android.app.PendingIntent;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
@@ -23,6 +25,10 @@
 import android.annotation.SystemService;
 import android.content.Context;
 import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.SoundModel;
+import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
 import android.os.Handler;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
@@ -178,4 +184,144 @@
             return mGenericSoundModel;
         }
     }
+
+
+    /**
+     * Default message type.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_UNKNOWN = -1;
+    /**
+     * Contents of EXTRA_MESSAGE_TYPE extra for a RecognitionEvent.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_RECOGNITION_EVENT = 0;
+    /**
+     * Contents of EXTRA_MESSAGE_TYPE extra for recognition error events.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_RECOGNITION_ERROR = 1;
+    /**
+     * Contents of EXTRA_MESSAGE_TYPE extra for a recognition paused events.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_RECOGNITION_PAUSED = 2;
+    /**
+     * Contents of EXTRA_MESSAGE_TYPE extra for recognition resumed events.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_RECOGNITION_RESUMED = 3;
+
+    /**
+     * Extra key in the intent for the type of the message.
+     * @hide
+     */
+    public static final String EXTRA_MESSAGE_TYPE = "android.media.soundtrigger.MESSAGE_TYPE";
+    /**
+     * Extra key in the intent that holds the RecognitionEvent parcelable.
+     * @hide
+     */
+    public static final String EXTRA_RECOGNITION_EVENT = "android.media.soundtrigger.RECOGNITION_EVENT";
+    /**
+     * Extra key in the intent that holds the status in an error message.
+     * @hide
+     */
+    public static final String EXTRA_STATUS = "android.media.soundtrigger.STATUS";
+
+    /**
+     * Loads a given sound model into the sound trigger. Note the model will be unloaded if there is
+     * an error/the system service is restarted.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public int loadSoundModel(SoundModel soundModel) {
+        if (soundModel == null) {
+            return STATUS_ERROR;
+        }
+
+        try {
+            switch (soundModel.type) {
+                case SoundModel.TYPE_GENERIC_SOUND:
+                    return mSoundTriggerService.loadGenericSoundModel(
+                            (GenericSoundModel) soundModel);
+                case SoundModel.TYPE_KEYPHRASE:
+                    return mSoundTriggerService.loadKeyphraseSoundModel(
+                            (KeyphraseSoundModel) soundModel);
+                default:
+                    Slog.e(TAG, "Unkown model type");
+                    return STATUS_ERROR;
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Starts recognition on the given model id. All events from the model will be sent to the
+     * PendingIntent.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public int startRecognition(UUID soundModelId, PendingIntent callbackIntent,
+            RecognitionConfig config) {
+        if (soundModelId == null || callbackIntent == null || config == null) {
+            return STATUS_ERROR;
+        }
+        try {
+            return mSoundTriggerService.startRecognitionForIntent(new ParcelUuid(soundModelId),
+                    callbackIntent, config);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Stops the given model's recognition.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public int stopRecognition(UUID soundModelId) {
+        if (soundModelId == null) {
+            return STATUS_ERROR;
+        }
+        try {
+            return mSoundTriggerService.stopRecognitionForIntent(new ParcelUuid(soundModelId));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Removes the given model from memory. Will also stop any pending recognitions.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public int unloadSoundModel(UUID soundModelId) {
+        if (soundModelId == null) {
+            return STATUS_ERROR;
+        }
+        try {
+            return mSoundTriggerService.unloadSoundModel(
+                    new ParcelUuid(soundModelId));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns true if the given model has had detection started on it.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public boolean isRecognitionActive(UUID soundModelId) {
+        if (soundModelId == null) {
+            return false;
+        }
+        try {
+            return mSoundTriggerService.isRecognitionActive(
+                    new ParcelUuid(soundModelId));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 07cfbda..df87e0f 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -367,7 +367,7 @@
         }
 
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             if (mTvInputSessionImpl == null) {
                 // The session has been finished.
                 finishInputEvent(event, false);
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index e7da20b..102e02d 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -601,10 +601,12 @@
      * given time frame.
      *
      * @param channelId The ID of the channel to return programs for.
-     * @param startTime The start time used to filter programs. The returned programs should have
-     *            {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time.
-     * @param endTime The end time used to filter programs. The returned programs should have
-     *            {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
+     * @param startTime The start time used to filter programs. The returned programs will have a
+     *            {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than or equal to
+                  {@code startTime}.
+     * @param endTime The end time used to filter programs. The returned programs will have
+     *            {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than or equal to
+     *            {@code endTime}.
      */
     public static Uri buildProgramsUriForChannel(long channelId, long startTime,
             long endTime) {
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 7b5f778..e24124d 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -974,7 +974,7 @@
          * seek to a position earlier than the start position.
          *
          * <p>For playback of a recorded program initiated by {@link #onTimeShiftPlay(Uri)}, the
-         * start position is the time when playback starts. It does not change.
+         * start position should be 0 and does not change.
          *
          * @see #onTimeShiftPlay(Uri)
          * @see #onTimeShiftResume()
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 56a5737..adcd79b 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -233,7 +233,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
@@ -466,10 +469,14 @@
                     if (parent == 0xFFFFFFFF) {
                         // all objects in root of store
                         parent = 0;
+                        where = STORAGE_PARENT_WHERE;
+                        whereArgs = new String[]{Integer.toString(storageID),
+                                Integer.toString(parent)};
+                    }  else {
+                        // If a parent is specified, the storage is redundant
+                        where = PARENT_WHERE;
+                        whereArgs = new String[]{Integer.toString(parent)};
                     }
-                    where = STORAGE_PARENT_WHERE;
-                    whereArgs = new String[] { Integer.toString(storageID),
-                                               Integer.toString(parent) };
                 }
             } else {
                 // query specific format
@@ -482,11 +489,16 @@
                     if (parent == 0xFFFFFFFF) {
                         // all objects in root of store
                         parent = 0;
+                        where = STORAGE_FORMAT_PARENT_WHERE;
+                        whereArgs = new String[]{Integer.toString(storageID),
+                                Integer.toString(format),
+                                Integer.toString(parent)};
+                    } else {
+                        // If a parent is specified, the storage is redundant
+                        where = FORMAT_PARENT_WHERE;
+                        whereArgs = new String[]{Integer.toString(format),
+                                Integer.toString(parent)};
                     }
-                    where = STORAGE_FORMAT_PARENT_WHERE;
-                    whereArgs = new String[] { Integer.toString(storageID),
-                                               Integer.toString(format),
-                                               Integer.toString(parent) };
                 }
             }
         }
@@ -838,6 +850,34 @@
         return MtpConstants.RESPONSE_OK;
     }
 
+    private int moveObject(int handle, int newParent, int newStorage, String newPath) {
+        String[] whereArgs = new String[] {  Integer.toString(handle) };
+
+        // do not allow renaming any of the special subdirectories
+        if (isStorageSubDirectory(newPath)) {
+            return MtpConstants.RESPONSE_OBJECT_WRITE_PROTECTED;
+        }
+
+        // update database
+        ContentValues values = new ContentValues();
+        values.put(Files.FileColumns.DATA, newPath);
+        values.put(Files.FileColumns.PARENT, newParent);
+        values.put(Files.FileColumns.STORAGE_ID, newStorage);
+        int updated = 0;
+        try {
+            // note - we are relying on a special case in MediaProvider.update() to update
+            // the paths for all children in the case where this is a directory.
+            updated = mMediaProvider.update(mObjectsUri, values, ID_WHERE, whereArgs);
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in mMediaProvider.update", e);
+        }
+        if (updated == 0) {
+            Log.e(TAG, "Unable to update path for " + handle + " to " + newPath);
+            return MtpConstants.RESPONSE_GENERAL_ERROR;
+        }
+        return MtpConstants.RESPONSE_OK;
+    }
+
     private int setObjectProperty(int handle, int property,
                             long intValue, String stringValue) {
         switch (property) {
diff --git a/media/java/android/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java
index d6958b3..e8b04ed 100644
--- a/media/java/android/mtp/MtpDevice.java
+++ b/media/java/android/mtp/MtpDevice.java
@@ -123,7 +123,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index 4f1a145..71f3856 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -302,13 +302,11 @@
     SkBitmap bitmap;
     GraphicsJNI::getSkBitmap(env, jBitmap, &bitmap);
 
-    bitmap.lockPixels();
     rotate((uint16_t*)bitmap.getPixels(),
            (uint16_t*)((char*)videoFrame + sizeof(VideoFrame)),
            videoFrame->mWidth,
            videoFrame->mHeight,
            videoFrame->mRotationAngle);
-    bitmap.unlockPixels();
 
     if (videoFrame->mDisplayWidth  != videoFrame->mWidth ||
         videoFrame->mDisplayHeight != videoFrame->mHeight) {
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index cf4458a..0c946ba 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -68,6 +68,7 @@
 static jmethodID method_getObjectInfo;
 static jmethodID method_getObjectFilePath;
 static jmethodID method_deleteFile;
+static jmethodID method_moveObject;
 static jmethodID method_getObjectReferences;
 static jmethodID method_setObjectReferences;
 static jmethodID method_sessionStarted;
@@ -178,6 +179,9 @@
 
     virtual MtpProperty*            getDevicePropertyDesc(MtpDeviceProperty property);
 
+    virtual MtpResponseCode         moveObject(MtpObjectHandle handle, MtpObjectHandle newParent,
+                                            MtpStorageID newStorage, MtpString& newPath);
+
     virtual void                    sessionStarted();
 
     virtual void                    sessionEnded();
@@ -993,6 +997,18 @@
     return result;
 }
 
+MtpResponseCode MyMtpDatabase::moveObject(MtpObjectHandle handle, MtpObjectHandle newParent,
+        MtpStorageID newStorage, MtpString &newPath) {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jstring stringValue = env->NewStringUTF((const char *) newPath);
+    MtpResponseCode result = env->CallIntMethod(mDatabase, method_moveObject,
+                (jint)handle, (jint)newParent, (jint) newStorage, stringValue);
+
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    env->DeleteLocalRef(stringValue);
+    return result;
+}
+
 struct PropertyTableEntry {
     MtpObjectProperty   property;
     int                 type;
@@ -1358,6 +1374,11 @@
         ALOGE("Can't find deleteFile");
         return -1;
     }
+    method_moveObject = env->GetMethodID(clazz, "moveObject", "(IIILjava/lang/String;)I");
+    if (method_moveObject == NULL) {
+        ALOGE("Can't find moveObject");
+        return -1;
+    }
     method_getObjectReferences = env->GetMethodID(clazz, "getObjectReferences", "(I)[I");
     if (method_getObjectReferences == NULL) {
         ALOGE("Can't find getObjectReferences");
diff --git a/media/jni/android_mtp_MtpServer.cpp b/media/jni/android_mtp_MtpServer.cpp
index e9e9309..6ce104d 100644
--- a/media/jni/android_mtp_MtpServer.cpp
+++ b/media/jni/android_mtp_MtpServer.cpp
@@ -72,7 +72,7 @@
     const char *deviceInfoDeviceVersionStr = env->GetStringUTFChars(deviceInfoDeviceVersion, NULL);
     const char *deviceInfoSerialNumberStr = env->GetStringUTFChars(deviceInfoSerialNumber, NULL);
     MtpServer* server = new MtpServer(getMtpDatabase(env, javaDatabase),
-            usePtp, AID_MEDIA_RW, 0664, 0775,
+            usePtp,
             MtpString((deviceInfoManufacturerStr != NULL) ? deviceInfoManufacturerStr : ""),
             MtpString((deviceInfoModelStr != NULL) ? deviceInfoModelStr : ""),
             MtpString((deviceInfoDeviceVersionStr != NULL) ? deviceInfoDeviceVersionStr : ""),
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp
index d456950..d7695ef 100644
--- a/native/graphics/jni/Android.bp
+++ b/native/graphics/jni/Android.bp
@@ -12,6 +12,33 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+cc_library_shared {
+    name: "libjnigraphics",
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wunused",
+        "-Wunreachable-code",
+    ],
+
+    // our source files
+    //
+    srcs: ["bitmap.cpp"],
+
+    shared_libs: [
+        "libandroid_runtime",
+        "libskia",
+    ],
+
+    arch: {
+        arm: {
+            // TODO: This is to work around b/24465209. Remove after root cause is fixed
+            ldflags: ["-Wl,--hash-style=both"],
+        },
+    },
+}
+
 // The headers module is in frameworks/native/Android.bp.
 ndk_library {
     name: "libjnigraphics",
diff --git a/native/graphics/jni/Android.mk b/native/graphics/jni/Android.mk
deleted file mode 100644
index ec4b35a..0000000
--- a/native/graphics/jni/Android.mk
+++ /dev/null
@@ -1,40 +0,0 @@
-BASE_PATH := $(call my-dir)
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# setup for skia optimizations
-#
-ifneq ($(ARCH_ARM_HAVE_VFP),true)
-    LOCAL_CFLAGS += -DSK_SOFTWARE_FLOAT
-endif
-
-ifeq ($(ARCH_ARM_HAVE_NEON),true)
-    LOCAL_CFLAGS += -D__ARM_HAVE_NEON
-endif
-
-# our source files
-#
-LOCAL_SRC_FILES:= \
-    bitmap.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libandroid_runtime \
-    libskia \
-    libui \
-    libandroidfw
-
-LOCAL_C_INCLUDES += \
-    frameworks/base/native/include \
-    frameworks/base/core/jni/android/graphics \
-    frameworks/base/libs/hwui
-
-LOCAL_MODULE:= libjnigraphics
-
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
-
-# TODO: This is to work around b/24465209. Remove after root cause is fixed
-LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
-
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/native/graphics/jni/bitmap.cpp b/native/graphics/jni/bitmap.cpp
index bf5cabb..ff14832 100644
--- a/native/graphics/jni/bitmap.cpp
+++ b/native/graphics/jni/bitmap.cpp
@@ -15,7 +15,7 @@
  */
 
 #include <android/bitmap.h>
-#include <Bitmap.h>
+#include <android/graphics/Bitmap.h>
 
 int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap,
                           AndroidBitmapInfo* info) {
@@ -56,4 +56,3 @@
     }
     return ANDROID_BITMAP_RESULT_SUCCESS;
 }
-
diff --git a/obex/javax/obex/ObexHelper.java b/obex/javax/obex/ObexHelper.java
index fa50943..478297f 100644
--- a/obex/javax/obex/ObexHelper.java
+++ b/obex/javax/obex/ObexHelper.java
@@ -80,6 +80,9 @@
     // The minimum allowed max packet size is 255 according to the OBEX specification
     public static final int LOWER_LIMIT_MAX_PACKET_SIZE = 255;
 
+    // The length of OBEX Byte Sequency Header Id according to the OBEX specification
+    public static final int OBEX_BYTE_SEQ_HEADER_LEN = 0x03;
+
     /**
      * Temporary workaround to be able to push files to Windows 7.
      * TODO: Should be removed as soon as Microsoft updates their driver.
@@ -205,12 +208,15 @@
                     case 0x40:
                         boolean trimTail = true;
                         index++;
-                        length = 0xFF & headerArray[index];
-                        length = length << 8;
-                        index++;
-                        length += 0xFF & headerArray[index];
-                        length -= 3;
-                        index++;
+                        length = ((0xFF & headerArray[index]) << 8) +
+                                 (0xFF & headerArray[index + 1]);
+                        index += 2;
+                        if (length <= OBEX_BYTE_SEQ_HEADER_LEN) {
+                            Log.e(TAG, "Remote sent an OBEX packet with " +
+                                  "incorrect header length = " + length);
+                            break;
+                        }
+                        length -= OBEX_BYTE_SEQ_HEADER_LEN;
                         value = new byte[length];
                         System.arraycopy(headerArray, index, value, 0, length);
                         if (length == 0 || (length > 0 && (value[length - 1] != 0))) {
diff --git a/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java b/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
index 7a3ed24..21c350be 100644
--- a/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
@@ -20,14 +20,11 @@
 
 public class EGLSurfaceImpl extends EGLSurface {
     long mEGLSurface;
-    private long mNativePixelRef;
     public EGLSurfaceImpl() {
         mEGLSurface = 0;
-        mNativePixelRef = 0;
     }
     public EGLSurfaceImpl(long surface) {
         mEGLSurface = surface;
-        mNativePixelRef = 0;
     }
 
     @Override
diff --git a/packages/BackupRestoreConfirmation/res/values-ar/strings.xml b/packages/BackupRestoreConfirmation/res/values-ar/strings.xml
index b7a56d1..4d4d6be 100644
--- a/packages/BackupRestoreConfirmation/res/values-ar/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ar/strings.xml
@@ -24,10 +24,10 @@
     <string name="restore_confirm_text" msgid="7499866728030461776">"تم طلب استرداد جميع البيانات بالكامل من كمبيوتر سطح مكتب متصل. هل تريد السماح بإجراء ذلك؟\n\nإذا لم تطلب الاسترداد بنفسك، فلا تسمح بمتابعة العملية. يؤدي لك إلى استبدال أية بيانات حاليًا على الجهاز."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"استرداد بياناتي"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"عدم الاسترداد"</string>
-    <string name="current_password_text" msgid="8268189555578298067">"الرجاء إدخال كلمة مرور النسخ الاحتياطي أدناه:"</string>
-    <string name="device_encryption_restore_text" msgid="1570864916855208992">"الرجاء إدخال كلمة مرور تشفير جهازك أدناه."</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"الرجاء إدخال كلمة مرور تشفير الجهاز. سيتم استخدام ذلك أيضًا لتشفير أرشيف النسخ الاحتياطي."</string>
-    <string name="backup_enc_password_text" msgid="4981585714795233099">"الرجاء إدخال كلمة المرور للاستخدام لتشفير بيانات النسخة الاحتياطية بالكامل. إذا تم ترك هذا فارغًا، فسيتم استخدام كلمة مرور النسخ الاحتياطي الحالية:"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"يُرجى إدخال كلمة مرور النسخ الاحتياطي أدناه:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"يُرجى إدخال كلمة مرور تشفير جهازك أدناه."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"يُرجى إدخال كلمة مرور تشفير الجهاز. سيتم استخدام ذلك أيضًا لتشفير أرشيف النسخ الاحتياطي."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"يُرجى إدخال كلمة المرور للاستخدام لتشفير بيانات النسخة الاحتياطية بالكامل. إذا تم ترك هذا فارغًا، فسيتم استخدام كلمة مرور النسخ الاحتياطي الحالية:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"إذا كنت ترغب في تشفير بيانات النسخة الاحتياطية بالكامل، فأدخل كلمة المرور أدناه:"</string>
     <string name="backup_enc_password_required" msgid="7889652203371654149">"نظرًا لكون جهازك مشفرًا، أنت مطالب بتشفير النسخة الاحتياطية. يُرجى إدخال كلمة المرور أدناه:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"إذا كانت بيانات الاسترداد مشفرة، فالرجاء إدخال كلمة المرور أدناه:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-bn/strings.xml b/packages/BackupRestoreConfirmation/res/values-bn/strings.xml
index 2b69d5b..afc8c3e 100644
--- a/packages/BackupRestoreConfirmation/res/values-bn/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-bn/strings.xml
@@ -20,13 +20,13 @@
     <string name="restore_confirm_title" msgid="5469365809567486602">"সম্পূর্ণ পুনরুদ্ধার"</string>
     <string name="backup_confirm_text" msgid="1878021282758896593">"একটি সংযুক্ত ডেস্কটপ কম্পিউটার থেকে সমস্ত ডেটার সম্পূর্ণ ব্যাকআপ নেওয়ার অনুরোধ করা হয়েছে৷ আপনি কি এটি করার অনুমতি দিতে চান?\n\nযদি আপনি নিজের থেকে এই ব্যাকআপ নেওয়ার অনুরোধ না করে থাকেন, তবে এটি প্রক্রিয়াটিতে অনুমতি প্রদান করবেন না৷"</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"আমার ডেটার ব্যাকআপ রাখুন"</string>
-    <string name="deny_backup_button_label" msgid="6009119115581097708">"ব্যাক আপ করবেন না"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"ব্যাক-আপ করবেন না"</string>
     <string name="restore_confirm_text" msgid="7499866728030461776">"একটি সংযুক্ত ডেস্কটপ কম্পিউটার থেকে সমস্ত ডেটার সম্পূর্ণ ব্যাকআপ নেওয়ার অনুরোধ করা হয়েছে৷ আপনি কি এটি করার অনুমতি দিতে চান?\n\nযদি আপনি নিজের থেকে এই ব্যাকআপ নেওয়ার অনুরোধ না করে থাকেন, তবে এই প্রক্রিয়াটিতে অনুমতি প্রদান করবেন না৷ এটি বর্তমানে ডিভাইসটিতে থাকা সমস্ত ডেটাকে প্রতিস্থাপন করবে!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"আমার ডেটা পুনরুদ্ধার করুন"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"পুনরুদ্ধার করবেন না"</string>
     <string name="current_password_text" msgid="8268189555578298067">"দয়া করে নিচে আপনার বর্তমান ব্যাকআপের পাসওয়ার্ড দিন:"</string>
     <string name="device_encryption_restore_text" msgid="1570864916855208992">"দয়া করে নিচে আপনার ডিভাইসের এনক্রিপশান পাসওয়ার্ড লিখুন৷"</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"দয়া করে নিচে আপানার ডিভাইসের এনক্রিপশান পাসওয়ার্ড লিখুন৷ এছাড়াও ব্যাকআপ সংরক্ষণাগার এনক্রিপ্ট করতে এটি ব্যবহার করা হবে৷"</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"অনুগ্রহ করে নিচে আপানার ডিভাইসের এনক্রিপশান পাসওয়ার্ড লিখুন৷ এছাড়াও ব্যাক-আপ আর্কাইভ এনক্রিপ্ট করতে এটি ব্যবহার করা হবে৷"</string>
     <string name="backup_enc_password_text" msgid="4981585714795233099">"সম্পূর্ণ ব্যাকআপ ডেটা এনক্রিপ্ট করতে দয়া করে একটি পাসওয়ার্ড লিখুন৷ যদি এটি খালি রেখে দেওয়া হয় তবে আপনার বর্তমান ব্যাকআপ পাসওয়ার্ডটি ব্যবহার করা হবে:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"আপনি যদি সম্পূর্ণ ব্যাকআপ ডেটা এনক্রিপ্ট করতে চান তাহলে নিচে একটি পাসওয়ার্ড লিখুন:"</string>
     <string name="backup_enc_password_required" msgid="7889652203371654149">"আপনার ডিভাইস এনক্রিপ্ট হয়ে থাকার কারণে আপনার ব্যাকআপকে এনক্রিপ্ট করতে হবে। দয়া করে নিচে একটি পাসওয়ার্ড দিন:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-bs/strings.xml b/packages/BackupRestoreConfirmation/res/values-bs/strings.xml
index 53b0bce..e4852ed 100644
--- a/packages/BackupRestoreConfirmation/res/values-bs/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-bs/strings.xml
@@ -17,23 +17,23 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Napraviti potpunu rezervnu kopiju"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Izvrši potpuno obnavljanje"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Izvrši potpuno vraćanje"</string>
     <string name="backup_confirm_text" msgid="1878021282758896593">"Zatraženo je pravljenje potpune rezervne kopije svih podataka na povezani računar. Da li želite da dozvolite to?\n\nPrekinite radnju ukoliko to niste sami zatražili."</string>
-    <string name="allow_backup_button_label" msgid="4217228747769644068">"Napravi rezervnu kopiju mojih podataka"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Napravi sigurnosnu kopiju mojih podataka"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nemoj napraviti rezervnu kopiju"</string>
     <string name="restore_confirm_text" msgid="7499866728030461776">"Sa povezanog računara je upućen zahtjev za potpuno obnavljanje svih podataka. Želite li to dozvoliti?\n\nUkoliko niste uputili zahtjev za obnavljanje, prekinite radnju. Ovim će zamijeniti svi podaci koji su trenutno na uređaju!"</string>
-    <string name="allow_restore_button_label" msgid="3081286752277127827">"Obnovi moje podatke"</string>
-    <string name="deny_restore_button_label" msgid="1724367334453104378">"Prekinuti obnavljanje podataka"</string>
-    <string name="current_password_text" msgid="8268189555578298067">"Ispod unesite svoju trenutnu lozinku za rezervnu kopiju:"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Vrati moje podatke"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Ne vraćaj"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Ispod unesite svoju trenutnu lozinku za sigurnosnu kopiju:"</string>
     <string name="device_encryption_restore_text" msgid="1570864916855208992">"Ispod unesite svoju lozinku za šifriranje uređaja."</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Molimo vas unesite svoju lozinku za šifriranje uređaja ispod. Ona će se koristiti i za šifriranje arhive rezervnih kopija."</string>
-    <string name="backup_enc_password_text" msgid="4981585714795233099">"Unesite lozinku za šifriranje potpune rezervne kopije podataka. Ukoliko ne unesete lozinku, primijenit će se vaša trenutna lozinka za rezervnu kopiju:"</string>
-    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ukoliko želite šifrirati potpunu rezervnu kopiju podataka, unesite lozinku ispod:"</string>
-    <string name="backup_enc_password_required" msgid="7889652203371654149">"Pošto je vaš uređaj šifriran, potrebno je šifrirati rezervnu kopiju. Unesite šifru ispod:"</string>
-    <string name="restore_enc_password_text" msgid="6140898525580710823">"Ukoliko su podaci za obnavljanje šifrirani, unesite lozinku ispod:"</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Molimo vas unesite svoju lozinku za šifriranje uređaja ispod. Ona će se koristiti i za šifriranje arhive sigurnosnih kopija."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Unesite lozinku za šifriranje potpune sigurnosne kopije podataka. Ukoliko ne unesete lozinku, primijenit će se vaša trenutna lozinka za sigurnosnu kopiju:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ukoliko želite šifrirati potpunu sigurnosnu kopiju podataka, unesite lozinku ispod:"</string>
+    <string name="backup_enc_password_required" msgid="7889652203371654149">"Pošto je vaš uređaj šifriran, potrebno je šifrirati sigurnosnu kopiju. Unesite šifru ispod:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Ukoliko su podaci za vraćanje šifrirani, unesite lozinku ispod:"</string>
     <string name="toast_backup_started" msgid="550354281452756121">"Pravljenje rezervne kopije..."</string>
     <string name="toast_backup_ended" msgid="3818080769548726424">"Pravljenje rezervne kopije završeno"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Počinje obnavljanje podataka..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Obnavljanje podatka završeno"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Pokretanje vraćanja..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Vraćanje završeno"</string>
     <string name="toast_timeout" msgid="5276598587087626877">"Isteklo je vrijeme za izvršenje radnje"</string>
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-hi/strings.xml b/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
index 2578e8f..06f9ebd 100644
--- a/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
@@ -18,22 +18,22 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"पूर्ण सुरक्षा"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"पूर्ण पुनर्स्‍थापना"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"कनेक्‍ट कि‍ए गए डेस्‍कटॉप कंप्‍यूटर से सभी डेटा के संपूर्ण सुरक्षा का अनुरोध कि‍या गया है. क्‍या आप इसकी अनुमति‍ देना चाहते हैं?\n\nयदि‍ आपने स्‍वयं बैकअप का अनुरोध नहीं कि‍या है, तो प्रक्रि‍या जारी रखने की अनुमति‍ न दें."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"कनेक्‍ट कि‍ए गए डेस्‍कटॉप कंप्‍यूटर से पूरे डेटा के बैकअप का अनुरोध कि‍या गया है. क्‍या आप इसकी अनुमति‍ देना चाहते हैं?\n\nअगर आपने बैकअप का अनुरोध नहीं कि‍या है, तो इस प्रक्रि‍या को जारी रखने की अनुमति‍ न दें."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"मेरे डेटा का बैकअप लें"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"बैकअप न लें"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"कनेक्‍ट कि‍ए गए डेस्‍कटॉप कंप्‍यूटर से सभी डेटा की पूर्ण पुनर्स्थापना का अनुरोध कि‍या गया है. क्‍या आप इसकी अनुमति‍ देना चाहते हैं?\n\nयदि‍ आपने स्‍वयं पुनर्प्राप्ति‍ का अनुरोध नहीं कि‍या है, तो प्रक्रि‍या जारी रखने की अनुमति‍ न दें. इससे वर्तमान में आपके डिवाइस पर मौजूद डेटा बदल जाएगा!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"कनेक्‍ट कि‍ए गए डेस्‍कटॉप कंप्‍यूटर से पूरे डेटा को बहाल करने का अनुरोध कि‍या गया है. क्‍या आप इसकी अनुमति‍ देना चाहते हैं?\n\nअगर आपने इसे बहाल करने का अनुरोध नहीं कि‍या है, तो इस प्रक्रि‍या को जारी रखने की अनुमति‍ न दें. इससे आपके डिवाइस पर इस वक्त जो भी डेटा मौजूद है वो बदल जाएगा!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"मेरा डेटा पुनर्स्थापित करें"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"पुनर्स्‍थापित न करें"</string>
     <string name="current_password_text" msgid="8268189555578298067">"कृपया नीचे अपना वर्तमान सुरक्षित करने का पासवर्ड डालें:"</string>
-    <string name="device_encryption_restore_text" msgid="1570864916855208992">"कृपया नीचे अपना डिवाइस एन्‍क्रिप्शन पासवर्ड डालें."</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"कृपया नीचे अपना डिवाइस सुरक्षित करने का पासवर्ड डालें."</string>
     <string name="device_encryption_backup_text" msgid="5866590762672844664">"कृपया अपना डिवाइस सुरक्षित तरीका पासवर्ड नीचे दर्ज करें. बैकअप मेमोरी को एन्‍क्रिप्‍ट करने के लिए भी इसका उपयोग किया जाएगा."</string>
     <string name="backup_enc_password_text" msgid="4981585714795233099">"कृपया संपूर्ण सुरक्षित डेटा को एन्‍क्रि‍प्‍ट करने में उपयोग के लि‍ए पासवर्ड डालें. यदि‍ यह खाली छोड़ दि‍या जाता है, तो आपके वर्तमान बैकअप पासवर्ड का उपयोग कि‍या जाएगा:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"यदि‍ आप संपूर्ण सुरक्षित डेटा को एन्‍क्रि‍प्‍ट करना चाहते हैं, तो नीचे पासवर्ड डालें:"</string>
     <string name="backup_enc_password_required" msgid="7889652203371654149">"चूंकि आपका डिवाइस एन्क्रिप्ट किया हुआ है, इसलिए आपको अपने बैकअप को एन्क्रिप्ट करना आवश्यक है. कृपया नीचे पासवर्ड डालें:"</string>
-    <string name="restore_enc_password_text" msgid="6140898525580710823">"यदि‍ पुनर्स्थापित डेटा को एन्‍क्रि‍प्‍ट कि‍या गया है, तो कृपया नीचे पासवर्ड डालें:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"अगर रिस्टोर किया गया डेटा सुरक्षित कि‍या गया है, तो कृपया नीचे पासवर्ड डालें:"</string>
     <string name="toast_backup_started" msgid="550354281452756121">"सुरक्षित करना शुरु हो रहा है..."</string>
     <string name="toast_backup_ended" msgid="3818080769548726424">"सुरक्षित करना पूर्ण"</string>
     <string name="toast_restore_started" msgid="7881679218971277385">"पुनर्स्‍थापना प्रारंभ हो रही है..."</string>
     <string name="toast_restore_ended" msgid="1764041639199696132">"पुनर्स्‍थापना समाप्त"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"कार्यवाही समयबाह्य हो गई"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"काम नहीं हो सका. टाइम आउट हो गया"</string>
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-iw/strings.xml b/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
index 3ad7c96..c060403 100644
--- a/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
@@ -21,7 +21,7 @@
     <string name="backup_confirm_text" msgid="1878021282758896593">"הוגשה בקשה לגיבוי מלא של כל הנתונים במחשב שולחני מחובר. האם אתה רוצה לאפשר פעולה זו? \n\nאם לא ביקשת את הגיבוי בעצמך, אל תאפשר לפעולה להמשיך."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"גיבוי הנתונים שלי"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"אל תגבה"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"הוגשה בקשה לשחזור מלא של כל הנתונים ממחשב שולחני מחובר. האם אתה רוצה לאפשר פעולה זו? \n \n אם לא ביקשת את השחזור בעצמך, אל תאפשר לפעולה להמשיך. פעולה זו תחליף את כל הנתונים שנמצאים כעת במכשיר!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"הוגשה בקשה לשחזור מלא של כל הנתונים ממחשב שולחני מחובר. האם ברצונך לאפשר פעולה זו? \n \n אם לא ביקשת את השחזור בעצמך, אל תאפשר לפעולה להמשיך. פעולה זו תחליף את כל הנתונים שנמצאים כעת במכשיר!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"שחזר את הנתונים שלי"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"אל תשחזר"</string>
     <string name="current_password_text" msgid="8268189555578298067">"הזן את סיסמת הגיבוי הנוכחית למטה:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-mr/strings.xml b/packages/BackupRestoreConfirmation/res/values-mr/strings.xml
index 121ad00..3ee60ca 100644
--- a/packages/BackupRestoreConfirmation/res/values-mr/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-mr/strings.xml
@@ -18,22 +18,22 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"पूर्ण बॅकअप"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"पूर्ण पुनर्संचयन"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"कनेक्‍ट केलेल्‍या डेस्‍कटॉप संगणकावरील सर्व डेटाच्‍या पूर्ण बॅकअपची विनंती केली गेली आहे. आपण असे होण्यासाठी अनुमती देऊ इच्‍छिता?\n\nआपण स्‍वत: बॅकअपची विनंती केली नसल्‍यास, कार्य पुढे सुरु राहण्‍यास अनुमती देऊ नका."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"कनेक्‍ट केलेल्‍या डेस्‍कटॉप काँप्युटरवरील सर्व डेटाच्‍या पूर्ण बॅकअपची विनंती केली गेली आहे. आपण असे होण्यासाठी अनुमती देऊ इच्‍छिता?\n\nआपण स्‍वत: बॅकअपची विनंती केली नसल्‍यास, कार्य पुढे सुरु राहण्‍यास अनुमती देऊ नका."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"माझ्‍या डेटाचा बॅकअप घ्‍या"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"बॅकअप घेऊ नका"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"कनेक्‍ट केलेल्‍या डेस्‍कटॉप संगणकावरील सर्व डेटाच्या पूर्ण पुनर्संचयनाची विनंती केली गेली आहे. आपण असे होण्यासाठी अनुमती देऊ इच्‍छिता?\n\nआपण स्‍वत: पुनर्संचयनाची विनंती केली नसल्‍यास, कार्य पुढे सुरु राहण्‍यास अनुमती देऊ नका. हे आपल्‍या डिव्‍हाइसवरील कोणत्याही वर्तमान डेटास पुनर्स्‍थित करेल!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"कनेक्‍ट केलेल्‍या डेस्‍कटॉप काँप्युटरवरील सर्व डेटाच्या पूर्ण पुनर्संचयनाची विनंती केली गेली आहे. आपण असे होण्यासाठी अनुमती देऊ इच्‍छिता?\n\nआपण स्‍वत: पुनर्संचयनाची विनंती केली नसल्‍यास, कार्य पुढे सुरु राहण्‍यास अनुमती देऊ नका. हे आपल्‍या डिव्‍हाइसवरील कोणत्याही वर्तमान डेटास पुनर्स्‍थित करेल!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"माझा डेटा पुनर्संचयित करा"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"पुनर्संचयित करू नका"</string>
     <string name="current_password_text" msgid="8268189555578298067">"कृपया आपला वर्तमान बॅकअप संकेतशब्‍द खाली प्रविष्‍ट करा:"</string>
-    <string name="device_encryption_restore_text" msgid="1570864916855208992">"कृपया आपला डिव्‍हाइस कूटबद्धीकरण संकेतशब्‍द खाली प्रविष्‍ट करा."</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"कृपया आपला डिव्‍हाइस कूटबद्धीकरण संकेतशब्‍द खाली प्रविष्‍‍ट करा. हा बॅकअप संग्रह कूटबद्ध करण्‍यासाठी देखील वापरला जाईल."</string>
-    <string name="backup_enc_password_text" msgid="4981585714795233099">"कृपया पूर्ण बॅकअप डेटा कूटबद्ध करण्‍यासाठी वापरण्याकरिता संकेतशब्‍द प्रविष्‍ट करा. हे रिक्त सोडल्‍यास, आपला वर्तमान बॅकअप संकेतशब्‍द वापरला जाईल:"</string>
-    <string name="backup_enc_password_optional" msgid="1350137345907579306">"आपण पूर्ण बॅकअप डेटा कूटबद्ध करू इच्‍छित असल्‍यास, खालील संकेतशब्‍द प्रविष्‍ट करा:"</string>
-    <string name="backup_enc_password_required" msgid="7889652203371654149">"आपले डिव्हाइस कूटबद्ध केले असल्यामुळे, आपल्याला आपला बॅक अप कूटबद्ध करणे आवश्यक आहे. कृपया खाली एक संकेतशब्द प्रविष्ट करा:"</string>
-    <string name="restore_enc_password_text" msgid="6140898525580710823">"पुनर्संचयित डेटा कूटबद्ध केला असल्‍यास, कृपया संकेतशब्‍द खाली प्रविष्‍ट करा:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"कृपया तुमचे डिव्हाइस एंक्रिप्शन पासवर्ड खाली एंटर करा."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"कृपया तुमचे डिव्हाइस एंक्रिप्शन पासवर्ड खाली एंटर करा. हा बॅकअप संग्रह एंक्रिप्ट करण्‍यासाठी देखील वापरला जाईल."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"कृपया पूर्ण बॅकअप डेटा एंक्रिप्ट करण्‍यासाठी वापरण्याकरिता पासवर्ड एंटर करा. हे रिक्त सोडल्‍यास, आपला वर्तमान बॅकअप पासवर्ड वापरला जाईल:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"तुम्ही पूर्ण बॅकअप डेटा एंक्रिप्ट करू इच्‍छित असल्‍यास, खालील पासवर्ड एंटर करा:"</string>
+    <string name="backup_enc_password_required" msgid="7889652203371654149">"तुमचे डिव्हाइस एंक्रिप्ट केले असल्यामुळे, तुम्हाला तुमचा बॅक अप एंक्रिप्ट करणे आवश्यक आहे. कृपया खाली एक पासवर्ड एंटर करा:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"पुनर्स्टोअर केलेला डेटा एंक्रिप्ट केला असल्‍यास, कृपया पासवर्ड खाली एंटर करा:"</string>
     <string name="toast_backup_started" msgid="550354281452756121">"बॅकअप सुरू होत आहे..."</string>
     <string name="toast_backup_ended" msgid="3818080769548726424">"बॅकअप समाप्त झाले"</string>
     <string name="toast_restore_started" msgid="7881679218971277385">"पुनर्संचयन सुरू होत आहे..."</string>
     <string name="toast_restore_ended" msgid="1764041639199696132">"पुनर्संचयन समाप्त झाले"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"कार्य कालबाह्य झाले"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"कार्य टाइमआउट झाले"</string>
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-pa/strings.xml b/packages/BackupRestoreConfirmation/res/values-pa/strings.xml
index 12dd546..72513ba 100644
--- a/packages/BackupRestoreConfirmation/res/values-pa/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-pa/strings.xml
@@ -16,23 +16,23 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"ਪੂਰਾ ਬੈਕਅਪ"</string>
+    <string name="backup_confirm_title" msgid="827563724209303345">"ਪੂਰਾ ਬੈਕਅੱਪ"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"ਪੂਰਾ ਰੀਸਟੋਰ"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"ਇੱਕ ਕਨੈਕਟ ਕੀਤੇ ਡੈਸਕਟੌਪ ਕੰਪਿਊਟਰ ਦੇ ਸਾਰੇ ਡੈਟਾ ਦੇ ਇੱਕ ਪੁੂਰੇ ਬੈਕਅਪ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਗਈ ਹੈ। ਕੀ ਤੁਸੀਂ ਅਜਿਹਾ ਹੋਣ ਦੀ ਆਗਿਆ ਦੇਣਾ ਚਾਹੁੰਦੇ ਹੋ?\n\nਜੇਕਰ ਤੁਸੀਂ ਖੁਦ ਬੈਕਅਪ ਦੀ ਬੇਨਤੀ ਨਹੀਂ ਕੀਤੀ ਸੀ, ਤਾਂ ਓਪਰੇਸ਼ਨ ਜਾਰੀ ਰੱਖਣ ਦੀ ਆਗਿਆ ਨਾ ਦਿਓ।"</string>
-    <string name="allow_backup_button_label" msgid="4217228747769644068">"ਮੇਰਾ ਡੈਟਾ ਬੈਕ ਅਪ ਕਰੋ"</string>
-    <string name="deny_backup_button_label" msgid="6009119115581097708">"ਬੈਕ ਅਪ ਨਾ ਕਰੋ"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"ਇੱਕ ਕਨੈਕਟ ਕੀਤੇ ਡੈਸਕਟੌਪ ਕੰਪਿਊਟਰ ਦੇ ਸਾਰੇ ਡੈਟਾ ਦੇ ਇੱਕ ਪੁੂਰੇ ਰੀਸਟੋਰ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਗਈ ਹੈ। ਕੀ ਤੁਸੀਂ ਅਜਿਹਾ ਹੋਣ ਦੀ ਆਗਿਆ ਦੇਣਾ ਚਾਹੁੰਦੇ ਹੋ?\n\nਜੇਕਰ ਤੁਸੀਂ ਖੁਦ ਰੀਸਟੋਰ ਦੀ ਬੇਨਤੀ ਨਹੀਂ ਕੀਤੀ ਸੀ, ਤਾਂ ਓਪਰੇਸ਼ਨ ਜਾਰੀ ਰੱਖਣ ਦੀ ਆਗਿਆ ਨਾ ਦਿਓ। ਇਹ ਡੀਵਾਈਸ ਤੇ ਇਸ ਵੇਲੇ ਮੌਜੂਦ ਕਿਸੇ ਵੀ ਡੈਟਾ ਨੂੰ ਬਦਲ ਦੇਵੇਗਾ!"</string>
-    <string name="allow_restore_button_label" msgid="3081286752277127827">"ਮੇਰਾ ਡੈਟਾ ਰੀਸਟੋਰ ਕਰੋ"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"ਇੱਕ ਕਨੈਕਟ ਕੀਤੇ ਡੈਸਕਟਾਪ ਕੰਪਿਊਟਰ ਦੇ ਸਾਰੇ ਡਾਟਾ ਦੇ ਇੱਕ ਪੁੂਰੇ ਬੈਕਅੱਪ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਗਈ ਹੈ। ਕੀ ਤੁਸੀਂ ਅਜਿਹਾ ਹੋਣ ਦੀ ਆਗਿਆ ਦੇਣਾ ਚਾਹੁੰਦੇ ਹੋ?\n\nਜੇਕਰ ਤੁਸੀਂ ਖੁਦ ਬੈਕਅੱਪ ਦੀ ਬੇਨਤੀ ਨਹੀਂ ਕੀਤੀ ਸੀ, ਤਾਂ ਓਪਰੇਸ਼ਨ ਜਾਰੀ ਰੱਖਣ ਦੀ ਆਗਿਆ ਨਾ ਦਿਓ।"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"ਮੇਰਾ ਡਾਟਾ ਬੈਕ ਅੱਪ ਲਓ"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"ਬੈਕ ਅੱਪ ਨਾ ਕਰੋ"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"ਇੱਕ ਕਨੈਕਟ ਕੀਤੇ ਡੈਸਕਟਾਪ ਕੰਪਿਊਟਰ ਦੇ ਸਾਰੇ ਡਾਟਾ ਦੇ ਇੱਕ ਪੁੂਰੇ ਰੀਸਟੋਰ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਗਈ ਹੈ। ਕੀ ਤੁਸੀਂ ਅਜਿਹਾ ਹੋਣ ਦੀ ਆਗਿਆ ਦੇਣਾ ਚਾਹੁੰਦੇ ਹੋ?\n\nਜੇਕਰ ਤੁਸੀਂ ਖੁਦ ਰੀਸਟੋਰ ਦੀ ਬੇਨਤੀ ਨਹੀਂ ਕੀਤੀ ਸੀ, ਤਾਂ ਓਪਰੇਸ਼ਨ ਜਾਰੀ ਰੱਖਣ ਦੀ ਆਗਿਆ ਨਾ ਦਿਓ। ਇਹ ਡੀਵਾਈਸ \'ਤੇ ਇਸ ਵੇਲੇ ਮੌਜੂਦ ਕਿਸੇ ਵੀ ਡਾਟਾ ਨੂੰ ਬਦਲ ਦੇਵੇਗਾ!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"ਮੇਰਾ  ਡਾਟਾ  ਰੀਸਟੋਰ ਕਰੋ"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"ਰੀਸਟੋਰ ਨਾ ਕਰੋ"</string>
-    <string name="current_password_text" msgid="8268189555578298067">"ਕਿਰਪਾ ਕਰਕੇ ਹੇਠਾਂ ਆਪਣਾ ਮੌਜੂਦਾ ਬੈਕਅਪ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ:"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"ਕਿਰਪਾ ਕਰਕੇ ਹੇਠਾਂ ਆਪਣਾ ਮੌਜੂਦਾ ਬੈਕਅੱਪ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ:"</string>
     <string name="device_encryption_restore_text" msgid="1570864916855208992">"ਕਿਰਪਾ ਕਰਕੇ ਹੇਠਾਂ ਆਪਣਾ ਡੀਵਾਈਸ ਇਨਕ੍ਰਿਪਸ਼ਨ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ।"</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"ਕਿਰਪਾ ਕਰਕੇ ਹੇਠਾਂ ਆਪਣਾ ਡੀਵਾਈਸ ਇਨਕ੍ਰਿਪਸ਼ਨ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ। ਇਹ ਬੈਕਅਪ ਆਰਕਾਈਵ ਇਨਕ੍ਰਿਪਟ ਕਰਨ ਲਈ ਵੀ ਵਰਤਿਆ ਜਾਏਗਾ।"</string>
-    <string name="backup_enc_password_text" msgid="4981585714795233099">"ਕਿਰਪਾ ਕਰਕੇ ਪੂਰਾ ਬੈਕਅਪ ਡੈਟਾ ਇਨਕ੍ਰਿਪਟ ਕਰਨ ਦੀ ਵਰਤੋਂ ਲਈ ਇੱਕ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ। ਜੇਕਰ ਇਸਨੂੰ ਖਾਲੀ ਛੱਡਿਆ ਜਾਂਦਾ ਹੈ, ਤਾਂ ਤੁਹਾਡਾ ਵਰਤਮਾਨ ਬੈਕਅਪ ਪਾਸਵਰਡ ਵਰਤਿਆ ਜਾਏਗਾ:"</string>
-    <string name="backup_enc_password_optional" msgid="1350137345907579306">"ਜੇਕਰ ਤੁਸੀਂ ਪੂਰਾ ਬੈਕਅਪ ਡੈਟਾ ਇਨਕ੍ਰਿਪਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ, ਤਾਂ ਹੇਠਾਂ ਇੱਕ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ:"</string>
-    <string name="backup_enc_password_required" msgid="7889652203371654149">"ਕਿਉਂਕਿ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਇਨਕ੍ਰਿਪਟਿਡ ਬੈ, ਇਸਲਈ ਤੁਹਾਡੇ ਤੋਂ ਆਪਣਾ ਬੈਕਅਪ ਇਨਕ੍ਰਿਪਟ ਕਰਨ ਦੀ ਮੰਗ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਕਿਰਪਾ ਕਰਕੇ ਹੇਠਾਂ ਇੱਕ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ:"</string>
-    <string name="restore_enc_password_text" msgid="6140898525580710823">"ਜੇਕਰ ਰੀਸਟੋਰ ਡੈਟਾ ਇਨਕ੍ਰਿਪਟ ਕੀਤਾ ਗਿਆ ਹੈ, ਤਾਂ ਹੇਠਾਂ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"ਬੈਕਅਪ ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"ਬੈਕਅਪ ਪੂਰਾ ਹੋਇਆ"</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"ਕਿਰਪਾ ਕਰਕੇ ਹੇਠਾਂ ਆਪਣਾ ਡੀਵਾਈਸ ਇਨਕ੍ਰਿਪਸ਼ਨ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ। ਇਹ ਬੈਕਅੱਪ ਪੁਰਾਲੇਖ ਇਨਕ੍ਰਿਪਟ ਕਰਨ ਲਈ ਵੀ ਵਰਤਿਆ ਜਾਏਗਾ।"</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"ਕਿਰਪਾ ਕਰਕੇ ਪੂਰਾ ਬੈਕਅੱਪ ਡਾਟਾ ਇਨਕ੍ਰਿਪਟ ਕਰਨ ਦੀ ਵਰਤੋਂ ਲਈ ਇੱਕ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ। ਜੇਕਰ ਇਸਨੂੰ ਖਾਲੀ ਛੱਡਿਆ ਜਾਂਦਾ ਹੈ, ਤਾਂ ਤੁਹਾਡਾ ਵਰਤਮਾਨ ਬੈਕਅੱਪ ਪਾਸਵਰਡ ਵਰਤਿਆ ਜਾਏਗਾ:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"ਜੇਕਰ ਤੁਸੀਂ ਪੂਰਾ ਬੈਕਅੱਪ ਡਾਟਾ ਇਨਕ੍ਰਿਪਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ, ਤਾਂ ਹੇਠਾਂ ਇੱਕ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ:"</string>
+    <string name="backup_enc_password_required" msgid="7889652203371654149">"ਕਿਉਂਕਿ ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਇਨਕ੍ਰਿਪਟਡ ਹੈ, ਇਸਲਈ ਤੁਹਾਡੇ ਤੋਂ ਆਪਣਾ ਬੈਕਅੱਪ ਇਨਕ੍ਰਿਪਟ ਕਰਨ ਦੀ ਮੰਗ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਕਿਰਪਾ ਕਰਕੇ ਹੇਠਾਂ ਇੱਕ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"ਜੇਕਰ ਰੀਸਟੋਰ ਡਾਟਾ ਇਨਕ੍ਰਿਪਟ ਕੀਤਾ ਗਿਆ ਹੈ, ਤਾਂ ਹੇਠਾਂ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"ਬੈਕਅੱਪ ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"ਬੈਕਅੱਪ ਪੂਰਾ ਹੋਇਆ"</string>
     <string name="toast_restore_started" msgid="7881679218971277385">"ਰੀਸਟੋਰ ਚਾਲੂ ਹੋ ਰਿਹਾ ਹੈ..."</string>
     <string name="toast_restore_ended" msgid="1764041639199696132">"ਰੀਸਟੋਰ ਖ਼ਤਮ ਹੋਇਆ"</string>
     <string name="toast_timeout" msgid="5276598587087626877">"ਓਪਰੇਸ਼ਨ ਦਾ ਸਮਾਂ ਸਮਾਪਤ"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-te/strings.xml b/packages/BackupRestoreConfirmation/res/values-te/strings.xml
index 52916d8..35e9492 100644
--- a/packages/BackupRestoreConfirmation/res/values-te/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-te/strings.xml
@@ -25,8 +25,8 @@
     <string name="allow_restore_button_label" msgid="3081286752277127827">"నా డేటాను పునరుద్ధరించు"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"పునరుద్ధరించవద్దు"</string>
     <string name="current_password_text" msgid="8268189555578298067">"దయచేసి దిగువ మీ ప్రస్తుత బ్యాకప్ పాస్‌వర్డ్‌ను నమోదు చేయండి:"</string>
-    <string name="device_encryption_restore_text" msgid="1570864916855208992">"దయచేసి దిగువ మీ పరికర గుప్తీకరణ పాస్‌వర్డ్‌ను నమోదు చేయండి."</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"దయచేసి దిగువ మీ పరికర గుప్తీకరణ పాస్‌వర్డ్‌ను నమోదు చేయండి. ఇది బ్యాకప్ ఆర్కైవ్‌ను గుప్తీకరించడానికి కూడా ఉపయోగించబడుతుంది."</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"దయచేసి దిగువ మీ పరికర ఎన్‌క్రిప్షన్ పాస్‌వర్డ్‌ను నమోదు చేయండి."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"దయచేసి దిగువ మీ పరికర ఎన్‌క్రిప్షన్ పాస్‌వర్డ్‌ను నమోదు చేయండి. ఇది బ్యాకప్ ఆర్కైవ్‌ను ఎన్‌క్రిప్ట్ చేయడానికి కూడా ఉపయోగించబడుతుంది."</string>
     <string name="backup_enc_password_text" msgid="4981585714795233099">"దయచేసి పూర్తి బ్యాకప్ డేటాను గుప్తీకరించడం కోసం ఉపయోగించడానికి పాస్‌వర్డ్‌ను నమోదు చేయండి. దీన్ని ఖాళీగా వదిలిపెడితే, మీ ప్రస్తుత బ్యాకప్ పాస్‌వర్డ్ ఉపయోగించబడుతుంది:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"మీరు పూర్తి బ్యాకప్ డేటాను గుప్తీకరించాలని కోరుకుంటున్నట్లయితే, దిగువ పాస్‌వర్డ్‌ను నమోదు చేయండి:"</string>
     <string name="backup_enc_password_required" msgid="7889652203371654149">"మీ పరికరం గుప్తీకరించబడినందున, మీరు మీ బ్యాకప్‌ని గుప్తీకరించాల్సి ఉంటుంది. దయచేసి దిగువ పాస్‌వర్డ్‌ని నమోదు చేయండి:"</string>
diff --git a/packages/CaptivePortalLogin/res/values-bn/strings.xml b/packages/CaptivePortalLogin/res/values-bn/strings.xml
index c6a044d..b75d76e 100644
--- a/packages/CaptivePortalLogin/res/values-bn/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-bn/strings.xml
@@ -4,9 +4,9 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"যেভাবে আছে সেভাবেই এই নেটওয়ার্ক ব্যবহার করুন"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"এই নেটওয়ার্ক ব্যবহার করবেন না"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"নেটওয়ার্কে প্রবেশ করুন"</string>
+    <string name="action_bar_label" msgid="917235635415966620">"নেটওয়ার্কে সাইন-ইন করুন"</string>
     <string name="action_bar_title" msgid="5645564790486983117">"%1$s তে সাইন-ইন করুন"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"আপনি যে নেটওয়ার্কে যোগ দেওয়ার চেষ্টা করছেন তাতে নিরাপত্তার সমস্যা আছে।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"উদাহরণস্বরূপ, লগইন পৃষ্ঠাটি প্রদর্শিত প্রতিষ্ঠানের অন্তর্গত নাও হতে পারে৷"</string>
+    <string name="ssl_error_example" msgid="647898534624078900">"উদাহরণস্বরূপ, লগ-ইন পৃষ্ঠাটি প্রদর্শিত প্রতিষ্ঠানের অন্তর্গত নাও হতে পারে৷"</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"যাই হোক না কেন ব্রাউজারের মাধ্যমে অবিরত রাখুন"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-bs/strings.xml b/packages/CaptivePortalLogin/res/values-bs/strings.xml
index 3237e5e..0b36cd0 100644
--- a/packages/CaptivePortalLogin/res/values-bs/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-bs/strings.xml
@@ -4,7 +4,7 @@
     <string name="app_name" msgid="5934709770924185752">"Prijava na zaštitnom portalu"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Koristi ovu mrežu kakva jeste"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne koristi ovu mrežu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prijavi me na mrežu"</string>
+    <string name="action_bar_label" msgid="917235635415966620">"Prijava na mrežu"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Mreža kojoj pokušavate pristupiti ima sigurnosnih problema."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Naprimjer, stranica za prijavu možda ne pripada prikazanoj organizaciji."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Ipak nastavi preko preglednika"</string>
diff --git a/packages/CaptivePortalLogin/res/values-hi/strings.xml b/packages/CaptivePortalLogin/res/values-hi/strings.xml
index 1bc6879..1bacc46 100644
--- a/packages/CaptivePortalLogin/res/values-hi/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-hi/strings.xml
@@ -4,8 +4,8 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"इस नेटवर्क का उपयोग जैसा है वैसा ही करें"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"इस नेटवर्क का उपयोग न करें"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"नेटवर्क में प्रवेश करें"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s में प्रवेश करें"</string>
+    <string name="action_bar_label" msgid="917235635415966620">"नेटवर्क में साइन इन करें"</string>
+    <string name="action_bar_title" msgid="5645564790486983117">"%1$s में साइन इन करें"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"आप जिस नेटवर्क में शामिल होने का प्रयास कर रहे हैं उसमें सुरक्षा समस्‍याएं हैं."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"उदाहरण के लिए, हो सकता है कि लॉगिन पृष्‍ठ दिखाए गए संगठन से संबद्ध ना हो."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"ब्राउज़र के द्वारा फिर जारी रखें"</string>
diff --git a/packages/CaptivePortalLogin/res/values-in/strings.xml b/packages/CaptivePortalLogin/res/values-in/strings.xml
index 7fa3a0a..f9f6481 100644
--- a/packages/CaptivePortalLogin/res/values-in/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-in/strings.xml
@@ -7,6 +7,6 @@
     <string name="action_bar_label" msgid="917235635415966620">"Masuk ke jaringan"</string>
     <string name="action_bar_title" msgid="5645564790486983117">"Login ke %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Jaringan yang ingin Anda masuki mengalami masalah keamanan."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Misalnya, laman masuk mungkin bukan milik organisasi yang ditampilkan."</string>
+    <string name="ssl_error_example" msgid="647898534624078900">"Misalnya, halaman masuk mungkin bukan milik organisasi yang ditampilkan."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Tetap lanjutkan melalui browser"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-pa/strings.xml b/packages/CaptivePortalLogin/res/values-pa/strings.xml
index c1b014c..03e252f 100644
--- a/packages/CaptivePortalLogin/res/values-pa/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-pa/strings.xml
@@ -4,9 +4,9 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"ਇਸ ਨੈੱਟਵਰਕ ਨੂੰ ਉਵੇਂ ਵਰਤੋ ਜਿਵੇਂ ਇਹ ਹੈ"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"ਇਹ ਨੈੱਟਵਰਕ ਨਾ ਵਰਤੋ"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ਨੈੱਟਵਰਕ ਤੇ ਸਾਈਨ ਇਨ ਕਰੋ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s \'ਤੇ ਸਾਈਨ ਇਨ ਕਰੋ"</string>
+    <string name="action_bar_label" msgid="917235635415966620">"ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
+    <string name="action_bar_title" msgid="5645564790486983117">"%1$s \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"ਤੁਹਾਡੇ ਦੁਆਰਾ ਸ਼ਾਮਿਲ ਹੋਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੇ ਜਾ ਰਹੇ ਨੈੱਟਵਰਕ ਵਿੱਚ ਸੁਰੱਖਿਆ ਸੰਬੰਧੀ ਸਮੱਸਿਆਵਾਂ ਹਨ।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ਉਦਾਹਰਣ ਵੱਜੋਂ, ਲੌਗਇਨ ਪੰਨਾ ਦਿਖਾਈ ਗਈ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ਬ੍ਰਾਉਜ਼ਰ ਰਾਹੀਂ ਫਿਰ ਵੀ ਜਾਰੀ ਰੱਖੋ"</string>
+    <string name="ssl_error_example" msgid="647898534624078900">"ਉਦਾਹਰਣ ਵੱਜੋਂ, ਲੌਗ-ਇਨ ਪੰਨਾ ਦਿਖਾਈ ਗਈ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
+    <string name="ssl_error_continue" msgid="6492718244923937110">"ਬ੍ਰਾਊਜ਼ਰ ਰਾਹੀਂ ਫਿਰ ਵੀ ਜਾਰੀ ਰੱਖੋ"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index e13aba7..35c6a99 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -62,7 +62,6 @@
 import java.lang.reflect.Method;
 import java.util.Objects;
 import java.util.Random;
-import java.util.concurrent.atomic.AtomicBoolean;
 
 public class CaptivePortalLoginActivity extends Activity {
     private static final String TAG = CaptivePortalLoginActivity.class.getSimpleName();
@@ -88,8 +87,6 @@
     private ConnectivityManager mCm;
     private boolean mLaunchBrowser = false;
     private MyWebViewClient mWebViewClient;
-    // Ensures that done() happens once exactly, handling concurrent callers with atomic operations.
-    private final AtomicBoolean isDone = new AtomicBoolean(false);
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -186,13 +183,13 @@
     }
 
     private void done(Result result) {
-        if (isDone.getAndSet(true)) {
-            // isDone was already true: done() already called
-            return;
-        }
         if (DBG) {
             Log.d(TAG, String.format("Result %s for %s", result.name(), mUrl.toString()));
         }
+        if (mNetworkCallback != null) {
+            mCm.unregisterNetworkCallback(mNetworkCallback);
+            mNetworkCallback = null;
+        }
         logMetricsEvent(result.metricsEvent);
         switch (result) {
             case DISMISSED:
@@ -252,8 +249,8 @@
     public void onDestroy() {
         super.onDestroy();
         if (mNetworkCallback != null) {
-            // mNetworkCallback is not null if mUrl is not null.
             mCm.unregisterNetworkCallback(mNetworkCallback);
+            mNetworkCallback = null;
         }
         if (mLaunchBrowser) {
             // Give time for this network to become default. After 500ms just proceed.
diff --git a/packages/CarrierDefaultApp/AndroidManifest.xml b/packages/CarrierDefaultApp/AndroidManifest.xml
index c309133..1cd7b61 100644
--- a/packages/CarrierDefaultApp/AndroidManifest.xml
+++ b/packages/CarrierDefaultApp/AndroidManifest.xml
@@ -34,6 +34,7 @@
             <intent-filter>
                 <action android:name="com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED" />
                 <action android:name="com.android.internal.telephony.CARRIER_SIGNAL_RESET" />
+                <action android:name="com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE" />
                 <action android:name="android.intent.action.LOCALE_CHANGED" />
             </intent-filter>
         </receiver>
@@ -43,10 +44,24 @@
             android:name="com.android.carrierdefaultapp.CaptivePortalLoginActivity"
             android:label="@string/action_bar_label"
             android:theme="@style/AppTheme"
-            android:configChanges="keyboardHidden|orientation|screenSize" >
+            android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <category android:name="android.intent.category.DEFAULT"/>
             </intent-filter>
         </activity>
+
+        <activity-alias
+            android:name="com.android.carrierdefaultapp.URLHandlerActivity"
+            android:targetActivity="com.android.carrierdefaultapp.CaptivePortalLoginActivity"
+            android:enabled="false" >
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="http" />
+                <data android:scheme="https" />
+                <data android:host="*" />
+            </intent-filter>
+        </activity-alias>
     </application>
 </manifest>
diff --git a/packages/CarrierDefaultApp/res/values-af/strings.xml b/packages/CarrierDefaultApp/res/values-af/strings.xml
index 8cff2fa..51cb6c8 100644
--- a/packages/CarrierDefaultApp/res/values-af/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-af/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Jou mobiele data is gedeaktiveer"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Tik om die %s-webwerf te besoek"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Kontak asseblief jou diensverskaffer %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Geen mobiele dataverbinding nie"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Voeg data of swerwingplan by deur %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status van mobiele data"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Meld by mobiele netwerk aan"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Die netwerk waarby jy probeer aansluit, het sekuriteitkwessies."</string>
diff --git a/packages/CarrierDefaultApp/res/values-am/strings.xml b/packages/CarrierDefaultApp/res/values-am/strings.xml
index 8326b4c..d5d50ac 100644
--- a/packages/CarrierDefaultApp/res/values-am/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-am/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"የእርስዎ የተንቀሳቃሽ ስልክ ውሂብ ቦዝኗል"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"የ%s ድር-ጣቢያን ለመጎብኘት መታ ያድርጉ"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"እባክዎ የአገልግሎት አቅራቢዎን %s ያነጋግሩ"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"ምንም የተንቀሳቃሽ ስልክ ውሂብ ግንኙነት የለም"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"በ%s በኩል ውሂብ ወይም ተንዣባቢ ዕቅድ ያክሉ"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"የተንቀሳቃሽ ስልክ ውሂብ ሁኔታ"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"ወደ የተንቀሳቃሽ ስልክ አውታረ መረብ ይግቡ"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"ለመቀላቀል እየሞከሩ ያሉት አውታረ መረብ የደህንነት ችግሮች አሉበት።"</string>
diff --git a/packages/CarrierDefaultApp/res/values-ar/strings.xml b/packages/CarrierDefaultApp/res/values-ar/strings.xml
index 4257a31..8db4560 100644
--- a/packages/CarrierDefaultApp/res/values-ar/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ar/strings.xml
@@ -7,6 +7,10 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"تم إلغاء تنشيط بيانات الجوال"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"‏النقر للانتقال إلى موقع %s الإلكتروني"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"‏يُرجى الاتصال بمقدم الخدمة %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"لا يوجد اتصال بيانات الجوال"</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for no_mobile_data_connection (544980465184147010) -->
+    <skip />
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"حالة بيانات الجوّال"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"تسجيل الدخول إلى شبكة الجوّال"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"الشبكة التي تحاول الانضمام إليها بها مشكلات أمنية."</string>
diff --git a/packages/CarrierDefaultApp/res/values-az/strings.xml b/packages/CarrierDefaultApp/res/values-az/strings.xml
index 911bb77..d1af3c9 100644
--- a/packages/CarrierDefaultApp/res/values-az/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-az/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Mobil data deaktiv edilib"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s veb saytına daxil olmaq üçün klikləyin"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Xidmət provayderi ilə əlaqə saxlayın %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Mobil data bağlantısı yoxdur"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Data və ya rominq planını %s vasitəsilə əlavə edin"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobil data statusu"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Mobil şəbəkəyə daxil olun"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Qoşulmaq istədiyiniz şəbəkənin təhlükəsizlik problemləri var."</string>
diff --git a/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml b/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
index e78fca3..0492685 100644
--- a/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
@@ -7,12 +7,9 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Mobilni podaci su deaktivirani"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Dodirnite da biste posetili veb-sajt %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Kontaktirajte dobavljača usluge %s"</string>
-    <!-- no translation found for action_bar_label (4290345990334377177) -->
-    <skip />
-    <!-- no translation found for ssl_error_warning (3127935140338254180) -->
-    <skip />
-    <!-- no translation found for ssl_error_example (6188711843183058764) -->
-    <skip />
-    <!-- no translation found for ssl_error_continue (1138548463994095584) -->
-    <skip />
+    <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status mobilnih podataka"</string>
+    <string name="action_bar_label" msgid="4290345990334377177">"Prijavite se na mobilnu mrežu"</string>
+    <string name="ssl_error_warning" msgid="3127935140338254180">"Mreža kojoj pokušavate da se pridružite ima bezbednosnih problema."</string>
+    <string name="ssl_error_example" msgid="6188711843183058764">"Na primer, stranica za prijavljivanje možda ne pripada prikazanoj organizaciji."</string>
+    <string name="ssl_error_continue" msgid="1138548463994095584">"Ipak nastavi preko pregledača"</string>
 </resources>
diff --git a/packages/CarrierDefaultApp/res/values-be/strings.xml b/packages/CarrierDefaultApp/res/values-be/strings.xml
index c46d0da..12677f2 100644
--- a/packages/CarrierDefaultApp/res/values-be/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-be/strings.xml
@@ -7,12 +7,9 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Перадача мабільных даных была дэактывавана"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Дакраніцеся, каб наведаць вэб-сайт %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Звярніцеся да свайго пастаўшчыка паслуг %s"</string>
-    <!-- no translation found for action_bar_label (4290345990334377177) -->
-    <skip />
-    <!-- no translation found for ssl_error_warning (3127935140338254180) -->
-    <skip />
-    <!-- no translation found for ssl_error_example (6188711843183058764) -->
-    <skip />
-    <!-- no translation found for ssl_error_continue (1138548463994095584) -->
-    <skip />
+    <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Статус мабільнага трафіка"</string>
+    <string name="action_bar_label" msgid="4290345990334377177">"Увайсці ў мабільную сетку"</string>
+    <string name="ssl_error_warning" msgid="3127935140338254180">"У сеткі, да якой вы спрабуеце далучыцца, ёсць праблемы з бяспекай."</string>
+    <string name="ssl_error_example" msgid="6188711843183058764">"Напрыклад, старонка ўваходу можа не належаць указанай арганізацыі."</string>
+    <string name="ssl_error_continue" msgid="1138548463994095584">"Усё роўна працягнуць праз браўзер"</string>
 </resources>
diff --git a/packages/CarrierDefaultApp/res/values-bg/strings.xml b/packages/CarrierDefaultApp/res/values-bg/strings.xml
index 5f6f818..f5308f0 100644
--- a/packages/CarrierDefaultApp/res/values-bg/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-bg/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Мобилните ви данни са деактивирани"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Докоснете, за да посетите уебсайта на %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Моля, свържете се с доставчика си на услуги %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Няма мобилна връзка за данни"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Добавете план за пренос на данни или за роуминг чрез %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Състояние на мобилните данни"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Вход в мобилна мрежа"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Мрежата, към която опитвате да се присъедините, има проблеми със сигурността."</string>
diff --git a/packages/CarrierDefaultApp/res/values-bn/strings.xml b/packages/CarrierDefaultApp/res/values-bn/strings.xml
index 5d6f077..448c42b 100644
--- a/packages/CarrierDefaultApp/res/values-bn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-bn/strings.xml
@@ -7,9 +7,11 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"আপনার মোবাইল ডেটা নিষ্ক্রিয় করা হয়েছে"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s এর ওয়েবসাইটটি দেখার জন্য ট্যাপ করুন"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"অনুগ্রহ করে আপনার পরিষেবা প্রদানকারী %s এর সাথে যোগাযোগ করুন"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"কোনও মোবাইল ডেটা সংযোগ নেই"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s এর মাধ্যমে ডেটা অথবা রোমিং পরিকল্পনা যোগ করুন"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"মোবাইল ডেটার স্ট্যাটাস"</string>
-    <string name="action_bar_label" msgid="4290345990334377177">"মোবাইল নেটওয়ার্কে প্রবেশ করুন"</string>
+    <string name="action_bar_label" msgid="4290345990334377177">"মোবাইল নেটওয়ার্কে সাইন-ইন করুন"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"আপনি যে নেটওয়ার্কে যোগ দেওয়ার চেষ্টা করছেন সেটিতে নিরাপত্তাজনিত সমস্যা আছে।"</string>
-    <string name="ssl_error_example" msgid="6188711843183058764">"যেমন, লগইন পৃষ্ঠাটি যে প্রতিষ্ঠানের পৃষ্ঠা বলে দেখানো আছে, আসলে তা নাও হতে পারে৷"</string>
+    <string name="ssl_error_example" msgid="6188711843183058764">"যেমন, লগ-ইন পৃষ্ঠাটি যে প্রতিষ্ঠানের পৃষ্ঠা বলে দেখানো আছে, আসলে তা নাও হতে পারে৷"</string>
     <string name="ssl_error_continue" msgid="1138548463994095584">"যাই হোক, ব্রাউজারের মাধ্যমে চালিয়ে যান"</string>
 </resources>
diff --git a/packages/CarrierDefaultApp/res/values-bs/strings.xml b/packages/CarrierDefaultApp/res/values-bs/strings.xml
index ba9863f..110924f 100644
--- a/packages/CarrierDefaultApp/res/values-bs/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-bs/strings.xml
@@ -7,12 +7,9 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Prijenos mobilnih podataka je deaktiviran"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Dodirnite da posjetite %s web lokaciju"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Obratite se pružaocu usluga %s"</string>
-    <!-- no translation found for action_bar_label (4290345990334377177) -->
-    <skip />
-    <!-- no translation found for ssl_error_warning (3127935140338254180) -->
-    <skip />
-    <!-- no translation found for ssl_error_example (6188711843183058764) -->
-    <skip />
-    <!-- no translation found for ssl_error_continue (1138548463994095584) -->
-    <skip />
+    <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status mobilnih podataka"</string>
+    <string name="action_bar_label" msgid="4290345990334377177">"Prijava na mobilnu mrežu"</string>
+    <string name="ssl_error_warning" msgid="3127935140338254180">"Mreža kojoj pokušavate pristupiti ima sigurnosnih problema."</string>
+    <string name="ssl_error_example" msgid="6188711843183058764">"Naprimjer, stranica za prijavljivanje možda ne pripada prikazanoj organizaciji."</string>
+    <string name="ssl_error_continue" msgid="1138548463994095584">"Ipak nastavi preko preglednika"</string>
 </resources>
diff --git a/packages/CarrierDefaultApp/res/values-ca/strings.xml b/packages/CarrierDefaultApp/res/values-ca/strings.xml
index 54859e0..66a8f37 100644
--- a/packages/CarrierDefaultApp/res/values-ca/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ca/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"S\'han desactivat les dades mòbils"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Toca per visitar el lloc web de: %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Contacta amb el teu proveïdor de serveis: %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"No hi ha connexió de dades mòbils"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Afegeix un pla de dades o d\'itinerància amb %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Estat de les dades mòbils"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Inicia la sessió a la xarxa mòbil"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"La xarxa a què et vols connectar té problemes de seguretat."</string>
diff --git a/packages/CarrierDefaultApp/res/values-cs/strings.xml b/packages/CarrierDefaultApp/res/values-cs/strings.xml
index a3ad316..5431836 100644
--- a/packages/CarrierDefaultApp/res/values-cs/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-cs/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Mobilní data byla deaktivována"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Klepnutím přejdete na web %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Kontaktujte poskytovatele služeb %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Žádné připojení přes mobilní data"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Přidejte data nebo tarif roamingu prostřednictvím aplikace %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Stav mobilních dat"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Přihlásit se k mobilní síti"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Síť, ke které se pokoušíte připojit, má bezpečnostní problémy."</string>
diff --git a/packages/CarrierDefaultApp/res/values-da/strings.xml b/packages/CarrierDefaultApp/res/values-da/strings.xml
index 8d831d5..b212117 100644
--- a/packages/CarrierDefaultApp/res/values-da/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-da/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Mobildata er blevet deaktiveret"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Tryk for at besøge websitet for %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Kontakt din tjenesteudbyder %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Der er ingen mobildataforbindelse"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Tilføj data- eller roamingabonnement via %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status for mobildata"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Log ind på mobilnetværk"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Der er sikkerhedsproblemer på det netværk, du forsøger at logge ind på."</string>
diff --git a/packages/CarrierDefaultApp/res/values-de/strings.xml b/packages/CarrierDefaultApp/res/values-de/strings.xml
index 8b8ca3f..927b8f0 100644
--- a/packages/CarrierDefaultApp/res/values-de/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-de/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Deine mobilen Daten wurden deaktiviert"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Tippe, um die Website \"%s\" zu besuchen"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Bitte wende dich an deinen Internetanbieter %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Keine mobile Datenverbindung"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Daten- oder Roaming-Tarif über %s hinzufügen"</string>
     <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>
diff --git a/packages/CarrierDefaultApp/res/values-el/strings.xml b/packages/CarrierDefaultApp/res/values-el/strings.xml
index 064941e..a13f634 100644
--- a/packages/CarrierDefaultApp/res/values-el/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-el/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Τα δεδομένα κινητής τηλεφωνίας έχουν απενεργοποιηθεί"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Πατήστε για να επισκεφτείτε τον ιστότοπο %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Επικοινωνήστε με τον παροχέα υπηρεσιών σας %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Δεν υπάρχει σύνδεση δεδομένων κινητής τηλεφωνίας"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Προσθήκη δεδομένων ή προγράμματος περιαγωγής μέσω του %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Κατάσταση δεδομένων κινητής τηλεφωνίας"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Σύνδεση σε δίκτυο κινητής τηλεφωνίας"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Παρουσιάζονται προβλήματα ασφάλειας στο δίκτυο στο οποίο προσπαθείτε να συνδεθείτε."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml b/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml
index 666c6759..a925a30 100644
--- a/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Tap to visit the %s website"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Please contact your service provider %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"No mobile data connection"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Add data or roaming plan through %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobile data status"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Sign in to mobile network"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"The network that you’re trying to join has security issues."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml b/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml
index 666c6759..a925a30 100644
--- a/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Tap to visit the %s website"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Please contact your service provider %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"No mobile data connection"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Add data or roaming plan through %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobile data status"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Sign in to mobile network"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"The network that you’re trying to join has security issues."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml b/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml
index 666c6759..a925a30 100644
--- a/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Tap to visit the %s website"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Please contact your service provider %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"No mobile data connection"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Add data or roaming plan through %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobile data status"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Sign in to mobile network"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"The network that you’re trying to join has security issues."</string>
diff --git a/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml b/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml
index 041421c..0455603 100644
--- a/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Se desactivaron los datos móviles"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Presiona para visitar el sitio web de %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Comunícate con tu proveedor de servicios %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"No hay conexión de datos móviles"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Agregar plan de roaming o datos mediante %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Estado de datos móviles"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Acceder a una red móvil"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"La red a la que intentas conectarte tiene problemas de seguridad."</string>
diff --git a/packages/CarrierDefaultApp/res/values-es/strings.xml b/packages/CarrierDefaultApp/res/values-es/strings.xml
index 7a0623f..b5d038c 100644
--- a/packages/CarrierDefaultApp/res/values-es/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-es/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Se han desactivado los datos móviles"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Toca para acceder al sitio web de %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Ponte en contacto con tu proveedor de servicios (%s)"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Sin conexión de datos móviles"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Añade un plan de datos o de itinerancia a través de %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Estado de la conexión de datos móviles"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Iniciar sesión en una red móvil"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"La red a la que intentas unirte tiene problemas de seguridad."</string>
diff --git a/packages/CarrierDefaultApp/res/values-et/strings.xml b/packages/CarrierDefaultApp/res/values-et/strings.xml
index 1404c86..28cc9a9 100644
--- a/packages/CarrierDefaultApp/res/values-et/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-et/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Teie mobiilne andmeside on inaktiveeritud"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Puudutage teenuse %s veebisaidi külastamiseks"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Võtke ühendust teenusepakkujaga %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Mobiilne andmesideühendus puudub"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Lisage andmed või rändluspakett teenuse %s kaudu"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobiilse andmeside olek"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Logi mobiilsidevõrku sisse"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Võrgul, millega üritate ühenduse luua, on turvaprobleeme."</string>
diff --git a/packages/CarrierDefaultApp/res/values-eu/strings.xml b/packages/CarrierDefaultApp/res/values-eu/strings.xml
index 63005ca..abd0696 100644
--- a/packages/CarrierDefaultApp/res/values-eu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-eu/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Desaktibatu da datu-konexioa"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Sakatu hau %s gunera joateko"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Jarri harremanetan %s operadorearekin"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Ez dago datu-konexiorik"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Gehitu datuak eta ibiltaritza-plana %s bidez"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Datu mugikorren egoera"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Hasi saioa sare mugikorrean"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Erabili nahi duzun sareak segurtasun-arazoak ditu."</string>
diff --git a/packages/CarrierDefaultApp/res/values-fa/strings.xml b/packages/CarrierDefaultApp/res/values-fa/strings.xml
index e15fa35..70ad837 100644
--- a/packages/CarrierDefaultApp/res/values-fa/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fa/strings.xml
@@ -9,6 +9,8 @@
     <!-- String.format failed for translation -->
     <!-- no translation found for no_data_notification_detail (3112125343857014825) -->
     <skip />
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"بدون اتصال داده دستگاه همراه"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"‏افزودن طرح داده یا رومینگ ازطریق %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"وضعیت داده تلفن همراه"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"ورود به سیستم شبکه تلفن همراه"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"شبکه‌ای که می‌خواهید به آن بپیوندید مشکلات امنیتی دارد."</string>
diff --git a/packages/CarrierDefaultApp/res/values-fi/strings.xml b/packages/CarrierDefaultApp/res/values-fi/strings.xml
index ddf3a14..d416c1d 100644
--- a/packages/CarrierDefaultApp/res/values-fi/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fi/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Mobiilidata poistettu käytöstä"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Siirry sivustolle %s napauttamalla."</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Ota yhteyttä palveluntarjoajaan %s."</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Ei mobiiliyhteyttä"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Lisää mobiilidata- tai roamingpaketti operaattoriisi %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobiilidatan tila"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Kirjaudu mobiiliverkkoon"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Verkossa, johon yrität muodostaa yhteyttä, havaittiin turvallisuusongelmia."</string>
diff --git a/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml b/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
index 3e4802a..1b8c262 100644
--- a/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Les données cellulaires ont été désactivées pour votre compte"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Touchez ici pour visiter le site Web de %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Veuillez communiquer avec votre fournisseur de services %s."</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Aucune connexion de données cellulaires"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Ajouter un forfait de données ou d\'itinérance auprès de %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"État des données cellulaires"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Connexion au réseau cellulaire"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Le réseau que vous essayez de joindre présente des problèmes de sécurité."</string>
diff --git a/packages/CarrierDefaultApp/res/values-fr/strings.xml b/packages/CarrierDefaultApp/res/values-fr/strings.xml
index 804c400..3ae9570 100644
--- a/packages/CarrierDefaultApp/res/values-fr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fr/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Les données mobiles ont été désactivées pour votre compte"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Appuyez ici pour consulter le site Web suivant : %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Veuillez contacter votre fournisseur de services, %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Aucune connexion de données mobiles"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Ajouter un forfait Internet national ou international via %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"État des données mobiles"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Se connecter au réseau mobile"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Le réseau auquel vous essayez de vous connecter présente des problèmes de sécurité."</string>
diff --git a/packages/CarrierDefaultApp/res/values-gl/strings.xml b/packages/CarrierDefaultApp/res/values-gl/strings.xml
index 91c3073..4f199ca 100644
--- a/packages/CarrierDefaultApp/res/values-gl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-gl/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Desactiváronse os datos móbiles"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Toca para acceder ao sitio web de %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Ponte en contacto co teu fornecedor de servizo %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Non hai conexión de datos móbiles"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Engadir plan de datos ou itinerancia a través de %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Estado dos datos móbiles"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Iniciar sesión na rede de telefonía móbil"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"A rede á que tentas unirte ten problemas de seguranza."</string>
diff --git a/packages/CarrierDefaultApp/res/values-gu/strings.xml b/packages/CarrierDefaultApp/res/values-gu/strings.xml
index 9f68aa4..57710d0 100644
--- a/packages/CarrierDefaultApp/res/values-gu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-gu/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"તમારો મોબાઇલ ડેટા નિષ્ક્રિય કરવામાં આવ્યો છે"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s વેબસાઇટની મુલાકાત લેવા માટે ટૅપ કરો"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"કૃપા કરીને તમારા સેવા પ્રદાતા %sનો સંપર્ક કરો"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"કોઈ મોબાઇલ ડેટા કનેક્શન નથી"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s મારફતે ડેટા અથવા રોમિંગ પ્લાન ઉમેરો"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"મોબાઇલ ડેટાની સ્થિતિ"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"મોબાઇલ નેટવર્કમાં સાઇન ઇન કરો"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"તમે જોડાવાનો પ્રયાસ કરી રહ્યા છો તે નેટવર્કમાં સુરક્ષા સંબંધી સમસ્યાઓ છે."</string>
diff --git a/packages/CarrierDefaultApp/res/values-hi/strings.xml b/packages/CarrierDefaultApp/res/values-hi/strings.xml
index 0ca7980..b9d6f42 100644
--- a/packages/CarrierDefaultApp/res/values-hi/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hi/strings.xml
@@ -2,13 +2,15 @@
 <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="5247871339820894594">"CarrierDefaultApp"</string>
-    <string name="android_system_label" msgid="2797790869522345065">"मोबाइल वाहक"</string>
+    <string name="android_system_label" msgid="2797790869522345065">"मोबाइल सेवा देने वाली कंपनी"</string>
     <string name="portal_notification_id" msgid="5155057562457079297">"मोबाइल डेटा खत्म हो गया है"</string>
-    <string name="no_data_notification_id" msgid="668400731803969521">"आपका मोबाइल डेटा निष्क्रिय कर दिया गया है"</string>
+    <string name="no_data_notification_id" msgid="668400731803969521">"आपका मोबाइल डेटा बंद कर दिया गया है"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s वेबसाइट पर जाने के लिए टैप करें"</string>
-    <string name="no_data_notification_detail" msgid="3112125343857014825">"कृपया अपने सेवा प्रदाता %s से संपर्क करें"</string>
+    <string name="no_data_notification_detail" msgid="3112125343857014825">"कृपया अपने सेवा देने वाले %s से संपर्क करें"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"कोई भी मोबाइल डेटा कनेक्शन नहीं है"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s के ज़रिए डेटा या रोमिंग योजना जोड़ें"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"मोबाइल डेटा की स्थिति"</string>
-    <string name="action_bar_label" msgid="4290345990334377177">"मोबाइल नेटवर्क में प्रवेश करें"</string>
+    <string name="action_bar_label" msgid="4290345990334377177">"मोबाइल नेटवर्क में साइन इन करें"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"आप जिस नेटवर्क में शामिल होने की कोशिश कर रहे हैं उसमें सुरक्षा से जुड़ी समस्‍याएं हैं."</string>
     <string name="ssl_error_example" msgid="6188711843183058764">"उदाहरण के लिए, हो सकता है कि लॉगिन पेज दिखाए गए संगठन का ना हो."</string>
     <string name="ssl_error_continue" msgid="1138548463994095584">"ब्राउज़र के ज़रिए किसी भी तरह जारी रखें"</string>
diff --git a/packages/CarrierDefaultApp/res/values-hr/strings.xml b/packages/CarrierDefaultApp/res/values-hr/strings.xml
index 0f91cda..66531a7 100644
--- a/packages/CarrierDefaultApp/res/values-hr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hr/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Mobilni su podaci deaktivirani"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Dodirnite da biste posjetili web-lokaciju tvrtke %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Obratite se svojem davatelju usluga %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Nema podatkovne veza mobilnog uređaja"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Dodajte podatkovni ili roaming paket putem usluge %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status mobilnih podataka"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Prijava na mobilnu mrežu"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Mreža kojoj se pokušavate pridružiti ima sigurnosne poteškoće."</string>
diff --git a/packages/CarrierDefaultApp/res/values-hu/strings.xml b/packages/CarrierDefaultApp/res/values-hu/strings.xml
index 0afaeff..4ae6ea6 100644
--- a/packages/CarrierDefaultApp/res/values-hu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hu/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"A rendszer deaktiválta a mobiladat-forgalmat"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Koppintson a(z) %s webhely meglátogatásához"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Vegye fel a kapcsolatot szolgáltatójával (%s)"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Nincs mobiladat-kapcsolat"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Adjon hozzá előfizetést vagy barangolási csomagot a következőn keresztül: %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobiladat-állapot"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Bejelentkezés a mobilhálózatra"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Biztonsági problémák vannak azzal a hálózattal, amelyhez csatlakozni szeretne."</string>
diff --git a/packages/CarrierDefaultApp/res/values-hy/strings.xml b/packages/CarrierDefaultApp/res/values-hy/strings.xml
index d88e0df..99398bc 100644
--- a/packages/CarrierDefaultApp/res/values-hy/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hy/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Ձեր բջջային ինտերնետն ապակտիվացված է"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Հպեք՝ %s կայք այցելելու համար"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Դիմեք ձեր ծառայություններ մատուցողին %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Բջջային տվյալների կապ չկա"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Ավելացնել տվյալներ ռոումինգի սակագնային փաթեթին %s միջոցով"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Բջջային ինտերնետի կարգավիճակը"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Մուտք գործել բջջային ցանց"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Ցանցը, որին փորձում եք միանալ, անվտանգության խնդիրներ ունի:"</string>
diff --git a/packages/CarrierDefaultApp/res/values-in/strings.xml b/packages/CarrierDefaultApp/res/values-in/strings.xml
index 915933b..01a9c60 100644
--- a/packages/CarrierDefaultApp/res/values-in/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-in/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Data seluler telah dinonaktifkan"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Tap untuk membuka situs web %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Hubungi penyedia layanan %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Tidak ada sambungan data seluler"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Tambahkan paket data atau roaming melalui %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status data seluler"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Login ke jaringan seluler"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Jaringan yang ingin Anda masuki memiliki masalah keamanan."</string>
diff --git a/packages/CarrierDefaultApp/res/values-is/strings.xml b/packages/CarrierDefaultApp/res/values-is/strings.xml
index 8a74446..cdba5be 100644
--- a/packages/CarrierDefaultApp/res/values-is/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-is/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Slökkt hefur verið á farsímagögnum"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Ýttu til að fara á vefsvæði %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Hafðu samband við þjónustuaðilann %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Engin farsímagagnatenging"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Bættu við gagna- eða reikiáskrift hjá %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Staða farsímagagna"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Skrá inn á farsímakerfi"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Öryggisvandamál eru á netinu sem þú ert að reyna að tengjast."</string>
diff --git a/packages/CarrierDefaultApp/res/values-it/strings.xml b/packages/CarrierDefaultApp/res/values-it/strings.xml
index a6e004f..a62ae86 100644
--- a/packages/CarrierDefaultApp/res/values-it/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-it/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"I dati mobili sono stati disattivati"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Tocca per visitare il sito web %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Contatta il tuo operatore telefonico %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Nessuna connessione dati mobili"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Aggiungi un piano dati o roaming tramite %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Stato dati mobili"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Accedi alla rete mobile"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"La rete a cui stai tentando di accedere presenta problemi di sicurezza."</string>
diff --git a/packages/CarrierDefaultApp/res/values-iw/strings.xml b/packages/CarrierDefaultApp/res/values-iw/strings.xml
index ca42d33..550936c 100644
--- a/packages/CarrierDefaultApp/res/values-iw/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-iw/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"חבילת הגלישה שלך הושבתה"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"‏הקש כדי לעבור לאתר של %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"‏פנה לספק השירות %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"אין חיבור לחבילת גלישה"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"‏אפשר להוסיף חבילת גלישה או חבילת נדידה באמצעות %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"סטטוס חבילת הגלישה"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"היכנס לרשת סלולרית"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"יש בעיות אבטחה ברשת שאליה אתה מנסה להתחבר."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ja/strings.xml b/packages/CarrierDefaultApp/res/values-ja/strings.xml
index 8e046cb..e5977ae 100644
--- a/packages/CarrierDefaultApp/res/values-ja/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ja/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"モバイルデータが無効になっています"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"タップして %s のウェブサイトにアクセス"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"ご利用のサービス プロバイダ %s にお問い合わせください"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"モバイルデータ接続を利用できません"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s からデータプランまたはローミング プランを追加してください"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"モバイルデータのステータス"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"モバイル ネットワークにログイン"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"接続しようとしているネットワークにセキュリティの問題があります。"</string>
diff --git a/packages/CarrierDefaultApp/res/values-ka/strings.xml b/packages/CarrierDefaultApp/res/values-ka/strings.xml
index 68c4490..91ae46d 100644
--- a/packages/CarrierDefaultApp/res/values-ka/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ka/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"მობილური ინტერნეტი დეაქტივირებულია"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"შეეხეთ, რათა ეწვიოთ ვებსაიტს: %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"გთხოვთ, დაუკავშირდეთ სერვისის პროვაიდერს (%s)"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"მობილური ინტერნეტის კავშირი არ არის"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"დაამატეთ მობილური ინტერნეტის ან როუმინგის პაკეტი %s-ის მეშვეობით"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"მობილური ინტერნეტის სტატუსი"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"მობილურ ქსელში შესვლა"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"ქსელს, რომელთან დაკავშრებასაც ცდილობთ, უსაფრთხოების პრობლემები აქვს."</string>
diff --git a/packages/CarrierDefaultApp/res/values-kk/strings.xml b/packages/CarrierDefaultApp/res/values-kk/strings.xml
index 77555aa..0fb57bc 100644
--- a/packages/CarrierDefaultApp/res/values-kk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-kk/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Мобильдік деректер өшірілді"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s вебсайтына кіру үшін түртіңіз"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Қызмет көрсетушіге (%s) хабарласыңыз"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Мобильдік деректер байланысы жоқ"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s арқылы деректер не роуминг жоспарын енгізу"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Мобильді деректер күйі"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Мобильдік желіге тіркелу"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Қосылайын деп жатқан желіңізде қауіпсіздік мәселелері бар."</string>
diff --git a/packages/CarrierDefaultApp/res/values-km/strings.xml b/packages/CarrierDefaultApp/res/values-km/strings.xml
index 30984cd..6ef1066 100644
--- a/packages/CarrierDefaultApp/res/values-km/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-km/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"ទិន្នន័យ​ចល័ត​របស់អ្នក​ត្រូវបាន​បិទដំណើរការហើយ"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"ចុច​ដើម្បី​ចូលទៅកាន់គេហទំព័រ %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"សូម​ទាក់ទង​ទៅ​ក្រុមហ៊ុន​ផ្តល់​សេវា​របស់​អ្នក %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"មិន​មាន​ការតភ្ជាប់​ទិន្នន័យចល័តទេ"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"បញ្ចូលគម្រោង​ទិន្នន័យ ឬ​រ៉ូមីង​តាម​រយៈ %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"ស្ថានភាព​ទិន្នន័យ​ទូរសព្ទ​ចល័ត"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"ចូលទៅបណ្តាញទូរសព្ទចល័ត"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"បណ្តាញដែលអ្នកកំពុងព្យាយាមចូលមានបញ្ហាសុវត្ថិភាព។"</string>
diff --git a/packages/CarrierDefaultApp/res/values-kn/strings.xml b/packages/CarrierDefaultApp/res/values-kn/strings.xml
index ad83f38..73d0764 100644
--- a/packages/CarrierDefaultApp/res/values-kn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-kn/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"ನಿಮ್ಮ ಮೊಬೈಲ್ ಡೇಟಾ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s ವೆಬ್‌ಸೈಟ್‌ಗೆ ಭೇಟಿ ನೀಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"ನಿಮಗೆ ಸೇವೆ ಒದಗಿಸುವವರನ್ನು ದಯವಿಟ್ಟು ಸಂಪರ್ಕಿಸಿ %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"ಮೊಬೈಲ್ ಡೇಟಾ ಸಂಪರ್ಕವಿಲ್ಲ"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s ಮೂಲಕ ಡೇಟಾ ಅಥವಾ ರೋಮಿಂಗ್ ಪ್ಲ್ಯಾನ್ ಸೇರಿಸಿ"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"ಮೊಬೈಲ್ ಡೇಟಾ ಸ್ಥಿತಿ"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"ಮೊಬೈಲ್ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"ನೀವು ಸೇರಬೇಕೆಂದಿರುವ ನೆಟ್‌ವರ್ಕ್, ಭದ್ರತೆ ಸಮಸ್ಯೆಗಳನ್ನು ಹೊಂದಿದೆ."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ko/strings.xml b/packages/CarrierDefaultApp/res/values-ko/strings.xml
index a620e1c..d6b3d61 100644
--- a/packages/CarrierDefaultApp/res/values-ko/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ko/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"모바일 데이터가 비활성화되었습니다."</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s 웹사이트를 방문하려면 탭하세요."</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"서비스 제공업체 %s에 문의하세요."</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"모바일 데이터 연결 없음"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s을(를) 통해 데이터 또는 로밍 요금제 추가"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"모바일 데이터 상태"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"모바일 네트워크에 로그인"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"가입하려는 네트워크에 보안 문제가 있습니다."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ky/strings.xml b/packages/CarrierDefaultApp/res/values-ky/strings.xml
index 9e32f21..066e8f6 100644
--- a/packages/CarrierDefaultApp/res/values-ky/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ky/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Мобилдик Интернет өчүрүлгөн"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s сайтына баш багуу үчүн басыңыз"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"%s Интернет провайдери менен байланышыңыз"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Мобилдик Интернет жок"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s аркылуу дайындарды же роуминг планын кошуу"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Мобилдик Интернеттин абалы"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Мобилдик тармакка кирүү"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Кошулайын деген тармагыңызда коопсуздук көйгөйлөрү бар."</string>
diff --git a/packages/CarrierDefaultApp/res/values-lo/strings.xml b/packages/CarrierDefaultApp/res/values-lo/strings.xml
index 47a8d05e..4a21d7c 100644
--- a/packages/CarrierDefaultApp/res/values-lo/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-lo/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"ປິດການນຳໃຊ້ອິນເຕີເນັດມືຖືຂອງທ່ານແລ້ວ"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"ແຕະເພື່ອເຂົ້າເບິ່ງເວັບໄຊ %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"ກະລຸນາຕິດຕໍ່ຜູ້ໃຫ້ບໍລິການຂອງທ່ານ %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"ບໍ່ມີອິນເຕີເນັດມືຖື"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"ເພີ່ມແພັກເກດອິນເຕີເນັດ ຫຼື ແພັກເກດໂຣມມິງຜ່ານ %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"ສະຖານະຂໍ້ມູນມືຖື"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"ເຂົ້າສູ່ລະບົບເຄືອຂ່າຍມືຖື"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"ເຄືອຂ່າຍທີ່ທ່ານກຳລັງເຂົ້າຮ່ວມມີບັນຫາຄວາມປອດໄພ."</string>
diff --git a/packages/CarrierDefaultApp/res/values-lt/strings.xml b/packages/CarrierDefaultApp/res/values-lt/strings.xml
index 173a297..be452b7 100644
--- a/packages/CarrierDefaultApp/res/values-lt/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-lt/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Mobiliojo ryšio duomenys išaktyvinti"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Palieskite ir apsilankykite svetainėje %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Susisiekite su paslaugos teikėju „%s“"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Nėra mobiliojo duomenų ryšio"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Pridėkite duomenų ar tarptinklinio ryšio planą naudodami „%s“"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobiliojo ryšio duomenų būsena"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Prisijungti prie mobiliojo ryšio tinklo"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Kilo tinklo, prie kurio bandote prisijungti, saugos problemų."</string>
diff --git a/packages/CarrierDefaultApp/res/values-lv/strings.xml b/packages/CarrierDefaultApp/res/values-lv/strings.xml
index aadb5bc..80a9b58 100644
--- a/packages/CarrierDefaultApp/res/values-lv/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-lv/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Jūsu mobilie dati ir deaktivizēti"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Pieskarieties, lai apmeklētu %s vietni"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Lūdzu, sazinieties ar pakalpojuma sniedzēju %s."</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Nav mobilo datu savienojuma"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Pievienojiet datus vai viesabonēšanas plānu, izmantojot %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobilo datu statuss"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Pierakstīties mobilajā tīklā"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Tīklā, kuram mēģināt pievienoties, ir drošības problēmas."</string>
diff --git a/packages/CarrierDefaultApp/res/values-mk/strings.xml b/packages/CarrierDefaultApp/res/values-mk/strings.xml
index 5cb2837..96b222c 100644
--- a/packages/CarrierDefaultApp/res/values-mk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-mk/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Мобилниот интернет ви е деактивиран"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Допрете за да го посетите веб-сајтот на %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Контактирајте со давателот на услуги %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Нема врска со мобилен интернет"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Додајте пакет за интернет или роаминг преку %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Статус на мобилна мрежа"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Најавете се на мобилна мрежа"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Мрежата на која се обидувате да се придружите има проблеми со безбедноста."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ml/strings.xml b/packages/CarrierDefaultApp/res/values-ml/strings.xml
index 22f5fc4..ae08ade 100644
--- a/packages/CarrierDefaultApp/res/values-ml/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ml/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"നിങ്ങളുടെ മൊബൈൽ ഡാറ്റ നിർജീവമാക്കി"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s ‌എന്ന വെബ്‌സൈറ്റ് സന്ദർശിക്കാൻ ടാപ്പുചെയ്യുക"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"നിങ്ങളുടെ ‌%s എന്ന സേവന‌ദാതാവിനെ ‌ബന്ധപ്പെടുക"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"മൊബൈൽ ഡാറ്റ കണക്ഷൻ ഇല്ല"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s എന്നതിലൂടെ ഡാറ്റ അല്ലെങ്കിൽ റോമിംഗ് പ്ലാൻ ചേർക്കുക"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"മൊബൈൽ ഡാറ്റാ നില"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"മൊബൈൽ നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"നിങ്ങൾ ചേരാൻ ശ്രമിക്കുന്ന നെറ്റ്‌വർക്കിൽ സുരക്ഷാ പ്രശ്‌നങ്ങളുണ്ടായിരിക്കാം."</string>
diff --git a/packages/CarrierDefaultApp/res/values-mn/strings.xml b/packages/CarrierDefaultApp/res/values-mn/strings.xml
index 16613b4..1a9b72e 100644
--- a/packages/CarrierDefaultApp/res/values-mn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-mn/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Таны мобайл датаг идэвхгүй болгосон"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s вэб хуудсанд зочлохын тулд товших"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"%s үйлчилгээ үзүүлэгчтэйгээ холбогдоно уу"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Мобайл дата холболт алга"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Дата эсвэл роуминг төлөвлөгөөг %s-р нэмнэ үү"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Мобайл датаны төлөв"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Мобайл сүлжээнд нэвтрэх"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Таны холбогдох гэж буй сүлжээ аюулгүй байдлын асуудалтай байна."</string>
diff --git a/packages/CarrierDefaultApp/res/values-mr/strings.xml b/packages/CarrierDefaultApp/res/values-mr/strings.xml
index 53d7400..7e7792f 100644
--- a/packages/CarrierDefaultApp/res/values-mr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-mr/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"आपला मोबाइल डेटा निष्क्रिय केला गेला"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s वेबसाइटला भेट देण्‍यासाठी टॅप करा"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"कृपया आपल्या %s सेवा प्रदात्याशी संपर्क साधा"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"मोबाइल डेटा कनेक्‍शन नाही"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%sने डेटा किंवा रोमिंग प्‍लॅन जोडा"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"मोबाइल डेटा स्थिती"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"मोबाइल नेटवर्कमध्ये साइन इन करा"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"आपण ज्या नेटवर्कमध्‍ये सामील होण्याचा प्रयत्न करत आहात त्यात सुरक्षितता समस्या आहेत."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ms/strings.xml b/packages/CarrierDefaultApp/res/values-ms/strings.xml
index 202ad59..7aca5f0 100644
--- a/packages/CarrierDefaultApp/res/values-ms/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ms/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Data mudah alih anda telah dinyahaktifkan"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Ketik untuk melawat tapak web %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Sila hubungi penyedia perkhidmatan anda, %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Tiada sambungan data mudah alih"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Tambahkan data atau pelan perayauan melalui %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status data mudah alih"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Log masuk ke rangkaian mudah alih"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Rangkaian yang cuba anda sertai mempunyai isu keselamatan."</string>
diff --git a/packages/CarrierDefaultApp/res/values-my/strings.xml b/packages/CarrierDefaultApp/res/values-my/strings.xml
index 8767080..82372f9 100644
--- a/packages/CarrierDefaultApp/res/values-my/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-my/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"သင်၏ မိုဘိုင်း ဒေတာကို ပိတ်ထားပါသည်"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s ဝဘ်ဆိုက်ကို ကြည့်ရှုရန် တို့ပါ"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"သင်၏ဝန်ဆောင်မှုပေးသူ %s ကို ဆက်သွယ်ပါ"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"မိုဘိုင်း ဒေတာချိတ်ဆက်မှုမရှိပါ"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"ဒေတာပလန် သို့မဟုတ် နိုင်ငံကူးလူးဖုန်းပလန်ကို %s မှ တစ်ဆင့် ထည့်ပါ"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"မိုဘိုင်းဒေတာ အခြေအနေ"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"မိုဘိုင်းကွန်ရက်သို့ လက်မှတ်ထိုးဝင်ပါ"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"သင်ချိတ်ဆက်ရန် ကြိုးစားနေသည့် ကွန်ရက်တွင် လုံခြုံရေးပြဿနာများ ရှိနေသည်။"</string>
diff --git a/packages/CarrierDefaultApp/res/values-nb/strings.xml b/packages/CarrierDefaultApp/res/values-nb/strings.xml
index 57d58a5..1bb9826 100644
--- a/packages/CarrierDefaultApp/res/values-nb/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-nb/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Mobildata er deaktivert"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Trykk for å besøke %s-nettstedet"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Ta kontakt med tjenesteleverandøren din, %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Ingen mobildatatilkobling"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Legg til data- eller roamingabonnement via %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status for mobildata"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Logg på mobilnettverk"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Nettverket du prøver å logge på, har sikkerhetsproblemer."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ne/strings.xml b/packages/CarrierDefaultApp/res/values-ne/strings.xml
index 1070a62..2349f9d 100644
--- a/packages/CarrierDefaultApp/res/values-ne/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ne/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"तपाईंको मोबाइल डेटा निष्क्रिय पारिएको छ"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s वेबसाइटमा जानका लागि ट्याप गर्नुहोस्"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"कृपया आफ्नो सेवा प्रदायक %s लाई सम्पर्क गर्नुहोस्"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"कुनै पनि मोबाइल डेटाको जडान उपलब्ध छैन"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s मार्फत डेटा वा रोमिङ योजना थप्नुहोस्"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"मोबाइल डेटाको स्थिति"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"मोबाइल नेटवर्कमा साइन इन गर्नुहोस्"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"तपाईंले सामेल हुने प्रयास गरिरहनु भएको नेटवर्कमा सुरक्षा सम्बन्धी समस्याहरू छन्।"</string>
diff --git a/packages/CarrierDefaultApp/res/values-nl/strings.xml b/packages/CarrierDefaultApp/res/values-nl/strings.xml
index b4991ac..4e2c09b 100644
--- a/packages/CarrierDefaultApp/res/values-nl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-nl/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Je mobiele data zijn uitgeschakeld"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Tik om de website van %s te bezoeken"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Neem contact op met je serviceprovider %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Geen mobiele internetverbinding"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Data- of roaming-abonnement toevoegen via %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status van mobiele data"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Inloggen bij mobiel netwerk"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Het netwerk waarmee je verbinding probeert te maken, heeft beveiligingsproblemen."</string>
diff --git a/packages/CarrierDefaultApp/res/values-pa/strings.xml b/packages/CarrierDefaultApp/res/values-pa/strings.xml
index 6b754c1..f4d4053 100644
--- a/packages/CarrierDefaultApp/res/values-pa/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pa/strings.xml
@@ -3,13 +3,15 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
     <string name="android_system_label" msgid="2797790869522345065">"ਮੋਬਾਈਲ ਕੈਰੀਅਰ"</string>
-    <string name="portal_notification_id" msgid="5155057562457079297">"ਮੋਬਾਈਲ ਡੈਟਾ ਖਤਮ ਹੋ ਗਿਆ ਹੈ"</string>
-    <string name="no_data_notification_id" msgid="668400731803969521">"ਤੁਹਾਡਾ ਮੋਬਾਈਲ ਡੈਟਾ ਅਕਿਰਿਆਸ਼ੀਲ ਕਰ ਦਿੱਤਾ ਗਿਆ ਹੈ"</string>
+    <string name="portal_notification_id" msgid="5155057562457079297">"ਮੋਬਾਈਲ ਡਾਟਾ ਖਤਮ ਹੋ ਗਿਆ ਹੈ"</string>
+    <string name="no_data_notification_id" msgid="668400731803969521">"ਤੁਹਾਡਾ ਮੋਬਾਈਲ ਡਾਟਾ ਅਕਿਰਿਆਸ਼ੀਲ ਕਰ ਦਿੱਤਾ ਗਿਆ ਹੈ"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s ਵੈੱਬਸਾਈਟ \'ਤੇ ਜਾਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"ਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਸੇਵਾ ਪ੍ਰਦਾਨਕ %s ਨੂੰ ਸੰਪਰਕ ਕਰੋ"</string>
-    <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"ਮੋਬਾਈਲ ਡੈਟੇ ਦੀ ਅਵਸਥਾ"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"ਕੋਈ ਮੋਬਾਈਲ ਡਾਟਾ ਕਨੈਕਸ਼ਨ ਨਹੀਂ"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s ਰਾਹੀਂ ਡਾਟਾ ਜਾਂ ਰੋਮਿੰਗ ਯੋਜਨਾ ਸ਼ਾਮਲ ਕਰੋ"</string>
+    <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"ਮੋਬਾਈਲ ਡਾਟੇ ਦੀ ਸਥਿਤੀ"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਵਿੱਚ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"ਤੁਸੀਂ ਜਿਸ ਨੈੱਟਵਰਕ ਵਿੱਚ ਸ਼ਾਮਲ ਹੋਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰ ਰਹੇ ਹੋ ਉਸ ਵਿੱਚ ਸੁਰੱਖਿਆ ਸਬੰਧੀ ਸਮੱਸਿਆਵਾਂ ਹਨ।"</string>
-    <string name="ssl_error_example" msgid="6188711843183058764">"ਉਦਾਹਰਣ ਵਜੋਂ, ਹੋ ਸਕਦਾ ਹੈ ਲੌਗਇਨ ਪੰਨਾ ਦਿਖਾਈ ਗਈ ਸੰਸਥਾ ਨਾਲ ਸਬੰਧਿਤ ਨਾ ਹੋਵੇ।"</string>
-    <string name="ssl_error_continue" msgid="1138548463994095584">"ਫਿਰ ਵੀ ਬ੍ਰਾਊਜ਼ਰ ਰਾਹੀਂ ਜਾਰੀ ਰੱਖੋ"</string>
+    <string name="ssl_error_example" msgid="6188711843183058764">"ਉਦਾਹਰਣ ਵੱਜੋਂ, ਲੌਗ-ਇਨ ਪੰਨਾ ਦਿਖਾਈ ਗਈ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
+    <string name="ssl_error_continue" msgid="1138548463994095584">"ਬ੍ਰਾਊਜ਼ਰ ਰਾਹੀਂ ਫਿਰ ਵੀ ਜਾਰੀ ਰੱਖੋ"</string>
 </resources>
diff --git a/packages/CarrierDefaultApp/res/values-pl/strings.xml b/packages/CarrierDefaultApp/res/values-pl/strings.xml
index 427e12a..ac45e27 100644
--- a/packages/CarrierDefaultApp/res/values-pl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pl/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Mobilna transmisja danych została wyłączona"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Kliknij, by odwiedzić stronę: %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Skontaktuj się z operatorem %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Brak połączenia mobilnej transmisji danych"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Dodaj abonament lub roaming w: %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Stan danych mobilnych"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Zaloguj się w sieci komórkowej"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"W sieci, z którą próbujesz się połączyć, występują problemy z zabezpieczeniami."</string>
diff --git a/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml b/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml
index 1028ef82..926de65 100644
--- a/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Os dados móveis foram desativados"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Toque para visitar o website %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Entre em contato com seu provedor de serviços %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Sem conexão de dados móveis"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Adicionar plano de roaming ou dados por meio de %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status dos dados móveis"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Fazer login na rede móvel"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"A rede à qual você está tentando se conectar tem problemas de segurança."</string>
diff --git a/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml b/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml
index 0f42e01..107a9c2 100644
--- a/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Os seus dados móveis foram desativados"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Tocar para aceder ao Website %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Contacte o seu fornecedor de serviços %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Sem ligação de dados móveis"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Adicionar dados ou um plano de roaming através de %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Estado dos dados móveis"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Iniciar sessão na rede móvel"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"A rede à qual está a tentar aceder tem problemas de segurança."</string>
diff --git a/packages/CarrierDefaultApp/res/values-pt/strings.xml b/packages/CarrierDefaultApp/res/values-pt/strings.xml
index 1028ef82..926de65 100644
--- a/packages/CarrierDefaultApp/res/values-pt/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pt/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Os dados móveis foram desativados"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Toque para visitar o website %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Entre em contato com seu provedor de serviços %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Sem conexão de dados móveis"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Adicionar plano de roaming ou dados por meio de %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status dos dados móveis"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Fazer login na rede móvel"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"A rede à qual você está tentando se conectar tem problemas de segurança."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ro/strings.xml b/packages/CarrierDefaultApp/res/values-ro/strings.xml
index 5a1f9f4..b91aa813 100644
--- a/packages/CarrierDefaultApp/res/values-ro/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ro/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Datele mobile au fost dezactivate"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Atingeți pentru a accesa site-ul %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Contactați furnizorul de servicii %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Nu există o conexiune de date mobile"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Adăugați un plan de date sau de roaming prin %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Starea datelor mobile"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Conectați-vă la rețeaua mobilă"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Rețeaua la care încercați să vă conectați are probleme de securitate."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ru/strings.xml b/packages/CarrierDefaultApp/res/values-ru/strings.xml
index 9436d61..ff24f1f 100644
--- a/packages/CarrierDefaultApp/res/values-ru/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ru/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Мобильный Интернет отключен"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Нажмите, чтобы открыть сайт %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Обратитесь к своему поставщику услуг \"%s\""</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Отсутствует подключение к мобильной сети"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Активировать мобильный Интернет или интернет-роуминг с помощью оператора \"%s\""</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Состояние мобильного Интернета"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Подключиться к мобильной сети"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Сеть, к которой вы хотите подключиться, небезопасна."</string>
diff --git a/packages/CarrierDefaultApp/res/values-si/strings.xml b/packages/CarrierDefaultApp/res/values-si/strings.xml
index a31e5c4..378a534 100644
--- a/packages/CarrierDefaultApp/res/values-si/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-si/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"ඔබගේ ජංගම දත්ත අක්‍රිය කර ඇත"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s වෙබ් අඩවිය වෙත යාමට තට්ටු කරන්න"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"කරුණාකර ඔබගේ සේවා සැපයුම්කරු %s අමතන්න"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"ජංගම දත්ත සබැඳුමක් නැත"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s හරහා දත්ත හෝ රෝමිං සැලසුම එක් කරන්න"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"ජංගම දත්ත තත්ත්වය"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"ජංගම ජාලය වෙත පුරනය වෙන්න"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"ඔබ සම්බන්ධ වීමට උත්සහ කරන ජාලයේ ආරක්ෂක ගැටළු ඇත."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sk/strings.xml b/packages/CarrierDefaultApp/res/values-sk/strings.xml
index 811ef9d..9fe38da 100644
--- a/packages/CarrierDefaultApp/res/values-sk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sk/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Vaše mobilné dáta boli deaktivované"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Klepnutím navštívite web %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Kontaktujte svojho poskytovateľa služieb %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Žiadne mobilné dátové pripojenie"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Pridať dátový alebo roamingový plán prostredníctvom služby %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Stav mobilných dát"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Prihlásiť sa do mobilnej siete"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Sieť, ku ktorej sa pokúšate pripojiť, má problémy so zabezpečením"</string>
diff --git a/packages/CarrierDefaultApp/res/values-sl/strings.xml b/packages/CarrierDefaultApp/res/values-sl/strings.xml
index 482a5c8..bdbc155 100644
--- a/packages/CarrierDefaultApp/res/values-sl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sl/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Prenos podatkov v mobilnih omrežjih je deaktiviran"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Dotaknite se, če želite obiskati spletno mesto %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Obrnite se na ponudnika storitev %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Brez mobilne podatkovne povezave"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Dodajte podatkovni paket ali paket gostovanja operaterja %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Stanje prenosa podatkov v mobilnem omrežju"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Prijava v mobilno omrežje"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Omrežje, ki se mu poskušate pridružiti, ima varnostne težave."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sq/strings.xml b/packages/CarrierDefaultApp/res/values-sq/strings.xml
index b384115..d4899e0 100644
--- a/packages/CarrierDefaultApp/res/values-sq/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sq/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Të dhënat celulare janë çaktivizuar"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Trokit për të vizituar sajtin e uebit të %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Kontakto me ofruesin e shërbimit %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Nuk ka lidhje të të dhënave celulare"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Shto plan të dhënash ose plan roaming përmes %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Statusi i të dhënave celulare"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Identifikohu në rrjetin celular"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Rrjeti në të cilin po përpiqesh të bashkohesh ka probleme sigurie."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sr/strings.xml b/packages/CarrierDefaultApp/res/values-sr/strings.xml
index cd7587d..34c3bdc 100644
--- a/packages/CarrierDefaultApp/res/values-sr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sr/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Мобилни подаци су деактивирани"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Додирните да бисте посетили веб-сајт %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Контактирајте добављача услуге %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Нема везе за пренос података преко мобилног оператера"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Додајте податке или пакет за роминг преко оператера %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Статус мобилних података"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Пријавите се на мобилну мрежу"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Мрежа којој покушавате да се придружите има безбедносних проблема."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sv/strings.xml b/packages/CarrierDefaultApp/res/values-sv/strings.xml
index 360e04e..4e76c8d 100644
--- a/packages/CarrierDefaultApp/res/values-sv/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sv/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Din mobildata har inaktiverats"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Tryck här för att besöka webbplatsen %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Kontakta operatören %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Det finns ingen mobildataanslutning"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Lägg till ett abonnemang för data eller roaming via %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status för mobildata"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Logga in på mobilnätverk"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Nätverket du försöker ansluta till har säkerhetsproblem."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sw/strings.xml b/packages/CarrierDefaultApp/res/values-sw/strings.xml
index d58316e..c546fcee 100644
--- a/packages/CarrierDefaultApp/res/values-sw/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sw/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Data yako ya mtandao wa simu imezimwa"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Gonga ili utembelee tovuti ya %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Tafadhali wasiliana na mtoa huduma wako %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Hakuna muunganisho wa data kwa simu za mkononi"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Ongeza mpango wa mitandao mingine au data kupitia %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Hali ya data ya mtandao wa simu"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Ingia katika akaunti ya mtandao wa simu"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Mtandao unaojaribu kujiunga nao una matatizo ya usalama."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ta/strings.xml b/packages/CarrierDefaultApp/res/values-ta/strings.xml
index 5153686..1a786fa 100644
--- a/packages/CarrierDefaultApp/res/values-ta/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ta/strings.xml
@@ -3,11 +3,13 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
     <string name="android_system_label" msgid="2797790869522345065">"தொலைத்தொடர்பு நிறுவனம்"</string>
-    <string name="portal_notification_id" msgid="5155057562457079297">"மொபைல் தரவு தீர்ந்துவிட்டது"</string>
-    <string name="no_data_notification_id" msgid="668400731803969521">"மொபைல் தரவு முடக்கப்பட்டது"</string>
+    <string name="portal_notification_id" msgid="5155057562457079297">"மொபைல் டேட்டா தீர்ந்துவிட்டது"</string>
+    <string name="no_data_notification_id" msgid="668400731803969521">"மொபைல் டேட்டா முடக்கப்பட்டது"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s இணையதளத்திற்குச் செல்ல, தட்டவும்"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"%s எனும் உங்கள் சேவை வழங்குநரைத் தொடர்புகொள்ளவும்"</string>
-    <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"மொபைல் தரவின் நிலை"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"மொபைல் டேட்டா இணைப்பு இல்லை"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s மூலம் தரவு அல்லது ரோமிங் திட்டத்தைச் சேர்க்கவும்"</string>
+    <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"மொபைல் டேட்டாவின் நிலை"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"மொபைல் நெட்வொர்க்கில் உள்நுழையவும்"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"நீங்கள் சேர முயலும் நெட்வொர்க்கில் பாதுகாப்புச் சிக்கல்கள் உள்ளன."</string>
     <string name="ssl_error_example" msgid="6188711843183058764">"எடுத்துக்காட்டாக, உள்நுழைவுப் பக்கமானது காட்டப்படும் அமைப்பிற்குச் சொந்தமானதாக இல்லாமல் இருக்கலாம்."</string>
diff --git a/packages/CarrierDefaultApp/res/values-te/strings.xml b/packages/CarrierDefaultApp/res/values-te/strings.xml
index b849c4c..8877c0c 100644
--- a/packages/CarrierDefaultApp/res/values-te/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-te/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"మీ మొబైల్ డేటా నిష్క్రియం చేయబడింది"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s వెబ్‌సైట్‌ని సందర్శించడం కోసం నొక్కండి"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"దయచేసి మీ సేవా ప్రదాత %sని సంప్రదించండి"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"మొబైల్ డేటా కనెక్షన్ లేదు"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s ద్వారా డేటాను లేదా రోమింగ్ ప్లాన్‌ను జోడించండి"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"మొబైల్ డేటా స్థితి"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"మొబైల్ నెట్‌వర్క్‌కి సైన్ ఇన్ చేయి"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"మీరు చేరడానికి ప్రయత్నిస్తున్న నెట్‌వర్క్ భద్రతా సమస్యలను కలిగి ఉంది."</string>
diff --git a/packages/CarrierDefaultApp/res/values-th/strings.xml b/packages/CarrierDefaultApp/res/values-th/strings.xml
index c374f9b..8d30cfd 100644
--- a/packages/CarrierDefaultApp/res/values-th/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-th/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"อินเทอร์เน็ตมือถือของคุณถูกปิดใช้งานแล้ว"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"แตะเพื่อเข้าชมเว็บไซต์ %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"โปรดติดต่อผู้ให้บริการ %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"ไม่มีการเชื่อมต่อเน็ตมือถือ"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"เพิ่มแพ็กเกจเน็ตหรือการโรมมิ่งผ่าน %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"สถานะเน็ตมือถือ"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"ลงชื่อเข้าใช้เครือข่ายมือถือ"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"เครือข่ายที่คุณพยายามเข้าร่วมมีปัญหาด้านความปลอดภัย"</string>
diff --git a/packages/CarrierDefaultApp/res/values-tl/strings.xml b/packages/CarrierDefaultApp/res/values-tl/strings.xml
index 3ef550c..083ec9a 100644
--- a/packages/CarrierDefaultApp/res/values-tl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-tl/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Na-deactivate na ang iyong mobile data"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"I-tap upang bisitahin ang website ng %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Makipag-ugnayan sa iyong service provider %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Walang koneksyon sa mobile data"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Magdagdag ng data o roaming plan sa pamamagitan ng %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status ng mobile data"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Mag-sign in sa mobile network"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"May mga isyu sa seguridad ang network na sinusubukan mong salihan."</string>
diff --git a/packages/CarrierDefaultApp/res/values-tr/strings.xml b/packages/CarrierDefaultApp/res/values-tr/strings.xml
index 7f5cc4b..aa17431 100644
--- a/packages/CarrierDefaultApp/res/values-tr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-tr/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Mobil veriniz devre dışı bırakıldı"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s web sitesini ziyaret etmek için dokunun"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Lütfen servis sağlayıcınıza (%s) başvurun"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Mobil veri bağlantısı yok"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s üzerinden veri veya dolaşım planı ekleyin"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobil veri durumu"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Mobil ağda oturum aç"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Katılmaya çalıştığınız ağda güvenlik sorunları var."</string>
diff --git a/packages/CarrierDefaultApp/res/values-uk/strings.xml b/packages/CarrierDefaultApp/res/values-uk/strings.xml
index 8b0f85e..8381e35 100644
--- a/packages/CarrierDefaultApp/res/values-uk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-uk/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Мобільний трафік дезактивовано"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Торкніться, щоб перейти на веб-сайт %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Зв’яжіться зі своїм постачальником послуг %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Немає мобільного Інтернету"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Додати тарифний план або роумінг через оператора %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Статус мобільного передавання даних"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Під’єднайте пристрій до мобільної мережі"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"У мережі, до якої ви намагаєтеся під’єднатись, є проблеми з безпекою."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ur/strings.xml b/packages/CarrierDefaultApp/res/values-ur/strings.xml
index f5fbdc8..fc286b8 100644
--- a/packages/CarrierDefaultApp/res/values-ur/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ur/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"آپ کا موبائل ڈیٹا غیر فعال کر دیا گیا ہے"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"‏‎%s ویب سائٹ ملاحظہ کرنے کیلئے تھپتھپائیں"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"‏براہ کرم اپنے خدمت کے فراہم کنندہ %s سے رابطہ کریں"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"کوئی موبائل ڈیٹا کنکشن نہیں ہے"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"‏%s کے ذریعے ڈیٹا یا رومنگ پلان شامل کریں"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"موبائل ڈیٹا کی صورت حال"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"موبائل نیٹ ورک میں سائن ان کریں"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"آپ جس نیٹ ورک میں شامل ہونے کی کوشش کر رہے ہیں، اس میں سیکیورٹی کے مسائل ہیں۔"</string>
diff --git a/packages/CarrierDefaultApp/res/values-uz/strings.xml b/packages/CarrierDefaultApp/res/values-uz/strings.xml
index c65f2cb..f2801c8 100644
--- a/packages/CarrierDefaultApp/res/values-uz/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-uz/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Mobil internet o‘chirildi"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"%s saytiga o‘tish uchun bosing"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"%s xizmat ta’minotchisi bilan bog‘laning"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Mobil internet aloqasi yo‘q"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"%s orqali trafik yoki rouming rejasini qo‘shish"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobil internet holati"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Mobil tarmoqqa ulanish"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Siz ulanmoqchi bo‘lgan tarmoqda xavfsizlik bilan bog‘liq muammolar mavjud."</string>
diff --git a/packages/CarrierDefaultApp/res/values-vi/strings.xml b/packages/CarrierDefaultApp/res/values-vi/strings.xml
index 1d302da..1047cd4 100644
--- a/packages/CarrierDefaultApp/res/values-vi/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-vi/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Dữ liệu di động của bạn đã bị hủy kích hoạt"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Nhấn để truy cập trang web %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Hãy liên hệ với nhà cung cấp dịch vụ của bạn %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Không có kết nối dữ liệu di động"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Thêm gói dữ liệu hoặc gói chuyển vùng thông qua %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Trạng thái dữ liệu di động"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Đăng nhập vào mạng di động"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Mạng mà bạn đang cố gắng tham gia có vấn đề về bảo mật."</string>
diff --git a/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml b/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml
index ce1e2fa..f84cedb 100644
--- a/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"您的移动数据网络已停用"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"点按即可访问%s网站"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"请与您的服务提供商(%s)联系"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"无移动数据网络连接"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"通过%s添加流量或漫游套餐"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"移动数据状态"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"登录到移动网络"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"您尝试加入的网络存在安全问题。"</string>
diff --git a/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml b/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml
index 23e0acc..ad76306 100644
--- a/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"您的流動數據已停用"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"輕按即可瀏覽 %s 網站"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"請與您的服務供應商 (%s) 聯絡"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"沒有流動數據連線"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"透過「%s」新增數據或漫遊計劃"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"流動數據狀態"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"登入流動網絡"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"您正在嘗試加入的網絡有安全性問題。"</string>
diff --git a/packages/CarrierDefaultApp/res/values-zh-rTW/strings.xml b/packages/CarrierDefaultApp/res/values-zh-rTW/strings.xml
index b3a7992..ccf95c1 100644
--- a/packages/CarrierDefaultApp/res/values-zh-rTW/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zh-rTW/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"你的行動數據已停用"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"輕觸即可造訪 %s 網站"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"請與你的服務供應商 (%s) 聯絡"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"沒有行動數據連線"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"透過「%s」新增數據或漫遊方案"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"行動數據狀態"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"登入行動網路"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"你嘗試加入的網路有安全性問題。"</string>
diff --git a/packages/CarrierDefaultApp/res/values-zu/strings.xml b/packages/CarrierDefaultApp/res/values-zu/strings.xml
index 48e4637..4ef80c1 100644
--- a/packages/CarrierDefaultApp/res/values-zu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zu/strings.xml
@@ -7,6 +7,8 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Idatha yakho yeselula yenziwe yangasebenzi"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Thepha ukuze uvakashele iwebhusayithi engu-%s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Sicela uxhumane nomhlinzeki wakho wesevisi ongu-%s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Akukho ukuxhumeka kwedatha yeselula"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Engeza idatha noma uhlelo lokuzulazula nge-%s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Isimo sedatha yeselula"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Ngena ngemvume kunethiwekhi yeselula"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Inethiwekhi ozama ukuyijoyina inezinkinga zokuvikela."</string>
diff --git a/packages/CarrierDefaultApp/res/values/strings.xml b/packages/CarrierDefaultApp/res/values/strings.xml
index fa5c3ff..65a7cec 100644
--- a/packages/CarrierDefaultApp/res/values/strings.xml
+++ b/packages/CarrierDefaultApp/res/values/strings.xml
@@ -6,6 +6,8 @@
     <string name="no_data_notification_id">Your mobile data has been deactivated</string>
     <string name="portal_notification_detail">Tap to visit the %s website</string>
     <string name="no_data_notification_detail">Please contact your service provider %s</string>
+    <string name="no_mobile_data_connection_title">No mobile data connection</string>
+    <string name="no_mobile_data_connection">Add data or roaming plan through %s</string>
     <string name="mobile_data_status_notification_channel_name">Mobile data status</string>
     <string name="action_bar_label">Sign in to mobile network</string>
     <string name="ssl_error_warning">The network you&#8217;re trying to join has security issues.</string>
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index c1f03fd..8553bcf 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -20,6 +20,9 @@
 import android.app.LoadedApk;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
@@ -34,6 +37,7 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.Rlog;
 import android.telephony.SubscriptionManager;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.TypedValue;
@@ -68,7 +72,7 @@
     private static final boolean DBG = true;
 
     private static final int SOCKET_TIMEOUT_MS = 10 * 1000;
-    public static final int NETWORK_REQUEST_TIMEOUT_MS = 5 * 1000;
+    private static final int NETWORK_REQUEST_TIMEOUT_MS = 5 * 1000;
 
     private URL mUrl;
     private Network mNetwork;
@@ -77,6 +81,7 @@
     private WebView mWebView;
     private MyWebViewClient mWebViewClient;
     private boolean mLaunchBrowser = false;
+    private Thread mTestingThread = null;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -127,8 +132,6 @@
 
     @Override
     public void onDestroy() {
-        super.onDestroy();
-        releaseNetworkRequest();
         if (mLaunchBrowser) {
             // Give time for this network to become default. After 500ms just proceed.
             for (int i = 0; i < 5; i++) {
@@ -143,6 +146,13 @@
             if (DBG) logd("starting activity with intent ACTION_VIEW for " + url);
             startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
         }
+
+        if (mTestingThread != null) {
+            mTestingThread.interrupt();
+        }
+        mWebView.destroy();
+        releaseNetworkRequest();
+        super.onDestroy();
     }
 
     // Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties.
@@ -170,7 +180,8 @@
     }
 
     private void done(boolean success) {
-        if (DBG) logd(String.format("Result success %b for %s", success, mUrl.toString()));
+        if (DBG) logd(String.format("Result success %b for %s", success,
+                mUrl != null ? mUrl.toString() : "null"));
         if (success) {
             // Trigger re-evaluation upon success http response code
             CarrierActionUtils.applyCarrierAction(
@@ -182,16 +193,19 @@
             CarrierActionUtils.applyCarrierAction(
                     CarrierActionUtils.CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS, getIntent(),
                     getApplicationContext());
-
+            CarrierActionUtils.applyCarrierAction(
+                    CarrierActionUtils.CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER, getIntent(),
+                    getApplicationContext());
+            CarrierActionUtils.applyCarrierAction(
+                    CarrierActionUtils.CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL, getIntent(),
+                    getApplicationContext());
         }
         finishAndRemoveTask();
     }
 
     private URL getUrlForCaptivePortal() {
         String url = getIntent().getStringExtra(TelephonyIntents.EXTRA_REDIRECTION_URL_KEY);
-        if (url.isEmpty()) {
-            url = mCm.getCaptivePortalServerUrl();
-        }
+        if (TextUtils.isEmpty(url)) url = mCm.getCaptivePortalServerUrl();
         final CarrierConfigManager configManager = getApplicationContext()
                 .getSystemService(CarrierConfigManager.class);
         final int subId = getIntent().getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
@@ -215,18 +229,20 @@
     }
 
     private void testForCaptivePortal() {
-        new Thread(new Runnable() {
+        mTestingThread = new Thread(new Runnable() {
             public void run() {
                 // Give time for captive portal to open.
                 try {
                     Thread.sleep(1000);
                 } catch (InterruptedException e) {
                 }
+                if (isFinishing() || isDestroyed()) return;
                 HttpURLConnection urlConnection = null;
                 int httpResponseCode = 500;
                 int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_PROBE);
                 try {
-                    urlConnection = (HttpURLConnection) mNetwork.openConnection(mUrl);
+                    urlConnection = (HttpURLConnection) mNetwork.openConnection(
+                            new URL(mCm.getCaptivePortalServerUrl()));
                     urlConnection.setInstanceFollowRedirects(false);
                     urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
                     urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
@@ -234,6 +250,7 @@
                     urlConnection.getInputStream();
                     httpResponseCode = urlConnection.getResponseCode();
                 } catch (IOException e) {
+                    loge(e.getMessage());
                 } finally {
                     if (urlConnection != null) urlConnection.disconnect();
                     TrafficStats.setThreadStatsTag(oldTag);
@@ -242,7 +259,8 @@
                     done(true);
                 }
             }
-        }).start();
+        });
+        mTestingThread.start();
     }
 
     private Network getNetworkForCaptivePortal() {
@@ -427,6 +445,27 @@
         }
     }
 
+    /**
+     * This alias presents the target activity, CaptivePortalLoginActivity, as a independent
+     * entity with its own intent filter to handle URL links. This alias will be enabled/disabled
+     * dynamically to handle url links based on the network conditions.
+     */
+    public static String getAlias(Context context) {
+        try {
+            PackageInfo p = context.getPackageManager().getPackageInfo(context.getPackageName(),
+                    PackageManager.GET_ACTIVITIES | PackageManager.MATCH_DISABLED_COMPONENTS);
+            for (ActivityInfo activityInfo : p.activities) {
+                String targetActivity = activityInfo.targetActivity;
+                if (CaptivePortalLoginActivity.class.getName().equals(targetActivity)) {
+                    return activityInfo.name;
+                }
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
     private static void logd(String s) {
         Rlog.d(TAG, s);
     }
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
index 0213306..a2bf964 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
@@ -19,8 +19,10 @@
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.telephony.SubscriptionManager;
@@ -49,6 +51,10 @@
     public static final int CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION          = 4;
     public static final int CARRIER_ACTION_SHOW_NO_DATA_SERVICE_NOTIFICATION = 5;
     public static final int CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS          = 6;
+    public static final int CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER        = 7;
+    public static final int CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER       = 8;
+    public static final int CARRIER_ACTION_REGISTER_DEFAULT_NETWORK_AVAIL    = 9;
+    public static final int CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL  = 10;
 
     public static void applyCarrierAction(int actionIdx, Intent intent, Context context) {
         switch (actionIdx) {
@@ -73,6 +79,18 @@
             case CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS:
                 onCancelAllNotifications(context);
                 break;
+            case CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER:
+                onEnableDefaultURLHandler(context);
+                break;
+            case CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER:
+                onDisableDefaultURLHandler(context);
+                break;
+            case CARRIER_ACTION_REGISTER_DEFAULT_NETWORK_AVAIL:
+                onRegisterDefaultNetworkAvail(intent, context);
+                break;
+            case CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL:
+                onDeregisterDefaultNetworkAvail(intent, context);
+                break;
             default:
                 loge("unsupported carrier action index: " + actionIdx);
         }
@@ -94,6 +112,38 @@
         telephonyMgr.carrierActionSetMeteredApnsEnabled(subId, ENABLE);
     }
 
+    private static void onEnableDefaultURLHandler(Context context) {
+        logd("onEnableDefaultURLHandler");
+        final PackageManager pm = context.getPackageManager();
+        pm.setComponentEnabledSetting(
+                new ComponentName(context, CaptivePortalLoginActivity.getAlias(context)),
+                PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
+    }
+
+    private static void onDisableDefaultURLHandler(Context context) {
+        logd("onDisableDefaultURLHandler");
+        final PackageManager pm = context.getPackageManager();
+        pm.setComponentEnabledSetting(
+                new ComponentName(context, CaptivePortalLoginActivity.getAlias(context)),
+                PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
+    }
+
+    private static void onRegisterDefaultNetworkAvail(Intent intent, Context context) {
+        int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
+                SubscriptionManager.getDefaultVoiceSubscriptionId());
+        logd("onRegisterDefaultNetworkAvail subId: " + subId);
+        final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
+        telephonyMgr.carrierActionReportDefaultNetworkStatus(subId, true);
+    }
+
+    private static void onDeregisterDefaultNetworkAvail(Intent intent, Context context) {
+        int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
+                SubscriptionManager.getDefaultVoiceSubscriptionId());
+        logd("onDeregisterDefaultNetworkAvail subId: " + subId);
+        final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
+        telephonyMgr.carrierActionReportDefaultNetworkStatus(subId, false);
+    }
+
     private static void onDisableRadio(Intent intent, Context context) {
         int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
                 SubscriptionManager.getDefaultVoiceSubscriptionId());
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
index d5d0b79..02c61d7 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
@@ -22,7 +22,6 @@
 import android.telephony.Rlog;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.Pair;
 
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.ArrayUtils;
@@ -95,6 +94,12 @@
                     configs = b.getStringArray(CarrierConfigManager
                             .KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET);
                     break;
+                case TelephonyIntents.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE:
+                    configs = b.getStringArray(CarrierConfigManager
+                            .KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE);
+                    arg1 = String.valueOf(intent.getBooleanExtra(TelephonyIntents
+                            .EXTRA_DEFAULT_NETWORK_AVAILABLE_KEY, false));
+                    break;
                 default:
                     Rlog.e(TAG, "load carrier config failure with un-configured key: " +
                             intent.getAction());
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index 3b29a6c..1e262314 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -77,7 +77,7 @@
 
     private BluetoothAdapter mBluetoothAdapter;
     private WifiManager mWifiManager;
-    private BluetoothLeScanner mBLEScanner;
+    @Nullable private BluetoothLeScanner mBLEScanner;
     private ScanSettings mDefaultScanSettings = new ScanSettings.Builder().build();
 
     private List<DeviceFilter<?>> mFilters;
@@ -185,7 +185,7 @@
             mBluetoothAdapter.startDiscovery();
         }
 
-        if (shouldScan(mBLEFilters)) {
+        if (shouldScan(mBLEFilters) && mBLEScanner != null) {
             mBLEScanCallback = new BLEScanCallback();
             mBLEScanner.startScan(mBLEScanFilters, mDefaultScanSettings, mBLEScanCallback);
         }
@@ -224,7 +224,7 @@
             unregisterReceiver(mBluetoothBroadcastReceiver);
             mBluetoothBroadcastReceiver = null;
         }
-        mBLEScanner.stopScan(mBLEScanCallback);
+        if (mBLEScanner != null) mBLEScanner.stopScan(mBLEScanCallback);
         if (mWifiBroadcastReceiver != null) {
             unregisterReceiver(mWifiBroadcastReceiver);
             mWifiBroadcastReceiver = null;
diff --git a/packages/DefaultContainerService/res/values-te/strings.xml b/packages/DefaultContainerService/res/values-te/strings.xml
index 58671ea..5be53e5 100644
--- a/packages/DefaultContainerService/res/values-te/strings.xml
+++ b/packages/DefaultContainerService/res/values-te/strings.xml
@@ -20,5 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="service_name" msgid="4841491635055379553">"ప్యాకేజీ ప్రాప్యత సహాయకం"</string>
+    <string name="service_name" msgid="4841491635055379553">"ప్యాకేజీ యాక్సెస్ సహాయకం"</string>
 </resources>
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 9347877..3800e6f 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -213,27 +213,6 @@
         }
 
         @Override
-        public long calculateDirectorySize(String path) throws RemoteException {
-            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-
-            final File dir = Environment.maybeTranslateEmulatedPathToInternal(new File(path));
-            if (dir.exists() && dir.isDirectory()) {
-                final String targetPath = dir.getAbsolutePath();
-                return MeasurementUtils.measureDirectory(targetPath);
-            } else {
-                return 0L;
-            }
-        }
-
-        @Override
-        public long[] getFileSystemStats(String path) {
-            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-
-            final File file = new File(path);
-            return new long[] { file.getTotalSpace(), file.getUsableSpace() };
-        }
-
-        @Override
         public void clearDirectory(String path) throws RemoteException {
             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
 
diff --git a/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml b/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml
index 9d2f7bb..235b621 100644
--- a/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml
@@ -17,8 +17,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="7123375275748530234">"Spoljna memorija"</string>
-    <!-- no translation found for storage_description (8541974407321172792) -->
-    <skip />
+    <string name="storage_description" msgid="8541974407321172792">"Lokalni memorijski prostor"</string>
     <string name="root_internal_storage" msgid="827844243068584127">"Interna memorija"</string>
     <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-be/strings.xml b/packages/ExternalStorageProvider/res/values-be/strings.xml
index ea8837b..911ff54 100644
--- a/packages/ExternalStorageProvider/res/values-be/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-be/strings.xml
@@ -17,8 +17,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="7123375275748530234">"Вонкавае сховішча"</string>
-    <!-- no translation found for storage_description (8541974407321172792) -->
-    <skip />
+    <string name="storage_description" msgid="8541974407321172792">"Лакальнае сховішча"</string>
     <string name="root_internal_storage" msgid="827844243068584127">"Унутранае сховішча"</string>
     <string name="root_documents" msgid="4051252304075469250">"Дакументы"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-bn/strings.xml b/packages/ExternalStorageProvider/res/values-bn/strings.xml
index f1cb2f2..264d82a 100644
--- a/packages/ExternalStorageProvider/res/values-bn/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-bn/strings.xml
@@ -16,8 +16,8 @@
 
 <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="7123375275748530234">"বাহ্যিক সঞ্চয়স্থান"</string>
-    <string name="storage_description" msgid="8541974407321172792">"স্থানীয় সঞ্চয়স্থান"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"অভ্যন্তরীণ সঞ্চয়স্থান"</string>
+    <string name="app_label" msgid="7123375275748530234">"এক্সটারনাল স্টোরেজ"</string>
+    <string name="storage_description" msgid="8541974407321172792">"স্থানীয় স্টোরেজ"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"ইন্টারনাল স্টোরেজ"</string>
     <string name="root_documents" msgid="4051252304075469250">"দস্তাবেজগুলি"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-bs/strings.xml b/packages/ExternalStorageProvider/res/values-bs/strings.xml
index 194e66b..1eb3020 100644
--- a/packages/ExternalStorageProvider/res/values-bs/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-bs/strings.xml
@@ -17,8 +17,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="7123375275748530234">"Aplikacija za vanjsku pohranu"</string>
-    <!-- no translation found for storage_description (8541974407321172792) -->
-    <skip />
+    <string name="storage_description" msgid="8541974407321172792">"Lokalna pohrana"</string>
     <string name="root_internal_storage" msgid="827844243068584127">"Interna pohrana"</string>
     <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-gu/strings.xml b/packages/ExternalStorageProvider/res/values-gu/strings.xml
index 3e8a099..3f59dd3 100644
--- a/packages/ExternalStorageProvider/res/values-gu/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-gu/strings.xml
@@ -18,6 +18,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7123375275748530234">"બાહ્ય સંગ્રહ"</string>
     <string name="storage_description" msgid="8541974407321172792">"સ્થાનિક સ્ટોરેજ"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"આંતરિક સંગ્રહ"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"આંતરિક સ્ટોરેજ"</string>
     <string name="root_documents" msgid="4051252304075469250">"દસ્તાવેજો"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-mk/strings.xml b/packages/ExternalStorageProvider/res/values-mk/strings.xml
index 83a22d9..5ebf8a6 100644
--- a/packages/ExternalStorageProvider/res/values-mk/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-mk/strings.xml
@@ -18,6 +18,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7123375275748530234">"Надворешна меморија"</string>
     <string name="storage_description" msgid="8541974407321172792">"Локална меморија"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Внатрешна меморија"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Внатрешен капацитет"</string>
     <string name="root_documents" msgid="4051252304075469250">"Документи"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-mr/strings.xml b/packages/ExternalStorageProvider/res/values-mr/strings.xml
index 5b81cc5..2bf3000 100644
--- a/packages/ExternalStorageProvider/res/values-mr/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-mr/strings.xml
@@ -18,6 +18,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7123375275748530234">"बाह्य संचयन"</string>
     <string name="storage_description" msgid="8541974407321172792">"स्थानिक संचय"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"अंतर्गत संचयन"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"अंतर्गत स्टोरेज"</string>
     <string name="root_documents" msgid="4051252304075469250">"दस्तऐवज"</string>
 </resources>
diff --git a/packages/InputDevices/res/values-bn/strings.xml b/packages/InputDevices/res/values-bn/strings.xml
index a0ce313..e9540b6 100644
--- a/packages/InputDevices/res/values-bn/strings.xml
+++ b/packages/InputDevices/res/values-bn/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8016145283189546017">"ইনপুট ডিভাইসগুলি"</string>
+    <string name="app_label" msgid="8016145283189546017">"ইনপুট ডিভাইস"</string>
     <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android কীবোর্ড"</string>
     <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"ইংরেজি (UK)"</string>
     <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"ইংরেজি (US)"</string>
diff --git a/packages/InputDevices/res/values-da/strings.xml b/packages/InputDevices/res/values-da/strings.xml
index 08fdee5..974c43d 100644
--- a/packages/InputDevices/res/values-da/strings.xml
+++ b/packages/InputDevices/res/values-da/strings.xml
@@ -3,7 +3,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="8016145283189546017">"Inputenheder"</string>
     <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android-tastatur"</string>
-    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Engelsk (UK)"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Engelsk (Storbritannien)"</string>
     <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"engelsk (USA)"</string>
     <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Engelsk (USA), international stil"</string>
     <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Engelsk (USA), Colemak-stil"</string>
diff --git a/packages/InputDevices/res/values-ml/strings.xml b/packages/InputDevices/res/values-ml/strings.xml
index 0faa40e..5186667 100644
--- a/packages/InputDevices/res/values-ml/strings.xml
+++ b/packages/InputDevices/res/values-ml/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8016145283189546017">"ടൈപ്പുചെയ്യൽ ഉപകരണങ്ങൾ"</string>
+    <string name="app_label" msgid="8016145283189546017">"ഇൻപുട്ട് ഉപകരണങ്ങൾ"</string>
     <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android കീബോർഡ്"</string>
     <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"ഇംഗ്ലീഷ് (യുകെ)"</string>
     <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"ഇംഗ്ലീഷ് (യുഎസ്)"</string>
diff --git a/packages/InputDevices/res/values-mr/strings.xml b/packages/InputDevices/res/values-mr/strings.xml
index 9ffcc70..a73d4fa 100644
--- a/packages/InputDevices/res/values-mr/strings.xml
+++ b/packages/InputDevices/res/values-mr/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8016145283189546017">"इनपुट डिव्‍हाइसेस"</string>
+    <string name="app_label" msgid="8016145283189546017">"इनपुट डिव्हाइस"</string>
     <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android कीबोर्ड"</string>
     <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"इंग्रजी (यूके)"</string>
     <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"इंग्रजी (यूएस)"</string>
diff --git a/packages/MtpDocumentsProvider/res/values-gu/strings.xml b/packages/MtpDocumentsProvider/res/values-gu/strings.xml
index 40ec38d..468bd9d 100644
--- a/packages/MtpDocumentsProvider/res/values-gu/strings.xml
+++ b/packages/MtpDocumentsProvider/res/values-gu/strings.xml
@@ -20,6 +20,6 @@
     <string name="downloads_app_label" msgid="7120690641874849726">"ડાઉનલોડ્સ"</string>
     <string name="root_name" msgid="5819495383921089536">"<xliff:g id="DEVICE_MODEL">%1$s</xliff:g> <xliff:g id="STORAGE_NAME">%2$s</xliff:g>"</string>
     <string name="accessing_notification_title" msgid="3030133609230917944">"<xliff:g id="DEVICE_MODEL">%1$s</xliff:g> ની ફાઇલોને ઍક્સેસ કરી રહ્યાં છે"</string>
-    <string name="error_busy_device" msgid="3997316850357386589">"અન્ય ઉપકરણ વ્યસ્ત છે. તે ઉપલબ્ધ ન થાય ત્યાં સુધી તમે ફાઇલોને સ્થાનાંતરિત કરી શકતાં નથી."</string>
+    <string name="error_busy_device" msgid="3997316850357386589">"અન્ય ઉપકરણ વ્યસ્ત છે. તે ઉપલબ્ધ ન થાય ત્યાં સુધી તમે ફાઇલોને ટ્રાન્સફર કરી શકતાં નથી."</string>
     <string name="error_locked_device" msgid="7557872102188356147">"કોઈ ફાઇલો મળી નહીં. અન્ય ઉપકરણ લૉક કરેલ હોઈ શકે છે. જો આમ હોય, તો તેને અનલૉક કરો અને ફરી પ્રયાસ કરો."</string>
 </resources>
diff --git a/packages/MtpDocumentsProvider/res/values-hi/strings.xml b/packages/MtpDocumentsProvider/res/values-hi/strings.xml
index 1cf1c03..6aceb95 100644
--- a/packages/MtpDocumentsProvider/res/values-hi/strings.xml
+++ b/packages/MtpDocumentsProvider/res/values-hi/strings.xml
@@ -21,5 +21,5 @@
     <string name="root_name" msgid="5819495383921089536">"<xliff:g id="DEVICE_MODEL">%1$s</xliff:g> <xliff:g id="STORAGE_NAME">%2$s</xliff:g>"</string>
     <string name="accessing_notification_title" msgid="3030133609230917944">"<xliff:g id="DEVICE_MODEL">%1$s</xliff:g> से फ़ाइलें एक्सेस कर रहा है"</string>
     <string name="error_busy_device" msgid="3997316850357386589">"दूसरा डिवाइस व्यस्त है. आप उसके उपलब्ध हो जाने तक फ़ाइलें स्थानांतरित नहीं कर सकते हैं."</string>
-    <string name="error_locked_device" msgid="7557872102188356147">"कोई फ़ाइल नहीं मिली. हो सकता है कि दूसरा डिवाइस लॉक हो. यदि ऐसा है, तो उसे अनलॉक करें और पुन: प्रयास करें."</string>
+    <string name="error_locked_device" msgid="7557872102188356147">"कोई फ़ाइल नहीं मिली. हो सकता है कि दूसरा डिवाइस लॉक हो. अगर ऐसा है, तो उसे अनलॉक करें और दोबारा कोशिश करें."</string>
 </resources>
diff --git a/packages/MtpDocumentsProvider/res/values-mr/strings.xml b/packages/MtpDocumentsProvider/res/values-mr/strings.xml
index 5b856dc..89a9d14 100644
--- a/packages/MtpDocumentsProvider/res/values-mr/strings.xml
+++ b/packages/MtpDocumentsProvider/res/values-mr/strings.xml
@@ -20,6 +20,6 @@
     <string name="downloads_app_label" msgid="7120690641874849726">"डाउनलोड"</string>
     <string name="root_name" msgid="5819495383921089536">"<xliff:g id="DEVICE_MODEL">%1$s</xliff:g> <xliff:g id="STORAGE_NAME">%2$s</xliff:g>"</string>
     <string name="accessing_notification_title" msgid="3030133609230917944">"<xliff:g id="DEVICE_MODEL">%1$s</xliff:g> मधून फायलींंमध्ये प्रवेश करीत आहे"</string>
-    <string name="error_busy_device" msgid="3997316850357386589">"अन्य डिव्हाइस व्यस्त आहे. ते उपलब्‍ध होईपर्यंत आपण फायली हस्तांतरित करू शकत नाही."</string>
-    <string name="error_locked_device" msgid="7557872102188356147">"कोणत्याही फायली आढळल्या नाहीत. अन्य डिव्हाइस कदाचित बंद असू शकते. तसे असल्यास, ते अनलॉक करा आणि पुन्हा प्रयत्न करा."</string>
+    <string name="error_busy_device" msgid="3997316850357386589">"दुसरे डिव्हाइस व्यस्त आहे. ते उपलब्‍ध होईपर्यंत तुम्ही फायली ट्रांसफर करू शकत नाही."</string>
+    <string name="error_locked_device" msgid="7557872102188356147">"कोणत्याही फायली आढळल्या नाहीत. दुसरे डिव्हाइस कदाचित बंद असू शकते. तसे असल्यास, ते अनलॉक करा आणि पुन्हा प्रयत्न करा."</string>
 </resources>
diff --git a/packages/MtpDocumentsProvider/res/values-pa/strings.xml b/packages/MtpDocumentsProvider/res/values-pa/strings.xml
index ab8ba15..7e3b892 100644
--- a/packages/MtpDocumentsProvider/res/values-pa/strings.xml
+++ b/packages/MtpDocumentsProvider/res/values-pa/strings.xml
@@ -20,6 +20,6 @@
     <string name="downloads_app_label" msgid="7120690641874849726">"ਡਾਊਨਲੋਡ"</string>
     <string name="root_name" msgid="5819495383921089536">"<xliff:g id="DEVICE_MODEL">%1$s</xliff:g> <xliff:g id="STORAGE_NAME">%2$s</xliff:g>"</string>
     <string name="accessing_notification_title" msgid="3030133609230917944">"<xliff:g id="DEVICE_MODEL">%1$s</xliff:g> ਦੀਆਂ ਫ਼ਾਈਲਾਂ \'ਤੇ ਪਹੁੰਚ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
-    <string name="error_busy_device" msgid="3997316850357386589">"ਦੂਜੀ ਡੀਵਾਈਸ ਰੁਝੇਵੇਂ ਵਿੱਚ ਹੈ। ਉਸਦੇ ਉਪਲਬਧ ਹੋਣ ਤੱਕ ਤੁਸੀਂ ਫ਼ਾਈਲਾਂ ਦਾ ਤਬਾਦਲਾ ਨਹੀਂ ਕਰ ਸਕਦੇ।"</string>
-    <string name="error_locked_device" msgid="7557872102188356147">"ਕੋਈ ਫ਼ਾਈਲਾਂ ਨਹੀਂ ਮਿਲੀਆਂ। ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਦੂਜੀ ਡੀਵਾਈਸ ਲੌਕ ਹੋਵੇ। ਜੇਕਰ ਇੰਝ ਹੈ, ਤਾਂ ਉਸਨੂੰ ਅਨਲੌਕ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="error_busy_device" msgid="3997316850357386589">"ਦੂਜਾ ਡੀਵਾਈਸ ਰੁਝੇਵੇਂ ਵਿੱਚ ਹੈ। ਉਸਦੇ ਉਪਲਬਧ ਹੋਣ ਤੱਕ ਤੁਸੀਂ ਫ਼ਾਈਲਾਂ ਦਾ ਤਬਾਦਲਾ ਨਹੀਂ ਕਰ ਸਕਦੇ।"</string>
+    <string name="error_locked_device" msgid="7557872102188356147">"ਕੋਈ ਫ਼ਾਈਲਾਂ ਨਹੀਂ ਮਿਲੀਆਂ। ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਦੂਜਾ ਡੀਵਾਈਸ ਲਾਕ ਹੋਵੇ। ਜੇਕਰ ਇੰਝ ਹੈ, ਤਾਂ ਉਸਨੂੰ ਅਣਲਾਕ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
 </resources>
diff --git a/packages/MtpDocumentsProvider/res/values-te/strings.xml b/packages/MtpDocumentsProvider/res/values-te/strings.xml
index 7add858..b3436bf 100644
--- a/packages/MtpDocumentsProvider/res/values-te/strings.xml
+++ b/packages/MtpDocumentsProvider/res/values-te/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="6271216747302322594">"MTP హోస్ట్"</string>
     <string name="downloads_app_label" msgid="7120690641874849726">"డౌన్‌లోడ్‌లు"</string>
     <string name="root_name" msgid="5819495383921089536">"<xliff:g id="DEVICE_MODEL">%1$s</xliff:g> <xliff:g id="STORAGE_NAME">%2$s</xliff:g>"</string>
-    <string name="accessing_notification_title" msgid="3030133609230917944">"<xliff:g id="DEVICE_MODEL">%1$s</xliff:g> నుండి ఫైల్‌లను ప్రాప్యత చేస్తోంది"</string>
+    <string name="accessing_notification_title" msgid="3030133609230917944">"<xliff:g id="DEVICE_MODEL">%1$s</xliff:g> నుండి ఫైల్‌లను యాక్సెస్ చేస్తోంది"</string>
     <string name="error_busy_device" msgid="3997316850357386589">"ఇతర పరికరం బిజీగా ఉంది. అది అందుబాటులోకి వచ్చే వరకు మీరు ఫైల్‌లను బదిలీ చేయలేరు."</string>
     <string name="error_locked_device" msgid="7557872102188356147">"ఫైల్‍లు ఏవీ కనుగొనబడలేదు. ఇతర పరికరం లాక్ చేయబడి ఉండవచ్చు. అలా జరిగి ఉంటే, దాన్ని అన్‌లాక్ చేసి, ఆపై మళ్లీ ప్రయత్నించండి."</string>
 </resources>
diff --git a/packages/Osu2/Android.mk b/packages/Osu2/Android.mk
new file mode 100644
index 0000000..05586f0
--- /dev/null
+++ b/packages/Osu2/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := Osu2
+LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
+
+include $(BUILD_PACKAGE)
+
+########################
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/Osu2/AndroidManifest.xml b/packages/Osu2/AndroidManifest.xml
new file mode 100644
index 0000000..236b120b
--- /dev/null
+++ b/packages/Osu2/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.osu">
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+
+    <application
+    android:enabled="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name">
+        <activity android:name=".MainActivity" android:exported="true">
+        </activity>
+    </application>
+
+</manifest>
diff --git a/packages/Osu2/res/layout/activity_main.xml b/packages/Osu2/res/layout/activity_main.xml
new file mode 100644
index 0000000..f9504c9
--- /dev/null
+++ b/packages/Osu2/res/layout/activity_main.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+</LinearLayout>
diff --git a/packages/Osu2/res/mipmap-hdpi/ic_launcher.png b/packages/Osu2/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
--- /dev/null
+++ b/packages/Osu2/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/packages/Osu2/res/mipmap-mdpi/ic_launcher.png b/packages/Osu2/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
--- /dev/null
+++ b/packages/Osu2/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/packages/Osu2/res/mipmap-xhdpi/ic_launcher.png b/packages/Osu2/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
--- /dev/null
+++ b/packages/Osu2/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/packages/Osu2/res/mipmap-xxhdpi/ic_launcher.png b/packages/Osu2/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
--- /dev/null
+++ b/packages/Osu2/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/packages/Osu2/res/mipmap-xxxhdpi/ic_launcher.png b/packages/Osu2/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..aee44e1
--- /dev/null
+++ b/packages/Osu2/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/packages/Osu2/res/values-w820dp/dimens.xml b/packages/Osu2/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/packages/Osu2/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+<resources>
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>
diff --git a/packages/Osu2/res/values/colors.xml b/packages/Osu2/res/values/colors.xml
new file mode 100644
index 0000000..3ab3e9c
--- /dev/null
+++ b/packages/Osu2/res/values/colors.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#3F51B5</color>
+    <color name="colorPrimaryDark">#303F9F</color>
+    <color name="colorAccent">#FF4081</color>
+</resources>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/dimens.xml b/packages/Osu2/res/values/dimens.xml
similarity index 100%
rename from tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/dimens.xml
rename to packages/Osu2/res/values/dimens.xml
diff --git a/packages/Osu2/res/values/strings.xml b/packages/Osu2/res/values/strings.xml
new file mode 100644
index 0000000..e5b1af6
--- /dev/null
+++ b/packages/Osu2/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">Passpoint Online Sign-Up</string>
+</resources>
diff --git a/packages/Osu2/src/com/android/osu/Constants.java b/packages/Osu2/src/com/android/osu/Constants.java
new file mode 100644
index 0000000..cd046d8
--- /dev/null
+++ b/packages/Osu2/src/com/android/osu/Constants.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.osu;
+
+public final class Constants {
+    public static final String INTENT_EXTRA_COMMAND = "com.android.osu.extra.COMMAND";
+    public static final String INTENT_EXTRA_OSU_PROVIDER = "com.android.osu.extra.OSU_PROVIDER";
+
+    public static final String COMMAND_PROVISION = "Provision";
+}
\ No newline at end of file
diff --git a/packages/Osu2/src/com/android/osu/MainActivity.java b/packages/Osu2/src/com/android/osu/MainActivity.java
new file mode 100644
index 0000000..4e2136b
--- /dev/null
+++ b/packages/Osu2/src/com/android/osu/MainActivity.java
@@ -0,0 +1,76 @@
+/*
+ * 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.osu;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.wifi.hotspot2.OsuProvider;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * Main entry point for the OSU (Online Sign-Up) app.
+ */
+public class MainActivity extends Activity {
+    private static final String TAG = "OSU_MainActivity";
+    private OsuService mService;
+
+    @Override
+    protected void onCreate(Bundle saveInstanceState) {
+        super.onCreate(saveInstanceState);
+
+        Intent intent = getIntent();
+        if (intent == null) {
+            Log.e(TAG, "Intent not provided");
+            finish();
+        }
+
+        if (!intent.hasExtra(Constants.INTENT_EXTRA_COMMAND)) {
+            Log.e(TAG, "Command not provided");
+            finish();
+        }
+
+        String command = intent.getStringExtra(Constants.INTENT_EXTRA_COMMAND);
+        switch (command) {
+            case Constants.COMMAND_PROVISION:
+                if (!startProvisionService(intent.getParcelableExtra(
+                        Constants.INTENT_EXTRA_OSU_PROVIDER))) {
+                    finish();
+                }
+                break;
+            default:
+                Log.e(TAG, "Unknown command: '" + command + "'");
+                finish();
+                break;
+        }
+    }
+
+    /**
+     * Start the {@link ProvisionService} to perform provisioning tasks.
+     *
+     * @return true if service is started
+     */
+    private boolean startProvisionService(OsuProvider provider) {
+        if (provider == null) {
+            Log.e(TAG, "OSU Provider not provided");
+            return false;
+        }
+        mService = new ProvisionService(this, provider);
+        mService.start();
+        return true;
+    }
+}
diff --git a/packages/Osu2/src/com/android/osu/NetworkConnection.java b/packages/Osu2/src/com/android/osu/NetworkConnection.java
new file mode 100644
index 0000000..9f5b929
--- /dev/null
+++ b/packages/Osu2/src/com/android/osu/NetworkConnection.java
@@ -0,0 +1,206 @@
+/*
+ * 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.osu;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Network;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiSsid;
+import android.os.Handler;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * Responsible for setup/monitor on a Wi-Fi connection.
+ */
+public class NetworkConnection {
+    private static final String TAG = "OSU_NetworkConnection";
+
+    private final WifiManager mWifiManager;
+    private final Callbacks mCallbacks;
+    private final int mNetworkId;
+    private boolean mConnected = false;
+
+    /**
+     * Callbacks on Wi-Fi connection state changes.
+     */
+    public interface Callbacks {
+        /**
+         * Invoked when network connection is established with IP connectivity.
+         *
+         * @param network {@link Network} associated with the connected network.
+         */
+        public void onConnected(Network network);
+
+        /**
+         * Invoked when the targeted network is disconnected.
+         */
+        public void onDisconnected();
+
+        /**
+         * Invoked when network connection is not established within the pre-defined timeout.
+         */
+        public void onTimeout();
+    }
+
+    /**
+     * Create an instance of {@link NetworkConnection} for the specified Wi-Fi network.
+     * The Wi-Fi network (specified by its SSID) will be added/enabled as part of this object
+     * creation.
+     *
+     * {@link #teardown} will need to be invoked once you're done with this connection,
+     * to remove the given Wi-Fi network from the framework.
+     *
+     * @param context The application context
+     * @param handler The handler to dispatch the processing of received broadcast intents
+     * @param ssid The SSID to connect to
+     * @param nai The network access identifier associated with the AP
+     * @param callbacks The callbacks to be invoked on network change events
+     * @throws IOException when failed to add/enable the specified Wi-Fi network
+     */
+    public NetworkConnection(Context context, Handler handler, WifiSsid ssid, String nai,
+            Callbacks callbacks) throws IOException {
+        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+        mCallbacks = callbacks;
+        mNetworkId = connect(ssid, nai);
+
+        // TODO(zqiu): setup alarm to timed out the connection attempt.
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        BroadcastReceiver receiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+                    handleNetworkStateChanged(
+                            intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO),
+                            intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO));
+                }
+            }
+        };
+        // Provide a Handler so that the onReceive call will be run on the specified handler
+        // thread instead of the main thread.
+        context.registerReceiver(receiver, filter, null, handler);
+    }
+
+    /**
+     * Teardown the network connection by removing the network.
+     */
+    public void teardown() {
+        mWifiManager.removeNetwork(mNetworkId);
+    }
+
+    /**
+     * Connect to a OSU Wi-Fi network specified by the given SSID. The security type of the Wi-Fi
+     * network is either open or OSEN (OSU Server-only authenticated layer 2 Encryption Network).
+     * When network access identifier is provided, OSEN is used.
+     *
+     * @param ssid The SSID to connect to
+     * @param nai Network access identifier of the network
+     *
+     * @return unique ID associated with the network
+     * @throws IOException
+     */
+    private int connect(WifiSsid ssid, String nai) throws IOException {
+        WifiConfiguration config = new WifiConfiguration();
+        config.SSID = "\"" + ssid.toString() + "\"";
+        if (TextUtils.isEmpty(nai)) {
+            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+        } else {
+            // TODO(zqiu): configuration setup for OSEN.
+        }
+        int networkId = mWifiManager.addNetwork(config);
+        if (networkId < 0) {
+            throw new IOException("Failed to add OSU network");
+        }
+        if (!mWifiManager.enableNetwork(networkId, true)) {
+            throw new IOException("Failed to enable OSU network");
+        }
+        return networkId;
+    }
+
+    /**
+     * Handle network state changed events.
+     *
+     * @param networkInfo {@link NetworkInfo} indicating the current network state
+     * @param wifiInfo {@link WifiInfo} associated with the current network when connected
+     */
+    private void handleNetworkStateChanged(NetworkInfo networkInfo, WifiInfo wifiInfo) {
+        if (networkInfo == null) {
+            Log.e(TAG, "NetworkInfo not provided for network state changed event");
+            return;
+        }
+        switch (networkInfo.getDetailedState()) {
+            case CONNECTED:
+                handleConnectedEvent(wifiInfo);
+                break;
+            case DISCONNECTED:
+                handleDisconnectedEvent();
+                break;
+            default:
+                Log.d(TAG, "Ignore uninterested state: " + networkInfo.getDetailedState());
+                break;
+        }
+    }
+
+    /**
+     * Handle network connected event.
+     *
+     * @param wifiInfo {@link WifiInfo} associated with the current connection
+     */
+    private void handleConnectedEvent(WifiInfo wifiInfo) {
+        if (mConnected) {
+            // No-op if already connected.
+            return;
+        }
+        if (wifiInfo == null) {
+            Log.e(TAG, "WifiInfo not provided for connected event");
+            return;
+        }
+        if (wifiInfo.getNetworkId() != mNetworkId) {
+            return;
+        }
+        Network network = mWifiManager.getCurrentNetwork();
+        if (network == null) {
+            Log.e(TAG, "Current network is not set");
+            return;
+        }
+        mConnected = true;
+        mCallbacks.onConnected(network);
+    }
+
+    /**
+     * Handle network disconnected event.
+     */
+    private void handleDisconnectedEvent() {
+        if (!mConnected) {
+            // No-op if not connected, most likely a disconnect event for a different network.
+            return;
+        }
+        mConnected = false;
+        mCallbacks.onDisconnected();
+    }
+}
diff --git a/packages/Osu2/src/com/android/osu/OsuService.java b/packages/Osu2/src/com/android/osu/OsuService.java
new file mode 100644
index 0000000..46a3c84
--- /dev/null
+++ b/packages/Osu2/src/com/android/osu/OsuService.java
@@ -0,0 +1,33 @@
+/*
+ * 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.osu;
+
+/**
+ * Abstraction for services that can be performed by the OSU app, such as provisioning,
+ * subscription remediation, and etc.
+ */
+public interface OsuService {
+    /**
+     * Start the service.
+     */
+    public void start();
+
+    /**
+     * Stop the service.
+     */
+    public void stop();
+}
diff --git a/packages/Osu2/src/com/android/osu/ProvisionService.java b/packages/Osu2/src/com/android/osu/ProvisionService.java
new file mode 100644
index 0000000..b1d43b2
--- /dev/null
+++ b/packages/Osu2/src/com/android/osu/ProvisionService.java
@@ -0,0 +1,119 @@
+/*
+ * 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.osu;
+
+import android.content.Context;
+import android.net.Network;
+import android.net.wifi.hotspot2.OsuProvider;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * Service responsible for performing Passpoint subscription provisioning tasks.
+ * This service will run on a separate thread to avoid blocking on the Main thread.
+ */
+public class ProvisionService implements OsuService {
+    private static final String TAG = "OSU_ProvisionService";
+    private static final int COMMAND_START = 1;
+    private static final int COMMAND_STOP = 2;
+
+    private final Context mContext;
+    private final HandlerThread mHandlerThread;
+    private final ServiceHandler mServiceHandler;
+    private final OsuProvider mProvider;
+
+    private boolean mStarted = false;
+    private NetworkConnection mNetworkConnection = null;
+
+    public ProvisionService(Context context, OsuProvider provider) {
+        mContext = context;
+        mProvider = provider;
+        mHandlerThread = new HandlerThread(TAG);
+        mHandlerThread.start();
+        mServiceHandler = new ServiceHandler(mHandlerThread.getLooper());
+    }
+
+    @Override
+    public void start() {
+        mServiceHandler.sendMessage(mServiceHandler.obtainMessage(COMMAND_START));
+    }
+
+    @Override
+    public void stop() {
+        mServiceHandler.sendMessage(mServiceHandler.obtainMessage(COMMAND_STOP));
+    }
+
+    /**
+     * Handler class for handling commands to the ProvisionService.
+     */
+    private final class ServiceHandler extends Handler {
+        public ServiceHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case COMMAND_START:
+                    if (mStarted) {
+                        Log.e(TAG, "Service already started");
+                        return;
+                    }
+                    try {
+                        // Initiate network connection to the OSU AP.
+                        mNetworkConnection = new NetworkConnection(
+                                mContext, this, mProvider.getOsuSsid(),
+                                mProvider.getNetworkAccessIdentifier(), new NetworkCallbacks());
+                        mStarted = true;
+                    } catch (IOException e) {
+                        // TODO(zqiu): broadcast failure event via LocalBroadcastManager.
+                    }
+                    break;
+                case COMMAND_STOP:
+                    if (!mStarted) {
+                        Log.e(TAG, "Service not started");
+                        return;
+                    }
+                    Log.e(TAG, "Stop provision service");
+                    break;
+                default:
+                    Log.e(TAG, "Unknown command: " + msg.what);
+                    break;
+            }
+        }
+    }
+
+    private final class NetworkCallbacks implements NetworkConnection.Callbacks {
+        @Override
+        public void onConnected(Network network) {
+            Log.d(TAG, "Connected to OSU AP");
+        }
+
+        @Override
+        public void onDisconnected() {
+        }
+
+        @Override
+        public void onTimeout() {
+        }
+    }
+}
diff --git a/packages/Osu2/tests/Android.mk b/packages/Osu2/tests/Android.mk
new file mode 100644
index 0000000..4b6e0e6
--- /dev/null
+++ b/packages/Osu2/tests/Android.mk
@@ -0,0 +1,43 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_JACK_FLAGS := --multi-dex native
+
+LOCAL_PACKAGE_NAME := OsuTests
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
+LOCAL_INSTRUMENTATION_FOR := Osu2
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    mockito-target-minus-junit4 \
+    frameworks-base-testutils
+
+# Code coverage puts us over the dex limit, so enable multi-dex for coverage-enabled builds
+ifeq (true,$(EMMA_INSTRUMENT))
+LOCAL_JACK_FLAGS := --multi-dex native
+LOCAL_DX_FLAGS := --multi-dex
+endif # EMMA_INSTRUMENT
+
+include $(BUILD_PACKAGE)
diff --git a/packages/Osu2/tests/AndroidManifest.xml b/packages/Osu2/tests/AndroidManifest.xml
new file mode 100644
index 0000000..e22c112
--- /dev/null
+++ b/packages/Osu2/tests/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?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
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.osu.tests">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <activity android:label="OsuTestDummyLabel"
+                  android:name="OsuTestDummyName">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.osu"
+        android:label="OSU App Tests">
+    </instrumentation>
+
+</manifest>
diff --git a/packages/Osu2/tests/README.md b/packages/Osu2/tests/README.md
new file mode 100644
index 0000000..dbfa79c
--- /dev/null
+++ b/packages/Osu2/tests/README.md
@@ -0,0 +1,45 @@
+# OSU Unit Tests
+This package contains unit tests for the OSU app based on the
+[Android Testing Support Library](http://developer.android.com/tools/testing-support-library/index.html).
+The test cases are built using the [JUnit](http://junit.org/) and [Mockito](http://mockito.org/)
+libraries.
+
+## Running Tests
+The easiest way to run tests is simply run
+
+```
+frameworks/base/packages/Osu2/tests/runtests.sh
+```
+
+`runtests.sh` will build the test project and all of its dependencies and push the APK to the
+connected device. It will then run the tests on the device.
+
+To enable syncing data to the device for first time after clean reflash:
+1. adb disable-verity
+2. adb reboot
+3. adb remount
+
+See below for a few example of options to limit which tests are run.
+See the
+[AndroidJUnitRunner Documentation](https://developer.android.com/reference/android/support/test/runner/AndroidJUnitRunner.html)
+for more details on the supported options.
+
+```
+runtests.sh -e package com.android.osu
+runtests.sh -e class com.android.osu.NetworkConnectionTest
+```
+
+If you manually build and push the test APK to the device you can run tests using
+
+```
+adb shell am instrument -w 'com.android.osu.tests/android.support.test.runner.AndroidJUnitRunner'
+```
+
+## Adding Tests
+Tests can be added by adding classes to the src directory. JUnit4 style test cases can
+be written by simply annotating test methods with `org.junit.Test`.
+
+## Debugging Tests
+If you are trying to debug why tests are not doing what you expected, you can add android log
+statements and use logcat to view them. The beginning and end of every tests is automatically logged
+with the tag `TestRunner`.
diff --git a/packages/Osu2/tests/runtests.sh b/packages/Osu2/tests/runtests.sh
new file mode 100755
index 0000000..3513f5b
--- /dev/null
+++ b/packages/Osu2/tests/runtests.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+if [ -z $ANDROID_BUILD_TOP ]; then
+  echo "You need to source and lunch before you can use this script"
+  exit 1
+fi
+
+echo "Running tests"
+
+set -e # fail early
+
+echo "+ mmma -j32 $ANDROID_BUILD_TOP/frameworks/base/packages/Osu2/tests"
+# NOTE Don't actually run the command above since this shell doesn't inherit functions from the
+#      caller.
+make -j32 -C $ANDROID_BUILD_TOP -f build/core/main.mk MODULES-IN-frameworks-base-packages-Osu2-tests
+
+set -x # print commands
+
+adb root
+adb wait-for-device
+
+adb install -r -g "$OUT/data/app/OsuTests/OsuTests.apk"
+
+adb shell am instrument -w "$@" 'com.android.osu.tests/android.support.test.runner.AndroidJUnitRunner'
diff --git a/packages/Osu2/tests/src/com/android/osu/NetworkConnectionTest.java b/packages/Osu2/tests/src/com/android/osu/NetworkConnectionTest.java
new file mode 100644
index 0000000..2753249
--- /dev/null
+++ b/packages/Osu2/tests/src/com/android/osu/NetworkConnectionTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.osu;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiSsid;
+import android.os.Handler;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+
+import java.io.IOException;
+
+/**
+ * Unit tests for {@link com.android.osu.NetworkConnection}.
+ */
+@SmallTest
+public class NetworkConnectionTest {
+    private static final String TEST_SSID = "TEST SSID";
+    private static final String TEST_SSID_WITH_QUOTES = "\"" + TEST_SSID + "\"";
+    private static final int TEST_NETWORK_ID = 1;
+
+    @Mock Context mContext;
+    @Mock Handler mHandler;
+    @Mock WifiManager mWifiManager;
+    @Mock NetworkConnection.Callbacks mCallbacks;
+
+    @Before
+    public void setUp() throws Exception {
+        initMocks(this);
+        when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
+    }
+
+    /**
+     * Verify that an IOException will be thrown when failed to add the network.
+     *
+     * @throws Exception
+     */
+    @Test(expected = IOException.class)
+    public void networkAddFailed() throws Exception {
+        when(mWifiManager.addNetwork(any(WifiConfiguration.class))).thenReturn(-1);
+        new NetworkConnection(mContext, mHandler, WifiSsid.createFromAsciiEncoded(TEST_SSID),
+                null, mCallbacks);
+    }
+
+    /**
+     * Verify that an IOException will be thrown when failed to enable the network.
+     *
+     * @throws Exception
+     */
+    @Test(expected = IOException.class)
+    public void networkEnableFailed() throws Exception {
+        when(mWifiManager.addNetwork(any(WifiConfiguration.class))).thenReturn(TEST_NETWORK_ID);
+        when(mWifiManager.enableNetwork(eq(TEST_NETWORK_ID), eq(true))).thenReturn(false);
+        new NetworkConnection(mContext, mHandler, WifiSsid.createFromAsciiEncoded(TEST_SSID),
+                null, mCallbacks);
+    }
+
+    /**
+     * Verify that the connection is established after receiving a
+     * WifiManager.NETWORK_STATE_CHANGED_ACTION intent indicating that we are connected.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void openNetworkConnectionEstablished() throws Exception {
+        when(mWifiManager.addNetwork(any(WifiConfiguration.class))).thenReturn(TEST_NETWORK_ID);
+        when(mWifiManager.enableNetwork(eq(TEST_NETWORK_ID), eq(true))).thenReturn(true);
+        NetworkConnection connection = new NetworkConnection(mContext, mHandler,
+                WifiSsid.createFromAsciiEncoded(TEST_SSID), null, mCallbacks);
+
+        // Verify the WifiConfiguration being added.
+        ArgumentCaptor<WifiConfiguration> wifiConfig =
+                ArgumentCaptor.forClass(WifiConfiguration.class);
+        verify(mWifiManager).addNetwork(wifiConfig.capture());
+        assertEquals(wifiConfig.getValue().SSID, TEST_SSID_WITH_QUOTES);
+
+        // Capture the BroadcastReceiver.
+        ArgumentCaptor<BroadcastReceiver> receiver =
+                ArgumentCaptor.forClass(BroadcastReceiver.class);
+        verify(mContext).registerReceiver(receiver.capture(), any(), any(), any());
+
+        // Setup intent.
+        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        NetworkInfo networkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, "WIFI", "");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", "");
+        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
+        WifiInfo wifiInfo = new WifiInfo();
+        wifiInfo.setNetworkId(TEST_NETWORK_ID);
+        intent.putExtra(WifiManager.EXTRA_WIFI_INFO, wifiInfo);
+
+        // Send intent to the receiver.
+        Network network = new Network(0);
+        when(mWifiManager.getCurrentNetwork()).thenReturn(network);
+        receiver.getValue().onReceive(mContext, intent);
+
+        // Verify we are connected.
+        verify(mCallbacks).onConnected(eq(network));
+    }
+}
diff --git a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
index 2b1b8ca..49fe52b 100644
--- a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
+++ b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
@@ -62,6 +62,8 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Još informacija o ovom štampaču"</string>
+    <string name="notification_channel_progress" msgid="872788690775721436">"Aktivni zadaci štampanja"</string>
+    <string name="notification_channel_failure" msgid="9042250774797916414">"Neuspeli zadaci štampanja"</string>
     <string name="could_not_create_file" msgid="3425025039427448443">"Pravljenje datoteke nije uspelo"</string>
     <string name="print_services_disabled_toast" msgid="9089060734685174685">"Neke usluge štampanja su onemogućene"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Pretraga štampača"</string>
diff --git a/packages/PrintSpooler/res/values-be/strings.xml b/packages/PrintSpooler/res/values-be/strings.xml
index 83d0627..c04756c 100644
--- a/packages/PrintSpooler/res/values-be/strings.xml
+++ b/packages/PrintSpooler/res/values-be/strings.xml
@@ -63,6 +63,8 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Больш падрабязная інфармацыя пра гэты прынтар"</string>
+    <string name="notification_channel_progress" msgid="872788690775721436">"Заданні друку, якія выконваюцца"</string>
+    <string name="notification_channel_failure" msgid="9042250774797916414">"Заданні друку са збоямі"</string>
     <string name="could_not_create_file" msgid="3425025039427448443">"Не ўдалося стварыць файл"</string>
     <string name="print_services_disabled_toast" msgid="9089060734685174685">"Некаторыя службы друку адключаны"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Пошук прынтараў"</string>
diff --git a/packages/PrintSpooler/res/values-bn/strings.xml b/packages/PrintSpooler/res/values-bn/strings.xml
index 88ba6ee..d2751f1 100644
--- a/packages/PrintSpooler/res/values-bn/strings.xml
+++ b/packages/PrintSpooler/res/values-bn/strings.xml
@@ -17,7 +17,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="4469836075319831821">"প্রিন্ট স্পোলার"</string>
-    <string name="more_options_button" msgid="2243228396432556771">"আরো বিকল্প"</string>
+    <string name="more_options_button" msgid="2243228396432556771">"আরও বিকল্প"</string>
     <string name="label_destination" msgid="9132510997381599275">"গন্তব্য"</string>
     <string name="label_copies" msgid="3634531042822968308">"প্রতিলিপিগুলি"</string>
     <string name="label_copies_summary" msgid="3861966063536529540">"অনুলিপিগুলি:"</string>
@@ -27,15 +27,15 @@
     <string name="label_duplex" msgid="5370037254347072243">"দ্বিভুজ"</string>
     <string name="label_orientation" msgid="2853142581990496477">"সজ্জা"</string>
     <string name="label_pages" msgid="7768589729282182230">"পৃষ্ঠাগুলি"</string>
-    <string name="destination_default_text" msgid="5422708056807065710">"একটি মুদ্রক নির্বাচন করুন"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"একটি মুদ্রক বেছে নিন"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"সমস্ত <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> এর পরিসর"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"যেমন, ১—৫,৮,১১—১৩"</string>
-    <string name="print_preview" msgid="8010217796057763343">"প্রিন্ট পূর্বরূপ"</string>
-    <string name="install_for_print_preview" msgid="6366303997385509332">"পূর্বরূপ দেখার জন্য PDF ভিউয়ার ইনস্টল করুন"</string>
+    <string name="print_preview" msgid="8010217796057763343">"প্রিন্ট প্রিভিউ"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"প্রিভিউ দেখার জন্য PDF ভিউয়ার ইনস্টল করুন"</string>
     <string name="printing_app_crashed" msgid="854477616686566398">"প্রিন্ট অ্যাপ্লিকেশান ক্র্যাশ করছে"</string>
     <string name="generating_print_job" msgid="3119608742651698916">"প্রিন্ট কার্য তৈরি করা হচ্ছে"</string>
-    <string name="save_as_pdf" msgid="5718454119847596853">"PDF হিসাবে সংরক্ষণ করুন"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"পিডিএফ হিসাবে সেভ করুন"</string>
     <string name="all_printers" msgid="5018829726861876202">"সমস্ত মুদ্রক…"</string>
     <string name="print_dialog" msgid="32628687461331979">"প্রিন্ট ডায়লগ"</string>
     <string name="current_page_template" msgid="5145005201131935302">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
@@ -44,33 +44,33 @@
     <string name="expand_handle" msgid="7282974448109280522">"প্রসারিত করার হ্যান্ডেল"</string>
     <string name="collapse_handle" msgid="6886637989442507451">"সঙ্কুচিত করার হ্যান্ডেল"</string>
     <string name="print_button" msgid="645164566271246268">"প্রিন্ট করুন"</string>
-    <string name="savetopdf_button" msgid="2976186791686924743">"PDF হিসাবে সংরক্ষণ করুন"</string>
+    <string name="savetopdf_button" msgid="2976186791686924743">"পিডিএফ হিসাবে সেভ করুন"</string>
     <string name="print_options_expanded" msgid="6944679157471691859">"প্রিন্ট বিকল্প প্রসারিত হয়েছে"</string>
     <string name="print_options_collapsed" msgid="7455930445670414332">"প্রিন্ট বিকল্প সংকুচিত হয়েছে"</string>
-    <string name="search" msgid="5421724265322228497">"অনুসন্ধান করুন"</string>
+    <string name="search" msgid="5421724265322228497">"খুঁজুন"</string>
     <string name="all_printers_label" msgid="3178848870161526399">"সমস্ত মুদ্রক"</string>
     <string name="add_print_service_label" msgid="5356702546188981940">"পরিষেবা যোগ করুন"</string>
     <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"অনুসন্ধান বাক্স দেখানো হচ্ছে"</string>
     <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"অনুসন্ধান বাক্স লুকানো রয়েছে"</string>
     <string name="print_add_printer" msgid="1088656468360653455">"মুদ্রক যোগ করুন"</string>
-    <string name="print_select_printer" msgid="7388760939873368698">"মুদ্রক নির্বাচন করুন"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"মুদ্রক বেছে নিন"</string>
     <string name="print_forget_printer" msgid="5035287497291910766">"মুদ্রকটিকে সরিয়ে দিন"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
       <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g>টি মুদ্রক খুঁজে পাওয়া গেছে</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g>টি মুদ্রক খুঁজে পাওয়া গেছে</item>
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
-    <string name="printer_info_desc" msgid="7181988788991581654">"এই মুদ্রকটির বিষয়ে আরো তথ্য"</string>
+    <string name="printer_info_desc" msgid="7181988788991581654">"এই মুদ্রকটির বিষয়ে আরও তথ্য"</string>
     <string name="notification_channel_progress" msgid="872788690775721436">"এগুলি প্রিন্ট হচ্ছে"</string>
     <string name="notification_channel_failure" msgid="9042250774797916414">"এগুলি প্রিন্ট করা যায়নি"</string>
     <string name="could_not_create_file" msgid="3425025039427448443">"ফাইল তৈরি করা গেল না"</string>
-    <string name="print_services_disabled_toast" msgid="9089060734685174685">"কিছু মুদ্রণ পরিষেবা অক্ষম করা আছে"</string>
+    <string name="print_services_disabled_toast" msgid="9089060734685174685">"কিছু প্রিন্ট পরিষেবা অক্ষম করা আছে"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"মুদ্রকগুলি অনুসন্ধান করা হচ্ছে"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"প্রিন্ট পরিষেবা সক্ষম নেই"</string>
     <string name="print_no_printers" msgid="4869403323900054866">"কোনো মুদ্রক পাওয়া যায়নি"</string>
     <string name="cannot_add_printer" msgid="7840348733668023106">"মুদ্রকগুলি যোগ করা যাবে না"</string>
-    <string name="select_to_add_printers" msgid="3800709038689830974">"মুদ্রক যোগ করতে নির্বাচন করুন"</string>
-    <string name="enable_print_service" msgid="3482815747043533842">"সক্ষম করতে নির্বাচন করুন"</string>
+    <string name="select_to_add_printers" msgid="3800709038689830974">"মুদ্রক যোগ করতে বেছে নিন"</string>
+    <string name="enable_print_service" msgid="3482815747043533842">"সক্ষম করতে বেছে নিন"</string>
     <string name="enabled_services_title" msgid="7036986099096582296">"সক্ষম করা পরিষেবাগুলি"</string>
     <string name="recommended_services_title" msgid="3799434882937956924">"প্রস্তাবিত পরিষেবাগুলি"</string>
     <string name="disabled_services_title" msgid="7313253167968363211">"অক্ষম করা পরিষেবাগুলি"</string>
@@ -84,7 +84,7 @@
     <string name="failed_notification_title_template" msgid="2256217208186530973">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> মুদ্রক ত্রুটি"</string>
     <string name="blocked_notification_title_template" msgid="1175435827331588646">"মুদ্রক <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> অবরুদ্ধ করেছে"</string>
     <string name="cancel" msgid="4373674107267141885">"বাতিল করুন"</string>
-    <string name="restart" msgid="2472034227037808749">"পুনর্সূচনা"</string>
+    <string name="restart" msgid="2472034227037808749">"রিস্টার্ট করুন"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"মুদ্রকে কোনো সংযোগ নেই"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"অজানা"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> ব্যবহার করবেন?"</string>
@@ -99,13 +99,13 @@
     <item msgid="79513688117503758">"সংক্ষিপ্ত প্রান্ত"</item>
   </string-array>
   <string-array name="orientation_labels">
-    <item msgid="4061931020926489228">"প্রতিকৃতি"</item>
-    <item msgid="3199660090246166812">"ভূদৃশ্য"</item>
+    <item msgid="4061931020926489228">"পোর্ট্রেট"</item>
+    <item msgid="3199660090246166812">"ল্যান্ডস্কেপ"</item>
   </string-array>
     <string name="print_write_error_message" msgid="5787642615179572543">"ফাইলে লেখা যায়নি"</string>
     <string name="print_error_default_message" msgid="8602678405502922346">"দুঃখিত, এটি কাজ করেনি৷ আবার চেষ্টা করুন৷"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"আবার চেষ্টা করুন"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"এই মূহুর্তে প্রিন্টার উপলব্ধ নয়।"</string>
-    <string name="print_cannot_load_page" msgid="6179560924492912009">"পূর্বরূপ প্রদর্শন করা যাবে না"</string>
-    <string name="print_preparing_preview" msgid="3939930735671364712">"পূর্বরূপ প্রস্তুত করছে..."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"প্রিভিউ প্রদর্শন করা যাবে না"</string>
+    <string name="print_preparing_preview" msgid="3939930735671364712">"প্রিভিউ প্রস্তুত করা হচ্ছে..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-bs/strings.xml b/packages/PrintSpooler/res/values-bs/strings.xml
index 2450be3..d3f1b80 100644
--- a/packages/PrintSpooler/res/values-bs/strings.xml
+++ b/packages/PrintSpooler/res/values-bs/strings.xml
@@ -62,6 +62,8 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Više informacija o ovom štampaču"</string>
+    <string name="notification_channel_progress" msgid="872788690775721436">"Tekući zadaci za štampanje"</string>
+    <string name="notification_channel_failure" msgid="9042250774797916414">"Neizvršeni zadaci za štampanje"</string>
     <string name="could_not_create_file" msgid="3425025039427448443">"Nije uspjelo kreiranje fajla"</string>
     <string name="print_services_disabled_toast" msgid="9089060734685174685">"Neke usluge za štampanje su isključene"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Traženje štampača"</string>
diff --git a/packages/PrintSpooler/res/values-gu/strings.xml b/packages/PrintSpooler/res/values-gu/strings.xml
index f5d698d..4d035da 100644
--- a/packages/PrintSpooler/res/values-gu/strings.xml
+++ b/packages/PrintSpooler/res/values-gu/strings.xml
@@ -26,7 +26,7 @@
     <string name="label_color" msgid="1108690305218188969">"રંગ"</string>
     <string name="label_duplex" msgid="5370037254347072243">"દ્વિભુજ"</string>
     <string name="label_orientation" msgid="2853142581990496477">"ઓરિએન્ટેશન"</string>
-    <string name="label_pages" msgid="7768589729282182230">"પૃષ્ઠો"</string>
+    <string name="label_pages" msgid="7768589729282182230">"પેજ"</string>
     <string name="destination_default_text" msgid="5422708056807065710">"પ્રિન્ટર પસંદ કરો"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"તમામ <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> ની શ્રેણી"</string>
@@ -84,7 +84,7 @@
     <string name="failed_notification_title_template" msgid="2256217208186530973">"પ્રિન્ટર ભૂલ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="blocked_notification_title_template" msgid="1175435827331588646">"પ્રિન્ટરે <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> અવરોધિત કર્યું"</string>
     <string name="cancel" msgid="4373674107267141885">"રદ કરો"</string>
-    <string name="restart" msgid="2472034227037808749">"પુનઃપ્રારંભ કરો"</string>
+    <string name="restart" msgid="2472034227037808749">"રિસ્ટાર્ટ કરો"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"પ્રિન્ટર માટે કોઈ કનેક્શન નથી"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"અજાણ્યું"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> નો ઉપયોગ કરીએ?"</string>
diff --git a/packages/PrintSpooler/res/values-hi/strings.xml b/packages/PrintSpooler/res/values-hi/strings.xml
index 809431d..37777d2 100644
--- a/packages/PrintSpooler/res/values-hi/strings.xml
+++ b/packages/PrintSpooler/res/values-hi/strings.xml
@@ -17,7 +17,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="4469836075319831821">"प्रिंट स्पूलर"</string>
-    <string name="more_options_button" msgid="2243228396432556771">"अधिक विकल्प"</string>
+    <string name="more_options_button" msgid="2243228396432556771">"ज़्यादा विकल्प"</string>
     <string name="label_destination" msgid="9132510997381599275">"गंतव्य"</string>
     <string name="label_copies" msgid="3634531042822968308">"प्रतियां"</string>
     <string name="label_copies_summary" msgid="3861966063536529540">"प्रतियां:"</string>
@@ -25,33 +25,33 @@
     <string name="label_paper_size_summary" msgid="5668204981332138168">"काग़ज़ का आकार:"</string>
     <string name="label_color" msgid="1108690305218188969">"रंग"</string>
     <string name="label_duplex" msgid="5370037254347072243">"दो-तरफ़ा"</string>
-    <string name="label_orientation" msgid="2853142581990496477">"अभिविन्‍यास"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"स्क्रीन की दिशा"</string>
     <string name="label_pages" msgid="7768589729282182230">"पेज"</string>
     <string name="destination_default_text" msgid="5422708056807065710">"कोई प्रिंटर चुनें"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"सभी <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"पेज संख्या <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
-    <string name="pages_range_example" msgid="8558694453556945172">"उदा. 1—5,8,11—13"</string>
-    <string name="print_preview" msgid="8010217796057763343">"प्रिंट पूर्वावलोकन"</string>
-    <string name="install_for_print_preview" msgid="6366303997385509332">"पूर्वावलोकन के लिए PDF व्यूअर इंस्टॉल करें"</string>
-    <string name="printing_app_crashed" msgid="854477616686566398">"प्रिंटिंग ऐप्लिकेशन क्रैश हो गया"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"उदाहरण 1—5,8,11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"प्रिंट की झलक"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"झलक देखने के लिए PDF व्यूअर इंस्टॉल करें"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"प्रिंटिंग ऐप बंद हो गया"</string>
     <string name="generating_print_job" msgid="3119608742651698916">"प्रिंट कार्य जनरेट हो रहा है"</string>
-    <string name="save_as_pdf" msgid="5718454119847596853">"PDF के रूप में जोड़ें"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"पीडीएफ़ के तौर पर सेव करें"</string>
     <string name="all_printers" msgid="5018829726861876202">"सभी प्रिंटर..."</string>
     <string name="print_dialog" msgid="32628687461331979">"प्रिंट डॉयलॉग"</string>
     <string name="current_page_template" msgid="5145005201131935302">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
     <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="PAGE_COUNT">%2$d</xliff:g> में से पेज <xliff:g id="CURRENT_PAGE">%1$d</xliff:g>"</string>
     <string name="summary_template" msgid="8899734908625669193">"सारांश, प्रतियां <xliff:g id="COPIES">%1$s</xliff:g>, काग़ज़ का आकार <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
-    <string name="expand_handle" msgid="7282974448109280522">"हैंडल विस्तृत करें"</string>
-    <string name="collapse_handle" msgid="6886637989442507451">"हैंडल संक्षिप्त करें"</string>
+    <string name="expand_handle" msgid="7282974448109280522">"हैंडल का विस्तार करें"</string>
+    <string name="collapse_handle" msgid="6886637989442507451">"हैंडल को छोटा करें"</string>
     <string name="print_button" msgid="645164566271246268">"प्रिंट करें"</string>
-    <string name="savetopdf_button" msgid="2976186791686924743">"PDF में जोड़ें"</string>
+    <string name="savetopdf_button" msgid="2976186791686924743">"पीडीएफ़ में सेव करें"</string>
     <string name="print_options_expanded" msgid="6944679157471691859">"प्रिंट विकल्पों को विस्तृत किया गया"</string>
     <string name="print_options_collapsed" msgid="7455930445670414332">"प्रिंट विकल्पों को संक्षिप्त किया गया"</string>
-    <string name="search" msgid="5421724265322228497">"खोजें"</string>
+    <string name="search" msgid="5421724265322228497">"सर्च करें"</string>
     <string name="all_printers_label" msgid="3178848870161526399">"सभी प्रिंटर"</string>
     <string name="add_print_service_label" msgid="5356702546188981940">"सेवा जोड़ें"</string>
-    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"खोज बॉक्स प्रदर्शित है"</string>
-    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"खोज बॉक्स छिपा हुआ है"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"सर्च बॉक्स दिखाई दे रहा है"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"सर्च बॉक्स छिपा हुआ है"</string>
     <string name="print_add_printer" msgid="1088656468360653455">"प्रिंटर जोड़ें"</string>
     <string name="print_select_printer" msgid="7388760939873368698">"प्रिंटर चुनें"</string>
     <string name="print_forget_printer" msgid="5035287497291910766">"प्रिंटर को भूल जाएं"</string>
@@ -60,12 +60,12 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> प्रिंटर मिले</item>
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
-    <string name="printer_info_desc" msgid="7181988788991581654">"इस प्रिंटर के बारे में अधिक जानकारी"</string>
+    <string name="printer_info_desc" msgid="7181988788991581654">"इस प्रिंटर के बारे में ज़्यादा जानकारी"</string>
     <string name="notification_channel_progress" msgid="872788690775721436">"चल रहे प्रिंट कार्य"</string>
     <string name="notification_channel_failure" msgid="9042250774797916414">"असफल रहे प्रिंट कार्य"</string>
     <string name="could_not_create_file" msgid="3425025039427448443">"फ़ाइल नहीं बनाई जा सकी"</string>
     <string name="print_services_disabled_toast" msgid="9089060734685174685">"कुछ प्रिंट सेवाएं अक्षम हैं"</string>
-    <string name="print_searching_for_printers" msgid="6550424555079932867">"प्रिंटर खोज रहा है"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"प्रिंटर सर्च कर रहा है"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"कोई भी प्रिंट सेवा सक्षम नहीं है"</string>
     <string name="print_no_printers" msgid="4869403323900054866">"कोई प्रिंटर नहीं मिले"</string>
     <string name="cannot_add_printer" msgid="7840348733668023106">"प्रिंटर जोड़े नहीं जा सकते"</string>
@@ -83,7 +83,7 @@
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> रद्द हो रहा है"</string>
     <string name="failed_notification_title_template" msgid="2256217208186530973">"प्रिंटर गड़बड़ी <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="blocked_notification_title_template" msgid="1175435827331588646">"प्रिंटर अवरोधित <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
-    <string name="cancel" msgid="4373674107267141885">"अभी नहीं"</string>
+    <string name="cancel" msgid="4373674107267141885">"रद्द करें"</string>
     <string name="restart" msgid="2472034227037808749">"पुन: आरंभ करें"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"प्रिंटर के लिए कोई कनेक्शन नहीं"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"अज्ञात"</string>
@@ -106,6 +106,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"क्षमा करें, उससे बात नहीं बनी. पुन: प्रयास करें."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"फिर से प्रयास करें"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"यह प्रिंटर इस समय उपलब्ध नहीं है."</string>
-    <string name="print_cannot_load_page" msgid="6179560924492912009">"पूर्वावलोकन प्रदर्शित नहीं किया जा सकता"</string>
-    <string name="print_preparing_preview" msgid="3939930735671364712">"पूर्वावलोकन तैयार हो रहा है..."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"झलक नहीं दिखाई जा सकती"</string>
+    <string name="print_preparing_preview" msgid="3939930735671364712">"झलक तैयार हो रही है..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-iw/strings.xml b/packages/PrintSpooler/res/values-iw/strings.xml
index 6000500..22ef612 100644
--- a/packages/PrintSpooler/res/values-iw/strings.xml
+++ b/packages/PrintSpooler/res/values-iw/strings.xml
@@ -47,9 +47,9 @@
     <string name="savetopdf_button" msgid="2976186791686924743">"‏שמור כ-PDF"</string>
     <string name="print_options_expanded" msgid="6944679157471691859">"אפשרויות ההדפסה הורחבו"</string>
     <string name="print_options_collapsed" msgid="7455930445670414332">"אפשרויות ההדפסה כווצו"</string>
-    <string name="search" msgid="5421724265322228497">"חפש"</string>
+    <string name="search" msgid="5421724265322228497">"חיפוש"</string>
     <string name="all_printers_label" msgid="3178848870161526399">"כל המדפסות"</string>
-    <string name="add_print_service_label" msgid="5356702546188981940">"הוסף שירות"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"הוספת שירות"</string>
     <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"תיבת החיפוש מוצגת"</string>
     <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"תיבת החיפוש מוסתרת"</string>
     <string name="print_add_printer" msgid="1088656468360653455">"הוסף מדפסת"</string>
@@ -88,7 +88,7 @@
     <string name="failed_notification_title_template" msgid="2256217208186530973">"שגיאת מדפסת ב-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="blocked_notification_title_template" msgid="1175435827331588646">"המדפסת חסמה את <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancel" msgid="4373674107267141885">"ביטול"</string>
-    <string name="restart" msgid="2472034227037808749">"הפעל מחדש"</string>
+    <string name="restart" msgid="2472034227037808749">"הפעלה מחדש"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"אין חיבור למדפסת"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"לא ידוע"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"האם להשתמש ב-<xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
diff --git a/packages/PrintSpooler/res/values-kn/strings.xml b/packages/PrintSpooler/res/values-kn/strings.xml
index c8eaf6e..2f8e6e0 100644
--- a/packages/PrintSpooler/res/values-kn/strings.xml
+++ b/packages/PrintSpooler/res/values-kn/strings.xml
@@ -99,7 +99,7 @@
     <item msgid="79513688117503758">"ಚಿಕ್ಕದಾದ ಅಂಚು"</item>
   </string-array>
   <string-array name="orientation_labels">
-    <item msgid="4061931020926489228">"ಪೋಟ್ರೇಟ್"</item>
+    <item msgid="4061931020926489228">"ಪೋರ್ಟ್ರೇಟ್"</item>
     <item msgid="3199660090246166812">"ಲ್ಯಾಂಡ್‌ಸ್ಕೇಪ್"</item>
   </string-array>
     <string name="print_write_error_message" msgid="5787642615179572543">"ಫೈಲ್‌ಗೆ ರೈಟ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
diff --git a/packages/PrintSpooler/res/values-mr/strings.xml b/packages/PrintSpooler/res/values-mr/strings.xml
index 8981cd8..05eb853 100644
--- a/packages/PrintSpooler/res/values-mr/strings.xml
+++ b/packages/PrintSpooler/res/values-mr/strings.xml
@@ -25,17 +25,17 @@
     <string name="label_paper_size_summary" msgid="5668204981332138168">"कागद आकार:"</string>
     <string name="label_color" msgid="1108690305218188969">"रंग"</string>
     <string name="label_duplex" msgid="5370037254347072243">"दोन्ही बाजूंनी"</string>
-    <string name="label_orientation" msgid="2853142581990496477">"अभिमुखता"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"ओरिएंटेशन"</string>
     <string name="label_pages" msgid="7768589729282182230">"पृष्ठे"</string>
     <string name="destination_default_text" msgid="5422708056807065710">"प्रिंटर निवडा"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"सर्व <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> ची श्रेणी"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"उदा. 1—5,8,11—13"</string>
     <string name="print_preview" msgid="8010217796057763343">"मुद्रण पूर्वावलोकन"</string>
-    <string name="install_for_print_preview" msgid="6366303997385509332">"पूर्वावलोकनासाठी PDF दर्शक स्‍थापित करा"</string>
-    <string name="printing_app_crashed" msgid="854477616686566398">"मुद्रण करण्याचा अ‍ॅप क्रॅश झाला"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"पूर्वावलोकनासाठी पीडीएफ व्ह्यूअर इंस्टॉल करा"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"प्रिंटिंग अ‍ॅप क्रॅश झाले"</string>
     <string name="generating_print_job" msgid="3119608742651698916">"मुद्रण कार्य व्‍युत्‍पन्न करीत आहे"</string>
-    <string name="save_as_pdf" msgid="5718454119847596853">"PDF म्‍हणून जतन करा"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"पीडीएफ म्‍हणून सेव्ह करा"</string>
     <string name="all_printers" msgid="5018829726861876202">"सर्व प्रिंटर..."</string>
     <string name="print_dialog" msgid="32628687461331979">"मुद्रण संवाद"</string>
     <string name="current_page_template" msgid="5145005201131935302">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
@@ -44,7 +44,7 @@
     <string name="expand_handle" msgid="7282974448109280522">"विस्तृत करण्याचे हँडल"</string>
     <string name="collapse_handle" msgid="6886637989442507451">"संक्षिप्त करण्याचे हँडल"</string>
     <string name="print_button" msgid="645164566271246268">"मुद्रण करा"</string>
-    <string name="savetopdf_button" msgid="2976186791686924743">"PDF वर जतन करा"</string>
+    <string name="savetopdf_button" msgid="2976186791686924743">"पीडीएफ वर सेव्ह करा"</string>
     <string name="print_options_expanded" msgid="6944679157471691859">"मुद्रण पर्याय विस्तृत झाले"</string>
     <string name="print_options_collapsed" msgid="7455930445670414332">"मुद्रण पर्याय संक्षिप्त झाले"</string>
     <string name="search" msgid="5421724265322228497">"शोध"</string>
@@ -76,12 +76,12 @@
     <string name="disabled_services_title" msgid="7313253167968363211">"अक्षम केलल्या सेवा"</string>
     <string name="all_services_title" msgid="5578662754874906455">"सर्व सेवा"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> प्रिंटर शोधण्यासाठी स्थापित करा</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> प्रिंटर शोधण्यासाठी स्थापित करा</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> प्रिंटर शोधण्यासाठी इंस्टॉल करा</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> प्रिंटर शोधण्यासाठी इंस्टॉल करा</item>
     </plurals>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> मुद्रण करीत आहे"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> रद्द करीत आहे"</string>
-    <string name="failed_notification_title_template" msgid="2256217208186530973">"प्रिंटर त्रुटी <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"प्रिंटर एरर <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="blocked_notification_title_template" msgid="1175435827331588646">"प्रिंटरने <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> अवरोधित केले"</string>
     <string name="cancel" msgid="4373674107267141885">"रद्द करा"</string>
     <string name="restart" msgid="2472034227037808749">"रीस्टार्ट करा"</string>
@@ -100,7 +100,7 @@
   </string-array>
   <string-array name="orientation_labels">
     <item msgid="4061931020926489228">"पोट्रेट"</item>
-    <item msgid="3199660090246166812">"भूदृश्य"</item>
+    <item msgid="3199660090246166812">"लॅंडस्केप"</item>
   </string-array>
     <string name="print_write_error_message" msgid="5787642615179572543">"फायलीवर लिहू शकलो नाही"</string>
     <string name="print_error_default_message" msgid="8602678405502922346">"क्षमस्व, त्याने कार्य केले नाही. पुन्हा प्रयत्न करा."</string>
diff --git a/packages/PrintSpooler/res/values-my/strings.xml b/packages/PrintSpooler/res/values-my/strings.xml
index c581e59..7c7b03e6 100644
--- a/packages/PrintSpooler/res/values-my/strings.xml
+++ b/packages/PrintSpooler/res/values-my/strings.xml
@@ -49,7 +49,7 @@
     <string name="print_options_collapsed" msgid="7455930445670414332">"ပရင့်ထုတ် ရွေးစရာများကို ခေါက်ထား"</string>
     <string name="search" msgid="5421724265322228497">"ရှာဖွေခြင်း"</string>
     <string name="all_printers_label" msgid="3178848870161526399">"စာထုတ်စက် အားလုံး"</string>
-    <string name="add_print_service_label" msgid="5356702546188981940">"ဆားဗစ် အသစ်ထည့်ရန်"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"ဝန်ဆောင်မှုထည့်ရန်"</string>
     <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"ရှာဖွေစရာ နေရာ မြင်တွေ့ရပါသည်"</string>
     <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"ရှာဖွေရန် နေရာ ပျောက်ကွယ်နေပါသည်"</string>
     <string name="print_add_printer" msgid="1088656468360653455">"စာထုတ်စက်ကို ထည့်ပါ"</string>
diff --git a/packages/PrintSpooler/res/values-ne/strings.xml b/packages/PrintSpooler/res/values-ne/strings.xml
index c5f5978..18f96dd 100644
--- a/packages/PrintSpooler/res/values-ne/strings.xml
+++ b/packages/PrintSpooler/res/values-ne/strings.xml
@@ -84,7 +84,7 @@
     <string name="failed_notification_title_template" msgid="2256217208186530973">"प्रिन्टर त्रुटि <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="blocked_notification_title_template" msgid="1175435827331588646">"प्रिन्टर ब्लक गरियो <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancel" msgid="4373674107267141885">"रद्द गर्नुहोस्"</string>
-    <string name="restart" msgid="2472034227037808749">"पुनःस्टार्ट गर्नुहोस्"</string>
+    <string name="restart" msgid="2472034227037808749">"पुनः सुरु गर्नुहोस्"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"प्रिन्टरमा कुनै जडान छैन"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"अज्ञात"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> प्रयोग गर्ने हो?"</string>
diff --git a/packages/PrintSpooler/res/values-pa/strings.xml b/packages/PrintSpooler/res/values-pa/strings.xml
index d7885ad..4ce8f97 100644
--- a/packages/PrintSpooler/res/values-pa/strings.xml
+++ b/packages/PrintSpooler/res/values-pa/strings.xml
@@ -30,12 +30,12 @@
     <string name="destination_default_text" msgid="5422708056807065710">"ਇੱਕ ਪ੍ਰਿੰਟਰ ਚੁਣੋ"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"ਸਾਰੇ <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> ਦੀ ਰੇਂਜ"</string>
-    <string name="pages_range_example" msgid="8558694453556945172">"ਉਦਾਹਰਨ ਲਈ 1—5,8,11—13"</string>
-    <string name="print_preview" msgid="8010217796057763343">"ਪ੍ਰਿੰਟ ਪ੍ਰੀਵਿਊ"</string>
-    <string name="install_for_print_preview" msgid="6366303997385509332">"ਪ੍ਰੀਵਿਊ ਲਈ PDF ਵਿਊਅਰ ਇੰਸਟੌਲ ਕਰੋ"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"ਉਦਾਹਰਨ ਵਜੋਂ 1—5,8,11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"ਪ੍ਰਿੰਟ ਦੀ ਪੂਰਵ-ਝਲਕ"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"ਪੂਰਵ-ਝਲਕ ਲਈ PDF ਵਿਊਅਰ ਸਥਾਪਤ ਕਰੋ"</string>
     <string name="printing_app_crashed" msgid="854477616686566398">"ਪ੍ਰਿੰਟਿੰਗ ਐਪ ਕ੍ਰੈਸ਼ ਹੋਇਆ"</string>
     <string name="generating_print_job" msgid="3119608742651698916">"ਪ੍ਰਿੰਟ ਜੌਬ ਬਣਾ ਰਿਹਾ ਹੈ"</string>
-    <string name="save_as_pdf" msgid="5718454119847596853">"PDF ਦੇ ਤੌਰ ਤੇ ਰੱਖਿਅਤ ਕਰੋ"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"PDF ਦੇ ਤੌਰ \'ਤੇ ਰੱਖਿਅਤ ਕਰੋ"</string>
     <string name="all_printers" msgid="5018829726861876202">"ਸਾਰੇ ਪ੍ਰਿੰਟਰ…"</string>
     <string name="print_dialog" msgid="32628687461331979">"ਪ੍ਰਿੰਟ ਡਾਇਲੌਗ"</string>
     <string name="current_page_template" msgid="5145005201131935302">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
@@ -43,16 +43,16 @@
     <string name="summary_template" msgid="8899734908625669193">"ਸਾਰ, ਕਾਪੀਆਂ <xliff:g id="COPIES">%1$s</xliff:g>, ਪੇਪਰ ਦਾ ਆਕਾਰ <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
     <string name="expand_handle" msgid="7282974448109280522">"ਹੈਂਡਲ ਨੂੰ ਵਿਸਤਾਰ ਦਿਓ"</string>
     <string name="collapse_handle" msgid="6886637989442507451">"ਇਕੱਠਾ ਹੋਣ ਦੀ ਸੰਭਾਲ"</string>
-    <string name="print_button" msgid="645164566271246268">"ਪ੍ਰਿੰਟ"</string>
+    <string name="print_button" msgid="645164566271246268">"ਪ੍ਰਿੰਟ ਕਰੋ"</string>
     <string name="savetopdf_button" msgid="2976186791686924743">"PDF ਵਿੱਚ ਰੱਖਿਅਤ ਕਰੋ"</string>
     <string name="print_options_expanded" msgid="6944679157471691859">"ਪ੍ਰਿੰਟ ਚੋਣਾਂ ਦਾ ਵਿਸਤਾਰ ਕੀਤਾ"</string>
     <string name="print_options_collapsed" msgid="7455930445670414332">"ਪ੍ਰਿੰਟ ਚੋਣਾਂ ਇਕੱਠਾ ਹੋਈਆਂ"</string>
     <string name="search" msgid="5421724265322228497">"ਖੋਜੋ"</string>
     <string name="all_printers_label" msgid="3178848870161526399">"ਸਾਰੇ ਪ੍ਰਿੰਟਰ"</string>
-    <string name="add_print_service_label" msgid="5356702546188981940">"ਸੇਵਾ ਜੋੜੋ"</string>
-    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"ਖੋਜ ਬੌਕਸ ਦਿਖਾਇਆ"</string>
-    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"ਖੋਜ ਬੌਕਸ ਲੁਕਾਇਆ"</string>
-    <string name="print_add_printer" msgid="1088656468360653455">"ਪ੍ਰਿੰਟਰ ਜੋੜੋ"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"ਸੇਵਾ ਸ਼ਾਮਲ ਕਰੋ"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"ਖੋਜ ਬਾਕਸ ਦਿਖਾਇਆ"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"ਖੋਜ ਬਾਕਸ ਲੁਕਾਇਆ"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"ਪ੍ਰਿੰਟਰ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="print_select_printer" msgid="7388760939873368698">"ਪ੍ਰਿੰਟਰ ਚੁਣੋ"</string>
     <string name="print_forget_printer" msgid="5035287497291910766">"ਪ੍ਰਿੰਟਰ ਭੁੱਲੋ"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
@@ -61,16 +61,16 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"ਇਸ ਪ੍ਰਿੰਟਰ ਬਾਰੇ ਹੋਰ ਜਾਣਕਾਰੀ"</string>
-    <string name="notification_channel_progress" msgid="872788690775721436">"ਚੱਲ ਰਹੇ ਪ੍ਰਿੰਟ ਕਾਰਜ"</string>
-    <string name="notification_channel_failure" msgid="9042250774797916414">"ਅਸਫਲ ਰਹੇ ਪ੍ਰਿੰਟ ਕਾਰਜ"</string>
+    <string name="notification_channel_progress" msgid="872788690775721436">"ਚੱਲ ਰਹੇ ਪ੍ਰਿੰਟ ਜੌਬ"</string>
+    <string name="notification_channel_failure" msgid="9042250774797916414">"ਅਸਫਲ ਰਹੇ ਪ੍ਰਿੰਟ ਜੌਬ"</string>
     <string name="could_not_create_file" msgid="3425025039427448443">"ਫ਼ਾਈਲ ਨੂੰ ਬਣਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ"</string>
-    <string name="print_services_disabled_toast" msgid="9089060734685174685">"ਕੁਝ ਪ੍ਰਿੰਟ ਸੇਵਾਵਾਂ ਅਯੋਗ ਬਣਾਈਆਂ ਗਈਆਂ ਹਨ"</string>
+    <string name="print_services_disabled_toast" msgid="9089060734685174685">"ਕੁਝ ਪ੍ਰਿੰਟ ਸੇਵਾਵਾਂ ਬੰਦ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"ਪ੍ਰਿੰਟਰ ਖੋਜ ਰਿਹਾ ਹੈ"</string>
-    <string name="print_no_print_services" msgid="8561247706423327966">"ਪ੍ਰਿੰਟ ਸੇਵਾਵਾਂ ਯੋਗ ਨਹੀਂ ਬਣਾਈਆਂ ਗਈਆਂ"</string>
+    <string name="print_no_print_services" msgid="8561247706423327966">"ਪ੍ਰਿੰਟ ਸੇਵਾਵਾਂ ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਕੀਤਾ ਗਿਆ"</string>
     <string name="print_no_printers" msgid="4869403323900054866">"ਕੋਈ ਪ੍ਰਿੰਟਰ ਨਹੀਂ ਮਿਲੇ"</string>
     <string name="cannot_add_printer" msgid="7840348733668023106">"ਪ੍ਰਿੰਟਰ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ"</string>
     <string name="select_to_add_printers" msgid="3800709038689830974">"ਪ੍ਰਿੰਟਰ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਚੁਣੋ"</string>
-    <string name="enable_print_service" msgid="3482815747043533842">"ਯੋਗ ਬਣਾਉਣ ਲਈ ਚੁਣੋ"</string>
+    <string name="enable_print_service" msgid="3482815747043533842">"ਚਾਲੂ ਕਰਨ ਲਈ ਚੁਣੋ"</string>
     <string name="enabled_services_title" msgid="7036986099096582296">"ਯੋਗ ਬਣਾਈਆਂ ਗਈਆਂ ਸੇਵਾਵਾਂ"</string>
     <string name="recommended_services_title" msgid="3799434882937956924">"ਸਿਫ਼ਾਰਸ਼ ਕੀਤੀਆਂ ਸੇਵਾਵਾਂ"</string>
     <string name="disabled_services_title" msgid="7313253167968363211">"ਅਯੋਗ ਬਣਾਈਆਂ ਗਈਆਂ ਸੇਵਾਵਾਂ"</string>
@@ -99,13 +99,13 @@
     <item msgid="79513688117503758">"ਛੋਟਾ ਕਿਨਾਰਾ"</item>
   </string-array>
   <string-array name="orientation_labels">
-    <item msgid="4061931020926489228">"ਤਸਵੀਰ"</item>
+    <item msgid="4061931020926489228">"ਪੋਰਟਰੇਟ"</item>
     <item msgid="3199660090246166812">"ਲੈਂਡਸਕੇਪ"</item>
   </string-array>
     <string name="print_write_error_message" msgid="5787642615179572543">"ਫਾਈਲ ਵਿੱਚ ਨਹੀਂ ਲਿਖ ਸਕਿਆ"</string>
     <string name="print_error_default_message" msgid="8602678405502922346">"ਮਾਫ਼ ਕਰਨਾ, ਉਸਨੇ ਲਾਭਕਾਰੀ ਨਹੀਂ ਹੋਇਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"ਇਹ ਪ੍ਰਿੰਟਰ ਇਸ ਵੇਲੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।"</string>
-    <string name="print_cannot_load_page" msgid="6179560924492912009">"ਝਲਕ ਨਹੀਂ ਵਿਖਾਈ ਜਾ ਸਕਦੀ"</string>
-    <string name="print_preparing_preview" msgid="3939930735671364712">"ਪ੍ਰੀਵਿਊ ਦੀ ਤਿਆਰੀ ਕਰ ਰਿਹਾ ਹੈ…"</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"ਪੂਰਵ-ਝਲਕ ਨਹੀਂ ਦਿਖਾਈ ਜਾ ਸਕਦੀ"</string>
+    <string name="print_preparing_preview" msgid="3939930735671364712">"ਪੂਰਵ-ਝਲਕ ਦੀ ਤਿਆਰੀ ਕਰ ਰਿਹਾ ਹੈ…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-te/strings.xml b/packages/PrintSpooler/res/values-te/strings.xml
index e5a0879..110bd49 100644
--- a/packages/PrintSpooler/res/values-te/strings.xml
+++ b/packages/PrintSpooler/res/values-te/strings.xml
@@ -25,7 +25,7 @@
     <string name="label_paper_size_summary" msgid="5668204981332138168">"కాగితపు పరిమాణం:"</string>
     <string name="label_color" msgid="1108690305218188969">"రంగు"</string>
     <string name="label_duplex" msgid="5370037254347072243">"రెండు వైపుల"</string>
-    <string name="label_orientation" msgid="2853142581990496477">"దృగ్విన్యాసం"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"ఓరియంటేషన్"</string>
     <string name="label_pages" msgid="7768589729282182230">"పేజీలు"</string>
     <string name="destination_default_text" msgid="5422708056807065710">"ప్రింటర్ ఎంచుకోండి"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"మొత్తం <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
@@ -33,7 +33,7 @@
     <string name="pages_range_example" msgid="8558694453556945172">"ఉదా. 1—5,8,11—13"</string>
     <string name="print_preview" msgid="8010217796057763343">"ముద్రణ పరిదృశ్యం"</string>
     <string name="install_for_print_preview" msgid="6366303997385509332">"పరిదృశ్యం చేయడానికి PDF వ్యూయర్‌ను ఇన్‌స్టాల్ చేయండి"</string>
-    <string name="printing_app_crashed" msgid="854477616686566398">"ముద్రణ అనువర్తనం క్రాష్ అయ్యింది"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"ముద్రణ యాప్ క్రాష్ అయ్యింది"</string>
     <string name="generating_print_job" msgid="3119608742651698916">"ముద్రణ జాబ్‌ను ఉత్పన్నం చేస్తోంది"</string>
     <string name="save_as_pdf" msgid="5718454119847596853">"PDF వలె సేవ్ చేయి"</string>
     <string name="all_printers" msgid="5018829726861876202">"అన్ని ప్రింటర్‌లు…"</string>
@@ -47,7 +47,7 @@
     <string name="savetopdf_button" msgid="2976186791686924743">"PDF వలె సేవ్ చేయి"</string>
     <string name="print_options_expanded" msgid="6944679157471691859">"ముద్రణ ఎంపికలు విస్తరించబడ్డాయి"</string>
     <string name="print_options_collapsed" msgid="7455930445670414332">"ముద్రణ ఎంపికలు కుదించబడ్డాయి"</string>
-    <string name="search" msgid="5421724265322228497">"శోధించు"</string>
+    <string name="search" msgid="5421724265322228497">"వెతుకు"</string>
     <string name="all_printers_label" msgid="3178848870161526399">"అన్ని ప్రింటర్‌లు"</string>
     <string name="add_print_service_label" msgid="5356702546188981940">"సేవను జోడించు"</string>
     <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"శోధన పెట్టె చూపబడింది"</string>
@@ -81,7 +81,7 @@
     </plurals>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ను ముద్రిస్తోంది"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ను రద్దు చేస్తోంది"</string>
-    <string name="failed_notification_title_template" msgid="2256217208186530973">"ప్రింటర్ లోపం <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"ప్రింటర్ ఎర్రర్ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="blocked_notification_title_template" msgid="1175435827331588646">"ప్రింటర్ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ను బ్లాక్ చేసింది"</string>
     <string name="cancel" msgid="4373674107267141885">"రద్దు చేయి"</string>
     <string name="restart" msgid="2472034227037808749">"పునఃప్రారంభించు"</string>
diff --git a/packages/PrintSpooler/res/values-vi/strings.xml b/packages/PrintSpooler/res/values-vi/strings.xml
index a181424..6e8c7a8 100644
--- a/packages/PrintSpooler/res/values-vi/strings.xml
+++ b/packages/PrintSpooler/res/values-vi/strings.xml
@@ -17,7 +17,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="4469836075319831821">"Print Spooler"</string>
-    <string name="more_options_button" msgid="2243228396432556771">"Thêm tùy chọn"</string>
+    <string name="more_options_button" msgid="2243228396432556771">"Tùy chọn khác"</string>
     <string name="label_destination" msgid="9132510997381599275">"Đích"</string>
     <string name="label_copies" msgid="3634531042822968308">"Bản sao"</string>
     <string name="label_copies_summary" msgid="3861966063536529540">"Bản sao:"</string>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
index 41952df..81f7315 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
@@ -190,8 +190,11 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            if (mState != STATE_DESTROYED) {
+            if (mCloseGuard != null) {
                 mCloseGuard.warnIfOpen();
+            }
+
+            if (mState != STATE_DESTROYED) {
                 destroy(null);
             }
         } finally {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
index bf8eb84..d592c30 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
@@ -561,8 +561,11 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            if (mState != STATE_DESTROYED) {
+            if (mCloseGuard != null) {
                 mCloseGuard.warnIfOpen();
+            }
+
+            if (mState != STATE_DESTROYED) {
                 destroy(null);
             }
         } finally {
diff --git a/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml b/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml
index 7716992e..72be35b 100644
--- a/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml
+++ b/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="PrintSpoolerOutOfProcessTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.printspooler.outofprocess.tests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/packages/SettingsLib/res/drawable/ic_expand_more.xml b/packages/SettingsLib/res/drawable/ic_expand_more.xml
new file mode 100644
index 0000000..a8ff539
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_expand_more.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+
+<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="@android:color/white"
+        android:pathData="M16.59,8.59L12.0,13.17 7.41,8.59 6.0,10.0l6.0,6.0 6.0,-6.0z"/>
+
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_info_outline_24dp.xml b/packages/SettingsLib/res/drawable/ic_info_outline_24dp.xml
new file mode 100644
index 0000000..3fe1e9e
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_info_outline_24dp.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/textColorSecondary">
+    <path
+        android:fillColor="#000000"
+        android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_landscape_from_auto_rotate.xml b/packages/SettingsLib/res/drawable/ic_landscape_from_auto_rotate.xml
new file mode 100644
index 0000000..061f9fe
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_landscape_from_auto_rotate.xml
@@ -0,0 +1,66 @@
+<?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.
+-->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_rotate_to_landscape"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48"
+    android:tint="?android:attr/colorControlNormal" >
+    <group
+        android:name="device"
+        android:translateX="24"
+        android:translateY="24" >
+        <group
+            android:name="device_pivot"
+            android:translateX="-24.15"
+            android:translateY="-24.25" >
+            <group
+                android:name="landscape"
+                android:translateX="24"
+                android:translateY="24"
+                android:scaleX="0.909"
+                android:scaleY="0.909"
+                android:rotation="45" >
+                <path
+                    android:name="device_merged"
+                    android:pathData="M -21.9799957275,-10.0 c 0.0,0.0 -0.0200042724609,20.0 -0.0200042724609,20.0 c 0.0,2.19999694824 1.80000305176,4.0 4.0,4.0 c 0.0,0.0 36.0,0.0 36.0,0.0 c 2.19999694824,0.0 4.0,-1.80000305176 4.0,-4.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,-2.19999694824 -1.80000305176,-4.0 -4.0,-4.0 c 0.0,0.0 -36.0,0.0 -36.0,0.0 c -2.19999694824,0.0 -3.97999572754,1.80000305176 -3.97999572754,4.0 Z M 14.0,10.0 c 0.0,0.0 -28.0,0.0 -28.0,0.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,0.0 28.0,0.0 28.0,0.0 c 0.0,0.0 0.0,20.0 0.0,20.0 Z"
+                    android:fillColor="#FFFFFFFF" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="arrows"
+        android:translateX="24"
+        android:translateY="24" >
+        <group
+            android:name="arrows_pivot"
+            android:translateX="-24.0798"
+            android:translateY="-24.23" >
+            <group
+                android:name="arrows_0"
+                android:translateX="12.2505"
+                android:translateY="37.2145" >
+                <path
+                    android:name="bottom_merged"
+                    android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z"
+                    android:fillColor="#FFFFFFFF" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_lockscreen_ime.xml b/packages/SettingsLib/res/drawable/ic_lockscreen_ime.xml
index 4aa8569..4b81a3c 100644
--- a/packages/SettingsLib/res/drawable/ic_lockscreen_ime.xml
+++ b/packages/SettingsLib/res/drawable/ic_lockscreen_ime.xml
@@ -18,7 +18,7 @@
     android:height="24dp"
     android:viewportWidth="24.0"
     android:viewportHeight="24.0"
-    android:tint="?android:attr/colorAccent">
+    android:tint="?android:attr/colorControlNormal">
     <path
         android:fillColor="#FF000000"
         android:pathData="M20,5L4,5c-1.1,0 -1.99,0.9 -1.99,2L2,17c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9
diff --git a/packages/SettingsLib/res/drawable/ic_mode_edit.xml b/packages/SettingsLib/res/drawable/ic_mode_edit.xml
new file mode 100644
index 0000000..2ad3119
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_mode_edit.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2017 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="20.0dp"
+        android:height="20.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorControlNormal">
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M3,18.08v2.42c0,0.28 0.22,0.5 0.5,0.5h2.42c0.53,0 1.04,-0.21 1.41,-0.59L17.81,9.94l-3.75,-3.75L3.59,16.66c-0.38,0.38 -0.59,0.89 -0.59,1.42zM20.71,7.04a0.996,0.996 0,0 0,0 -1.41l-2.34,-2.34a0.996,0.996 0,0 0,-1.41 0l-1.83,1.83 3.75,3.75 1.83,-1.83z" />
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml b/packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml
new file mode 100644
index 0000000..8801f5d
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml
@@ -0,0 +1,24 @@
+<!--
+    Copyright (C) 2017 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="64dp"
+    android:height="64dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:pathData="M13,12c0,-3.57 2.2,-6.62 5.31,-7.87 0.89,-0.36 0.75,-1.69 -0.19,-1.9 -1.1,-0.24 -2.27,-0.3 -3.48,-0.14 -4.51,0.6 -8.12,4.31 -8.59,8.83C5.43,16.93 10.12,22 16,22c0.73,0 1.43,-0.08 2.12,-0.23 0.95,-0.21 1.1,-1.53 0.2,-1.9A8.471,8.471 0,0 1,13 12z"
+        android:fillColor="#FFF"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/drawable/ic_signal_location.xml b/packages/SettingsLib/res/drawable/ic_signal_location.xml
new file mode 100644
index 0000000..2f60580
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_signal_location.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <group
+        android:translateX="0.02"
+        android:translateY="0.82">
+        <path
+            android:pathData="M12,2C8.13,2 5,5.13 5,9c0,4.17 4.42,9.92 6.24,12.11 0.4,0.48 1.13,0.48 1.53,0C14.58,18.92 19,13.17 19,9c0,-3.87 -3.13,-7 -7,-7zM12,11.5a2.5,2.5 0,0 1,0 -5,2.5 2.5,0 0,1 0,5z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/list_divider_dark.xml b/packages/SettingsLib/res/drawable/list_divider_dark.xml
new file mode 100644
index 0000000..5773d9e
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/list_divider_dark.xml
@@ -0,0 +1,24 @@
+<?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.
+  -->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#64000000" />
+    <size
+        android:height="1dp"
+        android:width="1dp" />
+</shape>
diff --git a/packages/SettingsLib/res/layout/preference_category_divider.xml b/packages/SettingsLib/res/layout/preference_category_divider.xml
new file mode 100644
index 0000000..6644eec
--- /dev/null
+++ b/packages/SettingsLib/res/layout/preference_category_divider.xml
@@ -0,0 +1,29 @@
+<?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.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/two_target_divider"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:gravity="start|center_vertical"
+    android:orientation="horizontal">
+    <View
+        android:layout_height="1dp"
+        android:layout_width="match_parent"
+        android:background="?android:attr/dividerHorizontal" />
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/layout/preference_category_material_settings.xml b/packages/SettingsLib/res/layout/preference_category_material_settings.xml
new file mode 100644
index 0000000..741435e
--- /dev/null
+++ b/packages/SettingsLib/res/layout/preference_category_material_settings.xml
@@ -0,0 +1,66 @@
+<?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.
+  -->
+
+<!-- Based off frameworks/base/core/res/res/layout/preference_category_material.xml
+     except that this supports icon -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginTop="8dp"
+    android:layout_marginBottom="8dp"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart" >
+
+    <LinearLayout
+        android:id="@+id/icon_container"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="start|center_vertical"
+        android:orientation="horizontal">
+        <com.android.internal.widget.PreferenceImageView
+            android:id="@android:id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:tint="?android:attr/textColorPrimary"
+            android:maxWidth="18dp"
+            android:maxHeight="18dp"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingStart="56dp"
+        android:orientation="vertical">
+        <TextView
+            android:id="@android:id/title"
+            android:layout_marginTop="16dp"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="@android:style/TextAppearance.Material.Body2"
+            android:textColor="?android:attr/colorAccent"
+            android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"/>
+        <TextView
+            android:id="@android:id/summary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+            android:textColor="?android:attr/textColorSecondary"
+            android:ellipsize="end"
+            android:singleLine="true" />
+    </LinearLayout>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/layout/preference_category_material_settings_with_divider.xml b/packages/SettingsLib/res/layout/preference_category_material_settings_with_divider.xml
new file mode 100644
index 0000000..70d0898
--- /dev/null
+++ b/packages/SettingsLib/res/layout/preference_category_material_settings_with_divider.xml
@@ -0,0 +1,28 @@
+<?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.
+  -->
+
+<!-- Similar to preference_category_material_settings.xml, except that this always adds
+     a divider above category. -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <include layout="@layout/preference_category_divider"/>
+    <include layout="@layout/preference_category_material_settings"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/layout/preference_footer.xml b/packages/SettingsLib/res/layout/preference_footer.xml
new file mode 100644
index 0000000..d83e249
--- /dev/null
+++ b/packages/SettingsLib/res/layout/preference_footer.xml
@@ -0,0 +1,54 @@
+<?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.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:background="?android:attr/selectableItemBackground"
+    android:clipToPadding="false">
+
+    <LinearLayout
+        android:id="@+id/icon_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:minWidth="56dp"
+        android:gravity="start|top"
+        android:orientation="horizontal"
+        android:paddingEnd="12dp"
+        android:paddingTop="16dp"
+        android:paddingBottom="4dp">
+        <ImageView
+            android:id="@android:id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+    </LinearLayout>
+
+    <com.android.settingslib.widget.LinkTextView
+        android:id="@android:id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingBottom="16dp"
+        android:paddingTop="16dp"
+        android:maxLines="10"
+        android:textColor="?android:attr/textColorSecondary"
+        android:ellipsize="marquee" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/layout/preference_two_target.xml b/packages/SettingsLib/res/layout/preference_two_target.xml
index 9fb956e..2309ec6 100644
--- a/packages/SettingsLib/res/layout/preference_two_target.xml
+++ b/packages/SettingsLib/res/layout/preference_two_target.xml
@@ -18,9 +18,10 @@
 <!-- Based off preference_material_settings.xml except that ripple on only on the left side. -->
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
     android:gravity="center_vertical"
     android:background="@android:color/transparent"
     android:clipToPadding="false">
@@ -31,23 +32,27 @@
         android:layout_weight="1"
         android:background="?android:attr/selectableItemBackground"
         android:gravity="start|center_vertical"
-        android:paddingStart="?android:attr/listPreferredItemPaddingStart">
+        android:clipToPadding="false"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
 
         <LinearLayout
-            android:id="@+id/icon_container"
+            android:id="@+id/icon_frame"
+            style="@style/preference_icon_frame"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:minWidth="56dp"
+            android:gravity="start|center_vertical"
             android:orientation="horizontal"
+            android:clipToPadding="false"
             android:paddingEnd="12dp"
             android:paddingTop="4dp"
             android:paddingBottom="4dp">
-            <com.android.internal.widget.PreferenceImageView
+            <android.support.v7.internal.widget.PreferenceImageView
                 android:id="@android:id/icon"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:maxWidth="48dp"
-                android:maxHeight="48dp" />
+                settings:maxWidth="48dp"
+                settings:maxHeight="48dp" />
         </LinearLayout>
 
         <RelativeLayout
diff --git a/packages/SettingsLib/res/layout/preference_two_target_divider.xml b/packages/SettingsLib/res/layout/preference_two_target_divider.xml
index ced6142..60efed4 100644
--- a/packages/SettingsLib/res/layout/preference_two_target_divider.xml
+++ b/packages/SettingsLib/res/layout/preference_two_target_divider.xml
@@ -27,5 +27,5 @@
     <View
         android:layout_width="1dp"
         android:layout_height="match_parent"
-        android:background="?android:attr/dividerVertical" />
+        android:background="@drawable/list_divider_dark" />
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/layout/usage_bottom_label.xml b/packages/SettingsLib/res/layout/usage_bottom_label.xml
deleted file mode 100644
index 6c16880..0000000
--- a/packages/SettingsLib/res/layout/usage_bottom_label.xml
+++ /dev/null
@@ -1,20 +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.
--->
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:textAppearance="?android:attr/textAppearanceSmall" />
diff --git a/packages/SettingsLib/res/layout/usage_side_label.xml b/packages/SettingsLib/res/layout/usage_side_label.xml
deleted file mode 100644
index 6c16880..0000000
--- a/packages/SettingsLib/res/layout/usage_side_label.xml
+++ /dev/null
@@ -1,20 +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.
--->
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:textAppearance="?android:attr/textAppearanceSmall" />
diff --git a/packages/SettingsLib/res/layout/usage_view.xml b/packages/SettingsLib/res/layout/usage_view.xml
deleted file mode 100644
index da66814..0000000
--- a/packages/SettingsLib/res/layout/usage_view.xml
+++ /dev/null
@@ -1,99 +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.
--->
-<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:id="@+id/graph_label_group"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:orientation="horizontal"
-        android:clipChildren="false"
-        android:clipToPadding="false">
-
-        <LinearLayout
-            android:id="@+id/label_group"
-            android:layout_width="@dimen/usage_graph_labels_width"
-            android:layout_height="match_parent"
-            android:orientation="vertical">
-
-            <include android:id="@+id/label_top"
-                layout="@layout/usage_side_label" />
-
-            <Space
-                android:id="@+id/space1"
-                android:layout_width="wrap_content"
-                android:layout_height="0dp"
-                android:layout_weight="1" />
-
-            <include android:id="@+id/label_middle"
-                layout="@layout/usage_side_label" />
-
-            <Space
-                android:id="@+id/space2"
-                android:layout_width="wrap_content"
-                android:layout_height="0dp"
-                android:layout_weight="1" />
-
-            <include android:id="@+id/label_bottom"
-                layout="@layout/usage_side_label" />
-
-        </LinearLayout>
-
-        <com.android.settingslib.graph.UsageGraph
-            android:id="@+id/usage_graph"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            android:layout_marginTop="@dimen/usage_graph_margin_top_bottom"
-            android:layout_marginBottom="@dimen/usage_graph_margin_top_bottom" />
-
-    </LinearLayout>
-
-    <LinearLayout
-        android:id="@+id/bottom_label_group"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal">
-        <Space
-            android:id="@+id/bottom_label_space"
-            android:layout_width="@dimen/usage_graph_labels_width"
-            android:layout_height="wrap_content"/>
-        <com.android.settingslib.graph.BottomLabelLayout
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:orientation="horizontal"
-            android:layoutDirection="ltr">
-            <include android:id="@+id/label_start"
-                     layout="@layout/usage_side_label" />
-
-            <Space
-                android:id="@+id/spacer"
-                android:layout_width="40dp"
-                android:layout_height="wrap_content"
-                android:layout_weight="1" />
-
-            <include android:id="@+id/label_end"
-                     layout="@layout/usage_side_label" />
-        </com.android.settingslib.graph.BottomLabelLayout>
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml
index bc27c30..f5b49784 100644
--- a/packages/SettingsLib/res/values-af/arrays.xml
+++ b/packages/SettingsLib/res/values-af/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (verstek)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Gebruik stelselkeuse (verstek)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX-HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Aktiveer opsionele kodekke"</item>
-    <item msgid="3304843301758635896">"Deaktiveer opsionele kodekke"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Gebruik stelselkeuse (verstek)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX-HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Aktiveer opsionele kodekke"</item>
-    <item msgid="741805482892725657">"Deaktiveer opsionele kodekke"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Gebruik stelselkeuse (verstek)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 8071041..5d04cf6 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Nie gekoppel nie weens laegehalte-netwerk"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi-verbinding het misluk"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Stawingsprobleem"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Kan nie koppel nie"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Kan nie aan \"<xliff:g id="AP_NAME">%1$s</xliff:g>\" koppel nie"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Gaan wagwoord na en probeer weer"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Nie binne ontvangs nie"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Sal nie outomaties koppel nie"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Geen internettoegang nie"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Gekoppel via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Beskikbaar via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Gekoppel, geen internet nie"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Baie stadig"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Stadig"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Middelmatig"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Vinnig"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Baie vinnig"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Ontkoppel"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Ontkoppel tans…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Verbind tans…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Gekoppel (geen media nie)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Gekoppel (geen boodskaptoegang nie)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Gekoppel (geen foon of media nie)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Gekoppel, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Gekoppel (geen foon nie), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Gekoppel (geen media nie), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Gekoppel (geen foon en media nie), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media-oudio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Foonoudio"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Foonoproepe"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Lêeroordrag"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Invoertoestel"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internettoegang"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontakdeling"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Gebruik vir kontakdeling"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Deling van internetverbinding"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Boodskaptoegang"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Teksboodskappe"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-toegang"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Gebruik hoëgehalte-oudio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Gebruik hoëgehalte-oudio"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-oudio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD oudio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Gekoppel aan media-oudio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Gekoppel aan foonoudio"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Gekoppel aan lêeroordragbediener"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressiewe Wi‑Fi-na-mobiel-oorhandiging"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Laat altyd Wi-Fi-swerfskanderings toe"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiele data is altyd aktief"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardewareversnelling vir verbinding"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Deaktiveer absolute volume"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Aktiveer inband-luitoon"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-weergawe"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Laat skynliggings toe"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Aktiveer aansigkenmerkinspeksie"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Hou mobiele data altyd aktief, selfs wanneer Wi‑Fi aktief is (vir vinnige netwerkwisseling)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Gebruik hardewareversnelling vir verbinding indien beskikbaar"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Laat USB-ontfouting toe?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-ontfouting is net vir ontwikkelingsdoeleindes bedoel. Gebruik dit om data te kopieer tussen jou rekenaar en jou toestel, programme op jou toestel te installeer sonder kennisgewing en om loglêerdata te lees."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Herroep toegang tot USB-ontfouting vanaf alle rekenaars wat jy voorheen gemagtig het?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Kleurregstelling"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Hierdie kenmerk is eksperimenteel en kan werkverrigting beïnvloed."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Geneutraliseer deur <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Omtrent <xliff:g id="TIME">%1$s</xliff:g> oor"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> oor tot vol gelaai"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> oor"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – omtrent <xliff:g id="TIME">%2$s</xliff:g> oor"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> oor"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Omtrent <xliff:g id="TIME">^1</xliff:g> oor"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Ongeveer <xliff:g id="TIME">^1</xliff:g> oor gegrond op jou gebruik"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> oor tot vol gelaai"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> oor"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> oor gegrond op jou gebruik"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – omtrent <xliff:g id="TIME">^2</xliff:g> oor"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – ongeveer <xliff:g id="TIME">^2</xliff:g> oor gegrond op jou gebruik"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> oor"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol gelaai"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> tot vol gelaai"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Onbekend"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Laai"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"laai tans"</string>
diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml
index 79dad14..e531f28 100644
--- a/packages/SettingsLib/res/values-am/arrays.xml
+++ b/packages/SettingsLib/res/values-am/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (ነባሪ)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"የስርዓቱን ምርጫ (ነባሪ) ተጠቀም"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"አማራጭ ኮዴኮችን አንቃ"</item>
-    <item msgid="3304843301758635896">"አማራጭ ኮዴኮችን አሰናክል"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"የስርዓቱን ምርጫ (ነባሪ) ተጠቀም"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"አማራጭ ኮዴኮችን አንቃ"</item>
-    <item msgid="741805482892725657">"አማራጭ ኮዴኮችን አሰናክል"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"የስርዓቱን ምርጫ (ነባሪ) ተጠቀም"</item>
     <item msgid="8895532488906185219">"44.1 ኪኸ"</item>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index f5fc77f..b42d26a 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"በዝቅተኛ አውታረ መረብ ምክንያት አልተገናኘም"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"የWiFi ግንኙነት መሰናከል"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"የማረጋገጫ ችግር"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"መገናኘት አልተቻለም"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"ወደ «<xliff:g id="AP_NAME">%1$s</xliff:g>» ማገናኘት አይቻልም"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"የይለፍ ቃልን ይፈትሹ እና እንደገና ይሞክሩ"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"በክልል ውስጥ የለም"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"በራስ-ሰር አይገናኝም"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"ምንም የበይነመረብ መዳረሻ ያለም"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"በ%1$s በኩል መገናኘት"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"በ%1$s በኩል የሚገኝ"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"ተገናኝቷል፣ ምንም በይነመረብ የለም"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"በጣም ቀርፋፋ"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"አዘግይ"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"እሺ"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"መካከለኛ"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"ፈጣን"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"እጅግ በጣም ፈጣን"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"ተለያይቷል"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"በመለያየት ላይ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"በማገናኘት ላይ…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"ተያይዟል (ምንም ማህደረ መረጃ የለም)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ተገናኝቷል (ምንም የመልዕክት መዳረሻ የለም)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ተያይዟል (ምንም ስልክ ወይም ማህደረ መረጃ የለም)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"ተገናኝቷል፣ ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"ተገናኝቷል (ምንም ስልክ የለም)፣ ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"ተገናኝቷል (ምንም ማህደረ መረጃ የለም)፣ ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"ተገናኝቷል (ምንም ስልክ ወይም ማህደረ መረጃ የለም)፣ ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"የማህደረ መረጃ ኦዲዮ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"የስልክ ኦዲዮ"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"የስልክ ጥሪዎች"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ፋይል ማስተላለፍ"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ግቤት መሣሪያ"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"የበይነመረብ ድረስ"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"እውቂያ ማጋራት"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"እውቂያን ለማጋራት ተጠቀም"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"የበይነ መረብ ተያያዥ ማጋሪያ"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"የመልዕክት መዳረሻ"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"የጽሑፍ መልዕክቶች"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"የሲም መዳረሻ"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ከፍተኛ ጥራት ያለውን ኦዲዮ ተጠቀም፦ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ከፍተኛ ጥራት ያለውን ኦዲዮ ተጠቀም"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"ኤችዲ ኦዲዮ፦ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"ኤችዲ ኦዲዮ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"ወደ ማህደረ  መረጃ  አውዲዮ ተያይዟል"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ወደ ስልክ አውዲዮ ተያይዟል"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ወደ ፋይል ዝውውር አገልጋይ ተያይዟል"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"አስገዳጅ ከWi‑Fi ወደ ሞባይል ማቀበል"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ሁልጊዜ የWi‑Fi ማንቀሳቀስ ቅኝቶችን ይፍቀዱ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"የተንቀሳቃሽ ስልክ ውሂብ ሁልጊዜ ገቢር ነው"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"የሃርድዌር ማቀላጠፊያን በማስተሳሰር ላይ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ፍጹማዊ ድምፅን አሰናክል"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"የውስጠ-ሞገድ ማስጮህን አንቃ"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"የብሉቱዝ AVRCP ስሪት"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"አስቂኝ ሥፍራዎችን ፍቀድ"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"የእይታ አይነታ ምርመራን አንቃ"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ምንም እንኳን Wi‑Fi ንቁ ቢሆንም የሞባይል ውሂብን ንቁ እንደሆነ አቆይ (ለፈጣን የአውታረ መረብ ቅይይር)።"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"የሃርድዌር ማቀላጠፊያን ማስተሳሰርን የሚገኝ ከሆነ ይጠቀሙ"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"የUSB ማረሚያ ይፈቀድ?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"የUSB አድስ ለግንባታ አላማ ብቻ የታሰበ ነው። ከኮምፒዩተርህ ወደ መሳሪያህ ውሂብ ለመገልበጥ፣ መሣሪያህ ላይ ያለ ማሳወቂያ መተግበሪያዎችን መጫን፣ እና ማስታወሻ ውሂብ ማንበብ ለመጠቀም ይቻላል።"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"የዩ ኤስ ቢ ማረም መዳረሻ ከዚህ ቀደም ፍቃድ ከሰጧቸው ኮምፒውተሮች ላይ ይሻሩ?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"የቀለም ማስተካከያ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ይህ ባህሪ የሙከራ ነውና አፈጻጸም ላይ ተጽዕኖ ሊኖረው ይችላል።"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"በ<xliff:g id="TITLE">%1$s</xliff:g> ተሽሯል"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"<xliff:g id="TIME">%1$s</xliff:g> አካባቢ ቀርቷል"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ሙሉ ኃይል እስኪሞላ ድረስ <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ቀርቷል"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> አካባቢ ይቀራል"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ይቀራል"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"<xliff:g id="TIME">^1</xliff:g> አካባቢ ቀርቷል"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"በእርስዎ አጠቃቀም ላይ በመመስረት <xliff:g id="TIME">^1</xliff:g> ገደማ ቀርቷል"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ሙሉ ኃይል እስኪሞላ ድረስ <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> ቀርቷል"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"በእርስዎ አጠቃቀም ላይ በመመስረት <xliff:g id="TIME">^1</xliff:g> ቀርቷል"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> አካባቢ ይቀራል"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - በእርስዎ አጠቃቀም ላይ በመመስረት <xliff:g id="TIME">^2</xliff:g> ገደማ ቀርቷል"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ሙሉ ለሙሉ እስኪሞላ ድረስ <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - ሙሉ ለሙሉ እስኪሞላ ድረስ <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"ያልታወቀ"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"ኃይል በመሙላት ላይ"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ኃይል በመሙላት ላይ"</string>
diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml
index ea31dbe..cc8293c 100644
--- a/packages/SettingsLib/res/values-ar/arrays.xml
+++ b/packages/SettingsLib/res/values-ar/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"‏AVRCP 1.4 (الافتراضي)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"استخدام اختيار النظام (افتراضي)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"تمكين برامج الترميز الاختيارية"</item>
-    <item msgid="3304843301758635896">"تعطيل برامج الترميز الاختيارية"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"استخدام اختيار النظام (افتراضي)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"تمكين برامج الترميز الاختيارية"</item>
-    <item msgid="741805482892725657">"تعطيل برامج الترميز الاختيارية"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"استخدام اختيار النظام (افتراضي)"</item>
     <item msgid="8895532488906185219">"44.1 كيلو هرتز"</item>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 9b8128c..08f4a630 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"الجهاز غير متصل بسبب انخفاض جودة الشبكة"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"‏تعذّر اتصال WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"حدثت مشكلة في المصادقة"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"تعذَّر الاتصال"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"تعذَّر الاتصال بـ \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"يُرجى التحقق من كلمة المرور وإعادة المحاولة"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"ليست في النطاق"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"لن يتم الاتصال تلقائيًا"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"لا يتوفر اتصال بالإنترنت"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"‏تم الاتصال عبر %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"‏متوفرة عبر %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"متصلة، ولا يتوفر إنترنت"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"بطيئة جدًا"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"بطيئة"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"موافق"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"متوسطة"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"سريعة"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"سريعة جدًا"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"غير متصل"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"جارٍ قطع الاتصال..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"جارٍ الاتصال…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"متصل (بجهاز غير الوسائط)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"تم الاتصال (يتعذر الدخول إلى الرسائل)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"متصل (بجهاز غير الهاتف أو الوسائط)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"الجهاز متّصل، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"الجهاز متّصل (من دون هاتف)، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"الجهاز متّصل (من دون وسائط)، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"الجهاز متّصل (من دون هاتف أو وسائط)، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"الإعدادات الصوتية للوسائط"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"الإعدادات الصوتية للهاتف"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"المكالمات الهاتفية"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"نقل الملف"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"جهاز الإرسال"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"الدخول إلى الإنترنت"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"مشاركة جهة الاتصال"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"استخدام مع مشاركة جهة الاتصال"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"مشاركة اتصال الإنترنت"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"الدخول إلى الرسائل"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"الرسائل النصية"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"‏الوصول إلى شريحة SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"استخدام صوت عالي الجودة: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"استخدام صوت عالي الجودة"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"صوت عالي الدقة: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"صوت عالي الدقة"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"متصل بالإعدادات الصوتية للوسائط"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"متصل بالإعدادات الصوتية للهاتف"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"متصل بخادم نقل الملف"</string>
@@ -97,13 +110,13 @@
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"ربط"</string>
     <string name="tether_settings_title_all" msgid="8356136101061143841">"الربط ونقطة الاتصال المحمولة"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"كل تطبيقات العمل"</string>
-    <string name="user_guest" msgid="8475274842845401871">"مدعو"</string>
+    <string name="user_guest" msgid="8475274842845401871">"ضيف"</string>
     <string name="unknown" msgid="1592123443519355854">"غير معروف"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"المستخدم: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="313159469856372621">"تم تعيين بعض الإعدادات الافتراضية"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"لم يتم تعيين إعدادات تلقائية"</string>
     <string name="tts_settings" msgid="8186971894801348327">"إعدادات تحويل النص إلى كلام"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"إخراج تحويل النص إلى كلام"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"تحويل النص إلى كلام"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"معدل سرعة الكلام"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"سرعة نطق الكلام"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"درجة الصوت"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"‏تسليم Wi-Fi حاد إلى جوّال"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏السماح دائمًا بعمليات فحص Wi-Fi للتجوال"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"بيانات الجوّال نشطة دائمًا"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"تسريع الأجهزة للتوصيل"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"تعطيل مستوى الصوت المطلق"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"تمكين الرنين ضمن النطاق الأساسي"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"‏إصدار Bluetooth AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"السماح بمواقع وهمية"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"تمكين فحص سمة العرض"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"‏اجعل بيانات الجوّال نشطة دائمًا، حتى عندما يكون اتصال Wi‑Fi نشطًا (لتبديل الشبكة بسرعة)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"استخدام إعداد تسريع الأجهزة للتوصيل إن كان متاحًا"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"‏هل تريد السماح بتصحيح أخطاء USB؟"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"‏تم تصميم تصحيح أخطاء USB لأغراض التطوير فقط. يمكن استخدامه لنسخ البيانات بين الكمبيوتر والجهاز، وتثبيت التطبيقات على جهازك بدون تنبيه، وقراءة بيانات السجل."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"‏هل تريد إلغاء إمكانية الدخول إلى تصحيح أخطاء USB من جميع أجهزة الكمبيوتر التي تم التصريح لها سابقًا؟"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"تصحيح الألوان"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"هذه الميزة تجريبية وقد تؤثر في الأداء."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"تم الاستبدال بـ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"يتبقى حوالي <xliff:g id="TIME">%1$s</xliff:g> لإتمام شحن البطارية"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"يتبقى <xliff:g id="TIME">%1$s</xliff:g> لشحن البطارية بالكامل"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"يتبقى <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - يتبقى <xliff:g id="TIME">%2$s</xliff:g> تقريبًا"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - يتبقى <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"يتبقى حوالي <xliff:g id="TIME">^1</xliff:g> لإتمام شحن البطارية"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"يتبقى <xliff:g id="TIME">^1</xliff:g> تقريبًا بناءً على استخدامك"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"يتبقى <xliff:g id="TIME">^1</xliff:g> لشحن البطارية بالكامل"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"يتبقى <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"يتبقى <xliff:g id="TIME">^1</xliff:g> بناءً على استخدامك"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - يتبقى <xliff:g id="TIME">^2</xliff:g> تقريبًا"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - يتبقى <xliff:g id="TIME">^2</xliff:g> تقريبًا بناءً على استخدامك"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - يتبقى <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى يكتمل الشحن"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> حتى يكتمل الشحن"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"غير معروف"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"جارٍ الشحن"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"جارٍ الشحن"</string>
@@ -350,7 +368,7 @@
     <string name="charge_length_format" msgid="8978516217024434156">"قبل <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"يتبقى <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="screen_zoom_summary_small" msgid="5867245310241621570">"صغير"</string>
-    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"افتراضي"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"تلقائي"</string>
     <string name="screen_zoom_summary_large" msgid="4835294730065424084">"كبير"</string>
     <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"أكبر"</string>
     <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"أكبر مستوى"</string>
diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml
index b25b382..f329e00 100644
--- a/packages/SettingsLib/res/values-az/arrays.xml
+++ b/packages/SettingsLib/res/values-az/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Defolt)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Sistem Seçimini istifadə edin (Defolt)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Şəxsi Kodekləri Aktiv edin"</item>
-    <item msgid="3304843301758635896">"Şəxsi Kodekləri Deaktiv edin"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Sistem Seçimini istifadə edin (Defolt)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Şəxsi Kodekləri Aktiv edin"</item>
-    <item msgid="741805482892725657">"Şəxsi Kodekləri Deaktiv edin"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Sistem Seçimini istifadə edin (Defolt)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 519b246..494ae00 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Şəbəkə keyfiyyəti aşağı olduğuna görə qoşulmadı"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi Bağlantı Uğursuzluğu"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Autentifikasiya problemi"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Qoşulmaq mümkün deyil"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\"<xliff:g id="AP_NAME">%1$s</xliff:g>\" şəbəkəsinə qoşulmaq mümkün deyil"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Parolu yoxlayın və yenidən cəhd edin"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Diapazonda deyil"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Avtomatik qoşulmayacaq"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"İnternet girişi yoxdur"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s vasitəsilə qoşuludur"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s vasitəsilə əlçatandır"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Qoşuludur, internet yoxdur"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Çox Yavaş"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Yavaş"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Orta"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Sürətli"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Çox Sürətli"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Ayrıldı"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Ayrılır..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Qoşulur..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Qoşuludur (media yoxdur)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Qoşulu (mesaj girişi yoxdur)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Bağlantı yaradılıb (telefon və ya media deyil)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Qoşuldu, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Qoşuldu (telefondan başqa), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Qoşuldu (mediadan başqa), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Qoşuldu (telefon və ya mediadan başqa), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefon audio"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefon zəngləri"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fayl transferi"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Daxiletmə cihazı"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"İnternet girişi"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontakt paylaşımı"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Kontakt paylaşımı üçün istifadə edin"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"internet bağlantı paylaşımı"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Mesaj Girişi"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Mətn Mesajları"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Girişi"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Yüksək keyfiyyətli audio istifadə edin: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Yüksək keyfiyyətli audio istifadə edin"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Media audioya birləşdirilib"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Telefon audiosuna qoşulu"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Fayl transfer serverinə qoşulu"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Möbül ötürücüyə aqressiv Wi‑Fi"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi axtarışlarına həmişə icazə verin"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil data həmişə aktiv"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Birləşmə üçün avadanlıq akselerasiyası"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Mütləq səs həcmi deaktiv edin"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Diapazon daxili zəngi aktiv edin"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Versiya"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Sınaq yerləşmələrə icazə verin"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Atribut inspeksiyasına baxışa icazə verin"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Hətta Wi‑Fi aktiv olanda da mobil datanı həmişə aktiv saxlayın (sürətli şəbəkək keçidi üçün)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Əlçatan oldarsa, birləşmə üçün avadanlıq akselerasiyasından istifadə edin"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB debaq funksiyasına icazə verilsin?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB sazlanması yalnız inkişaf məqsədlidir. Kompüteriniz və cihazınız arasında datanı kopyalamaq üçün ondan istifadə edin, bildiriş olmadan tətbiqləri cihazınıza quraşdırın və qeydiyyat datasını oxuyun."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Əvvəl icazə verdiyiniz kompüterlərdən USB debaq əməliyyatına giriş ləğv olunsun?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Rəng düzəlişi"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya eksperimentaldır və performansa təsir edə bilər."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tərəfindən qəbul edilmir"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Təxminən <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tam enerji yığmağına <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Təxminən <xliff:g id="TIME">^1</xliff:g> qalıb"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"İstifadəyə əsasən təxminən <xliff:g id="TIME">^1</xliff:g> qalıb"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tam enerji yığmağına <xliff:g id="TIME">^1</xliff:g> qalıb"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> qalıb"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"İstifadəyə əsasən <xliff:g id="TIME">^1</xliff:g> qalıb"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - təxminən <xliff:g id="TIME">^2</xliff:g> qalıb"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - istifadəyə əsasən təxminən <xliff:g id="TIME">^2</xliff:g> qalıb"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> qalıb"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tam enerji yığana kimi"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> tam enerji yığana kimi"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Naməlum"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Enerji doldurma"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"enerji yığır"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
index 7d09876..cc88aa9 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
@@ -58,27 +58,35 @@
     <item msgid="3878793616631049349">"Koristi HDCP proveru samo za DRM sadržaj"</item>
     <item msgid="45075631231212732">"Uvek koristi HDCP proveru"</item>
   </string-array>
-    <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
-    <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
-    <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+  <string-array name="bluetooth_avrcp_versions">
+    <item msgid="5347678900838034763">"AVRCP 1.4 (podrazumevano)"</item>
+    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+  </string-array>
+  <string-array name="bluetooth_avrcp_version_values">
+    <item msgid="2838624067805073303">"avrcp14"</item>
+    <item msgid="1913619118958233129">"avrcp15"</item>
+    <item msgid="7142710449249088270">"avrcp16"</item>
+  </string-array>
   <string-array name="bluetooth_a2dp_codec_titles">
     <item msgid="7065842274271279580">"Koristi izbor sistema (podrazumevano)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
+    <item msgid="723675059572222462">"Omogući opcionalne kodeke"</item>
+    <item msgid="3304843301758635896">"Onemogući opcionalne kodeke"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_summaries">
     <item msgid="5062108632402595000">"Koristi izbor sistema (podrazumevano)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
+    <item msgid="2209680154067241740">"Omogući opcionalne kodeke"</item>
+    <item msgid="741805482892725657">"Onemogući opcionalne kodeke"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Koristi izbor sistema (podrazumevano)"</item>
@@ -120,11 +128,13 @@
     <item msgid="7158319962230727476">"Optimizovano za kvalitet zvuka (990 kb/s/909 kb/s)"</item>
     <item msgid="2921767058740704969">"Ujednačen kvalitet zvuka i veze (660 kb/s/606 kb/s)"</item>
     <item msgid="8860982705384396512">"Optimizovano za kvalitet veze (330 kb/s/303 kb/s)"</item>
+    <item msgid="4414060457677684127">"Najbolje moguće (prilagodljiva brzina prenosa)"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
     <item msgid="6398189564246596868">"Optimizovano za kvalitet zvuka"</item>
     <item msgid="4327143584633311908">"Ujednačen kvalitet zvuka i veze"</item>
     <item msgid="4681409244565426925">"Optimizovano za kvalitet veze"</item>
+    <item msgid="364670732877872677">"Najbolje moguće (prilagodljiva brzina prenosa)"</item>
   </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Isključeno"</item>
@@ -188,7 +198,7 @@
     <item msgid="1069584980746680398">"Razmera animacije 10x"</item>
   </string-array>
   <string-array name="overlay_display_devices_entries">
-    <item msgid="1606809880904982133">"Nijedno"</item>
+    <item msgid="1606809880904982133">"Ništa"</item>
     <item msgid="9033194758688161545">"480 piksela"</item>
     <item msgid="1025306206556583600">"480 piksela (bezbedno)"</item>
     <item msgid="1853913333042744661">"720 piksela"</item>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 24b2a13..e8fade2 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -32,13 +32,23 @@
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Automatsko povezivanje nije uspelo"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Nema pristupa internetu"</string>
     <string name="saved_network" msgid="4352716707126620811">"Sačuvao/la je <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
-    <skip />
-    <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
-    <skip />
+    <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatski povezano preko %1$s"</string>
+    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatski povezano preko dobavljača ocene mreže"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Veza je uspostavljena preko pristupne tačke %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupna je preko pristupne tačke %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Veza je uspostavljena, nema interneta"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Veza je prekinuta"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Prekidanje veze..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Povezivanje…"</string>
@@ -49,15 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Povezano je (nema pristupa porukama)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Povezano (bez telefona ili medija)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk medija"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Zvuk telefona"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prenos datoteke"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Ulazni uređaj"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Pristup Internetu"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Deljenje kontakata"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Koristite za deljenje kontakata"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Deljenje internet veze"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Pristup porukama"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Pristup SIM kartici"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Povezano sa zvukom medija"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Povezano sa zvukom telefona"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Povezano sa serverom za prenos datoteka"</string>
@@ -127,7 +143,7 @@
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Podešavanja za <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Pokreni podešavanja mašine"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Željena mašina"</string>
-    <string name="tts_general_section_title" msgid="4402572014604490502">"Opšte"</string>
+    <string name="tts_general_section_title" msgid="4402572014604490502">"Opšta"</string>
     <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Resetujte visinu tona govora"</string>
     <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Resetujte visinu tona kojom se tekst izgovara na podrazumevanu."</string>
   <string-array name="tts_rate_entries">
@@ -141,7 +157,7 @@
     <item msgid="5194774745031751806">"Veoma ubrzano"</item>
     <item msgid="9085102246155045744">"Najbrže"</item>
   </string-array>
-    <string name="choose_profile" msgid="8229363046053568878">"Izaberite profil"</string>
+    <string name="choose_profile" msgid="6921016979430278661">"Izaberite profil"</string>
     <string name="category_personal" msgid="1299663247844969448">"Lično"</string>
     <string name="category_work" msgid="8699184680584175622">"Posao"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Opcije za programera"</string>
@@ -170,16 +186,13 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Sertifikacija bežičnog ekrana"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući detaljniju evidenciju za Wi‑Fi"</string>
-    <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
-    <skip />
+    <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresivan prelaz sa Wi‑Fi mreže na mobilnu"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvek dozvoli skeniranje Wi‑Fi-ja u romingu"</string>
-    <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
-    <skip />
+    <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci su uvek aktivni"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogući glavno podešavanje jačine zvuka"</string>
-    <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
-    <skip />
-    <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
-    <skip />
+    <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Omogućavanje zvonjave na istom kanalu"</string>
+    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verzija Bluetooth AVRCP-a"</string>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Izaberite verziju Bluetooth AVRCP-a"</string>
     <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth audio kodek"</string>
     <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Izaberite Bluetooth audio kodek"</string>
     <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Brzina uzorkovanja za Bluetooth audio"</string>
@@ -193,8 +206,7 @@
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Strimovanje: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaz opcija za sertifikaciju bežičnog ekrana"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećava nivo evidentiranja za Wi‑Fi. Prikaz po SSID RSSI-u u biraču Wi‑Fi mreže"</string>
-    <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
-    <skip />
+    <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kad se omogući, Wi‑Fi će biti agresivniji pri prebacivanju mreže za prenos podataka na mobilnu ako je Wi‑Fi signal slab"</string>
     <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Dozvoli/zabrani skeniranje Wi-Fi-ja u romingu na osnovu prisutnog protoka podataka na interfejsu"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Veličine bafera podataka u programu za evidentiranje"</string>
     <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Izaberite veličine po baferu evidencije"</string>
@@ -207,7 +219,7 @@
     <string name="allow_mock_location" msgid="2787962564578664888">"Dozvoli lažne lokacije"</string>
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Dozvoli lažne lokacije"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Omogući proveru atributa za pregled"</string>
-    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Neka podaci za mobilne uređaje uvek budu aktivni, čak i kada je Wi‑Fi aktivan (radi brze promene mreže)."</string>
+    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Neka mobilni podaci uvek budu aktivni, čak i kada je Wi‑Fi aktivan (radi brze promene mreže)."</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Dozvoli otklanjanje USB grešaka?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Otklanjanje USB grešaka namenjeno je samo za svrhe programiranja. Koristite ga za kopiranje podataka sa računara na uređaj i obrnuto, instaliranje aplikacija na uređaju bez obaveštenja i čitanje podataka iz evidencije."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Želite li da opozovete pristup otklanjanju USB grešaka sa svih računara koje ste prethodno odobrili?"</string>
@@ -216,6 +228,7 @@
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifikuj aplikacije preko USB-a"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Proverava da li su aplikacije instalirane preko ADB-a/ADT-a štetne."</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Onemogućava glavno podešavanje jačine zvuka na Bluetooth uređaju u slučaju problema sa jačinom zvuka na daljinskim uređajima, kao što su izuzetno velika jačina zvuka ili nedostatak kontrole."</string>
+    <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"Omogućite da se melodija zvona na telefonu pušta preko Bluetooth slušalica"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokalni terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Omogući aplik. terminala za pristup lokalnom komandnom okruženju"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP provera"</string>
@@ -275,6 +288,8 @@
     <string name="app_process_limit_title" msgid="4280600650253107163">"Ograničenje pozadinskih procesa"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"Prikaži sve ANR-ove"</string>
     <string name="show_all_anrs_summary" msgid="641908614413544127">"Prikaži dijalog Aplikacija ne reaguje za aplikacije u pozadini"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Prikazuj upozorenja zbog kanala za obaveštenja"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Prikazuje upozorenje na ekranu kada aplikacija postavi obaveštenje bez važećeg kanala"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"Prinudno dozvoli aplikacije u spoljnoj"</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Omogućava upisivanje svih aplikacija u spoljnu memoriju, bez obzira na vrednosti manifesta"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Prinudno omogući promenu veličine aktivnosti"</string>
@@ -302,8 +317,6 @@
     <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktivna. Dodirnite da biste je deaktivirali."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Pokrenute usluge"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Prikaz i kontrola trenutno pokrenutih usluga"</string>
-    <string name="enable_webview_multiprocess" msgid="3352660896640797330">"Višeprocesni WebView"</string>
-    <string name="enable_webview_multiprocess_desc" msgid="2485604010404197724">"Pokrećite WebView prikazivače zasebno"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Primena WebView-a"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Podesite primenu WebView-a"</string>
     <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"Ovaj izbor više nije važeći. Probajte ponovo."</string>
@@ -321,40 +334,28 @@
     <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"Protanomalija (crveno-zeleno)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Tritanomalija (plavo-žuto)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekcija boja"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna i može da utiče na performanse."</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna i može da utiče na kvalitet rada."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamenjuje ga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Još oko <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Na osnovu potrošnje imate još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> do potpunog punjenja"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Preostalo vreme: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_discharging_duration (2843747179907396142) -->
-    <skip />
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Na osnovu potrošnje imate još <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ostalo je oko <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – na osnovu potrošnje imate još otprilike <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"Preostalo je <xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$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>
-    <!-- no translation found for power_charging_duration (4676999980973411875) -->
-    <skip />
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpunog punjenja"</string>
     <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
-    <skip />
-    <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
-    <skip />
-    <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
-    <skip />
-    <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
-    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Punjenje preko punjača"</string>
-    <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Puni se"</string>
-    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Punjenje preko USB-a"</string>
-    <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Puni se"</string>
-    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bežično punjenje"</string>
-    <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Puni se"</string>
+    <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"puni se"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string>
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontroliše administrator"</string>
-    <string name="enabled_by_admin" msgid="2386503803463071894">"Omogućio je administrator"</string>
-    <string name="disabled_by_admin" msgid="3669999613095206948">"Onemogućio je 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="home" msgid="3256884684164448244">"Početna za Podešavanja"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
@@ -377,4 +378,7 @@
     <string name="retail_demo_reset_title" msgid="696589204029930100">"Potrebna je lozinka"</string>
     <string name="active_input_method_subtypes" msgid="3596398805424733238">"Metode aktivnog unosa"</string>
     <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"Koristi jezike sistema"</string>
+    <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Otvaranje podešavanja za aplikaciju <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> nije uspelo"</string>
+    <string name="ime_security_warning" msgid="4135828934735934248">"Ovaj metod unosa možda može da prikuplja sav tekst koji unosite, uključujući lične podatke, kao što su lozinke i brojevi kreditnih kartica. Potiče od aplikacije <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Želite li da koristite ovaj metod unosa?"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Napomena: Posle restartovanja ova aplikacija ne može da se pokrene dok ne otključate telefon"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-be/arrays.xml b/packages/SettingsLib/res/values-be/arrays.xml
index 6c883e3e..1467682 100644
--- a/packages/SettingsLib/res/values-be/arrays.xml
+++ b/packages/SettingsLib/res/values-be/arrays.xml
@@ -58,27 +58,35 @@
     <item msgid="3878793616631049349">"Выкарыстанне праверкі HDCP только для змесціва, абароненага DRM"</item>
     <item msgid="45075631231212732">"Заўсёды выкарыстоўваць праверку HDCP"</item>
   </string-array>
-    <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
-    <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
-    <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+  <string-array name="bluetooth_avrcp_versions">
+    <item msgid="5347678900838034763">"AVRCP 1.4 (стандартная)"</item>
+    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+  </string-array>
+  <string-array name="bluetooth_avrcp_version_values">
+    <item msgid="2838624067805073303">"avrcp14"</item>
+    <item msgid="1913619118958233129">"avrcp15"</item>
+    <item msgid="7142710449249088270">"avrcp16"</item>
+  </string-array>
   <string-array name="bluetooth_a2dp_codec_titles">
     <item msgid="7065842274271279580">"Выбар сістэмы (стандартны)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
+    <item msgid="723675059572222462">"Уключыць дадатковыя кодэкі"</item>
+    <item msgid="3304843301758635896">"Адключыць дадатковыя кодэкі"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_summaries">
     <item msgid="5062108632402595000">"Выбар сістэмы (стандартны)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
+    <item msgid="2209680154067241740">"Уключыць дадатковыя кодэкі"</item>
+    <item msgid="741805482892725657">"Адключыць дадатковыя кодэкі"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Выбар сістэмы (стандартны)"</item>
@@ -120,11 +128,13 @@
     <item msgid="7158319962230727476">"Аптымізавана якасць гуку (990 кбіт/c / 909 кбіт/c)"</item>
     <item msgid="2921767058740704969">"Збалансаваная якасць аўдыя і падключэння (660кбіт/c / 606 кбіт/c)"</item>
     <item msgid="8860982705384396512">"Аптымізавана якасць падключэння (330 кбіт/c / 303 кбіт/c)"</item>
+    <item msgid="4414060457677684127">"Best Effort (адаптыўны бітрэйт)"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
     <item msgid="6398189564246596868">"Аптымізавана якасць гуку"</item>
     <item msgid="4327143584633311908">"Збалансаваная якасць аўдыя і падключэння"</item>
     <item msgid="4681409244565426925">"Аптымізавана якасць падключэння"</item>
+    <item msgid="364670732877872677">"Best Effort (адаптыўны бітрэйт)"</item>
   </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Выкл."</item>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 36ebaa3..c69b314 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -32,13 +32,23 @@
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Не будзе аўтаматычна падключацца"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Няма доступу да інтэрнэту"</string>
     <string name="saved_network" msgid="4352716707126620811">"Хто захаваў: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
-    <skip />
-    <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
-    <skip />
+    <string name="connected_via_network_scorer" msgid="5713793306870815341">"Аўтаматычна падключана праз %1$s"</string>
+    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Аўтаматычна падключана праз пастаўшчыка паслугі ацэнкі сеткі"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Падлучана праз %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Даступна праз %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Падлучана, няма інтэрнэту"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Адключана"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Адключэнне..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Злучэнне..."</string>
@@ -49,15 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Падлучана (без доступу да паведамленняў)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Падключаны (без тэлефона або носьбіта)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Аўдыё медыяпрылады"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Аудыё тэлефона"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Перадача файлаў"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Прылада ўводу"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Доступ у інтэрнэт"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Абагуленне кантактаў"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Выкарыстоўваць для абагулення кантактаў"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Прадастаўленне доступу да Інтэрнэту"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Доступ да паведамленняў"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Доступ да SIM-карты"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Падключана да аўдыё медыа"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Падключана да аўдыё тэлефона"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Падключаны да серверу перадачы файлаў"</string>
@@ -95,7 +111,7 @@
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Партатыўная кропка доступу"</string>
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetooth-мадэм"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Мадэм"</string>
-    <string name="tether_settings_title_all" msgid="8356136101061143841">"Мадэм і партатыўны хотспот"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"Рэжым мадэма"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"Усе працоўныя праграмы"</string>
     <string name="user_guest" msgid="8475274842845401871">"Госць"</string>
     <string name="unknown" msgid="1592123443519355854">"Невядома"</string>
@@ -141,7 +157,7 @@
     <item msgid="5194774745031751806">"Вельмі шпарка"</item>
     <item msgid="9085102246155045744">"Максімальна хутка"</item>
   </string-array>
-    <string name="choose_profile" msgid="8229363046053568878">"Выбраць профіль"</string>
+    <string name="choose_profile" msgid="6921016979430278661">"Выбраць профіль"</string>
     <string name="category_personal" msgid="1299663247844969448">"Асабісты"</string>
     <string name="category_work" msgid="8699184680584175622">"Рабочы"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Параметры распрацоўшчыка"</string>
@@ -170,16 +186,13 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Сеткі"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Сертыфікацыя бесправаднога дысплея"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Уключыць падрабязны журнал Wi‑Fi"</string>
-    <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
-    <skip />
+    <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Інтэнсіўны пераход з Wi‑Fi на маб. сетку"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Заўсёды дазваляць роўмінгавае сканіраванне Wi‑Fi"</string>
-    <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
-    <skip />
+    <string name="mobile_data_always_on" msgid="8774857027458200434">"Мабільная перадача даных заўсёды актыўная"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Адключыць абсалютны гук"</string>
-    <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
-    <skip />
-    <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
-    <skip />
+    <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Уключыць унутрыпалосны празвон"</string>
+    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версія Bluetooth AVRCP"</string>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Выбраць версію Bluetooth AVRCP"</string>
     <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Кодэк Bluetooth Audio"</string>
     <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Выбраць аўдыякодэк Bluetooth"</string>
     <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Частата дыскрэтызацыі Bluetooth Audio"</string>
@@ -193,8 +206,7 @@
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Перадача плынню: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Паказаць опцыі сертыфікацыі бесправаднога дысплея"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Падвыс. узровень дэтал-цыі журнала Wi‑Fi у залежн. ад SSID RSSI у Wi‑Fi Picker"</string>
-    <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
-    <skip />
+    <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Калі гэта функцыя ўключана, Wi-Fi будзе больш інтэнсіўна імкнуцца перайсці на падключ. маб. перад. даных пры слабым сігнале Wi‑Fi"</string>
     <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Дазволіць/забараніць роўмінгавае сканіраванне Wi‑Fi ў залежнасці ад аб\'ёму трафіку даных у інтэрфейсе"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Памеры буфера для сродку вядзення журнала"</string>
     <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Выберыце памеры сродку вядзення журнала для буфераў журнала"</string>
@@ -216,6 +228,7 @@
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Праверце прыкладаннi па USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Праверце прыкладаннi, усталяваныя з дапамогай ADB/ADT, на нестабiльныя паводзiны."</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Адключыць функцыю абсалютнага гуку Bluetooth у выпадку праблем з гукам на аддаленых прыладах, напр., пры непрымальна высокай гучнасці або адсутнасці кіравання."</string>
+    <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"Дазволіць прайграванне рынгтонаў на тэлефоне праз гарнітуры Bluetooth"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Лакальны тэрмінал"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Уключэнне прыкладання тэрмінала, якое прапануе доступ да лакальнай абалонкі"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Праверка HDCP"</string>
@@ -275,6 +288,8 @@
     <string name="app_process_limit_title" msgid="4280600650253107163">"Ліміт фонавага працэсу"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"Паказаць усе ANRS"</string>
     <string name="show_all_anrs_summary" msgid="641908614413544127">"Паказаць дыялогавае акно \"Праграма не адказвае\" для фонавых прыкладанняў"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Паказваць папярэджанні канала апавяшчэннаў"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Паказвае папярэджанне на экране, калі праграма публікуе апавяшчэнне без сапраўднага канала"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"Прымусова дазволіць праграмы на вонкавым сховішчы"</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Робіць любую праграму даступнай для запісу на вонкавае сховішча, незалежна ад значэнняў маніфеста"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Зрабіць вокны дзеянняў даступнымі для змены памеру"</string>
@@ -302,8 +317,6 @@
     <string name="inactive_app_active_summary" msgid="4174921824958516106">"Актыўная. Краніце, каб пераключыць."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Запушчаныя службы"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Прагляд запушчаных службаў i кіраванне iмi"</string>
-    <string name="enable_webview_multiprocess" msgid="3352660896640797330">"Шматпрацэсны WebView"</string>
-    <string name="enable_webview_multiprocess_desc" msgid="2485604010404197724">"Запусціць апрацоўшчыкі WebView асобна"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Рэалізацыя WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Наладзіць рэалізацыю WebView"</string>
     <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"Гэты варыянт больш не даступны. Паспрабуйце яшчэ раз."</string>
@@ -311,7 +324,7 @@
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Пераход..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Шыфраванне файлаў ужо дзейнічае"</string>
     <string name="title_convert_fbe" msgid="1263622876196444453">"Пераход на шыфраванне файлаў"</string>
-    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Перайдзіце з шыфравання раздзелаў даных на шыфраванне файлаў.\n !!Увага!! Гэта прывядзе да выдалення ўсіх даных.\n Гэта функцыя ў альфа-версіі, яна можа працаваць няправільна.\n Каб працягнуць, націсніце «Сцерці і перайсці...»."</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Перайдзіце з шыфравання раздзелаў даных на шыфраванне файлаў.\n !!Увага!! Гэта прывядзе да выдалення ўсіх даных.\n Гэта функцыя ў альфа-версіі, яна можа працаваць няправільна.\n Каб працягнуць, націсніце \"Сцерці і перайсці...\"."</string>
     <string name="button_convert_fbe" msgid="5152671181309826405">"Сцерці і перайсці..."</string>
     <string name="picture_color_mode" msgid="4560755008730283695">"Каляровы рэжым выявы"</string>
     <string name="picture_color_mode_desc" msgid="1141891467675548590">"Выкарыстоўваць sRGB"</string>
@@ -321,40 +334,28 @@
     <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"Пратанамалія (чырвоны-зялёны)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Трытанамалія (сіні-жоўты)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Карэкцыя колеру"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Гэтая функцыя з\'яўляецца эксперыментальнай і можа паўплываць на прадукцыйнасць."</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Гэта функцыя з\'яўляецца эксперыментальнай і можа паўплываць на прадукцыйнасць."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Перавызначаны <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Засталося прыблізна <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Засталося каля <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Засталося каля <xliff:g id="TIME">%1$s</xliff:g> на аснове вашага выкарыстання"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Да поўнай зарадкі засталося <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Засталося <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_discharging_duration (2843747179907396142) -->
-    <skip />
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Засталося <xliff:g id="TIME">%1$s</xliff:g> на аснове вашага выкарыстання"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – засталося каля <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – засталося каля <xliff:g id="TIME">%2$s</xliff:g> на аснове вашага выкарыстання"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – засталося <xliff:g id="TIME">%2$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>
-    <!-- no translation found for power_charging_duration (4676999980973411875) -->
-    <skip />
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі"</string>
     <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
-    <skip />
-    <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
-    <skip />
-    <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
-    <skip />
-    <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Невядома"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Зарадка"</string>
-    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Зар. ад сеткі пер. току"</string>
-    <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Зарадка"</string>
-    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Зарадка па USB"</string>
-    <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Зарадка"</string>
-    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Бесправадная зарадка"</string>
-    <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Зарадка"</string>
+    <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ідзе зарадка"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"Не зараджаецца"</string>
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не зараджаецца"</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="2386503803463071894">"Уключана адміністратарам"</string>
-    <string name="disabled_by_admin" msgid="3669999613095206948">"Адключана адміністратарам"</string>
+    <string name="enabled_by_admin" msgid="5302986023578399263">"Уключана адміністратарам"</string>
+    <string name="disabled_by_admin" msgid="8505398946020816620">"Адключана адміністратарам"</string>
     <string name="home" msgid="3256884684164448244">"Галоўная старонка налад"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0 %"</item>
@@ -367,7 +368,7 @@
     <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Стандартны"</string>
     <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Вялікі"</string>
     <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Большы"</string>
-    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Найвялікшы"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Самы вялікі"</string>
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Карыстальніцкі (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Даведка і водгукі"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Меню"</string>
@@ -377,4 +378,7 @@
     <string name="retail_demo_reset_title" msgid="696589204029930100">"Патрабуецца пароль"</string>
     <string name="active_input_method_subtypes" msgid="3596398805424733238">"Актыўныя метады ўводу"</string>
     <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"Выкарыстоўваць мовы сістэмы"</string>
+    <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Не атрымалася адкрыць параметры <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
+    <string name="ime_security_warning" msgid="4135828934735934248">"Гэты метад уводу можа збіраць увесь тэкст, які ўводзіцца, у тым лiку такiя персанальныя дадзеныя, як паролі і нумары крэдытных карт. Ён выкарыстоўваецца прыкладаннем <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Выкарыстоўваць гэты метад уводу?"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Заўвага. Пасля перазагрузкі гэта праграма не зможа запусціцца, пакуль вы не разблакіруеце тэлефон"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bg/arrays.xml b/packages/SettingsLib/res/values-bg/arrays.xml
index 3f25978..fe1dad2 100644
--- a/packages/SettingsLib/res/values-bg/arrays.xml
+++ b/packages/SettingsLib/res/values-bg/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (по подразбиране)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Използване на сист. избор (стандартно)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"Разширено аудиокодиране (AAC)"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Активиране на кодеците по избор"</item>
-    <item msgid="3304843301758635896">"Деактивиране на кодеците по избор"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Използване на сист. избор (стандартно)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"Разширено аудиокодиране (AAC)"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Активиране на кодеците по избор"</item>
-    <item msgid="741805482892725657">"Деактивиране на кодеците по избор"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Използване на сист. избор (стандартно)"</item>
     <item msgid="8895532488906185219">"44,1 кХц"</item>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 2f7412e..aa42cce 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Не е установена връзка поради ниското качество на мрежата"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Неуспешна връзка с Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Проблем при удостоверяването"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Не може да се установи връзка"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Не може да се установи връзка с/ъс <xliff:g id="AP_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Проверете паролата и опитайте отново"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Извън обхват"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Няма да се свърже автоматично"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Няма достъп до интернет"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Установена е връзка през „%1$s“"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Мрежата е достъпна през „%1$s“"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Установена е връзка – няма достъп до интернет"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Много бавна"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Бавна"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ОK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Средна"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Бърза"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Много бърза"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Изкл."</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Изключва се..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Установява се връзка…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Свързано (без мултимедията)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Има връзка (няма достъп до съобщенията)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Свързано (без телефона или мултимедията)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Свързано, батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Свързано (без телефона), батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Свързано (без мултимедията), батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Свързано (без телефона или мултимедията), батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Мултимедийно аудио"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Звук на телефона"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефонни обаждания"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Прехвърляне на файл"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Входно устройство"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Достъп до интернет"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Споделяне на контакти"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Използване за споделяне на контакти"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Споделяне на връзката с интернет"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Достъп до съобщенията"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Текстови съобщения"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Достъп до SIM картата"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Използване на висококачествен звук: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Използване на висококачествен звук"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Висококачествено аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Висококачествено аудио"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Установена е връзка с медийно аудио"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Връзка със звука на телефона"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Установена е връзка със сървър за трансфер на файлове"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi към моб. мрежи: Агресивно предав."</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Сканирането за роуминг на Wi-Fi да е разрешено винаги"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Винаги активни мобилни данни"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардуерно ускорение за тетъринга"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Деактивиране на пълната сила на звука"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Активиране на звъненето в една и съща честотна лента"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версия на AVRCP за Bluetooth"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Разрешаване на измислени местоположения"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Актив. на инспектирането на атрибутите за преглед"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Мобилните данни са активни винаги – дори когато функцията за Wi‑Fi е включена (за бързо превключване между мрежите)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Да се използва хардуерно ускорение на тетъринга, ако е налице"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Разрешаване на отстраняването на грешки през USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Отстраняването на грешки през USB е предназначено само за програмни цели. Използвайте го за копиране на данни между компютъра и устройството си, за инсталиране на приложения на устройството си без известяване и за четене на регистрационни данни."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Да се отмени ли достъпът до отстраняването на грешки през USB от всички по-рано упълномощени от вас компютри?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекция на цветове"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Тази функция е експериментална и може да се отрази на ефективността."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Заменено от „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Оставащо време: около <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Оставащо време до пълно зареждане: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Оставащо време: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – около <xliff:g id="TIME">%2$s</xliff:g> оставащо време"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – оставащо време: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Оставащо време: около <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Още около <xliff:g id="TIME">^1</xliff:g> въз основа на използването"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Оставащо време до пълно зареждане: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Оставащо време: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Още <xliff:g id="TIME">^1</xliff:g> въз основа на използването"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – около <xliff:g id="TIME">^2</xliff:g> оставащо време"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – още около <xliff:g id="TIME">^2</xliff:g> въз основа на използването"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – оставащо време: <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> до пълно зареждане"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Неизвестно"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Зарежда се"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"зарежда се"</string>
diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml
index 4d5c1f1..ecfeb46 100644
--- a/packages/SettingsLib/res/values-bn/arrays.xml
+++ b/packages/SettingsLib/res/values-bn/arrays.xml
@@ -24,7 +24,7 @@
     <item msgid="1922181315419294640"></item>
     <item msgid="8934131797783724664">"স্ক্যান করা হচ্ছে…"</item>
     <item msgid="8513729475867537913">"সংযুক্ত হচ্ছে..."</item>
-    <item msgid="515055375277271756">"প্রমাণীকরণ হচ্ছে..."</item>
+    <item msgid="515055375277271756">"যাচাইকরণ হচ্ছে..."</item>
     <item msgid="1943354004029184381">"IP ঠিকানা প্রাপ্ত করা হচ্ছে..."</item>
     <item msgid="4221763391123233270">"সংযুক্ত হয়েছে"</item>
     <item msgid="624838831631122137">"স্থগিত করা হয়েছে"</item>
@@ -38,7 +38,7 @@
     <item msgid="7714855332363650812"></item>
     <item msgid="8878186979715711006">"স্ক্যান করা হচ্ছে…"</item>
     <item msgid="355508996603873860">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> এর সাথে সংযুক্ত হচ্ছে…"</item>
-    <item msgid="554971459996405634">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> দিয়ে প্রমাণীকরণ করা হচ্ছে..."</item>
+    <item msgid="554971459996405634">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> দিয়ে যাচাইকরণ করা হচ্ছে..."</item>
     <item msgid="7928343808033020343">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> থেকে IP ঠিকানা জানা হচ্ছে…"</item>
     <item msgid="8937994881315223448">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> তে সংযুক্ত হয়েছে"</item>
     <item msgid="1330262655415760617">"স্থগিত করা হয়েছে"</item>
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (ডিফল্ট)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"সিস্টেমের নির্বাচন ব্যবহার করুন (ডিফল্ট)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"ঐচ্ছিক কোডেক সক্ষম করুন"</item>
-    <item msgid="3304843301758635896">"ঐচ্ছিক কোডেক অক্ষম করুন"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"সিস্টেমের নির্বাচন ব্যবহার করুন (ডিফল্ট)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"ঐচ্ছিক কোডেক সক্ষম করুন"</item>
-    <item msgid="741805482892725657">"ঐচ্ছিক কোডেক অক্ষম করুন"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"সিস্টেমের নির্বাচন ব্যবহার করুন (ডিফল্ট)"</item>
     <item msgid="8895532488906185219">"৪৪.১ kHz"</item>
@@ -224,7 +210,7 @@
   </string-array>
   <string-array name="track_frame_time_entries">
     <item msgid="2193584639058893150">"বন্ধ করুন"</item>
-    <item msgid="2751513398307949636">"দন্ড হিসাবে স্ক্রীনে"</item>
+    <item msgid="2751513398307949636">"দন্ড হিসেবে স্ক্রীনে"</item>
     <item msgid="2355151170975410323">"<xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g> এ"</item>
   </string-array>
   <string-array name="debug_hw_overdraw_entries">
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 913345d..029d79d 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -27,37 +27,50 @@
     <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP কনফিগারেশনের ব্যর্থতা"</string>
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"খারাপ নেটওয়ার্কের কারণে সংযুক্ত নয়"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"ওয়াই ফাই সংযোগের ব্যর্থতা"</string>
-    <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"প্রমাণীকরণ সমস্যা"</string>
+    <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"যাচাইকরণ সমস্যা"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"সংযোগ স্থাপন করা যাচ্ছে না"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'এ যোগ করা যায়নি"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"পাসওয়ার্ড দেখে আবার চেষ্টা করুন"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"পরিসরের মধ্যে নয়"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"স্বয়ংক্রিয়ভাবে সংযোগ করবে না"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"কোনো ইন্টারনেট অ্যাক্সেস নেই"</string>
-    <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> দ্বারা সংরক্ষিত"</string>
+    <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> দ্বারা সেভ করা"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"স্বয়ংক্রিয়ভাবে %1$s এর মাধ্যমে সংযুক্ত হয়েছে"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"নেটওয়ার্কের রেটিং প্রদানকারীর মাধ্যমে স্বয়ংক্রিয়ভাবে সংযুক্ত"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s মাধ্যমে সংযুক্ত হয়েছে"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s এর মাধ্যমে উপলব্ধ"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"সংযুক্ত, ইন্টারনেট নেই"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"খুব ধীরে"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"ধীরে"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ঠিক আছে"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"মাঝারি"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"দ্রুত"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"খুব দ্রুত"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"সংযোগ বিচ্ছিন্ন করা হয়েছে"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"সংযোগ বিচ্ছিন্ন হচ্ছে..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"সংযুক্ত হচ্ছে..."</string>
     <string name="bluetooth_connected" msgid="6038755206916626419">"সংযুক্ত হয়েছে"</string>
-    <string name="bluetooth_pairing" msgid="1426882272690346242">"যুক্ত করা হচ্ছে..."</string>
+    <string name="bluetooth_pairing" msgid="1426882272690346242">"চেনানো হচ্ছে..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"সংযুক্ত (কোনো ফোন নেই)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"সংযুক্ত (কোনো মিডিয়া নেই)"</string>
-    <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"সংযুক্ত (কোনো বার্তা অ্যাক্সেস নেই)"</string>
+    <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"সংযুক্ত (কোনো মেসেজ অ্যাক্সেস নেই)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"সংযুক্ত (কোনো ফোন বা মিডিয়া নেই)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"সংযুক্ত হয়েছে, ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"সংযুক্ত হয়েছে (ফোন ছাড়া), ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"সংযুক্ত হয়েছে (মিডিয়া ছাড়া), ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"সংযুক্ত হয়েছে (ফোন বা মিডিয়া ছাড়া), ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"মিডিয়া অডিও"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ফোন অডিও"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ফোন কল"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ফাইল স্থানান্তর"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ইনপুট ডিভাইস"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ইন্টারনেট অ্যাক্সেস"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"পরিচিতি শেয়ার করা"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"পরিচিতি শেয়ার করার কাজে ব্যবহার করুন"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ইন্টারনেট সংযোগ শেয়ার করা হচ্ছে"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"বার্তা অ্যাক্সেস"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"এসএমএস"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"সিম -এর অ্যাক্সেস"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"উচ্চ মানের অডিও ব্যবহার করুন: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"উচ্চ মানের অডিও ব্যবহার করুন"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD অডিও: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD অডিও"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"মিডিয়া অডিওতে সংযুক্ত রয়েছে"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ফোন অডিওতে সংযুক্ত"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ফাইল স্থানান্তর সার্ভারের সঙ্গে সংযুক্ত"</string>
@@ -77,11 +90,11 @@
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"যুক্ত করুন"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"যুক্ত করুন"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"বাতিল করুন"</string>
-    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"যুক্ত করা থাকলে তা সংযুক্ত থাকাকালীন অবস্থায় আপনার পরিচিতিগুলি এবং কলের ইতিহাসকে অ্যাক্সেস করতে অনুমোদিত করে৷"</string>
-    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> এর সাথে যুক্ত করা যায়নি।"</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ভুল পিন বা পাস কী দেওয়ার কারণে <xliff:g id="DEVICE_NAME">%1$s</xliff:g> এর সঙ্গে যুক্ত করা যায়নি।"</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"চেনানো থাকলে তা সংযুক্ত থাকাকালীন অবস্থায় আপনার পরিচিতিগুলি এবং কলের ইতিহাসকে অ্যাক্সেস করতে অনুমোদিত করে৷"</string>
+    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> এর সাথে চেনানো যায়নি।"</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ভুল পিন বা কোড দেওয়ার কারণে <xliff:g id="DEVICE_NAME">%1$s</xliff:g> এর সঙ্গে চেনানো যায়নি।"</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> এর সঙ্গে যোগাযোগ করতে পারবেন না।"</string>
-    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"যুক্ত করা <xliff:g id="DEVICE_NAME">%1$s</xliff:g> প্রত্যাখ্যান করেছে।"</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"চেনানো <xliff:g id="DEVICE_NAME">%1$s</xliff:g> প্রত্যাখ্যান করেছে।"</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"ওয়াই ফাই বন্ধ৷"</string>
     <string name="accessibility_no_wifi" msgid="8834610636137374508">"ওয়াই ফাই এর সংযোগ বিচ্ছিন্ন হয়েছে৷"</string>
     <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"ওয়াই ফাই এ একটি দণ্ড৷"</string>
@@ -116,7 +129,7 @@
     <string name="tts_play_example_summary" msgid="8029071615047894486">"কথন সংশ্লেষণের উপর একটি ছোট ডেমো প্লে করুন"</string>
     <string name="tts_install_data_title" msgid="4264378440508149986">"ভয়েস ডেটা ইনস্টল করুন"</string>
     <string name="tts_install_data_summary" msgid="5742135732511822589">"বিবৃতি সংশ্লেষণের জন্য প্রয়োজনীয় ভয়েস ডেটা ইনস্টল করুন"</string>
-    <string name="tts_engine_security_warning" msgid="8786238102020223650">"এই বিবৃতি সংশ্লেষণ ইঞ্জিন হয়তো পাসওয়ার্ড এবং ক্রেডিট কার্ড নম্বর সহ কথ্য সমস্ত পাঠ্য সংগ্রহ করতে সক্ষম হতে পারে। এটি <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> ইঞ্জিন থেকে আসে। এই বিবৃতি সংশ্লেষণ ইঞ্জিন সক্ষম করবেন?"</string>
+    <string name="tts_engine_security_warning" msgid="8786238102020223650">"এই বিবৃতি সংশ্লেষণ ইঞ্জিন হয়তো পাসওয়ার্ড এবং ক্রেডিট কার্ড নম্বর সহ কথ্য সমস্ত টেক্সট সংগ্রহ করতে সক্ষম হতে পারে। এটি <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> ইঞ্জিন থেকে আসে। এই বিবৃতি সংশ্লেষণ ইঞ্জিন সক্রিয় করবেন?"</string>
     <string name="tts_engine_network_required" msgid="1190837151485314743">"পাঠ্য থেকে ভাষ্য আউটপুটের জন্য এই ভাষার একটি কাজ করছে এমন নেটওয়ার্ক সংযোগ প্রয়োজন।"</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"এটি হল ভাষ্য সংশ্লেষণের একটি উদাহরণ"</string>
     <string name="tts_status_title" msgid="7268566550242584413">"ডিফল্ট ভাষা স্থিতি"</string>
@@ -129,7 +142,7 @@
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"পছন্দের ইঞ্জিন"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"সাধারণ"</string>
     <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"ভাষ্য়ের শব্দ মাত্রাকে আবার সেট করুন"</string>
-    <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"ডিফল্ট হিসাবে যে মাত্রায় পাঠ্য উচ্চারিত হয়, সেই শব্দ মাত্রাকে আবার সেট করুন৷"</string>
+    <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"ডিফল্ট হিসেবে যে মাত্রায় পাঠ্য উচ্চারিত হয়, সেই শব্দ মাত্রাকে আবার সেট করুন৷"</string>
   <string-array name="tts_rate_entries">
     <item msgid="6695494874362656215">"অত্যন্ত ধীরে"</item>
     <item msgid="4795095314303559268">"ধীর"</item>
@@ -144,10 +157,10 @@
     <string name="choose_profile" msgid="6921016979430278661">"প্রোফাইল বেছে নিন"</string>
     <string name="category_personal" msgid="1299663247844969448">"ব্যক্তিগত"</string>
     <string name="category_work" msgid="8699184680584175622">"কর্মক্ষেত্র"</string>
-    <string name="development_settings_title" msgid="215179176067683667">"বিকাশকারী বিকল্পগুলি"</string>
-    <string name="development_settings_enable" msgid="542530994778109538">"বিকাশকারী বিকল্পগুলি সক্ষম করুন"</string>
+    <string name="development_settings_title" msgid="215179176067683667">"ডেভেলপার বিকল্প"</string>
+    <string name="development_settings_enable" msgid="542530994778109538">"ডেভেলপার বিকল্প সক্ষম করুন"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"অ্যাপ্লিকেশান উন্নয়নের জন্য বিকল্পগুলি সেট করুন"</string>
-    <string name="development_settings_not_available" msgid="4308569041701535607">"এই ব্যবহারকারীর জন্য বিকাশকারী বিকল্পগুলি উপলব্ধ নয়"</string>
+    <string name="development_settings_not_available" msgid="4308569041701535607">"এই ব্যবহারকারীর জন্য ডেভেলপার বিকল্প উপলব্ধ নয়"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"এই ব্যবহারকারীর জন্য VPN সেটিংস উপলব্ধ নয়"</string>
     <string name="tethering_settings_not_available" msgid="6765770438438291012">"এই ব্যবহারকারীর জন্য টেদারিং সেটিংস উপলব্ধ নয়"</string>
     <string name="apn_settings_not_available" msgid="7873729032165324000">"এই ব্যবহারকারীর জন্য অ্যাক্সেস পয়েন্ট নাম সেটিংস উপলব্ধ নয়"</string>
@@ -164,7 +177,7 @@
     <string name="oem_unlock_enable_summary" msgid="4720281828891618376">"বুট-লোডার আনলক করার অনুমতি দিন"</string>
     <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM আনলক করার অনুমতি দিতে চান?"</string>
     <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"সতর্কতা: এই ডিভাইসে সেটিংটি চালু থাকা অবস্থায় ডিভাইস সুরক্ষা বৈশিষ্ট্যগুলি কাজ করবে না৷"</string>
-    <string name="mock_location_app" msgid="7966220972812881854">"অনুরূপ অবস্থান অ্যাপ্লিকেশান নির্বাচন করুন"</string>
+    <string name="mock_location_app" msgid="7966220972812881854">"অনুরূপ অবস্থান অ্যাপ্লিকেশান বেছে নিন"</string>
     <string name="mock_location_app_not_set" msgid="809543285495344223">"কোনো অনুরূপ অবস্থান অ্যাপ্লিকেশান সেট করা নেই"</string>
     <string name="mock_location_app_set" msgid="8966420655295102685">"অনুরূপ অবস্থান অ্যাপ্লিকেশান: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="debug_networking_category" msgid="7044075693643009662">"নেটওয়ার্কিং"</string>
@@ -173,10 +186,11 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ওয়াই-ফাই থেকে মোবাইলে তৎপর হস্তান্তর"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"সর্বদা ওয়াই ফাই রোম স্ক্যানকে অনুমতি দিন"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"মোবাইল ডেটা সব সময় সক্রিয় থাক"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"টিথারিং হার্ডওয়্যার অ্যাক্সিলারেশন"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"চূড়ান্ত ভলিউম অক্ষম করুন"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ইন-ব্যান্ড রিং করা সক্ষম করুন"</string>
-    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ব্লুটুথ AVRCP সংস্করণ"</string>
-    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ব্লুটুথ AVRCP সংস্করণ বেছে নিন"</string>
+    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ব্লুটুথ AVRCP ভার্সন"</string>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ব্লুটুথ AVRCP ভার্সন বেছে নিন"</string>
     <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ব্লুটুথ অডিও কোডেক"</string>
     <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ব্লুটুথ অডিও কোডেক বেছে নিন"</string>
     <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ব্লুটুথ অডিওর নমুনা হার"</string>
@@ -193,23 +207,24 @@
     <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"সক্ষম করা থাকলে, ওয়াই ফাই সিগন্যালের মান খারাপ হলে ডেটা সংযোগ মোবাইলের কাছে হস্তান্তর করার জন্য ওয়াই ফাই আরো বেশি তৎপর হবে।"</string>
     <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ইন্টারফেসে উপস্থিত ডেটা ট্রাফিকের পরিমাণের উপরে ভিত্তি করে ওয়াই-ফাই রোম স্ক্যানকে অনুমোদিত/অননুমোদিত করুন"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"লগার বাফারের আকারগুলি"</string>
-    <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"লগ বাফার প্রতি অপেক্ষাকৃত বড় আকারগুলির নির্বাচন করুন"</string>
-    <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"লগারের সঞ্চয়স্থান সাফ করবেন?"</string>
+    <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"লগ বাফার প্রতি অপেক্ষাকৃত বড় আকারগুলির বেছে নিন"</string>
+    <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"লগারের স্টোরেজ সাফ করবেন?"</string>
     <string name="dev_logpersist_clear_warning_message" msgid="2256582531342994562">"যেহেতু আমারা সর্বদা লগার চালু রেখে আর নিরিক্ষণ করছি না, তাই আমাদের আপনার ডিভাইসে থাকা লগার ডেটা মুছে ফেলতে হবে৷"</string>
-    <string name="select_logpersist_title" msgid="7530031344550073166">"ডিভাইসে স্থায়ীভাবে লগার ডেটা সংরক্ষণ করুন"</string>
-    <string name="select_logpersist_dialog_title" msgid="4003400579973269060">"ডিভাইসে স্থায়ীভাবে সঞ্চয় করতে লগ বাফারগুলিকে নির্বাচন করুন"</string>
-    <string name="select_usb_configuration_title" msgid="2649938511506971843">"USB কনফিগারেশন নির্বাচন করুন"</string>
-    <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"USB কনফিগারেশন নির্বাচন করুন"</string>
+    <string name="select_logpersist_title" msgid="7530031344550073166">"ডিভাইসে স্থায়ীভাবে লগার ডেটা সেভ করুন"</string>
+    <string name="select_logpersist_dialog_title" msgid="4003400579973269060">"ডিভাইসে স্থায়ীভাবে সঞ্চয় করতে লগ বাফারগুলিকে বেছে নিন"</string>
+    <string name="select_usb_configuration_title" msgid="2649938511506971843">"USB কনফিগারেশন বেছে নিন"</string>
+    <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"USB কনফিগারেশন বেছে নিন"</string>
     <string name="allow_mock_location" msgid="2787962564578664888">"নকল অবস্থানের অনুমতি দিন"</string>
     <string name="allow_mock_location_summary" msgid="317615105156345626">"মক অবস্থানগুলি মঞ্জুর করুন"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"অ্যাট্রিবিউট পরিদর্শন দেখা সক্ষম করুন"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ওয়াই-ফাই সক্রিয় থাকার সময়েও (দ্রুত নেটওয়ার্কে পাল্টানোর জন্য) সর্বদা মোবাইল ডেটা সক্রিয় রাখুন।"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"টিথারিং হার্ডওয়্যার অ্যাক্সিলারেশন উপলব্ধ থাকলে ব্যবহার করুন"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB ডিবাগিং মঞ্জুর করবেন?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB ডিবাগিং কেবলমাত্র বিকাশ করার উদ্দেশ্যে। আপনার কম্পিউটার এবং আপনার ডিভাইসের মধ্যে ডেটা অনুলিপি করতে এটি ব্যবহার করুন, বিজ্ঞপ্তি ছাড়া আপনার ডিভাইসে অ্যাপ্লিকেশানগুলি ইনস্টল করুন এবং ডেটা লগ পড়ুন।"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"আপনি আগে যে সব কম্পিউটার USB ডিবাগিং এর অ্যাক্সেসের অনুমতি দিয়েছিলেন তা প্রত্যাহার করবেন?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"উন্নতি সেটিংসের অনুমতি দেবেন?"</string>
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"এইসব সেটিংস কেবলমাত্র উন্নত করার উদ্দেশ্য। সেগুলি কারণে আপনার ডিভাইস ভেঙ্গে এবং অ্যাপ্লিকেশানগুলি ভালো ভাবে কাজ করা নাও কারতে পারে।"</string>
-    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB এর অ্যাপ্লিকেশানগুলি যাচাই করুন"</string>
+    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB এর অ্যাপ্লিকেশনগুলি যাচাই করুন"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ক্ষতিকারক ক্রিয়াকলাপ করছে কিনা তার জন্য ADB/ADT মারফত ইনস্টল করা অ্যাপ্লিকেশানগুলি চেক করুন।"</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"অপ্রত্যাশিত উচ্চ ভলিউম বা নিয়ন্ত্রণের অভাবের মত দূরবর্তী ডিভাইসের ভলিউম সমস্যাগুলির ক্ষেত্রে, ব্লুটুথ চুড়ান্ত ভলিউম বৈশিষ্ট্য অক্ষম করে৷"</string>
     <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"ফোনের রিংটোন ব্লুটুথ হেডসেটে শোনা সক্ষম করুন"</string>
@@ -218,15 +233,15 @@
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP পরীক্ষণ"</string>
     <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"HDCP চেক করার আচরণ সেট করুন"</string>
     <string name="debug_debugging_category" msgid="6781250159513471316">"ডিবাগিং"</string>
-    <string name="debug_app" msgid="8349591734751384446">"ডিবাগ অ্যাপ্লিকেশান নির্বাচন করুন"</string>
+    <string name="debug_app" msgid="8349591734751384446">"ডিবাগ অ্যাপ্লিকেশান বেছে নিন"</string>
     <string name="debug_app_not_set" msgid="718752499586403499">"ডিবাগ অ্যাপ্লিকেশান সেট করা নেই"</string>
     <string name="debug_app_set" msgid="2063077997870280017">"ডিবাগিং অ্যাপ্লিকেশান: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="select_application" msgid="5156029161289091703">"অ্যাপ্লিকেশান নির্বাচন করুন"</string>
+    <string name="select_application" msgid="5156029161289091703">"অ্যাপ্লিকেশান বেছে নিন"</string>
     <string name="no_application" msgid="2813387563129153880">"কিছুই না"</string>
     <string name="wait_for_debugger" msgid="1202370874528893091">"ডিবাগারের জন্য অপেক্ষা করুন"</string>
     <string name="wait_for_debugger_summary" msgid="1766918303462746804">"চালানোর আগে সংযুক্ত করতে জন্য ডিবাগ করা অ্যাপ্লিকেশনটি ডিবাগারের জন্য অপেক্ষা করছে"</string>
     <string name="telephony_monitor_switch" msgid="1764958220062121194">"টেলিফোনি মনিটর"</string>
-    <string name="telephony_monitor_switch_summary" msgid="7695552966547975635">"টেলিফোনি মনিটর টেলিফোনি/মোডেমের কার্যকারিতায় কোনো সমস্যা শনাক্ত করলে সমস্যাটি লগ করবে এবং সমস্যাটি জানাতে একটি বাগ ফাইল করার জন্য ব্যবহারকারিকে বিজ্ঞপ্তি পাঠাবে"</string>
+    <string name="telephony_monitor_switch_summary" msgid="7695552966547975635">"টেলিফোনি মনিটর টেলিফোনি/মোডেমের কার্যকারিতায় কোনও সমস্যা শনাক্ত করলে সমস্যাটি লগ করবে এবং সমস্যাটি জানাতে একটি বাগ ফাইল করার জন্য ব্যবহারকারিকে বিজ্ঞপ্তি পাঠাবে"</string>
     <string name="debug_input_category" msgid="1811069939601180246">"ইনপুট"</string>
     <string name="debug_drawing_category" msgid="6755716469267367852">"অঙ্কন"</string>
     <string name="debug_hw_drawing_category" msgid="6220174216912308658">"হার্ডওয়্যার দ্বারা চালিত রেন্ডারিং"</string>
@@ -266,7 +281,7 @@
     <string name="transition_animation_scale_title" msgid="387527540523595875">"ট্র্যানজিশন অ্যানিমেশন স্কেল"</string>
     <string name="animator_duration_scale_title" msgid="3406722410819934083">"অ্যানিমেটর সময়কাল স্কেল"</string>
     <string name="overlay_display_devices_title" msgid="5364176287998398539">"গৌণ প্রদর্শনগুলি নকল করুন"</string>
-    <string name="debug_applications_category" msgid="4206913653849771549">"অ্যাপ্লিকেশানগুলি"</string>
+    <string name="debug_applications_category" msgid="4206913653849771549">"অ্যাপ"</string>
     <string name="immediately_destroy_activities" msgid="1579659389568133959">"কার্যকলাপ রাখবেন না"</string>
     <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"ব্যবহারকারী এটি ছেড়ে যাওয়ার পরে যত তাড়াতাড়ি সম্ভব প্রতিটি কার্যকলাপ ধ্বংস করুন"</string>
     <string name="app_process_limit_title" msgid="4280600650253107163">"পশ্চাদপট প্রক্রিয়ার সীমা"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"রঙ সংশোধন"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"এই বৈশিষ্ট্যটি পরীক্ষামূলক এবং এটি কার্য-সম্পাদনা প্রভাবিত করতে পারে।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> এর দ্বারা ওভাররাইড করা হয়েছে"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"প্রায় <xliff:g id="TIME">%1$s</xliff:g> বাকি"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%1$s</xliff:g> বাকি"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - প্রায় <xliff:g id="TIME">%2$s</xliff:g> বাকি আছে"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"প্রায় <xliff:g id="TIME">^1</xliff:g> বাকি"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"বর্তমান ব্যাটারি ব্যবহার অনুযায়ী আর <xliff:g id="TIME">^1</xliff:g> বাকি"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">^1</xliff:g> বাকি"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> বাকী আছে"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"বর্তমান ব্যাটারি ব্যবহার অনুযায়ী আর <xliff:g id="TIME">^1</xliff:g> বাকি"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - প্রায় <xliff:g id="TIME">^2</xliff:g> বাকি আছে"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - বর্তমান ব্যাটারি ব্যবহার অনুযায়ী আর <xliff:g id="TIME">^2</xliff:g> বাকি"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%2$s</xliff:g> লাগবে"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">^2</xliff:g> লাগবে"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"অজানা"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"চার্জ হচ্ছে"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"চার্জ হচ্ছে"</string>
@@ -364,6 +382,6 @@
     <string name="active_input_method_subtypes" msgid="3596398805424733238">"সক্রিয় ইনপুট পদ্ধতিগুলি"</string>
     <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"সিস্টেমের ভাষাগুলি ব্যবহার করুন"</string>
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> জন্য সেটিংস খুলতে ব্যর্থ হয়েছে"</string>
-    <string name="ime_security_warning" msgid="4135828934735934248">"এই ইনপুট পদ্ধতিটি হয়তো পাসওয়ার্ড এবং ক্রেডিট কার্ড নম্বর সহ আপনার টাইপ করা সমস্ত পাঠ্য সংগ্রহ করতে সক্ষম হতে পারে। এটি <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> অ্যাপ্লিকেশানের। এই ইনপুট পদ্ধতিটি ব্যবহার করবেন?"</string>
+    <string name="ime_security_warning" msgid="4135828934735934248">"এই ইনপুট পদ্ধতিটি হয়তো পাসওয়ার্ড এবং ক্রেডিট কার্ড নম্বর সহ আপনার টাইপ করা সমস্ত টেক্সট সংগ্রহ করতে সক্ষম হতে পারে। এটি <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> অ্যাপ থেকে এসেছে। এই ইনপুট পদ্ধতিটি ব্যবহার করবেন?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"দ্রষ্টব্য: পুনরায় চালু করার পরে, আপনি আপনার ফোন আনলক না করা পর্যন্ত এই অ্যাপটিকে চালু করতে পারবেন না"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index 58b3a47..a97d1ac 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -58,27 +58,35 @@
     <item msgid="3878793616631049349">"Koristi HDCP provjeru samo za DRM sadržaj"</item>
     <item msgid="45075631231212732">"Uvijek koristi HDCP provjeru"</item>
   </string-array>
-    <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
-    <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
-    <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+  <string-array name="bluetooth_avrcp_versions">
+    <item msgid="5347678900838034763">"AVRCP 1.4 (Zadano)"</item>
+    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+  </string-array>
+  <string-array name="bluetooth_avrcp_version_values">
+    <item msgid="2838624067805073303">"avrcp14"</item>
+    <item msgid="1913619118958233129">"avrcp15"</item>
+    <item msgid="7142710449249088270">"avrcp16"</item>
+  </string-array>
   <string-array name="bluetooth_a2dp_codec_titles">
     <item msgid="7065842274271279580">"Koristi odabir sistema (Zadano)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
+    <item msgid="723675059572222462">"Omogućite opcionalne kodeke"</item>
+    <item msgid="3304843301758635896">"Onemogućite opcionalne kodeke"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_summaries">
     <item msgid="5062108632402595000">"Koristi odabir sistema (Zadano)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
+    <item msgid="2209680154067241740">"Omogućite opcionalne kodeke"</item>
+    <item msgid="741805482892725657">"Onemogućite opcionalne kodeke"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Koristi odabir sistema (Zadano)"</item>
@@ -120,11 +128,13 @@
     <item msgid="7158319962230727476">"Optimizirano za kvalitet zvuka (990 kbps/909 kbps)"</item>
     <item msgid="2921767058740704969">"Uravnotežen kvalitet zvuka i veze (660kbps/606kbps)"</item>
     <item msgid="8860982705384396512">"Optimizirano za kvalitet veze (330 kbps/303 kbps)"</item>
+    <item msgid="4414060457677684127">"Maksimalan napor (Prilagodljiva brzina prijenosa)"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
     <item msgid="6398189564246596868">"Optimizirano za kvalitet zvuka"</item>
     <item msgid="4327143584633311908">"Uravnotežen kvalitet zvuka i veze"</item>
     <item msgid="4681409244565426925">"Optimizirano za kvalitet veze"</item>
+    <item msgid="364670732877872677">"Maksimalan napor (Prilagodljiva brzina prijenosa)"</item>
   </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Isključeno"</item>
@@ -235,7 +245,7 @@
     <item msgid="7899496259191969307">"Najviše 4 procesa"</item>
   </string-array>
   <string-array name="usb_configuration_titles">
-    <item msgid="488237561639712799">"Puni se"</item>
+    <item msgid="488237561639712799">"Punjenje"</item>
     <item msgid="5220695614993094977">"MTP (protokol za prijenos sadržaja medija)"</item>
     <item msgid="2086000968159047375">"PTP (protokol za prijenos slika)"</item>
     <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index ce40282..58598a3 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -32,13 +32,23 @@
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Neće se automatski povezati"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Nema pristupa internetu"</string>
     <string name="saved_network" msgid="4352716707126620811">"Sačuvao <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
-    <skip />
-    <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
-    <skip />
+    <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatski povezano koristeći %1$s"</string>
+    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatski povezano putem ocjenjivača mreže"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Povezani preko %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupan preko %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Povezano. Nema interneta"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Isključen"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Prekidanje veze…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Povezivanje…"</string>
@@ -49,15 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Povezano (bez pristupa porukama)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Povezano (bez zvuka telefona ili medija)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk medija"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Zvuk telefona"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prenošenje fajla"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Ulazni uređaj"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Pristup internetu"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Dijeljenje kontakta"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Koristi za dijeljenje kontakta"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Dijeljenje internet veze"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Pristup poruci"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Pristup SIM-u"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Povezano sa zvukom medija"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Povezano na zvuk telefona"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Povezan na server za prijenos podataka"</string>
@@ -95,7 +111,7 @@
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Prijenosna pristupna tačka"</string>
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Dijeljenje Bluetooth veze"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Dijeljenje veze"</string>
-    <string name="tether_settings_title_all" msgid="8356136101061143841">"Dijeljenje internetske veze i prijenosna pristupna tačka"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"Povezivanje putem mobitela i prijenosna pristupna tačka"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"Sve radne aplikacije"</string>
     <string name="user_guest" msgid="8475274842845401871">"Gost"</string>
     <string name="unknown" msgid="1592123443519355854">"Nepoznato"</string>
@@ -103,21 +119,21 @@
     <string name="launch_defaults_some" msgid="313159469856372621">"Neke zadane vrijednosti su postavljene"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"Nema postavljenih zadanih vrijednosti"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Postavke za pretvaranje teksta u govor"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"Izlaz za pretvaranje teksta u govor"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"Pretvaranje teksta u govor"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Brzina govora"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"Brzina kojom se izgovara tekst"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"Visina"</string>
     <string name="tts_default_pitch_summary" msgid="1944885882882650009">"Utječe na ton sintetiziranog govora"</string>
     <string name="tts_default_lang_title" msgid="8018087612299820556">"Jezik"</string>
-    <string name="tts_lang_use_system" msgid="2679252467416513208">"Koristi sistemski jezik"</string>
+    <string name="tts_lang_use_system" msgid="2679252467416513208">"Korištenje sistemskog jezika"</string>
     <string name="tts_lang_not_selected" msgid="7395787019276734765">"Jezik nije izabran"</string>
     <string name="tts_default_lang_summary" msgid="5219362163902707785">"Postavlja glas za dati jezik za izgovoreni tekst"</string>
     <string name="tts_play_example_title" msgid="7094780383253097230">"Poslušajte primjer"</string>
     <string name="tts_play_example_summary" msgid="8029071615047894486">"Reproduciraj kratku demonstraciju sintetiziranja govora"</string>
-    <string name="tts_install_data_title" msgid="4264378440508149986">"Instaliraj glasovne podatke"</string>
-    <string name="tts_install_data_summary" msgid="5742135732511822589">"Instalirajte glasovne podatke potrebne za sintetiziranje govora"</string>
+    <string name="tts_install_data_title" msgid="4264378440508149986">"Instaliranje glasovnih podataka"</string>
+    <string name="tts_install_data_summary" msgid="5742135732511822589">"Instaliranje glasovnih podataka potrebnih za sintetiziranje govora"</string>
     <string name="tts_engine_security_warning" msgid="8786238102020223650">"Ovaj program za sintetiziranje govora u mogućnosti je da prikuplja sav tekst koji se izgovara, uključujući lične podatke kao što su lozinke i brojevi kreditnih kartica. Program omogućava aplikacija <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Da li želite koristiti ovaj program za sintetiziranje govora?"</string>
-    <string name="tts_engine_network_required" msgid="1190837151485314743">"Ovaj jezik zahtijeva mrežnu vezu radi za izlaz tekst-u-govor."</string>
+    <string name="tts_engine_network_required" msgid="1190837151485314743">"Ovaj jezik zahtijeva aktivnu mrežnu vezu za pretvaranje teksta u govor."</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"Ovo je primjer sinteze govora"</string>
     <string name="tts_status_title" msgid="7268566550242584413">"Zadani status jezika"</string>
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> je u potpunosti podržan"</string>
@@ -126,8 +142,8 @@
     <string name="tts_status_checking" msgid="5339150797940483592">"Provjerava se…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Postavke za <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Pokreni postavke programa"</string>
-    <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Željeni program"</string>
-    <string name="tts_general_section_title" msgid="4402572014604490502">"Opće"</string>
+    <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Željeni alat"</string>
+    <string name="tts_general_section_title" msgid="4402572014604490502">"Opće postavke"</string>
     <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Postavite visinu glasa"</string>
     <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Visinu glasa koji izgovara tekst postavite na podrazumjevanu."</string>
   <string-array name="tts_rate_entries">
@@ -141,7 +157,7 @@
     <item msgid="5194774745031751806">"Veoma ubrzano"</item>
     <item msgid="9085102246155045744">"Najbrže"</item>
   </string-array>
-    <string name="choose_profile" msgid="8229363046053568878">"Odaberite profil"</string>
+    <string name="choose_profile" msgid="6921016979430278661">"Odaberite profil"</string>
     <string name="category_personal" msgid="1299663247844969448">"Lično"</string>
     <string name="category_work" msgid="8699184680584175622">"Posao"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Opcije za programere"</string>
@@ -170,16 +186,13 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikacija bežičnog prikaza"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogućiti Wi-Fi Verbose zapisivanje"</string>
-    <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
-    <skip />
+    <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresivni prijenos s Wi-Fi mreže na mob."</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvijek dopustiti Wi-Fi lutajuće skeniranje"</string>
-    <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
-    <skip />
+    <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilna mreža za prijenos podataka je uvijek aktivna"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogućite apsolutnu jačinu zvuka"</string>
-    <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
-    <skip />
-    <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
-    <skip />
+    <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Omogući zvono unutar pojasa"</string>
+    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP verzija"</string>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Odaberite Bluetooth AVRCP verziju"</string>
     <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio kodek"</string>
     <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Odaberite Bluetooth Audio kodek"</string>
     <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Brzina uzorkovanja za Bluetooth audio"</string>
@@ -193,8 +206,7 @@
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Prijenos: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaži opcije za certifikaciju Bežičnog prikaza"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećajte nivo Wi-Fi zapisivanja, pokazati po SSID RSSI Wi-Fi Picker"</string>
-    <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
-    <skip />
+    <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kada je omogućeno, Wi-Fi veza će u slučaju slabog signala agresivnije predavati vezu za prijenos podataka na mobilnu vezu"</string>
     <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Dozvoli/Zabrani Wi-Fi lutajuće skeniranje na osnovu količine podatkovnog prometa prisutnog na sučelju"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Veličine bafera za zapisnik"</string>
     <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Izaberite veličine za Logger prema međumemoriji evidencije"</string>
@@ -216,10 +228,11 @@
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifikuj aplikacije putem USB-a"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Provjerava da li se u aplikacijama instaliranim putem ADB-a/ADT-a javlja zlonamerno ponašanje."</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Onemogućava opciju Bluetooth apsolutne jačine zvuka u slučaju problema s jačinom zvuka na udaljenim uređajima, kao što je neprihvatljivo glasan zvuk ili nedostatak kontrole."</string>
+    <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"Dopusti da se melodije zvona reproduciranju na Bluetooth slušalicama"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokalni terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Omogući terminalnu aplik. koja nudi pristup lok. kom. okruženju"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP provjeravanje"</string>
-    <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"Pos. ponaš. kod HDCP pr."</string>
+    <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"Postavke HDCP provjere"</string>
     <string name="debug_debugging_category" msgid="6781250159513471316">"Otklanjanje grešaka"</string>
     <string name="debug_app" msgid="8349591734751384446">"Odaberi aplikaciju za otklanjanje grešaka"</string>
     <string name="debug_app_not_set" msgid="718752499586403499">"Nema postavljenih aplikac. za otklanjanje grešaka"</string>
@@ -275,18 +288,20 @@
     <string name="app_process_limit_title" msgid="4280600650253107163">"Ograničenje procesa u pozadini"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"Prikaži sve ANR-ove"</string>
     <string name="show_all_anrs_summary" msgid="641908614413544127">"Prik. dijalog Aplikacija ne reagira za apl. u poz."</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Prikaz upozorenja na obavještenju o kanalu"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Prikaz upozorenja ekranu kada aplikacija pošalje obavještenje bez važećeg kanala."</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"Nametni aplikacije na vanjskoj pohrani"</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Omogućava da svaka aplikacija bude pogodna za upisivanje na vanjsku pohranu, bez obzira na prikazane vrijednosti"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Nametni aktivnostima mijenjanje veličina"</string>
     <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Neka sve aktivnosti budu takve da mogu mijenjati veličinu za prikaz sa više prozora, bez obzira na prikazane vrijednosti."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Omogući prozore nepravilnih oblika"</string>
     <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Omogućiti podršku za eksperimentalne prozore nepravilnih oblika."</string>
-    <string name="local_backup_password_title" msgid="3860471654439418822">"Lozinka za rezervnu kopiju radne površine"</string>
+    <string name="local_backup_password_title" msgid="3860471654439418822">"Lozinka za sigurnosnu kopiju radne površine"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Potpune sigurnosne kopije za računare trenutno nisu zaštićene"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Dodirnite da promijenite ili uklonite lozinku za potpune rezervne kopije sa radne površine"</string>
-    <string name="local_backup_password_toast_success" msgid="582016086228434290">"Nova lozinka za rezervnu kopiju postavljena"</string>
+    <string name="local_backup_password_toast_success" msgid="582016086228434290">"Nova lozinka za sigurnosnu kopiju postavljena"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Nova lozinka i potvrda se ne podudaraju"</string>
-    <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Nije uspjelo postavljanje lozinke za rezervnu kopiju"</string>
+    <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Nije uspjelo postavljanje lozinke za sigurnosnu kopiju"</string>
   <string-array name="color_mode_names">
     <item msgid="2425514299220523812">"Živopisan (zadano)"</item>
     <item msgid="8446070607501413455">"Prirodan"</item>
@@ -302,16 +317,14 @@
     <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktivno. Dodirnite za promjenu opcije."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Pokrenute usluge"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Prikažite trenutno pokrenute usluge i upravljajte njima"</string>
-    <string name="enable_webview_multiprocess" msgid="3352660896640797330">"Višeprocesni WebView"</string>
-    <string name="enable_webview_multiprocess_desc" msgid="2485604010404197724">"Pokreni odvojeno WebView rendere"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Postavljanje WebViewa"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Podesi WebView"</string>
     <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"Ovaj izbor više ne vrijedi. Pokušajte ponovo."</string>
-    <string name="convert_to_file_encryption" msgid="3060156730651061223">"Pretvori u šifrirani fajl"</string>
+    <string name="convert_to_file_encryption" msgid="3060156730651061223">"Pretvaranje u šifrirani fajl"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Pretvaranje…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Fajl je već šifriran"</string>
     <string name="title_convert_fbe" msgid="1263622876196444453">"Pretvaranje u šifrirane fajlove"</string>
-    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Pretvori particiju sa podacima u particiju šifriranu sistemom fajlova.\n !! Upozorenje!! Ovo će izbrisati sve vaše podatke.\n Ova funkcija je u alfa fazi razvoja i možda neće ispravno raditi.\n Pritisnite \'Obriši i pretvori…\" da nastavite."</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Pretvorite particiju sa podacima u particiju šifriranu sistemom fajlova.\n !! Upozorenje!! Ovo će izbrisati sve vaše podatke.\n Ova funkcija je u alfa fazi razvoja i možda neće ispravno raditi.\n Pritisnite \"Obriši i pretvori…\" da nastavite."</string>
     <string name="button_convert_fbe" msgid="5152671181309826405">"Obriši i pretvori…"</string>
     <string name="picture_color_mode" msgid="4560755008730283695">"Režim boja Slika"</string>
     <string name="picture_color_mode_desc" msgid="1141891467675548590">"Koristi sRGB"</string>
@@ -321,40 +334,28 @@
     <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"Protanomalija (crveno-zeleno)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Tritanomalija (plavo-žuta)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Ispravka boje"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna te može utjecati na performanse."</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna i može uticati na performanse."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamjenjuje <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Preostalo je otprilike još <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Preostalo je još oko <xliff:g id="TIME">%1$s</xliff:g>, na osnovu vašeg korištenja"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Još <xliff:g id="TIME">%1$s</xliff:g> do potpune napunjenosti"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Imate još <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_discharging_duration (2843747179907396142) -->
-    <skip />
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Preostalo je još <xliff:g id="TIME">%1$s</xliff:g>, na osnovu vašeg korištenja"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - imate još <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - preostalo je još oko <xliff:g id="TIME">%2$s</xliff:g>, na osnovu vašeg korištenja"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - imate još <xliff:g id="TIME">%2$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>
-    <!-- no translation found for power_charging_duration (4676999980973411875) -->
-    <skip />
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti"</string>
     <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
-    <skip />
-    <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
-    <skip />
-    <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
-    <skip />
-    <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
-    <string name="battery_info_status_charging" msgid="1705179948350365604">"Puni se"</string>
-    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Puni se na punjaču"</string>
-    <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Punjenje"</string>
-    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Punjenje preko USB-a"</string>
-    <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Punjenje"</string>
-    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bežično punjenje"</string>
-    <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Punjenje"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
+    <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"punjenje"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string>
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</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="2386503803463071894">"Omogućio administrator"</string>
-    <string name="disabled_by_admin" msgid="3669999613095206948">"Onemogućio je 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="home" msgid="3256884684164448244">"Postavke početne stranice"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
@@ -366,8 +367,8 @@
     <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Malo"</string>
     <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Zadano"</string>
     <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Veliko"</string>
-    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Veće"</string>
-    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Najveće"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Vrlo veliko"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Najveći"</string>
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagodi (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Pomoć i povratne informacije"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Meni"</string>
@@ -377,4 +378,7 @@
     <string name="retail_demo_reset_title" msgid="696589204029930100">"Potrebna je lozinka"</string>
     <string name="active_input_method_subtypes" msgid="3596398805424733238">"Aktivne metode unosa"</string>
     <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"Koristi jezik sistema"</string>
+    <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Nije uspjelo otvaranje postavki za <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
+    <string name="ime_security_warning" msgid="4135828934735934248">"Ovaj način unosa može prikupiti sav tekst koji otkucate, uključujući lične podatke kao što su lozinke i brojevi kreditnih kartica. Način omogućava aplikacija <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Da li želite koristiti ovaj način unosa?"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Napomena: Nakon ponovnog pokretanja, ova aplikacija se neće moći pokrenuti dok ne otključate telefon"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index bdc2cac..d7eb2d4 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (predeterminada)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Utilitza selecció del sistema (predeterminada)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Activa els còdecs opcionals"</item>
-    <item msgid="3304843301758635896">"Desactiva els còdecs opcionals"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Utilitza selecció del sistema (predeterminada)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Activa els còdecs opcionals"</item>
-    <item msgid="741805482892725657">"Desactiva els còdecs opcionals"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Utilitza selecció del sistema (predeterminada)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 0efc5bc..00bb4a9 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"No s\'ha connectat a la xarxa perquè la qualitat és baixa"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Error de connexió Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problema d\'autenticació"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"No es pot connectar"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"No es pot connectar a <xliff:g id="AP_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Comprova la contrasenya i torna-ho a provar"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Fora de l\'abast"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"No es connectarà automàticament"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"No hi ha accés a Internet"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Connectada mitjançant %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible mitjançant %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connectada, sense Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Molt lenta"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Correcta"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Mitjana"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Ràpida"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Molt ràpida"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconnectat"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"S\'està desconnectant..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"S\'està connectant…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Connectat (sense fitxers multimèdia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connectat (no hi ha accés als missatges)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Connectat (sense telèfon o disp. mult.)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connectat (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria)"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connectat, sense telèfon (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria)"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connectat, sense àudio multimèdia (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria)"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connectat, sense telèfon ni àudio multimèdia (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Àudio multimèdia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Àudio del telèfon"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Trucades telefòniques"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferència del fitxer"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositiu d\'entrada"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Accés a Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartir contactes"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"S\'utilitza per compartir contactes."</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Connexió compartida a Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Accés al missatge"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Missatges de text"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Accés a la SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Utilitza àudio d\'alta qualitat: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Utilitza àudio d\'alta qualitat"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Àudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Àudio HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connectat a l\'àudio del mitjà"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connectat a àudio del telèfon"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connectat al servidor de transferència de fitxers"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Transferència agressiva de Wi-Fi a mòbil"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permet sempre cerca de Wi-Fi en ininerància"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dades mòbils sempre actives"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Acceleració per maquinari per compartir la xarxa"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desactiva el volum absolut"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Activa el so al mateix canal"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versió AVRCP de Bluetooth"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permet les ubicacions simulades"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Inspecció d\'atributs de visualització"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantén les dades mòbils sempre actives, fins i tot quan la Wi‑Fi està activada (per canviar de xarxa ràpidament)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Fes servir l\'acceleració per maquinari per compartir la xarxa, si està disponible"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Voleu permetre la depuració USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"La depuració USB només està indicada per a activitats de desenvolupament. Fes-la servir intercanviar dades entre l\'ordinador i el dispositiu, per instal·lar aplicacions al dispositiu sense rebre notificacions i per llegir dades de registre."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vols revocar l\'accés a la depuració d\'USB dels ordinadors que has autoritzat anteriorment?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correcció del color"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Aquesta funció és experimental i pot afectar el rendiment."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"S\'ha substituït per <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Temps restant aproximat: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> per completar la càrrega"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> aproximadament per esgotar la bateria"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g>; temps restant: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Temps restant aproximat: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Temps restant aproximat segons l\'ús que en fas: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> per completar la càrrega"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Temps restant segons l\'ús que en fas: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g>: <xliff:g id="TIME">^2</xliff:g> aproximadament per esgotar la bateria"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g>; temps restant aproximat segons l\'ús que en fas: <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g>; temps restant: <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g>: <xliff:g id="TIME">^2</xliff:g> per completar la càrrega"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g>: <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconegut"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"S\'està carregant"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"s\'està carregant"</string>
diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml
index 7457308..e4129e3 100644
--- a/packages/SettingsLib/res/values-cs/arrays.xml
+++ b/packages/SettingsLib/res/values-cs/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (výchozí)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Použít systémový výběr (výchozí)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Povolit volitelné kodeky"</item>
-    <item msgid="3304843301758635896">"Zakázat volitelné kodeky"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Použít systémový výběr (výchozí)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Povolit volitelné kodeky"</item>
-    <item msgid="741805482892725657">"Zakázat volitelné kodeky"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Použít systémový výběr (výchozí)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index b0a5ad7..8dd1c32 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Nejste připojeni, protože síť je příliš slabá"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Selhání připojení Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problém s ověřením"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Nelze se připojit"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"K síti <xliff:g id="AP_NAME">%1$s</xliff:g> se nelze připojit"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Zkontrolujte heslo a zkuste to znovu"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Mimo dosah"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Připojení nebude automaticky navázáno"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Nebyl zjištěn žádný přístup k internetu"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Připojeno prostřednictvím %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupné prostřednictvím %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Připojeno, není k dispozici internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Velmi pomalá"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Pomalá"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Střední"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Rychlá"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Velmi rychlá"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Odpojeno"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Odpojování..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Připojování..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Připojeno (žádná média)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Připojeno (bez přístupu ke zprávám)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Připojeno (žádný telefon nebo média)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Připojeno, baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Připojeno (žádný telefon), baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Připojeno (žádná média), baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Připojeno (žádný telefon ani média), baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk médií"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Zvuk telefonu"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonní hovory"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Přenos souborů"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Vstupní zařízení"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Přístup k internetu"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Sdílení kontaktů"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Použít ke sdílení kontaktů"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Sdílení internetového připojení"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Přístup ke zprávám"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Textové zprávy"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Přístup k SIM kartě"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Použít vysokou kvalitu zvuku: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Použít vysokou kvalitu zvuku"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD zvuk: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD zvuk"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Připojeno ke zvukovému médiu"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Připojeno k náhlavní soupravě"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Připojeno k serveru pro přenos dat"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresivní předání z Wi-Fi na mobilní síť"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vždy povolit Wi-Fi roaming"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilní data jsou vždy aktivní"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwarová akcelerace tetheringu"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zakázat absolutní hlasitost"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Povolit vyzvánění v hovorovém pásmu"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verze profilu Bluetooth AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Povolit simulované polohy"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Kontrola atributu zobrazení"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mobilní data budou vždy ponechána aktivní, i když bude aktivní Wi-Fi (za účelem rychlého přepínání sítí)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Pokud je k dispozici hardwarová akceleraci tetheringu, použít ji"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Povolit ladění USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Ladění prostřednictvím rozhraní USB je určeno pouze pro účely vývoje. Použijte je ke kopírování dat mezi počítačem a zařízením, instalaci aplikací do zařízení bez upozornění a čtení dat protokolů."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Zrušit přístup k ladění USB ze všech počítačů, které jste v minulosti autorizovali?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekce barev"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Funkce je experimentální a může mít vliv na výkon."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Přepsáno nastavením <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Zbývá asi <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Plně se nabije za <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zbývající čas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – zbývá přibližně <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zbývá <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Zbývá asi <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Při vašem obvyklém využití zbývá asi <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Plně se nabije za <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zbývající čas: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Při vašem obvyklém využití zbývá <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – zbývá přibližně <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – při vašem obvyklém využití zbývá asi <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – zbývá <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – plně se nabije za <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – plně se nabije za <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Neznámé"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjí se"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"nabíjení"</string>
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index 6c322ed..0e0a456 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (standard)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Brug systemvalg (standard)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Aktivér Optional Codecs"</item>
-    <item msgid="3304843301758635896">"Deaktiver Optional Codecs"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Brug systemvalg (standard)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Aktivér Optional Codecs"</item>
-    <item msgid="741805482892725657">"Deaktiver Optional Codecs"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Brug systemvalg (standard)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 73c7bea..ff47971 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Ingen forbindelse på grund af lav netværkskvalitet"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi-forbindelsesfejl"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problem med godkendelse"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Kan ikke forbinde"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Der kan ikke oprettes forbindelse til \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Tjek adgangskoden, og prøv igen"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Ikke inden for rækkevidde"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Der oprettes ikke automatisk forbindelse"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Ingen internetadgang"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Tilsluttet via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Tilgængelig via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Tilsluttet – intet internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Meget langsom"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Langsom"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Middel"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Hurtig"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Meget hurtig"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Afbrudt"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Afbryder ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Opretter forbindelse..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Tilsluttet (intet medie)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Forbundet (ingen adgang til meddelelse)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Forbundet (ingen telefon eller medier)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Tilsluttet – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Tilsluttet (ingen telefon) – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Tilsluttet (ingen medier) – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Tilsluttet (ingen telefon eller medier) – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medielyd"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefonlyd"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonopkald"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Filoverførsel"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Inputenhed"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetadgang"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Deling af kontaktpersoner"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Brug til deling af kontaktpersoner"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Deling af internetforbindelse"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Adgang til meddelelse"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Sms-beskeder"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-adgang"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Brug lyd i høj kvalitet: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Brug lyd i høj kvalitet"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-lyd: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-lyd"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Forbundet til medielyd"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Forbundet til telefonlyd"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Forbundet til filoverførselsserver"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Tvungen skift fra Wi-Fi til mobildata"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillad altid scanning af Wi-Fi-roaming"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata er altid aktiveret"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwareacceleration ved netdeling"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Deaktiver absolut lydstyrke"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Afspil ringetone via Bluetooth"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"AVRCP-version for Bluetooth"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Tillad imiterede placeringer"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Aktivér visning af attributinspektion"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Hold altid mobildata aktiveret, selv når Wi-Fi er aktiveret (for at skifte hurtigt mellem netværk)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Brug hardwareacceleration ved netdeling, hvis det er muligt"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Vil du tillade USB-fejlretning?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-fejlretning er kun beregnet til udvikling og kan bruges til at kopiere data mellem din computer og enheden, installere apps på enheden uden meddelelser og læse logdata."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vil du ophæve adgangen til USB-fejlfinding for alle computere, du tidligere har godkendt?"</string>
@@ -282,7 +297,7 @@
     <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Aktivér understøttelse af eksperimentelle vinduer i frit format."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Kode til lokal sikkerhedskopi"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Lokale fuldstændige sikkerhedskopieringer er i øjeblikket ikke beskyttet"</string>
-    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tryk for at skifte eller fjerne adgangskoden til fuld lokal sikkerhedskopiering"</string>
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tryk for at skifte eller fjerne adgangskoden til fuld lokal backup"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Ny adgangskode til sikkerhedskopi er angivet"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Ny adgangskode og bekræftelse matcher ikke"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Fejl ved angivelse af adgangskode til sikkerhedskopi"</string>
@@ -308,7 +323,7 @@
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Konvertér…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Allerede filkrypteret"</string>
     <string name="title_convert_fbe" msgid="1263622876196444453">"Konverterer til filbaseret kryptering"</string>
-    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Konvertér datapartitionen til filbaseret kryptering.\nAdvarsel! Alle dine data vil blive slettet.\n Dette er en alfafunktion, og den fungerer muligvis ikke korrekt.\n Tryk på \"Ryd og konvertér…\" for at fortsætte."</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Konvertér datapartitionen til filbaseret kryptering.\nAdvarsel! Alle dine data vil blive fuldstændigt slettet.\n Dette er en alfafunktion, og den fungerer muligvis ikke korrekt.\n Tryk på \"Ryd og konvertér…\" for at fortsætte."</string>
     <string name="button_convert_fbe" msgid="5152671181309826405">"Ryd og konvertér…"</string>
     <string name="picture_color_mode" msgid="4560755008730283695">"Farvetilstand for billeder"</string>
     <string name="picture_color_mode_desc" msgid="1141891467675548590">"Brug sRGB"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korriger farver"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Denne funktion er eksperimentel og kan påvirke ydeevnen."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tilsidesat af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Ca. <xliff:g id="TIME">%1$s</xliff:g> tilbage"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> til det er fuldt opladet"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> tilbage"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Ca. <xliff:g id="TIME">^1</xliff:g> tilbage"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Der er ca. <xliff:g id="TIME">^1</xliff:g> tilbage, alt efter hvordan du bruger enheden"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> til det er fuldt opladet"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> tilbage"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Der er <xliff:g id="TIME">^1</xliff:g> tilbage, alt efter hvordan du bruger enheden"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – ca. <xliff:g id="TIME">^2</xliff:g> tilbage"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – der er ca. <xliff:g id="TIME">^2</xliff:g> tilbage, alt efter hvordan du bruger enheden"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> tilbage"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fuldt opladet"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> til det er fuldt opladet"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Ukendt"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Oplader"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"oplader"</string>
diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml
index 2c441a5..c70d395 100644
--- a/packages/SettingsLib/res/values-de/arrays.xml
+++ b/packages/SettingsLib/res/values-de/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Standard)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Systemauswahl verwenden (Standard)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Optionale Codecs aktivieren"</item>
-    <item msgid="3304843301758635896">"Optionale Codecs deaktivieren"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Systemauswahl verwenden (Standard)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Optionale Codecs aktivieren"</item>
-    <item msgid="741805482892725657">"Optionale Codecs deaktivieren"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Systemauswahl verwenden (Standard)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 60ef680..fda1aa4 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Keine Verbindung aufgrund der geringen Netzwerkqualität"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WLAN-Verbindungsfehler"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Authentifizierungsproblem"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Verbindung nicht möglich"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Keine Verbindung zu \"<xliff:g id="AP_NAME">%1$s</xliff:g>\" möglich"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Prüfe das Passwort und versuch es noch einmal"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Nicht in Reichweite"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Kein automatischer Verbindungsaufbau"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Kein Internetzugriff"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Über %1$s verbunden"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Verfügbar über %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Verbunden, kein Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Sehr langsam"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Langsam"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Mittel"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Schnell"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Sehr schnell"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Nicht verbunden"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Verbindung wird getrennt..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Verbindung wird hergestellt..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Verbunden (außer Audiomedien)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Verbunden (ohne Nachrichtenzugriff)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Verbunden (außer Telefon- und Audiomedien)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Verbunden, Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Verbunden (außer Telefon), Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Verbunden (außer Medienwiedergabe), Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Verbunden (außer Telefon und Medienwiedergabe), Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media-Audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefon-Audio"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonanrufe"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Dateiübertragung"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Eingabegerät"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetzugriff"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktfreigabe"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Für Kontaktfreigabe nutzen"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Freigabe der Internetverbindung"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Nachrichtenzugriff"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"SMS"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Zugriff auf SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Hohe Audioqualität verwenden: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Hohe Audioqualität verwenden"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-Audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Verbunden mit  Audiosystem von Medien"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Verbunden mit Audiosystem des Telefons"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Mit Dateiübertragungsserver verbunden"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressives Handover von WLAN an Mobilfunk"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"WLAN-Roamingsuchen immer zulassen"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile Datennutzung immer aktiviert"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwarebeschleunigung für Tethering"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Maximallautstärke deaktivieren"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"In-Band-Klingeln aktivieren"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-Version"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Simulierte Standorte zulassen"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Inspektion der Anzeigeattribute aktivieren"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Die mobile Datennutzung bleibt auch dann aktiviert, wenn WLAN aktiviert ist. Dies dient einem schnelleren Wechsel zwischen Netzwerken."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Falls verfügbar, Hardwarebeschleunigung für Tethering verwenden"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB-Debugging zulassen?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-Debugging ist nur für Entwicklungszwecke vorgesehen. Damit kannst du Daten zwischen deinem Computer und deinem Gerät kopieren, Apps auf deinem Gerät ohne Benachrichtigung installieren und Protokolldaten lesen."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Zugriff auf USB-Debugging für alle zuvor autorisierten Computer aufheben?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Farbkorrektur"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Hierbei handelt es sich um eine experimentelle Funktion, die sich auf die Leistung auswirken kann."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Außer Kraft gesetzt von \"<xliff:g id="TITLE">%1$s</xliff:g>\""</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Ca. <xliff:g id="TIME">%1$s</xliff:g> übrig"</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_remaining_duration_only_short" msgid="5329694252258605547">"Noch <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ungefähr noch <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – noch <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Ca. <xliff:g id="TIME">^1</xliff:g> übrig"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Noch ca. <xliff:g id="TIME">^1</xliff:g>, basierend auf deiner Nutzung"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> bis zur vollständigen Aufladung"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Noch <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Noch <xliff:g id="TIME">^1</xliff:g>, basierend auf deiner Nutzung"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – ungefähr noch <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – noch ca. <xliff:g id="TIME">^2</xliff:g>, basierend auf deiner Nutzung"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – noch <xliff:g id="TIME">^2</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_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>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> bis vollständig geladen"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Unbekannt"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Wird aufgeladen"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"wird aufgeladen..."</string>
diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml
index 2f86aa7..4783843 100644
--- a/packages/SettingsLib/res/values-el/arrays.xml
+++ b/packages/SettingsLib/res/values-el/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Προεπιλογή)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Χρήση επιλογής συστήματος (Προεπιλογή)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Ενεργοποίηση προαιρετικών κωδικοποιητών"</item>
-    <item msgid="3304843301758635896">"Απενεργοποίηση προαιρετικών κωδικοποιητών"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Χρήση επιλογής συστήματος (Προεπιλογή)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Ενεργοποίηση προαιρετικών κωδικοποιητών"</item>
-    <item msgid="741805482892725657">"Απενεργοποίηση προαιρετικών κωδικοποιητών"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Χρήση επιλογής συστήματος (Προεπιλογή)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index e77e2f4..244af42 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Δεν υπάρχει σύνδεση λόγω χαμηλής ποιότητας δικτύου"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Αποτυχία σύνδεσης Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Πρόβλημα ελέγχου ταυτότητας"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Αδυναμία σύνδεσης"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Δεν είναι δυνατή η σύνδεση στο δίκτυο \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Ελέγξτε τον κωδικό πρόσβασης και δοκιμάστε ξανά"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Εκτός εμβέλειας"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Δεν θα συνδεθεί αυτόματα"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Δεν υπάρχει πρόσβαση στο διαδίκτυο"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Συνδέθηκε μέσω %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Διαθέσιμο μέσω %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Συνδέθηκε, χωρίς διαδίκτυο"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Πολύ αργή"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Αργή"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ΟΚ"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Μέτρια"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Γρήγορη"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Πολύ γρήγορη"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Αποσυνδέθηκε"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Αποσύνδεση..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Σύνδεση..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Συνδεδεμένο (όχι μέσα)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Συνδεδεμένο (χωρίς πρόσβαση μηνύματος)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Συνδεδεμένο (χωρίς τηλέφωνο ή πολυμέσα)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Συνδεδεμένη, μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Συνδεδεμένη (όχι τηλέφωνο), μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Συνδεδεμένη (όχι πολυμέσα), μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Συνδεδεμένη (όχι τηλέφωνο ή πολυμέσα), μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Ήχος πολυμέσων"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Ήχος τηλεφώνου"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Τηλεφωνικές κλήσεις"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Μεταφορά αρχείου"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Συσκευή εισόδου"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Πρόσβαση στο Διαδίκτυο"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Κοινή χρήση επαφών"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Για κοινή χρήση επαφών"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Κοινή χρήση σύνδεσης στο Διαδίκτυο"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Πρόσβαση στο μήνυμα"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Μηνύματα κειμένου"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Πρόσβαση SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Χρήση ήχου υψηλής ποιότητας: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Χρήση ήχου υψηλής ποιότητας"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Ήχος HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Ήχος HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Συνδέθηκε σε ήχο πολυμέσων"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Συνδεδεμένο στον ήχο τηλεφώνου"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Συνδεδεμένο σε διακομιστή μεταφοράς αρχείων"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Επιθ.μεταβ. Wi-Fi σε δίκτυο κιν.τηλ."</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Να επιτρέπεται πάντα η σάρωση Wi-Fi κατά την περιαγωγή"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Πάντα ενεργά δεδομένα κινητής τηλεφωνίας"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Σύνδεση επιτάχυνσης υλικού"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Απενεργοποίηση απόλυτης έντασης"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Ενεργοποίηση κλήσης εντός εύρους"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Έκδοση AVRCP Bluetooth"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Να επιτρέπονται ψευδείς τοποθεσίες"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Ενεργοποίηση του ελέγχου χαρακτηριστικών προβολής"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Τα δεδομένα κινητής τηλεφωνίας να διατηρούνται πάντα ενεργά, ακόμα και όταν είναι ενεργό το Wi-Fi (για γρήγορη εναλλαγή δικτύου)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Χρήση της σύνδεσης επιτάχυνσης υλικού εάν υπάρχει"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Να επιτρέπεται ο εντοπισμός σφαλμάτων USB;"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Ο εντοπισμός σφαλμάτων USB προορίζεται μόνο για σκοπούς προγραμματισμού. Χρησιμοποιήστε τον για αντιγραφή δεδομένων μεταξύ του υπολογιστή και της συσκευής σας, για την εγκατάσταση εφαρμογών στη συσκευή σας χωρίς προειδοποίηση και για την ανάγνωση δεδομένων καταγραφής."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Ανάκληση πρόσβασης στον εντοπισμό σφαλμάτων USB από όλους τους υπολογιστές για τους οποίους είχατε εξουσιοδότηση στο παρελθόν;"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Διόρθωση χρωμάτων"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Αυτή η λειτουργία είναι πειραματική και ενδεχομένως να επηρεάσει τις επιδόσεις."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Αντικαταστάθηκε από <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Απομένουν περίπου <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Απομένουν <xliff:g id="TIME">%1$s</xliff:g> έως την πλήρη φόρτιση"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Απομένει/ουν <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - απομένουν περίπου <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - απομένει/ουν <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Απομένουν περίπου <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Απομένει/ουν περίπου <xliff:g id="TIME">^1</xliff:g> με βάση τη χρήση σας"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Απομένουν <xliff:g id="TIME">^1</xliff:g> έως την πλήρη φόρτιση"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Απομένει/ουν <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Απομένει/ουν <xliff:g id="TIME">^1</xliff:g> με βάση τη χρήση σας"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - απομένουν περίπου <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - Απομένει/ουν περίπου <xliff:g id="TIME">^2</xliff:g> με βάση τη χρήση σας"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - απομένει/ουν <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> για πλήρη φόρτιση"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Άγνωστο"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Φόρτιση"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"φόρτιση"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/arrays.xml b/packages/SettingsLib/res/values-en-rAU/arrays.xml
index 77af30e..c5fe2d9 100644
--- a/packages/SettingsLib/res/values-en-rAU/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rAU/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Use System Selection (Default)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Enable Optional Codecs"</item>
-    <item msgid="3304843301758635896">"Disable Optional Codecs"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Use System Selection (Default)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Enable Optional Codecs"</item>
-    <item msgid="741805482892725657">"Disable Optional Codecs"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Use System Selection (Default)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 1d2a654..09ad05c 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Not connected due to low quality network"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi Connection Failure"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Authentication problem"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Can\'t connect"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Can\'t connect to \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Check password and try again"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Not in range"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Won\'t automatically connect"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"No Internet access"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connected, no Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Very slow"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Slow"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Medium"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Fast"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Very fast"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Disconnected"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Disconnecting…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Connecting…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Connected (no media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connected (no message access)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Connected (no phone or media)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connected (no phone), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connected (no media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connected (no phone or media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Phone audio"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Phone calls"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"File transfer"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Input device"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internet access"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Contact sharing"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Use for contact sharing"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internet connection sharing"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Message Access"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Text messages"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Access"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Use high-quality audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Use high-quality audio"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connected to media audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connected to phone audio"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connected to file-transfer server"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Enable in-band ringing"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Allow mock locations"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Enable view attribute inspection"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Always keep mobile data active, even when Wi‑Fi is active (for fast network switching)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Use tethering hardware acceleration if available"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Allow USB debugging?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB debugging is intended for development purposes only. Use it to copy data between your computer and your device, install apps on your device without notification and read log data."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revoke access to USB debugging from all computers you\'ve previously authorised?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Colour correction"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"About <xliff:g id="TIME">%1$s</xliff:g> left"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> left until fully charged"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – about <xliff:g id="TIME">%2$s</xliff:g> left"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"About <xliff:g id="TIME">^1</xliff:g> left"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"About <xliff:g id="TIME">^1</xliff:g> left based on your usage"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> left until fully charged"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> left"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> left based on your usage"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – about <xliff:g id="TIME">^2</xliff:g> left"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - about <xliff:g id="TIME">^2</xliff:g> left based on your usage"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> left"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> until fully charged"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/arrays.xml b/packages/SettingsLib/res/values-en-rGB/arrays.xml
index 77af30e..c5fe2d9 100644
--- a/packages/SettingsLib/res/values-en-rGB/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rGB/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Use System Selection (Default)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Enable Optional Codecs"</item>
-    <item msgid="3304843301758635896">"Disable Optional Codecs"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Use System Selection (Default)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Enable Optional Codecs"</item>
-    <item msgid="741805482892725657">"Disable Optional Codecs"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Use System Selection (Default)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 1d2a654..09ad05c 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Not connected due to low quality network"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi Connection Failure"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Authentication problem"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Can\'t connect"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Can\'t connect to \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Check password and try again"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Not in range"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Won\'t automatically connect"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"No Internet access"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connected, no Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Very slow"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Slow"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Medium"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Fast"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Very fast"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Disconnected"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Disconnecting…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Connecting…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Connected (no media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connected (no message access)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Connected (no phone or media)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connected (no phone), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connected (no media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connected (no phone or media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Phone audio"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Phone calls"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"File transfer"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Input device"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internet access"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Contact sharing"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Use for contact sharing"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internet connection sharing"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Message Access"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Text messages"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Access"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Use high-quality audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Use high-quality audio"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connected to media audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connected to phone audio"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connected to file-transfer server"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Enable in-band ringing"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Allow mock locations"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Enable view attribute inspection"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Always keep mobile data active, even when Wi‑Fi is active (for fast network switching)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Use tethering hardware acceleration if available"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Allow USB debugging?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB debugging is intended for development purposes only. Use it to copy data between your computer and your device, install apps on your device without notification and read log data."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revoke access to USB debugging from all computers you\'ve previously authorised?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Colour correction"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"About <xliff:g id="TIME">%1$s</xliff:g> left"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> left until fully charged"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – about <xliff:g id="TIME">%2$s</xliff:g> left"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"About <xliff:g id="TIME">^1</xliff:g> left"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"About <xliff:g id="TIME">^1</xliff:g> left based on your usage"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> left until fully charged"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> left"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> left based on your usage"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – about <xliff:g id="TIME">^2</xliff:g> left"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - about <xliff:g id="TIME">^2</xliff:g> left based on your usage"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> left"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> until fully charged"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/arrays.xml b/packages/SettingsLib/res/values-en-rIN/arrays.xml
index 77af30e..c5fe2d9 100644
--- a/packages/SettingsLib/res/values-en-rIN/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rIN/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Use System Selection (Default)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Enable Optional Codecs"</item>
-    <item msgid="3304843301758635896">"Disable Optional Codecs"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Use System Selection (Default)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Enable Optional Codecs"</item>
-    <item msgid="741805482892725657">"Disable Optional Codecs"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Use System Selection (Default)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 1d2a654..09ad05c 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Not connected due to low quality network"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi Connection Failure"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Authentication problem"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Can\'t connect"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Can\'t connect to \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Check password and try again"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Not in range"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Won\'t automatically connect"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"No Internet access"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connected, no Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Very slow"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Slow"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Medium"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Fast"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Very fast"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Disconnected"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Disconnecting…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Connecting…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Connected (no media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connected (no message access)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Connected (no phone or media)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connected (no phone), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connected (no media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connected (no phone or media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Phone audio"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Phone calls"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"File transfer"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Input device"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internet access"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Contact sharing"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Use for contact sharing"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internet connection sharing"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Message Access"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Text messages"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Access"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Use high-quality audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Use high-quality audio"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connected to media audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connected to phone audio"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connected to file-transfer server"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Enable in-band ringing"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Allow mock locations"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Enable view attribute inspection"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Always keep mobile data active, even when Wi‑Fi is active (for fast network switching)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Use tethering hardware acceleration if available"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Allow USB debugging?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB debugging is intended for development purposes only. Use it to copy data between your computer and your device, install apps on your device without notification and read log data."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revoke access to USB debugging from all computers you\'ve previously authorised?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Colour correction"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"About <xliff:g id="TIME">%1$s</xliff:g> left"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> left until fully charged"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – about <xliff:g id="TIME">%2$s</xliff:g> left"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"About <xliff:g id="TIME">^1</xliff:g> left"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"About <xliff:g id="TIME">^1</xliff:g> left based on your usage"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> left until fully charged"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> left"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> left based on your usage"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – about <xliff:g id="TIME">^2</xliff:g> left"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - about <xliff:g id="TIME">^2</xliff:g> left based on your usage"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> left"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> until fully charged"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml
index ef69114..01b9f70 100644
--- a/packages/SettingsLib/res/values-es-rUS/arrays.xml
+++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (predeterminado)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Usar selección del sistema (predeterminado)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Habilitar códecs opcionales"</item>
-    <item msgid="3304843301758635896">"Inhabilitar códecs opcionales"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Usar selección del sistema (predeterminado)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Habilitar códecs opcionales"</item>
-    <item msgid="741805482892725657">"Inhabilitar códecs opcionales"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Usar selección del sistema (predeterminado)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 8d3247d..f2acfe5 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"No se estableció conexión debido a la mala calidad de la red"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Error de conexión Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problema de autenticación"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"No se puede establecer la conexión"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"No se puede establecer conexión con \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Revisa la contraseña y vuelve a intentarlo"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Fuera de alcance"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"No se conectará automáticamente"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"No se detectó acceso a Internet"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conexión a través de %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectado a Wi-Fi, sin conexión a Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Muy lenta"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Aceptar"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Media"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Rápida"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Muy rápida"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Desconectando…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Conectando…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectado (sin audio multimedia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Conectado (sin acceso a mensajes)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectado (sin tel. ni audio multimedia)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Conectado. Batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Conectado (sin teléfono). Batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Conectado (sin audio multimedia). Batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Conectado (sin teléfono ni audio multimedia). Batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimedia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audio del dispositivo"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Llamadas telefónicas"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferencia de archivos"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acceso a Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartir contactos"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Utilizar para compartir contactos"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Compartir conexión a Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acceso a mensajes"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Mensajes de texto"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acceso SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Usar audio de alta calidad: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Usar audio de alta calidad"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio en HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio en HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado al audio multimedia"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado al audio del dispositivo"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado al servidor de transferencia de archivo"</string>
@@ -100,7 +113,7 @@
     <string name="user_guest" msgid="8475274842845401871">"Invitado"</string>
     <string name="unknown" msgid="1592123443519355854">"Desconocido"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"Usuario: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
-    <string name="launch_defaults_some" msgid="313159469856372621">"Hay algunas configuraciones predeterminadas establecidas."</string>
+    <string name="launch_defaults_some" msgid="313159469856372621">"Configuraciones predeterminadas establecidas"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"No hay configuraciones predeterminadas establecidas."</string>
     <string name="tts_settings" msgid="8186971894801348327">"Configuración de texto a voz"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"Salida de texto a voz"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Priorizar cambio de red Wi-Fi a móvil"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir siempre búsquedas de Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móviles siempre activados"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración de hardware de conexión mediante dispositivo portátil"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inhabilitar volumen absoluto"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Habilitar sonido dentro de banda"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versión de AVRCP del Bluetooth"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permitir ubicaciones de prueba"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Habilitar inspección de atributos de vista"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Siempre mantén los datos móviles activos, incluso cuando esté activada la conexión Wi‑Fi (para cambiar de red de forma rápida)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Usar la aceleración de hardware de conexión mediante dispositivo portátil si está disponible"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"¿Permitir depuración por USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"La depuración por USB solo está indicada para actividades de programación. Úsala para copiar datos entre tu computadora y el dispositivo, para instalar aplicaciones en el dispositivo sin recibir notificaciones y para leer datos de registro."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"¿Quieres revocar el acceso a la depuración por USB desde todas la computadoras que autorizaste hasta ahora?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corrección de color"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función es experimental y puede afectar el rendimiento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Reemplazado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Tiempo restante aproximado: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> para completar la carga"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tiempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> (tiempo restante: <xliff:g id="TIME">%2$s</xliff:g>)"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tiempo restante: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Tiempo restante aproximado: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Aproximadamente <xliff:g id="TIME">^1</xliff:g> restantes en función del uso"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> para completar la carga"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tiempo restante: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> restantes en función del uso"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> (tiempo restante: <xliff:g id="TIME">^2</xliff:g>)"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> (aproximadamente <xliff:g id="TIME">^2</xliff:g> restantes en función del uso)"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - Tiempo restante: <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> para completar la carga)"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> (<xliff:g id="TIME">^2</xliff:g> para completar la carga)"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconocido"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"cargando"</string>
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index 53c547d..7cd97fa 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Predeterminada)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Usar preferencia del sistema (predeter.)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Habilitar códecs opcionales"</item>
-    <item msgid="3304843301758635896">"Inhabilitar códecs opcionales"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Usar preferencia del sistema (predeter.)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Habilitar códecs opcionales"</item>
-    <item msgid="741805482892725657">"Inhabilitar códecs opcionales"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Usar preferencia del sistema (predeter.)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 360a754..4a6f12d 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"No conectado debido a la baja calidad de la red"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Error de conexión Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Error de autenticación"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"No se puede establecer conexión"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"No se puede establecer conexión con \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Comprueba la contraseña y vuelve a intentarlo"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Fuera de rango"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"No se establecerá conexión automáticamente"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"No se ha detectado acceso a Internet"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado a través de %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conexión sin Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Muy lenta"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Aceptar"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Media"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Rápida"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Muy rápida"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Desconectando…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Estableciendo conexión…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectado (sin audio multimedia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Conectado (sin acceso a mensajes)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectado (sin teléfono ni multimedia)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Conectado (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Conectado sin teléfono (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Conectado sin audio multimedia (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Conectado sin teléfono ni audio multimedia (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimedia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audio del teléfono"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Llamadas de teléfono"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferencia de archivos"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acceso a Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartir contactos"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Usar para compartir contactos"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Compartir conexión a Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acceso a mensajes"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Mensajes de texto"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acceso a tarjeta SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Usar audio de alta calidad: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Usar audio de alta calidad"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado al audio del medio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado al audio del teléfono"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado con el servidor de transferencia de archivos"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Transferencia agresiva de Wi-Fi a móvil"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir siempre búsquedas de Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móviles siempre activos"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración por hardware para conexión compartida"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inhabilitar volumen absoluto"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Habilitar tono de llamada por Bluetooth"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versión AVRCP del Bluetooth"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permitir ubicaciones simuladas"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Inspección de atributos de vista"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantén los datos móviles siempre activos, aunque la conexión Wi‑Fi esté activada (para cambiar de red rápidamente)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Usar la conexión compartida con aceleración por hardware si está disponible"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"¿Permitir depuración por USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"La depuración por USB solo está indicada para actividades de desarrollo. Puedes utilizarla para intercambiar datos entre el ordenador y el dispositivo, para instalar aplicaciones en el dispositivo sin recibir notificaciones y para leer datos de registro."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"¿Quieres revocar el acceso a la depuración por USB de todos los ordenadores que has autorizado?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corrección de color"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función es experimental y puede afectar al rendimiento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Tiempo restante aproximado: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tiempo restante hasta carga completa: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tiempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - tiempo aproximado restante: <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tiempo restante: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Tiempo restante aproximado: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Tiempo restante aproximado según tu uso: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tiempo restante hasta carga completa: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tiempo restante: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Tiempo restante aproximado según tu uso: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - tiempo aproximado restante: <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> (tiempo restante aproximado según tu uso: <xliff:g id="TIME">^2</xliff:g>)"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - Tiempo restante: <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> para completar la carga"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconocido"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"cargando"</string>
diff --git a/packages/SettingsLib/res/values-et/arrays.xml b/packages/SettingsLib/res/values-et/arrays.xml
index 7766890..91424b2 100644
--- a/packages/SettingsLib/res/values-et/arrays.xml
+++ b/packages/SettingsLib/res/values-et/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (vaikeseade)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Süsteemi valiku kasutamine (vaikeseade)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Lubatakse valikulised kodekid"</item>
-    <item msgid="3304843301758635896">"Keelatakse valikulised kodekid"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Süsteemi valiku kasutamine (vaikeseade)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Lubatakse valikulised kodekid"</item>
-    <item msgid="741805482892725657">"Keelatakse valikulised kodekid"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Süsteemi valiku kasutamine (vaikeseade)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 828b0e2..4a23f67 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Võrgu kehva kvaliteedi tõttu ei ühendatud"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi-ühenduse viga"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Autentimise probleem"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Ei saa ühendada"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Võrguga „<xliff:g id="AP_NAME">%1$s</xliff:g>” ei saa ühendada"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Kontrollige parooli ja proovige uuesti"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Pole vahemikus"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Automaatselt ei ühendata"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Interneti-ühendus puudub"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Ühendatud üksuse %1$s kaudu"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Saadaval üksuse %1$s kaudu"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Ühendatud, Interneti-ühendus puudub"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Väga aeglane"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Aeglane"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Hea"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Keskmine"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Kiire"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Väga kiire"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Ühendus katkestatud"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Ühenduse katkestamine ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Ühendamine ..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Ühendatud (meediat pole)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Ühendatud (sõnumita juurdepääs)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Ühendatud (pole telefoni ega meediat)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Ühendatud, aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Ühendatud (telefoni pole), aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Ühendatud (meediat pole), aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Ühendatud (telefoni ega meediat pole), aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Meedia heli"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefoni heli"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonikõned"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Failiedastus"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Sisendseade"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetti juurdepääs"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontakti jagamine"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Kasutamine kontaktide jagamiseks"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Interneti-ühenduse jagamine"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Juurdepääs sõnumile"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Tekstsõnumid"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-kaardi juurdepääs"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Kasuta kvaliteetset heli: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Kasuta kvaliteetset heli"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-heli: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-heli"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Ühendatud meediumiheliga"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Ühendatud telefoniheliga"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Ühendatud failiedastuse serveriga"</string>
@@ -92,10 +105,10 @@
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Eemaldatud rakendused"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Eemaldatud rakendused ja kasutajad"</string>
     <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB jagamine"</string>
-    <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Kantav tööpunkt"</string>
+    <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Mobiilne kuumkoht"</string>
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Jagamine Bluetoothiga"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Jagamine"</string>
-    <string name="tether_settings_title_all" msgid="8356136101061143841">"Jagam. ja kant. kuumkoht"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"Jagamine / kantav kuumkoht"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"Kõik töörakendused"</string>
     <string name="user_guest" msgid="8475274842845401871">"Külaline"</string>
     <string name="unknown" msgid="1592123443519355854">"Tundmatu"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agress. üleminek WiFi-lt mobiilsidele"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Luba alati WiFi-rändluse skannimine"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiilne andmeside on alati aktiivne"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Jagamise riistvaraline kiirendus"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Keela absoluutne helitugevus"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Luba ribasisene helisemine"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetoothi AVRCP versioon"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Luba võltsasukohti"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Luba kuva atribuudi hindamine"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Hoidke mobiilne andmeside alati aktiivsena, isegi kui WiFi on aktiivne (võrkude kiireks vahetamiseks)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Kasuta võimalusel jagamise riistvaralist kiirendust"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Luban USB silumise?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-silumine on mõeldud ainult arendamiseks. Kasutage seda andmete kopeerimiseks oma arvuti ja seadme vahel, seadmesse rakenduste installimiseks ilma teatisteta ning logiandmete lugemiseks."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Kas tühistada juurdepääs USB silumisele kõikides arvutites, mille olete varem volitanud?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Värvide korrigeerimine"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"See funktsioon on katseline ja võib mõjutada toimivust."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Umbes <xliff:g id="TIME">%1$s</xliff:g> on jäänud"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> täislaadimiseni"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> on jäänud"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – umbes <xliff:g id="TIME">%2$s</xliff:g> on jäänud"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> on jäänud"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Umbes <xliff:g id="TIME">^1</xliff:g> on jäänud"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Teie kasutuse alusel on jäänud ligikaudu <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> täislaadimiseni"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> on jäänud"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Teie kasutuse alusel on jäänud <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – umbes <xliff:g id="TIME">^2</xliff:g> on jäänud"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – teie kasutuse alusel on jäänud ligikaudu <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> on jäänud"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täislaadimiseni"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> täislaadimiseni"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Tundmatu"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Laadimine"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"laadimine"</string>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index 444ffbc..4b8ba15 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (lehenetsia)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Erabili sistema-hautapena (lehenetsia)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Gaitu aukerako kodekak"</item>
-    <item msgid="3304843301758635896">"Desgaitu aukerako kodekak"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Erabili sistema-hautapena (lehenetsia)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Gaitu aukerako kodekak"</item>
-    <item msgid="741805482892725657">"Desgaitu aukerako kodekak"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Erabili sistema-hautapena (lehenetsia)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 92d5ae5..9fd8ad84 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Ez dago konektatuta sarearen kalitate eskasagatik"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Ezin izan da konektatu Wi-Fi sarera"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Autentifikazio-arazoa"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Ezin da konektatu"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Ezin da konektatu \"<xliff:g id="AP_NAME">%1$s</xliff:g>\" sarera"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Egiaztatu pasahitza zuzena dela eta saiatu berriro"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Urrunegi"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Ez da konektatuko automatikoki"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Ezin da konektatu Internetera"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s bidez konektatuta"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s bidez erabilgarri"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Konektatuta, ez dago Interneteko konexiorik"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Oso motela"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Motela"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Ados"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Tartekoa"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Bizkorra"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Oso bizkorra"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Deskonektatuta"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Deskonektatzen…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Konektatzen…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Konektatuta (ez dago euskarririk)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Konektatuta (mezuetarako sarbiderik ez)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Konektatuta (ez dago telef./euskarririk)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Konektatuta. Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Konektatuta (telefonorik gabe). Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Konektatuta (euskarririk gabe). Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Konektatuta (telefono edo euskarririk gabe). Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Euskarriaren audioa"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefonoaren audioa"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefono-deiak"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fitxategi-transferentzia"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Sarrerako gailua"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Interneterako sarbidea"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktuak partekatzea"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Erabili kontaktuak partekatzeko"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Interneteko konexioa partekatzea"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Mezuetarako sarbidea"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Testu-mezuak"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM txartelerako sarbidea"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Erabili kalitate handiko audioa: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Erabili kalitate handiko audioa"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Kalitate handiko audioa: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Kalitate handiko audioa"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Euskarriaren audiora konektatuta"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Telefonoaren audiora konektatuta"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Fitxategi-transferentziako zerbitzarira konektatuta"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Behartu Wi-Fi konexiotik datuenera aldatzera"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Onartu beti ibiltaritzan Wi-Fi sareak bilatzea"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datu mugikorrak beti aktibo"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Konexioa partekatzeko hardwarearen azelerazioa"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desgaitu bolumen absolutua"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Gaitu tonuak audio-kanal berean erreproduzitzeko aukera"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP bertsioa"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Onartu kokapen faltsuak"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Gaitu ikuspegiaren atributuak ikuskatzeko aukera"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantendu mugikorreko datuak beti aktibo, baita Wi-Fi konexioa aktibo dagoenean ere (sarez bizkor aldatu ahal izateko)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Erabilgarri badago, erabili konexioa partekatzeko hardwarearen azelerazioa"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB arazketa onartu?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB arazketa garapen-xedeetarako soilik dago diseinatuta. Erabil ezazu ordenagailuaren eta gailuaren artean datuak kopiatzeko, aplikazioak gailuan jakinarazi gabe instalatzeko eta erregistro-datuak irakurtzeko."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Aurretik baimendutako ordenagailu guztiei USB arazketarako sarbidea baliogabetu nahi diezu?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Kolore-zuzenketa"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Eginbidea esperimentala da eta eragina izan dezake funtzionamenduan."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"<xliff:g id="TIME">%1$s</xliff:g> inguru gelditzen dira"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> falta dira guztiz kargatu arte"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> guztiz kargatu arte"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> inguru gelditzen dira"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"<xliff:g id="TIME">^1</xliff:g> inguru gelditzen dira"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"<xliff:g id="TIME">^1</xliff:g> inguru gelditzen dira, erabileraren arabera"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> falta dira guztiz kargatu arte"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> guztiz kargatu arte"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> gelditzen dira, erabileraren arabera"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> inguru gelditzen dira"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g>: <xliff:g id="TIME">^2</xliff:g> inguru gelditzen dira, erabileraren arabera"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> guztiz kargatu arte"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> guztiz kargatu arte"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Ezezaguna"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Kargatzen"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"kargatzen"</string>
diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml
index b9fa5e4..62b3f19 100644
--- a/packages/SettingsLib/res/values-fa/arrays.xml
+++ b/packages/SettingsLib/res/values-fa/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"‏AVRCP نسخه ۱.۴ (پیش‌فرض)"</item>
-    <item msgid="2089555299377409443">"‏AVRCP نسخه ۱.۵"</item>
-    <item msgid="2895327394279434278">"‏AVRCP نسخه ۱.۶"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"‏avrcp نسخه ۱۴"</item>
-    <item msgid="1913619118958233129">"‏avrcp نسخه ۱۵"</item>
-    <item msgid="7142710449249088270">"‏avrcp نسخه ۱۶"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"استفاده از انتخاب سیستم (پیش‌فرض)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"فعال کردن کدک‌های اختیاری"</item>
-    <item msgid="3304843301758635896">"غیرفعال کردن کدک‌های اختیاری"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"استفاده از انتخاب سیستم (پیش‌فرض)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"فعال کردن کدک‌های اختیاری"</item>
-    <item msgid="741805482892725657">"غیرفعال کردن کدک‌های اختیاری"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"استفاده از انتخاب سیستم (پیش‌فرض)"</item>
     <item msgid="8895532488906185219">"۴۴٫۱ کیلوهرتز"</item>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index b82d1bf..0430592 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"اتصال ناموفق به دلیل شبکه با کیفیت پایین"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"‏اتصال Wi-Fi برقرار نشد"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"مشکل احراز هویت"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"برقراری اتصال ممکن نیست"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"برقراری اتصال به «<xliff:g id="AP_NAME">%1$s</xliff:g>» ممکن نیست"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"گذرواژه را بررسی و دوباره امتحان کنید"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"در محدوده نیست"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"اتصال به‌صورت خودکار انجام نمی‌شود"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"دسترسی به اینترنت وجود ندارد"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"‏متصل از طریق %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"‏در دسترس از طریق %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"متصل، بدون اینترنت"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"بسیار آهسته"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"آهسته"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"تأیید"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"متوسط"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"سریع"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"خیلی سریع"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"اتصال قطع شد"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"در حال قطع اتصال..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"در حال اتصال…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"متصل شد (بدون رسانه)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"متصل (عدم دسترسی به پیام)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"متصل شد (بدون تلفن یا رسانه)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"متصل، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"متصل (بدون تلفن)، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"متصل (بدون رسانه)، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"متصل (بدون تلفن یا رسانه)، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"رسانه صوتی"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"صدای تلفن"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"تماس‌های تلفنی"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"انتقال فایل"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"دستگاه ورودی"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"دسترسی به اینترنت"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"اشتراک‌گذاری مخاطب"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"استفاده برای اشتراک‌گذاری مخاطب"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"اشتراک‌گذاری اتصال اینترنت"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"دسترسی به پیام"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"پیام‌های نوشتاری"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"دسترسی سیم‌کارت"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"استفاده از صوت با کیفیت بالا: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"استفاده از صوت با کیفیت بالا"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"‏صدای HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"‏صدای HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"به رسانه صوتی متصل شد"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"به تلفن صوتی متصل شد"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"به سرور انتقال فایل متصل شد"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"‏Wi‑Fi قوی برای واگذاری به دستگاه همراه"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏اسکن‌های رومینگ Wi‑Fi همیشه مجاز است"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"داده تلفن همراه همیشه فعال باشد"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"شتاب سخت‌افزاری اتصال به اینترنت با تلفن همراه"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"غیرفعال کردن میزان صدای مطلق"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"فعال کردن زنگ زدن درون باندی"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"‏نسخه AVRCP بلوتوث"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"مکان‌های کاذب مجاز هستند"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"فعال کردن نمایش بازبینی ویژگی"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"‏داده سلولی همیشه فعال نگه داشته می‌شود، حتی وقتی Wi-Fi فعال است (برای جابه‌جایی سریع شبکه)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"استفاده از شتاب سخت‌افزاری اتصال به اینترنت با تلفن همراه درصورت دردسترس بودن"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"‏اشکال‌زدایی USB انجام شود؟"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"‏اشکال‌زدایی USB فقط برای اهداف برنامه‌نویسی در نظر گرفته شده است. از آن برای رونوشت‌برداری داده بین رایانه و دستگاهتان، نصب برنامه‌ها در دستگاهتان بدون اعلان و خواندن داده‌های گزارش استفاده کنید."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"‏دسترسی به اشکال‌زدایی USB از تمام رایانه‌هایی که قبلاً مجاز دانسته‌اید لغو شود؟"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"تصحیح رنگ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"این قابلیت آزمایشی است و ممکن است عملکرد را تحت تأثیر قرار دهد."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"توسط <xliff:g id="TITLE">%1$s</xliff:g> لغو شد"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"حدود <xliff:g id="TIME">%1$s</xliff:g> باقی مانده است"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> تا شارژ شدن کامل باقی مانده است"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> باقی مانده"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی مانده است"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> باقی مانده"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"حدود <xliff:g id="TIME">^1</xliff:g> باقی مانده است"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"براساس میزان مصرف شما، <xliff:g id="TIME">^1</xliff:g> باقی‌مانده است"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> تا شارژ شدن کامل باقی مانده است"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> باقی مانده"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"براساس میزان مصرف شما، <xliff:g id="TIME">^1</xliff:g> باقی‌مانده است"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - تقریباً <xliff:g id="TIME">^2</xliff:g> باقی مانده است"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - براساس میزان مصرف شما، <xliff:g id="TIME">^2</xliff:g> باقی‌مانده است"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> مانده تا شارژ کامل"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> مانده تا شارژ کامل"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"ناشناس"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"در حال شارژ شدن"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"درحال شارژ شدن"</string>
diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml
index 7a5f860..1be1b5a 100644
--- a/packages/SettingsLib/res/values-fi/arrays.xml
+++ b/packages/SettingsLib/res/values-fi/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (oletus)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Käytä järjestelmän valintaa (oletus)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Ota valinnaiset koodekit käyttöön"</item>
-    <item msgid="3304843301758635896">"Poista valinnaiset koodekit käytöstä"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Käytä järjestelmän valintaa (oletus)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Ota valinnaiset koodekit käyttöön"</item>
-    <item msgid="741805482892725657">"Poista valinnaiset koodekit käytöstä"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Käytä järjestelmän valintaa (oletus)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 65e87d21..b7b65ad 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Ei yhteyttä – verkko huonolaatuinen"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi-yhteysvirhe"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Todennusvirhe"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Yhdistäminen ei onnistu."</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Yhdistäminen verkkoon <xliff:g id="AP_NAME">%1$s</xliff:g> ei onnistu."</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Tarkista salasana ja yritä uudelleen."</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Ei kantoalueella"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Yhteyttä ei muodosteta automaattisesti"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Ei internetyhteyttä"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Yhdistetty seuraavan kautta: %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Käytettävissä seuraavan kautta: %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Yhdistetty, ei internetyhteyttä."</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Hyvin hidas"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Hidas"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Kohtuullinen"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Nopea"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Hyvin nopea"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Yhteys katkaistu"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Katkaistaan yhteyttä..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Yhdistetään…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Yhdistetty (ei median ääntä)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Yhdistetty (ei MAP)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Yhdistetty (ei puhelimen/median ääntä)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Yhdistetty, akun varaus <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Yhdistetty (ei puhelimen ääntä), akun varaus <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Yhdistetty (ei median ääntä), akun varaus <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Yhdistetty (ei puhelimen tai median ääntä), akun varaustaso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Median ääni"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Puhelimen ääni"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Puhelut"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Tiedostonsiirto"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Syöttölaite"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetyhteys"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Yhteystietojen jakaminen"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Käytä yhteystietojen jakamiseen"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internetyhteyden jakaminen"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"MAP"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Tekstiviestit"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-kortin käyttö"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Käytä korkealaatuista ääntä: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Käytä korkealaatuista ääntä"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-ääni: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-ääni"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Yhdistetty median ääneen"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Yhdistetty puhelimen ääneen"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Yhdistetty tiedostonsiirtopalvelimeen"</string>
@@ -100,7 +113,7 @@
     <string name="user_guest" msgid="8475274842845401871">"Vieras"</string>
     <string name="unknown" msgid="1592123443519355854">"Tuntematon"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"Käyttäjä: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
-    <string name="launch_defaults_some" msgid="313159469856372621">"Joitakin oletuksia on asetettu."</string>
+    <string name="launch_defaults_some" msgid="313159469856372621">"Joitakin oletuksia on asetettu"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"Oletuksia ei asetettu."</string>
     <string name="tts_settings" msgid="8186971894801348327">"Tekstistä puheeksi -asetukset"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"Tekstistä puheeksi -toisto"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Vaihda herkästi Wi-Fi mobiiliyhteyteen"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Salli Wi-Fi-verkkovierailuskannaus aina"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiilidata aina käytössä"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Laitteistokiihdytyksen yhteyden jakaminen"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Poista yleinen äänenvoimakkuuden säätö käytöstä"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Ota käyttöön kaistalla soitto"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetoothin AVRCP-versio"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Salli sijaintien imitointi"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Ota attribuuttinäkymän tarkistus käyttöön"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Pidä mobiilidata aina käytössä, vaikka Wi-Fi olisi aktiivinen. Tämä mahdollistaa nopeamman vaihtelun verkkojen välillä."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Käytä laitteistokiihdytyksen yhteyden jakamista, jos se on käytettävissä"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Sallitaanko USB-vianetsintä?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-vianetsintä on tarkoitettu vain kehittäjien käyttöön. Sen avulla voidaan kopioida tietoja tietokoneesi ja laitteesi välillä, asentaa laitteeseesi sovelluksia ilmoittamatta siitä sinulle ja lukea lokitietoja."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Haluatko peruuttaa USB-vianetsinnän käyttöoikeuden kaikilta tietokoneilta, joille olet antanut luvan aiemmin?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Värikorjaus"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Tämä ominaisuus on kokeellinen ja voi vaikuttaa suorituskykyyn."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tämän ohittaa <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Noin <xliff:g id="TIME">%1$s</xliff:g> jäljellä"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> kunnes täynnä"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> jäljellä"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – noin <xliff:g id="TIME">%2$s</xliff:g> jäljellä"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> jäljellä"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Noin <xliff:g id="TIME">^1</xliff:g> jäljellä"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Noin <xliff:g id="TIME">^1</xliff:g> jäljellä käytön perusteella"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> kunnes täynnä"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> jäljellä"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> jäljellä käytön perusteella"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – noin <xliff:g id="TIME">^2</xliff:g> jäljellä"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – noin <xliff:g id="TIME">^2</xliff:g> jäljellä käytön perusteella"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> jäljellä"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täyteen lataukseen"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> täyteen lataukseen"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Tuntematon"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Ladataan"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ladataan"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
index 29348c9..31ea851 100644
--- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (par défaut)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Utiliser sélect. du système (par défaut)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Activer les codecs optionnels"</item>
-    <item msgid="3304843301758635896">"Désactiver les codecs optionnels"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Utiliser sélect. du système (par défaut)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Activer les codecs optionnels"</item>
-    <item msgid="741805482892725657">"Désactiver les codecs optionnels"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Utiliser sélect. du système (par défaut)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 4bbd116..e409fcc 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Non connecté en raison de la mauvaise qualité du réseau"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Échec de connexion Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problème d\'authentification"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Connexion impossible"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Impossible de se connecter à « <xliff:g id="AP_NAME">%1$s</xliff:g> »"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Vérifiez le mot de passe et réessayez"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Hors de portée"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Reconnexion automatique impossible"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Aucun accès à Internet"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Connecté par %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Accessible par %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connecté, aucun accès à Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Très lente"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lente"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Moyenne"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Élevée"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Très rapide"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Déconnecté"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Déconnexion…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Connexion en cours…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Connecté (sans audio contenu mutimédia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connecté (sans accès aux messages)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Connecté (sans audio tel./multimédia)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connecté. Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connecté (sans téléphone). Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connecté (sans média). Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connecté (sans téléphone ni média). Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Paramètres audio du support"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Paramètres audio du téléphone"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Appels téléphoniques"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfert de fichier"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Périphérique d\'entrée"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Accès Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Partage de contact"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Utiliser pour le partage de contacts"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Partage de connexion Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Accès aux messages"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Messages texte"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Accès à la carte SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Utiliser l\'audio de haute qualité : <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Utiliser l\'audio de haute qualité"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio HD : <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connecté aux paramètres audio du média"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connecté à l\'audio du téléphone"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connexion au serveur de transfert de fichiers"</string>
@@ -93,7 +106,7 @@
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Applications et utilisateurs supprimés"</string>
     <string name="tether_settings_title_usb" msgid="6688416425801386511">"Partage de connexion par USB"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Point d\'accès Wi-Fi mobile"</string>
-    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Par Bluetooth"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Partage connexion Bluetooth"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Partage de connexion"</string>
     <string name="tether_settings_title_all" msgid="8356136101061143841">"Partage de connexion"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"Toutes les applis profess."</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Passage forcé du Wi-Fi aux données cell."</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Toujours autoriser la détection de réseaux Wi-Fi en itinérance"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Données cellulaires toujours actives"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Accélération matérielle pour le partage de connexion"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Désactiver le volume absolu"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Activer la signalisation intra-bande"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Version du profil Bluetooth AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Autoriser les positions fictives"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Activer l\'inspection d\'attribut d\'affichage"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Toujours garder les données cellulaires actives, même lorsque le Wi-Fi est activé (pour la commutation rapide entre les réseaux)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Utiliser l\'accélération matérielle du partage de connexion si possible"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Autoriser le débogage USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Le débogage USB est conçu uniquement pour le développement. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applications sur votre appareil sans notification et lire les données de journal."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Voulez-vous vraiment désactiver l\'accès au débogage USB de tous les ordinateurs précédemment autorisés?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correction des couleurs"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut affecter les performances."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> jusqu\'à la charge complète"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant : <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> : il reste environ <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Il reste environ <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Il reste environ <xliff:g id="TIME">^1</xliff:g> en fonction de votre usage"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> jusqu\'à la charge complète"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant : <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Il reste <xliff:g id="TIME">^1</xliff:g> en fonction de votre usage"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> : il reste environ <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> : il reste environ <xliff:g id="TIME">^2</xliff:g> en fonction de votre usage"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – Temps restant : <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> : <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la charge complète"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> : <xliff:g id="TIME">^2</xliff:g> jusqu\'à la charge complète"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Inconnu"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Charge en cours…"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"en cours de charge"</string>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index 1c3605e..0576a53 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (par défaut)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Utiliser sélection système (par défaut)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Activer les codecs facultatifs"</item>
-    <item msgid="3304843301758635896">"Désactiver les codecs facultatifs"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Utiliser sélection système (par défaut)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Activer les codecs facultatifs"</item>
-    <item msgid="741805482892725657">"Désactiver les codecs facultatifs"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Utiliser sélection système (par défaut)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 96a73ff..48fcb38 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -28,15 +28,24 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Non connecté en raison de la faible qualité du réseau"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Échec de la connexion Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problème d\'authentification."</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Connexion impossible"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Impossible de se connecter au réseau \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Vérifiez le mot de passe et réessayez"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Hors de portée"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Reconnexion automatique impossible"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Aucun accès à Internet"</string>
-    <string name="saved_network" msgid="4352716707126620811">"Enregistré par : <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="saved_network" msgid="4352716707126620811">"Enregistré lors de : <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"Connecté automatiquement via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Connecté automatiquement via un fournisseur d\'évaluation de l\'état du réseau"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Connecté via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connecté, aucun accès à Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Très lente"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lente"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Correct"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Moyenne"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Élevée"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Très élevée"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Déconnecté"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Déconnexion…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Connexion…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Connecté (sans audio contenu mutimédia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connecté (sans accès aux messages)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Connecté (sans audio tel./multimédia)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connecté, batterie à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connecté (aucun téléphone), batterie à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connecté (aucun contenu multimédia), batterie à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connecté (aucun téléphone ni contenu multimédia), batterie à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Multimédia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Appels et notifications"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Appels téléphoniques"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfert de fichier"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Périphérique d\'entrée"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Accès Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Partage de contacts"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Utiliser pour le partage de contacts"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Partage de connexion Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Accès aux messages"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"SMS"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Accès à la carte SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Utiliser le codec audio haute qualité : <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Utiliser un codec audio haute qualité"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio HD : <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connecté aux paramètres audio du média"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connecté aux paramètres audio du téléphone"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connexion au serveur de transfert de fichiers"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Passage forcé Wi-Fi vers données mobiles"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Toujours autoriser la détection de réseaux Wi-Fi en itinérance"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Données mobiles toujours actives"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Accélération matérielle pour le partage de connexion"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Désactiver le volume absolu"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Activer la signalisation intra-bande"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Version Bluetooth AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Autoriser les positions fictives"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Activer inspect. attribut affich."</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Maintenir l\'état actif des données mobiles, même lorsque le Wi‑Fi est actif (pour changer rapidement de réseau)"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Utiliser l\'accélération matérielle pour le partage de connexion, si disponible"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Autoriser le débogage USB ?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Le débogage USB est conçu uniquement pour le développement. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applications sur votre appareil sans notification et lire les données de journal."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Voulez-vous vraiment désactiver l\'accès au débogage USB de tous les ordinateurs précédemment autorisés ?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correction couleur"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut affecter les performances."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> avant charge complète"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant : <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - encore environ <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Il reste environ <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Temps restant en fonction de votre utilisation : environ <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> avant charge complète"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant : <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Temps restant en fonction de votre utilisation : <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - encore environ <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – Temps restant en fonction de votre utilisation : environ <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – Temps restant : <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la charge complète"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> jusqu\'à la charge complète"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Inconnu"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Batterie en charge"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"chargement…"</string>
@@ -352,8 +370,8 @@
     <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Petit"</string>
     <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Par défaut"</string>
     <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grand"</string>
-    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Plus grand"</string>
-    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Le plus grand"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Très grand"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Extrêmement grand"</string>
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personnalisé (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Aide et commentaires"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml
index 1bfbbdf..c716dce 100644
--- a/packages/SettingsLib/res/values-gl/arrays.xml
+++ b/packages/SettingsLib/res/values-gl/arrays.xml
@@ -22,7 +22,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wifi_status">
     <item msgid="1922181315419294640"></item>
-    <item msgid="8934131797783724664">"Buscando..."</item>
+    <item msgid="8934131797783724664">"Explorando..."</item>
     <item msgid="8513729475867537913">"Conectando..."</item>
     <item msgid="515055375277271756">"Autenticando…"</item>
     <item msgid="1943354004029184381">"Obtendo enderezo IP..."</item>
@@ -36,7 +36,7 @@
   </string-array>
   <string-array name="wifi_status_with_ssid">
     <item msgid="7714855332363650812"></item>
-    <item msgid="8878186979715711006">"Buscando..."</item>
+    <item msgid="8878186979715711006">"Explorando..."</item>
     <item msgid="355508996603873860">"Conectando con <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
     <item msgid="554971459996405634">"Autenticando con <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
     <item msgid="7928343808033020343">"Obtendo enderezo IP de <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (predeterminado)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Usar selección sistema (predeterminado)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Activar códecs opcionais"</item>
-    <item msgid="3304843301758635896">"Desactivar códecs opcionais"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Usa selección sistema (predeterminado)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Activa os códecs opcionais"</item>
-    <item msgid="741805482892725657">"Desactiva os códecs opcionais"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Usar selección sistema (predeterminado)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index cc46efd..fe91f40 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Non se estableceu conexión porque a rede é de baixa calidade"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Erro na conexión wifi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problema de autenticación"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Non se pode establecer conexión"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Non se pode establecer conexión coa aplicación <xliff:g id="AP_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Comproba o contrasinal e téntao de novo"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Non está dentro da zona de cobertura"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Non se conectará automaticamente"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Non hai acceso a Internet"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado a través de %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Dispoñible a través de %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectado, pero sen Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Moi lenta"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Aceptar"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Media"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Rápida"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Moi rápida"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Desconectando..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Conectando..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectado (sen ficheiros multimedia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Conectado (sen acceso ás mensaxes)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectado (ningún teléfono nin soporte)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Dispositivo conectado. Nivel da batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Dispositivo conectado (sen teléfono). Nivel da batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Dispositivo conectado (sen audio multimedia). Nivel da batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Dispositivo conectado (sen teléfono nin audio multimedia). Nivel da batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimedia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audio do teléfono"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Chamadas telefónicas"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferencia de ficheiros"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acceso a Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartir contactos"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Utilizar para compartir contactos"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Uso compartido da conexión a Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acceso ás mensaxes"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Mensaxes de texto"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acceso á SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Usar audio de alta calidade: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Usar audio de alta calidade"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio en HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio en HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado ao audio multimedia"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado ao audio do teléfono"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado ao servidor de transferencia de ficheiros"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Transferencia agresiva de wifi a móbil"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir sempre buscas de itinerancia da wifi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móbiles sempre activados"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración de hardware para conexión compartida"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desactivar volume absoluto"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Activar a función de soar na mesma banda"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versión AVRCP de Bluetooth"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permite localizacións falsas"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Activar a inspección de atributos de visualización"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantén sempre os datos móbiles activos, aínda que a wifi estea activada (para un rápido cambio de rede)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Se está dispoñible, úsase a aceleración de hardware para conexión compartida"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Queres permitir a depuración USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"A depuración de erros USB está deseñada unicamente para fins de programación. Utilízaa para copiar datos entre o ordenador e o dispositivo, instalar aplicacións no dispositivo sen enviar notificacións e ler os datos do rexistro."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Queres revogar o acceso á depuración USB desde todos os ordenadores que autorizaches previamente?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corrección da cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función é experimental e pode afectar ao rendemento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Tempo que queda aproximadamente: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tempo que queda ata cargar de todo: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> (tempo restante aproximado: <xliff:g id="TIME">%2$s</xliff:g>)"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> (tempo restante: <xliff:g id="TIME">%2$s</xliff:g>)"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Tempo que queda aproximadamente: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Tempo restante aproximado en función do uso: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tempo que queda ata cargar de todo: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tempo restante: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Tempo restante en función do uso: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> (tempo restante aproximado: <xliff:g id="TIME">^2</xliff:g>)"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - Tempo restante aproximado en función do uso: <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> (tempo restante: <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ata completar a carga"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g>)"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> ata completar a carga"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> (<xliff:g id="TIME">^2</xliff:g>)"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Descoñecido"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"cargando"</string>
diff --git a/packages/SettingsLib/res/values-gu/arrays.xml b/packages/SettingsLib/res/values-gu/arrays.xml
index 1fc1d7c..45bd6ab 100644
--- a/packages/SettingsLib/res/values-gu/arrays.xml
+++ b/packages/SettingsLib/res/values-gu/arrays.xml
@@ -50,44 +50,30 @@
   </string-array>
   <string-array name="hdcp_checking_titles">
     <item msgid="441827799230089869">"ક્યારેય તપાસશો નહીં"</item>
-    <item msgid="6042769699089883931">"ફક્ત DRM સામગ્રી માટે તપાસો"</item>
+    <item msgid="6042769699089883931">"ફક્ત DRM કન્ટેન્ટ માટે તપાસો"</item>
     <item msgid="9174900380056846820">"હંમેશાં તપાસો"</item>
   </string-array>
   <string-array name="hdcp_checking_summaries">
     <item msgid="505558545611516707">"HDCP તપાસનો ક્યારેય ઉપયોગ કરશો નહીં"</item>
-    <item msgid="3878793616631049349">"ફક્ત DRM સામગ્રી માટે HDCP તપાસનો ઉપયોગ કરો"</item>
+    <item msgid="3878793616631049349">"ફક્ત DRM કન્ટેન્ટ માટે HDCP તપાસનો ઉપયોગ કરો"</item>
     <item msgid="45075631231212732">"હંમેશા HDCP તપાસનો ઉપયોગ કરો"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (ડિફૉલ્ટ)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"સિસ્ટમ પસંદગીનો ઉપયોગ કરો (ડિફૉલ્ટ)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"વૈકલ્પિક કોડેક સક્ષમ કરો"</item>
-    <item msgid="3304843301758635896">"વૈકલ્પિક કોડેક અક્ષમ કરો"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"સિસ્ટમ પસંદગીનો ઉપયોગ કરો (ડિફૉલ્ટ)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"વૈકલ્પિક કોડેક સક્ષમ કરો"</item>
-    <item msgid="741805482892725657">"વૈકલ્પિક કોડેક અક્ષમ કરો"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"સિસ્ટમ પસંદગીનો ઉપયોગ કરો (ડિફૉલ્ટ)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
@@ -238,7 +224,7 @@
   </string-array>
   <string-array name="app_process_limit_entries">
     <item msgid="3401625457385943795">"માનક સીમા"</item>
-    <item msgid="4071574792028999443">"કોઈ પૃષ્ઠભૂમિ પ્રક્રિયાઓ નથી"</item>
+    <item msgid="4071574792028999443">"કોઈ બૅકગ્રાઉન્ડ પ્રક્રિયાઓ નથી"</item>
     <item msgid="4810006996171705398">"સૌથી વધુ 1 પ્રક્રિયા"</item>
     <item msgid="8586370216857360863">"સૌથી વધુ 2 પ્રક્રિયા"</item>
     <item msgid="836593137872605381">"વધુમાં વધુ 3 પ્રક્રિયાઓ"</item>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index ac755ea..3457cc7 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"ઓછી ગુણવત્તાવાળા નેટવર્કના લીધે કનેક્ટ થયું નથી"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi કનેક્શન નિષ્ફળ"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"પ્રમાણીકરણ સમસ્યા"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"કનેક્ટ કરી શકાતું નથી"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' સાથે કનેક્ટ કરી શકાતું નથી"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"પાસવર્ડ તપાસો અને ફરી પ્રયાસ કરો"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"રેન્જમાં નથી"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"આપમેળે કનેક્ટ કરશે નહીં"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"કોઈ ઇન્ટરનેટ ઍક્સેસ નથી"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s દ્વારા કનેક્ટ થયેલ"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s દ્વારા ઉપલબ્ધ"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"કનેક્ટ કર્યું, કોઈ ઇન્ટરનેટ નથી"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"ખૂબ જ ધીમી"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"ધીમી"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ઓકે"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"મધ્યમ"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"ઝડપી"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"ખૂબ ઝડપી"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"ડિસ્કનેક્ટ કર્યું"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"ડિસ્કનેક્ટ થઈ રહ્યું છે..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"કનેક્ટ થઈ રહ્યું છે…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"કનેક્ટ કર્યું (મીડિયા નથી)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"કનેક્ટ કર્યું (કોઇ સંદેશ ઍક્સેસ નથી)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"કનેક્ટ કરેલ (કોઈ ફોન અથવા મીડિયા નથી)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"કનેક્ટ કરેલ, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"કનેક્ટ કરેલ (કોઈ ફોન નથી), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"કનેક્ટ કરેલ (કોઈ મીડિયા નથી), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"કનેક્ટ કરેલ (કોઈ ફોન અથવા મીડિયા નથી), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"મીડિયા ઑડિઓ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ફોન ઑડિઓ"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ફોન કૉલ"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ફાઇલ સ્થાનાંતરણ"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ઇનપુટ ઉપકરણ"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ઇન્ટરનેટ ઍક્સેસ"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"સંપર્ક શેરિંગ"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"સંપર્ક શેરિંગ માટે ઉપયોગ કરો"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ઇન્ટરનેટ કનેક્શન શેરિંગ"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"સંદેશ ઍક્સેસ"</string>
-    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM ઍક્સેસ"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ઉચ્ચ ગુણવત્તાવાળા ઑડિયોનો ઉપયોગ કરો: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ઉચ્ચ ગુણવત્તાવાળા ઑડિયોનો ઉપયોગ કરો"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"ટેક્સ્ટ સંદેશા"</string>
+    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"સિમ ઍક્સેસ"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ઑડિઓ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ઑડિઓ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"મીડિયા ઑડિઓ સાથે કનેક્ટ કર્યુ"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ફોન ઑડિઓ સાથે કનેક્ટ થયાં"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ફાઇલ સ્થાનાંતરણ સેવાથી કનેક્ટ થયાં"</string>
@@ -69,17 +82,17 @@
     <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1561383706411975199">"ઉપકરણ સાથે સ્થાનિક ઇન્ટરનેટ કનેક્શન શેર કરે છે"</string>
     <string name="bluetooth_pan_profile_summary_use_for" msgid="5664884523822068653">"ઇન્ટરનેટ ઍક્સેસ માટે ઉપયોગ કરો"</string>
     <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"નકશા માટે વાપરો"</string>
-    <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"SIM ઍક્સેસ માટે ઉપયોગ કરો"</string>
+    <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"સિમ ઍક્સેસ માટે ઉપયોગ કરો"</string>
     <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"મીડિયા ઑડિઓ માટે ઉપયોગ કરો"</string>
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ફોન ઑડિઓ માટે ઉપયોગ કરો"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ફાઇલ સ્થાનાંતર માટે ઉપયોગ કરો"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ઇનપુટ માટે ઉપયોગ કરો"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"જોડી"</string>
-    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"જોડી કરો"</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"જોડાણ બનાવો"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"રદ કરો"</string>
-    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"જોડી કરવી એ કનેક્ટ કરેલ હોય ત્યારે તમારા સંપર્કો અને કૉલ ઇતિહાસની અ‍ૅક્સેસ આપે છે."</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"એ કનેક્ટ કરેલ હોય ત્યારે જોડાણ બનાવવાથી તમારા સંપર્કો અને કૉલ ઇતિહાસનો અ‍ૅક્સેસ મળે છે."</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> સાથે જોડી કરી શક્યાં નહીં."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"એક ખોટા PIN અથવા પાસકીને કારણે <xliff:g id="DEVICE_NAME">%1$s</xliff:g> સાથે જોડી બનાવી શકાઈ નથી."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"એક ખોટા પિન અથવા પાસકીને કારણે <xliff:g id="DEVICE_NAME">%1$s</xliff:g> સાથે જોડી બનાવી શકાઈ નથી."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> સાથે સંચાર કરી શકાતો નથી."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> દ્વારા જોડી કરવાનું નકાર્યું."</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi બંધ."</string>
@@ -92,10 +105,10 @@
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"દૂર કરેલી ઍપ્લિકેશનો"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"દૂર કરેલી ઍપ્લિકેશનો અને વપરાશકર્તાઓ"</string>
     <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB ટિથરિંગ"</string>
-    <string name="tether_settings_title_wifi" msgid="3277144155960302049">"પોર્ટેબલ હોટસ્પોટ"</string>
-    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetooth ટિથરિંગ"</string>
+    <string name="tether_settings_title_wifi" msgid="3277144155960302049">"પોર્ટેબલ હૉટસ્પૉટ"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"બ્લૂટૂથ ટિથરિંગ"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"ટિથરિંગ"</string>
-    <string name="tether_settings_title_all" msgid="8356136101061143841">"ટિથરિંગ અને પોર્ટેબલ હોટસ્પોટ"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"ટિથરિંગ અને પોર્ટેબલ હૉટસ્પૉટ"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"તમામ કાર્ય અ‍ૅપ્લિકેશનો"</string>
     <string name="user_guest" msgid="8475274842845401871">"અતિથિ"</string>
     <string name="unknown" msgid="1592123443519355854">"અજાણ્યું"</string>
@@ -156,10 +169,10 @@
     <string name="clear_adb_keys" msgid="4038889221503122743">"USB ડીબગિંગ પ્રમાણીકરણોને રદબાતલ કરો"</string>
     <string name="bugreport_in_power" msgid="7923901846375587241">"બગ રિપોર્ટ શોર્ટકટ"</string>
     <string name="bugreport_in_power_summary" msgid="1778455732762984579">"બગ રિપોર્ટ લેવા માટે પાવર મેનૂમાં એક બટન બતાવો"</string>
-    <string name="keep_screen_on" msgid="1146389631208760344">"જાગૃત રહો"</string>
+    <string name="keep_screen_on" msgid="1146389631208760344">"સક્રિય રાખો"</string>
     <string name="keep_screen_on_summary" msgid="2173114350754293009">"ચાર્જિંગ દરમિયાન સ્ક્રીન ક્યારેય નિષ્ક્રિય થશે નહીં"</string>
-    <string name="bt_hci_snoop_log" msgid="3340699311158865670">"Bluetooth HCI સ્નૂપ લૉગ સક્ષમ કરો"</string>
-    <string name="bt_hci_snoop_log_summary" msgid="730247028210113851">"ફાઇલમાં તમામ Bluetooth HCI પૅકેટ્સ કેપ્ચર કરો"</string>
+    <string name="bt_hci_snoop_log" msgid="3340699311158865670">"બ્લૂટૂથ HCI સ્નૂપ લૉગ સક્ષમ કરો"</string>
+    <string name="bt_hci_snoop_log_summary" msgid="730247028210113851">"ફાઇલમાં તમામ બ્લૂટૂથ HCI પૅકેટ્સ કેપ્ચર કરો"</string>
     <string name="oem_unlock_enable" msgid="6040763321967327691">"OEM અનલૉકિંગ"</string>
     <string name="oem_unlock_enable_summary" msgid="4720281828891618376">"બુટલોડર અનલૉક કરવાની મંજૂરી આપો"</string>
     <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM ને અનલૉક કરવાની મંજૂરી આપીએ?"</string>
@@ -168,30 +181,31 @@
     <string name="mock_location_app_not_set" msgid="809543285495344223">"કોઈ મોક સ્થાન ઍપ્લિકેશન સેટ કરાયેલ નથી"</string>
     <string name="mock_location_app_set" msgid="8966420655295102685">"મોક સ્થાન ઍપ્લિકેશન: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="debug_networking_category" msgid="7044075693643009662">"નેટવર્કિંગ"</string>
-    <string name="wifi_display_certification" msgid="8611569543791307533">"બિનતારી પ્રદર્શન પ્રમાણન"</string>
-    <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi-Fi વર્બોઝ લૉગિંગ સક્ષમ કરો"</string>
+    <string name="wifi_display_certification" msgid="8611569543791307533">"વાયરલેસ ડિસ્પ્લે પ્રમાણન"</string>
+    <string name="wifi_verbose_logging" msgid="4203729756047242344">"વાઇ-ફાઇ વર્બોઝ લૉગિંગ સક્ષમ કરો"</string>
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"સશક્ત Wi‑Fiથી મોબાઇલ પર હૅન્ડઓવર"</string>
-    <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"હંમેશા Wi‑Fi રોમ સ્કૅન્સને મંજૂરી આપો"</string>
+    <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"હંમેશા વાઇ-ફાઇ રોમ સ્કૅન્સને મંજૂરી આપો"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"મોબાઇલ ડેટા હંમેશાં સક્રિય"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ટિથરિંગ માટે હાર્ડવેર ગતિવૃદ્ધિ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ચોક્કસ વૉલ્યૂમને અક્ષમ કરો"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"બેંડમાં રિંગ કરવાનું સક્ષમ કરો"</string>
-    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP સંસ્કરણ"</string>
-    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP સંસ્કરણ પસંદ કરો"</string>
-    <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth ઑડિઓ કોડેક"</string>
-    <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth ઑડિઓ LDAC કોડેક પસંદ કરો"</string>
-    <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth ઑડિઓ નમૂના દર"</string>
-    <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5628790207448471613">"Bluetooth ઑડિઓ LDAC કોડેક પસંદ કરો:\nનમૂના દર"</string>
-    <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="2099645202720164141">"નમૂના દીઠ Bluetooth ઑડિઓ બિટ"</string>
-    <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4546131401358681321">"Bluetooth ઑડિઓ કોડેક પસંદ કરો:\nનમૂના દીઠ બિટ"</string>
-    <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"Bluetooth ઑડિઓ ચેનલ મોડ"</string>
-    <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="9133545781346216071">"Bluetooth ઑડિઓ કોડેક પસંદ કરો:\nચૅનલ મોડ"</string>
-    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth ઑડિઓ LDAC કોડેક: પ્લેબૅક ગુણવત્તા"</string>
-    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Bluetooth ઑડિઓ LDAC કોડેક પસંદ કરો:\nપ્લેબૅક ગુણવત્તા"</string>
+    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"બ્લૂટૂથ AVRCP સંસ્કરણ"</string>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"બ્લૂટૂથ AVRCP સંસ્કરણ પસંદ કરો"</string>
+    <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"બ્લૂટૂથ ઑડિઓ કોડેક"</string>
+    <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"બ્લૂટૂથ ઑડિઓ LDAC કોડેક પસંદ કરો"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"બ્લૂટૂથ ઑડિઓ નમૂના દર"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5628790207448471613">"બ્લૂટૂથ ઑડિઓ LDAC કોડેક પસંદ કરો:\nનમૂના દર"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="2099645202720164141">"નમૂના દીઠ બ્લૂટૂથ ઑડિઓ બિટ"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4546131401358681321">"બ્લૂટૂથ ઑડિઓ કોડેક પસંદ કરો:\nનમૂના દીઠ બિટ"</string>
+    <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"બ્લૂટૂથ ઑડિઓ ચેનલ મોડ"</string>
+    <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="9133545781346216071">"બ્લૂટૂથ ઑડિઓ કોડેક પસંદ કરો:\nચૅનલ મોડ"</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"બ્લૂટૂથ ઑડિઓ LDAC કોડેક: પ્લેબૅક ગુણવત્તા"</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"બ્લૂટૂથ ઑડિઓ LDAC કોડેક પસંદ કરો:\nપ્લેબૅક ગુણવત્તા"</string>
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"સ્ટ્રીમિંગ: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"વાયરલેસ ડિસ્પ્લે પ્રમાણપત્ર માટેના વિકલ્પો બતાવો"</string>
-    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi લોગિંગ સ્તર વધારો, Wi‑Fi પીકરમાં SSID RSSI દીઠ બતાવો"</string>
-    <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"જ્યારે સક્ષમ કરેલ હોય, ત્યારે Wi‑Fi સિગ્નલ નબળું હોવા પર, Wi-Fi વધુ ઝડપથી ડેટા કનેક્શનને મોબાઇલ પર મોકલશે"</string>
-    <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ઇન્ટરફેસ પર હાજર ડેટા ટ્રાફિકના પ્રમાણનાં આધારે Wi‑Fi રોમ સ્કૅન્સને મંજૂરી આપો/નામંજૂર કરો"</string>
+    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"વાઇ-ફાઇ લોગિંગ સ્તર વધારો, વાઇ-ફાઇ પીકરમાં SSID RSSI દીઠ બતાવો"</string>
+    <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"જ્યારે સક્ષમ કરેલ હોય, ત્યારે વાઇ-ફાઇ સિગ્નલ નબળું હોવા પર, વાઇ-ફાઇ વધુ ઝડપથી ડેટા કનેક્શનને મોબાઇલ પર મોકલશે"</string>
+    <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ઇન્ટરફેસ પર હાજર ડેટા ટ્રાફિકના પ્રમાણનાં આધારે વાઇ-ફાઇ રોમ સ્કૅન્સને મંજૂરી આપો/નામંજૂર કરો"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"લોગર બફર કદ"</string>
     <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"લૉગ દીઠ લૉગર કદ બફર પસંદ કરો"</string>
     <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"લૉગર નિરંતર સ્ટોરેજ સાફ કરીએ?"</string>
@@ -203,16 +217,17 @@
     <string name="allow_mock_location" msgid="2787962564578664888">"મોક સ્થાનોની મંજૂરી આપો"</string>
     <string name="allow_mock_location_summary" msgid="317615105156345626">"મોક સ્થાનોની મંજૂરી આપો"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"લક્ષણ નિરીક્ષણ જોવાનું સક્ષમ કરો"</string>
-    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi‑Fi  સક્રિય હોય ત્યારે પણ, હંમેશા મોબાઇલ ડેટાને સક્રિય રાખો (ઝડપી નેટવર્ક સ્વિચિંગ માટે)."</string>
+    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"વાઇ-ફાઇ  સક્રિય હોય ત્યારે પણ, હંમેશા મોબાઇલ ડેટાને સક્રિય રાખો (ઝડપી નેટવર્ક સ્વિચિંગ માટે)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"જો ટિથરિંગ માટે હાર્ડવેર ગતિવૃદ્ધિ ઉપલબ્ધ હોય તો તેનો ઉપયોગ કરો"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB ડિબગિંગને મંજૂરી આપીએ?"</string>
-    <string name="adb_warning_message" msgid="7316799925425402244">"USB ડિબગીંગ ફક્ત વિકાસ હેતુઓ માટે જ બનાવાયેલ છે. તેનો ઉપયોગ તમારા કમ્પ્યુટર અને તમારા ઉપકરણ વચ્ચે ડેટાને કૉપિ કરવા, સૂચના વગર તમારા ઉપકરણ પર ઍપ્લિકેશનો ઇન્સ્ટોલ કરવા અને લૉગ ડેટા વાંચવા માટે કરો."</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"USB ડિબગીંગ ફક્ત વિકાસ હેતુઓ માટે જ બનાવાયેલ છે. તેનો ઉપયોગ તમારા કમ્પ્યુટર અને તમારા ઉપકરણ વચ્ચે ડેટાને કૉપિ કરવા, નોટિફિકેશન વગર તમારા ઉપકરણ પર ઍપ્લિકેશનો ઇન્સ્ટોલ કરવા અને લૉગ ડેટા વાંચવા માટે કરો."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"તમે અગાઉ અધિકૃત કરેલા તમામ કમ્પ્યુટર્સમાંથી USB ડિબગિંગ પરની અ‍ૅક્સેસ રદબાતલ કરીએ?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"વિકાસ સેટિંગ્સને મંજૂરી આપીએ?"</string>
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"આ સેટિંગ્સ ફક્ત વિકાસનાં ઉપયોગ માટે જ હેતુબદ્ધ છે. તે તમારા ઉપકરણ અને તેના પરની એપ્લિકેશન્સનાં ભંગ થવા અથવા ખરાબ વર્તનનું કારણ બની શકે છે."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB પર ઍપ્લિકેશનો ચકાસો"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"હાનિકારક વર્તણૂંક માટે ADB/ADT મારફતે ઇન્સ્ટોલ કરવામાં આવેલી ઍપ્લિકેશનો તપાસો."</string>
-    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"રિમોટ ઉપકરણોમાં વધુ પડતું ઊંચું વૉલ્યૂમ અથવા નિયંત્રણની કમી જેવી વૉલ્યૂમની સમસ્યાઓની સ્થિતિમાં Bluetooth ચોક્કસ વૉલ્યૂમ સુવિધાને અક્ષમ કરે છે."</string>
-    <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"ફોનનો રિંગટોન Bluetooth હેડસેટ પર વાગવાની મંજૂરી આપો"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"રિમોટ ઉપકરણોમાં વધુ પડતું ઊંચું વૉલ્યૂમ અથવા નિયંત્રણની કમી જેવી વૉલ્યૂમની સમસ્યાઓની સ્થિતિમાં બ્લૂટૂથ ચોક્કસ વૉલ્યૂમ સુવિધાને અક્ષમ કરે છે."</string>
+    <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"ફોનની રિંગટોન બ્લૂટૂથ હૅડસેટ પર વાગવાની મંજૂરી આપો"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"સ્થાનિક ટર્મિનલ"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"સ્થાનિક શેલ અ‍ૅક્સેસની ઑફર કરતી ટર્મિનલ એપ્લિકેશનને સક્ષમ કરો"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP તપાસણી"</string>
@@ -269,11 +284,11 @@
     <string name="debug_applications_category" msgid="4206913653849771549">"ઍપ્લિકેશનો"</string>
     <string name="immediately_destroy_activities" msgid="1579659389568133959">"પ્રવૃત્તિઓ રાખશો નહીં"</string>
     <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"જેવો વપરાશકર્તા તેને છોડે, તરત જ દરેક પ્રવૃત્તિ નષ્ટ કરો"</string>
-    <string name="app_process_limit_title" msgid="4280600650253107163">"પૃષ્ઠભૂમિ પ્રક્રિયા સીમા"</string>
+    <string name="app_process_limit_title" msgid="4280600650253107163">"બૅકગ્રાઉન્ડ પ્રક્રિયા સીમા"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"બધા ANR બતાવો"</string>
-    <string name="show_all_anrs_summary" msgid="641908614413544127">"પૃષ્ઠભૂમિ ઍપ્લિકેશનો માટે ઍપ્લિકેશન પ્રતિસાદ આપતી નથી સંવાદ બતાવો"</string>
-    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"સૂચના ચૅનલની ચેતવણી બતાવો"</string>
-    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ઍપ્લિકેશન માન્ય ચૅનલ વિના સૂચના પોસ્ટ કરે તો સ્ક્રીન પર ચેતવણી દેખાય છે"</string>
+    <string name="show_all_anrs_summary" msgid="641908614413544127">"બૅકગ્રાઉન્ડ ઍપ્લિકેશનો માટે ઍપ્લિકેશન પ્રતિસાદ આપતી નથી સંવાદ બતાવો"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"નોટિફિકેશન ચૅનલની ચેતવણી બતાવો"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ઍપ્લિકેશન માન્ય ચૅનલ વિના નોટિફિકેશન પોસ્ટ કરે તો સ્ક્રીન પર ચેતવણી દેખાય છે"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"બાહ્ય પર એપ્લિકેશનોને મંજૂરી આપવાની ફરજ પાડો"</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"મેનિફેસ્ટ મૂલ્યોને ધ્યાનમાં લીધા સિવાય, કોઈપણ ઍપ્લિકેશનને બાહ્ય સ્ટોરેજ પર લખાવા માટે લાયક બનાવે છે"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"પ્રવૃત્તિઓને ફરીથી કદ યોગ્ય થવા માટે ફરજ પાડો"</string>
@@ -294,7 +309,7 @@
   <string-array name="color_mode_descriptions">
     <item msgid="4979629397075120893">"વધારેલ રંગો"</item>
     <item msgid="8280754435979370728">"આંખો વડે જોઈ શકાતાં કુદરતી રંગો"</item>
-    <item msgid="5363960654009010371">"ડિજિટલ સામગ્રી માટે ઓપ્ટિમાઇઝ કરાયેલા રંગો"</item>
+    <item msgid="5363960654009010371">"ડિજિટલ કન્ટેન્ટ માટે ઓપ્ટિમાઇઝ કરાયેલા રંગો"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"નિષ્ક્રિય ઍપ્લિકેશનો"</string>
     <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"નિષ્ક્રિય. ટોગલ કરવા માટે ટૅપ કરો."</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"રંગ સુધારણા"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"આ સુવિધા પ્રાયોગિક છે અને કામગીરી પર અસર કરી શકે છે."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> દ્વારા ઓવરરાઇડ થયું"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"અંદાજે <xliff:g id="TIME">%1$s</xliff:g> બાકી"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"સંપૂર્ણપણે ચાર્જ થવામાં <xliff:g id="TIME">%1$s</xliff:g> બાકી"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> બાકી"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - લગભગ <xliff:g id="TIME">%2$s</xliff:g> બાકી"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> બાકી"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"અંદાજે <xliff:g id="TIME">^1</xliff:g> બાકી"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"તમારા વપરાશનાં આધારે લગભગ <xliff:g id="TIME">^1</xliff:g> બાકી છે"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"સંપૂર્ણપણે ચાર્જ થવામાં <xliff:g id="TIME">^1</xliff:g> બાકી"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> બાકી"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"તમારા વપરાશનાં આધારે <xliff:g id="TIME">^1</xliff:g> બાકી છે"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - લગભગ <xliff:g id="TIME">^2</xliff:g> બાકી"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - તમારા વપરાશનાં આધારે લગભગ <xliff:g id="TIME">^2</xliff:g> બાકી છે"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - સંપૂર્ણપણે ચાર્જ થવા માટે <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - સંપૂર્ણપણે ચાર્જ થવા માટે <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"અજાણ્યું"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"ચાર્જ થઈ રહ્યું છે"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ચાર્જ થઈ રહ્યું છે"</string>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index e304e90..f4bc1dd 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -25,7 +25,7 @@
     <item msgid="8934131797783724664">"स्‍कैन कर रहा है…"</item>
     <item msgid="8513729475867537913">"कनेक्ट हो रहा है..."</item>
     <item msgid="515055375277271756">"प्रमाणीकरण कर रहा है…"</item>
-    <item msgid="1943354004029184381">"IP पता प्राप्त कर रहा है…"</item>
+    <item msgid="1943354004029184381">"आईपी पता ले रहा है…"</item>
     <item msgid="4221763391123233270">"कनेक्ट किया गया"</item>
     <item msgid="624838831631122137">"निलंबित"</item>
     <item msgid="7979680559596111948">"डिस्‍कनेक्‍ट हो रहा है..."</item>
@@ -39,7 +39,7 @@
     <item msgid="8878186979715711006">"स्‍कैन कर रहा है…"</item>
     <item msgid="355508996603873860">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> से कनेक्‍ट कर रहा है…"</item>
     <item msgid="554971459996405634">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> के साथ प्रमाणीकरण कर रहा है…"</item>
-    <item msgid="7928343808033020343">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> से IP पता प्राप्त कर रहा है…"</item>
+    <item msgid="7928343808033020343">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> से आईपी पता ले रहा है..."</item>
     <item msgid="8937994881315223448">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> से कनेक्‍ट किया गया"</item>
     <item msgid="1330262655415760617">"निलंबित"</item>
     <item msgid="7698638434317271902">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> से डिस्‍कनेक्‍ट कर रहा है…"</item>
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (डिफ़ॉल्ट)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"सिस्टम चयन का उपयोग करें (डिफ़ॉल्ट)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"वैकल्पिक कोडेक सक्षम करें"</item>
-    <item msgid="3304843301758635896">"वैकल्पिक कोडेक अक्षम करें"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"सिस्टम चयन का उपयोग करें (डिफ़ॉल्ट)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"वैकल्पिक कोडेक सक्षम करें"</item>
-    <item msgid="741805482892725657">"वैकल्पिक कोडेक अक्षम करें"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"सिस्टम चयन का उपयोग करें (डिफ़ॉल्ट)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
@@ -128,13 +114,13 @@
     <item msgid="7158319962230727476">"ऑडियो की गुणवत्ता के लिए अनुकूलित किया गया (990kbps/909kbps)"</item>
     <item msgid="2921767058740704969">"संतुलित ऑडियो और कनेक्शन गुणवत्ता (660kbps/606kbps)"</item>
     <item msgid="8860982705384396512">"कनेक्शन की गुणवत्ता के लिए अनुकूलित किया गया (330kbps/303kbps)"</item>
-    <item msgid="4414060457677684127">"सबसे अच्छी कोशिश (अनुकूल बिट दर)"</item>
+    <item msgid="4414060457677684127">"सबसे अच्छी क्वालिटी में चलाएं (अनुकूल बिट रेट)"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
     <item msgid="6398189564246596868">"ऑडियो की गुणवत्ता के लिए अनुकूलित किया गया"</item>
     <item msgid="4327143584633311908">"संतुलित ऑडियो और कनेक्शन गुणवत्ता"</item>
     <item msgid="4681409244565426925">"कनेक्शन की गुणवत्ता के लिए अनुकूलित किया गया"</item>
-    <item msgid="364670732877872677">"सबसे अच्छी कोशिश (अनुकूल बिट दर)"</item>
+    <item msgid="364670732877872677">"सबसे अच्छी क्वालिटी में चलाएं (अनुकूल बिट रेट)"</item>
   </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"बंद"</item>
@@ -215,7 +201,7 @@
     <item msgid="3191973083884253830">"कोई नहीं"</item>
     <item msgid="9089630089455370183">"Logcat"</item>
     <item msgid="5397807424362304288">"Systrace (ग्राफ़िक)"</item>
-    <item msgid="1340692776955662664">"glGetError पर स्टैक कॉल करें"</item>
+    <item msgid="1340692776955662664">"glGetError पर कॉल स्टैक"</item>
   </string-array>
   <string-array name="show_non_rect_clip_entries">
     <item msgid="993742912147090253">"बंद"</item>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 103f22b..f23c82d 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -28,15 +28,24 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"खराब नेटवर्क होने के कारण कनेक्ट नहीं हुआ"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"वाईफ़ाई कनेक्‍शन विफलता"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"प्रमाणीकरण समस्या"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"कनेक्ट नहीं हो पा रहा है"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' से कनेक्ट नहीं हो पा रहा है"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"पासवर्ड जांचें और दोबारा कोशिश करें"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"रेंज में नहीं"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"अपने आप कनेक्ट नहीं होगा"</string>
-    <string name="wifi_no_internet" msgid="3880396223819116454">"कोई इंटरनेट एक्सेस नहीं"</string>
+    <string name="wifi_no_internet" msgid="3880396223819116454">"इंटरनेट नहीं है"</string>
     <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> के द्वारा सहेजा गया"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s के ज़रिए ऑटोमैटिक रूप से कनेक्ट है"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"नेटवर्क रेटिंग प्रदाता के ज़रिए अपने आप कनेक्ट है"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s के द्वारा उपलब्ध"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s के द्वारा उपलब्ध"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"कनेक्ट किया गया, इंटरनेट नहीं"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"अत्‍यधिक धीमी"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"धीमी"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ठीक है"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"मध्यम"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"तेज़"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"अत्‍यधिक तेज़"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"डिस्कनेक्‍ट किया गया"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"डिस्‍कनेक्‍ट हो रहा है..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"कनेक्ट हो रहा है..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"कनेक्‍ट है (मीडि‍या नहीं)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"कनेक्ट किया गया (कोई संदेश एक्सेस नहीं)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"कनेक्‍ट है (फ़ोन या मीडि‍या नहीं)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"कनेक्ट किया गया, बैटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> है"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"कनेक्ट किया गया (कोई फ़ोन नहीं), बैटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> है"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"कनेक्ट किया गया (कोई मीडिया नहीं), बैटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> है"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"कनेक्ट किया गया (कोई फ़ोन या मीडि‍या नहीं), बैटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> है"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मीडिया ऑडियो"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"फ़ोन ऑडियो"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"फ़ोन कॉल"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"फ़ाइल स्थानांतरण"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"इनपुट डिवाइस"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"इंटरनेट पहुंच"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"संपर्क साझाकरण"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"संपर्क साझाकरण के लिए उपयोग करें"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"इंटरनेट कनेक्शन साझाकरण"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"संदेश एक्सेस"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"लेख संदेश"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"सिम ऐक्सेस"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"अच्छी गुणवत्ता वाले ऑडियो का उपयोग करें: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"अच्छी गुणवत्ता वाले ऑडियो का उपयोग करें"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ऑडियो: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ऑडियो"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"मीडिया ऑडियो से कनेक्‍ट किया गया"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"फ़ोन ऑडियो से कनेक्‍ट किया गया"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"फ़ाइल स्‍थानांतरण सर्वर से कनेक्‍ट किया गया"</string>
@@ -75,13 +88,13 @@
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"फ़ाइल स्‍थानांतरण के लिए उपयोग करें"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"इनपुट के लिए उपयोग करें"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"युग्‍म बनाएं"</string>
-    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"युग्‍मित करें"</string>
-    <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"अभी नहीं"</string>
-    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"कनेक्ट रहने पर, पेयरिंग आपको अपने संपर्कों और कॉल इतिहास की एक्सेस प्रदान करता है."</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"दूसरे डिवाइस से जोड़ें"</string>
+    <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"रद्द करें"</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"कनेक्ट होने पर, पेयरिंग से आपके संपर्कों और कॉल इतिहास तक पहुंचा जा सकता है."</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> के साथ युग्‍मित नहीं हो सका."</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"गलत पिन या पासकी के कारण <xliff:g id="DEVICE_NAME">%1$s</xliff:g> के साथ युग्‍मित नहीं हो सका."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> से संचार नहीं कर सकता."</string>
-    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> द्वारा युग्‍मन अस्‍वीकृत किया गया."</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ने जोड़ने का अनुरोध नहीं माना."</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"वाई-फ़ाई बंद है."</string>
     <string name="accessibility_no_wifi" msgid="8834610636137374508">"वाई-फ़ाई डिसकनेक्ट है."</string>
     <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"वाई-फ़ाई का एक बार है."</string>
@@ -91,9 +104,9 @@
     <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"निकाले गए ऐप्स"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"ऐप्स  और उपयोगकर्ताओं को निकालें"</string>
-    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB टेदरिंग"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB से इंटरनेट पर शेयर करें"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"पोर्टेबल हॉटस्‍पॉट"</string>
-    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"ब्लूटूथ टेदरिंग"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"ब्लूटूथ से इंटरनेट पर शेयर करें."</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"टेदरिंग"</string>
     <string name="tether_settings_title_all" msgid="8356136101061143841">"टेदरिंग और पोर्टेबल हॉटस्‍पॉट"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"सभी कार्यस्थल ऐप्लिकेशन"</string>
@@ -113,10 +126,10 @@
     <string name="tts_lang_not_selected" msgid="7395787019276734765">"भाषा नहीं चुनी गई है"</string>
     <string name="tts_default_lang_summary" msgid="5219362163902707785">"बोले गए लेख के लिए भाषा-विशिष्ट ध्‍वनि सेट करता है"</string>
     <string name="tts_play_example_title" msgid="7094780383253097230">"एक उदाहरण सुनें"</string>
-    <string name="tts_play_example_summary" msgid="8029071615047894486">"बोली संश्लेषण का एक संक्षिप्त प्रदर्शन चलाएं"</string>
+    <string name="tts_play_example_summary" msgid="8029071615047894486">"लिखे हुए को बोली में बदलने की सुविधा की एक छोटी सी झलक चलाएं"</string>
     <string name="tts_install_data_title" msgid="4264378440508149986">"ध्‍वनि डेटा इंस्टॉल करें"</string>
     <string name="tts_install_data_summary" msgid="5742135732511822589">"बोली-संश्लेषण के लिए आवश्‍यक ध्‍वनि डेटा इंस्‍टॉल करें"</string>
-    <string name="tts_engine_security_warning" msgid="8786238102020223650">"यह बोली संश्लेषण इंजन पासवर्ड और क्रेडिट कार्ड नंबर जैसे निजी डेटा समेत आपके द्वारा बोले जाने वाले सभी लेख को एकत्र कर सकता है. यह <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> इंजन से आता है. इस बोली संश्लेषण इंजन के उपयोग को सक्षम करें?"</string>
+    <string name="tts_engine_security_warning" msgid="8786238102020223650">"यह स्पीच सिंथेसिस (लिखे हुए को मशीन द्वारा बोली में बदलना) इंजन, पासवर्ड और क्रेडिट कार्ड नंबर जैसे निजी डेटा सहित आपके द्वारा बोले जाने वाले सभी लेख इकट्ठा कर सकता है. यह <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> इंजन से आता है. स्पीच सिंथेसिस इंजन के इस्तेमाल को चालू करें?"</string>
     <string name="tts_engine_network_required" msgid="1190837151485314743">"लेख-से-बोली आउटपुट के लिए इस भाषा को क्रियाशील नेटवर्क कनेक्शन की आवश्यकता है."</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"यह बोली संश्लेषण का एक उदाहरण है"</string>
     <string name="tts_status_title" msgid="7268566550242584413">"डिफ़ॉल्ट भाषा स्थिति"</string>
@@ -144,37 +157,38 @@
     <string name="choose_profile" msgid="6921016979430278661">"प्रोफ़ाइल चुनें"</string>
     <string name="category_personal" msgid="1299663247844969448">"व्यक्तिगत"</string>
     <string name="category_work" msgid="8699184680584175622">"कार्यालय"</string>
-    <string name="development_settings_title" msgid="215179176067683667">"डेवलपर विकल्प"</string>
-    <string name="development_settings_enable" msgid="542530994778109538">"डेवलपर विकल्‍प सक्षम करें"</string>
+    <string name="development_settings_title" msgid="215179176067683667">"डेवलपर के लिए सेटिंग और टूल"</string>
+    <string name="development_settings_enable" msgid="542530994778109538">"डेवलपर के लिए सेटिंग और टूल चालू करें"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"ऐप्स विकास के लिए विकल्‍प सेट करें"</string>
-    <string name="development_settings_not_available" msgid="4308569041701535607">"इस उपयोगकर्ता के लिए डेवलपर विकल्प उपलब्ध नहीं हैं"</string>
+    <string name="development_settings_not_available" msgid="4308569041701535607">"यह उपयोगकर्ता, डेवलपर के लिए सेटिंग और टूल का इस्तेमाल नहीं कर सकता"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN सेटिंग इस उपयोगकर्ता के लिए उपलब्ध नहीं हैं"</string>
     <string name="tethering_settings_not_available" msgid="6765770438438291012">"टेदरिंग सेटिंग इस उपयोगकर्ता के लिए उपलब्ध नहीं हैं"</string>
-    <string name="apn_settings_not_available" msgid="7873729032165324000">"एक्सेस पॉइंट नाम सेटिंग इस उपयोगकर्ता के लिए उपलब्ध नहीं हैं"</string>
+    <string name="apn_settings_not_available" msgid="7873729032165324000">"एक्सेस पॉइंट नाम सेटिंग इस उपयोगकर्ता के लिए मौजूद नहीं हैं"</string>
     <string name="enable_adb" msgid="7982306934419797485">"USB डीबग करना"</string>
     <string name="enable_adb_summary" msgid="4881186971746056635">"डीबग मोड जब USB कनेक्‍ट किया गया हो"</string>
-    <string name="clear_adb_keys" msgid="4038889221503122743">"USB डीबगिंग प्राधिकरणों को निरस्त करें"</string>
-    <string name="bugreport_in_power" msgid="7923901846375587241">"बग रिपोर्ट शॉर्टकट"</string>
-    <string name="bugreport_in_power_summary" msgid="1778455732762984579">"बग रिपोर्ट लेने के लिए पावर मेनू में कोई बटन दिखाएं"</string>
-    <string name="keep_screen_on" msgid="1146389631208760344">"सचेत रहें"</string>
-    <string name="keep_screen_on_summary" msgid="2173114350754293009">"चार्ज होने के दौरान स्‍क्रीन कभी निष्‍क्रिय नहीं होगी"</string>
-    <string name="bt_hci_snoop_log" msgid="3340699311158865670">"ब्लूटूथ HCI स्‍नूप लॉग सक्षम करें"</string>
+    <string name="clear_adb_keys" msgid="4038889221503122743">"USB डीबग करने की मंज़ूरी रद्द करें"</string>
+    <string name="bugreport_in_power" msgid="7923901846375587241">"गड़बड़ी की रिपोर्ट का शॉर्टकट"</string>
+    <string name="bugreport_in_power_summary" msgid="1778455732762984579">"गड़बड़ी की रिपोर्ट लेने के लिए पावर मेन्यू में कोई बटन दिखाएं"</string>
+    <string name="keep_screen_on" msgid="1146389631208760344">"स्क्रीन को चालू रखें"</string>
+    <string name="keep_screen_on_summary" msgid="2173114350754293009">"चार्ज करते समय स्‍क्रीन कभी भी कम बैटरी मोड में नहीं जाएगी"</string>
+    <string name="bt_hci_snoop_log" msgid="3340699311158865670">"ब्लूटूथ HCI स्‍नूप लॉग चालू करें"</string>
     <string name="bt_hci_snoop_log_summary" msgid="730247028210113851">"फ़ाइल के सभी ब्लूटूथ HCI पैकेट कैप्‍चर करें"</string>
     <string name="oem_unlock_enable" msgid="6040763321967327691">"OEM अनलॉक करना"</string>
     <string name="oem_unlock_enable_summary" msgid="4720281828891618376">"बूटलोडर को अनलाॅक किए जाने की अनुमति दें"</string>
     <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM अनलॉक करने की अनुमति दें?"</string>
     <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"चेतावनी: इस सेटिंग के चालू रहने पर डिवाइस सुरक्षा सुविधाएं इस डिवाइस पर काम नहीं करेंगी."</string>
-    <string name="mock_location_app" msgid="7966220972812881854">"कृत्रिम स्‍थान वाला ऐप चुनें"</string>
-    <string name="mock_location_app_not_set" msgid="809543285495344223">"कृत्रिम स्‍थान वाला कोई ऐप सेट नहीं है"</string>
-    <string name="mock_location_app_set" msgid="8966420655295102685">"कृत्रिम स्‍थान वाला ऐप: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="mock_location_app" msgid="7966220972812881854">"जगह की नकली जानकारी देने के लिए ऐप चुनें"</string>
+    <string name="mock_location_app_not_set" msgid="809543285495344223">"जगह की नकली जानकारी देने के लिए ऐप सेट नहीं है"</string>
+    <string name="mock_location_app_set" msgid="8966420655295102685">"जगह की नकली जानकारी देने वाला ऐप: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="debug_networking_category" msgid="7044075693643009662">"नेटवर्किंग"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"वायरलेस दिखाई देने के लिए प्रमाणन"</string>
-    <string name="wifi_verbose_logging" msgid="4203729756047242344">"वाई-फ़ाई वर्बोस प्रवेश सक्षम करें"</string>
+    <string name="wifi_verbose_logging" msgid="4203729756047242344">"वाई-फ़ाई वर्बोस लॉगिंग चालू करें"</string>
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"वाई-फ़ाई से मोबाइल पर ज़्यादा तेज़ी से हैंडओवर"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"हमेशा वाई-फ़ाई रोम स्कैन करने दें"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा हमेशा सक्रिय"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"हार्डवेयर से तेज़ी लाने के लिए टेदर करें"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"पूर्ण वॉल्यूम अक्षम करें"</string>
-    <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"इन-बैंड रिंग करना सक्षम करें"</string>
+    <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"इन-बैंड रिंग करना चालू करें"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ब्लूटूथ AVRCP वर्शन"</string>
     <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ब्लूटूथ AVRCP वर्शन चुनें"</string>
     <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ब्लूटूथ ऑडियो कोडेक"</string>
@@ -187,7 +201,7 @@
     <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="9133545781346216071">"ब्लूटूथ ऑडियो कोडेक चुनें:\nचैनल मोड"</string>
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ब्लूटूथ ऑडियो LDAC कोडेक: प्लेबैक क्वालिटी"</string>
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ब्लूटूथ ऑडियो LDAC कोडेक चुनें:\nप्लेबैक क्वालिटी"</string>
-    <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"स्ट्रीम हो रहा है: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
+    <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"चलाया जा रहा है: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस दिखाई देने के लिए प्रमाणन विकल्प दिखाएं"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाई-फ़ाई प्रवेश स्तर बढ़ाएं, वाई-फ़ाई पिकर में प्रति SSID RSSI दिखाएं"</string>
     <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"इसके सक्षम होने पर, जब वाई-फ़ाई संकेत कमज़ोर हों तो वाई-फ़ाई, डेटा कनेक्शन को मोबाइल पर ज़्यादा तेज़ी से भेजेगा"</string>
@@ -202,19 +216,20 @@
     <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"USB कॉन्फ़िगरेशन चुनें"</string>
     <string name="allow_mock_location" msgid="2787962564578664888">"कृत्रिम स्‍थानों को अनुमति दें"</string>
     <string name="allow_mock_location_summary" msgid="317615105156345626">"कृत्रिम स्‍थानों को अनुमति दें"</string>
-    <string name="debug_view_attributes" msgid="6485448367803310384">"दृश्य विशेषता निरीक्षण सक्षम करें"</string>
+    <string name="debug_view_attributes" msgid="6485448367803310384">"देखने वाले से जुड़े खास डेटा को रखना चालू करें"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"वाई-फ़ाई के सक्रिय रहने पर भी, हमेशा मोबाइल डेटा सक्रिय रखें (तेज़ी से नेटवर्क स्विच करने के लिए)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"हार्डवेयर से तेज़ी लाने के लिए टेदर करने की सुविधा मौजूद होने पर उसका इस्तेमाल करें"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB डीबग करने की अनुमति दें?"</string>
-    <string name="adb_warning_message" msgid="7316799925425402244">"USB डीबग करने का उद्देश्‍य केवल विकास है. इसका इस्तेमाल आपके कंप्‍यूटर और आपके डिवाइस के बीच डेटा को कॉपी करने, बिना नोटिफ़िकेशन के आपके डिवाइस पर ऐप इंस्‍टॉल करने और लॉग डेटा पढ़ने के लिए करें."</string>
-    <string name="adb_keys_warning_message" msgid="5659849457135841625">"आपके द्वारा पूर्व में प्राधिकृत सभी कंप्यूटर से USB डीबगिंग की पहुंच निरस्त करें?"</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"USB डीबग करने का मकसद केवल डेवेलप करना है. इसका इस्तेमाल आपके कंप्‍यूटर और आपके डिवाइस के बीच डेटा को कॉपी करने, बिना सूचना के आपके डिवाइस पर ऐप इंस्‍टॉल करने और लॉग डेटा पढ़ने के लिए करें."</string>
+    <string name="adb_keys_warning_message" msgid="5659849457135841625">"उन सभी कंप्यूटरों से USB डीबग करने की पहुंचर रद्द करें, जिन्हें आपने पहले इसकी मंज़ूरी दी थी?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"विकास सेटिंग की अनुमति दें?"</string>
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"ये सेटिंग केवल विकास संबंधी उपयोग के प्रयोजन से हैं. वे आपके डिवाइस और उस पर स्‍थित ऐप्स  को खराब कर सकती हैं या उनके दुर्व्यवहार का कारण हो सकती हैं."</string>
-    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB पर ऐप्स  सत्यापित करें"</string>
+    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB पर ऐप की पुष्टि करें"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"नुकसानदेह व्यवहार के लिए ADB/ADT के द्वारा इंस्टॉल किए गए ऐप्स  जांचें."</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"दूरस्थ डिवाइस के साथ वॉल्यूम की समस्याओं जैसे अस्वीकार्य तेज़ वॉल्यूम या नियंत्रण की कमी की स्थिति में ब्लूटूथ पूर्ण वॉल्यूम सुविधा को अक्षम करता है."</string>
-    <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"फ़ोन की रिंगटोन को ब्लूटूथ हैडसेट पर बजने दें"</string>
+    <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"फ़ोन की रिंगटोन को ब्लूटूथ हेडसेट पर बजने दें"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"स्थानीय टर्मिनल"</string>
-    <string name="enable_terminal_summary" msgid="67667852659359206">"स्थानीय शेल एक्सेस ऑफ़र करने वाला टर्मिनल ऐप्स  सक्षम करें"</string>
+    <string name="enable_terminal_summary" msgid="67667852659359206">"लोकल शेल तक पहुंचने की सुविधा देने वाले टर्मिनल ऐप को चालू करें"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP जांच"</string>
     <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"HDCP जांच व्‍यवहार सेट करें"</string>
     <string name="debug_debugging_category" msgid="6781250159513471316">"डीबग करना"</string>
@@ -226,7 +241,7 @@
     <string name="wait_for_debugger" msgid="1202370874528893091">"डीबगर की प्रतीक्षा करें"</string>
     <string name="wait_for_debugger_summary" msgid="1766918303462746804">"डीबग किया गया ऐप्स  निष्पादन के पहले अनुलग्न करने के लिए डीबगर की प्रतीक्षा करता है"</string>
     <string name="telephony_monitor_switch" msgid="1764958220062121194">"टेलीफ़ोनी मॉनिटर"</string>
-    <string name="telephony_monitor_switch_summary" msgid="7695552966547975635">"टेलीफ़ोनी मॉनिटर को जब टेलीफ़ोनी/मॉडेम कार्यक्षमता में कोई समस्या मिलती है तो वह लॉग इकट्ठा करता है और उपयोगकर्ता को एक बग दर्ज करने के लिए नोटिफ़िकेशन देता है"</string>
+    <string name="telephony_monitor_switch_summary" msgid="7695552966547975635">"टेलीफ़ोनी मॉनिटर को जब टेलीफ़ोनी/मॉडेम के फंक्शन में कोई समस्या मिलती है, तो वह लॉग इकट्ठा करता है और उपयोगकर्ता को एक गड़बड़ी दर्ज करने के लिए सूचना देता है"</string>
     <string name="debug_input_category" msgid="1811069939601180246">"हिंदी में लिखें"</string>
     <string name="debug_drawing_category" msgid="6755716469267367852">"ड्रॉइंग"</string>
     <string name="debug_hw_drawing_category" msgid="6220174216912308658">"हार्डवेयर त्वरित रेंडरिंग"</string>
@@ -234,22 +249,22 @@
     <string name="debug_monitoring_category" msgid="7640508148375798343">"निगरानी"</string>
     <string name="strict_mode" msgid="1938795874357830695">"सख्‍त मोड सक्षम किया गया"</string>
     <string name="strict_mode_summary" msgid="142834318897332338">"जब ऐप्स मुख्‍य थ्रेड पर लंबी कार्यवाही करते हैं तो स्‍क्रीन फ़्लैश करें"</string>
-    <string name="pointer_location" msgid="6084434787496938001">"सूचक स्थान"</string>
-    <string name="pointer_location_summary" msgid="840819275172753713">"वर्तमान स्‍पर्श डेटा दिखाने वाला स्‍क्रीन ओवरले"</string>
+    <string name="pointer_location" msgid="6084434787496938001">"पॉइंटर की जगह"</string>
+    <string name="pointer_location_summary" msgid="840819275172753713">"मौजूदा स्‍पर्श डेटा दिखाने वाला स्‍क्रीन ओवरले"</string>
     <string name="show_touches" msgid="2642976305235070316">"टैप दिखाएं"</string>
     <string name="show_touches_summary" msgid="6101183132903926324">"टैप के लिए विज़ुअल फ़ीडबैक दिखाएं"</string>
-    <string name="show_screen_updates" msgid="5470814345876056420">"सतह के नई जानकारी दिखाएं"</string>
-    <string name="show_screen_updates_summary" msgid="2569622766672785529">"विंडो सतहें के नई जानकारी मिलने पर उन सभी को फ़्लैश करें"</string>
-    <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU दृश्य की नई जानकारी दिखाएं"</string>
+    <string name="show_screen_updates" msgid="5470814345876056420">"सर्फ़ेस अपडेट दिखाएं"</string>
+    <string name="show_screen_updates_summary" msgid="2569622766672785529">"अपडेट होने पर पूरे विंडो सर्फ़ेस को फ़्लैश करें"</string>
+    <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU व्यू अपडेट दिखाएं"</string>
     <string name="show_hw_screen_updates_summary" msgid="1115593565980196197">"GPU के साथ आरेखित करने पर विंडो में दृश्‍यों को फ़्लैश करें"</string>
-    <string name="show_hw_layers_updates" msgid="5645728765605699821">"हार्डवेयर लेयर की नई जानकारी"</string>
-    <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"हार्डवेयर लेयर की नई जानकारी मिलने पर हरा फ़्लैश होता है"</string>
+    <string name="show_hw_layers_updates" msgid="5645728765605699821">"हार्डवेयर लेयर अपडेट दिखाएं"</string>
+    <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"हार्डवेयर लेयर अपडेट होने पर उनमें हरी रोशनी डालें"</string>
     <string name="debug_hw_overdraw" msgid="2968692419951565417">"GPU ओवरड्रॉ डीबग करें"</string>
     <string name="debug_hw_renderer" msgid="7568529019431785816">"GPU दाता सेट करें"</string>
-    <string name="disable_overlays" msgid="2074488440505934665">"HW ओवरले अक्षम करें"</string>
+    <string name="disable_overlays" msgid="2074488440505934665">"HW ओवरले बंद करें"</string>
     <string name="disable_overlays_summary" msgid="3578941133710758592">"स्‍क्रीन संयोजन के लिए हमेशा GPU का उपयोग करें"</string>
     <string name="simulate_color_space" msgid="6745847141353345872">"रंग स्पेस सिम्युलेट करें"</string>
-    <string name="enable_opengl_traces_title" msgid="6790444011053219871">"OpenGL चिह्न सक्षम करें"</string>
+    <string name="enable_opengl_traces_title" msgid="6790444011053219871">"OpenGL ट्रेस चालू करें"</string>
     <string name="usb_audio_disable_routing" msgid="8114498436003102671">"USB ऑडियो रूटिंग अक्षम करें"</string>
     <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"USB ऑडियो पेरिफ़ेरल पर स्‍वत: रूटिंग अक्षम करें"</string>
     <string name="debug_layout" msgid="5981361776594526155">"लेआउट सीमाएं दिखाएं"</string>
@@ -259,27 +274,27 @@
     <string name="force_hw_ui" msgid="6426383462520888732">"बलपूर्वक GPU रेंडर करें"</string>
     <string name="force_hw_ui_summary" msgid="5535991166074861515">"2d ड्रॉइंग के लिए GPU का बलपूर्वक उपयोग करें"</string>
     <string name="force_msaa" msgid="7920323238677284387">"4x MSAA को बाध्य करें"</string>
-    <string name="force_msaa_summary" msgid="9123553203895817537">"OpenGL ES 2.0 ऐप्स  में 4x MSAA को सक्षम करें"</string>
+    <string name="force_msaa_summary" msgid="9123553203895817537">"OpenGL ES 2.0 ऐप में 4x MSAA को चालू करें"</string>
     <string name="show_non_rect_clip" msgid="505954950474595172">"गैर-आयताकार क्लिप परिचालनों को डीबग करें"</string>
     <string name="track_frame_time" msgid="6146354853663863443">"प्रोफ़ाइल GPU रेंडरिंग"</string>
     <string name="window_animation_scale_title" msgid="6162587588166114700">"विंडो एनिमेशन स्‍केल"</string>
     <string name="transition_animation_scale_title" msgid="387527540523595875">"संक्रमण एनिमेशन स्‍केल"</string>
     <string name="animator_duration_scale_title" msgid="3406722410819934083">"एनिमेटर अवधि स्केल"</string>
     <string name="overlay_display_devices_title" msgid="5364176287998398539">"द्वितीयक डिस्प्ले अनुरूपित करें"</string>
-    <string name="debug_applications_category" msgid="4206913653849771549">"ऐप्स"</string>
+    <string name="debug_applications_category" msgid="4206913653849771549">"ऐप"</string>
     <string name="immediately_destroy_activities" msgid="1579659389568133959">"गतिविधियों को न रखें"</string>
-    <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"उपयोगकर्ता के छोड़ते ही प्रत्‍येक गतिविधि समाप्त करें"</string>
+    <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"उपयोगकर्ता के छोड़ते ही हर गतिविधि को खत्म करें"</string>
     <string name="app_process_limit_title" msgid="4280600650253107163">"पृष्ठभूमि प्रक्रिया सीमा"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"सभी ANR दिखाएं"</string>
     <string name="show_all_anrs_summary" msgid="641908614413544127">"पृष्ठभूमि ऐप्स के लिए ऐप्स प्रतिसाद नहीं दे रहा डॉयलॉग दिखाएं"</string>
-    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"नोटिफ़िकेशन चैनल चेतावनी दिखाएं"</string>
-    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ऐप्लिकेशन मान्य चैनल के बिना नोटिफ़िकेशन पोस्ट करे तो स्क्रीन पर चेतावनी दिखाएं"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"सूचना चैनल चेतावनी दिखाएं"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ऐप सही चैनल के बिना सूचना पोस्ट करे तो स्क्रीन पर चेतावनी दिखाएं"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"ऐप्स को बाहरी मेमोरी पर बाध्‍य करें"</string>
-    <string name="force_allow_on_external_summary" msgid="3640752408258034689">"इससे कोई भी ऐप्लिकेशन, मेनिफेस्ट मानों को अनदेखा करके, बाहरी मेमोरी पर लिखने योग्य बन जाता है"</string>
+    <string name="force_allow_on_external_summary" msgid="3640752408258034689">"इससे कोई भी ऐप बाहरी मेमोरी में रखने लायक बन जाता है चाहे उसकी मेनिफ़ेस्ट वैल्यू कुछ भी हो"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"आकार बदले जाने के लिए गतिविधियों को बाध्य करें"</string>
-    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"सभी गतिविधियों को एकाधिक विंडो के लिए आकार बदलने योग्य बनाएं, चाहे मेनिफेस्ट मान कुछ भी हों."</string>
-    <string name="enable_freeform_support" msgid="1461893351278940416">"फ़्रीफ़ॉर्म विंडो सक्षम करें"</string>
-    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"प्रयोगात्मक फ़्रीफ़ॉर्म विंडो का समर्थन सक्षम करें."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"सभी गतिविधियों को मल्टी-विंडो (एक से ज़्यादा ऐप, एक साथ) के लिए आकार बदलने लायक बनाएं, चाहे उनकी मेनिफ़ेस्ट वैल्यू कुछ भी हो."</string>
+    <string name="enable_freeform_support" msgid="1461893351278940416">"फ़्रीफ़ॉर्म विंडो (एक साथ कई विंडो दिखाना) चालू करें"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"जांच के लिए बनी फ़्रीफ़ॉर्म विंडो के लिए सहायता चालू करें."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"डेस्‍कटॉप बैकअप पासवर्ड"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"डेस्‍कटॉप पूर्ण बैकअप वर्तमान में सुरक्षित नहीं हैं"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"डेस्कटॉप के पूर्ण बैकअप का पासवर्ड बदलने या निकालने के लिए टैप करें"</string>
@@ -296,19 +311,19 @@
     <item msgid="8280754435979370728">"आंखों को दिखाई देने वाले प्राकृतिक रंग"</item>
     <item msgid="5363960654009010371">"डिजिटल सामग्री के लिए ऑप्टिमाइज़़ किए गए रंग"</item>
   </string-array>
-    <string name="inactive_apps_title" msgid="1317817863508274533">"निष्क्रिय ऐप्स"</string>
-    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"निष्क्रिय. टॉगल करने के लिए टैप करें."</string>
-    <string name="inactive_app_active_summary" msgid="4174921824958516106">"सक्रिय. टॉगल करने पर टैप करें."</string>
+    <string name="inactive_apps_title" msgid="1317817863508274533">"बंद एेप"</string>
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"बंद है. टॉगल करने के लिए टैप करें."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"सक्रिय. टॉगल करने के लिए टैप करें."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"चल रही सेवाएं"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"वर्तमान में चल रही सेवाओं को देखें और नियंत्रित करें"</string>
-    <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView कार्यान्वयन"</string>
-    <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView कार्यान्वयन सेट करें"</string>
+    <string name="select_webview_provider_title" msgid="4628592979751918907">"वेबव्यू लागू करें"</string>
+    <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"वेबव्यू सेट करें"</string>
     <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"यह चयन अब मान्य नहीं है. पुनः प्रयास करें."</string>
-    <string name="convert_to_file_encryption" msgid="3060156730651061223">"फ़ाइल एन्क्रिप्शन में रूपांतरित करें"</string>
+    <string name="convert_to_file_encryption" msgid="3060156730651061223">"फ़ाइल आधारित सुरक्षित करने के तरीके में बदलें"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"रूपांतरित करें..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"फ़ाइल पहले से एन्क्रिप्ट की हुई है"</string>
-    <string name="title_convert_fbe" msgid="1263622876196444453">"फ़ाइल आधारित एन्क्रिप्शन में रूपांतरित कर रहा है"</string>
-    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"डेटा विभाजन को फ़ाइल आधारित एन्क्रिप्शन में रूपांतरित करें.\n !!चेतावनी!! इससे आपका सभी डेटा मिट जाएगा.\n यह सुविधा अल्फ़ा स्थिति में है और ठीक से कार्य नहीं कर सकती.\n जारी रखने के लिए \'वाइप करें और रूपांतरित करें…\' दबाएं."</string>
+    <string name="title_convert_fbe" msgid="1263622876196444453">"फ़ाइल के आधार पर सुरक्षित करने के तरीके में बदल  कर रहा है"</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"डेटा विभाजन (डेटा को अलग-अलग हिस्सों में बांटना) को फ़ाइल आधारित सुरक्षित करने के तरीके में बदलें.\n !!चेतावनी!! इससे आपका सभी डेटा मिट जाएगा.\n यह सुविधा अल्फ़ा स्थिति में है और हो सकता है ये ठीक से काम ना करे.\n जारी रखने के लिए \'वाइप करें और बदलें…\' दबाएं."</string>
     <string name="button_convert_fbe" msgid="5152671181309826405">"वाइप करें और रूपांतरित करें…"</string>
     <string name="picture_color_mode" msgid="4560755008730283695">"चित्र रंग मोड"</string>
     <string name="picture_color_mode_desc" msgid="1141891467675548590">"sRGB का उपयोग करें"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"रंग सुधार"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"यह सुविधा प्रायोगिक है और निष्पादन को प्रभावित कर सकती है."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> के द्वारा ओवरराइड किया गया"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"लगभग <xliff:g id="TIME">%1$s</xliff:g> शेष"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"पूरी तरह से चार्ज होने में <xliff:g id="TIME">%1$s</xliff:g> शेष"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> शेष"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - लगभग <xliff:g id="TIME">%2$s</xliff:g> शेष"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> शेष"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"लगभग <xliff:g id="TIME">^1</xliff:g> शेष"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"आपके उपयोग के आधार पर लगभग <xliff:g id="TIME">^1</xliff:g> का समय बचा है"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"पूरी तरह से चार्ज होने में <xliff:g id="TIME">^1</xliff:g> शेष"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> शेष"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"आपके उपयोग के आधार पर <xliff:g id="TIME">^1</xliff:g> का समय बचा है"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - लगभग <xliff:g id="TIME">^2</xliff:g> शेष"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - आपके उपयोग के आधार पर लगभग <xliff:g id="TIME">^2</xliff:g> का समय बचा है"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूरी तरह से चार्ज होने तक"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> पूरी तरह से चार्ज होने तक"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज हो रही है"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"चार्ज किया जा रहा है"</string>
@@ -340,8 +358,8 @@
     <string name="disabled" msgid="9206776641295849915">"अक्षम किया गया"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"अनुमति है"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"अनुमति नहीं है"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"अनजान ऐप्लिकेशन इंस्टॉल करें"</string>
-    <string name="home" msgid="3256884684164448244">"सेटिंग होम"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"अनजान ऐप इंस्टॉल करें"</string>
+    <string name="home" msgid="3256884684164448244">"सेटिंग का होम पेज"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
     <item msgid="8934126114226089439">"50%"</item>
@@ -356,7 +374,7 @@
     <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"सबसे बड़ा"</string>
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"कस्टम (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"सहायता और फ़ीडबैक"</string>
-    <string name="content_description_menu_button" msgid="8182594799812351266">"मेनू"</string>
+    <string name="content_description_menu_button" msgid="8182594799812351266">"मेन्यू"</string>
     <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
     <string name="retail_demo_reset_message" msgid="118771671364131297">"डेमो मोड में फ़ैक्टरी रीसेट के लिए पासवर्ड डालें"</string>
     <string name="retail_demo_reset_next" msgid="8356731459226304963">"आगे"</string>
diff --git a/packages/SettingsLib/res/values-hr/arrays.xml b/packages/SettingsLib/res/values-hr/arrays.xml
index 5deba6f..4d0cd2e 100644
--- a/packages/SettingsLib/res/values-hr/arrays.xml
+++ b/packages/SettingsLib/res/values-hr/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (zadano)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Upotreba odabira sustava (zadano)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Omogućivanje izbornih kodeka"</item>
-    <item msgid="3304843301758635896">"Onemogućivanje izbornih kodeka"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Upotreba odabira sustava (zadano)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Omogućivanje izbornih kodeka"</item>
-    <item msgid="741805482892725657">"Onemogućivanje izbornih kodeka"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Upotreba odabira sustava (zadano)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 371dedc..c244f31 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -28,15 +28,24 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Niste povezani jer je mreža loše kvalitete"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Povezivanje s Wi-Fi-jem nije uspjelo"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problem u autentifikaciji"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Povezivanje nije uspjelo"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Povezivanje s aplikacijom \"<xliff:g id="AP_NAME">%1$s</xliff:g>\" nije uspjelo"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Provjerite zaporku i pokušajte ponovo"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Nije u rasponu"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Neće se povezati automatski"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Nema pristupa internetu"</string>
-    <string name="saved_network" msgid="4352716707126620811">"Spremljeno: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="saved_network" msgid="4352716707126620811">"Spremila aplik. <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatski povezan putem %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatski povezan putem ocjenjivača mreže"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Povezano putem %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupno putem %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Povezano, bez interneta"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Vrlo sporo"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Sporo"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"U redu"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Srednje"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Brzo"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Vrlo brzo"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Niste povezani"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Isključivanje…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Povezivanje…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Povezano (bez medija)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Povezano (bez pristupa porukama)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Povezano (bez telefona ili medija)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Povezano, baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Povezano (bez telefona), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Povezano (bez medija), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Povezano (bez telefona i medija), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medijski zvuk"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Zvuk telefona"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonski pozivi"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prijenos datoteke"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Ulazni uređaj"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Pristup internetu"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Dijeljenje kontakata"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Upotrijebi za dijeljenje kontakata"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Dijeljenje internetske veze"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Pristup porukama"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"SMS-ovi"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Pristup SIM-u"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Upotrebljavaj visokokvalitetan audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Upotrebljavaj visokokvalitetan audio"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Povezano s medijskim zvukom"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Povezano sa telefonskim zvukom"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Povezano s poslužiteljem za prijenos datoteka"</string>
@@ -152,7 +165,7 @@
     <string name="tethering_settings_not_available" msgid="6765770438438291012">"Postavke dijeljenja veze nisu dostupne ovom korisniku"</string>
     <string name="apn_settings_not_available" msgid="7873729032165324000">"Postavke pristupne točke nisu dostupne ovom korisniku"</string>
     <string name="enable_adb" msgid="7982306934419797485">"Otklanjanje pogrešaka putem USB-a"</string>
-    <string name="enable_adb_summary" msgid="4881186971746056635">"Otklanjanje pogrešaka s priključenim USB-om"</string>
+    <string name="enable_adb_summary" msgid="4881186971746056635">"Otklanjanje pogrešaka putem USB-a"</string>
     <string name="clear_adb_keys" msgid="4038889221503122743">"Opoziv autorizacija za otklanjanje pogrešaka putem USB-a"</string>
     <string name="bugreport_in_power" msgid="7923901846375587241">"Prečac izvješća o pogreškama"</string>
     <string name="bugreport_in_power_summary" msgid="1778455732762984579">"Prikaži gumb u izborniku napajanja za izradu izvješća o programskim pogreškama"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aktivni prijelaz s Wi‑Fi na mob. mrežu"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvijek dopusti slobodno traženje Wi-Fi mreže"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci uvijek aktivni"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardversko ubrzanje za modemsko povezivanje"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogući apsolutnu glasnoću"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Omogući zvuk zvona unutar pojasne širine"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verzija AVRCP-a za Bluetooth"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Dopusti probne lokacije"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Omogući pregled atributa prikaza"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Neka mobilni podaci uvijek budu aktivni, čak i kada je Wi‑Fi aktivan (za brzo prebacivanje s jedne na drugu mrežu)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Upotreba hardverskog ubrzanja za modemsko povezivanje ako je dostupno"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Omogućiti otklanjanje pogrešaka putem USB-a?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Otklanjanje pogrešaka putem USB-a namijenjeno je samo u razvojne svrhe. Može se upotrijebiti za kopiranje podataka s računala na uređaj i obrnuto, instalaciju aplikacija na uređaju bez obavijesti i za čitanje dnevničkih zapisa."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Želite li opozvati pristup uklanjanju pogrešaka putem USB-a sa svih računala koja ste prethodno autorizirali?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekcija boje"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova je značajka eksperimentalna i može utjecati na performanse."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Premošćeno postavkom <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Još <xliff:g id="TIME">%1$s</xliff:g> do potpune napunjenosti"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Još <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – preostalo je približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – još <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Još otprilike <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Još otprilike <xliff:g id="TIME">^1</xliff:g> na temelju vaše upotrebe"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Još <xliff:g id="TIME">^1</xliff:g> do potpune napunjenosti"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Još <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Još <xliff:g id="TIME">^1</xliff:g> na temelju vaše upotrebe"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – preostalo je približno <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – još otprilike <xliff:g id="TIME">^2</xliff:g> na temelju vaše upotrebe"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – još <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> do potpune napunjenosti"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"punjenje"</string>
@@ -340,7 +358,7 @@
     <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>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instalacija nepoznatih aplikacija"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"Instalacija nepoznatih apl."</string>
     <string name="home" msgid="3256884684164448244">"Početni zaslon postavki"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-hu/arrays.xml b/packages/SettingsLib/res/values-hu/arrays.xml
index 81d69d0..a361d3e 100644
--- a/packages/SettingsLib/res/values-hu/arrays.xml
+++ b/packages/SettingsLib/res/values-hu/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (alapértelmezett)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Rendszerérték (alapértelmezett)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Nem kötelező kodekek engedélyezése"</item>
-    <item msgid="3304843301758635896">"Nem kötelező kodekek letiltása"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Rendszerérték (alapértelmezett)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Engedélyezi a nem kötelező kodekeket"</item>
-    <item msgid="741805482892725657">"Letiltja a nem kötelező kodekeket"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Rendszerérték (alapértelmezett)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index c4c342c..1cb9ef6 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Nem kapcsolódik a hálózat rossz minősége miatt"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi-kapcsolati hiba"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Azonosítási probléma"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Nem lehet csatlakozni"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Nem lehet csatlakozni a(z) „<xliff:g id="AP_NAME">%1$s</xliff:g>” hálózathoz"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Ellenőrizze a jelszót, majd próbálkozzon újra"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Hatókörön kívül"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nem csatlakozik automatikusan"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Nincs internet-hozzáférés"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Csatlakozva a következőn keresztül: %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Elérhető a következőn keresztül: %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Csatlakozva, nincs internetelérés"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Nagyon lassú"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lassú"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Rendben"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Közepes"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Gyors"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Nagyon gyors"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Szétkapcsolva"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Szétkapcsolás..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Csatlakozás…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Csatlakoztatva (nincs hordozó)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Csatlakoztatva (nincs üzenet-hozzáférés)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Csatlakoztatva (nincs telefon vagy hordozó)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Csatlakoztatva; az akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Csatlakoztatva (telefonhang nélkül); az akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Csatlakoztatva (médiahang nélkül); az akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Csatlakoztatva (telefon- vagy médiahang nélkül); az akkumulátor töltöttségi szintje:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Média audió"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefon hangja"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonhívások"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fájlátvitel"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Beviteli eszköz"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetelérés"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Névjegyek megosztása"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Használja a névjegyek megosztására"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internetkapcsolat megosztása"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Üzenet-hozzáférés"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Szöveges üzenetek"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-elérés"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Jó audiominőség használata: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Jó audiominőség használata"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Csatlakoztatva az eszköz hangjához"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Csatlakoztatva a telefon hangjához"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Csatlakozva a fájlküldő szerverhez"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresszív Wi‑Fi–mobilhálózat átadás"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi-roaming ellenőrzésének engedélyezése mindig"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"A mobilhálózati kapcsolat mindig aktív"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Internetmegosztás hardveres gyorsítása"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Abszolút hangerő funkció letiltása"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Sávon belüli csörgetés engedélyezése"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"A Bluetooth AVRCP-verziója"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Helyutánzatok engedélyezése"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Nézetattribútum vizsgálatának engedélyezése"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"A mobiladat-kapcsolat mindig maradjon aktív, még akkor is, ha a Wi‑Fi aktív (a gyors hálózatváltás érdekében)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Az internetmegosztás hardveres gyorsításának használata, amikor lehetséges"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Engedélyezi az USB hibakeresést?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Az USB hibakeresés fejlesztési célokat szolgál. Használhatja adatok másolására a számítógép és a készülék között, alkalmazások a készülékre való értesítés nélküli telepítésére és naplózási adatok olvasására."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Visszavonja a hozzáférést az USB-s hibakereséshez az összes számítógépről, ahol korábban engedélyezte azt?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Színkorrekció"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ez egy kísérleti funkció, és hatással lehet a teljesítményre."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Felülírva erre: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Körülbelül <xliff:g id="TIME">%1$s</xliff:g> maradt hátra"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> a teljes töltöttségig"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> van hátra"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - körülbelül <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Körülbelül <xliff:g id="TIME">^1</xliff:g> maradt hátra"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Körülbelül <xliff:g id="TIME">^1</xliff:g> van hátra az eszköz igénybevétele alapján"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> a teljes töltöttségig"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> van hátra"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> van hátra az eszköz igénybevétele alapján"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - körülbelül <xliff:g id="TIME">^2</xliff:g> van hátra"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – körülbelül <xliff:g id="TIME">^2</xliff:g> van hátra az eszköz igénybevétele alapján"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> van hátra"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> a teljes feltöltésig"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> a teljes feltöltésig"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Ismeretlen"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Töltés"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"töltés"</string>
@@ -340,7 +358,7 @@
     <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>
-    <string name="install_other_apps" msgid="6986686991775883017">"Ismeretlen alkalmazások telepítése"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"Új alkalmazások telepítése"</string>
     <string name="home" msgid="3256884684164448244">"Beállítások kezdőlapja"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml
index 22de938..cf4ade6 100644
--- a/packages/SettingsLib/res/values-hy/arrays.xml
+++ b/packages/SettingsLib/res/values-hy/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (կանխադրված)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Օգտագործել համակարգի կարգավորումը (կանխադրված)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Միացնել լրացուցիչ կոդեկները"</item>
-    <item msgid="3304843301758635896">"Անջատել լրացուցիչ կոդեկները"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Օգտագործել համակարգի կարգավորումը (կանխադրված)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Միացնել լրացուցիչ կոդեկները"</item>
-    <item msgid="741805482892725657">"Անջատել լրացուցիչ կոդեկները"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Օգտագործել համակարգի կարգավորումը (կանխադրված)"</item>
     <item msgid="8895532488906185219">"44,1 կՀց"</item>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 0c4533e..5b82dc3 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Չի կապակցվել ցանցի թույլ ազդանշանի պատճառով"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi կապի ձախողում"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Նույնականացման խնդիր"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Կապ չկա"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Հնարավոր չէ միանալ «<xliff:g id="AP_NAME">%1$s</xliff:g>»-ին"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Ստուգեք գաղտնաբառը և նորից փորձեք"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Ընդգրկույթից դուրս է"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Չի միանա ավտոմատ"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Ինտերնետ կապ չկա"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Կապակցված է %1$s-ի միջոցով"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Հասանելի է %1$s-ի միջոցով"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Կապակցված է առանց համացանցի"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Շատ դանդաղ"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Դանդաղ"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Հաստատել"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Միջին"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Արագ"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Շատ արագ"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Անջատված է"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Անջատվում է..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Միանում է..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Միացված է (առանց մեդիա)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Միացված է (հաղորդագրությանը մուտք չկա)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Միացված է (առանց հեռախոսի և մեդիայի)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Միացված է, մարտկոցի լիցք՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Միացած է (հեռախոս չկա), մարտկոցի լիցք՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Միացված է (մեդիա չկա), մարտկոցի լիցք՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Միացված է (հեռախոս կամ մեդիա չկա), մարտկոցի լիցք՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Մեդիա աուդիո"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Հեռախոսի աուդիո"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Հեռախոսազանգեր"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Ֆայլերի փոխանցում"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Ներմուծման սարք"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Ինտերնետի մուտք"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Կոնտակտի համօգտագործում"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Օգտագործել կոնտակտի համօգտագործման համար"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Ինտերնետ կապի տարածում"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Մուտք հաղորդագրություն"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"SMS հաղորդագրություններ"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM քարտի հասանելիություն"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Օգտագործել բարձրորակ ձայն՝ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Օգտագործել բարձրորակ ձայն"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD աուդիո՝ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD աուդիո"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Միացված է մեդիա աուդիոյին"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Միացված է հեռախոսի ձայնային տվյալներին"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Միացված է ֆայլերի փոխանցման սերվերին"</string>
@@ -99,7 +112,7 @@
     <string name="managed_user_title" msgid="8109605045406748842">"Բոլոր աշխատանքային հավելվածները"</string>
     <string name="user_guest" msgid="8475274842845401871">"Հյուր"</string>
     <string name="unknown" msgid="1592123443519355854">"Անհայտ"</string>
-    <string name="running_process_item_user_label" msgid="3129887865552025943">"Օտատեր՝ <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="running_process_item_user_label" msgid="3129887865552025943">"Օգտատեր՝ <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="313159469856372621">"Որոշ կանխադրված կարգավորումներ կան"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"Կանխադրված կարգավորումներ չկան"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Տեքստի հնչեցման կարգավորումներ"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi-ից կտրուկ անցում բջջային ինտերնետի"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Միշտ թույլատրել Wi‑Fi ռոումինգի որոնումը"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Բջջային ինտերնետը միշտ ակտիվ է"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Սարքակազմի արագացման միացում"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Անջատել ձայնի բացարձակ ուժգնությունը"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Միացնել ներխմբային զանգը"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP տարբերակը"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Թույլ տալ կեղծ տեղադրություններ"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Միացնել ցուցադրման հատկանիշների ստուգումը"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Միշտ ակտիվացրած պահել բջջային տվյալները, նույնիսկ Wi‑Fi-ը միացրած ժամանակ (ցանցերի միջև արագ փոխարկման համար):"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Օգտագործել սարքակազմի արագացման միացումը, եթե հասանելի է"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Թույլատրե՞լ USB-ի վրիպազերծումը:"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB վրիպազերծումը միայն ծրագրավորման նպատակների համար է: Օգտագործեք այն ձեր համակարգչից տվյալները ձեր սարք պատճենելու համար, առանց ծանուցման ձեր սարքի վրա ծրագրեր տեղադրելու և տվյալների մատյանը ընթերցելու համար:"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Փակե՞լ USB-ի վրիպազերծման մուտքը` անջատելով այն բոլոր համակարգիչներից, որտեղ նախկինում թույլատրել էիք:"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Գունաշտկում"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Սա փորձնական գործառույթ է և կարող է ազդել սարքի աշխատանքի վրա:"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Գերազանցված է <xliff:g id="TITLE">%1$s</xliff:g>-ից"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Մնացել է մոտ <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Մինչև լրիվ լիցքավորումը մնացել է <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Մնացել է <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – մնացել է մոտ <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - մնացել է <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Մնացել է մոտ <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Մնացել է մոտ <xliff:g id="TIME">^1</xliff:g>՝ օգտագործման եղանակից կախված"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Մինչև լրիվ լիցքավորումը մնացել է <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Մնացել է <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Մնացել է <xliff:g id="TIME">^1</xliff:g>՝ օգտագործման եղանակից կախված"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – մնացել է մոտ <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - մնացել է մոտ <xliff:g id="TIME">^2</xliff:g>՝ օգտագործման եղանակից կախված"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - մնացել է <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> մինչև լրիվ լիցքավորումը"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Անհայտ"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Լիցքավորում"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"լիցքավորում"</string>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index 7f02a6a..1a7e132 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Gunakan Pilihan Sistem (Default)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Aktifkan Codec Opsional"</item>
-    <item msgid="3304843301758635896">"Nonaktifkan Codec Opsional"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Gunakan Pilihan Sistem (Default)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Aktifkan Codec Opsional"</item>
-    <item msgid="741805482892725657">"Nonaktifkan Codec Opsional"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Gunakan Pilihan Sistem (Default)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 28e9826..a8dd4c2 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Tidak tersambung karena jaringan berkualitas rendah"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Kegagalan Sambungan Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Masalah autentikasi"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Tidak dapat tersambung"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Tidak dapat tersambung ke \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Periksa sandi dan coba lagi"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Tidak dalam jangkauan"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Tidak akan tersambung otomatis"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Tidak ada akses internet"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Terhubung melalui %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Tersambung, tidak ada internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Sangat Lambat"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lambat"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Oke"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Sedang"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Cepat"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Sangat Cepat"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Sambungan terputus"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Memutus sambungan..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Menyambung…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Terhubung (kecuali media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Tersambung (tidak ada akses pesan)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Terhubung (bukan telepon atau media)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Terhubung, baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Terhubung (tanpa ponsel), baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Terhubung (tanpa media), baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Terhubung (tanpa ponsel atau media), baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio media"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audio telepon"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Panggilan telepon"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfer file"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Perangkat masukan"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Akses Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Berbagi kontak"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Gunakan untuk berbagi kontak"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Berbagi sambungan internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Akses Pesan"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"SMS"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Akses SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Gunakan audio berkualitas tinggi: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Gunakan audio berkualitas tinggi"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Tersambung ke media audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Tersambung ke audio ponsel"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Sambungkan ke server transfer file"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Pengalihan Wi-Fi Agresif ke seluler"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Selalu izinkan Pemindaian Roaming Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Data seluler selalu aktif"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Akselerasi hardware tethering"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Nonaktifkan volume absolut"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Aktifkan dering in-band"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versi AVRCP Bluetooth"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Mengizinkan lokasi palsu"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Aktifkan inspeksi atribut tampilan"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Selalu aktifkan data seluler, meski Wi-Fi aktif (agar jaringan beralih dengan cepat)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Gunakan akselerasi hardware tethering jika tersedia"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Izinkan melakukan debug USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Debugging USB dimaksudkan untuk tujuan pengembangan saja. Gunakan untuk menyalin data antara komputer dan perangkat Anda, memasang apl pada perangkat tanpa notifikasi, dan membaca data log."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Cabut akses ke debug USB dari semua komputer yang telah Anda otorisasi sebelumnya?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Koreksi warna"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Fitur ini bersifat eksperimental dan dapat memengaruhi kinerja."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Digantikan oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Sekitar <xliff:g id="TIME">%1$s</xliff:g> lagi"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> lagi hingga terisi penuh"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> tersisa"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira <xliff:g id="TIME">%2$s</xliff:g> lagi"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tersisa"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Sekitar <xliff:g id="TIME">^1</xliff:g> lagi"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Kira-kira <xliff:g id="TIME">^1</xliff:g> lagi berdasarkan penggunaan Anda"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> lagi hingga terisi penuh"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> tersisa"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> lagi berdasarkan penggunaan Anda"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - kira-kira <xliff:g id="TIME">^2</xliff:g> lagi"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - kira-kira <xliff:g id="TIME">^2</xliff:g> lagi berdasarkan penggunaan Anda"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> tersisa"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi terisi penuh"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> lagi terisi penuh"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Tidak diketahui"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Mengisi daya"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"mengisi daya baterai"</string>
diff --git a/packages/SettingsLib/res/values-is/arrays.xml b/packages/SettingsLib/res/values-is/arrays.xml
index 7f6141d..f1453ab 100644
--- a/packages/SettingsLib/res/values-is/arrays.xml
+++ b/packages/SettingsLib/res/values-is/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (sjálfgefið)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Nota val kerfisins (sjálfgefið)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Gera valfrjálsa kóðara virka"</item>
-    <item msgid="3304843301758635896">"Gera valfrjálsa kóðara óvirka"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Nota val kerfisins (sjálfgefið)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Gera valfrjálsa kóðara virka"</item>
-    <item msgid="741805482892725657">"Gera valfrjálsa kóðara óvirka"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Nota val kerfisins (sjálfgefið)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 6bc3319..7f541ce 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Tenging er ekki til staðar því nettengingin er léleg"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi-tengingarvilla"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Vandamál við auðkenningu"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Ekki tókst að tengjast"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Ekki tókst að tengjast við „<xliff:g id="AP_NAME">%1$s</xliff:g>“"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Athugaðu aðgangsorðið og reyndu aftur"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Ekkert samband"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Mun ekki tengjast sjálfkrafa"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Enginn netaðgangur"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Tengt í gegnum %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Í boði í gegnum %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Tengt, enginn internetaðgangur"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Mjög hægt"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Hægt"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Í lagi"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Miðlungshratt"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Hratt"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Mjög hratt"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Aftengt"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Aftengist…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Tengist…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Tengt (ekki efnisspilun)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Tengt (enginn skilaboðaaðgangur)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Tengt (ekki sími eða efnisspilun)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Tengt, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlaða"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Tengt (ekki sími), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlaða"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Tengt (ekki efnisspilun), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlaða"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Tengt (ekki sími eða efnisspilun), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlaða"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Hljóð efnis"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Hljóð síma"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Símtöl"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Skráaflutningur"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Inntakstæki"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetaðgangur"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Deiling tengiliða"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Nota til að deila tengiliðum"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Deiling nettengingar"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Skilaboðaaðgangur"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Textaskilaboð"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Aðgangur að SIM-korti"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Nota hágæðahljóð: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Nota hágæðahljóð"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-hljóð: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-hljóð"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Tengt við hljóðspilun efnis"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Tengt við hljóð símans"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Tengt við skráaflutningsþjón"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Hröð skipti úr Wi‑Fi í farsímagögn"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Leyfa alltaf reikileit með Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Alltaf kveikt á farsímagögnum"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Vélbúnaðarhröðun fyrir tjóðrun"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Slökkva á samstillingu hljóðstyrks"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Leyfa símtöl á sömu rás"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-útgáfa"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Leyfa gervistaðsetningar"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Virkja yfirlit skoðunar eiginda"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Hafa alltaf kveikt á farsímagögnum, líka þegar kveikt er á Wi-Fi (til að skipta megi hratt milli kerfa)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Nota vélbúnaðarhröðun fyrir tjóðrun ef það býðst"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Leyfa USB-villuleit?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-villuleit er aðeins ætluð til nota í þróunarskyni. Hana má nota til að afrita gögn á milli tölvu og tækis, setja forrit upp í tækinu án tilkynninga og lesa annálagögn."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Afturkalla aðgang að USB-villuleit í öllum tölvum sem þú hefur áður veitt heimild?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Litaleiðrétting"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Þessi eiginleiki er á tilraunastigi og getur haft áhrif á frammistöðu."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Hnekkt af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Um það bil <xliff:g id="TIME">%1$s</xliff:g> eftir"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> þar til hleðslu er lokið"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> eftir"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – um <xliff:g id="TIME">%2$s</xliff:g> eftir"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> eftir"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Um það bil <xliff:g id="TIME">^1</xliff:g> eftir"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"U.þ.b. <xliff:g id="TIME">^1</xliff:g> eftir miðað við notkun þína"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> þar til hleðslu er lokið"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> eftir"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> eftir miðað við notkun þína"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – um <xliff:g id="TIME">^2</xliff:g> eftir"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – u.þ.b. <xliff:g id="TIME">^2</xliff:g> eftir miðað við notkun þína"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> eftir"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> þar til fullri hleðslu er náð"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> þar til fullri hleðslu er náð"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Óþekkt"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Í hleðslu"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"í hleðslu"</string>
diff --git a/packages/SettingsLib/res/values-it/arrays.xml b/packages/SettingsLib/res/values-it/arrays.xml
index cb6d5f7..6de7937 100644
--- a/packages/SettingsLib/res/values-it/arrays.xml
+++ b/packages/SettingsLib/res/values-it/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (predefinita)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Usa selezione di sistema (predefinita)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Attiva codec facoltativi"</item>
-    <item msgid="3304843301758635896">"Disattiva codec facoltativi"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Usa selezione di sistema (predefinita)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Attiva codec facoltativi"</item>
-    <item msgid="741805482892725657">"Disattiva codec facoltativi"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Usa selezione di sistema (predefinita)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index dee6b429..5598d87 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Impossibile connettersi a causa della bassa qualità della rete"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Errore connessione Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problema di autenticazione"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Impossibile stabilire una connessione"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Impossibile connettersi a \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Controlla la password e riprova"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Fuori portata"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Non verrà eseguita la connessione automatica"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Nessun accesso a Internet"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Collegato tramite %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponibile tramite %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connesso senza Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Molto lenta"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Media"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Veloce"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Molto veloce"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Disconnesso"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Disconnessione..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Connessione..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Collegato (contenuti multimed. esclusi)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connesso (nessun accesso ai messaggi)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Collegato (telef. o conten. mult. esclusi)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connesso, batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connesso (telefono escluso), batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connesso (contenuti multimediali esclusi), batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connesso (telefono o contenuti multimediali esclusi), batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimediale"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audio telefono"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonate"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Trasferimento file"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo di input"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Accesso Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Condivisione contatti"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Usa per condivisione contatti"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Condivisione connessione Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Accesso ai messaggi"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"SMS"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Accesso alla SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Utilizza audio di alta qualità: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Utilizza audio di alta qualità"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Collegato ad audio media"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Collegato ad audio telefono"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Collegato al server di trasferimento file"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi aggressivo per passaggio a cellulare"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Consenti sempre scansioni roaming Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dati mobili sempre attivi"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering accelerazione hardware"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disattiva volume assoluto"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Attiva suoneria in banda"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versione Bluetooth AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Consenti posizioni fittizie"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Attiva controllo attributi visualizzazione"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantieni sempre i dati cellulare attivi, anche se il Wi‑Fi è attivo (per un passaggio fra reti rapido)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Utilizza l\'accelerazione hardware per il tethering se disponibile"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Consentire debug USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Il debug USB è solo a scopo di sviluppo. Utilizzalo per copiare dati tra il computer e il dispositivo, per installare applicazioni sul tuo dispositivo senza notifica e per leggere i dati dei log."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revocare l\'accesso al debug USB da tutti i computer precedentemente autorizzati?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correzione del colore"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Questa funzione è sperimentale e potrebbe influire sulle prestazioni."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valore sostituito da <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Tempo approssimativo rimanente: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tempo rimanente alla carica completa: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tempo rimanente: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ancora circa <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tempo rimanente: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Tempo approssimativo rimanente: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Tempo rimanente in base al tuo utilizzo: <xliff:g id="TIME">^1</xliff:g> circa"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tempo rimanente alla carica completa: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tempo rimanente: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Tempo rimanente in base al tuo utilizzo: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - ancora circa <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - Tempo rimanente in base al tuo utilizzo: <xliff:g id="TIME">^2</xliff:g> circa"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - Tempo rimanente: <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> alla carica completa"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Sconosciuta"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"In carica"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"in carica"</string>
diff --git a/packages/SettingsLib/res/values-iw/arrays.xml b/packages/SettingsLib/res/values-iw/arrays.xml
index 917f710..ab4e0e1 100644
--- a/packages/SettingsLib/res/values-iw/arrays.xml
+++ b/packages/SettingsLib/res/values-iw/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"‏AVRCP 1.4 (ברירת המחדל)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"שימוש בבחירת המערכת (ברירת המחדל)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"‏הפעלה של Codecs אופציונליים"</item>
-    <item msgid="3304843301758635896">"‏השבתה של Codecs אופציונליים"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"השתמש בבחירת המערכת (ברירת המחדל)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"‏הפעלה של Codecs אופציונליים"</item>
-    <item msgid="741805482892725657">"‏השבתה של Codecs אופציונליים"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"שימוש בבחירת המערכת (ברירת המחדל)"</item>
     <item msgid="8895532488906185219">"44.1 קילו-הרץ"</item>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 9371d27..ffbabb5 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"אין חיבור לרשת, כי איכות הרשת נמוכה"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"‏כשל בחיבור Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"בעיית אימות"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"לא ניתן להתחבר"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"לא ניתן להתחבר אל <xliff:g id="AP_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"בדוק את הסיסמה ונסה שוב"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"מחוץ לטווח"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"לא יתבצע חיבור באופן אוטומטי"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"אין גישה לאינטרנט"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"‏מחובר דרך %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"‏זמינה דרך %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"מחובר. אין אינטרנט"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"איטית מאוד"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"איטית"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"אישור"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"בינונית"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"מהירה"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"מהירה מאוד"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"מנותק"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"מתנתק..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"מתחבר ..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"מחובר (ללא מדיה)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"מחובר (אין גישה להודעות)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"מחובר (ללא טלפון או מדיה)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"מחובר, הסוללה ב-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"מחובר (ללא טלפון), הסוללה ב-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"מחובר (ללא מדיה), הסוללה ב-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"מחובר (ללא טלפון וללא מדיה), הסוללה ב-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"אודיו של מדיה"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"אודיו של טלפון"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"שיחות טלפון"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"העברת קבצים"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"מכשיר קלט"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"גישה לאינטרנט"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"שיתוף אנשי קשר"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"השתמש עבור שיתוף אנשי קשר"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"שיתוף חיבור לאינטרנט"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"גישה להודעות"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"הודעות טקסט"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"‏גישה ל-SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"השתמש באודיו באיכות גבוהה: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"השתמש באודיו באיכות גבוהה"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"‏אודיו באיכות HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"‏אודיו באיכות HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"מחובר לאודיו של מדיה"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"מחובר לאודיו של הטלפון"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"מחובר לשרת העברת קבצים"</string>
@@ -128,8 +141,8 @@
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"השק הגדרות מנוע"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"מנוע מועדף"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"כללי"</string>
-    <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"אפס את גובה צליל הדיבור"</string>
-    <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"אפס את גובה הצליל שבו מושמע הטקסט לברירת המחדל."</string>
+    <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"איפוס של גובה צליל הדיבור"</string>
+    <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"איפוס גובה הצליל שבו מושמע הטקסט לברירת המחדל."</string>
   <string-array name="tts_rate_entries">
     <item msgid="6695494874362656215">"איטי מאוד"</item>
     <item msgid="4795095314303559268">"איטי"</item>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"‏העברה אגרסיבית מ-Wi‑Fi לרשת סלולרית"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏התר תמיד סריקות נדידה של Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"חבילת הגלישה פעילה תמיד"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"שיפור מהירות באמצעות חומרה לצורך שיתוף אינטרנט בין ניידים"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"השבת עוצמת קול מוחלטת"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"‏הפעל צלצולים בערוץ ה-Bluetooth‏ (in-band ringing)"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"‏Bluetooth גרסה AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"אפשר מיקומים מדומים"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"אפשר בדיקת תכונת תצוגה"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"‏השאר את חבילת הגלישה פעילה תמיד, גם כש-Wi‑Fi פעיל (למעבר מהיר בין רשתות)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"אם השירות זמין, יש להשתמש בשיפור מהירות באמצעות חומרה לצורך שיתוף אינטרנט בין ניידים"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"‏לאפשר ניפוי באגים של USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"‏ניפוי באגים באמצעות USB מיועד למטרות פיתוח בלבד. השתמש בו להעתקת נתונים בין המחשב והמכשיר שלך, להתקנת אפליקציות במכשיר ללא התראה ולקריאת נתוני יומן."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"‏האם לבטל את הגישה לניפוי ב-USB מכל המחשבים שהענקת להם בעבר הרשאה?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"תיקון צבע"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"תכונה זו היא ניסיונית ועשויה להשפיע על הביצועים."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"נעקף על ידי <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"עוד <xliff:g id="TIME">%1$s</xliff:g> בקירוב"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> עד לטעינה מלאה"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"נותרו <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - הזמן הנותר: בערך <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - נותרו <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"עוד <xliff:g id="TIME">^1</xliff:g> בקירוב"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"על סמך השימוש במכשיר, הסוללה תתרוקן בעוד <xliff:g id="TIME">^1</xliff:g>, בקירוב"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> עד לטעינה מלאה"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"נותרו <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"על סמך השימוש במכשיר, הסוללה תתרוקן בעוד <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - הזמן הנותר: בערך <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - על סמך השימוש במכשיר, הסוללה תתרוקן בעוד <xliff:g id="TIME">^2</xliff:g>, בקירוב"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - נותרו <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד לטעינה מלאה"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> עד לטעינה מלאה"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"לא ידוע"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"טוען"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"בטעינה"</string>
@@ -340,7 +358,7 @@
     <string name="disabled" msgid="9206776641295849915">"מושבת"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"מורשה"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"לא מורשה"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"להתקין גם אם לא מוכר?"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"להתקין גם אם לא מוכר לך?"</string>
     <string name="home" msgid="3256884684164448244">"דף הבית של ההגדרות"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index 779e2b1..150081c 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -23,7 +23,7 @@
   <string-array name="wifi_status">
     <item msgid="1922181315419294640"></item>
     <item msgid="8934131797783724664">"スキャン中..."</item>
-    <item msgid="8513729475867537913">"接続中..."</item>
+    <item msgid="8513729475867537913">"接続処理中..."</item>
     <item msgid="515055375277271756">"認証中..."</item>
     <item msgid="1943354004029184381">"IPアドレスを取得中..."</item>
     <item msgid="4221763391123233270">"接続済み"</item>
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4(デフォルト)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"システムの選択(デフォルト)を使用"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"オプションのコーデックの有効化"</item>
-    <item msgid="3304843301758635896">"オプションのコーデックの無効化"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"システムの選択(デフォルト)を使用"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"オプションのコーデックを有効にします"</item>
-    <item msgid="741805482892725657">"オプションのコーデックを無効にします"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"システムの選択(デフォルト)を使用"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index eb4cc10e..ba12e68 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"ネットワークの品質が低いため、接続されていません"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi接続エラー"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"認証に問題"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"接続できません"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"「<xliff:g id="AP_NAME">%1$s</xliff:g>」に接続できません"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"パスワードを確認して、もう一度お試しください"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"圏外"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"自動的に接続されません"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"インターネットに接続していません"</string>
@@ -37,27 +40,37 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s経由で接続"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s経由で使用可能"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"接続済み、インターネットは利用できません"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"とても遅い"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"遅い"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"普通"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"速い"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"とても速い"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"切断"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"切断中..."</string>
-    <string name="bluetooth_connecting" msgid="8555009514614320497">"接続中..."</string>
+    <string name="bluetooth_connecting" msgid="8555009514614320497">"接続処理中..."</string>
     <string name="bluetooth_connected" msgid="6038755206916626419">"接続"</string>
     <string name="bluetooth_pairing" msgid="1426882272690346242">"ペアとして設定中..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"接続済み(電話を除く)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"接続済み(メディアを除く)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"接続済み(メッセージへのアクセスなし)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"接続済み(電話/メディアを除く)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"接続済み、電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"接続済み(スマートフォンを除く)、電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"接続済み(メディアを除く)、電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"接続済み(スマートフォンやメディアを除く)、電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"メディアの音声"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"電話の音声"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"電話"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ファイル転送"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"入力デバイス"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"インターネットアクセス"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"連絡先の共有"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"連絡先の共有に使用"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"インターネット接続の共有"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"メッセージへのアクセス"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"テキスト メッセージ"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIMアクセス"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"高品質音声を使用: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"高品質音声を使用"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD オーディオ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD オーディオ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"メディアの音声に接続"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"携帯電話の音声に接続"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ファイル転送サーバーに接続"</string>
@@ -91,7 +104,7 @@
     <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"削除したアプリケーション"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"削除されたアプリとユーザー"</string>
-    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USBテザリング"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB テザリング"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"ポータブルアクセスポイント"</string>
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetoothテザリング"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"テザリング"</string>
@@ -100,7 +113,7 @@
     <string name="user_guest" msgid="8475274842845401871">"ゲスト"</string>
     <string name="unknown" msgid="1592123443519355854">"不明"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"ユーザー: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
-    <string name="launch_defaults_some" msgid="313159469856372621">"一部デフォルトを設定"</string>
+    <string name="launch_defaults_some" msgid="313159469856372621">"一部デフォルトで設定"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"デフォルトの設定なし"</string>
     <string name="tts_settings" msgid="8186971894801348327">"テキスト読み上げの設定"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"テキスト読み上げの出力"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi を強制的にモバイル接続に切り替える"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fiローミングスキャンを常に許可する"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"モバイルデータを常に ON にする"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"テザリング時のハードウェア アクセラレーション"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"絶対音量を無効にする"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"インバンド リンギングを有効にする"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP バージョン"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"擬似ロケーションを許可する"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"表示属性検査を有効にする"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi‑Fiが(ネットワークの自動切り替えで)ONのときでもモバイルデータが常にONになります。"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"テザリング時にハードウェア アクセラレーションを使用します(使用可能な場合)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USBデバッグを許可しますか?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USBデバッグは開発専用に設計されています。パソコンと端末の間でデータをコピーする場合や、アプリを通知なしで端末にインストールする場合、ログデータを読み取る場合に使用できます。"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"以前に許可したすべてのパソコンからのUSBデバッグへのアクセスを取り消しますか?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色補正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"この機能は試験運用機能であり、パフォーマンスに影響することがあります。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g>によって上書き済み"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"あと約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"フル充電まであと <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g>(残り時間)"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 残り約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>(残り時間)"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"あと約 <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"残り時間: 約 <xliff:g id="TIME">^1</xliff:g>(使用状況に基づく)"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"フル充電まであと <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g>(残り時間)"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"残り時間: <xliff:g id="TIME">^1</xliff:g>(使用状況に基づく)"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - 残り約 <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - 残り時間: 約 <xliff:g id="TIME">^2</xliff:g>(使用状況に基づく)"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - フル充電まで <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"不明"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"充電しています"</string>
diff --git a/packages/SettingsLib/res/values-ka/arrays.xml b/packages/SettingsLib/res/values-ka/arrays.xml
index cf2113b6..a0f10c8 100644
--- a/packages/SettingsLib/res/values-ka/arrays.xml
+++ b/packages/SettingsLib/res/values-ka/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (ნაგულისხმევი)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"სისტემის არჩეულის გამოყენება (ნაგულისხმევი)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"არასავალდებულო კოდეკების ჩართვა"</item>
-    <item msgid="3304843301758635896">"არასავალდებულო კოდეკების გათიშვა"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"სისტემის არჩეულის გამოყენება (ნაგულისხმევი)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"არასავალდებულო კოდეკების ჩართვა"</item>
-    <item msgid="741805482892725657">"არასავალდებულო კოდეკების გათიშვა"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"სისტემის არჩეულის გამოყენება (ნაგულისხმევი)"</item>
     <item msgid="8895532488906185219">"44,1 კჰც"</item>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index e52bf30..dd70c65 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"არ არის დაკავშირებული დაბალი ხარისხის ქსელის გამო"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi კავშირის შეფერხება"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"ავთენტიკაციის პრობლემა"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"დაკავშირება ვერ ხერხდება"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"<xliff:g id="AP_NAME">%1$s</xliff:g>-თან დაკავშირება ვერ ხერხდება"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"გადაამოწმეთ პაროლი და ხელახლა ცადეთ"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"არ არის დიაპაზონში"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ავტომატურად დაკავშირება ვერ მოხერხდება"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"ინტერნეტთან კავშირი არ არის"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-ით დაკავშირებული"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"ხელმისაწვდომია %1$s-ით"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"დაკავშირებულია, ინტერნეტის გარეშე"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"ძალიან ნელი"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"ნელი"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"კარგი"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"საშუალო"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"სწრაფი"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"ძალიან სწრაფი"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"კავშირი გაწყვეტილია"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"მიმდინარეობს გათიშვა…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"მიმდინარეობს დაკავშირება…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"მიერთებულია (მედიის გარდა)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"დაკავშირებულია (შეტყობინებაზე წვდომა არ არის)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"დაკავშირება (გარდა ტელეფონისა და მედიისა)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"დაკავშირებულია. ბატარეის დონე: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"დაკავშირებულია (ტელეფონი არ არის). ბატარეის დონე: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"დაკავშირებულია (მედია არ არის). ბატარეის დონე: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"დაკავშირებულია (მედია ან ტელეფონი არ არის). ბატარეის დონე: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"მედია აუდიო"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ტელეფონის აუდიო"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"სატელეფონო ზარები"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ფაილების გადაცემა"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"შეყვანის მოწყობილობა"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ინტერნეტზე წვდომა"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"კონტაქტის გაზიარება"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"კონტაქტის გაზიარებისთვის გამოყენება"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ინტერნეტ კავშირის გაზიარება"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"შეტყობინებებზე წვდომა"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"ტექსტური შეტყობინებები"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM წვდომა"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"მაღალხარისხიანი აუდიოს გამოყენება: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"მაღალხარისხიანი აუდიოს გამოყენება"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD აუდიო: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD აუდიო"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"დაკავშირებულია აუდიო მულტიმედიურ სისტემასთან"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"დაკავშირებულია ტელეფონის აუდიო მოწყობილობასთან"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"დაკავშირებულია ფაილების გადაცემის სერვერთან"</string>
@@ -91,11 +104,11 @@
     <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"აპების წაშლა"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"წაშლილი აპები და მომხმარებლები"</string>
-    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB მოდემი"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB ტეტერინგი"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"პორტატული უსადენო ქსელი"</string>
-    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetooth-მოდემი"</string>
-    <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"მოდემის რეჟიმი"</string>
-    <string name="tether_settings_title_all" msgid="8356136101061143841">"მოდემი და პორტატული უსადენო ქსელი"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetooth ტეტერინგი"</string>
+    <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"ტეტერინგი"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"ტეტერინგი და პორტატული უსადენო ქსელი"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"სამსახურის ყველა აპი"</string>
     <string name="user_guest" msgid="8475274842845401871">"სტუმარი"</string>
     <string name="unknown" msgid="1592123443519355854">"უცნობი"</string>
@@ -149,7 +162,7 @@
     <string name="development_settings_summary" msgid="1815795401632854041">"პარამეტრების დაყენება აპების დეველოპერებისთვის"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"ამ მომხმარებლისთვის დეველოპერის პარამეტრები არ არის ხელმისაწვდომი"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN პარამეტრები ამ მომხმარებლისათვის მიუწვდომელია"</string>
-    <string name="tethering_settings_not_available" msgid="6765770438438291012">"ტეთერინგის პარამეტრები ამ მომხმარებლისათვის მიუწვდომელია"</string>
+    <string name="tethering_settings_not_available" msgid="6765770438438291012">"ტეტერინგის პარამეტრები ამ მომხმარებლისათვის მიუწვდომელია"</string>
     <string name="apn_settings_not_available" msgid="7873729032165324000">"წვდომის წერტილის (APN) პარამეტრები ამ მომხმარებლისათვის მიუწვდომელია"</string>
     <string name="enable_adb" msgid="7982306934419797485">"USB გამართვა"</string>
     <string name="enable_adb_summary" msgid="4881186971746056635">"გამართვის რეჟიმი, როდესაც USB შეერთებულია"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi-ს მობ. ინტერნეტზე აგრესიული გადართვა"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi Roam სკანირების მუდამ დაშვება"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"მობილური ინტერნეტის ყოველთვის გააქტიურება"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ტეტერინგის აპარატურული აჩქარება"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ხმის აბსოლუტური სიძლიერის გათიშვა"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ზოლსშიდა დარეკვის ჩართვა"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth-ის AVRCP-ის ვერსია"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"ფიქტიური მდებარეობების დაშვება"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"ნახვის ატრიბუტის ინსპექტირების ჩართვა"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"მობილური მოწყობილობის მონაცემები ყოველთვის აქტიური დარჩეს, მაშინაც კი, როდესაც Wi-Fi აქტიურია (ქსელის სწრაფი გადართვისთვის)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ტეტერინგის აპარატურული აჩქარების ხელმისაწვდომობის შემთხვევაში გამოყენება"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"ჩაირთოს USB გამართვა?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB გამართვა განკუთვნილია მხოლოდ დეველოპერული მიზნებისთვის. გამოიყენეთ კომპიუტერსა და თქვენ მოწყობილობას შორის მონაცემების გადასატანად, თქვენ მოწყობილობაზე აპების შეტყობინების გარეშე დასაყენებლად და ჟურნალის მონაცემების წასაკითხად."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"გავაუქმოთ ყველა იმ კომპიუტერიდან USB გამართვაზე წვდომა, რომლებიდანაც აქამდე განახორციელეთ შესვლა?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ფერის კორექცია"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ეს ფუნქცია საცდელია და შეიძლება გავლენა იქონიოს ფუნქციონალობაზე."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"უკუგებულია <xliff:g id="TITLE">%1$s</xliff:g>-ის მიერ"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"დარჩა დაახლოებით <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"სრულ დატენვამდე დარჩენილია <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"დარჩენილია <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> — დარჩა დაახლოებით <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> — დარჩენილია <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"დარჩა დაახლოებით <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"დარჩა დაახლოებით <xliff:g id="TIME">^1</xliff:g>, ბატარეის მოხმარების გათვალისწინებით"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"სრულ დატენვამდე დარჩენილია <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"დარჩენილია <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"დარჩა <xliff:g id="TIME">^1</xliff:g>, ბატარეის მოხმარების გათვალისწინებით"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> — დარჩა დაახლოებით <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> — დარჩა დაახლოებით <xliff:g id="TIME">^2</xliff:g>, ბატარეის მოხმარების გათვალისწინებით"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> — დარჩენილია <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> — სრულ დატენვამდე დარჩა <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> — სრულ დატენვამდე დარჩა <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> — <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"უცნობი"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"იტენება"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"იტენება"</string>
diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml
index e348108..448cb14 100644
--- a/packages/SettingsLib/res/values-kk/arrays.xml
+++ b/packages/SettingsLib/res/values-kk/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (әдепкі)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Жүйені таңдау (әдепкі)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Қосымша кодектерді қосу"</item>
-    <item msgid="3304843301758635896">"Қосымша кодектерді өшіру"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Жүйені таңдау (әдепкі)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Қосымша кодектерді қосу"</item>
-    <item msgid="741805482892725657">"Қосымша кодектерді өшіру"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Жүйені таңдау (әдепкі)"</item>
     <item msgid="8895532488906185219">"44,1 кГц"</item>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 7cce073..27622a1 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Желі байланысының сапасы төмен болғандықтан қосылмады"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi байланысының қатесі"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Растау мәселесі"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Қосылу мүмкін емес"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\"<xliff:g id="AP_NAME">%1$s</xliff:g>\" қолданбасына қосылу мүмкін емес"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Құпия сөзді тексеріп, әрекетті қайталаңыз"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Аумақта жоқ"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Автоматты қосылмайды"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Интернетпен байланыс жоқ"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s арқылы қосылған"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s арқылы қолжетімді"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Қосылған, интернет жоқ"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Өте баяу"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Баяу"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Жарайды"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Орташа"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Жылдам"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Өте жылдам"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Ажыратылған"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Ажыратылуда…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Жалғауда..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Жалғанған (медиа жоқ)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Жалғанған (хабарлар қол жетімсіз)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Жалғанған (телефон және медиа жоқ)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Қосылды, батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Қосылды (телефон емес), батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Қосылды (медиа емес), батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Қосылды (телефон не медиа емес), батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Meдиа аудиосы"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Телефон аудиосы"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефон қоңыраулары"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Файл жіберу"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Кіріс құрылғысы"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Интернетке қосылу"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Контактіні бөлісу"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Контактіні бөлісу үшін пайдалану"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Интернет байланысын ортақ қолдану"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Хабарға кіру"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Мәтіндік хабарлар"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM картасына кіру"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Жоғары сапалы аудио дыбысын пайдалану: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Жоғары сапалы аудио дыбысын пайдалану"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD форматты аудиомазмұн: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD форматты аудиомазмұн"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Медиа аудиосына жалғанған"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Телефон аудиосына қосылған"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Файл жіберу серверіне жалғанған"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi желісінен мобильдік желіге ауысу"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi роумингін іздеулерге әрқашан рұқсат ету"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобильдік деректер әрқашан қосулы"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Тетерингтің аппараттық жеделдетуі"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Абсолютті дыбыс деңгейін өшіру"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Ішкі жолақтағы шылдырлауды қосу"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP нұсқасы"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Жасанды аймақтарды пайдалануға рұқсат беру"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Көру төлсипатын тексеруді қосу"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi‑Fi қосулы кезде де ұялы деректерді белсенді етіп ұстау (желіні жылдам ауыстыру үшін)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Қолжетімді болса тетерингтің аппараттық жеделдетуін пайдалану"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB жөндеулеріне рұқсат берілсін бе?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB жөндеу дамыту мақсаттарына ғана арналған. Оны компьютер және құрылғы арасында дерек көшіру, құрылғыға ескертусіз қолданба орнату және тіркелім деректерін оқу үшін қолданыңыз."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Бұған дейін рұқсат берілген барлық компьютерлерде USB жөндеу функциясына тыйым салынсын ба?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Түсті түзету"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бұл мүмкіндік эксперименттік болып табылады және өнімділікке әсер етуі мүмкін."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> үстінен басқан"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Қалған <xliff:g id="TIME">%1$s</xliff:g> туралы"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Толық зарядқа <xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – шамамен <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Қалған <xliff:g id="TIME">^1</xliff:g> туралы"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Пайдалану негізінде шамамен <xliff:g id="TIME">^1</xliff:g> қалды"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Толық зарядқа <xliff:g id="TIME">^1</xliff:g> қалды"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> қалды"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Пайдалану негізінде <xliff:g id="TIME">^1</xliff:g> қалды"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – шамамен <xliff:g id="TIME">^2</xliff:g> қалды"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - пайдалану негізінде шамамен <xliff:g id="TIME">^2</xliff:g> қалды"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – толық зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – толық зарядталғанға дейін <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Белгісіз"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Зарядталуда"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"зарядталуда"</string>
diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml
index 27e0e59..525f5aa 100644
--- a/packages/SettingsLib/res/values-km/arrays.xml
+++ b/packages/SettingsLib/res/values-km/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (លំនាំដើម)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"ប្រើ​ការ​ជ្រើសរើស​ប្រព័ន្ធ (លំនាំ​ដើម)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"បើក​កូឌិក​ប្រភេទ​ស្រេច​ចិត្ត"</item>
-    <item msgid="3304843301758635896">"បិទ​កូឌិក​ប្រភេទ​ស្រេច​ចិត្ត"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"ប្រើ​ការ​ជ្រើសរើស​ប្រព័ន្ធ (លំនាំ​ដើម)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"បើក​កូឌិក​ប្រភេទ​ស្រេច​ចិត្ត"</item>
-    <item msgid="741805482892725657">"បិទ​កូឌិក​ប្រភេទ​ស្រេច​ចិត្ត"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"ប្រើ​ការ​ជ្រើសរើស​ប្រព័ន្ធ (លំនាំ​ដើម)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index e0a1337..5f614f6 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"មិន​អាច​ភ្ជាប់​បាន​ទេ ដោយសារ​បណ្តាញ​មាន​គុណភាព​សេវា​ខ្សោយ"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"ការ​ភ្ជាប់​ WiFi បរាជ័យ"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"បញ្ហា​ក្នុង​ការ​ផ្ទៀងផ្ទាត់"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"មិនអាច​ភ្ជាប់​បានទេ"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"មិនអាចភ្ជាប់ជាមួយ \'<xliff:g id="AP_NAME">%1$s</xliff:g>\' បានទេ"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"សូមពិនិត្យមើលពាក្យសម្ងាត់ រួចព្យាយាមម្ដងទៀត"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"នៅ​ក្រៅ​តំបន់"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"នឹងមិនភ្ជាប់ដោយស្វ័យប្រវត្តិទេ"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"មិនមានអ៊ីនធឺណិតទេ"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"បានភ្ជាប់តាមរយៈ %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"មានតាមរយៈ %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"បានភ្ជាប់ ប៉ុន្តែគ្មានអ៊ីនធឺណិតទេ"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"យឺតណាស់"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"យឺត"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"យល់ព្រម"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"មធ្យម"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"លឿន"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"លឿន​ណាស់"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"បាន​ផ្ដាច់"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"កំពុង​ផ្ដាច់…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"កំពុង​ត​ភ្ជាប់​…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"បាន​តភ្ជាប់ (គ្មាន​មេឌៀ)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"បាន​ភ្ជាប់ (គ្មាន​ការ​ចូល​ដំណើរការ​សារ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"បាន​តភ្ជាប់ (គ្មាន​ទូរស័ព្ទ ឬ​មេឌៀ)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"បានភ្ជាប់ ហើយថ្មមានកម្រិត <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"បានភ្ជាប់ (គ្មានទូរសព្ទ) ហើយថ្មមានកម្រិត <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"បានភ្ជាប់ (គ្មានមេឌៀ) ហើយថ្មមានកម្រិត <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"បានភ្ជាប់ (គ្មានទូរសព្ទ ឬមេឌៀ) ហើយថ្មមានកម្រិត <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"សំឡេង​មេឌៀ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"សំឡេង​ទូរស័ព្ទ"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ការហៅ​ទូរសព្ទ"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ផ្ទេរ​ឯកសារ"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ឧបករណ៍​បញ្ចូល"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ចូល​អ៊ីនធឺណិត"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"ការ​ចែករំលែក​​ទំនាក់ទំនង"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"ប្រើ​សម្រាប់​ការ​ចែករំលែក​ទំនាក់ទំនង"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ចែករំលែក​ការ​តភ្ជាប់​អ៊ីនធឺណិត"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"​​ចូល​ដំណើរការ​សារ"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"សារ​ជាអក្សរ"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ការចូលដំណើរការស៊ីម"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ប្រើ​សំឡេង​គុណភាព​ខ្ពស់៖ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ប្រើ​សំឡេង​គុណភាព​ខ្ពស់"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"សំឡេងកម្រិត HD៖ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"សំឡេងកម្រិត HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"បា​ន​ភ្ជាប់​ទៅ​អូឌីយ៉ូ​មេឌៀ"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"តភ្ជាប់​ទៅ​អូឌីយ៉ូ​ទូរស័ព្ទ"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"បាន​តភ្ជាប់​ទៅ​ម៉ាស៊ីន​មេ​ផ្ទេរ​ឯកសារ"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ប្តូរទៅប្រើបណ្តាញចល័តពេល Wi‑Fi មានរលកសញ្ញាខ្លាំងពេក"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"តែងតែ​អនុញ្ញាត​​​ការវិភាគ​រ៉ូម​វ៉ាយហ្វាយ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ទិន្នន័យទូរសព្ទចល័តដំណើរការជានិច្ច"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ការ​បង្កើនល្បឿន​ផ្នែករឹងសម្រាប់​ការភ្ជាប់"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"បិទកម្រិតសំឡេងលឺខ្លាំង"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"បើក​ការ​រោទ៍​ក្នុងបណ្តាញ"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"កំណែប្ល៊ូធូស AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"អនុញ្ញាត​ទីតាំង​ក្លែងក្លាយ"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"បើក​ការ​ត្រួតពិនិត្យ​គុណ​លក្ខណៈ​ទិដ្ឋភាព"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"រក្សាទិន្នន័យចល័តឲ្យសកម្មជានិច្ច បើទោះបីជា Wi‑Fi សកម្មក៏ដោយ (សម្រាប់ការប្តូរបណ្តាញដែលមានល្បឿនលឿន)។"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ប្រើការ​បង្កើនល្បឿន​ផ្នែករឹងសម្រាប់​ការភ្ជាប់​ ប្រសិន​បើអាច​ប្រើបាន"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"អនុញ្ញាត​ការ​កែ​កំហុស​យូអេសប៊ី?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"ការ​កែ​កំហុស​​យូអេសប៊ី​គឺ​សម្រាប់​តែ​ការ​អភិវឌ្ឍ​ប៉ុណ្ណោះ។ ប្រើ​វា​ដើម្បី​ចម្លង​ទិន្នន័យ​រវាង​កុំព្យូទ័រ និង​ឧបករណ៍​របស់​អ្នក ដំឡើង​កម្មវិធី​ក្នុង​ឧបករណ៍​របស់​អ្នក​ដោយ​មិន​ជូន​ដំណឹង និង​អាន​ទិន្នន័យ​កំណត់ហេតុ។"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"ដក​សិទ្ធិ​ចូល​ការ​កែ​កំហុស​តាម​យូអេសប៊ី​ពី​គ្រប់​កុំព្យូទ័រ​ដែល​អ្នក​បាន​ផ្ដល់​សិទ្ធិ​ពី​មុន?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ការ​កែ​ពណ៌"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"មុខងារនេះ​គឺ​ជា​ការ​ពិសោធន៍ ហើយ​អាច​ប៉ះពាល់​ដំណើរការ​។"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"បដិសេធ​ដោយ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"សល់​ប្រហែល <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"សល់ <xliff:g id="TIME">%1$s</xliff:g> ទើប​សាកថ្ម​ពេញ"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"នៅសល់ <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - សល់ប្រហែល <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - នៅសល់ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"សល់​ប្រហែល <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"សល់ប្រហែល <xliff:g id="TIME">^1</xliff:g> ទៀតផ្អែកលើការប្រើប្រាស់របស់អ្នក"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"សល់ <xliff:g id="TIME">^1</xliff:g> ទើប​សាកថ្ម​ពេញ"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"នៅសល់ <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"សល់ <xliff:g id="TIME">^1</xliff:g> ទៀតផ្អែកលើការប្រើប្រាស់របស់អ្នក"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - សល់ប្រហែល <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - សល់ប្រហែល <xliff:g id="TIME">^2</xliff:g> ទៀតផ្អែកលើការប្រើប្រាស់របស់អ្នក"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - នៅសល់ <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់សាកពេញ"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> រហូតដល់សាកពេញ"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"មិន​ស្គាល់"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"កំពុងបញ្ចូល​ថ្ម"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"កំពុង​សាក​ថ្ម"</string>
diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml
index 810aefe..1e2e7ba 100644
--- a/packages/SettingsLib/res/values-kn/arrays.xml
+++ b/packages/SettingsLib/res/values-kn/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (ಡಿಫಾಲ್ಟ್)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"ಸಿಸ್ಟಂ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿ (ಡಿಫಾಲ್ಟ್)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"ಐಚ್ಛಿಕ ಕೋಡೆಕ್‌ಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</item>
-    <item msgid="3304843301758635896">"ಐಚ್ಛಿಕ ಕೋಡೆಕ್‌ಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"ಸಿಸ್ಟಂ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿ (ಡಿಫಾಲ್ಟ್)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"ಐಚ್ಛಿಕ ಕೋಡೆಕ್‌ಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</item>
-    <item msgid="741805482892725657">"ಐಚ್ಛಿಕ ಕೋಡೆಕ್‌ಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"ಸಿಸ್ಟಂ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿ (ಡಿಫಾಲ್ಟ್)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index ec0bef4..7148af5 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -28,15 +28,24 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"ಕಡಿಮೆ ಗುಣಮಟ್ಟದ ನೆಟ್‌ವರ್ಕ್‌ನಿಂದಾಗಿ ಸಂಪರ್ಕ ಸಾಧಿಸಿಲ್ಲ"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi ಸಂಪರ್ಕ ವಿಫಲತೆ"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"ಪ್ರಮಾಣೀಕರಣ ಸಮಸ್ಯೆ"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"ಪಾಸ್‌ವರ್ಡ್ ಪರಿಶೀಲಿಸಿ ಮತ್ತು ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"ವ್ಯಾಪ್ತಿಯಲ್ಲಿಲ್ಲ"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶವಿಲ್ಲ"</string>
-    <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> ರಿಂದ ಉಳಿಸಲಾಗಿದೆ"</string>
+    <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> ನಿಂದ ಉಳಿಸಲಾಗಿದೆ"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ಮೂಲಕ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"ನೆಟ್‌ವರ್ಕ್ ರೇಟಿಂಗ್ ಒದಗಿಸುವವರ ಮೂಲಕ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ಮೂಲಕ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ಮೂಲಕ ಲಭ್ಯವಿದೆ"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ, ಇಂಟರ್ನೆಟ್ ಇಲ್ಲ"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"ತುಂಬಾ ನಿಧಾನವಾಗಿದೆ"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"ನಿಧಾನ"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ಸರಿ"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"ಮಧ್ಯಮ"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"ವೇಗ"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"ತುಂಬಾ ವೇಗವಾಗಿದೆ"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"ಸಂಪರ್ಕಗೊಳಿಸಲಾಗುತ್ತಿದೆ..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಮಾಧ್ಯಮವಿಲ್ಲ)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ (ಯಾವುದೇ ಸಂದೇಶ ಪ್ರವೇಶವಿಲ್ಲ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಫೋನ್ ಅಥವಾ ಮಾಧ್ಯಮವಿಲ್ಲ)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"ಸಂಪರ್ಕಗೊಂಡಿದೆ, ಬ್ಯಾಟರಿ ಚಾರ್ಜ್‌ ಮಟ್ಟ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಫೋನ್ ಇಲ್ಲ), ಬ್ಯಾಟರಿ ಚಾರ್ಜ್‌ ಮಟ್ಟ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಮಾಧ್ಯಮವಿಲ್ಲ), ಬ್ಯಾಟರಿ ಚಾರ್ಜ್‌ ಮಟ್ಟ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಫೋನ್ ಅಥವಾ ಮಾಧ್ಯಮವಿಲ್ಲ), ಬ್ಯಾಟರಿ ಚಾರ್ಜ್‌ ಮಟ್ಟ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ಮಾಧ್ಯಮ ಆಡಿಯೋ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ಫೋನ್ ಆಡಿಯೋ"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ಫೋನ್ ಕರೆಗಳು"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ಫೈಲ್ ವರ್ಗಾವಣೆ"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ಇನ್‌ಪುಟ್‌ ಸಾಧನ"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶ"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"ಸಂಪರ್ಕ ಹಂಚಿಕೆ"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"ಸಂಪರ್ಕ ಹಂಚಿಕೆಗಾಗಿ ಬಳಸಿ"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕ ಹಂಚಿಕೊಳ್ಳುವಿಕೆ"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"ಸಂದೇಶ ಪ್ರವೇಶಿಸುವಿಕೆ"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"ಪಠ್ಯ ಸಂದೇಶಗಳು"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ಸಿಮ್ ಪ್ರವೇಶ"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ಉನ್ನತ ಗುಣಮಟ್ಟದ ಆಡಿಯೋ ಬಳಸಿ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ಉನ್ನತ ಗುಣಮಟ್ಟದ ಆಡಿಯೋ ಬಳಸಿ"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ಆಡಿಯೋ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ಆಡಿಯೋ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"ಮಾಧ್ಯಮ ಆಡಿಯೋಗೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ಫೋನ್ ಆಡಿಯೋಗೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ಫೈಲ್ ವರ್ಗಾವಣೆ ಸರ್ವರ್‌ಗೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
@@ -77,7 +90,7 @@
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"ಜೋಡಿ"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ಜೋಡಿ ಮಾಡು"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ರದ್ದುಮಾಡಿ"</string>
-    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"ಸಂಪರ್ಕಪಡಿಸಿದಾಗ, ಜೋಡಿಸುವಿಕೆಯು ನಿಮ್ಮ ಸಂಪರ್ಕಗಳು ಮತ್ತು ಕರೆ ಇತಿಹಾಸಕ್ಕೆ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸುತ್ತದೆ."</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"ಸಂಪರ್ಕಗೊಳಿಸಿದಾಗ, ಜೋಡಿಸುವಿಕೆಯು ನಿಮ್ಮ ಸಂಪರ್ಕಗಳು ಮತ್ತು ಕರೆ ಇತಿಹಾಸಕ್ಕೆ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಜೋಡಣೆ ಮಾಡಲಾಗಲಿಲ್ಲ."</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ತಪ್ಪಾಗಿರುವ ಪಿನ್‌ ಅಥವಾ ಪಾಸ್‌ಕೀ ಕಾರಣದಿಂದಾಗಿ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಜೋಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಸಂವಹನ ನಡೆಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
@@ -102,7 +115,7 @@
     <string name="running_process_item_user_label" msgid="3129887865552025943">"ಬಳಕೆದಾರ: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="313159469856372621">"ಕೆಲವು ಡೀಫಾಲ್ಟ್‌ಗಳನ್ನು ಹೊಂದಿಸಲಾಗಿದೆ"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"ಡೀಫಾಲ್ಟ್‌ಗಳನ್ನು ಹೊಂದಿಸಲಾಗಿಲ್ಲ"</string>
-    <string name="tts_settings" msgid="8186971894801348327">"ಪಠ್ಯದಿಂದ ಧ್ವನಿಗೆ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+    <string name="tts_settings" msgid="8186971894801348327">"ಪಠ್ಯದಿಂದ ಧ್ವನಿಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"ಧ್ವನಿಗೆ-ಪಠ್ಯದ ಔಟ್‌ಪುಟ್‌"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"ಧ್ವನಿಯ ಪ್ರಮಾಣ"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"ಪಠ್ಯವನ್ನು ಹೇಳಿದ ವೇಗ"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ವೈ-ಫೈನಿಂದ ಮೊಬೈಲ್‌ಗೆ ಆಕ್ರಮಣಕಾರಿ ಹಸ್ತಾಂತರ"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ವೈ-ಫೈ ರೋಮ್ ಸ್ಕ್ಯಾನ್‌ಗಳನ್ನು ಯಾವಾಗಲೂ ಅನುಮತಿಸಿ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ಮೊಬೈಲ್ ಡೇಟಾ ಯಾವಾಗಲೂ ಸಕ್ರಿಯ"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ಹಾರ್ಡ್‌ವೇರ್‌ನ ವೇಗವರ್ಧನೆಯನ್ನು ಟೆಥರಿಂಗ್ ಮಾಡಿ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ಸಂಪೂರ್ಣ ವಾಲ್ಯೂಮ್‌ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ಇನ್ ಬ್ಯಾಂಡ್ ರಿಂಗಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ಬ್ಲೂಟೂತ್ AVRCP ಆವೃತ್ತಿ"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"ಅಣಕು ಸ್ಥಾನಗಳನ್ನು ಅನುಮತಿಸಿ"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"ವೀಕ್ಷಣೆ ಆಟ್ರಿಬ್ಯೂಟ್ ಪರಿಶೀಲನೆ"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ವೈ-ಫೈ ಸಕ್ರಿಯವಾಗಿರುವಾಗಲೂ, ಯಾವಾಗಲೂ ಮೊಬೈಲ್‌ ಡೇಟಾ ಸಕ್ರಿಯವಾಗಿರಿಸಿ (ವೇಗವಾಗಿ ನೆಟ್‌ವರ್ಕ್‌ ಬದಲಾಯಿಸಲು)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ಹಾರ್ಡ್‌ವೇರ್‌ನ ವೇಗವರ್ಧನೆ ಟೆಥರಿಂಗ್ ಲಭ್ಯವಿದ್ದರೆ ಅದನ್ನು ಬಳಸಿ"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯು ಅಭಿವೃದ್ಧಿ ಉದ್ದೇಶಗಳಿಗೆ ಮಾತ್ರ ಆಗಿದೆ. ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ನಡುವೆ ಡೇಟಾವನ್ನು ನಕಲಿಸಲು, ಅಧಿಸೂಚನೆ ಇಲ್ಲದೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಲು ಮತ್ತು ಲಾಗ್ ಡೇಟಾ ಓದಲು ಅದನ್ನು ಬಳಸಿ."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"ನೀವು ಹಿಂದೆ ಅಧಿಕೃತಗೊಳಿಸಿದ ಎಲ್ಲ ಕಂಪ್ಯೂಟರ್‌ಗಳಿಂದ USB ಡೀಬಗ್‌ಗೆ ಪ್ರವೇಶವನ್ನು ರದ್ದುಗೊಳಿಸುವುದೇ?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ಬಣ್ಣದ ತಿದ್ದುಪಡಿ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ಇದು ಪ್ರಾಯೋಗಿಕ ವೈಶಿಷ್ಟ್ಯವಾಗಿದೆ. ಕಾರ್ಯಕ್ಷಮತೆ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರಬಹುದು."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ಮೂಲಕ ಅತಿಕ್ರಮಿಸುತ್ತದೆ"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"ಸುಮಾರು <xliff:g id="TIME">%1$s</xliff:g> ಬಾಕಿಯಿದೆ"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ಉಳಿದಿದೆ"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಸುಮಾರು <xliff:g id="TIME">%2$s</xliff:g> ಬಾಕಿಯಿದೆ"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ಉಳಿದಿದೆ"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"ಸುಮಾರು <xliff:g id="TIME">^1</xliff:g> ಬಾಕಿಯಿದೆ"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"ನಿಮ್ಮ ಬಳಕೆಯ ಆಧಾರದ ಮೇಲೆ ಸುಮಾರು <xliff:g id="TIME">^1</xliff:g> ಉಳಿದಿದೆ"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> ಉಳಿದಿದೆ"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"ನಿಮ್ಮ ಬಳಕೆಯ ಆಧಾರದ ಮೇಲೆ <xliff:g id="TIME">^1</xliff:g> ಉಳಿದಿದೆ"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - ಸುಮಾರು <xliff:g id="TIME">^2</xliff:g> ಬಾಕಿಯಿದೆ"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - ನಿಮ್ಮ ಬಳಕೆಯ ಆಧಾರದ ಮೇಲೆ <xliff:g id="TIME">^2</xliff:g> ಉಳಿದಿದೆ"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"ಅಪರಿಚಿತ"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml
index dbbe89d..8bc794f 100644
--- a/packages/SettingsLib/res/values-ko/arrays.xml
+++ b/packages/SettingsLib/res/values-ko/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4(기본)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"시스템 설정 사용(기본)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"선택사항 코덱 사용 설정"</item>
-    <item msgid="3304843301758635896">"선택사항 코덱 사용 중지"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"시스템 설정 사용(기본)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"선택사항 코덱 사용 설정"</item>
-    <item msgid="741805482892725657">"선택사항 코덱 사용 중지"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"시스템 설정 사용(기본)"</item>
     <item msgid="8895532488906185219">"44.1kHz"</item>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 0f4224a..b7cf515 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"저품질 네트워크로 인해 연결되지 않음"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi 연결 실패"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"인증 문제"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"연결할 수 없음"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'에 연결할 수 없음"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"비밀번호를 확인하고 다시 시도하세요."</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"범위 내에 없음"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"자동으로 연결되지 않습니다."</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"인터넷에 연결되어 있지 않습니다."</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s을(를) 통해 연결됨"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s을(를) 통해 사용 가능"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"인터넷을 사용하지 않고 연결됨"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"매우 느림"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"느림"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"확인"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"보통"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"빠름"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"매우 빠름"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"연결 끊김"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"연결을 끊는 중…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"연결 중…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"연결됨(미디어 없음)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"연결됨(메시지 액세스 없음)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"연결됨(전화 또는 미디어 없음)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"연결됨, 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"연결됨(전화 없음), 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"연결됨(미디어 없음), 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"연결됨(전화 또는 미디어 없음), 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"미디어 오디오"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"휴대폰 오디오"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"전화 통화"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"파일 전송"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"입력 장치"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"인터넷 액세스"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"연락처 공유"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"연락처 공유용"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"인터넷 연결 공유"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"메시지 액세스"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"문자 메시지"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 액세스"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"고품질 오디오 사용: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"고품질 오디오 사용"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD 오디오: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD 오디오"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"미디어 오디오에 연결됨"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"휴대전화 오디오에 연결됨"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"파일 전송 서버에 연결됨"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"적극적인 Wi-Fi-모바일 핸드오버"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi 로밍 스캔 항상 허용"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"항상 모바일 데이터 활성화"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"테더링 하드웨어 가속"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"절대 볼륨 사용 안함"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"대역 내 벨소리 사용 설정"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"블루투스 AVRCP 버전"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"모의 위치 허용"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"보기 속성 검사 사용"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi‑Fi가 활성화되어 있을 때에도 빠른 네트워크 전환을 위하여 항상 모바일 데이터를 활성 상태로 유지합니다."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"가능한 경우 테더링 하드웨어 가속 사용"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB 디버깅을 허용하시겠습니까?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB 디버깅은 개발용으로만 설계되었습니다. 이 기능을 사용하면 컴퓨터와 기기 간에 데이터를 복사하고 알림 없이 기기에 앱을 설치하며 로그 데이터를 읽을 수 있습니다."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"이전에 승인한 모든 컴퓨터에서 USB 디버깅에 대한 액세스 권한을 취소하시겠습니까?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"색보정"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"실험실 기능이며 성능에 영향을 줄 수 있습니다."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> 우선 적용됨"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"약 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"충전 완료까지 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 약 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"약 <xliff:g id="TIME">^1</xliff:g> 남음"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"내 사용량을 기준으로 약 <xliff:g id="TIME">^1</xliff:g> 남음"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"충전 완료까지 <xliff:g id="TIME">^1</xliff:g> 남음"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> 남음"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"내 사용량을 기준으로 <xliff:g id="TIME">^1</xliff:g> 남음"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - 약 <xliff:g id="TIME">^2</xliff:g> 남음"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - 내 사용량을 기준으로 약 <xliff:g id="TIME">^2</xliff:g> 남음"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 완료까지 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - 충전 완료까지 <xliff:g id="TIME">^2</xliff:g> 남음"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"알 수 없음"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"충전 중"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"충전 중"</string>
diff --git a/packages/SettingsLib/res/values-ky/arrays.xml b/packages/SettingsLib/res/values-ky/arrays.xml
index 9c8e28a..30c13b2 100644
--- a/packages/SettingsLib/res/values-ky/arrays.xml
+++ b/packages/SettingsLib/res/values-ky/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Демейки)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Тутум тандаганды колдонуу (демейки)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Кошумча кодекстер иштетилсин"</item>
-    <item msgid="3304843301758635896">"Кошумча кодекстер өчүрүлсүн"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Тутум тандаганды колдонуу (демейки)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Кошумча кодекстер иштетилсин"</item>
-    <item msgid="741805482892725657">"Кошумча кодекстер өчүрүлсүн"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Тутум тандаганды колдонуу (демейки)"</item>
     <item msgid="8895532488906185219">"44,1 кГц"</item>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 58cf6df..701c90f 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Тармактын сапаты начар болгондуктан туташкан жок"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi туташуусу бузулду"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Аутентификация маселеси бар"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Туташпай жатат"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\"<xliff:g id="AP_NAME">%1$s</xliff:g>\" тармагына туташпай койду"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Сырсөздү текшерип, кайра аракет кылыңыз."</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Тейлөө аймагында эмес"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Автоматтык түрдө туташпайт"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Интернетке туташпай турат"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s аркылуу жеткиликтүү"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s аркылуу жеткиликтүү"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Туташып турат, Интернет жок"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Өтө жай"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Жай"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Жарайт"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Орто"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Ылдам"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Абдан ылдам"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Ажыратылган"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Ажыратылууда…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Туташууда…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Туташып турат (медиасыз)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Байланышта (билдирүү алмашуу жок)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Туташып турат (телефониясыз же медиасыз)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Туташып турат, батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Туташып турат (телефониясыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Туташып турат (медиасыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Туташып турат (телефониясыз же медиасыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Аудио"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Телефон"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефон чалуулар"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Файл алмашуу"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Киргизүү түзмөгү"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Интернетке мүмкүнчүлүк алуу"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Байланышты бөлүшүү"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Байланышты бөлүшүү үчүн колдонуу"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Интернет байланышын бөлүшүү"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Билдирүү алмашуу"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"SMS билдирүүлөрү"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM картаны пайдалануу мүмкүнчүлүгү"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Жогорку сапаттагы аудио кодекти колдонуу: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Жогорку сапаттагы аудио кодекти колдонуу"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD форматындагы аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD форматындагы аудио"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Медиа аудиого туташты"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Телефон аудиосуна туташты"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Файл өткөрүү серверине туташты"</string>
@@ -100,10 +113,10 @@
     <string name="user_guest" msgid="8475274842845401871">"Конок"</string>
     <string name="unknown" msgid="1592123443519355854">"Белгисиз"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"Колдонуучу: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
-    <string name="launch_defaults_some" msgid="313159469856372621">"Айрым демейкилер коюлду"</string>
+    <string name="launch_defaults_some" msgid="313159469856372621">"Айрым демейки параметрлер туураланды"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"Демейкилер коюлган жок"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Кеп синтезаторунун жөндөөлөрү"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"Текстти-оозекилөө"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"Кеп синтезатору"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Кеп ылдамдыгы"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"Текст айтылчу ылдамдык"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"Негизги тон"</string>
@@ -117,7 +130,7 @@
     <string name="tts_install_data_title" msgid="4264378440508149986">"Үн дайындарын орнотуу"</string>
     <string name="tts_install_data_summary" msgid="5742135732511822589">"Кеп синтезине керектүү үн дайындарын орнотуңуз"</string>
     <string name="tts_engine_security_warning" msgid="8786238102020223650">"Бул кепти синтездөө каражаты бардык айтыла турган текстти, анын ичинде сырсөздөр жана насыя карточкасынын номери сыяктуу жеке маалыматты, топтошу мүмкүн. Ал <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> каражатынан алынат. Бул кепти синтездөө каражаты колдонулсунбу?"</string>
-    <string name="tts_engine_network_required" msgid="1190837151485314743">"Бул тилде текстти-оозекилөө үчүн иштеп турган интернет-байланыш керек."</string>
+    <string name="tts_engine_network_required" msgid="1190837151485314743">"Бул тилде кеп синтезаторун иштетүү үчүн Интернетке туташуу керек."</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"Бул айтылганды синтездөөнүн мисалы"</string>
     <string name="tts_status_title" msgid="7268566550242584413">"Абалкы тилдин абалы"</string>
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> толук колдоого алынган"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi начар болсо, мобилдик Инт-ке өтсүн"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi Роуминг Скандоо мүмкүнчүлүгүнө ар дайым уруксат берилсин"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилдик Интернет иштей берсин"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Тетерингдин иштешин тездетүү"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Үндүн абсолюттук деңгээли өчүрүлсүн"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Канал аралык чалууну иштетүү"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP версиясы"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Жасалма жайгашкан жерди көрсөтүүгө уруксат берилсин"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Аттрибут текшерүүсүнүн көрүнүшүн иштетүү"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi-Fi иштеп турганда да дайындар мобилдик тармак аркылуу өткөрүлө берсин (тармактар ортосунда тезирээк которулуу үчүн)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Эгер мүмкүн болсо, тетерингдин иштеши тездетилсин"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB аркылуу жөндөөгө уруксат берилсинби?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-жөндөө - өндүрүү максатында гана  түзүлгөн. Аны компүтериңиз менен түзмөгүңүздүн ортосунда берилиштерди алмашуу, түзмөгүңүзгө колдонмолорду эскертүүсүз орнотуу жана лог берилиштерин окуу үчүн колдонсоңуз болот."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Сиз мурун USB жөндөөлөрүнө уруксат берген бардык компүтерлердин жеткиси жокко чыгарылсынбы?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Түсүн тууралоо"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бул сынамык мүмкүнчүлүк болгондуктан, түзмөктүн иштешине таасир этиши мүмкүн."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> менен алмаштырылган"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Батарея түгөнгөнгө чейин калган убакыт: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Батарея толгонго чейин калган убакыт: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> калды"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – болжол менен <xliff:g id="TIME">%2$s</xliff:g> калды"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> калды"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Батарея түгөнгөнгө чейин калган убакыт: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Колдонушуңузга караганда болжол менен <xliff:g id="TIME">^1</xliff:g> калды"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Батарея толгонго чейин калган убакыт: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> калды"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Колдонушуңузга караганда <xliff:g id="TIME">^1</xliff:g> калды"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – болжол менен <xliff:g id="TIME">^2</xliff:g> калды"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - колдонушуңузга караганда болжол менен <xliff:g id="TIME">^2</xliff:g> калды"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталат"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> кийин толук кубатталат"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Белгисиз"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Кубатталууда"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"кубатталууда"</string>
diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml
index 63889e0..73fe616 100644
--- a/packages/SettingsLib/res/values-lo/arrays.xml
+++ b/packages/SettingsLib/res/values-lo/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Use System Selection (Default)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"ເປີດໃຊ້ Codecs ແບບເສີມ"</item>
-    <item msgid="3304843301758635896">"ປິດການໃຊ້ Codecs ແບບເສີມ"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Use System Selection (Default)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"ເປີດໃຊ້ Codecs ແບບເສີມ"</item>
-    <item msgid="741805482892725657">"ປິດການໃຊ້ Codecs ແບບເສີມ"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Use System Selection (Default)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 3411348..88bdc41 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"ບໍ່ໄດ້ເຊື່ອມຕໍ່ເນື່ອງຈາກຄຸນນະພາບເຄືອຂ່າຍຕໍ່າ"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"​ການ​ເຊື່ອມ​ຕໍ່ WiFi ລົ້ມ​ເຫຼວ"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"ບັນຫາການພິສູດຢືນຢັນ"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"ບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"ບໍ່ສາມາດເຊື່ອມຕໍ່ຫາ \'<xliff:g id="AP_NAME">%1$s</xliff:g>\' ໄດ້"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"ກະລຸນາກວດສອບລະຫັດຜ່ານແລ້ວລອງໃໝ່ອີກຄັ້ງ"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"ບໍ່ຢູ່ໃນໄລຍະທີ່ເຊື່ອມຕໍ່ໄດ້"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ຈະບໍ່ເຊື່ອມຕໍ່ອັດຕະໂນມັດ"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"​ເຊື່ອມຕໍ່​ຜ່ານ %1$s ​ແລ້ວ"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"ມີ​ໃຫ້​ຜ່ານ %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"​ເຊື່ອມ​ຕໍ່​ແລ້ວ,​ ບໍ່​ມີ​ອິນ​ເຕີ​ເນັດ"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"ຊ້າຫຼາຍ"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"ຊ້າ"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ຕົກລົງ"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"ປານກາງ"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"ໄວ"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"ໄວຫຼາຍ"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"ຕັດການເຊື່ອມຕໍ່ແລ້ວ"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"ກຳລັງຢຸດການເຊື່ອມຕໍ່..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"ກຳລັງເຊື່ອມຕໍ່..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີສື່)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ເຊື່ອມຕໍ່ (ບໍ່ມີການເຂົ້າເຖິງຂໍ້ຄວາມ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີໂທລະສັບ ຫຼືສື່)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"ເຊື່ອມຕໍ່ແລ້ວ, ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີໂທລະສັບ), ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີມີເດຍ), ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີໂທລະສັບ ຫຼື ມີເດຍ), ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ສຽງ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ສຽງໂທລະສັບ"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ການໂທ"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ການໂອນຍ້າຍໄຟລ໌"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ອຸປະກອນປ້ອນຂໍ້ມູນ"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ການເຂົ້າເຖິງອິນເຕີເນັດ"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"ການ​ແບ່ງ​ປັນ​ລາຍ​ຊື່​ຜູ່​ຕິດ​ຕໍ່"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"​ໃຊ້​ສຳ​ລັບການ​ແບ່ງ​ປັນ​ລາຍ​ຊື່​ຜູ່​ຕິດ​ຕໍ່"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ການແບ່ງປັນການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"ການ​ເຂົ້າ​ເຖິງ​ຂໍ້​ຄວາມ"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"ຂໍ້ຄວາມ"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ການ​ເຂົ້າ​ເຖິງ SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ໃຊ້ສຽງຄຸນນະພາບສູງ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ໃຊ້ສຽງຄຸນນະພາບສູງ"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"ສຽງ HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"ສຽງ HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"ເຊື່ອມຕໍ່ກັບສື່ດ້ານສຽງແລ້ວ"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ເຊື່ອມຕໍ່ກັບສຽງໂທລະສັບແລ້ວ"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ເຊື່ອມຕໍ່ກັບເຊີບເວີໂອນຍ້າຍໄຟລ໌ແລ້ວ"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ສະຫຼັບເປັນ Wi-Fi ເມື່ອມືຖືສັນຍານອ່ອນ"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ອະ​ນຸ​ຍາດ​ການ​ສະ​ແກນ​ການ​ໂຣມ Wi‑Fi ​ສະ​ເໝີ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ເປີດໃຊ້ອິນເຕີເນັດມືຖືຕະຫຼອດເວລາ"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ເປີດໃຊ້ການເລັ່ງຄວາມໄວດ້ວຍຮາດແວ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ປິດໃຊ້ລະດັບສຽງສົມບູນ"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ເປີດສຽງເຕືອນແບບອິນແບນ"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ເວີຊັນ Bluetooth AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"ອະນຸຍາດໃຫ້ຈຳລອງຕຳແໜ່ງ"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"ເປີດ​ນຳ​ໃຊ້​ການກວດ​ສອບ​ຄຸນ​ສົມ​ບັດ​ມຸມມອງ"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ໃຫ້​ຂໍ້​ມູນ​ມື​ຖື​ເປີດ​ຢູ່​ສະ​ເໝີ, ແມ້​ແຕ່​ເມື່ອ Wi‑Fi ເປີດ​ຢູ່ (ສຳ​ລັບ​ການ​ສະ​ຫຼັບ​ເຄືອ​ຂ່າຍ​ໄວ)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ເປີດໃຊ້ການເລັ່ງຄວາມໄວດ້ວຍຮາດແວຫາກວ່າສາມາດໃຊ້ໄດ້"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"ອະນຸຍາດໃຫ້ດີບັ໊ກຜ່ານ USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"ການດີບັ໊ກຜ່ານ USB ແມ່ນມີຈຸດປະສົງເພື່ອການພັດທະນາເທົ່ານັ້ນ. ມັນສາມາດໃຊ້ເພື່ອສຳເນົາຂໍ້ມູນລະຫວ່າງຄອມພິວເຕີ ແລະອຸປະກອນຂອງທ່ານ, ຕິດຕັ້ງແອັບຯໂດຍບໍ່ຜ່ານການແຈ້ງເຕືອນ ແລະອ່ານຂໍ້ມູນການບັນທຶກ."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"ຖອດຖອນການເຂົ້າເຖິງການດີບັ໊ກຜ່ານ USB ຈາກຄອມພິວເຕີທຸກເຄື່ອງ ທີ່ທ່ານເຄີຍອະນຸຍາດກ່ອນໜ້ານີ້?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ການ​ປັບ​ແຕ່ງ​ສີ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"​ຄຸນ​ສົມ​ບັດ​ນີ້​ກຳ​ລັງ​ຢູ່​ໃນ​ການ​ທົດ​ລອງ​ແລະ​ອາດ​ມີ​ຜົນ​ຕໍ່​ປະ​ສິດ​ທິ​ພາບ."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"ຖືກແທນໂດຍ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"ອີກປະມານ <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> ຈົນກວ່າຈະສາກເຕັມ"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"ຍັງເຫຼືອ <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ຍັງເຫຼືອປະມານ <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - ຍັງເຫຼືອ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"ອີກປະມານ <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"ເຫຼືອອີກປະມານ <xliff:g id="TIME">^1</xliff:g> ໂດຍອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> ຈົນກວ່າຈະສາກເຕັມ"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"ຍັງເຫຼືອ <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"ເຫຼືອອີກ <xliff:g id="TIME">^1</xliff:g> ໂດຍອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - ຍັງເຫຼືອປະມານ <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - ເຫຼືອອີກປະມານ <xliff:g id="TIME">^2</xliff:g> ໂດຍອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - ຍັງເຫຼືອ <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈົນກວ່າຈະສາກເຕັມ"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> ຈົນກວ່າຈະສາກເຕັມ"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"ບໍ່ຮູ້ຈັກ"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"ກຳລັງສາກໄຟ"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ກຳລັງສາກໄຟ"</string>
diff --git a/packages/SettingsLib/res/values-lt/arrays.xml b/packages/SettingsLib/res/values-lt/arrays.xml
index 3c325c1..99babf6 100644
--- a/packages/SettingsLib/res/values-lt/arrays.xml
+++ b/packages/SettingsLib/res/values-lt/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (numatytoji)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Naudoti sistemos pasirink. (numatytasis)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Įgalinti nebūtinus kodekus"</item>
-    <item msgid="3304843301758635896">"Išjungti nebūtinus kodekus"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Naudoti sistemos pasirink. (numatytasis)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Įgalinti nebūtinus kodekus"</item>
-    <item msgid="741805482892725657">"Išjungti nebūtinus kodekus"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Naudoti sistemos pasirink. (numatytasis)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index b05ff2c..8ca0d36 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Neprisijungta dėl žemos kokybės tinklo"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"„Wi-Fi“ ryšio triktis"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Autentifikavimo problema"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Nepavyksta prisijungti"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Nepavyksta prisijungti prie „<xliff:g id="AP_NAME">%1$s</xliff:g>“"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Patikrinkite slaptažodį ir bandykite dar kartą"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Ne diapazone"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nebus automatiškai prisijungiama"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Nėra interneto ryšio"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Prisijungta naudojant „%1$s“"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Pasiekiama naudojant „%1$s“"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Prisijungta, nėra interneto"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Labai lėtas"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lėtas"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Gerai"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Vidutinis"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Greitas"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Labai greitas"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Atsijungęs (-usi)"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Atjungiama..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Prisijungiama..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Prijungta (be laikmenos)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Prisijungta (be prieigos prie pranešimų)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Prijungta (be telefono ar laikmenos)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Prijungta, akumuliatorius <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Prijungta (be telefono), akumuliatorius <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Prijungta (be medijos), akumuliatorius <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Prijungta (be telefono ar medijos), akumuliatorius <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Laikmenos garsas"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefono garsas"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefono skambučiai"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Failo perkėlimas"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Įvesties įrenginys"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Prieiga prie interneto"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktų bendrinimas"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Naudoti kontaktams bendrinti"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Interneto ryšio bendrinimas"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Prieiga prie pranešimų"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Teksto pranešimai"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM prieiga"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Naudoti aukštos kokybės garsą: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Naudoti aukštos kokybės garsą"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD garsas: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD garsas"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Prijungta prie medijos garso įrašo"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Prijungta prie telefono garso"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Prijungta prie failų perkėlimo serverio"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agres. „Wi‑Fi“ perd. į mob. r. tinklą"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Visada leisti „Wi-Fi“ tarptiklinio ryšio nuskaitymą"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiliojo ryšio duomenys visada suaktyvinti"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Įrenginio kaip modemo naudojimo aparatinės įrangos spartinimas"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Išjungti didžiausią garsą"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Įgalinti diapazono skambėjimą"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"„Bluetooth“ AVRCP versija"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Leisti imituoti vietas"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Įgalinti peržiūros atributų tikrinimą"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Visada suaktyvinti mobiliojo ryšio duomenis, net kai aktyvus „Wi‑Fi“ ryšys (kad būtų galima greitai perjungti tinklą)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Naudoti įrenginio kaip modemo naudojimo aparatinės įrangos spartinimą, jei pasiekiama"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Leisti USB perkrovimą?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB derinimas skirtas naudoti tik kūrimo tikslais. Jis gali būti naudojamas norint kopijuoti duomenis iš kompiuterio į įrenginį ir atvirkščiai, įdiegti programas įrenginyje be pranešimo ir skaityti žurnalo duomenis."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Panaikinti visų kompiuterių, kuriems anksčiau suteikėte prieigos teisę, prieigą prie USB derinimo?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Spalvų taisymas"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ši funkcija yra eksperimentinė ir ji gali turėti įtakos našumui."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nepaisyta naudojant nuostatą „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Liko maždaug <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Iki visiškos įkrovos liko <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Liko <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko maždaug <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Liko maždaug <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Liko maždaug <xliff:g id="TIME">^1</xliff:g>, atsižvelgiant į naudojimą"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Iki visiškos įkrovos liko <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Liko <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Liko <xliff:g id="TIME">^1</xliff:g>, atsižvelgiant į naudojimą"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – liko maždaug <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – liko maždaug <xliff:g id="TIME">^2</xliff:g>, atsižvelgiant į naudojimą"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – liko <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> iki visiško įkrovimo"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Nežinomas"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Kraunasi..."</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"įkraunama"</string>
diff --git a/packages/SettingsLib/res/values-lv/arrays.xml b/packages/SettingsLib/res/values-lv/arrays.xml
index 2c69c7e..10f94d0 100644
--- a/packages/SettingsLib/res/values-lv/arrays.xml
+++ b/packages/SettingsLib/res/values-lv/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (noklusējuma)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Sistēmas atlases izmantošana (nokl.)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Iespējot neobligātos kodekus"</item>
-    <item msgid="3304843301758635896">"Atspējot neobligātos kodekus"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Sistēmas atlases izmantošana (nokl.)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Iespējot neobligātos kodekus"</item>
-    <item msgid="741805482892725657">"Atspējot neobligātos kodekus"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Sistēmas atlases izmantošana (nokl.)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index c24ad5c..518eb33 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Savienojums nav izveidots zemas kvalitātes tīkla dēļ"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi savienojuma kļūme"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Autentificēšanas problēma"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Nevar izveidot savienojumu"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Nevar izveidot savienojumu ar tīklu <xliff:g id="AP_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Pārbaudiet paroli un mēģiniet vēlreiz."</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Nav diapazona ietvaros"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Savienojums netiks izveidots automātiski"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Nav piekļuves internetam"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Savienots, izmantojot %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Pieejams, izmantojot %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Savienots, nav piekļuves internetam"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Ļoti lēns"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lēns"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Labi"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Vidējs"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Ātrs"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Ļoti ātrs"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Atvienots"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Notiek atvienošana..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Notiek savienojuma izveide…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Sav. ir izveidots (nav multivides)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Savienots (nav piekļuves ziņojumam)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Sav. ir izveidots (nav tel. vai multiv.)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Savienojums izveidots, akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Savienojums izveidots (nav tālrunis), akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Savienojums izveidots (nav multivide), akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Savienojums izveidots (nav tālrunis vai multivide), akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Multivides audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Tālruņa audio"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Tālruņa zvani"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Failu pārsūtīšana"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Ievades ierīce"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Interneta piekļuve"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktpersonas informācijas kopīgošana"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Izmantot kontaktpersonas informācijas kopīgošanai"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Interneta savienojuma koplietošana"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Piekļuve ziņojumam"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Īsziņas"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Piekļuve SIM kartei"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Izmantot augstas kvalitātes audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Izmantot augstas kvalitātes audio"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Savienots ar multivides audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Savienots ar tālruņa audio"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Savienots ar failu pārsūtīšanas serveri"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresīva pāreja no Wi‑Fi uz mobilo tīklu"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vienmēr atļaut Wi‑Fi meklēšanu"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Vienmēr aktīvs mobilo datu savienojums"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Paātrināta aparatūras darbība piesaistei"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Atspējot absolūto skaļumu"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Iespējot iekšjoslas zvanīšanu"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP versija"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Atļaut neīstas vietas"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Iespējot atribūtu pārbaudi"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mobilo datu savienojums būs vienmēr aktīvs, pat ja būs aktīvs Wi-Fi savienojums (ātrai ierīces pārslēgšanai uz citu tīklu)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Izmantot paātrinātu aparatūras darbību piesaistei, ja tā ir pieejama"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Vai atļaut USB atkļūdošanu?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB atkļūdošana ir paredzēta tikai ar izstrādi saistītām darbībām. Izmantojiet to datu kopēšanai no datora uz ierīci un pretēji, lietotņu instalēšanai ierīcē bez paziņojumiem un žurnāla datu lasīšanai."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vai atcelt piekļuvi USB atkļūdošanai no visiem datoriem, kuriem iepriekš piešķīrāt piekļuvi?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Krāsu korekcija"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Šī funkcija ir eksperimentāla un var ietekmēt veiktspēju."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Jaunā preference: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Atlikušais laiks: aptuveni <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Atlikušais laiks līdz pilnai uzlādei: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Atlicis: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - vēl apmēram <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> — atlicis: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Atlikušais laiks: aptuveni <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Atlikušais laiks: aptuveni <xliff:g id="TIME">^1</xliff:g> (ņemot vērā lietojumu)"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Atlikušais laiks līdz pilnai uzlādei: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Atlicis: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Atlikušais laiks: <xliff:g id="TIME">^1</xliff:g> (ņemot vērā lietojumu)"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - vēl apmēram <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> — atlikušais laiks: aptuveni <xliff:g id="TIME">^2</xliff:g> (ņemot vērā lietojumu)"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> — atlicis: <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>, kamēr pilnībā uzlādēts"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>, kamēr pilnībā uzlādēts"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> — <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Nezināms"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Uzlāde"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"notiek uzlāde"</string>
diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml
index 2da43f0..d643113 100644
--- a/packages/SettingsLib/res/values-mk/arrays.xml
+++ b/packages/SettingsLib/res/values-mk/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Стандардно)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Користи избор на системот (стандардно)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Овозможување на „Кодеци по избор“"</item>
-    <item msgid="3304843301758635896">"Оневозможување на „Кодеци по избор“"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Користи избор на системот (стандардно)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Овозможи ја „Кодеци по избор“"</item>
-    <item msgid="741805482892725657">"Оневозможи ја „Кодеци по избор“"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Користи избор на системот (стандардно)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 1f2391d..c931d99 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Не е поврзано поради нискиот квалитет на мрежата"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Поврзувањето преку Wi-Fi не успеа"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Проблем со автентикација"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Не може да се поврзе"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Не може да се поврзе на „<xliff:g id="AP_NAME">%1$s</xliff:g>“"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Проверете ја лозинката и обидете се повторно"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Надвор од опсег"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Не може да се поврзе автоматски"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Нема пристап до Интернет"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Поврзано преку %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Достапно преку %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Поврзана, нема интернет"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Многу бавна"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Бавна"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Во ред"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Средна"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Брза"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Многу брза"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Исклучено"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Се исклучува..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Се поврзува..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Поврзани (без медиуми)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Поврзано (без порака за пристап)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Поврзан (без телефон или медиуми)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Поврзан, ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Поврзан (освен телефонот), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Поврзан (освен аудио-визуелните содржини), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Поврзан (освен телефонот и аудио-визуелните содржини), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Аудио на медиуми"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Аудио на телефон"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефонски повици"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Пренос на датотека"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Влезен уред"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Пристап на интернет"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Споделување контакти"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Користи за споделување контакти"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Споделување конекција на интернет"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Порака за пристап"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Текстуални пораки"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Пристап до SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Користи висококвалитетно аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Користи висококвалитетно аудио"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD аудио"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Поврзан со аудио на медиуми"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Поврзан со аудио на телефон"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Поврзан со сервер за пренос на датотеки"</string>
@@ -125,7 +138,7 @@
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> не е поддржано"</string>
     <string name="tts_status_checking" msgid="5339150797940483592">"Се проверува..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Поставки на <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
-    <string name="tts_engine_settings_button" msgid="1030512042040722285">"Стартувај подесувања на софтвер"</string>
+    <string name="tts_engine_settings_button" msgid="1030512042040722285">"Стартувај поставки на софтвер"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Претпочитан софтвер"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Општо"</string>
     <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Ресетирајте ја висината на изговорот"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Агресивно предавање од Wi‑Fi на мобилен"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Секогаш дозволувај Wi‑Fi скенирање во роаминг"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилниот интернет е секогаш активен"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардверско забрзување за врзување"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Оневозможете апсолутна јачина на звук"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Овозможете ѕвонење во појас"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Верзија Bluetooth AVRCP"</string>
@@ -204,11 +218,12 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Овозможи лажни локации"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Овозможете проверка на атрибутот на приказот"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Секогаш држи го активен мобилниот интернет, дури и при активно Wi-Fi (за брзо префрлување мрежа)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Ако е достапно, користете хардверско забрзување за врзување"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Овозможи отстранување грешки на USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Отстранувањето грешки на USB е наменето само за целите на развој. Користете го за копирање податоци меѓу вашиот компјутер и вашиот уред, за инсталирање апликации на вашиот уред без известување и за читање евиденција на податоци."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Отповикај пристап кон отстранување грешка од USB од сите претходно овластени компјутери?"</string>
-    <string name="dev_settings_warning_title" msgid="7244607768088540165">"Дозволи подесувања за развој?"</string>
-    <string name="dev_settings_warning_message" msgid="2298337781139097964">"Овие подесувања се наменети само за употреба за развој. Тие може да предизвикаат уредот и апликациите во него да се расипат или да се однесуваат необично."</string>
+    <string name="dev_settings_warning_title" msgid="7244607768088540165">"Дозволи поставки за развој?"</string>
+    <string name="dev_settings_warning_message" msgid="2298337781139097964">"Овие поставки се наменети само за употреба за развој. Тие може да предизвикаат уредот и апликациите во него да се расипат или да се однесуваат необично."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Потврди апликации преку USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Провери апликации инсталирани преку ADB/ADT за штетно однесување."</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Ја оневозможува карактеристиката за апсолутна јачина на звук преку Bluetooth во случај кога ќе настанат проблеми со далечинските уреди, како на пр., неприфатливо силен звук или недоволна контрола."</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекција на боја"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Функцијата е експериментална и може да влијае на изведбата."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Преостануваат околу <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Преостануваат <xliff:g id="TIME">%1$s</xliff:g> дури се наполни целосно"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"уште <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - уште околу <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - уште <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Преостануваат околу <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Уште околу <xliff:g id="TIME">^1</xliff:g> според користењето"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Преостануваат <xliff:g id="TIME">^1</xliff:g> дури се наполни целосно"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"уште <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Уште <xliff:g id="TIME">^1</xliff:g> според користењето"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - уште околу <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - уште околу <xliff:g id="TIME">^2</xliff:g> според користењето"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - уште <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> дури се наполни целосно"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> дури се наполни целосно"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Непознато"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Се полни"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"се полни"</string>
diff --git a/packages/SettingsLib/res/values-ml/arrays.xml b/packages/SettingsLib/res/values-ml/arrays.xml
index 57382f1..05c4877 100644
--- a/packages/SettingsLib/res/values-ml/arrays.xml
+++ b/packages/SettingsLib/res/values-ml/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (ഡിഫോൾട്ട്)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"സിസ്റ്റം സെലക്ഷൻ ഉപയോഗിക്കൂ ‌(ഡിഫോൾട്ട്)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"ഓപ്ഷണൽ കോഡെകുകൾ പ്രവർത്തനക്ഷമമാക്കുക"</item>
-    <item msgid="3304843301758635896">"ഓപ്ഷണൽ കോഡെകുകൾ പ്രവർത്തനരഹിതമാക്കുക"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"സിസ്റ്റം സെലക്ഷൻ ഉപയോഗിക്കൂ ‌(ഡിഫോൾട്ട്)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"ഓപ്ഷണൽ കോഡെകുകൾ പ്രവർത്തനക്ഷമമാക്കുക"</item>
-    <item msgid="741805482892725657">"ഓപ്ഷണൽ കോഡെകുകൾ പ്രവർത്തനരഹിതമാക്കുക"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"സിസ്റ്റം സെലക്ഷൻ ഉപയോഗിക്കൂ ‌(ഡിഫോൾട്ട്)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index a7d0dde..128d977 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"മോശം നെറ്റ്‌വർക്ക് ‌ആയതിനാൽ കണക്‌റ്റായില്ല"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi കണക്ഷൻ പരാജയം"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"ആധികാരികമാക്കുന്നതിലെ പ്രശ്‌നം"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"കണക്റ്റുചെയ്യാനാകുന്നില്ല"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' എന്നതിലേക്ക് കണക്‌റ്റുചെയ്യാനാകുന്നില്ല"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"പാസ്‌വേഡ് പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"പരിധിയിലില്ല"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"സ്വയമേവ കണക്‌റ്റുചെയ്യില്ല"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"ഇന്റർനെറ്റ് ആക്‌സസ്സ് ഇല്ല"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s വഴി ബന്ധിപ്പിച്ചു"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s വഴി ലഭ്യം"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"കണക്റ്റുചെയ്തിരിക്കുന്നു, ഇന്റർനെറ്റില്ല"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"വളരെ കുറഞ്ഞ വേഗത്തിൽ"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"കുറഞ്ഞ വേഗത്തിൽ"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ശരി"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"ഇടത്തരം"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"വേഗത്തിൽ"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"വളരെ വേഗത്തിൽ"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"വിച്ഛേദിച്ചു"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"വിച്‌ഛേദിക്കുന്നു..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"കണക്‌റ്റുചെയ്യുന്നു..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"കണക്‌റ്റുചെയ്‌തു (മീഡിയ ഇല്ല)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"കണക്റ്റുചെയ്‌തു (സന്ദേശ ആക്‌സസ്സില്ല)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"കണ‌ക്റ്റുചെ‌യ്തു (ഫോണോ മീഡിയയോ അല്ല)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"കണക്‌റ്റുചെയ്‌തു, ബാറ്ററി നില <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"കണ‌ക്റ്റുചെയ്‌തു (ഫോൺ ഇല്ല), ബാറ്ററി നില <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"കണക്‌റ്റുചെയ്‌തു (മീഡിയ ഇല്ല), ബാറ്ററി നില <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"കണ‌ക്റ്റുചെയ്‌തു (ഫോണോ മീഡിയയോ ഇല്ല), ബാറ്ററി നില<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"മീഡിയ ഓഡിയോ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ഫോൺ ഓഡിയോ"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ഫോണ്‍‌ കോളുകൾ"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ഫയൽ കൈമാറൽ"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ഇൻപുട്ട് ഉപകരണം"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ഇന്റർനെറ്റ് ആക്‌സസ്സ്"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"കോൺടാക്‌റ്റ് പങ്കിടൽ"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"കോൺടാക്‌റ്റ് പങ്കിടലിനായി ഉപയോഗിക്കുക"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ഇന്റർനെറ്റ് കണക്ഷൻ പങ്കിടൽ"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"ആക്‌സസ്സ് നിയന്ത്രിക്കുക"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"അക്ഷര സന്ദേശങ്ങൾ"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM ആക്സസ്"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ഉയർന്ന നിലവാരമുള്ള ഓഡിയോ ഉപയോഗിക്കുക: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ഉയർന്ന നിലവാരമുള്ള ഓഡിയോ ഉപയോഗിക്കുക"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ഓഡിയോ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ഓഡിയോ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"മീഡിയ ഓഡിയോയിലേക്ക് കണ‌ക്റ്റുചെയ്‌തു"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ഫോൺ ഓഡിയോയിൽ കണ‌ക്റ്റുചെ‌യ്‌തു"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ഫയൽ കൈമാറ്റ സെർവറിലേക്ക് കണ‌ക്റ്റുചെ‌യ്‌തു"</string>
@@ -100,12 +113,12 @@
     <string name="user_guest" msgid="8475274842845401871">"അതിഥി"</string>
     <string name="unknown" msgid="1592123443519355854">"അജ്ഞാതം"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"ഉപയോക്താവ്: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
-    <string name="launch_defaults_some" msgid="313159469856372621">"സ്ഥിരമായ ചിലവ സജ്ജീകരിച്ചു"</string>
+    <string name="launch_defaults_some" msgid="313159469856372621">"സ്ഥിരമായ ചിലത് സജ്ജീകരിച്ചു"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"സ്ഥിരമായൊന്നും സജ്ജീകരിച്ചിട്ടില്ല"</string>
     <string name="tts_settings" msgid="8186971894801348327">"ടെക്‌സ്റ്റ്-ടു-സ്‌പീച്ച് ക്രമീകരണങ്ങൾ"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"ടെക്‌സ്റ്റ്-ടു-സ്‌പീച്ച് ഔട്ട്‌പുട്ട്"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"വായന നിരക്ക്"</string>
-    <string name="tts_default_rate_summary" msgid="4061815292287182801">"വാചകം പറയുന്ന വേഗത"</string>
+    <string name="tts_default_rate_summary" msgid="4061815292287182801">"ടെക്സ്റ്റ് ചെയ്യൽ പറയുമ്പോഴുടെക്കുന്ന വേഗത"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"പിച്ച്"</string>
     <string name="tts_default_pitch_summary" msgid="1944885882882650009">"സിന്തസൈസ് ചെയ്ത സംസാരത്തിന്റെ സ്വരഭേദത്തെ ബാധിക്കുന്നു"</string>
     <string name="tts_default_lang_title" msgid="8018087612299820556">"ഭാഷ"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"മൊബൈൽ ഹാൻഡ്ഓവറിലേക്ക് വൈഫൈ സക്രിയമാക്കുക"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"എപ്പോഴും വൈഫൈ റോം സ്‌‌കാൻ അനുവദിക്കൂ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"മൊബൈൽ ഡാറ്റ എല്ലായ്‌പ്പോഴും സജീവം"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ടെതറിംഗ് ഹാർഡ്‌വെയർ ത്വരിതപ്പെടുത്തൽ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"അബ്‌സൊല്യൂട്ട് വോളിയം പ്രവർത്തനരഹിതമാക്കുക"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ഇൻ-ബാൻഡ് റിംഗുചെയ്യൽ പ്രവർത്തനക്ഷമമാക്കുക"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP പതിപ്പ്"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"വ്യാജ ലൊക്കേഷനുകൾ അനുവദിക്കുക"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"ആട്രിബ്യൂട്ട് പരിശോധന കാണൽ സജീവമാക്കൂ"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"വൈഫൈ സജീവമാണെങ്കിലും, മൊബൈൽ ഡാറ്റ സജീവമായി നിർത്തുക (വേഗത്തിൽ നെറ്റ്‌വർക്ക് മാറുന്നതിനായി)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ലഭ്യമാണെങ്കിൽ \'ടെതറിംഗ് ഹാർഡ്‌വെയർ ത്വരിതപ്പെടുത്തൽ\' ഉപയോഗിക്കുക"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB ഡീബഗ്ഗുചെയ്യാൻ അനുവദിക്കണോ?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB ഡീബഗ്ഗിംഗ് വികസന ആവശ്യകതകൾക്ക് മാത്രമുള്ളതാണ്. നിങ്ങളുടെ കമ്പ്യൂട്ടറിനും ഉപകരണത്തിനുമിടയിൽ ഡാറ്റ പകർത്തുന്നതിനും അറിയിപ്പില്ലാതെ തന്നെ നിങ്ങളുടെ ഉപകരണത്തിൽ അപ്ലിക്കേഷനുകൾ ഇൻസ്‌റ്റാളുചെയ്യുന്നതിനും ലോഗ് ഡാറ്റ റീഡുചെയ്യുന്നതിനും ഇത് ഉപയോഗിക്കുക."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"നിങ്ങൾ മുമ്പ് അംഗീകരിച്ച എല്ലാ കമ്പ്യൂട്ടറുകളിൽ നിന്നും USB ഡീബഗ്ഗുചെയ്യുന്നതിനുള്ള ആക്‌സസ്സ് പിൻവലിക്കണോ?"</string>
@@ -240,7 +255,7 @@
     <string name="show_touches_summary" msgid="6101183132903926324">"ടാപ്പുകൾക്ക് ദൃശ്യ ഫീഡ്ബാക്ക് കാണിക്കുക"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"സർഫേസ് അപ്‌ഡേറ്റ് കാണിക്കൂ"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"മുഴുവൻ വിൻഡോ സർഫേസുകളും അപ്‌ഡേറ്റുചെയ്‌തുകഴിയുമ്പോൾ അവ ഫ്ലാഷുചെയ്യുക"</string>
-    <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU കാഴ്ച അപ്‌ഡേറ്റ് കാണിക്കൂ"</string>
+    <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU കാഴ്‌ചയുടെ അപ്‌ഡേറ്റുകൾ കാണിക്കൂ"</string>
     <string name="show_hw_screen_updates_summary" msgid="1115593565980196197">"GPU ഉപയോഗിച്ച് വലിക്കുമ്പോൾ വിൻഡോകൾക്കുള്ളിൽ കാഴ്‌ചകൾ ഫ്ലാഷുചെയ്യുക"</string>
     <string name="show_hw_layers_updates" msgid="5645728765605699821">"ഹാർഡ്‌വെയർ ലേയർ അപ്‌ഡേറ്റ് കാണിക്കൂ"</string>
     <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"ഹാർഡ്‌വെയർ ലേയറുകളുടെ അപ്‌ഡേറ്റുകൾ പൂർത്തിയാകുമ്പോൾ അവ പച്ച നിറത്തിൽ പ്രകാശിപ്പിക്കുക"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"വർണ്ണം ക്രമീകരിക്കൽ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ഈ ഫീച്ചർ പരീക്ഷണാത്മകമായതിനാൽ പ്രകടനത്തെ ബാധിച്ചേക്കാം."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ഉപയോഗിച്ച് അസാധുവാക്കി"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"ഏകദേശം <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"മുഴുവൻ ചാർജാകാൻ <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ഏതാണ്ട് <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"ഏകദേശം <xliff:g id="TIME">^1</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"നിങ്ങളുടെ ഉപയോഗത്തെ അടിസ്ഥാനമാക്കി ഏതാണ്ട് <xliff:g id="TIME">^1</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"മുഴുവൻ ചാർജാകാൻ <xliff:g id="TIME">^1</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"നിങ്ങളുടെ ഉപയോഗത്തെ അടിസ്ഥാനമാക്കി <xliff:g id="TIME">^1</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - ഏതാണ്ട് <xliff:g id="TIME">^2</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - നിങ്ങളുടെ ഉപയോഗത്തെ അടിസ്ഥാനമാക്കി ഏതാണ്ട് <xliff:g id="TIME">^2</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ഫുൾ ചാർജാകാൻ <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - ഫുൾ ചാർജാകാൻ <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"അജ്ഞാതം"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"ചാർജ്ജുചെയ്യുന്നു"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ചാർജ് ചെയ്യുന്നു"</string>
diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml
index d6a0772..052bbac 100644
--- a/packages/SettingsLib/res/values-mn/arrays.xml
+++ b/packages/SettingsLib/res/values-mn/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Өгөгдмөл)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Системийн сонголтыг ашиглах (Өгөгдмөл)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Нэмэлт кодлогчийг идэвхжүүлэх"</item>
-    <item msgid="3304843301758635896">"Нэмэлт кодлогчийг идэвхгүй болгох"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Системийн сонголтыг ашиглах (Өгөгдмөл)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Нэмэлт кодлогчийг идэвхжүүлэх"</item>
-    <item msgid="741805482892725657">"Нэмэлт кодлогчийг идэвхгүй болгох"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Системийн сонголтыг ашиглах (Өгөгдмөл)"</item>
     <item msgid="8895532488906185219">"44.1 кГц"</item>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index d6853d0..1e864da 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Сүлжээний чанар муу байгаа тул холбогдож чадсангүй"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi холболт амжилтгүй"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Гэрчлэлийн асуудал"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Холбогдож чадсангүй"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'-д холбогдож чадсангүй"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Нууц үгийг шалгаад дахин оролдоно уу"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Хүрээнд байхгүй"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Автоматаар холбогдохгүй"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Интернэт холболт алга"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-р холбогдсон"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s-р боломжтой"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Холбогдсон, интернэт байхгүй байна"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Маш удаан"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Удаан"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ЗА"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Дунд"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Хурдан"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Маш хурдан"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Салгагдсан"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Салгаж байна…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Холбогдож байна..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Холбогдсон (медиа байхгүй)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Холбогдсон (зурвас хандалт байхгүй)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Холбогдсон (утас буюу медиа байхгүй)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Холбогдсон, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Холбогдсон (утас байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Холбогдсон (медиа байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Холбогдсон (утас эсвэл медиа байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Медиа аудио"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Утасны аудио"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Утасны дуудлага"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Файл дамжуулалт"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Оруулах төхөөрөмж"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Интернэт хандалт"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Харилцагч хуваалцах"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Харилцагч хуваалцахад ашиглах"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Интернэт холболтыг хуваалцах"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Зурвас хандалт"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Мессеж"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Хандалт"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Өндөр чанарын аудио ашиглах: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Өндөр чанарын аудио ашиглах"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD аудио"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Медиа аудиод холбогдсон"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Утасны аудид холбогдсон"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Файл дамжуулах серверт холбогдсон"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Идэвхтэй Wi‑Fi-с мобайл сүлжээнд"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi Роум сканыг байнга зөвшөөрөх"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобайл дата байнга идэвхтэй"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Модем болгох хардвер хурдасгуур"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Үнэмлэхүй дууны түвшинг идэвхгүй болгох"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Сүлжээний хонхны аяыг идэвхжүүлэх"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP хувилбар"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Хуурамч байршлыг зөвшөөрөх"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Харах тохируулгын шалгалтыг идэвхжүүлэх"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi‑Fi идэвхтэй байхад ч гэсэн гар утасны датаг идэвхтэй байлгадаг (сүлжээг түргэн солихын тулд)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Модем болгох хардвер хурдасгуурыг боломжтой тохиолдолд ашиглах"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB дебаг хийхийг зөвшөөрөх үү?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB дебаг нь зөвхөн хөгжүүлэлтийн зорилготой. Үүнийг өөрийн компьютер болон төхөөрөмжийн хооронд өгөгдөл хуулах, өөрийн төхөөрөмж дээр мэдэгдэлгүйгээр аппликейшн суулгах, лог датаг унших зэрэгт ашиглаж болно."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Таны өмнө нь зөвшөөрөл өгсөн бүх компьютерээс USB дебаг хандалтыг нь хураах уу?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Өнгө тохируулах"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Энэ функц туршилтынх бөгөөд ажиллагаанд нөлөөлж болзошгүй."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Давхарласан <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Ойролцоогоор <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Бүрэн цэнэглэх хүртэл <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g>-с <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Ойролцоогоор <xliff:g id="TIME">^1</xliff:g> үлдсэн"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Таны хэрэглээнд тулгуурлан <xliff:g id="TIME">^1</xliff:g> орчмын хугацаа үлдсэн байна"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Бүрэн цэнэглэх хүртэл <xliff:g id="TIME">^1</xliff:g> үлдсэн"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> үлдсэн"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Таны хэрэглээнд тулгуурлан <xliff:g id="TIME">^1</xliff:g> орчмын хугацаа үлдсэн байна"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g>-с <xliff:g id="TIME">^2</xliff:g> үлдсэн"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - таны хэрэглээнд тулгуурлан <xliff:g id="TIME">^2</xliff:g> орчмын хугацаа үлдсэн байна"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"бүрэн цэнэглэх хүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"бүрэн цэнэглэх хүртэл <xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Тодорхойгүй"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Цэнэглэж байна"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"цэнэглэж байна"</string>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index 5c7b15f..e86f144 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -25,7 +25,7 @@
     <item msgid="8934131797783724664">"स्कॅन करत आहे…"</item>
     <item msgid="8513729475867537913">"कनेक्ट करत आहे..."</item>
     <item msgid="515055375277271756">"प्रमाणीकरण करत आहे…"</item>
-    <item msgid="1943354004029184381">"IP पत्ता प्राप्त करत आहे…"</item>
+    <item msgid="1943354004029184381">"IP पत्ता मिळवत आहे…"</item>
     <item msgid="4221763391123233270">"कनेक्ट केले"</item>
     <item msgid="624838831631122137">"निलंबित"</item>
     <item msgid="7979680559596111948">"डिस्कनेक्ट करत आहे..."</item>
@@ -39,7 +39,7 @@
     <item msgid="8878186979715711006">"स्कॅन करत आहे…"</item>
     <item msgid="355508996603873860">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> वर कनेक्ट करत आहे…"</item>
     <item msgid="554971459996405634">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> सह प्रमाणीकरण करत आहे…"</item>
-    <item msgid="7928343808033020343">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> वरून IP पत्ता प्राप्त करत आहे…"</item>
+    <item msgid="7928343808033020343">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> वरून IP पत्ता मिळवत आहे…"</item>
     <item msgid="8937994881315223448">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> वर कनेक्ट केले आहे"</item>
     <item msgid="1330262655415760617">"निलंबित"</item>
     <item msgid="7698638434317271902">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> वरून डिस्कनेक्ट करत आहे…"</item>
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (डीफॉल्ट)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"प्रणाली निवड वापरा (डीफॉल्ट)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"पर्यायी कोडेक सक्षम करा"</item>
-    <item msgid="3304843301758635896">"पर्यायी कोडेक अक्षम करा"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"प्रणाली निवड वापरा (डीफॉल्ट)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"पर्यायी कोडेक सक्षम करा"</item>
-    <item msgid="741805482892725657">"पर्यायी कोडेक अक्षम करा"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"प्रणाली निवड वापरा (डीफॉल्ट)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
@@ -104,15 +90,15 @@
   </string-array>
   <string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
     <item msgid="2684127272582591429">"प्रणाली निवड वापरा (डीफॉल्ट)"</item>
-    <item msgid="5618929009984956469">"16 बिट/नमुना"</item>
-    <item msgid="3412640499234627248">"24 बिट/नमुना"</item>
-    <item msgid="121583001492929387">"32 बिट/नमुना"</item>
+    <item msgid="5618929009984956469">"16 बिट/पॅटर्न"</item>
+    <item msgid="3412640499234627248">"24 बिट/पॅटर्न"</item>
+    <item msgid="121583001492929387">"32 बिट/पॅटर्न"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
     <item msgid="1081159789834584363">"प्रणाली निवड वापरा (डीफॉल्ट)"</item>
-    <item msgid="4726688794884191540">"16 बिट/नमुना"</item>
-    <item msgid="305344756485516870">"24 बिट/नमुना"</item>
-    <item msgid="244568657919675099">"32 बिट/नमुना"</item>
+    <item msgid="4726688794884191540">"16 बिट/पॅटर्न"</item>
+    <item msgid="305344756485516870">"24 बिट/पॅटर्न"</item>
+    <item msgid="244568657919675099">"32 बिट/पॅटर्न"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_channel_mode_titles">
     <item msgid="5226878858503393706">"प्रणाली निवड वापरा (डीफॉल्ट)"</item>
@@ -128,13 +114,13 @@
     <item msgid="7158319962230727476">"ऑडिओ गुणवत्ता (990kbps/909kbps) साठी ऑप्टिमाइझ केली"</item>
     <item msgid="2921767058740704969">"संतुलित ऑडिओ आणि कनेक्शन गुणवत्ता (660kbps/606kbps)"</item>
     <item msgid="8860982705384396512">"कनेक्शन गुणवत्ता (330kbps/303kbps) साठी ऑप्टिमाइझ केली"</item>
-    <item msgid="4414060457677684127">"सर्वोत्तम प्रयत्न (अनुकूल बिट दर)"</item>
+    <item msgid="4414060457677684127">"सर्वोत्तम प्रयत्न (अनुकूल बिट रेट)"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
     <item msgid="6398189564246596868">"ऑडिओ गुणवत्तेसाठी ऑप्टिमाइझ केले"</item>
     <item msgid="4327143584633311908">"संतुलित ऑडिओ आणि कनेक्शन गुणवत्ता"</item>
     <item msgid="4681409244565426925">"कनेक्शन गुणवत्तेसाठी ऑप्टिमाइझ केले"</item>
-    <item msgid="364670732877872677">"सर्वोत्तम प्रयत्न (अनुकूल बिट दर)"</item>
+    <item msgid="364670732877872677">"सर्वोत्तम प्रयत्न (अनुकूल बिट रेट)"</item>
   </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"बंद"</item>
@@ -220,7 +206,7 @@
   <string-array name="show_non_rect_clip_entries">
     <item msgid="993742912147090253">"बंद"</item>
     <item msgid="675719912558941285">"निळ्या रंगात आयताकार नसलेला क्लिप प्रांत रेखांकित करा"</item>
-    <item msgid="1064373276095698656">"चाचणी केलेले रेखांकित आदेश हिरव्या रंगामध्ये हायलाइट करा"</item>
+    <item msgid="1064373276095698656">"चाचणी केलेल्या रेखांकित कमांड हिरव्या रंगामध्ये हायलाइट करा"</item>
   </string-array>
   <string-array name="track_frame_time_entries">
     <item msgid="2193584639058893150">"बंद"</item>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 0e76443..66f8cec 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -28,15 +28,24 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"कमी दर्जाच्या नेटवर्कमुळे कनेक्ट केलेले नाही"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi कनेक्शन अयशस्वी"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"प्रमाणीकरण समस्या"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"कनेक्ट करू शकत नाही"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'शी कनेक्‍ट करू शकत नाही"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"पासवर्ड तपासा आणि पुन्‍हा प्रयत्‍न करा"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"परिक्षेत्रामध्ये नाही"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"स्वयंचलितपणे कनेक्ट करणार नाही"</string>
-    <string name="wifi_no_internet" msgid="3880396223819116454">"इंटरनेट प्रवेश नाही"</string>
+    <string name="wifi_no_internet" msgid="3880396223819116454">"इंटरनेट अॅक्सेस नाही"</string>
     <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> द्वारे जतन केले"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s द्वारे स्वयंचलितपणे कनेक्ट केले"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"नेटवर्क रेटिंग प्रदात्याद्वारे स्वयंचलितपणे कनेक्ट केले"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s द्वारे कनेक्‍ट केले"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s द्वारे उपलब्‍ध"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"कनेक्‍ट केले, इंटरनेट नाही"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"खूप हळू"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"हळू"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ठीक आहे"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"मध्‍यम"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"जलद"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"खूप जलद"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"डिस्कनेक्ट केले"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"डिस्कनेक्ट करत आहे..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"कनेक्ट करीत आहे..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"कनेक्ट केले (मीडिया नाही)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"कनेक्ट केलेले आहे (कोणत्याही संदेशामध्ये प्रवेश नाही)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"कनेक्ट केले (फोन किंवा मीडिया नाही)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"कनेक्ट केलेले आहे, बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"कनेक्ट केलेले आहे (कोणताही फोन नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"कनेक्ट केलेले आहे (कोणताही मीडिया नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"कनेक्ट केलेले आहे (कोणताही फोन किंवा मीडिया नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मीडिया ऑडिओ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"फोन ऑडिओ"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"फोन कॉल"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"फाइल स्थानांतरण"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"इनपुट डिव्हाइस"</string>
-    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"इंटरनेट प्रवेश"</string>
+    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"इंटरनेट अॅक्सेस"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"संपर्क सामायिकरण"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"संपर्क सामायिकरणासाठी वापरा"</string>
-    <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"इंटरनेट कनेक्शन सामायिकरण"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"संदेशात प्रवेश"</string>
+    <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"इंटरनेट कनेक्शन शेअररण"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"मजकूर संदेश"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"सिम प्रवेश"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"उच्च दर्जाचा ऑडिओ वापरा: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"उच्च दर्जाचा ऑडिओ वापरा"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ऑडिओ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ऑडिओ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"मीडिया ऑडिओवर कनेक्ट केले"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"फोन ऑडिओ वर कनेक्ट केले"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"फाईल स्थानांतर सर्व्हरवर कनेक्ट केले"</string>
@@ -65,23 +78,23 @@
     <string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"SAP शी कनेक्‍ट केले"</string>
     <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"फाइल स्थानांतर सर्व्हरशी कनेक्ट केले नाही"</string>
     <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"इनपुट डिव्हाइसवर कनेक्ट केले"</string>
-    <string name="bluetooth_pan_user_profile_summary_connected" msgid="4602294638909590612">"इंटरनेट प्रवेशासाठी डिव्हाइसवर कनेक्ट केले"</string>
-    <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1561383706411975199">"डिव्हाइससह स्थानिक इंटरनेट कनेक्शन सामायिक करत आहे"</string>
-    <string name="bluetooth_pan_profile_summary_use_for" msgid="5664884523822068653">"इंटरनेट प्रवेशासाठी वापरा"</string>
+    <string name="bluetooth_pan_user_profile_summary_connected" msgid="4602294638909590612">"इंटरनेट अॅक्सेससाठी डीव्हाइसवर कनेक्ट केले"</string>
+    <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1561383706411975199">"डीव्हाइससह स्थानिक इंटरनेट कनेक्शन शेअर करत आहे"</string>
+    <string name="bluetooth_pan_profile_summary_use_for" msgid="5664884523822068653">"इंटरनेट अॅक्सेससाठी वापरा"</string>
     <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"नकाशासाठी वापरा"</string>
     <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"SIM प्रवेशासाठी वापरा"</string>
     <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"मीडिया ऑडिओसाठी वापरा"</string>
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"फोन ऑडिओसाठी वापरा"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"फाईल स्थानांतरणासाठी वापरा"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"इनपुट साठी वापरा"</string>
-    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"जोडा"</string>
-    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"जोडा"</string>
+    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"पेअर करा"</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"पेअर करा"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"रद्द करा"</string>
-    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"कनेक्‍ट केल्यावर जोडणी आपले संपर्क आणि कॉल इतिहास यावरील प्रवेशास मंजूरी देते."</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"कनेक्‍ट केल्यावर पेअरींग तुमचे संपर्क आणि कॉल इतिहास यामध्ये अॅक्सेस देते."</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> शी जोडू शकलो नाही."</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"अयोग्य पिन किंवा पासकीमुळे <xliff:g id="DEVICE_NAME">%1$s</xliff:g> सह जोडू शकलो नाही."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> शी संप्रेषण करू शकत नाही."</string>
-    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> द्वारे जोडणी नाकारली."</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> द्वारे पेअरींग नाकारले."</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"वाय फाय बंद."</string>
     <string name="accessibility_no_wifi" msgid="8834610636137374508">"वाय फाय डिस्कनेक्ट झाले."</string>
     <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"वाय फाय एक बार."</string>
@@ -93,8 +106,8 @@
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"काढलेले अॅप्स आणि वापरकर्ते"</string>
     <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB टेदरिंग"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"पोर्टेबल हॉटस्पॉट"</string>
-    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"ब्लूटुथ टेदरिंग"</string>
-    <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"टिथरिंग"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"ब्लूटूथ टेदरिंग"</string>
+    <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"टेदरिंग"</string>
     <string name="tether_settings_title_all" msgid="8356136101061143841">"टेदरिंग आणि पोर्टेबल हॉटस्पॉट"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"सर्व कार्य अॅप्स"</string>
     <string name="user_guest" msgid="8475274842845401871">"अतिथी"</string>
@@ -114,8 +127,8 @@
     <string name="tts_default_lang_summary" msgid="5219362163902707785">"बोललेल्या मजकुरासाठी भाषा-विशिष्ट आवाज सेट करते"</string>
     <string name="tts_play_example_title" msgid="7094780383253097230">"उदाहरण ऐका"</string>
     <string name="tts_play_example_summary" msgid="8029071615047894486">"उच्चार संश्लेषणाचे एक छोटेसे प्रात्यक्षिक प्ले करा"</string>
-    <string name="tts_install_data_title" msgid="4264378440508149986">"व्हॉइस डेटा स्थापित करा"</string>
-    <string name="tts_install_data_summary" msgid="5742135732511822589">"उच्चार संश्लेषणासाठी आवश्यक आवाज डेटा स्थापित करा"</string>
+    <string name="tts_install_data_title" msgid="4264378440508149986">"व्हॉइस डेटा इंस्टॉल करा"</string>
+    <string name="tts_install_data_summary" msgid="5742135732511822589">"उच्चार संश्लेषणासाठी आवश्यक आवाज डेटा इंस्टॉल करा"</string>
     <string name="tts_engine_security_warning" msgid="8786238102020223650">"हे उच्चार संश्लेषण इंजिन संकेतशब्द आणि क्रेडिट कार्ड नंबर यासारख्या वैयक्तिक मजकुरासह, बोलला जाणारा सर्व मजकूर संकलित करण्यात सक्षम होऊ शकते. हे <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> इंजिनवरून येते. या उच्चार संश्लेषण इंजिनचा वापर सक्षम करायचा?"</string>
     <string name="tts_engine_network_required" msgid="1190837151485314743">"या भाषेस टेक्‍स्‍ट टू स्‍पीचसाठी एका नेटवर्क कनेक्शनची आवश्यकता आहे."</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"हे उच्चार संश्लेषणाचे एक उदाहरण आहे"</string>
@@ -144,53 +157,54 @@
     <string name="choose_profile" msgid="6921016979430278661">"प्रोफाइल निवडा"</string>
     <string name="category_personal" msgid="1299663247844969448">"वैयक्तिक"</string>
     <string name="category_work" msgid="8699184680584175622">"कार्य"</string>
-    <string name="development_settings_title" msgid="215179176067683667">"विकासक पर्याय"</string>
-    <string name="development_settings_enable" msgid="542530994778109538">"विकासक पर्याय सक्षम करा"</string>
+    <string name="development_settings_title" msgid="215179176067683667">"डेव्हलपर पर्याय"</string>
+    <string name="development_settings_enable" msgid="542530994778109538">"डेव्हलपर पर्याय सुरू करा"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"अॅप विकासासाठी पर्याय सेट करा"</string>
-    <string name="development_settings_not_available" msgid="4308569041701535607">"या वापरकर्त्यासाठी विकासक पर्याय उपलब्ध नाहीत"</string>
+    <string name="development_settings_not_available" msgid="4308569041701535607">"या वापरकर्त्यासाठी डेव्हलपर पर्याय उपलब्ध नाहीत"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"या वापरकर्त्यासाठी VPN सेटिंग्ज उपलब्ध नाहीत"</string>
-    <string name="tethering_settings_not_available" msgid="6765770438438291012">"या वापरकर्त्यासाठी टिथरिंग सेटिंग्ज उपलब्ध नाहीत"</string>
-    <string name="apn_settings_not_available" msgid="7873729032165324000">"या वापरकर्त्यासाठी प्रवेश बिंदू नाव सेटिंग्ज उपलब्ध नाहीत"</string>
+    <string name="tethering_settings_not_available" msgid="6765770438438291012">"या वापरकर्त्यासाठी टेदरिंग सेटिंग्ज उपलब्ध नाहीत"</string>
+    <string name="apn_settings_not_available" msgid="7873729032165324000">"या वापरकर्त्यासाठी अॅक्सेस बिंदू नाव सेटिंग्ज उपलब्ध नाहीत"</string>
     <string name="enable_adb" msgid="7982306934419797485">"USB डीबग करणे"</string>
     <string name="enable_adb_summary" msgid="4881186971746056635">"USB कनेक्ट केलेले असताना डीबग मोड"</string>
-    <string name="clear_adb_keys" msgid="4038889221503122743">"USB डीबग करणारी प्रमाणिकरणे पुनर्प्राप्त करा"</string>
-    <string name="bugreport_in_power" msgid="7923901846375587241">"दोष अहवाल शॉर्टकट"</string>
-    <string name="bugreport_in_power_summary" msgid="1778455732762984579">"दोष अहवाल घेण्यासाठी पॉवर मेनूमध्ये एक बटण दर्शवा"</string>
+    <string name="clear_adb_keys" msgid="4038889221503122743">"USB डीबग करणारी प्रमाणीकरणे रीव्होक करा"</string>
+    <string name="bugreport_in_power" msgid="7923901846375587241">"बग रीपोर्ट शॉर्टकट"</string>
+    <string name="bugreport_in_power_summary" msgid="1778455732762984579">"बग रीपोर्ट घेण्यासाठी पॉवर मेनूमध्ये एक बटण दर्शवा"</string>
     <string name="keep_screen_on" msgid="1146389631208760344">"सक्रिय रहा"</string>
     <string name="keep_screen_on_summary" msgid="2173114350754293009">"चार्ज होत असताना स्क्रीन कधीही निष्क्रिय होणार नाही"</string>
-    <string name="bt_hci_snoop_log" msgid="3340699311158865670">"ब्लूटुथ HCI स्नूप लॉग सक्षम करा"</string>
-    <string name="bt_hci_snoop_log_summary" msgid="730247028210113851">"सर्व ब्लूटुथ HCI पॅकेट एका फाईलमध्ये कॅप्चर करा"</string>
+    <string name="bt_hci_snoop_log" msgid="3340699311158865670">"ब्लूटूथ HCI स्नूप लॉग सक्षम करा"</string>
+    <string name="bt_hci_snoop_log_summary" msgid="730247028210113851">"सर्व ब्लूटूथ HCI पॅकेट एका फाईलमध्ये कॅप्चर करा"</string>
     <string name="oem_unlock_enable" msgid="6040763321967327691">"OEM अनलॉक करणे"</string>
     <string name="oem_unlock_enable_summary" msgid="4720281828891618376">"बूटलोडर अनलॉक करण्यासाठी अनुमती द्या"</string>
     <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM अनलॉक करण्यास अनुमती द्यायची?"</string>
-    <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"चेतावणी: ही सेटिंग चालू असताना या डिव्हाइसवर डिव्हाइस संरक्षण वैशिष्ट्ये कार्य करणार नाहीत."</string>
+    <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"चेतावणी: हे सेटिंग चालू असताना या डिव्हाइस वर डिव्हाइस संरक्षण वैशिष्ट्ये काम करणार नाहीत."</string>
     <string name="mock_location_app" msgid="7966220972812881854">"बनावट स्थान अॅप निवडा"</string>
     <string name="mock_location_app_not_set" msgid="809543285495344223">"कोणताही बनावट स्थान अॅप सेट केला नाही"</string>
     <string name="mock_location_app_set" msgid="8966420655295102685">"बनावट स्थान अॅप: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="debug_networking_category" msgid="7044075693643009662">"नेटवर्किंग"</string>
-    <string name="wifi_display_certification" msgid="8611569543791307533">"वायरलेस प्रदर्शन प्रमाणीकरण"</string>
-    <string name="wifi_verbose_logging" msgid="4203729756047242344">"वाय-फाय शब्दपाल्हाळ लॉगिंग सक्षम करा"</string>
-    <string name="wifi_aggressive_handover" msgid="5309131983693661320">"मोबाइलकडे सोपवण्यासाठी आक्रमक वाय-फाय"</string>
+    <string name="wifi_display_certification" msgid="8611569543791307533">"वायरलेस डिस्प्ले प्रमाणीकरण"</string>
+    <string name="wifi_verbose_logging" msgid="4203729756047242344">"वाय-फाय व्हर्बोझ लॉगिंग सक्षम करा"</string>
+    <string name="wifi_aggressive_handover" msgid="5309131983693661320">"मोबाइलकडे सोपवण्यासाठी अॅग्रेसिव्ह वाय-फाय"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"वाय-फाय रोम स्‍कॅनला नेहमी अनुमती द्या"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा नेहमी सक्रिय"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"टेदरिंग हार्डवेअर प्रवेग"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"संपूर्ण आवाज अक्षम करा"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"इन-बँड रिंगिंग सक्षम करा"</string>
-    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ब्लूटुथ AVRCP आवृत्ती"</string>
-    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ब्लूटुथ AVRCP आवृत्ती निवडा"</string>
+    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ब्लूटूथ AVRCP आवृत्ती"</string>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ब्लूटूथ AVRCP आवृत्ती निवडा"</string>
     <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ब्लूटूथ ऑडिओ कोडेक"</string>
-    <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ब्लूटुथ ऑडिओ कोडेक निवडा"</string>
-    <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ब्लूटूथ ऑडिओ नमुना दर"</string>
-    <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5628790207448471613">"ब्लूटुथ ऑडिओ कोडेक निवडा:\nनमुना दर"</string>
-    <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="2099645202720164141">"प्रति नमुना ब्लूटुथ ऑडिओ बिट"</string>
-    <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4546131401358681321">"ब्लूटुथ ऑडिओ कोडेक निवडा:\nबिट प्रति नमुना"</string>
+    <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ब्लूटूथ ऑडिओ कोडेक निवडा"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ब्लूटूथ ऑडिओ पॅटर्न दर"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5628790207448471613">"ब्लूटूध ऑडिओ कोडेक निवडा:\nपॅटर्न दर"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="2099645202720164141">"प्रति पॅटर्न ब्लूटूध ऑडिओ बिट"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4546131401358681321">"ब्लूटूध ऑडिओ कोडेक निवडा:\nबिट प्रति पॅटर्न"</string>
     <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"ब्लूटूथ ऑडिओ चॅनेल मोड"</string>
-    <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="9133545781346216071">"ब्लूटुथ ऑडिओ कोडेक निवडा:\nचॅनेल मोड"</string>
-    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ब्लूटुथ ऑडिओ LDAC कोडेक: प्लेबॅक गुणवत्ता"</string>
-    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ब्लूटुथ ऑडिओ LDAC कोडेक निवडा:\nप्लेबॅक गुणवत्ता"</string>
-    <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"धारावाहिक: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
-    <string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस प्रदर्शन प्रमाणिकरणासाठी पर्याय दर्शवा"</string>
-    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाय-फाय लॉगिंग स्‍तर वाढवा, वाय-फाय निवडकामध्‍ये प्रति SSID RSSI दर्शवा"</string>
-    <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"सक्षम केले असताना, वाय-फाय सिग्‍नल कमी असताना, मोबाइलकडे डेटा कनेक्‍शन सोपवण्यासाठी वाय-फाय अधिक आक्रमक असेल."</string>
+    <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="9133545781346216071">"ब्लूटूथ ऑडिओ कोडेक निवडा:\nचॅनेल मोड"</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ब्लूटूथ ऑडिओ LDAC कोडेक: प्लेबॅक गुणवत्ता"</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ब्लूटूथ ऑडिओ LDAC कोडेक निवडा:\nप्लेबॅक गुणवत्ता"</string>
+    <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"स्ट्रीमिंग: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
+    <string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस डिस्प्ले प्रमाणिकरणाचे पर्याय दाखवा"</string>
+    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाय-फाय लॉगिंग स्‍तर वाढवा, वाय-फाय सिलेक्टरमध्‍ये प्रति SSID RSSI दर्शवा"</string>
+    <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"सक्षम केले असताना, वाय-फाय सिग्‍नल कमी असताना, मोबाइलकडे डेटा कनेक्‍शन सोपवण्यासाठी वाय-फाय अधिक अॅग्रेसिव्ह असेल."</string>
     <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"वाय-फाय रोम स्‍कॅनला इंटरफेसवर उपस्‍थित असलेल्‍या रहदारी डेटाच्या प्रमाणावर आधारित अनुमती द्या/अनुमती देऊ नका"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"लॉगर बफर आकार"</string>
     <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"प्रति लॉग बफर लॉगर आकार निवडा"</string>
@@ -203,28 +217,29 @@
     <string name="allow_mock_location" msgid="2787962564578664888">"बनावट स्थानांना अनुमती द्या"</string>
     <string name="allow_mock_location_summary" msgid="317615105156345626">"बनावट स्थानांना अनुमती द्या"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"दृश्‍य विशेषता तपासणी सक्षम करा"</string>
-    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"जरी वाय-फाय सक्रिय असले तरीही, नेहमी मोबाईल डेटा सक्रिय ठेवा (जलद नेटवर्क स्विच करण्यासाठी)."</string>
+    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"जरी वाय-फाय चालू असले तरीही, मोबाईल डेटा नेहमी चालू ठेवा (नेटवर्क जलदरीत्या स्विच करण्यासाठी)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"उपलब्ध असल्यास टेदरिंग हार्डवेअर प्रवेग वापरा"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB डीबग करण्यास अनुमती द्यायची?"</string>
-    <string name="adb_warning_message" msgid="7316799925425402244">"USB डीबग करण्याचा हेतू फक्त विकासाच्या उद्देशांसाठी आहे. याचा वापर आपला संगणक आणि आपले डिव्हाइस यांच्या दरम्यान डेटा कॉपी करण्यासाठी करा, सूचनेशिवाय आपल्या डिव्हाइसवर अॅप्स स्थापित करा आणि लॉग डेटा वाचा."</string>
-    <string name="adb_keys_warning_message" msgid="5659849457135841625">"आपण पूर्वी प्राधिकृत केलेल्या सर्व संगणकांवरुन USB डीबग करण्यासाठी प्रवेश पुनर्प्राप्त करायचा?"</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"USB डीबग करण्याचा हेतू फक्त विकास उद्देशांसाठी आहे. याचा वापर तुमचा कॉंप्युटर आणि तुमचे डिव्हाइस यांच्या दरम्यान डेटा कॉपी करण्यासाठी करा, सूचनेशिवाय तुमच्या डिव्हाइस वर अॅप्स इंस्टॉल करा आणि लॉग डेटा वाचा."</string>
+    <string name="adb_keys_warning_message" msgid="5659849457135841625">"आपण पूर्वी अॉथोराइझ केलेल्या सर्व संगणकांवरुन USB डीबग करण्यासाठी अॅक्सेस रीव्होक करायचा?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"विकास सेटिंग्जला अनुमती द्यायची?"</string>
-    <string name="dev_settings_warning_message" msgid="2298337781139097964">"या सेटिंग्जचा हेतू फक्त विकास करण्याच्या वापरासाठी आहे. त्यामुळे आपले डिव्हाइस आणि त्यावरील अनुप्रयोग विघटित होऊ शकतात किंवा गैरवर्तन करू शकतात."</string>
-    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB वरील अॅप्स सत्यापित करा"</string>
-    <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"हानिकारक वर्तनासाठी ADB/ADT द्वारे स्थापित अॅप्स तपासा."</string>
-    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"दूरस्थ डिव्हाइसेसमध्ये सहन न होणारा मोठा आवाज किंवा नियंत्रणचा अभाव यासारखी आवाजाची समस्या असल्यास ब्लूटुथ संपूर्ण आवाज वैशिष्ट्य अक्षम करते."</string>
-    <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"फोनवरील रिंगटोन ब्लूटुथ हेडसेटवर वाजू द्या"</string>
+    <string name="dev_settings_warning_message" msgid="2298337781139097964">"या सेटिंग्जचा हेतू फक्त विकास वापरासाठी आहे. त्यामुळे तुमचे डिव्हाइस आणि त्यावरील अॅप्लिकेशन ब्रेक होऊ शकतात किंवा नेहमीपेक्षा वेगळे वर्तन करू शकतात."</string>
+    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB वर अॅप्स पडताळून पाहा"</string>
+    <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"हानिकारक वर्तनासाठी ADB/ADT द्वारे इंस्टॉल अॅप्स तपासा."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"दूरस्थ डीव्हाइसमध्ये सहन न होणारा मोठा आवाज किंवा नियंत्रणचा अभाव यासारखी आवाजाची समस्या असल्यास ब्लूटूथ संपूर्ण आवाज वैशिष्ट्य अक्षम करते."</string>
+    <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"फोनवरील रिंगटोन ब्लूटूथ हेडसेटवर वाजू द्या"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"स्थानिक टर्मिनल"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"स्थानिक शेल प्रवेश देणारा टर्मिनल अॅप सक्षम करा"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP तपासणी"</string>
     <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"HDCP तपासणी वर्तन सेट करा"</string>
     <string name="debug_debugging_category" msgid="6781250159513471316">"डीबग करणे"</string>
     <string name="debug_app" msgid="8349591734751384446">"डीबग अॅप निवडा"</string>
-    <string name="debug_app_not_set" msgid="718752499586403499">"कोणताही डीबग अनुप्रयोग सेट नाही"</string>
-    <string name="debug_app_set" msgid="2063077997870280017">"अनुप्रयोग डीबग करीत आहे: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="select_application" msgid="5156029161289091703">"अनुप्रयोग निवडा"</string>
+    <string name="debug_app_not_set" msgid="718752499586403499">"कोणतेही डीबग अॅप्लिकेशन सेट नाही"</string>
+    <string name="debug_app_set" msgid="2063077997870280017">"अॅप्लिकेशन डीबग करीत आहे: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="select_application" msgid="5156029161289091703">"अॅप्लिकेशन निवडा"</string>
     <string name="no_application" msgid="2813387563129153880">"काहीही नाही"</string>
     <string name="wait_for_debugger" msgid="1202370874528893091">"डीबगरची प्रतीक्षा करा"</string>
-    <string name="wait_for_debugger_summary" msgid="1766918303462746804">"डीबग केलेला अनुप्रयोग अंमलात आणण्यापूर्वी डीबगर संलग्न करण्याची प्रतीक्षा करतो"</string>
+    <string name="wait_for_debugger_summary" msgid="1766918303462746804">"डीबग केलेले अॅप्लिकेशन अंमलात आणण्यापूर्वी डीबगर संलग्न करण्याची प्रतीक्षा करतो"</string>
     <string name="telephony_monitor_switch" msgid="1764958220062121194">"टेलिफोनी मॉनिटर"</string>
     <string name="telephony_monitor_switch_summary" msgid="7695552966547975635">"टेलिफोनी/मोडेमच्‍या कार्यक्षमतेत समस्‍या आढळल्‍यावर टेलिफोनी मॉनिटर लॉग्‍ज गोळा करेल आणि दोष फाइल करण्‍यासाठी वापरकर्त्याला सूचनेचे संकेत देईल"</string>
     <string name="debug_input_category" msgid="1811069939601180246">"इनपुट"</string>
@@ -235,18 +250,18 @@
     <string name="strict_mode" msgid="1938795874357830695">"कठोर मोड सक्षम"</string>
     <string name="strict_mode_summary" msgid="142834318897332338">"मुख्य थ्रेडवर अॅप्स मोठी कार्ये करतात तेव्हा स्क्रीन फ्लॅश करा"</string>
     <string name="pointer_location" msgid="6084434787496938001">"पॉइंटर स्थान"</string>
-    <string name="pointer_location_summary" msgid="840819275172753713">"वर्तमान स्पर्श डेटा दर्शविणारे स्क्रीन आच्छादन"</string>
+    <string name="pointer_location_summary" msgid="840819275172753713">"वर्तमान स्पर्श डेटा दर्शविणारे स्क्रीन ओव्हरले"</string>
     <string name="show_touches" msgid="2642976305235070316">"टॅप दर्शवा"</string>
     <string name="show_touches_summary" msgid="6101183132903926324">"टॅपसाठी दृश्यमान अभिप्राय दर्शवा"</string>
-    <string name="show_screen_updates" msgid="5470814345876056420">"पृष्ठभाग अद्यतने दर्शवा"</string>
+    <string name="show_screen_updates" msgid="5470814345876056420">"पृष्ठभाग अपडेट दर्शवा"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"संपूर्ण विंडो पृष्ठभाग अद्ययावत होतात तेव्हा ते फ्‍लॅश करा"</string>
-    <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU दृश्य अद्यतने दर्शवा"</string>
+    <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU दृश्य अपडेट दर्शवा"</string>
     <string name="show_hw_screen_updates_summary" msgid="1115593565980196197">"GPU सह रेखांकित करताना विंडोच्या आतील दृश्ये फ्लॅश करा"</string>
-    <string name="show_hw_layers_updates" msgid="5645728765605699821">"हार्डवेअर स्तर अद्यतने दर्शवा"</string>
+    <string name="show_hw_layers_updates" msgid="5645728765605699821">"हार्डवेअर स्तर अपडेट दर्शवा"</string>
     <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"हार्डवेअर स्तर अद्ययावत झाल्यावर ते हिरव्या रंगात फ्लॅश करा"</string>
-    <string name="debug_hw_overdraw" msgid="2968692419951565417">"GPU अधोरेखांकित डीबग करा"</string>
+    <string name="debug_hw_overdraw" msgid="2968692419951565417">"GPU ओव्हरड्रॉ डीबग करा"</string>
     <string name="debug_hw_renderer" msgid="7568529019431785816">"GPU प्रदाता सेट करा"</string>
-    <string name="disable_overlays" msgid="2074488440505934665">"HW आच्छादने अक्षम करा"</string>
+    <string name="disable_overlays" msgid="2074488440505934665">"HW ओव्हरले अक्षम करा"</string>
     <string name="disable_overlays_summary" msgid="3578941133710758592">"स्क्रीन तयार करण्यासाठी नेहमी GPU वापरा"</string>
     <string name="simulate_color_space" msgid="6745847141353345872">"रंग स्थानाची बतावणी करा"</string>
     <string name="enable_opengl_traces_title" msgid="6790444011053219871">"OpenGL ट्रेस सक्षम करा"</string>
@@ -267,25 +282,25 @@
     <string name="animator_duration_scale_title" msgid="3406722410819934083">"अॅनिमेटर कालावधी स्केल"</string>
     <string name="overlay_display_devices_title" msgid="5364176287998398539">"दुय्यम प्रदर्शनांची बतावणी करा"</string>
     <string name="debug_applications_category" msgid="4206913653849771549">"अॅप्स"</string>
-    <string name="immediately_destroy_activities" msgid="1579659389568133959">"क्रियाकलाप ठेवू नका"</string>
-    <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"वापरकर्त्याने प्रत्येक क्रियाकलाप सोडताच तो नष्ट करा"</string>
+    <string name="immediately_destroy_activities" msgid="1579659389568133959">"अॅक्टिव्हिटी ठेवू नका"</string>
+    <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"वापरकर्त्याने प्रत्येक अॅक्टिव्हिटी सोडताच ती नष्ट करा"</string>
     <string name="app_process_limit_title" msgid="4280600650253107163">"पार्श्वभूमी प्रक्रिया मर्यादा"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"सर्व ANR दर्शवा"</string>
     <string name="show_all_anrs_summary" msgid="641908614413544127">"पार्श्वभूमी अॅप्ससाठी अॅप प्रतिसाद देत नाही संवाद दर्शवा"</string>
     <string name="show_notification_channel_warnings" msgid="1399948193466922683">"सूचना चॅनेल चेतावण्या दाखवा"</string>
     <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"एखादे अ‍ॅप वैध चॅनेलशिवाय सूचना पोस्ट करते तेव्हा स्क्रीनवर चेतावणी देते"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"बाह्यवर अॅप्सना अनुमती देण्याची सक्ती करा"</string>
-    <string name="force_allow_on_external_summary" msgid="3640752408258034689">"मॅनिफेस्ट मूल्यांकडे दुर्लक्ष करून, कोणत्याही अॅपला बाह्य संचयनावर लेखन केले जाण्यासाठी पात्र बनविते"</string>
+    <string name="force_allow_on_external_summary" msgid="3640752408258034689">"manifest मूल्यांकडे दुर्लक्ष करून, कोणत्याही अॅपला बाह्य स्टोरेजवर लेखन केले जाण्यासाठी पात्र बनविते"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"क्र‍ियाकलापाचा आकार बदलण्यायोग्य होण्याची सक्ती करा"</string>
-    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"मॅनिफेस्ट मूल्यांकडे दुर्लक्ष करून, एकाधिक-विंडोसाठी सर्व क्रियाकलापांचा आकार बदलण्यायोग्य करा."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"manifest मूल्यांकडे दुर्लक्ष करून, एकाधिक-विंडोसाठी सर्व क्रियाकलापांचा आकार बदलण्यायोग्य करा."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"freeform विंडो सक्षम करा"</string>
     <string name="enable_freeform_support_summary" msgid="8247310463288834487">"प्रायोगिक मुक्तस्वरूपाच्या विंडोसाठी समर्थन सक्षम करा."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"डेस्कटॉप बॅकअप संकेतशब्द"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"डेस्कटॉप पूर्ण बॅक अप सध्या संरक्षित नाहीत"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"डेस्कटॉपच्या पूर्ण बॅकअपसाठी असलेला संकेतशब्द बदलण्यासाठी किंवा काढण्यासाठी टॅप  करा"</string>
-    <string name="local_backup_password_toast_success" msgid="582016086228434290">"नवीन बॅक अप संकेतशब्द सेट झाला"</string>
+    <string name="local_backup_password_toast_success" msgid="582016086228434290">"नवीन बॅक अप पासवर्ड सेट झाला"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"नवीन संकेतशब्द आणि पुष्टीकरण जुळत नाही"</string>
-    <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"बॅक अप संकेतशब्द सेट करणे अयशस्वी"</string>
+    <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"बॅक अप पासवर्ड सेट करणे अयशस्वी"</string>
   <string-array name="color_mode_names">
     <item msgid="2425514299220523812">"सशक्त (डीफॉल्ट)"</item>
     <item msgid="8446070607501413455">"नैसर्गिक"</item>
@@ -306,7 +321,7 @@
     <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"ही निवड यापुढे वैध असणार नाही. पुन्हा प्रयत्न करा."</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"फाईल कूटबद्धीकरणावर रूपांतरित करा"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"रूपांतरित करा..."</string>
-    <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"फाईल आधीपासून कूटबद्ध केली"</string>
+    <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"फाईल आधीपासून एंक्रिप्ट होती"</string>
     <string name="title_convert_fbe" msgid="1263622876196444453">"फाईल आधारित कूटबद्धीकरणावर रूपांतरित करणे"</string>
     <string name="convert_to_fbe_warning" msgid="6139067817148865527">"फाईल आधारित कूटबद्धीकरणावर डेटा विभाजक रूपांतरित करा.\n !!चेतावणी!! हे आपल्‍या सर्व डेटास मिटवेल.\n हे वैशिष्ट्य अल्‍फा आहे आणि कदाचित योग्यरित्या कार्य करू शकत नाही.\n सुरु ठेवण्‍यासाठी \'पुसा आणि रूपांतरित करा...\' दाबा."</string>
     <string name="button_convert_fbe" msgid="5152671181309826405">"पुसा आणि रुपांतरित करा..."</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"रंग सुधारणा"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"हे वैशिष्‍ट्य प्रायोगिक आहे आणि कदाचित कार्यप्रदर्शन प्रभावित करू शकते."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारे अधिलिखित"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"सुमारे <xliff:g id="TIME">%1$s</xliff:g> शिल्‍लक"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"पूर्णपणे चार्ज होण्यास <xliff:g id="TIME">%1$s</xliff:g> शिल्‍लक"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> शिल्लक"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - सुमारे <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"सुमारे <xliff:g id="TIME">^1</xliff:g> शिल्‍लक"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"तुमच्या वापरानुसार अंदाजे <xliff:g id="TIME">^1</xliff:g> पुरेल इतकी बॅटरी शिल्लक आहे"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"पूर्णपणे चार्ज होण्यास <xliff:g id="TIME">^1</xliff:g> शिल्‍लक"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> शिल्लक"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"तुमच्या वापरानुसार <xliff:g id="TIME">^1</xliff:g> पुरेल इतकी बॅटरी शिल्लक आहे"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - सुमारे <xliff:g id="TIME">^2</xliff:g> शिल्लक"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - तुमच्या वापरानुसार अंदाजे <xliff:g id="TIME">^2</xliff:g> पुरेल इतकी बॅटरी शिल्लक आहे"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूर्णपणे चार्ज होण्यात <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - पूर्णपणे चार्ज होण्यात <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज होत आहे"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"चार्ज होत आहे"</string>
@@ -340,12 +358,12 @@
     <string name="disabled" msgid="9206776641295849915">"अक्षम"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"अनुमती आहे"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"अनुमती नाही"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"अज्ञात अ‍ॅप्स स्थापित करा"</string>
-    <string name="home" msgid="3256884684164448244">"सेटिंग्ज मुख्यपृष्ठ"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"अज्ञात अ‍ॅप्स इंस्टॉल करा"</string>
+    <string name="home" msgid="3256884684164448244">"सेटिंग्ज होम"</string>
   <string-array name="battery_labels">
-    <item msgid="8494684293649631252">"0%"</item>
-    <item msgid="8934126114226089439">"50%"</item>
-    <item msgid="1286113608943010849">"100%"</item>
+    <item msgid="8494684293649631252">"०%"</item>
+    <item msgid="8934126114226089439">"५०%"</item>
+    <item msgid="1286113608943010849">"१००%"</item>
   </string-array>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> पूर्वी"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> शिल्लक"</string>
@@ -358,12 +376,12 @@
     <string name="help_feedback_label" msgid="6815040660801785649">"मदत आणि अभिप्राय"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"मेनू"</string>
     <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
-    <string name="retail_demo_reset_message" msgid="118771671364131297">"डेमो मोडमध्ये फॅक्टरी रीसेट करण्यासाठी संकेतशब्द प्रविष्ट करा"</string>
+    <string name="retail_demo_reset_message" msgid="118771671364131297">"डेमो मोडमध्ये फॅक्टरी रीसेट करण्यासाठी पासवर्ड प्रविष्ट करा"</string>
     <string name="retail_demo_reset_next" msgid="8356731459226304963">"पुढील"</string>
     <string name="retail_demo_reset_title" msgid="696589204029930100">"संकेतशब्द आवश्यक"</string>
     <string name="active_input_method_subtypes" msgid="3596398805424733238">"सक्रिय इनपुट पद्धती"</string>
-    <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"सिस्टीम भाषा वापरा"</string>
+    <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"सिस्टम भाषा वापरा"</string>
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> साठी सेटिंग्ज उघडण्यात अयशस्वी"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"ही इनपुट पद्धत संकेतशब्द आणि क्रेडिट कार्ड नंबर यासह, आपण टाइप करता तो सर्व मजकूर संकलित करण्यात सक्षम होऊ शकते. ही <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> अॅपवरून येते. ही इनपुट पद्धत वापरायची?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"टीप: रीबूट केल्यानंतर, आपण आपला फोन अनलॉक करे पर्यंत हा अॅप प्रारंभ होऊ शकत नाही"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"टीप: रीबूट केल्यानंतर, तुम्ही आपला फोन अनलॉक करे पर्यंत हे अॅप सुरू होऊ शकत नाही"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ms/arrays.xml b/packages/SettingsLib/res/values-ms/arrays.xml
index bab4642..2d7e014a 100644
--- a/packages/SettingsLib/res/values-ms/arrays.xml
+++ b/packages/SettingsLib/res/values-ms/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Lalai)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Gunakan Pilihan Sistem (Lalai)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Dayakan Codec Pilihan"</item>
-    <item msgid="3304843301758635896">"Lumpuhkan Codec Pilihan"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Gunakan Pilihan Sistem (Lalai)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Dayakan Codec Pilihan"</item>
-    <item msgid="741805482892725657">"Lumpuhkan Codec Pilihan"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Gunakan Pilihan Sistem (Lalai)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 19bf62e..caa07f9 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Tidak disambungkan kerana rangkaian berkualiti rendah"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Kegagalan Sambungan WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Masalah pengesahan"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Tidak dapat bersambung"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Tidak dapat bersambung ke \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Semak kata laluan, kemudian cuba lagi"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Tidak dalam liputan"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Tidak akan menyambung secara automatik"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Tiada akses Internet"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Disambungkan melalui %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Disambungkan, tiada Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Sangat Perlahan"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Perlahan"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Sederhana"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Laju"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Sangat Laju"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Diputuskan sambungan"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Memutuskan sambungan..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Menyambung..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Disambungkan (tiada media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Disambungkan (tiada akses mesej)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Disambungkan (tiada telefon atau media)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Disambungkan, bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Disambungkan (tiada telefon), bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Disambungkan (tiada media), bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Disambungkan (tiada telefon atau media), bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio media"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audio telefon"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Panggilan telefon"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Pemindahan fail"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Peranti input"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Akses Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Perkongsian kenalan"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Gunakan untuk perkongsian kenalan"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Perkongsian sambungan Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Akses Mesej"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Mesej Teks"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Akses SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Gunakan audio berkualiti tinggi: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Gunakan audio berkualiti tinggi"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Disambungkan ke audio media"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Disambungkan ke audio telefon"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Bersambung ke pelayan pemindahan fail"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Penyerahan Wi-Fi ke mudah alih agresif"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sentiasa benarkan Imbasan Perayauan Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Data mudah alih sentiasa aktif"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Pecutan perkakasan penambatan"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Lumpuhkan kelantangan mutlak"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Dayakan dering dalam jalur"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versi AVRCP Bluetooth"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Benarkan lokasi olokan"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Dayakan pemeriksaan atribut paparan"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Pastikan data mudah alih sentiasa aktif, walaupun Wi-Fi aktif (untuk penukaran rangkaian yang pantas)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Gunakan pecutan perkakasan penambatan jika tersedia"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Benarkan penyahpepijatan USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Penyahpepijatan USB adalah dimaksudkan untuk tujuan pembangunan sahaja. Gunakannya untuk menyalin data antara komputer dan peranti anda, memasang aplikasi pada peranti anda tanpa pemberitahuan, dan membaca data log."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Batalkan akses ke penyahpepijatan USB dari semua komputer yang anda berikan kebenaran sebelum ini?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Pembetulan warna"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ciri ini adalah percubaan dan boleh menjejaskan prestasi."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Diatasi oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Kira-kira <xliff:g id="TIME">%1$s</xliff:g> lagi"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> lagi sehingga dicas penuh"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> lagi"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira <xliff:g id="TIME">%2$s</xliff:g> lagi"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Kira-kira <xliff:g id="TIME">^1</xliff:g> lagi"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Tinggal kira-kira <xliff:g id="TIME">^1</xliff:g> berdasarkan penggunaan anda"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> lagi sehingga dicas penuh"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> lagi"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Tinggal <xliff:g id="TIME">^1</xliff:g> berdasarkan penggunaan anda"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - kira-kira <xliff:g id="TIME">^2</xliff:g> lagi"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - tinggal kira-kira <xliff:g id="TIME">^2</xliff:g> berdasarkan penggunaan anda"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> lagi"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga dicas penuh"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> sehingga dicas penuh"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Tidak diketahui"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Mengecas"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"mengecas"</string>
diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml
index 97a9c53..3a802a7 100644
--- a/packages/SettingsLib/res/values-my/arrays.xml
+++ b/packages/SettingsLib/res/values-my/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (မူလ)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"စနစ်ရွေးချယ်မှုကို အသုံးပြုပါ (မူရင်း)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"စိတ်ကြိုက်ထည့်သွင်းနိုင်သော ကိုးဒက်ခ်များကို ဖွင့်ပါ"</item>
-    <item msgid="3304843301758635896">"စိတ်ကြိုက်ထည့်သွင်းနိုင်သော ကိုးဒက်ခ်များကို ပိတ်ပါ"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"စနစ်ရွေးချယ်မှုကို အသုံးပြုပါ (မူရင်း)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"စိတ်ကြိုက်ထည့်သွင်းနိုင်သော ကိုးဒက်ခ်များကို ဖွင့်ပါ"</item>
-    <item msgid="741805482892725657">"စိတ်ကြိုက်ထည့်သွင်းနိုင်သော ကိုးဒက်ခ်များကို ပိတ်ပါ"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"စနစ်ရွေးချယ်မှုကို အသုံးပြုပါ (မူရင်း)"</item>
     <item msgid="8895532488906185219">"၄၄.၁ kHz"</item>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 6864162..abee907 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"ကွန်ရက်ချိတ်ဆက်မှု အားနည်းသည့်အတွက် ချိတ်ဆက်ထားခြင်း မရှိပါ"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi ချိတ်ဆက်မှု မအောင်မြင်ပါ"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"စစ်မှန်ကြောင်းအတည်ပြုရန်၌ ပြသနာရှိခြင်း"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"ချိတ်ဆက်၍ မရပါ"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' နှင့် ချိတ်ဆက်၍ မရပါ"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"စကားဝှက်ကို စစ်ဆေးပြီး ထပ်လုပ်ကြည့်ပါ"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"စက်ကွင်းထဲတွင် မဟုတ်ပါ"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"အလိုအလျောက်ချိတ်ဆက်မည်မဟုတ်ပါ"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"အင်တာနက် ချိတ်ဆက်မှု မရှိပါ"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s မှတစ်ဆင့်ရနိုင်သည်"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"ချိတ်ဆက်ထားသည်၊ အင်တာနက်မရှိ"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"အလွန်နှေး"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"နှေး"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"အိုကေ"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"အတော်အသင့်"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"မြန်"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"အလွန်မြန်"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"ချိတ်ဆက်မှုပြတ်တောက်သည်"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"အဆက်အသွယ်ဖြတ်တောက်သည်"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"ချိတ်ဆက်နေသည်"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"ချိတ်ဆက်ထားပြီး (မီဒီယာမရှိ)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ချိတ်ဆက်မိသည် (သတင်းရယူမှုမရှိ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ချိတ်ဆက်ပြီး (ဖုန်း သို့ မီဒီယာမဟုတ်ပါ)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"ချိတ်ဆက်ပြီးပါပြီ၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"ချိတ်ဆက်ပြီးပါပြီ (မည်သည့်ဖုန်းမျှ မရှိပါ)၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"ချိတ်ဆက်ပြီးပါပြီ (မည်သည့် မီဒီယာမျှ မရှိပါ)၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"ချိတ်ဆက်ပြီးပါပြီ (မည်သည့် ဖုန်း သို့မဟုတ် မီဒီယာမျှ မရှိပါ)၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"မီဒီယာ အသံ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ဖုန်းအသံ"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ဖုန်းခေါ်ဆိုမှုများ"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ဖိုင်လွဲပြောင်းခြင်း"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ထည့်သွင်းသော စက်"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"အင်တာနက်ချိတ်ဆက်ခြင်း"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"အဆက်အသွယ်ကို မျှဝေရန်"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"အဆက်အသွယ်ကို မျှဝေရန် အတွက် သုံးရန်"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"အင်တာနက်ဆက်သွယ်မှု မျှဝေခြင်း"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"သတင်းရယူမှု"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"မိုဘိုင်းမက်ဆေ့ဂျ်များ"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM အသုံးပြုခြင်း"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"အရည်အသွေးမြင့် အသံအမျိုးအစားကို သုံးရန်− <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"အရည်အသွေးမြင့် အသံအမျိုးအစားကိုသုံးရန်"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD အသံ- <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD အသံ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"မီဒီယာအသံအား ချိတ်ဆက်ရန်"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ဖုန်းအသံအား ချိတ်ဆက်ရန်"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ဖိုင်လွှဲပြောင်းမည့်ဆာဗာနှင့် ချိတ်ဆက်ထားပြီး"</string>
@@ -100,7 +113,7 @@
     <string name="user_guest" msgid="8475274842845401871">"ဧည့်သည်"</string>
     <string name="unknown" msgid="1592123443519355854">"အကြောင်းအရာ မသိရှိ"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"သုံးစွဲသူ၊ <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
-    <string name="launch_defaults_some" msgid="313159469856372621">"တချို့အားပုံမှတ်အဖြစ်သတ်မှတ်"</string>
+    <string name="launch_defaults_some" msgid="313159469856372621">"မူရင်းအချို့ သတ်မှတ်ပြီး"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"ပုံမှန်သတ်မှတ်ထားခြင်းမရှိ"</string>
     <string name="tts_settings" msgid="8186971894801348327">"စာသားမှစကားပြောပြောင်း ဆက်တင်များ"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"စာသားမှ အသံထွက်စေခြင်း"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi မှ မိုဘိုင်းသို့ လွှဲပြောင်းရန်"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi ရွမ်းရှာဖွေမှုကို အမြဲတမ်း ခွင့်ပြုမည်"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"မိုဘိုင်းဒေတာကို အမြဲဖွင့်ထားရန်"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ဖုန်းကို မိုဒမ်အဖြစ်အသုံးပြုမှု စက်ပစ္စည်းဖြင့် အရှိန်မြှင့်တင်ခြင်း"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ပကတိ အသံနှုန်း သတ်မှတ်ချက် ပိတ်ရန်"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"သတ်မှတ်ထားသည့်ဖုန်းမြည်သံကို အသုံးပြုခြင်းအား ဖွင့်ရန်"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ဘလူးတုသ် AVRCP ဗားရှင်း"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"ပုံစံတုတည်နေရာများကို ခွင့်ပြုရန်"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"အရည်အချင်းများ စူးစမ်းမှု မြင်ကွင်းကို ဖွင့်ပေးရန်"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ဝိုင်ဖိုင်ဖွင့်ထားလျှင်တောင် မိုဘိုင်းဒေတာအမြဲတမ်းဖွင့်မည် (မြန်ဆန်သည့် ကွန်ရက် ပြောင်းခြင်းအတွက်)။"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ဖုန်းကို မိုဒမ်အဖြစ်သုံးမှု စက်ပစ္စည်းဖြင့် အရှိမြှင့်တင်ခြင်းကို ရနိုင်လျှင် သုံးရန်"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB ပြသနာရှာခြင်း ခွင့်ပြုပါမလား?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USBအမှားရှားခြင်းမှာ ဆော့ဝဲလ်ရေးသားရန်အတွက်သာ ရည်ရွယ်ပါသည်။ သင့်ကွန်ပြုတာနှင့်သင့်စက်ကြားတွင် ဒေတာများကိုကူးယူရန်၊ အကြောင်းမကြားပဲနှင့် သင့်စက်အတွင်းသို့ အပလီကေးရှင်းများထည့်သွင်းခြင်းနှင့် ဒေတာမှတ်တမ်းများဖတ်ရန်အတွက် အသုံးပြုပါ"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"သင် ယခင်က ခွင့်ပြုခဲ့သော ကွန်ပျူတာအားလုံးမှ ယူအက်စ်ဘီ အမှားစစ်ခွင့်ကို ရုတ်သိမ်းမည်လား ?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"အရောင်ပြင်ဆင်မှု"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ဤဝန်ဆောင်မှုမှာ စမ်းသပ်အဆင့်သာဖြစ်၍ လုပ်ဆောင်မှုအားနည်းနိုင်သည်။"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"<xliff:g id="TIME">%1$s</xliff:g> ခန့်လိုပါသည်"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"အားပြည့်ရန် <xliff:g id="TIME">%1$s</xliff:g> လိုပါသည်"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ကျန်သည်"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> − <xliff:g id="TIME">%2$s</xliff:g> ခန့်ကျန်သည်"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"<xliff:g id="TIME">^1</xliff:g> ခန့်လိုပါသည်"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"သင့်အသုံးပြုမှုအရ <xliff:g id="TIME">^1</xliff:g> ခန့် ကျန်ပါသည်"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"အားပြည့်ရန် <xliff:g id="TIME">^1</xliff:g> လိုပါသည်"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> ကျန်သည်"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"သင့်အသုံးပြုမှုအရ <xliff:g id="TIME">^1</xliff:g> ကျန်ပါသည်"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> − <xliff:g id="TIME">^2</xliff:g> ခန့်ကျန်သည်"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - သင့်အသုံးပြုမှုအရ <xliff:g id="TIME">^2</xliff:g> ခန့် ကျန်ပါသည်"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> − အားပြည့်ရန် <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> − အားပြည့်ရန် <xliff:g id="TIME">^2</xliff:g> ကျန်သည်"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"အကြောင်းအရာ မသိရှိ"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"အားသွင်းနေပါသည်"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"အားသွင်းနေပါသည်"</string>
@@ -339,8 +357,8 @@
     <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>
-    <string name="install_other_apps" msgid="6986686991775883017">"အမျိုးအမည်မသိအက်ပ် ထည့်သွင်းနိုင်ခြင်း"</string>
+    <string name="external_source_untrusted" msgid="2677442511837596726">"ခွင့်မပြုပါ"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"အမည်မသိအက်ပ်"</string>
     <string name="home" msgid="3256884684164448244">"ဆက်တင် ပင်မစာမျက်နှာ"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"၀%"</item>
diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml
index 287c386..a67e999 100644
--- a/packages/SettingsLib/res/values-nb/arrays.xml
+++ b/packages/SettingsLib/res/values-nb/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (standard)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Bruk systemvalg (standard)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Slå på valgfrie kodeker"</item>
-    <item msgid="3304843301758635896">"Slå av valgfrie kodeker"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Bruk systemvalg (standard)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Slå på valgfrie kodeker"</item>
-    <item msgid="741805482892725657">"Slå av valgfrie kodeker"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Bruk systemvalg (standard)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index c69b1b8..004fcf1e 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Ikke tilkoblet på grunn av nettverk av lav kvalitet"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi-tilkoblingsfeil"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Autentiseringsproblem"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Kan ikke koble til"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Kan ikke koble til «<xliff:g id="AP_NAME">%1$s</xliff:g>»"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Sjekk passordet og prøv igjen"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Utenfor område"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Kobler ikke til automatisk"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Ingen Internett-tilgang"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Tilkoblet via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Tilgjengelig via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Tilkoblet – ingen Internett-forbindelse"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Veldig treg"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Treg"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Ok"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Middels"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Rask"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Veldig rask"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Frakoblet"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Kobler fra…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Kobler til…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Tilkoblet (ingen medier)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Tilkoblet (ingen meldingstilgang)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Tilkoblet (ingen telefon eller media)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Tilkoblet, batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Tilkoblet (ingen telefon), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Tilkoblet (ingen medier), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Tilkoblet (ingen telefon eller medier), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medielyd"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefonlyd"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonsamtaler"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Filoverføring"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Inndataenhet"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internett-tilgang"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktdeling"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Bruk til kontaktdeling"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Deling av Internett-tilkobling"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Meldingstilgang"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Tekstmeldinger"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Tilgang til SIM-kortet"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Bruk lyd av høy kvalitet: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Bruk lyd av høy kvalitet"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-lyd: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-lyd"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Koblet til medielyd"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Koblet til telefonlyd"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Koblet til tjener for filoverføring"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressiv overføring fra Wi-Fi til mobil"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillat alltid skanning for Wi-Fi-roaming"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata er alltid aktiv"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Maskinvareakselerasjon for internettdeling"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Slå av funksjonen for absolutt volum"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Slå på innenbåndsringing"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-versjon"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Tillat bruk av simulerte GPS-koordinater"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Slå på inspeksjon av visningsattributt"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Ha alltid mobildata slått på, selv når Wi-Fi er aktiv (for hurtig nettverksbytting)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Bruk maskinvareakselerasjon for internettdeling hvis det er tilgjengelig"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Tillate USB-feilsøking?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-feilsøking er bare ment for utviklingsformål. Bruk det til å kopiere data mellom datamaskinen og enheten, installere apper på enheten uten varsel og lese loggdata."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vil du oppheve tilgangen til USB-feilsøking fra alle datamaskiner du tidligere har autorisert?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Fargekorrigering"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Dette er en eksperimentell funksjon som kan gjøre at telefonen ikke fungerer optimalt."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overstyres av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Omtrent <xliff:g id="TIME">%1$s</xliff:g> gjenstår"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> til det er fulladet"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> gjenstår"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – omtrent <xliff:g id="TIME">%2$s</xliff:g> gjenstår"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> gjenstår"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Omtrent <xliff:g id="TIME">^1</xliff:g> gjenstår"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Omtrent <xliff:g id="TIME">^1</xliff:g> igjen basert på bruken din"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> til det er fulladet"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> gjenstår"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> igjen basert på bruken din"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – omtrent <xliff:g id="TIME">^2</xliff:g> gjenstår"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – omtrent <xliff:g id="TIME">^2</xliff:g> igjen basert på bruken din"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> gjenstår"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fulladet"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> til det er fulladet"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Ukjent"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Lader"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"lader"</string>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index ba7affd..f26125b 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP १.४ (पूर्वनिर्धारित)"</item>
-    <item msgid="2089555299377409443">"AVRCP १.५"</item>
-    <item msgid="2895327394279434278">"AVRCP १.६"</item>
+    <item msgid="2809759619990248160">"AVRCP १.३"</item>
+    <item msgid="6199178154704729352">"AVRCP १.५"</item>
+    <item msgid="5172170854953034852">"AVRCP १.६"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp १३"</item>
+    <item msgid="8837606198371920819">"avrcp १५"</item>
+    <item msgid="3422726142222090896">"avrcp १६"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"प्रणालीको चयन प्रयोग गर्नुहोस् (पूर्वनिर्धारित)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"वैकल्पिक कोडेकहरूलाई सक्षम पार्नुहोस्"</item>
-    <item msgid="3304843301758635896">"वैकल्पिक कोडेकहरूलाई असक्षम पार्नुहोस्"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"प्रणालीको चयन प्रयोग गर्नुहोस् (पूर्वनिर्धारित)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"वैकल्पिक कोडेकहरूलाई सक्षम पार्नुहोस्"</item>
-    <item msgid="741805482892725657">"वैकल्पिक कोडेकहरूलाई असक्षम पार्नुहोस्"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"प्रणालीको चयन प्रयोग गर्नुहोस् (पूर्वनिर्धारित)"</item>
     <item msgid="8895532488906185219">"४४.१ kHz"</item>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index fe7f780..eac1e24 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"कम गुणस्तरको नेटवर्कका कारण जडान गर्न सकिएन"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"वाईफाई जडान असफल"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"प्रमाणीकरण समस्या"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"जडान गर्न सकिँदैन"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' मा जडान गर्न सकिँदैन"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"पासवर्ड जाँच गरेर फेरि प्रयास गर्नुहोस्"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"दायराभित्र छैन"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"स्वतः जडान हुने छैन"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"इन्टरनेट माथिको पहुँच छैन"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s मार्फत जडित"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s मार्फत उपलब्ध"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"जडित, इन्टरनेट चलेको छैन"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"धेरै ढिलो"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"बिस्तारै"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ठीक छ"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"मध्यम"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"छिटो"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"धेरै छिटो"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"विच्छेदन गरियो"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"जडान हटाइँदै ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"जडान हुँदै..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"जडित (कुनै पनि मिडिया छैन)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"जडित छ (सन्देशमा पहुँच छैन)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"जडित (फोन वा मिडिया छैन)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"यन्त्र जडान भयो, ब्याट्रीको चार्ज स्तर <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"यन्त्र जडान भयो (फोनको अडियो छैन), ब्याट्रीको चार्ज स्तर <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"यन्त्र जडान भयो (मिडियाको अडियो छैन), ब्याट्रीको चार्ज स्तर <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"यन्त्र जडान भयो (फोन वा मिडियाको अडियो छैन), ब्याट्रीको चार्ज स्तर <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मिडिया अडियो"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"फोन अडियो"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"फोन कलहरू"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"फाइल स्थानान्तरण"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"इनपुट उपकरण"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"इन्टरनेट पहुँच"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"सम्पर्क साझेदारी"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"सम्पर्क साझेदारीका लागि प्रयोग"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"इन्टरनेट जडान साझेदारी गर्दै"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"सन्देश पहुँच"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"पाठ सन्देशहरू"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM पहुँच"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"उच्च गुणस्तरको अडियो प्रयोग गर्नुहोस्‌: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"उच्च गुणस्तरको अडियो प्रयोग गर्नुहोस्‌"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD अडियो: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD अडियो"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"मिडिया अडियोसँग जडित"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"फोन अडियोमा जडान गरियो"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"फाइल ट्रान्सफर सर्भरमा जडान गरियो"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"आक्रामक ढंगले Wi‑Fi बाट मोबाइलमा हस्तान्तरण"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi घुम्ने स्क्यान गर्न सधैँ अनुमति दिनुहोस्"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा सधैँ सक्रिय राख्नुहोस्"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"टेदरिङको लागि हार्डवेयरको प्रवेग"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"निरपेक्ष आवाज असक्षम गर्नुहोस्"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"इन-ब्यान्ड घन्टी बज्ने सुविधालाई सक्षम पार्नुहोस्"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ब्लुटुथको AVRCP संस्करण"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"नक्कली स्थानहरूलाई अनुमति दिनुहोस्"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"दृष्टिकोण विशेषता निरीक्षण सक्षम पार्नुहोस्"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi-Fi सक्रिय हुँदा पनि मोबाइल डेटा सधैँ सक्रिय राख्नुहोस् (द्रूत नेटवर्क स्विच गर्नको लागि)।"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"उपलब्ध भएमा टेदरिङको लागि हार्डवेयरको प्रवेग प्रयोग गर्नुहोस्"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB डिबग गर्न लागि अनुमति दिने हो?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"युएसबी डिबगिङ विकास प्रयोजनका लागि मात्र निर्मित हुन्छ। यसलाई तपाईँको कम्प्युटर र तपाईँको उपकरणका बीच डेटा प्रतिलिपि गर्न, बिना सूचना तपाईँको उपकरणमा अनुप्रयोगहरू स्थापना गर्न र लग डेटा पढ्नका लागि प्रयोग गर्नुहोस्।"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"तपाईं पहिले नै अधिकृत गर्नुभएका सबै कम्प्यूटरबाट USB डिबग गर्नको लागि पहुँच रद्द गर्ने हो?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"रङ्ग सुधार"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"यो सुविधा प्रयोगात्मक छ र प्रदर्शनमा असर गर्न सक्छ।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारा अधिरोहित"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"लगभग <xliff:g id="TIME">%1$s</xliff:g> बाँकी"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">%1$s</xliff:g> बाँकी"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"बाँकी समय <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - करिब <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"बाँकी समय <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"लगभग <xliff:g id="TIME">^1</xliff:g> बाँकी"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"तपाईंको प्रयोगका आधारमा लगभग <xliff:g id="TIME">^1</xliff:g> बाँकी"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">^1</xliff:g> बाँकी"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"बाँकी समय <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"तपाईंको प्रयोगका आधारमा <xliff:g id="TIME">^1</xliff:g> बाँकी"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - करिब <xliff:g id="TIME">^2</xliff:g> बाँकी"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - तपाईंको प्रयोगका आधारमा लगभग <xliff:g id="TIME">^2</xliff:g> बाँकी"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"बाँकी समय <xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">^2</xliff:g> बाँकी"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज हुँदै"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"चार्ज हुँदै"</string>
diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml
index 25b803a..b35245b 100644
--- a/packages/SettingsLib/res/values-nl/arrays.xml
+++ b/packages/SettingsLib/res/values-nl/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (standaard)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Systeemselectie gebruiken (standaard)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Optionele codecs inschakelen"</item>
-    <item msgid="3304843301758635896">"Optionele codecs uitschakelen"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Systeemselectie gebruiken (standaard)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Optionele codecs inschakelen"</item>
-    <item msgid="741805482892725657">"Optionele codecs uitschakelen"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Systeemselectie gebruiken (standaard)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 65a4a20..0c2e96d 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Niet verbonden wegens netwerk van lage kwaliteit"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wifi-verbinding mislukt"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Authenticatieprobleem"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Kan geen verbinding maken"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Kan geen verbinding maken met \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Controleer het wachtwoord en probeer het opnieuw"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Niet binnen bereik"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Er wordt niet automatisch verbinding gemaakt"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Geen internettoegang"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Verbonden via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Beschikbaar via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Verbonden, geen internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Zeer langzaam"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Langzaam"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Redelijk"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Gemiddeld"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Snel"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Zeer snel"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Verbinding verbroken"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Verbinding verbreken..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Verbinding maken..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Gekoppeld (geen media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Verbonden (geen toegang tot berichten)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Gekoppeld (geen telefoon of media)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Verbonden, batterij <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Verbonden (geen telefoon), batterij <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Verbonden (geen media), batterij <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Verbonden (geen telefoon of media), batterij <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media-audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefoonaudio"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefoongesprekken"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Bestandsoverdracht"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Invoerapparaat"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internettoegang"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Contacten delen"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Gebruiken voor contacten delen"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internetverbinding delen"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Toegang tot berichten"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Sms-berichten"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Sim-toegang"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Audio van hoge kwaliteit gebruiken: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Audio van hoge kwaliteit gebruiken"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Verbonden met audio van medium"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Verbonden met audio van telefoon"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Verbonden met server voor bestandsoverdracht"</string>
@@ -144,7 +157,7 @@
     <string name="choose_profile" msgid="6921016979430278661">"Profiel kiezen"</string>
     <string name="category_personal" msgid="1299663247844969448">"Persoonlijk"</string>
     <string name="category_work" msgid="8699184680584175622">"Werk"</string>
-    <string name="development_settings_title" msgid="215179176067683667">"Opties voor ontwikkelaars"</string>
+    <string name="development_settings_title" msgid="215179176067683667">"Ontwikkelaarsopties"</string>
     <string name="development_settings_enable" msgid="542530994778109538">"Opties voor ontwikkelaars inschakelen"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Opties instellen voor appontwikkeling"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Ontwikkelaarsopties zijn niet beschikbaar voor deze gebruiker"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agressieve handover van wifi naar mobiel"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Altijd roamingscans voor wifi toestaan"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiele data altijd actief"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwareversnelling voor tethering"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Absoluut volume uitschakelen"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"In-band bellen inschakelen"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth-AVRCP-versie"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Neplocaties toestaan"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Inspectie van weergavekenmerk inschakelen"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mobiele gegevens altijd actief houden, ook als wifi actief is (voor sneller schakelen tussen netwerken)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Hardwareversnelling voor tethering gebruiken indien beschikbaar"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB-foutopsporing toestaan?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-foutopsporing is alleen bedoeld voor ontwikkeldoeleinden. Het kan worden gebruikt om gegevens te kopiëren tussen je computer en je apparaat, apps zonder melding op je apparaat te installeren en loggegevens te lezen."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Toegang tot USB-foutopsporing intrekken voor alle computers waarvoor je dit eerder hebt toegestaan?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Kleurcorrectie"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Deze functie is experimenteel en kan invloed hebben op de prestaties."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overschreven door <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Nog ongeveer <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Nog <xliff:g id="TIME">%1$s</xliff:g> tot volledig opgeladen"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> resterend"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ongeveer <xliff:g id="TIME">%2$s</xliff:g> resterend"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> resterend"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Nog ongeveer <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Nog ongeveer <xliff:g id="TIME">^1</xliff:g> over op basis van je gebruik"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Nog <xliff:g id="TIME">^1</xliff:g> tot volledig opgeladen"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> resterend"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Nog <xliff:g id="TIME">^1</xliff:g> over op basis van je gebruik"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - ongeveer <xliff:g id="TIME">^2</xliff:g> resterend"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g>: nog ongeveer <xliff:g id="TIME">^2</xliff:g> over op basis van je gebruik"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> resterend"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot volledig opgeladen"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> tot volledig opgeladen"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Onbekend"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Opladen"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"opladen"</string>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index 2715f9d..55e67f0a 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -39,7 +39,7 @@
     <item msgid="8878186979715711006">"ਸਕੈਨ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."</item>
     <item msgid="355508996603873860">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕਰ ਰਿਹਾ ਹੈ…"</item>
     <item msgid="554971459996405634">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> ਨਾਲ ਪ੍ਰਮਾਣਿਤ ਕਰ ਰਿਹਾ ਹੈ…"</item>
-    <item msgid="7928343808033020343">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> ਤੋਂ IP ਪਤਾ ਪ੍ਰਾਪਤ ਕਰ ਰਿਹਾ ਹੈ…"</item>
+    <item msgid="7928343808033020343">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> ਤੋਂ IP ਪਤਾ ਪ੍ਰਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</item>
     <item msgid="8937994881315223448">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</item>
     <item msgid="1330262655415760617">"ਮੁਅੱਤਲ ਕੀਤਾ"</item>
     <item msgid="7698638434317271902">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> ਤੋਂ ਡਿਸਕਨੈਕਟ ਕਰ ਰਿਹਾ ਹੈ…"</item>
@@ -50,7 +50,7 @@
   </string-array>
   <string-array name="hdcp_checking_titles">
     <item msgid="441827799230089869">"ਕਦੇ ਵੀ ਜਾਂਚ ਨਾ ਕਰੋ"</item>
-    <item msgid="6042769699089883931">"ਕੇਵਲ DRM ਸਮੱਗਰੀ ਲਈ ਜਾਂਚ ਕਰੋ"</item>
+    <item msgid="6042769699089883931">"ਸਿਰਫ਼ DRM ਸਮੱਗਰੀ ਲਈ ਜਾਂਚ ਕਰੋ"</item>
     <item msgid="9174900380056846820">"ਹਮੇਸ਼ਾਂ ਜਾਂਚ ਕਰੋ"</item>
   </string-array>
   <string-array name="hdcp_checking_summaries">
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"ਸਿਸਟਮ ਚੋਣ ਦੀ ਵਰਤੋਂ ਕਰੋ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"ਵਿਕਲਪਿਕ ਕੋਡੈਕ ਯੋਗ ਬਣਾਓ"</item>
-    <item msgid="3304843301758635896">"ਵਿਕਲਪਿਕ ਕੋਡੈਕ ਅਯੋਗ ਬਣਾਓ"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"ਸਿਸਟਮ ਚੋਣ ਦੀ ਵਰਤੋਂ ਕਰੋ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"ਵਿਕਲਪਿਕ ਕੋਡੈਕ ਯੋਗ ਬਣਾਓ"</item>
-    <item msgid="741805482892725657">"ਵਿਕਲਪਿਕ ਕੋਡੈਕ ਅਯੋਗ ਬਣਾਓ"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"ਸਿਸਟਮ ਚੋਣ ਦੀ ਵਰਤੋਂ ਕਰੋ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
@@ -125,14 +111,14 @@
     <item msgid="8883739882299884241">"ਸਟੀਰੀਓ"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
-    <item msgid="7158319962230727476">"ਔਡੀਓ ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ (990kbps/909kbps)"</item>
-    <item msgid="2921767058740704969">"ਸੰਤੁਲਿਤ ਔਡੀਓ ਅਤੇ ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ (660kbps/606kbps)"</item>
+    <item msgid="7158319962230727476">" ਆਡੀਓ  ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ (990kbps/909kbps)"</item>
+    <item msgid="2921767058740704969">"ਸੰਤੁਲਿਤ  ਆਡੀਓ  ਅਤੇ ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ (660kbps/606kbps)"</item>
     <item msgid="8860982705384396512">"ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ (330kbps/303kbps)"</item>
     <item msgid="4414060457677684127">"ਸਰਵੋਤਮ ਕੋਸ਼ਿਸ਼ (ਅਨੁਕੂਲਨਕਾਰੀ ਬਿਟ ਰੇਟ)"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
-    <item msgid="6398189564246596868">"ਔਡੀਓ ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ"</item>
-    <item msgid="4327143584633311908">"ਸੰਤੁਲਿਤ ਔਡੀਓ ਅਤੇ ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ"</item>
+    <item msgid="6398189564246596868">" ਆਡੀਓ  ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ"</item>
+    <item msgid="4327143584633311908">"ਸੰਤੁਲਿਤ  ਆਡੀਓ  ਅਤੇ ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ"</item>
     <item msgid="4681409244565426925">"ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ"</item>
     <item msgid="364670732877872677">"ਸਰਵੋਤਮ ਕੋਸ਼ਿਸ਼ (ਅਨੁਕੂਲਨਕਾਰੀ ਬਿਟ ਰੇਟ)"</item>
   </string-array>
@@ -152,11 +138,11 @@
   </string-array>
   <string-array name="select_logd_size_summaries">
     <item msgid="6921048829791179331">"ਬੰਦ"</item>
-    <item msgid="2969458029344750262">"64K ਪ੍ਰਤੀ ਲੌਗ ਬਫਰ"</item>
-    <item msgid="1342285115665698168">"256K ਪ੍ਰਤੀ ਲੌਗ ਬਫਰ"</item>
-    <item msgid="1314234299552254621">"1M ਪ੍ਰਤੀ ਲੌਗ ਬਫਰ"</item>
-    <item msgid="3606047780792894151">"4M ਪ੍ਰਤੀ ਲੌਗ ਬਫਰ"</item>
-    <item msgid="5431354956856655120">"16M ਪ੍ਰਤੀ ਲੌਗ ਬਫਰ"</item>
+    <item msgid="2969458029344750262">"64K ਪ੍ਰਤੀ ਲੌਗ ਬਫ਼ਰ"</item>
+    <item msgid="1342285115665698168">"256K ਪ੍ਰਤੀ ਲੌਗ ਬਫ਼ਰ"</item>
+    <item msgid="1314234299552254621">"1M ਪ੍ਰਤੀ ਲੌਗ ਬਫ਼ਰ"</item>
+    <item msgid="3606047780792894151">"4M ਪ੍ਰਤੀ ਲੌਗ ਬਫ਼ਰ"</item>
+    <item msgid="5431354956856655120">"16M ਪ੍ਰਤੀ ਲੌਗ ਬਫ਼ਰ"</item>
   </string-array>
   <string-array name="select_logpersist_titles">
     <item msgid="1744840221860799971">"ਬੰਦ"</item>
@@ -220,7 +206,7 @@
   <string-array name="show_non_rect_clip_entries">
     <item msgid="993742912147090253">"ਬੰਦ"</item>
     <item msgid="675719912558941285">"ਨੀਲੇ ਵਿੱਚ ਗ਼ੈਰ-ਆਇਤਾਕਾਰ ਕਲਿਪ ਖੇਤਰ ਡ੍ਰਾ ਕਰੋ"</item>
-    <item msgid="1064373276095698656">"ਹਾਈਲਾਈਟ ਜਾਂਚ ਕੀਤੀਆਂ ਡ੍ਰਾਇੰਗ ਕਮਾਂਡਾਂ ਹਰੇ ਵਿੱਚ ਹਨ"</item>
+    <item msgid="1064373276095698656">"ਜਾਂਚ ਕੀਤੀਆਂ ਡ੍ਰਾਇੰਗ ਕਮਾਂਡਾਂ ਹਰੇ ਵਿੱਚ ਉਜਾਗਰ ਕਰੋ"</item>
   </string-array>
   <string-array name="track_frame_time_entries">
     <item msgid="2193584639058893150">"ਬੰਦ"</item>
@@ -247,9 +233,9 @@
   <string-array name="usb_configuration_titles">
     <item msgid="488237561639712799">"ਚਾਰਜਿੰਗ"</item>
     <item msgid="5220695614993094977">"MTP (ਮੀਡੀਆ ਟ੍ਰਾਂਸਫਰ ਪ੍ਰੋਟੋਕੋਲ)"</item>
-    <item msgid="2086000968159047375">"PTP (ਤਸਵੀਰ ਟ੍ਰਾਂਸਫਰ ਪ੍ਰੋਟੋਕੋਲ)"</item>
+    <item msgid="2086000968159047375">"PTP (ਪਿਕਚਰ ਟ੍ਰਾਂਸਫਰ ਪ੍ਰੋਟੋਕੋਲ)"</item>
     <item msgid="7398830860950841822">"RNDIS (USB ਈਥਰਨੈਟ)"</item>
-    <item msgid="1718924214939774352">"ਔਡੀਓ ਸਰੋਤ"</item>
+    <item msgid="1718924214939774352">" ਆਡੀਓ  ਸਰੋਤ"</item>
     <item msgid="8126315616613006284">"MIDI"</item>
   </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 3324b19..2994f8a 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -28,58 +28,71 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"ਘੱਟ ਗੁਣਵੱਤਾ ਵਾਲੇ ਨੈੱਟਵਰਕ ਕਾਰਨ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਗਿਆ"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi ਕਨੈਕਸ਼ਨ ਅਸਫਲਤਾ"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"ਪ੍ਰਮਾਣੀਕਰਨ ਸਮੱਸਿਆ"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"ਪਾਸਵਰਡ ਦੀ ਜਾਂਚ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"ਰੇਂਜ ਵਿੱਚ ਨਹੀਂ ਹੈ"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"ਕੋਈ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ"</string>
     <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> ਵੱਲੋਂ ਸੁਰੱਖਿਅਤ ਕੀਤਾ"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ਰਾਹੀਂ ਆਪਣੇ-ਆਪ ਕਨੈਕਟ ਹੋਇਆ"</string>
-    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"ਨੈੱਟਵਰਕ ਰੇਟਿੰਗ ਪ੍ਰਦਾਨਕ ਰਾਹੀਂ ਆਪਣੇ-ਆਪ ਕਨੈਕਟ ਹੋਇਆ"</string>
+    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"ਨੈੱਟਵਰਕ ਰੇਟਿੰਗ ਪ੍ਰਦਾਨਕ ਰਾਹੀਂ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਕਨੈਕਟ ਹੋਇਆ"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ਰਾਹੀਂ ਉਪਲਬਧ"</string>
-    <string name="wifi_connected_no_internet" msgid="3149853966840874992">"ਕਨੈਕਟ ਕੀਤਾ, ਕੋਈ ਇੰਟਰਨੈਟ ਨਹੀਂ"</string>
+    <string name="wifi_connected_no_internet" msgid="3149853966840874992">"ਕਨੈਕਟ ਕੀਤਾ, ਕੋਈ ਇੰਟਰਨੈੱਟ ਨਹੀਂ"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"ਬਹੁਤ ਹੌਲੀ"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"ਹੌਲੀ"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ਠੀਕ ਹੈ"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"ਔਸਤ"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"ਤੇਜ਼"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"ਬਹੁਤ ਤੇਜ਼"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"ਡਿਸਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"ਡਿਸਕਨੈਕਟ ਕਰ ਰਿਹਾ ਹੈ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"ਕਨੈਕਟ ਕਰ ਰਿਹਾ ਹੈ…"</string>
     <string name="bluetooth_connected" msgid="6038755206916626419">"ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="bluetooth_pairing" msgid="1426882272690346242">"ਪੇਅਰ ਕਰ ਰਿਹਾ ਹੈ…"</string>
-    <string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"ਕਨੈਕਟ ਕੀਤਾ (ਕੋਈ ਫੋਨ ਨਹੀਂ)"</string>
+    <string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"ਕਨੈਕਟ ਕੀਤਾ (ਕੋਈ ਫ਼ੋਨ ਨਹੀਂ)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"ਕਨੈਕਟ ਕੀਤਾ (ਕੋਈ ਮੀਡੀਆ ਨਹੀਂ)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ਕਨੈਕਟ ਕੀਤਾ (ਕੋਈ ਸੁਨੇਹਾ ਪਹੁੰਚ ਨਹੀਂ)"</string>
-    <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ਕਨੈਕਟ ਕੀਤਾ (ਕੋਈ ਫੋਨ ਜਾਂ ਮੀਡੀਆ ਨਹੀਂ)"</string>
-    <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ਮੀਡੀਆ ਔਡੀਓ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ਫੋਨ ਔਡੀਓ"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ਕਨੈਕਟ ਕੀਤਾ (ਕੋਈ ਫ਼ੋਨ ਜਾਂ ਮੀਡੀਆ ਨਹੀਂ)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"ਕਨੈਕਟ ਕੀਤੀ ਗਈ, ਬੈਟਰੀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"ਕਨੈਕਟ ਕੀਤਾ (ਕੋਈ ਫ਼ੋਨ ਨਹੀਂ), ਬੈਟਰੀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"ਕਨੈਕਟ ਕੀਤੀ ਗਈ (ਕੋਈ ਮੀਡੀਆ ਨਹੀਂ), ਬੈਟਰੀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"ਕਨੈਕਟ ਕੀਤਾ (ਕੋਈ ਫ਼ੋਨ ਜਾਂ ਮੀਡੀਆ ਨਹੀਂ), ਬੈਟਰੀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ਮੀਡੀਆ  ਆਡੀਓ"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ਫ਼ੋਨ ਕਾਲਾਂ"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ"</string>
-    <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ਇਨਪੁਟ ਡੀਵਾਈਸ"</string>
-    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ਇੰਟਰਨੈਟ ਪਹੁੰਚ"</string>
+    <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ਇਨਪੁੱਟ ਡੀਵਾਈਸ"</string>
+    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"ਸੰਪਰਕ ਸ਼ੇਅਰਿੰਗ"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"ਸੰਪਰਕ ਸ਼ੇਅਰਿੰਗ ਲਈ ਵਰਤੋ"</string>
-    <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ਇੰਟਰਨੈਟ ਕਨੈਕਸ਼ਨ ਸ਼ੇਅਰਿੰਗ"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"ਸੁਨੇਹਾ ਪਹੁੰਚ"</string>
-    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM ਪਹੁੰਚ"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ਉੱਚ ਗੁਣਵੱਤਾ ਔਡੀਓ ਵਰਤੋ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ਉੱਚ ਗੁਣਵੱਤਾ ਔਡੀਓ ਵਰਤੋ"</string>
-    <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"ਮੀਡੀਆ ਔਡੀਓ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
-    <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ਫੋਨ ਔਡੀਓ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
-    <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ ਸਰਵਰ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
+    <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ਇੰਟਰਨੈੱਟ ਕਨੈਕਸ਼ਨ ਸਾਂਝਾਕਰਨ"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"ਲਿਖਤ ਸੁਨੇਹੇ"</string>
+    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ਸਿਮ ਪਹੁੰਚ"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ਆਡੀਓ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ਆਡੀਓ"</string>
+    <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"ਮੀਡੀਆ  ਆਡੀਓ  ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
+    <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ਫ਼ੋਨ ਔਡੀਓ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
+    <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ਫਾਈਲ ਟ੍ਰਾਂਸਫ਼ਰ ਸਰਵਰ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="bluetooth_map_profile_summary_connected" msgid="8191407438851351713">"ਨਕਸ਼ੇ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"SAP ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
-    <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ ਸਰਵਰ ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ"</string>
-    <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"ਇਨਪੁਟ ਡੀਵਾਈਸ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
-    <string name="bluetooth_pan_user_profile_summary_connected" msgid="4602294638909590612">"ਇੰਟਰਨੈਟ ਪਹੁੰਚ ਲਈ ਡੀਵਾਈਸ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
-    <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1561383706411975199">"ਡੀਵਾਈਸ ਨਾਲ ਸਥਾਨਕ ਇੰਟਰਨੈਟ ਕਨੈਕਸ਼ਨ ਸ਼ੇਅਰ ਕਰ ਰਿਹਾ ਹੈ"</string>
-    <string name="bluetooth_pan_profile_summary_use_for" msgid="5664884523822068653">"ਇੰਟਰਨੈਟ ਪਹੁੰਚ ਲਈ ਵਰਤੋ"</string>
+    <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"ਫਾਈਲ ਟ੍ਰਾਂਸਫ਼ਰ ਸਰਵਰ ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ"</string>
+    <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"ਇਨਪੁੱਟ ਡੀਵਾਈਸ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
+    <string name="bluetooth_pan_user_profile_summary_connected" msgid="4602294638909590612">"ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਲਈ ਡੀਵਾਈਸ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
+    <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1561383706411975199">"ਡੀਵਾਈਸ ਨਾਲ ਸਥਾਨਕ ਇੰਟਰਨੈੱਟ ਕਨੈਕਸ਼ਨ ਸਾਂਝਾ ਕਰ ਰਿਹਾ ਹੈ"</string>
+    <string name="bluetooth_pan_profile_summary_use_for" msgid="5664884523822068653">"ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਲਈ ਵਰਤੋ"</string>
     <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"ਨਕਸ਼ੇ ਲਈ ਵਰਤੋ"</string>
-    <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"SIM ਪਹੁੰਚ ਲਈ ਵਰਤੋ"</string>
-    <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"ਮੀਡੀਆ ਔਡੀਓ ਲਈ ਵਰਤੋ"</string>
-    <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ਫੋਨ ਔਡੀਓ ਲਈ ਵਰਤੋ"</string>
+    <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"ਸਿਮ ਪਹੁੰਚ ਲਈ ਵਰਤੋ"</string>
+    <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"ਮੀਡੀਆ  ਆਡੀਓ  ਲਈ ਵਰਤੋ"</string>
+    <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ਫ਼ੋਨ ਔਡੀਓ ਲਈ ਵਰਤੋ"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ ਲਈ ਵਰਤੋ"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ਇਨਪੁਟ ਲਈ ਵਰਤੋ"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"ਪੇਅਰ ਕਰੋ"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ਪੇਅਰ ਕਰੋ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ਰੱਦ ਕਰੋ"</string>
-    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"ਪੇਅਰ ਕਰਨਾ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ ਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਅਤੇ ਕਾਲ ਇਤਿਹਾਸ ਤੱਕ ਪਹੁੰਚ ਦੀ ਅਨੁਮਤੀ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"ਜੋੜਾਬੱਧ ਕਰਨਾ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ ਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਅਤੇ ਕਾਲ ਇਤਿਹਾਸ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਪੇਅਰ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ਇੱਕ ਗ਼ਲਤ PIN ਜਾਂ ਪਾਸਕੁੰਜੀ ਦੇ ਕਾਰਨ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਪੇਅਰ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ਇੱਕ ਗਲਤ ਪਿੰਨ ਜਾਂ ਪਾਸਕੁੰਜੀ ਦੇ ਕਾਰਨ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਜੋੜਾਬੱਧ ਨਹੀਂ ਹੋ ਸਕਿਆ।"</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਸੰਚਾਰ ਨਹੀਂ ਕਰ ਸਕਦਾ।"</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"ਪੇਅਰਿੰਗ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਰੱਦ ਕੀਤੀ ਗਈ।"</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi ਬੰਦ।"</string>
@@ -93,17 +106,17 @@
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"ਹਟਾਏ ਗਏ ਐਪਸ ਅਤੇ ਉਪਭੋਗਤਾ"</string>
     <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB ਟੈਦਰਿੰਗ"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"ਪੋਰਟੇਬਲ ਹੌਟਸਪੌਟ"</string>
-    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetooth ਟੈਦਰਿੰਗ"</string>
-    <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"ਟੀਥਰਿੰਗ"</string>
-    <string name="tether_settings_title_all" msgid="8356136101061143841">"ਟੀਥਰਿੰਗ &amp; ਪੋਰਟੇਬਲ ਹੌਟਸਪੌਟ"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"ਬਲੂਟੁੱਥ ਟੈਦਰਿੰਗ"</string>
+    <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"ਟੈਦਰਿੰਗ"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"ਟੈਦਰਿੰਗ &amp; ਪੋਰਟੇਬਲ ਹੌਟਸਪੌਟ"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"ਸਾਰੀਆਂ ਕੰਮ ਐਪਾਂ"</string>
     <string name="user_guest" msgid="8475274842845401871">"ਮਹਿਮਾਨ"</string>
     <string name="unknown" msgid="1592123443519355854">"ਅਗਿਆਤ"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"ਵਰਤੋਂਕਾਰ: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
-    <string name="launch_defaults_some" msgid="313159469856372621">"ਕੁਝ ਡਿਫੌਲਟਸ ਸੈਟ ਕੀਤੇ"</string>
+    <string name="launch_defaults_some" msgid="313159469856372621">"ਕੁਝ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੈੱਟ ਕੀਤੇ"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"ਕੋਈ ਡਿਫੌਲਟਸ ਸੈਟ ਨਹੀਂ ਕੀਤੇ"</string>
-    <string name="tts_settings" msgid="8186971894801348327">"ਟੈਕਸਟ-ਟੂ-ਸਪੀਚ ਸੈਟਿੰਗਾਂ"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"ਲਿਖਤ-ਤੋਂ-ਬੋਲੀ ਆਊਟਪੁਟ"</string>
+    <string name="tts_settings" msgid="8186971894801348327">"ਲਿਖਤ ਤੋਂ ਬੋਲੀ ਸੈਟਿੰਗਾਂ"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"ਲਿਖਤ ਤੋਂ ਬੋਲੀ ਆਊਟਪੁਟ"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"ਸਪੀਚ ਰੇਟ"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"ਸਪੀਡ ਜਿਸਤੇ ਟੈਕਸਟ ਬੋਲਿਆ ਜਾਂਦਾ ਹੈ"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"ਪਿਚ"</string>
@@ -114,10 +127,10 @@
     <string name="tts_default_lang_summary" msgid="5219362163902707785">"ਬੋਲੇ ਗਏ ਟੈਕਸਟ ਲਈ ਭਾਸ਼ਾ-ਵਿਸ਼ੇਸ਼ ਵੌਇਸ ਸੈਟ ਕਰਦਾ ਹੈ"</string>
     <string name="tts_play_example_title" msgid="7094780383253097230">"ਇੱਕ ਉਦਾਹਰਨ ਲਈ ਸੁਣੋ"</string>
     <string name="tts_play_example_summary" msgid="8029071615047894486">"ਸਪੀਚ ਸਿੰਥੈਸਿਸ ਦਾ ਇੱਕ ਛੋਟਾ ਪ੍ਰਦਰਸ਼ਨ ਪਲੇ ਕਰੋ"</string>
-    <string name="tts_install_data_title" msgid="4264378440508149986">"ਵੌਇਸ ਡੈਟਾ ਇੰਸਟੌਲ ਕਰੋ"</string>
-    <string name="tts_install_data_summary" msgid="5742135732511822589">"ਸਪੀਚ ਸਿੰਥੈਸਿਸ ਲਈ ਲੁੜੀਂਦਾ ਵੌਇਸ ਡੈਟਾ ਇੰਸਟੌਲ ਕਰੋ"</string>
-    <string name="tts_engine_security_warning" msgid="8786238102020223650">"ਇਹ ਸਪੀਚ ਸਿੰਥੈਸਿਸ ਇੰਜਣ ਉਹ ਸਾਰਾ ਟੈਕਸਟ ਇਕੱਤਰ ਕਰਨ ਵਿੱਚ ਸਮਰੱਥ ਹੋ ਸਕਦਾ ਹੈ, ਜੋ ਬੋਲਿਆ ਜਾਏਗਾ, ਨਿੱਜੀ ਡੈਟਾ ਸਮੇਤ ਜਿਵੇਂ ਪਾਸਵਰਡ ਅਤੇ ਕ੍ਰੈਡਿਟ ਕਾਰਡ ਨੰਬਰ। ਇਹ <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> ਇੰਜਣ ਤੋਂ ਆਉਂਦਾ ਹੈ। ਕੀ ਇਸ ਸਪੀਚ ਸਿੰਥੈਸਿਸ ਇੰਜਣ ਦੀ ਵਰਤੋਂ ਕਰਨੀ ਹੈ?"</string>
-    <string name="tts_engine_network_required" msgid="1190837151485314743">"ਇਸ ਭਾਸ਼ਾ ਲਈ ਟੈਕਸਟ-ਟੂ-ਸਪੀਚ ਆਊਟਪੁਟ ਲਈ ਇੱਕ ਚਾਲੂ ਨੈੱਟਵਰਕ ਕਨੈਕਸ਼ਨ ਦੀ ਲੋੜ ਹੈ।"</string>
+    <string name="tts_install_data_title" msgid="4264378440508149986">"ਵੌਇਸ ਡਾਟਾ ਸਥਾਪਤ ਕਰੋ"</string>
+    <string name="tts_install_data_summary" msgid="5742135732511822589">"ਸਪੀਚ ਸਿੰਥੈਸਿਸ ਲਈ ਲੋੜੀਂਦਾ ਵੌਇਸ ਡਾਟਾ ਸਥਾਪਤ ਕਰੋ"</string>
+    <string name="tts_engine_security_warning" msgid="8786238102020223650">"ਇਹ ਸਪੀਚ ਸਿੰਥੈਸਿਸ ਇੰਜਣ ਉਹ ਸਭ ਲਿਖਤ ਇਕੱਤਰ ਕਰਨ ਵਿੱਚ ਸਮਰੱਥ ਹੋ ਸਕਦਾ ਹੈ, ਜੋ ਬੋਲਿਆ ਜਾਏਗਾ, ਨਿੱਜੀ ਡਾਟਾ ਸਮੇਤ ਜਿਵੇਂ ਪਾਸਵਰਡ ਅਤੇ ਕ੍ਰੈਡਿਟ ਕਾਰਡ ਨੰਬਰ। ਇਹ <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> ਇੰਜਣ ਤੋਂ ਆਉਂਦਾ ਹੈ। ਕੀ ਇਸ ਸਪੀਚ ਸਿੰਥੈਸਿਸ ਇੰਜਣ ਦੀ ਵਰਤੋਂ ਨੂੰ ਚਾਲੂ ਕਰਨਾ ਹੈੈ?"</string>
+    <string name="tts_engine_network_required" msgid="1190837151485314743">"ਇਸ ਭਾਸ਼ਾ ਲਈ ਲਿਖਤ ਤੋਂ ਬੋਲੀ ਆਊਟਪੁੱਟ ਲਈ ਇੱਕ ਚਾਲੂ ਨੈੱਟਵਰਕ ਕਨੈਕਸ਼ਨ ਦੀ ਲੋੜ ਹੈ।"</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"ਇਹ ਸਪੀਚ ਸਿੰਥੈਸਿਸ ਦਾ ਇੱਕ ਉਦਾਹਰਨ ਹੈ"</string>
     <string name="tts_status_title" msgid="7268566550242584413">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਭਾਸ਼ਾ ਸਥਿਤੀ"</string>
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> ਪੂਰੀ ਤਰ੍ਹਾਂ ਸਮਰਥਿਤ ਹੈ"</string>
@@ -125,7 +138,7 @@
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ"</string>
     <string name="tts_status_checking" msgid="5339150797940483592">"ਜਾਂਚ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> ਲਈ ਸੈਟਿੰਗਾਂ"</string>
-    <string name="tts_engine_settings_button" msgid="1030512042040722285">"ਇੰਜਨ ਸੈਟਿੰਗਾਂ ਲੌਂਚ ਕਰੋ"</string>
+    <string name="tts_engine_settings_button" msgid="1030512042040722285">"ਇੰਜਣ ਸੈਟਿੰਗਾਂ ਲਾਂਚ ਕਰੋ"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"ਤਰਜੀਹੀ ਇੰਜਣ"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"ਸਧਾਰਨ"</string>
     <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"ਬੋਲਣ ਦੀ ਪਿੱਚ ਨੂੰ ਦੁਬਾਰਾ ਮੁੜ-ਸੈੱਟ ਕਰੋ"</string>
@@ -144,123 +157,125 @@
     <string name="choose_profile" msgid="6921016979430278661">"ਪ੍ਰੋਫਾਈਲ ਚੁਣੋ"</string>
     <string name="category_personal" msgid="1299663247844969448">"ਨਿੱਜੀ"</string>
     <string name="category_work" msgid="8699184680584175622">"ਦਫ਼ਤਰ"</string>
-    <string name="development_settings_title" msgid="215179176067683667">"ਵਿਕਾਸਕਾਰ ਚੋਣਾਂ"</string>
-    <string name="development_settings_enable" msgid="542530994778109538">"ਵਿਕਾਸਕਾਰ ਚੋਣਾਂ ਨੂੰ ਯੋਗ ਬਣਾਓ"</string>
+    <string name="development_settings_title" msgid="215179176067683667">"ਵਿਕਾਸਕਾਰ ਵਿਕਲਪ"</string>
+    <string name="development_settings_enable" msgid="542530994778109538">"ਵਿਕਾਸਕਾਰ ਵਿਕਲਪਾਂ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"ਐਪ ਵਿਕਾਸ ਲਈ ਚੋਣਾਂ ਸੈੱਟ ਕਰੋ"</string>
-    <string name="development_settings_not_available" msgid="4308569041701535607">"ਇਸ ਉਪਭੋਗਤਾ ਲਈ ਵਿਕਾਸਕਾਰ ਚੋਣਾਂ ਉਪਲਬਧ ਨਹੀਂ ਹਨ"</string>
-    <string name="vpn_settings_not_available" msgid="956841430176985598">"ਇਸ ਉਪਭੋਗਤਾ ਲਈ VPN ਸੈਟਿੰਗਾਂ ਉਪਲਬਧ ਨਹੀਂ ਹਨ"</string>
-    <string name="tethering_settings_not_available" msgid="6765770438438291012">"ਇਸ ਉਪਭੋਗਤਾ ਲਈ ਟੀਥਰਿੰਗ ਸੈਟਿੰਗਾਂ ਉਪਲਬਧ ਨਹੀਂ ਹਨ"</string>
-    <string name="apn_settings_not_available" msgid="7873729032165324000">"ਪਹੁੰਚ ਬਿੰਦੂ ਨਾਮ ਸੈਟਿੰਗਾਂ ਇਸ ਉਪਭੋਗਤਾ ਲਈ ਉਪਲਬਧ ਨਹੀਂ ਹਨ"</string>
+    <string name="development_settings_not_available" msgid="4308569041701535607">"ਇਸ ਵਰਤੋਂਕਾਰ ਲਈ ਵਿਕਾਸਕਾਰ ਵਿਕਲਪ ਉਪਲਬਧ ਨਹੀਂ ਹਨ"</string>
+    <string name="vpn_settings_not_available" msgid="956841430176985598">"ਇਸ ਵਰਤੋਂਕਾਰ ਲਈ VPN ਸੈਟਿੰਗਾਂ ਉਪਲਬਧ ਨਹੀਂ ਹਨ"</string>
+    <string name="tethering_settings_not_available" msgid="6765770438438291012">"ਇਸ ਵਰਤੋਂਕਾਰ ਲਈ ਟੈਦਰਿੰਗ ਸੈਟਿੰਗਾਂ ਉਪਲਬਧ ਨਹੀਂ ਹਨ"</string>
+    <string name="apn_settings_not_available" msgid="7873729032165324000">"ਐਕਸੈੱਸ ਪੁਆਇੰਟ ਨਾਮ ਸੈਟਿੰਗਾਂ ਇਸ ਵਰਤੋਂਕਾਰ ਲਈ ਉਪਲਬਧ ਨਹੀਂ ਹਨ"</string>
     <string name="enable_adb" msgid="7982306934419797485">"USB ਡੀਬਗਿੰਗ"</string>
-    <string name="enable_adb_summary" msgid="4881186971746056635">"ਡੀਬਗ ਮੋਡ ਜਦੋਂ USB ਕਨੈਕਟ ਕੀਤੀ ਜਾਏ"</string>
+    <string name="enable_adb_summary" msgid="4881186971746056635">"ਡੀਬੱਗ ਮੋਡ ਜਦੋਂ USB ਕਨੈਕਟ ਕੀਤੀ ਜਾਏ"</string>
     <string name="clear_adb_keys" msgid="4038889221503122743">"USB ਡੀਬਗਿੰਗ ਅਧਿਕਾਰ ਰੱਦ ਕਰੋ"</string>
-    <string name="bugreport_in_power" msgid="7923901846375587241">"ਬਗ ਰਿਪੋਰਟ ਸ਼ਾਰਟਕੱਟ"</string>
-    <string name="bugreport_in_power_summary" msgid="1778455732762984579">"ਇੱਕ ਬਗ ਰਿਪੋਰਟ ਲੈਣ ਲਈ ਪਾਵਰ ਮੀਨੂ ਵਿੱਚ ਇੱਕ ਬਟਨ ਦਿਖਾਓ"</string>
+    <string name="bugreport_in_power" msgid="7923901846375587241">"ਬੱਗ ਰਿਪੋਰਟ ਸ਼ਾਰਟਕੱਟ"</string>
+    <string name="bugreport_in_power_summary" msgid="1778455732762984579">"ਇੱਕ ਬੱਗ ਰਿਪੋਰਟ ਲੈਣ ਲਈ ਪਾਵਰ ਮੀਨੂ ਵਿੱਚ ਇੱਕ ਬਟਨ ਦਿਖਾਓ"</string>
     <string name="keep_screen_on" msgid="1146389631208760344">"ਸਕਿਰਿਆ ਰੱਖੋ"</string>
     <string name="keep_screen_on_summary" msgid="2173114350754293009">"ਸਕ੍ਰੀਨ ਚਾਰਜਿੰਗ ਦੇ ਸਮੇਂ ਕਦੇ ਵੀ ਸਲੀਪ ਨਹੀਂ ਹੋਵੇਗੀ"</string>
-    <string name="bt_hci_snoop_log" msgid="3340699311158865670">"Bluetooth HCI ਸਨੂਪ ਲੌਗ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ"</string>
+    <string name="bt_hci_snoop_log" msgid="3340699311158865670">"ਬਲੂਟੁੱਥ HCI ਸਨੂਪ ਲੌਗ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
     <string name="bt_hci_snoop_log_summary" msgid="730247028210113851">"ਇੱਕ ਫਾਈਲ ਵਿੱਚ ਸਾਰੇ bluetooth HCI ਪੈਕੇਟ ਕੈਪਚਰ ਕਰੋ"</string>
-    <string name="oem_unlock_enable" msgid="6040763321967327691">"OEM ਅਨਲੌਕ ਕਰਨਾ"</string>
-    <string name="oem_unlock_enable_summary" msgid="4720281828891618376">"ਬੂਟਲੋਡਰ ਨੂੰ ਅਨਲੌਕ ਕੀਤੇ ਜਾਣ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
-    <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"ਕੀ OEM ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
+    <string name="oem_unlock_enable" msgid="6040763321967327691">"OEM ਅਣਲਾਕ ਕਰਨਾ"</string>
+    <string name="oem_unlock_enable_summary" msgid="4720281828891618376">"ਬੂਟਲੋਡਰ ਨੂੰ ਅਣਲਾਕ ਕੀਤੇ ਜਾਣ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
+    <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"ਕੀ OEM ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
     <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"ਚਿਤਾਵਨੀ: ਡੀਵਾਈਸ ਸੁਰੱਖਿਆ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਉਦੋਂ ਇਸ ਡੀਵਾਈਸ ਤੇ ਕੰਮ ਨਹੀਂ ਕਰਨਗੀਆਂ ਜਦੋਂ ਇਹ ਸੈਟਿੰਗ ਚਾਲੂ ਹੋਵੇਗੀ।"</string>
     <string name="mock_location_app" msgid="7966220972812881854">"ਮੌਕ ਸਥਾਨ ਐਪ ਚੁਣੋ"</string>
     <string name="mock_location_app_not_set" msgid="809543285495344223">"ਕੋਈ ਵੀ ਮੌਕ ਸਥਾਨ ਐਪ ਸੈੱਟ ਨਹੀਂ ਕੀਤੀ ਗਈ"</string>
     <string name="mock_location_app_set" msgid="8966420655295102685">"ਮੌਕ ਸਥਾਨ ਐਪ: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="debug_networking_category" msgid="7044075693643009662">"ਨੈੱਟਵਰਕਿੰਗ"</string>
-    <string name="wifi_display_certification" msgid="8611569543791307533">"ਵਾਇਰਲੈਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ"</string>
-    <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi ਵਰਬੋਸ ਲੌਗਿੰਗ ਸਮਰੱਥ ਬਣਾਓ"</string>
-    <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ਆਕਰਮਣਸ਼ੀਲ Wi‑Fi ਤੋਂ ਮੋਬਾਈਲ ਹੈਂਡਓਵਰ"</string>
-    <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ਹਮੇਸ਼ਾਂ Wi‑Fi Roam Scans ਦੀ ਆਗਿਆ ਦਿਓ"</string>
-    <string name="mobile_data_always_on" msgid="8774857027458200434">"ਮੋਬਾਈਲ ਡੈਟਾ ਹਮੇਸ਼ਾਂ ਕਿਰਿਆਸ਼ੀਲ"</string>
+    <string name="wifi_display_certification" msgid="8611569543791307533">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ"</string>
+    <string name="wifi_verbose_logging" msgid="4203729756047242344">"ਵਾਈ-ਫਾਈ ਵਰਬੋਸ ਲੌਗਿੰਗ ਚਾਲੂ ਕਰੋ"</string>
+    <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ਆਕਰਮਣਸ਼ੀਲ ਵਾਈ‑ਫਾਈ ਤੋਂ ਮੋਬਾਈਲ ਹੈਂਡਓਵਰ"</string>
+    <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ਹਮੇਸ਼ਾਂ ਵਾਈ‑ਫਾਈ ਰੋਮ ਸਕੈਨਾਂ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
+    <string name="mobile_data_always_on" msgid="8774857027458200434">"ਮੋਬਾਈਲ ਡਾਟਾ ਹਮੇਸ਼ਾਂ ਕਿਰਿਆਸ਼ੀਲ"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ਟੈਦਰਿੰਗ ਹਾਰਡਵੇਅਰ ਐਕਸੈੱਲਰੇਸ਼ਨ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ਪੂਰਨ ਵੌਲਿਊਮ ਨੂੰ ਅਯੋਗ ਬਣਾਓ"</string>
-    <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ਇਨ-ਬੈਂਡ ਘੰਟੀ ਵੱਜਣ ਨੂੰ ਯੋਗ ਬਣਾਓ"</string>
-    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ਬਲੂਟੁੱਥ AVRCP ਰੂਪ"</string>
-    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ਬਲੂਟੁੱਥ AVRCP ਰੂਪ ਚੁਣੋ"</string>
+    <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ਇਨ-ਬੈਂਡ ਘੰਟੀ ਵੱਜਣ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
+    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ਬਲੂਟੁੱਥ AVRCP ਵਰਜਨ"</string>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ਬਲੂਟੁੱਥ AVRCP ਵਰਜਨ ਚੁਣੋ"</string>
     <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਕੋਡੇਕ"</string>
     <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਕੋਡੇਕ ਚੁਣੋ"</string>
-    <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਨਮੂਨਾ ਦਰ"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ਬਲੂਟੁੱਥ  ਆਡੀਓ  ਨਮੂਨਾ ਦਰ"</string>
     <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5628790207448471613">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਕੋਡੇਕ ਚੁਣੋ:\nਸੈਂਪਲ ਰੇਟ"</string>
-    <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="2099645202720164141">"ਪ੍ਰਤੀ ਨਮੂਨਾ ਬਲੂਟੁੱਥ ਔਡੀਓ ਬਿਟਾਂ"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="2099645202720164141">"ਪ੍ਰਤੀ ਨਮੂਨਾ ਬਲੂਟੁੱਥ  ਆਡੀਓ  ਬਿਟਾਂ"</string>
     <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4546131401358681321">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਕੋਡੇਕ ਚੁਣੋ:\nਬਿਟਾਂ ਪ੍ਰਤੀ ਨਮੂਨਾ"</string>
-    <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਚੈਨਲ ਮੋਡ"</string>
+    <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"ਬਲੂਟੁੱਥ  ਆਡੀਓ  ਚੈਨਲ ਮੋਡ"</string>
     <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="9133545781346216071">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਕੋਡੇਕ ਚੁਣੋ:\nਚੈਨਲ ਮੋਡ"</string>
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ਬਲੂਟੁੱਥ ਔਡੀਓ LDAC ਕੋਡੇਕ: ਪਲੇਬੈਕ ਗੁਣਵੱਤਾ"</string>
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ਬਲੂਟੁੱਥ ਔਡੀਓ LDAC ਕੋਡੇਕ ਚੁਣੋ:\nਪਲੇਬੈਕ ਗੁਣਵੱਤਾ"</string>
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ਸਟ੍ਰੀਮਿੰਗ: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
-    <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ਵਾਇਰਲੈਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਚੋਣਾਂ ਦਿਖਾਓ"</string>
-    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ਲੌਗਿੰਗ ਪੱਧਰ ਵਧਾਓ, Wi‑Fi Picker ਵਿੱਚ ਪ੍ਰਤੀ SSID RSSI ਦਿਖਾਓ"</string>
-    <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ਜਦੋਂ ਯੋਗ ਬਣਾਇਆ ਹੋਵੇ, ਤਾਂ Wi‑Fi ਸਿਗਨਲ ਘੱਟ ਹੋਣ \'ਤੇ Wi‑Fi ਡੈਟਾ ਕਨੈਕਸ਼ਨ ਮੋਬਾਈਲ ਨੂੰ ਹੈਂਡ ਓਵਰ ਕਰਨ ਵਿੱਚ ਵੱਧ ਆਕਰਮਣਸ਼ੀਲ ਹੋਵੇਗਾ।"</string>
-    <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ਇੰਟਰਫੇਸ ਤੇ ਮੌਜੂਦ ਡੈਟਾ ਟ੍ਰੈਫਿਕ ਦੀ ਮਾਤਰਾ ਦੇ ਆਧਾਰ ਤੇ Wi‑Fi ਰੋਮ ਸਕੈਨ ਦੀ ਆਗਿਆ ਦਿਓ/ਅਸਵੀਕਾਰ ਕਰੋ"</string>
-    <string name="select_logd_size_title" msgid="7433137108348553508">"ਲੌਗਰ ਬਫਰ ਆਕਾਰ"</string>
-    <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ਪ੍ਰਤੀ ਲੌਗ ਬਫਰ ਲੌਗਰ ਆਕਾਰ ਚੁਣੋ"</string>
+    <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਚੋਣਾਂ ਪ੍ਰਦਰਸ਼ਿਤ ਕਰੋ"</string>
+    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ਵਾਈ‑ਫਾਈ ਲੌਗਿੰਗ ਪੱਧਰ ਵਧਾਓ, ਵਾਈ‑ਫਾਈ Picker ਵਿੱਚ ਪ੍ਰਤੀ SSID RSSI ਦਿਖਾਓ"</string>
+    <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ਜਦੋਂ ਯੋਗ ਬਣਾਇਆ ਹੋਵੇ, ਤਾਂ ਵਾਈ‑ਫਾਈ ਸਿਗਨਲ ਘੱਟ ਹੋਣ \'ਤੇ ਵਾਈ‑ਫਾਈ ਡਾਟਾ ਕਨੈਕਸ਼ਨ ਮੋਬਾਈਲ ਨੂੰ ਹੈਂਡ ਓਵਰ ਕਰਨ ਵਿੱਚ ਵੱਧ ਆਕਰਮਣਸ਼ੀਲ ਹੋਵੇਗਾ।"</string>
+    <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ਇੰਟਰਫੇਸ ਤੇ ਮੌਜੂਦ ਡਾਟਾ ਟ੍ਰੈਫਿਕ ਦੀ ਮਾਤਰਾ ਦੇ ਆਧਾਰ ਤੇ ਵਾਈ-ਫਾਈ ਰੋਮ ਸਕੈਨ ਦੀ ਆਗਿਆ ਦਿਓ/ਅਸਵੀਕਾਰ ਕਰੋ"</string>
+    <string name="select_logd_size_title" msgid="7433137108348553508">"ਲੌਗਰ ਬਫ਼ਰ ਆਕਾਰ"</string>
+    <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ਪ੍ਰਤੀ ਲੌਗ ਬਫ਼ਰ ਲੌਗਰ ਆਕਾਰ ਚੁਣੋ"</string>
     <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"ਕੀ ਲੌਗਰ ਪ੍ਰਸਿੱਸਟੈਂਟ ਸਟੋਰੇਜ ਨੂੰ ਸਾਫ਼ ਕਰਨਾ ਹੈ?"</string>
-    <string name="dev_logpersist_clear_warning_message" msgid="2256582531342994562">"ਜਦੋਂ ਅਸੀਂ ਪ੍ਰਸਿੱਸਟੈਂਟ ਲੌਗਰ ਨਾਲ ਨਿਗਰਾਨੀ ਨਹੀਂ ਕਰ ਰਹੇ ਹੁੰਦੇ ਹਾਂ, ਤਾਂ ਸਾਨੂੰ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਵਿੱਚ ਮੌਜੂਦ ਲੌਗਰ ਡੈਟੇ ਨੂੰ ਮਿਟਾਉਣ ਦੀ ਲੋੜ ਪੈਂਦੀ ਹੈ।"</string>
+    <string name="dev_logpersist_clear_warning_message" msgid="2256582531342994562">"ਜਦੋਂ ਅਸੀਂ ਪ੍ਰਸਿੱਸਟੈਂਟ ਲੌਗਰ ਨਾਲ ਨਿਗਰਾਨੀ ਨਹੀਂ ਕਰ ਰਹੇ ਹੁੰਦੇ ਹਾਂ, ਤਾਂ ਸਾਨੂੰ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਵਿੱਚ ਮੌਜੂਦ ਲੌਗਰ ਡਾਟੇ ਨੂੰ ਮਿਟਾਉਣ ਦੀ ਲੋੜ ਪੈਂਦੀ ਹੈ।"</string>
     <string name="select_logpersist_title" msgid="7530031344550073166">"ਡੀਵਾਈਸ \'ਤੇ ਲੌਗ ਬਫ਼ਰਾਂ ਨੂੰ ਸਥਾਈ ਤੌਰ \'ਤੇ ਸਟੋਰ ਕਰੋ"</string>
     <string name="select_logpersist_dialog_title" msgid="4003400579973269060">"ਡੀਵਾਈਸ \'ਤੇ ਸਥਾਈ ਤੌਰ \'ਤੇ ਸਟੋਰ ਕਰਨ ਲਈ ਲੌਗ ਬਫ਼ਰਾਂ ਨੂੰ ਚੁਣੋ"</string>
     <string name="select_usb_configuration_title" msgid="2649938511506971843">"USB ਕੌਂਫਿਗਰੇਸ਼ਨ ਚੁਣੋ"</string>
     <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"USB ਕੌਂਫਿਗਰੇਸ਼ਨ ਚੁਣੋ"</string>
     <string name="allow_mock_location" msgid="2787962564578664888">"ਨਕਲੀ ਨਿਰਧਾਰਿਤ ਸਥਾਨਾਂ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
     <string name="allow_mock_location_summary" msgid="317615105156345626">"ਨਕਲੀ ਨਿਰਧਾਰਿਤ ਸਥਾਨਾਂ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
-    <string name="debug_view_attributes" msgid="6485448367803310384">"ਗੁਣ ਛਾਣਬੀਣ ਦੇਖੋ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ"</string>
-    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ਹਮੇਸ਼ਾ ਮੋਬਾਈਲ ਡੇਟਾ ਨੂੰ ਕਿਰਿਆਸ਼ੀਲ ਰੱਖੋ ਭਾਵੇਂ Wi‑Fi ਕਿਰਿਆਸ਼ੀਲ ਹੋਵੇ (ਤੇਜ਼ ਨੈੱਟਵਰਕ ਸਵਿੱਚਿੰਗ ਲਈ)।"</string>
+    <string name="debug_view_attributes" msgid="6485448367803310384">"ਵਿਸ਼ੇਸ਼ਤਾ ਛਾਣਬੀਣ ਦੇਖੋ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
+    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ਹਮੇਸ਼ਾਂ ਮੋਬਾਈਲ ਡਾਟਾ ਨੂੰ ਕਿਰਿਆਸ਼ੀਲ ਰੱਖੋ ਭਾਵੇਂ ਵਾਈ‑ਫਾਈ ਕਿਰਿਆਸ਼ੀਲ ਹੋਵੇ (ਤੇਜ਼ ਨੈੱਟਵਰਕ ਸਵਿੱਚਿੰਗ ਲਈ)।"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ਉਪਲਬਧ ਹੋਣ \'ਤੇ ਟੈਦਰਿੰਗ ਹਾਰਡਵੇਅਰ ਐਕਸੈੱਲਰੇਸ਼ਨ ਵਰਤੋ"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"ਕੀ USB ਡੀਬਗਿੰਗ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
-    <string name="adb_warning_message" msgid="7316799925425402244">"USB ਡੀਬਗਿੰਗ ਕੇਵਲ ਵਿਕਾਸ ਮੰਤਵਾਂ ਲਈ ਹੁੰਦੀ ਹੈ। ਇਸਨੂੰ ਆਪਣੇ ਕੰਪਿਊਟਰ ਅਤੇ ਆਪਣੀ ਡੀਵਾਈਸ ਵਿਚਕਾਰ ਡੈਟਾ ਕਾਪੀ ਕਰਨ ਲਈ ਵਰਤੋ, ਸੂਚਨਾ ਦੇ ਬਿਨਾਂ ਆਪਣੀ ਡੀਵਾਈਸ ਤੇ ਐਪਸ ਇੰਸਟੌਲ ਕਰੋ ਅਤੇ ਲੌਗ ਡੈਟਾ ਪੜ੍ਹੋ।"</string>
-    <string name="adb_keys_warning_message" msgid="5659849457135841625">"ਕੀ ਉਹਨਾਂ ਸਾਰੇ ਕੰਪਿਊਟਰਾਂ ਤੋਂ USB ਡੀਬਗਿੰਗ ਤੱਕ ਪਹੁੰਚ ਰੱਦ ਕਰਨੀ ਹੈ, ਜਿਹਨਾਂ ਲਈ ਪਹਿਲਾਂ ਤੁਸੀਂ ਅਧਿਕਾਰਤ ਕੀਤਾ ਹੈ?"</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"USB ਡੀਬਗਿੰਗ ਸਿਰਫ਼ ਵਿਕਾਸ ਮੰਤਵਾਂ ਲਈ ਹੁੰਦੀ ਹੈ। ਇਸਨੂੰ ਆਪਣੇ ਕੰਪਿਊਟਰ ਅਤੇ ਆਪਣੇ ਡੀਵਾਈਸ ਵਿਚਕਾਰ ਡਾਟਾ ਕਾਪੀ ਕਰਨ ਲਈ ਵਰਤੋ, ਸੂਚਨਾ ਦੇ ਬਿਨਾਂ ਆਪਣੇ ਡੀਵਾਈਸ ਤੇ ਐਪਾਂ ਸਥਾਪਤ ਕਰੋ ਅਤੇ ਲੌਗ ਡਾਟਾ ਪੜ੍ਹੋ।"</string>
+    <string name="adb_keys_warning_message" msgid="5659849457135841625">"ਕੀ ਉਹਨਾਂ ਸਾਰੇ ਕੰਪਿਊਟਰਾਂ ਤੋਂ USB ਡੀਬੱਗਿੰਗ ਤੱਕ ਪਹੁੰਚ ਰੱਦ ਕਰਨੀ ਹੈ, ਜਿਹਨਾਂ ਲਈ ਪਹਿਲਾਂ ਤੁਸੀਂ ਅਧਿਕਾਰਤ ਕੀਤਾ ਹੈ?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"ਕੀ ਵਿਕਾਸ ਸੈਟਿੰਗਾਂ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
-    <string name="dev_settings_warning_message" msgid="2298337781139097964">"ਇਹ ਸੈਟਿੰਗਾਂ ਕੇਵਲ ਵਿਕਾਸਕਾਰ ਦੀ ਵਰਤੋਂ ਲਈ ਹਨ। ਇਹ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਅਤੇ ਇਸਤੇ ਮੌਜੂਦ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਬ੍ਰੇਕ ਕਰਨ ਜਾਂ ਦੁਰਵਿਵਹਾਰ ਕਰਨ ਦਾ ਕਾਰਨ ਬਣ ਸਕਦੇ ਹਨ।"</string>
-    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB ਤੇ ਐਪਸ ਨੂੰ ਪ੍ਰਮਾਣਿਤ ਕਰੋ"</string>
-    <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ਹਾਨੀਕਾਰਕ ਵਿਵਹਾਰ ਲਈ ADB/ADT ਰਾਹੀਂ ਇੰਸਟੌਲ ਕੀਤੇ ਐਪਸ ਦੀ ਜਾਂਚ ਕਰੋ।"</string>
+    <string name="dev_settings_warning_message" msgid="2298337781139097964">"ਇਹ ਸੈਟਿੰਗਾਂ ਕੇਵਲ ਵਿਕਾਸਕਾਰ ਦੀ ਵਰਤੋਂ ਲਈ ਹਨ। ਇਹ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਅਤੇ ਇਸਤੇ ਮੌਜੂਦ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਬ੍ਰੇਕ ਕਰਨ ਜਾਂ ਦੁਰਵਿਵਹਾਰ ਕਰਨ ਦਾ ਕਾਰਨ ਬਣ ਸਕਦੇ ਹਨ।"</string>
+    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB ਤੇ ਐਪਾਂ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
+    <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ਹਾਨੀਕਾਰਕ ਵਿਵਹਾਰ ਲਈ ADB/ADT ਰਾਹੀਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਐਪਾਂ ਦੀ ਜਾਂਚ ਕਰੋ।"</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"ਰਿਮੋਟ ਡੀਵਾਈਸਾਂ ਨਾਲ ਵੌਲਿਊਮ ਸਮੱਸਿਆਵਾਂ ਜਿਵੇਂ ਕਿ ਨਾ ਪਸੰਦ ਕੀਤੀ ਜਾਣ ਵਾਲੀ ਉੱਚੀ ਵੌਲਿਊਮ ਜਾਂ ਕੰਟਰੋਲ ਦੀ ਕਮੀ ਵਰਗੀ ਹਾਲਤ ਵਿੱਚ ਬਲੂਟੁੱਥ ਪੂਰਨ ਵੌਲਿਊਮ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਅਯੋਗ ਬਣਾਉਂਦਾ ਹੈ।"</string>
     <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੀਆਂ ਰਿੰਗਟੋਨਾਂ ਨੂੰ ਬਲੂਟੁੱਥ ਹੈੱਡਸੈੱਟਾਂ \'ਤੇ ਚਲਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"ਸਥਾਨਕ ਟਰਮੀਨਲ"</string>
-    <string name="enable_terminal_summary" msgid="67667852659359206">"ਟਰਮੀਨਲ ਐਪ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ ਜੋ ਸਥਾਨਕ ਸ਼ੈਲ ਪਹੁੰਚ ਆੱਫਰ ਕਰਦਾ ਹੈ"</string>
+    <string name="enable_terminal_summary" msgid="67667852659359206">"ਟਰਮੀਨਲ ਐਪ ਨੂੰ ਚਾਲੂ ਕਰੋ ਜੋ ਸਥਾਨਕ ਸ਼ੈਲ ਪਹੁੰਚ ਪੇਸ਼ਕਸ਼ ਕਰਦਾ ਹੈ"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP ਜਾਂਚ"</string>
     <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"HDCP ਜਾਂਚ ਵਿਵਹਾਰ ਸੈੱਟ ਕਰੋ"</string>
     <string name="debug_debugging_category" msgid="6781250159513471316">"ਡੀਬਗਿੰਗ"</string>
-    <string name="debug_app" msgid="8349591734751384446">"ਡੀਬਗ ਐਪ ਚੁਣੋ"</string>
-    <string name="debug_app_not_set" msgid="718752499586403499">"ਕੋਈ ਡੀਬਗ ਐਪਲੀਕੇਸ਼ਨ ਸੈਟ ਨਹੀਂ ਕੀਤੀ"</string>
+    <string name="debug_app" msgid="8349591734751384446">"ਡੀਬੱਗ ਐਪ ਚੁਣੋ"</string>
+    <string name="debug_app_not_set" msgid="718752499586403499">"ਕੋਈ ਡੀਬੱਗ ਐਪਲੀਕੇਸ਼ਨ ਸੈੱਟ ਨਹੀਂ ਕੀਤੀ"</string>
     <string name="debug_app_set" msgid="2063077997870280017">"ਡੀਬਗਿੰਗ ਐਪਲੀਕੇਸ਼ਨ: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="select_application" msgid="5156029161289091703">"ਐਪਲੀਕੇਸ਼ਨ ਚੁਣੋ"</string>
     <string name="no_application" msgid="2813387563129153880">"ਕੁਝ ਨਹੀਂ"</string>
-    <string name="wait_for_debugger" msgid="1202370874528893091">"ਡੀਬਗਰ ਦੀ ਉਡੀਕ ਕਰੋ"</string>
-    <string name="wait_for_debugger_summary" msgid="1766918303462746804">"ਡੀਬਗ ਕੀਤੇ ਐਪਲੀਕੇਸ਼ਨ ਐਗਜੀਕਿਊਟ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਅਟੈਚ ਕਰਨ ਲਈ ਡੀਬਗਰ ਦੀ ਉਡੀਕ ਕਰਦੇ ਹਨ"</string>
+    <string name="wait_for_debugger" msgid="1202370874528893091">"ਡੀਬੱਗਰ ਦੀ ਉਡੀਕ ਕਰੋ"</string>
+    <string name="wait_for_debugger_summary" msgid="1766918303462746804">"ਡੀਬੱਗ ਕੀਤੇ ਐਪਲੀਕੇਸ਼ਨ ਐਗਜੀਕਿਊਟ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਅਟੈਚ ਕਰਨ ਲਈ ਡੀਬੱਗਰ ਦੀ ਉਡੀਕ ਕਰਦੇ ਹਨ"</string>
     <string name="telephony_monitor_switch" msgid="1764958220062121194">"ਟੈਲੀਫ਼ੋਨੀ ਮੋਨੀਟਰ"</string>
     <string name="telephony_monitor_switch_summary" msgid="7695552966547975635">"ਟੈਲੀਫ਼ੋਨੀ ਮੋਨੀਟਰ ਟੈਲੀਫ਼ੋਨੀ/ਮੌਡਮ ਪ੍ਰਕਾਰਜਾਤਮਕਤਾ ਵਿੱਚ ਕਿਸੇ ਸਮੱਸਿਆ ਦਾ ਪਤਾ ਲੱਗਣ \'ਤੇ ਲੌਗਾਂ ਨੂੰ ਇਕੱਤਰ ਕਰੇਗਾ ਅਤੇ ਵਰਤੋਂਕਾਰ ਨੂੰ ਇੱਕ ਬੱਗ ਦਾਇਰ ਕਰਨ ਲਈ ਸੂਚਨਾ ਦੇਵੇਗਾ"</string>
     <string name="debug_input_category" msgid="1811069939601180246">"ਇਨਪੁਟ"</string>
     <string name="debug_drawing_category" msgid="6755716469267367852">"ਡਰਾਇੰਗ"</string>
-    <string name="debug_hw_drawing_category" msgid="6220174216912308658">"ਹਾਰਡਵੇਅਰ ਤੇਜ਼ ਕੀਤਾ ਪ੍ਰਗਟਾਅ"</string>
+    <string name="debug_hw_drawing_category" msgid="6220174216912308658">"ਹਾਰਡਵੇਅਰ ਐਕਸੇਲਰੇਟਿਡ ਰੈਂਡਰਿੰਗ"</string>
     <string name="media_category" msgid="4388305075496848353">"ਮੀਡੀਆ"</string>
     <string name="debug_monitoring_category" msgid="7640508148375798343">"ਨਿਰੀਖਣ ਕਰ ਰਿਹਾ ਹੈ"</string>
     <string name="strict_mode" msgid="1938795874357830695">"ਸਟ੍ਰਿਕਟ ਮੋਡ ਸਮਰਥਿਤ"</string>
     <string name="strict_mode_summary" msgid="142834318897332338">"ਜਦੋਂ ਐਪਸ ਮੇਨ ਥ੍ਰੈਡ ਤੇ ਲੰਮੇ ਓਪਰੇਸ਼ਨ ਕਰਨ ਤਾਂ ਸਕ੍ਰੀਨ ਫਲੈਸ਼ ਕਰੋ"</string>
     <string name="pointer_location" msgid="6084434787496938001">"ਪੌਇੰਟਰ ਟਿਕਾਣਾ"</string>
-    <string name="pointer_location_summary" msgid="840819275172753713">"ਸਕ੍ਰੀਨ ਓਵਰਲੇ ਮੌਜੂਦਾ ਟਚ ਡੈਟਾ ਦਿਖਾ ਰਿਹਾ ਹੈ"</string>
-    <string name="show_touches" msgid="2642976305235070316">"ਟੈਪਾਂ ਵਿਖਾਓ"</string>
-    <string name="show_touches_summary" msgid="6101183132903926324">"ਟੈਪਾਂ ਲਈ ਨਜ਼ਰ ਸਬੰਧੀ ਪ੍ਰਤੀਕਰਮ ਵਿਖਾਓ"</string>
+    <string name="pointer_location_summary" msgid="840819275172753713">"ਸਕ੍ਰੀਨ ਓਵਰਲੇ ਮੌਜੂਦਾ ਟਚ  ਡਾਟਾ  ਦਿਖਾ ਰਿਹਾ ਹੈ"</string>
+    <string name="show_touches" msgid="2642976305235070316">"ਟੈਪਾਂ  ਦਿਖਾਓ"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"ਟੈਪਾਂ ਲਈ ਨਜ਼ਰ ਸਬੰਧੀ ਪ੍ਰਤੀਕਰਮ  ਦਿਖਾਓ"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"ਸਰਫਸ ਅਪਡੇਟਾਂ ਦਿਖਾਓ"</string>
-    <string name="show_screen_updates_summary" msgid="2569622766672785529">"ਸਮੁੱਚੀ ਵਿੰਡੋ ਸਰਫੇਸਾਂ ਫਲੈਸ਼ ਕਰੋ ਜਦੋਂ ਉਹ ਅਪਡੇਟ ਹੁੰਦੀਆਂ ਹਨ"</string>
-    <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU ਦ੍ਰਿਸ਼ ਅਪਡੇਟਾਂ ਦਿਖਾਓ"</string>
-    <string name="show_hw_screen_updates_summary" msgid="1115593565980196197">"ਜਦੋਂ GPU ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਜਾਏ ਤਾਂ ਵਿੰਡੋਜ ਦੇ ਅੰਦਰ ਦ੍ਰਿਸ਼ ਫਲੈਸ਼ ਕਰੋ"</string>
-    <string name="show_hw_layers_updates" msgid="5645728765605699821">"ਹਾਰਡਵੇਅਰ ਲੇਅਰਸ ਅਪਡੇਟਾਂ ਦਿਖਾਓ"</string>
-    <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"ਹਾਰਡਵੇਅਰ ਲੇਅਰਾਂ ਨੂੰ ਹਰੀਆਂ ਫਲੈਸ਼ ਕਰੋ ਜਦੋਂ ਉਹ ਅਪਡੇਟ ਹੁੰਦੀਆਂ ਹਨ"</string>
-    <string name="debug_hw_overdraw" msgid="2968692419951565417">"GPU ਓਵਰਡ੍ਰਾ ਡੀਬਗ ਕਰੋ"</string>
+    <string name="show_screen_updates_summary" msgid="2569622766672785529">"ਵਿੰਡੋ ਦੇ ਸਮੁੱਚੇ ਤਲਾਂ ਦੇ ਅੱਪਡੇਟ ਹੋਣ \'ਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਰੌਸ਼ਨ ਕਰੋ"</string>
+    <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU ਦ੍ਰਿਸ਼ ਅੱਪਡੇਟਾਂ ਦਿਖਾਓ"</string>
+    <string name="show_hw_screen_updates_summary" msgid="1115593565980196197">"ਜਦੋਂ GPU ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਜਾਏ ਤਾਂ ਵਿੰਡੋਜ਼ ਦੇ ਅੰਦਰ ਦ੍ਰਿਸ਼ ਫਲੈਸ਼ ਕਰੋ"</string>
+    <string name="show_hw_layers_updates" msgid="5645728765605699821">"ਹਾਰਡਵੇਅਰ ਲੇਅਰਾਂ ਦੇ ਅੱਪਡੇਟਾਂ ਦਿਖਾਓ"</string>
+    <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"ਹਾਰਡਵੇਅਰ ਲੇਅਰਾਂ ਅੱਪਡੇਟ ਹੋਣ \'ਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਹਰਾ ਕਰੋ"</string>
+    <string name="debug_hw_overdraw" msgid="2968692419951565417">"GPU ਓਵਰਡ੍ਰਾ ਡੀਬੱਗ ਕਰੋ"</string>
     <string name="debug_hw_renderer" msgid="7568529019431785816">"GPU ਰੈਂਡਰਰ ਸੈੱਟ ਕਰੋ"</string>
     <string name="disable_overlays" msgid="2074488440505934665">"HW ਓਵਰਲੇਜ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
     <string name="disable_overlays_summary" msgid="3578941133710758592">"ਸਕ੍ਰੀਨ ਕੰਪੋਜਿਟਿੰਗ ਲਈ ਹਮੇਸ਼ਾਂ GPU ਵਰਤੋ"</string>
     <string name="simulate_color_space" msgid="6745847141353345872">"ਰੰਗ ਸਪੇਸ ਦੀ ਨਕਲ ਕਰੋ"</string>
-    <string name="enable_opengl_traces_title" msgid="6790444011053219871">"OpenGL ਟ੍ਰੇਸਿਜ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ"</string>
-    <string name="usb_audio_disable_routing" msgid="8114498436003102671">"USB ਔਡੀਓ ਰੂਟਿੰਗ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
-    <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"USB ਔਡੀਓ ਪੈਰੀਫਰਲ ਲਈ ਆਟੋਮੈਟਿਕ ਰੂਟਿੰਗ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
+    <string name="enable_opengl_traces_title" msgid="6790444011053219871">"OpenGL ਟ੍ਰੇਸਿਜ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
+    <string name="usb_audio_disable_routing" msgid="8114498436003102671">"USB  ਆਡੀਓ  ਰੂਟਿੰਗ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
+    <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"USB  ਆਡੀਓ  ਪੈਰੀਫਰਲ ਲਈ ਆਟੋਮੈਟਿਕ ਰੂਟਿੰਗ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
     <string name="debug_layout" msgid="5981361776594526155">"ਲੇਆਉਟ ਬਾਊਂਡਸ ਦਿਖਾਓ"</string>
     <string name="debug_layout_summary" msgid="2001775315258637682">"ਕਲਿਪ ਬਾਊਂਡਸ, ਮਾਰਜਿਨ ਆਦਿ ਦਿਖਾਓ"</string>
     <string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"RTL ਲੇਆਉਟ ਦਿਸ਼ਾ ਤੇ ਜ਼ੋਰ ਪਾਓ"</string>
     <string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"ਸਾਰੇ ਸਥਾਨਾਂ ਲਈ RTL ਵੱਲ ਸਕ੍ਰੀਨ ਲੇਆਉਟ ਦਿਸ਼ਾ ਤੇ ਜ਼ੋਰ ਪਾਓ"</string>
-    <string name="force_hw_ui" msgid="6426383462520888732">"GPU ਪ੍ਰਗਟਾਅ ਤੇ ਜ਼ੋਰ ਪਾਓ"</string>
+    <string name="force_hw_ui" msgid="6426383462520888732">"GPU ਰੈਂਡਰਿੰਗ ਤੇ ਜ਼ੋਰ ਪਾਓ"</string>
     <string name="force_hw_ui_summary" msgid="5535991166074861515">"2d ਡ੍ਰਾਇੰਗ ਲਈ GPU ਦੀ ਵਰਤੋਂ ਤੇ ਜ਼ੋਰ ਪਾਓ"</string>
     <string name="force_msaa" msgid="7920323238677284387">"4x MSAA ਤੇ ਜ਼ੋਰ ਪਾਓ"</string>
-    <string name="force_msaa_summary" msgid="9123553203895817537">"OpenGL ES 2.0 ਐਪਸ ਵਿੱਚ 4x MSAA ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ"</string>
-    <string name="show_non_rect_clip" msgid="505954950474595172">"ਗ਼ੈਰ-ਆਇਤਾਕਾਰ ਕਲਿਪ ਓਪਰੇਸ਼ਨ ਡੀਬਗ ਕਰੋ"</string>
+    <string name="force_msaa_summary" msgid="9123553203895817537">"OpenGL ES 2.0 ਐਪਾਂ ਵਿੱਚ 4x MSAA ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
+    <string name="show_non_rect_clip" msgid="505954950474595172">"ਗੈਰ-ਆਇਤਾਕਾਰ ਕਲਿੱਪ ਓਪਰੇਸ਼ਨ ਡੀਬੱਗ ਕਰੋ"</string>
     <string name="track_frame_time" msgid="6146354853663863443">"ਪ੍ਰੋਫਾਈਲ GPU ਰੈਂਡਰਿੰਗ"</string>
     <string name="window_animation_scale_title" msgid="6162587588166114700">"ਵਿੰਡੋ ਐਨੀਮੇਸ਼ਨ ਸਕੇਲ"</string>
     <string name="transition_animation_scale_title" msgid="387527540523595875">"ਟ੍ਰਾਂਜਿਸ਼ਨ ਐਨੀਮੇਸ਼ਨ ਸਕੇਲ"</string>
@@ -271,21 +286,21 @@
     <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"ਹਰੇਕ ਗਤੀਵਿਧੀ ਨੂੰ ਨਸ਼ਟ ਕਰੋ ਜਿਵੇਂ ਹੀ ਉਪਭੋਗਤਾ ਇਸਨੂੰ ਛੱਡ ਦੇਵੇ"</string>
     <string name="app_process_limit_title" msgid="4280600650253107163">"ਪਿਛੋਕੜ ਪ੍ਰਕਿਰਿਆ ਸੀਮਾ"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"ਸਾਰੇ ANR ਦਿਖਾਓ"</string>
-    <string name="show_all_anrs_summary" msgid="641908614413544127">"ਪਿਛੋਕੜ ਐਪਸ ਲਈ ਐਪਸ ਜਵਾਬ ਨਹੀਂ ਦੇ ਰਹੇ ਡਾਇਲੌਗ ਦਿਖਾਓ"</string>
-    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"ਸੂਚਨਾ ਚੈਨਲ ਚੇਤਾਵਨੀਆਂ ਦਿਖਾਓ"</string>
-    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ਐਪ ਵੱਲੋਂ ਵੈਧ ਚੈਨਲ ਤੋਂ ਬਿਨਾਂ ਸੂਚਨਾ ਪੋਸਟ ਕਰਨ \'ਤੇ ਸਕ੍ਰੀਨ \'ਤੇ ਚੇਤਾਵਨੀ ਦਿਖਾਉਂਦੀ ਹੈ"</string>
+    <string name="show_all_anrs_summary" msgid="641908614413544127">"ਬੈਕਗਰਾਊਂਡ ਐਪਾਂ ਲਈ ਐਪ ਜਵਾਬ ਨਹੀਂ ਦੇ ਰਹੇ ਡਾਇਲੌਗ ਦਿਖਾਓ"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"ਸੂਚਨਾ ਚੈਨਲ ਚਿਤਾਵਨੀਆਂ ਦਿਖਾਓ"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ਐਪ ਵੱਲੋਂ ਵੈਧ ਚੈਨਲ ਤੋਂ ਬਿਨਾਂ ਸੂਚਨਾ ਪੋਸਟ ਕਰਨ \'ਤੇ ਸਕ੍ਰੀਨ \'ਤੇ ਚਿਤਾਵਨੀ ਦਿਖਾਉਂਦੀ ਹੈ"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"ਐਪਸ ਨੂੰ ਬਾਹਰਲੇ ਤੇ ਜ਼ਬਰਦਸਤੀ ਆਗਿਆ ਦਿਓ"</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"ਮੈਨੀਫੈਸਟ ਮੁੱਲਾਂ ਦੀ ਪਰਵਾਹ ਕੀਤੇ ਬਿਨਾਂ, ਕਿਸੇ ਵੀ ਐਪ ਨੂੰ ਬਾਹਰੀ ਸਟੋਰੇਜ \'ਤੇ ਲਿਖਣ ਦੇ ਯੋਗ ਬਣਾਉਂਦੀ ਹੈ"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"ਮੁੜ-ਆਕਾਰ ਬਦਲਣ ਲਈ ਸਰਗਰਮੀਆਂ \'ਤੇ ਜ਼ੋਰ ਦਿਓ"</string>
-    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"ਮੈਨੀਫੈਸਟ ਮੁੱਲਾਂ ਦੀ ਪਰਵਾਹ ਕੀਤੇ ਬਿਨਾਂ, ਮਲਟੀ-ਵਿੰਡੋ ਲਈ ਸਾਰੀਆਂ ਸਰਗਰਮੀਆਂ ਨੂੰ ਆਕਾਰ ਬਦਲਣਯੋਗ ਬਣਾਓ।"</string>
-    <string name="enable_freeform_support" msgid="1461893351278940416">"freeform windows ਨੂੰ ਯੋਗ ਬਣਾਓ"</string>
-    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"ਪ੍ਰਯੋਗਮਈ ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਜ਼ ਲਈ ਸਮਰਥਨ ਨੂੰ ਯੋਗ ਬਣਾਓ।"</string>
-    <string name="local_backup_password_title" msgid="3860471654439418822">"ਡੈਸਕਟੌਪ ਬੈਕਅਪ ਪਾਸਵਰਡ"</string>
-    <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ਡੈਸਕਟੌਪ ਪੂਰੇ ਬੈਕਅਪਸ ਇਸ ਵੇਲੇ ਸੁਰੱਖਿਅਤ ਨਹੀਂ ਹਨ"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"ਮੈਨੀਫ਼ੈਸਟ ਮੁੱਲਾਂ ਦੀ ਪਰਵਾਹ ਕੀਤੇ ਬਿਨਾਂ, ਮਲਟੀ-ਵਿੰਡੋ ਲਈ ਸਾਰੀਆਂ ਸਰਗਰਮੀਆਂ ਨੂੰ ਆਕਾਰ ਬਦਲਣਯੋਗ ਬਣਾਓ।"</string>
+    <string name="enable_freeform_support" msgid="1461893351278940416">"freeform windows ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"ਪ੍ਰਯੋਗਮਈ ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਜ਼ ਲਈ ਸਮਰਥਨ ਨੂੰ ਚਾਲੂ ਕਰੋ।"</string>
+    <string name="local_backup_password_title" msgid="3860471654439418822">"ਡੈਸਕਟਾਪ ਬੈਕਅੱਪ ਪਾਸਵਰਡ"</string>
+    <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ਡੈਸਕਟਾਪ ਪੂਰੇ ਬੈਕਅੱਪ ਇਸ ਵੇਲੇ ਸੁਰੱਖਿਅਤ ਨਹੀਂ ਹਨ"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ਡੈਸਕਟਾਪ ਦੇ ਮੁਕੰਮਲ ਬੈਕਅੱਪਾਂ ਲਈ ਪਾਸਵਰਡ ਨੂੰ ਬਦਲਣ ਜਾਂ ਹਟਾਉਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
-    <string name="local_backup_password_toast_success" msgid="582016086228434290">"ਨਵਾਂ ਬੈਕਅਪ ਪਾਸਵਰਡ ਸੈੱਟ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="local_backup_password_toast_success" msgid="582016086228434290">"ਨਵਾਂ ਬੈਕਅੱਪ ਪਾਸਵਰਡ ਸੈੱਟ ਕੀਤਾ ਗਿਆ"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"ਨਵਾਂ ਪਾਸਵਰਡ ਅਤੇ ਪੁਸ਼ਟੀ ਮੇਲ ਨਹੀਂ ਖਾਂਦੀ"</string>
-    <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"ਬੈਕਅਪ ਪਾਸਵਰਡ ਸੈਟ ਕਰਨ ਵਿੱਚ ਅਸਫਲਤਾ"</string>
+    <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"ਬੈਕਅੱਪ ਪਾਸਵਰਡ ਸੈੱਟ ਕਰਨ ਵਿੱਚ ਅਸਫਲਤਾ"</string>
   <string-array name="color_mode_names">
     <item msgid="2425514299220523812">"ਚਮਕੀਲਾ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
     <item msgid="8446070607501413455">"ਕੁਦਰਤੀ"</item>
@@ -308,7 +323,7 @@
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"ਤਬਦੀਲ ਕਰੋ ..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"ਫ਼ਾਈਲ ਪਹਿਲਾਂ ਤੋਂ ਇਨਕ੍ਰਿਪਟਡ ਹੈ"</string>
     <string name="title_convert_fbe" msgid="1263622876196444453">"ਫ਼ਾਈਲ ਆਧਾਰਿਤ ਇਨਕ੍ਰਿਪਸ਼ਨ ਵਿੱਚ ਤਬਦੀਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
-    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"ਡੈਟਾ ਪਾਰਟੀਸ਼ਨ ਦਾ ਫ਼ਾਈਲ ਆਧਾਰਿਤ ਇਨਕ੍ਰਿਪਸ਼ਨ ਵਿੱਚ ਰੁਪਾਂਤਰਣ ਕਰੋ\n !!ਚੇਤਾਵਨੀ!! ਇਹ ਤੁਹਾਡੇ ਸਾਰੇ ਡੈਟੇ ਨੂੰ ਮਿਟਾ ਦੇਵੇਗਾ\n ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਪ੍ਰਯੋਗਿਕ ਹੈ, ਅਤੇ ਸ਼ਾਇਦ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ।\n ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਮਿਟਾਓ ਅਤੇ ਰੁਪਾਂਤਰਣ ਕਰੋ...\' ਨੂੰ ਦਬਾਓ।"</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">" ਡਾਟਾ  ਪਾਰਟੀਸ਼ਨ ਦਾ ਫ਼ਾਈਲ ਆਧਾਰਿਤ ਇਨਕ੍ਰਿਪਸ਼ਨ ਵਿੱਚ ਰੁਪਾਂਤਰਣ ਕਰੋ\n !! ਚਿਤਾਵਨੀ !! ਇਹ ਤੁਹਾਡੇ ਸਾਰੇ  ਡਾਟੇ  ਨੂੰ ਮਿਟਾ ਦੇਵੇਗਾ\n ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਪ੍ਰਯੋਗਿਕ ਹੈ, ਅਤੇ ਸ਼ਾਇਦ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ।\n ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਮਿਟਾਓ ਅਤੇ ਰੁਪਾਂਤਰਣ ਕਰੋ...\' ਨੂੰ ਦਬਾਓ।"</string>
     <string name="button_convert_fbe" msgid="5152671181309826405">"ਮਿਟਾਓ ਅਤੇ ਰੁਪਾਂਤਰਣ ਕਰੋ..."</string>
     <string name="picture_color_mode" msgid="4560755008730283695">"ਤਸਵੀਰ ਰੰਗ ਮੋਡ"</string>
     <string name="picture_color_mode_desc" msgid="1141891467675548590">"sRGB ਵਰਤੋਂ ਕਰੋ"</string>
@@ -320,16 +335,19 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ਰੰਗ ਸੰਸ਼ੋਧਨ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਪ੍ਰਯੋਗਾਤਮਿਕ ਹੈ ਅਤੇ ਪ੍ਰਦਰਸ਼ਨ ਤੇ ਅਸਰ ਪਾ ਸਕਦੀ ਹੈ।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ਦੁਆਰਾ ਓਵਰਰਾਈਡ ਕੀਤਾ"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਲਈ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"ਲਗਭਗ <xliff:g id="TIME">^1</xliff:g> ਬਾਕੀ"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ ਲਗਭਗ <xliff:g id="TIME">^1</xliff:g> ਬਾਕੀ"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਲਈ <xliff:g id="TIME">^1</xliff:g> ਬਾਕੀ"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> ਬਾਕੀ"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ <xliff:g id="TIME">^1</xliff:g> ਬਾਕੀ"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - ਲਗਭਗ <xliff:g id="TIME">^2</xliff:g> ਬਾਕੀ"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ ਲਗਭਗ <xliff:g id="TIME">^2</xliff:g> ਬਾਕੀ"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਤੱਕ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਤੱਕ <xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"ਅਗਿਆਤ"</string>
-    <string name="battery_info_status_charging" msgid="1705179948350365604">"ਚਾਰਜਿੰਗ"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ਚਾਰਜ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string>
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string>
@@ -340,7 +358,7 @@
     <string name="disabled" msgid="9206776641295849915">"ਅਯੋਗ ਬਣਾਇਆ"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"ਇਜਾਜ਼ਤ ਹੈ"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"ਇਜਾਜ਼ਤ ਨਹੀਂ"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਿਤ ਕਰੋ"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰੋ"</string>
     <string name="home" msgid="3256884684164448244">"ਸੈਟਿੰਗਾਂ ਮੁੱਖ ਪੰਨਾ"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
@@ -354,8 +372,8 @@
     <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ਵੱਡੀ"</string>
     <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ਥੋੜ੍ਹਾ ਵੱਡੀ"</string>
     <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ਸਭ ਤੋਂ ਵੱਡੀ"</string>
-    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
-    <string name="help_feedback_label" msgid="6815040660801785649">"ਮਦਦ ਅਤੇ ਪ੍ਰਤੀਕਰਮ"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ਵਿਉਂਂਤੀ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
+    <string name="help_feedback_label" msgid="6815040660801785649">"ਮਦਦ &amp; ਫੀਡਬੈਕ"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"ਮੀਨੂ"</string>
     <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
     <string name="retail_demo_reset_message" msgid="118771671364131297">"ਡੈਮੋ ਮੋਡ \'ਚ ਫੈਕਟਰੀ ਰੀਸੈੱਟ ਲਈ ਪਾਸਵਰਡ ਦਿਓ"</string>
@@ -364,6 +382,6 @@
     <string name="active_input_method_subtypes" msgid="3596398805424733238">"ਸਰਗਰਮ ਇਨਪੁਟ ਵਿਧੀਆਂ"</string>
     <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"ਸਿਸਟਮ ਭਾਸ਼ਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> ਲਈ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹਣ ਵਿੱਚ ਅਸਫਲ"</string>
-    <string name="ime_security_warning" msgid="4135828934735934248">"ਇਹ ਇਨਪੁਟ ਵਿਧੀ ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤਾ ਜਾਣ ਵਾਲਾ ਸਾਰਾ ਟੈਕਸਟ ਇਕੱਤਰ ਕਰਨ ਵਿੱਚ ਸਮਰੱਥ ਹੋ ਸਕਦਾ ਹੈ, ਨਿੱਜੀ ਡੈਟਾ ਸਮੇਤ ਜਿਵੇਂ ਪਾਸਵਰਡ ਅਤੇ ਕ੍ਰੈਡਿਟ ਕਾਰਡ ਨੰਬਰ। ਇਹ <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>ਐਪ ਤੋਂ ਆਉਂਦਾ ਹੈ। ਕੀ ਇਹ ਸਪੈੱਲ ਚੈਕਰ ਵਰਤਣਾ ਹੈ?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"ਨੋਟ ਕਰੋ: ਰੀਬੂਟ ਤੋਂ ਬਾਅਦ, ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਆਪਣਾ ਫ਼ੋਨ ਅਨਲੌਕ ਨਹੀਂ ਕਰਦੇ ਤਦ ਤੱਕ ਇਹ ਐਪ ਚਾਲੂ ਨਹੀਂ ਹੋ ਸਕਦੀ"</string>
+    <string name="ime_security_warning" msgid="4135828934735934248">"ਇਹ ਇਨਪੁੱਟ ਵਿਧੀ ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤਾ ਜਾਣ ਵਾਲੀ ਸਾਰੀ ਲਿਖਤ ਇਕੱਤਰ ਕਰਨ ਵਿੱਚ ਸਮਰੱਥ ਹੋ ਸਕਦੀ ਹੈ, ਨਿੱਜੀ ਡਾਟਾ ਸਮੇਤ ਜਿਵੇਂ ਪਾਸਵਰਡ ਅਤੇ ਕ੍ਰੈਡਿਟ ਕਾਰਡ ਨੰਬਰ। ਇਹ <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> ਐਪ ਤੋਂ ਆਉਂਦਾ ਹੈ। ਕੀ ਇਹ ਸਪੈੱਲ ਚੈਕਰ ਵਰਤਣਾ ਹੈ?"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"ਨੋਟ ਕਰੋ: ਰੀਬੂਟ ਤੋਂ ਬਾਅਦ, ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਆਪਣਾ ਫ਼ੋਨ ਅਣਲਾਕ ਨਹੀਂ ਕਰਦੇ ਤਦ ਤੱਕ ਇਹ ਐਪ ਚਾਲੂ ਨਹੀਂ ਹੋ ਸਕਦੀ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index 375615f..2e23878 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (domyślna)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Użyj wyboru systemu (domyślnie)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Włącz opcjonalne kodeki"</item>
-    <item msgid="3304843301758635896">"Wyłącz opcjonalne kodeki"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Użyj wyboru systemu (domyślnie)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Włączenie opcjonalnych kodeków"</item>
-    <item msgid="741805482892725657">"Wyłączenie opcjonalnych kodeków"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Użyj wyboru systemu (domyślnie)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 0e92353..58454b4 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Brak połączenia z powodu słabego sygnału sieci"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Błąd połączenia Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problem z uwierzytelnianiem"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Nie można się połączyć"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Nie można się połączyć z siecią „<xliff:g id="AP_NAME">%1$s</xliff:g>”"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Sprawdź hasło i spróbuj ponownie"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Poza zasięgiem"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nie można połączyć automatycznie"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Brak dostępu do internetu"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Połączono przez %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Dostępne przez %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Połączono, brak internetu"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Bardzo wolna"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Wolna"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Średnia"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Szybka"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Bardzo szybka"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Rozłączona"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Rozłączanie..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Łączenie..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Połączono (bez multimediów)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Połączono (brak dostępu do wiadomości)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Połączono (bez telefonu ani multimediów)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Połączono, bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Połączono (bez telefonu), bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Połączono (bez multimediów), bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Połączono (bez telefonu i multimediów), bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Dźwięk multimediów"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Dźwięk telefonu"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Połączenia telefoniczne"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Przesyłanie pliku"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Urządzenie wejściowe"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Dostęp do internetu"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Udostępnianie kontaktów"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Używaj do udostępniania kontaktów"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Udostępnianie połączenia internetowego"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Dostęp do wiadomości"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"SMS-y"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Dostęp do karty SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Korzystaj z dźwięku wysokiej jakości: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Korzystaj z dźwięku wysokiej jakości"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Dźwięk HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Dźwięk HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Połączono z funkcją audio multimediów"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Połączono z funkcją audio telefonu"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Połączono z serwerem transferu plików"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Przełączaj z Wi-Fi na sieć komórkową"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Zawsze szukaj Wi-Fi w roamingu"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilna transmisja danych zawsze aktywna"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Akceleracja sprzętowa tetheringu"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Wyłącz głośność bezwzględną"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Włącz dzwonek w kanale dźwiękowym"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Wersja AVRCP Bluetooth"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Zezwalaj na pozorowanie lokalizacji"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Inspekcja wyświetlania atrybutu"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Nie wyłączaj transmisji danych przez sieć komórkową, nawet gdy aktywne jest połączenie Wi-Fi (aby szybko przełączać sieci)"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Użyj akceleracji sprzętowej tetheringu, jeśli jest dostępna"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Czy zezwalać na debugowanie USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Debugowanie USB jest przeznaczone wyłącznie do celów programistycznych. Może służyć do kopiowania danych między komputerem a urządzeniem, instalowania aplikacji na urządzeniu bez powiadamiania, a także odczytu danych dziennika."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Odwołać dostęp wszystkich poprzednio autoryzowanych komputerów do debugowania USB?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekcja kolorów"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"To jest funkcja eksperymentalna i może wpływać na działanie urządzenia."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nadpisana przez <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Pozostało: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> do pełnego naładowania"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zostało <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – pozostało około <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostało <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Pozostało: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Jeszcze około <xliff:g id="TIME">^1</xliff:g> (na podstawie Twojego sposobu korzystania)"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> do pełnego naładowania"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zostało <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Jeszcze <xliff:g id="TIME">^1</xliff:g> (na podstawie Twojego sposobu korzystania)"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – pozostało około <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – jeszcze około <xliff:g id="TIME">^2</xliff:g> (na podstawie Twojego sposobu korzystania)"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – zostało <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> do pełnego naładowania"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Nieznane"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Ładowanie"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ładowanie"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
index e3f287b..a1b545f 100644
--- a/packages/SettingsLib/res/values-pt-rBR/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (padrão)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Usar seleção do sistema (padrão)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Ativar codecs opcionais"</item>
-    <item msgid="3304843301758635896">"Desativar codecs opcionais"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Usar seleção do sistema (padrão)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Ativar codecs opcionais"</item>
-    <item msgid="741805482892725657">"Desativar codecs opcionais"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Usar seleção do sistema (padrão)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index e0683a8..3b97a7f 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Não conectado devido à baixa qualidade da rede"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Falha de conexão Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problema de autenticação"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Não é possível estabelecer conexão"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Não é possível conectar-se a \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Verifique a senha e tente novamente"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Fora do alcance"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Não se conectará automaticamente"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Sem acesso à Internet"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectada, sem Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Muito lenta"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Ok"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Média"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Rápida"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Muito rápida"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Desconectando…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Conectando..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectado (sem mídia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Conectado (sem acesso a mensagens)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectado (sem telefone ou mídia)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Conectado, nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Conectado (sem smartphone), nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Conectado (sem mídia), nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Conectado (sem smartphone ou mídia), nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Áudio da mídia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Áudio do smartphone"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Chamadas telefônicas"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferência de arquivo"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acesso à Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartilhamento de contatos"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Usar para compartilhamento de contatos"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Compartilhamento de conexão à Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acesso a mensagens"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Mensagens de texto"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acesso SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Usar áudio de alta qualidade: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Usar áudio de alta qualidade"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Áudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Áudio HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado ao áudio da mídia"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado ao áudio do smartphone"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado ao servidor de transferência de arquivo"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mudança agressiva de Wi-Fi para móvel"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sempre permitir verif. de roaming de Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware de tethering"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Ativar o toque em banda"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versão do Bluetooth AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permitir locais fictícios"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Ativar visualiz. insp. atributo"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Sempre manter dados móveis ativos, mesmo quando o Wi-Fi estiver ativado (para troca rápida de rede)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Usar aceleração de hardware de tethering quando disponível"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Permitir a depuração USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"A depuração USB serve apenas para fins de desenvolvimento. Use-a para copiar dados entre o computador e o dispositivo, instalar apps no seu aparelho sem notificação e ler dados de registro."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revogar o acesso à depuração USB para todos os computadores autorizados?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correção de cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Este recurso é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Cerca de <xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> restante(s) até a carga completa"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Cerca de <xliff:g id="TIME">^1</xliff:g> restante(s)"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Cerca de <xliff:g id="TIME">^1</xliff:g> restante(s) com base no seu uso"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> restante(s) até a carga completa"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> restante(s)"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> restante(s) com base no seu uso"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - cerca de <xliff:g id="TIME">^2</xliff:g> restante(s)"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g>: cerca de <xliff:g id="TIME">^2</xliff:g> restante(s) com base no seu uso"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> restante(s)"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> até a carga completa"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"carregando"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
index 3eeade0..e55d124 100644
--- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (predefinição)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Utilizar seleção do sistema (predef.)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Ativar codecs opcionais"</item>
-    <item msgid="3304843301758635896">"Desativar codecs opcionais"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Utilizar seleção do sistema (predef.)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Ativar codecs opcionais"</item>
-    <item msgid="741805482892725657">"Desativar codecs opcionais"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Utilizar seleção do sistema (predef.)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 6889e01..e2c6b2f 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Não ligado devido à baixa qualidade da rede"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Falha de ligação Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problema de autenticação"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Não é possível ligar"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Não é possível ligar a \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Verifique a palavra-passe e tente novamente"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Fora do alcance"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Não é efetuada uma ligação automaticamente"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Sem acesso à Internet"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Ligado através de %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponível através de %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Ligado, sem Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Muito lenta"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Média"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Rápida"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Muito rápida"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desligado"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"A desligar..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"A ligar..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Ligado (sem multimédia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Ligado (sem acesso a mensagens)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Ligado (sem telefone ou multimédia)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Ligado com <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Ligado (sem telemóvel) com <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Ligado (sem multimédia) com <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Ligado (sem telemóvel nem multimédia) com <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Áudio de multimédia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Áudio do telemóvel"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Chamadas telefónicas"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferência do ficheiro"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acesso à internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Partilha de contactos"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Utilizar para a partilha de contactos"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Partilha da ligação à internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acesso a mensagens"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Mensagens de texto"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acesso ao SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Utilizar áudio de alta qualidade: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Utilizar áudio de alta qualidade"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Áudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Áudio HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Ligado ao áudio de multimédia"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Ligado ao áudio do telefone"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Ligado ao servidor de transferência de ficheiros"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mudança brusca de Wi‑Fi para rede móvel"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir sempre a deteção de Wi-Fi em roaming"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware para ligação (à Internet) via telemóvel"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Ativar toque dentro da banda"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versão de Bluetooth AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permitir locais fictícios"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Ativar a inspeção do atributo de visualização"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Manter sempre os dados móveis ativados, mesmo quando o Wi‑Fi estiver ativado (para mudança de rede rápida)"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Se disponível, utilizar a aceleração de hardware para ligação (à Internet) via telemóvel"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Permitir depuração USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"A depuração USB é utilizada apenas para fins de programação. Utilize-a para copiar dados entre o computador e o aparelho, instalar aplicações no aparelho sem notificação e ler dados de registo."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revogar acesso à depuração USB de todos os computadores anteriormente autorizados?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correção da cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta funcionalidade é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Falta(m) cerca de <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Falta(m) <xliff:g id="TIME">%1$s</xliff:g> para concluir o carregamento"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Resta(m) <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – falta(m) cerca de <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – resta(m) <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Falta(m) cerca de <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Resta(m) cerca de <xliff:g id="TIME">^1</xliff:g> com base na sua utilização"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Falta(m) <xliff:g id="TIME">^1</xliff:g> para concluir o carregamento"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Resta(m) <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Resta(m) <xliff:g id="TIME">^1</xliff:g> com base na sua utilização"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – falta(m) cerca de <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – resta(m) cerca de <xliff:g id="TIME">^2</xliff:g> com base na sua utilização"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – resta(m) <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar totalmente carregada"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> até ficar totalmente carregada"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"A carregar"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"a carregar…"</string>
diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml
index e3f287b..a1b545f 100644
--- a/packages/SettingsLib/res/values-pt/arrays.xml
+++ b/packages/SettingsLib/res/values-pt/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (padrão)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Usar seleção do sistema (padrão)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Ativar codecs opcionais"</item>
-    <item msgid="3304843301758635896">"Desativar codecs opcionais"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Usar seleção do sistema (padrão)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Ativar codecs opcionais"</item>
-    <item msgid="741805482892725657">"Desativar codecs opcionais"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Usar seleção do sistema (padrão)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index e0683a8..3b97a7f 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Não conectado devido à baixa qualidade da rede"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Falha de conexão Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problema de autenticação"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Não é possível estabelecer conexão"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Não é possível conectar-se a \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Verifique a senha e tente novamente"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Fora do alcance"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Não se conectará automaticamente"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Sem acesso à Internet"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectada, sem Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Muito lenta"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Ok"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Média"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Rápida"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Muito rápida"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Desconectando…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Conectando..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectado (sem mídia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Conectado (sem acesso a mensagens)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectado (sem telefone ou mídia)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Conectado, nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Conectado (sem smartphone), nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Conectado (sem mídia), nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Conectado (sem smartphone ou mídia), nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Áudio da mídia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Áudio do smartphone"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Chamadas telefônicas"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferência de arquivo"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acesso à Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartilhamento de contatos"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Usar para compartilhamento de contatos"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Compartilhamento de conexão à Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acesso a mensagens"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Mensagens de texto"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acesso SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Usar áudio de alta qualidade: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Usar áudio de alta qualidade"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Áudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Áudio HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado ao áudio da mídia"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado ao áudio do smartphone"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado ao servidor de transferência de arquivo"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mudança agressiva de Wi-Fi para móvel"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sempre permitir verif. de roaming de Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware de tethering"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Ativar o toque em banda"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versão do Bluetooth AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permitir locais fictícios"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Ativar visualiz. insp. atributo"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Sempre manter dados móveis ativos, mesmo quando o Wi-Fi estiver ativado (para troca rápida de rede)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Usar aceleração de hardware de tethering quando disponível"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Permitir a depuração USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"A depuração USB serve apenas para fins de desenvolvimento. Use-a para copiar dados entre o computador e o dispositivo, instalar apps no seu aparelho sem notificação e ler dados de registro."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revogar o acesso à depuração USB para todos os computadores autorizados?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correção de cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Este recurso é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Cerca de <xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> restante(s) até a carga completa"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Cerca de <xliff:g id="TIME">^1</xliff:g> restante(s)"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Cerca de <xliff:g id="TIME">^1</xliff:g> restante(s) com base no seu uso"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> restante(s) até a carga completa"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> restante(s)"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> restante(s) com base no seu uso"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - cerca de <xliff:g id="TIME">^2</xliff:g> restante(s)"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g>: cerca de <xliff:g id="TIME">^2</xliff:g> restante(s) com base no seu uso"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> restante(s)"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> até a carga completa"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"carregando"</string>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index 39ebb82..4cb0a4f 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (prestabilit)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Folosiți selectarea sist. (prestabilit)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Activați codecurile opționale"</item>
-    <item msgid="3304843301758635896">"Dezactivați codecurile opționale"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Folosiți selectarea sist. (prestabilit)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Activați codecurile opționale"</item>
-    <item msgid="741805482892725657">"Dezactivați codecurile opționale"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Folosiți selectarea sist. (prestabilit)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 4a4a7a0..97e2877 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Nu există conexiune din cauza rețelei de calitate slabă"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Eroare de conexiune Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problemă la autentificare"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Nu se poate conecta"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Nu se poate conecta la „<xliff:g id="AP_NAME">%1$s</xliff:g>”"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Verificați parola și încercați din nou"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"În afara ariei de acoperire"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nu se va conecta automat"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Nu există acces la internet"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectată prin %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponibilă prin %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectată, fără internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Foarte lentă"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Lentă"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Bine"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Medie"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Rapidă"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Foarte rapidă"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Deconectat"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"În curs de deconectare..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Se conectează..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectat (fără conținut media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Conectat (fără acces la mesaje)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectat (fără telefon sau conț. media)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Conectat, bateria la <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Conectat (fără telefon), bateria la <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Conectat (fără conținut media), bateria la <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Conectat (fără telefon sau conținut media), bateria la <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Conținut media audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Componenta audio a telefonului"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Apeluri telefonice"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfer de fișiere"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispozitiv de intrare"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acces internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Acces la Agendă"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Utilizați pentru a permite accesul la Agendă"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Distribuirea conexiunii la internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acces la mesaje"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Mesaje text"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acces la SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Utilizați conținut audio de înaltă calitate: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Utilizați conținut audio de înaltă calitate"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectat la profilul pentru conținut media audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectat la componenta audio a telefonului"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectat la serverul de transfer de fișiere"</string>
@@ -151,9 +164,9 @@
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Setările VPN nu sunt disponibile pentru acest utilizator"</string>
     <string name="tethering_settings_not_available" msgid="6765770438438291012">"Setările pentru tethering nu sunt disponibile pentru acest utilizator"</string>
     <string name="apn_settings_not_available" msgid="7873729032165324000">"Setările pentru „Nume puncte de acces” nu sunt disponibile pentru acest utilizator"</string>
-    <string name="enable_adb" msgid="7982306934419797485">"Depanare USB"</string>
+    <string name="enable_adb" msgid="7982306934419797485">"Remedierea erorilor prin USB"</string>
     <string name="enable_adb_summary" msgid="4881186971746056635">"Mod de depanare când este conectat USB"</string>
-    <string name="clear_adb_keys" msgid="4038889221503122743">"Revoc autorizații depanare USB"</string>
+    <string name="clear_adb_keys" msgid="4038889221503122743">"Revoc autorizații remediere a erorilor prin USB"</string>
     <string name="bugreport_in_power" msgid="7923901846375587241">"Comandă rapidă pentru raportul de erori"</string>
     <string name="bugreport_in_power_summary" msgid="1778455732762984579">"Afișați un buton în meniul de pornire pentru a realiza un raport de erori"</string>
     <string name="keep_screen_on" msgid="1146389631208760344">"Activ permanent"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Predare agresivă de la Wi-Fi la mobilă"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Se permite întotdeauna scanarea traficului Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Date mobile permanent active"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Accelerare hardware pentru tethering"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Dezactivați volumul absolut"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Activați soneria în căști"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versiunea AVRCP pentru Bluetooth"</string>
@@ -204,8 +218,9 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permiteți locațiile fictive"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Activați inspectarea atributelor de vizualizare"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Păstrați întotdeauna conexiunea de date mobile activată, chiar și atunci când funcția Wi‑Fi este activată (pentru comutarea rapidă între rețele)."</string>
-    <string name="adb_warning_title" msgid="6234463310896563253">"Permiteți depanarea USB?"</string>
-    <string name="adb_warning_message" msgid="7316799925425402244">"Depanarea USB are exclusiv scopuri de dezvoltare. Utilizați-o pentru a copia date de pe computer pe dispozitiv, pentru a instala aplicații pe dispozitiv fără notificare și pentru a citi datele din jurnale."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Folosiți accelerarea hardware pentru tethering, dacă este disponibilă"</string>
+    <string name="adb_warning_title" msgid="6234463310896563253">"Permiteți remedierea erorilor prin USB?"</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"Remedierea erorilor prin USB are exclusiv scopuri de dezvoltare. Utilizați-o pentru a copia date de pe computer pe dispozitiv, pentru a instala aplicații pe dispozitiv fără notificare și pentru a citi datele din jurnale."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revocați accesul la remedierea erorilor prin USB de pe toate computerele pe care le-ați autorizat anterior?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"Permiteți setările pentru dezvoltare?"</string>
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Aceste setări sunt destinate exclusiv utilizării pentru dezvoltare. Din cauza lor, este posibil ca dispozitivul dvs. și aplicațiile de pe acesta să nu mai funcționeze sau să funcționeze necorespunzător."</string>
@@ -320,16 +335,19 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corecția culorii"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Această funcție este experimentală și poate afecta performanțele."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valoare înlocuită de <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Timp rămas: aproximativ <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Timp rămas până la încărcarea completă: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Timp rămas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - încă aproximativ <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – timp rămas: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Timp rămas: aproximativ <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"În baza utilizării, timpul aproximativ rămas este: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Timp rămas până la încărcarea completă: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Timp rămas: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"În baza utilizării, timpul rămas este: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - încă aproximativ <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – în baza utilizării, timpul aproximativ rămas este: <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – timp rămas: <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcarea completă"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> până la încărcarea completă"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Necunoscut"</string>
-    <string name="battery_info_status_charging" msgid="1705179948350365604">"Încarcă"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Se încarcă"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"se încarcă"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"Nu se încarcă"</string>
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nu încarcă"</string>
diff --git a/packages/SettingsLib/res/values-ru/arrays.xml b/packages/SettingsLib/res/values-ru/arrays.xml
index 784e48e..c5a9ddd 100644
--- a/packages/SettingsLib/res/values-ru/arrays.xml
+++ b/packages/SettingsLib/res/values-ru/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (по умолчанию)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Выбор системы (по умолчанию)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Включить дополнительные кодеки"</item>
-    <item msgid="3304843301758635896">"Отключить дополнительные кодеки"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Выбор системы (по умолчанию)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Включить дополнительные кодеки"</item>
-    <item msgid="741805482892725657">"Отключить дополнительные кодеки"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Выбор системы (по умолчанию)"</item>
     <item msgid="8895532488906185219">"44,1 кГц"</item>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 90d9c33..381d931 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Подключение невозможно из-за низкого качества сети"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Ошибка подключения Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Ошибка аутентификации"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Ошибка подключения"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Не удалось подключиться к сети \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Возможно, вы указали неверный пароль. Повторите попытку."</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Недоступна"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Подключение не будет выполняться автоматически"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Отсутствует подключение к Интернету"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Подключено к %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Доступно через %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Подключено, без Интернета"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Очень медленная"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Медленная"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ОК"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Средняя"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Быстрая"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Очень быстрая"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Нет подключения"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Отключение..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Подключение..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Подключено (кроме A2DP)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Подключено (нет доступа к сообщениям)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Подключено (кроме HSP/HFP/A2DP)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Подключено, уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Подключено (кроме звонков), уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Подключено (кроме аудио), уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Подключено (кроме звонков и аудио), уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Профиль A2DP"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Профиль HSP/HFP"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Звонки"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Профиль OPP"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Профиль HID"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Доступ к Интернету"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Обмен контактами"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Использовать для обмена контактами"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Профиль PAN"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Доступ к сообщениям"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Текстовые сообщения"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Доступ к SIM-карте"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Использовать аудио высокого качества: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Использовать аудио высокого качества"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD Audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Подключено к мультимедийному аудиоустройству"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Подключено к аудиоустройству телефона"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Установлено подключение к серверу передачи файлов"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Переключаться на мобильную сеть"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Всегда включать поиск сетей Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Не отключать мобильный Интернет"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Аппаратное ускорение в режиме модема"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Отключить абсолютный уровень громкости"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Включить внутриполосное воспроизведение"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версия Bluetooth AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Разрешить использование фиктивных местоположений"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Включить проверку атрибутов"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Не отключать передачу данных по мобильной сети даже при активном Wi-Fi-подключении (для быстрого переключения между сетями)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Использовать аппаратное ускорение в режиме модема (если доступно)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Разрешить отладку по USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Отладка по USB – это режим, который позволяет использовать ваше устройство как внешний накопитель: перемещать файлы (с компьютера и на компьютер), напрямую устанавливать приложения, а также просматривать системные журналы."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Запретить доступ к USB-отладке для всех компьютеров, которым он был разрешен?"</string>
@@ -255,12 +270,12 @@
     <string name="debug_layout" msgid="5981361776594526155">"Показывать границы элементов"</string>
     <string name="debug_layout_summary" msgid="2001775315258637682">"Показывать границы обрезки, поля и т. п."</string>
     <string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"Отразить интерфейс"</string>
-    <string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"Включить написание справа налево для всех языков"</string>
+    <string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"Принудительно расположить элементы интерфейса справа налево во всех локалях"</string>
     <string name="force_hw_ui" msgid="6426383462520888732">"GPU-ускорение"</string>
     <string name="force_hw_ui_summary" msgid="5535991166074861515">"Всегда использовать GPU для двухмерного рисования"</string>
     <string name="force_msaa" msgid="7920323238677284387">"Включить 4x MSAA"</string>
     <string name="force_msaa_summary" msgid="9123553203895817537">"Включить 4x MSAA в приложениях OpenGL ES 2.0"</string>
-    <string name="show_non_rect_clip" msgid="505954950474595172">"Отладить операции непрямоугольного усечения"</string>
+    <string name="show_non_rect_clip" msgid="505954950474595172">"Отладка операций усечения сложной формы"</string>
     <string name="track_frame_time" msgid="6146354853663863443">"Профилировать GPU-отрисовку"</string>
     <string name="window_animation_scale_title" msgid="6162587588166114700">"Анимация окон"</string>
     <string name="transition_animation_scale_title" msgid="387527540523595875">"Анимация переходов"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Коррекция цвета"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Это экспериментальная функция, она может снизить производительность устройства."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Новая настройка: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Осталось примерно <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Ещё <xliff:g id="TIME">%1$s</xliff:g> до полной зарядки"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Осталось: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – осталось примерно <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g>, осталось: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Осталось примерно <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Осталось примерно <xliff:g id="TIME">^1</xliff:g> при текущем уровне использования"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Ещё <xliff:g id="TIME">^1</xliff:g> до полной зарядки"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Осталось: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Осталось <xliff:g id="TIME">^1</xliff:g> при текущем уровне использования"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – осталось примерно <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> (осталось примерно <xliff:g id="TIME">^2</xliff:g> при текущем уровне использования)"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g>, осталось: <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> до полной зарядки"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Неизвестно"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Идет зарядка"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"заряжается"</string>
diff --git a/packages/SettingsLib/res/values-si/arrays.xml b/packages/SettingsLib/res/values-si/arrays.xml
index 582c248..069470a 100644
--- a/packages/SettingsLib/res/values-si/arrays.xml
+++ b/packages/SettingsLib/res/values-si/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (පෙරනිමි)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"පද්ධති තේරීම භාවිත කරන්න (පෙරනිමි)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"විකල්පමය කොඩෙක් සබල කරන්න"</item>
-    <item msgid="3304843301758635896">"විකල්පමය කොඩෙක් අබල කරන්න"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"පද්ධති තේරීම භාවිත කරන්න (පෙරනිමි)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"විකල්පමය කොඩෙක් සබල කරන්න"</item>
-    <item msgid="741805482892725657">"විකල්පමය කොඩෙක් අබල කරන්න"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"පද්ධති තේරීම භාවිත කරන්න (පෙරනිමි)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index a89af0a..f20af61 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"අඩු ගුණත්වයේ ජාලය හේතුවෙන් සම්බන්ධ නොවීය"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi සම්බන්ධතාව අසාර්ථකයි"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"සත්‍යාපනයේ ගැටලුවකි"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"සම්බන්ධ විය නොහැකිය"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' වෙත සම්බන්ධ විය නොහැකිය"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"මුරපදය පරික්ෂා කර නැවත උත්සාහ කරන්න"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"පරාසයේ නැත"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ස්වයංක්‍රිය නැවත සම්බන්ධ නොවනු ඇත"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"අන්තර්ජාල ප්‍රවේශය නැත"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s හරහා සම්බන්ධ විය"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s හරහා ලබා ගැනීමට හැකිය"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"සම්බන්ධයි, අන්තර්ජාලය නැත"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"ඉතා මන්දගාමී"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"මන්දගාමී"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"හරි"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"මධ්‍යම"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"වේගවත්"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"ඉතා වේගවත්"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"විසන්ධි වුණි"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"විසන්ධි වෙමින්…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"සම්බන්ධ වෙමින්…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"සම්බන්ධිතයි (මාධ්‍යයක් නොමැත)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"සම්බන්ධිතයි (පණිවිඩ ප්‍රවේශ නොමැත)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"සම්බන්ධිතයි (දුරකතනයක් හෝ මාධ්‍යයක් නැත)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"සම්බන්ධිතයි, බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"සම්බන්ධිතයි (දුරකථනය නැත), බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"සම්බන්ධිතයි (මාධ්‍යයක් නොමැත), බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"සම්බන්ධිතයි (දුරකථනයක් හෝ මාධ්‍යයක් නැත), බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"මාධ්‍ය ශ්‍රව්‍ය"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"දුරකථන ශ්‍රව්‍ය"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"දුරකථන ඇමතුම්"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ගොනු හුවමාරුව"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ආදාන උපාංගය"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"අන්තර්ජාල ප්‍රවේශය"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"සම්බන්ධතා බෙදාගැනීම"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"සම්බන්ධතා බෙදාගැනීම සඳහා භාවිතා කිරීම"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"අන්තර්ජාල සම්බන්ධතා බෙදාගැනීම"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"පණිවිඩ ප්‍රවේශය"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"පෙළ පණිවිඩ"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM ප්‍රවේශය"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ඉහළ ගුණත්වයේ ශ්‍රව්‍ය භාවිත කරන්න: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ඉහළ ගුණත්වයේ ශ්‍රව්‍ය භාවිත කරන්න"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ශ්‍රව්‍යය: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ශ්‍රව්‍යය"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"මාධ්‍ය ශ්‍රව්‍යට සම්බන්ධ විය"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"දුරකතනයේ ශ්‍රව්‍යට සම්බන්ධ විය"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ගොනු හුවමාරු සේවාදායකය සමග සම්බන්ධ විය"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ආක්‍රමණික Wi‑Fi සිට ජංගම බාර දීම"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi රෝම් පරිලෝකන වෙතට සැමවිට අවසර දෙන්න"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ජංගම දත්ත සැමවිට ක්‍රියාකාරීය"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ටෙදරින් දෘඪාංග ත්වරණය"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"නිරපේක්ෂ හඩ පරිමාව අබල කරන්න"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"කලාපය තුළ නාද වීම සබල කරන්න"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"බ්ලූටූත් AVRCP අනුවාදය"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"ව්‍යාජ ස්ථාන අනුමත කරන්න"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"උපලක්ෂණ පරික්ෂාව බැලීම සබල කරන්න"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi‑Fi අක්‍රිය විට පවා, සැම විටම ජංගම දත්ත ක්‍රියාකාරීව තබන්න (අවසන් ජාල මාරුව සඳහා)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ලබා ගත හැකි නම්, ටෙදරින් දෘඪාංග ත්වරණය භාවිත කරන්න"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB දෝශාවේක්ෂණයට ඉඩ දෙන්නද?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB දෝශාවේක්ෂණය සංවර්ධන කටයුතු සඳහා පමණක් යොදාගැනේ. එය ඔබගේ පරිගණකය සහ ඔබගේ උපාංගය අතර දත්ත පිටපත් කිරීමට පමණක් භාවිතා කරන්න, ඔබගේ උපාංගය මත දැනුම්දීම් රහිතව යෙදුම් ස්ථාපනය කරන්න, සහ ලොග් දත්ත කියවන්න."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"ඔබ මින්පෙර අවසර ලබාදුන් සියළුම පරිගණක වෙතින් USB නිදොස්කරණට ප්‍රවේශය අහෝසි කරන්නද?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"වර්ණ නිවැරදි කිරීම"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"මෙම විශේෂාංගය පරීක්ෂණාත්මක සහ ඇතැම් විට ක්‍රියාකාරිත්වයට බලපෑ හැක."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> මගින් ඉක්මවන ලදී"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"<xliff:g id="TIME">%1$s</xliff:g> පමණ ඉතිරියි"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"පූර්ණව ආරෝපණය වන තෙක් <xliff:g id="TIME">%1$s</xliff:g> ඉතිරියි"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"ඉතිරි <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>ක් පමණ ඇත"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - ඉතිරි <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"<xliff:g id="TIME">^1</xliff:g> පමණ ඉතිරියි"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"ඔබගේ භාවිතය මත පදනම්ව <xliff:g id="TIME">^1</xliff:g> පමණ ඉතිරිව ඇත"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"පූර්ණව ආරෝපණය වන තෙක් <xliff:g id="TIME">^1</xliff:g> ඉතිරියි"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"ඉතිරි <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"ඔබගේ භාවිතය මත පදනම්ව <xliff:g id="TIME">^1</xliff:g> ඉතිරිව ඇත"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>ක් පමණ ඇත"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - ඔබගේ භාවිතය මත පදනම්ව <xliff:g id="TIME">^2</xliff:g> පමණ ඉතිරිව ඇත"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - ඉතිරි <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පූර්ණයෙන් ආරෝපණය වන තෙක්"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> සම්පූර්ණයෙන් ආරෝපණය වන තෙක්"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"නොදනී"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"ආරෝපණය වෙමින්"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ආරෝපණය වේ"</string>
@@ -340,7 +358,7 @@
     <string name="disabled" msgid="9206776641295849915">"අබල කර ඇත"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"ඉඩ දුන්"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"ඉඩ නොදෙන"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"නොදන්නා යෙදුම් ස්ථාපනය කරන්න"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"නොදන්නා යෙදුම් ස්ථාප."</string>
     <string name="home" msgid="3256884684164448244">"සැකසීම් මුල් පිටුව"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-sk/arrays.xml b/packages/SettingsLib/res/values-sk/arrays.xml
index b7ac435..e2005ba2 100644
--- a/packages/SettingsLib/res/values-sk/arrays.xml
+++ b/packages/SettingsLib/res/values-sk/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (predvolené)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Použiť voľbu systému (predvolené)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Povoliť voliteľné kodeky"</item>
-    <item msgid="3304843301758635896">"Zakázať voliteľné kodeky"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Použiť voľbu systému (predvolené)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Povoliť voliteľné kodeky"</item>
-    <item msgid="741805482892725657">"Zakázať voliteľné kodeky"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Použiť voľbu systému (predvolené)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
@@ -245,7 +231,7 @@
     <item msgid="7899496259191969307">"Najviac 4 procesy"</item>
   </string-array>
   <string-array name="usb_configuration_titles">
-    <item msgid="488237561639712799">"Nabíjanie"</item>
+    <item msgid="488237561639712799">"Nabíja sa"</item>
     <item msgid="5220695614993094977">"MTP (Media Transfer Protocol – protokol na prenos médií)"</item>
     <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol – protokol na prenos obrázkov)"</item>
     <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 89f0b1c..c97448f 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -23,11 +23,14 @@
     <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Siete sa nedajú vyhľadávať"</string>
     <string name="wifi_security_none" msgid="7985461072596594400">"Žiadne"</string>
     <string name="wifi_remembered" msgid="4955746899347821096">"Uložené"</string>
-    <string name="wifi_disabled_generic" msgid="4259794910584943386">"Zakázané"</string>
+    <string name="wifi_disabled_generic" msgid="4259794910584943386">"Vypnuté"</string>
     <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Zlyhanie konfigurácie adresy IP"</string>
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Nepripojené z dôvodu siete nízkej kvality"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Zlyhanie pripojenia Wi-Fi"</string>
+    <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Zlyhanie pripojenia Wi‑Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problém s overením totožnosti"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Nedá sa pripojiť"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"K sieti <xliff:g id="AP_NAME">%1$s</xliff:g> sa nedá pripojiť"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Skontrolujte heslo a skúste to znova"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Mimo dosah"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nedôjde k automatickému pripojeniu"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Žiadny prístup k internetu"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Pripojené prostredníctvom %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"K dispozícii prostredníctvom %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Pripojené, žiadny internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Veľmi nízka"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Nízka"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Stredná"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Vysoká"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Veľmi vysoká"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Odpojený"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Prebieha odpájanie..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Prebieha pripájanie…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Pripojené (bez média)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Pripojené (bez prístupu ku správam)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Pripojené (bez telefónu alebo média)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Pripojené, stav batérie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Pripojené (žiadny telefón), stav batérie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Pripojené (žiadne médiá), stav batérie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Pripojené (žiadny telefón ani médiá), stav batérie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk medií"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Zvuk telefónu"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonické hovory"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prenos súborov"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Vstupné zariadenie"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Prístup na Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Zdieľanie kontaktov"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Použiť na zdieľanie kontaktov"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Zdieľanie pripojenia na Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Prístup ku správam"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Textové správy"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Prístup k SIM karte"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Použiť zvuk s vysokou kvalitou: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Použiť zvuk s vysokou kvalitou"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD zvuk: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD zvuk"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Pripojené ku zvukovému médiu"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Pripojené ku zvuku telefónu"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Pripojené na server pre prenos údajov"</string>
@@ -82,12 +95,12 @@
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Nepodarilo sa spárovať so zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, pretože ste zadali nesprávny kód PIN alebo prístupový kľúč."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"So zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nie je možné komunikovať."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Párovanie odmietnuté zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="accessibility_wifi_off" msgid="1166761729660614716">"Sieť Wi-Fi je vypnutá."</string>
-    <string name="accessibility_no_wifi" msgid="8834610636137374508">"Sieť Wi-Fi je odpojená."</string>
-    <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Jedna čiarka signálu Wi-Fi."</string>
-    <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Dve čiarky signálu Wi-Fi."</string>
-    <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Tri čiarky signálu Wi-Fi."</string>
-    <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Plný signál Wi-Fi."</string>
+    <string name="accessibility_wifi_off" msgid="1166761729660614716">"Sieť Wi‑Fi je vypnutá."</string>
+    <string name="accessibility_no_wifi" msgid="8834610636137374508">"Sieť Wi‑Fi je odpojená."</string>
+    <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Jedna čiarka signálu Wi‑Fi."</string>
+    <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Dve čiarky signálu Wi‑Fi."</string>
+    <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Tri čiarky signálu Wi‑Fi."</string>
+    <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Plný signál Wi‑Fi."</string>
     <string name="process_kernel_label" msgid="3916858646836739323">"OS Android"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Odstránené aplikácie"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Odstránené aplikácie a používatelia"</string>
@@ -100,7 +113,7 @@
     <string name="user_guest" msgid="8475274842845401871">"Hosť"</string>
     <string name="unknown" msgid="1592123443519355854">"Neznáme"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"Používateľ: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
-    <string name="launch_defaults_some" msgid="313159469856372621">"Predvolená pre niektoré akcie"</string>
+    <string name="launch_defaults_some" msgid="313159469856372621">"Pre niektoré akcie"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"Nie je predvolená pre žiadne akcie"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Nastavenia prevodu textu na reč"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"Prevod textu na reč"</string>
@@ -169,10 +182,11 @@
     <string name="mock_location_app_set" msgid="8966420655295102685">"Aplikácia so simulovanou polohou: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="debug_networking_category" msgid="7044075693643009662">"Siete"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikácia bezdrôtového zobrazenia"</string>
-    <string name="wifi_verbose_logging" msgid="4203729756047242344">"Podrobné denníky Wi-Fi"</string>
-    <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agres. odovzdávať Wi-Fi na mobilnú sieť"</string>
-    <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vždy povoliť funkciu Wi-Fi Roam Scans"</string>
+    <string name="wifi_verbose_logging" msgid="4203729756047242344">"Podrobné denníky Wi‑Fi"</string>
+    <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agres. odovzdávať Wi‑Fi na mobilnú sieť"</string>
+    <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vždy povoliť funkciu Wi‑Fi Roam Scans"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilné dáta ponechať vždy aktívne"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardvérovú akcelerácia pre tethering"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zakázať absolútnu hlasitosť"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Povoliť zvonenie v hovorovom pásme"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verzia rozhrania Bluetooth AVRCP"</string>
@@ -189,8 +203,8 @@
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Vybrať kodek LDAC Bluetooth Audio:\nKvalita prehrávania"</string>
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streamovanie: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobraziť možnosti certifikácie bezdrôtového zobrazenia"</string>
-    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšiť úroveň denníkov Wi-Fi, zobrazovať podľa SSID RSSI pri výbere siete Wi-Fi"</string>
-    <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Keď túto možnosť zapnete, Wi-Fi bude agresívnejšie odovzdávať dátové pripojenie na mobilnú sieť vtedy, keď bude slabý signál Wi-Fi"</string>
+    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšiť úroveň denníkov Wi‑Fi, zobrazovať podľa SSID RSSI pri výbere siete Wi‑Fi"</string>
+    <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Keď túto možnosť zapnete, Wi‑Fi bude agresívnejšie odovzdávať dátové pripojenie na mobilnú sieť vtedy, keď bude slabý signál Wi‑Fi"</string>
     <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Povoliť alebo zakázať funkciu Wifi Roam Scans na základe objemu prenosu údajov v rozhraní"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Vyrovnávacia pamäť nástroja denníkov"</string>
     <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Veľkosť vyrovnávacej pamäte nástroja denníkov"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Povoliť simulované polohy"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Kontrola atribútov zobrazenia"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Vždy ponechávať mobilné dáta aktívne, dokonca aj pri aktívnej sieti Wi‑Fi (na rýchle prepínanie sietí)"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Používať hardvérovú akceleráciu pre tethering (ak je k dispozícii)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Povoliť ladenie cez USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Ladenie cez USB je určené iba na účely vývoja. Možno ho použiť na kopírovanie dát medzi počítačom a zariadením, inštaláciu aplikácií do zariadenia bez upozornenia a čítanie dát denníka."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Chcete všetkým v minulosti autorizovaným počítačom odvolať prístup k ladeniu cez USB?"</string>
@@ -312,7 +327,7 @@
     <string name="button_convert_fbe" msgid="5152671181309826405">"Vymazať a konvertovať…"</string>
     <string name="picture_color_mode" msgid="4560755008730283695">"Farebný režim obrázka"</string>
     <string name="picture_color_mode_desc" msgid="1141891467675548590">"Použije sa sRGB"</string>
-    <string name="daltonizer_mode_disabled" msgid="7482661936053801862">"Zakázané"</string>
+    <string name="daltonizer_mode_disabled" msgid="7482661936053801862">"Vypnuté"</string>
     <string name="daltonizer_mode_monochromacy" msgid="8485709880666106721">"Monochromázia (úplna farbosleposť)"</string>
     <string name="daltonizer_mode_deuteranomaly" msgid="5475532989673586329">"Deuteranomália (červená a zelená)"</string>
     <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"Protanomália (červená a zelená)"</string>
@@ -320,24 +335,27 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Úprava farieb"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Funkcia je experimentálna a môže mať vplyv na výkonnosť."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Prekonané predvoľbou <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Približný zostávajúci čas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Zostávajúci čas do úplného nabitia: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zostávajúci čas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – približný zostávajúci čas: <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostávajúci čas: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Približný zostávajúci čas: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Zostáva približne <xliff:g id="TIME">^1</xliff:g> v závislosti od intenzity využitia"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Zostávajúci čas do úplného nabitia: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zostávajúci čas: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Zostáva <xliff:g id="TIME">^1</xliff:g> v závislosti od intenzity využitia"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – približný zostávajúci čas: <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – zostáva približne <xliff:g id="TIME">^2</xliff:g> v závislosti od intenzity využitia"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – zostávajúci čas: <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> do úplného nabitia"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Neznáme"</string>
-    <string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjanie"</string>
-    <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"nabíjanie"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíja sa"</string>
+    <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"nabíja sa"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"Nenabíja sa"</string>
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíja sa"</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">"Zakázané"</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>
     <string name="install_other_apps" msgid="6986686991775883017">"Inštalácia neznámych aplikácií"</string>
diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml
index 5ffdd17..40ec134 100644
--- a/packages/SettingsLib/res/values-sl/arrays.xml
+++ b/packages/SettingsLib/res/values-sl/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (privzeto)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Uporabi sistemsko izbiro (privzeto)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Omogoči izbirne kodeke"</item>
-    <item msgid="3304843301758635896">"Onemogoči izbirne kodeke"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Uporabi sistemsko izbiro (privzeto)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Omogoči izbirne kodeke"</item>
-    <item msgid="741805482892725657">"Onemogoči izbirne kodeke"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Uporabi sistemsko izbiro (privzeto)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 6cc5904..28f2af6 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Ni povezano zaradi slabe kakovosti omrežja"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Povezava prek Wi-Fi-ja ni uspela"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Težava s preverjanjem pristnosti"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Povezava ni mogoča"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Povezava z aplikacijo »<xliff:g id="AP_NAME">%1$s</xliff:g>« ni mogoča"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Preverite geslo in poskusite znova"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Ni v obsegu"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Samodejna vnovična vzpostavitev povezave se ne bo izvedla"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Ni dostopa do interneta"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Vzpostavljena povezava prek: %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Na voljo prek: %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Vzpostavljena povezava, brez interneta"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Zelo počasna"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Počasna"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"V redu"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Srednje hitra"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Hitra"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Zelo hitra"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Prekinjena povezava"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Prekinjanje povezave ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Vzpostavljanje povezave ..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Povezava vzpostavljena (brez predstavnosti)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Povezava vzp. (ni dostopa do sporočil)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Povezava vzpostavljena (brez telefona ali predstavnosti)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Povezava je vzpostavljena, raven napolnjenosti akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Povezava je vzpostavljena (brez telefona), raven napolnjenosti akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Povezava je vzpostavljena (brez predstavnosti), raven napolnjenosti akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Povezava je vzpostavljena (brez telefona ali predstavnosti), raven napolnjenosti akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvok predstavnosti"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Zvok telefona"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonski klici"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prenos datoteke"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Vnosna naprava"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetni dostop"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Dajanje stikov v skupno rabo"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Uporabi za dajanje stikov v skupno rabo"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Skupna raba internetne povezave"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Dostop do sporočil"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Sporočila SMS"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Dostop do kartice SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Uporabi zvok visoke kakovosti: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Uporabi zvok visoke kakovosti"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Zvok visoke kakovosti: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Zvok visoke kakovosti"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Povezan s profilom za predstavnostni zvok"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Povezava s profilom za zvok telefona vzpostavljena"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Povezava s strežnikom za prenos datotek je vzpostavljena"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Odločen prehod iz Wi-Fi-ja v mobil. omr."</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vedno omogoči iskanje omrežij Wi-Fi za gostovanje"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Prenos podatkov v mobilnem omrežju je vedno aktiven"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Strojno pospeševanje za internetno povezavo prek mobilnega telefona"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogočanje absolutnega praga glasnosti"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Omogoči zvonjenje iz telefona"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Različica profila AVRCP za Bluetooth"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Dovoli lažne lokacije"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Omogoči pregled atributa pogleda"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Prenos podatkov v mobilnih omrežjih je vedno aktiven – tudi ko je aktivna povezava Wi-Fi (za hiter preklop med omrežji)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Uporabi strojno pospeševanje za internetno povezavo prek mobilnega telefona, če je na voljo"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Ali dovolite odpravljanje težav s povezavo USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Odpravljanje težav s povezavo USB je namenjeno samo za razvoj. Lahko ga uporabljate za kopiranje podatkov med računalnikom in napravo, nameščanje aplikacij v napravo brez obveščanja in branje podatkov v dnevniku."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Ali želite preklicati dostop do odpravljanja težav prek povezave USB iz vseh računalnikov, ki ste jih pooblastili?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Popravljanje barv"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"To je preskusna funkcija in lahko vpliva na učinkovitost delovanja."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Preglasila nastavitev: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Še približno <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Še <xliff:g id="TIME">%1$s</xliff:g> do polne napolnjenosti"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Še <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – še približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – še <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Še približno <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Glede na način uporabe imate na voljo še približno <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Še <xliff:g id="TIME">^1</xliff:g> do polne napolnjenosti"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Še <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Glede na način uporabe imate na voljo še <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – še približno <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – glede na način uporabe imate na voljo še približno <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – še <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> do napolnjenosti"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Neznano"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Polnjenje"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"polnjenje"</string>
@@ -339,7 +357,7 @@
     <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">"Nedovoljene"</string>
+    <string name="external_source_untrusted" msgid="2677442511837596726">"Ni dovoljeno"</string>
     <string name="install_other_apps" msgid="6986686991775883017">"Nameščanje neznanih aplikacij"</string>
     <string name="home" msgid="3256884684164448244">"Začetna stran nastavitev"</string>
   <string-array name="battery_labels">
diff --git a/packages/SettingsLib/res/values-sq/arrays.xml b/packages/SettingsLib/res/values-sq/arrays.xml
index 3db4250..46a7ae9 100644
--- a/packages/SettingsLib/res/values-sq/arrays.xml
+++ b/packages/SettingsLib/res/values-sq/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (I parazgjedhur)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Përdor përzgjedhjen e sistemit (e parazgjedhur)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Aktivizo kodekët opsionalë"</item>
-    <item msgid="3304843301758635896">"Çaktivizo kodekët opsionalë"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Përdor përzgjedhjen e sistemit (e parazgjedhur)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Aktivizo kodekët opsionalë"</item>
-    <item msgid="741805482892725657">"Çaktivizo kodekët opsionalë"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Përdor përzgjedhjen e sistemit (e parazgjedhur)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 33fa56f..34d0333 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Nuk është lidhur për shkak të rrjetit me cilësi të dobët"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Dështim i lidhjes WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problem me vërtetimin"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Nuk mund të lidhet"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Nuk mund të lidhet me \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Kontrollo fjalëkalimin dhe provo sërish"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Nuk është brenda rrezes"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nuk do të lidhet automatikisht"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Nuk ka qsaje në internet"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"E lidhur përmes %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"E mundshme përmes %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"U lidh, nuk ka internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Shumë e ulët"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"E ngadaltë"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Në rregull"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Mesatare"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"E shpejtë"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Shumë e shpejtë"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Shkëputur"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Po shkëputet..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Po lidhet..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"U lidh (nuk ka media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"U lidh (pa qasje te mesazhet)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"I lidhur (pa telefon apo media)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"E lidhur, bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"E lidhur (nuk ka telefon), bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"E lidhur (nuk ka media), bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"E lidhur (nuk ka telefon ose media), bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audioja e klipit \"media\""</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audioja e telefonit"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonatat"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferimi i skedarëve"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Pajisja e hyrjes"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Qasja në internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Ndarja e kontakteve"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Përdore për ndarjen e kontakteve"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Ndarja e lidhjes së internetit"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Qasja në mesazhe"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Mesazhet me tekst"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Qasje në kartën SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Përdor audion me cilësi të lartë: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Përdor audion me cilësi të lartë"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"U lidh me audion e medias"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"U lidh me audion e telefonit"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"U lidh me serverin e transferimit të skedarëve"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Dorëzimi agresiv i Wi‑Fi te rrjeti celular"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Lejo gjithmonë skanimet për Wi-Fi edhe kur je në lëvizje"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Të dhënat celulare gjithmonë aktive"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Përshpejtimi i harduerit për ndarjen"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Çaktivizo volumin absolut"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Aktivizo zilen brenda të njëjtit brez"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versioni AVRCP i Bluetooth-it"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Lejo vendndodhje të simuluara"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Aktivizo shikimin e inspektimit të atributeve"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mbaji të dhënat celulare gjithmonë aktive edhe kur Wi‑Fi është aktiv (për ndërrim të shpejtë të rrjetit)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Përdor përshpejtimin e harduerit për ndarjen nëse është i disponueshëm"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Të lejohet korrigjimi i USB-së?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Korrigjuesi i USB-së është vetëm për qëllime zhvillimore. Përdore për të kopjuar të dhëna mes kompjuterit dhe pajisjes tënde, për të instaluar aplikacione në pajisjen tënde pa asnjë njoftim si dhe për të lexuar të dhënat e ditarit."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Të bllokohet qasja për korrigjim të USB-së nga të gjithë kompjuterët që ke autorizuar më parë?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korrigjimi i ngjyrës"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ky funksion është eksperimental dhe mund të ndikojë në veprimtari."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Mbivendosur nga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Rreth <xliff:g id="TIME">%1$s</xliff:g> të mbetura"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura deri në ngarkimin e plotë"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - rreth <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Rreth <xliff:g id="TIME">^1</xliff:g> të mbetura"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Rreth <xliff:g id="TIME">^1</xliff:g> të mbetura bazuar në përdorimin tënd"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> të mbetura deri në ngarkimin e plotë"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> të mbetura"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> të mbetura bazuar në përdorimin tënd"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - rreth <xliff:g id="TIME">^2</xliff:g> të mbetura"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - rreth <xliff:g id="TIME">^2</xliff:g> të mbetura bazuar në përdorimin tënd"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> të mbetura"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të mbushet plotësisht"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> derisa të mbushet plotësisht"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"I panjohur"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Po ngarkohet"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"po ngarkohet"</string>
diff --git a/packages/SettingsLib/res/values-sr/arrays.xml b/packages/SettingsLib/res/values-sr/arrays.xml
index ef1c9de..f097b01 100644
--- a/packages/SettingsLib/res/values-sr/arrays.xml
+++ b/packages/SettingsLib/res/values-sr/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (подразумевано)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Користи избор система (подразумевано)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Омогући опционалне кодеке"</item>
-    <item msgid="3304843301758635896">"Онемогући опционалне кодеке"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Користи избор система (подразумевано)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Омогући опционалне кодеке"</item>
-    <item msgid="741805482892725657">"Онемогући опционалне кодеке"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Користи избор система (подразумевано)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index e7dfc4c..2b21d30 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Није повезано због лошег квалитета мреже"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi веза је отказала"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Проблем са потврдом аутентичности"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Повезивање није успело"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Повезивање са „<xliff:g id="AP_NAME">%1$s</xliff:g>“ није успело"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Проверите лозинку и пробајте поново"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Није у опсегу"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Аутоматско повезивање није успело"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Нема приступа интернету"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Веза је успостављена преко приступне тачке %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Доступна је преко приступне тачке %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Веза је успостављена, нема интернета"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Веома спора"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Спора"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Потврди"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Средња"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Брза"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Веома брза"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Веза је прекинута"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Прекидање везе..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Повезивање…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Повезано (без медија)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Повезано је (нема приступа порукама)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Повезано (без телефона или медија)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Повезано, ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Повезано (без телефона), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Повезано (без медија), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Повезано (без телефона или медија), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Звук медија"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Звук телефона"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефонски позиви"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Пренос датотеке"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Улазни уређај"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Приступ Интернету"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Дељење контаката"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Користите за дељење контаката"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Дељење интернет везе"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Приступ порукама"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"SMS-ови"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Приступ SIM картици"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Користи звук високог квалитета: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Користи звук високог квалитета"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD звук: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD звук"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Повезано са звуком медија"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Повезано са звуком телефона"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Повезано са сервером за пренос датотека"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Агресиван прелаз са Wi‑Fi мреже на мобилну"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Увек дозволи скенирање Wi‑Fi-ја у ромингу"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилни подаци су увек активни"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардверско убрзање привезивања"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Онемогући главно подешавање јачине звука"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Омогућавање звоњаве на истом каналу"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Верзија Bluetooth AVRCP-а"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Дозволи лажне локације"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Омогући проверу атрибута за преглед"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Нека мобилни подаци увек буду активни, чак и када је Wi‑Fi активан (ради брзе промене мреже)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Користи хардверско убрзање привезивања ако је доступно"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Дозволи отклањање USB грешака?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Отклањање USB грешака намењено је само за сврхе програмирања. Користите га за копирање података са рачунара на уређај и обрнуто, инсталирање апликација на уређају без обавештења и читање података из евиденције."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Желите ли да опозовете приступ отклањању USB грешака са свих рачунара које сте претходно одобрили?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекција боја"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ова функција је експериментална и може да утиче на квалитет рада."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замењује га <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Још око <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> до потпуног пуњења"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Преостало време: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – остало је око <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"Преостало је <xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Још око <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"На основу потрошње имате још отприлике <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> до потпуног пуњења"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Преостало време: <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"На основу потрошње имате још <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – остало је око <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – на основу потрошње имате још отприлике <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"Преостало је <xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до потпуног пуњења"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> до потпуног пуњења"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Непознато"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Пуњење"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"пуни се"</string>
diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml
index 23bb797..37cb084 100644
--- a/packages/SettingsLib/res/values-sv/arrays.xml
+++ b/packages/SettingsLib/res/values-sv/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (standard)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Använd systemval (standardinställning)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Aktivera valfria kodekar"</item>
-    <item msgid="3304843301758635896">"Inaktivera valfria kodekar"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Använd systemval (standardinställning)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Aktivera valfria kodekar"</item>
-    <item msgid="741805482892725657">"Inaktivera valfria kodekar"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Använd systemval (standardinställning)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
@@ -171,31 +157,31 @@
     <item msgid="8489661142527693381">"endast buffert av kernellogg"</item>
   </string-array>
   <string-array name="window_animation_scale_entries">
-    <item msgid="8134156599370824081">"Animering avstängd"</item>
-    <item msgid="6624864048416710414">"Animering i skala 0,5x"</item>
-    <item msgid="2219332261255416635">"Animering i skala 1x"</item>
-    <item msgid="3544428804137048509">"Animering i skala 1,5x"</item>
-    <item msgid="3110710404225974514">"Animering i skala 2x"</item>
-    <item msgid="4402738611528318731">"Animering i skala 5x"</item>
-    <item msgid="6189539267968330656">"Animering i skala 10x"</item>
+    <item msgid="8134156599370824081">"Animation avstängd"</item>
+    <item msgid="6624864048416710414">"Animation i skala 0,5x"</item>
+    <item msgid="2219332261255416635">"Animation i skala 1x"</item>
+    <item msgid="3544428804137048509">"Animation i skala 1,5x"</item>
+    <item msgid="3110710404225974514">"Animation i skala 2x"</item>
+    <item msgid="4402738611528318731">"Animation i skala 5x"</item>
+    <item msgid="6189539267968330656">"Animation i skala 10x"</item>
   </string-array>
   <string-array name="transition_animation_scale_entries">
-    <item msgid="8464255836173039442">"Animering avstängd"</item>
-    <item msgid="3375781541913316411">"Animering i skala 0,5x"</item>
-    <item msgid="1991041427801869945">"Animering i skala 1x"</item>
-    <item msgid="4012689927622382874">"Animering i skala 1,5x"</item>
-    <item msgid="3289156759925947169">"Animering i skala 2x"</item>
-    <item msgid="7705857441213621835">"Animering i skala 5x"</item>
-    <item msgid="6660750935954853365">"Animering i skala 10x"</item>
+    <item msgid="8464255836173039442">"Animation avstängd"</item>
+    <item msgid="3375781541913316411">"Animation i skala 0,5x"</item>
+    <item msgid="1991041427801869945">"Animation i skala 1x"</item>
+    <item msgid="4012689927622382874">"Animation i skala 1,5x"</item>
+    <item msgid="3289156759925947169">"Animation i skala 2x"</item>
+    <item msgid="7705857441213621835">"Animation i skala 5x"</item>
+    <item msgid="6660750935954853365">"Animation i skala 10x"</item>
   </string-array>
   <string-array name="animator_duration_scale_entries">
-    <item msgid="6039901060648228241">"Animering avstängd"</item>
-    <item msgid="1138649021950863198">"Animering i skala 0,5x"</item>
-    <item msgid="4394388961370833040">"Animering i skala 1x"</item>
-    <item msgid="8125427921655194973">"Animering i skala 1,5x"</item>
-    <item msgid="3334024790739189573">"Animering i skala 2x"</item>
-    <item msgid="3170120558236848008">"Animering i skala 5x"</item>
-    <item msgid="1069584980746680398">"Animering i skala 10x"</item>
+    <item msgid="6039901060648228241">"Animation avstängd"</item>
+    <item msgid="1138649021950863198">"Animation i skala 0,5x"</item>
+    <item msgid="4394388961370833040">"Animation i skala 1x"</item>
+    <item msgid="8125427921655194973">"Animation i skala 1,5x"</item>
+    <item msgid="3334024790739189573">"Animation i skala 2x"</item>
+    <item msgid="3170120558236848008">"Animation i skala 5x"</item>
+    <item msgid="1069584980746680398">"Animation i skala 10x"</item>
   </string-array>
   <string-array name="overlay_display_devices_entries">
     <item msgid="1606809880904982133">"Inga"</item>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index e5fa8cb..172a7d1 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Ingen anslutning på grund av låg kvalitet på nätverket"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi-anslutningsfel"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Autentiseringsproblem"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Det gick inte att ansluta"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Det gick inte att ansluta till <xliff:g id="AP_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Kontrollera lösenordet och försök igen"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Utom räckhåll"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Det går inte att ansluta automatiskt"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Ingen internetåtkomst"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Anslutet via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Tillgängligt via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Ansluten, inget internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Mycket långsam"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Långsam"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Okej"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Medelsnabb"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Snabb"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Mycket snabb"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Kopplas ifrån"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Kopplar ifrån…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Ansluter…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Ansluten (inga media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Ansluten (ingen meddelandeåtkomst)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Ansluten (ingen telefon och inga media)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Ansluten, batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Ansluten (ingen mobil), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Ansluten (inga medier), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Ansluten (ingen mobil och inga medier), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medialjud"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefonljud"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonsamtal"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Filöverföring"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Indataenhet"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetåtkomst"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktdelning"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Använd för kontaktdelning"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Delning av Internetanslutning"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Meddelandeåtkomst"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Sms"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-åtkomst"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Använd högkvalitativt ljud: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Använd högkvalitativt ljud"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-ljud: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-ljud"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Ansluten till medialjud"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Ansluten till telefonens ljud"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Ansluten till filöverföringsserver"</string>
@@ -75,7 +88,7 @@
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Använd för filöverföring"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Använd för inmatning"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Parkoppling"</string>
-    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"KOPPLA"</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"PARKOPPLA"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Avbryt"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Om du kopplar enheten får du tillgång till dina kontakter och din samtalshistorik när du är ansluten."</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Det gick inte att koppla till <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
@@ -92,10 +105,10 @@
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Borttagna appar"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Borttagna appar och användare"</string>
     <string name="tether_settings_title_usb" msgid="6688416425801386511">"Internetdelning via USB"</string>
-    <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Mobil surfpunkt"</string>
+    <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Mobil surfzon"</string>
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Delning via Bluetooth"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Internetdelning"</string>
-    <string name="tether_settings_title_all" msgid="8356136101061143841">"Internetdelning och surfpunkt"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"Internetdelning och surfzon"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"Alla jobbappar"</string>
     <string name="user_guest" msgid="8475274842845401871">"Gäst"</string>
     <string name="unknown" msgid="1592123443519355854">"Okänd"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressiv överlämning fr. Wi-Fi t. mobil"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillåt alltid sökning efter Wi-Fi-roaming"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata alltid aktiverad"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Maskinvaruacceleration för internetdelning"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inaktivera Absolute volume"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Aktivera samtal inom nätverket"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"AVRCP-version för Bluetooth"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Tillåt skenplatser"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Aktivera inspektion av visningsattribut"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Håll alltid mobildata aktiverad, även när Wi-Fi är aktiverat (så att du snabbt kan byta mellan nätverk)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Använd maskinvaruacceleration för internetdelning om tillgängligt"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Ska USB-felsökning tillåtas?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-felsökning ska endast användas i utvecklingssyfte. Använd den för att kopiera data mellan datorn och enheten, installera appar på enheten utan meddelanden och läsa loggdata."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vill du återkalla åtkomst till USB-felsökning för alla datorer som du tidigare har godkänt?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Färgkorrigering"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Den här funktionen är experimentell och kan påverka prestandan."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Har åsidosatts av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Cirka <xliff:g id="TIME">%1$s</xliff:g> återstår"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Batteriet är fulladdat om <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> kvar"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – cirka <xliff:g id="TIME">%2$s</xliff:g> kvar"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kvar"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Cirka <xliff:g id="TIME">^1</xliff:g> återstår"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Cirka <xliff:g id="TIME">^1</xliff:g> kvar utifrån din användning"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Batteriet är fulladdat om <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> kvar"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> kvar utifrån din användning"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – cirka <xliff:g id="TIME">^2</xliff:g> kvar"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – cirka <xliff:g id="TIME">^2</xliff:g> kvar utifrån din användning"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> kvar"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tills det är fulladdat"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> tills det är fulladdat"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Okänd"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Laddar"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"laddas"</string>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index b5953a3..53d003d 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Chaguo-msingi)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Tumia Uteuzi wa Mfumo (Chaguo-msingi)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Washa Kodeki Zisizo za Lazima"</item>
-    <item msgid="3304843301758635896">"Zima Kodeki Zisizo za Lazima"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Tumia Uteuzi wa Mfumo (Chaguo-msingi)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Washa Kodeki Zisizo za Lazima"</item>
-    <item msgid="741805482892725657">"Zima Kodeki Zisizo za Lazima"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Tumia Uteuzi wa Mfumo (Chaguo-msingi)"</item>
     <item msgid="8895532488906185219">"kHz 44.1"</item>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 7330572..1818118 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Haijaunganishwa kwa sababu intaneti si thabiti"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Haikuweza Kuunganisha kwenye WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Tatizo la uthibitishaji"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Imeshindwa kuunganisha"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Imeshindwa kuunganisha kwenye \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Angalia nenosiri na ujaribu tena"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Haiko karibu"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Haiwezi kuunganisha kiotomatiki"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Hakuna muunganisho wa Intaneti"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Imeunganishwa kupitia %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Inapatikana kupitia %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Imeunganishwa, hakuna Intaneti"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Polepole Sana"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Polepole"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Sawa"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Wastani"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Haraka"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Haraka Sana"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Haijaunganishwa"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Inatenganisha..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Inaunganisha…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Imeunganishwa(hakuna vyombo vya habari)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Imeunganishwa (hakuna ufikiaji kwa ujumbe)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Imeunganishwa(hakuna simu au vyombo vya habari)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Imeunganishwa, kiwango cha betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Imeunganishwa (hakuna simu), kiwango cha betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Imeunganishwa (hakuna maudhui), kiwango cha betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Imeunganishwa (hakuna simu wala maudhui), kiwango cha betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media ya sauti"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Sauti ya simu"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Simu"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Uhamishaji wa faili"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Kifaa cha kuingiza"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Ufikivu wa mtandao"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kushiriki anwani"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Tumia kwa kushiriki anwani"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Kushiriki muunganisho wa tovuti"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Ufikiaji wa Ujumbe"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"SMS"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Ufikiaji wa SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Tumia sauti ya ubora wa juu: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Tumia sauti ya ubora wa juu"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Sauti ya HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Sauti ya HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Imeunganishwa kwenye sikika ya njia ya mawasiliano"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Imeunganishwa kwenye sauti ya simu"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Imeunganishwa kwenye seva ya kuhamisha faili"</string>
@@ -103,7 +116,7 @@
     <string name="launch_defaults_some" msgid="313159469856372621">"Baadhi ya chaguo-msingi zimewekwa"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"Hakuna chaguo-misingi zilizowekwa"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Mipangilio ya kusoma maandishi kwa sauti"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"Kipengele cha kusoma maandishi kwa sauti"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"Kusoma maandishi kwa sauti"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Kasi ya kutamka"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"Kasi ya kutamkwa kwa maneno"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"Uzito wa sauti"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Ukabidhi hima kutoka Wifi kwenda mtandao wa simu"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Ruhusu Uchanganuzi wa Matumizi ya Mitandao mingine"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Iendelee kutumia data ya simu"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Kuongeza kasi kwa kutumia maunzi ili kusambaza mtandao"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zima sauti kamili"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Washa kipengele cha mlio wa simu katika kituo hicho hicho"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Toleo la Bluetooth AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Ruhusu maeneo ya majaribio"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Washa ukaguzi wa sifa ya onyesho"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Washa kila wakati data ya kifaa cha mkononi, hata kama Wi-Fi inatumika (katika uzimaji wa haraka wa mtandao)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Tumia huduma ya kuongeza kasi kwa kutumia maunzi ili kusambaza mtandao ikiwa inapatikana"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Ruhusu utatuaji USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Ueuaji wa USB umekusudiwa kwa malengo ya utengenezaji tu. Itumi kunakili data kati ya kompyuta yako na kifaa chako, kusanidi programu kwa kifaa chako bila arifa, na kusoma data ya rajisi."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Unataka kubatilisha ufikiaji wa urekebishaji wa USB kutoka kwenye kompyuta zote ulizotangulia kuidhinisha?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Usahihishaji wa rangi"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Kipengele hiki ni cha majaribio na huenda kikaathiri utendaji wa kifaa chako."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Imetanguliwa na <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Zimesalia takribani <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Imebaki <xliff:g id="TIME">%1$s</xliff:g> chaji ijae"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zimesalia <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia takribani <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"Imechaji <xliff:g id="LEVEL">%1$s</xliff:g> - Zimesalia <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Zimesalia takribani <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Takriban <xliff:g id="TIME">^1</xliff:g> zimesalia kulingana na matumizi yako"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Imebaki <xliff:g id="TIME">^1</xliff:g> chaji ijae"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zimesalia <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> zimesalia kulingana na matumizi yako"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - imesalia takribani <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - takriban <xliff:g id="TIME">^2</xliff:g> zimesalia kulingana na matumizi yako"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"Imechaji <xliff:g id="LEVEL">^1</xliff:g> - Zimesalia <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hadi ijae chaji"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> hadi ijae chaji"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Haijulikani"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Inachaji"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"inachaji"</string>
@@ -340,7 +358,7 @@
     <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>
-    <string name="install_other_apps" msgid="6986686991775883017">"Sakinisha programu ambazo hazijulikani"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"Kuweka programu zisizojulikana"</string>
     <string name="home" msgid="3256884684164448244">"Ukurasa wa Kwanza wa Mipangilio"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ta/arrays.xml b/packages/SettingsLib/res/values-ta/arrays.xml
index 96c9122..61ff58a 100644
--- a/packages/SettingsLib/res/values-ta/arrays.xml
+++ b/packages/SettingsLib/res/values-ta/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (இயல்பு)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"சாதனத் தேர்வைப் பயன்படுத்து (இயல்பு)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"கட்டாயமில்லா கோடெக்குகளை இயக்கு"</item>
-    <item msgid="3304843301758635896">"கட்டாயமில்லா கோடெக்குகளை முடக்கு"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"சாதனத் தேர்வைப் பயன்படுத்து (இயல்பு)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"கட்டாயமில்லா கோடெக்குகளை இயக்கு"</item>
-    <item msgid="741805482892725657">"கட்டாயமில்லா கோடெக்குகளை முடக்கு"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"சாதனத் தேர்வைப் பயன்படுத்து (இயல்பு)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
@@ -137,7 +123,7 @@
     <item msgid="364670732877872677">"சிறந்த முறை (அடாப்டிவ் பிட் வீதம்)"</item>
   </string-array>
   <string-array name="select_logd_size_titles">
-    <item msgid="8665206199209698501">"முடக்கு"</item>
+    <item msgid="8665206199209698501">"ஆஃப்"</item>
     <item msgid="1593289376502312923">"64K"</item>
     <item msgid="487545340236145324">"256K"</item>
     <item msgid="2423528675294333831">"1M"</item>
@@ -145,13 +131,13 @@
     <item msgid="2803199102589126938">"16M"</item>
   </string-array>
   <string-array name="select_logd_size_lowram_titles">
-    <item msgid="6089470720451068364">"முடக்கு"</item>
+    <item msgid="6089470720451068364">"ஆஃப்"</item>
     <item msgid="4622460333038586791">"64K"</item>
     <item msgid="2212125625169582330">"256K"</item>
     <item msgid="1704946766699242653">"1M"</item>
   </string-array>
   <string-array name="select_logd_size_summaries">
-    <item msgid="6921048829791179331">"முடக்கத்தில்"</item>
+    <item msgid="6921048829791179331">"ஆஃப்"</item>
     <item msgid="2969458029344750262">"64K / லாக் பஃபர்"</item>
     <item msgid="1342285115665698168">"256K / லாக் பஃபர்"</item>
     <item msgid="1314234299552254621">"1M / லாக் பஃபர்"</item>
@@ -159,13 +145,13 @@
     <item msgid="5431354956856655120">"16M / லாக் பஃபர்"</item>
   </string-array>
   <string-array name="select_logpersist_titles">
-    <item msgid="1744840221860799971">"முடக்கத்தில்"</item>
+    <item msgid="1744840221860799971">"ஆஃப்"</item>
     <item msgid="3054662377365844197">"எல்லாம்"</item>
     <item msgid="688870735111627832">"எல்லாம் (ரேடியோ தவிர்த்து)"</item>
     <item msgid="2850427388488887328">"கெர்னல் மட்டும்"</item>
   </string-array>
   <string-array name="select_logpersist_summaries">
-    <item msgid="2216470072500521830">"முடக்கத்தில்"</item>
+    <item msgid="2216470072500521830">"ஆஃப்"</item>
     <item msgid="172978079776521897">"தற்காலிகமாகச் சேமித்த எல்லா பதிவுகளும்"</item>
     <item msgid="3873873912383879240">"எல்லாம் (தற்காலிகமாகச் சேமித்த ரேடியோ பதிவுகள் தவிர்த்து)"</item>
     <item msgid="8489661142527693381">"கெர்னல் லாக் பஃபர் மட்டும்"</item>
@@ -218,17 +204,17 @@
     <item msgid="1340692776955662664">"glGetError இல் அழைப்பின் அடுக்கு"</item>
   </string-array>
   <string-array name="show_non_rect_clip_entries">
-    <item msgid="993742912147090253">"முடக்கத்தில்"</item>
+    <item msgid="993742912147090253">"ஆஃப்"</item>
     <item msgid="675719912558941285">"செவ்வகம் அல்லாத கிளிப் பகுதியை நீல நிறத்தில் வரையவும்"</item>
     <item msgid="1064373276095698656">"சோதிக்கப்பட்ட வரைதல் கட்டளைகளைப் பச்சை நிறத்தில் தனிப்படுத்தவும்"</item>
   </string-array>
   <string-array name="track_frame_time_entries">
-    <item msgid="2193584639058893150">"முடக்கத்தில்"</item>
+    <item msgid="2193584639058893150">"ஆஃப்"</item>
     <item msgid="2751513398307949636">"திரையில் பட்டிகளாக"</item>
     <item msgid="2355151170975410323">"<xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g> இல்"</item>
   </string-array>
   <string-array name="debug_hw_overdraw_entries">
-    <item msgid="8190572633763871652">"முடக்கத்தில்"</item>
+    <item msgid="8190572633763871652">"ஆஃப்"</item>
     <item msgid="7688197031296835369">"ஓவர்டிரா பகுதிகளைக் காட்டு"</item>
     <item msgid="2290859360633824369">"நிறக்குருடின் பகுதிகளைக் காட்டு"</item>
   </string-array>
@@ -245,7 +231,7 @@
     <item msgid="7899496259191969307">"அதிகபட்சமாக 4 செயல்முறைகள்"</item>
   </string-array>
   <string-array name="usb_configuration_titles">
-    <item msgid="488237561639712799">"சார்ஜ் ஏறுகிறது"</item>
+    <item msgid="488237561639712799">"சார்ஜ் ஆகிறது"</item>
     <item msgid="5220695614993094977">"MTP (மீடியா பரிமாற்ற நெறிமுறை)"</item>
     <item msgid="2086000968159047375">"PTP (படப் பரிமாற்ற நெறிமுறை)"</item>
     <item msgid="7398830860950841822">"RNDIS (USB ஈத்தர்நெட்)"</item>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 454d43d..fde89df 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"தரம் குறைவான நெட்வொர்க்கின் காரணமாக, இணைக்கப்படவில்லை"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"வைஃபை இணைப்பில் தோல்வி"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"அங்கீகரிப்புச் சிக்கல்"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"இணைக்க முடியவில்லை"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' உடன் இணைக்க முடியவில்லை"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"கடவுச்சொல்லைச் சரிபார்த்து, மீண்டும் முயலவும்"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"தொடர்பு எல்லையில் இல்லை"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"தானாக இணைக்கப்படாது"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"இணைய அணுகல் இல்லை"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s வழியாக இணைக்கப்பட்டது"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s வழியாகக் கிடைக்கிறது"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"இணைக்கப்பட்டது, இணையம் இல்லை"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"மிகவும் வேகம் குறைவானது"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"வேகம் குறைவு"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"சரி"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"நடுத்தரம்"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"வேகம்"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"மிகவும் வேகமானது"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"தொடர்பு துண்டிக்கப்பட்டது"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"துண்டிக்கிறது..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"இணைக்கிறது..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"இணைக்கப்பட்டது (மீடியா இல்லை)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"இணைக்கப்பட்டது (செய்திக்கான அணுகல் இல்லை)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"இணைக்கப்பட்டது (மொபைல் அல்லது மீடியாவுடன் அல்ல)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"இணைக்கப்பட்டது, பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"இணைக்கப்பட்டது (மொபைல் ஆடியோ இணைக்கப்படவில்லை), பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"இணைக்கப்பட்டது (மீடியா ஆடியோ இணைக்கப்படவில்லை), பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"இணைக்கப்பட்டது (மொபைல் அல்லது மீடியா ஆடியோ இணைக்கப்படவில்லை), பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"மீடியா ஆடியோ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"மொபைல் ஆடியோ"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ஃபோன் அழைப்புகள்"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"கோப்பு இடமாற்றம்"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"உள்ளீட்டுச் சாதனம்"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"இணைய அணுகல்"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"தொடர்புப் பகிர்தல்"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"தொடர்புப் பகிர்தலுக்குப் பயன்படுத்து"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"இணைய இணைப்பு பகிர்தல்"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"செய்திக்கான அணுகல்"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"உரைச் செய்திகள்"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"சிம் அணுகல்"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"உயர்தர ஆடியோவைப் பயன்படுத்து: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"உயர்தர ஆடியோவைப் பயன்படுத்து"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ஆடியோ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ஆடியோ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"மீடியா ஆடியோவுடன் இணைக்கப்பட்டது"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"மொபைல் ஆடியோவுடன் இணைக்கப்பட்டது"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"கோப்பைப் பரிமாற்றும் சேவையகத்துடன் இணைக்கப்பட்டது"</string>
@@ -97,7 +110,7 @@
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"டெதெரிங்"</string>
     <string name="tether_settings_title_all" msgid="8356136101061143841">"டெதெரிங் &amp; போர்டபிள் ஹாட்ஸ்பாட்"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"எல்லா பணிப் பயன்பாடுகளும்"</string>
-    <string name="user_guest" msgid="8475274842845401871">"கெஸ்ட்"</string>
+    <string name="user_guest" msgid="8475274842845401871">"வேறொருவர்"</string>
     <string name="unknown" msgid="1592123443519355854">"அறியப்படாத"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"பயனர்: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="313159469856372621">"சில இயல்புநிலைகள் அமைக்கப்பட்டன"</string>
@@ -172,7 +185,8 @@
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"வைஃபை அதிவிவர நுழைவை இயக்கு"</string>
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ஒத்துழைக்காத வைஃபையிலிருந்து மொபைல் தரவிற்கு மாறு"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"எப்போதும் வைஃபை ரோமிங் ஸ்கேன்களை அனுமதி"</string>
-    <string name="mobile_data_always_on" msgid="8774857027458200434">"மொபைல் தரவை எப்போதும் இயக்கத்திலேயே வை"</string>
+    <string name="mobile_data_always_on" msgid="8774857027458200434">"மொபைல் டேட்டாவை எப்போதும் இயக்கத்திலேயே வை"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"வன்பொருள் விரைவுப்படுத்துதல் இணைப்பு முறை"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"அப்சல்யூட் ஒலியளவு அம்சத்தை முடக்கு"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"இன்-பேண்ட் ரிங் செய்வதை இயக்கு"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"புளூடூத் AVRCP பதிப்பு"</string>
@@ -203,7 +217,8 @@
     <string name="allow_mock_location" msgid="2787962564578664888">"போலி இருப்பிடங்களை அனுமதி"</string>
     <string name="allow_mock_location_summary" msgid="317615105156345626">"போலி இருப்பிடங்களை அனுமதி"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"காட்சி பண்புக்கூறு சோதனையை இயக்கு"</string>
-    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"வைஃபை இயங்கும் போதும் (வேகமான நெட்வொர்க் மாற்றத்திற்கு), மொபைல் தரவை எப்போதும் இயக்கத்தில் வைக்கும்."</string>
+    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"வைஃபை இயங்கும் போதும் (வேகமான நெட்வொர்க் மாற்றத்திற்கு), மொபைல் டேட்டாவை எப்போதும் இயக்கத்தில் வைக்கும்."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"வன்பொருள் விரைவுப்படுத்துதல் இணைப்பு முறை கிடைக்கும் போது, அதைப் பயன்படுத்தும்"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB பிழைத்திருத்தத்தை அனுமதிக்கவா?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB பிழைத்திருத்தம் மேம்படுத்தல் நோக்கங்களுக்காக மட்டுமே. அதை உங்கள் கணினி மற்றும் சாதனத்திற்கு இடையில் தரவை நகலெடுக்கவும், அறிவிப்பு இல்லாமல் உங்கள் சாதனத்தில் பயன்பாடுகளை நிறுவவும், பதிவு தரவைப் படிக்கவும் பயன்படுத்தவும்."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"நீங்கள் ஏற்கனவே அனுமதித்த எல்லா கணினிகளிலிருந்தும் USB பிழைத்திருத்தத்திற்கான அணுகலைத் திரும்பப்பெற வேண்டுமா?"</string>
@@ -266,7 +281,7 @@
     <string name="transition_animation_scale_title" msgid="387527540523595875">"அனிமேஷன் மாற்றத்தின் அளவு"</string>
     <string name="animator_duration_scale_title" msgid="3406722410819934083">"அனிமேட்டர் கால அளவு"</string>
     <string name="overlay_display_devices_title" msgid="5364176287998398539">"இரண்டாம்நிலைக் காட்சிகளை உருவகப்படுத்து"</string>
-    <string name="debug_applications_category" msgid="4206913653849771549">"பயன்பாடுகள்"</string>
+    <string name="debug_applications_category" msgid="4206913653849771549">"ஆப்ஸ்"</string>
     <string name="immediately_destroy_activities" msgid="1579659389568133959">"செயல்பாடுகளை வைத்திருக்காதே"</string>
     <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"பயனர் வெளியேறியதும் செயல்பாடுகளை நீக்கு"</string>
     <string name="app_process_limit_title" msgid="4280600650253107163">"பின்புலச் செயல்முறை வரம்பு"</string>
@@ -320,27 +335,30 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"வண்ணத்திருத்தம்"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"இது சோதனை முறையிலான அம்சம், இது செயல்திறனைப் பாதிக்கலாம்."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> மூலம் மேலெழுதப்பட்டது"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"கிட்டத்தட்ட <xliff:g id="TIME">%1$s</xliff:g> உள்ளது"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"முழு சார்ஜாக <xliff:g id="TIME">%1$s</xliff:g> ஆகும்"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> மீதமுள்ளது"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - கிட்டத்தட்ட <xliff:g id="TIME">%2$s</xliff:g> மீதமுள்ளது"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> மீதமுள்ளது"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"கிட்டத்தட்ட <xliff:g id="TIME">^1</xliff:g> உள்ளது"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"உபயோகத்தின் அடிப்படையில் கிட்டத்தட்ட <xliff:g id="TIME">^1</xliff:g> மீதமுள்ளது"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"முழு சார்ஜாக <xliff:g id="TIME">^1</xliff:g> ஆகும்"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> மீதமுள்ளது"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"உபயோகத்தின் அடிப்படையில் <xliff:g id="TIME">^1</xliff:g> மீதமுள்ளது"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - கிட்டத்தட்ட <xliff:g id="TIME">^2</xliff:g> மீதமுள்ளது"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - உபயோகத்தின் அடிப்படையில் கிட்டத்தட்ட <xliff:g id="TIME">^2</xliff:g> மீதமுள்ளது"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - முழு சார்ஜாக <xliff:g id="TIME">%2$s</xliff:g> ஆகும்"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - முழு சார்ஜாக <xliff:g id="TIME">^2</xliff:g> ஆகும்"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"அறியப்படாத"</string>
-    <string name="battery_info_status_charging" msgid="1705179948350365604">"சார்ஜ் ஏற்றப்படுகிறது"</string>
-    <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"சார்ஜாகிறது"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"சார்ஜ் ஆகிறது"</string>
+    <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"சார்ஜ் ஆகிறது"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"சார்ஜ் செய்யப்படவில்லை"</string>
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"சார்ஜ் ஏறவில்லை"</string>
-    <string name="battery_info_status_full" msgid="2824614753861462808">"முழுமை"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"முழுவதும் சார்ஜ் ஆனது"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"நிர்வாகி கட்டுப்படுத்துகிறார்"</string>
     <string name="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>
-    <string name="install_other_apps" msgid="6986686991775883017">"அறியப்படாத பயன்பாடுகளை நிறுவு"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"நிறுவுதல் (அறியாதவை)"</string>
     <string name="home" msgid="3256884684164448244">"அமைப்புகள் முகப்பு"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index cc77139..f12fd2a 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (డిఫాల్ట్)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"ఐచ్ఛిక కోడెక్‌లను ప్రారంభించు"</item>
-    <item msgid="3304843301758635896">"ఐచ్ఛిక కోడెక్‌లను నిలిపివేయి"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"ఐచ్ఛిక కోడెక్‌లను ప్రారంభించు"</item>
-    <item msgid="741805482892725657">"ఐచ్ఛిక కోడెక్‌లను నిలిపివేయి"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 45c6cb8..42b08f1 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -28,15 +28,24 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"తక్కువ నాణ్యతా నెట్‌వర్క్ కారణంగా కనెక్ట్ చేయబడలేదు"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi కనెక్షన్ వైఫల్యం"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"ప్రామాణీకరణ సమస్య"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"కనెక్ట్ చేయడం సాధ్యపడదు"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'కు కనెక్ట్ చేయడం సాధ్యపడదు"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"పాస్‌వర్డ్‌ను తనిఖీ చేసి, మళ్లీ ప్రయత్నించండి"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"పరిధిలో లేదు"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"స్వయంచాలకంగా కనెక్ట్ కాదు"</string>
-    <string name="wifi_no_internet" msgid="3880396223819116454">"ఇంటర్నెట్ ప్రాప్యత లేదు"</string>
+    <string name="wifi_no_internet" msgid="3880396223819116454">"ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
     <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> ద్వారా సేవ్ చేయబడింది"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ద్వారా స్వయంచాలకంగా కనెక్ట్ చేయబడింది"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"నెట్‌వర్క్ రేటింగ్ ప్రదాత ద్వారా స్వయంచాలకంగా కనెక్ట్ చేయబడింది"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ద్వారా కనెక్ట్ చేయబడింది"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ద్వారా అందుబాటులో ఉంది"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"కనెక్ట్ చేయబడింది, ఇంటర్నెట్ లేదు"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"చాలా నెమ్మది"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"నెమ్మది"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"సరే"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"మధ్యస్థం"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"వేగవంతం"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"చాలా వేగవంతం"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"డిస్‌కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"డిస్‌కనెక్ట్ చేస్తోంది..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"కనెక్ట్ చేస్తోంది..."</string>
@@ -44,20 +53,24 @@
     <string name="bluetooth_pairing" msgid="1426882272690346242">"జత చేస్తోంది..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"కనెక్ట్ చేయబడింది (ఫోన్‌ కాదు)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"కనెక్ట్ చేయబడింది (మీడియా కాదు)"</string>
-    <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"కనెక్ట్ చేయబడింది (సందేశ ప్రాప్యత లేదు)"</string>
+    <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"కనెక్ట్ చేయబడింది (సందేశ యాక్సెస్ లేదు)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"కనెక్ట్ చేయబడింది (ఫోన్ లేదా మీడియా కాకుండా)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"కనెక్ట్ చేయబడింది, బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"కనెక్ట్ చేయబడింది (ఫోన్ కాదు), బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"కనెక్ట్ చేయబడింది (మీడియా కాదు), బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"కనెక్ట్ చేయబడింది (ఫోన్ లేదా మీడియా కాదు), బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"మీడియా ఆడియో"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ఫోన్ ఆడియో"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ఫోన్ కాల్‌లు"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ఫైల్ బదిలీ"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ఇన్‌పుట్ పరికరం"</string>
-    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ఇంటర్నెట్ ప్రాప్యత"</string>
+    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ఇంటర్నెట్ యాక్సెస్"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"పరిచయ భాగస్వామ్యం"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"పరిచయ భాగస్వామ్యం కోసం ఉపయోగించు"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ఇంటర్నెట్ కనెక్షన్ భాగస్వామ్యం"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"సందేశ ప్రాప్యత"</string>
-    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM ప్రాప్యత"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"అధిక నాణ్యత ఆడియోను ఉపయోగించండి: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"అధిక నాణ్యత ఆడియోను ఉపయోగించండి"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"వచన సందేశాలు"</string>
+    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM యాక్సెస్"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ఆడియో: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ఆడియో"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"మీడియా ఆడియోకు కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ఫోన్ ఆడియోకు కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ఫైల్ బదిలీ సర్వర్‌కు కనెక్ట్ చేయబడింది"</string>
@@ -65,11 +78,11 @@
     <string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"SAPకి కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"ఫైల్ బదిలీ సర్వర్‌కు కనెక్ట్ చేయబడలేదు"</string>
     <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"ఇన్‌పుట్ పరికరానికి కనెక్ట్ చేయబడింది"</string>
-    <string name="bluetooth_pan_user_profile_summary_connected" msgid="4602294638909590612">"ఇంటర్నెట్ ప్రాప్యత కోసం పరికరానికి కనెక్ట్ చేయబడింది"</string>
+    <string name="bluetooth_pan_user_profile_summary_connected" msgid="4602294638909590612">"ఇంటర్నెట్ యాక్సెస్ కోసం పరికరానికి కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1561383706411975199">"స్థానిక ఇంటర్నెట్ కనెక్షన్‌ను పరికరంతో భాగస్వామ్యం చేయడం"</string>
-    <string name="bluetooth_pan_profile_summary_use_for" msgid="5664884523822068653">"ఇంటర్నెట్ ప్రాప్యత కోసం ఉపయోగించు"</string>
+    <string name="bluetooth_pan_profile_summary_use_for" msgid="5664884523822068653">"ఇంటర్నెట్ యాక్సెస్ కోసం ఉపయోగించు"</string>
     <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"మ్యాప్ కోసం ఉపయోగించు"</string>
-    <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"SIM ప్రాప్యత కోసం ఉపయోగించబడుతుంది"</string>
+    <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"SIM యాక్సెస్ కోసం ఉపయోగించబడుతుంది"</string>
     <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"మీడియా ఆడియో కోసం ఉపయోగించు"</string>
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ఫోన్ ఆడియో కోసం ఉపయోగించు"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ఫైల్ బదిలీ కోసం ఉపయోగించు"</string>
@@ -79,7 +92,7 @@
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"రద్దు చేయి"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"జత చేయడం వలన కనెక్ట్ చేయబడినప్పుడు మీ పరిచయాలకు మరియు కాల్ చరిత్రకు ప్రాప్యతను మంజూరు చేస్తుంది."</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>తో జత చేయడం సాధ్యపడలేదు."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"పిన్‌ లేదా పాస్‌కీ చెల్లని కారణంగా <xliff:g id="DEVICE_NAME">%1$s</xliff:g>తో జత చేయడం సాధ్యపడలేదు."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"పిన్ లేదా పాస్‌కీ చెల్లని కారణంగా <xliff:g id="DEVICE_NAME">%1$s</xliff:g>తో జత చేయడం సాధ్యపడలేదు."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>తో కమ్యూనికేట్ చేయడం సాధ్యపడదు."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> జత చేయడాన్ని తిరస్కరించింది."</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi ఆఫ్‌లో ఉంది."</string>
@@ -150,11 +163,11 @@
     <string name="development_settings_not_available" msgid="4308569041701535607">"ఈ వినియోగదారు కోసం డెవలపర్ ఎంపికలు అందుబాటులో లేవు"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN సెట్టింగ్‌లు ఈ వినియోగదారుకి అందుబాటులో లేవు"</string>
     <string name="tethering_settings_not_available" msgid="6765770438438291012">"టీథరింగ్ సెట్టింగ్‌లు ఈ వినియోగదారుకి అందుబాటులో లేవు"</string>
-    <string name="apn_settings_not_available" msgid="7873729032165324000">"ప్రాప్యత స్థానం పేరు సెట్టింగ్‌లు ఈ వినియోగదారుకి అందుబాటులో లేవు"</string>
+    <string name="apn_settings_not_available" msgid="7873729032165324000">"యాక్సెస్ స్థానం పేరు సెట్టింగ్‌లు ఈ వినియోగదారుకి అందుబాటులో లేవు"</string>
     <string name="enable_adb" msgid="7982306934419797485">"USB డీబగ్గింగ్"</string>
     <string name="enable_adb_summary" msgid="4881186971746056635">"USB కనెక్ట్ చేయబడినప్పుడు డీబగ్ మోడ్"</string>
     <string name="clear_adb_keys" msgid="4038889221503122743">"USB డీబగ్ ప్రామాణీకరణలను ఉపసంహరించు"</string>
-    <string name="bugreport_in_power" msgid="7923901846375587241">"బగ్ నివేదిక సత్వరమార్గం"</string>
+    <string name="bugreport_in_power" msgid="7923901846375587241">"బగ్ నివేదిక షార్ట్‌కట్"</string>
     <string name="bugreport_in_power_summary" msgid="1778455732762984579">"బగ్ నివేదికను తీసుకోవడానికి పవర్ మెనులో బటన్‌ను చూపు"</string>
     <string name="keep_screen_on" msgid="1146389631208760344">"సక్రియంగా ఉంచు"</string>
     <string name="keep_screen_on_summary" msgid="2173114350754293009">"ఛార్జ్ చేస్తున్నప్పుడు స్క్రీన్ ఎప్పటికీ నిద్రావస్థలోకి వెళ్లదు"</string>
@@ -165,17 +178,18 @@
     <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM అన్‌లాకింగ్‌ను అనుమతించాలా?"</string>
     <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"హెచ్చరిక: ఈ సెట్టింగ్ ఆన్ చేయబడినప్పుడు పరికరం రక్షణ లక్షణాలు ఈ పరికరంలో పని చేయవు."</string>
     <string name="mock_location_app" msgid="7966220972812881854">"అనుకృత స్థాన అనువర్తనాన్ని ఎంచుకోండి"</string>
-    <string name="mock_location_app_not_set" msgid="809543285495344223">"అనుకృత స్థాన అనువర్తనం ఏదీ సెట్ చేయబడలేదు"</string>
-    <string name="mock_location_app_set" msgid="8966420655295102685">"అనుకృత స్థాన అనువర్తనం: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="mock_location_app_not_set" msgid="809543285495344223">"అనుకృత స్థాన యాప్ ఏదీ సెట్ చేయబడలేదు"</string>
+    <string name="mock_location_app_set" msgid="8966420655295102685">"అనుకృత స్థాన యాప్: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="debug_networking_category" msgid="7044075693643009662">"నెట్‌వర్కింగ్"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"వైర్‌లెస్ ప్రదర్శన ప్రమాణీకరణ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi విశదీకృత లాగింగ్‌ను ప్రారంభించండి"</string>
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"మొబైల్‌కి మార్చేలా చురుకైన Wi‑Fi"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi సంచార స్కాన్‌లను ఎల్లప్పుడూ అనుమతించు"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"మొబైల్ డేటాని ఎల్లప్పుడూ సక్రియంగా ఉంచు"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"టెథెరింగ్ హార్డ్‌వేర్ వేగవృద్ధి"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"సంపూర్ణ వాల్యూమ్‌‍ను నిలిపివేయి"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ఇన్-బ్యాండ్ రింగింగ్‌ని ప్రారంభించండి"</string>
-    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"బ్లూటూత్ AVRCP సంస్కరణ"</string>
+    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"బ్లూటూత్ AVRCP వెర్షన్"</string>
     <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"బ్లూటూత్ AVRCP సంస్కరణను ఎంచుకోండి"</string>
     <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"బ్లూటూత్ ఆడియో కోడెక్"</string>
     <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"బ్లూటూత్ ఆడియో కోడెక్‌ని ఎంచుకోండి"</string>
@@ -188,7 +202,7 @@
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"బ్లూటూత్ ఆడియో LDAC కోడెక్: ప్లేబ్యాక్ నాణ్యత"</string>
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"బ్లూటూత్ ఆడియో LDAC కోడెక్‌ని ఎంచుకోండి:\nప్లేబ్యాక్ నాణ్యత"</string>
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ప్రసారం చేస్తోంది: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
-    <string name="wifi_display_certification_summary" msgid="1155182309166746973">"వైర్‌లెస్ ప్రదర్శన ప్రమాణపత్రం కోసం ఎంపికలను చూపు"</string>
+    <string name="wifi_display_certification_summary" msgid="1155182309166746973">"వైర్‌లెస్ ప్రదర్శన సర్టిఫికెట్ కోసం ఎంపికలను చూపు"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ఎంపికలో SSID RSSI ప్రకారం చూపబడే Wi‑Fi లాగింగ్ స్థాయిని పెంచండి"</string>
     <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ప్రారంభించబడినప్పుడు, Wi‑Fi సిగ్నల్ బలహీనంగా ఉంటే డేటా కనెక్షన్‌ను మొబైల్‌కి మార్చేలా Wi‑Fi చురుగ్గా వ్యవహరిస్తుంది"</string>
     <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ఇంటర్‌ఫేస్‌లో ఉండే డేటా ట్రాఫిక్ పరిమాణం ఆధారంగా Wi‑Fi సంచార స్కాన్‌లను అనుమతించు/నిరాకరించు"</string>
@@ -204,11 +218,12 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"అనుకృత స్థానాలను అనుమతించు"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"వీక్షణ లక్షణ పర్యవేక్షణను ప్రారంభించు"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ఎల్లప్పుడూ మొబైల్ డేటాను సక్రియంగా ఉంచు, Wi‑Fi సక్రియంగా ఉన్నా కూడా (వేగవంతమైన నెట్‌వర్క్ మార్పు కోసం)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"అందుబాటులో ఉంటే టెథెరింగ్ హార్డ్‌వేర్ వేగవృద్ధిని ఉపయోగించండి"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB డీబగ్గింగ్‌ను అనుమతించాలా?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB డీబగ్గింగ్ అనేది అభివృద్ధి ప్రయోజనాల కోసం మాత్రమే ఉద్దేశించబడింది. మీ కంప్యూటర్ మరియు మీ పరికరం మధ్య డేటాను కాపీ చేయడానికి, నోటిఫికేషన్ లేకుండా మీ పరికరంలో అనువర్తనాలను ఇన్‌స్టాల్ చేయడానికి మరియు లాగ్ డేటాను చదవడానికి దీన్ని ఉపయోగించండి."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"మీరు గతంలో ప్రామాణీకరించిన అన్ని కంప్యూటర్‌ల నుండి USB డీబగ్గింగ్‌కు ప్రాప్యతను ఉపసంహరించాలా?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"అభివృద్ధి సెట్టింగ్‌లను అనుమతించాలా?"</string>
-    <string name="dev_settings_warning_message" msgid="2298337781139097964">"ఈ సెట్టింగ్‌లు అభివృద్ధి వినియోగం కోసం మాత్రమే ఉద్దేశించబడినవి. వీటి వలన మీ పరికరం మరియు దీనిలోని అనువర్తనాలు విచ్ఛిన్నం కావచ్చు లేదా తప్పుగా ప్రవర్తించవచ్చు."</string>
+    <string name="dev_settings_warning_message" msgid="2298337781139097964">"ఈ సెట్టింగ్‌లు అభివృద్ధి వినియోగం కోసం మాత్రమే ఉద్దేశించబడినవి. వీటి వలన మీ పరికరం మరియు దీనిలోని యాప్‌లు విచ్ఛిన్నం కావచ్చు లేదా తప్పుగా ప్రవర్తించవచ్చు."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB ద్వారా అనువర్తనాలను ధృవీకరించు"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"హానికరమైన ప్రవర్తన కోసం ADB/ADT ద్వారా ఇన్‌స్టాల్ చేయబడిన అనువర్తనాలను తనిఖీ చేయి."</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"రిమోట్ పరికరాల్లో ఆమోదించలేని స్థాయిలో అధిక వాల్యూమ్ ఉండటం లేదా వాల్యూమ్ నియంత్రణ లేకపోవడం వంటి సమస్యలు ఉంటే బ్లూటూత్ సంపూర్ణ వాల్యూమ్ లక్షణాన్ని నిలిపివేస్తుంది."</string>
@@ -219,12 +234,12 @@
     <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"HDCP తనిఖీ ప్రవర్తనను సెట్ చేయండి"</string>
     <string name="debug_debugging_category" msgid="6781250159513471316">"డీబగ్గింగ్"</string>
     <string name="debug_app" msgid="8349591734751384446">"డీబగ్ అనువర్తనాన్ని ఎంచుకోండి"</string>
-    <string name="debug_app_not_set" msgid="718752499586403499">"డీబగ్ అనువర్తనం సెట్ చేయబడలేదు"</string>
-    <string name="debug_app_set" msgid="2063077997870280017">"డీబగ్గింగ్ అనువర్తనం: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="debug_app_not_set" msgid="718752499586403499">"డీబగ్ యాప్ సెట్ చేయబడలేదు"</string>
+    <string name="debug_app_set" msgid="2063077997870280017">"డీబగ్గింగ్ యాప్: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="select_application" msgid="5156029161289091703">"అనువర్తనాన్ని ఎంచుకోండి"</string>
     <string name="no_application" msgid="2813387563129153880">"ఏదీ వద్దు"</string>
     <string name="wait_for_debugger" msgid="1202370874528893091">"డీబగ్గర్ కోసం వేచి ఉండండి"</string>
-    <string name="wait_for_debugger_summary" msgid="1766918303462746804">"డీబగ్ చేయబడిన అనువర్తనం అమలు కావడానికి ముందు జోడించాల్సిన డీబగ్గర్ కోసం వేచి ఉంటుంది"</string>
+    <string name="wait_for_debugger_summary" msgid="1766918303462746804">"డీబగ్ చేయబడిన యాప్ అమలు కావడానికి ముందు జోడించాల్సిన డీబగ్గర్ కోసం వేచి ఉంటుంది"</string>
     <string name="telephony_monitor_switch" msgid="1764958220062121194">"టెలిఫోనీ మానిటర్"</string>
     <string name="telephony_monitor_switch_summary" msgid="7695552966547975635">"టెలిఫోనీ/మోడెమ్ కార్యాచరణలో సమస్యను గుర్తించినప్పుడు TelephonyMonitor లాగ్‌లను సేకరిస్తుంది మరియు బగ్‌ని ఫైల్ చేయమని వినియోగదారును ప్రోత్సహిస్తుంది"</string>
     <string name="debug_input_category" msgid="1811069939601180246">"ఇన్‌పుట్"</string>
@@ -238,11 +253,11 @@
     <string name="pointer_location_summary" msgid="840819275172753713">"ప్రస్తుత స్పర్శ డేటాను చూపేలా స్క్రీన్ అతివ్యాప్తి చేయండి"</string>
     <string name="show_touches" msgid="2642976305235070316">"నొక్కినవి చూపు"</string>
     <string name="show_touches_summary" msgid="6101183132903926324">"నొక్కినవాటికి సంబంధించిన దృశ్య అభిప్రాయాన్ని చూపు"</string>
-    <string name="show_screen_updates" msgid="5470814345876056420">"సర్ఫేస్ నవీకరణలను చూపండి"</string>
+    <string name="show_screen_updates" msgid="5470814345876056420">"సర్ఫేస్ అప్‌డేట్‌లను చూపండి"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"పూర్తి విండో ఉపరితలాలు నవీకరించబడినప్పుడు వాటిని ఫ్లాష్ చేయండి"</string>
-    <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU వీక్షణ నవీకరణలను చూపండి"</string>
+    <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU వీక్షణ అప్‌డేట్‌లను చూపండి"</string>
     <string name="show_hw_screen_updates_summary" msgid="1115593565980196197">"GPUతో గీసినప్పుడు విండోల లోపల వీక్షణలను ఫ్లాష్ చేయండి"</string>
-    <string name="show_hw_layers_updates" msgid="5645728765605699821">"హార్డ్‌వేర్ లేయర్‌ల నవీకరణలను చూపండి"</string>
+    <string name="show_hw_layers_updates" msgid="5645728765605699821">"హార్డ్‌వేర్ లేయర్‌ల అప్‌డేట్‌లను చూపండి"</string>
     <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"హార్డ్‌వేర్ లేయర్‌లు నవీకరించబడినప్పుడు వాటిని ఆకుపచ్చ రంగులో ఫ్లాష్ చేయండి"</string>
     <string name="debug_hw_overdraw" msgid="2968692419951565417">"GPU ఓవర్‌డ్రాను డీబగ్ చేయండి"</string>
     <string name="debug_hw_renderer" msgid="7568529019431785816">"GPU Rendererని సెట్ చేయండి"</string>
@@ -266,14 +281,14 @@
     <string name="transition_animation_scale_title" msgid="387527540523595875">"పరివర్తన యానిమేషన్ ప్రమాణం"</string>
     <string name="animator_duration_scale_title" msgid="3406722410819934083">"యానిమేటర్ వ్యవధి ప్రమాణం"</string>
     <string name="overlay_display_devices_title" msgid="5364176287998398539">"ప్రత్యామ్నాయ ప్రదర్శనలను అనుకరించండి"</string>
-    <string name="debug_applications_category" msgid="4206913653849771549">"అనువర్తనాలు"</string>
+    <string name="debug_applications_category" msgid="4206913653849771549">"యాప్‌లు"</string>
     <string name="immediately_destroy_activities" msgid="1579659389568133959">"కార్యాచరణలను ఉంచవద్దు"</string>
     <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"ప్రతి కార్యాచరణను వినియోగదారు నిష్క్రమించిన వెంటనే తొలగించండి"</string>
     <string name="app_process_limit_title" msgid="4280600650253107163">"నేపథ్య ప్రాసెస్ పరిమితి"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"అన్ని ANRలను చూపు"</string>
-    <string name="show_all_anrs_summary" msgid="641908614413544127">"నేపథ్య అనువర్తనాల కోసం అనువర్తనం ప్రతిస్పందించడం లేదు డైలాగ్‌ను చూపు"</string>
+    <string name="show_all_anrs_summary" msgid="641908614413544127">"నేపథ్య యాప్‌ల కోసం యాప్ ప్రతిస్పందించడం లేదు డైలాగ్‌ను చూపు"</string>
     <string name="show_notification_channel_warnings" msgid="1399948193466922683">"ఛానెల్ హెచ్చరికల నోటిఫికేషన్‌‌ను చూపు"</string>
-    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"చెల్లుబాటు అయ్యే ఛానెల్ లేకుండా అనువర్తనం నోటిఫికేషన్‌ను పోస్ట్ చేస్తున్నప్పుడు స్క్రీన్‌పై హెచ్చరికను చూపిస్తుంది"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"చెల్లుబాటు అయ్యే ఛానెల్ లేకుండా యాప్ నోటిఫికేషన్‌ను పోస్ట్ చేస్తున్నప్పుడు స్క్రీన్‌పై హెచ్చరికను చూపిస్తుంది"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"అనువర్తనాలను బాహ్య నిల్వలో నిర్బంధంగా అనుమతించు"</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"ఏ అనువర్తనాన్ని అయినా మానిఫెస్ట్ విలువలతో సంబంధం లేకుండా బాహ్య నిల్వలో వ్రాయడానికి అనుమతిస్తుంది"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"కార్యాచరణలను పరిమాణం మార్చగలిగేలా నిర్బంధించు"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"రంగు సవరణ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ఈ లక్షణం ప్రయోగాత్మకమైనది మరియు పనితీరుపై ప్రభావం చూపవచ్చు."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"మిగిలి ఉన్న సమయం, <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"పూర్తిగా ఛార్జ్ కావడానికి <xliff:g id="TIME">%1$s</xliff:g> పడుతుంది"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> మిగిలి ఉంది"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> పని చేస్తుంది"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> మిగిలి ఉంది"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"మిగిలి ఉన్న సమయం, <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"మీ వినియోగం ఆధారంగా సుమారు <xliff:g id="TIME">^1</xliff:g> సమయం మిగిలి ఉంది"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"పూర్తిగా ఛార్జ్ కావడానికి <xliff:g id="TIME">^1</xliff:g> పడుతుంది"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> మిగిలి ఉంది"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"మీ వినియోగం ఆధారంగా <xliff:g id="TIME">^1</xliff:g> సమయం మిగిలి ఉంది"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> పని చేస్తుంది"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - మీ వినియోగం ఆధారంగా సుమారు <xliff:g id="TIME">^2</xliff:g> సమయం మిగిలి ఉంది"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>లో పూర్తిగా ఛార్జ్ అవుతుంది"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>లో పూర్తిగా ఛార్జ్ అవుతుంది"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"తెలియదు"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"ఛార్జ్ అవుతోంది"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ఛార్జ్ అవుతోంది"</string>
@@ -340,7 +358,7 @@
     <string name="disabled" msgid="9206776641295849915">"నిలిపివేయబడింది"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"అనుమతించినవి"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"అనుమతించబడలేదు"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"తెలియని అనువర్తనాలను ఇన్‌స్టాల్ చేయండి"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"తెలియని యాప్‌లను ఇన్‌స్టాల్ చేయండి"</string>
     <string name="home" msgid="3256884684164448244">"సెట్టింగ్‌ల హోమ్"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
@@ -359,11 +377,11 @@
     <string name="content_description_menu_button" msgid="8182594799812351266">"మెను"</string>
     <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
     <string name="retail_demo_reset_message" msgid="118771671364131297">"డెమో మోడ్‌లో ఫ్యాక్టరీ రీసెట్‌ను నిర్వహించడానికి పాస్‌వర్డ్‌ను నమోదు చేయండి"</string>
-    <string name="retail_demo_reset_next" msgid="8356731459226304963">"తదుపరి"</string>
+    <string name="retail_demo_reset_next" msgid="8356731459226304963">"తర్వాత"</string>
     <string name="retail_demo_reset_title" msgid="696589204029930100">"పాస్‌వర్డ్ అవసరం"</string>
     <string name="active_input_method_subtypes" msgid="3596398805424733238">"సక్రియ ఇన్‌పుట్ పద్ధతులు"</string>
     <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"సిస్టమ్ భాషలను ఉపయోగించు"</string>
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> యొక్క సెట్టింగ్‌లను తెరవడం విఫలమైంది"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"ఈ ఇన్‌పుట్ పద్ధతి మీరు టైప్ చేసే మొత్తం వచనాన్ని అలాగే పాస్‌వర్డ్‌లు మరియు క్రెడిట్ కార్డు నంబర్‌ల వంటి వ్యక్తిగత డేటాను సేకరించగలదు. ఇది <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> అనువర్తనంలో అందించబడుతుంది. ఈ ఇన్‌పుట్ పద్ధతిని ఉపయోగించాలా?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"గమనిక: రీబూట్ చేసాక, మీరు మీ ఫోన్‌ను అన్‌లాక్ చేసే వరకు ఈ అనువర్తనం ప్రారంభం కాదు"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"గమనిక: రీబూట్ చేసాక, మీరు మీ ఫోన్‌ను అన్‌లాక్ చేసే వరకు ఈ యాప్ ప్రారంభం కాదు"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index d46fc7d..1ef6c1e 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (ค่าเริ่มต้น)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"ใช้การเลือกระบบ (ค่าเริ่มต้น)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"เปิดใช้ตัวแปลงรหัสที่ไม่บังคับ"</item>
-    <item msgid="3304843301758635896">"ปิดใช้ตัวแปลงรหัสที่ไม่บังคับ"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"ใช้การเลือกระบบ (ค่าเริ่มต้น)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"เปิดใช้ตัวแปลงรหัสที่ไม่บังคับ"</item>
-    <item msgid="741805482892725657">"ปิดใช้ตัวแปลงรหัสที่ไม่บังคับ"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"ใช้การเลือกระบบ (ค่าเริ่มต้น)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index d31ca04..4f31238 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"ไม่ได้เชื่อมต่อเนื่องจากเครือข่ายคุณภาพต่ำ"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"การเชื่อมต่อ Wi-Fi ล้มเหลว"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"ปัญหาในการตรวจสอบสิทธิ์"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"ไม่สามารถเชื่อมต่อ"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"ไม่สามารถเชื่อมต่อกับ \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"ตรวจสอบรหัสผ่านและลองอีกครั้ง"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"ไม่อยู่ในพื้นที่ให้บริการ"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"จะไม่เชื่อมต่อโดยอัตโนมัติ"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"ไม่สามารถเข้าถึงอินเทอร์เน็ต"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"เชื่อมต่อผ่าน %1$s แล้ว"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"พร้อมใช้งานผ่านทาง %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"เชื่อมต่อแล้ว ไม่พบอินเทอร์เน็ต"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"ช้ามาก"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"ช้า"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ตกลง"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"ปานกลาง"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"เร็ว"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"เร็วมาก"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"ตัดการเชื่อมต่อ"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"กำลังตัดการเชื่อมต่อ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"กำลังเชื่อมต่อ…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"เชื่อมต่อแล้ว (ยกเว้นเสียงสื่อ)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"เชื่อมต่อแล้ว (ไม่มีการเข้าถึงข้อความ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"เชื่อมต่อ (ยกเว้นเสียงโทรศัพท์หรือสื่อ)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"เชื่อมต่ออยู่ แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"เชื่อมต่ออยู่ (ไม่มีโทรศัพท์) แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"เชื่อมต่ออยู่ (ไม่มีสื่อ) แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"เชื่อมต่ออยู่ (ไม่มีโทรศัพท์หรือสื่อ) แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"เสียงของสื่อ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"เสียงโทรศัพท์"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"โทรศัพท์"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"การถ่ายโอนไฟล์"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"อุปกรณ์อินพุต"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"การเข้าถึงอินเทอร์เน็ต"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"การแชร์รายชื่อผู้ติดต่อ"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"ใช้สำหรับการแชร์รายชื่อผู้ติดต่อ"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"การแชร์การเชื่อมต่ออินเทอร์เน็ต"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"การเข้าถึงข้อความ"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"ข้อความ"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"การเข้าถึงซิม"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ใช้เสียงคุณภาพสูง: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ใช้เสียงคุณภาพสูง"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"เสียง HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"เสียง HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"เชื่อมต่อกับระบบเสียงของสื่อแล้ว"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"เชื่อมต่อกับระบบเสียงของโทรศัพท์แล้ว"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"เชื่อมต่อกับเซิร์ฟเวอร์สำหรับโอนไฟล์แล้ว"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"สลับ Wi‑Fi เป็นมือถือเมื่อสัญญาณอ่อน"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ใช้การสแกน Wi-Fi ข้ามเครือข่ายเสมอ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"เปิดใช้อินเทอร์เน็ตมือถือเสมอ"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"การเร่งฮาร์ดแวร์การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ปิดใช้การควบคุมระดับเสียงของอุปกรณ์อื่น"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"เปิดใช้การส่งเสียงในช่องสัญญาณเดียวกัน"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"เวอร์ชันของบลูทูธ AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"อนุญาตให้จำลองตำแหน่ง"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"เปิดใช้การตรวจสอบแอตทริบิวต์มุมมอง"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"เปิดใช้ข้อมูลมือถืออยู่เสมอ แม้ในเวลาที่ใช้งาน Wi-Fi อยู่ (สำหรับสวิตชิงเครือข่ายความเร็วสูง)"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ใช้การเร่งฮาร์ดแวร์การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ หากมี"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"อนุญาตให้แก้ไขข้อบกพร่อง USB หรือไม่"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"การแก้ไขข้อบกพร่อง USB มีไว้เพื่อการพัฒนาเท่านั้น ให้ใช้การแก้ไขนี้เพื่อคัดลอกข้อมูลระหว่างคอมพิวเตอร์และอุปกรณ์ ติดตั้งแอปพลิเคชันบนอุปกรณ์โดยไม่มีการแจ้งเตือน และอ่านข้อมูลบันทึก"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"ยกเลิกการเข้าถึงเพื่อแก้ปัญหาผ่าน USB จากคอมพิวเตอร์ทุกเครื่องที่คุณได้ให้สิทธิ์ก่อนหน้านี้ไหม"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"การแก้สี"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ฟีเจอร์นี้เป็นแบบทดลองและอาจส่งผลต่อประสิทธิภาพการทำงาน"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"แทนที่โดย <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"อีกประมาณ <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"อีก <xliff:g id="TIME">%1$s</xliff:g> จึงจะชาร์จเต็ม"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"เหลืออีก <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลือเวลาประมาณ <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลืออีก <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"อีกประมาณ <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"เหลืออีกราว <xliff:g id="TIME">^1</xliff:g> ขึ้นอยู่กับการใช้งานของคุณ"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"อีก <xliff:g id="TIME">^1</xliff:g> จึงจะชาร์จเต็ม"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"เหลืออีก <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"เหลืออีก <xliff:g id="TIME">^1</xliff:g> ขึ้นอยู่กับการใช้งานของคุณ"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - เหลือเวลาประมาณ <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - เหลืออีกราว <xliff:g id="TIME">^2</xliff:g> ขึ้นอยู่กับการใช้งานของคุณ"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - เหลืออีก <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะชาร์จเต็ม"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> จนกว่าจะชาร์จเต็ม"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"ไม่ทราบ"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"กำลังชาร์จ"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"กำลังชาร์จ"</string>
diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml
index 2a82ab6..c643e49 100644
--- a/packages/SettingsLib/res/values-tl/arrays.xml
+++ b/packages/SettingsLib/res/values-tl/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Gamitin ang Pagpili ng System (Default)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"I-enable ang Mga Opsyonal na Codec"</item>
-    <item msgid="3304843301758635896">"I-disable ang Mga Opsyonal na Codec"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Gamitin ang Pagpili ng System (Default)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"I-enable ang Mga Opsyonal na Codec"</item>
-    <item msgid="741805482892725657">"I-disable ang Mga Opsyonal na Codec"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Gamitin ang Pagpili ng System (Default)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index a2e625c..42556a0 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -28,15 +28,24 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Hindi nakakonekta dahil mababa ang kalidad ng network"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Pagkabigo ng Koneksyon sa WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problema sa pagpapatotoo"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Hindi makakonekta"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Hindi makakonekta sa \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Suriin ang password at subukang muli"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Wala sa sakop"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Hindi awtomatikong kokonekta"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Walang access sa Internet"</string>
-    <string name="saved_network" msgid="4352716707126620811">"Na-save ni <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="saved_network" msgid="4352716707126620811">"Na-save ng <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"Awtomatikong nakakonekta sa pamamagitan ng %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Awtomatikong nakakonekta sa pamamagitan ng provider ng rating ng network"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Nakakonekta sa pamamagitan ng %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Available sa pamamagitan ng %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Nakakonekta, walang Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Napakabagal"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Mabagal"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Katamtaman"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Mabilis"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Napakabilis"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Hindi nakakonekta"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Nadidiskonekta..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Kumukonekta…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Nakakonekta (walang media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Nakakonekta (walang access sa mensahe)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Nakakonekta (walang telepono o media)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Nakakonekta, baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Nakakonekta (walang telepono), baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Nakakonekta (walang media), baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Nakakonekta (walang telepono o media), baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio ng media"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audio ng telepono"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Mga tawag sa telepono"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Paglilipat ng file"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Device sa pag-input"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Access sa internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Pagbabahagi ng contact"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Gamitin para sa pagbabahagi ng contact"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Pagbabahagi ng koneksyon sa internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Access sa Mensahe"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Mga Text Message"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Access sa SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Gumamit ng mataas na kalidad na audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Gumamit ng mataas na kalidad na audio"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Konektado sa media audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Nakakonekta sa audio ng telepono"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Nakakonekta sa server sa paglilipat ng file"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresibong paglipat ng Wi‑Fi sa mobile"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Palaging payagan ang Mga Pag-scan sa Roaming ng Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Palaging aktibo ang mobile data"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardware acceleration para sa pag-tether"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"I-disable ang absolute volume"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"I-enable ang pag-ring na nasa band"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bersyon ng AVRCP ng Bluetooth"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Payagan ang mga kunwaring lokasyon"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"I-enable ang pagsisiyasat sa attribute na view"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Palaging panatilihing aktibo ang mobile data, kahit na aktibo ang Wi‑Fi (para sa mabilis na paglipat ng network)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Gamitin ang hardware acceleration para sa pag-tether kung available"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Payagan ang pag-debug ng USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Ang pag-debug ng USB ay para lang sa mga layuning pag-develop. Gamitin ito upang kumopya ng data sa pagitan ng iyong computer at iyong device, mag-install ng mga app sa iyong device nang walang notification, at magbasa ng data ng log."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Bawiin ang access sa pag-debug ng USB mula sa lahat ng computer na dati mong pinahintulutan?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Pagtatama ng kulay"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ang feature na ito ay pinag-eeksperimentuhan at maaaring makaapekto sa performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Na-override ng <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> ang natitira"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> ang natitira bago makumpleto ang charge"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> pa"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - humigit-kumulang <xliff:g id="TIME">%2$s</xliff:g> pa ang natitira"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> pa"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Humigit-kumulang <xliff:g id="TIME">^1</xliff:g> ang natitira"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Humigit-kumulang <xliff:g id="TIME">^1</xliff:g> ang natitira batay sa iyong paggamit"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> ang natitira bago makumpleto ang charge"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> pa"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> ang natitira batay sa iyong paggamit"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - humigit-kumulang <xliff:g id="TIME">^2</xliff:g> pa ang natitira"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - humigit-kumulang <xliff:g id="TIME">^2</xliff:g> ang natitira batay sa iyong paggamit"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> pa"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hanggang sa makumpleto ang charge"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> hanggang sa makumpleto ang charge"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Hindi Kilala"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Nagcha-charge"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"nagcha-charge"</string>
@@ -340,7 +358,7 @@
     <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>
-    <string name="install_other_apps" msgid="6986686991775883017">"Mag-install ng mga hindi alam na app"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"Mag-install ng di-kilalang app"</string>
     <string name="home" msgid="3256884684164448244">"Home ng Mga Setting"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml
index bb43ec7..b6d0ab2 100644
--- a/packages/SettingsLib/res/values-tr/arrays.xml
+++ b/packages/SettingsLib/res/values-tr/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Varsayılan)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Sistem Seçimini Kullan (Varsayılan)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"İsteğe Bağlı Codec\'leri Etkinleştir"</item>
-    <item msgid="3304843301758635896">"İsteğe Bağlı Codec\'leri Devre Dışı Bırak"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Sistem Seçimini Kullan (Varsayılan)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"İsteğe Bağlı Codec\'leri Etkinleştir"</item>
-    <item msgid="741805482892725657">"İsteğe Bağlı Codec\'leri Devre Dışı Bırak"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Sistem Seçimini Kullan (Varsayılan)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 5316357..b0c60f5 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Ağ kalitesi düşük olduğundan bağlanamadı"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Kablosuz Bağlantı Hatası"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Kimlik doğrulama sorunu"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Bağlanılamıyor"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\"<xliff:g id="AP_NAME">%1$s</xliff:g>\" ağına bağlanılamıyor"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Şifreyi kontrol edin ve tekrar deneyin"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Kapsama alanı dışında"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Otomatik olarak bağlanma"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"İnternet erişimi yok"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s üzerinden bağlı"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s üzerinden kullanılabilir"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Bağlı, İnternet yok"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Çok Yavaş"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Yavaş"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Tamam"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Orta"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Hızlı"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Çok Hızlı"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Bağlantı kesildi"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Bağlantı kesiliyor…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Bağlanıyor…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Bağlandı (medya yok)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Bağlı (mesaj erişimi yok)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Bağlandı (telefon veya medya yok)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Bağlandı, pil seviyesi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Bağlandı (telefon yok), pil seviyesi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Bağlandı (medya yok), pil seviyesi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Bağlandı (telefon veya medya yok), pil seviyesi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medya sesi"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefon sesi"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefon çağrıları"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Dosya aktarımı"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Giriş cihazı"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"İnternet erişimi"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kişi paylaşma"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Kişi paylaşmak için kullan"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"İnternet bağlantısı paylaşımı"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Mesaj Erişimi"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Kısa Mesajlar"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Erişimi"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Yüksek kalite ses kullan: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Yüksek kalite ses kullan"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ses: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ses"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Medya sesine bağlanıldı"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Telefon sesine bağlandı"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Dosya aktarım sunucusuna bağlandı"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Kablosuzdan mobil ağa agresif geçiş"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Kablosuz Dolaşım Taramalarına daima izin ver"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil veri her zaman etkin"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering donanım hızlandırıcısı"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Mutlak sesi iptal et"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Bant içi zil çaldırmayı etkinleştir"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Sürümü"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Sahte konumlara izin ver"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Görünüm özelliği incelemeyi etkinleştir"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Kablosuz bağlantı etkin bile olsa mobil veri kullanımını her zaman etkin tut (ağlar arasında hızlı geçiş yapmak için)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Mevcutsa, tethering donanım hızlandırıcısını kullan"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB hata ayıklamasına izin verilsin mi?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB hata ayıklaması yalnızca geliştirme amaçlıdır. Verileri bilgisayarınızla cihazınız arasında kopyalamak, bildirim göndermeksizin uygulamaları cihazınıza yüklemek ve günlük verilerini okumak için kullanın."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Daha önce yetki verdiğiniz tüm bilgisayarların USB hata ayıklama erişimini iptal etmek istiyor musunuz?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Renk düzeltme"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu özellik deneyseldir ve performansı etkileyebilir."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tarafından geçersiz kılındı"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Yaklaşık <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tam olarak şarj olmasına <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - yaklaşık <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Yaklaşık <xliff:g id="TIME">^1</xliff:g> kaldı"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Kullanımınıza dayalı olarak yaklaşık <xliff:g id="TIME">^1</xliff:g> kaldı"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tam olarak şarj olmasına <xliff:g id="TIME">^1</xliff:g> kaldı"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> kaldı"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Kullanımınıza dayalı olarak <xliff:g id="TIME">^1</xliff:g> kaldı"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - yaklaşık <xliff:g id="TIME">^2</xliff:g> kaldı"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - kullanımınıza dayalı olarak yaklaşık <xliff:g id="TIME">^2</xliff:g> kaldı"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> kaldı"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - Tam şarj olmasına <xliff:g id="TIME">^2</xliff:g> kaldı"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Bilinmiyor"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Şarj oluyor"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"şarj oluyor"</string>
diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml
index a8705e7..90629f9 100644
--- a/packages/SettingsLib/res/values-uk/arrays.xml
+++ b/packages/SettingsLib/res/values-uk/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (за умовчанням)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"acrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Використовувати вибір системи (за умовчанням)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Увімкнути додаткові кодеки"</item>
-    <item msgid="3304843301758635896">"Вимкнути додаткові кодеки"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Використовувати вибір системи (за умовчанням)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Увімкнути додаткові кодеки"</item>
-    <item msgid="741805482892725657">"Вимкнути додаткові кодеки"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Використовувати вибір системи (за умовчанням)"</item>
     <item msgid="8895532488906185219">"44,1 кГц"</item>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 5b0a6c0..28c5276 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Не під’єднано через низьку якість мережі"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Помилка з’єднання Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Проблема з автентифікацією"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Не вдається під’єднатись"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Не вдається під’єднатися до мережі <xliff:g id="AP_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Перевірте пароль і повторіть спробу"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Не в діапазоні"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Не під’єднуватиметься автоматично"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Немає доступу до Інтернету"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Під’єднано через %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Доступ через %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Під’єднано, але немає доступу до Інтернету"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Дуже повільна"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Повільна"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ОК"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Середня"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Швидка"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Дуже швидка"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Роз’єднано"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Відключення..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Підключення…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Під’єднано (без медіа-файлів)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Під’єднано (без доступу до повідомлень)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Під’єднано (без телефону чи медіа)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Під’єдано, заряд акумулятора: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Під’єднано (без телефона), заряд акумулятора: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Під’єднано (без медіа-вмісту), заряд акумулятора: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Під’єднано (без телефона та медіа-вмісту), заряд акумулятора: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Звук медіа-файлів"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Звук телефону"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефонні дзвінки"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Передавання файлів"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Пристрій введення"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Доступ до Інтернету"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Надсилання контактів"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Використовувати для надсилання контактів"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Надання доступу до Інтернету"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Доступ до повідомлень"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Текстові повідомлення"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Доступ до SIM-карти"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Використовувати аудіо високої якості: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Використовувати аудіо високої якості"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-аудіо: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-аудіо"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Підключено до аудіоджерела"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Підключено до звуку телеф."</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Підключ. до сервера передачі файлів"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Перемикатися з Wi-Fi на мобільну мережу"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Завжди шукати мережі Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Не вимикати мобільне передавання даних"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Апаратне прискорення під час використання телефона в режимі модема"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Вимкнути абсолютну гучність"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Увімкнути внутрішньосмугові сигнали"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версія Bluetooth AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Дозв. фіктивні місцезн."</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Увімкнути оцінку атрибуції переглядів"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Не вимикати мобільний Інтернет, навіть якщо ввімкнено Wi‑Fi (щоб швидше переходити між мережами)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Якщо доступно, вмикати апаратне прискорення під час використання телефона в режимі модема"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Дозвол. налагодж. USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Налагодження USB застосовується лише з метою розробки. Його можна використовувати для копіювання даних між комп’ютером і пристроєм, встановлення програм на вашому пристрої без сповіщення та читання даних журналу."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Скасувати доступ до налагодження USB для всіх комп’ютерів, які раніше отримали таке право?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекція кольору"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Це експериментальна функція. Вона може вплинути на продуктивність."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замінено на <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Залишилося близько <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"До повного зарядження залишилося <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Залишилося <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ще <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – залишилося <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Залишилося близько <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"На основі використання залишилося близько <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"До повного зарядження залишилося <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Залишилося <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"На основі використання залишилося <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – ще <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> – на основі використання залишилося близько <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – залишилося <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> до повного заряду"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Невідомо"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Заряджається"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"заряджається"</string>
diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml
index 6da98dc..321f8fe1 100644
--- a/packages/SettingsLib/res/values-ur/arrays.xml
+++ b/packages/SettingsLib/res/values-ur/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"‏AVRCP 1.4 (ڈیفالٹ)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"سسٹم انتخاب کا استعمال کریں (ڈیفالٹ)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"اختیاری کوڈیکز کو فعال کریں"</item>
-    <item msgid="3304843301758635896">"اختیاری کوڈیکز کو غیر فعال کریں"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"سسٹم انتخاب کا استعمال کریں (ڈیفالٹ)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"اختیاری کوڈیکز کو فعال کریں"</item>
-    <item msgid="741805482892725657">"اختیاری کوڈیکز کو غیر فعال کریں"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"سسٹم انتخاب کا استعمال کریں (ڈیفالٹ)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index c683995..97662edd 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"کم معیاری نیٹ ورک کی وجہ سے منسلک نہیں ہے"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"‏WiFi کنکشن کی ناکامی"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"توثیق کا مسئلہ"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"منسلک نہیں ہو سکتا ہے"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' سے منسلک نہیں ہو سکتا ہے"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"پاسورڈ چیک کر کے دوبارہ کوشش کریں"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"رینج میں نہیں ہے"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"خودکار طور پر منسلک نہیں ہو گا"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"انٹرنیٹ تک کوئی رسائی نہیں"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"‏منسلک بذریعہ ‎%1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"‏دستیاب بذریعہ ‎%1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"منسلک، انٹرنیٹ نہیں ہے"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"بہت سست"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"سست"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ٹھیک ہے"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"متوسط"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"تیز"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"بہت تیز"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"منقطع"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"منقطع کیا جارہا ہے…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"مربوط ہو رہا ہے…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"مربوط (کوئی میڈیا نہیں ہے)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"مربوط (کسی پیغام تک رسائی نہیں ہے)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"مربوط (کوئی فون یا میڈیا نہیں ہے)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"منسلک ہے، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"منسلک ہے (کوئی فون نہیں)، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"منسلک ہے (کوئی میڈیا نہیں)، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"منسلک ہے (کوئی فون یا میڈیا نہیں)، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"میڈيا آڈیو"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"فون آڈیو"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"فون کالز"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"فائل کی منتقلی"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ان پٹ آلہ"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"انٹرنیٹ تک رسائی"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"رابطہ کا اشتراک"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"رابطہ کے اشتراک کیلئے استعمال کریں"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"انٹرنیٹ کنکشن کا اشتراک کرنا"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"پیغام تک رسائی"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"ٹیکسٹ پیغامات"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"‏SIM رسائی"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"اعلی معیار کی آڈیو استعمال کریں: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"اعلی معیار کی آڈیو استعمال کریں"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"‏HD آڈیو: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"‏HD آڈیو"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"میڈیا آڈیو سے مربوط"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"فون آڈیو سے مربوط"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"فائل منتقلی سرور سے مربوط ہو گیا ہے"</string>
@@ -91,11 +104,11 @@
     <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"ہٹائی گئی ایپس"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"ہٹائی گئی ایپس اور صارفین"</string>
-    <string name="tether_settings_title_usb" msgid="6688416425801386511">"‏USB ٹیتھرنگ"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"‏USB ٹیدرنگ"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"پورٹیبل ہاٹ اسپاٹ"</string>
-    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"بلوٹوتھ ٹیتھرنگ"</string>
-    <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"ٹیتھرنگ"</string>
-    <string name="tether_settings_title_all" msgid="8356136101061143841">"ٹیتھرنگ و پورٹیبل ہاٹ اسپاٹ"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"بلوٹوتھ ٹیدرنگ"</string>
+    <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"ٹیدرنگ"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"ٹیدرنگ و پورٹیبل ہاٹ اسپاٹ"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"تمام کام کی ایپس"</string>
     <string name="user_guest" msgid="8475274842845401871">"مہمان"</string>
     <string name="unknown" msgid="1592123443519355854">"نامعلوم"</string>
@@ -149,7 +162,7 @@
     <string name="development_settings_summary" msgid="1815795401632854041">"ایپ ڈویلپمنٹ کیلئے اختیارات سیٹ کریں"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"اس صارف کیلئے ڈیولپر کے اختیارات دستیاب نہیں ہیں"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"‏VPN ترتیبات اس صارف کیلئے دستیاب نہیں ہیں"</string>
-    <string name="tethering_settings_not_available" msgid="6765770438438291012">"ٹیتھرنگ ترتیبات اس صارف کیلئے دستیاب نہیں ہیں"</string>
+    <string name="tethering_settings_not_available" msgid="6765770438438291012">"ٹیدرنگ ترتیبات اس صارف کیلئے دستیاب نہیں ہیں"</string>
     <string name="apn_settings_not_available" msgid="7873729032165324000">"رسائی کی جگہ کے نام کی ترتیبات اس صارف کیلئے دستیاب نہیں ہیں"</string>
     <string name="enable_adb" msgid="7982306934419797485">"‏USB ڈیبگ کرنا"</string>
     <string name="enable_adb_summary" msgid="4881186971746056635">"‏USB مربوط ہونے پر ڈيبگ کرنے کی وضع"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"‏Wi‑Fi سے موبائل کو جارحانہ ہینڈ اوور"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏ہمیشہ Wi‑Fi روم اسکینز کی اجازت دیں"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"موبائل ڈیٹا ہمیشہ فعال رکھیں"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ٹیدرنگ ہارڈویئر سرعت کاری"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"مطلق والیوم کو غیر فعال کریں"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ان بینڈ رنگنگ فعال کریں"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"‏بلوٹوتھ AVRCP ورژن"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"فرضی مقامات کی اجازت دیں"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"منظر انتساب کے معائنہ کو فعال کریں"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"‏Wi‑Fi فعال ہونے پر بھی موبائل ڈیٹا کو ہمیشہ فعال رکھیں (تیزی سے نیٹ ورک سوئچ کرنے کیلئے)۔"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"اگر دستیاب ہو تو ٹیدرنگ ہارڈویئر سرعت کاری کا استعمال کریں"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"‏USB ڈیبگ کرنے کی اجازت دیں؟"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"‏USB ڈیبگ کرنا صرف ڈیولپمنٹ کے مقاصد کیلئے ہے۔ اپنے کمپیوٹر اور اپنے آلہ کے درمیان ڈیٹا کاپی کرنے کیلئے اسے استعمال کریں، بغیر اطلاع کے اپنے آلہ پر ایپس انسٹال کریں اور لاگ ڈیٹا پڑھیں۔"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"‏اپنے ذریعہ پہلے سے اجازت یافتہ سبھی کمپیوٹرز سے USB ڈیبگ کرنے کی رسائی کو کالعدم کریں؟"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"رنگ کی اصلاح"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"یہ خصوصیت تجرباتی ہے اور اس کی وجہ سے کاکردگی متاثر ہو سکتی ہے۔"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> کے ذریعہ منسوخ کردیا گیا"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"تقریبًا <xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"پوری طرح چارج ہونے میں <xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"تقریبًا <xliff:g id="TIME">^1</xliff:g> باقی ہے"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"آپ کے استعمال کی بنیاد پر تقریباً <xliff:g id="TIME">^1</xliff:g> باقی ہے"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"پوری طرح چارج ہونے میں <xliff:g id="TIME">^1</xliff:g> باقی ہے"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> باقی ہے"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"آپ کے استعمال کی بنیاد پر <xliff:g id="TIME">^1</xliff:g> باقی ہے"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - تقریباً <xliff:g id="TIME">^2</xliff:g> باقی ہے"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - آپ کے استعمال کی بنیاد پر تقریباً <xliff:g id="TIME">^2</xliff:g> باقی ہے"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> پوری طرح چارج ہونے تک"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> پوری طرح چارج ہونے تک"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"نامعلوم"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"چارج ہو رہا ہے"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"چارج ہو رہا ہے"</string>
diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml
index 1d4e1e9..847489e 100644
--- a/packages/SettingsLib/res/values-uz/arrays.xml
+++ b/packages/SettingsLib/res/values-uz/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (asosiy)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Tizim tanlovi (birlamchi)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Boshqa kodeklarni yoqish"</item>
-    <item msgid="3304843301758635896">"Boshqa kodeklarni o‘chirib qo‘yish"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Tizim tanlovi (birlamchi)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Boshqa kodeklarni yoqish"</item>
-    <item msgid="741805482892725657">"Boshqa kodeklarni o‘chirib qo‘yish"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Tizim tanlovi (birlamchi)"</item>
     <item msgid="8895532488906185219">"44.1 kGs"</item>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index ed62041..9399db6 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Sifatsiz tarmoq sababli ulanib bo‘lmadi"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi ulanishini o‘rnatib bo‘lmadi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Tasdiqdan o‘tishda muammo"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Tarmoqqa ulanilmadi"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"“<xliff:g id="AP_NAME">%1$s</xliff:g>” nomli tarmoqqa ulanilmadi"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Parolni tekshirib, qaytadan urining"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Xizmat doirasidan tashqarida"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Avtomatik ravishda ulanilmaydi"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Internet aloqasi yo‘q"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s orqali ulangan"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s orqali ishlaydi"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Ulangan, lekin internet aloqasi yo‘q"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Juda sekin"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Sekin"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"O‘rtacha"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Tez"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Juda tez"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Uzildi"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Uzilyapti…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Ulanmoqda…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Ulanildi (mediadan tashqari)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Ulangan (xabarlarga kirib bo‘lmaydi)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Ulangan (telefon yoki media qurilma emas)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Ulangan, batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Ulangan (HSP/HFP dan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Ulangan (A2DP dan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Ulangan (HSP/HFP/A2DP dan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefon audiosi"</string>
-    <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fayl o‘tkazish"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefon chaqiruvlari"</string>
+    <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fayl uzatish"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Kiritish qurilmasi"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetga kirish"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktlarni ulashish"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Kontaktlarni ulashish uchun ishlatilsin"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internet aloqasi ulashmasi"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Xabarga kirish"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"SMS xabarlari"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-kartaga kirish"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Yuqori sifatli audiodan foydalanish: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Yuqori sifatli audiodan foydalanish"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Audio qurilmasiga ulangan"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Telefon karnayiga ulanildi"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Fayl almashinish serveriga ulanildi"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mobil internetga o‘tish"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi tarmoqlarini qidirishga doim ruxsat"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil internet doim yoniq tursin"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Modem rejimida apparatli tezlashtirish"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Ovoz balangligining mutlaq darajasini o‘chirib qo‘yish"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Bitta liniyada jiringlashni yoqish"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP versiyasi"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Joylashuv emulyatsiyasiga ruxsat berish"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Alomatlar tekshiruvini yoqish"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mobil internet har doim yoniq tursin, hatto Wi-Fi yoniq bo‘lsa ham (bir tarmoqdan ikkinchisiga tezroq o‘tish uchun)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Modem rejimida apparatli tezlashtirishdan foydalanish (agar mavjud bo‘lsa)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB orqali nosozliklarni tuzatishga ruxsat berilsinmi?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB orqali nosozliklarni tuzatish faqat dasturlash maqsadlarida yoqiladi. Undan ma‘lumotlarni qurilmangiz va kompyuter o‘rtasida ko‘chirish, ilovalarni xabarnomasiz o‘rnatish va jurnal ma‘lumotlarini o‘qish uchun foydalaniladi."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"USB orqali nosozliklarni tuzatishga berilgan ruxsat siz hisobingizga kirgan barcha kompyuterlar uchun bekor qilinsinmi?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Rangni tuzatish"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya tajribaviy bo‘lib, u qurilma unumdorligiga ta’sir qilishi mumkin."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> bilan almashtirildi"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"To‘lishiga <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Taxminan <xliff:g id="TIME">^1</xliff:g> qoldi"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Joriy holatda taxminan <xliff:g id="TIME">^1</xliff:g> qoldi"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"To‘lishiga <xliff:g id="TIME">^1</xliff:g> qoldi"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> qoldi"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Joriy holatda <xliff:g id="TIME">^1</xliff:g> qoldi"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – taxminan <xliff:g id="TIME">^2</xliff:g> qoldi"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> (joriy holatda taxminan <xliff:g id="TIME">^2</xliff:g> qoldi)"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> qoldi"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> ichida to‘ladi"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> ichida to‘ladi"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Noma’lum"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Quvvat olmoqda"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"quvvat olmoqda"</string>
diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml
index 134dc8b..3c2b584 100644
--- a/packages/SettingsLib/res/values-vi/arrays.xml
+++ b/packages/SettingsLib/res/values-vi/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (Mặc định)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Sử dụng lựa chọn hệ thống (Mặc định)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"Bật codec tùy chọn"</item>
-    <item msgid="3304843301758635896">"Tắt codec tùy chọn"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Sử dụng lựa chọn hệ thống (Mặc định)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"Bật codec tùy chọn"</item>
-    <item msgid="741805482892725657">"Tắt codec tùy chọn"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Sử dụng lựa chọn hệ thống (Mặc định)"</item>
     <item msgid="8895532488906185219">"44,1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index c91e89c..db2b29d 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Không được kết nối do mạng chất lượng kém"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Lỗi kết nối WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Sự cố xác thực"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Không thể kết nối"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Không thể kết nối với \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Kiểm tra mật khẩu và thử lại"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Ngoài vùng phủ sóng"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Sẽ không tự động kết nối"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Không có quyền truy cập Internet"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Được kết nối qua %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Có sẵn qua %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Đã kết nối, không có Internet"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Rất chậm"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Chậm"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"Khá tốt"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Trung bình"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Nhanh"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Rất nhanh"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Đã ngắt kết nối"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Đang ngắt kết nối…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Đang kết nối…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Đã kết nối (không có phương tiện)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Đã kết nối (không truy cập tin nhắn)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Đã k.nối (kg có ĐT hoặc p.tiện nào)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Đã kết nối, mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Đã kết nối (không có điện thoại), mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Đã kết nối (không có phương tiện), mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Đã kết nối (không có điện thoại hoặc phương tiện), mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Âm thanh của phương tiện"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Âm thanh điện thoại"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Cuộc gọi điện thoại"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Chuyển tệp"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Thiết bị đầu vào"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Truy cập Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Chia sẻ liên hệ"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Sử dụng để chia sẻ liên hệ"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Chia sẻ kết nối internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Truy cập tin nhắn"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Tin nhắn văn bản"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Quyền truy cập SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Sử dụng âm thanh chất lượng cao: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Sử dụng âm thanh chất lượng cao"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Âm thanh HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Âm thanh HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Đã kết nối với âm thanh phương tiện"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Đã kết nối với âm thanh điện thoại"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Đã kết nối với máy chủ chuyển tệp"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Chuyển vùng Wi‑Fi tích cực sang mạng DĐ"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Luôn cho phép quét chuyển vùng Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dữ liệu di động luôn hiện hoạt"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tăng tốc phần cứng cho chia sẻ kết nối"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Vô hiệu hóa âm lượng tuyệt đối"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Bật đổ chuông trong dải"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth phiên bản AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Cho phép vị trí mô phỏng"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Cho phép kiểm tra thuộc tính của chế độ xem"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Luôn giữ cho dữ liệu di động hoạt động, ngay cả khi Wi-Fi đang hoạt động (để chuyển đổi mạng nhanh)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Sử dụng tăng tốc phần cứng cho chia sẻ kết nối nếu được"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Cho phép gỡ lỗi USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Gỡ lỗi USB chỉ dành cho mục đích phát triển. Hãy sử dụng tính năng này để sao chép dữ liệu giữa máy tính và thiết bị của bạn, cài đặt ứng dụng trên thiết bị của bạn mà không thông báo và đọc dữ liệu nhật ký."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Thu hồi quyền truy cập gỡ lỗi USB từ tất cả máy tính mà bạn đã ủy quyền trước đó?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Sửa màu"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Tính năng này là tính năng thử nghiệm và có thể ảnh hưởng đến hoạt động."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Bị ghi đè bởi <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Còn khoảng <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Còn <xliff:g id="TIME">%1$s</xliff:g> cho tới khi được sạc đầy"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Còn lại <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn khoảng <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn lại <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Còn khoảng <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Còn khoảng <xliff:g id="TIME">^1</xliff:g> dựa trên mức sử dụng của bạn"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Còn <xliff:g id="TIME">^1</xliff:g> cho tới khi được sạc đầy"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Còn lại <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Còn <xliff:g id="TIME">^1</xliff:g> dựa trên mức sử dụng của bạn"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - còn khoảng <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - còn khoảng <xliff:g id="TIME">^2</xliff:g> dựa trên mức sử dụng của bạn"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - còn lại <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho tới khi được sạc đầy"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> cho tới khi được sạc đầy"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Không xác định"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Đang sạc"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"đang sạc"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
index fadc7a9..4599951 100644
--- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4(默认)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"使用系统选择(默认)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"启用可选编解码器"</item>
-    <item msgid="3304843301758635896">"停用可选编解码器"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"使用系统选择(默认)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"启用可选编解码器"</item>
-    <item msgid="741805482892725657">"停用可选编解码器"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"使用系统选择(默认)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 10a077b..1fe8778 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"网络质量较差,因此未连接"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WLAN 连接失败"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"身份验证出现问题"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"无法连接"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"无法连接到“<xliff:g id="AP_NAME">%1$s</xliff:g>”"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"请检查密码,然后重试"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"不在范围内"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"无法自动连接"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"无法连接到互联网"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"已通过%1$s连接"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"可通过%1$s连接"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"已连接,但无法访问互联网"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"很慢"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"慢"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"良好"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"适中"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"快"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"很快"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"已断开连接"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"正在断开连接..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"正在连接..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"已连接(无媒体)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"已连接(无消息权限)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"已连接(没有手机或媒体信号)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"已连接,电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"已连接(无手机),电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"已连接(无媒体),电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"已连接(无手机或媒体),电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"媒体音频"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"手机音频"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"通话"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"文件传输"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"输入设备"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"互联网连接"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"共享联系人"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"用于共享联系人"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"共享互联网连接"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"消息权限"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"短信"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 卡存取权限"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"使用高品质音频:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"使用高品质音频"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD 音频:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD 音频"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"已连接到媒体音频"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"已连接到手机音频"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"已连接到文件传输服务器"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"主动从 WLAN 网络切换到移动数据网络"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"一律允许WLAN漫游扫描"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"始终开启移动数据网络"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"网络共享硬件加速"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用绝对音量功能"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"启用手机默认铃声"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"蓝牙 AVRCP 版本"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"允许模拟位置"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"启用视图属性检查功能"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"始终开启移动数据网络,即使 WLAN 网络已开启(便于快速切换网络)。"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"使用网络共享硬件加速功能(如果可用)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"是否允许 USB 调试?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB 调试仅用于开发目的。该功能可用于在您的计算机和设备之间复制数据、在您的设备上安装应用(事先不发通知)以及读取日志数据。"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"是否针对您之前授权的所有计算机撤消 USB 调试的访问权限?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色彩校正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"这是实验性功能,性能可能不稳定。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已被“<xliff:g id="TITLE">%1$s</xliff:g>”覆盖"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"还剩大约 <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"还需 <xliff:g id="TIME">%1$s</xliff:g>充满电"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"还可用 <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 大约还剩 <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还可用 <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"还剩大约 <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"根据您的使用情况,大约还可使用 <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"还需 <xliff:g id="TIME">^1</xliff:g>充满电"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"还可用 <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"根据您的使用情况,大约还可使用 <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - 大约还剩 <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - 根据您的使用情况,大约还可使用 <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - 还可用 <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需 <xliff:g id="TIME">%2$s</xliff:g>充满"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - 还需 <xliff:g id="TIME">^2</xliff:g>充满"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"未知"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"正在充电"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"正在充电"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/arrays.xml b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
index 7f4c427..f700e86 100644
--- a/packages/SettingsLib/res/values-zh-rHK/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
@@ -22,7 +22,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wifi_status">
     <item msgid="1922181315419294640"></item>
-    <item msgid="8934131797783724664">"掃瞄中…"</item>
+    <item msgid="8934131797783724664">"掃描中…"</item>
     <item msgid="8513729475867537913">"正在連線..."</item>
     <item msgid="515055375277271756">"正在驗證…"</item>
     <item msgid="1943354004029184381">"正在取得 IP 位址…"</item>
@@ -36,7 +36,7 @@
   </string-array>
   <string-array name="wifi_status_with_ssid">
     <item msgid="7714855332363650812"></item>
-    <item msgid="8878186979715711006">"掃瞄中…"</item>
+    <item msgid="8878186979715711006">"掃描中…"</item>
     <item msgid="355508996603873860">"正在連線到 <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
     <item msgid="554971459996405634">"正在取得 <xliff:g id="NETWORK_NAME">%1$s</xliff:g> 的授權…"</item>
     <item msgid="7928343808033020343">"正在從 <xliff:g id="NETWORK_NAME">%1$s</xliff:g> 取得 IP 位址…"</item>
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (預設)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"使用系統選擇 (預設)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"啟用選用的編解碼器"</item>
-    <item msgid="3304843301758635896">"停用選用的編解碼器"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"使用系統選擇 (預設)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"啟用選用的編解碼器"</item>
-    <item msgid="741805482892725657">"停用選用的編解碼器"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"使用系統選擇 (預設)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index accfb3f..9d608cc 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_fail_to_scan" msgid="1265540342578081461">"無法掃瞄網絡"</string>
+    <string name="wifi_fail_to_scan" msgid="1265540342578081461">"無法掃描網絡"</string>
     <string name="wifi_security_none" msgid="7985461072596594400">"無"</string>
     <string name="wifi_remembered" msgid="4955746899347821096">"已儲存"</string>
     <string name="wifi_disabled_generic" msgid="4259794910584943386">"已停用"</string>
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"網絡品質欠佳,因此無法連線"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi 連線失敗"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"驗證問題"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"無法連線"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"無法連線至「<xliff:g id="AP_NAME">%1$s</xliff:g>」"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"請檢查密碼,然後再試一次"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"超出可用範圍"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"不會自動連線"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"無法偵測互聯網連線"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"已透過 %1$s 連線"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"可透過 %1$s 連線"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"已連線,沒有互聯網"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"非常慢"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"慢"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"良好"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"適中"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"快"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"非常快"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"已中斷連線"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"正在中斷連線..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"正在連線..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"已連線 (無媒體)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"已連結 (無訊息存取權)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"已連線 (無手機或媒體)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"已連線,電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"已連線 (沒有手機),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"已連線 (沒有媒體音訊),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"已連線 (沒有手機或媒體音訊),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"媒體音效"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"手機音效"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"通話"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"檔案傳輸"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"輸入裝置"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"互聯網連線"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"共用聯絡人"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"用於共用聯絡人"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"互聯網連線分享"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"訊息存取權"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"短訊"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 卡存取"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"使用優質音訊編解碼器:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"使用優質音訊編解碼器"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"高清音訊:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"高清音訊"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"已連接媒體音頻裝置"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"已連接手機耳機"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"已連線至檔案傳輸伺服器"</string>
@@ -171,8 +184,9 @@
     <string name="wifi_display_certification" msgid="8611569543791307533">"無線螢幕分享認證"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"啟用 Wi‑Fi 詳細記錄"</string>
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"加強 Wi-Fi 至流動數據轉換"</string>
-    <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"永遠允許 Wi-Fi 漫遊掃瞄"</string>
+    <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"永遠允許 Wi-Fi 漫遊掃描"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"一律保持啟用流動數據"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"網絡共享硬件加速"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用絕對音量功能"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"啟用頻內鈴聲"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"藍牙 AVRCP 版本"</string>
@@ -191,7 +205,7 @@
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細紀錄"</string>
     <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"啟用後,Wi-Fi 連線會在訊號不穩定的情況下更積極轉換成流動數據連線"</string>
-    <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"根據介面中目前的數據流量允許/禁止 WiFi 漫遊掃瞄"</string>
+    <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"根據介面中目前的數據流量允許/禁止 WiFi 漫遊掃描"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"記錄器緩衝區空間"</string>
     <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"選取每個記錄緩衝區的記錄器空間"</string>
     <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"要清除記錄器的持久儲存空間嗎?"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"允許模擬位置"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"啟用檢視屬性檢查"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"即使 Wi‑Fi 已啟用,仍永遠啟用流動數據 (可快速切換網絡)。"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"使用網絡共享硬件加速功能 (如果可用)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"允許 USB 偵錯嗎?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB 偵錯是針對應用程式開發而設計的功能,可讓您在電腦與裝置間複製資料、不用通知即可在裝置上安裝應用程式,以及讀取記錄資料。"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"要針對先前授權的所有電腦撤銷 USB 偵錯存取權嗎?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色彩校正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是實驗性功能,效能尚待改善。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"剩餘約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g>後就能充滿電"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"尚餘 <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 剩餘約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 尚餘 <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"剩餘約 <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"根據您的使用情況,剩餘約 <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g>後就能充滿電"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"尚餘 <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"根據您的使用情況,剩餘 <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - 剩餘約 <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - 根據您的使用情況,剩餘約 <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - 尚餘 <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還需 <xliff:g id="TIME">%2$s</xliff:g>才能充滿電"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - 還需 <xliff:g id="TIME">^2</xliff:g>才能充滿電"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"未知"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"正在充電"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
index 0f3bf23..a62151b 100644
--- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"AVRCP 1.4 (預設)"</item>
-    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"avrcp14"</item>
-    <item msgid="1913619118958233129">"avrcp15"</item>
-    <item msgid="7142710449249088270">"avrcp16"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"使用系統選擇 (預設)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"LDAC"</item>
-    <item msgid="723675059572222462">"啟用選用的轉碼器"</item>
-    <item msgid="3304843301758635896">"停用選用的轉碼器"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"使用系統選擇 (預設)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"LDAC"</item>
-    <item msgid="2209680154067241740">"啟用選用的轉碼器"</item>
-    <item msgid="741805482892725657">"停用選用的轉碼器"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"使用系統選擇 (預設)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 9a0b1bf..0b7c3fa 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -28,15 +28,24 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"網路品質不佳,因此未連線"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi 連線失敗"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"驗證問題"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"無法連線"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"無法連線至「<xliff:g id="AP_NAME">%1$s</xliff:g>」"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"請檢查密碼,然後再試一次"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"不在有效範圍內"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"無法自動連線"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"沒有可用的網際網路連線"</string>
-    <string name="saved_network" msgid="4352716707126620811">"由<xliff:g id="NAME">%1$s</xliff:g>儲存"</string>
+    <string name="saved_network" msgid="4352716707126620811">"由「<xliff:g id="NAME">%1$s</xliff:g>」儲存"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"已透過 %1$s 自動連線"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"已透過網路評分供應商自動連線"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"已透過 %1$s 連線"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"可透過 %1$s 使用"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"已連線,沒有網際網路"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"非常慢"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"慢"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"確定"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"適中"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"快"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"非常快"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"已中斷連線"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"正在中斷連線…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"連線中…"</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"已連線 (無媒體音訊)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"已連線 (無訊息存取權)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"已連線 (無手機或媒體音訊)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"已連線,電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"已連線 (無手機),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"已連線 (無媒體音訊),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"已連線 (無手機或媒體音訊),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"媒體音訊"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"手機音訊"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"通話"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"檔案傳輸"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"輸入裝置"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"網際網路連線"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"聯絡人共用"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"用於聯絡人共用"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"網際網路連線分享"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"訊息存取權"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"簡訊"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 卡存取權"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"使用高品質音訊:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"使用高品質音訊"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD 高解析音訊:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD 高解析音訊"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"連接至媒體音訊"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"連接至電話音訊"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"已連線到檔案傳輸伺服器"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi 至行動數據轉換強化"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"一律允許 Wi-Fi 漫遊掃描"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"行動數據連線一律保持啟用狀態"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"數據連線硬體加速"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用絕對音量功能"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"啟用藍牙同步鈴聲功能"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"藍牙 AVRCP 版本"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"允許模擬位置"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"啟用檢視屬性檢查"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"即使 Wi‑Fi 連線已啟用,一律將行動數據連線保持啟用狀態 (以便快速切換網路)。"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"使用數據連線硬體加速功能 (如果可用的話)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"允許 USB 偵錯嗎?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB 偵錯是針對應用程式開發而設計的功能,可讓你複製電腦和裝置中的資料、不需經由通知即可在裝置上安裝應用程式,以及讀取記錄資料。"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"要針對先前授權的所有電腦撤銷 USB 偵錯權限嗎?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色彩校正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是一項實驗性功能,可能會對效能造成影響。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已改為<xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"還有大約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"再過 <xliff:g id="TIME">%1$s</xliff:g>就能完成充電"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"還剩 <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 約剩 <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還剩 <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"還有大約 <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"根據你的使用情形,剩餘時間大約還有 <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"再過 <xliff:g id="TIME">^1</xliff:g>就能完成充電"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"還剩 <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"根據你的使用情形,剩餘時間還有 <xliff:g id="TIME">^1</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - 約剩 <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - 根據你的使用情形,剩餘時間大約還有 <xliff:g id="TIME">^2</xliff:g>"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - 還剩 <xliff:g id="TIME">^2</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>後充飽"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"不明"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"充電中"</string>
diff --git a/packages/SettingsLib/res/values-zu/arrays.xml b/packages/SettingsLib/res/values-zu/arrays.xml
index d7449f1..cbec89f 100644
--- a/packages/SettingsLib/res/values-zu/arrays.xml
+++ b/packages/SettingsLib/res/values-zu/arrays.xml
@@ -60,34 +60,20 @@
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
     <item msgid="5347678900838034763">"I-AVRCP 1.4 (Okuzenzakalelayo)"</item>
-    <item msgid="2089555299377409443">"I-AVRCP 1.5"</item>
-    <item msgid="2895327394279434278">"I-AVRCP 1.6"</item>
+    <item msgid="2809759619990248160">"I-AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"I-AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"I-AVRCP 1.6"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_version_values">
     <item msgid="2838624067805073303">"I-avrcp14"</item>
-    <item msgid="1913619118958233129">"I-avrcp15"</item>
-    <item msgid="7142710449249088270">"I-avrcp16"</item>
+    <item msgid="3011533352527449572">"I-avrcp13"</item>
+    <item msgid="8837606198371920819">"I-avrcp15"</item>
+    <item msgid="3422726142222090896">"I-avrcp16"</item>
   </string-array>
-  <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Sebenzisa ukukhetha kwesistimu (Okuzenzakalelayo)"</item>
-    <item msgid="7539690996561263909">"SBC"</item>
-    <item msgid="686685526567131661">"I-AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
-    <item msgid="6751080638867012696">"I-LDAC"</item>
-    <item msgid="723675059572222462">"Nika amandla amakhodekhi akhethekayo"</item>
-    <item msgid="3304843301758635896">"Khubaza amakhodekhi akhethekayo"</item>
-  </string-array>
-  <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Sebenzisa ukukhetha kwesistimu (Okuzenzakalelayo)"</item>
-    <item msgid="6898329690939802290">"SBC"</item>
-    <item msgid="6839647709301342559">"I-AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
-    <item msgid="7950781694447359344">"I-LDAC"</item>
-    <item msgid="2209680154067241740">"Nika amandla amakhodekhi akhethekayo"</item>
-    <item msgid="741805482892725657">"Khubaza amakhodekhi akhethekayo"</item>
-  </string-array>
+    <!-- no translation found for bluetooth_a2dp_codec_titles:3 (965655874372831982) -->
+    <!-- no translation found for bluetooth_a2dp_codec_titles:4 (1736964107585972103) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:3 (3558743545747527853) -->
+    <!-- no translation found for bluetooth_a2dp_codec_summaries:4 (9167103241281353659) -->
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Sebenzisa ukukhetha kwesistimu (Okuzenzakalelayo)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index bdd4bf2..f3c27a1 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -28,6 +28,9 @@
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Ayixhunyiwe ngenxa yenethiwekhi yekhwalithi ephansi"</string>
     <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Ukwehlulekla koxhumo le-WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Inkinga yokufakazela ubuqiniso"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"Ayikwazi ukuxhuma"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Ayikwazi ukuxhumeka ku-\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"Hlola iphasiwedi uphinde uzame futhi"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Ayikho ebubanzini"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Ngeke ize ixhumeke ngokuzenzakalela"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Akukho ukufinyelela ku-inthanethi"</string>
@@ -37,6 +40,12 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Kuxhumeke nge-%1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Iyatholakala nge-%1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Kuxhumekile, ayikho i-inthanethi"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"Phansi kakhulu"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"Phansi"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"KULUNGILE"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"Okumaphakathi"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"Sheshayo"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"Kushesha kakhulu"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Ayixhunyiwe"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Inqamula uxhumano kwi-inthanethi..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Iyaxhuma..."</string>
@@ -46,18 +55,22 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Ixhunyiwe (ayikho imidiya)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Kuxhunyiwe (akukho ukufinyelela umlayezo)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Ixhunyiwe (ayikho ifoni noma imidiya)"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Kuxhunyiwe, ibhethri elingu-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Kuxhunyiwe (ayikho ifoni), ibhethri lingu-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Kuxhunyiwe (ayikho imidiya), ibhethri lingu-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Kuxhunyiwe (ayikho ifoni noma imidiya), ibhethri lingu-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Umsindo wemidiya"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Umsindo wefoni"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Amakholi efoni"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Dlulisa ifayela"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Idivaysi yokufakwayo"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Ukufinyelela i-Inthanethi"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Ukwabelana kokuxhumana"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Sebenzisela ukwabelana kokuxhumana"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Ukwabelana ngoxhumano lwe-Inthanethi"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Ukufinyelela umlayezo"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"Imilayezo yombhalo"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Ukufinyelela kwe-SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Sebenzisa umsindo wekhwalithi ephezulu: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Sebenzisa umsindo wekhwalithi ephezulu"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Umsindo we-HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Umsindo we-HD"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Ixhume emsindweni wemidiya"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Ixhunywe kumsindo wefoni"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Ixhunywe kwiseva yokudlulisa ifayela"</string>
@@ -173,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Ukudluliselwa okunamandla kakhulu kwe-Wi-Fi ukuya kuselula"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vumela njalo ukuskena kokuzula kwe-Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Idatha yeselula ihlala isebenza"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"I-Tethering hardware acceleration"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Khubaza ivolumu ngokuphelele"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Nika amandla ukukhala okuphakathi nomkhiqizo"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Inguqulo ye-Bluetooth ye-AVRCP"</string>
@@ -204,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Vumela izindawo mbumbulu"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Nika amandla ukubuka"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Hlala ugcine idatha yeselula isebenza, nanoma i-Wi-Fi isebenza (ngokushintshwa kwenethiwekhi okusheshayo)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Sebenzisa i-tethering hardware acceleration uma itholakala"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Vumela ukulungisa iphutha le-USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Ukulungisa iphutha le-USB kuhloselwe izinjongo zokuthuthukisa kuphela. Ingasebenziselwa ukukopisha idatha phakathi kwekhompyutha yakho nedivaysi yakho, faka izinhlelo zokusebenza kwidivaysi yakho ngaphandle kwesaziso, bese ufunda idatha yefayela lokungena."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Buyisa ukufinyelela ekususeni iphutha le-USB kusuka kuwo wonke amakhompyutha owagunyaze ngaphambilini?"</string>
@@ -320,14 +335,17 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Ukulungiswa kombala"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Lesi sici esesilingo futhi singathinta ukusebenza."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Igitshezwe ngaphezulu yi-<xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="845431008899029842">"Cishe u-<xliff:g id="TIME">%1$s</xliff:g> osele"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> kushiywe ishaja"</string>
-    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> esisele"</string>
-    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - cishe ngu-<xliff:g id="TIME">%2$s</xliff:g> osele"</string>
-    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> okusele"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Cishe u-<xliff:g id="TIME">^1</xliff:g> osele"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Cishe kusele okungu-<xliff:g id="TIME">^1</xliff:g> kusukela ekusetshenzisweni kwakho"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> kushiywe ishaja"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> esisele"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> esele kusukela ekusetshenzisweni kwakho"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - cishe ngu-<xliff:g id="TIME">^2</xliff:g> osele"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - cishe ngu-<xliff:g id="TIME">^2</xliff:g> osele kusukela ekusetshenzisweni kwakho"</string>
+    <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> okusele"</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_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze ligcwale ngokuphelele"</string>
-    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> kuze ligcwale ngokuphelele"</string>
+    <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Akwaziwa"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Iyashaja"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"iyashaja"</string>
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index db3274a..9704bd6 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -105,6 +105,7 @@
     <!-- Titles for Bluetooth AVRCP Versions -->
     <string-array name="bluetooth_avrcp_versions">
         <item>AVRCP 1.4 (Default)</item>
+        <item>AVRCP 1.3</item>
         <item>AVRCP 1.5</item>
         <item>AVRCP 1.6</item>
     </string-array>
@@ -112,6 +113,7 @@
     <!-- Values for Bluetooth AVRCP Versions -->
     <string-array name="bluetooth_avrcp_version_values">
         <item>avrcp14</item>
+        <item>avrcp13</item>
         <item>avrcp15</item>
         <item>avrcp16</item>
     </string-array>
@@ -121,8 +123,8 @@
         <item>Use System Selection (Default)</item>
         <item>SBC</item>
         <item>AAC</item>
-        <item>aptX</item>
-        <item>aptX HD</item>
+        <item><xliff:g id="aptx">Qualcomm(R) aptX(TM) audio</xliff:g></item>
+        <item><xliff:g id="aptx_hd">Qualcomm(R) aptX(TM) HD audio</xliff:g></item>
         <item>LDAC</item>
         <item>Enable Optional Codecs</item>
         <item>Disable Optional Codecs</item>
@@ -145,8 +147,8 @@
         <item>Use System Selection (Default)</item>
         <item>SBC</item>
         <item>AAC</item>
-        <item>aptX</item>
-        <item>aptX HD</item>
+        <item><xliff:g id="aptx">Qualcomm(R) aptX(TM) audio</xliff:g></item>
+        <item><xliff:g id="aptx_hd">Qualcomm(R) aptX(TM) HD audio</xliff:g></item>
         <item>LDAC</item>
         <item>Enable Optional Codecs</item>
         <item>Disable Optional Codecs</item>
diff --git a/packages/SettingsLib/res/values/attrs.xml b/packages/SettingsLib/res/values/attrs.xml
index ea538fb..6d852df 100644
--- a/packages/SettingsLib/res/values/attrs.xml
+++ b/packages/SettingsLib/res/values/attrs.xml
@@ -46,12 +46,11 @@
     <attr name="wifi_signal" format="reference" />
     <attr name="wifi_friction" format="reference" />
 
-    <declare-styleable name="UsageView">
-        <attr name="android:colorAccent" />
-        <attr name="sideLabels" format="reference" />
-        <attr name="bottomLabels" format="reference" />
-        <attr name="textColor" format="color" />
-        <attr name="android:gravity" />
+    <attr name="footerPreferenceStyle" format="reference" />
+
+    <declare-styleable name="PreferenceImageView">
+        <attr name="maxWidth" format="dimension" />
+        <attr name="maxHeight" format="dimension" />
     </declare-styleable>
 
 </resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 8f7a3dd..a73f800 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -64,6 +64,14 @@
     <!-- Status for networks disabled from authentication failure (wrong password
          or certificate). -->
     <string name="wifi_disabled_password_failure">Authentication problem</string>
+
+    <!-- Status detail for a network that can't be connected to for some reason -->
+    <string name="wifi_cant_connect">Can\'t connect</string>
+    <!-- Status for a named network that can't be connected to for some reason-->
+    <string name="wifi_cant_connect_to_ap">Can\'t connect to \'<xliff:g id="ap_name">%1$s</xliff:g>\'</string>
+    <!-- Message shown when the user likely entered an incorrect password for a wifi network -->
+    <string name="wifi_check_password_try_again">Check password and try again</string>
+
     <!-- Summary for the remembered network but currently not in range. -->
     <string name="wifi_not_in_range">Not in range</string>
     <!-- Summary for the network but no internet connection was detected. -->
@@ -89,6 +97,19 @@
     <!-- Summary for Connected wifi network without internet -->
     <string name="wifi_connected_no_internet">Connected, no Internet</string>
 
+    <!-- Speed label for very slow network speed -->
+    <string name="speed_label_very_slow">Very Slow</string>
+    <!-- Speed label for slow network speed -->
+    <string name="speed_label_slow">Slow</string>
+    <!-- Speed label for okay network speed -->
+    <string name="speed_label_okay">OK</string>
+    <!-- Speed label for medium network speed -->
+    <string name="speed_label_medium">Medium</string>
+    <!-- Speed label for fast network speed -->
+    <string name="speed_label_fast">Fast</string>
+    <!-- Speed label for very fast network speed -->
+    <string name="speed_label_very_fast">Very Fast</string>
+
     <!-- Bluetooth settings.  Message when a device is disconnected -->
     <string name="bluetooth_disconnected">Disconnected</string>
     <!-- Bluetooth settings.  Message when disconnecting from a device -->
@@ -109,10 +130,19 @@
     <!-- Bluetooth settings.  Message when connected to a device, except for phone/media audio. [CHAR LIMIT=40] -->
     <string name="bluetooth_connected_no_headset_no_a2dp">Connected (no phone or media)</string>
 
+    <!-- Bluetooth settings.  Message when connected to a device, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_connected_battery_level">Connected, battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
+    <!-- Bluetooth settings.  Message when connected to a device, except for phone audio, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_connected_no_headset_battery_level">Connected (no phone), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
+    <!-- Bluetooth settings.  Message when connected to a device, except for media audio, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_connected_no_a2dp_battery_level">Connected (no media), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
+    <!-- Bluetooth settings.  Message when connected to a device, except for phone/media audio, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level">Connected (no phone or media), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
+
     <!-- Bluetooth settings.  The user-visible string that is used whenever referring to the A2DP profile. -->
     <string name="bluetooth_profile_a2dp">Media audio</string>
     <!-- Bluetooth settings.  The user-visible string that is used whenever referring to the headset or handsfree profile. -->
-    <string name="bluetooth_profile_headset">Phone audio</string>
+    <string name="bluetooth_profile_headset">Phone calls</string>
     <!-- Bluetooth settings.  The user-visible string that is used whenever referring to the OPP profile. -->
     <string name="bluetooth_profile_opp">File transfer</string>
     <!-- Bluetooth settings. The user-visible string that is used whenever referring to the HID profile. -->
@@ -126,15 +156,15 @@
     <!-- Bluetooth settings. The user-visible string that is used whenever referring to the PAN profile (sharing this device's Internet connection). [CHAR LIMIT=40] -->
     <string name="bluetooth_profile_pan_nap">Internet connection sharing</string>
     <!-- Bluetooth settings. The user-visible string that is used whenever referring to the map profile. -->
-    <string name="bluetooth_profile_map">Message Access</string>
+    <string name="bluetooth_profile_map">Text Messages</string>
     <!-- Bluetooth settings. The user-visible string that is used whenever referring to the SAP profile (sharing SIM card). -->
     <string name="bluetooth_profile_sap">SIM Access</string>
 
     <!-- Bluetooth settings. The user-visible string for the setting controlling whether to use a high-quality codec if the device supports it, along with the name of the codec (eg AAC, LDAC, aptX) -->
-    <string name="bluetooth_profile_a2dp_high_quality">Use high quality audio: <xliff:g id="codec_name">%1$s</xliff:g></string>
+    <string name="bluetooth_profile_a2dp_high_quality">HD audio: <xliff:g id="codec_name">%1$s</xliff:g></string>
 
     <!-- Bluetooth settings. Similar to bluetooth_profile_a2dp_high_quality, but used when the device supports high quality audio but we don't know which codec that will be used. -->
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec">Use high quality audio</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec">HD audio</string>
 
     <!-- Bluetooth settings.  Connection options screen.  The summary for the A2DP checkbox preference when A2DP is connected. -->
     <string name="bluetooth_a2dp_profile_summary_connected">Connected to media audio</string>
@@ -435,6 +465,8 @@
     <string name="wifi_allow_scan_with_traffic">Always allow Wi\u2011Fi Roam Scans</string>
     <!-- Setting Checkbox title whether to always keep mobile data active. [CHAR LIMIT=80] -->
     <string name="mobile_data_always_on">Mobile data always active</string>
+    <!-- Setting Checkbox title whether to enable hardware acceleration for tethering. [CHAR LIMIT=80] -->
+    <string name="tethering_hardware_offload">Tethering hardware acceleration</string>
     <!-- Setting Checkbox title for disabling Bluetooth absolute volume -->
     <string name="bluetooth_disable_absolute_volume">Disable absolute volume</string>
     <!-- Setting Checkbox title for enabling Bluetooth inband ringing -->
@@ -473,6 +505,14 @@
     <!-- [CHAR LIMIT=NONE] Label for displaying Bluetooth Audio Codec Parameters while streaming -->
     <string name="bluetooth_select_a2dp_codec_streaming_label">Streaming: <xliff:g id="streaming_parameter">%1$s</xliff:g></string>
 
+    <!-- Developer option setting for Private DNS -->
+    <string name="select_private_dns_configuration_title">Private DNS</string>
+    <string name="select_private_dns_configuration_dialog_title">Select Private DNS Mode</string>
+    <string name="private_dns_mode_off">Off</string>
+    <string name="private_dns_mode_opportunistic">Opportunistic</string>
+    <string name="private_dns_mode_provider">Private DNS provider hostname</string>
+    <string name="private_dns_mode_provider_hostname_hint">Enter hostname of DNS provider</string>
+
     <!-- setting Checkbox summary whether to show options for wireless display certification  -->
     <string name="wifi_display_certification_summary">Show options for wireless display certification</string>
     <!-- Setting Checkbox summary whether to enable Wifi verbose Logging [CHAR LIMIT=80] -->
@@ -504,6 +544,7 @@
     <!-- Setting Checkbox title whether to enable view attribute inspection -->
     <string name="debug_view_attributes">Enable view attribute inspection</string>
     <string name="mobile_data_always_on_summary">Always keep mobile data active, even when Wi\u2011Fi is active (for fast network switching).</string>
+    <string name="tethering_hardware_offload_summary">Use tethering hardware acceleration if available</string>
     <!-- Title of warning dialog about the implications of enabling USB debugging -->
     <string name="adb_warning_title">Allow USB debugging?</string>
     <!-- Warning text to user about the implications of enabling USB debugging -->
@@ -794,30 +835,31 @@
     <string name="daltonizer_type_overridden">Overridden by <xliff:g id="title" example="Simulate color space">%1$s</xliff:g></string>
 
     <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery discharging -->
-    <string name="power_remaining_duration_only">About <xliff:g id="time">%1$s</xliff:g> left</string>
+    <string name="power_remaining_duration_only">About <xliff:g id="time">^1</xliff:g> left</string>
+    <!-- [CHAR_LIMIT=60] Label for estimated remaining duration of battery discharging -->
+    <string name="power_remaining_duration_only_enhanced">About <xliff:g id="time">^1</xliff:g> left based on your usage</string>
     <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery charging -->
-    <string name="power_remaining_charging_duration_only"><xliff:g id="time">%1$s</xliff:g> left until fully charged</string>
+    <string name="power_remaining_charging_duration_only"><xliff:g id="time">^1</xliff:g> left until fully charged</string>
 
     <!-- [CHAR_LIMIT=40] Short label for estimated remaining duration of battery charging/discharging -->
-    <string name="power_remaining_duration_only_short"><xliff:g id="time">%1$s</xliff:g> left</string>
+    <string name="power_remaining_duration_only_short"><xliff:g id="time">^1</xliff:g> left</string>
+    <!-- [CHAR_LIMIT=60] Short label for estimated remaining duration of battery charging/discharging -->
+    <string name="power_remaining_duration_only_short_enhanced"><xliff:g id="time">^1</xliff:g> left based on your usage</string>
 
     <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration -->
-    <string name="power_discharging_duration"><xliff:g id="level">%1$s</xliff:g>
-        - about <xliff:g id="time">%2$s</xliff:g> left</string>
+    <string name="power_discharging_duration"><xliff:g id="level">^1</xliff:g> - about <xliff:g id="time">^2</xliff:g> left</string>
+    <!-- [CHAR_LIMIT=60] Label for battery level chart when discharging with duration and using enhanced estimate -->
+    <string name="power_discharging_duration_enhanced"><xliff:g id="level">^1</xliff:g> - about <xliff:g id="time">^2</xliff:g> left based on your usage</string>
 
     <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration -->
-    <string name="power_discharging_duration_short"><xliff:g id="level">%1$s</xliff:g>
-        - <xliff:g id="time">%2$s</xliff:g> left</string>
+    <string name="power_discharging_duration_short"><xliff:g id="level">^1</xliff:g> - <xliff:g id="time">^2</xliff:g> left</string>
 
     <!-- [CHAR_LIMIT=40] Label for battery level chart when charging -->
-    <string name="power_charging"><xliff:g id="level">%1$s</xliff:g> -
-            <xliff:g id="state">%2$s</xliff:g></string>
+    <string name="power_charging"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="state">%2$s</xliff:g></string>
     <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration -->
-    <string name="power_charging_duration"><xliff:g id="level">%1$s</xliff:g> -
-            <xliff:g id="time">%2$s</xliff:g> until fully charged</string>
+    <string name="power_charging_duration"><xliff:g id="level">^1</xliff:g> - <xliff:g id="time">^2</xliff:g> until fully charged</string>
     <!-- [CHAR_LIMIT=40] Short label for battery level chart when charging with duration -->
-    <string name="power_charging_duration_short"><xliff:g id="level">%1$s</xliff:g> -
-        <xliff:g id="time">%2$s</xliff:g></string>
+    <string name="power_charging_duration_short"><xliff:g id="level">^1</xliff:g> - <xliff:g id="time">^2</xliff:g></string>
 
     <!-- Battery Info screen. Value for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="battery_info_status_unknown">Unknown</string>
diff --git a/packages/SettingsLib/res/values/styles.xml b/packages/SettingsLib/res/values/styles.xml
index 3f312f4..b7ea1d4 100644
--- a/packages/SettingsLib/res/values/styles.xml
+++ b/packages/SettingsLib/res/values/styles.xml
@@ -21,4 +21,9 @@
     <style name="TextAppearanceMedium">
         <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
     </style>
+
+    <style name="preference_icon_frame">
+        <item name="android:layout_marginStart">-4dp</item>
+        <item name="android:minWidth">60dp</item>
+    </style>
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java b/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java
deleted file mode 100644
index 2d8defa..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java
+++ /dev/null
@@ -1,298 +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.settingslib;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.os.AsyncTask;
-import android.os.BatteryManager;
-import android.os.BatteryStats;
-import android.os.BatteryStats.HistoryItem;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.text.format.Formatter;
-import android.util.SparseIntArray;
-import com.android.internal.os.BatteryStatsHelper;
-import com.android.settingslib.graph.UsageView;
-
-public class BatteryInfo {
-
-    public String chargeLabelString;
-    public int batteryLevel;
-    public boolean discharging = true;
-    public long remainingTimeUs = 0;
-    public String batteryPercentString;
-    public String remainingLabel;
-    public String statusLabel;
-    private boolean mCharging;
-    private BatteryStats mStats;
-    private long timePeriod;
-
-    public interface Callback {
-        void onBatteryInfoLoaded(BatteryInfo info);
-    }
-
-    public void bindHistory(final UsageView view, BatteryDataParser... parsers) {
-        BatteryDataParser parser = new BatteryDataParser() {
-            SparseIntArray points = new SparseIntArray();
-
-            @Override
-            public void onParsingStarted(long startTime, long endTime) {
-                timePeriod = endTime - startTime - remainingTimeUs / 1000;
-                view.clearPaths();
-                view.configureGraph((int) (endTime - startTime), 100, remainingTimeUs != 0,
-                        mCharging);
-            }
-
-            @Override
-            public void onDataPoint(long time, HistoryItem record) {
-                points.put((int) time, record.batteryLevel);
-            }
-
-            @Override
-            public void onDataGap() {
-                if (points.size() > 1) {
-                    view.addPath(points);
-                }
-                points.clear();
-            }
-
-            @Override
-            public void onParsingDone() {
-                if (points.size() > 1) {
-                    view.addPath(points);
-                }
-            }
-        };
-        BatteryDataParser[] parserList = new BatteryDataParser[parsers.length + 1];
-        for (int i = 0; i < parsers.length; i++) {
-            parserList[i] = parsers[i];
-        }
-        parserList[parsers.length] = parser;
-        parse(mStats, remainingTimeUs, parserList);
-        final Context context = view.getContext();
-        String timeString = context.getString(R.string.charge_length_format,
-                Formatter.formatShortElapsedTime(context, timePeriod));
-        String remaining = "";
-        if (remainingTimeUs != 0) {
-            remaining = context.getString(R.string.remaining_length_format,
-                    Formatter.formatShortElapsedTime(context, remainingTimeUs / 1000));
-        }
-        view.setBottomLabels(new CharSequence[]{timeString, remaining});
-    }
-
-    public static void getBatteryInfo(final Context context, final Callback callback) {
-        BatteryInfo.getBatteryInfo(context, callback, false /* shortString */);
-    }
-
-    public static void getBatteryInfo(final Context context, final Callback callback,
-            boolean shortString) {
-        new AsyncTask<Void, Void, BatteryStats>() {
-            @Override
-            protected BatteryStats doInBackground(Void... params) {
-                BatteryStatsHelper statsHelper = new BatteryStatsHelper(context, true);
-                statsHelper.create((Bundle) null);
-                return statsHelper.getStats();
-            }
-
-            @Override
-            protected void onPostExecute(BatteryStats batteryStats) {
-                final long elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
-                Intent batteryBroadcast = context.registerReceiver(null,
-                        new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
-                BatteryInfo batteryInfo = BatteryInfo.getBatteryInfo(context, batteryBroadcast,
-                        batteryStats, elapsedRealtimeUs, shortString);
-                callback.onBatteryInfoLoaded(batteryInfo);
-            }
-        }.execute();
-    }
-
-    public static BatteryInfo getBatteryInfo(Context context, Intent batteryBroadcast,
-                                             BatteryStats stats, long elapsedRealtimeUs) {
-        return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats, elapsedRealtimeUs,
-                false /* shortString */);
-    }
-
-    public static BatteryInfo getBatteryInfo(Context context, Intent batteryBroadcast,
-            BatteryStats stats, long elapsedRealtimeUs, boolean shortString) {
-        BatteryInfo info = new BatteryInfo();
-        info.mStats = stats;
-        info.batteryLevel = Utils.getBatteryLevel(batteryBroadcast);
-        info.batteryPercentString = Utils.formatPercentage(info.batteryLevel);
-        info.mCharging = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
-        final Resources resources = context.getResources();
-
-        info.statusLabel = Utils.getBatteryStatus(resources, batteryBroadcast);
-        if (!info.mCharging) {
-            final long drainTime = stats.computeBatteryTimeRemaining(elapsedRealtimeUs);
-            if (drainTime > 0) {
-                info.remainingTimeUs = drainTime;
-                String timeString = Formatter.formatShortElapsedTime(context,
-                        drainTime / 1000);
-                info.remainingLabel = resources.getString(
-                        shortString ? R.string.power_remaining_duration_only_short
-                                : R.string.power_remaining_duration_only,
-                        timeString);
-                info.chargeLabelString = resources.getString(
-                        shortString ? R.string.power_discharging_duration_short
-                                : R.string.power_discharging_duration,
-                        info.batteryPercentString, timeString);
-            } else {
-                info.remainingLabel = null;
-                info.chargeLabelString = info.batteryPercentString;
-            }
-        } else {
-            final long chargeTime = stats.computeChargeTimeRemaining(elapsedRealtimeUs);
-            final int status = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS,
-                    BatteryManager.BATTERY_STATUS_UNKNOWN);
-            info.discharging = false;
-            if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) {
-                info.remainingTimeUs = chargeTime;
-                String timeString = Formatter.formatShortElapsedTime(context,
-                        chargeTime / 1000);
-                int resId = shortString ? R.string.power_charging_duration_short
-                        : R.string.power_charging_duration;
-                info.remainingLabel = resources.getString(
-                        R.string.power_remaining_charging_duration_only, timeString);
-                info.chargeLabelString = resources.getString(
-                        resId, info.batteryPercentString, timeString);
-            } else {
-                final String chargeStatusLabel = resources.getString(
-                        R.string.battery_info_status_charging_lower);
-                info.remainingLabel = null;
-                info.chargeLabelString = resources.getString(
-                        R.string.power_charging, info.batteryPercentString, chargeStatusLabel);
-            }
-        }
-        return info;
-    }
-
-    public interface BatteryDataParser {
-        void onParsingStarted(long startTime, long endTime);
-
-        void onDataPoint(long time, HistoryItem record);
-
-        void onDataGap();
-
-        void onParsingDone();
-    }
-
-    private static void parse(BatteryStats stats, long remainingTimeUs,
-            BatteryDataParser... parsers) {
-        long startWalltime = 0;
-        long endDateWalltime = 0;
-        long endWalltime = 0;
-        long historyStart = 0;
-        long historyEnd = 0;
-        byte lastLevel = -1;
-        long curWalltime = startWalltime;
-        long lastWallTime = 0;
-        long lastRealtime = 0;
-        int lastInteresting = 0;
-        int pos = 0;
-        boolean first = true;
-        if (stats.startIteratingHistoryLocked()) {
-            final HistoryItem rec = new HistoryItem();
-            while (stats.getNextHistoryLocked(rec)) {
-                pos++;
-                if (first) {
-                    first = false;
-                    historyStart = rec.time;
-                }
-                if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
-                        || rec.cmd == HistoryItem.CMD_RESET) {
-                    // If there is a ridiculously large jump in time, then we won't be
-                    // able to create a good chart with that data, so just ignore the
-                    // times we got before and pretend like our data extends back from
-                    // the time we have now.
-                    // Also, if we are getting a time change and we are less than 5 minutes
-                    // since the start of the history real time, then also use this new
-                    // time to compute the base time, since whatever time we had before is
-                    // pretty much just noise.
-                    if (rec.currentTime > (lastWallTime + (180 * 24 * 60 * 60 * 1000L))
-                            || rec.time < (historyStart + (5 * 60 * 1000L))) {
-                        startWalltime = 0;
-                    }
-                    lastWallTime = rec.currentTime;
-                    lastRealtime = rec.time;
-                    if (startWalltime == 0) {
-                        startWalltime = lastWallTime - (lastRealtime - historyStart);
-                    }
-                }
-                if (rec.isDeltaData()) {
-                    if (rec.batteryLevel != lastLevel || pos == 1) {
-                        lastLevel = rec.batteryLevel;
-                    }
-                    lastInteresting = pos;
-                    historyEnd = rec.time;
-                }
-            }
-        }
-        stats.finishIteratingHistoryLocked();
-        endDateWalltime = lastWallTime + historyEnd - lastRealtime;
-        endWalltime = endDateWalltime + (remainingTimeUs / 1000);
-
-        int i = 0;
-        final int N = lastInteresting;
-
-        for (int j = 0; j < parsers.length; j++) {
-            parsers[j].onParsingStarted(startWalltime, endWalltime);
-        }
-        if (endDateWalltime > startWalltime && stats.startIteratingHistoryLocked()) {
-            final HistoryItem rec = new HistoryItem();
-            while (stats.getNextHistoryLocked(rec) && i < N) {
-                if (rec.isDeltaData()) {
-                    curWalltime += rec.time - lastRealtime;
-                    lastRealtime = rec.time;
-                    long x = (curWalltime - startWalltime);
-                    if (x < 0) {
-                        x = 0;
-                    }
-                    for (int j = 0; j < parsers.length; j++) {
-                        parsers[j].onDataPoint(x, rec);
-                    }
-                } else {
-                    long lastWalltime = curWalltime;
-                    if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
-                            || rec.cmd == HistoryItem.CMD_RESET) {
-                        if (rec.currentTime >= startWalltime) {
-                            curWalltime = rec.currentTime;
-                        } else {
-                            curWalltime = startWalltime + (rec.time - historyStart);
-                        }
-                        lastRealtime = rec.time;
-                    }
-
-                    if (rec.cmd != HistoryItem.CMD_OVERFLOW
-                            && (rec.cmd != HistoryItem.CMD_CURRENT_TIME
-                            || Math.abs(lastWalltime - curWalltime) > (60 * 60 * 1000))) {
-                        for (int j = 0; j < parsers.length; j++) {
-                            parsers[j].onDataGap();
-                        }
-                    }
-                }
-                i++;
-            }
-        }
-
-        stats.finishIteratingHistoryLocked();
-
-        for (int j = 0; j < parsers.length; j++) {
-            parsers[j].onParsingDone();
-        }
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/CustomDialogPreference.java b/packages/SettingsLib/src/com/android/settingslib/CustomDialogPreference.java
new file mode 100644
index 0000000..9554e81
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/CustomDialogPreference.java
@@ -0,0 +1,112 @@
+/*
+ * 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.settingslib;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v14.preference.PreferenceDialogFragment;
+import android.support.v7.preference.DialogPreference;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class CustomDialogPreference extends DialogPreference {
+
+    private CustomPreferenceDialogFragment mFragment;
+
+    public CustomDialogPreference(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public CustomDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public CustomDialogPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public CustomDialogPreference(Context context) {
+        super(context);
+    }
+
+    public boolean isDialogOpen() {
+        return getDialog() != null && getDialog().isShowing();
+    }
+
+    public Dialog getDialog() {
+        return mFragment != null ? mFragment.getDialog() : null;
+    }
+
+    protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
+            DialogInterface.OnClickListener listener) {
+    }
+
+    protected void onDialogClosed(boolean positiveResult) {
+    }
+
+    protected void onClick(DialogInterface dialog, int which) {
+    }
+
+    protected void onBindDialogView(View view) {
+    }
+
+    private void setFragment(CustomPreferenceDialogFragment fragment) {
+        mFragment = fragment;
+    }
+
+    public static class CustomPreferenceDialogFragment extends PreferenceDialogFragment {
+
+        public static CustomPreferenceDialogFragment newInstance(String key) {
+            final CustomPreferenceDialogFragment fragment = new CustomPreferenceDialogFragment();
+            final Bundle b = new Bundle(1);
+            b.putString(ARG_KEY, key);
+            fragment.setArguments(b);
+            return fragment;
+        }
+
+        private CustomDialogPreference getCustomizablePreference() {
+            return (CustomDialogPreference) getPreference();
+        }
+
+        @Override
+        protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+            super.onPrepareDialogBuilder(builder);
+            getCustomizablePreference().setFragment(this);
+            getCustomizablePreference().onPrepareDialogBuilder(builder, this);
+        }
+
+        @Override
+        public void onDialogClosed(boolean positiveResult) {
+            getCustomizablePreference().onDialogClosed(positiveResult);
+        }
+
+        @Override
+        protected void onBindDialogView(View view) {
+            super.onBindDialogView(view);
+            getCustomizablePreference().onBindDialogView(view);
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            super.onClick(dialog, which);
+            getCustomizablePreference().onClick(dialog, which);
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/CustomEditTextPreference.java b/packages/SettingsLib/src/com/android/settingslib/CustomEditTextPreference.java
new file mode 100644
index 0000000..692d211
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/CustomEditTextPreference.java
@@ -0,0 +1,119 @@
+/*
+ * 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.settingslib;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v14.preference.EditTextPreferenceDialogFragment;
+import android.support.v7.preference.EditTextPreference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.EditText;
+
+public class CustomEditTextPreference extends EditTextPreference {
+
+    private CustomPreferenceDialogFragment mFragment;
+
+    public CustomEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public CustomEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public CustomEditTextPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public CustomEditTextPreference(Context context) {
+        super(context);
+    }
+
+    public EditText getEditText() {
+        return mFragment != null ? (EditText) mFragment.getDialog().findViewById(android.R.id.edit)
+                : null;
+    }
+
+    public boolean isDialogOpen() {
+        return getDialog() != null && getDialog().isShowing();
+    }
+
+    public Dialog getDialog() {
+        return mFragment != null ? mFragment.getDialog() : null;
+    }
+
+    protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
+            DialogInterface.OnClickListener listener) {
+    }
+
+    protected void onDialogClosed(boolean positiveResult) {
+    }
+
+    protected void onClick(DialogInterface dialog, int which) {
+    }
+
+    protected void onBindDialogView(View view) {
+    }
+
+    private void setFragment(CustomPreferenceDialogFragment fragment) {
+        mFragment = fragment;
+    }
+
+    public static class CustomPreferenceDialogFragment extends EditTextPreferenceDialogFragment {
+
+        public static CustomPreferenceDialogFragment newInstance(String key) {
+            final CustomPreferenceDialogFragment fragment = new CustomPreferenceDialogFragment();
+            final Bundle b = new Bundle(1);
+            b.putString(ARG_KEY, key);
+            fragment.setArguments(b);
+            return fragment;
+        }
+
+        private CustomEditTextPreference getCustomizablePreference() {
+            return (CustomEditTextPreference) getPreference();
+        }
+
+        @Override
+        protected void onBindDialogView(View view) {
+            super.onBindDialogView(view);
+            getCustomizablePreference().onBindDialogView(view);
+        }
+
+        @Override
+        protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+            super.onPrepareDialogBuilder(builder);
+            getCustomizablePreference().setFragment(this);
+            getCustomizablePreference().onPrepareDialogBuilder(builder, this);
+        }
+
+        @Override
+        public void onDialogClosed(boolean positiveResult) {
+            super.onDialogClosed(positiveResult);
+            getCustomizablePreference().onDialogClosed(positiveResult);
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            super.onClick(dialog, which);
+            getCustomizablePreference().onClick(dialog, which);
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
index ebb5d19..78a9064 100644
--- a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
@@ -76,16 +76,17 @@
 
     public static String formatKernelVersion(String rawKernelVersion) {
         // Example (see tests for more):
-        // Linux version 3.0.31-g6fb96c9 (android-build@xxx.xxx.xxx.xxx.com) \
-        //     (gcc version 4.6.x-xxx 20120106 (prerelease) (GCC) ) #1 SMP PREEMPT \
-        //     Thu Jun 28 11:02:39 PDT 2012
-
+        // Linux version 4.9.29-g958411d (android-build@xyz) (Android clang version 3.8.256229 \
+        //       (based on LLVM 3.8.256229)) #1 SMP PREEMPT Wed Jun 7 00:06:03 CST 2017
+        // Linux version 4.9.29-geb63318482a7 (android-build@xyz) (gcc version 4.9.x 20150123 \
+        //       (prerelease) (GCC) ) #1 SMP PREEMPT Thu Jun 1 03:41:57 UTC 2017
         final String PROC_VERSION_REGEX =
                 "Linux version (\\S+) " + /* group 1: "3.0.31-g6fb96c9" */
-                "\\((\\S+)\\)" +          /* group 2: "x@y.com" (kernel builder) */
-                ".*(#\\d+)" +             /* group 3: "#1" */
-                /* group 4: "Thu Jun 28 11:02:39 PDT 2012" */
-                ".*((?:Sun|Mon|Tue|Wed|Thu|Fri|Sat).+)";
+                "\\((\\S+?)\\) " +        /* group 2: "(x@y.com) " */
+                "\\((.+?)\\) " +          /* group 3:  kernel toolchain version information */
+                "(#\\d+) " +              /* group 4: "#1" */
+                "(?:.*?)?" +              /* ignore: optional SMP, PREEMPT, and any CONFIG_FLAGS */
+                "((Sun|Mon|Tue|Wed|Thu|Fri|Sat).+)"; /* group 5: "Thu Jun 28 11:02:39 PDT 2012" */
 
         Matcher m = Pattern.compile(PROC_VERSION_REGEX).matcher(rawKernelVersion);
         if (!m.matches()) {
@@ -96,9 +97,9 @@
                     + " groups");
             return "Unavailable";
         }
-        return m.group(1) + "\n" +                 // 3.0.31-g6fb96c9
-                m.group(2) + " " + m.group(3) + "\n" + // x@y.com #1
-                m.group(4);                            // Thu Jun 28 11:02:39 PDT 2012
+        return m.group(1) + " ("+ m.group(3) + ")\n" +   // 3.0.31-g6fb96c9 (toolchain version)
+                m.group(2) + " " + m.group(4) + "\n" +   // x@y.com #1
+                m.group(5);                              // Thu Jun 28 11:02:39 PDT 2012
     }
 
     /**
diff --git a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
deleted file mode 100644
index 4b0ab59..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
+++ /dev/null
@@ -1,461 +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.settingslib;
-
-import android.Manifest;
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.annotation.RequiresPermission;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.support.annotation.VisibleForTesting;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Xml;
-import android.view.InflateException;
-import com.android.settingslib.drawer.Tile;
-import com.android.settingslib.drawer.TileUtils;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-public class SuggestionParser {
-
-    private static final String TAG = "SuggestionParser";
-
-    // If defined, only returns this suggestion if the feature is supported.
-    public static final String META_DATA_REQUIRE_FEATURE = "com.android.settings.require_feature";
-
-    // If defined, only display this optional step if an account of that type exists.
-    private static final String META_DATA_REQUIRE_ACCOUNT = "com.android.settings.require_account";
-
-    // If defined and not true, do not should optional step.
-    private static final String META_DATA_IS_SUPPORTED = "com.android.settings.is_supported";
-
-    // If defined, only display this optional step if the current user is of that type.
-    private static final String META_DATA_REQUIRE_USER_TYPE =
-            "com.android.settings.require_user_type";
-
-    // If defined, only display this optional step if a connection is available.
-    private static final String META_DATA_IS_CONNECTION_REQUIRED =
-            "com.android.settings.require_connection";
-
-    // The valid values that setup wizard recognizes for differentiating user types.
-    private static final String META_DATA_PRIMARY_USER_TYPE_VALUE = "primary";
-    private static final String META_DATA_ADMIN_USER_TYPE_VALUE = "admin";
-    private static final String META_DATA_GUEST_USER_TYPE_VALUE = "guest";
-    private static final String META_DATA_RESTRICTED_USER_TYPE_VALUE = "restricted";
-
-    /**
-     * Allows suggestions to appear after a certain number of days, and to re-appear if dismissed.
-     * For instance:
-     * 0,10
-     * Will appear immediately, but if the user removes it, it will come back after 10 days.
-     *
-     * Another example:
-     * 10,30
-     * Will only show up after 10 days, and then again after 30.
-     */
-    public static final String META_DATA_DISMISS_CONTROL = "com.android.settings.dismiss";
-
-    // Shared prefs keys for storing dismissed state.
-    // Index into current dismissed state.
-    private static final String DISMISS_INDEX = "_dismiss_index";
-    private static final String SETUP_TIME = "_setup_time";
-    private static final String IS_DISMISSED = "_is_dismissed";
-
-    private static final long MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
-
-    // Default dismiss control for smart suggestions.
-    private static final String DEFAULT_SMART_DISMISS_CONTROL = "0,10";
-
-    private final Context mContext;
-    private final List<SuggestionCategory> mSuggestionList;
-    private final ArrayMap<Pair<String, String>, Tile> mAddCache = new ArrayMap<>();
-    private final SharedPreferences mSharedPrefs;
-    private final String mSmartDismissControl;
-
-
-    public SuggestionParser(
-        Context context, SharedPreferences sharedPrefs, int orderXml, String smartDismissControl) {
-        mContext = context;
-        mSuggestionList = (List<SuggestionCategory>) new SuggestionOrderInflater(mContext)
-                .parse(orderXml);
-        mSharedPrefs = sharedPrefs;
-        mSmartDismissControl = smartDismissControl;
-    }
-
-    public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml) {
-       this(context, sharedPrefs, orderXml, DEFAULT_SMART_DISMISS_CONTROL);
-    }
-
-    @VisibleForTesting
-    public SuggestionParser(Context context, SharedPreferences sharedPrefs) {
-        mContext = context;
-        mSuggestionList = new ArrayList<SuggestionCategory>();
-        mSharedPrefs = sharedPrefs;
-        mSmartDismissControl = DEFAULT_SMART_DISMISS_CONTROL;
-        Log.wtf(TAG, "Only use this constructor for testing");
-    }
-
-    public List<Tile> getSuggestions() {
-        return getSuggestions(false);
-    }
-
-    public List<Tile> getSuggestions(boolean isSmartSuggestionEnabled) {
-        List<Tile> suggestions = new ArrayList<>();
-        final int N = mSuggestionList.size();
-        for (int i = 0; i < N; i++) {
-            readSuggestions(mSuggestionList.get(i), suggestions, isSmartSuggestionEnabled);
-        }
-        return suggestions;
-    }
-
-    public boolean dismissSuggestion(Tile suggestion) {
-        return dismissSuggestion(suggestion, false);
-    }
-
-    /**
-     * Dismisses a suggestion, returns true if the suggestion has no more dismisses left and should
-     * be disabled.
-     */
-    public boolean dismissSuggestion(Tile suggestion, boolean isSmartSuggestionEnabled) {
-        String keyBase = suggestion.intent.getComponent().flattenToShortString();
-        int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
-        String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
-        if (dismissControl == null || parseDismissString(dismissControl).length == index) {
-            return true;
-        }
-        mSharedPrefs.edit()
-                .putBoolean(keyBase + IS_DISMISSED, true)
-                .commit();
-        return false;
-    }
-
-    @VisibleForTesting
-    public void filterSuggestions(
-        List<Tile> suggestions, int countBefore, boolean isSmartSuggestionEnabled) {
-        for (int i = countBefore; i < suggestions.size(); i++) {
-            if (!isAvailable(suggestions.get(i)) ||
-                    !isSupported(suggestions.get(i)) ||
-                    !satisifesRequiredUserType(suggestions.get(i)) ||
-                    !satisfiesRequiredAccount(suggestions.get(i)) ||
-                    !satisfiesConnectivity(suggestions.get(i)) ||
-                    isDismissed(suggestions.get(i), isSmartSuggestionEnabled)) {
-                suggestions.remove(i--);
-            }
-        }
-    }
-
-    @VisibleForTesting
-    void readSuggestions(
-        SuggestionCategory category, List<Tile> suggestions, boolean isSmartSuggestionEnabled) {
-        int countBefore = suggestions.size();
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.addCategory(category.category);
-        if (category.pkg != null) {
-            intent.setPackage(category.pkg);
-        }
-        TileUtils.getTilesForIntent(mContext, new UserHandle(UserHandle.myUserId()), intent,
-                mAddCache, null, suggestions, true, false);
-        filterSuggestions(suggestions, countBefore, isSmartSuggestionEnabled);
-        if (!category.multiple && suggestions.size() > (countBefore + 1)) {
-            // If there are too many, remove them all and only re-add the one with the highest
-            // priority.
-            Tile item = suggestions.remove(suggestions.size() - 1);
-            while (suggestions.size() > countBefore) {
-                Tile last = suggestions.remove(suggestions.size() - 1);
-                if (last.priority > item.priority) {
-                    item = last;
-                }
-            }
-            // If category is marked as done, do not add any item.
-            if (!isCategoryDone(category.category)) {
-                suggestions.add(item);
-            }
-        }
-    }
-
-    private boolean isAvailable(Tile suggestion) {
-        final String featuresRequired = suggestion.metaData.getString(META_DATA_REQUIRE_FEATURE);
-        if (featuresRequired != null) {
-            for (String feature : featuresRequired.split(",")) {
-                if (TextUtils.isEmpty(feature)) {
-                    Log.w(TAG, "Found empty substring when parsing required features: "
-                            + featuresRequired);
-                } else if (!mContext.getPackageManager().hasSystemFeature(feature)) {
-                    Log.i(TAG, suggestion.title + " requires unavailable feature " + feature);
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    @RequiresPermission(Manifest.permission.MANAGE_USERS)
-    private boolean satisifesRequiredUserType(Tile suggestion) {
-        final String requiredUser = suggestion.metaData.getString(META_DATA_REQUIRE_USER_TYPE);
-        if (requiredUser != null) {
-            final UserManager userManager = mContext.getSystemService(UserManager.class);
-            UserInfo userInfo = userManager.getUserInfo(UserHandle.myUserId());
-            for (String userType : requiredUser.split("\\|")) {
-                final boolean primaryUserCondtionMet = userInfo.isPrimary()
-                        && META_DATA_PRIMARY_USER_TYPE_VALUE.equals(userType);
-                final boolean adminUserConditionMet = userInfo.isAdmin()
-                        && META_DATA_ADMIN_USER_TYPE_VALUE.equals(userType);
-                final boolean guestUserCondtionMet = userInfo.isGuest()
-                        && META_DATA_GUEST_USER_TYPE_VALUE.equals(userType);
-                final boolean restrictedUserCondtionMet = userInfo.isRestricted()
-                        && META_DATA_RESTRICTED_USER_TYPE_VALUE.equals(userType);
-                if (primaryUserCondtionMet || adminUserConditionMet || guestUserCondtionMet
-                        || restrictedUserCondtionMet) {
-                    return true;
-                }
-            }
-            Log.i(TAG, suggestion.title + " requires user type " + requiredUser);
-            return false;
-        }
-        return true;
-    }
-
-    public boolean satisfiesRequiredAccount(Tile suggestion) {
-        final String requiredAccountType = suggestion.metaData.getString(META_DATA_REQUIRE_ACCOUNT);
-        if (requiredAccountType == null) {
-            return true;
-        }
-        AccountManager accountManager = AccountManager.get(mContext);
-        Account[] accounts = accountManager.getAccountsByType(requiredAccountType);
-        boolean satisfiesRequiredAccount = accounts.length > 0;
-        if (!satisfiesRequiredAccount) {
-            Log.i(TAG, suggestion.title + " requires unavailable account type "
-                    + requiredAccountType);
-        }
-        return satisfiesRequiredAccount;
-    }
-
-    public boolean isSupported(Tile suggestion) {
-        final int isSupportedResource = suggestion.metaData.getInt(META_DATA_IS_SUPPORTED);
-        try {
-            if (suggestion.intent == null) {
-                return false;
-            }
-            final Resources res = mContext.getPackageManager().getResourcesForActivity(
-                    suggestion.intent.getComponent());
-            boolean isSupported =
-                    isSupportedResource != 0 ? res.getBoolean(isSupportedResource) : true;
-            if (!isSupported) {
-                Log.i(TAG, suggestion.title + " requires unsupported resource "
-                        + isSupportedResource);
-            }
-            return isSupported;
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.w(TAG, "Cannot find resources for " + suggestion.intent.getComponent());
-            return false;
-        } catch (Resources.NotFoundException e) {
-            Log.w(TAG, "Cannot find resources for " + suggestion.intent.getComponent(), e);
-            return false;
-        }
-    }
-
-    private boolean satisfiesConnectivity(Tile suggestion) {
-        final boolean isConnectionRequired =
-                suggestion.metaData.getBoolean(META_DATA_IS_CONNECTION_REQUIRED);
-        if (!isConnectionRequired) {
-          return true;
-        }
-        ConnectivityManager cm =
-                (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-        NetworkInfo netInfo = cm.getActiveNetworkInfo();
-        boolean satisfiesConnectivity = netInfo != null && netInfo.isConnectedOrConnecting();
-        if (!satisfiesConnectivity) {
-            Log.i(TAG, suggestion.title + " is missing required connection.");
-        }
-        return satisfiesConnectivity;
-    }
-
-    public boolean isCategoryDone(String category) {
-        String name = Settings.Secure.COMPLETED_CATEGORY_PREFIX + category;
-        return Settings.Secure.getInt(mContext.getContentResolver(), name, 0) != 0;
-    }
-
-    public void markCategoryDone(String category) {
-        String name = Settings.Secure.COMPLETED_CATEGORY_PREFIX + category;
-        Settings.Secure.putInt(mContext.getContentResolver(), name, 1);
-    }
-
-    private boolean isDismissed(Tile suggestion, boolean isSmartSuggestionEnabled) {
-        String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
-        if (dismissControl == null) {
-            return false;
-        }
-        String keyBase = suggestion.intent.getComponent().flattenToShortString();
-        if (!mSharedPrefs.contains(keyBase + SETUP_TIME)) {
-            mSharedPrefs.edit()
-                    .putLong(keyBase + SETUP_TIME, System.currentTimeMillis())
-                    .commit();
-        }
-        // Default to dismissed, so that we can have suggestions that only first appear after
-        // some number of days.
-        if (!mSharedPrefs.getBoolean(keyBase + IS_DISMISSED, true)) {
-            return false;
-        }
-        int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
-        int currentDismiss = parseDismissString(dismissControl)[index];
-        long time = getEndTime(mSharedPrefs.getLong(keyBase + SETUP_TIME, 0), currentDismiss);
-        if (System.currentTimeMillis() >= time) {
-            // Dismiss timeout has passed, undismiss it.
-            mSharedPrefs.edit()
-                    .putBoolean(keyBase + IS_DISMISSED, false)
-                    .putInt(keyBase + DISMISS_INDEX, index + 1)
-                    .commit();
-            return false;
-        }
-        return true;
-    }
-
-    private long getEndTime(long startTime, int daysDelay) {
-        long days = daysDelay * MILLIS_IN_DAY;
-        return startTime + days;
-    }
-
-    private int[] parseDismissString(String dismissControl) {
-        String[] dismissStrs = dismissControl.split(",");
-        int[] dismisses = new int[dismissStrs.length];
-        for (int i = 0; i < dismissStrs.length; i++) {
-            dismisses[i] = Integer.parseInt(dismissStrs[i]);
-        }
-        return dismisses;
-    }
-
-    private String getDismissControl(Tile suggestion, boolean isSmartSuggestionEnabled) {
-        if (isSmartSuggestionEnabled) {
-            return mSmartDismissControl;
-        } else {
-            return suggestion.metaData.getString(META_DATA_DISMISS_CONTROL);
-        }
-    }
-
-    @VisibleForTesting
-    static class SuggestionCategory {
-        public String category;
-        public String pkg;
-        public boolean multiple;
-    }
-
-    private static class SuggestionOrderInflater {
-        private static final String TAG_LIST = "optional-steps";
-        private static final String TAG_ITEM = "step";
-
-        private static final String ATTR_CATEGORY = "category";
-        private static final String ATTR_PACKAGE = "package";
-        private static final String ATTR_MULTIPLE = "multiple";
-
-        private final Context mContext;
-
-        public SuggestionOrderInflater(Context context) {
-            mContext = context;
-        }
-
-        public Object parse(int resource) {
-            XmlPullParser parser = mContext.getResources().getXml(resource);
-            final AttributeSet attrs = Xml.asAttributeSet(parser);
-            try {
-                // Look for the root node.
-                int type;
-                do {
-                    type = parser.next();
-                } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT);
-
-                if (type != XmlPullParser.START_TAG) {
-                    throw new InflateException(parser.getPositionDescription()
-                            + ": No start tag found!");
-                }
-
-                // Temp is the root that was found in the xml
-                Object xmlRoot = onCreateItem(parser.getName(), attrs);
-
-                // Inflate all children under temp
-                rParse(parser, xmlRoot, attrs);
-                return xmlRoot;
-            } catch (XmlPullParserException | IOException e) {
-                Log.w(TAG, "Problem parser resource " + resource, e);
-                return null;
-            }
-        }
-
-        /**
-         * Recursive method used to descend down the xml hierarchy and instantiate
-         * items, instantiate their children.
-         */
-        private void rParse(XmlPullParser parser, Object parent, final AttributeSet attrs)
-                throws XmlPullParserException, IOException {
-            final int depth = parser.getDepth();
-
-            int type;
-            while (((type = parser.next()) != XmlPullParser.END_TAG ||
-                    parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
-                if (type != XmlPullParser.START_TAG) {
-                    continue;
-                }
-
-                final String name = parser.getName();
-
-                Object item = onCreateItem(name, attrs);
-                onAddChildItem(parent, item);
-                rParse(parser, item, attrs);
-            }
-        }
-
-        protected void onAddChildItem(Object parent, Object child) {
-            if (parent instanceof List<?> && child instanceof SuggestionCategory) {
-                ((List<SuggestionCategory>) parent).add((SuggestionCategory) child);
-            } else {
-                throw new IllegalArgumentException("Parent was not a list");
-            }
-        }
-
-        protected Object onCreateItem(String name, AttributeSet attrs) {
-            if (name.equals(TAG_LIST)) {
-                return new ArrayList<SuggestionCategory>();
-            } else if (name.equals(TAG_ITEM)) {
-                SuggestionCategory category = new SuggestionCategory();
-                category.category = attrs.getAttributeValue(null, ATTR_CATEGORY);
-                category.pkg = attrs.getAttributeValue(null, ATTR_PACKAGE);
-                String multiple = attrs.getAttributeValue(null, ATTR_MULTIPLE);
-                category.multiple = !TextUtils.isEmpty(multiple) && Boolean.parseBoolean(multiple);
-                return category;
-            } else {
-                throw new IllegalArgumentException("Unknown item " + name);
-            }
-        }
-    }
-}
-
diff --git a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
index 151e0ea..abbef70 100644
--- a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
@@ -17,13 +17,19 @@
 
 import android.content.Context;
 import android.os.SystemProperties;
+import android.support.annotation.VisibleForTesting;
 import android.telephony.CarrierConfigManager;
 
 public class TetherUtil {
 
-    private static boolean isEntitlementCheckRequired(Context context) {
+    @VisibleForTesting
+    static boolean isEntitlementCheckRequired(Context context) {
         final CarrierConfigManager configManager = (CarrierConfigManager) context
              .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        if (configManager == null || configManager.getConfig() == null) {
+            // return service default
+            return true;
+        }
         return configManager.getConfig().getBoolean(CarrierConfigManager
              .KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL);
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/TronUtils.java b/packages/SettingsLib/src/com/android/settingslib/TronUtils.java
index bea6e8f..945cb57 100644
--- a/packages/SettingsLib/src/com/android/settingslib/TronUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/TronUtils.java
@@ -16,48 +16,18 @@
 package com.android.settingslib;
 
 import android.content.Context;
-import android.net.NetworkBadging;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.settingslib.wifi.AccessPoint.Speed;
 
 /** Utilites for Tron Logging. */
 public final class TronUtils {
 
+    private static final String TAG = "TronUtils";
+
     private TronUtils() {};
 
-    public static void logWifiSettingsBadge(Context context, int badgeEnum) {
-        logNetworkBadgeMetric(context, "settings_wifibadging", badgeEnum);
-    }
-
-    /**
-     * Logs an occurrence of the given network badge to a Histogram.
-     *
-     * @param context Context
-     * @param histogram the Tron histogram name to write to
-     * @param badgeEnum the {@link NetworkBadging.Badging} badge value
-     * @throws IllegalArgumentException if the given badge enum is not supported
-     */
-    private static void logNetworkBadgeMetric(
-            Context context, String histogram, int badgeEnum)
-            throws IllegalArgumentException {
-        int bucket;
-        switch (badgeEnum) {
-            case NetworkBadging.BADGING_NONE:
-                bucket = 0;
-                break;
-            case NetworkBadging.BADGING_SD:
-                bucket = 1;
-                break;
-            case NetworkBadging.BADGING_HD:
-                bucket = 2;
-                break;
-            case NetworkBadging.BADGING_4K:
-                bucket = 3;
-                break;
-            default:
-                throw new IllegalArgumentException("Unsupported badge enum: " + badgeEnum);
-        }
-
-        MetricsLogger.histogram(context, histogram, bucket);
+    public static void logWifiSettingsSpeed(Context context, @Speed int speedEnum) {
+        MetricsLogger.histogram(context, "settings_wifi_speed_labels", speedEnum);
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index 3135f1d..e8c4884 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -19,8 +19,10 @@
 import android.net.ConnectivityManager;
 import android.net.NetworkBadging;
 import android.os.BatteryManager;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.print.PrintManager;
+import android.provider.Settings;
 import android.view.View;
 
 import com.android.internal.util.UserIcons;
@@ -29,12 +31,18 @@
 import java.text.NumberFormat;
 
 public class Utils {
+    /** Broadcast intent action when the location mode is about to change. */
+    private static final String MODE_CHANGING_ACTION =
+            "com.android.settings.location.MODE_CHANGING";
+    private static final String CURRENT_MODE_KEY = "CURRENT_MODE";
+    private static final String NEW_MODE_KEY = "NEW_MODE";
+
     private static Signature[] sSystemSignature;
     private static String sPermissionControllerPackageName;
     private static String sServicesSystemSharedLibPackageName;
     private static String sSharedSystemSharedLibPackageName;
 
-    public static final int[] WIFI_PIE_FOR_BADGING = {
+    static final int[] WIFI_PIE_FOR_BADGING = {
           com.android.internal.R.drawable.ic_signal_wifi_badged_0_bars,
           com.android.internal.R.drawable.ic_signal_wifi_badged_1_bar,
           com.android.internal.R.drawable.ic_signal_wifi_badged_2_bars,
@@ -42,6 +50,18 @@
           com.android.internal.R.drawable.ic_signal_wifi_badged_4_bars
     };
 
+    public static boolean updateLocationMode(Context context, int oldMode, int newMode,
+            int userId) {
+        Intent intent = new Intent(MODE_CHANGING_ACTION);
+        intent.putExtra(CURRENT_MODE_KEY, oldMode);
+        intent.putExtra(NEW_MODE_KEY, newMode);
+        intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+        context.sendBroadcastAsUser(intent, UserHandle.of(userId),
+                android.Manifest.permission.WRITE_SECURE_SETTINGS);
+        return Settings.Secure.putIntForUser(context.getContentResolver(),
+                Settings.Secure.LOCATION_MODE, newMode, userId);
+    }
+
     /**
      * Return string resource that best describes combination of tethering
      * options available on this device.
@@ -129,7 +149,7 @@
     }
 
     /** Formats a double from 0.0..1.0 as a percentage. */
-    private static String formatPercentage(double percentage) {
+    public static String formatPercentage(double percentage) {
         return NumberFormat.getPercentInstance().format(percentage);
     }
 
@@ -293,12 +313,7 @@
                 });
     }
 
-    /**
-     * Returns the resource id for the given badge or {@link View.NO_ID} if no badge is to be shown.
-     *
-     * @throws IllegalArgumentException if the given badge value is not supported.
-     */
-    public static int getWifiBadgeResource(int badge) {
+    private static int getWifiBadgeResource(int badge) {
         switch (badge) {
             case NetworkBadging.BADGING_NONE:
                 return View.NO_ID;
@@ -313,4 +328,20 @@
                     "No badge resource found for badge value: " + badge);
         }
     }
+
+    public static int getDefaultStorageManagerDaysToRetain(Resources resources) {
+        int defaultDays = Settings.Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_DEFAULT;
+        try {
+            defaultDays =
+                    resources.getInteger(
+                            com.android
+                                    .internal
+                                    .R
+                                    .integer
+                                    .config_storageManagerDaystoRetainDefault);
+        } catch (Resources.NotFoundException e) {
+            // We are likely in a test environment.
+        }
+        return defaultDays;
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
index b06b032..7357fe6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
@@ -107,4 +107,20 @@
         return false;
     }
 
+    /** Returns the label for a given package. */
+    public static CharSequence getApplicationLabel(
+            PackageManager packageManager, String packageName) {
+        try {
+            final ApplicationInfo appInfo =
+                    packageManager.getApplicationInfo(
+                            packageName,
+                            PackageManager.MATCH_DISABLED_COMPONENTS
+                                    | PackageManager.MATCH_ANY_USER);
+            return appInfo.loadLabel(packageManager);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "Unable to find info for package: " + packageName);
+        }
+        return null;
+    }
+
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/InterestingConfigChanges.java b/packages/SettingsLib/src/com/android/settingslib/applications/InterestingConfigChanges.java
index e4e0f7f..c4cbc2b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/InterestingConfigChanges.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/InterestingConfigChanges.java
@@ -36,7 +36,8 @@
     }
 
     public boolean applyNewConfig(Resources res) {
-        int configChanges = mLastConfiguration.updateFrom(res.getConfiguration());
+        int configChanges = mLastConfiguration.updateFrom(
+                Configuration.generateDelta(mLastConfiguration, res.getConfiguration()));
         boolean densityChanged = mLastDensity != res.getDisplayMetrics().densityDpi;
         if (densityChanged || (configChanges & (mFlags)) != 0) {
             mLastDensity = res.getDisplayMetrics().densityDpi;
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapper.java b/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapper.java
index caa7929..6c79a61 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapper.java
@@ -123,4 +123,9 @@
      * @return the label as a CharSequence
      */
     CharSequence loadLabel(ApplicationInfo app);
+
+    /**
+     * Retrieve all activities that can be performed for the given intent.
+     */
+    List<ResolveInfo> queryIntentActivities(Intent intent, int flags);
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapperImpl.java b/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapperImpl.java
index 9b2cd7c..dcb40b2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapperImpl.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapperImpl.java
@@ -113,4 +113,9 @@
     public CharSequence loadLabel(ApplicationInfo app) {
         return app.loadLabel(mPm);
     }
+
+    @Override
+    public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
+        return mPm.queryIntentActivities(intent, flags);
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 80b943c..63d944d5 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -97,24 +97,26 @@
 
         // Pairing broadcasts
         addHandler(BluetoothDevice.ACTION_BOND_STATE_CHANGED, new BondStateChangedHandler());
-        addHandler(BluetoothDevice.ACTION_PAIRING_CANCEL, new PairingCancelHandler());
 
         // Fine-grained state broadcasts
         addHandler(BluetoothDevice.ACTION_CLASS_CHANGED, new ClassChangedHandler());
         addHandler(BluetoothDevice.ACTION_UUID, new UuidChangedHandler());
+        addHandler(BluetoothDevice.ACTION_BATTERY_LEVEL_CHANGED, new BatteryLevelChangedHandler());
 
         // Dock event broadcasts
         addHandler(Intent.ACTION_DOCK_EVENT, new DockEventHandler());
 
         mContext.registerReceiver(mBroadcastReceiver, mAdapterIntentFilter, null, mReceiverHandler);
+        mContext.registerReceiver(mProfileBroadcastReceiver, mProfileIntentFilter, null, mReceiverHandler);
     }
 
     void registerProfileIntentReceiver() {
-        mContext.registerReceiver(mBroadcastReceiver, mProfileIntentFilter, null, mReceiverHandler);
+        mContext.registerReceiver(mProfileBroadcastReceiver, mProfileIntentFilter, null, mReceiverHandler);
     }
 
     public void setReceiverHandler(android.os.Handler handler) {
         mContext.unregisterReceiver(mBroadcastReceiver);
+        mContext.unregisterReceiver(mProfileBroadcastReceiver);
         mReceiverHandler = handler;
         mContext.registerReceiver(mBroadcastReceiver, mAdapterIntentFilter, null, mReceiverHandler);
         registerProfileIntentReceiver();
@@ -148,11 +150,31 @@
         }
     };
 
+    private final BroadcastReceiver mProfileBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            BluetoothDevice device = intent
+                    .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+
+            Handler handler = mHandlerMap.get(action);
+            if (handler != null) {
+                handler.onReceive(context, intent, device);
+            }
+        }
+    };
+
     private class AdapterStateChangedHandler implements Handler {
         public void onReceive(Context context, Intent intent,
                 BluetoothDevice device) {
             int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
                                     BluetoothAdapter.ERROR);
+            // Reregister Profile Broadcast Receiver as part of TURN OFF
+            if (state == BluetoothAdapter.STATE_OFF)
+            {
+                context.unregisterReceiver(mProfileBroadcastReceiver);
+                registerProfileIntentReceiver();
+            }
             // update local profiles and get paired devices
             mLocalAdapter.setBluetoothStateInt(state);
             // send callback to update UI and possibly start scanning
@@ -343,24 +365,6 @@
         }
     }
 
-    private class PairingCancelHandler implements Handler {
-        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
-            if (device == null) {
-                Log.e(TAG, "ACTION_PAIRING_CANCEL with no EXTRA_DEVICE");
-                return;
-            }
-            CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
-            if (cachedDevice == null) {
-                Log.e(TAG, "ACTION_PAIRING_CANCEL with no cached device");
-                return;
-            }
-            int errorMsg = R.string.bluetooth_pairing_error_message;
-            if (context != null && cachedDevice != null) {
-                Utils.showError(context, cachedDevice.getName(), errorMsg);
-            }
-        }
-    }
-
     private class DockEventHandler implements Handler {
         public void onReceive(Context context, Intent intent, BluetoothDevice device) {
             // Remove if unpair device upon undocking
@@ -376,6 +380,17 @@
             }
         }
     }
+
+    private class BatteryLevelChangedHandler implements Handler {
+        public void onReceive(Context context, Intent intent,
+                BluetoothDevice device) {
+            CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
+            if (cachedDevice != null) {
+                cachedDevice.refresh();
+            }
+        }
+    }
+
     boolean readPairedDevices() {
         Set<BluetoothDevice> bondedDevices = mLocalAdapter.getBondedDevices();
         if (bondedDevices == null) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index e279a09..bfa8de9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -332,8 +332,7 @@
     }
 
     public int getProfileConnectionState(LocalBluetoothProfile profile) {
-        if (mProfileConnectionState == null ||
-                mProfileConnectionState.get(profile) == null) {
+        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);
@@ -368,6 +367,15 @@
         return mDevice;
     }
 
+    /**
+     * Convenience method that can be mocked - it lets tests avoid having to call getDevice() which
+     * causes problems in tests since BluetoothDevice is final and cannot be mocked.
+     * @return the address of this device
+     */
+    public String getAddress() {
+        return mDevice.getAddress();
+    }
+
     public String getName() {
         return mName;
     }
@@ -410,6 +418,14 @@
         }
     }
 
+    /**
+     * Get battery level from remote device
+     * @return battery level in percentage [0-100], or {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN}
+     */
+    public int getBatteryLevel() {
+        return mDevice.getBatteryLevel();
+    }
+
     void refresh() {
         dispatchAttributesChanged();
     }
@@ -828,7 +844,7 @@
     /**
      * @return resource for string that discribes the connection state of this device.
      */
-    public int getConnectionSummary() {
+    public String getConnectionSummary() {
         boolean profileConnected = false;       // at least one profile is connected
         boolean a2dpNotConnected = false;       // A2DP is preferred but not connected
         boolean hfpNotConnected = false;    // HFP is preferred but not connected
@@ -839,7 +855,7 @@
             switch (connectionStatus) {
                 case BluetoothProfile.STATE_CONNECTING:
                 case BluetoothProfile.STATE_DISCONNECTING:
-                    return Utils.getConnectionStateSummary(connectionStatus);
+                    return mContext.getString(Utils.getConnectionStateSummary(connectionStatus));
 
                 case BluetoothProfile.STATE_CONNECTED:
                     profileConnected = true;
@@ -859,18 +875,54 @@
             }
         }
 
+        String batteryLevelPercentageString = null;
+        // Android framework should only set mBatteryLevel to valid range [0-100] or
+        // BluetoothDevice.BATTERY_LEVEL_UNKNOWN, any other value should be a framework bug.
+        // Thus assume here that if value is not BluetoothDevice.BATTERY_LEVEL_UNKNOWN, it must
+        // be valid
+        final int batteryLevel = getBatteryLevel();
+        if (batteryLevel != BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
+            // TODO: name com.android.settingslib.bluetooth.Utils something different
+            batteryLevelPercentageString =
+                    com.android.settingslib.Utils.formatPercentage(batteryLevel);
+        }
+
         if (profileConnected) {
             if (a2dpNotConnected && hfpNotConnected) {
-                return R.string.bluetooth_connected_no_headset_no_a2dp;
+                if (batteryLevelPercentageString != null) {
+                    return mContext.getString(
+                            R.string.bluetooth_connected_no_headset_no_a2dp_battery_level,
+                            batteryLevelPercentageString);
+                } else {
+                    return mContext.getString(R.string.bluetooth_connected_no_headset_no_a2dp);
+                }
+
             } else if (a2dpNotConnected) {
-                return R.string.bluetooth_connected_no_a2dp;
+                if (batteryLevelPercentageString != null) {
+                    return mContext.getString(R.string.bluetooth_connected_no_a2dp_battery_level,
+                            batteryLevelPercentageString);
+                } else {
+                    return mContext.getString(R.string.bluetooth_connected_no_a2dp);
+                }
+
             } else if (hfpNotConnected) {
-                return R.string.bluetooth_connected_no_headset;
+                if (batteryLevelPercentageString != null) {
+                    return mContext.getString(R.string.bluetooth_connected_no_headset_battery_level,
+                            batteryLevelPercentageString);
+                } else {
+                    return mContext.getString(R.string.bluetooth_connected_no_headset);
+                }
             } else {
-                return R.string.bluetooth_connected;
+                if (batteryLevelPercentageString != null) {
+                    return mContext.getString(R.string.bluetooth_connected_battery_level,
+                            batteryLevelPercentageString);
+                } else {
+                    return mContext.getString(R.string.bluetooth_connected);
+                }
             }
         }
 
-        return getBondState() == BluetoothDevice.BOND_BONDING ? R.string.bluetooth_pairing : 0;
+        return getBondState() == BluetoothDevice.BOND_BONDING ?
+                mContext.getString(R.string.bluetooth_pairing) : null;
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
index 5529866..d45fe1a 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
@@ -34,7 +34,7 @@
 /**
  * HeadsetProfile handles Bluetooth HFP and Headset profiles.
  */
-public final class HeadsetProfile implements LocalBluetoothProfile {
+public class HeadsetProfile implements LocalBluetoothProfile {
     private static final String TAG = "HeadsetProfile";
     private static boolean V = true;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
index a9e8db5..213002f 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
@@ -19,7 +19,7 @@
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothInputDevice;
+import android.bluetooth.BluetoothHidHost;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 import android.util.Log;
@@ -31,11 +31,11 @@
 /**
  * HidProfile handles Bluetooth HID profile.
  */
-public final class HidProfile implements LocalBluetoothProfile {
+public class HidProfile implements LocalBluetoothProfile {
     private static final String TAG = "HidProfile";
     private static boolean V = true;
 
-    private BluetoothInputDevice mService;
+    private BluetoothHidHost mService;
     private boolean mIsProfileReady;
 
     private final LocalBluetoothAdapter mLocalAdapter;
@@ -53,7 +53,7 @@
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
             if (V) Log.d(TAG,"Bluetooth service connected");
-            mService = (BluetoothInputDevice) proxy;
+            mService = (BluetoothHidHost) proxy;
             // We just bound to the service, so refresh the UI for any connected HID devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
             while (!deviceList.isEmpty()) {
@@ -87,7 +87,7 @@
         mDeviceManager = deviceManager;
         mProfileManager = profileManager;
         adapter.getProfileProxy(context, new InputDeviceServiceListener(),
-                BluetoothProfile.INPUT_DEVICE);
+                BluetoothProfile.HID_HOST);
     }
 
     public boolean isConnectable() {
@@ -190,7 +190,7 @@
         if (V) Log.d(TAG, "finalize()");
         if (mService != null) {
             try {
-                BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.INPUT_DEVICE,
+                BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.HID_HOST,
                                                                        mService);
                 mService = null;
             }catch (Throwable t) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
index 2fb6843..22674cb 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
@@ -90,6 +90,10 @@
         return mAdapter.disable();
     }
 
+    public String getAddress() {
+        return mAdapter.getAddress();
+    }
+
     void getProfileProxy(Context context,
             BluetoothProfile.ServiceListener listener, int profile) {
         mAdapter.getProfileProxy(context, listener, profile);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 0750dc7..9cda669 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -21,9 +21,9 @@
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothHeadsetClient;
+import android.bluetooth.BluetoothHidHost;
 import android.bluetooth.BluetoothMap;
 import android.bluetooth.BluetoothMapClient;
-import android.bluetooth.BluetoothInputDevice;
 import android.bluetooth.BluetoothPan;
 import android.bluetooth.BluetoothPbapClient;
 import android.bluetooth.BluetoothProfile;
@@ -123,7 +123,7 @@
         // Always add HID and PAN profiles
         mHidProfile = new HidProfile(context, mLocalAdapter, mDeviceManager, this);
         addProfile(mHidProfile, HidProfile.NAME,
-                BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
+                BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED);
 
         mPanProfile = new PanProfile(context);
         addPanProfile(mPanProfile, PanProfile.NAME,
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
index e6a152f..0b45f51 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
@@ -34,7 +34,7 @@
 /**
  * MapProfile handles Bluetooth MAP profile.
  */
-public final class MapProfile implements LocalBluetoothProfile {
+public class MapProfile implements LocalBluetoothProfile {
     private static final String TAG = "MapProfile";
     private static boolean V = true;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
index 7bda231..3299cb2 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
@@ -32,7 +32,7 @@
 /**
  * PanProfile handles Bluetooth PAN profile (NAP and PANU).
  */
-public final class PanProfile implements LocalBluetoothProfile {
+public class PanProfile implements LocalBluetoothProfile {
     private static final String TAG = "PanProfile";
     private static boolean V = true;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
index bd37abe..28137ff 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
@@ -32,7 +32,7 @@
 import java.util.Collection;
 import java.util.List;
 
-final class PbapClientProfile implements LocalBluetoothProfile {
+public final class PbapClientProfile implements LocalBluetoothProfile {
     private static final String TAG = "PbapClientProfile";
     private static boolean V = false;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
index 9e76933..f3b6912 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
@@ -25,19 +25,21 @@
 import android.os.ParcelUuid;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.R;
 
 /**
  * PBAPServer Profile
  */
-public final class PbapServerProfile implements LocalBluetoothProfile {
+public class PbapServerProfile implements LocalBluetoothProfile {
     private static final String TAG = "PbapServerProfile";
     private static boolean V = true;
 
     private BluetoothPbap mService;
     private boolean mIsProfileReady;
 
-    static final String NAME = "PBAP Server";
+    @VisibleForTesting
+    public static final String NAME = "PBAP Server";
 
     // Order of this profile in device profiles list
     private static final int ORDINAL = 6;
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/Lifecycle.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/Lifecycle.java
new file mode 100644
index 0000000..b2351a9
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/Lifecycle.java
@@ -0,0 +1,171 @@
+/*
+ * 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.settingslib.core.lifecycle;
+
+import android.annotation.UiThread;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.preference.PreferenceScreen;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+import com.android.settingslib.core.lifecycle.events.OnAttach;
+import com.android.settingslib.core.lifecycle.events.OnCreate;
+import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
+import com.android.settingslib.core.lifecycle.events.OnDestroy;
+import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
+import com.android.settingslib.core.lifecycle.events.OnPause;
+import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
+import com.android.settingslib.core.lifecycle.events.OnResume;
+import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+import com.android.settingslib.core.lifecycle.events.SetPreferenceScreen;
+import com.android.settingslib.utils.ThreadUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Dispatcher for lifecycle events.
+ */
+public class Lifecycle {
+
+    protected final List<LifecycleObserver> mObservers = new ArrayList<>();
+
+    /**
+     * Registers a new observer of lifecycle events.
+     */
+    @UiThread
+    public <T extends LifecycleObserver> T addObserver(T observer) {
+        ThreadUtils.ensureMainThread();
+        mObservers.add(observer);
+        return observer;
+    }
+
+    public void onAttach(Context context) {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnAttach) {
+                ((OnAttach) observer).onAttach(context);
+            }
+        }
+    }
+
+    public void onCreate(Bundle savedInstanceState) {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnCreate) {
+                ((OnCreate) observer).onCreate(savedInstanceState);
+            }
+        }
+    }
+
+    public void onStart() {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnStart) {
+                ((OnStart) observer).onStart();
+            }
+        }
+    }
+
+    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof SetPreferenceScreen) {
+                ((SetPreferenceScreen) observer).setPreferenceScreen(preferenceScreen);
+            }
+        }
+    }
+
+    public void onResume() {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnResume) {
+                ((OnResume) observer).onResume();
+            }
+        }
+    }
+
+    public void onPause() {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnPause) {
+                ((OnPause) observer).onPause();
+            }
+        }
+    }
+
+    public void onSaveInstanceState(Bundle outState) {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnSaveInstanceState) {
+                ((OnSaveInstanceState) observer).onSaveInstanceState(outState);
+            }
+        }
+    }
+
+    public void onStop() {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnStop) {
+                ((OnStop) observer).onStop();
+            }
+        }
+    }
+
+    public void onDestroy() {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnDestroy) {
+                ((OnDestroy) observer).onDestroy();
+            }
+        }
+    }
+
+    public void onCreateOptionsMenu(final Menu menu, final @Nullable MenuInflater inflater) {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnCreateOptionsMenu) {
+                ((OnCreateOptionsMenu) observer).onCreateOptionsMenu(menu, inflater);
+            }
+        }
+    }
+
+    public void onPrepareOptionsMenu(final Menu menu) {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnPrepareOptionsMenu) {
+                ((OnPrepareOptionsMenu) observer).onPrepareOptionsMenu(menu);
+            }
+        }
+    }
+
+    public boolean onOptionsItemSelected(final MenuItem menuItem) {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnOptionsItemSelected) {
+                if (((OnOptionsItemSelected) observer).onOptionsItemSelected(menuItem)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/LifecycleObserver.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/LifecycleObserver.java
new file mode 100644
index 0000000..6c41072
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/LifecycleObserver.java
@@ -0,0 +1,22 @@
+/*
+ * 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.settingslib.core.lifecycle;
+
+/**
+ * Observer of lifecycle events.
+ */
+public interface LifecycleObserver {
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableActivity.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableActivity.java
new file mode 100644
index 0000000..727bec7
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableActivity.java
@@ -0,0 +1,105 @@
+/*
+ * 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.settingslib.core.lifecycle;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.view.Menu;
+import android.view.MenuItem;
+
+/**
+ * {@link Activity} that has hooks to observe activity lifecycle events.
+ */
+public class ObservableActivity extends Activity {
+
+    private final Lifecycle mLifecycle = new Lifecycle();
+
+    protected Lifecycle getLifecycle() {
+        return mLifecycle;
+    }
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        mLifecycle.onAttach(this);
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState,
+            @Nullable PersistableBundle persistentState) {
+        mLifecycle.onAttach(this);
+        super.onCreate(savedInstanceState, persistentState);
+    }
+
+    @Override
+    protected void onStart() {
+        mLifecycle.onStart();
+        super.onStart();
+    }
+
+    @Override
+    protected void onResume() {
+        mLifecycle.onResume();
+        super.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        mLifecycle.onPause();
+        super.onPause();
+    }
+
+    @Override
+    protected void onStop() {
+        mLifecycle.onStop();
+        super.onStop();
+    }
+
+    @Override
+    protected void onDestroy() {
+        mLifecycle.onDestroy();
+        super.onDestroy();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(final Menu menu) {
+        if (super.onCreateOptionsMenu(menu)) {
+            mLifecycle.onCreateOptionsMenu(menu, null);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(final Menu menu) {
+        if (super.onPrepareOptionsMenu(menu)) {
+            mLifecycle.onPrepareOptionsMenu(menu);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(final MenuItem menuItem) {
+        boolean lifecycleHandled = mLifecycle.onOptionsItemSelected(menuItem);
+        if (!lifecycleHandled) {
+            return super.onOptionsItemSelected(menuItem);
+        }
+        return lifecycleHandled;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableDialogFragment.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableDialogFragment.java
new file mode 100644
index 0000000..315bedc
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableDialogFragment.java
@@ -0,0 +1,94 @@
+/*
+ * 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.settingslib.core.lifecycle;
+
+import android.app.DialogFragment;
+import android.content.Context;
+import android.support.annotation.VisibleForTesting;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+/**
+ * {@link DialogFragment} that has hooks to observe fragment lifecycle events.
+ */
+public class ObservableDialogFragment extends DialogFragment {
+
+    protected final Lifecycle mLifecycle = createLifecycle();
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        mLifecycle.onAttach(context);
+    }
+
+    @Override
+    public void onStart() {
+        mLifecycle.onStart();
+        super.onStart();
+    }
+
+    @Override
+    public void onResume() {
+        mLifecycle.onResume();
+        super.onResume();
+    }
+
+    @Override
+    public void onPause() {
+        mLifecycle.onPause();
+        super.onPause();
+    }
+
+    @Override
+    public void onStop() {
+        mLifecycle.onStop();
+        super.onStop();
+    }
+
+    @Override
+    public void onDestroy() {
+        mLifecycle.onDestroy();
+        super.onDestroy();
+    }
+
+    @Override
+    public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
+        mLifecycle.onCreateOptionsMenu(menu, inflater);
+        super.onCreateOptionsMenu(menu, inflater);
+    }
+
+    @Override
+    public void onPrepareOptionsMenu(final Menu menu) {
+        mLifecycle.onPrepareOptionsMenu(menu);
+        super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(final MenuItem menuItem) {
+        boolean lifecycleHandled = mLifecycle.onOptionsItemSelected(menuItem);
+        if (!lifecycleHandled) {
+            return super.onOptionsItemSelected(menuItem);
+        }
+        return lifecycleHandled;
+    }
+
+    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+    /** @return a new lifecycle. */
+    public static Lifecycle createLifecycle() {
+        return new Lifecycle();
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableFragment.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableFragment.java
new file mode 100644
index 0000000..3a00eba
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableFragment.java
@@ -0,0 +1,114 @@
+/*
+ * 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.settingslib.core.lifecycle;
+
+import android.annotation.CallSuper;
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+public class ObservableFragment extends Fragment {
+
+    private final Lifecycle mLifecycle = new Lifecycle();
+
+    protected Lifecycle getLifecycle() {
+        return mLifecycle;
+    }
+
+    @CallSuper
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        mLifecycle.onAttach(context);
+    }
+
+    @CallSuper
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        mLifecycle.onCreate(savedInstanceState);
+        super.onCreate(savedInstanceState);
+    }
+
+    @CallSuper
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        mLifecycle.onSaveInstanceState(outState);
+    }
+
+    @CallSuper
+    @Override
+    public void onStart() {
+        mLifecycle.onStart();
+        super.onStart();
+    }
+
+    @CallSuper
+    @Override
+    public void onStop() {
+        mLifecycle.onStop();
+        super.onStop();
+    }
+
+    @CallSuper
+    @Override
+    public void onResume() {
+        mLifecycle.onResume();
+        super.onResume();
+    }
+
+    @CallSuper
+    @Override
+    public void onPause() {
+        mLifecycle.onPause();
+        super.onPause();
+    }
+
+    @CallSuper
+    @Override
+    public void onDestroy() {
+        mLifecycle.onDestroy();
+        super.onDestroy();
+    }
+
+    @CallSuper
+    @Override
+    public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
+        mLifecycle.onCreateOptionsMenu(menu, inflater);
+        super.onCreateOptionsMenu(menu, inflater);
+    }
+
+    @CallSuper
+    @Override
+    public void onPrepareOptionsMenu(final Menu menu) {
+        mLifecycle.onPrepareOptionsMenu(menu);
+        super.onPrepareOptionsMenu(menu);
+    }
+
+    @CallSuper
+    @Override
+    public boolean onOptionsItemSelected(final MenuItem menuItem) {
+        boolean lifecycleHandled = mLifecycle.onOptionsItemSelected(menuItem);
+        if (!lifecycleHandled) {
+            return super.onOptionsItemSelected(menuItem);
+        }
+        return lifecycleHandled;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java
new file mode 100644
index 0000000..76e5c85
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java
@@ -0,0 +1,124 @@
+/*
+ * 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.settingslib.core.lifecycle;
+
+
+import android.annotation.CallSuper;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.PreferenceScreen;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+/**
+ * {@link PreferenceFragment} that has hooks to observe fragment lifecycle events.
+ */
+public abstract class ObservablePreferenceFragment extends PreferenceFragment {
+
+    private final Lifecycle mLifecycle = new Lifecycle();
+
+    protected Lifecycle getLifecycle() {
+        return mLifecycle;
+    }
+
+    @CallSuper
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        mLifecycle.onAttach(context);
+    }
+
+    @CallSuper
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        mLifecycle.onCreate(savedInstanceState);
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+        mLifecycle.setPreferenceScreen(preferenceScreen);
+        super.setPreferenceScreen(preferenceScreen);
+    }
+
+    @CallSuper
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        mLifecycle.onSaveInstanceState(outState);
+    }
+
+    @CallSuper
+    @Override
+    public void onStart() {
+        mLifecycle.onStart();
+        super.onStart();
+    }
+
+    @CallSuper
+    @Override
+    public void onStop() {
+        mLifecycle.onStop();
+        super.onStop();
+    }
+
+    @CallSuper
+    @Override
+    public void onResume() {
+        mLifecycle.onResume();
+        super.onResume();
+    }
+
+    @CallSuper
+    @Override
+    public void onPause() {
+        mLifecycle.onPause();
+        super.onPause();
+    }
+
+    @CallSuper
+    @Override
+    public void onDestroy() {
+        mLifecycle.onDestroy();
+        super.onDestroy();
+    }
+
+    @CallSuper
+    @Override
+    public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
+        mLifecycle.onCreateOptionsMenu(menu, inflater);
+        super.onCreateOptionsMenu(menu, inflater);
+    }
+
+    @CallSuper
+    @Override
+    public void onPrepareOptionsMenu(final Menu menu) {
+        mLifecycle.onPrepareOptionsMenu(menu);
+        super.onPrepareOptionsMenu(menu);
+    }
+
+    @CallSuper
+    @Override
+    public boolean onOptionsItemSelected(final MenuItem menuItem) {
+        boolean lifecycleHandled = mLifecycle.onOptionsItemSelected(menuItem);
+        if (!lifecycleHandled) {
+            return super.onOptionsItemSelected(menuItem);
+        }
+        return lifecycleHandled;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnAttach.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnAttach.java
new file mode 100644
index 0000000..152cbac
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnAttach.java
@@ -0,0 +1,22 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+import android.content.Context;
+
+public interface OnAttach {
+    void onAttach(Context context);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreate.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreate.java
new file mode 100644
index 0000000..44cbf8d
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreate.java
@@ -0,0 +1,23 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+
+import android.os.Bundle;
+
+public interface OnCreate {
+    void onCreate(Bundle savedInstanceState);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreateOptionsMenu.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreateOptionsMenu.java
new file mode 100644
index 0000000..c14b7d7
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreateOptionsMenu.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.core.lifecycle.events;
+
+import android.view.Menu;
+import android.view.MenuInflater;
+
+public interface OnCreateOptionsMenu {
+    void onCreateOptionsMenu(Menu menu, MenuInflater inflater);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnDestroy.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnDestroy.java
new file mode 100644
index 0000000..ffa3d16
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnDestroy.java
@@ -0,0 +1,20 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+public interface OnDestroy {
+    void onDestroy();
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnOptionsItemSelected.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnOptionsItemSelected.java
new file mode 100644
index 0000000..bcb3032
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnOptionsItemSelected.java
@@ -0,0 +1,23 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+import android.view.MenuItem;
+
+public interface OnOptionsItemSelected {
+    boolean onOptionsItemSelected(MenuItem menuItem);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPause.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPause.java
new file mode 100644
index 0000000..4a71105
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPause.java
@@ -0,0 +1,20 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+public interface OnPause {
+    void onPause();
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPrepareOptionsMenu.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPrepareOptionsMenu.java
new file mode 100644
index 0000000..b9f1371
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPrepareOptionsMenu.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.core.lifecycle.events;
+
+import android.view.Menu;
+import android.view.MenuInflater;
+
+public interface OnPrepareOptionsMenu {
+    void onPrepareOptionsMenu(Menu menu);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnResume.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnResume.java
new file mode 100644
index 0000000..8dd24e9
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnResume.java
@@ -0,0 +1,20 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+public interface OnResume {
+    void onResume();
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnSaveInstanceState.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnSaveInstanceState.java
new file mode 100644
index 0000000..9d46110
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnSaveInstanceState.java
@@ -0,0 +1,23 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+import android.os.Bundle;
+
+
+public interface OnSaveInstanceState {
+    void onSaveInstanceState(Bundle outState);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStart.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStart.java
new file mode 100644
index 0000000..c88ddaa
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStart.java
@@ -0,0 +1,21 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+public interface OnStart {
+
+    void onStart();
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStop.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStop.java
new file mode 100644
index 0000000..32f61d9
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStop.java
@@ -0,0 +1,21 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+public interface OnStop {
+
+    void onStop();
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/SetPreferenceScreen.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/SetPreferenceScreen.java
new file mode 100644
index 0000000..cdd72fb
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/SetPreferenceScreen.java
@@ -0,0 +1,24 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+import android.support.v7.preference.PreferenceScreen;
+
+public interface SetPreferenceScreen {
+
+    void setPreferenceScreen(PreferenceScreen preferenceScreen);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
index 9d09737..e067de1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
@@ -34,6 +34,8 @@
     public static final String CATEGORY_SOUND = "com.android.settings.category.ia.sound";
     public static final String CATEGORY_STORAGE = "com.android.settings.category.ia.storage";
     public static final String CATEGORY_SECURITY = "com.android.settings.category.ia.security";
+    public static final String CATEGORY_SECURITY_LOCKSCREEN =
+            "com.android.settings.category.ia.lockscreen";
     public static final String CATEGORY_ACCOUNT = "com.android.settings.category.ia.accounts";
     public static final String CATEGORY_SYSTEM = "com.android.settings.category.ia.system";
     public static final String CATEGORY_SYSTEM_LANGUAGE =
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java b/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java
index 512049f..c79b1466d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java
@@ -68,10 +68,8 @@
     public void onClick(DialogInterface dialog, int which) {
         UserHandle user = mSelectedTile.userHandle.get(which);
         // Show menu on top level items.
-        mSelectedTile.intent.putExtra(SettingsDrawerActivity.EXTRA_SHOW_MENU, true);
         mSelectedTile.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
         getActivity().startActivityAsUser(mSelectedTile.intent, user);
-        ((SettingsDrawerActivity) getActivity()).onProfileTileOpen();
     }
 
     public static void updateUserHandlesIfNeeded(Context context, Tile tile) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
index c7efb07..f1d43bf 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
@@ -23,6 +23,7 @@
 import android.os.Parcelable;
 import android.os.UserHandle;
 import android.text.TextUtils;
+import android.widget.RemoteViews;
 
 import java.util.ArrayList;
 
@@ -50,6 +51,12 @@
     public Icon icon;
 
     /**
+     * Whether the icon can be tinted. This should be set to true for monochrome (single-color)
+     * icons that can be tinted to match the design.
+     */
+    public boolean isIconTintable;
+
+    /**
      * Intent to launch when the preference is selected.
      */
     public Intent intent;
@@ -84,6 +91,11 @@
      */
     public String key;
 
+    /**
+     * Optional remote view which will be displayed instead of the regular title-summary item.
+     */
+    public RemoteViews remoteViews;
+
     public Tile() {
         // Empty
     }
@@ -119,6 +131,8 @@
         dest.writeInt(priority);
         dest.writeBundle(metaData);
         dest.writeString(key);
+        dest.writeParcelable(remoteViews, flags);
+        dest.writeBoolean(isIconTintable);
     }
 
     public void readFromParcel(Parcel in) {
@@ -139,6 +153,8 @@
         priority = in.readInt();
         metaData = in.readBundle();
         key = in.readString();
+        remoteViews = in.readParcelable(RemoteViews.class.getClassLoader());
+        isIconTintable = in.readBoolean();
     }
 
     Tile(Parcel in) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
index fb48054..9620a91 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
@@ -21,7 +21,6 @@
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
@@ -35,6 +34,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
+import android.widget.RemoteViews;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -133,15 +133,25 @@
 
     /**
      * Name of the meta-data item that should be set in the AndroidManifest.xml
-     * to specify the title that should be displayed for the preference.
+     * to specify whether the icon is tintable. This should be a boolean value {@code true} or
+     * {@code false}, set using {@code android:value}
      */
-    @Deprecated
-    public static final String META_DATA_PREFERENCE_TITLE = "com.android.settings.title";
+    public static final String META_DATA_PREFERENCE_ICON_TINTABLE =
+            "com.android.settings.icon_tintable";
 
     /**
      * Name of the meta-data item that should be set in the AndroidManifest.xml
      * to specify the title that should be displayed for the preference.
+     *
+     * <p>Note: It is preferred to provide this value using {@code android:resource} with a string
+     * resource for localization.
      */
+    public static final String META_DATA_PREFERENCE_TITLE = "com.android.settings.title";
+
+    /**
+     * @deprecated Use {@link #META_DATA_PREFERENCE_TITLE} with {@code android:resource}
+     */
+    @Deprecated
     public static final String META_DATA_PREFERENCE_TITLE_RES_ID =
             "com.android.settings.title.resid";
 
@@ -161,6 +171,17 @@
     public static final String META_DATA_PREFERENCE_SUMMARY_URI =
             "com.android.settings.summary_uri";
 
+    /**
+     * Name of the meta-data item that should be set in the AndroidManifest.xml to specify the
+     * custom view which should be displayed for the preference. The custom view will be inflated
+     * as a remote view.
+     *
+     * This also can be used with {@link META_DATA_PREFERENCE_SUMMARY_URI} above, by setting the id
+     * of the summary TextView to '@android:id/summary'.
+     */
+    public static final String META_DATA_PREFERENCE_CUSTOM_VIEW =
+            "com.android.settings.custom_view";
+
     public static final String SETTING_PKG = "com.android.settings";
 
     /**
@@ -298,15 +319,17 @@
             intent.setPackage(settingPkg);
         }
         getTilesForIntent(context, user, intent, addedCache, defaultCategory, outTiles,
-                usePriority, true);
+                usePriority, true, true);
     }
 
-    public static void getTilesForIntent(Context context, UserHandle user, Intent intent,
+    public static void getTilesForIntent(
+            Context context, UserHandle user, Intent intent,
             Map<Pair<String, String>, Tile> addedCache, String defaultCategory, List<Tile> outTiles,
-            boolean usePriority, boolean checkCategory) {
+            boolean usePriority, boolean checkCategory, boolean forceTintExternalIcon) {
         PackageManager pm = context.getPackageManager();
         List<ResolveInfo> results = pm.queryIntentActivitiesAsUser(intent,
                 PackageManager.GET_META_DATA, user.getIdentifier());
+        Map<String, IContentProvider> providerMap = new HashMap<>();
         for (ResolveInfo resolved : results) {
             if (!resolved.system) {
                 // Do not allow any app to add to settings, only system ones.
@@ -338,7 +361,7 @@
                 tile.priority = usePriority ? resolved.priority : 0;
                 tile.metaData = activityInfo.metaData;
                 updateTileData(context, tile, activityInfo, activityInfo.applicationInfo,
-                        pm);
+                        pm, providerMap, forceTintExternalIcon);
                 if (DEBUG) Log.d(LOG_TAG, "Adding tile " + tile.title);
 
                 addedCache.put(key, tile);
@@ -353,25 +376,41 @@
     }
 
     private static boolean updateTileData(Context context, Tile tile,
-            ActivityInfo activityInfo, ApplicationInfo applicationInfo, PackageManager pm) {
+            ActivityInfo activityInfo, ApplicationInfo applicationInfo, PackageManager pm,
+            Map<String, IContentProvider> providerMap, boolean forceTintExternalIcon) {
         if (applicationInfo.isSystemApp()) {
+            boolean forceTintIcon = false;
             int icon = 0;
             Pair<String, Integer> iconFromUri = null;
             CharSequence title = null;
             String summary = null;
             String keyHint = null;
-            Uri uri = null;
+            boolean isIconTintable = false;
+            RemoteViews remoteViews = null;
 
             // Get the activity's meta-data
             try {
-                Resources res = pm.getResourcesForApplication(
-                        applicationInfo.packageName);
+                Resources res = pm.getResourcesForApplication(applicationInfo.packageName);
                 Bundle metaData = activityInfo.metaData;
 
+                if (forceTintExternalIcon
+                        && !context.getPackageName().equals(applicationInfo.packageName)) {
+                    isIconTintable = true;
+                    forceTintIcon = true;
+                }
+
                 if (res != null && metaData != null) {
                     if (metaData.containsKey(META_DATA_PREFERENCE_ICON)) {
                         icon = metaData.getInt(META_DATA_PREFERENCE_ICON);
                     }
+                    if (metaData.containsKey(META_DATA_PREFERENCE_ICON_TINTABLE)) {
+                        if (forceTintIcon) {
+                            Log.w(LOG_TAG, "Ignoring icon tintable for " + activityInfo);
+                        } else {
+                            isIconTintable =
+                                    metaData.getBoolean(META_DATA_PREFERENCE_ICON_TINTABLE);
+                        }
+                    }
                     int resId = 0;
                     if (metaData.containsKey(META_DATA_PREFERENCE_TITLE_RES_ID)) {
                         resId = metaData.getInt(META_DATA_PREFERENCE_TITLE_RES_ID);
@@ -379,8 +418,6 @@
                             title = res.getString(resId);
                         }
                     }
-                    // Fallback to legacy title extraction if we couldn't get the title through
-                    // res id.
                     if ((resId == 0) && metaData.containsKey(META_DATA_PREFERENCE_TITLE)) {
                         if (metaData.get(META_DATA_PREFERENCE_TITLE) instanceof Integer) {
                             title = res.getString(metaData.getInt(META_DATA_PREFERENCE_TITLE));
@@ -402,6 +439,19 @@
                             keyHint = metaData.getString(META_DATA_PREFERENCE_KEYHINT);
                         }
                     }
+                    if (metaData.containsKey(META_DATA_PREFERENCE_CUSTOM_VIEW)) {
+                        int layoutId = metaData.getInt(META_DATA_PREFERENCE_CUSTOM_VIEW);
+                        remoteViews = new RemoteViews(applicationInfo.packageName, layoutId);
+                        if (metaData.containsKey(META_DATA_PREFERENCE_SUMMARY_URI)) {
+                            String uriString = metaData.getString(
+                                    META_DATA_PREFERENCE_SUMMARY_URI);
+                            String overrideSummary = getTextFromUri(context, uriString, providerMap,
+                                    META_DATA_PREFERENCE_SUMMARY);
+                            if (overrideSummary != null) {
+                                remoteViews.setTextViewText(android.R.id.summary, overrideSummary);
+                            }
+                        }
+                    }
                 }
             } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
                 if (DEBUG) Log.d(LOG_TAG, "Couldn't find info", e);
@@ -431,6 +481,8 @@
                     activityInfo.name);
             // Suggest a key for this tile
             tile.key = keyHint;
+            tile.isIconTintable = isIconTintable;
+            tile.remoteViews = remoteViews;
 
             return true;
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
index e5cdc85..988060e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
@@ -16,6 +16,7 @@
 
 package com.android.settingslib.dream;
 
+import android.annotation.IntDef;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -35,6 +36,8 @@
 import android.util.Log;
 import android.util.Xml;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -68,6 +71,15 @@
         }
     }
 
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({WHILE_CHARGING, WHILE_DOCKED, EITHER, NEVER})
+    public @interface WhenToDream{}
+
+    public static final int WHILE_CHARGING = 0;
+    public static final int WHILE_DOCKED = 1;
+    public static final int EITHER = 2;
+    public static final int NEVER = 3;
+
     private final Context mContext;
     private final IDreamManager mDreamManager;
     private final DreamInfoComparator mComparator;
@@ -75,6 +87,15 @@
     private final boolean mDreamsActivatedOnSleepByDefault;
     private final boolean mDreamsActivatedOnDockByDefault;
 
+    private static DreamBackend sInstance;
+
+    public static DreamBackend getInstance(Context context) {
+        if (sInstance == null) {
+            sInstance = new DreamBackend(context);
+        }
+        return sInstance;
+    }
+
     public DreamBackend(Context context) {
         mContext = context;
         mDreamManager = IDreamManager.Stub.asInterface(
@@ -138,6 +159,42 @@
         return null;
     }
 
+    public @WhenToDream int getWhenToDreamSetting() {
+        if (!isEnabled()) {
+            return NEVER;
+        }
+        return isActivatedOnDock() && isActivatedOnSleep() ? EITHER
+                : isActivatedOnDock() ? WHILE_DOCKED
+                : isActivatedOnSleep() ? WHILE_CHARGING
+                : NEVER;
+    }
+
+    public void setWhenToDream(@WhenToDream int whenToDream) {
+        setEnabled(whenToDream != NEVER);
+
+        switch (whenToDream) {
+            case WHILE_CHARGING:
+                setActivatedOnDock(false);
+                setActivatedOnSleep(true);
+                break;
+
+            case WHILE_DOCKED:
+                setActivatedOnDock(true);
+                setActivatedOnSleep(false);
+                break;
+
+            case EITHER:
+                setActivatedOnDock(true);
+                setActivatedOnSleep(true);
+                break;
+
+            case NEVER:
+            default:
+                break;
+        }
+
+    }
+
     public boolean isEnabled() {
         return getBoolean(Settings.Secure.SCREENSAVER_ENABLED, mDreamsEnabledByDefault);
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
index 3d50f23..426dc7c 100755
--- a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
@@ -26,6 +26,9 @@
 import android.graphics.ColorFilter;
 import android.graphics.Paint;
 import android.graphics.Path;
+import android.graphics.Path.Direction;
+import android.graphics.Path.FillType;
+import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
@@ -36,8 +39,9 @@
 
 public class BatteryMeterDrawableBase extends Drawable {
 
-    private static final float ASPECT_RATIO = 9.5f / 14.5f;
+    private static final float ASPECT_RATIO = .58f;
     public static final String TAG = BatteryMeterDrawableBase.class.getSimpleName();
+    private static final float RADIUS_RATIO = 1.0f / 17f;
 
     protected final Context mContext;
     protected final Paint mFramePaint;
@@ -79,6 +83,7 @@
     private final float[] mPlusPoints;
     private final Path mPlusPath = new Path();
 
+    private final Rect mPadding = new Rect();
     private final RectF mFrame = new RectF();
     private final RectF mButtonFrame = new RectF();
     private final RectF mBoltFrame = new RectF();
@@ -216,12 +221,40 @@
     @Override
     public void setBounds(int left, int top, int right, int bottom) {
         super.setBounds(left, top, right, bottom);
-        mHeight = bottom - top;
-        mWidth = right - left;
+        updateSize();
+    }
+
+    private void updateSize() {
+        final Rect bounds = getBounds();
+
+        mHeight = (bounds.bottom - mPadding.bottom) - (bounds.top + mPadding.top);
+        mWidth = (bounds.right - mPadding.right) - (bounds.left + mPadding.left);
         mWarningTextPaint.setTextSize(mHeight * 0.75f);
         mWarningTextHeight = -mWarningTextPaint.getFontMetrics().ascent;
     }
 
+    @Override
+    public boolean getPadding(Rect padding) {
+        if (mPadding.left == 0
+            && mPadding.top == 0
+            && mPadding.right == 0
+            && mPadding.bottom == 0) {
+            return super.getPadding(padding);
+        }
+
+        padding.set(mPadding);
+        return true;
+    }
+
+    public void setPadding(int left, int top, int right, int bottom) {
+        mPadding.left = left;
+        mPadding.top = top;
+        mPadding.right = right;
+        mPadding.bottom = bottom;
+
+        updateSize();
+    }
+
     private int getColorForLevel(int percent) {
         // If we are in power save mode, always use the normal color.
         if (mPowerSaveEnabled) {
@@ -248,10 +281,15 @@
         mIconTint = fillColor;
         mFramePaint.setColor(backgroundColor);
         mBoltPaint.setColor(fillColor);
+        mPlusPaint.setColor(fillColor);
         mChargeColor = fillColor;
         invalidateSelf();
     }
 
+    protected int batteryColorForLevel(int level) {
+        return mCharging ? mChargeColor : getColorForLevel(level);
+    }
+
     @Override
     public void draw(Canvas c) {
         final int level = mLevel;
@@ -261,33 +299,24 @@
         float drawFrac = (float) level / 100f;
         final int height = mHeight;
         final int width = (int) (ASPECT_RATIO * mHeight);
-        int px = (mWidth - width) / 2;
+        final int px = (mWidth - width) / 2;
+        final int buttonHeight = Math.round(height * mButtonHeightFraction);
 
-        final int buttonHeight = (int) (height * mButtonHeightFraction);
-
-        mFrame.set(0, 0, width, height);
+        mFrame.set(mPadding.left, mPadding.top, width + mPadding.left, height + mPadding.top);
         mFrame.offset(px, 0);
 
         // button-frame: area above the battery body
         mButtonFrame.set(
-                mFrame.left + Math.round(width * 0.25f),
+                mFrame.left + Math.round(width * 0.28f),
                 mFrame.top,
-                mFrame.right - Math.round(width * 0.25f),
+                mFrame.right - Math.round(width * 0.28f),
                 mFrame.top + buttonHeight);
 
-        mButtonFrame.top += mSubpixelSmoothingLeft;
-        mButtonFrame.left += mSubpixelSmoothingLeft;
-        mButtonFrame.right -= mSubpixelSmoothingRight;
-
         // frame: battery body area
         mFrame.top += buttonHeight;
-        mFrame.left += mSubpixelSmoothingLeft;
-        mFrame.top += mSubpixelSmoothingLeft;
-        mFrame.right -= mSubpixelSmoothingRight;
-        mFrame.bottom -= mSubpixelSmoothingRight;
 
         // set the battery charging color
-        mBatteryPaint.setColor(mCharging ? mChargeColor : getColorForLevel(level));
+        mBatteryPaint.setColor(batteryColorForLevel(level));
 
         if (level >= FULL) {
             drawFrac = 1f;
@@ -300,21 +329,17 @@
 
         // define the battery shape
         mShapePath.reset();
-        mShapePath.moveTo(mButtonFrame.left, mButtonFrame.top);
-        mShapePath.lineTo(mButtonFrame.right, mButtonFrame.top);
-        mShapePath.lineTo(mButtonFrame.right, mFrame.top);
-        mShapePath.lineTo(mFrame.right, mFrame.top);
-        mShapePath.lineTo(mFrame.right, mFrame.bottom);
-        mShapePath.lineTo(mFrame.left, mFrame.bottom);
-        mShapePath.lineTo(mFrame.left, mFrame.top);
-        mShapePath.lineTo(mButtonFrame.left, mFrame.top);
-        mShapePath.lineTo(mButtonFrame.left, mButtonFrame.top);
+        final float radius = RADIUS_RATIO * (mFrame.height() + buttonHeight);
+        mShapePath.setFillType(FillType.WINDING);
+        mShapePath.addRoundRect(mFrame, radius, radius, Direction.CW);
+        mShapePath.addRect(mButtonFrame, Direction.CW);
 
         if (mCharging) {
             // define the bolt shape
-            final float bl = mFrame.left + mFrame.width() / 4f;
+            // Shift right by 1px for maximal bolt-goodness
+            final float bl = mFrame.left + mFrame.width() / 4f + 1;
             final float bt = mFrame.top + mFrame.height() / 6f;
-            final float br = mFrame.right - mFrame.width() / 4f;
+            final float br = mFrame.right - mFrame.width() / 4f + 1;
             final float bb = mFrame.bottom - mFrame.height() / 10f;
             if (mBoltFrame.left != bl || mBoltFrame.top != bt
                     || mBoltFrame.right != br || mBoltFrame.bottom != bb) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BottomLabelLayout.java b/packages/SettingsLib/src/com/android/settingslib/graph/BottomLabelLayout.java
deleted file mode 100644
index 8161dd4..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/graph/BottomLabelLayout.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *
- */
-
-package com.android.settingslib.graph;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.support.annotation.VisibleForTesting;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.android.settingslib.R;
-
-/**
- * An extension of LinearLayout that automatically switches to vertical
- * orientation when it can't fit its child views horizontally.
- *
- * Main logic in this class comes from {@link android.support.v7.widget.ButtonBarLayout}.
- * Compared with {@link android.support.v7.widget.ButtonBarLayout}, this layout won't reverse
- * children's order and won't update the minimum height
- */
-public class BottomLabelLayout extends LinearLayout {
-    private static final String TAG = "BottomLabelLayout";
-
-    public BottomLabelLayout(Context context,
-            @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-        final boolean isStacked = isStacked();
-        boolean needsRemeasure = false;
-
-        // If we're not stacked, make sure the measure spec is AT_MOST rather
-        // than EXACTLY. This ensures that we'll still get TOO_SMALL so that we
-        // know to stack the buttons.
-        final int initialWidthMeasureSpec;
-        if (!isStacked && MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
-            initialWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.AT_MOST);
-
-            // We'll need to remeasure again to fill excess space.
-            needsRemeasure = true;
-        } else {
-            initialWidthMeasureSpec = widthMeasureSpec;
-        }
-
-        super.onMeasure(initialWidthMeasureSpec, heightMeasureSpec);
-        if (!isStacked) {
-            final int measuredWidth = getMeasuredWidthAndState();
-            final int measuredWidthState = measuredWidth & View.MEASURED_STATE_MASK;
-
-            if (measuredWidthState == View.MEASURED_STATE_TOO_SMALL) {
-                setStacked(true);
-                // Measure again in the new orientation.
-                needsRemeasure = true;
-            }
-        }
-
-        if (needsRemeasure) {
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        }
-
-    }
-
-    @VisibleForTesting
-    void setStacked(boolean stacked) {
-        setOrientation(stacked ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL);
-        setGravity(stacked ? Gravity.START : Gravity.BOTTOM);
-
-        final View spacer = findViewById(R.id.spacer);
-        if (spacer != null) {
-            spacer.setVisibility(stacked ? View.GONE : View.VISIBLE);
-        }
-    }
-
-    private boolean isStacked() {
-        return getOrientation() == LinearLayout.VERTICAL;
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/UsageGraph.java b/packages/SettingsLib/src/com/android/settingslib/graph/UsageGraph.java
deleted file mode 100644
index 1fff0fb..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/graph/UsageGraph.java
+++ /dev/null
@@ -1,277 +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.settingslib.graph;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.CornerPathEffect;
-import android.graphics.DashPathEffect;
-import android.graphics.LinearGradient;
-import android.graphics.Paint;
-import android.graphics.Paint.Cap;
-import android.graphics.Paint.Join;
-import android.graphics.Paint.Style;
-import android.graphics.Path;
-import android.graphics.Shader.TileMode;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.SparseIntArray;
-import android.util.TypedValue;
-import android.view.View;
-import com.android.settingslib.R;
-
-public class UsageGraph extends View {
-
-    private static final int PATH_DELIM = -1;
-
-    private final Paint mLinePaint;
-    private final Paint mFillPaint;
-    private final Paint mDottedPaint;
-
-    private final Drawable mDivider;
-    private final Drawable mTintedDivider;
-    private final int mDividerSize;
-
-    private final Path mPath = new Path();
-
-    // Paths in coordinates they are passed in.
-    private final SparseIntArray mPaths = new SparseIntArray();
-    // Paths in local coordinates for drawing.
-    private final SparseIntArray mLocalPaths = new SparseIntArray();
-    private final int mCornerRadius;
-
-    private int mAccentColor;
-    private boolean mShowProjection;
-    private boolean mProjectUp;
-
-    private float mMaxX = 100;
-    private float mMaxY = 100;
-
-    private float mMiddleDividerLoc = .5f;
-    private int mMiddleDividerTint = -1;
-    private int mTopDividerTint = -1;
-
-    public UsageGraph(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-        final Resources resources = context.getResources();
-
-        mLinePaint = new Paint();
-        mLinePaint.setStyle(Style.STROKE);
-        mLinePaint.setStrokeCap(Cap.ROUND);
-        mLinePaint.setStrokeJoin(Join.ROUND);
-        mLinePaint.setAntiAlias(true);
-        mCornerRadius = resources.getDimensionPixelSize(R.dimen.usage_graph_line_corner_radius);
-        mLinePaint.setPathEffect(new CornerPathEffect(mCornerRadius));
-        mLinePaint.setStrokeWidth(resources.getDimensionPixelSize(R.dimen.usage_graph_line_width));
-
-        mFillPaint = new Paint(mLinePaint);
-        mFillPaint.setStyle(Style.FILL);
-
-        mDottedPaint = new Paint(mLinePaint);
-        mDottedPaint.setStyle(Style.STROKE);
-        float dots = resources.getDimensionPixelSize(R.dimen.usage_graph_dot_size);
-        float interval = resources.getDimensionPixelSize(R.dimen.usage_graph_dot_interval);
-        mDottedPaint.setStrokeWidth(dots * 3);
-        mDottedPaint.setPathEffect(new DashPathEffect(new float[] {dots, interval}, 0));
-        mDottedPaint.setColor(context.getColor(R.color.usage_graph_dots));
-
-        TypedValue v = new TypedValue();
-        context.getTheme().resolveAttribute(com.android.internal.R.attr.listDivider, v, true);
-        mDivider = context.getDrawable(v.resourceId);
-        mTintedDivider = context.getDrawable(v.resourceId);
-        mDividerSize = resources.getDimensionPixelSize(R.dimen.usage_graph_divider_size);
-    }
-
-    void clearPaths() {
-        mPaths.clear();
-    }
-
-    void setMax(int maxX, int maxY) {
-        mMaxX = maxX;
-        mMaxY = maxY;
-    }
-
-    void setDividerLoc(int height) {
-        mMiddleDividerLoc = 1 - height / mMaxY;
-    }
-
-    void setDividerColors(int middleColor, int topColor) {
-        mMiddleDividerTint = middleColor;
-        mTopDividerTint = topColor;
-    }
-
-    public void addPath(SparseIntArray points) {
-        for (int i = 0; i < points.size(); i++) {
-            mPaths.put(points.keyAt(i), points.valueAt(i));
-        }
-        mPaths.put(points.keyAt(points.size() - 1) + 1, PATH_DELIM);
-        calculateLocalPaths();
-        postInvalidate();
-    }
-
-    void setAccentColor(int color) {
-        mAccentColor = color;
-        mLinePaint.setColor(mAccentColor);
-        updateGradient();
-        postInvalidate();
-    }
-
-    void setShowProjection(boolean showProjection, boolean projectUp) {
-        mShowProjection = showProjection;
-        mProjectUp = projectUp;
-        postInvalidate();
-    }
-
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        super.onSizeChanged(w, h, oldw, oldh);
-        updateGradient();
-        calculateLocalPaths();
-    }
-
-    private void calculateLocalPaths() {
-        if (getWidth() == 0) return;
-        mLocalPaths.clear();
-        int pendingXLoc = 0;
-        int pendingYLoc = PATH_DELIM;
-        for (int i = 0; i < mPaths.size(); i++) {
-            int x = mPaths.keyAt(i);
-            int y = mPaths.valueAt(i);
-            if (y == PATH_DELIM) {
-                if (i == mPaths.size() - 1 && pendingYLoc != PATH_DELIM) {
-                    // Connect to the end of the graph.
-                    mLocalPaths.put(pendingXLoc, pendingYLoc);
-                }
-                // Clear out any pending points.
-                pendingYLoc = PATH_DELIM;
-                mLocalPaths.put(pendingXLoc + 1, PATH_DELIM);
-            } else {
-                final int lx = getX(x);
-                final int ly = getY(y);
-                pendingXLoc = lx;
-                if (mLocalPaths.size() > 0) {
-                    int lastX = mLocalPaths.keyAt(mLocalPaths.size() - 1);
-                    int lastY = mLocalPaths.valueAt(mLocalPaths.size() - 1);
-                    if (lastY != PATH_DELIM && !hasDiff(lastX, lx) && !hasDiff(lastY, ly)) {
-                        pendingYLoc = ly;
-                        continue;
-                    }
-                }
-                mLocalPaths.put(lx, ly);
-            }
-        }
-    }
-
-    private boolean hasDiff(int x1, int x2) {
-        return Math.abs(x2 - x1) >= mCornerRadius;
-    }
-
-    private int getX(float x) {
-        return (int) (x / mMaxX * getWidth());
-    }
-
-    private int getY(float y) {
-        return (int) (getHeight() * (1 - (y / mMaxY)));
-    }
-
-    private void updateGradient() {
-        mFillPaint.setShader(new LinearGradient(0, 0, 0, getHeight(),
-                getColor(mAccentColor, .2f), 0, TileMode.CLAMP));
-    }
-
-    private int getColor(int color, float alphaScale) {
-        return (color & (((int) (0xff * alphaScale) << 24) | 0xffffff));
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        // Draw lines across the top, middle, and bottom.
-        if (mMiddleDividerLoc != 0) {
-            drawDivider(0, canvas, mTopDividerTint);
-        }
-        drawDivider((int) ((canvas.getHeight() - mDividerSize) * mMiddleDividerLoc), canvas,
-                mMiddleDividerTint);
-        drawDivider(canvas.getHeight() - mDividerSize, canvas, -1);
-
-        if (mLocalPaths.size() == 0) {
-            return;
-        }
-        if (mShowProjection) {
-            drawProjection(canvas);
-        }
-        drawFilledPath(canvas);
-        drawLinePath(canvas);
-    }
-
-    private void drawProjection(Canvas canvas) {
-        mPath.reset();
-        int x = mLocalPaths.keyAt(mLocalPaths.size() - 2);
-        int y = mLocalPaths.valueAt(mLocalPaths.size() - 2);
-        mPath.moveTo(x, y);
-        mPath.lineTo(canvas.getWidth(), mProjectUp ? 0 : canvas.getHeight());
-        canvas.drawPath(mPath, mDottedPaint);
-    }
-
-    private void drawLinePath(Canvas canvas) {
-        mPath.reset();
-        mPath.moveTo(mLocalPaths.keyAt(0), mLocalPaths.valueAt(0));
-        for (int i = 1; i < mLocalPaths.size(); i++) {
-            int x = mLocalPaths.keyAt(i);
-            int y = mLocalPaths.valueAt(i);
-            if (y == PATH_DELIM) {
-                if (++i < mLocalPaths.size()) {
-                    mPath.moveTo(mLocalPaths.keyAt(i), mLocalPaths.valueAt(i));
-                }
-            } else {
-                mPath.lineTo(x, y);
-            }
-        }
-        canvas.drawPath(mPath, mLinePaint);
-    }
-
-    private void drawFilledPath(Canvas canvas) {
-        mPath.reset();
-        float lastStartX = mLocalPaths.keyAt(0);
-        mPath.moveTo(mLocalPaths.keyAt(0), mLocalPaths.valueAt(0));
-        for (int i = 1; i < mLocalPaths.size(); i++) {
-            int x = mLocalPaths.keyAt(i);
-            int y = mLocalPaths.valueAt(i);
-            if (y == PATH_DELIM) {
-                mPath.lineTo(mLocalPaths.keyAt(i - 1), getHeight());
-                mPath.lineTo(lastStartX, getHeight());
-                mPath.close();
-                if (++i < mLocalPaths.size()) {
-                    lastStartX = mLocalPaths.keyAt(i);
-                    mPath.moveTo(mLocalPaths.keyAt(i), mLocalPaths.valueAt(i));
-                }
-            } else {
-                mPath.lineTo(x, y);
-            }
-        }
-        canvas.drawPath(mPath, mFillPaint);
-    }
-
-    private void drawDivider(int y, Canvas canvas, int tintColor) {
-        Drawable d = mDivider;
-        if (tintColor != -1) {
-            mTintedDivider.setTint(tintColor);
-            d = mTintedDivider;
-        }
-        d.setBounds(0, y, canvas.getWidth(), y + mDividerSize);
-        d.draw(canvas);
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java b/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java
deleted file mode 100644
index e2c05a1..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java
+++ /dev/null
@@ -1,141 +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.settingslib.graph;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.util.SparseIntArray;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import com.android.settingslib.R;
-
-public class UsageView extends FrameLayout {
-
-    private final UsageGraph mUsageGraph;
-    private final TextView[] mLabels;
-    private final TextView[] mBottomLabels;
-
-    public UsageView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        LayoutInflater.from(context).inflate(R.layout.usage_view, this);
-        mUsageGraph = findViewById(R.id.usage_graph);
-        mLabels = new TextView[] {
-                findViewById(R.id.label_bottom),
-                findViewById(R.id.label_middle),
-                findViewById(R.id.label_top),
-        };
-        mBottomLabels = new TextView[] {
-                findViewById(R.id.label_start),
-                findViewById(R.id.label_end),
-        };
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.UsageView, 0, 0);
-        if (a.hasValue(R.styleable.UsageView_sideLabels)) {
-            setSideLabels(a.getTextArray(R.styleable.UsageView_sideLabels));
-        }
-        if (a.hasValue(R.styleable.UsageView_bottomLabels)) {
-            setBottomLabels(a.getTextArray(R.styleable.UsageView_bottomLabels));
-        }
-        if (a.hasValue(R.styleable.UsageView_textColor)) {
-            int color = a.getColor(R.styleable.UsageView_textColor, 0);
-            for (TextView v : mLabels) {
-                v.setTextColor(color);
-            }
-            for (TextView v : mBottomLabels) {
-                v.setTextColor(color);
-            }
-        }
-        if (a.hasValue(R.styleable.UsageView_android_gravity)) {
-            int gravity = a.getInt(R.styleable.UsageView_android_gravity, 0);
-            if (gravity == Gravity.END) {
-                LinearLayout layout = findViewById(R.id.graph_label_group);
-                LinearLayout labels = findViewById(R.id.label_group);
-                // Swap the children order.
-                layout.removeView(labels);
-                layout.addView(labels);
-                // Set gravity.
-                labels.setGravity(Gravity.END);
-                // Swap the bottom space order.
-                LinearLayout bottomLabels = findViewById(R.id.bottom_label_group);
-                View bottomSpace = bottomLabels.findViewById(R.id.bottom_label_space);
-                bottomLabels.removeView(bottomSpace);
-                bottomLabels.addView(bottomSpace);
-            } else if (gravity != Gravity.START) {
-                throw new IllegalArgumentException("Unsupported gravity " + gravity);
-            }
-        }
-        mUsageGraph.setAccentColor(a.getColor(R.styleable.UsageView_android_colorAccent, 0));
-    }
-
-    public void clearPaths() {
-        mUsageGraph.clearPaths();
-    }
-
-    public void addPath(SparseIntArray points) {
-        mUsageGraph.addPath(points);
-    }
-
-    public void configureGraph(int maxX, int maxY, boolean showProjection, boolean projectUp) {
-        mUsageGraph.setMax(maxX, maxY);
-        mUsageGraph.setShowProjection(showProjection, projectUp);
-    }
-
-    public void setAccentColor(int color) {
-        mUsageGraph.setAccentColor(color);
-    }
-
-    public void setDividerLoc(int dividerLoc) {
-        mUsageGraph.setDividerLoc(dividerLoc);
-    }
-
-    public void setDividerColors(int middleColor, int topColor) {
-        mUsageGraph.setDividerColors(middleColor, topColor);
-    }
-
-    public void setSideLabelWeights(float before, float after) {
-        setWeight(R.id.space1, before);
-        setWeight(R.id.space2, after);
-    }
-
-    private void setWeight(int id, float weight) {
-        View v = findViewById(id);
-        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) v.getLayoutParams();
-        params.weight = weight;
-        v.setLayoutParams(params);
-    }
-
-    public void setSideLabels(CharSequence[] labels) {
-        if (labels.length != mLabels.length) {
-            throw new IllegalArgumentException("Invalid number of labels");
-        }
-        for (int i = 0; i < mLabels.length; i++) {
-            mLabels[i].setText(labels[i]);
-        }
-    }
-
-    public void setBottomLabels(CharSequence[] labels) {
-        if (labels.length != mBottomLabels.length) {
-            throw new IllegalArgumentException("Invalid number of labels");
-        }
-        for (int i = 0; i < mBottomLabels.length; i++) {
-            mBottomLabels[i].setText(labels[i]);
-        }
-    }
-
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionCategory.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionCategory.java
new file mode 100644
index 0000000..19e556a
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionCategory.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.suggestions;
+
+public class SuggestionCategory {
+    public String category;
+    public String pkg;
+    public boolean multiple;
+    public boolean exclusive;
+    public long exclusiveExpireDaysInMillis;
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionList.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionList.java
new file mode 100644
index 0000000..2151ba0
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionList.java
@@ -0,0 +1,95 @@
+/*
+ * 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.settingslib.suggestions;
+
+import android.content.Intent;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+
+import com.android.settingslib.drawer.Tile;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class SuggestionList {
+    // Category -> list of suggestion map
+    private final Map<SuggestionCategory, List<Tile>> mSuggestions;
+
+    // A flatten list of all suggestions.
+    private List<Tile> mSuggestionList;
+
+    public SuggestionList() {
+        mSuggestions = new ArrayMap<>();
+    }
+
+    public void addSuggestions(SuggestionCategory category, List<Tile> suggestions) {
+        mSuggestions.put(category, suggestions);
+    }
+
+    public List<Tile> getSuggestions() {
+        if (mSuggestionList != null) {
+            return mSuggestionList;
+        }
+        mSuggestionList = new ArrayList<>();
+        for (List<Tile> suggestions : mSuggestions.values()) {
+            mSuggestionList.addAll(suggestions);
+        }
+        dedupeSuggestions(mSuggestionList);
+        return mSuggestionList;
+    }
+
+    public boolean isExclusiveSuggestionCategory() {
+        if (mSuggestions.size() != 1) {
+            // If there is no category, or more than 1 category, it's not exclusive by definition.
+            return false;
+        }
+        for (SuggestionCategory category : mSuggestions.keySet()) {
+            if (category.exclusive) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public List<Tile> getSuggestionForCategory(String category) {
+        for (Map.Entry<SuggestionCategory, List<Tile>> entry : mSuggestions.entrySet()) {
+            if (TextUtils.equals(entry.getKey().category, category)) {
+                return entry.getValue();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Filter suggestions list so they are all unique.
+     */
+    private void dedupeSuggestions(List<Tile> suggestions) {
+        final Set<String> intents = new ArraySet<>();
+        for (int i = suggestions.size() - 1; i >= 0; i--) {
+            final Tile suggestion = suggestions.get(i);
+            final String intentUri = suggestion.intent.toUri(Intent.URI_INTENT_SCHEME);
+            if (intents.contains(intentUri)) {
+                suggestions.remove(i);
+            } else {
+                intents.add(intentUri);
+            }
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
new file mode 100644
index 0000000..7f82a1ca
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
@@ -0,0 +1,515 @@
+/*
+ * 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.settingslib.suggestions;
+
+import android.Manifest;
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.annotation.RequiresPermission;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.util.ArrayMap;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Xml;
+import android.view.InflateException;
+
+import com.android.settingslib.drawer.Tile;
+import com.android.settingslib.drawer.TileUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SuggestionParser {
+
+    private static final String TAG = "SuggestionParser";
+
+    // If defined, only returns this suggestion if the feature is supported.
+    public static final String META_DATA_REQUIRE_FEATURE = "com.android.settings.require_feature";
+
+    // If defined, only display this optional step if an account of that type exists.
+    private static final String META_DATA_REQUIRE_ACCOUNT = "com.android.settings.require_account";
+
+    // If defined and not true, do not should optional step.
+    private static final String META_DATA_IS_SUPPORTED = "com.android.settings.is_supported";
+
+    // If defined, only display this optional step if the current user is of that type.
+    private static final String META_DATA_REQUIRE_USER_TYPE =
+            "com.android.settings.require_user_type";
+
+    // If defined, only display this optional step if a connection is available.
+    private static final String META_DATA_IS_CONNECTION_REQUIRED =
+            "com.android.settings.require_connection";
+
+    // The valid values that setup wizard recognizes for differentiating user types.
+    private static final String META_DATA_PRIMARY_USER_TYPE_VALUE = "primary";
+    private static final String META_DATA_ADMIN_USER_TYPE_VALUE = "admin";
+    private static final String META_DATA_GUEST_USER_TYPE_VALUE = "guest";
+    private static final String META_DATA_RESTRICTED_USER_TYPE_VALUE = "restricted";
+
+    /**
+     * Allows suggestions to appear after a certain number of days, and to re-appear if dismissed.
+     * For instance:
+     * 0,10
+     * Will appear immediately, but if the user removes it, it will come back after 10 days.
+     *
+     * Another example:
+     * 10,30
+     * Will only show up after 10 days, and then again after 30.
+     */
+    public static final String META_DATA_DISMISS_CONTROL = "com.android.settings.dismiss";
+
+    // Shared prefs keys for storing dismissed state.
+    // Index into current dismissed state.
+    @VisibleForTesting
+    static final String DISMISS_INDEX = "_dismiss_index";
+    private static final String SETUP_TIME = "_setup_time";
+    private static final String IS_DISMISSED = "_is_dismissed";
+
+    private static final long MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
+
+    // Default dismiss control for smart suggestions.
+    private static final String DEFAULT_SMART_DISMISS_CONTROL = "0,10";
+
+    private final Context mContext;
+    private final List<SuggestionCategory> mSuggestionList;
+    private final ArrayMap<Pair<String, String>, Tile> mAddCache = new ArrayMap<>();
+    private final SharedPreferences mSharedPrefs;
+    private final String mSmartDismissControl;
+
+
+    public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml,
+            String smartDismissControl) {
+        this(
+                context,
+                sharedPrefs,
+                (List<SuggestionCategory>) new SuggestionOrderInflater(context).parse(orderXml),
+                smartDismissControl);
+    }
+
+    public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml) {
+        this(context, sharedPrefs, orderXml, DEFAULT_SMART_DISMISS_CONTROL);
+    }
+
+    @VisibleForTesting
+    public SuggestionParser(
+            Context context,
+            SharedPreferences sharedPrefs,
+            List<SuggestionCategory> suggestionList,
+            String smartDismissControl) {
+        mContext = context;
+        mSuggestionList = suggestionList;
+        mSharedPrefs = sharedPrefs;
+        mSmartDismissControl = smartDismissControl;
+    }
+
+    public SuggestionList getSuggestions(boolean isSmartSuggestionEnabled) {
+        final SuggestionList suggestionList = new SuggestionList();
+        final int N = mSuggestionList.size();
+        for (int i = 0; i < N; i++) {
+            final SuggestionCategory category = mSuggestionList.get(i);
+            if (category.exclusive && !isExclusiveCategoryExpired(category)) {
+                // If suggestions from an exclusive category are present, parsing is stopped
+                // and only suggestions from that category are displayed. Note that subsequent
+                // exclusive categories are also ignored.
+                final List<Tile> exclusiveSuggestions = new ArrayList<>();
+
+                // Read suggestion and force isSmartSuggestion to be false so the rule defined
+                // from each suggestion itself is used.
+                readSuggestions(category, exclusiveSuggestions, false /* isSmartSuggestion */);
+                if (!exclusiveSuggestions.isEmpty()) {
+                    final SuggestionList exclusiveList = new SuggestionList();
+                    exclusiveList.addSuggestions(category, exclusiveSuggestions);
+                    return exclusiveList;
+                }
+            } else {
+                // Either the category is not exclusive, or the exclusiveness expired so we should
+                // treat it as a normal category.
+                final List<Tile> suggestions = new ArrayList<>();
+                readSuggestions(category, suggestions, isSmartSuggestionEnabled);
+                suggestionList.addSuggestions(category, suggestions);
+            }
+        }
+        return suggestionList;
+    }
+
+    public boolean dismissSuggestion(Tile suggestion) {
+        return dismissSuggestion(suggestion, false);
+    }
+
+    /**
+     * Dismisses a suggestion, returns true if the suggestion has no more dismisses left and should
+     * be disabled.
+     */
+    public boolean dismissSuggestion(Tile suggestion, boolean isSmartSuggestionEnabled) {
+        String keyBase = suggestion.intent.getComponent().flattenToShortString();
+        int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
+        String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
+        if (dismissControl == null || parseDismissString(dismissControl).length == index) {
+            return true;
+        }
+        mSharedPrefs.edit()
+                .putBoolean(keyBase + IS_DISMISSED, true)
+                .commit();
+        return false;
+    }
+
+    @VisibleForTesting
+    public void filterSuggestions(
+            List<Tile> suggestions, int countBefore, boolean isSmartSuggestionEnabled) {
+        for (int i = countBefore; i < suggestions.size(); i++) {
+            if (!isAvailable(suggestions.get(i)) ||
+                    !isSupported(suggestions.get(i)) ||
+                    !satisifesRequiredUserType(suggestions.get(i)) ||
+                    !satisfiesRequiredAccount(suggestions.get(i)) ||
+                    !satisfiesConnectivity(suggestions.get(i)) ||
+                    isDismissed(suggestions.get(i), isSmartSuggestionEnabled)) {
+                suggestions.remove(i--);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    void readSuggestions(
+            SuggestionCategory category, List<Tile> suggestions, boolean isSmartSuggestionEnabled) {
+        int countBefore = suggestions.size();
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(category.category);
+        if (category.pkg != null) {
+            intent.setPackage(category.pkg);
+        }
+        TileUtils.getTilesForIntent(mContext, new UserHandle(UserHandle.myUserId()), intent,
+                mAddCache, null, suggestions, true, false, false);
+        filterSuggestions(suggestions, countBefore, isSmartSuggestionEnabled);
+        if (!category.multiple && suggestions.size() > (countBefore + 1)) {
+            // If there are too many, remove them all and only re-add the one with the highest
+            // priority.
+            Tile item = suggestions.remove(suggestions.size() - 1);
+            while (suggestions.size() > countBefore) {
+                Tile last = suggestions.remove(suggestions.size() - 1);
+                if (last.priority > item.priority) {
+                    item = last;
+                }
+            }
+            // If category is marked as done, do not add any item.
+            if (!isCategoryDone(category.category)) {
+                suggestions.add(item);
+            }
+        }
+    }
+
+    private boolean isAvailable(Tile suggestion) {
+        final String featuresRequired = suggestion.metaData.getString(META_DATA_REQUIRE_FEATURE);
+        if (featuresRequired != null) {
+            for (String feature : featuresRequired.split(",")) {
+                if (TextUtils.isEmpty(feature)) {
+                    Log.w(TAG, "Found empty substring when parsing required features: "
+                            + featuresRequired);
+                } else if (!mContext.getPackageManager().hasSystemFeature(feature)) {
+                    Log.i(TAG, suggestion.title + " requires unavailable feature " + feature);
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @RequiresPermission(Manifest.permission.MANAGE_USERS)
+    private boolean satisifesRequiredUserType(Tile suggestion) {
+        final String requiredUser = suggestion.metaData.getString(META_DATA_REQUIRE_USER_TYPE);
+        if (requiredUser != null) {
+            final UserManager userManager = mContext.getSystemService(UserManager.class);
+            UserInfo userInfo = userManager.getUserInfo(UserHandle.myUserId());
+            for (String userType : requiredUser.split("\\|")) {
+                final boolean primaryUserCondtionMet = userInfo.isPrimary()
+                        && META_DATA_PRIMARY_USER_TYPE_VALUE.equals(userType);
+                final boolean adminUserConditionMet = userInfo.isAdmin()
+                        && META_DATA_ADMIN_USER_TYPE_VALUE.equals(userType);
+                final boolean guestUserCondtionMet = userInfo.isGuest()
+                        && META_DATA_GUEST_USER_TYPE_VALUE.equals(userType);
+                final boolean restrictedUserCondtionMet = userInfo.isRestricted()
+                        && META_DATA_RESTRICTED_USER_TYPE_VALUE.equals(userType);
+                if (primaryUserCondtionMet || adminUserConditionMet || guestUserCondtionMet
+                        || restrictedUserCondtionMet) {
+                    return true;
+                }
+            }
+            Log.i(TAG, suggestion.title + " requires user type " + requiredUser);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean satisfiesRequiredAccount(Tile suggestion) {
+        final String requiredAccountType = suggestion.metaData.getString(META_DATA_REQUIRE_ACCOUNT);
+        if (requiredAccountType == null) {
+            return true;
+        }
+        AccountManager accountManager = AccountManager.get(mContext);
+        Account[] accounts = accountManager.getAccountsByType(requiredAccountType);
+        boolean satisfiesRequiredAccount = accounts.length > 0;
+        if (!satisfiesRequiredAccount) {
+            Log.i(TAG, suggestion.title + " requires unavailable account type "
+                    + requiredAccountType);
+        }
+        return satisfiesRequiredAccount;
+    }
+
+    public boolean isSupported(Tile suggestion) {
+        final int isSupportedResource = suggestion.metaData.getInt(META_DATA_IS_SUPPORTED);
+        try {
+            if (suggestion.intent == null) {
+                return false;
+            }
+            final Resources res = mContext.getPackageManager().getResourcesForActivity(
+                    suggestion.intent.getComponent());
+            boolean isSupported =
+                    isSupportedResource != 0 ? res.getBoolean(isSupportedResource) : true;
+            if (!isSupported) {
+                Log.i(TAG, suggestion.title + " requires unsupported resource "
+                        + isSupportedResource);
+            }
+            return isSupported;
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "Cannot find resources for " + suggestion.intent.getComponent());
+            return false;
+        } catch (Resources.NotFoundException e) {
+            Log.w(TAG, "Cannot find resources for " + suggestion.intent.getComponent(), e);
+            return false;
+        }
+    }
+
+    private boolean satisfiesConnectivity(Tile suggestion) {
+        final boolean isConnectionRequired =
+                suggestion.metaData.getBoolean(META_DATA_IS_CONNECTION_REQUIRED);
+        if (!isConnectionRequired) {
+            return true;
+        }
+        ConnectivityManager cm =
+                (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo netInfo = cm.getActiveNetworkInfo();
+        boolean satisfiesConnectivity = netInfo != null && netInfo.isConnectedOrConnecting();
+        if (!satisfiesConnectivity) {
+            Log.i(TAG, suggestion.title + " is missing required connection.");
+        }
+        return satisfiesConnectivity;
+    }
+
+    public boolean isCategoryDone(String category) {
+        String name = Settings.Secure.COMPLETED_CATEGORY_PREFIX + category;
+        return Settings.Secure.getInt(mContext.getContentResolver(), name, 0) != 0;
+    }
+
+    public void markCategoryDone(String category) {
+        String name = Settings.Secure.COMPLETED_CATEGORY_PREFIX + category;
+        Settings.Secure.putInt(mContext.getContentResolver(), name, 1);
+    }
+
+    /**
+     * Whether or not the category's exclusiveness has expired.
+     */
+    private boolean isExclusiveCategoryExpired(SuggestionCategory category) {
+        final String keySetupTime = category.category + SETUP_TIME;
+        final long currentTime = System.currentTimeMillis();
+        if (!mSharedPrefs.contains(keySetupTime)) {
+            mSharedPrefs.edit()
+                    .putLong(keySetupTime, currentTime)
+                    .commit();
+        }
+        if (category.exclusiveExpireDaysInMillis < 0) {
+            // negative means never expires
+            return false;
+        }
+        final long setupTime = mSharedPrefs.getLong(keySetupTime, 0);
+        final long elapsedTime = currentTime - setupTime;
+        Log.d(TAG, "Day " + elapsedTime / DateUtils.DAY_IN_MILLIS + " for " + category.category);
+        return elapsedTime > category.exclusiveExpireDaysInMillis;
+    }
+
+    @VisibleForTesting
+    boolean isDismissed(Tile suggestion, boolean isSmartSuggestionEnabled) {
+        String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
+        if (dismissControl == null) {
+            return false;
+        }
+        String keyBase = suggestion.intent.getComponent().flattenToShortString();
+        if (!mSharedPrefs.contains(keyBase + SETUP_TIME)) {
+            mSharedPrefs.edit()
+                    .putLong(keyBase + SETUP_TIME, System.currentTimeMillis())
+                    .commit();
+        }
+        // Default to dismissed, so that we can have suggestions that only first appear after
+        // some number of days.
+        if (!mSharedPrefs.getBoolean(keyBase + IS_DISMISSED, true)) {
+            return false;
+        }
+        int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
+        int[] dismissRules = parseDismissString(dismissControl);
+        if (dismissRules.length <= index) {
+            return true;
+        }
+        int currentDismiss = dismissRules[index];
+        long time = getEndTime(mSharedPrefs.getLong(keyBase + SETUP_TIME, 0), currentDismiss);
+        if (System.currentTimeMillis() >= time) {
+            // Dismiss timeout has passed, undismiss it.
+            mSharedPrefs.edit()
+                    .putBoolean(keyBase + IS_DISMISSED, false)
+                    .putInt(keyBase + DISMISS_INDEX, index + 1)
+                    .commit();
+            return false;
+        }
+        return true;
+    }
+
+    private long getEndTime(long startTime, int daysDelay) {
+        long days = daysDelay * MILLIS_IN_DAY;
+        return startTime + days;
+    }
+
+    private int[] parseDismissString(String dismissControl) {
+        String[] dismissStrs = dismissControl.split(",");
+        int[] dismisses = new int[dismissStrs.length];
+        for (int i = 0; i < dismissStrs.length; i++) {
+            dismisses[i] = Integer.parseInt(dismissStrs[i]);
+        }
+        return dismisses;
+    }
+
+    private String getDismissControl(Tile suggestion, boolean isSmartSuggestionEnabled) {
+        if (isSmartSuggestionEnabled) {
+            return mSmartDismissControl;
+        } else {
+            return suggestion.metaData.getString(META_DATA_DISMISS_CONTROL);
+        }
+    }
+
+    private static class SuggestionOrderInflater {
+        private static final String TAG_LIST = "optional-steps";
+        private static final String TAG_ITEM = "step";
+
+        private static final String ATTR_CATEGORY = "category";
+        private static final String ATTR_PACKAGE = "package";
+        private static final String ATTR_MULTIPLE = "multiple";
+        private static final String ATTR_EXCLUSIVE = "exclusive";
+        private static final String ATTR_EXCLUSIVE_EXPIRE_DAYS = "exclusiveExpireDays";
+
+        private final Context mContext;
+
+        public SuggestionOrderInflater(Context context) {
+            mContext = context;
+        }
+
+        public Object parse(int resource) {
+            XmlPullParser parser = mContext.getResources().getXml(resource);
+            final AttributeSet attrs = Xml.asAttributeSet(parser);
+            try {
+                // Look for the root node.
+                int type;
+                do {
+                    type = parser.next();
+                } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT);
+
+                if (type != XmlPullParser.START_TAG) {
+                    throw new InflateException(parser.getPositionDescription()
+                            + ": No start tag found!");
+                }
+
+                // Temp is the root that was found in the xml
+                Object xmlRoot = onCreateItem(parser.getName(), attrs);
+
+                // Inflate all children under temp
+                rParse(parser, xmlRoot, attrs);
+                return xmlRoot;
+            } catch (XmlPullParserException | IOException e) {
+                Log.w(TAG, "Problem parser resource " + resource, e);
+                return null;
+            }
+        }
+
+        /**
+         * Recursive method used to descend down the xml hierarchy and instantiate
+         * items, instantiate their children.
+         */
+        private void rParse(XmlPullParser parser, Object parent, final AttributeSet attrs)
+                throws XmlPullParserException, IOException {
+            final int depth = parser.getDepth();
+
+            int type;
+            while (((type = parser.next()) != XmlPullParser.END_TAG ||
+                    parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
+                if (type != XmlPullParser.START_TAG) {
+                    continue;
+                }
+
+                final String name = parser.getName();
+
+                Object item = onCreateItem(name, attrs);
+                onAddChildItem(parent, item);
+                rParse(parser, item, attrs);
+            }
+        }
+
+        protected void onAddChildItem(Object parent, Object child) {
+            if (parent instanceof List<?> && child instanceof SuggestionCategory) {
+                ((List<SuggestionCategory>) parent).add((SuggestionCategory) child);
+            } else {
+                throw new IllegalArgumentException("Parent was not a list");
+            }
+        }
+
+        protected Object onCreateItem(String name, AttributeSet attrs) {
+            if (name.equals(TAG_LIST)) {
+                return new ArrayList<SuggestionCategory>();
+            } else if (name.equals(TAG_ITEM)) {
+                SuggestionCategory category = new SuggestionCategory();
+                category.category = attrs.getAttributeValue(null, ATTR_CATEGORY);
+                category.pkg = attrs.getAttributeValue(null, ATTR_PACKAGE);
+                String multiple = attrs.getAttributeValue(null, ATTR_MULTIPLE);
+                category.multiple = !TextUtils.isEmpty(multiple) && Boolean.parseBoolean(multiple);
+                String exclusive = attrs.getAttributeValue(null, ATTR_EXCLUSIVE);
+                category.exclusive =
+                        !TextUtils.isEmpty(exclusive) && Boolean.parseBoolean(exclusive);
+                String expireDaysAttr = attrs.getAttributeValue(null,
+                        ATTR_EXCLUSIVE_EXPIRE_DAYS);
+                long expireDays = !TextUtils.isEmpty(expireDaysAttr)
+                        ? Integer.parseInt(expireDaysAttr)
+                        : -1;
+                category.exclusiveExpireDaysInMillis = DateUtils.DAY_IN_MILLIS * expireDays;
+                return category;
+            } else {
+                throw new IllegalArgumentException("Unknown item " + name);
+            }
+        }
+    }
+}
+
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/ThreadUtils.java b/packages/SettingsLib/src/com/android/settingslib/utils/ThreadUtils.java
new file mode 100644
index 0000000..2024991
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/ThreadUtils.java
@@ -0,0 +1,42 @@
+/*
+ * 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.settingslib.utils;
+
+import android.os.Looper;
+
+public class ThreadUtils {
+    private static volatile Thread sMainThread;
+
+    /**
+     * Returns true if the current thread is the UI thread.
+     */
+    public static boolean isMainThread() {
+        if (sMainThread == null) {
+            sMainThread = Looper.getMainLooper().getThread();
+        }
+        return Thread.currentThread() == sMainThread;
+    }
+
+    /**
+     * Checks that the current thread is the UI thread. Otherwise throws an exception.
+     */
+    public static void ensureMainThread() {
+        if (!isMainThread()) {
+            throw new RuntimeException("Must be called on the UI thread");
+        }
+    }
+
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java b/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java
new file mode 100644
index 0000000..0c3a5e9
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java
@@ -0,0 +1,63 @@
+/*
+ * 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.settingslib.widget;
+
+import android.content.Context;
+import android.support.v4.content.res.TypedArrayUtils;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.text.method.LinkMovementMethod;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+import com.android.settingslib.R;
+
+/**
+ * A custom preference acting as "footer" of a page. It has a field for icon and text. It is added
+ * to screen as the last preference.
+ */
+public class FooterPreference extends Preference {
+
+    static final int ORDER_FOOTER = Integer.MAX_VALUE - 1;
+    static final String KEY_FOOTER = "footer_preference";
+
+    public FooterPreference(Context context, AttributeSet attrs) {
+        super(context, attrs, TypedArrayUtils.getAttr(
+                context, R.attr.footerPreferenceStyle, android.R.attr.preferenceStyle));
+        init();
+    }
+
+    public FooterPreference(Context context) {
+        this(context, null);
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        TextView title = holder.itemView.findViewById(android.R.id.title);
+        title.setMovementMethod(new LinkMovementMethod());
+        title.setClickable(false);
+        title.setLongClickable(false);
+    }
+
+    private void init() {
+        setIcon(R.drawable.ic_info_outline_24dp);
+        setKey(KEY_FOOTER);
+        setOrder(ORDER_FOOTER);
+        setSelectable(false);
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreferenceMixin.java b/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreferenceMixin.java
new file mode 100644
index 0000000..2edcd9e
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreferenceMixin.java
@@ -0,0 +1,71 @@
+/*
+ * 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.settingslib.widget;
+
+import android.content.Context;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.SetPreferenceScreen;
+
+public class FooterPreferenceMixin implements LifecycleObserver, SetPreferenceScreen {
+
+    private final PreferenceFragment mFragment;
+    private FooterPreference mFooterPreference;
+
+    public FooterPreferenceMixin(PreferenceFragment fragment, Lifecycle lifecycle) {
+        mFragment = fragment;
+        lifecycle.addObserver(this);
+    }
+
+    @Override
+    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+        if (mFooterPreference != null) {
+            preferenceScreen.addPreference(mFooterPreference);
+        }
+    }
+
+    /**
+     * Creates a new {@link FooterPreference}.
+     */
+    public FooterPreference createFooterPreference() {
+        final PreferenceScreen screen = mFragment.getPreferenceScreen();
+        if (mFooterPreference != null && screen != null) {
+            screen.removePreference(mFooterPreference);
+        }
+        mFooterPreference = new FooterPreference(getPrefContext());
+
+        if (screen != null) {
+            screen.addPreference(mFooterPreference);
+        }
+        return mFooterPreference;
+    }
+
+    /**
+     * Returns an UI context with theme properly set for new Preference objects.
+     */
+    private Context getPrefContext() {
+        return mFragment.getPreferenceManager().getContext();
+    }
+
+    public boolean hasFooter() {
+        return mFooterPreference != null;
+    }
+}
+
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 0ea9d96..306f9ac 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -16,13 +16,14 @@
 
 package com.android.settingslib.wifi;
 
+import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.app.AppGlobals;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
-import android.net.NetworkBadging;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
@@ -53,6 +54,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.R;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.concurrent.ConcurrentHashMap;
@@ -82,6 +85,30 @@
      */
     public static final int HIGHER_FREQ_5GHZ = 5900;
 
+    @IntDef({Speed.NONE, Speed.SLOW, Speed.MODERATE, Speed.FAST, Speed.VERY_FAST})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Speed {
+        /**
+         * Constant value representing an unlabeled / unscored network.
+         */
+        int NONE = 0;
+        /**
+         * Constant value representing a slow speed network connection.
+         */
+        int SLOW = 5;
+        /**
+         * Constant value representing a medium speed network connection.
+         */
+        int MODERATE = 10;
+        /**
+         * Constant value representing a fast speed network connection.
+         */
+        int FAST = 20;
+        /**
+         * Constant value representing a very fast speed network connection.
+         */
+        int VERY_FAST = 30;
+    }
 
     /**
      * Experimental: we should be able to show the user the list of BSSIDs and bands
@@ -91,6 +118,7 @@
      */
     private final ConcurrentHashMap<String, ScanResult> mScanResultCache =
             new ConcurrentHashMap<String, ScanResult>(32);
+    /** Maximum age of scan results to hold onto while actively scanning. **/
     private static final long MAX_SCAN_RESULT_AGE_MS = 15000;
 
     static final String KEY_NETWORKINFO = "key_networkinfo";
@@ -148,7 +176,7 @@
     private Object mTag;
 
     private int mRankingScore = Integer.MIN_VALUE;
-    private int mBadge = NetworkBadging.BADGING_NONE;
+    private int mSpeed = Speed.NONE;
     private boolean mIsScoredNetworkMetered = false;
 
     // used to co-relate internal vs returned accesspoint.
@@ -195,6 +223,8 @@
             mProviderFriendlyName = savedState.getString(KEY_PROVIDER_FRIENDLY_NAME);
         }
         update(mConfig, mInfo, mNetworkInfo);
+
+        // Do not evict old scan results on initial creation
         updateRssi();
         updateSeen();
         mId = sLastId.incrementAndGet();
@@ -248,7 +278,7 @@
         this.mScanResultCache.clear();
         this.mScanResultCache.putAll(that.mScanResultCache);
         this.mId = that.mId;
-        this.mBadge = that.mBadge;
+        this.mSpeed = that.mSpeed;
         this.mIsScoredNetworkMetered = that.mIsScoredNetworkMetered;
         this.mRankingScore = that.mRankingScore;
     }
@@ -293,8 +323,15 @@
         if (difference != 0) {
             return difference;
         }
+
         // Sort by ssid.
-        return getSsidStr().compareToIgnoreCase(other.getSsidStr());
+        difference = getSsidStr().compareToIgnoreCase(other.getSsidStr());
+        if (difference != 0) {
+            return difference;
+        }
+
+        // Do a case sensitive comparison to distinguish SSIDs that differ in case only
+        return getSsidStr().compareTo(other.getSsidStr());
     }
 
     @Override
@@ -335,13 +372,12 @@
         if (security != SECURITY_NONE) {
             builder.append(',').append(securityToString(security, pskType));
         }
-        builder.append(",mRssi=").append(mRssi);
         builder.append(",level=").append(getLevel());
         if (mRankingScore != Integer.MIN_VALUE) {
             builder.append(",rankingScore=").append(mRankingScore);
         }
-        if (mBadge != NetworkBadging.BADGING_NONE) {
-            builder.append(",badge=").append(mBadge);
+        if (mSpeed != Speed.NONE) {
+            builder.append(",speed=").append(mSpeed);
         }
         builder.append(",metered=").append(isMetered());
 
@@ -349,7 +385,7 @@
     }
 
     /**
-     * Updates the AccessPoint rankingScore, metering, and badge, returning true if the data has
+     * Updates the AccessPoint rankingScore, metering, and speed, returning true if the data has
      * changed.
      *
      * @param scoreCache The score cache to use to retrieve scores.
@@ -364,14 +400,14 @@
     }
 
     /**
-     * Updates the AccessPoint rankingScore and badge, returning true if the data has changed.
+     * Updates the AccessPoint rankingScore and speed, returning true if the data has changed.
      *
      * @param scoreCache The score cache to use to retrieve scores.
      */
     private boolean updateScores(WifiNetworkScoreCache scoreCache) {
-        int oldBadge = mBadge;
+        int oldSpeed = mSpeed;
         int oldRankingScore = mRankingScore;
-        mBadge = NetworkBadging.BADGING_NONE;
+        mSpeed = Speed.NONE;
         mRankingScore = Integer.MIN_VALUE;
 
         for (ScanResult result : mScanResultCache.values()) {
@@ -383,10 +419,11 @@
             if (score.hasRankingScore()) {
                 mRankingScore = Math.max(mRankingScore, score.calculateRankingScore(result.level));
             }
-            mBadge = Math.max(mBadge, score.calculateBadge(result.level));
+            // TODO(sghuman): Rename calculateBadge API
+            mSpeed = Math.max(mSpeed, score.calculateBadge(result.level));
         }
 
-        return (oldBadge != mBadge || oldRankingScore != mRankingScore);
+        return (oldSpeed != mSpeed || oldRankingScore != mRankingScore);
     }
 
     /**
@@ -470,12 +507,8 @@
      * results, returning the best RSSI for all matching AccessPoints averaged with the previous
      * value. If the access point is not connected and there are no scan results, the rssi will be
      * set to {@link #UNREACHABLE_RSSI}.
-     *
-     * <p>Old scan results will be evicted from the cache when this method is invoked.
      */
     private void updateRssi() {
-        evictOldScanResults();
-
         if (this.isActive()) {
             return;
         }
@@ -494,14 +527,8 @@
         }
     }
 
-    /**
-     * Updates {@link #mSeen} based on the scan result cache.
-     *
-     * <p>Old scan results will be evicted from the cache when this method is invoked.
-     */
+    /** Updates {@link #mSeen} based on the scan result cache. */
     private void updateSeen() {
-        evictOldScanResults();
-
         // TODO(sghuman): Set to now if connected
 
         long seen = 0;
@@ -643,6 +670,13 @@
         // Update to new summary
         StringBuilder summary = new StringBuilder();
 
+        // TODO(b/62354743): Standardize and international delimiter usage
+        final String concatenator = " / ";
+
+        if (mSpeed != Speed.NONE) {
+            summary.append(getSpeedLabel() + concatenator);
+        }
+
         if (isActive() && config != null && config.isPasspoint()) {
             // This is the active connection on passpoint
             summary.append(getSummary(mContext, getDetailedState(),
@@ -667,6 +701,9 @@
                 case WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE:
                     summary.append(mContext.getString(R.string.wifi_disabled_password_failure));
                     break;
+                case WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD:
+                    summary.append(mContext.getString(R.string.wifi_check_password_try_again));
+                    break;
                 case WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE:
                 case WifiConfiguration.NetworkSelectionStatus.DISABLED_DNS_FAILURE:
                     summary.append(mContext.getString(R.string.wifi_disabled_network_failure));
@@ -722,6 +759,14 @@
                 }
             }
         }
+
+        // Strip trailing delimiter if applicable
+        int concatLength = concatenator.length();
+        if (summary.length() >= concatLength && summary.substring(
+                summary.length() - concatLength, summary.length()).equals(concatenator)) {
+            summary.delete(summary.length() - concatLength, summary.length());
+        }
+
         return summary.toString();
     }
 
@@ -750,10 +795,10 @@
             visibility.append(" ");
             visibility.append(" score=").append(mInfo.score);
             if (mRankingScore != Integer.MIN_VALUE) {
-              visibility.append(" rankingScore=").append(getRankingScore());
+                visibility.append(" rankingScore=").append(getRankingScore());
             }
-            if (mBadge != NetworkBadging.BADGING_NONE) {
-              visibility.append(" badge=").append(getBadge());
+            if (mSpeed != Speed.NONE) {
+                visibility.append(" speed=").append(getSpeedLabel());
             }
             visibility.append(String.format(" tx=%.1f,", mInfo.txSuccessRate));
             visibility.append(String.format("%.1f,", mInfo.txRetriesRate));
@@ -973,12 +1018,22 @@
         mAccessPointListener = listener;
     }
 
-    boolean update(ScanResult result) {
+    /**
+     * Update the AP with the given scan result.
+     *
+     * @param result the ScanResult to add to the AccessPoint scan cache
+     * @param evictOldScanResults whether stale scan results should be removed
+     *         from the cache during this update process
+     * @return true if the scan result update caused a change in state which would impact ranking
+     *     or AccessPoint rendering (e.g. wifi level, security)
+     */
+    boolean update(ScanResult result, boolean evictOldScanResults) {
         if (matches(result)) {
             int oldLevel = getLevel();
 
             /* Add or update the scan result for the BSSID */
             mScanResultCache.put(result.BSSID, result);
+            if (evictOldScanResults) evictOldScanResults();
             updateSeen();
             updateRssi();
             int newLevel = getLevel();
@@ -1001,12 +1056,19 @@
     }
 
     /** Attempt to update the AccessPoint and return true if an update occurred. */
-    public boolean update(WifiConfiguration config, WifiInfo info, NetworkInfo networkInfo) {
+    public boolean update(
+            @Nullable WifiConfiguration config, WifiInfo info, NetworkInfo networkInfo) {
         boolean updated = false;
         final int oldLevel = getLevel();
         if (info != null && isInfoForThisAccessPoint(config, info)) {
             updated = (mInfo == null);
-            if (mRssi != info.getRssi()) {
+            if (mConfig != config) {
+                // We do not set updated = true as we do not want to increase the amount of sorting
+                // and copying performed in WifiTracker at this time. If issues involving refresh
+                // are still seen, we will investigate further.
+                update(config); // Notifies the AccessPointListener of the change
+            }
+            if (mRssi != info.getRssi() && info.getRssi() != WifiInfo.INVALID_RSSI) {
                 mRssi = info.getRssi();
                 updated = true;
             } else if (mNetworkInfo != null && networkInfo != null
@@ -1030,9 +1092,9 @@
         return updated;
     }
 
-    void update(WifiConfiguration config) {
+    void update(@Nullable WifiConfiguration config) {
         mConfig = config;
-        networkId = config.networkId;
+        networkId = config != null ? config.networkId : WifiConfiguration.INVALID_NETWORK_ID;
         if (mAccessPointListener != null) {
             mAccessPointListener.onAccessPointChanged(this);
         }
@@ -1052,8 +1114,23 @@
         return mRankingScore;
     }
 
-    int getBadge() {
-        return mBadge;
+    int getSpeed() { return mSpeed;}
+
+    @Nullable
+    String getSpeedLabel() {
+        switch (mSpeed) {
+            case Speed.VERY_FAST:
+                return mContext.getString(R.string.speed_label_very_fast);
+            case Speed.FAST:
+                return mContext.getString(R.string.speed_label_fast);
+            case Speed.MODERATE:
+                return mContext.getString(R.string.speed_label_okay);
+            case Speed.SLOW:
+                return mContext.getString(R.string.speed_label_slow);
+            case Speed.NONE:
+            default:
+                return null;
+        }
     }
 
     /** Return true if the current RSSI is reachable, and false otherwise. */
@@ -1096,8 +1173,9 @@
 
             if (nc != null) {
                 if (nc.hasCapability(nc.NET_CAPABILITY_CAPTIVE_PORTAL)) {
-                    return context.getString(
-                        com.android.internal.R.string.network_available_sign_in);
+                    int id = context.getResources()
+                            .getIdentifier("network_available_sign_in", "string", "android");
+                    return context.getString(id);
                 } else if (!nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
                     return context.getString(R.string.wifi_connected_no_internet);
                 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
index 7f95379..92995a8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
@@ -60,15 +60,29 @@
     private int mLevel;
     private CharSequence mContentDescription;
     private int mDefaultIconResId;
-    private int mWifiBadge = NetworkBadging.BADGING_NONE;
+    private int mWifiSpeed = NetworkBadging.BADGING_NONE;
 
     static final int[] WIFI_CONNECTION_STRENGTH = {
+            R.string.accessibility_no_wifi,
             R.string.accessibility_wifi_one_bar,
             R.string.accessibility_wifi_two_bars,
             R.string.accessibility_wifi_three_bars,
             R.string.accessibility_wifi_signal_full
     };
 
+    public static String generatePreferenceKey(AccessPoint accessPoint) {
+        StringBuilder builder = new StringBuilder();
+
+        if (TextUtils.isEmpty(accessPoint.getBssid())) {
+            builder.append(accessPoint.getSsidStr());
+        } else {
+            builder.append(accessPoint.getBssid());
+        }
+
+        builder.append(',').append(accessPoint.getSecurity());
+        return builder.toString();
+    }
+
     // Used for dummy pref.
     public AccessPointPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -160,8 +174,11 @@
             safeSetDefaultIcon();
             return;
         }
-        TronUtils.logWifiSettingsBadge(context, mWifiBadge);
-        Drawable drawable = NetworkBadging.getWifiIcon(level, mWifiBadge, getContext().getTheme());
+        TronUtils.logWifiSettingsSpeed(context, mWifiSpeed);
+
+        // TODO(b/62355275): Revert this to N code after deleting NetworkBadging API
+        Drawable drawable = NetworkBadging.getWifiIcon(
+                level, NetworkBadging.BADGING_NONE, getContext().getTheme());
         if (!mForSavedNetworks && drawable != null) {
             drawable.setTint(Utils.getColorAttr(context, android.R.attr.colorControlNormal));
             setIcon(drawable);
@@ -219,10 +236,10 @@
 
         final Context context = getContext();
         int level = mAccessPoint.getLevel();
-        int wifiBadge = mAccessPoint.getBadge();
-        if (level != mLevel || wifiBadge != mWifiBadge) {
+        int wifiSpeed = mAccessPoint.getSpeed();
+        if (level != mLevel || wifiSpeed != mWifiSpeed) {
             mLevel = level;
-            mWifiBadge = wifiBadge;
+            mWifiSpeed = wifiSpeed;
             updateIcon(mLevel, context);
             notifyChanged();
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java b/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
new file mode 100644
index 0000000..3413f24
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
@@ -0,0 +1,205 @@
+/*
+ * 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.settingslib.wifi;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.os.Bundle;
+import android.support.annotation.Keep;
+
+/**
+* Build and return a valid AccessPoint.
+*
+* Only intended for testing the AccessPoint class or creating Access points to be used in testing
+* applications. AccessPoints were designed to only be populated by the mechanisms of scan results
+* and wifi configurations.
+*/
+@Keep
+public class TestAccessPointBuilder {
+    // match the private values in WifiManager
+    private static final int MIN_RSSI = -100;
+    private static final int MAX_RSSI = -55;
+
+    // set some sensible defaults
+    private String mBssid = null;
+    private int mRssi = AccessPoint.UNREACHABLE_RSSI;
+    private int mNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
+    private String ssid = "TestSsid";
+    private NetworkInfo mNetworkInfo = null;
+    private String mFqdn = null;
+    private String mProviderFriendlyName = null;
+    private int mSecurity = AccessPoint.SECURITY_NONE;
+    private WifiConfiguration mWifiConfig;
+    private WifiInfo mWifiInfo;
+
+    Context mContext;
+
+    @Keep
+    public TestAccessPointBuilder(Context context) {
+        mContext = context;
+    }
+
+    @Keep
+    public AccessPoint build() {
+        Bundle bundle = new Bundle();
+
+        WifiConfiguration wifiConfig = new WifiConfiguration();
+        wifiConfig.networkId = mNetworkId;
+        wifiConfig.BSSID = mBssid;
+
+        bundle.putString(AccessPoint.KEY_SSID, ssid);
+        bundle.putParcelable(AccessPoint.KEY_CONFIG, wifiConfig);
+        bundle.putParcelable(AccessPoint.KEY_NETWORKINFO, mNetworkInfo);
+        bundle.putParcelable(AccessPoint.KEY_WIFIINFO, mWifiInfo);
+        if (mFqdn != null) {
+            bundle.putString(AccessPoint.KEY_FQDN, mFqdn);
+        }
+        if (mProviderFriendlyName != null) {
+            bundle.putString(AccessPoint.KEY_PROVIDER_FRIENDLY_NAME, mProviderFriendlyName);
+        }
+        bundle.putInt(AccessPoint.KEY_SECURITY, mSecurity);
+
+        AccessPoint ap = new AccessPoint(mContext, bundle);
+        ap.setRssi(mRssi);
+        return ap;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setActive(boolean active) {
+        if (active) {
+            mNetworkInfo = new NetworkInfo(
+                ConnectivityManager.TYPE_DUMMY,
+                ConnectivityManager.TYPE_DUMMY,
+                "TestNetwork",
+                "TestNetwork");
+        } else {
+            mNetworkInfo = null;
+        }
+        return this;
+    }
+
+    /**
+     * Set the rssi based upon the desired signal level.
+     *
+     * <p>Side effect: if this AccessPoint was previously unreachable,
+     * setting the level will also make it reachable.
+     */
+    @Keep
+    public TestAccessPointBuilder setLevel(int level) {
+        // Reversal of WifiManager.calculateSignalLevels
+        if (level == 0) {
+            mRssi = MIN_RSSI;
+        } else if (level >= AccessPoint.SIGNAL_LEVELS) {
+            mRssi = MAX_RSSI;
+        } else {
+            float inputRange = MAX_RSSI - MIN_RSSI;
+            float outputRange = AccessPoint.SIGNAL_LEVELS - 1;
+            mRssi = (int) (level * inputRange / outputRange + MIN_RSSI);
+        }
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setNetworkInfo(NetworkInfo info) {
+        mNetworkInfo = info;
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setRssi(int rssi) {
+        mRssi = rssi;
+        return this;
+    }
+
+    /**
+    * Set whether the AccessPoint is reachable.
+    * Side effect: if the signal level was not previously set,
+    * making an AccessPoint reachable will set the signal to the minimum level.
+    */
+    @Keep
+    public TestAccessPointBuilder setReachable(boolean reachable) {
+        if (reachable) {
+            // only override the mRssi if it hasn't been set yet
+            if (mRssi == AccessPoint.UNREACHABLE_RSSI) {
+                mRssi = MIN_RSSI;
+            }
+        } else {
+            mRssi = AccessPoint.UNREACHABLE_RSSI;
+        }
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setSaved(boolean saved){
+        if (saved) {
+             mNetworkId = 1;
+        } else {
+             mNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
+        }
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setSecurity(int security) {
+        mSecurity = security;
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setSsid(String newSsid) {
+        ssid = newSsid;
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setFqdn(String fqdn) {
+        mFqdn = fqdn;
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setProviderFriendlyName(String friendlyName) {
+        mProviderFriendlyName = friendlyName;
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setWifiInfo(WifiInfo info) {
+        mWifiInfo = info;
+        return this;
+    }
+
+    /**
+     * Set the networkId in the WifiConfig.
+     *
+     * <p>Setting this to a value other than {@link WifiConfiguration#INVALID_NETWORK_ID} makes this
+     * AccessPoint a saved network.
+     */
+    @Keep
+    public TestAccessPointBuilder setNetworkId(int networkId) {
+        mNetworkId = networkId;
+        return this;
+    }
+
+    public TestAccessPointBuilder setBssid(String bssid) {
+        mBssid = bssid;
+        return this;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index ec94841..0d67ad0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -12,17 +12,13 @@
 
 import android.content.Intent;
 import android.net.NetworkInfo;
-import android.net.NetworkKey;
-import android.net.WifiKey;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
-import android.util.Log;
 
 import java.util.List;
 
 public class WifiStatusTracker {
-    private static final String TAG = "WifiStatusTracker";
 
     private final WifiManager mWifiManager;
     public boolean enabled;
@@ -32,7 +28,6 @@
     public String ssid;
     public int rssi;
     public int level;
-    public NetworkKey networkKey;
 
     public WifiStatusTracker(WifiManager wifiManager) {
         mWifiManager = wifiManager;
@@ -54,32 +49,19 @@
             connecting = networkInfo != null && !networkInfo.isConnected()
                     && networkInfo.isConnectedOrConnecting();
             connected = networkInfo != null && networkInfo.isConnected();
-            WifiInfo info = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO) != null
-                    ? (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO)
-                    : mWifiManager.getConnectionInfo();
-
             // If Connected grab the signal strength and ssid.
-            if (connected && info != null) {
-                ssid = getSsid(info);
-                String bssid = info.getBSSID();
-                if ((ssid != null) && (bssid != null)) {
-                    // Reuse existing network key object if possible.
-                    if ((networkKey == null)
-                            || !networkKey.wifiKey.ssid.equals(ssid)
-                            || !networkKey.wifiKey.bssid.equals(bssid)) {
-                        try {
-                            networkKey = new NetworkKey(
-                                    new WifiKey(ssid, bssid));
-                        } catch (IllegalArgumentException e) {
-                            Log.e(TAG, "Cannot create NetworkKey", e);
-                        }
-                    }
+            if (connected) {
+                // try getting it out of the intent first
+                WifiInfo info = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO) != null
+                        ? (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO)
+                        : mWifiManager.getConnectionInfo();
+                if (info != null) {
+                    ssid = getSsid(info);
                 } else {
-                    networkKey = null;
+                    ssid = null;
                 }
-            } else {
+            } else if (!connected) {
                 ssid = null;
-                networkKey = null;
             }
         } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
             // Default to -200 as its below WifiManager.MIN_RSSI.
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index fcc9090..f8e2f8b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -36,7 +36,6 @@
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiNetworkScoreCache;
 import android.net.wifi.WifiNetworkScoreCache.CacheListener;
-import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -91,7 +90,7 @@
     private final boolean mIncludeScans;
     private final boolean mIncludePasspoints;
     @VisibleForTesting final MainHandler mMainHandler;
-    private final WorkHandler mWorkHandler;
+    @VisibleForTesting final WorkHandler mWorkHandler;
 
     private WifiTrackerNetworkCallback mNetworkCallback;
 
@@ -136,13 +135,17 @@
 
     private final NetworkScoreManager mNetworkScoreManager;
     private final WifiNetworkScoreCache mScoreCache;
+    private boolean mNetworkScoringUiEnabled;
+    private final ContentObserver mObserver;
 
     @GuardedBy("mLock")
     private final Set<NetworkKey> mRequestedScores = new ArraySet<>();
 
     @VisibleForTesting
     Scanner mScanner;
-    private boolean mStaleScanResults = false;
+
+    @GuardedBy("mLock")
+    private boolean mStaleScanResults = true;
 
     public WifiTracker(Context context, WifiListener wifiListener,
             boolean includeSaved, boolean includeScans) {
@@ -224,18 +227,30 @@
                 updateNetworkScores();
             }
         });
+
+        mObserver = new ContentObserver(mWorkHandler) {
+            @Override
+            public void onChange(boolean selfChange) {
+                mNetworkScoringUiEnabled =
+                        Settings.Global.getInt(
+                                mContext.getContentResolver(),
+                                Settings.Global.NETWORK_SCORING_UI_ENABLED, 0) == 1;
+            }
+        };
     }
 
-    /**
-     * Synchronously update the list of access points with the latest information.
-     */
+    /** Synchronously update the list of access points with the latest information. */
     @MainThread
     public void forceUpdate() {
         synchronized (mLock) {
             mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
             mLastInfo = mWifiManager.getConnectionInfo();
             mLastNetworkInfo = mConnectivityManager.getNetworkInfo(mWifiManager.getCurrentNetwork());
-            updateAccessPointsLocked();
+
+            final List<ScanResult> newScanResults = mWifiManager.getScanResults();
+            List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+            mInternalAccessPoints.clear();
+            updateAccessPointsLocked(newScanResults, configs);
 
             if (DBG) {
                 Log.d(TAG, "force update - internal access point list:\n" + mInternalAccessPoints);
@@ -297,6 +312,12 @@
         synchronized (mLock) {
             registerScoreCache();
 
+            mContext.getContentResolver().registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.NETWORK_SCORING_UI_ENABLED),
+                    false /* notifyForDescendants */,
+                    mObserver);
+            mObserver.onChange(false /* selfChange */); // Set mScoringUiEnabled
+
             resumeScanning();
             if (!mRegistered) {
                 mContext.registerReceiver(mReceiver, mFilter);
@@ -345,20 +366,24 @@
                 mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
                 mRegistered = false;
             }
-            unregisterAndClearScoreCache();
+            unregisterScoreCache();
             pauseScanning();
+            mContext.getContentResolver().unregisterContentObserver(mObserver);
 
             mWorkHandler.removePendingMessages();
             mMainHandler.removePendingMessages();
+            mStaleScanResults = true;
         }
-        mStaleScanResults = true;
     }
 
-    private void unregisterAndClearScoreCache() {
+    private void unregisterScoreCache() {
         mNetworkScoreManager.unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI, mScoreCache);
-        mScoreCache.clearScores();
 
-        // Synchronize on mLock to avoid concurrent modification during updateAccessPointsLocked
+        // We do not want to clear the existing scores in the cache, as this method is called during
+        // stop tracking on activity pause. Hence, on resumption we want the ability to show the
+        // last known, potentially stale, scores. However, by clearing requested scores, the scores
+        // will be requested again upon resumption of tracking, and if any changes have occurred
+        // the listeners (UI) will be updated accordingly.
         synchronized (mLock) {
             mRequestedScores.clear();
         }
@@ -408,9 +433,8 @@
         mScanId = 0;
     }
 
-    private Collection<ScanResult> fetchScanResults() {
+    private Collection<ScanResult> updateScanResultCache(final List<ScanResult> newResults) {
         mScanId++;
-        final List<ScanResult> newResults = mWifiManager.getScanResults();
         for (ScanResult newResult : newResults) {
             if (newResult.SSID == null || newResult.SSID.isEmpty()) {
                 continue;
@@ -438,8 +462,8 @@
         return mScanResultCache.values();
     }
 
-    private WifiConfiguration getWifiConfigurationForNetworkId(int networkId) {
-        final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+    private WifiConfiguration getWifiConfigurationForNetworkId(
+            int networkId, final List<WifiConfiguration> configs) {
         if (configs != null) {
             for (WifiConfiguration config : configs) {
                 if (mLastInfo != null && networkId == config.networkId &&
@@ -451,20 +475,37 @@
         return null;
     }
 
-    /** Safely modify {@link #mInternalAccessPoints} by acquiring {@link #mLock} first. */
-    private void updateAccessPointsLocked() {
+    /**
+     * Safely modify {@link #mInternalAccessPoints} by acquiring {@link #mLock} first.
+     *
+     * <p>Will not perform the update if {@link #mStaleScanResults} is true
+     */
+    private void updateAccessPoints() {
+        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+        final List<ScanResult> newScanResults = mWifiManager.getScanResults();
+
         synchronized (mLock) {
-            updateAccessPoints();
+            if(!mStaleScanResults) {
+                updateAccessPointsLocked(newScanResults, configs);
+            }
         }
     }
 
     /**
      * Update the internal list of access points.
      *
-     * <p>Should never be called directly, use {@link #updateAccessPointsLocked()} instead.
+     * <p>Do not called directly (except for forceUpdate), use {@link #updateAccessPoints()} which
+     * respects {@link #mStaleScanResults}.
      */
     @GuardedBy("mLock")
-    private void updateAccessPoints() {
+    private void updateAccessPointsLocked(final List<ScanResult> newScanResults,
+            List<WifiConfiguration> configs) {
+        WifiConfiguration connectionConfig = null;
+        if (mLastInfo != null) {
+            connectionConfig = getWifiConfigurationForNetworkId(
+                    mLastInfo.getNetworkId(), mWifiManager.getConfiguredNetworks());
+        }
+
         // Swap the current access points into a cached list.
         List<AccessPoint> cachedAccessPoints = new ArrayList<>(mInternalAccessPoints);
         ArrayList<AccessPoint> accessPoints = new ArrayList<>();
@@ -477,14 +518,9 @@
     /* Lookup table to more quickly update AccessPoints by only considering objects with the
      * correct SSID.  Maps SSID -> List of AccessPoints with the given SSID.  */
         Multimap<String, AccessPoint> apMap = new Multimap<String, AccessPoint>();
-        WifiConfiguration connectionConfig = null;
-        if (mLastInfo != null) {
-            connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId());
-        }
 
-        final Collection<ScanResult> results = fetchScanResults();
+        final Collection<ScanResult> results = updateScanResultCache(newScanResults);
 
-        final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
         if (configs != null) {
             for (WifiConfiguration config : configs) {
                 if (config.selfAdded && config.numAssociation == 0) {
@@ -533,7 +569,8 @@
 
                 boolean found = false;
                 for (AccessPoint accessPoint : apMap.getAll(result.SSID)) {
-                    if (accessPoint.update(result)) {
+                    // We want to evict old scan results if are current results are not stale
+                    if (accessPoint.update(result, !mStaleScanResults)) {
                         found = true;
                         break;
                     }
@@ -567,7 +604,7 @@
 
         requestScoresForNetworkKeys(scoresToRequest);
         for (AccessPoint ap : accessPoints) {
-            ap.update(mScoreCache, false /* mNetworkScoringUiEnabled */);
+            ap.update(mScoreCache, mNetworkScoringUiEnabled);
         }
 
         // Pre-sort accessPoints to speed preference insertion
@@ -606,7 +643,8 @@
         for (int i = 0; i < N; i++) {
             if (cache.get(i).matches(result)) {
                 AccessPoint ret = cache.remove(i);
-                ret.update(result);
+                // evict old scan results only if we have fresh results
+                ret.update(result, !mStaleScanResults);
                 return ret;
             }
         }
@@ -634,6 +672,7 @@
         /* sticky broadcasts can call this when wifi is disabled */
         if (!mWifiManager.isWifiEnabled()) {
             mMainHandler.sendEmptyMessage(MainHandler.MSG_PAUSE_SCANNING);
+            clearAccessPointsAndConditionallyUpdate();
             return;
         }
 
@@ -651,7 +690,8 @@
         WifiConfiguration connectionConfig = null;
         mLastInfo = mWifiManager.getConnectionInfo();
         if (mLastInfo != null) {
-            connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId());
+            connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId(),
+                    mWifiManager.getConfiguredNetworks());
         }
 
         boolean updated = false;
@@ -665,7 +705,7 @@
                     updated = true;
                     if (previouslyConnected != ap.isActive()) reorder = true;
                 }
-                if (ap.update(mScoreCache, false /* mNetworkScoringUiEnabled */)) {
+                if (ap.update(mScoreCache, mNetworkScoringUiEnabled)) {
                     reorder = true;
                     updated = true;
                 }
@@ -677,6 +717,17 @@
         }
     }
 
+    private void clearAccessPointsAndConditionallyUpdate() {
+        synchronized (mLock) {
+            if (!mInternalAccessPoints.isEmpty()) {
+                mInternalAccessPoints.clear();
+                if (!mMainHandler.hasMessages(MainHandler.MSG_ACCESS_POINT_CHANGED)) {
+                    mMainHandler.sendEmptyMessage(MainHandler.MSG_ACCESS_POINT_CHANGED);
+                }
+            }
+        }
+    }
+
     /**
      * Update all the internal access points rankingScores, badge and metering.
      *
@@ -688,8 +739,7 @@
         synchronized (mLock) {
             boolean updated = false;
             for (int i = 0; i < mInternalAccessPoints.size(); i++) {
-                if (mInternalAccessPoints.get(i).update(
-                        mScoreCache, false /* mNetworkScoringUiEnabled */)) {
+                if (mInternalAccessPoints.get(i).update(mScoreCache, mNetworkScoringUiEnabled)) {
                     updated = true;
                 }
             }
@@ -702,6 +752,9 @@
 
     private void updateWifiState(int state) {
         mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_WIFI_STATE, state, 0).sendToTarget();
+        if (!mWifiManager.isWifiEnabled()) {
+            clearAccessPointsAndConditionallyUpdate();
+        }
     }
 
     public static List<AccessPoint> getCurrentAccessPoints(Context context, boolean includeSaved,
@@ -719,23 +772,26 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
 
-            if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
-                mStaleScanResults = false;
-            }
-
             if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
                 updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                         WifiManager.WIFI_STATE_UNKNOWN));
-            } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action) ||
-                    WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action) ||
-                    WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) {
+            } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
+                mWorkHandler
+                        .obtainMessage(
+                            WorkHandler.MSG_UPDATE_ACCESS_POINTS,
+                            WorkHandler.CLEAR_STALE_SCAN_RESULTS,
+                            0)
+                        .sendToTarget();
+            } else if (WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action)
+                    || WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) {
                 mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
             } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
-                NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(
-                        WifiManager.EXTRA_NETWORK_INFO);
-                mConnected.set(info.isConnected());
+                NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
 
-                mMainHandler.sendEmptyMessage(MainHandler.MSG_CONNECTED_CHANGED);
+                if(mConnected.get() != info.isConnected()) {
+                    mConnected.set(info.isConnected());
+                    mMainHandler.sendEmptyMessage(MainHandler.MSG_CONNECTED_CHANGED);
+                }
 
                 mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO, info)
                         .sendToTarget();
@@ -785,8 +841,15 @@
                     mListener.onWifiStateChanged(msg.arg1);
                     break;
                 case MSG_ACCESS_POINT_CHANGED:
-                    copyAndNotifyListeners(true /*notifyListeners*/);
-                    mListener.onAccessPointsChanged();
+                    // Only notify listeners of changes if we have fresh scan results, otherwise the
+                    // UI will be updated with stale results. We want to copy the APs regardless,
+                    // for instances where forceUpdate was invoked by the caller.
+                    if (mStaleScanResults) {
+                        copyAndNotifyListeners(false /*notifyListeners*/);
+                    } else {
+                        copyAndNotifyListeners(true /*notifyListeners*/);
+                        mListener.onAccessPointsChanged();
+                    }
                     break;
                 case MSG_RESUME_SCANNING:
                     if (mScanner != null) {
@@ -810,12 +873,15 @@
         }
     }
 
-    private final class WorkHandler extends Handler {
+    @VisibleForTesting
+    final class WorkHandler extends Handler {
         private static final int MSG_UPDATE_ACCESS_POINTS = 0;
         private static final int MSG_UPDATE_NETWORK_INFO = 1;
         private static final int MSG_RESUME = 2;
         private static final int MSG_UPDATE_WIFI_STATE = 3;
 
+        private static final int CLEAR_STALE_SCAN_RESULTS = 1;
+
         public WorkHandler(Looper looper) {
             super(looper);
         }
@@ -827,15 +893,15 @@
             }
         }
 
-        @GuardedBy("mLock")
         private void processMessage(Message msg) {
             if (!mRegistered) return;
 
             switch (msg.what) {
                 case MSG_UPDATE_ACCESS_POINTS:
-                    if (!mStaleScanResults) {
-                        updateAccessPointsLocked();
+                    if (msg.arg1 == CLEAR_STALE_SCAN_RESULTS) {
+                        mStaleScanResults = false;
                     }
+                    updateAccessPoints();
                     break;
                 case MSG_UPDATE_NETWORK_INFO:
                     updateNetworkInfo((NetworkInfo) msg.obj);
diff --git a/packages/SettingsLib/tests/integ/AndroidManifest.xml b/packages/SettingsLib/tests/integ/AndroidManifest.xml
index 0d5ff2c..e8e0b41 100644
--- a/packages/SettingsLib/tests/integ/AndroidManifest.xml
+++ b/packages/SettingsLib/tests/integ/AndroidManifest.xml
@@ -21,6 +21,7 @@
     <uses-permission android:name="android.permission.MANAGE_USERS" />
     <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY"/>
     <uses-permission android:name="android.permission.SET_TIME_ZONE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
diff --git a/packages/SettingsLib/tests/integ/AndroidTest.xml b/packages/SettingsLib/tests/integ/AndroidTest.xml
index 8581acb..96621eb 100644
--- a/packages/SettingsLib/tests/integ/AndroidTest.xml
+++ b/packages/SettingsLib/tests/integ/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="SettingsLibTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.settingslib" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
index 83667ea..01df0ec 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
@@ -3,6 +3,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
+import android.graphics.Rect;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -12,6 +13,7 @@
 import org.junit.runner.RunWith;
 
 import static com.google.common.truth.Truth.assertThat;
+import static junit.framework.Assert.assertTrue;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyFloat;
 import static org.mockito.Matchers.anyString;
@@ -68,4 +70,49 @@
             }
         }
     }
+
+    @Test
+    public void testPadding_returnsCorrectValues() {
+        // different pads on each side to differentiate
+        final int left = 1;
+        final int top = 2;
+        final int right = 3;
+        final int bottom = 4;
+
+        final Rect expected = new Rect(left, top, right, bottom);
+        final Rect padding = new Rect();
+
+        mBatteryDrawable.setPadding(left, top, right, bottom);
+
+        assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(true);
+        assertThat(padding).isEqualTo(expected);
+    }
+
+    @Test
+    public void testPadding_falseIfUnsetOrZero() {
+        final Rect padding = new Rect();
+        assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(false);
+        assertThat(isRectZero(padding)).isEqualTo(true);
+
+        mBatteryDrawable.setPadding(0, 0, 0, 0);
+        assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(false);
+        assertThat(isRectZero(padding)).isEqualTo(true);
+    }
+
+    private boolean isRectZero(Rect r) {
+        return r.left == 0 && r.top == 0 && r.right == 0 && r.bottom == 0;
+    }
+
+    @Test
+    public void testPlusPaint_isEqualToBoltPaint() {
+        // Before setting color
+        assertTrue(mBatteryDrawable.mPlusPaint.hasEqualAttributes(mBatteryDrawable.mBoltPaint));
+
+        final int fakeFillColor = 123;
+        final int fakeBackgrundColor = 456;
+
+        // After
+        mBatteryDrawable.setColors(fakeFillColor, fakeBackgrundColor);
+        assertTrue(mBatteryDrawable.mPlusPaint.hasEqualAttributes(mBatteryDrawable.mBoltPaint));
+    }
 }
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index 801844b..88d3a32 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -19,12 +19,18 @@
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
+import android.net.NetworkKey;
+import android.net.RssiCurve;
 import android.net.ScoredNetwork;
+import android.net.WifiKey;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
@@ -40,6 +46,8 @@
 import android.text.SpannableString;
 import android.text.style.TtsSpan;
 
+import com.android.settingslib.R;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -55,7 +63,8 @@
 
     private static final String TEST_SSID = "test_ssid";
     private Context mContext;
-    @Mock private WifiNetworkScoreCache mWifiNetworkScoreCache;
+    @Mock private RssiCurve mockBadgeCurve;
+    @Mock private WifiNetworkScoreCache mockWifiNetworkScoreCache;
 
     @Before
     public void setUp() {
@@ -162,6 +171,21 @@
     }
 
     @Test
+    public void testCompareTo_GivesSsidCasePrecendenceAfterAlphabetical() {
+
+        final String firstName = "aaAaaa";
+        final String secondName = "aaaaaa";
+        final String thirdName = "BBBBBB";
+
+        AccessPoint firstAp = new TestAccessPointBuilder(mContext).setSsid(firstName).build();
+        AccessPoint secondAp = new TestAccessPointBuilder(mContext).setSsid(secondName).build();
+        AccessPoint thirdAp = new TestAccessPointBuilder(mContext).setSsid(thirdName).build();
+
+        assertSortingWorks(firstAp, secondAp);
+        assertSortingWorks(secondAp, thirdAp);
+    }
+
+    @Test
     public void testCompareTo_AllSortingRulesCombined() {
 
         AccessPoint active = new TestAccessPointBuilder(mContext).setActive(true).build();
@@ -223,7 +247,7 @@
         scanResult.BSSID = "bssid";
         scanResult.timestamp = SystemClock.elapsedRealtime() * 1000;
         scanResult.capabilities = "";
-        assertThat(ap.update(scanResult)).isTrue();
+        assertThat(ap.update(scanResult, true /* evict old scan results */)).isTrue();
 
         assertThat(ap.getRssi()).isEqualTo(expectedRssi);
     }
@@ -294,13 +318,13 @@
     public void testIsMetered_returnTrueWhenScoredNetworkIsMetered() {
         AccessPoint ap = createAccessPointWithScanResultCache();
 
-        when(mWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
                 .thenReturn(
                         new ScoredNetwork(
                                 null /* NetworkKey */,
                                 null /* rssiCurve */,
                                 true /* metered */));
-        ap.update(mWifiNetworkScoreCache, false /* scoringUiEnabled */);
+        ap.update(mockWifiNetworkScoreCache, false /* scoringUiEnabled */);
 
         assertThat(ap.isMetered()).isTrue();
     }
@@ -321,6 +345,119 @@
         assertThat(accessPoint.isMetered()).isFalse();
     }
 
+    @Test
+    public void testSpeedLabel_returnsVeryFast() {
+        AccessPoint ap = createAccessPointWithScanResultCache();
+
+        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
+
+        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
+
+        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.VERY_FAST);
+        assertThat(ap.getSpeedLabel())
+                .isEqualTo(mContext.getString(R.string.speed_label_very_fast));
+    }
+
+    @Test
+    public void testSpeedLabel_returnsFast() {
+        AccessPoint ap = createAccessPointWithScanResultCache();
+
+        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.FAST);
+
+        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
+
+        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.FAST);
+        assertThat(ap.getSpeedLabel())
+                .isEqualTo(mContext.getString(R.string.speed_label_fast));
+    }
+
+    @Test
+    public void testSpeedLabel_returnsOkay() {
+        AccessPoint ap = createAccessPointWithScanResultCache();
+
+        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.MODERATE);
+
+        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
+
+        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.MODERATE);
+        assertThat(ap.getSpeedLabel())
+                .isEqualTo(mContext.getString(R.string.speed_label_okay));
+    }
+
+    @Test
+    public void testSpeedLabel_returnsSlow() {
+        AccessPoint ap = createAccessPointWithScanResultCache();
+
+        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.SLOW);
+
+        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
+
+        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.SLOW);
+        assertThat(ap.getSpeedLabel())
+                .isEqualTo(mContext.getString(R.string.speed_label_slow));
+    }
+
+    @Test
+    public void testSummaryString_showsSpeedLabel() {
+        AccessPoint ap = createAccessPointWithScanResultCache();
+
+        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
+
+        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
+
+        assertThat(ap.getSummary()).isEqualTo(mContext.getString(R.string.speed_label_very_fast));
+    }
+
+    @Test
+    public void testSummaryString_concatenatesSpeedLabel() {
+        AccessPoint ap = createAccessPointWithScanResultCache();
+        ap.update(new WifiConfiguration());
+
+        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
+
+        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
+
+        String expectedString = mContext.getString(R.string.speed_label_very_fast) + " / "
+                + mContext.getString(R.string.wifi_remembered);
+        assertThat(ap.getSummary()).isEqualTo(expectedString);
+    }
+
+    @Test
+    public void testSummaryString_showsWrongPasswordLabel() {
+        WifiConfiguration configuration = createWifiConfiguration();
+        configuration.getNetworkSelectionStatus().setNetworkSelectionStatus(
+                WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED);
+        configuration.getNetworkSelectionStatus().setNetworkSelectionDisableReason(
+                WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD);
+        AccessPoint ap = new AccessPoint(mContext, configuration);
+
+        assertThat(ap.getSummary()).isEqualTo(mContext.getString(
+                R.string.wifi_check_password_try_again));
+    }
+
+    private ScoredNetwork buildScoredNetworkWithMockBadgeCurve() {
+        Bundle attr1 = new Bundle();
+        attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve);
+        return new ScoredNetwork(
+                new NetworkKey(new WifiKey("\"ssid\"", "00:00:00:00:00:00")),
+                mockBadgeCurve,
+                false /* meteredHint */,
+                attr1);
+
+    }
+
     private AccessPoint createAccessPointWithScanResultCache() {
         Bundle bundle = new Bundle();
         ArrayList<ScanResult> scanResults = new ArrayList<>();
@@ -333,7 +470,7 @@
             scanResults.add(scanResult);
         }
 
-        bundle.putParcelableArrayList("key_scanresultcache", scanResults);
+        bundle.putParcelableArrayList(AccessPoint.KEY_SCANRESULTCACHE, scanResults);
         return new AccessPoint(mContext, bundle);
     }
 
@@ -487,4 +624,111 @@
         NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
         assertThat(ap.update(config, wifiInfo, newInfo)).isFalse();
     }
+
+    @Test
+    public void testUpdateWithDifferentRssi_returnsTrue() {
+        int networkId = 123;
+        int rssi = -55;
+        WifiConfiguration config = new WifiConfiguration();
+        config.networkId = networkId;
+        WifiInfo wifiInfo = new WifiInfo();
+        wifiInfo.setNetworkId(networkId);
+        wifiInfo.setRssi(rssi);
+
+        NetworkInfo networkInfo =
+                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
+
+        AccessPoint ap = new TestAccessPointBuilder(mContext)
+                .setNetworkInfo(networkInfo)
+                .setNetworkId(networkId)
+                .setRssi(rssi)
+                .setWifiInfo(wifiInfo)
+                .build();
+
+        NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
+        wifiInfo.setRssi(rssi + 1);
+        assertThat(ap.update(config, wifiInfo, newInfo)).isTrue();
+    }
+
+    @Test
+    public void testUpdateWithInvalidRssi_returnsFalse() {
+        int networkId = 123;
+        int rssi = -55;
+        WifiConfiguration config = new WifiConfiguration();
+        config.networkId = networkId;
+        WifiInfo wifiInfo = new WifiInfo();
+        wifiInfo.setNetworkId(networkId);
+        wifiInfo.setRssi(rssi);
+
+        NetworkInfo networkInfo =
+                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
+
+        AccessPoint ap = new TestAccessPointBuilder(mContext)
+                .setNetworkInfo(networkInfo)
+                .setNetworkId(networkId)
+                .setRssi(rssi)
+                .setWifiInfo(wifiInfo)
+                .build();
+
+        NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
+        wifiInfo.setRssi(WifiInfo.INVALID_RSSI);
+        assertThat(ap.update(config, wifiInfo, newInfo)).isFalse();
+    }
+    @Test
+    public void testUpdateWithConfigChangeOnly_returnsFalseButInvokesListener() {
+        int networkId = 123;
+        int rssi = -55;
+        WifiConfiguration config = new WifiConfiguration();
+        config.networkId = networkId;
+        config.numNoInternetAccessReports = 1;
+
+        WifiInfo wifiInfo = new WifiInfo();
+        wifiInfo.setNetworkId(networkId);
+        wifiInfo.setRssi(rssi);
+
+        NetworkInfo networkInfo =
+                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", "");
+
+        AccessPoint ap = new TestAccessPointBuilder(mContext)
+                .setNetworkInfo(networkInfo)
+                .setNetworkId(networkId)
+                .setRssi(rssi)
+                .setWifiInfo(wifiInfo)
+                .build();
+
+        AccessPoint.AccessPointListener mockListener = mock(AccessPoint.AccessPointListener.class);
+        ap.setListener(mockListener);
+        WifiConfiguration newConfig = new WifiConfiguration(config);
+        config.validatedInternetAccess = true;
+
+        assertThat(ap.update(newConfig, wifiInfo, networkInfo)).isFalse();
+        verify(mockListener).onAccessPointChanged(ap);
+    }
+
+    @Test
+    public void testUpdateWithNullWifiConfiguration_doesNotThrowNPE() {
+        int networkId = 123;
+        int rssi = -55;
+        WifiConfiguration config = new WifiConfiguration();
+        config.networkId = networkId;
+        WifiInfo wifiInfo = new WifiInfo();
+        wifiInfo.setNetworkId(networkId);
+        wifiInfo.setRssi(rssi);
+
+        NetworkInfo networkInfo =
+                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
+
+        AccessPoint ap = new TestAccessPointBuilder(mContext)
+                .setNetworkInfo(networkInfo)
+                .setNetworkId(networkId)
+                .setRssi(rssi)
+                .setWifiInfo(wifiInfo)
+                .build();
+
+        ap.update(null, wifiInfo, networkInfo);
+    }
 }
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
deleted file mode 100644
index 2213ae6..0000000
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
+++ /dev/null
@@ -1,174 +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.settingslib.wifi;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiInfo;
-import android.os.Bundle;
-
-/**
-* Build and return a valid AccessPoint.
-*
-* Only intended for testing the AccessPoint class;
-* AccessPoints were designed to only be populated
-* by the mechanisms of scan results and wifi configurations.
-*/
-public class TestAccessPointBuilder {
-    // match the private values in WifiManager
-    private static final int MIN_RSSI = -100;
-    private static final int MAX_RSSI = -55;
-
-    // set some sensible defaults
-    private int mRssi = AccessPoint.UNREACHABLE_RSSI;
-    private int mNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
-    private String ssid = "TestSsid";
-    private NetworkInfo mNetworkInfo = null;
-    private String mFqdn = null;
-    private String mProviderFriendlyName = null;
-    private WifiConfiguration mWifiConfig;
-    private WifiInfo mWifiInfo;
-
-    Context mContext;
-
-    public TestAccessPointBuilder(Context context) {
-        mContext = context;
-    }
-
-    public AccessPoint build() {
-        Bundle bundle = new Bundle();
-
-        WifiConfiguration wifiConfig = new WifiConfiguration();
-        wifiConfig.networkId = mNetworkId;
-
-        bundle.putString(AccessPoint.KEY_SSID, ssid);
-        bundle.putParcelable(AccessPoint.KEY_CONFIG, wifiConfig);
-        bundle.putParcelable(AccessPoint.KEY_NETWORKINFO, mNetworkInfo);
-        bundle.putParcelable(AccessPoint.KEY_WIFIINFO, mWifiInfo);
-        if (mFqdn != null) {
-            bundle.putString(AccessPoint.KEY_FQDN, mFqdn);
-        }
-        if (mProviderFriendlyName != null) {
-            bundle.putString(AccessPoint.KEY_PROVIDER_FRIENDLY_NAME, mProviderFriendlyName);
-        }
-        AccessPoint ap = new AccessPoint(mContext, bundle);
-        ap.setRssi(mRssi);
-        return ap;
-    }
-
-    public TestAccessPointBuilder setActive(boolean active) {
-        if (active) {
-            mNetworkInfo = new NetworkInfo(
-                ConnectivityManager.TYPE_DUMMY,
-                ConnectivityManager.TYPE_DUMMY,
-                "TestNetwork",
-                "TestNetwork");
-        } else {
-            mNetworkInfo = null;
-        }
-        return this;
-    }
-
-    /**
-     * Set the rssi based upon the desired signal level.
-     *
-     * <p>Side effect: if this AccessPoint was previously unreachable,
-     * setting the level will also make it reachable.
-     */
-    public TestAccessPointBuilder setLevel(int level) {
-        // Reversal of WifiManager.calculateSignalLevels
-        if (level == 0) {
-            mRssi = MIN_RSSI;
-        } else if (level >= AccessPoint.SIGNAL_LEVELS) {
-            mRssi = MAX_RSSI;
-        } else {
-            float inputRange = MAX_RSSI - MIN_RSSI;
-            float outputRange = AccessPoint.SIGNAL_LEVELS - 1;
-            mRssi = (int) (level * inputRange / outputRange + MIN_RSSI);
-        }
-        return this;
-    }
-
-    public TestAccessPointBuilder setNetworkInfo(NetworkInfo info) {
-        mNetworkInfo = info;
-        return this;
-    }
-
-    public TestAccessPointBuilder setRssi(int rssi) {
-        mRssi = rssi;
-        return this;
-    }
-
-    /**
-    * Set whether the AccessPoint is reachable.
-    * Side effect: if the signal level was not previously set,
-    * making an AccessPoint reachable will set the signal to the minimum level.
-    */
-    public TestAccessPointBuilder setReachable(boolean reachable) {
-        if (reachable) {
-            // only override the mRssi if it hasn't been set yet
-            if (mRssi == AccessPoint.UNREACHABLE_RSSI) {
-                mRssi = MIN_RSSI;
-            }
-        } else {
-            mRssi = AccessPoint.UNREACHABLE_RSSI;
-        }
-        return this;
-    }
-
-    public TestAccessPointBuilder setSaved(boolean saved){
-        if (saved) {
-             mNetworkId = 1;
-        } else {
-             mNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
-        }
-        return this;
-    }
-
-    public TestAccessPointBuilder setSsid(String newSsid) {
-        ssid = newSsid;
-        return this;
-    }
-
-    public TestAccessPointBuilder setFqdn(String fqdn) {
-        mFqdn = fqdn;
-        return this;
-    }
-
-    public TestAccessPointBuilder setProviderFriendlyName(String friendlyName) {
-        mProviderFriendlyName = friendlyName;
-        return this;
-    }
-
-    public TestAccessPointBuilder setWifiInfo(WifiInfo info) {
-        mWifiInfo = info;
-        return this;
-    }
-
-    /**
-     * Set the networkId in the WifiConfig.
-     *
-     * <p>Setting this to a value other than {@link WifiConfiguration#INVALID_NETWORK_ID} makes this
-     * AccessPoint a saved network.
-     */
-    public TestAccessPointBuilder setNetworkId(int networkId) {
-        mNetworkId = networkId;
-        return this;
-    }
-}
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 eb9a7f6..df6587e 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
@@ -38,7 +38,6 @@
 import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.Network;
-import android.net.NetworkBadging;
 import android.net.NetworkInfo;
 import android.net.NetworkKey;
 import android.net.NetworkScoreManager;
@@ -60,6 +59,7 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.FlakyTest;
 
 import org.junit.After;
 import org.junit.Before;
@@ -95,7 +95,7 @@
             new NetworkKey(new WifiKey('"' + SSID_1 + '"', BSSID_1));
     private static final int RSSI_1 = -30;
     private static final byte SCORE_1 = 10;
-    private static final int BADGE_1 = NetworkBadging.BADGING_SD;
+    private static final int BADGE_1 = AccessPoint.Speed.MODERATE;
 
     private static final String SSID_2 = "ssid2";
     private static final String BSSID_2 = "AA:AA:AA:AA:AA:AA";
@@ -103,7 +103,7 @@
             new NetworkKey(new WifiKey('"' + SSID_2 + '"', BSSID_2));
     private static final int RSSI_2 = -30;
     private static final byte SCORE_2 = 15;
-    private static final int BADGE_2 = NetworkBadging.BADGING_HD;
+    private static final int BADGE_2 = AccessPoint.Speed.FAST;
 
     private static final int CONNECTED_NETWORK_ID = 123;
     private static final int CONNECTED_RSSI = -50;
@@ -135,6 +135,7 @@
     private HandlerThread mWorkerThread;
     private Looper mWorkerLooper;
     private Looper mMainLooper;
+
     private int mOriginalScoringUiSettingValue;
 
     @Before
@@ -210,6 +211,7 @@
                 InstrumentationRegistry.getTargetContext().getContentResolver(),
                 Settings.Global.NETWORK_SCORING_UI_ENABLED,
                 1 /* enabled */);
+
     }
 
     @After
@@ -257,6 +259,7 @@
         }
 
         sendScanResultsAndProcess(tracker);
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
         return tracker;
     }
@@ -339,7 +342,27 @@
 
         Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
         intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
-        return createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(intent);
+        WifiTracker tracker =
+                createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(intent);
+        assertThat(tracker.isConnected()).isTrue();
+        return tracker;
+    }
+
+    private void waitForHandlersToProcessCurrentlyEnqueuedMessages(WifiTracker tracker)
+            throws InterruptedException {
+        CountDownLatch workerLatch = new CountDownLatch(1);
+        tracker.mWorkHandler.post(() -> {
+            workerLatch.countDown();
+        });
+        assertTrue("Latch timed out while waiting for WorkerHandler",
+                workerLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+
+        CountDownLatch mainLatch = new CountDownLatch(1);
+        tracker.mMainHandler.post(() -> {
+            mainLatch.countDown();
+        });
+        assertTrue("Latch timed out while waiting for MainHandler",
+                mainLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
     }
 
     @Test
@@ -427,7 +450,7 @@
 
     @Test
     public void startTrackingShouldSetConnectedAccessPointAsActive() throws InterruptedException {
-        WifiTracker tracker =  createTrackerWithScanResultsAndAccessPoint1Connected();
+        WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
@@ -455,38 +478,52 @@
     }
 
     @Test
+    public void stopTracking_shouldNotClearExistingScores()
+            throws InterruptedException {
+        // Start the tracker and inject the initial scan results and then stop tracking
+        WifiTracker tracker =  createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
+        tracker.stopTracking();
+
+        assertThat(mScoreCacheCaptor.getValue().getScoredNetwork(NETWORK_KEY_1)).isNotNull();
+    }
+
+    @Test
     public void scoreCacheUpdateScoresShouldTriggerOnAccessPointsChanged()
             throws InterruptedException {
         WifiTracker tracker = createMockedWifiTracker();
         startTracking(tracker);
         sendScanResultsAndProcess(tracker);
 
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
     }
 
-    private void updateScoresAndWaitForAccessPointsChangedCallback() throws InterruptedException {
+    private void updateScoresAndWaitForAccessPointsChangedCallback(WifiTracker tracker)
+            throws InterruptedException {
         // Updating scores can happen together or one after the other, so the latch countdown is set
         // to 2.
-        mAccessPointsChangedLatch = new CountDownLatch(2);
+        mAccessPointsChangedLatch = new CountDownLatch(1);
         updateScores();
-        assertTrue("onAccessPointChanged was not called twice",
+        assertTrue("onAccessPointChanged was not called after updating scores",
             mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
     }
 
+    @FlakyTest
     @Test
-    public void scoreCacheUpdateScoresShouldNotChangeSortOrder() throws InterruptedException {
+    public void scoreCacheUpdateScoresShouldChangeSortOrder() throws InterruptedException {
         WifiTracker tracker =  createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
         List<AccessPoint> aps = tracker.getAccessPoints();
         assertTrue(aps.size() == 2);
         assertEquals(aps.get(0).getSsidStr(), SSID_1);
         assertEquals(aps.get(1).getSsidStr(), SSID_2);
 
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         aps = tracker.getAccessPoints();
         assertTrue(aps.size() == 2);
-        assertEquals(aps.get(0).getSsidStr(), SSID_1);
-        assertEquals(aps.get(1).getSsidStr(), SSID_2);
+        assertEquals(aps.get(0).getSsidStr(), SSID_2);
+        assertEquals(aps.get(1).getSsidStr(), SSID_1);
     }
 
     @Test
@@ -503,7 +540,7 @@
         assertEquals(aps.get(0).getSsidStr(), SSID_1);
         assertEquals(aps.get(1).getSsidStr(), SSID_2);
 
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         aps = tracker.getAccessPoints();
         assertTrue(aps.size() == 2);
@@ -511,19 +548,20 @@
         assertEquals(aps.get(1).getSsidStr(), SSID_2);
     }
 
+    @FlakyTest
     @Test
-    public void scoreCacheUpdateScoresShouldNotInsertBadgeIntoAccessPoint()
+    public void scoreCacheUpdateScoresShouldInsertSpeedIntoAccessPoint()
             throws InterruptedException {
         WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
         for (AccessPoint ap : aps) {
             if (ap.getSsidStr().equals(SSID_1)) {
-                assertEquals(NetworkBadging.BADGING_NONE, ap.getBadge());
+                assertEquals(BADGE_1, ap.getSpeed());
             } else if (ap.getSsidStr().equals(SSID_2)) {
-                assertEquals(NetworkBadging.BADGING_NONE, ap.getBadge());
+                assertEquals(BADGE_2, ap.getSpeed());
             }
         }
     }
@@ -532,7 +570,7 @@
     public void scoreCacheUpdateMeteredShouldUpdateAccessPointMetering()
             throws InterruptedException {
         WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
@@ -546,7 +584,7 @@
     }
 
     @Test
-    public void noBadgesShouldBeInsertedIntoAccessPointWhenScoringUiDisabled()
+    public void noSpeedsShouldBeInsertedIntoAccessPointWhenScoringUiDisabled()
             throws InterruptedException {
         Settings.Global.putInt(
                 InstrumentationRegistry.getTargetContext().getContentResolver(),
@@ -554,15 +592,15 @@
                 0 /* disabled */);
 
         WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
         for (AccessPoint ap : aps) {
             if (ap.getSsidStr().equals(SSID_1)) {
-                assertEquals(NetworkBadging.BADGING_NONE, ap.getBadge());
+                assertEquals(AccessPoint.Speed.NONE, ap.getSpeed());
             } else if (ap.getSsidStr().equals(SSID_2)) {
-                assertEquals(NetworkBadging.BADGING_NONE, ap.getBadge());
+                assertEquals(AccessPoint.Speed.NONE, ap.getSpeed());
             }
         }
     }
@@ -702,7 +740,7 @@
         verify(mockWifiManager, times(2)).getConfiguredNetworks();
         verify(mockConnectivityManager).getNetworkInfo(any(Network.class));
 
-        verify(mockWifiListener).onAccessPointsChanged();
+        verify(mockWifiListener, never()).onAccessPointsChanged(); // mStaleAccessPoints is true
         assertThat(tracker.getAccessPoints().size()).isEqualTo(2);
         assertThat(tracker.getAccessPoints().get(0).isActive()).isTrue();
     }
@@ -755,13 +793,10 @@
             throws Exception {
         WifiTracker tracker = createMockedWifiTracker();
         startTracking(tracker);
-        tracker.stopTracking();
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
-        CountDownLatch latch1 = new CountDownLatch(1);
-        tracker.mMainHandler.post(() -> {
-                latch1.countDown();
-        });
-        assertTrue("Latch 1 timed out", latch1.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+        tracker.stopTracking();
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
         startTracking(tracker);
 
@@ -771,14 +806,79 @@
         tracker.mReceiver.onReceive(
                 mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION));
 
-        CountDownLatch latch2 = new CountDownLatch(1);
-        tracker.mMainHandler.post(() -> {
-            latch2.countDown();
-        });
-        assertTrue("Latch 2 timed out", latch2.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
         verify(mockWifiListener, never()).onAccessPointsChanged();
 
         sendScanResultsAndProcess(tracker); // verifies onAccessPointsChanged is invoked
     }
+
+    @Test
+    public void startTrackingShouldNotSendAnyCallbacksUntilScanResultsAreProcessed()
+            throws Exception {
+        WifiTracker tracker = createMockedWifiTracker();
+        startTracking(tracker);
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+
+        tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
+        tracker.mReceiver.onReceive(
+                mContext, new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
+        tracker.mReceiver.onReceive(
+                mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION));
+
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+        verify(mockWifiListener, never()).onAccessPointsChanged();
+
+        sendScanResultsAndProcess(tracker); // verifies onAccessPointsChanged is invoked
+    }
+
+    @Test
+    public void disablingWifiShouldClearExistingAccessPoints() throws Exception {
+        WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
+
+        when(mockWifiManager.isWifiEnabled()).thenReturn(false);
+        mAccessPointsChangedLatch = new CountDownLatch(1);
+        tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
+
+        mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+
+        assertThat(tracker.getAccessPoints()).isEmpty();
+    }
+
+    @Test
+    public void onConnectedChangedCallback_shouldNotBeInvokedWhenNoStateChange() throws Exception {
+        WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
+        verify(mockWifiListener, times(1)).onConnectedChanged();
+
+        NetworkInfo networkInfo = new NetworkInfo(
+                ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "connected", "test");
+
+        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
+        tracker.mReceiver.onReceive(mContext, intent);
+
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+        verify(mockWifiListener, times(1)).onConnectedChanged();
+    }
+
+    @Test
+    public void onConnectedChangedCallback_shouldBeInvokedWhenStateChanges() throws Exception {
+        WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
+        verify(mockWifiListener, times(1)).onConnectedChanged();
+
+        NetworkInfo networkInfo = new NetworkInfo(
+                ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
+        networkInfo.setDetailedState(
+                NetworkInfo.DetailedState.DISCONNECTED, "disconnected", "test");
+
+        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
+        tracker.mReceiver.onReceive(mContext, intent);
+
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+        assertThat(tracker.isConnected()).isFalse();
+        verify(mockWifiListener, times(2)).onConnectedChanged();
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/res/drawable/ic_info_outline_24dp.xml b/packages/SettingsLib/tests/robotests/res/drawable/ic_info_outline_24dp.xml
new file mode 100644
index 0000000..3fe1e9e
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/res/drawable/ic_info_outline_24dp.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/textColorSecondary">
+    <path
+        android:fillColor="#000000"
+        android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
+</vector>
diff --git a/packages/SettingsLib/tests/robotests/res/layout/preference_footer.xml b/packages/SettingsLib/tests/robotests/res/layout/preference_footer.xml
new file mode 100644
index 0000000..c47bff7
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/res/layout/preference_footer.xml
@@ -0,0 +1,54 @@
+<?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.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:background="?android:attr/selectableItemBackground"
+    android:clipToPadding="false">
+
+    <LinearLayout
+        android:id="@+id/icon_container"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:minWidth="60dp"
+        android:gravity="start|top"
+        android:orientation="horizontal"
+        android:paddingEnd="12dp"
+        android:paddingTop="20dp"
+        android:paddingBottom="4dp">
+        <ImageView
+            android:id="@android:id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+    </LinearLayout>
+
+    <com.android.settingslib.widget.LinkTextView
+        android:id="@android:id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingBottom="16dp"
+        android:paddingTop="16dp"
+        android:maxLines="10"
+        android:textColor="?android:attr/textColorSecondary"
+        android:ellipsize="marquee" />
+
+</LinearLayout>
diff --git a/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml b/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml
index 1eeafba..f02ac15 100644
--- a/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml
+++ b/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml
@@ -15,10 +15,14 @@
 -->
 
 <optional-steps>
+    <step category="com.android.settings.suggested.category.DEFERRED_SETUP"
+        exclusive="true" />
     <step category="com.android.settings.suggested.category.LOCK_SCREEN" />
+    <step category="com.android.settings.suggested.category.TRUST_AGENT" />
     <step category="com.android.settings.suggested.category.EMAIL" />
     <step category="com.android.settings.suggested.category.PARTNER_ACCOUNT"
         multiple="true" />
+    <step category="com.android.settings.suggested.category.GESTURE" />
     <step category="com.android.settings.suggested.category.HOTWORD" />
     <step category="com.android.settings.suggested.category.DEFAULT"
         multiple="true" />
diff --git a/packages/SettingsLib/tests/robotests/src/android/net/wifi/WifiNetworkScoreCache.java b/packages/SettingsLib/tests/robotests/src/android/net/wifi/WifiNetworkScoreCache.java
new file mode 100644
index 0000000..abccd8d
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/android/net/wifi/WifiNetworkScoreCache.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.net.wifi;
+
+import android.content.Context;
+import android.os.Handler;
+
+import java.util.List;
+
+/**
+ * Will be removed once robolectric is updated to O
+ */
+public class WifiNetworkScoreCache {
+
+    public WifiNetworkScoreCache(Context context, WifiNetworkScoreCache.CacheListener listener) {
+    }
+
+    public abstract static class CacheListener {
+        public CacheListener(Handler handler) {
+        }
+
+        void post(List updatedNetworks) {
+        }
+
+        public abstract void networkCacheUpdated(List updatedNetworks);
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/BatteryInfoTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/BatteryInfoTest.java
deleted file mode 100644
index 69efc9e..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/BatteryInfoTest.java
+++ /dev/null
@@ -1,120 +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.settingslib;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.BatteryManager;
-import android.os.BatteryStats;
-import android.os.SystemClock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.when;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class BatteryInfoTest {
-    private static final String STATUS_FULL = "Full";
-    private static final String STATUS_CHARGING_NO_TIME = "Charging";
-    private static final String STATUS_CHARGING_TIME = "Charging - 2h left";
-    private static final int PLUGGED_IN = 1;
-    private static final long REMAINING_TIME_NULL = -1;
-    private static final long REMAINING_TIME = 2;
-    private Intent mDisChargingBatteryBroadcast;
-    private Intent mChargingBatteryBroadcast;
-
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private BatteryStats mBatteryStats;
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        mDisChargingBatteryBroadcast = new Intent();
-        mDisChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_PLUGGED, 0);
-        mDisChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_LEVEL, 0);
-        mDisChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_SCALE, 100);
-        mDisChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_STATUS,
-                BatteryManager.BATTERY_STATUS_FULL);
-
-        mChargingBatteryBroadcast = new Intent();
-        mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_PLUGGED,
-                BatteryManager.BATTERY_PLUGGED_AC);
-        mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_LEVEL, 50);
-        mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_SCALE, 100);
-        mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_STATUS,
-                BatteryManager.BATTERY_STATUS_UNKNOWN);
-
-        when(mContext.getResources().getString(R.string.battery_info_status_full))
-                .thenReturn(STATUS_FULL);
-        when(mContext.getResources().getString(eq(R.string.power_charging), any(),
-                any())).thenReturn(STATUS_CHARGING_NO_TIME);
-        when(mContext.getResources().getString(eq(R.string.power_charging_duration), any(),
-                any())).thenReturn(STATUS_CHARGING_TIME);
-    }
-
-    @Test
-    public void testGetBatteryInfo_hasStatusLabel() {
-        doReturn(REMAINING_TIME_NULL).when(mBatteryStats).computeBatteryTimeRemaining(anyLong());
-        BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
-                mBatteryStats, SystemClock.elapsedRealtime() * 1000, true);
-
-        assertThat(info.statusLabel).isEqualTo(STATUS_FULL);
-    }
-
-    @Test
-    public void testGetBatteryInfo_doNotShowChargingMethod_hasRemainingTime() {
-        doReturn(REMAINING_TIME).when(mBatteryStats).computeChargeTimeRemaining(anyLong());
-        BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
-                mBatteryStats, SystemClock.elapsedRealtime() * 1000, false);
-
-        assertThat(info.chargeLabelString).isEqualTo(STATUS_CHARGING_TIME);
-    }
-
-    @Test
-    public void testGetBatteryInfo_doNotShowChargingMethod_noRemainingTime() {
-        doReturn(REMAINING_TIME_NULL).when(mBatteryStats).computeChargeTimeRemaining(anyLong());
-        BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
-                mBatteryStats, SystemClock.elapsedRealtime() * 1000, false);
-
-        assertThat(info.chargeLabelString).isEqualTo(STATUS_CHARGING_NO_TIME);
-    }
-
-    @Test
-    public void testGetBatteryInfo_pluggedIn_dischargingFalse() {
-        BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
-                mBatteryStats, SystemClock.elapsedRealtime() * 1000, true);
-
-        assertThat(info.discharging).isEqualTo(false);
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
deleted file mode 100644
index 7729dec..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
+++ /dev/null
@@ -1,128 +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.settingslib;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-
-import com.android.settingslib.drawer.Tile;
-import com.android.settingslib.drawer.TileUtilsTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-@RunWith(SettingLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class SuggestionParserTest {
-
-    @Mock
-    private PackageManager mPackageManager;
-    private Context mContext;
-    private SuggestionParser mSuggestionParser;
-    private SuggestionParser.SuggestionCategory mSuggestioCategory;
-    private List<Tile> mSuggestionsBeforeDismiss;
-    private List<Tile> mSuggestionsAfterDismiss;
-    private SharedPreferences mPrefs;
-    private Tile mSuggestion;
-    private List<ResolveInfo> mInfo;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = spy(RuntimeEnvironment.application);
-        when(mContext.getPackageManager()).thenReturn(mPackageManager);
-        mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
-        mSuggestion = new Tile();
-        mSuggestion.intent = new Intent("action");
-        mSuggestion.intent.setComponent(new ComponentName("pkg", "cls"));
-        mSuggestion.metaData = new Bundle();
-        mSuggestionParser = new SuggestionParser(
-            mContext, mPrefs, R.xml.suggestion_ordering, "0,0");
-        mSuggestioCategory = new SuggestionParser.SuggestionCategory();
-        mSuggestioCategory.category = "category1";
-        mSuggestioCategory.multiple = true;
-        mInfo = new ArrayList<>();
-        ResolveInfo info1 = TileUtilsTest.newInfo(true, "category1");
-        info1.activityInfo.packageName = "pkg";
-        ResolveInfo info2 = TileUtilsTest.newInfo(true, "category1");
-        info2.activityInfo.packageName = "pkg2";
-        mInfo.add(info1);
-        mInfo.add(info2);
-        when(mPackageManager.queryIntentActivitiesAsUser(
-            any(Intent.class), anyInt(), anyInt())).thenReturn(mInfo);
-    }
-
-    @Test
-    public void testDismissSuggestion_withoutSmartSuggestion() {
-        assertThat(mSuggestionParser.dismissSuggestion(mSuggestion, false)).isTrue();
-    }
-
-    @Test
-    public void testDismissSuggestion_withSmartSuggestion() {
-        assertThat(mSuggestionParser.dismissSuggestion(mSuggestion, true)).isFalse();
-    }
-
-    @Test
-    public void testGetSuggestions_withoutSmartSuggestions() {
-        readAndDismissSuggestion(false);
-        mSuggestionParser.readSuggestions(mSuggestioCategory, mSuggestionsAfterDismiss, false);
-        assertThat(mSuggestionsBeforeDismiss.size()).isEqualTo(2);
-        assertThat(mSuggestionsAfterDismiss.size()).isEqualTo(1);
-        assertThat(mSuggestionsBeforeDismiss.get(1)).isEqualTo(mSuggestionsAfterDismiss.get(0));
-    }
-
-    @Test
-    public void testGetSuggestions_withSmartSuggestions() {
-        readAndDismissSuggestion(true);
-        assertThat(mSuggestionsBeforeDismiss.size()).isEqualTo(2);
-        assertThat(mSuggestionsAfterDismiss.size()).isEqualTo(2);
-        assertThat(mSuggestionsBeforeDismiss).isEqualTo(mSuggestionsAfterDismiss);
-    }
-
-    private void readAndDismissSuggestion(boolean isSmartSuggestionEnabled) {
-        mSuggestionsBeforeDismiss = new ArrayList<Tile>();
-        mSuggestionsAfterDismiss = new ArrayList<Tile>();
-        mSuggestionParser.readSuggestions(
-            mSuggestioCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled);
-        if (mSuggestionParser.dismissSuggestion(
-            mSuggestionsBeforeDismiss.get(0), isSmartSuggestionEnabled)) {
-            mInfo.remove(0);
-        }
-        mSuggestionParser.readSuggestions(
-            mSuggestioCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled);
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
index 22fd83c..31abecd 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
@@ -19,5 +19,5 @@
 public class TestConfig {
     public static final int SDK_VERSION = 23;
     public static final String MANIFEST_PATH =
-            "frameworks/base/packages/SettingsLib/robotests/AndroidManifest.xml";
+            "frameworks/base/packages/SettingsLib/tests/robotests/AndroidManifest.xml";
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java
new file mode 100644
index 0000000..3b1c3ac
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.settingslib;
+
+
+import android.content.Context;
+
+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 static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class TetherUtilTest {
+
+    @Mock
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void isEntitlementCheckRequired_noConfigManager_returnTrue() {
+        when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)).thenReturn(null);
+
+        assertThat(TetherUtil.isEntitlementCheckRequired(mContext)).isTrue();
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
index e42c35b..0164f80 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
@@ -21,6 +21,12 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.content.res.Resources;
+
 @RunWith(SettingLibRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class UtilsTest {
@@ -54,4 +60,18 @@
             assertThat(percentage).isEqualTo(expectedPercentages[i]);
         }
     }
+
+    @Test
+    public void testStorageManagerDaysToRetainUsesResources() {
+        Resources resources = mock(Resources.class);
+        when(resources.getInteger(
+                        eq(
+                                com.android
+                                        .internal
+                                        .R
+                                        .integer
+                                        .config_storageManagerDaystoRetainDefault)))
+                .thenReturn(60);
+        assertThat(Utils.getDefaultStorageManagerDaysToRetain(resources)).isEqualTo(60);
+    }
 }
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
new file mode 100644
index 0000000..9ac08f9
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -0,0 +1,155 @@
+/*
+ * 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.settingslib.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+
+import com.android.settingslib.R;
+import com.android.settingslib.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, resourceDir =
+        "../../res")
+public class CachedBluetoothDeviceTest {
+    @Mock
+    private LocalBluetoothAdapter mAdapter;
+    @Mock
+    private LocalBluetoothProfileManager mProfileManager;
+    @Mock
+    private HeadsetProfile mHfpProfile;
+    @Mock
+    private A2dpProfile mA2dpProfile;
+    @Mock
+    private PanProfile mPanProfile;
+    @Mock
+    private BluetoothDevice mDevice;
+    private CachedBluetoothDevice mCachedDevice;
+    private Context mContext;
+    private int mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        when(mAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
+        when(mHfpProfile.isProfileReady()).thenReturn(true);
+        when(mA2dpProfile.isProfileReady()).thenReturn(true);
+        when(mPanProfile.isProfileReady()).thenReturn(true);
+        mCachedDevice = spy(
+                new CachedBluetoothDevice(mContext, mAdapter, mProfileManager, mDevice));
+        doAnswer((invocation) -> mBatteryLevel).when(mCachedDevice).getBatteryLevel();
+    }
+
+    /**
+     * Test to verify the current test context object works so that we are not checking null
+     * against null
+     */
+    @Test
+    public void testContextMock() {
+        assertThat(mContext.getString(R.string.bluetooth_connected)).isEqualTo("Connected");
+    }
+
+    @Test
+    public void testGetConnectionSummary_testSingleProfileConnectDisconnect() {
+        // Test without battery level
+        // Set PAN profile to be connected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
+                R.string.bluetooth_connected));
+
+        // Set PAN profile to be disconnected and test connection state summary
+        mCachedDevice.onProfileStateChanged(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);
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
+                R.string.bluetooth_connected_battery_level,
+                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
+
+        // Set PAN profile to be disconnected and test connection state summary
+        mCachedDevice.onProfileStateChanged(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);
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
+                R.string.bluetooth_connected));
+
+        // Set PAN profile to be disconnected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isNull();
+    }
+
+    @Test
+    public void testGetConnectionSummary_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);
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
+                R.string.bluetooth_connected_battery_level,
+                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
+
+        // Disconnect HFP only and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
+                R.string.bluetooth_connected_no_headset_battery_level,
+                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
+
+        // Disconnect A2DP only and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
+                R.string.bluetooth_connected_no_a2dp_battery_level,
+                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
+
+        // Disconnect both HFP and A2DP and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
+                R.string.bluetooth_connected_no_headset_no_a2dp_battery_level,
+                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
+
+        // Disconnect all profiles and test connection state summary
+        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isNull();
+    }
+}
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
new file mode 100644
index 0000000..5856332
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
@@ -0,0 +1,261 @@
+/*
+ * 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.settingslib.core.lifecycle;
+
+import android.content.Context;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+import com.android.settingslib.SettingLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+import com.android.settingslib.core.lifecycle.events.OnAttach;
+import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
+import com.android.settingslib.core.lifecycle.events.OnDestroy;
+import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
+import com.android.settingslib.core.lifecycle.events.OnPause;
+import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
+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 org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ActivityController;
+import org.robolectric.util.FragmentController;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class LifecycleTest {
+
+    public static class TestDialogFragment extends ObservableDialogFragment {
+
+        final TestObserver mFragObserver;
+
+        public TestDialogFragment() {
+            mFragObserver = new TestObserver();
+            mLifecycle.addObserver(mFragObserver);
+        }
+    }
+
+    public static class TestFragment extends ObservableFragment {
+
+        final TestObserver mFragObserver;
+
+        public TestFragment() {
+            mFragObserver = new TestObserver();
+            getLifecycle().addObserver(mFragObserver);
+        }
+    }
+
+    public static class TestActivity extends ObservableActivity {
+
+        final TestObserver mActObserver;
+
+        public TestActivity() {
+            mActObserver = new TestObserver();
+            getLifecycle().addObserver(mActObserver);
+        }
+
+    }
+
+    public static class TestObserver implements LifecycleObserver, OnAttach, OnStart, OnResume,
+            OnPause, OnStop, OnDestroy, OnCreateOptionsMenu, OnPrepareOptionsMenu,
+            OnOptionsItemSelected {
+
+        boolean mOnAttachObserved;
+        boolean mOnAttachHasContext;
+        boolean mOnStartObserved;
+        boolean mOnResumeObserved;
+        boolean mOnPauseObserved;
+        boolean mOnStopObserved;
+        boolean mOnDestroyObserved;
+        boolean mOnCreateOptionsMenuObserved;
+        boolean mOnPrepareOptionsMenuObserved;
+        boolean mOnOptionsItemSelectedObserved;
+
+        @Override
+        public void onAttach(Context context) {
+            mOnAttachObserved = true;
+            mOnAttachHasContext = context != null;
+        }
+
+        @Override
+        public void onStart() {
+            mOnStartObserved = true;
+        }
+
+        @Override
+        public void onPause() {
+            mOnPauseObserved = true;
+        }
+
+        @Override
+        public void onResume() {
+            mOnResumeObserved = true;
+        }
+
+        @Override
+        public void onStop() {
+            mOnStopObserved = true;
+        }
+
+        @Override
+        public void onDestroy() {
+            mOnDestroyObserved = true;
+        }
+
+        @Override
+        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+            mOnCreateOptionsMenuObserved = true;
+        }
+
+        @Override
+        public boolean onOptionsItemSelected(MenuItem menuItem) {
+            mOnOptionsItemSelectedObserved = true;
+            return true;
+        }
+
+        @Override
+        public void onPrepareOptionsMenu(Menu menu) {
+            mOnPrepareOptionsMenuObserved = true;
+        }
+    }
+
+    @Test
+    public void runThroughActivityLifecycles_shouldObserveEverything() {
+        ActivityController<TestActivity> ac = Robolectric.buildActivity(TestActivity.class);
+        TestActivity activity = ac.get();
+
+        ac.start();
+        assertThat(activity.mActObserver.mOnStartObserved).isTrue();
+        ac.resume();
+        assertThat(activity.mActObserver.mOnResumeObserved).isTrue();
+        activity.onCreateOptionsMenu(null);
+        assertThat(activity.mActObserver.mOnCreateOptionsMenuObserved).isTrue();
+        activity.onPrepareOptionsMenu(null);
+        assertThat(activity.mActObserver.mOnPrepareOptionsMenuObserved).isTrue();
+        activity.onOptionsItemSelected(null);
+        assertThat(activity.mActObserver.mOnOptionsItemSelectedObserved).isTrue();
+        ac.pause();
+        assertThat(activity.mActObserver.mOnPauseObserved).isTrue();
+        ac.stop();
+        assertThat(activity.mActObserver.mOnStopObserved).isTrue();
+        ac.destroy();
+        assertThat(activity.mActObserver.mOnDestroyObserved).isTrue();
+    }
+
+    @Test
+    public void runThroughDialogFragmentLifecycles_shouldObserveEverything() {
+        FragmentController<TestDialogFragment> fragmentController =
+                Robolectric.buildFragment(TestDialogFragment.class);
+        TestDialogFragment fragment = fragmentController.get();
+
+        fragmentController.attach().create().start().resume();
+        fragment.onCreateOptionsMenu(null, null);
+        fragment.onPrepareOptionsMenu(null);
+        fragment.onOptionsItemSelected(null);
+        fragmentController.pause().stop().destroy();
+
+        assertThat(fragment.mFragObserver.mOnAttachObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnAttachHasContext).isTrue();
+        assertThat(fragment.mFragObserver.mOnStartObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnResumeObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnPauseObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnStopObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnDestroyObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnCreateOptionsMenuObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnPrepareOptionsMenuObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnOptionsItemSelectedObserved).isTrue();
+    }
+
+    @Test
+    public void runThroughFragmentLifecycles_shouldObserveEverything() {
+        FragmentController<TestFragment> fragmentController =
+                Robolectric.buildFragment(TestFragment.class);
+        TestFragment fragment = fragmentController.get();
+
+        fragmentController.attach().create().start().resume();
+        fragment.onCreateOptionsMenu(null, null);
+        fragment.onPrepareOptionsMenu(null);
+        fragment.onOptionsItemSelected(null);
+        fragmentController.pause().stop().destroy();
+
+        assertThat(fragment.mFragObserver.mOnAttachObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnAttachHasContext).isTrue();
+        assertThat(fragment.mFragObserver.mOnStartObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnResumeObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnPauseObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnStopObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnDestroyObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnCreateOptionsMenuObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnPrepareOptionsMenuObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnOptionsItemSelectedObserved).isTrue();
+    }
+
+    @Test
+    public void addObserverDuringObserve_shoudNotCrash() {
+        Lifecycle lifecycle = new Lifecycle();
+        lifecycle.addObserver(new OnStartObserver(lifecycle));
+        lifecycle.onStart();
+    }
+
+    private static class OptionItemAccepter implements LifecycleObserver, OnOptionsItemSelected {
+        public boolean wasCalled = false;
+
+        @Override
+        public boolean onOptionsItemSelected(MenuItem menuItem) {
+            wasCalled = true;
+            return false;
+        }
+    }
+
+    @Test
+    public void onOptionItemSelectedShortCircuitsIfAnObserverHandlesTheMenuItem() {
+        FragmentController<TestFragment> fragmentController =
+                Robolectric.buildFragment(TestFragment.class);
+        TestFragment fragment = fragmentController.get();
+        OptionItemAccepter accepter = new OptionItemAccepter();
+        fragment.getLifecycle().addObserver(accepter);
+
+        fragmentController.attach().create().start().resume();
+        fragment.onCreateOptionsMenu(null, null);
+        fragment.onPrepareOptionsMenu(null);
+        fragment.onOptionsItemSelected(null);
+        fragmentController.pause().stop().destroy();
+
+        assertThat(accepter.wasCalled).isFalse();
+    }
+
+    private class OnStartObserver implements LifecycleObserver, OnStart {
+
+        private final Lifecycle mLifecycle;
+
+        public OnStartObserver(Lifecycle lifecycle) {
+            mLifecycle = lifecycle;
+        }
+
+        @Override
+        public void onStart() {
+            mLifecycle.addObserver(new LifecycleObserver() {
+            });
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
index 40353e7..9fc8a96 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
@@ -54,13 +54,14 @@
         allKeys.add(CategoryKey.CATEGORY_SOUND);
         allKeys.add(CategoryKey.CATEGORY_STORAGE);
         allKeys.add(CategoryKey.CATEGORY_SECURITY);
+        allKeys.add(CategoryKey.CATEGORY_SECURITY_LOCKSCREEN);
         allKeys.add(CategoryKey.CATEGORY_ACCOUNT);
         allKeys.add(CategoryKey.CATEGORY_SYSTEM);
         allKeys.add(CategoryKey.CATEGORY_SYSTEM_LANGUAGE);
         allKeys.add(CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
         // DO NOT REMOVE ANYTHING ABOVE
 
-        assertThat(allKeys.size()).isEqualTo(13);
+        assertThat(allKeys.size()).isEqualTo(14);
     }
 
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index 8415dc5..0364418 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -16,11 +16,23 @@
 
 package com.android.settingslib.drawer;
 
-import android.app.ActivityManager;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
-import android.content.IContentProvider;
+import static org.mockito.Mockito.when;
+import static org.robolectric.RuntimeEnvironment.application;
+
+import android.app.ActivityManager;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.IContentProvider;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
@@ -37,40 +49,34 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Pair;
+import android.widget.RemoteViews;
 
-import com.android.settingslib.SuggestionParser;
+import com.android.settingslib.R;
 import com.android.settingslib.TestConfig;
-import com.android.settingslib.drawer.TileUtilsTest;
-import static org.mockito.Mockito.atLeastOnce;
+import com.android.settingslib.suggestions.SuggestionParser;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.shadows.ShadowApplication;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.internal.ShadowExtractor;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-import org.mockito.ArgumentCaptor;
-
-
 @RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH,
+        sdk = TestConfig.SDK_VERSION,
+        shadows = {TileUtilsTest.TileUtilsShadowRemoteViews.class})
 public class TileUtilsTest {
 
     @Mock
@@ -94,8 +100,11 @@
         MockitoAnnotations.initMocks(this);
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
         when(mPackageManager.getResourcesForApplication(anyString())).thenReturn(mResources);
-        mContentResolver = spy(RuntimeEnvironment.application.getContentResolver());
+        when(mPackageManager.getApplicationInfo(eq("abc"), anyInt()))
+                .thenReturn(application.getApplicationInfo());
+        mContentResolver = spy(application.getContentResolver());
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
+        when(mContext.getPackageName()).thenReturn("com.android.settings");
     }
 
     @Test
@@ -112,7 +121,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).category).isEqualTo(testCategory);
@@ -133,7 +142,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).key).isEqualTo(keyHint);
@@ -153,7 +162,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.isEmpty()).isTrue();
     }
@@ -176,10 +185,14 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
-        SuggestionParser parser = new SuggestionParser(mContext, null);
+        SuggestionParser parser = new SuggestionParser(
+                mContext,
+                null,
+                Collections.emptyList(),
+                "0,10");
         parser.filterSuggestions(outTiles, 0, false);
         assertThat(outTiles.size()).isEqualTo(0);
     }
@@ -204,8 +217,8 @@
         }), anyInt(), anyInt())).thenReturn(info);
 
         List<DashboardCategory> categoryList = TileUtils.getCategories(
-            mContext, cache, false /* categoryDefinedInManifest */, testAction,
-            TileUtils.SETTING_PKG);
+                mContext, cache, false /* categoryDefinedInManifest */, testAction,
+                TileUtils.SETTING_PKG);
         assertThat(categoryList.get(0).tiles.get(0).category).isEqualTo(testCategory);
     }
 
@@ -221,13 +234,13 @@
         when(mUserManager.getUserProfiles()).thenReturn(userHandleList);
 
         TileUtils.getCategories(
-            mContext, cache, false /* categoryDefinedInManifest */, null /* action */,
-            TileUtils.SETTING_PKG);
+                mContext, cache, false /* categoryDefinedInManifest */, null /* action */,
+                TileUtils.SETTING_PKG);
         verify(mPackageManager, atLeastOnce()).queryIntentActivitiesAsUser(
-            intentCaptor.capture(), anyInt(), anyInt());
+                intentCaptor.capture(), anyInt(), anyInt());
 
         assertThat(intentCaptor.getAllValues().get(0).getPackage())
-            .isEqualTo(TileUtils.SETTING_PKG);
+                .isEqualTo(TileUtils.SETTING_PKG);
     }
 
     @Test
@@ -245,7 +258,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).title).isEqualTo("my title");
@@ -269,10 +282,60 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).title).isEqualTo("my localized title");
+
+        // Icon should be tintable because the tile is not from settings package, and
+        // "forceTintExternalIcon" is set
+        assertThat(outTiles.get(0).isIconTintable).isTrue();
+    }
+
+    @Test
+    public void getTilesForIntent_shouldNotTintIconIfInSettingsPackage() {
+        Intent intent = new Intent();
+        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+        List<Tile> outTiles = new ArrayList<>();
+        List<ResolveInfo> info = new ArrayList<>();
+        ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
+                URI_GET_SUMMARY, null, 123);
+        resolveInfo.activityInfo.packageName = "com.android.settings";
+        resolveInfo.activityInfo.applicationInfo.packageName = "com.android.settings";
+        info.add(resolveInfo);
+
+        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+                .thenReturn(info);
+
+        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+                null /* defaultCategory */, outTiles, false /* usePriority */,
+                false /* checkCategory */, true /* forceTintExternalIcon */);
+
+        assertThat(outTiles.size()).isEqualTo(1);
+        assertThat(outTiles.get(0).isIconTintable).isFalse();
+    }
+
+    @Test
+    public void getTilesForIntent_shouldMarkIconTintableIfMetadataSet() {
+        Intent intent = new Intent();
+        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+        List<Tile> outTiles = new ArrayList<>();
+        List<ResolveInfo> info = new ArrayList<>();
+        ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
+                URI_GET_SUMMARY, null, 123);
+        resolveInfo.activityInfo.metaData
+                .putBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE, true);
+        info.add(resolveInfo);
+
+        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+                .thenReturn(info);
+
+        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+                null /* defaultCategory */, outTiles, false /* usePriority */,
+                false /* checkCategory */, false /* forceTintExternalIcon */);
+
+        assertThat(outTiles.size()).isEqualTo(1);
+        assertThat(outTiles.get(0).isIconTintable).isTrue();
     }
 
     @Test
@@ -291,7 +354,7 @@
         // Case 1: No provider associated with the uri specified.
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).icon.getResId()).isEqualTo(314159);
@@ -309,7 +372,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).icon.getResId()).isEqualTo(314159);
@@ -331,11 +394,115 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
     }
 
+    @Test
+    public void getTilesForIntent_shouldShowRemoteViewIfSpecified() {
+        Intent intent = new Intent();
+        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+        List<Tile> outTiles = new ArrayList<>();
+        List<ResolveInfo> info = new ArrayList<>();
+        ResolveInfo resolveInfo = newInfo(true, null /* category */);
+        resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
+                R.layout.user_preference);
+        info.add(resolveInfo);
+
+        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+                .thenReturn(info);
+
+        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+                null /* defaultCategory */, outTiles, false /* usePriority */,
+                false /* checkCategory */, true /* forceTintExternalIcon */);
+
+        assertThat(outTiles.size()).isEqualTo(1);
+        Tile tile = outTiles.get(0);
+        assertThat(tile.remoteViews).isNotNull();
+        assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
+    }
+
+    @Test
+    public void getTilesForIntent_summaryUriSpecified_shouldOverrideRemoteViewSummary()
+            throws RemoteException {
+        Intent intent = new Intent();
+        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+        List<Tile> outTiles = new ArrayList<>();
+        List<ResolveInfo> info = new ArrayList<>();
+        ResolveInfo resolveInfo = newInfo(true, null /* category */, null,
+                null, URI_GET_SUMMARY);
+        resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
+                R.layout.user_preference);
+        info.add(resolveInfo);
+
+        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+                .thenReturn(info);
+
+        // Mock the content provider interaction.
+        Bundle bundle = new Bundle();
+        bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, "new summary text");
+        when(mIContentProvider.call(anyString(),
+                eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
+                any())).thenReturn(bundle);
+        when(mContentResolver.acquireUnstableProvider(anyString()))
+                .thenReturn(mIContentProvider);
+        when(mContentResolver.acquireUnstableProvider(any(Uri.class)))
+                .thenReturn(mIContentProvider);
+
+        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+                null /* defaultCategory */, outTiles, false /* usePriority */,
+                false /* checkCategory */, true /* forceTintExternalIcon */);
+
+        assertThat(outTiles.size()).isEqualTo(1);
+        Tile tile = outTiles.get(0);
+        assertThat(tile.remoteViews).isNotNull();
+        assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
+        // Make sure the summary TextView got a new text string.
+        TileUtilsShadowRemoteViews shadowRemoteViews =
+                (TileUtilsShadowRemoteViews) ShadowExtractor.extract(tile.remoteViews);
+        assertThat(shadowRemoteViews.overrideViewId).isEqualTo(android.R.id.summary);
+        assertThat(shadowRemoteViews.overrideText).isEqualTo("new summary text");
+    }
+
+    @Test
+    public void getTilesForIntent_providerUnavailable_shouldNotOverrideRemoteViewSummary()
+            throws RemoteException {
+        Intent intent = new Intent();
+        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+        List<Tile> outTiles = new ArrayList<>();
+        List<ResolveInfo> info = new ArrayList<>();
+        ResolveInfo resolveInfo = newInfo(true, null /* category */, null,
+                null, URI_GET_SUMMARY);
+        resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
+                R.layout.user_preference);
+        info.add(resolveInfo);
+
+        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+                .thenReturn(info);
+
+        // Mock the content provider interaction.
+        Bundle bundle = new Bundle();
+        bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, "new summary text");
+        when(mIContentProvider.call(anyString(),
+                eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
+                any())).thenReturn(bundle);
+
+        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+                null /* defaultCategory */, outTiles, false /* usePriority */,
+                false /* checkCategory */, true /* forceTintExternalIcon */);
+
+        assertThat(outTiles.size()).isEqualTo(1);
+        Tile tile = outTiles.get(0);
+        assertThat(tile.remoteViews).isNotNull();
+        assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
+        // Make sure the summary TextView didn't get any text view updates.
+        TileUtilsShadowRemoteViews shadowRemoteViews =
+                (TileUtilsShadowRemoteViews) ShadowExtractor.extract(tile.remoteViews);
+        assertThat(shadowRemoteViews.overrideViewId).isNull();
+        assertThat(shadowRemoteViews.overrideText).isNull();
+    }
+
     public static ResolveInfo newInfo(boolean systemApp, String category) {
         return newInfo(systemApp, category, null);
     }
@@ -370,7 +537,9 @@
         if (summaryUri != null) {
             info.activityInfo.metaData.putString("com.android.settings.summary_uri", summaryUri);
         }
-        if (title != null) {
+        if (titleResId != 0) {
+            info.activityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title);
+        } else if (title != null) {
             info.activityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title);
         }
         if (titleResId != 0) {
@@ -395,4 +564,17 @@
             info.activityInfo.metaData.putString(key, value);
         }
     }
+
+    @Implements(RemoteViews.class)
+    public static class TileUtilsShadowRemoteViews {
+
+        private Integer overrideViewId;
+        private CharSequence overrideText;
+
+        @Implementation
+        public void setTextViewText(int viewId, CharSequence text) {
+            overrideViewId = viewId;
+            overrideText = text;
+        }
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BottomLabelLayoutTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BottomLabelLayoutTest.java
deleted file mode 100644
index ec21723..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BottomLabelLayoutTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *
- */
-
-package com.android.settingslib.graph;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.Space;
-
-import com.android.settingslib.R;
-import com.android.settingslib.TestConfig;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class BottomLabelLayoutTest {
-    private BottomLabelLayout mBottomLabelLayout;
-    private Context mContext;
-    private Space mSpace;
-
-    @Before
-    public void setUp() {
-        mContext = RuntimeEnvironment.application;
-        mBottomLabelLayout = new BottomLabelLayout(mContext, null);
-        mBottomLabelLayout.setOrientation(LinearLayout.HORIZONTAL);
-
-        mSpace = new Space(mContext);
-        mSpace.setId(R.id.spacer);
-        mBottomLabelLayout.addView(mSpace);
-    }
-
-    @Test
-    public void testSetStacked_stackedTrue_layoutVertical() {
-        mBottomLabelLayout.setStacked(true);
-
-        assertThat(mBottomLabelLayout.getOrientation()).isEqualTo(LinearLayout.VERTICAL);
-        assertThat(mSpace.getVisibility()).isEqualTo(View.GONE);
-    }
-
-    @Test
-    public void testSetStacked_stackedFalse_layoutHorizontal() {
-        mBottomLabelLayout.setStacked(false);
-
-        assertThat(mBottomLabelLayout.getOrientation()).isEqualTo(LinearLayout.HORIZONTAL);
-        assertThat(mSpace.getVisibility()).isEqualTo(View.VISIBLE);
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
new file mode 100644
index 0000000..8391136
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
@@ -0,0 +1,238 @@
+/*
+ * 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.settingslib.suggestions;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+
+import com.android.settingslib.SettingLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+import com.android.settingslib.drawer.Tile;
+import com.android.settingslib.drawer.TileUtilsTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.res.ResourceLoader;
+import org.robolectric.res.builder.DefaultPackageManager;
+import org.robolectric.res.builder.RobolectricPackageManager;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SuggestionParserTest {
+
+    private Context mContext;
+    private RobolectricPackageManager mPackageManager;
+    private SuggestionParser mSuggestionParser;
+    private SuggestionCategory mMultipleCategory;
+    private SuggestionCategory mExclusiveCategory;
+    private SuggestionCategory mExpiredExclusiveCategory;
+    private List<Tile> mSuggestionsBeforeDismiss;
+    private List<Tile> mSuggestionsAfterDismiss;
+    private SharedPreferences mPrefs;
+    private Tile mSuggestion;
+
+    @Before
+    public void setUp() {
+        RuntimeEnvironment.setRobolectricPackageManager(
+                new TestPackageManager(RuntimeEnvironment.getAppResourceLoader()));
+        mContext = RuntimeEnvironment.application;
+        mPackageManager = RuntimeEnvironment.getRobolectricPackageManager();
+        mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+        mSuggestion = new Tile();
+        mSuggestion.intent = new Intent("action");
+        mSuggestion.intent.setComponent(new ComponentName("pkg", "cls"));
+        mSuggestion.metaData = new Bundle();
+        mMultipleCategory = new SuggestionCategory();
+        mMultipleCategory.category = "category1";
+        mMultipleCategory.multiple = true;
+        mExclusiveCategory = new SuggestionCategory();
+        mExclusiveCategory.category = "category2";
+        mExclusiveCategory.exclusive = true;
+        mExpiredExclusiveCategory = new SuggestionCategory();
+        mExpiredExclusiveCategory.category = "category3";
+        mExpiredExclusiveCategory.exclusive = true;
+        mExpiredExclusiveCategory.exclusiveExpireDaysInMillis = 0;
+
+        mSuggestionParser = new SuggestionParser(mContext, mPrefs,
+                Arrays.asList(mMultipleCategory, mExclusiveCategory, mExpiredExclusiveCategory),
+                "0,0");
+
+        ResolveInfo info1 = TileUtilsTest.newInfo(true, null);
+        info1.activityInfo.packageName = "pkg";
+        ResolveInfo infoDupe1 = TileUtilsTest.newInfo(true, null);
+        infoDupe1.activityInfo.packageName = "pkg";
+
+        ResolveInfo info2 = TileUtilsTest.newInfo(true, null);
+        info2.activityInfo.packageName = "pkg2";
+        ResolveInfo info3 = TileUtilsTest.newInfo(true, null);
+        info3.activityInfo.packageName = "pkg3";
+        ResolveInfo info4 = TileUtilsTest.newInfo(true, null);
+        info4.activityInfo.packageName = "pkg4";
+
+        Intent intent1 = new Intent(Intent.ACTION_MAIN).addCategory("category1");
+        Intent intent2 = new Intent(Intent.ACTION_MAIN).addCategory("category2");
+        Intent intent3 = new Intent(Intent.ACTION_MAIN).addCategory("category3");
+
+        mPackageManager.addResolveInfoForIntent(intent1, info1);
+        mPackageManager.addResolveInfoForIntent(intent1, info2);
+        mPackageManager.addResolveInfoForIntent(intent1, infoDupe1);
+        mPackageManager.addResolveInfoForIntent(intent2, info3);
+        mPackageManager.addResolveInfoForIntent(intent3, info4);
+    }
+
+    @Test
+    public void testDismissSuggestion_withoutSmartSuggestion() {
+        assertThat(mSuggestionParser.dismissSuggestion(mSuggestion, false)).isTrue();
+    }
+
+    @Test
+    public void testDismissSuggestion_withSmartSuggestion() {
+        assertThat(mSuggestionParser.dismissSuggestion(mSuggestion, true)).isFalse();
+    }
+
+    @Test
+    public void testGetSuggestions_withoutSmartSuggestions() {
+        readAndDismissSuggestion(false);
+        mSuggestionParser.readSuggestions(mMultipleCategory, mSuggestionsAfterDismiss, false);
+        assertThat(mSuggestionsBeforeDismiss).hasSize(2);
+        assertThat(mSuggestionsAfterDismiss).hasSize(1);
+        assertThat(mSuggestionsBeforeDismiss.get(1)).isEqualTo(mSuggestionsAfterDismiss.get(0));
+    }
+
+    @Test
+    public void testGetSuggestions_withSmartSuggestions() {
+        readAndDismissSuggestion(true);
+        assertThat(mSuggestionsBeforeDismiss).hasSize(2);
+        assertThat(mSuggestionsAfterDismiss).hasSize(2);
+        assertThat(mSuggestionsBeforeDismiss).isEqualTo(mSuggestionsAfterDismiss);
+    }
+
+    @Test
+    public void testGetSuggestion_exclusiveNotAvailable_onlyRegularCategoryAndNoDupe() {
+        mPackageManager.removeResolveInfosForIntent(
+                new Intent(Intent.ACTION_MAIN).addCategory("category2"),
+                "pkg3");
+        mPackageManager.removeResolveInfosForIntent(
+                new Intent(Intent.ACTION_MAIN).addCategory("category3"),
+                "pkg4");
+
+        // If exclusive item is not available, the other categories should be shown
+        final SuggestionList sl =
+                mSuggestionParser.getSuggestions(false /* isSmartSuggestionEnabled */);
+        final List<Tile> suggestions = sl.getSuggestions();
+        assertThat(suggestions).hasSize(2);
+
+        assertThat(suggestions.get(0).intent.getComponent().getPackageName()).isEqualTo("pkg");
+        assertThat(suggestions.get(1).intent.getComponent().getPackageName()).isEqualTo("pkg2");
+    }
+
+    @Test
+    public void testGetSuggestion_exclusiveExpiredAvailable_shouldLoadWithRegularCategory() {
+        // First remove permanent exclusive
+        mPackageManager.removeResolveInfosForIntent(
+                new Intent(Intent.ACTION_MAIN).addCategory("category2"),
+                "pkg3");
+        // Set the other exclusive to be expired.
+        mPrefs.edit()
+                .putLong(mExpiredExclusiveCategory.category + "_setup_time",
+                        System.currentTimeMillis() - 1000)
+                .commit();
+
+        // If exclusive is expired, they should be shown together with the other categories
+        final SuggestionList sl =
+                mSuggestionParser.getSuggestions(true /* isSmartSuggestionEnabled */);
+        final List<Tile> suggestions = sl.getSuggestions();
+
+        assertThat(suggestions).hasSize(3);
+
+        final List<Tile> category1Suggestions = sl.getSuggestionForCategory("category1");
+        final List<Tile> category3Suggestions = sl.getSuggestionForCategory("category3");
+
+        assertThat(category1Suggestions).hasSize(2);
+        assertThat(category3Suggestions).hasSize(1);
+    }
+
+    @Test
+    public void testGetSuggestions_exclusive() {
+        final SuggestionList sl =
+                mSuggestionParser.getSuggestions(false /* isSmartSuggestionEnabled */);
+        final List<Tile> suggestions = sl.getSuggestions();
+
+        assertThat(suggestions).hasSize(1);
+        assertThat(sl.getSuggestionForCategory("category2")).hasSize(1);
+    }
+
+    @Test
+    public void isSuggestionDismissed_mismatchRule_shouldDismiss() {
+        final Tile suggestion = new Tile();
+        suggestion.metaData = new Bundle();
+        suggestion.metaData.putString(SuggestionParser.META_DATA_DISMISS_CONTROL, "1,2,3");
+        suggestion.intent = new Intent().setComponent(new ComponentName("pkg", "cls"));
+
+        // Dismiss suggestion when smart suggestion is not enabled.
+        mSuggestionParser.dismissSuggestion(suggestion, false /* isSmartSuggestionEnabled */);
+        final String suggestionKey = suggestion.intent.getComponent().flattenToShortString();
+        // And point to last rule in dismiss control
+        mPrefs.edit().putInt(suggestionKey + SuggestionParser.DISMISS_INDEX, 2).apply();
+
+        // Turn on smart suggestion, and check if suggestion is enabled.
+        assertThat(mSuggestionParser.isDismissed(suggestion, true /* isSmartSuggestionEnabled */))
+                .isTrue();
+    }
+
+    private void readAndDismissSuggestion(boolean isSmartSuggestionEnabled) {
+        mSuggestionsBeforeDismiss = new ArrayList<>();
+        mSuggestionsAfterDismiss = new ArrayList<>();
+        mSuggestionParser.readSuggestions(
+                mMultipleCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled);
+
+        final Tile suggestion = mSuggestionsBeforeDismiss.get(0);
+        if (mSuggestionParser.dismissSuggestion(suggestion, isSmartSuggestionEnabled)) {
+            RuntimeEnvironment.getRobolectricPackageManager().removeResolveInfosForIntent(
+                    new Intent(Intent.ACTION_MAIN).addCategory(mMultipleCategory.category),
+                    suggestion.intent.getComponent().getPackageName());
+        }
+        mSuggestionParser.readSuggestions(
+                mMultipleCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled);
+    }
+
+    private static class TestPackageManager extends DefaultPackageManager {
+
+        TestPackageManager(ResourceLoader appResourceLoader) {
+            super(appResourceLoader);
+        }
+
+        @Override
+        public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
+            return super.queryIntentActivities(intent, flags);
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/ThreadUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/ThreadUtilsTest.java
new file mode 100644
index 0000000..425d162
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/ThreadUtilsTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.settingslib.utils;
+
+
+import com.android.settingslib.TestConfig;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class ThreadUtilsTest {
+
+    @Test
+    public void testMainThread() throws InterruptedException {
+        assertThat(ThreadUtils.isMainThread()).isTrue();
+        Thread background = new Thread(new Runnable() {
+            public void run() {
+                assertThat(ThreadUtils.isMainThread()).isFalse();
+            }
+        });
+        background.start();
+        background.join();
+    }
+
+    @Test
+    public void testEnsureMainThread() throws InterruptedException {
+        ThreadUtils.ensureMainThread();
+        Thread background = new Thread(new Runnable() {
+            public void run() {
+                try {
+                    ThreadUtils.ensureMainThread();
+                    fail("Should not pass ensureMainThread in a background thread");
+                } catch (RuntimeException e) {
+                }
+            }
+        });
+        background.start();
+        background.join();
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceMixinTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceMixinTest.java
new file mode 100644
index 0000000..ded1574
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceMixinTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.settingslib.widget;
+
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.PreferenceManager;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settingslib.SettingLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+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.shadows.ShadowApplication;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class FooterPreferenceMixinTest {
+
+    @Mock
+    private PreferenceFragment mFragment;
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private Lifecycle mLifecycle;
+    private FooterPreferenceMixin mMixin;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mLifecycle = new Lifecycle();
+        when(mFragment.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
+        when(mFragment.getPreferenceManager().getContext())
+                .thenReturn(ShadowApplication.getInstance().getApplicationContext());
+        mMixin = new FooterPreferenceMixin(mFragment, mLifecycle);
+    }
+
+    @Test
+    public void createFooter_screenNotAvailable_noCrash() {
+        assertThat(mMixin.createFooterPreference()).isNotNull();
+    }
+
+    @Test
+    public void createFooter_screenAvailable_canAttachToScreen() {
+        when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
+
+        final FooterPreference preference = mMixin.createFooterPreference();
+
+        assertThat(preference).isNotNull();
+        verify(mScreen).addPreference(preference);
+    }
+
+    @Test
+    public void createFooter_screenAvailableDelayed_canAttachToScreen() {
+        final FooterPreference preference = mMixin.createFooterPreference();
+
+        mLifecycle.setPreferenceScreen(mScreen);
+
+        assertThat(preference).isNotNull();
+        verify(mScreen).addPreference(preference);
+    }
+
+    @Test
+    public void createFooterTwice_screenAvailable_replaceOldFooter() {
+        when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
+
+        mMixin.createFooterPreference();
+        mMixin.createFooterPreference();
+
+        verify(mScreen).removePreference(any(FooterPreference.class));
+        verify(mScreen, times(2)).addPreference(any(FooterPreference.class));
+    }
+
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
new file mode 100644
index 0000000..17b3de0
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.settingslib.widget;
+
+import android.content.Context;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.text.method.LinkMovementMethod;
+import android.view.LayoutInflater;
+import android.widget.TextView;
+
+import com.android.settingslib.R;
+import com.android.settingslib.SettingLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class FooterPreferenceTest {
+
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = ShadowApplication.getInstance().getApplicationContext();
+    }
+
+    @Test
+    public void createNewPreference_shouldSetKeyAndOrder() {
+        final FooterPreference preference = new FooterPreference(mContext);
+
+        assertThat(preference.getKey()).isEqualTo(FooterPreference.KEY_FOOTER);
+        assertThat(preference.getOrder()).isEqualTo(FooterPreference.ORDER_FOOTER);
+    }
+
+    @Test
+    public void bindPreference_shouldLinkifyContent() {
+        final FooterPreference preference = new FooterPreference(mContext);
+        final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+                LayoutInflater.from(mContext).inflate(R.layout.preference_footer, null));
+
+        preference.onBindViewHolder(holder);
+        assertThat(((TextView) holder.findViewById(android.R.id.title)).getMovementMethod())
+                .isInstanceOf(LinkMovementMethod.class);
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java
new file mode 100644
index 0000000..335653b
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import com.android.settingslib.SettingLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AccessPointPreferenceTest {
+
+    private Context mContext = RuntimeEnvironment.application;
+
+    @Test
+    public void generatePreferenceKey_shouldReturnSsidPlusSecurity() {
+        String ssid = "ssid";
+        int security = AccessPoint.SECURITY_WEP;
+        String expectedKey = ssid + ',' + security;
+
+        TestAccessPointBuilder builder = new TestAccessPointBuilder(mContext);
+        builder.setSsid(ssid).setSecurity(security);
+
+        assertThat(AccessPointPreference.generatePreferenceKey(builder.build()))
+                .isEqualTo(expectedKey);
+    }
+
+    @Test
+    public void generatePreferenceKey_shouldReturnBssidPlusSecurity() {
+        String bssid = "bssid";
+        int security = AccessPoint.SECURITY_WEP;
+        String expectedKey = bssid + ',' + security;
+
+        TestAccessPointBuilder builder = new TestAccessPointBuilder(mContext);
+        builder.setBssid(bssid).setSecurity(security);
+
+        assertThat(AccessPointPreference.generatePreferenceKey(builder.build()))
+                .isEqualTo(expectedKey);
+    }
+}
diff --git a/packages/SettingsProvider/res/values-bn/strings.xml b/packages/SettingsProvider/res/values-bn/strings.xml
index 95cb73a..7e72dfb 100644
--- a/packages/SettingsProvider/res/values-bn/strings.xml
+++ b/packages/SettingsProvider/res/values-bn/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="app_label" msgid="4567566098528588863">"সেটিংস সঞ্চয়স্থান"</string>
+    <string name="app_label" msgid="4567566098528588863">"সেটিংস স্টোরেজ"</string>
 </resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index b777d41..27d461b 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -45,8 +45,8 @@
 
 import com.android.ims.ImsConfig;
 import com.android.internal.content.PackageHelper;
+import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.util.XmlUtils;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.LockPatternView;
@@ -1836,20 +1836,10 @@
         }
 
         if (upgradeVersion < 116) {
-            if (mUserHandle == UserHandle.USER_SYSTEM) {
-                db.beginTransaction();
-                SQLiteStatement stmt = null;
-                try {
-                    stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
-                            + " VALUES(?,?);");
-                    loadSetting(stmt, Settings.Global.ENHANCED_4G_MODE_ENABLED,
-                            ImsConfig.FeatureValueConstants.ON);
-                    db.setTransactionSuccessful();
-                } finally {
-                    db.endTransaction();
-                    if (stmt != null) stmt.close();
-                }
-            }
+            /*
+             * To control the default value by carrier config manager, initializing
+             * ENHANCED_4G_MODE_ENABLED has been removed.
+             */
             upgradeVersion = 116;
         }
 
@@ -2617,9 +2607,9 @@
             loadSetting(stmt, Settings.Global.PREFERRED_NETWORK_MODE, type);
 
             // Set the preferred cdma subscription source to target desired value or default
-            // value defined in CdmaSubscriptionSourceManager
+            // value defined in Phone
             type = SystemProperties.getInt("ro.telephony.default_cdma_sub",
-                        CdmaSubscriptionSourceManager.PREFERRED_CDMA_SUBSCRIPTION);
+                        Phone.PREFERRED_CDMA_SUBSCRIPTION);
             loadSetting(stmt, Settings.Global.CDMA_SUBSCRIPTION_MODE, type);
 
             loadIntegerSetting(stmt, Settings.Global.LOW_BATTERY_SOUND_TIMEOUT,
@@ -2633,9 +2623,6 @@
 
             loadSetting(stmt, Settings.Global.DEVICE_NAME, getDefaultDeviceName());
 
-            loadSetting(stmt, Settings.Global.ENHANCED_4G_MODE_ENABLED,
-                    ImsConfig.FeatureValueConstants.ON);
-
             /*
              * IMPORTANT: Do not add any more upgrade steps here as the global,
              * secure, and system settings are no longer stored in a database
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 920df2e..f8701c4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -16,6 +16,7 @@
 
 package com.android.providers.settings;
 
+import android.annotation.UserIdInt;
 import android.app.backup.BackupAgentHelper;
 import android.app.backup.BackupDataInput;
 import android.app.backup.BackupDataOutput;
@@ -133,6 +134,10 @@
     // Keys within the lock settings section
     private static final String KEY_LOCK_SETTINGS_OWNER_INFO_ENABLED = "owner_info_enabled";
     private static final String KEY_LOCK_SETTINGS_OWNER_INFO = "owner_info";
+    private static final String KEY_LOCK_SETTINGS_VISIBLE_PATTERN_ENABLED =
+            "visible_pattern_enabled";
+    private static final String KEY_LOCK_SETTINGS_POWER_BUTTON_INSTANTLY_LOCKS =
+            "power_button_instantly_locks";
 
     // Name of the temporary file we use during full backup/restore.  This is
     // stored in the full-backup tarfile as well, so should not be changed.
@@ -142,6 +147,10 @@
 
     private WifiManager mWifiManager;
 
+    // Version of the SDK that com.android.providers.settings package has been restored from.
+    // Populated in onRestore().
+    private int mRestoredFromSdkInt;
+
     @Override
     public void onCreate() {
         if (DEBUG_BACKUP) Log.d(TAG, "onCreate() invoked");
@@ -158,7 +167,7 @@
         byte[] systemSettingsData = getSystemSettings();
         byte[] secureSettingsData = getSecureSettings();
         byte[] globalSettingsData = getGlobalSettings();
-        byte[] lockSettingsData   = getLockSettings();
+        byte[] lockSettingsData   = getLockSettings(UserHandle.myUserId());
         byte[] locale = mSettingsHelper.getLocaleData();
         byte[] softApConfigData = getSoftAPConfiguration();
         byte[] netPoliciesData = getNetworkPolicies();
@@ -196,6 +205,9 @@
     public void onRestore(BackupDataInput data, int appVersionCode,
             ParcelFileDescriptor newState) throws IOException {
 
+        // versionCode of com.android.providers.settings corresponds to SDK_INT
+        mRestoredFromSdkInt = appVersionCode;
+
         HashSet<String> movedToGlobal = new HashSet<String>();
         Settings.System.getMovedToGlobalSettings(movedToGlobal);
         Settings.Secure.getMovedToGlobalSettings(movedToGlobal);
@@ -236,7 +248,7 @@
                     break;
 
                 case KEY_LOCK_SETTINGS :
-                    restoreLockSettings(data);
+                    restoreLockSettings(UserHandle.myUserId(), data);
                     break;
 
                 case KEY_SOFTAP_CONFIG :
@@ -275,7 +287,7 @@
         byte[] systemSettingsData = getSystemSettings();
         byte[] secureSettingsData = getSecureSettings();
         byte[] globalSettingsData = getGlobalSettings();
-        byte[] lockSettingsData   = getLockSettings();
+        byte[] lockSettingsData   = getLockSettings(UserHandle.myUserId());
         byte[] locale = mSettingsHelper.getLocaleData();
         byte[] softApConfigData = getSoftAPConfiguration();
         byte[] netPoliciesData = getNetworkPolicies();
@@ -405,7 +417,7 @@
                 if (nBytes > buffer.length) buffer = new byte[nBytes];
                 if (nBytes > 0) {
                     in.readFully(buffer, 0, nBytes);
-                    restoreLockSettings(buffer, nBytes);
+                    restoreLockSettings(UserHandle.myUserId(), buffer, nBytes);
                 }
             }
             // softap config
@@ -531,12 +543,16 @@
     }
 
     /**
-     * Serialize the owner info settings
+     * Serialize the owner info and other lock settings
      */
-    private byte[] getLockSettings() {
+    private byte[] getLockSettings(@UserIdInt int userId) {
         final LockPatternUtils lockPatternUtils = new LockPatternUtils(this);
-        final boolean ownerInfoEnabled = lockPatternUtils.isOwnerInfoEnabled(UserHandle.myUserId());
-        final String ownerInfo = lockPatternUtils.getOwnerInfo(UserHandle.myUserId());
+        final boolean ownerInfoEnabled = lockPatternUtils.isOwnerInfoEnabled(userId);
+        final String ownerInfo = lockPatternUtils.getOwnerInfo(userId);
+        final boolean lockPatternEnabled = lockPatternUtils.isLockPatternEnabled(userId);
+        final boolean visiblePatternEnabled = lockPatternUtils.isVisiblePatternEnabled(userId);
+        final boolean powerButtonInstantlyLocks =
+                lockPatternUtils.getPowerButtonInstantlyLocks(userId);
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream out = new DataOutputStream(baos);
@@ -547,6 +563,14 @@
                 out.writeUTF(KEY_LOCK_SETTINGS_OWNER_INFO);
                 out.writeUTF(ownerInfo != null ? ownerInfo : "");
             }
+            if (lockPatternUtils.isVisiblePatternEverChosen(userId)) {
+                out.writeUTF(KEY_LOCK_SETTINGS_VISIBLE_PATTERN_ENABLED);
+                out.writeUTF(visiblePatternEnabled ? "1" : "0");
+            }
+            if (lockPatternUtils.isPowerButtonInstantlyLocksEverChosen(userId)) {
+                out.writeUTF(KEY_LOCK_SETTINGS_POWER_BUTTON_INSTANTLY_LOCKS);
+                out.writeUTF(powerButtonInstantlyLocks ? "1" : "0");
+            }
             // End marker
             out.writeUTF("");
             out.flush();
@@ -623,7 +647,8 @@
             final Uri destination = (movedToGlobal != null && movedToGlobal.contains(key))
                     ? Settings.Global.CONTENT_URI
                     : contentUri;
-            settingsHelper.restoreValue(this, cr, contentValues, destination, key, value);
+            settingsHelper.restoreValue(this, cr, contentValues, destination, key, value,
+                    mRestoredFromSdkInt);
 
             if (DEBUG) {
                 Log.d(TAG, "Restored setting: " + destination + " : " + key + "=" + value);
@@ -632,12 +657,12 @@
     }
 
     /**
-     * Restores the owner info enabled and owner info settings in LockSettings.
+     * Restores the owner info enabled and other settings in LockSettings.
      *
      * @param buffer
      * @param nBytes
      */
-    private void restoreLockSettings(byte[] buffer, int nBytes) {
+    private void restoreLockSettings(@UserIdInt int userId, byte[] buffer, int nBytes) {
         final LockPatternUtils lockPatternUtils = new LockPatternUtils(this);
 
         ByteArrayInputStream bais = new ByteArrayInputStream(buffer, 0, nBytes);
@@ -652,11 +677,17 @@
                 }
                 switch (key) {
                     case KEY_LOCK_SETTINGS_OWNER_INFO_ENABLED:
-                        lockPatternUtils.setOwnerInfoEnabled("1".equals(value),
-                                UserHandle.myUserId());
+                        lockPatternUtils.setOwnerInfoEnabled("1".equals(value), userId);
                         break;
                     case KEY_LOCK_SETTINGS_OWNER_INFO:
-                        lockPatternUtils.setOwnerInfo(value, UserHandle.myUserId());
+                        lockPatternUtils.setOwnerInfo(value, userId);
+                        break;
+                    case KEY_LOCK_SETTINGS_VISIBLE_PATTERN_ENABLED:
+                        lockPatternUtils.reportPatternWasChosen(userId);
+                        lockPatternUtils.setVisiblePatternEnabled("1".equals(value), userId);
+                        break;
+                    case KEY_LOCK_SETTINGS_POWER_BUTTON_INSTANTLY_LOCKS:
+                        lockPatternUtils.setPowerButtonInstantlyLocks("1".equals(value), userId);
                         break;
                 }
             }
@@ -665,7 +696,7 @@
         }
     }
 
-    private void restoreLockSettings(BackupDataInput data) {
+    private void restoreLockSettings(@UserIdInt int userId, BackupDataInput data) {
         final byte[] settings = new byte[data.getDataSize()];
         try {
             data.readEntityData(settings, 0, settings.length);
@@ -673,7 +704,7 @@
             Log.e(TAG, "Couldn't read entity data");
             return;
         }
-        restoreLockSettings(settings, settings.length);
+        restoreLockSettings(userId, settings, settings.length);
     }
 
     /**
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 1e171d3..344cd8f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -37,10 +37,12 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArraySet;
+import android.util.Slog;
 
 import java.util.Locale;
 
 public class SettingsHelper {
+    private static final String TAG = "SettingsHelper";
     private static final String SILENT_RINGTONE = "_silent";
     private Context mContext;
     private AudioManager mAudioManager;
@@ -110,7 +112,7 @@
      * and in some cases the property value needs to be modified before setting.
      */
     public void restoreValue(Context context, ContentResolver cr, ContentValues contentValues,
-            Uri destination, String name, String value) {
+            Uri destination, String name, String value, int restoredFromSdkInt) {
         // Will we need a post-restore broadcast for this element?
         String oldValue = null;
         boolean sendBroadcast = false;
@@ -167,7 +169,8 @@
                         .setPackage("android").addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
                         .putExtra(Intent.EXTRA_SETTING_NAME, name)
                         .putExtra(Intent.EXTRA_SETTING_NEW_VALUE, value)
-                        .putExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE, oldValue);
+                        .putExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE, oldValue)
+                        .putExtra(Intent.EXTRA_SETTING_RESTORED_FROM_SDK_INT, restoredFromSdkInt);
                 context.sendBroadcastAsUser(intent, UserHandle.SYSTEM, null);
             }
         }
@@ -324,11 +327,17 @@
      */
     void setLocaleData(byte[] data, int size) {
         // Check if locale was set by the user:
-        Configuration conf = mContext.getResources().getConfiguration();
-        // TODO: The following is not working as intended because the network is forcing a locale
-        // change after registering. Need to find some other way to detect if the user manually
-        // changed the locale
-        if (conf.userSetLocale) return; // Don't change if user set it in the SetupWizard
+        final ContentResolver cr = mContext.getContentResolver();
+        final boolean userSetLocale = mContext.getResources().getConfiguration().userSetLocale;
+        final boolean provisioned = Settings.Global.getInt(cr,
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+        if (userSetLocale || provisioned) {
+            // Don't change if user set it in the SetupWizard, or if this is a post-setup
+            // deferred restore operation
+            Slog.i(TAG, "Not applying restored locale; "
+                    + (userSetLocale ? "user already specified" : "device already provisioned"));
+            return;
+        }
 
         final String[] availableLocales = mContext.getAssets().getLocales();
         // Replace "_" with "-" to deal with older backups.
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index b328933..819ee3e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -915,9 +915,6 @@
                 Settings.Global.DEVICE_DEMO_MODE,
                 GlobalSettingsProto.DEVICE_DEMO_MODE);
         dumpSetting(s, p,
-                Settings.Global.RETAIL_DEMO_MODE_CONSTANTS,
-                GlobalSettingsProto.RETAIL_DEMO_MODE_CONSTANTS);
-        dumpSetting(s, p,
                 Settings.Global.DATABASE_DOWNGRADE_REASON,
                 GlobalSettingsProto.DATABASE_DOWNGRADE_REASON);
         dumpSetting(s, p,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index f5d7dd8..d22d0b36 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2597,7 +2597,7 @@
             synchronized (mLock) {
                 final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
                 File globalFile = getSettingsFile(key);
-                if (globalFile.exists()) {
+                if (SettingsState.stateFileExists(globalFile)) {
                     return;
                 }
 
@@ -2634,7 +2634,7 @@
             // Every user has secure settings and if no file we need to migrate.
             final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
             File secureFile = getSettingsFile(secureKey);
-            if (secureFile.exists()) {
+            if (SettingsState.stateFileExists(secureFile)) {
                 return;
             }
 
@@ -2895,7 +2895,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 145;
+            private static final int SETTINGS_VERSION = 146;
 
             private final int mUserId;
 
@@ -3421,22 +3421,11 @@
                 }
 
                 if (currentVersion == 141) {
-                    // Version 142: We added the notion of a default and whether the system set
-                    // the setting. This is used for resetting the internal state and we need
-                    // to make sure this value is updated for the existing settings, otherwise
-                    // we would delete system set settings while they should stay unmodified.
-                    SettingsState globalSettings = getGlobalSettingsLocked();
-                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(globalSettings);
-                    globalSettings.persistSyncLocked();
-
-                    SettingsState secureSettings = getSecureSettingsLocked(mUserId);
-                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(secureSettings);
-                    secureSettings.persistSyncLocked();
-
-                    SettingsState systemSettings = getSystemSettingsLocked(mUserId);
-                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(systemSettings);
-                    systemSettings.persistSyncLocked();
-
+                    // This implementation was incorrectly setting the current value of
+                    // settings changed by non-system packages as the default which default
+                    // is set by the system. We add a new upgrade step at the end to properly
+                    // handle this case which would also fix incorrect changes made by the
+                    // old implementation of this step.
                     currentVersion = 142;
                 }
 
@@ -3496,6 +3485,31 @@
                     currentVersion = 145;
                 }
 
+                if (currentVersion == 145) {
+                    // Version 146: In step 142 we had a bug where incorrectly
+                    // some settings were considered system set and as a result
+                    // made the default and marked as the default being set by
+                    // the system. Here reevaluate the default and default system
+                    // set flags. This would both fix corruption by the old impl
+                    // of step 142 and also properly handle devices which never
+                    // run 142.
+                    if (userId == UserHandle.USER_SYSTEM) {
+                        SettingsState globalSettings = getGlobalSettingsLocked();
+                        ensureLegacyDefaultValueAndSystemSetUpdatedLocked(globalSettings, userId);
+                        globalSettings.persistSyncLocked();
+                    }
+
+                    SettingsState secureSettings = getSecureSettingsLocked(mUserId);
+                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(secureSettings, userId);
+                    secureSettings.persistSyncLocked();
+
+                    SettingsState systemSettings = getSystemSettingsLocked(mUserId);
+                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(systemSettings, userId);
+                    systemSettings.persistSyncLocked();
+
+                    currentVersion = 146;
+                }
+
                 // vXXX: Add new settings above this point.
 
                 if (currentVersion != newVersion) {
@@ -3514,19 +3528,46 @@
             }
         }
 
-        private void ensureLegacyDefaultValueAndSystemSetUpdatedLocked(SettingsState settings) {
+        private void ensureLegacyDefaultValueAndSystemSetUpdatedLocked(SettingsState settings,
+                int userId) {
             List<String> names = settings.getSettingNamesLocked();
             final int nameCount = names.size();
             for (int i = 0; i < nameCount; i++) {
                 String name = names.get(i);
                 Setting setting = settings.getSettingLocked(name);
-                if (setting.getDefaultValue() == null) {
-                    boolean systemSet = SettingsState.isSystemPackage(getContext(),
-                            setting.getPackageName());
+
+                // In the upgrade case we pretend the call is made from the app
+                // that made the last change to the setting to properly determine
+                // whether the call has been made by a system component.
+                int callingUid = -1;
+                try {
+                    callingUid = mPackageManager.getPackageUid(setting.getPackageName(), 0, userId);
+                } catch (RemoteException e) {
+                    /* ignore - handled below */
+                }
+                if (callingUid < 0) {
+                    Slog.e(LOG_TAG, "Unknown package: " + setting.getPackageName());
+                    continue;
+                }
+                try {
+                    final boolean systemSet = SettingsState.isSystemPackage(getContext(),
+                            setting.getPackageName(), callingUid);
                     if (systemSet) {
                         settings.insertSettingLocked(name, setting.getValue(),
                                 setting.getTag(), true, setting.getPackageName());
+                    } else if (setting.getDefaultValue() != null && setting.isDefaultFromSystem()) {
+                        // We had a bug where changes by non-system packages were marked
+                        // as system made and as a result set as the default. Therefore, if
+                        // the package changed the setting last is not a system one but the
+                        // setting is marked as its default coming from the system we clear
+                        // the default and clear the system set flag.
+                        settings.resetSettingDefaultValueLocked(name);
                     }
+                } catch (IllegalStateException e) {
+                    // If the package goes over its quota during the upgrade, don't
+                    // crash but just log the error as the system does the upgrade.
+                    Slog.e(LOG_TAG, "Error upgrading setting: " + setting.getName(), e);
+
                 }
             }
         }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 5f4b239..4151ada 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -298,6 +298,22 @@
     }
 
     // The settings provider must hold its lock when calling here.
+    public void resetSettingDefaultValueLocked(String name) {
+        Setting oldSetting = getSettingLocked(name);
+        if (oldSetting != null && !oldSetting.isNull() && oldSetting.getDefaultValue() != null) {
+            String oldValue = oldSetting.getValue();
+            String oldDefaultValue = oldSetting.getDefaultValue();
+            Setting newSetting = new Setting(name, oldSetting.getValue(), null,
+                    oldSetting.getPackageName(), oldSetting.getTag(), false,
+                    oldSetting.getId());
+            mSettings.put(name, newSetting);
+            updateMemoryUsagePerPackageLocked(newSetting.getPackageName(), oldValue,
+                    newSetting.getValue(), oldDefaultValue, newSetting.getDefaultValue());
+            scheduleWriteIfNeededLocked();
+        }
+    }
+
+    // The settings provider must hold its lock when calling here.
     public boolean insertSettingLocked(String name, String value, String tag,
             boolean makeDefault, String packageName) {
         if (TextUtils.isEmpty(name)) {
@@ -689,17 +705,11 @@
 
     private void readStateSyncLocked() {
         FileInputStream in;
-        if (!mStatePersistFile.exists()) {
-            Slog.i(LOG_TAG, "No settings state " + mStatePersistFile);
-            addHistoricalOperationLocked(HISTORICAL_OPERATION_INITIALIZE, null);
-            return;
-        }
         try {
             in = new AtomicFile(mStatePersistFile).openRead();
         } catch (FileNotFoundException fnfe) {
-            String message = "No settings state " + mStatePersistFile;
-            Slog.wtf(LOG_TAG, message);
-            Slog.i(LOG_TAG, message);
+            Slog.i(LOG_TAG, "No settings state " + mStatePersistFile);
+            addHistoricalOperationLocked(HISTORICAL_OPERATION_INITIALIZE, null);
             return;
         }
         try {
@@ -715,6 +725,16 @@
         }
     }
 
+    /**
+     * Uses AtomicFile to check if the file or its backup exists.
+     * @param file The file to check for existence
+     * @return whether the original or backup exist
+     */
+    public static boolean stateFileExists(File file) {
+        AtomicFile stateFile = new AtomicFile(file);
+        return stateFile.exists();
+    }
+
     private void parseStateLocked(XmlPullParser parser)
             throws IOException, XmlPullParserException {
         final int outerDepth = parser.getDepth();
@@ -1003,6 +1023,10 @@
     }
 
     public static boolean isSystemPackage(Context context, String packageName) {
+        return isSystemPackage(context, packageName, Binder.getCallingUid());
+    }
+
+    public static boolean isSystemPackage(Context context, String packageName, int callingUid) {
         synchronized (sLock) {
             if (SYSTEM_PACKAGE_NAME.equals(packageName)) {
                 return true;
@@ -1015,7 +1039,7 @@
             }
 
             // Native services running as a special UID get a pass
-            final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
+            final int callingAppId = UserHandle.getAppId(callingUid);
             if (callingAppId < FIRST_APPLICATION_UID) {
                 sSystemUids.put(callingAppId, callingAppId);
                 return true;
@@ -1026,7 +1050,7 @@
             // profile for the purpose of determining whether the other end is a
             // system component we need to use the user id of the caller for
             // pulling information about the caller from the package manager.
-            final int callingUserId = UserHandle.getCallingUserId();
+            final int callingUserId = UserHandle.getUserId(callingUid);
 
             final long identity = Binder.clearCallingIdentity();
             try {
diff --git a/packages/SettingsProvider/test/Android.mk b/packages/SettingsProvider/test/Android.mk
index 2673f3d..85e611f 100644
--- a/packages/SettingsProvider/test/Android.mk
+++ b/packages/SettingsProvider/test/Android.mk
@@ -19,4 +19,6 @@
 
 LOCAL_CERTIFICATE := platform
 
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
 include $(BUILD_PACKAGE)
diff --git a/packages/SettingsProvider/test/AndroidTest.xml b/packages/SettingsProvider/test/AndroidTest.xml
new file mode 100644
index 0000000..3a156895
--- /dev/null
+++ b/packages/SettingsProvider/test/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+<configuration description="Run Settings Provider Tests.">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="SettingsProviderTest.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-tag" value="SettingsProviderTest" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.providers.setting.test" />
+        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+    </test>
+</configuration>
diff --git a/packages/Shell/res/values-ar/strings.xml b/packages/Shell/res/values-ar/strings.xml
index 1d64c99..b81a904 100644
--- a/packages/Shell/res/values-ar/strings.xml
+++ b/packages/Shell/res/values-ar/strings.xml
@@ -21,7 +21,7 @@
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"جارٍ إنشاء تقرير الخطأ <xliff:g id="ID">#%d</xliff:g>."</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"تم تسجيل تقرير الخطأ <xliff:g id="ID">#%d</xliff:g>."</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"إضافة تفاصيل إلى تقرير الخطأ"</string>
-    <string name="bugreport_updating_wait" msgid="3322151947853929470">"الرجاء الانتظار…"</string>
+    <string name="bugreport_updating_wait" msgid="3322151947853929470">"يُرجى الانتظار…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"سيظهر تقرير الخطأ على الهاتف بعد قليل"</string>
     <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"اختر لمشاركة تقرير الخطأ"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"انقر لمشاركة تقرير الخطأ."</string>
diff --git a/packages/Shell/res/values-b+sr+Latn/strings.xml b/packages/Shell/res/values-b+sr+Latn/strings.xml
index 5809bfc..805aed6 100644
--- a/packages/Shell/res/values-b+sr+Latn/strings.xml
+++ b/packages/Shell/res/values-b+sr+Latn/strings.xml
@@ -23,7 +23,9 @@
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodaju se detalji u izveštaj o grešci"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Sačekajte..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Izveštaj o grešci će se uskoro pojaviti na telefonu"</string>
+    <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Izaberite da biste delili izveštaj o grešci"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste delili izveštaj o grešci"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Izaberite da biste delili izveštaj o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dodirnite za deljenje izveštaja o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dodirnite za deljenje izveštaja o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
     <string name="bugreport_confirm" msgid="5917407234515812495">"Izveštaji o greškama sadrže podatke iz različitih sistemskih datoteka evidencije, koji obuhvataju lične i privatne podatke (poput korišćenja aplikacija i podataka o lokaciji). Delite izveštaje o greškama samo sa aplikacijama i ljudima u koje imate poverenja."</string>
diff --git a/packages/Shell/res/values-be/strings.xml b/packages/Shell/res/values-be/strings.xml
index f69317c..bea1c30 100644
--- a/packages/Shell/res/values-be/strings.xml
+++ b/packages/Shell/res/values-be/strings.xml
@@ -23,7 +23,9 @@
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Дадаванне падрабязнасцей да справаздачы пра памылкі"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Калі ласка, пачакайце..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Паведамленне пра памылку хутка з\'явіцца на тэлефоне"</string>
+    <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Выберыце, каб абагуліць справаздачу пра памылку"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Дакраніцеся, каб абагуліць сваю справаздачу пра памылку"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Выберыце, каб абагуліць справаздачу пра памылку без здымка экрана, або чакайце атрымання здымка"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Краніце, каб абагуліць справаздачу пра памылку без здымка экрана, або чакайце атрымання здымка."</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Краніце, каб абагуліць справаздачу пра памылку без здымка экрана, або чакайце атрымання здымка."</string>
     <string name="bugreport_confirm" msgid="5917407234515812495">"Справаздачы пра памылкі ўтрымліваюць даныя з розных файлаў журналаў сістэмы, якія могуць уключаць даныя, што вы лічыце канфідэнцыяльнымі (напрыклад, пра выкарыстанне праграм і даныя аб месцазнаходжанні). Абагульвайце справаздачы пра памылкі толькі з тымі людзьмі і праграмамі, якім вы давяраеце."</string>
diff --git a/packages/Shell/res/values-bn/strings.xml b/packages/Shell/res/values-bn/strings.xml
index 07a9df3..56a608d 100644
--- a/packages/Shell/res/values-bn/strings.xml
+++ b/packages/Shell/res/values-bn/strings.xml
@@ -26,8 +26,8 @@
     <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"ত্রুটির প্রতিবেদনটি শেয়ার করতে এটি বেছে নিন"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"আপনার ত্রুটির প্রতিবেদন শেয়ার করতে আলতো চাপ দিন"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"কোনো স্ক্রিনশট ছাড়াই ত্রুটির প্রতিবেদনটি শেয়ার করতে এটি বেছে নিন, বা স্ক্রিনশটের জন্য অপেক্ষা করুন"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"কোনো স্ক্রীনশট ছাড়াই ত্রুটির প্রতিবেদন শেয়ার করতে আলতো চাপ দিন বা সম্পন্ন করতে স্ক্রীনশটের জন্য অপেক্ষা করুন"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"কোনো স্ক্রীনশট ছাড়াই ত্রুটির প্রতিবেদন শেয়ার করতে আলতো চাপ দিন বা সম্পন্ন করতে স্ক্রীনশটের জন্য অপেক্ষা করুন"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"কোনও স্ক্রিনশট ছাড়াই ত্রুটির প্রতিবেদন শেয়ার করতে আলতো চাপ দিন বা সম্পন্ন করতে স্ক্রিনশটের জন্য অপেক্ষা করুন"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"কোনও স্ক্রিনশট ছাড়াই ত্রুটির প্রতিবেদন শেয়ার করতে আলতো চাপ দিন বা সম্পন্ন করতে স্ক্রিনশটের জন্য অপেক্ষা করুন"</string>
     <string name="bugreport_confirm" msgid="5917407234515812495">"ত্রুটির প্রতিবেদনগুলিতে থাকা ডেটা, সিস্টেমের বিভিন্ন লগ ফাইলগুলি থেকে আসে, যাতে আপনার বিবেচনা অনুযায়ী সংবেদনশীল ডেটা (যেমন, অ্যাপ্লিকেশানের ব্যবহার এবং অবস্থান ডেটা) থাকতে পারে৷ আপনি বিশ্বাস করেন শুধুমাত্র এমন অ্যাপ্লিকেশান এবং ব্যক্তিদের সাথেই ত্রুটির প্রতিবেদনগুলিকে শেয়ার করুন৷"</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"আর দেখাবেন না"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"ত্রুটির প্রতিবেদনগুলি"</string>
@@ -35,13 +35,13 @@
     <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"জিপ ফাইলে ত্রুটি প্রতিবেদনের বিশদ বিবরণ যোগ করা যায়নি"</string>
     <string name="bugreport_unnamed" msgid="2800582406842092709">"নামবিহীন"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"বিশদ বিবরণ"</string>
-    <string name="bugreport_screenshot_action" msgid="8677781721940614995">"স্ক্রীনশট"</string>
-    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"স্ক্রীনশট সফলভাবে নেওয়া হয়েছে৷"</string>
-    <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"স্ক্রীনশট নেওয়া যায়নি৷"</string>
+    <string name="bugreport_screenshot_action" msgid="8677781721940614995">"স্ক্রিনশট"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"স্ক্রিনশট সফলভাবে নেওয়া হয়েছে৷"</string>
+    <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"স্ক্রিনশট নেওয়া যায়নি৷"</string>
     <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ত্রুটির প্রতিবেদন <xliff:g id="ID">#%d</xliff:g> এর বিশদ বিবরণ"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"ফাইলের নাম"</string>
     <string name="bugreport_info_title" msgid="2306030793918239804">"ত্রুটির শীর্ষক"</string>
     <string name="bugreport_info_description" msgid="5072835127481627722">"ত্রুটির সারাংশ"</string>
-    <string name="save" msgid="4781509040564835759">"সংরক্ষণ করুন"</string>
+    <string name="save" msgid="4781509040564835759">"সেভ করুন"</string>
     <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"ত্রুটির প্রতিবেদন শেয়ার করুন"</string>
 </resources>
diff --git a/packages/Shell/res/values-bs/strings.xml b/packages/Shell/res/values-bs/strings.xml
index 8815e94..6abcc33 100644
--- a/packages/Shell/res/values-bs/strings.xml
+++ b/packages/Shell/res/values-bs/strings.xml
@@ -23,10 +23,12 @@
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodavanje detalja u izvještaj o greškama"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Pričekajte..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Izvještaj o greškama će se ubrzo pojaviti na ekranu"</string>
+    <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Odaberite da podijelite izvještaj o greškama"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste podijelili izvještaj o grešci"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Odaberite da podijelite izvještaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dodirnite da podijelite izveštaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dodirnite da podijelite izveštaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"Izvještaji o greškama sadrže podatke iz raznih zapisnika sistema koji mogu sadržavati lične i privatne informacije koje smatrate osjetljivima (poput podataka o upotrebi aplikacije ili podataka o lokaciji). Izvještaje o greškama dijelite samo sa aplikacijama i osobama kojima vjerujete."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"Izvještaji o greškama sadrže podatke iz raznih zapisnika sistema koji mogu sadržavati lične i privatne informacije koje smatrate osjetljivima (poput podataka o korištenju aplikacije ili podataka o lokaciji). Izvještaje o greškama dijelite samo sa aplikacijama i osobama kojima vjerujete."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ne prikazuj opet"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Izvještaji o greškama"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Nije moguće pročitati izvještaj o grešci"</string>
diff --git a/packages/Shell/res/values-hi/strings.xml b/packages/Shell/res/values-hi/strings.xml
index 66ad35c..666d254 100644
--- a/packages/Shell/res/values-hi/strings.xml
+++ b/packages/Shell/res/values-hi/strings.xml
@@ -17,31 +17,31 @@
 <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="3701846017049540910">"शेल"</string>
-    <string name="bugreport_notification_channel" msgid="2574150205913861141">"बग रिपोर्ट"</string>
-    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"बग रिपोर्ट <xliff:g id="ID">#%d</xliff:g> जेनरेट की जा रही है"</string>
-    <string name="bugreport_finished_title" msgid="4429132808670114081">"बग रिपोर्ट <xliff:g id="ID">#%d</xliff:g> कैप्चर की गई"</string>
-    <string name="bugreport_updating_title" msgid="4423539949559634214">"बग रिपोर्ट में विवरण जोड़े जा रहे हैं"</string>
+    <string name="bugreport_notification_channel" msgid="2574150205913861141">"गड़बड़ी की रिपोर्ट"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"गड़बड़ी की रिपोर्ट <xliff:g id="ID">#%d</xliff:g> तैयार की जा रही है"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"गड़बड़ी की रिपोर्ट <xliff:g id="ID">#%d</xliff:g> कैप्चर की गई"</string>
+    <string name="bugreport_updating_title" msgid="4423539949559634214">"गड़बड़ी की रिपोर्ट में पूरी जानकारी जोड़ी जा रही है"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"कृपया प्रतीक्षा करें…"</string>
-    <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"बग रिपोर्ट थोड़ी ही देर में फ़ोन पर दिखाई देगी"</string>
-    <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"अपनी बग रिपोर्ट साझा करना चुनें"</string>
-    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"अपनी बग रिपोर्ट साझा करने के लिए टैप करें"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"किसी स्क्रीनशॉट के बिना अपनी बग रिपोर्ट साझा करना चुनें या स्क्रीनशॉट पूरा होने तक इंतज़ार करें"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"अपनी बग रिपोर्ट को बिना स्क्रीनशॉट साझा करने हेतु टैप करें या स्क्रीनशॉट पूरा होने की प्रतीक्षा करें"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"अपनी बग रिपोर्ट को बिना स्क्रीनशॉट साझा करने हेतु टैप करें या स्क्रीनशॉट पूरा होने की प्रतीक्षा करें"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"बग रिपोर्ट में सिस्टम की विभिन्न लॉग फ़ाइलों का डेटा शामिल होता है, जिसमें ऐसा डेटा शामिल हो सकता है जिसे आप संवेदनशील मानते हैं (जैसे कि ऐप्लिकेशन का उपयोग और स्थान डेटा). बग रिपोर्ट केवल अपने विश्वसनीय लोगों और ऐप्लिकेशन से साझा करें."</string>
+    <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"गड़बड़ी की रिपोर्ट थोड़ी ही देर में फ़ोन पर दिखाई देगी"</string>
+    <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"अपनी गड़बड़ी की रिपोर्ट शेयर करने के लिए टैप करें"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"अपनी गड़बड़ी की रिपोर्ट शेयर करने के लिए टैप करें"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"स्क्रीनशॉट के बिना अपनी गड़बड़ी की रिपोर्ट शेयर करना चुनें या स्क्रीनशॉट पूरा होने तक इंतज़ार करें"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"अपनी गड़बड़ी की रिपोर्ट को बिना स्क्रीनशॉट के शेयर करने के लिए टैप करें या स्क्रीनशॉट पूरा होने की इंतज़ार करें"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"अपनी गड़बड़ी की रिपोर्ट को बिना स्क्रीनशॉट के शेयर करने के लिए टैप करें या स्क्रीनशॉट पूरा होने की इंतज़ार करें"</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"गड़बड़ी की रिपोर्ट में सिस्टम की अलग-अलग लॉग फ़ाइलों का डेटा शामिल होता है, जिसमें ऐसा डेटा शामिल हो सकता है जिसे आप संवेदनशील मानते हैं (जैसे कि ऐप्लिकेशन का उपयोग और जगह डेटा). गड़बड़ी की रिपोर्ट केवल अपने भरोसेमंद लोगों और ऐप्लिकेशन से शेयर करें."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"फिर से ना दिखाएं"</string>
-    <string name="bugreport_storage_title" msgid="5332488144740527109">"बग रिपोर्ट"</string>
-    <string name="bugreport_unreadable_text" msgid="586517851044535486">"बग रिपोर्ट फ़ाइल नहीं पढ़ी जा सकी"</string>
-    <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"बग रिपोर्ट को ज़िप फ़ाइल में नहीं जोड़ा जा सका"</string>
+    <string name="bugreport_storage_title" msgid="5332488144740527109">"गड़बड़ी की रिपोर्ट"</string>
+    <string name="bugreport_unreadable_text" msgid="586517851044535486">"गड़बड़ी की रिपोर्ट फ़ाइल नहीं पढ़ी जा सकी"</string>
+    <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"गड़बड़ी की रिपोर्ट को ज़िप फ़ाइल में नहीं जोड़ा जा सका"</string>
     <string name="bugreport_unnamed" msgid="2800582406842092709">"अनामांकित"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"विवरण"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"स्क्रीनशॉट"</string>
     <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"स्क्रीनशॉट सफलतापूर्वक लिया गया."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"स्क्रीनशॉट नहीं लिया जा सका."</string>
-    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"बग रिपोर्ट <xliff:g id="ID">#%d</xliff:g> के विवरण"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"गड़बड़ी की रिपोर्ट <xliff:g id="ID">#%d</xliff:g> की पूरी जानकारी"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"फ़ाइल नाम"</string>
-    <string name="bugreport_info_title" msgid="2306030793918239804">"बग शीर्षक"</string>
-    <string name="bugreport_info_description" msgid="5072835127481627722">"बग सारांश"</string>
-    <string name="save" msgid="4781509040564835759">"सहेजें"</string>
-    <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"बग रिपोर्ट साझा करें"</string>
+    <string name="bugreport_info_title" msgid="2306030793918239804">"गड़बड़ी का शीर्षक"</string>
+    <string name="bugreport_info_description" msgid="5072835127481627722">"गड़बड़ी का सारांश"</string>
+    <string name="save" msgid="4781509040564835759">"सेव करें"</string>
+    <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"गड़बड़ी की रिपोर्ट शेयर करें"</string>
 </resources>
diff --git a/packages/Shell/res/values-iw/strings.xml b/packages/Shell/res/values-iw/strings.xml
index 5accb77..c99e69e 100644
--- a/packages/Shell/res/values-iw/strings.xml
+++ b/packages/Shell/res/values-iw/strings.xml
@@ -42,6 +42,6 @@
     <string name="bugreport_info_name" msgid="4414036021935139527">"שם קובץ"</string>
     <string name="bugreport_info_title" msgid="2306030793918239804">"כותרת הבאג"</string>
     <string name="bugreport_info_description" msgid="5072835127481627722">"סיכום הבאג"</string>
-    <string name="save" msgid="4781509040564835759">"שמור"</string>
+    <string name="save" msgid="4781509040564835759">"שמירה"</string>
     <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"שיתוף דוח על באג"</string>
 </resources>
diff --git a/packages/Shell/res/values-mr/strings.xml b/packages/Shell/res/values-mr/strings.xml
index 7e66436..7cab9d7 100644
--- a/packages/Shell/res/values-mr/strings.xml
+++ b/packages/Shell/res/values-mr/strings.xml
@@ -17,31 +17,31 @@
 <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="3701846017049540910">"शेल"</string>
-    <string name="bugreport_notification_channel" msgid="2574150205913861141">"दोष अहवाल"</string>
-    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"दोष अहवाल <xliff:g id="ID">#%d</xliff:g> तयार केला जात आहे"</string>
-    <string name="bugreport_finished_title" msgid="4429132808670114081">"दोष अहवाल <xliff:g id="ID">#%d</xliff:g> कॅप्चर केला"</string>
+    <string name="bugreport_notification_channel" msgid="2574150205913861141">"बग रीपोर्ट"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"बग रीपोर्ट <xliff:g id="ID">#%d</xliff:g> तयार केला जात आहे"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"बग रीपोर्ट <xliff:g id="ID">#%d</xliff:g> कॅप्चर केला"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"दोष अहवालामध्‍ये तपशील जोडत आहे"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"कृपया प्रतीक्षा करा..."</string>
-    <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"फोनवर दोष अहवाल लवकरच दिसेल"</string>
-    <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"आपला दोष अहवाल शेअर करण्यासाठी निवडा"</string>
-    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"आपला दोष अहवाल सामायिक करण्यासाठी टॅप करा"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"आपला दोष अहवाल स्क्रीनशॉटशिवाय शेअर करण्यासाठी टॅप करा किंवा स्क्रीनशॉट पूर्ण होण्याची प्रतीक्षा करा"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"स्क्रीनशॉट शिवाय आपला दोष अहवाल सामायिक करण्यासाठी टॅप करा किंवा समाप्त करण्यासाठी स्क्रीनशॉटची प्रतीक्षा करा"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"स्क्रीनशॉट शिवाय आपला दोष अहवाल सामायिक करण्यासाठी टॅप करा किंवा समाप्त करण्यासाठी स्क्रीनशॉटची प्रतीक्षा करा"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"दोष अहवालांमध्ये आपण संवेदनशील (अॅप-वापर आणि स्थान डेटा यासारखा) डेटा म्हणून विचार करता त्या डेटाच्या समावेशासह सिस्टीमच्या विविध लॉग फायलींमधील डेटा असतो. ज्या लोकांवर आणि अॅपवर आपला विश्वास आहे केवळ त्यांच्यासह हा दोष अहवाल सामायिक करा."</string>
+    <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"फोनवर बग रीपोर्ट लवकरच दिसेल"</string>
+    <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"आपला बग रीपोर्ट शेअर करण्यासाठी निवडा"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"आपला बग रीपोर्ट शेअर करण्यासाठी टॅप करा"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"आपला बग रीपोर्ट स्क्रीनशॉटशिवाय शेअर करण्यासाठी टॅप करा किंवा स्क्रीनशॉट पूर्ण होण्याची प्रतीक्षा करा"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"स्क्रीनशॉट शिवाय आपला बग रीपोर्ट शेअर करण्यासाठी टॅप करा किंवा समाप्त करण्यासाठी स्क्रीनशॉटची प्रतीक्षा करा"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"स्क्रीनशॉट शिवाय आपला बग रीपोर्ट शेअर करण्यासाठी टॅप करा किंवा समाप्त करण्यासाठी स्क्रीनशॉटची प्रतीक्षा करा"</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"बग रीपोर्टांमध्ये आपण संवेदनशील (अॅप-वापर आणि स्थान डेटा यासारखा) डेटा म्हणून विचार करता त्या डेटाच्या समावेशासह सिस्टीमच्या विविध लॉग फायलींमधील डेटा असतो. ज्या लोकांवर आणि अॅपवर आपला विश्वास आहे केवळ त्यांच्यासह हा बग रीपोर्ट शेअर करा."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"पुन्हा दर्शवू नका"</string>
-    <string name="bugreport_storage_title" msgid="5332488144740527109">"दोष अहवाल"</string>
-    <string name="bugreport_unreadable_text" msgid="586517851044535486">"दोष अहवाल फाईल वाचणे शक्य झाले नाही"</string>
-    <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"झिप फाईल मध्ये दोष अहवाल तपशील जोडणे शक्य झाले नाही"</string>
+    <string name="bugreport_storage_title" msgid="5332488144740527109">"बग रीपोर्ट"</string>
+    <string name="bugreport_unreadable_text" msgid="586517851044535486">"बग रीपोर्ट फाईल वाचणे शक्य झाले नाही"</string>
+    <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"झिप फाईल मध्ये बग रीपोर्ट तपशील जोडणे शक्य झाले नाही"</string>
     <string name="bugreport_unnamed" msgid="2800582406842092709">"अनामित"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"तपशील"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"स्क्रीनशॉट"</string>
     <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"स्क्रीनशॉट यशस्वीरित्या घेतला."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"स्क्रीनशॉट घेणे शक्य झाले नाही."</string>
-    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"दोष अहवाल <xliff:g id="ID">#%d</xliff:g> तपशील"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"बग रीपोर्ट <xliff:g id="ID">#%d</xliff:g> तपशील"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"फाईलनाव"</string>
     <string name="bugreport_info_title" msgid="2306030793918239804">"दोष शीर्षक"</string>
     <string name="bugreport_info_description" msgid="5072835127481627722">"दोष सारांश"</string>
-    <string name="save" msgid="4781509040564835759">"जतन करा"</string>
-    <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"दोष अहवाल सामायिक करा"</string>
+    <string name="save" msgid="4781509040564835759">"सेव्ह करा"</string>
+    <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"बग रीपोर्ट शेअर करा"</string>
 </resources>
diff --git a/packages/Shell/res/values-pa/strings.xml b/packages/Shell/res/values-pa/strings.xml
index 56a2bea..cdf3769 100644
--- a/packages/Shell/res/values-pa/strings.xml
+++ b/packages/Shell/res/values-pa/strings.xml
@@ -22,14 +22,14 @@
     <string name="bugreport_finished_title" msgid="4429132808670114081">"ਬੱਗ ਰਿਪੋਰਟ <xliff:g id="ID">#%d</xliff:g> ਕੈਪਚਰ ਕੀਤੀ ਗਈ"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"ਬੱਗ ਰਿਪੋਰਟ ਵਿੱਚ ਵੇਰਵਿਆਂ ਨੂੰ ਸ਼ਾਮਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"ਕਿਰਪਾ ਕਰਕੇ ਉਡੀਕ ਕਰੋ..."</string>
-    <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"ਬੱਗ ਰਿਪੋਰਟ ਜਲਦ ਹੀ ਫ਼ੋਨ \'ਤੇ ਵਿਖਾਈ ਦੇਵੇਗੀ"</string>
+    <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"ਬੱਗ ਰਿਪੋਰਟ ਜਲਦ ਹੀ ਫ਼ੋਨ \'ਤੇ ਦਿਖਾਈ ਦੇਵੇਗੀ"</string>
     <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"ਆਪਣੀ ਬੱਗ ਰਿਪੋਰਟ ਨੂੰ ਸਾਂਝਾ ਕਰਨ ਲਈ ਚੁਣੋ"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"ਆਪਣੀ ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਦੇ ਬਿਨਾਂ ਆਪਣੀ ਬੱਗ ਰਿਪੋਰਟ ਨੂੰ ਸਾਂਝਾ ਕਰਨ ਲਈ ਚੁਣੋ ਜਾਂ ਸਕ੍ਰੀਨਸ਼ਾਟ ਦੇ ਪੂਰੇ ਹੋਣ ਦੀ ਉਡੀਕ ਕਰੋ"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਦੇ ਬਿਨਾਂ ਆਪਣੀ ਬੱਗ ਰਿਪੋਰਟ ਨੂੰ ਸਾਂਝੀ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ ਜਾਂ ਸਕ੍ਰੀਨਸ਼ਾਟ ਦੇ ਪੂਰੇ ਹੋਣ ਦੀ ਉਡੀਕ ਕਰੋ"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਦੇ ਬਿਨਾਂ ਆਪਣੀ ਬੱਗ ਰਿਪੋਰਟ ਨੂੰ ਸਾਂਝੀ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ ਜਾਂ ਸਕ੍ਰੀਨਸ਼ਾਟ ਦੇ ਪੂਰੇ ਹੋਣ ਦੀ ਉਡੀਕ ਕਰੋ"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"ਬੱਗ ਰਿਪੋਰਟਾਂ ਵਿੱਚ ਸਿਸਟਮ ਦੀਆਂ ਵੱਖ-ਵੱਖ ਲੌਗ ਫ਼ਾਈਲਾਂ ਦਾ ਡੈਟਾ ਸ਼ਾਮਲ ਹੁੰਦਾ ਹੈ, ਜਿਸ ਵਿੱਚ ਉਹ ਡੈਟਾ ਸ਼ਾਮਲ ਹੋ ਸਕਦਾ ਹੈ ਜਿਸ ਨੂੰ ਤੁਸੀਂ ਸੰਵੇਦਨਸ਼ੀਲ ਮੰਨਦੇ ਹੋ (ਜਿਵੇਂ ਕਿ ਐਪ-ਵਰਤੋਂ ਅਤੇ ਟਿਕਾਣਾ ਡੈਟਾ)। ਬੱਗ ਰਿਪੋਰਟਾਂ ਨੂੰ ਸਿਰਫ਼ ਆਪਣੇ ਭਰੋਸੇਯੋਗ ਲੋਕਾਂ ਅਤੇ ਐਪਾਂ ਨਾਲ ਸਾਂਝਾ ਕਰੋ।"</string>
-    <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"ਦੁਬਾਰਾ ਨਾ ਵਿਖਾਓ"</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"ਬੱਗ ਰਿਪੋਰਟਾਂ ਵਿੱਚ ਸਿਸਟਮ ਦੀਆਂ ਵੱਖ-ਵੱਖ ਲੌਗ ਫ਼ਾਈਲਾਂ ਦਾ ਡਾਟਾ ਸ਼ਾਮਲ ਹੁੰਦਾ ਹੈ, ਜਿਸ ਵਿੱਚ ਉਹ ਡਾਟਾ ਸ਼ਾਮਲ ਹੋ ਸਕਦਾ ਹੈ ਜਿਸ ਨੂੰ ਤੁਸੀਂ ਸੰਵੇਦਨਸ਼ੀਲ ਮੰਨਦੇ ਹੋ (ਜਿਵੇਂ ਕਿ ਐਪ-ਵਰਤੋਂ ਅਤੇ ਟਿਕਾਣਾ ਡਾਟਾ)। ਬੱਗ ਰਿਪੋਰਟਾਂ ਨੂੰ ਸਿਰਫ਼ ਆਪਣੇ ਭਰੋਸੇਯੋਗ ਲੋਕਾਂ ਅਤੇ ਐਪਾਂ ਨਾਲ ਸਾਂਝਾ ਕਰੋ।"</string>
+    <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"ਦੁਬਾਰਾ ਨਾ  ਦਿਖਾਓ"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"ਬਗ ਰਿਪੋਰਟਾਂ"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"ਬਗ ਰਿਪੋਰਟ ਫ਼ਾਈਲ ਪੜ੍ਹੀ ਨਹੀਂ ਜਾ ਸਕੀ"</string>
     <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"ਬੱਗ ਰਿਪੋਰਟ ਵੇਰਵਿਆਂ ਨੂੰ ਜ਼ਿਪ ਫ਼ਾਈਲ ਵਿੱਚ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
diff --git a/packages/Shell/res/values-te/strings.xml b/packages/Shell/res/values-te/strings.xml
index dd2d910..bed7367 100644
--- a/packages/Shell/res/values-te/strings.xml
+++ b/packages/Shell/res/values-te/strings.xml
@@ -24,11 +24,11 @@
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"దయచేసి వేచి ఉండండి..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"బగ్ నివేదిక త్వరలో ఫోన్‌లో కనిపిస్తుంది"</string>
     <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"మీ బగ్ నివేదికను భాగస్వామ్యం చేయడానికి ఎంచుకోండి"</string>
-    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"మీ బగ్ నివేదికను భాగస్వామ్యం చేయడానికి నొక్కండి"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"మీ బగ్ నివేదికను షేర్ చేయడానికి నొక్కండి"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"స్క్రీన్‌షాట్ లేకుండా మీ బగ్ నివేదికను భాగస్వామ్యం చేయడానికి ఎంచుకోండి లేదా స్క్రీన్‌షాట్ ముగిసేదాకా వేచి ఉండండి"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"స్క్రీన్‌షాట్ లేకుండా మీ బగ్ నివే. భాగ. చేయడానికి నొక్కండి లేదా స్క్రీన్‌షాట్ ముగిసేదాకా వేచి ఉండండి"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"స్క్రీన్‌షాట్ లేకుండా మీ బగ్ నివే. భాగ. చేయడానికి నొక్కండి లేదా స్క్రీన్‌షాట్ ముగిసేదాకా వేచి ఉండండి"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"బగ్ నివేదికల్లో మీరు గోప్యమైనదిగా పరిగణించే (అనువర్తన వినియోగం మరియు స్థాన డేటా వంటి) డేటాతో సహా సిస్టమ్‌కు సంబంధించిన విభిన్న లాగ్ ఫైల్‌ల డేటా ఉంటుంది. బగ్ నివేదికలను మీరు విశ్వసించే అనువర్తనాలు మరియు వ్యక్తులతో మాత్రమే భాగస్వామ్యం చేయండి."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"బగ్ నివేదికల్లో మీరు గోప్యమైనదిగా పరిగణించే (యాప్ వినియోగం మరియు స్థాన డేటా వంటి) డేటాతో సహా సిస్టమ్‌కు సంబంధించిన విభిన్న లాగ్ ఫైల్‌ల డేటా ఉంటుంది. బగ్ నివేదికలను మీరు విశ్వసించే యాప్‌లు మరియు వ్యక్తులతో మాత్రమే షేర్ చేయండి."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"మళ్లీ చూపవద్దు"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"బగ్ నివేదికలు"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"బగ్ నివేదిక ఫైల్‌ను చదవడం సాధ్యపడలేదు"</string>
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 348b02a..988b986 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -786,14 +786,6 @@
      */
     private void onBugreportFinished(int id, Intent intent) {
         final File bugreportFile = getFileExtra(intent, EXTRA_BUGREPORT);
-        // Since BugreportProvider and BugreportProgressService aren't tightly coupled,
-        // we need to make sure they are explicitly tied to a single unique notification URI
-        // so that the service can alert the provider of changes it has done (ie. new bug
-        // reports)
-        // See { @link Cursor#setNotificationUri } and {@link ContentResolver#notifyChanges }
-        final Uri notificationUri = BugreportStorageProvider.getNotificationUri();
-        mContext.getContentResolver().notifyChange(notificationUri, null, false);
-
         if (bugreportFile == null) {
             // Should never happen, dumpstate always set the file.
             Log.wtf(TAG, "Missing " + EXTRA_BUGREPORT + " on intent " + intent);
diff --git a/packages/Shell/src/com/android/shell/BugreportStorageProvider.java b/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
index b9b77a4..1bb36fb 100644
--- a/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
+++ b/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
@@ -26,22 +26,22 @@
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Root;
-import android.provider.DocumentsProvider;
-import android.webkit.MimeTypeMap;
+
+import com.android.internal.content.FileSystemProvider;
 
 import java.io.File;
 import java.io.FileNotFoundException;
 
-public class BugreportStorageProvider extends DocumentsProvider {
+public class BugreportStorageProvider extends FileSystemProvider {
     private static final String AUTHORITY = "com.android.shell.documents";
     private static final String DOC_ID_ROOT = "bugreport";
 
-    private static final String[] DEFAULT_ROOT_PROJECTION = new String[] {
+    private static final String[] DEFAULT_ROOT_PROJECTION = new String[]{
             Root.COLUMN_ROOT_ID, Root.COLUMN_FLAGS, Root.COLUMN_ICON, Root.COLUMN_TITLE,
             Root.COLUMN_DOCUMENT_ID,
     };
 
-    private static final String[] DEFAULT_DOCUMENT_PROJECTION = new String[] {
+    private static final String[] DEFAULT_DOCUMENT_PROJECTION = new String[]{
             Document.COLUMN_DOCUMENT_ID, Document.COLUMN_MIME_TYPE, Document.COLUMN_DISPLAY_NAME,
             Document.COLUMN_LAST_MODIFIED, Document.COLUMN_FLAGS, Document.COLUMN_SIZE,
     };
@@ -50,6 +50,7 @@
 
     @Override
     public boolean onCreate() {
+        super.onCreate(DEFAULT_DOCUMENT_PROJECTION);
         mRoot = new File(getContext().getFilesDir(), "bugreports");
         return true;
     }
@@ -69,35 +70,13 @@
     @Override
     public Cursor queryDocument(String documentId, String[] projection)
             throws FileNotFoundException {
-        final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
         if (DOC_ID_ROOT.equals(documentId)) {
-            final RowBuilder row = result.newRow();
-            row.add(Document.COLUMN_DOCUMENT_ID, documentId);
-            row.add(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR);
-            row.add(Document.COLUMN_DISPLAY_NAME, mRoot.getName());
-            row.add(Document.COLUMN_LAST_MODIFIED, mRoot.lastModified());
-            row.add(Document.COLUMN_FLAGS, Document.FLAG_DIR_PREFERS_LAST_MODIFIED);
+            final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
+            includeDefaultDocument(result);
+            return result;
         } else {
-            addFileRow(result, getFileForDocId(documentId));
+            return super.queryDocument(documentId, projection);
         }
-        return result;
-    }
-
-    @Override
-    public Cursor queryChildDocuments(
-            String parentDocumentId, String[] projection, String sortOrder)
-            throws FileNotFoundException {
-        final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
-        if (DOC_ID_ROOT.equals(parentDocumentId)) {
-            final File[] files = mRoot.listFiles();
-            if (files != null) {
-                for (File file : files) {
-                    addFileRow(result, file);
-                }
-                result.setNotificationUri(getContext().getContentResolver(), getNotificationUri());
-            }
-        }
-        return result;
     }
 
     @Override
@@ -112,17 +91,8 @@
     }
 
     @Override
-    public void deleteDocument(String documentId) throws FileNotFoundException {
-        if (!getFileForDocId(documentId).delete()) {
-            throw new FileNotFoundException("Failed to delete: " + documentId);
-        }
-        getContext().getContentResolver().notifyChange(getNotificationUri(), null);
-    }
-
-    // This is used by BugreportProgressService so that the notification uri shared by
-    // BugreportProgressService and BugreportStorageProvider are guaranteed the same and unique
-    protected static Uri getNotificationUri() {
-      return DocumentsContract.buildChildDocumentsUri(AUTHORITY, DOC_ID_ROOT);
+    protected Uri buildNotificationUri(String docId) {
+        return DocumentsContract.buildChildDocumentsUri(AUTHORITY, docId);
     }
 
     private static String[] resolveRootProjection(String[] projection) {
@@ -133,45 +103,45 @@
         return projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION;
     }
 
-    private static String getTypeForName(String name) {
-        final int lastDot = name.lastIndexOf('.');
-        if (lastDot >= 0) {
-            final String extension = name.substring(lastDot + 1).toLowerCase();
-            final String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
-            if (mime != null) {
-                return mime;
-            }
-        }
-        return "application/octet-stream";
-    }
-
-    private String getDocIdForFile(File file) {
+    @Override
+    protected String getDocIdForFile(File file) {
         return DOC_ID_ROOT + ":" + file.getName();
     }
 
-    private File getFileForDocId(String documentId) throws FileNotFoundException {
-        final int splitIndex = documentId.indexOf(':', 1);
-        final String name = documentId.substring(splitIndex + 1);
-        if (splitIndex == -1 || !DOC_ID_ROOT.equals(documentId.substring(0, splitIndex)) ||
-                !FileUtils.isValidExtFilename(name)) {
-            throw new FileNotFoundException("Invalid document ID: " + documentId);
+    @Override
+    protected File getFileForDocId(String documentId, boolean visible)
+            throws FileNotFoundException {
+        if (DOC_ID_ROOT.equals(documentId)) {
+            return mRoot;
+        } else {
+            final int splitIndex = documentId.indexOf(':', 1);
+            final String name = documentId.substring(splitIndex + 1);
+            if (splitIndex == -1 || !DOC_ID_ROOT.equals(documentId.substring(0, splitIndex)) ||
+                    !FileUtils.isValidExtFilename(name)) {
+                throw new FileNotFoundException("Invalid document ID: " + documentId);
+            }
+            final File file = new File(mRoot, name);
+            if (!file.exists()) {
+                throw new FileNotFoundException("File not found: " + documentId);
+            }
+            return file;
         }
-        final File file = new File(mRoot, name);
-        if (!file.exists()) {
-            throw new FileNotFoundException("File not found: " + documentId);
-        }
-        return file;
     }
 
-    private void addFileRow(MatrixCursor result, File file) {
-        String mimeType = getTypeForName(file.getName());
-        int flags = Document.FLAG_SUPPORTS_DELETE;
+    @Override
+    protected RowBuilder includeFile(MatrixCursor result, String docId, File file)
+            throws FileNotFoundException {
+        RowBuilder row = super.includeFile(result, docId, file);
+        row.add(Document.COLUMN_FLAGS, Document.FLAG_SUPPORTS_DELETE);
+        return row;
+    }
+
+    private void includeDefaultDocument(MatrixCursor result) {
         final RowBuilder row = result.newRow();
-        row.add(Document.COLUMN_DOCUMENT_ID, getDocIdForFile(file));
-        row.add(Document.COLUMN_MIME_TYPE, mimeType);
-        row.add(Document.COLUMN_DISPLAY_NAME, file.getName());
-        row.add(Document.COLUMN_LAST_MODIFIED, file.lastModified());
-        row.add(Document.COLUMN_FLAGS, flags);
-        row.add(Document.COLUMN_SIZE, file.length());
+        row.add(Document.COLUMN_DOCUMENT_ID, DOC_ID_ROOT);
+        row.add(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR);
+        row.add(Document.COLUMN_DISPLAY_NAME, mRoot.getName());
+        row.add(Document.COLUMN_LAST_MODIFIED, mRoot.lastModified());
+        row.add(Document.COLUMN_FLAGS, Document.FLAG_DIR_PREFERS_LAST_MODIFIED);
     }
 }
diff --git a/packages/Shell/src/com/android/shell/Screenshooter.java b/packages/Shell/src/com/android/shell/Screenshooter.java
index 92c5fcc..8e27edf 100644
--- a/packages/Shell/src/com/android/shell/Screenshooter.java
+++ b/packages/Shell/src/com/android/shell/Screenshooter.java
@@ -100,7 +100,7 @@
         // Rotate the screenshot to the current orientation
         if (rotation != ROTATION_FREEZE_0) {
             Bitmap unrotatedScreenShot = Bitmap.createBitmap(displayWidth, displayHeight,
-                    Bitmap.Config.ARGB_8888);
+                    Bitmap.Config.ARGB_8888, screenShot.hasAlpha(), screenShot.getColorSpace());
             Canvas canvas = new Canvas(unrotatedScreenShot);
             canvas.translate(unrotatedScreenShot.getWidth() / 2,
                     unrotatedScreenShot.getHeight() / 2);
diff --git a/packages/Shell/tests/AndroidTest.xml b/packages/Shell/tests/AndroidTest.xml
index ed9cb2b..bd37712c 100644
--- a/packages/Shell/tests/AndroidTest.xml
+++ b/packages/Shell/tests/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="ShellTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.shell.tests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 193c336..86ff8fe 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -22,6 +22,11 @@
         android:sharedUserId="android.uid.systemui"
         coreApp="true">
 
+    <!-- SysUI must be the one to define this permission; its name is
+         referenced by the core OS. -->
+    <permission android:name="android.permission.systemui.IDENTITY"
+        android:protectionLevel="signature" />
+
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@@ -190,6 +195,9 @@
     <!-- to access instant apps -->
     <uses-permission android:name="android.permission.ACCESS_INSTANT_APPS" />
 
+    <!-- to change themes - light or dark -->
+    <uses-permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES" />
+
     <application
         android:name=".SystemUIApplication"
         android:persistent="true"
@@ -200,7 +208,7 @@
         android:icon="@drawable/icon"
         android:process="com.android.systemui"
         android:supportsRtl="true"
-        android:theme="@style/systemui_theme"
+        android:theme="@style/Theme.SystemUI"
         android:defaultToDeviceProtectedStorage="true"
         android:directBootAware="true">
         <!-- Keep theme in sync with SystemUIApplication.onCreate().
diff --git a/packages/SystemUI/docs/demo_mode.md b/packages/SystemUI/docs/demo_mode.md
index 258c76b..6cf7060 100644
--- a/packages/SystemUI/docs/demo_mode.md
+++ b/packages/SystemUI/docs/demo_mode.md
@@ -29,6 +29,7 @@
 ```battery```        |                            |                | Control the battery display
                      | ```level```                |                | Sets the battery level (0 - 100)
                      | ```plugged```              |                | Sets charging state (```true```, ```false```)
+                     | ```powersave```            |                | Sets power save mode (```true```, ```anything else```)
 ```network```        |                            |                | Control the RSSI display
                      | ```airplane```             |                | ```show``` to show icon, any other value to hide
                      | ```fully```                |                | Sets MCS state to fully connected (```true```, ```false```)
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/DozeServicePlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DozeServicePlugin.java
new file mode 100644
index 0000000..3ca5690
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DozeServicePlugin.java
@@ -0,0 +1,21 @@
+package com.android.systemui.plugins;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+@ProvidesInterface(action = DozeServicePlugin.ACTION, version = DozeServicePlugin.VERSION)
+public interface DozeServicePlugin extends Plugin {
+    String ACTION = "com.android.systemui.action.PLUGIN_DOZE";
+    int VERSION = 1;
+
+    public interface RequestDoze {
+        void onRequestShowDoze();
+
+        void onRequestHideDoze();
+    }
+
+    void onDreamingStarted();
+
+    void onDreamingStopped();
+
+    void setDozeRequester(RequestDoze requester);
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
index bb21fb3..1f633da 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
@@ -26,6 +26,8 @@
     int VERSION = 1;
 
     void showGlobalActions(GlobalActionsManager manager);
+    default void showShutdownUi(boolean isReboot, String reason) {
+    }
 
     @ProvidesInterface(version = GlobalActionsManager.VERSION)
     public interface GlobalActionsManager {
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NotificationListenerController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NotificationListenerController.java
new file mode 100644
index 0000000..fac9e98
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NotificationListenerController.java
@@ -0,0 +1,62 @@
+/*
+ * 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.service.notification.NotificationListenerService.RankingMap;
+import android.service.notification.StatusBarNotification;
+
+import com.android.systemui.plugins.NotificationListenerController.NotificationProvider;
+import com.android.systemui.plugins.annotations.DependsOn;
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+@ProvidesInterface(action = NotificationListenerController.ACTION,
+        version = NotificationListenerController.VERSION)
+@DependsOn(target = NotificationProvider.class)
+public interface NotificationListenerController extends Plugin {
+    String ACTION = "com.android.systemui.action.PLUGIN_NOTIFICATION_ASSISTANT";
+    int VERSION = 1;
+
+    void onListenerConnected(NotificationProvider provider);
+
+    default boolean onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
+        return false;
+    }
+    default boolean onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
+        return false;
+    }
+
+    default StatusBarNotification[] getActiveNotifications(
+            StatusBarNotification[] activeNotifications) {
+        return activeNotifications;
+    }
+
+    default RankingMap getCurrentRanking(RankingMap currentRanking) {
+        return currentRanking;
+    }
+
+    @ProvidesInterface(version = NotificationProvider.VERSION)
+    interface NotificationProvider {
+        int VERSION = 1;
+
+        // Methods to get info about current notifications
+        StatusBarNotification[] getActiveNotifications();
+        RankingMap getRankingMap();
+
+        // Methods to notify sysui of changes to notification list.
+        void addNotification(StatusBarNotification sbn);
+        void removeNotification(StatusBarNotification sbn);
+        void updateRanking();
+    }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java
new file mode 100644
index 0000000..925214e
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java
@@ -0,0 +1,92 @@
+/*
+ * 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.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A PluginActivity is an activity that replaces another full activity (e.g. RecentsActivity)
+ * at runtime within the sysui process.
+ */
+@ProvidesInterface(version = PluginActivity.VERSION)
+public abstract class PluginActivity extends Activity implements Plugin {
+
+    public static final int VERSION = 1;
+
+    public static final String ACTION_RECENTS = "com.android.systemui.action.PLUGIN_RECENTS";
+
+    private Context mSysuiContext;
+    private boolean mSettingActionBar;
+
+    @Override
+    public final void onCreate(Context sysuiContext, Context pluginContext) {
+        mSysuiContext = sysuiContext;
+        super.attachBaseContext(pluginContext);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Theme theme = getClass().getDeclaredAnnotation(Theme.class);
+        if (theme != null && theme.value() != 0) {
+            setTheme(theme.value());
+        }
+        mSettingActionBar = true;
+        getActionBar();
+        mSettingActionBar = false;
+    }
+
+    @Override
+    public Resources getResources() {
+        return mSettingActionBar ? mSysuiContext.getResources() : super.getResources();
+    }
+
+    @Override
+    protected void attachBaseContext(Context newBase) {
+        mSysuiContext = newBase;
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    public Context getSysuiContext() {
+        return mSysuiContext;
+    }
+
+    public Context getPluginContext() {
+        return getBaseContext();
+    }
+
+    /**
+     * Since PluginActivities are declared as services instead of activities (since they
+     * are plugins), they can't have a theme attached to them. Instead a PluginActivity
+     * can annotate itself with @Theme to specify the resource of the style it wants
+     * to be themed with.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface Theme {
+        int value();
+    }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java
index 25ce3dd..db2e376 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java
@@ -21,6 +21,11 @@
     public static final int VERSION = 1;
     static DependencyProvider sProvider;
 
+    /**
+     * Allows a plugin to get a hold of static dependencies if they have declared dependence
+     * on their interface. For one-shot plugins this will only work during onCreate and will
+     * not work afterwards.
+     */
     public static <T> T get(Plugin p, Class<T> cls) {
         return sProvider.get(p, cls);
     }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index ed62b71..b4b4e19 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -112,6 +112,7 @@
         public boolean dualTarget = false;
         public boolean isTransient = false;
         public String expandedAccessibilityClassName;
+        public SlashState slash;
 
         public boolean copyTo(State other) {
             if (other == null) throw new IllegalArgumentException();
@@ -126,7 +127,8 @@
                     || !Objects.equals(other.disabledByPolicy, disabledByPolicy)
                     || !Objects.equals(other.state, state)
                     || !Objects.equals(other.isTransient, isTransient)
-                    || !Objects.equals(other.dualTarget, dualTarget);
+                    || !Objects.equals(other.dualTarget, dualTarget)
+                    || !Objects.equals(other.slash, slash);
             other.icon = icon;
             other.label = label;
             other.contentDescription = contentDescription;
@@ -136,6 +138,7 @@
             other.state = state;
             other.dualTarget = dualTarget;
             other.isTransient = isTransient;
+            other.slash = slash != null ? slash.copy() : null;
             return changed;
         }
 
@@ -155,6 +158,7 @@
             sb.append(",dualTarget=").append(dualTarget);
             sb.append(",isTransient=").append(isTransient);
             sb.append(",state=").append(state);
+            sb.append(",slash=\"").append(slash).append("\"");
             return sb.append(']');
         }
 
@@ -252,4 +256,34 @@
         }
     }
 
+    @ProvidesInterface(version = SlashState.VERSION)
+    public static class SlashState {
+        public static final int VERSION = 2;
+
+        public boolean isSlashed;
+        public float rotation;
+
+        @Override
+        public String toString() {
+            return "isSlashed=" + isSlashed + ",rotation=" + rotation;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == null) return false;
+            try {
+                return (((SlashState) o).rotation == rotation)
+                        && (((SlashState) o).isSlashed == isSlashed);
+            } catch (ClassCastException e) {
+                return false;
+            }
+        }
+
+        public SlashState copy() {
+            SlashState state = new SlashState();
+            state.rotation = rotation;
+            state.isSlashed = isSlashed;
+            return state;
+        }
+    }
 }
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 28f78e5..ecc2ff4 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
@@ -15,6 +15,7 @@
 package com.android.systemui.plugins.statusbar;
 
 import android.content.Context;
+import android.service.notification.StatusBarNotification;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -37,7 +38,7 @@
 public interface NotificationMenuRowPlugin extends Plugin {
 
     public static final String ACTION = "com.android.systemui.action.PLUGIN_NOTIFICATION_MENU_ROW";
-    public static final int VERSION = 2;
+    public static final int VERSION = 3;
 
     @ProvidesInterface(version = OnMenuEventListener.VERSION)
     public interface OnMenuEventListener {
@@ -77,7 +78,7 @@
 
     public void setAppName(String appName);
 
-    public void createMenu(ViewGroup parent);
+    public void createMenu(ViewGroup parent, StatusBarNotification sbn);
 
     public View getMenuView();
 
@@ -89,10 +90,14 @@
 
     public void onHeightUpdate();
 
-    public void onNotificationUpdated();
+    public void onNotificationUpdated(StatusBarNotification sbn);
 
     public boolean onTouchEvent(View view, MotionEvent ev, float velocity);
 
+    public default boolean onInterceptTouchEvent(View view, MotionEvent ev) {
+        return false;
+    }
+
     public default boolean useDefaultMenuItems() {
         return false;
     }
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 3cd5d89..f6cf035 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
@@ -22,6 +22,7 @@
 import android.service.notification.StatusBarNotification;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 
 @ProvidesInterface(version = NotificationSwipeActionHelper.VERSION)
 @DependsOn(target = SnoozeOption.class)
@@ -56,19 +57,17 @@
     public boolean swipedFastEnough(float translation, float velocity);
 
     @ProvidesInterface(version = SnoozeOption.VERSION)
-    public static class SnoozeOption {
-        public static final int VERSION = 1;
-        public int snoozeForMinutes;
-        public SnoozeCriterion criterion;
-        public CharSequence description;
-        public CharSequence confirmation;
+    public interface SnoozeOption {
+        public static final int VERSION = 2;
 
-        public SnoozeOption(SnoozeCriterion crit, int minsToSnoozeFor, CharSequence desc,
-                CharSequence confirm) {
-            criterion = crit;
-            snoozeForMinutes = minsToSnoozeFor;
-            description = desc;
-            confirmation = confirm;
-        }
+        public SnoozeCriterion getSnoozeCriterion();
+
+        public CharSequence getDescription();
+
+        public CharSequence getConfirmation();
+
+        public int getMinutesToSnoozeFor();
+
+        public AccessibilityAction getAccessibilityAction();
     }
 }
diff --git a/packages/SystemUI/res-keyguard/drawable-hdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-hdpi/ic_done_wht.png
deleted file mode 100644
index 82c01ef..0000000
--- a/packages/SystemUI/res-keyguard/drawable-hdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-mdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-mdpi/ic_done_wht.png
deleted file mode 100644
index 8c16930..0000000
--- a/packages/SystemUI/res-keyguard/drawable-mdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xhdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-xhdpi/ic_done_wht.png
deleted file mode 100644
index 6a4d8a7..0000000
--- a/packages/SystemUI/res-keyguard/drawable-xhdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxhdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-xxhdpi/ic_done_wht.png
deleted file mode 100644
index 4c04ba2..0000000
--- a/packages/SystemUI/res-keyguard/drawable-xxhdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/ic_done_wht.png
deleted file mode 100644
index bd6c4df..0000000
--- a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_access_alarms_big.xml b/packages/SystemUI/res-keyguard/drawable/ic_access_alarms_big.xml
index 84ccb7c..fffa0bd 100644
--- a/packages/SystemUI/res-keyguard/drawable/ic_access_alarms_big.xml
+++ b/packages/SystemUI/res-keyguard/drawable/ic_access_alarms_big.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -18,8 +18,7 @@
     android:height="18dp"
     android:viewportWidth="24.0"
     android:viewportHeight="24.0">
-
     <path
-        android:fillColor="@color/clock_gray"
-        android:pathData="M22.0,5.7l-4.6,-3.9l-1.3,1.5l4.6,3.9L22.0,5.7zM7.9,3.4L6.6,1.9L2.0,5.7l1.3,1.5L7.9,3.4zM12.5,8.0L11.0,8.0l0.0,6.0l4.7,2.9l0.8,-1.2l-4.0,-2.4L12.5,8.0zM12.0,4.0c-5.0,0.0 -9.0,4.0 -9.0,9.0c0.0,5.0 4.0,9.0 9.0,9.0s9.0,-4.0 9.0,-9.0C21.0,8.0 17.0,4.0 12.0,4.0zM12.0,20.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.9 3.1,-7.0 7.0,-7.0c3.9,0.0 7.0,3.1 7.0,7.0C19.0,16.9 15.9,20.0 12.0,20.0z"/>
+        android:fillColor="@android:color/white"
+        android:pathData="M21.35,6.49c-0.35,0.42 -0.98,0.47 -1.4,0.12l-3.07,-2.57a1,1 0,1 1,1.29 -1.53l3.07,2.57c0.42,0.35 0.47,0.98 0.11,1.41zM7.24,2.63a1,1 0,0 0,-1.41 -0.13L2.77,5.07A0.996,0.996 0,1 0,4.05 6.6l3.06,-2.57c0.43,-0.35 0.48,-0.98 0.13,-1.4zM11.75,8c-0.41,0 -0.75,0.34 -0.75,0.75v4.68c0,0.35 0.18,0.68 0.49,0.86l3.65,2.19c0.34,0.2 0.78,0.1 0.98,-0.24a0.71,0.71 0,0 0,-0.25 -0.99l-3.37,-2v-4.5c0,-0.41 -0.34,-0.75 -0.75,-0.75zM12,5.9c-3.91,0 -7.1,3.18 -7.1,7.1s3.19,7.1 7.1,7.1 7.1,-3.18 7.1,-7.1 -3.19,-7.1 -7.1,-7.1M12,4a9,9 0,1 1,-0.001 18.001A9,9 0,0 1,12 4z" />
 </vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_backspace_24dp.xml b/packages/SystemUI/res-keyguard/drawable/ic_backspace_24dp.xml
deleted file mode 100644
index 1e4022e..0000000
--- a/packages/SystemUI/res-keyguard/drawable/ic_backspace_24dp.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:autoMirrored="true"
-        android:height="24dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#ffffffff"
-        android:pathData="M44.0,6.0L14.0,6.0c-1.4,0.0 -2.5,0.7 -3.2,1.8L0.0,24.0l10.8,16.2c0.7,1.1 1.8,1.8 3.2,1.8l30.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L48.0,10.0C48.0,7.8 46.2,6.0 44.0,6.0zM38.0,31.2L35.2,34.0L28.0,26.8L20.8,34.0L18.0,31.2l7.2,-7.2L18.0,16.8l2.8,-2.8l7.2,7.2l7.2,-7.2l2.8,2.8L30.8,24.0L38.0,31.2z"/>
-</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_backspace_black_24dp.xml b/packages/SystemUI/res-keyguard/drawable/ic_backspace_black_24dp.xml
new file mode 100644
index 0000000..6edae4b
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_backspace_black_24dp.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright (C) 2017 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M22,3H7C6.31,3 5.77,3.35 5.41,3.88l-5.04,7.57c-0.22,0.34 -0.22,0.77 0,1.11l5.04,7.56C5.77,20.64 6.31,21 7,21h15c1.1,0 2,-0.9 2,-2V5C24,3.9 23.1,3 22,3zM18.3,16.3L18.3,16.3c-0.39,0.39 -1.02,0.39 -1.41,0L14,13.41l-2.89,2.89c-0.39,0.39 -1.02,0.39 -1.41,0h0c-0.39,-0.39 -0.39,-1.02 0,-1.41L12.59,12L9.7,9.11c-0.39,-0.39 -0.39,-1.02 0,-1.41l0,0c0.39,-0.39 1.02,-0.39 1.41,0L14,10.59l2.89,-2.89c0.39,-0.39 1.02,-0.39 1.41,0v0c0.39,0.39 0.39,1.02 0,1.41L15.41,12l2.89,2.89C18.68,15.27 18.68,15.91 18.3,16.3z"/>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_done_black_24dp.xml b/packages/SystemUI/res-keyguard/drawable/ic_done_black_24dp.xml
new file mode 100644
index 0000000..5026f07
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_done_black_24dp.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright (C) 2017 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M9,16.2l-3.5,-3.5a0.984,0.984 0,0 0,-1.4 0,0.984 0.984,0 0,0 0,1.4l4.19,4.19c0.39,0.39 1.02,0.39 1.41,0L20.3,7.7a0.984,0.984 0,0 0,0 -1.4,0.984 0.984,0 0,0 -1.4,0L9,16.2z"/>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/pin_divider.xml b/packages/SystemUI/res-keyguard/drawable/pin_divider.xml
new file mode 100644
index 0000000..39104b5
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/pin_divider.xml
@@ -0,0 +1,20 @@
+<?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
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/pin_divider_color" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
new file mode 100644
index 0000000..8cbd94b
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This contains disable esim buttonas shared by sim_pin/sim_puk screens -->
+<com.android.keyguard.KeyguardEsimArea
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:id="@+id/keyguard_disable_esim"
+    android:visibility="gone"
+    android:text="@string/disable_carrier_button_text"
+    style="?android:attr/buttonBarButtonStyle"
+    android:textAppearance="?android:attr/textAppearanceMedium"
+    android:textSize="@dimen/kg_status_line_font_size"
+    android:textColor="?android:attr/textColorSecondary"
+    android:textAllCaps="@bool/kg_use_all_caps" />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
index 29c93d5..9fdb00e 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
@@ -43,7 +43,7 @@
          android:layout_height="wrap_content"
          android:layout_width="280dp"
          android:layout_gravity="center_horizontal"
-         android:theme="@style/PasswordTheme"
+         android:theme="?attr/passwordStyle"
          >
 
          <EditText android:id="@+id/passwordEntry"
@@ -54,6 +54,7 @@
              android:textStyle="normal"
              android:inputType="textPassword"
              android:textSize="16sp"
+             android:textColor="?attr/wallpaperTextColor"
              android:textAppearance="?android:attr/textAppearanceMedium"
              android:imeOptions="flagForceAscii|actionDone"
              android:maxLength="500"
@@ -67,6 +68,7 @@
              android:contentDescription="@string/accessibility_ime_switch_button"
              android:clickable="true"
              android:padding="8dip"
+             android:tint="@color/background_protected"
              android:layout_gravity="end|center_vertical"
              android:background="?android:attr/selectableItemBackground"
              android:visibility="gone"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
index e75f3c15..631cc0d 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
@@ -53,7 +53,8 @@
                     android:gravity="center"
                     android:layout_centerHorizontal="true"
                     android:layout_marginRight="72dp"
-                    androidprv:scaledTextSize="28"
+                    androidprv:scaledTextSize="@integer/scaled_password_text_size"
+                    android:textColor="?attr/wallpaperTextColor"
                     android:contentDescription="@string/keyguard_accessibility_pin_area"
                     />
             <ImageButton
@@ -61,23 +62,25 @@
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
                     android:gravity="center_vertical"
-                    android:src="@drawable/ic_backspace_24dp"
+                    android:src="@drawable/ic_backspace_black_24dp"
                     android:clickable="true"
                     android:paddingTop="8dip"
                     android:paddingBottom="8dip"
-                    android:paddingRight="8dp"
+                    android:paddingRight="0dp"
                     android:paddingLeft="24dp"
                     android:background="@drawable/ripple_drawable"
                     android:contentDescription="@string/keyboardview_keycode_delete"
                     android:layout_alignEnd="@+id/pinEntry"
                     android:layout_alignParentRight="true"
+                    android:tint="@color/pin_delete_color"
+                    android:tintMode="src_in"
                     />
             <View
                     android:id="@+id/divider"
                     android:layout_width="match_parent"
                     android:layout_height="1dp"
                     android:layout_alignParentBottom="true"
-                    android:background="#28FFFFFF"
+                    android:background="@drawable/pin_divider"
                     />
         </com.android.keyguard.AlphaOptimizedRelativeLayout>
         <LinearLayout
@@ -202,7 +205,8 @@
                     android:layout_height="match_parent"
                     android:layout_weight="1"
                     android:paddingBottom="11sp"
-                    android:src="@drawable/ic_done_wht"
+                    android:src="@drawable/ic_done_black_24dp"
+                    style="@style/Keyguard.ImageButton.NumPadEnter"
                     android:background="@drawable/ripple_drawable"
                     android:contentDescription="@string/keyboardview_keycode_enter"
                     />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
index 920498f..6dea493 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
@@ -41,7 +41,7 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center_horizontal|top"
-                android:textColor="@color/clock_white"
+                android:textColor="?attr/wallpaperTextColor"
                 android:singleLine="true"
                 style="@style/widget_big_thin"
                 android:format12Hour="@string/keyguard_widget_12_hours_format"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
index b0a93e6..97c8965 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
@@ -42,9 +42,16 @@
             android:layout_width="match_parent"
             android:layout_height="0dp"
             android:orientation="vertical"
+            android:gravity="center"
             android:layout_weight="1"
             android:layoutDirection="ltr"
             >
+        <include layout="@layout/keyguard_esim_area"
+             android:id="@+id/keyguard_esim_area"
+             android:layout_width="wrap_content"
+             android:layout_height="wrap_content"
+             android:layout_marginTop="@dimen/eca_overlap" />
+
         <RelativeLayout
                 android:id="@+id/row0"
                 android:layout_width="match_parent"
@@ -59,7 +66,8 @@
                     android:gravity="center"
                     android:layout_centerHorizontal="true"
                     android:layout_marginRight="72dp"
-                    androidprv:scaledTextSize="28"
+                    androidprv:scaledTextSize="@integer/scaled_password_text_size"
+                    android:textColor="?attr/wallpaperTextColor"
                     android:contentDescription="@string/keyguard_accessibility_sim_pin_area"
                     />
             <ImageButton
@@ -67,23 +75,25 @@
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
                     android:gravity="center_vertical"
-                    android:src="@drawable/ic_backspace_24dp"
+                    android:src="@drawable/ic_backspace_black_24dp"
                     android:clickable="true"
                     android:paddingTop="8dip"
                     android:paddingBottom="8dip"
-                    android:paddingRight="8dp"
+                    android:paddingRight="0dp"
                     android:paddingLeft="24dp"
                     android:background="@drawable/ripple_drawable"
                     android:contentDescription="@string/keyboardview_keycode_delete"
                     android:layout_alignEnd="@+id/pinEntry"
                     android:layout_alignParentRight="true"
+                    android:tint="@color/pin_delete_color"
+                    android:tintMode="src_in"
                     />
             <View
                     android:id="@+id/divider"
                     android:layout_width="match_parent"
                     android:layout_height="1dp"
                     android:layout_alignParentBottom="true"
-                    android:background="#28FFFFFF"
+                    android:background="@drawable/pin_divider"
                     />
         </RelativeLayout>
         <LinearLayout
@@ -204,7 +214,8 @@
                     android:layout_height="match_parent"
                     android:layout_weight="1"
                     android:paddingBottom="11sp"
-                    android:src="@drawable/ic_done_wht"
+                    android:src="@drawable/ic_done_black_24dp"
+                    style="@style/Keyguard.ImageButton.NumPadEnter"
                     android:background="@drawable/ripple_drawable"
                     android:contentDescription="@string/keyboardview_keycode_enter"
                     />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
index cf41bd3..d4c5d74 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
@@ -43,9 +43,16 @@
             android:layout_width="match_parent"
             android:layout_height="0dp"
             android:orientation="vertical"
+            android:gravity="center"
             android:layout_weight="1"
             android:layoutDirection="ltr"
             >
+        <include layout="@layout/keyguard_esim_area"
+            android:id="@+id/keyguard_esim_area"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/eca_overlap" />
+
         <RelativeLayout
                 android:id="@+id/row0"
                 android:layout_width="match_parent"
@@ -60,7 +67,8 @@
                     android:gravity="center"
                     android:layout_centerHorizontal="true"
                     android:layout_marginRight="72dp"
-                    androidprv:scaledTextSize="28"
+                    androidprv:scaledTextSize="@integer/scaled_password_text_size"
+                    android:textColor="?attr/wallpaperTextColor"
                     android:contentDescription="@string/keyguard_accessibility_sim_puk_area"
                     />
             <ImageButton
@@ -68,23 +76,25 @@
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
                     android:gravity="center_vertical"
-                    android:src="@drawable/ic_backspace_24dp"
+                    android:src="@drawable/ic_backspace_black_24dp"
                     android:clickable="true"
                     android:paddingTop="8dip"
                     android:paddingBottom="8dip"
-                    android:paddingRight="8dp"
+                    android:paddingRight="0dp"
                     android:paddingLeft="24dp"
                     android:background="@drawable/ripple_drawable"
                     android:contentDescription="@string/keyboardview_keycode_delete"
                     android:layout_alignEnd="@+id/pinEntry"
                     android:layout_alignParentRight="true"
+                    android:tint="@color/pin_delete_color"
+                    android:tintMode="src_in"
                     />
             <View
                     android:id="@+id/divider"
                     android:layout_width="match_parent"
                     android:layout_height="1dp"
                     android:layout_alignParentBottom="true"
-                    android:background="#28FFFFFF"
+                    android:background="@drawable/pin_divider"
                     />
         </RelativeLayout>
         <LinearLayout
@@ -205,7 +215,8 @@
                     android:layout_height="match_parent"
                     android:layout_weight="1"
                     android:paddingBottom="11sp"
-                    android:src="@drawable/ic_done_wht"
+                    android:src="@drawable/ic_done_black_24dp"
+                    style="@style/Keyguard.ImageButton.NumPadEnter"
                     android:background="@drawable/ripple_drawable"
                     android:contentDescription="@string/keyboardview_keycode_enter"
                     />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
index 7e664d0..56fb73f 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
@@ -29,9 +29,9 @@
         android:id="@+id/date_view"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:textColor="@color/clock_white"
+        android:textColor="?attr/wallpaperTextColor"
         style="@style/widget_label"
-        android:letterSpacing="0.15"
+        android:letterSpacing="0.05"
         android:gravity="center"
         />
     <TextView android:id="@+id/alarm_status"
@@ -39,8 +39,10 @@
         android:layout_height="wrap_content"
         android:drawablePadding="6dp"
         android:drawableStart="@drawable/ic_access_alarms_big"
-        android:textColor="@color/clock_gray"
-        android:letterSpacing="0.15"
+        android:drawableTint="?attr/wallpaperTextColorSecondary"
+        android:drawableTintMode="src_in"
+        android:textColor="?attr/wallpaperTextColorSecondary"
+        android:letterSpacing="0.05"
         style="@style/widget_label"
         android:layout_marginStart="6dp"
         android:gravity="center"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index 51adc1e..138733e 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -28,41 +28,46 @@
     androidprv:layout_maxWidth="@dimen/keyguard_security_width"
     androidprv:layout_maxHeight="@dimen/keyguard_security_height"
     android:gravity="center_horizontal|top">
-    <RelativeLayout
-        android:id="@+id/keyguard_clock_container"
+    <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_horizontal|top">
-        <TextClock
-            android:id="@+id/clock_view"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_horizontal"
-            android:layout_centerHorizontal="true"
-            android:layout_alignParentTop="true"
-            android:textColor="@color/clock_white"
-            android:singleLine="true"
-            style="@style/widget_big_thin"
-            android:format12Hour="@string/keyguard_widget_12_hours_format"
-            android:format24Hour="@string/keyguard_widget_24_hours_format"
-            android:layout_marginBottom="@dimen/bottom_text_spacing_digital" />
-        <com.android.systemui.ChargingView
-            android:id="@+id/battery_doze"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignTop="@id/clock_view"
-            android:layout_alignBottom="@id/clock_view"
-            android:layout_toEndOf="@id/clock_view"
-            android:visibility="invisible"
-            android:src="@drawable/ic_aod_charging_24dp"
-            android:contentDescription="@string/accessibility_ambient_display_charging"
-        />
-
-        <include layout="@layout/keyguard_status_area"
-            android:id="@+id/keyguard_status_area"
+        android:orientation="vertical">
+        <RelativeLayout
+            android:id="@+id/keyguard_clock_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_below="@id/clock_view" />
+            android:layout_gravity="center_horizontal|top">
+            <TextClock
+                android:id="@+id/clock_view"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:layout_centerHorizontal="true"
+                android:layout_alignParentTop="true"
+                android:textColor="?attr/wallpaperTextColor"
+                android:singleLine="true"
+                style="@style/widget_big_thin"
+                android:format12Hour="@string/keyguard_widget_12_hours_format"
+                android:format24Hour="@string/keyguard_widget_24_hours_format"
+                android:layout_marginBottom="@dimen/bottom_text_spacing_digital" />
+            <com.android.systemui.ChargingView
+                android:id="@+id/battery_doze"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignTop="@id/clock_view"
+                android:layout_alignBottom="@id/clock_view"
+                android:layout_toEndOf="@id/clock_view"
+                android:visibility="invisible"
+                android:src="@drawable/ic_aod_charging_24dp"
+                android:contentDescription="@string/accessibility_ambient_display_charging"
+            />
+
+            <include layout="@layout/keyguard_status_area"
+                android:id="@+id/keyguard_status_area"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/clock_view" />
+        </RelativeLayout>
 
         <TextView
             android:id="@+id/owner_info"
@@ -71,13 +76,13 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/date_owner_info_margin"
+            android:layout_gravity="center_horizontal"
             android:layout_centerHorizontal="true"
-            android:layout_below="@id/keyguard_status_area"
-            android:textColor="@color/clock_gray"
+            android:textColor="?attr/wallpaperTextColorSecondary"
             android:textSize="@dimen/widget_label_font_size"
             android:letterSpacing="0.05"
             android:ellipsize="marquee"
             android:singleLine="true" />
 
-    </RelativeLayout>
+    </LinearLayout>
 </com.android.keyguard.KeyguardStatusView>
diff --git a/packages/SystemUI/res-keyguard/values-af/strings.xml b/packages/SystemUI/res-keyguard/values-af/strings.xml
index ac4dfc8..1662bc8 100644
--- a/packages/SystemUI/res-keyguard/values-af/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-af/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Voer wagwoord in om te ontsluit"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Tik PIN in om te ontsluit"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Verkeerde PIN-kode."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Gelaai"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Laai"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Laai tans vinnig"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM-PUK-area"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Volgende wekker gestel vir <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Vee uit"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Deaktiveer e-SIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Het jy die patroon vergeet?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Verkeerde patroon"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Verkeerde PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Probeer weer oor <xliff:g id="NUMBER">%d</xliff:g> sekondes."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Teken jou patroon"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Voer SIM se PIN in"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Voer SIM se PIN vir \"<xliff:g id="CARRIER">%1$s</xliff:g>\" in"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Voer SIM se PIN in."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Voer SIM se PIN vir \"<xliff:g id="CARRIER">%1$s</xliff:g>\" in."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Deaktiveer e-SIM om toestel sonder mobiele diens te gebruik."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Voer PIN in"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Voer wagwoord in"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM is nou gedeaktiveer. Voer PUK-kode in om voort te gaan. Kontak diensverskaffer vir besonderhede."</string>
diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml
index aa33845..fc7634a 100644
--- a/packages/SystemUI/res-keyguard/values-am/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-am/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"ለመክፈት የይለፍ ቃል ይተይቡ"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"ለመክፈት ፒን ይተይቡ"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ትክክል ያልሆነ ፒን  ኮድ።"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"ባትሪ ሞልቷል"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"ኃይል በመሙላት ላይ"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"ኃይል በፍጥነት በመሙላት ላይ"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"የሲም ፒዩኬ አካባቢ"</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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"አስገባ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ስርዓተ ጥለቱን እርሳ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"የተሳሳተ ስርዓተ ጥለት"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"የተሳሳተ ፒን"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"በ<xliff:g id="NUMBER">%d</xliff:g> ሰከንዶች ውስጥ እንደገና ይሞክሩ።"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ስርዓተ ጥለትዎን ይሳሉ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"የሲም ፒን ያስገቡ"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"የ«<xliff:g id="CARRIER">%1$s</xliff:g>» ሲም ፒን ያስገቡ"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"የሲም ፒን ያስገቡ።"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"የ«<xliff:g id="CARRIER">%1$s</xliff:g>» ሲም ፒን ያስገቡ።"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"መሣሪያን ያለተንቀሳቃሽ ስልክ አገልግሎት ለመጠቀም 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>
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index 129b4cc..42f92e3 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"اكتب كلمة المرور لإلغاء التأمين"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"اكتب رمز رقم التعريف الشخصي لإلغاء التأمين"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"رمز رقم التعريف الشخصي غير صحيح."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"تم الشحن"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"جارٍ الشحن"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"الشحن سريعًا"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"‏منطقة PUK لشريحة SIM"</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">"Delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"‏تعطيل شريحة eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"نسيت النقش"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"نقش خاطئ"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"رقم تعريف شخصي خاطئ"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"حاول مرة أخرى خلال <xliff:g id="NUMBER">%d</xliff:g> ثانية."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ارسم نقشك"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"‏أدخل رمز رقم التعريف الشخصي لشريحة SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"‏أدخل رقم التعريف الشخصي لشريحة SIM التابعة للمشغّل \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"‏أدخل رقم التعريف الشخصي لشريحة SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"‏أدخل رقم التعريف الشخصي لشريحة SIM التابعة للمشغّل \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"‏يجب تعطيل شريحة 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">"‏شريحة SIM معطّلة الآن. أدخل رمز PUK للمتابعة. اتصل بمشغل شبكة الجوّال للاطلاع على التفاصيل."</string>
diff --git a/packages/SystemUI/res-keyguard/values-az/strings.xml b/packages/SystemUI/res-keyguard/values-az/strings.xml
index 08ad2b74..c074380 100644
--- a/packages/SystemUI/res-keyguard/values-az/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-az/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Kilidi açmaq üçün parol daxil edin"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Kilidi açmaq üçün PIN daxil edin"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Yanlış PIN kod."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Enerji yığdı"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Enerji yığır"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Sürətlə enerji yığır"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK sahəsi"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Növbəti zəng vaxtı: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Silin"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSİM\'i deaktiv edin"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Daxil edin"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Modeli unutmuşam"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Yanlış Model"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Yanlış PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Modeli çəkin"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN kodu daxil edin"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" üçün SIM PIN daxil edin"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN\'ni daxil edin."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" üçün SIM PIN\'ni daxil edin."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Mobil xidmət olmadan cihazı istifadə etmək üçün eSIM\'i deaktiv edin."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN daxil edin"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Parol daxil edin"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM indi deaktivdir. Davam etmək üçün PUK kod daxil edin. Ətraflı məlumat üçün operatorla əlaqə saxlayın."</string>
diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
index c7cfe88..7952b7a 100644
--- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Oblast za PUK za SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Sledeći alarm je podešen za <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Izbriši"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Onemogući eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Zaboravio/la sam šablon"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Pogrešan šablon"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Pogrešan PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Probajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> sek."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Nacrtajte šablon"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Unesite PIN za SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Unesite PIN za SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Unesite PIN za SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Unesite PIN za SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Onemogućite eSIM da biste uređaj koristili bez mobilne usluge."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Unesite PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Unesite lozinku"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM kartica je sada onemogućena. Unesite PUK kôd da biste nastavili. Detaljne informacije potražite od mobilnog operatera."</string>
@@ -116,7 +118,7 @@
     <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"Treba da unesete šablon kada prelazite sa jednog profila na drugi"</string>
     <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"Treba da unesete PIN kada prelazite sa jednog profila na drugi"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"Treba da unesete lozinku kada prelazite sa jednog profila na drugi"</string>
-    <string name="kg_prompt_reason_device_admin" msgid="2438626748767361010">"Administrator uređaja je zaključao uređaj"</string>
+    <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"Administrator je zaključao uređaj"</string>
     <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"Uređaj je ručno zaključan"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="71299470072448533">
       <item quantity="one">Niste otključali uređaj <xliff:g id="NUMBER_1">%d</xliff:g> sat. Potvrdite šablon.</item>
diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml
index e1dfc04..3b9a9bb 100644
--- a/packages/SystemUI/res-keyguard/values-be/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-be/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Поле для PUK-кода SIM-карты"</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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Увесці"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Забыў(-ла) узор"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Няправільны ўзор"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Няправільны PIN-код"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Паўтарыце спробу праз <xliff:g id="NUMBER">%d</xliff:g> с."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Намалюйце ўзор"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Увядзіце PIN-код SIM-карты"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Увядзіце PIN-код SIM-карты \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Увядзіце PIN-код SIM-карты."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Увядзіце PIN-код SIM-карты для \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Адключыце eSIM-карту, каб выкарыстоўваць прыладу без сэрвісу мабільнай перадачы даных."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Увядзіце PIN-код"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Увядзіце пароль"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-карта зараз адключана. Увядзіце PUK-код, каб працягнуць. Звяжыцеся са сваім аператарам, каб атрымаць дадатковую інфармацыю."</string>
@@ -108,7 +110,7 @@
     <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>
-    <string name="airplane_mode" msgid="3807209033737676010">"Рэжым самалёта"</string>
+    <string name="airplane_mode" msgid="3807209033737676010">"Рэжым палёту"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"Пасля перазапуску прылады патрабуецца ўзор"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"Пасля перазапуску прылады патрабуецца PIN-код"</string>
     <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"Пасля перазапуску прылады патрабуецца пароль"</string>
@@ -118,7 +120,7 @@
     <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"Пры пераключэнні профіляў патрабуецца ўзор"</string>
     <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"Пры пераключэнні профіляў патрабуецца PIN-код"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"Пры пераключэнні профіляў патрабуецца пароль"</string>
-    <string name="kg_prompt_reason_device_admin" msgid="2438626748767361010">"Адміністратар прылады заблакіраваў яе"</string>
+    <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"Прылада заблакіравана адміністратарам"</string>
     <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"Прылада была заблакіравана ўручную"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="71299470072448533">
       <item quantity="one">Прылада не была разблакіравана на працягу <xliff:g id="NUMBER_1">%d</xliff:g> гадзіны. Увядзіце ўзор.</item>
diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml
index 73373d5e..1e42f25 100644
--- a/packages/SystemUI/res-keyguard/values-bg/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Въведете парола, за да отключите"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Въведете ПИН кода, за да отключите"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Неправилен ПИН код."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Заредена"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Зарежда се"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Зарежда се бързо"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Област за PUK кода на SIM картата"</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">"Деактивиране на ел. SIM карта"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"„Enter“"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Забравена фигура"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Грешна фигура"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Грешен ПИН код"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Опитайте отново след <xliff:g id="NUMBER">%d</xliff:g> секунди."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Начертайте фигурата си"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Въведете ПИН кода за SIM картата"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Въведете ПИН кода на SIM картата за „<xliff:g id="CARRIER">%1$s</xliff:g>“"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Въведете ПИН кода за SIM картата."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Въведете ПИН кода на SIM картата за „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Деактивирайте електронната SIM карта, за да използвате устройството без мобилна услуга."</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">"SIM картата вече е деактивирана. Въведете PUK кода, за да продължите. Свържете се с оператора за подробности."</string>
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index 26ba5e9..66a5621 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"আনলক করতে পাসওয়ার্ড লিখুন"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"আনলক করতে পিন লিখুন"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ভুল পিন কোড দেওয়া হয়েছে।"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"চার্জ হয়েছে"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"চার্জ হচ্ছে"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"দ্রুত চার্জ হচ্ছে"</string>
@@ -51,6 +53,7 @@
     <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">"ই-সিমটি অক্ষম করুন"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"এন্টার"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"প্যাটার্ন ভুলে গেছি"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ভুল প্যাটার্ন"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"ভুল পিন"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"আপনার প্যাটার্ন আঁকুন"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"সিমের পিন লিখুন"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" এর জন্য সিমের পিন লিখুন"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"সিমের পিন লিখুন।"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" এর জন্য সিমের পিন লিখুন।"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"মোবাইল পরিষেবা ছাড়াই ডিভাইস ব্যবহার করতে ই-সিম অক্ষম করুন।"</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">"সিমটি এখন অক্ষম করা হয়েছে। চালিয়ে যেতে PUK কোডটি লিখুন। বিশদ বিবরণের জন্য পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।"</string>
@@ -70,25 +74,25 @@
     <string name="kg_invalid_sim_pin_hint" msgid="3057533256729513335">"একটি ৪ থেকে ৮ সংখ্যার পিন লিখুন।"</string>
     <string name="kg_invalid_sim_puk_hint" msgid="6003602401368264144">"PUK কোডটি ৮ বা তার বেশি সংখ্যার হতে হবে।"</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_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>
+    <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>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7724148763268377734">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে আপনার পাসওয়ার্ড লিখেছেন।\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে আপনার আনলকের প্যাটার্ন এঁকেছেন।\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1629351522209932316">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন। আরো <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর এই ট্যাবলেটটিকে রিসেট করা হবে, যার ফলে এর সমস্ত ডেটা মুছে যাবে।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="3921998703529189931">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে ফোনটি আনলক করার চেষ্টা করেছেন। আরো <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর এই ফোনটিকে রিসেট করা হবে, যার ফলে এর সমস্ত ডেটা মুছে যাবে।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1629351522209932316">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর এই ট্যাবলেটটিকে রিসেট করা হবে, যার ফলে এর সমস্ত ডেটা মুছে যাবে।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="3921998703529189931">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে ফোনটি আনলক করার চেষ্টা করেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর এই ফোনটিকে রিসেট করা হবে, যার ফলে এর সমস্ত ডেটা মুছে যাবে।"</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="4694232971224663735">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুলভাবে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন। এই ফোনটিকে রিসেট করা হবে, যার ফলে এর সমস্ত ডেটা মুছে যাবে।"</string>
     <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_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_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_failed_attempts_almost_at_login" product="tablet" msgid="956706236554092172">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে আনলকের প্যাটার্ন এঁকেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর আপনাকে একটি ইমেল অ্যাকাউন্টের মাধ্যমে আপনার ট্যাবলেটটি আনলক করতে বলা হবে।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে আনলকের প্যাটার্ন এঁকেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর আপনাকে একটি ইমেল অ্যাকাউন্টের মাধ্যমে আপনার ফোনটি আনলক করতে বলা হবে।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="3389829202093674267">"ভুল সিম পিন কোড দিয়েছেন, আপনার ডিভাইসটি আনলক করতে এখন আপনাকে অবশ্যই আপনার পরিষেবা প্রদানকারীর সাথে যোগাযোগ করতে হবে।"</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="4314341367727055967">
       <item quantity="one">সিমের পিন কোডটি ভুল, আপনি আর <xliff:g id="NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারেন।</item>
@@ -112,7 +116,7 @@
     <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"অতিরিক্ত সুরক্ষার জন্য পিন দেওয়া প্রয়োজন"</string>
     <string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"অতিরিক্ত সুরক্ষার জন্য পাসওয়ার্ড দেওয়া প্রয়োজন"</string>
     <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"আপনি প্রোফাইলগুলি স্যুইচ করার সময় প্যাটার্নের প্রয়োজন হবে"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"আপনি প্রোফাইলগুলি স্যুইচ করার সময় পিন এর প্রয়োজন হবে"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"প্রোফাইলগুলি স্যুইচ করার সময় পিন প্রয়োজন হবে"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"আপনি প্রোফাইলগুলি স্যুইচ করার সময় পাসওয়ার্ডের প্রয়োজন হবে"</string>
     <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"প্রশাসক ডিভাইসটি লক করেছেন"</string>
     <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"ডিভাইসটিকে ম্যানুয়ালি লক করা হয়েছে"</string>
@@ -121,8 +125,8 @@
       <item quantity="other">ডিভাইসটি <xliff:g id="NUMBER_1">%d</xliff:g> ঘন্টা ধরে আনলক করা হয় নি। প্যাটার্নটি নিশ্চিত করুন।</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="34586942088144385">
-      <item quantity="one">ডিভাইসটি <xliff:g id="NUMBER_1">%d</xliff:g> ঘন্টা ধরে আনলক করা হয় নি। পিন নিশ্চিত করুন।</item>
-      <item quantity="other">ডিভাইসটি <xliff:g id="NUMBER_1">%d</xliff:g> ঘন্টা ধরে আনলক করা হয় নি। পিন নিশ্চিত করুন।</item>
+      <item quantity="one">ডিভাইসটি <xliff:g id="NUMBER_1">%d</xliff:g> ঘণ্টা ধরে আনলক করা হয়নি। পিন নিশ্চিত করুন৷</item>
+      <item quantity="other">ডিভাইসটি <xliff:g id="NUMBER_1">%d</xliff:g> ঘণ্টা ধরে আনলক করা হয়নি। পিন নিশ্চিত করুন৷</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_password" formatted="false" msgid="257297696215346527">
       <item quantity="one">ডিভাইসটি <xliff:g id="NUMBER_1">%d</xliff:g> ঘন্টা ধরে আনলক করা হয় নি। পাসওয়ার্ড নিশ্চিত করুন।</item>
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index 04256f1..0ec4ad5 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -30,7 +30,7 @@
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Upišite PIN kôd za otključavanje"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Pogrešan PIN kôd."</string>
     <string name="keyguard_charged" msgid="2222329688813033109">"Napunjeno"</string>
-    <string name="keyguard_plugged_in" msgid="89308975354638682">"Puni se"</string>
+    <string name="keyguard_plugged_in" msgid="89308975354638682">"Punjenje"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Brzo punjenje"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="6637043106038550407">"Sporo punjenje"</string>
     <string name="keyguard_low_battery" msgid="9218432555787624490">"Priključite punjač."</string>
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Prostor za PUK kôd za SIM karticu"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Naredni alarm je podešen za <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Izbriši"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Onemogući eSIM karticu"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Zaboravili ste uzorak?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Pogrešan uzorak"</string>
@@ -58,12 +59,13 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Pogrešan PIN kôd"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Pokušajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> sek."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Nacrtajte uzorak"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Unesite PIN kôd za SIM karticu"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Unesite PIN kôd za SIM karticu operatera \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Unesite PIN kôd SIM kartice."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Unesite PIN kôd SIM kartice operatera \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Onemogućite eSIM karticu za korištenje uređaja bez mobilne usluge."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Unesite PIN kôd"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Unesite lozinku"</string>
-    <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM kartica je sada onemogućena. Unesite PUK kôd da nastavite. Obratite se operateru za detalje."</string>
-    <string name="kg_puk_enter_puk_hint_multi" msgid="1373131883510840794">"Operater SIM kartice \"<xliff:g id="CARRIER">%1$s</xliff:g>\" sada je onemogućen. Unesite PUK kôd da nastavite. Za više detalja obratite se operateru."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM kartica je sada onemogućena. Unesite PUK kôd da nastavite. Za više informacija obratite se operateru."</string>
+    <string name="kg_puk_enter_puk_hint_multi" msgid="1373131883510840794">"Operater SIM kartice \"<xliff:g id="CARRIER">%1$s</xliff:g>\" sada je onemogućen. Unesite PUK kôd da nastavite. Za više informacija obratite se operateru."</string>
     <string name="kg_puk_enter_pin_hint" msgid="3137789674920391087">"Unesite željeni PIN kôd"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="3089485999116759671">"Potvrdite željeni PIN kôd"</string>
     <string name="kg_sim_unlock_progress_dialog_message" msgid="4471738151810900114">"Otključavanje SIM kartice…"</string>
@@ -116,7 +118,7 @@
     <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"Potreban je uzorak nakon prelaska na drugi profil"</string>
     <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"Potreban je PIN kôd nakon prelaska na drugi profil"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"Potrebna je lozinka nakon prelaska na drugi profil"</string>
-    <string name="kg_prompt_reason_device_admin" msgid="2438626748767361010">"Administrator je zaključao uređaj."</string>
+    <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"Uređaj je zaključao administrator"</string>
     <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"Uređaj je ručno zaključan"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="71299470072448533">
       <item quantity="one">Uređaj nije otključavan <xliff:g id="NUMBER_1">%d</xliff:g> sat. Potvrdite uzorak.</item>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index 723d502..553b41e 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Escriu la contrasenya per desbloquejar"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Escriu el PIN per desbloquejar"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"El codi PIN no és correcte."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Bateria carregada"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"S\'està carregant"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"S\'està carregant ràpidament"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Zona del PUK de la SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"S\'ha definit la pròxima alarma per a l\'hora següent: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Suprimeix"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Desactiva l\'eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Retorn"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"He oblidat el patró"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"El patró no és correcte"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"El PIN no és correcte"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER">%d</xliff:g> segons."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dibuixa el patró"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Introdueix el PIN de la SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Introdueix el PIN de la SIM següent: <xliff:g id="CARRIER">%1$s</xliff:g>"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Introdueix el PIN de la SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Introdueix el PIN de la SIM de: <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Desactiva l\'eSIM per utilitzar el dispositiu sense servei mòbil."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Introdueix el PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Introdueix la contrasenya"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La SIM està desactivada. Introdueix el codi PUK per continuar. Contacta amb l\'operador de telefonia mòbil per obtenir més informació."</string>
@@ -69,7 +73,7 @@
     <string name="kg_sim_unlock_progress_dialog_message" msgid="4471738151810900114">"S\'està desbloquejant la targeta SIM…"</string>
     <string name="kg_invalid_sim_pin_hint" msgid="3057533256729513335">"Escriu un PIN que tingui entre 4 i 8 números."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="6003602401368264144">"El codi PUK ha de tenir 8 números o més."</string>
-    <string name="kg_invalid_puk" msgid="5399287873762592502">"Torna a introduir el codi PUK correcte. Si ho intentes diverses vegades, es desactivarà la SIM de manera permanent."</string>
+    <string name="kg_invalid_puk" msgid="5399287873762592502">"Torna a introduir el codi PUK correcte. Si ho intentes diverses vegades, es desactivarà la SIM permanentment."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="5672736555427444330">"Els codis PIN no coincideixen"</string>
     <string name="kg_login_too_many_attempts" msgid="6604574268387867255">"Has intentat dibuixar el patró massa vegades"</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8637788033282252027">"Has escrit el PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml
index 52b12bf..2d52059 100644
--- a/packages/SystemUI/res-keyguard/values-cs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Zadejte heslo pro odemknutí"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Zadejte kód PIN pro odemknutí"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Nesprávný kód PIN."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Nabito"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Nabíjení"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Rychlé nabíjení"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Oblast kódu PUK SIM karty"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Další budík je nastaven na <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Smazat"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Deaktivovat eSIM kartu"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Zapomenuté gesto"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Nesprávné gesto"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Nesprávný kód PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Zkuste to znovu za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Zadejte gesto"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Zadejte kód PIN SIM karty"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Zadejte kód PIN SIM karty <xliff:g id="CARRIER">%1$s</xliff:g>"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Zadejte kód PIN SIM karty."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Zadejte kód PIN SIM karty <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"eSIM kartu deaktivujte, chcete-li telefon používat bez mobilních služeb."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Zadejte kód PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Zadejte heslo"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM karta byla zablokována. Chcete-li pokračovat, je třeba zadat kód PUK. Podrobné informace získáte od operátora."</string>
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index 486b46c..eeff613 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Indtast adgangskoden for at låse op"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Indtast pinkoden for at låse op"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Forkert pinkode."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Opladet"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Oplader"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Oplader hurtigt"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Område for PUK-koden til SIM-kortet"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Næste alarm er indstillet til <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Slet"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Deaktiver eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Har du glemt mønsteret?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Forkert mønster"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Forkert pinkode"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Prøv igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Tegn dit mønster"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Indtast pinkoden til SIM-kortet"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Indtast pinkoden til SIM-kortet for \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Angiv pinkoden til SIM-kortet."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Angiv pinkoden til SIM-kortet fra \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Deaktiver eSIM for at bruge enheden uden mobiltjeneste."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Indtast pinkode"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Angiv adgangskode"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortet er nu deaktiveret. Indtast PUK-koden for at fortsætte. Kontakt mobilselskabet for at få flere oplysninger."</string>
diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml
index 190f203..1c73463 100644
--- a/packages/SystemUI/res-keyguard/values-de/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-de/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Bitte gib das Passwort zum Entsperren ein"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Bitte gib die PIN zum Entsperren ein"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Falscher PIN-Code."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Aufgeladen"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Wird aufgeladen"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Schnelles Aufladen"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM-PUK-Bereich"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nächster Wecker gestellt für <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Löschen"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM deaktivieren"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Eingabe"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Muster vergessen"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Falsches Muster"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Falsche PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Versuche es in <xliff:g id="NUMBER">%d</xliff:g> Sekunden noch einmal."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Muster zeichnen"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM-PIN eingeben"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"SIM-PIN für \"<xliff:g id="CARRIER">%1$s</xliff:g>\" eingeben"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Gib die SIM-PIN ein"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Gib die SIM-PIN für \"<xliff:g id="CARRIER">%1$s</xliff:g>\" ein."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Deaktiviere eSIM, um das Gerät ohne Mobilfunkdienst zu verwenden."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN eingeben"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Passwort eingeben"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Die SIM-Karte ist jetzt deaktiviert. Gib den PUK-Code ein, um fortzufahren. Weitere Informationen erhältst du von deinem Mobilfunkanbieter."</string>
diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml
index 9707c90..bfef121 100644
--- a/packages/SystemUI/res-keyguard/values-el/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-el/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Πληκτρολογήστε τον κωδικό πρόσβασης για ξεκλείδωμα"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Πληκτρολογήστε τον αριθμό PIN για ξεκλείδωμα"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Λανθασμένος κωδικός PIN."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Φορτίστηκε"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Φόρτιση σε εξέλιξη"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Ταχεία φόρτιση"</string>
@@ -51,15 +53,17 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Περιοχή κωδικού PUK κάρτας SIM"</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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Ξεχάσατε το μοτίβο"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Λάθος μοτίβο"</string>
     <string name="kg_wrong_password" msgid="4580683060277329277">"Λανθασμένος κωδικός πρόσβασης"</string>
-    <string name="kg_wrong_pin" msgid="4785660766909463466">"Λανθασμένος αριθμός PIN"</string>
+    <string name="kg_wrong_pin" msgid="4785660766909463466">"Λανθασμένο PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Δοκιμάστε ξανά σε <xliff:g id="NUMBER">%d</xliff:g> δευτερόλεπτα."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Σχεδιάστε το μοτίβο σας"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Εισαγωγή αριθμού PIN της κάρτας SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Εισάγετε τον αριθμό PIN της SIM της εταιρείας κινητής τηλεφωνίας \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Εισαγωγή αριθμού PIN κάρτας SIM"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Εισαγάγετε τον αριθμό PIN της κάρτας SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Απενεργοποιήστε την eSIM, για να χρησιμοποιήσετε τη συσκευή χωρίς υπηρεσία για κινητά."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Εισαγάγετε τον αριθμό PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Εισαγάγετε κωδικό πρόσβασης"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Η κάρτα SIM είναι απενεργοποιημένη αυτή τη στιγμή. Εισαγάγετε τον κωδικό PUK για να συνεχίσετε. Επικοινωνήστε με την εταιρεία κινητής τηλεφωνίας σας για λεπτομέρειες."</string>
@@ -106,13 +110,13 @@
     <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"Εναλλαγή μεθόδου εισαγωγής"</string>
     <string name="airplane_mode" msgid="3807209033737676010">"Λειτουργία πτήσης"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"Απαιτείται μοτίβο μετά από την επανεκκίνηση της συσκευής"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"Απαιτείται αριθμός PIN μετά από την επανεκκίνηση της συσκευής"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"Απαιτείται PIN μετά από την επανεκκίνηση της συσκευής"</string>
     <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"Απαιτείται κωδικός πρόσβασης μετά από την επανεκκίνηση της συσκευής"</string>
     <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"Απαιτείται μοτίβο για πρόσθετη ασφάλεια"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"Απαιτείται αριθμός PIN για πρόσθετη ασφάλεια"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"Απαιτείται PIN για πρόσθετη ασφάλεια"</string>
     <string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"Απαιτείται κωδικός πρόσβασης για πρόσθετη ασφάλεια"</string>
     <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"Απαιτείται μοτίβο κατά την εναλλαγή προφίλ"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"Απαιτείται αριθμός PIN κατά την εναλλαγή προφίλ"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"Απαιτείται PIN κατά την εναλλαγή προφίλ"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"Απαιτείται κωδικός πρόσβασης κατά την εναλλαγή προφίλ"</string>
     <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"Η συσκευή κλειδώθηκε από τον διαχειριστή"</string>
     <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"Η συσκευή κλειδώθηκε με μη αυτόματο τρόπο"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
index 6b02d6d..a17b784 100644
--- a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Type password to unlock"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Type PIN to unlock"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Incorrect PIN code."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Charged"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Charging"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Charging rapidly"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK area"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Next alarm set for <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Disable eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Forgotten Pattern"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Wrong Pattern"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Wrong PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Draw your pattern"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Enter SIM PIN"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Enter SIM PIN for \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Enter SIM PIN."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Enter SIM PIN for \'<xliff:g id="CARRIER">%1$s</xliff:g>\'."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Disable eSIM to use device without mobile service."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Enter PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Enter Password"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
index 6b02d6d..a17b784 100644
--- a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Type password to unlock"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Type PIN to unlock"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Incorrect PIN code."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Charged"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Charging"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Charging rapidly"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK area"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Next alarm set for <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Disable eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Forgotten Pattern"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Wrong Pattern"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Wrong PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Draw your pattern"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Enter SIM PIN"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Enter SIM PIN for \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Enter SIM PIN."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Enter SIM PIN for \'<xliff:g id="CARRIER">%1$s</xliff:g>\'."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Disable eSIM to use device without mobile service."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Enter PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Enter Password"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
index 6b02d6d..a17b784 100644
--- a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Type password to unlock"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Type PIN to unlock"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Incorrect PIN code."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Charged"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Charging"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Charging rapidly"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK area"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Next alarm set for <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Disable eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Forgotten Pattern"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Wrong Pattern"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Wrong PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Draw your pattern"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Enter SIM PIN"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Enter SIM PIN for \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Enter SIM PIN."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Enter SIM PIN for \'<xliff:g id="CARRIER">%1$s</xliff:g>\'."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Disable eSIM to use device without mobile service."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Enter PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Enter Password"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index 761e3a1..4514dee 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Ingresa la contraseña para desbloquearlo"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Ingresa el PIN para desbloquearlo"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Código PIN incorrecto"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Cargada"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Cargando"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Carga rápida"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Área de PUK de la tarjeta SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Próxima alarma establecida: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Borrar"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Inhabilitar eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Intro"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"¿Olvidaste el patrón?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Patrón incorrecto"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN incorrecto"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Vuelve a intentarlo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dibuja tu patrón"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Ingresa el PIN de la tarjeta SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Ingresa el PIN de la tarjeta SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Ingresa el PIN de la tarjeta SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Ingresa el PIN de la tarjeta SIM de \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Inhabilita la eSIM para usar el dispositivo sin servicio de datos móviles."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Ingresa el PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Escribe la contraseña"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La tarjeta SIM está inhabilitada. Para continuar, ingresa el código PUK. Si quieres obtener más información, comunícate con el proveedor."</string>
diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml
index 9811023..8c75489 100644
--- a/packages/SystemUI/res-keyguard/values-es/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Escribe la contraseña para desbloquear"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Escribe el código PIN para desbloquear"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"El código PIN es incorrecto."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Cargada"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Cargando"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Cargando rápidamente"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Área de PUK de la tarjeta SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Próxima alarma: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Eliminar"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Inhabilita la tarjeta eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Intro"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"¿Has olvidado el patrón?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Patrón incorrecto"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN incorrecto"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Vuelve a intentarlo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dibuja tu patrón"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Introduce el PIN de la tarjeta SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Introduce el PIN de la tarjeta SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Introduce el PIN de la tarjeta SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Introduce el PIN de la tarjeta SIM de <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Inhabilita la tarjeta eSIM para utilizar el dispositivo sin servicio móvil."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Introduce el PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Introduce tu contraseña"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La tarjeta SIM está inhabilitada. Para continuar, introduce el código PUK. Si quieres obtener más información, ponte en contacto con el operador."</string>
diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml
index 1892ef6..97742cb 100644
--- a/packages/SystemUI/res-keyguard/values-et/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-et/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Avamiseks sisestage parool"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Avamiseks sisestage PIN-kood"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Vale PIN-kood."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Laetud"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Laadimine"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Kiiresti laadimine"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM-kaardi PUK-koodi ala"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Järgmine alarm on määratud ajaks <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Kustuta"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Keela eSIM-kaart"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Sisesta"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Unustasin mustri"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Vale muster"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Vale PIN-kood"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Proovige <xliff:g id="NUMBER">%d</xliff:g> sekundi pärast uuesti."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Joonistage oma muster"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Sisestage SIM-kaardi PIN-kood"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Sisestage operaatori „<xliff:g id="CARRIER">%1$s</xliff:g>” puhul SIM-kaardi PIN-kood"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Sisestage SIM-kaardi PIN-kood."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Sisestage operaatori „<xliff:g id="CARRIER">%1$s</xliff:g>” SIM-kaardi PIN-kood."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Keelake eSIM-kaart, et seadet ilma mobiilsideteenuseta kasutada."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Sisestage PIN-kood"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Sisestage parool"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kaart on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Lisateabe saamiseks võtke ühendust operaatoriga."</string>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index 38ff52e..b493a09 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Idatzi desblokeatzeko pasahitza"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Idatzi desblokeatzeko PIN kodea"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN kode hori ez da zuzena."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Kargatuta"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Kargatzen"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Bizkor kargatzen"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM txartelaren PUK kodearen eremua"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Hurrengo alarmak ordu honetan joko du: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Ezabatu"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Desgaitu eSIM txartela"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Sartu"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Eredua ahaztu zaizu"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Eredu hori ez da zuzena"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN kode hori ez da zuzena"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Saiatu berriro <xliff:g id="NUMBER">%d</xliff:g> segundo barru."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Marraztu eredua"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Idatzi SIM txartelaren PIN kodea"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Idatzi \"<xliff:g id="CARRIER">%1$s</xliff:g>\" operadorearen SIM txartelaren PIN kodea"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Idatzi SIM txartelaren PIN kodea."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Idatzi \"<xliff:g id="CARRIER">%1$s</xliff:g>\" operadorearen SIM txartelaren PIN kodea."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Desgaitu eSIM txartela gailua zerbitzu mugikorrik gabe erabiltzeko."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Idatzi PIN kodea"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Idatzi pasahitza"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Desgaitu egin da SIM txartela. Aurrera egiteko, idatzi PUK kodea. Xehetasunak lortzeko, jarri operadorearekin harremanetan."</string>
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index 3dc59ca..8e23d9d 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"برای بازکردن قفل، گذرواژه را وارد کنید"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"برای بازکردن قفل، پین را تایپ کنید"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"کد پین اشتباه است."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"شارژ کامل شد"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"درحال شارژ شدن"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"شارژ سریع"</string>
@@ -51,6 +53,7 @@
     <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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"الگو را فراموش کرده‌اید"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"الگوی اشتباه"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"پین اشتباه"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"پس از <xliff:g id="NUMBER">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"الگوی خود را رسم کنید"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"پین سیم‌کارت را وارد کنید"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"پین سیم‌کارت «<xliff:g id="CARRIER">%1$s</xliff:g>» را وارد کنید"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"پین سیم‌کارت را وارد کنید."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"پین سیم‌کارت «<xliff:g id="CARRIER">%1$s</xliff:g>» را وارد کنید."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"‏برای استفاده از دستگاه بدون سرویس همراه، 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>
diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml
index 91d8d82..d531e65 100644
--- a/packages/SystemUI/res-keyguard/values-fi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Poista lukitus antamalla salasana."</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Poista lukitus antamalla PIN-koodi."</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Väärä PIN-koodi"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Ladattu"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Ladataan"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Nopea lataus käynnissä"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM-kortin PUK-koodin alue"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Seuraava hälytys asetettu: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Poista"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Poista eSIM käytöstä"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Unohtunut kuvio"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Väärä kuvio"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Väärä PIN-koodi"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Yritä uudelleen <xliff:g id="NUMBER">%d</xliff:g> sekunnin kuluttua."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Piirrä kuvio"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Anna SIM-kortin PIN-koodi"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Anna operaattorin <xliff:g id="CARRIER">%1$s</xliff:g> SIM-kortin PIN-koodi."</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Anna SIM-kortin PIN-koodi."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Anna operaattorin <xliff:g id="CARRIER">%1$s</xliff:g> SIM-kortin PIN-koodi."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Poista eSIM käytöstä, jos haluat käyttää laitetta ilman mobiilipalvelua."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Anna PIN-koodi."</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Anna salasana"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortti on nyt poistettu käytöstä. Jatka antamalla PUK-koodi. Saat lisätietoja ottamalla yhteyttä operaattoriin."</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
index 5f2462c..11f6ff1 100644
--- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Entrez le mot de passe pour déverrouiller le clavier."</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Entrez le NIP pour déverrouiller le clavier."</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"NIP erroné."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Chargé"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Pile en cours de charge"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Charge rapide"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Zone du code PUK de la carte SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Heure de la prochaine alarme : <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Supprimer"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Désactiver la carte eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Entrée"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"J\'ai oublié le schéma"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Schéma incorrect"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"NIP incorrect"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Veuillez réessayer dans <xliff:g id="NUMBER">%d</xliff:g> secondes."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dessinez votre schéma"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Entrez le NIP de la carte SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Entrez le NIP de la carte SIM pour « <xliff:g id="CARRIER">%1$s</xliff:g> »"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Entrez le NIP de la carte SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Entrez le NIP de la carte SIM pour « <xliff:g id="CARRIER">%1$s</xliff:g> »."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Désactivez la carte eSIM pour utiliser l\'appareil sans service cellulaire."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Entrez le NIP"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Entrez votre mot de passe."</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La carte SIM est maintenant désactivée. Entrez le code PUK pour continuer. Pour obtenir plus de détails, communiquez avec votre fournisseur de services."</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index ed38ae0..5acf96e 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Saisissez le mot de passe pour déverrouiller le clavier"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Saisissez le code pour déverrouiller le clavier"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Le code est incorrect."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Chargé"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"En charge…"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Chargement rapide…"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Champ de la clé PUK de la carte SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Date et heure de la prochaine alarme : <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Supprimer"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Désactiver la carte eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Entrée"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"J\'ai oublié le schéma"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Schéma incorrect"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Code incorrect"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Réessayez dans <xliff:g id="NUMBER">%d</xliff:g> secondes."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dessinez votre schéma"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Saisissez le code PIN de la carte SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Saisissez le code PIN de la carte SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Saisissez le code PIN de la carte SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Saisissez le code PIN de la carte SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Désactivez la carte eSIM pour utiliser l\'appareil sans service mobile."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Saisissez le code"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Saisissez le mot de passe"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La carte SIM est maintenant désactivée. Pour continuer, saisissez la clé PUK. Contactez votre opérateur pour en savoir plus."</string>
diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml
index a615f7f..a81affb 100644
--- a/packages/SystemUI/res-keyguard/values-gl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Escribe o contrasinal para desbloquear"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Escribe o PIN para desbloquear"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Código PIN incorrecto"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Cargada"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Cargando"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Cargando rapidamente"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Área do PUK da tarxeta SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Próxima alarma definida para: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Eliminar"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Desactivar eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Intro"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Esqueciches o padrón"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Padrón incorrecto"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN incorrecto"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Téntao de novo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Debuxa o teu padrón"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Introduce o PIN da SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Introduce o PIN da SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Introduce o PIN da SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Introduce o PIN da SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Desactiva a eSIM para usar o dispositivo sen servizo móbil."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Introduce o PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Insire o teu contrasinal"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Agora a tarxeta SIM está desactivada. Introduce o código PUK para continuar. Ponte en contacto co operador para obter máis información."</string>
@@ -103,7 +107,7 @@
     <string name="kg_password_puk_failed" msgid="1331621440873439974">"Produciuse un erro ao tentar desbloquear a tarxeta SIM co código PUK."</string>
     <string name="kg_pin_accepted" msgid="7637293533973802143">"Código válido"</string>
     <string name="keyguard_carrier_default" msgid="4274828292998453695">"Non hai servizo."</string>
-    <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"Cambia o método de entrada"</string>
+    <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"Cambia o método de introdución"</string>
     <string name="airplane_mode" msgid="3807209033737676010">"Modo avión"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"É necesario o padrón despois do reinicio do dispositivo"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"É necesario o PIN despois do reinicio do dispositivo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index d036ef4..60666fb 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -21,14 +21,16 @@
 <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="3171996292755059205">"કીગાર્ડ"</string>
-    <string name="keyguard_password_enter_pin_code" msgid="3420548423949593123">"PIN કોડ લખો"</string>
-    <string name="keyguard_password_enter_puk_code" msgid="670683628782925409">"SIM PUK અને નવો PIN કોડ લખો"</string>
-    <string name="keyguard_password_enter_puk_prompt" msgid="3747778500166059332">"SIM PUK કોડ"</string>
-    <string name="keyguard_password_enter_pin_prompt" msgid="8188243197504453830">"નવો SIM PIN કોડ"</string>
-    <string name="keyguard_password_entry_touch_hint" msgid="5790410752696806482"><font size="17">"પાસવર્ડ લખવા માટે ટચ કરો"</font></string>
+    <string name="keyguard_password_enter_pin_code" msgid="3420548423949593123">"પિન કોડ લખો"</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>
-    <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"અનલૉક કરવા માટે PIN લખો"</string>
-    <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ખોટો PIN કોડ."</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"અનલૉક કરવા માટે પિન લખો"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ખોટો પિન કોડ."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"ચાર્જ થઈ ગયું"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"ચાર્જ થઈ રહ્યું છે"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"ઝડપથી ચાર્જ થઈ રહ્યું છે"</string>
@@ -36,45 +38,47 @@
     <string name="keyguard_low_battery" msgid="9218432555787624490">"તમારું ચાર્જર કનેક્ટ કરો."</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8566679946700751371">"અનલૉક કરવા માટે મેનૂ દબાવો."</string>
     <string name="keyguard_network_locked_message" msgid="6743537524631420759">"નેટવર્ક લૉક થયું"</string>
-    <string name="keyguard_missing_sim_message_short" msgid="6327533369959764518">"કોઈ SIM કાર્ડ નથી"</string>
-    <string name="keyguard_missing_sim_message" product="tablet" msgid="4550152848200783542">"ટૅબ્લેટમાં SIM કાર્ડ નથી."</string>
-    <string name="keyguard_missing_sim_message" product="default" msgid="6585414237800161146">"ફોનમાં SIM કાર્ડ નથી."</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7350295932015220392">"એક SIM કાર્ડ દાખલ કરો."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="589889372883904477">"SIM કાર્ડ ખૂટે છે અથવા વાંચન યોગ્ય નથી. SIM કાર્ડ દાખલ કરો."</string>
-    <string name="keyguard_permanent_disabled_sim_message_short" msgid="654102080186420706">"બિનઉપયોગી SIM કાર્ડ."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="4683178224791318347">"તમારું SIM કાર્ડ કાયમી રૂપે અક્ષમ કરવામાં આવ્યું છે.\n બીજા SIM કાર્ડ માટે તમારા વાયરલેસ સેવા પ્રદાતાનો સંપર્ક કરો."</string>
-    <string name="keyguard_sim_locked_message" msgid="953766009432168127">"SIM કાર્ડ લૉક કરેલ છે."</string>
-    <string name="keyguard_sim_puk_locked_message" msgid="1772789643694942073">"SIM કાર્ડ, PUK-લૉક કરેલ છે."</string>
-    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="3586601150825821675">"SIM કાર્ડ અનલૉક કરી રહ્યા છીએ…"</string>
-    <string name="keyguard_accessibility_pin_area" msgid="703175752097279029">"PIN ક્ષેત્ર"</string>
-    <string name="keyguard_accessibility_sim_pin_area" msgid="912702510825058921">"SIM PIN ક્ષેત્ર"</string>
-    <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK ક્ષેત્ર"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="6327533369959764518">"કોઈ સિમ કાર્ડ નથી"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="4550152848200783542">"ટૅબ્લેટમાં સિમ કાર્ડ નથી."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="6585414237800161146">"ફોનમાં સિમ કાર્ડ નથી."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="7350295932015220392">"એક સિમ કાર્ડ દાખલ કરો."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="589889372883904477">"સિમ કાર્ડ ખૂટે છે અથવા વાંચન યોગ્ય નથી. સિમ કાર્ડ દાખલ કરો."</string>
+    <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">"સિમ કાર્ડ, 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_sim_pin_area" msgid="912702510825058921">"સિમ પિન ક્ષેત્ર"</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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"દાખલ કરો"</string>
-    <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"પેટર્ન ભૂલી ગયાં"</string>
-    <string name="kg_wrong_pattern" msgid="7620081431514773802">"ખોટી પેટર્ન"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"પૅટર્ન ભૂલી ગયાં"</string>
+    <string name="kg_wrong_pattern" msgid="7620081431514773802">"ખોટી પૅટર્ન"</string>
     <string name="kg_wrong_password" msgid="4580683060277329277">"ખોટો પાસવર્ડ"</string>
-    <string name="kg_wrong_pin" msgid="4785660766909463466">"ખોટો PIN"</string>
+    <string name="kg_wrong_pin" msgid="4785660766909463466">"ખોટો પિન"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
-    <string name="kg_pattern_instructions" msgid="5547646893001491340">"તમારી પેટર્ન દોરો"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN દાખલ કરો"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" માટે SIM PIN દાખલ કરો"</string>
-    <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN દાખલ કરો"</string>
+    <string name="kg_pattern_instructions" msgid="5547646893001491340">"તમારી પૅટર્ન દોરો"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"સિમ પિન દાખલ કરો"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" માટે સિમ પિન દાખલ કરો."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"મોબાઇલ સેવા વગર ઉપકરણનો ઉપયોગ કરવા 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">"SIM હમણાં અક્ષમ કરેલ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. વિગતો માટે કૅરિઅરનો સંપર્ક કરો."</string>
-    <string name="kg_puk_enter_puk_hint_multi" msgid="1373131883510840794">"SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\" હમણાં અક્ષમ કરેલ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. વિગતો માટે કૅરિઅરનો સંપર્ક કરો."</string>
-    <string name="kg_puk_enter_pin_hint" msgid="3137789674920391087">"જોઈતો PIN કોડ દાખલ કરો"</string>
-    <string name="kg_enter_confirm_pin_hint" msgid="3089485999116759671">"જોઈતા PIN કોડની પુષ્ટિ કરો"</string>
-    <string name="kg_sim_unlock_progress_dialog_message" msgid="4471738151810900114">"SIM કાર્ડ અનલૉક કરી રહ્યા છીએ…"</string>
-    <string name="kg_invalid_sim_pin_hint" msgid="3057533256729513335">"4 થી 8 સંખ્યાનો હોય તેવો એક PIN લખો."</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">"PUK કોડ 8 કે તેનાથી વધુ સંખ્યાનો હોવો જોઈએ."</string>
-    <string name="kg_invalid_puk" msgid="5399287873762592502">"સાચો PUK કોડ ફરીથી દાખલ કરો. પુનરાવર્તિત પ્રયાસો SIM ને કાયમી રીતે અક્ષમ કરશે."</string>
-    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="5672736555427444330">"PIN કોડ મેળ ખાતા નથી"</string>
-    <string name="kg_login_too_many_attempts" msgid="6604574268387867255">"ઘણા બધા પેટર્ન પ્રયાસો"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8637788033282252027">"તમારો PIN તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
+    <string name="kg_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>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7724148763268377734">"તમારો પાસવર્ડ તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"તમારી અનલૉક પેટર્ન તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"તમારી અનલૉક પૅટર્ન તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1629351522209932316">"તમે ટૅબ્લેટને <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, આ ટૅબ્લેટ ફરીથી સેટ કરવામાં આવશે, જે તેનો તમામ ડેટા કાઢી નાખશે."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="3921998703529189931">"તમે ફોનને <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, આ ફોન ફરીથી સેટ કરવામાં આવશે, જે તેનો તમામ ડેટા કાઢી નાખશે."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="4694232971224663735">"તમે ટૅબ્લેટને <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. આ ટૅબ્લેટ ફરીથી સેટ થશે, જે તેનો તમામ ડેટા કાઢી નાખશે."</string>
@@ -83,36 +87,36 @@
     <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>
+    <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">"ખોટો સિમ પિન કોડ, તમારે હવે તમારું ઉપકરણ અનલૉક કરવા માટે તમારા કૅરીઅરનો સંપર્ક કરવો આવશ્યક છે."</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="4314341367727055967">
-      <item quantity="one">ખોટો SIM PIN કોડ, તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
-      <item quantity="other">ખોટો SIM PIN કોડ, તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
+      <item quantity="one">ખોટો સિમ પિન કોડ, તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
+      <item quantity="other">ખોટો સિમ પિન કોડ, તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
     </plurals>
-    <string name="kg_password_wrong_puk_code_dead" msgid="3329017604125179374">"SIM અનુપયોગી છે. તમારા કૅરિઅરનો સંપર્ક કરો."</string>
+    <string name="kg_password_wrong_puk_code_dead" msgid="3329017604125179374">"સિમ અનુપયોગી છે. તમારા કૅરિઅરનો સંપર્ક કરો."</string>
     <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="2287504898931957513">
-      <item quantity="one">ખોટો SIM PUK કોડ, SIM કાયમી રૂપે અનુપયોગી બની જાય તે પહેલા તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
-      <item quantity="other">ખોટો SIM PUK કોડ, SIM કાયમી રૂપે અનુપયોગી બની જાય તે પહેલા તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
+      <item quantity="one">ખોટો સિમ PUK કોડ, સિમ કાયમી રૂપે અનુપયોગી બની જાય તે પહેલા તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
+      <item quantity="other">ખોટો સિમ PUK કોડ, સિમ કાયમી રૂપે અનુપયોગી બની જાય તે પહેલા તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
     </plurals>
-    <string name="kg_password_pin_failed" msgid="8769990811451236223">"SIM PIN ઑપરેશન નિષ્ફળ થયું!"</string>
-    <string name="kg_password_puk_failed" msgid="1331621440873439974">"SIM PUK ઓપરેશન નિષ્ફળ થયું!"</string>
+    <string name="kg_password_pin_failed" msgid="8769990811451236223">"સિમ પિન ઑપરેશન નિષ્ફળ થયું!"</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>
     <string name="airplane_mode" msgid="3807209033737676010">"એરપ્લેન મોડ"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"ઉપકરણનો પુનઃપ્રારંભ થાય તે પછી પેટર્ન જરૂરી છે"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"ઉપકરણનો પુનઃપ્રારંભ થાય તે પછી PIN જરૂરી છે"</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"ઉપકરણનો પુનઃપ્રારંભ થાય તે પછી પૅટર્ન જરૂરી છે"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"ઉપકરણનો પુનઃપ્રારંભ થાય તે પછી પિન જરૂરી છે"</string>
     <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"ઉપકરણનો પુનઃપ્રારંભ થાય તે પછી પાસવર્ડ જરૂરી છે"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"વધારાની સુરક્ષા માટે પેટર્ન જરૂરી છે"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"વધારાની સુરક્ષા માટે PIN જરૂરી છે"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"વધારાની સુરક્ષા માટે પૅટર્ન જરૂરી છે"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"વધારાની સુરક્ષા માટે પિન જરૂરી છે"</string>
     <string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"વધારાની સુરક્ષા માટે પાસવર્ડ જરૂરી છે"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"જ્યારે તમે પ્રોફાઇલો સ્વિચ કરો ત્યારે પેટર્ન જરૂરી છે"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"જ્યારે તમે પ્રોફાઇલો સ્વિચ કરો ત્યારે PIN જરૂરી છે"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"જ્યારે તમે પ્રોફાઇલો સ્વિચ કરો ત્યારે પૅટર્ન જરૂરી છે"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"જ્યારે તમે પ્રોફાઇલો સ્વિચ કરો ત્યારે પિન જરૂરી છે"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"જ્યારે તમે પ્રોફાઇલો સ્વિચ કરો ત્યારે પાસવર્ડ જરૂરી છે"</string>
     <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"વ્યવસ્થાપકે ઉપકરણ લૉક કરેલું છે"</string>
     <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"ઉપકરણ મેન્યુઅલી લૉક કર્યું હતું"</string>
@@ -121,8 +125,8 @@
       <item quantity="other">ઉપકરણને <xliff:g id="NUMBER_1">%d</xliff:g> કલાક માટે અનલૉક કરવામાં આવ્યું નથી. પેટર્નની પુષ્ટિ કરો.</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="34586942088144385">
-      <item quantity="one">ઉપકરણને <xliff:g id="NUMBER_1">%d</xliff:g> કલાક માટે અનલૉક કરવામાં આવ્યું નથી. PIN ની પુષ્ટિ કરો.</item>
-      <item quantity="other">ઉપકરણને <xliff:g id="NUMBER_1">%d</xliff:g> કલાક માટે અનલૉક કરવામાં આવ્યું નથી. PIN ની પુષ્ટિ કરો.</item>
+      <item quantity="one">ઉપકરણને <xliff:g id="NUMBER_1">%d</xliff:g> કલાક માટે અનલૉક કરવામાં આવ્યું નથી. પિનની પુષ્ટિ કરો.</item>
+      <item quantity="other">ઉપકરણને <xliff:g id="NUMBER_1">%d</xliff:g> કલાક માટે અનલૉક કરવામાં આવ્યું નથી. પિનની પુષ્ટિ કરો.</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_password" formatted="false" msgid="257297696215346527">
       <item quantity="one">ઉપકરણને <xliff:g id="NUMBER_1">%d</xliff:g> કલાક માટે અનલૉક કરવામાં આવ્યું નથી. પાસવર્ડની પુષ્ટિ કરો.</item>
diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml
index 023e433..3beb4fe 100644
--- a/packages/SystemUI/res-keyguard/values-hi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml
@@ -25,16 +25,18 @@
     <string name="keyguard_password_enter_puk_code" msgid="670683628782925409">"SIM PUK और नया पिन कोड लिखें"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="3747778500166059332">"SIM PUK कोड"</string>
     <string name="keyguard_password_enter_pin_prompt" msgid="8188243197504453830">"नया SIM पिन कोड"</string>
-    <string name="keyguard_password_entry_touch_hint" msgid="5790410752696806482"><font size="17">"पासवर्ड लिखने हेतु स्पर्श करें"</font></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>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"अनलॉक करने के लिए पिन लिखें"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"गलत पिन कोड."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"चार्ज हो गई है"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"चार्ज हो रही है"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"तेज़ी से चार्ज हो रही है"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="6637043106038550407">"धीरे चार्ज हो रही है"</string>
     <string name="keyguard_low_battery" msgid="9218432555787624490">"अपना चार्जर कनेक्‍ट करें."</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8566679946700751371">"अनलॉक करने के लिए मेनू दबाएं."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="8566679946700751371">"लॉक खोलने के लिए मेन्यू दबाएं."</string>
     <string name="keyguard_network_locked_message" msgid="6743537524631420759">"नेटवर्क लॉक किया हुआ है"</string>
     <string name="keyguard_missing_sim_message_short" msgid="6327533369959764518">"कोई SIM कार्ड नहीं है"</string>
     <string name="keyguard_missing_sim_message" product="tablet" msgid="4550152848200783542">"टैबलेट में कोई SIM कार्ड नहीं है."</string>
@@ -42,7 +44,7 @@
     <string name="keyguard_missing_sim_instructions" msgid="7350295932015220392">"SIM कार्ड लगाएं."</string>
     <string name="keyguard_missing_sim_instructions_long" msgid="589889372883904477">"SIM कार्ड मौजूद नहीं है या उसे पढ़ा नहीं जा सकता है. कोई SIM कार्ड लगाएं."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="654102080186420706">"बेकार SIM कार्ड."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="4683178224791318347">"आपका SIM कार्ड हमेशा के लिए अक्षम कर दिया गया है.\n दूसरे SIM कार्ड के लिए अपने वायरलेस सेवा प्रदाता से संपर्क करें."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="4683178224791318347">"आपका सिम कार्ड हमेशा के लिए बंद कर दिया गया है.\n दूसरे सिम कार्ड के लिए अपने वायरलेस सेवा देने वाले से संपर्क करें."</string>
     <string name="keyguard_sim_locked_message" msgid="953766009432168127">"SIM कार्ड लॉक किया हुआ है."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="1772789643694942073">"SIM कार्ड को PUK के ज़रिए लॉक किया हुआ है."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="3586601150825821675">"SIM कार्ड अनलॉक हो रहा है…"</string>
@@ -50,7 +52,8 @@
     <string name="keyguard_accessibility_sim_pin_area" msgid="912702510825058921">"SIM पिन क्षेत्र"</string>
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM 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="keyboardview_keycode_delete" msgid="6883116827512721630">"मिटाएं"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM अक्षम करें"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"पैटर्न भूल गए हैं"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"गलत पैटर्न"</string>
@@ -58,12 +61,13 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"गलत पिन"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"अपना पैटर्न बनाएं"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM पिन डालें"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" का SIM पिन डालें"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"सिम पिन डालें."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" के लिए सिम पिन डालें"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"मोबाइल सेवा के बिना डिवाइस का उपयोग करने के लिए 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">"SIM अब अक्षम हो गया है. जारी रखने के लिए PUK कोड डालें. विवरण के लिए वाहक से संपर्क करें."</string>
-    <string name="kg_puk_enter_puk_hint_multi" msgid="1373131883510840794">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" का SIM अब अक्षम हो गया है. जारी रखने के लिए PUK कोड डालें. विवरण के लिए वाहक से संपर्क करें."</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">"SIM कार्ड अनलॉक हो रहा है…"</string>
@@ -74,27 +78,27 @@
     <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>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7724148763268377734">"आप अपना पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से लिख चुके हैं. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"आपने अपना अनलॉक पैटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से बनाया है. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"आपने अपने लॉक खोलने के पैटर्न को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से ड्रॉ किया है. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1629351522209932316">"आपने टैबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश की है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल कोशिशों के बाद, इस टैबलेट को रीसेट कर दिया जाएगा, जिससे इसका सारा डेटा हट जाएगा."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="3921998703529189931">"आपने फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश की है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल कोशिशों के बाद, इस फ़ोन को रीसेट कर दिया जाएगा, जिससे इसका सारा डेटा हट जाएगा."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="4694232971224663735">"आपने टैबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से कोशिश की है. इस टैबलेट को रीसेट कर दिया जाएगा, जिससे इसका सारा डेटा हट जाएगा."</string>
     <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_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 पिन कोड, अपने डिवाइस को अनलॉक करने के लिए अब आपको अपने वाहक से संपर्क करना होगा."</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 पिन कोड, अपने डिवाइस को अनलॉक करने के लिए अब आपको अपनी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करना होगा."</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="4314341367727055967">
-      <item quantity="one">SIM पिन कोड गलत है, आप <xliff:g id="NUMBER_1">%d</xliff:g> बार और कोशिश कर सकते हैं.</item>
-      <item quantity="other">SIM पिन कोड गलत है, आप <xliff:g id="NUMBER_1">%d</xliff:g> बार और कोशिश कर सकते हैं.</item>
+      <item quantity="one">गलत सिम पिन कोड, आप <xliff:g id="NUMBER_1">%d</xliff:g> बार और कोशिश कर सकते हैं.</item>
+      <item quantity="other">गलत सिम पिन कोड, आप <xliff:g id="NUMBER_1">%d</xliff:g> बार और कोशिश कर सकते हैं.</item>
     </plurals>
-    <string name="kg_password_wrong_puk_code_dead" msgid="3329017604125179374">"SIM बेकार हो गया है. अपने वाहक से संपर्क करें."</string>
+    <string name="kg_password_wrong_puk_code_dead" msgid="3329017604125179374">"SIM बेकार हो गया है. अपनी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करें."</string>
     <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="2287504898931957513">
       <item quantity="one">SIM PUK कोड गलत है, SIM के हमेशा के लिए बेकार हो जाने से पहले आप <xliff:g id="NUMBER_1">%d</xliff:g> बार और कोशिश कर सकते हैं.</item>
       <item quantity="other">SIM PUK कोड गलत है, SIM के हमेशा के लिए बेकार हो जाने से पहले आप <xliff:g id="NUMBER_1">%d</xliff:g> बार और कोशिश कर सकते हैं.</item>
@@ -103,14 +107,14 @@
     <string name="kg_password_puk_failed" msgid="1331621440873439974">"SIM 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>
+    <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"इनपुट का तरीका बदलें"</string>
     <string name="airplane_mode" msgid="3807209033737676010">"हवाई जहाज़ मोड"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"डिवाइस फिर से चालू होने के बाद पैटर्न ज़रूरी है"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"डिवाइस फिर से चालू होने के बाद पिन ज़रूरी है"</string>
     <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"डिवाइस फिर से चालू होने के बाद पासवर्ड ज़रूरी है"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"अतिरिक्‍त सुरक्षा के लिए पैटर्न ज़रूरी है"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"अतिरिक्‍त सुरक्षा के लिए पिन ज़रूरी है"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"अतिरिक्‍त सुरक्षा के लिए पासवर्ड ज़रूरी है"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"अतिरिक्त सुरक्षा के लिए पैटर्न ज़रूरी है"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"अतिरिक्त सुरक्षा के लिए पिन ज़रूरी है"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"अतिरिक्त सुरक्षा के लिए पासवर्ड ज़रूरी है"</string>
     <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"प्रोफ़ाइल स्विच करते समय पैटर्न ज़रूरी है"</string>
     <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"प्रोफ़ाइल स्विच करते समय पिन ज़रूरी है"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"प्रोफ़ाइल स्विच करते समय पासवर्ड ज़रूरी है"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml
index 0cc452a..1862c9d 100644
--- a/packages/SystemUI/res-keyguard/values-hr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Unesite zaporku da biste otključali"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Unesite PIN da biste otključali"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN kôd nije točan."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Napunjeno"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Punjenje"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Brzo punjenje"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Područje PUK-a za SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Sljedeći alarm postavljen za <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Izbriši"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Onemogući eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Unos"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Zaboravili ste uzorak"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Pogrešan uzorak"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Pogrešan PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Pokušajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Iscrtajte svoj uzorak"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Unesite PIN za SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Unesite PIN za SIM mobilnog operatera \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Unesite PIN za SIM"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Unesite PIN za SIM mobilnog operatera \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Onemogućite eSIM kako biste uređaj upotrebljavali bez mobilne usluge."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Unesite PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Unesite zaporku"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM je sad onemogućen. Unesite PUK kôd da biste nastavili. Obratite se mobilnom operateru za više pojedinosti."</string>
diff --git a/packages/SystemUI/res-keyguard/values-hu/strings.xml b/packages/SystemUI/res-keyguard/values-hu/strings.xml
index 32f2f47..a7ce5296 100644
--- a/packages/SystemUI/res-keyguard/values-hu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hu/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"A feloldáshoz írja be a jelszót"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"A feloldáshoz írja be a PIN-kódot"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Helytelen PIN-kód."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Feltöltve"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Töltés folyamatban"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Gyors töltés folyamatban"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"A SIM-kártyához tartozó PUK-kód mezője"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"A következő ébresztés beállított ideje: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Törlés"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Az e-SIM-kártya letiltása"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Elfelejtettem a mintát"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Helytelen minta"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Helytelen PIN-kód"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Próbálja újra <xliff:g id="NUMBER">%d</xliff:g> másodperc múlva."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Rajzolja le a mintát"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Adja meg a SIM-kártya PIN-kódját"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Adja meg a(z) „<xliff:g id="CARRIER">%1$s</xliff:g>” SIM-kártya PIN-kódját"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Adja meg a SIM-kártya PIN-kódját."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Adja meg a(z) „<xliff:g id="CARRIER">%1$s</xliff:g>” SIM-kártya PIN-kódját."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Tiltsa le az e-SIM-kártyát az eszköz mobilszolgáltatás nélküli használatához."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Adja meg a PIN-kódot"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Írja be a jelszót"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"A SIM-kártya le van tiltva. A folytatáshoz adja meg a PUK-kódot. A részletekért vegye fel a kapcsolatot szolgáltatójával."</string>
diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml
index 9433ae3..3279074 100644
--- a/packages/SystemUI/res-keyguard/values-hy/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Ապակողպելու համար մուտքագրեք գաղտնաբառը"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Ապակողպելու համար մուտքագրեք PIN կոդը"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN կոդը սխալ է։"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Լիցքավորված է"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Լիցքավորում"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Արագ լիցքավորում"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM քարտի 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">"Անջատել էլեկտրոնային SIM քարտը"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Մուտքի ստեղն"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Մոռացել եմ նախշը"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Նախշը սխալ է"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN կոդը սխալ է"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Փորձեք կրկին <xliff:g id="NUMBER">%d</xliff:g> վայրկյանից:"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Մուտքագրեք նախշը"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Մուտքագրեք SIM քարտի PIN կոդը"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Մուտքագրեք SIM քարտի PIN կոդը «<xliff:g id="CARRIER">%1$s</xliff:g>»-ի համար"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Մուտքագրեք SIM քարտի PIN կոդը։"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Մուտքագրեք SIM քարտի PIN կոդը «<xliff:g id="CARRIER">%1$s</xliff:g>»-ի համար:"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Անջատել էլեկտրոնային SIM քարտը՝ սարքն առանց բջջային ծառայությունների օգտագործելու համար:"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Մուտքագրեք PIN-ը"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Մուտքագրեք գաղտնաբառը"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM քարտն այժմ անջատված է: Շարունակելու համար մուտքագրեք PUK կոդը: Մանրամասն տեղեկություններ ստանալու համար դիմեք օպերատորին:"</string>
diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml
index fba6df2..3385f23 100644
--- a/packages/SystemUI/res-keyguard/values-in/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-in/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Ketik sandi untuk membuka kunci"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Ketik PIN untuk membuka kunci"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Kode PIN salah."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Terisi"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Mengisi daya"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Mengisi daya dengan cepat"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Bidang PUK SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Alarm berikutnya disetel untuk <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Hapus"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Nonaktifkan eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Masukkan"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Lupa Pola?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Pola Salah"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN Salah"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Coba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> detik."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Gambar pola Anda"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Masukkan PIN SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Masukkan PIN SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Masukkan PIN SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Masukkan PIN SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Nonaktifkan eSIM untuk menggunakan perangkat tanpa layanan seluler."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Masukkan PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Masukkan Sandi"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM telah dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Hubungi operator untuk keterangan selengkapnya."</string>
diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml
index 90e378c..21bc49e 100644
--- a/packages/SystemUI/res-keyguard/values-is/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-is/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Sláðu inn aðgangsorðið til að opna"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Sláðu inn PIN-númer til að opna"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Rangt PIN-númer."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Fullhlaðin"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Í hleðslu"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Hröð hleðsla"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"PUK-svæði SIM-korts"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Næsti vekjari stilltur á <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Eyða"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Aftengja eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Færa inn"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Man ekki mynstrið"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Rangt mynstur"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Rangt PIN-númer"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Reyndu aftur eftir <xliff:g id="NUMBER">%d</xliff:g> sekúndur."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Teiknaðu mynstrið þitt"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Sláðu inn PIN-númer SIM-kortsins"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Sláðu inn PIN-númer SIM-korts fyrir „<xliff:g id="CARRIER">%1$s</xliff:g>“"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Sláðu inn PIN-númer SIM-kortsins."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Sláðu inn PIN-númer SIM-korts fyrir „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Aftengdu eSIM til að nota tækið án farsímakerfisþjónustu."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Sláðu inn PIN-númer"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Sláðu inn aðgangsorð"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortið hefur verið gert óvirkt. Sláðu inn PUK-númerið til að halda áfram. Hafðu samband við símafyrirtækið til að fá frekari upplýsingar."</string>
diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml
index 47181ca..aa3062e 100644
--- a/packages/SystemUI/res-keyguard/values-it/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-it/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Inserisci password per sbloccare"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Inserisci PIN per sbloccare"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Codice PIN errato."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Carico"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"In carica"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Ricarica veloce"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Area PUK SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Prossima sveglia impostata a: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Elimina"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Disattiva eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Invio"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Sequenza dimenticata"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Sequenza sbagliata"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN errato"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Riprova fra <xliff:g id="NUMBER">%d</xliff:g> secondi."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Inserisci la sequenza"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Inserisci il PIN della SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Inserisci il PIN della scheda SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Inserisci il PIN della SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Inserisci il PIN della SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Disattiva l\'eSIM per usare il dispositivo senza servizio dati mobile."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Inserisci PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Inserisci la password"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La scheda SIM è disattivata. Inserisci il codice PUK per continuare. Contatta l\'operatore per avere informazioni dettagliate."</string>
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index 2efa1a8..9899958b 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"הזן סיסמה לביטול הנעילה"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"הזן את קוד הגישה לביטול הנעילה"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"קוד הגישה שגוי"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"הסוללה טעונה"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"הסוללה נטענת"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"הסוללה נטענת מהר"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"‏אזור לקוד הגישה של כרטיס ה-SIM"</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">"Delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"‏השבתת ה-eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"שכחתי את קו ביטול הנעילה"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"קו ביטול הנעילה שגוי"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"קוד הגישה שגוי"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"נסה שוב בעוד <xliff:g id="NUMBER">%d</xliff:g> שניות."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"שרטט את קו ביטול הנעילה"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"‏הזן את קוד הגישה של כרטיס ה-SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"‏הזן את קוד הגישה של כרטיס ה-SIM של \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"‏הזן את קוד הגישה של כרטיס ה-SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"‏הזן את קוד הגישה של כרטיס ה-SIM של <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"‏השבת את ה-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">"‏כרטיס ה-SIM מושבת כעת. הזן קוד PUK כדי להמשיך. פנה אל הספק לפרטים."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index 9a96f7e..4c2d4e3 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -29,6 +29,7 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"ロックを解除するにはパスワードを入力してください"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"ロックを解除するには PIN を入力してください"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN コードが無効です。"</string>
+    <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"無効なカードです。"</string>
     <string name="keyguard_charged" msgid="2222329688813033109">"充電が完了しました"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"充電しています"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"急速充電しています"</string>
@@ -51,6 +52,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM 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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"入力"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"パターンを忘れた場合"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"パターンが正しくありません"</string>
@@ -58,8 +60,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN が正しくありません"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> 秒後にもう一度お試しください。"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"パターンを入力してください"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN を入力してください"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"「<xliff:g id="CARRIER">%1$s</xliff:g>」の SIM PIN を入力してください"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN を入力してください。"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"「<xliff:g id="CARRIER">%1$s</xliff:g>」の SIM PIN を入力してください。"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"モバイル サービスなしで端末を使用するには eSIM を無効にしてください。"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN を入力してください"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"パスワードを入力してください"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM が無効になりました。続行するには PUK コードを入力してください。詳しくは携帯通信会社にお問い合わせください。"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml
index 74ae02a..ed1e0b3 100644
--- a/packages/SystemUI/res-keyguard/values-ka/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"განსაბლოკად აკრიფეთ პაროლი"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"განსაბლოკად აკრიფეთ PIN-კოდი"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN-კოდი არასწორია."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"დატენილია"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"მიმდინარეობს დატენა"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"მიმდინარეობს სწრაფი დატენა"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM ბარათის 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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"შეყვანა"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"დაგავიწყდათ ნიმუში"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ნიმუში არასწორია"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN-კოდი არასწორია"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"ცადეთ ხელახლა <xliff:g id="NUMBER">%d</xliff:g> წამში."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"დახატეთ თქვენი ნიმუში"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"შეიყვანეთ SIM ბარათის PIN-კოდი"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"შეიყვანეთ SIM ბარათის PIN-კოდი „<xliff:g id="CARRIER">%1$s</xliff:g>“-სთვის"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"შეიყვანეთ SIM ბარათის PIN-კოდი."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"შეიყვანეთ SIM ბარათის PIN-კოდი „<xliff:g id="CARRIER">%1$s</xliff:g>“-ისთვის."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"გათიშეთ eSIM, მოწყობილობის მობილური სერვისების გარეშე გამოსაყენებლად."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"შეიყვანეთ PIN-კოდი"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"შეიყვანეთ პაროლი"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM ბარათი ახლა დეაქტივირებულია. გასაგრძელებლად შეიყვანეთ PUK-კოდი. დეტალური ინფორმაციისთვის დაუკავშირდით თქვენს ოპერატორს."</string>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index 8a088f3..3400de4 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Құлпын ашу үшін құпия сөзді теріңіз"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Құлпын ашу үшін PIN кодын енгізіңіз"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN коды қате"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Зарядталды"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Зарядталуда"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Жылдам зарядталуда"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM 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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Енгізу"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Өрнекті ұмытып қалдыңыз ба?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Өрнек қате"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN коды қате"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Өрнекті енгізіңіз"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN кодын енгізіңіз"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" үшін SIM PIN кодын енгізіңіз"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN кодын енгізіңіз."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" үшін SIM PIN кодын енгізіңіз."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Құрылғыны мобильдік қызметсіз пайдалану үшін eSIM картасын өшіріңіз."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN кодын енгізіңіз"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Кілтсөзді енгізіңіз"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM картасы өшірілді. Жалғастыру үшін PUK кодын енгізіңіз. Толығырақ ақпаратты оператордан алыңыз."</string>
diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml
index b4be59e..df4a5c8 100644
--- a/packages/SystemUI/res-keyguard/values-km/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-km/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"វាយ​បញ្ចូល​ពាក្យ​សម្ងាត់​ ដើម្បី​ដោះ​សោ"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"វាយ​បញ្ចូល​កូដ PIN ដើម្បី​ដោះ​សោ"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"កូដ PIN មិន​ត្រឹមត្រូវ​ទេ។"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"បាន​សាក​ថ្ម"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"កំពុង​សាក​ថ្ម"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"សាកយ៉ាងឆាប់រហ័ស"</string>
@@ -51,6 +53,7 @@
     <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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ភ្លេច​​លំនាំ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"លំនាំ​មិន​ត្រឹមត្រូវ​ទេ"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"កូដ PIN មិន​ត្រឹមត្រូវ​ទេ"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"សូម​ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER">%d</xliff:g> វិនាទី​ទៀត។"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"គូរ​លំនាំ​របស់​អ្នក"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"បញ្ចូល​កូដ PIN របស់​ស៊ីម"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"បញ្ចូល​កូដ PIN របស់​ស៊ីម​សម្រាប់ \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"បញ្ចូល​កូដ PIN របស់​ស៊ីម។"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"បញ្ចូល​កូដ PIN របស់​ស៊ីម​សម្រាប់ \"<xliff:g id="CARRIER">%1$s</xliff:g>\"។"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"បិទ eSIM ដើម្បីប្រើប្រាស់ឧបករណ៍​ដោយ​មិនចាំបាច់ប្រើសេវាកម្មទិន្នន័យចល័ត។"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"បញ្ចូល​កូដ PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"បញ្ចូល​ពាក្យ​សម្ងាត់"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ឥឡូវ​នេះ​ ស៊ីម​ត្រូវ​បាន​បិទ​ដំណើរការ​ហើយ។ បញ្ចូល​កូដ PUK ដើម្បី​បន្ត។ សូម​ទាក់ទង​ទៅក្រុមហ៊ុន​បម្រើ​សេវា​ទូរសព្ទ​របស់​អ្នក ដើម្បី​ទទួល​បាន​ព័ត៌មាន​លម្អិត។"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml
index b2dd79e..cd1db40 100644
--- a/packages/SystemUI/res-keyguard/values-kn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"ಅನ್‌ಲಾಕ್‌ ಮಾಡಲು ಪಾಸ್‌ವರ್ಡ್‌ ಟೈಪ್‌ ಮಾಡಿ"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"ಅನ್‌ಲಾಕ್‌ ಮಾಡಲು ಪಿನ್‌ ಟೈಪ್‌ ಮಾಡಿ"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ತಪ್ಪಾದ ಪಿನ್‌ ಕೋಡ್."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"ಚಾರ್ಜ್ ಆಗಿದೆ"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"ವೇಗವಾಗಿ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
@@ -51,6 +53,7 @@
     <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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"ನಮೂದಿಸಿ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ಪ್ಯಾಟರ್ನ್ ಮರೆತಿದ್ದೀರಿ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ಪ್ಯಾಟರ್ನ್ ತಪ್ಪಾಗಿದೆ"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"ಪಿನ್‌ ತಪ್ಪಾಗಿದೆ"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ನಿಮ್ಮ ಪ್ಯಾಟರ್ನ್ ಚಿತ್ರಿಸಿ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"ಸಿಮ್‌ ಪಿನ್‌ ನಮೂದಿಸಿ"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" ಗೆ ಸಿಮ್ ಪಿನ್ ನಮೂದಿಸಿ"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"ಸಿಮ್‌ ಪಿನ್‌ ನಮೂದಿಸಿ."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" ಗಾಗಿ ಸಿಮ್ ಪಿನ್ ನಮೂದಿಸಿ."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"ಮೊಬೈಲ್ ಸೇವೆ ಇಲ್ಲದೆಯೇ ಸಾಧನವನ್ನು ಬಳಸಲು 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">"ಈಗ ಸಿಮ್‌ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ. ಮುಂದುವರೆಯಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml
index 70588d3..0a16504 100644
--- a/packages/SystemUI/res-keyguard/values-ko/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"잠금 해제하려면 비밀번호 입력"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"잠금 해제하려면 PIN 입력"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"잘못된 PIN 코드입니다."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"충전됨"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"충전 중"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"고속 충전 중"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM 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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter 키"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"패턴을 잊음"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"잘못된 패턴"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"잘못된 PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g>초 후에 다시 시도하세요."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"패턴 그리기"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN 입력"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\'<xliff:g id="CARRIER">%1$s</xliff:g>\'의 SIM PIN 입력"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN을 입력하세요."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\'<xliff:g id="CARRIER">%1$s</xliff:g>\'의 SIM PIN을 입력하세요."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"모바일 서비스 없이 기기를 사용하려면 eSIM을 사용 중지하세요."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN 입력"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"비밀번호 입력"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM이 사용 중지되었습니다. 계속하려면 PUK 코드를 입력하세요. 자세한 내용은 이동통신사에 문의하시기 바랍니다."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index 8cbd4f5..c55bef4 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Кулпуну ачуу үчүн сырсөздү териңиз"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Кулпуну ачуу үчүн PIN-кодду териңиз"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN-код туура эмес."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Кубатталды"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Кубатталууда"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Ыкчам кубатталууда"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM-картанын 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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Киргизүү"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Графикалык ачкычты унутуп калдым"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Графикалык ачкыч туура эмес"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN-код туура эмес"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> секунддан кийин кайталаңыз."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Графикалык ачкычты тартыңыз"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM-картанын PIN-кодун киргизиңиз"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" байланыш операторунун SIM-картасынын PIN-кодун киргизиңиз"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM-картанын PIN-кодун киргизиңиз."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" SIM-картасынын PIN-кодун киргизиңиз."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Түзмөктү мобилдик кызматсыз колдонуу үчүн eSIM-картаны өчүрүңүз."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN-кодду киргизиңиз"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Сырсөздү киргизиңиз"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK-кодду киргизиңиз. Анын чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз."</string>
diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml
index d063827..ac7d49f3 100644
--- a/packages/SystemUI/res-keyguard/values-lo/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"ພິມລະຫັດເພື່ອປົດລັອກ"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"ພິມລະຫັດ PIN ເພື່ອປົດລັອກ"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ລະຫັດ PIN ບໍ່ຖືກຕ້ອງ."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"ສາກເຕັມແລ້ວ."</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"ກຳລັງສາກໄຟ"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"ກຳລັງສາກດ່ວນ"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"ພື້ນທີ່ PUK ຂອງ SIM"</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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"ປ້ອນເຂົ້າ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ລືມຮູບແບບປົດລັອກ?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ຮູບແບບຜິດ"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"ລະຫັດ PIN ບໍ່ຖືກຕ້ອງ"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"ລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER">%d</xliff:g> ວິນາທີ."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"ໃສ່ລະຫັດ PIN ຂອງຊິມ"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"ປ້ອນ SIM PIN ສຳລັບ \"<xliff:g id="CARRIER">%1$s</xliff:g>\" ເຂົ້າໄປ"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"ໃສ່ລະຫັດ PIN ຂອງຊິມ."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"ໃສ່ລະຫັດ PIN ຂອງຊິມສຳລັບ \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"ປິດການໃຊ້ eSIM ເພື່ອໃຊ້ອຸປະກອນໂດຍບໍ່ມີບໍລິການມືຖື."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"ໃສ່ລະຫັດ PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"ໃສ່ລະຫັດຜ່ານ"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ຊິມຖືກປິດການນຳໃຊ້ແລ້ວ. ປ້ອນລະຫັດ PUK ເພື່ອດຳເນີນການຕໍ່. ຕິດຕໍ່ຜູ່ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ."</string>
diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml
index 2dd3ed7..cafb2e37 100644
--- a/packages/SystemUI/res-keyguard/values-lt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Įveskite slaptažodį, kad atrakintumėte"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Įveskite PIN kodą, kad atrakintumėte"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Netinkamas PIN kodas."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Įkrauta"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Įkraunama"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Greitai įkraunama"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM kortelės PUK kodo sritis"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Kitas nustatytas signalas: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Ištrinti"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Išjungti eSIM kortelę"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Pamiršau atrakinimo piešinį"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Netinkamas atrakinimo piešinys"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Netinkamas PIN kodas"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Bandykite dar kartą po <xliff:g id="NUMBER">%d</xliff:g> sek."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Nupieškite atrakinimo piešinį"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Įveskite SIM kortelės PIN kodą"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Įveskite „<xliff:g id="CARRIER">%1$s</xliff:g>“ SIM kortelės PIN kodą"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Įveskite SIM kortelės PIN kodą."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Įveskite „<xliff:g id="CARRIER">%1$s</xliff:g>“ SIM kortelės PIN kodą"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Išjungti eSIM kortelę ir naudoti įrenginį be mobiliojo ryšio paslaugos."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Įveskite PIN kodą"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Įveskite slaptažodį"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Dabar SIM neleidžiama. Jei norite tęsti, įveskite PUK kodą. Jei reikia išsamios informacijos, susisiekite su operatoriumi."</string>
diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml
index 26ed490..0eafef8 100644
--- a/packages/SystemUI/res-keyguard/values-lv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Ievadiet paroli, lai atbloķētu."</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Ievadiet PIN kodu, lai atbloķētu."</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN kods nav pareizs."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Akumulators uzlādēts"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Notiek uzlāde"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Notiek ātrā uzlāde"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM kartes PUK apgabals"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nākamā signāla atskaņošanas laiks: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Dzēšanas taustiņš"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Atspējot eSIM karti"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Ievadīšanas taustiņš"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Aizmirsu kombināciju"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Nepareiza kombinācija."</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Nepareizs PIN kods."</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER">%d</xliff:g> sekundes(-ēm)."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Zīmējiet savu kombināciju."</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Ievadiet SIM kartes PIN kodu"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Ievadiet SIM kartes “<xliff:g id="CARRIER">%1$s</xliff:g>” PIN kodu"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Ievadiet SIM kartes PIN kodu."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Ievadiet SIM kartes “<xliff:g id="CARRIER">%1$s</xliff:g>” PIN kodu."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Atspējojiet eSIM karti, lai ierīci varētu izmantot bez mobilā pakalpojuma."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Ievadiet PIN."</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Ievadiet paroli"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM karte ir atspējota. Lai turpinātu, ievadiet PUK kodu. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru."</string>
diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml
index e757c51..d25d86b 100644
--- a/packages/SystemUI/res-keyguard/values-mk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Напишете ја лозинката за да отклучите"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Напишете PIN-код за да отклучите"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Погрешен PIN-код."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Полна"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Се полни"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Брзо полнење"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Поле за PUK на SIM"</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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Внеси"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Ја заборавивте шемата?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Погрешна шема"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Погрешен PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Обидете се повторно за <xliff:g id="NUMBER">%d</xliff:g> секунди."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Нацртајте ја шемата"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Внесете PIN на SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Внесете PIN на SIM за „<xliff:g id="CARRIER">%1$s</xliff:g>“"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Внесете PIN на SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Внесете PIN на SIM за „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Оневозможете ја eSIM за да го користите уредот без мобилна услуга."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Внесете PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Внесете лозинка"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-картичката сега е оневозможена. Внесете PUK-код за да продолжите. Контактирајте со операторот за детали."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml
index 5abf129..dc070d4 100644
--- a/packages/SystemUI/res-keyguard/values-ml/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"അൺലോക്കുചെയ്യുന്നതിന് പാസ്‌വേഡ് ടൈപ്പുചെയ്യുക"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"അൺലോക്കുചെയ്യുന്നതിന് പിൻ ടൈപ്പുചെയ്യുക"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"പിൻ കോഡ് തെറ്റാണ്."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"ചാർജായി"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"ചാർജ്ജുചെയ്യുന്നു"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"വേഗത്തിൽ ചാർജുചെയ്യുന്നു"</string>
@@ -51,6 +53,7 @@
     <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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"എന്റർ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"പാറ്റേൺ മറന്നു"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"പാറ്റേൺ തെറ്റാണ്"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"പിൻ തെറ്റാണ്"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> സെക്കന്റിനു‌ശേഷം വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"നിങ്ങളുടെ പാറ്റേൺ വരയ്‌ക്കുക"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"സിം പിൻ നൽകുക"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" എന്നതിനുള്ള സിം പിൻ നൽകുക"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"സിം പിൻ നൽകുക."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" എന്ന കാരിയർക്കുള്ള സിം പിൻ നൽകുക."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"മൊ‌ബൈൽ സേവനമില്ലാതെ ഉപകരണം ഉപയോഗിക്കാൻ 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">"സിം ഇപ്പോൾ പ്രവർത്തനരഹിതമാക്കി. തുടരുന്നതിന് PUK കോഡ് നൽകുക. വിശദാംശങ്ങൾക്ക് കാരിയറെ ബന്ധപ്പെടുക."</string>
diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml
index eb045bb..6d81a7a 100644
--- a/packages/SystemUI/res-keyguard/values-mn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Түгжээг тайлахын тулд нууц үгийг оруулна уу"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Түгжээг тайлахын тулд ПИН кодыг оруулна уу"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ПИН код буруу байна."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Цэнэглэсэн"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Цэнэглэж байна"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Хурдан цэнэглэж байна"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM-н 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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Оруулах"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Загварыг мартсан"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Загвар буруу байна"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"ПИН код буруу байна"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Загварыг оруулна уу"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM-н ПИН-г оруулна уу"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\"-н SIM-н ПИН-г оруулна уу"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM-н ПИН-г оруулна уу."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\"-н SIM-н ПИН-г оруулна уу."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Төхөөрөмжийг мобайл үйлчилгээгүй ашиглахын тулд 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">"SIM идэвхгүй байна. Үргэлжлүүлэх бол PUK кодыг оруулна уу. Дэлгэрэнгүй мэдээлэл авах бол оператор компанитайгаа холбогдоно уу."</string>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index 946a2dd..20b352c 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"अनलॉक करण्यासाठी संकेतशब्द टाइप करा"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"अनलॉक करण्यासाठी पिन टाइप करा"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"चुकीचा पिन कोड."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"चार्ज झाली"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"चार्ज होत आहे"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"द्रुतपणे चार्ज होत आहे"</string>
@@ -51,15 +53,17 @@
     <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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"प्रविष्ट करा"</string>
-    <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"नमुना विसरलात"</string>
-    <string name="kg_wrong_pattern" msgid="7620081431514773802">"चुकीचा नमुना"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"पॅटर्न विसरलात"</string>
+    <string name="kg_wrong_pattern" msgid="7620081431514773802">"चुकीचा पॅटर्न"</string>
     <string name="kg_wrong_password" msgid="4580683060277329277">"चुकीचा संकेतशब्द"</string>
     <string name="kg_wrong_pin" msgid="4785660766909463466">"चुकीचा पिन"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="kg_pattern_instructions" msgid="5547646893001491340">"आपला नमुना काढा"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"सिम पिन प्रविष्ट करा"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" साठी सिम पिन प्रविष्ट करा"</string>
+    <string name="kg_pattern_instructions" msgid="5547646893001491340">"तुमचा पॅटर्न काढा"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"सिम पिन एंटर करा"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" साठी सिम पिन एंटर करा"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"मोबाइल सेवांशिवाय डिव्हाइस वापरण्यासाठी 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">"सिम आता अक्षम केले आहे. सुरू ठेवण्यासाठी PUK कोड प्रविष्ट करा. तपशीलांसाठी वाहकाशी संपर्क साधा."</string>
@@ -71,10 +75,10 @@
     <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_login_too_many_attempts" msgid="6604574268387867255">"खूप जास्त पॅटर्न प्रयत्न"</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8637788033282252027">"आपण आपला PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने टाइप केला आहे. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7724148763268377734">"आपण आपला संकेतशब्द <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने टाइप केला आहे. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"आपण आपला अनलॉक नमुना <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने काढला. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"तुम्ही आपला अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने काढला. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1629351522209932316">"आपण टॅबलेट अनलॉक करण्याचा <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, हे टॅबलेट रीसेट केला जाईल, जे त्याचा सर्व डेटा हटवेल."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="3921998703529189931">"आपण फोन अनलॉक करण्याचा <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, हा फोन रीसेट केला जाईल, जे त्याचा सर्व डेटा हटवेल."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="4694232971224663735">"आपण टॅबलेट अनलॉक करण्याचा <xliff:g id="NUMBER">%d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. हे टॅबलेट रीसेट केले जाईल, जे त्याचा सर्व डेटा हटवेल."</string>
@@ -87,12 +91,12 @@
     <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">"सिम पिन कोड चुकीचा आहे आपण आता आपले डिव्‍हाइस अनलॉक करण्‍यासाठी आपल्‍या वाहकाशी संपर्क साधावा."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="956706236554092172">"तुम्ही आपला अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुमच्याला ईमेल खाते वापरून आपला टॅब्लेट अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"तुम्ही आपला अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुमच्याला ईमेल खाते वापरून आपला फोन अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="kg_password_wrong_pin_code_pukked" msgid="3389829202093674267">"सिम पिन कोड चुकीचा आहे तुम्ही आता तुमचे डिव्हाइस अनलॉक करण्‍यासाठी तुमच्या वाहकाशी संपर्क साधावा."</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="4314341367727055967">
-      <item quantity="one">चुकीचा सिम पिन कोड, आपल्‍याकडे <xliff:g id="NUMBER_1">%d</xliff:g> प्रयत्न शिल्लक आहे.</item>
-      <item quantity="other">चुकीचा सिम पिन कोड, आपल्‍याकडे <xliff:g id="NUMBER_1">%d</xliff:g> प्रयत्न शिल्लक आहेत.</item>
+      <item quantity="one">चुकीचा सिम पिन कोड, तुमच्याकडे <xliff:g id="NUMBER_1">%d</xliff:g> प्रयत्न शिल्लक आहेत.</item>
+      <item quantity="other">चुकीचा सिम पिन कोड, तुमच्याकडे <xliff:g id="NUMBER_1">%d</xliff:g> प्रयत्न शिल्लक आहेत.</item>
     </plurals>
     <string name="kg_password_wrong_puk_code_dead" msgid="3329017604125179374">"सिम निरुपयोगी आहे. आपल्या वाहकाशी संपर्क साधा."</string>
     <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="2287504898931957513">
@@ -105,28 +109,28 @@
     <string name="keyguard_carrier_default" msgid="4274828292998453695">"सेवा नाही."</string>
     <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"इनपुट पद्धत स्विच करा"</string>
     <string name="airplane_mode" msgid="3807209033737676010">"विमान मोड"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"डिव्हाइस रीस्टार्ट झाल्यावर नमुना आवश्यक आहे"</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"डिव्हाइस रीस्टार्ट झाल्यावर पॅटर्न आवश्यक आहे"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"डिव्हाइस रीस्टार्ट झाल्यावर पिन आवश्यक आहे"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"डिव्हाइस रीस्टार्ट झाल्यावर संकेतशब्द आवश्यक आहे"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"अतिरिक्त सुरक्षिततेसाठी नमुना आवश्‍यक आहे"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"डिव्हाइस रीस्टार्ट झाल्यावर पासवर्ड आवश्यक आहे"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"अतिरिक्त सुरक्षिततेसाठी पॅटर्न आवश्‍यक आहे"</string>
     <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"अतिरिक्त सुरक्षिततेसाठी पिन आवश्‍यक आहे"</string>
     <string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"अतिरिक्त सुरक्षिततेसाठी संकेतशब्द आवश्‍यक आहे"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"आपण प्रोफाईल स्विच करता तेव्‍हा नमुना आवश्‍यक आहे"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"तुम्ही प्रोफाईल स्विच करता तेव्‍हा पॅटर्न आवश्‍यक आहे"</string>
     <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"आपण प्रोफाईल स्विच करता तेव्‍हा पिन आवश्‍यक आहे"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"आपण प्रोफाईल स्विच करता तेव्‍हा संकेतशब्द आवश्‍यक आहे"</string>
     <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"प्रशासकाद्वारे लॉक केलेले डिव्हाइस"</string>
-    <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"डिव्हाइस व्यक्तिचलितरित्या लॉक केले होते"</string>
+    <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"डिव्हाइस मॅन्युअली लॉक केले होते"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="71299470072448533">
-      <item quantity="one">डिव्‍हाइस <xliff:g id="NUMBER_1">%d</xliff:g> तासासाठी अनलॉक केले गेले नाही. नमुन्याची पुष्टी करा.</item>
-      <item quantity="other">डिव्‍हाइस <xliff:g id="NUMBER_1">%d</xliff:g> तासांसाठी अनलॉक केले गेले नाही. नमुन्याची पुष्टी करा.</item>
+      <item quantity="one">डिव्हाइस <xliff:g id="NUMBER_1">%d</xliff:g> तासासाठी अनलॉक केले गेले नाही. पॅटर्नची खात्री करा.</item>
+      <item quantity="other">डिव्हाइस <xliff:g id="NUMBER_1">%d</xliff:g> तासांसाठी अनलॉक केले गेले नाही. पॅटर्नची खात्री करा.</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="34586942088144385">
-      <item quantity="one">डिव्‍हाइस <xliff:g id="NUMBER_1">%d</xliff:g> तासासाठी अनलॉक केले गेले नाही. पिन ची पुष्टी करा.</item>
-      <item quantity="other">डिव्‍हाइस <xliff:g id="NUMBER_1">%d</xliff:g> तासांसाठी अनलॉक केले गेले नाही. पिन ची पुष्टी करा.</item>
+      <item quantity="one">डिव्हाइस <xliff:g id="NUMBER_1">%d</xliff:g> तासासाठी अनलॉक केले गेले नाही. पिनची खात्री करा.</item>
+      <item quantity="other">डिव्हाइस <xliff:g id="NUMBER_1">%d</xliff:g> तासांसाठी अनलॉक केले गेले नाही. पिन ची खात्री करा.</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_password" formatted="false" msgid="257297696215346527">
-      <item quantity="one">डिव्‍हाइस <xliff:g id="NUMBER_1">%d</xliff:g> तासासाठी अनलॉक केले गेले नाही. संकेतशब्दाची पुष्टी करा.</item>
-      <item quantity="other">डिव्‍हाइस <xliff:g id="NUMBER_1">%d</xliff:g> तासांसाठी अनलॉक केले गेले नाही. संकेतशब्दाची पुष्टी करा.</item>
+      <item quantity="one">डिव्हाइस <xliff:g id="NUMBER_1">%d</xliff:g> तासासाठी अनलॉक केले गेले नाही. पासवर्डची खात्री करा.</item>
+      <item quantity="other">डिव्हाइस <xliff:g id="NUMBER_1">%d</xliff:g> तासांसाठी अनलॉक केले गेले नाही. पासवर्डची खात्री करा.</item>
     </plurals>
     <string name="fingerprint_not_recognized" msgid="348813995267914625">"ओळखले नाही"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml
index 197965f..a68fa0a 100644
--- a/packages/SystemUI/res-keyguard/values-ms/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Taip kata laluan untuk membuka kunci"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Taip PIN untuk membuka kunci"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Kod PIN salah."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Sudah dicas"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Mengecas"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Mengecas dengan cepat"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Bahagian PUK SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Penggera seterusnya ditetapkan pada <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Padam"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Lumpuhkan eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Kekunci Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Terlupa Corak"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Corak salah"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN salah"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Cuba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> saat."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Lukis corak anda"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Masukkan PIN SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Masukkan PIN SIM untuk \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Masukkan PIN SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Masukkan PIN SIM untuk \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Lumpuhkan eSIM untuk menggunakan peranti tanpa perkhidmatan mudah alih."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Masukkan PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Masukkan Kata Laluan"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM kini dilumpuhkan. Masukkan kod PUK untuk meneruskan. Hubungi pembawa untuk mendapatkan butiran."</string>
diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml
index b052b21..391b9e9 100644
--- a/packages/SystemUI/res-keyguard/values-my/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-my/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"လော့ခ်ဖွင့်ရန် စကားဝှက်ကို ထည့်ပါ"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"လော့ခ်ဖွင့်ရန် ပင်နံပါတ်ထည့်ပါ"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ပင်နံပါတ် မှားနေသည်။"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"အားသွင်းပြီးပါပြီ"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"အားသွင်းနေပါသည်"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"လျှင်မြန်စွာ အားသွင်းနေသည်"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"ဆင်းမ် ပင်နံပါတ် ပြန်ဖွင့်သည့်ကုဒ် နေရာ"</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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter ခလုတ်"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ပုံစံအား မေ့သွားပါသည်"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ပုံစံ မမှန်ကန်ပါ"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"ပင်နံပါတ် မမှန်ကန်ပါ"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> စက္ကန့်အကြာတွင် ထပ်လုပ်ကြည့်ပါ။"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ပုံစံကို ဆွဲပါ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"ဆင်းမ်ကဒ် ပင်နံပါတ်ကို ထည့်ပါ"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" အတွက် ဆင်းမ်ပင်နံပါတ်ကို ထည့်ပါ"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"ဆင်းမ်ကဒ် ပင်နံပါတ်ကို ထည့်ပါ။"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" အတွက် ဆင်းမ်ကဒ်ပင်နံပါတ်ကို ထည့်ပါ။"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"စက်ပစ္စည်းကို မိုဘိုင်းဝန်ဆောင်မှုမပါဘဲ အသုံးပြုရန် 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>
diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml
index 2ba38ec..dbc54c2 100644
--- a/packages/SystemUI/res-keyguard/values-nb/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Skriv inn passordet for å låse opp"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Skriv inn PIN-koden for å låse opp"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Feil PIN-kode."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Oppladet"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Lader"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Lader raskt"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"PUK-området for SIM-kortet"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Neste alarm er stilt inn for <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Slett"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Deaktiver e-SIM-kortet"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Har du glemt mønsteret?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Feil mønster"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Feil PIN-kode"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Prøv på nytt om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Tegn mønsteret ditt"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Skriv inn PIN-koden for SIM-kortet"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Skriv inn PIN-koden for SIM-kortet «<xliff:g id="CARRIER">%1$s</xliff:g>»"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Skriv inn PIN-koden for SIM-kortet."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Skriv inn PIN-koden for SIM-kortet «<xliff:g id="CARRIER">%1$s</xliff:g>»."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Deaktiver e-SIM-kortet for å bruke enheten uten mobiltjeneste."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Skriv inn PIN-koden"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Skriv inn passordet"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortet er nå deaktivert. Skriv inn PUK-koden for å fortsette. Ta kontakt med operatøren for mer informasjon."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index fa5f284..568059d 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"अनलक गर्न पासवर्ड टाइप गर्नुहोस्"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"अनलक गर्न PIN कोड टाइप गर्नुहोस्"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN कोड गलत छ।"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"चार्ज भयो"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"चार्ज हुँदै"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"छिटो चार्ज हुँदै"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM को 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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"प्रविष्टि गर्नुहोस्"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ढाँचा बिर्सनुभयो"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"गलत ढाँचा"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"गलत PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"आफ्नो ढाँचा कोर्नुहोस्"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM को PIN प्रविष्टि गर्नुहोस्"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"<xliff:g id="CARRIER">%1$s</xliff:g> को SIM PIN प्रविष्ट गर्नुहोस्"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM को PIN प्रविष्टि गर्नुहोस्।"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" को SIM को PIN प्रविष्ट गर्नुहोस्।"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"मोबाइल सेवा बिना यन्त्रको प्रयोग गर्न eSIM लाई असक्षम पार्नुहोस्।"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN प्रविष्टि गर्नुहोस्"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"पासवर्ड प्रविष्ट गर्नुहोस्"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM कार्ड अहिले असक्षम छ। सुचारु गर्नको लागि PUK कोड प्रविष्ट गर्नुहोस्।  विवरणको लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index 4da7398..f0be94b4 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Typ het wachtwoord om te ontgrendelen"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Typ pincode om te ontgrendelen"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Onjuiste pincode."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Opgeladen"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Opladen"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Snel opladen"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Gebied voor pukcode van simkaart"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Volgende alarm ingesteld voor <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Simkaart uitschakelen"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Patroon vergeten"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Onjuist patroon"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Onjuiste pincode"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Probeer het over <xliff:g id="NUMBER">%d</xliff:g> seconden opnieuw."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Teken je patroon"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Geef de pincode van de simkaart op"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Geef de pincode op voor de simkaart van \'<xliff:g id="CARRIER">%1$s</xliff:g>\'"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Geef de pincode van de simkaart op."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Geef de pincode voor de simkaart van \'<xliff:g id="CARRIER">%1$s</xliff:g>\' op."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Schakel de e-simkaart uit om het apparaat te gebruiken zonder mobiele service."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Geef je pincode op"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Geef je wachtwoord op"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"De simkaart is nu uitgeschakeld. Geef de pukcode op om door te gaan. Neem contact op met de provider voor informatie."</string>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index 82bd400..b17eebd 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -21,112 +21,116 @@
 <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="3171996292755059205">"ਕੀ-ਗਾਰਡ"</string>
-    <string name="keyguard_password_enter_pin_code" msgid="3420548423949593123">"PIN ਕੋਡ ਟਾਈਪ ਕਰੋ"</string>
-    <string name="keyguard_password_enter_puk_code" msgid="670683628782925409">"SIM PUK ਅਤੇ ਨਵਾਂ PIN ਕੋਡ ਟਾਈਪ ਕਰੋ"</string>
-    <string name="keyguard_password_enter_puk_prompt" msgid="3747778500166059332">"SIM PUK ਕੋਡ"</string>
-    <string name="keyguard_password_enter_pin_prompt" msgid="8188243197504453830">"ਨਵਾਂ SIM PIN ਕੋਡ"</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>
-    <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"ਅਨਲੌਕ ਕਰਨ ਲਈ PIN ਟਾਈਪ ਕਰੋ"</string>
-    <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ਗਲਤ PIN ਕੋਡ।"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3420548423949593123">"ਪਿੰਨ ਕੋਡ ਟਾਈਪ ਕਰੋ"</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>
+    <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਪਿੰਨ ਟਾਈਪ ਕਰੋ"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ਗਲਤ ਪਿੰਨ ਕੋਡ।"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"ਚਾਰਜ ਹੋ ਗਿਆ"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"ਤੇਜ਼ੀ ਨਾਲ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="6637043106038550407">"ਹੌਲੀ-ਹੌਲੀ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="keyguard_low_battery" msgid="9218432555787624490">"ਆਪਣਾ ਚਾਰਜਰ ਕਨੈਕਟ ਕਰੋ।"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8566679946700751371">"ਅਨਲੌਕ ਕਰਨ ਲਈ \"ਮੀਨੂ\" ਦਬਾਓ।"</string>
-    <string name="keyguard_network_locked_message" msgid="6743537524631420759">"ਨੈੱਟਵਰਕ ਲੌਕ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="keyguard_missing_sim_message_short" msgid="6327533369959764518">"ਕੋਈ SIM ਕਾਰਡ ਮੌਜੂਦ ਨਹੀਂ"</string>
-    <string name="keyguard_missing_sim_message" product="tablet" msgid="4550152848200783542">"ਟੈਬਲੈੱਟ ਵਿੱਚ ਕੋਈ SIM ਕਾਰਡ ਮੌਜੂਦ ਨਹੀਂ।"</string>
-    <string name="keyguard_missing_sim_message" product="default" msgid="6585414237800161146">"ਫ਼ੋਨ ਵਿੱਚ ਕੋਈ SIM ਕਾਰਡ ਮੌਜੂਦ ਨਹੀਂ।"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="8566679946700751371">"ਅਣਲਾਕ ਕਰਨ ਲਈ \"ਮੀਨੂ\" ਦਬਾਓ।"</string>
+    <string name="keyguard_network_locked_message" msgid="6743537524631420759">"ਨੈੱਟਵਰਕ  ਲਾਕ  ਕੀਤਾ ਗਿਆ"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="6327533369959764518">"ਕੋਈ ਸਿਮ ਕਾਰਡ ਨਹੀਂ"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="4550152848200783542">"ਟੈਬਲੈੱਟ ਵਿੱਚ ਕੋਈ ਸਿਮ ਕਾਰਡ ਮੌਜੂਦ ਨਹੀਂ।"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="6585414237800161146">"ਫ਼ੋਨ ਵਿੱਚ ਕੋਈ ਸਿਮ ਕਾਰਡ ਮੌਜੂਦ ਨਹੀਂ।"</string>
     <string name="keyguard_missing_sim_instructions" msgid="7350295932015220392">"ਇੱਕ SIM ਕਾਰਡ ਪਾਓ।"</string>
     <string name="keyguard_missing_sim_instructions_long" msgid="589889372883904477">"SIM ਕਾਰਡ ਮੌਜੂਦ ਨਹੀਂ ਜਾਂ ਪੜ੍ਹਨਯੋਗ ਨਹੀਂ ਹੈ। ਇੱਕ SIM ਕਾਰਡ ਪਾਓ।"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="654102080186420706">"ਨਾ-ਵਰਤਣਯੋਗ SIM ਕਾਰਡ।"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="4683178224791318347">"ਤੁਹਾਡਾ SIM ਕਾਰਡ ਸਥਾਈ ਤੌਰ \'ਤੇ ਅਯੋਗ ਬਣਾ ਦਿੱਤਾ ਗਿਆ ਹੈ।\n ਇੱਕ ਹੋਰ SIM ਕਾਰਡ ਲਈ ਆਪਣੇ ਵਾਇਰਲੈੱਸ ਸੇਵਾ ਪ੍ਰਦਾਨਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
-    <string name="keyguard_sim_locked_message" msgid="953766009432168127">"SIM ਕਾਰਡ ਲੌਕ ਕੀਤਾ ਹੋਇਆ ਹੈ।"</string>
-    <string name="keyguard_sim_puk_locked_message" msgid="1772789643694942073">"SIM ਕਾਰਡ PUK-ਲੌਕ ਕੀਤਾ ਹੋਇਆ ਹੈ।"</string>
-    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="3586601150825821675">"SIM ਕਾਰਡ ਨੂੰ ਅਨਲੌਕ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
-    <string name="keyguard_accessibility_pin_area" msgid="703175752097279029">"PIN ਖੇਤਰ"</string>
-    <string name="keyguard_accessibility_sim_pin_area" msgid="912702510825058921">"SIM PIN ਖੇਤਰ"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="4683178224791318347">"ਤੁਹਾਡਾ ਸਿਮ ਕਾਰਡ ਸਥਾਈ ਤੌਰ \'ਤੇ ਅਯੋਗ ਬਣਾ ਦਿੱਤਾ ਗਿਆ ਹੈ।\n ਇੱਕ ਹੋਰ ਸਿਮ ਕਾਰਡ ਲਈ ਆਪਣੇ ਵਾਇਰਲੈੱਸ ਸੇਵਾ ਪ੍ਰਦਾਨਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
+    <string name="keyguard_sim_locked_message" msgid="953766009432168127">"SIM ਕਾਰਡ  ਲਾਕ  ਕੀਤਾ ਹੋਇਆ ਹੈ।"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="1772789643694942073">"SIM ਕਾਰਡ PUK- ਲਾਕ  ਕੀਤਾ ਹੋਇਆ ਹੈ।"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="3586601150825821675">"SIM ਕਾਰਡ ਨੂੰ ਅਣਲਾਕ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
+    <string name="keyguard_accessibility_pin_area" msgid="703175752097279029">"ਪਿੰਨ ਖੇਤਰ"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="912702510825058921">"ਸਿਮ ਪਿੰਨ ਖੇਤਰ"</string>
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM 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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"ਦਾਖਲ ਕਰੋ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ਪੈਟਰਨ ਭੁੱਲ ਗਏ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ਗਲਤ ਪੈਟਰਨ"</string>
     <string name="kg_wrong_password" msgid="4580683060277329277">"ਗਲਤ ਪਾਸਵਰਡ"</string>
-    <string name="kg_wrong_pin" msgid="4785660766909463466">"ਗਲਤ PIN"</string>
+    <string name="kg_wrong_pin" msgid="4785660766909463466">"ਗਲਤ ਪਿੰਨ"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ਆਪਣਾ ਪੈਟਰਨ ਉਲੀਕੋ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN ਦਾਖਲ ਕਰੋ"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" ਲਈ SIM PIN ਦਾਖਲ ਕਰੋ"</string>
-    <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN ਦਾਖਲ ਕਰੋ"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"ਸਿਮ ਪਿੰਨ ਦਾਖਲ ਕਰੋ।"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" ਲਈ ਸਿਮ ਪਿੰਨ ਦਾਖਲ ਕਰੋ।"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"ਮੋਬਾਈਲ ਸੇਵਾ ਤੋਂ ਬਿਨਾਂ ਡੀਵਾਈਸ ਨੂੰ ਵਰਤਣ ਲਈ 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">"SIM ਹੁਣ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
-    <string name="kg_puk_enter_puk_hint_multi" msgid="1373131883510840794">"SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\" ਹੁਣ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
-    <string name="kg_puk_enter_pin_hint" msgid="3137789674920391087">"ਇੱਛਤ PIN ਕੋਡ ਦਾਖਲ ਕਰੋ"</string>
-    <string name="kg_enter_confirm_pin_hint" msgid="3089485999116759671">"ਇੱਛਤ PIN ਕੋਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string>
-    <string name="kg_sim_unlock_progress_dialog_message" msgid="4471738151810900114">"SIM ਕਾਰਡ ਨੂੰ ਅਨਲੌਕ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
-    <string name="kg_invalid_sim_pin_hint" msgid="3057533256729513335">"ਕੋਈ PIN ਟਾਈਪ ਕਰੋ ਜੋ 4 ਤੋਂ 8 ਨੰਬਰਾਂ ਦਾ ਹੋਵੇ।"</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">"SIM ਕਾਰਡ ਨੂੰ ਅਣਲਾਕ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="3057533256729513335">"ਕੋਈ ਪਿੰਨ ਟਾਈਪ ਕਰੋ ਜੋ 4 ਤੋਂ 8 ਨੰਬਰਾਂ ਦਾ ਹੋਵੇ।"</string>
     <string name="kg_invalid_sim_puk_hint" msgid="6003602401368264144">"PUK ਕੋਡ 8 ਜਾਂ ਵੱਧ ਨੰਬਰਾਂ ਦਾ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।"</string>
-    <string name="kg_invalid_puk" msgid="5399287873762592502">"ਸਹੀ PUK ਕੋਡ ਮੁੜ-ਦਾਖਲ ਕਰੋ। ਬਾਰ-ਬਾਰ ਕੀਤੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ SIM ਨੂੰ ਸਥਾਈ ਤੌਰ \'ਤੇ ਅਯੋਗ ਬਣਾ ਦੇਣਗੀਆਂ।"</string>
-    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="5672736555427444330">"PIN ਕੋਡ ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ"</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">"ਤੁਸੀਂ ਆਪਣਾ PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="kg_too_many_failed_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>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7724148763268377734">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਪਾਸਵਰਡ ਗਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ।\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਉਲੀਕਿਆ ਹੈ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1629351522209932316">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਇਹ ਟੈਬਲੈੱਟ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇਸਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="3921998703529189931">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਇਹ ਫ਼ੋਨ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇਸਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
-    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="4694232971224663735">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। ਇਹ ਟੈਬਲੈੱਟ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇਸਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
-    <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_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>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਉਲੀਕਿਆ ਹੈ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1629351522209932316">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਇਹ ਟੈਬਲੈੱਟ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇਸਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="3921998703529189931">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਇਹ ਫ਼ੋਨ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇਸਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="4694232971224663735">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। ਇਹ ਟੈਬਲੈੱਟ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇਸਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
+    <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_login" product="tablet" msgid="956706236554092172">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਉਲੀਕਿਆ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣੇ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਵੇਗਾ।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ ਫ਼ੋਨ ਅਣਲਾਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="kg_password_wrong_pin_code_pukked" msgid="3389829202093674267">"ਗਲਤ ਸਿਮ ਪਿੰਨ ਕੋਡ, ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਲਈ ਹੁਣ ਤੁਹਾਨੂੰ ਲਾਜ਼ਮੀ ਤੌਰ \'ਤੇ ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਸੰਪਰਕ ਕਰਨਾ ਚਾਹੀਦਾ ਹੈ।"</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="4314341367727055967">
-      <item quantity="one">ਗਲਤ SIM PIN ਕੋਡ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ।</item>
-      <item quantity="other">ਗਲਤ SIM PIN ਕੋਡ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ।</item>
+      <item quantity="one">ਗਲਤ ਸਿਮ ਪਿੰਨ ਕੋਡ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ।</item>
+      <item quantity="other">ਗਲਤ ਸਿਮ ਪਿੰਨ ਕੋਡ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ।</item>
     </plurals>
     <string name="kg_password_wrong_puk_code_dead" msgid="3329017604125179374">"SIM ਨਾ-ਵਰਤਣਯੋਗ ਹੈ। ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
     <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="2287504898931957513">
-      <item quantity="one">ਗਲਤ SIM PUK ਕੋਡ, ਇਸਤੋਂ ਪਹਿਲਾਂ ਕਿ SIM ਸਥਾਈ ਤੌਰ \'ਤੇ ਵਰਤਣਯੋਗ ਨਾ ਰਹੇ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ।</item>
-      <item quantity="other">ਗਲਤ SIM PUK ਕੋਡ, ਇਸਤੋਂ ਪਹਿਲਾਂ ਕਿ SIM ਸਥਾਈ ਤੌਰ \'ਤੇ ਵਰਤਣਯੋਗ ਨਾ ਰਹੇ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ।</item>
+      <item quantity="one">ਗਲਤ ਸਿਮ PUK ਕੋਡ, ਇਸਤੋਂ ਪਹਿਲਾਂ ਕਿ ਸਿਮ ਸਥਾਈ ਤੌਰ \'ਤੇ ਵਰਤਣਯੋਗ ਨਾ ਰਹੇ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ।</item>
+      <item quantity="other">ਗਲਤ ਸਿਮ PUK ਕੋਡ, ਇਸਤੋਂ ਪਹਿਲਾਂ ਕਿ ਸਿਮ ਸਥਾਈ ਤੌਰ \'ਤੇ ਵਰਤਣਯੋਗ ਨਾ ਰਹੇ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ।</item>
     </plurals>
-    <string name="kg_password_pin_failed" msgid="8769990811451236223">"SIM PIN ਕਾਰਵਾਈ ਅਸਫਲ ਰਹੀ!"</string>
+    <string name="kg_password_pin_failed" msgid="8769990811451236223">"ਸਿਮ ਪਿੰਨ ਕਾਰਵਾਈ ਅਸਫਲ ਰਹੀ!"</string>
     <string name="kg_password_puk_failed" msgid="1331621440873439974">"SIM 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>
+    <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"ਇਨਪੁੱਟ ਵਿਧੀ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="airplane_mode" msgid="3807209033737676010">"ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"ਡੀਵਾਈਸ ਦੇ ਮੁੜ-ਚਾਲੂ ਹੋਣ \'ਤੇ ਪੈਟਰਨ ਦੀ ਲੋੜ ਹੈ"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"ਡੀਵਾਈਸ ਦੇ ਮੁੜ-ਚਾਲੂ ਹੋਣ \'ਤੇ PIN ਦੀ ਲੋੜ ਹੈ"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"ਡੀਵਾਈਸ ਦੇ ਮੁੜ-ਚਾਲੂ ਹੋਣ \'ਤੇ ਪਿੰਨ ਦੀ ਲੋੜ ਹੈ"</string>
     <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"ਡੀਵਾਈਸ ਦੇ ਮੁੜ-ਚਾਲੂ ਹੋਣ \'ਤੇ ਪਾਸਵਰਡ ਦੀ ਲੋੜ ਹੈ"</string>
     <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"ਵਧੀਕ ਸੁਰੱਖਿਆ ਲਈ ਪੈਟਰਨ ਦੀ ਲੋੜ ਹੈ"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"ਵਧੀਕ ਸੁਰੱਖਿਆ ਲਈ PIN ਦੀ ਲੋੜ ਹੈ"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"ਵਧੀਕ ਸੁਰੱਖਿਆ ਲਈ ਪਿੰਨ ਦੀ ਲੋੜ ਹੈ"</string>
     <string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"ਵਧੀਕ ਸੁਰੱਖਿਆ ਲਈ ਪਾਸਵਰਡ ਦੀ ਲੋੜ ਹੈ"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"ਜਦ ਤੁਸੀਂ ਇੱਕ ਪ੍ਰੋਫਾਈਲ ਤੋਂ ਦੂਜੇ \'ਤੇ ਜਾਂਦੇ ਹੋ ਤਾਂ ਪੈਟਰਨ ਦੀ ਲੋੜ ਹੈ"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"ਜਦ ਤੁਸੀਂ ਇੱਕ ਪ੍ਰੋਫਾਈਲ ਤੋਂ ਦੂਜੇ \'ਤੇ ਜਾਂਦੇ ਹੋ ਤਾਂ PIN ਦੀ ਲੋੜ ਹੈ"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"ਜਦ ਤੁਸੀਂ ਪ੍ਰੋਫਾਈਲਾਂ ਨੂੰ ਸਵਿੱਚ ਕਰਦੇ ਹੋ ਤਾਂ ਪੈਟਰਨ ਦੀ ਲੋੜ ਹੈ"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"ਜਦ ਤੁਸੀਂ ਪ੍ਰੋਫਾਈਲਾਂ ਨੂੰ ਸਵਿੱਚ ਕਰਦੇ ਹੋ ਤਾਂ ਪਿੰਨ ਦੀ ਲੋੜ ਹੈ"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"ਜਦ ਤੁਸੀਂ ਇੱਕ ਪ੍ਰੋਫਾਈਲ ਤੋਂ ਦੂਜੇ \'ਤੇ ਜਾਂਦੇ ਹੋ ਤਾਂ ਪਾਸਵਰਡ ਦੀ ਲੋੜ ਹੈ"</string>
-    <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਡੀਵਾਈਸ ਨੂੰ ਲੌਕ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"ਡੀਵਾਈਸ ਨੂੰ ਹੱਥੀਂ ਲੌਕ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਡੀਵਾਈਸ ਨੂੰ ਲਾਕ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"ਡੀਵਾਈਸ ਨੂੰ ਹੱਥੀਂ ਲਾਕ ਕੀਤਾ ਗਿਆ"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="71299470072448533">
-      <item quantity="one">ਡੀਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟੇ ਤੋਂ ਅਨਲੌਕ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ। ਪੈਟਰਨ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।</item>
-      <item quantity="other">ਡੀਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟਿਆਂ ਤੋਂ ਅਨਲੌਕ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ। ਪੈਟਰਨ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।</item>
+      <item quantity="one">ਡੀਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟੇ ਤੋਂ ਅਣਲਾਕ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ। ਪੈਟਰਨ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।</item>
+      <item quantity="other">ਡੀਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟਿਆਂ ਤੋਂ ਅਣਲਾਕ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ। ਪੈਟਰਨ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="34586942088144385">
-      <item quantity="one">ਡੀਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟੇ ਤੋਂ ਅਨਲੌਕ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ। PIN ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।</item>
-      <item quantity="other">ਡੀਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟਿਆਂ ਤੋਂ ਅਨਲੌਕ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ। PIN ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।</item>
+      <item quantity="one">ਡੀਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟੇ ਤੋਂ ਅਣਲਾਕ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ। ਪਿੰਨ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।</item>
+      <item quantity="other">ਡੀਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟਿਆਂ ਤੋਂ ਅਣਲਾਕ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ। ਪਿੰਨ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_password" formatted="false" msgid="257297696215346527">
-      <item quantity="one">ਡੀਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟੇ ਤੋਂ ਅਨਲੌਕ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ। ਪਾਸਵਰਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।</item>
-      <item quantity="other">ਡੀਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟਿਆਂ ਤੋਂ ਅਨਲੌਕ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ। ਪਾਸਵਰਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।</item>
+      <item quantity="one">ਡੀਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟੇ ਤੋਂ ਅਣਲਾਕ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ। ਪਾਸਵਰਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ</item>
+      <item quantity="other">ਡੀਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟਿਆਂ ਤੋਂ ਅਣਲਾਕ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ। ਪਾਸਵਰਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ</item>
     </plurals>
     <string name="fingerprint_not_recognized" msgid="348813995267914625">"ਪਛਾਣ ਨਹੀਂ ਹੋਈ"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml
index a71cd8b..ee42dbb 100644
--- a/packages/SystemUI/res-keyguard/values-pl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Wpisz hasło, aby odblokować"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Wpisz kod PIN, aby odblokować"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Nieprawidłowy kod PIN."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Naładowana"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Ładowanie"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Szybkie ładowanie"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Miejsce na kod PUK karty SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Następny alarm ustawiony na: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Usuwanie"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Wyłącz eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Nie pamiętam wzoru"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Nieprawidłowy wzór"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Nieprawidłowy kod PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Spróbuj ponownie za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Narysuj wzór"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Wpisz kod PIN karty SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Wpisz kod PIN karty SIM „<xliff:g id="CARRIER">%1$s</xliff:g>”"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Wpisz kod PIN karty SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Wpisz kod PIN karty SIM „<xliff:g id="CARRIER">%1$s</xliff:g>”."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Wyłącz eSIM, by używać urządzenia bez usługi sieci komórkowej."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Wpisz kod PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Wpisz hasło"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Karta SIM została wyłączona. Wpisz kod PUK, by przejść dalej. Skontaktuj się z operatorem, by uzyskać więcej informacji."</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
index 8206b4f..6eee60a 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
@@ -29,6 +29,7 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Digite a senha para desbloquear"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Insira o PIN para desbloquear"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Código PIN incorreto."</string>
+    <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Cartão inválido."</string>
     <string name="keyguard_charged" msgid="2222329688813033109">"Carregada"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Carregando"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Carregando rapidamente"</string>
@@ -51,6 +52,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Área do PUK SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Próximo alarme definido para <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Excluir"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Desativar eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Inserir"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Esqueci o padrão"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Padrão incorreto"</string>
@@ -58,8 +60,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN incorreto"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Tente novamente em <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Desenhe seu padrão"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Digite o PIN do cartão SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Informe o PIN do SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Informe o PIN do cartão SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Informe o PIN do cartão SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Desative o eSIM para usar o dispositivo sem serviço móvel."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Digite o PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Digite a senha"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"O SIM foi desativado. Insira o código PUK para continuar. Entre em contato com a operadora para mais detalhes."</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index 871d2cf..5bfa74e 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Introduza a palavra-passe para desbloquear"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Introduza o PIN para desbloquear"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Código PIN incorreto."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Carregada"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"A carregar…"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"A carregar rapidamente…"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Área do PUK do cartão SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Próximo alarme definido para <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Eliminar"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Desativar eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Tecla Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Esqueceu-se do padrão"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Padrão incorreto"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN incorreto"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Tente novamente dentro de <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Desenhe o seu padrão"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Introduza o PIN do cartão SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Introduza o PIN do cartão SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Introduza o PIN do cartão SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Introduza o PIN do cartão SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Desativar eSIM para utilizar sem serviço móvel"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Introduza o PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Introduza a palavra-passe"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"O cartão SIM está agora desativado. Introduza o código PUK para continuar. Contacte o operador para obter mais detalhes."</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt/strings.xml b/packages/SystemUI/res-keyguard/values-pt/strings.xml
index 8206b4f..6eee60a 100644
--- a/packages/SystemUI/res-keyguard/values-pt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt/strings.xml
@@ -29,6 +29,7 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Digite a senha para desbloquear"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Insira o PIN para desbloquear"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Código PIN incorreto."</string>
+    <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Cartão inválido."</string>
     <string name="keyguard_charged" msgid="2222329688813033109">"Carregada"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Carregando"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Carregando rapidamente"</string>
@@ -51,6 +52,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Área do PUK SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Próximo alarme definido para <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Excluir"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Desativar eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Inserir"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Esqueci o padrão"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Padrão incorreto"</string>
@@ -58,8 +60,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN incorreto"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Tente novamente em <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Desenhe seu padrão"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Digite o PIN do cartão SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Informe o PIN do SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Informe o PIN do cartão SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Informe o PIN do cartão SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Desative o eSIM para usar o dispositivo sem serviço móvel."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Digite o PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Digite a senha"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"O SIM foi desativado. Insira o código PUK para continuar. Entre em contato com a operadora para mais detalhes."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml
index 5e75e5b..01f150d 100644
--- a/packages/SystemUI/res-keyguard/values-ro/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Introduceți parola pentru a debloca"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Introduceți codul PIN pentru a debloca"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Cod PIN incorect."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Încărcată"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Se încarcă"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Se încarcă rapid"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Zona codului PUK pentru cardul SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Următoarea alarmă este setată pentru <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Ștergeți"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Dezactivați cardul eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Introduceți"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Ați uitat modelul"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Model greșit"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Cod PIN greșit"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Încercați din nou peste <xliff:g id="NUMBER">%d</xliff:g> secunde."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Desenați modelul"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Introduceți codul PIN al cardului SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Introduceți codul PIN al cardului SIM pentru „<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Introduceți codul PIN al cardului SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Introduceți codul PIN al cardului SIM pentru „<xliff:g id="CARRIER">%1$s</xliff:g>”."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Dezactivați cardul eSIM pentru a folosi dispozitivul fără serviciu mobil."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Introduceți codul PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Introduceți parola"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Cardul SIM este acum dezactivat. Pentru a continua, introduceți codul PUK. Pentru detalii, contactați operatorul."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml
index 1bdaaf4..47f85ae 100644
--- a/packages/SystemUI/res-keyguard/values-ru/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Введите пароль"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Введите PIN-код для разблокировки"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Неверный PIN-код."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Батарея заряжена"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Зарядка батареи"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Быстрая зарядка"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"PUK-код SIM-карты"</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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Клавиша ввода"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Забыли графический ключ?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Неверный графический ключ"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Неверный PIN-код"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Повторите попытку через <xliff:g id="NUMBER">%d</xliff:g> сек."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Введите графический ключ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Введите PIN-код SIM-карты"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Введите PIN-код SIM-карты \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Введите PIN-код SIM-карты."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Введите PIN-код SIM-карты \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Чтобы пользоваться устройством без мобильной связи, отключите eSIM."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Введите PIN-код"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Введите пароль"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-карта отключена. Чтобы продолжить, введите PUK-код. За подробной информацией обратитесь к оператору связи."</string>
diff --git a/packages/SystemUI/res-keyguard/values-si/strings.xml b/packages/SystemUI/res-keyguard/values-si/strings.xml
index 2854853..5951e11 100644
--- a/packages/SystemUI/res-keyguard/values-si/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-si/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"අගුළු ඇරීමට මුරපදය ටයිප් කරන්න"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"අගුළු හැරීමට PIN එක ටයිප් කරන්න"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"වැරදි PIN කේතයකි."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"අරෝපිතයි"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"ආරෝපණය වෙමින්"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"වේගයෙන් ආරෝපණය වෙමින්"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM 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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"ඇතුල් කරන්න"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"රටාව අමතකයි"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"වැරදි රටාවකි"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN එක වැරදියි"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"තත්පර <xliff:g id="NUMBER">%d</xliff:g> කින් නැවත උත්සහ කරන්න."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ඔබගේ රටාව අඳින්න"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN ඇතුලු කරන්න"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" සඳහා SIM PIN ඇතුළත් කරන්න"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN ඇතුළු කරන්න"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" සඳහා SIM PIN ඇතුළු කරන්න"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"ජංගම සේවාවෙන් තොරව උපාංගය භාවිත කිරීමට eSIM අබල කරන්න."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN එක ඇතුළු කරන්න"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"මුරපදය ඇතුළු කරන්න"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"දැන් SIM එක අබල කර ඇත. ඉදිරියට යාමට PUK කේතය යොදන්න. විස්තර සඳහා වාහකයා අමතන්න."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml
index f88055d..c290320 100644
--- a/packages/SystemUI/res-keyguard/values-sk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Zadajte heslo na odomknutie"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Zadajte kód PIN na odomknutie"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Nesprávny kód PIN."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Nabité"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Nabíja sa"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Rýchle nabíjanie"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Oblasť kódu PUK SIM karty"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nasledujúci budík je nastavený na <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Odstrániť"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Zakázať eSIM kartu"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Nepamätám si vzor"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Nesprávny vzor"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Nesprávny kód PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Skúste to znova o <xliff:g id="NUMBER">%d</xliff:g> s."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Nakreslite svoj vzor"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Zadajte PIN SIM karty"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Zadajte kód PIN pre SIM kartu operátora <xliff:g id="CARRIER">%1$s</xliff:g>"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Zadajte PIN pre SIM kartu"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Zadajte kód PIN pre SIM kartu operátora <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Zakážte eSIM kartu a používajte zariadenie bez mobilnej služby."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Zadajte kód PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Zadajte heslo"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM karta je teraz zakázaná. Ak chcete pokračovať, zadajte kód PUK. Podrobné informácie získate od operátora."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sl/strings.xml b/packages/SystemUI/res-keyguard/values-sl/strings.xml
index 882ba22..7cd6eec 100644
--- a/packages/SystemUI/res-keyguard/values-sl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sl/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Vnesite geslo za odklepanje"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Vnesite kodo PIN za odklepanje"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Napačna koda PIN."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Akumulator napolnjen"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Polnjenje"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Hitro polnjenje"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Območje za kodo PUK kartice SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Naslednji alarm je nastavljen za <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Izbris"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Onemogoči kartico e-SIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Tipka Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Pozabljen vzorec"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Napačen vzorec"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Napačna koda PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Poskusite znova čez <xliff:g id="NUMBER">%d</xliff:g> s."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Narišite vzorec"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Vnesite kodo PIN kartice SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Vnesite kodo PIN kartice SIM operaterja »<xliff:g id="CARRIER">%1$s</xliff:g>«"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Vnesite kodo PIN kartice SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Vnesite kodo PIN kartice SIM operaterja »<xliff:g id="CARRIER">%1$s</xliff:g>«."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Onemogočite kartico e-SIM, če želite napravo uporabljati brez mobilne storitve."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Vnesite kodo PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Vnesite geslo"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Kartica SIM je onemogočena. Če želite nadaljevati, vnesite kodo PUK. Za dodatne informacije se obrnite na operaterja."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml
index d3f1f3a..64bf9c0 100644
--- a/packages/SystemUI/res-keyguard/values-sq/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Shkruaj fjalëkalimin për të shkyçur"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Shkruaj kodin PIN për ta shkyçur"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Kodi PIN është i pasaktë."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"I ngarkuar"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Po ngarkon"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Po ngarkon me shpejtësi"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Zona e kodit PUK të kartës SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Alarmi tjetër i caktuar: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Fshi"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Çaktivizo kartën eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Dërgo"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Harrova motivin"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Motivi është i gabuar"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Kod PIN i gabuar"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Provo përsëri për <xliff:g id="NUMBER">%d</xliff:g> sekonda."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Vizato motivin tënd"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Fut kodin PIN të kartës SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Fut kodin PIN të kartës SIM të \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Fut kodin PIN të kartës SIM"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Fut kodin PIN të kartës SIM për \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Çaktivizo kartën eSIM për ta përdorur pajisjen pa shërbimin celular."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Fut kodin PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Fut fjalëkalimin"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Karta SIM tani është e çaktivizuar. Fut kodin PUK për të vazhduar. Kontakto me operatorin për detaje."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml
index 683eef6..5b69c0c 100644
--- a/packages/SystemUI/res-keyguard/values-sr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Унесите лозинку да бисте откључали"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Унесите PIN за откључавање"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN кôд је нетачан."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Напуњена је"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Пуни се"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Брзо се пуни"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Област за PUK за SIM"</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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Заборавио/ла сам шаблон"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Погрешан шаблон"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Погрешан PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Пробајте поново за <xliff:g id="NUMBER">%d</xliff:g> сек."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Нацртајте шаблон"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Унесите PIN за SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Унесите PIN за SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Унесите PIN за SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Унесите PIN за SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Онемогућите eSIM да бисте уређај користили без мобилне услуге."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Унесите PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Унесите лозинку"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM картица је сада онемогућена. Унесите PUK кôд да бисте наставили. Детаљне информације потражите од мобилног оператера."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index 47334f8..9431e42 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Lås upp med lösenordet"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Lås upp med pinkoden"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Fel pinkod."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Laddat"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Laddas"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Laddas snabbt"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"PUK-kodsområde för SIM-kort"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nästa alarm är inställt på <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Radera"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Inaktivera eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Retur"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Har du glömt ditt grafiska lösenord?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Fel grafiskt lösenord"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Fel pinkod"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Försök igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Rita ditt grafiska lösenord"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Ange pinkod för SIM-kortet"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Ange pinkod för SIM-kortet för <xliff:g id="CARRIER">%1$s</xliff:g>"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Ange pinkod för SIM-kortet."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Ange pinkod för SIM-kortet för <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Inaktivera eSIM om du vill använda enheten utan mobiltjänst."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Ange pinkod"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Ange lösenord"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortet har inaktiverats. Du måste ange en PUK-kod innan du kan fortsätta. Kontakta operatören för mer information."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml
index b2991d2..4209334 100644
--- a/packages/SystemUI/res-keyguard/values-sw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Andika nenosiri ili ufungue"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Andika PIN ili ufungue"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Nambari ya PIN si sahihi."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Betri imejaa"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Inachaji"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Inachaji kwa kasi"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Eneo la PUK ya SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Kengele inayofuata italia saa <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Futa"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Zima eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Weka"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Umesahau Mchoro"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Mchoro si Sahihi"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Nambari ya PIN si sahihi"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Jaribu tena baada ya sekunde <xliff:g id="NUMBER">%d</xliff:g>."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Chora mchoro wako"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Weka PIN ya SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Weka PIN ya SIM ya \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Weka PIN ya SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Weka PIN ya SIM ya \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Zima eSIM ili utumie kifaa bila huduma ya vifaa vya mkononi."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Weka PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Weka Nenosiri"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM sasa imefungwa. Weka nambari ya PUK ili uendelee. Wasiliana na mtoa huduma za mtandao kwa maelezo."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml
index 436d000..157eabc 100644
--- a/packages/SystemUI/res-keyguard/values-ta/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml
@@ -29,8 +29,10 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"திறக்க, கடவுச்சொல்லை உள்ளிடவும்"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"திறக்க, பின்னை உள்ளிடவும்"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"தவறான பின் குறியீடு."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"சார்ஜ் செய்யப்பட்டது"</string>
-    <string name="keyguard_plugged_in" msgid="89308975354638682">"சார்ஜாகிறது"</string>
+    <string name="keyguard_plugged_in" msgid="89308975354638682">"சார்ஜ் ஆகிறது"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"வேகமாகச் சார்ஜாகிறது"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="6637043106038550407">"மெதுவாகச் சார்ஜாகிறது"</string>
     <string name="keyguard_low_battery" msgid="9218432555787624490">"சார்ஜரை இணைக்கவும்."</string>
@@ -51,6 +53,7 @@
     <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">"இ-சிம்மை முடக்கும்"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"என்டர் பொத்தான்"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"பேட்டர்ன் நினைவில்லையா"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"தவறான பேட்டர்ன்"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"தவறான பின்"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"பேட்டர்னை வரையவும்"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"சிம் பின்னை உள்ளிடவும்"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\"க்கான சிம் பின்னை உள்ளிடவும்"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"சிம் பின்னை உள்ளிடவும்."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\"க்கான சிம் பின்னை உள்ளிடவும்."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"மொபைல் சேவை இல்லாமல் சாதனத்தைப் பயன்படுத்த, இ-சிம்மை முடக்கவும்."</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">"சிம் தற்போது முடக்கப்பட்டுள்ளது. தொடர, PUK குறியீட்டை உள்ளிடவும். விவரங்களுக்கு, தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்புகொள்ளவும்."</string>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index 1b635659..f83ada8 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"అన్‌లాక్ చేయడానికి పాస్‌వర్డ్‌ను టైప్ చేయండి"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"అన్‌లాక్ చేయడానికి పిన్ టైప్ చేయండి"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"పిన్ కోడ్ తప్పు."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"ఛార్జ్ చేయబడింది"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"ఛార్జ్ అవుతోంది"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"వేగంగా ఛార్జ్ అవుతోంది"</string>
@@ -49,17 +51,19 @@
     <string name="keyguard_accessibility_pin_area" msgid="703175752097279029">"పిన్ ప్రాంతం"</string>
     <string name="keyguard_accessibility_sim_pin_area" msgid="912702510825058921">"SIM పిన్ ప్రాంతం"</string>
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK ప్రాంతం"</string>
-    <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"తదుపరి అలారం <xliff:g id="ALARM">%1$s</xliff:g>కి సెట్ చేయబడింది"</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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"నమూనాను మర్చిపోయాను"</string>
-    <string name="kg_wrong_pattern" msgid="7620081431514773802">"నమూనా తప్పు"</string>
+    <string name="kg_wrong_pattern" msgid="7620081431514773802">"ఆకృతి తప్పు"</string>
     <string name="kg_wrong_password" msgid="4580683060277329277">"పాస్‌వర్డ్ తప్పు"</string>
     <string name="kg_wrong_pin" msgid="4785660766909463466">"పిన్ తప్పు"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"మీ నమూనాను గీయండి"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM పిన్‌ను నమోదు చేయండి"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" కోసం SIM పిన్ నమోదు చేయండి"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM పిన్‌ని నమోదు చేయండి."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" కోసం SIM పిన్‌ని నమోదు చేయండి."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"మొబైల్ సేవ లేకుండా డివైజ్‌ని ఉపయోగించడం కోసం 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">"ఇప్పుడు SIM నిలిపివేయబడింది. కొనసాగించాలంటే, PUK కోడ్‌ను నమోదు చేయండి. వివరాల కోసం క్యారియర్‌ను సంప్రదించండి."</string>
@@ -89,10 +93,10 @@
     <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 పిన్ కోడ్ తప్పు, ఇప్పుడు మీ పరికరాన్ని అన్‌లాక్ చేయాలంటే, మీరు తప్పనిసరిగా మీ క్యారియర్‌ను సంప్రదించాలి."</string>
+    <string name="kg_password_wrong_pin_code_pukked" msgid="3389829202093674267">"SIM పిన్ కోడ్ తప్పు, ఇప్పుడు మీ డివైజ్‌ను అన్‌లాక్ చేయాలంటే, మీరు తప్పనిసరిగా మీ క్యారియర్‌ను సంప్రదించాలి."</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="4314341367727055967">
       <item quantity="other">SIM పిన్ కోడ్ తప్పు, మీకు మరో <xliff:g id="NUMBER_1">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి.</item>
-      <item quantity="one">SIM పిన్ కోడ్ తప్పు, మీకు మరో <xliff:g id="NUMBER_0">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది, ఆ తర్వాత మీ పరికరాన్ని అన్‌లాక్ చేయాలంటే, మీరు తప్పనిసరిగా మీ క్యారియర్‌ని సంప్రదించాలి.</item>
+      <item quantity="one">SIM పిన్ కోడ్ తప్పు, మీకు మరో <xliff:g id="NUMBER_0">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది, ఆ తర్వాత మీ డివైజ్‌ను అన్‌లాక్ చేయాలంటే, మీరు తప్పనిసరిగా మీ క్యారియర్‌ని సంప్రదించాలి.</item>
     </plurals>
     <string name="kg_password_wrong_puk_code_dead" msgid="3329017604125179374">"SIM నిరుపయోగకరంగా మారింది. మీ క్యారియర్‌ను సంప్రదించండి."</string>
     <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="2287504898931957513">
@@ -106,7 +110,7 @@
     <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"ఇన్‌పుట్ పద్ధతిని మార్చు"</string>
     <string name="airplane_mode" msgid="3807209033737676010">"విమానం మోడ్"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"పరికరాన్ని పునఃప్రారంభించిన తర్వాత నమూనాను గీయాలి"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"పరికరాన్ని పునఃప్రారంభించిన తర్వాత పిన్ నమోదు చేయాలి"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"డివైజ్‌ను పునఃప్రారంభించిన తర్వాత పిన్ నమోదు చేయాలి"</string>
     <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"పరికరాన్ని పునఃప్రారంభించిన తర్వాత పాస్‌వర్డ్‌ను నమోదు చేయాలి"</string>
     <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"అదనపు భద్రత కోసం నమూనాని గీయాలి"</string>
     <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"అదనపు భద్రత కోసం పిన్ నమోదు చేయాలి"</string>
@@ -121,8 +125,8 @@
       <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> గంట పాటు పరికరాన్ని అన్‌లాక్ చేయలేదు. నమూనాను గీయండి.</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="34586942088144385">
-      <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> గంటల పాటు పరికరాన్ని అన్‌లాక్ చేయలేదు. పిన్ నమోదు చేయండి.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> గంట పాటు పరికరాన్ని అన్‌లాక్ చేయలేదు. పిన్ నమోదు చేయండి.</item>
+      <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> గంటల పాటు డివైజ్‌ను అన్‌లాక్ చేయలేదు. పిన్‌ను నిర్ధారించండి.</item>
+      <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> గంట పాటు డివైజ్‌ను అన్‌లాక్ చేయలేదు. పిన్‌ను నిర్ధారించండి.</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_password" formatted="false" msgid="257297696215346527">
       <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> గంటల పాటు పరికరాన్ని అన్‌లాక్ చేయలేదు. పాస్‌వర్డ్‌ని నమోదు చేయండి.</item>
diff --git a/packages/SystemUI/res-keyguard/values-th/strings.xml b/packages/SystemUI/res-keyguard/values-th/strings.xml
index 0472c16..2425892 100644
--- a/packages/SystemUI/res-keyguard/values-th/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-th/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"พิมพ์รหัสผ่านเพื่อปลดล็อก"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"พิมพ์ PIN เพื่อปลดล็อก"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"รหัส PIN ไม่ถูกต้อง"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"ชาร์จแล้ว"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"กำลังชาร์จ"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"กำลังชาร์จเร็ว"</string>
@@ -51,6 +53,7 @@
     <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">"ปิดใช้ซิมอิเล็กทรอนิกส์"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ลืมรูปแบบ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"รูปแบบไม่ถูกต้อง"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN ไม่ถูกต้อง"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"ลองอีกครั้งในอีก <xliff:g id="NUMBER">%d</xliff:g> วินาที"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"วาดรูปแบบของคุณ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"ป้อน PIN ของซิม"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"ป้อน PIN ของซิมสำหรับ \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"ป้อน PIN ของซิม"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"ป้อน PIN ของซิมสำหรับ \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"ปิดใช้ซิมอิเล็กทรอนิกส์เพื่อใช้อุปกรณ์โดยไม่มีบริการมือถือ"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"ป้อน PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"ป้อนรหัสผ่าน"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ซิมการ์ดถูกปิดใช้แล้ว ป้อนรหัส PUK เพื่อดำเนินการต่อ โปรดสอบถามรายละเอียดจากผู้ให้บริการ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml
index 0b7aa13..9b806c6 100644
--- a/packages/SystemUI/res-keyguard/values-tl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"I-type ang password upang i-unlock"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"I-type ang PIN upang i-unlock"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Mali ang PIN code."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Tapos nang mag-charge"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Nagcha-charge"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Mabilis na nagcha-charge"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Lugar ng PUK ng SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nakatakda ang susunod na alarm sa <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"I-delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"I-disable ang eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Nakalimutan ang Pattern"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Mali ang Pattern"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Mali ang PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Subukang muli sa loob ng <xliff:g id="NUMBER">%d</xliff:g> (na) segundo."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Iguhit ang iyong pattern"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Ilagay ang PIN ng SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Ilagay ang PIN ng SIM para sa \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Ilagay ang PIN ng SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Ilagay ang PIN ng SIM para sa \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"I-disable ang eSIM upang magamit ang device nang walang serbisyo sa mobile."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Ilagay ang PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Ilagay ang Password"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Naka-disable na ngayon ang SIM. Ilagay ang PUK code upang magpatuloy. Makipag-ugnayan sa carrier para sa mga detalye."</string>
diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml
index f108095..034dce3 100644
--- a/packages/SystemUI/res-keyguard/values-tr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Kilidi açmak için şifreyi yazın"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Kilidi açmak için PIN kodunu yazın"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Yanlış PIN kodu."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Ödeme alındı"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Şarj oluyor"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Hızlı şarj oluyor"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK alanı"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Sonraki alarm <xliff:g id="ALARM">%1$s</xliff:g> olarak ayarlandı"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM\'i devre dışı bırak"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Deseni unuttunuz mu?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Yanlış Desen"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Yanlış PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> saniye içinde yeniden deneyin."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Deseninizi çizin"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN kodunu girin"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" için SIM PIN\'ini kodunu girin"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN kodunu girin."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" için SIM PIN kodunu girin."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Cihazı mobil hizmet olmadan kullanmak için eSIM\'i devre dışı bırakın."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN\'i girin"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Şifreyi Girin"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM kart artık devre dışı bırakıldı. Devam etmek için PUK kodunu girin. Ayrıntılı bilgi için operatörle bağlantı kurun."</string>
diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml
index fc52ce3..4e41e1b 100644
--- a/packages/SystemUI/res-keyguard/values-uk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Введіть пароль, щоб розблокувати"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Введіть PIN-код, щоб розблокувати"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Неправильний PIN-код."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Заряджено"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Заряджається"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Швидке заряджання"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"PUK-код SIM-карти"</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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Ввести"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Не пам’ятаю ключ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Неправильний ключ"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Неправильний PIN-код"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Повторіть спробу через <xliff:g id="NUMBER">%d</xliff:g> с."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Намалюйте ключ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Введіть PIN-код SIM-карти"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Введіть PIN-код SIM-карти для оператора \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Введіть PIN-код SIM-карти."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Введіть PIN-код SIM-карти для оператора \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Вимкнути eSIM-карту, щоб використовувати пристрій без мобільного зв’язку."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Введіть PIN-код"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Введіть пароль"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Зараз SIM-карту вимкнено. Введіть PUK-код, щоб продовжити. Зв’яжіться з оператором, щоб дізнатися більше."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index 1258547..9e408dd 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"غیر مقفل کرنے کیلئے پاس ورڈ ٹائپ کریں"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"‏غیر مقفل کرنے کیلئے PIN ٹائپ کریں"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"‏غلط PIN کوڈ۔"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"چارج ہوگئی"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"چارج ہو رہا ہے"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"تیزی سے چارج ہو رہا ہے"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"‏SIM 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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"درج کریں"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"پیٹرن بھول گئے"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"غلط پیٹرن"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"‏غلط PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"اپنا پیٹرن ڈرا کریں"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"‏SIM PIN درج کریں"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"‏\"<xliff:g id="CARRIER">%1$s</xliff:g>\" کیلئے SIM PIN درج کریں"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"‏SIM PIN درج کریں۔"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"‏\"<xliff:g id="CARRIER">%1$s</xliff:g>\" کیلئے SIM PIN درج کریں۔"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"‏موبائل سروس کے بغیر آلہ کا استعمال کرنے کیلئے eSIM غیر فعال کریں۔"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"‏PIN درج کریں"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"پاسورڈ درج کریں"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"‏SIM اب غیر فعال ہوگیا ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml
index e822382..901885c 100644
--- a/packages/SystemUI/res-keyguard/values-uz/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Qulfni ochish uchun parolni kiriting"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Qulfni ochish uchun PIN kodni kiriting"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN kodi xato."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Batareya quvvati to‘ldi"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Quvvatlash"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Tezkor quvvat olmoqda"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM karta PUK kodi maydoni"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Signal <xliff:g id="ALARM">%1$s</xliff:g> da chalinadi."</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"O‘chirib tashlash"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIMni faolsizlantirish"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter tugmasi"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Grafik kalit esimdan chiqdi"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Grafik kalit xato"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN kod xato"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> soniyadan keyin qaytadan urining."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Grafik kalit chizing"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM kartaning PIN kodini kiriting"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"“<xliff:g id="CARRIER">%1$s</xliff:g>” SIM kartasi uchun PIN kodni kiriting"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM karta PIN kodini kiriting."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"“<xliff:g id="CARRIER">%1$s</xliff:g>” SIM kartasi PIN kodini kiriting."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Qurilmadan mobil xizmatlarsiz foydalanish uchun eSIMni faolsizlantiring."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN kodni kiriting"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Parol kiriting"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM karta hozir o‘chirilgan. Davom etish uchun PUK kodni kiriting. Batafsil axborot olish uchun tarmoq operatori bilan bog‘laning."</string>
diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml
index 59e5c9c..a51be62 100644
--- a/packages/SystemUI/res-keyguard/values-vi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Nhập mật khẩu để mở khóa"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Nhập mã PIN để mở khóa"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Mã PIN không chính xác."</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Đã sạc đầy"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Đang sạc"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Đang sạc nhanh"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Khu vực mã PUK của SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Báo thức tiếp theo được đặt cho <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Xóa"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Vô hiệu hóa eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Nhập"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Đã quên hình mở khóa"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Hình mở khóa sai"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Mã PIN sai"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Thử lại sau <xliff:g id="NUMBER">%d</xliff:g> giây."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Vẽ hình mở khóa của bạn"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Nhập mã PIN của SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Nhập mã PIN của SIM dành cho \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Nhập mã PIN của SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Nhập mã PIN của SIM dành cho \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Vô hiệu hóa eSIM để sử dụng thiết bị khi không có dịch vụ di động."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Nhập mã PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Nhập mật khẩu"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM hiện bị vô hiệu hóa. Hãy nhập mã PUK để tiếp tục. Liên hệ với nhà cung cấp dịch vụ để biết chi tiết."</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
index a5eca34..1953b03 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"输入密码即可解锁"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"输入 PIN 码即可解锁"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN 码有误。"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"已充满电"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"正在充电"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"正在快速充电"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM 卡 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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"输入"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"忘记了图案"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"图案错误"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN 码错误"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"请在 <xliff:g id="NUMBER">%d</xliff:g> 秒后重试。"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"绘制您的图案"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"请输入 SIM 卡 PIN 码"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"请输入“<xliff:g id="CARRIER">%1$s</xliff:g>”的 SIM 卡 PIN 码"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"请输入 SIM 卡 PIN 码。"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"请输入“<xliff:g id="CARRIER">%1$s</xliff:g>”的 SIM 卡 PIN 码。"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"停用 eSIM 卡即可在没有移动服务的情况下使用设备。"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"请输入 PIN 码"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"请输入密码"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM 卡现已停用,需要输入 PUK 码才能继续使用。要了解详情,请联系您的运营商。"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index 8059a04..12567fc 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"輸入密碼即可解鎖"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"輸入 PIN 碼即可解鎖"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN 碼不正確。"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"已完成充電"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"正在充電"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"正在快速充電"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM 卡 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">"Delete 鍵 (刪除)"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"停用 eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter 鍵 (輸入)"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"忘記上鎖圖案"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"上鎖圖案錯誤"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN 碼錯誤"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"請在 <xliff:g id="NUMBER">%d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"畫出上鎖圖案"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"輸入 SIM 卡 PIN 碼"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"輸入「<xliff:g id="CARRIER">%1$s</xliff:g>」的 SIM 卡 PIN 碼"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"輸入 SIM 卡的 PIN 碼。"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"輸入「<xliff:g id="CARRIER">%1$s</xliff:g>」SIM 卡的 PIN 碼。"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"停用 eSIM,即可在沒有流動服務的情況下使用裝置。"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"輸入 PIN 碼"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"輸入密碼"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM 卡現已停用,請輸入 PUK 碼以繼續。詳情請與流動網絡供應商聯絡。"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index a03635b..7df7373 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"輸入密碼即可解鎖"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"輸入 PIN 碼即可解鎖"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN 碼不正確。"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"充電完成"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"充電中"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"快速充電中"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM 卡 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>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter 鍵"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"忘記解鎖圖案"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"解鎖圖案錯誤"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN 碼錯誤"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"請在 <xliff:g id="NUMBER">%d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"畫出解鎖圖案"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"輸入 SIM 卡 PIN 碼"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"輸入「<xliff:g id="CARRIER">%1$s</xliff:g>」的 SIM 卡 PIN 碼"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"輸入 SIM 卡的 PIN 碼。"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"輸入「<xliff:g id="CARRIER">%1$s</xliff:g>」SIM 卡的 PIN 碼。"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"停用 eSIM 卡即可在沒有行動服務的情況下使用裝置。"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"輸入 PIN 碼"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"輸入密碼"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM 卡已遭停用,輸入 PUK 碼即可繼續使用。如需瞭解詳情,請與電信業者聯絡。"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zu/strings.xml b/packages/SystemUI/res-keyguard/values-zu/strings.xml
index eaa5ecb..2208306 100644
--- a/packages/SystemUI/res-keyguard/values-zu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zu/strings.xml
@@ -29,6 +29,8 @@
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Bhala iphasiwedi ukuze kuvuleke"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Faka i-PIN ukuvula"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Ikhodi ye-PIN engalungile!"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
     <string name="keyguard_charged" msgid="2222329688813033109">"Kushajiwe"</string>
     <string name="keyguard_plugged_in" msgid="89308975354638682">"Iyashaja"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Ishaja ngokushesha"</string>
@@ -51,6 +53,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Indawo ye-SIM PUK"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"I-alamu elandelayo esethelwe i-<xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Susa"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Khubaza i-eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Faka"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Ukhohlwe iphethini?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Iphatheni engalungile"</string>
@@ -58,8 +61,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Iphinikhodi engalungile"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Zama futhi emasekhondini angu-<xliff:g id="NUMBER">%d</xliff:g>."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dweba iphethini yakho"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Faka i-PIN ye-SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Faka i-PIN ye-SIM ye-\"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Faka i-PIN ye-SIM"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Faka i-PIN ye-SIM ye-\"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Khubaza i-eSIM ukusebenzisa idivayisi ngaphandle kwesevisi yeselula."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Faka iphinikhodi"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Faka iphasiwedi"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"I-SIM manje ikhutshaziwe. Faka ikhodi ye-PUK ukuze uqhubeke. Xhumana nenkampani yenethiwekhi ngemininingwane."</string>
diff --git a/packages/SystemUI/res-keyguard/values/attrs.xml b/packages/SystemUI/res-keyguard/values/attrs.xml
index 7cfe631..e2ce210 100644
--- a/packages/SystemUI/res-keyguard/values/attrs.xml
+++ b/packages/SystemUI/res-keyguard/values/attrs.xml
@@ -35,9 +35,12 @@
         <attr name="android:gravity" />
         <attr name="dotSize" format="dimension" />
         <attr name="charPadding" format="dimension" />
+        <attr name="android:textColor" format="color" />
     </declare-styleable>
 
     <declare-styleable name="CarrierText">
         <attr name="allCaps" format="boolean" />
     </declare-styleable>
+
+    <attr name="passwordStyle" format="reference" />
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values/colors.xml b/packages/SystemUI/res-keyguard/values/colors.xml
deleted file mode 100644
index 3998c5b..0000000
--- a/packages/SystemUI/res-keyguard/values/colors.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-
-    <!-- Clock -->
-    <color name="clock_white">#ffffffff</color>
-    <color name="clock_gray">@*android:color/secondary_text_default_material_dark</color>
-</resources>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 41c723e..a721dd0 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -48,6 +48,8 @@
 
     <!-- The size of the dots in the PIN unlock method. -->
     <dimen name="password_dot_size">9dp</dimen>
+    <!-- The size of PIN text in the PIN unlock method. -->
+    <integer name="scaled_password_text_size">40</integer>
 
     <!-- The padding between chars of the password view. -->
     <dimen name="password_char_padding">8dp</dimen>
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 1efa3a8..cb23cf3 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -48,6 +48,9 @@
          to unlock the keyguard.  Displayed in one line in a large font.  -->
     <string name="keyguard_password_wrong_pin_code">Incorrect PIN code.</string>
 
+    <!-- Shown in the lock screen when there is SIM card IO error. -->
+    <string name="keyguard_sim_error_message_short">Invalid Card.</string>
+
     <!-- When the lock screen is showing, the phone is plugged in and the battery is fully
          charged, say that it is charged. -->
     <string name="keyguard_charged">Charged</string>
@@ -99,12 +102,12 @@
     <string name="keyguard_sim_unlock_progress_dialog_message">Unlocking SIM card\u2026</string>
 
     <!-- Time format strings for fall-back clock widget -->
-    <string name="keyguard_widget_12_hours_format" translatable="false">h\uee01mm</string>
+    <string name="keyguard_widget_12_hours_format" translatable="false">h:mm</string>
     <!-- Time format strings for fall-back clock widget -->
-    <string name="keyguard_widget_24_hours_format" translatable="false">kk\uee01mm</string>
+    <string name="keyguard_widget_24_hours_format" translatable="false">kk:mm</string>
     <!-- The character used in keyguard_widget_12_hours_format and keyguard_widget_24_hours_format
          to represent a ":". -->
-    <string name="keyguard_fancy_colon" translatable="false">\uee01</string>
+    <string name="keyguard_fancy_colon" translatable="false"></string>
 
     <!-- Accessibility description of the PIN password view. [CHAR_LIMIT=none] -->
     <string name="keyguard_accessibility_pin_area">PIN area</string>
@@ -119,6 +122,8 @@
     <!-- KeyguardPinView - accessibility support --><skip />
     <!-- Description of the Delete button in a KeyboardView. [CHAR LIMIT=NONE] -->
     <string name="keyboardview_keycode_delete">Delete</string>
+    <!-- Description of the button used to disable current carrier when the device supported embedded SIM. [CHAR LIMIT=30] -->
+    <string name="disable_carrier_button_text">Disable eSIM</string>
     <!-- Description of the Enter button in a KeyboardView. [CHAR LIMIT=NONE] -->
     <string name="keyboardview_keycode_enter">Enter</string>
 
@@ -135,9 +140,11 @@
     <!-- Instructions for using the pattern unlock screen -->
     <string name="kg_pattern_instructions">Draw your pattern</string>
     <!-- Instructions for using the SIM PIN unlock screen -->
-    <string name="kg_sim_pin_instructions">Enter SIM PIN</string>
+    <string name="kg_sim_pin_instructions">Enter SIM PIN.</string>
     <!-- Instructions for using the SIM PIN unlock screen when there's more than one SIM -->
-    <string name="kg_sim_pin_instructions_multi">Enter SIM PIN for \"<xliff:g id="carrier" example="CARD 1">%1$s</xliff:g>\"</string>
+    <string name="kg_sim_pin_instructions_multi">Enter SIM PIN for \"<xliff:g id="carrier" example="CARD 1">%1$s</xliff:g>\".</string>
+    <!-- Instructions for disabling eSIM carrier to unlock the phone with embedded SIM -->
+    <string name="kg_sim_lock_instructions_esim">Disable eSIM to use device without mobile service.</string>
     <!-- Instructions for using the PIN unlock screen -->
     <string name="kg_pin_instructions">Enter PIN</string>
     <!-- Instructions for using the password unlock screen -->
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 53a559f..826e3ea 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -20,11 +20,11 @@
 <resources>
     <!-- Keyguard PIN pad styles -->
     <style name="Keyguard.TextView" parent="@android:style/Widget.DeviceDefault.TextView">
-        <item name="android:textColor">@*android:color/primary_device_default_light</item>
+        <item name="android:textColor">?attr/wallpaperTextColorSecondary</item>
         <item name="android:textSize">@dimen/kg_status_line_font_size</item>
     </style>
     <style name="Keyguard.TextView.EmergencyButton" parent="@android:style/DeviceDefault.ButtonBar">
-        <item name="android:textColor">@*android:color/primary_device_default_light</item>
+        <item name="android:textColor">?attr/wallpaperTextColorSecondary</item>
         <item name="android:textSize">@dimen/kg_status_line_font_size</item>
         <item name="android:background">@null</item>
     </style>
@@ -32,15 +32,18 @@
         <item name="android:singleLine">true</item>
         <item name="android:gravity">center_horizontal|center_vertical</item>
         <item name="android:background">@null</item>
-        <item name="android:textSize">36sp</item>
-        <item name="android:fontFamily">sans-serif-light</item>
-        <item name="android:textColor">#ffffffff</item>
+        <item name="android:textSize">32sp</item>
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamilyLight</item>
+        <item name="android:textColor">?attr/wallpaperTextColor</item>
         <item name="android:paddingBottom">-16dp</item>
     </style>
+    <style name="Keyguard.ImageButton.NumPadEnter" parent="@android:style/Widget.ImageButton">
+        <item name="android:tint">@color/background_protected</item>
+    </style>
     <style name="Widget.TextView.NumPadKey.Klondike" parent="Widget.TextView.NumPadKey">
         <item name="android:textSize">12sp</item>
         <item name="android:fontFamily">sans-serif</item>
-        <item name="android:textColor">#80ffffff</item>
+        <item name="android:textColor">?attr/wallpaperTextColorSecondary</item>
         <item name="android:paddingBottom">0dp</item>
     </style>
 
@@ -50,19 +53,29 @@
     </style>
     <style name="widget_big_thin">
         <item name="android:textSize">@dimen/widget_big_font_size</item>
-        <item name="android:fontFamily">sans-serif-light</item>
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamilyLight</item>
+        <item name="android:fontFeatureSettings">@*android:string/config_headlineFontFeatureSettings</item>
     </style>
 
     <style name="BouncerSecurityContainer">
         <item name="android:layout_gravity">center_horizontal|bottom</item>
     </style>
 
-    <style name="PasswordTheme" parent="@android:style/Theme.DeviceDefault">
-        <item name="android:colorControlNormal">#80ffffff</item>
-        <item name="android:colorControlActivated">#80ffffff</item>
+    <style name="PasswordTheme" parent="Theme.SystemUI">
+        <item name="android:textColor">?attr/wallpaperTextColor</item>
+        <item name="android:colorControlNormal">?attr/wallpaperTextColor</item>
+        <item name="android:colorControlActivated">?attr/wallpaperTextColor</item>
+    </style>
+
+    <style name="PasswordTheme.Light" parent="Theme.SystemUI.Light">
+        <item name="android:textColor">?attr/wallpaperTextColor</item>
+        <item name="android:colorControlNormal">?attr/wallpaperTextColor</item>
+        <item name="android:colorControlActivated">?attr/wallpaperTextColor</item>
     </style>
 
     <style name="keyguard_presentation_theme" parent="@android:style/Theme.Material.NoActionBar.Fullscreen">
+        <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
+        <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item>
     </style>
 
 </resources>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_bottompath_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_bottompath_animation.xml
new file mode 100644
index 0000000..073bf6d
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_bottompath_animation.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="283"
+        android:propertyName="pathData"
+        android:valueFrom="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z"
+        android:valueTo="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+        android:valueType="pathType"
+        android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_circlepath_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_circlepath_animation.xml
new file mode 100644
index 0000000..990392d
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_circlepath_animation.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="383"
+        android:propertyName="trimPathEnd"
+        android:valueFrom="1.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_1_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_1_animation.xml
old mode 100755
new mode 100644
index 1c50165..a00d937
--- a/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_1_animation.xml
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_1_animation.xml
@@ -1,46 +1,35 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
 
-         http://www.apache.org/licenses/LICENSE-2.0
+          http://www.apache.org/licenses/LICENSE-2.0
 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="strokeColor"
-        android:valueFrom="#FFF3511E"
-        android:valueTo="#FFFFFFFF"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="1.0"
-        android:valueTo="0.5"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="383"
-        android:propertyName="trimPathStart"
-        android:valueFrom="0.5001"
-        android:valueTo="0.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_3" />
-    <objectAnimator
-        android:duration="383"
-        android:propertyName="trimPathEnd"
-        android:valueFrom="1.5"
-        android:valueTo="0.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_1" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M 0.0,-1.988645 c 1.09829830627,0.0 1.988645,0.890346693734 1.988645,1.988645 c 0.0,1.09829830627 -0.890346693734,1.988645 -1.988645,1.988645 c -1.09829830627,0.0 -1.988645,-0.890346693734 -1.988645,-1.988645 c 0.0,-1.09829830627 0.890346693734,-1.988645 1.988645,-1.988645 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_6" />
+    </set>
 </set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_2_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_2_animation.xml
deleted file mode 100755
index 598255c..0000000
--- a/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_2_animation.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="316"
-            android:propertyName="pathData"
-            android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
-            android:valueTo="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="233"
-            android:propertyName="pathData"
-            android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
-            android:valueTo="M 0.0,-1.988645 c 1.09829830627,0.0 1.988645,0.890346693734 1.988645,1.988645 c 0.0,1.09829830627 -0.890346693734,1.988645 -1.988645,1.988645 c -1.09829830627,0.0 -1.988645,-0.890346693734 -1.988645,-1.988645 c 0.0,-1.09829830627 0.890346693734,-1.988645 1.988645,-1.988645 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_1" />
-    </set>
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFF3511E"
-        android:valueTo="#FFFFFFFF"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="1.0"
-        android:valueTo="0.5"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_errorcircle_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_errorcircle_animation.xml
new file mode 100644
index 0000000..59d6232
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_errorcircle_animation.xml
@@ -0,0 +1,35 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="33"
+            android:propertyName="rotation"
+            android:valueFrom="5.0"
+            android:valueTo="5.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="366"
+            android:propertyName="rotation"
+            android:valueFrom="5.0"
+            android:valueTo="-180.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_errorexclamationdot_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_errorexclamationdot_animation.xml
new file mode 100644
index 0000000..55bfa58
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_errorexclamationdot_animation.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="283"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 12.0,12.0 c 0.0,-0.66667 0.0,-3.33333 0.0,-4.0"
+        android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_5" />
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_exclamation_dot_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_exclamation_dot_animation.xml
deleted file mode 100755
index 7e0fa43..0000000
--- a/packages/SystemUI/res/anim/error_to_trustedstate_exclamation_dot_animation.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="133"
-        android:propertyXName="translateX"
-        android:propertyYName="translateY"
-        android:pathData="M -0.00391,5.333 c 0.00065,-0.22217 0.00326,-1.11083 0.00391,-1.333"
-        android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_0" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_exclamationtop_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_exclamationtop_animation.xml
new file mode 100644
index 0000000..4c44c6b
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_exclamationtop_animation.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="283"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 0.0,-2.0 c 0.0,0.5 0.0,2.5 0.0,3.0"
+        android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_2" />
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_lock_left_side_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_lock_left_side_animation.xml
deleted file mode 100755
index f413cbf..0000000
--- a/packages/SystemUI/res/anim/error_to_trustedstate_lock_left_side_animation.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="scaleX"
-            android:valueFrom="1.33333"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="scaleX"
-            android:valueFrom="1.33333"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="scaleY"
-            android:valueFrom="1.33333"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="scaleY"
-            android:valueFrom="1.33333"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_lock_right_side_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_lock_right_side_animation.xml
deleted file mode 100755
index f413cbf..0000000
--- a/packages/SystemUI/res/anim/error_to_trustedstate_lock_right_side_animation.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="scaleX"
-            android:valueFrom="1.33333"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="scaleX"
-            android:valueFrom="1.33333"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="scaleY"
-            android:valueFrom="1.33333"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="scaleY"
-            android:valueFrom="1.33333"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_lock_top_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_lock_top_animation.xml
old mode 100755
new mode 100644
index 2518041..6f7d692
--- a/packages/SystemUI/res/anim/error_to_trustedstate_lock_top_animation.xml
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_lock_top_animation.xml
@@ -1,32 +1,31 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
 
-         http://www.apache.org/licenses/LICENSE-2.0
+          http://www.apache.org/licenses/LICENSE-2.0
 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="333"
+            android:duration="266"
             android:propertyName="scaleX"
             android:valueFrom="0.0"
             android:valueTo="0.0"
             android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="16"
+            android:duration="66"
             android:propertyName="scaleX"
             android:valueFrom="0.0"
             android:valueTo="1.0"
@@ -36,14 +35,14 @@
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="333"
+            android:duration="266"
             android:propertyName="scaleY"
             android:valueFrom="0.0"
             android:valueTo="0.0"
             android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="16"
+            android:duration="66"
             android:propertyName="scaleY"
             android:valueFrom="0.0"
             android:valueTo="1.0"
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml
old mode 100755
new mode 100644
index 15f8d2e..6821e62
--- a/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml
@@ -1,56 +1,52 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
 
-         http://www.apache.org/licenses/LICENSE-2.0
+          http://www.apache.org/licenses/LICENSE-2.0
 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="33"
+            android:duration="283"
             android:propertyName="pathData"
-            android:valueFrom="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
-            android:valueTo="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
+            android:valueFrom="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.0118713378906,7.9296875 0.0118713378906,7.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 -0.01123046875,-7.9296875 -0.01123046875,-7.9296875 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
+            android:valueTo="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.0118713378906,7.9296875 0.0118713378906,7.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 -0.01123046875,-7.9296875 -0.01123046875,-7.9296875 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
             android:valueType="pathType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="183"
-            android:propertyName="pathData"
-            android:valueFrom="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
-            android:valueTo="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.0118713378906,7.9296875 0.0118713378906,7.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 -0.01123046875,-7.9296875 -0.01123046875,-7.9296875 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="316"
+            android:duration="266"
             android:propertyName="pathData"
             android:valueFrom="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.0118713378906,7.9296875 0.0118713378906,7.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 -0.01123046875,-7.9296875 -0.01123046875,-7.9296875 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
             android:valueTo="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
             android:valueType="pathType"
-            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_4" />
+            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_3" />
     </set>
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFF3511E"
-        android:valueTo="#FFFFFFFF"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="1.0"
-        android:valueTo="0.5"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="266"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
 </set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml
old mode 100755
new mode 100644
index aa81fcf..a8251dc
--- a/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml
@@ -1,56 +1,52 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
 
-         http://www.apache.org/licenses/LICENSE-2.0
+          http://www.apache.org/licenses/LICENSE-2.0
 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="33"
+            android:duration="283"
             android:propertyName="pathData"
-            android:valueFrom="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
-            android:valueTo="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
+            android:valueFrom="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.01123046875,7.9296875 0.01123046875,7.9296875 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 -0.0108337402344,-7.92947387695 -0.0108337402344,-7.92947387695 Z"
+            android:valueTo="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.01123046875,7.9296875 0.01123046875,7.9296875 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 -0.0108337402344,-7.92947387695 -0.0108337402344,-7.92947387695 Z"
             android:valueType="pathType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="183"
-            android:propertyName="pathData"
-            android:valueFrom="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
-            android:valueTo="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.01123046875,7.9296875 0.01123046875,7.9296875 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 -0.0108337402344,-7.92947387695 -0.0108337402344,-7.92947387695 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="316"
+            android:duration="266"
             android:propertyName="pathData"
             android:valueFrom="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.01123046875,7.9296875 0.01123046875,7.9296875 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 -0.0108337402344,-7.92947387695 -0.0108337402344,-7.92947387695 Z"
             android:valueTo="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
             android:valueType="pathType"
-            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_4" />
+            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_3" />
     </set>
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFF3511E"
-        android:valueTo="#FFFFFFFF"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="1.0"
-        android:valueTo="0.5"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="266"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
 </set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_path_3_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_path_3_animation.xml
old mode 100755
new mode 100644
index f94fe0a..c1ece08
--- a/packages/SystemUI/res/anim/error_to_trustedstate_path_3_animation.xml
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_path_3_animation.xml
@@ -1,49 +1,35 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
 
-         http://www.apache.org/licenses/LICENSE-2.0
+          http://www.apache.org/licenses/LICENSE-2.0
 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="233"
+            android:duration="250"
             android:propertyName="pathData"
             android:valueFrom="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
             android:valueTo="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
             android:valueType="pathType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="366"
+            android:duration="216"
             android:propertyName="pathData"
             android:valueFrom="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
             android:valueTo="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
             android:valueType="pathType"
-            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_2" />
+            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_4" />
     </set>
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFF3511E"
-        android:valueTo="#FFFFFFFF"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="1.0"
-        android:valueTo="0.5"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
 </set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_rectangle_path_1_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_rectangle_path_1_animation.xml
deleted file mode 100755
index bcc8c41..0000000
--- a/packages/SystemUI/res/anim/error_to_trustedstate_rectangle_path_1_animation.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFF3511E"
-        android:valueTo="#FFFFFFFF"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="1.0"
-        android:valueTo="0.5"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_toppath_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_toppath_animation.xml
new file mode 100644
index 0000000..d9781df
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_toppath_animation.xml
@@ -0,0 +1,52 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="66"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueTo="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="216"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueTo="M 0.0,-6.0 l 0.0,0.0 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 l 0.0,5.0 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 l 0.0,0.0 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 l 0.0,-5.0 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_0" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="283"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_bluetooth_transient_dot_left_animation.xml b/packages/SystemUI/res/anim/ic_bluetooth_transient_dot_left_animation.xml
new file mode 100644
index 0000000..b5dd5c3
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_bluetooth_transient_dot_left_animation.xml
@@ -0,0 +1,77 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_bluetooth_transient_dot_right_animation.xml b/packages/SystemUI/res/anim/ic_bluetooth_transient_dot_right_animation.xml
new file mode 100644
index 0000000..14704bf
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_bluetooth_transient_dot_right_animation.xml
@@ -0,0 +1,77 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_bluetooth_transient_group_1_animation.xml b/packages/SystemUI/res/anim/ic_bluetooth_transient_group_1_animation.xml
deleted file mode 100644
index 26c6aa7..0000000
--- a/packages/SystemUI/res/anim/ic_bluetooth_transient_group_1_animation.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleX"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleY"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_bluetooth_transient_group_2_animation.xml b/packages/SystemUI/res/anim/ic_bluetooth_transient_group_2_animation.xml
deleted file mode 100644
index e1f8989..0000000
--- a/packages/SystemUI/res/anim/ic_bluetooth_transient_group_2_animation.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleX"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_bluetooth_transient_animation_interpolator_0" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleY"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_bluetooth_transient_animation_interpolator_0" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_caret_down_left_animation.xml b/packages/SystemUI/res/anim/ic_caret_down_left_animation.xml
new file mode 100644
index 0000000..d465f19
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_caret_down_left_animation.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 12.699,8.701 c 0.0,1.09767 0.0,5.48833 0.0,6.586"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <objectAnimator
+        android:duration="200"
+        android:propertyName="rotation"
+        android:valueFrom="-45.0"
+        android:valueTo="45.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_caret_down_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_caret_down_right_animation.xml b/packages/SystemUI/res/anim/ic_caret_down_right_animation.xml
new file mode 100644
index 0000000..7a38ac3
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_caret_down_right_animation.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 11.287,8.701 c 0.0,1.09767 0.0,5.48833 0.0,6.586"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <objectAnimator
+        android:duration="200"
+        android:propertyName="rotation"
+        android:valueFrom="45.0"
+        android:valueTo="-45.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_caret_down_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_caret_up_left_animation.xml b/packages/SystemUI/res/anim/ic_caret_up_left_animation.xml
new file mode 100644
index 0000000..125a616
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_caret_up_left_animation.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 12.699,15.287 c -0.04833,0.452 -0.04833,-7.03583 0.0,-6.586"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <objectAnimator
+        android:duration="200"
+        android:propertyName="rotation"
+        android:valueFrom="45.0"
+        android:valueTo="-45.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_caret_up_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_caret_up_right_animation.xml b/packages/SystemUI/res/anim/ic_caret_up_right_animation.xml
new file mode 100644
index 0000000..3fd4df5
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_caret_up_right_animation.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 11.287,15.287 c 0.04883,0.452 0.04883,-7.03583 0.0,-6.586"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <objectAnimator
+        android:duration="200"
+        android:propertyName="rotation"
+        android:valueFrom="-45.0"
+        android:valueTo="45.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_caret_up_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_dnd_disable_bar01_0_animation.xml b/packages/SystemUI/res/anim/ic_dnd_disable_bar01_0_animation.xml
deleted file mode 100644
index a914687c..0000000
--- a/packages/SystemUI/res/anim/ic_dnd_disable_bar01_0_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 0.680404663086,3.53039550781 c 0.0,0.0 -0.01416015625,0.00492858886719 -0.01416015625,0.00492858886719 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 0.0151519775391,-0.00492858886719 0.0151519775391,-0.00492858886719 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z"
-        android:valueTo="M 0.680404663086,3.53039550781 c 0.0,0.0 20.0110015869,20.0110015869 20.0110015869,20.0110015869 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 -20.0100097656,-20.0110015869 -20.0100097656,-20.0110015869 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_dnd_disable_mask_1_animation.xml b/packages/SystemUI/res/anim/ic_dnd_disable_mask_1_animation.xml
deleted file mode 100644
index 3c60c013..0000000
--- a/packages/SystemUI/res/anim/ic_dnd_disable_mask_1_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 0.219390869141,0.219299316406 0.219390869141,0.219299316406 c 0.0,0.0 -1.41998291016,1.40998840332 -1.41998291016,1.40998840332 c 0.0,0.0 -0.219390869141,-0.219299316406 -0.219390869141,-0.219299316406 Z"
-        android:valueTo="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 20.4531555176,20.4530792236 20.4531555176,20.4530792236 c 0.0,0.0 -1.41999816895,1.40995788574 -1.41999816895,1.40995788574 c 0.0,0.0 -20.4531402588,-20.4530487061 -20.4531402588,-20.4530487061 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_mask_1_animation.xml b/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_mask_1_animation.xml
deleted file mode 100644
index 8d3296e..0000000
--- a/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_mask_1_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 0.219390869141,0.219299316406 0.219390869141,0.219299316406 c 0.0,0.0 -1.41998291016,1.40998840332 -1.41998291016,1.40998840332 c 0.0,0.0 -0.219390869141,-0.219299316406 -0.219390869141,-0.219299316406 Z"
-        android:valueTo="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 19.8804626465,19.8695220947 19.8804626465,19.8695220947 c 0.0,0.0 -1.41999816895,1.40995788574 -1.41999816895,1.40995788574 c 0.0,0.0 -19.8804473877,-19.8694915771 -19.8804473877,-19.8694915771 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_outer_ring_merged_animation.xml b/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_outer_ring_merged_animation.xml
deleted file mode 100644
index 2626499..0000000
--- a/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_outer_ring_merged_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 0.0,-10.0 c -5.5,0.0 -10.0,4.5 -10.0,10.0 c 0.0,5.5 4.5,10.0 10.0,10.0 c 5.5,0.0 10.0,-4.5 10.0,-10.0 c 0.0,-5.5 -4.5,-10.0 -10.0,-10.0 Z M 0.0,8.5 c -4.69999694824,0.0 -8.5,-3.80000305176 -8.5,-8.5 c 0.0,-4.69999694824 3.80000305176,-8.5 8.5,-8.5 c 4.69999694824,0.0 8.5,3.80000305176 8.5,8.5 c 0.0,4.69999694824 -3.80000305176,8.5 -8.5,8.5 Z M -11.3195953369,-8.46960449219 c 0.0,0.0 -0.0141754150391,0.00492858886719 -0.014175415039,0.00492858886719 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 0.0151672363281,-0.00492858886719 0.0151672363281,-0.00492858886719 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z M 3.0,1.0 c 0.0,0.0 -6.0,0.0 -6.0,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 c 0.0,0.0 6.0,0.0 6.0,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 Z M 0.0,-6.0 c -3.30000305176,0.0 -6.0,2.69999694824 -6.0,6.0 c 0.0,3.30000305176 2.69999694824,6.0 6.0,6.0 c 3.30000305176,0.0 6.0,-2.69999694824 6.0,-6.0 c 0.0,-3.30000305176 -2.60000610352,-6.0 -6.0,-6.0 Z"
-        android:valueTo="M 0.0,-10.0 c -5.5,0.0 -10.0,4.5 -10.0,10.0 c 0.0,5.5 4.5,10.0 10.0,10.0 c 5.5,0.0 10.0,-4.5 10.0,-10.0 c 0.0,-5.5 -4.5,-10.0 -10.0,-10.0 Z M 0.0,8.5 c -4.69999694824,0.0 -8.5,-3.80000305176 -8.5,-8.5 c 0.0,-4.69999694824 3.80000305176,-8.5 8.5,-8.5 c 4.69999694824,0.0 8.5,3.80000305176 8.5,8.5 c 0.0,4.69999694824 -3.80000305176,8.5 -8.5,8.5 Z M -11.3195953369,-8.46960449219 c 0.0,0.0 20.0109863281,20.0110015869 20.0109863281,20.0110015869 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 -20.0099945068,-20.0110015869 -20.0099945068,-20.0110015869 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z M 5.0,1.0 c 0.0,0.0 -10.0,0.0 -10.0,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 c 0.0,0.0 10.0,0.0 10.0,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 Z M 0.0,-10.0 c -5.52000427246,0.0 -10.0,4.47999572754 -10.0,10.0 c 0.0,5.52000427246 4.47999572754,10.0 10.0,10.0 c 5.52000427246,0.0 10.0,-4.47999572754 10.0,-10.0 c 0.0,-5.52000427246 -4.47999572754,-10.0 -10.0,-10.0 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_bottompath_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_bottompath_animation.xml
new file mode 100644
index 0000000..91829c0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_bottompath_animation.xml
@@ -0,0 +1,35 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="316"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="83"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_5" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_circlepath_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_circlepath_animation.xml
new file mode 100644
index 0000000..9b08fa2
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_circlepath_animation.xml
@@ -0,0 +1,35 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="533"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_errorcircle_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_errorcircle_animation.xml
new file mode 100644
index 0000000..1ea2100
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_errorcircle_animation.xml
@@ -0,0 +1,35 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="150"
+            android:propertyName="rotation"
+            android:valueFrom="190.0"
+            android:valueTo="190.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="549"
+            android:propertyName="rotation"
+            android:valueFrom="190.0"
+            android:valueTo="-6.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_2" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_errorexclamation_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_errorexclamation_animation.xml
new file mode 100644
index 0000000..0b9cb95
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_errorexclamation_animation.xml
@@ -0,0 +1,35 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="rotation"
+            android:valueFrom="180.0"
+            android:valueTo="180.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="499"
+            android:propertyName="rotation"
+            android:valueFrom="180.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_6" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_exclamationbottom_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_exclamationbottom_animation.xml
new file mode 100644
index 0000000..c597b82
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_exclamationbottom_animation.xml
@@ -0,0 +1,17 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" />
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_exclamationtop_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_exclamationtop_animation.xml
new file mode 100644
index 0000000..bde83de
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_exclamationtop_animation.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="700"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 0.0,0.0 c 0.0,-0.33333 0.0,-1.66667 0.0,-2.0"
+        android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_3" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_fingerprinterror_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_fingerprinterror_animation.xml
new file mode 100644
index 0000000..a3afaef
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_fingerprinterror_animation.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="100"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="566"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="-305.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_2" />
+        <objectAnimator
+            android:duration="1066"
+            android:propertyName="rotation"
+            android:valueFrom="-305.0"
+            android:valueTo="-305.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_0" />
+        <objectAnimator
+            android:duration="800"
+            android:propertyName="rotation"
+            android:valueFrom="-305.0"
+            android:valueTo="-720.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_0" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_fingerprintwhite_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_fingerprintwhite_animation.xml
new file mode 100644
index 0000000..a3afaef
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_fingerprintwhite_animation.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="100"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="566"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="-305.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_2" />
+        <objectAnimator
+            android:duration="1066"
+            android:propertyName="rotation"
+            android:valueFrom="-305.0"
+            android:valueTo="-305.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_0" />
+        <objectAnimator
+            android:duration="800"
+            android:propertyName="rotation"
+            android:valueFrom="-305.0"
+            android:valueTo="-720.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_0" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_1_path_0_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_1_path_0_animation.xml
new file mode 100644
index 0000000..1c3a766f
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_1_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="133"
+        android:propertyName="trimPathEnd"
+        android:valueFrom="0.0"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="100"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="100"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_1_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_1_path_animation.xml
new file mode 100644
index 0000000..5a9258a
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_1_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="66"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_2_path_0_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_2_path_0_animation.xml
new file mode 100644
index 0000000..04b8b80
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_2_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_2" />
+    </set>
+    <objectAnimator
+        android:duration="166"
+        android:propertyName="trimPathStart"
+        android:valueFrom="1.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_2" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_2_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_2_path_animation.xml
new file mode 100644
index 0000000..c69001c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_2_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="133"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_5_path_0_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_5_path_0_animation.xml
new file mode 100644
index 0000000..6fb22cd
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_5_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="166"
+        android:propertyName="trimPathEnd"
+        android:valueFrom="0.0"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="150"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_5_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_5_path_animation.xml
new file mode 100644
index 0000000..8e9a0510
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_5_path_animation.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="150"
+        android:propertyName="trimPathStart"
+        android:valueFrom="0.0"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/linear" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_6_path_0_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_6_path_0_animation.xml
new file mode 100644
index 0000000..3ffb8f8
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_6_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyName="trimPathEnd"
+        android:valueFrom="0.0"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_0" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="133"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="199"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_0" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_6_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_6_path_animation.xml
new file mode 100644
index 0000000..3584f91
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_6_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="216"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_7_path_0_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_7_path_0_animation.xml
new file mode 100644
index 0000000..0d44810
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_7_path_0_animation.xml
@@ -0,0 +1,53 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="216"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="133"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="199"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_7_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_7_path_animation.xml
new file mode 100644
index 0000000..52a5b3e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_7_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="33"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="150"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_toppath_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_toppath_animation.xml
new file mode 100644
index 0000000..ff7420b
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_toppath_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M -1.0,0.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M -1.0,0.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="499"
+            android:propertyName="pathData"
+            android:valueFrom="M -1.0,0.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_4" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_bottompath_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_bottompath_animation.xml
new file mode 100644
index 0000000..4bc18f2
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_bottompath_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="250"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z"
+            android:valueTo="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="150"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z"
+            android:valueTo="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_circlepath_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_circlepath_animation.xml
new file mode 100644
index 0000000..9273b9a
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_circlepath_animation.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="383"
+        android:propertyName="trimPathEnd"
+        android:valueFrom="1.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_4" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_errorcircle_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_errorcircle_animation.xml
new file mode 100644
index 0000000..062c6a0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_errorcircle_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="33"
+            android:propertyName="rotation"
+            android:valueFrom="10.0"
+            android:valueTo="10.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="366"
+            android:propertyName="rotation"
+            android:valueFrom="10.0"
+            android:valueTo="-180.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_2" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_errorexclamation_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_errorexclamation_animation.xml
new file mode 100644
index 0000000..5d4b268
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_errorexclamation_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="33"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="416"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="-180.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_5" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_exclamationbottom_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_exclamationbottom_animation.xml
new file mode 100644
index 0000000..d3d7d1c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_exclamationbottom_animation.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="450"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 0.0,4.0 c 0.0,-0.66667 0.0,-3.33333 0.0,-4.0"
+        android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_exclamationtop_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_exclamationtop_animation.xml
new file mode 100644
index 0000000..04b6868
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_exclamationtop_animation.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="450"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 0.0,-2.0 c 0.0,0.33333 0.0,1.66667 0.0,2.0"
+        android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_3" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_fingerprintwhite_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_fingerprintwhite_animation.xml
new file mode 100644
index 0000000..25f2c43
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_fingerprintwhite_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="rotation"
+            android:valueFrom="180.0"
+            android:valueTo="180.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="499"
+            android:propertyName="rotation"
+            android:valueFrom="180.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_2" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_1_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_1_path_animation.xml
new file mode 100644
index 0000000..4a6f39a
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_1_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="416"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_2_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_2_path_animation.xml
new file mode 100644
index 0000000..c9a9f64
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_2_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_5_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_5_path_animation.xml
new file mode 100644
index 0000000..43e44cf
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_5_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_6_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_6_path_animation.xml
new file mode 100644
index 0000000..04a6036
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_6_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="250"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="250"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_7_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_7_path_animation.xml
new file mode 100644
index 0000000..031c5e6
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_7_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="266"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="433"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_toppath_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_toppath_animation.xml
new file mode 100644
index 0000000..9b3498f
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_toppath_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueTo="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="250"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueTo="M -1.0,0.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_hotspot_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_hotspot_disable_animation_cross_1.xml
deleted file mode 100644
index ad06d8e..0000000
--- a/packages/SystemUI/res/anim/ic_hotspot_disable_animation_cross_1.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 4.44044494629,2.24310302734 c 0.0,0.0 0.0875396728516,0.112457275391 0.0875396728516,0.112457275391 "
-        android:valueTo="M 4.44044494629,2.24310302734 c 0.0,0.0 35.4000396729,35.3999633789 35.4000396729,35.3999633789 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_hotspot_disable_cross_1_pathdata_interpolator" />
-    <objectAnimator
-        android:duration="17"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="0"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_hotspot_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_hotspot_disable_animation_mask.xml
deleted file mode 100644
index 4cd8ce9..0000000
--- a/packages/SystemUI/res/anim/ic_hotspot_disable_animation_mask.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="pathData"
-            android:valueFrom="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 6.97125244141,7.33258056641 6.97125244141,7.33258056641 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -6.77128601074,-6.82850646973 -6.77128601074,-6.82850646973 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.659332275391,0.664688110352 0.659332275391,0.664688110351 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 29.0108337402,34.4080963135 29.0108337402,34.4080963135 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueTo="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 29.8566131592,30.1964874268 29.8566131592,30.1964874268 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -29.6566467285,-29.6924133301 -29.6566467285,-29.6924133301 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.905746459961,0.856552124023 0.905746459961,0.856552124023 c 0.0,0.0 -3.13299560547,2.82975769043 -3.13299560547,2.82975769043 c 0.0,0.0 28.7644195557,34.2162475586 28.7644195557,34.2162475586 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/ic_hotspot_disable_mask_pathdata_interpolator_1" />
-        <objectAnimator
-            android:duration="233"
-            android:propertyName="pathData"
-            android:valueFrom="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 29.8566131592,30.1964874268 29.8566131592,30.1964874268 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -29.6566467285,-29.6924133301 -29.6566467285,-29.6924133301 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.905746459961,0.856552124023 0.905746459961,0.856552124023 c 0.0,0.0 -3.13299560547,2.82975769043 -3.13299560547,2.82975769043 c 0.0,0.0 28.7644195557,34.2162475586 28.7644195557,34.2162475586 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueTo="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 43.1884765625,43.515335083 43.1884765625,43.515335083 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -42.9885101318,-43.0112609863 -42.9885101318,-43.0112609863 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 13.0984039307,13.025604248 13.0984039307,13.025604248 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 16.571762085,22.0471801758 16.571762085,22.0471801758 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/ic_hotspot_disable_mask_pathdata_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_hotspot_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_hotspot_enable_animation_cross_1.xml
deleted file mode 100644
index 523e53a..0000000
--- a/packages/SystemUI/res/anim/ic_hotspot_enable_animation_cross_1.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 4.44044494629,2.24310302734 c 0.0,0.0 35.4000396729,35.3999633789 35.4000396729,35.3999633789 "
-        android:valueTo="M 4.44044494629,2.24310302734 c 0.0,0.0 0.0875396728516,0.112457275391 0.0875396728516,0.112457275391 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_hotspot_enable_cross_1_pathdata_interpolator" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="17"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_hotspot_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_hotspot_enable_animation_mask.xml
deleted file mode 100644
index 7562c9b..0000000
--- a/packages/SystemUI/res/anim/ic_hotspot_enable_animation_mask.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="233"
-            android:propertyName="pathData"
-            android:valueFrom="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 43.1884765625,43.515335083 43.1884765625,43.515335083 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -42.9885101318,-43.0112609863 -42.9885101318,-43.0112609863 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 13.0984039307,13.025604248 13.0984039307,13.025604248 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 16.571762085,22.0471801758 16.571762085,22.0471801758 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueTo="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 29.8566131592,30.1964874268 29.8566131592,30.1964874268 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -29.6566467285,-29.6924133301 -29.6566467285,-29.6924133301 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.905746459961,0.856552124023 0.905746459961,0.856552124023 c 0.0,0.0 -3.13299560547,2.82975769043 -3.13299560547,2.82975769043 c 0.0,0.0 28.7644195557,34.2162475586 28.7644195557,34.2162475586 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/ic_hotspot_enable_mask_pathdata_interpolator_1" />
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="pathData"
-            android:valueFrom="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 29.8566131592,30.1964874268 29.8566131592,30.1964874268 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -29.6566467285,-29.6924133301 -29.6566467285,-29.6924133301 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.905746459961,0.856552124023 0.905746459961,0.856552124023 c 0.0,0.0 -3.13299560547,2.82975769043 -3.13299560547,2.82975769043 c 0.0,0.0 28.7644195557,34.2162475586 28.7644195557,34.2162475586 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueTo="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 6.97125244141,7.33258056641 6.97125244141,7.33258056641 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -6.77128601074,-6.82850646973 -6.77128601074,-6.82850646973 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.659332275391,0.664688110352 0.659332275391,0.664688110351 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 29.0108337402,34.4080963135 29.0108337402,34.4080963135 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/ic_hotspot_enable_mask_pathdata_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_hotspot_transient_circle_1_animation.xml b/packages/SystemUI/res/anim/ic_hotspot_transient_circle_1_animation.xml
index 3444747..5e71847 100644
--- a/packages/SystemUI/res/anim/ic_hotspot_transient_circle_1_animation.xml
+++ b/packages/SystemUI/res/anim/ic_hotspot_transient_circle_1_animation.xml
@@ -1,16 +1,24 @@
 <?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.
+-->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="266"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
             android:duration="16"
             android:propertyName="fillAlpha"
             android:valueFrom="1.0"
@@ -18,7 +26,7 @@
             android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="433"
+            android:duration="633"
             android:propertyName="fillAlpha"
             android:valueFrom="0.5"
             android:valueTo="0.5"
diff --git a/packages/SystemUI/res/anim/ic_hotspot_transient_circle_2_animation.xml b/packages/SystemUI/res/anim/ic_hotspot_transient_circle_2_animation.xml
index 06e08cd9..9081e6f 100644
--- a/packages/SystemUI/res/anim/ic_hotspot_transient_circle_2_animation.xml
+++ b/packages/SystemUI/res/anim/ic_hotspot_transient_circle_2_animation.xml
@@ -1,10 +1,25 @@
 <?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.
+-->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="133"
+            android:duration="200"
             android:propertyName="fillAlpha"
             android:valueFrom="1.0"
             android:valueTo="1.0"
@@ -18,7 +33,7 @@
             android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="433"
+            android:duration="633"
             android:propertyName="fillAlpha"
             android:valueFrom="0.5"
             android:valueTo="0.5"
diff --git a/packages/SystemUI/res/anim/ic_hotspot_transient_circle_3_animation.xml b/packages/SystemUI/res/anim/ic_hotspot_transient_circle_3_animation.xml
index 6b01687..eaf5f05 100644
--- a/packages/SystemUI/res/anim/ic_hotspot_transient_circle_3_animation.xml
+++ b/packages/SystemUI/res/anim/ic_hotspot_transient_circle_3_animation.xml
@@ -1,9 +1,31 @@
 <?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.
+-->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
+            android:duration="400"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
             android:duration="16"
             android:propertyName="fillAlpha"
             android:valueFrom="1.0"
@@ -11,7 +33,7 @@
             android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="433"
+            android:duration="633"
             android:propertyName="fillAlpha"
             android:valueFrom="0.5"
             android:valueTo="0.5"
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_cross_1.xml
deleted file mode 100644
index 5e78f4c..0000000
--- a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_cross_1.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator" />
-    <objectAnimator
-        android:duration="17"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="0"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_icon.xml b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_icon.xml
deleted file mode 100644
index 9cc3b8e..0000000
--- a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_icon.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_mask.xml
deleted file mode 100644
index 7f77372..0000000
--- a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_mask.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_cross_1.xml
deleted file mode 100644
index eacd248..0000000
--- a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_cross_1.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="17"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_icon.xml b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_icon.xml
deleted file mode 100644
index 50a1af6..0000000
--- a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_icon.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="0.54"
-            android:valueTo="0.54"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="0.54"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_mask.xml
deleted file mode 100644
index a2126a0..0000000
--- a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_mask.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_invert_colors_enable_mask_pathdata_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml
deleted file mode 100644
index b003e92..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="367"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml
deleted file mode 100644
index b003e92..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="367"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml
deleted file mode 100644
index 5c37479..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <objectAnimator
-        android:duration="450"
-        android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-135"
-        android:interpolator="@interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml
deleted file mode 100644
index aa086c9..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="67"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="217"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
deleted file mode 100644
index 27fd653..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="400"
-        android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-45"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml
deleted file mode 100644
index fa10b119..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml
deleted file mode 100644
index fa10b119..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml
deleted file mode 100644
index caae73a..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="333"
-        android:propertyName="scaleX"
-        android:valueFrom="0.9"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-    <objectAnimator
-        android:duration="333"
-        android:propertyName="scaleY"
-        android:valueFrom="0.9"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-    <objectAnimator
-        android:duration="450"
-        android:propertyName="rotation"
-        android:valueFrom="-135"
-        android:valueTo="0"
-        android:interpolator="@interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml
deleted file mode 100644
index aa22c3b..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="67"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="217"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml
deleted file mode 100644
index 2530f08..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="400"
-        android:propertyName="rotation"
-        android:valueFrom="-45"
-        android:valueTo="0"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml
new file mode 100644
index 0000000..8fdad80
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="616"
+        android:propertyName="rotation"
+        android:valueFrom="-90.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml
new file mode 100644
index 0000000..3c3c131
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="83"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml
new file mode 100644
index 0000000..57132e1
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="466"
+        android:propertyName="scaleX"
+        android:valueFrom="1.0"
+        android:valueTo="0.909"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_landscape_to_rotate_animation_interpolator_0" />
+    <objectAnimator
+        android:duration="466"
+        android:propertyName="scaleY"
+        android:valueFrom="1.0"
+        android:valueTo="0.909"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_landscape_to_rotate_animation_interpolator_0" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="400"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="45.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml
deleted file mode 100644
index 4e20d81..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml
deleted file mode 100644
index 4e20d81..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml
deleted file mode 100644
index 61bdfea..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <objectAnimator
-        android:duration="617"
-        android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-221"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml
deleted file mode 100644
index 6a0a20b..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="400"
-        android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-135"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml
deleted file mode 100644
index 92b19ad..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="167"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="217"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
deleted file mode 100644
index 682dcf3..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml
deleted file mode 100644
index 682dcf3..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml
deleted file mode 100644
index 9fa8ec0..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="scaleX"
-            android:valueFrom="0.9"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="0.9"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="scaleY"
-            android:valueFrom="0.9"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="0.9"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <objectAnimator
-        android:duration="617"
-        android:propertyName="rotation"
-        android:valueFrom="-221"
-        android:valueTo="0"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml
deleted file mode 100644
index 3208eee..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="rotation"
-            android:valueFrom="-135"
-            android:valueTo="-135"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="rotation"
-            android:valueFrom="-135"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml
deleted file mode 100644
index c1124af..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="500"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml
new file mode 100644
index 0000000..ad2a5fa
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml
@@ -0,0 +1,53 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="scaleX"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleX"
+            android:valueFrom="1.0"
+            android:valueTo="0.9"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="scaleY"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleY"
+            android:valueFrom="1.0"
+            android:valueTo="0.9"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml
new file mode 100644
index 0000000..cdb7890
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="616"
+        android:propertyName="rotation"
+        android:valueFrom="0.0"
+        android:valueTo="-221.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml
new file mode 100644
index 0000000..46100b4
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="400"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="83"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml
new file mode 100644
index 0000000..8f6d24d
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="400"
+        android:propertyName="rotation"
+        android:valueFrom="0.0"
+        android:valueTo="-135.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml
new file mode 100644
index 0000000..300ed53
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="66"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="216"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml
new file mode 100644
index 0000000..ad2a5fa
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml
@@ -0,0 +1,53 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="scaleX"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleX"
+            android:valueFrom="1.0"
+            android:valueTo="0.9"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="scaleY"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleY"
+            android:valueFrom="1.0"
+            android:valueTo="0.9"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml
new file mode 100644
index 0000000..c152152
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="616"
+        android:propertyName="rotation"
+        android:valueFrom="0.0"
+        android:valueTo="-180.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml
new file mode 100644
index 0000000..b2c1eb8
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="83"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml
new file mode 100644
index 0000000..2a9bbe3
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml
@@ -0,0 +1,60 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="scaleX"
+            android:valueFrom="0.909"
+            android:valueTo="0.909"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="scaleX"
+            android:valueFrom="0.909"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_rotate_to_landscape_animation_interpolator_0" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="scaleY"
+            android:valueFrom="0.909"
+            android:valueTo="0.909"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="scaleY"
+            android:valueFrom="0.909"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_rotate_to_landscape_animation_interpolator_0" />
+    </set>
+    <objectAnimator
+        android:duration="616"
+        android:propertyName="rotation"
+        android:valueFrom="45.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml
new file mode 100644
index 0000000..ce26770
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="466"
+        android:propertyName="scaleX"
+        android:valueFrom="0.9"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_rotate_to_portrait_animation_interpolator_0" />
+    <objectAnimator
+        android:duration="466"
+        android:propertyName="scaleY"
+        android:valueFrom="0.9"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_rotate_to_portrait_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml
new file mode 100644
index 0000000..6e8941d
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="616"
+        android:propertyName="rotation"
+        android:valueFrom="-221.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml
new file mode 100644
index 0000000..3c3c131
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="83"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml
new file mode 100644
index 0000000..fd8e4f8
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="rotation"
+            android:valueFrom="-135.0"
+            android:valueTo="-135.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="400"
+            android:propertyName="rotation"
+            android:valueFrom="-135.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml
new file mode 100644
index 0000000..a77a536
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="500"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_cross_1.xml
deleted file mode 100644
index 39e4aec..0000000
--- a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_cross_1.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator" />
-    <objectAnimator
-        android:duration="17"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="0"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_ic_signal_airplane.xml b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_ic_signal_airplane.xml
deleted file mode 100644
index 9cc3b8e..0000000
--- a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_ic_signal_airplane.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_mask.xml
deleted file mode 100644
index 7f77372..0000000
--- a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_mask.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_cross_1.xml
deleted file mode 100644
index 1b73cc0..0000000
--- a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_cross_1.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="17"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_ic_signal_airplane.xml b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_ic_signal_airplane.xml
deleted file mode 100644
index 5fdb2a0..0000000
--- a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_ic_signal_airplane.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_mask.xml
deleted file mode 100644
index c45426c..0000000
--- a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_mask.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_cross_1.xml
deleted file mode 100644
index b9b19f5..0000000
--- a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_cross_1.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
-        android:valueTo="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="17"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="0"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_ic_signal_flashlight.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_ic_signal_flashlight.xml
deleted file mode 100644
index 9cc3b8e..0000000
--- a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_ic_signal_flashlight.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_mask.xml
deleted file mode 100644
index 321a965..0000000
--- a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_mask.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_cross_1.xml
deleted file mode 100644
index 011a96f..0000000
--- a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_cross_1.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
-        android:valueTo="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="17"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_ic_signal_flashlight.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_ic_signal_flashlight.xml
deleted file mode 100644
index 5fdb2a0..0000000
--- a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_ic_signal_flashlight.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_mask.xml
deleted file mode 100644
index 14bab3a..0000000
--- a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_mask.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_cross_1.xml
deleted file mode 100644
index 0c57530..0000000
--- a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_cross_1.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
-        android:valueTo="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="17"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="0"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_ic_signal_location.xml b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_ic_signal_location.xml
deleted file mode 100644
index 9cc3b8e..0000000
--- a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_ic_signal_location.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_mask.xml
deleted file mode 100644
index 501d68b..0000000
--- a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_mask.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_cross_1.xml
deleted file mode 100644
index 1b5445d..0000000
--- a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_cross_1.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
-        android:valueTo="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="17"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_ic_signal_location.xml b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_ic_signal_location.xml
deleted file mode 100644
index 5fdb2a0..0000000
--- a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_ic_signal_location.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_mask.xml
deleted file mode 100644
index 9ca12da..0000000
--- a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_mask.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_location_enable_mask_pathdata_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_cross_1.xml
deleted file mode 100644
index 661ab08..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_cross_1.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator" />
-    <objectAnimator
-        android:duration="17"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="0"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_mask.xml
deleted file mode 100644
index 1199442..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_mask.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml
deleted file mode 100644
index 6c7e751..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="17"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml
deleted file mode 100644
index c699fe2..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml
deleted file mode 100644
index 5595e5c..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_volume_collapse_chevron_02_animation.xml b/packages/SystemUI/res/anim/ic_volume_collapse_chevron_02_animation.xml
deleted file mode 100644
index 443f2a6..0000000
--- a/packages/SystemUI/res/anim/ic_volume_collapse_chevron_02_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <objectAnimator
-        android:duration="250"
-        android:interpolator="@android:interpolator/fast_out_slow_in"
-        android:pathData="M 12.0,9.0 c 0.0,0.66667 0.0,5.0 0.0,6.0"
-        android:propertyXName="translateX"
-        android:propertyYName="translateY" />
-
-</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/ic_volume_collapse_rectangle_1_animation.xml b/packages/SystemUI/res/anim/ic_volume_collapse_rectangle_1_animation.xml
deleted file mode 100644
index d82f670..0000000
--- a/packages/SystemUI/res/anim/ic_volume_collapse_rectangle_1_animation.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <objectAnimator
-        android:duration="200"
-        android:interpolator="@interpolator/ic_volume_collapse_animation_interpolator_0"
-        android:propertyName="rotation"
-        android:valueFrom="45.0"
-        android:valueTo="-45.0"
-        android:valueType="floatType" />
-
-</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/ic_volume_collapse_rectangle_2_animation.xml b/packages/SystemUI/res/anim/ic_volume_collapse_rectangle_2_animation.xml
deleted file mode 100644
index 0bc66bd..0000000
--- a/packages/SystemUI/res/anim/ic_volume_collapse_rectangle_2_animation.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <objectAnimator
-        android:duration="200"
-        android:interpolator="@interpolator/ic_volume_collapse_animation_interpolator_0"
-        android:propertyName="rotation"
-        android:valueFrom="-45.0"
-        android:valueTo="45.0"
-        android:valueType="floatType" />
-
-</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/ic_volume_expand_chevron_01_animation.xml b/packages/SystemUI/res/anim/ic_volume_expand_chevron_01_animation.xml
deleted file mode 100644
index e43e645..0000000
--- a/packages/SystemUI/res/anim/ic_volume_expand_chevron_01_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <objectAnimator
-        android:duration="250"
-        android:interpolator="@android:interpolator/fast_out_slow_in"
-        android:pathData="M 12.0,15.0 c 0.0,-1.0 0.0,-5.33333 0.0,-6.0"
-        android:propertyXName="translateX"
-        android:propertyYName="translateY" />
-
-</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/ic_volume_expand_rectangle_3_animation.xml b/packages/SystemUI/res/anim/ic_volume_expand_rectangle_3_animation.xml
deleted file mode 100644
index 9b575d8..0000000
--- a/packages/SystemUI/res/anim/ic_volume_expand_rectangle_3_animation.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <objectAnimator
-        android:duration="200"
-        android:interpolator="@interpolator/ic_volume_expand_animation_interpolator_0"
-        android:propertyName="rotation"
-        android:valueFrom="45.0"
-        android:valueTo="-45.0"
-        android:valueType="floatType" />
-
-</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/ic_volume_expand_rectangle_4_animation.xml b/packages/SystemUI/res/anim/ic_volume_expand_rectangle_4_animation.xml
deleted file mode 100644
index 6ae0fef..0000000
--- a/packages/SystemUI/res/anim/ic_volume_expand_rectangle_4_animation.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <objectAnimator
-        android:duration="200"
-        android:interpolator="@interpolator/ic_volume_expand_animation_interpolator_0"
-        android:propertyName="rotation"
-        android:valueFrom="-45.0"
-        android:valueTo="45.0"
-        android:valueType="floatType" />
-
-</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_group_1_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_group_1_animation.xml
deleted file mode 100644
index 0c87c4b..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_group_1_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="416"
-        android:propertyName="rotation"
-        android:valueFrom="430.0"
-        android:valueTo="206.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_linear_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_group_2_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_group_2_animation.xml
deleted file mode 100644
index 0ff1c8c..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_group_2_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="233"
-        android:propertyName="rotation"
-        android:valueFrom="0.0"
-        android:valueTo="-289.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_1_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_1_animation.xml
deleted file mode 100644
index a1cadf8..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_1_animation.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="pathData"
-            android:valueFrom="M 1.35363769531,1.36633300781 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-8.09997558594 0.0,-8.09997558594 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,8.09997558594 0.0,8.09997558594 Z"
-            android:valueTo="M 1.35363769531,1.36633300781 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-8.09997558594 0.0,-8.09997558594 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,8.09997558594 0.0,8.09997558594 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="pathData"
-            android:valueFrom="M 1.35363769531,1.36633300781 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-8.09997558594 0.0,-8.09997558594 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,8.09997558594 0.0,8.09997558594 Z"
-            android:valueTo="M 1.35363769531,1.36633300781 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 -0.0213623046875,0.0250244140625 -0.0213623046875,0.0250244140625 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0213623046875,-0.0250244140625 0.0213623046875,-0.0250244140625 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_2_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_2_animation.xml
deleted file mode 100644
index 1ca49ba..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_2_animation.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="pathData"
-            android:valueFrom="M 1.35900878906,6.76104736328 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-2.69995117188 0.0,-2.69995117188 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,2.69995117188 0.0,2.69995117188 Z"
-            android:valueTo="M 1.35900878906,6.76104736328 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-2.69995117188 0.0,-2.69995117188 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,2.69995117188 0.0,2.69995117188 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="pathData"
-            android:valueFrom="M 1.35900878906,6.76104736328 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-2.69995117188 0.0,-2.69995117188 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,2.69995117188 0.0,2.69995117188 Z"
-            android:valueTo="M 1.35900878906,6.76104736328 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0340270996094,0.050048828125 0.0340270996094,0.050048828125 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 -0.0340270996094,-0.050048828125 -0.0340270996094,-0.050048828125 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_3_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_3_animation.xml
deleted file mode 100644
index 8491747..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_3_animation.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="383"
-        android:propertyName="trimPathEnd"
-        android:valueFrom="1.0"
-        android:valueTo="0.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_linear_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_1_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_1_path_animation.xml
deleted file mode 100644
index b9636ae..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_1_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="199"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_2_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_2_path_animation.xml
deleted file mode 100644
index c1a3ecf..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_2_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_3" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_5_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_5_path_animation.xml
deleted file mode 100644
index e285edc..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_5_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="216"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="316"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_0" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_6_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_6_path_animation.xml
deleted file mode 100644
index 2ea1021..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_6_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_5" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_7_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_7_path_animation.xml
deleted file mode 100644
index 1481cfa..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_7_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="233"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_white_fingerprint_ridges_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_white_fingerprint_ridges_animation.xml
deleted file mode 100644
index 9dc587c..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_white_fingerprint_ridges_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="rotation"
-            android:valueFrom="200.66753"
-            android:valueTo="200.66753"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="266"
-            android:propertyName="rotation"
-            android:valueFrom="200.66753"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_4" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_fingerprint_ridges_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_fingerprint_ridges_animation.xml
deleted file mode 100644
index ada4213..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_fingerprint_ridges_animation.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="rotation"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="516"
-            android:propertyName="rotation"
-            android:valueFrom="0.0"
-            android:valueTo="-305.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_3" />
-        <objectAnimator
-            android:duration="1116"
-            android:propertyName="rotation"
-            android:valueFrom="-305.0"
-            android:valueTo="-305.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0" />
-        <objectAnimator
-            android:duration="800"
-            android:propertyName="rotation"
-            android:valueFrom="-305.0"
-            android:valueTo="-720.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_group_1_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_group_1_animation.xml
deleted file mode 100644
index 2cdd02c..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_group_1_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="rotation"
-            android:valueFrom="231.0"
-            android:valueTo="231.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="rotation"
-            android:valueFrom="231.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_4" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_group_2_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_group_2_animation.xml
deleted file mode 100644
index 7b62f20..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_group_2_animation.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="266"
-            android:propertyName="scaleX"
-            android:valueFrom="0.63838"
-            android:valueTo="0.63838"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="316"
-            android:propertyName="scaleX"
-            android:valueFrom="0.63838"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_1" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="266"
-            android:propertyName="scaleY"
-            android:valueFrom="0.63838"
-            android:valueTo="0.63838"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="316"
-            android:propertyName="scaleY"
-            android:valueFrom="0.63838"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_1" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="266"
-            android:propertyName="rotation"
-            android:valueFrom="184.0"
-            android:valueTo="184.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="316"
-            android:propertyName="rotation"
-            android:valueFrom="184.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_4" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_1_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_1_animation.xml
deleted file mode 100644
index bdd24b7..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_1_animation.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="316"
-            android:propertyName="pathData"
-            android:valueFrom="M -1.3737487793,-6.77532958984 c 0.0,0.0 0.00604248046875,0.0166625976562 0.00604248046876,0.0166625976562 c 0.0,0.0 0.0213623046875,0.0250244140625 0.0213623046875,0.0250244140625 c 0.0,0.0 -0.00604248046875,-0.0166625976562 -0.00604248046876,-0.0166625976562 c 0.0,0.0 -0.0213623046875,-0.0250244140625 -0.0213623046875,-0.0250244140625 Z"
-            android:valueTo="M -1.3737487793,-6.77532958984 c 0.0,0.0 0.00604248046875,0.0166625976562 0.00604248046876,0.0166625976562 c 0.0,0.0 0.0213623046875,0.0250244140625 0.0213623046875,0.0250244140625 c 0.0,0.0 -0.00604248046875,-0.0166625976562 -0.00604248046876,-0.0166625976562 c 0.0,0.0 -0.0213623046875,-0.0250244140625 -0.0213623046875,-0.0250244140625 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="pathData"
-            android:valueFrom="M -1.3737487793,-6.77532958984 c 0.0,0.0 0.00604248046875,0.0166625976562 0.00604248046876,0.0166625976562 c 0.0,0.0 0.0213623046875,0.0250244140625 0.0213623046875,0.0250244140625 c 0.0,0.0 -0.00604248046875,-0.0166625976562 -0.00604248046876,-0.0166625976562 c 0.0,0.0 -0.0213623046875,-0.0250244140625 -0.0213623046875,-0.0250244140625 Z"
-            android:valueTo="M 1.33227539062,-6.75866699219 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0213623046875,0.0250244140625 0.0213623046875,0.0250244140625 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 -0.0213623046875,-0.0250244140625 -0.0213623046875,-0.0250244140625 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="pathData"
-            android:valueFrom="M 1.33227539062,-6.75866699219 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0213623046875,0.0250244140625 0.0213623046875,0.0250244140625 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 -0.0213623046875,-0.0250244140625 -0.0213623046875,-0.0250244140625 Z"
-            android:valueTo="M 1.35363769531,1.36633300781 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-8.09997558594 0.0,-8.09997558594 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,8.09997558594 0.0,8.09997558594 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_5" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_2_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_2_animation.xml
deleted file mode 100644
index 8ec7c30..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_2_animation.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="316"
-            android:propertyName="pathData"
-            android:valueFrom="M -1.3705291748,4.06730651855 c 0.0,0.0 0.036376953125,-0.0102386474609 0.036376953125,-0.0102386474609 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 -0.0161437988281,0.00479125976562 -0.0161437988281,0.00479125976563 c 0.0,0.0 -0.0134124755859,0.00141906738281 -0.0134124755859,0.00141906738281 Z"
-            android:valueTo="M -1.3705291748,4.06730651855 c 0.0,0.0 0.036376953125,-0.0102386474609 0.036376953125,-0.0102386474609 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 -0.0161437988281,0.00479125976562 -0.0161437988281,0.00479125976563 c 0.0,0.0 -0.0134124755859,0.00141906738281 -0.0134124755859,0.00141906738281 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="pathData"
-            android:valueFrom="M -1.3705291748,4.06730651855 c 0.0,0.0 0.036376953125,-0.0102386474609 0.036376953125,-0.0102386474609 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 -0.0161437988281,0.00479125976562 -0.0161437988281,0.00479125976563 c 0.0,0.0 -0.0134124755859,0.00141906738281 -0.0134124755859,0.00141906738281 Z"
-            android:valueTo="M 1.36582946777,4.05706787109 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 2.72023010254,-0.00544738769531 2.72023010254,-0.00544738769531 c 0.0,0.0 -0.013427734375,0.00141906738281 -0.013427734375,0.00141906738281 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="pathData"
-            android:valueFrom="M 1.36582946777,4.05706787109 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 2.72023010254,-0.00544738769531 2.72023010254,-0.00544738769531 c 0.0,0.0 -0.013427734375,0.00141906738281 -0.013427734375,0.00141906738281 Z"
-            android:valueTo="M 1.36582946777,4.05706787109 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.00682067871094,-0.0040283203125 0.00682067871094,-0.0040283203125 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="99"
-            android:propertyName="pathData"
-            android:valueFrom="M 1.36582946777,4.05706787109 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.00682067871094,-0.0040283203125 0.00682067871094,-0.0040283203125 Z"
-            android:valueTo="M 1.35900878906,6.76104736328 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-2.69995117188 0.0,-2.69995117188 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,2.69995117188 0.0,2.69995117188 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_5" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_3_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_3_animation.xml
deleted file mode 100644
index ec65805..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_3_animation.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_0_animation.xml
deleted file mode 100644
index 26622dd..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_0_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="133"
-        android:propertyName="trimPathEnd"
-        android:valueFrom="0.0"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_animation.xml
deleted file mode 100644
index 443e6fb..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_animation.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="66"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_0_animation.xml
deleted file mode 100644
index f383c0a..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_0_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_3" />
-    </set>
-    <objectAnimator
-        android:duration="166"
-        android:propertyName="trimPathStart"
-        android:valueFrom="1.0"
-        android:valueTo="0.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_3" />
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_animation.xml
deleted file mode 100644
index f8140d5..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_0_animation.xml
deleted file mode 100644
index 870c44d..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_0_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="166"
-        android:propertyName="trimPathEnd"
-        android:valueFrom="0.0"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="150"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="166"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_animation.xml
deleted file mode 100644
index eef1efd..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_animation.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="150"
-        android:propertyName="trimPathStart"
-        android:valueFrom="0.0"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_0_animation.xml
deleted file mode 100644
index 1b8a77f..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_0_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="250"
-        android:propertyName="trimPathEnd"
-        android:valueFrom="0.0"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="216"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_animation.xml
deleted file mode 100644
index ad37bc1..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="216"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_0_animation.xml
deleted file mode 100644
index cd04abaf6..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_0_animation.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="216"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="199"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_animation.xml
deleted file mode 100644
index a09bdea..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="150"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_white_fingerprint_ridges_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_white_fingerprint_ridges_animation.xml
deleted file mode 100644
index ada4213..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_white_fingerprint_ridges_animation.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="rotation"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="516"
-            android:propertyName="rotation"
-            android:valueFrom="0.0"
-            android:valueTo="-305.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_3" />
-        <objectAnimator
-            android:duration="1116"
-            android:propertyName="rotation"
-            android:valueFrom="-305.0"
-            android:valueTo="-305.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0" />
-        <objectAnimator
-            android:duration="800"
-            android:propertyName="rotation"
-            android:valueFrom="-305.0"
-            android:valueTo="-720.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_bottompath_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_bottompath_animation.xml
new file mode 100644
index 0000000..7a01896
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_bottompath_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="149"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_0" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_circlepath_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_circlepath_animation.xml
new file mode 100644
index 0000000..ac5e448
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_circlepath_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="100"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="450"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_1_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_1_animation.xml
old mode 100755
new mode 100644
index 5cf4809..6697316
--- a/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_1_animation.xml
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_1_animation.xml
@@ -1,66 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
 
-         http://www.apache.org/licenses/LICENSE-2.0
+          http://www.apache.org/licenses/LICENSE-2.0
 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <objectAnimator
-        android:duration="600"
-        android:propertyName="strokeColor"
-        android:valueFrom="#FFFFFFFF"
-        android:valueTo="#FFF3511E"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="0.5"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="166"
-            android:propertyName="trimPathOffset"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="433"
-            android:propertyName="trimPathOffset"
-            android:valueFrom="1.0"
-            android:valueTo="0.5"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_2" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="166"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="433"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_0" />
-    </set>
+        android:duration="200"
+        android:propertyName="pathData"
+        android:valueFrom="M 0.0,-1.988645 c 1.09829830627,0.0 1.988645,0.890346693734 1.988645,1.988645 c 0.0,1.09829830627 -0.890346693734,1.988645 -1.988645,1.988645 c -1.09829830627,0.0 -1.988645,-0.890346693734 -1.988645,-1.988645 c 0.0,-1.09829830627 0.890346693734,-1.988645 1.988645,-1.988645 Z"
+        android:valueTo="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+        android:valueType="pathType"
+        android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_0" />
 </set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_2_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_2_animation.xml
deleted file mode 100755
index a387f97..0000000
--- a/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_2_animation.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="200"
-        android:propertyName="pathData"
-        android:valueFrom="M 0.0,-1.988645 c 1.09829830627,0.0 1.988645,0.890346693734 1.988645,1.988645 c 0.0,1.09829830627 -0.890346693734,1.988645 -1.988645,1.988645 c -1.09829830627,0.0 -1.988645,-0.890346693734 -1.988645,-1.988645 c 0.0,-1.09829830627 0.890346693734,-1.988645 1.988645,-1.988645 Z"
-        android:valueTo="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFFFFFFF"
-        android:valueTo="#FFF3511E"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="0.5"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_errorcircle_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_errorcircle_animation.xml
new file mode 100644
index 0000000..903d97e
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_errorcircle_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="rotation"
+            android:valueFrom="184.0"
+            android:valueTo="184.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="450"
+            android:propertyName="rotation"
+            android:valueFrom="184.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_errorexclamationdot_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_errorexclamationdot_animation.xml
new file mode 100644
index 0000000..c5339a0
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_errorexclamationdot_animation.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="550"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 12.0,8.0 c 0.0,0.66667 0.0,3.33333 0.0,4.0"
+        android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_3" />
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_exclamation_dot_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_exclamation_dot_animation.xml
deleted file mode 100755
index 7a9fb3b..0000000
--- a/packages/SystemUI/res/anim/trusted_state_to_error_exclamation_dot_animation.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="566"
-        android:propertyXName="translateX"
-        android:propertyYName="translateY"
-        android:pathData="M 0.0,4.0 c -0.00065,0.22217 -0.00326,1.11083 -0.00391,1.333"
-        android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_1" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="300"
-            android:propertyName="scaleX"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="scaleX"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="300"
-            android:propertyName="scaleY"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="scaleY"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_exclamationtop_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_exclamationtop_animation.xml
new file mode 100644
index 0000000..c5b2c12
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_exclamationtop_animation.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="500"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 0.0,2.5 c 0.0,-0.75 0.0,-3.75 0.0,-4.5"
+        android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_4" />
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_lock_left_side_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_lock_left_side_animation.xml
deleted file mode 100755
index 2a4753a..0000000
--- a/packages/SystemUI/res/anim/trusted_state_to_error_lock_left_side_animation.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_lock_right_side_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_lock_right_side_animation.xml
deleted file mode 100755
index 2a4753a..0000000
--- a/packages/SystemUI/res/anim/trusted_state_to_error_lock_right_side_animation.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_lock_top_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_lock_top_animation.xml
old mode 100755
new mode 100644
index 1f601d3..63a25d9
--- a/packages/SystemUI/res/anim/trusted_state_to_error_lock_top_animation.xml
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_lock_top_animation.xml
@@ -1,25 +1,24 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
 
-         http://www.apache.org/licenses/LICENSE-2.0
+          http://www.apache.org/licenses/LICENSE-2.0
 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="116"
+            android:duration="150"
             android:propertyName="scaleX"
             android:valueFrom="1.0"
             android:valueTo="1.0"
@@ -36,7 +35,7 @@
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="116"
+            android:duration="150"
             android:propertyName="scaleY"
             android:valueFrom="1.0"
             android:valueTo="1.0"
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml
old mode 100755
new mode 100644
index 7b9be5c..547f42e
--- a/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml
@@ -1,56 +1,52 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
 
-         http://www.apache.org/licenses/LICENSE-2.0
+          http://www.apache.org/licenses/LICENSE-2.0
 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="33"
-            android:propertyName="pathData"
-            android:valueFrom="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
-            android:valueTo="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="166"
+            android:duration="200"
             android:propertyName="pathData"
             android:valueFrom="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
             android:valueTo="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.00064086914062,10.625 0.00064086914062,10.625 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.625 0.0,-10.625 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
             android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_0" />
         <objectAnimator
-            android:duration="200"
+            android:duration="149"
             android:propertyName="pathData"
             android:valueFrom="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.00064086914062,10.625 0.00064086914062,10.625 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.625 0.0,-10.625 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
             android:valueTo="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
             android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_5" />
     </set>
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFFFFFFF"
-        android:valueTo="#FFF3511E"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="0.5"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="183"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
 </set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml
old mode 100755
new mode 100644
index 8eb0c62..e5fe4d14
--- a/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml
@@ -1,56 +1,52 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
 
-         http://www.apache.org/licenses/LICENSE-2.0
+          http://www.apache.org/licenses/LICENSE-2.0
 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="33"
-            android:propertyName="pathData"
-            android:valueFrom="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
-            android:valueTo="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="166"
+            android:duration="200"
             android:propertyName="pathData"
             android:valueFrom="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
             android:valueTo="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.625 0.0,10.625 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 0.00039672851562,-10.624786377 0.00039672851562,-10.624786377 Z"
             android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_0" />
         <objectAnimator
-            android:duration="200"
+            android:duration="149"
             android:propertyName="pathData"
             android:valueFrom="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.625 0.0,10.625 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 0.00039672851562,-10.624786377 0.00039672851562,-10.624786377 Z"
             android:valueTo="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
             android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_5" />
     </set>
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFFFFFFF"
-        android:valueTo="#FFF3511E"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="0.5"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="183"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
 </set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_path_3_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_path_3_animation.xml
old mode 100755
new mode 100644
index 2e86744..455d0b8
--- a/packages/SystemUI/res/anim/trusted_state_to_error_path_3_animation.xml
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_path_3_animation.xml
@@ -1,39 +1,35 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
 
-         http://www.apache.org/licenses/LICENSE-2.0
+          http://www.apache.org/licenses/LICENSE-2.0
 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="200"
-        android:propertyName="pathData"
-        android:valueFrom="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
-        android:valueTo="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
-        android:valueType="pathType"
-        android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_3" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFFFFFFF"
-        android:valueTo="#FFF3511E"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="0.5"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="pathData"
+            android:valueFrom="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+            android:valueTo="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="150"
+            android:propertyName="pathData"
+            android:valueFrom="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+            android:valueTo="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_0" />
+    </set>
 </set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_rectangle_path_1_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_rectangle_path_1_animation.xml
deleted file mode 100755
index 46d571c..0000000
--- a/packages/SystemUI/res/anim/trusted_state_to_error_rectangle_path_1_animation.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFFFFFFF"
-        android:valueTo="#FFF3511E"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="0.5"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_toppath_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_toppath_animation.xml
new file mode 100644
index 0000000..b2944e5
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_toppath_animation.xml
@@ -0,0 +1,53 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 l 0.0,7.0 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 l 0.0,0.0 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 l 0.0,-7.0 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
+            android:valueTo="M 0.0,-7.0 l 0.0,0.0 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 l 0.0,7.0 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 l 0.0,0.0 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 l 0.0,-7.0 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="300"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 l 0.0,7.0 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 l 0.0,0.0 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 l 0.0,-7.0 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
+            android:valueTo="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_2" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="183"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/color/background_protect_secondary.xml b/packages/SystemUI/res/color/background_protect_secondary.xml
new file mode 100644
index 0000000..97744db
--- /dev/null
+++ b/packages/SystemUI/res/color/background_protect_secondary.xml
@@ -0,0 +1,20 @@
+<?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
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="?attr/wallpaperTextColorSecondary" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/background_protected.xml b/packages/SystemUI/res/color/background_protected.xml
new file mode 100644
index 0000000..ff2009d
--- /dev/null
+++ b/packages/SystemUI/res/color/background_protected.xml
@@ -0,0 +1,20 @@
+<?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
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="?attr/wallpaperTextColor" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/pin_delete_color.xml b/packages/SystemUI/res/color/pin_delete_color.xml
new file mode 100644
index 0000000..7d4f132
--- /dev/null
+++ b/packages/SystemUI/res/color/pin_delete_color.xml
@@ -0,0 +1,19 @@
+<?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
+  -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:alpha="0.61" android:color="?attr/wallpaperTextColor" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/pin_divider_color.xml b/packages/SystemUI/res/color/pin_divider_color.xml
new file mode 100644
index 0000000..aff2317
--- /dev/null
+++ b/packages/SystemUI/res/color/pin_divider_color.xml
@@ -0,0 +1,19 @@
+<?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
+  -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:alpha="0.45" android:color="?attr/wallpaperTextColorSecondary" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_background_dark.xml b/packages/SystemUI/res/color/qs_background_dark.xml
new file mode 100644
index 0000000..62e4959
--- /dev/null
+++ b/packages/SystemUI/res/color/qs_background_dark.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:alpha="0.93"
+          android:color="?android:attr/colorBackgroundFloating"/>
+</selector>
diff --git a/packages/SystemUI/res/drawable/brightness_mirror_background.xml b/packages/SystemUI/res/drawable/brightness_mirror_background.xml
index 0c69d89..b3a0484 100644
--- a/packages/SystemUI/res/drawable/brightness_mirror_background.xml
+++ b/packages/SystemUI/res/drawable/brightness_mirror_background.xml
@@ -15,5 +15,5 @@
   ~ limitations under the License
   -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <solid android:color="?android:attr/colorPrimary" />
+    <solid android:color="@color/qs_background_dark" />
 </shape>
diff --git a/packages/SystemUI/res/drawable/car_progress_bar.xml b/packages/SystemUI/res/drawable/car_progress_bar.xml
new file mode 100644
index 0000000..742fca7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/car_progress_bar.xml
@@ -0,0 +1,30 @@
+<!--
+  Copyright (C) 2017 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@android:id/background">
+        <shape>
+            <solid android:color="@color/car_user_switcher_progress_bgcolor" />
+        </shape>
+    </item>
+
+    <item android:id="@android:id/progress">
+        <clip>
+            <shape>
+                <solid android:color="@color/car_user_switcher_progress_fgcolor" />
+            </shape>
+        </clip>
+    </item>
+</layer-list>
diff --git a/packages/SystemUI/res/drawable/car_round_button.xml b/packages/SystemUI/res/drawable/car_round_button.xml
new file mode 100644
index 0000000..5f4deb3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/car_round_button.xml
@@ -0,0 +1,21 @@
+<!--
+  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
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+
+    <solid android:color="@color/car_start_driving_background" />
+    <corners android:radius="@dimen/car_start_driving_corner_radius" />
+</shape>
diff --git a/packages/SystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml b/packages/SystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml
index b131c38..99ee3b1 100644
--- a/packages/SystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml
+++ b/packages/SystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2016 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -16,10 +16,13 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="17dp"
         android:height="17dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M14.0,24.0l-4.0,-4.0l-4.0,4.0l4.0,4.0L14.0,24.0zM35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6zM38.0,20.0l-4.0,4.0l4.0,4.0l4.0,-4.0L38.0,20.0z"/>
+        android:viewportWidth="18.0"
+        android:viewportHeight="18.0">
+    <group
+        android:translateY="0.5"
+        android:translateX="0.5" >
+        <path
+            android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/error_to_trustedstate.xml b/packages/SystemUI/res/drawable/error_to_trustedstate.xml
index 6211edf..bc196c9 100755
--- a/packages/SystemUI/res/drawable/error_to_trustedstate.xml
+++ b/packages/SystemUI/res/drawable/error_to_trustedstate.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
+    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
 
@@ -17,50 +17,38 @@
 <vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:name="error_to_trustedstate"
-    android:width="32dp"
-    android:viewportWidth="32"
-    android:height="32dp"
-    android:viewportHeight="32" >
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:height="24dp"
+    android:viewportHeight="24" >
     <group
-        android:name="error_to_trusted_state"
-        android:translateX="16"
-        android:translateY="16" >
-        <group
-            android:name="error_circle" >
-            <path
-                android:name="ellipse_path_1"
-                android:trimPathStart="0"
-                android:trimPathEnd="1"
-                android:trimPathOffset="0.0"
-                android:strokeColor="#FFF3511E"
-                android:strokeWidth="2"
-                android:pathData="M 0.0,-12.0 c 6.6274169976,0.0 12.0,5.3725830024 12.0,12.0 c 0.0,6.6274169976 -5.3725830024,12.0 -12.0,12.0 c -6.6274169976,0.0 -12.0,-5.3725830024 -12.0,-12.0 c 0.0,-6.6274169976 5.3725830024,-12.0 12.0,-12.0 Z" />
-        </group>
+        android:name="lock"
+        android:translateX="12"
+        android:translateY="12" >
         <group
             android:name="middle_ellipse"
             android:translateY="2.9375" >
             <path
-                android:name="ellipse_path_2"
-                android:fillColor="#FFF3511E"
+                android:name="ellipse_path_1"
+                android:fillColor="?attr/wallpaperTextColor"
+                android:fillAlpha="0.5"
                 android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
         </group>
         <group
-            android:name="lock_right_side"
-            android:scaleX="1.33333"
-            android:scaleY="1.33333" >
+            android:name="lock_right_side" >
             <path
                 android:name="path_1"
-                android:pathData="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
-                android:fillColor="#FFF3511E" />
+                android:pathData="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.0118713378906,7.9296875 0.0118713378906,7.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 -0.01123046875,-7.9296875 -0.01123046875,-7.9296875 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
+                android:fillColor="?attr/wallpaperTextColor"
+                android:fillAlpha="0.5" />
         </group>
         <group
-            android:name="lock_left_side"
-            android:scaleX="1.33333"
-            android:scaleY="1.33333" >
+            android:name="lock_left_side" >
             <path
                 android:name="path_2"
-                android:pathData="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
-                android:fillColor="#FFF3511E" />
+                android:pathData="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.01123046875,7.9296875 0.01123046875,7.9296875 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 -0.0108337402344,-7.92947387695 -0.0108337402344,-7.92947387695 Z"
+                android:fillColor="?attr/wallpaperTextColor"
+                android:fillAlpha="0.5" />
         </group>
         <group
             android:name="lock_top"
@@ -69,16 +57,49 @@
             <path
                 android:name="path_3"
                 android:pathData="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
-                android:fillColor="#FFF3511E" />
+                android:fillColor="?attr/wallpaperTextColor"
+                android:fillAlpha="0.5" />
         </group>
+    </group>
+    <group
+        android:name="errorexclamationdot"
+        android:translateX="12"
+        android:translateY="12" >
         <group
-            android:name="exclamation_dot"
-            android:translateX="-0.00391"
-            android:translateY="5.333" >
+            android:name="exclamationbottom"
+            android:translateY="4" >
             <path
-                android:name="rectangle_path_1"
-                android:fillColor="#FFF3511E"
-                android:pathData="M -1.33871,-1.3335 l 2.67742,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,2.667 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.67742,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-2.667 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+                android:name="bottompath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z" />
+        </group>
+    </group>
+    <group
+        android:name="errorexclamation"
+        android:translateX="12"
+        android:translateY="12" >
+        <group
+            android:name="exclamationtop"
+            android:translateY="-2" >
+            <path
+                android:name="toppath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z" />
+        </group>
+    </group>
+    <group
+        android:name="errorcircle"
+        android:translateX="12"
+        android:translateY="12"
+        android:rotation="5" >
+        <group
+            android:name="circle" >
+            <path
+                android:name="circlepath"
+                android:strokeColor="?android:attr/colorError"
+                android:strokeWidth="2"
+                android:strokeLineCap="round"
+                android:pathData="M 0.0,-9.0 c 4.9705627482,0.0 9.0,4.0294372518 9.0,9.0 c 0.0,4.9705627482 -4.0294372518,9.0 -9.0,9.0 c -4.9705627482,0.0 -9.0,-4.0294372518 -9.0,-9.0 c 0.0,-4.9705627482 4.0294372518,-9.0 9.0,-9.0 Z" />
         </group>
     </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/error_to_trustedstate_animation.xml b/packages/SystemUI/res/drawable/error_to_trustedstate_animation.xml
index 6befe13..a494f1d 100755
--- a/packages/SystemUI/res/drawable/error_to_trustedstate_animation.xml
+++ b/packages/SystemUI/res/drawable/error_to_trustedstate_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -21,18 +21,9 @@
         android:name="ellipse_path_1"
         android:animation="@anim/error_to_trustedstate_ellipse_path_1_animation" />
     <target
-        android:name="ellipse_path_2"
-        android:animation="@anim/error_to_trustedstate_ellipse_path_2_animation" />
-    <target
-        android:name="lock_right_side"
-        android:animation="@anim/error_to_trustedstate_lock_right_side_animation" />
-    <target
         android:name="path_1"
         android:animation="@anim/error_to_trustedstate_path_1_animation" />
     <target
-        android:name="lock_left_side"
-        android:animation="@anim/error_to_trustedstate_lock_left_side_animation" />
-    <target
         android:name="path_2"
         android:animation="@anim/error_to_trustedstate_path_2_animation" />
     <target
@@ -42,9 +33,21 @@
         android:name="path_3"
         android:animation="@anim/error_to_trustedstate_path_3_animation" />
     <target
-        android:name="exclamation_dot"
-        android:animation="@anim/error_to_trustedstate_exclamation_dot_animation" />
+        android:name="errorexclamationdot"
+        android:animation="@anim/error_to_trustedstate_errorexclamationdot_animation" />
     <target
-        android:name="rectangle_path_1"
-        android:animation="@anim/error_to_trustedstate_rectangle_path_1_animation" />
+        android:name="bottompath"
+        android:animation="@anim/error_to_trustedstate_bottompath_animation" />
+    <target
+        android:name="exclamationtop"
+        android:animation="@anim/error_to_trustedstate_exclamationtop_animation" />
+    <target
+        android:name="toppath"
+        android:animation="@anim/error_to_trustedstate_toppath_animation" />
+    <target
+        android:name="errorcircle"
+        android:animation="@anim/error_to_trustedstate_errorcircle_animation" />
+    <target
+        android:name="circlepath"
+        android:animation="@anim/error_to_trustedstate_circlepath_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_access_alarms_small.xml b/packages/SystemUI/res/drawable/ic_access_alarms_small.xml
index b94cc8e..f6e5ceb 100644
--- a/packages/SystemUI/res/drawable/ic_access_alarms_small.xml
+++ b/packages/SystemUI/res/drawable/ic_access_alarms_small.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -17,10 +17,8 @@
     android:width="16dp"
     android:height="16dp"
     android:viewportWidth="24.0"
-    android:viewportHeight="24.0"
-    android:tint="?android:attr/textColorTertiary">
-
+    android:viewportHeight="24.0">
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M22.0,5.7l-4.6,-3.9l-1.3,1.5l4.6,3.9L22.0,5.7zM7.9,3.4L6.6,1.9L2.0,5.7l1.3,1.5L7.9,3.4zM12.5,8.0L11.0,8.0l0.0,6.0l4.7,2.9l0.8,-1.2l-4.0,-2.4L12.5,8.0zM12.0,4.0c-5.0,0.0 -9.0,4.0 -9.0,9.0c0.0,5.0 4.0,9.0 9.0,9.0s9.0,-4.0 9.0,-9.0C21.0,8.0 17.0,4.0 12.0,4.0zM12.0,20.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.9 3.1,-7.0 7.0,-7.0c3.9,0.0 7.0,3.1 7.0,7.0C19.0,16.9 15.9,20.0 12.0,20.0z"/>
+        android:pathData="M21.35,6.49c-0.35,0.42 -0.98,0.47 -1.4,0.12l-3.07,-2.57a1,1 0,1 1,1.29 -1.53l3.07,2.57c0.42,0.35 0.47,0.98 0.11,1.41zM7.24,2.63a1,1 0,0 0,-1.41 -0.13L2.77,5.07A0.996,0.996 0,1 0,4.05 6.6l3.06,-2.57c0.43,-0.35 0.48,-0.98 0.13,-1.4zM11.75,8c-0.41,0 -0.75,0.34 -0.75,0.75v4.68c0,0.35 0.18,0.68 0.49,0.86l3.65,2.19c0.34,0.2 0.78,0.1 0.98,-0.24a0.71,0.71 0,0 0,-0.25 -0.99l-3.37,-2v-4.5c0,-0.41 -0.34,-0.75 -0.75,-0.75zM12,5.9c-3.91,0 -7.1,3.18 -7.1,7.1s3.19,7.1 7.1,7.1 7.1,-3.18 7.1,-7.1 -3.19,-7.1 -7.1,-7.1M12,4a9,9 0,1 1,-0.001 18.001A9,9 0,0 1,12 4z"
+        android:fillColor="#FFFFFFFF"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_bluetooth_transient.xml b/packages/SystemUI/res/drawable/ic_bluetooth_transient.xml
index 76026af..33d1fb3 100644
--- a/packages/SystemUI/res/drawable/ic_bluetooth_transient.xml
+++ b/packages/SystemUI/res/drawable/ic_bluetooth_transient.xml
@@ -1,4 +1,18 @@
 <?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.
+-->
 <vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:name="ic_bluetooth_transient"
@@ -7,89 +21,54 @@
     android:height="48dp"
     android:viewportHeight="48" >
     <group
-        android:name="ic_signal_wifi_4_bar_48px_outlines_"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
+        android:name="ic_bluetooth_transient_0"
+        android:translateX="23.99883"
+        android:translateY="23.99839" >
         <group
-            android:name="ic_signal_wifi_4_bar_48px_outlines__pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
+            android:name="ic_bluetooth_transient_pivot"
+            android:translateX="-23.99883"
+            android:translateY="-23.99839" >
             <group
-                android:name="bluetooth"
-                android:translateX="22.08789"
-                android:translateY="18.72031" >
+                android:name="ic_bluetooth_white_outlines"
+                android:translateX="22.73986"
+                android:translateY="23.99839" >
                 <group
-                    android:name="bluetooth_pivot"
-                    android:translateX="-22.08789"
-                    android:translateY="-18.72031" >
-                    <group
-                        android:name="cross"
-                        android:rotation="-1.88453" >
-                        <path
-                            android:name="extented_cross"
-                            android:pathData="M 10.6188659668,6.56344604492 c 0.0,0.0 21.7386016846,23.1297454834 21.7386016846,23.1297454834"
-                            android:strokeColor="#FFFFFFFF"
-                            android:strokeWidth="4" />
-                    </group>
-                    <group
-                        android:name="bluetooth_0"
-                        android:translateX="23.38789"
-                        android:translateY="18.72031" >
-                        <path
-                            android:name="b_shape_merged"
-                            android:pathData="M 11.3999938965,-8.60000610352 c 0.0,0.0 -11.3999938965,-11.3999938965 -11.3999938965,-11.3999938965 c 0.0,0.0 -2.0,0.0 -2.0,0.0 c 0.0,0.0 0.0,15.1999969482 0.0,15.1999969482 c 0.0,0.0 -9.19999694824,-9.19999694824 -9.19999694824,-9.19999694824 c 0.0,0.0 -2.80000305176,2.80000305176 -2.80000305176,2.80000305176 c 0.0,0.0 11.1999969482,11.1999969482 11.1999969482,11.1999969482 c 0.0,0.0 -11.1999969482,11.1999969482 -11.1999969482,11.1999969482 c 0.0,0.0 2.80000305176,2.80000305176 2.80000305176,2.80000305176 c 0.0,0.0 9.19999694824,-9.19999694824 9.19999694824,-9.19999694824 c 0.0,0.0 0.0,15.1999969482 0.0,15.1999969482 c 0.0,0.0 2.0,0.0 2.0,0.0 c 0.0,0.0 11.3999938965,-11.3999938965 11.3999938965,-11.3999938965 c 0.0,0.0 -8.59999084473,-8.60000610352 -8.59999084473,-8.60000610352 c 0.0,0.0 8.59999084473,-8.60000610352 8.59999084473,-8.60000610352 Z M 2.0,-12.3000030518 c 0.0,0.0 3.80000305176,3.80000305176 3.80000305176,3.80000305176 c 0.0,0.0 -3.80000305176,3.69999694824 -3.80000305176,3.69999694824 c 0.0,0.0 0.0,-7.5 0.0,-7.5 Z M 5.80000305176,8.60000610352 c 0.0,0.0 -3.80000305176,3.69999694824 -3.80000305176,3.69999694824 c 0.0,0.0 0.0,-7.5 0.0,-7.5 c 0.0,0.0 3.80000305176,3.80000305176 3.80000305176,3.80000305176 Z"
-                            android:fillColor="#FFFFFFFF" />
-                    </group>
+                    android:name="ic_bluetooth_white_outlines_pivot"
+                    android:translateX="-12.84937"
+                    android:translateY="-20.4772" >
+                    <path
+                        android:name="b_shape_merged"
+                        android:pathData="M 17.1289978027,20.4790039062 c 0.0,0.0 7.5,-7.48100280762 7.5,-7.48100280762 c 0.81999206543,-0.819000244141 0.81999206543,-2.13899230957 0.0,-2.95999145508 c 0.0,0.0 -8.93899536133,-8.93899536133 -8.93899536133,-8.93899536133 c 0.0,0.0 -0.0610046386719,-0.0610046386719 -0.0610046386718,-0.0610046386719 c -0.844009399414,-0.788009643555 -2.16799926758,-0.74299621582 -2.95600891113,0.102005004883 c -0.359985351562,0.384994506836 -0.561996459961,0.891998291016 -0.56298828125,1.41899108887 c 0.0,0.0 0.0,12.8800048828 0.0,12.8800048828 c 0.0,0.0 -8.10000610352,-8.10000610352 -8.10000610352,-8.10000610352 c -0.81999206543,-0.81999206543 -2.12100219727,-0.81999206543 -2.9409942627,0.0 c -0.819000244141,0.819000244141 -0.819000244141,2.12001037598 0.0,2.94000244141 c 0.0,0.0 10.1799926758,10.1999969482 10.1799926758,10.1999969482 c 0.0,0.0 -10.1799926758,10.1790008545 -10.1799926758,10.1790008545 c -0.819000244141,0.820999145508 -0.819000244141,2.12100219727 0.0,2.94100952148 c 0.81999206543,0.81999206543 2.12100219727,0.81999206543 2.9409942627,0.0 c 0.0,0.0 8.10000610352,-8.1009979248 8.10000610352,-8.1009979248 c 0.0,0.0 0.0,12.9009857178 0.0,12.9009857178 c 0.0,1.14801025391 0.929992675781,2.08000183105 2.08000183105,2.08000183105 c 0.526992797852,0.0 1.03399658203,-0.199996948242 1.41999816895,-0.559997558594 c 0.0,0.0 0.0989990234375,-0.100006103516 0.0989990234375,-0.100006103516 c 0.0,0.0 8.91999816895,-8.91999816895 8.91999816895,-8.91999816895 c 0.81999206543,-0.820999145508 0.81999206543,-2.13999938965 0.0,-2.95999145508 c 0.0,0.0 -7.5,-7.46000671387 -7.5,-7.46000671387 Z M 16.0899963379,15.8190002441 c 0.0,0.0 0.0,-8.59999084473 0.0,-8.59999084473 c 0.0,0.0 4.30000305176,4.30000305176 4.30000305176,4.30000305176 c 0.0,0.0 -4.30000305176,4.29998779297 -4.30000305176,4.29998779297 Z M 16.0899963379,33.7190093994 c 0.0,0.0 0.0,-8.6009979248 0.0,-8.6009979248 c 0.0,0.0 4.30000305176,4.30099487305 4.30000305176,4.30099487305 c 0.0,0.0 -4.30000305176,4.30000305176 -4.30000305176,4.30000305176 Z"
+                        android:fillColor="#FFFFFFFF" />
                 </group>
             </group>
             <group
-                android:name="dot_left"
-                android:translateX="20.16992"
-                android:translateY="18.64258" >
+                android:name="dot_left_outlines"
+                android:translateX="20.6501"
+                android:translateY="24.00011" >
                 <group
-                    android:name="dot_left_pivot"
-                    android:translateX="-20.16992"
-                    android:translateY="-18.64258" >
-                    <group
-                        android:name="group_1"
-                        android:translateX="9.38789"
-                        android:translateY="18.72031" >
-                        <group
-                            android:name="group_1_pivot"
-                            android:translateX="-9.38789"
-                            android:translateY="-18.72031" >
-                            <path
-                                android:name="dot_left_0"
-                                android:pathData="M 13.3878936768,18.7203063965 c 0.0,0.0 -4.0,-4.0 -4.0,-4.0 c 0.0,0.0 -4.0,4.0 -4.0,4.0 c 0.0,0.0 4.0,4.0 4.0,4.0 c 0.0,0.0 4.0,-4.0 4.0,-4.0 Z"
-                                android:fillColor="#FFFFFFFF" />
-                        </group>
-                    </group>
+                    android:name="dot_left_outlines_pivot"
+                    android:translateX="-14.2"
+                    android:translateY="-3.55" >
+                    <path
+                        android:name="dot_left"
+                        android:pathData="M 5.66999816895,5.66999816895 c -1.18000793457,1.17999267578 -3.08000183105,1.17999267578 -4.24000549316,0.0 c -1.17999267578,-1.16000366211 -1.17999267578,-3.03999328613 -0.0199890136719,-4.2200012207 c 0.0,0.0 0.0199890136719,-0.0200042724609 0.0199890136719,-0.0200042724609 c 1.16000366211,-1.17999267578 3.04000854492,-1.17999267578 4.2200012207,-0.0199890136719 c 0.0,0.0 0.0200042724609,0.0199890136719 0.0200042724609,0.0199890136719 c 1.17999267578,1.17900085449 1.17999267578,3.06001281738 0.0,4.24000549316 Z"
+                        android:fillColor="#FFFFFFFF"
+                        android:fillAlpha="0.5" />
                 </group>
             </group>
             <group
-                android:name="dot_right"
-                android:translateX="26.16094"
-                android:translateY="18.60898" >
+                android:name="dot_right_outlines"
+                android:translateX="27.3501"
+                android:translateY="23.99741" >
                 <group
-                    android:name="dot_right_pivot"
-                    android:translateX="-26.16094"
-                    android:translateY="-18.60898" >
-                    <group
-                        android:name="group_2"
-                        android:translateX="37.38789"
-                        android:translateY="18.72031"
-                        android:scaleX="0"
-                        android:scaleY="0" >
-                        <group
-                            android:name="group_1_pivot_0"
-                            android:translateX="-37.38789"
-                            android:translateY="-18.72031" >
-                            <path
-                                android:name="dot_right_0"
-                                android:pathData="M 37.3878936768,14.7203063965 c 0.0,0.0 -4.0,4.0 -4.0,4.0 c 0.0,0.0 4.0,4.0 4.0,4.0 c 0.0,0.0 4.0,-4.0 4.0,-4.0 c 0.0,0.0 -4.0,-4.0 -4.0,-4.0 Z"
-                                android:fillColor="#FFFFFFFF" />
-                        </group>
-                    </group>
+                    android:name="dot_right_outlines_pivot"
+                    android:translateX="7.1"
+                    android:translateY="-3.5525" >
+                    <path
+                        android:name="dot_right"
+                        android:pathData="M 5.66999816895,1.43499755859 c 1.17999267578,1.18000793457 1.17999267578,3.08000183105 0.0,4.24000549316 c -1.18000793457,1.17999267578 -3.08000183105,1.17999267578 -4.24000549316,0.0 c -1.17999267578,-1.16000366211 -1.17999267578,-3.04000854492 -0.0200042724609,-4.21899414062 c 0.0,0.0 0.0200042724609,-0.0210113525391 0.0200042724609,-0.0210113525391 c 1.15299987793,-1.17098999023 3.03799438477,-1.18499755859 4.20899963379,-0.0309906005859 c 0.0,0.0 0.031005859375,0.0309906005859 0.031005859375,0.0309906005859 Z"
+                        android:fillColor="#FFFFFFFF" />
                 </group>
             </group>
         </group>
diff --git a/packages/SystemUI/res/drawable/ic_bluetooth_transient_animation.xml b/packages/SystemUI/res/drawable/ic_bluetooth_transient_animation.xml
index f7eb23c..dc3c3e2 100644
--- a/packages/SystemUI/res/drawable/ic_bluetooth_transient_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_bluetooth_transient_animation.xml
@@ -1,11 +1,25 @@
 <?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.
+-->
 <animated-vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/ic_bluetooth_transient" >
     <target
-        android:name="group_1"
-        android:animation="@anim/ic_bluetooth_transient_group_1_animation" />
+        android:name="dot_left"
+        android:animation="@anim/ic_bluetooth_transient_dot_left_animation" />
     <target
-        android:name="group_2"
-        android:animation="@anim/ic_bluetooth_transient_group_2_animation" />
+        android:name="dot_right"
+        android:animation="@anim/ic_bluetooth_transient_dot_right_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml b/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
index 604e918..beedcbb 100644
--- a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
+++ b/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -22,6 +22,6 @@
         android:pathData="m18.250000,12.000000a6.250000,6.250000 0.000000,1.000000 1.000000,-12.500000 0.000000,6.250000 6.250000,0.000000 1.000000,1.000000 12.500000,0.000000z"
         android:fillColor="?android:attr/colorPrimary" />
     <path
-        android:fillColor="?android:attr/colorControlNormal"
-        android:pathData="M20.000000,8.700000L20.000000,4.000000L15.300000,4.000000L12.000000,0.700000 8.700000,4.000000L4.000000,4.000000L4.000000,8.700000L0.700000,12.000000 4.000000,15.300000L4.000000,20.000000L8.700000,20.000000L12.000000,23.299999 15.300000,20.000000L20.000000,20.000000L20.000000,15.300000L23.299999,12.000000 20.000000,8.700000zM12.000000,18.000000C8.700000,18.000000 6.000000,15.300000 6.000000,12.000000 6.000000,8.700000 8.700000,6.000000 12.000000,6.000000c3.300000,0.000000 6.000000,2.700000 6.000000,6.000000 0.000000,3.300000 -2.700000,6.000000 -6.000000,6.000000zM12.000000,8.000000c-2.200000,0.000000 -4.000000,1.800000 -4.000000,4.000000 0.000000,2.200000 1.800000,4.000000 4.000000,4.000000 2.200000,0.000000 4.000000,-1.800000 4.000000,-4.000000 0.000000,-2.200000 -1.800000,-4.000000 -4.000000,-4.000000z"/>
+        android:pathData="M20,8.69L20,5c0,-0.55 -0.45,-1 -1,-1h-3.69l-2.6,-2.6a0.996,0.996 0,0 0,-1.41 0L8.69,4L5,4c-0.55,0 -1,0.45 -1,1v3.69l-2.6,2.6a0.996,0.996 0,0 0,0 1.41L4,15.3L4,19c0,0.55 0.45,1 1,1h3.69l2.6,2.6c0.39,0.39 1.02,0.39 1.41,0l2.6,-2.6L19,20c0.55,0 1,-0.45 1,-1v-3.69l2.6,-2.6a0.996,0.996 0,0 0,0 -1.41L20,8.69zM12,18.08c-3.36,0 -6.08,-2.73 -6.08,-6.08S8.64,5.92 12,5.92s6.08,2.73 6.08,6.08 -2.72,6.08 -6.08,6.08zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4z"
+        android:fillColor="?android:attr/colorControlNormal" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_close_white_rounded.xml b/packages/SystemUI/res/drawable/ic_close_white_rounded.xml
new file mode 100644
index 0000000..ca37698
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_close_white_rounded.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M18.3,5.71a0.996,0.996 0,0 0,-1.41 0L12,10.59 7.11,5.7A0.996,0.996 0,1 0,5.7 7.11L10.59,12 5.7,16.89a0.996,0.996 0,1 0,1.41 1.41L12,13.41l4.89,4.89a0.996,0.996 0,1 0,1.41 -1.41L13.41,12l4.89,-4.89c0.38,-0.38 0.38,-1.02 0,-1.4z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_data_saver.xml b/packages/SystemUI/res/drawable/ic_data_saver.xml
index 64bbff0..0f027ee 100644
--- a/packages/SystemUI/res/drawable/ic_data_saver.xml
+++ b/packages/SystemUI/res/drawable/ic_data_saver.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,18 +14,15 @@
     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"
-        android:tint="?android:attr/colorControlNormal">
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0"
+    android:tint="?android:attr/colorControlNormal">
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M12.0,19.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.5 2.6,-6.4 6.0,-6.9L11.0,2.0C5.9,2.5 2.0,6.8 2.0,12.0c0.0,5.5 4.5,10.0 10.0,10.0c3.3,0.0 6.2,-1.6 8.1,-4.1l-2.6,-1.5C16.2,18.0 14.2,19.0 12.0,19.0z"/>
+        android:pathData="M16,12c0,0.55 -0.45,1 -1,1h-2v2c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1v-2L9,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h2L11,9c0,-0.55 0.45,-1 1,-1s1,0.45 1,1v2h2c0.55,0 1,0.45 1,1zM17.69,16.87a7.437,7.437 0,0 1,-5.93 2.63c-3.82,-0.12 -7.03,-3.25 -7.25,-7.07 -0.21,-3.84 2.48,-7.1 6.07,-7.79 0.24,-0.04 0.42,-0.24 0.42,-0.48L11,2.62c0,-0.3 -0.27,-0.55 -0.57,-0.5A10.02,10.02 0,0 0,2.09 13.4c0.59,4.4 4.16,7.94 8.56,8.52a9.99,9.99 0,0 0,9.14 -3.65,0.5 0.5,0 0,0 -0.15,-0.74l-1.32,-0.76a0.469,0.469 0,0 0,-0.63 0.1z"
+        android:fillColor="#FFFFFFFF"/>
     <path
-        android:fillColor="#54FFFFFF"
-        android:pathData="M13.0,2.0l0.0,3.0c3.4,0.5 6.0,3.4 6.0,6.9c0.0,0.9 -0.2,1.8 -0.5,2.5l2.6,1.5c0.6,-1.2 0.9,-2.6 0.9,-4.1C22.0,6.8 18.0,2.6 13.0,2.0z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M16.0,11.0l0.0,2.0 -3.0,0.0 0.0,3.0 -2.0,0.0 0.0,-3.0 -3.0,0.0 0.0,-2.0 3.0,0.0 0.0,-3.0 2.0,0.0 0.0,3.0z"/>
+        android:pathData="M13.41,4.64a0.493,0.493 0,0 1,-0.41 -0.48L13,2.62c0,-0.3 0.27,-0.55 0.57,-0.5C18.35,2.88 22,7.01 22,12c0,1.23 -0.23,2.41 -0.64,3.5 -0.11,0.28 -0.45,0.4 -0.72,0.24l-1.33,-0.77a0.484,0.484 0,0 1,-0.21 -0.59c0.25,-0.75 0.39,-1.55 0.39,-2.38 0.01,-3.65 -2.62,-6.69 -6.08,-7.36z"
+        android:fillColor="#54FFFFFF" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_data_saver_off.xml b/packages/SystemUI/res/drawable/ic_data_saver_off.xml
index 3001ad9..29e6c91 100644
--- a/packages/SystemUI/res/drawable/ic_data_saver_off.xml
+++ b/packages/SystemUI/res/drawable/ic_data_saver_off.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -21,8 +21,5 @@
         android:tint="?android:attr/colorControlNormal">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M12.0,19.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.5 2.6,-6.4 6.0,-6.9L11.0,2.0C5.9,2.5 2.0,6.8 2.0,12.0c0.0,5.5 4.5,10.0 10.0,10.0c3.3,0.0 6.2,-1.6 8.1,-4.1l-2.6,-1.5C16.2,18.0 14.2,19.0 12.0,19.0z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.0,2.0l0.0,3.0c3.4,0.5 6.0,3.4 6.0,6.9c0.0,0.9 -0.2,1.8 -0.5,2.5l2.6,1.5c0.6,-1.2 0.9,-2.6 0.9,-4.1C22.0,6.8 18.0,2.6 13.0,2.0z"/>
+        android:pathData="M18.32,16.75l1.32,0.76c0.26,0.15 0.34,0.51 0.15,0.74 -2.09,2.6 -5.44,4.14 -9.14,3.65 -4.4,-0.58 -7.96,-4.12 -8.56,-8.52C1.34,7.8 5.21,2.95 10.43,2.12c0.3,-0.05 0.57,0.2 0.57,0.5v1.53c0,0.24 -0.18,0.44 -0.41,0.49 -3.6,0.69 -6.29,3.95 -6.07,7.79 0.21,3.82 3.43,6.95 7.25,7.07 2.37,0.08 4.51,-0.96 5.93,-2.63a0.48,0.48 0,0 1,0.62 -0.12zM19.5,12c0,0.83 -0.14,1.63 -0.39,2.38 -0.08,0.23 0.01,0.47 0.21,0.59l1.33,0.77c0.26,0.15 0.61,0.04 0.72,-0.24 0.4,-1.09 0.63,-2.27 0.63,-3.5 0,-4.99 -3.65,-9.12 -8.43,-9.88 -0.3,-0.04 -0.57,0.2 -0.57,0.5v1.53c0,0.24 0.18,0.44 0.41,0.48 3.46,0.68 6.09,3.72 6.09,7.37z" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_dnd.xml b/packages/SystemUI/res/drawable/ic_dnd.xml
index e658e68..9a1d502 100644
--- a/packages/SystemUI/res/drawable/ic_dnd.xml
+++ b/packages/SystemUI/res/drawable/ic_dnd.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,13 +15,13 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
     android:width="24dp"
     android:tint="?android:attr/colorControlNormal">
 
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M24.0,4.0C12.95,4.0 4.0,12.95 4.0,24.0s8.95,20.0 20.0,20.0 20.0,-8.95 20.0,-20.0S35.05,4.0 24.0,4.0zm10.0,22.0L14.0,26.0l0.0,-4.0l20.0,0.0l0.0,4.0z" />
+        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16,13L8,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"/>
 
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_dnd_disable_animation.xml b/packages/SystemUI/res/drawable/ic_dnd_disable_animation.xml
deleted file mode 100644
index d755481..0000000
--- a/packages/SystemUI/res/drawable/ic_dnd_disable_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animated-vector
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_dnd_disable" >
-    <target
-        android:name="mask_1"
-        android:animation="@anim/ic_dnd_disable_mask_1_animation" />
-    <target
-        android:name="bar01_0"
-        android:animation="@anim/ic_dnd_disable_bar01_0_animation" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml b/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml
index 0515b35..e7b9fa7 100644
--- a/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml
+++ b/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -22,9 +22,6 @@
 
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0s10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM12.0,20.5c-4.7,0.0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12.0,3.5s8.5,3.8 8.5,8.5S16.7,20.5 12.0,20.5z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M12.0,6.0c-3.3,0.0 -6.0,2.7 -6.0,6.0c0.0,3.3 2.7,6.0 6.0,6.0s6.0,-2.7 6.0,-6.0C18.0,8.7 15.4,6.0 12.0,6.0zM15.0,13.0L9.0,13.0l0.0,-2.0l6.0,0.0L15.0,13.0z"/>
+        android:pathData="M12,2C6.5,2 2,6.5 2,12s4.5,10 10,10 10,-4.5 10,-10S17.5,2 12,2zM12,20.5c-4.7,0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12,3.5s8.5,3.8 8.5,8.5 -3.8,8.5 -8.5,8.5zM12,6c-3.3,0 -6,2.7 -6,6s2.7,6 6,6 6,-2.7 6,-6 -2.6,-6 -6,-6zM14,13h-4c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h4c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"/>
 
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable_animation.xml b/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable_animation.xml
deleted file mode 100644
index f796d62..0000000
--- a/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animated-vector
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_dnd_total_silence_disable" >
-    <target
-        android:name="mask_1"
-        android:animation="@anim/ic_dnd_total_silence_disable_mask_1_animation" />
-    <target
-        android:name="outer_ring_merged"
-        android:animation="@anim/ic_dnd_total_silence_disable_outer_ring_merged_animation" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_fingerprint.xml b/packages/SystemUI/res/drawable/ic_fingerprint.xml
index ee2cf03..7bbd39d 100644
--- a/packages/SystemUI/res/drawable/ic_fingerprint.xml
+++ b/packages/SystemUI/res/drawable/ic_fingerprint.xml
@@ -1,5 +1,5 @@
 <!--
-  ~ Copyright (C) 2015 The Android Open Source Project
+  ~ Copyright (C) 2017 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -13,24 +13,55 @@
   ~ 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="32.0dp"
-        android:height="32.0dp"
-        android:viewportWidth="32.0"
-        android:viewportHeight="32.0">
-    <path
-        android:fillColor="#80ffffff"
-        android:pathData="M23.7,5.9c-0.1,0.0 -0.2,0.0 -0.3,-0.1C21.0,4.5 18.6,3.9 16.0,3.9c-2.5,0.0 -4.6,0.6 -6.9,1.9C8.8,6.0 8.3,5.9 8.1,5.5C7.9,5.2 8.0,4.7 8.4,4.5c2.5,-1.4 4.9,-2.1 7.7,-2.1c2.8,0.0 5.4,0.7 8.0,2.1c0.4,0.2 0.5,0.6 0.3,1.0C24.2,5.7 24.0,5.9 23.7,5.9z"/>
-    <path
-        android:fillColor="#80ffffff"
-        android:pathData="M5.3,13.2c-0.1,0.0 -0.3,0.0 -0.4,-0.1c-0.3,-0.2 -0.4,-0.7 -0.2,-1.0c1.3,-1.9 2.9,-3.4 4.9,-4.5c4.1,-2.2 9.3,-2.2 13.4,0.0c1.9,1.1 3.6,2.5 4.9,4.4c0.2,0.3 0.1,0.8 -0.2,1.0c-0.3,0.2 -0.8,0.1 -1.0,-0.2c-1.2,-1.7 -2.6,-3.0 -4.3,-4.0c-3.7,-2.0 -8.3,-2.0 -12.0,0.0c-1.7,0.9 -3.2,2.3 -4.3,4.0C5.7,13.1 5.5,13.2 5.3,13.2z"/>
-    <path
-        android:fillColor="#80ffffff"
-        android:pathData="M13.3,29.6c-0.2,0.0 -0.4,-0.1 -0.5,-0.2c-1.1,-1.2 -1.7,-2.0 -2.6,-3.6c-0.9,-1.7 -1.4,-3.7 -1.4,-5.9c0.0,-4.1 3.3,-7.4 7.4,-7.4c4.1,0.0 7.4,3.3 7.4,7.4c0.0,0.4 -0.3,0.7 -0.7,0.7s-0.7,-0.3 -0.7,-0.7c0.0,-3.3 -2.7,-5.9 -5.9,-5.9c-3.3,0.0 -5.9,2.7 -5.9,5.9c0.0,2.0 0.4,3.8 1.2,5.2c0.8,1.6 1.4,2.2 2.4,3.3c0.3,0.3 0.3,0.8 0.0,1.0C13.7,29.5 13.5,29.6 13.3,29.6z"/>
-    <path
-        android:fillColor="#80ffffff"
-        android:pathData="M22.6,27.1c-1.6,0.0 -2.9,-0.4 -4.1,-1.2c-1.9,-1.4 -3.1,-3.6 -3.1,-6.0c0.0,-0.4 0.3,-0.7 0.7,-0.7s0.7,0.3 0.7,0.7c0.0,1.9 0.9,3.7 2.5,4.8c0.9,0.6 1.9,1.0 3.2,1.0c0.3,0.0 0.8,0.0 1.3,-0.1c0.4,-0.1 0.8,0.2 0.8,0.6c0.1,0.4 -0.2,0.8 -0.6,0.8C23.4,27.1 22.8,27.1 22.6,27.1z"/>
-    <path
-        android:fillColor="#80ffffff"
-        android:pathData="M20.0,29.9c-0.1,0.0 -0.1,0.0 -0.2,0.0c-2.1,-0.6 -3.4,-1.4 -4.8,-2.9c-1.8,-1.9 -2.8,-4.4 -2.8,-7.1c0.0,-2.2 1.8,-4.1 4.1,-4.1c2.2,0.0 4.1,1.8 4.1,4.1c0.0,1.4 1.2,2.6 2.6,2.6c1.4,0.0 2.6,-1.2 2.6,-2.6c0.0,-5.1 -4.2,-9.3 -9.3,-9.3c-3.6,0.0 -6.9,2.1 -8.4,5.4C7.3,17.1 7.0,18.4 7.0,19.8c0.0,1.1 0.1,2.7 0.9,4.9c0.1,0.4 -0.1,0.8 -0.4,0.9c-0.4,0.1 -0.8,-0.1 -0.9,-0.4c-0.6,-1.8 -0.9,-3.6 -0.9,-5.4c0.0,-1.6 0.3,-3.1 0.9,-4.4c1.7,-3.8 5.6,-6.3 9.8,-6.3c5.9,0.0 10.7,4.8 10.7,10.7c0.0,2.2 -1.8,4.1 -4.1,4.1s-4.0,-1.8 -4.0,-4.1c0.0,-1.4 -1.2,-2.6 -2.6,-2.6c-1.4,0.0 -2.6,1.2 -2.6,2.6c0.0,2.3 0.9,4.5 2.4,6.1c1.2,1.3 2.4,2.0 4.2,2.5c0.4,0.1 0.6,0.5 0.5,0.9C20.6,29.7 20.3,29.9 20.0,29.9z"/>
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="32dp"
+    android:viewportWidth="24"
+    android:height="32dp"
+    android:viewportHeight="24" >
+    <group
+        android:translateX="12"
+        android:translateY="12.4"
+        android:scaleX="0.738"
+        android:scaleY="0.738" >
+        <group
+            android:translateX="33"
+            android:translateY="34" >
+            <path
+                android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
+                android:strokeColor="?attr/wallpaperTextColor"
+                android:strokeAlpha="0.5"
+                android:strokeWidth="1.45"
+                android:strokeLineCap="round" />
+            <path
+                android:name="ridge_7_path"
+                android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
+                android:strokeColor="?attr/wallpaperTextColor"
+                android:strokeAlpha="0.5"
+                android:strokeWidth="1.45"
+                android:strokeLineCap="round" />
+            <path
+                android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
+                android:strokeColor="?attr/wallpaperTextColor"
+                android:strokeAlpha="0.5"
+                android:strokeWidth="1.45"
+                android:strokeLineCap="round" />
+            <path
+                android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
+                android:strokeColor="?attr/wallpaperTextColor"
+                android:strokeAlpha="0.5"
+                android:strokeWidth="1.45"
+                android:strokeLineCap="round" />
+            <group
+                android:translateX="-97.5"
+                android:translateY="-142.5" >
+                <path
+                    android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
+                    android:strokeColor="?attr/wallpaperTextColor"
+                    android:strokeAlpha="0.5"
+                    android:strokeWidth="1.45"
+                    android:strokeLineCap="round" />
+            </group>
+        </group>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot.xml b/packages/SystemUI/res/drawable/ic_hotspot.xml
new file mode 100644
index 0000000..8450bf6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_hotspot.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <group
+        android:translateY="-0.32">
+        <path
+            android:pathData="M12,11c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,13a6,6 0,0 0,-6.75 -5.95c-2.62,0.32 -4.78,2.41 -5.18,5.02 -0.32,2.14 0.49,4.11 1.92,5.39 0.48,0.43 1.24,0.33 1.56,-0.23 0.24,-0.42 0.14,-0.94 -0.22,-1.26a3.99,3.99 0,0 1,-1.22 -3.94,3.954 3.954,0 0,1 2.9,-2.91A4.007,4.007 0,0 1,16 13c0,1.18 -0.51,2.23 -1.33,2.96 -0.36,0.33 -0.47,0.85 -0.23,1.27 0.31,0.54 1.04,0.69 1.5,0.28A5.97,5.97 0,0 0,18 13zM10.83,3.07c-4.62,0.52 -8.35,4.33 -8.78,8.96a9.966,9.966 0,0 0,4.02 9.01c0.48,0.35 1.16,0.2 1.46,-0.31 0.25,-0.43 0.14,-0.99 -0.26,-1.29 -2.28,-1.69 -3.65,-4.55 -3.16,-7.7 0.54,-3.5 3.46,-6.29 6.98,-6.68C15.91,4.51 20,8.28 20,13c0,2.65 -1.29,4.98 -3.27,6.44 -0.4,0.3 -0.51,0.85 -0.26,1.29 0.3,0.52 0.98,0.66 1.46,0.31A9.96,9.96 0,0 0,22 13c0,-5.91 -5.13,-10.62 -11.17,-9.93z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_disable.xml b/packages/SystemUI/res/drawable/ic_hotspot_disable.xml
deleted file mode 100644
index 2570483..0000000
--- a/packages/SystemUI/res/drawable/ic_hotspot_disable.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:alpha="1.0"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48"
-    android:tint="?android:attr/colorControlNormal" >
-    <group
-        android:name="ic_hotspot"
-        android:translateX="23.9778"
-        android:translateY="24.26443" >
-        <group
-            android:name="ic_hotspot_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 6.97125244141,7.33258056641 6.97125244141,7.33258056641 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -6.77128601074,-6.82850646973 -6.77128601074,-6.82850646973 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.659332275391,0.664688110352 0.659332275391,0.664688110351 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 29.0108337402,34.4080963135 29.0108337402,34.4080963135 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 4.44044494629,2.24310302734 c 0.0,0.0 0.0875396728516,0.112457275391 0.0875396728516,0.112457275391 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="0"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="hotspot"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
-                <group
-                    android:name="circles"
-                    android:translateX="-0.23909"
-                    android:translateY="-0.10807" >
-                    <path
-                        android:name="path_3"
-                        android:pathData="M -0.0042724609375,-2.64895629883 c -2.20922851562,0.0 -4.0,1.791015625 -4.0,4.0 c 0.0,2.20922851562 1.79077148438,4.0 4.0,4.0 c 2.208984375,0.0 4.0,-1.79077148438 4.0,-4.0 c 0.0,-2.208984375 -1.791015625,-4.0 -4.0,-4.0 Z M 11.9957275391,1.35104370117 c 0.0,-6.626953125 -5.373046875,-12.0 -12.0,-12.0 c -6.62719726562,0.0 -12.0,5.373046875 -12.0,12.0 c 0.0,4.43603515625 2.41381835938,8.30004882812 5.99194335938,10.3771972656 c 0.0,0.0 2.01586914062,-3.48217773438 2.01586914062,-3.48217773438 c -2.38500976562,-1.38500976562 -4.0078125,-3.93798828125 -4.0078125,-6.89501953125 c 0.0,-4.41796875 3.58178710938,-8.0 8.0,-8.0 c 4.41796875,0.0 8.0,3.58203125 8.0,8.0 c 0.0,2.95703125 -1.623046875,5.51000976562 -4.00805664062,6.89501953125 c 0.0,0.0 2.01586914062,3.48217773438 2.01586914062,3.48217773438 c 3.578125,-2.0771484375 5.9921875,-5.94116210938 5.9921875,-10.3771972656 Z M -0.0042724609375,-18.6489562988 c -11.0451660156,0.0 -20.0,8.9541015625 -20.0,20.0 c 0.0,7.39306640625 4.02099609375,13.8330078125 9.98779296875,17.2951660156 c 0.0,0.0 2.00219726562,-3.458984375 2.00219726562,-3.458984375 c -4.77319335938,-2.77001953125 -7.98999023438,-7.92211914062 -7.98999023438,-13.8361816406 c 0.0,-8.8369140625 7.16381835938,-16.0 16.0,-16.0 c 8.83595275879,0.0 16.0000152588,7.1630859375 16.0000152588,16.0 c 0.0,5.9140625 -3.21704101562,11.0661621094 -7.990234375,13.8361816406 c 0.0,0.0 2.00219726562,3.458984375 2.00219726563,3.458984375 c 5.966796875,-3.46215820312 9.98803710937,-9.90209960938 9.98803710938,-17.2951660156 c 0.0,-11.0458984375 -8.955078125,-20.0 -20.0000152588,-20.0 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                </group>
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_disable_animation.xml b/packages/SystemUI/res/drawable/ic_hotspot_disable_animation.xml
deleted file mode 100644
index e446a32..0000000
--- a/packages/SystemUI/res/drawable/ic_hotspot_disable_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_hotspot_disable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_hotspot_disable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_hotspot_disable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_enable.xml b/packages/SystemUI/res/drawable/ic_hotspot_enable.xml
deleted file mode 100644
index 7a99630..0000000
--- a/packages/SystemUI/res/drawable/ic_hotspot_enable.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_hotspot"
-        android:translateX="23.97354"
-        android:translateY="24.26306" >
-        <group
-            android:name="ic_hotspot_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 43.1884765625,43.515335083 43.1884765625,43.515335083 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -42.9885101318,-43.0112609863 -42.9885101318,-43.0112609863 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 13.0984039307,13.025604248 13.0984039307,13.025604248 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 16.571762085,22.0471801758 16.571762085,22.0471801758 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 4.44044494629,2.24310302734 c 0.0,0.0 35.4000396729,35.3999633789 35.4000396729,35.3999633789 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="1"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="hotspot"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
-                <group
-                    android:name="circles"
-                    android:translateX="-0.23909"
-                    android:translateY="-0.10807" >
-                    <path
-                        android:name="circle_3"
-                        android:pathData="M 0.0843505859375,-2.93901062012 c -2.30102539062,0.0 -4.16702270508,1.86602783203 -4.16702270508,4.16702270508 c 0.0,2.29898071289 1.86599731445,4.16598510742 4.16702270508,4.16598510742 c 2.29998779297,0.0 4.16598510742,-1.86700439453 4.16598510742,-4.16598510742 c 0.0,-2.30099487305 -1.86599731445,-4.16702270508 -4.16598510742,-4.16702270508 Z M 11.1185302734,5.83390808105 c 0.0,0.0 0.0009765625,0.00100708007812 0.0009765625,0.00100708007812 c 0.14501953125,-0.356994628906 0.27099609375,-0.725006103516 0.382995605469,-1.09799194336 c 0.0570068359375,-0.195007324219 0.101013183594,-0.394989013672 0.149017333984,-0.595001220703 c 0.0690002441406,-0.281005859375 0.126983642578,-0.563995361328 0.175994873047,-0.851989746094 c 0.0270080566406,-0.169006347656 0.0559997558594,-0.337005615234 0.0759887695313,-0.509002685547 c 0.0580139160156,-0.468017578125 0.0970153808594,-0.942993164062 0.0970153808593,-1.4280090332 c 0.0,0.0 0.0,-0.00100708007812 0.0,-0.00100708007812 c 0.0,-5.03900146484 -3.11099243164,-9.3450012207 -7.5119934082,-11.1229858398 c -0.00601196289062,-0.00299072265625 -0.0130004882812,-0.0050048828125 -0.0190124511719,-0.00701904296875 c -0.686004638672,-0.275970458984 -1.39999389648,-0.492980957031 -2.14099121094,-0.638977050781 c -0.072998046875,-0.0150146484375 -0.149017333984,-0.02099609375 -0.222991943359,-0.0339965820313 c -0.302001953125,-0.0540161132812 -0.605010986328,-0.106018066406 -0.916015625,-0.136016845703 c -0.389984130859,-0.0390014648438 -0.786987304688,-0.0599975585938 -1.18899536133,-0.0599975585937 c -0.402008056641,0.0 -0.799011230469,0.02099609375 -1.19000244141,0.0599975585937 c -0.304992675781,0.0299987792969 -0.602996826172,0.0809936523438 -0.901000976563,0.132995605469 c -0.0790100097656,0.0150146484375 -0.160003662109,0.02099609375 -0.238006591797,0.0370178222656 c -0.368988037109,0.0719909667969 -0.730987548828,0.164001464844 -1.08700561523,0.269989013672 c -0.00299072265625,0.00100708007812 -0.0059814453125,0.00201416015625 -0.00900268554687,0.0020141601562 c -0.351989746094,0.10498046875 -0.694000244141,0.226989746094 -1.0309753418,0.361999511719 c -0.0110168457031,0.00399780273438 -0.0220031738281,0.00698852539062 -0.0320129394531,0.0119934082031 c -4.40200805664,1.77798461914 -7.51098632812,6.083984375 -7.5119934082,11.1229858398 c 0.0,0.00799560546875 0.00198364257812,0.0160217285156 0.0019836425781,0.0240173339844 c 0.00100708007812,0.475006103516 0.0380249023438,0.940002441406 0.0950012207032,1.39898681641 c 0.02001953125,0.175994873047 0.0490112304688,0.348999023438 0.0780029296875,0.523010253906 c 0.0469970703125,0.281982421875 0.105010986328,0.557983398438 0.171997070312,0.833984375 c 0.0480041503906,0.204010009766 0.093017578125,0.410003662109 0.152008056641,0.610015869141 c 0.110992431641,0.372009277344 0.238006591797,0.736999511719 0.382019042969,1.09298706055 c 0.0,0.0 0.0009765625,0.0 0.0009765625,0.0 c 1.00701904297,2.48400878906 2.81301879883,4.56100463867 5.11001586914,5.89501953125 c 0.0,0.0 2.01599121094,-3.48300170898 2.01599121094,-3.48300170898 c -2.03900146484,-1.18402099609 -3.5119934082,-3.22500610352 -3.89898681641,-5.63900756836 c 0.0,0.0 0.0009765625,-0.00100708007812 0.0009765625,-0.00100708007812 c -0.0220031738281,-0.130981445312 -0.0369873046875,-0.265991210938 -0.052978515625,-0.399993896484 c -0.0290222167969,-0.274993896484 -0.0570068359375,-0.552001953125 -0.0570068359375,-0.834991455078 c 0.0,0.0 0.0,-0.0190124511719 0.0,-0.0190124511719 c 0.0,-3.98999023438 2.92498779297,-7.28900146484 6.74398803711,-7.89199829102 c 0.0,0.0 0.0180053710938,0.0169982910156 0.0180053710938,0.0169982910156 c 0.404998779297,-0.0639953613281 0.81298828125,-0.125 1.23599243164,-0.125 c 0.0,0.0 0.00201416015625,0.0 0.00201416015624,0.0 c 0.0,0.0 0.00299072265625,0.0 0.00299072265626,0.0 c 0.423004150391,0.0 0.830017089844,0.0610046386719 1.23501586914,0.125 c 0.0,0.0 0.0169982910156,-0.0180053710938 0.0169982910156,-0.0180053710938 c 3.81997680664,0.60400390625 6.74499511719,3.90301513672 6.74499511719,7.89199829102 c 0.0,0.292999267578 -0.0280151367188,0.578002929688 -0.0589904785156,0.861999511719 c -0.0150146484375,0.132019042969 -0.0290222167969,0.264007568359 -0.051025390625,0.393005371094 c -0.385986328125,2.41500854492 -1.85897827148,4.45599365234 -3.89797973633,5.64001464844 c 0.0,0.0 2.01599121094,3.48300170898 2.01599121094,3.48300170898 c 2.29699707031,-1.33401489258 4.10299682617,-3.41101074219 5.11001586914,-5.89602661133 Z M 19.9300231934,2.95698547363 c 0.0059814453125,-0.0659790039062 0.0159912109375,-0.130981445312 0.02099609375,-0.196990966797 c 0.031982421875,-0.462005615234 0.0479736328125,-0.928009033203 0.0489807128906,-1.39700317383 c 0,0.0 0,-0.00997924804688 0,-0.00997924804687 c 0,0.0 0,-0.00100708007812 0,-0.00100708007813 c 0,-7.22500610352 -3.84399414062,-13.5360107422 -9.58599853516,-17.0500183105 c -1.06500244141,-0.652984619141 -2.19299316406,-1.20599365234 -3.37799072266,-1.65197753906 c -0.157989501953,-0.0599975585938 -0.317016601562,-0.118011474609 -0.476989746094,-0.174011230469 c -0.317016601562,-0.110992431641 -0.634002685547,-0.218994140625 -0.9580078125,-0.31298828125 c -0.470001220703,-0.139007568359 -0.944000244141,-0.264007568359 -1.4280090332,-0.368011474609 c -0.186004638672,-0.0390014648438 -0.376983642578,-0.0669860839844 -0.565002441406,-0.101013183594 c -0.414001464844,-0.0759887695312 -0.832000732422,-0.140991210938 -1.25500488281,-0.190979003906 c -0.184997558594,-0.0220031738281 -0.369995117188,-0.0429992675781 -0.556976318359,-0.0599975585937 c -0.592010498047,-0.0530090332031 -1.18801879883,-0.0899963378906 -1.79602050781,-0.0899963378907 c -0.605987548828,0.0 -1.20300292969,0.0369873046875 -1.79598999023,0.0899963378907 c -0.186004638672,0.0169982910156 -0.371002197266,0.0379943847656 -0.555999755859,0.0599975585937 c -0.423004150391,0.0499877929688 -0.842010498047,0.114990234375 -1.25601196289,0.190979003906 c -0.18798828125,0.0350036621094 -0.377990722656,0.06201171875 -0.563995361328,0.101013183594 c -0.483001708984,0.10400390625 -0.959991455078,0.22900390625 -1.42999267578,0.368011474609 c -0.321990966797,0.093994140625 -0.638000488281,0.201995849609 -0.953002929688,0.311981201172 c -0.162994384766,0.0570068359375 -0.324005126953,0.115997314453 -0.484985351562,0.177001953125 c -1.18099975586,0.445007324219 -2.30599975586,0.997009277344 -3.36801147461,1.64700317383 c -0.00201416015625,0.00100708007812 -0.00399780273438,0.00201416015625 -0.0060119628907,0.0029907226562 c -5.74099731445,3.51400756836 -9.58499145508,9.82501220703 -9.58599853516,17.0500183105 c 0,0.0 0,0.00100708007812 0,0.00100708007813 c 0,0.0059814453125 0.00100708007812,0.0130004882812 0.0010070800781,0.0199890136719 c 0.0,0.466003417969 0.0169982910156,0.928009033203 0.0490112304688,1.38598632812 c 0.0050048828125,0.0690002441406 0.0159912109375,0.136016845703 0.02099609375,0.206024169922 c 0.031982421875,0.401000976562 0.0719909667969,0.799987792969 0.127990722656,1.19400024414 c 0.00201416015625,0.0189819335938 0.00701904296875,0.0369873046875 0.010009765625,0.0569763183594 c 0.888000488281,6.17202758789 4.59799194336,11.4250183105 9.7799987793,14.4309997559 c 0.0,0.0 2.00198364258,-3.458984375 2.00198364258,-3.458984375 c -2.58599853516,-1.5 -4.708984375,-3.70401000977 -6.11697387695,-6.34399414063 c 0.0,0.0 0.0169982910156,-0.0180053710938 0.0169982910156,-0.0180053710938 c -0.890014648438,-1.67098999023 -1.50601196289,-3.5110168457 -1.76000976562,-5.46499633789 c -0.00698852539062,-0.0500183105469 -0.010009765625,-0.102020263672 -0.0159912109375,-0.152008056641 c -0.0330200195312,-0.273010253906 -0.0610046386719,-0.545989990234 -0.0800170898437,-0.821990966797 c -0.0220031738281,-0.343017578125 -0.0350036621094,-0.68701171875 -0.0350036621094,-1.03500366211 c 0,-6.53701782227 3.92599487305,-12.1480102539 9.54299926758,-14.6310119629 c 0.157012939453,-0.0700073242188 0.313995361328,-0.135986328125 0.472015380859,-0.199981689453 c 0.373992919922,-0.151000976562 0.751983642578,-0.294006347656 1.13900756836,-0.417022705078 c 0.108978271484,-0.0350036621094 0.221984863281,-0.0619812011719 0.332000732422,-0.0950012207031 c 0.349975585938,-0.102996826172 0.705993652344,-0.194976806641 1.06597900391,-0.273986816406 c 0.114013671875,-0.0249938964844 0.227996826172,-0.052001953125 0.342010498047,-0.0750122070313 c 0.440002441406,-0.0869750976562 0.885986328125,-0.154998779297 1.33700561523,-0.203979492188 c 0.10400390625,-0.0120239257812 0.209991455078,-0.02001953125 0.315002441406,-0.0299987792969 c 0.47998046875,-0.0429992675781 0.963989257812,-0.072998046875 1.45397949219,-0.072998046875 c 0.492004394531,0.0 0.975006103516,0.0299987792969 1.45401000977,0.072998046875 c 0.105987548828,0.00997924804688 0.212005615234,0.0179748535156 0.316986083984,0.0299987792969 c 0.450012207031,0.0489807128906 0.89501953125,0.117004394531 1.33502197266,0.203002929688 c 0.115997314453,0.0239868164062 0.22998046875,0.0509948730469 0.345001220703,0.0769958496094 c 0.358001708984,0.0780029296875 0.710998535156,0.169982910156 1.06097412109,0.272003173828 c 0.111022949219,0.0329895019531 0.226013183594,0.0609741210938 0.336029052734,0.0969848632813 c 0.385986328125,0.123016357422 0.761993408203,0.265014648438 1.13497924805,0.415008544922 c 0.160003662109,0.0650024414062 0.319000244141,0.131988525391 0.477020263672,0.201995849609 c 5.61599731445,2.48400878906 9.53997802734,8.09399414062 9.53997802734,14.6310119629 c 0,0.346984863281 -0.0130004882812,0.690979003906 -0.0350036621094,1.03399658203 c -0.0179748535156,0.274993896484 -0.0469970703125,0.548004150391 -0.0789794921875,0.819000244141 c -0.00601196289062,0.052001953125 -0.010009765625,0.10498046875 -0.0160217285156,0.154998779297 c -0.252990722656,1.95498657227 -0.871002197266,3.79400634766 -1.75997924805,5.46499633789 c 0.0,0.0 0.0169982910156,0.0180053710938 0.0169982910156,0.0180053710938 c -1.40802001953,2.63998413086 -3.53100585938,4.84399414062 -6.11700439453,6.34399414063 c 0.0,0.0 2.00198364258,3.458984375 2.00198364258,3.458984375 c 5.18402099609,-3.00698852539 8.89501953125,-8.26300048828 9.78100585938,-14.4379882813 c 0.00201416015625,-0.0169982910156 0.00601196289062,-0.0320129394531 0.0079956054688,-0.0490112304688 c 0.0570068359375,-0.39697265625 0.0970153808594,-0.798980712891 0.129028320312,-1.20300292969 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                </group>
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_enable_animation.xml b/packages/SystemUI/res/drawable/ic_hotspot_enable_animation.xml
deleted file mode 100644
index 945e42f..0000000
--- a/packages/SystemUI/res/drawable/ic_hotspot_enable_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_hotspot_enable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_hotspot_enable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_hotspot_enable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_transient.xml b/packages/SystemUI/res/drawable/ic_hotspot_transient.xml
index 8c1f7ea..22f7267 100644
--- a/packages/SystemUI/res/drawable/ic_hotspot_transient.xml
+++ b/packages/SystemUI/res/drawable/ic_hotspot_transient.xml
@@ -1,4 +1,19 @@
 <?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.
+-->
 <vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:name="ic_hotspot_transient"
@@ -7,42 +22,53 @@
     android:height="48dp"
     android:viewportHeight="48" >
     <group
-        android:name="ic_hotspot"
-        android:translateX="23.97354"
-        android:translateY="24.26306" >
+        android:name="ic_hotspot_transient_0"
+        android:translateX="24.00209"
+        android:translateY="24.2354" >
         <group
-            android:name="ic_hotspot_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
+            android:name="ic_hotspot_transient_pivot"
+            android:translateX="-24.00209"
+            android:translateY="-24.2354" >
             <group
-                android:name="hotspot"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
+                android:name="circle01"
+                android:translateX="24.0002"
+                android:translateY="25.9996" >
                 <group
-                    android:name="circles"
-                    android:translateX="-0.23909"
-                    android:translateY="-0.10807" >
-                    <group
-                        android:name="group_3" >
-                        <path
-                            android:name="circle_3"
-                            android:pathData="M -0.154739379883,-3.04708862305 c -2.30102539062,0.0 -4.16702270508,1.86602783203 -4.16702270508,4.16702270508 c 0.0,2.29898071289 1.86599731445,4.16598510742 4.16702270508,4.16598510742 c 2.29998779297,0.0 4.16598510742,-1.86700439453 4.16598510742,-4.16598510742 c 0.0,-2.30099487305 -1.86599731445,-4.16702270508 -4.16598510742,-4.16702270508 Z"
-                            android:fillColor="#FFFFFFFF" />
-                    </group>
-                    <group
-                        android:name="group_1" >
-                        <path
-                            android:name="circle_2"
-                            android:pathData="M 10.8794403076,5.72583007812 c 0.0,0.0 0.0009765625,0.00100708007812 0.0009765625,0.00100708007812 c 0.14501953125,-0.356994628906 0.27099609375,-0.725006103516 0.382995605469,-1.09799194336 c 0.0570068359375,-0.195007324219 0.101013183594,-0.394989013672 0.149017333984,-0.595001220703 c 0.0690002441406,-0.281005859375 0.126983642578,-0.563995361328 0.175994873047,-0.851989746094 c 0.0270080566406,-0.169006347656 0.0559997558594,-0.337005615234 0.0759887695312,-0.509002685547 c 0.0580139160156,-0.468017578125 0.0970153808594,-0.942993164062 0.0970153808594,-1.4280090332 c 0.0,0.0 0.0,-0.00100708007812 0.0,-0.00100708007813 c 0.0,-5.03900146484 -3.11099243164,-9.3450012207 -7.5119934082,-11.1229858398 c -0.00601196289062,-0.00299072265625 -0.0130004882812,-0.0050048828125 -0.0190124511719,-0.00701904296875 c -0.686004638672,-0.275970458984 -1.39999389648,-0.492980957031 -2.14099121094,-0.638977050781 c -0.072998046875,-0.0150146484375 -0.149017333984,-0.02099609375 -0.222991943359,-0.0339965820312 c -0.302001953125,-0.0540161132812 -0.605010986328,-0.106018066406 -0.916015625,-0.136016845703 c -0.389984130859,-0.0390014648438 -0.786987304688,-0.0599975585938 -1.18899536133,-0.0599975585937 c -0.402008056641,0.0 -0.799011230469,0.02099609375 -1.19000244141,0.0599975585937 c -0.304992675781,0.0299987792969 -0.602996826172,0.0809936523438 -0.901000976563,0.132995605469 c -0.0790100097656,0.0150146484375 -0.160003662109,0.02099609375 -0.238006591797,0.0370178222656 c -0.368988037109,0.0719909667969 -0.730987548828,0.164001464844 -1.08700561523,0.269989013672 c -0.00299072265625,0.00100708007812 -0.0059814453125,0.00201416015625 -0.00900268554687,0.0020141601562 c -0.351989746094,0.10498046875 -0.694000244141,0.226989746094 -1.0309753418,0.361999511719 c -0.0110168457031,0.00399780273438 -0.0220031738281,0.00698852539062 -0.0320129394531,0.0119934082031 c -4.40200805664,1.77798461914 -7.51098632812,6.083984375 -7.5119934082,11.1229858398 c 0.0,0.00799560546875 0.00198364257812,0.0160217285156 0.0019836425781,0.0240173339844 c 0.00100708007812,0.475006103516 0.0380249023438,0.940002441406 0.0950012207032,1.39898681641 c 0.02001953125,0.175994873047 0.0490112304688,0.348999023438 0.0780029296875,0.523010253906 c 0.0469970703125,0.281982421875 0.105010986328,0.557983398438 0.171997070312,0.833984375 c 0.0480041503906,0.204010009766 0.093017578125,0.410003662109 0.152008056641,0.610015869141 c 0.110992431641,0.372009277344 0.238006591797,0.736999511719 0.382019042969,1.09298706055 c 0.0,0.0 0.0009765625,0.0 0.0009765625,0.0 c 1.00701904297,2.48400878906 2.81301879883,4.56100463867 5.11001586914,5.89501953125 c 0.0,0.0 2.01599121094,-3.48300170898 2.01599121094,-3.48300170898 c -2.03900146484,-1.18402099609 -3.5119934082,-3.22500610352 -3.89898681641,-5.63900756836 c 0.0,0.0 0.0009765625,-0.00100708007812 0.0009765625,-0.00100708007813 c -0.0220031738281,-0.130981445312 -0.0369873046875,-0.265991210938 -0.052978515625,-0.399993896484 c -0.0290222167969,-0.274993896484 -0.0570068359375,-0.552001953125 -0.0570068359375,-0.834991455078 c 0.0,0.0 0.0,-0.0190124511719 0.0,-0.0190124511719 c 0.0,-3.98999023438 2.92498779297,-7.28900146484 6.74398803711,-7.89199829102 c 0.0,0.0 0.0180053710938,0.0169982910156 0.0180053710938,0.0169982910156 c 0.404998779297,-0.0639953613281 0.81298828125,-0.125 1.23599243164,-0.125 c 0.0,0.0 0.00201416015625,0.0 0.00201416015625,0.0 c 0.0,0.0 0.00299072265625,0.0 0.00299072265625,0.0 c 0.423004150391,0.0 0.830017089844,0.0610046386719 1.23501586914,0.125 c 0.0,0.0 0.0169982910156,-0.0180053710938 0.0169982910156,-0.0180053710938 c 3.81997680664,0.60400390625 6.74499511719,3.90301513672 6.74499511719,7.89199829102 c 0.0,0.292999267578 -0.0280151367188,0.578002929688 -0.0589904785156,0.861999511719 c -0.0150146484375,0.132019042969 -0.0290222167969,0.264007568359 -0.051025390625,0.393005371094 c -0.385986328125,2.41500854492 -1.85897827148,4.45599365234 -3.89797973633,5.64001464844 c 0.0,0.0 2.01599121094,3.48300170898 2.01599121094,3.48300170898 c 2.29699707031,-1.33401489258 4.10299682617,-3.41101074219 5.11001586914,-5.89602661133 Z"
-                            android:fillColor="#FFFFFFFF" />
-                    </group>
-                    <group
-                        android:name="group_2" >
-                        <path
-                            android:name="circle_1"
-                            android:pathData="M 19.6909332275,2.8489074707 c 0.0059814453125,-0.0659790039062 0.0159912109375,-0.130981445312 0.02099609375,-0.196990966797 c 0.031982421875,-0.462005615234 0.0479736328125,-0.928009033203 0.0489807128906,-1.39700317383 c 0.0,0.0 0.0,-0.00997924804688 0.0,-0.00997924804687 c 0.0,0.0 0.0,-0.00100708007812 0.0,-0.00100708007813 c 0.0,-7.22500610352 -3.84399414062,-13.5360107422 -9.58599853516,-17.0500183105 c -1.06500244141,-0.652984619141 -2.19299316406,-1.20599365234 -3.37799072266,-1.65197753906 c -0.157989501953,-0.0599975585938 -0.317016601562,-0.118011474609 -0.476989746094,-0.174011230469 c -0.317016601562,-0.110992431641 -0.634002685547,-0.218994140625 -0.9580078125,-0.31298828125 c -0.470001220703,-0.139007568359 -0.944000244141,-0.264007568359 -1.4280090332,-0.368011474609 c -0.186004638672,-0.0390014648438 -0.376983642578,-0.0669860839844 -0.565002441406,-0.101013183594 c -0.414001464844,-0.0759887695312 -0.832000732422,-0.140991210938 -1.25500488281,-0.190979003906 c -0.184997558594,-0.0220031738281 -0.369995117188,-0.0429992675781 -0.556976318359,-0.0599975585937 c -0.592010498047,-0.0530090332031 -1.18801879883,-0.0899963378906 -1.79602050781,-0.0899963378907 c -0.605987548828,0.0 -1.20300292969,0.0369873046875 -1.79598999023,0.0899963378907 c -0.186004638672,0.0169982910156 -0.371002197266,0.0379943847656 -0.555999755859,0.0599975585937 c -0.423004150391,0.0499877929688 -0.842010498047,0.114990234375 -1.25601196289,0.190979003906 c -0.18798828125,0.0350036621094 -0.377990722656,0.06201171875 -0.563995361328,0.101013183594 c -0.483001708984,0.10400390625 -0.959991455078,0.22900390625 -1.42999267578,0.368011474609 c -0.321990966797,0.093994140625 -0.638000488281,0.201995849609 -0.953002929688,0.311981201172 c -0.162994384766,0.0570068359375 -0.324005126953,0.115997314453 -0.484985351562,0.177001953125 c -1.18099975586,0.445007324219 -2.30599975586,0.997009277344 -3.36801147461,1.64700317383 c -0.00201416015625,0.00100708007812 -0.00399780273438,0.00201416015625 -0.0060119628907,0.0029907226562 c -5.74099731445,3.51400756836 -9.58499145508,9.82501220703 -9.58599853516,17.0500183105 c 0.0,0.0 0.0,0.00100708007812 0.0,0.00100708007813 c 0.0,0.0059814453125 0.00100708007812,0.0130004882812 0.0010070800781,0.0199890136719 c 0.0,0.466003417969 0.0169982910156,0.928009033203 0.0490112304688,1.38598632813 c 0.0050048828125,0.0690002441406 0.0159912109375,0.136016845703 0.02099609375,0.206024169922 c 0.031982421875,0.401000976562 0.0719909667969,0.799987792969 0.127990722656,1.19400024414 c 0.00201416015625,0.0189819335938 0.00701904296875,0.0369873046875 0.010009765625,0.0569763183594 c 0.888000488281,6.17202758789 4.59799194336,11.4250183105 9.7799987793,14.4309997559 c 0.0,0.0 2.00198364258,-3.458984375 2.00198364258,-3.458984375 c -2.58599853516,-1.5 -4.708984375,-3.70401000977 -6.11697387695,-6.34399414063 c 0.0,0.0 0.0169982910156,-0.0180053710938 0.0169982910156,-0.0180053710938 c -0.890014648438,-1.67098999023 -1.50601196289,-3.5110168457 -1.76000976563,-5.46499633789 c -0.00698852539062,-0.0500183105469 -0.010009765625,-0.102020263672 -0.0159912109375,-0.152008056641 c -0.0330200195312,-0.273010253906 -0.0610046386719,-0.545989990234 -0.0800170898437,-0.821990966797 c -0.0220031738281,-0.343017578125 -0.0350036621094,-0.68701171875 -0.0350036621094,-1.03500366211 c 0.0,-6.53701782227 3.92599487305,-12.1480102539 9.54299926758,-14.6310119629 c 0.157012939453,-0.0700073242188 0.313995361328,-0.135986328125 0.472015380859,-0.199981689453 c 0.373992919922,-0.151000976562 0.751983642578,-0.294006347656 1.13900756836,-0.417022705078 c 0.108978271484,-0.0350036621094 0.221984863281,-0.0619812011719 0.332000732422,-0.0950012207031 c 0.349975585938,-0.102996826172 0.705993652344,-0.194976806641 1.06597900391,-0.273986816406 c 0.114013671875,-0.0249938964844 0.227996826172,-0.052001953125 0.342010498047,-0.0750122070313 c 0.440002441406,-0.0869750976562 0.885986328125,-0.154998779297 1.33700561523,-0.203979492188 c 0.10400390625,-0.0120239257812 0.209991455078,-0.02001953125 0.315002441406,-0.0299987792969 c 0.47998046875,-0.0429992675781 0.963989257812,-0.072998046875 1.45397949219,-0.072998046875 c 0.492004394531,0.0 0.975006103516,0.0299987792969 1.45401000977,0.072998046875 c 0.105987548828,0.00997924804688 0.212005615234,0.0179748535156 0.316986083984,0.0299987792969 c 0.450012207031,0.0489807128906 0.89501953125,0.117004394531 1.33502197266,0.203002929688 c 0.115997314453,0.0239868164062 0.22998046875,0.0509948730469 0.345001220703,0.0769958496094 c 0.358001708984,0.0780029296875 0.710998535156,0.169982910156 1.06097412109,0.272003173828 c 0.111022949219,0.0329895019531 0.226013183594,0.0609741210938 0.336029052734,0.0969848632813 c 0.385986328125,0.123016357422 0.761993408203,0.265014648438 1.13497924805,0.415008544922 c 0.160003662109,0.0650024414062 0.319000244141,0.131988525391 0.477020263672,0.201995849609 c 5.61599731445,2.48400878906 9.53997802734,8.09399414062 9.53997802734,14.6310119629 c 0.0,0.346984863281 -0.0130004882812,0.690979003906 -0.0350036621094,1.03399658203 c -0.0179748535156,0.274993896484 -0.0469970703125,0.548004150391 -0.0789794921875,0.819000244141 c -0.00601196289062,0.052001953125 -0.010009765625,0.10498046875 -0.0160217285156,0.154998779297 c -0.252990722656,1.95498657227 -0.871002197266,3.79400634766 -1.75997924805,5.46499633789 c 0.0,0.0 0.0169982910156,0.0180053710938 0.0169982910156,0.0180053710938 c -1.40802001953,2.63998413086 -3.53100585938,4.84399414062 -6.11700439453,6.34399414063 c 0.0,0.0 2.00198364258,3.458984375 2.00198364258,3.458984375 c 5.18402099609,-3.00698852539 8.89501953125,-8.26300048828 9.78100585937,-14.4379882813 c 0.00201416015625,-0.0169982910156 0.00601196289062,-0.0320129394531 0.0079956054688,-0.0490112304688 c 0.0570068359375,-0.39697265625 0.0970153808594,-0.798980712891 0.129028320312,-1.20300292969 Z"
-                            android:fillColor="#FFFFFFFF" />
-                    </group>
+                    android:name="circle01_pivot"
+                    android:translateX="-24.0002"
+                    android:translateY="-25.9996" >
+                    <path
+                        android:name="circle01_0"
+                        android:pathData="M 24.0001983643,21.9996032715 c -2.19999694824,0.0 -4.0,1.80000305176 -4.0,4.0 c 0.0,2.20100402832 1.80000305176,4.0 4.0,4.0 c 2.19999694824,0.0 4.0,-1.79899597168 4.0,-4.0 c 0.0,-2.19999694824 -1.80000305176,-4.0 -4.0,-4.0 Z"
+                        android:fillColor="#FFFFFFFF" />
+                </group>
+            </group>
+            <group
+                android:name="circle02"
+                android:translateX="24.00071"
+                android:translateY="24.74686" >
+                <group
+                    android:name="circle02_pivot"
+                    android:translateX="-24.00071"
+                    android:translateY="-24.74686" >
+                    <path
+                        android:name="circle02_0"
+                        android:pathData="M 36.0001983643,25.9996032715 c -0.00299072265625,-6.62699890137 -5.37899780273,-11.9969940186 -12.0059967041,-11.9940032959 c -0.5,0.0 -0.999008178711,0.031005859375 -1.4940032959,0.0940093994141 c -5.24000549316,0.640991210938 -9.55999755859,4.81999206543 -10.3600006104,10.0399932861 c -0.639999389648,4.2799987793 0.979995727539,8.22099304199 3.83999633789,10.7799987793 c 0.960006713867,0.86100769043 2.48001098633,0.660003662109 3.1190032959,-0.460006713867 c 0.481002807617,-0.839996337891 0.281005859375,-1.87998962402 -0.438995361328,-2.51899719238 c -2.21299743652,-1.97099304199 -3.15200805664,-5.00500488281 -2.44000244141,-7.8809967041 c 0.695007324219,-2.86999511719 2.93099975586,-5.11500549316 5.79899597168,-5.81900024414 c 4.29100036621,-1.08599853516 8.65000915527,1.51100158691 9.73600769043,5.80200195312 c 0.162002563477,0.639999389648 0.244003295898,1.29699707031 0.244995117188,1.95700073242 c 0.0,2.36099243164 -1.02000427246,4.45999145508 -2.66000366211,5.91999816895 c -0.720001220703,0.660003662109 -0.939987182617,1.69999694824 -0.459991455078,2.53999328613 c 0.619995117188,1.08000183105 2.08000183105,1.38000488281 3.0,0.560012817383 c 2.61599731445,-2.26699829102 4.1190032959,-5.55801391602 4.11999511719,-9.02000427246 Z"
+                        android:fillColor="#FFFFFFFF" />
+                </group>
+            </group>
+            <group
+                android:name="circle03"
+                android:translateX="24.00209"
+                android:translateY="24.23539" >
+                <group
+                    android:name="circle03_pivot"
+                    android:translateX="-24.00209"
+                    android:translateY="-24.23539" >
+                    <path
+                        android:name="circle03_0"
+                        android:pathData="M 21.6602020264,6.13960266113 c -9.24000549316,1.03999328613 -16.6999969482,8.66000366211 -17.5599975586,17.9199981689 c -0.690002441406,7.00500488281 2.36599731445,13.8540039062 8.03999328613,18.0200042725 c 0.958999633789,0.700988769531 2.32000732422,0.401000976562 2.91900634766,-0.620010375977 c 0.5,-0.860000610352 0.280990600586,-1.97898864746 -0.518997192383,-2.57998657227 c -4.56001281738,-3.38000488281 -7.30000305176,-9.09901428223 -6.32000732422,-15.3990020752 c 1.08000183105,-7.0 6.91900634766,-12.5800018311 13.9600067139,-13.3610076904 c 9.63999938965,-1.09999084473 17.8199920654,6.44000244141 17.8199920654,15.8800048828 c 0.0,5.30000305176 -2.57998657227,9.95999145508 -6.53999328613,12.8800048828 c -0.800003051758,0.600997924805 -1.02000427246,1.69999694824 -0.520004272461,2.57998657227 c 0.600006103516,1.04000854492 1.96000671387,1.32099914551 2.91999816895,0.620010375977 c 5.12100219727,-3.75500488281 8.14500427246,-9.72799682617 8.13999938965,-16.0800018311 c 0.0,-11.8200073242 -10.2599945068,-21.2400054932 -22.3399963379,-19.8600006104 Z"
+                        android:fillColor="#FFFFFFFF" />
                 </group>
             </group>
         </group>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_transient_animation.xml b/packages/SystemUI/res/drawable/ic_hotspot_transient_animation.xml
index b2945f1..929a941 100644
--- a/packages/SystemUI/res/drawable/ic_hotspot_transient_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_hotspot_transient_animation.xml
@@ -1,14 +1,29 @@
 <?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.
+-->
 <animated-vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/ic_hotspot_transient" >
     <target
-        android:name="circle_3"
-        android:animation="@anim/ic_hotspot_transient_circle_3_animation" />
+        android:name="circle01_0"
+        android:animation="@anim/ic_hotspot_transient_circle_1_animation" />
     <target
-        android:name="circle_2"
+        android:name="circle02_0"
         android:animation="@anim/ic_hotspot_transient_circle_2_animation" />
     <target
-        android:name="circle_1"
-        android:animation="@anim/ic_hotspot_transient_circle_1_animation" />
+        android:name="circle03_0"
+        android:animation="@anim/ic_hotspot_transient_circle_3_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors.xml b/packages/SystemUI/res/drawable/ic_invert_colors.xml
new file mode 100644
index 0000000..f7a86a4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_invert_colors.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <group
+        android:translateX="-0.61">
+        <path
+            android:pathData="M17.44,7.71L12.7,2.97a0.996,0.996 0,0 0,-1.41 0L6.56,7.71c-3,3 -3.4,7.89 -0.62,11.1 1.6,1.85 3.83,2.77 6.06,2.77s4.46,-0.92 6.06,-2.77c2.78,-3.21 2.38,-8.1 -0.62,-11.1zM12,19.59c-1.6,0 -3.11,-0.62 -4.24,-1.76C6.62,16.69 6,15.19 6,13.59s0.62,-3.11 1.76,-4.24L12,5.1v14.49z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml b/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml
deleted file mode 100644
index 49ee48b..0000000
--- a/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:alpha="1.0"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48"
-    android:tint="?android:attr/colorControlNormal" >
-    <group
-        android:name="icon"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="icon_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="0"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="ink_drop"
-                android:translateY="-6.8" >
-                <path
-                    android:name="outer_drop"
-                    android:pathData="M 35.3000030518,15.8999938965 c 0.0,0.0 -11.3000030518,-11.3999938965 -11.3000030518,-11.3999938965 c 0,0.0 -11.3000030518,11.3999938965 -11.3000030518,11.3999938965 c -6.19999694824,6.20001220703 -6.19999694824,16.4000091553 0.0,22.6000061035 c 3.10000610352,3.10000610352 7.19999694824,4.69999694824 11.3000030518,4.69999694824 c 4.10000610352,0.0 8.19999694824,-1.59999084473 11.3000030518,-4.69999694824 c 6.30000305176,-6.30000305176 6.30000305176,-16.3999938965 0.0,-22.6000061035 Z M 24,39.1999969482 c 0,0.0 0,0.0 0,0.0 c -3.19999694824,0.0 -6.19999694824,-1.19999694824 -8.5,-3.5 c -2.30000305176,-2.29998779297 -3.5,-5.30000305176 -3.5,-8.5 c 0,-3.19999694824 1.19999694824,-6.19999694824 3.5,-8.5 c 0.0,0.0 8.5,-8.5 8.5,-8.5 c 0,0.0 0,29.0 0,29.0 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_disable_animation.xml b/packages/SystemUI/res/drawable/ic_invert_colors_disable_animation.xml
deleted file mode 100644
index aeda0a5..0000000
--- a/packages/SystemUI/res/drawable/ic_invert_colors_disable_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_invert_colors_disable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_invert_colors_disable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_invert_colors_disable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml b/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml
deleted file mode 100644
index 169cc71..0000000
--- a/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48"
-    android:tint="?android:attr/colorControlNormal" >
-    <group
-        android:name="icon"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="icon_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="1"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="ink_drop"
-                android:translateY="-6.8" >
-                <path
-                    android:name="outer_drop"
-                    android:pathData="M 35.3000030518,15.8999938965 c 0.0,0.0 -11.3000030518,-11.3999938965 -11.3000030518,-11.3999938965 c 0,0.0 -11.3000030518,11.3999938965 -11.3000030518,11.3999938965 c -6.19999694824,6.20001220703 -6.19999694824,16.4000091553 0.0,22.6000061035 c 3.10000610352,3.10000610352 7.19999694824,4.69999694824 11.3000030518,4.69999694824 c 4.10000610352,0.0 8.19999694824,-1.59999084473 11.3000030518,-4.69999694824 c 6.30000305176,-6.30000305176 6.30000305176,-16.3999938965 0.0,-22.6000061035 Z M 24,39.1999969482 c 0,0.0 0,0.0 0,0.0 c -3.19999694824,0.0 -6.19999694824,-1.19999694824 -8.5,-3.5 c -2.30000305176,-2.29998779297 -3.5,-5.30000305176 -3.5,-8.5 c 0,-3.19999694824 1.19999694824,-6.19999694824 3.5,-8.5 c 0.0,0.0 8.5,-8.5 8.5,-8.5 c 0,0.0 0,29.0 0,29.0 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_enable_animation.xml b/packages/SystemUI/res/drawable/ic_invert_colors_enable_animation.xml
deleted file mode 100644
index 85928ac..0000000
--- a/packages/SystemUI/res/drawable/ic_invert_colors_enable_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_invert_colors_enable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_invert_colors_enable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_invert_colors_enable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml
deleted file mode 100644
index 8b2585b..0000000
--- a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48"
-    android:tint="?android:attr/colorControlNormal" >
-    <group
-        android:name="ic_screen_rotation_48px_outlines"
-        android:translateX="24"
-        android:translateY="24" >
-        <group
-            android:name="ic_screen_rotation_48px_outlines_pivot"
-            android:translateX="-24.15"
-            android:translateY="-24.25" >
-            <group
-                android:name="arrows"
-                android:translateX="24.1"
-                android:translateY="24.1" >
-                <group
-                    android:name="arrows_pivot"
-                    android:translateX="-24.1"
-                    android:translateY="-24.1" >
-                    <path
-                        android:name="arrow_top"
-                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                    <path
-                        android:name="arrow_bottom"
-                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                </group>
-            </group>
-            <group
-                android:name="device"
-                android:translateX="24.14999"
-                android:translateY="24.25" >
-                <path
-                    android:name="body"
-                    android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
index 400a28b..00bcaf6 100644
--- a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,21 +14,19 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/ic_landscape_from_auto_rotate" >
     <target
+        android:name="landscape"
+        android:animation="@anim/ic_rotate_to_landscape_landscape_animation" />
+    <target
         android:name="arrows"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrows" />
+        android:animation="@anim/ic_rotate_to_landscape_arrows_animation" />
     <target
-        android:name="arrow_top"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrow_top" />
+        android:name="arrows_0"
+        android:animation="@anim/ic_rotate_to_landscape_arrows_0_animation" />
     <target
-        android:name="arrow_bottom"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrow_bottom" />
-    <target
-        android:name="device"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_device" />
-    <target
-        android:name="body"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_body" />
+        android:name="bottom_merged"
+        android:animation="@anim/ic_rotate_to_landscape_bottom_merged_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
index 603d0bf..cde6797 100644
--- a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
+++ b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,53 +14,51 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_landscape_to_rotate"
     android:height="48dp"
     android:width="48dp"
     android:viewportHeight="48"
     android:viewportWidth="48"
     android:tint="?android:attr/colorControlNormal" >
     <group
-        android:name="ic_screen_rotation_48px_outlines"
+        android:name="device"
         android:translateX="24"
         android:translateY="24" >
         <group
-            android:name="ic_screen_rotation_48px_outlines_pivot"
+            android:name="device_pivot"
             android:translateX="-24.15"
             android:translateY="-24.25" >
             <group
-                android:name="arrows"
-                android:translateX="24.1"
-                android:translateY="24.1"
-                android:scaleX="0.9"
-                android:scaleY="0.9"
-                android:rotation="-135" >
-                <group
-                    android:name="arrows_pivot"
-                    android:translateX="-24.1"
-                    android:translateY="-24.1" >
-                    <path
-                        android:name="arrow_top"
-                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="0" />
-                    <path
-                        android:name="arrow_bottom"
-                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="0" />
-                </group>
-            </group>
-            <group
-                android:name="device"
-                android:translateX="24.14999"
-                android:translateY="24.25"
-                android:rotation="-45" >
+                android:name="landscape"
+                android:translateX="24"
+                android:translateY="24" >
                 <path
-                    android:name="body"
-                    android:pathData="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+                    android:name="device_merged"
+                    android:pathData="M -21.9799957275,-10.0 c 0.0,0.0 -0.0200042724609,20.0 -0.0200042724609,20.0 c 0.0,2.19999694824 1.80000305176,4.0 4.0,4.0 c 0.0,0.0 36.0,0.0 36.0,0.0 c 2.19999694824,0.0 4.0,-1.80000305176 4.0,-4.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,-2.19999694824 -1.80000305176,-4.0 -4.0,-4.0 c 0.0,0.0 -36.0,0.0 -36.0,0.0 c -2.19999694824,0.0 -3.97999572754,1.80000305176 -3.97999572754,4.0 Z M 14.0,10.0 c 0.0,0.0 -28.0,0.0 -28.0,0.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,0.0 28.0,0.0 28.0,0.0 c 0.0,0.0 0.0,20.0 0.0,20.0 Z"
+                    android:fillColor="#FFFFFFFF" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="arrows"
+        android:translateX="24"
+        android:translateY="24"
+        android:rotation="-90" >
+        <group
+            android:name="arrows_pivot"
+            android:translateX="-24.0798"
+            android:translateY="-24.23" >
+            <group
+                android:name="arrows_0"
+                android:translateX="12.2505"
+                android:translateY="37.2145" >
+                <path
+                    android:name="bottom_merged"
+                    android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z"
                     android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
+                    android:fillAlpha="0" />
             </group>
         </group>
     </group>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
index 5263eb4..86dc6ce 100644
--- a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,21 +14,16 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/ic_landscape_to_auto_rotate" >
     <target
+        android:name="landscape"
+        android:animation="@anim/ic_landscape_to_rotate_landscape_animation" />
+    <target
         android:name="arrows"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrows" />
+        android:animation="@anim/ic_landscape_to_rotate_arrows_animation" />
     <target
-        android:name="arrow_top"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrow_top" />
-    <target
-        android:name="arrow_bottom"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrow_bottom" />
-    <target
-        android:name="device"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_device" />
-    <target
-        android:name="body"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_body" />
+        android:name="bottom_merged"
+        android:animation="@anim/ic_landscape_to_rotate_bottom_merged_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_lock_24dp.xml b/packages/SystemUI/res/drawable/ic_lock_24dp.xml
index 204af7e..bf0dc95 100644
--- a/packages/SystemUI/res/drawable/ic_lock_24dp.xml
+++ b/packages/SystemUI/res/drawable/ic_lock_24dp.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -20,6 +20,6 @@
         android:viewportHeight="24.0">
 
     <path
-        android:fillColor="@color/keyguard_affordance"
+        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_24dp.xml b/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml
index c877f06..232cf70 100644
--- a/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml
+++ b/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -20,6 +20,6 @@
         android:viewportHeight="24.0">
 
     <path
-        android:fillColor="@color/keyguard_affordance"
+        android:fillColor="?attr/wallpaperTextColor"
         android:pathData="M12.0,17.0c1.1,0.0 2.0,-0.9 2.0,-2.0s-0.9,-2.0 -2.0,-2.0c-1.1,0.0 -2.0,0.9 -2.0,2.0S10.9,17.0 12.0,17.0zM18.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.0l1.9,0.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1l0.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.0zM18.0,20.0L6.0,20.0L6.0,10.0l12.0,0.0L18.0,20.0z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_mic_26dp.xml b/packages/SystemUI/res/drawable/ic_mic_26dp.xml
index 83e4ba8..15c97b3 100644
--- a/packages/SystemUI/res/drawable/ic_mic_26dp.xml
+++ b/packages/SystemUI/res/drawable/ic_mic_26dp.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -19,6 +19,6 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:pathData="M12.000000,14.000000c1.700000,0.000000 3.000000,-1.300000 3.000000,-3.000000l0.000000,-6.000000c0.000000,-1.700000 -1.300000,-3.000000 -3.000000,-3.000000c-1.700000,0.000000 -3.000000,1.300000 -3.000000,3.000000l0.000000,6.000000C9.000000,12.700000 10.300000,14.000000 12.000000,14.000000zM17.299999,11.000000c0.000000,3.000000 -2.500000,5.100000 -5.300000,5.100000c-2.800000,0.000000 -5.300000,-2.100000 -5.300000,-5.100000L5.000000,11.000000c0.000000,3.400000 2.700000,6.200000 6.000000,6.700000L11.000000,21.000000l2.000000,0.000000l0.000000,-3.300000c3.300000,-0.500000 6.000000,-3.300000 6.000000,-6.700000L17.299999,11.000001z"
-        android:fillColor="#FF000000"/>
+        android:fillColor="#FF000000"
+        android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM18.08,11c-0.42,0 -0.77,0.3 -0.83,0.71 -0.37,2.61 -2.72,4.39 -5.25,4.39s-4.88,-1.77 -5.25,-4.39a0.839,0.839 0,0 0,-0.83 -0.71c-0.52,0 -0.92,0.46 -0.85,0.97 0.46,2.96 2.96,5.3 5.93,5.75v2.43c0,0.47 0.38,0.85 0.85,0.85h0.31c0.47,0 0.85,-0.38 0.85,-0.85v-2.43c2.96,-0.43 5.47,-2.78 5.93,-5.75a0.87,0.87 0,0 0,-0.86 -0.97z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_mode_edit.xml b/packages/SystemUI/res/drawable/ic_mode_edit.xml
deleted file mode 100644
index f32da59..0000000
--- a/packages/SystemUI/res/drawable/ic_mode_edit.xml
+++ /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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="20.0dp"
-        android:height="20.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"
-        android:tint="?android:attr/colorControlNormal">
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M3.0,17.25L3.0,21.0l3.75,0.0L17.81,9.94l-3.75,-3.75L3.0,17.25zM20.71,7.04c0.39,-0.3 0.39,-1.02 0.0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0.0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
index 17185a7c..bce494c 100644
--- a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
+++ b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,50 +14,51 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_portrait_to_rotate"
     android:height="48dp"
     android:width="48dp"
     android:viewportHeight="48"
     android:viewportWidth="48"
     android:tint="?android:attr/colorControlNormal" >
     <group
-        android:name="icon"
+        android:name="device"
         android:translateX="24"
         android:translateY="24" >
         <group
-            android:name="icon_pivot"
+            android:name="device_pivot"
             android:translateX="-24.15"
             android:translateY="-24.25" >
             <group
-                android:name="arrows"
-                android:translateX="24.1"
-                android:translateY="24.1" >
-                <group
-                    android:name="arrows_pivot"
-                    android:translateX="-24.1"
-                    android:translateY="-24.1" >
-                    <path
-                        android:name="arrow_top"
-                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                    <path
-                        android:name="arrow_bottom"
-                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                </group>
-            </group>
-            <group
-                android:name="device"
+                android:name="device_0"
                 android:translateX="24.14999"
                 android:translateY="24.25" >
                 <path
-                    android:name="device_1"
+                    android:name="device_merged"
                     android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
+                    android:fillColor="#FFFFFFFF" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="arrows"
+        android:translateX="24"
+        android:translateY="24" >
+        <group
+            android:name="arrows_pivot"
+            android:translateX="-24.0798"
+            android:translateY="-24.23" >
+            <group
+                android:name="arrows_0"
+                android:translateX="12.2505"
+                android:translateY="37.2145" >
+                <path
+                    android:name="bottom_merged"
+                    android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z"
+                    android:fillColor="#FFFFFFFF" />
             </group>
         </group>
     </group>
 </vector>
+
diff --git a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
index 565ef26..b8465f4 100644
--- a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,21 +14,22 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_portrait_from_auto_rotate" >
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_portrait_to_auto_rotate" >
+    <target
+        android:name="device_0"
+        android:animation="@anim/ic_portrait_to_rotate_device_0_animation" />
+    <target
+        android:name="device_merged"
+        android:animation="@anim/ic_portrait_to_rotate_device_merged_animation" />
     <target
         android:name="arrows"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrows" />
+        android:animation="@anim/ic_portrait_to_rotate_arrows_animation" />
     <target
-        android:name="arrow_top"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrow_top" />
+        android:name="arrows_0"
+        android:animation="@anim/ic_portrait_to_rotate_arrows_0_animation" />
     <target
-        android:name="arrow_bottom"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrow_bottom" />
-    <target
-        android:name="device"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_device" />
-    <target
-        android:name="device_1"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_device_1" />
+        android:name="bottom_merged"
+        android:animation="@anim/ic_portrait_to_rotate_bottom_merged_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
index 88bf486..0ef15f0 100644
--- a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
+++ b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,53 +14,54 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_rotate_to_portrait"
     android:height="48dp"
     android:width="48dp"
     android:viewportHeight="48"
     android:viewportWidth="48"
     android:tint="?android:attr/colorControlNormal" >
     <group
-        android:name="icon"
+        android:name="device"
         android:translateX="24"
         android:translateY="24" >
         <group
-            android:name="icon_pivot"
+            android:name="device_pivot"
             android:translateX="-24.15"
             android:translateY="-24.25" >
             <group
-                android:name="arrows"
-                android:translateX="24.1"
-                android:translateY="24.1"
-                android:scaleX="0.9"
-                android:scaleY="0.9"
-                android:rotation="-221" >
-                <group
-                    android:name="arrows_pivot"
-                    android:translateX="-24.1"
-                    android:translateY="-24.1" >
-                    <path
-                        android:name="arrow_top"
-                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="0" />
-                    <path
-                        android:name="arrow_bottom"
-                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="0" />
-                </group>
-            </group>
-            <group
-                android:name="device"
+                android:name="device_0"
                 android:translateX="24.14999"
                 android:translateY="24.25"
                 android:rotation="-135" >
                 <path
-                    android:name="device_1"
+                    android:name="device_merged"
                     android:pathData="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+                    android:fillColor="#FFFFFFFF" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="arrows"
+        android:translateX="24"
+        android:translateY="24"
+        android:rotation="-221" >
+        <group
+            android:name="arrows_pivot"
+            android:translateX="-24.0798"
+            android:translateY="-24.23" >
+            <group
+                android:name="arrows_0"
+                android:translateX="12.2505"
+                android:translateY="37.2145"
+                android:scaleX="0.9"
+                android:scaleY="0.9" >
+                <path
+                    android:name="bottom_merged"
+                    android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z"
                     android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
+                    android:fillAlpha="0" />
             </group>
         </group>
     </group>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
index f75617f..6d3fd37 100644
--- a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,21 +14,22 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_portrait_to_auto_rotate" >
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_portrait_from_auto_rotate" >
+    <target
+        android:name="device_0"
+        android:animation="@anim/ic_rotate_to_portrait_device_0_animation" />
+    <target
+        android:name="device_merged"
+        android:animation="@anim/ic_rotate_to_portrait_device_merged_animation" />
     <target
         android:name="arrows"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrows" />
+        android:animation="@anim/ic_rotate_to_portrait_arrows_animation" />
     <target
-        android:name="arrow_top"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrow_top" />
+        android:name="arrows_0"
+        android:animation="@anim/ic_rotate_to_portrait_arrows_0_animation" />
     <target
-        android:name="arrow_bottom"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrow_bottom" />
-    <target
-        android:name="device"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_device" />
-    <target
-        android:name="device_1"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_device_1" />
+        android:name="bottom_merged"
+        android:animation="@anim/ic_rotate_to_portrait_bottom_merged_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml
index 8a3e975..3eb81f8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,13 +14,12 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0"
-        android:tint="?android:attr/colorControlNormal">
-
+    android:width="64dp"
+    android:height="64dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0"
+    android:tint="?android:attr/colorControlNormal" >
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M14.0,24.0l-4.0,-4.0l-4.0,4.0l4.0,4.0L14.0,24.0zM35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6zM38.0,20.0l-4.0,4.0l4.0,4.0l4.0,-4.0L38.0,20.0z"/>
+        android:pathData="M13.51,12l3.75,-3.74c0.41,-0.41 0.41,-1.07 0,-1.48l-4.47,-4.47 -0.03,-0.03a1.046,1.046 0,0 0,-1.76 0.76v6.44L6.95,5.43c-0.41,-0.41 -1.06,-0.41 -1.47,0s-0.41,1.06 0,1.47l5.09,5.1 -5.09,5.09c-0.41,0.41 -0.41,1.06 0,1.47s1.06,0.41 1.47,0L11,14.51v6.45a1.04,1.04 0,0 0,1.75 0.76l0.05,-0.05 4.46,-4.46c0.41,-0.41 0.41,-1.07 0,-1.48L13.51,12zM12.99,9.67v-4.3l2.15,2.15 -2.15,2.15zM12.99,18.62v-4.3l2.15,2.15 -2.15,2.15zM6.06,13.06c-0.59,0.59 -1.54,0.59 -2.12,0a1.49,1.49 0,0 1,0 -2.12,1.49 1.49,0 0,1 2.12,0c0.59,0.59 0.59,1.53 0,2.12zM20.06,10.94c0.59,0.59 0.59,1.54 0,2.12 -0.59,0.59 -1.54,0.59 -2.12,0a1.49,1.49 0,0 1,0 -2.12,1.49 1.49,0 0,1 2.12,0z"
+        android:fillColor="#FFFFFFFF" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml
index 1dadc05..fbd92de 100644
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,13 +14,12 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0"
-        android:tint="?android:attr/colorControlNormal">
-
+    android:width="64dp"
+    android:height="64dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0"
+    android:tint="?android:attr/colorControlNormal" >
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M28.5,24.0l4.6,4.6c0.6,-1.4 0.9,-3.0 0.9,-4.7c0.0,-1.6 -0.3,-3.2 -0.9,-4.6L28.5,24.0zM39.1,13.4L36.5,16.0c1.3,2.4 2.0,5.1 2.0,8.0s-0.7,5.6 -2.0,8.0l2.4,2.4c1.9,-3.1 3.1,-6.7 3.1,-10.6C42.0,20.0 40.9,16.5 39.1,13.4zM31.4,15.4L20.0,4.0l-2.0,0.0l0.0,15.2L8.8,10.0L6.0,12.8L17.2,24.0L6.0,35.2L8.8,38.0l9.2,-9.2L18.0,44.0l2.0,0.0l11.4,-11.4L22.8,24.0L31.4,15.4zM22.0,11.7l3.8,3.8L22.0,19.2L22.0,11.7zM25.8,32.6L22.0,36.3l0.0,-7.5L25.8,32.6z"/>
+        android:pathData="M14.95,11.3l1.62,-1.61C16.84,10.41 17,11.18 17,12s-0.16,1.61 -0.44,2.33l-1.61,-1.61C14.56,12.33 14.56,11.69 14.95,11.3zM18.69,7.54c-0.26,0.26 -0.32,0.65 -0.17,0.98c0.47,1.07 0.72,2.24 0.72,3.47c0,1.24 -0.26,2.43 -0.73,3.49c-0.14,0.32 -0.09,0.69 0.16,0.94c0.4,0.4 1.09,0.29 1.34,-0.23c0.63,-1.3 0.98,-2.76 0.98,-4.3c-0.01,-1.46 -0.33,-2.86 -0.91,-4.12C19.84,7.23 19.12,7.11 18.69,7.54zM15.26,15.74c0.41,0.41 0.41,1.07 0,1.48l-4.51,4.51C10.57,21.89 10.32,22 10.04,22C9.47,22 9,21.53 9,20.96v-6.45l-4.05,4.05c-0.41,0.41 -1.06,0.41 -1.47,0s-0.41,-1.06 0,-1.47L8.57,12L3.48,6.9c-0.41,-0.41 -0.41,-1.06 0,-1.47s1.06,-0.41 1.47,0L9,9.49V3.04C9,2.47 9.47,2 10.04,2c0.28,0 0.53,0.11 0.72,0.29l4.5,4.5c0.41,0.41 0.41,1.07 0,1.48L11.51,12L15.26,15.74zM13.14,7.53l-2.15,-2.15v4.3C10.99,9.68 13.14,7.53 13.14,7.53zM13.14,16.47l-2.15,-2.15v4.3C10.99,18.62 13.14,16.47 13.14,16.47z"
+        android:fillColor="#FFFFFFFF" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_detail_empty.xml
index 33a4047..e6d6f2c 100644
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_detail_empty.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_detail_empty.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -16,12 +16,12 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="56dp"
         android:height="56dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
         android:alpha="0.14"
         android:tint="?android:attr/colorForeground">
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6z"/>
+        android:pathData="M13.5,12l3.8,-3.7c0.4,-0.4 0.4,-1.1 0,-1.5l-4.5,-4.5c-0.4,-0.4 -1.1,-0.4 -1.5,0.1C11.1,2.5 11,2.8 11,3v6.4L6.9,5.4C6.5,5 5.9,5 5.5,5.4s-0.4,1.1 0,1.5l5.1,5.1l-5.1,5.1c-0.4,0.4 -0.4,1.1 0,1.5s1.1,0.4 1.5,0l4.1,-4V21c0,0.6 0.5,1 1,1c0.3,0 0.5,-0.1 0.7,-0.3l0.1,0l4.5,-4.5c0.4,-0.4 0.4,-1.1 0,-1.5L13.5,12zM13,9.7V5.4l2.1,2.2L13,9.7zM13,18.6v-4.3l2.1,2.2L13,18.6z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_off.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_off.xml
deleted file mode 100644
index 3148a2c..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_off.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0"
-        android:tint="?android:attr/colorControlNormal">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M26.0,11.8l3.8,3.8l-3.2,3.2l2.8,2.8l6.0,-6.0L24.0,4.2l-2.0,0.0l0.0,10.1l4.0,4.0L26.0,11.8zM10.8,8.2L8.0,11.0l13.2,13.2L10.0,35.3l2.8,2.8L22.0,29.0l0.0,15.2l2.0,0.0l8.6,-8.6l4.6,4.6l2.8,-2.8L10.8,8.2zM26.0,36.5L26.0,29.0l3.8,3.8L26.0,36.5z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml
index 2e9e741..8cc6caa 100644
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,13 +14,12 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0"
-        android:tint="?android:attr/colorControlNormal">
-
+    android:width="64dp"
+    android:height="64dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0"
+    android:tint="?android:attr/colorControlNormal">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6z"/>
+        android:pathData="M13.5,12l3.8,-3.7c0.4,-0.4 0.4,-1.1 0,-1.5l-4.5,-4.5c-0.4,-0.4 -1.1,-0.4 -1.5,0.1C11.1,2.5 11,2.8 11,3v6.4L6.9,5.4C6.5,5 5.9,5 5.5,5.4s-0.4,1.1 0,1.5l5.1,5.1l-5.1,5.1c-0.4,0.4 -0.4,1.1 0,1.5s1.1,0.4 1.5,0l4.1,-4V21c0,0.6 0.5,1 1,1c0.3,0 0.5,-0.1 0.7,-0.3l0.1,0l4.5,-4.5c0.4,-0.4 0.4,-1.1 0,-1.5L13.5,12zM13,9.7V5.4l2.1,2.2L13,9.7zM13,18.6v-4.3l2.1,2.2L13,18.6z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml
index b7fe5ab..aaebc77 100644
--- a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
diff --git a/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml
index fc831f4..ffde286 100644
--- a/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -23,5 +23,5 @@
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0zM2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0z"/>
+        android:pathData="M1,18v2c0,0.55 0.45,1 1,1h2c0,-1.66 -1.34,-3 -3,-3zM0.97,15.06c-0.01,0.51 0.35,0.93 0.85,1.02 2.08,0.36 3.74,2 4.1,4.08 0.09,0.48 0.5,0.84 0.99,0.84 0.61,0 1.09,-0.54 1,-1.14a6.996,6.996 0,0 0,-5.8 -5.78c-0.59,-0.09 -1.12,0.38 -1.14,0.98zM0.97,11.03c-0.01,0.52 0.37,0.96 0.88,1.01 4.26,0.43 7.68,3.82 8.1,8.08 0.05,0.5 0.48,0.88 0.99,0.88 0.59,0 1.06,-0.51 1,-1.1 -0.52,-5.21 -4.66,-9.34 -9.87,-9.85 -0.57,-0.05 -1.08,0.4 -1.1,0.98zM21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2z" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_cast_off.xml b/packages/SystemUI/res/drawable/ic_qs_cast_off.xml
index 06a0886..9e57577 100644
--- a/packages/SystemUI/res/drawable/ic_qs_cast_off.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_cast_off.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,12 +14,11 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
+    android:width="64dp"
+    android:height="64dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0zM2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0z"/>
+        android:pathData="M1,18v2c0,0.55 0.45,1 1,1h2c0,-1.66 -1.34,-3 -3,-3zM0.97,15.06c-0.01,0.51 0.35,0.93 0.85,1.02 2.08,0.36 3.74,2 4.1,4.08 0.09,0.48 0.5,0.84 0.99,0.84 0.61,0 1.09,-0.54 1,-1.14a6.996,6.996 0,0 0,-5.8 -5.78c-0.59,-0.09 -1.12,0.38 -1.14,0.98zM0.97,11.03c-0.01,0.52 0.37,0.96 0.88,1.01 4.26,0.43 7.68,3.82 8.1,8.08 0.05,0.5 0.48,0.88 0.99,0.88 0.59,0 1.06,-0.51 1,-1.1 -0.52,-5.21 -4.66,-9.34 -9.87,-9.85 -0.57,-0.05 -1.08,0.4 -1.1,0.98zM21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2z"
+        android:fillColor="#FFFFFFFF" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_cast_on.xml b/packages/SystemUI/res/drawable/ic_qs_cast_on.xml
index 794eb9e..3dda87c 100644
--- a/packages/SystemUI/res/drawable/ic_qs_cast_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_cast_on.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -16,10 +16,10 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="64dp"
         android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
 
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM38.0,14.0L10.0,14.0l0.0,3.3c7.9,2.6 14.2,8.8 16.7,16.7L38.0,34.0L38.0,14.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0zM42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0z"/>
+        android:pathData="M1,18v2c0,0.55 0.45,1 1,1h2c0,-1.66 -1.34,-3 -3,-3zM0.97,15.06c-0.01,0.51 0.35,0.93 0.85,1.02 2.08,0.36 3.74,2 4.1,4.08 0.09,0.48 0.5,0.84 0.99,0.84 0.61,0 1.09,-0.54 1,-1.14a6.996,6.996 0,0 0,-5.8 -5.78c-0.59,-0.09 -1.12,0.38 -1.14,0.98zM19,7L5,7v1.63c3.96,1.28 7.09,4.41 8.37,8.37L19,17L19,7zM0.97,11.03c-0.01,0.52 0.37,0.96 0.88,1.01 4.26,0.43 7.68,3.82 8.1,8.08 0.05,0.5 0.48,0.88 0.99,0.88 0.59,0 1.06,-0.51 1,-1.1 -0.52,-5.21 -4.66,-9.34 -9.87,-9.85 -0.57,-0.05 -1.08,0.4 -1.1,0.98zM21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2z" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_data_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_data_disabled.xml
index 8b5e4b0..8908975 100644
--- a/packages/SystemUI/res/drawable/ic_qs_data_disabled.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_data_disabled.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
+        android:width="12dp"
         android:height="24.0dp"
-        android:viewportWidth="40.0"
+        android:viewportWidth="20.0"
         android:viewportHeight="40.0"
         android:tint="?android:attr/colorControlNormal">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_detail_empty.xml
new file mode 100644
index 0000000..d71018b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_dnd_detail_empty.xml
@@ -0,0 +1,26 @@
+<!--
+    Copyright (C) 2017 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="56dp"
+    android:height="56dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0"
+    android:alpha="0.14"
+    android:tint="?android:attr/colorForeground">
+    <path
+        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16,13L8,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"
+        android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_off.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_off.xml
deleted file mode 100644
index 9168dbc..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_dnd_off.xml
+++ /dev/null
@@ -1,40 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="64dp"
-    android:viewportHeight="24.0"
-    android:viewportWidth="24.0"
-    android:width="64dp" >
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.8,11.1L17.0,11.1l0.0,2.0l-1.2,0.0l4.5,4.5c1.1,-1.6 1.7,-3.5 1.7,-5.5c0.0,-5.5 -4.5,-10.0 -10.0,-10.0c-2.0,0.0 -3.9,0.6 -5.5,1.7L13.8,11.1z" />
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.0,13.1L7.0,13.1l0.0,-2.0l4.0,0.0L4.9,5.0C3.1,6.8 2.0,9.3 2.0,12.1c0.0,5.5 4.5,10.0 10.0,10.0c2.8,0.0 5.3,-1.1 7.1,-2.9L13.0,13.1z" />
-
-    <group
-        android:pivotX="12.0"
-        android:pivotY="12.0"
-        android:rotation="45.0"
-        android:translateX="0.5"
-        android:translateY="0.5" >
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M-2.8,11.8l28.3,0.0l0.0,2.0l-28.3,0.0z" />
-    </group>
-
-</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml
index f4c20a9..233b9b9 100644
--- a/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2015 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -16,9 +16,9 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="64dp"
         android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M24.0,4.0C12.95,4.0 4.0,12.95 4.0,24.0s8.95,20.0 20.0,20.0 20.0,-8.95 20.0,-20.0S35.05,4.0 24.0,4.0zm10.0,22.0L14.0,26.0l0.0,-4.0l20.0,0.0l0.0,4.0z"/>
+        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16,13L8,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"
+        android:fillColor="#FFFFFFFF"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml
index fb26c09..5012aa4 100644
--- a/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2015 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -18,12 +18,7 @@
         android:height="64dp"
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
-
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0s10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM12.0,20.5c-4.7,0.0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12.0,3.5s8.5,3.8 8.5,8.5S16.7,20.5 12.0,20.5z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M12.0,6.0c-3.3,0.0 -6.0,2.7 -6.0,6.0c0.0,3.3 2.7,6.0 6.0,6.0s6.0,-2.7 6.0,-6.0C18.0,8.7 15.4,6.0 12.0,6.0zM15.0,13.0L9.0,13.0l0.0,-2.0l6.0,0.0L15.0,13.0z"/>
-
+        android:pathData="M12,2C6.5,2 2,6.5 2,12s4.5,10 10,10 10,-4.5 10,-10S17.5,2 12,2zM12,20.5c-4.7,0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12,3.5s8.5,3.8 8.5,8.5 -3.8,8.5 -8.5,8.5zM12,6c-3.3,0 -6,2.7 -6,6s2.7,6 6,6 6,-2.7 6,-6 -2.6,-6 -6,-6zM14,13h-4c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h4c0.55,0 1,0.45 1,1s-0.45,1 -1,1z" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_minus.xml b/packages/SystemUI/res/drawable/ic_qs_minus.xml
index 6a3410a..ead6b03 100644
--- a/packages/SystemUI/res/drawable/ic_qs_minus.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_minus.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,12 +15,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24.0dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
     android:width="24.0dp" >
-
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M38.0,26.0L10.0,26.0l0.0,-4.0l28.0,0.0l0.0,4.0z" />
-
-</vector>
\ No newline at end of file
+        android:pathData="M18,13H6c-0.55,0 -1,-0.45 -1,-1v0c0,-0.55 0.45,-1 1,-1h12c0.55,0 1,0.45 1,1v0C19,12.55 18.55,13 18,13z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml b/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml
deleted file mode 100644
index aaca663e..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="64dp"
-    android:height="64dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:fillColor="#FFF"
-        android:pathData="M6,12c0,5.5,4.5,10,10,10c1,0,2-0.2,3-0.5c-4.1-1.3-7-5.1-7-9.5s2.9-8.3,7-9.5C18.1,2.2,17.1,2,16,2C10.5,2,6,6.5,6,12z" />
-
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml b/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml
deleted file mode 100644
index aaca663e..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="64dp"
-    android:height="64dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:fillColor="#FFF"
-        android:pathData="M6,12c0,5.5,4.5,10,10,10c1,0,2-0.2,3-0.5c-4.1-1.3-7-5.1-7-9.5s2.9-8.3,7-9.5C18.1,2.2,17.1,2,16,2C10.5,2,6,6.5,6,12z" />
-
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_plus.xml b/packages/SystemUI/res/drawable/ic_qs_plus.xml
index 393f51c..f1b19e1e 100644
--- a/packages/SystemUI/res/drawable/ic_qs_plus.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_plus.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,12 +15,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24.0dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
     android:width="24.0dp" >
-
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M38.0,26.0L26.0,26.0l0.0,12.0l-4.0,0.0L22.0,26.0L10.0,26.0l0.0,-4.0l12.0,0.0L22.0,10.0l4.0,0.0l0.0,12.0l12.0,0.0l0.0,4.0z" />
-
-</vector>
\ No newline at end of file
+        android:pathData="M18,13h-5v5c0,0.55 -0.45,1 -1,1h0c-0.55,0 -1,-0.45 -1,-1v-5H6c-0.55,0 -1,-0.45 -1,-1v0c0,-0.55 0.45,-1 1,-1h5V6c0,-0.55 0.45,-1 1,-1h0c0.55,0 1,0.45 1,1v5h5c0.55,0 1,0.45 1,1v0C19,12.55 18.55,13 18,13z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml b/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml
index 15d521f..5217748 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
+        android:width="12.0dp"
         android:height="24dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml
index ce37331..c84ac8f 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
+        android:width="12dp"
         android:height="24dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml
index 4a8d0ab..26b68c7 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
+        android:width="12.0dp"
         android:height="24dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml b/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml
index e0c6b68..6e4b4c5 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml
@@ -14,9 +14,9 @@
     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:width="15.0dp"
+        android:height="20.0dp"
+        android:viewportWidth="18.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_e.xml b/packages/SystemUI/res/drawable/ic_qs_signal_e.xml
index 5525508..f4b6ed8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_e.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_e.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
+        android:width="12dp"
         android:height="24dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
   <group
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_g.xml
index f499fe7..60a7f1e9 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_g.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_g.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
+        android:width="12dp"
         android:height="24dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <group android:translateX="3.5" >
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_h.xml b/packages/SystemUI/res/drawable/ic_qs_signal_h.xml
index 2e6ea23..4ffb4be 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_h.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_h.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
+        android:width="12dp"
         android:height="24dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
       <group
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml b/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml
index af9c446..816cd32 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
+        android:width="11.9dp"
+        android:height="22dp"
+        android:viewportWidth="13.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml b/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml
index 5ff7d85..4c43e13 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml
@@ -14,9 +14,9 @@
     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:width="15.0dp"
+        android:height="19.5dp"
+        android:viewportWidth="18.5"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_0.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_0.xml
index e6f9292..7cbc26f 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_0.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_0.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,15 +14,19 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillAlpha="0.3"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.799999,-1.800001z"
-        android:fillColor="#FFFFFF"/>
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="25.50"
+    android:viewportHeight="25.50">
+    <group
+        android:translateX="0.77"
+        android:translateY="0.23" >
+        <path
+            android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+            android:fillAlpha="0.3"
+            android:fillColor="#FFFFFF"/>
+        <path
+            android:pathData="M22.71,15.67l-1.83,1.83l1.83,1.83c0.38,0.38 0.38,1 0,1.38v0c-0.38,0.38 -1,0.39 -1.38,0l-1.83,-1.83l-1.83,1.83c-0.38,0.38 -1,0.38 -1.38,0l-0.01,-0.01c-0.38,-0.38 -0.38,-1 0,-1.38l1.83,-1.83l-1.82,-1.82c-0.38,-0.38 -0.38,-1 0,-1.38l0.01,-0.01c0.38,-0.38 1,-0.38 1.38,0l1.82,1.82l1.82,-1.82c0.38,-0.38 1,-0.38 1.38,0l0,0C23.09,14.67 23.09,15.29 22.71,15.67z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml
index d423ccb..675dfc9 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,18 +14,19 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,13.2c-0.1,0.0 -0.3,-0.1 -0.4,-0.1c-0.1,0.0 -0.3,0.0 -0.4,-0.1c-0.3,0.0 -0.6,-0.1 -0.9,-0.1c0.0,0.0 0.0,0.0 -0.1,0.0c0.0,0.0 0.0,0.0 0.0,0.0s0.0,0.0 0.0,0.0c0.0,0.0 0.0,0.0 -0.1,0.0c-0.3,0.0 -0.6,0.0 -0.9,0.1c-0.1,0.0 -0.3,0.0 -0.4,0.1c-0.2,0.0 -0.3,0.1 -0.5,0.1c-0.2,0.0 -0.3,0.1 -0.5,0.1c-0.1,0.0 -0.1,0.0 -0.2,0.1c-1.6,0.5 -2.7,1.3 -2.8,1.5l5.3,6.6l0.0,0.0l0.0,0.0l0.0,0.0l0.0,0.0l1.8,-2.2L13.700002,13.2z"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillAlpha="0.3"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.799999,-1.800001z"
-        android:fillColor="#FFFFFF"/>
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="25.50"
+    android:viewportHeight="25.50">
+    <group
+        android:translateX="0.77"
+        android:translateY="0.23" >
+        <path
+            android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+            android:fillAlpha="0.3"
+            android:fillColor="#FFFFFF"/>
+        <path
+            android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53 -1.23,0.53 -1.66,0l-5.1,-6.35C7.65,13.85 9.72,13 12,13c0.69,0 1.36,0.08 2,0.23V20.13zM22.71,14.29L22.71,14.29c-0.38,-0.38 -1,-0.39 -1.38,0l-1.82,1.82l-1.82,-1.82c-0.38,-0.38 -1,-0.38 -1.38,0l-0.01,0.01c-0.38,0.38 -0.38,1 0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38 -0.38,1 0,1.38l0.01,0.01c0.38,0.38 1,0.38 1.38,0l1.83,-1.83l1.83,1.83c0.38,0.38 1,0.38 1.38,0v0c0.38,-0.38 0.38,-1 0,-1.38l-1.83,-1.83l1.83,-1.83C23.09,15.29 23.09,14.67 22.71,14.29z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml
index 1982130..c9a7eb8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,18 +14,19 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l4.9,0.0c-1.0,-0.7 -3.4,-2.2 -6.7,-2.2c-4.1,0.0 -6.9,2.2 -7.2,2.5l7.2,9.0l0.0,0.0l0.0,0.0l1.8,-2.2L13.800001,12.2z"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillAlpha="0.3"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.800001,1.9 -1.800001,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
-        android:fillColor="#FFFFFF"/>
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="25.50"
+    android:viewportHeight="25.50">
+    <group
+        android:translateX="0.77"
+        android:translateY="0.23" >
+        <path
+            android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+            android:fillAlpha="0.3"
+            android:fillColor="#FFFFFF"/>
+        <path
+            android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53 -1.23,0.53 -1.66,0l-6.98,-8.7C6.28,11.1 9.01,10 12,10c2.45,0 4.72,0.74 6.62,2H14V20.13zM22.71,14.29L22.71,14.29c-0.38,-0.38 -1,-0.39 -1.38,0l-1.82,1.82l-1.82,-1.82c-0.38,-0.38 -1,-0.38 -1.38,0l-0.01,0.01c-0.38,0.38 -0.38,1 0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38 -0.38,1 0,1.38l0.01,0.01c0.38,0.38 1,0.38 1.38,0l1.83,-1.83l1.83,1.83c0.38,0.38 1,0.38 1.38,0v0c0.38,-0.38 0.38,-1 0,-1.38l-1.83,-1.83l1.83,-1.83C23.09,15.29 23.09,14.67 22.71,14.29z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml
index b350111..a6facae 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,18 +14,19 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0l1.0,-1.2C20.0,10.6 16.8,8.0 12.0,8.0s-8.0,2.6 -8.5,3.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillAlpha="0.3"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
-        android:fillColor="#FFFFFF"/>
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="25.50"
+    android:viewportHeight="25.50">
+    <group
+        android:translateX="0.77"
+        android:translateY="0.23" >
+        <path
+            android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+            android:fillAlpha="0.3"
+            android:fillColor="#FFFFFF"/>
+        <path
+            android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53 -1.23,0.53 -1.66,0L2.93,11.35C5.37,9.26 8.54,8 12,8c3.46,0 6.62,1.26 9.07,3.34L20.54,12H14V20.13zM22.71,14.29L22.71,14.29c-0.38,-0.38 -1,-0.39 -1.38,0l-1.82,1.82l-1.82,-1.82c-0.38,-0.38 -1,-0.38 -1.38,0l-0.01,0.01c-0.38,0.38 -0.38,1 0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38 -0.38,1 0,1.38l0.01,0.01c0.38,0.38 1,0.38 1.38,0l1.83,-1.83l1.83,1.83c0.38,0.38 1,0.38 1.38,0v0c0.38,-0.38 0.38,-1 0,-1.38l-1.83,-1.83l1.83,-1.83C23.09,15.29 23.09,14.67 22.71,14.29z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml
index 136a004..2eae8f5 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,15 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
-        android:fillColor="#FFFFFF"/>
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="25.50"
+    android:viewportHeight="25.50">
+    <group
+        android:translateX="0.77"
+        android:translateY="0.23" >
+        <path
+            android:pathData="M22.71,15.67l-1.83,1.83l1.83,1.83c0.38,0.38 0.38,1 0,1.38v0c-0.38,0.38 -1,0.39 -1.38,0l-1.83,-1.83l-1.83,1.83c-0.38,0.38 -1,0.38 -1.38,0l-0.01,-0.01c-0.38,-0.38 -0.38,-1 0,-1.38l1.83,-1.83l-1.82,-1.82c-0.38,-0.38 -0.38,-1 0,-1.38l0.01,-0.01c0.38,-0.38 1,-0.38 1.38,0l1.82,1.82l1.82,-1.82c0.38,-0.38 1,-0.38 1.38,0l0,0C23.09,14.67 23.09,15.29 22.71,15.67zM14,12h6.54l3.12,-3.89c0.39,-0.48 0.28,-1.19 -0.23,-1.54C21.66,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml
index 7993c80..95345b8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,17 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="56dp"
-        android:height="56dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0"
-        android:alpha="0.14"
-        android:tint="?android:attr/colorForeground">
-
-    <path
-        android:pathData="M24.0,4.0C15.0,4.0 6.7,7.0 0.0,12.0l24.0,32.0l24.0,-32.0C41.3,7.0 33.0,4.0 24.0,4.0z"
-        android:fillColor="#FFFFFF" />
+    android:width="56dp"
+    android:height="56dp"
+    android:viewportWidth="25.0"
+    android:viewportHeight="23.5"
+    android:alpha="0.14"
+    android:tint="?android:attr/colorForeground" >
+    <group
+        android:translateX="0.51"
+        android:translateY="-1.1">
+        <path
+            android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
index 70e4780..ea02ba7 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,16 +14,15 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M17.500000,16.500000L5.800000,3.400000c0.000000,0.000000 0.000000,0.000000 0.000000,0.000000l-2.700000,-3.000000L1.600000,1.800000l2.200000,2.500000c-2.000000,1.000000 -3.200000,2.000000 -3.400000,2.200000L13.000000,22.000000l0.000000,0.000000l0.000000,0.000000l0.000000,0.000000l0.000000,0.000000l3.200000,-3.900000l2.400000,2.700000l1.500000,-1.400000L17.500000,16.500000L17.500000,16.500000z"
-        android:fillAlpha=".3"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000c-1.900000,0.000000 -3.600000,0.300000 -5.200000,0.700000L18.700001,15.000000L25.600000,6.500000z"
-        android:fillAlpha=".3"/>
+    android:width="32dp"
+    android:height="29.5dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.6">
+    <group
+        android:translateX="0.8"
+        android:translateY="1.1">
+        <path
+            android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml
index 2dcdb71..cb87cae 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,29 +14,19 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="26.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M21.0,8.5
-        c0.85,0.0 1.6,0.23 2.3,0.62l2.24,-2.79
-        C25.1,5.96 20.26,2.0 13.0,2.0
-        S0.9,5.9 0.42,6.32
-        l12.57,15.6 4.21,-5.17
-        c-0.76,-0.87 -1.22,-2.0 -1.22,-3.25
-        c0.0,-2.76 2.24,-5.0 5.0,-5.0z"
-        android:fillAlpha=".3"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M21.0,10.0
-        c-1.93,0.0 -3.5,1.57 -3.5,3.5l1.75,0.0
-        c0.0,-0.9 0.78,-1.75 1.75,-1.75s1.7,0.78 1.75,1.75
-        c0.0,0.48 -0.2,0.92 -0.51,1.24l-1.09,1.1
-        c-0.6,0.63 -1.02,1.51 -1.02,2.47l0.0,0.44l1.75,0.0
-        c0.0,-1.3 0.39,-1.84 1.03,-2.47l0.78,-0.8
-        c0.5,-0.5 0.82,-1.2 0.82,-1.97
-        C24.5,11.57 22.93,10.0 21.0,10.0z
-        m-0.95,11.95l1.9,0.0l0.0,-1.9l-1.9,0.0l0.0,1.9z"/>
+    android:width="26dp"
+    android:height="24dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.7">
+    <group
+        android:translateX="0.82"
+        android:translateY="-1">
+        <path
+            android:pathData="M18.9,20.85c0,-0.61 0.49,-1.1 1.1,-1.1 0.61,0 1.1,0.49 1.1,1.1 0,0.61 -0.49,1.1 -1.1,1.1 -0.61,0 -1.1,-0.49 -1.1,-1.1zM20,10c-1.53,0 -2.84,0.99 -3.31,2.36 -0.19,0.56 0.23,1.14 0.81,1.14 0.36,0 0.72,-0.21 0.84,-0.55 0.23,-0.7 0.89,-1.2 1.66,-1.2 0.97,0 1.75,0.78 1.75,1.75 0,0.48 -0.2,0.92 -0.51,1.24l-1.09,1.1c-0.69,0.69 -0.92,1.38 -0.99,2.2 -0.04,0.51 0.36,0.96 0.88,0.96 0.44,0 0.83,-0.33 0.87,-0.77 0.07,-0.79 0.31,-1.27 1,-1.95l0.78,-0.8c0.5,-0.5 0.82,-1.2 0.82,-1.97C23.5,11.57 21.93,10 20,10z"
+            android:fillColor="#FFFFFFFF"/>
+        <path
+            android:pathData="M14.73,12.88c0,-2.7 2.19,-4.88 4.88,-4.88 1.22,0 2.32,0.46 3.18,1.2l0.88,-1.09c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0l3.88,-4.82a4.862,4.862 0,0 1,-1.97 -3.9z"
+            android:fillAlpha="0.3"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_0.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_0.xml
index 1bc7438..53e4efc 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_0.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_0.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,11 +14,15 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    android:width="32.0dp"
+    android:height="29.5dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.6">
+    <group
+        android:translateX="0.8"
+        android:translateY="-0.9">
+        <path
+            android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+            android:fillColor="#4DFFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_1.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_1.xml
index 5856115..8294183 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_1.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_1.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M13.100000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.500000,6.500000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.100000,22.000000l5.500000,-6.800000c-0.200000,-0.200000 -2.300000,-1.900000 -5.500000,-1.900000s-5.300000,1.800000 -5.500000,1.900000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000z"/>
+    android:width="32dp"
+    android:height="29.5dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.6">
+    <group
+        android:translateX="0.8"
+        android:translateY="-0.9">
+        <path
+            android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+            android:fillColor="#4DFFFFFF"/>
+        <path
+            android:pathData="M12.82,21.6l5.11,-6.36A8.942,8.942 0,0 0,12 13c-2.28,0 -4.35,0.85 -5.94,2.25l5.1,6.35c0.43,0.53 1.23,0.53 1.66,0z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_2.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_2.xml
index 4a5e1f8..3d59cf2 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_2.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_2.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.000000,22.000000l7.600000,-9.400000C20.299999,12.400000 17.400000,10.000000 13.000000,10.000000s-7.300000,2.400000 -7.600000,2.700000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    android:width="32dp"
+    android:height="29.5dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.6">
+    <group
+        android:translateX="0.8"
+        android:translateY="-0.9">
+        <path
+            android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+            android:fillColor="#4DFFFFFF"/>
+        <path
+            android:pathData="M12.82,21.6l6.99,-8.7C17.71,11.1 14.99,10 12,10c-2.99,0 -5.72,1.1 -7.82,2.91l6.98,8.7c0.43,0.52 1.23,0.52 1.66,-0.01z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_3.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_3.xml
index 965442d..21313b8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_3.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_3.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.000000,22.000000l9.200000,-11.400000c-0.400000,-0.300000 -3.900000,-3.200000 -9.200000,-3.200000s-8.900000,3.000000 -9.200000,3.200000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    android:width="32dp"
+    android:height="29.5dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.6">
+    <group
+        android:translateX="0.8"
+        android:translateY="-0.9">
+        <path
+            android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+            android:fillColor="#4DFFFFFF"/>
+        <path
+            android:pathData="M12.82,21.6l8.25,-10.26A13.961,13.961 0,0 0,12 8c-3.46,0 -6.63,1.26 -9.07,3.35l8.23,10.26c0.43,0.52 1.23,0.52 1.66,-0.01z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_4.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_4.xml
index b29d3f9..fd763ff 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_4.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_4.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,11 +14,15 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    android:width="32dp"
+    android:height="29.5dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.6">
+    <group
+        android:translateX="0.8"
+        android:translateY="-0.9">
+        <path
+            android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_settings.xml b/packages/SystemUI/res/drawable/ic_settings.xml
index 9c78742..6d24c7e4 100644
--- a/packages/SystemUI/res/drawable/ic_settings.xml
+++ b/packages/SystemUI/res/drawable/ic_settings.xml
@@ -1,4 +1,4 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at"+
@@ -13,14 +13,11 @@
 limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-android:width="24dp"
-android:height="24dp" android:viewportWidth="24.0"
-          android:viewportHeight="24.0">
-
-
-<path
-     android:pathData="M19.4,13.0c0.0,-0.3 0.1,-0.6 0.1,-1.0s0.0,-0.7 -0.1,-1.0l2.1,-1.7c0.2,-0.2 0.2,-0.4 0.1,-0.6l-2.0,-3.5C19.5,5.1 19.3,5.0 19.0,5.1l-2.5,1.0c-0.5,-0.4 -1.1,-0.7 -1.7,-1.0l-0.4,-2.6C14.5,2.2 14.2,2.0 14.0,2.0l-4.0,0.0C9.8,2.0 9.5,2.2 9.5,2.4L9.1,5.1C8.5,5.3 8.0,5.7 7.4,6.1L5.0,5.1C4.7,5.0 4.5,5.1 4.3,5.3l-2.0,3.5C2.2,8.9 2.3,9.2 2.5,9.4L4.6,11.0c0.0,0.3 -0.1,0.6 -0.1,1.0s0.0,0.7 0.1,1.0l-2.1,1.7c-0.2,0.2 -0.2,0.4 -0.1,0.6l2.0,3.5C4.5,18.9 4.7,19.0 5.0,18.9l2.5,-1.0c0.5,0.4 1.1,0.7 1.7,1.0l0.4,2.6c0.0,0.2 0.2,0.4 0.5,0.4l4.0,0.0c0.2,0.0 0.5,-0.2 0.5,-0.4l0.4,-2.6c0.6,-0.3 1.2,-0.6 1.7,-1.0l2.5,1.0c0.2,0.1 0.5,0.0 0.6,-0.2l2.0,-3.5c0.1,-0.2 0.1,-0.5 -0.1,-0.6L19.4,13.0zM12.0,15.5c-1.9,0.0 -3.5,-1.6 -3.5,-3.5s1.6,-3.5 3.5,-3.5s3.5,1.6 3.5,3.5S13.9,15.5 12.0,15.5z"
-     android:fillColor="#ffffffff"
-     />
-
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:pathData="M21.4,14.2l-1.94,-1.45c0.03,-0.25 0.04,-0.5 0.04,-0.76s-0.01,-0.51 -0.04,-0.76L21.4,9.8c0.42,-0.31 0.52,-0.94 0.24,-1.41l-1.6,-2.76c-0.28,-0.48 -0.88,-0.7 -1.36,-0.5l-2.14,0.91c-0.48,-0.37 -1.01,-0.68 -1.57,-0.92l-0.27,-2.2c-0.06,-0.52 -0.56,-0.92 -1.11,-0.92h-3.18c-0.55,0 -1.05,0.4 -1.11,0.92l-0.26,2.19c-0.57,0.24 -1.1,0.55 -1.58,0.92l-2.14,-0.91c-0.48,-0.2 -1.08,0.02 -1.36,0.5l-1.6,2.76c-0.28,0.48 -0.18,1.1 0.24,1.42l1.94,1.45c-0.03,0.24 -0.04,0.49 -0.04,0.75s0.01,0.51 0.04,0.76L2.6,14.2c-0.42,0.31 -0.52,0.94 -0.24,1.41l1.6,2.76c0.28,0.48 0.88,0.7 1.36,0.5l2.14,-0.91c0.48,0.37 1.01,0.68 1.57,0.92l0.27,2.19c0.06,0.53 0.56,0.93 1.11,0.93h3.18c0.55,0 1.04,-0.4 1.11,-0.92l0.27,-2.19c0.56,-0.24 1.09,-0.55 1.57,-0.92l2.14,0.91c0.48,0.2 1.08,-0.02 1.36,-0.5l1.6,-2.76c0.28,-0.48 0.18,-1.1 -0.24,-1.42zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"
+        android:fillColor="#FFFFFFFF"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_settings_16dp.xml b/packages/SystemUI/res/drawable/ic_settings_16dp.xml
index c21b60c..e3ed229 100644
--- a/packages/SystemUI/res/drawable/ic_settings_16dp.xml
+++ b/packages/SystemUI/res/drawable/ic_settings_16dp.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -19,6 +19,6 @@
     android:viewportWidth="24.0"
     android:viewportHeight="24.0">
     <path
-        android:pathData="M19.4,13.0c0.0,-0.3 0.1,-0.6 0.1,-1.0s0.0,-0.7 -0.1,-1.0l2.1,-1.7c0.2,-0.2 0.2,-0.4 0.1,-0.6l-2.0,-3.5C19.5,5.1 19.3,5.0 19.0,5.1l-2.5,1.0c-0.5,-0.4 -1.1,-0.7 -1.7,-1.0l-0.4,-2.6C14.5,2.2 14.2,2.0 14.0,2.0l-4.0,0.0C9.8,2.0 9.5,2.2 9.5,2.4L9.1,5.1C8.5,5.3 8.0,5.7 7.4,6.1L5.0,5.1C4.7,5.0 4.5,5.1 4.3,5.3l-2.0,3.5C2.2,8.9 2.3,9.2 2.5,9.4L4.6,11.0c0.0,0.3 -0.1,0.6 -0.1,1.0s0.0,0.7 0.1,1.0l-2.1,1.7c-0.2,0.2 -0.2,0.4 -0.1,0.6l2.0,3.5C4.5,18.9 4.7,19.0 5.0,18.9l2.5,-1.0c0.5,0.4 1.1,0.7 1.7,1.0l0.4,2.6c0.0,0.2 0.2,0.4 0.5,0.4l4.0,0.0c0.2,0.0 0.5,-0.2 0.5,-0.4l0.4,-2.6c0.6,-0.3 1.2,-0.6 1.7,-1.0l2.5,1.0c0.2,0.1 0.5,0.0 0.6,-0.2l2.0,-3.5c0.1,-0.2 0.1,-0.5 -0.1,-0.6L19.4,13.0zM12.0,15.5c-1.9,0.0 -3.5,-1.6 -3.5,-3.5s1.6,-3.5 3.5,-3.5s3.5,1.6 3.5,3.5S13.9,15.5 12.0,15.5z"
-        android:fillColor="#ffffffff" />
+        android:pathData="M21.4,14.2l-1.94,-1.45c0.03,-0.25 0.04,-0.5 0.04,-0.76s-0.01,-0.51 -0.04,-0.76L21.4,9.8c0.42,-0.31 0.52,-0.94 0.24,-1.41l-1.6,-2.76c-0.28,-0.48 -0.88,-0.7 -1.36,-0.5l-2.14,0.91c-0.48,-0.37 -1.01,-0.68 -1.57,-0.92l-0.27,-2.2c-0.06,-0.52 -0.56,-0.92 -1.11,-0.92h-3.18c-0.55,0 -1.05,0.4 -1.11,0.92l-0.26,2.19c-0.57,0.24 -1.1,0.55 -1.58,0.92l-2.14,-0.91c-0.48,-0.2 -1.08,0.02 -1.36,0.5l-1.6,2.76c-0.28,0.48 -0.18,1.1 0.24,1.42l1.94,1.45c-0.03,0.24 -0.04,0.49 -0.04,0.75s0.01,0.51 0.04,0.76L2.6,14.2c-0.42,0.31 -0.52,0.94 -0.24,1.41l1.6,2.76c0.28,0.48 0.88,0.7 1.36,0.5l2.14,-0.91c0.48,0.37 1.01,0.68 1.57,0.92l0.27,2.19c0.06,0.53 0.56,0.93 1.11,0.93h3.18c0.55,0 1.04,-0.4 1.11,-0.92l0.27,-2.19c0.56,-0.24 1.09,-0.55 1.57,-0.92l2.14,0.91c0.48,0.2 1.08,-0.02 1.36,-0.5l1.6,-2.76c0.28,-0.48 0.18,-1.1 -0.24,-1.42zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"
+        android:fillColor="#FFFFFFFF"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane.xml b/packages/SystemUI/res/drawable/ic_signal_airplane.xml
new file mode 100644
index 0000000..50dd436
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_airplane.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="20.5"
+    android:viewportHeight="20.5">
+    <group
+        android:translateX="0.985"
+        android:translateY="1.10">
+        <path
+            android:pathData="M16.01,9.87l-6.24,-3.9v-4.7C9.77,0.57 9.21,0 8.5,0S7.23,0.57 7.23,1.28v4.7L0.99,9.88c-0.37,0.23 -0.6,0.64 -0.6,1.08v0.41c0,0.29 0.29,0.5 0.55,0.41l6.27,-1.97v4.7l-1.37,1.02c-0.21,0.16 -0.34,0.41 -0.34,0.68v0.57c0,0.15 0.12,0.23 0.27,0.2 1.67,-0.47 1.12,-0.31 2.73,-0.78 1.03,0.3 1.7,0.49 2.72,0.78 0.15,0.03 0.27,-0.06 0.27,-0.2v-0.57c0,-0.27 -0.13,-0.52 -0.34,-0.68l-1.37,-1.02v-4.7l6.27,1.97c0.28,0.09 0.55,-0.12 0.55,-0.41v-0.41c0.01,-0.45 -0.23,-0.87 -0.59,-1.09z"
+            android:fillColor="#FF0"/>
+    </group>
+</vector>
+
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml
deleted file mode 100644
index 09a67e1..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:alpha="1.0"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_signal_airplane"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="ic_signal_airplane_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="0"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="plane"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
-                <path
-                    android:name="plane_1"
-                    android:pathData="M 18.9439849854,7.98849487305 c 0.0,0.0 0.0,-4.0 0.0,-4.0 c 0.0,0.0 -16.0,-10.0 -16.0,-10.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,-1.70001220703 -1.30000305176,-3.0 -3.0,-3.0 c -1.69999694824,0.0 -3.0,1.29998779297 -3.0,3.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -16.0,10.0 -16.0,10.0 c 0.0,0.0 0.0,4.0 0.0,4.0 c 0.0,0.0 16.0,-5.0 16.0,-5.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -4.0,3.0 -4.0,3.0 c 0.0,0.0 0.0,3.0 0.0,3.0 c 0.0,0.0 7.0,-2.0 7.0,-2.0 c 0.0,0.0 7.0,2.0 7.0,2.0 c 0.0,0.0 0.0,-3.0 0.0,-3.0 c 0.0,0.0 -4.0,-3.0 -4.0,-3.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,0.0 16.0,5.0 16.0,5.0 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_disable_animation.xml
deleted file mode 100644
index 56ae4aa..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_airplane_disable_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_airplane_disable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_airplane_disable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_airplane_disable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml
deleted file mode 100644
index b7ac0134..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_signal_airplane"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="ic_signal_airplane_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="1"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="plane"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
-                <path
-                    android:name="plane_1"
-                    android:pathData="M 18.9439849854,7.98849487305 c 0.0,0.0 0.0,-4.0 0.0,-4.0 c 0.0,0.0 -16.0,-10.0 -16.0,-10.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,-1.70001220703 -1.30000305176,-3.0 -3.0,-3.0 c -1.69999694824,0.0 -3.0,1.29998779297 -3.0,3.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -16.0,10.0 -16.0,10.0 c 0.0,0.0 0.0,4.0 0.0,4.0 c 0.0,0.0 16.0,-5.0 16.0,-5.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -4.0,3.0 -4.0,3.0 c 0.0,0.0 0.0,3.0 0.0,3.0 c 0.0,0.0 7.0,-2.0 7.0,-2.0 c 0.0,0.0 7.0,2.0 7.0,2.0 c 0.0,0.0 0.0,-3.0 0.0,-3.0 c 0.0,0.0 -4.0,-3.0 -4.0,-3.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,0.0 16.0,5.0 16.0,5.0 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_enable_animation.xml
deleted file mode 100644
index 87dfba9..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_airplane_enable_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_airplane_enable" >
-    <target
-        android:name="ic_signal_airplane"
-        android:animation="@anim/ic_signal_airplane_enable_animation_ic_signal_airplane" />
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_airplane_enable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_airplane_enable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight.xml
new file mode 100644
index 0000000..38979a8
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_flashlight.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <group
+        android:translateX="-0.05"
+        android:translateY="0.85" >
+        <path
+            android:pathData="M8.28,2h7.43c0.55,0 1,0.45 1,1v0.96L7.28,3.96L7.28,3c0,-0.55 0.45,-1 1,-1zM14.8,9.76L14.8,21c0,0.55 -0.45,1 -1,1h-3.61c-0.55,0 -1,-0.45 -1,-1L9.19,9.78c-2.2,-1.17 -1.91,-3.76 -1.91,-3.76L7.28,5.7h9.44v0.32s0.26,2.57 -1.92,3.74zM13.38,12.47c0,-0.76 -0.62,-1.38 -1.38,-1.38s-1.38,0.62 -1.38,1.38 0.62,1.38 1.38,1.38 1.38,-0.62 1.38,-1.38z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml
deleted file mode 100644
index 35844b7..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:alpha="1.0"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_signal_flashlight"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="ic_signal_flashlight_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="0"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="flashlight"
-                android:translateX="25.06235"
-                android:translateY="22.48294" >
-                <path
-                    android:name="light"
-                    android:pathData="M -9.40809631348,-23.6970062256 c 0.0,0.0 18.8699951172,0.0 18.8699951172,0.0 c 0.0,0.0 0.0,3.91700744629 0.0,3.91700744629 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,-3.91700744629 0.0,-3.91700744629 Z M 9.4615020752,-15.6629943848 c 0.0,0.0 0.0,-0.639999389648 0.0,-0.639999389649 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,0.639999389648 0.0,0.639999389649 c 0.0,0.0 -0.581008911133,5.18899536133 3.82598876953,7.52299499512 c 0.0,0.0 0.0,24.4429931641 0.0,24.4429931641 c 0.0,0.0 11.2129974365,0.0 11.2129974365,0.0 c 0.0,0.0 0.0,-24.4769897461 0.0,-24.4769897461 c 4.35900878906,-2.35301208496 3.83100891113,-7.48899841309 3.83100891113,-7.48899841309 Z M 0.0234985351562,0 c -1.52299499512,0 -2.75700378418,-1.23399353027 -2.75700378418,-2.75700378418 c 0.0,-1.52299499512 1.23400878906,-2.75700378418 2.75700378418,-2.75700378418 c 1.52299499512,0.0 2.75700378418,1.23400878906 2.75700378418,2.75700378418 c 0.0,1.52200317383 -1.23400878906,2.75700378418 -2.75700378418,2.75700378418 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_disable_animation.xml
deleted file mode 100644
index e228b7c..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_flashlight_disable_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_flashlight_disable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_flashlight_disable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_flashlight_disable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml
deleted file mode 100644
index c2215f1..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_signal_flashlight"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="ic_signal_flashlight_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="1"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="flashlight"
-                android:translateX="25.06235"
-                android:translateY="22.48294" >
-                <path
-                    android:name="light"
-                    android:pathData="M -9.40809631348,-23.6970062256 c 0.0,0.0 18.8699951172,0.0 18.8699951172,0.0 c 0.0,0.0 0.0,3.91700744629 0.0,3.91700744629 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,-3.91700744629 0.0,-3.91700744629 Z M 9.4615020752,-15.6629943848 c 0.0,0.0 0.0,-0.639999389648 0.0,-0.639999389649 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,0.639999389648 0.0,0.639999389649 c 0.0,0.0 -0.581008911133,5.18899536133 3.82598876953,7.52299499512 c 0.0,0.0 0.0,24.4429931641 0.0,24.4429931641 c 0.0,0.0 11.2129974365,0.0 11.2129974365,0.0 c 0.0,0.0 0.0,-24.4769897461 0.0,-24.4769897461 c 4.35900878906,-2.35301208496 3.83100891113,-7.48899841309 3.83100891113,-7.48899841309 Z M 0.0234985351562,0 c -1.52299499512,0 -2.75700378418,-1.23399353027 -2.75700378418,-2.75700378418 c 0.0,-1.52299499512 1.23400878906,-2.75700378418 2.75700378418,-2.75700378418 c 1.52299499512,0.0 2.75700378418,1.23400878906 2.75700378418,2.75700378418 c 0.0,1.52200317383 -1.23400878906,2.75700378418 -2.75700378418,2.75700378418 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_enable_animation.xml
deleted file mode 100644
index 220c65e..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_flashlight_enable_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_flashlight_enable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_flashlight_enable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_flashlight_enable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_disable.xml b/packages/SystemUI/res/drawable/ic_signal_location_disable.xml
deleted file mode 100644
index 439851d..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_location_disable.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:alpha="1.0"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_signal_location"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="ic_signal_location_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="0"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="location"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
-                <path
-                    android:name="pin"
-                    android:pathData="M 1.76899719238,-20.011505127 c -7.69999694824,0.0 -14.0,6.30000305176 -14.0,14.0 c 0.0,10.5 14.0,26.0 14.0,26.0 c 0.0,0.0 14.0,-15.5 14.0,-26.0 c 0.0,-7.69999694824 -6.30000305176,-14.0 -14.0,-14.0 Z M 1.76899719238,-1.01150512695 c -2.80000305176,0.0 -5.0,-2.19999694824 -5.0,-5.0 c 0.0,-2.80000305176 2.19999694824,-5.0 5.0,-5.0 c 2.80000305176,0.0 5.0,2.19999694824 5.0,5.0 c 0.0,2.80000305176 -2.19999694824,5.0 -5.0,5.0 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_location_disable_animation.xml
deleted file mode 100644
index 0e9d1cb..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_location_disable_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_location_disable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_location_disable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_location_disable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_enable.xml b/packages/SystemUI/res/drawable/ic_signal_location_enable.xml
deleted file mode 100644
index d4b8673..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_location_enable.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_signal_location"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="ic_signal_location_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="1"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="location"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
-                <path
-                    android:name="pin"
-                    android:pathData="M 1.76899719238,-20.011505127 c -7.69999694824,0.0 -14.0,6.30000305176 -14.0,14.0 c 0.0,10.5 14.0,26.0 14.0,26.0 c 0.0,0.0 14.0,-15.5 14.0,-26.0 c 0.0,-7.69999694824 -6.30000305176,-14.0 -14.0,-14.0 Z M 1.76899719238,-1.01150512695 c -2.80000305176,0.0 -5.0,-2.19999694824 -5.0,-5.0 c 0.0,-2.80000305176 2.19999694824,-5.0 5.0,-5.0 c 2.80000305176,0.0 5.0,2.19999694824 5.0,5.0 c 0.0,2.80000305176 -2.19999694824,5.0 -5.0,5.0 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_location_enable_animation.xml
deleted file mode 100644
index 9f1d917..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_location_enable_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_location_enable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_location_enable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_location_enable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml
deleted file mode 100644
index 9c23126..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_workmode_disable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_workmode_disable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_workmode_disable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml
deleted file mode 100644
index 04ddfad..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_workmode_enable" >
-    <target
-        android:name="ic_signal_briefcase"
-        android:animation="@anim/ic_signal_workmode_enable_animation_ic_signal_briefcase" />
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_workmode_enable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_workmode_enable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_alarm.xml b/packages/SystemUI/res/drawable/ic_volume_alarm.xml
index e64f445..996e488 100644
--- a/packages/SystemUI/res/drawable/ic_volume_alarm.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_alarm.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,13 +15,13 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24.0dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
     android:width="24.0dp"
     android:tint="?android:attr/colorControlNormal">
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M44.0,11.44l-9.19,-7.71 -2.57,3.06 9.19,7.71 2.57,-3.06zm-28.24,-4.66l-2.57,-3.06 -9.19,7.71 2.57,3.06 9.19,-7.71zm9.24,9.22l-3.0,0.0l0.0,12.0l9.49,5.71 1.51,-2.47 -8.0,-4.74l0.0,-10.5zm-1.01,-8.0c-9.95,0.0 -17.99,8.06 -17.99,18.0s8.04,18.0 17.99,18.0 18.01,-8.06 18.01,-18.0 -8.06,-18.0 -18.01,-18.0zm0.01,32.0c-7.73,0.0 -14.0,-6.27 -14.0,-14.0s6.27,-14.0 14.0,-14.0 14.0,6.27 14.0,14.0 -6.26,14.0 -14.0,14.0z" />
+        android:pathData="M2.7,6.5c-0.4,-0.4 -0.3,-1 0.1,-1.4l3,-2.6c0.4,-0.4 1,-0.3 1.4,0.1C7.6,3 7.5,3.7 7.1,4l-3,2.6C3.6,7 3,6.9 2.7,6.5zM21.3,5.1l-3.1,-2.6c-0.4,-0.4 -0.99,-0.31 -1.4,0.1c-0.4,0.4 -0.3,1 0.1,1.4L20,6.6c0.41,0.37 1,0.3 1.4,-0.1C21.73,6.12 21.7,5.4 21.3,5.1zM21,13c0,5 -4,9 -9,9s-9,-4 -9,-9s4,-9 9,-9S21,8 21,13zM19.1,13c0,-3.9 -3.2,-7.1 -7.1,-7.1S4.9,9.1 4.9,13s3.2,7.1 7.1,7.1S19.1,16.9 19.1,13zM11.75,8C11.34,8 11,8.34 11,8.75V14l4.14,2.48c0.34,0.21 0.77,0.1 0.98,-0.24s0.09,-0.79 -0.25,-0.99l-3.37,-2v-4.5C12.5,8.34 12.16,8 11.75,8z"/>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml b/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml
index 37d7690..02fb1e7 100644
--- a/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,13 +15,13 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24.0dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
     android:width="24.0dp"
     android:tint="?android:attr/colorControlNormal" >
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M24.0,12.0c7.73,0.0 14.0,6.27 14.0,14.0 0.0,1.69 -0.31,3.3 -0.86,4.8l3.04,3.04c1.16,-2.37 1.82,-5.03 1.82,-7.84 0.0,-9.94 -8.06,-18.0 -18.01,-18.0 -2.81,0.0 -5.46,0.66 -7.84,1.81l3.05,3.05c1.5,-0.55 3.11,-0.86 4.8,-0.86zm20.0,-0.56l-9.19,-7.71 -2.57,3.06 9.19,7.71 2.57,-3.06zm-38.16,-6.85l-2.55,2.54 2.66,2.66 -2.22,1.86 2.84,2.84 2.22,-1.86 1.6,1.6c-2.73,3.16 -4.39,7.27 -4.39,11.77 0.0,9.94 8.04,18.0 17.99,18.0 4.51,0.0 8.62,-1.67 11.77,-4.4l4.4,4.4 2.54,-2.55 -34.91,-34.91 -1.95,-1.95zm27.1,32.19c-2.43,2.01 -5.54,3.22 -8.94,3.22 -7.73,0.0 -14.0,-6.27 -14.0,-14.0 0.0,-3.4 1.21,-6.51 3.22,-8.94l19.72,19.72zm-16.91,-30.23l-2.84,-2.84 -1.7,1.43 2.84,2.84 1.7,-1.43z" />
+        android:pathData="M21.35,6.49c-0.35,0.42 -0.98,0.47 -1.4,0.12l-3.07,-2.57a1,1 0,1 1,1.29 -1.53l3.07,2.57c0.42,0.35 0.47,0.98 0.11,1.41zM20.72,20.09a0.9,0.9 0,0 1,0 1.27,0.9 0.9,0 0,1 -1.27,0l-1.57,-1.57A8.875,8.875 0,0 1,12 22c-4.98,0 -9,-4.03 -9,-9 0,-2.25 0.83,-4.31 2.2,-5.89l-0.8,-0.8 -0.41,0.35a1,1 0,0 1,-1.35 -0.06,1 1,0 0,1 0.07,-1.47l0.27,-0.23 -0.7,-0.7a0.9,0.9 0,0 1,0 -1.27c0.35,-0.35 0.93,-0.35 1.28,0l17.16,17.16zM16.54,18.45L6.55,8.46A7.041,7.041 0,0 0,4.9 13c0,3.91 3.19,7.1 7.1,7.1 1.73,0 3.31,-0.62 4.54,-1.65zM7.17,3.98A0.997,0.997 0,1 0,5.9 2.44l-0.16,0.13 1.42,1.42 0.01,-0.01zM12,4c-1.41,0 -2.73,0.33 -3.92,0.91l1.45,1.45c0.77,-0.29 1.6,-0.46 2.47,-0.46 3.91,0 7.1,3.18 7.1,7.1 0,0.87 -0.17,1.7 -0.45,2.47l1.44,1.44c0.58,-1.18 0.91,-2.5 0.91,-3.91a9,9 0,0 0,-9 -9z"/>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml b/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml
index 5c3c650..b0b9404 100644
--- a/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,13 +15,16 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24.0dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
     android:width="24.0dp"
     android:tint="?android:attr/colorControlNormal" >
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M29.41,19.0L34.0,14.41L34.0,22.0l1.0,0.0l5.71,-5.71 -4.3,-4.29 4.29,-4.29L35.0,2.0l-1.0,0.0l0.0,7.59L29.41,5.0 28.0,6.41 33.59,12.0 28.0,17.59 29.41,19.0zM36.0,5.83l1.88,1.88L36.0,9.59L36.0,5.83zm0.0,8.58l1.88,1.88L36.0,18.17l0.0,-3.76zM40.0,31.0c-2.49,0.0 -4.89,-0.4 -7.14,-1.14 -0.69,-0.22 -1.48,-0.06 -2.0,0.49l-4.4,4.41c-5.67,-2.88 -10.29,-7.51 -13.18,-13.17l4.4,-4.41c0.55,-0.5 0.71,-1.3 0.49,-2.03C17.4,12.9 17.0,10.49 17.0,8.0c0.0,-1.11 -0.89,-2.0 -2.0,-2.0L8.0,6.0c-1.11,0.0 -2.0,0.89 -2.0,2.0 0.0,18.78 15.22,34.0 34.0,34.0 1.11,0.0 2.0,-0.89 2.0,-2.0l0.0,-7.0c0.0,-1.11 -0.89,-2.0 -2.0,-2.0z" />
+        android:pathData="M20,15.5c-1.25,0 -2.45,-0.2 -3.57,-0.57c-0.35,-0.11 -0.74,-0.03 -1.02,0.24l-2.2,2.2c-2.83,-1.44 -5.15,-3.75 -6.59,-6.59l2.2,-2.21c0.28,-0.26 0.36,-0.65 0.25,-1C8.7,6.45 8.5,5.25 8.5,4c0,-0.55 -0.45,-1 -1,-1H4C3.45,3 3,3.45 3,4c0,9.39 7.61,17 17,17c0.55,0 1,-0.45 1,-1v-3.5C21,15.95 20.55,15.5 20,15.5z"/>
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M17.97,6l1.88,-1.87c0.21,-0.21 0.21,-0.54 0,-0.74L17.6,1.16l-0.01,-0.01c-0.21,-0.2 -0.53,-0.2 -0.73,0.01c-0.09,0.1 -0.15,0.23 -0.15,0.36v3.23l-2.03,-2.03c-0.21,-0.21 -0.53,-0.21 -0.74,0c-0.21,0.21 -0.21,0.53 0,0.74L16.49,6l-2.55,2.55c-0.21,0.21 -0.21,0.53 0,0.74c0.21,0.21 0.53,0.21 0.74,0l2.03,-2.03v3.23c0,0.29 0.24,0.52 0.52,0.52c0.13,0 0.26,-0.05 0.35,-0.15l2.25,-2.25c0.21,-0.21 0.21,-0.54 0,-0.74L17.97,6zM17.75,2.78l0.99,0.99l-0.99,0.99V2.78zM17.75,9.23V7.27l0.99,0.99L17.75,9.23z"/>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_collapse.xml b/packages/SystemUI/res/drawable/ic_volume_collapse.xml
index 0f488a4..3853d12 100644
--- a/packages/SystemUI/res/drawable/ic_volume_collapse.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_collapse.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,51 +13,43 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="ic_volume_collapse"
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_caret_down"
+    android:width="24dp"
+    android:viewportWidth="24"
     android:height="24dp"
     android:viewportHeight="24"
-    android:viewportWidth="24"
-    android:width="24dp"
     android:tint="?android:attr/colorControlNormal" >
-
     <group
-        android:name="chevron_02"
-        android:rotation="90"
-        android:translateX="12"
-        android:translateY="9" >
+        android:name="caret___4" >
         <group
-            android:name="rectangle_2"
-            android:rotation="-45" >
+            android:name="right"
+            android:translateX="11.287"
+            android:translateY="8.701"
+            android:rotation="45" >
             <group
-                android:name="rectangle_2_pivot"
-                android:translateY="4" >
-                <group
-                    android:name="rectangle_path_2_position"
-                    android:translateY="-1" >
-                    <path
-                        android:name="rectangle_path_2"
-                        android:fillColor="#FFFFFFFF"
-                        android:pathData="M -1.0,-4.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
-                </group>
+                android:name="right_pivot"
+                android:translateX="4.242" >
+                <path
+                    android:name="rectangle_path_1"
+                    android:fillColor="#FFFFFFFF"
+                    android:pathData="M -3.242,-1.0 l 6.484,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,0.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l -6.484,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,0.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z" />
             </group>
         </group>
         <group
-            android:name="rectangle_1"
-            android:rotation="45" >
+            android:name="left"
+            android:translateX="12.699"
+            android:translateY="8.701"
+            android:rotation="-45" >
             <group
-                android:name="rectangle_1_pivot"
-                android:translateY="-4" >
-                <group
-                    android:name="rectangle_path_1_position"
-                    android:translateY="1" >
-                    <path
-                        android:name="rectangle_path_1"
-                        android:fillColor="#FFFFFFFF"
-                        android:pathData="M -1.0,-4.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
-                </group>
+                android:name="left_pivot"
+                android:translateX="-4.242" >
+                <path
+                    android:name="rectangle_path_2"
+                    android:fillColor="#FFFFFFFF"
+                    android:pathData="M -3.242,-1.0 l 6.484,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,0.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l -6.484,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,0.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z" />
             </group>
         </group>
     </group>
-
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_collapse_animation.xml b/packages/SystemUI/res/drawable/ic_volume_collapse_animation.xml
index 5c482bc..18c6307 100644
--- a/packages/SystemUI/res/drawable/ic_volume_collapse_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_collapse_animation.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,17 +13,13 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/ic_volume_collapse" >
-
     <target
-        android:name="chevron_02"
-        android:animation="@anim/ic_volume_collapse_chevron_02_animation" />
+        android:name="right"
+        android:animation="@anim/ic_caret_down_right_animation" />
     <target
-        android:name="rectangle_2"
-        android:animation="@anim/ic_volume_collapse_rectangle_2_animation" />
-    <target
-        android:name="rectangle_1"
-        android:animation="@anim/ic_volume_collapse_rectangle_1_animation" />
-
-</animated-vector>
\ No newline at end of file
+        android:name="left"
+        android:animation="@anim/ic_caret_down_left_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_expand.xml b/packages/SystemUI/res/drawable/ic_volume_expand.xml
index 70ff1f3..79ff808 100644
--- a/packages/SystemUI/res/drawable/ic_volume_expand.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_expand.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,51 +13,43 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="ic_volume_expand"
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_caret_up"
+    android:width="24dp"
+    android:viewportWidth="24"
     android:height="24dp"
     android:viewportHeight="24"
-    android:viewportWidth="24"
-    android:width="24dp"
     android:tint="?android:attr/colorControlNormal" >
-
     <group
-        android:name="chevron_01"
-        android:rotation="90"
-        android:translateX="12"
-        android:translateY="15" >
+        android:name="caret___4" >
         <group
-            android:name="rectangle_3"
-            android:rotation="45" >
+            android:name="right"
+            android:translateX="11.287"
+            android:translateY="15.287"
+            android:rotation="-45" >
             <group
-                android:name="rectangle_2_pivot_0"
-                android:translateY="4" >
-                <group
-                    android:name="rectangle_path_3_position"
-                    android:translateY="-1" >
-                    <path
-                        android:name="rectangle_path_3"
-                        android:fillColor="#FFFFFFFF"
-                        android:pathData="M -1.0,-4.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
-                </group>
+                android:name="right_pivot"
+                android:translateX="4.242" >
+                <path
+                    android:name="rectangle_path_1"
+                    android:fillColor="#FFFFFFFF"
+                    android:pathData="M -3.242,-1.0 l 6.484,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,0.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l -6.484,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,0.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z" />
             </group>
         </group>
         <group
-            android:name="rectangle_4"
-            android:rotation="-45" >
+            android:name="left"
+            android:translateX="12.699"
+            android:translateY="15.287"
+            android:rotation="45" >
             <group
-                android:name="rectangle_1_pivot_0"
-                android:translateY="-4" >
-                <group
-                    android:name="rectangle_path_4_position"
-                    android:translateY="1" >
-                    <path
-                        android:name="rectangle_path_4"
-                        android:fillColor="#FFFFFFFF"
-                        android:pathData="M -1.0,-4.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
-                </group>
+                android:name="left_pivot"
+                android:translateX="-4.242" >
+                <path
+                    android:name="rectangle_path_2"
+                    android:fillColor="#FFFFFFFF"
+                    android:pathData="M -3.242,-1.0 l 6.484,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,0.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l -6.484,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,0.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z" />
             </group>
         </group>
     </group>
-
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_expand_animation.xml b/packages/SystemUI/res/drawable/ic_volume_expand_animation.xml
index ae2d7e4..abd6678 100644
--- a/packages/SystemUI/res/drawable/ic_volume_expand_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_expand_animation.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,17 +13,13 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/ic_volume_expand" >
-
     <target
-        android:name="chevron_01"
-        android:animation="@anim/ic_volume_expand_chevron_01_animation" />
+        android:name="right"
+        android:animation="@anim/ic_caret_up_right_animation" />
     <target
-        android:name="rectangle_3"
-        android:animation="@anim/ic_volume_expand_rectangle_3_animation" />
-    <target
-        android:name="rectangle_4"
-        android:animation="@anim/ic_volume_expand_rectangle_4_animation" />
-
-</animated-vector>
\ No newline at end of file
+        android:name="left"
+        android:animation="@anim/ic_caret_up_left_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_media.xml b/packages/SystemUI/res/drawable/ic_volume_media.xml
index d689207..53c0740 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -22,6 +22,6 @@
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M12.0,3.0l0.0,9.28c-0.47,-0.17 -0.97,-0.28 -1.5,-0.28C8.01,12.0 6.0,14.01 6.0,16.5S8.01,21.0 10.5,21.0c2.31,0.0 4.2,-1.75 4.45,-4.0L15.0,17.0L15.0,6.0l4.0,0.0L19.0,3.0l-7.0,0.0z" />
+        android:pathData="M18,3h-5c-0.55,0 -1,0.45 -1,1v8.3a3.88,3.88 0,0 0,-2.9 -0.04c-1.79,0.67 -3.11,2.35 -3.1,4.26A4.483,4.483 0,0 0,10.5 21c2.5,0 4.5,-2.3 4.5,-4.5V6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1z"/>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_media_bt.xml b/packages/SystemUI/res/drawable/ic_volume_media_bt.xml
index 9b7b2da..60d0184 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media_bt.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media_bt.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -22,9 +22,6 @@
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M17.0,3.0l-7.0,0.0l0.0,9.3C9.5,12.1 9.0,12.0 8.5,12.0C6.0,12.0 4.0,14.0 4.0,16.5S6.0,21.0 8.5,21.0s4.5,-2.3 4.5,-4.5C13.0,14.7 13.0,6.0 13.0,6.0l4.0,0.0L17.0,3.0z"/>
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M23.4,9.9L20.5,7.0L20.0,7.0l0.0,3.8l-2.3,-2.3L17.0,9.2l2.8,2.8L17.0,14.8l0.7,0.7l2.3,-2.3L20.0,17.0l0.5,0.0l2.8,-2.8L21.2,12.0L23.4,9.9zM21.0,8.9l0.9,0.9l-0.9,1.0L21.0,8.9zM21.9,14.2L21.0,15.1l0.0,-1.9L21.9,14.2z"/>
+        android:pathData="M16,3h-5c-0.55,0 -1,0.45 -1,1v8.3c-0.93,-0.39 -1.96,-0.4 -2.9,-0.04c-1.79,0.67 -3.11,2.35 -3.1,4.26C4,19 6.01,21 8.49,21c0,0 0.01,0 0.01,0c2.5,0 4.5,-2.3 4.5,-4.5V6h3c0.55,0 1,-0.45 1,-1V4C17,3.45 16.55,3 16,3zM20.97,12l1.88,-1.87c0.21,-0.21 0.21,-0.54 0,-0.74L20.6,7.16l-0.01,-0.01c-0.21,-0.2 -0.53,-0.2 -0.73,0.01c-0.09,0.1 -0.15,0.23 -0.15,0.36v3.23l-2.03,-2.03c-0.21,-0.21 -0.53,-0.21 -0.74,0c-0.21,0.21 -0.21,0.53 0,0.74L19.49,12l-2.55,2.55c-0.21,0.21 -0.21,0.53 0,0.74c0.21,0.21 0.53,0.21 0.74,0l2.03,-2.03v3.23c0,0.29 0.24,0.52 0.52,0.52c0.13,0 0.26,-0.05 0.35,-0.15l0.02,-0.02l2.23,-2.23c0.21,-0.21 0.21,-0.54 0,-0.74L20.97,12zM20.75,10.75V8.78l0.99,0.99L20.75,10.75zM20.75,15.23v-1.96l0.99,0.99C21.73,14.25 20.75,15.23 20.75,15.23z"/>
 
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml b/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml
index 17ac01d..49fcfc4 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -22,12 +22,12 @@
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M13.0,6.0l4.0,0.0L17.0,3.0l-7.0,0.0l0.0,5.6l3.0,3.0C13.0,8.8 13.0,6.0 13.0,6.0z"/>
+        android:pathData="M13,6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1h-5c-0.55,0 -1,0.45 -1,1v4.6l3,3V6z"/>
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M2.1,5.7L8.4,12.0C6.0,12.1 4.0,14.0 4.0,16.5S6.0,21.0 8.5,21.0c2.7,0.0 4.5,-2.3 4.5,-4.3l0.0,-0.1l3.9,3.9l1.3,-1.3L3.4,4.5L2.1,5.7z"/>
+        android:pathData="M4,5.1C3.67,4.76 3.12,4.75 2.78,5.08C2.41,5.42 2.4,6 2.75,6.35L8.4,12C6,12.1 4,14 4,16.5c0,2.51 2.33,4.67 4.84,4.48C11.35,20.81 13,18.62 13,16.7v-0.1l3.27,3.27c0.35,0.35 0.91,0.35 1.25,0l0.05,-0.05c0.35,-0.35 0.35,-0.91 0,-1.25L4,5.1z"/>
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M23.4,9.9L20.5,7.0L20.0,7.0l0.0,3.8l-2.3,-2.3L17.0,9.2l2.8,2.8L17.0,14.8l0.7,0.7l2.3,-2.3L20.0,17.0l0.5,0.0l2.8,-2.8L21.2,12.0L23.4,9.9zM21.0,8.9l0.9,0.9l-0.9,1.0L21.0,8.9zM21.9,14.2L21.0,15.1l0.0,-1.9L21.9,14.2z"/>
+        android:pathData="M20.97,12l1.88,-1.87c0.21,-0.21 0.21,-0.54 0,-0.74L20.6,7.16l-0.01,-0.01c-0.21,-0.2 -0.53,-0.2 -0.73,0.01c-0.09,0.1 -0.15,0.23 -0.15,0.36v3.23l-2.03,-2.03c-0.21,-0.21 -0.53,-0.21 -0.74,0c-0.21,0.21 -0.21,0.53 0,0.74L19.49,12l-2.55,2.55c-0.21,0.21 -0.21,0.53 0,0.74c0.21,0.21 0.53,0.21 0.74,0l2.03,-2.03v3.23c0,0.29 0.24,0.52 0.52,0.52c0.13,0 0.26,-0.05 0.35,-0.15l2.25,-2.25c0.21,-0.21 0.21,-0.54 0,-0.74L20.97,12zM20.75,8.78l0.99,0.99l-0.99,0.98V8.78zM20.75,15.23v-1.96l0.99,0.99C21.73,14.25 20.75,15.23 20.75,15.23z"/>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_media_mute.xml b/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
index 267d09d..ebb86e8 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -22,9 +22,6 @@
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M15.0,6.0l4.0,0.0L19.0,3.0l-7.0,0.0l0.0,5.6l3.0,3.0C15.0,8.8 15.0,6.0 15.0,6.0z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M4.8,3.9L3.5,5.1l6.9,6.9C8.0,12.1 6.0,14.0 6.0,16.5C6.0,19.0 8.0,21.0 10.5,21.0c2.7,0.0 4.5,-2.3 4.5,-4.3c0.0,0.0 0.0,-0.1 0.0,-0.1l4.0,4.0l1.3,-1.3L4.8,3.9z" />
+        android:pathData="M15,6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1h-5c-0.55,0 -1,0.45 -1,1v4.6l3,3V6zM4.18,4.48c-0.37,0.34 -0.38,0.92 -0.03,1.27L10.4,12C8,12.1 6,14 6,16.5c0,2.51 2.33,4.67 4.84,4.48 2.51,-0.17 4.16,-2.36 4.16,-4.28v-0.1l3.37,3.37c0.35,0.35 0.91,0.35 1.25,0l0.05,-0.05c0.35,-0.35 0.35,-0.91 0,-1.25L5.4,4.5a0.866,0.866 0,0 0,-1.22 -0.02z"/>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer.xml b/packages/SystemUI/res/drawable/ic_volume_ringer.xml
index 18af711..f258856 100644
--- a/packages/SystemUI/res/drawable/ic_volume_ringer.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_ringer.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,13 +15,17 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24.0"
-    android:viewportWidth="24.0"
+    android:viewportHeight="23.4"
+    android:viewportWidth="23.4"
     android:width="24dp"
     android:tint="?android:attr/colorControlNormal" >
 
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,16.0l0.0,-5.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0L18.0,16.0z" />
+    <group
+        android:translateX="-0.78"
+        android:translateY="-0.5" >
+        <path
+            android:fillColor="#FFFFFF"
+            android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C7.63,5.36 6,7.92 6,11v5l-2.15,2.15c-0.19,0.2 -0.19,0.51 0.01,0.71C3.95,18.95 4.07,19 4.2,19h15.6c0.45,0 0.67,-0.54 0.35,-0.85L18,16z"/>
+    </group>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml b/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml
index bc926c3..106d899 100644
--- a/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,13 +15,23 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0"
+    android:viewportHeight="23.4"
+    android:viewportWidth="23.3"
     android:width="24dp"
     android:tint="?android:attr/colorControlNormal" >
 
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M23.000000,44.000000c2.200000,0.000000 4.000000,-1.800000 4.000000,-4.000000l-8.000000,0.000000C19.000000,42.200001 20.799999,44.000000 23.000000,44.000000zM36.000000,21.000000c0.000000,-6.100000 -4.300000,-11.300000 -10.000000,-12.600000L26.000000,7.000000c0.000000,-1.700000 -1.300000,-3.000000 -3.000000,-3.000000c-1.700000,0.000000 -3.000000,1.300000 -3.000000,3.000000l0.000000,1.400000c-1.000000,0.200000 -2.000000,0.600000 -2.900000,1.100000L36.000000,28.400000L36.000000,21.000000zM35.500000,38.000000l4.000000,4.000000l2.500000,-2.500000L8.500000,6.000000L6.000000,8.500000l5.800000,5.800000C10.700000,16.299999 10.000000,18.600000 10.000000,21.000000l0.000000,11.000000l-4.000000,4.000000l0.000000,2.000000L35.500000,38.000000z" />
+    <group
+        android:translateX="-0.85"
+        android:translateY="-0.5" >
+        <path
+            android:fillColor="#FF0"
+            android:pathData="M20.73,19.46l-0.6,-0.6c0,0 0,0 0,0L5.54,4.26c-0.35,-0.35 -0.92,-0.35 -1.27,0c-0.35,0.35 -0.35,0.92 0,1.27l2.4,2.4C6.25,8.85 6,9.88 6,11v5l-2.15,2.15c-0.19,0.2 -0.19,0.51 0.01,0.71C3.95,18.95 4.07,19 4.2,19h13.53l1.73,1.73c0.35,0.35 0.92,0.35 1.27,0C21.09,20.38 21.09,19.81 20.73,19.46z"/>
+        <path
+            android:fillColor="#FF0"
+            android:pathData="M18,11c0,-3.07 -1.64,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C9.87,4.83 9.31,5.08 8.8,5.4l9.2,9.2V11z"/>
+        <path
+            android:fillColor="#FF0"
+            android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/>
+    </group>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
index ffbffad..9db8511 100644
--- a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -22,6 +22,6 @@
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M0.0,15.0l2.0,0.0L2.0,9.0L0.0,9.0L0.0,15.0zM3.0,17.0l2.0,0.0L5.0,7.0L3.0,7.0L3.0,17.0zM22.0,9.0l0.0,6.0l2.0,0.0L24.0,9.0L22.0,9.0zM19.0,17.0l2.0,0.0L21.0,7.0l-2.0,0.0L19.0,17.0zM16.5,3.0l-9.0,0.0C6.7,3.0 6.0,3.7 6.0,4.5l0.0,15.0C6.0,20.3 6.7,21.0 7.5,21.0l9.0,0.0c0.8,0.0 1.5,-0.7 1.5,-1.5l0.0,-15.0C18.0,3.7 17.3,3.0 16.5,3.0zM16.0,19.0L8.0,19.0L8.0,5.0l8.0,0.0L16.0,19.0z" />
+        android:pathData="M1,15c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v4c0,0.55 0.45,1 1,1zM4,17c0.55,0 1,-0.45 1,-1L5,8c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v8c0,0.55 0.45,1 1,1zM22,10v4c0,0.55 0.45,1 1,1s1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1zM20,17c0.55,0 1,-0.45 1,-1L21,8c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v8c0,0.55 0.45,1 1,1zM16.5,3h-9C6.67,3 6,3.67 6,4.5v15c0,0.83 0.67,1.5 1.5,1.5h9c0.83,0 1.5,-0.67 1.5,-1.5v-15c0,-0.83 -0.67,-1.5 -1.5,-1.5zM16,19L8,19L8,5h8v14z"/>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_off.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_off.xml
index 81da26d..8d382a3 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_off.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_off.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2015 The Android Open Source Project
+  ~ Copyright (C) 2017 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@
                 <path
                     android:name="ridge_5_path"
                     android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -44,7 +44,7 @@
                 <path
                     android:name="ridge_7_path"
                     android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -54,7 +54,7 @@
                 <path
                     android:name="ridge_6_path"
                     android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -64,7 +64,7 @@
                 <path
                     android:name="ridge_2_path"
                     android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -76,7 +76,7 @@
                 <path
                     android:name="ridge_1_path"
                     android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_on.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_on.xml
index 8b517b6..4fe160d 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_on.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_on.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2015 The Android Open Source Project
+  ~ Copyright (C) 2017 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@
                 <path
                     android:name="ridge_5_path"
                     android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -45,7 +45,7 @@
                 <path
                     android:name="ridge_7_path"
                     android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -56,7 +56,7 @@
                 <path
                     android:name="ridge_6_path"
                     android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -67,7 +67,7 @@
                 <path
                     android:name="ridge_2_path"
                     android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -80,7 +80,7 @@
                 <path
                     android:name="ridge_1_path"
                     android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp.xml
index 3af2f7f..832716a 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2015 The Android Open Source Project
+  ~ Copyright (C) 2017 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -16,26 +16,28 @@
   -->
 <vector
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="lockscreen_fingerprint_error_state_to_fp"
+    android:name="ic_fingerprint_tofp"
     android:width="32dp"
-    android:viewportWidth="32"
+    android:viewportWidth="24"
     android:height="32dp"
-    android:viewportHeight="32" >
+    android:viewportHeight="24" >
     <group
-        android:name="white_fingerprint_ridges"
-        android:translateX="16.125"
-        android:translateY="19.75"
-        android:rotation="200.66753" >
+        android:name="fingerprintwhite"
+        android:translateX="12"
+        android:translateY="12.4"
+        android:scaleX="0.738"
+        android:scaleY="0.738"
+        android:rotation="180" >
         <group
-            android:name="white_fingerprint_ridges_pivot"
-            android:translateX="33.2085"
-            android:translateY="30.91685" >
+            android:name="fingerprintwhite_pivot"
+            android:translateX="33"
+            android:translateY="34" >
             <group
                 android:name="ridge_5" >
                 <path
                     android:name="ridge_5_path"
                     android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -46,18 +48,18 @@
                 <path
                     android:name="ridge_7_path"
                     android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
-                    android:trimPathStart="1" />
+                    android:trimPathEnd="0" />
             </group>
             <group
                 android:name="ridge_3" >
                 <path
                     android:name="ridge_6_path"
                     android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -68,7 +70,7 @@
                 <path
                     android:name="ridge_2_path"
                     android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -81,7 +83,7 @@
                 <path
                     android:name="ridge_1_path"
                     android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -90,37 +92,39 @@
         </group>
     </group>
     <group
-        android:name="exclamation"
-        android:translateX="16"
-        android:translateY="16" >
+        android:name="errorcircle"
+        android:translateX="12"
+        android:translateY="12"
+        android:rotation="10" >
         <group
-            android:name="group_2" >
+            android:name="circle" >
             <path
-                android:name="path_2"
-                android:pathData="M 1.35900878906,6.76104736328 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-2.69995117188 0.0,-2.69995117188 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,2.69995117188 0.0,2.69995117188 Z"
-                android:fillColor="?android:attr/colorError" />
-            <path
-                android:name="path_1"
-                android:pathData="M 1.35363769531,1.36633300781 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-8.09997558594 0.0,-8.09997558594 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,8.09997558594 0.0,8.09997558594 Z"
-                android:fillColor="?android:attr/colorError" />
+                android:name="circlepath"
+                android:strokeColor="?android:attr/colorError"
+                android:strokeWidth="2"
+                android:strokeLineCap="round"
+                android:pathData="M 0.0,-9.0 c 4.9705627482,0.0 9.0,4.0294372518 9.0,9.0 c 0.0,4.9705627482 -4.0294372518,9.0 -9.0,9.0 c -4.9705627482,0.0 -9.0,-4.0294372518 -9.0,-9.0 c 0.0,-4.9705627482 4.0294372518,-9.0 9.0,-9.0 Z" />
         </group>
     </group>
     <group
-        android:name="circle_outline"
-        android:translateX="16"
-        android:translateY="16" >
+        android:name="errorexclamation"
+        android:translateX="12"
+        android:translateY="12" >
         <group
-            android:name="group_1"
-            android:scaleX="1.12734"
-            android:scaleY="1.12734"
-            android:rotation="430" >
+            android:name="exclamationbottom"
+            android:translateY="4" >
             <path
-                android:name="path_3"
-                android:pathData="M 0.0101470947266,10.8087768555 c -5.96701049805,0.0 -10.8000183105,-4.8330078125 -10.8000183105,-10.8000488281 c 0.0,-5.96691894531 4.8330078125,-10.7999267578 10.8000183105,-10.7999267578 c 5.96697998047,0.0 10.799987793,4.8330078125 10.799987793,10.7999267578 c 0.0,5.96704101562 -4.8330078125,10.8000488281 -10.799987793,10.8000488281 Z"
-                android:strokeColor="?android:attr/colorError"
-                android:strokeWidth="2"
-                android:trimPathStart="0"
-                android:trimPathEnd="1" />
+                android:name="bottompath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z" />
+        </group>
+        <group
+            android:name="exclamationtop"
+            android:translateY="-2" >
+            <path
+                android:name="toppath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z" />
         </group>
     </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp_animation.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp_animation.xml
index 0351524..2f33306 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp_animation.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp_animation.xml
@@ -1,53 +1,59 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
+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.
+-->
 <animated-vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/lockscreen_fingerprint_error_state_to_fp" >
     <target
-        android:name="white_fingerprint_ridges"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_white_fingerprint_ridges_animation" />
+        android:name="fingerprintwhite"
+        android:animation="@anim/ic_fingerprint_tofp_fingerprintwhite_animation" />
     <target
         android:name="ridge_5_path"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_ridge_5_path_animation" />
+        android:animation="@anim/ic_fingerprint_tofp_ridge_5_path_animation" />
     <target
         android:name="ridge_7_path"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_ridge_7_path_animation" />
+        android:animation="@anim/ic_fingerprint_tofp_ridge_7_path_animation" />
     <target
         android:name="ridge_6_path"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_ridge_6_path_animation" />
+        android:animation="@anim/ic_fingerprint_tofp_ridge_6_path_animation" />
     <target
         android:name="ridge_2_path"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_ridge_2_path_animation" />
+        android:animation="@anim/ic_fingerprint_tofp_ridge_2_path_animation" />
     <target
         android:name="ridge_1_path"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_ridge_1_path_animation" />
+        android:animation="@anim/ic_fingerprint_tofp_ridge_1_path_animation" />
     <target
-        android:name="group_2"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_group_2_animation" />
+        android:name="errorcircle"
+        android:animation="@anim/ic_fingerprint_tofp_errorcircle_animation" />
     <target
-        android:name="path_2"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_path_2_animation" />
+        android:name="circlepath"
+        android:animation="@anim/ic_fingerprint_tofp_circlepath_animation" />
     <target
-        android:name="path_1"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_path_1_animation" />
+        android:name="errorexclamation"
+        android:animation="@anim/ic_fingerprint_tofp_errorexclamation_animation" />
     <target
-        android:name="group_1"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_group_1_animation" />
+        android:name="exclamationbottom"
+        android:animation="@anim/ic_fingerprint_tofp_exclamationbottom_animation" />
     <target
-        android:name="path_3"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_path_3_animation" />
+        android:name="bottompath"
+        android:animation="@anim/ic_fingerprint_tofp_bottompath_animation" />
+    <target
+        android:name="exclamationtop"
+        android:animation="@anim/ic_fingerprint_tofp_exclamationtop_animation" />
+    <target
+        android:name="toppath"
+        android:animation="@anim/ic_fingerprint_tofp_toppath_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state.xml
index a577afc..7cc2e5c 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state.xml
@@ -1,40 +1,42 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
+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:name="lockscreen_fingerprint_fp_to_error_state"
+    android:name="ic_fingerprint_toerror"
     android:width="32dp"
-    android:viewportWidth="32"
+    android:viewportWidth="24"
     android:height="32dp"
-    android:viewportHeight="32" >
+    android:viewportHeight="24" >
     <group
-        android:name="white_fingerprint_ridges"
-        android:translateX="16.125"
-        android:translateY="19.75" >
+        android:name="fingerprintwhite"
+        android:translateX="12"
+        android:translateY="12.4"
+        android:scaleX="0.738"
+        android:scaleY="0.738" >
         <group
-            android:name="white_fingerprint_ridges_pivot"
-            android:translateX="33.2085"
-            android:translateY="30.91685" >
+            android:name="fingerprintwhite_pivot"
+            android:translateX="33"
+            android:translateY="34" >
             <group
                 android:name="ridge_5" >
                 <path
                     android:name="ridge_5_path"
                     android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -44,7 +46,7 @@
                 <path
                     android:name="ridge_7_path"
                     android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -54,7 +56,7 @@
                 <path
                     android:name="ridge_6_path"
                     android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -64,7 +66,7 @@
                 <path
                     android:name="ridge_2_path"
                     android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -76,7 +78,7 @@
                 <path
                     android:name="ridge_1_path"
                     android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -84,13 +86,15 @@
         </group>
     </group>
     <group
-        android:name="fingerprint_ridges"
-        android:translateX="16.125"
-        android:translateY="19.75" >
+        android:name="fingerprinterror"
+        android:translateX="12"
+        android:translateY="12.4"
+        android:scaleX="0.738"
+        android:scaleY="0.738" >
         <group
-            android:name="fingerprint_ridges_pivot"
-            android:translateX="33.2085"
-            android:translateY="30.91685" >
+            android:name="fingerprinterror_pivot"
+            android:translateX="33"
+            android:translateY="34" >
             <group
                 android:name="ridge_6" >
                 <path
@@ -146,39 +150,40 @@
         </group>
     </group>
     <group
-        android:name="exclamation"
-        android:translateX="16"
-        android:translateY="16" >
+        android:name="errorcircle"
+        android:translateX="12"
+        android:translateY="12"
+        android:rotation="190" >
         <group
-            android:name="group_2"
-            android:scaleX="0.63838"
-            android:scaleY="0.63838"
-            android:rotation="184" >
+            android:name="circle" >
             <path
-                android:name="path_2"
-                android:pathData="M -1.3705291748,4.06730651855 c 0.0,0.0 0.036376953125,-0.0102386474609 0.036376953125,-0.0102386474609 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 -0.0161437988281,0.00479125976562 -0.0161437988281,0.00479125976563 c 0.0,0.0 -0.0134124755859,0.00141906738281 -0.0134124755859,0.00141906738281 Z"
-                android:fillColor="?android:attr/colorError" />
-            <path
-                android:name="path_1"
-                android:pathData="M -1.3737487793,-6.77532958984 c 0.0,0.0 0.00604248046875,0.0166625976562 0.00604248046876,0.0166625976562 c 0.0,0.0 0.0213623046875,0.0250244140625 0.0213623046875,0.0250244140625 c 0.0,0.0 -0.00604248046875,-0.0166625976562 -0.00604248046876,-0.0166625976562 c 0.0,0.0 -0.0213623046875,-0.0250244140625 -0.0213623046875,-0.0250244140625 Z"
-                android:fillColor="?android:attr/colorError" />
+                android:name="circlepath"
+                android:strokeColor="?android:attr/colorError"
+                android:strokeWidth="2"
+                android:strokeLineCap="round"
+                android:trimPathStart="1"
+                android:pathData="M 0.0,-9.0 c 4.9705627482,0.0 9.0,4.0294372518 9.0,9.0 c 0.0,4.9705627482 -4.0294372518,9.0 -9.0,9.0 c -4.9705627482,0.0 -9.0,-4.0294372518 -9.0,-9.0 c 0.0,-4.9705627482 4.0294372518,-9.0 9.0,-9.0 Z" />
         </group>
     </group>
     <group
-        android:name="circle_outline"
-        android:translateX="16"
-        android:translateY="16" >
+        android:name="errorexclamation"
+        android:translateX="12"
+        android:translateY="12"
+        android:rotation="180" >
         <group
-            android:name="group_1"
-            android:scaleX="1.12734"
-            android:scaleY="1.12734"
-            android:rotation="231" >
+            android:name="exclamationbottom"
+            android:translateY="4" >
             <path
-                android:name="path_3"
-                android:pathData="M 0.0101470947266,10.8087768555 c -5.96701049805,0.0 -10.8000183105,-4.8330078125 -10.8000183105,-10.8000488281 c 0.0,-5.96691894531 4.8330078125,-10.7999267578 10.8000183105,-10.7999267578 c 5.96697998047,0.0 10.799987793,4.8330078125 10.799987793,10.7999267578 c 0.0,5.96704101562 -4.8330078125,10.8000488281 -10.799987793,10.8000488281 Z"
-                android:strokeColor="?android:attr/colorError"
-                android:strokeWidth="2"
-                android:trimPathStart="1" />
+                android:name="bottompath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+        </group>
+        <group
+            android:name="exclamationtop" >
+            <path
+                android:name="toppath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M -1.0,0.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
         </group>
     </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state_animation.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state_animation.xml
index f7b710f..38096a9 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state_animation.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state_animation.xml
@@ -1,71 +1,77 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
+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.
+-->
 <animated-vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/lockscreen_fingerprint_fp_to_error_state" >
     <target
-        android:name="white_fingerprint_ridges"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_white_fingerprint_ridges_animation" />
+        android:name="fingerprintwhite"
+        android:animation="@anim/ic_fingerprint_toerror_fingerprintwhite_animation" />
     <target
         android:name="ridge_5_path"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_5_path_animation" />
     <target
         android:name="ridge_7_path"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_7_path_animation" />
     <target
         android:name="ridge_6_path"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_6_path_animation" />
     <target
         android:name="ridge_2_path"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_2_path_animation" />
     <target
         android:name="ridge_1_path"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_1_path_animation" />
     <target
-        android:name="fingerprint_ridges"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_fingerprint_ridges_animation" />
+        android:name="fingerprinterror"
+        android:animation="@anim/ic_fingerprint_toerror_fingerprinterror_animation" />
     <target
         android:name="ridge_5_path_0"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_0_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_5_path_0_animation" />
     <target
         android:name="ridge_7_path_0"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_0_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_7_path_0_animation" />
     <target
         android:name="ridge_6_path_0"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_0_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_6_path_0_animation" />
     <target
         android:name="ridge_2_path_0"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_0_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_2_path_0_animation" />
     <target
         android:name="ridge_1_path_0"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_0_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_1_path_0_animation" />
     <target
-        android:name="group_2"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_group_2_animation" />
+        android:name="errorcircle"
+        android:animation="@anim/ic_fingerprint_toerror_errorcircle_animation" />
     <target
-        android:name="path_2"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_path_2_animation" />
+        android:name="circlepath"
+        android:animation="@anim/ic_fingerprint_toerror_circlepath_animation" />
     <target
-        android:name="path_1"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_path_1_animation" />
+        android:name="errorexclamation"
+        android:animation="@anim/ic_fingerprint_toerror_errorexclamation_animation" />
     <target
-        android:name="group_1"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_group_1_animation" />
+        android:name="exclamationbottom"
+        android:animation="@anim/ic_fingerprint_toerror_exclamationbottom_animation" />
     <target
-        android:name="path_3"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_path_3_animation" />
+        android:name="bottompath"
+        android:animation="@anim/ic_fingerprint_toerror_bottompath_animation" />
+    <target
+        android:name="exclamationtop"
+        android:animation="@anim/ic_fingerprint_toerror_exclamationtop_animation" />
+    <target
+        android:name="toppath"
+        android:animation="@anim/ic_fingerprint_toerror_toppath_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_background_primary.xml b/packages/SystemUI/res/drawable/qs_background_primary.xml
index 8ea9e06..03bba53 100644
--- a/packages/SystemUI/res/drawable/qs_background_primary.xml
+++ b/packages/SystemUI/res/drawable/qs_background_primary.xml
@@ -15,6 +15,6 @@
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android">
     <shape>
-        <solid android:color="?android:attr/colorPrimary"/>
+        <solid android:color="@color/qs_background_dark"/>
     </shape>
 </inset>
diff --git a/packages/SystemUI/res/drawable/recents_dismiss_dark.xml b/packages/SystemUI/res/drawable/recents_dismiss_dark.xml
index 951269b..b837ebe 100644
--- a/packages/SystemUI/res/drawable/recents_dismiss_dark.xml
+++ b/packages/SystemUI/res/drawable/recents_dismiss_dark.xml
@@ -14,11 +14,16 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48.0dp"
-        android:height="48.0dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:fillColor="@color/recents_task_bar_dark_icon_color"
-        android:pathData="M38.000000,12.800000l-2.799999,-2.800000 -11.200001,11.200001 -11.200000,-11.200001 -2.800000,2.800000 11.200001,11.200000 -11.200001,11.200001 2.800000,2.799999 11.200000,-11.200001 11.200001,11.200001 2.799999,-2.799999 -11.200001,-11.200001z"/>
+android:width="24dp"
+android:height="24dp"
+android:viewportWidth="24"
+android:viewportHeight="24">
+
+<path
+    android:fillColor="@color/recents_task_bar_dark_icon_color"
+    android:pathData="M18.3 5.71a.996 .996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996 .996 0 1 0 5.7
+7.11L10.59 12 5.7 16.89a.996 .996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996 .996 0
+1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38 .38 -1.02 0-1.4z" />
+<path
+    android:pathData="M0 0h24v24H0z" />
 </vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/recents_dismiss_light.xml b/packages/SystemUI/res/drawable/recents_dismiss_light.xml
index 1f44c1c..2b20814 100644
--- a/packages/SystemUI/res/drawable/recents_dismiss_light.xml
+++ b/packages/SystemUI/res/drawable/recents_dismiss_light.xml
@@ -14,11 +14,16 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48.0dp"
-        android:height="48.0dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:fillColor="@color/recents_task_bar_light_icon_color"
-        android:pathData="M38.000000,12.800000l-2.799999,-2.800000 -11.200001,11.200001 -11.200000,-11.200001 -2.800000,2.800000 11.200001,11.200000 -11.200001,11.200001 2.800000,2.799999 11.200000,-11.200001 11.200001,11.200001 2.799999,-2.799999 -11.200001,-11.200001z"/>
+android:width="24dp"
+android:height="24dp"
+android:viewportWidth="24"
+android:viewportHeight="24">
+
+<path
+    android:fillColor="@color/recents_task_bar_light_icon_color"
+    android:pathData="M18.3 5.71a.996 .996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996 .996 0 1 0 5.7
+7.11L10.59 12 5.7 16.89a.996 .996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996 .996 0
+1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38 .38 -1.02 0-1.4z" />
+<path
+    android:pathData="M0 0h24v24H0z" />
 </vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/rounded.xml b/packages/SystemUI/res/drawable/rounded.xml
new file mode 100644
index 0000000..ef7aea7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded.xml
@@ -0,0 +1,24 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES 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="8dp"
+    android:height="8dp"
+    android:viewportWidth="8"
+    android:viewportHeight="8">
+
+    <path
+        android:fillColor="#000000"
+        android:pathData="M8,0H0v8C0,3.6,3.6,0,8,0z" />
+
+</vector>
diff --git a/packages/SystemUI/res/drawable/rounded_bg.xml b/packages/SystemUI/res/drawable/rounded_bg.xml
new file mode 100644
index 0000000..c23a87f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_bg.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="?android:attr/colorPrimary" />
+    <corners
+        android:bottomLeftRadius="@dimen/corner_size"
+        android:topLeftRadius="@dimen/corner_size"
+        android:bottomRightRadius="0dp"
+        android:topRightRadius="0dp"
+        />
+</shape>
diff --git a/packages/SystemUI/res/drawable/rounded_bg_bottom.xml b/packages/SystemUI/res/drawable/rounded_bg_bottom.xml
new file mode 100644
index 0000000..b3bea63
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_bg_bottom.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="?android:attr/colorPrimaryDark" />
+    <corners
+        android:bottomLeftRadius="@dimen/corner_size"
+        android:topLeftRadius="0dp"
+        android:bottomRightRadius="0dp"
+        android:topRightRadius="0dp"
+        />
+</shape>
diff --git a/packages/SystemUI/res/drawable/rounded_bg_full.xml b/packages/SystemUI/res/drawable/rounded_bg_full.xml
new file mode 100644
index 0000000..a6f40fa
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_bg_full.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="?android:attr/colorPrimary" />
+    <corners
+        android:bottomLeftRadius="@dimen/corner_size"
+        android:topLeftRadius="@dimen/corner_size"
+        android:bottomRightRadius="@dimen/corner_size"
+        android:topRightRadius="@dimen/corner_size"
+        />
+</shape>
diff --git a/packages/SystemUI/res/drawable/rounded_full_bg_bottom.xml b/packages/SystemUI/res/drawable/rounded_full_bg_bottom.xml
new file mode 100644
index 0000000..c3e36f2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_full_bg_bottom.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="?android:attr/colorPrimaryDark" />
+    <corners
+        android:bottomLeftRadius="@dimen/corner_size"
+        android:topLeftRadius="0dp"
+        android:bottomRightRadius="@dimen/corner_size"
+        android:topRightRadius="0dp"
+        />
+</shape>
diff --git a/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml b/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml
index 433da5f..2655bcd 100644
--- a/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml
@@ -1,28 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2014 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17.25dp"
-        android:height="18dp"
-        android:viewportWidth="46.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M20.4,18.0"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M42.0,32.0l0.0,-4.0L26.0,18.0L26.0,7.0c0.0,-1.7 -1.3,-3.0 -3.0,-3.0c-1.7,0.0 -3.0,1.3 -3.0,3.0l0.0,11.0L4.0,28.0l0.0,4.0l16.0,-5.0l0.0,11.0l-4.0,3.0l0.0,3.0l7.0,-2.0l7.0,2.0l0.0,-3.0l-4.0,-3.0L26.0,27.0L42.0,32.0z"/>
+    android:width="17.25dp"
+    android:height="18dp"
+    android:viewportWidth="19.65"
+    android:viewportHeight="20.5">
+    <group
+        android:translateX="1.3"
+        android:translateY="1.7">
+        <path
+            android:pathData="M16.01,9.87l-6.24,-3.9v-4.7C9.77,0.57 9.21,0 8.5,0S7.23,0.57 7.23,1.28v4.7L0.99,9.88c-0.37,0.23 -0.6,0.64 -0.6,1.08v0.41c0,0.29 0.29,0.5 0.55,0.41l6.27,-1.97v4.7l-1.37,1.02c-0.21,0.16 -0.34,0.41 -0.34,0.68v0.57c0,0.15 0.12,0.23 0.27,0.2 1.67,-0.47 1.12,-0.31 2.73,-0.78 1.03,0.3 1.7,0.49 2.72,0.78 0.15,0.03 0.27,-0.06 0.27,-0.2v-0.57c0,-0.27 -0.13,-0.52 -0.34,-0.68l-1.37,-1.02v-4.7l6.27,1.97c0.28,0.09 0.55,-0.12 0.55,-0.41v-0.41c0.01,-0.45 -0.23,-0.87 -0.59,-1.09z"
+            android:fillColor="#FFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_alarm.xml b/packages/SystemUI/res/drawable/stat_sys_alarm.xml
index 48c2222..0e9319c 100644
--- a/packages/SystemUI/res/drawable/stat_sys_alarm.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_alarm.xml
@@ -1,29 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2014 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
     android:insetRight="2.5dp">
-    <vector xmlns:android="http://schemas.android.com/apk/res/android"
+    <vector
         android:width="17dp"
         android:height="17dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-
-        <path
-            android:fillColor="#ffffffff"
-            android:pathData="M22.0,5.7l-4.6,-3.9l-1.3,1.5l4.6,3.9L22.0,5.7zM7.9,3.4L6.6,1.9L2.0,5.7l1.3,1.5L7.9,3.4zM12.5,8.0L11.0,8.0l0.0,6.0l4.7,2.9l0.8,-1.2l-4.0,-2.4L12.5,8.0zM12.0,4.0c-5.0,0.0 -9.0,4.0 -9.0,9.0c0.0,5.0 4.0,9.0 9.0,9.0s9.0,-4.0 9.0,-9.0C21.0,8.0 17.0,4.0 12.0,4.0zM12.0,20.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.9 3.1,-7.0 7.0,-7.0c3.9,0.0 7.0,3.1 7.0,7.0C19.0,16.9 15.9,20.0 12.0,20.0z"/>
+        android:viewportWidth="19.3"
+        android:viewportHeight="19.3">
+        <group
+            android:translateX="1.2"
+            android:translateY="1.2">
+            <path
+                android:pathData="M0.97,3.97c-0.32,-0.33 -0.24,-0.81 0.08,-1.13L3.47,0.74C3.79,0.42 4.28,0.5 4.6,0.82s0.24,0.89 -0.08,1.13L2.1,4.05c-0.4,0.32 -0.89,0.24 -1.13,-0.08zM15.97,2.84l-2.5,-2.1c-0.32,-0.32 -0.8,-0.25 -1.13,0.08 -0.32,0.32 -0.24,0.81 0.08,1.13l2.5,2.1c0.33,0.3 0.81,0.24 1.13,-0.08 0.27,-0.31 0.25,-0.89 -0.08,-1.13zM15.73,9.21c0,4.03 -3.23,7.26 -7.26,7.26s-7.26,-3.23 -7.26,-7.26 3.23,-7.26 7.26,-7.26 7.26,3.23 7.26,7.26zM14.2,9.21c0,-3.15 -2.58,-5.73 -5.73,-5.73S2.74,6.06 2.74,9.21s2.58,5.73 5.73,5.73 5.73,-2.59 5.73,-5.73zM8.27,5.18c-0.33,0 -0.6,0.27 -0.6,0.6v4.23l3.34,2c0.27,0.17 0.62,0.08 0.79,-0.19s0.07,-0.64 -0.2,-0.8L8.87,9.41L8.87,5.78c0,-0.33 -0.27,-0.6 -0.6,-0.6z"
+                android:fillColor="#FFF"/>
+        </group>
     </vector>
-</inset>
\ No newline at end of file
+</inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_cast.xml b/packages/SystemUI/res/drawable/stat_sys_cast.xml
index 4a7cbb3..5228085 100644
--- a/packages/SystemUI/res/drawable/stat_sys_cast.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_cast.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -18,11 +18,11 @@
     android:insetRight="2.5dp">
     <vector android:width="17dp"
             android:height="17dp"
-            android:viewportWidth="48.0"
-            android:viewportHeight="48.0">
+            android:viewportWidth="17.0"
+            android:viewportHeight="17.0">
 
         <path
             android:fillColor="#FFFFFFFF"
-            android:pathData="M2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM38.0,14.0L10.0,14.0l0.0,3.3c7.9,2.6 14.2,8.8 16.7,16.7L38.0,34.0L38.0,14.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0zM42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0z"/>
+            android:pathData="M0.71,12.75v1.42c0,0.39 0.32,0.71 0.71,0.71h1.42C2.83,13.7 1.88,12.75 0.71,12.75zM0.69,10.67c-0.01,0.36 0.25,0.66 0.6,0.72c1.47,0.26 2.65,1.42 2.9,2.89c0.06,0.34 0.35,0.6 0.7,0.6c0.43,0 0.77,-0.38 0.71,-0.81c-0.34,-2.11 -2,-3.76 -4.11,-4.09C1.08,9.91 0.7,10.24 0.69,10.67zM13.46,4.96H3.54v1.15c2.81,0.91 5.02,3.12 5.93,5.93h3.99V4.96zM0.69,7.81C0.68,8.18 0.95,8.49 1.31,8.53c3.02,0.3 5.44,2.71 5.74,5.72c0.04,0.35 0.34,0.62 0.7,0.62c0.42,0 0.75,-0.36 0.71,-0.78c-0.37,-3.69 -3.3,-6.62 -6.99,-6.98C1.06,7.08 0.7,7.4 0.69,7.81zM14.88,2.12H2.12c-0.78,0 -1.42,0.64 -1.42,1.42v2.12h1.42V3.54h12.75v9.92H9.92v1.42h4.96c0.78,0 1.42,-0.64 1.42,-1.42V3.54C16.29,2.76 15.65,2.12 14.88,2.12z" />
     </vector>
 </inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml
index e2d3539..4dc0e4b 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml
@@ -1,25 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="17dp"
         android:height="17dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6z"/>
+        android:viewportWidth="17.0"
+        android:viewportHeight="17.0">
+    <group
+        android:translateY="0.5"
+        android:translateX="0.5" >
+        <path
+            android:pathData="M8.84,8l2.62,-2.62c0.29,-0.29 0.29,-0.75 0,-1.04L8.33,1.22L8.31,1.2c-0.3,-0.28 -0.76,-0.26 -1.03,0.04c-0.13,0.13 -0.2,0.31 -0.2,0.5v4.51L4.24,3.4c-0.29,-0.29 -0.74,-0.29 -1.03,0s-0.29,0.74 0,1.03L6.78,8l-3.56,3.56c-0.29,0.29 -0.29,0.74 0,1.03s0.74,0.29 1.03,0l2.83,-2.83v4.51c0,0.4 0.33,0.73 0.73,0.73c0.18,0 0.36,-0.07 0.5,-0.2l0.03,-0.03l3.12,-3.12c0.29,-0.29 0.29,-0.75 0,-1.04L8.84,8zM8.47,6.37V3.36l1.5,1.5L8.47,6.37zM8.47,12.63V9.62l1.5,1.5L8.47,12.63z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml
index 94c40ba..c8a4440 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml
@@ -1,25 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="17dp"
         android:height="17dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M14.0,24.0l-4.0,-4.0l-4.0,4.0l4.0,4.0L14.0,24.0zM35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6zM38.0,20.0l-4.0,4.0l4.0,4.0l4.0,-4.0L38.0,20.0z"/>
+        android:viewportWidth="18.0"
+        android:viewportHeight="18.0">
+    <group
+        android:translateY="0.5"
+        android:translateX="0.5" >
+        <path
+            android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
index 3cdd3e1..719a6ca 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17.0dp"
-        android:height="17.0dp"
-        android:viewportWidth="24.0"
+        android:width="10.5dp"
+        android:height="14.0dp"
+        android:viewportWidth="18.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml
index db18fad..62159b3 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17.0dp"
-        android:height="17.0dp"
-        android:viewportWidth="24.0"
+        android:width="11.08dp"
+        android:height="14.0dp"
+        android:viewportWidth="19.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_saver.xml b/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
index c36678d..fed7cae 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
@@ -1,34 +1,43 @@
+<?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.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
+    android:insetRight="2.5dp" >
     <vector
-        android:width="17.0dp"
-        android:height="17.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M12.0,19.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.5 2.6,-6.4 6.0,-6.9L11.0,2.0C5.9,2.5 2.0,6.8 2.0,12.0c0.0,5.5 4.5,10.0 10.0,10.0c3.3,0.0 6.2,-1.6 8.1,-4.1l-2.6,-1.5C16.2,18.0 14.2,19.0 12.0,19.0z"/>
-        <path
-            android:fillColor="#4DFFFFFF"
-            android:pathData="M13.0,2.0l0.0,3.0c3.4,0.5 6.0,3.4 6.0,6.9c0.0,0.9 -0.2,1.8 -0.5,2.5l2.6,1.5c0.6,-1.2 0.9,-2.6 0.9,-4.1C22.0,6.8 18.0,2.6 13.0,2.0z"/>
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M16.0,11.0l0.0,2.0 -3.0,0.0 0.0,3.0 -2.0,0.0 0.0,-3.0 -3.0,0.0 0.0,-2.0 3.0,0.0 0.0,-3.0 2.0,0.0 0.0,3.0z"/>
+        android:width="18dp"
+        android:height="18dp"
+        android:viewportWidth="19.0"
+        android:viewportHeight="19.0">
+        <group
+            android:translateX="1.0"
+            android:translateY="1.0">
+            <path
+                android:pathData="M11.5,8.5c0,0.41 -0.34,0.74 -0.74,0.74L9.24,9.24v1.5c0,0.41 -0.34,0.74 -0.74,0.74s-0.74,-0.34 -0.74,-0.74v-1.5h-1.5c-0.41,0 -0.74,-0.34 -0.74,-0.74s0.34,-0.74 0.74,-0.74h1.5v-1.5c0,-0.41 0.34,-0.74 0.74,-0.74s0.74,0.34 0.74,0.74v1.5h1.5c0.42,-0.01 0.76,0.33 0.76,0.74z"
+                android:fillColor="#FFF"/>
+            <path
+                android:pathData="M13.23,12.05l0.99,0.57c0.19,0.12 0.25,0.38 0.12,0.55A7.452,7.452 0,0 1,7.5 15.9c-3.29,-0.44 -5.96,-3.08 -6.41,-6.38 -0.57,-4.17 2.33,-7.8 6.23,-8.42 0.23,-0.04 0.44,0.15 0.44,0.37v1.15c0,0.18 -0.14,0.33 -0.31,0.37 -2.7,0.52 -4.71,2.96 -4.55,5.83 0.16,2.86 2.57,5.21 5.43,5.29 1.77,0.06 3.38,-0.72 4.44,-1.97 0.11,-0.14 0.31,-0.18 0.46,-0.09z"
+                android:fillColor="#FFF" />
+            <path
+                android:pathData="M14.11,8.5c0,0.62 -0.11,1.22 -0.29,1.78 -0.06,0.17 0.01,0.35 0.16,0.45l1,0.57c0.19,0.12 0.46,0.03 0.54,-0.18 0.3,-0.82 0.47,-1.7 0.47,-2.62 0,-3.73 -2.73,-6.82 -6.31,-7.39a0.377,0.377 0,0 0,-0.44 0.37v1.15c0,0.18 0.14,0.33 0.31,0.36 2.59,0.51 4.56,2.78 4.56,5.51z"
+                android:fillAlpha="0.3"
+                android:fillColor="#FFF" />
+
+        </group>
     </vector>
 </inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_dnd.xml b/packages/SystemUI/res/drawable/stat_sys_dnd.xml
index 3bf5e98..bd4cb0a 100644
--- a/packages/SystemUI/res/drawable/stat_sys_dnd.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_dnd.xml
@@ -1,28 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-    Copyright (C) 2015 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
+    android:insetRight="2.5dp" >
     <vector
-            android:width="17dp"
-            android:height="17dp"
-            android:viewportWidth="48.0"
-            android:viewportHeight="48.0">
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M24.0,4.0C12.95,4.0 4.0,12.95 4.0,24.0s8.95,20.0 20.0,20.0 20.0,-8.95 20.0,-20.0S35.05,4.0 24.0,4.0zm10.0,22.0L14.0,26.0l0.0,-4.0l20.0,0.0l0.0,4.0z"/>
+        android:width="17dp"
+        android:height="17dp"
+        android:viewportWidth="16.6"
+        android:viewportHeight="16.6">
+        <group
+            android:translateX="-0.2"
+            android:translateY="-0.2">
+            <path
+                android:pathData="M8.5,1.59c-3.81,0 -6.91,3.09 -6.91,6.91s3.09,6.91 6.91,6.91 6.91,-3.09 6.91,-6.91 -3.1,-6.91 -6.91,-6.91zM11.16,9.56L5.84,9.56c-0.59,0 -1.06,-0.48 -1.06,-1.06s0.48,-1.06 1.06,-1.06h5.31a1.06,1.06 0,0 1,0.01 2.12z"
+                android:fillColor="#FFF"/>
+        </group>
     </vector>
 </inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml b/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml
index 82e25ca..11a3bdd 100644
--- a/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml
@@ -1,31 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-    Copyright (C) 2015 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
+    android:insetRight="2.5dp" >
     <vector
-            android:width="17dp"
-            android:height="17dp"
-            android:viewportWidth="24.0"
-            android:viewportHeight="24.0">
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0s10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM12.0,20.5c-4.7,0.0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12.0,3.5s8.5,3.8 8.5,8.5S16.7,20.5 12.0,20.5z"/>
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M12.0,6.0c-3.3,0.0 -6.0,2.7 -6.0,6.0c0.0,3.3 2.7,6.0 6.0,6.0s6.0,-2.7 6.0,-6.0C18.0,8.7 15.4,6.0 12.0,6.0zM15.0,13.0L9.0,13.0l0.0,-2.0l6.0,0.0L15.0,13.0z"/>
+        android:width="16dp"
+        android:height="16dp"
+        android:viewportWidth="16.6"
+        android:viewportHeight="16.6">
+        <group
+            android:translateX="-0.2"
+            android:translateY="-0.2">
+            <path
+                android:pathData="M8.5,3.72c-2.62,0 -4.78,2.16 -4.78,4.78s2.16,4.78 4.78,4.78 4.78,-2.16 4.78,-4.78 -2.07,-4.78 -4.78,-4.78zM10.09,9.56L6.91,9.56c-0.59,0 -1.06,-0.48 -1.06,-1.06s0.48,-1.06 1.06,-1.06h3.19c0.59,0 1.06,0.48 1.06,1.06s-0.48,1.06 -1.07,1.06z"
+                android:fillColor="#FFF"/>
+            <path
+                android:pathData="M8.5,0.53C4.11,0.53 0.53,4.11 0.53,8.5s3.58,7.97 7.97,7.97 7.97,-3.58 7.97,-7.97S12.89,0.53 8.5,0.53zM8.5,15.28c-3.75,0 -6.78,-3.03 -6.78,-6.78S4.75,1.72 8.5,1.72s6.78,3.03 6.78,6.78 -3.03,6.78 -6.78,6.78z"
+                android:fillColor="#FFF"/>
+        </group>
     </vector>
 </inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_hotspot.xml b/packages/SystemUI/res/drawable/stat_sys_hotspot.xml
index 01e8888..4f52777 100644
--- a/packages/SystemUI/res/drawable/stat_sys_hotspot.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_hotspot.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -17,13 +17,16 @@
     android:insetLeft="2.5dp"
     android:insetRight="2.5dp">
     <vector
-        android:width="17.0dp"
-        android:height="17.0dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M24.000000,22.000000c-2.200000,0.000000 -4.000000,1.800000 -4.000000,4.000000c0.000000,2.200000 1.800000,4.000000 4.000000,4.000000c2.200000,0.000000 4.000000,-1.800000 4.000000,-4.000000C28.000000,23.799999 26.200001,22.000000 24.000000,22.000000zM36.000000,26.000000c0.000000,-6.600000 -5.400000,-12.000000 -12.000000,-12.000000c-6.600000,0.000000 -12.000000,5.400000 -12.000000,12.000000c0.000000,4.400000 2.400000,8.300000 6.000000,10.400000l2.000000,-3.500000c-2.400000,-1.400000 -4.000000,-3.900000 -4.000000,-6.900000c0.000000,-4.400000 3.600000,-8.000000 8.000000,-8.000000s8.000000,3.600000 8.000000,8.000000c0.000000,3.000000 -1.600000,5.500000 -4.000000,6.900000l2.000000,3.500000C33.599998,34.299999 36.000000,30.400000 36.000000,26.000000zM24.000000,6.000000C13.000000,6.000000 4.000000,15.000000 4.000000,26.000000c0.000000,7.400000 4.000000,13.800000 10.000000,17.299999l2.000000,-3.500000c-4.800000,-2.800000 -8.000000,-7.900000 -8.000000,-13.800000c0.000000,-8.800000 7.200000,-16.000000 16.000000,-16.000000s16.000000,7.200000 16.000000,16.000000c0.000000,5.900000 -3.200000,11.100000 -8.000000,13.800000l2.000000,3.500000c6.000000,-3.500000 10.000000,-9.900000 10.000000,-17.299999C44.000000,15.000000 35.000000,6.000000 24.000000,6.000000z"/>
+        android:width="18.0dp"
+        android:height="18.0dp"
+        android:viewportWidth="18.0"
+        android:viewportHeight="18.0">
+      <group
+          android:translateX="0.5"
+          android:translateY="0.5" >
+          <path
+              android:pathData="M8.5,7.79c-0.78,0 -1.42,0.64 -1.42,1.42c0,0.78 0.64,1.42 1.42,1.42s1.42,-0.64 1.42,-1.42C9.92,8.43 9.28,7.79 8.5,7.79zM12.75,9.21c0,-2.35 -1.9,-4.25 -4.25,-4.25c-0.18,0 -0.35,0.01 -0.53,0.03C6.11,5.22 4.58,6.7 4.3,8.55c-0.23,1.52 0.35,2.91 1.36,3.82C6,12.67 6.54,12.6 6.76,12.2c0.17,-0.3 0.1,-0.67 -0.16,-0.89c-0.78,-0.7 -1.12,-1.77 -0.86,-2.79C5.99,7.5 6.78,6.71 7.8,6.46C9.32,6.08 10.86,7 11.25,8.52c0.06,0.23 0.09,0.46 0.09,0.69c0,0.84 -0.36,1.58 -0.94,2.1c-0.25,0.23 -0.33,0.6 -0.16,0.9c0.22,0.38 0.74,0.49 1.06,0.2C12.22,11.6 12.75,10.43 12.75,9.21zM7.63,1.85C4.19,2.24 1.42,5.07 1.1,8.52c-0.26,2.61 0.88,5.15 2.99,6.7c0.36,0.26 0.86,0.15 1.09,-0.23c0.19,-0.32 0.1,-0.74 -0.19,-0.96c-1.7,-1.26 -2.71,-3.38 -2.35,-5.73c0.4,-2.6 2.57,-4.68 5.19,-4.97c3.59,-0.41 6.63,2.4 6.63,5.91c0,1.97 -0.96,3.7 -2.43,4.79c-0.3,0.22 -0.38,0.63 -0.19,0.96c0.22,0.39 0.73,0.49 1.09,0.23c1.9,-1.4 3.03,-3.62 3.03,-5.98C15.94,4.84 12.12,1.34 7.63,1.85z"
+              android:fillColor="#FFFFFFFF"/>
+      </group>
     </vector>
 </inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
index 370f89c..d73e2a4 100644
--- a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
@@ -22,19 +22,19 @@
     The asset contains a briefcase symbol of 15.26dp x 13.6dp in the center.
 -->
     <path
-        android:fillColor="@android:color/white"
+        android:fillColor="#ff000000"
         android:pathData="M15.0815,4.5903 L15.0815,3.43636 L13.9276,2.2 L9.14696,2.2 L7.99302,3.43636
 L7.99302,4.5903 L9.14696,4.5903 L9.14696,3.43636 L13.9276,3.43636
 L13.9276,4.5903 Z" />
     <path
-        android:fillColor="@android:color/white"
+        android:fillColor="#ff000000"
         android:pathData="M18.0488,4.5903 L5.02575,4.5903 C4.36635,4.5903,3.87181,5.08485,3.87181,5.74424
 L3.87181,9.28848 C3.87181,9.94788,4.36635,10.4424,5.02575,10.4424
 L9.72393,10.4424 L9.72393,9.28848 L13.2682,9.28848 L13.2682,10.4424
 L17.9664,10.4424 C18.6257,10.4424,19.1203,9.94788,19.1203,9.28848
 L19.1203,5.74424 C19.2027,5.08485,18.6257,4.5903,18.0488,4.5903 Z" />
     <path
-        android:fillColor="@android:color/white"
+        android:fillColor="#ff000000"
         android:pathData="M9.80635,12.8327 L9.80635,11.6788 L4.44878,11.6788 L4.44878,14.6461
 C4.44878,15.3055,4.94332,15.8,5.60272,15.8 L17.3894,15.8
 C18.0488,15.8,18.5433,15.3055,18.5433,14.6461 L18.5433,11.6788 L13.2682,11.6788
diff --git a/packages/SystemUI/res/drawable/stat_sys_no_sims.xml b/packages/SystemUI/res/drawable/stat_sys_no_sims.xml
index 2229c99..faea7d1 100644
--- a/packages/SystemUI/res/drawable/stat_sys_no_sims.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_no_sims.xml
@@ -1,25 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17dp"
-        android:height="17dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-
-    <path
-        android:fillColor="?attr/backgroundColor"
-        android:pathData="M19.0,5.0c0.0,-1.1 -0.9,-2.0 -2.0,-2.0l-7.0,0.0L7.7,5.3L19.0,16.7L19.0,5.0zM3.7,3.9L2.4,5.2L5.0,7.8L5.0,19.0c0.0,1.1 0.9,2.0 2.0,2.0l10.0,0.0c0.4,0.0 0.7,-0.1 1.0,-0.3l1.9,1.9l1.3,-1.3L3.7,3.9z"/>
+    android:width="17dp"
+    android:height="17dp"
+    android:viewportWidth="18.4"
+    android:viewportHeight="18.4">
+    <group
+        android:translateX="0.7"
+        android:translateY="1.0">
+        <path
+            android:pathData="M13.91,11.84L5.14,3.08l1.81,-1.81h5.41c0.85,0 1.54,0.69 1.54,1.54l0.01,9.03zM15.06,14.95L2.54,2.44c-0.28,-0.28 -0.71,-0.28 -0.99,0s-0.28,0.71 0,0.98l1.53,1.53v8.67c0,0.85 0.69,1.54 1.54,1.54h7.74c0.27,0 0.52,-0.07 0.74,-0.2l0.96,0.96c0.28,0.28 0.71,0.28 0.99,0 0.28,-0.26 0.28,-0.69 0.01,-0.97z"
+            android:fillColor="?attr/backgroundColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
index eb7b4fc..e525fec 100644
--- a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
@@ -1,28 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
-    android:insetLeft="3dp"
-    android:insetRight="3dp">
-    <vector android:width="18dp"
-            android:height="18dp"
-            android:viewportWidth="24.0"
-            android:viewportHeight="24.0">
-
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M0.0,15.0l2.0,0.0L2.0,9.0L0.0,9.0L0.0,15.0zM3.0,17.0l2.0,0.0L5.0,7.0L3.0,7.0L3.0,17.0zM22.0,9.0l0.0,6.0l2.0,0.0L24.0,9.0L22.0,9.0zM19.0,17.0l2.0,0.0L21.0,7.0l-2.0,0.0L19.0,17.0zM16.5,3.0l-9.0,0.0C6.7,3.0 6.0,3.7 6.0,4.5l0.0,15.0C6.0,20.3 6.7,21.0 7.5,21.0l9.0,0.0c0.8,0.0 1.5,-0.7 1.5,-1.5l0.0,-15.0C18.0,3.7 17.3,3.0 16.5,3.0zM16.0,19.0L8.0,19.0L8.0,5.0l8.0,0.0L16.0,19.0z"/>
+    android:insetLeft="2.5dp"
+    android:insetRight="2.5dp">
+    <vector
+        android:width="19dp"
+        android:height="17dp"
+        android:viewportWidth="21.0"
+        android:viewportHeight="19.0">
+        <group
+            android:translateX="1.0"
+            android:translateY="1.0">
+            <path
+                android:pathData="M13.28,0.53L5.84,0.53c-0.88,0 -1.59,0.71 -1.59,1.59v12.75c0,0.88 0.71,1.59 1.59,1.59h7.44c0.88,0 1.59,-0.71 1.59,-1.59L14.87,2.12c0.01,-0.88 -0.71,-1.59 -1.59,-1.59zM13.28,14.88L5.84,14.88L5.84,2.12h7.44v12.76zM2.66,13.81a0.52,0.52 0,0 1,-0.53 -0.53L2.13,3.72c0,-0.3 0.23,-0.53 0.53,-0.53 0.3,0 0.53,0.23 0.53,0.53v9.56c0,0.3 -0.24,0.53 -0.53,0.53zM0.53,11.69a0.52,0.52 0,0 1,-0.53 -0.53L0,5.84c0,-0.3 0.23,-0.53 0.53,-0.53 0.3,0 0.53,0.23 0.53,0.53v5.31c0,0.3 -0.23,0.54 -0.53,0.54zM16.47,13.81c0.3,0 0.53,-0.23 0.53,-0.53L17,3.72c0,-0.3 -0.23,-0.53 -0.53,-0.53 -0.3,0 -0.53,0.23 -0.53,0.53v9.56c0,0.3 0.23,0.53 0.53,0.53zM18.59,11.69c0.3,0 0.53,-0.23 0.53,-0.53L19.12,5.84c0,-0.3 -0.23,-0.53 -0.53,-0.53 -0.3,0 -0.53,0.23 -0.53,0.53v5.31c0,0.3 0.24,0.54 0.53,0.54z"
+                android:fillColor="#FFF"/>
+        </group>
     </vector>
-</inset>
\ No newline at end of file
+</inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml b/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml
index 7ca8c40..66f4fbb 100644
--- a/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml
@@ -1,24 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17.0dp"
-        android:height="17.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M12.700000,10.000000c-0.800000,-2.300000 -3.000000,-4.000000 -5.700000,-4.000000c-3.300000,0.000000 -6.000000,2.700000 -6.000000,6.000000s2.700000,6.000000 6.000000,6.000000c2.600000,0.000000 4.800000,-1.700000 5.700000,-4.000000L17.000000,14.000000l0.000000,4.000000l4.000000,0.000000l0.000000,-4.000000l2.000000,0.000000l0.000000,-4.000000L12.700000,10.000000zM7.000000,14.000000c-1.100000,0.000000 -2.000000,-0.900000 -2.000000,-2.000000c0.000000,-1.100000 0.900000,-2.000000 2.000000,-2.000000s2.000000,0.900000 2.000000,2.000000C9.000000,13.100000 8.100000,14.000000 7.000000,14.000000z"/>
+    android:width="17dp"
+    android:height="17dp"
+    android:viewportWidth="19.0"
+    android:viewportHeight="19.0">
+    <group
+        android:translateX="1.0"
+        android:translateY="1.0">
+        <path
+            android:pathData="M15.46,6.96H9a4.637,4.637 0,0 0,-4.37 -3.09C2.07,3.87 0,5.94 0,8.5s2.07,4.63 4.63,4.63c2.02,0 3.73,-1.29 4.37,-3.09h2.2v1.54a1.54,1.54 0,0 0,3.08 0v-1.54h1.16c0.87,0 1.56,-0.69 1.56,-1.54s-0.69,-1.54 -1.54,-1.54zM4.63,10.04a1.54,1.54 0,1 1,0.001 -3.081,1.54 1.54,0 0,1 -0.001,3.081z"
+            android:fillColor="#FFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0.xml
index 2de2e36..b3cd455 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -16,12 +16,16 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="18.41dp"
         android:height="18.41dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="?attr/backgroundColor"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.799999,-1.800001z"
-        android:fillColor="?attr/fillColor"/>
+        android:viewportWidth="21.2"
+        android:viewportHeight="21.2">
+      <group
+          android:translateX="0.5"
+          android:translateY="2.0">
+        <path
+            android:pathData="M18.79,9.79c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8l0,0c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21l0,0c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15l-1.21,-1.21l1.21,-1.21C19.1,10.64 19.1,10.13 18.79,9.79z"
+            android:fillColor="?attr/fillColor"/>
+        <path
+            android:pathData="M11.69,7.44h6.27L19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56c-1.6,-1.05 -5.04,-2.9 -9.62,-2.9c-4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44z"
+            android:fillColor="?attr/backgroundColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0_fully.xml
index 60f7eb6..6c0fad8 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0_fully.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0_fully.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,11 +14,15 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="17dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="?attr/backgroundColor"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    android:width="18.41dp"
+    android:height="17dp"
+    android:viewportWidth="21.66"
+    android:viewportHeight="20">
+    <group
+        android:translateX="0.74"
+        android:translateY="1.2">
+        <path
+            android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z"
+            android:fillColor="?attr/backgroundColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1.xml
index 144a7c1..2ebbaf2 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,17 +14,21 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="18.41dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,13.2c-0.1,0.0 -0.3,-0.1 -0.4,-0.1c-0.1,0.0 -0.3,0.0 -0.4,-0.1c-0.3,0.0 -0.6,-0.1 -0.9,-0.1c0.0,0.0 0.0,0.0 -0.1,0.0c0.0,0.0 0.0,0.0 0.0,0.0s0.0,0.0 0.0,0.0c0.0,0.0 0.0,0.0 -0.1,0.0c-0.3,0.0 -0.6,0.0 -0.9,0.1c-0.1,0.0 -0.3,0.0 -0.4,0.1c-0.2,0.0 -0.3,0.1 -0.5,0.1c-0.2,0.0 -0.3,0.1 -0.5,0.1c-0.1,0.0 -0.1,0.0 -0.2,0.1c-1.6,0.5 -2.7,1.3 -2.8,1.5l5.3,6.6l0.0,0.0l0.0,0.0l0.0,0.0l0.0,0.0l1.8,-2.2L13.700002,13.2z"
-        android:fillColor="?attr/fillColor"/>
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="?attr/backgroundColor"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.799999,-1.800001z"
-        android:fillColor="?attr/fillColor"/>
+    android:width="18.41dp"
+    android:height="18.41dp"
+    android:viewportWidth="21.7"
+    android:viewportHeight="21.7">
+    <group
+        android:translateY="2.2"
+        android:translateX="0.75">
+        <path
+            android:pathData="M11.69,7.44h6.27L19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56c-1.6,-1.05 -5.04,-2.9 -9.62,-2.9c-4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44z"
+            android:fillColor="?attr/backgroundColor" />
+        <path
+            android:pathData="M5.02,10.86l4.25,5.21c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V9.14c-0.51,-0.11 -1.05,-0.17 -1.59,-0.17C8.15,8.97 6.37,9.69 5.02,10.86z"
+            android:fillColor="?attr/fillColor" />
+        <path
+            android:pathData="M17.57,12.17l1.21,-1.21c0.32,-0.32 0.32,-0.83 0,-1.17c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15L17.57,12.17z"
+            android:fillColor="?attr/fillColor" />
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1_fully.xml
index 554350d..eaead9b 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1_fully.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1_fully.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="17dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="?attr/backgroundColor"
-        android:pathData="M13.100000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.500000,6.500000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000z"/>
-    <path
-        android:fillColor="?attr/fillColor"
-        android:pathData="M13.100000,22.000000l5.500000,-6.800000c-0.200000,-0.200000 -2.300000,-1.900000 -5.500000,-1.900000s-5.300000,1.800000 -5.500000,1.900000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000z"/>
+    android:width="18.41dp"
+    android:height="17dp"
+    android:viewportWidth="21.66"
+    android:viewportHeight="20.0">
+    <group
+        android:translateX="0.79"
+        android:translateY="1.2">
+        <path
+            android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z"
+            android:fillColor="?attr/backgroundColor"/>
+        <path
+            android:pathData="M10.1,8.97c-1.95,0 -3.72,0.72 -5.08,1.9l4.25,5.21c0.42,0.52 1.22,0.52 1.64,0l4.26,-5.22a7.702,7.702 0,0 0,-5.07 -1.89z"
+            android:fillColor="?attr/fillColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2.xml
index 6b7f712..809147c 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,17 +14,21 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="18.41dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l4.9,0.0c-1.0,-0.7 -3.4,-2.2 -6.7,-2.2c-4.1,0.0 -6.9,2.2 -7.2,2.5l7.2,9.0l0.0,0.0l0.0,0.0l1.8,-2.2L13.800001,12.2z"
-        android:fillColor="?attr/fillColor"/>
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="?attr/backgroundColor"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.800001,1.9 -1.800001,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
-        android:fillColor="?attr/fillColor"/>
+    android:width="18.41dp"
+    android:height="18.41dp"
+    android:viewportWidth="21.7"
+    android:viewportHeight="21.7">
+    <group
+        android:translateX="0.75"
+        android:translateY="2.2" >
+        <path
+            android:pathData="M11.69,7.44h6.27L19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56c-1.6,-1.05 -5.04,-2.9 -9.62,-2.9c-4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44z"
+            android:fillColor="?attr/backgroundColor"/>
+        <path
+            android:pathData="M10.09,6.44c-2.55,0 -4.88,0.93 -6.68,2.45l5.85,7.18c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44h2.84C13.18,6.8 11.68,6.44 10.09,6.44z"
+            android:fillColor="?attr/fillColor"/>
+        <path
+            android:pathData="M17.57,12.17l1.21,-1.21c0.32,-0.32 0.32,-0.83 0,-1.17c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15L17.57,12.17z"
+            android:fillColor="?attr/fillColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2_fully.xml
index 2c2465a..6d4fb77 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2_fully.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2_fully.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="17dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="?attr/backgroundColor"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
-    <path
-        android:fillColor="?attr/fillColor"
-        android:pathData="M13.000000,22.000000l7.600000,-9.400000C20.299999,12.400000 17.400000,10.000000 13.000000,10.000000s-7.300000,2.400000 -7.600000,2.700000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+android:width="18.41dp"
+android:height="17dp"
+android:viewportWidth="21.86"
+android:viewportHeight="20.19">
+    <group
+        android:translateX="0.85"
+        android:translateY="1.4" >
+        <path
+            android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z"
+            android:fillColor="?attr/backgroundColor" />
+        <path
+            android:pathData="M10.09,6.44c-2.55,0 -4.88,0.93 -6.68,2.45l5.85,7.18c0.42,0.52 1.22,0.52 1.64,0l5.86,-7.19a10.284,10.284 0,0 0,-6.67 -2.44z"
+            android:fillColor="?attr/fillColor" />
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3.xml
index d34b4de..4c479c0 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -16,15 +16,19 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="18.41dp"
         android:height="18.41dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0l1.0,-1.2C20.0,10.6 16.8,8.0 12.0,8.0s-8.0,2.6 -8.5,3.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="?attr/fillColor"/>
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="?attr/backgroundColor"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
-        android:fillColor="?attr/fillColor"/>
+        android:viewportWidth="21.7"
+        android:viewportHeight="21.7">
+    <group
+            android:translateX="0.75"
+            android:translateY="2.3" >
+        <path
+            android:pathData="M11.69,7.44h6.27L19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56c-1.6,-1.05 -5.04,-2.9 -9.62,-2.9c-4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44z"
+            android:fillColor="?attr/backgroundColor"/>
+        <path
+            android:pathData="M10.08,4.75c-2.96,0 -5.66,1.06 -7.74,2.82l6.93,8.5c0.21,0.26 0.51,0.39 0.82,0.39c0.22,0 0.44,-0.07 0.63,-0.2c0.07,-0.05 0.14,-0.11 0.2,-0.19l0.78,-0.96V7.44h5.98C15.6,5.77 12.96,4.75 10.08,4.75z"
+            android:fillColor="?attr/fillColor"/>
+        <path
+            android:pathData="M17.57,12.17l1.21,-1.21c0.32,-0.32 0.32,-0.83 0,-1.17c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15L17.57,12.17z"
+            android:fillColor="?attr/fillColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3_fully.xml
index 7d0f756..6c96300 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3_fully.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3_fully.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="17dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="?attr/backgroundColor"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
-    <path
-        android:fillColor="?attr/fillColor"
-        android:pathData="M13.000000,22.000000l9.200000,-11.400000c-0.400000,-0.300000 -3.900000,-3.200000 -9.200000,-3.200000s-8.900000,3.000000 -9.200000,3.200000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    android:width="18.41dp"
+    android:height="17dp"
+    android:viewportWidth="21.80"
+    android:viewportHeight="20.1">
+    <group
+        android:translateX="0.81"
+        android:translateY="1.29" >
+        <path
+            android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z"
+            android:fillColor="?attr/backgroundColor"/>
+        <path
+            android:pathData="M10.08,4.75c-2.96,0 -5.66,1.06 -7.74,2.82l6.93,8.5c0.21,0.26 0.51,0.39 0.82,0.39 0.23,0 0.46,-0.07 0.65,-0.22 -0.02,0.02 -0.04,0.03 -0.07,0.05 0.09,-0.06 0.17,-0.13 0.24,-0.22l6.93,-8.5c-2.09,-1.74 -4.8,-2.82 -7.76,-2.82z"
+            android:fillColor="?attr/fillColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4.xml
index 7d1bfe1..8fb7a7b 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,16 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="18.41dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="?attr/singleToneColor"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
-        android:fillColor="?attr/singleToneColor"/>
+    android:width="18.41dp"
+    android:height="18.41dp"
+    android:viewportWidth="21.95"
+    android:viewportHeight="21.65">
+    <group
+        android:translateX="0.90"
+        android:translateY="2.25"
+        >
+        <path
+            android:pathData="M11.69,15.12l-0.78,0.96c-0.43,0.52 -1.22,0.52 -1.64,0L0.24,5c-0.4,-0.49 -0.29,-1.22 0.23,-1.56c1.59,-1.05 5.03,-2.9 9.62,-2.9c4.59,0 8.02,1.85 9.62,2.9c0.53,0.35 0.63,1.08 0.23,1.56l-1.99,2.44h-6.27V15.12zM18.79,9.79c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8l0,0c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21l0,0c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15l-1.21,-1.21l1.21,-1.21C19.1,10.64 19.1,10.13 18.79,9.79z"
+            android:fillColor="?attr/singleToneColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4_fully.xml
index a7e213f..bc3fdb5 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4_fully.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4_fully.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -14,11 +14,15 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="17dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="?attr/singleToneColor"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    android:width="18.41dp"
+    android:height="17dp"
+    android:viewportWidth="21.75"
+    android:viewportHeight="20.0">
+    <group
+        android:translateX="0.80"
+        android:translateY="1.25">
+        <path
+            android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z"
+            android:fillColor="?attr/singleToneColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/trusted_state_to_error.xml b/packages/SystemUI/res/drawable/trusted_state_to_error.xml
index 534a9a5..4a8e452 100755
--- a/packages/SystemUI/res/drawable/trusted_state_to_error.xml
+++ b/packages/SystemUI/res/drawable/trusted_state_to_error.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
+    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
 
@@ -17,31 +17,20 @@
 <vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:name="trusted_state_to_error"
-    android:width="32dp"
-    android:viewportWidth="32"
-    android:height="32dp"
-    android:viewportHeight="32" >
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:height="24dp"
+    android:viewportHeight="24" >
     <group
-        android:name="trusted_state_to_error_0"
-        android:translateX="16"
-        android:translateY="16" >
-        <group
-            android:name="error_circle" >
-            <path
-                android:name="ellipse_path_1"
-                android:trimPathStart="1"
-                android:trimPathOffset="1"
-                android:strokeColor="#FFFFFFFF"
-                android:strokeAlpha="0.5"
-                android:strokeWidth="2"
-                android:pathData="M 0.0,-12.0 c 6.6274169976,0.0 12.0,5.3725830024 12.0,12.0 c 0.0,6.6274169976 -5.3725830024,12.0 -12.0,12.0 c -6.6274169976,0.0 -12.0,-5.3725830024 -12.0,-12.0 c 0.0,-6.6274169976 5.3725830024,-12.0 12.0,-12.0 Z" />
-        </group>
+        android:name="lock"
+        android:translateX="12"
+        android:translateY="12" >
         <group
             android:name="middle_ellipse"
             android:translateY="2.9375" >
             <path
-                android:name="ellipse_path_2"
-                android:fillColor="#FFFFFFFF"
+                android:name="ellipse_path_1"
+                android:fillColor="?attr/wallpaperTextColor"
                 android:fillAlpha="0.5"
                 android:pathData="M 0.0,-1.988645 c 1.09829830627,0.0 1.988645,0.890346693734 1.988645,1.988645 c 0.0,1.09829830627 -0.890346693734,1.988645 -1.988645,1.988645 c -1.09829830627,0.0 -1.988645,-0.890346693734 -1.988645,-1.988645 c 0.0,-1.09829830627 0.890346693734,-1.988645 1.988645,-1.988645 Z" />
         </group>
@@ -50,7 +39,7 @@
             <path
                 android:name="path_1"
                 android:pathData="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
-                android:fillColor="#FFFFFFFF"
+                android:fillColor="?attr/wallpaperTextColor"
                 android:fillAlpha="0.5" />
         </group>
         <group
@@ -58,7 +47,7 @@
             <path
                 android:name="path_2"
                 android:pathData="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
-                android:fillColor="#FFFFFFFF"
+                android:fillColor="?attr/wallpaperTextColor"
                 android:fillAlpha="0.5" />
         </group>
         <group
@@ -66,19 +55,50 @@
             <path
                 android:name="path_3"
                 android:pathData="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
-                android:fillColor="#FFFFFFFF"
+                android:fillColor="?attr/wallpaperTextColor"
                 android:fillAlpha="0.5" />
         </group>
+    </group>
+    <group
+        android:name="errorexclamationdot"
+        android:translateX="12"
+        android:translateY="8" >
         <group
-            android:name="exclamation_dot"
-            android:translateY="4"
-            android:scaleX="0"
-            android:scaleY="0" >
+            android:name="exclamationbottom"
+            android:translateY="4" >
             <path
-                android:name="rectangle_path_1"
-                android:fillColor="#FFFFFFFF"
-                android:fillAlpha="0.5"
-                android:pathData="M -1.33871,-1.3335 l 2.67742,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,2.667 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.67742,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-2.667 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+                android:name="bottompath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+        </group>
+    </group>
+    <group
+        android:name="errorexclamation"
+        android:translateX="12"
+        android:translateY="12" >
+        <group
+            android:name="exclamationtop"
+            android:translateY="2.5" >
+            <path
+                android:name="toppath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M 0.0,-7.0 l 0.0,0.0 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 l 0.0,7.0 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 l 0.0,0.0 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 l 0.0,-7.0 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z" />
+        </group>
+    </group>
+    <group
+        android:name="errorcircle"
+        android:translateX="12"
+        android:translateY="12"
+        android:rotation="184" >
+        <group
+            android:name="circle" >
+            <path
+                android:name="circlepath"
+                android:strokeColor="?android:attr/colorError"
+                android:strokeWidth="2"
+                android:strokeLineCap="round"
+                android:trimPathStart="1"
+                android:pathData="M 0.0,-9.0 c 4.9705627482,0.0 9.0,4.0294372518 9.0,9.0 c 0.0,4.9705627482 -4.0294372518,9.0 -9.0,9.0 c -4.9705627482,0.0 -9.0,-4.0294372518 -9.0,-9.0 c 0.0,-4.9705627482 4.0294372518,-9.0 9.0,-9.0 Z" />
         </group>
     </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/trusted_state_to_error_animation.xml b/packages/SystemUI/res/drawable/trusted_state_to_error_animation.xml
index 5686d54..3457be5 100755
--- a/packages/SystemUI/res/drawable/trusted_state_to_error_animation.xml
+++ b/packages/SystemUI/res/drawable/trusted_state_to_error_animation.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
+    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
 
@@ -21,18 +21,9 @@
         android:name="ellipse_path_1"
         android:animation="@anim/trusted_state_to_error_ellipse_path_1_animation" />
     <target
-        android:name="ellipse_path_2"
-        android:animation="@anim/trusted_state_to_error_ellipse_path_2_animation" />
-    <target
-        android:name="lock_right_side"
-        android:animation="@anim/trusted_state_to_error_lock_right_side_animation" />
-    <target
         android:name="path_1"
         android:animation="@anim/trusted_state_to_error_path_1_animation" />
     <target
-        android:name="lock_left_side"
-        android:animation="@anim/trusted_state_to_error_lock_left_side_animation" />
-    <target
         android:name="path_2"
         android:animation="@anim/trusted_state_to_error_path_2_animation" />
     <target
@@ -42,9 +33,21 @@
         android:name="path_3"
         android:animation="@anim/trusted_state_to_error_path_3_animation" />
     <target
-        android:name="exclamation_dot"
-        android:animation="@anim/trusted_state_to_error_exclamation_dot_animation" />
+        android:name="errorexclamationdot"
+        android:animation="@anim/trusted_state_to_error_errorexclamationdot_animation" />
     <target
-        android:name="rectangle_path_1"
-        android:animation="@anim/trusted_state_to_error_rectangle_path_1_animation" />
+        android:name="bottompath"
+        android:animation="@anim/trusted_state_to_error_bottompath_animation" />
+    <target
+        android:name="exclamationtop"
+        android:animation="@anim/trusted_state_to_error_exclamationtop_animation" />
+    <target
+        android:name="toppath"
+        android:animation="@anim/trusted_state_to_error_toppath_animation" />
+    <target
+        android:name="errorcircle"
+        android:animation="@anim/trusted_state_to_error_errorcircle_animation" />
+    <target
+        android:name="circlepath"
+        android:animation="@anim/trusted_state_to_error_circlepath_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/volume_dialog_background.xml b/packages/SystemUI/res/drawable/volume_dialog_background.xml
index d6adea9..996ac5e 100644
--- a/packages/SystemUI/res/drawable/volume_dialog_background.xml
+++ b/packages/SystemUI/res/drawable/volume_dialog_background.xml
@@ -14,5 +14,5 @@
      limitations under the License.
 -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android" >
-    <solid android:color="?android:attr/colorPrimary" />
+    <solid android:color="?android:attr/colorBackgroundFloating" />
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_0.xml
old mode 100755
new mode 100644
index 262cb88..7f4fdbf
--- a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_0.xml
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_0.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
+    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 l 0.254777070064,0.0 c 0.00007,0.0 0.447133757962,1.0 0.745222929936,1.0 L 1.0,1.0" />
+    android:pathData="M 0.0,0.0 c 1.0,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_1.xml
old mode 100755
new mode 100644
index 9ecee94..1695962
--- a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_1.xml
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_1.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
+    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.00010,0.0 0.6,1.0 1.0,1.0" />
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_2.xml
old mode 100755
new mode 100644
index ae0b2d7..91c08f8
--- a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_2.xml
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_2.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
+    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.000100000000009,0.0 0.6,1.0 1.0,1.0" />
+    android:pathData="M 0.0,0.0 l 0.236439499305,0.0 c 0.763560500695,0.0 0.458136300417,1.0 0.763560500695,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_3.xml
old mode 100755
new mode 100644
index be7cc69..f5cbc31
--- a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_3.xml
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_3.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
+    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.00010,0.0 0.2,1.0 1.0,1.0" />
+    android:pathData="M 0.0,0.0 c 0.00100000000001,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_4.xml
old mode 100755
new mode 100644
index f8f978d..cf21d81
--- a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_4.xml
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_4.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
+    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
+    android:pathData="M 0.0,0.0 c 0.00100000000002,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_5.xml
new file mode 100644
index 0000000..0c18d92
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_5.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.8,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_6.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_6.xml
new file mode 100644
index 0000000..0bf41e5
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_6.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.2,0.0 0.0,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_bluetooth_transient_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_bluetooth_transient_animation_interpolator_0.xml
deleted file mode 100644
index c421f9e..0000000
--- a/packages/SystemUI/res/interpolator/ic_bluetooth_transient_animation_interpolator_0.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.16666666667,0.0 0.83333333333,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_caret_down_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_caret_down_animation_interpolator_0.xml
new file mode 100644
index 0000000..ed90d64
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_caret_down_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.2,0.0 0.0,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_caret_up_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_caret_up_animation_interpolator_0.xml
new file mode 100644
index 0000000..ed90d64
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_caret_up_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.2,0.0 0.0,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_0.xml
new file mode 100644
index 0000000..fcd751d
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.16666666667,0.0 0.83333333333,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_1.xml
new file mode 100644
index 0000000..38dbdb7
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_1.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.8,0.0 0.5,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_2.xml
new file mode 100644
index 0000000..1695962
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_2.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_3.xml
new file mode 100644
index 0000000..8538f98
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_3.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 l 0.286298568507,0.0 c 0.142740286299,0.0 0.0,1.0 0.713701431493,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_4.xml
new file mode 100644
index 0000000..0bf41e5
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_4.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.2,0.0 0.0,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_5.xml
new file mode 100644
index 0000000..2202094
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_5.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.00010,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_6.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_6.xml
new file mode 100644
index 0000000..0c18d92
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_6.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.8,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_0.xml
new file mode 100644
index 0000000..ac1b566
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 l 0.555555555556,0.0 c 0.177777777778,0.0 0.0888888888889,1.0 0.444444444444,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_1.xml
new file mode 100644
index 0000000..7f4fdbf
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_1.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 1.0,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_2.xml
new file mode 100644
index 0000000..1695962
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_2.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_3.xml
new file mode 100644
index 0000000..02c6cd5
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_3.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 l 0.445544554455,0.0 c 0.554455445545,0.0 0.332673267327,1.0 0.554455445545,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_4.xml
new file mode 100644
index 0000000..7ae249e
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_4.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.00010,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_5.xml
new file mode 100644
index 0000000..0c18d92
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_5.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.8,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_hotspot_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_hotspot_disable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index bc0442f..0000000
--- a/packages/SystemUI/res/interpolator/ic_hotspot_disable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_hotspot_disable_ic_hotspot_alpha_interpolator.xml b/packages/SystemUI/res/interpolator/ic_hotspot_disable_ic_hotspot_alpha_interpolator.xml
deleted file mode 100644
index f7072f2..0000000
--- a/packages/SystemUI/res/interpolator/ic_hotspot_disable_ic_hotspot_alpha_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_hotspot_disable_mask_pathdata_interpolator_1.xml b/packages/SystemUI/res/interpolator/ic_hotspot_disable_mask_pathdata_interpolator_1.xml
deleted file mode 100644
index 0cc9c02..0000000
--- a/packages/SystemUI/res/interpolator/ic_hotspot_disable_mask_pathdata_interpolator_1.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0 0.833333333,0.833333333 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_hotspot_disable_mask_pathdata_interpolator_2.xml b/packages/SystemUI/res/interpolator/ic_hotspot_disable_mask_pathdata_interpolator_2.xml
deleted file mode 100644
index 44c755e..0000000
--- a/packages/SystemUI/res/interpolator/ic_hotspot_disable_mask_pathdata_interpolator_2.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0.166666667 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_hotspot_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_hotspot_enable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index bc90d28..0000000
--- a/packages/SystemUI/res/interpolator/ic_hotspot_enable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_hotspot_enable_mask_pathdata_interpolator_1.xml b/packages/SystemUI/res/interpolator/ic_hotspot_enable_mask_pathdata_interpolator_1.xml
deleted file mode 100644
index e361d9c..0000000
--- a/packages/SystemUI/res/interpolator/ic_hotspot_enable_mask_pathdata_interpolator_1.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.833333333,0.833333333 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_hotspot_enable_mask_pathdata_interpolator_2.xml b/packages/SystemUI/res/interpolator/ic_hotspot_enable_mask_pathdata_interpolator_2.xml
deleted file mode 100644
index 25ba970..0000000
--- a/packages/SystemUI/res/interpolator/ic_hotspot_enable_mask_pathdata_interpolator_2.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0.166666667 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index bc0442f..0000000
--- a/packages/SystemUI/res/interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index bc90d28..0000000
--- a/packages/SystemUI/res/interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_invert_colors_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_invert_colors_enable_mask_pathdata_interpolator.xml
deleted file mode 100644
index f7072f2..0000000
--- a/packages/SystemUI/res/interpolator/ic_invert_colors_enable_mask_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml
deleted file mode 100644
index 76f5667..0000000
--- a/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.458031162,0 0.299442342,0.748308635 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
deleted file mode 100644
index ac27e4d..0000000
--- a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.4,0.143709151 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_to_rotate_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_landscape_to_rotate_animation_interpolator_0.xml
new file mode 100644
index 0000000..793e7ff
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_landscape_to_rotate_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_rotate_to_landscape_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_rotate_to_landscape_animation_interpolator_0.xml
new file mode 100644
index 0000000..793e7ff
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_rotate_to_landscape_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_rotate_to_portrait_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_rotate_to_portrait_animation_interpolator_0.xml
new file mode 100644
index 0000000..793e7ff
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_rotate_to_portrait_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index bc0442f..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index bc90d28..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator.xml
deleted file mode 100644
index f7072f2..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index f7072f2..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator.xml
deleted file mode 100644
index f7072f2..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index f7072f2..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_location_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_location_enable_mask_pathdata_interpolator.xml
deleted file mode 100644
index f7072f2..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_location_enable_mask_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index 66cfaff..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index a0118d70..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml
deleted file mode 100644
index 1820bab..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_volume_collapse_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_volume_collapse_animation_interpolator_0.xml
deleted file mode 100644
index c3930e4..0000000
--- a/packages/SystemUI/res/interpolator/ic_volume_collapse_animation_interpolator_0.xml
+++ /dev/null
@@ -1,17 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0001,0.0 0.0,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_volume_expand_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_volume_expand_animation_interpolator_0.xml
deleted file mode 100644
index c3930e4..0000000
--- a/packages/SystemUI/res/interpolator/ic_volume_expand_animation_interpolator_0.xml
+++ /dev/null
@@ -1,17 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0001,0.0 0.0,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_0.xml
deleted file mode 100644
index 708de2a..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_0.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0,0.0 0.29,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_1.xml
deleted file mode 100644
index 07cae89..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_1.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.4,0.0 0.83333333333,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_2.xml
deleted file mode 100644
index a5ffc40..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_2.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0,0.0 0.5,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_3.xml
deleted file mode 100644
index 34156c3..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_3.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0,0.0 0.9999,0.999933333333 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_4.xml
deleted file mode 100644
index 24a3d43..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_4.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0,0.0 0.612659627466,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_5.xml
deleted file mode 100644
index c0a68e2..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_5.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0,0.0 0.9999,0.999883333333 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0.xml
deleted file mode 100644
index 39c5211..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.16666666667,0.0 0.83333333333,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_1.xml
deleted file mode 100644
index 9769a83..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_1.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.312548622571,1.03663900165 0.662518487347,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_2.xml
deleted file mode 100644
index e10db01..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_2.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.8,0.0 0.5,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_3.xml
deleted file mode 100644
index 736eac6..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_3.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_4.xml
deleted file mode 100644
index d3ae9d7..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_4.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_5.xml
deleted file mode 100644
index a5ffc40..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_5.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0,0.0 0.5,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_0.xml
old mode 100755
new mode 100644
index 9ecee94..7f4fdbf
--- a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_0.xml
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_0.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
+    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.00010,0.0 0.6,1.0 1.0,1.0" />
+    android:pathData="M 0.0,0.0 c 1.0,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_1.xml
old mode 100755
new mode 100644
index 87ef1d4..1695962
--- a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_1.xml
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_1.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
+    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 l 0.412907702984,0.0 c 0.00006,0.0 0.35225537821,1.0 0.587092297016,1.0 L 1.0,1.0" />
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_2.xml
old mode 100755
new mode 100644
index be7cc69..138851e
--- a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_2.xml
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_2.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
+    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.00010,0.0 0.2,1.0 1.0,1.0" />
+    android:pathData="M 0.0,0.0 c 0.001,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_3.xml
old mode 100755
new mode 100644
index 83af65a..7657cb6
--- a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_3.xml
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_3.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
+    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.4,0.0 0.9999,1.0 1.0,1.0" />
+    android:pathData="M 0.0,0.0 l 0.364238410596,0.0 c 0.127152317881,0.0 0.0,1.0 0.635761589404,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_4.xml
new file mode 100644
index 0000000..3e5efd7
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_4.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 l 0.4,0.0 c 0.0006,0.0 0.12,1.0 0.6,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_5.xml
new file mode 100644
index 0000000..2202094
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_5.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.00010,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/layout/ambient_indication.xml b/packages/SystemUI/res/layout/ambient_indication.xml
new file mode 100644
index 0000000..37ba35f
--- /dev/null
+++ b/packages/SystemUI/res/layout/ambient_indication.xml
@@ -0,0 +1,19 @@
+<?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.
+  -->
+
+<!-- empty stub -->
+<merge />
diff --git a/packages/SystemUI/res/layout/back.xml b/packages/SystemUI/res/layout/back.xml
index 4e8726b..43bec91 100644
--- a/packages/SystemUI/res/layout/back.xml
+++ b/packages/SystemUI/res/layout/back.xml
@@ -22,8 +22,10 @@
     android:layout_height="match_parent"
     android:layout_weight="0"
     systemui:keyCode="4"
-    android:scaleType="center"
+    android:scaleType="fitCenter"
     android:contentDescription="@string/accessibility_back"
+    android:paddingTop="15dp"
+    android:paddingBottom="15dp"
     android:paddingStart="@dimen/navigation_key_padding"
     android:paddingEnd="@dimen/navigation_key_padding"
     />
diff --git a/packages/SystemUI/res/layout/battery_detail.xml b/packages/SystemUI/res/layout/battery_detail.xml
deleted file mode 100644
index 6162d65..0000000
--- a/packages/SystemUI/res/layout/battery_detail.xml
+++ /dev/null
@@ -1,107 +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.
--->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical">
-
-    <TextView
-        android:id="@+id/charge_and_estimation"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingStart="16dp"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="?android:attr/colorAccent" />
-
-    <com.android.systemui.ResizingSpace
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/battery_detail_graph_space_top" />
-
-    <com.android.settingslib.graph.UsageView
-        android:id="@+id/battery_usage"
-        android:layout_width="match_parent"
-        android:layout_height="141dp"
-        android:layout_marginStart="16dp"
-        android:layout_marginEnd="24dp"
-        systemui:sideLabels="@array/battery_labels"
-        android:colorAccent="?android:attr/colorAccent"
-        systemui:textColor="?android:attr/textColorSecondary" />
-
-    <com.android.systemui.ResizingSpace
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/battery_detail_graph_space_bottom" />
-
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="1dp"
-        android:background="?android:attr/listDivider"
-        android:layout_marginBottom="8dp" />
-
-    <RelativeLayout
-        android:id="@+id/switch_container"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingTop="16dp"
-        android:paddingBottom="16dp"
-        android:background="?android:attr/selectableItemBackground"
-        android:clickable="true">
-
-        <ImageView
-            android:id="@android:id/icon"
-            android:layout_width="24dp"
-            android:layout_height="24dp"
-            android:scaleType="fitCenter"
-            android:adjustViewBounds="true"
-            android:layout_alignParentTop="true"
-            android:layout_alignParentStart="true"
-            android:layout_marginStart="16dp"
-            android:layout_marginEnd="32dp" />
-
-        <TextView
-            android:id="@android:id/title"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_toStartOf="@android:id/toggle"
-            android:layout_toEndOf="@android:id/icon"
-            android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary"
-            android:text="@string/battery_detail_switch_title" />
-
-        <TextView
-            android:id="@android:id/summary"
-            android:visibility="gone"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_below="@android:id/title"
-            android:layout_toStartOf="@android:id/toggle"
-            android:layout_toEndOf="@android:id/icon"
-            android:textAppearance="@style/TextAppearance.QS.DetailItemSecondary"
-            android:text="@string/battery_detail_switch_summary" />
-
-        <Switch
-            android:id="@android:id/toggle"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentEnd="true"
-            android:layout_alignParentTop="true"
-            android:layout_marginEnd="16dp"
-            android:clickable="false"
-            android:textAppearance="@style/TextAppearance.QS.DetailHeader" />
-
-    </RelativeLayout>
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/brightness_mirror.xml b/packages/SystemUI/res/layout/brightness_mirror.xml
index bbaff6a..d6e7507 100644
--- a/packages/SystemUI/res/layout/brightness_mirror.xml
+++ b/packages/SystemUI/res/layout/brightness_mirror.xml
@@ -16,7 +16,7 @@
   -->
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/brightness_mirror"
-    android:layout_width="@dimen/notification_panel_width"
+    android:layout_width="@dimen/qs_panel_width"
     android:layout_height="wrap_content"
     android:layout_gravity="@integer/notification_panel_layout_gravity"
     android:visibility="invisible">
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
index b7e666f..bc29012 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
@@ -15,24 +15,26 @@
      limitations under the License.
 -->
 
-<!--  LinearLayout -->
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
-    android:gravity="top|center_horizontal"
-    android:layout_width="180dp"
-    android:layout_height="wrap_content">
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_marginLeft="@dimen/car_fullscreen_user_pod_margin_side"
+    android:layout_marginRight="@dimen/car_fullscreen_user_pod_margin_side"
+    android:gravity="center"
+    android:layout_weight="1" >
 
     <ImageView android:id="@+id/user_avatar"
-               android:padding="10dp"
-               android:layout_gravity="center"
-               android:layout_width="@dimen/car_fullscreen_user_pod_image_avatar_width"
-               android:layout_height="@dimen/car_fullscreen_user_pod_image_avatar_height" />
+        android:layout_gravity="center"
+        android:layout_width="@dimen/car_fullscreen_user_pod_image_avatar_width"
+        android:layout_height="@dimen/car_fullscreen_user_pod_image_avatar_height" />
 
     <TextView android:id="@+id/user_name"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:textSize="@dimen/car_fullscreen_user_pod_text_size"
-              android:textColor="@color/qs_user_detail_name"
-              android:gravity="center_horizontal" />
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/car_fullscreen_user_pod_margin_above_text"
+        android:textSize="@dimen/car_fullscreen_user_pod_text_size"
+        android:textColor="@color/qs_user_detail_name"
+        android:layout_gravity="center_horizontal" />
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_pod_container.xml b/packages/SystemUI/res/layout/car_fullscreen_user_pod_container.xml
new file mode 100644
index 0000000..8c55680
--- /dev/null
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_pod_container.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center">
+
+    <!-- car_fullscreen_user_pods will be dynamically added here. -->
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
index 6e4b213..c82eddc 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
@@ -14,38 +14,58 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-             android:fitsSystemWindows="true"
-             android:layout_width="match_parent"
-             android:layout_height="match_parent"
-             android:visibility="gone">
-    <LinearLayout
+        android:fitsSystemWindows="true"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:orientation="vertical">
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/car_lockscreen_disclaimer_title"
-            android:textSize="@dimen/car_lockscreen_disclaimer_title_size"
-            android:paddingStart="@dimen/car_lockscreen_disclaimer_title_padding_start"
-            android:paddingTop="@dimen/car_lockscreen_disclaimer_title_padding_top" />
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="0dp"
-            android:layout_weight="1"
-            android:text="@string/car_lockscreen_disclaimer_text"
-            android:textSize="@dimen/car_lockscreen_disclaimer_text_size"
-            android:paddingStart="@dimen/car_lockscreen_disclaimer_text_padding_start"
-            android:paddingEnd="@dimen/car_lockscreen_disclaimer_text_padding_end"
-            android:paddingTop="@dimen/car_lockscreen_disclaimer_text_padding_top" />
+        android:background="@android:color/black"
+        android:visibility="gone">
+
+    <!-- This progressbar is activated while we're switching users. -->
+    <ProgressBar
+        android:id="@+id/switching_users"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:indeterminate="true"
+        android:visibility="gone"
+        android:layout_gravity="center" />
+
+    <RelativeLayout
+        android:id="@+id/container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <!-- This progress bar is the countdown timer. -->
+        <ProgressBar
+            android:id="@+id/countdown_progress"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/car_user_switcher_progress_bar_height"
+            style="@style/CarUserSwitcher.ProgressBar"
+            android:layout_marginTop="@dimen/car_user_switcher_progress_bar_margin_top"
+            android:layout_alignParentTop="true"/>
+
         <com.android.systemui.statusbar.car.UserGridView
             android:id="@+id/user_grid"
-            android:layout_gravity="center"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:stretchMode="columnWidth">
-        </com.android.systemui.statusbar.car.UserGridView>
-    </LinearLayout>
+            android:layout_marginLeft="@dimen/car_margin"
+            android:layout_marginRight="@dimen/car_margin"
+            android:layout_centerInParent="true" />
+
+        <com.android.systemui.statusbar.car.PageIndicator
+            android:id="@+id/user_switcher_page_indicator"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/car_page_indicator_dot_diameter"
+            android:layout_marginTop="@dimen/car_page_indicator_margin_top"
+            android:layout_below="@+id/user_grid" />
+
+        <Button
+            android:id="@+id/start_driving"
+            android:layout_width="wrap_content"
+            android:layout_height="@dimen/car_start_driving_height"
+            android:text="@string/start_driving"
+            style="@style/CarUserSwitcher.StartDrivingButton"
+            android:layout_alignParentBottom="true"
+            android:layout_centerHorizontal="true" />
+    </RelativeLayout>
 </FrameLayout>
diff --git a/packages/SystemUI/res/layout/global_actions_item.xml b/packages/SystemUI/res/layout/global_actions_item.xml
new file mode 100644
index 0000000..e3a488c
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_actions_item.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- RelativeLayouts have an issue enforcing minimum heights, so just
+     work around this for now with LinearLayouts. -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center"
+    android:minWidth="92dp"
+    android:minHeight="92dp"
+    android:gravity="center"
+    android:orientation="vertical"
+    android:paddingEnd="8dip"
+    android:paddingStart="8dip">
+
+    <ImageView
+        android:id="@*android:id/icon"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        android:layout_gravity="center"
+        android:scaleType="center"/>
+
+    <TextView
+        android:id="@*android:id/message"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top|center_horizontal"
+        android:paddingTop="10dp"
+        android:gravity="center"
+        android:textSize="12sp"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        />
+
+    <TextView
+        android:id="@*android:id/status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top|center_horizontal"
+        android:gravity="center"
+        android:textColor="?android:attr/textColorTertiary"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        />
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/global_actions_wrapped.xml b/packages/SystemUI/res/layout/global_actions_wrapped.xml
new file mode 100644
index 0000000..ec357d2
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_actions_wrapped.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.systemui.HardwareUiLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_marginBottom="0dp"
+    android:paddingTop="@dimen/global_actions_top_padding"
+    android:clipToPadding="false"
+    android:theme="@style/qs_theme"
+    android:clipChildren="false">
+
+    <LinearLayout
+        android:id="@android:id/list"
+        android:layout_width="@dimen/global_actions_panel_width"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top|end"
+        android:gravity="center"
+        android:orientation="vertical"
+        android:padding="12dp"
+        android:translationZ="8dp" />
+
+</com.android.systemui.HardwareUiLayout>
diff --git a/packages/SystemUI/res/layout/home.xml b/packages/SystemUI/res/layout/home.xml
index 9586327..53ef2ab 100644
--- a/packages/SystemUI/res/layout/home.xml
+++ b/packages/SystemUI/res/layout/home.xml
@@ -21,8 +21,10 @@
     android:layout_height="match_parent"
     android:layout_weight="0"
     systemui:keyCode="3"
-    android:scaleType="center"
+    android:scaleType="fitCenter"
     android:contentDescription="@string/accessibility_home"
+    android:paddingTop="13dp"
+    android:paddingBottom="13dp"
     android:paddingStart="@dimen/navigation_key_padding"
     android:paddingEnd="@dimen/navigation_key_padding"
     />
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index e3063c5..2fd4df4 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -39,7 +39,7 @@
             android:layout_height="wrap_content"
             android:gravity="center_horizontal"
             android:textStyle="italic"
-            android:textColor="#ffffff"
+            android:textColor="?attr/wallpaperTextColorSecondary"
             android:textAppearance="?android:attr/textAppearanceSmall"
             android:visibility="gone" />
 
@@ -49,7 +49,7 @@
             android:layout_height="wrap_content"
             android:gravity="center_horizontal"
             android:textStyle="italic"
-            android:textColor="#ffffff"
+            android:textColor="?attr/wallpaperTextColorSecondary"
             android:textAppearance="?android:attr/textAppearanceSmall"
             android:accessibilityLiveRegion="polite" />
 
@@ -68,7 +68,8 @@
         android:layout_gravity="bottom|end"
         android:src="@drawable/ic_camera_alt_24dp"
         android:scaleType="center"
-        android:contentDescription="@string/accessibility_camera_button" />
+        android:contentDescription="@string/accessibility_camera_button"
+        android:tint="?attr/wallpaperTextColor" />
 
     <com.android.systemui.statusbar.KeyguardAffordanceView
         android:id="@+id/left_button"
@@ -77,7 +78,8 @@
         android:layout_gravity="bottom|start"
         android:src="@drawable/ic_phone_24dp"
         android:scaleType="center"
-        android:contentDescription="@string/accessibility_phone_button" />
+        android:contentDescription="@string/accessibility_phone_button"
+        android:tint="?attr/wallpaperTextColor" />
 
     <com.android.systemui.statusbar.phone.LockIcon
         android:id="@+id/lock_icon"
@@ -88,4 +90,13 @@
         android:contentDescription="@string/accessibility_unlock_button"
         android:scaleType="center" />
 
+    <FrameLayout
+        android:id="@+id/overlay_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <include layout="@layout/keyguard_bottom_area_overlay" />
+
+    </FrameLayout>
+
 </com.android.systemui.statusbar.phone.KeyguardBottomAreaView>
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area_overlay.xml b/packages/SystemUI/res/layout/keyguard_bottom_area_overlay.xml
new file mode 100644
index 0000000..37ba35f
--- /dev/null
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area_overlay.xml
@@ -0,0 +1,19 @@
+<?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.
+  -->
+
+<!-- empty stub -->
+<merge />
diff --git a/packages/SystemUI/res/layout/keyguard_status_bar.xml b/packages/SystemUI/res/layout/keyguard_status_bar.xml
index c5f2f4a..7b30d6a 100644
--- a/packages/SystemUI/res/layout/keyguard_status_bar.xml
+++ b/packages/SystemUI/res/layout/keyguard_status_bar.xml
@@ -63,7 +63,7 @@
         android:gravity="center_vertical"
         android:ellipsize="marquee"
         android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="#ffffff"
+        android:textColor="?attr/wallpaperTextColorSecondary"
         android:singleLine="true" />
 
 </com.android.systemui.statusbar.phone.KeyguardStatusBarView>
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index 2bf4d9c..53f5dfe 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -18,9 +18,13 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:layout_marginStart="@dimen/rounded_corner_content_padding"
+    android:layout_marginEnd="@dimen/rounded_corner_content_padding"
+    android:paddingStart="8dp"
+    android:paddingEnd="8dp">
 
-    <FrameLayout
+    <com.android.systemui.statusbar.phone.NearestTouchFrame
         android:id="@+id/nav_buttons"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
@@ -40,7 +44,7 @@
             android:orientation="horizontal"
             android:clipChildren="false" />
 
-    </FrameLayout>
+    </com.android.systemui.statusbar.phone.NearestTouchFrame>
 
     <com.android.systemui.statusbar.policy.DeadZone
         android:id="@+id/deadzone"
diff --git a/packages/SystemUI/res/layout/navigation_layout_rot90.xml b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
index 7601efc..39cdff4 100644
--- a/packages/SystemUI/res/layout/navigation_layout_rot90.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
@@ -18,9 +18,13 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:layout_marginTop="@dimen/rounded_corner_content_padding"
+    android:layout_marginBottom="@dimen/rounded_corner_content_padding"
+    android:paddingTop="8dp"
+    android:paddingBottom="8dp">
 
-    <FrameLayout
+    <com.android.systemui.statusbar.phone.NearestTouchFrame
         android:id="@+id/nav_buttons"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
@@ -40,7 +44,7 @@
             android:orientation="vertical"
             android:clipChildren="false" />
 
-    </FrameLayout>
+    </com.android.systemui.statusbar.phone.NearestTouchFrame>
 
     <com.android.systemui.statusbar.policy.DeadZone
         android:id="@+id/deadzone"
diff --git a/packages/SystemUI/res/layout/notification_children_divider.xml b/packages/SystemUI/res/layout/notification_children_divider.xml
index 76315b8..eb74306 100644
--- a/packages/SystemUI/res/layout/notification_children_divider.xml
+++ b/packages/SystemUI/res/layout/notification_children_divider.xml
@@ -20,4 +20,4 @@
     android:id="@+id/notification_more_divider"
     android:layout_width="match_parent"
     android:layout_height="@dimen/notification_divider_height"
-    android:background="#FF616161" />
+    android:background="@color/notification_divider_color" />
diff --git a/packages/SystemUI/res/layout/notification_snooze.xml b/packages/SystemUI/res/layout/notification_snooze.xml
index b70f24b..3209f27 100644
--- a/packages/SystemUI/res/layout/notification_snooze.xml
+++ b/packages/SystemUI/res/layout/notification_snooze.xml
@@ -20,12 +20,13 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
+    android:clickable="true"
     android:background="@color/notification_guts_bg_color"
     android:theme="@*android:style/Theme.DeviceDefault.Light">
 
     <RelativeLayout
-        android:layout_width="match_parent"
         android:id="@+id/notification_snooze"
+        android:layout_width="match_parent"
         android:layout_height="@dimen/snooze_snackbar_min_height">
 
         <TextView
diff --git a/packages/SystemUI/res/layout/qs_customize_panel.xml b/packages/SystemUI/res/layout/qs_customize_panel.xml
index cbc2575..9ab8ac63 100644
--- a/packages/SystemUI/res/layout/qs_customize_panel.xml
+++ b/packages/SystemUI/res/layout/qs_customize_panel.xml
@@ -21,7 +21,6 @@
     android:layout_width="match_parent"
     android:layout_height="0dp"
     android:orientation="vertical"
-    android:elevation="4dp"
     android:background="@drawable/qs_customizer_background"
     android:gravity="center_horizontal">
 
diff --git a/packages/SystemUI/res/layout/qs_detail.xml b/packages/SystemUI/res/layout/qs_detail.xml
index 34e43ce..1fd239b 100644
--- a/packages/SystemUI/res/layout/qs_detail.xml
+++ b/packages/SystemUI/res/layout/qs_detail.xml
@@ -20,7 +20,6 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@drawable/qs_detail_background"
-    android:elevation="4dp"
     android:clickable="true"
     android:orientation="vertical"
     android:paddingBottom="8dp"
@@ -41,7 +40,6 @@
         android:background="@color/qs_detail_progress_track"
         android:src="@drawable/indeterminate_anim"
         android:scaleType="fitXY"
-        android:translationY="16dp"
         />
 
     <com.android.systemui.qs.NonInterceptingScrollView
diff --git a/packages/SystemUI/res/layout/qs_footer.xml b/packages/SystemUI/res/layout/qs_footer.xml
index 871d1f3..db39905 100644
--- a/packages/SystemUI/res/layout/qs_footer.xml
+++ b/packages/SystemUI/res/layout/qs_footer.xml
@@ -21,13 +21,11 @@
     android:id="@+id/header"
     android:layout_width="match_parent"
     android:layout_height="48dp"
-    android:elevation="4dp"
     android:baselineAligned="false"
     android:clickable="false"
     android:clipChildren="false"
     android:clipToPadding="false"
     android:paddingTop="0dp"
-    android:background="#00000000"
     android:gravity="center_vertical"
     android:orientation="horizontal">
 
@@ -116,9 +114,4 @@
             android:padding="14dp" />
     </LinearLayout>
 
-    <include layout="@layout/qs_divider"
-        android:layout_width="match_parent"
-        android:layout_height="1dp"
-        android:layout_gravity="bottom" />
-
 </com.android.systemui.qs.QSFooter>
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index fb4ac04..87101e4 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -18,24 +18,16 @@
     android:id="@+id/quick_settings_container"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="?android:attr/colorPrimaryDark"
+    android:background="@drawable/qs_background_primary"
+    android:elevation="4dp"
     android:clipToPadding="false"
     android:clipChildren="false">
 
-    <View
-        android:id="@+id/qs_background"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:background="@drawable/qs_background_primary"
-        android:elevation="4dp" />
-
     <com.android.systemui.qs.QSPanel
         android:id="@+id/quick_settings_panel"
         android:layout_marginTop="28dp"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:elevation="4dp"
-        android:background="#00000000"
         android:layout_marginBottom="48dp" />
 
     <include layout="@layout/quick_status_bar_expanded_header" />
diff --git a/packages/SystemUI/res/layout/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml
index 35a9477..b138df0 100644
--- a/packages/SystemUI/res/layout/qs_tile_label.xml
+++ b/packages/SystemUI/res/layout/qs_tile_label.xml
@@ -63,7 +63,8 @@
             android:layout_width="18dp"
             android:layout_height="match_parent"
             android:src="@drawable/qs_dual_tile_caret"
-            android:tint="?android:attr/textColorPrimary" />
+            android:tint="?android:attr/textColorPrimary"
+            android:visibility="gone" />
     </LinearLayout>
 
     <TextView
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index 1fb254c..f8b7b8a 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -24,8 +24,6 @@
     android:layout_height="@dimen/status_bar_header_height"
     android:layout_gravity="@integer/notification_panel_layout_gravity"
     android:baselineAligned="false"
-    android:background="#00000000"
-    android:elevation="4dp"
     android:clickable="false"
     android:clipChildren="false"
     android:clipToPadding="false"
@@ -35,13 +33,13 @@
 
     <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="32dp"
+        android:layout_height="40dp"
         android:layout_alignParentEnd="true"
         android:clipChildren="false"
         android:clipToPadding="false"
         android:gravity="center"
-        android:paddingStart="16dp"
-        android:paddingEnd="16dp"
+        android:paddingStart="8dp"
+        android:paddingEnd="8dp"
         android:orientation="horizontal">
 
 
diff --git a/packages/SystemUI/res/layout/recent_apps.xml b/packages/SystemUI/res/layout/recent_apps.xml
index 870bcf7..c84d280 100644
--- a/packages/SystemUI/res/layout/recent_apps.xml
+++ b/packages/SystemUI/res/layout/recent_apps.xml
@@ -21,8 +21,10 @@
     android:layout_width="@dimen/navigation_key_width"
     android:layout_height="match_parent"
     android:layout_weight="0"
-    android:scaleType="center"
+    android:scaleType="fitCenter"
     android:contentDescription="@string/accessibility_recent"
+    android:paddingTop="15dp"
+    android:paddingBottom="15dp"
     android:paddingStart="@dimen/navigation_key_padding"
     android:paddingEnd="@dimen/navigation_key_padding"
     />
diff --git a/packages/SystemUI/res/layout/recents_empty.xml b/packages/SystemUI/res/layout/recents_empty.xml
index 53d9cc5..d7f058c 100644
--- a/packages/SystemUI/res/layout/recents_empty.xml
+++ b/packages/SystemUI/res/layout/recents_empty.xml
@@ -23,7 +23,8 @@
     android:drawableTop="@drawable/recents_empty"
     android:drawablePadding="25dp"
     android:textSize="16sp"
-    android:textColor="#ffffffff"
+    android:drawableTint="?attr/wallpaperTextColor"
+    android:textColor="?attr/wallpaperTextColor"
     android:text="@string/recents_empty_message"
     android:fontFamily="sans-serif"
     android:visibility="gone" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/recents_stack_action_button.xml b/packages/SystemUI/res/layout/recents_stack_action_button.xml
index 34b4e17..4707a8c 100644
--- a/packages/SystemUI/res/layout/recents_stack_action_button.xml
+++ b/packages/SystemUI/res/layout/recents_stack_action_button.xml
@@ -24,7 +24,7 @@
     android:paddingBottom="12dp"
     android:text="@string/recents_stack_action_button_label"
     android:textSize="14sp"
-    android:textColor="#FFFFFF"
+    android:textColor="?attr/wallpaperTextColor"
     android:textAllCaps="true"
     android:shadowColor="#99000000"
     android:shadowDx="0"
diff --git a/packages/SystemUI/res/layout/rounded_corners.xml b/packages/SystemUI/res/layout/rounded_corners.xml
new file mode 100644
index 0000000..d1ef5d6
--- /dev/null
+++ b/packages/SystemUI/res/layout/rounded_corners.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+-->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <ImageView
+        android:id="@+id/left"
+        android:layout_width="12dp"
+        android:layout_height="12dp"
+        android:layout_gravity="left"
+        android:tint="#ff000000"
+        android:src="@drawable/rounded" />
+    <ImageView
+        android:id="@+id/right"
+        android:layout_width="12dp"
+        android:layout_height="12dp"
+        android:tint="#ff000000"
+        android:layout_gravity="right"
+        android:src="@drawable/rounded" />
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml
index 2e22943..25c87d3 100644
--- a/packages/SystemUI/res/layout/signal_cluster_view.xml
+++ b/packages/SystemUI/res/layout/signal_cluster_view.xml
@@ -32,6 +32,7 @@
         android:layout_width="wrap_content"
         android:paddingEnd="6dp"
         android:src="@drawable/stat_sys_vpn_ic"
+        android:tint="@color/background_protect_secondary"
         android:contentDescription="@string/accessibility_vpn_on"
         />
     <FrameLayout
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 0852020..bef0830 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -27,7 +27,6 @@
 
     <include
         layout="@layout/keyguard_status_view"
-        android:layout_height="wrap_content"
         android:visibility="gone" />
 
     <com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer
@@ -41,7 +40,7 @@
         <FrameLayout
             android:id="@+id/qs_frame"
             android:layout="@layout/qs_panel"
-            android:layout_width="@dimen/notification_panel_width"
+            android:layout_width="@dimen/qs_panel_width"
             android:layout_height="match_parent"
             android:layout_gravity="@integer/notification_panel_layout_gravity"
             android:clipToPadding="false"
@@ -50,11 +49,15 @@
 
         <com.android.systemui.statusbar.stack.NotificationStackScrollLayout
             android:id="@+id/notification_stack_scroller"
+            android:layout_marginTop="@dimen/notification_panel_margin_top"
             android:layout_width="@dimen/notification_panel_width"
             android:layout_height="match_parent"
             android:layout_gravity="@integer/notification_panel_layout_gravity"
             android:layout_marginBottom="@dimen/close_handle_underlap" />
 
+        <include layout="@layout/ambient_indication"
+            android:id="@+id/ambient_indication_container" />
+
         <ViewStub
             android:id="@+id/keyguard_user_switcher"
             android:layout="@layout/keyguard_user_switcher"
diff --git a/packages/SystemUI/res/layout/status_bar_no_notifications.xml b/packages/SystemUI/res/layout/status_bar_no_notifications.xml
index 6f87184..0a25b69 100644
--- a/packages/SystemUI/res/layout/status_bar_no_notifications.xml
+++ b/packages/SystemUI/res/layout/status_bar_no_notifications.xml
@@ -27,7 +27,7 @@
             android:layout_height="64dp"
             android:paddingTop="28dp"
             android:gravity="top|center_horizontal"
-            android:textColor="#e6ffffff"
+            android:textColor="?attr/wallpaperTextColor"
             android:textSize="16sp"
             android:text="@string/empty_shade_text"/>
 </com.android.systemui.statusbar.EmptyShadeView>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml b/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
index efb273f..8dc4cb4 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
@@ -30,5 +30,6 @@
             android:focusable="true"
             android:contentDescription="@string/accessibility_clear_all"
             android:text="@string/clear_all_notifications_text"
+            android:textColor="?attr/wallpaperTextColor"
             android:textAllCaps="true"/>
 </com.android.systemui.statusbar.DismissView>
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 51eefb6..029d16e 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -48,7 +48,6 @@
         android:layout_height="match_parent"
         android:importantForAccessibility="no"
         sysui:ignoreRightInset="true"
-        sysui:scrimColor="@color/scrim_behind_color"
         />
 
     <com.android.systemui.statusbar.AlphaOptimizedView
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 18ffd0f..4487abc 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -21,6 +21,7 @@
     android:layout_marginBottom="@dimen/volume_dialog_margin_bottom"
     android:background="@drawable/volume_dialog_background"
     android:paddingTop="@dimen/volume_dialog_padding_top"
+    android:theme="@style/qs_theme"
     android:translationZ="4dp" >
 
     <LinearLayout
diff --git a/packages/SystemUI/res/layout/volume_zen_footer.xml b/packages/SystemUI/res/layout/volume_zen_footer.xml
index 91dc617..7ffcb1e 100644
--- a/packages/SystemUI/res/layout/volume_zen_footer.xml
+++ b/packages/SystemUI/res/layout/volume_zen_footer.xml
@@ -51,8 +51,7 @@
             android:clickable="true"
             android:contentDescription="@string/accessibility_desc_close"
             android:scaleType="center"
-            android:src="@drawable/ic_close"
-            android:tint="@android:color/white" />
+            android:src="@drawable/ic_close_white_rounded" />
 
         <TextView
             android:id="@+id/zen_introduction_message"
@@ -128,4 +127,4 @@
         android:textColor="?android:attr/colorAccent"
         android:textAppearance="@style/TextAppearance.QS.DetailButton" />
 
-</com.android.systemui.volume.ZenFooter>
\ No newline at end of file
+</com.android.systemui.volume.ZenFooter>
diff --git a/packages/SystemUI/res/layout/zen_mode_condition.xml b/packages/SystemUI/res/layout/zen_mode_condition.xml
index 2b4a0f5..ab52465 100644
--- a/packages/SystemUI/res/layout/zen_mode_condition.xml
+++ b/packages/SystemUI/res/layout/zen_mode_condition.xml
@@ -27,6 +27,8 @@
         android:id="@android:id/content"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:minHeight="48dp"
+        android:gravity="center_vertical"
         android:layout_centerVertical="true"
         android:orientation="vertical"
         android:layout_toEndOf="@android:id/checkbox"
@@ -79,4 +81,4 @@
         android:tint="?android:attr/textColorPrimary"
         android:src="@drawable/ic_qs_plus" />
 
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index 200eabf..3826bdd 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -59,8 +59,7 @@
                 android:clickable="true"
                 android:contentDescription="@string/accessibility_desc_close"
                 android:scaleType="center"
-                android:src="@drawable/ic_close"
-                android:tint="@android:color/white" />
+                android:src="@drawable/ic_close_white_rounded" />
 
             <TextView
                 android:id="@+id/zen_introduction_message"
@@ -94,7 +93,7 @@
 
         </RelativeLayout>
 
-        <LinearLayout
+        <com.android.systemui.volume.ZenRadioLayout
             android:id="@+id/zen_conditions"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
@@ -112,7 +111,7 @@
                 android:layout_width="fill_parent"
                 android:layout_height="fill_parent"
                 android:orientation="vertical"/>
-        </LinearLayout>
+        </com.android.systemui.volume.ZenRadioLayout>
 
         <TextView
             android:id="@+id/zen_alarm_warning"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 32f3ca5..131214d 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Meer instellings"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Klaar"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Gekoppel"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Gekoppel, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Koppel tans …"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"USB-verbinding"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Warmkol"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Jy is gekoppel aan <xliff:g id="APPLICATION">%1$s</xliff:g>, wat jou persoonlike netwerkaktiwiteit, insluitend e-posse, programme en webwerwe, kan monitor."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> bestuur jou werkprofiel. Die profiel is gekoppel aan <xliff:g id="APPLICATION">%2$s</xliff:g>, wat jou netwerkaktiwiteit, insluitend e-posse, programme en webwerwe, kan monitor.\n\nKontak jou administrateur vir meer inligting."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> bestuur jou werkprofiel. Die profiel is gekoppel aan <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, wat jou netwerkaktiwiteit, insluitend e-posse, programme en webwerwe, kan monitor.\n\nJy is ook gekoppel aan <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, wat jou persoonlike netwerkaktiwiteit kan monitor."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Ontsluit vir <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> loop tans"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Toestel sal gesluit bly totdat jy dit handmatig ontsluit"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Kry kennisgewings vinniger"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Sien hulle voordat jy ontsluit"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Af"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Met kragkennisgewingkontroles kan jy \'n belangrikheidvlak van 0 tot 5 vir \'n program se kennisgewings stel. \n\n"<b>"Vlak 5"</b>" \n- Wys aan die bokant van die kennisgewinglys \n- Laat volskermonderbreking toe \n- Wys altyd opspringkennisgewings \n\n"<b>"Vlak 4"</b>" \n- Verhoed volskermonderbreking \n- Wys altyd opspringkennisgewings \n\n"<b>"Vlak 3"</b>" \n- Verhoed volskermonderbreking \n- Verhoed opspringkennisgewings \n\n"<b>"Vlak 2"</b>" \n- Verhoed volskermonderbreking \n- Verhoed opspringkennisgewings \n- Moet nooit \'n klank maak of vibreer nie \n\n"<b>"Vlak 1"</b>" \n- Verhoed volskermonderbreking \n- Verhoed opspringkennisgewings \n- Moet nooit \'n klank maak of vibreer nie \n- Versteek van sluitskerm en statusbalk \n- Wys aan die onderkant van die kennisgewinglys \n\n"<b>"Vlak 0"</b>" \n- Blokkeer alle kennisgewings van die program af"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Kennisgewings"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Jy sal nie meer hierdie kennisgewings kry nie."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Jy sal nie meer hierdie kennisgewings kry nie"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> kennisgewingkategorieë"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Hierdie program het nie kennisgewingkategorieë nie"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Kennisgewings van hierdie program af kan nie afgeskakel word nie"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 uit <xliff:g id="NUMBER_1">%d</xliff:g> kennisgewingkategorieë van hierdie program</item>
       <item quantity="one">1 uit <xliff:g id="NUMBER_0">%d</xliff:g> kennisgewingkategorie van hierdie program</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kennisgewingkontroles"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"kennisgewing-sluimeropsies"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minute"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minute"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 uur"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 uur"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ONTDOEN"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Sluimer vir <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d uur</item>
+      <item quantity="one">%d uur</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minute</item>
+      <item quantity="one">%d minuut</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Batterygebruik"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterybespaarder is nie beskikbaar wanneer gelaai word nie"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterybespaarder"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Vervang"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Programme wat op die agtergrond loop"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tik vir besonderhede oor battery- en datagebruik"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Skakel mobiele data af?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-af/strings_car.xml b/packages/SystemUI/res/values-af/strings_car.xml
index 7c6f609..87462fc 100644
--- a/packages/SystemUI/res/values-af/strings_car.xml
+++ b/packages/SystemUI/res/values-af/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Ry veilig"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Bly heeltemal bewus van bestuurtoestande en gehoorsaam toepaslike wette altyd. Rigtingaanwysings sal dalk onakkuraat, onvolledig, gevaarlik, ontoepaslik of verbode wees of behels dat administratiewe gebiede oorgesteek word. Besigheidsinligting sal dalk ook onakkuraat of onvolledig wees. Data is nie intyds nie en liggingakkuraatheid kan nie gewaarborg word nie. Moenie jou mobiele toestel hanteer of programme wat nie vir Android Auto bedoel is, gebruik terwyl jy bestuur nie."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Onbekend"</string>
+    <string name="start_driving" msgid="864023351402918991">"Begin ry"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 197239f..4e5357d 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -298,7 +298,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi ጠፍቷል"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi በርቷል"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"ምንም የWi-Fi  አውታረ መረቦች የሉም"</string>
-    <string name="quick_settings_cast_title" msgid="7709016546426454729">"ውሰድ"</string>
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"በመውሰድ ላይ"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ያልተሰየመ መሳሪያ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"ለመውሰድ ዝግጁ"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"ተጨማሪ ቅንብሮች"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"ተከናውኗል"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"ተገናኝቷል"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"ተገናኝቷል፣ ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"በማገናኘት ላይ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"በማገናኘት ላይ"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"መገናኛ ነጥብ"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"እርስዎ ኢሜይሎችን፣ መተግበሪያዎችን እና ድር ጣቢያዎችንም ጨምሮ የግል የአውታረ መረብ እንቅስቃሴዎን ከሚከታተለው ከ<xliff:g id="APPLICATION">%1$s</xliff:g> ጋር ተገናኝተዋል።"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"የእርስዎ የሥራ መገለጫ በ<xliff:g id="ORGANIZATION">%1$s</xliff:g> የሚተዳደር ነው። መገለጫው ኢሜይሎችን፣ መተግበሪያዎችን፣ እና የድር ጣቢያዎችን ጨምሮ የአውታረ መረብ እንቅስቃሴን መቆጣጠር ከሚችለው ከ<xliff:g id="APPLICATION">%2$s</xliff:g> ጋር ተገናኝቷል።\n\nለተጨማሪ መረጃ የእርስዎን አስተዳዳሪ ያነጋግሩ።"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"የእርስዎ የሥራ መገለጫ በ<xliff:g id="ORGANIZATION">%1$s</xliff:g> የሚተዳደር ነው። መገለጫው ኢሜይሎችን፣ መተግበሪያዎችን፣ እና የድር ጣቢያዎችን ጨምሮ የአውታረ መረብ እንቅስቃሴን መቆጣጠር ከሚችለው ከ<xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ጋር ተገናኝቷል።\n\nበተጨማሪ የእርስዎን የግል የአውታረ መረብ እንቅስቃሴ መቆጣጠር ከሚችለው ከ<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ጋር ተገናኝተዋል።"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"ለ<xliff:g id="USER_NAME">%1$s</xliff:g> ተከፍቷል"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> እያሄደ ነው"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"እራስዎ እስኪከፍቱት ድረስ መሣሪያ እንደተቆለፈ ይቆያል"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"ማሳወቂያዎችን ፈጥነው ያግኙ"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ከመክፈትዎ በፊት ይመልከቷቸው"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ጠፍቷል"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"በኃይል ማሳወቂያ መቆጣጠሪያዎች አማካኝነት የአንድ መተግበሪያ ማሳወቂያዎች የአስፈላጊነት ደረጃ ከ0 እስከ 5 ድረስ ማዘጋጀት ይችላሉ። \n\n"<b>"ደረጃ 5"</b>" \n- በማሳወቂያ ዝርዝሩ አናት ላይ አሳይ \n- የሙሉ ማያ ገጽ ማቋረጥን ፍቀድ \n- ሁልጊዜ አጮልቀው ይመልከቱ \n\n"<b>"ደረጃ 4"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ከልክል \n- ሁልጊዜ አጮልቀው ይመልከቱ \n\n"<b>"ደረጃ 3"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ከልክል \n- በፍጹም አጮልቀው አይምልከቱ \n\n"<b>"ደረጃ 2"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ይከልክሉ \n- በፍጹም አጮልቀው አይመልከቱ \n- ድምፅ እና ንዝረትን በፍጹም አይኑር \n\n"<b>"ደረጃ 1"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ይከልክሉ \n- በፍጹም አጮልቀው አይመልከቱ \n- ድምፅ ወይም ንዝረትን በፍጹም አያደርጉ \n- ከመቆለፊያ ገጽ እና የሁኔታ አሞሌ ይደብቁ \n- በማሳወቂያ ዝርዝር ግርጌ ላይ አሳይ \n\n"<b>"ደረጃ 0"</b>" \n- ሁሉንም የመተግበሪያው ማሳወቂያዎች ያግዱ"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ማሳወቂያዎች"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"እነዚህን ማሳወቂያዎች ከእንግዲህ አያግኙዋቸውም።"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"እነዚህን ማሳወቂያዎች ከእንግዲህ አያገኟቸውም"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> የማሳወቂያ ምድቦች"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ይህ መተግበሪያ የማሳወቂያ ምድቦች የሉትም"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"ከዚህ መተግበሪያ የሚመጡ ማሳወቂያዎች ሊጠፉ አይችሉም"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 ከ<xliff:g id="NUMBER_1">%d</xliff:g> የማሳወቂያ ምድቦች ከዚህ መተግበሪያ</item>
       <item quantity="other">1 <xliff:g id="NUMBER_1">%d</xliff:g> የማሳወቂያ ምድቦች ከዚህ መተግበሪያ</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"የማሳወቂያ መቆጣጠሪያዎች"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"የማሳወቂያ ማሸለቢያ አማራጮች"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 ደቂቃዎች"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 ደቂቃዎች"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ሰዓት"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ሰዓቶች"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ቀልብስ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"ለ<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> አሸልቧል"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one"> %d ሰዓቶች</item>
+      <item quantity="other"> %d ሰዓቶች</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one"> %d ደቂቃዎች</item>
+      <item quantity="other"> %d ደቂቃዎች</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"የባትሪ አጠቃቀም"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ኃይል በሚሞላበት ጊዜ ባትሪ ቆጣቢ አይገኝም"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ባትሪ ቆጣቢ"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"ተካ"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"በጀርባ ውስጥ የሚያሄዱ መተግበሪያዎች"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"በባትሪ እና ውሂብ አጠቃቀም ላይ ዝርዝሮችን ለማግኘት መታ ያድርጉ"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"የተንቀሳቃሽ ስልክ ውሂብ ይጥፋ?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings_car.xml b/packages/SystemUI/res/values-am/strings_car.xml
index 8550c42..5ebb05a 100644
--- a/packages/SystemUI/res/values-am/strings_car.xml
+++ b/packages/SystemUI/res/values-am/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ደህንነትዎን ጠብቀው ያሽከርክሩ"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"የመኪና አነዳድ ሁኔታዎችን በተመለከተ ሙሉ በሙሉ ግንዛቤ ይኑርዎት፣ እንዲሁም የሚመለከታቸውን ሕጎች ሁልጊዜ ያክብሩ። የሚሰጡ አቅጣጫዎች ምናልባት ትክክል ያልሆኑ፣ ያልተሟሉ፣ አደገኛ፣ አግባብ ያልሆኑ፣ የተከለከሉ ወይም አስተዳደራዊ አካባቢዎችን ማቋረጥን የሚያካትቱ ሊሆኑ ይችላሉ። በተጨማሪም የንግድ ሥራ መረጃ ትክክል ያልሆነ ወይም ያልተሟላ ሊሆን ይችላል። ውሂብ ቅጽበታዊ አይደለም፣ እና የአካባቢ ትክክለኛነት ዋስትና ሊሰጥበት አይችልም። መኪና በሚነዱበት ጊዜ የእርስዎን ተንቀሳቃሽ መሣሪያ አይነካኩ ወይም ለAndroid Auto የታለሙ መተግበሪያዎችን አይጠቀሙ።"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"ያልታወቀ"</string>
+    <string name="start_driving" msgid="864023351402918991">"መንዳት ይጀምሩ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 5775436..b622a89 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -156,7 +156,7 @@
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"‏ليست هناك شريحة SIM."</string>
-    <string name="accessibility_cell_data" msgid="5326139158682385073">"بيانات الجوال"</string>
+    <string name="accessibility_cell_data" msgid="5326139158682385073">"بيانات الجوّال"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"تشغيل بيانات الجوال"</string>
     <string name="accessibility_cell_data_off" msgid="443267573897409704">"إيقاف بيانات الجوال"</string>
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ربط البلوتوث."</string>
@@ -244,7 +244,7 @@
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"جارٍ الشحن"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"بيانات شبكات الجيل الثاني والثالث متوقفة مؤقتًا"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"تم إيقاف بيانات شبكة الجيل الرابع مؤقتًا"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"تم إيقاف بيانات الجوال مؤقتًا"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"تم إيقاف بيانات الجوّال مؤقتًا"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"تم إيقاف البيانات مؤقتًا"</string>
     <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"تم الوصول إلى حد البيانات الذي عيَّنته. لم يُعد بإمكانك استخدام بيانات الجوال.\n\nفي حالة الاستئناف، قد يتم تطبيق الرسوم لاستخدام البيانات."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"استئناف"</string>
@@ -318,6 +318,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"المزيد من الإعدادات"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"تم"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"متصل"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"الجهاز متّصل، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"جارٍ الاتصال..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"النطاق"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"نقطة اتصال"</string>
@@ -327,7 +328,7 @@
     <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"استخدام البيانات"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"البيانات المتبقية"</string>
     <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"فوق القيد"</string>
-    <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> مستخدم"</string>
+    <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> مستخدَمة"</string>
     <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="6244915274350490429">"وضع العمل"</string>
@@ -475,6 +476,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"أنت متصل بـ <xliff:g id="APPLICATION">%1$s</xliff:g>، الذي يمكنه مراقبة أنشطتك الشخصية على الشبكة، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"يخضع الملف الشخصي للعمل لإدارة <xliff:g id="ORGANIZATION">%1$s</xliff:g>. تم ربط الملف الشخصي بـ <xliff:g id="APPLICATION">%2$s</xliff:g>، الذي يمكنه مراقبة أنشطة شبكتك، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب.\n\nيمكنك الاتصال بالمشرف للحصول على مزيد من المعلومات."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"يخضع الملف الشخصي للعمل لإدارة <xliff:g id="ORGANIZATION">%1$s</xliff:g>. تم ربط هذا الملف الشخصي بـ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>، الذي يمكنه مراقبة أنشطة شبكتك، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب.\n\nتم ربطك بـ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>، الذي يمكنه مراقبة أنشطة شبكتك الشخصية."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"تم إلغاء القفل لـ <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> قيد التشغيل"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"سيظل الجهاز مقفلاً إلى أن يتم إلغاء قفله يدويًا"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"الحصول على الإشعارات بشكل أسرع"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"الاطلاع عليها قبل إلغاء القفل"</string>
@@ -556,9 +559,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"إيقاف"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"باستخدام عناصر التحكم في إشعار التشغيل، يمكنك تعيين مستوى الأهمية من 0 إلى 5 لإشعارات التطبيق. \n\n"<b>"المستوى 5"</b>" \n- العرض أعلى قائمة الإشعارات \n- يسمح بمقاطعة ملء الشاشة \n- الظهور الخاطف دائمًا \n\n"<b>"المستوى 4"</b>" \n- منع مقاطعة ملء الشاشة \n- الظهور الخاطف دائمًا \n\n"<b>"المستوى 3"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n\n"<b>"المستوى 2"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n- عدم إصدار أصوات واهتزاز \n\n"<b>"المستوى 1"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n- عدم إصدار أصوات أو اهتزاز أبدًا \n- الإخفاء من شاشة التأمين وشريط الحالة \n- العرض أسفل قائمة الإشعارات \n\n"<b>"المستوى 0"</b>" \n- حظر جميع الإشعارات من التطبيق"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"الإشعارات"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"لن تتلقى هذه الإشعارات بعد الآن."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"لن تتلقى هذه الإشعارات بعد الآن."</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> فئة إشعار"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"لا يحتوي هذا التطبيق على فئات إشعار"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"لا يمكن إيقاف الإشعارات من هذا التطبيق"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="zero">1 من إجمالي <xliff:g id="NUMBER_1">%d</xliff:g> فئة إشعار من هذا التطبيق</item>
       <item quantity="two">1 من إجمالي فئتي إشعار (<xliff:g id="NUMBER_1">%d</xliff:g>) من هذا التطبيق</item>
@@ -586,12 +590,24 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"عناصر التحكم في الإشعارات"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"خيارات تأجيل الإشعارات"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"١٥ دقيقة"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"٣۰ دقيقة"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"ساعة واحدة"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"ساعتان"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"تراجع"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"تم تأجيل الإشعار لمدة <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="zero">‏%d ساعة</item>
+      <item quantity="two">‏ساعتان (%d)</item>
+      <item quantity="few">‏%d ساعات</item>
+      <item quantity="many">‏%d ساعة</item>
+      <item quantity="other">‏%d ساعة</item>
+      <item quantity="one">ساعة واحدة</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="zero">‏%d دقيقة</item>
+      <item quantity="two">‏دقيقتان (%d)</item>
+      <item quantity="few">‏%d دقائق</item>
+      <item quantity="many">‏%d دقيقة</item>
+      <item quantity="other">‏%d دقيقة</item>
+      <item quantity="one">دقيقة واحدة</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"استخدام البطارية"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"وضع توفير شحن البطارية غير متاح أثناء الشحن."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"توفير شحن البطارية"</string>
@@ -643,7 +659,7 @@
     <string name="volume_dnd_silent" msgid="4363882330723050727">"اختصار أزرار مستوى الصوت"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"تعطيل \"عدم الإزعاج\" عند رفع مستوى الصوت"</string>
     <string name="battery" msgid="7498329822413202973">"البطارية"</string>
-    <string name="clock" msgid="7416090374234785905">"ساعة"</string>
+    <string name="clock" msgid="7416090374234785905">"الساعة"</string>
     <string name="headset" msgid="4534219457597457353">"سماعة الرأس"</string>
     <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"تم توصيل سماعات رأس"</string>
     <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"تم توصيل سماعات رأس"</string>
@@ -781,4 +797,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"استبدال"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"التطبيقات التي تعمل في الخلفية"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"انقر للحصول على تفاصيل حول البطارية واستخدام البيانات"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"هل تريد إيقاف تشغيل بيانات الجوال؟"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings_car.xml b/packages/SystemUI/res/values-ar/strings_car.xml
index 0f315a4..7fec955 100644
--- a/packages/SystemUI/res/values-ar/strings_car.xml
+++ b/packages/SystemUI/res/values-ar/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"القيادة بأمان"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"‏عليك التعرف بشكل تام على ظروف القيادة والالتزام بالقوانين السارية. ويمكن أن تكون الاتجاهات غير دقيقة أو غير مكتملة أو خطيرة أو غير مناسبة أو محظورة أو تتضمن عبور مناطق إدارية. ويمكن أن تكون معلومات الأنشطة التجارية أيضًا غير دقيقة أو غير مكتملة. ولا يتم نشر البيانات في الوقت الفعلي، كما لا يمكن ضمان دقة المواقع. ولا تتعامل مع جهازك الجوّال أو تستخدم تطبيقات ليست متوافقة مع Android Auto أثناء القيادة."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"غير معروف"</string>
+    <string name="start_driving" msgid="864023351402918991">"بدء القيادة"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 40bd32a..3e3d331 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Digər ayarlar"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Hazır"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Qoşulu"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Qoşuldu, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Qoşulur..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Birləşmə"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə qoşulmusunuz və o, e-məktublar, tətbiq və veb saytlar daxil olmaqla şəxsi şəbəkə fəaliyyətinizə nəzarət edə bilər."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"İş profili <xliff:g id="ORGANIZATION">%1$s</xliff:g> tərəfindən idarə olunur. Profil e-poçt, tətbiq və veb saytlar da daxil olmaqla şəbəkə fəaliyyətinə nəzarət edən <xliff:g id="APPLICATION">%2$s</xliff:g> tətbiqinə qoşuludur.\n\nƏtraflı məlumat üçün admin ilə əlaqə saxlayın."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"İş profili <xliff:g id="ORGANIZATION">%1$s</xliff:g> tərəfindən idarə edilir. Profil e-poçt, tətbiq və veb saytlar da daxil olmaqla şəbəkə fəaliyyətinə nəzarət edən <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> tətbiqinə qoşuludur.\n\nEyni zamanda şəxsi şəbəkə fəaliyyətinə nəzarət edən <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> tətbiqinə qoşulusunuz."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> üçün kiliddən çıxarıldı"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> işləyir"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Device will stay locked until you manually unlock"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Bildirişləri daha sürətlə əldə edin"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Kiliddən çıxarmadan öncə onları görün"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Deaktiv"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Enerji bildiriş nəzarəti ilə, tətbiq bildirişləri üçün əhəmiyyət səviyyəsini 0-dan 5-ə kimi ayarlaya bilərsiniz. \n\n"<b>"Səviyyə 5"</b>" \n- Bildiriş siyahısının yuxarı hissəsində göstərin \n- Tam ekran kəsintisinə icazə verin \n- Hər zaman izləyin \n\n"<b>"Səviyyə 4"</b>" \n- Tam ekran kəsintisinin qarşısını alın \n- Hər zaman izləyin \n\n"<b>"Level 3"</b>" \n- Tam ekran kəsintisinin qarşısını alın \n- Heç vaxt izləməyin \n\n"<b>"Level 2"</b>" \n- Tam ekran kəsintisinin qarşısını alın \n- Heç vaxt izləməyin \n- Heç vaxt səsliyə və ya vibrasiyaya qoymayın \n\n"<b>"Səviyyə 1"</b>" \n- Prevent full screen interruption \n- Heç vaxt izləməyin \n- Heç vaxt səsliyə və ya vibrasiyaya qoymayın \n- Ekran kilidi və ya status panelindən gizlədin \n- Bildiriş siyahısının yuxarı hissəsində göstərin \n\n"<b>"Səviyyə 0"</b>" \n- Bütün bildirişləri tətbiqdən blok edin"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Bildirişlər"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Bu bildirişlər daha sizə göndərilməyəcək."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Bu bildirişlər daha sizə göndərilməyəcək"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> bildiriş kateqoriyaları"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Bu tətbiqin bildiriş kateqoriyası yoxdur"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Bu tətbiqin bildirişləri deaktiv edilə bilməz"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Bu tətbiqin <xliff:g id="NUMBER_1">%d</xliff:g> bildiriş kateqoriyasından 1 kanal</item>
       <item quantity="one">Bu tətbiqin <xliff:g id="NUMBER_0">%d</xliff:g> bildiriş kateqoriyasından 1 kanal</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"bildiriş nəzarəti"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"bildiriş təxirə salma seçimləri"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 dəqiqə"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 dəqiqə"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 saat"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 saat"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"GERİ QAYTARIN"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> üçün təxirə salınıb"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other"> %d saat</item>
+      <item quantity="one">%d saat</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d dəqiqə</item>
+      <item quantity="one">%d dəqiqə</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Batareya istifadəsi"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Enerji Qənaəti doldurulma zamanı əlçatan deyil"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Enerji Qənaəti"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Əvəz edin"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Arxa fonda işləyən tətbiqlər"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Batareya və data istifadəsi haqqında ətraflı məlumat üçün klikləyin"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Mobil data söndürülsün?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings_car.xml b/packages/SystemUI/res/values-az/strings_car.xml
index 9ac7ce0..0b49eda 100644
--- a/packages/SystemUI/res/values-az/strings_car.xml
+++ b/packages/SystemUI/res/values-az/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Təhlükəsiz sürün"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Yol şəraitindən tam xəbərdar olun və hər zaman tətbiq olunan qaydalara riayət edin. İstiqamətlər qeyri-dəqiq, natamam, təhlükəli, uyğun olmayan, qadağan edilmiş və ya inzibati sahələrə keçid ilə nəticələnə bilər. Biznes məlumatı da qeyri-dəqiq və ya natamam ola bilər. Data real vaxtda deyil və məkan dəqiqliyinə zəmanət verilmir. Avtomobil idarə edərkən mobil cihazınızı elinizə almayın və ya Android Avto üçün nəzərdə tutulmamış tətbiqlərdən istifadə etməyin."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Naməlum"</string>
+    <string name="start_driving" msgid="864023351402918991">"Sürməyə başlayın"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 0b44eb5..42a3aec 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -76,7 +76,7 @@
     <string name="screenshot_failed_title" msgid="705781116746922771">"Nije moguće napraviti snimak ekrana."</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Došlo je do problema pri čuvanju snimka ekrana."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Čuvanje snimka ekrana nije uspelo zbog ograničenog memorijskog prostora."</string>
-    <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Aplikacija ili organizacija ne dozvoljavaju pravljenje snimaka ekrana."</string>
+    <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Aplikacija ili organizacija ne dozvoljavaju pravljenje snimaka ekrana"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prenosa datoteka"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Priključi kao medija plejer (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Priključi kao kameru (PTP)"</string>
@@ -91,7 +91,7 @@
     <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
     <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Glasovna pomoć"</string>
     <string name="accessibility_unlock_button" msgid="128158454631118828">"Otključajte"</string>
-    <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Dugme za otključavanje, čeka se na otisak prsta"</string>
+    <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"Čeka se otisak prsta"</string>
     <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Otključaj bez korišćenja otiska prsta"</string>
     <string name="unlock_label" msgid="8779712358041029439">"otključaj"</string>
     <string name="phone_label" msgid="2320074140205331708">"otvori telefon"</string>
@@ -153,11 +153,12 @@
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"Nema SIM kartice."</string>
-    <string name="accessibility_cell_data" msgid="7080312242791850520">"Podaci za mobilne uređaje"</string>
-    <string name="accessibility_cell_data_on" msgid="4310018593519761767">"Podaci za mobilne uređaje su uključeni"</string>
-    <string name="accessibility_cell_data_off" msgid="8000803571751407635">"Podaci za mobilne uređaje su isključeni"</string>
+    <string name="accessibility_cell_data" msgid="5326139158682385073">"Mobilni podaci"</string>
+    <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Mobilni podaci su uključeni"</string>
+    <string name="accessibility_cell_data_off" msgid="443267573897409704">"Mobilni podaci su isključeni"</string>
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth privezivanje."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Režim rada u avionu."</string>
+    <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN je uključen."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Nema SIM kartice."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Promena mreže mobilnog operatera."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Otvori detalje o bateriji"</string>
@@ -165,7 +166,7 @@
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Baterija se puni, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procenata."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistemska podešavanja."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obaveštenja."</string>
-    <string name="notification_shelf_content_description" msgid="5511922384591583913">"Kontejner preklopnog menija za obaveštenja"</string>
+    <string name="accessibility_overflow_action" msgid="5681882033274783311">"Pogledajte sva obaveštenja"</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Obriši obaveštenje."</string>
     <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS je omogućen."</string>
     <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Učitavanje GPS-a."</string>
@@ -237,13 +238,12 @@
     <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Ušteda podataka je isključena."</string>
     <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Ušteda podataka je uključena."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Osvetljenost ekrana"</string>
-    <!-- no translation found for accessibility_ambient_display_charging (9084521679384069087) -->
-    <skip />
+    <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Puni se"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G podaci su pauzirani"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G podaci su pauzirani"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"Mobilni podaci su pauzirani"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Mobilni podaci su pauzirani"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Podaci su pauzirani"</string>
-    <string name="data_usage_disabled_dialog" msgid="1841738975235283398">"Ograničenje potrošnje podataka koje ste podesili je dostignuto. Više ne koristite mobilne podatke.\n\nAko nastavite, možda će biti naplaćeni troškovi za potrošnju podataka."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Dostigli se ograničenje za podatke koje ste podesili. Više ne koristite mobilne podatke.\n\nAko nastavite, možda će važiti tarife za potrošnju podataka."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Nastavi"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nema internet veze"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi je povezan"</string>
@@ -279,7 +279,7 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Osvetljenost"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Automatska rotacija"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"Automatsko rotiranje ekrana"</string>
-    <string name="accessibility_quick_settings_rotation_value" msgid="1428962304214992318">"Podesi na <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"Režim <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Rotacija je zaključana"</string>
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Vertikalni prikaz"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Horizontalni prikaz"</string>
@@ -317,7 +317,7 @@
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Obaveštenja"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lampa"</string>
-    <string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Podaci za mobilne uređaje"</string>
+    <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilni podaci"</string>
     <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Potrošnja podataka"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Preostala količina podataka"</string>
     <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Preko ograničenja"</string>
@@ -337,7 +337,6 @@
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Pokretanje aplikacije <xliff:g id="APP">%s</xliff:g> nije uspelo."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacija <xliff:g id="APP">%s</xliff:g> je onemogućena u bezbednom režimu."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Obriši sve"</string>
-    <string name="recents_incompatible_app_message" msgid="5075812958564082451">"Aplikacija ne podržava podeljeni ekran"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Prevucite ovde da biste koristili razdeljeni ekran"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podeli horizontalno"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Podeli vertikalno"</string>
@@ -363,7 +362,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Manje hitna obaveštenja su u nastavku"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite ponovo da biste otvorili"</string>
     <string name="keyguard_unlock" msgid="8043466894212841998">"Prevucite nagore da biste otključali"</string>
-    <string name="do_disclosure_generic" msgid="8498005633306135779">"Ovim uređajem se upravlja"</string>
+    <string name="do_disclosure_generic" msgid="5615898451805157556">"Ovim uređajem upravlja organizacija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Prevucite od ikone za telefon"</string>
     <string name="voice_hint" msgid="8939888732119726665">"Prevucite od ikone za glasovnu pomoć"</string>
@@ -401,7 +400,7 @@
     <string name="user_logout_notification_text" msgid="3350262809611876284">"Odjavite aktuelnog korisnika"</string>
     <string name="user_logout_notification_action" msgid="1195428991423425062">"ODJAVI KORISNIKA"</string>
     <string name="user_add_user_title" msgid="4553596395824132638">"Dodajete novog korisnika?"</string>
-    <string name="user_add_user_message_short" msgid="2161624834066214559">"Kada dodate novog korisnika, ta osoba treba da podesi sopstveni prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string>
+    <string name="user_add_user_message_short" msgid="2161624834066214559">"Kada dodate novog korisnika, ta osoba treba da podesi svoj prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string>
     <string name="user_remove_user_title" msgid="4681256956076895559">"Želite li da uklonite korisnika?"</string>
     <string name="user_remove_user_message" msgid="1453218013959498039">"Sve aplikacije i podaci ovog korisnika će biti izbrisani."</string>
     <string name="user_remove_user_remove" msgid="7479275741742178297">"Ukloni"</string>
@@ -416,13 +415,40 @@
     <string name="profile_owned_footer" msgid="8021888108553696069">"Profil se možda nadgleda"</string>
     <string name="vpn_footer" msgid="2388611096129106812">"Mreža se možda nadgleda"</string>
     <string name="branded_vpn_footer" msgid="2168111859226496230">"Mreža se možda nadgleda"</string>
-    <string name="monitoring_title_device_owned" msgid="7121079311903859610">"Nadgledanje uređaja"</string>
+    <string name="quick_settings_disclosure_management_monitoring" msgid="6645176135063957394">"Organizacija upravlja ovim uređajem i može da nadgleda mrežni saobraćaj"</string>
+    <string name="quick_settings_disclosure_named_management_monitoring" msgid="370622174777570853">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> upravlja ovim uređajem i može da nadgleda mrežni saobraćaj"</string>
+    <string name="quick_settings_disclosure_management_named_vpn" msgid="1085137869053332307">"Uređajem upravlja organizacija i povezan je sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="6290456493852584017">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je sa aplikacijom <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_management" msgid="3294967280853150271">"Uređajem upravlja organizacija"</string>
+    <string name="quick_settings_disclosure_named_management" msgid="1059403025094542908">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_management_vpns" msgid="3698767349925266482">"Uređajem upravlja organizacija i povezan je sa VPN-ovima"</string>
+    <string name="quick_settings_disclosure_named_management_vpns" msgid="7777821385318891527">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je sa VPN-ovima"</string>
+    <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="5125463987558278215">"Organizacija može da prati mrežni saobraćaj na profilu za Work"</string>
+    <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8973606847896650284">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može da nadgleda mrežni saobraćaj na profilu za Work"</string>
+    <string name="quick_settings_disclosure_monitoring" msgid="679658227269205728">"Mreža se možda nadgleda"</string>
+    <string name="quick_settings_disclosure_vpns" msgid="8170318392053156330">"Uređaj je povezan sa VPN-ovima"</string>
+    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="3494535754792751741">"Profil za Work je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4467456202486569906">"Lični profil je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_vpn" msgid="6943724064780847080">"Uređaj je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_device_owned" msgid="1652495295941959815">"Upravljanje uređajima"</string>
     <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"Nadgledanje profila"</string>
     <string name="monitoring_title" msgid="169206259253048106">"Nadgledanje mreže"</string>
     <string name="monitoring_subtitle_vpn" msgid="876537538087857300">"VPN"</string>
-    <string name="monitoring_subtitle_network_logging" msgid="5569072711320784030">"Evidentiranje mreže"</string>
+    <string name="monitoring_subtitle_network_logging" msgid="3341264304793193386">"Evidentiranje mreže"</string>
+    <string name="monitoring_subtitle_ca_certificate" msgid="3874151893894355988">"CA sertifikati"</string>
     <string name="disable_vpn" msgid="4435534311510272506">"Onemogući VPN"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"Prekini vezu sa VPN-om"</string>
+    <string name="monitoring_button_view_policies" msgid="100913612638514424">"Prikaži smernice"</string>
+    <string name="monitoring_description_named_management" msgid="5281789135578986303">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od administratora."</string>
+    <string name="monitoring_description_management" msgid="4573721970278370790">"Uređajem upravlja organizacija.\n\nAdministrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od administratora."</string>
+    <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"Organizacija je na ovom uređaju instalirala autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
+    <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"Organizacija je na profilu za Work instalirala autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
+    <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"Na ovom uređaju je instaliran autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
+    <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"Administrator je uključio evidentiranje mreže, koje prati saobraćaj na uređaju."</string>
+    <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"Povezani ste sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>, koja može da nadgleda aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
+    <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"Povezani ste sa aplikacijama <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g>, koje mogu da nadgledaju aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
+    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"Profil za Work je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>, koja može da nadgleda aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
+    <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"Lični profil je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>, koja može da nadgleda aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
     <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"Uređajem upravlja <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g>."</string>
     <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> koristi <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> za upravljanje uređajem."</string>
     <string name="monitoring_description_do_body" msgid="3639594537660975895">"Administrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima."</string>
@@ -431,20 +457,24 @@
     <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"Povezani ste sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>, koja može da nadgleda aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"Otvorite podešavanja VPN-a"</string>
+    <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
+    <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"Otvorite pouzdane akreditive"</string>
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"Administrator je uključio evidentiranje mreže, koje prati saobraćaj na uređaju.\n\nKontaktirajte administratora za više informacija."</string>
     <string name="monitoring_description_vpn" msgid="4445150119515393526">"Dali ste dozvolu aplikaciji da podešava VPN vezu.\n\nTa aplikacija može da nadgleda aktivnosti na uređaju i mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> upravlja profilom za Work.\n\nAdministrator može da prati aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove.\n\nKontaktirajte administratora za više informacija.\n\nPovezani ste i sa VPN-om, koji može da prati aktivnosti na mreži."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
-    <string name="monitoring_description_app" msgid="6259179342284742878">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može da nadgleda aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
+    <string name="monitoring_description_app" msgid="1828472472674709532">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može da nadgleda aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
     <string name="monitoring_description_app_personal" msgid="484599052118316268">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može da nadgleda aktivnosti na ličnoj mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može da nadgleda aktivnosti na ličnoj mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
-    <string name="monitoring_description_app_work" msgid="7777228449969022305">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> upravlja profilom za Work. On je povezan sa aplikacijom <xliff:g id="APPLICATION">%2$s</xliff:g>, koja može da prati aktivnosti na poslovnoj mreži, uključujući imejlove, aplikacije i veb-sajtove.\n\nKontaktirajte administratora za više informacija."</string>
-    <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"Profilom za Work upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je sa aplikacijom <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, koja može da nadgleda aktivnosti na poslovnoj mreži, uključujući imejlove, aplikacije i veb-sajtove.\n\nPovezani ste i sa aplikacijom <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, koja može da nadgleda aktivnosti na ličnoj mreži."</string>
+    <string name="monitoring_description_app_work" msgid="4612997849787922906">"Profilom za Work upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je sa aplikacijom <xliff:g id="APPLICATION">%2$s</xliff:g>, koja može da nadgleda aktivnosti na poslovnoj mreži, uključujući imejlove, aplikacije i veb-sajtove.\n\nViše informacija potražite od administratora."</string>
+    <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Profilom za Work upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je sa aplikacijom <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, koja može da nadgleda aktivnosti na poslovnoj mreži, uključujući imejlove, aplikacije i veb-sajtove.\n\nPovezani ste i sa aplikacijom <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, koja može da nadgleda aktivnosti na ličnoj mreži."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Otključano za korisnika <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Funkcija <xliff:g id="TRUST_AGENT">%1$s</xliff:g> je pokrenuta"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Uređaj će ostati zaključan dok ga ne otključate ručno"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Brže dobijajte obaveštenja"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Pregledajte ih pre otključavanja"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ne, hvala"</string>
-    <string name="hidden_notifications_setup" msgid="41079514801976810">"Podesi"</string>
+    <string name="hidden_notifications_setup" msgid="41079514801976810">"Aktiviraj"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="volume_zen_end_now" msgid="3179845345429841822">"Prekini odmah"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Proširi"</string>
@@ -470,10 +500,8 @@
     <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Dodirnite da biste uključili zvuk."</string>
     <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Dodirnite da biste podesili na vibraciju. Zvuk usluga pristupačnosti će možda biti isključen."</string>
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Dodirnite da biste isključili zvuk. Zvuk usluga pristupačnosti će možda biti isključen."</string>
-    <!-- no translation found for volume_stream_content_description_vibrate_a11y (6427727603978431301) -->
-    <skip />
-    <!-- no translation found for volume_stream_content_description_mute_a11y (8995013018414535494) -->
-    <skip />
+    <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Dodirnite da biste podesili na vibraciju."</string>
+    <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Dodirnite da biste isključili zvuk."</string>
     <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Kontrole za jačinu zvuka (%s) su prikazane. Prevucite nagore da biste ih odbacili."</string>
     <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Kontrole za jačinu zvuka su sakrivene"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Tjuner za korisnički interfejs sistema"</string>
@@ -523,24 +551,36 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Isključeno"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Pomoću naprednih kontrola za obaveštenja možete da podesite nivo važnosti od 0. do 5. za obaveštenja aplikacije. \n\n"<b>"5. nivo"</b>" \n– Prikazuju se u vrhu liste obaveštenja \n- Dozvoli prekid režima celog ekrana \n– Uvek zaviruj \n\n"<b>"4. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Uvek zaviruj \n\n"<b>"3. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n\n"<b>"2. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n– Nikada ne proizvodi zvuk ili vibraciju \n\n"<b>"1. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n– Nikada ne proizvodi zvuk ili vibraciju \n– Sakrij na zaključanom ekranu i statusnoj traci \n– Prikazuju se u dnu liste obaveštenja \n\n"<b>"0. nivo"</b>" \n– Blokiraj sva obaveštenja iz aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obaveštenja"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Više nećete da dobijate ova obaveštenja."</string>
-    <plurals name="notification_num_channels_desc" formatted="false" msgid="8808748716499517938">
-      <item quantity="one">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije iz ove aplikacije</item>
-      <item quantity="few">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije iz ove aplikacije</item>
-      <item quantity="other">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorija iz ove aplikacije</item>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Više nećete dobijati ova obaveštenja"</string>
+    <string name="notification_num_channels" msgid="2048144408999179471">"Kategorija obaveštenja: <xliff:g id="NUMBER">%d</xliff:g>"</string>
+    <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ova aplikacija nema kategorije obaveštenja"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
+    <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
+      <item quantity="one">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije obaveštenja za ovu aplikaciju</item>
+      <item quantity="few">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije obaveštenja za ovu aplikaciju</item>
+      <item quantity="other">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorija obaveštenja za ovu aplikaciju</item>
     </plurals>
+    <string name="notification_channels_list_desc_2" msgid="6214732715833946441">"<xliff:g id="CHANNEL_NAME_1">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2">%2$s</xliff:g>"</string>
+    <plurals name="notification_channels_list_desc_2_and_others" formatted="false" msgid="2747813553355336157">
+      <item quantity="one"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> i još <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+      <item quantity="few"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> i još <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+      <item quantity="other"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> i još <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+    </plurals>
+    <string name="notification_channel_controls_opened_accessibility" msgid="6553950422055908113">"Kontrole obaveštenja za otvaranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="notification_channel_controls_closed_accessibility" msgid="7521619812603693144">"Kontrole obaveštenja za zatvaranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="notification_channel_switch_accessibility" msgid="3420796005601900717">"Dozvoli obaveštenja sa ovog kanala"</string>
     <string name="notification_all_categories" msgid="5407190218055113282">"Sve kategorije"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Još podešavanja"</string>
+    <string name="notification_app_settings" msgid="3743278649182392015">"Prilagodite: <xliff:g id="SUB_CATEGORY">%1$s</xliff:g>"</string>
     <string name="notification_done" msgid="5279426047273930175">"Gotovo"</string>
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kontrole obaveštenja"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opcije za odlaganje obaveštenja"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 sat"</string>
-    <string name="snooze_option_dont_snooze" msgid="655446566007801922">"Ne odlaži"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"OPOZOVI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odloženo je za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Potrošnja baterije"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ušteda baterije nije dostupna tokom punjenja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ušteda baterije"</string>
@@ -553,8 +593,8 @@
     <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Taster sa strelicom nalevo"</string>
     <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Taster sa strelicom nadesno"</string>
     <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Taster sa centralnom strelicom"</string>
-    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulator"</string>
-    <string name="keyboard_key_space" msgid="2499861316311153293">"Taster za razmak"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Razmak"</string>
     <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
     <string name="keyboard_key_backspace" msgid="1559580097512385854">"Taster za brisanje unazad"</string>
     <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Taster za reprodukciju/pauziranje"</string>
@@ -620,7 +660,7 @@
   </string-array>
     <string name="menu_ime" msgid="4998010205321292416">"Prebacivač za tastaturu"</string>
     <string name="save" msgid="2311877285724540644">"Sačuvaj"</string>
-    <string name="reset" msgid="2448168080964209908">"Ponovo postavi"</string>
+    <string name="reset" msgid="2448168080964209908">"Resetuj"</string>
     <string name="adjust_button_width" msgid="6138616087197632947">"Prilagodi širinu dugmeta"</string>
     <string name="clipboard" msgid="1313879395099896312">"Privremena memorija"</string>
     <string name="accessibility_key" msgid="5701989859305675896">"Prilagođeno dugme za navigaciju"</string>
@@ -666,6 +706,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"Obaveštenja za <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacija možda neće funkcionisati sa podeljenim ekranom."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacija ne podržava podeljeni ekran."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Aplikacija možda neće funkcionisati na sekundarnom ekranu."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Otvori Podešavanja."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Otvori Brza podešavanja."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Zatvori Brza podešavanja."</string>
@@ -680,6 +722,17 @@
     <string name="pip_phone_expand" msgid="5889780005575693909">"Proširi"</string>
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Umanji"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Zatvori"</string>
+    <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Prevucite nadole da biste odbili"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Meni Slika u slici"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> je slika u slici"</string>
+    <string name="pip_notification_message" msgid="4171698133469539591">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da biste otvorili podešavanja i isključili je."</string>
+    <string name="pip_play" msgid="1417176722760265888">"Pusti"</string>
+    <string name="pip_pause" msgid="8881063404466476571">"Pauziraj"</string>
+    <string name="pip_skip_to_next" msgid="1948440006726306284">"Pređi na sledeće"</string>
+    <string name="pip_skip_to_prev" msgid="1955311326688637914">"Pređi na prethodno"</string>
+    <string name="thermal_shutdown_title" msgid="4458304833443861111">"Telefon se isključio zbog toplote"</string>
+    <string name="thermal_shutdown_message" msgid="9006456746902370523">"Telefon sada normalno radi"</string>
+    <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"Telefon je bio prevruć, pa se isključio da se ohladi. Sada radi normalno.\n\nTelefon može previše da se ugreje ako:\n	• Koristite aplikacije koje zahtevaju puno resursa (npr. video igre, video ili aplikacije za navigaciju)\n	• Preuzimate/otpremate velike datoteke\n	• Koristite telefon na visokoj temperaturi"</string>
     <string name="high_temp_title" msgid="4589508026407318374">"Telefon se zagrejao"</string>
     <string name="high_temp_notif_message" msgid="5642466103153429279">"Neke funkcije su ograničene dok se telefon ne ohladi"</string>
     <string name="high_temp_dialog_message" msgid="6840700639374113553">"Telefon će automatski pokušati da se ohladi. I dalje ćete moći da koristite telefon, ali će sporije reagovati.\n\nKada se telefon ohladi, normalno će raditi."</string>
@@ -688,7 +741,7 @@
     <string name="lockscreen_unlock_left" msgid="2043092136246951985">"I leva prečica otključava"</string>
     <string name="lockscreen_unlock_right" msgid="1529992940510318775">"I desna prečica otključava"</string>
     <string name="lockscreen_none" msgid="4783896034844841821">"Ništa"</string>
-    <string name="tuner_launch_app" msgid="1527264114781925348">"Pokretanje <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="tuner_launch_app" msgid="1527264114781925348">"Pokreni <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="tuner_other_apps" msgid="4726596850501162493">"Druge aplikacije"</string>
     <string name="tuner_circle" msgid="2340998864056901350">"Krug"</string>
     <string name="tuner_plus" msgid="6792960658533229675">"Plus"</string>
@@ -702,9 +755,19 @@
     <string name="notification_channel_general" msgid="4525309436693914482">"Opšte poruke"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Memorijski prostor"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant aplikacije"</string>
-    <!-- no translation found for pip_menu_title (3328510504196964712) -->
-    <skip />
     <string name="instant_apps_message" msgid="8116608994995104836">"Instant aplikacije ne zahtevaju instalaciju."</string>
     <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Idi na veb"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobilni podaci"</string>
+    <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je isključen"</string>
+    <string name="bt_is_off" msgid="2640685272289706392">"Bluetooth je isključen"</string>
+    <string name="dnd_is_off" msgid="6167780215212497572">"Režim Ne uznemiravaj je isključen"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"Automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>) je uključilo režim Ne uznemiravaj."</string>
+    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"Aplikacija (<xliff:g id="ID_1">%s</xliff:g>) je uključila režim Ne uznemiravaj."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"Automatsko pravilo ili aplikacija su uključili režim Ne uznemiravaj."</string>
+    <string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="qs_dnd_keep" msgid="1825009164681928736">"Zadrži"</string>
+    <string name="qs_dnd_replace" msgid="8019520786644276623">"Zameni"</string>
+    <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacije pokrenute u pozadini"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_car.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_car.xml
index f45af7c..ac65171 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings_car.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vozite bezbedno"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Uvek vodite računa o uslovima vožnje i uvek poštujte primenjive zakone. Uputstva mogu da budu netačna, nepotpuna, opasna, neprikladna ili zabranjena, odnosno da podrazumevaju prelazak između administrativnih oblasti. I podaci o preduzeću mogu da budu netačni ili nepotpuni. Podaci ne nastaju u realnom vremenu i ne možemo da garantujemo preciznost lokacije. Nemojte da upotrebljavate mobilni uređaj niti da koristite aplikacije koje nisu namenjene za Android Auto tokom vožnje."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Nepoznato"</string>
+    <string name="start_driving" msgid="864023351402918991">"Počnite da vozite"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
index 8b01a83..6be4046 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
@@ -19,15 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Slika u slici"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program bez naslova)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Zatvori PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Ceo ekran"</string>
-    <string name="pip_play" msgid="674145557658227044">"Pusti"</string>
-    <string name="pip_pause" msgid="8412075640017218862">"Pauziraj"</string>
-    <string name="pip_hold_home" msgid="340086535668778109"><b>"POČETNI EKRAN"</b>" kont. PIP"</string>
-    <string name="pip_onboarding_title" msgid="7850436557670253991">"Slika u slici"</string>
-    <string name="pip_onboarding_description" msgid="4028124563309465267">"Na ovaj način će video biti prikazan dok ne pustite neki drugi. Pritisnite i zadržite "<b>"POČETNA"</b>" da biste ga kontrolisali."</string>
-    <string name="pip_onboarding_button" msgid="3957426748484904611">"Važi"</string>
-    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Odbaci"</string>
-  <string-array name="recents_tv_blacklist_array">
-  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 0796cff..d48ee4f 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -77,7 +77,7 @@
     <string name="screenshot_failed_title" msgid="705781116746922771">"Не атрымалася зрабiць скрыншот."</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Падчас захавання скрыншота адбылася памылка."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Немагчыма захаваць здымак экрана, бо мала месца ў памяці."</string>
-    <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Рабіць здымкі экрана не дазваляе праграма ці ваша арганізацыя."</string>
+    <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Рабіць здымкі экрана не дазваляе праграма ці ваша арганізацыя"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Парам. перадачы файлаў па USB"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Падлучыць як медыяпрайгравальнік (ССП)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Падлучыць як камеру (PTP)"</string>
@@ -92,7 +92,7 @@
     <string name="accessibility_phone_button" msgid="6738112589538563574">"Тэлефон"</string>
     <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Галасавая дапамога"</string>
     <string name="accessibility_unlock_button" msgid="128158454631118828">"Разблакiраваць"</string>
-    <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Кнопка разблакіроўкі, чаканне адбітка пальца"</string>
+    <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"Чаканне ўводу даных адбітка пальца"</string>
     <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Разблакіроўка без выкарыстання адбітка пальца"</string>
     <string name="unlock_label" msgid="8779712358041029439">"разблакiраваць"</string>
     <string name="phone_label" msgid="2320074140205331708">"адкрыць тэлефон"</string>
@@ -154,11 +154,12 @@
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"Няма SIM-карты."</string>
-    <string name="accessibility_cell_data" msgid="7080312242791850520">"Сотавая перадача даных"</string>
-    <string name="accessibility_cell_data_on" msgid="4310018593519761767">"Сотавая перадача даных уключана"</string>
-    <string name="accessibility_cell_data_off" msgid="8000803571751407635">"Мабільная перадача даных адключана"</string>
+    <string name="accessibility_cell_data" msgid="5326139158682385073">"Мабільная перадача даных"</string>
+    <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Мабільная перадача даных уключана"</string>
+    <string name="accessibility_cell_data_off" msgid="443267573897409704">"Мабільная перадача даных выключана"</string>
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Сувязь па Bluetooth."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Рэжым палёту."</string>
+    <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN уключана."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Няма SIM-карты."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Змяненне аператара сеткі."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Паказаць падрабязную інфармацыю пра акумулятар"</string>
@@ -168,7 +169,7 @@
     <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="notification_shelf_content_description" msgid="5511922384591583913">"Кантэйнер для апавяшчэнняў пры перапаўненні"</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>
     <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Атрыманне GPS."</string>
@@ -231,7 +232,7 @@
     <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"Інверсія колеру адключаецца."</string>
     <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"Інверсія колеру ўключаецца."</string>
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Мабільны хот-спот выключаецца."</string>
-    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Мабільны хот-спот ўключаецца."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Мабільная кропка доступу ўключаная."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Трансляцыя экрана спынена."</string>
     <string name="accessibility_quick_settings_work_mode_off" msgid="7045417396436552890">"Рэжым працы выкл."</string>
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Рэжым працы ўкл."</string>
@@ -240,13 +241,12 @@
     <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Эканомія трафіку адключана."</string>
     <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Эканомія трафіку ўключана."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Яркасць дысплэя"</string>
-    <!-- no translation found for accessibility_ambient_display_charging (9084521679384069087) -->
-    <skip />
+    <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Ідзе зарадка"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Перадача даных 2G-3G прыпынена"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Перадача даных 4G прыпынена"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"Мабільная перадача даных прыпынена"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Мабільная перадача даных прыпынена"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Перадача даных прыпынена"</string>
-    <string name="data_usage_disabled_dialog" msgid="1841738975235283398">"Ліміт даных, які вы задалі, быў дасягнуты. Вы больш не выкарыстоўваеце сотавую перадачу даных.\n\nКалі вы ўзновіце карыстанне, можа спаганяцца плата за выкарыстанне трафіка."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Ліміт даных, які вы задалі, быў дасягнуты. Вы больш не выкарыстоўваеце мабільную перадачу даных.\n\nКалі вы ўзновіце карыстанне, можа спаганяцца плата за выкарыстанне трафіка."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Узнавіць"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Няма падключэння да Iнтэрнэту"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi падключаны"</string>
@@ -283,7 +283,7 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Яркасць"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Аўтапаварот"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"Аўтаматычны паварот экрана"</string>
-    <string name="accessibility_quick_settings_rotation_value" msgid="1428962304214992318">"Усталявана на <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"Рэжым <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Паварот заблакіраваны"</string>
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Кніжная арыентацыя"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Альбомная арыентацыя"</string>
@@ -318,10 +318,10 @@
     <string name="quick_settings_connected" msgid="1722253542984847487">"Падлучана"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Падлучэнне..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Мадэм"</string>
-    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Хот-спот"</string>
+    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Кропка доступу"</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="8575062783675171695">"Мабільная перадача даных"</string>
+    <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мабільная перадача даных"</string>
     <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Выкарыстанне трафіку"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Засталося трафіку"</string>
     <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Ліміт перавышаны"</string>
@@ -341,7 +341,6 @@
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Не атрымалася запусціць <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> адключана ў бяспечным рэжыме."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Ачысціць усё"</string>
-    <string name="recents_incompatible_app_message" msgid="5075812958564082451">"Праграма не падтрымлівае функцыю дзялення экрана"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Перацягніце сюды, каб перайсці ў рэжым падзеленага экрана"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Падзяліць гарызантальна"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Падзяліць вертыкальна"</string>
@@ -367,7 +366,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Менш тэрміновыя апавяшчэнні ніжэй"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Дакраніцеся яшчэ раз, каб адкрыць"</string>
     <string name="keyguard_unlock" msgid="8043466894212841998">"Правядзіце пальцам уверх, каб разблакіраваць"</string>
-    <string name="do_disclosure_generic" msgid="8498005633306135779">"Гэта прылада знаходзіцца пад кіраваннем"</string>
+    <string name="do_disclosure_generic" msgid="5615898451805157556">"Гэта прылада знаходзіцца пад кіраваннем вашай арганізацыі"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Гэта прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Тэлефон: правядзіце пальцам ад значка"</string>
     <string name="voice_hint" msgid="8939888732119726665">"Галасавая дапамога: правядзіце пальцам ад значка"</string>
@@ -420,13 +419,40 @@
     <string name="profile_owned_footer" msgid="8021888108553696069">"За профілем могуць назіраць"</string>
     <string name="vpn_footer" msgid="2388611096129106812">"За сеткай могуць назіраць"</string>
     <string name="branded_vpn_footer" msgid="2168111859226496230">"За сеткай могуць назіраць"</string>
-    <string name="monitoring_title_device_owned" msgid="7121079311903859610">"Маніторынг прылад"</string>
+    <string name="quick_settings_disclosure_management_monitoring" msgid="6645176135063957394">"Ваша арганізацыя кіруе гэтай прыладай і можа сачыць за сеткавым трафікам"</string>
+    <string name="quick_settings_disclosure_named_management_monitoring" msgid="370622174777570853">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> кіруе гэтай прыладай і можа сачыць за сеткавым трафікам"</string>
+    <string name="quick_settings_disclosure_management_named_vpn" msgid="1085137869053332307">"Прылада знаходзіцца пад кіраваннем вашай арганізацыі і падключана да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="6290456493852584017">"Прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> і падключана да праграмы <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_management" msgid="3294967280853150271">"Прылада знаходзіцца пад кіраваннем вашай арганізацыі"</string>
+    <string name="quick_settings_disclosure_named_management" msgid="1059403025094542908">"Гэта прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_management_vpns" msgid="3698767349925266482">"Прылада знаходзіцца пад кіраваннем вашай арганізацыі і падключана да сетак VPN"</string>
+    <string name="quick_settings_disclosure_named_management_vpns" msgid="7777821385318891527">"Прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> і падключана да сетак VPN"</string>
+    <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="5125463987558278215">"Ваша арганізацыя можа сачыць за сеткавым трафікам у вашым працоўным профілі"</string>
+    <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8973606847896650284">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> можа сачыць за сеткавым трафікам у вашым працоўным профілі"</string>
+    <string name="quick_settings_disclosure_monitoring" msgid="679658227269205728">"За сеткай могуць сачыць"</string>
+    <string name="quick_settings_disclosure_vpns" msgid="8170318392053156330">"Прылада падключана да сетак VPN"</string>
+    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="3494535754792751741">"Працоўны профіль падключаны да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4467456202486569906">"Асабісты профіль падключаны да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_vpn" msgid="6943724064780847080">"Прылада падключана да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_device_owned" msgid="1652495295941959815">"Кіраванне прыладай"</string>
     <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"Маніторынг профіляў"</string>
     <string name="monitoring_title" msgid="169206259253048106">"Маніторынг сеткі"</string>
     <string name="monitoring_subtitle_vpn" msgid="876537538087857300">"VPN"</string>
-    <string name="monitoring_subtitle_network_logging" msgid="5569072711320784030">"Журнал сеткі"</string>
+    <string name="monitoring_subtitle_network_logging" msgid="3341264304793193386">"Журнал сеткі"</string>
+    <string name="monitoring_subtitle_ca_certificate" msgid="3874151893894355988">"Сертыфікаты ЦС"</string>
     <string name="disable_vpn" msgid="4435534311510272506">"Адключыць VPN"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"Адлучыць VPN"</string>
+    <string name="monitoring_button_view_policies" msgid="100913612638514424">"Праглядзець палітыку"</string>
+    <string name="monitoring_description_named_management" msgid="5281789135578986303">"Ваша прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nВаш адміністратар можа сачыць і кіраваць наладамі, карпаратыўным доступам, праграмамі, данымі, звязанымі з вашай прыладай, і звесткамі пра месцазнаходжанне вашай прылады.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара."</string>
+    <string name="monitoring_description_management" msgid="4573721970278370790">"Ваша прылада знаходзіцца пад кіраваннем вашай арганізацыі.\n\nУ вашага адміністратара ёсць магчымасць маніторынгу і адміністравання налад, карпаратыўнага доступу, праграм, даных, звязаных з гэтай прыладай, і адпаведных геаданых.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара."</string>
+    <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"Ваша арганізацыя ўсталявала на гэтай прыладзе цэнтр сертыфікацыі. Ваш абаронены сеткавы трафік могуць праглядваць ці змяняць."</string>
+    <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"Ваша арганізацыя ўсталявала ў вашым працоўным профілі цэнтр сертыфікацыі. Ваш абаронены сеткавы трафік могуць праглядваць ці змяняць."</string>
+    <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"На гэтай прыладзе ўсталяваны цэнтр сертыфікацыі. Ваш абаронены сеткавы трафік могуць праглядваць ці змяняць."</string>
+    <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"Ваш адміністратар уключыў вядзенне журнала сеткі, з дапамогай якога адсочваецца трафік на вашай прыладзе."</string>
+    <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"Вы падключаны да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>, якая можа сачыць за вашай сеткавай дзейнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
+    <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"Вы падключаны да праграм <xliff:g id="VPN_APP_0">%1$s</xliff:g> і <xliff:g id="VPN_APP_1">%2$s</xliff:g>, якія могуць сачыць за вашай сеткавай дзейнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
+    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"Ваш працоўны профіль падключаны да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>, якая можа сачыць за вашай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
+    <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"Ваш асабісты профіль падключаны да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>, якая можа сачыць за вашай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
     <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"Ваша прылада знаходзіцца пад кіраваннем <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g>."</string>
     <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> выкарыстоўвае <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> для кіравання вашай прыладай."</string>
     <string name="monitoring_description_do_body" msgid="3639594537660975895">"Адміністратар кантралюе налады, праграмы, карпаратыўны доступ, звязаныя з прыладай даныя і перадачу геаданых."</string>
@@ -435,15 +461,19 @@
     <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"Вы падключаны да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>, якая можа сачыць за вашай сеткавай дзейнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" ,"</string>
     <string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"Адкрыйце налады VPN"</string>
+    <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
+    <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"Адкрыць давераныя ўліковыя даныя"</string>
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"Ваш адміністратар уключыў вядзенне журнала сеткі, з дапамогай якога адсочваецца трафік на вашай прыладзе.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара."</string>
     <string name="monitoring_description_vpn" msgid="4445150119515393526">"Вы далі праграме дазвол на наладжванне злучэння VPN.\n\nГэта праграма можа сачыць за актыўнасцю вашай прылады і вашай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"Ваш працоўны профіль знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nВаш адміністратар можа сачыць за вашай сеткавай дзейнасцю, уключаючы электронную пошту, праграмы і вэб-сайты.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара.\n\nВы таксама падключаны да сеткі VPN, якая можа сачыць за вашай сеткавай дзейнасцю."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
-    <string name="monitoring_description_app" msgid="6259179342284742878">"Вы падлучаны да праграмы <xliff:g id="APPLICATION">%1$s</xliff:g>, якая можа сачыць за вашай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
+    <string name="monitoring_description_app" msgid="1828472472674709532">"Вы падключаны да праграмы <xliff:g id="APPLICATION">%1$s</xliff:g>, якая можа сачыць за вашай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
     <string name="monitoring_description_app_personal" msgid="484599052118316268">"Вы падлучаны да праграмы <xliff:g id="APPLICATION">%1$s</xliff:g>, якая сачыць за вашай асабістай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Вы падключаны да праграмы <xliff:g id="APPLICATION">%1$s</xliff:g>, якая можа сачыць за вашай асабістай сеткавай дзейнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
-    <string name="monitoring_description_app_work" msgid="7777228449969022305">"Ваш працоўны профіль знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ён падключаны да праграмы <xliff:g id="APPLICATION">%2$s</xliff:g>, якая можа сачыць за вашай сеткавай дзейнасцю, уключаючы электронную пошту, праграмы і вэб-сайты.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара."</string>
-    <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"Ваш працоўны профіль знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ён падлучаны да праграмы <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, якая можа сачыць за вашай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты.\n\nВы таксама падлучаны да праграмы <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, якая можа сачыць за вашай асабістай сеткавай актыўнасцю."</string>
+    <string name="monitoring_description_app_work" msgid="4612997849787922906">"Ваш працоўны профіль знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ён падключаны да праграмы <xliff:g id="APPLICATION">%2$s</xliff:g>, якая можа сачыць за вашай працоўнай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара."</string>
+    <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Ваш працоўны профіль знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ён падключаны да праграмы <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, якая можа сачыць за вашай працоўнай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты.\n\nВы таксама падключаны да праграмы <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, якая можа сачыць за вашай асабістай сеткавай актыўнасцю."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Разблакіравана для карыстальніка <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> працуе"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Прылада будзе заставацца заблакіраванай, пакуль вы не разблакіруеце яе ўручную"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Атрымлівайце апавяшчэнні хутчэй"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Праглядайце іх перад разблакіроўкай"</string>
@@ -474,10 +504,8 @@
     <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>
-    <!-- no translation found for volume_stream_content_description_vibrate_a11y (6427727603978431301) -->
-    <skip />
-    <!-- no translation found for volume_stream_content_description_mute_a11y (8995013018414535494) -->
-    <skip />
+    <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_dialog_accessibility_shown_message" msgid="1834631467074259998">"Паказваецца наступная колькасць рэгулятараў гучнасці: %s. Правядзіце пальцам уверх, каб закрыць іх."</string>
     <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Рэгулятары гучнасці схаваны"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Наладка сістэмнага інтэрфейсу карыстальніка"</string>
@@ -500,7 +528,7 @@
     <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>
+    <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>
@@ -527,25 +555,38 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Выключана"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"З дапамогай пашыранага кіравання апавяшчэннямі вы можаце задаваць узровень важнасці апавяшчэнняў праграмы ад 0 да 5. \n\n"<b>"Узровень 5"</b>" \n- Паказваць уверсе спіса апавяшчэнняў \n- Дазваляць перапыняць рэжым поўнага экрана \n- Заўсёды дазваляць кароткі паказ \n\n"<b>"Узровень 4"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Заўсёды дазваляць кароткі паказ \n\n"<b>"Узровень 3"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Ніколі не дазваляць кароткі паказ \n\n"<b>"Узровень 2"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Ніколі не дазваляць кароткі паказ \n- Ніколі не прайграваць гук і не вібрыраваць \n\n"<b>"Узровень 1"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Ніколі не дазваляць кароткі паказ \n- Ніколі не прайграваць гук і не вібрыраваць \n- Хаваць з экрана блакіроўкі і панэлі стану \n- Паказваць унізе спіса апавяшчэнняў \n\n"<b>"Узровень 0"</b>" \n- Блакіраваць усе апавяшчэнні ад праграмы"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Апавяшчэнні"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Вы больш не будзеце атрымліваць гэтыя апавяшчэнні."</string>
-    <plurals name="notification_num_channels_desc" formatted="false" msgid="8808748716499517938">
-      <item quantity="one">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорыі ў гэтай праграме</item>
-      <item quantity="few">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорый у гэтай праграме</item>
-      <item quantity="many">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорый у гэтай праграме</item>
-      <item quantity="other">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорыі ў гэтай праграме</item>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Вы больш не будзеце атрымліваць гэтыя апавяшчэнні"</string>
+    <string name="notification_num_channels" msgid="2048144408999179471">"Катэгорый апавяшчэнняў: <xliff:g id="NUMBER">%d</xliff:g>"</string>
+    <string name="notification_default_channel_desc" msgid="2506053815870808359">"У гэтай праграме няма катэгорый апавяшчэнняў"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
+    <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
+      <item quantity="one">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорыі апавяшчэнняў у гэтай праграме</item>
+      <item quantity="few">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорый апавяшчэнняў у гэтай праграме</item>
+      <item quantity="many">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорый апавяшчэнняў у гэтай праграме</item>
+      <item quantity="other">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорыі апавяшчэнняў у гэтай праграме</item>
     </plurals>
+    <string name="notification_channels_list_desc_2" msgid="6214732715833946441">"<xliff:g id="CHANNEL_NAME_1">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2">%2$s</xliff:g>"</string>
+    <plurals name="notification_channels_list_desc_2_and_others" formatted="false" msgid="2747813553355336157">
+      <item quantity="one"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> і яшчэ <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+      <item quantity="few"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> і яшчэ <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+      <item quantity="many"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> і яшчэ <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+      <item quantity="other"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> і яшчэ <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+    </plurals>
+    <string name="notification_channel_controls_opened_accessibility" msgid="6553950422055908113">"Кіраванне апавяшчэннямі для <xliff:g id="APP_NAME">%1$s</xliff:g> адкрыта"</string>
+    <string name="notification_channel_controls_closed_accessibility" msgid="7521619812603693144">"Кіраванне апавяшчэннямі для <xliff:g id="APP_NAME">%1$s</xliff:g> закрыта"</string>
+    <string name="notification_channel_switch_accessibility" msgid="3420796005601900717">"Дазволіць апавяшчэнні з гэтага канала"</string>
     <string name="notification_all_categories" msgid="5407190218055113282">"Усе катэгорыі"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Дадатковыя налады"</string>
+    <string name="notification_app_settings" msgid="3743278649182392015">"Персаналізаваць: <xliff:g id="SUB_CATEGORY">%1$s</xliff:g>"</string>
     <string name="notification_done" msgid="5279426047273930175">"Гатова"</string>
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"кіраванне апавяшчэннямі"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"параметры адкладвання апавяшчэнняў"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 хвілін"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 хвілін"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 гадзіна"</string>
-    <string name="snooze_option_dont_snooze" msgid="655446566007801922">"Не адкладваць"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"АДРАБІЦЬ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Адкладзена на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Выкарыстанне зараду"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Эканомія зараду акумулятара недаступная падчас зарадкі"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Эканомія зараду"</string>
@@ -671,6 +712,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"Апавяшчэнне <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Праграма можа не працаваць у рэжыме дзялення экрана."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Праграма не падтрымлівае функцыю дзялення экрана."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Праграма можа не працаваць на дадатковых экранах."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Праграма не падтрымлівае запуск на дадатковых экранах."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Адкрыць налады."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Адкрыць хуткія налады."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Закрыць хуткія налады."</string>
@@ -685,6 +728,17 @@
     <string name="pip_phone_expand" msgid="5889780005575693909">"Разгарнуць"</string>
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Згарнуць"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Закрыць"</string>
+    <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Перацягніце ўніз, каб адхіліць"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Меню \"Відарыс у відарысе\""</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> з’яўляецца відарысам у відарысе"</string>
+    <string name="pip_notification_message" msgid="4171698133469539591">"Калі вы не хочаце, каб праграма <xliff:g id="NAME">%s</xliff:g> выкарыстоўвала гэту функцыю, дакраніцеся, каб адкрыць налады і адключыць яе."</string>
+    <string name="pip_play" msgid="1417176722760265888">"Прайграць"</string>
+    <string name="pip_pause" msgid="8881063404466476571">"Прыпыніць"</string>
+    <string name="pip_skip_to_next" msgid="1948440006726306284">"Перайсці да наступнага"</string>
+    <string name="pip_skip_to_prev" msgid="1955311326688637914">"Перайсці да папярэдняга"</string>
+    <string name="thermal_shutdown_title" msgid="4458304833443861111">"З-за перагрэву тэл. выключыўся"</string>
+    <string name="thermal_shutdown_message" msgid="9006456746902370523">"Тэлефон працуе нармальна"</string>
+    <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"Ваш тэлефон пераграваўся, таму ён выключыўся, каб астыць. Зараз тэлефон працуе нармальна.\n\nТэлефон можа перагравацца пры:\n	• Выкарыстанні рэсурсаёмістых праграм (напрыклад, гульняў, відэа або праграм навігацыі)\n	• Спампоўцы або запампоўцы вялікіх файлаў\n	• Выкарыстанні тэлефона пры высокіх тэмпературах"</string>
     <string name="high_temp_title" msgid="4589508026407318374">"Тэлефон награваецца"</string>
     <string name="high_temp_notif_message" msgid="5642466103153429279">"Некаторыя функцыі абмежаваны, пакуль тэлефон астывае"</string>
     <string name="high_temp_dialog_message" msgid="6840700639374113553">"Ваш тэлефон аўтаматычна паспрабуе астыць. Вы можаце па-ранейшаму карыстацца сваім тэлефонам, але ён можа працаваць больш павольна.\n\nПасля таго як ваш тэлефон астыне, ён будзе працаваць у звычайным рэжыме."</string>
@@ -707,9 +761,19 @@
     <string name="notification_channel_general" msgid="4525309436693914482">"Агульныя паведамленні"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Захоўванне"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Імгненныя праграмы"</string>
-    <!-- no translation found for pip_menu_title (3328510504196964712) -->
-    <skip />
     <string name="instant_apps_message" msgid="8116608994995104836">"Імгненныя праграмы не патрабуюць усталёўкі."</string>
     <string name="app_info" msgid="6856026610594615344">"Інфармацыя пра праграму"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Перайсці ў інтэрнэт"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Маб. перадача даных"</string>
+    <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi выключаны"</string>
+    <string name="bt_is_off" msgid="2640685272289706392">"Bluetooth выключаны"</string>
+    <string name="dnd_is_off" msgid="6167780215212497572">"Рэжым \"Не турбаваць\" выключаны"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"Рэжым \"Не турбаваць\" быў уключаны аўтаматычным правілам (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"Рэжым \"Не турбаваць\" быў уключаны праграмай (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"Рэжым \"Не турбаваць\" быў уключаны аўтаматычным правілам ці праграмай."</string>
+    <string name="qs_dnd_until" msgid="3469471136280079874">"Да <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="qs_dnd_keep" msgid="1825009164681928736">"Пакінуць"</string>
+    <string name="qs_dnd_replace" msgid="8019520786644276623">"Замяніць"</string>
+    <string name="running_foreground_services_title" msgid="381024150898615683">"Праграмы, якія працуюць у фонавым рэжыме"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Дакраніцеся, каб даведацца пра выкарыстанне трафіка і акумулятара"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings_car.xml b/packages/SystemUI/res/values-be/strings_car.xml
index e3ef7c6..7d53c97 100644
--- a/packages/SystemUI/res/values-be/strings_car.xml
+++ b/packages/SystemUI/res/values-be/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Кіруйце аўтамабілем бяспечна"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Будзьце заўсёды ў курсе дарожных умоў і заўсёды прытрымлівайцеся дзеючага заканадаўства. Указанні могуць быць недакладнымі, няпоўнымі, небяспечнымі, непадыходзячымі, забароненымі ці прадугледжваць уезд на адміністрацыйныя тэрыторыі. Інфармацыя пра кампаніі таксама можа быць недакладнай ці няпоўнай. Даныя не прадстаўляюцца ў рэжыме рэальнага часу, і дакладнасць вызначэння месцазнаходжання не можа быць гарантавана. Не выкарыстоўвайце сваю мабільную прыладу або праграмы, не прызначаныя для Android Auto, падчас кіравання."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Невядомы"</string>
+    <string name="start_driving" msgid="864023351402918991">"Пачаць паездку"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings_tv.xml b/packages/SystemUI/res/values-be/strings_tv.xml
index 4b871a6..b9761b7 100644
--- a/packages/SystemUI/res/values-be/strings_tv.xml
+++ b/packages/SystemUI/res/values-be/strings_tv.xml
@@ -19,15 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Відарыс у відарысе"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Праграма без назвы)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Закрыць PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Ва ўвесь экран"</string>
-    <string name="pip_play" msgid="674145557658227044">"Прайграць"</string>
-    <string name="pip_pause" msgid="8412075640017218862">"Прыпыніць"</string>
-    <string name="pip_hold_home" msgid="340086535668778109">"Утрым. "<b>"HOME"</b>" для кір. PIP"</string>
-    <string name="pip_onboarding_title" msgid="7850436557670253991">"Відарыс у відарысе"</string>
-    <string name="pip_onboarding_description" msgid="4028124563309465267">"Гэта дазваляе захоўваць ваша відэа ў полі зроку, пакуль вы не пачняце прайграванне іншага. Націсніце і ўтрымлівайце "<b>"HOME"</b>" для кіравання."</string>
-    <string name="pip_onboarding_button" msgid="3957426748484904611">"Зразумела"</string>
-    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Адхіліць"</string>
-  <string-array name="recents_tv_blacklist_array">
-  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index ac11dc7..21d4d12 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Още настройки"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Готово"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Установена е връзка"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Свързано, батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Установява се връзка..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Тетъринг"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Точка за достъп"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Установена е връзка с приложението <xliff:g id="APPLICATION">%1$s</xliff:g>, което може да наблюдава личната ви активност в мрежата, включително имейли, приложения и уебсайтове."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Служебният ви потребителски профил се управлява от <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Той е свързан с приложението <xliff:g id="APPLICATION">%2$s</xliff:g>, което може да наблюдава служебната ви активност в мрежата, включително имейли, приложения и уебсайтове.\n\nЗа още информация се свържете с администратора си."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Служебният ви потребителски профил се управлява от <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Той е свързан с приложението <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, което може да наблюдава служебната ви активност в мрежата, включително имейли, приложения и уебсайтове.\n\nУстановена е връзка и с приложението <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, което може да наблюдава личната ви активност в мрежата."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Отключено за <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> се изпълнява"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Устройството ще остане заключено, докато не го отключите ръчно"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Получавайте известия по-бързо"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Вижте известията, преди да отключите"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Изкл."</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"С помощта на контролите за известията можете да зададете ниво на важност от 0 до 5 за известията от дадено приложение. \n\n"<b>"Ниво 5"</b>" \n– Показване най-горе в списъка с известия. \n– Разрешаване на прекъсването на цял екран. \n– Известията винаги се показват мимолетно. \n\n"<b>"Ниво 4"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията винаги се показват мимолетно. \n\n"<b>"Ниво 3"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията никога не се показват мимолетно. \n\n"<b>"Ниво 2"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията никога не се показват мимолетно. \n– Без издаване на звуков сигнал и вибриране. \n\n"<b>"Ниво 1"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията никога не се показват мимолетно. \n– Без издаване на звуков сигнал и вибриране. \n– Скриване от заключения екран и лентата на състоянието. \n– Показване най-долу в списъка с известия. \n\n"<b>"Ниво 0"</b>" \n– Блокиране на всички известия от приложението."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Известия"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Вече няма да получавате тези известия."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Вече няма да получавате тези известия"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> категории известия"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"За това приложение няма категории на известията"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Известията от това приложение не могат да бъдат изключени"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 от <xliff:g id="NUMBER_1">%d</xliff:g> категории известия от това приложение</item>
       <item quantity="one">1 от <xliff:g id="NUMBER_0">%d</xliff:g> категория известия от това приложение</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> от <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"контроли за известията"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"опции за отлагане на известията"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минути"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 минути"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 час"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 часа"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ОТМЯНА"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Отложено за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d часа</item>
+      <item quantity="one">%d час</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d минути</item>
+      <item quantity="one">%d минута</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Ползв. на батерията"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режимът за запазване на батерията не е налице при зареждане"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим за запазване на батерията"</string>
@@ -606,7 +614,7 @@
     <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
     <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
     <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Цифрова клавиатура – <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Системни"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Системни настройки"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Начало"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Скорошни"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Замяна"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Приложения, работещи на заден план"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Докоснете за информация относно използването на батерията и преноса на данни"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Да се изключат ли мобилните данни?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings_car.xml b/packages/SystemUI/res/values-bg/strings_car.xml
index bd9fe79..c7f6974 100644
--- a/packages/SystemUI/res/values-bg/strings_car.xml
+++ b/packages/SystemUI/res/values-bg/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Карайте внимателно"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Бъдете осведомени за условията при шофиране и винаги спазвайте приложимите закони. Упътванията може да са неточни, непълни, опасни, неподходящи, забранени или да включват преминаване през административни райони. Бизнес информацията може също да е неточна или непълна. Данните не са в реално време и точността на местоположението не може да се гарантира. Не работете с мобилното си устройство, нито използвайте приложения, които не са предназначени за Android Auto, докато шофирате."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Няма информация"</string>
+    <string name="start_driving" msgid="864023351402918991">"Започнете да шофирате"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn-land/strings.xml b/packages/SystemUI/res/values-bn-land/strings.xml
index ac873fa..bf53a77 100644
--- a/packages/SystemUI/res/values-bn-land/strings.xml
+++ b/packages/SystemUI/res/values-bn-land/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="toast_rotation_locked" msgid="7609673011431556092">"এখন ভূদৃশ্য সজ্জাতে স্ক্রীণ লক করা হয়েছে৷"</string>
+    <string name="toast_rotation_locked" msgid="7609673011431556092">"এখন ল্যান্ডস্কেপ সজ্জাতে স্ক্রিন লক করা হয়েছে৷"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 65ea6b1..206612f 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -22,7 +22,7 @@
     <string name="app_label" msgid="7164937344850004466">"সিস্টেম UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"সাফ করুন"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"তালিকা থেকে সরান"</string>
-    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"অ্যাপ্লিকেশানের তথ্য"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"অ্যাপের তথ্য"</string>
     <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"আপনার সাম্প্রতিক স্ক্রীনগুলো এখানে দেখা যাবে"</string>
     <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"সাম্প্রতিক অ্যাপ্লিকেশানগুলি খারিজ করুন"</string>
     <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
@@ -44,7 +44,7 @@
     <string name="battery_saver_start_action" msgid="5576697451677486320">"ব্যাটারি সঞ্চয়কারী চালু"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"সেটিংস"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"ওয়াই-ফাই"</string>
-    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"স্বতঃ-ঘূর্ণায়মান স্ক্রীণ"</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_auto_brightness_label" msgid="511453614962324674">"স্বতঃ"</string>
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"বিজ্ঞপ্তিগুলি"</string>
@@ -55,7 +55,7 @@
     <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"এই <xliff:g id="APPLICATION">%1$s</xliff:g> অ্যাপ্লিকেশানটিকে কি USB যন্ত্রাংশ অ্যাক্সেস করার অনুমতি দেবেন?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"যখন এই USB ডিভাইসটি সংযুক্ত থাকে তখন কি <xliff:g id="ACTIVITY">%1$s</xliff:g> খুলবেন?"</string>
     <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"যখন এই USB যন্ত্রাংশটি সংযুক্ত থাকে তখন কি <xliff:g id="ACTIVITY">%1$s</xliff:g> খুলবেন?"</string>
-    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"ইনস্টল থাকা কোনো অ্যাপ্লিকেশান এই USB যন্ত্রাংশের সাথে কাজ করে না৷ <xliff:g id="URL">%1$s</xliff:g> এ এই যন্ত্রাংশের সম্পর্কে আরো জানুন৷"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"ইনস্টল থাকা কোনো অ্যাপ্লিকেশান এই USB যন্ত্রাংশের সাথে কাজ করে না৷ <xliff:g id="URL">%1$s</xliff:g> এ এই যন্ত্রাংশের সম্পর্কে আরও জানুন৷"</string>
     <string name="title_usb_accessory" msgid="4966265263465181372">"USB যন্ত্রাংশ"</string>
     <string name="label_view" msgid="6304565553218192990">"দেখুন"</string>
     <string name="always_use_device" msgid="1450287437017315906">"এই USB ডিভাইসের জন্য এটি ডিফল্টরুপে ব্যবহার করুন"</string>
@@ -66,26 +66,26 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB ডিবাগিং অনুমোদিত নয়"</string>
     <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"ব্যবহারকারী বর্তমানে এই ডিভাইসটিতে প্রবেশ করেছেন তাই USB ডিবাগিং চালু করা যাবে না। এই বৈশিষ্ট্যটি ব্যবহার করতে, অনুগ্রহ করে প্রশাসক ব্যবহারকারীতে পাল্টান।"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"স্ক্রীণ পূরণ করতে জুম করুন"</string>
-    <string name="compat_mode_off" msgid="4434467572461327898">"পূর্ণ স্ক্রীণে প্রসারিত করুন"</string>
-    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"স্ক্রীনশট সংরক্ষণ করা হচ্ছে..."</string>
-    <string name="screenshot_saving_title" msgid="8242282144535555697">"স্ক্রীনশট সংরক্ষণ করা হচ্ছে..."</string>
-    <string name="screenshot_saving_text" msgid="2419718443411738818">"স্ক্রীনশট সংরক্ষণ করা হচ্ছে৷"</string>
-    <string name="screenshot_saved_title" msgid="6461865960961414961">"স্ক্রীনশট নেওয়া হযেছে৷"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"ফুল স্ক্রিন করুন"</string>
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"স্ক্রিনশট সেভ করা হচ্ছে..."</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"স্ক্রিনশট সেভ করা হচ্ছে..."</string>
+    <string name="screenshot_saving_text" msgid="2419718443411738818">"স্ক্রিনশট সেভ করা হচ্ছে৷"</string>
+    <string name="screenshot_saved_title" msgid="6461865960961414961">"স্ক্রিনশট নেওয়া হযেছে৷"</string>
     <string name="screenshot_saved_text" msgid="2685605830386712477">"আপনার স্ক্রিনশট দেখতে আলতো চাপ দিন৷"</string>
-    <string name="screenshot_failed_title" msgid="705781116746922771">"স্ক্রীনশট নেওয়া যায়নি৷"</string>
-    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"স্ক্রীনশট সংরক্ষণের সময়ে সমস্যা হয়েছে৷"</string>
-    <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"সঞ্চয়স্থান সীমিত থাকায় স্ক্রীনশটটি সংরক্ষণ করা যাবে না৷"</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"স্ক্রিনশট নেওয়া যায়নি৷"</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"স্ক্রিনশট সেভের সময়ে সমস্যা হয়েছে৷"</string>
+    <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"স্টোরেজ সীমিত থাকায় স্ক্রিনশটটি সেভ করা যাবে না৷"</string>
     <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"এই অ্যাপ বা আপনার প্রতিষ্ঠান স্ক্রিনশট নেওয়ার অনুমতি দেয়নি"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ফাইল স্থানান্তরের বিকল্পগুলি"</string>
-    <string name="use_mtp_button_title" msgid="4333504413563023626">"একটি মিডিয়া প্লেয়ার হিসাবে মাউন্ট করুন (MTP)"</string>
-    <string name="use_ptp_button_title" msgid="7517127540301625751">"একটি ক্যামেরা হিসাবে মাউন্ট করুন (PTP)"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"একটি মিডিয়া প্লেয়ার হিসেবে মাউন্ট করুন (MTP)"</string>
+    <string name="use_ptp_button_title" msgid="7517127540301625751">"একটি ক্যামেরা হিসেবে মাউন্ট করুন (PTP)"</string>
     <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac এর জন্য Android এর ফাইল স্তানান্তর অ্যাপ্লিকেশান ইনস্টল করুন"</string>
     <string name="accessibility_back" msgid="567011538994429120">"ফিরুন"</string>
     <string name="accessibility_home" msgid="8217216074895377641">"হোম"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"মেনু"</string>
     <string name="accessibility_accessibility_button" msgid="7601252764577607915">"অ্যাক্সেসযোগ্যতা"</string>
     <string name="accessibility_recent" msgid="5208608566793607626">"এক নজরে"</string>
-    <string name="accessibility_search_light" msgid="1103867596330271848">"অনুসন্ধান করুন"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"খুঁজুন"</string>
     <string name="accessibility_camera_button" msgid="8064671582820358152">"ক্যামেরা"</string>
     <string name="accessibility_phone_button" msgid="6738112589538563574">"ফোন"</string>
     <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ভয়েস সহায়তা"</string>
@@ -96,7 +96,7 @@
     <string name="phone_label" msgid="2320074140205331708">"ফোন খুলুন"</string>
     <string name="voice_assist_label" msgid="3956854378310019854">"ভয়েস সহায়তা খুলুন"</string>
     <string name="camera_label" msgid="7261107956054836961">"ক্যামেরা খুলুন"</string>
-    <string name="recents_caption_resize" msgid="3517056471774958200">"নতুন কার্য লেআউট নির্বাচন করুন"</string>
+    <string name="recents_caption_resize" msgid="3517056471774958200">"নতুন কার্য লেআউট বেছে নিন"</string>
     <string name="cancel" msgid="6442560571259935130">"বাতিল করুন"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"সামঞ্জস্যের জুম বোতাম৷"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ছোট থেকে বৃহৎ স্ক্রীণে জুম করুন৷"</string>
@@ -184,10 +184,10 @@
     <string name="accessibility_notification_dismissed" msgid="854211387186306927">"বিজ্ঞপ্তি খারিজ করা হয়েছে৷"</string>
     <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"বিজ্ঞপ্তি শেড৷"</string>
     <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"দ্রুত সেটিংস৷"</string>
-    <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"লক স্ক্রীন।"</string>
+    <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"লক স্ক্রিন।"</string>
     <string name="accessibility_desc_settings" msgid="3417884241751434521">"সেটিংস"</string>
     <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"এক নজরে৷"</string>
-    <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"কর্মস্থলের স্ক্রীন লক"</string>
+    <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"কর্মস্থলের স্ক্রিন লক"</string>
     <string name="accessibility_desc_close" msgid="7479755364962766729">"বন্ধ করুন"</string>
     <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>।"</string>
     <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"ওয়াই ফাই বন্ধ হয়েছে।"</string>
@@ -212,10 +212,10 @@
     <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"ব্লুটুথ সংযুক্ত হয়েছে৷"</string>
     <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"ব্লুটুথ বন্ধ হয়েছে।"</string>
     <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"ব্লুটুথ চালু হয়েছে।"</string>
-    <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"অবস্থানের প্রতিবেদন বন্ধ আছে।"</string>
-    <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"অবস্থানের প্রতিবেদন চালু আছে।"</string>
-    <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"অবস্থানের প্রতিবেদন বন্ধ হয়েছে।"</string>
-    <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"অবস্থানের প্রতিবেদন চালু হয়েছে।"</string>
+    <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"অবস্থান জানানো বন্ধ আছে।"</string>
+    <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"অবস্থান জানানো চালু আছে।"</string>
+    <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"অবস্থান জানানো বন্ধ হয়েছে।"</string>
+    <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"অবস্থান জানানো চালু হয়েছে।"</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"<xliff:g id="TIME">%s</xliff:g> এ অ্যালার্ম সেট করা হয়েছে৷"</string>
     <string name="accessibility_quick_settings_close" msgid="3115847794692516306">"প্যানেল বন্ধ করুন।"</string>
     <string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"বেশি সময়।"</string>
@@ -258,13 +258,13 @@
     <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>
-    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"প্রতিকৃতি সজ্জাতে স্ক্রীন লক করা আছে৷"</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"ল্যান্ডস্কেপ সজ্জাতে স্ক্রিন লক করা আছে৷"</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"পোর্ট্রেট অবস্থায় স্ক্রিন লক করা আছে৷"</string>
     <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"স্ক্রিন এখন স্বয়ংক্রিয়ভাবে ঘুরবে।"</string>
-    <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"এখন ভূদৃশ্য সজ্জাতে স্ক্রীন লক হয়েছে।"</string>
-    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"এখন প্রতিকৃতি সজ্জাতে স্ক্রীন লক হয়েছে।"</string>
+    <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"এখন ল্যান্ডস্কেপ সজ্জাতে স্ক্রিন লক হয়েছে।"</string>
+    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"এখন পোর্ট্রেট অবস্থায় স্ক্রিন লক হয়েছে।"</string>
     <string name="dessert_case" msgid="1295161776223959221">"ডেজার্ট কেস"</string>
-    <string name="start_dreams" msgid="5640361424498338327">"স্ক্রীন সেভার"</string>
+    <string name="start_dreams" msgid="5640361424498338327">"স্ক্রিন সেভার"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ইথারনেট"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"বিরক্ত করবেন না"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"শুধুমাত্র অগ্রাধিকার"</string>
@@ -273,14 +273,14 @@
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"ব্লুটুথ"</string>
     <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"ব্লুটুথ (<xliff:g id="NUMBER">%d</xliff:g> টি ডিভাইস)"</string>
     <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"ব্লুটুথ বন্ধ"</string>
-    <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"যুক্ত করা কোন ডিভাইস উপলব্ধ নয়"</string>
+    <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"চেনা কোনও ডিভাইস নেই"</string>
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"উজ্জ্বলতা"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"স্বতঃ ঘূর্ণায়মান"</string>
-    <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"স্বতঃ-ঘূর্ণায়মান স্ক্রীন"</string>
+    <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"স্বতঃ-ঘূর্ণায়মান স্ক্রিন"</string>
     <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"<xliff:g id="ID_1">%s</xliff:g> মোড"</string>
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"ঘূর্ণন লক করা হয়েছে"</string>
-    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"প্রতিকৃতি"</string>
-    <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"ভূদৃশ্য"</string>
+    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"পোর্ট্রেট"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"ল্যান্ডস্কেপ"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"ইনপুট পদ্ধতি"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"অবস্থান"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"অবস্থান বন্ধ করা আছে"</string>
@@ -307,9 +307,10 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"স্বয়ং"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"বিপরীত কোনো রং দিন"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"রঙ সংশোধন মোড"</string>
-    <string name="quick_settings_more_settings" msgid="326112621462813682">"আরো সেটিংস"</string>
+    <string name="quick_settings_more_settings" msgid="326112621462813682">"আরও সেটিংস"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"সম্পন্ন হয়েছে"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"সংযুক্ত হয়েছে"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"সংযুক্ত হয়েছে, ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"সংযুক্ত হচ্ছে..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"টেদারিং"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"হটস্পট"</string>
@@ -330,7 +331,7 @@
     <string name="recents_empty_message" msgid="808480104164008572">"কোনো সাম্প্রতিক আইটেম নেই"</string>
     <string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"আপনি সবকিছু সাফ করেছেন"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"অ্যাপ্লিকেশানের তথ্য"</string>
-    <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"স্ক্রীন পিন করা"</string>
+    <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"স্ক্রিন পিন করা"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"অনুসন্ধান"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> শুরু করা যায়নি৷"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"নিরাপদ মোডে <xliff:g id="APP">%s</xliff:g> অক্ষম করা হয়েছে৷"</string>
@@ -349,7 +350,7 @@
     <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"পূর্ণ হতে <xliff:g id="CHARGING_TIME">%s</xliff:g> সময় লাগবে"</string>
     <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"চার্জ হচ্ছে না"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"নেটওয়ার্ক নিরীক্ষণ\nকরা হতে পারে"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"অনুসন্ধান করুন"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"খুঁজুন"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> এর জন্য উপরের দিকে স্লাইড করুন৷"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> এর জন্য বাঁ দিকে স্লাইড করুন৷"</string>
     <string name="zen_priority_introduction" msgid="7577965386868311310">"অ্যালার্ম, রিমাইন্ডার, ইভেন্ট, এবং আপনার নির্দিষ্ট করে দেওয়া ব্যক্তিদের কল ছাড়া অন্য কোনও আওয়াজ বা ভাইব্রেশন হবে না। তবে সঙ্গীত, ভিডিও, এবং গেমের আওয়াজ শুনতে পাবেন।"</string>
@@ -396,7 +397,7 @@
     <string name="guest_notification_text" msgid="335747957734796689">"অ্যাপ্লিকেশান এবং ডেটা মুছে ফেলার জন্য অতিথি ব্যবহারকারী সরান।"</string>
     <string name="guest_notification_remove_action" msgid="8820670703892101990">"অতিথি সরান"</string>
     <string name="user_logout_notification_title" msgid="1453960926437240727">"ব্যবহারকারীকে লগ-আউট করুন"</string>
-    <string name="user_logout_notification_text" msgid="3350262809611876284">"বর্তমান ব্যবহারকারীকে লগ আউট করুন"</string>
+    <string name="user_logout_notification_text" msgid="3350262809611876284">"বর্তমান ব্যবহারকারীকে লগ-আউট করুন"</string>
     <string name="user_logout_notification_action" msgid="1195428991423425062">"ব্যবহারকারীকে লগ-আউট করুন"</string>
     <string name="user_add_user_title" msgid="4553596395824132638">"নতুন ব্যবহারকারীকে যোগ করবেন?"</string>
     <string name="user_add_user_message_short" msgid="2161624834066214559">"আপনি একজন নতুন ব্যবহারকারী যোগ করলে তাকে তার জায়গা সেট আপ করে নিতে হবে৷\n\nযেকোনো ব্যবহারকারী অন্য সব ব্যবহারকারীর জন্য অ্যাপ্লিকেশান আপডেট করতে পারবেন৷"</string>
@@ -434,15 +435,15 @@
     <string name="monitoring_title" msgid="169206259253048106">"নেটওয়ার্ক নিরীক্ষণ"</string>
     <string name="monitoring_subtitle_vpn" msgid="876537538087857300">"VPN"</string>
     <string name="monitoring_subtitle_network_logging" msgid="3341264304793193386">"নেটওয়ার্ক লগিং"</string>
-    <string name="monitoring_subtitle_ca_certificate" msgid="3874151893894355988">"CA শংসাপত্র"</string>
+    <string name="monitoring_subtitle_ca_certificate" msgid="3874151893894355988">"CA সার্টিফিকেট"</string>
     <string name="disable_vpn" msgid="4435534311510272506">"VPN অক্ষম করুন"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"VPN এর সংযোগ বিচ্ছিন্ন করুন"</string>
     <string name="monitoring_button_view_policies" msgid="100913612638514424">"নীতিগুলি দেখুন"</string>
     <string name="monitoring_description_named_management" msgid="5281789135578986303">"আপনার ডিভাইসটি <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> এর দ্বারা পরিচালিত হয়।\n\nআপনার প্রশাসক এই ডিভাইসের সেটিংস, কর্পোরেট অ্যাক্সেস, অ্যাপ, ডিভাইসের সাথে সম্পর্কিত ডেটা এবং ডিভাইসের অবস্থান তথ্য নিরীক্ষণ ও পরিচালনা করতে পারেন।\n\nআরও তথ্যের জন্য আপনার প্রশাসকের সাথে যোগাযোগ করুন।"</string>
     <string name="monitoring_description_management" msgid="4573721970278370790">"আপনার ডিভাইসটি আপনার প্রতিষ্ঠানের দ্বারা পরিচালিত হয়।\n\nআপনার প্রশাসক এই ডিভাইসের সেটিংস, কর্পোরেট অ্যাক্সেস, অ্যাপ, ডিভাইসের সাথে সম্পর্কিত ডেটা এবং ডিভাইসের অবস্থান তথ্য নিরীক্ষণ ও পরিচালনা করতে পারেন।\n\nআরও তথ্যের জন্য আপনার প্রশাসকের সাথে যোগাযোগ করুন।"</string>
-    <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"আপনার প্রতিষ্ঠান আপনার কর্মস্থলের প্রোফাইলে একটি শংসাপত্র কর্তৃপক্ষ ইনস্টল করেছে।আপনার সুরক্ষিত নেটওয়ার্ক ট্রাফিক নিরীক্ষণ বা পরিবর্তন করা হতে পারে।"</string>
-    <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"আপনার প্রতিষ্ঠান আপনার কর্মস্থলের প্রোফাইলে একটি শংসাপত্র কর্তৃপক্ষ ইনস্টল করেছে। আপনার নিরাপদ নেটওয়ার্ক ট্রাফিকে নজর রাখা হতে পারে বা তাতে পরিবর্তন করা হতে পারে।"</string>
-    <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"এই ডিভাইসে একটি শংসাপত্র কর্তৃপক্ষ ইনস্টল করা আছে। আপনার নিরাপদ নেটওয়ার্ক ট্রাফিকে নজর রাখা হতে পারে বা তাতে পরিবর্তন করা হতে পারে।"</string>
+    <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"আপনার প্রতিষ্ঠান আপনার অফিস প্রোফাইলে একটি সার্টিফিকেট কর্তৃপক্ষ ইনস্টল করেছে।আপনার সুরক্ষিত নেটওয়ার্ক ট্রাফিক নিরীক্ষণ বা পরিবর্তন করা হতে পারে।"</string>
+    <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"আপনার প্রতিষ্ঠান আপনার অফিস প্রোফাইলে একটি সার্টিফিকেট কর্তৃপক্ষ ইনস্টল করেছে। আপনার নিরাপদ নেটওয়ার্ক ট্রাফিকে নজর রাখা হতে পারে বা তাতে পরিবর্তন করা হতে পারে।"</string>
+    <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"এই ডিভাইসে একটি সার্টিফিকেট কর্তৃপক্ষ ইনস্টল করা আছে। আপনার নিরাপদ নেটওয়ার্ক ট্রাফিকে নজর রাখা হতে পারে বা তাতে পরিবর্তন করা হতে পারে।"</string>
     <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"আপনার প্রশাসক নেটওয়ার্ক লগিং চালু করেছেন, যা আপনার ডিভাইসের ট্রাফিকের উপরে নজর রাখে।"</string>
     <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"আপনি <xliff:g id="VPN_APP">%1$s</xliff:g> এ সংযুক্ত রয়েছেন, যা আপনার ইমেল, অ্যাপ, এবং ওয়েবসাইট সহ আপনার নেটওয়ার্ক কার্যকলাপের উপর নজর রাখতে পারে।"</string>
     <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"আপনি <xliff:g id="VPN_APP_0">%1$s</xliff:g> এবং <xliff:g id="VPN_APP_1">%2$s</xliff:g> এর সাথে সংযুক্ত রয়েছেন, যেগুলি আপনার ইমেল, অ্যাপ, এবং ওয়েবসাইট সহ আপনার নেটওয়ার্ক কার্যকলাপের উপর নজর রাখতে পারে।"</string>
@@ -452,31 +453,33 @@
     <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> আপনার ডিভাইস পরিচালনা করার জন্য <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> ব্যবহার করে৷"</string>
     <string name="monitoring_description_do_body" msgid="3639594537660975895">"আপনার প্রশাসক আপনার ডিভাইসের অবস্থান তথ্য সহ এই ডিভাইসের সেটিংস, কর্পোরেট অ্যাক্সেস, অ্যাপ্স, ডেটা নিরীক্ষণ ও পরিচালনা করতে পারেন।"</string>
     <string name="monitoring_description_do_learn_more_separator" msgid="3785251953067436862">" "</string>
-    <string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"আরো জানুন"</string>
+    <string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"আরও জানুন"</string>
     <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"আপনি <xliff:g id="VPN_APP">%1$s</xliff:g> এ সংযুক্ত হয়েছেন, যা ইমেল, অ্যাপ এবং ওয়েবসাইটগুলি সহ আপনার নেটওয়ার্ক কার্যকলাপ নিরীক্ষণ করবে৷"</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"VPN সেটিংস খুলুন"</string>
     <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
     <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"বিশ্বস্ত শংসাপত্রগুলি খুলুন"</string>
-    <string name="monitoring_description_network_logging" msgid="7223505523384076027">"আপনার প্রশাসক নেটওয়ার্ক লগিং চালু করেছেন, যা আপনার ডিভাইসের ট্রাফিক নিরীক্ষণ করে।\n\nআরো তথ্যের জন্য আপনার প্রশাসকের সাথে যোগাযোগ করুন।"</string>
+    <string name="monitoring_description_network_logging" msgid="7223505523384076027">"আপনার প্রশাসক নেটওয়ার্ক লগিং চালু করেছেন, যা আপনার ডিভাইসের ট্রাফিক নিরীক্ষণ করে।\n\nআরও তথ্যের জন্য আপনার প্রশাসকের সাথে যোগাযোগ করুন।"</string>
     <string name="monitoring_description_vpn" msgid="4445150119515393526">"আপনি VPN সংযোগ সেট আপ করার জন্য একটি অ্যাপ্লিকেশানকে অনুমতি দিন৷\n\nএই অ্যাপ্লিকেশানটি ইমেল, অ্যাপ্লিকেশান ও ওয়েবসাইটগুলি সহ আপনার ডিভাইস এবং নেটওয়ার্কের কার্যকলাপ নিরীক্ষণ করতে পারে।"</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"আপনার কর্মস্থলের প্রোফাইলটি <xliff:g id="ORGANIZATION">%1$s</xliff:g> দ্বারা পরিচালিত হয়।\n\nআপনার প্রশাসক আপনার ইমেল, অ্যাপ্স ও ওয়েবসাইট সহ কর্মস্থলের নেটওয়ার্ক কার্যকলাপ নিরীক্ষণ করতে পারেন।\n\nআরো তথ্যের জন্য আপনার প্রশাসকের সঙ্গে যোগাযোগ করুন।\n\nএছাড়া আপনি একটি VPN এর সাথেও সংযুক্ত যা আপনার নেটওয়ার্ক কার্যকলাপ নিরীক্ষণ করতে পারে।"</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"আপনার কর্মস্থলের প্রোফাইলটি <xliff:g id="ORGANIZATION">%1$s</xliff:g> দ্বারা পরিচালিত হয়।\n\nআপনার প্রশাসক আপনার ইমেল, অ্যাপ্স ও ওয়েবসাইট সহ কর্মস্থলের নেটওয়ার্ক কার্যকলাপ নিরীক্ষণ করতে পারেন।\n\nআরও তথ্যের জন্য আপনার প্রশাসকের সঙ্গে যোগাযোগ করুন।\n\nএছাড়া আপনি একটি VPN এর সাথেও সংযুক্ত যা আপনার নেটওয়ার্ক কার্যকলাপ নিরীক্ষণ করতে পারে।"</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
     <string name="monitoring_description_app" msgid="1828472472674709532">"আপনি <xliff:g id="APPLICATION">%1$s</xliff:g> এর সাথে সংযুক্ত রয়েছেন, যেটি ইমেল, অ্যাপ, এবং ওয়েবসাইট সহ আপনার নেটওয়ার্ক কার্যকলাপে নজর রাখতে পারে৷"</string>
     <string name="monitoring_description_app_personal" msgid="484599052118316268">"আপনি <xliff:g id="APPLICATION">%1$s</xliff:g> -এ সংযুক্ত হয়েছেন, যা ইমেল, অ্যাপ্লিকেশান এবং ওয়েবসাইটগুলি সমেত আপনার ব্যক্তিগত নেটওয়ার্ক কার্যকলাপ নিরীক্ষণ করতে পারে৷"</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"আপনি <xliff:g id="APPLICATION">%1$s</xliff:g> এর সাথে সংযুক্ত হয়েছেন, যা ইমেল, অ্যাপ এবং ওয়েবসাইটগুলি সহ আপনার ব্যক্তিগত নেটওয়ার্কের কার্যকলাপ নিরীক্ষণ করবে৷"</string>
-    <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> আপনার কর্মস্থলের প্রোফাইল পরিচালনা করে। প্রোফাইলটি <xliff:g id="APPLICATION">%2$s</xliff:g> এর সাথে সংযুক্ত, যেটি ইমেল, অ্যাপ, ও ওয়েবসাইট সহ আপনার কর্মস্থলের নেটওয়ার্ক কার্যকলাপের উপরে নজর রাখতে পারে।\n\nআরো তথ্যের জন্য প্রশাসকের সাথে যোগাযোগ করুন।"</string>
+    <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> আপনার কর্মস্থলের প্রোফাইল পরিচালনা করে। প্রোফাইলটি <xliff:g id="APPLICATION">%2$s</xliff:g> এর সাথে সংযুক্ত, যেটি ইমেল, অ্যাপ, ও ওয়েবসাইট সহ আপনার কর্মস্থলের নেটওয়ার্ক কার্যকলাপের উপরে নজর রাখতে পারে।\n\nআরও তথ্যের জন্য প্রশাসকের সাথে যোগাযোগ করুন।"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> আপনার কর্মস্থলের প্রোফাইল পরিচালনা করে। প্রোফাইলটি <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> এর সাথে সংযুক্ত, যেটি ইমেল অ্যাপ, ও ওয়েবসাইট সহ আপনার কর্মস্থলের নেটওয়ার্ক কার্যকলাপের উপরে নজর রাখতে পারে।\n\n এ ছাড়াও আপনি <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> এর সাথে সংযুক্ত, যেটি আপনার ব্যক্তিগত নেটওয়ার্কে নজর রাখে।"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> এর জন্য আনলক করা হয়েছে"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> চালু আছে"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"আপনি নিজে আনলক না করা পর্যন্ত ডিভাইসটি লক হয়ে থাকবে"</string>
-    <string name="hidden_notifications_title" msgid="7139628534207443290">"বিজ্ঞপ্তিগুলি আরো দ্রুত পান"</string>
+    <string name="hidden_notifications_title" msgid="7139628534207443290">"বিজ্ঞপ্তিগুলি আরও দ্রুত পান"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"আপনি আনলক করার আগে ওগুলো দেখুন"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"না থাক"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"সেট আপ"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="volume_zen_end_now" msgid="6930243045593601084">"এখনই বন্ধ করুন"</string>
-    <string name="accessibility_volume_expand" msgid="5946812790999244205">"প্রসারিত করুন"</string>
+    <string name="accessibility_volume_expand" msgid="5946812790999244205">"বড় করুন"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"সঙ্কুচিত করুন"</string>
-    <string name="screen_pinning_title" msgid="3273740381976175811">"স্ক্রীন পিন করা হয়েছে"</string>
+    <string name="screen_pinning_title" msgid="3273740381976175811">"স্ক্রিন পিন করা হয়েছে"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"এটি আপনি আনপিন না করা পর্যন্ত এটিকে প্রদর্শিত করবে৷ আনপিন করতে ফিরুন এবং ওভারভিউ স্পর্শ করে ধরে থাকুন।"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"এটি আপনি আনপিন না করা পর্যন্ত এটিকে প্রদর্শিত করবে৷ আনপিন করতে ওভারভিউ স্পর্শ করে ধরে থাকুন৷"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"বুঝেছি"</string>
@@ -505,7 +508,7 @@
     <string name="show_battery_percentage" msgid="5444136600512968798">"এম্বেড করা ব্যাটারির শতকরা হার দেখায়"</string>
     <string name="show_battery_percentage_summary" msgid="3215025775576786037">"যখন চার্জ করা হবে না তখন স্থিতি দন্ডের আইকনের ভিতরে ব্যাটারি স্তরের শতকার হার দেখায়"</string>
     <string name="quick_settings" msgid="10042998191725428">"দ্রুত সেটিংস"</string>
-    <string name="status_bar" msgid="4877645476959324760">"স্থিতি দন্ড"</string>
+    <string name="status_bar" msgid="4877645476959324760">"স্ট্যাটাস বার"</string>
     <string name="overview" msgid="4018602013895926956">"এক নজরে"</string>
     <string name="demo_mode" msgid="2532177350215638026">"সিস্টেম UI ডেমো মোড"</string>
     <string name="enable_demo_mode" msgid="4844205668718636518">"ডেমো মোড সক্ষম করুন"</string>
@@ -546,36 +549,41 @@
     <string name="tuner_full_importance_settings" msgid="3207312268609236827">"পাওয়ার বিজ্ঞপ্তির নিয়ন্ত্রণগুলি"</string>
     <string name="tuner_full_importance_settings_on" msgid="7545060756610299966">"চালু আছে"</string>
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"বন্ধ আছে"</string>
-    <string name="power_notification_controls_description" msgid="4372459941671353358">"পাওয়ার বিজ্ঞপ্তির নিয়ন্ত্রণগুলি ব্যহবার করে, আপনি কোনো অ্যাপ্লিকেশানের বিজ্ঞপ্তির জন্য ০ থেকে ৫ পর্যন্ত একটি গুরুত্বের লেভেলকে সেট করতে পারবেন৷ \n\n"<b>"লেভেল ৫"</b>" \n- বিজ্ঞপ্তি তালিকার শীর্ষে দেখায় \n- পূর্ণ স্ক্রীনের বাধাকে অনুমতি দেয় \n- সর্বদা স্ক্রীনে উপস্থিত হয় \n\n"<b>"লেভেল ৪"</b>" \n- পূর্ণ স্ক্রীনের বাধাকে আটকায় \n- সর্বদা স্ক্রীনে উপস্থিত হয় \n\n"<b>"লেভেল ৩"</b>" \n- পূর্ণ স্ক্রীনের বাধাকে আটকায় \n- কখনই স্ক্রীনে উপস্থিত হয় না \n\n"<b>"লেভেল ২"</b>" \n- পূর্ণ স্ক্রীনের বাধাকে আটকায় \n- কখনই স্ক্রীনে উপস্থিত হয় না \n- কখনই শব্দ এবং কম্পন করে না \n\n"<b>"লেভেল ১"</b>" \n- পূর্ণ স্ক্রীনের বাধাকে আটকায় \n- কখনই স্ক্রীনে উপস্থিত হয় না \n- কখনই শব্দ এবং কম্পন করে না \n- লক স্ক্রীন এবং স্থিতি দন্ড থেকে লুকায় \n- বিজ্ঞপ্তি তালিকার নীচের দিকে দেখায় \n\n"<b>"লেভেল ০"</b>" \n- অ্যাপ্লিকেশান থেকে সমস্ত বিজ্ঞপ্তিকে অবরূদ্ধ করে"</string>
+    <string name="power_notification_controls_description" msgid="4372459941671353358">"পাওয়ার বিজ্ঞপ্তির নিয়ন্ত্রণগুলি ব্যহবার করে, আপনি কোনও অ্যাপ্লিকেশনের বিজ্ঞপ্তির জন্য ০ থেকে ৫ পর্যন্ত একটি গুরুত্বের লেভেলকে সেট করতে পারবেন৷ \n\n"<b>"লেভেল ৫"</b>" \n- বিজ্ঞপ্তি তালিকার শীর্ষে দেখায় \n- পূর্ণ স্ক্রিনের বাধাকে অনুমতি দেয় \n- সর্বদা স্ক্রিনে উপস্থিত হয় \n\n"<b>"লেভেল ৪"</b>" \n- পূর্ণ স্ক্রিনের বাধাকে আটকায় \n- সর্বদা স্ক্রিনে উপস্থিত হয় \n\n"<b>"লেভেল ৩"</b>" \n- পূর্ণ স্ক্রিনের বাধাকে আটকায় \n- কখনওই স্ক্রিনে উপস্থিত হয় না \n\n"<b>"লেভেল ২"</b>" \n- পূর্ণ স্ক্রিনের বাধাকে আটকায় \n- কখনওই স্ক্রিনে উপস্থিত হয় না \n- কখনওই শব্দ এবং কম্পন করে না \n\n"<b>"লেভেল ১"</b>" \n- পূর্ণ স্ক্রিনের বাধাকে আটকায় \n- কখনওই স্ক্রিনে উপস্থিত হয় না \n- কখনওই শব্দ এবং কম্পন করে না \n- লক স্ক্রিন এবং স্ট্যাটাস বার থেকে লুকায় \n- বিজ্ঞপ্তি তালিকার নীচের দিকে দেখায় \n\n"<b>"লেভেল ০"</b>" \n- অ্যাপ্লিকেশন থেকে সমস্ত বিজ্ঞপ্তিকে অবরূদ্ধ করে"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"বিজ্ঞপ্তি"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"আপনি আর এই বিজ্ঞপ্তিগুলি পাবেন না।"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"আপনি এই বিজ্ঞপ্তিগুলি আর পাবেন না"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> বিজ্ঞপ্তির বিভাগগুলি"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"এই অ্যাপটিতে বিজ্ঞপ্তির বিভাগ নেই"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"এই অ্যাপ থেকে আসা বিজ্ঞপ্তি বন্ধ করা যাবে না"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">এই অ্যাপের <xliff:g id="NUMBER_1">%d</xliff:g>টি বিজ্ঞপ্তির বিভাগের মধ্যে ১টি</item>
       <item quantity="other">এই অ্যাপের <xliff:g id="NUMBER_1">%d</xliff:g>টি বিজ্ঞপ্তির বিভাগের মধ্যে ১টি</item>
     </plurals>
     <string name="notification_channels_list_desc_2" msgid="6214732715833946441">"<xliff:g id="CHANNEL_NAME_1">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2">%2$s</xliff:g>"</string>
     <plurals name="notification_channels_list_desc_2_and_others" formatted="false" msgid="2747813553355336157">
-      <item quantity="one"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g>, এবং আরো <xliff:g id="NUMBER_5">%3$d</xliff:g>টি</item>
-      <item quantity="other"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g>, এবং আরো <xliff:g id="NUMBER_5">%3$d</xliff:g>টি</item>
+      <item quantity="one"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g>, এবং আরও <xliff:g id="NUMBER_5">%3$d</xliff:g>টি</item>
+      <item quantity="other"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g>, এবং আরও <xliff:g id="NUMBER_5">%3$d</xliff:g>টি</item>
     </plurals>
     <string name="notification_channel_controls_opened_accessibility" msgid="6553950422055908113">"<xliff:g id="APP_NAME">%1$s</xliff:g> খোলা থাকলে বিজ্ঞপ্তি নিয়ন্ত্রণ"</string>
     <string name="notification_channel_controls_closed_accessibility" msgid="7521619812603693144">"<xliff:g id="APP_NAME">%1$s</xliff:g> বন্ধ থাকলে বিজ্ঞপ্তি নিয়ন্ত্রণ"</string>
     <string name="notification_channel_switch_accessibility" msgid="3420796005601900717">"এই চ্যানেল থেকে বিজ্ঞপ্তি আসতে দেয়"</string>
     <string name="notification_all_categories" msgid="5407190218055113282">"সকল বিভাগ"</string>
-    <string name="notification_more_settings" msgid="816306283396553571">"আরো সেটিংস"</string>
+    <string name="notification_more_settings" msgid="816306283396553571">"আরও সেটিংস"</string>
     <string name="notification_app_settings" msgid="3743278649182392015">"কাস্টমাইজ করুন: <xliff:g id="SUB_CATEGORY">%1$s</xliff:g>"</string>
     <string name="notification_done" msgid="5279426047273930175">"সম্পন্ন"</string>
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"বিজ্ঞপ্তির নিয়ন্ত্রণগুলি"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"বিজ্ঞপ্তি মনে করিয়ে দেওয়ার বিকল্পগুলি"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"১৫ মিনিট"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"৩০ মিনিট"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"১ ঘণ্টা"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"২ ঘণ্টা"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"পূর্বাবস্থায় ফিরুন"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> পরে আবার মনে করানো হবে"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d ঘণ্টা</item>
+      <item quantity="other">%d ঘণ্টা</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d মিনিট</item>
+      <item quantity="other">%d মিনিট</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"ব্যাটারির ব্যবহার"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"চার্জ করার সময় ব্যাটারি সেভার উপলব্ধ নয়"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ব্যাটারি সেভার"</string>
@@ -625,7 +633,7 @@
     <string name="tuner_full_zen_title" msgid="4540823317772234308">"ভলিউম নিয়ন্ত্রণ সহ দেখান"</string>
     <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"বিরক্ত করবেন না"</string>
     <string name="volume_dnd_silent" msgid="4363882330723050727">"ভলিউম বোতামের শর্টকাট"</string>
-    <string name="volume_up_silent" msgid="7141255269783588286">"ভলিউম বাড়ানোর মাধ্যেমে \'বিরক্ত করবেন না\' থেকে প্রস্থান করুন"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"ভলিউম বাড়ানোর মাধ্যেমে \'বিরক্ত করবেন না\' থেকে বেরিয়ে আসুন"</string>
     <string name="battery" msgid="7498329822413202973">"ব্যাটারি"</string>
     <string name="clock" msgid="7416090374234785905">"ঘড়ি"</string>
     <string name="headset" msgid="4534219457597457353">"হেডসেট"</string>
@@ -636,7 +644,7 @@
     <string name="accessibility_data_saver_off" msgid="8841582529453005337">"ডেটা সেভার বন্ধ আছে"</string>
     <string name="switch_bar_on" msgid="1142437840752794229">"চালু আছে"</string>
     <string name="switch_bar_off" msgid="8803270596930432874">"বন্ধ আছে"</string>
-    <string name="nav_bar" msgid="1993221402773877607">"নেভিগেশন দন্ড"</string>
+    <string name="nav_bar" msgid="1993221402773877607">"নেভিগেশন বার"</string>
     <string name="nav_bar_layout" msgid="3664072994198772020">"লেআউট"</string>
     <string name="left_nav_bar_button_type" msgid="8555981238887546528">"অতিরিক্ত বাঁদিকের বোতামের ধরণ"</string>
     <string name="right_nav_bar_button_type" msgid="2481056627065649656">"অতিরিক্ত ডানদিকের বোতামের ধরণ"</string>
@@ -649,16 +657,16 @@
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"সাধারণ"</item>
-    <item msgid="8256205964297588988">"নিবিড়"</item>
+    <item msgid="8256205964297588988">"অবিস্তৃত"</item>
     <item msgid="8719936228094005878">"বাঁদিক ঘেঁষা"</item>
     <item msgid="586019486955594690">"ডানদিক ঘেঁষা"</item>
   </string-array>
     <string name="menu_ime" msgid="4998010205321292416">"কিবোর্ড স্যুইচার"</string>
-    <string name="save" msgid="2311877285724540644">"সংরক্ষণ করুন"</string>
+    <string name="save" msgid="2311877285724540644">"সেভ করুন"</string>
     <string name="reset" msgid="2448168080964209908">"আবার সেট করুন"</string>
     <string name="adjust_button_width" msgid="6138616087197632947">"বোতামের প্রস্থ সমন্বয় করুন"</string>
     <string name="clipboard" msgid="1313879395099896312">"ক্লিপবোর্ড"</string>
-    <string name="accessibility_key" msgid="5701989859305675896">"কাস্টম নেভিগেশান বোতাম"</string>
+    <string name="accessibility_key" msgid="5701989859305675896">"কাস্টম নেভিগেশন বোতাম"</string>
     <string name="left_keycode" msgid="2010948862498918135">"বাঁদিকের কিকোড"</string>
     <string name="right_keycode" msgid="708447961000848163">"ডানদিকের কিকোড"</string>
     <string name="left_icon" msgid="3096287125959387541">"বাঁ দিকের আইকন"</string>
@@ -714,7 +722,7 @@
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ক্রম বা সেটিংস সম্পাদনা করুন৷"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g>টির মধ্যে <xliff:g id="ID_1">%1$d</xliff:g> নং পৃষ্ঠা"</string>
     <string name="tuner_lock_screen" msgid="5755818559638850294">"লক স্ক্রিন"</string>
-    <string name="pip_phone_expand" msgid="5889780005575693909">"প্রসারিত করুন"</string>
+    <string name="pip_phone_expand" msgid="5889780005575693909">"বড় করুন"</string>
     <string name="pip_phone_minimize" msgid="1079119422589131792">"ছোটো করুন"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"বন্ধ করুন"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"খারিজ করতে নিচের দিকে টেনে আনুন"</string>
@@ -745,13 +753,13 @@
     <string name="tuner_right" msgid="6222734772467850156">"ডান"</string>
     <string name="tuner_menu" msgid="191640047241552081">"মেনু"</string>
     <string name="tuner_app" msgid="3507057938640108777">"<xliff:g id="APP">%1$s</xliff:g> অ্যাপ"</string>
-    <string name="notification_channel_alerts" msgid="4496839309318519037">"সতর্কতাগুলি"</string>
+    <string name="notification_channel_alerts" msgid="4496839309318519037">"সতর্কতা"</string>
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"স্ক্রীনশটস"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"সাধারণ বার্তাগুলি"</string>
-    <string name="notification_channel_storage" msgid="3077205683020695313">"সঞ্চয়স্থান"</string>
+    <string name="notification_channel_storage" msgid="3077205683020695313">"স্টোরেজ"</string>
     <string name="instant_apps" msgid="6647570248119804907">"ঝটপট অ্যাপ"</string>
     <string name="instant_apps_message" msgid="8116608994995104836">"ঝটপট অ্যাপ ইনস্টল করার প্রয়োজন হয় না।"</string>
-    <string name="app_info" msgid="6856026610594615344">"অ্যাপ্লিকেশানের তথ্য"</string>
+    <string name="app_info" msgid="6856026610594615344">"অ্যাপের তথ্য"</string>
     <string name="go_to_web" msgid="1106022723459948514">"ওয়েবে যান"</string>
     <string name="mobile_data" msgid="7094582042819250762">"মোবাইল ডেটা"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"ওয়াই ফাই বন্ধ আছে"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"বদলে দিন"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"পটভূমিতে অ্যাপ চালু আছে"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"ব্যাটারি এবং ডেটার ব্যবহারের বিশদ বিবরণের জন্য ট্যাপ করুন"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"মোবাইল ডেটা বন্ধ করবেন?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings_car.xml b/packages/SystemUI/res/values-bn/strings_car.xml
index d8a8732..d014c02 100644
--- a/packages/SystemUI/res/values-bn/strings_car.xml
+++ b/packages/SystemUI/res/values-bn/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"সাবধানে চালান"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"গাড়ি চালানোর সময় সর্বদা সতর্ক থাকুন এবং প্রযোজ্য আইন মেনে চলুন৷ দিকনির্দেশ ভুল, অসম্পূর্ণ, বিপজ্জনক, অনুপযুক্ত, নিষিদ্ধ হতে পারে বা প্রশাসনিক এলাকাগুলি অতিক্রম করতে হতে পারে৷ বাণিজ্যিক তথ্য ভুল বা অসম্পূর্ণ হতে পারে৷ ডেটা প্রকৃত সময়ের নয় এবং অবস্থানের নির্ভুলতা নিশ্চিত করাও সম্ভব নয়৷ গাড়ি চালানোর সময় আপনার মোবাইল ডিভাইসটিকে বা Android Auto এর জন্য উপযুক্ত নয় এমন অ্যাপগুলিকে ব্যবহার করবেন না৷"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"অজানা"</string>
+    <string name="start_driving" msgid="864023351402918991">"ড্রাইভিং শুরু করুন"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 27390b9..1d1632f 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -76,7 +76,7 @@
     <string name="screenshot_failed_title" msgid="705781116746922771">"Došlo je do greške prilikom snimanja ekrana."</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Došlo je do problema prilikom spašavanja snimka ekrana."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Snimak ekrana se ne može sačuvati zbog manjka prostora za pohranu."</string>
-    <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Aplikacija ili vaša organizacija ne dopuštaju pravljenje snimaka ekrana."</string>
+    <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Ova aplikacija ili vaša organizacija ne dozvoljavaju snimanje ekrana"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prijenosa fajlova"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Reproduciranje medijskih sadržaja (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Priključiti kao kameru (PTP)"</string>
@@ -91,7 +91,7 @@
     <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
     <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Glasovna pomoć"</string>
     <string name="accessibility_unlock_button" msgid="128158454631118828">"Otključaj"</string>
-    <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Dugme za otključavanje, čeka se na otisak prsta"</string>
+    <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"Čeka se otisak prsta"</string>
     <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Otključaj bez korištenja otiska prsta"</string>
     <string name="unlock_label" msgid="8779712358041029439">"otključaj"</string>
     <string name="phone_label" msgid="2320074140205331708">"otvori telefon"</string>
@@ -153,11 +153,12 @@
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"Nema SIM kartice."</string>
-    <string name="accessibility_cell_data" msgid="7080312242791850520">"Mobilni podaci"</string>
-    <string name="accessibility_cell_data_on" msgid="4310018593519761767">"Prijenos mobilnih podataka uključen"</string>
-    <string name="accessibility_cell_data_off" msgid="8000803571751407635">"Mobilni podaci isključeni"</string>
+    <string name="accessibility_cell_data" msgid="5326139158682385073">"Mobilni podaci"</string>
+    <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Mobilni podaci su uključeni"</string>
+    <string name="accessibility_cell_data_off" msgid="443267573897409704">"Mobilni podaci su isključeni"</string>
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Dijeljenje Bluetooth veze."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Način rada u avionu."</string>
+    <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN uključen."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Nema SIM kartice."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Promjena mreže operatera."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Otvori detalje o potrošnji baterije"</string>
@@ -165,7 +166,7 @@
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Punjenje baterije, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procenata."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Postavke sistema."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obavještenja."</string>
-    <string name="notification_shelf_content_description" msgid="5511922384591583913">"Spremnik za prelijevanje obavještenja"</string>
+    <string name="accessibility_overflow_action" msgid="5681882033274783311">"Vidite sva obavještenja"</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Ukloniti obavještenje."</string>
     <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS omogućen."</string>
     <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Uspostavljanje GPS veze."</string>
@@ -237,13 +238,12 @@
     <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Ušteda podataka je isključena."</string>
     <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Ušteda podataka je uključena."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Osvjetljenje ekrana"</string>
-    <!-- no translation found for accessibility_ambient_display_charging (9084521679384069087) -->
-    <skip />
+    <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Punjenje"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G prijenos podataka je pauzirano"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G prijenos podataka je pauzirano"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"Mobilni podaci su pauzirani"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Mobilni podaci su pauzirani"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Prijenos podataka je pauziran"</string>
-    <string name="data_usage_disabled_dialog" msgid="1841738975235283398">"Dostigli ste ograničenje za prijenos podataka koje ste postavili. Više ne koristite mobilne podatke.\n\nUkoliko nastavite koristiti mobilne podatke, mogući su troškovi za prijenos podataka."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Dostigli ste ograničenje za prijenos podataka koje ste postavili. Više ne koristite mobilne podatke.\n\nUkoliko nastavite koristiti mobilne podatke, mogući su troškovi za prijenos podataka."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Nastavi"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Niste povezani na internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi veza aktivna"</string>
@@ -279,7 +279,7 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Osvjetljenje"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Automatsko rotiranje"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"Automatsko rotiranje ekrana"</string>
-    <string name="accessibility_quick_settings_rotation_value" msgid="1428962304214992318">"Postaviti način rada: <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"Način rada <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Rotiranje je zaključano"</string>
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Uspravno"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Vodoravno"</string>
@@ -300,10 +300,10 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi isključen"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi uključen"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nema dostupnih Wi-Fi mreža"</string>
-    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Prebacivanje"</string>
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Emitiranje"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Prebacivanje"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Neimenovani uređaj"</string>
-    <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Spreman za prebacivanje"</string>
+    <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Spreman za emitiranje"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Nema dostupnih uređaja"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Osvjetljenje"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
@@ -317,7 +317,7 @@
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Pristupna tačka"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Obavještenja"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Svjetiljka"</string>
-    <string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Mobilni podaci"</string>
+    <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilni podaci"</string>
     <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Prijenos podataka"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Preostala količina podataka"</string>
     <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Prekoračeno"</string>
@@ -337,7 +337,6 @@
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacija <xliff:g id="APP">%s</xliff:g> nije pokrenuta."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> je onemogućena u sigurnom načinu rada."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Obriši sve"</string>
-    <string name="recents_incompatible_app_message" msgid="5075812958564082451">"Aplikacija ne podržava dijeljenje ekrana."</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Povucite ovdje za korištenje podijeljenog ekrana"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podjela po horizontali"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Podjela po vertikali"</string>
@@ -352,10 +351,10 @@
     <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Do kraja punjenja preostalo <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
     <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"Ne puni se"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Mreža može \n biti nadzirana"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Traži"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Pretraživanje"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Povucite gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Povucite lijevo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="3070506961866919502">"Zvukovi i vibracije vas neće uznemiravati, osim alarma, podsjetnika, događaja i pozivalaca koje odredite."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Neće vas ometati zvukovi i vibracije, osim alarma, podsjetnika, događaja i pozivalaca koje odredite."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Prilagodi"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ovim se blokiraju SVI zvukovi i vibracije, uključujući alarme, muziku, videozapise i igre. I dalje ćete moći obavljati pozive."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Ovim se blokiraju SVI zvukovi i vibracije, uključujući alarme, muziku, video zapise i igre."</string>
@@ -363,7 +362,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Prikaži manje važna obavještenja ispod"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite ponovo da otvorite"</string>
     <string name="keyguard_unlock" msgid="8043466894212841998">"Prevucite prema gore da otključate"</string>
-    <string name="do_disclosure_generic" msgid="8498005633306135779">"Ovim uređajem upravlja"</string>
+    <string name="do_disclosure_generic" msgid="5615898451805157556">"Ovim uređajem upravlja vaša organizacija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Prevucite preko ikone da otvorite telefon"</string>
     <string name="voice_hint" msgid="8939888732119726665">"Prevucite preko ikone za glasovnu pomoć"</string>
@@ -416,13 +415,40 @@
     <string name="profile_owned_footer" msgid="8021888108553696069">"Profil može biti nadziran"</string>
     <string name="vpn_footer" msgid="2388611096129106812">"Mreža može biti nadzirana"</string>
     <string name="branded_vpn_footer" msgid="2168111859226496230">"Mreža može biti nadzirana"</string>
-    <string name="monitoring_title_device_owned" msgid="7121079311903859610">"Praćenje uređaja"</string>
+    <string name="quick_settings_disclosure_management_monitoring" msgid="6645176135063957394">"Vaša organizacija upravlja ovim uređajem i može pratiti mrežni promet."</string>
+    <string name="quick_settings_disclosure_named_management_monitoring" msgid="370622174777570853">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> upravlja ovim uređajem i može pratiti vaš mrežni promet"</string>
+    <string name="quick_settings_disclosure_management_named_vpn" msgid="1085137869053332307">"Uređajem upravlja vaša organizacija i povezan je s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="6290456493852584017">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s aplikacijom <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_management" msgid="3294967280853150271">"Uređajem upravlja vaša organizacija"</string>
+    <string name="quick_settings_disclosure_named_management" msgid="1059403025094542908">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>."</string>
+    <string name="quick_settings_disclosure_management_vpns" msgid="3698767349925266482">"Uređajem upravlja vaša organizacija i povezan je s VPN-ovima"</string>
+    <string name="quick_settings_disclosure_named_management_vpns" msgid="7777821385318891527">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s VPN-ovima"</string>
+    <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="5125463987558278215">"Vaša organizacija može pratiti mrežni promet na vašem profilu."</string>
+    <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8973606847896650284">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može pratiti mrežni promet na vašem radnom profilu"</string>
+    <string name="quick_settings_disclosure_monitoring" msgid="679658227269205728">"Mreža može biti nadzirana"</string>
+    <string name="quick_settings_disclosure_vpns" msgid="8170318392053156330">"Uređaj je povezan s VPN-ovima"</string>
+    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="3494535754792751741">"Radni profil je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4467456202486569906">"Lični profil je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_vpn" msgid="6943724064780847080">"Uređaj je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_device_owned" msgid="1652495295941959815">"Upravljanje uređajem"</string>
     <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"Praćenje profila"</string>
     <string name="monitoring_title" msgid="169206259253048106">"Praćenje mreže"</string>
     <string name="monitoring_subtitle_vpn" msgid="876537538087857300">"VPN mreža"</string>
-    <string name="monitoring_subtitle_network_logging" msgid="5569072711320784030">"Zapisivanje na mreži"</string>
+    <string name="monitoring_subtitle_network_logging" msgid="3341264304793193386">"Zapisivanje na mreži"</string>
+    <string name="monitoring_subtitle_ca_certificate" msgid="3874151893894355988">"CA certifikati"</string>
     <string name="disable_vpn" msgid="4435534311510272506">"Isključi VPN"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"Prekini VPN vezu"</string>
+    <string name="monitoring_button_view_policies" msgid="100913612638514424">"Prikaži pravila"</string>
+    <string name="monitoring_description_named_management" msgid="5281789135578986303">"Vašim uređajem upravlja organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVaš administrator može nadgledati i upravljati vašim postavkama, korporativnom pristupu, aplikacijama, podacima koji su povezani s vašim uređajem i informacijama o lokaciji vašeg uređaja.\n\nZa više informacija, obratite se svom administratoru."</string>
+    <string name="monitoring_description_management" msgid="4573721970278370790">"Vašim uređajem upravlja vaša organizacija.\n\nVaš administrator može nadgledati i upravljati vašim postavkama, korporativnom pristupu, aplikacijama, podacima koji su povezani s vašim uređajem i informacijama o lokaciji vašeg uređaja.\n\nZa više informacija, obratite se svom administratoru."</string>
+    <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"Vaša organizacija je instalirala CA certifikat na ovom uređaju. Vaš promet preko sigurne mreže može se pratiti."</string>
+    <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"Vaša organizacija je instalirala CA certifikat na vašem radnom profilu. Vaš promet preko sigurne mreže može se pratiti."</string>
+    <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"CA certifikat je instaliran na ovom uređaju. Vaš promet preko sigurne mreže može se pratiti."</string>
+    <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"Vaš administrator je uključio zapisivanje na mreži, čime se prati promet na vašem uređaju."</string>
+    <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"Povezani ste s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g> koja može pratiti vašu aktivnost na mreži, uključujući e-poštu i web lokacije."</string>
+    <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"Povezani ste s aplikacijama <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g> koje mogu pratiti vašu aktivnost na mreži, uključujući e-poštu, aplikacije i web lokacije."</string>
+    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"Vaš radni profil je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>, koja može pratiti vašu aktivnost na mreži, uključujući e-poruke i web lokacije."</string>
+    <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"Vaš lični profil je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>, koja može pratiti vašu aktivnost na mreži, uključujući e-poruke, aplikacije i web lokacije."</string>
     <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"Vašim uređajem upravlja aplikacija <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g>."</string>
     <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> koristi aplikaciju <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> za upravljanje vašim uređajem."</string>
     <string name="monitoring_description_do_body" msgid="3639594537660975895">"Vaš administrator može pratiti postavke, korporativni pristup, aplikacije, podatke povezane s vašim uređajem i informacije o lokaciji vašeg uređaja."</string>
@@ -431,15 +457,19 @@
     <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"Povezani ste s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>, koja može pratiti vašu aktivnost na mreži, uključujući e-poruke i web lokacije."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"Postavke otvorene VPN mreže"</string>
+    <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
+    <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"Otvorite pouzdane akreditive"</string>
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"Vaš administrator je uključio zapisivanje na mreži, čime se prati saobraćaj na vašem uređaju.\n\nZa više informacija, obratite se administratoru."</string>
     <string name="monitoring_description_vpn" msgid="4445150119515393526">"Jednoj aplikaciji ste dali odobrenje da uspostavi VPN vezu.\n\nTa aplikacija može pratiti vašu aktivnost na uređaju i mreži, uključujući e-poštu, aplikacije i web-lokacije."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"Vašim radnim profilom upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nVaš administrator može pratiti vašu aktivnost na radnoj mreži, uključujući e-poruke, aplikacije i web lokacije.\n\nZa više informacija, obratite se administratoru.\n\nPovezani ste i na VPN, koji može pratiti vašu aktivnost na mreži."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
-    <string name="monitoring_description_app" msgid="6259179342284742878">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može pratiti vašu aktivnost na mreži, uključujući e-mailove, aplikacije i web-lokacije."</string>
+    <string name="monitoring_description_app" msgid="1828472472674709532">"Povezani ste s aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može pratiti vašu aktivnost na mreži, uključujući e-poruke, aplikacije i web lokacije."</string>
     <string name="monitoring_description_app_personal" msgid="484599052118316268">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može pratiti vašu aktivnost na privatnoj mreži, uključujući e-mailove, aplikacije i web-lokacije."</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Povezani ste na aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može pratiti vaše privatne aktivnosti na mreži, uključujući e-poštu, aplikacije i web stranice."</string>
-    <string name="monitoring_description_app_work" msgid="7777228449969022305">"Vašim radnim profilom upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je s aplikacijom <xliff:g id="APPLICATION">%2$s</xliff:g>, koja može pratiti vašu aktivnost na radnoj mreži, uključujući e-poruke, aplikacije i web lokacije.\n\nZa više informacija, obratite se svom administratoru."</string>
-    <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"Profilom za posao upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je sa aplikacijom <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, koja može pratiti vašu aktivnost na radnoj mreži, uključujući e-poštu, aplikacije i web-lokacije.\n\nPovezani ste i sa aplikacijom <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, koja može pratiti vašu aktivnost na privatnoj mreži."</string>
+    <string name="monitoring_description_app_work" msgid="4612997849787922906">"Vašim radnim profilom upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil je povezan s aplikacijom <xliff:g id="APPLICATION">%2$s</xliff:g>, koja može pratiti vašu aktivnost na radnoj mreži, uključujući e-poruke, aplikacije i web lokacije.\n\nZa više informacija, obratite se svom administratoru."</string>
+    <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Radnim profilom upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil je povezan s aplikacijom <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, koja može pratiti vašu aktivnost na radnoj mreži, uključujući e-poruke, aplikacije i web lokacije.\n\nPovezani ste i sa aplikacijom <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, koja može pratiti vašu aktivnost na privatnoj mreži."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Otključano za korisnika <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Agent <xliff:g id="TRUST_AGENT">%1$s</xliff:g> je pokrenut"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Uređaj će ostati zaključan dok ga ručno ne otključate"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Brže primaj obavještenja"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Vidi ih prije otključavanja"</string>
@@ -452,7 +482,7 @@
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekran je prikačen"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Ekran ostaje prikazan ovako dok ga ne otkačite. Da ga otkačite, dodirnite i držite dugme Nazad."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Ekran ostaje prikazan ovako dok ga ne otkačite. Da ga otkačite, dodirnite i držite dugme Pregled."</string>
-    <string name="screen_pinning_positive" msgid="3783985798366751226">"Jasno mi je"</string>
+    <string name="screen_pinning_positive" msgid="3783985798366751226">"Razumijem"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Želite li sakriti <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Pojavit će se sljedeći put kada opciju uključite u postavkama."</string>
@@ -472,10 +502,8 @@
     <skip />
     <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Dodirnite za postavljanje vibracije. Zvukovi usluga pristupačnosti mogu biti isključeni."</string>
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Dodirnite da isključite zvuk. Zvukovi usluga pristupačnosti mogu biti isključeni."</string>
-    <!-- no translation found for volume_stream_content_description_vibrate_a11y (6427727603978431301) -->
-    <skip />
-    <!-- no translation found for volume_stream_content_description_mute_a11y (8995013018414535494) -->
-    <skip />
+    <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Dodirnite da postavite vibraciju."</string>
+    <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Dodirnite da isključite zvuk."</string>
     <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Prikazane kontrole jačine zvuka za: %s. Prevucite prema gore za odbacivanje."</string>
     <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Kontrole jačine zvuka sakrivene"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Podešavač za korisničko sučelje sistema"</string>
@@ -503,7 +531,7 @@
     <string name="tuner_warning_title" msgid="7094689930793031682">"Zabava za neke, ali ne za sve"</string>
     <string name="tuner_warning" msgid="8730648121973575701">"Podešavač za korisničko sučelje sistema vam omogućava dodatne načine da podesite i prilagodite Androidovo sučelje. Ove eksperimentalne funkcije se u budućim verzijama mogu mijenjati, kvariti ili nestati. Budite oprezni."</string>
     <string name="tuner_persistent_warning" msgid="8597333795565621795">"Ove eksperimentalne funkcije se u budućim verzijama mogu mijenjati, kvariti ili nestati. Budite oprezni."</string>
-    <string name="got_it" msgid="2239653834387972602">"Jasno mi je"</string>
+    <string name="got_it" msgid="2239653834387972602">"Razumijem"</string>
     <string name="tuner_toast" msgid="603429811084428439">"Čestitamo! Podešavač za korisničko sučelje sistema je dodan u Postavke"</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"Ukloni iz Postavki"</string>
     <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Želite li ukloniti Podešavač za korisničko sučelje sistema iz Postavki i prestati koristiti sve njegove funkcije?"</string>
@@ -525,25 +553,37 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Isključeno"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Uz kontrolu obavještenja o napajanju, možete postaviti nivo značaja obavještenja iz aplikacije, i to od nivoa 0 do 5. \n\n"<b>"Nivo 5"</b>" \n- Prikaži na vrhu liste obavještenja \n- Dopusti prekid prikaza cijelog ekrana \n- Uvijek izviruj \n\n"<b>"Nvio 4"</b>" \n- Spriječi prekid prikaza cijelog ekrana \n- Uvijek izviruj \n\n"<b>"Nivo 3"</b>" \n- Spriječi prekid prikaza cijelog ekrana \n- Nikad ne izviruj \n\n"<b>"Nivo 2"</b>" \n- Spriječi prekid prikaza cijelog ekrana \n- Nikad ne izviruj \n- Nikada ne puštaj zvuk ili vibraciju \n\n"<b>"Nivo 1"</b>" \n- Spriječi prekid prikaza cijelog ekrana \n- Nikada ne izviruj \n- Nikada ne puštaj zvuk ili vibraciju \n- Sakrij sa ekrana za zaključavanje i statusne trake \n- Prikaži na dnu liste obavještenja \n\n"<b>"Nivo 0"</b>" \n- Blokiraj sva obavještenja iz aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obavještenja"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Nećete više primati ova obavještenja."</string>
-    <plurals name="notification_num_channels_desc" formatted="false" msgid="8808748716499517938">
-      <item quantity="one">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije iz ove aplikacije</item>
-      <item quantity="few">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije iz ove aplikacije</item>
-      <item quantity="other">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorija iz ove aplikacije</item>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Nećete više primati ova obavještenja"</string>
+    <string name="notification_num_channels" msgid="2048144408999179471">"Kategorije obavještenja: <xliff:g id="NUMBER">%d</xliff:g>"</string>
+    <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ova aplikacija nema kategorije obavještenja"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
+    <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
+      <item quantity="one">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije obavještenja iz ove aplikacije</item>
+      <item quantity="few">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije obavještenja iz ove aplikacije</item>
+      <item quantity="other">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorija obavještenja iz ove aplikacije</item>
     </plurals>
+    <string name="notification_channels_list_desc_2" msgid="6214732715833946441">"<xliff:g id="CHANNEL_NAME_1">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2">%2$s</xliff:g>"</string>
+    <plurals name="notification_channels_list_desc_2_and_others" formatted="false" msgid="2747813553355336157">
+      <item quantity="one"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g>, i još <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+      <item quantity="few"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g>, i još <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+      <item quantity="other"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g>, i još <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+    </plurals>
+    <string name="notification_channel_controls_opened_accessibility" msgid="6553950422055908113">"Otvorene su kontrole obavještenja za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="notification_channel_controls_closed_accessibility" msgid="7521619812603693144">"Zatvorene su kontrole obavještenja za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="notification_channel_switch_accessibility" msgid="3420796005601900717">"Dozvoli obavještenja s ovog kanala"</string>
     <string name="notification_all_categories" msgid="5407190218055113282">"Sve kategorije"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Više postavki"</string>
+    <string name="notification_app_settings" msgid="3743278649182392015">"Prilagodite: <xliff:g id="SUB_CATEGORY">%1$s</xliff:g>"</string>
     <string name="notification_done" msgid="5279426047273930175">"Gotovo"</string>
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kontrole obavještenja"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opcije za odgodu obavještenja"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 sat"</string>
-    <string name="snooze_option_dont_snooze" msgid="655446566007801922">"Ne odgađaj"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"OPOZOVI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odgođeno za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <string name="battery_panel_title" msgid="7944156115535366613">"Upotreba baterije"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
+    <string name="battery_panel_title" msgid="7944156115535366613">"Potrošnja baterije"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ušteda baterije je isključena prilikom punjenja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ušteda baterije"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Ograničava rad i prijenos podataka u pozadini"</string>
@@ -578,7 +618,7 @@
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni ekrani"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Nazad"</string>
     <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Obavještenja"</string>
-    <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Skracenice tastature"</string>
+    <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Prečice tastature"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Promijeni način unosa"</string>
     <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplikacije"</string>
     <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Pomoć"</string>
@@ -602,7 +642,7 @@
     <string name="accessibility_data_saver_on" msgid="8454111686783887148">"Ušteda podataka je uključena"</string>
     <string name="accessibility_data_saver_off" msgid="8841582529453005337">"Ušteda podataka je isključena"</string>
     <string name="switch_bar_on" msgid="1142437840752794229">"Uključeno"</string>
-    <string name="switch_bar_off" msgid="8803270596930432874">"Isključi"</string>
+    <string name="switch_bar_off" msgid="8803270596930432874">"Isključeno"</string>
     <string name="nav_bar" msgid="1993221402773877607">"Navigaciona traka"</string>
     <string name="nav_bar_layout" msgid="3664072994198772020">"Raspored"</string>
     <string name="left_nav_bar_button_type" msgid="8555981238887546528">"Dodatni tip dugmeta lijevo"</string>
@@ -612,7 +652,7 @@
     <item msgid="1545641631806817203">"Međumemorija"</item>
     <item msgid="5742013440802239414">"Kôd tipke"</item>
     <item msgid="8802889973626281575">"Prebacivač tastatura"</item>
-    <item msgid="8175437057325747277">"Nema"</item>
+    <item msgid="8175437057325747277">"Ništa"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normalna"</item>
@@ -622,7 +662,7 @@
   </string-array>
     <string name="menu_ime" msgid="4998010205321292416">"Prebacivač tastatura"</string>
     <string name="save" msgid="2311877285724540644">"Sačuvaj"</string>
-    <string name="reset" msgid="2448168080964209908">"Ponovno pokretanje"</string>
+    <string name="reset" msgid="2448168080964209908">"Vraćanje na zadano"</string>
     <string name="adjust_button_width" msgid="6138616087197632947">"Podesite širinu dugmeta"</string>
     <string name="clipboard" msgid="1313879395099896312">"Međumemorija"</string>
     <string name="accessibility_key" msgid="5701989859305675896">"Prilagođeno dugme za navigaciju"</string>
@@ -630,7 +670,7 @@
     <string name="right_keycode" msgid="708447961000848163">"Kôd tipke desno"</string>
     <string name="left_icon" msgid="3096287125959387541">"Ikona lijevo"</string>
     <string name="right_icon" msgid="3952104823293824311">"Ikona desno"</string>
-    <string name="drag_to_add_tiles" msgid="7058945779098711293">"Povucite da dodate polja"</string>
+    <string name="drag_to_add_tiles" msgid="7058945779098711293">"Prevucite da dodate pločice"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Prevucite ovdje za uklanjanje"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Uredi"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Vrijeme"</string>
@@ -668,6 +708,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> obavještenje: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacija možda neće raditi na podijeljenom ekranu"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacija ne podržava dijeljenje ekrana."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Aplikacija možda neće raditi na sekundarnom ekranu."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Otvori postavke."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Otvoriti brze postavke."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Zatvoriti brze postavke."</string>
@@ -682,6 +724,17 @@
     <string name="pip_phone_expand" msgid="5889780005575693909">"Proširi"</string>
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Umanji"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Zatvori"</string>
+    <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Povucite prema dolje da odbacite"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Meni za način rada Slika u slici"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> je u načinu priakza Slika u slici"</string>
+    <string name="pip_notification_message" msgid="4171698133469539591">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da otvorite postavke i isključite je."</string>
+    <string name="pip_play" msgid="1417176722760265888">"Reproduciraj"</string>
+    <string name="pip_pause" msgid="8881063404466476571">"Pauziraj"</string>
+    <string name="pip_skip_to_next" msgid="1948440006726306284">"Preskoči na sljedeći"</string>
+    <string name="pip_skip_to_prev" msgid="1955311326688637914">"Preskoči na prethodni"</string>
+    <string name="thermal_shutdown_title" msgid="4458304833443861111">"Telefon se isključio zbog pregrijavanja"</string>
+    <string name="thermal_shutdown_message" msgid="9006456746902370523">"Vaš telefon sada radi normalno"</string>
+    <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"Vaš telefon se pregrijao, pa se isključio da se ohladi. Telefon sada radi normalno.\n\nTelefon se može pregrijati ako:\n	• Koristite aplikacije koje troše puno resursa (kao što su aplikacije za igranje, videozapise ili navigaciju)\n	• Preuzimate ili otpremate velike fajlove\n	• Koristite telefon na visokim temperaturama"</string>
     <string name="high_temp_title" msgid="4589508026407318374">"Telefon se pregrijava"</string>
     <string name="high_temp_notif_message" msgid="5642466103153429279">"Neke funkcije su ograničene dok se telefon hladi"</string>
     <string name="high_temp_dialog_message" msgid="6840700639374113553">"Vaš telefon će se automatski pokušati ohladiti. I dalje možete koristi telefon, ali će možda raditi sporije.\n\nNakon što se ohladi, telefon će normalno raditi."</string>
@@ -701,12 +754,22 @@
     <string name="tuner_app" msgid="3507057938640108777">"Aplikacija <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozorenja"</string>
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Snimci ekrana"</string>
-    <string name="notification_channel_general" msgid="4525309436693914482">"Općenite poruke"</string>
+    <string name="notification_channel_general" msgid="4525309436693914482">"Opće poruke"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Pohrana"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant-aplikacije"</string>
-    <!-- no translation found for pip_menu_title (3328510504196964712) -->
-    <skip />
     <string name="instant_apps_message" msgid="8116608994995104836">"Za instant aplikacije nije potrebna instalacija"</string>
     <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Idite na internet"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobilni podaci"</string>
+    <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi veza je isključena"</string>
+    <string name="bt_is_off" msgid="2640685272289706392">"Bluetooth je isključen"</string>
+    <string name="dnd_is_off" msgid="6167780215212497572">"Opcija Ne ometaj je isključena"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"Opciju Ne ometaju uključilo je automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"Opciju Ne ometaj uključila je aplikacija <xliff:g id="ID_1">%s</xliff:g>."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"Opciju Ne ometaj uključilo je automatsko pravilo ili aplikacija."</string>
+    <string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="qs_dnd_keep" msgid="1825009164681928736">"Zadrži"</string>
+    <string name="qs_dnd_replace" msgid="8019520786644276623">"Zamijeni"</string>
+    <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacije koje rade u pozadini"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite za detalje o potrošnji baterije i prijenosa podataka"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings_car.xml b/packages/SystemUI/res/values-bs/strings_car.xml
index 744eea8..d38620b 100644
--- a/packages/SystemUI/res/values-bs/strings_car.xml
+++ b/packages/SystemUI/res/values-bs/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vozite sigurno"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Uvijek budite upoznati s uslovima za vožnju i poštujte važeće zakone. Upute za kretanje mogu biti netačne, nepotpune, opasne, neprikladne, zabranjene ili takve da obuhvataju prelaženje preko administrativnih područja. Poslovne informacije takođe mogu biti netačne ili nepotpune. Podaci nisu u realnom vremenu, a tačnost lokacije se ne može garantirati. U vožnji nemojte rukovati mobilnim uređajem ili koristiti aplikacije koje nisu namijenjene za Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Nepoznato"</string>
+    <string name="start_driving" msgid="864023351402918991">"Početak vožnje"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings_tv.xml b/packages/SystemUI/res/values-bs/strings_tv.xml
index 40347dc..b0b3612 100644
--- a/packages/SystemUI/res/values-bs/strings_tv.xml
+++ b/packages/SystemUI/res/values-bs/strings_tv.xml
@@ -19,15 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Slika u slici"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program bez naslova)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Zatvori PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Cijeli ekran"</string>
-    <string name="pip_play" msgid="674145557658227044">"Pokreni"</string>
-    <string name="pip_pause" msgid="8412075640017218862">"Pauziraj"</string>
-    <string name="pip_hold_home" msgid="340086535668778109">"Za kontr. PIP držite "<b>"HOME"</b></string>
-    <string name="pip_onboarding_title" msgid="7850436557670253991">"Slika u slici"</string>
-    <string name="pip_onboarding_description" msgid="4028124563309465267">"Ovim videozapis ostaje prikazan sve dok pokrenete sljedeći. Pritisnite i držite "<b>" POČETAK "</b>" za kontrole PIP-a."</string>
-    <string name="pip_onboarding_button" msgid="3957426748484904611">"Jasno mi je"</string>
-    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Odbaci"</string>
-  <string-array name="recents_tv_blacklist_array">
-  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 07a8cf4..dbf8938 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Més opcions"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Fet"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Connectat"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connectat (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria)"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"S\'està connectant..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Compartició de xarxa"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Punt d\'accés Wi-Fi"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Estàs connectat a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pot supervisar la teva activitat personal a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> gestiona el teu perfil professional. El perfil està connectat a <xliff:g id="APPLICATION">%2$s</xliff:g>, que pot supervisar la teva activitat a la xarxa de treball, com ara els correus electrònics, les aplicacions i els llocs web.\n\nPer obtenir més informació, contacta amb l\'administrador."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> gestiona el teu perfil professional. El perfil està connectat a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pot supervisar la teva activitat a la xarxa de treball, com ara els correus electrònics, les aplicacions i els llocs web.\n\nTambé estàs connectat a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pot supervisar la teva activitat personal a la xarxa."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Desbloquejat per a <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> s\'està executant"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"El dispositiu continuarà bloquejat fins que no el desbloquegis manualment."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Rep notificacions més ràpidament"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Mostra-les abans de desbloquejar"</string>
@@ -533,8 +536,8 @@
     <string name="activity_not_found" msgid="348423244327799974">"L\'aplicació no està instal·lada al dispositiu"</string>
     <string name="clock_seconds" msgid="7689554147579179507">"Mostra els segons del rellotge"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostra els segons del rellotge a la barra d\'estat. Això pot afectar la durada de la bateria."</string>
-    <string name="qs_rearrange" msgid="8060918697551068765">"Reorganitza Configuració ràpida"</string>
-    <string name="show_brightness" msgid="6613930842805942519">"Mostra la brillantor a Configuració ràpida"</string>
+    <string name="qs_rearrange" msgid="8060918697551068765">"Reorganitza la configuració ràpida"</string>
+    <string name="show_brightness" msgid="6613930842805942519">"Mostra la brillantor a configuració ràpida"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimental"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vols activar el Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Per connectar el teclat amb la tauleta, primer has d\'activar el Bluetooth."</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desactivat"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Amb els controls de notificació millorats, pots establir un nivell d\'importància d\'entre 0 i 5 per a les notificacions d\'una aplicació. \n\n"<b>"Nivell 5"</b>" \n- Mostra les notificacions a la part superior de la llista \n- Permet la interrupció de la pantalla completa \n- Permet sempre la previsualització \n\n"<b>"Nivell 4"</b>" \n- No permet la interrupció de la pantalla completa \n- Permet sempre la previsualització \n\n"<b>"Nivell 3"</b>" \n- No permet la interrupció de la pantalla completa \n- No permet mai la previsualització \n\n"<b>"Nivell 2"</b>" \n- No permet la interrupció de la pantalla completa \n- No permet mai la previsualització \n- Les notificacions no poden emetre sons ni vibracions \n\n"<b>"Nivell 1"</b>" \n- No permet la interrupció de la pantalla completa \n- No permet mai la previsualització \n- No activa mai el so ni la vibració \n- Amaga les notificacions de la pantalla de bloqueig i de la barra d\'estat \n- Mostra les notificacions a la part inferior de la llista \n\n"<b>"Nivell 0"</b>" \n- Bloqueja totes les notificacions de l\'aplicació"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificacions"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ja no rebràs aquestes notificacions."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ja no rebràs aquestes notificacions"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categories de notificació"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Aquesta aplicació no té categories de notificació"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Les notificacions d\'aquesta aplicació no es poden desactivar"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categories de notificació d\'aquesta aplicació</item>
       <item quantity="one">1 de <xliff:g id="NUMBER_0">%d</xliff:g> categoria de notificació d\'aquesta aplicació</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"controls de notificació"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opcions per posposar la notificació"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuts"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuts"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 hores"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"DESFÉS"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"S\'ha posposat <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d hores</item>
+      <item quantity="one">%d hora</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minuts</item>
+      <item quantity="one">%d minut</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Ús de la bateria"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"La funció Estalvi de bateria no està disponible durant la càrrega"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Estalvi de bateria"</string>
@@ -697,7 +705,7 @@
     <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"<xliff:g id="TILE_NAME">%1$s</xliff:g> s\'ha afegit a la posició <xliff:g id="POSITION">%2$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> s\'ha suprimit"</string>
     <string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> s\'ha mogut a la posició <xliff:g id="POSITION">%2$d</xliff:g>"</string>
-    <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor de la configuració ràpida."</string>
+    <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor de configuració ràpida."</string>
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"Notificació de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"És possible que l\'aplicació no funcioni amb la pantalla dividida."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"L\'aplicació no admet la pantalla dividida."</string>
@@ -718,8 +726,8 @@
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Minimitza"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Tanca"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Arrossega cap avall per ignorar-ho"</string>
-    <string name="pip_menu_title" msgid="3328510504196964712">"Menú per a Imatge en imatge"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> està en imatge en imatge"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Menú per a Pantalla en pantalla"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> està en pantalla en pantalla"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"Si no vols que <xliff:g id="NAME">%s</xliff:g> utilitzi aquesta funció, toca per obrir la configuració i desactiva-la."</string>
     <string name="pip_play" msgid="1417176722760265888">"Reprodueix"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Posa en pausa"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Substitueix"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplicacions que s\'estan executant en segon pla"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca per obtenir informació sobre l\'ús de dades i de bateria"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vols desactivar les dades mòbils?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings_car.xml b/packages/SystemUI/res/values-ca/strings_car.xml
index efcac23..32a019e 100644
--- a/packages/SystemUI/res/values-ca/strings_car.xml
+++ b/packages/SystemUI/res/values-ca/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Condueix amb precaució"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Estigues al cas de la conducció i respecta sempre les lleis aplicables. Les indicacions poden ser inexactes, perilloses, inadequades o incompletes, o bé poden comportar maniobres prohibides o que creuis circumscripcions territorials. La informació de les empreses també pot ser inexacta o incompleta. No s\'ofereixen dades en temps real i no es pot garantir la precisió de les ubicacions. Mentre condueixes, no utilitzis el dispositiu mòbil ni cap aplicació que no estigui destinada a Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Desconegut"</string>
+    <string name="start_driving" msgid="864023351402918991">"Comença a conduir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings_tv.xml b/packages/SystemUI/res/values-ca/strings_tv.xml
index 6e9fae5..a6c17f8 100644
--- a/packages/SystemUI/res/values-ca/strings_tv.xml
+++ b/packages/SystemUI/res/values-ca/strings_tv.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="notification_channel_tv_pip" msgid="134047986446577723">"Imatge en imatge"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Pantalla en pantalla"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Programa sense títol)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Tanca PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Pantalla completa"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 0b7e41a..924883f 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -22,7 +22,7 @@
     <string name="app_label" msgid="7164937344850004466">"UI systému"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Vymazat"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Odebrat ze seznamu"</string>
-    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informace o aplikaci"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"O aplikaci"</string>
     <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Zde budou zobrazeny vaše poslední obrazovky"</string>
     <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Zavřít nové aplikace"</string>
     <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
@@ -316,6 +316,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Další nastavení"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Hotovo"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Připojeno"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Připojeno, baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Připojování..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Sdílené připojení"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -473,6 +474,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Jste připojeni k aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g>, která může sledovat vaši osobní aktivitu v síti, včetně e-mailů, aplikací a webů."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Váš pracovní profil spravuje organizace <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Je připojen k aplikaci <xliff:g id="APPLICATION">%2$s</xliff:g>, která může sledovat vaši aktivitu v síti, včetně e-mailů, aplikací a webů.\n\nDalší informace vám poskytne administrátor."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Váš pracovní profil spravuje organizace <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Je připojen k aplikaci <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, která může sledovat vaši aktivitu v síti, včetně e-mailů, aplikací a webů.\n\nTaké jste připojeni k aplikaci <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, která může sledovat vaši osobní aktivitu v síti."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Odemknuto pro uživatele <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> běží"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Zařízení zůstane uzamčeno, dokud je ručně neodemknete"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Čtěte si oznámení rychleji"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Můžete si je přečíst před odemčením obrazovky."</string>
@@ -554,9 +557,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Vypnuto"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Rozšířené ovládací prvky oznámení umožňují nastavit úroveň důležitosti oznámení aplikace od 0 do 5. \n\n"<b>"Úroveň 5"</b>" \n– Zobrazit na začátku seznamu oznámení \n– Povolit vyrušení na celou obrazovku \n– Vždy zobrazit náhled \n\n"<b>"Úroveň 4"</b>" \n– Zabránit vyrušení na celou obrazovku \n– Vždy zobrazit náhled \n\n"<b>"Úroveň 3"</b>" \n– Zabránit vyrušení na celou obrazovku \n– Nikdy nezobrazovat náhled \n\n"<b>"Úroveň 2"</b>" \n– Zabránit vyrušení na celou obrazovku \n– Nikdy nezobrazovat náhled \n– Nikdy nevydávat žádný zvukový signál ani nevibrovat \n\n"<b>"Úroveň 1"</b>" \n– Zabránit vyrušení na celou obrazovku \n– Nikdy nezobrazovat náhled \n– Nikdy nevydávat zvukový signál ani nevibrovat \n– Skrýt z obrazovky uzamčení a stavového řádku \n– Zobrazovat na konci seznamu oznámení \n\n"<b>";Úroveň 0"</b>" \n– Blokovat všechna oznámení z aplikace"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Oznámení"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Tato oznámení již nebudete dostávat."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Tato oznámení již nebudete dostávat"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Kategorie oznámení: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Tato aplikace nemá kategorie oznámení"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Oznámení této aplikace nelze vypnout"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="few">1 ze <xliff:g id="NUMBER_1">%d</xliff:g> kategorií oznámení z této aplikace</item>
       <item quantity="many">1 z <xliff:g id="NUMBER_1">%d</xliff:g> kategorie oznámení z této aplikace</item>
@@ -580,12 +584,20 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"Nastavení oznámení"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"Možnosti odložení oznámení"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minut"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minut"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hodina"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 hodiny"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"VRÁTIT ZPĚT"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odloženo o <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="few">%d hodiny</item>
+      <item quantity="many">%d hodiny</item>
+      <item quantity="other">%d hodin</item>
+      <item quantity="one">%d hodina</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="few">%d minuty</item>
+      <item quantity="many">%d minuty</item>
+      <item quantity="other">%d minut</item>
+      <item quantity="one">%d minuta</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Využití baterie"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Spořič baterie při nabíjení není k dispozici."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Spořič baterie"</string>
@@ -746,7 +758,7 @@
     <string name="lockscreen_unlock_left" msgid="2043092136246951985">"Zkratka vlevo také odemyká"</string>
     <string name="lockscreen_unlock_right" msgid="1529992940510318775">"Zkratka vpravo také odemyká"</string>
     <string name="lockscreen_none" msgid="4783896034844841821">"Žádné"</string>
-    <string name="tuner_launch_app" msgid="1527264114781925348">"Spustit aplikaci <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="tuner_launch_app" msgid="1527264114781925348">"Do aplikace <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="tuner_other_apps" msgid="4726596850501162493">"Další aplikace"</string>
     <string name="tuner_circle" msgid="2340998864056901350">"Kruh"</string>
     <string name="tuner_plus" msgid="6792960658533229675">"Plus"</string>
@@ -761,7 +773,7 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Úložiště"</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="app_info" msgid="6856026610594615344">"Informace o aplikaci"</string>
+    <string name="app_info" msgid="6856026610594615344">"O aplikaci"</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="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je vypnuta"</string>
@@ -775,4 +787,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Nahradit"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikace běžící na pozadí"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Klepnutím zobrazíte podrobnosti o využití baterie a dat"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vypnout mobilní data?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings_car.xml b/packages/SystemUI/res/values-cs/strings_car.xml
index d5e3324..b8a0d3e 100644
--- a/packages/SystemUI/res/values-cs/strings_car.xml
+++ b/packages/SystemUI/res/values-cs/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Řiďte bezpečně"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Věnujte plnou pozornost řízení a dodržujte platné předpisy. Trasy mohou být nepřesné, neúplné, nebezpečné, nevhodné, zakázané nebo mohou zahrnovat překročení hranic. Informace o firmách mohou být také nepřesné nebo neúplné. Data se neaktualizují v reálném čase a přesnost polohy nelze zaručit. Mobilní zařízení ani aplikace určené pro Android Auto nepoužívejte za jízdy."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Neznámé"</string>
+    <string name="start_driving" msgid="864023351402918991">"Zahájit jízdu"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 37f92f7..b847e6f 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -22,7 +22,7 @@
     <string name="app_label" msgid="7164937344850004466">"System-UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ryd"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Fjern fra listen"</string>
-    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Oplysninger om appen"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Appinfo"</string>
     <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Dine seneste skærme vises her"</string>
     <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Luk de seneste apps"</string>
     <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
@@ -255,7 +255,7 @@
       <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> underretning mere i gruppen.</item>
       <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> underretninger mere i gruppen.</item>
     </plurals>
-    <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Underretningsindstillinger"</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Indstillinger for underretninger"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Indstillinger for <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skærmen roterer automatisk."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skærmen er nu låst i liggende retning."</string>
@@ -279,7 +279,7 @@
     <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"Roter skærmen automatisk"</string>
     <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"Tilstanden <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Rotationen er låst"</string>
-    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Stående format"</string>
+    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Stående"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Liggende"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Inputmetode"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Placering"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Flere indstillinger"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Udfør"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Tilsluttet"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Tilsluttet – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Opretter forbindelse…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Netdeling"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Du har forbindelse til <xliff:g id="APPLICATION">%1$s</xliff:g>, som kan overvåge din private netværksaktivitet, bl.a. e-mails, apps og websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Din arbejdsprofil administreres af <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilen har forbindelse til <xliff:g id="APPLICATION">%2$s</xliff:g>, som kan overvåge din netværksaktivitet, bl.a. mails, apps og websites.\n\nKontakt din administrator for at få flere oplysninger."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Din arbejdsprofil administreres af <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilen har forbindelse til <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, som kan overvåge din netværksaktivitet, bl.a. mails, apps og websites.\n\nDu har også forbindelse til <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, som kan overvåge din personlige netværksaktivitet."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Låst op for <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> kører"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Enheden vil forblive låst, indtil du manuelt låser den op"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Modtag underretninger hurtigere"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Se dem, før du låser op"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Fra"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Med kontrolelementer til underretninger om strøm kan du konfigurere et vigtighedsniveau fra 0 til 5 for en apps underretninger. \n\n"<b>"Niveau 5"</b>\n"- Vis øverst på listen over underretninger \n- Tillad afbrydelse af fuld skærm \n- Se altid smugkig \n\n"<b>"Niveau 4"</b>\n"- Ingen afbrydelse af fuld skærm \n- Se altid smugkig \n\n"<b>"Niveau 3"</b>\n"- Ingen afbrydelse af fuld skærm \n- Se aldrig smugkig \n\n"<b>"Niveau 2"</b>\n"- Ingen afbrydelse af fuld skærm \n Se aldrig smugkig \n- Ingen lyd og vibration \n\n"<b>"Niveau 1"</b>\n"- Ingen afbrydelse af fuld skærm \n- Se aldrig smugkig \n- Ingen lyd eller vibration \n- Skjul fra låseskærm og statusbjælke \n- Vis nederst på listen over underretninger \n\n"<b>"Niveau 0"</b>\n"- Bloker alle underretninger fra appen."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Underretninger"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Du modtager ikke længere disse underretninger."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Du modtager ikke længere disse underretninger"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> underretningskategorier"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Denne app har ingen underretningskategorier"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Underretninger fra denne app kan ikke deaktiveres"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 ud af <xliff:g id="NUMBER_1">%d</xliff:g> underretningskategori fra denne app</item>
       <item quantity="other">1 ud af <xliff:g id="NUMBER_1">%d</xliff:g> underretningskategorier fra denne app</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kontrolelementer til underretninger"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"Indstillinger for udsættelse"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutter"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutter"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 time"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 timer"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"FORTRYD"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Udsat i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d time</item>
+      <item quantity="other">%d timer</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d minut</item>
+      <item quantity="other">%d minutter</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Batteriforbrug"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparefunktionen er ikke tilgængelig under opladning"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparefunktion"</string>
@@ -751,7 +759,7 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Lagerplads"</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="app_info" msgid="6856026610594615344">"Oplysninger om appen"</string>
+    <string name="app_info" msgid="6856026610594615344">"Appinfo"</string>
     <string name="go_to_web" msgid="1106022723459948514">"Gå til website"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobildata"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi er slået fra"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Erstat"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Apps, der kører i baggrunden"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tryk for at se oplysninger om batteri- og dataforbrug"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vil du deaktivere mobildata?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings_car.xml b/packages/SystemUI/res/values-da/strings_car.xml
index 6a421da..26843ac 100644
--- a/packages/SystemUI/res/values-da/strings_car.xml
+++ b/packages/SystemUI/res/values-da/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Kør forsigtigt"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Vær opmærksom på køreforholdene, og overhold altid færdselsloven. Rutevejledningen kan være unøjagtig, ufuldstændig, farlig, upassende, forbudt eller involvere krydsning af forbudte områder. Virksomhedsoplysninger kan også være unøjagtige eller ufuldstændige. Data er ikke i realtid, og placeringers nøjagtighed kan ikke garanteres. Håndter ikke din mobilenhed, og brug ikke apps, der ikke er beregnet til Android Auto, mens du kører."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Ukendt"</string>
+    <string name="start_driving" msgid="864023351402918991">"Kør"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index fe06c12..b0afce8 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -314,6 +314,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Weitere Einstellungen"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Fertig"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Verbunden"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Verbunden, Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Verbindung wird hergestellt…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -471,6 +472,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Du bist mit der App \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" verbunden. Diese kann deine persönlichen Netzwerkaktivitäten erfassen, einschließlich E-Mails, Apps und Websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Dein Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet. Das Profil ist mit <xliff:g id="APPLICATION">%2$s</xliff:g> verknüpft. Diese App kann deine Netzwerkaktivitäten überwachen, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhältst du von deinem Administrator."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Dein Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet. Das Profil ist mit <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> verknüpft. Diese App kann deine Netzwerkaktivitäten überwachen, einschließlich E-Mails, Apps und Websites.\n\nDu bist auch mit <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> verbunden, die deine persönlichen Netzwerkaktivitäten überwachen kann."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Entsperrt für <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> wird ausgeführt"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Das Gerät bleibt gesperrt, bis du es manuell entsperrst."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Benachrichtigungen schneller erhalten"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Vor dem Entsperren anzeigen"</string>
@@ -552,9 +555,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Aus"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Mit den erweiterten Benachrichtigungseinstellungen kannst du für App-Benachrichtigungen eine Wichtigkeitsstufe von 0 bis 5 festlegen. \n\n"<b>"Stufe 5"</b>" \n- Auf der Benachrichtigungsleiste ganz oben anzeigen \n- Vollbildunterbrechung zulassen \n- Immer kurz einblenden \n\n"<b>"Stufe 4"</b>" \n- Keine Vollbildunterbrechung \n- Immer kurz einblenden \n\n"<b>"Stufe 3"</b>" \n- Keine Vollbildunterbrechung \n- Nie kurz einblenden \n\n"<b>"Stufe 2"</b>" \n- Keine Vollbildunterbrechung \n- Nie kurz einblenden \n- Weder Ton noch Vibration \n\n"<b>"Stufe 1"</b>" \n- Keine Vollbildunterbrechung \n- Nie kurz einblenden \n- Weder Ton noch Vibration \n- Auf Sperrbildschirm und Statusleiste verbergen \n- Auf der Benachrichtigungsleiste ganz unten anzeigen \n\n"<b>"Stufe 0"</b>" \n- Alle Benachrichtigungen der App sperren"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Benachrichtigungen"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Du erhältst diese Benachrichtigungen nicht mehr."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Du erhältst diese Benachrichtigungen nicht mehr"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> Benachrichtigungskategorien"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Diese App hat keine Benachrichtigungskategorien"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Benachrichtigungen von dieser App können nicht deaktiviert werden"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 von <xliff:g id="NUMBER_1">%d</xliff:g> Benachrichtigungskategorien von dieser App</item>
       <item quantity="one">1 von <xliff:g id="NUMBER_0">%d</xliff:g> Benachrichtigungskategorie von dieser App</item>
@@ -574,12 +578,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> – <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"Benachrichtigungseinstellungen"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"Optionen für spätere Erinnerung bei Benachrichtigungen"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 Minuten"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 Minuten"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 Stunde"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 Stunden"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"RÜCKGÄNGIG"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Erinnerung in <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d Stunden</item>
+      <item quantity="one">%d Stunde</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d Minuten</item>
+      <item quantity="one">%d Minute</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Akkunutzung"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Der Energiesparmodus ist beim Aufladen nicht verfügbar."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Energiesparmodus"</string>
@@ -769,4 +777,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Ersetzen"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Apps, die im Hintergrund ausgeführt werden"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Für Details zur Akku- und Datennutzung tippen"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Mobile Daten deaktivieren?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings_car.xml b/packages/SystemUI/res/values-de/strings_car.xml
index 5b5920e..76ff268 100644
--- a/packages/SystemUI/res/values-de/strings_car.xml
+++ b/packages/SystemUI/res/values-de/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Sicher fahren"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Achte stets auf die Straßenverhältnisse und halte dich an die geltenden Gesetze. Routen können unter Umständen fehlerhaft, unvollständig, gefährlich, ungeeignet oder verboten sein oder das Überqueren von Verwaltungsgrenzen erfordern. Informationen zum Unternehmen können ebenfalls fehlerhaft oder unvollständig sein. Die Datenübertragung erfolgt nicht in Echtzeit und die Genauigkeit der Standortangaben kann nicht gewährleistet werden. Bediene während der Fahrt nicht dein Mobilgerät und verwende keine Apps, die du nicht über Android Auto steuern kannst."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Unbekannt"</string>
+    <string name="start_driving" msgid="864023351402918991">"Losfahren"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index aa7fb92..0b7e7ea 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -51,8 +51,8 @@
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Έγινε σύνδεση μέσω Bluetooth"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Ρύθμιση μεθόδων εισαγωγής"</string>
     <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Φυσικό πληκτρολόγιο"</string>
-    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Να επιτρέπεται στο <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στη συσκευή USB;"</string>
-    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Να επιτρέπεται στο <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στο αξεσουάρ USB;"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στη συσκευή USB;"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στο αξεσουάρ USB;"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Άνοιγμα του <xliff:g id="ACTIVITY">%1$s</xliff:g> κατά τη σύνδεση αυτής της συσκευής USB;"</string>
     <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Άνοιγμα του <xliff:g id="ACTIVITY">%1$s</xliff:g> κατά τη σύνδεση αυτού του αξεσουάρ USB;"</string>
     <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Δεν έχετε εφαρμογή που να συνεργάζεται με το αξεσουάρ USB. Για περισσότερα: <xliff:g id="URL">%1$s</xliff:g>"</string>
@@ -184,7 +184,7 @@
     <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Η ειδοποίηση έχει απορριφθεί."</string>
     <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Πλαίσιο σκίασης ειδοποιήσεων."</string>
     <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Γρήγορες ρυθμίσεις."</string>
-    <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Κλείδωμα οθόνης."</string>
+    <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Οθόνη κλειδώματος"</string>
     <string name="accessibility_desc_settings" msgid="3417884241751434521">"Ρυθμίσεις"</string>
     <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Επισκόπηση."</string>
     <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"Οθόνη κλειδωμένης εργασίας"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Περισσότερες ρυθμίσεις"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Τέλος"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Συνδέθηκε"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Συνδεδεμένη, μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Σύνδεση…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Πρόσδεση"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Σημείο πρόσβασης Wi-Fi"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του προσωπικού σας δικτύου, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Ο οργανισμός <xliff:g id="ORGANIZATION">%1$s</xliff:g> διαχειρίζεται το προφίλ εργασίας σας. Το προφίλ είναι συνδεδεμένο στην εφαρμογή <xliff:g id="APPLICATION">%2$s</xliff:g>, η οποία μπορεί να παρακολουθήσει τη δραστηριότητα του δικτύου εργασίας σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή σας."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Ο οργανισμός <xliff:g id="ORGANIZATION">%1$s</xliff:g> διαχειρίζεται το προφίλ εργασίας σας. Το προφίλ συνδέεται με την εφαρμογή <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου της εργασίας σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΕπίσης, είστε συνδεδεμένοι στην εφαρμογή <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, που έχει τη δυνατότητα παρακολούθησης της δραστηριότητας του προσωπικού σας δικτύου."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Ξεκλειδώθηκε για τον χρήστη <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Εκτελείται ο παράγοντας εμπιστοσύνης <xliff:g id="TRUST_AGENT">%1$s</xliff:g>"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Η συσκευή θα παραμείνει κλειδωμένη μέχρι να την ξεκλειδώσετε μη αυτόματα"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Λάβετε ειδοποιήσεις γρηγορότερα"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Εμφάνιση πριν το ξεκλείδωμα"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Ανενεργή"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Με τα στοιχεία ελέγχου ειδοποίησης ισχύος, μπορείτε να ορίσετε ένα επίπεδο βαρύτητας από 0 έως 5 για τις ειδοποιήσεις μιας εφαρμογής. \n\n"<b>"Επίπεδο 5"</b>" \n- Εμφάνιση στην κορυφή της λίστας ειδοποιήσεων \n- Να επιτρέπεται η διακοπή πλήρους οθόνης \n- Να γίνεται πάντα σύντομη προβολή \n\n"<b>"Επίπεδο 4"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να γίνεται πάντα σύντομη προβολή \n\n"<b>"Επίπεδο 3"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να μην γίνεται ποτέ σύντομη προβολή \n\n"<b>"Επίπεδο 2"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να μην γίνεται ποτέ σύντομη προβολή \n- Να μην χρησιμοποιείται ποτέ ήχος και δόνηση \n\n"<b>"Επίπεδο 1"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να μην γίνεται ποτέ σύντομη προβολή \n- Να μην χρησιμοποιείται ποτέ ήχος και δόνηση \n- Απόκρυψη από την οθόνη κλειδώματος και τη γραμμή κατάστασης \n- Εμφάνιση στο κάτω μέρος της λίστας ειδοποιήσεων \n\n"<b>"Επίπεδο 0"</b>" \n- Αποκλεισμός όλων των ειδοποιήσεων από την εφαρμογή"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Ειδοποιήσεις"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Δεν θα λαμβάνεται πλέον αυτές τις ειδοποιήσεις."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Δεν θα λαμβάνετε πλέον αυτές τις ειδοποιήσεις"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> κατηγορίες ειδοποιήσεων"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Αυτή η εφαρμογή δεν διαθέτει κατηγορίες ειδοποιήσεων"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Οι ειδοποιήσεις από αυτήν την εφαρμογή δεν μπορούν να απενεργοποιηθούν"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 από <xliff:g id="NUMBER_1">%d</xliff:g> κατηγορίες ειδοποιήσεων από αυτή την εφαρμογή</item>
       <item quantity="one">1 από <xliff:g id="NUMBER_0">%d</xliff:g> κατηγορία ειδοποιήσεων από αυτή την εφαρμογή</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"στοιχεία ελέγχου ειδοποιήσεων"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"επιλογές αφύπνισης ειδοποιήσεων"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 λεπτά"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 λεπτά"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ώρα"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ώρες"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ΑΝΑΙΡΕΣΗ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Σε αφύπνιση για <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d ώρες</item>
+      <item quantity="one">%d ώρα</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d λεπτά</item>
+      <item quantity="one">%d λεπτό</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Χρήση της μπαταρίας"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Η εξοικονόμηση μπαταρίας δεν είναι διαθέσιμη κατά τη διάρκεια της φόρτισης"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Εξοικονόμηση μπαταρίας"</string>
@@ -713,7 +721,7 @@
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Άνοιγμα ρυθμίσεων <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Επεξεργασία σειράς ρυθμίσεων."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Σελίδα <xliff:g id="ID_1">%1$d</xliff:g> από <xliff:g id="ID_2">%2$d</xliff:g>"</string>
-    <string name="tuner_lock_screen" msgid="5755818559638850294">"Κλείδωμα οθόνης"</string>
+    <string name="tuner_lock_screen" msgid="5755818559638850294">"Οθόνη κλειδώματος"</string>
     <string name="pip_phone_expand" msgid="5889780005575693909">"Ανάπτυξη"</string>
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Ελαχιστοποίηση"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Κλείσιμο"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Αντικατάσταση"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Εφαρμογές που εκτελούνται στο παρασκήνιο"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Πατήστε για λεπτομέρειες σχετικά με τη χρήση μπαταρίας και δεδομένων"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Απενεργοποίηση δεδομένων κινητής τηλεφωνίας;"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings_car.xml b/packages/SystemUI/res/values-el/strings_car.xml
index e960713..09a2a39 100644
--- a/packages/SystemUI/res/values-el/strings_car.xml
+++ b/packages/SystemUI/res/values-el/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Οδηγείτε προσεκτικά"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Μείνετε πλήρως ενημερωμένοι για τις προϋποθέσεις οδήγησης και υπακούτε πάντα τους ισχύοντες νόμους. Οι οδηγίες μπορεί να είναι ανακριβείς, ελλιπείς, επικίνδυνες, ακατάλληλες, απαγορευμένες ή να ανήκουν σε άλλες διοικητικές περιοχές. Οι πληροφορίες επιχειρήσεων μπορεί επίσης να είναι ανακριβείς ή ελλιπείς. Τα δεδομένα δεν είναι σε πραγματικό χρόνο και η ακρίβεια των τοποθεσιών δεν είναι εγγυημένη. Μη χειρίζεστε την κινητή συσκευή σας και μη χρησιμοποιείτε εφαρμογές που δεν προορίζονται για το Android Auto ενώ οδηγείτε."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Άγνωστο"</string>
+    <string name="start_driving" msgid="864023351402918991">"Έναρξη οδήγησης"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 35263c2..4d90d5b3 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"More settings"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Done"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Connected"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Connecting..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your personal network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>. The profile is connected to <xliff:g id="APPLICATION">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps and websites.\n\nFor more information, contact your admin."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>. The profile is connected to <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps and websites.\n\nYou\'re also connected to <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, which can monitor your personal network activity."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Unlocked for <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> is running"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Device will stay locked until you manually unlock"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Get notifications faster"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"See them before you unlock"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"With power notification controls, you can set an importance level from 0 to 5 for an app\'s notifications. \n\n"<b>"Level 5"</b>" \n- Show at the top of the notification list \n- Allow full screen interruption \n- Always peek \n\n"<b>"Level 4"</b>" \n- Prevent full screen interruption \n- Always peek \n\n"<b>"Level 3"</b>" \n- Prevent full screen interruption \n- Never peek \n\n"<b>"Level 2"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound and vibration \n\n"<b>"Level 1"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound or vibrate \n- Hide from lock screen and status bar \n- Show at the bottom of the notification list \n\n"<b>"Level 0"</b>" \n- Block all notifications from the app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"You won\'t get these notifications anymore."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"You won\'t get these notifications anymore"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> notification categories"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"This app doesn\'t have notification categories"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Notifications from this app can\'t be turned off"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 out of <xliff:g id="NUMBER_1">%d</xliff:g> notification categories from this app</item>
       <item quantity="one">1 out of <xliff:g id="NUMBER_0">%d</xliff:g> notification category from this app</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"notification controls"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"notification snooze options"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hour"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 hours"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"UNDO"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d hours</item>
+      <item quantity="one">%d hour</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minutes</item>
+      <item quantity="one">%d minute</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Replace"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Apps running in background"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap for details on battery and data usage"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Turn off mobile data?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings_car.xml b/packages/SystemUI/res/values-en-rAU/strings_car.xml
index 81089ba..27b916e 100644
--- a/packages/SystemUI/res/values-en-rAU/strings_car.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Drive safely"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Stay fully aware of driving conditions and always obey applicable laws. Directions may be inaccurate, incomplete, dangerous, not suitable, prohibited or involve crossing administrative areas. Business information may also be inaccurate or incomplete. Data is not real time and location accuracy cannot be guaranteed. Do not handle your mobile device or use apps not intended for Android Auto while driving."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Unknown"</string>
+    <string name="start_driving" msgid="864023351402918991">"Start Driving"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 35263c2..4d90d5b3 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"More settings"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Done"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Connected"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Connecting..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your personal network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>. The profile is connected to <xliff:g id="APPLICATION">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps and websites.\n\nFor more information, contact your admin."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>. The profile is connected to <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps and websites.\n\nYou\'re also connected to <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, which can monitor your personal network activity."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Unlocked for <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> is running"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Device will stay locked until you manually unlock"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Get notifications faster"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"See them before you unlock"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"With power notification controls, you can set an importance level from 0 to 5 for an app\'s notifications. \n\n"<b>"Level 5"</b>" \n- Show at the top of the notification list \n- Allow full screen interruption \n- Always peek \n\n"<b>"Level 4"</b>" \n- Prevent full screen interruption \n- Always peek \n\n"<b>"Level 3"</b>" \n- Prevent full screen interruption \n- Never peek \n\n"<b>"Level 2"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound and vibration \n\n"<b>"Level 1"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound or vibrate \n- Hide from lock screen and status bar \n- Show at the bottom of the notification list \n\n"<b>"Level 0"</b>" \n- Block all notifications from the app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"You won\'t get these notifications anymore."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"You won\'t get these notifications anymore"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> notification categories"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"This app doesn\'t have notification categories"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Notifications from this app can\'t be turned off"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 out of <xliff:g id="NUMBER_1">%d</xliff:g> notification categories from this app</item>
       <item quantity="one">1 out of <xliff:g id="NUMBER_0">%d</xliff:g> notification category from this app</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"notification controls"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"notification snooze options"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hour"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 hours"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"UNDO"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d hours</item>
+      <item quantity="one">%d hour</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minutes</item>
+      <item quantity="one">%d minute</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Replace"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Apps running in background"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap for details on battery and data usage"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Turn off mobile data?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings_car.xml b/packages/SystemUI/res/values-en-rGB/strings_car.xml
index 81089ba..27b916e 100644
--- a/packages/SystemUI/res/values-en-rGB/strings_car.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Drive safely"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Stay fully aware of driving conditions and always obey applicable laws. Directions may be inaccurate, incomplete, dangerous, not suitable, prohibited or involve crossing administrative areas. Business information may also be inaccurate or incomplete. Data is not real time and location accuracy cannot be guaranteed. Do not handle your mobile device or use apps not intended for Android Auto while driving."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Unknown"</string>
+    <string name="start_driving" msgid="864023351402918991">"Start Driving"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 35263c2..4d90d5b3 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"More settings"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Done"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Connected"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Connecting..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your personal network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>. The profile is connected to <xliff:g id="APPLICATION">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps and websites.\n\nFor more information, contact your admin."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>. The profile is connected to <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps and websites.\n\nYou\'re also connected to <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, which can monitor your personal network activity."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Unlocked for <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> is running"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Device will stay locked until you manually unlock"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Get notifications faster"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"See them before you unlock"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"With power notification controls, you can set an importance level from 0 to 5 for an app\'s notifications. \n\n"<b>"Level 5"</b>" \n- Show at the top of the notification list \n- Allow full screen interruption \n- Always peek \n\n"<b>"Level 4"</b>" \n- Prevent full screen interruption \n- Always peek \n\n"<b>"Level 3"</b>" \n- Prevent full screen interruption \n- Never peek \n\n"<b>"Level 2"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound and vibration \n\n"<b>"Level 1"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound or vibrate \n- Hide from lock screen and status bar \n- Show at the bottom of the notification list \n\n"<b>"Level 0"</b>" \n- Block all notifications from the app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"You won\'t get these notifications anymore."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"You won\'t get these notifications anymore"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> notification categories"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"This app doesn\'t have notification categories"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Notifications from this app can\'t be turned off"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 out of <xliff:g id="NUMBER_1">%d</xliff:g> notification categories from this app</item>
       <item quantity="one">1 out of <xliff:g id="NUMBER_0">%d</xliff:g> notification category from this app</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"notification controls"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"notification snooze options"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hour"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 hours"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"UNDO"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d hours</item>
+      <item quantity="one">%d hour</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minutes</item>
+      <item quantity="one">%d minute</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Replace"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Apps running in background"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap for details on battery and data usage"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Turn off mobile data?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings_car.xml b/packages/SystemUI/res/values-en-rIN/strings_car.xml
index 81089ba..27b916e 100644
--- a/packages/SystemUI/res/values-en-rIN/strings_car.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Drive safely"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Stay fully aware of driving conditions and always obey applicable laws. Directions may be inaccurate, incomplete, dangerous, not suitable, prohibited or involve crossing administrative areas. Business information may also be inaccurate or incomplete. Data is not real time and location accuracy cannot be guaranteed. Do not handle your mobile device or use apps not intended for Android Auto while driving."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Unknown"</string>
+    <string name="start_driving" msgid="864023351402918991">"Start Driving"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 3b776580..d6c97b7 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Más configuraciones"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Listo"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Conectado"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Conectado. Batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Conectando…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Anclaje a red"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona"</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Te conectaste a <xliff:g id="APPLICATION">%1$s</xliff:g>, que puede supervisar la actividad de tu red personal, incluidos los correos electrónicos, las apps y los sitios web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> administra tu perfil de trabajo. El perfil está conectado a <xliff:g id="APPLICATION">%2$s</xliff:g>, que puede controlar tu actividad de red de trabajo, incluidos los correos electrónicos, apps y sitios web.\n\nPara obtener más información, comunícate con tu administrador."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> administra tu perfil de red. El perfil está conectado a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que puede controlar tu actividad de red de trabajo, incluidos los correos electrónicos, las apps y los sitios web.\n\nTambién estás conectado a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que puede controlar tu actividad de red personal."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Se desbloqueó para <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Se está ejecutando <xliff:g id="TRUST_AGENT">%1$s</xliff:g>"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"El dispositivo permanecerá bloqueado hasta que lo desbloquees manualmente."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Recibe notificaciones más rápido"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Ver antes de desbloquear"</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desactivado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Con los controles de activación de notificaciones, puedes establecer un nivel de importancia para las notificaciones de una app. \n\n"<b>"Nivel 5"</b>" \n- Mostrar en la parte superior de la lista de notificaciones. \n- Permitir interrupción en la pantalla completa. \n- Mostrar siempre. \n\n"<b>"Nivel 4"</b>" \n- No permitir interrupción en la pantalla completa. \n- Mostrar siempre. \n\n"<b>"Nivel 3"</b>" \n- No permitir interrupción en la pantalla completa. \n- No mostrar. \n\n"<b>"Nivel 2"</b>" \n- No permitir interrupción en la pantalla completa. \n- No mostrar. \n- No sonar ni vibrar. \n\n"<b>"Nivel 1"</b>" \n- No permitir interrupción en la pantalla completa. \n- No mostrar. \n- No sonar ni vibrar. \n- Ocultar de la pantalla bloqueada y la barra de estado. \n- Mostrar al final de la lista de notificaciones. \n\n"<b>"Nivel 0"</b>" \n- Bloquear todas las notificaciones de la app."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificaciones"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ya no recibirás estas notificaciones."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ya no recibirás estas notificaciones"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorías de notificaciones"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Esta app no tiene categorías de notificación"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"No es posible desactivar las notificaciones de esta app"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categorías de notificación de esta app</item>
       <item quantity="one">1 de <xliff:g id="NUMBER_0">%d</xliff:g> categoría de notificación de esta app</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"controles de notificación"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opciones para posponer notificaciones"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 horas"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"DESHACER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Posponer <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d horas</item>
+      <item quantity="one">%d hora</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minutos</item>
+      <item quantity="one">%d minuto</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso de la batería"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ahorro de batería no está disponible durante la carga"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ahorro de batería"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Reemplazar"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Apps que se ejecutan en segundo plano"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Presiona para obtener información sobre el uso de datos y de la batería"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"¿Deseas desactivar los datos móviles?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings_car.xml b/packages/SystemUI/res/values-es-rUS/strings_car.xml
index 647236a..382602a 100644
--- a/packages/SystemUI/res/values-es-rUS/strings_car.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conducir de forma segura"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Permanece atento a la situación de conducción y cumple siempre con las leyes vigentes. Es posible que las indicaciones sean imprecisas, inadecuadas o peligrosas, que estén incompletas, que sugieran maniobras prohibidas o que impliquen atravesar áreas administrativas. La información de las empresas también puede ser imprecisa o estar incompleta. Los datos no se proporcionan en tiempo real ni se puede garantizar la precisión de las ubicaciones. No uses tu dispositivo móvil ni apps no diseñadas para Android Auto mientras conduces."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Desconocido"</string>
+    <string name="start_driving" msgid="864023351402918991">"Comenzar a conducir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index d005cd8..8c65c4a 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -34,14 +34,14 @@
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificaciones"</string>
     <string name="battery_low_title" msgid="6456385927409742437">"Nivel de batería bajo"</string>
     <string name="battery_low_percent_format" msgid="2900940511201380775">"Queda un <xliff:g id="PERCENTAGE">%s</xliff:g> de batería"</string>
-    <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"Queda un <xliff:g id="PERCENTAGE">%s</xliff:g> de batería. La función de ahorro de energía está activada."</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"Queda un <xliff:g id="PERCENTAGE">%s</xliff:g> de batería. La función de ahorro de batería está activada."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"No se admite la carga por USB.\nUtiliza solo el cargador proporcionado."</string>
     <string name="invalid_charger_title" msgid="3515740382572798460">"No se admite la carga por USB."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Utiliza solo el cargador proporcionado."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Ajustes"</string>
     <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"¿Activar ahorro de batería?"</string>
     <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"Activar"</string>
-    <string name="battery_saver_start_action" msgid="5576697451677486320">"Activar ahorro de energía"</string>
+    <string name="battery_saver_start_action" msgid="5576697451677486320">"Activar ahorro de batería"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Ajustes"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Girar pantalla automáticamente"</string>
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Más opciones"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Listo"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Conectado"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Conectado (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Conectando..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Compartir conexión"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona Wi-Fi"</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Estas conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que puede controlar tu actividad de red personal, como correos electrónicos, aplicaciones y sitios web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> gestiona tu perfil de trabajo. El perfil está conectado a <xliff:g id="APPLICATION">%2$s</xliff:g>, que puede supervisar tu actividad de red profesional, como los correos electrónicos, las aplicaciones y los sitios web.\n\nPara obtener más información, ponte en contacto con el administrador."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> gestiona tu perfil de trabajo. El perfil está conectado a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que puede supervisar tu actividad de red profesional, como los correos electrónicos, las aplicaciones y los sitios web.\n\nTambién te has conectado a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que puede supervisar tu actividad de red personal."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Desbloqueado para <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> se está ejecutando"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"El dispositivo permanecerá bloqueado hasta que se desbloquee manualmente"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Recibe notificaciones más rápido"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Ver antes de desbloquear"</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desactivado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Los controles de energía de las notificaciones permiten establecer un nivel de importancia de 0 a 5 para las notificaciones de las aplicaciones. \n\n"<b>"Nivel 5"</b>" \n- Mostrar en la parte superior de la lista de notificaciones \n- Permitir interrumpir en el modo de pantalla completa \n- Mostrar siempre \n\n"<b>"Nivel 4"</b>" \n- Evitar interrumpir en el modo de pantalla completa \n- Mostrar siempre \n\n"<b>"Nivel 3"</b>" \n- Evitar interrumpir en el modo de pantalla completa \n- No mostrar nunca \n\n"<b>"Nivel 2"</b>" \n- Evitar interrumpir en el modo de pantalla completa\n- No mostrar nunca \n- No emitir sonido ni vibrar nunca \n\n"<b>"Nivel 1"</b>" \n- Evitar interrumpir en el modo de pantalla completa \n- No mostrar nunca \n- No emitir sonido ni vibrar nunca \n- Ocultar de la pantalla de bloqueo y de la barra de estado \n- Mostrar en la parte inferior de la lista de notificaciones \n\n"<b>"Nivel 0"</b>" \n- Bloquear todas las notificaciones de la aplicación"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificaciones"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ya no recibirás estas notificaciones."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ya no recibirás estas notificaciones"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorías de notificación"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Esta aplicación no tiene categorías de notificación"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"No se pueden desactivar las notificaciones de esta aplicación"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categorías de notificación de esta aplicación</item>
       <item quantity="one">1 de <xliff:g id="NUMBER_0">%d</xliff:g> categoría de notificación de esta aplicación</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"Controles de las notificaciones"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"Opciones para posponer las notificaciones"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 horas"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"DESHACER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Volverá a mostrarse en <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d horas</item>
+      <item quantity="one">%d hora</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minutos</item>
+      <item quantity="one">%d minuto</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso de la batería"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ahorro de batería no disponible mientras se carga el dispositivo"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ahorro de batería"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Reemplazar"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplicaciones que se están ejecutando en segundo plano"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca para ver información detallada sobre el uso de datos y de la batería"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"¿Desactivar los datos móviles?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings_car.xml b/packages/SystemUI/res/values-es/strings_car.xml
index e19ca78..47a40b0 100644
--- a/packages/SystemUI/res/values-es/strings_car.xml
+++ b/packages/SystemUI/res/values-es/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduce de forma segura"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Permanece atento a la conducción y respeta siempre las normas de tráfico. Las indicaciones pueden ser inexactas, incompletas, peligrosas o inadecuadas o dar lugar a maniobras prohibidas o al cruce de zonas regionales diferentes. La información sobre empresas también puede ser inexacta o estar incompleta. No se ofrecen datos en tiempo real ni se puede garantizar la exactitud de las ubicaciones. No utilices el dispositivo móvil ni aplicaciones que no estén destinadas a Android Auto mientras conduces."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Desconocido"</string>
+    <string name="start_driving" msgid="864023351402918991">"Empezar a conducir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index f4605e0..3d3c5dc 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -229,8 +229,8 @@
     <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"Taskulamp on sisse lülitatud."</string>
     <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"Värvi ümberpööramine on välja lülitatud."</string>
     <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"Värvi ümberpööramine on sisse lülitatud."</string>
-    <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobiilside leviala on välja lülitatud."</string>
-    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobiilside leviala on sisse lülitatud."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobiilside kuumkoht on välja lülitatud."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobiilside kuumkoht on sisse lülitatud."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Ekraanikuva ülekandmine on peatatud."</string>
     <string name="accessibility_quick_settings_work_mode_off" msgid="7045417396436552890">"Töörežiim on väljas."</string>
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Töörežiim on sees."</string>
@@ -270,7 +270,7 @@
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Mitte segada"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Ainult prioriteetsed"</string>
-    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Ainult alarmid"</string>
+    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Ainult äratused"</string>
     <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Täielik vaikus"</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> seadet)"</string>
@@ -312,9 +312,10 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Rohkem seadeid"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Valmis"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Ühendatud"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Ühendatud, aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Ühenduse loomine ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Jagamine"</string>
-    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Leviala"</string>
+    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Kuumkoht"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Märguanded"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Taskulamp"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobiilne andmeside"</string>
@@ -331,7 +332,7 @@
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC on lubatud"</string>
     <string name="recents_empty_message" msgid="808480104164008572">"Hiljutisi üksusi pole"</string>
     <string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"Olete kõik ära kustutanud"</string>
-    <string name="recents_app_info_button_label" msgid="2890317189376000030">"Rakenduste teave"</string>
+    <string name="recents_app_info_button_label" msgid="2890317189376000030">"Rakenduse teave"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ekraanikuva kinnitamine"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"otsing"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Rakendust <xliff:g id="APP">%s</xliff:g> ei saanud käivitada."</string>
@@ -354,8 +355,8 @@
     <string name="description_target_search" msgid="3091587249776033139">"Otsing"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Lohistage üles: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Lohistage vasakule: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Helid ja vibratsioonid ei sega teid. Kuulete siiski enda määratud alarme, meeldetuletusi, sündmusi ja helistajaid. Samuti kuulete kõike, mille esitamise ise valite, sh muusika, videod ja mängud."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Helid ja vibratsioonid ei sega teid. Kuulete siiski alarme. Samuti kuulete kõike, mille esitamise ise valite, sh muusika, videod ja mängud."</string>
+    <string name="zen_priority_introduction" msgid="7577965386868311310">"Helid ja värinad ei sega teid. Kuulete siiski enda määratud äratusi, meeldetuletusi, sündmusi ja helistajaid. Samuti kuulete kõike, mille esitamise ise valite, sh muusika, videod ja mängud."</string>
+    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Helid ja värinad ei sega teid. Kuulete siiski äratusi. Samuti kuulete kõike, mille esitamise ise valite, sh muusika, videod ja mängud."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Kohanda"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"See blokeerib KÕIK – sealhulgas alarmide, muusika, videote ja mängude – helid ja värinad. Saate siiski helistada."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"See blokeerib KÕIK – sealhulgas alarmide, muusika, videote ja mängude – helid ja vibratsioonid."</string>
@@ -371,7 +372,7 @@
     <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"Täielik vaikus. See vaigistab ka ekraanilugejad."</string>
     <string name="interruption_level_none" msgid="6000083681244492992">"Täielik vaikus"</string>
     <string name="interruption_level_priority" msgid="6426766465363855505">"Ainult prioriteetsed"</string>
-    <string name="interruption_level_alarms" msgid="5226306993448328896">"Ainult alarmid"</string>
+    <string name="interruption_level_alarms" msgid="5226306993448328896">"Ainult äratused"</string>
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Täielik\nvaikus"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Ainult\nprioriteetsed"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Ainult\nalarmid"</string>
@@ -382,7 +383,7 @@
     <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Kasutaja vahetamine, praegune kasutaja: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Praegune kasutaja <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Kuva profiil"</string>
-    <string name="user_add_user" msgid="5110251524486079492">"Kasutaja lisamine"</string>
+    <string name="user_add_user" msgid="5110251524486079492">"Lisa kasutaja"</string>
     <string name="user_new_user_name" msgid="426540612051178753">"Uus kasutaja"</string>
     <string name="guest_nickname" msgid="8059989128963789678">"Külaline"</string>
     <string name="guest_new_guest" msgid="600537543078847803">"Lisa külaline"</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Olete ühendatud rakendusega <xliff:g id="APPLICATION">%1$s</xliff:g>, mis võib jälgida teie isiklikke võrgutegevusi, sh meile, rakendusi ja veebisaite."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Teie tööprofiili haldab <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profiil on ühendatud rakendusega <xliff:g id="APPLICATION">%2$s</xliff:g>, mis saab jälgida teie töökoha võrgutegevusi, sh meile, rakendusi ja veebisaite.\n\nLisateabe saamiseks võtke ühendust administraatoriga."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Teie tööprofiili haldab <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profiil on ühendatud rakendusega <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, mis saab jälgida teie töökoha võrgutegevusi, sh meile, rakendusi ja veebisaite.\n\nOlete ühendatud ka rakendusega <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, mis saab jälgida teie isiklikke võrgutegevusi."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Avatud kasutaja <xliff:g id="USER_NAME">%1$s</xliff:g> jaoks"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Funktsioon <xliff:g id="TRUST_AGENT">%1$s</xliff:g> töötab"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Seade jääb lukku, kuni selle käsitsi avate"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Saate märguandeid kiiremini"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Näete neid enne avamist"</string>
@@ -523,7 +526,7 @@
     <string name="alarm_template" msgid="3980063409350522735">"kell <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="4242179982586714810">"kell <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Kiirseaded, <xliff:g id="TITLE">%s</xliff:g>."</string>
-    <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Leviala"</string>
+    <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Kuumkoht"</string>
     <string name="accessibility_managed_profile" msgid="6613641363112584120">"Tööprofiil"</string>
     <string name="tuner_warning_title" msgid="7094689930793031682">"Kõik ei pruugi sellest rõõmu tunda"</string>
     <string name="tuner_warning" msgid="8730648121973575701">"Süsteemi kasutajaliidese tuuner pakub täiendavaid võimalusi Androidi kasutajaliidese muutmiseks ja kohandamiseks. Need katselised funktsioonid võivad muutuda, rikki minna või tulevastest versioonidest kaduda. Olge jätkamisel ettevaatlik."</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Väljas"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Toite märguannete juhtnuppudega saate määrata rakenduse märguannete tähtsuse taseme vahemikus 0–5. \n\n"<b>"5. tase"</b>" \n- Kuva märguannete loendi ülaosas\n- Luba täisekraanil häirimine \n- Kuva alati ekraani servas \n\n"<b>"4. tase"</b>" \n- Keela täisekraanil häirimine \n- Kuva alati ekraani servas \n\n"<b>"3. tase"</b>" \n- Keela täisekraanil häirimine \n- Ära kunagi kuva ekraani servas \n\n"<b>"2. tase"</b>" \n- Keela täisekraanil häirimine \n- Ära kunagi kuva ekraani servas \n- Ära kunagi helise ega vibreeri \n\n"<b>"1. tase"</b>" \n- Keela täisekraanil häirimine \n- Ära kunagi kuva ekraani servas \n- Ära kunagi helise ega vibreeri \n- Peida lukustuskuval ja olekuribal \n- Kuva märguannete loendi allosas \n\n"<b>"Tase 0"</b>" \n- Blokeeri kõik rakenduse märguanded"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Märguanded"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Te ei saa enam neid märguandeid."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Te ei saa enam neid märguandeid"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> märguandekategooriat"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Sellel rakendusel ei ole märguannete kategooriaid"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Selle rakenduse märguandeid ei saa välja lülitada"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 <xliff:g id="NUMBER_1">%d</xliff:g>-st märguannete kategooriast sellelt rakenduselt</item>
       <item quantity="one">1 <xliff:g id="NUMBER_0">%d</xliff:g>-st märguannete kategooriast sellelt rakenduselt</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"märguannete juhtnupud"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"märguannete edasilükkamise valikud"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutit"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutit"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"Üks tund"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"kaks tundi"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"VÕTA TAGASI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Edasi lükatud <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d tundi</item>
+      <item quantity="one">%d tund</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minutit</item>
+      <item quantity="one">%d minut</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Akukasutus"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akusäästja pole laadimise ajal saadaval"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akusäästja"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Asenda"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Rakendusi käitatakse taustal"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Aku ja andmekasutuse üksikasjade nägemiseks puudutage"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Kas lülitada mobiilne andmeside välja?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings_car.xml b/packages/SystemUI/res/values-et/strings_car.xml
index c41385a..a63c3f3 100644
--- a/packages/SystemUI/res/values-et/strings_car.xml
+++ b/packages/SystemUI/res/values-et/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Sõitke turvaliselt"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Olge teadlik sõidutingimustest ja järgige alati kohaldatavaid seadusi. Juhised võivad olla ebatäpsed, mittetäielikud, ohtlikud, sobimatud, keelatud või hõlmata kattuvaid administratiivpiirkondi. Ka ettevõtteteave võib olla ebatäpne või mittetäielik. Andmed pole reaalajas ja asukoha täpsust ei saa garanteerida. Ärge kasutage auto juhtimisel mobiilseadet ega rakendusi, mis pole mõeldud teenuse Android Auto jaoks."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Teadmata"</string>
+    <string name="start_driving" msgid="864023351402918991">"Sõidu alustamine"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 06432b8..ddbf5bc 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -242,7 +242,7 @@
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Kargatzen"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G datuen erabilera eten da"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G datuen erabilera eten da"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Datu mugikorrak pausatu egin dira"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Datu-konexioa pausatu egin da"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Datuen erabilera eten da"</string>
     <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Iritsi zara ezarri zenuen datu-mugara. Datu mugikorrak erabiltzeari utzi diozu.\n\nDatu mugikorrak erabiltzeari berrekiten badiozu, datuen erabileragatiko gastuak izango dituzu."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Jarraitu erabiltzen"</string>
@@ -300,7 +300,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi konexioa desaktibatuta"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Aktibatuta dago Wi-Fi konexioa"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Ez dago Wi-Fi sarerik erabilgarri"</string>
-    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Igorri"</string>
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Igortzen"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Izenik gabeko gailua"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Igortzeko prest"</string>
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Ezarpen gehiago"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Eginda"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Konektatuta"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Konektatuta. Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Konektatzen…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Konexioa partekatzea"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Sare publikoa"</string>
@@ -341,9 +342,9 @@
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Zatitze horizontala"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Zatitze bertikala"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Zatitze pertsonalizatua"</string>
-    <string name="recents_accessibility_split_screen_top" msgid="9056056469282256287">"Banandu pantaila eta ezarri goian"</string>
-    <string name="recents_accessibility_split_screen_left" msgid="8987144699630620019">"Banandu pantaila eta ezarri ezkerrean"</string>
-    <string name="recents_accessibility_split_screen_right" msgid="275069779299592867">"Banandu pantaila eta ezarri eskuinean"</string>
+    <string name="recents_accessibility_split_screen_top" msgid="9056056469282256287">"Zatitu pantaila eta ezarri goian"</string>
+    <string name="recents_accessibility_split_screen_left" msgid="8987144699630620019">"Zatitu pantaila eta ezarri ezkerrean"</string>
+    <string name="recents_accessibility_split_screen_right" msgid="275069779299592867">"Zatitu pantaila eta ezarri eskuinean"</string>
   <string-array name="recents_blacklist_array">
   </string-array>
     <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Kargatuta"</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"<xliff:g id="APPLICATION">%1$s</xliff:g> aplikaziora konektatuta zaude. Aplikazio horrek sarean egiten dituzun jarduera pertsonalak kontrola ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> erakundeak kudeatzen dizu laneko profila. <xliff:g id="APPLICATION">%2$s</xliff:g> aplikaziora dago konektatuta profila, eta aplikazio horrek sarean egiten dituzun jarduerak kontrola ditzake, mezu elektronikoak, aplikazioak eta webguneak barne.\n\nInformazio gehiago lortzeko, jarri administratzailearekin harremanetan."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> erakundeak kudeatzen dizu laneko profila. <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> aplikaziora dago konektatuta profila, eta aplikazio horrek sarean egiten dituzun jarduerak kontrola ditzake, mezu elektronikoak, aplikazioak eta webguneak barne. \n\n<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> aplikaziora ere zaude konektatuta, eta hark sare pertsonalean egiten dituzun jarduerak kontrola ditzake."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> erabiltzailearentzat desblokeatu da"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> abian da"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Gailua blokeatuta egongo da eskuz desblokeatu arte"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Eskuratu jakinarazpenak azkarrago"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Ikusi desblokeatu baino lehen"</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desaktibatuta"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Bateria-mailaren arabera jakinarazpenak kontrolatzeko aukerekin, 0 eta 5 bitarteko garrantzi-mailetan sailka ditzakezu aplikazioen jakinarazpenak. \n\n"<b>"5. maila"</b>" \n- Erakutsi jakinarazpenen zerrendaren goialdean. \n- Baimendu etetea pantaila osoko moduan zaudenean. \n- Agerrarazi beti jakinarazpenak. \n\n"<b>"4. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Agerrarazi beti jakinarazpenak. \n\n"<b>"3. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Ez agerrarazi jakinarazpenik inoiz. \n\n"<b>"2. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Ez agerrarazi jakinarazpenik inoiz. \n- Ez egin soinurik edo dardararik inoiz. \n\n"<b>"1. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Ez agerrarazi jakinarazpenik inoiz. \n- Ez egin soinurik edo dardararik inoiz. \n- Ezkutatu pantaila blokeatutik eta egoera-barratik. \n- Erakutsi jakinarazpenen zerrendaren behealdean. \n\n"<b>"0. maila"</b>" \n- Blokeatu aplikazioaren jakinarazpen guztiak."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Jakinarazpenak"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Aurrerantzean ez duzu jasoko horrelako jakinarazpenik."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Aurrerantzean ez duzu jasoko horrelako jakinarazpenik"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Jakinarazpenen <xliff:g id="NUMBER">%d</xliff:g> kategoria"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Aplikazio honek ez du jakinarazpen-kategoriarik"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Ezin dira desaktibatu aplikazio honen jakinarazpenak"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Aplikazio honen 1/<xliff:g id="NUMBER_1">%d</xliff:g> jakinarazpen-kategoria</item>
       <item quantity="one">Aplikazio honen 1/<xliff:g id="NUMBER_0">%d</xliff:g> jakinarazpen-kategoria</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"jakinarazpena kontrolatzeko aukerak"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"jakinarazpena atzeratzeko aukerak"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutu"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutu"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ordu"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ordu"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"DESEGIN"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>z atzeratu da"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d ordu</item>
+      <item quantity="one">%d ordu</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minutu</item>
+      <item quantity="one">%d minutu</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Bateriaren erabilera"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Bateria-aurrezlea ez dago erabilgarri gailua kargatzen ari denean"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Bateria-aurrezlea"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Ordeztu"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikazioak exekutatzen ari dira atzeko planoan"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Sakatu bateria eta datuen erabilerari buruzko xehetasunak ikusteko"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Datu-konexioa desaktibatu nahi duzu?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings_car.xml b/packages/SystemUI/res/values-eu/strings_car.xml
index c4371f7..59c2bb2 100644
--- a/packages/SystemUI/res/values-eu/strings_car.xml
+++ b/packages/SystemUI/res/values-eu/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Gidatu zentzuz"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Egon erne errepidera begira eta gorde lege aplikagarri oro. Agian jarraibideak ez dira guztiz zehatzak, osatuak edo egokiak izango; arriskutsuak izan daitezke edo debekatuta dagoen zerbait egitea edo mugak zeharkatzea proposa diezazukete. Baliteke enpresei buruzko informazioa ere guztiz zehatza edo osatua ez izatea. Datuak ez dira une-unekoak eta ezin da bermatu kokapenaren zehaztasuna. Gidatu bitartean, ez erabili gailu mugikorrik edo Android Auto zerbitzuarekin erabiltzeko egina ez dagoen aplikaziorik."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Ezezaguna"</string>
+    <string name="start_driving" msgid="864023351402918991">"Hasi gidatzen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index ec567dc..75495fe 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"تنظیمات بیشتر"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"تمام"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"متصل"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"متصل، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"در حال اتصال..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"اتصال به اینترنت با تلفن همراه"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"نقطه اتصال"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"به <xliff:g id="APPLICATION">%1$s</xliff:g> وصل شده‌اید، که می‌تواند فعالیت شبکه شخصی شما را (ازجمله رایانامه‌‌ها، برنامه‌‌ها و وب‌سایت‌ها) کنترل کند."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"نمایه کاری شما توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g> مدیریت می‌شود. این نمایه به <xliff:g id="APPLICATION">%2$s</xliff:g> متصل است که می‌تواند فعالیت شما در شبکه (ازجمله رایانامه‌ها، برنامه‌ها و وب‌سایت‌ها) را پایش کند.\n\nبرای اطلاعات بیشتر، با سرپرست سیستم تماس بگیرید."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"نمایه کاری‌تان توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g> مدیریت می‌شود. این نمایه به <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> متصل است که می‌تواند تنظیمات، دسترسی شرکتی، برنامه‌ها، داده‌های مرتبط با دستگاه و اطلاعات مکان دستگاه شما را پایش کند.\n\nشما همچنین به <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> متصل هستید که می‌تواند فعالیت خصوصی شما را در شبکه پایش کند."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"قفل برای <xliff:g id="USER_NAME">%1$s</xliff:g> باز شد"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> درحال اجرا است"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"دستگاه قفل باقی می‌ماند تا زمانی که قفل آن را به صورت دستی باز کنید"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"دریافت سریع‌تر اعلان‌ها"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"قبل از باز کردن قفل آنها را مشاهده کنید"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"خاموش"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"با کنترل‌های قدرتمند اعلان می‌توانید سطح اهمیت اعلان‌های هر برنامه را از ۰ تا ۵ تعیین کنید. \n\n"<b>"سطح ۵"</b>" \n- در صدر فهرست اعلان‌ها نشان داده می‌شود \n- وقفه برای نمایش تمام‌صفحه مجاز است \n- همیشه اجمالی نشان داده می‌شود \n\n"<b>"سطح ۴"</b>" \n- وقفه برای نمایش تمام‌صفحه مجاز نیست \n- همیشه اجمالی نشان داده می‌شود \n\n"<b>"سطح ۳"</b>" \n- وقفه برای نمایش تمام‌صفحه مجاز نیست \n- هیچ‌وقت اجمالی نشان داده نمی‌شود \n\n"<b>"سطح ۲"</b>" \n- وقفه برای نمایش تمام‌صفحه مجاز نیست \n- هیچ‌وقت اجمالی نشان داده نمی‌شود \n- هیچ‌وقت صدا و لرزش ایجاد نمی‌کند \n\n"<b>"سطح ۱"</b>" \n- نمایش تمام صفحه مجاز نیست \n- هیچ‌وقت اجمالی نشان داده نمی‌شود \n- هیچ‌وقت صدا یا لرزش ایجاد نمی‌کند \n- در قفل صفحه و نوار وضعیت پنهان است \n- در پایین فهرست اعلان‌ها نشان داده می‌شود \n\n"<b>"سطح ۰"</b>" \n- همه اعلان‌های این برنامه مسدود است"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"اعلان‌ها"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"دیگر این اعلان‌ها را دریافت نخواهید کرد."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"دیگر این اعلان‌ها را دریافت نخواهید کرد"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> دسته اعلان"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"این برنامه دسته اعلان ندارد"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"نمی‌توان اعلان‌های این برنامه را خاموش کرد"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">۱ از <xliff:g id="NUMBER_1">%d</xliff:g> دسته اعلان این برنامه</item>
       <item quantity="other">۱ از <xliff:g id="NUMBER_1">%d</xliff:g> دسته اعلان این برنامه</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"کنترل‌های اعلان"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"گزینه‌های تعویق اعلان"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"۱۵ دقیقه"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"۳۰ دقیقه"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"۱ ساعت"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"۲ ساعت"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"واگرد"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> به تعویق افتاد"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">‏%d ساعت</item>
+      <item quantity="other">‏%d ساعت</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">‏%d دقیقه</item>
+      <item quantity="other">‏%d دقیقه</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"مصرف باتری"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"هنگام شارژ شدن، «بهینه‌سازی باتری» در دسترس نیست"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"بهینه‌سازی باتری"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"جایگزین کردن"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"برنامه‌هایی که در پس‌زمینه اجرا می‌شوند"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"برای جزئیات مربوط به مصرف باتری و داده، ضربه بزنید"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"داده شبکه تلفن همراه خاموش شود؟"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings_car.xml b/packages/SystemUI/res/values-fa/strings_car.xml
index e8433fa..e914796 100644
--- a/packages/SystemUI/res/values-fa/strings_car.xml
+++ b/packages/SystemUI/res/values-fa/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"با ایمنی برانید"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"‏کاملاً از شرایط رانندگی آگاه باشید و همیشه قوانین مربوطه را رعایت کنید. مسیرها ممکن است غیردقیق، ناقص، ناکامل، خطرناک، نامناسب، ممنوع یا مستلزم عبور از تقسیمات کشوری باشند. اطلاعات کسب و کار نیز ممکن است غیردقیق یا ناکامل باشند. داده‌ها بی‌درنگ نیستند و دقت مکان نمی‌تواند تضمین شود. هنگام رانندگی دستگاه همراه را در دست نگیرید یا از برنامه‌هایی که ویژه Android Auto نیستند استفاده نکنید."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"نامشخص"</string>
+    <string name="start_driving" msgid="864023351402918991">"شروع رانندگی"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index f4e5616..4ed7f1c 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -240,7 +240,7 @@
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Ladataan"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G-tiedonsiirto keskeytettiin"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-tiedonsiirto keskeytettiin"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Mobiilidatan käyttö on keskeytetty."</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Mobiilidatan käyttö on keskeytetty"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Tiedonsiirto keskeytettiin"</string>
     <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Asettamasi dataraja on saavutettu. Et enää käytä mobiilidataa.\n\nJos jatkat käyttöä, datan käytöstä saatetaan periä maksuja."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Jatka"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Lisäasetukset"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Valmis"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Yhdistetty"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Yhdistetty, akun varaus <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Yhdistetään…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Jaettu yhteys"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Olet muodostanut yhteyden sovellukseen <xliff:g id="APPLICATION">%1$s</xliff:g>, joka voi valvoa henkilökohtaista toimintaasi verkossa. Sovellus voi esimerkiksi seurata avaamiasi sähköposteja, sovelluksia ja verkkosivustoja."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> hallinnoi työprofiiliasi. Se on yhteydessä sovellukseen <xliff:g id="APPLICATION">%2$s</xliff:g>, joka voi valvoa toimintaasi verkossa, esimerkiksi sähköposteja, sovelluksia ja verkkosivustoja.\n\nPyydä lisätietoja järjestelmänvalvojalta."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> hallinnoi työprofiiliasi. Se on yhteydessä sovellukseen <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, joka voi valvoa toimintaasi verkossa, esimerkiksi sähköposteja, sovelluksia ja verkkosivustoja.\n\nLisäksi olet yhteydessä sovellukseen <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, joka voi valvoa henkilökohtaista toimintaasi verkossa."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Lukitus avattu käyttäjälle <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> on käytössä"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Laite pysyy lukittuna, kunnes se avataan käsin"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Näe ilmoitukset nopeammin"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Näytä ennen lukituksen avaamista"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Pois käytöstä"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Ilmoitusten tehohallinnan avulla voit määrittää sovelluksen ilmoituksille tärkeystason väliltä 0–5. \n\n"<b>"Taso 5"</b>" \n– Ilmoitukset näytetään ilmoitusluettelon yläosassa \n– Näkyminen koko näytön tilassa sallitaan \n– Ilmoitukset kurkistavat aina näytölle\n\n"<b>"Taso 4"</b>" \n– Näkyminen koko näytön tilassa estetään \n– Ilmoitukset kurkistavat aina näytölle \n\n"<b>"Taso 3"</b>" \n– Näkyminen koko näytön tilassa estetään \n– Ei kurkistamista \n\n"<b>"Taso 2"</b>" \n– Näkyminen koko näytön tilassa estetään \n– Ei kurkistamista \n– Ei ääniä eikä värinää \n\n"<b>"Taso 1"</b>" \n– Näkyminen koko näytön tilassa estetään \n– Ei kurkistamista \n– Ei ääniä eikä värinää \n– Ilmoitukset piilotetaan lukitusnäytöltä ja tilapalkista \n– Ilmoitukset näytetään ilmoitusluettelon alaosassa \n\n"<b>"Taso 0"</b>" \n– Kaikki sovelluksen ilmoitukset estetään"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Ilmoitukset"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Et saa näitä ilmoituksia enää."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Et saa näitä ilmoituksia enää."</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ilmoitusluokkaa"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Tällä sovelluksella ei ole ilmoitusluokkia."</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Tämän sovelluksen ilmoituksia ei voi poistaa käytöstä."</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Tämä sovellus: 1/<xliff:g id="NUMBER_1">%d</xliff:g> ilmoitusluokkaa</item>
       <item quantity="one">Tämä sovellus: 1/<xliff:g id="NUMBER_0">%d</xliff:g> ilmoitusluokkaa</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"Ilmoitusten hallinta"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"Ilmoitusten torkkuasetukset"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuuttia"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuuttia"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 tunti"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 tuntia"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"KUMOA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Torkku: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d tuntia</item>
+      <item quantity="one">%d tunti</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minuuttia</item>
+      <item quantity="one">%d minuutti</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Akun käyttö"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Virransäästö ei ole käytettävissä latauksen aikana."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Virransäästö"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Korvaa"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Sovelluksia käynnissä taustalla"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Katso lisätietoja akun ja datan käytöstä napauttamalla"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Poistetaanko mobiilidata käytöstä?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings_car.xml b/packages/SystemUI/res/values-fi/strings_car.xml
index fc94b90..927b13d 100644
--- a/packages/SystemUI/res/values-fi/strings_car.xml
+++ b/packages/SystemUI/res/values-fi/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Aja varovasti"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Tarkkaile huolellisesti ajo-olosuhteita ja noudata aina voimassa olevia lakeja. Reittiohjeet saattavat olla epätarkkoja, epätäydellisiä, vaarallisia, epäsopivia, kiellettyjä tai kulkea hallintoalueiden läpi. Myös yritystiedot voivat olla epätarkkoja tai epätäydellisiä. Tietoja ei päivitetä reaaliajassa eikä sijaintien tarkkuutta taata. Älä käytä ajon aikana mobiililaitettasi tai sovelluksia, joita ei ole suunniteltu Android Autolle."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Tuntematon"</string>
+    <string name="start_driving" msgid="864023351402918991">"Aloita ajaminen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 827958c..9218f76 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -269,8 +269,8 @@
     <string name="start_dreams" msgid="5640361424498338327">"Écran de veille"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ne pas déranger"</string>
-    <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Priorités seulement"</string>
-    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alarmes uniquement"</string>
+    <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Prioritaires seulement"</string>
+    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alarmes seulement"</string>
     <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Aucune interruption"</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> appareils)"</string>
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Plus de paramètres"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Terminé"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Connecté"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connecté. Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Connexion en cours…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Partage de connexion"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Point d\'accès sans fil"</string>
@@ -335,7 +336,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"épinglage d\'écran"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Impossible de lancer <xliff:g id="APP">%s</xliff:g>."</string>
-    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> est désactivée en mode sécurisé."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> est désactivée en mode sans échec."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Effacer tout"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Glissez l\'élément ici pour utiliser l\'écran partagé"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Séparation horizontale"</string>
@@ -351,7 +352,7 @@
     <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Chargée dans <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
     <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"N\'est pas en charge"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Le réseau peut\nêtre surveillé."</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Recherche"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Rechercher"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Faire glisser le doigt vers le haut : <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Faites glisser votre doigt vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="zen_priority_introduction" msgid="7577965386868311310">"Vous ne serez pas dérangé par les sons et les vibrations, sauf pour les alarmes, les rappels, les événements et les appelants. Vous entendrez tout ce que vous choisissez d\'écouter, y compris la musique, les vidéos et les jeux."</string>
@@ -371,7 +372,7 @@
     <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"Aucune interruption : le son des lecteurs d\'écran sera également désactivé."</string>
     <string name="interruption_level_none" msgid="6000083681244492992">"Aucune interruption"</string>
     <string name="interruption_level_priority" msgid="6426766465363855505">"Priorités seulement"</string>
-    <string name="interruption_level_alarms" msgid="5226306993448328896">"Alarmes uniquement"</string>
+    <string name="interruption_level_alarms" msgid="5226306993448328896">"Alarmes seulement"</string>
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Aucune\ninterruption"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priorités\nuniquement"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarmes\nuniquement"</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Vous êtes connecté à <xliff:g id="APPLICATION">%1$s</xliff:g>. Cette application peut contrôler votre activité personnelle sur le réseau, y compris les courriels, les applications et les sites Web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Votre profil professionnel est géré par <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ce profil est connecté à <xliff:g id="APPLICATION">%2$s</xliff:g>, qui peut contrôler votre activité professionnelle sur le réseau, y compris l\'activité relative aux courriels, aux applications et aux sites Web.\n\nPour en savoir plus, communiquez avec votre administrateur."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Votre profil professionnel est géré par <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ce profil est connecté à <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, qui peut contrôler votre activité professionnelle sur le réseau, y compris l\'activité relative aux courriels, aux applications et aux sites Web.\n\nVous êtes également connecté à <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, qui peut contrôler votre activité personnelle sur le réseau."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Déverrouillé pour for <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> fonctionne"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"L\'appareil restera verrouillé jusqu\'à ce que vous le déverrouilliez manuellement"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Voir les notifications plus rapidement"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Afficher les notifications avant de déverrouiller l\'appareil"</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Désactivé"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Avec les réglages avancés des notifications, vous pouvez définir un degré d\'importance de 0 à 5 pour les notifications d\'une application. \n\n"<b>"Niveau 5"</b>" \n- Afficher dans le haut de la liste des notifications \n- Autoriser les interruptions en mode plein écran \n- Toujours afficher les aperçus \n\n"<b>"Niveau 4"</b>" \n- Empêcher les interruptions en mode plein écran \n- Toujours afficher les aperçus \n\n"<b>"Niveau 3"</b>" \n- Empêcher les interruptions en mode plein écran \n- Ne jamais afficher les aperçus \n\n"<b>"Niveau 2"</b>" \n- Empêcher les interruptions en mode plein écran \n- Ne jamais afficher les aperçus \n- Ne pas autoriser les sons et les vibrations \n\n"<b>"Niveau 1"</b>" \n- Empêcher les interruptions en mode plein écran \n- Ne jamais afficher les aperçus \n- Ne pas autoriser les sons et les vibrations \n- Masquer de l\'écran de verrouillage et de la barre d\'état status bar \n- Afficher dans le bas de la liste des notifications \n\n"<b>"Level 0"</b>" \n- Bloquer toutes les notifications de l\'application"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Vous ne recevrez plus ces notifications."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Vous ne recevrez plus ces notifications"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> catégories de notification"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Cette application n\'a pas de catégories de notification"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Les notifications de cette application ne peuvent pas être désactivées"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 catégorie de notification sur <xliff:g id="NUMBER_1">%d</xliff:g> provenant de cette application</item>
       <item quantity="other">1 catégorie de notification sur <xliff:g id="NUMBER_1">%d</xliff:g> provenant de cette application</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"paramètres des notifications"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"options de répétition des notifications"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 heure"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 heures"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ANNULER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Reporté pour <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d heure</item>
+      <item quantity="other">%d heures</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d minute</item>
+      <item quantity="other">%d minutes</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Utilisation de la pile"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Le mode Économie d\'énergie n\'est pas accessible pendant la charge"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Économie d\'énergie"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Remplacer"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Applications qui fonctionnent en arrière-plan"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Touchez pour afficher des détails sur l\'utilisation de la pile et des données"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Désactiver les données cellulaires?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings_car.xml b/packages/SystemUI/res/values-fr-rCA/strings_car.xml
index 10e1fd5..a88dc3b 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings_car.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduisez prudemment"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Tenez compte des conditions de la route et respectez toujours les lois en vigueur. Les itinéraires peuvent être incorrects, incomplets, dangereux, inappropriés ou interdits, et ils peuvent traverser des zones administratives. Les renseignements sur les entreprises peuvent également être incorrects ou incomplets. Les données ne sont pas fournies en temps réel, et la précision de la localisation n\'est pas garantie. Ne manipulez pas votre appareil mobile et n\'utilisez pas d\'applications non conçues pour Android Auto lorsque vous conduisez."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Inconnu"</string>
+    <string name="start_driving" msgid="864023351402918991">"Commencer à conduire"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index e78c892..b962ca4 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Plus de paramètres"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"OK"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Connecté"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connecté, batterie à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Connexion en cours..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Partage de connexion"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Point d\'accès"</string>
@@ -354,8 +355,8 @@
     <string name="description_target_search" msgid="3091587249776033139">"Rechercher"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Faites glisser vers le haut pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Faites glisser vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Vous ne serez pas dérangé par des sons ou des vibrations, hormis ceux des alarmes, des rappels, des événements et des appelants de votre choix. Vous entendrez toujours les sons que vous choisirez de jouer, notamment la musique, les vidéos et les jeux."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Vous ne serez pas dérangé par des sons ou des vibrations, hormis ceux des alarmes. Vous entendrez toujours les sons que vous choisirez de jouer, notamment la musique, les vidéos et les jeux."</string>
+    <string name="zen_priority_introduction" msgid="7577965386868311310">"Vous ne serez dérangé par aucun son ni aucune vibration, hormis ceux des alarmes, des rappels, des événements et des appels des contacts de votre choix. Le son continuera de fonctionner notamment pour la musique, les vidéos et les jeux."</string>
+    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Vous ne serez dérangé par aucun son ni aucune vibration, hormis ceux des alarmes. Le son continuera de fonctionner notamment pour la musique, les vidéos et les jeux."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personnaliser"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Cette option permet de bloquer TOUS les sons et les vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux. Vous pourrez toujours passer des appels téléphoniques."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Cette option permet de bloquer TOUS les sons et les vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux."</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Vous êtes connecté à <xliff:g id="APPLICATION">%1$s</xliff:g>. Cette application peut contrôler votre activité personnelle sur le réseau, y compris les e-mails, les applications et les sites Web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Votre profil professionnel est géré par <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ce profil est connecté à <xliff:g id="APPLICATION">%2$s</xliff:g>, qui peut contrôler votre activité professionnelle sur le réseau, y compris l\'activité relative aux e-mails, aux applications et aux sites Web.\n\nPour plus d\'informations, contactez votre administrateur."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Votre profil professionnel est géré par <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ce profil est connecté à <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, qui peut contrôler votre activité professionnelle sur le réseau, y compris l\'activité relative aux e-mails, aux applications et aux sites Web.\n\nVous êtes également connecté à <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, qui peut contrôler votre activité personnelle sur le réseau."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Déverrouillé pour <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> est en cours d\'exécution"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"L\'appareil restera verrouillé jusqu\'à ce que vous le déverrouilliez manuellement."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Recevoir les notifications plus vite"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Afficher les notifications avant de déverrouiller l\'appareil"</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Désactivé"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Grâce aux commandes de gestion des notifications, vous pouvez définir le niveau d\'importance (compris entre 0 et 5) des notifications d\'une application. \n\n"<b>"Niveau 5"</b>" \n- Afficher en haut de la liste des notifications \n- Autoriser l\'interruption en plein écran \n- Toujours en aperçu \n\n"<b>"Niveau 4"</b>" \n- Empêcher l\'interruption en plein écran \n- Toujours en aperçu \n\n"<b>"Niveau 3"</b>" \n- Empêcher l\'interruption en plein écran \n- Jamais en aperçu \n\n"<b>"Niveau 2"</b>" \n- Empêcher l\'interruption en plein écran \n- Jamais en aperçu \n- Ne jamais émettre de signal sonore ni déclencher le vibreur \n\n"<b>"Niveau 1"</b>" \n- Empêcher l\'interruption en plein écran \n- Jamais en aperçu \n- Ne jamais émettre de signal sonore ni déclencher le vibreur \n- Masquer les notifications dans l\'écran de verrouillage et la barre d\'état \n- Afficher au bas de la liste des notifications \n\n"<b>"Niveau 0"</b>" \n- Bloquer toutes les notifications de l\'application"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Vous ne recevrez plus ces notifications."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Vous ne recevrez plus ces notifications"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> catégories de notification"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Cette application n\'a pas de catégories de notification"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Impossible de désactiver les notifications de cette application"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 catégorie de notification sur <xliff:g id="NUMBER_1">%d</xliff:g> provenant de cette application</item>
       <item quantity="other">1 catégorie de notification sur <xliff:g id="NUMBER_1">%d</xliff:g> provenant de cette application</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> : <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"paramètres des notifications"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"options de répétition des notifications"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 heure"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 heures"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ANNULER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Répétée après <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d heure</item>
+      <item quantity="other">%d heures</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d minute</item>
+      <item quantity="other">%d minutes</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Utilisation batterie"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"L\'économiseur de batterie n\'est pas disponible lorsque l\'appareil est en charge."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Économiseur de batterie"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Remplacer"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Applications en cours d\'exécution en arrière-plan"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Appuyer pour obtenir des informations sur l\'utilisation de la batterie et des données"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Désactiver les données mobiles ?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings_car.xml b/packages/SystemUI/res/values-fr/strings_car.xml
index d42586e..a88dc3b 100644
--- a/packages/SystemUI/res/values-fr/strings_car.xml
+++ b/packages/SystemUI/res/values-fr/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Soyez prudent sur la route"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Tenez compte des conditions de conduite et respectez toujours les lois en vigueur. Les itinéraires peuvent être incorrects, incomplets, dangereux, inappropriés ou interdits, et traverser des frontières administratives. Les informations sur les établissements peuvent également être incorrectes ou incomplètes. Les données ne sont pas fournies en temps réel, et la précision de la localisation n\'est pas garantie. Ne manipulez pas votre appareil mobile et n\'utilisez pas d\'applications non conçues pour Android Auto lorsque vous conduisez."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Inconnu"</string>
+    <string name="start_driving" msgid="864023351402918991">"Commencer à conduire"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 3cd4e71..64fda6b 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -43,7 +43,7 @@
     <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"Activar"</string>
     <string name="battery_saver_start_action" msgid="5576697451677486320">"Activar o aforro de batería"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Configuración"</string>
-    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
+    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wifi"</string>
     <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Xirar pantalla automaticamente"</string>
     <string name="status_bar_settings_mute_label" msgid="554682549917429396">"APAGAR"</string>
     <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
@@ -252,7 +252,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Localización establecida polo GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de localización activas"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Eliminar todas as notificacións."</string>
-    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> máis"</string>
     <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404">
       <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> notificacións máis no grupo.</item>
       <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> notificación máis no grupo.</item>
@@ -288,7 +288,7 @@
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Localización desactivada"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Dispositivo multimedia"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
-    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Só chamadas de emerxencia"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Só chamadas de urxencia"</string>
     <string name="quick_settings_settings_label" msgid="5326556592578065401">"Configuración"</string>
     <string name="quick_settings_time_label" msgid="4635969182239736408">"Hora"</string>
     <string name="quick_settings_user_label" msgid="5238995632130897840">"Eu"</string>
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Máis opcións"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Feito"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Conectado"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Dispositivo conectado. Nivel da batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Conectando..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Conexión compartida"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona wifi"</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Estás conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode supervisar a túa actividade persoal na rede, incluídos os correos electrónicos, as aplicacións e os sitios web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> xestiona o teu perfil de traballo, que está conectado a <xliff:g id="APPLICATION">%2$s</xliff:g>. Esta aplicación pode controlar a túa actividade na rede, mesmo os correos electrónicos, as aplicacións e os sitios web.\n\nPara obter máis información, contacta co administrador."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> xestiona o teu perfil de traballo, que está conectado a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>. Esta aplicación pode controlar a túa actividade na rede, mesmo os correos electrónicos, as aplicacións e os sitios web.\n\nTamén estás conectado a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pode controlar a túa actividade persoal na rede."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Desbloqueado para: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Estase executando: <xliff:g id="TRUST_AGENT">%1$s</xliff:g>"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"O dispositivo permanecerá bloqueado ata que o desbloquees manualmente"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Recibir notificacións máis rápido"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Consúltaas antes de desbloquear"</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desactivar"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Cos controis de notificacións mellorados, podes asignarlles un nivel de importancia comprendido entre 0 e 5 ás notificacións dunha aplicación determinada. \n\n"<b>"Nivel 5"</b>" \n- Mostrar na parte superior da lista de notificacións. \n- Permitir interrupcións no modo de pantalla completa. \n- Mostrar sempre. \n\n"<b>"Nivel 4"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Mostrar sempre. \n\n"<b>"Nivel 3"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Non mostrar nunca. \n\n"<b>"Nivel 2"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Non mostrar nunca. \n- Non soar nin vibrar nunca. \n\n"<b>"Nivel 1"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Non mostrar nunca. \n- Non soar nin vibrar nunca. \n- Ocultar na pantalla de bloqueo e na barra de estado. \n- Mostrar na parte inferior da lista de notificacións. \n\n"<b>"Nivel 0"</b>" \n- Bloquear todas as notificacións da aplicación."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificacións"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Deixarás de recibir estas notificacións."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Deixarás de recibir estas notificacións"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorías de notificacións"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Esta aplicación non ten categorías de notificacións"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Non se poden desactivar as notificacións desta aplicación"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categorías de notificacións desta aplicación</item>
       <item quantity="one">1 de <xliff:g id="NUMBER_0">%d</xliff:g> categoría de notificación desta aplicación</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"controis de notificacións"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opcións para adiar notificacións"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 horas"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"DESFACER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Adiouse <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d horas</item>
+      <item quantity="one">%d hora</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minutos</item>
+      <item quantity="one">%d minuto</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso de batería"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A función de aforro da batería non está dispoñible durante a carga"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Aforro de batería"</string>
@@ -614,7 +622,7 @@
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Volver"</string>
     <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notificacións"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Atallos de teclado"</string>
-    <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Cambiar de método de entrada"</string>
+    <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Cambiar de método de introdución"</string>
     <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplicacións"</string>
     <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Asistente"</string>
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navegador"</string>
@@ -753,7 +761,7 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Almacenamento"</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="app_info" msgid="6856026610594615344">"Información de aplicacións"</string>
+    <string name="app_info" msgid="6856026610594615344">"Info. da aplicación"</string>
     <string name="go_to_web" msgid="1106022723459948514">"Acceder á web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Datos móbiles"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"A wifi está desactivada"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Substituír"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplicacións que se executan en segundo plano"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca para obter información sobre o uso de datos e a batería"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Queres desactivar os datos móbiles?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings_car.xml b/packages/SystemUI/res/values-gl/strings_car.xml
index bb3f8eb..e6c6298 100644
--- a/packages/SystemUI/res/values-gl/strings_car.xml
+++ b/packages/SystemUI/res/values-gl/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduce de forma segura"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Ten moi en conta as condicións de condución e respecta sempre as leis aplicables. É posible que as indicacións sexan imprecisas, incompletas, perigosas, inadecuadas, estean prohibidas ou que impliquen atravesar áreas administrativas. A información das empresas tamén pode ser imprecisa ou estar incompleta. Os datos non se proporcionan en tempo real e non se garante a precisión da localización. Non manipules o teu dispositivo móbil nin utilices aplicacións que non estean deseñadas para Android Auto mentres conduces."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Descoñecido"</string>
+    <string name="start_driving" msgid="864023351402918991">"Comezar a conducir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 2cb19ed..1a8a7f0b 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/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="6456385927409742437">"બૅટરી ઓછી છે"</string>
     <string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> બાકી"</string>
     <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> બાકી. બૅટરી સેવર ચાલુ છે."</string>
@@ -43,12 +43,12 @@
     <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"ચાલુ કરો"</string>
     <string name="battery_saver_start_action" msgid="5576697451677486320">"બૅટરી સેવર ચાલુ કરો"</string>
     <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_wifi_button" msgid="1733928151698311923">"વાઇ-ફાઇ"</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_auto_brightness_label" msgid="511453614962324674">"સ્વતઃ"</string>
-    <string name="status_bar_settings_notifications" msgid="397146176280905137">"સૂચનાઓ"</string>
-    <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth ટિથર કર્યું"</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>
     <string name="usb_device_permission_prompt" msgid="834698001271562057">"<xliff:g id="APPLICATION">%1$s</xliff:g> એપ્લિકેશનને USB ઉપકરણ અ‍ૅક્સેસ કરવાની મંજૂરી આપીએ?"</string>
@@ -84,7 +84,7 @@
     <string name="accessibility_home" msgid="8217216074895377641">"હોમ"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"મેનુ"</string>
     <string name="accessibility_accessibility_button" msgid="7601252764577607915">"ઍક્સેસિબિલિટી"</string>
-    <string name="accessibility_recent" msgid="5208608566793607626">"વિહંગાવલોકન"</string>
+    <string name="accessibility_recent" msgid="5208608566793607626">"ઝલક"</string>
     <string name="accessibility_search_light" msgid="1103867596330271848">"શોધો"</string>
     <string name="accessibility_camera_button" msgid="8064671582820358152">"કૅમેરો"</string>
     <string name="accessibility_phone_button" msgid="6738112589538563574">"ફોન"</string>
@@ -100,7 +100,7 @@
     <string name="cancel" msgid="6442560571259935130">"રદ કરો"</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>
+    <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"બ્લૂટૂથ કનેક્ટ થયું."</string>
     <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"બ્લૂટૂથ ડિસ્કનેક્ટ થયું."</string>
     <string name="accessibility_no_battery" msgid="358343022352820946">"બૅટરી નથી."</string>
     <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"બૅટરી એક બાર."</string>
@@ -150,21 +150,21 @@
     <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
     <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"રોમિંગ"</string>
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
-    <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
-    <string name="accessibility_no_sim" msgid="8274017118472455155">"SIM નથી."</string>
+    <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"વાઇ-ફાઇ"</string>
+    <string name="accessibility_no_sim" msgid="8274017118472455155">"સિમ નથી."</string>
     <string name="accessibility_cell_data" msgid="5326139158682385073">"મોબાઇલ ડેટા"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"મોબાઇલ ડેટા ચાલુ છે"</string>
     <string name="accessibility_cell_data_off" msgid="443267573897409704">"મોબાઇલ ડેટા બંધ છે"</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth ટિથરિંગ."</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"બ્લૂટૂથ ટિથરિંગ."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"એરપ્લેન મોડ."</string>
     <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN ચાલુ છે."</string>
-    <string name="accessibility_no_sims" msgid="3957997018324995781">"કોઇ SIM કાર્ડ નથી."</string>
+    <string name="accessibility_no_sims" msgid="3957997018324995781">"કોઈ સિમ કાર્ડ નથી."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"કેરીઅર નેટવર્કમાં ફેરફાર થઈ રહ્યો છે."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"બૅટરીની વિગતો ખોલો"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"બૅટરી <xliff:g id="NUMBER">%d</xliff:g> ટકા."</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"બૅટરી ચાર્જ થઈ રહી છે, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ટકા."</string>
     <string name="accessibility_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>
@@ -182,11 +182,11 @@
     <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> પ્રારંભ કરી રહ્યું છે."</string>
     <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$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>
-    <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"વિહંગાવલોકન."</string>
+    <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"ઝલક."</string>
     <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"કાર્ય લૉક સ્ક્રીન"</string>
     <string name="accessibility_desc_close" msgid="7479755364962766729">"બંધ કરો"</string>
     <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
@@ -205,13 +205,13 @@
     <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"ખલેલ પાડશો નહીં બંધ."</string>
     <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"ખલેલ પાડશો નહીં બંધ કર્યું."</string>
     <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"ખલેલ પાડશો નહીં ચાલુ કર્યું."</string>
-    <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth."</string>
-    <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth બંધ."</string>
-    <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth ચાલુ."</string>
-    <string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"Bluetooth કનેક્ટ કરી રહ્યું છે."</string>
-    <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"Bluetooth કનેક્ટ થયું."</string>
-    <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"Bluetooth બંધ કરી."</string>
-    <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"Bluetooth ચાલુ કર્યું."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"બ્લૂટૂથ."</string>
+    <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"બ્લૂટૂથ બંધ."</string>
+    <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"બ્લૂટૂથ ચાલુ."</string>
+    <string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"બ્લૂટૂથ કનેક્ટ કરી રહ્યું છે."</string>
+    <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"બ્લૂટૂથ કનેક્ટ થયું."</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"બ્લૂટૂથ બંધ કરી."</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"બ્લૂટૂથ ચાલુ કર્યું."</string>
     <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"સ્થાનની જાણ કરવી બંધ."</string>
     <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"સ્થાનની જાણ કરવી ચાલુ."</string>
     <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"સ્થાનની જાણ કરવી બંધ કર્યું."</string>
@@ -227,8 +227,8 @@
     <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"ફ્લેશલાઇટ ચાલુ કરી."</string>
     <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"રંગ ઉલટાવવાનું બંધ કર્યું."</string>
     <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"રંગ ઉલટાવવાનું ચાલુ કર્યું."</string>
-    <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"મોબાઇલ હોટસ્પોટ બંધ કર્યું."</string>
-    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"મોબાઇલ હોટસ્પોટ ચાલુ કર્યું."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"મોબાઇલ હૉટસ્પૉટ બંધ કર્યું."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"મોબાઇલ હૉટસ્પૉટ ચાલુ કર્યું."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"સ્ક્રીન કાસ્ટિંગ બંધ કર્યું."</string>
     <string name="accessibility_quick_settings_work_mode_off" msgid="7045417396436552890">"કાર્ય મોડ બંધ."</string>
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"કાર્ય મોડ ચાલુ."</string>
@@ -242,10 +242,10 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G ડેટા થોભાવ્યો છે"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"મોબાઇલ ડેટા થોભાવ્યો છે"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"ડેટા થોભાવ્યો છે"</string>
-    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"તમે સેટ કરેલી ડેટા મર્યાદા પહોંચી ગઇ છે. તમે હવે મોબાઇલ ડેટાનો ઉપયોગ નથી કરી રહ્યાં.\n\nજો હવે તમે ફરી શરૂ કરો, તો ડેટા વપરાશ માટે શુલ્ક લાગુ થઇ શકે છે."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"તમારા દ્વારા સેટ કરેલ ડેટા મર્યાદા પર તમે પહોંચી ગયાં છો. તમે હવે મોબાઇલ ડેટાનો ઉપયોગ કરી રહ્યાં નથી.\n\nજો તમે ફરી શરૂ કરો છો, તો ડેટા વપરાશ માટે શુલ્ક લાગુ થઈ શકે છે."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"ફરી શરૂ કરો"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"કોઈ ઇન્ટરનેટ કનેક્શન નથી"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi કનેક્ટ કર્યું"</string>
+    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"વાઇ-ફાઇ કનેક્ટ કર્યું"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS માટે શોધી રહ્યાં છે"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS દ્વારા સ્થાન સેટ કરાયું"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"સ્થાન વિનંતીઓ સક્રિય"</string>
@@ -270,13 +270,13 @@
     <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_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>
-    <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth બંધ"</string>
+    <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"બ્લૂટૂથ"</string>
+    <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"બ્લૂટૂથ (<xliff:g id="NUMBER">%d</xliff:g> ઉપકરણો)"</string>
+    <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"બ્લૂટૂથ બંધ"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"કોઈ જોડી કરેલ ઉપકરણો ઉપલબ્ધ નથી"</string>
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"તેજ"</string>
-    <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"સ્વતઃ-ફેરવો"</string>
-    <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"સ્ક્રીનને સ્વતઃ-ફેરવો"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"આપમેળે ફેરવો"</string>
+    <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"સ્ક્રીનને આપમેળે ફેરવો"</string>
     <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"<xliff:g id="ID_1">%s</xliff:g> મોડ"</string>
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"પરિભ્રમણ લૉક થયું"</string>
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"પોર્ટ્રેટ"</string>
@@ -292,12 +292,12 @@
     <string name="quick_settings_user_label" msgid="5238995632130897840">"હું"</string>
     <string name="quick_settings_user_title" msgid="4467690427642392403">"વપરાશકર્તા"</string>
     <string name="quick_settings_user_new_user" msgid="9030521362023479778">"નવો વપરાશકર્તા"</string>
-    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
+    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"વાઇ-ફાઇ"</string>
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"કનેક્ટ થયેલ નથી"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"કોઈ નેટવર્ક નથી"</string>
-    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi બંધ"</string>
-    <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi ચાલુ"</string>
-    <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"કોઈ Wi-Fi નેટવર્ક્સ ઉપલબ્ધ નથી"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"વાઇ-ફાઇ બંધ"</string>
+    <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"વાઇ-ફાઇ ચાલુ"</string>
+    <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"કોઈ વાઇ-ફાઇ નેટવર્ક્સ ઉપલબ્ધ નથી"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"કાસ્ટ કરો"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"કાસ્ટ કરી રહ્યાં છે"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"અનામાંકિત ઉપકરણ"</string>
@@ -310,10 +310,11 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"વધુ સેટિંગ્સ"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"થઈ ગયું"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"કનેક્ટ થયેલ"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"કનેક્ટ કરેલ, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"કનેક્ટ કરી રહ્યું છે..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ટિથરિંગ"</string>
-    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"હોટસ્પોટ"</string>
-    <string name="quick_settings_notifications_label" msgid="4818156442169154523">"સૂચનાઓ"</string>
+    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"હૉટસ્પૉટ"</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>
@@ -352,7 +353,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"શોધો"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> માટે ઉપર સ્લાઇડ કરો."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> માટે ડાબે સ્લાઇડ કરો."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"તમને ધ્વનિ કે વાઇબ્રેશનો દ્વારા ખલેલ પહોંચાડવામાં આવશે નહીં, સિવાય કે અલાર્મ, સ્મૃતિપત્રો, ઇવેન્ટ અને તમે ઉલ્લેખ કરો તે કૉલર. તમે સંગીત, વીડિયો અને રમતો સહિત તમે જે કંઈપણ ચલાવવાનું પસંદ કરો તે હજુ પણ સંભળાશે."</string>
+    <string name="zen_priority_introduction" msgid="7577965386868311310">"અલાર્મ, રિમાઇન્ડર, ઇવેન્ટ અને તમે ઉલ્લેખ કરો તે કૉલર સિવાય તમને ધ્વનિ કે વાઇબ્રેશન દ્વારા ખલેલ પહોંચાડવામાં આવશે નહીં. સંગીત, વીડિઓ અને રમતો સહિત તમે જે કંઈપણ ચલાવવાનું પસંદ કરશો તે સંભળાતું રહેશે."</string>
     <string name="zen_alarms_introduction" msgid="7034415210361973827">"તમને ધ્વનિ કે વાઇબ્રેશનો દ્વારા ખલેલ પહોંચાડવામાં આવશે નહીં, સિવાય કે અલાર્મ. તમે સંગીત, વીડિયો અને રમતો સહિત તમે જે કંઈપણ ચલાવવાનું પસંદ કરો તે હજુ પણ સંભળાશે."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"કસ્ટમાઇઝ કરો"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"આ એલાર્મ્સ, સંગીત, વિડિઓઝ અને રમતો સહિત તમામ ધ્વનિઓ અને વાઇબ્રેશન્સને અવરોધિત કરે છે.  તમે હજુ પણ ફોન કૉલ્સ કરવા માટે સમર્થ હશો."</string>
@@ -404,7 +405,7 @@
     <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="237918726750955859">"બેટરી સેવર ચાલુ છે"</string>
-    <string name="battery_saver_notification_text" msgid="820318788126672692">"પ્રદર્શન અને પૃષ્ઠભૂમિ ડેટા ઘટાડે છે"</string>
+    <string name="battery_saver_notification_text" msgid="820318788126672692">"પ્રદર્શન અને બૅકગ્રાઉન્ડ ડેટા ઘટાડે છે"</string>
     <string name="battery_saver_notification_action_text" msgid="109158658238110382">"બૅટરી સેવર બંધ કરો"</string>
     <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>
@@ -426,7 +427,7 @@
     <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8973606847896650284">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> તમારી કાર્ય પ્રોફાઇલમાં નેટવર્ક ટ્રાફિકનું નિયમન કરી શકે છે"</string>
     <string name="quick_settings_disclosure_monitoring" msgid="679658227269205728">"નેટવર્કનું નિયમન કરવામાં આવી શકે છે"</string>
     <string name="quick_settings_disclosure_vpns" msgid="8170318392053156330">"આ ઉપકરણ બે VPN સાથે કનેક્ટ કરેલ છે"</string>
-    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="3494535754792751741">"કાર્ય પ્રોફાઇલ <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે"</string>
+    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="3494535754792751741">"કાર્યાલયની પ્રોફાઇલ <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4467456202486569906">"વ્યક્તિગત પ્રોફાઇલ <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="6943724064780847080">"આ ઉપકરણ <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે"</string>
     <string name="monitoring_title_device_owned" msgid="1652495295941959815">"ઉપકરણનું સંચાલન"</string>
@@ -446,7 +447,7 @@
     <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"તમારા વ્યવસ્થાપકે નેટવર્ક લૉગિંગ ચાલુ કર્યું છે, જે તમારા ઉપકરણ પર નેટવર્ક ટ્રાફિકનું નિયમન કરે છે."</string>
     <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"તમે <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ થયાં છો, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટ સહિત તમારી નેટવર્ક પ્રવૃત્તિનું નિરીક્ષણ કરી શકે છે."</string>
     <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"તમે <xliff:g id="VPN_APP_0">%1$s</xliff:g> અને <xliff:g id="VPN_APP_1">%2$s</xliff:g> સાથે કનેક્ટ થયાં છો, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટ સહિત તમારી નેટવર્ક પ્રવૃત્તિનું નિરીક્ષણ કરી શકે છે."</string>
-    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"તમારી કાર્ય પ્રોફાઇલ <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે."</string>
+    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"તમારી કાર્યાલયની પ્રોફાઇલ <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે."</string>
     <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"તમારી વ્યક્તિગત પ્રોફાઇલ <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે."</string>
     <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"તમારું ઉપકરણ <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે."</string>
     <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, તમારા ઉપકરણનું સંચાલન કરવા માટે <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> નો ઉપયોગ કરે છે."</string>
@@ -465,33 +466,35 @@
     <string name="monitoring_description_app" msgid="1828472472674709532">"તમે <xliff:g id="APPLICATION">%1$s</xliff:g> સાથે કનેક્ટ થયા છો, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે."</string>
     <string name="monitoring_description_app_personal" msgid="484599052118316268">"તમે <xliff:g id="APPLICATION">%1$s</xliff:g> સાથે કનેક્ટ થયાં છો, જે ઇમેઇલ્સ, ઍપ્લિકેશનો અને વેબસાઇટ્સ સહિતની તમારી વ્યક્તિગત નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે."</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"તમે <xliff:g id="APPLICATION">%1$s</xliff:g> સાથે કનેક્ટ થયાં છો, જે ઇમેઇલ્સ, ઍપ્લિકેશનો અને વેબસાઇટ્સ સહિત તમારી વ્યક્તિગત નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે."</string>
-    <string name="monitoring_description_app_work" msgid="4612997849787922906">"તમારી કાર્ય પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા  સંચાલિત કરાય છે. આ પ્રોફાઇલ <xliff:g id="APPLICATION">%2$s</xliff:g> સાથે કનેક્ટ કરેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
-    <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"તમારી કાર્ય પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે. આ પ્રોફાઇલ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> સાથે કનેક્ટ કરેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે.\n\nતમે <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> સાથે પણ કનેક્ટ કરેલું છે, જે તમારી વ્યક્તિગત નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે."</string>
+    <string name="monitoring_description_app_work" msgid="4612997849787922906">"તમારી કાર્યાલયની પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે. આ પ્રોફાઇલ <xliff:g id="APPLICATION">%2$s</xliff:g> સાથે કનેક્ટ થયેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિત તમારા કાર્યાલયના નેટવર્કની પ્રવૃત્તિનું નિયમન કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
+    <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"તમારી કાર્યાલયની પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે. આ પ્રોફાઇલ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> સાથે કનેક્ટ કરેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે.\n\nતમે <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> સાથે પણ કનેક્ટ કરેલું છે, જે તમારી વ્યક્તિગત નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> માટે અનલૉક કર્યુ"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ચાલી રહ્યું છે"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"તમે ઉપકરણને મેન્યુઅલી અનલૉક કરશો નહીં ત્યાં સુધી તે લૉક રહેશે"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"વધુ ઝડપથી સૂચનાઓ મેળવો"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"તમે અનલૉક કરો તે પહેલાં તેમને જુઓ"</string>
-    <string name="hidden_notifications_cancel" msgid="3690709735122344913">"નહીં આભાર"</string>
+    <string name="hidden_notifications_cancel" msgid="3690709735122344913">"ના, આભાર"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"સેટ અપ"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="volume_zen_end_now" msgid="6930243045593601084">"હમણાં બંધ કરો"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"વિસ્તૃત કરો"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"સંકુચિત કરો"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"સ્ક્રીન પિન કરેલ છે"</string>
-    <string name="screen_pinning_description" msgid="8909878447196419623">"તમે જ્યાં સુધી અનપિન કરશો નહીં ત્યાં સુધી આ તેને દૃશ્યક્ષમ રાખે છે. અનપિન કરવા માટે પાછળ અને વિહંગાવલોકન ટચ કરો અને પકડી રાખો."</string>
-    <string name="screen_pinning_description_accessible" msgid="426190689254018656">"તમે જ્યાં સુધી અનપિન કરશો નહીં ત્યાં સુધી આ તેને દૃશ્યક્ષમ રાખે છે. અનપિન કરવા માટે વિહંગાવલોકન ટચ કરો અને પકડી રાખો."</string>
+    <string name="screen_pinning_description" msgid="8909878447196419623">"તમે જ્યાં સુધી અનપિન કરશો નહીં ત્યાં સુધી આ તેને દૃશ્યક્ષમ રાખે છે. અનપિન કરવા માટે પાછળ અને ઝલકને સ્પર્શ કરી રાખો."</string>
+    <string name="screen_pinning_description_accessible" msgid="426190689254018656">"તમે જ્યાં સુધી અનપિન કરશો નહીં ત્યાં સુધી આ તેને દૃશ્યક્ષમ રાખે છે. અનપિન કરવા માટે ઝલકને સ્પર્શ કરી રાખો."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"સમજાઈ ગયું"</string>
-    <string name="screen_pinning_negative" msgid="3741602308343880268">"નહીં આભાર"</string>
+    <string name="screen_pinning_negative" msgid="3741602308343880268">"ના, આભાર"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ને છુપાવીએ?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"તે સેટિંગ્સમાં તમે તેને ચાલુ કરશો ત્યારે આગલી વખતે ફરીથી દેખાશે."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"છુપાવો"</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"તમે તમારી કાર્ય પ્રોફાઇલનો ઉપયોગ કરી રહ્યાં છો"</string>
     <string name="stream_voice_call" msgid="4410002696470423714">"કૉલ કરો"</string>
     <string name="stream_system" msgid="7493299064422163147">"સિસ્ટમ"</string>
-    <string name="stream_ring" msgid="8213049469184048338">"રિંગ કરો"</string>
+    <string name="stream_ring" msgid="8213049469184048338">"રિંગ વગાડો"</string>
     <string name="stream_music" msgid="9086982948697544342">"મીડિયા"</string>
     <string name="stream_alarm" msgid="5209444229227197703">"એલાર્મ"</string>
-    <string name="stream_notification" msgid="2563720670905665031">"સૂચના"</string>
-    <string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
+    <string name="stream_notification" msgid="2563720670905665031">"નોટિફિકેશન"</string>
+    <string name="stream_bluetooth_sco" msgid="2055645746402746292">"બ્લૂટૂથ"</string>
     <string name="stream_dtmf" msgid="2447177903892477915">"દ્વિ બહુ ટોન આવર્તન"</string>
     <string name="stream_accessibility" msgid="301136219144385106">"ઍક્સેસિબિલિટી"</string>
     <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. અનમ્યૂટ કરવા માટે ટૅપ કરો."</string>
@@ -503,16 +506,16 @@
     <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"વૉલ્યૂમ નિયંત્રણ છુપાવ્યાં"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"સિસ્ટમ UI ટ્યૂનર"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"એમ્બેડ કરેલ બૅટરી ટકા બતાવો"</string>
-    <string name="show_battery_percentage_summary" msgid="3215025775576786037">"જ્યારે ચાર્જ ન થઈ રહ્યું હોય ત્યારે સ્થિતિ બાર આયકનની અંદર બૅટરી સ્તર ટકા બતાવો"</string>
+    <string name="show_battery_percentage_summary" msgid="3215025775576786037">"જ્યારે ચાર્જ ન થઈ રહ્યું હોય ત્યારે સ્ટેટસ બાર આયકનની અંદર બૅટરી સ્તર ટકા બતાવો"</string>
     <string name="quick_settings" msgid="10042998191725428">"ઝડપી સેટિંગ્સ"</string>
-    <string name="status_bar" msgid="4877645476959324760">"સ્થિતિ બાર"</string>
-    <string name="overview" msgid="4018602013895926956">"વિહંગાવલોકન"</string>
+    <string name="status_bar" msgid="4877645476959324760">"સ્ટેટસ બાર"</string>
+    <string name="overview" msgid="4018602013895926956">"ઝલક"</string>
     <string name="demo_mode" msgid="2532177350215638026">"સિસ્ટમ UI ડેમો મોડ"</string>
     <string name="enable_demo_mode" msgid="4844205668718636518">"ડેમો મોડ સક્ષમ કરો"</string>
     <string name="show_demo_mode" msgid="2018336697782464029">"ડેમો મોડ બતાવો"</string>
     <string name="status_bar_ethernet" msgid="5044290963549500128">"ઇથરનેટ"</string>
     <string name="status_bar_alarm" msgid="8536256753575881818">"એલાર્મ"</string>
-    <string name="status_bar_work" msgid="6022553324802866373">"કાર્ય પ્રોફાઇલ"</string>
+    <string name="status_bar_work" msgid="6022553324802866373">"કાર્યાલયની પ્રોફાઇલ"</string>
     <string name="status_bar_airplane" msgid="7057575501472249002">"એરપ્લેન મોડ"</string>
     <string name="add_tile" msgid="2995389510240786221">"ટાઇલ ઉમેરો"</string>
     <string name="broadcast_tile" msgid="3894036511763289383">"બ્રોડકાસ્ટ ટાઇલ"</string>
@@ -521,8 +524,8 @@
     <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>
-    <string name="accessibility_managed_profile" msgid="6613641363112584120">"કાર્ય પ્રોફાઇલ"</string>
+    <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">"સિસ્ટમ UI ટ્યૂનર તમને Android વપરાશકર્તા ઇન્ટરફેસને ટ્વીક અને કસ્ટમાઇઝ કરવાની વધારાની રીતો આપે છે. ભાવિ રીલિઝેસમાં આ પ્રાયોગિક સુવિધાઓ બદલાઈ, ભંગ અથવા અદૃશ્ય થઈ શકે છે. સાવધાની સાથે આગળ વધો."</string>
     <string name="tuner_persistent_warning" msgid="8597333795565621795">"ભાવિ રીલિઝેસમાં આ પ્રાયોગિક સુવિધાઓ બદલાઈ, ભંગ અથવા અદૃશ્ય થઈ શકે છે. સાવધાની સાથે આગળ વધો."</string>
@@ -536,21 +539,22 @@
     <string name="qs_rearrange" msgid="8060918697551068765">"ઝડપી સેટિંગ્સને ફરીથી ગોઠવો"</string>
     <string name="show_brightness" msgid="6613930842805942519">"ઝડપી સેટિંગ્સમાં તેજ બતાવો"</string>
     <string name="experimental" msgid="6198182315536726162">"પ્રાયોગિક"</string>
-    <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth ચાલુ કરવુ છે?"</string>
-    <string name="enable_bluetooth_message" msgid="9106595990708985385">"તમારા ટેબ્લેટ સાથે કીબોર્ડ કનેક્ટ કરવા માટે, તમારે પહેલાં Bluetooth ચાલુ કરવાની જરૂર પડશે."</string>
+    <string name="enable_bluetooth_title" msgid="5027037706500635269">"બ્લૂટૂથ ચાલુ કરવુ છે?"</string>
+    <string name="enable_bluetooth_message" msgid="9106595990708985385">"તમારા ટેબ્લેટ સાથે કીબોર્ડ કનેક્ટ કરવા માટે, તમારે પહેલાં બ્લૂટૂથ ચાલુ કરવાની જરૂર પડશે."</string>
     <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"ચાલુ કરો"</string>
     <string name="show_silently" msgid="6841966539811264192">"સૂચનાઓ ચુપચાપ બતાવો"</string>
-    <string name="block" msgid="2734508760962682611">"તમામ સૂચનાઓને અવરોધિત કરો"</string>
+    <string name="block" msgid="2734508760962682611">"તમામ સૂચનાઓને બ્લૉક કરો"</string>
     <string name="do_not_silence" msgid="6878060322594892441">"ચુપ કરશો નહીં"</string>
     <string name="do_not_silence_block" msgid="4070647971382232311">"ચુપ કે અવરોધિત કરશો નહીં"</string>
     <string name="tuner_full_importance_settings" msgid="3207312268609236827">"પાવર સૂચના નિયંત્રણો"</string>
     <string name="tuner_full_importance_settings_on" msgid="7545060756610299966">"ચાલુ"</string>
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"બંધ"</string>
-    <string name="power_notification_controls_description" msgid="4372459941671353358">"પાવર સૂચના નિયંત્રણો સાથે, તમે ઍપ્લિકેશનની સૂચનાઓ માટે 0 થી 5 સુધીના મહત્વના સ્તરને સેટ કરી શકો છો. \n\n"<b>"સ્તર 5"</b>" \n- સૂચના સૂચિની ટોચ પર બતાવો \n- પૂર્ણ સ્ક્રીન અવરોધની મંજૂરી આપો \n- હંમેશાં ત્વરિત દૃષ્ટિ કરો \n\n"<b>"સ્તર 4"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- હંમેશાં ત્વરિત દૃષ્ટિ કરો \n\n"<b>"સ્તર 3"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- ક્યારેય ત્વરિત દૃષ્ટિ કરશો નહીં \n\n"<b>"સ્તર 2"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- ક્યારેય ત્વરિત દૃષ્ટિ કરશો નહીં \n- ક્યારેય અવાજ અને વાઇબ્રેશન કરશો નહીં \n\n"<b>"સ્તર 1"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- ક્યારેય ત્વરિત દૃષ્ટિ કરશો નહીં \n- ક્યારેય અવાજ અથવા વાઇબ્રેટ કરશો નહીં \n- લૉક સ્ક્રીન અને સ્થિતિ બારથી છુપાવો \n- સૂચના સૂચિના તળિયા પર બતાવો \n\n"<b>"સ્તર 0"</b>" \n- ઍપ્લિકેશનની તમામ સૂચનાઓને અવરોધિત કરો"</string>
-    <string name="notification_header_default_channel" msgid="7506845022070889909">"સૂચનાઓ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"તમને હવે આ સૂચનાઓ મળશે નહીં."</string>
+    <string name="power_notification_controls_description" msgid="4372459941671353358">"પાવર સૂચના નિયંત્રણો સાથે, તમે ઍપની સૂચનાઓ માટે 0 થી 5 સુધીના મહત્વના સ્તરને સેટ કરી શકો છો. \n\n"<b>"સ્તર 5"</b>" \n- સૂચના સૂચિની ટોચ પર બતાવો \n- પૂર્ણ સ્ક્રીન અવરોધની મંજૂરી આપો \n- હંમેશાં ત્વરિત દૃષ્ટિ કરો \n\n"<b>"સ્તર 4"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- હંમેશાં ત્વરિત દૃષ્ટિ કરો \n\n"<b>"સ્તર 3"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- ક્યારેય ત્વરિત દૃષ્ટિ કરશો નહીં \n\n"<b>"સ્તર 2"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- ક્યારેય ત્વરિત દૃષ્ટિ કરશો નહીં \n- ક્યારેય અવાજ અથવા વાઇબ્રેટ કરશો નહીં \n\n"<b>"સ્તર 1"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધની મંજૂરી આપો \n- ક્યારેય ત્વરિત દૃષ્ટિ કરશો નહીં \n- ક્યારેય અવાજ અથવા વાઇબ્રેટ કરશો નહીં \n- લૉક સ્ક્રીન અને સ્ટેટસ બારથી છુપાવો \n- સૂચના સૂચિના તળિયા પર બતાવો \n\n"<b>"સ્તર 0"</b>" \n- ઍપની તમામ સૂચનાઓને બ્લૉક કરો"</string>
+    <string name="notification_header_default_channel" msgid="7506845022070889909">"નોટિફિકેશનો"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"તમને હવે આ સૂચનાઓ મળશે નહીં"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> સૂચના કૅટેગરીઓ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"આ ઍપ્લિકેશનમાં સૂચના કૅટેગરી નથી"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"આ ઍપ્લિકેશનની સૂચનાઓ બંધ કરી શકાતી નથી"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">આ ઍપ્લિકેશનમાંની <xliff:g id="NUMBER_1">%d</xliff:g> સૂચના કૅટેગરીમાંથી 1</item>
       <item quantity="other">આ ઍપ્લિકેશનમાંની <xliff:g id="NUMBER_1">%d</xliff:g> સૂચના કૅટેગરીમાંથી 1</item>
@@ -570,16 +574,20 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"સૂચના નિયંત્રણો"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"સૂચના સ્નૂઝ કરવાના વિકલ્પો"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 મિનિટ"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 મિનિટ"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 કલાક"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 કલાક"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"પૂર્વવત્ કરો"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> માટે સ્નૂઝ કરો"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d કલાક</item>
+      <item quantity="other">%d કલાક</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d મિનિટ</item>
+      <item quantity="other">%d મિનિટ</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"બૅટરી વપરાશ"</string>
-    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ચાર્જિંગ દરમિયાન બૅટરી બચતકર્તા ઉપલબ્ધ નથી"</string>
-    <string name="battery_detail_switch_title" msgid="6285872470260795421">"બૅટરી બચતકર્તા"</string>
-    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"પ્રદર્શન અને પૃષ્ઠભૂમિ ડેટા ઘટાડે છે"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ચાર્જિંગ દરમિયાન બૅટરી સેવર ઉપલબ્ધ નથી"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"બૅટરી સેવર"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"પ્રદર્શન અને બૅકગ્રાઉન્ડ ડેટા ઘટાડે છે"</string>
     <string name="keyboard_key_button_template" msgid="6230056639734377300">"બટન <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
     <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
@@ -610,7 +618,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="2334164096341310324">"ઇનપુટ પદ્ધતિ સ્વિચ કરો"</string>
     <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"ઍપ્લિકેશનો"</string>
@@ -628,9 +636,9 @@
     <string name="volume_up_silent" msgid="7141255269783588286">"વૉલ્યૂમ વધારવા પર ખલેલ પાડશો નહીંમાંથી બહાર નિકળો"</string>
     <string name="battery" msgid="7498329822413202973">"બૅટરી"</string>
     <string name="clock" msgid="7416090374234785905">"ઘડિયાળ"</string>
-    <string name="headset" msgid="4534219457597457353">"હેડસેટ"</string>
+    <string name="headset" msgid="4534219457597457353">"હૅડસેટ"</string>
     <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"હેડફોન કનેક્ટ કર્યાં"</string>
-    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"હેડસેટ કનેક્ટ કર્યો"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"હૅડસેટ કનેક્ટ કર્યો"</string>
     <string name="data_saver" msgid="5037565123367048522">"ડેટા સેવર"</string>
     <string name="accessibility_data_saver_on" msgid="8454111686783887148">"ડેટા સેવર ચાલુ છે"</string>
     <string name="accessibility_data_saver_off" msgid="8841582529453005337">"ડેટા સેવર બંધ છે"</string>
@@ -668,7 +676,7 @@
     <string name="qs_edit" msgid="2232596095725105230">"સંપાદિત કરો"</string>
     <string name="tuner_time" msgid="6572217313285536011">"સમય"</string>
   <string-array name="clock_options">
-    <item msgid="5965318737560463480">"કલાક, મિનિટ અને સેકંડ બતાવો"</item>
+    <item msgid="5965318737560463480">"કલાક, મિનિટ અને સેકન્ડ બતાવો"</item>
     <item msgid="1427801730816895300">"કલાક અને મિનિટ બતાવો (ડિફોલ્ટ)"</item>
     <item msgid="3830170141562534721">"આ આઇકન બતાવશો નહીં"</item>
   </string-array>
@@ -698,7 +706,7 @@
     <string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> દૂર કરવામાં આવ્યું છે"</string>
     <string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ને <xliff:g id="POSITION">%2$d</xliff:g> સ્થિતિ પર ખસેડ્યું"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"ઝડપી સેટિંગ્સ સંપાદક."</string>
-    <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> સૂચના: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
+    <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> નોટિફિકેશન: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"વિભાજિત-સ્ક્રીન સાથે ઍપ્લિકેશન કદાચ કામ ન કરે."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ઍપ્લિકેશન સ્ક્રીન-વિભાજનનું સમર્થન કરતી નથી."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર કદાચ કામ ન કરે."</string>
@@ -727,7 +735,7 @@
     <string name="pip_skip_to_prev" msgid="1955311326688637914">"પહેલાંના પર જાઓ"</string>
     <string name="thermal_shutdown_title" msgid="4458304833443861111">"ફોન વધુ પડતી ગરમીને લીધે બંધ થઇ ગયો છે"</string>
     <string name="thermal_shutdown_message" msgid="9006456746902370523">"તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"તમારો ફોન અત્યંત ગરમ હતો, તેથી તે ઠંડો થવા આપમેળે બંધ થઇ ગયો છે. તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે.\n\nતમારો ફોન અત્યંત ગરમ થઇ શકે છે, જો તમે:\n • એવી ઍપ્લિકેશન વાપરતા હો જે સંસાધન સઘન રીતે વાપરતી હોય (જેમ કે ગેમિંગ, વિડિઓ, અથવા નેવિગેટ કરતી ઍપ્લિકેશનો)\n • મોટી ફાઇલો અપલોડ અથવા ડાઉનલોડ કરતા હો\n • તમારા ફોનનો ઉપયોગ ઉચ્ચ તાપમાનમાં કરતા હો"</string>
+    <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"તમારો ફોન અત્યંત ગરમ હતો, તેથી તે ઠંડો થવા આપમેળે બંધ થઇ ગયો છે. તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે.\n\nતમારો ફોન અત્યંત ગરમ થઇ શકે છે, જો તમે:\n • એવી ઍપ્લિકેશન વાપરતા હો જે સંસાધન સઘન રીતે વાપરતી હોય (જેમ કે ગેમિંગ, વીડિઓ, અથવા નેવિગેટ કરતી ઍપ્લિકેશનો)\n • મોટી ફાઇલો અપલોડ અથવા ડાઉનલોડ કરતા હો\n • તમારા ફોનનો ઉપયોગ ઉચ્ચ તાપમાનમાં કરતા હો"</string>
     <string name="high_temp_title" msgid="4589508026407318374">"ફોન ગરમ થઈ રહ્યો છે"</string>
     <string name="high_temp_notif_message" msgid="5642466103153429279">"ફોન ઠંડો થાય ત્યાં સુધી કેટલીક સુવિધાઓ મર્યાદિત હોય છે"</string>
     <string name="high_temp_dialog_message" msgid="6840700639374113553">"તમારો ફોન આપમેળે ઠંડો થવાનો પ્રયાસ કરશે. તમે હજી પણ તમારા ફોનનો ઉપયોગ કરી શકો છો, પરંતુ તે કદાચ થોડો ધીમો ચાલે.\n\nતમારો ફોન ઠંડો થઈ જવા પર, તે સામાન્ય રીતે ચાલશે."</string>
@@ -754,8 +762,8 @@
     <string name="app_info" msgid="6856026610594615344">"ઍપ્લિકેશન માહિતી"</string>
     <string name="go_to_web" msgid="1106022723459948514">"વેબ પર જાઓ"</string>
     <string name="mobile_data" msgid="7094582042819250762">"મોબાઇલ ડેટા"</string>
-    <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi બંધ છે"</string>
-    <string name="bt_is_off" msgid="2640685272289706392">"Bluetooth બંધ છે"</string>
+    <string name="wifi_is_off" msgid="1838559392210456893">"વાઇ-ફાઇ બંધ છે"</string>
+    <string name="bt_is_off" msgid="2640685272289706392">"બ્લૂટૂથ બંધ છે"</string>
     <string name="dnd_is_off" msgid="6167780215212497572">"ખલેલ પાડશો નહીં બંધ છે"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"ખલેલ પાડશો નહીં એક સ્વચાલિત નિયમ દ્વારા ચાલુ કરાયું હતું (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"ખલેલ પાડશો નહીં એક ઍપ્લિકેશન દ્વારા ચાલુ કરાયું હતું (<xliff:g id="ID_1">%s</xliff:g>)."</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"બદલો"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"પૃષ્ઠભૂમિમાં ચાલી રહેલ ઍપ્લિકેશનો"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"બૅટરી અને ડેટા વપરાશ વિશેની વિગતો માટે ટૅપ કરો"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"મોબાઇલ ડેટા બંધ કરીએ?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings_car.xml b/packages/SystemUI/res/values-gu/strings_car.xml
index b22b688..57a6f02 100644
--- a/packages/SystemUI/res/values-gu/strings_car.xml
+++ b/packages/SystemUI/res/values-gu/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"સુરક્ષિત રીતે વાહન ચલાવો"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ડ્રાઇવિંગ સ્થિતિઓથી સંપૂર્ણપણે વાકેફ રહો અને હંમેશા લાગુ કાયદાઓનું પાલન કરો. દિશા નિર્દેશો અચોક્કસ, અપૂર્ણ, જોખમમકારક, બિન અનુકૂળ, પ્રતિબંધિત અથવા વહીવટી વિસ્તારોને ઓળંગવાનું સમાવતા હોઇ શકે છે. વ્યવસાય માહિતી પણ અચોક્કસ અથવા અપૂર્ણ હોઇ શકે છે. ડેટા રિઅલ-ટાઇમ નથી અને સ્થાન ચોકસાઈની ગેરંટી આપી શકતાં નથી. ડ્રાઇવિંગ કરતી વખતે Android Auto માટે તમારું મોબાઇલ સાધન હેન્ડલ કરવું અથવા ઍપ્લિકેશનનો ઉપયોગ કરવાનું કોઇ પ્રયોજન નથી."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"અજાણ"</string>
+    <string name="start_driving" msgid="864023351402918991">"ડ્રાઇવિંગ શરૂ કરો"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi-land/strings.xml b/packages/SystemUI/res/values-hi-land/strings.xml
index de6a6c9..ed0070d 100644
--- a/packages/SystemUI/res/values-hi-land/strings.xml
+++ b/packages/SystemUI/res/values-hi-land/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="toast_rotation_locked" msgid="7609673011431556092">"स्‍क्रीन को अभी भूदृश्य अभिविन्यास में लॉक किया गया है."</string>
+    <string name="toast_rotation_locked" msgid="7609673011431556092">"स्क्रीन अभी लैंडस्केप दिशा में लॉक है."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index a61499b..6ddc813 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -19,17 +19,17 @@
 
 <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">"सिस्‍टम UI"</string>
+    <string name="app_label" msgid="7164937344850004466">"सिस्‍टम यूआई"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"साफ़ करें"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"सूची से निकालें"</string>
-    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"ऐप्स की जानकारी"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"ऐप की जानकारी"</string>
     <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"आपकी हाल की स्‍क्रीन यहां दिखाई देती हैं"</string>
     <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"हाल ही के ऐप्स  खारिज करें"</string>
     <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
-      <item quantity="one">अवलोकन में %d स्‍क्रीन</item>
-      <item quantity="other">अवलोकन में %d स्‍क्रीन</item>
+      <item quantity="one">%d स्क्रीन की खास जानकारी</item>
+      <item quantity="other">%d स्क्रीन की खास जानकारी</item>
     </plurals>
-    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"कोई नोटिफ़िकेशन नहीं"</string>
+    <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="battery_low_title" msgid="6456385927409742437">"बैटरी कम है"</string>
@@ -49,7 +49,7 @@
     <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>
-    <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"इनपुट पद्धति सेट करें"</string>
+    <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"इनपुट का तरीका सेट करें"</string>
     <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"भौतिक कीबोर्ड"</string>
     <string name="usb_device_permission_prompt" msgid="834698001271562057">"ऐप्स  <xliff:g id="APPLICATION">%1$s</xliff:g> को USB डिवाइस तक पहुंचने दें?"</string>
     <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"ऐप्स  <xliff:g id="APPLICATION">%1$s</xliff:g> को USB सहायक डिवाइस तक पहुंचने दें?"</string>
@@ -64,9 +64,9 @@
     <string name="usb_debugging_message" msgid="2220143855912376496">"कंप्यूटर का RSA कुंजी फ़िंगरप्रिंट है:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"इस कंप्यूटर से हमेशा अनुमति दें"</string>
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB डीबगिंग की अनुमति नहीं है"</string>
-    <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"वर्तमान में इस डिवाइस में प्रवेश किया हुआ उपयोगकर्ता USB डीबगिंग चालू नहीं कर सकता. इस सुविधा का उपयोग करने के लिए, कृपया किसी नियंत्रक उपयोगकर्ता में स्‍विच करें."</string>
+    <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"अभी इस डिवाइस में जिस उपयोगकर्ता ने साइन इन किया है वो USB डीबगिंग चालू नहीं कर सकता. इस सुविधा का इस्तेमाल करने के लिए, कृपया किसी एडमिन उपयोगकर्ता में बदलें."</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"स्‍क्रीन भरने के लिए ज़ूम करें"</string>
-    <string name="compat_mode_off" msgid="4434467572461327898">"स्‍क्रीन को भरने के लिए खींचें"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"स्‍क्रीन भरने के लिए खींचें"</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"स्क्रीनशॉट सहेजा जा रहा है..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"स्क्रीनशॉट सहेजा जा रहा है..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"स्क्रीनशॉट सहेजा जा रहा है."</string>
@@ -74,7 +74,7 @@
     <string name="screenshot_saved_text" msgid="2685605830386712477">"अपना स्क्रीनशॉट देखने के लिए टैप करें."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"स्क्रीनशॉट को कैप्चर नहीं किया जा सका."</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"स्क्रीनशॉट सहेजने में समस्या आई"</string>
-    <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"सीमित मेमोरी स्थान के कारण स्क्रीनशॉट सहेजा नहीं जा सकता."</string>
+    <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"मेमोरी में जगह कम होने की वजह से स्क्रीनशॉट सेव नहीं किया जा सकता."</string>
     <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ऐप्लिकेशन या आपका संगठन स्क्रीनशॉट लेने की अनुमति नहीं देता"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB फ़ाइल स्थानांतरण विकल्प"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"मीडिया प्लेयर के रूप में माउंट करें (MTP)"</string>
@@ -82,22 +82,22 @@
     <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac के लिए Android File Transfer ऐप्स इंस्टॉल करें"</string>
     <string name="accessibility_back" msgid="567011538994429120">"वापस जाएं"</string>
     <string name="accessibility_home" msgid="8217216074895377641">"होम"</string>
-    <string name="accessibility_menu" msgid="316839303324695949">"मेनू"</string>
-    <string name="accessibility_accessibility_button" msgid="7601252764577607915">"एक्सेस-योग्यता"</string>
-    <string name="accessibility_recent" msgid="5208608566793607626">"अवलोकन"</string>
-    <string name="accessibility_search_light" msgid="1103867596330271848">"खोजें"</string>
+    <string name="accessibility_menu" msgid="316839303324695949">"मेन्यू"</string>
+    <string name="accessibility_accessibility_button" msgid="7601252764577607915">"सुलभता"</string>
+    <string name="accessibility_recent" msgid="5208608566793607626">"खास जानकारी"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"सर्च करें"</string>
     <string name="accessibility_camera_button" msgid="8064671582820358152">"कैमरा"</string>
     <string name="accessibility_phone_button" msgid="6738112589538563574">"फ़ोन"</string>
-    <string name="accessibility_voice_assist_button" msgid="487611083884852965">"वॉइस सहायक"</string>
+    <string name="accessibility_voice_assist_button" msgid="487611083884852965">"आवाज़ से डिवाइस का इस्तेमाल"</string>
     <string name="accessibility_unlock_button" msgid="128158454631118828">"अनलॉक करें"</string>
     <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"फ़िंगरप्रिंट का इंतज़ार हो रहा है"</string>
-    <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"अपने फ़िंगरप्रिंट का उपयोग किए बिना अनलॉक करें"</string>
+    <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"अपने फ़िंगरप्रिंट का इस्तेमाल किए बिना अनलॉक करें"</string>
     <string name="unlock_label" msgid="8779712358041029439">"अनलॉक करें"</string>
     <string name="phone_label" msgid="2320074140205331708">"फ़ोन खोलें"</string>
-    <string name="voice_assist_label" msgid="3956854378310019854">"वॉइस सहायक खोलें"</string>
+    <string name="voice_assist_label" msgid="3956854378310019854">"आवाज़ से डिवाइस को इस्तेमाल करें"</string>
     <string name="camera_label" msgid="7261107956054836961">"कैमरा खोलें"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"नया कार्य लेआउट चुनें"</string>
-    <string name="cancel" msgid="6442560571259935130">"अभी नहीं"</string>
+    <string name="cancel" msgid="6442560571259935130">"रद्द करें"</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>
@@ -155,22 +155,22 @@
     <string name="accessibility_cell_data" msgid="5326139158682385073">"मोबाइल डेटा"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"मोबाइल डेटा चालू है"</string>
     <string name="accessibility_cell_data_off" msgid="443267573897409704">"मोबाइल डेटा बंद है"</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ब्लूटूथ टेदरिंग."</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ब्लूटूथ से इंटरनेट पर शेयर करें."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"हवाई जहाज मोड."</string>
     <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN चालू."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"कोई सिम कार्ड नहीं है."</string>
-    <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"वाहक नेटवर्क बदलना."</string>
+    <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"मोबाइल और इंटरनेट सेवा देने वाली कंपनी का नेटवर्क बदला जा रहा है."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"बैटरी का विवरण खोलें"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> प्रति‍शत बैटरी."</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"बैटरी चार्ज हो रही है, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> प्रतिशत."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"सिस्टम सेटिंग."</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_overflow_action" msgid="5681882033274783311">"पूरी सूचनाएं देखें"</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"सूचना साफ़ करें"</string>
     <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS सक्षम."</string>
     <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS प्राप्त करना."</string>
     <string name="accessibility_tty_enabled" msgid="4613200365379426561">"टेलीटाइपराइटर सक्षम."</string>
-    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"रिंगर कंपन."</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"रिंगर कंपन (वाइब्रेशन)."</string>
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"रिंगर मौन."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
@@ -178,15 +178,15 @@
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> को ख़ारिज करें."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> खा़रिज कर दिया गया."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"हाल ही के सभी ऐप्लिकेशन ख़ारिज कर दिए गए."</string>
-    <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> ऐप्लिकेशन जानकारी खोलें."</string>
+    <string name="accessibility_recents_item_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_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
-    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"नोटिफ़िकेशन खारिज की गई."</string>
-    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"नोटिफ़िकेशन शेड."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"सूचना खारिज की गई."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"सूचना शेड."</string>
     <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"त्वरित सेटिंग."</string>
     <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"लॉक स्क्रीन."</string>
     <string name="accessibility_desc_settings" msgid="3417884241751434521">"सेटिंग"</string>
-    <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"अवलोकन."</string>
+    <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"खास जानकारी."</string>
     <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"कार्य लॉक स्‍क्रीन"</string>
     <string name="accessibility_desc_close" msgid="7479755364962766729">"बंद करें"</string>
     <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
@@ -198,9 +198,9 @@
     <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"हवाई जहाज़ मोड चालू है."</string>
     <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_priority_on" msgid="1448402297221249355">"परेशान ना करें चालू, केवल प्राथमिकता."</string>
+    <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"परेशान ना करें चालू, सिर्फ़ प्राथमिकता."</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"परेशान ना करें चालू है, पूरी तरह शांत."</string>
-    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"परेशान ना करें चालू, केवल अलार्म."</string>
+    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"परेशान ना करें चालू, सिर्फ़ अलार्म."</string>
     <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"परेशान ना करें."</string>
     <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"परेशान ना करें बंद."</string>
     <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"परेशान ना करें बंद किया गया."</string>
@@ -212,12 +212,12 @@
     <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"ब्लूटूथ कनेक्ट है."</string>
     <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"ब्लूटूथ को बंद किया गया."</string>
     <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"ब्लूटूथ को चालू किया गया."</string>
-    <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"स्‍थान रिपोर्टिंग बंद है."</string>
-    <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"स्‍थान रिपोर्टिंग चालू है."</string>
-    <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"स्‍थान रिपोर्टिंग को बंद किया गया."</string>
-    <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"स्‍थान रिपोर्टिंग को चालू किया गया."</string>
+    <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"जगह की रिपोर्ट बंद है."</string>
+    <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"जगह की रिपोर्ट चालू है."</string>
+    <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"जगह की रिपोर्ट को बंद किया गया."</string>
+    <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"जगह की रिपोर्ट को चालू किया गया."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"<xliff:g id="TIME">%s</xliff:g> के लिए अलार्म सेट किया गया."</string>
-    <string name="accessibility_quick_settings_close" msgid="3115847794692516306">"फलक बंद करें."</string>
+    <string name="accessibility_quick_settings_close" msgid="3115847794692516306">"पैनल बंद करें."</string>
     <string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"अधिक समय."</string>
     <string name="accessibility_quick_settings_less_time" msgid="2404728746293515623">"कम समय."</string>
     <string name="accessibility_quick_settings_flashlight_off" msgid="4936432000069786988">"फ़्लैशलाइट बंद है."</string>
@@ -234,41 +234,41 @@
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"कार्य मोड चालू है."</string>
     <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"कार्य मोड बंद कर दिया गया."</string>
     <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"कार्य मोड चालू किया गया."</string>
-    <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"डेटा बचतकर्ता बंद किया गया."</string>
-    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"डेटा बचतकर्ता चालू किया गया."</string>
+    <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"डेटा बचाने की सेटिंग बंद कर दी गई है."</string>
+    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"डेटा बचाने की सेटिंग चालू कर दी गई है."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"स्क्रीन की स्क्रीन की रोशनी"</string>
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"चार्ज हो रही है"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G डेटा रोक दिया गया है"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G डेटा रोक दिया गया है"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"मोबाइल डेटा रोक दिया गया है"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"डेटा रोक दिया गया है"</string>
-    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"आपने जो डेटा सीमा सेट की थी, वह पूरी हो चुकी है. अब आप मोबाइल डेटा का उपयोग नहीं कर रहे हैं.\n\nअगर आप फिर से शुरू करते हैं, तो डेटा उपयोग के लिए शुल्क लगाया जा सकता है."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"आपकी सेट की हुई डेटा सीमा खत्म हो गई है. अब आप मोबाइल डेटा का इस्तेमाल नहीं कर रहे हैं.\n\nअगर आप फिर से शुरू करते हैं, तो डेटा खर्च  के लिए शुल्क लागू किया जा सकता है."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"फिर से शुरू करें"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"कोई इंटरनेट कनेक्शन नहीं"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"वाई-फ़ाई  कनेक्‍ट किया गया"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS को खोजा जा रहा है"</string>
-    <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS द्वारा सेट किया गया स्‍थान"</string>
-    <string name="accessibility_location_active" msgid="2427290146138169014">"स्थान अनुरोध सक्रिय"</string>
+    <string name="gps_notification_found_text" msgid="4619274244146446464">"जीपीएस ने यह जगह सेट की है"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"जगह का अनुरोध किया जा रहा है"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"सभी सूचनाएं साफ़ करें."</string>
     <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404">
-      <item quantity="one">इसमें <xliff:g id="NUMBER_1">%s</xliff:g> और नोटिफ़िकेशन हैं.</item>
-      <item quantity="other">इसमें <xliff:g id="NUMBER_1">%s</xliff:g> और नोटिफ़िकेशन हैं.</item>
+      <item quantity="one">इसमें <xliff:g id="NUMBER_1">%s</xliff:g> और सूचनाएं हैं.</item>
+      <item quantity="other">इसमें <xliff:g id="NUMBER_1">%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>
-    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"स्‍क्रीन पोर्ट्रेट अभिविन्‍यास में लॉक है."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"स्क्रीन लैंडस्केप दिशा में लॉक है."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"स्‍क्रीन पोर्ट्रेट दिशा में लॉक है."</string>
     <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"स्‍क्रीन अब अपने आप घूमेगी."</string>
-    <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"स्‍क्रीन को अब भू-दृश्य अभिविन्यास में लॉक कर दिया गया है."</string>
-    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"स्‍क्रीन को अब पोर्ट्रेट अभिविन्‍यास में लॉक की दिया गया है."</string>
+    <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"स्क्रीन अभी लैंडस्केप दिशा में लॉक है."</string>
+    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"स्‍क्रीन अभी पोर्ट्रेट दिशा में लॉक है."</string>
     <string name="dessert_case" msgid="1295161776223959221">"मिठाई का डिब्बा"</string>
     <string name="start_dreams" msgid="5640361424498338327">"स्क्रीन सेवर"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ईथरनेट"</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_priority_label" msgid="483232950670692036">"सिर्फ़ प्राथमिकता"</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">"ब्लूटूथ"</string>
     <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"ब्लूटूथ (<xliff:g id="NUMBER">%d</xliff:g> डिवाइस)"</string>
@@ -282,8 +282,8 @@
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"पोर्ट्रेट"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"लैंडस्केप"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"इनपुट विधि"</string>
-    <string name="quick_settings_location_label" msgid="5011327048748762257">"स्थान"</string>
-    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"स्थान बंद"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"जगह"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"जगह की जानकारी बंद है"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"मीडिया डिवाइस"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"केवल आपातकालीन कॉल"</string>
@@ -308,15 +308,16 @@
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"रंग उलटें"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"रंग सुधार मोड"</string>
     <string name="quick_settings_more_settings" msgid="326112621462813682">"और सेटिंग"</string>
-    <string name="quick_settings_done" msgid="3402999958839153376">"पूर्ण"</string>
+    <string name="quick_settings_done" msgid="3402999958839153376">"हो गया"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"कनेक्ट है"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"कनेक्ट किया गया, बैटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> है"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"कनेक्ट हो रहा है..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"टेदरिंग"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"हॉटस्पॉट"</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>
+    <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"डेटा खर्च"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"शेष डेटा"</string>
     <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"सीमा से अधिक"</string>
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> उपयोग किया गया"</string>
@@ -329,16 +330,16 @@
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC चालू है"</string>
     <string name="recents_empty_message" msgid="808480104164008572">"हाल ही का कोई आइटम नहीं"</string>
     <string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"आपने सब कुछ साफ़ कर दिया है"</string>
-    <string name="recents_app_info_button_label" msgid="2890317189376000030">"एप्‍लिकेशन जानकारी"</string>
+    <string name="recents_app_info_button_label" msgid="2890317189376000030">"ऐप्लिकेशन की जानकारी"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"स्क्रीन पिन करना"</string>
-    <string name="recents_search_bar_label" msgid="8074997400187836677">"खोज"</string>
+    <string name="recents_search_bar_label" msgid="8074997400187836677">"सर्च"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> प्रारंभ नहीं किया जा सका."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> को सुरक्षित-मोड में अक्षम किया गया."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
-    <string name="recents_drag_hint_message" msgid="2649739267073203985">"विभाजित स्क्रीन का उपयोग करने के लिए यहां खींचें"</string>
+    <string name="recents_drag_hint_message" msgid="2649739267073203985">"स्क्रीन के दो हिस्से में बंट जाने, स्पिल्ट स्क्रीन, का इस्तेमाल करने के लिए यहां खींचें और छोडें"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"क्षैतिज रूप से विभाजित करें"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"लम्बवत रूप से विभाजित करें"</string>
-    <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"कस्‍टम रूप से विभाजित करें"</string>
+    <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"अपने मुताबिक बांटें"</string>
     <string name="recents_accessibility_split_screen_top" msgid="9056056469282256287">"ऊपर की ओर दो स्क्रीन बनाएं"</string>
     <string name="recents_accessibility_split_screen_left" msgid="8987144699630620019">"बाईं ओर दो स्क्रीन बनाएं"</string>
     <string name="recents_accessibility_split_screen_right" msgid="275069779299592867">"दाईं ओर दो स्क्रीन बनाएं"</string>
@@ -349,36 +350,36 @@
     <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"पूर्ण होने में <xliff:g id="CHARGING_TIME">%s</xliff:g> शेष"</string>
     <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"चार्ज नहीं हो रही है"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"नेटवर्क को\nमॉनीटर किया जा सकता है"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"खोजें"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"सर्च करें"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए ऊपर स्‍लाइड करें."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए बाएं स्‍लाइड करें."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"आपको अलार्म, रिमाइंडर, इवेंट और आपने जिन कॉलर के बारे में विशेष रूप से बताया है, उन्हें छोड़कर ध्‍वनियों और कंपनों से परेशान नहीं किया जाएगा. आपको अभी भी संगीत, वीडियो और गेम सहित वह सब कुछ सुनाई देगा जो आपने चलाने के लिए चुना है."</string>
+    <string name="zen_priority_introduction" msgid="7577965386868311310">"आपको अलार्म, रिमाइंडर, इवेंट और चुनिंदा कॉल करने वालों के अलावा किसी और तरह से (आवाज़ करके और थरथरा कर ) परेशान नहीं किया जाएगा. आप फिर भी संगीत, वीडियो और गेम सहित अपना चुना हुआ सब कुछ सुन सकते हैं."</string>
     <string name="zen_alarms_introduction" msgid="7034415210361973827">"आपको अलार्म छोड़कर दूसरी ध्‍वनियों और कंपनों से परेशान नहीं किया जाएगा. आपको अभी भी संगीत, वीडियो और गेम सहित वह सब कुछ सुनाई देगा जो आपने चलाने के लिए चुना है."</string>
-    <string name="zen_priority_customize_button" msgid="7948043278226955063">"कस्टमाइज़ करें"</string>
-    <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी ध्‍वनियां और कंपन अवरुद्ध हो जाते हैं. आप अभी भी फ़ोन काॅल कर सकेंगे."</string>
-    <string name="zen_silence_introduction" msgid="3137882381093271568">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी ध्वनियां और कंपन अवरुद्ध हो जाते हैं."</string>
+    <string name="zen_priority_customize_button" msgid="7948043278226955063">"अपनी पसंद के मुताबिक बनाएं"</string>
+    <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी आवाज़ और कंपन (वाइब्रेशन) रोक दिए जाते हैं. आप तब भी फ़ोन काॅल कर सकेंगे."</string>
+    <string name="zen_silence_introduction" msgid="3137882381093271568">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी आवाज़ और कंपन (वाइब्रेशन) रोक दिए जाते हैं."</string>
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"कम अत्यावश्यक सूचनाएं नीचे दी गई हैं"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"खोलने के लिए पुन: टैप करें"</string>
     <string name="keyguard_unlock" msgid="8043466894212841998">"अनलॉक करने के लिए ऊपर स्वाइप करें"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"इस डिवाइस का प्रबंधन आपका संगठन करता है"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"इस डिवाइस के प्रबंधक <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> हैं"</string>
-    <string name="phone_hint" msgid="4872890986869209950">"फ़ोन के लिए आइकन से स्वाइप करें"</string>
-    <string name="voice_hint" msgid="8939888732119726665">"वॉइस सहायक के लिए आइकन से स्वाइप करें"</string>
-    <string name="camera_hint" msgid="7939688436797157483">"कैमरे के लिए आइकन से स्वाइप करें"</string>
+    <string name="phone_hint" msgid="4872890986869209950">"फ़ोन के लिए आइकॉन से स्वाइप करें"</string>
+    <string name="voice_hint" msgid="8939888732119726665">"\'आवाज़ से डिवाइस का इस्तेमाल\' आइकॉन से स्वाइप करें"</string>
+    <string name="camera_hint" msgid="7939688436797157483">"कैमरे के लिए आइकॉन से स्वाइप करें"</string>
     <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_priority" msgid="6426766465363855505">"सिर्फ़ प्राथमिकता"</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>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"चार्ज हो रहा है (पूरा होने में <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> बाकी)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"तेज़ी से चार्ज हो रहा है (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> में हो जाएगा)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"धीरे चार्ज हो रहा है (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> में पूरा हो जाएगा)"</string>
-    <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"उपयोगकर्ता स्विच करें"</string>
-    <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"उपयोगकर्ता स्विच करें, वर्तमान उपयोगकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
-    <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"वर्तमान उपयोगकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
+    <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"उपयोगकर्ता बदलें"</string>
+    <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"उपयोगकर्ता बदलें, मौजूदा उपयोगकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
+    <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"मौजूदा उपयोगकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <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>
@@ -390,27 +391,27 @@
     <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"निकालें"</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_wipe" msgid="5065558566939858884">"फिर से शुरू करें"</string>
     <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"हां, जारी रखें"</string>
     <string name="guest_notification_title" msgid="1585278533840603063">"अतिथि उपयोगकर्ता"</string>
-    <string name="guest_notification_text" msgid="335747957734796689">"ऐप्‍स और डेटा हटाने के लिए, अतिथि उपयोगकर्ता को निकालें"</string>
+    <string name="guest_notification_text" msgid="335747957734796689">"ऐप और डेटा हटाने के लिए, अतिथि उपयोगकर्ता को निकालें"</string>
     <string name="guest_notification_remove_action" msgid="8820670703892101990">"अतिथि को निकालें"</string>
     <string name="user_logout_notification_title" msgid="1453960926437240727">"उपयोगकर्ता को प्रस्थान करवाना"</string>
-    <string name="user_logout_notification_text" msgid="3350262809611876284">"वर्तमान उपयोगकर्ता से प्रस्थान करें"</string>
+    <string name="user_logout_notification_text" msgid="3350262809611876284">"मौजूदा उपयोगकर्ता से प्रस्थान करें"</string>
     <string name="user_logout_notification_action" msgid="1195428991423425062">"उपयोगकर्ता को प्रस्थान करवाएं"</string>
     <string name="user_add_user_title" msgid="4553596395824132638">"नया उपयोगकर्ता जोड़ें?"</string>
-    <string name="user_add_user_message_short" msgid="2161624834066214559">"जब आप कोई नया उपयोगकर्ता जोड़ते हैं तो उस व्यक्ति को अपना स्थान सेट करना होता है.\n\nकोई भी उपयोगकर्ता अन्य सभी उपयोगकर्ताओं के लिए ऐप्स अपडेट कर सकता है."</string>
+    <string name="user_add_user_message_short" msgid="2161624834066214559">"जब आप कोई नया उपयोगकर्ता जोड़ते हैं तो उस व्यक्ति को अपनी जगह सेट करनी होती है.\n\nकोई भी उपयोगकर्ता बाकी सभी उपयोगकर्ताओं के लिए ऐप अपडेट कर सकता है."</string>
     <string name="user_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="237918726750955859">"बैटरी सेवर चालू है"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"निष्‍पादन और पृष्ठभूमि डेटा को कम करता है"</string>
     <string name="battery_saver_notification_action_text" msgid="109158658238110382">"बैटरी बचतकर्ता को बंद करें"</string>
-    <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> आपके स्क्रीन पर प्रदर्शित प्रत्येक सामग्री को कैप्चर करना प्रारंभ कर देगी."</string>
+    <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="media_projection_action_text" msgid="8470872969457985954">"अब प्रारंभ करें"</string>
-    <string name="empty_shade_text" msgid="708135716272867002">"कोई नोटिफ़िकेशन नहीं"</string>
+    <string name="clear_all_notifications_text" msgid="814192889771462828">"सभी साफ़ करें"</string>
+    <string name="media_projection_action_text" msgid="8470872969457985954">"अब शुरू करें"</string>
+    <string name="empty_shade_text" msgid="708135716272867002">"कोई सूचना नहीं मिली"</string>
     <string name="profile_owned_footer" msgid="8021888108553696069">"प्रोफ़ाइल को मॉनीटर किया जा सकता है"</string>
     <string name="vpn_footer" msgid="2388611096129106812">"नेटवर्क को मॉनीटर किया जा सकता है"</string>
     <string name="branded_vpn_footer" msgid="2168111859226496230">"नेटवर्क को मॉनिटर किया जा सकता है"</string>
@@ -438,11 +439,11 @@
     <string name="disable_vpn" msgid="4435534311510272506">"VPN अक्षम करें"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"VPN डिस्‍कनेक्‍ट करें"</string>
     <string name="monitoring_button_view_policies" msgid="100913612638514424">"नीतियां देखें"</string>
-    <string name="monitoring_description_named_management" msgid="5281789135578986303">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> आपके डिवाइस का प्रबंधन करता है.\n\nआपका व्यवस्थापक सेटिंग, कॉर्पोरेट एक्सेस, ऐप्लिकेशन, आपके डिवाइस से संबद्ध डेटा और आपके डिवाइस की स्थान की जानकारी की निगरानी कर सकता है और उन्हें प्रबंधित कर सकता है.\n\nअधिक जानकारी के लिए, अपने व्यवस्थापक से संपर्क करें."</string>
-    <string name="monitoring_description_management" msgid="4573721970278370790">"आपका संगठन आपके डिवाइस का प्रबंधन करता है.\n\nआपका व्यवस्थापक सेटिंग, कॉर्पोरेट एक्सेस, ऐप्लिकेशन, आपके डिवाइस से संबद्ध डेटा और आपके डिवाइस की स्थान की जानकारी की निगरानी कर सकता है और उन्हें प्रबंधित कर सकता है.\n\nअधिक जानकारी के लिए, अपने व्यवस्थापक से संपर्क करें."</string>
-    <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"आपके संगठन ने इस डिवाइस पर एक प्रमाणपत्र प्राधिकरण इंस्टॉल किया है. आपके सुरक्षित नेटवर्क की निगरानी या उसमें बदलाव किया जा सकता है."</string>
-    <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"आपके संगठन ने आपकी कार्य प्रोफ़ाइल में एक प्रमाणपत्र प्राधिकरण इंस्टॉल किया है. आपके सुरक्षित नेटवर्क ट्रैफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string>
-    <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"इस डिवाइस पर एक प्रमाणपत्र प्राधिकरण इंस्टॉल किया गया है. आपके सुरक्षित नेटवर्क ट्रैफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string>
+    <string name="monitoring_description_named_management" msgid="5281789135578986303">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> आपके डिवाइस का प्रबंधन करता है.\n\nआपका एडमिन सेटिंग, कॉर्पोरेट पहुंच, ऐप्लिकेशन, आपके डिवाइस से जुड़े डेटा और आपके डिवाइस की जगह की जानकारी की निगरानी कर सकता है और उन्हें प्रबंधित कर सकता है.\n\n और जानकारी के लिए, अपने एडमिन से संपर्क करें."</string>
+    <string name="monitoring_description_management" msgid="4573721970278370790">"आपका संगठन आपके डिवाइस का प्रबंधन करता है.\n\nआपका एडमिन सेटिंग, कॉर्पोरेट पहुंच, ऐप्लिकेशन, आपके डिवाइस से जुड़े डेटा और आपके डिवाइस की जगह की जानकारी की निगरानी कर सकता है और उन्हें प्रबंधित कर सकता है.\n\nऔर जानकारी के लिए, अपने एडमिन से संपर्क करें."</string>
+    <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"आपके संगठन ने इस डिवाइस पर एक प्रमाणपत्र अनुमति इंस्टॉल की है. आपके सुरक्षित नेटवर्क पर ट्रेफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string>
+    <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"आपके संगठन ने आपकी कार्य प्रोफ़ाइल में एक प्रमाणपत्र अनुमति इंस्टॉल की है. आपके सुरक्षित नेटवर्क ट्रैफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string>
+    <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"इस डिवाइस पर एक प्रमाणपत्र अनुमति इंस्टॉल की है. आपके सुरक्षित नेटवर्क ट्रैफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string>
     <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"आपके व्यवस्थापक ने नेटवर्क लॉगिंग चालू किया है, जो आपके डिवाइस पर ट्रैफ़िक की निगरानी करता है."</string>
     <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"आप <xliff:g id="VPN_APP">%1$s</xliff:g> से कनेक्‍ट हैं, जो ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकते हैं."</string>
     <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"आप <xliff:g id="VPN_APP_0">%1$s</xliff:g> और <xliff:g id="VPN_APP_1">%2$s</xliff:g> से कनेक्ट हैं, जो ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकते हैं."</string>
@@ -450,36 +451,38 @@
     <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"आपकी व्यक्तिगत प्रोफ़ाइल <xliff:g id="VPN_APP">%1$s</xliff:g> से कनेक्ट है, जो ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकता है."</string>
     <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"<xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> आपका डिवाइस प्रबंधित करता है."</string>
     <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> आपका डिवाइस प्रबंधित करने के लिए <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> का उपयोग करता है."</string>
-    <string name="monitoring_description_do_body" msgid="3639594537660975895">"आपका व्यवस्थापक आपके डिवाइस से जुड़ी सेटिंग, कॉर्पोरेट एक्सेस, ऐप्लिकेशन, डेटा और आपके डिवाइस की स्थान जानकारी की निगरानी और उसका प्रबंधन कर सकता है."</string>
+    <string name="monitoring_description_do_body" msgid="3639594537660975895">"आपका एडमिन आपके डिवाइस से जुड़ी सेटिंग, कॉर्पोरेट पहुंच, ऐप्लिकेशन, डेटा और आपके डिवाइस की जगह की जानकारी की निगरानी और उसका प्रबंधन कर सकता है."</string>
     <string name="monitoring_description_do_learn_more_separator" msgid="3785251953067436862">" "</string>
-    <string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"अधिक जानें"</string>
+    <string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"ज़्यादा जानें"</string>
     <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"आप <xliff:g id="VPN_APP">%1$s</xliff:g> से कनेक्‍ट हैं, जो ईमेल, ऐप्लिकेशन और वेबसाइट सहित आपकी नेटवर्क गतिविधि को मॉनिटर कर सकता है."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"VPN सेटिंग खोलें"</string>
     <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
-    <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"विश्वसनीय क्रेडेंशियल खोलें"</string>
-    <string name="monitoring_description_network_logging" msgid="7223505523384076027">"आपके व्‍यवस्‍थापक ने नेटवर्क लॉग करना चालू कर दिया है, जो आपके डिवाइस पर ट्रैफ़िक की निगरानी करता है.\n\nअधिक जानकारी के लिए अपने व्‍यवस्‍थापक से संपर्क करें."</string>
+    <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"भरोसेमंद क्रेडेंशियल खोलें"</string>
+    <string name="monitoring_description_network_logging" msgid="7223505523384076027">"आपके एडमिन ने नेटवर्क लॉग करना चालू कर दिया है, जो आपके डिवाइस पर ट्रैफ़िक की निगरानी करता है.\n\nअधिक जानकारी के लिए अपने एडमिन से संपर्क करें."</string>
     <string name="monitoring_description_vpn" msgid="4445150119515393526">"आपने किसी ऐप को VPN कनेक्‍शन सेट करने की अनुमति दी है.\n\nयह ऐप ईमेल, ऐप्‍स और सुरक्षित वेबसाइटों सहित आपके डिवाइस और नेटवर्क की गतिविधि की निगरानी कर सकता है."</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> आपकी कार्य प्रोफ़ाइल को प्रबंधित करता है.\n\nआपका व्‍यवस्‍थापक ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकता है.\n\nअधिक जानकारी के लिए अपने व्‍यवस्‍थापक से संपर्क करें.\n\nआप ऐसे VPN से भी कनेक्‍ट हैं, जो आपकी नेटवर्क गतिविधि की निगरानी कर सकता है."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> आपकी वर्क प्रोफ़ाइल को प्रबंधित करता है.\n\n आपका एडमिन ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकता है.\n\nऔर जानकारी के लिए अपने एडमिन से संपर्क करें.\n\nआप ऐसे VPN से भी कनेक्‍ट हैं, जो आपकी नेटवर्क गतिविधि की निगरानी कर सकता है."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
     <string name="monitoring_description_app" msgid="1828472472674709532">"आप <xliff:g id="APPLICATION">%1$s</xliff:g> से कनेक्ट हैं, जो ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकता है."</string>
     <string name="monitoring_description_app_personal" msgid="484599052118316268">"आप <xliff:g id="APPLICATION">%1$s</xliff:g> से कनेक्‍ट हैं, जो ईमेल, ऐप्‍स और वेबसाइटों सहित आपकी व्‍यक्‍तिगत नेटवर्क गतिविधि की निगरानी कर सकता है."</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"आप <xliff:g id="APPLICATION">%1$s</xliff:g> से कनेक्‍ट हैं, जो ईमेल, ऐप्लिकेशन और वेबसाइट सहित आपकी व्‍यक्‍तिगत नेटवर्क गतिविधि को मॉनिटर कर सकता है."</string>
-    <string name="monitoring_description_app_work" msgid="4612997849787922906">"आपकी कार्य प्रोफ़ाइल का प्रबंधन <xliff:g id="ORGANIZATION">%1$s</xliff:g> करता है. प्रोफ़ाइल <xliff:g id="APPLICATION">%2$s</xliff:g> से कनेक्ट है, जो ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकता है.\n\nअधिक जानकारी के लिए, अपने व्यवस्थापक से संपर्क करें."</string>
+    <string name="monitoring_description_app_work" msgid="4612997849787922906">"आपकी वर्क प्रोफ़ाइल का प्रबंधन <xliff:g id="ORGANIZATION">%1$s</xliff:g> करता है. प्रोफ़ाइल <xliff:g id="APPLICATION">%2$s</xliff:g> से कनेक्ट है, जो ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकता है.\n\nऔर जानकारी के लिए, अपने एडमिन से संपर्क करें."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"आपकी कार्य प्रोफ़ाइल का प्रबंधन <xliff:g id="ORGANIZATION">%1$s</xliff:g> करता है. प्रोफ़ाइल <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> से कनेक्ट है, जो ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकता है.\n\nआप <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> से भी कनेक्ट हैं, जो आपकी व्यक्तिगत नेटवर्क गतिविधि की निगरानी कर सकता है."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> के लिए अनलॉक किया गया"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> चल रहा है"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"जब तक कि आप मैन्‍युअल रूप से अनलॉक नहीं करते तब तक डिवाइस लॉक रहेगा"</string>
-    <string name="hidden_notifications_title" msgid="7139628534207443290">"सूचनाएं अधिक तेज़ी से प्राप्त करें"</string>
+    <string name="hidden_notifications_title" msgid="7139628534207443290">"सूचनाएं ज़्यादा तेज़ी से पाएं"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"आपके द्वारा उन्हें अनलॉक किए जाने से पहले देखें"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"रहने दें"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"सेट करें"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="volume_zen_end_now" msgid="6930243045593601084">"अभी बंद करें"</string>
-    <string name="accessibility_volume_expand" msgid="5946812790999244205">"विस्तृत करें"</string>
-    <string name="accessibility_volume_collapse" msgid="3609549593031810875">"संक्षिप्त करें"</string>
+    <string name="accessibility_volume_expand" msgid="5946812790999244205">"विस्तार करें"</string>
+    <string name="accessibility_volume_collapse" msgid="3609549593031810875">"छोटा करें"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"स्‍क्रीन पिन कर दी गई है"</string>
-    <string name="screen_pinning_description" msgid="8909878447196419623">"इससे वह तब तक दृश्य में बना रहता है जब तक कि आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, वापस जाएं और अवलोकन को स्पर्श करके रखें."</string>
-    <string name="screen_pinning_description_accessible" msgid="426190689254018656">"इससे वह तब तक दृश्य में बना रहता है जब तक कि आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, अवलोकन को स्पर्श करके रखें."</string>
-    <string name="screen_pinning_positive" msgid="3783985798366751226">"समझ लिया"</string>
+    <string name="screen_pinning_description" msgid="8909878447196419623">"इससे वह तब तक दिखता रहता है जब तक कि आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, \'वापस जाएं\' और \'खास जानकारी\' को दबाकर रखें."</string>
+    <string name="screen_pinning_description_accessible" msgid="426190689254018656">"इससे वह तब तक दिखता रहता है जब तक कि आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, \'खास जानकारी\' को दबाकर रखें."</string>
+    <string name="screen_pinning_positive" msgid="3783985798366751226">"ठीक है"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"नहीं, रहने दें"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> को छिपाएं?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"जब आप उसे अगली बार सेटिंग में चालू करेंगे तो वह फिर से दिखाई देगी."</string>
@@ -487,28 +490,28 @@
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"आप अपनी कार्य प्रोफ़ाइल का उपयोग कर रहे हैं"</string>
     <string name="stream_voice_call" msgid="4410002696470423714">"कॉल करें"</string>
     <string name="stream_system" msgid="7493299064422163147">"सिस्‍टम"</string>
-    <string name="stream_ring" msgid="8213049469184048338">"रिंग करें"</string>
+    <string name="stream_ring" msgid="8213049469184048338">"घंटी बजाएं"</string>
     <string name="stream_music" msgid="9086982948697544342">"मीडिया"</string>
     <string name="stream_alarm" msgid="5209444229227197703">"अलार्म"</string>
-    <string name="stream_notification" msgid="2563720670905665031">"नोटिफ़िकेशन"</string>
+    <string name="stream_notification" msgid="2563720670905665031">"सूचना"</string>
     <string name="stream_bluetooth_sco" msgid="2055645746402746292">"ब्लूटूथ"</string>
     <string name="stream_dtmf" msgid="2447177903892477915">"दोहरी बहु टोन आवृत्ति"</string>
-    <string name="stream_accessibility" msgid="301136219144385106">"एक्सेस-योग्यता"</string>
+    <string name="stream_accessibility" msgid="301136219144385106">"सुलभता"</string>
     <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. अनम्यूट करने के लिए टैप करें."</string>
-    <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. कंपन पर सेट करने के लिए टैप करें. एक्सेस-योग्यता सेवाएं म्यूट हो सकती हैं."</string>
-    <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. म्यूट करने के लिए टैप करें. एक्सेस-योग्यता सेवाएं म्यूट हो सकती हैं."</string>
-    <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. कंपन पर सेट करने के लिए टैप करें."</string>
+    <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. कंपन पर सेट करने के लिए टैप करें. सुलभता सेवाएं म्यूट हो सकती हैं."</string>
+    <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. म्यूट करने के लिए टैप करें. सुलभता सेवाएं म्यूट हो सकती हैं."</string>
+    <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. कंपन (वाइब्रेशन) पर सेट करने के लिए छूएं."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. म्यूट करने के लिए टैप करें."</string>
     <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s वॉल्यूम नियंत्रण दिखाए गए हैं. खारिज करने के लिए स्वाइप करें."</string>
     <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"वॉल्यूम नियंत्रण छिपे हुए हैं"</string>
-    <string name="system_ui_tuner" msgid="708224127392452018">"सिस्टम UI ट्यूनर"</string>
+    <string name="system_ui_tuner" msgid="708224127392452018">"सिस्टम यूज़र इंटरफ़ेस (यूआई) ट्यूनर"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"एम्बेड किया गया बैटरी प्रतिशत दिखाएं"</string>
-    <string name="show_battery_percentage_summary" msgid="3215025775576786037">"जब चार्ज नहीं किया जा रहा हो तब स्थिति बार आइकन में बैटरी स्तर का प्रतिशत दिखाएं"</string>
+    <string name="show_battery_percentage_summary" msgid="3215025775576786037">"जब चार्ज नहीं किया जा रहा हो तब स्टेटस बार आइकॉन में बैटरी लेवल का प्रतिशत दिखाएं"</string>
     <string name="quick_settings" msgid="10042998191725428">"तेज़ सेटिंग"</string>
-    <string name="status_bar" msgid="4877645476959324760">"स्थिति बार"</string>
-    <string name="overview" msgid="4018602013895926956">"अवलोकन"</string>
-    <string name="demo_mode" msgid="2532177350215638026">"सिस्टम UI डेमो मोड"</string>
-    <string name="enable_demo_mode" msgid="4844205668718636518">"डेमो मोड सक्षम करें"</string>
+    <string name="status_bar" msgid="4877645476959324760">"स्टेटस बार"</string>
+    <string name="overview" msgid="4018602013895926956">"खास जानकारी"</string>
+    <string name="demo_mode" msgid="2532177350215638026">"सिस्टम यूज़र इंटरफ़ेस (यूआई) डेमो मोड"</string>
+    <string name="enable_demo_mode" msgid="4844205668718636518">"डेमो मोड चालू करें"</string>
     <string name="show_demo_mode" msgid="2018336697782464029">"डेमो मोड दिखाएं"</string>
     <string name="status_bar_ethernet" msgid="5044290963549500128">"ईथरनेट"</string>
     <string name="status_bar_alarm" msgid="8536256753575881818">"अलार्म"</string>
@@ -524,58 +527,63 @@
     <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">"सिस्टम UI ट्यूनर आपको 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">"बधाई हो! सिस्टम UI ट्यूनर को सेटिंग में जोड़ दिया गया है"</string>
+    <string name="got_it" msgid="2239653834387972602">"ठीक है"</string>
+    <string name="tuner_toast" msgid="603429811084428439">"बधाई हो! सिस्टम यूज़र इंटरफ़ेस (यूआई) ट्यूनर को सेटिंग में जोड़ दिया गया है"</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"सेटिंग से निकालें"</string>
-    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"सेटिंग से सिस्टम UI ट्यूनर निकालें और इसकी सभी सुविधाओं का उपयोग रोक दें?"</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>
+    <string name="clock_seconds_desc" msgid="6282693067130470675">"स्टेटस बार में सेकंड में समय दिखाएं. इससे बैटरी लाइफ़ पर असर पड़ सकता है."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"त्वरित सेटिंग को पुन: व्यवस्थित करें"</string>
     <string name="show_brightness" msgid="6613930842805942519">"त्वरित सेटिंग में स्क्रीन की रोशनी दिखाएं"</string>
     <string name="experimental" msgid="6198182315536726162">"प्रयोगात्मक"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"ब्लूटूथ चालू करें?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"अपने कीबोर्ड को अपने टैबलेट से कनेक्ट करने के लिए, आपको पहले ब्लूटूथ चालू करना होगा."</string>
     <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"चालू करें"</string>
-    <string name="show_silently" msgid="6841966539811264192">"नोटिफ़िकेशन मौन रूप से दिखाएं"</string>
-    <string name="block" msgid="2734508760962682611">"सभी नोटिफ़िकेशन अवरुद्ध करें"</string>
+    <string name="show_silently" msgid="6841966539811264192">"सूचना बिना आवाज़ के दिखाएं"</string>
+    <string name="block" msgid="2734508760962682611">"सभी सूचनाएं रोकें"</string>
     <string name="do_not_silence" msgid="6878060322594892441">"मौन ना करें"</string>
     <string name="do_not_silence_block" msgid="4070647971382232311">"मौन या अवरुद्ध ना करें"</string>
-    <string name="tuner_full_importance_settings" msgid="3207312268609236827">"पावर नोटिफ़िकेशन नियंत्रण"</string>
+    <string name="tuner_full_importance_settings" msgid="3207312268609236827">"पावर सूचना नियंत्रण"</string>
     <string name="tuner_full_importance_settings_on" msgid="7545060756610299966">"चालू"</string>
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"बंद"</string>
-    <string name="power_notification_controls_description" msgid="4372459941671353358">"पावर नोटिफ़िकेशन नियंत्रण के द्वारा, आप किसी ऐप्लिकेशन के नोटिफ़िकेशन के लिए 0 से 5 तक महत्व का लेवल सेट कर सकते हैं. \n\n"<b>"लेवल 5"</b>" \n- नोटिफ़िकेशन सूची के शीर्ष पर दिखाएं \n- पूर्ण स्क्रीन बाधा की अनुमति दें \n- हमेशा तांक-झांक करें \n\n"<b>"लेवल 4"</b>" \n- पूर्ण स्क्रीन बाधा को रोकें \n- हमेशा तांक-झांक करें \n\n"<b>"लेवल 3"</b>" \n- पूर्ण स्क्रीन बाधा को रोकें \n- कभी भी तांक-झांक ना करें \n\n"<b>"लेवल 2"</b>" \n- पूर्ण स्क्रीन बाधा को रोकें \n- कभी भी तांक-झांक ना करें \n- कभी भी ध्वनि या कंपन ना करें \n\n"<b>"लेवल 1"</b>" \n- पूर्ण स्क्रीन बाधा को रोकें \n- कभी भी तांक-झांक ना करें \n- कभी भी ध्वनि या कंपन ना करें \n- लॉक स्क्रीन और स्थिति बार से छिपाएं \n- नोटिफ़िकेशन सूची के नीचे दिखाएं \n\n"<b>"लेवल 0"</b>" \n- ऐप्लिकेशन के सभी नोटिफ़िकेशन अवरुद्ध कर दें"</string>
-    <string name="notification_header_default_channel" msgid="7506845022070889909">"नोटिफ़िकेशन"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"अब आपको ये नोटिफ़िकेशन नहीं मिलेंगे."</string>
-    <string name="notification_num_channels" msgid="2048144408999179471">"नोटिफ़िकेशन की <xliff:g id="NUMBER">%d</xliff:g> श्रेणियां"</string>
-    <string name="notification_default_channel_desc" msgid="2506053815870808359">"इस ऐप्लिकेशन में नोटिफ़िकेशन श्रेणियां नहीं हैं"</string>
+    <string name="power_notification_controls_description" msgid="4372459941671353358">"पावर सूचना नियंत्रण के ज़रिये, आप किसी ऐप की सूचना को उसकी अहमियत के हिसाब से 0 से 5 के लेवल पर सेट कर सकते हैं.\n\n"<b>"लेवल 5"</b>" \n- सूचना सूची में सबसे ऊपर दिखाएं \n- पूरे स्क्रीन को ढंकने की अनुमति दें \n- लगातार देखते रहें \n\n"<b>" लेवल 4"</b>" \n- पूरे स्क्रीन को ढंकें \n- लगातार देखते रहें \n\n"<b>"लेवल 3"</b>" \n- पूरे स्क्रीन को ढंकने से रोकें \n-कभी भी न देखें \n\n"<b>"लेवल 2"</b>" \n- पूरे स्क्रीन को ढंकने से रोकें \n- कभी भी देखें \n- कभी भी आवाज़ या कंपन (वाइब्रेशन) न करें \n\n"<b>"लेवल 1"</b>" \n- पूरे स्क्रीन को ढंकने से रोकें \n- कभी भी न देखें \n- कभी भी आवाज़ या कंपन (वाइब्रेशन) न करें \n- लॉक स्क्रीन और स्टेटस बार से छिपाएं \n- सूचना सूची के नीचे दिखाएं \n\n"<b>"लेवल 0"</b>" \n- ऐप्लिकेशन की सभी सूचनाएं रोक दें"</string>
+    <string name="notification_header_default_channel" msgid="7506845022070889909">"सूचना"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"अब आपको ये सूचनाएं नहीं मिलेंगी"</string>
+    <string name="notification_num_channels" msgid="2048144408999179471">"सूचना की <xliff:g id="NUMBER">%d</xliff:g> श्रेणियां"</string>
+    <string name="notification_default_channel_desc" msgid="2506053815870808359">"इस ऐप्लिकेशन में सूचना श्रेणियां नहीं हैं"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"इस ऐप की सूचनाएं बंद नहीं की जा सकती"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
-      <item quantity="one">इस ऐप्लिकेशन की <xliff:g id="NUMBER_1">%d</xliff:g> नोटिफ़िकेशन श्रेणियों में से 1 श्रेणी</item>
-      <item quantity="other">इस ऐप्लिकेशन की <xliff:g id="NUMBER_1">%d</xliff:g> नोटिफ़िकेशन श्रेणियों में से 1 श्रेणी</item>
+      <item quantity="one">इस ऐप की <xliff:g id="NUMBER_1">%d</xliff:g> सूचना श्रेणियों में से 1 श्रेणी</item>
+      <item quantity="other">इस ऐप की <xliff:g id="NUMBER_1">%d</xliff:g> सूचना श्रेणियों में से 1 श्रेणी</item>
     </plurals>
     <string name="notification_channels_list_desc_2" msgid="6214732715833946441">"<xliff:g id="CHANNEL_NAME_1">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2">%2$s</xliff:g>"</string>
     <plurals name="notification_channels_list_desc_2_and_others" formatted="false" msgid="2747813553355336157">
       <item quantity="one"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> और <xliff:g id="NUMBER_5">%3$d</xliff:g> अन्य</item>
       <item quantity="other"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> और <xliff:g id="NUMBER_5">%3$d</xliff:g> अन्य</item>
     </plurals>
-    <string name="notification_channel_controls_opened_accessibility" msgid="6553950422055908113">"<xliff:g id="APP_NAME">%1$s</xliff:g> के लिए नोटिफ़िकेशन नियंत्रण चालू हैं"</string>
-    <string name="notification_channel_controls_closed_accessibility" msgid="7521619812603693144">"<xliff:g id="APP_NAME">%1$s</xliff:g> के लिए नोटिफ़िकेशन नियंत्रण बंद हैं"</string>
-    <string name="notification_channel_switch_accessibility" msgid="3420796005601900717">"इस चैनल से नोटिफ़िकेशन की अनुमति दें"</string>
+    <string name="notification_channel_controls_opened_accessibility" msgid="6553950422055908113">"<xliff:g id="APP_NAME">%1$s</xliff:g> के लिए सूचना नियंत्रण चालू हैं"</string>
+    <string name="notification_channel_controls_closed_accessibility" msgid="7521619812603693144">"<xliff:g id="APP_NAME">%1$s</xliff:g> के लिए सूचना नियंत्रण बंद हैं"</string>
+    <string name="notification_channel_switch_accessibility" msgid="3420796005601900717">"इस चैनल से सूचना की पाने की मंज़ूरी दें"</string>
     <string name="notification_all_categories" msgid="5407190218055113282">"सभी श्रेणियां"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"और सेटिंग"</string>
-    <string name="notification_app_settings" msgid="3743278649182392015">"कस्टमाइज़ करें: <xliff:g id="SUB_CATEGORY">%1$s</xliff:g>"</string>
+    <string name="notification_app_settings" msgid="3743278649182392015">"अपनी पसंद के मुताबिक बनाएं: <xliff:g id="SUB_CATEGORY">%1$s</xliff:g>"</string>
     <string name="notification_done" msgid="5279426047273930175">"हो गया"</string>
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
-    <string name="notification_menu_gear_description" msgid="2204480013726775108">"नोटिफ़िकेशन नियंत्रण"</string>
-    <string name="notification_menu_snooze_description" msgid="3653669438131034525">"नोटिफ़िकेशन की याद दिलाने के विकल्प"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 मिनट"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 मिनट"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 घंटा"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 घंटे"</string>
+    <string name="notification_menu_gear_description" msgid="2204480013726775108">"सूचना नियंत्रण"</string>
+    <string name="notification_menu_snooze_description" msgid="3653669438131034525">"सूचना को स्नूज़ (थोड़ी देर के लिए चुप करना) करने के विकल्प"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"पहले जैसा करें"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> के लिए याद दिलाया गया"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d घंटे</item>
+      <item quantity="other">%d घंटे</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d मिनट</item>
+      <item quantity="other">%d मिनट</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"बैटरी उपयोग"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज किए जाने के दौरान बैटरी सेवर उपलब्ध नहीं है"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"बैटरी सेवर"</string>
@@ -607,18 +615,18 @@
     <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
     <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"सिस्टम"</string>
-    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"होम"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"होम पेज"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"हाल ही के"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"वापस जाएं"</string>
-    <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"नोटिफ़िकेशन"</string>
+    <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="2334164096341310324">"इनपुट पद्धति‍ बदलें"</string>
+    <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"इनपुट का तरीका बदलें"</string>
     <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"ऐप्लिकेशन"</string>
     <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"सहायक"</string>
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ब्राउज़र"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"संपर्क"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ईमेल"</string>
-    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS करें"</string>
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"मैसेज (एसएमएस) करें"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"संगीत"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"कैलेंडर"</string>
@@ -628,18 +636,18 @@
     <string name="volume_up_silent" msgid="7141255269783588286">"वॉल्यूम बढ़ाएं पर परेशान न करें से बाहर निकलें"</string>
     <string name="battery" msgid="7498329822413202973">"बैटरी"</string>
     <string name="clock" msgid="7416090374234785905">"घड़ी"</string>
-    <string name="headset" msgid="4534219457597457353">"हैडसेट"</string>
+    <string name="headset" msgid="4534219457597457353">"हेडसेट"</string>
     <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"हेडफ़ोन कनेक्‍ट किए गए"</string>
-    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"हैडसेट कनेक्‍ट किया गया"</string>
-    <string name="data_saver" msgid="5037565123367048522">"डेटा बचतकर्ता"</string>
-    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"डेटा बचतकर्ता चालू है"</string>
-    <string name="accessibility_data_saver_off" msgid="8841582529453005337">"डेटा बचतकर्ता बंद है"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"हेडसेट कनेक्‍ट किया गया"</string>
+    <string name="data_saver" msgid="5037565123367048522">"डेटा बचाने की सेटिंग"</string>
+    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"डेटा बचाने की सेटिंग चालू है"</string>
+    <string name="accessibility_data_saver_off" msgid="8841582529453005337">"डेटा बचाने की सेटिंग बंद है"</string>
     <string name="switch_bar_on" msgid="1142437840752794229">"चालू"</string>
     <string name="switch_bar_off" msgid="8803270596930432874">"बंद"</string>
     <string name="nav_bar" msgid="1993221402773877607">"नेविगेशन बार"</string>
     <string name="nav_bar_layout" msgid="3664072994198772020">"लेआउट"</string>
-    <string name="left_nav_bar_button_type" msgid="8555981238887546528">"अतिरिक्त बायां बटन प्रकार"</string>
-    <string name="right_nav_bar_button_type" msgid="2481056627065649656">"अतिरिक्त दायां बटन प्रकार"</string>
+    <string name="left_nav_bar_button_type" msgid="8555981238887546528">"कुछ और बाएं बटन के प्रकार"</string>
+    <string name="right_nav_bar_button_type" msgid="2481056627065649656">"कुछ और दाएं बटन के प्रकार"</string>
     <string name="nav_bar_default" msgid="8587114043070993007">"(डिफ़ॉल्ट)"</string>
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"क्लिपबोर्ड"</item>
@@ -654,28 +662,28 @@
     <item msgid="586019486955594690">"दाएं झुका हुआ"</item>
   </string-array>
     <string name="menu_ime" msgid="4998010205321292416">"कीबोर्ड स्विचर"</string>
-    <string name="save" msgid="2311877285724540644">"सहेजें"</string>
+    <string name="save" msgid="2311877285724540644">"सेव करें"</string>
     <string name="reset" msgid="2448168080964209908">"रीसेट करें"</string>
     <string name="adjust_button_width" msgid="6138616087197632947">"बटन की चौड़ाई समायोजित करें"</string>
     <string name="clipboard" msgid="1313879395099896312">"क्लिपबोर्ड"</string>
-    <string name="accessibility_key" msgid="5701989859305675896">"कस्‍टम मार्गदर्शक बटन"</string>
+    <string name="accessibility_key" msgid="5701989859305675896">"आपके मुताबिक नेविगेट करने के लिए बटन"</string>
     <string name="left_keycode" msgid="2010948862498918135">"बायां कुंजी कोड"</string>
     <string name="right_keycode" msgid="708447961000848163">"दायां कुंजी कोड"</string>
-    <string name="left_icon" msgid="3096287125959387541">"बायां आइकन"</string>
-    <string name="right_icon" msgid="3952104823293824311">"दायां आइकन"</string>
-    <string name="drag_to_add_tiles" msgid="7058945779098711293">"टाइलों को जोड़ने के लिए खींचें"</string>
-    <string name="drag_to_remove_tiles" msgid="3361212377437088062">"निकालने के लिए यहां खींचें"</string>
-    <string name="qs_edit" msgid="2232596095725105230">"संपादित करें"</string>
+    <string name="left_icon" msgid="3096287125959387541">"बायां आइकॉन"</string>
+    <string name="right_icon" msgid="3952104823293824311">"दायां आइकॉन"</string>
+    <string name="drag_to_add_tiles" msgid="7058945779098711293">"टाइलों को जोड़ने के लिए खींचें और छोड़ें"</string>
+    <string name="drag_to_remove_tiles" msgid="3361212377437088062">"हटाने के लिए यहां खींचें और छोड़ें"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"बदलाव करें"</string>
     <string name="tuner_time" msgid="6572217313285536011">"समय"</string>
   <string-array name="clock_options">
     <item msgid="5965318737560463480">"घंटे, मिनट और सेकंड दिखाएं"</item>
     <item msgid="1427801730816895300">"घंटे और मिनट दिखाएं (डिफ़ॉल्ट)"</item>
-    <item msgid="3830170141562534721">"यह आइकन ना दिखाएं"</item>
+    <item msgid="3830170141562534721">"इस आइकॉन को ना दिखाएं"</item>
   </string-array>
   <string-array name="battery_options">
     <item msgid="3160236755818672034">"हमेशा प्रतिशत दिखाएं"</item>
     <item msgid="2139628951880142927">"चार्ज होते समय प्रतिशत दिखाएं (डिफ़ॉल्ट)"</item>
-    <item msgid="3327323682209964956">"यह आइकन ना दिखाएं"</item>
+    <item msgid="3327323682209964956">"इस आइकॉन को ना दिखाएं"</item>
   </string-array>
     <string name="other" msgid="4060683095962566764">"अन्य"</string>
     <string name="accessibility_divider" msgid="5903423481953635044">"विभाजित स्क्रीन विभाजक"</string>
@@ -689,16 +697,16 @@
     <string name="accessibility_action_divider_top_50" msgid="6385859741925078668">"ऊपर की स्क्रीन को 50% बनाएं"</string>
     <string name="accessibility_action_divider_top_30" msgid="6201455163864841205">"ऊपर की स्क्रीन को 30% बनाएं"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="301433196679548001">"नीचे की स्क्रीन को पूर्ण स्क्रीन बनाएं"</string>
-    <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. संपादित करने के लिए डबल टैप करें."</string>
-    <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. जोड़ने के लिए डबल टैप करें."</string>
-    <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>. चुनने के लिए डबल टैप करें."</string>
+    <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. में बदलाव करने के लिए दो बार छूएं."</string>
+    <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. जोड़ने के लिए दो बार छूएं."</string>
+    <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>. चुनने के लिए दो बार छूएं."</string>
     <string name="accessibility_qs_edit_move_tile" msgid="2461819993780159542">"<xliff:g id="TILE_NAME">%1$s</xliff:g> को ले जाएं"</string>
     <string name="accessibility_qs_edit_remove_tile" msgid="7484493384665907197">"<xliff:g id="TILE_NAME">%1$s</xliff:g> निकालें"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"<xliff:g id="TILE_NAME">%1$s</xliff:g> को <xliff:g id="POSITION">%2$d</xliff:g> स्थिति में जोड़ा गया"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> निकाल दिया गया है"</string>
     <string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> को <xliff:g id="POSITION">%2$d</xliff:g> स्थिति में ले जाया गया"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"त्वरित सेटिंग संपादक."</string>
-    <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> नोटिफ़िकेशन: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
+    <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> सूचना: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"हो सकता है कि ऐप्लिकेशन विभाजित स्क्रीन के साथ काम ना करे."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ऐप विभाजित स्‍क्रीन का समर्थन नहीं करता है."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"हो सकता है कि ऐप प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर काम न करे."</string>
@@ -711,15 +719,15 @@
     <string name="accessibility_quick_settings_no_internet" msgid="31890692343084075">"कोई इंटरनेट नहीं."</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"विवरण खोलें."</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> सेटिंग खोलें."</string>
-    <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"सेटिंग का क्रम संपादित करें."</string>
+    <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"सेटिंग के क्रम को बदलें"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"पेज <xliff:g id="ID_2">%2$d</xliff:g> में से <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="5755818559638850294">"लॉक स्‍क्रीन"</string>
-    <string name="pip_phone_expand" msgid="5889780005575693909">"विस्तृत करें"</string>
+    <string name="pip_phone_expand" msgid="5889780005575693909">"विस्तार करें"</string>
     <string name="pip_phone_minimize" msgid="1079119422589131792">"छोटा करें"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"बंद करें"</string>
-    <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"खारिज करने के लिए नीचे खींचें"</string>
-    <string name="pip_menu_title" msgid="3328510504196964712">"चित्र में चित्र मेनू"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> स्क्रीन में स्क्रीन के अंदर है"</string>
+    <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"खारिज करने के लिए नीचे खींचें और छोड़ें"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"पिक्चर में पिक्चर मेन्यू"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> पिक्चर में पिक्चर के अंदर है"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"अगर आप नहीं चाहते कि <xliff:g id="NAME">%s</xliff:g> इस सुविधा का उपयोग करे, तो सेटिंग खोलने और उसे बंद करने के लिए टैप करें."</string>
     <string name="pip_play" msgid="1417176722760265888">"चलाएं"</string>
     <string name="pip_pause" msgid="8881063404466476571">"रोकें"</string>
@@ -743,7 +751,7 @@
     <string name="tuner_minus" msgid="4806116839519226809">"घटाने का चिह्न"</string>
     <string name="tuner_left" msgid="8404287986475034806">"बायां"</string>
     <string name="tuner_right" msgid="6222734772467850156">"दायां"</string>
-    <string name="tuner_menu" msgid="191640047241552081">"मेनू"</string>
+    <string name="tuner_menu" msgid="191640047241552081">"मेन्यू"</string>
     <string name="tuner_app" msgid="3507057938640108777">"<xliff:g id="APP">%1$s</xliff:g> ऐप"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"सूचनाएं"</string>
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"स्‍क्रीनशॉट"</string>
@@ -764,5 +772,6 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"रखें"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"बदलें"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"बैकग्राउंड में चल रहे ऐप्लिकेशन"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"बैटरी और डेटा उपयोग के विवरण देखने के लिए टैप करें"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"बैटरी और डेटा खर्च की जानकारी के लिए छूएं"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"मोबाइल डेटा बंद करना चाहते हैं?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings_car.xml b/packages/SystemUI/res/values-hi/strings_car.xml
index a643bd8..3cf1fb3 100644
--- a/packages/SystemUI/res/values-hi/strings_car.xml
+++ b/packages/SystemUI/res/values-hi/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"सुरक्षित ढंग से गाड़ी चलाएं"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"गाड़ी चलाने की स्थितियों के प्रति पूरी तरह से सतर्क रहें और हमेशा लागू कानूनों का पालन करें. दिशाएं गलत, अपूर्ण, खतरनाक, निषिद्ध हो सकती हैं या उनमें प्रशासनिक क्षेत्रों को पार करना शामिल हो सकता है. व्यावसायिक जानकारी भी गलत या अपूर्ण हो सकती है. डेटा रीयल-टाइम नहीं है और स्थान सटीकता की गारंटी नहीं दी जा सकती. गाड़ी चलाते समय अपने मोबाइल डिवाइस या फ़ोन या Android Auto के लिए अभिप्रेत न किए गए ऐप्स का उपयोग ना करें."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"अज्ञात"</string>
+    <string name="start_driving" msgid="864023351402918991">"ड्राइविंग शुरू करें"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings_tv.xml b/packages/SystemUI/res/values-hi/strings_tv.xml
index 5e65e46..357f7a6 100644
--- a/packages/SystemUI/res/values-hi/strings_tv.xml
+++ b/packages/SystemUI/res/values-hi/strings_tv.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="notification_channel_tv_pip" msgid="134047986446577723">"स्क्रीन में स्क्रीन"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"पिक्चर में पिक्चर"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(कोई शीर्षक कार्यक्रम नहीं)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP बंद करें"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"पूर्ण स्‍क्रीन"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index e71a6a6..c0bfee9 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -235,8 +235,8 @@
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Način rada uključen."</string>
     <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Način rada isključen."</string>
     <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Način rada uključen."</string>
-    <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Ušteda podataka isključena."</string>
-    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Ušteda podataka uključena."</string>
+    <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Štednja podatkovnog prometa isključena."</string>
+    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Štednja podatkovnog prometa uključena."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Svjetlina zaslona"</string>
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Punjenje"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G – 3G podaci pauzirani"</string>
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Više  postavki"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Gotovo"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Povezano"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Povezano, baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Povezivanje..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Dijeljenje veze"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Žarišna točka"</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Povezani ste s aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g> koja može nadzirati vašu osobnu aktivnost na mreži, uključujući e-poštu, aplikacije i web-lokacije."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Vašim radnim profilom upravlja organizacija <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil je povezan s aplikacijom <xliff:g id="APPLICATION">%2$s</xliff:g> koja može nadzirati vaše poslovne aktivnosti na mreži, uključujući e-poruke, aplikacije i web-lokacije.\n\nAko vam je potrebno više informacija, obratite se administratoru."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Vašim radnim profilom upravlja organizacija <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil je povezan s aplikacijom <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> koja može nadzirati vaše poslovne aktivnosti na mreži, uključujući e-poruke, aplikacije i web-lokacije.\n\nPovezani ste i s aplikacijom <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> koja može nadzirati vaše osobne aktivnosti na mreži."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Otključano za korisnika <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Izvodi se <xliff:g id="TRUST_AGENT">%1$s</xliff:g>"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Uređaj će ostati zaključan dok ga ručno ne otključate"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Primajte obavijesti brže"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Pogledajte ih prije otključavanja"</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Isključeno"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Napredne kontrole obavijesti omogućuju vam da postavite razinu važnosti za obavijesti aplikacije od 0 do 5. \n\n"<b>"Razina 5"</b>" \n– prikaži na vrhu popisa obavijesti \n– dopusti prekide prikaza na cijelom zaslonu \n– uvijek dopusti brzi pregled \n\n"<b>"Razina 4"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– uvijek dopusti brzi pregled \n\n"<b>"Razina 3"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– nikad ne dopusti brzi pregled\n\n"<b>"Razina 2"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– nikad ne dopusti brzi pregled \n– nikad ne emitiraj zvuk ni vibraciju \n\n"<b>"Razina 1"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– nikad ne dopusti brzi pregled \n– nikad ne emitiraj zvuk ni vibraciju \n– ne prikazuj na zaključanom zaslonu i traci statusa \n– prikaži na dnu popisa obavijesti \n\n"<b>"Razina 0"</b>" \n– blokiraj sve obavijesti aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obavijesti"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Više nećete primati te obavijesti."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Više nećete primati te obavijesti"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Broj kategorija obavijesti: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ova aplikacija nema kategorije obavijesti"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Obavijesti ove aplikacije ne mogu se isključiti"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije obavijesti iz ove aplikacije</item>
       <item quantity="few">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije obavijesti iz ove aplikacije</item>
@@ -574,12 +578,18 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kontrole obavijesti"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opcije odgode obavijesti"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 sat"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 sata"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"PONIŠTI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odgođeno <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d sat</item>
+      <item quantity="few">%d sata</item>
+      <item quantity="other">%d sati</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d minuta</item>
+      <item quantity="few">%d minute</item>
+      <item quantity="other">%d minuta</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Potrošnja baterije"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Štednja baterije nije dostupna tijekom punjenja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Štednja baterije"</string>
@@ -627,17 +637,17 @@
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendar"</string>
     <string name="tuner_full_zen_title" msgid="4540823317772234308">"Prikaži s kontrolama glasnoće"</string>
-    <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ne uznemiravaj"</string>
+    <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ne ometaj"</string>
     <string name="volume_dnd_silent" msgid="4363882330723050727">"Prečac tipki za glasnoću"</string>
-    <string name="volume_up_silent" msgid="7141255269783588286">"Zaustavi \"Ne uznemiravaj\" kada je zvuk pojačan"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Zaustavi \"Ne ometaj\" kada je zvuk pojačan"</string>
     <string name="battery" msgid="7498329822413202973">"Baterija"</string>
     <string name="clock" msgid="7416090374234785905">"Sat"</string>
     <string name="headset" msgid="4534219457597457353">"Slušalice"</string>
     <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Slušalice su povezane"</string>
     <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Slušalice su povezane"</string>
-    <string name="data_saver" msgid="5037565123367048522">"Ušteda podataka"</string>
-    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"Ušteda podataka je uključena"</string>
-    <string name="accessibility_data_saver_off" msgid="8841582529453005337">"Ušteda podataka je isključena"</string>
+    <string name="data_saver" msgid="5037565123367048522">"Štednja podatkovnog prometa"</string>
+    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"Štednja podatkovnog prometa je uključena"</string>
+    <string name="accessibility_data_saver_off" msgid="8841582529453005337">"Štednja podatkovnog prometa je isključena"</string>
     <string name="switch_bar_on" msgid="1142437840752794229">"Uključeno"</string>
     <string name="switch_bar_off" msgid="8803270596930432874">"Isključeno"</string>
     <string name="nav_bar" msgid="1993221402773877607">"Navigacijska traka"</string>
@@ -760,13 +770,14 @@
     <string name="mobile_data" msgid="7094582042819250762">"Mobilni podaci"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je isključen"</string>
     <string name="bt_is_off" msgid="2640685272289706392">"Bluetooth je isključen"</string>
-    <string name="dnd_is_off" msgid="6167780215212497572">"Način Ne uznemiravaj isključen"</string>
-    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"Način Ne uznemiravaj uključilo je automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
-    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"Način Ne uznemiravaj uključila je aplikacija (<xliff:g id="ID_1">%s</xliff:g>)."</string>
-    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"Način Ne uznemiravaj uključilo je automatsko pravilo ili aplikacija."</string>
+    <string name="dnd_is_off" msgid="6167780215212497572">"Način Ne ometaj isključen"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"Način Ne ometaj uključilo je automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"Način Ne ometaj uključila je aplikacija (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"Način Ne ometaj uključilo je automatsko pravilo ili aplikacija."</string>
     <string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Zadrži"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Zamijeni"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Izvođenje aplikacija u pozadini"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite da biste vidjeli pojedinosti o potrošnji baterije i podatkovnom prometu"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Isključiti mobilne podatke?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings_car.xml b/packages/SystemUI/res/values-hr/strings_car.xml
index 034bd71d..0a281d7 100644
--- a/packages/SystemUI/res/values-hr/strings_car.xml
+++ b/packages/SystemUI/res/values-hr/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vozite sigurno"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Pažljivo pratite promet i uvijek se pridržavajte primjenjivih zakona. Upute mogu biti neprecizne, nepotpune, opasne, neprikladne, zabranjene ili mogu uključivati prelazak administrativnih granica. Podaci o tvrtkama također mogu biti neprecizni i nepotpuni. Podaci nisu u stvarnom vremenu i preciznost lokacije nije zajamčena. Tijekom vožnje ne rukujte mobilnim uređajem i ne upotrebljavajte aplikacije koje nisu namijenjene za Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Nepoznato"</string>
+    <string name="start_driving" msgid="864023351402918991">"Započni vožnju"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 05dd386..2aeaeca 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"További beállítások"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Kész"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Csatlakoztatva"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Csatlakoztatva; az akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Csatlakozás…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Megosztás"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Ön a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazáshoz csatlakozik, amely figyelheti személyes hálózati tevékenységét, beleértve az e-maileket, alkalmazásokat és webhelyeket."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Munkaprofilját a(z) <xliff:g id="ORGANIZATION">%1$s</xliff:g> kezeli. A profil csatlakozik a(z) <xliff:g id="APPLICATION">%2$s</xliff:g> alkalmazáshoz, amely figyelheti az Ön hálózati tevékenységeit, beleértve az e-maileket, alkalmazásokat és webhelyeket.\n\nTovábbi információért forduljon a rendszergazdához."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Munkaprofilját a(z) <xliff:g id="ORGANIZATION">%1$s</xliff:g> kezeli. A profil csatlakozik a(z) <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> alkalmazáshoz, amely figyelheti az Ön hálózati tevékenységeit, beleértve az e-maileket, alkalmazásokat és webhelyeket.\n\nCsatlakoztatta továbbá a(z) <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> alkalmazást, amely figyelheti az Ön személyes hálózati tevékenységeit."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Felnyitva a következő számára: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"A(z) <xliff:g id="TRUST_AGENT">%1$s</xliff:g> jelenleg fut"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Az eszköz addig zárolva marad, amíg kézileg fel nem oldja"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Gyorsabban megkaphatja az értesítéseket"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Már a képernyőzár feloldása előtt megtekintheti őket"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Kikapcsolva"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Az értesítési beállítások révén 0-tól 5-ig állíthatja be a fontossági szintet az alkalmazás értesítéseinél. \n\n"<b>"5. szint"</b>" \n– Megjelenítés az értesítési lista tetején \n– Teljes képernyő megszakításának engedélyezése \n– Mindig felugrik \n\n"<b>"4. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Mindig felugrik \n\n"<b>"3. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Soha nem ugrik fel \n\n"<b>"2. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Soha nem ugrik fel \n– Soha nincs hangjelzés és rezgés \n\n"<b>"1. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Soha nem ugrik fel \n– Soha nincs hangjelzés vagy rezgés \n– Elrejtés a lezárási képernyőről és az állapotsávról \n– Megjelenítés az értesítési lista alján \n\n"<b>"0. szint"</b>" \n– Az alkalmazás összes értesítésének letiltása"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Értesítések"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Többé nem jelennek meg ezek az értesítések."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Többé nem jelennek meg ezek az értesítések"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> értesítéskategória"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Az alkalmazás nem rendelkezik értesítési kategóriákkal"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Az alkalmazástól érkező értesítések nem kapcsolhatók ki"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g>/1 értesítési kategória az alkalmazásból</item>
       <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g>/1 értesítési kategória az alkalmazásból</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> – <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"értesítésvezérlők"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"értesítések halasztási beállításai"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 perc"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 perc"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 óra"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 óra"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"VISSZAVONÁS"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Elhalasztva: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d óra</item>
+      <item quantity="one">%d óra</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d perc</item>
+      <item quantity="one">%d perc</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Akkumulátorhasználat"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Az Akkumulátorkímélő módot töltés közben nem lehet használni"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akkumulátorkímélő mód"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Csere"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"A háttérben még futnak alkalmazások"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Koppintson az akkumulátor- és adathasználat részleteinek megtekintéséhez"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Kikapcsolja a mobiladatokat?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings_car.xml b/packages/SystemUI/res/values-hu/strings_car.xml
index 688d88b..46bf09d 100644
--- a/packages/SystemUI/res/values-hu/strings_car.xml
+++ b/packages/SystemUI/res/values-hu/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vezessen óvatosan"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Mindig legyen teljes mértékben tisztában a vezetési körülményekkel, és a vonatkozó törvényeket tartsa be! Az útvonaltervek pontatlanok, hiányosak, veszélyesek, nem megfelelők vagy tiltottak lehetnek, illetve a közforgalom számára nem használható utakat érinthetnek. Az üzleti információk is pontatlanok vagy hiányosak lehetnek. Az adatok nem valós idejűek, ezért nem garantálhatjuk a helyadatok pontosságát. Vezetés közben ne kezelje mobileszközét, illetve ne használjon olyan alkalmazásokat az Android Auto rendszerrel, amelyeket nem ahhoz terveztek."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Ismeretlen"</string>
+    <string name="start_driving" msgid="864023351402918991">"Kezdhet vezetni"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 37a7cbd..79cef68 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -67,12 +67,12 @@
     <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"Սարքի վրա այս պահին մուտք գործած օգտատերը չի կարող միացնել USB վրիպազերծումը: Այս գործառույթից օգտվելու համար մուտք գործեք ադմինիստրատորի հաշվով:"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Խոշորացնել` էկրանը լցնելու համար"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ձգել` էկրանը լցնելու համար"</string>
-    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Պահում է էկրանի հանույթը…"</string>
-    <string name="screenshot_saving_title" msgid="8242282144535555697">"Պահում է էկրանի հանույթը..."</string>
-    <string name="screenshot_saving_text" msgid="2419718443411738818">"Էկրանի հանույթը պահվում է:"</string>
-    <string name="screenshot_saved_title" msgid="6461865960961414961">"Էկրանի հանույթը լուսանկարվել է:"</string>
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Պահում է էկրանի պատկերը…"</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"Պահում է էկրանի պատկերը..."</string>
+    <string name="screenshot_saving_text" msgid="2419718443411738818">"Էկրանի պատկերը պահվում է:"</string>
+    <string name="screenshot_saved_title" msgid="6461865960961414961">"Էկրանի պատկերը լուսանկարվել է:"</string>
     <string name="screenshot_saved_text" msgid="2685605830386712477">"Հպեք՝ էկրանի պատկերը տեսնելու համար:"</string>
-    <string name="screenshot_failed_title" msgid="705781116746922771">"Չհաջողվեց լուսանկարել էկրանի հանույթը:"</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Չհաջողվեց լուսանկարել էկրանի պատկերը:"</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Էկրանի պատկերը պահելիս խնդիր առաջացավ:"</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Չհաջողվեց պահել էկրանի պատկերը սահմանափակ հիշողության պատճառով:"</string>
     <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Հավելվածը կամ ձեր կազմակերպությունը չի թույլատրում էկրանի պատկերի ստացումը"</string>
@@ -290,7 +290,7 @@
     <string name="quick_settings_settings_label" msgid="5326556592578065401">"Կարգավորումներ"</string>
     <string name="quick_settings_time_label" msgid="4635969182239736408">"Ժամանակը"</string>
     <string name="quick_settings_user_label" msgid="5238995632130897840">"Ես"</string>
-    <string name="quick_settings_user_title" msgid="4467690427642392403">"Օտատեր"</string>
+    <string name="quick_settings_user_title" msgid="4467690427642392403">"Օգտատեր"</string>
     <string name="quick_settings_user_new_user" msgid="9030521362023479778">"Նոր օգտատեր"</string>
     <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Միացված չէ"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Հավելյալ կարգավորումներ"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Պատրաստ է"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Կապակցված է"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Միացված է, մարտկոցի լիցք՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Միանում է..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Մոդեմի ռեժիմ"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Թեժ կետ"</string>
@@ -383,7 +384,7 @@
     <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_new_guest" msgid="600537543078847803">"Հյուր ավելացնել"</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_dialog_message" msgid="4155503224769676625">"Այս աշխատաշրջանի բոլոր ծրագրերն ու տվյալները կջնջվեն:"</string>
@@ -409,7 +410,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="media_projection_action_text" msgid="8470872969457985954">"Մեկնարկել հիմա"</string>
+    <string name="media_projection_action_text" msgid="8470872969457985954">"Սկսել հիմա"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ծանուցումներ չկան"</string>
     <string name="profile_owned_footer" msgid="8021888108553696069">"Պրոֆիլը կարող է վերահսկվել"</string>
     <string name="vpn_footer" msgid="2388611096129106812">"Ցանցը կարող է վերահսկվել"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Դուք կապակցված եք <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածին, որը կարող է վերահսկել անձնական ցանցում կատարած ձեր գործողությունները, այդ թվում նաև էլփոստի հաշիվները, հավելվածները և կայքերը:"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Ձեր աշխատանքային պրոֆիլի կառավարիչն է <xliff:g id="ORGANIZATION">%1$s</xliff:g> կազմակերպությունը: Այն կապակցված է <xliff:g id="APPLICATION">%2$s</xliff:g> հավելվածին, որը կարող է վերահսկել աշխատանքային ցանցում կատարած գործունեությունը, այդ թվում նաև էլփոստի հաշիվները, հավելվածները և կայքերը:\n\nԼրացուցիչ տեղեկություններ ստանալու համար դիմեք ձեր ադմինիստրատորին։"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Ձեր աշխատանքային պրոֆիլի կառավարիչն է <xliff:g id="ORGANIZATION">%1$s</xliff:g> կազմակերպությունը: Այն կապակցված է <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> հավելվածին, որը կարող է վերահսկել աշխատանքային ցանցում կատարած գործունեությունը, այդ թվում նաև էլփոստի հաշիվները, հավելվածները և կայքերը:\n\nԴուք կապակցված եք նաև <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> հավելվածին, որը կարող է վերահսկել անձնական ցանցում կատարած ձեր գործողությունները:"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Ապակողպվել է <xliff:g id="USER_NAME">%1$s</xliff:g> օգտատիրոջ համար"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g>-ն աշխատում է"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Սարքը կմնա արգելափակված՝ մինչև ձեռքով չբացեք"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Ավելի արագ ստացեք ծանուցումները"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Տեսեք դրանք մինչև ապակողպելը"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Անջատել"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Ծանուցումների ընդլայնված կառավարման օգնությամբ կարող եք յուրաքանչյուր հավելվածի ծանուցումների համար նշանակել կարևորության աստիճան՝ 0-5 սահմաններում: \n\n"<b>"5-րդ աստիճան"</b>" \n- Ցուցադրել ծանուցումների ցանկի վերևում \n- Թույլատրել լիաէկրան ընդհատումները \n- Միշտ ցուցադրել կարճ ծանուցումները \n\n"<b>"4-րդ աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Միշտ ցուցադրել կարճ ծանուցումները \n\n"<b>"3-րդ աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Արգելել կարճ ծանուցումների ցուցադրումը \n\n"<b>"2-րդ աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Արգելել կարճ ծանուցումների ցուցադրումը \n- Անջատել ձայնը և թրթռումը \n\n"<b>"1-ին աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Արգելել կարճ ծանուցումների ցուցադրումը \n- Անջատել ձայնը և թրթռումը \n- Չցուցադրել կողպէկրանում և կարգավիճակի գոտում \n- Ցուցադրել ծանուցումների ցանկի ներքևում \n\n"<b>"0-րդ աստիճան"</b>\n"- Արգելափակել հավելվածի բոլոր ծանուցումները"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Ծանուցումներ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Այս ծանուցումներն այլևս չեք ստանա։"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Այս ծանուցումներն այլևս չեք ստանա"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ծանուցման կատեգորիաներ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Այս հավելվածը ծանուցման կատեգորիաներ չունի"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Այս հավելվածի ծանուցումները հնարավոր չէ անջատել"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 out of <xliff:g id="NUMBER_1">%d</xliff:g> notification categories from this app</item>
       <item quantity="other">1 ալիք` այս հավելվածի <xliff:g id="NUMBER_1">%d</xliff:g> կատեգորիաներից</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"ծանուցման կառավարներ"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"ծանուցման հետաձգման ընտրանքներ"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 րոպե"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 րոպե"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ժամ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ժամ"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ՀԵՏԱՐԿԵԼ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Հետաձգվել է <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>ով"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d hours</item>
+      <item quantity="other">%d ժամ</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d minutes</item>
+      <item quantity="other">%d րոպե</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Մարտկոցի օգտագործում"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Մարտկոցի տնտեսումը լիցքավորման ժամանակ հասանելի չէ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Մարտկոցի տնտեսում"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Փոխարինել"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Ֆոնային ռեժիմում աշխատող հավելվածներ"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Հպեք՝ մարտկոցի և թրաֆիկի մանրամասները տեսնելու համար"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Անջատե՞լ բջջային ինտերնետը։"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings_car.xml b/packages/SystemUI/res/values-hy/strings_car.xml
index 4f214f7..3d7f225 100644
--- a/packages/SystemUI/res/values-hy/strings_car.xml
+++ b/packages/SystemUI/res/values-hy/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Վարեք ապահով"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Երթևեկության պայմաններին միշտ լավատեղյակ եղեք և կատարեք համապատասխան օրենքների պահանջները: Երթուղիները կարող են լինել սխալ, կիսատ, վտանգավոր, ոչ պատշաճ, արգելված կամ կարող են անցնել վարչական միավորների միջով: Բիզնես տվյալները նույնպես կարող են լինել սխալ կամ կիսատ: Տվյալներն իրական ժամանակում չեն թարմացվում, իսկ տեղադրության ճշգրտությունը չի կարող երաշխավորվել: Մեքենա վարելիս մի օգտագործեք ձեր շարժական սարքը, ինչպես նաև Android Auto-ի համար չնախատեսված հավելվածները:"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Անհայտ"</string>
+    <string name="start_driving" msgid="864023351402918991">"Սկսել վարումը"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 3e77a71..f0c25e1 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -298,7 +298,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Mati"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi Aktif"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Tidak ada jaringan Wi-Fi yang tersedia"</string>
-    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Transmisi"</string>
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Melakukan transmisi"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Perangkat tanpa nama"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Siap melakukan transmisi"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Setelan lainnya"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Selesai"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Tersambung"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Terhubung, baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Menyambung..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Menambatkan"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Anda tersambung ke <xliff:g id="APPLICATION">%1$s</xliff:g>, yang dapat memantau aktivitas jaringan pribadi, termasuk email, aplikasi, dan situs web.."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Profil kerja Anda dikelola oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil tersambung ke <xliff:g id="APPLICATION">%2$s</xliff:g>, yang dapat memantau aktivitas jaringan kerja, termasuk email, aplikasi, dan situs.\n\nHubungi admin untuk mendapatkan informasi lebih lanjut."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Profil kerja Anda dikelola oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil tersambung ke <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, yang dapat memantau aktivitas jaringan, termasuk email, aplikasi, dan situs.\n\nAnda juga tersambung ke <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, yang dapat memantau aktivitas jaringan pribadi."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Dibuka kuncinya untuk <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> sedang berjalan"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Perangkat akan tetap terkunci hingga Anda membukanya secara manual"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Dapatkan pemberitahuan lebih cepat"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Lihat sebelum membuka kunci"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Nonaktif"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Dengan kontrol notifikasi daya, Anda dapt menyetel level kepentingan notifikasi aplikasi dari 0 sampai 5. \n\n"<b>"Level 5"</b>" \n- Muncul di atas daftar notifikasi \n- Izinkan interupsi layar penuh \n- Selalu intip pesan \n\n"<b>"Level 4"</b>" \n- Jangan interupsi layar penuh \n- Selalu intip pesan \n\n"<b>"Level 3"</b>" \n- Jangan interupsi layar penuh \n- Tak pernah intip pesan \n\n"<b>"Level 2"</b>" \n- Jangan interupsi layar penuh \n- Tak pernah intip pesan \n- Tanpa suara dan getaran \n\n"<b>"Level 1"</b>" \n- Jangan interupsi layar penuh \n- Tak pernah intip pesan \n- Tanpa suara atau getaran \n- Sembunyikan dari layar kunci dan bilah status \n- Muncul di bawah daftar notifikasi \n\n"<b>"Level 0"</b>" \n- Blokir semua notifikasi dari aplikasi"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifikasi"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Anda tidak akan mendapatkan notifikasi ini lagi."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Anda tidak akan mendapatkan notifikasi ini lagi"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> kategori notifikasi"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Aplikasi ini tidak memiliki kategori notifikasi"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Notifikasi dari aplikasi ini tidak dapat dinonaktifkan"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 dari <xliff:g id="NUMBER_1">%d</xliff:g> kategori notifikasi dari aplikasi ini</item>
       <item quantity="one">1 dari <xliff:g id="NUMBER_0">%d</xliff:g> kategori notifikasi dari aplikasi ini</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kontrol notifikasi"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opsi tunda notifikasi"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 menit"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 menit"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 jam"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 jam"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"URUNG"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Ditunda selama <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d jam</item>
+      <item quantity="one">%d jam</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d menit</item>
+      <item quantity="one">%d menit</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Pemakaian baterai"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Penghemat Baterai tidak tersedia selama pengisian daya"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Penghemat Baterai"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Ganti"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikasi yang sedang berjalan di latar belakang"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap untuk melihat detail penggunaan baterai dan data"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Nonaktifkan data seluler?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings_car.xml b/packages/SystemUI/res/values-in/strings_car.xml
index cc23ecf..09f31b0 100644
--- a/packages/SystemUI/res/values-in/strings_car.xml
+++ b/packages/SystemUI/res/values-in/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Hati-hati saat berkendara"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Tetap perhatikan keadaan saat mengemudi dan selalu patuhi peraturan yang berlaku. Petunjuk arah mungkin tidak akurat, tidak lengkap, berbahaya, tidak cocok, terlarang, atau dapat melewati wilayah administratif. Informasi bisnis juga mungkin tidak akurat atau tidak lengkap. Data tidak dalam waktu nyata dan keakuratan lokasi tidak dijamin. Jangan menggunakan perangkat seluler atau aplikasi yang tidak berkaitan dengan Android Auto saat mengemudi."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Tidak diketahui"</string>
+    <string name="start_driving" msgid="864023351402918991">"Mulai Mengemudi"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index ce665e2..b0b77df 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Fleiri stillingar"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Lokið"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Tengt"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Tengt, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlaða"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Tengist..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tjóðrun"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Heitur reitur"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Þú ert með tengingu við <xliff:g id="APPLICATION">%1$s</xliff:g>, sem getur fylgst með persónulegri netnotkun þinni, þ. á m. tölvupósti, forritum og vefsvæðum."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Vinnusniðinu þínu er stýrt af <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Sniðið er tengt <xliff:g id="APPLICATION">%2$s</xliff:g>, sem getur fylgst með netnotkun þinni, þ. á m. tölvupósti, forritum og vefsvæðum\n\nFrekari upplýsingar fást hjá kerfisstjóra."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Vinnusniðinu þínu er stýrt af <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Sniðið er tengt <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, sem getur fylgst með netnotkun þinni, þ. á m. tölvupósti, forritum og vefsvæðum\n\nÞú ert einnig með tengingu við <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, sem getur fylgst með persónulegri netnotkun þinni."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Opnað fyrir <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> er í gangi"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Tækið verður læst þar til þú opnar það handvirkt"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Fáðu tilkynningar hraðar"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Sjáðu þær áður en þú opnar"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Slökkt"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Með orkutilkynningastýringum geturðu stillt mikilvægi frá 0 upp í 5 fyrir tilkynningar forrita. \n\n"<b>"Stig 5"</b>" \n- Sýna efst á tilkynningalista \n- Leyfa truflun þegar birt er á öllum skjánum \n- Kíkja alltaf \n\n"<b>"Stig 4"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja alltaf \n\n"<b>"Stig 3"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja aldrei \n\n"<b>"Stig 2"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja aldrei \n- Slökkva á hljóði og titringi \n\n"<b>"Stig 1"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja aldrei \n- Slökkva á hljóði og titringi \n- Fela á lásskjá og stöðustiku \n- Sýna neðst á tilkynningalista \n\n"<b>"Stig 0"</b>" \n- Setja allar tilkynningar frá forriti á bannlista"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Tilkynningar"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Þú færð þessar tilkynningar ekki framar."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Þú færð þessar tilkynningar ekki framar"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> tilkynningaflokkar"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Þetta forrit er ekki með tilkynningaflokka"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Ekki er hægt að slökkva á tilkynningum frá þessu forriti"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 af <xliff:g id="NUMBER_1">%d</xliff:g> tilkynningaflokki frá þessu forriti</item>
       <item quantity="other">1 af <xliff:g id="NUMBER_1">%d</xliff:g> tilkynningaflokkum frá þessu forriti</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"tilkynningastýringar"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"þöggunarstillingar tilkynninga"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 mínútur"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 mínútur"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 klukkustund"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 klukkustundir"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"AFTURKALLA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Þaggað í <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d klukkustund</item>
+      <item quantity="other">%d klukkustundir</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d mínúta</item>
+      <item quantity="other">%d mínútur</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Rafhlöðunotkun"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ekki er hægt að nota rafhlöðusparnað meðan á hleðslu stendur"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Rafhlöðusparnaður"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Skipta út"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Forrit sem keyra í bakgrunni"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Ýttu til að fá upplýsingar um rafhlöðu- og gagnanotkun"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Slökkva á farsímagögnum?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings_car.xml b/packages/SystemUI/res/values-is/strings_car.xml
index 65117be..5c89c76 100644
--- a/packages/SystemUI/res/values-is/strings_car.xml
+++ b/packages/SystemUI/res/values-is/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Aktu varlega"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Vertu vakandi fyrir akstursskilyrðum hverju sinni og farðu ævinlega eftir gildandi lögum. Leiðarlýsing kann að vera ónákvæm, ófullkomin, ekki við hæfi, bönnuð eða fela í sér ferðir um opinber svæði. Upplýsingar um fyrirtæki kunna einnig að vera ónákvæmar eða ófullkomnar. Gögn eru ekki í rauntíma og ekki er hægt að tryggja nákvæmni staðsetningarupplýsinga. Ekki handleika fartækið þitt meðan á akstri stendur eða nota forrit sem ekki eru hugsuð fyrir Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Óþekkt"</string>
+    <string name="start_driving" msgid="864023351402918991">"Keyra af stað"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 7bd3201..5a52e57 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Altre impostazioni"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Fine"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Connesso"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connesso, batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Connessione..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Sei collegato a <xliff:g id="APPLICATION">%1$s</xliff:g>, che consente di monitorare la tua attività di rete personale, inclusi siti web, email e app."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Il tuo profilo di lavoro è gestito da <xliff:g id="ORGANIZATION">%1$s</xliff:g> ed è collegato a <xliff:g id="APPLICATION">%2$s</xliff:g>, da cui è possibile monitorare la tua attività di rete lavorativa, inclusi siti web, email e app.\n\nPer ulteriori informazioni, contatta l\'amministratore."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Il tuo profilo di lavoro è gestito da <xliff:g id="ORGANIZATION">%1$s</xliff:g> ed è collegato a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, da cui è possibile monitorare la tua attività di rete lavorativa, inclusi siti web, email e app.\n\nSei collegato anche a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, da cui è possibile monitorare la tua attività di rete personale."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Sbloccato per <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> in esecuzione"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Il dispositivo resterà bloccato fino allo sblocco manuale"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Ricevi notifiche più velocemente"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Visualizza prima di sbloccare"</string>
@@ -503,7 +506,7 @@
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Tocca per disattivare l\'audio."</string>
     <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s comandi del volume mostrati. Fai scorrere verso l\'alto per ignorare."</string>
     <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Comandi del volume nascosti"</string>
-    <string name="system_ui_tuner" msgid="708224127392452018">"Sintetizzatore interfaccia utente di sistema"</string>
+    <string name="system_ui_tuner" msgid="708224127392452018">"Ottimizzatore UI di sistema"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostra percentuale batteria incorporata"</string>
     <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostra la percentuale di carica della batteria nell\'icona della barra di stato quando non è in carica"</string>
     <string name="quick_settings" msgid="10042998191725428">"Impostazioni rapide"</string>
@@ -526,12 +529,12 @@
     <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string>
     <string name="accessibility_managed_profile" msgid="6613641363112584120">"Profilo di lavoro"</string>
     <string name="tuner_warning_title" msgid="7094689930793031682">"Il divertimento riservato a pochi eletti"</string>
-    <string name="tuner_warning" msgid="8730648121973575701">"Il sintetizzatore interfaccia utente di sistema mette a disposizione altri metodi per modificare e personalizzare l\'interfaccia utente di Android. Queste funzioni sperimentali potrebbero cambiare, interrompersi o scomparire nelle versioni successive. Procedi con cautela."</string>
+    <string name="tuner_warning" msgid="8730648121973575701">"L\'Ottimizzatore UI di sistema mette a disposizione altri metodi per modificare e personalizzare l\'interfaccia utente di Android. Queste funzioni sperimentali potrebbero cambiare, interrompersi o scomparire nelle versioni successive. Procedi con cautela."</string>
     <string name="tuner_persistent_warning" msgid="8597333795565621795">"Queste funzioni sperimentali potrebbero cambiare, interrompersi o scomparire nelle versioni successive. Procedi con cautela."</string>
     <string name="got_it" msgid="2239653834387972602">"OK"</string>
-    <string name="tuner_toast" msgid="603429811084428439">"Complimenti! Il sintetizzatore interfaccia utente di sistema è stato aggiunto alle impostazioni."</string>
+    <string name="tuner_toast" msgid="603429811084428439">"Complimenti! L\'Ottimizzatore UI di sistema è stato aggiunto alle impostazioni."</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"Rimuovi dalle impostazioni"</string>
-    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vuoi rimuovere il sintetizzatore interfaccia utente di sistema dalle impostazioni e smettere di utilizzare tutte le sue funzioni?"</string>
+    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vuoi rimuovere l\'Ottimizzatore UI di sistema dalle impostazioni e smettere di utilizzare tutte le sue funzioni?"</string>
     <string name="activity_not_found" msgid="348423244327799974">"Applicazione non installata sul dispositivo"</string>
     <string name="clock_seconds" msgid="7689554147579179507">"Mostra i secondi nell\'orologio"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostra i secondi nell\'orologio nella barra di stato. Ciò potrebbe ridurre la durata della carica della batteria."</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"I controlli di gestione delle notifiche ti consentono di impostare un livello di importanza compreso tra 0 e 5 per le notifiche di un\'app. \n\n"<b>"Livello 5"</b>" \n- Mostra in cima all\'elenco di notifiche \n- Consenti l\'interruzione a schermo intero \n- Visualizza sempre \n\n"<b>"Livello 4"</b>" \n- Impedisci l\'interruzione a schermo intero \n- Visualizza sempre \n\n"<b>"Livello 3"</b>" \n- Impedisci l\'interruzione a schermo intero \n- Non visualizzare mai \n\n"<b>"Livello 2"</b>" \n- Impedisci l\'interruzione a schermo intero \n- Non visualizzare mai \n- Non emettere mai suoni e vibrazioni \n\n"<b>"Livello 1"</b>" \n- Impedisci l\'interruzione a schermo intero \n- Non visualizzare mai \n- Non emettere mai suoni e vibrazioni \n- Nascondi da schermata di blocco e barra di stato \n- Mostra in fondo all\'elenco di notifiche \n\n"<b>"Livello 0"</b>" \n- Blocca tutte le notifiche dell\'app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifiche"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Non riceverai più queste notifiche."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Non riceverai più queste notifiche"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorie di notifica"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Questa app non ha categorie di notifica"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Le notifiche di quest\'app non possono essere disattivate"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 categoria di notifica su <xliff:g id="NUMBER_1">%d</xliff:g> di questa app</item>
       <item quantity="one">1 categoria di notifica su <xliff:g id="NUMBER_0">%d</xliff:g> di questa app</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"gestione delle notifiche"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opzioni di posticipazione notifiche"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuti"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuti"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ore"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ANNULLA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Posticipato di <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d ore</item>
+      <item quantity="one">%d ora</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minuti</item>
+      <item quantity="one">%d minuto</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Utilizzo batteria"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Risparmio energetico non disponibile durante la ricarica"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Risparmio energetico"</string>
@@ -590,7 +598,7 @@
     <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Sinistra"</string>
     <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Destra"</string>
     <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Al centro"</string>
-    <string name="keyboard_key_tab" msgid="3871485650463164476">"Scheda"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
     <string name="keyboard_key_space" msgid="2499861316311153293">"Spazio"</string>
     <string name="keyboard_key_enter" msgid="5739632123216118137">"Invio"</string>
     <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Sostituisci"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"App in esecuzione in background"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tocca per conoscere i dettagli sull\'utilizzo dei dati e della batteria"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Disattivare i dati mobili?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings_car.xml b/packages/SystemUI/res/values-it/strings_car.xml
index 19c4e2b..65a90f8 100644
--- a/packages/SystemUI/res/values-it/strings_car.xml
+++ b/packages/SystemUI/res/values-it/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Guida in modo sicuro"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"È necessario essere sempre pienamente informati sulle condizioni della strada e rispettare la legislazione vigente. Le indicazioni stradali potrebbero essere imprecise, incomplete, pericolose, inadatte, vietate o richiedere l\'attraversamento di aree amministrative. Anche le informazioni sugli esercizi commerciali potrebbero essere imprecise o incomplete. I dati forniti non sono aggiornati in tempo reale e non è possibile garantire la precisione della geolocalizzazione. Non maneggiare dispositivi mobili e app non destinate ad Android Auto durante la guida."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Sconosciuto"</string>
+    <string name="start_driving" msgid="864023351402918991">"Inizia la guida"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 9d5c11e..ce40c32 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -20,7 +20,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"ממשק משתמש של המערכת"</string>
-    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"נקה"</string>
+    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"ניקוי"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"הסר מהרשימה"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"פרטי אפליקציה"</string>
     <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"המסכים האחרונים מופיעים כאן"</string>
@@ -87,7 +87,7 @@
     <string name="accessibility_menu" msgid="316839303324695949">"תפריט"</string>
     <string name="accessibility_accessibility_button" msgid="7601252764577607915">"נגישות"</string>
     <string name="accessibility_recent" msgid="5208608566793607626">"סקירה"</string>
-    <string name="accessibility_search_light" msgid="1103867596330271848">"חפש"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"חיפוש"</string>
     <string name="accessibility_camera_button" msgid="8064671582820358152">"מצלמה"</string>
     <string name="accessibility_phone_button" msgid="6738112589538563574">"טלפון"</string>
     <string name="accessibility_voice_assist_button" msgid="487611083884852965">"מסייע קולי"</string>
@@ -314,6 +314,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"הגדרות נוספות"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"בוצע"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"מחובר"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"מחובר, הסוללה ב-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"מתחבר..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"שיתוף אינטרנט בין ניידים"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"נקודה לשיתוף אינטרנט"</string>
@@ -335,7 +336,7 @@
     <string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"מחקת הכול"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"מידע על האפליקציה"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"הצמדת מסך"</string>
-    <string name="recents_search_bar_label" msgid="8074997400187836677">"חפש"</string>
+    <string name="recents_search_bar_label" msgid="8074997400187836677">"חיפוש"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"לא ניתן היה להפעיל את <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> מושבת במצב בטוח."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"נקה הכל"</string>
@@ -387,7 +388,7 @@
     <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_new_guest" msgid="600537543078847803">"הוסף אורח"</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_dialog_message" msgid="4155503224769676625">"כל האפליקציות והנתונים בפעילות זו באתר יימחקו."</string>
@@ -471,6 +472,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"אתה מחובר לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת הפרטית, כולל הודעות אימייל, אפליקציות ואתרים."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"פרופיל העבודה שלך מנוהל על ידי <xliff:g id="ORGANIZATION">%1$s</xliff:g>. הפרופיל מחובר לאפליקציה <xliff:g id="APPLICATION">%2$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים.\n\nלמידע נוסף, פנה למנהל המערכת."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"פרופיל העבודה שלך מנוהל על ידי <xliff:g id="ORGANIZATION">%1$s</xliff:g>. הפרופיל מחובר לאפליקציה <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים.\n\nהפרופיל מחובר גם לאפליקציה <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"הנעילה בוטלה על ידי <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> פועל"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"המכשיר יישאר נעול עד שתבטל את נעילתו באופן ידני"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"קבל התראות מהר יותר"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"צפה בהן לפני שתבטל נעילה"</string>
@@ -552,9 +555,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"כבוי"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"בעזרת פקדים של הודעות הפעלה, תוכל להגדיר רמת חשיבות מ-0 עד 5 להודעות אפליקציה. \n\n"<b>"רמה 5"</b>" \n- הצג בראש רשימת ההודעות \n- אפשר הפרעה במסך מלא \n- תמיד אפשר הצצה \n\n"<b>"רמה 4"</b>" \n- מנע הפרעה במסך מלא \n- תמיד אפשר הצצה \n\n"<b>"רמה 3"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n\n"<b>"רמה 2"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n- אף פעם אל תאפשר קול ורטט \n\n"<b>"רמה 1"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n- אף פעם אל תאפשר קול ורטט \n- הסתר ממסך הנעילה ומשורת הסטטוס \n- הצג בתחתית רשימת ההודעות \n\n"<b>"רמה 0"</b>" \n- חסום את כל ההודעות מהאפליקציה"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"הודעות"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"לא תקבל את ההודעות האלה יותר."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"לא תקבל את ההודעות האלה יותר"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> קטגוריות של התראות"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"האפליקציה הזו לא תומכת בקטגוריות של הודעות"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"לא ניתן לכבות התראות של האפליקציה הזאת"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="two">קטגוריית הודעות אחת מתוך <xliff:g id="NUMBER_1">%d</xliff:g> מאפליקציה זו</item>
       <item quantity="many">קטגוריית הודעות אחת מתוך <xliff:g id="NUMBER_1">%d</xliff:g> מאפליקציה זו</item>
@@ -578,12 +582,20 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"בקרת הודעות"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"אפשרויות של דחיית הודעות לטיפול בהמשך"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 דקות"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 דקות"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"שעה אחת"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"שעתיים"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ביטול"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"נדחה לטיפול בעוד <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="two">שעתיים</item>
+      <item quantity="many">‏%d שעות</item>
+      <item quantity="other">‏%d שעות</item>
+      <item quantity="one">שעה</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="two">‏%d דקות</item>
+      <item quantity="many">‏%d דקות</item>
+      <item quantity="other">‏%d דקות</item>
+      <item quantity="one">דקה</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"שימוש בסוללה"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"תכונת החיסכון בסוללה אינה זמינה בעת טעינת המכשיר"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"חיסכון בסוללה"</string>
@@ -662,7 +674,7 @@
     <item msgid="586019486955594690">"נטייה ימינה"</item>
   </string-array>
     <string name="menu_ime" msgid="4998010205321292416">"מחליף מקלדת"</string>
-    <string name="save" msgid="2311877285724540644">"שמור"</string>
+    <string name="save" msgid="2311877285724540644">"שמירה"</string>
     <string name="reset" msgid="2448168080964209908">"איפוס"</string>
     <string name="adjust_button_width" msgid="6138616087197632947">"שינוי של רוחב לחצן"</string>
     <string name="clipboard" msgid="1313879395099896312">"לוח"</string>
@@ -673,7 +685,7 @@
     <string name="right_icon" msgid="3952104823293824311">"סמל ימני"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"ניתן לגרור כדי להוסיף או להסיר משבצות"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"גרור לכאן כדי להסיר"</string>
-    <string name="qs_edit" msgid="2232596095725105230">"ערוך"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"עריכה"</string>
     <string name="tuner_time" msgid="6572217313285536011">"שעה"</string>
   <string-array name="clock_options">
     <item msgid="5965318737560463480">"הצג שעות, דקות ושניות"</item>
@@ -769,8 +781,9 @@
     <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"מצב \'נא לא להפריע\' הופעל על ידי אפליקציה (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"מצב \'נא לא להפריע להפריע\' הופעל על ידי אפליקציה או על ידי כלל אוטומטי."</string>
     <string name="qs_dnd_until" msgid="3469471136280079874">"עד <xliff:g id="ID_1">%s</xliff:g>"</string>
-    <string name="qs_dnd_keep" msgid="1825009164681928736">"שמור"</string>
+    <string name="qs_dnd_keep" msgid="1825009164681928736">"שמירה"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"החלף"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"אפליקציות שפועלות ברקע"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"הקש לקבלת פרטים על צריכה של נתונים וסוללה"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"לכבות את חבילת הגלישה?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings_car.xml b/packages/SystemUI/res/values-iw/strings_car.xml
index 4b7ba97..d172094 100644
--- a/packages/SystemUI/res/values-iw/strings_car.xml
+++ b/packages/SystemUI/res/values-iw/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"נסיעה בטוחה"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"‏שמור על עירנות לתנאי הנסיעה וציית תמיד לכללים והחוקים. ייתכן שהמסלול לא מדויק, לא שלם, מסוכן, לא מתאים, אסור למעבר או כרוך בחציית אזורים מנהליים. ייתכן גם שחלק מהמידע העסקי לא מדויק או לא שלם. הנתונים אינם מדווחים בזמן אמת ולא ניתן להבטיח דיוק במיקום. אל תתעסק במכשיר הנייד ואל תשתמש באפליקציות שאינן מיועדות ל-Android Auto בזמן הנהיגה."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"לא ידוע"</string>
+    <string name="start_driving" msgid="864023351402918991">"עבור למצב נהיגה"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index d426a8c..ebf3121 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"詳細設定"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"完了"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"接続済み"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"接続済み、電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"接続しています..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"テザリング"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"アクセスポイント"</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"「<xliff:g id="APPLICATION">%1$s</xliff:g>」に接続しています。このアプリはあなたの個人のネットワーク アクティビティ(メール、アプリ、ウェブサイトなど)を監視できます。"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"この仕事用プロファイルは<xliff:g id="ORGANIZATION">%1$s</xliff:g>によって管理され、<xliff:g id="APPLICATION">%2$s</xliff:g> に接続しています。このアプリはあなたの仕事のネットワーク アクティビティ(メール、アプリ、ウェブサイトなど)を監視できます。\n\n詳しくは管理者にお問い合わせください。"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"この仕事用プロファイルは<xliff:g id="ORGANIZATION">%1$s</xliff:g>によって管理され、<xliff:g id="APPLICATION_WORK">%2$s</xliff:g> に接続しています。このアプリはあなたの仕事のネットワーク アクティビティ(メール、アプリ、ウェブサイトなど)を管理できます。\n\nまた、<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> にも接続しているため、あなたの個人のネットワーク アクティビティも監視できます。"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> さんのロックを解除しました"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> を実行しています"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"手動でロックを解除するまでロックされたままとなります"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"通知をすばやく確認できます"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ロックを解除する前にご確認ください"</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"OFF"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"電源通知管理では、アプリの通知の重要度をレベル 0~5 で設定できます。\n\n"<b>"レベル 5"</b>" \n- 通知リストの一番上に表示する \n- 全画面表示を許可する \n- 常にポップアップする \n\n"<b>"レベル 4"</b>" \n- 全画面表示しない \n- 常にポップアップする \n\n"<b>"レベル 3"</b>" \n- 全画面表示しない \n- ポップアップしない \n\n"<b>"レベル 2"</b>" \n- 全画面表示しない \n- ポップアップしない \n- 音やバイブレーションを使用しない \n\n"<b>"レベル 1"</b>" \n- 全画面表示しない \n- ポップアップしない \n- 音やバイブレーションを使用しない \n- ロック画面やステータスバーに表示しない \n- 通知リストの一番下に表示する \n\n"<b>"レベル 0"</b>" \n- アプリからのすべての通知をブロックする"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"今後、この通知は配信されません。"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"今後、この通知は配信されません"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> 個の通知カテゴリ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"このアプリでは通知カテゴリが設定されていません"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"このアプリの通知を OFF にすることはできません"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">このアプリの通知カテゴリ <xliff:g id="NUMBER_1">%d</xliff:g> 件中 1 件</item>
       <item quantity="one">このアプリの通知カテゴリ <xliff:g id="NUMBER_0">%d</xliff:g> 件中 1 件</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"通知管理"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"通知スヌーズ設定"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15分"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30分"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1時間"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2時間"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"元に戻す"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"スヌーズ: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d時間</item>
+      <item quantity="one">%d時間</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d分</item>
+      <item quantity="one">%d分</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"電池の使用状況"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電中はバッテリー セーバーは利用できません"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"バッテリー セーバー"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"設定を変更"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"バックグラウンドで実行中のアプリ"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"タップして電池やデータの使用量を確認"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"モバイルデータを OFF にしますか?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings_car.xml b/packages/SystemUI/res/values-ja/strings_car.xml
index 667de81..15caa95 100644
--- a/packages/SystemUI/res/values-ja/strings_car.xml
+++ b/packages/SystemUI/res/values-ja/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"安全運転を心がけましょう"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"道路状況に十分気を配り、適用される法律を遵守してください。経路は、不正確、不完全、危険、不適切である場合や、通行が禁止されている、管理区域を通行する必要があるなどの場合があります。ビジネス情報も不正確または不完全である可能性があります。データはリアルタイムではなく、場所の正確性は保証されません。運転中はモバイル端末を手に持って操作したり、Android Auto とは無関係のアプリを使用したりしないでください。"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"不明"</string>
+    <string name="start_driving" msgid="864023351402918991">"運転を開始"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index e07b041..2a1ba7e 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -155,7 +155,7 @@
     <string name="accessibility_cell_data" msgid="5326139158682385073">"მობილური ინტერნეტი"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"მობილური ინტერნეტი ჩართულია"</string>
     <string name="accessibility_cell_data_off" msgid="443267573897409704">"მობილური ინტერნეტი გამორთულია"</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-ის ჩართვა"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth ტეტერინგის ჩართვა"</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"თვითმფრინავის რეჟიმი"</string>
     <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN ჩართულია."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"SIM ბარათი არ არის."</string>
@@ -310,8 +310,9 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"დამატებითი პარამეტრები"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"დასრულდა"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"დაკავშირებულია"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"დაკავშირებულია. ბატარეის დონე: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"დაკავშირება..."</string>
-    <string name="quick_settings_tethering_label" msgid="7153452060448575549">"მოდემის რეჟიმი"</string>
+    <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ტეტერინგი"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"წვდომის წერტილი"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"შეტყობინებები"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ფანარი"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"თქვენ დაუკავშირდით <xliff:g id="APPLICATION">%1$s</xliff:g>-ს, რომელსაც თქვენი პირადი ქსელის აქტივობის მონიტორინგი შეუძლია, მათ შორის, ელფოსტის, აპებისა და ვებსაიტების."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"თქვენს სამსახურის პროფილს მართავს <xliff:g id="ORGANIZATION">%1$s</xliff:g>. პროფილი დაკავშირებულია <xliff:g id="APPLICATION">%2$s</xliff:g>-თან, რომელსაც შეუძლია ქსელში თქვენი სამსახურეობრივი აქტივობის (მათ შორის, ელფოსტის, აპებისა და ვებსაიტების) მონიტორინგი.\n\nდამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"თქვენს სამსახურის პროფილს მართავს <xliff:g id="ORGANIZATION">%1$s</xliff:g>. პროფილი დაკავშირებულია <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>-თან, რომელსაც შეუძლია ქსელში თქვენი სამსახურეობრივი აქტივობის (მათ შორის, ელფოსტის, აპებისა და ვებსაიტების) მონიტორინგი.\n\nგარდა ამისა, თქვენ დაკავშირებული ხართ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>-თან, რომელსაც ქსელში თქვენი პირადი აქტივობის მონიტორინგი შეუძლია."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"განბლოკილია მომხმარებლისთვის: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> გაშვებულია"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"მოწყობილობის დარჩება ჩაკეტილი, სანამ ხელით არ გახსნით"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"შეტყობინებების უფრო სწრაფად მიღება"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"იხილეთ განბლოკვამდე"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"გამორთული"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"შეტყობინებების მართვის საშუალებების მეშვეობით, შეგიძლიათ განსაზღვროთ აპის შეტყობინებების მნიშვნელობის დონე 0-დან 5-მდე დიაპაზონში. \n\n"<b>"დონე 5"</b>" \n— შეტყობინებათა სიის თავში ჩვენება \n— სრულეკრანიანი რეჟიმის შეფერხების დაშვება \n— ეკრანზე ყოველთვის გამოჩენა \n\n"<b>"დონე 4"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე ყოველთვის გამოჩენა \n\n"<b>"დონე 3"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე გამოჩენის აღკვეთა \n\n"<b>"დონე 2"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე გამოჩენის აღკვეთა \n— ხმისა და ვიბრაციის აღკვეთა \n\n"<b>"დონე 1"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე გამოჩენის აღკვეთა \n— ხმისა და ვიბრაციის აღკვეთა \n— ჩაკეტილი ეკრანიდან და სტატუსის ზოლიდან დამალვა \n— შეტყობინებათა სიის ბოლოში ჩვენება \n\n"<b>"დონე 0"</b>" \n— აპის ყველა შეტყობინების დაბლოკვა"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"შეტყობინებები"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ამ შეტყობინებებს აღარ მიიღებთ."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ამ შეტყობინებებს აღარ მიიღებთ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"შეტყობინებების <xliff:g id="NUMBER">%d</xliff:g> კატეგორია"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ამ აპს შეტყობინებების კატეგორიები არ აქვს"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"ამ აპიდან შეტყობინებების გამორთვა ვერ მოხერხდება"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">ამ აპის შეტყობინებების <xliff:g id="NUMBER_1">%d</xliff:g> კატეგორიიდან 1</item>
       <item quantity="one">ამ აპის შეტყობინებების <xliff:g id="NUMBER_0">%d</xliff:g> კატეგორიიდან 1</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"შეტყობინებების მართვის საშუალებები"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"შეტყობინებების ჩაჩუმების ვარიანტები"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 წუთი"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 წუთი"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 საათი"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 საათი"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"მოქმედების გაუქმება"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"ჩაჩუმებული იქნება <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d საათი</item>
+      <item quantity="one">%d საათი</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d წუთი</item>
+      <item quantity="one">%d წუთი</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"ბატარეის მოხმარება"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ბატარეის დამზოგი დატენვისას მიწვდომელია"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ბატარეის დამზოგი"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"ჩანაცვლება"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"ფონურ რეჟიმში გაშვებული აპები"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"შეეხეთ ბატარეისა და მონაცემების მოხმარების შესახებ დეტალური ინფორმაციისთვის"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"გსურთ მობილური ინტერნეტის გამორთვა?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings_car.xml b/packages/SystemUI/res/values-ka/strings_car.xml
index c8e17dd..d6f5693 100644
--- a/packages/SystemUI/res/values-ka/strings_car.xml
+++ b/packages/SystemUI/res/values-ka/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"უსაფრთხოდ მართვის წესები"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ყოველთვის გულდასმით გაეცანით მდგომარეობას გზებზე და დაიცავით მოქმედი კანონები. შეთავაზებული მიმართულებები შეიძლება იყოს უზუსტო, არასრული, სახიფათო, შეუფერებელი, აკრძალული, ან ადმინისტრაციული ერთეულების გადაკვეთას გულისხმობდეს. ბიზნეს-ინფორმაცია შეიძლება ასევე იყოს უზუსტო ან არასრული. მონაცემების განახლება რეალური დროის რეჟიმში არ ხდება და შესაბამისად, მდებარეობის სიზუსტე გარანტირებული ვერ იქნება. ავტომობილის მართვისას ნუ შეეცდებით თქვენი მობილური მოწყობილობით მანიპულირებას, ან ისეთი აპების გამოყენებას, რომლებიც Android Auto-სთვის შექმნილი არ არის."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"უცნობი"</string>
+    <string name="start_driving" msgid="864023351402918991">"დაიწყეთ მართვა"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 9478a96..4bc858d 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -298,7 +298,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi өшірулі"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi қосулы"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Қолжетімді Wi-Fi желілері жоқ"</string>
-    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Трансляциялау"</string>
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Трансляция"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Трансляциялануда"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Атаусыз құрылғы"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Трансляциялауға дайын"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Қосымша параметрлер"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Дайын"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Қосылды"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Қосылды, батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Қосылуда…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Тетеринг"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Хот-спот"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Жеке желідегі әрекеттеріңізді, соның ішінде электрондық пошта хабарларын, қолданбаларды және вебсайттарды бақылай алатын <xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасына қосылғансыз."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Жұмыс профиліңізді <xliff:g id="ORGANIZATION">%1$s</xliff:g> басқарады. Бұл профиль жұмыс желісіндегі белсенділігіңізді, соның ішінде электрондық хабарларды, қолданбаларды және веб-сайттарды бақылай алатын <xliff:g id="APPLICATION">%2$s</xliff:g> қолданбасына қосылған.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Жұмыс профиліңізді <xliff:g id="ORGANIZATION">%1$s</xliff:g> басқарады. Бұл профиль жұмыс желісіндегі белсенділігіңізді, соның ішінде электрондық хабарларды, қолданбаларды және веб-сайттарды бақылай алатын <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> қолданбасына қосылған.\n\nСондай-ақ сіз жеке желідегі белсенділігіңізді бақылай алатын <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> қолданбасына қосылғансыз."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> үшін құлпы ашылды"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> белсенді"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Қолмен бекітпесін ашқанша құрылғы бекітілген күйде қалады"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Хабарландыруларды тезірек алу"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Бекітпесін ашу алдында оларды көру"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Өшірулі"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Қуат хабарландыруының басқару элементтерімен қолданбаның хабарландырулары үшін 0-ден бастап 5-ке дейін маңыздылық деңгейін орнатуға болады. \n\n"<b>"5-деңгей"</b>" \n- Хабарландыру тізімінің ең басында көрсету \n- Толық экранға ашылуын рұқсат ету \n- Әрдайым қалқымалы хабарландыру түрінде көрсету \n\n"<b>"4-деңгей"</b>" \n- Толық экранға шығармау \n- Әрдайым қалқымалы хабарландыру түрінде көрсету \n\n"<b>"3-деңгей"</b>" \n- Толық экранға шығармау \n- Ешқашан қалқымалы хабарландыру түрінде көрсетпеу \n\n"<b>"2-деңгей"</b>" \n- Толық экранға шығармау \n- Ешқашан қалқымалы хабарландыру түрінде көрсетпеу \n- Ешқашан дыбыс және діріл шығармау \n\n"<b>"1-деңгей"</b>" \n- Толық экранға шығармау \n- Ешқашан қалқымалы хабарландыру түрінде көрсетпеу \n- Ешқашан дыбыс немесе діріл шығармау \n- Құлыпталған экраннан және күйін көрсету жолағынан жасыру \n- Хабарландыру тізімінің ең астында көрсету \n\n"<b>"0-деңгей"</b>" \n- Қолданбадағы барлық хабарландыруларға тыйым салу"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Хабарландырулар"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Сізге енді бұл хабарландырулар жіберілмейді."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Енді сізге бұл хабарландырулар жіберілмейді"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> хабарландыру санаттары"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Бұл қолданбада хабарландыру санаттары жоқ"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Бұл қолданбаның хабарландырулары өшірілмейді"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Осы қолданбадан <xliff:g id="NUMBER_1">%d</xliff:g> ішінен 1 хабарландыру санаты</item>
       <item quantity="one">Осы қолданбадан <xliff:g id="NUMBER_0">%d</xliff:g> ішінен 1 хабарландыру санаты</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"хабарландыруларды басқару элементтері"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"хабарландыруды кідірту опциялары"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минут"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 минут"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 сағат"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 сағат"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"КЕРІ ҚАЙТАРУ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> кідіртілді"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d сағат</item>
+      <item quantity="one">%d сағат</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d минут</item>
+      <item quantity="one">%d минут</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Батареяны пайдалану"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Зарядтау кезінде Батарея үнемдегіш қол жетімді емес"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Батарея үнемдегіш"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Ауыстыру"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Фонда жұмыс істеп тұрған қолданбалар"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Батарея мен деректер трафигі туралы білу үшін түртіңіз"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Мобильдік деректер өшірілсін бе?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings_car.xml b/packages/SystemUI/res/values-kk/strings_car.xml
index 056b75c..d8c6337 100644
--- a/packages/SystemUI/res/values-kk/strings_car.xml
+++ b/packages/SystemUI/res/values-kk/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Қауіпсіз жүргізу"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Жүргізу жағдайларын толығымен ұғыныңыз және тиісті заңдарды әрқашан сақтаңыз. Бағыттар дәл емес, толық емес, қауіпті, жарамсыз, тыйым салынған болуы немесе әкімшілік аумақтарды қиып өтуі мүмкін. Іскери ақпарат та дәл емес немесе толық емес болуы мүмкін. Деректер нақты уақыттағы деректер емес және орын дәлдігіне кепілдік берілмейді. Жүргізу кезінде мобильді құрылғыңызды ұстамаңыз немесе Android Auto қолданбасына арналмаған қолданбаларды пайдаланбаңыз."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Белгісіз"</string>
+    <string name="start_driving" msgid="864023351402918991">"Жүргізуді бастау"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 2388327..52ab1cd 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -150,7 +150,7 @@
     <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
     <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"រ៉ូ​មីង"</string>
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
-    <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"វ៉ាយហ្វាយ"</string>
+    <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"គ្មាន​ស៊ីម​កាត។"</string>
     <string name="accessibility_cell_data" msgid="5326139158682385073">"ទិន្នន័យ​ទូរសព្ទចល័ត"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"ទិន្នន័យទូរសព្ទចល័តបានបើក"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"ការ​កំណត់​ច្រើន​ទៀត"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"រួចរាល់"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"បាន​ភ្ជាប់"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"បានភ្ជាប់ ហើយថ្មមានកម្រិត <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"កំពុង​តភ្ជាប់..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ការ​ភ្ជាប់"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ហតស្ប៉ត"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"អ្នកត្រូវបានភ្ជាប់ទៅ <xliff:g id="APPLICATION">%1$s</xliff:g> ដែលអាចឃ្លាំមើលសកម្មភាពបណ្តាញរបស់អ្នក រាប់បញ្ចូលទាំងអ៊ីមែល កម្មវិធី និងគេហទំព័រ។"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"កម្រង​ព័ត៌មាន​ការងារ​របស់អ្នក​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ។ កម្រងព័ត៌មាន​នេះត្រូវ​បាន​ភ្ជាប់ទៅ <xliff:g id="APPLICATION">%2$s</xliff:g> ដែលអាច​តាមដាន​សកម្មភាព​បណ្តាញ​របស់អ្នក រួមទាំង​អ៊ីមែល កម្មវិធី និង​គេហទំព័រ​ផងដែរ។\n\nសម្រាប់​ព័ត៌មាន​បន្ថែម សូម​ទាក់ទង​ទៅអ្នក​គ្រប់គ្រង​របស់​អ្នក។"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"កម្រងព័ត៌មាន​ការងារ​របស់អ្នក​ស្ថិតក្រោម​គ្រប់គ្រង​របស់ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ។ កម្រង​ព័ត៌មាននេះ​ត្រូវបាន​ភ្ជាប់​ទៅ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ដែលអាច​តាមដាន​សកម្មភាព​បណ្តាញ​របស់អ្នក រួមទាំង​អ៊ីមែល កម្មវិធី និង​គេហទំព័រ​ផងដែរ។\n\nអ្នកក៏ត្រូវបាន​ភ្ជាប់​ទៅ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ដែលអាច​តាមដាន​សកម្មភាព​បណ្តាញ​ផ្ទាល់ខ្លួន​របស់​អ្នក។"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"បាន​ដោះសោ​សម្រាប់ <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> កំពុង​ដំណើរការ"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"ឧបករណ៍​នឹង​ចាក់​សោ​រហូត​ដល់​អ្នក​ដោះ​សោ​ដោយ​ដៃ"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"ទទួល​បាន​ការ​ជូន​ដំណឹង​កាន់តែ​លឿន"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ឃើញ​ពួកវា​មុន​ពេល​ដោះ​សោ"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"បិទ"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ជាមួយអង្គគ្រប់គ្រងការជូនដំណឹងថាមពល អ្នកអាចកំណត់កម្រិតសំខាន់ពី 0 ទៅ 5 សម្រាប់ការជូនដំណឹងរបស់កម្មវិធី។ \n\n"<b>"កម្រិត 5"</b>" \n- បង្ហាញនៅផ្នែកខាងលើបញ្ជីជូនដំណឹង \n- អនុញ្ញាតការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n\n"<b>"កម្រិត 4"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n\n"<b>"កម្រិត 3"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n\n"<b>"កម្រិត 2"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n- មិនបន្លឺសំឡេង ឬញ័រ \n\n"<b>"កម្រិត 1"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n- មិនបន្លឺសំឡេង ឬញ័រ \n- លាក់ពីអេក្រង់ចាក់សោ និងរបារស្ថានភាព \n- បង្ហាញនៅផ្នែកខាងក្រោមបញ្ជីជូនដំណឹង \n\n"<b>"កម្រិត 0"</b>" \n- រារាំងការជូនដំណឹងទាំងអស់ពីកម្មវិធី"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ការ​ជូនដំណឹង"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"អ្នក​នឹង​មិន​ទទួល​បាន​ការ​ជូនដំណឹង​ទាំងនេះ​ទៀត​ទេ។"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"អ្នក​នឹង​មិន​ទទួល​បានការ​ជូនដំណឹង​ទាំងនេះ​ទៀត​ទេ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"ប្រភេទនៃការជូនដំណឹងចំនួន <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"កម្មវិធីនេះ​មិនមាន​ប្រភេទនៃ​ការជូនដំណឹង​ទេ"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"ការជូនដំណឹងពី​កម្មវិធីនេះមិនអាចបិទបានទេ"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">ប្រភេទនៃការ​ជូនដំណឹង 1 ក្នុង​ចំណោម <xliff:g id="NUMBER_1">%d</xliff:g> ដែលបានពី​កម្មវិធី​នេះ</item>
       <item quantity="one">ប្រភេទនៃការ​ជូនដំណឹង 1 ក្នុង​ចំណោម <xliff:g id="NUMBER_0">%d</xliff:g> ដែលបានពី​កម្មវិធី​នេះ</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"ការគ្រប់គ្រង​ការជូន​ដំណឹង"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"ជម្រើស​ផ្អាកការ​ជូនដំណឹង"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 នាទី"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 នាទី"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ម៉ោង"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ម៉ោង"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"មិន​ធ្វើវិញ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"បាន​ផ្អាក​រយៈពេល <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d ម៉ោង</item>
+      <item quantity="one">%d ម៉ោង</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d នាទី</item>
+      <item quantity="one">%d នាទី</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"ការប្រើប្រាស់ថ្ម"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"កម្មវិធីសន្សំថ្មមិនអាចប្រើបានអំឡុងពេលសាកថ្មទេ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"កម្មវិធីសន្សំថ្ម"</string>
@@ -753,7 +761,7 @@
     <string name="instant_apps_message" msgid="8116608994995104836">"កម្មវិធី​ប្រើ​ភ្លាមៗ​មិន​តម្រូវ​ឲ្យ​មានការ​ដំឡើង​ទេ។"</string>
     <string name="app_info" msgid="6856026610594615344">"ព័ត៌មាន​កម្មវិធី"</string>
     <string name="go_to_web" msgid="1106022723459948514">"ចូលទៅកាន់បណ្តាញ"</string>
-    <string name="mobile_data" msgid="7094582042819250762">"ទិន្នន័យ​ចល័ត"</string>
+    <string name="mobile_data" msgid="7094582042819250762">"ទិន្នន័យ​ទូរសព្ទចល័ត"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi បាន​បិទ"</string>
     <string name="bt_is_off" msgid="2640685272289706392">"ប៊្លូធូស​បាន​បិទ"</string>
     <string name="dnd_is_off" msgid="6167780215212497572">"មុខងារ​កុំរំខាន​បាន​បិទ"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"ជំនួស"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"កម្មវិធីដែលកំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"ចុចដើម្បីមើលព័ត៌មានលម្អិតអំពីការប្រើប្រាស់ទិន្នន័យ និងថ្ម"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"បិទទិន្នន័យ​ចល័ត?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings_car.xml b/packages/SystemUI/res/values-km/strings_car.xml
index 9648a5fb..5c9b1d6 100644
--- a/packages/SystemUI/res/values-km/strings_car.xml
+++ b/packages/SystemUI/res/values-km/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"បើកបរដោយសុវត្ថិភាព"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ត្រូវមានការគ្រប់គ្រងពេញលេញលើស្ថានភាពបើកបរ និងគោរពច្បាប់ដែលត្រូវអនុវត្តជានិច្ច។ ទិសដៅអាចនឹងមិនមានភាពសុក្រិត មិនពេញលេញ គ្រោះថ្នាក់ មិនសមស្រប ឬពាក់ព័ន្ធនឹងការឆ្លងកាត់តំបន់រដ្ឋបាល។ ព័ត៌មានផ្នែកអាជីវកម្មក៏អាចនឹងមិនមានភាពសុក្រិត ឬមិនពេញលេញផងដែរ។ ទិន្នន័យគឺមិនមែនបញ្ជូនបន្តផ្ទាល់នោះទេ ហើយភាពសុក្រិតនៃទីតាំងក៏មិនអាចធានាបានផងដែរ។ កុំកាន់ឧបករណ៍ចល័តរបស់អ្នក ឬប្រើកម្មវិធីដែលមិនមែនសម្រាប់ Android Auto ខណៈពេលកំពុងបើកបរ។"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"មិន​ស្គាល់"</string>
+    <string name="start_driving" msgid="864023351402918991">"ចាប់ផ្តើមបើកបរ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 096416e..1e376fc 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -259,10 +259,10 @@
     <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>
-    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"ಪರದೆಯನ್ನು ಪೋಟ್ರೇಟ್ ಓರಿಯಂಟೇಶನ್‍ನಲ್ಲಿ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"ಪರದೆಯನ್ನು ಪೋರ್ಟ್ರೇಟ್ ಓರಿಯಂಟೇಶನ್‍ನಲ್ಲಿ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ."</string>
     <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"ಪರದೆಯು ಈಗ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ತಿರುಗುತ್ತದೆ."</string>
     <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"ಪರದೆಯು ಇದೀಗ ಲ್ಯಾಂಡ್‌ಸ್ಕೇಪ್ ಒರಿಯಂಟೇಶನ್‌ನಲ್ಲಿ ಲಾಕ್ ಆಗಿದೆ."</string>
-    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"ಪರದೆಯು ಇದೀಗ ಪೋಟ್ರೇಟ್ ಒರಿಯಂಟೇಶನ್‌ನಲ್ಲಿ ಲಾಕ್ ಆಗಿದೆ."</string>
+    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"ಪರದೆಯು ಇದೀಗ ಪೋರ್ಟ್ರೇಟ್ ಒರಿಯಂಟೇಶನ್‌ನಲ್ಲಿ ಲಾಕ್ ಆಗಿದೆ."</string>
     <string name="dessert_case" msgid="1295161776223959221">"ಡೆಸರ್ಟ್ ಕೇಸ್"</string>
     <string name="start_dreams" msgid="5640361424498338327">"ಸ್ಕ್ರೀನ್ ಸೇವರ್"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ಇಥರ್ನೆಟ್"</string>
@@ -279,7 +279,7 @@
     <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"ಪರದೆಯನ್ನು ಸ್ವಯಂ-ತಿರುಗಿಸಿ"</string>
     <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"<xliff:g id="ID_1">%s</xliff:g> ಮೋಡ್"</string>
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"ತಿರುಗುವಿಕೆ ಲಾಕ್ ಆಗಿದೆ"</string>
-    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"ಪೋಟ್ರೇಟ್"</string>
+    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"ಪೋರ್ಟ್ರೇಟ್"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"ಲ್ಯಾಂಡ್‌ಸ್ಕೇಪ್"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"ಇನ್‌ಪುಟ್ ವಿಧಾನ"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"ಸ್ಥಳ"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"ಹೆಚ್ಚಿನ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"ಮುಗಿದಿದೆ"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"ಸಂಪರ್ಕಗೊಂಡಿದೆ, ಬ್ಯಾಟರಿ ಚಾರ್ಜ್‌ ಮಟ್ಟ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ಟೆಥರಿಂಗ್‌"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ಹಾಟ್‌ಸ್ಪಾಟ್"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"ನೀವು ಇಮೇಲ್‌ಗಳು, ಅಪ್ಲಿಕೇಶನ್‌ಗಳು, ಮತ್ತು ವೆಬ್‌ಸೈಟ್‌ಗಳನ್ನು ಒಳಗೊಂಡಂತೆ ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ನೆಟ್‌ವರ್ಕ್ ಚಟುವಟಿಕೆಯ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದಾದ <xliff:g id="APPLICATION">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವಿರಿ."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ ಅನ್ನು <xliff:g id="ORGANIZATION">%1$s</xliff:g> ನಿರ್ವಹಿಸುತ್ತಿದೆ. <xliff:g id="APPLICATION">%2$s</xliff:g> ಗೆ ಪ್ರೊಫೈಲ್ ಸಂಪರ್ಕಗೊಂಡಿರುವ ಕಾರಣ, ಅದು ನಿಮ್ಮ ಇಮೇಲ್‌ಗಳು, ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಹಾಗೂ ವೆಬ್‌ಸೈಟ್‌ಗಳೂ ಸೇರಿದಂತೆ ನೆಟ್‌ವರ್ಕ್ ಚಟುವಟಿಕೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು.\n\nಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ, ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ ಅನ್ನು <xliff:g id="ORGANIZATION">%1$s</xliff:g> ನಿರ್ವಹಿಸುತ್ತಿದೆ. <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ಗೆ ಪ್ರೊಫೈಲ್ ಸಂಪರ್ಕಗೊಂಡಿರುವ ಕಾರಣ, ಅದು ನಿಮ್ಮ ಇಮೇಲ್‌ಗಳು, ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ವೆಬ್‌ಸೈಟ್‌ಗಳೂ ಸೇರಿದಂತೆ ನೆಟ್‌ವರ್ಕ್ ಚಟುವಟಿಕೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು.\n\nನೀವು <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ಗೆ ಕೂಡಾ ಸಂಪರ್ಕಗೊಂಡಿದ್ದೀರಿ, ಇದು ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ನೆಟ್‌ವರ್ಕ್ ಚಟುವಟಿಕೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> ಗಾಗಿ ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ಚಾಲನೆಯಲ್ಲಿದೆ"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"ನೀವಾಗಿಯೇ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವವರೆಗೆ ಸಾಧನವು ಲಾಕ್‌ ಆಗಿಯೇ ಇರುತ್ತದೆ"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"ವೇಗವಾಗಿ ಅಧಿಸೂಚನೆಗಳನ್ನು ಪಡೆದುಕೊಳ್ಳಿ"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ನೀವು ಅನ್‌ಲಾಕ್‌ ಮಾಡುವ ಮೊದಲೇ ಅವುಗಳನ್ನು ನೋಡಿ"</string>
@@ -494,7 +497,7 @@
     <string name="stream_bluetooth_sco" msgid="2055645746402746292">"ಬ್ಲೂಟೂತ್‌"</string>
     <string name="stream_dtmf" msgid="2447177903892477915">"ಡ್ಯುಯಲ್‌ ಬಹು ಟೋನ್ ಆವರ್ತನೆ"</string>
     <string name="stream_accessibility" msgid="301136219144385106">"ಪ್ರವೇಶಿಸುವಿಕೆ"</string>
-    <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. ಅನ್‌ಮ್ಯೂಟ್‌ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+    <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. ಅನ್‌ಮ್ಯೂಟ್‌ ಮಾಡುವುದಕ್ಕಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. ಕಂಪನಕ್ಕೆ ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಪ್ರವೇಶಿಸುವಿಕೆ ಸೇವೆಗಳನ್ನು ಮ್ಯೂಟ್‌ ಮಾಡಬಹುದು."</string>
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಪ್ರವೇಶಿಸುವಿಕೆ ಸೇವೆಗಳನ್ನು ಮ್ಯೂಟ್‌ ಮಾಡಬಹುದು."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. ವೈಬ್ರೇಟ್ ಮಾಡಲು ಹೊಂದಿಸುವುದಕ್ಕಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ಆಫ್"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ಪವರ್ ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳ ಮೂಲಕ, ನೀವು ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಅಧಿಸೂಚನೆಗಳನ್ನು 0 ರಿಂದ 5 ರವರೆಗಿನ ಹಂತಗಳ ಪ್ರಾಮುಖ್ಯತೆಯನ್ನು ಹೊಂದಿಸಬಹುದು. \n\n"<b>"ಹಂತ 5"</b>" \n- ಮೇಲಿನ ಅಧಿಸೂಚನೆ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ಅನುಮತಿಸಿ \n- ಯಾವಾಗಲು ಇಣುಕು ನೋಟ \n\n"<b>"ಹಂತ 4"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಯಾವಾಗಲು ಇಣುಕು ನೋಟ\n\n"<b>"ಹಂತ 3"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n\n"<b>"ಹಂತ 2"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n- ಶಬ್ದ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಎಂದಿಗೂ ಮಾಡಬೇಡಿ \n\n"<b>"ಹಂತ 1"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n- ಶಬ್ದ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಎಂದಿಗೂ ಮಾಡಬೇಡಿ \n- ಸ್ಥಿತಿ ಪಟ್ಟಿ ಮತ್ತು ಲಾಕ್ ಪರದೆಯಿಂದ ಮರೆಮಾಡಿ \n- ಕೆಳಗಿನ ಅಧಿಸೂಚನೆ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ \n\n"<b>"ಹಂತ 0"</b>" \n- ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ನಿರ್ಬಂಧಿಸಿ"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ಅಧಿಸೂಚನೆಗಳು"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ನೀವು ಇನ್ನು ಮುಂದೆ ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಪಡೆಯುವುದಿಲ್ಲ."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ನೀವು ಇನ್ನು ಮುಂದೆ ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಪಡೆಯುವುದಿಲ್ಲ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ಅಧಿಸೂಚನೆ ವರ್ಗಗಳು"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಅಧಿಸೂಚನೆ ವರ್ಗಗಳನ್ನು ಹೊಂದಿಲ್ಲ"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"ಈ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆಫ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">ಈ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ <xliff:g id="NUMBER_1">%d</xliff:g> ಅಧಿಸೂಚನೆ ವರ್ಗಗಳಲ್ಲಿ 1 ವರ್ಗ</item>
       <item quantity="other">ಈ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ <xliff:g id="NUMBER_1">%d</xliff:g> ಅಧಿಸೂಚನೆ ವರ್ಗಗಳಲ್ಲಿ 1 ವರ್ಗ</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳು"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"ಅಧಿಸೂಚನೆ ಸ್ನೂಜ್ ಆಯ್ಕೆಗಳು"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 ನಿಮಿಷಗಳು"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 ನಿಮಿಷಗಳು"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ಗಂಟೆ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ಗಂಟೆಗಳು"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ರದ್ದುಮಾಡಿ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ಗೆ ಸ್ನೂಜ್ ಮಾಡಲಾಗಿದೆ"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d ಗಂಟೆಗಳು</item>
+      <item quantity="other">%d ಗಂಟೆಗಳು</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d ನಿಮಿಷಗಳು</item>
+      <item quantity="other">%d ನಿಮಿಷಗಳು</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"ಬ್ಯಾಟರಿ ಬಳಕೆ"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ಚಾರ್ಜಿಂಗ್ ಸಮಯದಲ್ಲಿ ಬ್ಯಾಟರಿ ಸೇವರ್‌‌ ಲಭ್ಯವಿರುವುದಿಲ್ಲ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ಬ್ಯಾಟರಿ ಸೇವರ್‌‌"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"ಬದಲಿಸಿ"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿವೆ"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"ಬ್ಯಾಟರಿ,ಡೇಟಾ ಬಳಕೆಯ ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"ಮೊಬೈಲ್ ಡೇಟಾ ಆಫ್ ಮಾಡಬೇಕೆ?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings_car.xml b/packages/SystemUI/res/values-kn/strings_car.xml
index e8e99c4..bc1f7fc 100644
--- a/packages/SystemUI/res/values-kn/strings_car.xml
+++ b/packages/SystemUI/res/values-kn/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ಸುರಕ್ಷಿತವಾಗಿ ಚಾಲನೆ ಮಾಡಿ"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ಚಾಲನೆ ಸ್ಥಿತಿಗಳ ಕುರಿತು ಸಂಪೂರ್ಣವಾಗಿ ತಿಳಿದುಕೊಳ್ಳಿ ಮತ್ತು ಅನ್ವಯವಾಗುವ ಕಾನೂನುಗಳನ್ನು ಯಾವಾಗಲೂ ಅನುಸರಿಸಿ. ದಿಕ್ಕುಗಳು ಸರಿಯಾಗಿ ಇಲ್ಲದಿರಬಹುದು, ಅಪೂರ್ಣವಾಗಿರಬಹುದು, ಅಪಾಯಕಾರಿಯಾಗಿರಬಹುದು, ಸೂಕ್ತವಾಗಿಲ್ಲದಿರಬಹುದು, ನಿಷೇಧಿಸಿರಬಹುದು ಅಥವಾ ನಿರ್ವಹಣೆ ಪ್ರದೇಶಗಳ ಮೂಲಕ ಹಾದು ಹೋಗಬೇಕಾಗಬಹುದು. ವ್ಯಾಪಾರ ಮಾಹಿತಿಯು ಸಹ ತಪ್ಪಾಗಿರಬಹುದು ಅಥವಾ ಅಪೂರ್ಣವಾಗಿರಬಹುದು. ಡೇಟಾ ನೈಜ ಸಮಯದ್ದಾಗಿರದಿರಬಹುದು ಮತ್ತು ಸ್ಥಳ ನಿಖರತೆಗೆ ಖಾತ್ರಿ ನೀಡಲಾಗುವುದಿಲ್ಲ. ನಿಮ್ಮ ಮೊಬೈಲ್ ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸಬೇಡಿ ಅಥವಾ ಚಾಲನೆ ಮಾಡುತ್ತಿರುವಾಗ Android Auto ಗೆ ಅಲ್ಲದಿರುವ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬಳಸಬೇಡಿ."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"ಅಪರಿಚಿತ"</string>
+    <string name="start_driving" msgid="864023351402918991">"ಡ್ರೈವ್ ಮಾಡಲು ಆರಂಭಿಸಿ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index ce2f47f..acc1949 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -242,9 +242,9 @@
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"충전 중"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G 데이터 사용 중지됨"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G 데이터 사용 중지됨"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"모바일 데이터가 일시 중지됨"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"모바일 데이터가 일시중지됨"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"데이터 사용 중지됨"</string>
-    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"설정한 데이터 한도에 도달했습니다. 더 이상 모바일 데이터를 사용하지 않습니다.\n\n계속하면 데이터 사용량에 따른 요금이 부과될 수 있습니다."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"설정한 데이터 한도에 도달했습니다. 더 이상 모바일 데이터를 사용하지 않습니다.\n\n계속하면 데이터 사용량에 따라 요금이 부과될 수 있습니다."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"재개"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"인터넷에 연결되지 않음"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi 연결됨"</string>
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"설정 더보기"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"완료"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"연결됨"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"연결됨, 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"연결 중..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"테더링"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"핫스팟"</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"<xliff:g id="APPLICATION">%1$s</xliff:g>에 연결되었습니다. 이 앱은 이메일, 앱, 웹사이트와 같은 내 개인 네트워크 활동을 모니터링할 수 있습니다."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"직장 프로필은 <xliff:g id="ORGANIZATION">%1$s</xliff:g>에서 관리합니다. 프로필이 <xliff:g id="APPLICATION">%2$s</xliff:g>에 연결되어 이메일, 앱, 웹사이트와 같은 직장 네트워크 활동을 모니터링할 수 있습니다.\n\n자세한 내용을 확인하려면 관리자에게 문의하세요."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"직장 프로필은 <xliff:g id="ORGANIZATION">%1$s</xliff:g>에서 관리합니다. 이 프로필은 <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>에 연결되어 이메일, 앱, 웹사이트와 같은 직장 네트워크 활동을 모니터링할 수 있습니다.\n\n개인 네트워크 활동을 모니터링할 수 있는 <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>에도 연결됩니다."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g>님 잠금 해제됨"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> 실행 중"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"수동으로 잠금 해제할 때까지 기기가 잠금 상태로 유지됩니다."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"알림을 더욱 빠르게 받기"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"잠금 해제하기 전에 알림을 봅니다."</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"사용 안함"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"전원 알림 컨트롤을 사용하면 앱 알림 관련 중요도를 0부터 5까지로 설정할 수 있습니다. \n\n"<b>"레벨 5"</b>" \n- 알림 목록 상단에 표시 \n- 전체 화면일 경우 알림 표시 허용 \n- 항상 엿보기 표시 \n\n"<b>"레벨 4"</b>" \n- 전체 화면에 알림 표시 금지 \n- 항상 엿보기 표시 \n\n"<b>"레벨 3"</b>" \n- 전체 화면에 알림 표시 금지 \n- 엿보기 표시 안함 \n\n"<b>"레벨 2"</b>" \n- 전체 화면에 알림 표시 금지 \n- 엿보기 표시 안함 \n- 소리나 진동으로 알리지 않음 \n\n"<b>"레벨 1"</b>" \n- 전체 화면에 알림 표시 금지 \n- 엿보기 표시 안함 \n- 소리나 진동으로 알리지 않음 \n- 잠금 화면 및 상태 표시줄에서 숨김 \n- 알림 목록 하단에 표시 \n\n"<b>"레벨 0"</b>" \n- 앱의 모든 알림 차단"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"알림"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"더 이상 다음의 알림을 받지 않습니다."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"더 이상 다음의 알림을 받지 않습니다."</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"알림 카테고리 <xliff:g id="NUMBER">%d</xliff:g>개"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"이 앱에는 알림 카테고리가 없습니다."</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"이 앱의 알림을 사용 중지할 수 없습니다."</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">이 앱에서 <xliff:g id="NUMBER_1">%d</xliff:g>개의 알림 카테고리 중 1개가 정의됨</item>
       <item quantity="one">이 앱에서 <xliff:g id="NUMBER_0">%d</xliff:g>개의 알림 카테고리 중 1개가 정의됨</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"알림 관리"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"알림 일시 중지 옵션"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15분"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30분"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1시간"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2시간"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"실행취소"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> 동안 일시 중지됨"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d시간</item>
+      <item quantity="one">%d시간</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d분</item>
+      <item quantity="one">%d분</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"배터리 사용량"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"충전하는 동안 배터리 세이버는 사용할 수 없습니다."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"배터리 세이버"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"바꾸기"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"백그라운드에서 실행 중인 앱"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"탭하여 배터리 및 데이터 사용량 확인"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"모바일 데이터를 사용 중지하시겠습니까?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings_car.xml b/packages/SystemUI/res/values-ko/strings_car.xml
index fcc2d7b..6d31bbf 100644
--- a/packages/SystemUI/res/values-ko/strings_car.xml
+++ b/packages/SystemUI/res/values-ko/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"안전 운전"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"도로 상황에 주의를 기울이고 관련 법규를 항상 준수하세요. 경로가 정확하지 않거나 불완전하거나 위험하거나 적합하지 않을 수 있으며 금지된 지역이나 여러 행정 구역을 통과할 수 있습니다. 비즈니스 정보 또한 부정확하거나 불완전할 수 있습니다. 데이터는 실시간이 아니며 위치의 정확도를 보증할 수 없습니다. 운전 중에 휴대기기를 조작하거나 Android Auto가 지원되지 않는 앱을 사용해서는 안 됩니다."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"알 수 없음"</string>
+    <string name="start_driving" msgid="864023351402918991">"운전 시작"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index aceb1c2..f27e97b 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -193,7 +193,7 @@
     <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wifi өчүрүлдү."</string>
     <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"Wifi күйгүзүлдү."</string>
     <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Мобилдик түйүн <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Батарей: <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Батарея: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"Учак режими өчүк."</string>
     <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"Учак режими күйүк."</string>
     <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Учак режими өчүрүлдү."</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Дагы жөндөөлөр"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Бүттү"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Туташкан"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Туташып турат, батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Туташууда…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Тетеринг"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Туташуу чекити"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Электрондук почта, колдонмолор жана вебсайттар сыяктуу тармактагы жеке аракеттериңизди тескей турган <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосуна туташып турасыз."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Жумуш профилиңизди <xliff:g id="ORGANIZATION">%1$s</xliff:g> башкарат. Ал электрондук почта, колдонмолор жана вебсайттар сыяктуу жумуш тармагыңыздагы аракеттерди көзөмөлдөй турган <xliff:g id="APPLICATION">%2$s</xliff:g> колдонмосуна туташкан.\n\nКөбүрөөк маалымат алуу үчүн администраторуңузга кайрылыңыз."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Жумуш профилиңизди <xliff:g id="ORGANIZATION">%1$s</xliff:g> башкарат. Ал электрондук почта, колдонмолор жана вебсайттар сыяктуу жумуш тармагыңыздагы аракеттерди көзөмөлдөй турган <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> колдонмосуна туташкан.\n\nМындан тышкары, тармактагы жеке аракеттериңизди көзөмөлдөгөн <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> колдонмосуна туташып турасыз."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> үчүн кулпусу ачылды"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> иштеп жатат"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Түзмөктүн кулпусу кол менен ачылмайынча кулпуланган бойдон алат"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Эскертмелерди тезирээк алуу"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Аларды кулпудан чыгараардан мурун көрүңүз"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Өчүк"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Бул функциянын жардамы менен ар бир колдонмо үчүн эскертменин маанилүүлүк деңгээлин 0дон 5ке чейин койсоңуз болот. \n\n"<b>"5-деңгээл"</b>" \n- Эскертмелер тизмесинин башында көрсөтүлсүн \n- Эскертмелер толук экранда көрсөтүлсүн \n- Калкып чыгуучу эскертмелерге уруксат берилсин \n\n"<b>"4-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге уруксат берилсин \n\n"<b>"3-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге тыюу салынсын \n\n"<b>"2-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге тыюу салынсын \n- Эч качан добуш чыгып же дирилдебесин \n\n"<b>"1-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге тыюу салынсын \n- Эч качан добуш чыгып же дирилдебесин \n- Кулпуланган экрандан жана абал тилкесинен жашырылсын \n- Эскертмелер тизмесинин аягында көрсөтүлсүн \n\n"<b>"0-деңгээл"</b>" \n- Колдонмодон алынган бардык эскертмелер бөгөттөлсүн"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Эскертмелер"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Мындан ары бул эскертмелер сизге жөнөтүлбөйт."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Мындан ары бул эскертмелер сизге жөнөтүлбөйт"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Эскертмелердин <xliff:g id="NUMBER">%d</xliff:g> категориясы"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Бул колдонмонун эскертме категориялары жок"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Бул колдонмонун эскертмелерин өчүрүүгө болбойт"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Бул колдонмодогу <xliff:g id="NUMBER_1">%d</xliff:g> эскертме категориянын ичинен 1 категория</item>
       <item quantity="one">Бул колдонмодогу <xliff:g id="NUMBER_0">%d</xliff:g> эскертме категориянын ичинен 1 категория</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"эскертмелерди башкаруу каражаттары"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"эскертмени тындыруу опциялары"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 мүнөт"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 мүнөт"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 саат"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 саат"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"КАЙТАРУУ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> тындырылды"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d саат</item>
+      <item quantity="one">%d саат</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d мүнөт</item>
+      <item quantity="one">%d мүнөт</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Батарея колдонулушу"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Батареяны үнөмдөгүч түзмөк кубатталып жатканда иштебейт"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Батареяны үнөмдөгүч"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Алмаштыруу"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Фондо иштеп жаткан колдонмолор"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Батареянын кубаты жана трафиктин көлөмү жөнүндө билүү үчүн таптап коюңуз"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Мобилдик Интернетти өчүрөсүзбү?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings_car.xml b/packages/SystemUI/res/values-ky/strings_car.xml
index 1d99ff2..51a46b9 100644
--- a/packages/SystemUI/res/values-ky/strings_car.xml
+++ b/packages/SystemUI/res/values-ky/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Коопсуздук эрежелерин сактаңыз"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Унаа айдап бара жатканда жолдогу шарттар менен эрежелерге ар дайым көңүл буруңуз. Багыттар так же толук эмес берилип, кесип өтүү үчүн опурталдуу же ылайыксыз болгон административдик аймактар аркылуу өтүшү мүмкүн. Ишканалар тууралуу маалымат да так же толук эмес болушу мүмкүн. Дайындар тез-тез жаңыртылып турбагандыктан, жайгашкан жердин так аныкталгандыгына кепилдик жок. Андыктан унаа айдап бара жатканда, мобилдик түзмөгүңүздү же Android Auto\'го арналбаган колдонмолорду пайдаланбаңыз."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Белгисиз"</string>
+    <string name="start_driving" msgid="864023351402918991">"Унаа айдап баштоо"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index d7f1200..3b792ed 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"​ການ​ຕັ້ງ​ຄ່າ​ເພີ່ມ​ເຕີມ"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"ແລ້ວໆ"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"ເຊື່ອມ​ຕໍ່ແລ້ວ"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"ເຊື່ອມຕໍ່ແລ້ວ, ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"ກຳລັງເຊື່ອມຕໍ່..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"​ການ​ປ່ອນ​ສັນ​ຍານ"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"​ຮັອດ​ສະ​ປອດ"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"ທ່ານເຊື່ອມຕໍ່ກັບ <xliff:g id="APPLICATION">%1$s</xliff:g> ແລ້ວ, ເຊິ່ງສາມາດຕິດຕາມການເຄື່ອນໄຫວເຄືອຂ່າຍສ່ວນຕົວຂອງທ່ານ ຮວມທັງອີເມວ, ​ແອັບ ແລະເວັບໄຊໄດ້."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານແມ່ນຖືກຈັດການໂດຍ <xliff:g id="ORGANIZATION">%1$s</xliff:g>. ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກດັ່ງກ່າວເຊື່ອມຕໍ່ຫາ <xliff:g id="APPLICATION">%2$s</xliff:g>, ເຊິ່ງສາມາດຕິດຕາມການເຄື່ອນໄຫວເຄືອຂ່າຍຂອງທ່ານ, ຮວມທັງອີເມວ, ແອັບ ແລະ ເວັບໄຊໄດ້.\nສຳລັບຂໍ້ມູນເພີ່ມເຕີມ, ໃຫ້ຕິດຕໍ່ຫາຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ\n."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານແມ່ນຖືກຈັດການໂດຍ <xliff:g id="ORGANIZATION">%1$s</xliff:g>. ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກດັ່ງກ່າວເຊື່ອມຕໍ່ຫາ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, ເຊິ່ງສາມາດຕິດຕາມການເຄື່ອນໄຫວເຄືອຂ່າຍຂອງທ່ານ, ຮວມທັງອີເມວ, ແອັບ ແລະ ເວັບໄຊໄດ້.\n\nນອກຈາກນັ້ນ, ທ່ານຍັງເຊື່ອມຕໍ່ຫາ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, ເຊິ່ງສາມາດຕິດຕາມການເຄື່ອນໄຫວເຄືອຂ່າຍສ່ວນຕົວຂອງທ່ານໄດ້."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"ປົດລັອກສຳລັບ <xliff:g id="USER_NAME">%1$s</xliff:g> ແລ້ວ"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ກຳລັງເຮັດວຽກຢູ່"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Device will stay locked until you manually unlock"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"ຮັບເອົາການ​ແຈ້ງເຕືອນ​ໄວຂຶ້ນ"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ເບິ່ງພວກ​ມັນກ່ອນ​ທ່ານຈະ​ປົດລັອກ"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ປິດ"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ດ້ວຍການຄວບຄຸມການແຈ້ງເຕືອນ, ທ່ານສາມາດຕັ້ງລະດັບຄວາມສຳຄັນຈາກ 0 ຮອດ 5 ໃຫ້ກັບການແຈ້ງເຕືອນແອັບໃດໜຶ່ງໄດ້. \n\n"<b>"ລະດັບ 5"</b>" \n- ສະແດງຢູ່ເທິງສຸດຂອງລາຍການແຈ້ງເຕືອນ \n- ອະນຸຍາດໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ແນມເບິ່ງທຸກເທື່ອ \n\n"<b>"ລະດັບ 4"</b>" \n- ກັນບໍ່ໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ແນມເບິ່ງທຸກເທື່ອ \n\n"<b>"ລະດັບ 3"</b>" \n- ກັນບໍ່ໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ບໍ່ແນມເບິ່ງ \n\n"<b>"ລະດັບ 2"</b>" \n- ກັນບໍ່ໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ບໍ່ແນມເບິ່ງ \n- ບໍ່ມີສຽງ ແລະ ບໍ່ມີການສັ່ນເຕືອນ \n\n"<b>"ລະດັບ 1"</b>" \n- ກັນບໍ່ໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ບໍ່ແນມເບິ່ງ \n- ບໍ່ມີສຽງ ແລະ ບໍ່ມີການສັ່ນເຕືອນ \n- ເຊື່ອງຈາກໜ້າຈໍລັອກ ແລະ ແຖບສະຖານະ \n- ສະແດງຢູ່ລຸ່ມສຸດຂອງລາຍການແຈ້ງເຕືອນ \n\n"<b>"ລະດັບ 0"</b>" \n- ປິດກັ້ນການແຈ້ງເຕືອນທັງໝົດຈາກແອັບ"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ການແຈ້ງເຕືອນ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ທ່ານຈະບໍ່ໄດ້ຮັບການແຈ້ງເຕືອນເຫຼົ່ານີ້ອີກຕໍ່ໄປ."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ທ່ານຈະບໍ່ໄດ້ຮັບການແຈ້ງເຕືອນເຫຼົ່ານີ້ອີກຕໍ່ໄປ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ໝວດໝູ່ການແຈ້ງເຕືອນ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ແອັບນີ້ບໍ່ມີໝວດໝູ່ການແຈ້ງເຕືອນ"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"ການແຈ້ງເຕືອນຈາກແອັບນີ້ບໍ່ສາມາດປິດໄວ້ໄດ້"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 ຈາກທັງໝົດ <xliff:g id="NUMBER_1">%d</xliff:g> ໝວດໝູ່ການແຈ້ງເຕືອນຈາກແອັບນີ້</item>
       <item quantity="one">1 ຈາກທັງໝົດ <xliff:g id="NUMBER_0">%d</xliff:g> ໝວດໝູ່ການແຈ້ງເຕືອນຈາກແອັບນີ້</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"ການຄວບຄຸມການແຈ້ງເຕືອນ"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"ຕົວເລືອກການເລື່ອນການແຈ້ງເຕືອນ"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 ນາທີ"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 ນາທີ"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ຊົ່ວໂມງ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ຊົ່ວໂມງ"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ຍົກເລີກ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"ເລື່ອນໄປ <xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ນາທີແລ້ວ"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d ຊົ່ວໂມງ</item>
+      <item quantity="one">%d ຊົ່ວໂມງ</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d ນາທີ</item>
+      <item quantity="one">%d ນາທີ</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"ການໃຊ້ແບັດເຕີຣີ"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ຕົວປະຢັດແບັດເຕີຣີບໍ່ມີໃຫ້ນຳໃຊ້ໃນລະຫວ່າງການສາກ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ຕົວປະຢັດ​ແບັດເຕີຣີ"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"ແທນທີ່"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"ແອັບທີ່ກຳລັງເຮັດວຽກໃນພື້ນຫຼັງ"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"ແຕະເພື່ອເບິ່ງລາຍລະອຽດການນຳໃຊ້ແບັດເຕີຣີ ແລະ ອິນເຕີເນັດ"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"ປິດອິນເຕີເນັດມືຖືໄວ້ບໍ?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings_car.xml b/packages/SystemUI/res/values-lo/strings_car.xml
index 3388f54..038e43b 100644
--- a/packages/SystemUI/res/values-lo/strings_car.xml
+++ b/packages/SystemUI/res/values-lo/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ຂັບຂີ່ຢ່າງປອດໄພ"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ຮູ້ຈັກສະພາບການຂັບຂີ່ຢ່າງຄົບຖ້ວນ ແລະ ປະຕິບັດຕາມກົດໝາຍທີ່ນຳໃຊ້ສະເໝີ. ຄຳແນະນຳເສັ້ນທາງອາດຈະບໍ່ຖືກຕ້ອງ, ບໍ່ຄົບຖ້ວນ, ອັນຕະລາຍ, ບໍ່ເໝາະສົມ, ຖືກຫ້າມ ຫຼື ກ່ຽວຂ້ອງກັບການຂ້າມເຂດປົກຄອງ. ຂໍ້ມູນທຸລະກິດອາດຈະບໍ່ຖືກຕ້ອງ ຫຼື ບໍ່ຄົບຖ້ວນ. ຂໍ້ມູນບໍ່ແມ່ນຂໍ້ມູນສົດ ແລະ ບໍ່ສາມາດຮັບປະກັນຄວາມຖືກຕ້ອງຂອງສະຖານທີ່ໄດ້. ຢ່າໃຊ້ອຸປະກອນມືຖືຂອງທ່ານ ຫຼື ໃຊ້ແອັບທີ່ບໍ່ມີໄວ້ສຳລັບ Android Auto ໃນຂະນະທີ່ຂັບຂີ່."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"ບໍ່​ຮູ້ຈັກ"</string>
+    <string name="start_driving" msgid="864023351402918991">"ເລີ່ມການຂັບ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 8b03861..d4c27b4f 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -314,6 +314,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Daugiau nustatymų"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Atlikta"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Prijungtas"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Prijungta, akumuliatorius <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Prisijungiama..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Susiejimas"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Viešosios interneto prieigos taškas"</string>
@@ -384,7 +385,7 @@
     <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Perjungti naudotoją, dabartinis naudotojas <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Dabartinis naudotojas <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Rodyti profilį"</string>
-    <string name="user_add_user" msgid="5110251524486079492">"Naudotojo pridėjimas"</string>
+    <string name="user_add_user" msgid="5110251524486079492">"Pridėti naudotoją"</string>
     <string name="user_new_user_name" msgid="426540612051178753">"Naujas naudotojas"</string>
     <string name="guest_nickname" msgid="8059989128963789678">"Svečias"</string>
     <string name="guest_new_guest" msgid="600537543078847803">"Pridėti svečią"</string>
@@ -471,6 +472,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Esate prisijungę prie programos „<xliff:g id="APPLICATION">%1$s</xliff:g>“, kuri gali stebėti asmeninio tinklo veiklą, įskaitant el. laiškus, programas ir svetaines."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Jūsų darbo profilį tvarko „<xliff:g id="ORGANIZATION">%1$s</xliff:g>“. Profilis susietas su programa „<xliff:g id="APPLICATION">%2$s</xliff:g>“, kuri gali stebėti jūsų tinklo veiklą, įskaitant el. laiškus, programas ir svetaines.\n\nJei reikia daugiau informacijos, susisiekite su administratoriumi."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Jūsų darbo profilį tvarko „<xliff:g id="ORGANIZATION">%1$s</xliff:g>“. Profilis susietas su programa „<xliff:g id="APPLICATION_WORK">%2$s</xliff:g>“, kuri gali stebėti jūsų tinklo veiklą, įskaitant el. laiškus, programas ir svetaines.\n\nTaip pat esate prisijungę prie programos „<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>“, kuri gali stebėti asmeninio tinklo veiklą."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Atrakinta (<xliff:g id="USER_NAME">%1$s</xliff:g>)"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"„<xliff:g id="TRUST_AGENT">%1$s</xliff:g>“ vykdoma"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Įrenginys liks užrakintas, kol neatrakinsite jo neautomatiniu būdu"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Greičiau gaukite pranešimus"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Peržiūrėti prieš atrakinant"</string>
@@ -552,9 +555,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Išjungta"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Naudodami pranešimų valdiklius galite nustatyti programos pranešimų svarbos lygį nuo 0 iki 5. \n\n"<b>"5 lygis"</b>" \n– Rodyti pranešimų sąrašo viršuje \n– Leisti pertraukti, kai veikia viso ekrano režimas \n– Visada rodyti pranešimus \n\n"<b>"4 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Visada rodyti pranešimus \n\n"<b>"3 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Niekada nerodyti pranešimų \n\n"<b>"2 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Niekada nerodyti pranešimų \n– Niekada neleisti garso ir nevibruoti \n\n"<b>"1 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Niekada nerodyti pranešimų \n– Niekada neleisti garso ir nevibruoti \n– Slėpti užrakinimo ekrane ir būsenos juostoje \n– Rodyti pranešimų sąrašo apačioje \n\n"<b>"0 lygis"</b>" \n– Blokuoti visus programos pranešimus"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Pranešimai"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Nebegausite šių pranešimų."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Nebegausite šių pranešimų"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Pranešimų kategorijų: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Šioje programoje nėra pranešimų kategorijų"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Šios programos pranešimų negalima išjungti"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 iš <xliff:g id="NUMBER_1">%d</xliff:g> šios programos pranešimų kategorijos</item>
       <item quantity="few">1 iš <xliff:g id="NUMBER_1">%d</xliff:g> šios programos pranešimų kategorijų</item>
@@ -578,12 +582,20 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"pranešimų valdikliai"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"pranešimų snaudimo parinktys"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 min."</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 min."</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 val."</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 val."</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ANULIUOTI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Nustatyta snausti <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d valanda</item>
+      <item quantity="few">%d valandos</item>
+      <item quantity="many">%d valandos</item>
+      <item quantity="other">%d valandų</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d minutė</item>
+      <item quantity="few">%d minutės</item>
+      <item quantity="many">%d minutės</item>
+      <item quantity="other">%d minučių</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Akum. energ. vartoj."</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akumuliatoriaus tausojimo priemonė nepasiekiama įkraunant"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akumuliatoriaus tausojimo priemonė"</string>
@@ -773,4 +785,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Pakeisti"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Programos, veikiančios fone"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Palieskite ir sužinokite išsamios informacijos apie akumuliatoriaus bei duomenų naudojimą"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Išjungti mobiliojo ryšio duomenis?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings_car.xml b/packages/SystemUI/res/values-lt/strings_car.xml
index 03d656a..4bdd5a7 100644
--- a/packages/SystemUI/res/values-lt/strings_car.xml
+++ b/packages/SystemUI/res/values-lt/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vairuokite saugiai"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Visada atsižvelkite į vairavimo sąlygas ir laikykitės galiojančių įstatymų. Nuorodos gali būti netikslios, neužbaigtos, pavojingos, netinkamos, draudžiamos ar nukreipiančios per administracines sritis. Įmonių informacija taip pat gali būti netiksli ar neužbaigta. Duomenys nėra teikiami realiuoju laiku ir vietovių tikslumo negalima garantuoti. Vairuodami nenaudokite mobiliojo įrenginio ar programų, kurios nėra skirtos „Android Auto“."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Nežinoma"</string>
+    <string name="start_driving" msgid="864023351402918991">"Pradėti vairuoti"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 26f4370..0fac57f 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Vairāk iestatījumu"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Gatavs"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Pievienota"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Savienojums izveidots, akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Notiek savienojuma izveide…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Piesaiste"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Tīklājs"</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Ir izveidots savienojums ar lietotni <xliff:g id="APPLICATION">%1$s</xliff:g>, kas var pārraudzīt jūsu tīklā veiktās privātās darbības, tostarp e-pasta ziņojumus, lietotnes un vietnes."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Jūsu darba profilu pārvalda <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profils ir saistīts ar lietotni <xliff:g id="APPLICATION">%2$s</xliff:g>, kura var pārraudzīt jūsu tīklā veiktās darbības, tostarp saņemtos un nosūtītos e-pasta ziņojumus, izmantotās lietotnes un apmeklētās tīmekļa vietnes.\n\nLai iegūtu plašāku informāciju, sazinieties ar administratoru."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Jūsu darba profilu pārvalda <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profils ir saistīts ar lietotni <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, kura var pārraudzīt jūsu tīklā veiktās darbības, tostarp saņemtos un nosūtītos e-pasta ziņojumus, instalētās lietotnes un apmeklētās tīmekļa vietnes.\n\nIr izveidots savienojums ar lietotni <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, kas var pārraudzīt jūsu tīklā veiktās privātās darbības, tostarp saņemtos un nosūtītos e-pasta ziņojumus, instalētās lietotnes un apmeklētās tīmekļa vietnes."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Atbloķēta lietotājam <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> darbojas"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Ierīce būs bloķēta, līdz to manuāli atbloķēsiet."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Saņemiet paziņojumus ātrāk"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Skatiet tos pirms atbloķēšanas."</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Izslēgts"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Izmantojot barošanas paziņojumu vadīklas, varat lietotnes paziņojumiem iestatīt svarīguma līmeni (no 0 līdz 5). \n\n"<b>"5. līmenis"</b>" \n- Tiek rādīts paziņojumu saraksta augšdaļā \n- Tiek atļauta pilnekrāna režīma pārtraukšana \n- Ieskats vienmēr atļauts \n\n"<b>"4. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats vienmēr atļauts \n\n"<b>"3. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats nav atļauts \n\n"<b>"2. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats nav atļauts \n- Nav atļautas skaņas un vibrosignāls \n\n"<b>"1. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats nav atļauts \n- Nav atļautas skaņas un vibrosignāls \n- Paziņojumi tiek paslēpti bloķēšanas ekrānā un statusa joslā \n- Paziņojumi tiek rādīti paziņojumu saraksta apakšdaļā \n\n"<b>"0. līmenis"</b>" \n- Visi lietotnes paziņojumi tiek bloķēti"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Paziņojumi"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Jūs vairs nesaņemsiet šos paziņojumus."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Jūs vairs nesaņemsiet šos paziņojumus"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> paziņojumu kategorijas"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Paziņojumu kategorijas šajā lietotnē nav pieejamas."</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Paziņojumus no šīs lietotnes nevar izslēgt"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="zero">1 no <xliff:g id="NUMBER_1">%d</xliff:g> šīs lietotnes paziņojumu kategorijām.</item>
       <item quantity="one">1 no <xliff:g id="NUMBER_1">%d</xliff:g> šīs lietotnes paziņojumu kategorijas.</item>
@@ -574,12 +578,18 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"paziņojumu vadīklas"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"paziņojumu atlikšanas opcijas"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minūtes"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minūtes"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 stunda"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 stundas"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ATSAUKT"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Atlikts: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="zero">%d stundas</item>
+      <item quantity="one">%d stunda</item>
+      <item quantity="other">%d stundas</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="zero">%d minūtes</item>
+      <item quantity="one">%d minūte</item>
+      <item quantity="other">%d minūtes</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Akumulatora lietojums"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akumulatora jaudas taupīšanas režīms uzlādes laikā nav pieejams."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akumulatora jaudas taupīšanas režīms"</string>
@@ -769,4 +779,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Aizstāt"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Lietotnes, kas darbojas fonā"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Pieskarieties, lai skatītu detalizētu informāciju par akumulatora un datu lietojumu"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vai izslēgt mobilos datus?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings_car.xml b/packages/SystemUI/res/values-lv/strings_car.xml
index 0171624..d804f86 100644
--- a/packages/SystemUI/res/values-lv/strings_car.xml
+++ b/packages/SystemUI/res/values-lv/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Droša braukšana"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Pievērsiet visu uzmanību braukšanas apstākļiem un vienmēr ievērojiet piemērojamos tiesību aktus. Norādes var būt neprecīzas, nepilnīgas, bīstamas, nepiemērotas, aizliegtas vai var ietvert administratīvo teritoriju šķērsošanu. Arī uzņēmumu informācija var būt neprecīza vai nepilnīga. Dati netiek nodrošināti reāllaikā, un netiek garantēta atrašanās vietu precizitāte. Vadot transportlīdzekli, nelietojiet mobilo ierīci rokās un neizmantojiet lietotnes, kas nav paredzētas pakalpojumam Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Nezināms"</string>
+    <string name="start_driving" msgid="864023351402918991">"Sākt braukšanu"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mcc311-mnc480/config.xml b/packages/SystemUI/res/values-mcc311-mnc480/config.xml
new file mode 100644
index 0000000..7dadae7
--- /dev/null
+++ b/packages/SystemUI/res/values-mcc311-mnc480/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources>
+    <!-- Enable 5 bar signal strength icon -->
+    <bool name="config_inflateSignalStrength">true</bool>
+</resources>
+
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 4d4e227..f2992ad 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Повеќе поставки"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Готово"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Поврзано"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Поврзан, ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Се поврзува..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Поврзување"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Точка на пристап"</string>
@@ -352,8 +353,8 @@
     <string name="description_target_search" msgid="3091587249776033139">"Пребарај"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Лизгај нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Лизгај налево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Нема да ве вознемируваат звуци и вибрации, освен од аларми, потсетници, настани и повикувачи што ќе ги наведете. Сѐ уште ќе слушате сѐ што ќе изберете да пуштите, што опфаќа музика, видеа и игри."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Нема да ве вознемируваат звуци и вибрации, освен од аларми. Сѐ уште ќе слушате сѐ што ќе изберете да пуштите, што опфаќа музика, видеа и игри."</string>
+    <string name="zen_priority_introduction" msgid="7577965386868311310">"Нема да ве вознемируваат звуци и вибрации, освен од аларми, потсетници, настани и повикувачи што ќе ги наведете. Сѐ уште ќе слушате сѐ што ќе изберете да пуштите, како музика, видеа и игри."</string>
+    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Нема да ве вознемируваат звуци и вибрации, освен од аларми. Сѐ уште ќе слушате сѐ што ќе изберете да пуштите, како музика, видеа и игри."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Приспособи"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ова ги блокира СИТЕ звуци и вибрации, вклучувајќи ги и оние од алармите, музиката, видеата и игрите. Сѐ уште ќе може да воспоставувате телефонски повици."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Ова ги блокира СИТЕ звуци и вибрации, вклучувајќи ги и оние од алармите, музиката, видеата и игрите."</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Поврзани сте на <xliff:g id="APPLICATION">%1$s</xliff:g>, којашто може да ја следи вашата лична активност на мрежата, вклучувајќи ги е-пораките, апликациите и веб-локациите."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> управува со вашиот работен профил. Профилот е поврзан на <xliff:g id="APPLICATION">%2$s</xliff:g>, што може да ја следи вашата работна активност на мрежата, заедно со е-пораките, апликациите и веб-сајтовите.\n\nЗа повеќе информации, контактирајте со вашиот администратор."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> управува со вашиот работен профил. Профилот е поврзан на <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, што може да ја следи вашата работна активност на мрежата, заедно со е-пораките, апликациите и веб-сајтовите.\n\nПоврзани сте и на <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, што може да ја следи вашата лична активност на мрежата."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Отклучен за <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> работи"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Уредот ќе остане заклучен додека рачно не го отклучите"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Добивајте известувања побрзо"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Видете ги пред да отклучите"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Исклучено"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Со контролите за известувањата за напојување, може да поставите ниво на важност од 0 до 5 за известувањата на која било апликација. \n\n"<b>"Ниво 5"</b>" \n- Прикажувај на врвот на списокот со известувања \n- Дозволи прекин во цел екран \n- Секогаш користи појавување \n\n"<b>"Ниво 4"</b>" \n- Спречи прекин во цел екран \n- Секогаш користи појавување \n\n"<b>"Ниво 3"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n\n"<b>"Ниво 2"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n- Без звук и вибрации \n\n"<b>"Ниво 1"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n- Без звук и вибрации \n- Сокриј од заклучен екран и статусна лента \n- Прикажувај на дното на списокот со известувања \n\n"<b>"Ниво 0"</b>" \n- Блокирај ги сите известувања од апликацијата"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Известувања"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Веќе нема да ги добивате овие известувања."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Веќе нема да ги добивате овие известувања"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> категории известувања"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Апликацијава нема катерии известувања"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Известувањата од апликацијава не може да се исклучат"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 од <xliff:g id="NUMBER_1">%d</xliff:g> категорија известувања од апликацијава</item>
       <item quantity="other">1 од <xliff:g id="NUMBER_1">%d</xliff:g> категории известувања од апликацијава</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"контроли за известувањето"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"опции за одложување на известувањето"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минути"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 минути"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 час"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 часа"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ВРАТИ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Одложено за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d час</item>
+      <item quantity="other">%d часа</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d минута</item>
+      <item quantity="other">%d минути</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Користење батерија"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Штедачот на батерија не е достапен при полнење"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Штедач на батерија"</string>
@@ -588,8 +596,8 @@
     <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Стрелка налево"</string>
     <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Стрелка надесно"</string>
     <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Центар"</string>
-    <string name="keyboard_key_tab" msgid="3871485650463164476">"Картичка"</string>
-    <string name="keyboard_key_space" msgid="2499861316311153293">"Празно место"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
     <string name="keyboard_key_enter" msgid="5739632123216118137">"Внеси"</string>
     <string name="keyboard_key_backspace" msgid="1559580097512385854">"Бришење наназад"</string>
     <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Пушти/Паузирај"</string>
@@ -748,7 +756,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Предупредувања"</string>
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Слики од екранот"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Општи пораки"</string>
-    <string name="notification_channel_storage" msgid="3077205683020695313">"Меморија"</string>
+    <string name="notification_channel_storage" msgid="3077205683020695313">"Капацитет"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Инстант апликации"</string>
     <string name="instant_apps_message" msgid="8116608994995104836">"Инстант апликациите нема потреба да се инсталираат."</string>
     <string name="app_info" msgid="6856026610594615344">"Информации за апликација"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Замени"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Апликациите се извршуваат во заднина"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Допрете за детали за батеријата и потрошениот сообраќај"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Да се исклучи мобилниот интернет?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings_car.xml b/packages/SystemUI/res/values-mk/strings_car.xml
index f5ed824..9220ccb 100644
--- a/packages/SystemUI/res/values-mk/strings_car.xml
+++ b/packages/SystemUI/res/values-mk/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Возете безбедно"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Секогаш бидете известени за условите за возење и почитувајте ги важечките закони. Насоките може да бидат неточни, нецелосни, опасни, несоодветни, забранети или да вклучуваат премин преку административни области. Бизнис информациите исто така може да бидат неточни или нецелосни. Податоците не се даваат во реално време и не може да се гарантира точноста на локацијата. Не ракувајте со вашиот мобилен уред и не користете апликации што не се наменети за Android Auto додека возите."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Непознато"</string>
+    <string name="start_driving" msgid="864023351402918991">"Започнете да возите"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 67d7404..c50f143 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -34,14 +34,14 @@
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"അറിയിപ്പുകൾ"</string>
     <string name="battery_low_title" msgid="6456385927409742437">"ബാറ്ററി കുറവാണ്"</string>
     <string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> ശേഷിക്കുന്നു"</string>
-    <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> ശേഷിക്കുന്നു. ബാറ്ററി സേവർ ഓണാണ്."</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> ശേഷിക്കുന്നു. ബാറ്ററി ലാഭിക്കൽ ഓണാണ്."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"USB ചാർജ്ജുചെയ്യൽ പിന്തുണയ്ക്കുന്നില്ല.\nഅതിന്റെ അനുബന്ധ ചാർജ്ജർ മാത്രം ഉപയോഗിക്കുക."</string>
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB ചാർജ്ജുചെയ്യൽ പിന്തുണച്ചില്ല."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"വിതരണം ചെയ്‌ത ചാർജ്ജർ മാത്രം ഉപയോഗിക്കുക."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"ക്രമീകരണം"</string>
-    <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"ബാറ്ററി സേവർ ഓണാക്കണോ?"</string>
+    <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"ബാറ്ററി ലാഭിക്കൽ ഓണാക്കണോ?"</string>
     <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"ഓൺ ചെയ്യുക"</string>
-    <string name="battery_saver_start_action" msgid="5576697451677486320">"ബാറ്ററി സേവർ ഓണാക്കുക"</string>
+    <string name="battery_saver_start_action" msgid="5576697451677486320">"ബാറ്ററി ലാഭിക്കൽ ഓണാക്കുക"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"ക്രമീകരണം"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"വൈഫൈ"</string>
     <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"സ്‌ക്രീൻ സ്വയമേ തിരിക്കുക"</string>
@@ -84,7 +84,7 @@
     <string name="accessibility_home" msgid="8217216074895377641">"ഹോം"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"മെനു"</string>
     <string name="accessibility_accessibility_button" msgid="7601252764577607915">"ഉപയോഗസഹായി"</string>
-    <string name="accessibility_recent" msgid="5208608566793607626">"കാഴ്ച"</string>
+    <string name="accessibility_recent" msgid="5208608566793607626">"അവലോകനം"</string>
     <string name="accessibility_search_light" msgid="1103867596330271848">"തിരയൽ"</string>
     <string name="accessibility_camera_button" msgid="8064671582820358152">"ക്യാമറ"</string>
     <string name="accessibility_phone_button" msgid="6738112589538563574">"ഫോണ്‍"</string>
@@ -186,9 +186,9 @@
     <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>
-    <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"കാഴ്ച."</string>
+    <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"അവലോകനം."</string>
     <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"ഔദ്യോഗിക ലോക്ക് സ്ക്രീൻ"</string>
-    <string name="accessibility_desc_close" msgid="7479755364962766729">"അടയ്‌ക്കുക"</string>
+    <string name="accessibility_desc_close" msgid="7479755364962766729">"അവസാനിപ്പിക്കുക"</string>
     <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
     <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"വൈഫൈ ഓഫാക്കി."</string>
     <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"വൈഫൈ ഓണാക്കി."</string>
@@ -293,7 +293,7 @@
     <string name="quick_settings_user_title" msgid="4467690427642392403">"ഉപയോക്താവ്"</string>
     <string name="quick_settings_user_new_user" msgid="9030521362023479778">"പുതിയ ഉപയോക്താവ്"</string>
     <string name="quick_settings_wifi_label" msgid="9135344704899546041">"വൈഫൈ"</string>
-    <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"കണ‌ക്റ്റുചെയ്‌തിട്ടില്ല"</string>
+    <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"കണ‌ക്റ്റ് ചെയ്‌തിട്ടില്ല"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"നെറ്റ്‌വർക്ക് ഒന്നുമില്ല"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"വൈഫൈ ഓഫുചെയ്യുക"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"വൈഫൈ ഓണാണ്"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"കൂടുതൽ ക്രമീകരണങ്ങൾ"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"പൂർത്തിയാക്കി"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"കണക്‌റ്റുചെയ്‌തു"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"കണക്‌റ്റുചെയ്‌തു, ബാറ്ററി നില <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"കണക്റ്റുചെയ്യുന്നു..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ടെതറിംഗ്"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ഹോട്ട്‌സ്‌പോട്ട്"</string>
@@ -403,9 +404,9 @@
     <string name="user_remove_user_title" msgid="4681256956076895559">"ഉപയോക്താവിനെ ഇല്ലാതാക്കണോ?"</string>
     <string name="user_remove_user_message" msgid="1453218013959498039">"ഈ ഉപയോക്താവിന്റെ എല്ലാ ആപ്സും ഡാറ്റയും ഇല്ലാതാക്കും."</string>
     <string name="user_remove_user_remove" msgid="7479275741742178297">"നീക്കംചെയ്യുക"</string>
-    <string name="battery_saver_notification_title" msgid="237918726750955859">"ബാറ്ററി സേവർ ഓണാണ്"</string>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"ബാറ്ററി ലാഭിക്കൽ ഓണാണ്"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"പ്രവർത്തനവും പശ്ചാത്തല ഡാറ്റയും കുറയ്‌ക്കുന്നു"</string>
-    <string name="battery_saver_notification_action_text" msgid="109158658238110382">"ബാറ്ററി സേവർ ഓഫാക്കുക"</string>
+    <string name="battery_saver_notification_action_text" msgid="109158658238110382">"ബാറ്ററി ലാഭിക്കൽ ഓഫാക്കുക"</string>
     <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>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"നിങ്ങൾ <xliff:g id="APPLICATION">%1$s</xliff:g> ആപ്പിലേക്ക് കണക്റ്റുചെയ്‌തിരിക്കുന്നു, ഇമെയിലുകൾ, ആപ്‌സ്, വെബ്‌സൈറ്റുകൾ എന്നിവ ഉൾപ്പെടെ നെറ്റ്‌വർക്ക് ആക്റ്റിവിറ്റി നിരീക്ഷിക്കാൻ ഈ ആപ്പിന് കഴിയും."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ആണ് നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈൽ മാനേജുചെയ്യുന്നത്. <xliff:g id="APPLICATION">%2$s</xliff:g> ആപ്പിലേക്ക് പ്രൊഫൈൽ കണക്റ്റുചെയ്‌തിരിക്കുന്നു, അതിന് ഇമെയിലുകൾ, ആപ്പുകൾ, വെബ്‌സൈറ്റുകൾ എന്നിവ ഉൾപ്പെടെ നിങ്ങളുടെ ഔദ്യോഗിക നെറ്റ്‌വർക്ക് ആക്റ്റിവിറ്റി നിരീക്ഷിക്കാനാകും.\n\nകൂടുതൽ വിവരങ്ങൾക്ക് നിങ്ങളുടെ അഡ്‌മിനെ ബന്ധപ്പെടുക."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ആണ് നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈൽ മാനേജുചെയ്യുന്നത്. <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ആപ്പിലേക്ക് പ്രൊഫൈൽ കണക്റ്റുചെയ്‌തിരിക്കുന്നു, അതിന് ഇമെയിലുകൾ, ആപ്പുകൾ, വെബ്‌സൈറ്റുകൾ എന്നിവ ഉൾപ്പെടെ നിങ്ങളുടെ ഔദ്യോഗിക നെറ്റ്‌വർക്ക് ആക്റ്റിവിറ്റി നിരീക്ഷിക്കാനാകും.\n\n<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ആപ്പിലേക്കും നിങ്ങൾ കണക്റ്റുചെയ്‌തിരിക്കുന്നു, അതിന് നിങ്ങളുടെ വ്യക്തിഗത നെറ്റ്‌വർക്ക് ആക്റ്റിവിറ്റി നിരീക്ഷിക്കാനാകും."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> എന്നയാൾക്കായി അൺലോക്കുചെയ്‌തു"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> റൺ ചെയ്യുന്നു"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"നിങ്ങൾ സ്വമേധയാ അൺലോക്കുചെയ്യുന്നതുവരെ ഉപകരണം ലോക്കുചെയ്‌തതായി തുടരും"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"അറിയിപ്പുകൾ വേഗത്തിൽ സ്വീകരിക്കുക"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"അൺലോക്കുചെയ്യുന്നതിന് മുമ്പ് അവ കാണുക"</string>
@@ -485,7 +488,7 @@
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"അടുത്ത തവണ നിങ്ങൾ അത് ക്രമീകരണങ്ങളിൽ ഓണാക്കുമ്പോൾ അത് വീണ്ടും ദൃശ്യമാകും."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"മറയ്‌ക്കുക"</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"നിങ്ങൾ ഉപയോഗിക്കുന്നത് ഔദ്യോഗിക പ്രൊഫൈലാണ്"</string>
-    <string name="stream_voice_call" msgid="4410002696470423714">"കോള്‍ ചെയ്യുക"</string>
+    <string name="stream_voice_call" msgid="4410002696470423714">"കോള്‍"</string>
     <string name="stream_system" msgid="7493299064422163147">"സിസ്റ്റം"</string>
     <string name="stream_ring" msgid="8213049469184048338">"റിംഗുചെയ്യുക"</string>
     <string name="stream_music" msgid="9086982948697544342">"മീഡിയ"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ഓഫ്"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"പവർ അറിയിപ്പ് നിയന്ത്രണം ഉപയോഗിച്ച്, ഒരു ആപ്പിനായുള്ള അറിയിപ്പുകൾക്ക് 0 മുതൽ 5 വരെയുള്ള പ്രാധാന്യ ലെവലുകളിലൊന്ന് നിങ്ങൾക്ക് സജ്ജമാക്കാവുന്നതാണ്. \n\n"<b>"ലെവൽ 5"</b>" \n- അറിയിപ്പ് ലിസ്റ്റിന്റെ മുകളിൽ കാണിക്കുക \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം അനുവദിക്കുക \n- എല്ലായ്പ്പോഴും ദൃശ്യമാക്കുക \n\n"<b>"ലെവൽ 4"</b>" \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം തടയുക \n- എല്ലായ്പ്പോഴും ദൃശ്യമാക്കുക \n\n"<b>"ലെവൽ 3"</b>" \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം തടയുക \n- ഒരിക്കലും സൃശ്യമാക്കരുത് \n\n"<b>"ലെവൽ 2"</b>" \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം തടയുക \n- ഒരിക്കലും ദൃശ്യമാക്കരുത് \n- ഒരിക്കലും ശബ്ദവും വൈബ്രേഷനും ഉണ്ടാക്കരുത് \n\n"<b>"ലെവൽ 1"</b>" \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം തടയുക \n- ഒരിക്കലും ദൃശ്യമാക്കരുത് \n- ഒരിക്കലും ശബ്ദവും വൈബ്രേഷനും ഉണ്ടാക്കരുത് \n- ലോക്ക് സ്ക്രീനിൽ നിന്നും സ്റ്റാറ്റസ് ബാറിൽ നിന്നും മറയ്ക്കുക \n- അറിയിപ്പ് ലിസ്റ്റിന്റെ അടിയിൽ കാണിക്കുക \n\n"<b>"ലെവൽ 0"</b>" \n- ആപ്പിൽ നിന്നുള്ള എല്ലാ അറിയിപ്പുകളും ബ്ലോക്കുചെയ്യുക"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"അറിയിപ്പുകൾ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"നിങ്ങൾക്ക് ഈ അറിയിപ്പുകൾ ഇനിയങ്ങോട്ട് ലഭിക്കില്ല."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"നിങ്ങൾക്ക് ഇനി ഈ അറിയിപ്പുകൾ ലഭിക്കില്ല"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> അറിയിപ്പ് വിഭാഗങ്ങൾ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ഈ ആപ്പിന് അറിയിപ്പ് വിഭാഗങ്ങളില്ല"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"ഈ ആപ്പിൽ നിന്നുള്ള അറിയിപ്പുകൾ ഓഫാക്കാൻ കഴിയില്ല"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">ഈ ആപ്പിൽ നിന്ന് 1 / <xliff:g id="NUMBER_1">%d</xliff:g> അറിയിപ്പ് വിഭാഗങ്ങൾ</item>
       <item quantity="one">ഈ ആപ്പിൽ നിന്ന് 1 / <xliff:g id="NUMBER_0">%d</xliff:g> അറിയിപ്പ് വിഭാഗം</item>
@@ -570,15 +574,19 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"അറിയിപ്പ് നിയന്ത്രണങ്ങൾ"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"അറിയിപ്പ് സ്‌നൂസ് ഓപ്ഷനുകൾ"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 മിനിറ്റ്"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 മിനിറ്റ്"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"ഒരു മണിക്കൂർ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 മണിക്കൂർ"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"പഴയപടിയാക്കുക"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> സമയത്തേക്ക് സ്‌നൂസ് ‌ചെയ്‌തു"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d മണിക്കൂർ</item>
+      <item quantity="one">%d മണിക്കൂർ</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d മിനിറ്റ്</item>
+      <item quantity="one">%d മിനിറ്റ്</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"ബാറ്ററി ഉപയോഗം"</string>
-    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ചാർജുചെയ്യുന്ന സമയത്ത് ബാറ്ററി സേവർ ലഭ്യമല്ല"</string>
-    <string name="battery_detail_switch_title" msgid="6285872470260795421">"ബാറ്ററി സേവർ"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ചാർജുചെയ്യുന്ന സമയത്ത് ബാറ്ററി ലാഭിക്കൽ നടക്കില്ല"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"ബാറ്ററി ലാഭിക്കൽ"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"പ്രവർത്തനവും പശ്ചാത്തല ഡാറ്റയും കുറയ്‌ക്കുന്നു"</string>
     <string name="keyboard_key_button_template" msgid="6230056639734377300">"ബട്ടൺ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="2243500072071305073">"ഹോം"</string>
@@ -716,7 +724,7 @@
     <string name="tuner_lock_screen" msgid="5755818559638850294">"ലോക്ക് സ്‌ക്രീൻ"</string>
     <string name="pip_phone_expand" msgid="5889780005575693909">"വികസിപ്പിക്കുക"</string>
     <string name="pip_phone_minimize" msgid="1079119422589131792">"ചെറുതാക്കുക‍"</string>
-    <string name="pip_phone_close" msgid="8416647892889710330">"അടയ്‌ക്കുക"</string>
+    <string name="pip_phone_close" msgid="8416647892889710330">"അവസാനിപ്പിക്കുക"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"തള്ളിക്കളയാൻ താഴേക്ക് വലിച്ചിടുക"</string>
     <string name="pip_menu_title" msgid="3328510504196964712">"\'ചിത്രത്തിനുള്ളിൽ ചിത്രം\' മെനു"</string>
     <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ചിത്രത്തിനുള്ളിലെ ചിത്രത്തിലാണ്"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"മാറ്റിസ്ഥാപിക്കുക"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"ആപ്പുകൾ പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുന്നു"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"ബാറ്ററി, ഡാറ്റ ഉപയോഗം എന്നിവയുടെ വിശദാംശങ്ങളറിയാൻ ടാപ്പുചെയ്യുക"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"മൊബൈൽ ഡാറ്റ ഓഫാക്കണോ?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings_car.xml b/packages/SystemUI/res/values-ml/strings_car.xml
index b53029c..eb4e1e6 100644
--- a/packages/SystemUI/res/values-ml/strings_car.xml
+++ b/packages/SystemUI/res/values-ml/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"സുരക്ഷിതമായി ഡ്രൈവ് ചെയ്യുക"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ഡ്രൈവിംഗ് സാഹചര്യങ്ങളെ കുറിച്ച് നല്ലവണ്ണം അറിഞ്ഞുവയ്ക്കുക, എല്ലായ്പ്പോഴും ബാധകമായ നിയമങ്ങൾ അനുസരിക്കുക. ദിശാസൂചനകൾ കൃത്യമല്ലാത്തതും അപൂർണ്ണവും അപകടകരവും അനുയോജ്യമല്ലാത്തതും നിരോധിക്കപ്പെട്ടതും അഡ്‌മിനിസ്ട്രേറ്റീവ് ഏരിയകൾ അതിലംഘിച്ച് പോകേണ്ടതുമായിരിക്കാം. വിവരങ്ങൾ തത്സമയം എടുത്തിട്ടുള്ളതല്ല, അതിനാൽ ലൊക്കേഷൻ കൃത്യത ഉറപ്പാക്കാൻ കഴിയില്ല. ഡ്രൈവ് ചെയ്യുന്ന സമയത്ത് മൊബൈൽ ഉപകരണങ്ങളോ Android Auto-യ്ക്കായി ഉദ്ദേശിക്കപ്പെട്ടിട്ടില്ലാത്ത ആപ്‌സോ കൈകാര്യം ചെയ്യരുത്"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"അറിഞ്ഞുകൂടാത്തത്"</string>
+    <string name="start_driving" msgid="864023351402918991">"ഡ്രൈവ് ചെയ്തുതുടങ്ങുക"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index ec0dcee..f59046a 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -308,6 +308,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Өөр тохиргоо"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Дууссан"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Холбогдсон"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Холбогдсон, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Холбогдож байна..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Модем болгох"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Сүлжээний цэг"</string>
@@ -465,6 +466,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Та имэйл, апп, вэб хуудас зэрэг хувийн сүлжээнийхээ үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон байна."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Таны ажлын профайлыг <xliff:g id="ORGANIZATION">%1$s</xliff:g> удирддаг. Энэ нь таны имэйл, апп, вэб хуудас зэрэг ажлын сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION">%2$s</xliff:g>-д холбогдсон. \n\nДэлгэрэнгүй мэдээллийг авахын тулд админтай холбогдоно уу."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Таны ажлын профайлыг <xliff:g id="ORGANIZATION">%1$s</xliff:g> удирддаг. Энэ нь таны имэйл, апп, вэб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>-тай холбогдсон. \n\nМөн таны сүлжээний хувийн үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>-д холбогдсон байна."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g>-н түгжээг тайлсан"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ажиллаж байна"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Таныг гараар нээх хүртэл төхөөрөмж түгжээтэй байх болно"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Мэдэгдлийг хурдан авах"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Түгжээг тайлахын өмнө үзнэ үү"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Идэвхгүй"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Тэжээлийн мэдэгдлийн удирдлагын тусламжтайгаар та апп-н мэдэгдэлд 0-5 хүртэлх ач холбогдлын түвшин тогтоох боломжтой. \n\n"<b>"5-р түвшин"</b>" \n- Мэдэгдлийн жагсаалтын хамгийн дээр харуулна \n- Бүтэн дэлгэцэд саад болно \n- Дэлгэцэд тогтмол гарч ирнэ \n\n"<b>"4-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд тогтмол гарч ирнэ \n\n"<b>"3-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд хэзээ ч гарч ирэхгүй \n\n"<b>"2-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд хэзээ ч гарч ирэхгүй \n- Дуу болон чичиргээ хэзээ ч гаргахгүй \n\n"<b>"1-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд хэзээ ч гарч ирэхгүй \n- Дуу болон чичиргээ хэзээ ч гаргахгүй \n- Түгжигдсэн дэлгэц болон статусын самбараас нууна \n- Мэдэгдлийн жагсаалтын доор харуулна \n\n"<b>"0-р түвшин"</b>" \n- Энэ апп-н бүх мэдэгдлийг блоклоно"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Мэдэгдэл"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ta цаашид мэдэгдэл авахгүй."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ta цаашид эдгээр мэдэгдлийг авахгүй"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> мэдэгдлийн ангилал"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Энэ апп-д мэдэгдлийн категори алга"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Энэ аппын мэдэгдлийг унтраах боломжгүй"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Энэ аппын <xliff:g id="NUMBER_1">%d</xliff:g> мэдэгдлийн категорийн 1</item>
       <item quantity="one">Энэ аппын <xliff:g id="NUMBER_0">%d</xliff:g> мэдэгдлийн категорийн 1</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"мэдэгдлийн удирдлага"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"мэдэгдэл түр хойшлуулагчийн сонголт"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минут"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 минут"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 цаг"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 цаг"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"БУЦААХ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>-д түр хойшлуулсан"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d цаг</item>
+      <item quantity="one">%d цаг</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d минут</item>
+      <item quantity="one">%d минут</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Тэжээл ашиглалт"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Цэнэглэх үед тэжээл хэмнэгч ажиллахгүй"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Тэжээл хэмнэгч"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Солих"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Цаана ажиллаж буй апп"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Мобайл датаг унтраах уу?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings_car.xml b/packages/SystemUI/res/values-mn/strings_car.xml
index d48580f..74b983a 100644
--- a/packages/SystemUI/res/values-mn/strings_car.xml
+++ b/packages/SystemUI/res/values-mn/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Жолооны аюулгүй байдал"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Жолоодох нөхцөлийн талаар бүрэн ойлгож, холбогдох дүрэм журмыг мөрдөөрэй. Чиглэл нь тодорхой бус, гүйцэт бус, аюултай, тохиромжгүй, хориглосон эсвэл тусгай хамгаалалттай газар нутагт нэвтэрсэн байж болзошгүй. Бизнесийн мэдээлэл мөн адил тохиромжгүй эсвэл гүйцэт бус байна. Өгөгдөл нь тухайн цаг хугацааных биш учир байршлыг зөв тодорхойлсон эсэхийг батлах боломжгүй. Жолоодож байхдаа гар утсаа болон Android Автод зориулаагүй апп-г бүү ашиглаарай."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Тодорхойгүй"</string>
+    <string name="start_driving" msgid="864023351402918991">"Жолоо барьж эхлэх"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr-land/strings.xml b/packages/SystemUI/res/values-mr-land/strings.xml
index fd3ba77..01728d3 100644
--- a/packages/SystemUI/res/values-mr-land/strings.xml
+++ b/packages/SystemUI/res/values-mr-land/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="toast_rotation_locked" msgid="7609673011431556092">"स्‍क्रीन आता भूदृश्य अभिमुखतेत लॉक केली आहे."</string>
+    <string name="toast_rotation_locked" msgid="7609673011431556092">"स्‍क्रीन आता लॅंडस्केप ओरिएंटेशनमध्ये लॉक केली आहे."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index fd6b0c3..05ed38e 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -45,21 +45,21 @@
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"सेटिंग्ज"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"वाय-फाय"</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>
+    <string name="bluetooth_tethered" msgid="7094101612161133267">"ब्लूटूथ टेदर केले"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"इनपुट पद्धती सेट करा"</string>
     <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"वास्तविक कीबोर्ड"</string>
     <string name="usb_device_permission_prompt" msgid="834698001271562057">"USB डिव्हाइसवर प्रवेश करण्यासाठी <xliff:g id="APPLICATION">%1$s</xliff:g> अॅप ला अनुमती द्यायची?"</string>
     <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"अ‍ॅप <xliff:g id="APPLICATION">%1$s</xliff:g> ला USB उपसाधनात प्रवेश करण्‍याची अनुमती द्यायची?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"हे USB डिव्हाइस कनेक्ट केलेले असते तेव्हा <xliff:g id="ACTIVITY">%1$s</xliff:g> उघडायचे?"</string>
     <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"हे USB उपसाधन कनेक्ट केलेले असते तेव्हा <xliff:g id="ACTIVITY">%1$s</xliff:g> उघडायचे?"</string>
-    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"स्थापित केलेले अॅप्स या USB उपसाधनासह कार्य करत नाहीत. <xliff:g id="URL">%1$s</xliff:g> येथे या उपसाधनाविषयी अधिक जाणून घ्या"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"इंस्टॉल केलेले अॅप्स या USB उपसाधनासह कार्य करत नाहीत. <xliff:g id="URL">%1$s</xliff:g> येथे या उपसाधनाविषयी अधिक जाणून घ्या"</string>
     <string name="title_usb_accessory" msgid="4966265263465181372">"USB उपसाधन"</string>
     <string name="label_view" msgid="6304565553218192990">"पहा"</string>
-    <string name="always_use_device" msgid="1450287437017315906">"या USB डिव्‍हाइससाठी डीफॉल्‍टनुसार वापरा"</string>
-    <string name="always_use_accessory" msgid="1210954576979621596">"या USB उपसाधनासाठी डीफॉल्‍टनुसार वापरा"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"या USB डीव्‍हाइससाठी डीफॉल्‍टनुसार वापरा"</string>
+    <string name="always_use_accessory" msgid="1210954576979621596">"या USB अॅक्सेसरीसाठी डीफॉल्‍टनुसार वापरा"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"USB डीबग करण्यास अनुमती द्यायची?"</string>
     <string name="usb_debugging_message" msgid="2220143855912376496">"संगणकाची RSA की फिंगरप्रिंट ही आहे:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"या संगणकावरून नेहमी अनुमती द्या"</string>
@@ -79,12 +79,12 @@
     <string name="usb_preference_title" msgid="6551050377388882787">"USB फाईल स्थानांतरण पर्याय"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"मीडिया प्लेअर म्हणून माउंट करा (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"कॅमेरा म्हणून माउंट करा (PTP)"</string>
-    <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac साठी Android फाईल स्थानांतर अॅप स्थापित करा"</string>
-    <string name="accessibility_back" msgid="567011538994429120">"परत"</string>
-    <string name="accessibility_home" msgid="8217216074895377641">"मुख्‍यपृष्‍ठ"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac साठी Android फाईल स्थानांतर अॅप इंस्टॉल करा"</string>
+    <string name="accessibility_back" msgid="567011538994429120">"मागे"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"होम"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"मेनू"</string>
     <string name="accessibility_accessibility_button" msgid="7601252764577607915">"प्रवेशयोग्यता"</string>
-    <string name="accessibility_recent" msgid="5208608566793607626">"विहंगावलोकन"</string>
+    <string name="accessibility_recent" msgid="5208608566793607626">"अवलोकन"</string>
     <string name="accessibility_search_light" msgid="1103867596330271848">"शोधा"</string>
     <string name="accessibility_camera_button" msgid="8064671582820358152">"कॅमेरा"</string>
     <string name="accessibility_phone_button" msgid="6738112589538563574">"फोन"</string>
@@ -100,8 +100,8 @@
     <string name="cancel" msgid="6442560571259935130">"रद्द करा"</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>
-    <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"ब्लूटुथ डिस्कनेक्ट केले."</string>
+    <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ब्लूटूथ कनेक्‍ट केले."</string>
+    <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"ब्लूटूथ डिस्कनेक्ट केले."</string>
     <string name="accessibility_no_battery" msgid="358343022352820946">"बॅटरी नाही."</string>
     <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"बॅटरी एक बार."</string>
     <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"बॅटरी दोन बार."</string>
@@ -155,7 +155,7 @@
     <string name="accessibility_cell_data" msgid="5326139158682385073">"मोबाइल डेटा"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"मोबाइल डेटा चालू आहे"</string>
     <string name="accessibility_cell_data_off" msgid="443267573897409704">"मोबाइल डेटा बंद आहे"</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ब्लूटुथ टिथरिंग."</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ब्लूटूथ टेदरिंग."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"विमान मोड."</string>
     <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN चालू."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"सिम कार्ड नाही."</string>
@@ -177,8 +177,8 @@
     <string name="accessibility_work_mode" msgid="2478631941714607225">"कार्य मोड"</string>
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> डिसमिस करा."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> डिसमिस केला."</string>
-    <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"अलीकडील सर्व अनुप्रयोग डिसमिस झाले."</string>
-    <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> अनुप्रयोग माहिती उघडा."</string>
+    <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"अलीकडील सर्व अॅप्लिकेशन डिसमिस झाले."</string>
+    <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> अॅप्लिकेशन माहिती उघडा."</string>
     <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> प्रारंभ करीत आहे."</string>
     <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
     <string name="accessibility_notification_dismissed" msgid="854211387186306927">"सूचना डिसमिस केल्या."</string>
@@ -186,7 +186,7 @@
     <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>
-    <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"विहंगावलोकन."</string>
+    <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"अवलोकन."</string>
     <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"कार्य लॉक स्क्रीन"</string>
     <string name="accessibility_desc_close" msgid="7479755364962766729">"बंद करा"</string>
     <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
@@ -205,13 +205,13 @@
     <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"व्यत्यय आणू नका बंद."</string>
     <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"व्यत्यय आणू नका बंद करा"</string>
     <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"व्यत्यय आणू नका चालू करा"</string>
-    <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"ब्लूटुथ."</string>
-    <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"ब्लूटुथ बंद."</string>
-    <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"ब्लूटुथ चालू."</string>
-    <string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"ब्लूटुथ कनेक्ट करत आहे."</string>
-    <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"ब्लूटुथ कनेक्‍ट केले."</string>
-    <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"ब्लूटुथ बंद केले."</string>
-    <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"ब्लूटुथ चालू केले."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"ब्लूटूथ."</string>
+    <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"ब्लूटूथ बंद."</string>
+    <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"ब्लूटूथ चालू."</string>
+    <string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"ब्लूटूथ कनेक्ट करत आहे."</string>
+    <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"ब्लूटूथ कनेक्‍ट केले."</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"ब्लूटूथ बंद केले."</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"ब्लूटूथ चालू केले."</string>
     <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"स्थान अहवाल बंद."</string>
     <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"स्थान अहवाल चालू."</string>
     <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"स्थान अहवाल बंद केला."</string>
@@ -236,7 +236,7 @@
     <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"कार्य मोड चालू केला."</string>
     <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"डेटा सर्व्हर बंद केला."</string>
     <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"डेटा सर्व्हर चालू केला."</string>
-    <string name="accessibility_brightness" msgid="8003681285547803095">"प्रदर्शन चमक"</string>
+    <string name="accessibility_brightness" msgid="8003681285547803095">"डिस्प्ले चमक"</string>
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"चार्ज होत आहे"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G डेटास विराम दिला आहे"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G डेटास विराम दिला आहे"</string>
@@ -258,10 +258,10 @@
     <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>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"लॅंडस्केप ओरिएंटेशनमध्ये स्क्रीन लॉक केली आहे."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"पोर्ट्रेट अभिमुखतेमध्ये स्क्रीन लॉक केली आहे."</string>
     <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"स्क्रीन आता स्वयंचलितपणे फिरेल."</string>
-    <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"स्‍क्रीन आता भूदृश्य अभिमुखतेत लॉक केली आहे."</string>
+    <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"स्‍क्रीन आता लॅंडस्केप ओरिएंटेशनमध्ये लॉक केली आहे."</string>
     <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"स्क्रीन आता पोर्ट्रेट अभिमुखतेत लॉक केली आहे."</string>
     <string name="dessert_case" msgid="1295161776223959221">"मिष्ठान्न प्रकरण"</string>
     <string name="start_dreams" msgid="5640361424498338327">"स्क्रीन सेव्हर"</string>
@@ -270,9 +270,9 @@
     <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_none_label" msgid="5025477807123029478">"संपूर्ण शांतता"</string>
-    <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"ब्लूटुथ"</string>
-    <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"ब्लूटुथ (<xliff:g id="NUMBER">%d</xliff:g> डिव्हाइसेस)"</string>
-    <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"ब्लूटुथ बंद"</string>
+    <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"ब्लूटूथ"</string>
+    <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"ब्लूटूथ (<xliff:g id="NUMBER">%d</xliff:g> डिव्हाइस)"</string>
+    <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"ब्लूटूथ बंद"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"कोणतेही जोडलेले डिव्हाइसेस उपलब्ध नाहीत"</string>
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"चमक"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"स्वयं-फिरवा"</string>
@@ -280,7 +280,7 @@
     <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"<xliff:g id="ID_1">%s</xliff:g> मोड"</string>
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"फिरविणे लॉक केले"</string>
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"पोर्ट्रेट"</string>
-    <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"भूदृश्य"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"लॅंडस्केप"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"इनपुट पद्धत"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"स्थान"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"स्थान बंद"</string>
@@ -297,7 +297,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"नेटवर्क नाही"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"वाय-फाय बंद"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"वाय-फाय चालू"</string>
-    <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Wi-Fi नेटवर्क उपलब्‍ध नाहीत"</string>
+    <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"वाय-फाय नेटवर्क उपलब्‍ध नाहीत"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"कास्‍ट करा"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"कास्ट करत आहे"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"निनावी डिव्हाइस"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"अधिक सेटिंग्ज"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"पूर्ण झाले"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"कनेक्ट केलेले"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"कनेक्ट केलेले आहे, बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"कनेक्ट करीत आहे..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"टेदरिंग"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"हॉटस्पॉट"</string>
@@ -329,7 +330,7 @@
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC सक्षम केले आहे"</string>
     <string name="recents_empty_message" msgid="808480104164008572">"अलीकडील कोणतेही आयटम नाहीत"</string>
     <string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"आपण सर्वकाही साफ केले"</string>
-    <string name="recents_app_info_button_label" msgid="2890317189376000030">"अनुप्रयोग माहिती"</string>
+    <string name="recents_app_info_button_label" msgid="2890317189376000030">"अॅप्लिकेशन माहिती"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"स्‍क्रीन पिन करणे"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"शोधा"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> प्रारंभ करणे शक्य झाले नाही."</string>
@@ -353,7 +354,7 @@
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> साठी वर स्लाइड करा."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> साठी डावीकडे स्लाइड करा."</string>
     <string name="zen_priority_introduction" msgid="7577965386868311310">"अलार्म, रिमाइंडर्स, इव्‍हेंट आणि तुम्ही निश्चित केलेल्या कॉलरचा अपवाद वगळता तुम्हाला कोणत्याही आवाज आणि कंपनांचा व्यत्त्यय आणला जाणार नाही. तसे असले तरीही तुम्ही प्ले करायचे ठरवलेले कोणतेही संगीत, व्हिडिओ आणि गेमचे आवाज चालू ठेवले जातील."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"अलार्मचा अपवाद सोडल्यास तुम्हाला कोणत्याही आवाज आणि कंपनांचा व्यत्त्यय आणला जाणार नाही. तसे असले तरीही तुम्ही प्ले करायचे ठरवलेले कोणतेही संगीत, व्हिडिओ आणि गेमचे आवाज चालू ठेवले जातील."</string>
+    <string name="zen_alarms_introduction" msgid="7034415210361973827">"अलार्मचा अपवाद सोडल्यास तुम्हाला कोणत्याही आवाज आणि कंपनांचा व्यत्यय आणला जाणार नाही. तसे असले तरीही तुम्ही प्ले करायचे ठरवलेले कोणतेही संगीत, व्हिडिओ आणि गेमचे आवाज चालू ठेवले जातील."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"सानुकूलित करा"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"हे अलार्म, संगीत, व्हिडिओ आणि गेम यासह, सर्व आवाज आणि कंपने अवरोधित करते. आपण तरीही फोन कॉल करण्यात सक्षम व्हाल."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"हे अलार्म, संगीत, व्हिडिओ आणि गेम यासह, सर्व आवाज आणि कंपने अवरोधित करते."</string>
@@ -361,7 +362,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"खाली कमी तातडीच्या सूचना"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"उघडण्यासाठी पुन्हा टॅप करा"</string>
     <string name="keyguard_unlock" msgid="8043466894212841998">"अनलॉक करण्यासाठी स्वाइप करा"</string>
-    <string name="do_disclosure_generic" msgid="5615898451805157556">"हे डिव्हाइस आपल्या संस्थेने व्यवस्थापित केले आहे"</string>
+    <string name="do_disclosure_generic" msgid="5615898451805157556">"हे डिव्हाइस तुमची संस्था व्यवस्थापित करते"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ने व्यवस्थापित केले आहे"</string>
     <string name="phone_hint" msgid="4872890986869209950">"फोनसाठी चिन्हावरून स्वाइप करा"</string>
     <string name="voice_hint" msgid="8939888732119726665">"व्हॉइस सहाय्यासाठी चिन्हावरून स्वाइप करा"</string>
@@ -390,7 +391,7 @@
     <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"काढा"</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_wipe" msgid="5065558566939858884">"येथून सुरू करा"</string>
     <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"होय, सुरु ठेवा"</string>
     <string name="guest_notification_title" msgid="1585278533840603063">"अतिथी वापरकर्ता"</string>
     <string name="guest_notification_text" msgid="335747957734796689">"अ‍ॅप्स आणि डेटा हटविण्‍यासाठी, अतिथी वापरकर्ता काढा"</string>
@@ -399,28 +400,28 @@
     <string name="user_logout_notification_text" msgid="3350262809611876284">"वर्तमान वापरकर्ता लॉगआउट करा"</string>
     <string name="user_logout_notification_action" msgid="1195428991423425062">"वापरकर्त्यास लॉगआउट करा"</string>
     <string name="user_add_user_title" msgid="4553596395824132638">"नवीन वापरकर्ता जोडायचा?"</string>
-    <string name="user_add_user_message_short" msgid="2161624834066214559">"आपण एक नवीन वापरकर्ता जोडता तेव्हा, त्या व्यक्तीने त्यांचे स्थान सेट करणे आवश्यक असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अॅप्स अद्यतनित करू शकतो."</string>
+    <string name="user_add_user_message_short" msgid="2161624834066214559">"आपण एक नवीन वापरकर्ता जोडता तेव्हा, त्या व्यक्तीने त्यांचे स्थान सेट करणे आवश्यक असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अॅप्स अपडेट करू शकतो."</string>
     <string name="user_remove_user_title" msgid="4681256956076895559">"वापरकर्त्यास काढायचे?"</string>
     <string name="user_remove_user_message" msgid="1453218013959498039">"या वापरकर्त्याचे सर्व अॅप्स आणि डेटा काढून टाकला जाईल."</string>
     <string name="user_remove_user_remove" msgid="7479275741742178297">"काढा"</string>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"बॅटरी बचतकर्ता चालू आहे"</string>
-    <string name="battery_saver_notification_text" msgid="820318788126672692">"कार्यप्रदर्शन आणि पार्श्वभूमी डेटा कमी करते"</string>
+    <string name="battery_saver_notification_text" msgid="820318788126672692">"कामगिरी आणि पार्श्वभूमीवरील डेटा कमी करते"</string>
     <string name="battery_saver_notification_action_text" msgid="109158658238110382">"बॅटरी बचतकर्ता बंद करा"</string>
     <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="media_projection_action_text" msgid="8470872969457985954">"आता प्रारंभ करा"</string>
+    <string name="media_projection_action_text" msgid="8470872969457985954">"आता सुरू करा"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"सूचना नाहीत"</string>
     <string name="profile_owned_footer" msgid="8021888108553696069">"प्रोफाईलचे परीक्षण केले जाऊ शकते"</string>
     <string name="vpn_footer" msgid="2388611096129106812">"नेटवर्कचे परीक्षण केले जाऊ शकते"</string>
     <string name="branded_vpn_footer" msgid="2168111859226496230">"नेटवर्कचे परीक्षण केले जाऊ शकते"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="6645176135063957394">"आपली संस्था हे डिव्हाइस व्यवस्थापित करते आणि नेटवर्क रहदारीचे परीक्षण करू शकते"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="370622174777570853">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> हे डिव्हाइस व्यवस्थापित करते आणि नेटवर्क रहदारीचे परीक्षण करू शकते"</string>
-    <string name="quick_settings_disclosure_management_named_vpn" msgid="1085137869053332307">"डिव्हाइस आपल्या संस्थेद्वारे व्यवस्थापित केले जाते आणि ते <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्ट केलेले आहे"</string>
+    <string name="quick_settings_disclosure_management_named_vpn" msgid="1085137869053332307">"डिव्हाइस तुमच्या संस्थेद्वारे व्यवस्थापित केले जाते आणि ते <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्ट केलेले आहे"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="6290456493852584017">"डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते आणि ते <xliff:g id="VPN_APP">%2$s</xliff:g> शी कनेक्ट केलेले आहे"</string>
-    <string name="quick_settings_disclosure_management" msgid="3294967280853150271">"डिव्हाइस आपल्या संस्थेद्वारे व्यवस्थापित आहे"</string>
+    <string name="quick_settings_disclosure_management" msgid="3294967280853150271">"डिव्हाइस तुमच्या संस्थेद्वारे व्यवस्थापित आहे"</string>
     <string name="quick_settings_disclosure_named_management" msgid="1059403025094542908">"डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते"</string>
-    <string name="quick_settings_disclosure_management_vpns" msgid="3698767349925266482">"डिव्हाइस आपल्या संस्थेद्वारे व्यवस्थापित केले जाते आणि ते VPN शी कनेक्ट केलेले आहे"</string>
+    <string name="quick_settings_disclosure_management_vpns" msgid="3698767349925266482">"डिव्हाइस तुमच्या संस्थेद्वारे व्यवस्थापित केले जाते आणि ते VPN शी कनेक्ट केलेले आहे"</string>
     <string name="quick_settings_disclosure_named_management_vpns" msgid="7777821385318891527">"डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते आणि ते VPN शी कनेक्ट केलेले आहे"</string>
     <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="5125463987558278215">"आपली संस्था आपल्या कार्य प्रोफाइलमधील नेटवर्क रहदारीचे परीक्षण करू शकते"</string>
     <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8973606847896650284">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> आपल्या कार्य प्रोफाइलमधील नेटवर्क रहदारीचे परीक्षण करू शकते"</string>
@@ -438,18 +439,18 @@
     <string name="disable_vpn" msgid="4435534311510272506">"VPN अक्षम करा"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"VPN डिस्कनेक्ट करा"</string>
     <string name="monitoring_button_view_policies" msgid="100913612638514424">"धोरणे पहा"</string>
-    <string name="monitoring_description_named_management" msgid="5281789135578986303">"तुमचे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> व्‍यवस्‍थापित करते.\n\nतुमचा प्रशासक सेटिंग्ज, कॉर्पोरेट अॅक्सेस, अॅप्स, आपल्या डिव्हाइसशी संबंधित डेटा आणि आपल्या डिव्हाइसच्या ठिकाणाची माहिती मॉनिटर करू आणि व्‍यवस्‍थापित करू शकतो.\n\nआणखी माहितीसाठी, आपल्या प्रशासकाशी संपर्क साधा."</string>
-    <string name="monitoring_description_management" msgid="4573721970278370790">"तुमचे डिव्हाइस तुमची संस्‍था व्‍यवस्‍थापित करते.\n\nतुमचा प्रशासक सेटिंग्ज, कॉर्पोरेट अॅक्सेस, अॅप्स, आपल्या डिव्हाइसशी संबंधित डेटा आणि आपल्या डिव्हाइसच्या ठिकाणाची माहिती मॉनिटर करू आणि व्‍यवस्‍थापित करू शकतो.\n\nआणखी माहितीसाठी, आपल्या प्रशासकाशी संपर्क साधा."</string>
-    <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"आपल्या संस्थेने या डिव्हाइसवर प्रमाणपत्र अधिकार स्थापित केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
-    <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"आपल्या संस्थेने आपल्या कार्य प्रोफाइलवर प्रमाणपत्र अधिकार स्थापित केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
-    <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"या डिव्हाइसवर प्रमाणपत्र अधिकार स्थापित केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
+    <string name="monitoring_description_named_management" msgid="5281789135578986303">"तुमचे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> व्यवस्थापित करते.\n\nतुमचा प्रशासक सेटिंग्ज, कॉर्पोरेट अॅक्सेस, अॅप्स, तुमच्या डिव्हाइस शी संबंधित डेटा आणि तुमच्या डिव्हाइस च्या ठिकाणाची माहिती मॉनिटर करू शकते आणि ती व्यवस्थापित करू शकतो.\n\nआणखी माहितीसाठी, तुमच्या प्रशासकाशी संपर्क साधा."</string>
+    <string name="monitoring_description_management" msgid="4573721970278370790">"तुमचे डिव्हाइस तुमची संस्‍था व्यवस्थापित करते.\n\nतुमचा प्रशासक सेटिंग्ज, कॉर्पोरेट अॅक्सेस, अॅप्स, तुमच्या डिव्हाइस शी संबंधित डेटा आणि तुमच्या डिव्हाइस च्या ठिकाणाची माहिती मॉनिटर करू शकतो आणि ती व्यवस्थापित करू शकतो.\n\nआणखी माहितीसाठी, तुमच्या प्रशासकाशी संपर्क साधा."</string>
+    <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"आपल्या संस्थेने या डिव्हाइसवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
+    <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"आपल्या संस्थेने आपल्या कार्य प्रोफाइलवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
+    <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"या डिव्हाइसवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
     <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"आपल्या प्रशासकाने नेटवर्क लॉगिंग चालू केले आहे, जे आपल्या डिव्हाइसवरील रहदारीचे परीक्षण करते."</string>
     <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"तुम्‍ही <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसहित आपल्‍या नेटवर्क क्रिया मॉनिटर करू शकते."</string>
     <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"तुम्‍ही <xliff:g id="VPN_APP_0">%1$s</xliff:g> आणि <xliff:g id="VPN_APP_1">%2$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसहित आपल्‍या नेटवर्क क्रिया मॉनिटर करू शकते."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"आपले कार्य प्रोफाइल <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या नेटवर्क क्रियाकलापाचे परीक्षण करू शकते."</string>
     <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"आपले वैयक्तिक प्रोफाइल <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या नेटवर्क क्रियाकलापाचे परीक्षण करू शकते."</string>
-    <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"आपले डिव्हाइस <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> ने व्यवस्थापित केले आहे."</string>
-    <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"आपले डिव्हाइस व्यवस्थापित करण्यासाठी <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> वापरते."</string>
+    <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"तुमचे डिव्हाइस <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> ने व्यवस्थापित केले आहे."</string>
+    <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"तुमचे डिव्हाइस व्यवस्थापित करण्यासाठी <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> वापरते."</string>
     <string name="monitoring_description_do_body" msgid="3639594537660975895">"आपला प्रशासक सेटिंग्ज, कॉर्पोरेट प्रवेश, अॅप्स, आपल्या डिव्हाइशी संबंधित डेटा आणि डिव्हाइसच्या स्थान माहितीचे निरीक्षण आणि व्यवस्थापन करू शकतो."</string>
     <string name="monitoring_description_do_learn_more_separator" msgid="3785251953067436862">" "</string>
     <string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"अधिक जाणून घ्या"</string>
@@ -457,20 +458,22 @@
     <string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"VPN सेटिंग्ज उघडा"</string>
     <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
-    <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"विश्वासू क्रेडेन्शियल उघडा"</string>
+    <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"विश्वासू क्रेडेंशियल उघडा"</string>
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"आपल्या प्रशासकाने नेटवर्क लॉगिंग चालू केले आहे, जे आपल्या डिव्हाइसवरील रहदारीचे निरीक्षण करते.\n\nअधिक माहितीसाठी आपल्या प्रशासकाशी संपर्क साधा."</string>
-    <string name="monitoring_description_vpn" msgid="4445150119515393526">"आपण VPN कनेक्शन सेट करण्यासाठी अ‍ॅपला परवानगी दिली.\n\nहा अ‍ॅप ईमेल, अ‍ॅप्स आणि वेबसाइटसह, आपल्या डिव्हाइस आणि नेटवर्क क्रियाकलापाचे परीक्षण करू शकतो."</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"आपले कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते.\n\nआपला प्रशासक ईमेल, अॅप्स आणि वेबसाइटसह आपल्या नेटवर्क क्रियाकलापाचे निरीक्षण करण्यास सक्षम आहे.\n\nअधिक माहितीसाठी आपल्या प्रशासकाशी संपर्क साधा.\n\nआपण VPN शी देखील कनेक्ट आहात, जे आपल्या नेटवर्क क्रियाकलापाचे निरीक्षण करू शकते."</string>
+    <string name="monitoring_description_vpn" msgid="4445150119515393526">"तुम्ही VPN कनेक्शन सेट करण्यासाठी अ‍ॅपला परवानगी दिली.\n\nहा अ‍ॅप ईमेल, अ‍ॅप्स आणि वेबसाइटसह, तुमच्या डिव्हाइस आणि नेटवर्क अॅक्टिव्हिटीचे परीक्षण करू शकतो."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"आपले कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते.\n\nआपला प्रशासक ईमेल, अॅप्स आणि वेबसाइटसह आपल्या नेटवर्क अॅक्टिव्हिटीचे निरीक्षण करण्यास सक्षम आहे.\n\nअधिक माहितीसाठी आपल्या प्रशासकाशी संपर्क साधा.\n\nआपण VPN शी देखील कनेक्ट आहात, जे आपल्या नेटवर्क अॅक्टिव्हिटीचे निरीक्षण करू शकते."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
     <string name="monitoring_description_app" msgid="1828472472674709532">"आपण <xliff:g id="APPLICATION">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या नेटवर्क क्रियाकलापाचे परीक्षण करू शकते."</string>
     <string name="monitoring_description_app_personal" msgid="484599052118316268">"आपण <xliff:g id="APPLICATION">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जो ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या वैयक्तिक नेटवर्क क्रियाकलापाचे परीक्षण करू शकतो."</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"आपण <xliff:g id="APPLICATION">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जो ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या वैयक्तिक नेटवर्क क्रियाकलापाचे परीक्षण करू शकतो."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"आपले कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते. प्रोफाइल <xliff:g id="APPLICATION">%2$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या कार्य नेटवर्क क्रियाकलापाचे परीक्षण करू शकते.\n\nअधिक माहितीसाठी, आपल्या प्रशासकाशी संपर्क साधा."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"आपले कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते. प्रोफाइल <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या कार्य नेटवर्क क्रियाकलापाचे परीक्षण करू शकते.\n\nआपण <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> शीदेखील कनेक्‍ट केले आहे, जे आपल्या वैयक्तिक नेटवर्क क्रियाकलापाचे परीक्षण करू शकते."</string>
-    <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"आपण व्यक्तिचलितपणे अनलॉक करेपर्यंत डिव्हाइस लॉक केलेले राहील"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> साठी अनलॉक केले"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> चालू आहे"</string>
+    <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"तुम्ही मॅन्युअली अनलॉक करेपर्यंत डिव्हाइस लॉक राहील"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"सूचना अधिक जलद मिळवा"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"आपण अनलॉक करण्‍यापूर्वी त्यांना पहा"</string>
-    <string name="hidden_notifications_cancel" msgid="3690709735122344913">"नाही धन्यवाद"</string>
+    <string name="hidden_notifications_cancel" msgid="3690709735122344913">"नाही, नको"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"सेट अप"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="volume_zen_end_now" msgid="6930243045593601084">"आता बंद करा"</string>
@@ -480,18 +483,18 @@
     <string name="screen_pinning_description" msgid="8909878447196419623">"आपण अनपिन करेर्यंत हे यास दृश्यामध्ये ठेवते. अनपिन करण्‍यासाठी परत आणि विहंगावलोकनास स्पर्श करा आणि धरून ठेवा."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"आपण अनपिन करेर्यंत हे यास दृश्यामध्ये ठेवते. अनपिन करण्‍यासाठी विहंगावलोकनास स्पर्श करा आणि धरून ठेवा."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"समजले"</string>
-    <string name="screen_pinning_negative" msgid="3741602308343880268">"नाही धन्यवाद"</string>
+    <string name="screen_pinning_negative" msgid="3741602308343880268">"नाही, नको"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> लपवायचे?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"आपण सेटिंग्जमध्ये ते पुढील वेळी चालू कराल तेव्हा ते पुन्हा दिसेल."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"लपवा"</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"आपण आपले कार्य प्रोफाईल वापरत आहात"</string>
     <string name="stream_voice_call" msgid="4410002696470423714">"कॉल करा"</string>
-    <string name="stream_system" msgid="7493299064422163147">"सिस्टीम"</string>
+    <string name="stream_system" msgid="7493299064422163147">"सिस्टम"</string>
     <string name="stream_ring" msgid="8213049469184048338">"रिंग करा"</string>
     <string name="stream_music" msgid="9086982948697544342">"मीडिया"</string>
     <string name="stream_alarm" msgid="5209444229227197703">"अलार्म"</string>
     <string name="stream_notification" msgid="2563720670905665031">"सूचना"</string>
-    <string name="stream_bluetooth_sco" msgid="2055645746402746292">"ब्लूटुथ"</string>
+    <string name="stream_bluetooth_sco" msgid="2055645746402746292">"ब्लूटूथ"</string>
     <string name="stream_dtmf" msgid="2447177903892477915">"दुहेरी एकाधिक टोन वारंंवारता"</string>
     <string name="stream_accessibility" msgid="301136219144385106">"प्रवेशयोग्यता"</string>
     <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. सशब्द करण्यासाठी टॅप करा."</string>
@@ -501,14 +504,14 @@
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. नि:शब्द करण्यासाठी टॅप करा."</string>
     <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s आवाज नियंत्रणे दर्शविली. डिसमिस करण्यासाठी वर स्वाइप करा."</string>
     <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"आवाज नियंत्रणे लपविली"</string>
-    <string name="system_ui_tuner" msgid="708224127392452018">"सिस्टीम UI ट्यूनर"</string>
+    <string name="system_ui_tuner" msgid="708224127392452018">"सिस्टम UI ट्युनर"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"एम्बेडेड बॅटरी टक्केवारी दर्शवा"</string>
     <string name="show_battery_percentage_summary" msgid="3215025775576786037">"चार्ज होत नसताना स्टेटस बार चिन्हामध्‍ये बॅटरी पातळी टक्केवारी दर्शवा"</string>
     <string name="quick_settings" msgid="10042998191725428">"द्रुत सेटिंग्ज"</string>
     <string name="status_bar" msgid="4877645476959324760">"स्टेटस बार"</string>
-    <string name="overview" msgid="4018602013895926956">"विहंगावलोकन"</string>
-    <string name="demo_mode" msgid="2532177350215638026">"सिस्टीम UI डेमो मोड"</string>
-    <string name="enable_demo_mode" msgid="4844205668718636518">"डेमो मोड सक्षम करा"</string>
+    <string name="overview" msgid="4018602013895926956">"अवलोकन"</string>
+    <string name="demo_mode" msgid="2532177350215638026">"सिस्टम UI डेमो मोड"</string>
+    <string name="enable_demo_mode" msgid="4844205668718636518">"डेमो मोड सुरू करा"</string>
     <string name="show_demo_mode" msgid="2018336697782464029">"डेमो मोड दर्शवा"</string>
     <string name="status_bar_ethernet" msgid="5044290963549500128">"इथरनेट"</string>
     <string name="status_bar_alarm" msgid="8536256753575881818">"अलार्म"</string>
@@ -524,33 +527,34 @@
     <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">"सिस्टीम UI ट्यूनर आपल्‍याला Android वापरकर्ता इंटरफेस ट्विक आणि सानुकूल करण्‍याचे अनेक प्रकार देते. ही प्रयोगात्मक वैशिष्‍ट्ये बदलू शकतात, खंडित होऊ शकतात किंवा भविष्‍यातील रिलीज मध्‍ये कदाचित दिसणार नाहीत. सावधगिरी बाळगून पुढे सुरु ठेवा."</string>
+    <string name="tuner_warning" msgid="8730648121973575701">"सिस्टम UI ट्युनर आपल्‍याला Android वापरकर्ता इंटरफेस ट्विक आणि कस्टमाइझ करण्‍याचे अनेक प्रकार देते. ही प्रयोगात्मक वैशिष्‍ट्ये बदलू शकतात, खंडित होऊ शकतात किंवा भविष्‍यातील रिलीज मध्‍ये कदाचित दिसणार नाहीत. सावधगिरी बाळगून पुढे सुरु ठेवा."</string>
     <string name="tuner_persistent_warning" msgid="8597333795565621795">"ही प्रयोगात्मक वैशिष्‍ट्ये बदलू शकतात, खंडित होऊ शकतात किंवा भविष्‍यातील रिलीज मध्‍ये कदाचित दिसणार नाहीत."</string>
     <string name="got_it" msgid="2239653834387972602">"समजले"</string>
-    <string name="tuner_toast" msgid="603429811084428439">"अभिनंदन! सिस्टीम UI ट्यूनर सेटिंग्जमध्‍ये जोडले गेले आहे"</string>
+    <string name="tuner_toast" msgid="603429811084428439">"अभिनंदन! सिस्टम UI ट्युनर सेटिंग्जमध्‍ये जोडले गेले आहे"</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"सेटिंग्ज मधून काढा"</string>
-    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"सेटिंग्ज मधून सिस्टीम UI ट्यूनर काढून त्याची सर्व वैशिष्ट्‍ये वापरणे थांबवायचे?"</string>
-    <string name="activity_not_found" msgid="348423244327799974">"अनुप्रयोग आपल्या डिव्हाइसवर स्थापित केलेला नाही"</string>
-    <string name="clock_seconds" msgid="7689554147579179507">"घड्‍याळ सेकंद दर्शवा"</string>
-    <string name="clock_seconds_desc" msgid="6282693067130470675">"स्टेटस बारमध्‍ये घड्‍याळ सेकंद दर्शवा. कदाचित बॅटरी आयुष्‍य प्रभावित होऊ शकते."</string>
+    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"सेटिंग्ज मधून सिस्टम UI ट्युनर काढून त्याची सर्व वैशिष्ट्‍ये वापरणे थांबवायचे?"</string>
+    <string name="activity_not_found" msgid="348423244327799974">"अॅप्लिकेशन आपल्या डिव्हाइसवर इंस्टॉल केलेला नाही"</string>
+    <string name="clock_seconds" msgid="7689554147579179507">"घड्याळाचे सेकंद दर्शवा"</string>
+    <string name="clock_seconds_desc" msgid="6282693067130470675">"स्टेटस बारमध्‍ये घड्याळाचे सेकंद दर्शवा. कदाचित बॅटरी आयुष्‍य प्रभावित होऊ शकते."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"द्रुत सेटिंग्जची पुनर्रचना करा"</string>
     <string name="show_brightness" msgid="6613930842805942519">"द्रुत सेटिंग्जमध्‍ये चमक दर्शवा"</string>
     <string name="experimental" msgid="6198182315536726162">"प्रायोगिक"</string>
-    <string name="enable_bluetooth_title" msgid="5027037706500635269">"ब्लूटुथ सुरू करायचे?"</string>
-    <string name="enable_bluetooth_message" msgid="9106595990708985385">"आपला कीबोर्ड आपल्या टॅब्लेटसह कनेक्ट करण्यासाठी, आपल्याला प्रथम ब्लूटुथ चालू करणे आवश्यक आहे."</string>
+    <string name="enable_bluetooth_title" msgid="5027037706500635269">"ब्लूटूथ सुरू करायचे?"</string>
+    <string name="enable_bluetooth_message" msgid="9106595990708985385">"आपला कीबोर्ड तुमच्या टॅबलेटसह कनेक्ट करण्यासाठी, तुम्ही प्रथम ब्लूटूथ चालू करणे आवश्यक आहे."</string>
     <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"चालू करा"</string>
     <string name="show_silently" msgid="6841966539811264192">"सूचना शांतपणे दर्शवा"</string>
-    <string name="block" msgid="2734508760962682611">"सर्व सूचना अवरोधित करा"</string>
+    <string name="block" msgid="2734508760962682611">"सर्व सूचना ब्लॉक करा"</string>
     <string name="do_not_silence" msgid="6878060322594892441">"शांत करू नका"</string>
     <string name="do_not_silence_block" msgid="4070647971382232311">"शांत किंवा अवरोधित करू नका"</string>
     <string name="tuner_full_importance_settings" msgid="3207312268609236827">"पॉवर सूचना नियंत्रणे"</string>
     <string name="tuner_full_importance_settings_on" msgid="7545060756610299966">"चालू"</string>
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"बंद"</string>
-    <string name="power_notification_controls_description" msgid="4372459941671353358">"पॉवर सूचना नियंत्रणांसह, आपण अॅपच्या सूचनांसाठी महत्त्व स्तर 0 ते 5 पर्यंत सेट करू शकता. \n\n"<b>"स्तर 5"</b>" \n- सूचना सूचीच्या शीर्षस्थानी दर्शवा \n- पूर्ण स्क्रीन व्यत्ययास अनुमती द्या \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 4"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 3"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n\n"<b>"स्तर 2"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा कंपन करू नका \n\n"<b>"स्तर 1"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा कंपन करू नका \n- लॉक स्क्रीन आणि स्टेटस बार मधून लपवा \n- सूचना सूचीच्या तळाशी दर्शवा \n\n"<b>"स्तर 0"</b>" \n- अॅपमधील सर्व सूचना अवरोधित करा"</string>
+    <string name="power_notification_controls_description" msgid="4372459941671353358">"पॉवर सूचना नियंत्रणांच्या साहाय्याने तुम्ही अॅप सूचनांसाठी 0 ते 5 असे महत्त्व स्तर सेट करू शकता. \n\n"<b>"स्तर 5"</b>" \n- सूचना सूचीच्या शीर्षस्थानी दाखवा \n- पूर्ण स्क्रीन व्यत्ययास अनुमती द्या \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 4"</b>\n" - पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 3"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n\n"<b>"स्तर 2"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा कंपन करू नका \n\n"<b>"स्तर 1"</b>\n"- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा कंपन करू नका \n- लॉक स्क्रीन आणि स्टेटस बार मधून लपवा \n- सूचना सूचीच्या तळाशी दर्शवा \n\n"<b>"स्तर 0"</b>" \n- अॅपमधील सर्व सूचना ब्लॉक करा"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"सूचना"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"आपल्याला यापुढे या सूचना प्राप्त होणार नाहीत."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"तुम्हाला यापुढे या सूचना प्राप्त होणार नाहीत"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> सूचना श्रेण्या"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"या अ‍ॅपला सूचना श्रेण्या नाहीत"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"या अ‍ॅपकडून येणार्‍या सूचना बंद ठेवता येणार नाहीत"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">या अॅपकडील <xliff:g id="NUMBER_1">%d</xliff:g> पैकी 1 सूचना श्रेणी</item>
       <item quantity="other">या अॅपकडील <xliff:g id="NUMBER_1">%d</xliff:g> पैकी 1 सूचना श्रेणी</item>
@@ -570,16 +574,20 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"सूचना नियंत्रणे"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"सूचना स्नूझ पर्याय"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 मिनिटे"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 मिनिटे"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 तास"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 तास"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"पूर्ववत करा"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> साठी स्नूझ करा"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one"> %d तास</item>
+      <item quantity="other"> %d तास</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one"> %d मिनिट</item>
+      <item quantity="other"> %d मिनिटे</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"बॅटरी वापर"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज करताना बॅटरी बचतकर्ता उपलब्ध नाही"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"बॅटरी बचतकर्ता"</string>
-    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"कार्यप्रदर्शन आणि पार्श्वभूमी डेटा कमी करते"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"कामगिरी आणि पार्श्वभूमीवरील डेटा कमी करते"</string>
     <string name="keyboard_key_button_template" msgid="6230056639734377300">"बटण <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
     <string name="keyboard_key_back" msgid="2337450286042721351">"परत"</string>
@@ -606,14 +614,14 @@
     <string name="keyboard_key_insert" msgid="8530501581636082614">"घाला"</string>
     <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
     <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"सिस्टीम"</string>
-    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"मुख्यपृष्ठ"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"सिस्टम"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"होम"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"अलीकडील"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"परत"</string>
     <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"सूचना"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"कीबोर्ड शॉर्टकट"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"इनपुट पद्धत स्विच करा"</string>
-    <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"अनुप्रयोग"</string>
+    <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"अॅप्लिकेशन"</string>
     <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"सहाय्य"</string>
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ब्राउझर"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"संपर्क"</string>
@@ -654,15 +662,15 @@
     <item msgid="586019486955594690">"उजवीकडे कललेले"</item>
   </string-array>
     <string name="menu_ime" msgid="4998010205321292416">"कीबोर्ड स्विचर"</string>
-    <string name="save" msgid="2311877285724540644">"जतन करा"</string>
+    <string name="save" msgid="2311877285724540644">"सेव्ह करा"</string>
     <string name="reset" msgid="2448168080964209908">"रीसेट करा"</string>
     <string name="adjust_button_width" msgid="6138616087197632947">"बटण रूंदी समायोजित करा"</string>
     <string name="clipboard" msgid="1313879395099896312">"क्लिपबोर्ड"</string>
     <string name="accessibility_key" msgid="5701989859305675896">"सानुकूल नेव्हिगेशन बटण"</string>
     <string name="left_keycode" msgid="2010948862498918135">"डावा कीकोड"</string>
     <string name="right_keycode" msgid="708447961000848163">"उजवा कीकोड"</string>
-    <string name="left_icon" msgid="3096287125959387541">"डावे चिन्ह"</string>
-    <string name="right_icon" msgid="3952104823293824311">"उजवे चिन्ह"</string>
+    <string name="left_icon" msgid="3096287125959387541">"डावे आयकन"</string>
+    <string name="right_icon" msgid="3952104823293824311">"उजवे आयकन"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"टाइल जोडण्यासाठी ड्रॅग करा"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"काढण्यासाठी येथे ड्रॅग करा"</string>
     <string name="qs_edit" msgid="2232596095725105230">"संपादित करा"</string>
@@ -670,12 +678,12 @@
   <string-array name="clock_options">
     <item msgid="5965318737560463480">"तास, मिनिटे आणि सेकंद दर्शवा"</item>
     <item msgid="1427801730816895300">"तास आणि मिनिटे दर्शवा (डीफॉल्ट)"</item>
-    <item msgid="3830170141562534721">"हे चिन्ह दर्शवू नका"</item>
+    <item msgid="3830170141562534721">"हे आयकन दाखवू नका"</item>
   </string-array>
   <string-array name="battery_options">
     <item msgid="3160236755818672034">"नेहमी टक्केवारी दर्शवा"</item>
     <item msgid="2139628951880142927">"चार्ज करताना टक्केवारी दर्शवा (डीफॉल्ट)"</item>
-    <item msgid="3327323682209964956">"हे चिन्ह दर्शवू नका"</item>
+    <item msgid="3327323682209964956">"हे आयकन दाखवू नका"</item>
   </string-array>
     <string name="other" msgid="4060683095962566764">"अन्य"</string>
     <string name="accessibility_divider" msgid="5903423481953635044">"विभाजित-स्क्रीन विभाजक"</string>
@@ -739,8 +747,8 @@
     <string name="tuner_launch_app" msgid="1527264114781925348">"<xliff:g id="APP">%1$s</xliff:g> लाँच करा"</string>
     <string name="tuner_other_apps" msgid="4726596850501162493">"इतर अॅप्स"</string>
     <string name="tuner_circle" msgid="2340998864056901350">"मंडळ"</string>
-    <string name="tuner_plus" msgid="6792960658533229675">"अधिक चिन्ह"</string>
-    <string name="tuner_minus" msgid="4806116839519226809">"उणे चिन्ह"</string>
+    <string name="tuner_plus" msgid="6792960658533229675">"अधिक आयकन"</string>
+    <string name="tuner_minus" msgid="4806116839519226809">"उणे आयकन"</string>
     <string name="tuner_left" msgid="8404287986475034806">"डावा"</string>
     <string name="tuner_right" msgid="6222734772467850156">"उजवा"</string>
     <string name="tuner_menu" msgid="191640047241552081">"मेनू"</string>
@@ -755,7 +763,7 @@
     <string name="go_to_web" msgid="1106022723459948514">"वेबवर जा"</string>
     <string name="mobile_data" msgid="7094582042819250762">"मोबाइल डेटा"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"वाय-फाय बंद आहे"</string>
-    <string name="bt_is_off" msgid="2640685272289706392">"ब्लूटुथ बंद आहे"</string>
+    <string name="bt_is_off" msgid="2640685272289706392">"ब्लूटूथ बंद आहे"</string>
     <string name="dnd_is_off" msgid="6167780215212497572">"व्यत्यय आणू नका बंद आहे"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"व्यत्यय आणू नका एका <xliff:g id="ID_1">%s</xliff:g> स्वयंचलित नियमाने चालू केले."</string>
     <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"व्यत्यय आणू नका (<xliff:g id="ID_1">%s</xliff:g>) अॅपने चालू केले."</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"पुनर्स्थित करा"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"अॅप्‍स बॅकग्राउंडमध्‍ये चालू आहेत"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"बॅटरी आणि डेटा वापराच्‍या तपशीलांसाठी टॅप करा"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"मोबाइल डेटा बंद करायचा?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings_car.xml b/packages/SystemUI/res/values-mr/strings_car.xml
index 7dc5d17..5d66f14 100644
--- a/packages/SystemUI/res/values-mr/strings_car.xml
+++ b/packages/SystemUI/res/values-mr/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"सुरक्षितपणे वाहन चालवा"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"वाहन चालविण्‍याच्या शर्तींची पूर्णपणे माहिती असू द्या आणि नेहमी लागू असलेल्या कायद्यांचे पालन करा. दिशानिर्देश कदाचित चुकीचे, अपूर्ण, धोकादायक, अनुकूल नसलेले, प्रतिबंधित किंवा प्रशासकीय क्षेत्रांना ओलांडणारे असू शकतात. व्यवसाय माहिती देखील चुकीची किंवा अपूर्ण असू शकते. डेटा हा रिअल-टाइम नसतो आणि स्थान अचूकतेची हमी दिली जाऊ शकत नाही. वाहन चालविताना Android Auto च्या उद्देशासाठी नसलेले आपले मोबाईल डिव्हाइस हाताळू नका किंवा अॅप्स वापरू नका."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"अज्ञात"</string>
+    <string name="start_driving" msgid="864023351402918991">"वाहन चालवणे सुरू करा"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 46fcf43..b1592d6 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Lagi tetapan"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Selesai"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Disambungkan"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Disambungkan, bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Menyambung..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Penambatan"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Tempat liputan"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Anda disambungkan ke <xliff:g id="APPLICATION">%1$s</xliff:g>, yang boleh memantau aktiviti rangkaian peribadi anda, termasuk e-mel, apl dan tapak web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Profil kerja anda diurus oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil itu dihubungkan ke <xliff:g id="APPLICATION">%2$s</xliff:g>, yang boleh memantau aktiviti rangkaian kerja anda, termasuk e-mel, apl dan tapak web.\n\nUntuk mendapatkan maklumat lanjut, hubungi pentadbir anda."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Profil kerja anda diurus oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil itu dihubungkan ke <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, yang boleh memantau aktiviti rangkaian kerja anda, termasuk e-mel, apl dan tapak web.\n\nAnda turut dihubungkan ke <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, yang boleh memantau aktiviti rangkaian peribadi anda."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Kunci dibuka untuk <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> sedang berjalan"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Peranti akan kekal terkunci sehingga anda membuka kunci secara manual"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Dapatkan pemberitahuan lebih cepat"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Lihat sebelum anda membuka kunci"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Mati"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Dengan kawalan pemberitahuan berkuasa, anda boleh menetapkan tahap kepentingan dari 0 hingga 5 untuk pemberitahuan apl. \n\n"<b>"Tahap 5"</b>" \n- Tunjukkan pada bahagian atas senarai pemberitahuan \n- Benarkan gangguan skrin penuh \n- Sentiasa intai \n\n"<b>"Tahap 4"</b>" \n- Halang gangguan skrin penuh \n- Sentiasa intai \n\n"<b>"Tahap 3"</b>" \n- Halang gangguan skrin penuh \n- Jangan intai \n\n"<b>"Tahap 2"</b>" \n- Halang gangguan skrin penuh \n- Jangan intai \n- Jangan berbunyi dan bergetar \n\n"<b>"Tahap 1"</b>" \n- Halang gangguan skrin penuh \n- Jangan intai \n- Jangan berbunyi atau bergetar \n- Sembunyikan daripada skrin kunci dan bar status \n- Tunjukkan di bahagian bawah senarai pemberitahuan \n\n"<b>"Tahap 0"</b>" \n- Sekat semua pemberitahuan daripada apl"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Pemberitahuan"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Anda tidak akan menerima pemberitahuan ini lagi."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Anda tidak akan menerima pemberitahuan ini lagi"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> kategori pemberitahuan"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Apl ini tiada kategori pemberitahuan"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Pemberitahuan daripada apl ini tidak boleh dimatikan"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 daripada <xliff:g id="NUMBER_1">%d</xliff:g> kategori pemberitahuan daripada apl ini</item>
       <item quantity="one">1 daripada <xliff:g id="NUMBER_0">%d</xliff:g> kategori pemberitahuan daripada apl ini</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kawalan pemberitahuan"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"pilihan tunda pemberitahuan"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minit"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minit"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 jam"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 jam"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"BUAT ASAL"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Ditunda selama <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d jam</item>
+      <item quantity="one">%d jam</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minit</item>
+      <item quantity="one">%d minit</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Penggunaan bateri"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Penjimat Bateri tidak tersedia semasa mengecas"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Penjimat Bateri"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Gantikan"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Apl yang berjalan di latar belakang"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Ketik untuk mendapatkan butiran tentang penggunaan kuasa bateri dan data"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Matikan data mudah alih?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings_car.xml b/packages/SystemUI/res/values-ms/strings_car.xml
index 392530a..0daa093 100644
--- a/packages/SystemUI/res/values-ms/strings_car.xml
+++ b/packages/SystemUI/res/values-ms/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Pandu dengan selamat"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Pastikan anda sentiasa sedar sepenuhnya akan keadaan pemanduan dan mematuhi undang-undang yang dikenakan pada sepanjang masa. Arah mungkin tidak tepat, tidak lengkap, berbahaya, tidak sesuai, dilarang atau melibatkan lintasan kawasan pentadbiran. Maklumat perniagaan juga mungkin tidak tepat atau tidak lengkap. Data bukan masa sebenar dan ketepatan lokasi tidak dapat dijamin. Jangan kendalikan peranti mudah alih anda atau gunakan apl yang bukan untuk Android Auto semasa memandu."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Tidak diketahui"</string>
+    <string name="start_driving" msgid="864023351402918991">"Mulakan Pemanduan"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 39dac57..c07969a 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -79,7 +79,7 @@
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ဖိုင်ပြောင်း ရွေးမှုများ"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"မီဒီယာပလေရာအနေဖြင့် တပ်ဆင်ရန် (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"ကင်မရာအနေဖြင့် တပ်ဆင်ရန် (PTP)"</string>
-    <string name="installer_cd_button_title" msgid="2312667578562201583">"Macအတွက်Andriodဖိုင်ပြောင်းအပ်ပလီကေးရှင်းထည့်ခြင်း"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac အတွက် Android File Transfer အက်ပ်ထည့်ခြင်း"</string>
     <string name="accessibility_back" msgid="567011538994429120">"နောက်သို့"</string>
     <string name="accessibility_home" msgid="8217216074895377641">"ပင်မစာမျက်နှာ"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"မီနူး"</string>
@@ -308,13 +308,14 @@
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"အရောင်များ ပြောင်းပြန်လုပ်ရန်"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"အရောင် မှန်ကန်စေခြင်း အခြေအနေ"</string>
     <string name="quick_settings_more_settings" msgid="326112621462813682">"နောက်ထပ် ဆက်တင်များ"</string>
-    <string name="quick_settings_done" msgid="3402999958839153376">"လုပ်ပြီး"</string>
+    <string name="quick_settings_done" msgid="3402999958839153376">"ပြီးပါပြီ"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"ချိတ်ဆက်ထား"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"ချိတ်ဆက်ပြီးပါပြီ၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"ဆက်သွယ်နေ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"တွဲချီပေးခြင်း"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ဟော့စပေါ့"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"အကြောင်းကြားချက်များ"</string>
-    <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ဖလက်ရှမီး"</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>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ကျန်ရှိ ဒေတာ"</string>
@@ -380,10 +381,10 @@
     <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"အသုံးပြုသူကို ပြောင်းရန်၊ လက်ရှိ အသုံးပြုသူ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"လတ်တလော သုံးစွဲသူ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"ပရိုဖိုင်ကို ပြရန်"</string>
-    <string name="user_add_user" msgid="5110251524486079492">"သုံးသူ ထပ်ထည့်ရန်"</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_new_guest" msgid="600537543078847803">"ဧည့်သည့်ကို ထည့်ပေးရန်"</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_dialog_message" msgid="4155503224769676625">"ဒီချိတ်ဆက်မှု ထဲက အက်ပ်များ အားလုံး နှင့် ဒေတာကို ဖျက်ပစ်မည်။"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"သင်သည် အီးမေးလ်၊ အက်ပ်နှင့် ဝဘ်ဆိုက်များအပါအဝင် သင့်ကိုယ်ရေးကိုယ်တာ ကွန်ရက်အသုံးပြုမှုကို စောင့်ကြည့်နိုင်သည့် <xliff:g id="APPLICATION">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်။"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"သင်၏ အလုပ်ပရိုဖိုင်ကို <xliff:g id="ORGANIZATION">%1$s</xliff:g> က စီမံခန့်ခွဲထားပါသည်။ ပရိုဖိုင်သည် အီးမေး၊ အက်ပ်နှင့် ဝဘ်ဆိုက်များအပါအဝင် သင်၏ကွန်ရက် လုပ်ဆောင်ချက်များကို စောင့်ကြည့်နိုင်သည့် <xliff:g id="APPLICATION">%2$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်။\n\nနောက်ထပ် အချက်အလက်များအတွက် သင်၏ စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"သင်၏ အလုပ်ပရိုဖိုင်ကို <xliff:g id="ORGANIZATION">%1$s</xliff:g> က စီမံခန့်ခွဲထားသည်။ ပရိုဖိုင်သည် အီးမေး၊ အက်ပ်နှင့် ဝဘ်ဆိုက်များအပါအဝင် သင်၏ကွန်ရက် လုပ်ဆောင်ချက်များကို စောင့်ကြည့်နိုင်သည့် <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်။\n\nသင်၏ ကိုယ်ရေးကိုယ်တာ ကွန်ရက်လုပ်ဆောင်ချက်များကို စောင့်ကြည့်နိုင်သည့် <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> သို့လည်း ချိတ်ဆက်ထားပါသည်။"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> အတွက် လော့ခ်ဖွင့်ထားသည်"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ပွင့်နေပါသည်"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"သင်က လက်ဖြင့် သော့မဖွင့်မချင်း ကိရိယာမှာ သော့ပိတ်လျက် ရှိနေမည်"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"အကြောင်းကြားချက်များ မြန်မြန်ရရန်"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"မဖွင့်ခင် ၎င်းတို့ကို ကြည့်ပါ"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ပိတ်ပါ"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ပါဝါအကြောင်းကြားချက် ထိန်းချုပ်မှုများကိုအသုံးပြုပြီး အက်ပ်တစ်ခု၏ အကြောင်းကြားချက် အရေးပါမှု ၀ မှ ၅ အထိသတ်မှတ်ပေးနိုင်သည်။ \n\n"<b>"အဆင့် ၅"</b>" \n- အကြောင်းကြားချက်စာရင်း၏ ထိပ်ဆုံးတွင် ပြသည် \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်းကို ခွင့်ပြုသည် \n- အမြဲတမ်း ခေတ္တပြပါမည် \n\n"<b>"အဆင့် ၄"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- အမြဲတမ်း ခေတ္တပြပါမည် \n\n"<b>"အဆင့် ၃"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- ဘယ်တော့မှ ခေတ္တပြခြင်း မရှိပါ \n\n"<b>"အဆင့် ၂"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- ဘယ်တော့မှ ခေတ္တပြခြင်း မရှိပါ \n- အသံမြည်ခြင်းနှင့် တုန်ခါခြင်းများ ဘယ်တော့မှ မပြုလုပ်ပါ \n\n"<b>"အဆင့် ၁"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- ဘယ်တော့မှ ခေတ္တပြခြင်း မရှိပါ \n- အသံမြည်ခြင်းနှင့် တုန်ခါခြင်းများ ဘယ်တော့မှ မပြုလုပ်ပါ \n- လော့ခ်ချထားသည့် မျက်နှာပြင်နှင့် အခြေအနေဘားတန်းတို့တွင် မပြပါ \n- အကြောင်းကြားချက်စာရင်း အောက်ဆုံးတွင်ပြသည် \n\n"<b>"အဆင့် ၀"</b>" \n- အက်ပ်မှ အကြောင်းကြားချက်များ အားလုံးကို ပိတ်ဆို့သည်"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"အကြောင်းကြားချက်များ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"သင်သည် ဤအကြောင်းကြားချက်များကို လက်ခံရရှိတော့မည် မဟုတ်ပါ။"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"သင်သည် ဤအကြောင်းကြားချက်များကို နောက်ထပ် လက်ခံရရှိတော့မည် မဟုတ်ပါ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"အကြောင်းကြားချက် အမျိုးအစား <xliff:g id="NUMBER">%d</xliff:g> ခု"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ဤအက်ပ်တွင် အကြောင်းကြားချက် အမျိုးအစားများ မရှိပါ"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"ဤအက်ပ်မှပို့သော အကြောင်းကြားချက်များကို ပိတ်ထား၍မရပါ"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">ဤအက်ပ်ရှိ အကြောင်းကြားချက်အမျိုးအစား <xliff:g id="NUMBER_1">%d</xliff:g> ခု အနက်မှ ၁ ခု</item>
       <item quantity="one">ဤအက်ပ်ရှိ အကြောင်းကြားချက်အမျိုးအစား <xliff:g id="NUMBER_0">%d</xliff:g> ခု အနက်မှ ၁ ခု</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"အကြောင်းကြားချက် ထိန်းချုပ်မှုများ"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"အကြောင်းကြားချက်များကို ဆိုင်းငံ့ရန် ရွေးချယ်စရာများ"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"၁၅ မိနစ်"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"၃၀ မိနစ်"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"၁ နာရီ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"၂ နာရီ"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"တစ်ဆင့် နောက်ပြန်ပြန်ပါ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ဆိုင်းငံ့ရန်"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d နာရီ</item>
+      <item quantity="one">%d နာရီ</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d မိနစ်</item>
+      <item quantity="one">%d မိနစ်</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"ဘက်ထရီ အသုံးပြုမှု"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"အားသွင်းနေချိန်မှာ Battery Saver ကို သုံးမရပါ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
@@ -589,7 +597,7 @@
     <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ညာ"</string>
     <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"ဌာန"</string>
     <string name="keyboard_key_tab" msgid="3871485650463164476">"တဘ်"</string>
-    <string name="keyboard_key_space" msgid="2499861316311153293">"နေရာခြားပါ"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
     <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter ခလုတ်"</string>
     <string name="keyboard_key_backspace" msgid="1559580097512385854">"နောက်ပြန်ဖျက်ပါ"</string>
     <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"ဖွင့်ပါ/ခဏရပ်ပါ"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"အစားထိုးရန်"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"နောက်ခံတွင် ပွင့်နေသော အက်ပ်များ"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"ဘက်ထရီနှင့် ဒေတာအသုံးပြုမှု အသေးစိတ်ကို ကြည့်ရန် တို့ပါ"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"မိုဘိုင်းဒေတာကို ပိတ်လိုပါသလား။"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings_car.xml b/packages/SystemUI/res/values-my/strings_car.xml
index dd41713..c2700c4 100644
--- a/packages/SystemUI/res/values-my/strings_car.xml
+++ b/packages/SystemUI/res/values-my/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ဘေးကင်းလုံခြုံစွာ မောင်းနှင်ပါ"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ယာဉ်မောင်းမှုအခြေအနေများကို အပြည့်အဝအာရုံစိုက်ပြီး သက်ဆိုင်ရာဥပဒေများကို အမြဲတမ်းလိုက်နာပါ။ လမ်းညွှန်ချက်များသည် မှန်ကန်မှုမရှိခြင်း၊ မပြည့်စုံခြင်း၊ အန္တရာယ်ရှိခြင်း၊ ကိုက်ညီမှုမရှိခြင်း၊ တားမြစ်ထားခြင်း၊ သို့မဟုတ် လမ်းဖြတ်ကူးခြင်း ကြီးကြပ်ထားသည့်နေရာများ ဖြစ်နေနိုင်ပါသည်။ စီးပွားရေးအချက်အလက်များသည်လည်း မမှန်ကန်ခြင်း သို့မဟုတ် မပြည့်စုံခြင်းများ ရှိနိုင်ပါသည်။ ဒေတာသည် အချိန်နှင့်တစ်ပြေးညီ မဟုတ်ပါ၊ တည်နေရာမှန်ကန်မှုကိုလည်း အာမ မခံနိုင်ပါ။ ယာဉ်မောင်းနှင်နေစဉ် Android Auto အတွက်ရည်ရွယ်ထားခြင်းမဟုတ်သည့် မိုဘိုင်းစက်ပစ္စည်း ကိုမကိုင်တွယ်ပါနှင့် သို့မဟုတ် အက်ပ်များကို အသုံးမပြုပါနှင့်။ိ"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"အမျိုးအမည်မသိ"</string>
+    <string name="start_driving" msgid="864023351402918991">"စတင် မောင်းနှင်ရန်"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 3fdc266..78ec748 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -240,7 +240,7 @@
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Lader"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G- og 3G-data er satt på pause"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-data er satt på pause"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Mobildata er satt på pause"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Mobildatabruk er satt på pause"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Data er satt på pause"</string>
     <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Datagrensen du har angitt, er nådd. Du bruker ikke lenger mobildata.\n\nHvis du fortsetter, kan avgifter for databruk påløpe."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Gjenoppta"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Flere innstillinger"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Ferdig"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Tilkoblet"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Tilkoblet, batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Kobler til …"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Internettdeling"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Wi-Fi-sone"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Enheten er koblet til <xliff:g id="APPLICATION">%1$s</xliff:g>, som kan overvåke den personlige nettverksaktiviteten din, inkludert e-post, apper og nettsteder."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Jobbprofilen din administreres av <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilen er koblet til <xliff:g id="APPLICATION">%2$s</xliff:g>, som kan overvåke nettverksaktiviteten din på jobben, inkludert e-poster, apper og nettsteder.\n\nTa kontakt med administratoren hvis du vil ha mer informasjon."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Jobbprofilen din administreres av <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilen er koblet til <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, som kan overvåke nettverksaktiviteten din på jobben, inkludert e-poster, apper og nettsteder.\n\nDu er også koblet til <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, som kan overvåke den personlige nettverksaktiviteten din."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Låst opp for <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> kjører"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Enheten forblir låst til du låser den opp manuelt"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Motta varsler raskere"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Se dem før du låser opp"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Av"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Med effektive varselinnstillinger kan du angi viktighetsnivåer fra 0 til 5 for appvarsler. \n\n"<b>"Nivå 5"</b>" \n– Vis øverst på varsellisten \n– Tillat forstyrrelser ved fullskjermmodus \n– Vis alltid raskt \n\n"<b>"Nivå 4"</b>" \n– Forhindre forstyrrelser ved fullskjermmodus \n– Vis alltid raskt \n\n"<b>"Nivå 3"</b>" \n– Forhindre forstyrrelser ved fullskjermmodus \n– Vis aldri raskt \n\n"<b>"Nivå 2"</b>" \n– Forhindre forstyrrelser ved fullskjermmodus \n– Vis aldri fort \n– Tillat aldri lyder eller vibrering \n\n"<b>"Nivå 1"</b>" \n– Forhindre forstyrrelser ved fullskjermmodus \n– Vis aldri raskt \n– Tillat aldri lyder eller vibrering \n– Skjul fra låseskjermen og statusfeltet \n– Vis nederst på varsellisten \n\n"<b>"Nivå 0"</b>" \n– Blokkér alle varsler fra appen"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Varsler"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Du får ikke disse varslene lenger."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Du får ikke disse varslene lenger"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> varselkategorier"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Denne appen har ikke varselkategorier"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Varsler fra denne appen kan ikke slås av"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 av <xliff:g id="NUMBER_1">%d</xliff:g> varselkategorier fra denne appen</item>
       <item quantity="one">1 av <xliff:g id="NUMBER_0">%d</xliff:g> varselkategori fra denne appen</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"varselinnstillinger"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"slumrealternativer for varsler"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutter"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutter"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 time"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 timer"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ANGRE"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Slumrer i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d timer</item>
+      <item quantity="one">%d time</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minutter</item>
+      <item quantity="one">%d minutt</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Batteribruk"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparing er ikke tilgjengelig under lading"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparing"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Erstatt"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Apper kjører i bakgrunnen"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Trykk for detaljer om batteri- og databruk"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vil du slå av mobildata?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings_car.xml b/packages/SystemUI/res/values-nb/strings_car.xml
index 421420e..2a1b3ca 100644
--- a/packages/SystemUI/res/values-nb/strings_car.xml
+++ b/packages/SystemUI/res/values-nb/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Kjør forsiktig"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Ha full oversikt over kjøreforhold, og følg alltid gjeldende lov og rett. Veibeskrivelser kan være unøyaktige, ufullstendige, farlige, upassende, forbudte eller de kan involvere kjøring på administrative områder. Bedriftsinformasjon kan også være unøyaktig eller ufullstendig. Data er ikke i sanntid, og posisjonsnøyaktighet kan ikke garanteres. Ikke bruk mobilenheten din eller apper som ikke er ment for Android Auto, mens du kjører."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Ukjent"</string>
+    <string name="start_driving" msgid="864023351402918991">"Begynn å kjøre"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index e21da54..e37cde6 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"थप सेटिङहरू"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"भयो"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"जोडिएको"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"यन्त्र जडान भयो, ब्याट्रीको चार्ज स्तर <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"जडान हुँदै..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"टेदर गर्दै"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"हटस्पट"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"तपाईं <xliff:g id="APPLICATION">%1$s</xliff:g> मा जोडिनुभएको छ जसले इमेल, अनुप्रयोग र वेबसाइटहरू लगायतको तपाईंको  व्यक्तिगत नेटवर्क सम्बन्धी गतिविधिको अनुगमन गर्न सक्छ।"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ले तपाईंको कार्य प्रोफाइलको व्यवस्थापन गर्छ। उक्त प्रोफाइल तपाईंका इमेल, अनुप्रयोग र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION">%2$s</xliff:g> मा जडान छ।\n\nथप जानकारीका लागि, आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ले तपाईंको कार्य प्रोफाइलको व्यवस्थापन गर्छ। उक्त प्रोफाइल तपाईंका इमेल, अनुप्रयोग र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> मा जडान छ। \n\nतपाईं आफ्नो व्यक्तिगत नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> मा पनि जडान हुनुहुन्छ।"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> का लागि अनलक गरियो"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> चल्दै छ"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"तपाईँले नखोले सम्म उपकरण बन्द रहनेछ"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"छिटो सूचनाहरू प्राप्त गर्नुहोस्"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"तपाईँले अनलक गर्नअघि तिनीहरूलाई हेर्नुहोस्"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"निष्क्रिय"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"सशक्त सूचना नियन्त्रणहरू मार्फत तपाईं अनुप्रयाेगका सूचनाहरूका लागि ० देखि ५ सम्मको महत्व सम्बन्धी स्तर सेट गर्न सक्नुहुन्छ। \n\n"<b>"स्तर ५"</b>" \n- सूचनाको सूचीको माथिल्लो भागमा देखाउने \n- पूर्ण स्क्रिनमा अवरोधका लागि अनुमति दिने \n- सधैँ चियाउने \n\n"<b>"स्तर ४"</b>" \n- पूर्ण स्क्रिनमा अवरोधलाई रोक्ने \n- सधैँ चियाउने \n\n"<b>"स्तर ३"</b>" \n- पूर्ण स्क्रिनमा अवरोधलाई रोक्ने \n- कहिल्यै नचियाउने \n\n"<b>"स्तर २"</b>" \n- पूर्ण स्क्रिनमा अवरोधलाई रोक्ने \n- कहिल्यै नचियाउने \n- कहिल्यै पनि आवाज ननिकाल्ने र कम्पन नगर्ने \n\n"<b>"स्तर १"</b>" \n- पूर्ण स्क्रिनमा अवरोध रोक्ने \n- कहिल्यै नचियाउने \n- कहिल्यै पनि आवाज ननिकाल्ने वा कम्पन नगर्ने \n- लक स्क्रिन र वस्तुस्थिति पट्टीबाट लुकाउने \n- सूचनाको सूचीको तल्लो भागमा देखाउने \n\n"<b>"स्तर ०"</b>" \n- अनुप्रयोगका सबै सूचनाहरूलाई रोक्ने"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"सूचनाहरू"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"तपाईंले अबदेखि यी सूचनाहरू प्राप्त गर्नुहुने छैन।"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"तपाईंले अब उप्रान्त यी सूचनाहरू प्राप्त गर्नुहुने छैन"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> सूचनाका कोटिहरू"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"यस अनुप्रयोगमा सूचना सम्बन्धी कोटीहरू छैनन्"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"यस अनुप्रयोगका सूचनाहरूलाई निष्क्रिय पार्न सकिँदैन"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">यस अनुप्रयोगका <xliff:g id="NUMBER_1">%d</xliff:g> सूचना कोटिहरू मध्ये १</item>
       <item quantity="one"> यस अनुप्रयोगको <xliff:g id="NUMBER_0">%d</xliff:g> सूचना कोटी मध्ये १</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"सूचना सम्बन्धी नियन्त्रणहरू"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"सूचना स्नुज गर्ने विकल्पहरू"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"१५ मिनेट"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"३० मिनेट"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"१ घन्टा"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"२ घन्टा"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"अनडू गर्नुहोस्"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> का लागि स्नुज गरियो"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d घन्टा</item>
+      <item quantity="one">%d घन्टा</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d मिनेट</item>
+      <item quantity="one">%d मिनेट</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"ब्याट्री उपयोग"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज गर्ने समयमा ब्याट्री सेभर उपलब्ध छैन"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ब्याट्री सेभर"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"प्रतिस्थापन गर्नुहोस्"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"पृष्ठभूमिमा चल्ने अनुप्रयोगहरू"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"ब्याट्री र डेटाका प्रयोग सम्बन्धी विवरणहरूका लागि ट्याप गर्नुहोस्"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"मोबाइल डेटा निष्क्रिय पार्ने हो?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings_car.xml b/packages/SystemUI/res/values-ne/strings_car.xml
index 1a4f8ef9..d4d7d0b 100644
--- a/packages/SystemUI/res/values-ne/strings_car.xml
+++ b/packages/SystemUI/res/values-ne/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"सुरक्षित तरिकाले सवारी चलाउनुहोस्"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ड्राइभिङ सर्तहरूका बारे पूर्ण सजग रहनुहोस् र जहिले पनि लागू हुने नियमहरूको पालना गर्नुहोस्। दिशा निर्देशनहरू अशुद्ध, अपूर्ण, खतरनाक, अनुपयुक्त, निषेधित वा प्रशासनिक क्षेत्र पार गर्ने हुन सक्छ। व्यवसायिक जानकारी अशुद्ध वा अपूर्ण पनि हुन सक्छ। डेटा वास्तविक समयको हुँदैन र स्थान सटीकताको ग्यारेन्टी गर्न सकिँदैन। आफ्नो मोबाइल यन्त्र ह्याण्डल गर्ने वा सवारी चलाएको बेलामा Android स्वतःको लागि लक्षित नगरिएका अनुप्रयोगहरूको प्रयोग गर्ने नगर्नुहोस्।"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"अज्ञात"</string>
+    <string name="start_driving" msgid="864023351402918991">"ड्राइभिङ सुरु गर्नुहोस्"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 3e36c13..ee113a7 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Meer instellingen"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Gereed"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Verbonden"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Verbonden, batterij <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Verbinding maken…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Je bent verbonden met <xliff:g id="APPLICATION">%1$s</xliff:g>, waarmee je persoonlijke netwerkactiviteit kan worden gecontroleerd, inclusief e-mails, apps en websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Je werkprofiel wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Het profiel is verbonden met <xliff:g id="APPLICATION">%2$s</xliff:g>, waarmee je werkgerelateerde netwerkactiviteit (waaronder e-mails, apps en websites) kan worden bijgehouden.\n\nNeem contact op met je beheerder voor meer informatie."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Je werkprofiel wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Het profiel is verbonden met <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, waarmee je werkgerelateerde netwerkactiviteit (waaronder e-mails, apps en websites) kan worden bijgehouden.\n\nJe bent ook verbonden met <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, waarmee je persoonlijke netwerkactiviteit kan worden bijgehouden."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Ontgrendeld voor <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> is actief"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Het apparaat blijft vergrendeld totdat u het handmatig ontgrendelt"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Sneller meldingen ontvangen"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Weergeven voordat u ontgrendelt"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Uit"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Met beheeropties voor meldingen met betrekking tot stroomverbruik kun je een belangrijkheidsniveau van 0 tot 5 instellen voor de meldingen van een app. \n\n"<b>"Niveau 5"</b>" \n- Boven aan de lijst met meldingen weergeven \n- Onderbreking op volledig scherm toestaan \n- Altijd korte weergave \n\n"<b>"Niveau 4"</b>" \n- Geen onderbreking op volledig scherm \n- Altijd korte weergave \n\n"<b>"Niveau 3"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n\n"<b>"Niveau 2"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n- Nooit geluid laten horen of trillen \n\n"<b>"Niveau 1"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n- Nooit geluid laten horen of trillen \n- Verbergen op vergrendelingsscherm en statusbalk \n- Onder aan de lijst met meldingen weergeven \n\n"<b>"Niveau 0"</b>" \n- Alle meldingen van de app blokkeren"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Meldingen"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Je ontvangt deze meldingen niet meer."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Je ontvangt deze meldingen niet meer"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> meldingscategorieën"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Deze app heeft geen meldingscategorieën"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Meldingen van deze app kunnen niet worden uitgeschakeld"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 van <xliff:g id="NUMBER_1">%d</xliff:g> meldingscategorieën van deze app</item>
       <item quantity="one">1 van <xliff:g id="NUMBER_0">%d</xliff:g> meldingscategorie van deze app</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"beheeropties voor meldingen"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"snooze-opties voor meldingen"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuten"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuten"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 uur"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 uur"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ONGEDAAN MAKEN"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozefunctie <xliff:g id="TIME_AMOUNT">%1$s</xliff:g> actief"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d uur</item>
+      <item quantity="one">%d uur</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minuten</item>
+      <item quantity="one">%d minuut</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Accugebruik"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterijbesparing niet beschikbaar tijdens opladen"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterijbesparing"</string>
@@ -744,7 +752,7 @@
     <string name="tuner_left" msgid="8404287986475034806">"Links"</string>
     <string name="tuner_right" msgid="6222734772467850156">"Rechts"</string>
     <string name="tuner_menu" msgid="191640047241552081">"Menu"</string>
-    <string name="tuner_app" msgid="3507057938640108777">"Apps <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="tuner_app" msgid="3507057938640108777">"<xliff:g id="APP">%1$s</xliff:g>-app"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Meldingen"</string>
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Screenshots"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Algemene berichten"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Vervangen"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Apps uitgevoerd op achtergrond"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tik voor batterij- en datagebruik"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Mobiele data uitschakelen?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings_car.xml b/packages/SystemUI/res/values-nl/strings_car.xml
index be66e01..32582e5 100644
--- a/packages/SystemUI/res/values-nl/strings_car.xml
+++ b/packages/SystemUI/res/values-nl/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Rijd veilig"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Blijf je volledig bewust van de rijomstandigheden en houd je altijd aan de wet. Aanwijzingen kunnen onnauwkeurig, onvolledig, gevaarlijk, ongeschikt of verboden zijn of het doorkruisen van overheidszones vereisen. Bedrijfsinformatie kan ook onnauwkeurg of onvolledig zijn. De gegevens worden niet in realtime verstrekt en de nauwkeurigheid van een locatie kan niet worden gegarandeerd. Bedien tijdens het rijden je mobiele apparaat niet en gebruik geen apps die niet bedoeld zijn voor Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Onbekend"</string>
+    <string name="start_driving" msgid="864023351402918991">"Beginnen met rijden"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa-land/strings.xml b/packages/SystemUI/res/values-pa-land/strings.xml
index fef122a..dfe2a5d 100644
--- a/packages/SystemUI/res/values-pa-land/strings.xml
+++ b/packages/SystemUI/res/values-pa-land/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="toast_rotation_locked" msgid="7609673011431556092">"ਸਕ੍ਰੀਨ ਹੁਣ ਲੈਂਡਸਕੇਪ ਅਨੁਕੂਲਨ ਵਿੱਚ ਲੌਕ ਕੀਤੀ ਗਈ ਹੈ।"</string>
+    <string name="toast_rotation_locked" msgid="7609673011431556092">"ਸਕ੍ਰੀਨ ਹੁਣ ਲੈਂਡਸਕੇਪ ਅਨੁਕੂਲਨ ਵਿੱਚ  ਲਾਕ  ਕੀਤੀ ਗਈ ਹੈ।"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 12b1dcb..bb21a99 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -24,7 +24,7 @@
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"ਸੂਚੀ ਵਿੱਚੋਂ ਹਟਾਓ"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"ਐਪ ਜਾਣਕਾਰੀ"</string>
     <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"ਤੁਹਾਡੀਆਂ ਹਾਲੀਆ ਸਕ੍ਰੀਨਾਂ ਇੱਥੇ ਪ੍ਰਗਟ ਹੋਣਗੀਆਂ"</string>
-    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"ਹਾਲੀਆ ਐਪਸ ਰੱਦ ਕਰੋ"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"ਹਾਲੀਆ ਐਪਾਂ ਨੂੰ ਖਾਰਜ ਕਰੋ"</string>
     <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
       <item quantity="one">ਰੂਪ-ਰੇਖਾ ਵਿੱਚ %d ਸਕ੍ਰੀਨਾਂ</item>
       <item quantity="other">ਰੂਪ-ਰੇਖਾ ਵਿੱਚ %d ਸਕ੍ਰੀਨਾਂ</item>
@@ -43,7 +43,7 @@
     <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"ਚਾਲੂ ਕਰੋ"</string>
     <string name="battery_saver_start_action" msgid="5576697451677486320">"ਬੈਟਰੀ ਸੇਵਰ ਚਾਲੂ ਕਰੋ"</string>
     <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_wifi_button" msgid="1733928151698311923">"ਵਾਈ-ਫਾਈ"</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_auto_brightness_label" msgid="511453614962324674">"ਆਟੋ"</string>
@@ -52,34 +52,34 @@
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ਇਨਪੁਟ ਵਿਧੀਆਂ ਸੈਟ ਅਪ ਕਰੋ"</string>
     <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"ਫਿਜੀਕਲ ਕੀ-ਬੋਰਡ"</string>
     <string name="usb_device_permission_prompt" msgid="834698001271562057">"ਕੀ ਐਪ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨੂੰ USB ਡੀਵਾਈਸ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
-    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"ਕੀ ਐਪ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨੂੰ USB ਐਕਸੈਸਰੀ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
-    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"ਕੀ ਜਦੋਂ ਇਹ USB ਡੀਵਾਈਸ ਕਨੈਕਟ ਕੀਤੀ ਜਾਂਦੀ ਹੈ ਤਾਂ <xliff:g id="ACTIVITY">%1$s</xliff:g> ਨੂੰ ਖੋਲ੍ਹਂਣਾ ਹੈ?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"ਕੀ ਐਪ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨੂੰ USB ਐਕਸੈੱਸਰੀ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
+    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"ਕੀ ਜਦੋਂ ਇਹ USB ਡੀਵਾਈਸ ਕਨੈਕਟ ਕੀਤੀ ਜਾਂਦੀ ਹੈ ਤਾਂ <xliff:g id="ACTIVITY">%1$s</xliff:g> ਨੂੰ ਖੋਲ੍ਹਣਾ ਹੈ?"</string>
     <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"ਕੀ ਜਦੋਂ ਇਹ USB ਐਕਸੈਸਰੀ ਕਨੈਕਟ ਕੀਤੀ ਜਾਂਦੀ ਹੈ ਤਾਂ <xliff:g id="ACTIVITY">%1$s</xliff:g> ਨੂੰ ਖੋਲ੍ਹਣਾ ਹੈ?"</string>
     <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"ਕੋਈ ਇੰਸਟੌਲ ਕੀਤੇ ਐਪਸ ਇਸ USB ਐਕਸੈਸਰੀ ਨਾਲ ਕੰਮ ਨਹੀਂ ਕਰਦੇ। <xliff:g id="URL">%1$s</xliff:g> ਤੇ ਇਸ ਐਕਸੈਸਰੀ ਬਾਰੇ ਹੋਰ ਜਾਣੋ"</string>
     <string name="title_usb_accessory" msgid="4966265263465181372">"USB ਐਕਸੈਸਰੀ"</string>
     <string name="label_view" msgid="6304565553218192990">"ਦੇਖੋ"</string>
-    <string name="always_use_device" msgid="1450287437017315906">"ਇਸ USB ਡੀਵਾਈਸ ਲਈ ਬਾਇ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਵਰਤੋ"</string>
-    <string name="always_use_accessory" msgid="1210954576979621596">"ਇਸ USB ਐਕਸਸੈਰੀ ਲਈ ਬਾਇ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਵਰਤੋ"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"ਇਸ USB ਡੀਵਾਈਸ ਲਈ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੌਰ \'ਤੇ ਵਰਤੋ"</string>
+    <string name="always_use_accessory" msgid="1210954576979621596">"ਇਸ USB ਐਕਸਸੈਰੀ ਲਈ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੌਰ \'ਤੇ ਵਰਤੋ"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"ਕੀ USB ਡੀਬਗਿੰਗ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"ਕੰਪਿਊਟਰ ਦਾ RSA ਕੁੰਜੀ ਫਿੰਗਰਪ੍ਰਿੰਟ ਹੈ:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"ਕੰਪਿਊਟਰ ਦਾ RSA ਕੁੰਜੀ ਫਿੰਗਰਪ੍ਰਿੰਟ \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"ਹਮੇਸ਼ਾਂ ਇਸ ਕੰਪਿਊਟਰ ਤੋਂ ਆਗਿਆ ਦਿਓ"</string>
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB ਡਿਬੱਗਿੰਗ ਦੀ ਆਗਿਆ ਨਹੀਂ"</string>
-    <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਵਰਤਮਾਨ ਵਿੱਚ ਸਾਈਨ ਇਨ ਕੀਤਾ ਉਪਭੋਗਤਾ USB ਡਿਬੱਗਿੰਗ ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਕਰ ਸਕਦਾ ਹੈ। ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਦਾ ਉਪਯੋਗ ਕਰਨ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਕਿਸੇ ਪ੍ਰਸ਼ਾਸਕ ਉਪਭੋਗਤਾ ਵਿੱਚ ਸਵਿੱਚ ਕਰੋ।"</string>
+    <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਵਰਤਮਾਨ ਵਿੱਚ ਸਾਈਨ-ਇਨ ਕੀਤਾ ਵਰਤੋਂਕਾਰ USB ਡਿਬੱਗਿੰਗ ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਕਰ ਸਕਦਾ ਹੈ। ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਕਿਸੇ ਪ੍ਰਸ਼ਾਸਕ ਵਰਤੋਂਕਾਰ ਵਿੱਚ ਸਵਿੱਚ ਕਰੋ।"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"ਸਕ੍ਰੀਨ ਭਰਨ ਲਈ ਜ਼ੂਮ ਕਰੋ"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ਸਕ੍ਰੀਨ ਭਰਨ ਲਈ ਸਟ੍ਰੈਚ ਕਰੋ"</string>
-    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"ਸਕ੍ਰੀਨਸ਼ੌਟ ਸੁਰੱਖਿਅਤ ਕਰ ਰਿਹਾ ਹੈ…"</string>
-    <string name="screenshot_saving_title" msgid="8242282144535555697">"ਸਕ੍ਰੀਨਸ਼ੌਟ ਸੁਰੱਖਿਅਤ ਕਰ ਰਿਹਾ ਹੈ…"</string>
-    <string name="screenshot_saving_text" msgid="2419718443411738818">"ਸਕ੍ਰੀਨਸ਼ੌਟ ਸੁਰੱਖਿਅਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"</string>
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸੁਰੱਖਿਅਤ ਕਰ ਰਿਹਾ ਹੈ…"</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸੁਰੱਖਿਅਤ ਕਰ ਰਿਹਾ ਹੈ…"</string>
+    <string name="screenshot_saving_text" msgid="2419718443411738818">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸੁਰੱਖਿਅਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"</string>
     <string name="screenshot_saved_title" msgid="6461865960961414961">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਕੈਪਚਰ ਕੀਤਾ।"</string>
-    <string name="screenshot_saved_text" msgid="2685605830386712477">"ਆਪਣਾ ਸਕ੍ਰੀਨਸ਼ਾਟ ਵੇਖਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="screenshot_failed_title" msgid="705781116746922771">"ਸਕ੍ਰੀਨਸ਼ੌਟ ਕੈਪਚਰ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string>
+    <string name="screenshot_saved_text" msgid="2685605830386712477">"ਆਪਣਾ ਸਕ੍ਰੀਨਸ਼ਾਟ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਕੈਪਚਰ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਰੱਖਿਅਤ ਕਰਨ ਦੌਰਾਨ ਸਮੱਸਿਆ ਆਈ।"</string>
-    <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"ਸੀਮਿਤ ਸਟੋਰੇਜ ਥਾਂ ਦੇ ਕਾਰਨ ਸਕ੍ਰੀਨਸ਼ਾਟ ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਸਕਦਾ।"</string>
+    <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"ਸਟੋਰੇਜ ਦੀ ਸੀਮਿਤ ਜਗ੍ਹਾ ਹੋਣ ਕਾਰਨ ਸਕ੍ਰੀਨਸ਼ਾਟ ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਸਕਦਾ।"</string>
     <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ਐਪ ਜਾਂ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈਣ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਹੈ"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ ਚੋਣਾਂ"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"ਇੱਕ ਮੀਡੀਆ ਪਲੇਅਰ (MTP) ਦੇ ਤੌਰ ਤੇ ਮਾਊਂਟ ਕਰੋ"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"ਇੱਕ ਕੈਮਰੇ (PTP) ਦੇ ਤੌਰ ਤੇ ਮਾਊਂਟ ਕਰੋ"</string>
-    <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac ਲਈ Android ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ ਐਪ ਇੰਸਟੌਲ ਕਰੋ"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac ਲਈ Android ਫ਼ਾਈਲ ਟ੍ਰਾਂਸਫਰ ਐਪ ਸਥਾਪਤ ਕਰੋ"</string>
     <string name="accessibility_back" msgid="567011538994429120">"ਪਿੱਛੇ"</string>
     <string name="accessibility_home" msgid="8217216074895377641">"ਘਰ"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"ਮੀਨੂ"</string>
@@ -87,18 +87,18 @@
     <string name="accessibility_recent" msgid="5208608566793607626">"ਰੂਪ-ਰੇਖਾ"</string>
     <string name="accessibility_search_light" msgid="1103867596330271848">"ਖੋਜੋ"</string>
     <string name="accessibility_camera_button" msgid="8064671582820358152">"ਕੈਮਰਾ"</string>
-    <string name="accessibility_phone_button" msgid="6738112589538563574">"ਫੋਨ"</string>
-    <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ਵੌਇਸ ਅਸਿਸਟ"</string>
-    <string name="accessibility_unlock_button" msgid="128158454631118828">"ਅਨਲੌਕ ਕਰੋ"</string>
+    <string name="accessibility_phone_button" msgid="6738112589538563574">"ਫ਼ੋਨ ਕਰੋ"</string>
+    <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ਅਵਾਜ਼ੀ ਸਹਾਇਕ"</string>
+    <string name="accessibility_unlock_button" msgid="128158454631118828">"ਅਣਲਾਕ ਕਰੋ"</string>
     <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਉਡੀਕ ਹੋ ਰਹੀ ਹੈ"</string>
-    <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ਆਪਣਾ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤੇ ਬਿਨਾਂ ਅਨਲੌਕ ਕਰੋ"</string>
-    <string name="unlock_label" msgid="8779712358041029439">"ਅਨਲੌਕ ਕਰੋ"</string>
-    <string name="phone_label" msgid="2320074140205331708">"ਫੋਨ ਖੋਲ੍ਹੋ"</string>
-    <string name="voice_assist_label" msgid="3956854378310019854">"ਵੌਇਸ ਅਸਿਸਟ ਖੋਲ੍ਹੋ"</string>
+    <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ਆਪਣਾ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤੇ ਬਿਨਾਂ ਅਣਲਾਕ ਕਰੋ"</string>
+    <string name="unlock_label" msgid="8779712358041029439">"ਅਣਲਾਕ ਕਰੋ"</string>
+    <string name="phone_label" msgid="2320074140205331708">"ਫ਼ੋਨ ਖੋਲ੍ਹੋ"</string>
+    <string name="voice_assist_label" msgid="3956854378310019854">"ਅਵਾਜ਼ੀ ਸਹਾਇਕ ਖੋਲ੍ਹੋ"</string>
     <string name="camera_label" msgid="7261107956054836961">"ਕੈਮਰਾ ਖੋਲ੍ਹੋ"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"ਨਵਾਂ ਕੰਮ ਲੇਆਉਟ ਚੁਣੋ"</string>
     <string name="cancel" msgid="6442560571259935130">"ਰੱਦ ਕਰੋ"</string>
-    <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"ਅਨੁਕੂਲਤਾ ਜ਼ੂਮ ਬਟਨ।"</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>
     <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth ਡਿਸਕਨੈਕਟ ਕੀਤਾ।"</string>
@@ -107,16 +107,16 @@
     <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"ਬੈਟਰੀ ਦੋ ਬਾਰਸ।"</string>
     <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"ਬੈਟਰੀ ਤਿੰਨ ਬਾਰਸ।"</string>
     <string name="accessibility_battery_full" msgid="8909122401720158582">"ਬੈਟਰੀ ਪੂਰੀ।"</string>
-    <string name="accessibility_no_phone" msgid="4894708937052611281">"ਕੋਈ ਫੋਨ ਨਹੀਂ।"</string>
-    <string name="accessibility_phone_one_bar" msgid="687699278132664115">"ਫੋਨ ਇੱਕ ਬਾਰ।"</string>
-    <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"ਫੋਨ ਦੋ ਬਾਰਸ।"</string>
-    <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"ਫੋਨ ਤਿੰਨ ਬਾਰਸ।"</string>
-    <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"ਫੋਨ ਸਿਗਨਲ ਪੂਰਾ।"</string>
-    <string name="accessibility_no_data" msgid="4791966295096867555">"ਕੋਈ ਡੈਟਾ ਨਹੀਂ।"</string>
-    <string name="accessibility_data_one_bar" msgid="1415625833238273628">"ਡੈਟਾ ਇੱਕ ਬਾਰ।"</string>
-    <string name="accessibility_data_two_bars" msgid="6166018492360432091">"ਡੈਟਾ ਦੋ ਬਾਰਸ।"</string>
-    <string name="accessibility_data_three_bars" msgid="9167670452395038520">"ਡੈਟਾ ਤਿੰਨ ਬਾਰ।"</string>
-    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"ਡੈਟਾ ਸਿਗਨਲ ਪੂਰਾ।"</string>
+    <string name="accessibility_no_phone" msgid="4894708937052611281">"ਕੋਈ ਫ਼ੋਨ ਨਹੀਂ।"</string>
+    <string name="accessibility_phone_one_bar" msgid="687699278132664115">"ਫ਼ੋਨ ਇੱਕ ਬਾਰ।"</string>
+    <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"ਫ਼ੋਨ ਦੋ ਬਾਰਸ।"</string>
+    <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"ਫ਼ੋਨ ਤਿੰਨ ਬਾਰਸ।"</string>
+    <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"ਫ਼ੋਨ ਸਿਗਨਲ ਪੂਰਾ।"</string>
+    <string name="accessibility_no_data" msgid="4791966295096867555">"ਕੋਈ  ਡਾਟਾ  ਨਹੀਂ।"</string>
+    <string name="accessibility_data_one_bar" msgid="1415625833238273628">" ਡਾਟਾ  ਇੱਕ ਬਾਰ।"</string>
+    <string name="accessibility_data_two_bars" msgid="6166018492360432091">" ਡਾਟਾ  ਦੋ ਬਾਰਸ।"</string>
+    <string name="accessibility_data_three_bars" msgid="9167670452395038520">" ਡਾਟਾ  ਤਿੰਨ ਬਾਰ।"</string>
+    <string name="accessibility_data_signal_full" msgid="2708384608124519369">" ਡਾਟਾ  ਸਿਗਨਲ ਪੂਰਾ।"</string>
     <string name="accessibility_wifi_name" msgid="7202151365171148501">"<xliff:g id="WIFI">%s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ।"</string>
     <string name="accessibility_bluetooth_name" msgid="8441517146585531676">"<xliff:g id="BLUETOOTH">%s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ।"</string>
     <string name="accessibility_cast_name" msgid="4026393061247081201">"<xliff:g id="CAST">%s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ।"</string>
@@ -150,15 +150,15 @@
     <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
     <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"ਰੋਮਿੰਗ"</string>
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"ਕਿਨਾਰਾ"</string>
-    <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
+    <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"ਵਾਈ-ਫਾਈ"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"ਕੋਈ SIM ਨਹੀਂ।"</string>
-    <string name="accessibility_cell_data" msgid="5326139158682385073">"ਮੋਬਾਈਲ ਡੈਟਾ"</string>
-    <string name="accessibility_cell_data_on" msgid="5927098403452994422">"ਮੋਬਾਈਲ ਡੈਟਾ ਚਾਲੂ ਹੈ"</string>
-    <string name="accessibility_cell_data_off" msgid="443267573897409704">"ਮੋਬਾਈਲ ਡੈਟਾ ਬੰਦ ਹੈ"</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth ਟੈਦਰਿੰਗ।"</string>
+    <string name="accessibility_cell_data" msgid="5326139158682385073">"ਮੋਬਾਈਲ ਡਾਟਾ"</string>
+    <string name="accessibility_cell_data_on" msgid="5927098403452994422">"ਮੋਬਾਈਲ ਡਾਟਾ ਚਾਲੂ"</string>
+    <string name="accessibility_cell_data_off" msgid="443267573897409704">"ਮੋਬਾਈਲ ਡਾਟਾ ਬੰਦ"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ਬਲੂਟੁੱਥ ਟੈਦਰਿੰਗ।"</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"ਏਅਰਪਲੇਨ ਮੋਡ।"</string>
     <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN ਚਾਲੂ ਹੈ।"</string>
-    <string name="accessibility_no_sims" msgid="3957997018324995781">"ਕੋਈ SIM ਕਾਰਡ ਨਹੀਂ।"</string>
+    <string name="accessibility_no_sims" msgid="3957997018324995781">"ਕੋਈ ਸਿਮ ਕਾਰਡ ਨਹੀਂ।"</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"ਕੈਰੀਅਰ ਨੈੱਟਵਰਕ ਪਰਿਵਰਤਨ।"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ਬੈਟਰੀ ਵੇਰਵੇ ਖੋਲ੍ਹੋ"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ਬੈਟਰੀ <xliff:g id="NUMBER">%d</xliff:g> ਪ੍ਰਤੀਸ਼ਤ ਹੈ।"</string>
@@ -175,7 +175,7 @@
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
     <string name="accessibility_work_mode" msgid="2478631941714607225">"ਕੰਮ ਮੋਡ"</string>
-    <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਰੱਦ ਕਰੋ।"</string>
+    <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਖਾਰਜ ਕਰੋ।"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ਰੱਦ ਕੀਤਾ।"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ਸਾਰੀਆਂ ਹਾਲੀਆ ਐਪਲੀਕੇਸ਼ਨਾਂ ਰੱਦ ਕੀਤੀਆਂ।"</string>
     <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> ਐਪਲੀਕੇਸ਼ਨਾਂ ਜਾਣਕਾਰੀ ਖੋਲ੍ਹੋ।"</string>
@@ -184,10 +184,10 @@
     <string name="accessibility_notification_dismissed" msgid="854211387186306927">"ਸੂਚਨਾ ਰੱਦ ਕੀਤੀ।"</string>
     <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"ਸੂਚਨਾ ਸ਼ੇਡ।"</string>
     <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ।"</string>
-    <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"ਲੌਕ ਸਕ੍ਰੀਨ।"</string>
+    <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">" ਲਾਕ  ਸਕ੍ਰੀਨ।"</string>
     <string name="accessibility_desc_settings" msgid="3417884241751434521">"ਸੈਟਿੰਗਾਂ"</string>
     <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"ਰੂਪ-ਰੇਖਾ।"</string>
-    <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"ਕਾਰਜ-ਸਥਾਨ ਲੌਕ ਸਕ੍ਰੀਨ"</string>
+    <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"ਕਾਰਜ-ਸਥਾਨ  ਲਾਕ  ਸਕ੍ਰੀਨ"</string>
     <string name="accessibility_desc_close" msgid="7479755364962766729">"ਬੰਦ ਕਰੋ"</string>
     <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>।"</string>
     <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wifi ਬੰਦ ਕੀਤਾ।"</string>
@@ -199,9 +199,9 @@
     <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_priority_on" msgid="1448402297221249355">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਚਾਲੂ, ਕੇਵਲ ਤਰਜੀਹੀ।"</string>
-    <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਚਾਲੂ ਕਰੋ, ਕੁਲ ਚੁੱਪੀ।"</string>
+    <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਚਾਲੂ ਕਰੋ, ਪੂਰਾ ਸ਼ਾਂਤ।"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਚਾਲੂ, ਕੇਵਲ ਅਲਾਰਮ।"</string>
-    <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ।"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ।"</string>
     <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਬੰਦ।"</string>
     <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਬੰਦ ਕੀਤਾ।"</string>
     <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਚਾਲੂ ਕੀਤਾ।"</string>
@@ -227,25 +227,25 @@
     <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"ਫਲੈਸ਼ਲਾਈਟ ਚਾਲੂ ਕੀਤੀ।"</string>
     <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"ਰੰਗ ਦੀ ਉਲਟੀ ਤਰਤੀਬ ਬੰਦ ਕੀਤੀ।"</string>
     <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"ਰੰਗ ਦੀ ਉਲਟੀ ਤਰਤੀਬ ਚਾਲੂ ਕੀਤੀ।"</string>
-    <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"ਮੋਬਾਈਲ ਹੌਟਸਪੌਟ ਬੰਦ ਕੀਤੀ।"</string>
-    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"ਮੋਬਾਈਲ ਹੌਟਸਪੌਟ ਚਾਲੂ ਕੀਤੀ।"</string>
+    <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"ਮੋਬਾਈਲ ਹੌਟਸਪੌਟ ਬੰਦ ਕੀਤਾ।"</string>
+    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"ਮੋਬਾਈਲ ਹੌਟਸਪੌਟ ਚਾਲੂ ਕੀਤਾ।"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"ਸਕ੍ਰੀਨ ਜੋੜਨਾ ਬੰਦ ਹੋਇਆ।"</string>
     <string name="accessibility_quick_settings_work_mode_off" msgid="7045417396436552890">"ਕੰਮ ਮੋਡ ਬੰਦ ਹੈ।"</string>
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"ਕੰਮ ਮੋਡ ਚਾਲੂ ਹੈ।"</string>
     <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"ਕੰਮ ਮੋਡ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"ਕੰਮ ਮੋਡ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string>
-    <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ਡੈਟਾ ਸੇਵਰ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
-    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"ਡੈਟਾ ਸੇਵਰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string>
+    <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ਡਾਟਾ ਸੇਵਰ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
+    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"ਡਾਟਾ ਸੇਵਰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"ਡਿਸਪਲੇ ਚਮਕ"</string>
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
-    <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ਡੈਟਾ ਰੁਕ ਗਿਆ ਹੈ"</string>
-    <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G ਡੈਟਾ ਰੁਕ ਗਿਆ ਹੈ"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"ਮੋਬਾਈਲ ਡੈਟਾ ਰੋਕ ਦਿੱਤਾ ਗਿਆ ਹੈ"</string>
-    <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"ਡੈਟਾ ਰੁਕ ਗਿਆ ਹੈ"</string>
-    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"ਤੁਸੀਂ ਤੁਹਾਡੇ ਵੱਲੋਂ ਸੈੱਟ ਕੀਤੀ ਗਈ ਡੈਟਾ ਸੀਮਾ \'ਤੇ ਪਹੁੰਚ ਚੁੱਕੇ ਹੋ। ਤੁਸੀਂ ਹੁਣ ਮੋਬਾਈਲ ਡੈਟੇ ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕਰ ਰਹੇ ਹੋ।\n\nਜੇਕਰ ਤੁਸੀਂ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਦੇ ਹੋ, ਤਾਂ ਡੈਟਾ ਵਰਤੋਂ ਲਈ ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ।"</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ਡਾਟਾ ਰੁਕ ਗਿਆ ਹੈ"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G  ਡਾਟਾ  ਰੁਕ ਗਿਆ ਹੈ"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"ਮੋਬਾਈਲ ਡਾਟਾ ਰੋਕ ਦਿੱਤਾ ਗਿਆ ਹੈ"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">" ਡਾਟਾ  ਰੁਕ ਗਿਆ ਹੈ"</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"ਤੁਸੀਂ ਤੁਹਾਡੇ ਵੱਲੋਂ ਸੈੱਟ ਕੀਤੀ ਗਈ ਡਾਟਾ ਸੀਮਾ \'ਤੇ ਪਹੁੰਚ ਚੁੱਕੇ ਹੋ। ਤੁਸੀਂ ਹੁਣ ਮੋਬਾਈਲ ਡਾਟੇ ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕਰ ਰਹੇ ਹੋ।\n\nਜੇਕਰ ਤੁਸੀਂ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਦੇ ਹੋ, ਤਾਂ ਡਾਟਾ ਵਰਤੋਂ ਲਈ ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ।"</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"ਦੁਬਾਰਾ ਸ਼ੁਰੂ ਕਰੋ"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"ਕੋਈ ਇੰਟਰਨੈਟ ਕਨੈਕਸ਼ਨ ਨਹੀਂ"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi ਕਨੈਕਟ ਕੀਤਾ"</string>
+    <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"ਕੋਈ ਇੰਟਰਨੈੱਟ ਕਨੈਕਸ਼ਨ ਨਹੀਂ"</string>
+    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"ਵਾਈ-ਫਾਈ ਕਨੈਕਟ ਹੈ"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS ਦੀ ਖੋਜ ਕਰ ਰਿਹਾ ਹੈ"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS ਵੱਲੋਂ ਸੈੱਟ ਕੀਤਾ ਗਿਆ ਟਿਕਾਣਾ"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਸੇਵਾ ਬੇਨਤੀਆਂ ਸਕਿਰਿਆ"</string>
@@ -258,19 +258,19 @@
     <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>
-    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"ਸਕ੍ਰੀਨ ਤਸਵੀਰ ਅਨੁਕੂਲਨ ਵਿੱਚ ਲੌਕ ਕੀਤੀ ਗਈ ਹੈ।"</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"ਸਕ੍ਰੀਨ ਲੈਂਡਸਕੇਪ ਅਨੁਕੂਲਨ ਵਿੱਚ  ਲਾਕ  ਕੀਤੀ ਹੈ।"</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"ਸਕ੍ਰੀਨ ਪੋਰਟਰੇਟ ਅਨੁਕੂਲਨ ਵਿੱਚ  ਲਾਕ  ਕੀਤੀ ਗਈ ਹੈ।"</string>
     <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"ਸਕ੍ਰੀਨ ਹੁਣ ਆਟੋਮੈਟਿਕਲੀ ਰੋਟੇਟ ਕਰੇਗੀ।"</string>
-    <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"ਸਕ੍ਰੀਨ ਹੁਣ ਲੈਂਡਸਕੇਪ ਅਨੁਕੂਲਨ ਵਿੱਚ ਲੌਕ ਕੀਤੀ ਗਈ ਹੈ।"</string>
-    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"ਸਕ੍ਰੀਨ ਹੁਣ ਤਸਵੀਰ ਅਨੁਕੂਲਨ ਵਿੱਚ ਲੌਕ ਕੀਤੀ ਗਈ ਹੈ।"</string>
+    <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"ਸਕ੍ਰੀਨ ਹੁਣ ਲੈਂਡਸਕੇਪ ਅਨੁਕੂਲਨ ਵਿੱਚ  ਲਾਕ  ਕੀਤੀ ਗਈ ਹੈ।"</string>
+    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"ਸਕ੍ਰੀਨ ਹੁਣ ਪੋਰਟਰੇਟ ਅਨੁਕੂਲਨ ਵਿੱਚ  ਲਾਕ  ਕੀਤੀ ਗਈ ਹੈ।"</string>
     <string name="dessert_case" msgid="1295161776223959221">"ਡੈਜ਼ਰਟ ਕੇਸ"</string>
     <string name="start_dreams" msgid="5640361424498338327">"ਸਕ੍ਰੀਨ ਸੇਵਰ"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ਈਥਰਨੈਟ"</string>
-    <string name="quick_settings_dnd_label" msgid="8735855737575028208">"ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</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_none_label" msgid="5025477807123029478">"ਸੰਪੂਰਨ ਖਾਮੋਸ਼ੀ"</string>
-    <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
+    <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"ਪੂਰਾ ਸ਼ਾਂਤ"</string>
+    <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"ਬਲੂਟੁੱਥ"</string>
     <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> ਡਿਵਾਈਸਾਂ)"</string>
     <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth ਬੰਦ"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"ਕੋਈ ਜੋੜਾਬੱਧ ਕੀਤੀਆਂ ਡੀਵਾਈਸਾਂ ਉਪਲਬਧ ਨਹੀਂ"</string>
@@ -278,10 +278,10 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"ਆਟੋ-ਰੋਟੇਟ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"ਸਕ੍ਰੀਨ ਨੂੰ ਆਪਣੇ ਆਪ ਘੁੰਮਾਓ"</string>
     <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"<xliff:g id="ID_1">%s</xliff:g> ਮੋਡ"</string>
-    <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"ਰੋਟੇਸ਼ਨ ਲੌਕ ਕੀਤੀ"</string>
-    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"ਤਸਵੀਰ"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"ਰੋਟੇਸ਼ਨ  ਲਾਕ  ਕੀਤੀ"</string>
+    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"ਪੋਰਟਰੇਟ"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"ਲੈਂਡਸਕੇਪ"</string>
-    <string name="quick_settings_ime_label" msgid="7073463064369468429">"ਇਨਪੁਟ ਵਿਧੀ"</string>
+    <string name="quick_settings_ime_label" msgid="7073463064369468429">"ਇਨਪੁੱਟ ਵਿਧੀ"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"ਟਿਕਾਣਾ"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਬੰਦ"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"ਮੀਡੀਆ ਡੀਵਾਈਸ"</string>
@@ -292,15 +292,15 @@
     <string name="quick_settings_user_label" msgid="5238995632130897840">"ਮੈਂ"</string>
     <string name="quick_settings_user_title" msgid="4467690427642392403">"ਵਰਤੋਂਕਾਰ"</string>
     <string name="quick_settings_user_new_user" msgid="9030521362023479778">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ"</string>
-    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
+    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"ਵਾਈ-ਫਾਈ"</string>
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"ਕੋਈ ਨੈੱਟਵਰਕ ਨਹੀਂ"</string>
-    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi ਬੰਦ"</string>
-    <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi ਚਾਲੂ"</string>
-    <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"ਕੋਈ Wi-Fi ਨੈੱਟਵਰਕ ਉਪਲਬਧ ਨਹੀਂ"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"ਵਾਈ-ਫਾਈ ਬੰਦ"</string>
+    <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"ਵਾਈ-ਫਾਈ ਚਾਲੂ"</string>
+    <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"ਕੋਈ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਉਪਲਬਧ ਨਹੀਂ"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"ਕਾਸਟ"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"ਕਾਸਟਿੰਗ"</string>
-    <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ਬਿਨਾਂ ਨਾਮ ਦਿੱਤੀ ਡੀਵਾਈਸ"</string>
+    <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ਬਿਨਾਂ ਨਾਮ ਦਾ ਡੀਵਾਈਸ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"ਜੋੜਨ ਲਈ ਤਿਆਰ"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"ਕੋਈ ਡਿਵਾਈਸਾਂ ਉਪਲਬਧ ਨਹੀਂ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ਚਮਕ"</string>
@@ -310,14 +310,15 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"ਹੋਰ ਸੈਟਿੰਗਾਂ"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"ਹੋ ਗਿਆ"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"ਕਨੈਕਟ ਕੀਤਾ"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"ਕਨੈਕਟ ਕੀਤੀ ਗਈ, ਬੈਟਰੀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"ਕਨੈਕਟ ਕਰ ਰਿਹਾ ਹੈ..."</string>
-    <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ਟੀਥਰਿੰਗ"</string>
+    <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ਟੈਦਰਿੰਗ"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ਹੌਟਸਪੌਟ"</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>
-    <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ਬਾਕੀ ਡੈਟਾ"</string>
+    <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"ਮੋਬਾਈਲ ਡਾਟਾ"</string>
+    <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ਡਾਟਾ ਵਰਤੋਂ"</string>
+    <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ਬਾਕੀ  ਡਾਟਾ"</string>
     <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"ਸੀਮਾ ਤੋਂ ਵੱਧ"</string>
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> ਵਰਤਿਆ"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ਸੀਮਾ"</string>
@@ -338,7 +339,7 @@
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ ਇੱਥੇ ਘਸੀਟੋ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ਹੌਰੀਜ਼ੌਂਟਲ ਸਪਲਿਟ"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ਵਰਟੀਕਲ ਸਪਲਿਟ"</string>
-    <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"ਕਸਟਮ ਸਪਲਿਟ"</string>
+    <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"ਵਿਉਂਂਤੀ ਸਪਲਿਟ"</string>
     <string name="recents_accessibility_split_screen_top" msgid="9056056469282256287">"ਸਕ੍ਰੀਨ ਨੂੰ ਉੱਪਰ ਵੱਲ ਵਿਭਾਜਿਤ ਕਰੋ"</string>
     <string name="recents_accessibility_split_screen_left" msgid="8987144699630620019">"ਸਕ੍ਰੀਨ ਨੂੰ ਖੱਬੇ ਪਾਸੇ ਵਿਭਾਜਿਤ ਕਰੋ"</string>
     <string name="recents_accessibility_split_screen_right" msgid="275069779299592867">"ਸਕ੍ਰੀਨ ਨੂੰ ਸੱਜੇ ਪਾਸੇ ਵਿਭਾਜਿਤ ਕਰੋ"</string>
@@ -354,20 +355,20 @@
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ਤੱਕ ਖੱਬੇ ਪਾਸੇ ਸਲਾਈਡ ਕਰੋ।"</string>
     <string name="zen_priority_introduction" msgid="7577965386868311310">"ਧੁਨੀਆਂ ਅਤੇ ਥਰਥਰਾਹਟਾਂ ਤੁਹਾਨੂੰ ਪਰੇਸ਼ਾਨ ਨਹੀਂ ਕਰਨਗੀਆਂ, ਸਿਵਾਏ ਅਲਾਰਮਾਂ, ਯਾਦ-ਦਹਾਨੀਆਂ, ਵਰਤਾਰਿਆਂ, ਅਤੇ ਤੁਹਾਡੇ ਵੱਲੋਂ ਨਿਰਧਾਰਤ ਕੀਤੇ ਕਾਲਰਾਂ ਦੀ ਸੂਰਤ ਵਿੱਚ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਸੰਗੀਤ, ਵੀਡੀਓ ਅਤੇ ਗੇਮਾਂ ਸਮੇਤ ਆਪਣੀ ਚੋਣ ਅਨੁਸਾਰ ਕੁਝ ਵੀ ਸੁਣ ਸਕਦੇ ਹੋ।"</string>
     <string name="zen_alarms_introduction" msgid="7034415210361973827">"ਧੁਨੀਆਂ ਅਤੇ ਥਰਥਰਾਹਟਾਂ ਤੁਹਾਨੂੰ ਪਰੇਸ਼ਾਨ ਨਹੀਂ ਕਰਨਗੀਆਂ, ਸਿਵਾਏ ਅਲਾਰਮਾਂ ਦੀ ਸੂਰਤ ਵਿੱਚ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਸੰਗੀਤ, ਵੀਡੀਓ ਅਤੇ ਗੇਮਾਂ ਸਮੇਤ ਆਪਣੀ ਚੋਣ ਅਨੁਸਾਰ ਕੁਝ ਵੀ ਸੁਣ ਸਕਦੇ ਹੋ।"</string>
-    <string name="zen_priority_customize_button" msgid="7948043278226955063">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
-    <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ਇਹ ਅਲਾਰਮ, ਸੰਗੀਤ, ਵੀਡੀਓ, ਅਤੇ ਗੇਮਾਂ ਸਮੇਤ, ਸਾਰੀਆਂ ਧੁਨੀਆਂ ਅਤੇ ਥਰਥਰਾਹਟ ਨੂੰ ਬਲੌਕ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਫ਼ੋਨ ਕਾਲ ਕਰਨ ਦੇ ਯੋਗ ਹੋਵੋਂਗੇ।"</string>
+    <string name="zen_priority_customize_button" msgid="7948043278226955063">"ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
+    <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ਇਹ ਅਲਾਰਮ, ਸੰਗੀਤ, ਵੀਡੀਓ, ਅਤੇ ਗੇਮਾਂ ਸਮੇਤ, ਸਾਰੀਆਂ ਧੁਨੀਆਂ ਅਤੇ ਥਰਥਰਾਹਟ ਨੂੰ ਬਲਾਕ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਫ਼ੋਨ ਕਾਲ ਕਰਨ ਦੇ ਯੋਗ ਹੋਵੋਂਗੇ।"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"ਇਹ ਅਲਾਰਮ, ਸੰਗੀਤ, ਵੀਡੀਓਜ਼, ਅਤੇ ਗੇਮਸ ਸਮੇਤ, ਸਾਰੀਆਂ ਧੁਨੀਆਂ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਨੂੰ ਬਲੌਕ ਕਰਦਾ ਹੈ।"</string>
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ਹੇਠਾਂ ਘੱਟ ਲਾਜ਼ਮੀ ਸੂਚਨਾਵਾਂ"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ਖੋਲ੍ਹਣ ਲਈ ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"ਅਨਲੌਕ ਕਰਨ ਲਈ ਉੱਪਰ ਸਵਾਈਪ ਕਰੋ।"</string>
+    <string name="keyguard_unlock" msgid="8043466894212841998">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਉੱਪਰ ਸਵਾਈਪ ਕਰੋ।"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਸੰਗਠਨ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
-    <string name="do_disclosure_with_name" msgid="5640615509915445501">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤੀ ਗਈ ਹੈ"</string>
-    <string name="phone_hint" msgid="4872890986869209950">"ਫ਼ੋਨ ਲਈ ਆਈਕਨ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
-    <string name="voice_hint" msgid="8939888732119726665">"ਵੌਇਸ ਅਸਿਸਟ ਲਈ ਆਈਕਨ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
-    <string name="camera_hint" msgid="7939688436797157483">"ਕੈਮਰੇ ਲਈ ਆਈਕਨ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
-    <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"ਕੁੱਲ ਸਾਈਲੈਂਟ। ਇਹ ਸਕ੍ਰੀਨ ਰੀਡਰਾਂ ਨੂੰ ਵੀ ਸਾਈਲੈਂਸ ਕਰ ਦੇਵੇਗਾ।"</string>
-    <string name="interruption_level_none" msgid="6000083681244492992">"ਸੰਪੂਰਨ ਖਾਮੋਸ਼ੀ"</string>
+    <string name="do_disclosure_with_name" msgid="5640615509915445501">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+    <string name="phone_hint" msgid="4872890986869209950">"ਫ਼ੋਨ ਲਈ ਪ੍ਰਤੀਕ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
+    <string name="voice_hint" msgid="8939888732119726665">"ਅਵਾਜ਼ੀ ਸਹਾਇਕ ਲਈ ਪ੍ਰਤੀਕ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
+    <string name="camera_hint" msgid="7939688436797157483">"ਕੈਮਰੇ ਲਈ ਪ੍ਰਤੀਕ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
+    <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_none_twoline" msgid="3957581548190765889">"ਕੁਲ \n ਚੁੱਪੀ"</string>
@@ -376,35 +377,35 @@
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ਚਾਰਜਿੰਗ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ਪੂਰਾ ਹੋਣ ਤੱਕ)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"ਤੇਜ਼ੀ ਨਾਲ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ਪੂਰੀ ਹੋਣ ਤੱਕ)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"ਹੌਲੀ-ਹੌਲੀ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ਪੂਰੀ ਹੋਣ ਤੱਕ)"</string>
-    <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ਉਪਭੋਗਤਾ ਸਵਿਚ ਕਰੋ"</string>
-    <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ਉਪਭੋਗਤਾ, ਵਰਤਮਾਨ ਉਪਭੋਗਤਾ ਸਵਿਚ ਕਰੋ<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
+    <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ਵਰਤੋਂਕਾਰ ਸਵਿੱਚ ਕਰੋ"</string>
+    <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ਵਰਤੋਂਕਾਰ, ਵਰਤਮਾਨ ਵਰਤੋਂਕਾਰ ਸਵਿੱਚ ਕਰੋ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"ਮੌਜੂਦਾ ਉਪਭੋਗਤਾ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <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_new_guest" msgid="600537543078847803">"ਮਹਿਮਾਨ ਜੋੜੋ"</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_dialog_message" msgid="4155503224769676625">"ਇਸ ਸੈਸ਼ਨ ਵਿੱਚ ਸਾਰੇ ਐਪਸ ਅਤੇ ਡੈਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਏਗਾ।"</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_message" msgid="8476238178270112811">"ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਸੈਸ਼ਨ ਜਾਰੀ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
     <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"ਸ਼ੁਰੂ ਕਰੋ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"ਹਾਂ, ਜਾਰੀ ਰੱਖੋ"</string>
     <string name="guest_notification_title" msgid="1585278533840603063">"ਮਹਿਮਾਨ ਉਪਭੋਗਤਾ"</string>
-    <string name="guest_notification_text" msgid="335747957734796689">"ਐਪਸ ਅਤੇ ਡੈਟਾ ਮਿਟਾਉਣ ਲਈ, ਮਹਿਮਾਨ ਉਪਭੋਗਤਾ ਹਟਾਓ"</string>
-    <string name="guest_notification_remove_action" msgid="8820670703892101990">"ਮਹਿਮਾਨ ਨੂੰ ਹਟਾਓ"</string>
+    <string name="guest_notification_text" msgid="335747957734796689">"ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਮਿਟਾਉਣ ਲਈ, ਮਹਿਮਾਨ ਵਰਤੋਂਕਾਰ ਹਟਾਓ"</string>
+    <string name="guest_notification_remove_action" msgid="8820670703892101990">"ਮਹਿਮਾਨ ਹਟਾਓ"</string>
     <string name="user_logout_notification_title" msgid="1453960926437240727">"ਉਪਭੋਗਤਾ ਨੂੰ ਲੌਗ ਆਉਟ ਕਰੋ"</string>
     <string name="user_logout_notification_text" msgid="3350262809611876284">"ਵਰਤਮਾਨ ਉਪਭੋਗਤਾ ਨੂੰ ਲੌਗਆਉਟ ਕਰੋ"</string>
     <string name="user_logout_notification_action" msgid="1195428991423425062">"ਉਪਭੋਗਤਾ ਨੂੰ ਲੌਗ ਆਉਟ ਕਰੋ"</string>
     <string name="user_add_user_title" msgid="4553596395824132638">"ਕੀ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਨਾ ਹੈ?"</string>
     <string name="user_add_user_message_short" msgid="2161624834066214559">"ਜਦੋਂ ਤੁਸੀਂ ਇੱਕ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਦੇ ਹੋ, ਉਸ ਵਿਅਕਤੀ ਨੂੰ ਆਪਣੀ ਜਗ੍ਹਾ ਸਥਾਪਤ ਕਰਨ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ।\n\nਕੋਈ ਵੀ ਵਰਤੋਂਕਾਰ ਹੋਰ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰ ਸਕਦਾ ਹੈ।"</string>
     <string name="user_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="237918726750955859">"ਬੈਟਰੀ ਸੇਵਰ ਚਾਲੂ ਹੈ"</string>
-    <string name="battery_saver_notification_text" msgid="820318788126672692">"ਪ੍ਰਦਰਸ਼ਨ ਅਤੇ ਪਿਛੋਕੜ ਡੈਟਾ ਘੱਟ ਕਰਦਾ ਹੈ"</string>
+    <string name="battery_saver_notification_text" msgid="820318788126672692">"ਪ੍ਰਦਰਸ਼ਨ ਅਤੇ ਪਿਛੋਕੜ  ਡਾਟਾ  ਘੱਟ ਕਰਦਾ ਹੈ"</string>
     <string name="battery_saver_notification_action_text" msgid="109158658238110382">"ਬੈਟਰੀ ਸੇਵਰ ਬੰਦ ਕਰੋ"</string>
     <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>
@@ -437,20 +438,20 @@
     <string name="monitoring_subtitle_ca_certificate" msgid="3874151893894355988">"CA ਪ੍ਰਮਾਣ-ਪੱਤਰ"</string>
     <string name="disable_vpn" msgid="4435534311510272506">"VPN ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"VPN ਨੂੰ ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
-    <string name="monitoring_button_view_policies" msgid="100913612638514424">"ਨੀਤੀਆਂ ਵੇਖੋ"</string>
-    <string name="monitoring_description_named_management" msgid="5281789135578986303">"ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।\n\nਤੁਹਾਡਾ ਪ੍ਰਸ਼ਾਸਕ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਨਾਲ ਸਬੰਧਿਤ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਾਂ, ਡੈਟੇ ਅਤੇ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਦੀ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਦੀ ਨਿਗਰਾਨੀ ਅਤੇ ਉਹਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦਾ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
-    <string name="monitoring_description_management" msgid="4573721970278370790">"ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।\n\nਤੁਹਾਡਾ ਪ੍ਰਸ਼ਾਸਕ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਨਾਲ ਸਬੰਧਿਤ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਾਂ, ਡੈਟੇ ਅਤੇ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਦੀ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ ਅਤੇ ਉਹਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦਾ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
+    <string name="monitoring_button_view_policies" msgid="100913612638514424">"ਨੀਤੀਆਂ ਦੇਖੋ"</string>
+    <string name="monitoring_description_named_management" msgid="5281789135578986303">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।\n\nਤੁਹਾਡਾ ਪ੍ਰਸ਼ਾਸਕ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਸਬੰਧਿਤ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਾਂ, ਡਾਟਾ ਅਤੇ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਦੀ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਦੀ ਨਿਗਰਾਨੀ ਅਤੇ ਉਹਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦਾ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
+    <string name="monitoring_description_management" msgid="4573721970278370790">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।\n\nਤੁਹਾਡਾ ਪ੍ਰਸ਼ਾਸਕ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਸਬੰਧਿਤ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਾਂ, ਡਾਟਾ ਅਤੇ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੀ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ ਅਤੇ ਉਹਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦਾ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਇੱਕ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਥਾਰਟੀ ਸਥਾਪਤ ਕੀਤੀ ਗਈ ਹੈ। ਤੁਹਾਡੇ ਸੁਰੱਖਿਅਤ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਾਂ ਉਸਨੂੰ ਸੋਧਿਆ ਜਾ ਸਕਦਾ ਹੈ।"</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ ਇੱਕ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਥਾਰਟੀ ਸਥਾਪਤ ਕੀਤੀ ਗਈ ਹੈ। ਤੁਹਾਡੇ ਸੁਰੱਖਿਅਤ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਾਂ ਉਸਨੂੰ ਸੋਧਿਆ ਜਾ ਸਕਦਾ ਹੈ।"</string>
     <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"ਇੱਕ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਥਾਰਟੀ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਸਥਾਪਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਤੁਹਾਡੇ ਸੁਰੱਖਿਅਤ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਾਂ ਉਸਨੂੰ ਸੋਧਿਆ ਜਾ ਸਕਦਾ ਹੈ।"</string>
-    <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਨੈੱਟਵਰਕ ਲੌਗਿੰਗ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਹੋਇਆ ਹੈ, ਜੋ ਤੁਹਾਡੀ ਡੀਵਾਈਸ \'ਤੇ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰਦਾ ਹੈ।"</string>
+    <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਨੈੱਟਵਰਕ ਲੌਗਿੰਗ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਹੋਇਆ ਹੈ, ਜੋ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰਦਾ ਹੈ।"</string>
     <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"ਤੁਸੀਂ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
     <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"ਤੁਸੀਂ <xliff:g id="VPN_APP_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="VPN_APP_1">%2$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
-    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
-    <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"ਤੁਹਾਡਾ ਨਿੱਜੀ ਪ੍ਰੋਫਾਈਲ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
-    <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"ਤੁਹਾਡੀ ਡੀਵਾਈਸ <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ।"</string>
-    <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਦੇ ਪ੍ਰਬੰਧਨ ਲਈ <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ।"</string>
-    <string name="monitoring_description_do_body" msgid="3639594537660975895">"ਤੁਹਾਡਾ ਪ੍ਰਸ਼ਾਸਕ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਾਂ, ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਨਾਲ ਜੁੜੇ ਡੈਟੇ ਅਤੇ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਦੀ ਨਿਗਰਾਨੀ ਅਤੇ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦਾ ਹੈ।"</string>
+    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"ਤੁਹਾਡੀ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
+    <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"ਤੁਹਾਡੀ ਨਿੱਜੀ ਪ੍ਰੋਫਾਈਲ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
+    <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"ਤੁਹਾਡਾ ਡੀਵਾਈਸ <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।"</string>
+    <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੇ ਪ੍ਰਬੰਧਨ ਲਈ <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ।"</string>
+    <string name="monitoring_description_do_body" msgid="3639594537660975895">"ਤੁਹਾਡਾ ਪ੍ਰਸ਼ਾਸਕ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਾਂ, ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਜੁੜੇ ਡਾਟੇ ਅਤੇ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਦੀ ਨਿਗਰਾਨੀ ਅਤੇ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦਾ ਹੈ।"</string>
     <string name="monitoring_description_do_learn_more_separator" msgid="3785251953067436862">" "</string>
     <string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"ਹੋਰ ਜਾਣੋ"</string>
     <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"ਤੁਸੀਂ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
@@ -458,18 +459,20 @@
     <string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"VPN ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ"</string>
     <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
     <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"ਭਰੋਸੇਯੋਗ ਕ੍ਰੀਡੈਂਸ਼ੀਅਲ ਖੋਲ੍ਹੋ"</string>
-    <string name="monitoring_description_network_logging" msgid="7223505523384076027">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਨੈੱਟਵਰਕ ਲੌਗਿੰਗ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਹੋਇਆ ਹੈ, ਜੋ ਤੁਹਾਡੀ ਡੀਵਾਈਸ \'ਤੇ ਟ੍ਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰਦਾ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
-    <string name="monitoring_description_vpn" msgid="4445150119515393526">"ਤੁਸੀਂ ਇੱਕ ਐਪ ਨੂੰ ਇੱਕ VPN ਕਨੈਕਸ਼ਨ ਸੈਟ ਅਪ ਕਰਨ ਦੀ ਅਨੁਮਤੀ ਦਿੱਤੀ ਹੈ।\n\nਇਹ ਐਪ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਅਤੇ ਨੈੱਟਵਰਕ ਗਤੀਵਿਧੀ ਦਾ ਨਿਰੀਖਣ ਕਰ ਸਕਦਾ ਹੈ, ਈਮੇਲਾਂ, ਐਪਸ ਅਤੇ ਸੁਰੱਖਿਅਤ ਵੈਬਸਾਈਟਾਂ ਸਮੇਤ।"</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"ਤੁਹਾਡੇ ਕਾਰਜ-ਸਥਾਨ ਪ੍ਰੋਫ਼ਾਈਲ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।\n\nਤੁਹਾਡਾ ਪ੍ਰਸ਼ਾਸਕ ਈਮੇਲ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰਨ ਦੇ ਸਮਰੱਥ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।\n\nਤੁਸੀਂ ਇੱਕ VPN ਨਾਲ ਵੀ ਕਨੈਕਟ ਹੋਂ, ਜੋ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ।"</string>
+    <string name="monitoring_description_network_logging" msgid="7223505523384076027">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਨੈੱਟਵਰਕ ਲੌਗਿੰਗ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਹੋਇਆ ਹੈ, ਜੋ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰਦਾ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
+    <string name="monitoring_description_vpn" msgid="4445150119515393526">"ਤੁਸੀਂ ਕਿਸੇ ਐਪ ਨੂੰ ਇੱਕ VPN ਕਨੈਕਸ਼ਨ ਸੈੱਟ ਅੱਪ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੱਤੀ ਹੈ।\n\nਇਹ ਐਪ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਅਤੇ ਨੈੱਟਵਰਕ ਗਤੀਵਿਧੀ ਦਾ ਨਿਰੀਖਣ ਕਰ ਸਕਦੀ ਹੈ, ਈਮੇਲਾਂ, ਐਪਾਂ ਅਤੇ ਸੁਰੱਖਿਅਤ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ।"</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।\n\nਤੁਹਾਡਾ ਪ੍ਰਸ਼ਾਸਕ ਈਮੇਲ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰਨ ਦੇ ਸਮਰੱਥ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।\n\nਤੁਸੀਂ ਇੱਕ VPN ਨਾਲ ਵੀ ਕਨੈਕਟ ਹੋਂ, ਜੋ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ।"</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
     <string name="monitoring_description_app" msgid="1828472472674709532">"ਤੁਸੀਂ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
     <string name="monitoring_description_app_personal" msgid="484599052118316268">"ਤੁਸੀਂ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲ, ਐਪਸ ਅਤੇ ਵੈਬਸਫ਼ਿਆਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਗਤੀਵਿਧੀ ਦਾ ਨਿਰੀਖਣ ਕਰ ਸਕਦੀ ਹੈ।"</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"ਤੁਸੀਂ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨਿੱਜੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
-    <string name="monitoring_description_app_work" msgid="4612997849787922906">"ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫ਼ਾਈਲ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਇਹ ਪ੍ਰੋਫ਼ਾਈਲ <xliff:g id="APPLICATION">%2$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਕਾਰਜ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
+    <string name="monitoring_description_app_work" msgid="4612997849787922906">"ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਇਹ ਪ੍ਰੋਫਾਈਲ <xliff:g id="APPLICATION">%2$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਕਾਰਜ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਪ੍ਰੋਫਾਈਲ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ ਹੈ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਕਾਰਜ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।\n\nਤੁਸੀਂ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ਨਾਲ ਵੀ ਕਨੈਕਟ ਹੋਂ, ਜੋ ਤੁਹਾਡੀ ਨਿੱਜੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
-    <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"ਡੀਵਾਈਸ ਲੌਕ ਰਹੇਗੀ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਮੈਨੂਅਲੀ ਅਨਲੌਕ ਨਹੀਂ ਕਰਦੇ"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> ਲਈ ਅਣਲਾਕ ਕੀਤੀ ਗਈ"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ਚੱਲ ਰਿਹਾ ਹੈ"</string>
+    <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"ਡੀਵਾਈਸ ਲਾਕ ਰਹੇਗਾ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਮੈਨੂਅਲੀ ਅਣਲਾਕ ਨਹੀਂ ਕਰਦੇ"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"ਤੇਜ਼ੀ ਨਾਲ ਸੂਚਨਾਵਾਂ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
-    <string name="hidden_notifications_text" msgid="2326409389088668981">"ਅਨਲੌਕ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਉਹਨਾਂ ਨੂੰ ਦੇਖੋ"</string>
+    <string name="hidden_notifications_text" msgid="2326409389088668981">"ਅਣਲਾਕ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਉਹਨਾਂ ਨੂੰ ਦੇਖੋ"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"ਸਥਾਪਤ ਕਰੋ"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
@@ -484,8 +487,8 @@
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"ਕੀ <xliff:g id="TILE_LABEL">%1$s</xliff:g> ਨੂੰ ਲੁਕਾਉਣਾ ਹੈ?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"ਇਹ ਅਗਲੀ ਵਾਰ ਮੁੜ ਪ੍ਰਗਟ ਹੋਵੇਗਾ ਜਦੋਂ ਤੁਸੀਂ ਇਸਨੂੰ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਚਾਲੂ ਕਰਦੇ ਹੋ।"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"ਲੁਕਾਓ"</string>
-    <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ਤੁਸੀਂ ਆਪਣੀ ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਵਰਤ ਰਹੇ ਹੋ"</string>
-    <string name="stream_voice_call" msgid="4410002696470423714">"ਕਾਲ"</string>
+    <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ਤੁਸੀਂ ਆਪਣੀ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਰਤ ਰਹੇ ਹੋ"</string>
+    <string name="stream_voice_call" msgid="4410002696470423714">"ਕਾਲ ਕਰੋ"</string>
     <string name="stream_system" msgid="7493299064422163147">"ਸਿਸਟਮ"</string>
     <string name="stream_ring" msgid="8213049469184048338">"ਘੰਟੀ ਵਜਾਓ"</string>
     <string name="stream_music" msgid="9086982948697544342">"ਮੀਡੀਆ"</string>
@@ -499,22 +502,22 @@
     <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_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s ਵੌਲਿਊਮ ਕੰਟਰੋਲ ਵਿਖਾਏ ਗਏ ਹਨ। ਬਰਖ਼ਾਸਤ ਕਰਨ ਲਈ ਉੱਪਰ ਸਵਾਈਪ ਕਰੋ।"</string>
+    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s ਅਵਾਜ਼ ਕੰਟਰੋਲ ਦਿਖਾਏ ਗਏ ਹਨ। ਖਾਰਜ ਕਰਨ ਲਈ ਉੱਪਰ ਸਵਾਈਪ ਕਰੋ।"</string>
     <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"ਵੌਲਿਊਮ ਕੰਟਰੋਲ ਲੁਕਾਏ ਗਏ ਹਨ"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI ਟਿਊਨਰ"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"ਜੋਡ਼ੀ ਗਈ ਬੈਟਰੀ ਪ੍ਰਤਿਸ਼ਤਤਾ ਦਿਖਾਓ"</string>
-    <string name="show_battery_percentage_summary" msgid="3215025775576786037">"ਜਦੋਂ ਚਾਰਜ ਨਾ ਹੋ ਰਹੀ ਹੋਵੇ ਤਾਂ ਸਥਿਤੀ ਬਾਰ ਦੇ ਅੰਦਰ ਬੈਟਰੀ ਪੱਧਰ ਪ੍ਰਤਿਸ਼ਤਤਾ ਦਿਖਾਓ"</string>
-    <string name="quick_settings" msgid="10042998191725428">"ਤਤਕਾਲ ਸੈੱਟਿੰਗਜ਼"</string>
-    <string name="status_bar" msgid="4877645476959324760">"ਸਥਿਤੀ ਬਾਰ"</string>
+    <string name="show_battery_percentage_summary" msgid="3215025775576786037">"ਜਦੋਂ ਚਾਰਜ ਨਾ ਹੋ ਰਹੀ ਹੋਵੇ ਤਾਂ ਸਥਿਤੀ ਪੱਟੀ ਪ੍ਰਤੀਕ ਦੇ ਅੰਦਰ ਬੈਟਰੀ ਪੱਧਰ ਪ੍ਰਤਿਸ਼ਤਤਾ ਦਿਖਾਓ"</string>
+    <string name="quick_settings" msgid="10042998191725428">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ"</string>
+    <string name="status_bar" msgid="4877645476959324760">"ਸਥਿਤੀ ਪੱਟੀ"</string>
     <string name="overview" msgid="4018602013895926956">"ਰੂਪ-ਰੇਖਾ"</string>
     <string name="demo_mode" msgid="2532177350215638026">"ਸਿਸਟਮ UI ਡੈਮੋ ਮੋਡ"</string>
-    <string name="enable_demo_mode" msgid="4844205668718636518">"ਡੈਮੋ ਮੋਡ ਸਮਰੱਥ ਬਣਾਓ"</string>
+    <string name="enable_demo_mode" msgid="4844205668718636518">"ਡੈਮੋ ਮੋਡ ਚਾਲੂ ਕਰੋ"</string>
     <string name="show_demo_mode" msgid="2018336697782464029">"ਡੈਮੋ ਮੋਡ ਦੇਖੋ"</string>
     <string name="status_bar_ethernet" msgid="5044290963549500128">"ਈਥਰਨੈਟ"</string>
     <string name="status_bar_alarm" msgid="8536256753575881818">"ਅਲਾਰਮ"</string>
-    <string name="status_bar_work" msgid="6022553324802866373">"ਕੰਮ ਪ੍ਰੋਫਾਈਲ"</string>
+    <string name="status_bar_work" msgid="6022553324802866373">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
     <string name="status_bar_airplane" msgid="7057575501472249002">"ਜਹਾਜ਼ ਮੋਡ"</string>
-    <string name="add_tile" msgid="2995389510240786221">"ਟਾਇਲ ਜੋੜੋ"</string>
+    <string name="add_tile" msgid="2995389510240786221">"ਟਾਇਲ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="broadcast_tile" msgid="3894036511763289383">"ਪ੍ਰਸਾਰਨ ਟਾਇਲ"</string>
     <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"ਤੁਸੀਂ <xliff:g id="WHEN">%1$s</xliff:g> ਵਜੇ ਆਪਣਾ ਅਗਲਾ ਅਲਾਰਮ ਨਹੀਂ ਸੁਣੋਗੇ ਜਦੋਂ ਤੱਕ ਉਸਤੋਂ ਪਹਿਲਾਂ ਤੁਸੀਂ ਇਸਨੂੰ ਬੰਦ ਨਹੀਂ ਕਰਦੇ"</string>
     <string name="zen_alarm_warning" msgid="444533119582244293">"ਤੁਸੀਂ <xliff:g id="WHEN">%1$s</xliff:g> ਵਜੇ ਆਪਣਾ ਅਗਲਾ ਅਲਾਰਮ ਨਹੀਂ ਸੁਣੋਗੇ"</string>
@@ -522,38 +525,39 @@
     <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>
-    <string name="accessibility_managed_profile" msgid="6613641363112584120">"ਕੰਮ ਪ੍ਰੋਫਾਈਲ"</string>
+    <string name="accessibility_managed_profile" msgid="6613641363112584120">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
     <string name="tuner_warning_title" msgid="7094689930793031682">"ਕੁਝ ਵਾਸਤੇ ਤਾਂ ਮਜ਼ੇਦਾਰ ਹੈ ਲੇਕਿਨ ਸਾਰਿਆਂ ਵਾਸਤੇ ਨਹੀਂ"</string>
-    <string name="tuner_warning" msgid="8730648121973575701">"ਸਿਸਟਮ UI ਟਿਊਨਰ ਤੁਹਾਨੂੰ Android ਉਪਭੋਗਤਾ ਇੰਟਰਫੇਸ ਤਬਦੀਲ ਕਰਨ ਅਤੇ ਅਨੁਕੂਲਿਤ ਕਰਨ ਲਈ ਵਾਧੂ ਤਰੀਕੇ ਦਿੰਦਾ ਹੈ। ਇਹ ਪ੍ਰਯੋਗਾਤਮਿਕ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਭਵਿੱਖ ਦੀ ਰੀਲੀਜ਼ ਵਿੱਚ ਬਦਲ ਸਕਦੀਆਂ ਹਨ, ਟੁੱਟ ਸਕਦੀਆਂ ਹਨ, ਜਾਂ ਅਲੋਪ ਹੋ ਸਕਦੀਆਂ ਹਨ। ਸਾਵਧਾਨੀ ਨਾਲ ਅੱਗੇ ਵੱਧੋ।"</string>
+    <string name="tuner_warning" msgid="8730648121973575701">"ਸਿਸਟਮ UI ਟਿਊਨਰ ਤੁਹਾਨੂੰ Android ਵਰਤੋਂਕਾਰ ਇੰਟਰਫੇਸ ਤਬਦੀਲ ਕਰਨ ਅਤੇ ਵਿਉਂਤਬੱਧ ਕਰਨ ਲਈ ਵਾਧੂ ਤਰੀਕੇ ਦਿੰਦਾ ਹੈ। ਇਹ ਪ੍ਰਯੋਗਾਤਮਿਕ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਭਵਿੱਖ ਦੀ ਰੀਲੀਜ਼ ਵਿੱਚ ਬਦਲ ਸਕਦੀਆਂ ਹਨ, ਟੁੱਟ ਸਕਦੀਆਂ ਹਨ, ਜਾਂ ਅਲੋਪ ਹੋ ਸਕਦੀਆਂ ਹਨ। ਸਾਵਧਾਨੀ ਨਾਲ ਅੱਗੇ ਵੱਧੋ।"</string>
     <string name="tuner_persistent_warning" msgid="8597333795565621795">"ਇਹ ਪ੍ਰਯੋਗਾਤਮਿਕ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਭਵਿੱਖ ਦੀ ਰੀਲੀਜ਼ ਵਿੱਚ ਬਦਲ ਸਕਦੀਆਂ ਹਨ, ਟੁੱਟ ਸਕਦੀਆਂ ਹਨ, ਜਾਂ ਅਲੋਪ ਹੋ ਸਕਦੀਆਂ ਹਨ। ਸਾਵਧਾਨੀ ਨਾਲ ਅੱਗੇ ਵੱਧੋ।"</string>
     <string name="got_it" msgid="2239653834387972602">"ਸਮਝ ਲਿਆ"</string>
-    <string name="tuner_toast" msgid="603429811084428439">"ਵਧਾਈਆਂ! ਸਿਸਟਮ UI ਟਿਊਨਰ ਨੂੰ ਸੈਟਿੰਗਜ਼ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ ਹੈ"</string>
-    <string name="remove_from_settings" msgid="8389591916603406378">"ਸੈਟਿੰਗਜ਼ ਤੋਂ ਹਟਾਓ"</string>
-    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"ਕੀ ਸੈਟਿੰਗਜ਼ ਤੋਂ ਸਿਸਟਮ UI ਟਿਊਨਰ ਨੂੰ ਹਟਾਉਣਾ ਹੈ ਅਤੇ ਇਸਦੀਆਂ ਸਾਰੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਉਪਯੋਗ ਕਰਨ ਤੋਂ ਰੋਕਣਾ ਹੈ?"</string>
-    <string name="activity_not_found" msgid="348423244327799974">"ਐਪਲੀਕੇਸ਼ਨ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਤੇ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ"</string>
+    <string name="tuner_toast" msgid="603429811084428439">"ਵਧਾਈਆਂ! ਸਿਸਟਮ UI ਟਿਊਨਰ ਨੂੰ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ ਹੈ"</string>
+    <string name="remove_from_settings" msgid="8389591916603406378">"ਸੈਟਿੰਗਾਂ ਤੋਂ ਹਟਾਓ"</string>
+    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"ਕੀ ਸੈਟਿੰਗਾਂ ਤੋਂ ਸਿਸਟਮ UI ਟਿਊਨਰ ਨੂੰ ਹਟਾਉਣਾ ਹੈ ਅਤੇ ਇਸਦੀਆਂ ਸਾਰੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਵਰਤੋਂ ਕਰਨ ਤੋਂ ਰੋਕਣਾ ਹੈ?"</string>
+    <string name="activity_not_found" msgid="348423244327799974">"ਐਪਲੀਕੇਸ਼ਨ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਤੇ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ"</string>
     <string name="clock_seconds" msgid="7689554147579179507">"ਘੜੀ ਸਕਿੰਟ ਦਿਖਾਓ"</string>
-    <string name="clock_seconds_desc" msgid="6282693067130470675">"ਸਥਿਤੀ ਬਾਰ ਵਿੱਚ ਘੜੀ ਸਕਿੰਟ ਦਿਖਾਓ। ਬੈਟਰੀ ਸਮਰੱਥਾ ਤੇ ਅਸਰ ਪੈ ਸਕਦਾ ਹੈ।"</string>
+    <string name="clock_seconds_desc" msgid="6282693067130470675">"ਸਥਿਤੀ ਪੱਟੀ ਵਿੱਚ ਘੜੀ ਸਕਿੰਟ ਦਿਖਾਓ। ਬੈਟਰੀ ਸਮਰੱਥਾ ਤੇ ਅਸਰ ਪੈ ਸਕਦਾ ਹੈ।"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਨੂੰ ਦੁਬਾਰਾ ਕ੍ਰਮ ਦਿਓ"</string>
     <string name="show_brightness" msgid="6613930842805942519">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਚਮਕ ਦਿਖਾਓ"</string>
     <string name="experimental" msgid="6198182315536726162">"ਪ੍ਰਯੋਗਾਤਮਿਕ"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth ਚਾਲੂ ਕਰੋ?"</string>
-    <string name="enable_bluetooth_message" msgid="9106595990708985385">"ਆਪਣੇ ਟੈਬਲੇਟ ਨਾਲ ਆਪਣਾ ਕੀ-ਬੋਰਡ ਕਨੈਕਟ ਕਰਨ ਲਈ, ਤੁਹਾਨੂੰ ਪਹਿਲਾਂ Bluetooth ਚਾਲੂ ਕਰਨ ਦੀ ਜ਼ਰੂਰਤ ਹੈ।"</string>
+    <string name="enable_bluetooth_message" msgid="9106595990708985385">"ਆਪਣੇ ਟੈਬਲੈੱਟ ਨਾਲ ਆਪਣਾ ਕੀ-ਬੋਰਡ ਕਨੈਕਟ ਕਰਨ ਲਈ, ਤੁਹਾਨੂੰ ਪਹਿਲਾਂ ਬਲੂਟੁੱਥ ਚਾਲੂ ਕਰਨ ਦੀ ਲੋੜ ਹੈ।"</string>
     <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"ਚਾਲੂ ਕਰੋ"</string>
-    <string name="show_silently" msgid="6841966539811264192">"ਸੂਚਨਾਵਾਂ ਚੁੱਪਚਾਪ ਢੰਗ ਨਾਲ ਵਿਖਾਓ"</string>
-    <string name="block" msgid="2734508760962682611">"ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬਲੌਕ ਕਰੋ"</string>
+    <string name="show_silently" msgid="6841966539811264192">"ਸੂਚਨਾਵਾਂ ਚੁੱਪਚਾਪ ਢੰਗ ਨਾਲ  ਦਿਖਾਓ"</string>
+    <string name="block" msgid="2734508760962682611">"ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬਲਾਕ ਕਰੋ"</string>
     <string name="do_not_silence" msgid="6878060322594892441">"ਚੁੱਪ ਨਾ ਕਰਵਾਓ"</string>
     <string name="do_not_silence_block" msgid="4070647971382232311">"ਚੁੱਪ ਨਾ ਕਰਵਾਓ ਜਾਂ ਬਲੌਕ ਨਾ ਕਰੋ"</string>
     <string name="tuner_full_importance_settings" msgid="3207312268609236827">"ਪਾਵਰ ਸੂਚਨਾ ਕੰਟਰੋਲ"</string>
     <string name="tuner_full_importance_settings_on" msgid="7545060756610299966">"ਚਾਲੂ"</string>
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ਬੰਦ"</string>
-    <string name="power_notification_controls_description" msgid="4372459941671353358">"ਪਾਵਰ ਸੂਚਨਾ ਕੰਟਰੋਲਾਂ ਨਾਲ, ਤੁਸੀਂ ਕਿਸੇ ਐਪ ਦੀਆਂ ਸੂਚਨਾਵਾਂ ਲਈ ਮਹੱਤਤਾ ਪੱਧਰ ਨੂੰ 0 ਤੋਂ 5 ਤੱਕ ਸੈੱਟ ਕਰ ਸਕਦੇ ਹੋ। \n\n"<b>"ਪੱਧਰ 5"</b>" \n- ਸੂਚਨਾ ਸੂਚੀ ਦੇ ਸਿਖਰ \'ਤੇ ਵਿਖਾਓ \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਦੀ ਆਗਿਆ ਦਿਓ \n- ਹਮੇਸ਼ਾਂ ਝਲਕ ਵਿਖਾਓ \n\n"<b>"ਪੱਧਰ 4"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਨੂੰ ਰੋਕੋ \n- ਹਮੇਸ਼ਾਂ ਝਲਕ ਵਿਖਾਓ \n\n"<b>"ਪੱਧਰ 3"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਨੂੰ ਰੋਕੋ \n- ਕਦੇ ਝਲਕ ਨਾ ਵਿਖਾਓ \n\n"<b>"ਪੱਧਰ 2"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਰੋਕੋ \n- ਕਦੇ ਝਲਕ ਨਾ ਵਿਖਾਓ \n- ਕਦੇ ਵੀ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਾ ਕਰੋ \n\n"<b>"ਪੱੱਧਰ 1"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਨੂੰ ਰੋਕੋ \n- ਕਦੇ ਝਲਕ ਨਾ ਵਿਖਾਓ \n- ਕਦੇ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਾ ਕਰੋ \n- ਲੌਕ ਸਕ੍ਰੀਨ ਅਤੇ ਸਥਿਤੀ ਪੱਟੀ ਤੋਂ ਲੁਕਾਓ \n- ਸੂਚਨਾ ਸੂਚੀ ਦੇ ਹੇਠਾਂ ਵਿਖਾਓ \n\n"<b>"ਪੱਧਰ 0"</b>" \n- ਐਪ ਤੋਂ ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬਲੌਕ ਕਰੋ"</string>
+    <string name="power_notification_controls_description" msgid="4372459941671353358">"ਪਾਵਰ ਸੂਚਨਾ ਕੰਟਰੋਲਾਂ ਨਾਲ, ਤੁਸੀਂ ਕਿਸੇ ਐਪ ਦੀਆਂ ਸੂਚਨਾਵਾਂ ਲਈ ਮਹੱਤਤਾ ਪੱਧਰ ਨੂੰ 0 ਤੋਂ 5 ਤੱਕ ਸੈੱਟ ਕਰ ਸਕਦੇ ਹੋ। \n\n"<b>"ਪੱਧਰ 5"</b>" \n- ਸੂਚਨਾ ਸੂਚੀ ਦੇ ਸਿਖਰ \'ਤੇ ਦਿਖਾਓ \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਦੀ ਆਗਿਆ ਦਿਓ \n- ਹਮੇਸ਼ਾਂ ਝਲਕ ਦਿਖਾਓ \n\n"<b>"ਪੱਧਰ 4"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਨੂੰ ਰੋਕੋ \n- ਹਮੇਸ਼ਾਂ ਝਲਕ ਦਿਖਾਓ \n\n"<b>"ਪੱਧਰ 3"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਨੂੰ ਰੋਕੋ \n- ਕਦੇ ਝਲਕ ਨਾ ਦਿਖਾਓ \n\n"<b>"ਪੱਧਰ 2"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਨੂੰ ਰੋਕੋ \n- ਕਦੇ ਝਲਕ ਨਾ ਦਿਖਾਓ \n- ਕਦੇ ਵੀ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਾ ਕਰੋ \n\n"<b>"ਪੱਧਰ 1"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਨੂੰ ਰੋਕੋ \n- ਕਦੇ ਝਲਕ ਨਾ ਦਿਖਾਓ \n- ਕਦੇ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਾ ਕਰੋ \n- ਲਾਕ ਸਕ੍ਰੀਨ ਅਤੇ ਸਥਿਤੀ ਪੱਟੀ ਤੋਂ ਲੁਕਾਓ \n- ਸੂਚਨਾ ਸੂਚੀ ਦੇ ਹੇਠਾਂ ਦਿਖਾਓ \n\n"<b>"ਪੱਧਰ 0"</b>" \n- ਐਪ ਤੋਂ ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬਲਾਕ ਕਰੋ"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ਸੂਚਨਾਵਾਂ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ਤੁਸੀਂ ਹੁਣ ਇਹ ਸੂਚਨਾਵਾਂ ਪ੍ਰਾਪਤ ਨਹੀਂ ਕਰੋਂਗੇ।"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ਤੁਹਾਨੂੰ ਹੁਣ ਇਹ ਸੂਚਨਾਵਾਂ ਪ੍ਰਾਪਤ ਨਹੀਂ ਹੋਣਗੀਆਂ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ਸੂਚਨਾ ਸ਼੍ਰੇਣੀਆਂ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ਇਸ ਐਪ ਵਿੱਚ ਸੂਚਨਾ ਸ਼੍ਰੇਣੀਆਂ ਨਹੀਂ ਹਨ"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"ਇਸ ਐਪ ਤੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬੰਦ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">ਇਸ ਐਪ ਤੋਂ <xliff:g id="NUMBER_1">%d</xliff:g> ਸੂਚਨਾ ਸ਼੍ਰੇਣੀ ਵਿੱਚੋਂ 1</item>
-      <item quantity="other">ਇਸ ਐਪ ਤੋਂ <xliff:g id="NUMBER_1">%d</xliff:g> ਸੂਚਨਾ ਸ਼੍ਰੇਣੀਆਂ ਵਿੱਚੋਂ 1</item>
+      <item quantity="other">ਇਸ ਐਪ ਤੋਂ <xliff:g id="NUMBER_1">%d</xliff:g> ਸੂਚਨਾ ਸ਼੍ਰੇਣੀ ਵਿੱਚੋਂ 1</item>
     </plurals>
     <string name="notification_channels_list_desc_2" msgid="6214732715833946441">"<xliff:g id="CHANNEL_NAME_1">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2">%2$s</xliff:g>"</string>
     <plurals name="notification_channels_list_desc_2_and_others" formatted="false" msgid="2747813553355336157">
@@ -565,21 +569,25 @@
     <string name="notification_channel_switch_accessibility" msgid="3420796005601900717">"ਇਸ ਚੈਨਲ ਤੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਇਜਾਜ਼ਤ ਦਿਓ"</string>
     <string name="notification_all_categories" msgid="5407190218055113282">"ਸਭ ਸ਼੍ਰੇਣੀਆਂ"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"ਹੋਰ ਸੈਟਿੰਗਾਂ"</string>
-    <string name="notification_app_settings" msgid="3743278649182392015">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਕਰੋ: <xliff:g id="SUB_CATEGORY">%1$s</xliff:g>"</string>
+    <string name="notification_app_settings" msgid="3743278649182392015">"ਵਿਉਂਤਬੱਧ ਕਰੋ: <xliff:g id="SUB_CATEGORY">%1$s</xliff:g>"</string>
     <string name="notification_done" msgid="5279426047273930175">"ਹੋ ਗਿਆ"</string>
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"ਸੂਚਨਾ ਕੰਟਰੋਲ"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"ਸੂਚਨਾ ਸਨੂਜ਼ ਵਿਕਲਪ"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 ਮਿੰਟ"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 ਮਿੰਟ"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ਘੰਟਾ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ਘੰਟੇ"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ਅਣਕੀਤਾ ਕਰੋ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ਲਈ ਸਨੂਜ਼ ਕੀਤਾ ਗਿਆ"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one"> %d ਘੰਟਾ</item>
+      <item quantity="other">%d ਘੰਟੇ</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d ਮਿੰਟ</item>
+      <item quantity="other"> %d ਮਿੰਟ</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"ਬੈਟਰੀ ਵਰਤੋਂ"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ਬੈਟਰੀ ਸੇਵਰ ਚਾਰਜਿੰਗ ਦੌਰਾਨ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ਬੈਟਰੀ ਸੇਵਰ"</string>
-    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ਕਾਰਗੁਜ਼ਾਰੀ ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਡੈਟੇ ਨੂੰ ਘਟਾਉਂਦਾ ਹੈ"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ਕਾਰਗੁਜ਼ਾਰੀ ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ  ਡਾਟੇ  ਨੂੰ ਘਟਾਉਂਦਾ ਹੈ"</string>
     <string name="keyboard_key_button_template" msgid="6230056639734377300">"ਬਟਨ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
     <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
@@ -588,31 +596,31 @@
     <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
     <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
     <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Center"</string>
-    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"ਟੈਬ"</string>
     <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
     <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
     <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
     <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
     <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
-    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
-    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"ਅੱਗੇ"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"ਪਿਛਲਾ"</string>
     <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
-    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"ਤੇਜ਼ੀ ਨਾਲ ਅੱਗੇ ਭੇਜੋ"</string>
     <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
     <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
-    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"ਮਿਟਾਓ"</string>
     <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
     <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
     <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
     <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
     <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ਸਿਸਟਮ"</string>
-    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ਮੁੱਖ ਸਕ੍ਰੀਨ"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ਹੋਮ ਸਕ੍ਰੀਨ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ਹਾਲੀਆ"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ਪਿੱਛੇ"</string>
     <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"ਸੂਚਨਾਵਾਂ"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ"</string>
-    <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"ਇਨਪੁੱਟ ਵਿਧੀ ਬਦਲੋ"</string>
+    <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"ਇਨਪੁੱਟ ਵਿਧੀ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"ਐਪਲੀਕੇਸ਼ਨਾਂ"</string>
     <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"ਸਹਾਇਕ"</string>
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ਬ੍ਰਾਊਜ਼ਰ"</string>
@@ -622,21 +630,21 @@
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"ਸੰਗੀਤ"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"ਕੈਲੰਡਰ"</string>
-    <string name="tuner_full_zen_title" msgid="4540823317772234308">"ਵੌਲਿਊਮ ਕੰਟਰੋਲਾਂ ਨਾਲ ਵਿਖਾਓ"</string>
-    <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
+    <string name="tuner_full_zen_title" msgid="4540823317772234308">"ਵੌਲਿਊਮ ਕੰਟਰੋਲਾਂ ਨਾਲ  ਦਿਖਾਓ"</string>
+    <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
     <string name="volume_dnd_silent" msgid="4363882330723050727">"ਵੌਲਿਊਮ ਬਟਨ ਸ਼ਾਰਟਕੱਟ"</string>
-    <string name="volume_up_silent" msgid="7141255269783588286">"ਵੌਲਿਊਮ ਉੱਚੀ ਹੋਣ \'ਤੇ ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਤੋਂ ਬਾਹਰ ਜਾਓ"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"ਅਵਾਜ਼ ਉੱਚੀ ਹੋਣ \'ਤੇ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਤੋਂ ਬਾਹਰ ਜਾਓ"</string>
     <string name="battery" msgid="7498329822413202973">"ਬੈਟਰੀ"</string>
     <string name="clock" msgid="7416090374234785905">"ਘੜੀ"</string>
     <string name="headset" msgid="4534219457597457353">"ਹੈੱਡਸੈੱਟ"</string>
-    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"ਹੈੱਡਫੋਨਾਂ ਨੂੰ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"ਹੈੱਡਫ਼ੋਨ ਨੂੰ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
     <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"ਹੈੱਡਸੈੱਟ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="data_saver" msgid="5037565123367048522">"ਡੈਟਾ ਸੇਵਰ"</string>
-    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"ਡੈਟਾ ਸੇਵਰ ਚਾਲੂ ਹੈ"</string>
-    <string name="accessibility_data_saver_off" msgid="8841582529453005337">"ਡੈਟਾ ਸੇਵਰ ਬੰਦ ਹੈ"</string>
+    <string name="data_saver" msgid="5037565123367048522">"ਡਾਟਾ ਸੇਵਰ"</string>
+    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"ਡਾਟਾ ਸੇਵਰ ਚਾਲੂ ਹੈ"</string>
+    <string name="accessibility_data_saver_off" msgid="8841582529453005337">"ਡਾਟਾ ਸੇਵਰ ਬੰਦ ਹੈ"</string>
     <string name="switch_bar_on" msgid="1142437840752794229">"ਚਾਲੂ"</string>
     <string name="switch_bar_off" msgid="8803270596930432874">"ਬੰਦ"</string>
-    <string name="nav_bar" msgid="1993221402773877607">"ਆਵਾਗੌਣ ਪੱਟੀ"</string>
+    <string name="nav_bar" msgid="1993221402773877607">"ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਪੱਟੀ"</string>
     <string name="nav_bar_layout" msgid="3664072994198772020">"ਖਾਕਾ"</string>
     <string name="left_nav_bar_button_type" msgid="8555981238887546528">"ਵਧੇਰੇ ਖੱਬੇ ਬਟਨ ਕਿਸਮ"</string>
     <string name="right_nav_bar_button_type" msgid="2481056627065649656">"ਵਧੇਰੇ ਸੱਜੇ ਬਟਨ ਕਿਸਮ"</string>
@@ -649,7 +657,7 @@
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"ਸਧਾਰਨ"</item>
-    <item msgid="8256205964297588988">"ਸੰਖੇਪ"</item>
+    <item msgid="8256205964297588988">"ਸੰਖਿਪਤ"</item>
     <item msgid="8719936228094005878">"ਖੱਬੇ-ਉਲਾਰ"</item>
     <item msgid="586019486955594690">"ਸੱਜੇ-ਉਲਾਰ"</item>
   </string-array>
@@ -658,7 +666,7 @@
     <string name="reset" msgid="2448168080964209908">"ਰੀਸੈੱਟ ਕਰੋ"</string>
     <string name="adjust_button_width" msgid="6138616087197632947">"ਬਟਨ ਚੁੜਾਈ ਵਿਵਸਥਿਤ ਕਰੋ"</string>
     <string name="clipboard" msgid="1313879395099896312">"ਕਲਿੱਪਬੋਰਡ"</string>
-    <string name="accessibility_key" msgid="5701989859305675896">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਆਵਾਗੌਣ ਬਟਨ"</string>
+    <string name="accessibility_key" msgid="5701989859305675896">"ਵਿਉਂਂਤੀ ਨੈਵੀਗੇਟ ਬਟਨ"</string>
     <string name="left_keycode" msgid="2010948862498918135">"ਖੱਬਾ ਕੀ-ਕੋਡ"</string>
     <string name="right_keycode" msgid="708447961000848163">"ਸੱਜਾ ਕੀ-ਕੋਡ"</string>
     <string name="left_icon" msgid="3096287125959387541">"ਖੱਬਾ ਪ੍ਰਤੀਕ"</string>
@@ -668,14 +676,14 @@
     <string name="qs_edit" msgid="2232596095725105230">"ਸੰਪਾਦਨ ਕਰੋ"</string>
     <string name="tuner_time" msgid="6572217313285536011">"ਸਮਾਂ"</string>
   <string-array name="clock_options">
-    <item msgid="5965318737560463480">"ਘੰਟੇ, ਮਿੰਟ, ਅਤੇ ਸਕਿੰਟ ਵਿਖਾਓ"</item>
-    <item msgid="1427801730816895300">"ਘੰਟੇ ਅਤੇ ਮਿੰਟ ਵਿਖਾਓ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
-    <item msgid="3830170141562534721">"ਇਸ ਚਿੰਨ੍ਹ ਨੂੰ ਨਾ ਵਿਖਾਓ"</item>
+    <item msgid="5965318737560463480">"ਘੰਟੇ, ਮਿੰਟ, ਅਤੇ ਸਕਿੰਟ  ਦਿਖਾਓ"</item>
+    <item msgid="1427801730816895300">"ਘੰਟੇ ਅਤੇ ਮਿੰਟ ਦਿਖਾਓ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
+    <item msgid="3830170141562534721">"ਇਸ ਪ੍ਰਤੀਕ ਨੂੰ ਨਾ ਦਿਖਾਓ"</item>
   </string-array>
   <string-array name="battery_options">
-    <item msgid="3160236755818672034">"ਹਮੇਸ਼ਾਂ ਪ੍ਰਤੀਸ਼ਤਤਾ ਵਿਖਾਓ"</item>
-    <item msgid="2139628951880142927">"ਚਾਰਜਿੰਗ ਦੌਰਾਨ ਪ੍ਰਤੀਸ਼ਤਤਾ ਵਿਖਾਓ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
-    <item msgid="3327323682209964956">"ਇਸ ਚਿੰਨ੍ਹ ਨੂੰ ਨਾ ਵਿਖਾਓ"</item>
+    <item msgid="3160236755818672034">"ਹਮੇਸ਼ਾਂ ਪ੍ਰਤੀਸ਼ਤਤਾ  ਦਿਖਾਓ"</item>
+    <item msgid="2139628951880142927">"ਚਾਰਜਿੰਗ ਦੌਰਾਨ ਪ੍ਰਤੀਸ਼ਤਤਾ ਦਿਖਾਓ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
+    <item msgid="3327323682209964956">"ਇਸ ਪ੍ਰਤੀਕ ਨੂੰ ਨਾ ਦਿਖਾਓ"</item>
   </string-array>
     <string name="other" msgid="4060683095962566764">"ਹੋਰ"</string>
     <string name="accessibility_divider" msgid="5903423481953635044">"ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਡਿਵਾਈਡਰ"</string>
@@ -691,7 +699,7 @@
     <string name="accessibility_action_divider_bottom_full" msgid="301433196679548001">"ਹੇਠਾਂ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
     <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"ਸਥਿਤੀ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>। ਸੰਪਾਦਨ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ।"</string>
     <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>। ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ।"</string>
-    <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"ਸਥਿਤੀ <xliff:g id="POSITION">%1$d</xliff:g>। ਚੁਣਨ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ।"</string>
+    <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"ਸਥਿਤੀ <xliff:g id="POSITION">%1$d</xliff:g>। ਚੁਣਨ ਲਈ ਡਬਲ ਟੈਪ ਕਰੋ।"</string>
     <string name="accessibility_qs_edit_move_tile" msgid="2461819993780159542">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ਨੂੰ ਤਬਦੀਲ ਕਰੋ"</string>
     <string name="accessibility_qs_edit_remove_tile" msgid="7484493384665907197">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ਹਟਾਓ"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ਨੂੰ <xliff:g id="POSITION">%2$d</xliff:g> ਸਥਿਤੀ \'ਤੇ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string>
@@ -702,7 +710,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ।"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ।"</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇ \'ਤੇ ਕੰਮ ਨਾ ਕਰੇ।"</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇਆਂ \'ਤੇ ਲਾਂਚ ਕਰਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ।"</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇਆਂ \'ਤੇ ਲਾਂਚ ਕਰਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ।"</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਨੂੰ ਖੋਲ੍ਹੋ।"</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਨੂੰ ਬੰਦ ਕਰੋ।"</string>
@@ -713,28 +721,28 @@
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ।"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ਸੈਟਿੰਗਾਂ ਦੇ ਕ੍ਰਮ ਦਾ ਸੰਪਾਦਨ ਕਰੋ।"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> ਦਾ <xliff:g id="ID_1">%1$d</xliff:g> ਪੰਨਾ"</string>
-    <string name="tuner_lock_screen" msgid="5755818559638850294">"ਲੌਕ ਸਕ੍ਰੀਨ"</string>
+    <string name="tuner_lock_screen" msgid="5755818559638850294">" ਲਾਕ  ਸਕ੍ਰੀਨ"</string>
     <string name="pip_phone_expand" msgid="5889780005575693909">"ਵਿਸਤਾਰ ਕਰੋ"</string>
     <string name="pip_phone_minimize" msgid="1079119422589131792">"ਛੋਟਾ ਕਰੋ"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"ਬੰਦ ਕਰੋ"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"ਖਾਰਜ ਕਰਨ ਲਈ ਹੇਠਾਂ ਘਸੀਟੋ"</string>
     <string name="pip_menu_title" msgid="3328510504196964712">"ਤਸਵੀਰ-ਵਿੱਚ-ਤਸਵੀਰ ਮੀਨੂ"</string>
     <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ਤਸਵੀਰ-ਵਿੱਚ-ਤਸਵੀਰ \'ਚ ਹੈ"</string>
-    <string name="pip_notification_message" msgid="4171698133469539591">"ਜੇ ਤੁਸੀਂ ਨਹੀਂ ਚਾਹੁੰਦੇ ਕਿ <xliff:g id="NAME">%s</xliff:g> ਐਪ ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਦੀ ਵਰਤੋਂ ਕਰੇ, ਤਾਂ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹਣ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਇਸਨੂੰ ਬੰਦ ਕਰੋ।"</string>
+    <string name="pip_notification_message" msgid="4171698133469539591">"ਜੇਕਰ ਤੁਸੀਂ ਨਹੀਂ ਚਾਹੁੰਦੇ ਕਿ <xliff:g id="NAME">%s</xliff:g> ਐਪ ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਦੀ ਵਰਤੋਂ ਕਰੇ, ਤਾਂ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹਣ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਇਸਨੂੰ ਬੰਦ ਕਰੋ।"</string>
     <string name="pip_play" msgid="1417176722760265888">"ਚਲਾਓ"</string>
     <string name="pip_pause" msgid="8881063404466476571">"ਵਿਰਾਮ ਦਿਓ"</string>
     <string name="pip_skip_to_next" msgid="1948440006726306284">"ਅਗਲੇ \'ਤੇ ਜਾਓ"</string>
     <string name="pip_skip_to_prev" msgid="1955311326688637914">"ਪਿਛਲੇ \'ਤੇ ਜਾਓ"</string>
     <string name="thermal_shutdown_title" msgid="4458304833443861111">"ਗਰਮ ਹੋਣ ਕਾਰਨ ਫ਼ੋਨ ਬੰਦ ਹੋ ਗਿਆ"</string>
     <string name="thermal_shutdown_message" msgid="9006456746902370523">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਬਹੁਤ ਗਰਮ ਸੀ, ਇਸ ਲਈ ਇਹ ਠੰਡਾ ਹੋਣ ਵਾਸਤੇ ਬੰਦ ਹੋ ਗਿਆ ਸੀ। ਤੁਹਾਡਾ ਫ਼ੋਨ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\n\nਤੁਹਾਡਾ ਫ਼ੋਨ ਬਹੁਤ ਗਰਮ ਹੋ ਸਕਦਾ ਹੈ ਜੇ:\n	• ਤੁਸੀਂ ਸਰੋਤਾਂ ਦੀ ਵੱਧ ਵਰਤੋਂ ਵਾਲੀਆਂ ਐਪਾਂ (ਜਿਵੇਂ ਗੇਮਿੰਗ, ਵੀਡੀਓ, ਜਾਂ ਆਵਾਗੌਣ ਐਪਾਂ) ਵਰਤਦੇ ਹੋ \n	• ਵੱਡੀਆਂ ਫ਼ਾਈਲਾਂ ਡਾਊਨਲੋਡ ਜਾਂ ਅੱਪਲੋਡ ਕਰਦੇ ਹੋ\n	• ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਉੱਚ ਤਾਪਮਾਨਾਂ ਵਿੱਚ ਵਰਤਦੇ ਹੋ"</string>
+    <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">\n"ਤੁਹਾਡਾ ਫ਼ੋਨ ਬਹੁਤ ਗਰਮ ਸੀ, ਇਸ ਲਈ ਇਹ ਠੰਡਾ ਹੋਣ ਵਾਸਤੇ ਬੰਦ ਹੋ ਗਿਆ ਸੀ। ਤੁਹਾਡਾ ਫ਼ੋਨ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\n\nਤੁਹਾਡਾ ਫ਼ੋਨ ਬਹੁਤ ਗਰਮ ਹੋ ਸਕਦਾ ਹੈ ਜੇ:\n	• ਤੁਸੀਂ ਸਰੋਤਾਂ ਦੀ ਵੱਧ ਵਰਤੋਂ ਵਾਲੀਆਂ ਐਪਾਂ (ਜਿਵੇਂ ਗੇਮਿੰਗ, ਵੀਡੀਓ, ਜਾਂ ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਐਪਾਂ) ਵਰਤਦੇ ਹੋ 	• ਵੱਡੀਆਂ ਫ਼ਾਈਲਾਂ ਡਾਊਨਲੋਡ ਜਾਂ ਅੱਪਲੋਡ ਕਰਦੇ ਹੋ\n	• ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਉੱਚ ਤਾਪਮਾਨਾਂ ਵਿੱਚ ਵਰਤਦੇ ਹੋ"</string>
     <string name="high_temp_title" msgid="4589508026407318374">"ਫ਼ੋਨ ਗਰਮ ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="high_temp_notif_message" msgid="5642466103153429279">"ਫ਼ੋਨ ਦੇ ਠੰਡਾ ਹੋਣ ਦੇ ਦੌਰਾਨ ਕੁਝ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਸੀਮਿਤ ਹੁੰਦੀਆਂ ਹਨ"</string>
     <string name="high_temp_dialog_message" msgid="6840700639374113553">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਸਵੈਚਲਿਤ ਰੂਪ ਵਿੱਚ ਠੰਡਾ ਹੋਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੇਗਾ। ਤੁਸੀਂ ਹਾਲੇ ਵੀ ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਵਰਤ ਸਕਦੇ ਹੋ, ਪਰੰਤੂ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਇਹ ਵਧੇਰੇ ਹੌਲੀ ਚੱਲੇ।\n\nਇੱਕ ਵਾਰ ਠੰਡਾ ਹੋਣ ਤੋਂ ਬਾਅਦ ਤੁਹਾਡਾ ਫ਼ੋਨ ਸਧਾਰਨ ਤੌਰ \'ਤੇ ਚੱਲੇਗਾ।"</string>
     <string name="lockscreen_shortcut_left" msgid="2182769107618938629">"ਖੱਬਾ ਸ਼ਾਰਟਕੱਟ"</string>
     <string name="lockscreen_shortcut_right" msgid="3328683699505226536">"ਸੱਜਾ ਸ਼ਾਰਟਕੱਟ"</string>
-    <string name="lockscreen_unlock_left" msgid="2043092136246951985">"ਖੱਬੇ ਸ਼ਾਰਟਕੱਟ ਨਾਲ ਵੀ ਅਨਲੌਕ ਹੁੰਦੀ ਹੈ"</string>
-    <string name="lockscreen_unlock_right" msgid="1529992940510318775">"ਸੱਜੇ ਸ਼ਾਰਟਕੱਟ ਨਾਲ ਵੀ ਅਨਲੌਕ ਹੁੰਦੀ ਹੈ"</string>
+    <string name="lockscreen_unlock_left" msgid="2043092136246951985">"ਖੱਬੇ ਸ਼ਾਰਟਕੱਟ ਨਾਲ ਵੀ ਅਣਲਾਕ ਹੁੰਦੀ ਹੈ"</string>
+    <string name="lockscreen_unlock_right" msgid="1529992940510318775">"ਸੱਜੇ ਸ਼ਾਰਟਕੱਟ ਨਾਲ ਵੀ ਅਣਲਾਕ ਹੁੰਦੀ ਹੈ"</string>
     <string name="lockscreen_none" msgid="4783896034844841821">"ਕੋਈ ਨਹੀਂ"</string>
     <string name="tuner_launch_app" msgid="1527264114781925348">"<xliff:g id="APP">%1$s</xliff:g> ਲਾਂਚ ਕਰੋ"</string>
     <string name="tuner_other_apps" msgid="4726596850501162493">"ਹੋਰ ਐਪਾਂ"</string>
@@ -753,16 +761,17 @@
     <string name="instant_apps_message" msgid="8116608994995104836">"ਤਤਕਾਲ ਐਪਾਂ ਨੂੰ ਸਥਾਪਨਾ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ।"</string>
     <string name="app_info" msgid="6856026610594615344">"ਐਪ ਜਾਣਕਾਰੀ"</string>
     <string name="go_to_web" msgid="1106022723459948514">"ਵੈੱਬ \'ਤੇ ਜਾਓ"</string>
-    <string name="mobile_data" msgid="7094582042819250762">"ਮੋਬਾਈਲ ਡੈਟਾ"</string>
-    <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ਬੰਦ ਹੈ"</string>
+    <string name="mobile_data" msgid="7094582042819250762">"ਮੋਬਾਈਲ ਡਾਟਾ"</string>
+    <string name="wifi_is_off" msgid="1838559392210456893">"ਵਾਈ-ਫਾਈ ਬੰਦ ਹੈ"</string>
     <string name="bt_is_off" msgid="2640685272289706392">"ਬਲੂਟੁੱਥ ਬੰਦ ਹੈ"</string>
-    <string name="dnd_is_off" msgid="6167780215212497572">"\'ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਬੰਦ ਹੈ"</string>
-    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"ਸਵੈਚਲਿਤ ਨਿਯਮ (<xliff:g id="ID_1">%s</xliff:g>) ਦੁਆਰਾ \'ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
-    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"ਐਪ (<xliff:g id="ID_1">%s</xliff:g>) ਵੱਲੋਂ \'ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
-    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"ਇੱਕ ਸਵੈਚਲਿਤ ਨਿਯਮ ਜਾਂ ਐਪ ਵੱਲੋਂ \'ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
+    <string name="dnd_is_off" msgid="6167780215212497572">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਬੰਦ ਹੈ"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"ਸਵੈਚਲਿਤ ਨਿਯਮ (<xliff:g id="ID_1">%s</xliff:g>) ਦੁਆਰਾ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
+    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"ਐਪ (<xliff:g id="ID_1">%s</xliff:g>) ਵੱਲੋਂ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"ਇੱਕ ਸਵੈਚਲਿਤ ਨਿਯਮ ਜਾਂ ਐਪ ਵੱਲੋਂ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
     <string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> ਤੱਕ"</string>
     <string name="qs_dnd_keep" msgid="1825009164681928736">"ਰੱਖੋ"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"ਬਦਲੋ"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀਆਂ ਐਪਾਂ"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"ਬੈਟਰੀ ਅਤੇ ਡੈਟਾ ਉਪਯੋਗ ਸਬੰਧੀ ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"ਬੈਟਰੀ ਅਤੇ ਡਾਟਾ ਵਰਤੋਂ ਸਬੰਧੀ ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"ਮੋਬਾਈਲ ਡਾਟਾ ਬੰਦ ਕਰਨਾ ਹੈ?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings_car.xml b/packages/SystemUI/res/values-pa/strings_car.xml
index ac38625d..1c023a3 100644
--- a/packages/SystemUI/res/values-pa/strings_car.xml
+++ b/packages/SystemUI/res/values-pa/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਗੱਡੀ ਚਲਾਓ"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ਗੱਡੀ ਚਲਾਉਣ ਦੇ ਹਾਲਾਤਾਂ ਤੋਂ ਪੂਰੀ ਤਰ੍ਹਾਂ ਜਾਣੂ ਰਹੋ ਅਤੇ ਸਦਾ ਲਾਗੂ ਕਾਨੂੰਨਾਂ ਦੀ ਪਾਲਣਾ ਕਰੋ। ਦਿਸ਼ਾਵਾਂ ਗਲਤ, ਅਧੂਰੀਆਂ, ਖ਼ਤਰਨਾਕ, ਢੁੱਕਵੀਆਂ ਨਹੀਂ, ਪ੍ਰਤਿਬੰਧਿਤ ਹੋ ਸਕਦੀਆਂ ਹਨ ਜਾਂ ਪ੍ਰਸ਼ਾਸਕੀ ਖੇਤਰਾਂ ਵਿੱਚੋਂ ਲੰਘਣਾ ਸ਼ਾਮਲ ਹੋ ਸਕਦਾ ਹੈ। ਵਪਾਰਕ ਜਾਣਕਾਰੀ ਵੀ ਗਲਤ ਜਾਂ ਅਧੂਰੀ ਹੋ ਸਕਦੀ ਹੈ। ਡੈਟਾ ਰੀਅਲ-ਟਾਈਮ ਨਹੀਂ ਹੈ ਅਤੇ ਟਿਕਾਣਾ ਸਟੀਕਤਾ ਗਾਰੰਟੀਸ਼ੁਦਾ ਨਹੀਂ ਹੋ ਸਕਦੀ ਹੈ। ਗੱਡੀ ਚਲਾਉਣ ਦੌਰਾਨ ਆਪਣੀ ਮੋਬਾਈਲ ਡੀਵਾਈਸ ਜਾਂ ਉਹਨਾਂ ਐਪਾਂ ਦੀ ਵਰਤੋਂ ਨਾ ਕਰੋ ਜੋ ਕਿ Android Auto ਲਈ ਨਹੀਂ ਬਣੀਆਂ ਹਨ।"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"ਅਗਿਆਤ"</string>
+    <string name="start_driving" msgid="864023351402918991">"ਗੱਡੀ ਚਲਾਉਣਾ ਸ਼ੁਰੂ ਕਰੋ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index fd59150..acb2710 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -244,7 +244,7 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Transmisja danych 4G została wstrzymana"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Mobilna transmisja danych jest wstrzymana"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Transmisja danych została wstrzymana"</string>
-    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Osiągnięto ustawiony limit danych. Nie korzystasz już z komórkowej transmisji danych.\n\nJeśli włączysz ją ponownie, może zostać naliczona opłata za transmisję danych."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Osiągnięto ustawiony limit danych. Nie korzystasz już z komórkowej transmisji danych.\n\nJeśli włączysz ją ponownie, może zostać naliczona opłata za użycie danych."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Wznów"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Brak internetu"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: połączono"</string>
@@ -314,6 +314,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Więcej ustawień"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Gotowe"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Połączono"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Połączono, bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Łączę..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Powiązanie"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -471,6 +472,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Masz połączenie z aplikacją <xliff:g id="APPLICATION">%1$s</xliff:g>, która może monitorować Twoją prywatną aktywność w sieci, w tym e-maile, aplikacje i strony internetowe."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Organizacja <xliff:g id="ORGANIZATION">%1$s</xliff:g> zarządza Twoim profilem do pracy. Profil jest połączony z aplikacją <xliff:g id="APPLICATION">%2$s</xliff:g>, która może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe.\n\nSkontaktuj się z administratorem, aby uzyskać więcej informacji."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Organizacja <xliff:g id="ORGANIZATION">%1$s</xliff:g> zarządza Twoim profilem do pracy. Profil jest połączony z aplikacją <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, która może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe.\n\nMasz też połączenie z aplikacją <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, która może monitorować Twoją osobistą aktywność w sieci."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Odblokowano dla: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Aplikacja <xliff:g id="TRUST_AGENT">%1$s</xliff:g> jest uruchomiona"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Urządzenie pozostanie zablokowane, aż odblokujesz je ręcznie"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Szybszy dostęp do powiadomień"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Zobacz powiadomienia, jeszcze zanim odblokujesz ekran"</string>
@@ -552,9 +555,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Wył."</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Dzięki zaawansowanym ustawieniom możesz określić poziom ważności powiadomień z aplikacji w skali od 0 do 5. \n\n"<b>"Poziom 5"</b>" \n– Pokazuj u góry listy powiadomień \n– Zezwalaj na powiadomienia na pełnym ekranie \n– Zawsze pokazuj podgląd \n\n"<b>"Poziom 4"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Zawsze pokazuj podgląd \n\n"<b>"Poziom 3"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Nigdy nie pokazuj podglądu \n\n"<b>"Poziom 2"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Nigdy nie pokazuj podglądu \n– NIgdy nie powiadamiaj dźwiękiem ani wibracjami \n\n"<b>"Poziom 1"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Nigdy nie pokazuj podglądu \n– NIgdy nie powiadamiaj dźwiękiem ani wibracjami \n– Ukrywaj na ekranie blokady i pasku stanu \n– Pokazuj u dołu listy powiadomień \n\n"<b>"Poziom 0"</b>" \n– Blokuj wszystkie powiadomienia aplikacji"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Powiadomienia"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Nie będziesz już otrzymywać tych powiadomień."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Nie będziesz już otrzymywać tych powiadomień"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Kategorie powiadomień: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ta aplikacja nie ma kategorii powiadomień"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Powiadomień z tej aplikacji nie można wyłączyć"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="few">1 z <xliff:g id="NUMBER_1">%d</xliff:g> kategorii powiadomień z tej aplikacji</item>
       <item quantity="many">1 z <xliff:g id="NUMBER_1">%d</xliff:g> kategorii powiadomień z tej aplikacji</item>
@@ -578,12 +582,20 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"sterowanie powiadomieniami"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opcje odkładania powiadomień"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 min"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 min"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 godz."</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 godziny"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"COFNIJ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odłożono na <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="few">%d godziny</item>
+      <item quantity="many">%d godzin</item>
+      <item quantity="other">%d godziny</item>
+      <item quantity="one">%d godzina</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="few">%d minuty</item>
+      <item quantity="many">%d minut</item>
+      <item quantity="other">%d minuty</item>
+      <item quantity="one">]%d minuta</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Wykorzystanie baterii"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Oszczędzanie baterii nie jest dostępne podczas ładowania"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Oszczędzanie baterii"</string>
@@ -772,5 +784,6 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Zachowaj"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Zastąp"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacje działające w tle"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Kliknij, by wyświetlić szczegóły wykorzystania baterii i transmisji danych"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Kliknij, by wyświetlić szczegóły wykorzystania baterii i użycia danych"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Wyłączyć mobilną transmisję danych?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings_car.xml b/packages/SystemUI/res/values-pl/strings_car.xml
index dbb0373..0841e27 100644
--- a/packages/SystemUI/res/values-pl/strings_car.xml
+++ b/packages/SystemUI/res/values-pl/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Jedź bezpiecznie"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Uważnie obserwuj warunki na drodze i zawsze przestrzegaj obowiązującego prawa. Wskazówki mogą być niedokładne, niekompletne, niebezpieczne, nieprzydatne lub niezgodne z prawem, mogą też obejmować przekraczanie obszarów administracyjnych. Informacje o firmach również mogą być niedokładne lub niekompletne. Dane nie są podawane w czasie rzeczywistym. Nie ma gwarancji, że dane o lokalizacji są dokładne. Podczas prowadzenia samochodu nie obsługuj urządzenia mobilnego ani nie używaj aplikacji nieprzeznaczonych na Androida Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Brak informacji"</string>
+    <string name="start_driving" msgid="864023351402918991">"Uruchom tryb Jazda samochodem"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index a8bdd91..ed3f9e46 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -22,7 +22,7 @@
     <string name="app_label" msgid="7164937344850004466">"Interf sist"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Limpar"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Remover da lista"</string>
-    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informações do app"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Inform. do app"</string>
     <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Suas telas recentes aparecem aqui"</string>
     <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Dispensar apps recentes"</string>
     <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Mais configurações"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Concluído"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Conectado"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Conectado, nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Conectando..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Ponto de acesso"</string>
@@ -469,13 +470,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Você está conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorar sua atividade pessoal na rede, incluindo e-mails, apps e websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Seu perfil de trabalho é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está conectado a <xliff:g id="APPLICATION">%2$s</xliff:g>, que pode monitorar sua atividade profissional de rede, incluindo e-mails, apps e websites.\n\nPara saber mais informações, entre em contato com seu administrador."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Seu perfil de trabalho é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está conectado a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pode monitorar sua atividade profissional de rede, incluindo e-mails, apps e websites.\n\nVocê também está conectado a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pode monitorar sua atividade pessoal de rede."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Desbloqueado para <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> está em execução"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"O dispositivo permanecerá bloqueado até que você o desbloqueie manualmente"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Receba notificações mais rápido"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Veja-as antes de desbloquear"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Não, obrigado"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Configurar"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Desligar agora"</string>
+    <string name="volume_zen_end_now" msgid="6930243045593601084">"Desativar agora"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expandir"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Recolher"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"A tela está fixada"</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desativado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Com controles de ativação de notificações, é possível definir o nível de importância de 0 a 5 para as notificações de um app. \n\n"<b>"Nível 5"</b>" \n- Exibir na parte superior da lista de notificações \n- Permitir interrupção em tela cheia \n- Sempre exibir \n\n"<b>"Nível 4"</b>" \n- Impedir interrupções em tela cheia \n- Sempre exibir \n\n"<b>"Nível 3"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n\n"<b>"Nível 2"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n- Nunca emitir som ou vibrar \n\n"<b>"Nível 1"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n- Nunca emitir som ou vibrar \n- Ocultar da tela de bloqueio e barra de status \n- Exibir na parte inferior da lista de notificações \n\n"<b>"Nível 0"</b>" \n- Bloquear todas as notificações do app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificações"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Você deixará de receber essas notificações."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Você deixará de receber essas notificações"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorias de notificação"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Este app não tem categorias de notificação"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Notificações deste app não podem ser desativadas"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categoria de notificação deste app</item>
       <item quantity="other">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categorias de notificação deste app</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"controles de notificação"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opções de adiamento de notificação"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"Uma hora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 horas"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"DESFAZER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Adiada para <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d hora</item>
+      <item quantity="other">%d horas</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d minuto</item>
+      <item quantity="other">%d minutos</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso da bateria"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A Economia de bateria não fica disponível durante o carregamento"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economia de bateria"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Substituir"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Apps sendo executados em segundo plano"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Desativar os dados móveis?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings_car.xml b/packages/SystemUI/res/values-pt-rBR/strings_car.xml
index 5d754ef..b113ed7 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings_car.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Dirija com segurança"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Mantenha-se atento às condições da estrada  e sempre obedeça às leis aplicáveis. As instruções podem ser imprecisas, incompletas, perigosas, inadequadas, proibidas ou envolver o cruzamento de áreas administrativas. As informações comerciais também podem ser imprecisas ou incompletas. Os dados não são exibidos em tempo real, e a precisão da localização não pode ser garantida. Enquanto dirige, não manuseie seu dispositivo móvel nem use apps que não tenham sido criados para o Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Desconhecido"</string>
+    <string name="start_driving" msgid="864023351402918991">"Começar a dirigir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 65b130b..65bed3c 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Mais definições"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Concluído"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Ligado"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Ligado, bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"A ligar..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Associação"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona Wi-Fi"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Está ligado ao <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a atividade da rede pessoal, incluindo emails, aplicações e Sites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Sites.\n\nContacte o administrador para obter mais informações."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Sites.\n\nTambém está associado à aplicação <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pode monitorizar a atividade da rede pessoal."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Desbloqueado para <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> em execução"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"O dispositivo permanecerá bloqueado até ser desbloqueado manualmente"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Receber notificações mais rapidamente"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Ver antes de desbloquear"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desativado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Com os controlos de notificações do consumo de energia, pode definir um nível de importância de 0 a 5 para as notificações de aplicações. \n\n"<b>"Nível 5"</b>" \n- Mostrar no início da lista de notificações \n- Permitir a interrupção do ecrã inteiro \n- Aparecer rapidamente sempre \n\n"<b>"Nível 4"</b>" \n- Impedir a interrupção do ecrã inteiro \n- Aparecer rapidamente sempre\n\n"<b>"Nível 3"</b>" \n- Impedir a interrupção do ecrã inteiro \n- Nunca aparecer rapidamente \n\n"<b>"Nível 2"</b>" \n- Impedir a interrupção do ecrã inteiro \n- Nunca aparecer rapidamente \n- Nunca tocar nem vibrar \n\n"<b>"Nível 1"</b>" \n- Impedir a interrupção do ecrã inteiro \n- Nunca aparecer rapidamente \n- Nunca tocar nem vibrar \n- Ocultar do ecrã de bloqueio e da barra de estado \n- Mostrar no fim da lista de notificações \n\n"<b>"Nível 0"</b>" \n- Bloquear todas as notificações da aplicação"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificações"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Já não recebe estas notificações."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Deixará de receber estas notificações"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorias de notificação"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Esta aplicação não tem categorias de notificação"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Não é possível desativar as notificações desta aplicação"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 de <xliff:g id="NUMBER_0">%d</xliff:g> categoria de notificação desta aplicação</item>
       <item quantity="other">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categorias de notificação desta aplicação</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"controlos de notificação"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opções de suspensão de notificações"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 horas"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ANULAR"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Suspensa por <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d hora</item>
+      <item quantity="other">%d horas</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d minuto</item>
+      <item quantity="other">%d minutos</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Utiliz. da bateria"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Poupança de bateria não disponível durante o carregamento"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Poupança de bateria"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Substituir"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplicações em execução em segundo plano"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Toque para obter detalhes acerca da utilização da bateria e dos dados"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Pretende desativar os dados móveis?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings_car.xml b/packages/SystemUI/res/values-pt-rPT/strings_car.xml
index afb030a..6a8b40d 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings_car.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduza com segurança"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Mantenha-se completamente atento às condições de condução e respeite sempre as leis aplicáveis. As direções podem ser imprecisas, incompletas, perigosas, inadequadas, proibidas ou envolver a travessia de áreas administrativas. Os dados das empresas também podem ser imprecisos ou incompletos. Os dados não são fornecidos em tempo real e não é possível garantir a precisão da localização. Não manuseie o dispositivo móvel nem utilize aplicações não destinadas ao Android Auto durante a condução."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Desconhecido"</string>
+    <string name="start_driving" msgid="864023351402918991">"Começar a conduzir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index a8bdd91..ed3f9e46 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -22,7 +22,7 @@
     <string name="app_label" msgid="7164937344850004466">"Interf sist"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Limpar"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Remover da lista"</string>
-    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informações do app"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Inform. do app"</string>
     <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Suas telas recentes aparecem aqui"</string>
     <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Dispensar apps recentes"</string>
     <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Mais configurações"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Concluído"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Conectado"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Conectado, nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Conectando..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Ponto de acesso"</string>
@@ -469,13 +470,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Você está conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorar sua atividade pessoal na rede, incluindo e-mails, apps e websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Seu perfil de trabalho é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está conectado a <xliff:g id="APPLICATION">%2$s</xliff:g>, que pode monitorar sua atividade profissional de rede, incluindo e-mails, apps e websites.\n\nPara saber mais informações, entre em contato com seu administrador."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Seu perfil de trabalho é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está conectado a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pode monitorar sua atividade profissional de rede, incluindo e-mails, apps e websites.\n\nVocê também está conectado a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pode monitorar sua atividade pessoal de rede."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Desbloqueado para <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> está em execução"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"O dispositivo permanecerá bloqueado até que você o desbloqueie manualmente"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Receba notificações mais rápido"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Veja-as antes de desbloquear"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Não, obrigado"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Configurar"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Desligar agora"</string>
+    <string name="volume_zen_end_now" msgid="6930243045593601084">"Desativar agora"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expandir"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Recolher"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"A tela está fixada"</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desativado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Com controles de ativação de notificações, é possível definir o nível de importância de 0 a 5 para as notificações de um app. \n\n"<b>"Nível 5"</b>" \n- Exibir na parte superior da lista de notificações \n- Permitir interrupção em tela cheia \n- Sempre exibir \n\n"<b>"Nível 4"</b>" \n- Impedir interrupções em tela cheia \n- Sempre exibir \n\n"<b>"Nível 3"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n\n"<b>"Nível 2"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n- Nunca emitir som ou vibrar \n\n"<b>"Nível 1"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n- Nunca emitir som ou vibrar \n- Ocultar da tela de bloqueio e barra de status \n- Exibir na parte inferior da lista de notificações \n\n"<b>"Nível 0"</b>" \n- Bloquear todas as notificações do app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificações"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Você deixará de receber essas notificações."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Você deixará de receber essas notificações"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorias de notificação"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Este app não tem categorias de notificação"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Notificações deste app não podem ser desativadas"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categoria de notificação deste app</item>
       <item quantity="other">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categorias de notificação deste app</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"controles de notificação"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opções de adiamento de notificação"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"Uma hora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 horas"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"DESFAZER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Adiada para <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d hora</item>
+      <item quantity="other">%d horas</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d minuto</item>
+      <item quantity="other">%d minutos</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso da bateria"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A Economia de bateria não fica disponível durante o carregamento"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economia de bateria"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Substituir"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Apps sendo executados em segundo plano"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Desativar os dados móveis?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings_car.xml b/packages/SystemUI/res/values-pt/strings_car.xml
index 5d754ef..b113ed7 100644
--- a/packages/SystemUI/res/values-pt/strings_car.xml
+++ b/packages/SystemUI/res/values-pt/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Dirija com segurança"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Mantenha-se atento às condições da estrada  e sempre obedeça às leis aplicáveis. As instruções podem ser imprecisas, incompletas, perigosas, inadequadas, proibidas ou envolver o cruzamento de áreas administrativas. As informações comerciais também podem ser imprecisas ou incompletas. Os dados não são exibidos em tempo real, e a precisão da localização não pode ser garantida. Enquanto dirige, não manuseie seu dispositivo móvel nem use apps que não tenham sido criados para o Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Desconhecido"</string>
+    <string name="start_driving" msgid="864023351402918991">"Começar a dirigir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 5799bc3..7e307cd 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -22,7 +22,7 @@
     <string name="app_label" msgid="7164937344850004466">"UI sistem"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ștergeți"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Eliminați din listă"</string>
-    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informații despre aplicație"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Info aplicație"</string>
     <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Ecranele dvs. recente apar aici"</string>
     <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Renunțați la aplicațiile recente"</string>
     <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
@@ -61,7 +61,7 @@
     <string name="label_view" msgid="6304565553218192990">"Afișați"</string>
     <string name="always_use_device" msgid="1450287437017315906">"Utilizați în mod prestabilit pt. acest dispoz. USB"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Utiliz. în mod prestabilit pt. acest accesoriu USB"</string>
-    <string name="usb_debugging_title" msgid="4513918393387141949">"Permiteți depanarea USB?"</string>
+    <string name="usb_debugging_title" msgid="4513918393387141949">"Permiteți remedierea erorilor prin USB?"</string>
     <string name="usb_debugging_message" msgid="2220143855912376496">"Amprenta digitală din cheia RSA a computerului este:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Permiteți întotdeauna de pe acest computer"</string>
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Remedierea erorilor prin USB nu este permisă"</string>
@@ -314,6 +314,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Mai multe setări"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Terminat"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Conectat"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Conectat, bateria la <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Se conectează..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -387,7 +388,7 @@
     <string name="user_add_user" msgid="5110251524486079492">"Adăugați un utilizator"</string>
     <string name="user_new_user_name" msgid="426540612051178753">"Utilizator nou"</string>
     <string name="guest_nickname" msgid="8059989128963789678">"Invitat"</string>
-    <string name="guest_new_guest" msgid="600537543078847803">"Adăugați un oaspete"</string>
+    <string name="guest_new_guest" msgid="600537543078847803">"Adăugați un invitat"</string>
     <string name="guest_exit_guest" msgid="7187359342030096885">"Eliminați invitatul"</string>
     <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"Ștergeți invitatul?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Toate aplicațiile și datele din această sesiune vor fi șterse."</string>
@@ -471,6 +472,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"V-ați conectat la aplicația <xliff:g id="APPLICATION">%1$s</xliff:g>, care vă poate monitoriza activitatea personală în rețea, inclusiv e-mailurile, aplicațiile și site-urile accesate."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Profilul de serviciu este gestionat de <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilul este conectat la <xliff:g id="APPLICATION">%2$s</xliff:g>, care vă poate monitoriza activitatea în rețeaua de serviciu, inclusiv e-mailurile, aplicațiile și site-urile accesate.\n\nPentru mai multe informații, contactați administratorul."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Profilul de serviciu este gestionat de <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilul este conectat la <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, care vă poate monitoriza activitatea în rețeaua de serviciu, inclusiv e-mailurile, aplicațiile și site-urile accesate.\n\nDe asemenea, v-ați conectat la <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, care vă poate monitoriza activitatea în rețeaua personală."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Deblocat pentru <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> rulează"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Dispozitivul va rămâne blocat până când îl deblocați manual"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Obțineți notificări mai rapid"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Doresc să se afișeze înainte de deblocare"</string>
@@ -552,9 +555,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Dezactivate"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Folosind comenzile de gestionare a notificărilor, puteți să setați un nivel de importanță de la 0 la 5 pentru notificările unei aplicații. \n\n"<b>"Nivelul 5"</b>" \n– Se afișează la începutul listei de notificări \n– Se permite întreruperea pe ecranul complet \n– Se afișează întotdeauna scurt \n\n"<b>"Nivelul 4"</b>" \n– Se împiedică întreruperea pe ecranul complet \n– Se afișează întotdeauna scurt \n\n"<b>"Nivelul 3"</b>" \n– Se împiedică întreruperea pe ecranul complet \n– Nu se afișează niciodată scurt \n\n"<b>"Nivelul 2"</b>" \n– Se împiedică întreruperea pe ecranul complet \n– Nu se afișează niciodată scurt \n– Nu se emit sunete și nu vibrează niciodată \n\n"<b>"Nivelul 1"</b>" \n– Se împiedică întreruperea pe ecranul complet \n– Nu se afișează niciodată scurt \n– Nu se emit sunete și nu vibrează niciodată \n– Se ascunde în ecranul de blocare și în bara de stare \n– Se afișează la finalul listei de notificări \n\n"<b>"Nivelul 0"</b>" \n– Se blochează toate notificările din aplicație"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificări"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Nu veți mai primi aceste notificări."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Nu veți mai primi aceste notificări"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorii de notificări"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Această aplicație nu are categorii de notificare"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Notificările din această aplicație nu pot fi dezactivate"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="few">1 din <xliff:g id="NUMBER_1">%d</xliff:g> categorii de notificare din această aplicație</item>
       <item quantity="other">1 din <xliff:g id="NUMBER_1">%d</xliff:g> de categorii de notificare din această aplicație</item>
@@ -576,12 +580,18 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"comenzile notificării"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opțiuni de amânare a notificării"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minute"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 de minute"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 oră"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ore"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ANULAȚI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Amânată <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="few">%d ore</item>
+      <item quantity="other">%d de ore</item>
+      <item quantity="one">%d oră</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="few">%d minute</item>
+      <item quantity="other">%d de minute</item>
+      <item quantity="one">%d minut</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Utilizarea bateriei"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Economisirea bateriei nu este disponibilă pe durata încărcării"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economisirea bateriei"</string>
@@ -771,4 +781,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Înlocuiți"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplicațiile rulează în fundal"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Atingeți pentru mai multe detalii privind bateria și utilizarea datelor"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Dezactivați datele mobile?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings_car.xml b/packages/SystemUI/res/values-ro/strings_car.xml
index 54d8585..27751f6 100644
--- a/packages/SystemUI/res/values-ro/strings_car.xml
+++ b/packages/SystemUI/res/values-ro/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduceți atent"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Aflați mereu condițiile de trafic și respectați întotdeauna legislația aplicabilă. Indicațiile de orientare pot fi inexacte, incomplete, periculoase, neadecvate, interzise sau pot implica trecerea prin zone administrative. Informațiile despre companii pot fi, de asemenea, inexacte sau incomplete. Datele nu sunt în timp real și nu se poate garanta exactitatea locației. Nu manipulați dispozitivul mobil și nu folosiți aplicații neconcepute pentru Android Auto când sunteți la volan."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Necunoscut"</string>
+    <string name="start_driving" msgid="864023351402918991">"Începeți să conduceți"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 2fa3ad2..599dacf 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -244,9 +244,9 @@
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Зарядка батареи"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Передача данных 2G и 3G приостановлена"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Передача данных 4G приостановлена"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Передача данных по моб. сети приостановлена"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Передача данных остановлена"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Передача данных приостановлена"</string>
-    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Достигнут лимит мобильного трафика, и вы больше его не расходуете.\n\nЕсли вы продолжите, возможно, начнет взиматься плата за передачу данных."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Достигнут лимит мобильного трафика, и передача данных остановлена.\n\nЕсли вы возобновите передачу данных по мобильной сети, может взиматься плата."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Возобновить"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Нет интернет-подключения"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi подключено"</string>
@@ -316,6 +316,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Настройки"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Готово"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Подключено"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Подключено, уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Соединение..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Режим модема"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Точка доступа"</string>
@@ -473,6 +474,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Запущено приложение \"<xliff:g id="APPLICATION">%1$s</xliff:g>\", которое может отслеживать ваши действия в сети, включая работу с электронной почтой, приложениями и веб-сайтами."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Вашим рабочим профилем управляет организация \"<xliff:g id="ORGANIZATION">%1$s</xliff:g>\". Приложение \"<xliff:g id="APPLICATION">%2$s</xliff:g>\" может отслеживать ваши действия в корпоративной сети, включая работу с электронной почтой, приложениями и веб-сайтами.\n\nЧтобы получить подробную информацию, обратитесь к администратору."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Вашим рабочим профилем управляет организация \"<xliff:g id="ORGANIZATION">%1$s</xliff:g>\". Приложение \"<xliff:g id="APPLICATION_WORK">%2$s</xliff:g>\" может отслеживать ваши действия в корпоративной сети, включая работу с электронной почтой, приложениями и веб-сайтами.\n\nТакже запущено приложение \"<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>\", которое может отслеживать ваши действия в сети, выполняемые в личном профиле."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Разблокировано для пользователя <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Агент \"<xliff:g id="TRUST_AGENT">%1$s</xliff:g>\" работает"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Устройство необходимо будет разблокировать вручную"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Быстрый доступ к уведомлениям"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Просматривайте уведомления на заблокированном экране."</string>
@@ -554,9 +557,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Отключено"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"С помощью этой функции вы можете устанавливать уровень важности уведомлений от 0 до 5 для каждого приложения.\n\n"<b>"Уровень 5"</b>\n"‒ Помещать уведомления в начало списка.\n‒ Показывать полноэкранные уведомления.\n‒ Показывать всплывающие уведомления.\nУровень 4\n"<b></b>\n"‒ Не показывать полноэкранные уведомления.\n‒ Показывать всплывающие уведомления.\nУровень 3\n"<b></b>\n"‒ Не показывать полноэкранные уведомления.\n‒ Не показывать всплывающие уведомления.\nУровень 2\n"<b></b>\n"‒ Не показывать полноэкранные уведомления.\n‒ Не показывать всплывающие уведомления.\n‒ Не использовать звук и вибрацию.\nУровень 1\n"<b></b>\n"‒ Не показывать полноэкранные уведомления.\n‒ Не показывать всплывающие уведомления.\n‒ Не использовать звук и вибрацию.\n‒ Не показывать на экране блокировки и в строке состояния.\n‒ Помещать уведомления в конец списка.\nУровень 0\n"<b></b>\n"‒ Блокировать все уведомления приложения."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Уведомления"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Вы больше не будете получать эти уведомления."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Вы больше не будете получать эти уведомления"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Категорий оповещений: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"В приложении нет категорий уведомлений"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Уведомления этого приложения нельзя отключить"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 из <xliff:g id="NUMBER_1">%d</xliff:g> категории уведомлений этого приложения</item>
       <item quantity="few">1 из <xliff:g id="NUMBER_1">%d</xliff:g> категорий уведомлений этого приложения</item>
@@ -580,12 +584,20 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g>: <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"настройки уведомлений"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"параметры отсрочки уведомлений"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минут"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 минут"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 час"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 часа"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ОТМЕНИТЬ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Отложено на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d час</item>
+      <item quantity="few">%d часа</item>
+      <item quantity="many">%d часов</item>
+      <item quantity="other">%d часа</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d минута</item>
+      <item quantity="few">%d минуты</item>
+      <item quantity="many">%d минут</item>
+      <item quantity="other">%d минуты</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Уровень заряда"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режим энергосбережения нельзя включить во время зарядки"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим энергосбережения"</string>
@@ -775,4 +787,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Заменить"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Приложения, работающие в фоновом режиме"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Нажмите, чтобы проверить энергопотребление и трафик"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Отключить мобильный Интернет?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings_car.xml b/packages/SystemUI/res/values-ru/strings_car.xml
index cbdb8d7..f697cbd 100644
--- a/packages/SystemUI/res/values-ru/strings_car.xml
+++ b/packages/SystemUI/res/values-ru/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Безопасность движения"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Всегда учитывайте дорожную обстановку и соблюдайте правила. Маршруты могут быть неточными, неполными, проходить по опасным, неподходящим или запрещенным для движения участкам или пересекать границы. Сведения об организациях также могут быть неточными и неполными. Данные не обновляются в режиме реального времени, и точность определения местоположения не гарантируется. Не пользуйтесь мобильным устройством и не используйте приложения, не предназначенные для Android Auto, управляя автомобилем."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Неизвестный пользователь"</string>
+    <string name="start_driving" msgid="864023351402918991">"Запустить навигацию"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index c8865ae..2d3ce16 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"තව සැකසීම්"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"නිමයි"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"සම්බන්ධිත"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"සම්බන්ධිතයි, බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"සම්බන්ධ වෙමින්..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ටෙදරින්"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"හොට්ස්පොට්"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"ඊ-තැපැල්, යෙදුම් සහ වෙබ් අඩවි ඇතුළු ඔබේ පෞද්ගලික ජාල ක්‍රියාකාරකම් නිරීක්ෂණය කළ හැකි, <xliff:g id="APPLICATION">%1$s</xliff:g> වෙත ඔබ සම්බන්ධ වී ඇත."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"ඔබේ කාර්ය පැතිකඩ කළමනාකරණය කරන්නේ <xliff:g id="ORGANIZATION">%1$s</xliff:g> මගිනි. ඔබේ ඊ-තැපැල්, යෙදුම්, සහ වෙබ් අඩවි ඇතුළු, ඔබේ ජාල ක්‍රියාකාරකම් නිරීක්ෂණය කළ හැකි, <xliff:g id="APPLICATION">%2$s</xliff:g> වෙත පැතිකඩ සම්බන්ධය.\n\nවැඩිදුර තොරතුරු සඳහා, ඔබගේ පරිපාලක අමතන්න."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"ඔබේ කාර්යාල පැතිකඩ කළමනාකරණය කරන්නේ <xliff:g id="ORGANIZATION">%1$s</xliff:g> විසිනි. ඊ-තැපැල්, යෙදුම් සහ වෙබ් අඩවි ඇතුළු ඔබේ කාර්යාල ජාල ක්‍රියාකාරකම් නිරීක්ෂණය කළ හැකි, <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, වෙත පැතිකඩ සම්බන්ධ වී ඇත.\n\nඔබ ඔබේ පෞද්ගලික ජාල ක්‍රියාකාරකම් නිරීක්ෂණය කළ හැකි, <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> වෙතද සම්බන්ධ වී ඇත."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> සඳහා අගුලු හරින ලදී"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ධාවනය වේ"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"ඔබ අතින් අගුළු අරින තුරු උපකරණය අගුළු වැටි තිබේ"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"දැනුම්දීම් ඉක්මනින් ලබාගන්න"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ඔබ අඟුළු හැරීමට කලින් ඒවා බලන්න"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ක්‍රියාවිරහිතයි"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"බල දැනුම්දීම් පාලන සමගින්, ඔබට යෙදුමක දැනුම්දීම් සඳහා වැදගත්කම 0 සිට 5 දක්වා සැකසිය හැකිය. \n\n"<b>"5 මට්ටම"</b>" \n- දැනුම්දීම් ලැයිස්තුවේ ඉහළින්ම පෙන්වන්න \n- පූර්ණ තිර බාධාවට ඉඩ දෙන්න \n- සැම විට එබී බලන්න \n\n"<b>"4 මට්ටම"</b>" \n- පූර්ණ තිර බාධාව වළක්වන්න \n- සැම විට එබී බලන්න \n\n"<b>"3 මට්ටම"</b>" \n- පූර්ණ තිර බාධාව වළක්වන්න \n- කිසි විටක එබී නොබලන්න \n\n"<b>"2 මට්ටම"</b>" \n- පූර්ණ තිර බාධාව වළක්වන්න \n- කිසි විටක එබී නොබලන්න \n- කිසි විටක හඬ සහ කම්පනය සිදු නොකරන්න \n\n"<b>"1 මට්ටම"</b>" \n- පූර්ණ තිර බාධාව වළක්වන්න \n- කිසි විටක එබී නොබලන්න \n- කිසි විටක හඬ සහ කම්පනය සිදු නොකරන්න \n- අගුලු තිරය සහ තත්ත්ව තීරුව වෙතින් සඟවන්න \n- දැනුම්දීම් ලැයිස්තුවේ පහළින්ම පෙන්වන්න \n\n"<b>"0 මට්ටම"</b>" \n- යෙදුම වෙතින් වන සියලු දැනුම් දීම් සඟවන්න."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"දැනුම් දීම්"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ඔබ තවදුරටත් මෙම දැනුම්දීම් නොලැබෙනු ඇත."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ඔබට තවදුරටත් මෙම දැනුම්දීම් නොලැබෙනු ඇත"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"දැනුම්දීම් කාණ්ඩ <xliff:g id="NUMBER">%d</xliff:g>ක්"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"මෙම යෙදුම හට දැනුම්දීම් ප්‍රවර්ග නොමැත"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"මෙම යෙදුම වෙතින් වන දැනුම්දීම් ක්‍රියාවිරහිත කළ නොහැකිය"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">මෙම යෙදුමෙන් දැනුම්දීම් ප්‍රවර්ග <xliff:g id="NUMBER_1">%d</xliff:g>න් 1ක්</item>
       <item quantity="other">මෙම යෙදුමෙන් දැනුම්දීම් ප්‍රවර්ග <xliff:g id="NUMBER_1">%d</xliff:g>න් 1ක්</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"දැනුම්දීම් පාලන"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"දැනුම්දීම් මදක් නතර කිරීමේ විකල්ප"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"මිනිත්තු 15"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"මිනිත්තු 30"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"පැය 1"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"පැය 2"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"අස් කරන්න"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>ක් මදක් නතර කරන ලදී"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">පැය %d</item>
+      <item quantity="other">පැය %d</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">මිනිත්තු %d</item>
+      <item quantity="other">මිනිත්තු %d</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"බැටරි භාවිතය"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ආරෝපණය අතරතුර බැටරි සුරැකුම ලබා ගත නොහැකිය."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"බැටරි සුරැකුම"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"ප්‍රතිස්ථාපනය"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"පසුබිමින් ධාවනය වන යෙදුම්"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"බැටරි හා දත්ත භාවිතය පිළිබඳව විස්තර සඳහා තට්ටු කරන්න"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"ජංගම දත්ත ක්‍රියාවිරහිත කරන්නද?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings_car.xml b/packages/SystemUI/res/values-si/strings_car.xml
index 549e89b..14ec53b 100644
--- a/packages/SystemUI/res/values-si/strings_car.xml
+++ b/packages/SystemUI/res/values-si/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ආරක්ෂිතව රිය පදවන්න"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"රිය පැදවීම් තත්ත්වයන් ගැන පූර්ණ අවධානයෙන් සිටින්න, සැම විටම අදාළ සියලු නීතිවලට ගරු කරන්න. මග පෙන්වීම් නිවැරදි නොවීමට, අසම්පූර්ණ වීමට, භයානක වීමට, නුසුදුසු වීමට, තහනම් ඒවා වීමට, හෝ පරිපාලන ප්‍රදේශ තරණයට අදාළ ඒවා වීමට හැකිය. දත්ත තථ්‍ය කාල නොවීමට හැකි අතර, ස්ථාන නිරවද්‍යතාව සහතික කළ නොහැකිය. රිය පදවන අතරතුර ඔබේ ජංගම උපාංගය භාවිත කිරීම හෝ Android Auto සඳහා නිපදවා නැති යෙදුම් භාවිත කිරීම නොකරන්න."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"නොදනී"</string>
+    <string name="start_driving" msgid="864023351402918991">"රිය පැදවීම ආරම්භ කරන්න"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 0741d84..ca37a63 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -45,7 +45,7 @@
     <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"Zapnúť"</string>
     <string name="battery_saver_start_action" msgid="5576697451677486320">"Zapnúť šetrič batérie"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nastavenia"</string>
-    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
+    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi‑Fi"</string>
     <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Automatické otočenie obrazovky"</string>
     <string name="status_bar_settings_mute_label" msgid="554682549917429396">"STLMIŤ"</string>
     <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
@@ -57,7 +57,7 @@
     <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k periférnemu zariadeniu USB?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Chcete pri pripojení tohto zariadenia USB otvoriť aplikáciu <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string>
     <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Chcete pri pripojení tohto periférneho zariadenia USB otvoriť aplikáciu <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string>
-    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"S týmto zariad. USB nefunguje žiadna nainštal. aplikácia. Viac informácií na <xliff:g id="URL">%1$s</xliff:g>"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"S týmto zariad. USB nefunguje žiadna nainštal. aplikácia. Ďalšie informácie na <xliff:g id="URL">%1$s</xliff:g>"</string>
     <string name="title_usb_accessory" msgid="4966265263465181372">"Periférne zariadenie USB"</string>
     <string name="label_view" msgid="6304565553218192990">"Zobraziť"</string>
     <string name="always_use_device" msgid="1450287437017315906">"Pre toto zariadenie USB použiť ako predvolené"</string>
@@ -152,7 +152,7 @@
     <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
     <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Roaming"</string>
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
-    <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
+    <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi‑Fi"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"Žiadna SIM karta."</string>
     <string name="accessibility_cell_data" msgid="5326139158682385073">"Mobilné dáta"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Mobilné dáta sú zapnuté"</string>
@@ -194,8 +194,8 @@
     <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"Uzamknutá obrazovka pracovného profilu"</string>
     <string name="accessibility_desc_close" msgid="7479755364962766729">"Zavrieť"</string>
     <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>"</string>
-    <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Pripojenie Wi-Fi je vypnuté."</string>
-    <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"Pripojenie Wi-Fi je zapnuté."</string>
+    <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Pripojenie Wi‑Fi je vypnuté."</string>
+    <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"Pripojenie Wi‑Fi je zapnuté."</string>
     <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Batéria: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"Režim v lietadle je vypnutý."</string>
@@ -246,10 +246,10 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Dátové prenosy 4G sú pozastavené"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Mobilné dáta sú pozastavené"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Dáta sú pozastavené"</string>
-    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Dosiahli ste nastavený dátový limit. Už nepoužívate mobilné dáta.\n\nAk budete pokračovať, môžu vám byť účtované poplatky za spotrebu dát."</string>
-    <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Znova spustiť"</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Dosiahli ste nastavený dátový limit. Už nepoužívate mobilné dátové pripojenie.\n\nAk ho znovu zapnete, môžu vám byť účtované poplatky za spotrebu dát."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Znova zapnúť"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Bez prip. na Internet"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: pripojené"</string>
+    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi‑Fi: pripojené"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Vyhľadávanie satelitov GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Poloha nastavená pomocou GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Žiadosti o polohu sú aktívne"</string>
@@ -298,12 +298,12 @@
     <string name="quick_settings_user_label" msgid="5238995632130897840">"Ja"</string>
     <string name="quick_settings_user_title" msgid="4467690427642392403">"Používateľ"</string>
     <string name="quick_settings_user_new_user" msgid="9030521362023479778">"Nový používateľ"</string>
-    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
+    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi‑Fi"</string>
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Nepripojené"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Žiadna sieť"</string>
-    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Sieť Wi-Fi je vypnutá"</string>
-    <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi je zapnuté"</string>
-    <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"K dispozícii nie sú žiadne siete Wi-Fi"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Sieť Wi‑Fi je vypnutá"</string>
+    <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi‑Fi je zapnuté"</string>
+    <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"K dispozícii nie sú žiadne siete Wi‑Fi"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Prenos"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Prenáša sa"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Nepomenované zariadenie"</string>
@@ -311,11 +311,12 @@
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Nie sú k dispozícii žiadne zariadenia"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Jas"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATICKY"</string>
-    <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Invertovať farby"</string>
+    <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inverzia farieb"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Režim korekcie farieb"</string>
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Ďalšie nastavenia"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Hotovo"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Pripojené"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Pripojené, stav batérie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Pripája sa..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Zdieľané pripojenie"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -473,6 +474,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Ste pripojený/-á k aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g>, ktorá môže sledovať vašu osobnú aktivitu v sieti vrátane e-mailových správ, aplikácií a webových stránok."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Váš pracovný profil spravuje organizácia <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Je pripojený k aplikácii <xliff:g id="APPLICATION">%2$s</xliff:g>, ktorá môže sledovať vašu pracovnú aktivitu v sieti vrátane správ, aplikácií a webových stránok.\n\nĎalšie informácie vám poskytne správca."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Váš pracovný profil spravuje organizácia <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Je pripojený k aplikácii <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, ktorá môže sledovať vašu pracovnú aktivitu v sieti vrátane správ, aplikácií a webových stránok.\n\nPripojili ste sa k aplikácii <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, ktorá môže sledovať vašu osobnú aktivitu v sieti."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Odomknuté pre používateľa <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Agent <xliff:g id="TRUST_AGENT">%1$s</xliff:g> je spustený"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Zariadenie zostane uzamknuté, dokým ho ručne neodomknete."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Získavať upozornenia rýchlejšie"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Zobraziť pred odomknutím"</string>
@@ -554,9 +557,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Vypnuté"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Pomocou ovládacích prvkov zobrazovania upozornení môžete nastaviť pre upozornenia aplikácie úroveň dôležitosti od 0 do 5. \n\n"<b>"Úroveň 5"</b>" \n– Zobrazovať v hornej časti zoznamu upozornení. \n– Povoliť prerušenia na celú obrazovku. \n– Vždy zobrazovať čiastočne. \n\n"<b>"Úroveň 4"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Vždy zobrazovať čiastočne. \n\n"<b>"Úroveň 3"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Nikdy nezobrazovať čiastočne. \n\n"<b>"Úroveň 2"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Nikdy nezobrazovať čiastočne. \n– Nikdy nespúšťať zvuk ani vibrácie. \n\n"<b>"Úroveň 1"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Nikdy nezobrazovať čiastočne. \n– Nikdy nespúšťať zvuk ani vibrácie. \n– Skryť na uzamknutej obrazovke a v stavovom riadku. \n– Zobraziť v dolnej časti zoznamu upozornení. \n\n"<b>"Úroveň 0"</b>" \n– Blokovať všetky upozornenia z aplikácie."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Upozornenia"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Takéto upozornenia už nebudete dostávať."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Tieto upozornenia už nebudete dostávať"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Počet kategórií upozornení: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Táto aplikácia nemá kategórie upozornení"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Upozornenia z tejto aplikácie sa nedajú vypnúť"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="few">1 z <xliff:g id="NUMBER_1">%d</xliff:g> kategórií upozornení z tejto aplikácie</item>
       <item quantity="many">1 z <xliff:g id="NUMBER_1">%d</xliff:g> kategórie upozornení z tejto aplikácie</item>
@@ -580,12 +584,20 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"ovládacie prvky pre upozornenia"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"možnosti stlmenia upozornení"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minút"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minút"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hod."</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 hodiny"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"SPÄŤ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Stlmené na <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="few">%d hodiny</item>
+      <item quantity="many">%d hodiny</item>
+      <item quantity="other">%d hodín</item>
+      <item quantity="one">%d hodina</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="few">%d minúty</item>
+      <item quantity="many">%d minúty</item>
+      <item quantity="other">%d minút</item>
+      <item quantity="one">%d minúta</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Využitie batérie"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Počas nabíjania nie je Šetrič batérie k dispozícii"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Šetrič batérie"</string>
@@ -604,7 +616,7 @@
     <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
     <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Prehrať/pozastaviť"</string>
     <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Zastaviť"</string>
-    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Nasledujúce"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Ďalej"</string>
     <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Predchádzajúce"</string>
     <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Pretočiť späť"</string>
     <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Pretočiť dopredu"</string>
@@ -764,7 +776,7 @@
     <string name="app_info" msgid="6856026610594615344">"Info o aplikácii"</string>
     <string name="go_to_web" msgid="1106022723459948514">"Prejsť na internet"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobilné dáta"</string>
-    <string name="wifi_is_off" msgid="1838559392210456893">"Pripojenie Wi-Fi je vypnuté"</string>
+    <string name="wifi_is_off" msgid="1838559392210456893">"Pripojenie Wi‑Fi je vypnuté"</string>
     <string name="bt_is_off" msgid="2640685272289706392">"Rozhranie Bluetooth je vypnuté"</string>
     <string name="dnd_is_off" msgid="6167780215212497572">"Nastavenie Nerušiť je vypnuté"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"Režim Nerušiť bol zapnutý automatickým pravidlom (<xliff:g id="ID_1">%s</xliff:g>)."</string>
@@ -775,4 +787,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Nahradiť"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikácie sú spustené na pozadí"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Klepnutím zobrazíte podrobnosti o batérii a spotrebe dát"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vypnúť mobilné dáta?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings_car.xml b/packages/SystemUI/res/values-sk/strings_car.xml
index bd9410d..6512065 100644
--- a/packages/SystemUI/res/values-sk/strings_car.xml
+++ b/packages/SystemUI/res/values-sk/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Jazdite bezpečne"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Zachovajte si úplný prehľad o jazdných podmienkach a vždy dodržiavajte príslušné zákony. Trasy môžu byť nepresné, neúplné, nebezpečné, nevhodné, zakázané alebo môžu zahŕňať cestu cez rôzne správne oblasti. Obchodné informácie môžu byť tiež nepresné alebo neúplné. Údaje nie sú aktualizované v reálnom čase a presnosť polohy nemôžeme zaručiť. Počas jazdy nemanipulujte s mobilným zariadením ani nepoužívajte aplikácie, ktoré nie sú určené pre funkciu Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Neznáme"</string>
+    <string name="start_driving" msgid="864023351402918991">"Začať šoférovať"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 8289516..16f830e06 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -316,6 +316,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Več nastavitev"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Končano"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Povezava je vzpostavljena"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Povezava je vzpostavljena, raven napolnjenosti akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Vzpostavljanje povezave ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Internet prek mobilne naprave"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Dostopna točka"</string>
@@ -473,6 +474,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Povezani ste z aplikacijo <xliff:g id="APPLICATION">%1$s</xliff:g>, ki lahko nadzira vašo osebno omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Delovni profil upravlja organizacija <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil je povezan z aplikacijo <xliff:g id="APPLICATION">%2$s</xliff:g>, ki lahko nadzira vašo delovno omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti.\n\nZa več informacij se obrnite na skrbnika."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Delovni profil upravlja organizacija <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil je povezan z aplikacijo <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, ki lahko nadzira vašo delovno omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti.\n\nPovezani ste tudi z aplikacijo <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, ki lahko nadzira vašo osebno omrežno dejavnost."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Odklenjeno za uporabnika <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> se izvaja"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Naprava bo ostala zaklenjena, dokler je ročno ne odklenete."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Hitrejše prejemanje obvestil"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Oglejte si jih pred odklepanjem"</string>
@@ -554,9 +557,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Izklopljeno"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"S kontrolniki za pomebnost obvestila je mogoče za obvestila aplikacije nastaviti stopnjo pomembnosti od 0 do 5. \n\n"<b>"Stopnja 5"</b>" \n– Prikaz na vrhu seznama obvestil \n– Omogočanje prekinitev v celozaslonskem načinu \n– Vedno prikaži hitre predoglede \n\n"<b>"Stopnja 4"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Vedno prikaži hitre predoglede \n\n"<b>"Stopnja 3"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Nikoli ne prikaži hitrih predogledov \n\n"<b>"Stopnja 2"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Nikoli ne prikaži hitrih predogledov \n– Nikoli ne uporabi zvoka in vibriranja \n\n"<b>"Stopnja 1"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Nikoli ne prikaži hitrih predogledov \n– Nikoli ne uporabi zvoka in vibriranja \n– Skrivanje na zaklenjenem zaslonu in v vrstici stanja \n– Prikaz na dnu seznama obvestil \n\n"<b>"Stopnja 0"</b>" \n– Blokiranje vseh obvestil aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obvestila"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Teh obvestil ne boste več prejemali."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Teh obvestil ne boste več prejemali"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Št. kategorij obvestil: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ta aplikacija nima kategorij obvestil"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Obvestil te aplikacije ni mogoče izklopiti"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije obvestil iz te aplikacije</item>
       <item quantity="two">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorij obvestil iz te aplikacije</item>
@@ -580,12 +584,20 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kontrolniki obvestil"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"možnosti preložitve obvestil"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minut"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minut"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ura"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 uri"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"RAZVELJAVI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Preloženo za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d ura</item>
+      <item quantity="two">%d uri</item>
+      <item quantity="few">%d ure</item>
+      <item quantity="other">%d ur</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d minuta</item>
+      <item quantity="two">%d minuti</item>
+      <item quantity="few">%d minute</item>
+      <item quantity="other">%d minut</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Poraba akumulatorja"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Varčevanje z energijo akumulatorja med polnjenjem ni na voljo"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Varčevanje z energijo akumulatorja"</string>
@@ -775,4 +787,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Zamenjaj"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacije, ki se izvajajo v ozadju"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dotaknite se za prikaz podrobnosti porabe akumulatorja in prenosa podatkov"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Želite izklopiti prenos podatkov v mobilnih omrežjih?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings_car.xml b/packages/SystemUI/res/values-sl/strings_car.xml
index 0102799..8e05730 100644
--- a/packages/SystemUI/res/values-sl/strings_car.xml
+++ b/packages/SystemUI/res/values-sl/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Varna vožnja"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Bodite pozorni na vozne razmere in vselej upoštevajte veljavno zakonodajo. Navodila za pot so morda nenatančna, nepopolna, nevarna, neprimerna ali prepovedana oziroma vključujejo prečkanje upravnih območij. Prav tako nenatančni ali nepopolni so lahko podatki o podjetjih. Podatki niso sprotni in natančnosti lociranja ni mogoče zagotoviti. Med vožnjo ne uporabljajte mobilne naprave ali aplikacij, ki niso namenjene za Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Neznano"</string>
+    <string name="start_driving" msgid="864023351402918991">"Začnite voziti"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 15cc542..f0a7e45 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Cilësime të tjera"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"U krye!"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"I lidhur"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"E lidhur, bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Po lidhet..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Lidhje çiftimi"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Qasje në zona publike interneti"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Je i lidhur me aplikacionin <xliff:g id="APPLICATION">%1$s</xliff:g>, i cili mund të monitorojë aktivitetin tënd personal në rrjet, përfshirë mailet, aplikacionet dhe sajtet e uebit."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Profili yt i punës menaxhohet nga <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profili është i lidhur me <xliff:g id="APPLICATION">%2$s</xliff:g>, i cili mund të monitorojë aktivitetin tënd të punës në rrjet, duke përfshirë mail-et, aplikacionet dhe sajtet e uebit.\n\nPër më shumë informacione, kontakto me administratorin."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Profili yt i punës menaxhohet nga <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profili është i lidhur me <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, i cili mund të monitorojë aktivitetin tënd të punës në rrjet, duke përfshirë mail-et, aplikacionet dhe sajtet e uebit.\n\nJe lidhur gjithashtu edhe me <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, i cili mund të monitorojë aktivitetin tënd personal në rrjet."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Shkyçur për <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> po ekzekutohet"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Pajisje do të qëndrojë e kyçur derisa ta shkyçësh manualisht"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Merr njoftime më shpejt"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Shikoji para se t\'i shkyçësh"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Joaktiv"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Me kontrollet e njoftimit të energjisë, mund të caktosh një nivel rëndësie nga 0 në 5 për njoftimet e një aplikacioni. \n\n"<b>"Niveli 5"</b>" \n- Shfaq në krye të listës së njoftimeve \n- Lejo ndërprerjen e ekranit të plotë \n- Gjithmonë shfaq shpejt \n\n"<b>"Niveli 4"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Gijthmonë shfaq shpejt \n\n"<b>"Niveli 3"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Asnjëherë mos shfaq shpejt \n\n"<b>"Niveli 2"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Asnjëherë mos shfaq shpejt \n- Asnjëherë mos lësho tingull dhe dridhje \n\n"<b>"Niveli 1"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Asnjëherë mos shfaq shpejt \n- Asnjëherë mos lësho tingull ose dridhje \n- Fshih nga ekrani i kyçjes dhe shiriti i statusit \n- Shfaq në fund të listës së njoftimeve \n\n"<b>"Niveli 0"</b>" \n- Blloko të gjitha njoftimet nga aplikacioni"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Njoftime"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Këto njoftime nuk do t\'i marrësh më."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Këto njoftime nuk do t\'i marrësh më"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> kategori njoftimesh"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ky aplikacion nuk ka kategori njoftimesh"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Njoftimet nga ky aplikacion nuk mund të çaktivizohen"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 nga <xliff:g id="NUMBER_1">%d</xliff:g> kategori njoftimi nga ky aplikacion</item>
       <item quantity="one">1 nga <xliff:g id="NUMBER_0">%d</xliff:g> kategori njoftimi nga ky aplikacion</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kontrollet e njoftimit"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opsionet e shtyrjes së njoftimit"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 orë"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 orë"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ZHBËJ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"U shty për <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d orë</item>
+      <item quantity="one">%d orë</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minuta</item>
+      <item quantity="one">%d minutë</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Përdorimi i baterisë"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"\"Kursyesi i baterisë\" nuk është i disponueshëm gjatë karikimit"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Kursyesi i baterisë"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Zëvendëso"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacionet që ekzekutohen në sfond"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Trokit për detaje mbi baterinë dhe përdorimin e të dhënave"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Të çaktivizohen të dhënat celulare?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings_car.xml b/packages/SystemUI/res/values-sq/strings_car.xml
index 2e63877..b3a52b8 100644
--- a/packages/SystemUI/res/values-sq/strings_car.xml
+++ b/packages/SystemUI/res/values-sq/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Drejtoje makinën në mënyrë të sigurt"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Ji plotësisht i vetëdijshëm për kushtet e lëvizjes me makinë dhe respekto gjithmonë ligjet përkatëse. Udhëzimet mund të jenë të pasakta, jo të plota, të rrezikshme, të papërshtatshme, të ndaluara ose mund të përfshijnë kalimin në zona administrative. Informacionet e biznesit mund të jenë po ashtu të pasakta ose jo të plota. Të dhënat nuk janë në kohë reale dhe saktësia e vendndodhjes nuk mund të garantohet. Gjatë drejtimit të makinës mos e përdor pajisjen celulare ose mos përdor aplikacionet që nuk janë të planifikuara për Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"E panjohur"</string>
+    <string name="start_driving" msgid="864023351402918991">"Fillo të drejtosh makinën"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 4ef7267..94a5909 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Још подешавања"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Готово"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Повезан"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Повезано, ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Повезује се..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Повезивање"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Хотспот"</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Повезани сте са апликацијом <xliff:g id="APPLICATION">%1$s</xliff:g>, која може да надгледа активности на личној мрежи, укључујући имејлове, апликације и веб-сајтове."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Профилом за Work управља <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Повезан је са апликацијом <xliff:g id="APPLICATION">%2$s</xliff:g>, која може да надгледа активности на пословној мрежи, укључујући имејлове, апликације и веб-сајтове.\n\nВише информација потражите од администратора."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Профилом за Work управља <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Повезан је са апликацијом <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, која може да надгледа активности на пословној мрежи, укључујући имејлове, апликације и веб-сајтове.\n\nПовезани сте и са апликацијом <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, која може да надгледа активности на личној мрежи."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Откључано за корисника <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Функција <xliff:g id="TRUST_AGENT">%1$s</xliff:g> је покренута"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Уређај ће остати закључан док га не откључате ручно"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Брже добијајте обавештења"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Прегледајте их пре откључавања"</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Искључено"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Помоћу напредних контрола за обавештења можете да подесите ниво важности од 0. до 5. за обавештења апликације. \n\n"<b>"5. ниво"</b>" \n– Приказују се у врху листе обавештења \n- Дозволи прекид режима целог екрана \n– Увек завируј \n\n"<b>"4. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Увек завируј \n\n"<b>"3. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n\n"<b>"2. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n– Никада не производи звук или вибрацију \n\n"<b>"1. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n– Никада не производи звук или вибрацију \n– Сакриј на закључаном екрану и статусној траци \n– Приказују се у дну листе обавештења \n\n"<b>"0. ниво"</b>" \n– Блокирај сва обавештења из апликације"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Обавештења"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Више нећете да добијате ова обавештења."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Више нећете добијати ова обавештења"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Категорија обавештења: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ова апликација нема категорије обавештења"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Обавештења из ове апликације не могу да се искључе"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 од <xliff:g id="NUMBER_1">%d</xliff:g> категорије обавештења за ову апликацију</item>
       <item quantity="few">1 од <xliff:g id="NUMBER_1">%d</xliff:g> категорије обавештења за ову апликацију</item>
@@ -574,12 +578,18 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"контроле обавештења"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"опције за одлагање обавештења"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минута"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 минута"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 сат"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 сата"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ОПОЗОВИ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Одложено је за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d сат</item>
+      <item quantity="few">%d сата</item>
+      <item quantity="other">%d сати</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d минут</item>
+      <item quantity="few">%d минута</item>
+      <item quantity="other">%d минута</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Потрошња батерије"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Уштеда батерије није доступна током пуњења"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Уштеда батерије"</string>
@@ -769,4 +779,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Замени"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Апликације покренуте у позадини"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Додирните за детаље о батерији и потрошњи података"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Желите да онемогућите мобилне податке?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings_car.xml b/packages/SystemUI/res/values-sr/strings_car.xml
index 7f99120..88e2714 100644
--- a/packages/SystemUI/res/values-sr/strings_car.xml
+++ b/packages/SystemUI/res/values-sr/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Возите безбедно"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Увек водите рачуна о условима вожње и увек поштујте примењиве законе. Упутства могу да буду нетачна, непотпуна, опасна, неприкладна или забрањена, односно да подразумевају прелазак између административних области. И подаци о предузећу могу да буду нетачни или непотпуни. Подаци не настају у реалном времену и не можемо да гарантујемо прецизност локације. Немојте да употребљавате мобилни уређај нити да користите апликације које нису намењене за Android Auto током вожње."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Непознато"</string>
+    <string name="start_driving" msgid="864023351402918991">"Почните да возите"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index a479bea..839cc4b 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -227,8 +227,8 @@
     <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"Ficklampan har aktiverats."</string>
     <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"Färginverteringen har inaktiverats."</string>
     <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"Färginverteringen har aktiverats."</string>
-    <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Den mobila trådlösa surfzonen har inaktiverats."</string>
-    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Den mobila trådlösa surfzonen har aktiverats."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Den mobila surfzonen har inaktiverats."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Den mobila surfzonen har aktiverats."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Castningen av skärmen har stoppats."</string>
     <string name="accessibility_quick_settings_work_mode_off" msgid="7045417396436552890">"Arbetsläget är inaktiverat."</string>
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Arbetsläget aktiverat."</string>
@@ -310,9 +310,10 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Fler inställningar"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Klart"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Ansluten"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Ansluten, batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Ansluter ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Internetdelning"</string>
-    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Trådlös surfzon"</string>
+    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Surfzon"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Aviseringar"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Ficklampa"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobildata"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Du är ansluten till <xliff:g id="APPLICATION">%1$s</xliff:g> som kan övervaka din privata aktivitet på nätverket, inklusive e-postmeddelanden, appar och webbplatser."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Jobbprofilen hanteras av <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilen är ansluten till <xliff:g id="APPLICATION">%2$s</xliff:g> som kan bevaka din nätverksaktivitet, exempelvis e-post, appar och webbplatser.\n\nKontakta administratören om du vill veta mer."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Jobbprofilen hanteras av <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilen är ansluten till <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> som kan bevaka din nätverksaktivitet på jobbet, exempelvis e-post, appar och webbplatser.\n\nDu är även ansluten till <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> som kan bevaka din privata nätverksaktivitet."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Upplåst för <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> körs"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Enheten förblir låst tills du låser upp den manuellt"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Få aviseringar snabbare"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Visa dem innan du låser upp"</string>
@@ -521,7 +524,7 @@
     <string name="alarm_template" msgid="3980063409350522735">"kl. <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="4242179982586714810">"kl. <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Snabbinställningar, <xliff:g id="TITLE">%s</xliff:g>."</string>
-    <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Trådlös surfzon"</string>
+    <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Surfzon"</string>
     <string name="accessibility_managed_profile" msgid="6613641363112584120">"Jobbprofil"</string>
     <string name="tuner_warning_title" msgid="7094689930793031682">"Kul för vissa, inte för alla"</string>
     <string name="tuner_warning" msgid="8730648121973575701">"Du kan använda inställningarna för systemgränssnitt för att justera användargränssnittet i Android. Dessa experimentfunktioner kan när som helst ändras, sluta fungera eller försvinna. Använd med försiktighet."</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"På"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Med aviseringsinställningarna kan du ange prioritetsnivå från 0 till 5 för aviseringar från en app. \n\n"<b>"Nivå 5"</b>" \n– Visa högst upp i aviseringslistan\n– Tillåt avbrott i helskärmsläge \n– Snabbvisa alltid \n\n"<b>"Nivå 4"</b>" \n– Tillåt inte avbrott i helskärmsläge \n– Snabbvisa alltid \n\n"<b>"Nivå 3"</b>" \n- Tillåt inte avbrott i helskärmsläge \n– Snabbvisa aldrig \n\n"<b>"Nivå 2"</b>" \n– Tillåt inte avbrott i helskärmsläge \n– Snabbvisa aldrig \n– Aldrig med ljud eller vibration \n\n"<b>"Nivå 1"</b>" \n– Tillåt inte avbrott i helskärmsläge \n– Snabbvisa aldrig \n– Aldrig med ljud eller vibration \n– Visa inte på låsskärmen och i statusfältet \n– Visa längst ned i aviseringslistan \n\n"<b>"Nivå 0"</b>" \n– Blockera alla aviseringar från appen"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Aviseringar"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Inga fler aviseringar av det här slaget visas."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Inga fler aviseringar av det här slaget visas"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> aviseringskategorier"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Det finns inga aviseringskategorier i appen"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Det går inte att inaktivera aviseringar från den här appen"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 av <xliff:g id="NUMBER_1">%d</xliff:g> aviseringskategorier från denna app</item>
       <item quantity="one">1 av <xliff:g id="NUMBER_0">%d</xliff:g> aviseringskategorier från denna app</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"inställningar för aviseringar"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"alternativ för att snooza aviseringar"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuter"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuter"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 timme"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 timmar"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ÅNGRA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozad i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d timmar</item>
+      <item quantity="one">%d timme</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d minuter</item>
+      <item quantity="one">%d minut</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Batteriförbrukning"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparläget är inte tillgängligt vid laddning"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparläge"</string>
@@ -717,7 +725,7 @@
     <string name="pip_phone_expand" msgid="5889780005575693909">"Utöka"</string>
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Minimera"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Stäng"</string>
-    <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Tryck och dra nedåt för att ignorera"</string>
+    <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Tryck och dra nedåt för att avvisa"</string>
     <string name="pip_menu_title" msgid="3328510504196964712">"Bild-i-bild-meny"</string>
     <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> visas i bild-i-bild"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"Om du inte vill att den här funktionen används för <xliff:g id="NAME">%s</xliff:g> öppnar du inställningarna genom att trycka. Sedan inaktiverar du funktionen."</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Ersätt"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Appar körs i bakgrunden"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tryck för information om batteri- och dataanvändning"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vill du inaktivera mobildatan?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings_car.xml b/packages/SystemUI/res/values-sv/strings_car.xml
index 0c03fb6..25b1136 100644
--- a/packages/SystemUI/res/values-sv/strings_car.xml
+++ b/packages/SystemUI/res/values-sv/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Kör försiktigt"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Håll koll på trafik- och körförhållanden och följ gällande lagar. Det kan hända att vägbeskrivningen inte stämmer, att den är ofullständig, farlig, olämplig, förbjuden eller att den innebär att du måste korsa en administrativ enhet. Det kan även hända att företagsuppgifter är felaktiga eller ofullständiga. Uppgifter visas inte i realtid och det går inte att garantera att platsen är korrekt. Hantera inte din mobila enhet och använd inte appar som inte är ämnade för Android Auto medan du kör."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Okänt"</string>
+    <string name="start_driving" msgid="864023351402918991">"Börja köra"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 462b1ed..e54f6cc 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -77,7 +77,7 @@
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Haina nafasi ya kutosha kuhifadhi picha ya skrini."</string>
     <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Programu au shirika lako halikuruhusu kupiga picha za skrini"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Machaguo ya uhamisho wa faili la USB"</string>
-    <string name="use_mtp_button_title" msgid="4333504413563023626">"Angika kama kichezeshi cha midia (MTP)"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"Angika kama kichezaji cha maudhui (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Angika kama kamera (PTP)"</string>
     <string name="installer_cd_button_title" msgid="2312667578562201583">"Sakinisha programu ya Kuhamisha Faili ya Android ya Mac"</string>
     <string name="accessibility_back" msgid="567011538994429120">"Nyuma"</string>
@@ -284,7 +284,7 @@
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Mbinu ya uingizaji"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Kutambua Eneo"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Kitambua eneo kimezimwa"</string>
-    <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Kifaa cha midia"</string>
+    <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Kifaa cha faili"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Simu za Dharura Pekee"</string>
     <string name="quick_settings_settings_label" msgid="5326556592578065401">"Mipangilio"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Mipangilio zaidi"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Nimemaliza"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Imeunganishwa"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Imeunganishwa, kiwango cha betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Inaunganisha..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Kusambaza mtandao"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Mtandao-hewa"</string>
@@ -383,7 +384,7 @@
     <string name="user_add_user" msgid="5110251524486079492">"Ongeza mtumiaji"</string>
     <string name="user_new_user_name" msgid="426540612051178753">"Mtumiaji mpya"</string>
     <string name="guest_nickname" msgid="8059989128963789678">"Aliyealikwa"</string>
-    <string name="guest_new_guest" msgid="600537543078847803">"Ongeza aliyealikwa"</string>
+    <string name="guest_new_guest" msgid="600537543078847803">"Ongeza mgeni"</string>
     <string name="guest_exit_guest" msgid="7187359342030096885">"Ondoa aliyealikwa"</string>
     <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"Ungependa kumwondoa aliyealikwa?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Data na programu zote katika kipindi hiki zitafutwa."</string>
@@ -467,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Umeunganishwa kwenye <xliff:g id="APPLICATION">%1$s</xliff:g>, ambayo inaweza kufuatilia shughuli za mtandao wako, ikiwa ni pamoja na barua pepe, programu na tovuti."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Wasifu wako wa kazini unasimamiwa na <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Wasifu umeunganishwa kwenye <xliff:g id="APPLICATION">%2$s</xliff:g>, ambayo inaweza kufuatilia shughuli za mtandao wako wa kazini, ikiwa ni pamoja na barua pepe, programu na tovuti.\n\n Wasiliana na msimamizi wako kwa maelezo zaidi."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Wasifu wako wa kazini unasimamiwa na <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Wasifu umeunganishwa kwenye <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, ambayo inaweza kufuatilia shughuli zako kwenye mtandao wa kazini, ikiwa ni pamoja na barua pepe, programu na tovuti.\n\n Umeunganishwa pia kwenye  <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, ambayo inaweza kufuatilia shughuli zako kwenye mtandao wa binafsi."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Imefunguliwa kwa ajili ya <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> inatumika"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Kifaa kitaendelea kuwa katika hali ya kufungwa hadi utakapokifungua mwenyewe"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Pata arifa kwa haraka"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Zitazame kabla hujafungua"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Hapana, asante"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Sanidi"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Zima sasa"</string>
+    <string name="volume_zen_end_now" msgid="6930243045593601084">"Izime sasa"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Panua"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Kunja"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skrini imebandikwa"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Imezimwa"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Ukiwa na udhibiti wa arifa, unaweza kuweka kiwango cha umuhimu wa arifa za programu kuanzia 0 hadi 5. \n\n"<b>"Kiwango cha 5"</b>" \n- Onyesha katika sehemu ya juu ya orodha ya arifa \n- Ruhusu ukatizaji wa skrini nzima \n- Ruhusu arifa za kuchungulia kila wakati\n\n"<b>"Kiwango cha 4"</b>" \n- Zuia ukatizaji wa skrini nzima\n- Ruhusu arifa za kuchungulia kila wakati \n\n"<b>"Kiwango cha 3"</b>" \n- Zuia ukatizaji wa skrini nzima\n- Usiruhusu kamwe arifa za kuchungulia\n\n"<b>"Kiwango cha 2"</b>" \n- Zuia ukatizaji wa skrini nzima\n- Usiruhusu kamwe arifa za kuchungulia \n- Usiruhusu kamwe sauti au mtetemo \n\n"<b>"Kiwango cha 1"</b>" \n- Zuia ukatizaji wa skrini nzima \n- Usiruhusu kamwe arifa za kuchungulia \n- Usiruhusu kamwe sauti na mtetemo \n- Usionyeshe skrini iliyofungwa na sehemu ya arifa \n- Onyesha katika sehemu ya chini ya orodha ya arifa \n\n"<b>"Kiwango cha 0"</b>" \n- Zuia arifa zote kutoka programu"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Arifa"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Hutapokea arifa hizi tena."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Hutapokea arifa hizi tena"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Aina <xliff:g id="NUMBER">%d</xliff:g> za arifa"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Programu hii haina aina za arifa"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Arifa kutoka kwenye programu hii haziwezi kuzimwa"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Aina 1 ya arifa kati ya <xliff:g id="NUMBER_1">%d</xliff:g> kutoka kwenye kifaa hiki</item>
       <item quantity="one">Aina 1 ya arifa kati ya <xliff:g id="NUMBER_0">%d</xliff:g> kutoka kwenye kifaa hiki</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"vidhibiti vya arifa"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"chaguo za kuahirisha arifa"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"Dakika 15"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"Dakika 30"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"Saa 1"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"Saa 2"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"TENDUA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Imeahirishwa kwa <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">Saa %d</item>
+      <item quantity="one">Saa %d</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">Dakika %d</item>
+      <item quantity="one">Dakika %d</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Matumizi ya betri"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Kiokoa Betri hakipatikani unapochaji betri"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Kiokoa Betri"</string>
@@ -588,8 +596,8 @@
     <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Kushoto"</string>
     <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Kulia"</string>
     <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Katikati"</string>
-    <string name="keyboard_key_tab" msgid="3871485650463164476">"Sogeza"</string>
-    <string name="keyboard_key_space" msgid="2499861316311153293">"Nafasi"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
     <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
     <string name="keyboard_key_backspace" msgid="1559580097512385854">"Nafasinyuma"</string>
     <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Cheza/Sitisha"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Badilisha"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Programu zinatumika chinichini"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Gonga ili upate maelezo kuhusu betri na matumizi ya data"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Ungependa kuzima data ya mtandao wa simu?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings_car.xml b/packages/SystemUI/res/values-sw/strings_car.xml
index e4bb25c..319f882 100644
--- a/packages/SystemUI/res/values-sw/strings_car.xml
+++ b/packages/SystemUI/res/values-sw/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Endesha gari kwa usalama"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Jifahamishe kikamilifu kuhusu masharti ya kuendesha gari na utii kila wakati sheria zilizopo. Huenda maelekezo yasiwe sahihi, hayajakamilika, ni hatari, hayafai, hayaruhusiwi au yanahusisha kuvuka maeneo ya kiutawala. Huenda pia maelezo ya biashara yasiwe sahihi au hayajakamilika. Data si ya wakati halisi na hatuwezi kukupa hakikisho kuhusu usahihi wa mahali. Usitumie kifaa chako cha mkononi au programu zisizo za Android Auto wakati unapoendesha gari."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Haijulikani"</string>
+    <string name="start_driving" msgid="864023351402918991">"Anza Kuendesha Gari"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw372dp/config.xml b/packages/SystemUI/res/values-sw372dp/config.xml
new file mode 100644
index 0000000..07b797a
--- /dev/null
+++ b/packages/SystemUI/res/values-sw372dp/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources>
+    <!-- Nav bar button default ordering/layout -->
+    <string name="config_navBarLayout" translatable="false">left[.25W],back[.5WC];home;recent[.5WC],right[.25W]</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index e8ff85c..9905244 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -19,10 +19,10 @@
 
 <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">"UI அமைப்பு"</string>
+    <string name="app_label" msgid="7164937344850004466">"சாதனத்தின் UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"அழி"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"பட்டியலில் இருந்து அகற்று"</string>
-    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"பயன்பாட்டுத் தகவல்"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"ஆப்ஸ் தகவல்"</string>
     <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"சமீபத்திய திரைகள் இங்கு தோன்றும்"</string>
     <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"சமீபத்திய பயன்பாடுகளை நிராகரி"</string>
     <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
@@ -152,9 +152,9 @@
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"வைஃபை"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"சிம் இல்லை."</string>
-    <string name="accessibility_cell_data" msgid="5326139158682385073">"மொபைல் தரவு"</string>
-    <string name="accessibility_cell_data_on" msgid="5927098403452994422">"மொபைல் தரவு இயக்கப்பட்டது"</string>
-    <string name="accessibility_cell_data_off" msgid="443267573897409704">"மொபைல் தரவு முடக்கப்பட்டது"</string>
+    <string name="accessibility_cell_data" msgid="5326139158682385073">"மொபைல் டேட்டா"</string>
+    <string name="accessibility_cell_data_on" msgid="5927098403452994422">"மொபைல் டேட்டா இயக்கப்பட்டது"</string>
+    <string name="accessibility_cell_data_off" msgid="443267573897409704">"மொபைல் டேட்டா முடக்கப்பட்டது"</string>
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"புளூடூத் டெதெரிங்."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"விமானப் பயன்முறை."</string>
     <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN இயக்கத்தில் உள்ளது."</string>
@@ -184,10 +184,10 @@
     <string name="accessibility_notification_dismissed" msgid="854211387186306927">"அறிவிப்பு நிராகரிக்கப்பட்டது."</string>
     <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"அறிவிப்பு விவரம்."</string>
     <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"உடனடி அமைப்பு."</string>
-    <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"பூட்டுத் திரை."</string>
+    <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"லாக் ஸ்கிரீன்."</string>
     <string name="accessibility_desc_settings" msgid="3417884241751434521">"அமைப்பு"</string>
     <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"மேலோட்டப் பார்வை."</string>
-    <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"பணிப் பூட்டுத் திரை"</string>
+    <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"பணி லாக் ஸ்கிரீன்"</string>
     <string name="accessibility_desc_close" msgid="7479755364962766729">"மூடு"</string>
     <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
     <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"வைஃபை முடக்கப்பட்டது."</string>
@@ -201,7 +201,7 @@
     <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"தொந்தரவு செய்ய வேண்டாம் என்பது இயக்கப்பட்டது, முதன்மை மட்டும்."</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"தொந்தரவு செய்ய வேண்டாம் என்பது இயக்கப்பட்டது, அறிவிப்புகள் வேண்டாம்."</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"தொந்தரவு செய்ய வேண்டாம் என்பது இயக்கப்பட்டது, அலாரங்கள் மட்டும்."</string>
-    <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"தொந்தரவு செய்ய வேண்டாம்."</string>
+    <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"தொந்தரவு செய்யாதே."</string>
     <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"தொந்தரவு செய்ய வேண்டாம் என்பது முடக்கப்பட்டது."</string>
     <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"தொந்தரவு செய்ய வேண்டாம் என்பது முடக்கப்பட்டது."</string>
     <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"தொந்தரவு செய்ய வேண்டாம் என்பது இயக்கப்பட்டது."</string>
@@ -234,15 +234,15 @@
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"பணிப் பயன்முறை இயக்கப்பட்டுள்ளது."</string>
     <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"பணிப் பயன்முறை முடக்கப்பட்டது."</string>
     <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"பணிப் பயன்முறை இயக்கப்பட்டது."</string>
-    <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"தரவுச் சேமிப்பான் முடக்கப்பட்டது."</string>
-    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"தரவுச் சேமிப்பான் இயக்கப்பட்டது."</string>
+    <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"டேட்டா சேமிப்பான் முடக்கப்பட்டது."</string>
+    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"டேட்டா சேமிப்பான் இயக்கப்பட்டது."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"திரை பிரகாசம்"</string>
-    <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"சார்ஜ் ஏறுகிறது"</string>
+    <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"சார்ஜ் ஆகிறது"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G டேட்டா இடைநிறுத்தப்பட்டது"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G டேட்டா இடைநிறுத்தப்பட்டது"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"மொபைல் தரவு இடைநிறுத்தப்பட்டுள்ளது"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"மொபைல் டேட்டா இடைநிறுத்தப்பட்டுள்ளது"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"தரவு இடைநிறுத்தப்பட்டது"</string>
-    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"நீங்கள் அமைத்த தரவு வரம்பை அடைந்துவிட்டீர்கள். இப்போது மொபைல் தரவைப் பயன்படுத்தவில்லை.\n\nபயன்படுத்தத் தொடங்கினால், தரவு உபயோகத்திற்குக் கட்டணங்கள் விதிக்கப்படலாம்."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"நீங்கள் அமைத்த டேட்டா வரம்பை அடைந்துவிட்டீர்கள். இப்போது மொபைல் டேட்டாவைப் பயன்படுத்தவில்லை.\n\nமீண்டும் மொபைல் டேட்டாவைப் பயன்படுத்தத் தொடங்கினால், டேட்டா பயன்பாட்டிற்குக் கட்டணம் விதிக்கப்படலாம்."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"மீண்டும் தொடங்கு"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"இணைய இணைப்பு இல்லை"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"வைஃபை இணைக்கப்பட்டது"</string>
@@ -266,7 +266,7 @@
     <string name="dessert_case" msgid="1295161776223959221">"இனிப்பு வடிவங்கள்"</string>
     <string name="start_dreams" msgid="5640361424498338327">"ஸ்கிரீன் சேவர்"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ஈதர்நெட்"</string>
-    <string name="quick_settings_dnd_label" msgid="8735855737575028208">"தொந்தரவு செய்ய வேண்டாம்"</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_none_label" msgid="5025477807123029478">"அறிவிப்புகள் வேண்டாம்"</string>
@@ -298,7 +298,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"வைஃபையை முடக்கு"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"வைஃபை இயக்கத்தில்"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"வைஃபை நெட்வொர்க்குகள் இல்லை"</string>
-    <string name="quick_settings_cast_title" msgid="7709016546426454729">"திரையிடு"</string>
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"அனுப்புகிறது"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"பெயரிடப்படாத சாதனம்"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"திரையிடத் தயார்"</string>
@@ -310,13 +310,14 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"அமைப்பில் மாற்று"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"முடிந்தது"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"இணைக்கப்பட்டது"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"இணைக்கப்பட்டது, பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"இணைக்கிறது..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"டெதெரிங்"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ஹாட்ஸ்பாட்"</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>
+    <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"மொபைல் டேட்டா"</string>
+    <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"டேட்டா பயன்பாடு"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"மீதமுள்ள தரவு"</string>
     <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"வரம்பைக் கடந்தது"</string>
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"பயன்படுத்தியது - <xliff:g id="DATA_USED">%s</xliff:g>"</string>
@@ -345,18 +346,18 @@
   <string-array name="recents_blacklist_array">
   </string-array>
     <string name="expanded_header_battery_charged" msgid="5945855970267657951">"சார்ஜ் செய்யப்பட்டது"</string>
-    <string name="expanded_header_battery_charging" msgid="205623198487189724">"சார்ஜாகிறது"</string>
+    <string name="expanded_header_battery_charging" msgid="205623198487189724">"சார்ஜ் ஆகிறது"</string>
     <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"முழுவதும் சார்ஜாக <xliff:g id="CHARGING_TIME">%s</xliff:g> ஆகும்"</string>
     <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"சார்ஜ் ஏறவில்லை"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"பிணையம்\nகண்காணிக்கப்படலாம்"</string>
     <string name="description_target_search" msgid="3091587249776033139">"தேடு"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> க்கு மேலாக இழுக்கவும்."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> க்கு இடதுபக்கமாக இழுக்கவும்."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"அலாரங்கள், நினைவூட்டல்கள், நிகழ்வுகள் மற்றும் குறிப்பிட்ட அழைப்பாளர்களைத் தவிர்த்து, பிற ஒலிகள் மற்றும் அதிர்வுகளின் தொந்தரவு இருக்காது. எனினும், நீங்கள் எதையேனும் (இசை, வீடியோக்கள் மற்றும் கேம்கள் உட்பட) ஒலிக்கும்படி தேர்ந்தெடுத்திருந்தால், அவை வழக்கம் போல் ஒலிக்கும்."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"அலாரங்களைத் தவிர்த்து, பிற ஒலிகள் மற்றும் அதிர்வுகளின் தொந்தரவு இருக்காது. எனினும், நீங்கள் எதையேனும் (இசை, வீடியோக்கள் மற்றும் கேம்கள் உட்பட) ஒலிக்கும்படி தேர்ந்தெடுத்திருந்தால், அவை வழக்கம் போல் ஒலிக்கும்."</string>
+    <string name="zen_priority_introduction" msgid="7577965386868311310">"அலாரங்கள், நினைவூட்டல்கள், நிகழ்வுகள் மற்றும் குறிப்பிட்ட அழைப்பாளர்களைத் தவிர்த்து, பிற ஒலிகள் மற்றும் அதிர்வுகளின் தொந்தரவு இருக்காது. எனினும், நீங்கள் எதையேனும் (இசை, வீடியோக்கள் மற்றும் கேம்ஸ் உட்பட) ஒலிக்கும்படி தேர்ந்தெடுத்திருந்தால், அவை வழக்கம் போல் ஒலிக்கும்."</string>
+    <string name="zen_alarms_introduction" msgid="7034415210361973827">"அலாரங்களைத் தவிர்த்து, பிற ஒலிகள் மற்றும் அதிர்வுகளின் தொந்தரவு இருக்காது. எனினும், நீங்கள் எதையேனும் (இசை, வீடியோக்கள் மற்றும் கேம்ஸ் உட்பட) ஒலிக்கும்படி தேர்ந்தெடுத்திருந்தால், அவை வழக்கம் போல் ஒலிக்கும்."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"தனிப்பயனாக்கு"</string>
-    <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"இது அலாரங்கள், இசை, வீடியோக்கள் மற்றும் கேம்கள் உட்பட எல்லா ஒலிகளையும் அதிர்வுகளையும் தடுக்கும். இருப்பினும் நீங்கள் அழைப்புகளைச் செய்யலாம்."</string>
-    <string name="zen_silence_introduction" msgid="3137882381093271568">"இது அலாரங்கள், இசை, வீடியோக்கள் மற்றும் கேம்கள் உட்பட எல்லா ஒலிகளையும் அதிர்வுகளையும் தடுக்கும்."</string>
+    <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"இது அலாரங்கள், இசை, வீடியோக்கள் மற்றும் கேம்ஸ் உட்பட எல்லா ஒலிகளையும் அதிர்வுகளையும் தடுக்கும். இருப்பினும் நீங்கள் அழைப்புகளைச் செய்யலாம்."</string>
+    <string name="zen_silence_introduction" msgid="3137882381093271568">"இது அலாரங்கள், இசை, வீடியோக்கள் மற்றும் கேம்ஸ் உட்பட எல்லா ஒலிகளையும் அதிர்வுகளையும் தடுக்கும்."</string>
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"அவசர நிலைக் குறைவான அறிவிப்புகள் கீழே உள்ளன"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"திறக்க, மீண்டும் தட்டவும்"</string>
@@ -382,8 +383,8 @@
     <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_new_guest" msgid="600537543078847803">"அழைக்கப்பட்டவரைச் சேர்"</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_dialog_message" msgid="4155503224769676625">"இந்த அமர்வின் எல்லா பயன்பாடுகளும், தரவும் நீக்கப்படும்."</string>
@@ -392,7 +393,7 @@
     <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>
-    <string name="guest_notification_title" msgid="1585278533840603063">"கெஸ்ட்"</string>
+    <string name="guest_notification_title" msgid="1585278533840603063">"வேறொருவர்"</string>
     <string name="guest_notification_text" msgid="335747957734796689">"பயன்பாடுகளையும் தரவையும் நீக்க, விருந்தினர் பயனரை அகற்றவும்"</string>
     <string name="guest_notification_remove_action" msgid="8820670703892101990">"அழைக்கப்பட்டவரை அகற்றவா?"</string>
     <string name="user_logout_notification_title" msgid="1453960926437240727">"பயனரை வெளியேற்று"</string>
@@ -438,8 +439,8 @@
     <string name="disable_vpn" msgid="4435534311510272506">"VPNஐ முடக்கு"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"VPNஐத் துண்டி"</string>
     <string name="monitoring_button_view_policies" msgid="100913612638514424">"கொள்கைகளைக் காட்டு"</string>
-    <string name="monitoring_description_named_management" msgid="5281789135578986303">"சாதனத்தை <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> நிர்வகிக்கிறது.\n\nஉங்கள் நிர்வாகியால் அமைப்புகள், நிறுவன அணுகல், பயன்பாடுகள், உங்கள் சாதனத்துடன் தொடர்புடைய தரவு, சாதனங்களின் இருப்பிடத் தகவல் ஆகியவற்றைக் கண்காணிக்கவும் நிர்வகிக்கவும் முடியும்.\n\nமேலும் தகவலுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
-    <string name="monitoring_description_management" msgid="4573721970278370790">"சாதனத்தை உங்கள் நிறுவனம் நிர்வகிக்கிறது.\n\nஉங்கள் நிர்வாகியால் அமைப்புகள், நிறுவன அணுகல், பயன்பாடுகள், உங்கள் சாதனத்துடன் தொடர்புடைய தரவு, சாதனங்களின் இருப்பிடத் தகவல் ஆகியவற்றைக் கண்காணிக்கவும் நிர்வகிக்கவும் முடியும்.\n\nமேலும் தகவலுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
+    <string name="monitoring_description_named_management" msgid="5281789135578986303">"சாதனத்தை <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> நிர்வகிக்கிறது.\n\nஉங்கள் நிர்வாகியால் அமைப்புகள், நிறுவன அணுகல், ஆப்ஸ், உங்கள் சாதனத்துடன் தொடர்புடைய டேட்டா, சாதனங்களின் இருப்பிடத் தகவல் ஆகியவற்றைக் கண்காணிக்கவும் நிர்வகிக்கவும் முடியும்.\n\nமேலும் தகவலுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
+    <string name="monitoring_description_management" msgid="4573721970278370790">"சாதனத்தை உங்கள் நிறுவனம் நிர்வகிக்கிறது.\n\nஉங்கள் நிர்வாகியால் அமைப்புகள், நிறுவன அணுகல், ஆப்ஸ், உங்கள் சாதனத்துடன் தொடர்புடைய டேட்டா, சாதனங்களின் இருப்பிடத் தகவல் ஆகியவற்றைக் கண்காணிக்கவும் நிர்வகிக்கவும் முடியும்.\n\nமேலும் தகவலுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"உங்கள் நிறுவனம் இந்தச் சாதனத்தில் சான்றிதழ் அங்கீகாரத்தை நிறுவியுள்ளது. உங்களின் பாதுகாப்பான நெட்வொர்க் ட்ராஃபிக் கண்காணிக்கப்படலாம் அல்லது மாற்றப்படலாம்."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"உங்கள் நிறுவனம், பணி விவரத்தில் சான்றிதழ் அங்கீகாரத்தை நிறுவியுள்ளது. உங்களின் பாதுகாப்பான நெட்வொர்க் ட்ராஃபிக் கண்காணிக்கப்படலாம் அல்லது மாற்றப்படலாம்."</string>
     <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"இந்தச் சாதனத்தில் சான்றிதழ் அங்கீகாரம் நிறுவப்பட்டுள்ளது. உங்களின் பாதுகாப்பான நெட்வொர்க் ட்ராஃபிக் கண்காணிக்கப்படலாம் அல்லது மாற்றப்படலாம்."</string>
@@ -450,7 +451,7 @@
     <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் உங்களின் தனிப்பட்ட சுயவிவரம் இணைக்கப்பட்டுள்ளது."</string>
     <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"உங்கள் சாதனத்தை நிர்வகிப்பது: <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g>."</string>
     <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"உங்கள் சாதனத்தை நிர்வகிக்க, <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> பயன்பாட்டை <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> பயன்படுத்தும்."</string>
-    <string name="monitoring_description_do_body" msgid="3639594537660975895">"உங்கள் நிர்வாகியால் அமைப்புகள், நிறுவன அணுகல், பயன்பாடுகள், சாதனத்துடன் தொடர்புடைய தரவு, சாதன இருப்பிடத் தகவல் ஆகியவற்றைக் கண்காணிக்கவும் நிர்வகிக்கவும் முடியும்."</string>
+    <string name="monitoring_description_do_body" msgid="3639594537660975895">"உங்கள் நிர்வாகியால் அமைப்புகள், நிறுவன அணுகல், ஆப்ஸ், சாதனத்துடன் தொடர்புடைய டேட்டா, சாதன இருப்பிடத் தகவல் ஆகியவற்றைக் கண்காணிக்கவும் நிர்வகிக்கவும் முடியும்."</string>
     <string name="monitoring_description_do_learn_more_separator" msgid="3785251953067436862">" "</string>
     <string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"மேலும் அறிக"</string>
     <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"<xliff:g id="VPN_APP">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள். இந்தப் பயன்பாட்டால் மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்க முடியும்."</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"<xliff:g id="APPLICATION">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள். இந்தப் பயன்பாட்டால் மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் தனிப்பட்ட நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்க முடியும்."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"உங்கள் பணி விவரத்தை <xliff:g id="ORGANIZATION">%1$s</xliff:g> நிர்வகிக்கிறது. மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் பணி நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION">%2$s</xliff:g> உடன் அது இணைக்கப்பட்டுள்ளது.\n\nமேலும் தகவலுக்கு, நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"உங்கள் பணி விவரத்தை <xliff:g id="ORGANIZATION">%1$s</xliff:g> நிர்வகிக்கிறது. மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் பணி நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> உடன் அது இணைக்கப்பட்டுள்ளது.\n\nஉங்கள் தனிப்பட்ட நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> உடனும் இணைக்கப்பட்டுள்ளீர்கள்."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g>க்குத் திறக்கப்பட்டது"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> இயங்குகிறது"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"நீங்கள் கைமுறையாகத் திறக்கும் வரை, சாதனம் பூட்டப்பட்டிருக்கும்"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"விரைவாக அறிவிப்புகளைப் பெறுதல்"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"திறக்கும் முன் அவற்றைப் பார்க்கவும்"</string>
@@ -486,7 +489,7 @@
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"மறை"</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"பணி சுயவிவரத்தைப் பயன்படுத்துகிறீர்கள்"</string>
     <string name="stream_voice_call" msgid="4410002696470423714">"அழைப்பு"</string>
-    <string name="stream_system" msgid="7493299064422163147">"அமைப்பு"</string>
+    <string name="stream_system" msgid="7493299064422163147">"சிஸ்டம்"</string>
     <string name="stream_ring" msgid="8213049469184048338">"ரிங் செய்"</string>
     <string name="stream_music" msgid="9086982948697544342">"மீடியா"</string>
     <string name="stream_alarm" msgid="5209444229227197703">"அலாரம்"</string>
@@ -544,13 +547,14 @@
     <string name="do_not_silence" msgid="6878060322594892441">"ஒலியை அனுமதி"</string>
     <string name="do_not_silence_block" msgid="4070647971382232311">"ஒலி அல்லது அறிவிப்பைத் தடுக்காதே"</string>
     <string name="tuner_full_importance_settings" msgid="3207312268609236827">"ஆற்றல்மிக்க அறிவிப்புக் கட்டுப்பாடுகள்"</string>
-    <string name="tuner_full_importance_settings_on" msgid="7545060756610299966">"இயக்கத்தில்"</string>
-    <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"முடக்கத்தில்"</string>
+    <string name="tuner_full_importance_settings_on" msgid="7545060756610299966">"ஆன்"</string>
+    <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ஆஃப்"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ஆற்றல்மிக்க அறிவிப்புக் கட்டுப்பாடுகள் மூலம், பயன்பாட்டின் அறிவிப்புகளுக்கு முக்கியத்துவ நிலையை (0-5) அமைக்கலாம். \n\n"<b>"நிலை 5"</b>" \n- அறிவிப்புப் பட்டியலின் மேலே காட்டும் \n- முழுத் திரைக் குறுக்கீட்டை அனுமதிக்கும் \n- எப்போதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டும் \n\n"<b>"நிலை 4"</b>" \n- முழுத் திரைக் குறுக்கீட்டைத் தடுக்கும் \n- எப்போதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டும் \n\n"<b>"நிலை 3"</b>" \n- முழுத் திரைக் குறுக்கீட்டைத் தடுக்கும் \n- ஒருபோதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டாது \n\n"<b>"நிலை 2"</b>" \n- முழுத் திரைக் குறுக்கீட்டைத் தடுக்கும் \n- ஒருபோதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டாது \n- ஒருபோதும் ஒலி எழுப்பாது, அதிர்வுறாது \n\n"<b>"நிலை 1"</b>" \n- முழுத் திரைக் குறுக்கீட்டைத் தடுக்கும் \n- ஒருபோதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டாது \n- ஒருபோதும் ஒலி எழுப்பாது அல்லது அதிர்வுறாது \n- பூட்டுத்திரை மற்றும் நிலைப்பட்டியிலிருந்து மறைக்கும் \n- அறிவிப்புகள் பட்டியலின் கீழே காட்டும் \n\n"<b>"நிலை 0"</b>" \n- பயன்பாட்டின் எல்லா அறிவிப்புகளையும் தடுக்கும்"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"அறிவிப்புகள்"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"இந்த அறிவிப்புகளை இனி பெறமாட்டீர்கள்."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"இந்த அறிவிப்புகளை இனி பெறமாட்டீர்கள்"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> அறிவிப்பு வகைகள்"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"இந்தப் பயன்பாட்டில் அறிவிப்பு வகைகள் இல்லை"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"இந்தப் பயன்பாட்டிலிருந்து அறிவிப்புகளைப் பெறுவதை முடக்க முடியாது"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">இந்தப் பயன்பாடு வழங்கும் <xliff:g id="NUMBER_1">%d</xliff:g> அறிவிப்பு வகைகளில் ஒரு அறிவிப்பு வகை</item>
       <item quantity="one">இந்தப் பயன்பாடு வழங்கும் <xliff:g id="NUMBER_0">%d</xliff:g> அறிவிப்பு வகையில் ஒரு அறிவிப்பு வகை</item>
@@ -570,13 +574,17 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"அறிவிப்புக் கட்டுப்பாடுகள்"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"அறிவிப்பை உறக்கநிலையாக்கும் விருப்பங்கள்"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 நிமிடங்கள்"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 நிமிடங்கள்"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 மணிநேரம்"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 மணிநேரம்"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"செயல்தவிர்"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"உறக்கநிலையில் வைத்திருந்த நேரம்: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <string name="battery_panel_title" msgid="7944156115535366613">"பேட்டரி உபயோகம்"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d மணிநேரம்</item>
+      <item quantity="one">%d மணிநேரம்</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d நிமிடங்கள்</item>
+      <item quantity="one">%d நிமிடம்</item>
+    </plurals>
+    <string name="battery_panel_title" msgid="7944156115535366613">"பேட்டரி பயன்பாடு"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"சார்ஜ் செய்யும் போது பேட்டரி சேமிப்பானைப் பயன்படுத்த முடியாது"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"பேட்டரி சேமிப்பான்"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"செயல்திறனையும் பின்புலத்தில் தரவு செயலாக்கப்படுவதையும் குறைக்கும்"</string>
@@ -606,7 +614,7 @@
     <string name="keyboard_key_insert" msgid="8530501581636082614">"இன்சர்ட்"</string>
     <string name="keyboard_key_num_lock" msgid="5052537581246772117">"நம்பர் லாக்"</string>
     <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"நம்பர் பேடு <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"முறைமை"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"சிஸ்டம்"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"முகப்பு"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"சமீபத்தியவை"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"முந்தையது"</string>
@@ -623,7 +631,7 @@
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"கேலெண்டர்"</string>
     <string name="tuner_full_zen_title" msgid="4540823317772234308">"ஒலிக் கட்டுப்பாடுகளுடன் காட்டு"</string>
-    <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"தொந்தரவு செய்ய வேண்டாம்"</string>
+    <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"தொந்தரவு செய்யாதே"</string>
     <string name="volume_dnd_silent" msgid="4363882330723050727">"ஒலியளவுப் பொத்தான்களுக்கான குறுக்குவழி"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"ஒலியைக் கூட்டும் போது தொந்தரவு செய்ய வேண்டாம் என்பதை முடக்கு"</string>
     <string name="battery" msgid="7498329822413202973">"பேட்டரி"</string>
@@ -631,11 +639,11 @@
     <string name="headset" msgid="4534219457597457353">"ஹெட்செட்"</string>
     <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"ஹெட்ஃபோன்கள் இணைக்கப்பட்டன"</string>
     <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"ஹெட்செட் இணைக்கப்பட்டது"</string>
-    <string name="data_saver" msgid="5037565123367048522">"தரவுச்சேமிப்பான்"</string>
-    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"தரவு சேமிப்பான் இயக்கப்பட்டது"</string>
-    <string name="accessibility_data_saver_off" msgid="8841582529453005337">"தரவு சேமிப்பான் முடக்கப்பட்டது"</string>
-    <string name="switch_bar_on" msgid="1142437840752794229">"இயக்கு"</string>
-    <string name="switch_bar_off" msgid="8803270596930432874">"முடக்கு"</string>
+    <string name="data_saver" msgid="5037565123367048522">"டேட்டா சேமிப்பான்"</string>
+    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"டேட்டா சேமிப்பான் இயக்கப்பட்டது"</string>
+    <string name="accessibility_data_saver_off" msgid="8841582529453005337">"டேட்டா சேமிப்பான் முடக்கப்பட்டது"</string>
+    <string name="switch_bar_on" msgid="1142437840752794229">"ஆன்"</string>
+    <string name="switch_bar_off" msgid="8803270596930432874">"ஆஃப்"</string>
     <string name="nav_bar" msgid="1993221402773877607">"வழிசெலுத்தல் பட்டி"</string>
     <string name="nav_bar_layout" msgid="3664072994198772020">"தளவமைப்பு"</string>
     <string name="left_nav_bar_button_type" msgid="8555981238887546528">"கூடுதல் இடப்புறப் பொத்தான் வகை"</string>
@@ -713,7 +721,7 @@
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> அமைப்புகளைத் திற."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"அமைப்புகளின் வரிசை முறையைத் திருத்து."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"பக்கம் <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
-    <string name="tuner_lock_screen" msgid="5755818559638850294">"பூட்டுத் திரை"</string>
+    <string name="tuner_lock_screen" msgid="5755818559638850294">"லாக் ஸ்கிரீன்"</string>
     <string name="pip_phone_expand" msgid="5889780005575693909">"விரி"</string>
     <string name="pip_phone_minimize" msgid="1079119422589131792">"சிறிதாக்கு"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"மூடு"</string>
@@ -737,7 +745,7 @@
     <string name="lockscreen_unlock_right" msgid="1529992940510318775">"வலப்புறக் குறுக்குவழி மூலமாகவும் திறக்கும்"</string>
     <string name="lockscreen_none" msgid="4783896034844841821">"ஏதுமில்லை"</string>
     <string name="tuner_launch_app" msgid="1527264114781925348">"<xliff:g id="APP">%1$s</xliff:g>ஐத் துவக்கு"</string>
-    <string name="tuner_other_apps" msgid="4726596850501162493">"பிற பயன்பாடுகள்"</string>
+    <string name="tuner_other_apps" msgid="4726596850501162493">"பிற ஆப்ஸ்"</string>
     <string name="tuner_circle" msgid="2340998864056901350">"வட்டம்"</string>
     <string name="tuner_plus" msgid="6792960658533229675">"பிளஸ்"</string>
     <string name="tuner_minus" msgid="4806116839519226809">"மைனஸ்"</string>
@@ -751,9 +759,9 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"சேமிப்பிடம்"</string>
     <string name="instant_apps" msgid="6647570248119804907">"இன்ஸ்டண்ட் பயன்பாடுகள்"</string>
     <string name="instant_apps_message" msgid="8116608994995104836">"இன்ஸ்டண்ட் பயன்பாடுகளுக்கு நிறுவல் தேவையில்லை."</string>
-    <string name="app_info" msgid="6856026610594615344">"பயன்பாட்டுத் தகவல்"</string>
+    <string name="app_info" msgid="6856026610594615344">"ஆப்ஸ் தகவல்"</string>
     <string name="go_to_web" msgid="1106022723459948514">"இணையத்திற்குச் செல்"</string>
-    <string name="mobile_data" msgid="7094582042819250762">"மொபைல் தரவு"</string>
+    <string name="mobile_data" msgid="7094582042819250762">"மொபைல் டேட்டா"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"வைஃபை முடக்கத்தில் உள்ளது"</string>
     <string name="bt_is_off" msgid="2640685272289706392">"புளூடூத் முடக்கத்தில் உள்ளது"</string>
     <string name="dnd_is_off" msgid="6167780215212497572">"\"தொந்தரவு செய்ய வேண்டாம்\" முடக்கத்தில் உள்ளது"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"மாற்று"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"பின்னணியில் இயங்கும் பயன்பாடுகள்"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"பேட்டரி மற்றும் தரவு உபயோக விவரங்களைக் காண, தட்டவும்"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"மொபைல் டேட்டாவை முடக்கவா?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings_car.xml b/packages/SystemUI/res/values-ta/strings_car.xml
index 7ddd5e0..9a53db0 100644
--- a/packages/SystemUI/res/values-ta/strings_car.xml
+++ b/packages/SystemUI/res/values-ta/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"பாதுகாப்பாக வண்டியோட்டவும்"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"வாகனம் ஓட்டுவதற்கான சூழ்நிலைகளை முழுவதுமாகத் தெரிந்து வைத்திருக்கவும் மற்றும் பொருந்தும் விதிகளை எப்போதும் பின்பற்றவும். வழிகள் துல்லியமற்றதாக, முழுமையற்றதாக, ஆபத்துக்குரியதாக, பொருத்தமில்லாததாக, தடைசெய்யப்பட்டதாக அல்லது அரசின் கட்டுப்பாட்டில் உள்ள எல்லைகளைக் கடப்பதாக இருக்கலாம். வணிகத் தகவலும் துல்லியமற்றதாக அல்லது முழுமையற்றதாக இருக்கலாம். தரவு நிகழ்நேர அடிப்படையிலானது அல்ல மற்றும் இருப்பிடத் துல்லியத்திற்கு உத்தரவாதம் வழங்க முடியாது. வாகனம் ஓட்டும் போது மொபைல் சாதனத்தையோ அல்லது Android Auto மூலம் கட்டுப்படுத்த முடியாத பயன்பாடுகளையோ பயன்படுத்த வேண்டாம்."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"தெரியாதது"</string>
+    <string name="start_driving" msgid="864023351402918991">"வாகனம் ஓட்டத் தொடங்கு"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 97763d4..f87ee6f 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -22,7 +22,7 @@
     <string name="app_label" msgid="7164937344850004466">"సిస్టమ్ UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"క్లియర్ చేయండి"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"జాబితా నుండి తీసివేయండి"</string>
-    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"అనువర్తన సమాచారం"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"యాప్ సమాచారం"</string>
     <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"మీ ఇటీవలి స్క్రీన్‌లు ఇక్కడ కనిపిస్తాయి"</string>
     <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"ఇటీవలి అనువర్తనాలను తీసివేయండి"</string>
     <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
@@ -51,8 +51,8 @@
     <string name="bluetooth_tethered" msgid="7094101612161133267">"బ్లూటూత్ టీథర్ చేయబడింది"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ఇన్‌పుట్ పద్ధతులను సెటప్ చేయండి"</string>
     <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"భౌతిక కీబోర్డ్"</string>
-    <string name="usb_device_permission_prompt" msgid="834698001271562057">"USB పరికరాన్ని ప్రాప్యత చేయడానికి అనువర్తనాన్ని <xliff:g id="APPLICATION">%1$s</xliff:g> అనుమతించాలా?"</string>
-    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"USB ఉపకరణాన్ని ప్రాప్యత చేయడానికి అనువర్తనం <xliff:g id="APPLICATION">%1$s</xliff:g>ను అనుమతించాలా?"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"USB పరికరాన్ని యాక్సెస్ చేయడానికి యాప్‌ <xliff:g id="APPLICATION">%1$s</xliff:g> అనుమతించాలా?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"USB ఉపకరణాన్ని యాక్సెస్ చేయడానికి యాప్ <xliff:g id="APPLICATION">%1$s</xliff:g>ను అనుమతించాలా?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"ఈ USB పరికరం కనెక్ట్ చేయబడినప్పుడు <xliff:g id="ACTIVITY">%1$s</xliff:g>ని తెరవాలా?"</string>
     <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"ఈ USB ఉపకరణం కనెక్ట్ చేయబడినప్పుడు <xliff:g id="ACTIVITY">%1$s</xliff:g>ని తెరవాలా?"</string>
     <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"ఈ USB ఉపకరణంతో ఇన్‌స్టాల్ చేయబడిన అనువర్తనాలు ఏవీ పని చేయవు. ఈ ఉపకరణం గురించి <xliff:g id="URL">%1$s</xliff:g>లో మరింత తెలుసుకోండి"</string>
@@ -75,29 +75,29 @@
     <string name="screenshot_failed_title" msgid="705781116746922771">"స్క్రీన్‌షాట్‌ను క్యాప్చర్ చేయడం సాధ్యపడలేదు."</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"స్క్రీన్‌షాట్‌ని సేవ్ చేస్తున్నప్పుడు సమస్య సంభవించింది."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"పరిమిత నిల్వ స్థలం కారణంగా స్క్రీన్‌షాట్‌ను సేవ్ చేయడం సాధ్యపడదు."</string>
-    <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"స్క్రీన్‌షాట్‌లు తీయడానికి అనువర్తనం లేదా మీ సంస్థ అనుమతించలేదు"</string>
+    <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"స్క్రీన్‌షాట్‌లు తీయడానికి యాప్ లేదా మీ సంస్థ అనుమతించలేదు"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ఫైల్ బదిలీ ఎంపికలు"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"మీడియా ప్లేయర్‌గా (MTP) మౌంట్ చేయి"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"కెమెరాగా (PTP) మౌంట్ చేయి"</string>
-    <string name="installer_cd_button_title" msgid="2312667578562201583">"Macకు Android ఫైల్ బదిలీ అను. ఇన్‌స్టాల్ చేయండి"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Macకు Android ఫైల్ బదిలీ యాప్ ఇన్‌స్టాల్ చేయండి"</string>
     <string name="accessibility_back" msgid="567011538994429120">"వెనుకకు"</string>
     <string name="accessibility_home" msgid="8217216074895377641">"హోమ్"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"మెను"</string>
-    <string name="accessibility_accessibility_button" msgid="7601252764577607915">"ప్రాప్యత"</string>
+    <string name="accessibility_accessibility_button" msgid="7601252764577607915">"యాక్సెస్ సామర్థ్యం"</string>
     <string name="accessibility_recent" msgid="5208608566793607626">"అవలోకనం"</string>
-    <string name="accessibility_search_light" msgid="1103867596330271848">"శోధించు"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"వెతుకు"</string>
     <string name="accessibility_camera_button" msgid="8064671582820358152">"కెమెరా"</string>
     <string name="accessibility_phone_button" msgid="6738112589538563574">"ఫోన్"</string>
-    <string name="accessibility_voice_assist_button" msgid="487611083884852965">"వాయిస్ సహాయకం"</string>
+    <string name="accessibility_voice_assist_button" msgid="487611083884852965">"వాయిస్ అసిస్టెంట్"</string>
     <string name="accessibility_unlock_button" msgid="128158454631118828">"అన్‌లాక్ చేయి"</string>
     <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"వేలిముద్ర కోసం వేచి ఉంది"</string>
     <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"మీ వేలిముద్రను ఉపయోగించకుండా అన్‌లాక్ చేయండి"</string>
     <string name="unlock_label" msgid="8779712358041029439">"అన్‌లాక్ చేయి"</string>
     <string name="phone_label" msgid="2320074140205331708">"ఫోన్‌ను తెరువు"</string>
-    <string name="voice_assist_label" msgid="3956854378310019854">"వాయిస్ సహాయకం తెరువు"</string>
+    <string name="voice_assist_label" msgid="3956854378310019854">"వాయిస్ అసిస్టెంట్‌ను తెరువు"</string>
     <string name="camera_label" msgid="7261107956054836961">"కెమెరాను తెరువు"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"కొత్త విధి లేఅవుట్‌ను ఎంచుకోండి"</string>
-    <string name="cancel" msgid="6442560571259935130">"రద్దు చేయండి"</string>
+    <string name="cancel" msgid="6442560571259935130">"రద్దు చేయి"</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>
@@ -194,10 +194,10 @@
     <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"వైఫై ఆన్ చేయబడింది."</string>
     <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"మొబైల్ <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"బ్యాటరీ <xliff:g id="STATE">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"ఎయిర్‌ప్లైన్ మోడ్ ఆఫ్‌లో ఉంది."</string>
-    <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"ఎయిర్‌ప్లైన్ మోడ్ ఆన్‌లో ఉంది."</string>
-    <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"ఎయిర్‌ప్లైన్ మోడ్ ఆఫ్ చేయబడింది."</string>
-    <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"ఎయిర్‌ప్లైన్ మోడ్ ఆన్ చేయబడింది."</string>
+    <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"ఎయిర్‌ప్లేన్ మోడ్ ఆఫ్‌లో ఉంది."</string>
+    <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"ఎయిర్‌ప్లేన్ మోడ్ ఆన్‌లో ఉంది."</string>
+    <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"ఎయిర్‌ప్లేన్ మోడ్ ఆఫ్ చేయబడింది."</string>
+    <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"ఎయిర్‌ప్లేన్ మోడ్ ఆన్ చేయబడింది."</string>
     <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"అంతరాయం కలిగించవద్దు ఆన్‌లో ఉంది, ప్రాధాన్యత మాత్రమే."</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"అంతరాయం కలిగించవద్దు ఆన్‌లో ఉంది, మొత్తం నిశ్శబ్దం."</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"అంతరాయం కలిగించవద్దు ఆన్‌లో ఉంది, అలారాలు మాత్రమే."</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"మరిన్ని సెట్టింగ్‌లు"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"పూర్తయింది"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"కనెక్ట్ చేయబడినది"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"కనెక్ట్ చేయబడింది, బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"కనెక్ట్ అవుతోంది..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"టీథరింగ్"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"హాట్‌స్పాట్"</string>
@@ -331,7 +332,7 @@
     <string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"మీరు అన్నింటినీ తీసివేసారు"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"అనువర్తన సమాచారం"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"స్క్రీన్ పిన్నింగ్"</string>
-    <string name="recents_search_bar_label" msgid="8074997400187836677">"శోధించు"</string>
+    <string name="recents_search_bar_label" msgid="8074997400187836677">"వెతుకు"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ని ప్రారంభించడం సాధ్యపడలేదు."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> సురక్షిత-మోడ్‌లో నిలిపివేయబడింది."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"అన్నీ తీసివేయి"</string>
@@ -364,7 +365,7 @@
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ఈ పరికరాన్ని మీ సంస్థ నిర్వహిస్తోంది"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> నిర్వహణలో ఉంది"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ఫోన్ కోసం చిహ్నాన్ని స్వైప్ చేయండి"</string>
-    <string name="voice_hint" msgid="8939888732119726665">"వాయిస్ సహాయకం చిహ్నం నుండి స్వైప్"</string>
+    <string name="voice_hint" msgid="8939888732119726665">"వాయిస్ అసిస్టెంట్ చిహ్నం నుండి స్వైప్"</string>
     <string name="camera_hint" msgid="7939688436797157483">"కెమెరా కోసం చిహ్నాన్ని స్వైప్ చేయండి"</string>
     <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"మొత్తం నిశ్శబ్దం. దీని వలన స్క్రీన్ రీడర్‌లు కూడా నిశ్శబ్దమవుతాయి."</string>
     <string name="interruption_level_none" msgid="6000083681244492992">"మొత్తం నిశ్శబ్దం"</string>
@@ -438,8 +439,8 @@
     <string name="disable_vpn" msgid="4435534311510272506">"VPNని నిలిపివేయి"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"VPNను డిస్‌కనెక్ట్ చేయి"</string>
     <string name="monitoring_button_view_policies" msgid="100913612638514424">"విధానాలను వీక్షించండి"</string>
-    <string name="monitoring_description_named_management" msgid="5281789135578986303">"మీ పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> నిర్వహణలో ఉంది.\n\nమీ నిర్వాహకులు మీ పరికరం అనుబంధిత సెట్టింగ్‌లు, కార్పొరేట్ ప్రాప్యత, అనువర్తనాలు, డేటా మరియు మీ పరికర స్థాన సమాచారం పర్యవేక్షించగలరు మరియు నిర్వహించగలరు.\n\nమరింత సమాచారం కోసం, మీ నిర్వాహకులను సంప్రదించండి."</string>
-    <string name="monitoring_description_management" msgid="4573721970278370790">"మీ పరికరం మీ సంస్థ నిర్వహణలో ఉంది.\n\nమీ నిర్వాహకులు మీ పరికరం అనుబంధిత సెట్టింగ్‌లు, కార్పొరేట్ ప్రాప్యత, అనువర్తనాలు, డేటాను మరియు మీ పరికర స్థాన సమాచారాన్ని పర్యవేక్షించగలరు మరియు నిర్వహించగలరు.\n\nమరింత సమాచారం కోసం, మీ నిర్వాహకులను సంప్రదించండి."</string>
+    <string name="monitoring_description_named_management" msgid="5281789135578986303">"మీ పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> నిర్వహణలో ఉంది.\n\nమీ నిర్వాహకులు మీ పరికరం అనుబంధిత సెట్టింగ్‌లు, కార్పొరేట్ యాక్సెస్, యాప్‌లు, డేటా మరియు మీ పరికర స్థాన సమాచారం పర్యవేక్షించగలరు మరియు నిర్వహించగలరు.\n\nమరింత సమాచారం కోసం, మీ నిర్వాహకులను సంప్రదించండి."</string>
+    <string name="monitoring_description_management" msgid="4573721970278370790">"మీ పరికరం మీ సంస్థ నిర్వహణలో ఉంది.\n\nమీ నిర్వాహకులు మీ పరికరం అనుబంధిత సెట్టింగ్‌లు, కార్పొరేట్ యాక్సెస్, యాప్‌లు, డేటాను మరియు మీ పరికర స్థాన సమాచారాన్ని పర్యవేక్షించగలరు మరియు నిర్వహించగలరు.\n\nమరింత సమాచారం కోసం, మీ నిర్వాహకులను సంప్రదించండి."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"ఈ పరికరంలో మీ సంస్థ ఒక ప్రమాణపత్ర అధికారాన్ని ఇన్‌స్టాల్ చేసింది. మీ సురక్షిత నెట్‌వర్క్ ట్రాఫిక్ పర్యవేక్షించబడవచ్చు లేదా సవరించబడవచ్చు."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"మీ కార్యాలయ ప్రొఫైల్‌లో మీ సంస్థ ఒక ప్రమాణపత్ర అధికారాన్ని ఇన్‌స్టాల్ చేసింది. మీ సురక్షిత నెట్‌వర్క్ ట్రాఫిక్ పర్యవేక్షించబడవచ్చు లేదా సవరించబడవచ్చు."</string>
     <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"ఈ పరికరంలో ప్రమాణపత్ర అధికారం ఇన్‌స్టాల్ చేయబడింది. మీ సురక్షిత నెట్‌వర్క్ ట్రాఫిక్ పర్యవేక్షించబడవచ్చు లేదా సవరించబడవచ్చు."</string>
@@ -450,7 +451,7 @@
     <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"మీ వ్యక్తిగత ప్రొఫైల్ ఇమెయిల్‌లు, అనువర్తనాలు మరియు వెబ్‌సైట్‌లతో సహా మీ నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడింది."</string>
     <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"మీ పరికరం <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> ద్వారా నిర్వహించబడుతోంది."</string>
     <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> మీ పరికరాన్ని నిర్వహించడానికి <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g>ని ఉపయోగిస్తుంది."</string>
-    <string name="monitoring_description_do_body" msgid="3639594537660975895">"మీ పరికరంతో అనుబంధించబడిన సెట్టింగ్‌లు, కార్పొరేట్ ప్రాప్యత, అనువర్తనాలు, డేటా మరియు మీ పరికరం యొక్క స్థాన సమాచారాన్ని మీ నిర్వాహకులు పర్యవేక్షించగలరు మరియు నిర్వహించగలరు."</string>
+    <string name="monitoring_description_do_body" msgid="3639594537660975895">"మీ పరికరంతో అనుబంధించబడిన సెట్టింగ్‌లు, కార్పొరేట్ యాక్సెస్, యాప్‌లు, డేటా మరియు మీ పరికరం యొక్క స్థాన సమాచారాన్ని మీ నిర్వాహకులు పర్యవేక్షించగలరు మరియు నిర్వహించగలరు."</string>
     <string name="monitoring_description_do_learn_more_separator" msgid="3785251953067436862">" "</string>
     <string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"మరింత తెలుసుకోండి"</string>
     <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"మీరు <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు, ఇది ఇమెయిల్‌లు, అనువర్తనాలు మరియు వెబ్‌సైట్‌లతో సహా మీ వ్యక్తిగత నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
@@ -459,7 +460,7 @@
     <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
     <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"విశ్వసనీయ ఆధారాలను తెరువు"</string>
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"మీ నిర్వాహకులు మీ పరికరంలోని ట్రాఫిక్‌ని పర్యవేక్షించగల నెట్‌వర్క్ లాగింగ్‌ని ఆన్ చేసారు.\n\nమరింత సమాచారం కావాలంటే, మీ నిర్వాహకులను సంప్రదించండి."</string>
-    <string name="monitoring_description_vpn" msgid="4445150119515393526">"మీరు VPN కనెక్షన్ సెటప్ చేయడానికి ఒక అనువర్తనానికి అనుమతి ఇచ్చారు.\n\nఈ అనువర్తనం ఇమెయిల్‌లు, అనువర్తనాలు మరియు వెబ్‌సైట్‌లతో సహా మీ పరికరం మరియు నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
+    <string name="monitoring_description_vpn" msgid="4445150119515393526">"మీరు VPN కనెక్షన్ సెటప్ చేయడానికి ఒక యాప్‌నకు అనుమతి ఇచ్చారు.\n\nఈ యాప్ ఇమెయిల్‌లు,యాప్‌లు మరియు వెబ్‌సైట్‌లతో సహా మీ డివైజ్ మరియు నెట్‌వర్క్ కార్యకలాపాన్ని పర్యవేక్షించగలదు."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ద్వారా మీ కార్యాలయ ప్రొఫైల్ నిర్వహించబడుతోంది.\n\nఇమెయిల్‌లు, అనువర్తనాలు మరియు వెబ్‌సైట్‌లతో సహా మీ నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగల సామర్థ్యం మీ నిర్వాహకులకు ఉంది.\n\nమరింత సమాచారం కావాలంటే, మీ నిర్వాహకులను సంప్రదించండి.\n\nమీరు VPNకి కూడా కనెక్ట్ అయ్యారు, ఇది మీ నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
     <string name="monitoring_description_app" msgid="1828472472674709532">"మీరు ఇమెయిల్‌లు, అనువర్తనాలు మరియు వెబ్‌సైట్‌లతో సహా మీ నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు."</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"మీరు <xliff:g id="APPLICATION">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు, ఇది ఇమెయిల్‌లు, అనువర్తనాలు మరియు వెబ్‌సైట్‌లతో సహా మీ వ్యక్తిగత నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"మీ కార్యాలయ ప్రొఫైల్ <xliff:g id="ORGANIZATION">%1$s</xliff:g> నిర్వహణలో ఉంది. ఇమెయిల్‌లు, అనువర్తనాలు మరియు వెబ్‌సైట్‌లతో సహా మీ కార్యాలయ నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION">%2$s</xliff:g>కి ప్రొఫైల్ కనెక్ట్ చేయబడింది.\n\nమరింత సమాచారం కోసం, మీ నిర్వాహకులను సంప్రదించండి."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"మీ కార్యాలయ ప్రొఫైల్ <xliff:g id="ORGANIZATION">%1$s</xliff:g> నిర్వహణలో ఉంది. ఇమెయిల్‌లు, అనువర్తనాలు మరియు వెబ్‌సైట్‌లతో సహా మీ కార్యాలయ నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>కి ప్రొఫైల్ కనెక్ట్ చేయబడింది.\n\nమీ వ్యక్తిగత నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>కి కూడా మీరు కనెక్ట్ చేయబడ్డారు."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> కోసం అన్‌లాక్ చేయబడింది"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> అమలులో ఉంది"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"మీరు మాన్యువల్‌గా అన్‌లాక్ చేస్తే మినహా పరికరం లాక్ చేయబడి ఉంటుంది"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"నోటిఫికేషన్‌లను వేగంగా పొందండి"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"వీటిని మీరు అన్‌లాక్ చేయకముందే చూడండి"</string>
@@ -493,10 +496,10 @@
     <string name="stream_notification" msgid="2563720670905665031">"నోటిఫికేషన్"</string>
     <string name="stream_bluetooth_sco" msgid="2055645746402746292">"బ్లూటూత్"</string>
     <string name="stream_dtmf" msgid="2447177903892477915">"డ్యూయల్ మల్టీ టోన్ ఫ్రీక్వెన్సీ"</string>
-    <string name="stream_accessibility" msgid="301136219144385106">"ప్రాప్యత"</string>
+    <string name="stream_accessibility" msgid="301136219144385106">"యాక్సెస్ సామర్థ్యం"</string>
     <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. అన్‌మ్యూట్ చేయడానికి నొక్కండి."</string>
-    <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. వైబ్రేషన్‌కు సెట్ చేయడానికి నొక్కండి. ప్రాప్యత సేవలు మ్యూట్ చేయబడవచ్చు."</string>
-    <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. మ్యూట్ చేయడానికి నొక్కండి. ప్రాప్యత సేవలు మ్యూట్ చేయబడవచ్చు."</string>
+    <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. వైబ్రేషన్‌కు సెట్ చేయడానికి నొక్కండి. యాక్సెస్ సామర్థ్య సేవలు మ్యూట్ చేయబడవచ్చు."</string>
+    <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. మ్యూట్ చేయడానికి నొక్కండి. యాక్సెస్ సామర్థ్య సేవలు మ్యూట్ చేయబడవచ్చు."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. వైబ్రేట్ అయ్యేలా సెట్ చేయడం కోసం నొక్కండి."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. మ్యూట్ చేయడానికి నొక్కండి."</string>
     <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s వాల్యూమ్ నియంత్రణలు చూపబడ్డాయి. తీసివేయడానికి పైకి స్వైప్ చేయండి."</string>
@@ -513,11 +516,11 @@
     <string name="status_bar_ethernet" msgid="5044290963549500128">"ఈథర్‌నెట్"</string>
     <string name="status_bar_alarm" msgid="8536256753575881818">"అలారం"</string>
     <string name="status_bar_work" msgid="6022553324802866373">"కార్యాలయ ప్రొఫైల్‌"</string>
-    <string name="status_bar_airplane" msgid="7057575501472249002">"ఎయిర్‌ప్లైన్ మోడ్"</string>
+    <string name="status_bar_airplane" msgid="7057575501472249002">"ఎయిర్‌ప్లేన్ మోడ్"</string>
     <string name="add_tile" msgid="2995389510240786221">"టైల్‌ను జోడించండి"</string>
     <string name="broadcast_tile" msgid="3894036511763289383">"ప్రసార టైల్"</string>
-    <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"మీరు <xliff:g id="WHEN">%1$s</xliff:g> సెట్ చేసిన మీ తదుపరి అలారం మీరు ఆ లోపల దీన్ని ఆఫ్ చేయకుంటే వినిపించదు"</string>
-    <string name="zen_alarm_warning" msgid="444533119582244293">"మీరు <xliff:g id="WHEN">%1$s</xliff:g> సెట్ చేసిన మీ తదుపరి అలారం మీకు వినిపించదు"</string>
+    <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"మీరు <xliff:g id="WHEN">%1$s</xliff:g> సెట్ చేసిన మీ తర్వాత అలారం మీరు ఆ లోపల దీన్ని ఆఫ్ చేయకుంటే వినిపించదు"</string>
+    <string name="zen_alarm_warning" msgid="444533119582244293">"మీరు <xliff:g id="WHEN">%1$s</xliff:g> సెట్ చేసిన మీ తర్వాత అలారం మీకు వినిపించదు"</string>
     <string name="alarm_template" msgid="3980063409350522735">"<xliff:g id="WHEN">%1$s</xliff:g>కి"</string>
     <string name="alarm_template_far" msgid="4242179982586714810">"<xliff:g id="WHEN">%1$s</xliff:g>కి"</string>
     <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"శీఘ్ర సెట్టింగ్‌లు, <xliff:g id="TITLE">%s</xliff:g>."</string>
@@ -530,7 +533,7 @@
     <string name="tuner_toast" msgid="603429811084428439">"అభినందనలు! సెట్టింగ్‌లకు సిస్టమ్ UI ట్యూనర్ జోడించబడింది"</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"సెట్టింగ్‌ల నుండి తీసివేయి"</string>
     <string name="remove_from_settings_prompt" msgid="6069085993355887748">"సిస్టమ్ UI ట్యూనర్‌ను సెట్టింగ్‌ల నుండి తీసివేసి, దాని అన్ని లక్షణాలను ఉపయోగించడం ఆపివేయాలా?"</string>
-    <string name="activity_not_found" msgid="348423244327799974">"అనువర్తనం మీ పరికరంలో ఇన్‌స్టాల్ చేయలేదు"</string>
+    <string name="activity_not_found" msgid="348423244327799974">"యాప్ మీ డివైజ్‌లో ఇన్‌స్టాల్ చేయలేదు"</string>
     <string name="clock_seconds" msgid="7689554147579179507">"గడియారం సెకన్లు చూపు"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"స్థితి పట్టీలో గడియారం సెకన్లు చూపుతుంది. బ్యాటరీ శక్తి ప్రభావితం చేయవచ్చు."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"శీఘ్ర సెట్టింగ్‌ల ఏర్పాటు క్రమం మార్చు"</string>
@@ -546,14 +549,15 @@
     <string name="tuner_full_importance_settings" msgid="3207312268609236827">"పవర్ నోటిఫికేషన్ నియంత్రణలు"</string>
     <string name="tuner_full_importance_settings_on" msgid="7545060756610299966">"ఆన్‌లో ఉన్నాయి"</string>
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ఆఫ్‌లో ఉన్నాయి"</string>
-    <string name="power_notification_controls_description" msgid="4372459941671353358">"పవర్ నోటిఫికేషన్ నియంత్రణలతో, మీరు అనువర్తన నోటిఫికేషన్‌ల కోసం ప్రాముఖ్యత స్థాయిని 0 నుండి 5 వరకు సెట్ చేయవచ్చు. \n\n"<b>"స్థాయి 5"</b>" \n- నోటిఫికేషన్ జాబితా పైభాగంలో చూపబడతాయి \n- పూర్తి స్క్రీన్ అంతరాయం అనుమతించబడుతుంది \n- ఎల్లప్పుడూ త్వరిత వీక్షణ అందించబడుతుంది \n\n"<b>"స్థాయి 4"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎల్లప్పుడూ త్వరిత వీక్షణ అందించబడుతుంది \n\n"<b>"స్థాయి 3"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎప్పుడూ త్వరిత వీక్షణ అందించబడదు \n\n"<b>"స్థాయి 2"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎప్పుడూ త్వరిత వీక్షణ అందించబడదు \n- ఎప్పుడూ శబ్దం మరియు వైబ్రేషన్ చేయవు \n\n"<b>"స్థాయి 1"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎప్పుడూ త్వరిత వీక్షణ అందించబడదు \n- ఎప్పుడూ శబ్దం లేదా వైబ్రేట్ చేయవు \n- లాక్ స్క్రీన్ మరియు స్థితి పట్టీ నుండి దాచబడతాయి \n- నోటిఫికేషన్ జాబితా దిగువ భాగంలో చూపబడతాయి \n\n"<b>"స్థాయి 0"</b>" \n- అనువర్తనం నుండి అన్ని నోటిఫికేషన్‌లు బ్లాక్ చేయబడతాయి"</string>
+    <string name="power_notification_controls_description" msgid="4372459941671353358">"పవర్ నోటిఫికేషన్ నియంత్రణలతో, మీరు యాప్ నోటిఫికేషన్‌ల కోసం ప్రాముఖ్యత స్థాయిని 0 నుండి 5 వరకు సెట్ చేయవచ్చు. \n\n"<b>"స్థాయి 5"</b>" \n- నోటిఫికేషన్ జాబితా పైభాగంలో చూపబడతాయి \n- పూర్తి స్క్రీన్ అంతరాయం అనుమతించబడుతుంది \n- ఎల్లప్పుడూ త్వరిత వీక్షణ అందించబడుతుంది \n\n"<b>"స్థాయి 4"</b>\n"- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎల్లప్పుడూ త్వరిత వీక్షణ అందించబడుతుంది \n\n"<b>"స్థాయి 3"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎప్పుడూ త్వరిత వీక్షణ అందించబడదు \n\n"<b>"స్థాయి 2"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎప్పుడూ త్వరిత వీక్షణ అందించబడదు \n- ఎప్పుడూ శబ్దం మరియు వైబ్రేషన్ చేయవు \n\n"<b>"స్థాయి 1"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎప్పుడూ త్వరిత వీక్షణ అందించబడదు \n- ఎప్పుడూ శబ్దం లేదా వైబ్రేట్ చేయవు \n- లాక్ స్క్రీన్ మరియు స్థితి పట్టీ నుండి దాచబడతాయి \n- నోటిఫికేషన్ జాబితా దిగువ భాగంలో చూపబడతాయి \n\n"<b>"స్థాయి 0"</b>" \n- యాప్ నుండి అన్ని నోటిఫికేషన్‌లు బ్లాక్ చేయబడతాయి"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"నోటిఫికేషన్‌లు"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"మీరు ఇకపై ఈ నోటిఫికేషన్‌లను పొందరు."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"మీరు ఇకపై ఈ నోటిఫికేషన్‌లను పొందరు"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> నోటిఫికేషన్ వర్గాలు"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ఈ అనువర్తనానికి నోటిఫికేషన్ వర్గాలు లేవు"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"ఈ యాప్ నుండి వచ్చే నోటిఫికేషన్‌లను ఆఫ్ చేయలేరు"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
-      <item quantity="other">ఈ అనువర్తనం నుంచి <xliff:g id="NUMBER_1">%d</xliff:g> నోటిఫికేషన్ వర్గాలలో 1</item>
-      <item quantity="one">ఈ అనువర్తనం నుంచి <xliff:g id="NUMBER_0">%d</xliff:g> నోటిఫికేషన్ వర్గంలో 1</item>
+      <item quantity="other">ఈ యాప్ నుంచి <xliff:g id="NUMBER_1">%d</xliff:g> నోటిఫికేషన్ వర్గాలలో 1</item>
+      <item quantity="one">ఈ యాప్ నుంచి <xliff:g id="NUMBER_0">%d</xliff:g> నోటిఫికేషన్ వర్గంలో 1</item>
     </plurals>
     <string name="notification_channels_list_desc_2" msgid="6214732715833946441">"<xliff:g id="CHANNEL_NAME_1">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2">%2$s</xliff:g>"</string>
     <plurals name="notification_channels_list_desc_2_and_others" formatted="false" msgid="2747813553355336157">
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"నోటిఫికేషన్ నియంత్రణలు"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"నోటిఫికేషన్ తాత్కాలిక ఆపివేత ఎంపికలు"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 నిమిషాలు"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 నిమిషాలు"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 గంట"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 గంటలు"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"చర్య రద్దు చేయి"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> వరకు తాత్కాలికంగా ఆపివేయబడింది"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d గంటలు</item>
+      <item quantity="one">%d గంట</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d నిమిషాలు</item>
+      <item quantity="one">%d నిమిషం</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"బ్యాటరీ వినియోగం"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ఛార్జ్ అవుతున్న సమయంలో బ్యాటరీ సేవర్ అందుబాటులో ఉండదు"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"బ్యాటరీ సేవర్"</string>
@@ -594,7 +602,7 @@
     <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
     <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"ప్లే చేయి/పాజ్ చేయి"</string>
     <string name="keyboard_key_media_stop" msgid="2859963958595908962">"ఆపివేయి"</string>
-    <string name="keyboard_key_media_next" msgid="1894394911630345607">"తదుపరి"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"తర్వాత"</string>
     <string name="keyboard_key_media_previous" msgid="4256072387192967261">"మునుపటి"</string>
     <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"రివైండ్ చేయి"</string>
     <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"వేగంగా ఫార్వార్డ్ చేయి"</string>
@@ -624,7 +632,7 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"క్యాలెండర్"</string>
     <string name="tuner_full_zen_title" msgid="4540823317772234308">"వాల్యూమ్ నియంత్రణలతో చూపు"</string>
     <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"అంతరాయం కలిగించవద్దు"</string>
-    <string name="volume_dnd_silent" msgid="4363882330723050727">"వాల్యూమ్ బటన్‌ల సత్వరమార్గం"</string>
+    <string name="volume_dnd_silent" msgid="4363882330723050727">"వాల్యూమ్ బటన్‌ల షార్ట్‌కట్"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"వాల్యూమ్ పెంచితే అంతరాయం కలిగించవద్దు నుండి నిష్క్రమిస్తుంది"</string>
     <string name="battery" msgid="7498329822413202973">"బ్యాటరీ"</string>
     <string name="clock" msgid="7416090374234785905">"గడియారం"</string>
@@ -699,7 +707,7 @@
     <string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g>వ స్థానానికి తరలించబడింది"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"శీఘ్ర సెట్టింగ్‌ల ఎడిటర్."</string>
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> నోటిఫికేషన్: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
-    <string name="dock_forced_resizable" msgid="5914261505436217520">"స్క్రీన్ విభజనతో అనువర్తనం పని చేయకపోవచ్చు."</string>
+    <string name="dock_forced_resizable" msgid="5914261505436217520">"స్క్రీన్ విభజనతో యాప్‌ పని చేయకపోవచ్చు."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"అనువర్తనంలో స్క్రీన్ విభజనకు మద్దతు లేదు."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ప్రత్యామ్నాయ డిస్‌ప్లేలో యాప్ పని చేయకపోవచ్చు."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"ప్రత్యామ్నాయ డిస్‌ప్లేల్లో ప్రారంభానికి యాప్ మద్దతు లేదు."</string>
@@ -723,7 +731,7 @@
     <string name="pip_notification_message" msgid="4171698133469539591">"<xliff:g id="NAME">%s</xliff:g> ఈ లక్షణాన్ని ఉపయోగించకూడదు అని మీరు అనుకుంటే, సెట్టింగ్‌లను తెరవడానికి నొక్కి, దీన్ని ఆఫ్ చేయండి."</string>
     <string name="pip_play" msgid="1417176722760265888">"ప్లే చేయి"</string>
     <string name="pip_pause" msgid="8881063404466476571">"పాజ్ చేయి"</string>
-    <string name="pip_skip_to_next" msgid="1948440006726306284">"దాటవేసి తదుపరి దానికి వెళ్లు"</string>
+    <string name="pip_skip_to_next" msgid="1948440006726306284">"దాటవేసి తర్వాత దానికి వెళ్లు"</string>
     <string name="pip_skip_to_prev" msgid="1955311326688637914">"దాటవేసి మునుపటి దానికి వెళ్లు"</string>
     <string name="thermal_shutdown_title" msgid="4458304833443861111">"వేడెక్కినందుకు ఫోన్ ఆఫ్ చేయబడింది"</string>
     <string name="thermal_shutdown_message" msgid="9006456746902370523">"మీ ఫోన్ ఇప్పుడు సాధారణంగా పని చేస్తుంది"</string>
@@ -731,13 +739,13 @@
     <string name="high_temp_title" msgid="4589508026407318374">"ఫోన్ వేడెక్కుతోంది"</string>
     <string name="high_temp_notif_message" msgid="5642466103153429279">"ఫోన్‌ను చల్లబరిచే క్రమంలో కొన్ని లక్షణాలు పరిమితం చేయబడ్డాయి"</string>
     <string name="high_temp_dialog_message" msgid="6840700639374113553">"మీ ఫోన్ స్వయంచాలకంగా చల్లబడటానికి ప్రయత్నిస్తుంది. మీరు ఇప్పటికీ మీ ఫోన్‌ను ఉపయోగించవచ్చు, కానీ దాని పనితీరు నెమ్మదిగా ఉండవచ్చు.\n\nమీ ఫోన్ చల్లబడిన తర్వాత, అది సాధారణ రీతిలో పని చేస్తుంది."</string>
-    <string name="lockscreen_shortcut_left" msgid="2182769107618938629">"ఎడమవైపు సత్వరమార్గం"</string>
-    <string name="lockscreen_shortcut_right" msgid="3328683699505226536">"కుడివైపు సత్వరమార్గం"</string>
-    <string name="lockscreen_unlock_left" msgid="2043092136246951985">"ఎడమవైపు సత్వరమార్గం కూడా అన్‌లాక్ చేస్తుంది"</string>
-    <string name="lockscreen_unlock_right" msgid="1529992940510318775">"కుడివైపు సత్వరమార్గం కూడా అన్‌లాక్ చేస్తుంది"</string>
+    <string name="lockscreen_shortcut_left" msgid="2182769107618938629">"ఎడమవైపు షార్ట్‌కట్"</string>
+    <string name="lockscreen_shortcut_right" msgid="3328683699505226536">"కుడివైపు షార్ట్‌కట్"</string>
+    <string name="lockscreen_unlock_left" msgid="2043092136246951985">"ఎడమవైపు షార్ట్‌కట్ కూడా అన్‌లాక్ చేస్తుంది"</string>
+    <string name="lockscreen_unlock_right" msgid="1529992940510318775">"కుడివైపు షార్ట్‌కట్ కూడా అన్‌లాక్ చేస్తుంది"</string>
     <string name="lockscreen_none" msgid="4783896034844841821">"ఏదీ వద్దు"</string>
     <string name="tuner_launch_app" msgid="1527264114781925348">"<xliff:g id="APP">%1$s</xliff:g>ని ప్రారంభించండి"</string>
-    <string name="tuner_other_apps" msgid="4726596850501162493">"ఇతర అనువర్తనాలు"</string>
+    <string name="tuner_other_apps" msgid="4726596850501162493">"ఇతర యాప్‌లు"</string>
     <string name="tuner_circle" msgid="2340998864056901350">"సర్కిల్"</string>
     <string name="tuner_plus" msgid="6792960658533229675">"కూడిక చిహ్నం"</string>
     <string name="tuner_minus" msgid="4806116839519226809">"తీసివేత చిహ్నం"</string>
@@ -751,18 +759,19 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"నిల్వ"</string>
     <string name="instant_apps" msgid="6647570248119804907">"తక్షణ అనువర్తనాలు"</string>
     <string name="instant_apps_message" msgid="8116608994995104836">"తక్షణ అనువర్తనాలకు ఇన్‌స్టాలేషన్ అవసరం లేదు."</string>
-    <string name="app_info" msgid="6856026610594615344">"అనువర్తన సమాచారం"</string>
+    <string name="app_info" msgid="6856026610594615344">"యాప్ సమాచారం"</string>
     <string name="go_to_web" msgid="1106022723459948514">"వెబ్‌కు వెళ్లు"</string>
     <string name="mobile_data" msgid="7094582042819250762">"మొబైల్ డేటా"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ఆఫ్‌లో ఉంది"</string>
     <string name="bt_is_off" msgid="2640685272289706392">"బ్లూటూత్ ఆఫ్‌లో ఉంది"</string>
     <string name="dnd_is_off" msgid="6167780215212497572">"అంతరాయం కలిగించవద్దు ఆఫ్‌లో ఉంది"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"స్వయంచాలక నియమం (<xliff:g id="ID_1">%s</xliff:g>) ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
-    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"అనువర్తనం (<xliff:g id="ID_1">%s</xliff:g>) ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
-    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"స్వయంచాలక నియమం లేదా అనువర్తనం ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
+    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"యాప్ (<xliff:g id="ID_1">%s</xliff:g>) ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"స్వయంచాలక నియమం లేదా యాప్ ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
     <string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> వరకు"</string>
     <string name="qs_dnd_keep" msgid="1825009164681928736">"ఉంచు"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"భర్తీ చేయి"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"నేపథ్యంలో అమలు అవుతున్న ఆప్‌లు"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"బ్యాటరీ మరియు డేటా వినియోగ వివరాల కోసం నొక్కండి"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"మొబైల్ డేటాని ఆఫ్ చేయాలా?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings_car.xml b/packages/SystemUI/res/values-te/strings_car.xml
index 6f60b3a..1831422 100644
--- a/packages/SystemUI/res/values-te/strings_car.xml
+++ b/packages/SystemUI/res/values-te/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"సురక్షితంగా డ్రైవ్ చేయండి"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"డ్రైవింగ్ షరతులపై పూర్తి అవగాహనను కలిగి ఉండండి మరియు ఎల్లప్పుడూ వర్తించే చట్టాలకు అనుగుణంగా నడుచుకోండి. దిశలు నిర్దిష్టంగా ఉండకపోవచ్చు, అసంపూర్ణంగా ఉండవచ్చు, ప్రమాదకరంగా ఉండవచ్చు, అనుకూలంగా ఉండకపోవచ్చు, నిషేధించబడి ఉండవచ్చు లేదా పాలనా ప్రాంతాల మీదుగా వెళ్లే విధంగా ఉండవచ్చు. వ్యాపార సమాచారం కూడా నిర్దిష్టంగా లేదా సంపూర్ణంగా ఉండకపోవచ్చు. డేటా నిజ-సమయానికి సంబంధించినది కాదు మరియు స్థాన ఖచ్చితత్వానికి ఎలాంటి హామీ ఉండకపోవచ్చు. డ్రైవింగ్ చేస్తున్నప్పుడు మీ మొబైల్ పరికరాన్ని ఉపయోగించవద్దు లేదా Android Auto కోసం ఉద్దేశించబడని అనువర్తనాలను ఉపయోగించవద్దు."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"తెలియని"</string>
+    <string name="start_driving" msgid="864023351402918991">"డ్రైవింగ్‌ను ప్రారంభించండి"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 28957c5..28fc431 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -243,7 +243,7 @@
     <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"หยุดการใช้อินเทอร์เน็ตมือถือชั่วคราว"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"หยุดการใช้ข้อมูลชั่วคราวแล้ว"</string>
     <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"คุณใช้อินเทอร์เน็ตถึงปริมาณที่กำหนดไว้แล้ว คุณไม่ได้ใช้อินเทอร์เน็ตมือถือแล้วในขณะนี้\n\nหากใช้ต่อ อาจมีการเรียกเก็บค่าบริการอินเทอร์เน็ต"</string>
-    <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"ทำต่อ"</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"ใช้ต่อ"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"ไม่มีอินเทอร์เน็ต"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"เชื่อมต่อ WiFi แล้ว"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"กำลังค้นหา GPS"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"การตั้งค่าเพิ่มเติม"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"เสร็จสิ้น"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"เชื่อมต่อ"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"เชื่อมต่ออยู่ แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"กำลังเชื่อมต่อ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"การปล่อยสัญญาณ"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ฮอตสปอต"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"คุณเชื่อมต่อกับ <xliff:g id="APPLICATION">%1$s</xliff:g> ซึ่งสามารถตรวจสอบกิจกรรมในเครือข่ายส่วนตัวของคุณ รวมถึงอีเมล แอป และเว็บไซต์ได้"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> เป็นผู้จัดการโปรไฟล์งานของคุณ โปรไฟล์ดังกล่าวเชื่อมต่ออยู่กับ <xliff:g id="APPLICATION">%2$s</xliff:g> ซึ่งสามารถตรวจสอบกิจกรรมในเครือข่ายของคุณ รวมถึงอีเมล แอป และเว็บไซต์\n\nโปรดติดต่อผู้ดูแลระบบของคุณสำหรับข้อมูลเพิ่มเติม"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> เป็นผู้จัดการโปรไฟล์งานของคุณ โปรไฟล์ดังกล่าวเชื่อมต่ออยู่กับ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ซึ่งสามารถตรวจสอบกิจกรรมในเครือข่ายของคุณ รวมถึงอีเมล แอป และเว็บไซต์\n\nคุณยังเชื่อมต่ออยู่กับ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ด้วย ซึ่งสามารถตรวจสอบกิจกรรมในเครือข่ายส่วนตัวของคุณ"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"ปลดล็อกสำหรับ <xliff:g id="USER_NAME">%1$s</xliff:g> แล้ว"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> กำลังทำงาน"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"อุปกรณ์จะล็อกจนกว่าคุณจะปลดล็อกด้วยตนเอง"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"รับการแจ้งเตือนเร็วขึ้น"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ดูก่อนปลดล็อก"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ปิด"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ส่วนควบคุมการแจ้งเตือนแบบเปิด/ปิดช่วยให้คุณตั้งค่าระดับความสำคัญสำหรับการแจ้งเตือนของแอปได้ตั้งแต่ระดับ 0-5 \n\n"<b>"ระดับ 5"</b>" \n- แสดงที่ด้านบนของรายการแจ้งเตือน \n- อนุญาตให้รบกวนแบบเต็มหน้าจอ \n- อนุญาตให้แสดงชั่วครู่ \n\n"<b>"ระดับ 4"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- แสดงชั่วครู่เสมอ \n\n"<b>"ระดับ 3"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- ไม่แสดงชั่วครู่เลย \n\n"<b>"ระดับ 2"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- ไม่แสดงชั่วครู่เลย \n- ไม่ส่งเสียงหรือสั่นเลย \n\n"<b>"ระดับ 1"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- ไม่แสดงชั่วครู่เลย \n- ไม่ส่งเสียงหรือสั่นเลย \n- ซ่อนจากหน้าจอล็อกและแถบสถานะ \n- แสดงที่ด้านล่างของรายการแจ้งเตือน \n\n"<b>"ระดับ 0"</b>" \n- บล็อกการแจ้งเตือนทั้งหมดจากแอป"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"การแจ้งเตือน"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"คุณจะไม่ได้รับการแจ้งเตือนเหล่านี้อีก"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"คุณจะไม่ได้รับการแจ้งเตือนเหล่านี้อีก"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"หมวดหมู่การแจ้งเตือน <xliff:g id="NUMBER">%d</xliff:g> หมวด"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"แอปนี้ไม่มีหมวดหมู่การแจ้งเตือน"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"ไม่สามารถปิดการแจ้งเตือนจากแอปนี้"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">การแจ้งเตือน 1 ใน <xliff:g id="NUMBER_1">%d</xliff:g> หมวดหมู่จากแอปนี้</item>
       <item quantity="one">การแจ้งเตือน 1 ใน <xliff:g id="NUMBER_0">%d</xliff:g> หมวดหมู่จากแอปนี้</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"ส่วนควบคุมการแจ้งเตือน"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"ตัวเลือกการปิดเสียงแจ้งเตือนชั่วคราว"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 นาที"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 นาที"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ชั่วโมง"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ชั่วโมง"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"เลิกทำ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"ปิดเสียงเตือนชั่วคราวไว้เป็นเวลา <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d ชั่วโมง</item>
+      <item quantity="one">%d ชั่วโมง</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d นาที</item>
+      <item quantity="one">%d นาที</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"การใช้งานแบตเตอรี่"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ไม่สามารถใช้โหมดประหยัดแบตเตอรี่ระหว่างการชาร์จ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"โหมดประหยัดแบตเตอรี่"</string>
@@ -718,8 +726,8 @@
     <string name="pip_phone_minimize" msgid="1079119422589131792">"ย่อเล็กสุด"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"ปิด"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"ลากลงเพื่อปิด"</string>
-    <string name="pip_menu_title" msgid="3328510504196964712">"เมนูการแสดงผลหลายแหล่งพร้อมกัน"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ใช้การแสดงผลหลายแหล่งพร้อมกัน"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"เมนูการแสดงภาพซ้อนภาพ"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ใช้การแสดงภาพซ้อนภาพ"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"หากคุณไม่ต้องการให้ <xliff:g id="NAME">%s</xliff:g> ใช้ฟีเจอร์นี้ ให้แตะเพื่อเปิดการตั้งค่าแล้วปิดฟีเจอร์"</string>
     <string name="pip_play" msgid="1417176722760265888">"เล่น"</string>
     <string name="pip_pause" msgid="8881063404466476571">"หยุดชั่วคราว"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"แทนที่"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"แอปที่กำลังทำงานในเบื้องหลัง"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"แตะเพื่อดูรายละเอียดเกี่ยวกับแบตเตอรี่และปริมาณการใช้อินเทอร์เน็ต"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"ปิดอินเทอร์เน็ตมือถือไหม"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings_car.xml b/packages/SystemUI/res/values-th/strings_car.xml
index b40584a..d6cd225 100644
--- a/packages/SystemUI/res/values-th/strings_car.xml
+++ b/packages/SystemUI/res/values-th/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ขับขี่อย่างปลอดภัย"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"มีสติรู้ตัวเต็มที่ในสภาพการขับขี่ต่างๆ เและปฏิบัติตามกฎหมายที่บังคับใช้เสมอ ทั้งนี้เส้นทางอาจไม่ถูกต้อง ไม่ครบถ้วน เป็นอันตราย ไม่เหมาะสม ห้ามใช้ หรือมีการข้ามเขตปกครอง นอกจากนี้ข้อมูลทางธุรกิจอาจไม่ถูกต้องหรือไม่สมบูรณ์ ข้อมูลไม่ใช่แบบเรียลไทม์ และไม่สามารถรับประกันความถูกต้องของตำแหน่ง อย่าใช้งานอุปกรณ์เคลื่อนที่หรือใช้แอปที่ไม่ได้ออกแบบมาสำหรับ Android Auto ขณะขับรถ"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"ไม่ทราบ"</string>
+    <string name="start_driving" msgid="864023351402918991">"เริ่มขับรถ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings_tv.xml b/packages/SystemUI/res/values-th/strings_tv.xml
index 3a5eba1..5c49291 100644
--- a/packages/SystemUI/res/values-th/strings_tv.xml
+++ b/packages/SystemUI/res/values-th/strings_tv.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="notification_channel_tv_pip" msgid="134047986446577723">"การแสดงผลหลายแหล่งพร้อมกัน"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"การแสดงภาพซ้อนภาพ"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(ไม่มีชื่อรายการ)"</string>
     <string name="pip_close" msgid="3480680679023423574">"ปิด PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"เต็มหน้าจอ"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 4788a0e..8e8c6f6 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -242,7 +242,7 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Naka-pause ang 4G data"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Naka-pause ang mobile data"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Naka-pause ang data"</string>
-    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Naabot na ang itinakda mong limitasyon sa data. Hindi ka na gumagamit ng mobile data.\n\nKung magpapatuloy ka, maaaring may mga singil sa paggamit ng data."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Naabot na ang itinakda mong limitasyon ng data. Hindi ka na gumagamit ng mobile data.\n\nKung magpapatuloy ka, maaaring may mga singil sa paggamit ng data."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Ipagpatuloy"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Walang koneksyon sa Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"nakakonekta ang Wi-Fi"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Marami pang setting"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Tapos na"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Nakakonekta"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Nakakonekta, baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Kumokonekta..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Nagte-tether"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Nakakonekta ka sa <xliff:g id="APPLICATION">%1$s</xliff:g>, na maaaring sumubaybay sa aktibidad sa iyong personal na network, kabilang ang mga email, app at website."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Pinamamahalaan ng <xliff:g id="ORGANIZATION">%1$s</xliff:g> ang iyong profile sa trabaho. Nakakonekta ang profile sa <xliff:g id="APPLICATION">%2$s</xliff:g>, na maaaring sumubaybay sa aktibidad sa iyong network sa trabaho, kasama ang mga email, app, at website.\n\nPara sa higit pang impormasyon, makipag-ugnayan sa iyong admin."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Pinamamahalaan ng <xliff:g id="ORGANIZATION">%1$s</xliff:g> ang iyong profile sa trabaho. Nakakonekta ang profile sa <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, na maaaring sumubaybay sa aktibidad sa iyong network sa trabaho, kasama ang mga email, app, at website.\n\nNakakonekta ka rin sa <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, na maaaring sumubaybay sa aktibidad sa iyong personal na network."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Na-unlock para kay <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Gumagana ang <xliff:g id="TRUST_AGENT">%1$s</xliff:g>"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Mananatiling naka-lock ang device hanggang sa manu-mano mong i-unlock"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Kunin ang notification nang mas mabilis"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Tingnan ang mga ito bago ka mag-unlock"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Naka-off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Sa pamamagitan ng mga kontrol sa notification ng power, magagawa mong itakda ang antas ng kahalagahan ng mga notification ng isang app mula 0 hanggang 5. \n\n"<b>"Antas 5"</b>" \n- Ipakita sa itaas ng listahan ng notification \n- Payagan ang pag-istorbo kapag full screen \n- Palaging sumilip \n\n"<b>"Antas 4"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Palaging sumilip \n\n"<b>"Antas 3"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Huwag kailanman sumilip \n\n"<b>"Antas 2"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Huwag kailanman sumilip \n- Huwag kailanman tumunog o mag-vibrate \n\n"<b>"Antas 1"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Huwag kailanman sumilip \n- Huwag kailanman tumunog o mag-vibrate \n- Itago sa lock screen at status bar \n- Ipakita sa ibaba ng listahan ng notification \n\n"<b>"Antas 0"</b>" \n- I-block ang lahat ng notification mula sa app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Mga Notification"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Hindi mo na matatanggap ang mga notification na ito."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Hindi ka na makakatanggap ng ganitong mga notification"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> (na) kategorya ng notification"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Walang kategorya ng notification ang app na ito"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Hindi maaaring i-off ang mga notification mula sa app na ito"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 sa <xliff:g id="NUMBER_1">%d</xliff:g> kategorya ng notification mula sa app na ito</item>
       <item quantity="other">1 sa <xliff:g id="NUMBER_1">%d</xliff:g> na kategorya ng notification mula sa app na ito</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"mga kontrol ng notification"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"mga opsyon sa pag-snooze ng notification"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuto"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuto"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 oras"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 oras"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"I-UNDO"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Na-snooze ng <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d oras</item>
+      <item quantity="other">%d na oras</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d minuto</item>
+      <item quantity="other">%d na minuto</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Paggamit ng baterya"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Hindi available ang Pangtipid sa Baterya kapag nagcha-charge"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Pangtipid sa Baterya"</string>
@@ -753,7 +761,7 @@
     <string name="instant_apps_message" msgid="8116608994995104836">"Hindi kailangang i-install ang mga instant na app."</string>
     <string name="app_info" msgid="6856026610594615344">"Impormasyon ng app"</string>
     <string name="go_to_web" msgid="1106022723459948514">"Pumunta sa web"</string>
-    <string name="mobile_data" msgid="7094582042819250762">"Data ng mobile"</string>
+    <string name="mobile_data" msgid="7094582042819250762">"Mobile data"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Naka-off ang Wi-Fi"</string>
     <string name="bt_is_off" msgid="2640685272289706392">"Naka-off ang Bluetooth"</string>
     <string name="dnd_is_off" msgid="6167780215212497572">"Naka-off ang Huwag Istorbohin"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Palitan"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Tumatakbo ang mga app sa background"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"I-tap para sa mga detalye tungkol sa paggamit ng baterya at data"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"I-off ang mobile data?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings_car.xml b/packages/SystemUI/res/values-tl/strings_car.xml
index c6926ed..16442b85 100644
--- a/packages/SystemUI/res/values-tl/strings_car.xml
+++ b/packages/SystemUI/res/values-tl/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Magmaneho nang ligtas"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Manatiling lubos na nakakaalam sa mga kondisyon sa pagmamaneho at palaging sumunod sa mga naaangkop na batas. Ang mga direksyon ay maaaring hindi tumpak, hindi kumpleto, mapanganib, hindi naaangkop, ipinagbabawal o kinasasangkutan ng pagtawid sa mga administratibong lugar. Maaari ding hindi tumpak o hindi kumpleto ang impormasyon ng negosyo. Hindi real-time ang data at hindi magagarantiya ang katumpakan ng lokasyon. Huwag gamitin ang iyong mobile device o gumamit ng mga app na hindi ginawa para sa Android Auto habang nagmamaneho."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Hindi Alam"</string>
+    <string name="start_driving" msgid="864023351402918991">"Simulan ang Pagmamaneho"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 20002f6..a451b90 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Diğer ayarlar"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Bitti"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Bağlı"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Bağlandı, pil seviyesi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Bağlanılıyor..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"E-postalarınız, uygulamalarınız ve web siteleriniz dahil olmak üzere kişisel ağ etkinliğinizi izleyebilen <xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasına bağlısınız."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"İş profiliniz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tarafından yönetiliyor. Profil; e-postalar, uygulamalar ve web siteleri de dahil olmak üzere iş ağı etkinliğinizi izleyebilen <xliff:g id="APPLICATION">%2$s</xliff:g> uygulamasına bağlı.\n\nDaha fazla bilgi için yöneticinize başvurun."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"İş profiliniz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tarafından yönetiliyor. Profil; e-postalar, uygulamalar ve web siteleri de dahil olmak üzere iş ağı etkinliğinizi izleyebilen <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> uygulamasına bağlı.\n\nAyrıca, kişisel ağ etkinliğinizi izleyebilen <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> uygulamasına bağlısınız."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> için kilit açıldı"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> çalışıyor"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Cihazınızın kilidini manuel olarak açmadıkça cihaz kilitli kalacak"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Bildirimleri daha hızlı alın"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Kilidi açmadan bildirimleri görün"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Kapalı"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Güç bildirim kontrolleriyle, bir uygulamanın bildirimleri için 0 ile 5 arasında bir önem düzeyi ayarlayabilirsiniz. \n\n"<b>"5. Düzey"</b>" \n- Bildirim listesinin en üstünde gösterilsin \n- Tam ekran kesintisine izin verilsin \n- Ekranda her zaman kısaca belirsin \n\n"<b>"4. Düzey"</b>" \n- Tam ekran kesintisi engellensin \n- Ekranda her zaman kısaca belirsin \n\n"<b>"3. Düzey"</b>" \n- Tam ekran kesintisi engellensin \n- Ekranda hiçbir zaman kısaca belirmesin \n\n"<b>"2. Düzey"</b>" \n- Tam ekran kesintisi engellensin \n- Ekranda hiçbir zaman belirmesin \n- Hiçbir zaman ses çıkarmasın ve titreştirmesin \n\n"<b>"1. Düzey"</b>" \n- Tam ekran kesintisi engellensin \n- Ekranda hiçbir zaman kısaca belirmesin \n- Hiçbir zaman ses çıkarmasın veya titreştirmesin \n- Kilit ekranından ve durum çubuğundan gizlensin \n- Bildirim listesinin en altında gösterilsin \n\n"<b>"0. Düzey"</b>" \n- Uygulamadan gelen tüm bildirimler engellensin"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Bildirimler"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Bu bildirimleri artık almayacaksınız."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Bu bildirimleri artık almayacaksınız"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> bildirim kategorisi"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Bu uygulamanın bildirim kategorisi yok"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Bu uygulamanın bildirimleri kapatılamaz"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Bu uygulamadaki <xliff:g id="NUMBER_1">%d</xliff:g> bildirim kategorisinden 1 tanesi</item>
       <item quantity="one">Bu uygulamadaki <xliff:g id="NUMBER_0">%d</xliff:g> bildirim kategorisinden 1 tanesi</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"Bildirim kontrolleri"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"bildirim erteleme seçenekleri"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 dakika"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 dakika"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 saat"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 saat"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"GERİ AL"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> süreyle ertelendi"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d saat</item>
+      <item quantity="one">%d saat</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d dakika</item>
+      <item quantity="one">%d dakika</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Pil kullanımı"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Şarj sırasında Pil Tasarrufu özelliği kullanılamaz"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Pil Tasarrufu"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Değiştir"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Arka planda çalışan uygulamalar"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Pil ve veri kullanımı ile ilgili ayrıntılar için dokunun"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Mobil veri kapatılsın mı?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings_car.xml b/packages/SystemUI/res/values-tr/strings_car.xml
index 72018e2..126789f 100644
--- a/packages/SystemUI/res/values-tr/strings_car.xml
+++ b/packages/SystemUI/res/values-tr/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Güvenli bir şekilde sürün"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Sürüş koşullarına karşı dikkatli olun ve geçerli yasalara her zaman uyun. Yol tarifi yanlış, eksik, tehlikeli, uygunsuz, yasak olabilir veya idari bölgelerden geçişleri içerebilir. İşletme bilgileri de yanlış veya eksik olabilir. Veriler gerçek zamanlı değildir ve konum doğruluğu garanti edilemez. Sürüş sırasında mobil cihazınızı veya Android Auto için geliştirilmemiş uygulamaları kullanmayın."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Bilinmiyor"</string>
+    <string name="start_driving" msgid="864023351402918991">"Sürmeye Başla"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 51005c1..140fcca 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -246,7 +246,7 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Передавання даних 4G призупинено"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Мобільне передавання даних призупинено"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Передавання даних призупинено"</string>
-    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Досягнуто вказаного обмеження обсягу даних. Мобільне передавання даних вимкнено.\n\nЯкщо ввімкнути його, може стягуватися плата за використання трафіку."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Досягнуто ліміту мобільного трафіку. Ви його більше не витрачаєте.\n\nЯкщо ви продовжите, може стягуватися плата за використання трафіку."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Відновити"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Немає з’єднання"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi під’єднано"</string>
@@ -316,6 +316,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Більше налаштувань"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Готово"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Під’єднано"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Під’єдано, заряд акумулятора: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"З’єднання…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Режим модема"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Точка доступу"</string>
@@ -473,6 +474,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Ваш профіль під’єднано до додатка <xliff:g id="APPLICATION">%1$s</xliff:g>, який може відстежувати вашу особисту активність у мережі, зокрема доступ до електронної пошти, додатків і веб-сайтів."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Вашим робочим профілем керує адміністратор організації <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Цей профіль під’єднано до додатка <xliff:g id="APPLICATION">%2$s</xliff:g>, який може відстежувати вашу активність у мережі, зокрема в електронній пошті, додатках і на веб-сайтах.\n\nЩоб дізнатися більше, зв’яжіться з адміністратором."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Вашим робочим профілем керує адміністратор організації <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Цей профіль під’єднано до додатка <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, який може відстежувати вашу активність у мережі, зокрема а електронній пошті, додатках і на веб-сайтах.\n\nВаш профіль також під’єднано до додатка <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, який може відстежувати вашу особисту активність у мережі."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Розблоковано для користувача <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> працює"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Пристрій залишатиметься заблокованим, доки ви не розблокуєте його вручну"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Швидше отримуйте сповіщення"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Переглядайте сповіщення, перш ніж розблокувати екран"</string>
@@ -554,9 +557,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Вимк."</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"За допомогою елементів керування сповіщеннями ви можете налаштувати пріоритет сповіщень додатка – від 0 до 5 рівня. \n\n"<b>"Рівень 5"</b>\n"- Показувати сповіщення вгорі списку \n- Виводити на весь екран \n- Завжди показувати короткі сповіщення \n\n"<b>"Рівень 4"</b>\n"- Не виводити на весь екран \n- Завжди показувати короткі сповіщення \n\n"<b>"Рівень 3"</b>\n"- Не виводити на весь екран \n- Не показувати короткі сповіщення \n\n"<b>"Рівень 2"</b>\n"- Не виводити на весь екран \n- Не показувати короткі сповіщення \n- Вимкнути звук і вібросигнал \n\n"<b>"Рівень 1"</b>\n"- Не виводити на весь екран \n- Не показувати короткі сповіщення \n- Вимкнути звук і вібросигнал \n- Не показувати на заблокованому екрані та в рядку стану \n- Показувати сповіщення внизу списку \n\n"<b>"Рівень 0"</b>\n"- Блокувати всі сповіщення з додатка"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Сповіщення"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ви більше не отримуватимете ці сповіщення."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ви більше не отримуватимете ці сповіщення"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Категорії сповіщень (<xliff:g id="NUMBER">%d</xliff:g>)"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"У цьому додатку немає категорій сповіщень"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Сповіщення з цього додатка не можна вимкнути"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 з <xliff:g id="NUMBER_1">%d</xliff:g> категорії сповіщень із цього додатка</item>
       <item quantity="few">1 з <xliff:g id="NUMBER_1">%d</xliff:g> категорій сповіщень із цього додатка</item>
@@ -580,12 +584,20 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"елементи керування сповіщеннями"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"параметри відкладення сповіщень"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 хвилин"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 хвилин"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 годину"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 години"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ВІДМІНИТИ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Відкладено на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d година</item>
+      <item quantity="few">%d години</item>
+      <item quantity="many">%d годин</item>
+      <item quantity="other">%d години</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d хвилина</item>
+      <item quantity="few">%d хвилини</item>
+      <item quantity="many">%d хвилин</item>
+      <item quantity="other">%d хвилини</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Використання заряду"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режим енергозбереження не можна ввімкнути під час заряджання"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим енергозбереження"</string>
@@ -775,4 +787,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Замінити"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Додатки, які працюють у фоновому режимі"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Торкніться, щоб перевірити використання акумулятора й трафік"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Вимкнути мобільний трафік?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings_car.xml b/packages/SystemUI/res/values-uk/strings_car.xml
index 4fda0ab..852e1c6 100644
--- a/packages/SystemUI/res/values-uk/strings_car.xml
+++ b/packages/SystemUI/res/values-uk/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Будьте уважні за кермом"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Стежте умовами дорожнього руху та завжди дотримуйтеся відповідних законів. Маршрути можуть бути неточними, неповними, небезпечними, непридатними або перетинати межі адміністративних одиниць. Інформація про компанії також може бути неточною або неповною. Дані надаються не в реальному часі. Точність визначення місцезнаходжень не гарантується. Коли ви за кермом, не користуйтеся мобільним пристроєм або додатками, не призначеними для Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Невідомо"</string>
+    <string name="start_driving" msgid="864023351402918991">"Почати рух"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 23a0626..0415f87 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -155,7 +155,7 @@
     <string name="accessibility_cell_data" msgid="5326139158682385073">"موبائل ڈیٹا"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"موبائل ڈیٹا آن ہے"</string>
     <string name="accessibility_cell_data_off" msgid="443267573897409704">"موبائل ڈیٹا آف ہے"</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"بلوٹوتھ ٹیتھرنگ۔"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"بلوٹوتھ ٹیدرنگ۔"</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"ہوائی جہاز وضع۔"</string>
     <string name="accessibility_vpn_on" msgid="5993385083262856059">"‏VPN آن ہے۔"</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"‏کوئی SIM کارڈ نہیں ہے۔"</string>
@@ -310,8 +310,9 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"مزید ترتیبات"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"ہو گیا"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"مربوط"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"منسلک ہے، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"مربوط ہو رہا ہے…"</string>
-    <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ٹیتھرنگ"</string>
+    <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ٹیدرنگ"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ہاٹ اسپاٹ"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"اطلاعات"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"فلیش لائٹ"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"آپ <xliff:g id="APPLICATION">%1$s</xliff:g> سے منسلک ہیں، جو ای میلز، ایپس اور ویب سائٹس سمیت آپ کے نجی نیٹ ورک کی سرگرمی مانیٹر کر سکتی ہے۔"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"آپ کا دفتری پروفائل <xliff:g id="ORGANIZATION">%1$s</xliff:g> کے زیر انتظام ہے۔ پروفائل <xliff:g id="APPLICATION">%2$s</xliff:g> سے منسلک ہے جو ای میلز، ایپس اور ویب سائٹس سمیت آپ کے دفتری نیٹ ورک کی سرگرمی مانیٹر کر سکتی ہے۔\n\nمزید معلومات کیلئے اپنے منتظم سے رابطہ کریں۔"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"آپ کا دفتری پروفائل <xliff:g id="ORGANIZATION">%1$s</xliff:g> کے زیر انتظام ہے۔ پروفائل <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> سے منسلک ہے جو ای میلز، ایپس اور ویب سائٹس سمیت آپ کے دفتری نیٹ ورک کی سرگرمی مانیٹر کر سکتی ہے۔\n\nآپ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> سے بھی منسلک ہیں، جو آپ کے ذاتی نیٹ ورک کی سرگرمی مانیٹر کر سکتی ہے۔"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> کے لیے غیر مقفل کر دیا گیا"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> چل رہا ہے"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"آلہ اس وقت تک مقفل رہے گا جب تک آپ دستی طور پر اسے غیر مقفل نہ کریں"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"تیزی سے اطلاعات حاصل کریں"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"غیر مقفل کرنے سے پہلے انہیں دیکھیں"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"آف"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"پاور اطلاع کنٹرولز کے ساتھ آپ کسی ایپ کی اطلاعات کیلئے 0 سے 5 تک اہمیت کی سطح سیٹ کر سکتے ہیں۔ \n\n"<b>"سطح 5"</b>\n"- اطلاعات کی فہرست کے اوپر دکھائیں \n- پوری اسکرین کی مداخلت کی اجازت دیں \n- ہمیشہ جھانکنا\n\n"<b>"سطح 4"</b>\n"- پوری اسکرین کی مداخلت کو روکیں \n- ہمیشہ جھانکنا\n\n"<b>"سطح 3"</b>\n"- پوری اسکرین کی مداخلت کو روکیں \n- کبھی نہ جھانکنا \n\n"<b>"سطح 2"</b>\n"- پوری اسکرین کی مداخلت کو روکیں \n- کبھی نہ جھانکنا \n- کبھی آواز اور ارتعاش پیدا نہ کرنا \n\n"<b>" سطح 1"</b>\n"- پوری اسکرین کی مداخلت کو روکنا \n- کبھی نہ جھانکنا \n- کبھی بھی آواز یا ارتعاش پیدا نہ کرنا\n- مقفل اسکرین اور اسٹیٹس بار سے چھپانا \n - اطلاع کی فہرست کی نیچے دکھانا \n\n"<b>"سطح 0"</b>\n"- ایپ سے تمام اطلاعات مسدود کریں"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"اطلاعات"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"آپ کو یہ اطلاعات مزید نہیں ملیں گی۔"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"آپ کو یہ اطلاعات مزید نہیں ملیں گی"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"اطلاع کے <xliff:g id="NUMBER">%d</xliff:g> زمرے"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"اس ایپ میں اطلاعاتی زمرے نہیں ہیں"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"اس ایپ کی اطلاعات کو آف نہیں کیا جا سکتا"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">اس ایپ کے <xliff:g id="NUMBER_1">%d</xliff:g> اطلاعاتی زمروں میں سے 1</item>
       <item quantity="one">اس ایپ کے <xliff:g id="NUMBER_0">%d</xliff:g> اطلاعاتی زمرے میں سے 1</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"اطلاع کے کنٹرولز"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"اطلاع اسنوز کرنے کے اختیارات"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 منٹ"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 منٹ"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 گھنٹہ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 گھنٹے"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"کالعدم کریں"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> کیلئے اسنوز کیا گیا"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">‏‎%d گھنٹے</item>
+      <item quantity="one">‏‎%d گھنٹہ</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">‏‎%d منٹ</item>
+      <item quantity="one">‏‎%d منٹ</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"بیٹری کا استعمال"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"چارجنگ کے دوران بیٹری سیور دستیاب نہیں ہے"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"بیٹری سیور"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"بدلیں"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"ایپس پس منظر میں چل رہی ہیں"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"بیٹری اور ڈیٹا استعمال کے بارے میں تفصیلات کے لیے تھپتھپائیں"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"موبائل ڈیٹا آف کریں؟"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings_car.xml b/packages/SystemUI/res/values-ur/strings_car.xml
index 151ca09..653a59b 100644
--- a/packages/SystemUI/res/values-ur/strings_car.xml
+++ b/packages/SystemUI/res/values-ur/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"احتیاط سے گاڑی چلائیں"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"‏گاڑی چلاتے وقت اپنے گردونواح سے مکمل طور پر باخبر رہیں اور ہمیشہ قابل اطلاق قوانین کی پابندی کریں۔ ہدایات غلط، نامکمل، خطرناک، موزوں نہیں، ممنوع یا انتظامی علاقوں میں سے گزرنے کے متعلق ہو سکتی ہیں۔ کاروباری معلومات بھی غلط یا نامکمل ہو سکتی ہے۔ گاڑی چلاتے وقت اپنا موبائل آلہ یا وہ ایپس استعمال نہ کریں جو Android Auto کیلئے نہیں ہیں۔"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"نامعلوم"</string>
+    <string name="start_driving" msgid="864023351402918991">"ڈرائیونگ شروع کریں"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index a60dc07..383faa4 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -44,7 +44,7 @@
     <string name="battery_saver_start_action" msgid="5576697451677486320">"Quvvat tejash funksiyasini yoqing"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Sozlamalar"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
-    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Ekranni avtomatik burish"</string>
+    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Ekranning avtomatik burilishi"</string>
     <string name="status_bar_settings_mute_label" msgid="554682549917429396">"MUTE"</string>
     <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"Eslatmalar"</string>
@@ -242,7 +242,7 @@
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Quvvat olmoqda"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G internet to‘xtatib qo‘yildi"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G internet to‘xtatib qo‘yildi"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Mobil internet pauza qilingan"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Mobil internet pauza qilindi"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Internetdan foydalanish to‘xtatib qo‘yildi"</string>
     <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Belgilangan trafik sarflab bo‘lindi. Endi mobil internetdan foydalana olmaysiz.\n\nDavom ettiradigan bo‘lsangiz, trafik uchun to‘lov olinishi mumkin."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Davom etish"</string>
@@ -278,7 +278,7 @@
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"Ulangan qurilmalar topilmadi"</string>
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Yorqinlik"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Avtomatik burilish"</string>
-    <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"Ekranni avtomatik burish"</string>
+    <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"Ekranning avtomatik burilishi"</string>
     <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"<xliff:g id="ID_1">%s</xliff:g> rejimi"</string>
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Aylanmaydigan qilingan"</string>
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Tik holat"</string>
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Boshqa sozlamalar"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Tayyor"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Ulangan"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Ulangan, batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Ulanmoqda…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Modem rejimi"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -382,10 +383,10 @@
     <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Foydalanuvchini o‘zgartirish. Joriy foydalanuvchi – <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Joriy foydalanuvchi <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Profilni ko‘rsatish"</string>
-    <string name="user_add_user" msgid="5110251524486079492">"Foydalanuvchi qo‘shish"</string>
+    <string name="user_add_user" msgid="5110251524486079492">"Foydalanuvchi"</string>
     <string name="user_new_user_name" msgid="426540612051178753">"Yangi foydalanuvchi"</string>
     <string name="guest_nickname" msgid="8059989128963789678">"Mehmon"</string>
-    <string name="guest_new_guest" msgid="600537543078847803">"Mehmon qo‘shish"</string>
+    <string name="guest_new_guest" msgid="600537543078847803">"Mehmon"</string>
     <string name="guest_exit_guest" msgid="7187359342030096885">"Mehmon rejimini o‘chirish"</string>
     <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"Mehmon hisobi o‘chirib tashlansinmi?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Ushbu seansdagi barcha ilovalar va ma’lumotlar o‘chirib tashlanadi."</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"<xliff:g id="APPLICATION">%1$s</xliff:g> ilovasi ishga tushirilgan. U internetdagi harakatlaringiz, jumladan, e-pochta, ilova va veb-saytlardagi xatti-harakatlaringizni kuzatishi mumkin."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Ishchi profilingiz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tomonidan boshqariladi. <xliff:g id="APPLICATION">%2$s</xliff:g> ilovasi ish tarmog‘idagi, jumladan, e-pochta, ilova va veb-saytlardagi xatti-harakatlaringizni kuzatishi mumkin.\n\nBatafsil axborot olish uchun administrator bilan bog‘laning."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Ishchi profilingiz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tomonidan boshqariladi. <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ilovasi ish tarmog‘idagi, jumladan, e-pochta, ilova va veb-saytlardagi xatti-harakatlaringizni kuzatishi mumkin.\n\nShuningdek, <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ilovasi ham shaxsiy tarmoqdagi harakatlaringizni kuzatishi mumkin."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> uchun qulfdan chiqarilgan"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ishlamoqda"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Qurilma qo‘lda qulfdan chiqarilmaguncha qulflangan holatda qoladi"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Bildirishnomalarni tezroq oling"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Ularni qulfdan chiqarishdan oldin ko‘ring"</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"O‘chiq"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Bildirishnomalar uchun kengaytirilgan boshqaruv yordamida ilova bildirishnomalarining muhimlik darajasini (0-5) sozlash mumkin. \n\n"<b>"5-daraja"</b>" \n- Bildirishnomani ro‘yxatning boshida ko‘rsatish \n- To‘liq ekranli bildirishnomalarni ko‘rsatish \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatish \n\n"<b>"4-daraja"</b>" \n- To‘liq ekranli bildirishnomalarni ko‘rsatmaslik \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatish \n\n"<b>"3-daraja"</b>" \n- To‘liq ekranli bildirishnomalarni ko‘rsatmaslik \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatmaslik \n\n"<b>"2-daraja"</b>" \n- To‘liq ekranli bildirishnomalarni ko‘rsatmaslik \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatmaslik \n- Ovoz va tebranishdan foydalanmaslik \n\n"<b>"1-daraja"</b>" \n- To‘liq ekranli bildirishnomalarni ko‘rsatmaslik \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatmaslik \n- Ovoz va tebranishdan foydalanmaslik \n- Ekran qulfi va holat qatorida ko‘rsatmaslik \n- Bildirishnomani ro‘yxatning oxirida ko‘rsatish \n\n"<b>"0-daraja"</b>" \n- Ilovadan keladigan barcha bildirishnomalarni bloklash"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Bildirishnomalar"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ushbu bildirishnomalar endi ko‘rsatilmaydi."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ushbu bildirishnomalar endi ko‘rsatilmaydi"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ta bildirishnoma turkumi"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Bu ilovada bildirishnomalar turkumi yo‘q"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Bu ilova bildirishnomalarini o‘chirib bo‘lmaydi"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Bu ilovadagi <xliff:g id="NUMBER_1">%d</xliff:g> ta bildirishnomalar turkumidan 1 tasi</item>
       <item quantity="one">Bu ilovadagi <xliff:g id="NUMBER_0">%d</xliff:g> ta bildirishnomalar turkumidan 1 tasi</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"bildirishnoma sozlamalari"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"bildirishnomalarni kechiktirish parametrlari"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 daqiqa"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 daqiqa"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 soat"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 soat"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"BEKOR QILISH"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> muddatga kechiktirildi"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d soat</item>
+      <item quantity="one">%d soat</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d daqiqa</item>
+      <item quantity="one">%d daqiqa</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Batareya sarfi"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Quvvat tejash rejimidan quvvatlash vaqtida foydalanib bo‘lmaydi"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Quvvat tejash rejimi"</string>
@@ -665,7 +673,7 @@
     <string name="right_keycode" msgid="708447961000848163">"O‘ngga tugmasi kodi"</string>
     <string name="left_icon" msgid="3096287125959387541">"Chapga belgisi"</string>
     <string name="right_icon" msgid="3952104823293824311">"O‘ngga belgisi"</string>
-    <string name="drag_to_add_tiles" msgid="7058945779098711293">"Kerakli elementni tortib qo‘shing"</string>
+    <string name="drag_to_add_tiles" msgid="7058945779098711293">"Keraklisini tepaga torting"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"O‘chirish uchun bu yerga torting"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Tahrirlash"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Vaqt"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Almashtirish"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Fonda ishlayotgan ilovalar"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Batareya va trafik sarfi tafsilotlari uchun ustiga bosing"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Mobil internet o‘chirib qo‘yilsinmi?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings_car.xml b/packages/SystemUI/res/values-uz/strings_car.xml
index 610dc1f..29951be 100644
--- a/packages/SystemUI/res/values-uz/strings_car.xml
+++ b/packages/SystemUI/res/values-uz/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Xavfsiz haydash"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Harakat xavfsizligi va amaldagi qonunchilikka doim rioya qiling. Yo‘l ko‘rsatmalari noaniq, chala, xavfli, mos emas, taqiqlangan yoki ma’muriy hududlarni kesib o‘tadigan bo‘lishi mumkin. Biznes ma’lumotlari ham noaniq yoki chala bo‘lishi mumkin. Ma’lumotlar real vaqt rejimida bo‘lmasligi hamda joylashuv ma’lumotining aniqligi kafolatlanmaydi. Avtomobilni haydash mobaynida Android Auto xizmati bilan bog‘liq bo‘lmagan hollarda mobil qurilma yoki ilovalardan foydalanmang."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Noma’lum"</string>
+    <string name="start_driving" msgid="864023351402918991">"Navigatsiyani boshlash"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 29c70c6..5cce979 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -240,9 +240,9 @@
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Đang sạc"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Đã tạm dừng dữ liệu 2G-3G"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Đã tạm dừng dữ liệu 4G"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Dữ liệu di động bị tạm dừng"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Dữ liệu di động đã bị tạm dừng"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Đã tạm dừng dữ liệu"</string>
-    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Đã đạt đến giới hạn dữ liệu mà bạn đặt. Bạn hiện không còn sử dụng dữ liệu di động.\n\nNếu tiếp tục, bạn có thể phải trả phí sử dụng dữ liệu."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Dữ liệu đã đạt đến mức giới hạn mà bạn đã đặt. Bạn hiện không sử dụng dữ liệu di động nữa.\n\nNếu tiếp tục, bạn có thể bị tính phí sử dụng dữ liệu."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Tiếp tục"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ko có k.nối Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Đã kết nối Wi-Fi"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Cài đặt khác"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Xong"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Đã kết nối"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Đã kết nối, mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Đang kết nối..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Đang dùng làm điểm truy cập Internet"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Điểm phát sóng"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Bạn đang kết nối với <xliff:g id="APPLICATION">%1$s</xliff:g>. Ứng dụng này có thể giám sát hoạt động mạng cá nhân của bạn bao gồm email, ứng dụng và trang web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Hồ sơ công việc của bạn do <xliff:g id="ORGANIZATION">%1$s</xliff:g> quản lý. Hồ sơ này được kết nối với <xliff:g id="APPLICATION">%2$s</xliff:g>, ứng dụng này có thể giám sát hoạt động mạng cơ quan của bạn, bao gồm email, ứng dụng và trang web.\n\nĐể biết thêm thông tin, hãy liên hệ với quản trị viên của bạn."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Hồ sơ công việc của bạn do <xliff:g id="ORGANIZATION">%1$s</xliff:g> quản lý. Hồ sơ này được kết nối với <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, ứng dụng này có thể giám sát hoạt động mạng của bạn, bao gồm email, ứng dụng và trang web.\n\nBạn cũng đang kết nối với <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, ứng dụng này có thể giám sát hoạt động mạng cá nhân của bạn."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Được mở khóa cho <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> đang chạy"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Thiết bị sẽ vẫn bị khóa cho tới khi bạn mở khóa theo cách thủ công"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Nhận thông báo nhanh hơn"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Xem thông báo trước khi bạn mở khóa"</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Tắt"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Với các kiểm soát thông báo nguồn, bạn có thể đặt cấp độ quan trọng từ 0 đến 5 cho các thông báo của ứng dụng. \n\n"<b>"Cấp 5"</b>" \n- Hiển thị ở đầu danh sách thông báo \n- Cho phép gián đoạn ở chế độ toàn màn hình \n- Luôn xem nhanh \n\n"<b>"Cấp 4"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Luôn xem nhanh \n\n"<b>"Cấp 3"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n\n"<b>"Cấp 2"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n- Không bao giờ có âm báo và rung \n\n"<b>"Cấp 1"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n- Không bao giờ có âm báo và rung \n- Ẩn khỏi màn hình khóa và thanh trạng thái \n- Hiển thị ở cuối danh sách thông báo \n\n"<b>"Cấp 0"</b>" \n- Chặn tất cả các thông báo từ ứng dụng"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Thông báo"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Bạn sẽ không nhận được những thông báo này nữa."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Bạn sẽ không nhận được những thông báo này nữa"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> danh mục thông báo"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ứng dụng này không có loại thông báo"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Không thể tắt thông báo từ ứng dụng này"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 trên tổng số <xliff:g id="NUMBER_1">%d</xliff:g> loại thông báo từ ứng dụng này</item>
       <item quantity="one">1 trên tổng số <xliff:g id="NUMBER_0">%d</xliff:g> loại thông báo từ ứng dụng này</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"điều khiển thông báo"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"Tùy chọn báo lại thông báo"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 phút"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 phút"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 giờ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 giờ"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"HOÀN TÁC"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Báo lại sau <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d giờ</item>
+      <item quantity="one">%d giờ</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d phút</item>
+      <item quantity="one">%d phút</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Mức sử dụng pin"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Trình tiết kiệm pin không khả dụng trong khi sạc"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Trình tiết kiệm pin"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Thay thế"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Ứng dụng đang chạy trong nền"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Nhấn để biết chi tiết về mức sử dụng dữ liệu và pin"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Tắt dữ liệu di động?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings_car.xml b/packages/SystemUI/res/values-vi/strings_car.xml
index 2aee7d5..fb47969 100644
--- a/packages/SystemUI/res/values-vi/strings_car.xml
+++ b/packages/SystemUI/res/values-vi/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Lái xe an toàn"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Luôn biết rõ điều kiện lái xe và luôn tuân thủ luật pháp hiện hành. Chỉ đường có thể không chính xác, không hoàn chỉnh, nguy hiểm, không thích hợp, bị cấm hoặc bao gồm tuyến đường giao các khu vực hành chính. Thông tin doanh nghiệp cũng có thể không chính xác hoặc không hoàn chỉnh. Dữ liệu không ở thời gian thực và không thể đảm bảo độ chính xác của vị trí. Không sử dụng thiết bị di động của bạn hoặc sử dụng ứng dụng không dành cho Android Auto trong khi lái xe."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Không xác định"</string>
+    <string name="start_driving" msgid="864023351402918991">"Bắt đầu lái xe"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 9152dcb..75dd3d7 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -240,9 +240,9 @@
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"正在充电"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G 数据网络已暂停使用"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G 数据网络已暂停使用"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"移动数据已暂停使用"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"已暂停使用移动数据网络"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"数据网络已暂停使用"</string>
-    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"您的数据用量已达到所设置的用量上限,因此系统已停用移动数据。\n\n如果您要继续使用移动数据,则可能需要支付相应的数据流量费用。"</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"您的数据流量消耗已达到所设置的上限,因此已停用移动数据网络。\n\n如果您要继续使用移动数据网络,则可能需要支付相应的流量费用。"</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"恢复"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"未连接互联网"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"已连接到WLAN网络"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"更多设置"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"完成"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"已连接"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"已连接,电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"正在连接…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"网络共享"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"热点"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"您已连接到<xliff:g id="APPLICATION">%1$s</xliff:g>,该应用可以监控您的个人网络活动,包括收发电子邮件、使用应用和浏览网站。"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"您的工作资料由“<xliff:g id="ORGANIZATION">%1$s</xliff:g>”负责管理,且已连接到“<xliff:g id="APPLICATION">%2$s</xliff:g>”(该应用能够监控您的工作网络活动,其中包括收发电子邮件、使用应用和浏览网站)。\n\n如需更多信息,请与您的管理员联系。"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"您的工作资料由“<xliff:g id="ORGANIZATION">%1$s</xliff:g>”负责管理,且已连接到“<xliff:g id="APPLICATION_WORK">%2$s</xliff:g>”(该应用能够监控您的工作网络活动,其中包括收发电子邮件、使用应用和浏览网站)。\n\n此外,您还连接到了“<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>”(该应用能够监控您的个人网络活动)。"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"已为<xliff:g id="USER_NAME">%1$s</xliff:g>解锁"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"“<xliff:g id="TRUST_AGENT">%1$s</xliff:g>”正在运行"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"在您手动解锁之前,设备会保持锁定状态"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"更快捷地查看通知"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"无需解锁即可查看通知"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"关闭"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"利用高级通知设置,您可以为应用通知设置从 0 级到 5 级的重要程度等级。\n\n"<b>"5 级"</b>" \n- 在通知列表顶部显示 \n- 允许全屏打扰 \n- 一律短暂显示通知 \n\n"<b>"4 级"</b>" \n- 禁止全屏打扰 \n- 一律短暂显示通知 \n\n"<b>"3 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n\n"<b>"2 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n- 一律不发出声音或振动 \n\n"<b>"1 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n- 一律不发出声音或振动 \n- 不在锁定屏幕和状态栏中显示 \n- 在通知列表底部显示 \n\n"<b>"0 级"</b>" \n- 屏蔽应用的所有通知"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"您将不会再收到这类通知。"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"您将不会再收到这类通知"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> 个通知类别"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"此应用没有通知类别"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"无法关闭来自此应用的通知"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">此应用指定的 1 个通知类别(共 <xliff:g id="NUMBER_1">%d</xliff:g> 个)</item>
       <item quantity="one">此应用指定的 1 个通知类别(共 <xliff:g id="NUMBER_0">%d</xliff:g> 个)</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g><xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"通知设置"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"通知延后选项"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 分钟"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 分钟"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 小时"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 小时"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"撤消"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"已延后 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d 小时</item>
+      <item quantity="one">%d 小时</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d 分钟</item>
+      <item quantity="one">%d 分钟</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"电池使用情况"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充电过程中无法使用省电模式"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"省电模式"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"替换"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"在后台运行的应用"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"点按即可详细了解电量和流量消耗情况"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"要关闭移动数据网络吗?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings_car.xml b/packages/SystemUI/res/values-zh-rCN/strings_car.xml
index 6a5a4e8..27dd755 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings_car.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"安全驾驶"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"请充分了解驾驶条件并务必遵守适用的法律。路线指示可能不准确,不完整,也可能包含危险、不适合通行、禁止通行或跨越行政区域的路段。商家信息也可能不准确或不完整。数据并非实时提供,因此无法保证位置信息的精确度。请勿在驾驶过程中操作您的移动设备或使用不支持 Android Auto 的应用。"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"未知"</string>
+    <string name="start_driving" msgid="864023351402918991">"开始驾驶"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index cab3aea..beffd22 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -312,6 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"更多設定"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"完成"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"已連線"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"已連線,電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"正在連線…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"網絡共享"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"熱點"</string>
@@ -469,6 +470,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"您已連接至「<xliff:g id="APPLICATION">%1$s</xliff:g>」,此應用程式可以監控您的個人網絡活動,包括電郵、應用程式及網站。"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"您的工作設定檔由<xliff:g id="ORGANIZATION">%1$s</xliff:g>管理。設定檔已連結至「<xliff:g id="APPLICATION">%2$s</xliff:g>」,此應用程式可以監控您的工作網絡活動,包括電郵、應用程式和網站。\n\n如需瞭解詳情,請聯絡您的管理員。"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"您的工作設定檔由<xliff:g id="ORGANIZATION">%1$s</xliff:g>管理。設定檔已連結至「<xliff:g id="APPLICATION_WORK">%2$s</xliff:g>」,此應用程式可以監控您的工作網絡活動,包括電郵、應用程式和網站。\n\n您亦已連結至「<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>」,此應用程式可以監控您的個人網絡活動。"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"已為<xliff:g id="USER_NAME">%1$s</xliff:g>解鎖"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> 執行中"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"裝置將保持上鎖,直到您手動解鎖"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"更快取得通知"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"解鎖前顯示"</string>
@@ -550,9 +553,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"關閉"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"通知控制項讓您設定應用程式通知的重要性 (0 至 5 級)。\n\n"<b>"第 5 級"</b>" \n- 在通知清單頂部顯示 \n- 允許全螢幕騷擾 \n- 一律顯示通知 \n\n"<b>"第 4 級"</b>" \n- 阻止全螢幕騷擾 \n- 一律顯示通知 \n\n"<b>"第 3 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n\n"<b>"第 2 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n- 永不發出聲響和震動 \n\n"<b>"第 1 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n- 永不發出聲響和震動 \n- 從上鎖畫面和狀態列中隱藏 \n- 在通知清單底部顯示 \n\n"<b>"第 0 級"</b>" \n- 封鎖所有應用程式通知"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"您不會再收到這些通知。"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"您不會再收到這些通知"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> 個通知類別"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"此應用程式沒有通知類別"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"無法關閉此應用程式的通知"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">此應用程式的 1 個通知類別 (共 <xliff:g id="NUMBER_1">%d</xliff:g> 個)</item>
       <item quantity="one">此應用程式的 1 個通知類別 (共 <xliff:g id="NUMBER_0">%d</xliff:g> 個)</item>
@@ -572,12 +576,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"通知控制項"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"通知延後選項"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 分鐘"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 分鐘"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 小時"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 小時"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"復原"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"已延後 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d 個小時</item>
+      <item quantity="one">%d 個小時</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d 分鐘</item>
+      <item quantity="one">%d 分鐘</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"電池用量"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電時無法使用「省電模式」"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"省電模式"</string>
@@ -767,4 +775,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"取代"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"正在背景中執行的應用程式"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"輕按即可查看電池和數據用量詳情"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"要關閉流動數據嗎?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings_car.xml b/packages/SystemUI/res/values-zh-rHK/strings_car.xml
index 18f9e50..01f3b14 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings_car.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"請安全駕駛"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"請隨時留意路面情況,並遵守適用的交通規則。系統提供的路線可能不準確、不完整、存在危險、不適合、禁止通行,或涉及跨越行政區域的路段。此外,商家資訊也可能不準確或不完整。路況資料並非即時更新,也無法保證定位資訊的準確性。駕駛時請勿操作流動裝置,或使用不適用於 Android Auto 的應用程式。"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"不明"</string>
+    <string name="start_driving" msgid="864023351402918991">"開始駕駛"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 9526426..bfbea152 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -73,7 +73,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"已拍攝螢幕擷取畫面。"</string>
     <string name="screenshot_saved_text" msgid="2685605830386712477">"輕觸即可查看螢幕擷圖。"</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"無法拍攝螢幕擷取畫面。"</string>
-    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"儲存螢幕擷圖時發生問題。"</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"儲存螢幕擷取畫面時發生問題。"</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"由於儲存空間有限,因此無法儲存螢幕擷取畫面。"</string>
     <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"這個應用程式或貴機構不允許擷取螢幕畫面"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB 檔案傳輸選項"</string>
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"更多設定"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"完成"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"已連線"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"已連線,電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"連線中..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"網路共用"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"無線基地台"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"由於你已連結至「<xliff:g id="APPLICATION">%1$s</xliff:g>」,你的個人網路活動 (包括收發電子郵件、使用應用程式及瀏覽網站) 可能會受到這個應用程式監控。"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"你的 Work 設定檔是由「<xliff:g id="ORGANIZATION">%1$s</xliff:g>」所管理。由於該設定檔已連結至「<xliff:g id="APPLICATION">%2$s</xliff:g>」,因此你的網路活動 (包括收發電子郵件、使用應用程式和瀏覽網站) 可能會受到這個應用程式監控。\n\n如要瞭解詳情,請與你的管理員聯絡。"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"你的 Work 設定檔是由「<xliff:g id="ORGANIZATION">%1$s</xliff:g>」所管理。由於該設定檔已連結至「<xliff:g id="APPLICATION_WORK">%2$s</xliff:g>」,因此你的網路活動 (包括收發電子郵件、使用應用程式和瀏覽網站) 可能會受到這個應用程式監控。\n\n此外,你還與「<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>」建立了連結,因此你的個人網路活動也可能會受到該應用程式監控。"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"已為<xliff:g id="USER_NAME">%1$s</xliff:g>解鎖"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"「<xliff:g id="TRUST_AGENT">%1$s</xliff:g>」執行中"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"在你手動解鎖前,裝置將保持鎖定狀態"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"更快取得通知"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"解鎖前顯示"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"關閉"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"只要使用電源通知控制項,你就能為應用程式通知設定從 0 到 5 的重要性等級。\n\n"<b>"等級 5"</b>" \n- 顯示在通知清單頂端 \n- 允許全螢幕通知 \n- 一律允許短暫顯示通知 \n\n"<b>"等級 4"</b>" \n- 禁止全螢幕通知 \n- 一律允許短暫顯示通知 \n\n"<b>"等級 3"</b>" \n- 禁止全螢幕通知 \n- 一律不允許短暫顯示通知 \n\n"<b>"等級 2"</b>" \n- 禁止全螢幕通知 \n- 一律不允許短暫顯示通知 \n- 一律不發出音效或震動 \n\n"<b>"等級 1"</b>" \n- 禁止全螢幕通知 \n- 一律不允許短暫顯示通知 \n- 一律不發出音效或震動 \n- 在鎖定畫面和狀態列中隱藏 \n- 顯示在通知清單底端 \n\n"<b>"等級 0"</b>" \n- 封鎖應用程式的所有通知"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"你不會再收到這類通知。"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"你不會再收到這類通知"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> 個通知類別"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"這個應用程式沒有通知類別"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"無法關閉這個應用程式發出的通知"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">在 <xliff:g id="NUMBER_1">%d</xliff:g> 個通知類別中,有 1 個類別是來自這個應用程式</item>
       <item quantity="one">在 <xliff:g id="NUMBER_0">%d</xliff:g> 個通知類別中,有 1 個類別是來自這個應用程式</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"通知控制項"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"通知延後選項"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 分鐘"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 分鐘"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 小時"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 小時"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"復原"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"已延後 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="other">%d 小時</item>
+      <item quantity="one">%d 小時</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="other">%d 分鐘</item>
+      <item quantity="one">%d 分鐘</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"電池用量"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電時無法使用節約耗電量模式"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"節約耗電量"</string>
@@ -608,7 +616,7 @@
     <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"數字鍵 <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"系統"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string>
-    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"近期活動"</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_shortcuts_helper" msgid="4892255911160332762">"鍵盤快速鍵"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"取代"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"在背景執行的應用程式"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"輕觸即可查看電池和數據用量詳情"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"要關閉行動數據嗎?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings_car.xml b/packages/SystemUI/res/values-zh-rTW/strings_car.xml
index e420fe7..01f3b14 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings_car.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"安全駕駛"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"請隨時注意周遭路況並遵守交通規則。系統所提供的路線可能有誤、不完整,或包含危險、不合適、禁止通行或管制區域的路段;此外,商家資訊也可能有誤或不完整。路況資料並非即時更新,也無法保證定位資訊必然準確無誤。駕駛時請勿操作你的行動裝置,或使用不適用於 Android Auto 的應用程式。"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"不明"</string>
+    <string name="start_driving" msgid="864023351402918991">"開始駕駛"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 80ce905..bd54208 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -310,6 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Izilungiselelo eziningi"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Kwenziwe"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Ixhunyiwe"</string>
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Kuxhunyiwe, ibhethri elingu-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Iyaxhuma..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Ukusebenzisa njengemodemu"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"I-Hotspot"</string>
@@ -467,6 +468,8 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Uxhumeke ku-<xliff:g id="APPLICATION">%1$s</xliff:g>, engaqapha umsebenzi wakho womuntu siqu wenethiwekhi, ofaka ama-imeyili, izinhlelo zokusebenza, namawebhusayithi."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Iphrofayela yakho yomsebenzi iphethwe i-<xliff:g id="ORGANIZATION">%1$s</xliff:g>. Iphrofayela ixhumeke ku-<xliff:g id="APPLICATION">%2$s</xliff:g>, engaqapha umsebenzi wenethiwekhi yakho yokusebenza, ofaka ama-imeyili, izinhlelo zokusebenza, namawebhusayithi.\n\nUkuze uthole olunye ulwazi, xhumana nomlawuli wakho."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Iphrofayela yakho yomsebenzi iphethwe i-<xliff:g id="ORGANIZATION">%1$s</xliff:g>. Iphrofayela ixhumeke ku-<xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, engaqapha umsebenzi wakho wenethiwekhi, ofaka ama-imeyili, izinhlelo zokusebenza, namawebhusayithi.\n\nFuthi uxhumeke ku-<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, engaqapha umsebenzi wakho siqu wenethiwekhi."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Kuvulelwe u-<xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> iyasebenza"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Idivayisi izohlala ikhiyekile uze uyivule ngokwenza"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Thola izaziso ngokushesha"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Ibone ngaphambi kokuthi uyivule"</string>
@@ -548,9 +551,10 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Valiwe"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Ngezilawuli zesaziso zamandla, ungasetha ileveli ebalulekile kusuka ku-0 kuya ku-5 kusuka kuzaziso zohlelo lokusebenza. \n\n"<b>"Ileveli 5"</b>" \n- Ibonisa phezulu kuhlu lwesaziso \n- Vumela ukuphazamiseka kwesikrini esigcwele \n- Ukuhlola njalo \n\n"<b>"Ileveli 4"</b>" \n- Gwema ukuphazamiseka kwesikrini esigcwele \n- Ukuhlola njalo \n\n"<b>"Ileveli 3"</b>" \n- Gwema ukuphazamiseka kwesikrini esigcwele \n- Ukungahloli \n\n"<b>"Ileveli 2"</b>" \n- Gwema ukuphazamiseka kwesikrini esigcwele \n- Ukungahloli \n- Ungenzi umsindo nokudlidliza \n\n"<b>"Ileveli 1"</b>" \n- Gwema ukuphazamiseka kwesikrini esigcwele \n- Ukungahloli \n- Ungenzi umsindo noma ukudlidliza \n- Fihla kusuka kusikrini sokukhiya nebha yesimo \n- Bonisa phansi kohlu lwesaziso \n\n"<b>"Ileveli 0"</b>" \n- Vimbela zonke izaziso kusuka kuhlelo lokusebenza"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Izaziso"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ngeke usathola lezi zaziso."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ngeke usathola izaziso"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> izigaba zesaziso"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Lolu hlelo lokusebenza alunazo izigaba zesaziso"</string>
+    <string name="notification_unblockable_desc" msgid="3561016061737896906">"Izaziso kusuka kulolu hlelo lokusebenza azikwazi ukuvalwa"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 isigaba kwezingu-<xliff:g id="NUMBER_1">%d</xliff:g> sezaziso kusukela kulolu hlelo lokusebenza</item>
       <item quantity="other">1 isigaba kwezingu-<xliff:g id="NUMBER_1">%d</xliff:g> sezaziso kusukela kulolu hlelo lokusebenza</item>
@@ -570,12 +574,16 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"izilawuli zesaziso"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"izinketho zokusnuza zesaziso"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 amaminithi"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 amaminithi"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ihora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 amahora"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"HLEHLISA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Kusnuzwe u-<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+      <item quantity="one">%d amahora</item>
+      <item quantity="other">%d amahora</item>
+    </plurals>
+    <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+      <item quantity="one">%d amaminithi</item>
+      <item quantity="other">%d amaminithi</item>
+    </plurals>
     <string name="battery_panel_title" msgid="7944156115535366613">"Ukusetshenziswa kwebhethri"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Isilondolozi sebhethri asitholakali ngesikhathi sokushaja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Isilondolozi sebhethri"</string>
@@ -765,4 +773,5 @@
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Buyisela"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Izinhlelo zokusebenza zisebenza ngasemuva"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Thepha ngemininingwane ekusetshenzisweni kwebhethri nedatha"</string>
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vala idatha yeselula?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings_car.xml b/packages/SystemUI/res/values-zu/strings_car.xml
index 83301ac..3eddfd4 100644
--- a/packages/SystemUI/res/values-zu/strings_car.xml
+++ b/packages/SystemUI/res/values-zu/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Shayela ngokuqophelela"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Hlala wazi ngokugcwele izimo zokushayela uphinde uthobele yonke imithetho esebenzayo. Izikhombisi-ndlela kungenzeka azilungile, aziphelele, ziyingozi, azifanelekile, zivinjiwe, noma zifaka ukweqa izindawo zokulawula. Ulwazi lwebhizinisi kungenzeka lungalungi noma lungapheleli. Idatha akuyona isikhathi sangempela, futhi ukunemba kwendawo akukwazi ukuqinisekiswa. Ungaphathi idivayisi yakho yeselula noma usebenzise izinhlelo zokusebenza ezihloselwe i-Android Auto ngenkathi ushayela."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Akwaziwa"</string>
+    <string name="start_driving" msgid="864023351402918991">"Qala ukushayela"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 06b945d..745d6015 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -124,12 +124,10 @@
     <declare-styleable name="PluginInflateContainer">
         <attr name="viewType" format="string" />
     </declare-styleable>
-    <declare-styleable name="ScrimView">
-        <!-- The initial color for the scrim. -->
-        <attr name="scrimColor" format="color" />
-    </declare-styleable>
 
     <attr name="lightIconTheme" format="reference" />
     <attr name="darkIconTheme" format="reference" />
+    <attr name="wallpaperTextColor" format="reference|color" />
+    <attr name="wallpaperTextColorSecondary" format="reference|color" />
 </resources>
 
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 83a0b7b..f72f379 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -32,7 +32,6 @@
     <color name="qs_detail_button">@*android:color/quaternary_device_default_settings</color>
     <color name="qs_detail_button_white">#B3FFFFFF</color><!-- 70% white -->
     <color name="qs_detail_transition">#66FFFFFF</color>
-    <color name="scrim_behind_color">@android:color/black</color>
     <color name="status_bar_clock_color">#FFFFFFFF</color>
     <color name="qs_user_detail_icon_muted">#FFFFFFFF</color> <!-- not so muted after all -->
     <color name="qs_tile_disabled_color">#9E9E9E</color> <!-- 38% black -->
@@ -78,6 +77,9 @@
     <!-- The color of the material notification background when low priority -->
     <color name="notification_material_background_low_priority_color">#fff5f5f5</color>
 
+    <!-- The color of the dividing line between grouped notifications. -->
+    <color name="notification_divider_color">#FF616161</color>
+
     <!-- The background color of the notification shade -->
     <color name="notification_shade_background_color">#ffeeeeee</color>
 
@@ -144,4 +146,6 @@
 
     <color name="instant_apps_color">#ff4d5a64</color>
 
+    <color name="zen_introduction">#ffffffff</color>
+
 </resources>
diff --git a/packages/SystemUI/res/values/colors_car.xml b/packages/SystemUI/res/values/colors_car.xml
new file mode 100644
index 0000000..4faf252
--- /dev/null
+++ b/packages/SystemUI/res/values/colors_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources>
+    <color name="car_user_switcher_progress_bgcolor">#00000000</color> <!-- Transparent -->
+    <color name="car_user_switcher_progress_fgcolor">#80CBC4</color> <!-- Teal 200 -->
+    <color name="car_start_driving_background">#FAFAFA</color> <!-- Grey 50 -->
+    <color name="car_start_driving_text">#212121</color> <!-- Grey 900 -->
+</resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index fd7e165..a077fdb 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -210,9 +210,12 @@
     <!-- Set to true to enable the user switcher on the keyguard. -->
     <bool name="config_keyguardUserSwitcher">false</bool>
 
-    <!-- Doze: does this device support STATE_DOZE and STATE_DOZE_SUSPEND?  -->
+    <!-- Doze: does this device support STATE_DOZE?  -->
     <bool name="doze_display_state_supported">false</bool>
 
+    <!-- Doze: does this device support STATE_DOZE_SUSPEND?  -->
+    <bool name="doze_suspend_display_state_supported">false</bool>
+
     <!-- Doze: should the significant motion sensor be used as a pulse signal? -->
     <bool name="doze_pulse_on_significant_motion">false</bool>
 
@@ -244,6 +247,11 @@
     -->
     <string name="doze_pickup_subtype_performs_proximity_check"></string>
 
+    <!-- Type of a sensor that provides a low-power estimate of the desired display
+         brightness, suitable to listen to while the device is asleep (e.g. during
+         always-on display) -->
+    <string name="doze_brightness_sensor_type" translatable="false"></string>
+
     <!-- Doze: pulse parameter - how long does it take to fade in? -->
     <integer name="doze_pulse_duration_in">900</integer>
 
@@ -259,6 +267,31 @@
     <!-- Doze: alpha to apply to small icons when dozing -->
     <integer name="doze_small_icon_alpha">222</integer><!-- 87% of 0xff -->
 
+    <!-- Doze: Table that translates sensor values from the doze_brightness_sensor_type sensor
+               to brightness values; -1 means keeping the current brightness. -->
+    <integer-array name="config_doze_brightness_sensor_to_brightness">
+        <item>-1</item> <!-- 0: OFF -->
+        <item>2</item> <!-- 1: NIGHT -->
+        <item>5</item> <!-- 2: LOW -->
+        <item>27</item> <!-- 3: HIGH -->
+        <item>28</item> <!-- 4: SUN -->
+    </integer-array>
+
+    <!-- Doze: Table that translates sensor values from the doze_brightness_sensor_type sensor
+               to an opacity value for a black scrim that is overlayed in AOD1.
+               Valid range is from 0 (transparent) to 255 (opaque).
+               -1 means keeping the current opacity. -->
+    <integer-array name="config_doze_brightness_sensor_to_scrim_opacity">
+        <item>-1</item> <!-- 0: OFF -->
+        <item>0</item> <!-- 1: NIGHT -->
+        <item>0</item> <!-- 2: LOW -->
+        <item>0</item> <!-- 3: HIGH -->
+        <item>0</item> <!-- 4: SUN -->
+    </integer-array>
+
+    <!-- Doze: whether the double tap sensor reports 2D touch coordinates -->
+    <bool name="doze_double_tap_reports_touch_coordinates">false</bool>
+
     <!-- Hotspot tile: number of days to show after feature is used. -->
     <integer name="days_to_show_hotspot_tile">30</integer>
 
@@ -287,7 +320,7 @@
     <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIFactory</string>
 
     <!-- Nav bar button default ordering/layout -->
-    <string name="config_navBarLayout" translatable="false">left,back;home;recent,right</string>
+    <string name="config_navBarLayout" translatable="false">left[.5W],back[1WC];home;recent[1WC],right[.5W]</string>
 
     <bool name="quick_settings_show_full_alarm">false</bool>
 
@@ -295,9 +328,13 @@
     <integer name="config_showTemperatureWarning">0</integer>
 
     <!-- Temp at which to show a warning notification if config_showTemperatureWarning is true.
-         If < 0, uses the value from HardwarePropertiesManager#getDeviceTemperatures. -->
+         If < 0, uses the value from
+         HardwarePropertiesManager#getDeviceTemperatures - config_warningTemperatureTolerance. -->
     <integer name="config_warningTemperature">-1</integer>
 
+    <!-- Fudge factor for how much below the shutdown temp to show the warning. -->
+    <integer name="config_warningTemperatureTolerance">2</integer>
+
     <!-- Accessibility actions -->
     <item type="id" name="action_split_task_to_left" />
     <item type="id" name="action_split_task_to_right" />
@@ -336,4 +373,64 @@
     <!-- Whether to show activity indicators in the status bar -->
     <bool name="config_showActivity">false</bool>
 
+    <!-- Whether or not the button to clear all notifications will be shown. -->
+    <bool name="config_enableNotificationsClearAll">true</bool>
+
+    <!-- Whether or not to show the notification shelf that houses the icons of notifications that
+     have been scrolled off-screen. -->
+    <bool name="config_showNotificationShelf">true</bool>
+
+    <!-- Whether or not the notifications should always fade as they are dismissed. -->
+    <bool name="config_fadeNotificationsOnDismiss">false</bool>
+
+    <!-- Whether or not the parent of the notification row itself is being translated when swiped or
+         its children views. If true, then the contents are translated and vice versa. -->
+    <bool name="config_translateNotificationContentsOnSwipe">true</bool>
+
+    <!-- Whether or not the fade on the notification is based on the amount that it has been swiped
+         off-screen. -->
+    <bool name="config_fadeDependingOnAmountSwiped">false</bool>
+
+    <!-- Whether or not to show the expand button at the end of the notification header. -->
+    <bool name="config_showNotificationExpandButtonAtEnd">false</bool>
+
+    <!-- Whether or the notifications should be clipped to be reduced in height if it has been
+         scrolled to the top of the screen. -->
+    <bool name="config_clipNotificationScrollToTop">true</bool>
+
+    <!-- Whether or not the notification contents should be clipped to any background that is
+         set on the notification container. For example, if this value is true and the background
+         has rounded corners, then the contents will be clipped to those corners. -->
+    <bool name="config_clipNotificationsToOutline">false</bool>
+
+    <!-- Whether or not notifications that can be expanded will always be in their expanded state.
+         This value only affects notifications that are not a group of notifications from the same
+         applications. If this value is false, then only the first notification will be expanded;
+         the other notifications need to be manually expanded by the user. -->
+    <bool name="config_alwaysExpandNonGroupedNotifications">false</bool>
+
+    <!-- Whether or not an expandable notification can be manually expanded or collapsed by the
+         user. Grouped notifications are still expandable even if this value is false. -->
+    <bool name="config_enableNonGroupedNotificationExpand">true</bool>
+
+    <!-- Whether or not there should be dividing lines between child notifications when the
+         group has been expanded. -->
+    <bool name="config_showDividersWhenGroupNotificationExpanded">false</bool>
+
+    <!-- Whether or not the dividing lines should be shown when the container is expanding and
+         collapsing. If this value is true, then the lines will only show when the container has
+         been completely expanded. -->
+    <bool name="config_hideDividersDuringExpand">false</bool>
+
+    <!-- Whether or not child notifications that are part of a group will have shadows. -->
+    <bool name="config_enableShadowOnChildNotifications">true</bool>
+
+    <!-- Whether or not a view containing child notifications will have a custom background when
+         it has been expanded to reveal its children. -->
+    <bool name="config_showGroupNotificationBgWhenExpanded">false</bool>
+
+    <!-- Whether to artificially interpret all signal strengths as
+         one bar higher than they actually are -->
+    <bool name="config_inflateSignalStrength">false</bool>
+
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f66a09e..94687de 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -101,6 +101,9 @@
     <!-- Height of a the shelf with the notification icons -->
     <dimen name="notification_shelf_height">32dp</dimen>
 
+    <!-- Minimum height of a notification to be interactable -->
+    <dimen name="notification_min_interaction_height">40dp</dimen>
+
     <!-- the padding of the shelf icon container -->
     <dimen name="shelf_icon_container_padding">13dp</dimen>
 
@@ -204,8 +207,18 @@
     <!-- Width for the notification panel and related windows -->
     <dimen name="match_parent">-1px</dimen>
     <dimen name="standard_notification_panel_width">416dp</dimen>
+
+    <!-- The top margin of the panel that holds the list of notifications. -->
+    <dimen name="notification_panel_margin_top">0dp</dimen>
+
+    <!-- The bottom margin of the panel that holds the list of notifications. -->
+    <dimen name="notification_panel_margin_bottom">0dp</dimen>
+
     <dimen name="notification_panel_width">@dimen/match_parent</dimen>
 
+    <!-- The width of the panel that holds the quick settings. -->
+    <dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
+
     <dimen name="volume_dialog_panel_width">@dimen/standard_notification_panel_width</dimen>
 
     <!-- Gravity for the notification panel -->
@@ -323,6 +336,22 @@
     <!-- The height of the divider between the individual notifications. -->
     <dimen name="notification_divider_height">0.5dp</dimen>
 
+    <!-- The corner radius of the shadow behind the notification. -->
+    <dimen name="notification_shadow_radius">0dp</dimen>
+
+    <!-- The alpha of the dividing line between child notifications of a notification group. -->
+    <item name="notification_divider_alpha" format="float" type="dimen">0.5</item>
+
+    <!-- The height of the divider between the individual notifications in a notification
+         group. -->
+    <dimen name="notification_children_container_divider_height">@dimen/notification_divider_height</dimen>
+
+    <!-- The height of the header for a container containing child notifications. -->
+    <dimen name="notification_children_container_header_height">53dp</dimen>
+
+    <!-- The top margin for the notification children container in its non-expanded form. -->
+    <dimen name="notification_children_container_margin_top">@*android:dimen/notification_content_margin_top</dimen>
+
     <!-- The height of a notification header -->
     <dimen name="notification_header_height">53dp</dimen>
 
@@ -755,6 +784,9 @@
     <!-- The shortest-edge size of the expanded PiP. -->
     <dimen name="pip_expanded_shortest_edge_size">160dp</dimen>
 
+    <!-- The additional offset to apply to the IME animation to account for the input field. -->
+    <dimen name="pip_ime_offset">48dp</dimen>
+
     <!-- The padding between actions in the PiP in landscape  Note that the PiP does not reflect
          the configuration of the device, so we can't use -land resources. -->
     <dimen name="pip_between_action_padding_land">8dp</dimen>
@@ -774,9 +806,34 @@
 
     <dimen name="signal_icon_size">17dp</dimen>
 
-    <dimen name="qs_gutter_height">6dp</dimen>
+    <dimen name="hwui_edge_margin">16dp</dimen>
 
-    <!-- Width of the hollow triangle for empty signal state -->
-    <dimen name="mobile_signal_empty_strokewidth">2dp</dimen>
+    <dimen name="global_actions_panel_width">120dp</dimen>
+
+    <dimen name="global_actions_top_padding">120dp</dimen>
+
+    <!-- the maximum offset in either direction that elements are moved horizontally to prevent
+            burn-in on AOD -->
+    <dimen name="burn_in_prevention_offset_x">8dp</dimen>
+
+    <!-- the maximum offset in either direction that elements are moved vertically to prevent
+            burn-in on AOD -->
+    <dimen name="burn_in_prevention_offset_y">50dp</dimen>
+
+    <!-- padding between the notification stack and the keyguard status view when dozing -->
+    <dimen name="dozing_stack_padding">10dp</dimen>
+
+    <dimen name="corner_size">16dp</dimen>
+    <dimen name="top_padding">0dp</dimen>
+    <dimen name="bottom_padding">48dp</dimen>
+    <dimen name="edge_margin">16dp</dimen>
+
+    <dimen name="rounded_corner_radius">0dp</dimen>
+    <dimen name="rounded_corner_content_padding">8dp</dimen>
+
+    <!-- Intended corner radius when drawing the mobile signal -->
+    <dimen name="stat_sys_mobile_signal_corner_radius">0.75dp</dimen>
+    <!-- How far to inset the rounded edges -->
+    <dimen name="stat_sys_mobile_signal_circle_inset">0.9dp</dimen>
 
 </resources>
diff --git a/packages/SystemUI/res/values/dimens_car.xml b/packages/SystemUI/res/values/dimens_car.xml
index 988caf5..d5d4e10 100644
--- a/packages/SystemUI/res/values/dimens_car.xml
+++ b/packages/SystemUI/res/values/dimens_car.xml
@@ -16,18 +16,24 @@
 */
 -->
 <resources>
-    <dimen name="car_lockscreen_disclaimer_title_size">48sp</dimen>
-    <dimen name="car_lockscreen_disclaimer_title_padding_start">96dp</dimen>
-    <dimen name="car_lockscreen_disclaimer_title_padding_top">82dp</dimen>
-    <dimen name="car_lockscreen_disclaimer_text_size">28sp</dimen>
-    <dimen name="car_lockscreen_disclaimer_text_padding_start">96dp</dimen>
-    <dimen name="car_lockscreen_disclaimer_text_padding_end">96dp</dimen>
-    <dimen name="car_lockscreen_disclaimer_text_padding_top">8dp</dimen>
-    <dimen name="car_lockscreen_user_grid_view_padding_start">10dp</dimen>
-    <dimen name="car_lockscreen_user_grid_view_padding_end">10dp</dimen>
-    <dimen name="car_fullscreen_user_pod_image_avatar_width">128dp</dimen>
-    <dimen name="car_fullscreen_user_pod_image_avatar_height">128dp</dimen>
-    <dimen name="car_fullscreen_user_pod_text_size">24sp</dimen>
+    <dimen name="car_margin">148dp</dimen>
+
+    <dimen name="car_fullscreen_user_pod_margin_side">44dp</dimen>
+    <dimen name="car_fullscreen_user_pod_margin_above_text">24dp</dimen>
+    <dimen name="car_fullscreen_user_pod_image_avatar_width">192dp</dimen>
+    <dimen name="car_fullscreen_user_pod_image_avatar_height">192dp</dimen>
+    <dimen name="car_fullscreen_user_pod_text_size">40sp</dimen> <!-- B1 -->
+
     <dimen name="car_navigation_button_width">64dp</dimen>
     <dimen name="car_navigation_bar_width">760dp</dimen>
+
+    <dimen name="car_page_indicator_dot_diameter">12dp</dimen>
+    <dimen name="car_page_indicator_margin_top">32dp</dimen>
+
+    <dimen name="car_user_switcher_progress_bar_height">6dp</dimen>
+    <dimen name="car_user_switcher_progress_bar_margin_top">@dimen/status_bar_height</dimen>
+    <dimen name="car_start_driving_corner_radius">16dp</dimen>
+    <dimen name="car_start_driving_padding_side">30dp</dimen>
+    <dimen name="car_start_driving_height">80dp</dimen>
+    <dimen name="car_start_driving_text_size">32sp</dimen> <!-- B2 -->
 </resources>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index fc0c82c..b27dedd 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -45,6 +45,7 @@
     <item type="id" name="shadow_alpha_animator_start_value_tag"/>
     <item type="id" name="doze_saved_filter_tag"/>
     <item type="id" name="qs_icon_tag"/>
+    <item type="id" name="qs_slash_tag"/>
     <item type="id" name="scrim"/>
     <item type="id" name="scrim_target"/>
     <item type="id" name="scrim_alpha_start"/>
@@ -77,5 +78,13 @@
     <item type="id" name="action_move_tl_50" />
     <item type="id" name="action_move_tl_30" />
     <item type="id" name="action_move_rb_full" />
+
+    <!-- Accessibility actions for the notification menu -->
+    <item type="id" name="action_snooze_undo"/>
+    <item type="id" name="action_snooze_15_min"/>
+    <item type="id" name="action_snooze_30_min"/>
+    <item type="id" name="action_snooze_1_hour"/>
+    <item type="id" name="action_snooze_2_hours"/>
+    <item type="id" name="action_snooze_assistant_suggestion_1"/>
 </resources>
 
diff --git a/packages/SystemUI/res/values/integers_car.xml b/packages/SystemUI/res/values/integers_car.xml
new file mode 100644
index 0000000..320ee9f
--- /dev/null
+++ b/packages/SystemUI/res/values/integers_car.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android">
+    <integer name="car_user_switcher_timeout_ms">15000</integer>
+    <!-- This values less than ProgressBar.PROGRESS_ANIM_DURATION for a smooth animation. -->
+    <integer name="car_user_switcher_anim_update_ms">60</integer>
+</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 994a566..6202d13 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -741,6 +741,8 @@
     <string name="quick_settings_done">Done</string>
     <!-- QuickSettings: Control panel: Label for connected device. [CHAR LIMIT=NONE] -->
     <string name="quick_settings_connected">Connected</string>
+    <!-- QuickSettings: Control panel: Label for connected device, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_connected_battery_level">Connected, battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
     <!-- QuickSettings: Control panel: Label for connecting device. [CHAR LIMIT=NONE] -->
     <string name="quick_settings_connecting">Connecting...</string>
     <!-- QuickSettings: Tethering. [CHAR LIMIT=NONE] -->
@@ -1195,6 +1197,12 @@
         <xliff:g id="application_personal">%3$s</xliff:g>, which can monitor your personal network
         activity.</string>
 
+    <!-- Indication on the keyguard that appears when a trust agents unlocks the device. [CHAR LIMIT=40] -->
+    <string name="keyguard_indication_trust_granted">Unlocked for <xliff:g id="user_name" example="John Doe">%1$s</xliff:g></string>
+
+    <!-- Indication on the keyguard that appears when a trust agent is active and available. [CHAR LIMIT=40] -->
+    <string name="keyguard_indication_trust_managed"><xliff:g id="trust_agent" example="Smart Lock">%1$s</xliff:g> is running</string>
+
     <!-- Indication on the keyguard that appears when the user disables trust agents until the next time they unlock manually. [CHAR LIMIT=NONE] -->
     <string name="keyguard_indication_trust_disabled">Device will stay locked until you manually unlock</string>
 
@@ -1442,7 +1450,7 @@
     <string name="notification_header_default_channel">Notifications</string>
 
     <!-- Notification Inline Controls: Shown when a channel's notifications are currently blocked -->
-    <string name="notification_channel_disabled">You won\'t get these notifications anymore.</string>
+    <string name="notification_channel_disabled">You won\'t get these notifications anymore</string>
 
     <!-- Notification: Control panel: Label that shows how many channels are included in this bundle
         of notifications.  Replaces the channel name and only appears when there is more than one channel. -->
@@ -1452,6 +1460,9 @@
         Hints that the user's only option is to block all of the app's notifications. -->
     <string name="notification_default_channel_desc">This app doesn\'t have notification categories</string>
 
+    <!-- Notification: Control panel: Label that displays when the app's notifications cannot be blocked. -->
+    <string name="notification_unblockable_desc">Notifications from this app can\'t be turned off</string>
+
     <!-- Notification: Control panel: Label that shows how many channels this application has
         defined, describing the current notification channel as "1 out of n notification categories from this app". -->
     <plurals name="notification_num_channels_desc">
@@ -1502,20 +1513,27 @@
     <!-- Notification: Menu row: Content description for the snooze icon. [CHAR LIMIT=NONE] -->
     <string name="notification_menu_snooze_description">notification snooze options</string>
 
-    <!-- Notification: Menu row: Snooze options: 15 minute option. [CHAR LIMIT=50]-->
-    <string name="snooze_option_15_min">15 minutes</string>
-    <!-- Notification: Menu row: Snooze options: 30 minute option. [CHAR LIMIT=50]-->
-    <string name="snooze_option_30_min">30 minutes</string>
-    <!-- Notification: Menu row: Snooze options: 1 hour option. [CHAR LIMIT=50]-->
-    <string name="snooze_option_1_hour">1 hour</string>
-    <!-- Notification: Menu row: Snooze options: 1 hour option. [CHAR LIMIT=50]-->
-    <string name="snooze_option_2_hour">2 hours</string>
-    <!-- Notification: Menu row: Snooze undo button label. [CHAR LIMIT=50]-->
+    <!-- Notification: Snooze panel: Snooze undo button label. [CHAR LIMIT=50]-->
     <string name="snooze_undo">UNDO</string>
 
-    <!-- Notification: Menu row: Snooze: message indicating how long the notification was snoozed for. [CHAR LIMIT=100]-->
+    <!-- Notification: Snooze panel: message indicating how long the notification was snoozed for. [CHAR LIMIT=100]-->
     <string name="snoozed_for_time">Snoozed for <xliff:g id="time_amount" example="15 minutes">%1$s</xliff:g></string>
 
+    <!-- Notification:Snooze panel: Snooze options for hours -->
+    <plurals name="snoozeHourOptions">
+        <item quantity="one">%d hour</item>
+        <item quantity="two">%d hours</item>
+        <item quantity="few">%d hours</item>
+        <item quantity="other">%d hours</item>
+    </plurals>
+
+   <!--  Notification: Snooze panel: Snooze options for minutes -->
+   <plurals name="snoozeMinuteOptions">
+        <item quantity="one">%d minute</item>
+        <item quantity="few">%d minutes</item>
+        <item quantity="other">%d minutes</item>
+    </plurals>
+
     <!-- Title of the battery settings detail panel [CHAR LIMIT=20] -->
     <string name="battery_panel_title">Battery usage</string>
 
@@ -2028,4 +2046,7 @@
         been identified for them as running). [CHAR LIMIT=NONE] -->
     <string name="running_foreground_services_msg">Tap for details on battery and data usage</string>
 
+    <!-- Prompt to turn off data usage [CHAR LIMIT=NONE] -->
+    <string name="data_usage_disable_mobile" msgid="8656552431969276305">Turn off mobile data?</string>
+
 </resources>
diff --git a/packages/SystemUI/res/values/strings_car.xml b/packages/SystemUI/res/values/strings_car.xml
index 882773a..658eb4f 100644
--- a/packages/SystemUI/res/values/strings_car.xml
+++ b/packages/SystemUI/res/values/strings_car.xml
@@ -17,13 +17,6 @@
  */
 -->
 <resources>
-    <string name="car_lockscreen_disclaimer_title">Drive safely</string>
-    <string name="car_lockscreen_disclaimer_text">
-        Stay fully aware of driving conditions and always obey applicable laws. Directions may be
-        inaccurate, incomplete, dangerous, not suitable, prohibited, or involve crossing
-        administrative areas. Business information may also be inaccurate or incomplete. Data is
-        not real-time, and location accuracy cannot be guaranteed. Do not handle your mobile device
-        or use apps not intended for Android Auto while driving.
-    </string>
-
+    <string name="unknown_user_label">Unknown</string>
+    <string name="start_driving">Start Driving</string>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index d98b789..aacb4aa 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -27,7 +27,6 @@
         <item name="android:ambientShadowAlpha">0.35</item>
     </style>
 
-
     <!-- Recents theme -->
     <style name="RecentsTheme.Wallpaper">
         <item name="android:windowBackground">@*android:color/transparent</item>
@@ -35,6 +34,13 @@
         <item name="android:windowShowWallpaper">true</item>
         <item name="android:windowDisablePreview">true</item>
         <item name="clearAllStyle">@style/ClearAllButtonDefaultMargins</item>
+        <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
+        <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item>
+    </style>
+
+    <style name="RecentsTheme.Wallpaper.Light">
+        <item name="wallpaperTextColor">@*android:color/primary_text_material_light</item>
+        <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_light</item>
     </style>
 
     <style name="ClearAllButtonDefaultMargins">
@@ -47,6 +53,8 @@
     <!-- Performance optimized Recents theme (no wallpaper) -->
     <style name="RecentsTheme.NoWallpaper">
         <item name="android:windowBackground">@android:color/black</item>
+        <item name="wallpaperTextColor">@android:color/white</item>
+        <item name="wallpaperTextColorSecondary">@android:color/white</item>
     </style>
 
     <!-- Theme used for the activity that shows when the system forced an app to be resizable -->
@@ -210,6 +218,7 @@
 
     <style name="TextAppearance.QS.Introduction">
         <item name="android:textSize">14sp</item>
+        <item name="android:textColor">@color/zen_introduction</item>
     </style>
 
     <style name="TextAppearance.QS.Warning">
@@ -226,7 +235,7 @@
     </style>
 
     <style name="TextAppearance.QS.DetailButton.White">
-        <item name="android:textColor">@color/qs_detail_button_white</item>
+        <item name="android:textColor">@color/zen_introduction</item>
     </style>
 
     <style name="TextAppearance.QS.DetailEmpty">
@@ -290,11 +299,36 @@
     <style name="Animation.StatusBar">
     </style>
 
-    <style name="systemui_theme" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
+    <style name="Theme.SystemUI" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
         <item name="lightIconTheme">@style/DualToneLightTheme</item>
         <item name="darkIconTheme">@style/DualToneDarkTheme</item>
+        <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
+        <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item>
+        <item name="android:colorControlHighlight">@*android:color/primary_text_material_dark</item>
+        <item name="*android:lockPatternStyle">@style/LockPatternStyle</item>
+        <item name="passwordStyle">@style/PasswordTheme</item>
+
+        <!-- Needed for MediaRoute chooser dialog -->
+        <item name="*android:isLightTheme">false</item>
     </style>
-    <style name="qs_theme" parent="systemui_theme">
+
+    <style name="Theme.SystemUI.Light" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
+        <item name="wallpaperTextColor">@*android:color/primary_text_material_light</item>
+        <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_light</item>
+        <item name="android:colorControlHighlight">@*android:color/primary_text_material_light</item>
+        <item name="passwordStyle">@style/PasswordTheme.Light</item>
+    </style>
+
+    <style name="LockPatternStyle">
+        <item name="*android:regularColor">?attr/wallpaperTextColor</item>
+        <item name="*android:successColor">?attr/wallpaperTextColor</item>
+        <item name="*android:errorColor">?android:attr/colorError</item>
+    </style>
+
+    <!-- Overlay manager may replace this theme -->
+    <style name="qs_base" parent="@*android:style/Theme.DeviceDefault.QuickSettings" />
+
+    <style name="qs_theme" parent="qs_base">
         <item name="lightIconTheme">@style/QSIconTheme</item>
         <item name="darkIconTheme">@style/QSIconTheme</item>
     </style>
@@ -307,6 +341,8 @@
 
     <style name="Theme.SystemUI.Dialog.Alert" parent="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert" />
 
+    <style name="Theme.SystemUI.Dialog.GlobalActions" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar.Fullscreen" />
+
     <style name="QSBorderlessButton">
         <item name="android:padding">12dp</item>
         <item name="android:background">@drawable/qs_btn_borderless_rect</item>
@@ -448,7 +484,7 @@
         <item name="android:paddingEnd">8dp</item>
     </style>
 
-    <style name="edit_theme" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
+    <style name="edit_theme" parent="qs_base">
         <item name="android:colorBackground">?android:attr/colorSecondary</item>
     </style>
 
diff --git a/packages/SystemUI/res/values/styles_car.xml b/packages/SystemUI/res/values/styles_car.xml
new file mode 100644
index 0000000..c66792c
--- /dev/null
+++ b/packages/SystemUI/res/values/styles_car.xml
@@ -0,0 +1,34 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android">
+    <style name="CarUserSwitcher.ProgressBar" parent="@android:style/Widget.ProgressBar.Horizontal">
+        <item name="android:progressDrawable">@drawable/car_progress_bar</item>
+        <item name="android:min">0</item>
+        <item name="android:max">@integer/car_user_switcher_timeout_ms</item>
+        <item name="android:progress">0</item>
+        <item name="android:interpolator">@android:anim/linear_interpolator</item>
+    </style>
+
+    <style name="CarUserSwitcher.StartDrivingButton" parent="@android:style/Widget.Material.Button">
+        <item name="android:background">@drawable/car_round_button</item>
+        <item name="android:textSize">@dimen/car_start_driving_text_size</item>
+        <item name="android:textColor">@color/car_start_driving_text</item>
+        <item name="android:paddingLeft">@dimen/car_start_driving_padding_side</item>
+        <item name="android:paddingRight">@dimen/car_start_driving_padding_side</item>
+    </style>
+</resources>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 223dafd..32f502b 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -128,7 +128,7 @@
         <com.android.systemui.tuner.TunerSwitch
           android:key="doze_always_on"
           android:title="@string/tuner_doze_always_on"
-          sysui:defValue="false" />
+          sysui:defValue="true" />
 
     </PreferenceScreen>
 
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierText.java b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
index 159ac4c..13c48d0 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierText.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
@@ -39,6 +39,7 @@
 import com.android.internal.telephony.IccCardConstants.State;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.settingslib.WirelessUtils;
+import android.telephony.TelephonyManager;
 
 public class CarrierText extends TextView {
     private static final boolean DEBUG = KeyguardConstants.DEBUG;
@@ -52,6 +53,8 @@
 
     private WifiManager mWifiManager;
 
+    private boolean[] mSimErrorState = new boolean[TelephonyManager.getDefault().getPhoneCount()];
+
     private KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
         @Override
         public void onRefreshCarrierInfo() {
@@ -65,6 +68,22 @@
         public void onStartedWakingUp() {
             setSelected(true);
         };
+
+        public void onSimStateChanged(int subId, int slotId, IccCardConstants.State simState) {
+            if (slotId < 0) {
+                Log.d(TAG, "onSimStateChanged() - slotId invalid: " + slotId);
+                return;
+            }
+
+            if (DEBUG) Log.d(TAG,"onSimStateChanged: " + getStatusForIccState(simState));
+            if (getStatusForIccState(simState) == StatusMode.SimIoError) {
+                mSimErrorState[slotId] = true;
+                updateCarrierText();
+            } else if (mSimErrorState[slotId]) {
+                mSimErrorState[slotId] = false;
+                updateCarrierText();
+            }
+        };
     };
     /**
      * The status of this lock screen. Primarily used for widgets on LockScreen.
@@ -77,7 +96,8 @@
         SimPukLocked, // SIM card is PUK locked because SIM entered wrong too many times
         SimLocked, // SIM card is currently locked
         SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure
-        SimNotReady; // SIM is not ready yet. May never be on devices w/o a SIM.
+        SimNotReady, // SIM is not ready yet. May never be on devices w/o a SIM.
+        SimIoError; // SIM card is faulty
     }
 
     public CarrierText(Context context) {
@@ -101,6 +121,35 @@
         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
     }
 
+    /**
+     * Checks if there are faulty cards. Adds the text depending on the slot of the card
+     * @param text: current carrier text based on the sim state
+     * @param noSims: whether a valid sim card is inserted
+     * @return text
+    */
+    private CharSequence updateCarrierTextWithSimIoError(CharSequence text, boolean noSims) {
+        final CharSequence carrier = "";
+        CharSequence carrierTextForSimIOError = getCarrierTextForSimState(
+            IccCardConstants.State.CARD_IO_ERROR, carrier);
+        for (int index = 0; index < mSimErrorState.length; index++) {
+            if (mSimErrorState[index]) {
+                // In the case when no sim cards are detected but a faulty card is inserted
+                // overwrite the text and only show "Invalid card"
+                if (noSims) {
+                    return concatenate(carrierTextForSimIOError,
+                        getContext().getText(com.android.internal.R.string.emergency_calls_only));
+                } else if (index == 0) {
+                    // prepend "Invalid card" when faulty card is inserted in slot 0
+                    text = concatenate(carrierTextForSimIOError, text);
+                } else {
+                    // concatenate "Invalid card" when faulty card is inserted in slot 1
+                    text = concatenate(text, carrierTextForSimIOError);
+                }
+            }
+        }
+        return text;
+    }
+
     protected void updateCarrierText() {
         boolean allSimsMissing = true;
         boolean anySimReadyAndInService = false;
@@ -179,6 +228,7 @@
             }
         }
 
+        displayText = updateCarrierTextWithSimIoError(displayText, allSimsMissing);
         // APM (airplane mode) != no carrier state. There are carrier services
         // (e.g. WFC = Wi-Fi calling) which may operate in APM.
         if (!anySimReadyAndInService && WirelessUtils.isAirplaneModeOn(mContext)) {
@@ -270,6 +320,11 @@
                         getContext().getText(R.string.keyguard_sim_puk_locked_message),
                         text);
                 break;
+            case SimIoError:
+                carrierText = makeCarrierStringOnEmergencyCapable(
+                        getContext().getText(R.string.keyguard_sim_error_message_short),
+                        text);
+                break;
         }
 
         return carrierText;
@@ -319,6 +374,8 @@
                 return StatusMode.SimPermDisabled;
             case UNKNOWN:
                 return StatusMode.SimMissing;
+            case CARD_IO_ERROR:
+                return StatusMode.SimIoError;
         }
         return StatusMode.SimMissing;
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
index 80509a6..6a83c71 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
@@ -36,6 +36,9 @@
     @Override
     public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(host, event);
+        if (TextUtils.isEmpty(mFancyColon)) {
+            return;
+        }
         CharSequence text = event.getContentDescription();
         if (!TextUtils.isEmpty(text)) {
             event.setContentDescription(replaceFancyColon(text));
@@ -44,15 +47,22 @@
 
     @Override
     public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
-        CharSequence text = ((TextView) host).getText();
-        if (!TextUtils.isEmpty(text)) {
-            event.getText().add(replaceFancyColon(text));
+        if (TextUtils.isEmpty(mFancyColon)) {
+            super.onPopulateAccessibilityEvent(host, event);
+        } else {
+            CharSequence text = ((TextView) host).getText();
+            if (!TextUtils.isEmpty(text)) {
+                event.getText().add(replaceFancyColon(text));
+            }
         }
     }
 
     @Override
     public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(host, info);
+        if (TextUtils.isEmpty(mFancyColon)) {
+            return;
+        }
         if (!TextUtils.isEmpty(info.getText())) {
             info.setText(replaceFancyColon(info.getText()));
         }
@@ -62,6 +72,13 @@
     }
 
     private CharSequence replaceFancyColon(CharSequence text) {
+        if (TextUtils.isEmpty(mFancyColon)) {
+            return text;
+        }
         return text.toString().replace(mFancyColon, ":");
     }
+
+    public static boolean isNeeded(Context context) {
+        return !TextUtils.isEmpty(context.getString(R.string.keyguard_fancy_colon));
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java
new file mode 100644
index 0000000..ce3068d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java
@@ -0,0 +1,114 @@
+/*
+ * 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.keyguard;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.UserHandle;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Button;
+import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionInfo;
+import android.telephony.euicc.EuiccManager;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
+
+/***
+ * This button is used by the device with embedded SIM card to disable current carrier to unlock
+ * the device with no cellular service.
+ */
+class KeyguardEsimArea extends Button implements View.OnClickListener {
+    private static final String ACTION_DISABLE_ESIM = "com.android.keyguard.disable_esim";
+    private static final String TAG = "KeyguardEsimArea";
+    private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
+
+    private EuiccManager mEuiccManager;
+
+    private BroadcastReceiver mReceiver =
+        new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (ACTION_DISABLE_ESIM.equals(intent.getAction())) {
+                    int resultCode = getResultCode();
+                    if (resultCode != EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
+                        // TODO (b/62680294): Surface more info. to the end users for this failure.
+                        Log.e(TAG, "Error disabling esim, result code = " + resultCode);
+                    }
+                }
+            }
+        };
+
+    public KeyguardEsimArea(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardEsimArea(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public KeyguardEsimArea(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, android.R.style.Widget_Material_Button_Borderless);
+    }
+
+    public KeyguardEsimArea(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        setOnClickListener(this);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_DISABLE_ESIM),
+                PERMISSION_SELF, null /* scheduler */);
+    }
+
+    public static boolean isEsimLocked(Context context, int subId) {
+        EuiccManager euiccManager =
+                (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);
+        if (!euiccManager.isEnabled()) {
+            return false;
+        }
+        SubscriptionInfo sub = SubscriptionManager.from(context).getActiveSubscriptionInfo(subId);
+        return  sub != null && sub.isEmbedded();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        mContext.unregisterReceiver(mReceiver);
+        super.onDetachedFromWindow();
+    }
+
+    @Override
+    public void onClick(View v) {
+        Intent intent = new Intent(mContext, KeyguardEsimArea.class);
+        intent.setAction(ACTION_DISABLE_ESIM);
+        intent.setPackage(mContext.getPackageName());
+        PendingIntent callbackIntent = PendingIntent.getBroadcast(
+            mContext,
+            0 /* requestCode */,
+            intent,
+            PendingIntent.FLAG_UPDATE_CURRENT);
+        mEuiccManager
+                .switchToSubscription(SubscriptionManager.INVALID_SUBSCRIPTION_ID, callbackIntent);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 616e5b9..27bc599 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -21,6 +21,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.os.UserHandle;
+import android.support.annotation.VisibleForTesting;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Slog;
@@ -75,8 +76,7 @@
     }
 
     public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) {
-        super(new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault), attrs,
-                defStyle);
+        super(context, attrs, defStyle);
         mSecurityModel = new KeyguardSecurityModel(context);
         mLockPatternUtils = new LockPatternUtils(context);
         mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
@@ -471,7 +471,8 @@
         return 0;
     }
 
-    protected int getLayoutIdFor(SecurityMode securityMode) {
+    @VisibleForTesting
+    public int getLayoutIdFor(SecurityMode securityMode) {
         switch (securityMode) {
             case Pattern: return R.layout.keyguard_pattern_view;
             case PIN: return R.layout.keyguard_pin_view;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
index 7baa57e..0cb6423 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -57,16 +57,16 @@
     SecurityMode getSecurityMode(int userId) {
         KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
 
-        if (SubscriptionManager.isValidSubscriptionId(
-                monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED))) {
-            return SecurityMode.SimPin;
-        }
-
         if (mIsPukScreenAvailable && SubscriptionManager.isValidSubscriptionId(
                 monitor.getNextSubIdForState(IccCardConstants.State.PUK_REQUIRED))) {
             return SecurityMode.SimPuk;
         }
 
+        if (SubscriptionManager.isValidSubscriptionId(
+                monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED))) {
+            return SecurityMode.SimPin;
+        }
+
         final int security = mLockPatternUtils.getActivePasswordQuality(userId);
         switch (security) {
             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
index 0cf8900..432b406 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
@@ -35,8 +35,10 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.euicc.EuiccManager;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.View;
 import android.view.WindowManager;
 import android.widget.ImageView;
 
@@ -58,9 +60,23 @@
     KeyguardUpdateMonitorCallback mUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() {
         @Override
         public void onSimStateChanged(int subId, int slotId, State simState) {
-           if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",state=" + simState + ")");
-           resetState();
-       };
+            if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",state=" + simState + ")");
+            switch(simState) {
+                // If the SIM is removed, then we must remove the keyguard. It will be put up
+                // again when the PUK locked SIM is re-entered.
+                case ABSENT: {
+                    KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked(mSubId);
+                    // onSimStateChanged callback can fire when the SIM PIN lock is not currently
+                    // active and mCallback is null.
+                    if (mCallback != null) {
+                        mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
+                    }
+                    break;
+                }
+                default:
+                    resetState();
+            }
+        }
     };
 
     public KeyguardSimPinView(Context context) {
@@ -77,10 +93,11 @@
         if (DEBUG) Log.v(TAG, "Resetting state");
         KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
         mSubId = monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED);
+        boolean isEsimLocked = KeyguardEsimArea.isEsimLocked(mContext, mSubId);
         if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
             int count = TelephonyManager.getDefault().getSimCount();
             Resources rez = getResources();
-            final String msg;
+            String msg;
             int color = Color.WHITE;
             if (count < 2) {
                 msg = rez.getString(R.string.kg_sim_pin_instructions);
@@ -92,9 +109,14 @@
                     color = info.getIconTint();
                 }
             }
+            if (isEsimLocked) {
+                msg = msg + " " + rez.getString(R.string.kg_sim_lock_instructions_esim);
+            }
             mSecurityMessageDisplay.setMessage(msg);
             mSimImageView.setImageTintList(ColorStateList.valueOf(color));
         }
+        KeyguardEsimArea esimButton = findViewById(R.id.keyguard_esim_area);
+        esimButton.setVisibility(isEsimLocked ? View.VISIBLE : View.GONE);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
index fb3cee7..7f79008 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
@@ -29,8 +29,10 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.euicc.EuiccManager;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.View;
 import android.view.WindowManager;
 import android.widget.ImageView;
 
@@ -60,9 +62,27 @@
     KeyguardUpdateMonitorCallback mUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() {
         @Override
         public void onSimStateChanged(int subId, int slotId, State simState) {
-           if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",state=" + simState + ")");
-           resetState();
-       };
+            if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",state=" + simState + ")");
+            switch(simState) {
+                // If the SIM is removed, then we must remove the keyguard. It will be put up
+                // again when the PUK locked SIM is re-entered.
+                case ABSENT:
+                // intentional fall-through
+                // If the SIM is unlocked via a key sequence through the emergency dialer, it will
+                // move into the READY state and the PUK lock keyguard should be removed.
+                case READY: {
+                    KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked(mSubId);
+                    // mCallback can be null if onSimStateChanged callback is called when keyguard
+                    // isn't active.
+                    if (mCallback != null) {
+                        mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
+                    }
+                    break;
+                }
+                default:
+                    resetState();
+            }
+        }
     };
 
     public KeyguardSimPukView(Context context) {
@@ -118,10 +138,11 @@
             state = ENTER_PUK;
             KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
             mSubId = monitor.getNextSubIdForState(IccCardConstants.State.PUK_REQUIRED);
+            boolean isEsimLocked = KeyguardEsimArea.isEsimLocked(mContext, mSubId);
             if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
                 int count = TelephonyManager.getDefault().getSimCount();
                 Resources rez = getResources();
-                final String msg;
+                String msg;
                 int color = Color.WHITE;
                 if (count < 2) {
                     msg = rez.getString(R.string.kg_puk_enter_puk_hint);
@@ -133,11 +154,18 @@
                         color = info.getIconTint();
                     }
                 }
+                if (isEsimLocked) {
+                    msg = msg + " " + rez.getString(R.string.kg_sim_lock_instructions_esim);
+                }
                 mSecurityMessageDisplay.setMessage(msg);
                 mSimImageView.setImageTintList(ColorStateList.valueOf(color));
             }
+            KeyguardEsimArea esimButton = findViewById(R.id.keyguard_esim_area);
+            esimButton.setVisibility(isEsimLocked ? View.VISIBLE : View.GONE);
             mPasswordEntry.requestFocus();
         }
+
+
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index d214d55..bc2a59d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -19,9 +19,15 @@
 import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.UserHandle;
+import android.support.v4.graphics.ColorUtils;
 import android.text.TextUtils;
 import android.text.format.DateFormat;
 import android.util.AttributeSet;
@@ -44,6 +50,7 @@
 public class KeyguardStatusView extends GridLayout {
     private static final boolean DEBUG = KeyguardConstants.DEBUG;
     private static final String TAG = "KeyguardStatusView";
+    private static final int MARQUEE_DELAY_MS = 2000;
 
     private final LockPatternUtils mLockPatternUtils;
     private final AlarmManager mAlarmManager;
@@ -54,10 +61,16 @@
     private TextView mOwnerInfo;
     private ViewGroup mClockContainer;
     private ChargingView mBatteryDoze;
+    private View mKeyguardStatusArea;
+    private Runnable mPendingMarqueeStart;
+    private Handler mHandler;
 
     private View[] mVisibleInDoze;
     private boolean mPulsing;
-    private boolean mDark;
+    private float mDarkAmount = 0;
+    private int mTextColor;
+    private int mDateTextColor;
+    private int mAlarmTextColor;
 
     private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
 
@@ -104,9 +117,29 @@
         super(context, attrs, defStyle);
         mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         mLockPatternUtils = new LockPatternUtils(getContext());
+        mHandler = new Handler(Looper.myLooper());
     }
 
     private void setEnableMarquee(boolean enabled) {
+        if (DEBUG) Log.v(TAG, "Schedule setEnableMarquee: " + (enabled ? "Enable" : "Disable"));
+        if (enabled) {
+            if (mPendingMarqueeStart == null) {
+                mPendingMarqueeStart = () -> {
+                    setEnableMarqueeImpl(true);
+                    mPendingMarqueeStart = null;
+                };
+                mHandler.postDelayed(mPendingMarqueeStart, MARQUEE_DELAY_MS);
+            }
+        } else {
+            if (mPendingMarqueeStart != null) {
+                mHandler.removeCallbacks(mPendingMarqueeStart);
+                mPendingMarqueeStart = null;
+            }
+            setEnableMarqueeImpl(false);
+        }
+    }
+
+    private void setEnableMarqueeImpl(boolean enabled) {
         if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee");
         if (mAlarmStatusView != null) mAlarmStatusView.setSelected(enabled);
         if (mOwnerInfo != null) mOwnerInfo.setSelected(enabled);
@@ -120,10 +153,16 @@
         mDateView = findViewById(R.id.date_view);
         mClockView = findViewById(R.id.clock_view);
         mClockView.setShowCurrentUserTime(true);
-        mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
+        if (KeyguardClockAccessibilityDelegate.isNeeded(mContext)) {
+            mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
+        }
         mOwnerInfo = findViewById(R.id.owner_info);
         mBatteryDoze = findViewById(R.id.battery_doze);
-        mVisibleInDoze = new View[]{mBatteryDoze, mClockView};
+        mKeyguardStatusArea = findViewById(R.id.keyguard_status_area);
+        mVisibleInDoze = new View[]{mBatteryDoze, mClockView, mKeyguardStatusArea};
+        mTextColor = mClockView.getCurrentTextColor();
+        mDateTextColor = mDateView.getCurrentTextColor();
+        mAlarmTextColor = mAlarmStatusView.getCurrentTextColor();
 
         boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
         setEnableMarquee(shouldMarquee);
@@ -182,8 +221,11 @@
     }
 
     public int getClockBottom() {
-        return mClockView.getBottom() +
-                ((MarginLayoutParams) mClockView.getLayoutParams()).bottomMargin;
+        return mKeyguardStatusArea.getBottom();
+    }
+
+    public float getClockTextSize() {
+        return mClockView.getTextSize();
     }
 
     public static String formatNextAlarm(Context context, AlarmManager.AlarmClockInfo info) {
@@ -278,12 +320,13 @@
         }
     }
 
-    public void setDark(boolean dark) {
-        if (mDark == dark) {
+    public void setDark(float darkAmount) {
+        if (mDarkAmount == darkAmount) {
             return;
         }
-        mDark = dark;
+        mDarkAmount = darkAmount;
 
+        boolean dark = darkAmount == 1;
         final int N = mClockContainer.getChildCount();
         for (int i = 0; i < N; i++) {
             View child = mClockContainer.getChildAt(i);
@@ -292,8 +335,17 @@
             }
             child.setAlpha(dark ? 0 : 1);
         }
+        if (mOwnerInfo != null) {
+            mOwnerInfo.setAlpha(dark ? 0 : 1);
+        }
+
         updateDozeVisibleViews();
         mBatteryDoze.setDark(dark);
+        mClockView.setTextColor(ColorUtils.blendARGB(mTextColor, Color.WHITE, darkAmount));
+        mDateView.setTextColor(ColorUtils.blendARGB(mDateTextColor, Color.WHITE, darkAmount));
+        int blendedAlarmColor = ColorUtils.blendARGB(mAlarmTextColor, Color.WHITE, darkAmount);
+        mAlarmStatusView.setTextColor(blendedAlarmColor);
+        mAlarmStatusView.setCompoundDrawableTintList(ColorStateList.valueOf(blendedAlarmColor));
     }
 
     public void setPulsing(boolean pulsing) {
@@ -303,7 +355,7 @@
 
     private void updateDozeVisibleViews() {
         for (View child : mVisibleInDoze) {
-            child.setAlpha(mDark && mPulsing ? 0.8f : 1);
+            child.setAlpha(mDarkAmount == 1 && mPulsing ? 0.8f : 1);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index ad82840..b36ae24 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -52,7 +52,6 @@
 import android.os.IRemoteCallback;
 import android.os.Message;
 import android.os.RemoteException;
-import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -62,7 +61,6 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
 import android.telephony.TelephonyManager;
-import android.util.ArraySet;
 import android.util.Log;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
@@ -74,6 +72,8 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -131,6 +131,8 @@
     private static final int MSG_SCREEN_TURNED_OFF = 332;
     private static final int MSG_DREAMING_STATE_CHANGED = 333;
     private static final int MSG_USER_UNLOCKED = 334;
+    private static final int MSG_ASSISTANT_STACK_CHANGED = 335;
+    private static final int MSG_FINGERPRINT_AUTHENTICATION_CONTINUE = 336;
 
     /** Fingerprint state: Not listening to fingerprint. */
     private static final int FINGERPRINT_STATE_STOPPED = 0;
@@ -170,6 +172,8 @@
     private boolean mBootCompleted;
     private boolean mNeedsSlowUnlockTransition;
     private boolean mHasLockscreenWallpaper;
+    private boolean mAssistantVisible;
+    private boolean mKeyguardOccluded;
 
     // Device provisioning state
     private boolean mDeviceProvisioned;
@@ -197,6 +201,13 @@
     private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
     private LockPatternUtils mLockPatternUtils;
 
+    /**
+     * Short delay before restarting fingerprint authentication after a successful try
+     * This should be slightly longer than the time between onFingerprintAuthenticated and
+     * setKeyguardGoingAway(true).
+     */
+    private static final int FINGERPRINT_CONTINUE_DELAY_MS = 500;
+
     // If FP daemon dies, keyguard should retry after a short delay
     private int mHardwareUnavailableRetryCount = 0;
     private static final int HW_UNAVAILABLE_TIMEOUT = 3000; // ms
@@ -287,6 +298,13 @@
                 case MSG_USER_UNLOCKED:
                     handleUserUnlocked();
                     break;
+                case MSG_ASSISTANT_STACK_CHANGED:
+                    mAssistantVisible = (boolean)msg.obj;
+                    updateFingerprintListeningState();
+                    break;
+                case MSG_FINGERPRINT_AUTHENTICATION_CONTINUE:
+                    updateFingerprintListeningState();
+                    break;
             }
         }
     };
@@ -414,9 +432,22 @@
         mKeyguardGoingAway = goingAway;
     }
 
+    /**
+     * Updates KeyguardUpdateMonitor's internal state to know if keyguard is occluded
+     * @param occluded
+     */
+    public void setKeyguardOccluded(boolean occluded) {
+        mKeyguardOccluded = occluded;
+        updateFingerprintListeningState();
+    }
+
     private void onFingerprintAuthenticated(int userId) {
         Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
         mUserFingerprintAuthenticated.put(userId, true);
+        // Update/refresh trust state only if user can skip bouncer
+        if (getUserCanSkipBouncer(userId)) {
+            mTrustManager.unlockedByFingerprintForUser(userId);
+        }
         // Don't send cancel if authentication succeeds
         mFingerprintCancelSignal = null;
         for (int i = 0; i < mCallbacks.size(); i++) {
@@ -425,6 +456,13 @@
                 cb.onFingerprintAuthenticated(userId);
             }
         }
+
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATION_CONTINUE),
+                FINGERPRINT_CONTINUE_DELAY_MS);
+
+        // Only authenticate fingerprint once when assistant is visible
+        mAssistantVisible = false;
+
         Trace.endSection();
     }
 
@@ -826,6 +864,8 @@
                 }
             } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
                 state = IccCardConstants.State.NETWORK_LOCKED;
+            } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
+                state = IccCardConstants.State.CARD_IO_ERROR;
             } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
                         || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
                 // This is required because telephony doesn't return to "READY" after
@@ -1106,10 +1146,16 @@
             mFpm.addLockoutResetCallback(mLockoutResetCallback);
         }
 
+        SystemServicesProxy.getInstance(mContext).registerTaskStackListener(mTaskStackListener);
         mUserManager = context.getSystemService(UserManager.class);
     }
 
     private void updateFingerprintListeningState() {
+        // If this message exists, we should not authenticate again until this message is
+        // consumed by the handler
+        if (mHandler.hasMessages(MSG_FINGERPRINT_AUTHENTICATION_CONTINUE)) {
+            return;
+        }
         mHandler.removeCallbacks(mRetryFingerprintAuthentication);
         boolean shouldListenForFingerprint = shouldListenForFingerprint();
         if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING && !shouldListenForFingerprint) {
@@ -1122,8 +1168,10 @@
 
     private boolean shouldListenForFingerprint() {
         return (mKeyguardIsVisible || !mDeviceInteractive ||
-                    (mBouncer && !mKeyguardGoingAway) || mGoingToSleep)
-                && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser());
+                (mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
+                (mAssistantVisible && mKeyguardOccluded))
+                && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
+                && !mKeyguardGoingAway;
     }
 
     private void startListeningForFingerprint() {
@@ -1151,8 +1199,10 @@
     private void stopListeningForFingerprint() {
         if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
         if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING) {
-            mFingerprintCancelSignal.cancel();
-            mFingerprintCancelSignal = null;
+            if (mFingerprintCancelSignal != null) {
+                mFingerprintCancelSignal.cancel();
+                mFingerprintCancelSignal = null;
+            }
             setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
         }
         if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
@@ -1651,6 +1701,7 @@
 
     public void clearFingerprintRecognized() {
         mUserFingerprintAuthenticated.clear();
+        mTrustManager.clearAllFingerprints();
     }
 
     public boolean isSimPinVoiceSecure() {
@@ -1674,6 +1725,23 @@
         }
     }
 
+    private final TaskStackListener mTaskStackListener = new TaskStackListener() {
+        @Override
+        public void onTaskStackChangedBackground() {
+            try {
+                ActivityManager.StackInfo info = ActivityManager.getService().getStackInfo(
+                        ActivityManager.StackId.ASSISTANT_STACK_ID);
+                if (info == null) {
+                    return;
+                }
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_ASSISTANT_STACK_CHANGED,
+                        info.visible));
+            } catch (RemoteException e) {
+                Log.e(TAG, "unable to check task stack", e);
+            }
+        }
+    };
+
     /**
      * @return true if and only if the state has changed for the specified {@code slotId}
      */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 14d6b59..5a02178 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -154,13 +154,19 @@
 
     /**
      * Called when the device has started waking up.
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.WakefulnessLifecycle}.
      */
+    @Deprecated
     public void onStartedWakingUp() { }
 
     /**
      * Called when the device has started going to sleep.
      * @param why see {@link #onFinishedGoingToSleep(int)}
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.WakefulnessLifecycle}.
      */
+    @Deprecated
     public void onStartedGoingToSleep(int why) { }
 
     /**
@@ -168,17 +174,26 @@
      * @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_ADMIN},
      * {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER}, or
      * {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT}.
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.WakefulnessLifecycle}.
      */
+    @Deprecated
     public void onFinishedGoingToSleep(int why) { }
 
     /**
      * Called when the screen has been turned on.
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.ScreenLifecycle}.
      */
+    @Deprecated
     public void onScreenTurnedOn() { }
 
     /**
      * Called when the screen has been turned off.
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.ScreenLifecycle}.
      */
+    @Deprecated
     public void onScreenTurnedOff() { }
 
     /**
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
index c43820d..12f75bb 100644
--- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
@@ -23,15 +23,14 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.Typeface;
 import android.os.PowerManager;
 import android.os.SystemClock;
-import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.InputType;
-import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.View;
@@ -127,13 +126,16 @@
             mCharPadding = a.getDimensionPixelSize(R.styleable.PasswordTextView_charPadding,
                     getContext().getResources().getDimensionPixelSize(
                             R.dimen.password_char_padding));
+            int textColor = a.getColor(R.styleable.PasswordTextView_android_textColor, Color.WHITE);
+            mDrawPaint.setColor(textColor);
         } finally {
             a.recycle();
         }
         mDrawPaint.setFlags(Paint.SUBPIXEL_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
         mDrawPaint.setTextAlign(Paint.Align.CENTER);
-        mDrawPaint.setColor(0xffffffff);
-        mDrawPaint.setTypeface(Typeface.create("sans-serif-light", 0));
+        mDrawPaint.setTypeface(Typeface.create(
+                context.getString(com.android.internal.R.string.config_headlineFontFamilyLight),
+                0));
         mShowPassword = Settings.System.getInt(mContext.getContentResolver(),
                 Settings.System.TEXT_SHOW_PASSWORD, 1) == 1;
         mAppearInterpolator = AnimationUtils.loadInterpolator(mContext,
@@ -248,9 +250,9 @@
             mText = mText.substring(0, length - 1);
             CharState charState = mTextChars.get(length - 1);
             charState.startRemoveAnimation(0, 0);
+            sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
         }
         userActivity();
-        sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
     }
 
     public String getText() {
diff --git a/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java b/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java
index 810dd8c..01b4254 100644
--- a/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java
@@ -24,59 +24,50 @@
 import android.view.View;
 import android.widget.FrameLayout;
 
+import com.android.systemui.statusbar.policy.ConfigurationController;
+
 import java.util.ArrayList;
 import java.util.List;
 
 /**
  * Custom {@link FrameLayout} that re-inflates when changes to {@link Configuration} happen.
- * Currently supports changes to density and locale.
+ * Currently supports changes to density, asset path, and locale.
  */
-public class AutoReinflateContainer extends FrameLayout {
+public class AutoReinflateContainer extends FrameLayout implements
+        ConfigurationController.ConfigurationListener {
 
     private final List<InflateListener> mInflateListeners = new ArrayList<>();
     private final int mLayout;
-    private int mDensity;
-    private LocaleList mLocaleList;
 
     public AutoReinflateContainer(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
 
-        mDensity = context.getResources().getConfiguration().densityDpi;
-        mLocaleList = context.getResources().getConfiguration().getLocales();
-
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoReinflateContainer);
         if (!a.hasValue(R.styleable.AutoReinflateContainer_android_layout)) {
             throw new IllegalArgumentException("AutoReinflateContainer must contain a layout");
         }
         mLayout = a.getResourceId(R.styleable.AutoReinflateContainer_android_layout, 0);
+        a.recycle();
         inflateLayout();
     }
 
     @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        boolean shouldInflateLayout = false;
-        final int density = newConfig.densityDpi;
-        if (density != mDensity) {
-            mDensity = density;
-            shouldInflateLayout = true;
-        }
-        final LocaleList localeList = newConfig.getLocales();
-        if (localeList != mLocaleList) {
-            mLocaleList = localeList;
-            shouldInflateLayout = true;
-        }
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        Dependency.get(ConfigurationController.class).addCallback(this);
+    }
 
-        if (shouldInflateLayout) {
-            inflateLayout();
-        }
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        Dependency.get(ConfigurationController.class).removeCallback(this);
     }
 
     protected void inflateLayoutImpl() {
         LayoutInflater.from(getContext()).inflate(mLayout, this);
     }
 
-    protected void inflateLayout() {
+    public void inflateLayout() {
         removeAllViews();
         inflateLayoutImpl();
         final int N = mInflateListeners.size();
@@ -90,6 +81,21 @@
         listener.onInflated(getChildAt(0));
     }
 
+    @Override
+    public void onDensityOrFontScaleChanged() {
+        inflateLayout();
+    }
+
+    @Override
+    public void onOverlayChanged() {
+        inflateLayout();
+    }
+
+    @Override
+    public void onLocaleListChanged() {
+        inflateLayout();
+    }
+
     public interface InflateListener {
         /**
          * Called whenever a new view is inflated.
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 96a7112..c4de63b 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -71,6 +71,7 @@
 
     private int mLightModeBackgroundColor;
     private int mLightModeFillColor;
+    private float mDarkIntensity;
 
     public BatteryMeterView(Context context) {
         this(context, null, 0);
@@ -239,6 +240,7 @@
 
     @Override
     public void onDarkChanged(Rect area, float darkIntensity, int tint) {
+        mDarkIntensity = darkIntensity;
         float intensity = DarkIconDispatcher.isInArea(area, this) ? darkIntensity : 0;
         int foreground = getColorForDarkIntensity(intensity, mLightModeFillColor,
                 mDarkModeFillColor);
@@ -255,6 +257,14 @@
         }
     }
 
+    public void setFillColor(int color) {
+        if (mLightModeFillColor == color) {
+            return;
+        }
+        mLightModeFillColor = color;
+        onDarkChanged(new Rect(), mDarkIntensity, DarkIconDispatcher.DEFAULT_ICON_TINT);
+    }
+
     private int getColorForDarkIntensity(float darkIntensity, int lightColor, int darkColor) {
         return (int) ArgbEvaluator.getInstance().evaluate(darkIntensity, lightColor, darkColor);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 8ba33c3..ecc2111 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -16,6 +16,7 @@
 
 import android.content.Context;
 import android.content.res.Configuration;
+import android.hardware.SensorManager;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
@@ -28,19 +29,25 @@
 import com.android.internal.util.Preconditions;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.systemui.assist.AssistManager;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.PluginActivityManager;
 import com.android.systemui.plugins.PluginDependencyProvider;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.PluginManagerImpl;
 import com.android.systemui.plugins.VolumeDialogController;
+import com.android.systemui.power.PowerNotificationWarnings;
+import com.android.systemui.power.PowerUI;
 import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
 import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
 import com.android.systemui.statusbar.phone.ManagedProfileController;
 import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
-import com.android.systemui.statusbar.phone.StatusBarWindowManager;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl;
+import com.android.systemui.statusbar.phone.StatusBarWindowManager;
 import com.android.systemui.statusbar.policy.AccessibilityController;
 import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -77,8 +84,10 @@
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
+import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerServiceImpl;
+import com.android.systemui.util.AsyncSensorManager;
 import com.android.systemui.util.leak.GarbageMonitor;
 import com.android.systemui.util.leak.LeakDetector;
 import com.android.systemui.util.leak.LeakReporter;
@@ -105,6 +114,7 @@
  * services, registered receivers, etc.
  */
 public class Dependency extends SystemUI {
+    private static final String TAG = "Dependency";
 
     /**
      * Key for getting a background Looper for background work.
@@ -150,6 +160,9 @@
         mProviders.put(ActivityStarterDelegate.class, () ->
                 getDependency(ActivityStarter.class));
 
+        mProviders.put(AsyncSensorManager.class, () ->
+                new AsyncSensorManager(mContext.getSystemService(SensorManager.class)));
+
         mProviders.put(BluetoothController.class, () ->
                 new BluetoothControllerImpl(mContext, getDependency(BG_LOOPER)));
 
@@ -244,11 +257,17 @@
         mProviders.put(StatusBarIconController.class, () ->
                 new StatusBarIconControllerImpl(mContext));
 
+        mProviders.put(ScreenLifecycle.class, () ->
+                new ScreenLifecycle());
+
+        mProviders.put(WakefulnessLifecycle.class, () ->
+                new WakefulnessLifecycle());
+
         mProviders.put(FragmentService.class, () ->
                 new FragmentService(mContext));
 
         mProviders.put(ExtensionController.class, () ->
-                new ExtensionControllerImpl());
+                new ExtensionControllerImpl(mContext));
 
         mProviders.put(PluginDependencyProvider.class, () ->
                 new PluginDependencyProvider(get(PluginManager.class)));
@@ -264,11 +283,23 @@
         mProviders.put(AccessibilityManagerWrapper.class,
                 () -> new AccessibilityManagerWrapper(mContext));
 
+        // Creating a new instance will trigger color extraction.
+        // Thankfully this only happens once - during boot - and WallpaperManagerService
+        // loads colors from cache.
+        mProviders.put(SysuiColorExtractor.class, () -> new SysuiColorExtractor(mContext));
+
+        mProviders.put(TunablePaddingService.class, () -> new TunablePaddingService());
+
         mProviders.put(ForegroundServiceController.class,
                 () -> new ForegroundServiceControllerImpl(mContext));
 
         mProviders.put(UiOffloadThread.class, UiOffloadThread::new);
 
+        mProviders.put(PluginActivityManager.class,
+                () -> new PluginActivityManager(mContext, getDependency(PluginManager.class)));
+
+        mProviders.put(PowerUI.WarningsUI.class, () -> new PowerNotificationWarnings(mContext));
+
         // Put all dependencies above here so the factory can override them if it wants.
         SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java b/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java
index c382882..9fe730a 100644
--- a/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java
+++ b/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java
@@ -14,56 +14,77 @@
 
 package com.android.systemui;
 
+import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Log;
 import android.view.IDockedStackListener;
 import android.view.WindowManagerGlobal;
 
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
 import java.util.function.Consumer;
 
 /**
  * Utility wrapper to listen for whether or not a docked stack exists, to be
  * used for things like the different overview icon in that mode.
  */
-public class DockedStackExistsListener extends IDockedStackListener.Stub {
+public class DockedStackExistsListener {
 
     private static final String TAG = "DockedStackExistsListener";
 
-    private final Consumer<Boolean> mCallback;
+    private static ArrayList<WeakReference<Consumer<Boolean>>> sCallbacks = new ArrayList<>();
 
-    private DockedStackExistsListener(Consumer<Boolean> callback) {
-        mCallback = callback;
+    static {
+        try {
+            WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(
+                    new IDockedStackListener.Stub() {
+                        @Override
+                        public void onDividerVisibilityChanged(boolean b) throws RemoteException {
+
+                        }
+
+                        @Override
+                        public void onDockedStackExistsChanged(boolean exists)
+                                throws RemoteException {
+                            DockedStackExistsListener.onDockedStackExistsChanged(exists);
+                        }
+
+                        @Override
+                        public void onDockedStackMinimizedChanged(boolean b, long l, boolean b1)
+                                throws RemoteException {
+
+                        }
+
+                        @Override
+                        public void onAdjustedForImeChanged(boolean b, long l)
+                                throws RemoteException {
+
+                        }
+
+                        @Override
+                        public void onDockSideChanged(int i) throws RemoteException {
+
+                        }
+                    });
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed registering docked stack exists listener", e);
+        }
     }
 
-    @Override
-    public void onDividerVisibilityChanged(boolean visible) throws RemoteException {
-    }
 
-    @Override
-    public void onDockedStackExistsChanged(final boolean exists) throws RemoteException {
-        mCallback.accept(exists);
-    }
-
-    @Override
-    public void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
-                                              boolean isHomeStackResizable) throws RemoteException {
-    }
-
-    @Override
-    public void onAdjustedForImeChanged(boolean adjustedForIme, long animDuration)
-            throws RemoteException {
-    }
-
-    @Override
-    public void onDockSideChanged(int newDockSide) throws RemoteException {
+    private static void onDockedStackExistsChanged(boolean exists) {
+        synchronized (sCallbacks) {
+            sCallbacks.removeIf(wf -> {
+                Consumer<Boolean> l = wf.get();
+                if (l != null) l.accept(exists);
+                return l == null;
+            });
+        }
     }
 
     public static void register(Consumer<Boolean> callback) {
-        try {
-            WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(
-                    new DockedStackExistsListener(callback));
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed registering docked stack exists listener", e);
+        synchronized (sCallbacks) {
+            sCallbacks.add(new WeakReference<>(callback));
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 7fed3e8..377fab5 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -545,6 +545,16 @@
      */
     @VisibleForTesting
     void finishExpanding(boolean forceAbort, float velocity) {
+        finishExpanding(forceAbort, velocity, true /* allowAnimation */);
+    }
+
+    /**
+     * Finish the current expand motion
+     * @param forceAbort whether the expansion should be forcefully aborted and returned to the old
+     *                   state
+     * @param velocity the velocity this was expanded/ collapsed with
+     */
+    private void finishExpanding(boolean forceAbort, float velocity, boolean allowAnimation) {
         if (!mExpanding) return;
 
         if (DEBUG) Log.d(TAG, "scale in finishing on view: " + mResizedView);
@@ -568,7 +578,7 @@
         mCallback.expansionStateChanged(false);
         int naturalHeight = mScaler.getNaturalHeight();
         float targetHeight = nowExpanded ? naturalHeight : mSmallSize;
-        if (targetHeight != currentHeight && mEnabled) {
+        if (targetHeight != currentHeight && mEnabled && allowAnimation) {
             mScaleAnimation.setFloatValues(targetHeight);
             mScaleAnimation.setupStartValues();
             final View scaledView = mResizedView;
@@ -622,10 +632,22 @@
     }
 
     /**
+     * Use this to abort any pending expansions in progress and force that there will be no
+     * animations.
+     */
+    public void cancelImmediately() {
+        cancel(false /* allowAnimation */);
+    }
+
+    /**
      * Use this to abort any pending expansions in progress.
      */
     public void cancel() {
-        finishExpanding(true /* forceAbort */, 0f /* velocity */);
+        cancel(true /* allowAnimation */);
+    }
+
+    private void cancel(boolean allowAnimation) {
+        finishExpanding(true /* forceAbort */, 0f /* velocity */, allowAnimation);
         clearView();
 
         // reset the gesture detector
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java b/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java
new file mode 100644
index 0000000..467ec2e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java
@@ -0,0 +1,118 @@
+/*
+ * 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;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+
+import com.android.settingslib.Utils;
+
+public class HardwareBgDrawable extends LayerDrawable {
+
+    private final Paint mPaint = new Paint();
+    private final Drawable[] mLayers;
+    private final boolean mRoundTop;
+    private int mPoint;
+    private boolean mRotatedBackground;
+
+    public HardwareBgDrawable(boolean roundTop, boolean roundEnd, Context context) {
+        this(roundTop, getLayers(context, roundTop, roundEnd));
+    }
+
+    public HardwareBgDrawable(boolean roundTop, Drawable[] layers) {
+        super(layers);
+        if (layers.length != 2) {
+            throw new IllegalArgumentException("Need 2 layers");
+        }
+        mRoundTop = roundTop;
+        mLayers = layers;
+    }
+
+    private static Drawable[] getLayers(Context context, boolean roundTop, boolean roundEnd) {
+        int drawable = roundEnd ? R.drawable.rounded_bg_full : R.drawable.rounded_bg;
+        final Drawable[] layers;
+        if (roundTop) {
+            layers = new Drawable[]{
+                    context.getDrawable(drawable).mutate(),
+                    context.getDrawable(drawable).mutate(),
+            };
+        } else {
+            layers = new Drawable[]{
+                    context.getDrawable(drawable).mutate(),
+                    context.getDrawable(roundEnd ? R.drawable.rounded_full_bg_bottom
+                            : R.drawable.rounded_bg_bottom).mutate(),
+            };
+        }
+        layers[1].setTint(Utils.getColorAttr(context, android.R.attr.colorPrimaryDark));
+        return layers;
+    }
+
+    public void setCutPoint(int point) {
+        mPoint = point;
+        invalidateSelf();
+    }
+
+    public int getCutPoint() {
+        return mPoint;
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        if (mPoint >= 0 && !mRotatedBackground) {
+            Rect bounds = getBounds();
+            int top = bounds.top + mPoint;
+            if (top > bounds.bottom) top = bounds.bottom;
+            if (mRoundTop) {
+                mLayers[0].setBounds(bounds.left, bounds.top, bounds.right, top);
+            } else {
+                mLayers[1].setBounds(bounds.left, top, bounds.right, bounds.bottom);
+            }
+            if (mRoundTop) {
+                mLayers[1].draw(canvas);
+                mLayers[0].draw(canvas);
+            } else {
+                mLayers[0].draw(canvas);
+                mLayers[1].draw(canvas);
+            }
+        } else {
+            mLayers[0].draw(canvas);
+        }
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        mPaint.setAlpha(alpha);
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter colorFilter) {
+        mPaint.setColorFilter(colorFilter);
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.OPAQUE;
+    }
+
+    public void setRotatedBackground(boolean rotatedBackground) {
+        mRotatedBackground = rotatedBackground;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
new file mode 100644
index 0000000..ca34345
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
@@ -0,0 +1,432 @@
+/*
+ * 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;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
+import android.view.ViewTreeObserver;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.tuner.TunerService.Tunable;
+import com.android.systemui.util.leak.RotationUtils;
+
+import java.util.ArrayList;
+
+import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE;
+import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE;
+import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE;
+
+public class HardwareUiLayout extends FrameLayout implements Tunable {
+
+    private static final String EDGE_BLEED = "sysui_hwui_edge_bleed";
+    private static final String ROUNDED_DIVIDER = "sysui_hwui_rounded_divider";
+    private final int[] mTmp2 = new int[2];
+    private View mChild;
+    private int mOldHeight;
+    private boolean mAnimating;
+    private AnimatorSet mAnimation;
+    private View mDivision;
+    private boolean mHasOutsideTouch;
+    private HardwareBgDrawable mBackground;
+    private Animator mAnimator;
+    private boolean mCollapse;
+    private int mEndPoint;
+    private boolean mEdgeBleed;
+    private boolean mRoundedDivider;
+    private int mRotation = ROTATION_NONE;
+    private boolean mRotatedBackground;
+
+    public HardwareUiLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        updateSettings();
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        updateSettings();
+        Dependency.get(TunerService.class).addTunable(this, EDGE_BLEED, ROUNDED_DIVIDER);
+        getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsListener);
+        Dependency.get(TunerService.class).removeTunable(this);
+    }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        updateSettings();
+    }
+
+    private void updateSettings() {
+        mEdgeBleed = Settings.Secure.getInt(getContext().getContentResolver(),
+                EDGE_BLEED, 0) != 0;
+        mRoundedDivider = Settings.Secure.getInt(getContext().getContentResolver(),
+                ROUNDED_DIVIDER, 1) != 0;
+        updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
+        mBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed, getContext());
+        if (mChild != null) {
+            mChild.setBackground(mBackground);
+            requestLayout();
+        }
+    }
+
+    private void updateEdgeMargin(int edge) {
+        if (mChild != null) {
+            MarginLayoutParams params = (MarginLayoutParams) mChild.getLayoutParams();
+            if (mRotation == ROTATION_LANDSCAPE) {
+                params.topMargin = edge;
+            } else if (mRotation == ROTATION_SEASCAPE) {
+                params.bottomMargin = edge;
+            } else {
+                params.rightMargin = edge;
+            }
+            mChild.setLayoutParams(params);
+        }
+    }
+
+    private int getEdgePadding() {
+        return getContext().getResources().getDimensionPixelSize(R.dimen.edge_margin);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        if (mChild == null) {
+            if (getChildCount() != 0) {
+                mChild = getChildAt(0);
+                mChild.setBackground(mBackground);
+                updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
+                mOldHeight = mChild.getMeasuredHeight();
+                mChild.addOnLayoutChangeListener(
+                        (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+                                updatePosition());
+                updateRotation();
+            } else {
+                return;
+            }
+        }
+        int newHeight = mChild.getMeasuredHeight();
+        if (newHeight != mOldHeight) {
+            animateChild(mOldHeight, newHeight);
+        }
+        post(() -> updatePosition());
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        updateRotation();
+    }
+
+    private void updateRotation() {
+        int rotation = RotationUtils.getRotation(getContext());
+        if (rotation != mRotation) {
+            rotate(mRotation, rotation);
+            mRotation = rotation;
+        }
+    }
+
+    private void rotate(int from, int to) {
+        if (from != ROTATION_NONE && to != ROTATION_NONE) {
+            // Rather than handling this confusing case, just do 2 rotations.
+            rotate(from, ROTATION_NONE);
+            rotate(ROTATION_NONE, to);
+            return;
+        }
+        if (from == ROTATION_LANDSCAPE || to == ROTATION_SEASCAPE) {
+            rotateRight();
+        } else {
+            rotateLeft();
+        }
+        if (to != ROTATION_NONE) {
+            if (mChild instanceof LinearLayout) {
+                mRotatedBackground = true;
+                mBackground.setRotatedBackground(true);
+                LinearLayout linearLayout = (LinearLayout) mChild;
+                if (to == ROTATION_SEASCAPE) {
+                    swapOrder(linearLayout);
+                }
+                linearLayout.setOrientation(LinearLayout.HORIZONTAL);
+                swapDimens(this.mChild);
+            }
+        } else {
+            if (mChild instanceof LinearLayout) {
+                mRotatedBackground = false;
+                mBackground.setRotatedBackground(false);
+                LinearLayout linearLayout = (LinearLayout) mChild;
+                if (from == ROTATION_SEASCAPE) {
+                    swapOrder(linearLayout);
+                }
+                linearLayout.setOrientation(LinearLayout.VERTICAL);
+                swapDimens(mChild);
+            }
+        }
+    }
+
+    private void swapOrder(LinearLayout linearLayout) {
+        ArrayList<View> children = new ArrayList<>();
+        for (int i = 0; i < linearLayout.getChildCount(); i++) {
+            children.add(0, linearLayout.getChildAt(0));
+            linearLayout.removeViewAt(0);
+        }
+        children.forEach(v -> linearLayout.addView(v));
+    }
+
+    private void rotateRight() {
+        rotateRight(this);
+        rotateRight(mChild);
+        swapDimens(this);
+
+        LayoutParams p = (LayoutParams) mChild.getLayoutParams();
+        p.gravity = rotateGravityRight(p.gravity);
+        mChild.setLayoutParams(p);
+    }
+
+    private void swapDimens(View v) {
+        ViewGroup.LayoutParams params = v.getLayoutParams();
+        int h = params.width;
+        params.width = params.height;
+        params.height = h;
+        v.setLayoutParams(params);
+    }
+
+    private int rotateGravityRight(int gravity) {
+        int retGravity = 0;
+        int layoutDirection = getLayoutDirection();
+        final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
+        final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+
+        switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+            case Gravity.CENTER_HORIZONTAL:
+                retGravity |= Gravity.CENTER_VERTICAL;
+                break;
+            case Gravity.RIGHT:
+                retGravity |= Gravity.BOTTOM;
+                break;
+            case Gravity.LEFT:
+            default:
+                retGravity |= Gravity.TOP;
+                break;
+        }
+
+        switch (verticalGravity) {
+            case Gravity.CENTER_VERTICAL:
+                retGravity |= Gravity.CENTER_HORIZONTAL;
+                break;
+            case Gravity.BOTTOM:
+                retGravity |= Gravity.LEFT;
+                break;
+            case Gravity.TOP:
+            default:
+                retGravity |= Gravity.RIGHT;
+                break;
+        }
+        return retGravity;
+    }
+
+    private void rotateLeft() {
+        rotateLeft(this);
+        rotateLeft(mChild);
+        swapDimens(this);
+
+        LayoutParams p = (LayoutParams) mChild.getLayoutParams();
+        p.gravity = rotateGravityLeft(p.gravity);
+        mChild.setLayoutParams(p);
+    }
+
+    private int rotateGravityLeft(int gravity) {
+        if (gravity == -1) {
+            gravity = Gravity.TOP | Gravity.START;
+        }
+        int retGravity = 0;
+        int layoutDirection = getLayoutDirection();
+        final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
+        final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+
+        switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+            case Gravity.CENTER_HORIZONTAL:
+                retGravity |= Gravity.CENTER_VERTICAL;
+                break;
+            case Gravity.RIGHT:
+                retGravity |= Gravity.TOP;
+                break;
+            case Gravity.LEFT:
+            default:
+                retGravity |= Gravity.BOTTOM;
+                break;
+        }
+
+        switch (verticalGravity) {
+            case Gravity.CENTER_VERTICAL:
+                retGravity |= Gravity.CENTER_HORIZONTAL;
+                break;
+            case Gravity.BOTTOM:
+                retGravity |= Gravity.RIGHT;
+                break;
+            case Gravity.TOP:
+            default:
+                retGravity |= Gravity.LEFT;
+                break;
+        }
+        return retGravity;
+    }
+
+    private void rotateLeft(View v) {
+        v.setPadding(v.getPaddingTop(), v.getPaddingRight(), v.getPaddingBottom(),
+                v.getPaddingLeft());
+        MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
+        params.setMargins(params.topMargin, params.rightMargin, params.bottomMargin,
+                params.leftMargin);
+        v.setLayoutParams(params);
+    }
+
+    private void rotateRight(View v) {
+        v.setPadding(v.getPaddingBottom(), v.getPaddingLeft(), v.getPaddingTop(),
+                v.getPaddingRight());
+        MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
+        params.setMargins(params.bottomMargin, params.leftMargin, params.topMargin,
+                params.rightMargin);
+        v.setLayoutParams(params);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        post(() -> updatePosition());
+    }
+
+    private void animateChild(int oldHeight, int newHeight) {
+        if (true) return;
+        if (mAnimating) {
+            mAnimation.cancel();
+        }
+        mAnimating = true;
+        mAnimation = new AnimatorSet();
+        mAnimation.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mAnimating = false;
+            }
+        });
+        int fromTop = mChild.getTop();
+        int fromBottom = mChild.getBottom();
+        int toTop = fromTop - ((newHeight - oldHeight) / 2);
+        int toBottom = fromBottom + ((newHeight - oldHeight) / 2);
+        ObjectAnimator top = ObjectAnimator.ofInt(mChild, "top", fromTop, toTop);
+        top.addUpdateListener(animation -> mBackground.invalidateSelf());
+        mAnimation.playTogether(top,
+                ObjectAnimator.ofInt(mChild, "bottom", fromBottom, toBottom));
+    }
+
+    public void setDivisionView(View v) {
+        mDivision = v;
+        if (mDivision != null) {
+            mDivision.addOnLayoutChangeListener(
+                    (v1, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+                            updatePosition());
+        }
+        updatePosition();
+    }
+
+    private void updatePosition() {
+        if (mChild == null) return;
+        if (mDivision != null && mDivision.getVisibility() == VISIBLE) {
+            int index = mRotatedBackground ? 0 : 1;
+            mDivision.getLocationOnScreen(mTmp2);
+            float trans = mRotatedBackground ? mDivision.getTranslationX()
+                    : mDivision.getTranslationY();
+            int viewTop = (int) (mTmp2[index] + trans);
+            mChild.getLocationOnScreen(mTmp2);
+            viewTop -= mTmp2[index];
+            setCutPoint(viewTop);
+        } else {
+            setCutPoint(mChild.getMeasuredHeight());
+        }
+    }
+
+    private void setCutPoint(int point) {
+        int curPoint = mBackground.getCutPoint();
+        if (curPoint == point) return;
+        if (getAlpha() == 0 || curPoint == 0) {
+            mBackground.setCutPoint(point);
+            return;
+        }
+        if (mAnimator != null) {
+            if (mEndPoint == point) {
+                return;
+            }
+            mAnimator.cancel();
+        }
+        mEndPoint = point;
+        mAnimator = ObjectAnimator.ofInt(mBackground, "cutPoint", curPoint, point);
+        if (mCollapse) {
+            mAnimator.setStartDelay(300);
+            mCollapse = false;
+        }
+        mAnimator.start();
+    }
+
+    @Override
+    public ViewOutlineProvider getOutlineProvider() {
+        return super.getOutlineProvider();
+    }
+
+    public void setOutsideTouchListener(OnClickListener onClickListener) {
+        mHasOutsideTouch = true;
+        requestLayout();
+        setOnClickListener(onClickListener);
+        setClickable(true);
+        setFocusable(true);
+    }
+
+    public void setCollapse() {
+        mCollapse = true;
+    }
+
+    public static HardwareUiLayout get(View v) {
+        if (v instanceof HardwareUiLayout) return (HardwareUiLayout) v;
+        if (v.getParent() instanceof View) {
+            return get((View) v.getParent());
+        }
+        return null;
+    }
+
+    private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener = inoutInfo -> {
+        if (mHasOutsideTouch || (mChild == null)) {
+            inoutInfo.setTouchableInsets(
+                    ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
+            return;
+        }
+        inoutInfo.setTouchableInsets(
+                ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT);
+        inoutInfo.contentInsets.set(mChild.getLeft(), mChild.getTop(),
+                0, getBottom() - mChild.getBottom());
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 9a4179f..907a79e 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -199,7 +199,7 @@
             // Load background image dimensions, if we haven't saved them yet
             if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) {
                 // Need to load the image to get dimensions
-                loadWallpaper(forDraw, true /* needsReset */);
+                loadWallpaper(forDraw, false /* needsReset */);
                 if (DEBUG) {
                     Log.d(TAG, "Reloading, redoing updateSurfaceSize later.");
                 }
@@ -405,17 +405,17 @@
                     }
                 } else {
                     drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
+                    if (FIXED_SIZED_SURFACE) {
+                        // If the surface is fixed-size, we should only need to
+                        // draw it once and then we'll let the window manager
+                        // position it appropriately.  As such, we no longer needed
+                        // the loaded bitmap.  Yay!
+                        // hw-accelerated renderer retains bitmap for faster rotation
+                        unloadWallpaper(false /* forgetSize */);
+                    }
                 }
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_VIEW);
-                if (FIXED_SIZED_SURFACE && !mIsHwAccelerated) {
-                    // If the surface is fixed-size, we should only need to
-                    // draw it once and then we'll let the window manager
-                    // position it appropriately.  As such, we no longer needed
-                    // the loaded bitmap.  Yay!
-                    // hw-accelerated renderer retains bitmap for faster rotation
-                    unloadWallpaper(false /* forgetSize */);
-                }
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index 3cc81df..4437d31 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -47,6 +47,7 @@
         Key.QS_INVERT_COLORS_ADDED,
         Key.QS_WORK_ADDED,
         Key.QS_NIGHTDISPLAY_ADDED,
+        Key.SEEN_MULTI_USER,
     })
     public @interface Key {
         @Deprecated
@@ -62,12 +63,18 @@
         String DND_FAVORITE_BUCKET_INDEX = "DndCountdownMinuteIndex";
         String DND_NONE_SELECTED = "DndNoneSelected";
         String DND_FAVORITE_ZEN = "DndFavoriteZen";
-        String QS_HOTSPOT_ADDED = "QsHotspotAdded";
-        String QS_DATA_SAVER_ADDED = "QsDataSaverAdded";
         String QS_DATA_SAVER_DIALOG_SHOWN = "QsDataSaverDialogShown";
+        @Deprecated
+        String QS_HOTSPOT_ADDED = "QsHotspotAdded";
+        @Deprecated
+        String QS_DATA_SAVER_ADDED = "QsDataSaverAdded";
+        @Deprecated
         String QS_INVERT_COLORS_ADDED = "QsInvertColorsAdded";
+        @Deprecated
         String QS_WORK_ADDED = "QsWorkAdded";
+        @Deprecated
         String QS_NIGHTDISPLAY_ADDED = "QsNightDisplayAdded";
+        String SEEN_MULTI_USER = "HasSeenMultiUser";
     }
 
     public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
diff --git a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
new file mode 100644
index 0000000..f7936b6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
@@ -0,0 +1,220 @@
+/*
+ * 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;
+
+import static com.android.systemui.tuner.TunablePadding.FLAG_START;
+import static com.android.systemui.tuner.TunablePadding.FLAG_END;
+
+import android.app.Fragment;
+import android.content.res.ColorStateList;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.provider.Settings.Secure;
+import android.support.annotation.VisibleForTesting;
+import android.util.DisplayMetrics;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnLayoutChangeListener;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.view.WindowManager;
+import android.widget.ImageView;
+
+import com.android.systemui.R.id;
+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.SecureSetting;
+import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
+import com.android.systemui.statusbar.phone.NavigationBarFragment;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.tuner.TunablePadding;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+public class RoundedCorners extends SystemUI implements Tunable {
+    public static final String SIZE = "sysui_rounded_size";
+    public static final String PADDING = "sysui_rounded_content_padding";
+
+    private int mRoundedDefault;
+    private View mOverlay;
+    private View mBottomOverlay;
+    private float mDensity;
+    private TunablePadding mQsPadding;
+    private TunablePadding mStatusBarPadding;
+    private TunablePadding mNavBarPadding;
+
+    @Override
+    public void start() {
+        mRoundedDefault = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_radius);
+        if (mRoundedDefault != 0) {
+            setupRounding();
+        }
+        int padding = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_content_padding);
+        if (padding != 0) {
+            setupPadding(padding);
+        }
+    }
+
+    private void setupRounding() {
+        mOverlay = LayoutInflater.from(mContext)
+                .inflate(R.layout.rounded_corners, null);
+        mOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+        mOverlay.setAlpha(0);
+        mOverlay.findViewById(R.id.right).setRotation(90);
+
+        mContext.getSystemService(WindowManager.class)
+                .addView(mOverlay, getWindowLayoutParams());
+        mBottomOverlay = LayoutInflater.from(mContext)
+                .inflate(R.layout.rounded_corners, null);
+        mBottomOverlay.setAlpha(0);
+        mBottomOverlay.findViewById(R.id.right).setRotation(180);
+        mBottomOverlay.findViewById(R.id.left).setRotation(270);
+        WindowManager.LayoutParams layoutParams = getWindowLayoutParams();
+        layoutParams.gravity = Gravity.BOTTOM;
+        mContext.getSystemService(WindowManager.class)
+                .addView(mBottomOverlay, layoutParams);
+
+        DisplayMetrics metrics = new DisplayMetrics();
+        mContext.getSystemService(WindowManager.class)
+                .getDefaultDisplay().getMetrics(metrics);
+        mDensity = metrics.density;
+
+        Dependency.get(TunerService.class).addTunable(this, SIZE);
+
+        // Watch color inversion and invert the overlay as needed.
+        SecureSetting setting = new SecureSetting(mContext, Dependency.get(Dependency.MAIN_HANDLER),
+                Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) {
+            @Override
+            protected void handleValueChanged(int value, boolean observedChange) {
+                int tint = value != 0 ? Color.WHITE : Color.BLACK;
+                ColorStateList tintList = ColorStateList.valueOf(tint);
+                ((ImageView) mOverlay.findViewById(id.left)).setImageTintList(tintList);
+                ((ImageView) mOverlay.findViewById(id.right)).setImageTintList(tintList);
+                ((ImageView) mBottomOverlay.findViewById(id.left)).setImageTintList(tintList);
+                ((ImageView) mBottomOverlay.findViewById(id.right)).setImageTintList(tintList);
+            }
+        };
+        setting.setListening(true);
+        setting.onChange(false);
+
+        mOverlay.addOnLayoutChangeListener(new OnLayoutChangeListener() {
+            @Override
+            public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                    int oldLeft,
+                    int oldTop, int oldRight, int oldBottom) {
+                mOverlay.removeOnLayoutChangeListener(this);
+                mOverlay.animate()
+                        .alpha(1)
+                        .setDuration(1000)
+                        .start();
+                mBottomOverlay.animate()
+                        .alpha(1)
+                        .setDuration(1000)
+                        .start();
+            }
+        });
+    }
+
+    private void setupPadding(int padding) {
+        // Add some padding to all the content near the edge of the screen.
+        StatusBar sb = getComponent(StatusBar.class);
+        View statusBar = sb.getStatusBarWindow();
+
+        TunablePadding.addTunablePadding(statusBar.findViewById(R.id.keyguard_header), PADDING,
+                padding, FLAG_END);
+
+        FragmentHostManager fragmentHostManager = FragmentHostManager.get(statusBar);
+        fragmentHostManager.addTagListener(CollapsedStatusBarFragment.TAG,
+                new TunablePaddingTagListener(padding, R.id.status_bar));
+        fragmentHostManager.addTagListener(QS.TAG,
+                new TunablePaddingTagListener(padding, R.id.header));
+    }
+
+    private WindowManager.LayoutParams getWindowLayoutParams() {
+        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                LayoutParams.WRAP_CONTENT,
+                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+                0
+                    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+                    | WindowManager.LayoutParams.FLAG_SLIPPERY
+                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
+                ,
+                PixelFormat.TRANSLUCENT);
+        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS
+                | WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
+        lp.setTitle("RoundedOverlay");
+        lp.gravity = Gravity.TOP;
+        return lp;
+    }
+
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        if (mOverlay == null) return;
+        if (SIZE.equals(key)) {
+            int size = mRoundedDefault;
+            try {
+                size = (int) (Integer.parseInt(newValue) * mDensity);
+            } catch (Exception e) {
+            }
+            setSize(mOverlay.findViewById(R.id.left), size);
+            setSize(mOverlay.findViewById(R.id.right), size);
+            setSize(mBottomOverlay.findViewById(R.id.left), size);
+            setSize(mBottomOverlay.findViewById(R.id.right), size);
+        }
+    }
+
+    private void setSize(View view, int pixelSize) {
+        LayoutParams params = view.getLayoutParams();
+        params.width = pixelSize;
+        params.height = pixelSize;
+        view.setLayoutParams(params);
+    }
+
+    @VisibleForTesting
+    static class TunablePaddingTagListener implements FragmentListener {
+
+        private final int mPadding;
+        private final int mId;
+        private TunablePadding mTunablePadding;
+
+        public TunablePaddingTagListener(int padding, int id) {
+            mPadding = padding;
+            mId = id;
+        }
+
+        @Override
+        public void onFragmentViewCreated(String tag, Fragment fragment) {
+            if (mTunablePadding != null) {
+                mTunablePadding.destroy();
+            }
+            View view = fragment.getView();
+            if (mId != 0) {
+                view = view.findViewById(mId);
+            }
+            mTunablePadding = TunablePadding.addTunablePadding(view, PADDING, mPadding,
+                    FLAG_START | FLAG_END);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 74b745f..699fdef 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -22,6 +22,7 @@
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.RectF;
 import android.os.Handler;
 import android.util.Log;
@@ -30,7 +31,6 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.accessibility.AccessibilityEvent;
-
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
@@ -82,6 +82,7 @@
     private float mDensityScale;
     private float mTranslation = 0;
 
+    private boolean mMenuRowIntercepting;
     private boolean mLongPressSent;
     private LongPressListener mLongPressListener;
     private Runnable mWatchLongPress;
@@ -91,6 +92,7 @@
     private int mFalsingThreshold;
     private boolean mTouchAboveFalsingThreshold;
     private boolean mDisableHwLayers;
+    private boolean mFadeDependingOnAmountSwiped;
     private Context mContext;
 
     private HashMap<View, Animator> mDismissPendingMap = new HashMap<>();
@@ -101,12 +103,15 @@
         mHandler = new Handler();
         mSwipeDirection = swipeDirection;
         mVelocityTracker = VelocityTracker.obtain();
-        mDensityScale =  context.getResources().getDisplayMetrics().density;
         mPagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop();
 
-        mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f); // extra long-press!
-        mFalsingThreshold = context.getResources().getDimensionPixelSize(
-                R.dimen.swipe_helper_falsing_threshold);
+        // Extra long-press!
+        mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f);
+
+        Resources res = context.getResources();
+        mDensityScale =  res.getDisplayMetrics().density;
+        mFalsingThreshold = res.getDimensionPixelSize(R.dimen.swipe_helper_falsing_threshold);
+        mFadeDependingOnAmountSwiped = res.getBoolean(R.bool.config_fadeDependingOnAmountSwiped);
         mFalsingManager = FalsingManager.getInstance(context);
         mFlingAnimationUtils = new FlingAnimationUtils(context, getMaxEscapeAnimDuration() / 1000f);
     }
@@ -176,8 +181,7 @@
     }
 
     protected float getSize(View v) {
-        return mSwipeDirection == X ? v.getMeasuredWidth() :
-                v.getMeasuredHeight();
+        return mSwipeDirection == X ? v.getMeasuredWidth() : v.getMeasuredHeight();
     }
 
     public void setMinSwipeProgress(float minSwipeProgress) {
@@ -195,6 +199,11 @@
     }
 
     private float getSwipeAlpha(float progress) {
+        if (mFadeDependingOnAmountSwiped) {
+            // The more progress has been fade, the lower the alpha value so that the view fades.
+            return Math.max(1 - progress, 0);
+        }
+
         return Math.min(0, Math.max(1, progress / SWIPE_PROGRESS_FADE_END));
     }
 
@@ -207,9 +216,8 @@
         float swipeProgress = getSwipeProgressForOffset(animView, translation);
         if (!mCallback.updateSwipeProgress(animView, dismissable, swipeProgress)) {
             if (FADE_OUT_DURING_SWIPE && dismissable) {
-                float alpha = swipeProgress;
                 if (!mDisableHwLayers) {
-                    if (alpha != 0f && alpha != 1f) {
+                    if (swipeProgress != 0f && swipeProgress != 1f) {
                         animView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
                     } else {
                         animView.setLayerType(View.LAYER_TYPE_NONE, null);
@@ -259,6 +267,10 @@
 
     @Override
     public boolean onInterceptTouchEvent(final MotionEvent ev) {
+        if (mCurrView instanceof ExpandableNotificationRow) {
+            NotificationMenuRowPlugin nmr = ((ExpandableNotificationRow) mCurrView).getProvider();
+            mMenuRowIntercepting = nmr.onInterceptTouchEvent(mCurrView, ev);
+        }
         final int action = ev.getAction();
 
         switch (action) {
@@ -294,7 +306,10 @@
                                             menuItem = ((ExpandableNotificationRow) mCurrView)
                                                     .getProvider().getLongpressMenuItem(mContext);
                                         }
-                                        mLongPressListener.onLongPress(mCurrView, x, y, menuItem);
+                                        if (menuItem != null) {
+                                            mLongPressListener.onLongPress(mCurrView, x, y,
+                                                    menuItem);
+                                        }
                                     }
                                 }
                             };
@@ -324,15 +339,16 @@
 
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_CANCEL:
-                final boolean captured = (mDragging || mLongPressSent);
+                final boolean captured = (mDragging || mLongPressSent || mMenuRowIntercepting);
                 mDragging = false;
                 mCurrView = null;
                 mLongPressSent = false;
+                mMenuRowIntercepting = false;
                 removeLongPressCallback();
                 if (captured) return true;
                 break;
         }
-        return mDragging || mLongPressSent;
+        return mDragging || mLongPressSent || mMenuRowIntercepting;
     }
 
     /**
@@ -551,11 +567,11 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
-        if (mLongPressSent) {
+        if (mLongPressSent && !mMenuRowIntercepting) {
             return true;
         }
 
-        if (!mDragging) {
+        if (!mDragging && !mMenuRowIntercepting) {
             if (mCallback.getChildAtPosition(ev) != null) {
 
                 // We are dragging directly over a card, make sure that we also catch the gesture
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 0eb469f..9f2dcd9 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui;
 
+import android.app.Activity;
 import android.app.ActivityThread;
 import android.app.Application;
 import android.content.BroadcastReceiver;
@@ -39,6 +40,7 @@
 import com.android.systemui.plugins.GlobalActions;
 import com.android.systemui.plugins.OverlayPlugin;
 import com.android.systemui.plugins.Plugin;
+import com.android.systemui.plugins.PluginActivityManager;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.power.PowerUI;
@@ -87,6 +89,7 @@
             GarbageMonitor.Service.class,
             LatencyTester.class,
             GlobalActionsComponent.class,
+            RoundedCorners.class,
     };
 
     /**
@@ -113,7 +116,7 @@
         // Set the application theme that is inherited by all services. Note that setting the
         // application theme in the manifest does only work for activities. Keep this in sync with
         // the theme set there.
-        setTheme(R.style.systemui_theme);
+        setTheme(R.style.Theme_SystemUI);
 
         SystemUIFactory.createFromConfig(this);
 
@@ -265,4 +268,10 @@
     public SystemUI[] getServices() {
         return mServices;
     }
+
+    @Override
+    public Activity instantiateActivity(ClassLoader cl, String className, Intent intent) {
+        if (!mServicesStarted) return null;
+        return Dependency.get(PluginActivityManager.class).instantiate(cl, className, intent);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 5237244..0c067ff 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -40,6 +40,8 @@
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.volume.VolumeDialogControllerImpl;
 
+import java.util.function.Consumer;
+
 /**
  * Class factory to provide customizable SystemUI components.
  */
@@ -84,8 +86,10 @@
 
     public ScrimController createScrimController(LightBarController lightBarController,
             ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim,
-            LockscreenWallpaper lockscreenWallpaper) {
-        return new ScrimController(lightBarController, scrimBehind, scrimInFront, headsUpScrim);
+            LockscreenWallpaper lockscreenWallpaper,
+            Consumer<Boolean> scrimVisibleListener) {
+        return new ScrimController(lightBarController, scrimBehind, scrimInFront, headsUpScrim,
+                scrimVisibleListener);
     }
 
     public NotificationIconAreaController createNotificationIconAreaController(Context context,
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
index 8506734..e4b405f 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
@@ -34,8 +34,8 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.UiOffloadThread;
 import com.android.systemui.analytics.DataCollector;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.util.AsyncSensorManager;
 
 import java.io.PrintWriter;
 
@@ -76,6 +76,7 @@
     private boolean mSessionActive = false;
     private int mState = StatusBarState.SHADE;
     private boolean mScreenOn;
+    private boolean mShowingAod;
     private Runnable mPendingWtf;
 
     protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
@@ -87,7 +88,7 @@
 
     private FalsingManager(Context context) {
         mContext = context;
-        mSensorManager = mContext.getSystemService(SensorManager.class);
+        mSensorManager = Dependency.get(AsyncSensorManager.class);
         mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
         mDataCollector = DataCollector.getInstance(mContext);
         mHumanInteractionClassifier = HumanInteractionClassifier.getInstance(mContext);
@@ -122,7 +123,7 @@
                     .append(" mState=").append(StatusBarState.toShortString(mState))
                     .toString()
             );
-        return isEnabled() && mScreenOn && (mState == StatusBarState.KEYGUARD);
+        return isEnabled() && mScreenOn && (mState == StatusBarState.KEYGUARD) && !mShowingAod;
     }
 
     private boolean sessionEntrypoint() {
@@ -144,6 +145,14 @@
         }
     }
 
+    public void updateSessionActive() {
+        if (shouldSessionBeActive()) {
+            sessionEntrypoint();
+        } else {
+            sessionExitpoint(false /* force */);
+        }
+    }
+
     private void onSessionStart() {
         if (FalsingLog.ENABLED) {
             FalsingLog.i("onSessionStart", "classifierEnabled=" + isClassiferEnabled());
@@ -249,6 +258,11 @@
         return mEnforceBouncer;
     }
 
+    public void setShowingAod(boolean showingAod) {
+        mShowingAod = showingAod;
+        updateSessionActive();
+    }
+
     public void setStatusBarState(int state) {
         if (FalsingLog.ENABLED) {
             FalsingLog.i("setStatusBarState", new StringBuilder()
@@ -257,11 +271,7 @@
                     .toString());
         }
         mState = state;
-        if (shouldSessionBeActive()) {
-            sessionEntrypoint();
-        } else {
-            sessionExitpoint(false /* force */);
-        }
+        updateSessionActive();
     }
 
     public void onScreenTurningOn() {
diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
new file mode 100644
index 0000000..34c05a5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
@@ -0,0 +1,194 @@
+/*
+ * 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.colorextraction;
+
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.util.Log;
+import android.view.Display;
+import android.view.IWallpaperVisibilityListener;
+import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.types.ExtractionType;
+import com.android.internal.colorextraction.types.Tonal;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.Dumpable;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Arrays;
+
+/**
+ * ColorExtractor aware of wallpaper visibility
+ */
+public class SysuiColorExtractor extends ColorExtractor implements Dumpable {
+    private static final String TAG = "SysuiColorExtractor";
+    private boolean mWallpaperVisible;
+    // Colors to return when the wallpaper isn't visible
+    private final GradientColors mWpHiddenColors;
+
+    public SysuiColorExtractor(Context context) {
+        this(context, new Tonal(context), true);
+    }
+
+    @VisibleForTesting
+    public SysuiColorExtractor(Context context, ExtractionType type, boolean registerVisibility) {
+        super(context, type);
+        mWpHiddenColors = new GradientColors();
+
+        WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+        updateDefaultGradients(systemColors);
+
+        if (registerVisibility) {
+            try {
+                IWindowManager windowManagerService = WindowManagerGlobal.getWindowManagerService();
+                Handler handler = Handler.getMain();
+                boolean visible = windowManagerService.registerWallpaperVisibilityListener(
+                        new IWallpaperVisibilityListener.Stub() {
+                            @Override
+                            public void onWallpaperVisibilityChanged(boolean newVisibility,
+                                    int displayId) throws RemoteException {
+                                handler.post(() -> setWallpaperVisible(newVisibility));
+                            }
+                        }, Display.DEFAULT_DISPLAY);
+                setWallpaperVisible(visible);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Can't listen to wallpaper visibility changes", e);
+            }
+        }
+
+        WallpaperManager wallpaperManager = context.getSystemService(WallpaperManager.class);
+        if (wallpaperManager != null) {
+            // Listen to all users instead of only the current one.
+            wallpaperManager.removeOnColorsChangedListener(this);
+            wallpaperManager.addOnColorsChangedListener(this, null /* handler */,
+                    UserHandle.USER_ALL);
+        }
+    }
+
+    private void updateDefaultGradients(WallpaperColors colors) {
+        Tonal.applyFallback(colors, mWpHiddenColors);
+    }
+
+    @Override
+    public void onColorsChanged(WallpaperColors colors, int which, int userId) {
+        if (userId != KeyguardUpdateMonitor.getCurrentUser()) {
+            // Colors do not belong to current user, ignoring.
+            return;
+        }
+
+        super.onColorsChanged(colors, which);
+
+        if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
+            updateDefaultGradients(colors);
+        }
+    }
+
+    @VisibleForTesting
+    GradientColors getFallbackColors() {
+        return mWpHiddenColors;
+    }
+
+    /**
+     * Get TYPE_NORMAL colors when wallpaper is visible, or fallback otherwise.
+     *
+     * @param which FLAG_LOCK or FLAG_SYSTEM
+     * @return colors
+     */
+    @Override
+    public GradientColors getColors(int which) {
+        return getColors(which, TYPE_DARK);
+    }
+
+    /**
+     * Wallpaper colors when the wallpaper is visible, fallback otherwise.
+     *
+     * @param which FLAG_LOCK or FLAG_SYSTEM
+     * @param type TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK
+     * @return colors
+     */
+    @Override
+    public GradientColors getColors(int which, int type) {
+        return getColors(which, type, false /* ignoreVisibility */);
+    }
+
+    /**
+     * Get TYPE_NORMAL colors, possibly ignoring wallpaper visibility.
+     *
+     * @param which FLAG_LOCK or FLAG_SYSTEM
+     * @param ignoreWallpaperVisibility whether you want fallback colors or not if the wallpaper
+     *                                  isn't visible
+     * @return
+     */
+    public GradientColors getColors(int which, boolean ignoreWallpaperVisibility) {
+        return getColors(which, TYPE_NORMAL, ignoreWallpaperVisibility);
+    }
+
+    /**
+     *
+     * @param which FLAG_LOCK or FLAG_SYSTEM
+     * @param type TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK
+     * @param ignoreWallpaperVisibility true if true wallpaper colors should be returning
+     *                                  if it's visible or not
+     * @return colors
+     */
+    public GradientColors getColors(int which, int type, boolean ignoreWallpaperVisibility) {
+        // mWallpaperVisible only handles the "system wallpaper" and will be always set to false
+        // if we have different lock and system wallpapers.
+        if (which == WallpaperManager.FLAG_LOCK) {
+            ignoreWallpaperVisibility = true;
+        }
+        if (mWallpaperVisible || ignoreWallpaperVisibility) {
+            return super.getColors(which, type);
+        } else {
+            return mWpHiddenColors;
+        }
+    }
+
+    @VisibleForTesting
+    void setWallpaperVisible(boolean visible) {
+        if (mWallpaperVisible != visible) {
+            mWallpaperVisible = visible;
+            triggerColorsChanged(WallpaperManager.FLAG_SYSTEM);
+        }
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("SysuiColorExtractor:");
+
+        pw.println("  Current wallpaper colors:");
+        pw.println("    system: " + mSystemColors);
+        pw.println("    lock: " + mLockColors);
+
+        GradientColors[] system = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
+        GradientColors[] lock = mGradientColors.get(WallpaperManager.FLAG_LOCK);
+        pw.println("  Gradients:");
+        pw.println("    system: " + Arrays.toString(system));
+        pw.println("    lock: " + Arrays.toString(lock));
+        pw.println("  Default scrim: " + mWpHiddenColors);
+
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeBrightnessHostForwarder.java b/packages/SystemUI/src/com/android/systemui/doze/DozeBrightnessHostForwarder.java
new file mode 100644
index 0000000..0aeb128
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeBrightnessHostForwarder.java
@@ -0,0 +1,36 @@
+/*
+ * 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.doze;
+
+/**
+ * Forwards the currently used brightness to {@link DozeHost}.
+ */
+public class DozeBrightnessHostForwarder extends DozeMachine.Service.Delegate {
+
+    private final DozeHost mHost;
+
+    public DozeBrightnessHostForwarder(DozeMachine.Service wrappedService, DozeHost host) {
+        super(wrappedService);
+        mHost = host;
+    }
+
+    @Override
+    public void setDozeScreenBrightness(int brightness) {
+        super.setDozeScreenBrightness(brightness);
+        mHost.setDozeScreenBrightness(brightness);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index eea09df..d374d68 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -19,12 +19,18 @@
 import android.app.AlarmManager;
 import android.app.Application;
 import android.content.Context;
+import android.hardware.Sensor;
 import android.hardware.SensorManager;
 import android.os.Handler;
 
 import com.android.internal.hardware.AmbientDisplayConfiguration;
+import com.android.systemui.Dependency;
+import com.android.systemui.R;
 import com.android.systemui.SystemUIApplication;
+import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.util.AsyncSensorManager;
+import com.android.systemui.util.wakelock.DelayedWakeLock;
 import com.android.systemui.util.wakelock.WakeLock;
 
 public class DozeFactory {
@@ -35,33 +41,49 @@
     /** Creates a DozeMachine with its parts for {@code dozeService}. */
     public DozeMachine assembleMachine(DozeService dozeService) {
         Context context = dozeService;
-        SensorManager sensorManager = context.getSystemService(SensorManager.class);
+        SensorManager sensorManager = Dependency.get(AsyncSensorManager.class);
         AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
 
         DozeHost host = getHost(dozeService);
         AmbientDisplayConfiguration config = new AmbientDisplayConfiguration(context);
         DozeParameters params = new DozeParameters(context);
         Handler handler = new Handler();
-        WakeLock wakeLock = WakeLock.createPartial(context, "Doze");
+        WakeLock wakeLock = new DelayedWakeLock(handler,
+                WakeLock.createPartial(context, "Doze"));
 
-        DozeMachine machine = new DozeMachine(
-                DozeScreenStatePreventingAdapter.wrapIfNeeded(dozeService, params),
-                config,
-                wakeLock);
+        DozeMachine.Service wrappedService = dozeService;
+        wrappedService = new DozeBrightnessHostForwarder(wrappedService, host);
+        wrappedService = DozeScreenStatePreventingAdapter.wrapIfNeeded(wrappedService, params);
+        wrappedService = DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(wrappedService,
+                params);
+
+        DozeMachine machine = new DozeMachine(wrappedService, config, wakeLock);
         machine.setParts(new DozeMachine.Part[]{
-                createDozeTriggers(context, sensorManager, host, config, params, handler, wakeLock,
-                        machine),
+                new DozePauser(handler, machine, alarmManager),
+                new DozeFalsingManagerAdapter(FalsingManager.getInstance(context)),
+                createDozeTriggers(context, sensorManager, host, alarmManager, config, params,
+                        handler, wakeLock, machine),
                 createDozeUi(context, host, wakeLock, machine, handler, alarmManager),
+                new DozeScreenState(wrappedService, handler),
+                createDozeScreenBrightness(context, wrappedService, sensorManager, host, handler),
         });
 
         return machine;
     }
 
+    private DozeMachine.Part createDozeScreenBrightness(Context context,
+            DozeMachine.Service service, SensorManager sensorManager, DozeHost host,
+            Handler handler) {
+        Sensor sensor = DozeSensors.findSensorWithType(sensorManager,
+                context.getString(R.string.doze_brightness_sensor_type));
+        return new DozeScreenBrightness(context, service, sensorManager, sensor, host, handler);
+    }
+
     private DozeTriggers createDozeTriggers(Context context, SensorManager sensorManager,
-            DozeHost host, AmbientDisplayConfiguration config, DozeParameters params,
-            Handler handler, WakeLock wakeLock, DozeMachine machine) {
+            DozeHost host, AlarmManager alarmManager, AmbientDisplayConfiguration config,
+            DozeParameters params, Handler handler, WakeLock wakeLock, DozeMachine machine) {
         boolean allowPulseTriggers = true;
-        return new DozeTriggers(context, machine, host, config, params,
+        return new DozeTriggers(context, machine, host, alarmManager, config, params,
                 sensorManager, handler, wakeLock, allowPulseTriggers);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFalsingManagerAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFalsingManagerAdapter.java
new file mode 100644
index 0000000..00ca9a4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFalsingManagerAdapter.java
@@ -0,0 +1,47 @@
+/*
+ * 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.doze;
+
+import com.android.systemui.classifier.FalsingManager;
+
+/**
+ * Notifies FalsingManager of whether or not AOD is showing.
+ */
+public class DozeFalsingManagerAdapter implements DozeMachine.Part {
+
+    private final FalsingManager mFalsingManager;
+
+    public DozeFalsingManagerAdapter(FalsingManager falsingManager) {
+        mFalsingManager = falsingManager;
+    }
+
+    @Override
+    public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+        mFalsingManager.setShowingAod(isAodMode(newState));
+    }
+
+    private boolean isAodMode(DozeMachine.State state) {
+        switch (state) {
+            case DOZE_AOD:
+            case DOZE_AOD_PAUSING:
+            case DOZE_AOD_PAUSED:
+                return true;
+            default:
+                return false;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 3e424d0..7db118d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -31,6 +31,8 @@
     void dozeTimeTick();
     boolean isPowerSaveActive();
     boolean isPulsingBlocked();
+    boolean isProvisioned();
+    boolean isBlockingDoze();
 
     void startPendingIntentDismissingKeyguard(PendingIntent intent);
     void abortPulsing();
@@ -38,6 +40,13 @@
 
     void setAnimateWakeup(boolean animateWakeup);
 
+    void onDoubleTap(float x, float y);
+
+    default void setAodDimmingScrim(float scrimOpacity) {}
+    void setDozeScreenBrightness(int value);
+
+    void onIgnoreTouchWhilePulsing(boolean ignore);
+
     interface Callback {
         default void onNotificationHeadsUp() {}
         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 af02e5b..79de48a 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -35,7 +35,7 @@
     private static final int SIZE = Build.IS_DEBUGGABLE ? 400 : 50;
     static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
 
-    private static final int PULSE_REASONS = 5;
+    private static final int PULSE_REASONS = 6;
 
     public static final int PULSE_REASON_NONE = -1;
     public static final int PULSE_REASON_INTENT = 0;
@@ -43,6 +43,7 @@
     public static final int PULSE_REASON_SENSOR_SIGMOTION = 2;
     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;
 
     private static boolean sRegisterKeyguardCallback = true;
 
@@ -163,6 +164,11 @@
         }
     }
 
+    public static void traceState(DozeMachine.State state) {
+        if (!ENABLED) return;
+        log("state " + state);
+    }
+
     public static void traceProximityResult(Context context, boolean near, long millis,
             int pulseReason) {
         if (!ENABLED) return;
@@ -179,6 +185,7 @@
             case PULSE_REASON_SENSOR_SIGMOTION: return "sigmotion";
             case PULSE_REASON_SENSOR_PICKUP: return "pickup";
             case PULSE_REASON_SENSOR_DOUBLE_TAP: return "doubletap";
+            case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress";
             default: throw new IllegalArgumentException("bad reason: " + pulseReason);
         }
     }
@@ -231,10 +238,10 @@
                 + state + " blocked=" + blocked);
     }
 
-    public static void tracePulseCanceledByProx(Context context) {
+    public static void tracePulseTouchDisabledByProx(Context context, boolean disabled) {
         if (!ENABLED) return;
         init(context);
-        log("pulseCanceledByProx");
+        log("pulseTouchDisabledByProx " + disabled);
     }
 
     public static void setRegisterKeyguardCallback(boolean registerKeyguardCallback) {
@@ -248,6 +255,12 @@
         }
     }
 
+    public static void traceSensor(Context context, int pulseReason) {
+        if (!ENABLED) return;
+        init(context);
+        log("sensor type=" + pulseReasonToString(pulseReason));
+    }
+
     private static class SummaryStats {
         private int mCount;
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index 44bb33a..8ec6afc3 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -17,6 +17,7 @@
 package com.android.systemui.doze;
 
 import android.annotation.MainThread;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.util.Log;
 import android.view.Display;
@@ -60,13 +61,16 @@
         /** Doze is done. DozeService is finished. */
         FINISH,
         /** AOD, but the display is temporarily off. */
-        DOZE_AOD_PAUSED;
+        DOZE_AOD_PAUSED,
+        /** AOD, prox is near, transitions to DOZE_AOD_PAUSED after a timeout. */
+        DOZE_AOD_PAUSING;
 
         boolean canPulse() {
             switch (this) {
                 case DOZE:
                 case DOZE_AOD:
                 case DOZE_AOD_PAUSED:
+                case DOZE_AOD_PAUSING:
                     return true;
                 default:
                     return false;
@@ -88,11 +92,14 @@
                 case UNINITIALIZED:
                 case INITIALIZED:
                 case DOZE:
+                case DOZE_REQUEST_PULSE:
                 case DOZE_AOD_PAUSED:
                     return Display.STATE_OFF;
                 case DOZE_PULSING:
+                    return Display.STATE_ON;
                 case DOZE_AOD:
-                    return Display.STATE_DOZE; // TODO: use STATE_ON if appropriate.
+                case DOZE_AOD_PAUSING:
+                    return Display.STATE_DOZE_SUSPEND;
                 default:
                     return Display.STATE_UNKNOWN;
             }
@@ -219,9 +226,11 @@
         State oldState = mState;
         mState = newState;
 
+        DozeLog.traceState(newState);
+        Trace.traceCounter(Trace.TRACE_TAG_APP, "doze_machine_state", newState.ordinal());
+
         updatePulseReason(newState, oldState, pulseReason);
         performTransitionOnComponents(oldState, newState);
-        updateScreenState(newState);
         updateWakeLockState(newState);
 
         resolveIntermediateState(newState);
@@ -283,7 +292,8 @@
         if (mState == State.FINISH) {
             return State.FINISH;
         }
-        if ((mState == State.DOZE_AOD_PAUSED || mState == State.DOZE_AOD || mState == State.DOZE)
+        if ((mState == State.DOZE_AOD_PAUSED || mState == State.DOZE_AOD_PAUSING
+                || mState == State.DOZE_AOD || mState == State.DOZE)
                 && requestedState == State.DOZE_PULSE_DONE) {
             Log.i(TAG, "Dropping pulse done because current state is already done: " + mState);
             return mState;
@@ -306,13 +316,6 @@
         }
     }
 
-    private void updateScreenState(State newState) {
-        int state = newState.screenState();
-        if (state != Display.STATE_UNKNOWN) {
-            mDozeService.setDozeScreenState(state);
-        }
-    }
-
     private void resolveIntermediateState(State state) {
         switch (state) {
             case INITIALIZED:
@@ -359,5 +362,36 @@
 
         /** Request waking up. */
         void requestWakeUp();
+
+        /** Set screen brightness */
+        void setDozeScreenBrightness(int brightness);
+
+        class Delegate implements Service {
+            private final Service mDelegate;
+
+            public Delegate(Service delegate) {
+                mDelegate = delegate;
+            }
+
+            @Override
+            public void finish() {
+                mDelegate.finish();
+            }
+
+            @Override
+            public void setDozeScreenState(int state) {
+                mDelegate.setDozeScreenState(state);
+            }
+
+            @Override
+            public void requestWakeUp() {
+                mDelegate.requestWakeUp();
+            }
+
+            @Override
+            public void setDozeScreenBrightness(int brightness) {
+                mDelegate.setDozeScreenBrightness(brightness);
+            }
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozePauser.java b/packages/SystemUI/src/com/android/systemui/doze/DozePauser.java
new file mode 100644
index 0000000..a33b454c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozePauser.java
@@ -0,0 +1,53 @@
+/*
+ * 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.doze;
+
+import android.app.AlarmManager;
+import android.os.Handler;
+
+import com.android.systemui.util.AlarmTimeout;
+
+/**
+ * Moves the doze machine from the pausing to the paused state after a timeout.
+ */
+public class DozePauser implements DozeMachine.Part {
+    public static final String TAG = DozePauser.class.getSimpleName();
+    private static final long TIMEOUT = 10 * 1000;
+    private final AlarmTimeout mPauseTimeout;
+    private final DozeMachine mMachine;
+
+    public DozePauser(Handler handler, DozeMachine machine, AlarmManager alarmManager) {
+        mMachine = machine;
+        mPauseTimeout = new AlarmTimeout(alarmManager, this::onTimeout, TAG, handler);
+    }
+
+    @Override
+    public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+        switch (newState) {
+            case DOZE_AOD_PAUSING:
+                mPauseTimeout.schedule(TIMEOUT, AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
+                break;
+            default:
+                mPauseTimeout.cancel();
+                break;
+        }
+    }
+
+    private void onTimeout() {
+        mMachine.requestState(DozeMachine.State.DOZE_AOD_PAUSED);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeReceiver.java b/packages/SystemUI/src/com/android/systemui/doze/DozeReceiver.java
new file mode 100644
index 0000000..dcb3882
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeReceiver.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.doze;
+
+/**
+ * Interface for class that cares about doze states.
+ */
+public interface DozeReceiver {
+    void setDozing(boolean dozing);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
new file mode 100644
index 0000000..30420529
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -0,0 +1,128 @@
+/*
+ * 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.doze;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Handler;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.R;
+
+/**
+ * Controls the screen brightness when dozing.
+ */
+public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListener {
+    private final Context mContext;
+    private final DozeMachine.Service mDozeService;
+    private final DozeHost mDozeHost;
+    private final Handler mHandler;
+    private final SensorManager mSensorManager;
+    private final Sensor mLightSensor;
+    private final int[] mSensorToBrightness;
+    private final int[] mSensorToScrimOpacity;
+    private boolean mRegistered;
+
+    public DozeScreenBrightness(Context context, DozeMachine.Service service,
+            SensorManager sensorManager, Sensor lightSensor, DozeHost host,
+            Handler handler) {
+        mContext = context;
+        mDozeService = service;
+        mSensorManager = sensorManager;
+        mLightSensor = lightSensor;
+        mDozeHost = host;
+        mHandler = handler;
+
+        mSensorToBrightness = context.getResources().getIntArray(
+                R.array.config_doze_brightness_sensor_to_brightness);
+        mSensorToScrimOpacity = context.getResources().getIntArray(
+                R.array.config_doze_brightness_sensor_to_scrim_opacity);
+    }
+
+    @Override
+    public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+        switch (newState) {
+            case INITIALIZED:
+                resetBrightnessToDefault();
+                break;
+            case DOZE_AOD:
+            case DOZE_REQUEST_PULSE:
+                setLightSensorEnabled(true);
+                break;
+            case DOZE:
+            case DOZE_AOD_PAUSED:
+                setLightSensorEnabled(false);
+                resetBrightnessToDefault();
+                break;
+            case FINISH:
+                setLightSensorEnabled(false);
+                break;
+        }
+    }
+
+    @Override
+    public void onSensorChanged(SensorEvent event) {
+        if (mRegistered) {
+            int sensorValue = (int) event.values[0];
+            int brightness = computeBrightness(sensorValue);
+            if (brightness > 0) {
+                mDozeService.setDozeScreenBrightness(brightness);
+            }
+
+            int scrimOpacity = computeScrimOpacity(sensorValue);
+            if (scrimOpacity >= 0) {
+                mDozeHost.setAodDimmingScrim(scrimOpacity / 255f);
+            }
+        }
+    }
+
+    private int computeScrimOpacity(int sensorValue) {
+        if (sensorValue < 0 || sensorValue >= mSensorToScrimOpacity.length) {
+            return -1;
+        }
+        return mSensorToScrimOpacity[sensorValue];
+    }
+
+    private int computeBrightness(int sensorValue) {
+        if (sensorValue < 0 || sensorValue >= mSensorToBrightness.length) {
+            return -1;
+        }
+        return mSensorToBrightness[sensorValue];
+    }
+
+    @Override
+    public void onAccuracyChanged(Sensor sensor, int accuracy) {
+    }
+
+    private void resetBrightnessToDefault() {
+        mDozeService.setDozeScreenBrightness(mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_screenBrightnessDoze));
+    }
+
+    private void setLightSensorEnabled(boolean enabled) {
+        if (enabled && !mRegistered && mLightSensor != null) {
+            mRegistered = mSensorManager.registerListener(this, mLightSensor,
+                    SensorManager.SENSOR_DELAY_NORMAL, mHandler);
+        } else if (!enabled && mRegistered) {
+            mSensorManager.unregisterListener(this);
+            mRegistered = false;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
new file mode 100644
index 0000000..63f5d97
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
@@ -0,0 +1,69 @@
+/*
+ * 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.doze;
+
+import android.os.Handler;
+import android.view.Display;
+
+/**
+ * Controls the screen when dozing.
+ */
+public class DozeScreenState implements DozeMachine.Part {
+    private final DozeMachine.Service mDozeService;
+    private final Handler mHandler;
+    private int mPendingScreenState = Display.STATE_UNKNOWN;
+    private Runnable mApplyPendingScreenState = this::applyPendingScreenState;
+
+    public DozeScreenState(DozeMachine.Service service, Handler handler) {
+        mDozeService = service;
+        mHandler = handler;
+    }
+
+    @Override
+    public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+        int screenState = newState.screenState();
+        if (screenState == Display.STATE_UNKNOWN) {
+            // We'll keep it in the existing state
+            return;
+        }
+        boolean messagePending = mHandler.hasCallbacks(mApplyPendingScreenState);
+        if (messagePending || oldState == DozeMachine.State.INITIALIZED) {
+            // During initialization, we hide the navigation bar. That is however only applied after
+            // a traversal; setting the screen state here is immediate however, so it can happen
+            // that the screen turns on again before the navigation bar is hidden. To work around
+            // that, wait for a traversal to happen before applying the initial screen state.
+            mPendingScreenState = screenState;
+            if (!messagePending) {
+                mHandler.post(mApplyPendingScreenState);
+            }
+            return;
+        }
+        applyScreenState(screenState);
+    }
+
+    private void applyPendingScreenState() {
+        applyScreenState(mPendingScreenState);
+        mPendingScreenState = Display.STATE_UNKNOWN;
+    }
+
+    private void applyScreenState(int screenState) {
+        if (screenState != Display.STATE_UNKNOWN) {
+            mDozeService.setDozeScreenState(screenState);
+            mPendingScreenState = Display.STATE_UNKNOWN;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java
index ad5897a..5d0a9d7 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java
@@ -24,18 +24,11 @@
 /**
  * Prevents usage of doze screen states on devices that don't support them.
  */
-public class DozeScreenStatePreventingAdapter implements DozeMachine.Service {
-
-    private final DozeMachine.Service mInner;
+public class DozeScreenStatePreventingAdapter extends DozeMachine.Service.Delegate {
 
     @VisibleForTesting
     DozeScreenStatePreventingAdapter(DozeMachine.Service inner) {
-        mInner = inner;
-    }
-
-    @Override
-    public void finish() {
-        mInner.finish();
+        super(inner);
     }
 
     @Override
@@ -43,12 +36,7 @@
         if (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND) {
             state = Display.STATE_ON;
         }
-        mInner.setDozeScreenState(state);
-    }
-
-    @Override
-    public void requestWakeUp() {
-        mInner.requestWakeUp();
+        super.setDozeScreenState(state);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 73f5222..566353c 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -18,6 +18,7 @@
 
 import android.annotation.AnyThread;
 import android.app.ActivityManager;
+import android.app.AlarmManager;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
@@ -29,6 +30,7 @@
 import android.hardware.TriggerEventListener;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -38,6 +40,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.util.AlarmTimeout;
 import com.android.systemui.util.wakelock.WakeLock;
 
 import java.io.PrintWriter;
@@ -51,6 +54,7 @@
     private static final String TAG = "DozeSensors";
 
     private final Context mContext;
+    private final AlarmManager mAlarmManager;
     private final SensorManager mSensorManager;
     private final TriggerSensor[] mSensors;
     private final ContentResolver mResolver;
@@ -65,10 +69,12 @@
     private final ProxSensor mProxSensor;
 
 
-    public DozeSensors(Context context, SensorManager sensorManager, DozeParameters dozeParameters,
+    public DozeSensors(Context context, AlarmManager alarmManager, SensorManager sensorManager,
+            DozeParameters dozeParameters,
             AmbientDisplayConfiguration config, WakeLock wakeLock, Callback callback,
             Consumer<Boolean> proxCallback) {
         mContext = context;
+        mAlarmManager = alarmManager;
         mSensorManager = sensorManager;
         mDozeParameters = dozeParameters;
         mConfig = config;
@@ -81,17 +87,29 @@
                         mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
                         null /* setting */,
                         dozeParameters.getPulseOnSigMotion(),
-                        DozeLog.PULSE_REASON_SENSOR_SIGMOTION),
+                        DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */,
+                        false /* touchscreen */),
                 mPickupSensor = new TriggerSensor(
                         mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
                         Settings.Secure.DOZE_PULSE_ON_PICK_UP,
                         config.pulseOnPickupAvailable(),
-                        DozeLog.PULSE_REASON_SENSOR_PICKUP),
+                        DozeLog.PULSE_REASON_SENSOR_PICKUP, false /* touchCoords */,
+                        false /* touchscreen */),
                 new TriggerSensor(
                         findSensorWithType(config.doubleTapSensorType()),
                         Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP,
                         true /* configured */,
-                        DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP)
+                        DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP,
+                        dozeParameters.doubleTapReportsTouchCoordinates(),
+                        true /* touchscreen */),
+                new TriggerSensor(
+                        findSensorWithType(config.longPressSensorType()),
+                        Settings.Secure.DOZE_PULSE_ON_LONG_PRESS,
+                        false /* settingDef */,
+                        true /* configured */,
+                        DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
+                        true /* reports touch coordinates */,
+                        true /* touchscreen */),
         };
 
         mProxSensor = new ProxSensor();
@@ -99,10 +117,14 @@
     }
 
     private Sensor findSensorWithType(String type) {
+        return findSensorWithType(mSensorManager, type);
+    }
+
+    static Sensor findSensorWithType(SensorManager sensorManager, String type) {
         if (TextUtils.isEmpty(type)) {
             return null;
         }
-        List<Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+        List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);
         for (Sensor s : sensorList) {
             if (type.equals(s.getStringType())) {
                 return s;
@@ -123,6 +145,15 @@
         }
     }
 
+    /** Set the listening state of only the sensors that require the touchscreen. */
+    public void setTouchscreenSensorsListening(boolean listening) {
+        for (TriggerSensor sensor : mSensors) {
+            if (sensor.mRequiresTouchscreen) {
+                sensor.setListening(listening);
+            }
+        }
+    }
+
     public void reregisterAllSensors() {
         for (TriggerSensor s : mSensors) {
             s.setListening(false);
@@ -139,7 +170,7 @@
     }
 
     public void setProxListening(boolean listen) {
-        mProxSensor.setRegistered(listen);
+        mProxSensor.setRequested(listen);
     }
 
     private final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
@@ -163,15 +194,35 @@
         for (TriggerSensor s : mSensors) {
             pw.print("Sensor: "); pw.println(s.toString());
         }
+        pw.print("ProxSensor: "); pw.println(mProxSensor.toString());
+    }
+
+    /**
+     * @return true if prox is currently far, false if near or null if unknown.
+     */
+    public Boolean isProximityCurrentlyFar() {
+        return mProxSensor.mCurrentlyFar;
     }
 
     private class ProxSensor implements SensorEventListener {
 
+        static final long COOLDOWN_TRIGGER = 2 * 1000;
+        static final long COOLDOWN_PERIOD = 5 * 1000;
+
+        boolean mRequested;
         boolean mRegistered;
         Boolean mCurrentlyFar;
+        long mLastNear;
+        final AlarmTimeout mCooldownTimer;
 
-        void setRegistered(boolean register) {
-            if (mRegistered == register) {
+
+        public ProxSensor() {
+            mCooldownTimer = new AlarmTimeout(mAlarmManager, this::updateRegistered,
+                    "prox_cooldown", mHandler);
+        }
+
+        void setRequested(boolean requested) {
+            if (mRequested == requested) {
                 // Send an update even if we don't re-register.
                 mHandler.post(() -> {
                     if (mCurrentlyFar != null) {
@@ -180,6 +231,18 @@
                 });
                 return;
             }
+            mRequested = requested;
+            updateRegistered();
+        }
+
+        private void updateRegistered() {
+            setRegistered(mRequested && !mCooldownTimer.isScheduled());
+        }
+
+        private void setRegistered(boolean register) {
+            if (mRegistered == register) {
+                return;
+            }
             if (register) {
                 mRegistered = mSensorManager.registerListener(this,
                         mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY),
@@ -195,11 +258,30 @@
         public void onSensorChanged(SensorEvent event) {
             mCurrentlyFar = event.values[0] >= event.sensor.getMaximumRange();
             mProxCallback.accept(mCurrentlyFar);
+
+            long now = SystemClock.elapsedRealtime();
+            if (mCurrentlyFar == null) {
+                // Sensor has been unregistered by the proxCallback. Do nothing.
+            } else if (!mCurrentlyFar) {
+                mLastNear = now;
+            } else if (mCurrentlyFar && now - mLastNear < COOLDOWN_TRIGGER) {
+                // If the last near was very recent, we might be using more power for prox
+                // wakeups than we're saving from turning of the screen. Instead, turn it off
+                // for a while.
+                mCooldownTimer.schedule(COOLDOWN_PERIOD, AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
+                updateRegistered();
+            }
         }
 
         @Override
         public void onAccuracyChanged(Sensor sensor, int accuracy) {
         }
+
+        @Override
+        public String toString() {
+            return String.format("{registered=%s, requested=%s, coolingDown=%s, currentlyFar=%s}",
+                    mRegistered, mRequested, mCooldownTimer.isScheduled(), mCurrentlyFar);
+        }
     }
 
     private class TriggerSensor extends TriggerEventListener {
@@ -207,16 +289,30 @@
         final boolean mConfigured;
         final int mPulseReason;
         final String mSetting;
+        final boolean mReportsTouchCoordinates;
+        final boolean mSettingDefault;
+        final boolean mRequiresTouchscreen;
 
         private boolean mRequested;
         private boolean mRegistered;
         private boolean mDisabled;
 
-        public TriggerSensor(Sensor sensor, String setting, boolean configured, int pulseReason) {
+        public TriggerSensor(Sensor sensor, String setting, boolean configured, int pulseReason,
+                boolean reportsTouchCoordinates, boolean requiresTouchscreen) {
+            this(sensor, setting, true /* settingDef */, configured, pulseReason,
+                    reportsTouchCoordinates, requiresTouchscreen);
+        }
+
+        public TriggerSensor(Sensor sensor, String setting, boolean settingDef,
+                boolean configured, int pulseReason, boolean reportsTouchCoordinates,
+                boolean requiresTouchscreen) {
             mSensor = sensor;
             mSetting = setting;
+            mSettingDefault = settingDef;
             mConfigured = configured;
             mPulseReason = pulseReason;
+            mReportsTouchCoordinates = reportsTouchCoordinates;
+            mRequiresTouchscreen = requiresTouchscreen;
         }
 
         public void setListening(boolean listen) {
@@ -247,7 +343,7 @@
             if (TextUtils.isEmpty(mSetting)) {
                 return true;
             }
-            return Settings.Secure.getIntForUser(mResolver, mSetting, 1,
+            return Settings.Secure.getIntForUser(mResolver, mSetting, mSettingDefault ? 1 : 0,
                     UserHandle.USER_CURRENT) != 0;
         }
 
@@ -263,6 +359,7 @@
         @Override
         @AnyThread
         public void onTrigger(TriggerEvent event) {
+            DozeLog.traceSensor(mContext, mPulseReason);
             mHandler.post(mWakeLock.wrap(() -> {
                 if (DEBUG) Log.d(TAG, "onTrigger: " + triggerEventToString(event));
                 boolean sensorPerformsProxCheck = false;
@@ -276,7 +373,13 @@
                 }
 
                 mRegistered = false;
-                mCallback.onSensorPulse(mPulseReason, sensorPerformsProxCheck);
+                float screenX = -1;
+                float screenY = -1;
+                if (mReportsTouchCoordinates && event.values.length >= 2) {
+                    screenX = event.values[0];
+                    screenY = event.values[1];
+                }
+                mCallback.onSensorPulse(mPulseReason, sensorPerformsProxCheck, screenX, screenY);
                 updateListener();  // reregister, this sensor only fires once
             }));
         }
@@ -309,7 +412,12 @@
          * Called when a sensor requests a pulse
          * @param pulseReason Requesting sensor, e.g. {@link DozeLog#PULSE_REASON_SENSOR_PICKUP}
          * @param sensorPerformedProxCheck true if the sensor already checked for FAR proximity.
+         * @param screenX the location on the screen where the sensor fired or -1
+         *                if the sensor doesn't support reporting screen locations.
+         * @param screenY the location on the screen where the sensor fired or -1
+         *                if the sensor doesn't support reporting screen locations.
          */
-        void onSensorPulse(int pulseReason, boolean sensorPerformedProxCheck);
+        void onSensorPulse(int pulseReason, boolean sensorPerformedProxCheck,
+                float screenX, float screenY);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 5241266..98b1106 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -16,23 +16,27 @@
 
 package com.android.systemui.doze;
 
+import android.content.Context;
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.service.dreams.DreamService;
 import android.util.Log;
 
 import com.android.systemui.Dependency;
-import com.android.systemui.plugins.Plugin;
+import com.android.systemui.plugins.DozeServicePlugin;
 import com.android.systemui.plugins.PluginManager;
-
+import com.android.systemui.plugins.DozeServicePlugin.RequestDoze;
+import com.android.systemui.plugins.PluginListener;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
-public class DozeService extends DreamService implements DozeMachine.Service {
+public class DozeService extends DreamService
+        implements DozeMachine.Service, RequestDoze, PluginListener<DozeServicePlugin> {
     private static final String TAG = "DozeService";
     static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private DozeMachine mDozeMachine;
+    private DozeServicePlugin mDozePlugin;
 
     public DozeService() {
         setDebug(DEBUG);
@@ -48,21 +52,42 @@
             finish();
             return;
         }
-
+        Dependency.get(PluginManager.class).addPluginListener(this,
+                DozeServicePlugin.class, false /* Allow multiple */);
         mDozeMachine = new DozeFactory().assembleMachine(this);
     }
 
     @Override
+    public void onPluginConnected(DozeServicePlugin plugin, Context pluginContext) {
+        mDozePlugin = plugin;
+        mDozePlugin.setDozeRequester(this);
+    }
+
+    @Override
+    public void onPluginDisconnected(DozeServicePlugin plugin) {
+        if (mDozePlugin != null) {
+            mDozePlugin.onDreamingStopped();
+            mDozePlugin = null;
+        }
+    }
+
+    @Override
     public void onDreamingStarted() {
         super.onDreamingStarted();
         mDozeMachine.requestState(DozeMachine.State.INITIALIZED);
         startDozing();
+        if (mDozePlugin != null) {
+            mDozePlugin.onDreamingStarted();
+        }
     }
 
     @Override
     public void onDreamingStopped() {
         super.onDreamingStopped();
         mDozeMachine.requestState(DozeMachine.State.FINISH);
+        if (mDozePlugin != null) {
+            mDozePlugin.onDreamingStopped();
+        }
     }
 
     @Override
@@ -77,4 +102,18 @@
         PowerManager pm = getSystemService(PowerManager.class);
         pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:NODOZE");
     }
+
+    @Override
+    public void onRequestShowDoze() {
+        if (mDozeMachine != null) {
+            mDozeMachine.requestState(DozeMachine.State.DOZE_AOD);
+        }
+    }
+
+    @Override
+    public void onRequestHideDoze() {
+        if (mDozeMachine != null) {
+            mDozeMachine.requestState(DozeMachine.State.DOZE);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java
new file mode 100644
index 0000000..1c6521f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java
@@ -0,0 +1,54 @@
+/*
+ * 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.doze;
+
+import android.support.annotation.VisibleForTesting;
+import android.view.Display;
+
+import com.android.systemui.statusbar.phone.DozeParameters;
+
+/**
+ * Prevents usage of doze screen states on devices that don't support them.
+ */
+public class DozeSuspendScreenStatePreventingAdapter extends DozeMachine.Service.Delegate {
+
+    @VisibleForTesting
+    DozeSuspendScreenStatePreventingAdapter(DozeMachine.Service inner) {
+        super(inner);
+    }
+
+    @Override
+    public void setDozeScreenState(int state) {
+        if (state == Display.STATE_DOZE_SUSPEND) {
+            state = Display.STATE_DOZE;
+        }
+        super.setDozeScreenState(state);
+    }
+
+    /**
+     * If the device supports the doze display state, return {@code inner}. Otherwise
+     * return a new instance of {@link DozeSuspendScreenStatePreventingAdapter} wrapping {@code inner}.
+     */
+    public static DozeMachine.Service wrapIfNeeded(DozeMachine.Service inner,
+            DozeParameters params) {
+        return isNeeded(params) ? new DozeSuspendScreenStatePreventingAdapter(inner) : inner;
+    }
+
+    private static boolean isNeeded(DozeParameters params) {
+        return !params.getDozeSuspendDisplayStateSupported();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 563b8fe..4583160 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.doze;
 
+import android.app.AlarmManager;
 import android.app.UiModeManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -39,6 +40,7 @@
 import com.android.systemui.util.wakelock.WakeLock;
 
 import java.io.PrintWriter;
+import java.util.function.IntConsumer;
 
 /**
  * Handles triggers for ambient state changes.
@@ -69,7 +71,7 @@
 
 
     public DozeTriggers(Context context, DozeMachine machine, DozeHost dozeHost,
-            AmbientDisplayConfiguration config,
+            AlarmManager alarmManager, AmbientDisplayConfiguration config,
             DozeParameters dozeParameters, SensorManager sensorManager, Handler handler,
             WakeLock wakeLock, boolean allowPulseTriggers) {
         mContext = context;
@@ -81,8 +83,8 @@
         mHandler = handler;
         mWakeLock = wakeLock;
         mAllowPulseTriggers = allowPulseTriggers;
-        mDozeSensors = new DozeSensors(context, mSensorManager, dozeParameters, config,
-                wakeLock, this::onSensor, this::onProximityFar);
+        mDozeSensors = new DozeSensors(context, alarmManager, mSensorManager, dozeParameters,
+                config, wakeLock, this::onSensor, this::onProximityFar);
         mUiModeManager = mContext.getSystemService(UiModeManager.class);
     }
 
@@ -98,10 +100,53 @@
         requestPulse(DozeLog.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */);
     }
 
-    private void onSensor(int pulseReason, boolean sensorPerformedProxCheck) {
-        requestPulse(pulseReason, sensorPerformedProxCheck);
+    private void proximityCheckThenCall(IntConsumer callback,
+            boolean alreadyPerformedProxCheck,
+            int pulseReason) {
+        Boolean cachedProxFar = mDozeSensors.isProximityCurrentlyFar();
+        if (alreadyPerformedProxCheck) {
+            callback.accept(ProximityCheck.RESULT_NOT_CHECKED);
+        } else if (cachedProxFar != null) {
+            callback.accept(cachedProxFar ? ProximityCheck.RESULT_FAR : ProximityCheck.RESULT_NEAR);
+        } else {
+            final long start = SystemClock.uptimeMillis();
+            new ProximityCheck() {
+                @Override
+                public void onProximityResult(int result) {
+                    final long end = SystemClock.uptimeMillis();
+                    DozeLog.traceProximityResult(mContext, result == RESULT_NEAR,
+                            end - start, pulseReason);
+                    callback.accept(result);
+                }
+            }.check();
+        }
+    }
 
-        if (pulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP) {
+    private void onSensor(int pulseReason, boolean sensorPerformedProxCheck,
+            float screenX, float screenY) {
+        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;
+
+        if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT) && !isLongPress) {
+            proximityCheckThenCall((result) -> {
+                if (result == ProximityCheck.RESULT_NEAR) {
+                    // In pocket, drop event.
+                    return;
+                }
+                if (isDoubleTap) {
+                    mDozeHost.onDoubleTap(screenX, screenY);
+                    mMachine.wakeUp();
+                } else {
+                    mDozeHost.extendPulse();
+                }
+            }, sensorPerformedProxCheck, pulseReason);
+            return;
+        } else {
+            requestPulse(pulseReason, sensorPerformedProxCheck);
+        }
+
+        if (isPickup) {
             final long timeSinceNotification =
                     SystemClock.elapsedRealtime() - mNotificationPulseTime;
             final boolean withinVibrationThreshold =
@@ -112,29 +157,25 @@
 
     private void onProximityFar(boolean far) {
         final boolean near = !far;
-        DozeMachine.State state = mMachine.getState();
-        if (near && state == DozeMachine.State.DOZE_PULSING) {
-            if (DEBUG) Log.i(TAG, "Prox NEAR, ending pulse");
-            DozeLog.tracePulseCanceledByProx(mContext);
-            mMachine.requestState(DozeMachine.State.DOZE_PULSE_DONE);
+        final DozeMachine.State state = mMachine.getState();
+        final boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED);
+        final boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING);
+        final boolean aod = (state == DozeMachine.State.DOZE_AOD);
+
+        if (state == DozeMachine.State.DOZE_PULSING) {
+            boolean ignoreTouch = near;
+            if (DEBUG) Log.i(TAG, "Prox changed, ignore touch = " + ignoreTouch);
+            mDozeHost.onIgnoreTouchWhilePulsing(ignoreTouch);
         }
-        if (far && state == DozeMachine.State.DOZE_AOD_PAUSED) {
+        if (far && (paused || pausing)) {
             if (DEBUG) Log.i(TAG, "Prox FAR, unpausing AOD");
             mMachine.requestState(DozeMachine.State.DOZE_AOD);
-        } else if (near && state == DozeMachine.State.DOZE_AOD) {
+        } else if (near && aod) {
             if (DEBUG) Log.i(TAG, "Prox NEAR, pausing AOD");
-            mMachine.requestState(DozeMachine.State.DOZE_AOD_PAUSED);
+            mMachine.requestState(DozeMachine.State.DOZE_AOD_PAUSING);
         }
     }
 
-    private void onCarMode() {
-        mMachine.requestState(DozeMachine.State.FINISH);
-    }
-
-    private void onPowerSave() {
-        mMachine.requestState(DozeMachine.State.FINISH);
-    }
-
     @Override
     public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
         switch (newState) {
@@ -145,14 +186,19 @@
                 break;
             case DOZE:
             case DOZE_AOD:
-            case DOZE_AOD_PAUSED:
                 mDozeSensors.setProxListening(newState != DozeMachine.State.DOZE);
-                mDozeSensors.setListening(true);
                 if (oldState != DozeMachine.State.INITIALIZED) {
                     mDozeSensors.reregisterAllSensors();
                 }
+                mDozeSensors.setListening(true);
+                break;
+            case DOZE_AOD_PAUSED:
+            case DOZE_AOD_PAUSING:
+                mDozeSensors.setProxListening(true);
+                mDozeSensors.setListening(false);
                 break;
             case DOZE_PULSING:
+                mDozeSensors.setTouchscreenSensorsListening(false);
                 mDozeSensors.setProxListening(true);
                 break;
             case FINISH:
@@ -166,11 +212,11 @@
     }
 
     private void checkTriggersAtInit() {
-        if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) {
-            onCarMode();
-        }
-        if (mDozeHost.isPowerSaveActive()) {
-            onPowerSave();
+        if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR
+                || mDozeHost.isPowerSaveActive()
+                || mDozeHost.isBlockingDoze()
+                || !mDozeHost.isProvisioned()) {
+            mMachine.requestState(DozeMachine.State.FINISH);
         }
     }
 
@@ -186,33 +232,15 @@
         }
 
         mPulsePending = true;
-        if (!mDozeParameters.getProxCheckBeforePulse() || performedProxCheck) {
-            // skip proximity check
-            continuePulseRequest(reason);
-            return;
-        }
-
-        final long start = SystemClock.uptimeMillis();
-        new ProximityCheck() {
-            @Override
-            public void onProximityResult(int result) {
-                final long end = SystemClock.uptimeMillis();
-                DozeLog.traceProximityResult(mContext, result == RESULT_NEAR,
-                        end - start, reason);
-                if (performedProxCheck) {
-                    // we already continued
-                    return;
-                }
-                // avoid pulsing in pockets
-                if (result == RESULT_NEAR) {
-                    mPulsePending = false;
-                    return;
-                }
-
-                // not in-pocket, continue pulsing
+        proximityCheckThenCall((result) -> {
+            if (result == ProximityCheck.RESULT_NEAR) {
+                // in pocket, abort pulse
+                mPulsePending = false;
+            } else {
+                // not in pocket, continue pulsing
                 continuePulseRequest(reason);
             }
-        }.check();
+        }, !mDozeParameters.getProxCheckBeforePulse() || performedProxCheck, reason);
     }
 
     private boolean canPulse() {
@@ -246,6 +274,7 @@
         protected static final int RESULT_UNKNOWN = 0;
         protected static final int RESULT_NEAR = 1;
         protected static final int RESULT_FAR = 2;
+        protected static final int RESULT_NOT_CHECKED = 3;
 
         private boolean mRegistered;
         private boolean mFinished;
@@ -323,7 +352,7 @@
                 requestPulse(DozeLog.PULSE_REASON_INTENT, false /* performedProxCheck */);
             }
             if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
-                onCarMode();
+                mMachine.requestState(DozeMachine.State.FINISH);
             }
             if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
                 mDozeSensors.onUserSwitched();
@@ -359,7 +388,7 @@
         @Override
         public void onPowerSaveChanged(boolean active) {
             if (active) {
-                onPowerSave();
+                mMachine.requestState(DozeMachine.State.FINISH);
             }
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index ea33ebf..dc626fb 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -23,6 +23,7 @@
 import android.text.format.Formatter;
 import android.util.Log;
 
+import com.android.systemui.util.AlarmTimeout;
 import com.android.systemui.util.wakelock.WakeLock;
 
 import java.util.Calendar;
@@ -35,26 +36,23 @@
 
     private static final long TIME_TICK_DEADLINE_MILLIS = 90 * 1000; // 1.5min
     private final Context mContext;
-    private final AlarmManager mAlarmManager;
     private final DozeHost mHost;
     private final Handler mHandler;
     private final WakeLock mWakeLock;
     private final DozeMachine mMachine;
-    private final AlarmManager.OnAlarmListener mTimeTick;
+    private final AlarmTimeout mTimeTicker;
 
-    private boolean mTimeTickScheduled = false;
     private long mLastTimeTickElapsed = 0;
 
     public DozeUi(Context context, AlarmManager alarmManager, DozeMachine machine,
             WakeLock wakeLock, DozeHost host, Handler handler) {
         mContext = context;
-        mAlarmManager = alarmManager;
         mMachine = machine;
         mWakeLock = wakeLock;
         mHost = host;
         mHandler = handler;
 
-        mTimeTick = this::onTimeTick;
+        mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", handler);
     }
 
     private void pulseWhileDozing(int reason) {
@@ -76,6 +74,7 @@
     public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
         switch (newState) {
             case DOZE_AOD:
+            case DOZE_AOD_PAUSING:
                 scheduleTimeTick();
                 break;
             case DOZE:
@@ -87,6 +86,7 @@
                 break;
             case DOZE_PULSE_DONE:
                 mHost.abortPulsing();
+                break;
             case INITIALIZED:
                 mHost.startDozing();
                 break;
@@ -95,40 +95,41 @@
                 unscheduleTimeTick();
                 break;
         }
-        mHost.setAnimateWakeup(shouldAnimateWakeup(newState));
+        updateAnimateWakeup(newState);
     }
 
-    private boolean shouldAnimateWakeup(DozeMachine.State state) {
+    private void updateAnimateWakeup(DozeMachine.State state) {
         switch (state) {
-            case DOZE_AOD:
             case DOZE_REQUEST_PULSE:
             case DOZE_PULSING:
             case DOZE_PULSE_DONE:
-                return true;
+                mHost.setAnimateWakeup(true);
+                break;
+            case FINISH:
+                // Keep current state.
+                break;
             default:
-                return false;
+                mHost.setAnimateWakeup(false);
+                break;
         }
     }
 
     private void scheduleTimeTick() {
-        if (mTimeTickScheduled) {
+        if (mTimeTicker.isScheduled()) {
             return;
         }
 
         long delta = roundToNextMinute(System.currentTimeMillis()) - System.currentTimeMillis();
-        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                SystemClock.elapsedRealtime() + delta, "doze_time_tick", mTimeTick, mHandler);
-
-        mTimeTickScheduled = true;
+        mTimeTicker.schedule(delta, AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
         mLastTimeTickElapsed = SystemClock.elapsedRealtime();
     }
 
     private void unscheduleTimeTick() {
-        if (!mTimeTickScheduled) {
+        if (!mTimeTicker.isScheduled()) {
             return;
         }
         verifyLastTimeTick();
-        mAlarmManager.cancel(mTimeTick);
+        mTimeTicker.cancel();
     }
 
     private void verifyLastTimeTick() {
@@ -151,10 +152,6 @@
     }
 
     private void onTimeTick() {
-        if (!mTimeTickScheduled) {
-            // Alarm was canceled, but we still got the callback. Ignore.
-            return;
-        }
         verifyLastTimeTick();
 
         mHost.dozeTimeTick();
@@ -162,7 +159,6 @@
         // Keep wakelock until a frame has been pushed.
         mHandler.post(mWakeLock.wrap(() -> {}));
 
-        mTimeTickScheduled = false;
         scheduleTimeTick();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java b/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java
new file mode 100644
index 0000000..18fb423
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java
@@ -0,0 +1,68 @@
+/*
+ * 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.fragments;
+
+import android.app.Fragment;
+import android.util.Log;
+import android.view.View;
+
+import com.android.systemui.plugins.FragmentBase;
+import com.android.systemui.statusbar.policy.ExtensionController.Extension;
+
+import java.util.function.Consumer;
+
+/**
+ * Wires up an Extension to a Fragment tag/id so that it always contains the class
+ * selected by the extension.
+ */
+public class ExtensionFragmentListener<T extends FragmentBase> implements Consumer<T> {
+
+    private static final String TAG = "ExtensionFragmentListener";
+
+    private final FragmentHostManager mFragmentHostManager;
+    private final String mTag;
+    private final Extension<T> mExtension;
+    private final int mId;
+    private String mOldClass;
+
+    private ExtensionFragmentListener(View view, String tag, int id, Extension<T> extension) {
+        mTag = tag;
+        mFragmentHostManager = FragmentHostManager.get(view);
+        mExtension = extension;
+        mId = id;
+        mFragmentHostManager.getFragmentManager().beginTransaction()
+                .replace(id, (Fragment) mExtension.get(), mTag)
+                .commit();
+        mExtension.clearItem(false);
+    }
+
+    @Override
+    public void accept(T extension) {
+        try {
+            Fragment.class.cast(extension);
+            mFragmentHostManager.getExtensionManager().setCurrentExtension(mId, mTag,
+                    mOldClass, extension.getClass().getName(), mExtension.getContext());
+            mOldClass = extension.getClass().getName();
+        } catch (ClassCastException e) {
+            Log.e(TAG, extension.getClass().getName() + " must be a Fragment", e);
+        }
+        mExtension.clearItem(true);
+    }
+
+    public static <T> void attachExtensonToFragment(View view, String tag, int id,
+            Extension<T> extension) {
+        extension.addCallback(new ExtensionFragmentListener(view, tag, id, extension));
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
index ee155d9..f8f364d 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
@@ -28,6 +28,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Parcelable;
+import android.support.annotation.NonNull;
 import android.util.ArrayMap;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -52,7 +53,7 @@
             ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_LOCALE
                 | ActivityInfo.CONFIG_SCREEN_LAYOUT | ActivityInfo.CONFIG_ASSETS_PATHS);
     private final FragmentService mManager;
-    private final PluginFragmentManager mPlugins = new PluginFragmentManager();
+    private final ExtensionFragmentManager mPlugins = new ExtensionFragmentManager();
 
     private FragmentController mFragments;
     private FragmentLifecycleCallbacks mLifecycleCallbacks;
@@ -175,7 +176,7 @@
         return mFragments.getFragmentManager();
     }
 
-    PluginFragmentManager getPluginManager() {
+    ExtensionFragmentManager getExtensionManager() {
         return mPlugins;
     }
 
@@ -262,25 +263,17 @@
         }
     }
 
-    class PluginFragmentManager {
-        private final ArrayMap<String, Context> mPluginLookup = new ArrayMap<>();
+    class ExtensionFragmentManager {
+        private final ArrayMap<String, Context> mExtensionLookup = new ArrayMap<>();
 
-        public void removePlugin(String tag, String currentClass, String defaultClass) {
-            Fragment fragment = getFragmentManager().findFragmentByTag(tag);
-            mPluginLookup.remove(currentClass);
+        public void setCurrentExtension(int id, @NonNull  String tag, @Nullable String oldClass,
+                @NonNull String currentClass, @Nullable Context context) {
+            if (oldClass != null) {
+                mExtensionLookup.remove(oldClass);
+            }
+            mExtensionLookup.put(currentClass, context);
             getFragmentManager().beginTransaction()
-                    .replace(((View) fragment.getView().getParent()).getId(),
-                            instantiate(mContext, defaultClass, null), tag)
-                    .commit();
-            reloadFragments();
-        }
-
-        public void setCurrentPlugin(String tag, String currentClass, Context context) {
-            Fragment fragment = getFragmentManager().findFragmentByTag(tag);
-            mPluginLookup.put(currentClass, context);
-            getFragmentManager().beginTransaction()
-                    .replace(((View) fragment.getView().getParent()).getId(),
-                            instantiate(context, currentClass, null), tag)
+                    .replace(id, instantiate(context, currentClass, null), tag)
                     .commit();
             reloadFragments();
         }
@@ -293,11 +286,11 @@
         }
 
         Fragment instantiate(Context context, String className, Bundle arguments) {
-            Context pluginContext = mPluginLookup.get(className);
-            if (pluginContext != null) {
-                Fragment f = Fragment.instantiate(pluginContext, className, arguments);
+            Context extensionContext = mExtensionLookup.get(className);
+            if (extensionContext != null) {
+                Fragment f = Fragment.instantiate(extensionContext, className, arguments);
                 if (f instanceof Plugin) {
-                    ((Plugin) f).onCreate(mContext, pluginContext);
+                    ((Plugin) f).onCreate(mContext, extensionContext);
                 }
                 return f;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/PluginFragmentListener.java b/packages/SystemUI/src/com/android/systemui/fragments/PluginFragmentListener.java
deleted file mode 100644
index 03bb73d..0000000
--- a/packages/SystemUI/src/com/android/systemui/fragments/PluginFragmentListener.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.fragments;
-
-import android.app.Fragment;
-import android.content.Context;
-import android.util.Log;
-import android.view.View;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.plugins.FragmentBase;
-import com.android.systemui.plugins.Plugin;
-import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
-
-public class PluginFragmentListener implements PluginListener<Plugin> {
-
-    private static final String TAG = "PluginFragmentListener";
-
-    private final FragmentHostManager mFragmentHostManager;
-    private final PluginManager mPluginManager;
-    private final Class<? extends Fragment> mDefaultClass;
-    private final Class<? extends FragmentBase> mExpectedInterface;
-    private final String mTag;
-
-    public PluginFragmentListener(View view, String tag, Class<? extends Fragment> defaultFragment,
-            Class<? extends FragmentBase> expectedInterface) {
-        mTag = tag;
-        mFragmentHostManager = FragmentHostManager.get(view);
-        mPluginManager = Dependency.get(PluginManager.class);
-        mExpectedInterface = expectedInterface;
-        mDefaultClass = defaultFragment;
-    }
-
-    public void startListening() {
-        mPluginManager.addPluginListener(this, mExpectedInterface,
-                false /* Only allow one */);
-    }
-
-    public void stopListening() {
-        mPluginManager.removePluginListener(this);
-    }
-
-    @Override
-    public void onPluginConnected(Plugin plugin, Context pluginContext) {
-        try {
-            mExpectedInterface.cast(plugin);
-            Fragment.class.cast(plugin);
-            mFragmentHostManager.getPluginManager().setCurrentPlugin(mTag,
-                    plugin.getClass().getName(), pluginContext);
-        } catch (ClassCastException e) {
-            Log.e(TAG, plugin.getClass().getName() + " must be a Fragment and implement "
-                    + mExpectedInterface.getName(), e);
-        }
-    }
-
-    @Override
-    public void onPluginDisconnected(Plugin plugin) {
-        mFragmentHostManager.getPluginManager().removePlugin(mTag,
-                plugin.getClass().getName(), mDefaultClass.getName());
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
index f07027e..09a08f0 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
@@ -46,6 +46,11 @@
     }
 
     @Override
+    public void handleShowShutdownUi(boolean isReboot, String reason) {
+        mExtension.get().showShutdownUi(isReboot, reason);
+    }
+
+    @Override
     public void handleShowGlobalActionsMenu() {
         mExtension.get().showGlobalActions(this);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 206342e..33d5617 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -15,18 +15,29 @@
 package com.android.systemui.globalactions;
 
 import com.android.internal.R;
-import com.android.internal.app.AlertController;
-import com.android.internal.app.AlertController.AlertParams;
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.EmergencyAffordanceManager;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.Dependency;
+import com.android.systemui.HardwareUiLayout;
+import com.android.systemui.Interpolators;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
+import com.android.systemui.statusbar.notification.NotificationUtils;
+import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.volume.VolumeDialogMotion.LogAccelerateInterpolator;
+import com.android.systemui.volume.VolumeDialogMotion.LogDecelerateInterpolator;
 
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.ActivityManager;
 import android.app.Dialog;
+import android.app.WallpaperManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -34,11 +45,11 @@
 import android.content.IntentFilter;
 import android.content.pm.UserInfo;
 import android.database.ContentObserver;
+import android.graphics.Point;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.net.ConnectivityManager;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.os.RemoteException;
@@ -56,21 +67,25 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
-import android.util.TypedValue;
-import android.view.KeyEvent;
+import android.util.MathUtils;
+import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemLongClickListener;
 import android.widget.BaseAdapter;
 import android.widget.ImageView;
 import android.widget.ImageView.ScaleType;
-import android.widget.ListView;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import com.android.internal.colorextraction.drawable.GradientDrawable;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -79,7 +94,7 @@
  * may show depending on whether the keyguard is showing, and whether the device
  * is provisioned.
  */
-class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener  {
+class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener {
 
     static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
     static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
@@ -127,7 +142,7 @@
      * @param context everything needs a context :(
      */
     public GlobalActionsDialog(Context context, GlobalActionsManager windowManagerFuncs) {
-        mContext = context;
+        mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
         mWindowManagerFuncs = windowManagerFuncs;
         mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
         mDreamManager = IDreamManager.Stub.asInterface(
@@ -162,6 +177,7 @@
 
     /**
      * Show the global actions dialog (creating if necessary)
+     *
      * @param keyguardShowing True if keyguard is showing
      */
     public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {
@@ -205,12 +221,12 @@
             mDialog.getWindow().setAttributes(attrs);
             mDialog.show();
             mWindowManagerFuncs.onGlobalActionsShown();
-            mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
         }
     }
 
     /**
      * Create the global actions dialog.
+     *
      * @return A new dialog.
      */
     private ActionsDialog createDialog() {
@@ -314,29 +330,21 @@
 
         mAdapter = new MyAdapter();
 
-        AlertParams params = new AlertParams(mContext);
-        params.mAdapter = mAdapter;
-        params.mOnClickListener = this;
-        params.mForceInverseBackground = true;
-
-        ActionsDialog dialog = new ActionsDialog(mContext, params);
+        OnItemLongClickListener onItemLongClickListener = new OnItemLongClickListener() {
+            @Override
+            public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
+                    long id) {
+                final Action action = mAdapter.getItem(position);
+                if (action instanceof LongPressAction) {
+                    mDialog.dismiss();
+                    return ((LongPressAction) action).onLongPress();
+                }
+                return false;
+            }
+        };
+        ActionsDialog dialog = new ActionsDialog(mContext, this, mAdapter, onItemLongClickListener);
         dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
-
-        dialog.getListView().setItemsCanFocus(true);
-        dialog.getListView().setLongClickable(true);
-        dialog.getListView().setOnItemLongClickListener(
-                new AdapterView.OnItemLongClickListener() {
-                    @Override
-                    public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
-                            long id) {
-                        final Action action = mAdapter.getItem(position);
-                        if (action instanceof LongPressAction) {
-                            return ((LongPressAction) action).onLongPress();
-                        }
-                        return false;
-                    }
-        });
-        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+        dialog.setKeyguardShowing(mKeyguardShowing);
 
         dialog.setOnDismissListener(this);
 
@@ -346,7 +354,7 @@
     private final class PowerAction extends SinglePressAction implements LongPressAction {
         private PowerAction() {
             super(R.drawable.ic_lock_power_off,
-                R.string.global_action_power_off);
+                    R.string.global_action_power_off);
         }
 
         @Override
@@ -614,7 +622,7 @@
                     SinglePressAction switchToUser = new SinglePressAction(
                             R.drawable.ic_menu_cc, icon,
                             (user.name != null ? user.name : "Primary")
-                            + (isCurrentUser ? " \u2714" : "")) {
+                                    + (isCurrentUser ? " \u2714" : "")) {
                         public void onPress() {
                             try {
                                 ActivityManager.getService().switchUser(user.id);
@@ -641,7 +649,6 @@
         refreshSilentMode();
         mAirplaneModeOn.updateState(mAirplaneState);
         mAdapter.notifyDataSetChanged();
-        mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
         if (mShowSilentToggle) {
             IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
             mContext.registerReceiver(mRingerModeReceiver, filter);
@@ -652,7 +659,7 @@
         if (!mHasVibrator) {
             final boolean silentModeOn =
                     mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
-            ((ToggleAction)mSilentModeAction).updateState(
+            ((ToggleAction) mSilentModeAction).updateState(
                     silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
         }
     }
@@ -672,16 +679,18 @@
 
     /** {@inheritDoc} */
     public void onClick(DialogInterface dialog, int which) {
-        if (!(mAdapter.getItem(which) instanceof SilentModeTriStateAction)) {
+        Action item = mAdapter.getItem(which);
+        if (!(item instanceof SilentModeTriStateAction)) {
             dialog.dismiss();
         }
-        mAdapter.getItem(which).onPress();
+        item.onPress();
     }
 
     /**
      * The adapter used for the list within the global actions dialog, taking
      * into account whether the keyguard is showing via
-     * {@link com.android.systemui.globalactions.GlobalActionsDialog#mKeyguardShowing} and whether the device is provisioned
+     * {@link com.android.systemui.globalactions.GlobalActionsDialog#mKeyguardShowing} and whether
+     * the device is provisioned
      * via {@link com.android.systemui.globalactions.GlobalActionsDialog#mDeviceProvisioned}.
      */
     private class MyAdapter extends BaseAdapter {
@@ -744,7 +753,11 @@
 
         public View getView(int position, View convertView, ViewGroup parent) {
             Action action = getItem(position);
-            return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
+            View view = action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
+            if (position == 2) {
+                HardwareUiLayout.get(parent).setDivisionView(view);
+            }
+            return view;
         }
     }
 
@@ -760,7 +773,7 @@
     private interface Action {
         /**
          * @return Text that will be announced when dialog is created.  null
-         *     for none.
+         * for none.
          */
         CharSequence getLabelForAccessibility(Context context);
 
@@ -770,13 +783,13 @@
 
         /**
          * @return whether this action should appear in the dialog when the keygaurd
-         *    is showing.
+         * is showing.
          */
         boolean showDuringKeyguard();
 
         /**
          * @return whether this action should appear in the dialog before the
-         *   device is provisioned.
+         * device is provisioned.
          */
         boolean showBeforeProvisioning();
 
@@ -834,7 +847,8 @@
 
         public View create(
                 Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
-            View v = inflater.inflate(R.layout.global_actions_item, parent, false);
+            View v = inflater.inflate(com.android.systemui.R.layout.global_actions_item, parent,
+                    false);
 
             ImageView icon = (ImageView) v.findViewById(R.id.icon);
             TextView messageView = (TextView) v.findViewById(R.id.message);
@@ -895,10 +909,10 @@
         protected int mDisabledStatusMessageResId;
 
         /**
-         * @param enabledIconResId The icon for when this action is on.
-         * @param disabledIconResid The icon for when this action is off.
-         * @param message The general information message, e.g 'Silent Mode'
-         * @param enabledStatusMessageResId The on status message, e.g 'sound disabled'
+         * @param enabledIconResId           The icon for when this action is on.
+         * @param disabledIconResid          The icon for when this action is off.
+         * @param message                    The general information message, e.g 'Silent Mode'
+         * @param enabledStatusMessageResId  The on status message, e.g 'sound disabled'
          * @param disabledStatusMessageResId The off status message, e.g. 'sound enabled'
          */
         public ToggleAction(int enabledIconResId,
@@ -931,7 +945,7 @@
             willCreate();
 
             View v = inflater.inflate(R
-                            .layout.global_actions_item, parent, false);
+                    .layout.global_actions_item, parent, false);
 
             ImageView icon = (ImageView) v.findViewById(R.id.icon);
             TextView messageView = (TextView) v.findViewById(R.id.message);
@@ -979,6 +993,7 @@
          * Implementations may override this if their state can be in on of the intermediate
          * states until some notification is received (e.g airplane mode is 'turning off' until
          * we know the wireless connections are back online
+         *
          * @param buttonOn Whether the button was turned on or off
          */
         protected void changeStateFromPress(boolean buttonOn) {
@@ -1020,7 +1035,7 @@
 
     private static class SilentModeTriStateAction implements Action, View.OnClickListener {
 
-        private final int[] ITEM_IDS = { R.id.option1, R.id.option2, R.id.option3 };
+        private final int[] ITEM_IDS = {R.id.option1, R.id.option2, R.id.option3};
 
         private final AudioManager mAudioManager;
         private final Handler mHandler;
@@ -1145,19 +1160,19 @@
     private Handler mHandler = new Handler() {
         public void handleMessage(Message msg) {
             switch (msg.what) {
-            case MESSAGE_DISMISS:
-                if (mDialog != null) {
-                    mDialog.dismiss();
-                    mDialog = null;
-                }
-                break;
-            case MESSAGE_REFRESH:
-                refreshSilentMode();
-                mAdapter.notifyDataSetChanged();
-                break;
-            case MESSAGE_SHOW:
-                handleShow();
-                break;
+                case MESSAGE_DISMISS:
+                    if (mDialog != null) {
+                        mDialog.dismiss();
+                        mDialog = null;
+                    }
+                    break;
+                case MESSAGE_REFRESH:
+                    refreshSilentMode();
+                    mAdapter.notifyDataSetChanged();
+                    break;
+                case MESSAGE_SHOW:
+                    handleShow();
+                    break;
             }
         }
     };
@@ -1191,40 +1206,123 @@
         }
     }
 
-    private static final class ActionsDialog extends Dialog implements DialogInterface {
-        private final Context mContext;
-        private final AlertController mAlert;
-        private final MyAdapter mAdapter;
+    private static final class ActionsDialog extends Dialog implements DialogInterface,
+            ColorExtractor.OnColorsChangedListener {
 
-        public ActionsDialog(Context context, AlertParams params) {
-            super(context, getDialogTheme(context));
-            mContext = getContext();
-            mAlert = AlertController.create(mContext, this, getWindow());
-            mAdapter = (MyAdapter) params.mAdapter;
-            params.apply(mAlert);
+        private final Context mContext;
+        private final MyAdapter mAdapter;
+        private final LinearLayout mListView;
+        private final HardwareUiLayout mHardwareLayout;
+        private final OnClickListener mClickListener;
+        private final OnItemLongClickListener mLongClickListener;
+        private final GradientDrawable mGradientDrawable;
+        private final ColorExtractor mColorExtractor;
+        private boolean mKeyguardShowing;
+
+        public ActionsDialog(Context context, OnClickListener clickListener, MyAdapter adapter,
+                OnItemLongClickListener longClickListener) {
+            super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
+            mContext = context;
+            mAdapter = adapter;
+            mClickListener = clickListener;
+            mLongClickListener = longClickListener;
+            mGradientDrawable = new GradientDrawable(mContext);
+            mColorExtractor = Dependency.get(SysuiColorExtractor.class);
+
+            // Window initialization
+            Window window = getWindow();
+            window.requestFeature(Window.FEATURE_NO_TITLE);
+            window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
+                    | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
+            window.addFlags(
+                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                    | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
+            window.setBackgroundDrawable(mGradientDrawable);
+            window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
+
+            setContentView(com.android.systemui.R.layout.global_actions_wrapped);
+            mListView = findViewById(android.R.id.list);
+            mHardwareLayout = HardwareUiLayout.get(mListView);
+            mHardwareLayout.setOutsideTouchListener(view -> dismiss());
         }
 
-        private static int getDialogTheme(Context context) {
-            TypedValue outValue = new TypedValue();
-            context.getTheme().resolveAttribute(R.attr.alertDialogTheme,
-                    outValue, true);
-            return outValue.resourceId;
+        private void updateList() {
+            mListView.removeAllViews();
+            for (int i = 0; i < mAdapter.getCount(); i++) {
+                View v = mAdapter.getView(i, null, mListView);
+                final int pos = i;
+                v.setOnClickListener(view -> mClickListener.onClick(this, pos));
+                v.setOnLongClickListener(view ->
+                        mLongClickListener.onItemLongClick(null, v, pos, 0));
+                mListView.addView(v);
+            }
         }
 
         @Override
         protected void onStart() {
             super.setCanceledOnTouchOutside(true);
             super.onStart();
-        }
+            updateList();
 
-        public ListView getListView() {
-            return mAlert.getListView();
+            Point displaySize = new Point();
+            mContext.getDisplay().getRealSize(displaySize);
+            mColorExtractor.addOnColorsChangedListener(this);
+            mGradientDrawable.setScreenSize(displaySize.x, displaySize.y);
+            GradientColors colors = mColorExtractor.getColors(mKeyguardShowing ?
+                    WallpaperManager.FLAG_LOCK : WallpaperManager.FLAG_SYSTEM);
+            mGradientDrawable.setColors(colors, false);
         }
 
         @Override
-        protected void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            mAlert.installContent();
+        protected void onStop() {
+            super.onStop();
+            mColorExtractor.removeOnColorsChangedListener(this);
+        }
+
+        @Override
+        public void show() {
+            super.show();
+            mGradientDrawable.setAlpha(0);
+            mHardwareLayout.setTranslationX(getAnimTranslation());
+            mHardwareLayout.setAlpha(0);
+            mHardwareLayout.animate()
+                    .alpha(1)
+                    .translationX(0)
+                    .setDuration(300)
+                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                    .setUpdateListener(animation -> {
+                        int alpha = (int) ((Float) animation.getAnimatedValue()
+                                * ScrimController.GRADIENT_SCRIM_ALPHA * 255);
+                        mGradientDrawable.setAlpha(alpha);
+                    })
+                    .withEndAction(() -> getWindow().getDecorView().requestAccessibilityFocus())
+                    .start();
+        }
+
+        @Override
+        public void dismiss() {
+            mHardwareLayout.setTranslationX(0);
+            mHardwareLayout.setAlpha(1);
+            mHardwareLayout.animate()
+                    .alpha(0)
+                    .translationX(getAnimTranslation())
+                    .setDuration(300)
+                    .withEndAction(() -> super.dismiss())
+                    .setInterpolator(new LogAccelerateInterpolator())
+                    .setUpdateListener(animation -> {
+                        int alpha = (int) ((1f - (Float) animation.getAnimatedValue())
+                                * ScrimController.GRADIENT_SCRIM_ALPHA * 255);
+                        mGradientDrawable.setAlpha(alpha);
+                    })
+                    .start();
+        }
+
+        private float getAnimTranslation() {
+            return getContext().getResources().getDimension(
+                    com.android.systemui.R.dimen.global_actions_panel_width) / 2;
         }
 
         @Override
@@ -1242,19 +1340,20 @@
         }
 
         @Override
-        public boolean onKeyDown(int keyCode, KeyEvent event) {
-            if (mAlert.onKeyDown(keyCode, event)) {
-                return true;
+        public void onColorsChanged(ColorExtractor extractor, int which) {
+            if (mKeyguardShowing) {
+                if ((WallpaperManager.FLAG_LOCK & which) != 0) {
+                    mGradientDrawable.setColors(extractor.getColors(WallpaperManager.FLAG_LOCK));
+                }
+            } else {
+                if ((WallpaperManager.FLAG_SYSTEM & which) != 0) {
+                    mGradientDrawable.setColors(extractor.getColors(WallpaperManager.FLAG_SYSTEM));
+                }
             }
-            return super.onKeyDown(keyCode, event);
         }
 
-        @Override
-        public boolean onKeyUp(int keyCode, KeyEvent event) {
-            if (mAlert.onKeyUp(keyCode, event)) {
-                return true;
-            }
-            return super.onKeyUp(keyCode, event);
+        public void setKeyguardShowing(boolean keyguardShowing) {
+            mKeyguardShowing = keyguardShowing;
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index c1e51b9..2cf230c8 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -14,16 +14,33 @@
 
 package com.android.systemui.globalactions;
 
+import android.app.Dialog;
+import android.app.KeyguardManager;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.android.internal.R;
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.colorextraction.drawable.GradientDrawable;
+import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.GlobalActions;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 
-import android.content.Context;
-import android.support.v7.view.ContextThemeWrapper;
-
 public class GlobalActionsImpl implements GlobalActions {
 
+    private static final float SHUTDOWN_SCRIM_ALPHA = 0.95f;
+
     private final Context mContext;
     private final KeyguardMonitor mKeyguardMonitor;
     private final DeviceProvisionedController mDeviceProvisionedController;
@@ -38,11 +55,56 @@
     @Override
     public void showGlobalActions(GlobalActionsManager manager) {
         if (mGlobalActions == null) {
-            final ContextThemeWrapper context = new ContextThemeWrapper(mContext,
-                    android.R.style.Theme_Material_Light);
-            mGlobalActions = new GlobalActionsDialog(context, manager);
+            mGlobalActions = new GlobalActionsDialog(mContext, manager);
         }
         mGlobalActions.showDialog(mKeyguardMonitor.isShowing(),
                 mDeviceProvisionedController.isDeviceProvisioned());
     }
+
+    @Override
+    public void showShutdownUi(boolean isReboot, String reason) {
+        GradientDrawable background = new GradientDrawable(mContext);
+        background.setAlpha((int) (SHUTDOWN_SCRIM_ALPHA * 255));
+
+        Dialog d = new Dialog(mContext,
+                com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
+        // Window initialization
+        Window window = d.getWindow();
+        window.getAttributes().width = ViewGroup.LayoutParams.MATCH_PARENT;
+        window.getAttributes().height = ViewGroup.LayoutParams.MATCH_PARENT;
+        window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
+        window.requestFeature(Window.FEATURE_NO_TITLE);
+        window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
+                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
+        window.addFlags(
+                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                        | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
+        window.setBackgroundDrawable(background);
+        window.setWindowAnimations(R.style.Animation_Toast);
+
+        d.setContentView(R.layout.shutdown_dialog);
+        d.setCancelable(false);
+
+        int color = Utils.getColorAttr(mContext, com.android.systemui.R.attr.wallpaperTextColor);
+        boolean onKeyguard = mContext.getSystemService(
+                KeyguardManager.class).isKeyguardLocked();
+
+        ProgressBar bar = d.findViewById(R.id.progress);
+        bar.getIndeterminateDrawable().setTint(color);
+        TextView message = d.findViewById(R.id.text1);
+        message.setTextColor(color);
+        if (isReboot) message.setText(R.string.reboot_to_reset_message);
+
+        Point displaySize = new Point();
+        mContext.getDisplay().getRealSize(displaySize);
+        GradientColors colors = Dependency.get(SysuiColorExtractor.class).getColors(
+                onKeyguard ? WallpaperManager.FLAG_LOCK : WallpaperManager.FLAG_SYSTEM);
+        background.setColors(colors, false);
+        background.setScreenSize(displaySize.x, displaySize.y);
+
+        d.show();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
new file mode 100644
index 0000000..4c98c08
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
@@ -0,0 +1,86 @@
+/*
+ * 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.keyguard;
+
+import android.os.Handler;
+import android.os.Message;
+
+import com.android.internal.policy.IKeyguardDrawnCallback;
+
+/**
+ * Dispatches the lifecycles keyguard gets from WindowManager on the main thread.
+ */
+public class KeyguardLifecyclesDispatcher {
+
+    static final int SCREEN_TURNING_ON = 0;
+    static final int SCREEN_TURNED_ON = 1;
+    static final int SCREEN_TURNING_OFF = 2;
+    static final int SCREEN_TURNED_OFF = 3;
+
+    static final int STARTED_WAKING_UP = 4;
+    static final int FINISHED_WAKING_UP = 5;
+    static final int STARTED_GOING_TO_SLEEP = 6;
+    static final int FINISHED_GOING_TO_SLEEP = 7;
+
+    private final ScreenLifecycle mScreenLifecycle;
+    private final WakefulnessLifecycle mWakefulnessLifecycle;
+
+    public KeyguardLifecyclesDispatcher(ScreenLifecycle screenLifecycle,
+            WakefulnessLifecycle wakefulnessLifecycle) {
+        mScreenLifecycle = screenLifecycle;
+        mWakefulnessLifecycle = wakefulnessLifecycle;
+    }
+
+    void dispatch(int what) {
+        mHandler.obtainMessage(what).sendToTarget();
+    }
+
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case SCREEN_TURNING_ON:
+                    mScreenLifecycle.dispatchScreenTurningOn();
+                    break;
+                case SCREEN_TURNED_ON:
+                    mScreenLifecycle.dispatchScreenTurnedOn();
+                    break;
+                case SCREEN_TURNING_OFF:
+                    mScreenLifecycle.dispatchScreenTurningOff();
+                    break;
+                case SCREEN_TURNED_OFF:
+                    mScreenLifecycle.dispatchScreenTurnedOff();
+                    break;
+                case STARTED_WAKING_UP:
+                    mWakefulnessLifecycle.dispatchStartedWakingUp();
+                    break;
+                case FINISHED_WAKING_UP:
+                    mWakefulnessLifecycle.dispatchFinishedWakingUp();
+                    break;
+                case STARTED_GOING_TO_SLEEP:
+                    mWakefulnessLifecycle.dispatchStartedGoingToSleep();
+                    break;
+                case FINISHED_GOING_TO_SLEEP:
+                    mWakefulnessLifecycle.dispatchFinishedGoingToSleep();
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unknown message: " + msg);
+            }
+        }
+    };
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 2d5d198..2a5ae0d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -31,6 +31,7 @@
 import com.android.internal.policy.IKeyguardExitCallback;
 import com.android.internal.policy.IKeyguardService;
 import com.android.internal.policy.IKeyguardStateCallback;
+import com.android.systemui.Dependency;
 import com.android.systemui.SystemUIApplication;
 
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -40,12 +41,17 @@
     static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
 
     private KeyguardViewMediator mKeyguardViewMediator;
+    private KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher;
 
     @Override
     public void onCreate() {
         ((SystemUIApplication) getApplication()).startServicesIfNeeded();
         mKeyguardViewMediator =
                 ((SystemUIApplication) getApplication()).getComponent(KeyguardViewMediator.class);
+        mKeyguardLifecyclesDispatcher = new KeyguardLifecyclesDispatcher(
+                Dependency.get(ScreenLifecycle.class),
+                Dependency.get(WakefulnessLifecycle.class));
+
     }
 
     @Override
@@ -111,12 +117,16 @@
         public void onStartedGoingToSleep(int reason) {
             checkPermission();
             mKeyguardViewMediator.onStartedGoingToSleep(reason);
+            mKeyguardLifecyclesDispatcher.dispatch(
+                    KeyguardLifecyclesDispatcher.STARTED_GOING_TO_SLEEP);
         }
 
         @Override // Binder interface
         public void onFinishedGoingToSleep(int reason, boolean cameraGestureTriggered) {
             checkPermission();
             mKeyguardViewMediator.onFinishedGoingToSleep(reason, cameraGestureTriggered);
+            mKeyguardLifecyclesDispatcher.dispatch(
+                    KeyguardLifecyclesDispatcher.FINISHED_GOING_TO_SLEEP);
         }
 
         @Override // Binder interface
@@ -124,6 +134,15 @@
             Trace.beginSection("KeyguardService.mBinder#onStartedWakingUp");
             checkPermission();
             mKeyguardViewMediator.onStartedWakingUp();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.STARTED_WAKING_UP);
+            Trace.endSection();
+        }
+
+        @Override // Binder interface
+        public void onFinishedWakingUp() {
+            Trace.beginSection("KeyguardService.mBinder#onFinishedWakingUp");
+            checkPermission();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.FINISHED_WAKING_UP);
             Trace.endSection();
         }
 
@@ -132,6 +151,7 @@
             Trace.beginSection("KeyguardService.mBinder#onScreenTurningOn");
             checkPermission();
             mKeyguardViewMediator.onScreenTurningOn(callback);
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_ON);
             Trace.endSection();
         }
 
@@ -140,13 +160,21 @@
             Trace.beginSection("KeyguardService.mBinder#onScreenTurnedOn");
             checkPermission();
             mKeyguardViewMediator.onScreenTurnedOn();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_ON);
             Trace.endSection();
         }
 
         @Override // Binder interface
+        public void onScreenTurningOff() {
+            checkPermission();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_OFF);
+        }
+
+        @Override // Binder interface
         public void onScreenTurnedOff() {
             checkPermission();
             mKeyguardViewMediator.onScreenTurnedOff();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_OFF);
         }
 
         @Override // Binder interface
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 1ec52e7..d132e76 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -364,7 +364,10 @@
         public void onUserSwitchComplete(int userId) {
             if (userId != UserHandle.USER_SYSTEM) {
                 UserInfo info = UserManager.get(mContext).getUserInfo(userId);
-                if (info != null && (info.isGuest() || info.isDemo())) {
+                // Don't try to dismiss if the user has Pin/Patter/Password set
+                if (info == null || mLockPatternUtils.isSecure(userId)) {
+                    return;
+                } else if (info.isGuest() || info.isDemo()) {
                     // If we just switched to a guest, try to dismiss keyguard.
                     dismiss(null /* callback */);
                 }
@@ -656,7 +659,7 @@
     }
 
     boolean mustNotUnlockCurrentUser() {
-        return (UserManager.isSplitSystemUser() || UserManager.isDeviceInDemoMode(mContext))
+        return UserManager.isSplitSystemUser()
                 && KeyguardUpdateMonitor.getCurrentUser() == UserHandle.USER_SYSTEM;
     }
 
@@ -808,6 +811,7 @@
         synchronized (this) {
             mDeviceInteractive = false;
             mGoingToSleep = false;
+            mWakeAndUnlocking = false;
 
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
@@ -1173,6 +1177,7 @@
 
             if (mOccluded != isOccluded) {
                 mOccluded = isOccluded;
+                mUpdateMonitor.setKeyguardOccluded(isOccluded);
                 mStatusBarKeyguardViewManager.setOccluded(isOccluded, animate
                         && mDeviceInteractive);
                 adjustStatusBarLocked();
@@ -1953,7 +1958,6 @@
             if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOff");
             mStatusBarKeyguardViewManager.onScreenTurnedOff();
             mDrawnCallback = null;
-            mWakeAndUnlocking = false;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/Lifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/Lifecycle.java
new file mode 100644
index 0000000..1b20cfb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/Lifecycle.java
@@ -0,0 +1,42 @@
+/*
+ * 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.keyguard;
+
+import java.util.ArrayList;
+import java.util.function.Consumer;
+
+/**
+ * Base class for lifecycles with observers.
+ */
+public class Lifecycle<T> {
+
+    private ArrayList<T> mObservers = new ArrayList<>();
+
+    public void addObserver(T observer) {
+        mObservers.add(observer);
+    }
+
+    public void removeObserver(T observer) {
+        mObservers.remove(observer);
+    }
+
+    public void dispatch(Consumer<T> consumer) {
+        for (int i = 0; i < mObservers.size(); i++) {
+            consumer.accept(mObservers.get(i));
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java
new file mode 100644
index 0000000..b6fce44
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java
@@ -0,0 +1,80 @@
+/*
+ * 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.keyguard;
+
+import android.os.Trace;
+
+import com.android.systemui.Dumpable;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Tracks the screen lifecycle.
+ */
+public class ScreenLifecycle extends Lifecycle<ScreenLifecycle.Observer> implements Dumpable {
+
+    public static final int SCREEN_OFF = 0;
+    public static final int SCREEN_TURNING_ON = 1;
+    public static final int SCREEN_ON = 2;
+    public static final int SCREEN_TURNING_OFF = 3;
+
+    private int mScreenState = SCREEN_OFF;
+
+    public int getScreenState() {
+        return mScreenState;
+    }
+
+    public void dispatchScreenTurningOn() {
+        setScreenState(SCREEN_TURNING_ON);
+        dispatch(Observer::onScreenTurningOn);
+    }
+
+    public void dispatchScreenTurnedOn() {
+        setScreenState(SCREEN_ON);
+        dispatch(Observer::onScreenTurnedOn);
+    }
+
+    public void dispatchScreenTurningOff() {
+        setScreenState(SCREEN_TURNING_OFF);
+        dispatch(Observer::onScreenTurningOff);
+    }
+
+    public void dispatchScreenTurnedOff() {
+        setScreenState(SCREEN_OFF);
+        dispatch(Observer::onScreenTurnedOff);
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("ScreenLifecycle:");
+        pw.println("  mScreenState=" + mScreenState);
+    }
+
+    private void setScreenState(int screenState) {
+        mScreenState = screenState;
+        Trace.traceCounter(Trace.TRACE_TAG_APP, "screenState", screenState);
+    }
+
+    public interface Observer {
+        default void onScreenTurningOn() {}
+        default void onScreenTurnedOn() {}
+        default void onScreenTurningOff() {}
+        default void onScreenTurnedOff() {}
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
new file mode 100644
index 0000000..951c0ea
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
@@ -0,0 +1,80 @@
+/*
+ * 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.keyguard;
+
+import android.os.Trace;
+
+import com.android.systemui.Dumpable;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Tracks the wakefulness lifecycle.
+ */
+public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observer> implements
+        Dumpable {
+
+    public static final int WAKEFULNESS_ASLEEP = 0;
+    public static final int WAKEFULNESS_WAKING = 1;
+    public static final int WAKEFULNESS_AWAKE = 2;
+    public static final int WAKEFULNESS_GOING_TO_SLEEP = 3;
+
+    private int mWakefulness = WAKEFULNESS_ASLEEP;
+
+    public int getWakefulness() {
+        return mWakefulness;
+    }
+
+    public void dispatchStartedWakingUp() {
+        setWakefulness(WAKEFULNESS_WAKING);
+        dispatch(Observer::onStartedWakingUp);
+    }
+
+    public void dispatchFinishedWakingUp() {
+        setWakefulness(WAKEFULNESS_AWAKE);
+        dispatch(Observer::onFinishedWakingUp);
+    }
+
+    public void dispatchStartedGoingToSleep() {
+        setWakefulness(WAKEFULNESS_GOING_TO_SLEEP);
+        dispatch(Observer::onStartedGoingToSleep);
+    }
+
+    public void dispatchFinishedGoingToSleep() {
+        setWakefulness(WAKEFULNESS_ASLEEP);
+        dispatch(Observer::onFinishedGoingToSleep);
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("WakefulnessLifecycle:");
+        pw.println("  mWakefulness=" + mWakefulness);
+    }
+
+    private void setWakefulness(int wakefulness) {
+        mWakefulness = wakefulness;
+        Trace.traceCounter(Trace.TRACE_TAG_APP, "wakefulness", wakefulness);
+    }
+
+    public interface Observer {
+        default void onStartedWakingUp() {}
+        default void onFinishedWakingUp() {}
+        default void onStartedGoingToSleep() {}
+        default void onFinishedGoingToSleep() {}
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
index 6733421..abc5667 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
@@ -65,7 +65,7 @@
         }
 
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             boolean handled = true;
             try {
                 // To be implemented for input handling over Pip windows
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 0373d77..b3f992d 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -71,10 +71,6 @@
     TaskStackListener mTaskStackListener = new TaskStackListener() {
         @Override
         public void onActivityPinned(String packageName, int taskId) {
-            if (!checkCurrentUserId(mContext, false /* debug */)) {
-                return;
-            }
-
             mTouchHandler.onActivityPinned();
             mMediaController.onActivityPinned();
             mMenuController.onActivityPinned();
@@ -86,13 +82,10 @@
 
         @Override
         public void onActivityUnpinned() {
-            if (!checkCurrentUserId(mContext, false /* debug */)) {
-                return;
-            }
-
             ComponentName topPipActivity = PipUtils.getTopPinnedActivity(mContext,
                     mActivityManager);
-            mMenuController.hideMenu();
+            mMenuController.onActivityUnpinned(topPipActivity);
+            mTouchHandler.onActivityUnpinned(topPipActivity);
             mNotificationController.onActivityUnpinned(topPipActivity);
 
             SystemServicesProxy.getInstance(mContext).setPipVisibility(topPipActivity != null);
@@ -115,10 +108,6 @@
 
         @Override
         public void onPinnedActivityRestartAttempt(boolean clearedTask) {
-            if (!checkCurrentUserId(mContext, false /* debug */)) {
-                return;
-            }
-
             mTouchHandler.getMotionHelper().expandPip(clearedTask /* skipAnimation */);
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
index 62ec09b..b3a0794 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
@@ -26,14 +26,18 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.media.session.MediaSessionManager;
+import android.media.session.MediaSessionManager.OnActiveSessionsChangedListener;
 import android.media.session.PlaybackState;
 import android.os.UserHandle;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.UserInfoController;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -88,13 +92,21 @@
         }
     };
 
-    private MediaController.Callback mPlaybackChangedListener = new MediaController.Callback() {
+    private final MediaController.Callback mPlaybackChangedListener = new MediaController.Callback() {
         @Override
         public void onPlaybackStateChanged(PlaybackState state) {
             notifyActionsChanged();
         }
     };
 
+    private final MediaSessionManager.OnActiveSessionsChangedListener mSessionsChangedListener =
+            new OnActiveSessionsChangedListener() {
+        @Override
+        public void onActiveSessionsChanged(List<MediaController> controllers) {
+            resolveActiveMediaController(controllers);
+        }
+    };
+
     private ArrayList<ActionListener> mListeners = new ArrayList<>();
 
     public PipMediaController(Context context, IActivityManager activityManager) {
@@ -110,9 +122,11 @@
         createMediaActions();
         mMediaSessionManager =
                 (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE);
-        mMediaSessionManager.addOnActiveSessionsChangedListener(controllers -> {
-            resolveActiveMediaController(controllers);
-        }, null);
+
+        // The media session listener needs to be re-registered when switching users
+        UserInfoController userInfoController = Dependency.get(UserInfoController.class);
+        userInfoController.addCallback((String name, Drawable picture, String userAccount) ->
+                registerSessionListenerForCurrentUser());
     }
 
     /**
@@ -120,7 +134,8 @@
      */
     public void onActivityPinned() {
         // Once we enter PiP, try to find the active media controller for the top most activity
-        resolveActiveMediaController(mMediaSessionManager.getActiveSessions(null));
+        resolveActiveMediaController(mMediaSessionManager.getActiveSessionsForUser(null,
+                UserHandle.USER_CURRENT));
     }
 
     /**
@@ -201,6 +216,15 @@
     }
 
     /**
+     * Re-registers the session listener for the current user.
+     */
+    private void registerSessionListenerForCurrentUser() {
+        mMediaSessionManager.removeOnActiveSessionsChangedListener(mSessionsChangedListener);
+        mMediaSessionManager.addOnActiveSessionsChangedListener(mSessionsChangedListener, null,
+                UserHandle.USER_CURRENT, null);
+    }
+
+    /**
      * Tries to find and set the active media controller for the top PiP activity.
      */
     private void resolveActiveMediaController(List<MediaController> controllers) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index e310847..c558056 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -22,6 +22,7 @@
 import android.app.ActivityOptions;
 import android.app.IActivityManager;
 import android.app.RemoteAction;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ParceledListSlice;
@@ -32,6 +33,7 @@
 import android.os.Message;
 import android.os.Messenger;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.Log;
 import android.view.IWindowManager;
@@ -77,6 +79,9 @@
     public static final int MENU_STATE_CLOSE = 1;
     public static final int MENU_STATE_FULL = 2;
 
+    // The duration to wait before we consider the start activity as having timed out
+    private static final long START_ACTIVITY_REQUEST_TIMEOUT_MS = 300;
+
     /**
      * A listener interface to receive notification on changes in PIP.
      */
@@ -125,8 +130,9 @@
 
     private ReferenceCountedTrigger mOnAttachDecrementTrigger;
     private boolean mStartActivityRequested;
+    private long mStartActivityRequestedTime;
     private Messenger mToActivityMessenger;
-    private Messenger mMessenger = new Messenger(new Handler() {
+    private Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -161,7 +167,7 @@
                 }
                 case MESSAGE_UPDATE_ACTIVITY_CALLBACK: {
                     mToActivityMessenger = msg.replyTo;
-                    mStartActivityRequested = false;
+                    setStartActivityRequested(false);
                     if (mOnAttachDecrementTrigger != null) {
                         mOnAttachDecrementTrigger.decrement();
                         mOnAttachDecrementTrigger = null;
@@ -174,7 +180,17 @@
                 }
             }
         }
-    });
+    };
+    private Messenger mMessenger = new Messenger(mHandler);
+
+    private Runnable mStartActivityRequestedTimeoutRunnable = () -> {
+        setStartActivityRequested(false);
+        if (mOnAttachDecrementTrigger != null) {
+            mOnAttachDecrementTrigger.decrement();
+            mOnAttachDecrementTrigger = null;
+        }
+        Log.e(TAG, "Expected start menu activity request timed out");
+    };
 
     private ActionListener mMediaActionListener = new ActionListener() {
         @Override
@@ -202,6 +218,11 @@
         }
     }
 
+    public void onActivityUnpinned(ComponentName topPipActivity) {
+        hideMenu();
+        setStartActivityRequested(false);
+    }
+
     public void onPinnedStackAnimationEnded() {
         // Note: Only active menu activities care about this event
         if (mToActivityMessenger != null) {
@@ -243,7 +264,9 @@
             } catch (RemoteException e) {
                 Log.e(TAG, "Could not notify menu to update dismiss fraction", e);
             }
-        } else if (!mStartActivityRequested) {
+        } else if (!mStartActivityRequested || isStartActivityRequestedElapsed()) {
+            // If we haven't requested the start activity, or if it previously took too long to
+            // start, then start it
             startMenuActivity(MENU_STATE_NONE, null /* stackBounds */,
                     null /* movementBounds */, false /* allowMenuTimeout */);
         }
@@ -273,7 +296,9 @@
             } catch (RemoteException e) {
                 Log.e(TAG, "Could not notify menu to show", e);
             }
-        } else if (!mStartActivityRequested) {
+        } else if (!mStartActivityRequested || isStartActivityRequestedElapsed()) {
+            // If we haven't requested the start activity, or if it previously took too long to
+            // start, then start it
             startMenuActivity(menuState, stackBounds, movementBounds, allowMenuTimeout);
         }
     }
@@ -368,12 +393,12 @@
                         pinnedStackInfo.taskIds[pinnedStackInfo.taskIds.length - 1]);
                 options.setTaskOverlay(true, true /* canResume */);
                 mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT);
-                mStartActivityRequested = true;
+                setStartActivityRequested(true);
             } else {
                 Log.e(TAG, "No PIP tasks found");
             }
         } catch (RemoteException e) {
-            mStartActivityRequested = false;
+            setStartActivityRequested(false);
             Log.e(TAG, "Error showing PIP menu activity", e);
         }
     }
@@ -416,6 +441,14 @@
     }
 
     /**
+     * @return whether the time of the activity request has exceeded the timeout.
+     */
+    private boolean isStartActivityRequestedElapsed() {
+        return (SystemClock.uptimeMillis() - mStartActivityRequestedTime)
+                >= START_ACTIVITY_REQUEST_TIMEOUT_MS;
+    }
+
+    /**
      * Handles changes in menu visibility.
      */
     private void onMenuStateChanged(int menuState, boolean resize) {
@@ -443,12 +476,24 @@
         mMenuState = menuState;
     }
 
+    private void setStartActivityRequested(boolean requested) {
+        mHandler.removeCallbacks(mStartActivityRequestedTimeoutRunnable);
+        mStartActivityRequested = requested;
+        mStartActivityRequestedTime = requested ? SystemClock.uptimeMillis() : 0;
+    }
+
     public final void onBusEvent(HidePipMenuEvent event) {
         if (mStartActivityRequested) {
             // If the menu has been start-requested, but not actually started, then we defer the
-            // trigger callback until the menu has started and called back to the controller
+            // trigger callback until the menu has started and called back to the controller.
             mOnAttachDecrementTrigger = event.getAnimationTrigger();
             mOnAttachDecrementTrigger.increment();
+
+            // Fallback for b/63752800, we have started the PipMenuActivity but it has not made any
+            // callbacks. Don't continue to wait for the menu to show past some timeout.
+            mHandler.removeCallbacks(mStartActivityRequestedTimeoutRunnable);
+            mHandler.postDelayed(mStartActivityRequestedTimeoutRunnable,
+                    START_ACTIVITY_REQUEST_TIMEOUT_MS);
         }
     }
 
@@ -458,5 +503,7 @@
         pw.println(innerPrefix + "mMenuState=" + mMenuState);
         pw.println(innerPrefix + "mToActivityMessenger=" + mToActivityMessenger);
         pw.println(innerPrefix + "mListeners=" + mListeners.size());
+        pw.println(innerPrefix + "mStartActivityRequested=" + mStartActivityRequested);
+        pw.println(innerPrefix + "mStartActivityRequestedTime=" + mStartActivityRequestedTime);
     }
 }
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 b8771d7..cebb22f 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -241,14 +241,14 @@
     /**
      * Flings the minimized PiP to the closest minimized snap target.
      */
-    Rect flingToMinimizedState(float velocityY, Rect movementBounds) {
+    Rect flingToMinimizedState(float velocityY, Rect movementBounds, Point dragStartPosition) {
         cancelAnimations();
         // We currently only allow flinging the minimized stack up and down, so just lock the
         // movement bounds to the current stack bounds horizontally
         movementBounds = new Rect(mBounds.left, movementBounds.top, mBounds.left,
                 movementBounds.bottom);
         Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds,
-                0 /* velocityX */, velocityY);
+                0 /* velocityX */, velocityY, dragStartPosition);
         if (!mBounds.equals(toBounds)) {
             mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN);
             mFlingAnimationUtils.apply(mBoundsAnimator, 0,
@@ -281,10 +281,11 @@
      * Flings the PiP to the closest snap target.
      */
     Rect flingToSnapTarget(float velocity, float velocityX, float velocityY, Rect movementBounds,
-            AnimatorUpdateListener updateListener, AnimatorListener listener) {
+            AnimatorUpdateListener updateListener, AnimatorListener listener,
+            Point startPosition) {
         cancelAnimations();
         Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds,
-                velocityX, velocityY);
+                velocityX, velocityY, startPosition);
         if (!mBounds.equals(toBounds)) {
             mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN);
             mFlingAnimationUtils.apply(mBoundsAnimator, 0,
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 854696e..9b48320 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -25,10 +25,13 @@
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.IActivityManager;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.graphics.RectF;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.util.Log;
@@ -39,6 +42,7 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -116,10 +120,11 @@
             };
 
     // Behaviour states
-    private int mMenuState;
+    private int mMenuState = MENU_STATE_NONE;
     private boolean mIsMinimized;
     private boolean mIsImeShowing;
     private int mImeHeight;
+    private int mImeOffset;
     private float mSavedSnapFraction = -1f;
     private boolean mSendingHoverAccessibilityEvents;
     private boolean mMovementWithinMinimize;
@@ -184,14 +189,17 @@
         mDismissViewController = new PipDismissViewController(context);
         mSnapAlgorithm = new PipSnapAlgorithm(mContext);
         mTouchState = new PipTouchState(mViewConfig);
-        mFlingAnimationUtils = new FlingAnimationUtils(context, 2f);
+        mFlingAnimationUtils = new FlingAnimationUtils(context, 2.5f);
         mGestures = new PipTouchGesture[] {
                 mDefaultMovementGesture
         };
         mMotionHelper = new PipMotionHelper(mContext, mActivityManager, mMenuController,
                 mSnapAlgorithm, mFlingAnimationUtils);
-        mExpandedShortestEdgeSize = context.getResources().getDimensionPixelSize(
+
+        Resources res = context.getResources();
+        mExpandedShortestEdgeSize = res.getDimensionPixelSize(
                 R.dimen.pip_expanded_shortest_edge_size);
+        mImeOffset = res.getDimensionPixelSize(R.dimen.pip_ime_offset);
 
         // Register the listener for input consumer touch events
         inputConsumerController.setTouchListener(this::handleTouchEvent);
@@ -212,16 +220,17 @@
     }
 
     public void onActivityPinned() {
-        // Reset some states once we are pinned
-        mMenuState = MENU_STATE_NONE;
-
-        if (mIsMinimized) {
-            setMinimizedStateInternal(false);
-        }
-        cleanUpDismissTarget();
+        cleanUp();
         mShowPipMenuOnAnimationEnd = true;
     }
 
+    public void onActivityUnpinned(ComponentName topPipActivity) {
+        if (topPipActivity == null) {
+            // Clean up state after the last PiP activity is removed
+            cleanUp();
+        }
+    }
+
     public void onPinnedStackAnimationEnded() {
         // Always synchronize the motion helper bounds once PiP animations finish
         mMotionHelper.synchronizePinnedStackBounds();
@@ -262,7 +271,6 @@
         mSnapAlgorithm.getMovementBounds(mExpandedBounds, insetBounds, expandedMovementBounds,
                 mIsImeShowing ? mImeHeight : 0);
 
-
         // If this is from an IME adjustment, then we should move the PiP so that it is not occluded
         // by the IME
         if (fromImeAdjustement) {
@@ -275,18 +283,22 @@
                         ? expandedMovementBounds
                         : normalMovementBounds;
                 if (mIsImeShowing) {
-                    // IME visible
+                    // IME visible, apply the IME offset if the space allows for it
+                    final int imeOffset = toMovementBounds.bottom - Math.max(toMovementBounds.top,
+                            toMovementBounds.bottom - mImeOffset);
                     if (bounds.top == mMovementBounds.bottom) {
                         // If the PIP is currently resting on top of the IME, then adjust it with
-                        // the hiding IME
-                        bounds.offsetTo(bounds.left, toMovementBounds.bottom);
+                        // the showing IME
+                        bounds.offsetTo(bounds.left, toMovementBounds.bottom - imeOffset);
                     } else {
-                        bounds.offset(0, Math.min(0, toMovementBounds.bottom - bounds.top));
+                        bounds.offset(0, Math.min(0, toMovementBounds.bottom - imeOffset
+                                - bounds.top));
                     }
                 } else {
                     // IME hidden
-                    if (bounds.top == mMovementBounds.bottom) {
-                        // If the PIP is resting on top of the IME, then adjust it with the hiding IME
+                    if (bounds.top >= (mMovementBounds.bottom - mImeOffset)) {
+                        // If the PIP is resting on top of the IME, then adjust it with the hiding
+                        // IME
                         bounds.offsetTo(bounds.left, toMovementBounds.bottom);
                     }
                 }
@@ -376,10 +388,10 @@
                 if (!mSendingHoverAccessibilityEvents) {
                     AccessibilityEvent event = AccessibilityEvent.obtain(
                             AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
-                    AccessibilityNodeInfo info =
-                            PipAccessibilityInteractionConnection.obtainRootAccessibilityNodeInfo();
-                    event.setSource(info);
-                    info.recycle();
+                    event.setImportantForAccessibility(true);
+                    event.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID);
+                    event.setWindowId(
+                            AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID);
                     mAccessibilityManager.sendAccessibilityEvent(event);
                     mSendingHoverAccessibilityEvents = true;
                 }
@@ -389,10 +401,10 @@
                 if (mSendingHoverAccessibilityEvents) {
                     AccessibilityEvent event = AccessibilityEvent.obtain(
                             AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
-                    AccessibilityNodeInfo info =
-                            PipAccessibilityInteractionConnection.obtainRootAccessibilityNodeInfo();
-                    event.setSource(info);
-                    info.recycle();
+                    event.setImportantForAccessibility(true);
+                    event.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID);
+                    event.setWindowId(
+                            AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID);
                     mAccessibilityManager.sendAccessibilityEvent(event);
                     mSendingHoverAccessibilityEvents = false;
                 }
@@ -405,7 +417,7 @@
     /**
      * Updates the appearance of the menu and scrim on top of the PiP while dismissing.
      */
-    void updateDismissFraction() {
+    private void updateDismissFraction() {
         if (mMenuController != null) {
             Rect bounds = mMotionHelper.getBounds();
             final float target = mMovementBounds.bottom + bounds.height();
@@ -431,7 +443,7 @@
     /**
      * Sets the minimized state.
      */
-    void setMinimizedStateInternal(boolean isMinimized) {
+    private void setMinimizedStateInternal(boolean isMinimized) {
         if (!ENABLE_MINIMIZE) {
             return;
         }
@@ -470,7 +482,7 @@
     /**
      * Sets the menu visibility.
      */
-    void setMenuState(int menuState, boolean resize) {
+    private void setMenuState(int menuState, boolean resize) {
         if (menuState == MENU_STATE_FULL) {
             // Save the current snap fraction and if we do not drag or move the PiP, then
             // we store back to this snap fraction.  Otherwise, we'll reset the snap
@@ -538,6 +550,8 @@
     private PipTouchGesture mDefaultMovementGesture = new PipTouchGesture() {
         // Whether the PiP was on the left side of the screen at the start of the gesture
         private boolean mStartedOnLeft;
+        private final Point mStartPosition = new Point();
+        private final PointF mDelta = new PointF();
 
         @Override
         public void onDown(PipTouchState touchState) {
@@ -545,7 +559,10 @@
                 return;
             }
 
-            mStartedOnLeft = mMotionHelper.getBounds().left < mMovementBounds.centerX();
+            Rect bounds = mMotionHelper.getBounds();
+            mDelta.set(0f, 0f);
+            mStartPosition.set(bounds.left, bounds.top);
+            mStartedOnLeft = bounds.left < mMovementBounds.centerX();
             mMovementWithinMinimize = true;
             mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mMovementBounds.bottom;
 
@@ -578,10 +595,11 @@
 
             if (touchState.isDragging()) {
                 // Move the pinned stack freely
-                mTmpBounds.set(mMotionHelper.getBounds());
                 final PointF lastDelta = touchState.getLastTouchDelta();
-                float left = mTmpBounds.left + lastDelta.x;
-                float top = mTmpBounds.top + lastDelta.y;
+                float lastX = mStartPosition.x + mDelta.x;
+                float lastY = mStartPosition.y + mDelta.y;
+                float left = lastX + lastDelta.x;
+                float top = lastY + lastDelta.y;
                 if (!touchState.allowDraggingOffscreen() || !ENABLE_MINIMIZE) {
                     left = Math.max(mMovementBounds.left, Math.min(mMovementBounds.right, left));
                 }
@@ -591,6 +609,12 @@
                 } else {
                     top = Math.max(mMovementBounds.top, Math.min(mMovementBounds.bottom, top));
                 }
+
+                // Add to the cumulative delta after bounding the position
+                mDelta.x += left - lastX;
+                mDelta.y += top - lastY;
+
+                mTmpBounds.set(mMotionHelper.getBounds());
                 mTmpBounds.offsetTo((int) left, (int) top);
                 mMotionHelper.movePip(mTmpBounds);
 
@@ -691,7 +715,8 @@
 
                 if (isFling) {
                     mMotionHelper.flingToSnapTarget(velocity, vel.x, vel.y, mMovementBounds,
-                            mUpdateScrimListener, postAnimationCallback);
+                            mUpdateScrimListener, postAnimationCallback,
+                            mStartPosition);
                 } else {
                     mMotionHelper.animateToClosestSnapTarget(mMovementBounds, mUpdateScrimListener,
                             postAnimationCallback);
@@ -735,6 +760,16 @@
         mDismissViewController.destroyDismissTarget();
     }
 
+    /**
+     * Resets some states related to the touch handling.
+     */
+    private void cleanUp() {
+        if (mIsMinimized) {
+            setMinimizedStateInternal(false);
+        }
+        cleanUpDismissTarget();
+    }
+
     public void dump(PrintWriter pw, String prefix) {
         final String innerPrefix = prefix + "  ";
         pw.println(prefix + TAG);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
index b2b5b02..686b3bb 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
@@ -29,7 +29,7 @@
  */
 public class PipTouchState {
     private static final String TAG = "PipTouchHandler";
-    private static final boolean DEBUG = true;
+    private static final boolean DEBUG = false;
 
     private ViewConfiguration mViewConfig;
 
@@ -61,7 +61,7 @@
     }
 
     /**
-     * Processess a given touch event and updates the state.
+     * Processes a given touch event and updates the state.
      */
     public void onTouchEvent(MotionEvent ev) {
         switch (ev.getAction()) {
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java
new file mode 100644
index 0000000..9becc38
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java
@@ -0,0 +1,43 @@
+/*
+ * 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.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+
+public class PluginActivityManager {
+
+    private final Context mContext;
+    private final PluginManager mPluginManager;
+    private final ArrayMap<String, String> mActionLookup = new ArrayMap<>();
+
+    public PluginActivityManager(Context context, PluginManager pluginManager) {
+        mContext = context;
+        mPluginManager = pluginManager;
+    }
+
+    public void addActivityPlugin(String className, String action) {
+        mActionLookup.put(className, action);
+    }
+
+    public Activity instantiate(ClassLoader cl, String className, Intent intent) {
+        String action = mActionLookup.get(className);
+        if (TextUtils.isEmpty(action)) return null;
+        return mPluginManager.getOneShotPlugin(action, PluginActivity.class);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
index 493d244..a968399 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
@@ -42,7 +42,6 @@
 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;
@@ -120,14 +119,21 @@
         }
         PluginInstanceManager<T> p = mFactory.createPluginInstanceManager(mContext, action, null,
                 false, mLooper, cls, this);
+        PluginListener<Plugin> listener = new PluginListener<Plugin>() {
+            @Override
+            public void onPluginConnected(Plugin plugin, Context pluginContext) { }
+        };
+        mPluginMap.put(listener, p);
         mPluginPrefs.addAction(action);
-        PluginInfo<T> info = p.getPlugin();
+        PluginInstanceManager.PluginInfo<T> info = p.getPlugin();
         if (info != null) {
             mOneShotPackages.add(info.mPackage);
             mHasOneShot = true;
             startListening();
+            mPluginMap.remove(listener);
             return info.mPlugin;
         }
+        mPluginMap.remove(listener);
         return null;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 6b3daa3..b007f92 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -104,10 +104,9 @@
     private SystemUIDialog mHighTempDialog;
     private SystemUIDialog mThermalShutdownDialog;
 
-    public PowerNotificationWarnings(Context context, NotificationManager notificationManager,
-            StatusBar statusBar) {
+    public PowerNotificationWarnings(Context context) {
         mContext = context;
-        mNoMan = notificationManager;
+        mNoMan = mContext.getSystemService(NotificationManager.class);
         mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mReceiver.init();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index a642077..beb7712 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -16,12 +16,13 @@
 
 package com.android.systemui.power;
 
-import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.os.BatteryManager;
@@ -31,14 +32,17 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.Log;
 import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.statusbar.phone.StatusBar;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.Arrays;
@@ -56,6 +60,7 @@
     private PowerManager mPowerManager;
     private HardwarePropertiesManager mHardwarePropertiesManager;
     private WarningsUI mWarnings;
+    private final Configuration mLastConfiguration = new Configuration();
     private int mBatteryLevel = 100;
     private int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
     private int mPlugType = 0;
@@ -71,15 +76,18 @@
     private int mNumTemps;
     private long mNextLogTime;
 
+    // We create a method reference here so that we are guaranteed that we can remove a callback
+    // by using the same instance (method references are not guaranteed to be the same object
+    // each time they are created).
+    private final Runnable mUpdateTempCallback = this::updateTemperatureWarning;
+
     public void start() {
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mHardwarePropertiesManager = (HardwarePropertiesManager)
                 mContext.getSystemService(Context.HARDWARE_PROPERTIES_SERVICE);
         mScreenOffTime = mPowerManager.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
-        mWarnings = new PowerNotificationWarnings(
-                mContext,
-                (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE),
-                getComponent(StatusBar.class));
+        mWarnings = Dependency.get(WarningsUI.class);
+        mLastConfiguration.setTo(mContext.getResources().getConfiguration());
 
         ContentObserver obs = new ContentObserver(mHandler) {
             @Override
@@ -101,6 +109,16 @@
         initTemperatureWarning();
     }
 
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        final int mask = ActivityInfo.CONFIG_MCC | ActivityInfo.CONFIG_MNC;
+
+        // Safe to modify mLastConfiguration here as it's only updated by the main thread (here).
+        if ((mLastConfiguration.updateFrom(newConfig) & mask) != 0) {
+            mHandler.post(this::initTemperatureWarning);
+        }
+    }
+
     void updateBatteryWarningLevels() {
         int critLevel = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
@@ -247,16 +265,23 @@
             // Get the throttling temperature. No need to check if we're not throttling.
             float[] throttlingTemps = mHardwarePropertiesManager.getDeviceTemperatures(
                     HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
-                    HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+                    HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
             if (throttlingTemps == null
                     || throttlingTemps.length == 0
                     || throttlingTemps[0] == HardwarePropertiesManager.UNDEFINED_TEMPERATURE) {
                 return;
             }
-            mThresholdTemp = throttlingTemps[0];
+            mThresholdTemp = throttlingTemps[0] -
+                    resources.getInteger(R.integer.config_warningTemperatureTolerance);
         }
+
         setNextLogTime();
 
+        // This initialization method may be called on a configuration change. Only one set of
+        // ongoing callbacks should be occurring, so remove any now. updateTemperatureWarning will
+        // schedule an ongoing callback.
+        mHandler.removeCallbacks(mUpdateTempCallback);
+
         // We have passed all of the checks, start checking the temp
         updateTemperatureWarning();
     }
@@ -268,7 +293,8 @@
         }
     }
 
-    private void updateTemperatureWarning() {
+    @VisibleForTesting
+    protected void updateTemperatureWarning() {
         float[] temps = mHardwarePropertiesManager.getDeviceTemperatures(
                 HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
                 HardwarePropertiesManager.TEMPERATURE_CURRENT);
@@ -288,7 +314,7 @@
 
         logTemperatureStats();
 
-        mHandler.postDelayed(this::updateTemperatureWarning, TEMPERATURE_INTERVAL);
+        mHandler.postDelayed(mUpdateTempCallback, TEMPERATURE_INTERVAL);
     }
 
     private void logAtTemperatureThreshold(float temp) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.java b/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.java
new file mode 100644
index 0000000..f960dc5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.java
@@ -0,0 +1,98 @@
+/*
+ * 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.qs;
+
+import static com.android.systemui.statusbar.phone.AutoTileManager.HOTSPOT;
+import static com.android.systemui.statusbar.phone.AutoTileManager.INVERSION;
+import static com.android.systemui.statusbar.phone.AutoTileManager.NIGHT;
+import static com.android.systemui.statusbar.phone.AutoTileManager.SAVER;
+import static com.android.systemui.statusbar.phone.AutoTileManager.WORK;
+
+import android.content.Context;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.provider.Settings.Secure;
+import android.text.TextUtils;
+import android.util.ArraySet;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.Prefs;
+import com.android.systemui.Prefs.Key;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+public class AutoAddTracker {
+
+    private static final String[][] CONVERT_PREFS = {
+            {Key.QS_HOTSPOT_ADDED, HOTSPOT},
+            {Key.QS_DATA_SAVER_ADDED, SAVER},
+            {Key.QS_INVERT_COLORS_ADDED, INVERSION},
+            {Key.QS_WORK_ADDED, WORK},
+            {Key.QS_NIGHTDISPLAY_ADDED, NIGHT},
+    };
+
+    private final ArraySet<String> mAutoAdded;
+    private final Context mContext;
+
+    public AutoAddTracker(Context context) {
+        mContext = context;
+        mAutoAdded = new ArraySet<>(getAdded());
+        for (String[] convertPref : CONVERT_PREFS) {
+            if (Prefs.getBoolean(context, convertPref[0], false)) {
+                setTileAdded(convertPref[1]);
+                Prefs.putBoolean(context, convertPref[0], false);
+            }
+        }
+        mContext.getContentResolver().registerContentObserver(
+                Secure.getUriFor(Secure.QS_AUTO_ADDED_TILES), false, mObserver);
+    }
+
+    public boolean isAdded(String tile) {
+        return mAutoAdded.contains(tile);
+    }
+
+    public void setTileAdded(String tile) {
+        if (mAutoAdded.add(tile)) {
+            saveTiles();
+        }
+    }
+
+    public void destroy() {
+        mContext.getContentResolver().unregisterContentObserver(mObserver);
+    }
+
+    private void saveTiles() {
+        Secure.putString(mContext.getContentResolver(), Secure.QS_AUTO_ADDED_TILES,
+                TextUtils.join(",", mAutoAdded));
+    }
+
+    private Collection<String> getAdded() {
+        String current = Secure.getString(mContext.getContentResolver(), Secure.QS_AUTO_ADDED_TILES);
+        if (current == null) {
+            return Collections.emptyList();
+        }
+        return Arrays.asList(current.split(","));
+    }
+
+    @VisibleForTesting
+    protected final ContentObserver mObserver = new ContentObserver(new Handler()) {
+        @Override
+        public void onChange(boolean selfChange) {
+            mAutoAdded.addAll(getAdded());
+        }
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java b/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java
index 5b3ec08..3d8f9ff 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java
@@ -16,12 +16,14 @@
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.service.quicksettings.Tile;
 import android.widget.ImageView;
 
 import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.plugins.qs.QSTile.Icon;
 import com.android.systemui.plugins.qs.QSTile.State;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.phone.SignalDrawable;
 
 import java.util.Objects;
@@ -35,7 +37,8 @@
     public CellTileView(Context context) {
         super(context);
         mSignalDrawable = new SignalDrawable(mContext);
-        mSignalDrawable.setDarkIntensity(isDark(mContext));
+        mSignalDrawable.setColors(QSTileImpl.getColorForState(context, Tile.STATE_UNAVAILABLE),
+                QSTileImpl.getColorForState(context, Tile.STATE_ACTIVE));
         mSignalDrawable.setIntrinsicSize(context.getResources().getDimensionPixelSize(
                 R.dimen.qs_tile_icon_size));
     }
@@ -48,10 +51,6 @@
         }
     }
 
-    private static int isDark(Context context) {
-        return Utils.getColorAttr(context, android.R.attr.colorForeground) == 0xff000000 ? 1 : 0;
-    }
-
     public static class SignalIcon extends Icon {
 
         private final int mState;
@@ -68,7 +67,8 @@
         public Drawable getDrawable(Context context) {
             //TODO: Not the optimal solution to create this drawable
             SignalDrawable d = new SignalDrawable(context);
-            d.setDarkIntensity(isDark(context));
+            d.setColors(QSTileImpl.getColorForState(context, Tile.STATE_UNAVAILABLE),
+                    QSTileImpl.getColorForState(context, Tile.STATE_ACTIVE));
             d.setLevel(getState());
             return d;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 0d74b7a..ed57c04 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -39,8 +39,6 @@
     protected float mQsExpansion;
     private QSCustomizer mQSCustomizer;
     private QSFooter mQSFooter;
-    private int mGutterHeight;
-    private View mBackground;
     private float mFullElevation;
 
     public QSContainerImpl(Context context, AttributeSet attrs) {
@@ -55,8 +53,6 @@
         mHeader = findViewById(R.id.header);
         mQSCustomizer = findViewById(R.id.qs_customize);
         mQSFooter = findViewById(R.id.qs_footer);
-        mBackground = findViewById(R.id.qs_background);
-        mGutterHeight = getContext().getResources().getDimensionPixelSize(R.dimen.qs_gutter_height);
         mFullElevation = mQSPanel.getElevation();
 
         setClickable(true);
@@ -110,18 +106,10 @@
 
     public void updateExpansion() {
         int height = calculateContainerHeight();
-        int gutterHeight = Math.round(mQsExpansion * mGutterHeight);
-        setBottom(getTop() + height + gutterHeight);
+        setBottom(getTop() + height);
         mQSDetail.setBottom(getTop() + height);
-        mBackground.setBottom(getTop() + height);
         // Pin QS Footer to the bottom of the panel.
         mQSFooter.setTranslationY(height - mQSFooter.getHeight());
-
-        float elevation = mQsExpansion * mFullElevation;
-        mQSDetail.setElevation(elevation);
-        mBackground.setElevation(elevation);
-        mQSFooter.setElevation(elevation);
-        mQSPanel.setElevation(elevation);
     }
 
     protected int calculateContainerHeight() {
@@ -135,17 +123,4 @@
         mQsExpansion = expansion;
         updateExpansion();
     }
-
-    public void setGutterEnabled(boolean gutterEnabled) {
-        if (gutterEnabled == (mGutterHeight != 0)) {
-            return;
-        }
-        if (gutterEnabled) {
-            mGutterHeight = getContext().getResources().getDimensionPixelSize(
-                    R.dimen.qs_gutter_height);
-        } else {
-            mGutterHeight = 0;
-        }
-        updateExpansion();
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index 697db5f..10514a7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -287,11 +287,17 @@
         mScanState = state;
         final Animatable anim = (Animatable) mQsDetailHeaderProgress.getDrawable();
         if (state) {
-            mQsDetailHeaderProgress.animate().alpha(1f);
-            anim.start();
+            mQsDetailHeaderProgress.animate().cancel();
+            mQsDetailHeaderProgress.animate()
+                    .alpha(1)
+                    .withEndAction(anim::start)
+                    .start();
         } else {
-            mQsDetailHeaderProgress.animate().alpha(0f);
-            anim.stop();
+            mQsDetailHeaderProgress.animate().cancel();
+            mQsDetailHeaderProgress.animate()
+                    .alpha(0f)
+                    .withEndAction(anim::stop)
+                    .start();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java
index a318efc..c454048 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java
@@ -100,4 +100,8 @@
             mAnimator = null;
         };
     };
+
+    public void showBackground() {
+        mBackground.showSecondLayer();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index 488fc03..f47ef1e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -45,6 +45,7 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.keyguard.KeyguardStatusView;
 import com.android.settingslib.Utils;
+import com.android.settingslib.drawable.UserIconDrawable;
 import com.android.systemui.Dependency;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
@@ -169,12 +170,14 @@
         int defSpace = mContext.getResources().getDimensionPixelOffset(R.dimen.default_gear_space);
 
         mAnimator = new Builder()
-                .addFloat(mSettingsContainer, "translationX", -(remaining - defSpace), 0)
+                .addFloat(mSettingsContainer, "translationX",
+                        isLayoutRtl() ? (remaining - defSpace) : -(remaining - defSpace), 0)
                 .addFloat(mSettingsButton, "rotation", -120, 0)
                 .build();
         if (mAlarmShowing) {
+            int translate = isLayoutRtl() ? mDate.getWidth() : -mDate.getWidth();
             mAlarmAnimator = new Builder().addFloat(mDate, "alpha", 1, 0)
-                    .addFloat(mDateTimeGroup, "translationX", 0, -mDate.getWidth())
+                    .addFloat(mDateTimeGroup, "translationX", 0, translate)
                     .addFloat(mAlarmStatus, "alpha", 0, 1)
                     .setListener(new ListenerAdapter() {
                         @Override
@@ -427,8 +430,9 @@
     @Override
     public void onUserInfoChanged(String name, Drawable picture, String userAccount) {
         if (picture != null &&
-                UserManager.get(mContext).isGuestUser(ActivityManager.getCurrentUser())) {
-            picture = picture.getConstantState().newDrawable().mutate();
+                UserManager.get(mContext).isGuestUser(ActivityManager.getCurrentUser()) &&
+                !(picture instanceof UserIconDrawable)) {
+            picture = picture.getConstantState().newDrawable(mContext.getResources()).mutate();
             picture.setColorFilter(
                     Utils.getColorAttr(mContext, android.R.attr.colorForeground),
                     Mode.SRC_IN);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 39ef6c5..dc81772 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -63,7 +63,6 @@
     private QSContainerImpl mContainer;
     private int mLayoutDirection;
     private QSFooter mFooter;
-    private int mGutterHeight;
 
     @Override
     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@@ -80,7 +79,6 @@
         mHeader = view.findViewById(R.id.header);
         mFooter = view.findViewById(R.id.qs_footer);
         mContainer = view.findViewById(id.quick_settings_container);
-        mGutterHeight = getContext().getResources().getDimensionPixelSize(R.dimen.qs_gutter_height);
 
         mQSDetail.setQsPanel(mQSPanel, mHeader, mFooter);
 
@@ -96,6 +94,13 @@
         if (savedInstanceState != null) {
             setExpanded(savedInstanceState.getBoolean(EXTRA_EXPANDED));
             setListening(savedInstanceState.getBoolean(EXTRA_LISTENING));
+            int[] loc = new int[2];
+            View edit = view.findViewById(android.R.id.edit);
+            edit.getLocationInWindow(loc);
+            int x = loc[0] + edit.getWidth() / 2;
+            int y = loc[1] + edit.getHeight() / 2;
+            mQSCustomizer.setEditLocation(x, y);
+            mQSCustomizer.restoreInstanceState(savedInstanceState);
         }
     }
 
@@ -112,6 +117,7 @@
         super.onSaveInstanceState(outState);
         outState.putBoolean(EXTRA_EXPANDED, mQsExpanded);
         outState.putBoolean(EXTRA_LISTENING, mListening);
+        mQSCustomizer.saveInstanceState(outState);
     }
 
     @VisibleForTesting
@@ -131,7 +137,6 @@
 
     @Override
     public void setHasNotifications(boolean hasNotifications) {
-        mContainer.setGutterEnabled(hasNotifications);
     }
 
     public void setPanelView(HeightListener panelView) {
@@ -250,7 +255,7 @@
         mContainer.setExpansion(expansion);
         final float translationScaleY = expansion - 1;
         if (!mHeaderAnimating) {
-            int height = mHeader.getHeight() + mGutterHeight;
+            int height = mHeader.getHeight();
             getView().setTranslationY(mKeyguardShowing ? (translationScaleY * height)
                     : headerTranslation);
         }
@@ -334,15 +339,15 @@
             LayoutParams layoutParams = (LayoutParams) mQSPanel.getLayoutParams();
             int panelHeight = layoutParams.topMargin + layoutParams.bottomMargin +
                     + mQSPanel.getMeasuredHeight();
-            return panelHeight + getView().getPaddingBottom() + mGutterHeight;
+            return panelHeight + getView().getPaddingBottom();
         } else {
-            return getView().getMeasuredHeight() + mGutterHeight;
+            return getView().getMeasuredHeight();
         }
     }
 
     @Override
     public void setHeightOverride(int desiredHeight) {
-        mContainer.setHeightOverride(desiredHeight - mGutterHeight);
+        mContainer.setHeightOverride(desiredHeight);
     }
 
     public int getQsMinExpansionHeight() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index c4d88ae..8f41084 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -46,6 +46,7 @@
 import com.android.systemui.settings.BrightnessController;
 import com.android.systemui.settings.ToggleSliderView;
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
+import com.android.systemui.statusbar.policy.BrightnessMirrorController.BrightnessMirrorListener;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
 
@@ -53,7 +54,7 @@
 import java.util.Collection;
 
 /** View that represents the quick settings tile panel. **/
-public class QSPanel extends LinearLayout implements Tunable, Callback {
+public class QSPanel extends LinearLayout implements Tunable, Callback, BrightnessMirrorListener {
 
     public static final String QS_SHOW_BRIGHTNESS = "qs_show_brightness";
 
@@ -152,6 +153,9 @@
         if (mHost != null) {
             setTiles(mHost.getTiles());
         }
+        if (mBrightnessMirrorController != null) {
+            mBrightnessMirrorController.addCallback(this);
+        }
     }
 
     @Override
@@ -163,6 +167,9 @@
         for (TileRecord record : mRecords) {
             record.tile.removeCallbacks();
         }
+        if (mBrightnessMirrorController != null) {
+            mBrightnessMirrorController.removeCallback(this);
+        }
         super.onDetachedFromWindow();
     }
 
@@ -194,12 +201,19 @@
     }
 
     public void setBrightnessMirror(BrightnessMirrorController c) {
+        if (mBrightnessMirrorController != null) {
+            mBrightnessMirrorController.removeCallback(this);
+        }
         mBrightnessMirrorController = c;
-        ToggleSliderView brightnessSlider = findViewById(R.id.brightness_slider);
-        ToggleSliderView mirror = c.getMirror().findViewById(
-                R.id.brightness_slider);
-        brightnessSlider.setMirror(mirror);
-        brightnessSlider.setMirrorController(c);
+        if (mBrightnessMirrorController != null) {
+            mBrightnessMirrorController.addCallback(this);
+        }
+        updateBrightnessMirror();
+    }
+
+    @Override
+    public void onBrightnessMirrorReinflated(View brightnessMirror) {
+        updateBrightnessMirror();
     }
 
     View getBrightnessView() {
@@ -246,9 +260,16 @@
         super.onConfigurationChanged(newConfig);
         mFooter.onConfigurationChanged();
 
+        updateBrightnessMirror();
+    }
+
+    public void updateBrightnessMirror() {
         if (mBrightnessMirrorController != null) {
-            // Reload the mirror in case it got reinflated but we didn't.
-            setBrightnessMirror(mBrightnessMirrorController);
+            ToggleSliderView brightnessSlider = findViewById(R.id.brightness_slider);
+            ToggleSliderView mirrorSlider = mBrightnessMirrorController.getMirror()
+                    .findViewById(R.id.brightness_slider);
+            brightnessSlider.setMirror(mirrorSlider);
+            brightnessSlider.setMirrorController(mBrightnessMirrorController);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index d434f2f..3ce1465c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -15,18 +15,22 @@
  */
 package com.android.systemui.qs;
 
+import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.pm.UserInfo;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.text.SpannableStringBuilder;
 import android.text.method.LinkMovementMethod;
 import android.text.style.ClickableSpan;
 import android.util.Log;
+import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -58,6 +62,8 @@
     private final Handler mMainHandler;
     private final View mDivider;
 
+    private final UserManager mUm;
+
     private AlertDialog mDialog;
     private QSTileHost mHost;
     protected H mHandler;
@@ -80,6 +86,7 @@
         mSecurityController = Dependency.get(SecurityController.class);
         mHandler = new H(Dependency.get(Dependency.BG_LOOPER));
         mDivider = qsPanel == null ? null : qsPanel.getDivider();
+        mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
     }
 
     public void setHostEnvironment(QSTileHost host) {
@@ -127,6 +134,9 @@
 
     private void handleRefreshState() {
         final boolean isDeviceManaged = mSecurityController.isDeviceManaged();
+        final UserInfo currentUser = mUm.getUserInfo(ActivityManager.getCurrentUser());
+        final boolean isDemoDevice = UserManager.isDeviceInDemoMode(mContext) && currentUser != null
+                && currentUser.isDemo();
         final boolean hasWorkProfile = mSecurityController.hasWorkProfile();
         final boolean hasCACerts = mSecurityController.hasCACertInCurrentUser();
         final boolean hasCACertsInWorkProfile = mSecurityController.hasCACertInWorkProfile();
@@ -136,7 +146,7 @@
         final CharSequence organizationName = mSecurityController.getDeviceOwnerOrganizationName();
         final CharSequence workProfileName = mSecurityController.getWorkProfileOrganizationName();
         // Update visibility of footer
-        mIsVisible = isDeviceManaged || hasCACerts || hasCACertsInWorkProfile ||
+        mIsVisible = (isDeviceManaged && !isDemoDevice) || hasCACerts || hasCACertsInWorkProfile ||
             vpnName != null || vpnNameWorkProfile != null;
         // Update the string
         mFooterTextContent = getFooterText(isDeviceManaged, hasWorkProfile,
@@ -244,8 +254,9 @@
 
         mDialog = new SystemUIDialog(mContext);
         mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
-        View dialogView = LayoutInflater.from(mContext)
-               .inflate(R.layout.quick_settings_footer_dialog, null, false);
+        View dialogView = LayoutInflater.from(
+                new ContextThemeWrapper(mContext, R.style.Theme_SystemUI_Dialog))
+                .inflate(R.layout.quick_settings_footer_dialog, null, false);
         mDialog.setView(dialogView);
         mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(), this);
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index ad98013..b300e4a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -27,6 +27,7 @@
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.qs.QSTile.SignalState;
 import com.android.systemui.qs.tileimpl.QSIconViewImpl;
+import com.android.systemui.qs.tileimpl.SlashImageView;
 
 /** View that represents a custom quick settings tile for displaying signal info (wifi/cell). **/
 public class SignalTileView extends QSIconViewImpl {
@@ -62,7 +63,7 @@
     @Override
     protected View createIcon() {
         mIconFrame = new FrameLayout(mContext);
-        mSignal = new ImageView(mContext);
+        mSignal = new SlashImageView(mContext);
         mIconFrame.addView(mSignal);
         mOverlay = new ImageView(mContext);
         mIconFrame.addView(mOverlay, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java b/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java
new file mode 100644
index 0000000..c356148
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java
@@ -0,0 +1,228 @@
+/*
+ * 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.qs;
+
+import static com.android.systemui.qs.tileimpl.QSIconViewImpl.QS_ANIM_LENGTH;
+
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.annotation.ColorInt;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.res.ColorStateList;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Path.Direction;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.util.FloatProperty;
+
+public class SlashDrawable extends Drawable {
+
+    public static final float CORNER_RADIUS = 1f;
+
+    private final Path mPath = new Path();
+    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    // These values are derived in un-rotated (vertical) orientation
+    private static final float SLASH_WIDTH = 1.8384776f;
+    private static final float SLASH_HEIGHT = 28f;
+    private static final float CENTER_X = 10.65f;
+    private static final float CENTER_Y = 11.869239f;
+    private static final float SCALE = 24f;
+
+    // Bottom is derived during animation
+    private static final float LEFT = (CENTER_X - (SLASH_WIDTH / 2)) / SCALE;
+    private static final float TOP = (CENTER_Y - (SLASH_HEIGHT / 2)) / SCALE;
+    private static final float RIGHT = (CENTER_X + (SLASH_WIDTH / 2)) / SCALE;
+    // Draw the slash washington-monument style; rotate to no-u-turn style
+    private static final float DEFAULT_ROTATION = -45f;
+
+    private Drawable mDrawable;
+    private final RectF mSlashRect = new RectF(0, 0, 0, 0);
+    private float mRotation;
+    private boolean mSlashed;
+    private Mode mTintMode;
+    private ColorStateList mTintList;
+    private boolean mAnimationEnabled = true;
+
+    public SlashDrawable(Drawable d) {
+        mDrawable = d;
+    }
+
+    @Override
+    public int getIntrinsicHeight() {
+        return mDrawable != null ? mDrawable.getIntrinsicHeight(): 0;
+    }
+
+    @Override
+    public int getIntrinsicWidth() {
+        return mDrawable != null ? mDrawable.getIntrinsicWidth(): 0;
+    }
+
+    @Override
+    protected void onBoundsChange(Rect bounds) {
+        super.onBoundsChange(bounds);
+        mDrawable.setBounds(bounds);
+    }
+
+    public void setDrawable(Drawable d) {
+        mDrawable = d;
+        mDrawable.setCallback(getCallback());
+        mDrawable.setBounds(getBounds());
+        if (mTintMode != null) mDrawable.setTintMode(mTintMode);
+        if (mTintList != null) mDrawable.setTintList(mTintList);
+        invalidateSelf();
+    }
+
+    public void setRotation(float rotation) {
+        if (mRotation == rotation) return;
+        mRotation = rotation;
+        invalidateSelf();
+    }
+
+    public void setAnimationEnabled(boolean enabled) {
+        mAnimationEnabled = enabled;
+    }
+
+    // Animate this value on change
+    private float mCurrentSlashLength;
+    private final FloatProperty mSlashLengthProp = new FloatProperty<SlashDrawable>("slashLength") {
+        @Override
+        public void setValue(SlashDrawable object, float value) {
+            object.mCurrentSlashLength = value;
+        }
+
+        @Override
+        public Float get(SlashDrawable object) {
+            return object.mCurrentSlashLength;
+        }
+    };
+
+    public void setSlashed(boolean slashed) {
+        if (mSlashed == slashed) return;
+
+        mSlashed = slashed;
+
+        final float end = mSlashed ? SLASH_HEIGHT / SCALE : 0f;
+        final float start = mSlashed ? 0f : SLASH_HEIGHT / SCALE;
+
+        if (mAnimationEnabled) {
+            ObjectAnimator anim = ObjectAnimator.ofFloat(this, mSlashLengthProp, start, end);
+            anim.addUpdateListener((ValueAnimator valueAnimator) -> invalidateSelf());
+            anim.setDuration(QS_ANIM_LENGTH);
+            anim.start();
+        } else {
+            mCurrentSlashLength = end;
+            invalidateSelf();
+        }
+    }
+
+    @Override
+    public void draw(@NonNull Canvas canvas) {
+        canvas.save();
+        Matrix m = new Matrix();
+        final int width = getBounds().width();
+        final int height = getBounds().height();
+        final float radiusX = scale(CORNER_RADIUS, width);
+        final float radiusY = scale(CORNER_RADIUS, height);
+        updateRect(
+                scale(LEFT, width),
+                scale(TOP, height),
+                scale(RIGHT, width),
+                scale(TOP + mCurrentSlashLength, height)
+        );
+
+        mPath.reset();
+        // Draw the slash vertically
+        mPath.addRoundRect(mSlashRect, radiusX, radiusY, Direction.CW);
+        // Rotate -45 + desired rotation
+        m.setRotate(mRotation + DEFAULT_ROTATION, width / 2, height / 2);
+        mPath.transform(m);
+        canvas.drawPath(mPath, mPaint);
+
+        // Rotate back to vertical
+        m.setRotate(-mRotation - DEFAULT_ROTATION, width / 2, height / 2);
+        mPath.transform(m);
+
+        // Draw another rect right next to the first, for clipping
+        m.setTranslate(mSlashRect.width(), 0);
+        mPath.transform(m);
+        mPath.addRoundRect(mSlashRect, 1.0f * width, 1.0f * height, Direction.CW);
+        m.setRotate(mRotation + DEFAULT_ROTATION, width / 2, height / 2);
+        mPath.transform(m);
+        canvas.clipOutPath(mPath);
+
+        mDrawable.draw(canvas);
+        canvas.restore();
+    }
+
+    private float scale(float frac, int width) {
+        return frac * width;
+    }
+
+    private void updateRect(float left, float top, float right, float bottom) {
+        mSlashRect.left = left;
+        mSlashRect.top = top;
+        mSlashRect.right = right;
+        mSlashRect.bottom = bottom;
+    }
+
+    @Override
+    public void setTint(@ColorInt int tintColor) {
+        super.setTint(tintColor);
+        mDrawable.setTint(tintColor);
+        mPaint.setColor(tintColor);
+    }
+
+    @Override
+    public void setTintList(@Nullable ColorStateList tint) {
+        mTintList = tint;
+        super.setTintList(tint);
+        mDrawable.setTintList(tint);
+        mPaint.setColor(tint.getDefaultColor());
+        invalidateSelf();
+    }
+
+    @Override
+    public void setTintMode(@NonNull Mode tintMode) {
+        mTintMode = tintMode;
+        super.setTintMode(tintMode);
+        mDrawable.setTintMode(tintMode);
+    }
+
+    @Override
+    public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {
+        mDrawable.setAlpha(alpha);
+        mPaint.setAlpha(alpha);
+    }
+
+    @Override
+    public void setColorFilter(@Nullable ColorFilter colorFilter) {
+        mDrawable.setColorFilter(colorFilter);
+        mPaint.setColorFilter(colorFilter);
+    }
+
+    @Override
+    public int getOpacity() {
+        return 255;
+    }
+}
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 30053e3..6c95a80 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -20,6 +20,9 @@
 import android.animation.AnimatorListenerAdapter;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.TransitionDrawable;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.support.v7.widget.DefaultItemAnimator;
@@ -42,6 +45,7 @@
 import com.android.systemui.R;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.qs.QSContainerImpl;
 import com.android.systemui.qs.QSDetailClipper;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
@@ -60,6 +64,7 @@
 public class QSCustomizer extends LinearLayout implements OnMenuItemClickListener {
 
     private static final int MENU_RESET = Menu.FIRST;
+    private static final String EXTRA_QS_CUSTOMIZING = "qs_customizing";
 
     private final QSDetailClipper mClipper;
 
@@ -109,11 +114,16 @@
         DefaultItemAnimator animator = new DefaultItemAnimator();
         animator.setMoveDuration(TileAdapter.MOVE_DURATION);
         mRecyclerView.setItemAnimator(animator);
+        updateNavBackDrop(getResources().getConfiguration());
     }
 
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
+        updateNavBackDrop(newConfig);
+    }
+
+    private void updateNavBackDrop(Configuration newConfig) {
         View navBackdrop = findViewById(R.id.nav_bar_background);
         if (navBackdrop != null) {
             boolean shouldShow = newConfig.smallestScreenWidthDp >= 600
@@ -154,6 +164,21 @@
         }
     }
 
+
+    public void showImmediately() {
+        if (!isShown) {
+            setVisibility(VISIBLE);
+            mClipper.showBackground();
+            isShown = true;
+            setTileSpecs();
+            setCustomizing(true);
+            queryTiles();
+            mNotifQsContainer.setCustomizerAnimating(false);
+            mNotifQsContainer.setCustomizerShowing(true);
+            Dependency.get(KeyguardMonitor.class).addCallback(mKeyguardCallback);
+        }
+    }
+
     private void queryTiles() {
         mFinishedFetchingTiles = false;
         Runnable tileQueryFetchCompletion = () -> {
@@ -227,6 +252,35 @@
         }
     }
 
+
+    public void saveInstanceState(Bundle outState) {
+        if (isShown) {
+            Dependency.get(KeyguardMonitor.class).removeCallback(mKeyguardCallback);
+        }
+        outState.putBoolean(EXTRA_QS_CUSTOMIZING, mCustomizing);
+    }
+
+    public void restoreInstanceState(Bundle savedInstanceState) {
+        boolean customizing = savedInstanceState.getBoolean(EXTRA_QS_CUSTOMIZING);
+        if (customizing) {
+            setVisibility(VISIBLE);
+            addOnLayoutChangeListener(new OnLayoutChangeListener() {
+                @Override
+                public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                        int oldLeft,
+                        int oldTop, int oldRight, int oldBottom) {
+                    removeOnLayoutChangeListener(this);
+                    showImmediately();
+                }
+            });
+        }
+    }
+
+    public void setEditLocation(int x, int y) {
+        mX = x;
+        mY = y;
+    }
+
     private final Callback mKeyguardCallback = () -> {
         if (!isAttachedToWindow()) return;
         if (Dependency.get(KeyguardMonitor.class).isShowing() && !mOpening) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 0a0d2ce..bdc5e7d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -556,7 +556,7 @@
 
         @Override
         public int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder) {
-            if (viewHolder.getItemViewType() == TYPE_EDIT) {
+            if (viewHolder.getItemViewType() == TYPE_EDIT || viewHolder.getItemViewType() == TYPE_DIVIDER) {
                 return makeMovementFlags(0, 0);
             }
             int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index 17a0d33..77c3bfa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -16,7 +16,9 @@
 
 import android.content.Context;
 import android.util.Log;
+import android.view.ContextThemeWrapper;
 
+import com.android.systemui.R;
 import com.android.systemui.plugins.qs.*;
 import com.android.systemui.plugins.qs.QSTileView;
 import com.android.systemui.qs.external.CustomTile;
@@ -78,7 +80,7 @@
 
     @Override
     public QSTileView createTileView(QSTile tile, boolean collapsedView) {
-        Context context = mHost.getContext();
+        Context context = new ContextThemeWrapper(mHost.getContext(), R.style.qs_theme);
         QSIconView icon = tile.createTileView(context);
         if (collapsedView) {
             return new QSTileBaseView(context, icon, collapsedView);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
index 661c921..8074cb9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
@@ -21,7 +21,6 @@
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Color;
-import android.graphics.drawable.Animatable;
 import android.graphics.drawable.Animatable2;
 import android.graphics.drawable.Animatable2.AnimationCallback;
 import android.graphics.drawable.Drawable;
@@ -38,6 +37,8 @@
 
 public class QSIconViewImpl extends QSIconView {
 
+    public static final long QS_ANIM_LENGTH = 350;
+
     protected final View mIcon;
     protected final int mIconSizePx;
     protected final int mTilePaddingBelowIconPx;
@@ -85,7 +86,8 @@
     }
 
     protected void updateIcon(ImageView iv, State state) {
-        if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) {
+        if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))
+                || !Objects.equals(state.slash, iv.getTag(R.id.qs_slash_tag))) {
             boolean shouldAnimate = iv.isShown() && mAnimationEnabled
                     && iv.getDrawable() != null;
             Drawable d = state.icon != null
@@ -94,9 +96,18 @@
             int padding = state.icon != null ? state.icon.getPadding() : 0;
             if (d != null) {
                 d.setAutoMirrored(false);
+                d.setLayoutDirection(getLayoutDirection());
             }
-            iv.setImageDrawable(d);
+
+            if (iv instanceof SlashImageView) {
+                ((SlashImageView) iv).setAnimationEnabled(shouldAnimate);
+                ((SlashImageView) iv).setState(state.slash, d);
+            } else {
+                iv.setImageDrawable(d);
+            }
+
             iv.setTag(R.id.qs_icon_tag, state.icon);
+            iv.setTag(R.id.qs_slash_tag, state.slash);
             iv.setPadding(0, padding, 0, padding);
             if (d instanceof Animatable2) {
                 Animatable2 a = (Animatable2) d;
@@ -138,22 +149,26 @@
     }
 
     public static void animateGrayScale(int fromColor, int toColor, ImageView iv) {
-        final float fromAlpha = Color.alpha(fromColor);
-        final float toAlpha = Color.alpha(toColor);
-        final float fromChannel = Color.red(fromColor);
-        final float toChannel = Color.red(toColor);
+        if (ValueAnimator.areAnimatorsEnabled()) {
+            final float fromAlpha = Color.alpha(fromColor);
+            final float toAlpha = Color.alpha(toColor);
+            final float fromChannel = Color.red(fromColor);
+            final float toChannel = Color.red(toColor);
 
-        ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
-        anim.setDuration(350);
+            ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+            anim.setDuration(QS_ANIM_LENGTH);
+            anim.addUpdateListener(animation -> {
+                float fraction = animation.getAnimatedFraction();
+                int alpha = (int) (fromAlpha + (toAlpha - fromAlpha) * fraction);
+                int channel = (int) (fromChannel + (toChannel - fromChannel) * fraction);
 
-        anim.addUpdateListener(animation -> {
-            float fraction = animation.getAnimatedFraction();
-            int alpha = (int) (fromAlpha + (toAlpha - fromAlpha) * fraction);
-            int channel = (int) (fromChannel + (toChannel - fromChannel) * fraction);
+                setTint(iv, Color.argb(alpha, channel, channel, channel));
+            });
 
-            setTint(iv, Color.argb(alpha, channel, channel, channel));
-        });
-        anim.start();
+            anim.start();
+        } else {
+            setTint(iv, toColor);
+        }
     }
 
     public static void setTint(ImageView iv, int color) {
@@ -166,7 +181,7 @@
     }
 
     protected View createIcon() {
-        final ImageView icon = new ImageView(mContext);
+        final ImageView icon = new SlashImageView(mContext);
         icon.setId(android.R.id.icon);
         icon.setScaleType(ScaleType.FIT_CENTER);
         return icon;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 672f2c2..3495f570 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -439,15 +439,22 @@
 
     public static class DrawableIcon extends Icon {
         protected final Drawable mDrawable;
+        protected final Drawable mInvisibleDrawable;
 
         public DrawableIcon(Drawable drawable) {
             mDrawable = drawable;
+            mInvisibleDrawable = drawable.getConstantState().newDrawable();
         }
 
         @Override
         public Drawable getDrawable(Context context) {
             return mDrawable;
         }
+
+        @Override
+        public Drawable getInvisibleDrawable(Context context) {
+            return mInvisibleDrawable;
+        }
     }
 
     public static class DrawableIconWithRes extends DrawableIcon {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java
new file mode 100644
index 0000000..13912fe
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.qs.tileimpl;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+import android.widget.ImageView;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.plugins.qs.QSTile.SlashState;
+import com.android.systemui.qs.SlashDrawable;
+
+public class SlashImageView extends ImageView {
+
+    @VisibleForTesting
+    protected SlashDrawable mSlash;
+    private boolean mAnimationEnabled = true;
+
+    public SlashImageView(Context context) {
+        super(context);
+    }
+
+    private void ensureSlashDrawable() {
+        if (mSlash == null) {
+            mSlash = new SlashDrawable(getDrawable());
+            mSlash.setAnimationEnabled(mAnimationEnabled);
+            super.setImageDrawable(mSlash);
+        }
+    }
+
+    @Override
+    public void setImageDrawable(Drawable drawable) {
+        if (drawable == null) {
+            mSlash = null;
+            super.setImageDrawable(null);
+        } else if (mSlash == null) {
+            super.setImageDrawable(drawable);
+        } else {
+            mSlash.setAnimationEnabled(mAnimationEnabled);
+            mSlash.setDrawable(drawable);
+        }
+    }
+
+    public void setAnimationEnabled(boolean enabled) {
+        mAnimationEnabled = enabled;
+    }
+
+    private void setSlashState(@NonNull SlashState slashState) {
+        ensureSlashDrawable();
+        mSlash.setRotation(slashState.rotation);
+        mSlash.setSlashed(slashState.isSlashed);
+    }
+
+    public void setState(@Nullable SlashState state, @Nullable Drawable drawable) {
+        if (state != null) {
+            setImageDrawable(drawable);
+            setSlashState(state);
+        } else {
+            mSlash = null;
+            setImageDrawable(drawable);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index c5f798e..2e7012e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -29,19 +29,15 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
 import com.android.systemui.qs.GlobalSetting;
 import com.android.systemui.qs.QSHost;
-import com.android.systemui.plugins.qs.QSTile.BooleanState;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 
 /** Quick settings tile: Airplane mode **/
 public class AirplaneModeTile extends QSTileImpl<BooleanState> {
-    private final AnimationIcon mEnable =
-            new AnimationIcon(R.drawable.ic_signal_airplane_enable_animation,
-                    R.drawable.ic_signal_airplane_disable);
-    private final AnimationIcon mDisable =
-            new AnimationIcon(R.drawable.ic_signal_airplane_disable_animation,
-                    R.drawable.ic_signal_airplane_enable);
+    private final Icon mIcon =
+            ResourceIcon.get(R.drawable.ic_signal_airplane);
     private final GlobalSetting mSetting;
 
     private boolean mListening;
@@ -90,11 +86,11 @@
         final boolean airplaneMode = value != 0;
         state.value = airplaneMode;
         state.label = mContext.getString(R.string.airplane_mode);
-        if (airplaneMode) {
-            state.icon = mEnable;
-        } else {
-            state.icon = mDisable;
+        state.icon = mIcon;
+        if (state.slash == null) {
+            state.slash = new SlashState();
         }
+        state.slash.isSlashed = !airplaneMode;
         state.state = airplaneMode ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         state.contentDescription = state.label;
         state.expandedAccessibilityClassName = Switch.class.getName();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index 74cc0ec..3f419a8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -15,32 +15,15 @@
  */
 package com.android.systemui.qs.tiles;
 
-import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
+import android.graphics.drawable.Drawable;
 import android.service.quicksettings.Tile;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
-import android.text.style.RelativeSizeSpan;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnAttachStateChangeListener;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.Checkable;
-import android.widget.ImageView;
 import android.widget.Switch;
-import android.widget.TextView;
-
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settingslib.BatteryInfo;
 import com.android.settingslib.graph.BatteryMeterDrawableBase;
-import com.android.settingslib.graph.UsageView;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.plugins.qs.DetailAdapter;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
@@ -50,12 +33,10 @@
         BatteryController.BatteryStateChangeCallback {
 
     private final BatteryController mBatteryController;
-    private final BatteryDetail mBatteryDetail = new BatteryDetail();
 
     private int mLevel;
     private boolean mPowerSave;
     private boolean mCharging;
-    private boolean mDetailShown;
     private boolean mPluggedIn;
 
     public BatterySaverTile(QSHost host) {
@@ -83,14 +64,6 @@
     }
 
     @Override
-    public void setDetailListening(boolean listening) {
-        super.setDetailListening(listening);
-        if (!listening) {
-            mBatteryDetail.mCurrentView = null;
-        }
-    }
-
-    @Override
     public Intent getLongClickIntent() {
         return new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
     }
@@ -107,9 +80,11 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
-        state.state = mCharging ? Tile.STATE_UNAVAILABLE
+        state.state = mPluggedIn ? Tile.STATE_UNAVAILABLE
                 : mPowerSave ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
-        state.icon = ResourceIcon.get(R.drawable.ic_qs_battery_saver);
+        BatterySaverIcon bsi = new BatterySaverIcon();
+        bsi.mState = state.state;
+        state.icon = bsi;
         state.label = mContext.getString(R.string.battery_detail_switch_title);
         state.contentDescription = state.label;
         state.value = mPowerSave;
@@ -122,160 +97,48 @@
         mPluggedIn = pluggedIn;
         mCharging = charging;
         refreshState(level);
-        if (mDetailShown) {
-            mBatteryDetail.postBindView();
-        }
     }
 
     @Override
     public void onPowerSaveChanged(boolean isPowerSave) {
         mPowerSave = isPowerSave;
         refreshState(null);
-        if (mDetailShown) {
-            mBatteryDetail.postBindView();
+    }
+
+    public static class BatterySaverIcon extends Icon {
+        private int mState;
+
+        @Override
+        public Drawable getDrawable(Context context) {
+            BatterySaverDrawable b = new BatterySaverDrawable(context, 0);
+            b.mState = mState;
+            final int pad = context.getResources()
+                    .getDimensionPixelSize(R.dimen.qs_tile_divider_height);
+            b.setPadding(pad, pad, pad, pad);
+            return b;
         }
     }
 
-    private final class BatteryDetail implements DetailAdapter, OnClickListener,
-            OnAttachStateChangeListener {
-        private final BatteryMeterDrawableBase mDrawable
-                = new BatteryMeterDrawableBase(
-                        mHost.getContext(),
-                        mHost.getContext().getColor(R.color.meter_background_color));
-        private View mCurrentView;
+    private static class BatterySaverDrawable extends BatteryMeterDrawableBase {
+        private int mState;
+        private static final int MAX_BATTERY = 100;
 
-        @Override
-        public CharSequence getTitle() {
-            return mContext.getString(R.string.battery_panel_title, mLevel);
+        BatterySaverDrawable(Context context, int frameColor) {
+            super(context, frameColor);
+            // Show as full so it's always uniform color
+            super.setBatteryLevel(MAX_BATTERY);
+            setPowerSave(true);
+            setCharging(false);
         }
 
         @Override
-        public Boolean getToggleState() {
-            return null;
+        protected int batteryColorForLevel(int level) {
+            return QSTileImpl.getColorForState(mContext, mState);
         }
 
         @Override
-        public View createDetailView(Context context, View convertView, ViewGroup parent) {
-            if (convertView == null) {
-                convertView = LayoutInflater.from(mContext).inflate(R.layout.battery_detail, parent,
-                        false);
-            }
-            mCurrentView = convertView;
-            mCurrentView.addOnAttachStateChangeListener(this);
-            bindView();
-            return convertView;
+        public void setBatteryLevel(int val) {
+            // Don't change the actual level, otherwise this won't draw correctly
         }
-
-        private void postBindView() {
-            if (mCurrentView == null) return;
-            mCurrentView.post(new Runnable() {
-                @Override
-                public void run() {
-                    bindView();
-                }
-            });
-        }
-
-        private void bindView() {
-            if (mCurrentView == null) {
-                return;
-            }
-            mDrawable.setBatteryLevel(100);
-            mDrawable.setCharging(false);
-            mDrawable.setPowerSave(true);
-            mDrawable.setShowPercent(false);
-            ((ImageView) mCurrentView.findViewById(android.R.id.icon)).setImageDrawable(mDrawable);
-            Checkable checkbox = (Checkable) mCurrentView.findViewById(android.R.id.toggle);
-            checkbox.setChecked(mPowerSave);
-            BatteryInfo.getBatteryInfo(mContext, new BatteryInfo.Callback() {
-                @Override
-                public void onBatteryInfoLoaded(BatteryInfo info) {
-                    if (mCurrentView != null) {
-                        bindBatteryInfo(info);
-                    }
-                }
-            });
-            final TextView batterySaverTitle =
-                    (TextView) mCurrentView.findViewById(android.R.id.title);
-            final TextView batterySaverSummary =
-                    (TextView) mCurrentView.findViewById(android.R.id.summary);
-            if (mCharging) {
-                mCurrentView.findViewById(R.id.switch_container).setAlpha(.7f);
-                batterySaverTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
-                batterySaverTitle.setText(R.string.battery_detail_charging_summary);
-                mCurrentView.findViewById(android.R.id.toggle).setVisibility(View.GONE);
-                mCurrentView.findViewById(R.id.switch_container).setClickable(false);
-            } else {
-                mCurrentView.findViewById(R.id.switch_container).setAlpha(1);
-                batterySaverTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
-                batterySaverTitle.setText(R.string.battery_detail_switch_title);
-                batterySaverSummary.setText(R.string.battery_detail_switch_summary);
-                mCurrentView.findViewById(android.R.id.toggle).setVisibility(View.VISIBLE);
-                mCurrentView.findViewById(R.id.switch_container).setClickable(true);
-                mCurrentView.findViewById(R.id.switch_container).setOnClickListener(this);
-            }
-        }
-
-        private void bindBatteryInfo(BatteryInfo info) {
-            SpannableStringBuilder builder = new SpannableStringBuilder();
-            builder.append(info.batteryPercentString, new RelativeSizeSpan(2.6f),
-                    Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
-            if (info.remainingLabel != null) {
-                if (mContext.getResources().getBoolean(R.bool.quick_settings_wide)) {
-                    builder.append(' ');
-                } else {
-                    builder.append('\n');
-                }
-                builder.append(info.remainingLabel);
-            }
-            ((TextView) mCurrentView.findViewById(R.id.charge_and_estimation)).setText(builder);
-
-            info.bindHistory((UsageView) mCurrentView.findViewById(R.id.battery_usage));
-        }
-
-        @Override
-        public void onClick(View v) {
-            mBatteryController.setPowerSaveMode(!mPowerSave);
-        }
-
-        @Override
-        public Intent getSettingsIntent() {
-            return new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
-        }
-
-        @Override
-        public void setToggleState(boolean state) {
-            // No toggle state.
-        }
-
-        @Override
-        public int getMetricsCategory() {
-            return MetricsEvent.QS_BATTERY_DETAIL;
-        }
-
-        @Override
-        public void onViewAttachedToWindow(View v) {
-            if (!mDetailShown) {
-                mDetailShown = true;
-                v.getContext().registerReceiver(mReceiver,
-                        new IntentFilter(Intent.ACTION_TIME_TICK), null,
-                        Dependency.get(Dependency.TIME_TICK_HANDLER));
-            }
-        }
-
-        @Override
-        public void onViewDetachedFromWindow(View v) {
-            if (mDetailShown) {
-                mDetailShown = false;
-                v.getContext().unregisterReceiver(mReceiver);
-            }
-        }
-
-        private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                postBindView();
-            }
-        };
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 79fb5b3..12fccda 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -30,6 +30,7 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settingslib.Utils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
@@ -82,7 +83,7 @@
     @Override
     protected void handleClick() {
         // Secondary clicks are header clicks, just toggle.
-        final boolean isEnabled = (Boolean)mState.value;
+        final boolean isEnabled = mState.value;
         mController.setBluetoothEnabled(!isEnabled);
     }
 
@@ -99,6 +100,9 @@
             return;
         }
         showDetail(true);
+        if (!mState.value) {
+            mController.setBluetoothEnabled(true);
+        }
     }
 
     @Override
@@ -114,6 +118,10 @@
                 || mController.getBluetoothState() == BluetoothAdapter.STATE_TURNING_ON;
         state.dualTarget = true;
         state.value = enabled;
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
+        state.slash.isSlashed = !enabled;
         if (enabled) {
             state.label = null;
             if (connected) {
@@ -137,7 +145,7 @@
             }
             state.state = Tile.STATE_ACTIVE;
         } else {
-            state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_off);
+            state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_on);
             state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_bluetooth_off);
@@ -174,6 +182,7 @@
             refreshState();
             if (isShowingDetail()) {
                 mDetailAdapter.updateItems();
+                fireToggleStateChanged(mDetailAdapter.getToggleState());
             }
         }
 
@@ -264,10 +273,17 @@
                     item.icon = R.drawable.ic_qs_bluetooth_on;
                     item.line1 = device.getName();
                     item.tag = device;
-                    int state = mController.getMaxConnectionState(device);
+                    int state = device.getMaxConnectionState();
                     if (state == BluetoothProfile.STATE_CONNECTED) {
                         item.icon = R.drawable.ic_qs_bluetooth_connected;
-                        item.line2 = mContext.getString(R.string.quick_settings_connected);
+                        int batteryLevel = device.getBatteryLevel();
+                        if (batteryLevel != BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
+                            item.line2 = mContext.getString(
+                                    R.string.quick_settings_connected_battery_level,
+                                    Utils.formatPercentage(batteryLevel));
+                        } else {
+                            item.line2 = mContext.getString(R.string.quick_settings_connected);
+                        }
                         item.canDisconnect = true;
                         items.add(connectedDevices, item);
                         connectedDevices++;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index f0d7d6c..2fc9fc7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -34,6 +34,7 @@
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
 import android.widget.Button;
 
 import com.android.internal.app.MediaRouteChooserDialog;
@@ -50,6 +51,7 @@
 import com.android.systemui.qs.QSDetailItems.Item;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.CastController.CastDevice;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
@@ -139,25 +141,15 @@
                         Dependency.get(ActivityStarter.class)
                                 .postStartActivityDismissingKeyguard(getLongClickIntent(), 0);
                     });
-            mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
+            mDialog.getWindow().setType(LayoutParams.TYPE_KEYGUARD_DIALOG);
+            SystemUIDialog.setShowForAllUsers(mDialog, true);
+            SystemUIDialog.registerDismissListener(mDialog);
+            SystemUIDialog.setWindowOnTop(mDialog);
             mUiHandler.post(() -> mDialog.show());
-            registerReceiver();
             mHost.collapsePanels();
         });
     }
 
-    private void registerReceiver() {
-        mContext.registerReceiverAsUser(mReceiver, UserHandle.CURRENT,
-                new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), null, null);
-        mRegistered = true;
-        mDialog.setOnDismissListener(dialog -> {
-            if (mRegistered) {
-                mContext.unregisterReceiver(mReceiver);
-                mRegistered = false;
-            }
-        });
-    }
-
     @Override
     public CharSequence getTileLabel() {
         return mContext.getString(R.string.quick_settings_cast_title);
@@ -223,15 +215,6 @@
         }
     };
 
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (mDialog != null) {
-                mDialog.dismiss();
-            }
-        }
-    };
-
     private final class CastDetailAdapter implements DetailAdapter, QSDetailItems.Callback {
         private final LinkedHashMap<String, CastDevice> mVisibleOrder = new LinkedHashMap<>();
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index fbcdf1a..4afafb6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.qs.tiles;
 
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -24,6 +26,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.WindowManager.LayoutParams;
 import android.widget.Switch;
 
 import com.android.internal.logging.MetricsLogger;
@@ -31,6 +34,7 @@
 import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.R.string;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.DetailAdapter;
 import com.android.systemui.plugins.qs.QSIconView;
@@ -38,8 +42,9 @@
 import com.android.systemui.qs.CellTileView;
 import com.android.systemui.qs.CellTileView.SignalIcon;
 import com.android.systemui.qs.QSHost;
-import com.android.systemui.qs.SignalTileView;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
@@ -55,11 +60,13 @@
 
     private final CellSignalCallback mSignalCallback = new CellSignalCallback();
     private final ActivityStarter mActivityStarter;
+    private final KeyguardMonitor mKeyguardMonitor;
 
     public CellularTile(QSHost host) {
         super(host);
         mController = Dependency.get(NetworkController.class);
         mActivityStarter = Dependency.get(ActivityStarter.class);
+        mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
         mDataController = mController.getMobileDataController();
         mDetailAdapter = new CellularDetailAdapter();
     }
@@ -95,7 +102,31 @@
 
     @Override
     protected void handleClick() {
-        mDataController.setMobileDataEnabled(!mDataController.isMobileDataEnabled());
+        if (mDataController.isMobileDataEnabled()) {
+            if (mKeyguardMonitor.isSecure() && !mKeyguardMonitor.canSkipBouncer()) {
+                mActivityStarter.postQSRunnableDismissingKeyguard(this::showDisableDialog);
+            } else {
+                mUiHandler.post(this::showDisableDialog);
+            }
+        } else {
+            mDataController.setMobileDataEnabled(true);
+        }
+    }
+
+    private void showDisableDialog() {
+        mHost.collapsePanels();
+        AlertDialog dialog = new Builder(mContext)
+                .setMessage(string.data_usage_disable_mobile)
+                .setNegativeButton(android.R.string.cancel, null)
+                .setPositiveButton(
+                        com.android.internal.R.string.alert_windows_notification_turn_off_action,
+                        (d, w) -> mDataController.setMobileDataEnabled(false))
+                .create();
+        dialog.getWindow().setType(LayoutParams.TYPE_KEYGUARD_DIALOG);
+        SystemUIDialog.setShowForAllUsers(dialog, true);
+        SystemUIDialog.registerDismissListener(dialog);
+        SystemUIDialog.setWindowOnTop(dialog);
+        dialog.show();
     }
 
     @Override
@@ -139,6 +170,7 @@
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.value = mDataController.isMobileDataSupported()
                 && mDataController.isMobileDataEnabled();
+
         state.icon = new SignalIcon(cb.mobileSignalIconId);
         if (cb.airplaneModeEnabled) {
             state.state = Tile.STATE_INACTIVE;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 5b374b1..40fe484 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -25,6 +25,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
+import com.android.systemui.R.drawable;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
@@ -33,12 +34,7 @@
 /** Quick settings tile: Invert colors **/
 public class ColorInversionTile extends QSTileImpl<BooleanState> {
 
-    private final AnimationIcon mEnable
-            = new AnimationIcon(R.drawable.ic_invert_colors_enable_animation,
-            R.drawable.ic_invert_colors_disable);
-    private final AnimationIcon mDisable
-            = new AnimationIcon(R.drawable.ic_invert_colors_disable_animation,
-            R.drawable.ic_invert_colors_enable);
+    private final Icon mIcon = ResourceIcon.get(drawable.ic_invert_colors);
     private final SecureSetting mSetting;
 
     private boolean mListening;
@@ -96,10 +92,14 @@
     protected void handleUpdateState(BooleanState state, Object arg) {
         final int value = arg instanceof Integer ? (Integer) arg : mSetting.getValue();
         final boolean enabled = value != 0;
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
         state.value = enabled;
+        state.slash.isSlashed = !state.value;
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         state.label = mContext.getString(R.string.quick_settings_inversion_label);
-        state.icon = enabled ? mEnable : mDisable;
+        state.icon = mIcon;
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.contentDescription = state.label;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 9557262..5938749 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -27,13 +27,13 @@
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.net.Uri;
 import android.os.UserManager;
 import android.provider.Settings;
 import android.provider.Settings.Global;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeConfig.ZenRule;
 import android.service.quicksettings.Tile;
+import android.util.Log;
 import android.util.Slog;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -55,6 +55,7 @@
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.statusbar.policy.ZenModeController.Callback;
 import com.android.systemui.volume.ZenModePanel;
 
 /** Quick settings tile: Do not disturb **/
@@ -72,13 +73,6 @@
     private static final QSTile.Icon TOTAL_SILENCE =
             ResourceIcon.get(R.drawable.ic_qs_dnd_on_total_silence);
 
-    private final AnimationIcon mDisable =
-            new AnimationIcon(R.drawable.ic_dnd_disable_animation,
-                    R.drawable.ic_qs_dnd_off);
-    private final AnimationIcon mDisableTotalSilence =
-            new AnimationIcon(R.drawable.ic_dnd_total_silence_disable_animation,
-                    R.drawable.ic_qs_dnd_off);
-
     private final ZenModeController mController;
     private final DndDetailAdapter mDetailAdapter;
 
@@ -155,7 +149,22 @@
                     Toast.LENGTH_LONG).show();
             return;
         }
-        showDetail(true);
+        if (!mState.value) {
+            // Because of the complexity of the zen panel, it needs to be shown after
+            // we turn on zen below.
+            mController.addCallback(new ZenModeController.Callback() {
+                @Override
+                public void onZenChanged(int zen) {
+                    mController.removeCallback(this);
+                    showDetail(true);
+                }
+            });
+            int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN,
+                    Global.ZEN_MODE_ALARMS);
+            mController.setZen(zen, null, TAG);
+        } else {
+            showDetail(true);
+        }
     }
 
     @Override
@@ -168,9 +177,11 @@
         final int zen = arg instanceof Integer ? (Integer) arg : mController.getZen();
         final boolean newValue = zen != ZEN_MODE_OFF;
         final boolean valueChanged = state.value != newValue;
+        if (state.slash == null) state.slash = new SlashState();
         state.dualTarget = true;
         state.value = newValue;
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+        state.slash.isSlashed = !state.value;
         checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
         switch (zen) {
             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
@@ -192,7 +203,7 @@
                         R.string.accessibility_quick_settings_dnd_alarms_on);
                 break;
             default:
-                state.icon = TOTAL_SILENCE.equals(state.icon) ? mDisableTotalSilence : mDisable;
+                state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
                 state.label = mContext.getString(R.string.quick_settings_dnd_label);
                 state.contentDescription = mContext.getString(
                         R.string.accessibility_quick_settings_dnd);
@@ -322,7 +333,7 @@
                 mZenPanel.init(mController);
                 mZenPanel.addOnAttachStateChangeListener(this);
                 mZenPanel.setCallback(mZenModePanelCallback);
-                mZenPanel.setEmptyState(R.drawable.ic_qs_dnd_off, R.string.dnd_is_off);
+                mZenPanel.setEmptyState(R.drawable.ic_qs_dnd_detail_empty, R.string.dnd_is_off);
             }
             updatePanel();
             return mZenPanel;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index 6d2aa90..e6ac908 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -23,12 +23,11 @@
 import android.service.quicksettings.Tile;
 import android.widget.Switch;
 
-import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.qs.QSHost;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.policy.FlashlightController;
 
@@ -36,12 +35,7 @@
 public class FlashlightTile extends QSTileImpl<BooleanState> implements
         FlashlightController.FlashlightListener {
 
-    private final AnimationIcon mEnable
-            = new AnimationIcon(R.drawable.ic_signal_flashlight_enable_animation,
-            R.drawable.ic_signal_flashlight_disable);
-    private final AnimationIcon mDisable
-            = new AnimationIcon(R.drawable.ic_signal_flashlight_disable_animation,
-            R.drawable.ic_signal_flashlight_enable);
+    private final Icon mIcon = ResourceIcon.get(R.drawable.ic_signal_flashlight);
     private final FlashlightController mFlashlightController;
 
     public FlashlightTile(QSHost host) {
@@ -104,11 +98,13 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
         state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
         if (!mFlashlightController.isAvailable()) {
-            Drawable icon = mHost.getContext().getDrawable(R.drawable.ic_signal_flashlight_enable)
-                    .mutate();
-            state.icon = new DrawableIcon(icon);
+            state.icon = mIcon;
+            state.slash.isSlashed = true;
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_flashlight_unavailable);
             state.state = Tile.STATE_UNAVAILABLE;
@@ -123,8 +119,8 @@
         } else {
             state.value = mFlashlightController.isEnabled();
         }
-        final AnimationIcon icon = state.value ? mEnable : mDisable;
-        state.icon = icon;
+        state.icon = mIcon;
+        state.slash.isSlashed = !state.value;
         state.contentDescription = mContext.getString(R.string.quick_settings_flashlight_label);
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 40f2c4b..c17573d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -39,14 +39,7 @@
     static final Intent TETHER_SETTINGS = new Intent().setComponent(new ComponentName(
              "com.android.settings", "com.android.settings.TetherSettings"));
 
-    private final AnimationIcon mEnable =
-            new AnimationIcon(R.drawable.ic_hotspot_enable_animation,
-                    R.drawable.ic_hotspot_disable);
-    private final Icon mEnabledStatic = ResourceIcon.get(R.drawable.ic_hotspot_disable);
-    private final AnimationIcon mDisable =
-            new AnimationIcon(R.drawable.ic_hotspot_disable_animation,
-                    R.drawable.ic_hotspot_enable);
-    private final Icon mDisableNoAnimation = ResourceIcon.get(R.drawable.ic_hotspot_enable);
+    private final Icon mEnabledStatic = ResourceIcon.get(R.drawable.ic_hotspot);
     private final Icon mUnavailable = ResourceIcon.get(R.drawable.ic_hotspot_unavailable);
 
     private final HotspotController mController;
@@ -116,6 +109,9 @@
 
     @Override
     protected void handleUpdateState(AirplaneBooleanState state, Object arg) {
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
         state.label = mContext.getString(R.string.quick_settings_hotspot_label);
 
         checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_CONFIG_TETHERING);
@@ -124,18 +120,12 @@
         } else {
             state.value = mController.isHotspotEnabled();
         }
-        state.icon = !state.value ? mDisable
-                : state.isTransient ? mEnabledStatic
-                : mEnable;
-        boolean wasAirplane = state.isAirplaneMode;
+        state.icon = mEnabledStatic;
         state.isAirplaneMode = mAirplaneMode.getValue() != 0;
         state.isTransient = mController.isHotspotTransient();
+        state.slash.isSlashed = !state.value && !state.isTransient;
         if (state.isTransient) {
             state.icon = ResourceIcon.get(R.drawable.ic_hotspot_transient_animation);
-        } else if (state.isAirplaneMode) {
-            state.icon = mUnavailable;
-        } else if (wasAirplane) {
-            state.icon = mDisableNoAnimation;
         }
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.contentDescription = state.label;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index 6522e10..5e66334 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -25,6 +25,7 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.R.drawable;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
@@ -36,12 +37,7 @@
 /** Quick settings tile: Location **/
 public class LocationTile extends QSTileImpl<BooleanState> {
 
-    private final AnimationIcon mEnable =
-            new AnimationIcon(R.drawable.ic_signal_location_enable_animation,
-                    R.drawable.ic_signal_location_disable);
-    private final AnimationIcon mDisable =
-            new AnimationIcon(R.drawable.ic_signal_location_disable_animation,
-                    R.drawable.ic_signal_location_enable);
+    private final Icon mIcon = ResourceIcon.get(drawable.ic_signal_location);
 
     private final LocationController mController;
     private final KeyguardMonitor mKeyguard;
@@ -95,6 +91,9 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
         final boolean locationEnabled =  mController.isLocationEnabled();
 
         // Work around for bug 15916487: don't show location tile on top of lock screen. After the
@@ -102,13 +101,13 @@
         // state.visible = !(mKeyguard.isSecure() && mKeyguard.isShowing());
         state.value = locationEnabled;
         checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_SHARE_LOCATION);
+        state.icon = mIcon;
+        state.slash.isSlashed = !state.value;
         if (locationEnabled) {
-            state.icon = mEnable;
             state.label = mContext.getString(R.string.quick_settings_location_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_location_on);
         } else {
-            state.icon = mDisable;
             state.label = mContext.getString(R.string.quick_settings_location_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_location_off);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index 8aa1e43..2a12769 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -79,8 +79,7 @@
         state.value = isActivated;
         state.label = state.contentDescription =
                 mContext.getString(R.string.quick_settings_night_display_label);
-        state.icon = ResourceIcon.get(isActivated ? R.drawable.ic_qs_night_display_on
-                : R.drawable.ic_qs_night_display_off);
+        state.icon = ResourceIcon.get(R.drawable.ic_qs_night_display_on);
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index f26afcc..136cf21 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -127,6 +127,9 @@
             return;
         }
         showDetail(true);
+        if (!mState.value) {
+            mController.setWifiEnabled(true);
+        }
     }
 
     @Override
@@ -149,6 +152,12 @@
             mDetailAdapter.setItemsVisible(cb.enabled);
             fireToggleStateChanged(cb.enabled);
         }
+        if (state.slash == null) {
+            state.slash = new SlashState();
+            state.slash.rotation = 6;
+        }
+        state.slash.isSlashed = false;
+        state.state = Tile.STATE_ACTIVE;
         state.dualTarget = true;
         state.value = cb.enabled;
         state.activityIn = cb.enabled && cb.activityIn;
@@ -159,6 +168,8 @@
             state.icon = ResourceIcon.get(R.drawable.ic_signal_wifi_transient_animation);
             state.label = r.getString(R.string.quick_settings_wifi_label);
         } else if (!state.value) {
+            state.slash.isSlashed = true;
+            state.state = Tile.STATE_INACTIVE;
             state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_disabled);
             state.label = r.getString(R.string.quick_settings_wifi_label);
         } else if (wifiConnected) {
@@ -183,7 +194,6 @@
         state.dualLabelContentDescription = r.getString(
                 R.string.accessibility_quick_settings_open_settings, getTileLabel());
         state.expandedAccessibilityClassName = Switch.class.getName();
-        state.state = Tile.STATE_ACTIVE;
     }
 
     @Override
@@ -304,12 +314,10 @@
         public View createDetailView(Context context, View convertView, ViewGroup parent) {
             if (DEBUG) Log.d(TAG, "createDetailView convertView=" + (convertView != null));
             mAccessPoints = null;
-            mWifiController.scanForAccessPoints();
-            fireScanStateChanged(true);
             mItems = QSDetailItems.convertOrInflate(context, convertView, parent);
             mItems.setTagSuffix("Wifi");
             mItems.setCallback(this);
-            updateItems();
+            mWifiController.scanForAccessPoints(); // updates APs and items
             setItemsVisible(mState.value);
             return mItems;
         }
@@ -317,9 +325,24 @@
         @Override
         public void onAccessPointsChanged(final List<AccessPoint> accessPoints) {
             mAccessPoints = accessPoints.toArray(new AccessPoint[accessPoints.size()]);
+            filterUnreachableAPs();
+
             updateItems();
-            if (accessPoints != null && accessPoints.size() > 0) {
-                fireScanStateChanged(false);
+        }
+
+        /** Filter unreachable APs from mAccessPoints */
+        private void filterUnreachableAPs() {
+            int numReachable = 0;
+            for (AccessPoint ap : mAccessPoints) {
+                if (ap.isReachable()) numReachable++;
+            }
+            if (numReachable != mAccessPoints.length) {
+                AccessPoint[] unfiltered = mAccessPoints;
+                mAccessPoints = new AccessPoint[numReachable];
+                int i = 0;
+                for (AccessPoint ap : unfiltered) {
+                    if (ap.isReachable()) mAccessPoints[i++] = ap;
+                }
             }
         }
 
@@ -352,6 +375,12 @@
 
         private void updateItems() {
             if (mItems == null) return;
+            if ((mAccessPoints != null && mAccessPoints.length > 0)
+                    || !mSignalCallback.mInfo.enabled) {
+                fireScanStateChanged(false);
+            } else {
+                fireScanStateChanged(true);
+            }
 
             // Wi-Fi is off
             if (!mSignalCallback.mInfo.enabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index 6c89241..38821f6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -33,12 +33,7 @@
 /** Quick settings tile: Work profile on/off */
 public class WorkModeTile extends QSTileImpl<BooleanState> implements
         ManagedProfileController.Callback {
-    private final AnimationIcon mEnable =
-            new AnimationIcon(R.drawable.ic_signal_workmode_enable_animation,
-                    R.drawable.ic_signal_workmode_disable);
-    private final AnimationIcon mDisable =
-            new AnimationIcon(R.drawable.ic_signal_workmode_disable_animation,
-                    R.drawable.ic_signal_workmode_enable);
+    private final Icon mIcon = ResourceIcon.get(R.drawable.ic_signal_workmode_disable);
 
     private final ManagedProfileController mProfileController;
 
@@ -93,6 +88,10 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
+
         if (arg instanceof Boolean) {
             state.value = (Boolean) arg;
         } else {
@@ -100,12 +99,13 @@
         }
 
         state.label = mContext.getString(R.string.quick_settings_work_mode_label);
+        state.icon = mIcon;
         if (state.value) {
-            state.icon = mEnable;
+            state.slash.isSlashed = false;
             state.contentDescription =  mContext.getString(
                     R.string.accessibility_quick_settings_work_mode_on);
         } else {
-            state.icon = mDisable;
+            state.slash.isSlashed = true;
             state.contentDescription =  mContext.getString(
                     R.string.accessibility_quick_settings_work_mode_off);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl b/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
index 1240e05..cc7798e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
+++ b/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
@@ -31,4 +31,5 @@
     void sendRecentsDrawnEvent();
     void sendDockingTopTaskEvent(int dragMode, in Rect initialRect);
     void sendLaunchRecentsEvent();
+    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 9ba32b3..86dde54 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -43,17 +43,22 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
 import com.android.systemui.EventLogConstants;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.SystemUI;
+import com.android.systemui.plugins.PluginActivity;
+import com.android.systemui.plugins.PluginActivityManager;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
 import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
+import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
 import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
 import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
+import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
 import com.android.systemui.recents.events.component.ShowUserToastEvent;
 import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
 import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -234,6 +239,8 @@
             registerWithSystemUser();
         }
         putComponent(Recents.class, this);
+        Dependency.get(PluginActivityManager.class).addActivityPlugin(RecentsImpl.RECENTS_ACTIVITY,
+                PluginActivity.ACTION_RECENTS);
     }
 
     @Override
@@ -607,6 +614,14 @@
                 }
             });
         }
+
+        // This will catch the cases when a user launches from recents to another app
+        // (and vice versa) that is not in the recents stack (such as home or bugreport) and it
+        // would not reset the wait for transition flag. This will catch it and make sure that the
+        // flag is reset.
+        if (!event.visible) {
+            mImpl.setWaitingForTransitionStart(false);
+        }
     }
 
     /**
@@ -679,6 +694,11 @@
         }
     }
 
+    public final void onBusEvent(LaunchTaskFailedEvent event) {
+        // Reset the transition when tasks fail to launch
+        mImpl.setWaitingForTransitionStart(false);
+    }
+
     public final void onBusEvent(ConfigurationChangedEvent event) {
         // Update the configuration for the Recents component when the activity configuration
         // changes as well
@@ -706,6 +726,25 @@
         }
     }
 
+    public final void onBusEvent(SetWaitingForTransitionStartEvent event) {
+        int processUser = sSystemServicesProxy.getProcessUser();
+        if (sSystemServicesProxy.isSystemUser(processUser)) {
+            mImpl.setWaitingForTransitionStart(event.waitingForTransitionStart);
+        } else {
+            postToSystemUser(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        mUserToSystemCallbacks.setWaitingForTransitionStartEvent(
+                                event.waitingForTransitionStart);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Callback failed", e);
+                    }
+                }
+            });
+        }
+    }
+
     /**
      * Attempts to register with the system user.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index ba3bcc7..387527f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -20,6 +20,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.TaskStackBuilder;
+import android.app.WallpaperManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -40,12 +41,15 @@
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
 
+import com.android.internal.colorextraction.ColorExtractor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.DejankUtils;
-import com.android.systemui.Interpolators;
 import com.android.keyguard.LatencyTracker;
+import com.android.systemui.DejankUtils;
+import com.android.systemui.Dependency;
+import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
 import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
@@ -65,6 +69,7 @@
 import com.android.systemui.recents.events.component.ActivityUnpinnedEvent;
 import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
 import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
+import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
 import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
 import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
 import com.android.systemui.recents.events.ui.HideIncompatibleAppOverlayEvent;
@@ -72,6 +77,7 @@
 import com.android.systemui.recents.events.ui.ShowApplicationInfoEvent;
 import com.android.systemui.recents.events.ui.ShowIncompatibleAppOverlayEvent;
 import com.android.systemui.recents.events.ui.StackViewScrolledEvent;
+import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
 import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEvent;
 import com.android.systemui.recents.events.ui.UserInteractionEvent;
 import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
@@ -98,7 +104,8 @@
 /**
  * The main Recents activity that is started from RecentsComponent.
  */
-public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreDrawListener {
+public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreDrawListener,
+        ColorExtractor.OnColorsChangedListener {
 
     private final static String TAG = "RecentsActivity";
     private final static boolean DEBUG = false;
@@ -109,11 +116,10 @@
     private RecentsPackageMonitor mPackageMonitor;
     private Handler mHandler = new Handler();
     private long mLastTabKeyEventTime;
-    private int mLastDeviceOrientation = Configuration.ORIENTATION_UNDEFINED;
-    private int mLastDisplayDensity;
     private boolean mFinishedOnStartup;
     private boolean mIgnoreAltTabRelease;
     private boolean mIsVisible;
+    private Configuration mLastConfig;
 
     // Top level views
     private RecentsView mRecentsView;
@@ -128,6 +134,10 @@
     private DozeTrigger mIterateTrigger;
     private final UserInteractionEvent mUserInteractionEvent = new UserInteractionEvent();
 
+    // Theme and colors
+    private SysuiColorExtractor mColorExtractor;
+    private boolean mUsingDarkText;
+
     /**
      * A common Runnable to finish Recents by launching Home with an animation depending on the
      * last activity launch state. Generally we always launch home when we exit Recents rather than
@@ -328,20 +338,23 @@
         mPackageMonitor = new RecentsPackageMonitor();
         mPackageMonitor.register(this);
 
+        // Select theme based on wallpaper colors
+        mColorExtractor = Dependency.get(SysuiColorExtractor.class);
+        mColorExtractor.addOnColorsChangedListener(this);
+        mUsingDarkText = mColorExtractor.getColors(ColorExtractor.TYPE_DARK,
+                WallpaperManager.FLAG_SYSTEM, true).supportsDarkText();
+        setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light
+                : R.style.RecentsTheme_Wallpaper);
+
         // Set the Recents layout
         setContentView(R.layout.recents);
         takeKeyEvents(true);
         mRecentsView = findViewById(R.id.recents_view);
-        mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
-                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
-                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
         mScrimViews = new SystemBarScrimViews(this);
         getWindow().getAttributes().privateFlags |=
                 WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
 
-        Configuration appConfiguration = Utilities.getAppConfiguration(this);
-        mLastDeviceOrientation = appConfiguration.orientation;
-        mLastDisplayDensity = appConfiguration.densityDpi;
+        mLastConfig = new Configuration(Utilities.getAppConfiguration(this));
         mFocusTimerDuration = getResources().getInteger(R.integer.recents_auto_advance_duration);
         mIterateTrigger = new DozeTrigger(mFocusTimerDuration, new Runnable() {
             @Override
@@ -379,11 +392,37 @@
         EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true));
         MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY);
 
+        // Getting system scrim colors ignoring wallpaper visibility since it should never be grey.
+        ColorExtractor.GradientColors systemColors = mColorExtractor.getColors(
+                ColorExtractor.TYPE_DARK, WallpaperManager.FLAG_SYSTEM, true);
+        // We don't want to interpolate colors because we're defining the initial state.
+        // Gradient should be set/ready when you open "Recents".
+        mRecentsView.setScrimColors(systemColors, false);
+
         // Notify of the next draw
         mRecentsView.getViewTreeObserver().addOnPreDrawListener(mRecentsDrawnEventListener);
     }
 
     @Override
+    public void onColorsChanged(ColorExtractor colorExtractor, int which) {
+        if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
+            // Recents doesn't care about the wallpaper being visible or not, it always
+            // wants to scrim with wallpaper colors
+            ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+                    WallpaperManager.FLAG_SYSTEM,
+                    ColorExtractor.TYPE_DARK, true /* ignoreVis */);
+            boolean darkText = colors.supportsDarkText();
+            if (darkText != mUsingDarkText) {
+                mUsingDarkText = darkText;
+                setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light
+                        : R.style.RecentsTheme_Wallpaper);
+                mRecentsView.reevaluateStyles();
+            }
+            mRecentsView.setScrimColors(colors, true /* animated */);
+        }
+    }
+
+    @Override
     protected void onNewIntent(Intent intent) {
         super.onNewIntent(intent);
 
@@ -418,8 +457,7 @@
         loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
         loader.loadTasks(this, loadPlan, loadOpts);
         TaskStack stack = loadPlan.getTaskStack();
-        mRecentsView.onReload(mIsVisible, stack.getTaskCount() == 0);
-        mRecentsView.updateStack(stack, true /* setStackViewTasks */);
+        mRecentsView.onReload(stack, mIsVisible);
 
         // Update the nav bar scrim, but defer the animation until the enter-window event
         boolean animateNavBarScrim = !launchState.launchedViaDockGesture;
@@ -465,6 +503,11 @@
     public void onEnterAnimationComplete() {
         super.onEnterAnimationComplete();
         EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
+
+        // Workaround for b/64694148: The animation started callback is not made (see
+        // RecentsImpl.getThumbnailTransitionActivityOptions) so reset the transition-waiting state
+        // once the enter animation has completed.
+        EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false));
     }
 
     @Override
@@ -483,10 +526,10 @@
         Configuration newDeviceConfiguration = Utilities.getAppConfiguration(this);
         int numStackTasks = mRecentsView.getStack().getStackTaskCount();
         EventBus.getDefault().send(new ConfigurationChangedEvent(false /* fromMultiWindow */,
-                mLastDeviceOrientation != newDeviceConfiguration.orientation,
-                mLastDisplayDensity != newDeviceConfiguration.densityDpi, numStackTasks > 0));
-        mLastDeviceOrientation = newDeviceConfiguration.orientation;
-        mLastDisplayDensity = newDeviceConfiguration.densityDpi;
+                mLastConfig.orientation != newDeviceConfiguration.orientation,
+                mLastConfig.densityDpi != newDeviceConfiguration.densityDpi, numStackTasks > 0));
+
+        mLastConfig.updateFrom(newDeviceConfiguration);
     }
 
     @Override
@@ -750,6 +793,10 @@
         ssp.removeTask(event.task.key.id);
     }
 
+    public final void onBusEvent(TaskViewDismissedEvent event) {
+        mRecentsView.updateScrimOpacity();
+    }
+
     public final void onBusEvent(AllTaskViewsDismissedEvent event) {
         SystemServicesProxy ssp = Recents.getSystemServices();
         if (ssp.hasDockedTask()) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 42e8921..86e93fd 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -24,12 +24,11 @@
 import android.app.ActivityManager;
 import android.app.ActivityManager.TaskSnapshot;
 import android.app.ActivityOptions;
+import android.app.ActivityOptions.OnAnimationStartedListener;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.GraphicBuffer;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -208,6 +207,20 @@
     protected static RecentsTaskLoadPlan sInstanceLoadPlan;
     // Stores the last pinned task time
     protected static long sLastPipTime = -1;
+    // Stores whether we are waiting for a transition to/from recents to start. During this time,
+    // we disallow the user from manually toggling recents until the transition has started.
+    private static boolean mWaitingForTransitionStart = false;
+    // Stores whether or not the user toggled while we were waiting for a transition to/from
+    // recents. In this case, we defer the toggle state until then and apply it immediately after.
+    private static boolean mToggleFollowingTransitionStart = true;
+
+    private ActivityOptions.OnAnimationStartedListener mResetToggleFlagListener =
+            new OnAnimationStartedListener() {
+                @Override
+                public void onAnimationStarted() {
+                    setWaitingForTransitionStart(false);
+                }
+            };
 
     protected Context mContext;
     protected Handler mHandler;
@@ -365,6 +378,11 @@
             return;
         }
 
+        if (mWaitingForTransitionStart) {
+            mToggleFollowingTransitionStart = true;
+            return;
+        }
+
         mDraggingInRecents = false;
         mLaunchedWhileDocking = false;
         mTriggeredFromAltTab = false;
@@ -638,6 +656,18 @@
         }
     }
 
+    public void setWaitingForTransitionStart(boolean waitingForTransitionStart) {
+        if (mWaitingForTransitionStart == waitingForTransitionStart) {
+            return;
+        }
+
+        mWaitingForTransitionStart = waitingForTransitionStart;
+        if (!waitingForTransitionStart && mToggleFollowingTransitionStart) {
+            toggleRecents(DividerView.INVALID_RECENTS_GROW_TARGET);
+        }
+        mToggleFollowingTransitionStart = false;
+    }
+
     /**
      * Returns the preloaded load plan and invalidates it.
      */
@@ -865,8 +895,9 @@
             }
             AppTransitionAnimationSpec[] specsArray = new AppTransitionAnimationSpec[specs.size()];
             specs.toArray(specsArray);
+
             return new Pair<>(ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
-                    specsArray, mHandler, null, this), null);
+                    specsArray, mHandler, mResetToggleFlagListener, this), null);
         } else {
             // Update the destination rect
             Task toTask = new Task();
@@ -884,8 +915,10 @@
                         return Lists.newArrayList(new AppTransitionAnimationSpec(
                                 toTask.key.id, thumbnail, rect));
                     });
+
             return new Pair<>(ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext,
-                    mHandler, future.getFuture(), null, false /* scaleUp */), future);
+                    mHandler, future.getFuture(), mResetToggleFlagListener, false /* scaleUp */),
+                    future);
         }
     }
 
@@ -919,11 +952,11 @@
     private GraphicBuffer drawThumbnailTransitionBitmap(Task toTask,
             TaskViewTransform toTransform) {
         SystemServicesProxy ssp = Recents.getSystemServices();
-        if (toTransform != null && toTask.key != null) {
+        int width = (int) toTransform.rect.width();
+        int height = (int) toTransform.rect.height();
+        if (toTransform != null && toTask.key != null && width > 0 && height > 0) {
             synchronized (mHeaderBarLock) {
                 boolean disabledInSafeMode = !toTask.isSystemApp && ssp.isInSafeMode();
-                int width = (int) toTransform.rect.width();
-                int height = (int) toTransform.rect.height();
                 mHeaderBar.onTaskViewSizeChanged(width, height);
                 if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
                     return RecentsTransitionHelper.drawViewIntoGraphicBuffer(width, mTaskBarHeight,
@@ -991,6 +1024,10 @@
         launchState.launchedToTaskId = runningTaskId;
         launchState.launchedWithAltTab = mTriggeredFromAltTab;
 
+        // Disable toggling of recents between starting the activity and it is visible and the app
+        // has started its transition into recents.
+        setWaitingForTransitionStart(useThumbnailTransition);
+
         // Preload the icon (this will be a null-op if we have preloaded the icon already in
         // preloadRecents())
         preloadIcon(runningTaskId);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
index 3921a20..1285626 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
@@ -29,6 +29,7 @@
 import com.android.systemui.recents.events.EventBus;
 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;
 
@@ -105,4 +106,10 @@
     public void sendLaunchRecentsEvent() throws RemoteException {
         EventBus.getDefault().post(new RecentsActivityStartingEvent());
     }
+
+    @Override
+    public void setWaitingForTransitionStartEvent(boolean waitingForTransitionStart) {
+        EventBus.getDefault().post(new SetWaitingForTransitionStartEvent(
+                waitingForTransitionStart));
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index 521157d..d74970f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -43,14 +43,14 @@
 import android.widget.TextView;
 
 import com.android.systemui.R;
+import com.android.systemui.util.leak.RotationUtils;
 
 import java.util.ArrayList;
 
-public class ScreenPinningRequest implements View.OnClickListener {
+import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE;
+import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE;
 
-    private static final int ROTATION_NONE = 0;
-    private static final int ROTATION_LANDSCAPE = 1;
-    private static final int ROTATION_SEASCAPE = 2;
+public class ScreenPinningRequest implements View.OnClickListener {
 
     private final Context mContext;
 
@@ -160,7 +160,7 @@
             DisplayMetrics metrics = new DisplayMetrics();
             mWindowManager.getDefaultDisplay().getMetrics(metrics);
             float density = metrics.density;
-            int rotation = getRotation(mContext);
+            int rotation = RotationUtils.getRotation(mContext);
 
             inflateView(rotation);
             int bgColor = mContext.getColor(
@@ -202,19 +202,6 @@
             mContext.registerReceiver(mReceiver, filter);
         }
 
-        private int getRotation(Context context) {
-            Configuration config = mContext.getResources().getConfiguration();
-            int rot = context.getDisplay().getRotation();
-            if (config.smallestScreenWidthDp < 600) {
-                if (rot == Surface.ROTATION_90) {
-                    return ROTATION_LANDSCAPE;
-                } else if (rot == Surface.ROTATION_270) {
-                    return ROTATION_SEASCAPE;
-                }
-            }
-            return ROTATION_NONE;
-        }
-
         private void inflateView(int rotation) {
             // We only want this landscape orientation on <600dp, so rather than handle
             // resource overlay for -land and -sw600dp-land, just inflate this
@@ -287,14 +274,14 @@
 
         protected void onConfigurationChanged() {
             removeAllViews();
-            inflateView(getRotation(mContext));
+            inflateView(RotationUtils.getRotation(mContext));
         }
 
         private final Runnable mUpdateLayoutRunnable = new Runnable() {
             @Override
             public void run() {
                 if (mLayout != null && mLayout.getParent() != null) {
-                    mLayout.setLayoutParams(getRequestLayoutParams(getRotation(mContext)));
+                    mLayout.setLayoutParams(getRequestLayoutParams(RotationUtils.getRotation(mContext)));
                 }
             }
         };
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/SetWaitingForTransitionStartEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/SetWaitingForTransitionStartEvent.java
new file mode 100644
index 0000000..d9cf5fb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/component/SetWaitingForTransitionStartEvent.java
@@ -0,0 +1,31 @@
+/*
+ * 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.recents.events.component;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * This is sent when we are setting/resetting the flag to wait for the transition to start.
+ */
+public class SetWaitingForTransitionStartEvent extends EventBus.Event {
+
+    public final boolean waitingForTransitionStart;
+
+    public SetWaitingForTransitionStartEvent(boolean waitingForTransitionStart) {
+        this.waitingForTransitionStart = waitingForTransitionStart;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index 21dfe8c..67685b8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -54,6 +54,7 @@
 import com.android.systemui.recents.events.activity.LaunchTaskStartedEvent;
 import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
 import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
+import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
@@ -117,31 +118,58 @@
             final Rect windowRect = Recents.getSystemServices().getWindowRect();
             transitionFuture = getAppTransitionFuture(
                     () -> composeAnimationSpecs(task, stackView, destinationStack, windowRect));
-            animStartedListener = () -> {
-                // If we are launching into another task, cancel the previous task's
-                // window transition
-                EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
-                EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
-                stackView.cancelAllTaskViewAnimations();
+            animStartedListener = new OnAnimationStartedListener() {
+                private boolean mHandled;
 
-                if (screenPinningRequested) {
-                    // Request screen pinning after the animation runs
-                    mStartScreenPinningRunnable.taskId = task.key.id;
-                    mHandler.postDelayed(mStartScreenPinningRunnable, 350);
+                @Override
+                public void onAnimationStarted() {
+                    if (mHandled) {
+                        return;
+                    }
+                    mHandled = true;
+
+                    // If we are launching into another task, cancel the previous task's
+                    // window transition
+                    EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
+                    EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
+                    stackView.cancelAllTaskViewAnimations();
+
+                    if (screenPinningRequested) {
+                        // Request screen pinning after the animation runs
+                        mStartScreenPinningRunnable.taskId = task.key.id;
+                        mHandler.postDelayed(mStartScreenPinningRunnable, 350);
+                    }
+
+                    // Reset the state where we are waiting for the transition to start
+                    EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false));
                 }
             };
         } else {
             // This is only the case if the task is not on screen (scrolled offscreen for example)
             transitionFuture = null;
-            animStartedListener = () -> {
-                // If we are launching into another task, cancel the previous task's
-                // window transition
-                EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
-                EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
-                stackView.cancelAllTaskViewAnimations();
+            animStartedListener = new OnAnimationStartedListener() {
+                private boolean mHandled;
+
+                @Override
+                public void onAnimationStarted() {
+                    if (mHandled) {
+                        return;
+                    }
+                    mHandled = true;
+
+                    // If we are launching into another task, cancel the previous task's
+                    // window transition
+                    EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
+                    EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
+                    stackView.cancelAllTaskViewAnimations();
+
+                    // Reset the state where we are waiting for the transition to start
+                    EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false));
+                }
             };
         }
 
+        EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(true));
         final ActivityOptions opts = ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext,
                 mHandler, transitionFuture != null ? transitionFuture.future : null,
                 animStartedListener, true /* scaleUp */);
@@ -400,8 +428,8 @@
             view.draw(c);
         }
         node.end(c);
-        return ThreadedRenderer.createHardwareBitmap(node, bufferWidth, bufferHeight)
-                .createGraphicBufferHandle();
+        Bitmap hwBitmap = ThreadedRenderer.createHardwareBitmap(node, bufferWidth, bufferHeight);
+        return hwBitmap.createGraphicBufferHandle();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index a0ad782..8e09481 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -22,13 +22,15 @@
 import android.animation.ObjectAnimator;
 import android.app.ActivityOptions.OnAnimationStartedListener;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.PointF;
 import android.graphics.Rect;
-import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.util.ArraySet;
 import android.util.AttributeSet;
+import android.util.MathUtils;
 import android.view.AppTransitionAnimationSpec;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -39,8 +41,11 @@
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.drawable.GradientDrawable;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settingslib.Utils;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
@@ -75,6 +80,7 @@
 import com.android.systemui.recents.views.RecentsTransitionHelper.AppTransitionAnimationSpecsFuture;
 import com.android.systemui.stackdivider.WindowManagerProxy;
 import com.android.systemui.statusbar.FlingAnimationUtils;
+import com.android.systemui.statusbar.phone.ScrimController;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -89,15 +95,18 @@
     private static final String TAG = "RecentsView";
 
     private static final int DEFAULT_UPDATE_SCRIM_DURATION = 200;
-    private static final float DEFAULT_SCRIM_ALPHA = 0.33f;
-    private static final float GRID_LAYOUT_SCRIM_ALPHA = 0.45f;
 
     private static final int SHOW_STACK_ACTION_BUTTON_DURATION = 134;
     private static final int HIDE_STACK_ACTION_BUTTON_DURATION = 100;
 
+    private static final int BUSY_RECENTS_TASK_COUNT = 3;
+
     private TaskStackView mTaskStackView;
     private TextView mStackActionButton;
     private TextView mEmptyView;
+    private final float mStackButtonShadowRadius;
+    private final PointF mStackButtonShadowDistance;
+    private final int mStackButtonShadowColor;
 
     private boolean mAwaitingFirstLayout = true;
     private boolean mLastTaskLaunchedWasFreeform;
@@ -106,8 +115,8 @@
     Rect mSystemInsets = new Rect();
     private int mDividerSize;
 
-    private final float mScrimAlpha;
-    private final Drawable mBackgroundScrim;
+    private float mBusynessFactor;
+    private GradientDrawable mBackgroundScrim;
     private Animator mBackgroundScrimAnimator;
 
     private RecentsTransitionHelper mTransitionHelper;
@@ -136,33 +145,72 @@
         mDividerSize = ssp.getDockedDividerSize(context);
         mTouchHandler = new RecentsViewTouchHandler(this);
         mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f);
-        mScrimAlpha = Recents.getConfiguration().isGridEnabled
-                ? GRID_LAYOUT_SCRIM_ALPHA : DEFAULT_SCRIM_ALPHA;
-        mBackgroundScrim = new ColorDrawable(
-                Color.argb((int) (mScrimAlpha * 255), 0, 0, 0)).mutate();
+        mBackgroundScrim = new GradientDrawable(context);
+        mBackgroundScrim.setCallback(this);
+
+        boolean usingDarkText = Color.luminance(
+                Utils.getColorAttr(mContext, R.attr.wallpaperTextColor)) < 0.5f;
 
         LayoutInflater inflater = LayoutInflater.from(context);
-        if (RecentsDebugFlags.Static.EnableStackActionButton) {
-            mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button,
-                    this, false);
-            mStackActionButton.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    EventBus.getDefault().send(new DismissAllTaskViewsEvent());
-                }
-            });
-            addView(mStackActionButton);
-        }
         mEmptyView = (TextView) inflater.inflate(R.layout.recents_empty, this, false);
         addView(mEmptyView);
+
+        if (RecentsDebugFlags.Static.EnableStackActionButton) {
+            if (mStackActionButton != null) {
+                removeView(mStackActionButton);
+            }
+            mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button,
+                    this, false);
+            mStackActionButton.setOnClickListener(
+                    v -> EventBus.getDefault().send(new DismissAllTaskViewsEvent()));
+
+            mStackButtonShadowRadius = mStackActionButton.getShadowRadius();
+            mStackButtonShadowDistance = new PointF(mStackActionButton.getShadowDx(),
+                    mStackActionButton.getShadowDy());
+            mStackButtonShadowColor = mStackActionButton.getShadowColor();
+            addView(mStackActionButton);
+        }
+
+        reevaluateStyles();
+    }
+
+    public void reevaluateStyles() {
+        int textColor = Utils.getColorAttr(mContext, R.attr.wallpaperTextColor);
+        boolean usingDarkText = Color.luminance(textColor) < 0.5f;
+
+        mEmptyView.setTextColor(textColor);
+        mEmptyView.setCompoundDrawableTintList(new ColorStateList(new int[][]{
+                {android.R.attr.state_enabled}}, new int[]{textColor}));
+
+        if (mStackActionButton != null) {
+            mStackActionButton.setTextColor(textColor);
+            // Enable/disable shadow if text color is already dark.
+            if (usingDarkText) {
+                mStackActionButton.setShadowLayer(0, 0, 0, 0);
+            } else {
+                mStackActionButton.setShadowLayer(mStackButtonShadowRadius,
+                        mStackButtonShadowDistance.x, mStackButtonShadowDistance.y,
+                        mStackButtonShadowColor);
+            }
+        }
+
+        // Let's also require dark status and nav bars if the text is dark
+        int systemBarsStyle = usingDarkText ? View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
+                View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0;
+
+        setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
+                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
+                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
+                systemBarsStyle);
     }
 
     /**
      * Called from RecentsActivity when it is relaunched.
      */
-    public void onReload(boolean isResumingFromVisible, boolean isTaskStackEmpty) {
-        RecentsConfiguration config = Recents.getConfiguration();
-        RecentsActivityLaunchState launchState = config.getLaunchState();
+    public void onReload(TaskStack stack, boolean isResumingFromVisible) {
+        final RecentsConfiguration config = Recents.getConfiguration();
+        final RecentsActivityLaunchState launchState = config.getLaunchState();
+        final boolean isTaskStackEmpty = stack.getTaskCount() == 0;
 
         if (mTaskStackView == null) {
             isResumingFromVisible = false;
@@ -177,17 +225,19 @@
 
         // Update the stack
         mTaskStackView.onReload(isResumingFromVisible);
+        updateStack(stack, true /* setStackViewTasks */);
+        updateBusyness();
 
         if (isResumingFromVisible) {
             // If we are already visible, then restore the background scrim
-            animateBackgroundScrim(1f, DEFAULT_UPDATE_SCRIM_DURATION);
+            animateBackgroundScrim(getOpaqueScrimAlpha(), DEFAULT_UPDATE_SCRIM_DURATION);
         } else {
             // If we are already occluded by the app, then set the final background scrim alpha now.
             // Otherwise, defer until the enter animation completes to animate the scrim alpha with
             // the tasks for the home animation.
             if (launchState.launchedViaDockGesture || launchState.launchedFromApp
                     || isTaskStackEmpty) {
-                mBackgroundScrim.setAlpha(255);
+                mBackgroundScrim.setAlpha((int) (getOpaqueScrimAlpha() * 255));
             } else {
                 mBackgroundScrim.setAlpha(0);
             }
@@ -211,13 +261,40 @@
     }
 
     /**
+     * Animates the scrim opacity based on how many tasks are visible.
+     * Called from {@link RecentsActivity} when tasks are dismissed.
+     */
+    public void updateScrimOpacity() {
+        if (updateBusyness()) {
+            animateBackgroundScrim(getOpaqueScrimAlpha(), DEFAULT_UPDATE_SCRIM_DURATION);
+        }
+    }
+
+    /**
+     * Updates the busyness factor.
+     *
+     * @return True if it changed.
+     */
+    private boolean updateBusyness() {
+        final int taskCount = mTaskStackView.getStack().getStackTaskCount();
+        final float busyness = Math.min(taskCount, BUSY_RECENTS_TASK_COUNT)
+                / (float) BUSY_RECENTS_TASK_COUNT;
+        if (mBusynessFactor == busyness) {
+            return false;
+        } else {
+            mBusynessFactor = busyness;
+            return true;
+        }
+    }
+
+    /**
      * Returns the current TaskStack.
      */
     public TaskStack getStack() {
         return mTaskStackView.getStack();
     }
 
-    /*
+    /**
      * Returns the window background scrim.
      */
     public Drawable getBackgroundScrim() {
@@ -313,6 +390,16 @@
         }
     }
 
+    /**
+     * Set the color of the scrim.
+     *
+     * @param scrimColors Colors to use.
+     * @param animated Interpolate colors if true.
+     */
+    public void setScrimColors(ColorExtractor.GradientColors scrimColors, boolean animated) {
+        mBackgroundScrim.setColors(scrimColors, animated);
+    }
+
     @Override
     protected void onAttachedToWindow() {
         EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
@@ -378,6 +465,11 @@
             mEmptyView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
         }
 
+        // Needs to know the screen size since the gradient never scales up or down
+        // even when bounds change.
+        mBackgroundScrim.setScreenSize(right - left, bottom - top);
+        mBackgroundScrim.setBounds(left, top, right, bottom);
+
         if (RecentsDebugFlags.Static.EnableStackActionButton) {
             // Layout the stack action button such that its drawable is start-aligned with the
             // stack, vertically centered in the available space above the stack
@@ -606,7 +698,7 @@
         RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
         if (!launchState.launchedViaDockGesture && !launchState.launchedFromApp
                 && getStack().getTaskCount() > 0) {
-            animateBackgroundScrim(1f,
+            animateBackgroundScrim(getOpaqueScrimAlpha(),
                     TaskStackAnimationHelper.ENTER_FROM_HOME_TRANSLATION_DURATION);
         }
     }
@@ -766,13 +858,25 @@
     }
 
     /**
+     * Scrim alpha based on how busy recents is:
+     * Scrim will be {@link ScrimController#GRADIENT_SCRIM_ALPHA} when the stack is empty,
+     * and {@link ScrimController#GRADIENT_SCRIM_ALPHA_BUSY} when it's full.
+     *
+     * @return Alpha from 0 to 1.
+     */
+    private float getOpaqueScrimAlpha() {
+        return MathUtils.map(0, 1, ScrimController.GRADIENT_SCRIM_ALPHA,
+                ScrimController.GRADIENT_SCRIM_ALPHA_BUSY, mBusynessFactor);
+    }
+
+    /**
      * Animates the background scrim to the given {@param alpha}.
      */
     private void animateBackgroundScrim(float alpha, int duration) {
         Utilities.cancelAnimationWithoutCallbacks(mBackgroundScrimAnimator);
         // Calculate the absolute alpha to animate from
-        int fromAlpha = (int) ((mBackgroundScrim.getAlpha() / (mScrimAlpha * 255)) * 255);
-        int toAlpha = (int) (alpha * 255);
+        final int fromAlpha = mBackgroundScrim.getAlpha();
+        final int toAlpha = (int) (alpha * 255);
         mBackgroundScrimAnimator = ObjectAnimator.ofInt(mBackgroundScrim, Utilities.DRAWABLE_ALPHA,
                 fromAlpha, toAlpha);
         mBackgroundScrimAnimator.setDuration(duration);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index 8135034..9c14d48 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -23,6 +23,7 @@
 import android.graphics.Path;
 import android.graphics.Rect;
 import android.util.ArraySet;
+import android.util.Log;
 import android.util.MutableFloat;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
@@ -481,6 +482,13 @@
         int height = mStackRect.height() - mInitialTopOffset - mStackBottomOffset;
         mTaskRect.set(mStackRect.left, mStackRect.top, mStackRect.right, mStackRect.top + height);
 
+        if (mTaskRect.width() <= 0 || mTaskRect.height() <= 0) {
+            // Logging for b/36654830
+            Log.e(TAG, "Invalid task rect: taskRect=" + mTaskRect + " stackRect=" + mStackRect
+                    + " displayRect=" + displayRect + " windowRect=" + windowRect
+                    + " taskStackBounds=" + taskStackBounds);
+        }
+
         // Short circuit here if the stack rects haven't changed so we don't do all the work below
         if (!lastStackRect.equals(mStackRect)) {
             // Reinitialize the focused and unfocused curves
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 2d47c7b..a2409d1 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -50,6 +50,7 @@
 import android.os.UserHandle;
 import android.provider.MediaStore;
 import android.util.DisplayMetrics;
+import android.util.Slog;
 import android.view.Display;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -100,6 +101,7 @@
  * An AsyncTask that saves an image to the media store in the background.
  */
 class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
+    private static final String TAG = "SaveImageInBackgroundTask";
 
     private static final String SCREENSHOTS_DIR_NAME = "Screenshots";
     private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png";
@@ -303,6 +305,7 @@
         } catch (Exception e) {
             // IOException/UnsupportedOperationException may be thrown if external storage is not
             // mounted
+            Slog.e(TAG, "unable to save screenshot", e);
             mParams.clearImage();
             mParams.errorMsgResId = R.string.screenshot_failed_to_save_text;
         }
@@ -379,8 +382,6 @@
  * An AsyncTask that deletes an image from the media store in the background.
  */
 class DeleteImageInBackgroundTask extends AsyncTask<Uri, Void, Void> {
-    private static final String TAG = "DeleteImageInBackgroundTask";
-
     private Context mContext;
 
     DeleteImageInBackgroundTask(Context context) {
@@ -578,7 +579,8 @@
         if (requiresRotation) {
             // Rotate the screenshot to the current orientation
             Bitmap ss = Bitmap.createBitmap(mDisplayMetrics.widthPixels,
-                    mDisplayMetrics.heightPixels, Bitmap.Config.ARGB_8888);
+                    mDisplayMetrics.heightPixels, Bitmap.Config.ARGB_8888,
+                    mScreenBitmap.hasAlpha(), mScreenBitmap.getColorSpace());
             Canvas c = new Canvas(ss);
             c.translate(ss.getWidth() / 2, ss.getHeight() / 2);
             c.rotate(degrees);
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index 0232911..da0a435 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -82,6 +82,7 @@
     private void addDivider(Configuration configuration) {
         mView = (DividerView)
                 LayoutInflater.from(mContext).inflate(R.layout.docked_stack_divider, null);
+        mView.injectDependencies(mWindowManager, mDividerState);
         mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE);
         mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
         final int size = mContext.getResources().getDimensionPixelSize(
@@ -90,7 +91,6 @@
         final int width = landscape ? size : MATCH_PARENT;
         final int height = landscape ? MATCH_PARENT : size;
         mWindowManager.add(mView, width, height);
-        mView.injectDependencies(mWindowManager, mDividerState);
     }
 
     private void removeDivider() {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java
index 353a974..3a5c61e 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java
@@ -22,4 +22,5 @@
 public class DividerState {
     public boolean animateAfterRecentsDrawn;
     public boolean growAfterRecentsDrawn;
+    public float mRatioPositionBeforeMinimized;
 }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 7691652..45835d5 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -372,6 +372,17 @@
     public void injectDependencies(DividerWindowManager windowManager, DividerState dividerState) {
         mWindowManager = windowManager;
         mState = dividerState;
+
+        // Set the previous position ratio before minimized state after attaching this divider
+        if (mStableInsets.isEmpty()) {
+            SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
+        }
+        int position = (int) (mState.mRatioPositionBeforeMinimized *
+                (isHorizontalDivision() ? mDisplayHeight : mDisplayWidth));
+        mSnapAlgorithm = null;
+        initializeSnapAlgorithm();
+        mDividerPositionBeforeMinimized = mSnapAlgorithm.calculateNonDismissingSnapTarget(position)
+                .position;
     }
 
     public WindowManagerProxy getWindowManagerProxy() {
@@ -727,19 +738,12 @@
             mHandle.setAlpha(minimized ? 0f : 1f);
             mDockedStackMinimized = minimized;
         } else if (mDockedStackMinimized != minimized) {
-            if (mStableInsets.isEmpty()) {
-                SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
-            }
             mMinimizedSnapAlgorithm = null;
             mDockedStackMinimized = minimized;
             initializeSnapAlgorithm();
             if (mIsInMinimizeInteraction != minimized) {
                 if (minimized) {
                     mIsInMinimizeInteraction = true;
-                    mDividerPositionBeforeMinimized = DockedDividerUtils.calculateMiddlePosition(
-                            isHorizontalDivision(), mStableInsets, mDisplayWidth, mDisplayHeight,
-                            mDividerSize);
-
                     int position = mMinimizedSnapAlgorithm.getMiddleTarget().position;
                     resizeStack(position, position, mMinimizedSnapAlgorithm.getMiddleTarget());
                 } else {
@@ -784,7 +788,7 @@
             mIsInMinimizeInteraction = true;
             if (minimized && (mCurrentAnimator == null || !mCurrentAnimator.isRunning())
                     && (mDividerPositionBeforeMinimized <= 0 || !mAdjustedForIme)) {
-                mDividerPositionBeforeMinimized = getCurrentPosition();
+                savePositionBeforeMinimized();
             }
             mMinimizedSnapAlgorithm = null;
             mDockedStackMinimized = minimized;
@@ -844,10 +848,16 @@
         // Only get new position if home stack is resizable, ime is open and not minimized
         // (including the animation)
         if (mHomeStackResizable && adjustedForIme && !mIsInMinimizeInteraction) {
-            mDividerPositionBeforeMinimized = getCurrentPosition();
+            savePositionBeforeMinimized();
         }
     }
 
+    private void savePositionBeforeMinimized() {
+        mDividerPositionBeforeMinimized = getCurrentPosition();
+        mState.mRatioPositionBeforeMinimized = (float) mDividerPositionBeforeMinimized /
+                (isHorizontalDivision() ? mDisplayHeight : mDisplayWidth);
+    }
+
     private void resetBackground() {
         mBackground.setPivotX(mBackground.getWidth() / 2);
         mBackground.setPivotY(mBackground.getHeight() / 2);
@@ -1210,14 +1220,6 @@
                 mDockSide, mDividerSize);
         mEntranceAnimationRunning = true;
 
-        // Insets might not have been fetched yet, so fetch manually if needed.
-        if (mStableInsets.isEmpty()) {
-            SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
-            mSnapAlgorithm = null;
-            mMinimizedSnapAlgorithm = null;
-            initializeSnapAlgorithm();
-        }
-
         resizeStack(position, mSnapAlgorithm.getMiddleTarget().position,
                 mSnapAlgorithm.getMiddleTarget());
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index eec818b..29b720c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -943,6 +943,10 @@
         }
     }
 
+    public boolean isDrawingAppearAnimation() {
+        return mDrawingAppearAnimation;
+    }
+
     @Override
     protected void dispatchDraw(Canvas canvas) {
         if (mDrawingAppearAnimation) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
index ae665c7..ba92c45 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
@@ -32,6 +32,7 @@
     private final boolean mHasOverlappingRendering;
     AnimationDrawable mAnim;
     boolean mAttached;
+    private boolean mAllowAnimation = true;
 
     // Tracks the last image that was set, so that we don't refresh the image if it is exactly
     // the same as the previous one. If this is a resid, we track that. If it's a drawable, we
@@ -56,6 +57,17 @@
         }
     }
 
+    public void setAllowAnimation(boolean allowAnimation) {
+        if (mAllowAnimation != allowAnimation) {
+            mAllowAnimation = allowAnimation;
+            updateAnim();
+            if (!mAllowAnimation && mAnim != null) {
+                // Reset drawable such that we show the first frame whenever we're not animating.
+                mAnim.setVisible(getVisibility() == VISIBLE, true /* restart */);
+            }
+        }
+    }
+
     private void updateAnim() {
         Drawable drawable = getDrawable();
         if (mAttached && mAnim != null) {
@@ -63,7 +75,7 @@
         }
         if (drawable instanceof AnimationDrawable) {
             mAnim = (AnimationDrawable) drawable;
-            if (isShown()) {
+            if (isShown() && mAllowAnimation) {
                 mAnim.start();
             }
         } else {
@@ -114,7 +126,7 @@
     protected void onVisibilityChanged(View changedView, int vis) {
         super.onVisibilityChanged(changedView, vis);
         if (mAnim != null) {
-            if (isShown()) {
+            if (isShown() && mAllowAnimation) {
                 mAnim.start();
             } else {
                 mAnim.stop();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index bf89b01..2f4cd0d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -77,8 +77,9 @@
     private static final int MSG_TOGGLE_APP_SPLIT_SCREEN       = 30 << MSG_SHIFT;
     private static final int MSG_APP_TRANSITION_FINISHED       = 31 << MSG_SHIFT;
     private static final int MSG_DISMISS_KEYBOARD_SHORTCUTS    = 32 << MSG_SHIFT;
-    private static final int MSG_HANDLE_SYSNAV_KEY             = 33 << MSG_SHIFT;
+    private static final int MSG_HANDLE_SYSTEM_KEY             = 33 << MSG_SHIFT;
     private static final int MSG_SHOW_GLOBAL_ACTIONS           = 34 << MSG_SHIFT;
+    private static final int MSG_SHOW_SHUTDOWN_UI              = 35 << MSG_SHIFT;
 
     public static final int FLAG_EXCLUDE_NONE = 0;
     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -134,8 +135,9 @@
         default void remQsTile(ComponentName tile) { }
         default void clickTile(ComponentName tile) { }
 
-        default void handleSystemNavigationKey(int arg1) { }
+        default void handleSystemKey(int arg1) { }
         default void handleShowGlobalActionsMenu() { }
+        default void handleShowShutdownUi(boolean isReboot, String reason) { }
     }
 
     @VisibleForTesting
@@ -415,9 +417,9 @@
     }
 
     @Override
-    public void handleSystemNavigationKey(int key) {
+    public void handleSystemKey(int key) {
         synchronized (mLock) {
-            mHandler.obtainMessage(MSG_HANDLE_SYSNAV_KEY, key, 0).sendToTarget();
+            mHandler.obtainMessage(MSG_HANDLE_SYSTEM_KEY, key, 0).sendToTarget();
         }
     }
 
@@ -429,6 +431,15 @@
         }
     }
 
+    @Override
+    public void showShutdownUi(boolean isReboot, String reason) {
+        synchronized (mLock) {
+            mHandler.removeMessages(MSG_SHOW_SHUTDOWN_UI);
+            mHandler.obtainMessage(MSG_SHOW_SHUTDOWN_UI, isReboot ? 1 : 0, 0, reason)
+                    .sendToTarget();
+        }
+    }
+
     private final class H extends Handler {
         private H(Looper l) {
             super(l);
@@ -600,9 +611,9 @@
                         mCallbacks.get(i).toggleSplitScreen();
                     }
                     break;
-                case MSG_HANDLE_SYSNAV_KEY:
+                case MSG_HANDLE_SYSTEM_KEY:
                     for (int i = 0; i < mCallbacks.size(); i++) {
-                        mCallbacks.get(i).handleSystemNavigationKey(msg.arg1);
+                        mCallbacks.get(i).handleSystemKey(msg.arg1);
                     }
                     break;
                 case MSG_SHOW_GLOBAL_ACTIONS:
@@ -610,6 +621,11 @@
                         mCallbacks.get(i).handleShowGlobalActionsMenu();
                     }
                     break;
+                case MSG_SHOW_SHUTDOWN_UI:
+                    for (int i = 0; i < mCallbacks.size(); i++) {
+                        mCallbacks.get(i).handleShowShutdownUi(msg.arg1 != 0, (String) msg.obj);
+                    }
+                    break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
index 5436664..d7c6443 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar;
 
+import android.annotation.ColorInt;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.util.AttributeSet;
@@ -46,6 +47,10 @@
         mDismissButton = (DismissViewButton) findContentView();
     }
 
+    public void setTextColor(@ColorInt int color) {
+        mDismissButton.setTextColor(color);
+    }
+
     public void setOnButtonClickListener(OnClickListener listener) {
         mContent.setOnClickListener(listener);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
index 92b0890..58adde2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar;
 
+import android.annotation.ColorInt;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.util.AttributeSet;
@@ -45,6 +46,10 @@
         return findViewById(R.id.no_notifications);
     }
 
+    public void setTextColor(@ColorInt int color) {
+        mEmptyText.setTextColor(color);
+    }
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 1c1be98..22c0b736 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -63,6 +63,8 @@
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
 import com.android.systemui.statusbar.NotificationGuts.GutsContent;
+import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
+import com.android.systemui.statusbar.notification.AboveShelfObserver;
 import com.android.systemui.statusbar.notification.HybridNotificationView;
 import com.android.systemui.statusbar.notification.NotificationInflater;
 import com.android.systemui.statusbar.notification.NotificationUtils;
@@ -162,6 +164,7 @@
     private boolean mIsSystemChildExpanded;
     private boolean mIsPinned;
     private FalsingManager mFalsingManager;
+    private AboveShelfChangedListener mAboveShelfChangedListener;
     private HeadsUpManager mHeadsUpManager;
 
     private boolean mJustClicked;
@@ -171,6 +174,18 @@
     private OnExpandClickListener mOnExpandClickListener;
     private boolean mGroupExpansionChanging;
 
+    /**
+     * Whether or not a notification that is not part of a group of notifications can be manually
+     * expanded by the user.
+     */
+    private boolean mEnableNonGroupedNotificationExpand;
+
+    /**
+     * Whether or not to update the background of the header of the notification when its expanded.
+     * If {@code true}, the header background will disappear when expanded.
+     */
+    private boolean mShowGroupBackgroundWhenExpanded;
+
     private OnClickListener mExpandClickListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
@@ -183,7 +198,7 @@
                 MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTIFICATION_GROUP_EXPANDER,
                         nowExpanded);
                 onExpansionChanged(true /* userAction */, wasExpanded);
-            } else {
+            } else if (mEnableNonGroupedNotificationExpand) {
                 if (v.isAccessibilityFocused()) {
                     mPrivateLayout.setFocusOnVisibilityChange();
                 }
@@ -337,7 +352,7 @@
         mShowingPublicInitialized = false;
         updateNotificationColor();
         if (mMenuRow != null) {
-            mMenuRow.onNotificationUpdated();
+            mMenuRow.onNotificationUpdated(mStatusBarNotification);
         }
         if (mIsSummaryWithChildren) {
             mChildrenContainer.recreateNotificationHeader(mExpandClickListener);
@@ -376,6 +391,10 @@
         expandedIcon.setStaticDrawableColor(color);
     }
 
+    public void setAboveShelfChangedListener(AboveShelfChangedListener aboveShelfChangedListener) {
+        mAboveShelfChangedListener = aboveShelfChangedListener;
+    }
+
     @Override
     public boolean isDimmable() {
         if (!getShowingLayout().isDimmable()) {
@@ -430,6 +449,7 @@
     }
 
     public void setHeadsUp(boolean isHeadsUp) {
+        boolean wasAboveShelf = isAboveShelf();
         int intrinsicBefore = getIntrinsicHeight();
         mIsHeadsUp = isHeadsUp;
         mPrivateLayout.setHeadsUp(isHeadsUp);
@@ -442,6 +462,8 @@
         }
         if (isHeadsUp) {
             setAboveShelf(true);
+        } else if (isAboveShelf() != wasAboveShelf) {
+            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
         }
     }
 
@@ -622,6 +644,7 @@
      */
     public void setPinned(boolean pinned) {
         int intrinsicHeight = getIntrinsicHeight();
+        boolean wasAboveShelf = isAboveShelf();
         mIsPinned = pinned;
         if (intrinsicHeight != getIntrinsicHeight()) {
             notifyHeightChanged(false /* needsAnimation */);
@@ -633,6 +656,9 @@
             setUserExpanded(true);
         }
         setChronometerRunning(mLastChronometerRunning);
+        if (isAboveShelf() != wasAboveShelf) {
+            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
+        }
     }
 
     public boolean isPinned() {
@@ -730,6 +756,19 @@
         return getShowingLayout().getVisibleNotificationHeader();
     }
 
+
+    /**
+     * @return the contracted notification header. This can be different from
+     * {@link #getNotificationHeader()} and also {@link #getVisibleNotificationHeader()} and only
+     * returns the contracted version.
+     */
+    public NotificationHeaderView getContractedNotificationHeader() {
+        if (mIsSummaryWithChildren) {
+            return mChildrenContainer.getHeaderView();
+        }
+        return mPrivateLayout.getContractedNotificationHeader();
+    }
+
     public void setOnExpandClickListener(OnExpandClickListener onExpandClickListener) {
         mOnExpandClickListener = onExpandClickListener;
     }
@@ -805,7 +844,7 @@
 
     public NotificationMenuRowPlugin createMenu() {
         if (mMenuRow.getMenuView() == null) {
-            mMenuRow.createMenu(this);
+            mMenuRow.createMenu(this, mStatusBarNotification);
             mMenuRow.setAppName(mAppName);
             FrameLayout.LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
                     LayoutParams.MATCH_PARENT);
@@ -818,7 +857,9 @@
         return mMenuRow;
     }
 
+    @Override
     public void onDensityOrFontScaleChanged() {
+        super.onDensityOrFontScaleChanged();
         initDimens();
         // Let's update our childrencontainer. This is intentionally not guarded with
         // mIsSummaryWithChildren since we might have had children but not anymore.
@@ -838,7 +879,7 @@
         if (oldMenu != null) {
             int menuIndex = indexOfChild(oldMenu);
             removeView(oldMenu);
-            mMenuRow.createMenu(ExpandableNotificationRow.this);
+            mMenuRow.createMenu(ExpandableNotificationRow.this, mStatusBarNotification);
             mMenuRow.setAppName(mAppName);
             addView(mMenuRow.getMenuView(), menuIndex);
         }
@@ -979,8 +1020,12 @@
     }
 
     public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
+        boolean wasAboveShelf = isAboveShelf();
         mHeadsupDisappearRunning = headsUpAnimatingAway;
         mPrivateLayout.setHeadsUpAnimatingAway(headsUpAnimatingAway);
+        if (isAboveShelf() != wasAboveShelf) {
+            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
+        }
     }
 
     /**
@@ -1173,7 +1218,7 @@
     }
 
     public interface ExpansionLogger {
-        public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
+        void logNotificationExpansion(String key, boolean userAction, boolean expanded);
     }
 
     public ExpandableNotificationRow(Context context, AttributeSet attrs) {
@@ -1196,10 +1241,16 @@
         mMaxHeadsUpHeight = getFontScaledHeight(R.dimen.notification_max_heads_up_height);
         mMaxHeadsUpHeightIncreased = getFontScaledHeight(
                 R.dimen.notification_max_heads_up_height_increased);
-        mIncreasedPaddingBetweenElements = getResources()
-                .getDimensionPixelSize(R.dimen.notification_divider_height_increased);
-        mIconTransformContentShiftNoIcon = getResources().getDimensionPixelSize(
+
+        Resources res = getResources();
+        mIncreasedPaddingBetweenElements = res.getDimensionPixelSize(
+                R.dimen.notification_divider_height_increased);
+        mIconTransformContentShiftNoIcon = res.getDimensionPixelSize(
                 R.dimen.notification_icon_transform_content_shift);
+        mEnableNonGroupedNotificationExpand =
+                res.getBoolean(R.bool.config_enableNonGroupedNotificationExpand);
+        mShowGroupBackgroundWhenExpanded =
+                res.getBoolean(R.bool.config_showGroupNotificationBgWhenExpanded);
     }
 
     /**
@@ -1252,30 +1303,39 @@
                 mChildrenContainer.setIsLowPriority(mIsLowPriority);
                 mChildrenContainer.setContainingNotification(ExpandableNotificationRow.this);
                 mChildrenContainer.onNotificationUpdated();
-                mTranslateableViews.add(mChildrenContainer);
+
+                if (mShouldTranslateContents) {
+                    mTranslateableViews.add(mChildrenContainer);
+                }
             }
         });
 
-        // Add the views that we translate to reveal the menu
-        mTranslateableViews = new ArrayList<View>();
-        for (int i = 0; i < getChildCount(); i++) {
-            mTranslateableViews.add(getChildAt(i));
+        if (mShouldTranslateContents) {
+            // Add the views that we translate to reveal the menu
+            mTranslateableViews = new ArrayList<>();
+            for (int i = 0; i < getChildCount(); i++) {
+                mTranslateableViews.add(getChildAt(i));
+            }
+            // Remove views that don't translate
+            mTranslateableViews.remove(mChildrenContainerStub);
+            mTranslateableViews.remove(mGutsStub);
         }
-        // Remove views that don't translate
-        mTranslateableViews.remove(mChildrenContainerStub);
-        mTranslateableViews.remove(mGutsStub);
     }
 
     public void resetTranslation() {
         if (mTranslateAnim != null) {
             mTranslateAnim.cancel();
         }
-        if (mTranslateableViews != null) {
+
+        if (!mShouldTranslateContents) {
+            setTranslationX(0);
+        } else if (mTranslateableViews != null) {
             for (int i = 0; i < mTranslateableViews.size(); i++) {
                 mTranslateableViews.get(i).setTranslationX(0);
             }
+            invalidateOutline();
         }
-        invalidateOutline();
+
         mMenuRow.resetMenu();
     }
 
@@ -1295,13 +1355,17 @@
             // Don't translate if guts are showing.
             return;
         }
-        // Translate the group of views
-        for (int i = 0; i < mTranslateableViews.size(); i++) {
-            if (mTranslateableViews.get(i) != null) {
-                mTranslateableViews.get(i).setTranslationX(translationX);
+        if (!mShouldTranslateContents) {
+            setTranslationX(translationX);
+        } else if (mTranslateableViews != null) {
+            // Translate the group of views
+            for (int i = 0; i < mTranslateableViews.size(); i++) {
+                if (mTranslateableViews.get(i) != null) {
+                    mTranslateableViews.get(i).setTranslationX(translationX);
+                }
             }
+            invalidateOutline();
         }
-        invalidateOutline();
         if (mMenuRow.getMenuView() != null) {
             mMenuRow.onTranslationUpdate(translationX);
         }
@@ -1309,10 +1373,15 @@
 
     @Override
     public float getTranslation() {
+        if (!mShouldTranslateContents) {
+            return getTranslationX();
+        }
+
         if (mTranslateableViews != null && mTranslateableViews.size() > 0) {
             // All of the views in the list should have same translation, just use first one.
             return mTranslateableViews.get(0).getTranslationX();
         }
+
         return 0;
     }
 
@@ -1402,7 +1471,7 @@
         if (mIsSummaryWithChildren && !mShowingPublic) {
             return !mChildrenExpanded;
         }
-        return mExpandable;
+        return mEnableNonGroupedNotificationExpand && mExpandable;
     }
 
     public void setExpandable(boolean expandable) {
@@ -1456,6 +1525,10 @@
         mHasUserChangedExpansion = true;
         mUserExpanded = userExpanded;
         onExpansionChanged(true /* userAction */, wasExpanded);
+        if (!wasExpanded && isExpanded()
+                && getActualHeight() != getIntrinsicHeight()) {
+            notifyHeightChanged(true /* needsAnimation */);
+        }
     }
 
     public void resetUserExpansion() {
@@ -1514,6 +1587,7 @@
      */
     public void setOnKeyguard(boolean onKeyguard) {
         if (onKeyguard != mOnKeyguard) {
+            boolean wasAboveShelf = isAboveShelf();
             final boolean wasExpanded = isExpanded();
             mOnKeyguard = onKeyguard;
             onExpansionChanged(false /* userAction */, wasExpanded);
@@ -1523,6 +1597,9 @@
                 }
                 notifyHeightChanged(false /* needsAnimation */);
             }
+            if (isAboveShelf() != wasAboveShelf) {
+                mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
+            }
         }
     }
 
@@ -1896,6 +1973,9 @@
         if (mGuts != null) {
             mGuts.setActualHeight(height);
         }
+        if (mMenuRow.getMenuView() != null) {
+            mMenuRow.onHeightUpdate();
+        }
     }
 
     @Override
@@ -2001,7 +2081,8 @@
     public void updateBackgroundForGroupState() {
         if (mIsSummaryWithChildren) {
             // Only when the group has finished expanding do we hide its background.
-            mShowNoBackground = isGroupExpanded() && !isGroupExpansionChanging() && !isUserLocked();
+            mShowNoBackground = !mShowGroupBackgroundWhenExpanded && isGroupExpanded()
+                    && !isGroupExpansionChanging() && !isUserLocked();
             mChildrenContainer.updateHeaderForExpansion(mShowNoBackground);
             List<ExpandableNotificationRow> children = mChildrenContainer.getNotificationChildren();
             for (int i = 0; i < children.size(); i++) {
@@ -2010,10 +2091,10 @@
         } else if (isChildInGroup()) {
             final int childColor = getShowingLayout().getBackgroundColorForExpansionState();
             // Only show a background if the group is expanded OR if it is expanding / collapsing
-            // and has a custom background color
+            // and has a custom background color.
             final boolean showBackground = isGroupExpanded()
                     || ((mNotificationParent.isGroupExpansionChanging()
-                            || mNotificationParent.isUserLocked()) && childColor != 0);
+                    || mNotificationParent.isUserLocked()) && childColor != 0);
             mShowNoBackground = !showBackground;
         } else {
             // Only children or parents ever need no background.
@@ -2066,8 +2147,12 @@
         float x = event.getX();
         float y = event.getY();
         NotificationHeaderView header = getVisibleNotificationHeader();
-        if (header != null) {
-            return header.isInTouchRect(x - getTranslation(), y);
+        if (header != null && header.isInTouchRect(x - getTranslation(), y)) {
+            return true;
+        }
+        if ((!mIsSummaryWithChildren || mShowingPublic)
+                && getShowingLayout().disallowSingleClick(x, y)) {
+            return true;
         }
         return super.disallowSingleClick(event);
     }
@@ -2168,7 +2253,11 @@
     }
 
     public void setAboveShelf(boolean aboveShelf) {
+        boolean wasAboveShelf = isAboveShelf();
         mAboveShelf = aboveShelf;
+        if (isAboveShelf() != wasAboveShelf) {
+            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
+        }
     }
 
     public static class NotificationViewState extends ExpandableViewState {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
index 91abc87..2556890 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
@@ -17,12 +17,14 @@
 package com.android.systemui.statusbar;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Outline;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewOutlineProvider;
+import com.android.systemui.R;
 
 /**
  * Like {@link ExpandableView}, but setting an outline for the height and clipping.
@@ -32,18 +34,26 @@
     private final Rect mOutlineRect = new Rect();
     private boolean mCustomOutline;
     private float mOutlineAlpha = -1f;
+    private float mOutlineRadius;
 
-    ViewOutlineProvider mProvider = new ViewOutlineProvider() {
+    /**
+     * {@code true} if the children views of the {@link ExpandableOutlineView} are translated when
+     * it is moved. Otherwise, the translation is set on the {@code ExpandableOutlineView} itself.
+     */
+    protected boolean mShouldTranslateContents;
+
+    private final ViewOutlineProvider mProvider = new ViewOutlineProvider() {
         @Override
         public void getOutline(View view, Outline outline) {
-            int translation = (int) getTranslation();
+            int translation = mShouldTranslateContents ? (int) getTranslation() : 0;
             if (!mCustomOutline) {
-                outline.setRect(translation,
+                outline.setRoundRect(translation,
                         mClipTopAmount,
                         getWidth() + translation,
-                        Math.max(getActualHeight() - mClipBottomAmount, mClipTopAmount));
+                        Math.max(getActualHeight() - mClipBottomAmount, mClipTopAmount),
+                        mOutlineRadius);
             } else {
-                outline.setRect(mOutlineRect);
+                outline.setRoundRect(mOutlineRect, mOutlineRadius);
             }
             outline.setAlpha(mOutlineAlpha);
         }
@@ -52,6 +62,20 @@
     public ExpandableOutlineView(Context context, AttributeSet attrs) {
         super(context, attrs);
         setOutlineProvider(mProvider);
+        initDimens();
+    }
+
+    private void initDimens() {
+        Resources res = getResources();
+        mShouldTranslateContents =
+                res.getBoolean(R.bool.config_translateNotificationContentsOnSwipe);
+        mOutlineRadius = res.getDimension(R.dimen.notification_shadow_radius);
+        setClipToOutline(res.getBoolean(R.bool.config_clipNotificationsToOutline));
+    }
+
+    public void onDensityOrFontScaleChanged() {
+        initDimens();
+        invalidateOutline();
     }
 
     @Override
@@ -108,8 +132,8 @@
     }
 
     /**
-     * @return whether the view currently needs an outline. This is usually false in case it doesn't
-     * have a background.
+     * @return Whether the view currently needs an outline. This is usually {@code false} in case
+     * it doesn't have a background.
      */
     protected boolean needsOutline() {
         if (isChildInGroup()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index 6a1f470..efe5e0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -24,8 +24,8 @@
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
-import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.stack.ExpandableViewState;
+import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.stack.StackScrollState;
 
 import java.util.ArrayList;
@@ -355,7 +355,7 @@
         if (mClipToActualHeight) {
             int top = getClipTopAmount();
             mClipRect.set(0, top, getWidth(), Math.max(getActualHeight() + getExtraBottomPadding()
-                                - mClipBottomAmount, top));
+                    - mClipBottomAmount, top));
             setClipBounds(mClipRect);
         } else {
             setClipBounds(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index b15f090..e12b574 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -23,6 +23,7 @@
 import android.animation.ValueAnimator;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.CanvasProperty;
 import android.graphics.Color;
@@ -55,7 +56,7 @@
 
     private final int mMinBackgroundRadius;
     private final Paint mCirclePaint;
-    private final int mInverseColor;
+    private final int mDarkIconColor;
     private final int mNormalColor;
     private final ArgbEvaluator mColorInterpolator;
     private final FlingAnimationUtils mFlingAnimationUtils;
@@ -126,17 +127,21 @@
     public KeyguardAffordanceView(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+        TypedArray a = context.obtainStyledAttributes(attrs, android.R.styleable.ImageView);
+
         mCirclePaint = new Paint();
         mCirclePaint.setAntiAlias(true);
         mCircleColor = 0xffffffff;
         mCirclePaint.setColor(mCircleColor);
 
-        mNormalColor = 0xffffffff;
-        mInverseColor = 0xff000000;
+        mNormalColor = a.getColor(android.R.styleable.ImageView_tint, 0xffffffff);
+        mDarkIconColor = 0xff000000;
         mMinBackgroundRadius = mContext.getResources().getDimensionPixelSize(
                 R.dimen.keyguard_affordance_min_background_radius);
         mColorInterpolator = new ArgbEvaluator();
         mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.3f);
+
+        a.recycle();
     }
 
     public void setImageDrawable(@Nullable Drawable drawable, boolean tint) {
@@ -177,7 +182,7 @@
         Drawable drawable = getDrawable().mutate();
         float alpha = mCircleRadius / mMinBackgroundRadius;
         alpha = Math.min(1.0f, alpha);
-        int color = (int) mColorInterpolator.evaluate(alpha, mNormalColor, mInverseColor);
+        int color = (int) mColorInterpolator.evaluate(alpha, mNormalColor, mDarkIconColor);
         drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 1691e135..74737c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar;
 
-import android.app.ActivityManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -66,21 +65,22 @@
     private static final long TRANSIENT_FP_ERROR_TIMEOUT = 1300;
 
     private final Context mContext;
-    private final ViewGroup mIndicationArea;
-    private final KeyguardIndicationTextView mTextView;
-    private final KeyguardIndicationTextView mDisclosure;
+    private ViewGroup mIndicationArea;
+    private KeyguardIndicationTextView mTextView;
+    private KeyguardIndicationTextView mDisclosure;
     private final UserManager mUserManager;
     private final IBatteryStats mBatteryInfo;
     private final SettableWakeLock mWakeLock;
 
     private final int mSlowThreshold;
     private final int mFastThreshold;
-    private final LockIcon mLockIcon;
+    private LockIcon mLockIcon;
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
 
     private String mRestingIndication;
     private String mTransientIndication;
     private int mTransientTextColor;
+    private int mInitialTextColor;
     private boolean mVisible;
 
     private boolean mPowerPluggedIn;
@@ -89,7 +89,7 @@
     private int mChargingWattage;
     private String mMessageToShowOnScreenOn;
 
-    private KeyguardUpdateMonitorCallback mUpdateMonitor;
+    private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
 
     private final DevicePolicyManager mDevicePolicyManager;
     private boolean mDozing;
@@ -115,6 +115,7 @@
         mIndicationArea = indicationArea;
         mTextView = (KeyguardIndicationTextView) indicationArea.findViewById(
                 R.id.keyguard_indication_text);
+        mInitialTextColor = mTextView != null ? mTextView.getCurrentTextColor() : Color.WHITE;
         mDisclosure = (KeyguardIndicationTextView) indicationArea.findViewById(
                 R.id.keyguard_indication_enterprise_disclosure);
         mLockIcon = lockIcon;
@@ -153,10 +154,10 @@
      * same instance.
      */
     protected KeyguardUpdateMonitorCallback getKeyguardCallback() {
-        if (mUpdateMonitor == null) {
-            mUpdateMonitor = new BaseKeyguardCallback();
+        if (mUpdateMonitorCallback == null) {
+            mUpdateMonitorCallback = new BaseKeyguardCallback();
         }
-        return mUpdateMonitor;
+        return mUpdateMonitorCallback;
     }
 
     private void updateDisclosure() {
@@ -203,6 +204,24 @@
     }
 
     /**
+     * Returns the indication text indicating that trust has been granted.
+     *
+     * @return {@code null} or an empty string if a trust indication text should not be shown.
+     */
+    protected String getTrustGrantedIndication() {
+        return null;
+    }
+
+    /**
+     * Returns the indication text indicating that trust is currently being managed.
+     *
+     * @return {@code null} or an empty string if a trust managed text should not be shown.
+     */
+    protected String getTrustManagedIndication() {
+        return null;
+    }
+
+    /**
      * Hides transient indication in {@param delayMs}.
      */
     public void hideTransientIndicationDelayed(long delayMs) {
@@ -221,7 +240,7 @@
      * Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
      */
     public void showTransientIndication(String transientIndication) {
-        showTransientIndication(transientIndication, Color.WHITE);
+        showTransientIndication(transientIndication, mInitialTextColor);
     }
 
     /**
@@ -250,45 +269,56 @@
         }
     }
 
-    private void updateIndication() {
+    protected final void updateIndication() {
         if (TextUtils.isEmpty(mTransientIndication)) {
             mWakeLock.setAcquired(false);
         }
 
         if (mVisible) {
-            // Walk down a precedence-ordered list of what should indication
+            // Walk down a precedence-ordered list of what indication
             // should be shown based on user or device state
             if (mDozing) {
                 // If we're dozing, never show a persistent indication.
                 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.setTextColor(Color.WHITE);
                     mTextView.switchIndication(mTransientIndication);
-                    mTextView.setTextColor(mTransientTextColor);
-
                 } else {
                     mTextView.switchIndication(null);
                 }
                 return;
             }
 
-            if (!mUserManager.isUserUnlocked(KeyguardUpdateMonitor.getCurrentUser())) {
+            KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+            int userId = KeyguardUpdateMonitor.getCurrentUser();
+            String trustGrantedIndication = getTrustGrantedIndication();
+            String trustManagedIndication = getTrustManagedIndication();
+            if (!mUserManager.isUserUnlocked(userId)) {
                 mTextView.switchIndication(com.android.internal.R.string.lockscreen_storage_locked);
-                mTextView.setTextColor(Color.WHITE);
-
+                mTextView.setTextColor(mInitialTextColor);
             } else if (!TextUtils.isEmpty(mTransientIndication)) {
                 mTextView.switchIndication(mTransientIndication);
                 mTextView.setTextColor(mTransientTextColor);
-
+            } else if (!TextUtils.isEmpty(trustGrantedIndication)
+                    && updateMonitor.getUserHasTrust(userId)) {
+                mTextView.switchIndication(trustGrantedIndication);
+                mTextView.setTextColor(mInitialTextColor);
             } else if (mPowerPluggedIn) {
                 String indication = computePowerIndication();
                 if (DEBUG_CHARGING_SPEED) {
                     indication += ",  " + (mChargingWattage / 1000) + " mW";
                 }
                 mTextView.switchIndication(indication);
-                mTextView.setTextColor(Color.WHITE);
-
+                mTextView.setTextColor(mInitialTextColor);
+            } else if (!TextUtils.isEmpty(trustManagedIndication)
+                    && updateMonitor.getUserTrustIsManaged(userId)
+                    && !updateMonitor.getUserHasTrust(userId)) {
+                mTextView.switchIndication(trustManagedIndication);
+                mTextView.setTextColor(mInitialTextColor);
             } else {
                 mTextView.switchIndication(mRestingIndication);
-                mTextView.setTextColor(Color.WHITE);
+                mTextView.setTextColor(mInitialTextColor);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index c432ea8..9e059c89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -1308,6 +1308,14 @@
         return header;
     }
 
+
+    public NotificationHeaderView getContractedNotificationHeader() {
+        if (mContractedChild != null) {
+            return mContractedWrapper.getNotificationHeader();
+        }
+        return null;
+    }
+
     public NotificationHeaderView getVisibleNotificationHeader() {
         NotificationViewWrapper wrapper = getVisibleWrapper(mVisibleType);
         return wrapper == null ? null : wrapper.getNotificationHeader();
@@ -1440,4 +1448,15 @@
         }
         return true;
     }
+
+    /**
+     * Should a single click be disallowed on this view when on the keyguard?
+     */
+    public boolean disallowSingleClick(float x, float y) {
+        NotificationViewWrapper visibleWrapper = getVisibleWrapper(getVisibleType());
+        if (visibleWrapper != null) {
+            return visibleWrapper.disallowSingleClick(x, y);
+        }
+        return false;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index e5b1afe..ef4f419 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -89,6 +89,7 @@
         private int mCachedContrastColor = COLOR_INVALID;
         private int mCachedContrastColorIsFor = COLOR_INVALID;
         private InflationTask mRunningTask = null;
+        private Throwable mDebugThrowable;
 
         public Entry(StatusBarNotification n) {
             this.key = n.getKey();
@@ -249,6 +250,19 @@
         public InflationTask getRunningTask() {
             return mRunningTask;
         }
+
+        /**
+         * Set a throwable that is used for debugging
+         *
+         * @param debugThrowable the throwable to save
+         */
+        public void setDebugThrowable(Throwable debugThrowable) {
+            mDebugThrowable = debugThrowable;
+        }
+
+        public Throwable getDebugThrowable() {
+            return mDebugThrowable;
+        }
     }
 
     private final ArrayMap<String, Entry> mEntries = new ArrayMap<>();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 23a67e2..54d622b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -329,4 +329,8 @@
     public boolean isExposed() {
         return mExposed;
     }
+
+    public boolean isLeavebehind() {
+        return mGutsContent != null && mGutsContent.isLeavebehind();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
index 7f95d48..4301817 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
@@ -267,9 +267,10 @@
             if (!mApply) {
                 return;
             }
-            NotificationHeaderView header = row.getNotificationHeader();
+            NotificationHeaderView header = row.getContractedNotificationHeader();
             if (header == null) {
-                mApply = false;
+                // No header found. We still consider this to be the same to avoid weird flickering
+                // when for example showing an undo notification
                 return;
             }
             Object childData = mExtractor == null ? null : mExtractor.extractData(row);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 427708b..1ffb3b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -154,9 +154,32 @@
             }
         }
 
+        boolean nonBlockable = false;
+        try {
+            final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
+            if (Utils.isSystemPackage(getResources(), pm, pkgInfo)) {
+                final int numChannels = mNotificationChannels.size();
+                for (int i = 0; i < numChannels; i++) {
+                    final NotificationChannel notificationChannel = mNotificationChannels.get(i);
+                    // If any of the system channels is not blockable, the bundle is nonblockable
+                    if (!notificationChannel.isBlockableSystem()) {
+                        nonBlockable = true;
+                        break;
+                    }
+                }
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            // unlikely.
+        }
+        if (nonBlockablePkgs != null) {
+            nonBlockable |= nonBlockablePkgs.contains(pkg);
+        }
+
         String channelsDescText;
         mNumChannelsView = findViewById(R.id.num_channels_desc);
-        if (mIsSingleDefaultChannel) {
+        if (nonBlockable) {
+            channelsDescText = mContext.getString(R.string.notification_unblockable_desc);
+        } else if (mIsSingleDefaultChannel) {
             channelsDescText = mContext.getString(R.string.notification_default_channel_desc);
         } else {
             switch (mNotificationChannels.size()) {
@@ -188,8 +211,9 @@
             // Multiple channels don't use a channel name for the title.
             channelNameText = mContext.getString(R.string.notification_num_channels,
                     mNotificationChannels.size());
-        } else if (mIsSingleDefaultChannel) {
-            // If this is the default channel, don't use our channel-specific text.
+        } else if (mIsSingleDefaultChannel || nonBlockable) {
+            // If this is the default channel or the app is unblockable,
+            // don't use our channel-specific text.
             channelNameText = mContext.getString(R.string.notification_header_default_channel);
         } else {
             channelNameText = mSingleNotificationChannel.getName();
@@ -218,19 +242,6 @@
             groupDividerView.setVisibility(View.GONE);
         }
 
-        boolean nonBlockable = false;
-        try {
-            final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
-            nonBlockable = Utils.isSystemPackage(getResources(), pm, pkgInfo)
-                    && (mSingleNotificationChannel == null
-                    || !mSingleNotificationChannel.isBlockableSystem());
-        } catch (PackageManager.NameNotFoundException e) {
-            // unlikely.
-        }
-        if (nonBlockablePkgs != null) {
-            nonBlockable |= nonBlockablePkgs.contains(pkg);
-        }
-
         bindButtons(nonBlockable);
 
         // Top-level importance group
@@ -246,12 +257,11 @@
                     (View view) -> {
                         onSettingsClick.onClick(view, mSingleNotificationChannel, appUidF);
                     });
-            if (numTotalChannels > 1) {
-                settingsButton.setText(R.string.notification_all_categories);
-            } else {
+            if (numTotalChannels <= 1 || nonBlockable) {
                 settingsButton.setText(R.string.notification_more_settings);
+            } else {
+                settingsButton.setText(R.string.notification_all_categories);
             }
-
         } else {
             settingsButton.setVisibility(View.GONE);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index c09da21..99b4b07 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -100,6 +100,7 @@
     private boolean mShouldShowMenu;
 
     private NotificationSwipeActionHelper mSwipeHelper;
+    private boolean mIsUserTouching;
 
     public NotificationMenuRow(Context context) {
         mContext = context;
@@ -129,7 +130,7 @@
     }
 
     @Override
-    public void createMenu(ViewGroup parent) {
+    public void createMenu(ViewGroup parent, StatusBarNotification sbn) {
         mParent = (ExpandableNotificationRow) parent;
         createMenuViews(true /* resetState */);
     }
@@ -150,7 +151,7 @@
     }
 
     @Override
-    public void onNotificationUpdated() {
+    public void onNotificationUpdated(StatusBarNotification sbn) {
         if (mMenuContainer == null) {
             // Menu hasn't been created yet, no need to do anything.
             return;
@@ -202,8 +203,11 @@
         } else {
             mIconsPlaced = false;
             setMenuLocation();
-            // If the # of items showing changed we need to update the snap position
-            showMenu(mParent, mOnLeft ? getSpaceForMenu() : -getSpaceForMenu(), 0 /* velocity */);
+            if (!mIsUserTouching) {
+                // If the # of items showing changed we need to update the snap position
+                showMenu(mParent, mOnLeft ? getSpaceForMenu() : -getSpaceForMenu(),
+                        0 /* velocity */);
+            }
         }
     }
 
@@ -233,6 +237,7 @@
                 mHandler.removeCallbacks(mCheckForDrag);
                 mCheckForDrag = null;
                 mPrevX = ev.getRawX();
+                mIsUserTouching = true;
                 break;
 
             case MotionEvent.ACTION_MOVE:
@@ -265,7 +270,12 @@
                 break;
 
             case MotionEvent.ACTION_UP:
+                mIsUserTouching = false;
                 return handleUpEvent(ev, view, velocity);
+            case MotionEvent.ACTION_CANCEL:
+                mIsUserTouching = false;
+                cancelDrag();
+                return false;
         }
         return false;
     }
@@ -354,23 +364,24 @@
     }
 
     private void snapBack(View animView, float velocity) {
-        if (mFadeAnimator != null) {
-            mFadeAnimator.cancel();
-        }
-        mHandler.removeCallbacks(mCheckForDrag);
+        cancelDrag();
         mMenuSnappedTo = false;
         mSnapping = true;
         mSwipeHelper.snap(animView, 0 /* leftTarget */, velocity);
     }
 
     private void dismiss(View animView, float velocity) {
+        cancelDrag();
+        mMenuSnappedTo = false;
+        mDismissing = true;
+        mSwipeHelper.dismiss(animView, velocity);
+    }
+
+    private void cancelDrag() {
         if (mFadeAnimator != null) {
             mFadeAnimator.cancel();
         }
         mHandler.removeCallbacks(mCheckForDrag);
-        mMenuSnappedTo = false;
-        mDismissing = true;
-        mSwipeHelper.dismiss(animView, velocity);
     }
 
     /**
@@ -417,10 +428,10 @@
 
     @Override
     public void onHeightUpdate() {
-        if (mParent == null || mMenuItems.size() == 0) {
+        if (mParent == null || mMenuItems.size() == 0 || mMenuContainer == null) {
             return;
         }
-        int parentHeight = mParent.getCollapsedHeight();
+        int parentHeight = mParent.getActualHeight();
         float translationY;
         if (parentHeight < mVertSpaceForIcons) {
             translationY = (parentHeight / 2) - (mHorizSpaceForIcon / 2);
@@ -477,7 +488,7 @@
 
     private void setMenuLocation() {
         boolean showOnLeft = mTranslation > 0;
-        if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping
+        if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping || mMenuContainer == null
                 || !mMenuContainer.isAttachedToWindow()) {
             // Do nothing
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 1a99636..30cdb9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -16,8 +16,12 @@
 
 package com.android.systemui.statusbar;
 
+import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE;
+import static com.android.systemui.statusbar.phone.NotificationIconContainer.OVERFLOW_EARLY_AMOUNT;
+
 import android.content.Context;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.os.SystemProperties;
 import android.util.AttributeSet;
 import android.view.View;
@@ -66,6 +70,7 @@
     private boolean mHasItemsInStableShelf;
     private NotificationIconContainer mCollapsedIcons;
     private int mScrollFastThreshold;
+    private int mIconSize;
     private int mStatusBarState;
     private float mMaxShelfEnd;
     private int mRelativeOffset;
@@ -73,6 +78,7 @@
     private float mOpenedAmount;
     private boolean mNoAnimationsInThisFrame;
     private boolean mAnimationsEnabled = true;
+    private boolean mShowNotificationShelf;
 
     public NotificationShelf(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -101,21 +107,25 @@
     }
 
     private void initDimens() {
-        mIconAppearTopPadding = getResources().getDimensionPixelSize(
-                R.dimen.notification_icon_appear_padding);
-        mStatusBarHeight = getResources().getDimensionPixelOffset(R.dimen.status_bar_height);
-        mStatusBarPaddingStart = getResources().getDimensionPixelOffset(
-                R.dimen.status_bar_padding_start);
-        mPaddingBetweenElements = getResources().getDimensionPixelSize(
-                R.dimen.notification_divider_height);
+        Resources res = getResources();
+        mIconAppearTopPadding = res.getDimensionPixelSize(R.dimen.notification_icon_appear_padding);
+        mStatusBarHeight = res.getDimensionPixelOffset(R.dimen.status_bar_height);
+        mStatusBarPaddingStart = res.getDimensionPixelOffset(R.dimen.status_bar_padding_start);
+        mPaddingBetweenElements = res.getDimensionPixelSize(R.dimen.notification_divider_height);
+
         ViewGroup.LayoutParams layoutParams = getLayoutParams();
-        layoutParams.height = getResources().getDimensionPixelOffset(
-                R.dimen.notification_shelf_height);
+        layoutParams.height = res.getDimensionPixelOffset(R.dimen.notification_shelf_height);
         setLayoutParams(layoutParams);
-        int padding = getResources().getDimensionPixelOffset(R.dimen.shelf_icon_container_padding);
+
+        int padding = res.getDimensionPixelOffset(R.dimen.shelf_icon_container_padding);
         mShelfIcons.setPadding(padding, 0, padding, 0);
-        mScrollFastThreshold = getResources().getDimensionPixelOffset(
-                R.dimen.scroll_fast_threshold);
+        mScrollFastThreshold = res.getDimensionPixelOffset(R.dimen.scroll_fast_threshold);
+        mShowNotificationShelf = res.getBoolean(R.bool.config_showNotificationShelf);
+        mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
+
+        if (!mShowNotificationShelf) {
+            setVisibility(GONE);
+        }
     }
 
     @Override
@@ -150,7 +160,7 @@
     public void updateState(StackScrollState resultState,
             AmbientState ambientState) {
         View lastView = ambientState.getLastVisibleBackgroundChild();
-        if (lastView != null) {
+        if (mShowNotificationShelf && lastView != null) {
             float maxShelfEnd = ambientState.getInnerHeight() + ambientState.getTopPadding()
                     + ambientState.getStackTranslation();
             ExpandableViewState lastViewState = resultState.getViewStateForView(lastView);
@@ -174,7 +184,8 @@
                 mShelfState.notGoneIndex = Math.min(mShelfState.notGoneIndex, mNotGoneIndex);
             }
             mShelfState.hasItemsInStableShelf = lastViewState.inShelf;
-            mShelfState.hidden = !mAmbientState.isShadeExpanded();
+            mShelfState.hidden = !mAmbientState.isShadeExpanded()
+                    || mAmbientState.isQsCustomizerShowing();
             mShelfState.maxShelfEnd = maxShelfEnd;
         } else {
             mShelfState.hidden = true;
@@ -188,6 +199,11 @@
      * the icons from the notification area into the shelf.
      */
     public void updateAppearance() {
+        // If the shelf should not be shown, then there is no need to update anything.
+        if (!mShowNotificationShelf) {
+            return;
+        }
+
         mShelfIcons.resetViewStates();
         float shelfStart = getTranslationY();
         float numViewsInShelf = 0.0f;
@@ -230,7 +246,7 @@
             boolean aboveShelf = ViewState.getFinalTranslationZ(row) > baseZHeight;
             boolean isLastChild = child == lastChild;
             float rowTranslationY = row.getTranslationY();
-            if (isLastChild || aboveShelf || backgroundForceHidden) {
+            if ((isLastChild && !child.isInShelf()) || aboveShelf || backgroundForceHidden) {
                 notificationClipEnd = shelfStart + getIntrinsicHeight();
             } else {
                 notificationClipEnd = shelfStart - mPaddingBetweenElements;
@@ -284,7 +300,8 @@
     private void updateNotificationClipHeight(ExpandableNotificationRow row,
             float notificationClipEnd) {
         float viewEnd = row.getTranslationY() + row.getActualHeight();
-        boolean isPinned = row.isPinned() || row.isHeadsUpAnimatingAway();
+        boolean isPinned = (row.isPinned() || row.isHeadsUpAnimatingAway())
+                && !mAmbientState.isDozingAndNotPulsing(row);
         if (viewEnd > notificationClipEnd
                 && (mAmbientState.isShadeExpanded() || !isPinned)) {
             int clipBottomAmount = (int) (viewEnd - notificationClipEnd);
@@ -304,26 +321,65 @@
     private float updateIconAppearance(ExpandableNotificationRow row, float expandAmount,
             boolean scrolling, boolean scrollingFast, boolean expandingAnimated,
             boolean isLastChild) {
+        StatusBarIconView icon = row.getEntry().expandedIcon;
+        NotificationIconContainer.IconState iconState = getIconState(icon);
+        if (iconState == null) {
+            return 0.0f;
+        }
+
         // Let calculate how much the view is in the shelf
         float viewStart = row.getTranslationY();
         int fullHeight = row.getActualHeight() + mPaddingBetweenElements;
         float iconTransformDistance = getIntrinsicHeight() * 1.5f;
         iconTransformDistance *= NotificationUtils.interpolate(1.f, 1.5f, expandAmount);
+        iconTransformDistance = Math.min(iconTransformDistance, fullHeight);
         if (isLastChild) {
             fullHeight = Math.min(fullHeight, row.getMinHeight() - getIntrinsicHeight());
             iconTransformDistance = Math.min(iconTransformDistance, row.getMinHeight()
                     - getIntrinsicHeight());
         }
         float viewEnd = viewStart + fullHeight;
+        if (expandingAnimated && mAmbientState.getScrollY() == 0
+                && !mAmbientState.isOnKeyguard() && !iconState.isLastExpandIcon) {
+            // We are expanding animated. Because we switch to a linear interpolation in this case,
+            // the last icon may be stuck in between the shelf position and the notification
+            // position, which looks pretty bad. We therefore optimize this case by applying a
+            // shorter transition such that the icon is either fully in the notification or we clamp
+            // it into the shelf if it's close enough.
+            // We need to persist this, since after the expansion, the behavior should still be the
+            // same.
+            float position = mAmbientState.getIntrinsicPadding()
+                    + mHostLayout.getPositionInLinearLayout(row);
+            int maxShelfStart = mMaxLayoutHeight - getIntrinsicHeight();
+            if (position < maxShelfStart && position + row.getIntrinsicHeight() >= maxShelfStart
+                    && row.getTranslationY() < position) {
+                iconState.isLastExpandIcon = true;
+                iconState.customTransformHeight = NO_VALUE;
+                // Let's check if we're close enough to snap into the shelf
+                boolean forceInShelf = mMaxLayoutHeight - getIntrinsicHeight() - position
+                        < getIntrinsicHeight();
+                if (!forceInShelf) {
+                    // We are overlapping the shelf but not enough, so the icon needs to be
+                    // repositioned
+                    iconState.customTransformHeight = (int) (mMaxLayoutHeight
+                            - getIntrinsicHeight() - position);
+                }
+            }
+        }
         float fullTransitionAmount;
         float iconTransitionAmount;
         float shelfStart = getTranslationY();
+        if (iconState.hasCustomTransformHeight()) {
+            fullHeight = iconState.customTransformHeight;
+            iconTransformDistance = iconState.customTransformHeight;
+        }
+        boolean fullyInOrOut = true;
         if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || row.isInShelf())
                 && (mAmbientState.isShadeExpanded()
                         || (!row.isPinned() && !row.isHeadsUpAnimatingAway()))) {
             if (viewStart < shelfStart) {
-
                 float fullAmount = (shelfStart - viewStart) / fullHeight;
+                fullAmount = Math.min(1.0f, fullAmount);
                 float interpolatedAmount =  Interpolators.ACCELERATE_DECELERATE.getInterpolation(
                         fullAmount);
                 interpolatedAmount = NotificationUtils.interpolate(
@@ -333,7 +389,7 @@
                 iconTransitionAmount = (shelfStart - viewStart) / iconTransformDistance;
                 iconTransitionAmount = Math.min(1.0f, iconTransitionAmount);
                 iconTransitionAmount = 1.0f - iconTransitionAmount;
-
+                fullyInOrOut = false;
             } else {
                 fullTransitionAmount = 1.0f;
                 iconTransitionAmount = 1.0f;
@@ -342,6 +398,10 @@
             fullTransitionAmount = 0.0f;
             iconTransitionAmount = 0.0f;
         }
+        if (fullyInOrOut && !expandingAnimated && iconState.isLastExpandIcon) {
+            iconState.isLastExpandIcon = false;
+            iconState.customTransformHeight = NO_VALUE;
+        }
         updateIconPositioning(row, iconTransitionAmount, fullTransitionAmount,
                 iconTransformDistance, scrolling, scrollingFast, expandingAnimated, isLastChild);
         return fullTransitionAmount;
@@ -355,9 +415,10 @@
         if (iconState == null) {
             return;
         }
+        boolean forceInShelf = iconState.isLastExpandIcon && !iconState.hasCustomTransformHeight();
         float clampedAmount = iconTransitionAmount > 0.5f ? 1.0f : 0.0f;
         if (clampedAmount == fullTransitionAmount) {
-            iconState.noAnimations = scrollingFast || expandingAnimated;
+            iconState.noAnimations = (scrollingFast || expandingAnimated) && !forceInShelf;
             iconState.useFullTransitionAmount = iconState.noAnimations
                 || (!ICON_ANMATIONS_WHILE_SCROLLING && fullTransitionAmount == 0.0f && scrolling);
             iconState.useLinearTransitionAmount = !ICON_ANMATIONS_WHILE_SCROLLING
@@ -365,12 +426,18 @@
             iconState.translateContent = mMaxLayoutHeight - getTranslationY()
                     - getIntrinsicHeight() > 0;
         }
-        if (scrollingFast || (expandingAnimated && iconState.useFullTransitionAmount
-                && !ViewState.isAnimatingY(icon))) {
+        if (!forceInShelf && (scrollingFast || (expandingAnimated
+                && iconState.useFullTransitionAmount && !ViewState.isAnimatingY(icon)))) {
             iconState.cancelAnimations(icon);
             iconState.useFullTransitionAmount = true;
             iconState.noAnimations = true;
         }
+        if (iconState.hasCustomTransformHeight()) {
+            iconState.useFullTransitionAmount = true;
+        }
+        if (iconState.isLastExpandIcon) {
+            iconState.translateContent = false;
+        }
         float transitionAmount;
         if (isLastChild || !USE_ANIMATIONS_WHEN_OPENING || iconState.useFullTransitionAmount
                 || iconState.useLinearTransitionAmount) {
@@ -386,7 +453,7 @@
                 ? fullTransitionAmount
                 : transitionAmount;
         iconState.clampedAppearAmount = clampedAmount;
-        float contentTransformationAmount = !row.isAboveShelf()
+        float contentTransformationAmount = !mAmbientState.isAboveShelf(row)
                     && (isLastChild || iconState.translateContent)
                 ? iconTransitionAmount
                 : 0.0f;
@@ -421,12 +488,12 @@
         }
         notificationIconPosition += iconTopPadding;
         float shelfIconPosition = getTranslationY() + icon.getTop();
-        shelfIconPosition += ((1.0f - icon.getIconScale()) * icon.getHeight()) / 2.0f;
+        shelfIconPosition += (icon.getHeight() - icon.getIconScale() * mIconSize) / 2.0f;
         float iconYTranslation = NotificationUtils.interpolate(
                 notificationIconPosition - shelfIconPosition,
                 0,
                 transitionAmount);
-        float shelfIconSize = icon.getHeight() * icon.getIconScale();
+        float shelfIconSize = mIconSize * icon.getIconScale();
         float alpha = 1.0f;
         boolean noIcon = !row.isShowingIcon();
         if (noIcon) {
@@ -438,9 +505,14 @@
         float newSize = NotificationUtils.interpolate(notificationIconSize, shelfIconSize,
                 transitionAmount);
         if (iconState != null) {
-            iconState.scaleX = newSize / icon.getHeight() / icon.getIconScale();
+            iconState.scaleX = newSize / shelfIconSize;
             iconState.scaleY = iconState.scaleX;
             iconState.hidden = transitionAmount == 0.0f && !iconState.isAnimating(icon);
+            boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf();
+            if (isAppearing) {
+                iconState.hidden = true;
+                iconState.iconAppearAmount = 0.0f;
+            }
             iconState.alpha = alpha;
             iconState.yTranslation = iconYTranslation;
             if (stayingInShelf) {
@@ -450,7 +522,7 @@
                 iconState.scaleY = 1.0f;
                 iconState.hidden = false;
             }
-            if (row.isAboveShelf() || (!row.isInShelf() && (isLastChild && row.areGutsExposed()
+            if (mAmbientState.isAboveShelf(row) || (!row.isInShelf() && (isLastChild && row.areGutsExposed()
                     || row.getTranslationZ() > mAmbientState.getBaseZHeight()))) {
                 iconState.hidden = true;
             }
@@ -537,8 +609,7 @@
         if (!hasOverflow) {
             // we have to ensure that adding the low priority notification won't lead to an
             // overflow
-            collapsedPadding -= (1.0f + NotificationIconContainer.OVERFLOW_EARLY_AMOUNT)
-                    * mCollapsedIcons.getIconSize();
+            collapsedPadding -= (1.0f + OVERFLOW_EARLY_AMOUNT) * mCollapsedIcons.getIconSize();
         }
         float padding = NotificationUtils.interpolate(collapsedPadding,
                 mShelfIcons.getPaddingEnd(),
@@ -640,6 +711,10 @@
         updateRelativeOffset();
     }
 
+    public void setDarkOffsetX(int offsetX) {
+        mShelfIcons.setDarkOffsetX(offsetX);
+    }
+
     private class ShelfState extends ExpandableViewState {
         private float openedAmount;
         private boolean hasItemsInStableShelf;
@@ -647,6 +722,10 @@
 
         @Override
         public void applyToView(View view) {
+            if (!mShowNotificationShelf) {
+                return;
+            }
+
             super.applyToView(view);
             setMaxShelfEnd(maxShelfEnd);
             setOpenedAmount(openedAmount);
@@ -657,6 +736,10 @@
 
         @Override
         public void animateTo(View child, AnimationProperties properties) {
+            if (!mShowNotificationShelf) {
+                return;
+            }
+
             super.animateTo(child, properties);
             setMaxShelfEnd(maxShelfEnd);
             setOpenedAmount(openedAmount);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
index 8af1628..c45ca54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
@@ -21,11 +21,14 @@
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Typeface;
+import android.os.Bundle;
 import android.service.notification.SnoozeCriterion;
 import android.service.notification.StatusBarNotification;
 import android.text.SpannableString;
@@ -35,6 +38,9 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -45,6 +51,10 @@
 public class NotificationSnooze extends LinearLayout
         implements NotificationGuts.GutsContent, View.OnClickListener {
 
+    /**
+     * If this changes more number increases, more assistant action resId's should be defined for
+     * accessibility purposes, see {@link #setSnoozeOptions(List)}
+     */
     private static final int MAX_ASSISTANT_SUGGESTIONS = 1;
     private NotificationGuts mGutsContainer;
     private NotificationSwipeActionHelper mSnoozeListener;
@@ -79,16 +89,60 @@
         mDivider = findViewById(R.id.divider);
         mDivider.setAlpha(0f);
         mSnoozeOptionContainer = (ViewGroup) findViewById(R.id.snooze_options);
+        mSnoozeOptionContainer.setVisibility(View.INVISIBLE);
         mSnoozeOptionContainer.setAlpha(0f);
 
         // Create the different options based on list
         mSnoozeOptions = getDefaultSnoozeOptions();
         createOptionViews();
 
-        // Default to first option in list
         setSelected(mDefaultOption);
     }
 
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        if (mGutsContainer != null && mGutsContainer.isExposed()) {
+            if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+                event.getText().add(mSelectedOptionText.getText());
+            }
+        }
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.addAction(new AccessibilityAction(R.id.action_snooze_undo,
+                getResources().getString(R.string.snooze_undo)));
+        int count = mSnoozeOptions.size();
+        for (int i = 0; i < count; i++) {
+            AccessibilityAction action = mSnoozeOptions.get(i).getAccessibilityAction();
+            if (action != null) {
+                info.addAction(action);
+            }
+        }
+    }
+
+    @Override
+    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
+        if (super.performAccessibilityActionInternal(action, arguments)) {
+            return true;
+        }
+        if (action == R.id.action_snooze_undo) {
+            undoSnooze(mUndoButton);
+            return true;
+        }
+        for (int i = 0; i < mSnoozeOptions.size(); i++) {
+            SnoozeOption so = mSnoozeOptions.get(i);
+            if (so.getAccessibilityAction() != null
+                    && so.getAccessibilityAction().getId() == action) {
+                setSelected(so);
+                return true;
+            }
+        }
+        return false;
+    }
+
     public void setSnoozeOptions(final List<SnoozeCriterion> snoozeList) {
         if (snoozeList == null) {
             return;
@@ -98,7 +152,10 @@
         final int count = Math.min(MAX_ASSISTANT_SUGGESTIONS, snoozeList.size());
         for (int i = 0; i < count; i++) {
             SnoozeCriterion sc = snoozeList.get(i);
-            mSnoozeOptions.add(new SnoozeOption(sc, 0, sc.getExplanation(), sc.getConfirmation()));
+            AccessibilityAction action = new AccessibilityAction(
+                    R.id.action_snooze_assistant_suggestion_1, sc.getExplanation());
+            mSnoozeOptions.add(new NotificationSnoozeOption(sc, 0, sc.getExplanation(),
+                    sc.getConfirmation(), action));
         }
         createOptionViews();
     }
@@ -117,22 +174,30 @@
 
     private ArrayList<SnoozeOption> getDefaultSnoozeOptions() {
         ArrayList<SnoozeOption> options = new ArrayList<>();
-        options.add(createOption(R.string.snooze_option_15_min, 15));
-        options.add(createOption(R.string.snooze_option_30_min, 30));
-        mDefaultOption = createOption(R.string.snooze_option_1_hour, 60);
+
+        options.add(createOption(15 /* minutes */, R.id.action_snooze_15_min));
+        options.add(createOption(30 /* minutes */, R.id.action_snooze_30_min));
+        mDefaultOption = createOption(60 /* minutes */, R.id.action_snooze_1_hour);
         options.add(mDefaultOption);
-        options.add(createOption(R.string.snooze_option_2_hour, 60 * 2));
+        options.add(createOption(60 * 2 /* minutes */, R.id.action_snooze_2_hours));
         return options;
     }
 
-    private SnoozeOption createOption(int descriptionResId, int minutes) {
+    private SnoozeOption createOption(int minutes, int accessibilityActionId) {
         Resources res = getResources();
-        final String description = res.getString(descriptionResId);
+        boolean showInHours = minutes >= 60;
+        int pluralResId = showInHours
+                ? R.plurals.snoozeHourOptions
+                : R.plurals.snoozeMinuteOptions;
+        int count = showInHours ? (minutes / 60) : minutes;
+        String description = res.getQuantityString(pluralResId, count, count);
         String resultText = String.format(res.getString(R.string.snoozed_for_time), description);
         SpannableString string = new SpannableString(resultText);
         string.setSpan(new StyleSpan(Typeface.BOLD),
                 resultText.length() - description.length(), resultText.length(), 0 /* flags */);
-        return new SnoozeOption(null, minutes, res.getString(descriptionResId), string);
+        AccessibilityAction action = new AccessibilityAction(accessibilityActionId, description);
+        return new NotificationSnoozeOption(null, minutes, description, string,
+                action);
     }
 
     private void createOptionViews() {
@@ -144,7 +209,7 @@
             TextView tv = (TextView) inflater.inflate(R.layout.notification_snooze_option,
                     mSnoozeOptionContainer, false);
             mSnoozeOptionContainer.addView(tv);
-            tv.setText(option.description);
+            tv.setText(option.getDescription());
             tv.setTag(option);
             tv.setOnClickListener(this);
         }
@@ -179,18 +244,36 @@
                 mDivider.getAlpha(), show ? 1f : 0f);
         ObjectAnimator optionAnim = ObjectAnimator.ofFloat(mSnoozeOptionContainer, View.ALPHA,
                 mSnoozeOptionContainer.getAlpha(), show ? 1f : 0f);
+        mSnoozeOptionContainer.setVisibility(View.VISIBLE);
         mExpandAnimation = new AnimatorSet();
         mExpandAnimation.playTogether(dividerAnim, optionAnim);
         mExpandAnimation.setDuration(150);
         mExpandAnimation.setInterpolator(show ? Interpolators.ALPHA_IN : Interpolators.ALPHA_OUT);
+        mExpandAnimation.addListener(new AnimatorListenerAdapter() {
+            boolean cancelled = false;
+
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                cancelled = true;
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (!show && !cancelled) {
+                    mSnoozeOptionContainer.setVisibility(View.INVISIBLE);
+                    mSnoozeOptionContainer.setAlpha(0f);
+                }
+            }
+        });
         mExpandAnimation.start();
     }
 
     private void setSelected(SnoozeOption option) {
         mSelectedOption = option;
-        mSelectedOptionText.setText(option.confirmation);
+        mSelectedOptionText.setText(option.getConfirmation());
         showSnoozeOptions(false);
         hideSelectedOption();
+        sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
     }
 
     @Override
@@ -207,20 +290,24 @@
             showSnoozeOptions(!mExpanded);
         } else {
             // Undo snooze was selected
-            mSelectedOption = null;
-            int[] parentLoc = new int[2];
-            int[] targetLoc = new int[2];
-            mGutsContainer.getLocationOnScreen(parentLoc);
-            v.getLocationOnScreen(targetLoc);
-            final int centerX = v.getWidth() / 2;
-            final int centerY = v.getHeight() / 2;
-            final int x = targetLoc[0] - parentLoc[0] + centerX;
-            final int y = targetLoc[1] - parentLoc[1] + centerY;
-            showSnoozeOptions(false);
-            mGutsContainer.closeControls(x, y, false /* save */, false /* force */);
+            undoSnooze(v);
         }
     }
 
+    private void undoSnooze(View v) {
+        mSelectedOption = null;
+        int[] parentLoc = new int[2];
+        int[] targetLoc = new int[2];
+        mGutsContainer.getLocationOnScreen(parentLoc);
+        v.getLocationOnScreen(targetLoc);
+        final int centerX = v.getWidth() / 2;
+        final int centerY = v.getHeight() / 2;
+        final int x = targetLoc[0] - parentLoc[0] + centerX;
+        final int y = targetLoc[1] - parentLoc[1] + centerY;
+        showSnoozeOptions(false);
+        mGutsContainer.closeControls(x, y, false /* save */, false /* force */);
+    }
+
     @Override
     public int getActualHeight() {
         return mExpanded ? getHeight() : mCollapsedHeight;
@@ -265,4 +352,48 @@
     public boolean isLeavebehind() {
         return true;
     }
+
+    public class NotificationSnoozeOption implements SnoozeOption {
+        private SnoozeCriterion mCriterion;
+        private int mMinutesToSnoozeFor;
+        private CharSequence mDescription;
+        private CharSequence mConfirmation;
+        private AccessibilityAction mAction;
+
+        public NotificationSnoozeOption(SnoozeCriterion sc, int minToSnoozeFor,
+                CharSequence description,
+                CharSequence confirmation, AccessibilityAction action) {
+            mCriterion = sc;
+            mMinutesToSnoozeFor = minToSnoozeFor;
+            mDescription = description;
+            mConfirmation = confirmation;
+            mAction = action;
+        }
+
+        @Override
+        public SnoozeCriterion getSnoozeCriterion() {
+            return mCriterion;
+        }
+
+        @Override
+        public CharSequence getDescription() {
+            return mDescription;
+        }
+
+        @Override
+        public CharSequence getConfirmation() {
+            return mConfirmation;
+        }
+
+        @Override
+        public int getMinutesToSnoozeFor() {
+            return mMinutesToSnoozeFor;
+        }
+
+        @Override
+        public AccessibilityAction getAccessibilityAction() {
+            return mAction;
+        }
+
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
index f9d0cd6..a53e348 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
@@ -19,39 +19,51 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
+import android.annotation.NonNull;
 import android.content.Context;
-import android.content.res.TypedArray;
+import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.Paint;
+import android.graphics.Point;
 import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.support.v4.graphics.ColorUtils;
 import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Display;
 import android.view.View;
+import android.view.WindowManager;
 import android.view.animation.Interpolator;
-import com.android.systemui.R;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.drawable.GradientDrawable;
+import com.android.systemui.Dependency;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 
 /**
  * A view which can draw a scrim
  */
-public class ScrimView extends View
-{
-    private final Paint mPaint = new Paint();
-    private int mScrimColor;
-    private boolean mIsEmpty = true;
+public class ScrimView extends View implements ConfigurationController.ConfigurationListener {
+    private static final String TAG = "ScrimView";
+    private final ColorExtractor.GradientColors mColors;
     private boolean mDrawAsSrc;
     private float mViewAlpha = 1.0f;
     private ValueAnimator mAlphaAnimator;
     private Rect mExcludedRect = new Rect();
     private boolean mHasExcludedArea;
-    private ValueAnimator.AnimatorUpdateListener mAlphaUpdateListener
-            = new ValueAnimator.AnimatorUpdateListener() {
-        @Override
-        public void onAnimationUpdate(ValueAnimator animation) {
-            mViewAlpha = (float) animation.getAnimatedValue();
-            invalidate();
+    private Drawable mDrawable;
+    private PorterDuffColorFilter mColorFilter;
+    private int mTintColor;
+    private ValueAnimator.AnimatorUpdateListener mAlphaUpdateListener = animation -> {
+        if (mDrawable == null) {
+            Log.w(TAG, "Trying to animate null drawable");
+            return;
         }
+        mDrawable.setAlpha((int) (255 * (float) animation.getAnimatedValue()));
     };
     private AnimatorListenerAdapter mClearAnimatorListener = new AnimatorListenerAdapter() {
         @Override
@@ -76,72 +88,163 @@
     public ScrimView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
 
-        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ScrimView);
+        mDrawable = new GradientDrawable(context);
+        mDrawable.setCallback(this);
+        mColors = new ColorExtractor.GradientColors();
+        updateScreenSize();
+        updateColorWithTint(false);
+    }
 
-        try {
-            mScrimColor = ta.getColor(R.styleable.ScrimView_scrimColor, Color.BLACK);
-        } finally {
-            ta.recycle();
-        }
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        // We need to know about configuration changes to update the gradient size
+        // since it's independent from view bounds.
+        ConfigurationController config = Dependency.get(ConfigurationController.class);
+        config.addCallback(this);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        ConfigurationController config = Dependency.get(ConfigurationController.class);
+        config.removeCallback(this);
     }
 
     @Override
     protected void onDraw(Canvas canvas) {
-        if (mDrawAsSrc || (!mIsEmpty && mViewAlpha > 0f)) {
-            PorterDuff.Mode mode = mDrawAsSrc ? PorterDuff.Mode.SRC : PorterDuff.Mode.SRC_OVER;
-            int color = getScrimColorWithAlpha();
+        if (mDrawAsSrc || mDrawable.getAlpha() > 0) {
             if (!mHasExcludedArea) {
-                canvas.drawColor(color, mode);
+                mDrawable.draw(canvas);
             } else {
-                mPaint.setColor(color);
                 if (mExcludedRect.top > 0) {
-                    canvas.drawRect(0, 0, getWidth(), mExcludedRect.top, mPaint);
+                    canvas.save();
+                    canvas.clipRect(0, 0, getWidth(), mExcludedRect.top);
+                    mDrawable.draw(canvas);
+                    canvas.restore();
                 }
                 if (mExcludedRect.left > 0) {
-                    canvas.drawRect(0,  mExcludedRect.top, mExcludedRect.left, mExcludedRect.bottom,
-                            mPaint);
+                    canvas.save();
+                    canvas.clipRect(0, mExcludedRect.top, mExcludedRect.left,
+                            mExcludedRect.bottom);
+                    mDrawable.draw(canvas);
+                    canvas.restore();
                 }
                 if (mExcludedRect.right < getWidth()) {
-                    canvas.drawRect(mExcludedRect.right,
-                            mExcludedRect.top,
-                            getWidth(),
-                            mExcludedRect.bottom,
-                            mPaint);
+                    canvas.save();
+                    canvas.clipRect(mExcludedRect.right, mExcludedRect.top, getWidth(),
+                            mExcludedRect.bottom);
+                    mDrawable.draw(canvas);
+                    canvas.restore();
                 }
                 if (mExcludedRect.bottom < getHeight()) {
-                    canvas.drawRect(0,  mExcludedRect.bottom, getWidth(), getHeight(), mPaint);
+                    canvas.save();
+                    canvas.clipRect(0, mExcludedRect.bottom, getWidth(), getHeight());
+                    mDrawable.draw(canvas);
+                    canvas.restore();
                 }
             }
         }
     }
 
-    public int getScrimColorWithAlpha() {
-        int color = mScrimColor;
-        color = Color.argb((int) (Color.alpha(color) * mViewAlpha), Color.red(color),
-                Color.green(color), Color.blue(color));
-        return color;
+    public void setDrawable(Drawable drawable) {
+        mDrawable = drawable;
+        mDrawable.setCallback(this);
+        mDrawable.setBounds(getLeft(), getTop(), getRight(), getBottom());
+        mDrawable.setAlpha((int) (255 * mViewAlpha));
+        setDrawAsSrc(mDrawAsSrc);
+        updateScreenSize();
+        invalidate();
+    }
+
+    @Override
+    public void invalidateDrawable(@NonNull Drawable drawable) {
+        super.invalidateDrawable(drawable);
+        if (drawable == mDrawable) {
+            invalidate();
+        }
     }
 
     public void setDrawAsSrc(boolean asSrc) {
         mDrawAsSrc = asSrc;
-        mPaint.setXfermode(new PorterDuffXfermode(mDrawAsSrc ? PorterDuff.Mode.SRC
-                : PorterDuff.Mode.SRC_OVER));
-        invalidate();
+        PorterDuff.Mode mode = asSrc ? PorterDuff.Mode.SRC : PorterDuff.Mode.SRC_OVER;
+        mDrawable.setXfermode(new PorterDuffXfermode(mode));
     }
 
-    public void setScrimColor(int color) {
-        if (color != mScrimColor) {
-            mIsEmpty = Color.alpha(color) == 0;
-            mScrimColor = color;
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        if (changed) {
+            mDrawable.setBounds(left, top, right, bottom);
             invalidate();
-            if (mChangeRunnable != null) {
-                mChangeRunnable.run();
-            }
         }
     }
 
-    public int getScrimColor() {
-        return mScrimColor;
+    public void setColors(@NonNull ColorExtractor.GradientColors colors) {
+        setColors(colors, false);
+    }
+
+    public void setColors(@NonNull ColorExtractor.GradientColors colors, boolean animated) {
+        if (colors == null) {
+            throw new IllegalArgumentException("Colors cannot be null");
+        }
+        if (mColors.equals(colors)) {
+            return;
+        }
+        mColors.set(colors);
+        updateColorWithTint(animated);
+    }
+
+    @VisibleForTesting
+    Drawable getDrawable() {
+        return mDrawable;
+    }
+
+    public ColorExtractor.GradientColors getColors() {
+        return mColors;
+    }
+
+    public void setTint(int color) {
+        setTint(color, false);
+    }
+
+    public void setTint(int color, boolean animated) {
+        if (mTintColor == color) {
+            return;
+        }
+        mTintColor = color;
+        updateColorWithTint(animated);
+    }
+
+    private void updateColorWithTint(boolean animated) {
+        if (mDrawable instanceof GradientDrawable) {
+            // Optimization to blend colors and avoid a color filter
+            GradientDrawable drawable = (GradientDrawable) mDrawable;
+            float tintAmount = Color.alpha(mTintColor) / 255f;
+            int mainTinted = ColorUtils.blendARGB(mColors.getMainColor(), mTintColor,
+                    tintAmount);
+            int secondaryTinted = ColorUtils.blendARGB(mColors.getSecondaryColor(), mTintColor,
+                    tintAmount);
+            drawable.setColors(mainTinted, secondaryTinted, animated);
+        } else {
+            if (mColorFilter == null) {
+                mColorFilter = new PorterDuffColorFilter(mTintColor, PorterDuff.Mode.SRC_OVER);
+            } else {
+                mColorFilter.setColor(mTintColor);
+            }
+            mDrawable.setColorFilter(Color.alpha(mTintColor) == 0 ? null : mColorFilter);
+            mDrawable.invalidateSelf();
+        }
+
+        if (mChangeRunnable != null) {
+            mChangeRunnable.run();
+        }
+    }
+
+    public int getTint() {
+        return mTintColor;
     }
 
     @Override
@@ -150,23 +253,29 @@
     }
 
     public void setViewAlpha(float alpha) {
-        if (mAlphaAnimator != null) {
-            mAlphaAnimator.cancel();
-        }
         if (alpha != mViewAlpha) {
             mViewAlpha = alpha;
-            invalidate();
+
+            if (mAlphaAnimator != null) {
+                mAlphaAnimator.cancel();
+            }
+
+            mDrawable.setAlpha((int) (255 * alpha));
             if (mChangeRunnable != null) {
                 mChangeRunnable.run();
             }
         }
     }
 
+    public float getViewAlpha() {
+        return mViewAlpha;
+    }
+
     public void animateViewAlpha(float alpha, long durationOut, Interpolator interpolator) {
         if (mAlphaAnimator != null) {
             mAlphaAnimator.cancel();
         }
-        mAlphaAnimator = ValueAnimator.ofFloat(mViewAlpha, alpha);
+        mAlphaAnimator = ValueAnimator.ofFloat(getViewAlpha(), alpha);
         mAlphaAnimator.addUpdateListener(mAlphaUpdateListener);
         mAlphaAnimator.addListener(mClearAnimatorListener);
         mAlphaAnimator.setInterpolator(interpolator);
@@ -193,4 +302,25 @@
     public void setChangeRunnable(Runnable changeRunnable) {
         mChangeRunnable = changeRunnable;
     }
+
+    @Override
+    public void onConfigChanged(Configuration newConfig) {
+        updateScreenSize();
+    }
+
+    private void updateScreenSize() {
+        if (mDrawable instanceof GradientDrawable) {
+            WindowManager wm = mContext.getSystemService(WindowManager.class);
+            if (wm == null) {
+                Log.w(TAG, "Can't resize gradient drawable to fit the screen");
+                return;
+            }
+            Display display = wm.getDefaultDisplay();
+            if (display != null) {
+                Point size = new Point();
+                display.getRealSize(size);
+                ((GradientDrawable) mDrawable).setScreenSize(size.x, size.y);
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 6d2a023..25f3e25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -16,18 +16,15 @@
 
 package com.android.systemui.statusbar;
 
-import android.annotation.ColorInt;
 import android.annotation.DrawableRes;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.drawable.Animatable;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
 import android.telephony.SubscriptionInfo;
 import android.util.ArraySet;
 import android.util.AttributeSet;
@@ -79,10 +76,8 @@
     private boolean mEthernetVisible = false;
     private int mEthernetIconId = 0;
     private int mLastEthernetIconId = -1;
-    private int mWifiBadgeId = -1;
     private boolean mWifiVisible = false;
     private int mWifiStrengthId = 0;
-    private int mLastWifiBadgeId = -1;
     private int mLastWifiStrengthId = -1;
     private boolean mWifiIn;
     private boolean mWifiOut;
@@ -290,7 +285,6 @@
             boolean activityIn, boolean activityOut, String description, boolean isTransient) {
         mWifiVisible = statusIcon.visible && !mBlockWifi;
         mWifiStrengthId = statusIcon.icon;
-        mWifiBadgeId = statusIcon.iconOverlay;
         mWifiDescription = statusIcon.contentDescription;
         mWifiIn = activityIn && mActivityEnabled && mWifiVisible;
         mWifiOut = activityOut && mActivityEnabled && mWifiVisible;
@@ -427,7 +421,6 @@
             mWifi.setImageDrawable(null);
             mWifiDark.setImageDrawable(null);
             mLastWifiStrengthId = -1;
-            mLastWifiBadgeId = -1;
         }
 
         for (PhoneState state : mPhoneStates) {
@@ -483,16 +476,10 @@
                     (mEthernetVisible ? "VISIBLE" : "GONE")));
 
         if (mWifiVisible) {
-            if (mWifiStrengthId != mLastWifiStrengthId || mWifiBadgeId != mLastWifiBadgeId) {
-                if (mWifiBadgeId == -1) {
-                    setIconForView(mWifi, mWifiStrengthId);
-                    setIconForView(mWifiDark, mWifiStrengthId);
-                } else {
-                    setBadgedWifiIconForView(mWifi, mWifiStrengthId, mWifiBadgeId);
-                    setBadgedWifiIconForView(mWifiDark, mWifiStrengthId, mWifiBadgeId);
-                }
+            if (mWifiStrengthId != mLastWifiStrengthId) {
+                setIconForView(mWifi, mWifiStrengthId);
+                setIconForView(mWifiDark, mWifiStrengthId);
                 mLastWifiStrengthId = mWifiStrengthId;
-                mLastWifiBadgeId = mWifiBadgeId;
             }
             mWifiGroup.setContentDescription(mWifiDescription);
             mWifiGroup.setVisibility(View.VISIBLE);
@@ -557,10 +544,6 @@
         // Using the imageView's context to retrieve the Drawable so that theme is preserved.
         Drawable icon = imageView.getContext().getDrawable(iconId);
 
-        setScaledIcon(imageView, icon);
-    }
-
-    private void setScaledIcon(ImageView imageView, Drawable icon) {
         if (mIconScaleFactor == 1.f) {
             imageView.setImageDrawable(icon);
         } else {
@@ -568,32 +551,6 @@
         }
     }
 
-    /**
-     * Creates and sets a LayerDrawable from the given ids on the given view.
-     *
-     * <p>This method will also scale the icon by {@link #mIconScaleFactor} if appropriate.
-     */
-    private void setBadgedWifiIconForView(ImageView imageView, @DrawableRes int wifiPieId,
-            @DrawableRes int badgeId) {
-        // Using the imageView's context to retrieve the Drawable so that theme is preserved.;
-        LayerDrawable icon = new LayerDrawable(new Drawable[] {
-                imageView.getContext().getDrawable(wifiPieId),
-                imageView.getContext().getDrawable(badgeId)});
-
-        // The LayerDrawable shares an underlying state so we must mutate the object to change the
-        // color between the light and dark themes.
-        icon.mutate().setTint(getColorAttr(imageView.getContext(), R.attr.singleToneColor));
-
-        setScaledIcon(imageView, icon);
-    }
-
-    /** Returns the given color attribute value, or white if not defined. */
-    @ColorInt private static int getColorAttr(Context context, int attr) {
-        TypedArray ta = context.obtainStyledAttributes(new int[] {attr});
-        @ColorInt int colorAccent = ta.getColor(0, Color.WHITE);
-        ta.recycle();
-        return colorAccent;
-    }
 
     @Override
     public void onDarkChanged(Rect tintArea, float darkIntensity, int tint) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 89694b33..27fe33e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -23,11 +23,12 @@
 import android.app.Notification;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
-import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -54,9 +55,16 @@
 import com.android.systemui.statusbar.notification.NotificationUtils;
 
 import java.text.NumberFormat;
+import java.util.Arrays;
 
 public class StatusBarIconView extends AnimatedImageView {
     public static final int NO_COLOR = 0;
+
+    /**
+     * Multiply alpha values with (1+DARK_ALPHA_BOOST) when dozing. The chosen value boosts
+     * everything above 30% to 50%, making it appear on 1bit color depths.
+     */
+    private static final float DARK_ALPHA_BOOST = 0.67f;
     private final int ANIMATION_DURATION_FAST = 100;
 
     public static final int STATE_ICON = 0;
@@ -131,6 +139,8 @@
     private final NotificationIconDozeHelper mDozer;
     private int mContrastedDrawableColor;
     private int mCachedContrastBackgroundColor = NO_COLOR;
+    private float[] mMatrix;
+    private ColorMatrixColorFilter mMatrixColorFilter;
 
     public StatusBarIconView(Context context, String slot, StatusBarNotification sbn) {
         this(context, slot, sbn, false);
@@ -544,14 +554,33 @@
 
     private void updateIconColor() {
         if (mCurrentSetColor != NO_COLOR) {
-            setImageTintList(ColorStateList.valueOf(NotificationUtils.interpolateColors(
-                    mCurrentSetColor, Color.WHITE, mDarkAmount)));
+            if (mMatrixColorFilter == null) {
+                mMatrix = new float[4 * 5];
+                mMatrixColorFilter = new ColorMatrixColorFilter(mMatrix);
+            }
+            int color = NotificationUtils.interpolateColors(
+                    mCurrentSetColor, Color.WHITE, mDarkAmount);
+            updateTintMatrix(mMatrix, color, DARK_ALPHA_BOOST * mDarkAmount);
+            mMatrixColorFilter.setColorMatrixArray(mMatrix);
+            setColorFilter(mMatrixColorFilter);
+            invalidate();  // setColorFilter only invalidates if the filter instance changed.
         } else {
-            setImageTintList(null);
             mDozer.updateGrayscale(this, mDarkAmount);
         }
     }
 
+    /**
+     * Updates {@param array} such that it represents a matrix that changes RGB to {@param color}
+     * and multiplies the alpha channel with the color's alpha+{@param alphaBoost}.
+     */
+    private static void updateTintMatrix(float[] array, int color, float alphaBoost) {
+        Arrays.fill(array, 0);
+        array[4] = Color.red(color);
+        array[9] = Color.green(color);
+        array[14] = Color.blue(color);
+        array[18] = Color.alpha(color) / 255f + alphaBoost;
+    }
+
     public void setIconColor(int iconColor, boolean animate) {
         if (mIconColor != iconColor) {
             mIconColor = iconColor;
@@ -756,9 +785,16 @@
             updateIconScale();
             updateDecorColor();
             updateIconColor();
+            updateAllowAnimation();
         }, dark, fade, delay);
     }
 
+    private void updateAllowAnimation() {
+        if (mDarkAmount == 0 || mDarkAmount == 1) {
+            setAllowAnimation(mDarkAmount == 0);
+        }
+    }
+
     public interface OnVisibilityChangedListener {
         void onVisibilityChanged(int newVisibility);
     }
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 7162b31..76177a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -23,9 +23,11 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -33,6 +35,7 @@
 import android.view.ViewStub;
 import android.view.WindowManager;
 import android.widget.LinearLayout;
+
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
@@ -41,6 +44,7 @@
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
+import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
 import com.android.systemui.statusbar.phone.NavigationBarView;
@@ -62,6 +66,7 @@
 
     private CarBatteryController mCarBatteryController;
     private BatteryMeterView mBatteryMeterView;
+    private Drawable mNotificationPanelBackground;
 
     private ConnectedDeviceSignalController mConnectedDeviceSignalController;
     private CarNavigationBarView mNavigationBarView;
@@ -91,17 +96,18 @@
     protected void makeStatusBarView() {
         super.makeStatusBarView();
 
+        mNotificationPanelBackground = getDefaultWallpaper();
+        mScrimController.setScrimBehindDrawable(mNotificationPanelBackground);
+
         FragmentHostManager manager = FragmentHostManager.get(mStatusBarWindow);
         manager.addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
-            mBatteryMeterView = ((BatteryMeterView) fragment.getView().findViewById(
-                    R.id.battery));
+            mBatteryMeterView = fragment.getView().findViewById(R.id.battery);
 
             // By default, the BatteryMeterView should not be visible. It will be toggled
             // when a device has connected by bluetooth.
             mBatteryMeterView.setVisibility(View.GONE);
 
-            ViewStub stub = (ViewStub) fragment.getView().findViewById(
-                    R.id.connected_device_signals_stub);
+            ViewStub stub = fragment.getView().findViewById(R.id.connected_device_signals_stub);
             View signalsView = stub.inflate();
 
             // When a ViewStub if inflated, it does not respect the margins on the
@@ -256,7 +262,7 @@
         if (userSwitcherController.useFullscreenUserSwitcher()) {
             mFullscreenUserSwitcher = new FullscreenUserSwitcher(this,
                     userSwitcherController,
-                    (ViewStub) mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub));
+                    mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub));
         } else {
             super.createUserSwitcher();
         }
@@ -314,13 +320,46 @@
         return startActivityWithOptions(intent, options.toBundle());
     }
 
+    @Override
+    protected boolean shouldPeek(NotificationData.Entry entry, StatusBarNotification sbn) {
+        // Because space is usually constrained in the auto use-case, there should not be a
+        // pinned notification when the shade has been expanded. Ensure this by not pinning any
+        // notification if the shade is already opened.
+        if (mPanelExpanded) {
+            return false;
+        }
+
+        return super.shouldPeek(entry, sbn);
+    }
+
+    @Override
+    public void animateExpandNotificationsPanel() {
+        // Because space is usually constrained in the auto use-case, there should not be a
+        // pinned notification when the shade has been expanded. Ensure this by removing all heads-
+        // up notifications.
+        mHeadsUpManager.removeAllHeadsUpEntries();
+        super.animateExpandNotificationsPanel();
+    }
+
     /**
      * Ensures that relevant child views are appropriately recreated when the device's density
      * changes.
      */
     @Override
-    protected void onDensityOrFontScaleChanged() {
+    public void onDensityOrFontScaleChanged() {
         super.onDensityOrFontScaleChanged();
         mController.onDensityOrFontScaleChanged();
+
+        // Need to update the background on density changed in case the change was due to night
+        // mode.
+        mNotificationPanelBackground = getDefaultWallpaper();
+        mScrimController.setScrimBehindDrawable(mNotificationPanelBackground);
+    }
+
+    /**
+     * Returns the {@link Drawable} that represents the wallpaper that the user has currently set.
+     */
+    private Drawable getDefaultWallpaper() {
+        return mContext.getDrawable(com.android.internal.R.drawable.default_wallpaper);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index f8b6dee..9338887 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -16,8 +16,13 @@
 
 package com.android.systemui.statusbar.car;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.content.res.Resources;
+import android.os.CountDownTimer;
 import android.view.View;
 import android.view.ViewStub;
+import android.widget.ProgressBar;
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.StatusBar;
@@ -27,30 +32,132 @@
  * Manages the fullscreen user switcher.
  */
 public class FullscreenUserSwitcher {
+    private final View mContainer;
+    private final View mParent;
+    private final UserGridView mUserGridView;
+    private final UserSwitcherController mUserSwitcherController;
+    private final ProgressBar mProgressBar;
+    private final ProgressBar mSwitchingUsers;
+    private final int mLoginTimeoutMs;
+    private final int mAnimUpdateIntervalMs;
+    private final int mShortAnimDuration;
 
-    private View mContainer;
-    private UserGridView mUserGridView;
-    private UserSwitcherController mUserSwitcherController;
+    private boolean mShowing;
+
+    private CountDownTimer mTimer;
 
     public FullscreenUserSwitcher(StatusBar statusBar,
             UserSwitcherController userSwitcherController,
             ViewStub containerStub) {
         mUserSwitcherController = userSwitcherController;
-        mContainer = containerStub.inflate();
-        mUserGridView = (UserGridView) mContainer.findViewById(R.id.user_grid);
+        mParent = containerStub.inflate();
+        mContainer = mParent.findViewById(R.id.container);
+        mUserGridView = mContainer.findViewById(R.id.user_grid);
         mUserGridView.init(statusBar, mUserSwitcherController);
+        mUserGridView.setUserSelectionListener(record -> {
+            if (!record.isCurrent) {
+                toggleSwitchInProgress(true);
+            }
+        });
+
+        PageIndicator pageIndicator = mContainer.findViewById(R.id.user_switcher_page_indicator);
+        pageIndicator.setupWithViewPager(mUserGridView);
+
+        mProgressBar = mContainer.findViewById(R.id.countdown_progress);
+        Resources res = mContainer.getResources();
+        mLoginTimeoutMs = res.getInteger(R.integer.car_user_switcher_timeout_ms);
+        mAnimUpdateIntervalMs = res.getInteger(R.integer.car_user_switcher_anim_update_ms);
+        mShortAnimDuration = res.getInteger(android.R.integer.config_shortAnimTime);
+
+        mContainer.findViewById(R.id.start_driving).setOnClickListener(v -> {
+            cancelTimer();
+            automaticallySelectUser();
+        });
+
+        mSwitchingUsers = mParent.findViewById(R.id.switching_users);
     }
 
     public void onUserSwitched(int newUserId) {
         mUserGridView.onUserSwitched(newUserId);
     }
 
+    private void toggleSwitchInProgress(boolean inProgress) {
+        if (inProgress) {
+            crossFade(mSwitchingUsers, mContainer);
+        } else {
+            crossFade(mContainer, mSwitchingUsers);
+        }
+    }
+
+    private void crossFade(View incoming, View outgoing) {
+        incoming.animate()
+            .alpha(1.0f)
+            .setDuration(mShortAnimDuration)
+            .setListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animator) {
+                    incoming.setAlpha(0.0f);
+                    incoming.setVisibility(View.VISIBLE);
+                }
+            });
+
+        outgoing.animate()
+            .alpha(0.0f)
+            .setDuration(mShortAnimDuration)
+            .setListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    outgoing.setVisibility(View.GONE);
+                }
+            });
+    }
+
     public void show() {
-        mContainer.setVisibility(View.VISIBLE);
+        if (mShowing) {
+            return;
+        }
+        mShowing = true;
+        mParent.setVisibility(View.VISIBLE);
+        cancelTimer();
+
+        // This would be the case if we were in the middle of a switch.
+        if (mProgressBar.getVisibility() != View.VISIBLE) {
+            return;
+        }
+
+        mTimer = new CountDownTimer(mLoginTimeoutMs, mAnimUpdateIntervalMs) {
+            @Override
+            public void onTick(long msUntilFinished) {
+                int elapsed = mLoginTimeoutMs - (int) msUntilFinished;
+                mProgressBar.setProgress((int) elapsed, true /* animate */);
+            }
+
+            @Override
+            public void onFinish() {
+                mProgressBar.setProgress(mLoginTimeoutMs, true /* animate */);
+                automaticallySelectUser();
+            }
+        };
+        mTimer.start();
     }
 
     public void hide() {
-        mContainer.setVisibility(View.GONE);
+        mShowing = false;
+        cancelTimer();
+        toggleSwitchInProgress(false);
+        mParent.setVisibility(View.GONE);
+    }
+
+    private void cancelTimer() {
+        if (mTimer != null) {
+            mTimer.cancel();
+            mTimer = null;
+        }
+    }
+
+    private void automaticallySelectUser() {
+        // TODO: Switch according to some policy. This implementation just tries to drop the
+        //       keyguard for the current user.
+        mUserGridView.showOfflineAuthUi();
     }
 }
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/PageIndicator.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/PageIndicator.java
new file mode 100644
index 0000000..f7d0906
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/PageIndicator.java
@@ -0,0 +1,193 @@
+/*
+ * 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.statusbar.car;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.database.DataSetObserver;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+
+import com.android.systemui.R;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Displays the dots underneath the ViewPager on the lock screen. This is really just a simplified
+ * version of PagerTitleStrip. We don't inherit from there because it's impossible to bypass some
+ * of the overriden logic in that class.
+ */
+public class PageIndicator extends View {
+    private static final String TAG = "PageIndicator";
+    // These can be made a styleable attribute in the future if necessary.
+    private static final int SELECTED_COLOR = 0xFFF5F5F5;  // grey 100
+    private static final int UNSELECTED_COLOR = 0xFFBDBDBD;  // grey 400
+    private final PageListener mPageListener = new PageListener();
+
+    private ViewPager mPager;
+    private WeakReference<PagerAdapter> mWatchingAdapter;
+
+    private int mPageCount;
+    private int mCurrentPosition;
+    private Paint mPaint;
+    private int mRadius;
+    private int mStep;
+
+    public PageIndicator(Context context) {
+        super(context);
+        init();
+    }
+
+    public PageIndicator(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    private void init() {
+        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mPaint.setStyle(Paint.Style.FILL);
+        mRadius = getResources().getDimensionPixelSize(R.dimen.car_page_indicator_dot_diameter) / 2;
+        mStep = mRadius * 3;
+    }
+
+    public void setupWithViewPager(ViewPager pager) {
+        mPager = pager;
+
+        final PagerAdapter adapter = (PagerAdapter) pager.getAdapter();
+        pager.addOnPageChangeListener(mPageListener);
+        pager.addOnAdapterChangeListener(mPageListener);
+        updateAdapter(mWatchingAdapter != null ? mWatchingAdapter.get() : null, adapter);
+        invalidate();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        if (mPager != null) {
+            updateAdapter(mPager.getAdapter(), null);
+            mPager.removeOnPageChangeListener(mPageListener);
+            mPager.removeOnAdapterChangeListener(mPageListener);
+            mPager = null;
+        }
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+
+        int x = canvas.getWidth() / 2 - (mPageCount / 2) * mStep;
+        int y = canvas.getHeight() / 2;
+
+        for (int i = 0; i < mPageCount; i++) {
+            if (i == mCurrentPosition) {
+                mPaint.setColor(SELECTED_COLOR);
+            } else {
+                mPaint.setColor(UNSELECTED_COLOR);
+            }
+
+            canvas.drawCircle(x, y, mRadius, mPaint);
+            x += mStep;
+        }
+    }
+
+    void updateAdapter(PagerAdapter oldAdapter, PagerAdapter newAdapter) {
+        if (oldAdapter != null) {
+            oldAdapter.unregisterDataSetObserver(mPageListener);
+            mWatchingAdapter = null;
+        }
+
+        if (newAdapter != null) {
+            newAdapter.registerDataSetObserver(mPageListener);
+            mWatchingAdapter = new WeakReference<>(newAdapter);
+        }
+
+        updateDots();
+
+        if (mPager != null) {
+            requestLayout();
+        }
+    }
+
+    private <T> T getRef(WeakReference<T> weakRef) {
+        if (weakRef == null) {
+            return null;
+        }
+        return weakRef.get();
+    }
+
+    private void updateDots() {
+        PagerAdapter adapter = getRef(mWatchingAdapter);
+        if (adapter == null) {
+            return;
+        }
+
+        int count = adapter.getCount();
+        if (mPageCount == count) {
+            // Nothing to be done.
+            return;
+        }
+
+        mPageCount = count;
+        mCurrentPosition = 0;
+        invalidate();
+    }
+
+    private class PageListener extends DataSetObserver implements ViewPager.OnPageChangeListener,
+            ViewPager.OnAdapterChangeListener {
+
+        @Override
+        public void onPageScrolled(int unused1, float unused2, int unused3) { }
+
+        @Override
+        public void onPageSelected(int position) {
+            if (mCurrentPosition == position) {
+                return;
+            }
+
+            if (mPageCount <= position) {
+                Log.e(TAG, "Position out of bounds, position=" + position + " size=" + mPageCount);
+                return;
+            }
+
+            mCurrentPosition = position;
+            invalidate();
+        }
+
+        @Override
+        public void onPageScrollStateChanged(int state) { }
+
+        @Override
+        public void onAdapterChanged(ViewPager viewPager, PagerAdapter oldAdapter,
+                PagerAdapter newAdapter) {
+            updateAdapter(oldAdapter, newAdapter);
+        }
+
+        @Override
+        public void onChanged() {
+            updateDots();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
index 137b5cf..cfa9864 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
@@ -17,27 +17,35 @@
 package com.android.systemui.statusbar.car;
 
 import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
 import android.util.AttributeSet;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.GridView;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import com.android.internal.util.UserIcons;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.UserUtil;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 
-public class UserGridView extends GridView {
-
+/**
+ * Displays a ViewPager with icons for the users in the system to allow switching between users.
+ * One of the uses of this is for the lock screen in auto.
+ */
+public class UserGridView extends ViewPager {
     private StatusBar mStatusBar;
     private UserSwitcherController mUserSwitcherController;
     private Adapter mAdapter;
-    private int mPendingUserId = UserHandle.USER_NULL;
+    private UserSelectionListener mUserSelectionListener;
 
     public UserGridView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -47,116 +55,184 @@
         mStatusBar = statusBar;
         mUserSwitcherController = userSwitcherController;
         mAdapter = new Adapter(mUserSwitcherController);
+        addOnLayoutChangeListener(mAdapter);
         setAdapter(mAdapter);
-
-        setOnItemClickListener(new OnItemClickListener() {
-            @Override
-            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                mPendingUserId = UserHandle.USER_NULL;
-                UserSwitcherController.UserRecord record = mAdapter.getItem(position);
-                if (record == null) {
-                    return;
-                }
-
-                if (record.isGuest || record.isAddUser) {
-                    mUserSwitcherController.switchTo(record);
-                    return;
-                }
-
-                if (record.isCurrent) {
-                    showOfflineAuthUi();
-                } else {
-                    mPendingUserId = record.info.id;
-                    mUserSwitcherController.switchTo(record);
-                }
-            }
-        });
-
-        setOnItemLongClickListener(new OnItemLongClickListener() {
-            @Override
-            public boolean onItemLongClick(AdapterView<?> parent,
-                    View view, int position, long id) {
-                UserSwitcherController.UserRecord record = mAdapter.getItem(position);
-                if (record == null || record.isAddUser) {
-                    return false;
-                }
-                if (record.isGuest) {
-                    if (record.isCurrent) {
-                        mUserSwitcherController.switchTo(record);
-                    }
-                    return true;
-                }
-
-                UserUtil.deleteUserWithPrompt(getContext(), record.info.id,
-                        mUserSwitcherController);
-                return true;
-            }
-        });
     }
 
     public void onUserSwitched(int newUserId) {
-        if (mPendingUserId == newUserId) {
-            // Bring up security view after user switch is completed.
-            post(new Runnable() {
-                @Override
-                public void run() {
-                    showOfflineAuthUi();
-                }
-            });
-        }
-        mPendingUserId = UserHandle.USER_NULL;
+        // Bring up security view after user switch is completed.
+        post(this::showOfflineAuthUi);
     }
 
-    private void showOfflineAuthUi() {
+    public void setUserSelectionListener(UserSelectionListener userSelectionListener) {
+        mUserSelectionListener = userSelectionListener;
+    }
+
+    void showOfflineAuthUi() {
         // TODO: Show keyguard UI in-place.
         mStatusBar.executeRunnableDismissingKeyguard(null, null, true, true, true);
     }
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-        if (widthMode == MeasureSpec.UNSPECIFIED) {
-            setNumColumns(AUTO_FIT);
-        } else {
-            int columnWidth = Math.max(1, getRequestedColumnWidth());
-            int itemCount = getAdapter() == null ? 0 : getAdapter().getCount();
-            int numColumns = Math.max(1, Math.min(itemCount, widthSize / columnWidth));
-            setNumColumns(numColumns);
+        // Wrap content doesn't work in ViewPagers, so simulate the behavior in code.
+        int height = 0;
+        for(int i = 0; i < getChildCount(); i++) {
+            View child = getChildAt(i);
+            child.measure(widthMeasureSpec,
+                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+            height = Math.max(child.getMeasuredHeight(), height);
         }
+        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     }
 
-    private final class Adapter extends UserSwitcherController.BaseUserAdapter {
+    /**
+     * This is a ViewPager.PagerAdapter which deletegates the work to a
+     * UserSwitcherController.BaseUserAdapter. Java doesn't support multiple inheritance so we have
+     * to use composition instead to achieve the same goal since both the base classes are abstract
+     * classes and not interfaces.
+     */
+    private final class Adapter extends PagerAdapter implements View.OnLayoutChangeListener {
+        private final int mPodWidth;
+        private final int mPodMargin;
+
+        private final WrappedBaseUserAdapter mUserAdapter;
+        private int mContainerWidth;
+
         public Adapter(UserSwitcherController controller) {
-            super(controller);
+            super();
+            mUserAdapter = new WrappedBaseUserAdapter(controller, this);
+            mPodWidth = getResources().getDimensionPixelSize(
+                    R.dimen.car_fullscreen_user_pod_image_avatar_width);
+            mPodMargin = getResources().getDimensionPixelSize(
+                    R.dimen.car_fullscreen_user_pod_margin_side);
         }
 
         @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            if (convertView == null) {
-                LayoutInflater inflater = (LayoutInflater)getContext().getSystemService
-                        (Context.LAYOUT_INFLATER_SERVICE);
-                convertView = inflater.inflate(R.layout.car_fullscreen_user_pod, null);
-            }
-            UserSwitcherController.UserRecord record = getItem(position);
+        public void destroyItem(ViewGroup container, int position, Object object) {
+            container.removeView((View) object);
+        }
 
-            TextView nameView = (TextView) convertView.findViewById(R.id.user_name);
+        private int getIconsPerPage() {
+            // We need to know how many pods we need in this page. Each pod has its own width and
+            // margins on both sides. We can then divide the measured width of the parent by the
+            // sum of pod width and margin to get the number of pods that will completely fit.
+            return mContainerWidth / (mPodWidth + mPodMargin * 2);
+        }
+
+        @Override
+        public Object instantiateItem(ViewGroup container, int position) {
+            Context context = getContext();
+            LayoutInflater inflater = LayoutInflater.from(context);
+
+            ViewGroup pods = (ViewGroup) inflater.inflate(
+                    R.layout.car_fullscreen_user_pod_container, null);
+
+            int iconsPerPage = getIconsPerPage();
+            int limit = Math.min(mUserAdapter.getCount(), (position + 1) * iconsPerPage);
+            for (int i = position * iconsPerPage; i < limit; i++) {
+                pods.addView(makeUserPod(inflater, context, i, pods));
+            }
+            container.addView(pods);
+            return pods;
+        }
+
+        private Drawable getUserIcon(Context context, UserSwitcherController.UserRecord record) {
+            if (record.isAddUser) {
+                Drawable icon = context.getDrawable(R.drawable.ic_add_circle_qs);
+                icon.setTint(Color.WHITE);
+                return icon;
+            }
+            return UserIcons.getDefaultUserIcon(record.resolveId(), /* light= */ true);
+        }
+
+        private View makeUserPod(LayoutInflater inflater, Context context,
+                int position, ViewGroup parent) {
+            final UserSwitcherController.UserRecord record = mUserAdapter.getItem(position);
+            View view = inflater.inflate(R.layout.car_fullscreen_user_pod, parent, false);
+
+            TextView nameView = view.findViewById(R.id.user_name);
             if (record != null) {
-                nameView.setText(getName(getContext(), record));
-                convertView.setActivated(record.isCurrent);
+                nameView.setText(mUserAdapter.getName(context, record));
+                view.setActivated(record.isCurrent);
             } else {
-                nameView.setText("Unknown");
+                nameView.setText(context.getString(R.string.unknown_user_label));
             }
 
-            ImageView iconView = (ImageView) convertView.findViewById(R.id.user_avatar);
+            ImageView iconView = (ImageView) view.findViewById(R.id.user_avatar);
             if (record == null || record.picture == null) {
-                iconView.setImageDrawable(getDrawable(getContext(), record));
+                iconView.setImageDrawable(getUserIcon(context, record));
             } else {
                 iconView.setImageBitmap(record.picture);
             }
 
-            return convertView;
+            iconView.setOnClickListener(v -> {
+                if (record == null) {
+                    return;
+                }
+
+                if (mUserSelectionListener != null) {
+                    mUserSelectionListener.onUserSelected(record);
+                }
+
+                if (record.isCurrent) {
+                    showOfflineAuthUi();
+                } else {
+                    mUserSwitcherController.switchTo(record);
+                }
+            });
+
+            return view;
+        }
+
+        @Override
+        public int getCount() {
+            int iconsPerPage = getIconsPerPage();
+            if (iconsPerPage == 0) {
+                return 0;
+            }
+            return (int) Math.ceil((double) mUserAdapter.getCount() / getIconsPerPage());
+        }
+
+        public void refresh() {
+            mUserAdapter.refresh();
+        }
+
+        @Override
+        public boolean isViewFromObject(View view, Object object) {
+            return view == object;
+        }
+
+        @Override
+        public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                int oldLeft, int oldTop, int oldRight, int oldBottom) {
+            mContainerWidth = Math.max(left - right, right - left);
+            notifyDataSetChanged();
         }
     }
+
+    private final class WrappedBaseUserAdapter extends UserSwitcherController.BaseUserAdapter {
+        private Adapter mContainer;
+
+        public WrappedBaseUserAdapter(UserSwitcherController controller, Adapter container) {
+            super(controller);
+            mContainer = container;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            throw new UnsupportedOperationException("unused");
+        }
+
+        @Override
+        public void notifyDataSetChanged() {
+            super.notifyDataSetChanged();
+            mContainer.notifyDataSetChanged();
+        }
+    }
+
+    interface UserSelectionListener {
+        void onUserSelected(UserSwitcherController.UserRecord record);
+    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AboveShelfChangedListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AboveShelfChangedListener.java
new file mode 100644
index 0000000..07baedc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AboveShelfChangedListener.java
@@ -0,0 +1,28 @@
+/*
+ * 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.statusbar.notification;
+
+/**
+ * A listener for when the above shelf state of notification changes
+ */
+public interface AboveShelfChangedListener {
+
+    /**
+     * Notifies a listener that the above shelf state changed
+     */
+    void onAboveShelfStateChanged(boolean aboveShelf);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AboveShelfObserver.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AboveShelfObserver.java
new file mode 100644
index 0000000..f10d2d7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AboveShelfObserver.java
@@ -0,0 +1,73 @@
+/*
+ * 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.statusbar.notification;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+
+/**
+ * An observer that listens to the above shelf state and can notify listeners
+ */
+public class AboveShelfObserver implements AboveShelfChangedListener {
+
+    private final ViewGroup mHostLayout;
+    private boolean mHasViewsAboveShelf = false;
+    private HasViewAboveShelfChangedListener mListener;
+
+    public AboveShelfObserver(ViewGroup hostLayout) {
+        mHostLayout = hostLayout;
+    }
+
+    public void setListener(HasViewAboveShelfChangedListener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    public void onAboveShelfStateChanged(boolean aboveShelf) {
+        boolean hasViewsAboveShelf = aboveShelf;
+        if (!hasViewsAboveShelf && mHostLayout != null) {
+            int n = mHostLayout.getChildCount();
+            for (int i = 0; i < n; i++) {
+                View child = mHostLayout.getChildAt(i);
+                if (child instanceof ExpandableNotificationRow) {
+                    if (((ExpandableNotificationRow) child).isAboveShelf()) {
+                        hasViewsAboveShelf = true;
+                        break;
+                    }
+                }
+            }
+        }
+        if (mHasViewsAboveShelf != hasViewsAboveShelf) {
+            mHasViewsAboveShelf = hasViewsAboveShelf;
+            if (mListener != null) {
+                mListener.onHasViewsAboveShelfChanged(hasViewsAboveShelf);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    boolean hasViewsAboveShelf() {
+        return mHasViewsAboveShelf;
+    }
+
+    public interface HasViewAboveShelfChangedListener {
+        void onHasViewsAboveShelfChanged(boolean hasViewsAboveShelf);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
index e6b3fb8..92f26d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
@@ -48,10 +48,13 @@
 
     @Override
     protected boolean sameAs(TransformState otherState) {
+        if (super.sameAs(otherState)) {
+            return true;
+        }
         if (otherState instanceof ImageTransformState) {
             return mIcon != null && mIcon.sameAs(((ImageTransformState) otherState).getIcon());
         }
-        return super.sameAs(otherState);
+        return false;
     }
 
     @Override
@@ -113,7 +116,7 @@
     }
 
     @Override
-    protected boolean transformScale() {
+    protected boolean transformScale(TransformState otherState) {
         return true;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
index 15cca5f..fcc982ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -31,6 +31,7 @@
 
 import com.android.internal.widget.NotificationExpandButton;
 import com.android.systemui.Interpolators;
+import com.android.systemui.R;
 import com.android.systemui.ViewInvertHelper;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.TransformableView;
@@ -61,9 +62,12 @@
     private ImageView mWorkProfileImage;
     private boolean mIsLowPriority;
     private boolean mTransformLowPriorityTitle;
+    private boolean mShowExpandButtonAtEnd;
 
     protected NotificationHeaderViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
         super(ctx, view, row);
+        mShowExpandButtonAtEnd = ctx.getResources().getBoolean(
+                R.bool.config_showNotificationExpandButtonAtEnd);
         mInvertHelper = new ViewInvertHelper(ctx, NotificationPanelView.DOZE_ANIMATION_DURATION);
         mTransformationHelper = new ViewTransformationHelper();
 
@@ -114,6 +118,7 @@
         mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge);
         mColor = resolveColor(mExpandButton);
         mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header);
+        mNotificationHeader.setShowExpandButtonAtEnd(mShowExpandButtonAtEnd);
         getDozer().setColor(mColor);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
index abb4cf6..bb979eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.graphics.Color;
+import android.graphics.Rect;
 import android.service.notification.StatusBarNotification;
 import android.view.View;
 import android.widget.ImageView;
@@ -41,6 +42,8 @@
     private TextView mTitle;
     private TextView mText;
     private View mActionsContainer;
+    private View mReplyAction;
+    private Rect mTmpRect = new Rect();
 
     private int mContentHeight;
     private int mMinHeightHint;
@@ -130,6 +133,29 @@
             mProgressBar = null;
         }
         mActionsContainer = mView.findViewById(com.android.internal.R.id.actions_container);
+        mReplyAction = mView.findViewById(com.android.internal.R.id.reply_icon_action);
+    }
+
+    @Override
+    public boolean disallowSingleClick(float x, float y) {
+        if (mReplyAction != null && mReplyAction.getVisibility() == View.VISIBLE) {
+            if (isOnView(mReplyAction, x, y) || isOnView(mPicture, x, y)) {
+                return true;
+            }
+        }
+        return super.disallowSingleClick(x, y);
+    }
+
+    private boolean isOnView(View view, float x, float y) {
+        View searchView = (View) view.getParent();
+        while (searchView != null && !(searchView instanceof ExpandableNotificationRow)) {
+            searchView.getHitRect(mTmpRect);
+            x -= mTmpRect.left;
+            y -= mTmpRect.top;
+            searchView = (View) searchView.getParent();
+        }
+        view.getHitRect(mTmpRect);
+        return mTmpRect.contains((int) x,(int) y);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
index 4b73613..5200d69 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -186,4 +186,8 @@
     public boolean isDimmable() {
         return true;
     }
+
+    public boolean disallowSingleClick(float x, float y) {
+        return false;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java
index 6fe5756..c4aabe4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.notification;
 
 import android.text.Layout;
+import android.text.Spanned;
 import android.text.TextUtils;
 import android.util.Pools;
 import android.view.View;
@@ -41,16 +42,76 @@
 
     @Override
     protected boolean sameAs(TransformState otherState) {
+        if (super.sameAs(otherState)) {
+            return true;
+        }
         if (otherState instanceof TextViewTransformState) {
             TextViewTransformState otherTvs = (TextViewTransformState) otherState;
             if(TextUtils.equals(otherTvs.mText.getText(), mText.getText())) {
                 int ownEllipsized = getEllipsisCount();
                 int otherEllipsized = otherTvs.getEllipsisCount();
                 return ownEllipsized == otherEllipsized
-                        && getInnerHeight(mText) == getInnerHeight(otherTvs.mText);
+                        && mText.getLineCount() == otherTvs.mText.getLineCount()
+                        && hasSameSpans(otherTvs);
             }
         }
-        return super.sameAs(otherState);
+        return false;
+    }
+
+    private boolean hasSameSpans(TextViewTransformState otherTvs) {
+        boolean hasSpans = mText instanceof Spanned;
+        boolean otherHasSpans = otherTvs.mText instanceof Spanned;
+        if (hasSpans != otherHasSpans) {
+            return false;
+        } else if (!hasSpans) {
+            return true;
+        }
+        // Actually both have spans, let's try to compare them
+        Spanned ownSpanned = (Spanned) mText;
+        Object[] spans = ownSpanned.getSpans(0, ownSpanned.length(), Object.class);
+        Spanned otherSpanned = (Spanned) otherTvs.mText;
+        Object[] otherSpans = otherSpanned.getSpans(0, otherSpanned.length(), Object.class);
+        if (spans.length != otherSpans.length) {
+            return false;
+        }
+        for (int i = 0; i < spans.length; i++) {
+            Object span = spans[i];
+            Object otherSpan = otherSpans[i];
+            if (!span.getClass().equals(otherSpan.getClass())) {
+                return false;
+            }
+            if (ownSpanned.getSpanStart(span) != otherSpanned.getSpanStart(otherSpan)
+                    || ownSpanned.getSpanEnd(span) != otherSpanned.getSpanEnd(otherSpan)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    protected boolean transformScale(TransformState otherState) {
+        if (!(otherState instanceof TextViewTransformState)) {
+            return false;
+        }
+        TextViewTransformState otherTvs = (TextViewTransformState) otherState;
+        int lineCount = mText.getLineCount();
+        return lineCount == 1 && lineCount == otherTvs.mText.getLineCount()
+                && getEllipsisCount() == otherTvs.getEllipsisCount()
+                && getViewHeight() != otherTvs.getViewHeight();
+    }
+
+    @Override
+    protected int getViewWidth() {
+        Layout l = mText.getLayout();
+        if (l != null) {
+            return (int) l.getLineWidth(0);
+        }
+        return super.getViewWidth();
+    }
+
+    @Override
+    protected int getViewHeight() {
+        return mText.getLineHeight();
     }
 
     private int getInnerHeight(TextView text) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
index c3f1cb1..bafedff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
@@ -54,6 +54,7 @@
 
     protected View mTransformedView;
     private int[] mOwnPosition = new int[2];
+    private boolean mSameAsAny;
     private float mTransformationEndY = UNDEFINED;
     private float mTransformationEndX = UNDEFINED;
 
@@ -107,7 +108,7 @@
         final View transformedView = mTransformedView;
         boolean transformX = (transformationFlags & TRANSFORM_X) != 0;
         boolean transformY = (transformationFlags & TRANSFORM_Y) != 0;
-        boolean transformScale = transformScale();
+        boolean transformScale = transformScale(otherState);
         // lets animate the positions correctly
         if (transformationAmount == 0.0f
                 || transformX && getTransformationStartX() == UNDEFINED
@@ -131,16 +132,16 @@
                 }
                 // we also want to animate the scale if we're the same
                 View otherView = otherState.getTransformedView();
-                if (transformScale && otherView.getWidth() != transformedView.getWidth()) {
-                    setTransformationStartScaleX(otherView.getWidth() * otherView.getScaleX()
-                            / (float) transformedView.getWidth());
+                if (transformScale && otherState.getViewWidth() != getViewWidth()) {
+                    setTransformationStartScaleX(otherState.getViewWidth() * otherView.getScaleX()
+                            / (float) getViewWidth());
                     transformedView.setPivotX(0);
                 } else {
                     setTransformationStartScaleX(UNDEFINED);
                 }
-                if (transformScale && otherView.getHeight() != transformedView.getHeight()) {
-                    setTransformationStartScaleY(otherView.getHeight() * otherView.getScaleY()
-                            / (float) transformedView.getHeight());
+                if (transformScale && otherState.getViewHeight() != getViewHeight()) {
+                    setTransformationStartScaleY(otherState.getViewHeight() * otherView.getScaleY()
+                            / (float) getViewHeight());
                     transformedView.setPivotY(0);
                 } else {
                     setTransformationStartScaleY(UNDEFINED);
@@ -204,7 +205,15 @@
         }
     }
 
-    protected boolean transformScale() {
+    protected int getViewWidth() {
+        return mTransformedView.getWidth();
+    }
+
+    protected int getViewHeight() {
+        return mTransformedView.getHeight();
+    }
+
+    protected boolean transformScale(TransformState otherState) {
         return false;
     }
 
@@ -258,7 +267,7 @@
         final View transformedView = mTransformedView;
         boolean transformX = (transformationFlags & TRANSFORM_X) != 0;
         boolean transformY = (transformationFlags & TRANSFORM_Y) != 0;
-        boolean transformScale = transformScale();
+        boolean transformScale = transformScale(otherState);
         // lets animate the positions correctly
         if (transformationAmount == 0.0f) {
             if (transformX) {
@@ -274,13 +283,13 @@
                 setTransformationStartY(start);
             }
             View otherView = otherState.getTransformedView();
-            if (transformScale && otherView.getWidth() != transformedView.getWidth()) {
+            if (transformScale && otherState.getViewWidth() != getViewWidth()) {
                 setTransformationStartScaleX(transformedView.getScaleX());
                 transformedView.setPivotX(0);
             } else {
                 setTransformationStartScaleX(UNDEFINED);
             }
-            if (transformScale && otherView.getHeight() != transformedView.getHeight()) {
+            if (transformScale && otherState.getViewHeight() != getViewHeight()) {
                 setTransformationStartScaleY(transformedView.getScaleY());
                 transformedView.setPivotY(0);
             } else {
@@ -332,14 +341,14 @@
             if (transformationStartScaleX != UNDEFINED) {
                 transformedView.setScaleX(
                         NotificationUtils.interpolate(transformationStartScaleX,
-                                (otherView.getWidth() / (float) transformedView.getWidth()),
+                                (otherState.getViewWidth() / (float) getViewWidth()),
                                 interpolatedValue));
             }
             float transformationStartScaleY = getTransformationStartScaleY();
             if (transformationStartScaleY != UNDEFINED) {
                 transformedView.setScaleY(
                         NotificationUtils.interpolate(transformationStartScaleY,
-                                (otherView.getHeight() / (float) transformedView.getHeight()),
+                                (otherState.getViewHeight() / (float) getViewHeight()),
                                 interpolatedValue));
             }
         }
@@ -418,7 +427,7 @@
     }
 
     protected boolean sameAs(TransformState otherState) {
-        return false;
+        return mSameAsAny;
     }
 
     public void appear(float transformationAmount, TransformableView otherView) {
@@ -449,6 +458,9 @@
         if (view instanceof ImageView) {
             ImageTransformState result = ImageTransformState.obtain();
             result.initFrom(view);
+            if (view.getId() == com.android.internal.R.id.reply_icon_action) {
+                ((TransformState) result).setIsSameAsAnyView(true);
+            }
             return result;
         }
         if (view instanceof ProgressBar) {
@@ -461,6 +473,10 @@
         return result;
     }
 
+    private void setIsSameAsAnyView(boolean sameAsAny) {
+        mSameAsAny = sameAsAny;
+    }
+
     public void recycle() {
         reset();
         if (getClass() == TransformState.class) {
@@ -514,6 +530,7 @@
 
     protected void reset() {
         mTransformedView = null;
+        mSameAsAny = false;
         mTransformationEndX = UNDEFINED;
         mTransformationEndY = UNDEFINED;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 7512efa..1bd90fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -24,6 +24,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.Prefs;
 import com.android.systemui.Prefs.Key;
+import com.android.systemui.qs.AutoAddTracker;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.qs.SecureSetting;
 import com.android.systemui.statusbar.policy.DataSaverController;
@@ -36,39 +37,47 @@
  */
 public class AutoTileManager {
 
+    public static final String HOTSPOT = "hotspot";
+    public static final String SAVER = "saver";
+    public static final String INVERSION = "inversion";
+    public static final String WORK = "work";
+    public static final String NIGHT = "night";
     private final Context mContext;
     private final QSTileHost mHost;
     private final Handler mHandler;
+    private final AutoAddTracker mAutoTracker;
 
     public AutoTileManager(Context context, QSTileHost host) {
+        mAutoTracker = new AutoAddTracker(context);
         mContext = context;
         mHost = host;
         mHandler = new Handler((Looper) Dependency.get(Dependency.BG_LOOPER));
-        if (!Prefs.getBoolean(context, Key.QS_HOTSPOT_ADDED, false)) {
+        if (!mAutoTracker.isAdded(HOTSPOT)) {
             Dependency.get(HotspotController.class).addCallback(mHotspotCallback);
         }
-        if (!Prefs.getBoolean(context, Key.QS_DATA_SAVER_ADDED, false)) {
+        if (!mAutoTracker.isAdded(SAVER)) {
             Dependency.get(DataSaverController.class).addCallback(mDataSaverListener);
         }
-        if (!Prefs.getBoolean(context, Key.QS_INVERT_COLORS_ADDED, false)) {
+        if (!mAutoTracker.isAdded(INVERSION)) {
             mColorsSetting = new SecureSetting(mContext, mHandler,
                     Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) {
                 @Override
                 protected void handleValueChanged(int value, boolean observedChange) {
+                    if (mAutoTracker.isAdded(INVERSION)) return;
                     if (value != 0) {
-                        mHost.addTile("inversion");
-                        Prefs.putBoolean(mContext, Key.QS_INVERT_COLORS_ADDED, true);
+                        mHost.addTile(INVERSION);
+                        mAutoTracker.setTileAdded(INVERSION);
                         mHandler.post(() -> mColorsSetting.setListening(false));
                     }
                 }
             };
             mColorsSetting.setListening(true);
         }
-        if (!Prefs.getBoolean(context, Key.QS_WORK_ADDED, false)) {
+        if (!mAutoTracker.isAdded(WORK)) {
             Dependency.get(ManagedProfileController.class).addCallback(mProfileCallback);
         }
 
-        if (!Prefs.getBoolean(context, Key.QS_NIGHTDISPLAY_ADDED, false)
+        if (!mAutoTracker.isAdded(NIGHT)
                 && NightDisplayController.isAvailable(mContext)) {
             Dependency.get(NightDisplayController.class).setListener(mNightDisplayCallback);
         }
@@ -76,6 +85,7 @@
 
     public void destroy() {
         mColorsSetting.setListening(false);
+        mAutoTracker.destroy();
         Dependency.get(HotspotController.class).removeCallback(mHotspotCallback);
         Dependency.get(DataSaverController.class).removeCallback(mDataSaverListener);
         Dependency.get(ManagedProfileController.class).removeCallback(mProfileCallback);
@@ -86,9 +96,10 @@
             new ManagedProfileController.Callback() {
                 @Override
                 public void onManagedProfileChanged() {
+                    if (mAutoTracker.isAdded(WORK)) return;
                     if (Dependency.get(ManagedProfileController.class).hasActiveProfile()) {
-                        mHost.addTile("work");
-                        Prefs.putBoolean(mContext, Key.QS_WORK_ADDED, true);
+                        mHost.addTile(WORK);
+                        mAutoTracker.setTileAdded(WORK);
                         mHandler.post(() -> Dependency.get(ManagedProfileController.class)
                                 .removeCallback(mProfileCallback));
                     }
@@ -104,9 +115,10 @@
     private final DataSaverController.Listener mDataSaverListener = new Listener() {
         @Override
         public void onDataSaverChanged(boolean isDataSaving) {
+            if (mAutoTracker.isAdded(SAVER)) return;
             if (isDataSaving) {
-                mHost.addTile("saver");
-                Prefs.putBoolean(mContext, Key.QS_DATA_SAVER_ADDED, true);
+                mHost.addTile(SAVER);
+                mAutoTracker.setTileAdded(SAVER);
                 mHandler.post(() -> Dependency.get(DataSaverController.class).removeCallback(
                         mDataSaverListener));
             }
@@ -116,9 +128,10 @@
     private final HotspotController.Callback mHotspotCallback = new Callback() {
         @Override
         public void onHotspotChanged(boolean enabled) {
+            if (mAutoTracker.isAdded(HOTSPOT)) return;
             if (enabled) {
-                mHost.addTile("hotspot");
-                Prefs.putBoolean(mContext, Key.QS_HOTSPOT_ADDED, true);
+                mHost.addTile(HOTSPOT);
+                mAutoTracker.setTileAdded(HOTSPOT);
                 mHandler.post(() -> Dependency.get(HotspotController.class)
                         .removeCallback(mHotspotCallback));
             }
@@ -144,8 +157,9 @@
         }
 
         private void addNightTile() {
-            mHost.addTile("night");
-            Prefs.putBoolean(mContext, Key.QS_NIGHTDISPLAY_ADDED, true);
+            if (mAutoTracker.isAdded(NIGHT)) return;
+            mHost.addTile(NIGHT);
+            mAutoTracker.setTileAdded(NIGHT);
             mHandler.post(() -> Dependency.get(NightDisplayController.class)
                     .setListener(null));
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.java
index 020dc25..37554c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.java
@@ -15,36 +15,76 @@
 package com.android.systemui.statusbar.phone;
 
 import android.content.Context;
+import android.content.om.IOverlayManager;
+import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
+import android.os.LocaleList;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
 
 import com.android.systemui.ConfigurationChangedReceiver;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
 
 public class ConfigurationControllerImpl implements ConfigurationController,
         ConfigurationChangedReceiver {
 
     private final ArrayList<ConfigurationListener> mListeners = new ArrayList<>();
+    private final Configuration mLastConfig = new Configuration();
     private int mDensity;
     private float mFontScale;
+    private LocaleList mLocaleList;
 
     public ConfigurationControllerImpl(Context context) {
         Configuration currentConfig = context.getResources().getConfiguration();
         mFontScale = currentConfig.fontScale;
         mDensity = currentConfig.densityDpi;
+        mLocaleList = currentConfig.getLocales();
     }
 
     @Override
     public void onConfigurationChanged(Configuration newConfig) {
-        mListeners.forEach(l -> l.onConfigChanged(newConfig));
+        // Avoid concurrent modification exception
+        ArrayList<ConfigurationListener> listeners = new ArrayList<>(mListeners);
+
+        listeners.forEach(l -> {
+            if (mListeners.contains(l)) {
+                l.onConfigChanged(newConfig);
+            }
+        });
         final float fontScale = newConfig.fontScale;
         final int density = newConfig.densityDpi;
         if (density != mDensity || mFontScale != fontScale) {
-            mListeners.forEach(l -> l.onDensityOrFontScaleChanged());
+            listeners.forEach(l -> {
+                if (mListeners.contains(l)) {
+                    l.onDensityOrFontScaleChanged();
+                }
+            });
             mDensity = density;
             mFontScale = fontScale;
         }
+
+        final LocaleList localeList = newConfig.getLocales();
+        if (!localeList.equals(mLocaleList)) {
+            mLocaleList = localeList;
+            listeners.forEach(l -> {
+                if (mListeners.contains(l)) {
+                    l.onLocaleListChanged();
+                }
+            });
+        }
+
+        if ((mLastConfig.updateFrom(newConfig) & ActivityInfo.CONFIG_ASSETS_PATHS) != 0) {
+                listeners.forEach(l -> {
+                    if (mListeners.contains(l)) {
+                        l.onOverlayChanged();
+                    }
+                });
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index e1ca929..6b7397b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -77,6 +77,10 @@
         return getBoolean("doze.display.supported", R.bool.doze_display_state_supported);
     }
 
+    public boolean getDozeSuspendDisplayStateSupported() {
+        return mContext.getResources().getBoolean(R.bool.doze_suspend_display_state_supported);
+    }
+
     public int getPulseDuration(boolean pickup) {
         return getPulseInDuration(pickup) + getPulseVisibleDuration() + getPulseOutDuration();
     }
@@ -153,6 +157,10 @@
         return 2 * getPulseVisibleDuration();
     }
 
+    public boolean doubleTapReportsTouchCoordinates() {
+        return mContext.getResources().getBoolean(R.bool.doze_double_tap_reports_touch_coordinates);
+    }
+
 
     /**
      * Parses a spec of the form `1,2,3,!5,*`. The resulting object will match numbers that are
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 6b276f8..c45c05e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -23,14 +23,11 @@
 import android.content.Context;
 import android.os.Handler;
 import android.util.Log;
-import android.view.View;
 import android.view.animation.Interpolator;
 
-import com.android.keyguard.KeyguardStatusView;
 import com.android.systemui.Interpolators;
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.doze.DozeLog;
-import com.android.systemui.doze.DozeTriggers;
 
 /**
  * Controller which handles all the doze animations of the scrims.
@@ -54,6 +51,9 @@
     private float mBehindTarget;
     private boolean mDozingAborted;
     private boolean mWakeAndUnlocking;
+    private boolean mFullyPulsing;
+
+    private float mAodFrontScrimOpacity = 0;
 
     public DozeScrimController(ScrimController scrimController, Context context) {
         mContext = context;
@@ -69,7 +69,8 @@
             mDozingAborted = false;
             abortAnimations();
             mScrimController.setDozeBehindAlpha(1f);
-            mScrimController.setDozeInFrontAlpha(mDozeParameters.getAlwaysOn() ? 0f : 1f);
+            mScrimController.setDozeInFrontAlpha(
+                    mDozeParameters.getAlwaysOn() ? mAodFrontScrimOpacity : 1f);
         } else {
             cancelPulsing();
             if (animate) {
@@ -87,6 +88,19 @@
         }
     }
 
+    /**
+     * Set the opacity of the front scrim when showing AOD1
+     *
+     * Used to emulate lower brightness values than the hardware supports natively.
+     */
+    public void setAodDimmingScrim(float scrimOpacity) {
+        mAodFrontScrimOpacity = scrimOpacity;
+        if (mDozing && !isPulsing() && !mDozingAborted && !mWakeAndUnlocking
+                && mDozeParameters.getAlwaysOn()) {
+            mScrimController.setDozeInFrontAlpha(mAodFrontScrimOpacity);
+        }
+    }
+
     public void setWakeAndUnlocking() {
         // Immediately abort the doze scrims in case of wake-and-unlock
         // for pulsing so the Keyguard fade-out animation scrim can take over.
@@ -113,6 +127,7 @@
         // be invoked when we're done so that the caller can drop the pulse wakelock.
         mPulseCallback = callback;
         mPulseReason = reason;
+        mScrimController.setDozeInFrontAlpha(1f);
         mHandler.post(mPulseIn);
     }
 
@@ -124,7 +139,8 @@
         if (mDozing && !mWakeAndUnlocking) {
             mScrimController.setDozeBehindAlpha(1f);
             mScrimController.setDozeInFrontAlpha(
-                    mDozeParameters.getAlwaysOn() && !mDozingAborted ? 0f : 1f);
+                    mDozeParameters.getAlwaysOn() && !mDozingAborted ?
+                            mAodFrontScrimOpacity : 1f);
         }
     }
 
@@ -136,6 +152,12 @@
         abortPulsing();
     }
 
+    public void pulseOutNow() {
+        if (mPulseCallback != null && mFullyPulsing) {
+            mPulseOut.run();
+        }
+    }
+
     public void onScreenTurnedOn() {
         if (isPulsing()) {
             final boolean pickupOrDoubleTap = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP
@@ -163,6 +185,7 @@
         if (DEBUG) Log.d(TAG, "Cancel pulsing");
 
         if (mPulseCallback != null) {
+            mFullyPulsing = false;
             mHandler.removeCallbacks(mPulseIn);
             mHandler.removeCallbacks(mPulseOut);
             mHandler.removeCallbacks(mPulseOutExtended);
@@ -282,10 +305,6 @@
 
             // Signal that the pulse is ready to turn the screen on and draw.
             pulseStarted();
-
-            if (mDozeParameters.getAlwaysOn()) {
-                mHandler.post(DozeScrimController.this::onScreenTurnedOn);
-            }
         }
     };
 
@@ -297,6 +316,7 @@
             mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
             mHandler.postDelayed(mPulseOutExtended,
                     mDozeParameters.getPulseVisibleDurationExtended());
+            mFullyPulsing = true;
         }
     };
 
@@ -311,23 +331,41 @@
     private final Runnable mPulseOut = new Runnable() {
         @Override
         public void run() {
+            mFullyPulsing = false;
+            mHandler.removeCallbacks(mPulseOut);
             mHandler.removeCallbacks(mPulseOutExtended);
             if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
             if (!mDozing) return;
-            startScrimAnimation(true /* inFront */, mDozeParameters.getAlwaysOn() ? 0 : 1,
+            startScrimAnimation(true /* inFront */, 1,
                     mDozeParameters.getPulseOutDuration(),
-                    Interpolators.ALPHA_IN, mPulseOutFinished);
+                    Interpolators.ALPHA_IN, mPulseOutFinishing);
+        }
+    };
+
+    private final Runnable mPulseOutFinishing = new Runnable() {
+        @Override
+        public void run() {
+            if (DEBUG) Log.d(TAG, "Pulse out finished");
+            DozeLog.tracePulseFinish();
+            if (mDozeParameters.getAlwaysOn() && mDozing) {
+                // Setting power states can block rendering. For AOD, delay finishing the pulse and
+                // setting the power state until the fully black scrim had time to hit the
+                // framebuffer.
+                mHandler.postDelayed(mPulseOutFinished, 30);
+            } else {
+                mPulseOutFinished.run();
+            }
         }
     };
 
     private final Runnable mPulseOutFinished = new Runnable() {
         @Override
         public void run() {
-            if (DEBUG) Log.d(TAG, "Pulse out finished");
-            DozeLog.tracePulseFinish();
-
             // Signal that the pulse is all finished so we can turn the screen off now.
-            pulseFinished();
+            DozeScrimController.this.pulseFinished();
+            if (mDozeParameters.getAlwaysOn()) {
+                mScrimController.setDozeInFrontAlpha(mAodFrontScrimOpacity);
+            }
         }
     };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
index 6cb722f..cb96dea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -29,6 +29,8 @@
 import com.android.keyguard.LatencyTracker;
 import com.android.systemui.Dependency;
 import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
 
 /**
  * Controller which coordinates all the fingerprint unlocking actions with the UI.
@@ -99,6 +101,8 @@
     private final UnlockMethodCache mUnlockMethodCache;
     private final Context mContext;
     private int mPendingAuthenticatedUserId = -1;
+    private boolean mPendingShowBouncer;
+    private boolean mHasScreenTurnedOnSinceAuthenticating;
 
     public FingerprintUnlockController(Context context,
             DozeScrimController dozeScrimController,
@@ -110,6 +114,8 @@
         mPowerManager = context.getSystemService(PowerManager.class);
         mUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
         mUpdateMonitor.registerCallback(this);
+        Dependency.get(WakefulnessLifecycle.class).addObserver(mWakefulnessObserver);
+        Dependency.get(ScreenLifecycle.class).addObserver(mScreenObserver);
         mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class);
         mDozeScrimController = dozeScrimController;
         mKeyguardViewMediator = keyguardViewMediator;
@@ -163,18 +169,16 @@
             }
             mHandler.postDelayed(mReleaseFingerprintWakeLockRunnable,
                     FINGERPRINT_WAKELOCK_TIMEOUT_MS);
-            if (mDozeScrimController.isPulsing()) {
-
-                // If we are waking the device up while we are pulsing the clock and the
-                // notifications would light up first, creating an unpleasant animation.
-                // Defer changing the screen brightness by forcing doze brightness on our window
-                // until the clock and the notifications are faded out.
-                mStatusBarWindowManager.setForceDozeBrightness(true);
-            }
         }
         Trace.endSection();
     }
 
+    private boolean pulsingOrAod() {
+        boolean pulsing = mDozeScrimController.isPulsing();
+        boolean dozingWithScreenOn = mStatusBar.isDozing() && !mStatusBar.isScreenFullyOff();
+        return pulsing || dozingWithScreenOn;
+    }
+
     @Override
     public void onFingerprintAuthenticated(int userId) {
         Trace.beginSection("FingerprintUnlockController#onFingerprintAuthenticated");
@@ -183,8 +187,20 @@
             Trace.endSection();
             return;
         }
+        startWakeAndUnlock(calculateMode());
+    }
+
+    public void startWakeAndUnlock(int mode) {
         boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
-        mMode = calculateMode();
+        mMode = mode;
+        mHasScreenTurnedOnSinceAuthenticating = false;
+        if (mMode == MODE_WAKE_AND_UNLOCK_PULSING && pulsingOrAod()) {
+            // If we are waking the device up while we are pulsing the clock and the
+            // notifications would light up first, creating an unpleasant animation.
+            // Defer changing the screen brightness by forcing doze brightness on our window
+            // until the clock and the notifications are faded out.
+            mStatusBarWindowManager.setForceDozeBrightness(true);
+        }
         if (!wasDeviceInteractive) {
             if (DEBUG_FP_WAKELOCK) {
                 Log.i(TAG, "fp wakelock: Authenticated, waking up...");
@@ -206,9 +222,10 @@
                 Trace.beginSection("MODE_UNLOCK or MODE_SHOW_BOUNCER");
                 if (!wasDeviceInteractive) {
                     mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
+                    mPendingShowBouncer = true;
+                } else {
+                    showBouncer();
                 }
-                mStatusBarKeyguardViewManager.animateCollapsePanels(
-                        FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
                 Trace.endSection();
                 break;
             case MODE_WAKE_AND_UNLOCK_PULSING:
@@ -219,6 +236,7 @@
                             true /* allowEnterAnimation */);
                 } else {
                     Trace.beginSection("MODE_WAKE_AND_UNLOCK");
+
                     mDozeScrimController.abortDoze();
                 }
                 mStatusBarWindowManager.setStatusBarFocusable(false);
@@ -234,13 +252,16 @@
             case MODE_NONE:
                 break;
         }
-        if (mMode != MODE_WAKE_AND_UNLOCK_PULSING) {
-            mStatusBarWindowManager.setForceDozeBrightness(false);
-        }
         mStatusBar.notifyFpAuthModeChanged();
         Trace.endSection();
     }
 
+    private void showBouncer() {
+        mStatusBarKeyguardViewManager.animateCollapsePanels(
+                FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
+        mPendingShowBouncer = false;
+    }
+
     @Override
     public void onStartedGoingToSleep(int why) {
         mPendingAuthenticatedUserId = -1;
@@ -263,12 +284,19 @@
         Trace.endSection();
     }
 
+    public boolean hasPendingAuthentication() {
+        return mPendingAuthenticatedUserId != -1
+                && mUpdateMonitor.isUnlockingWithFingerprintAllowed()
+                && mPendingAuthenticatedUserId == KeyguardUpdateMonitor.getCurrentUser();
+    }
+
     public int getMode() {
         return mMode;
     }
 
     private int calculateMode() {
         boolean unlockingAllowed = mUpdateMonitor.isUnlockingWithFingerprintAllowed();
+
         if (!mUpdateMonitor.isDeviceInteractive()) {
             if (!mStatusBarKeyguardViewManager.isShowing()) {
                 return MODE_ONLY_WAKE;
@@ -325,4 +353,26 @@
         }
         mStatusBar.notifyFpAuthModeChanged();
     }
+
+    private final WakefulnessLifecycle.Observer mWakefulnessObserver =
+            new WakefulnessLifecycle.Observer() {
+        @Override
+        public void onFinishedWakingUp() {
+            if (mPendingShowBouncer) {
+                FingerprintUnlockController.this.showBouncer();
+            }
+        }
+    };
+
+    private final ScreenLifecycle.Observer mScreenObserver =
+            new ScreenLifecycle.Observer() {
+                @Override
+                public void onScreenTurnedOn() {
+                    mHasScreenTurnedOnSinceAuthenticating = true;
+                }
+            };
+
+    public boolean hasScreenTurnedOnSinceAuthenticating() {
+        return mHasScreenTurnedOnSinceAuthenticating;
+    }
 }
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 674a61c..df1ffda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -168,8 +168,7 @@
                         distance = mTranslationOnDown + distance;
                         distance = Math.max(0, distance);
                     }
-                    setTranslation(distance, false /* isReset */, false /* animateReset */,
-                            false /* force */);
+                    setTranslation(distance, false /* isReset */, false /* animateReset */);
                 }
                 break;
 
@@ -374,12 +373,11 @@
         targetView.finishAnimation(velocity, mAnimationEndRunnable);
     }
 
-    private void setTranslation(float translation, boolean isReset, boolean animateReset,
-            boolean force) {
+    private void setTranslation(float translation, boolean isReset, boolean animateReset) {
         translation = rightSwipePossible() ? translation : Math.max(0, translation);
         translation = leftSwipePossible() ? translation : Math.min(0, translation);
         float absTranslation = Math.abs(translation);
-        if (translation != mTranslation || isReset || force) {
+        if (translation != mTranslation || isReset) {
             KeyguardAffordanceView targetView = translation > 0 ? mLeftIcon : mRightIcon;
             KeyguardAffordanceView otherView = translation > 0 ? mRightIcon : mLeftIcon;
             float alpha = absTranslation / getMinTranslationAmount();
@@ -394,15 +392,15 @@
             boolean slowAnimation = isReset && isBelowFalsingThreshold();
             if (!isReset) {
                 updateIcon(targetView, radius, alpha + fadeOutAlpha * targetView.getRestingAlpha(),
-                        false, false, force, false);
+                        false, false, false, false);
             } else {
                 updateIcon(targetView, 0.0f, fadeOutAlpha * targetView.getRestingAlpha(),
-                        animateIcons, slowAnimation, force, forceNoCircleAnimation);
+                        animateIcons, slowAnimation, true /* isReset */, forceNoCircleAnimation);
             }
             updateIcon(otherView, 0.0f, fadeOutAlpha * otherView.getRestingAlpha(),
-                    animateIcons, slowAnimation, force, forceNoCircleAnimation);
+                    animateIcons, slowAnimation, isReset, forceNoCircleAnimation);
             updateIcon(mCenterIcon, 0.0f, fadeOutAlpha * mCenterIcon.getRestingAlpha(),
-                    animateIcons, slowAnimation, force, forceNoCircleAnimation);
+                    animateIcons, slowAnimation, isReset, forceNoCircleAnimation);
 
             mTranslation = translation;
         }
@@ -510,12 +508,8 @@
     }
 
     public void reset(boolean animate) {
-        reset(animate, false /* force */);
-    }
-
-    public void reset(boolean animate, boolean force) {
         cancelAnimation();
-        setTranslation(0.0f, true, animate, force);
+        setTranslation(0.0f, true /* isReset */, animate);
         mMotionCancelled = true;
         if (mSwipingInProgress) {
             mCallback.onSwipingAborted();
@@ -523,10 +517,6 @@
         }
     }
 
-    public void resetImmediately() {
-        reset(false /* animate */, true /* force */);
-    }
-
     public boolean isSwipingInProgress() {
         return mSwipingInProgress;
     }
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 6fe8827..6cfa838 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -100,6 +100,7 @@
     public static final String CAMERA_LAUNCH_SOURCE_AFFORDANCE = "lockscreen_affordance";
     public static final String CAMERA_LAUNCH_SOURCE_WIGGLE = "wiggle_gesture";
     public static final String CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = "power_double_tap";
+    public static final String CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER = "lift_to_launch_ml";
 
     public static final String EXTRA_CAMERA_LAUNCH_SOURCE
             = "com.android.systemui.camera_launch_source";
@@ -125,6 +126,7 @@
     private TextView mEnterpriseDisclosure;
     private TextView mIndicationText;
     private ViewGroup mPreviewContainer;
+    private ViewGroup mOverlayContainer;
 
     private View mLeftPreview;
     private View mCameraPreview;
@@ -228,6 +230,7 @@
         super.onFinishInflate();
         mLockPatternUtils = new LockPatternUtils(mContext);
         mPreviewContainer = findViewById(R.id.preview_container);
+        mOverlayContainer = findViewById(R.id.overlay_container);
         mRightAffordanceView = findViewById(R.id.camera_button);
         mLeftAffordanceView = findViewById(R.id.left_button);
         mLockIcon = findViewById(R.id.lock_icon);
@@ -235,10 +238,12 @@
         mEnterpriseDisclosure = findViewById(
                 R.id.keyguard_indication_enterprise_disclosure);
         mIndicationText = findViewById(R.id.keyguard_indication_text);
-        watchForCameraPolicyChanges();
         updateCameraVisibility();
         mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
         mUnlockMethodCache.addListener(this);
+        KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+        mLockIcon.setScreenOn(updateMonitor.isScreenOn());
+        mLockIcon.setDeviceInteractive(updateMonitor.isDeviceInteractive());
         mLockIcon.update();
         setClipChildren(false);
         setClipToPadding(false);
@@ -253,6 +258,7 @@
         mFlashlightController = Dependency.get(FlashlightController.class);
         mAccessibilityController = Dependency.get(AccessibilityController.class);
         mAssistManager = Dependency.get(AssistManager.class);
+        mLockIcon.setAccessibilityController(mAccessibilityController);
         updateLeftAffordance();
     }
 
@@ -274,6 +280,11 @@
                 .withDefault(() -> new DefaultLeftButton())
                 .withCallback(button -> setLeftButton(button))
                 .build();
+        final IntentFilter filter = new IntentFilter();
+        filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
+        getContext().registerReceiverAsUser(mDevicePolicyReceiver,
+                UserHandle.ALL, filter, null, null);
+        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
     }
 
     @Override
@@ -282,6 +293,8 @@
         mAccessibilityController.removeStateChangedCallback(this);
         mRightExtension.destroy();
         mLeftExtension.destroy();
+        getContext().unregisterReceiver(mDevicePolicyReceiver);
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallback);
     }
 
     private void initAccessibility() {
@@ -319,6 +332,7 @@
         lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
         lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
         mLockIcon.setLayoutParams(lp);
+        mLockIcon.setContentDescription(getContext().getText(R.string.accessibility_unlock_button));
         mLockIcon.update(true /* force */);
 
         lp = mLeftAffordanceView.getLayoutParams();
@@ -397,32 +411,6 @@
                 && pm.resolveActivity(PHONE_INTENT, 0) != null;
     }
 
-    private boolean isCameraDisabledByDpm() {
-        final DevicePolicyManager dpm =
-                (DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
-        if (dpm != null && mStatusBar != null) {
-            try {
-                final int userId = ActivityManager.getService().getCurrentUser().id;
-                final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId);
-                final  boolean disabledBecauseKeyguardSecure =
-                        (disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0
-                                && mStatusBar.isKeyguardSecure();
-                return dpm.getCameraDisabled(null) || disabledBecauseKeyguardSecure;
-            } catch (RemoteException e) {
-                Log.e(TAG, "Can't get userId", e);
-            }
-        }
-        return false;
-    }
-
-    private void watchForCameraPolicyChanges() {
-        final IntentFilter filter = new IntentFilter();
-        filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
-        getContext().registerReceiverAsUser(mDevicePolicyReceiver,
-                UserHandle.ALL, filter, null, null);
-        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
-    }
-
     @Override
     public void onStateChanged(boolean accessibilityEnabled, boolean touchExplorationEnabled) {
         mRightAffordanceView.setClickable(touchExplorationEnabled);
@@ -819,8 +807,10 @@
 
         if (dozing) {
             mLockIcon.setVisibility(INVISIBLE);
+            mOverlayContainer.setVisibility(INVISIBLE);
         } else {
             mLockIcon.setVisibility(VISIBLE);
+            mOverlayContainer.setVisibility(VISIBLE);
             if (animate) {
                 startFinishDozeAnimation();
             }
@@ -865,7 +855,8 @@
         @Override
         public IconState getIcon() {
             ResolveInfo resolved = resolveCameraIntent();
-            mIconState.isVisible = !isCameraDisabledByDpm() && resolved != null
+            boolean isCameraDisabled = (mStatusBar != null) && !mStatusBar.isCameraAllowedByAdmin();
+            mIconState.isVisible = !isCameraDisabled && resolved != null
                     && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
                     && mUserSetupComplete;
             mIconState.drawable = mContext.getDrawable(R.drawable.ic_camera_alt_24dp);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 95f32bb..fd95cc4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -234,8 +234,11 @@
     }
 
     protected void ensureView() {
-        mHandler.removeCallbacks(mRemoveViewRunnable);
-        if (mRoot == null) {
+        // Removal of the view might be deferred to reduce unlock latency,
+        // in this case we need to force the removal, otherwise we'll
+        // end up in an unpredictable state.
+        boolean forceRemoval = mHandler.hasCallbacks(mRemoveViewRunnable);
+        if (mRoot == null || forceRemoval) {
             inflateView();
         }
     }
@@ -249,6 +252,7 @@
         mKeyguardView.setViewMediatorCallback(mCallback);
         mContainer.addView(mRoot, mContainer.getChildCount());
         mRoot.setVisibility(View.INVISIBLE);
+        mRoot.dispatchApplyWindowInsets(mRoot.getRootWindowInsets());
     }
 
     protected void removeView() {
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 7370c03..e65bab6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -16,13 +16,14 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.android.systemui.statusbar.notification.NotificationUtils.interpolate;
+
 import android.content.res.Resources;
 import android.graphics.Path;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.PathInterpolator;
 
 import com.android.systemui.R;
-import com.android.systemui.statusbar.notification.NotificationUtils;
 
 /**
  * Utility class to calculate the clock position and top padding of notifications on Keyguard.
@@ -40,6 +41,10 @@
     private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MIN = 1.4f;
     private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MAX = 3.2f;
 
+    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;
+
     private int mClockNotificationsMarginMin;
     private int mClockNotificationsMarginMax;
     private float mClockYFractionMin;
@@ -52,6 +57,8 @@
     private int mKeyguardStatusHeight;
     private float mEmptyDragAmount;
     private float mDensity;
+    private int mBurnInPreventionOffsetX;
+    private int mBurnInPreventionOffsetY;
 
     /**
      * The number (fractional) of notifications the "more" card counts when calculating how many
@@ -71,6 +78,7 @@
     private AccelerateInterpolator mAccelerateInterpolator = new AccelerateInterpolator();
     private int mClockBottom;
     private float mDarkAmount;
+    private int mDozingStackPadding;
 
     /**
      * Refreshes the dimension values.
@@ -86,6 +94,11 @@
                 (float) res.getDimensionPixelSize(R.dimen.notification_shelf_height) /
                         res.getDimensionPixelSize(R.dimen.notification_min_height);
         mDensity = res.getDisplayMetrics().density;
+        mBurnInPreventionOffsetX = res.getDimensionPixelSize(
+                R.dimen.burn_in_prevention_offset_x);
+        mBurnInPreventionOffsetY = res.getDimensionPixelSize(
+                R.dimen.burn_in_prevention_offset_y);
+        mDozingStackPadding = res.getDimensionPixelSize(R.dimen.dozing_stack_padding);
     }
 
     public void setup(int maxKeyguardNotifications, int maxPanelHeight, float expandedHeight,
@@ -122,10 +135,12 @@
                 y + getClockNotificationsPadding() + mKeyguardStatusHeight);
         result.clockAlpha = getClockAlpha(result.clockScale);
 
-        result.stackScrollerPadding = (int) NotificationUtils.interpolate(
+        result.stackScrollerPadding = (int) interpolate(
                 result.stackScrollerPadding,
-                mClockBottom + y,
+                mClockBottom + y + mDozingStackPadding,
                 mDarkAmount);
+
+        result.clockX = (int) interpolate(0, burnInPreventionOffsetX(), mDarkAmount);
     }
 
     private float getClockScale(int notificationPadding, int clockY, int startPadding) {
@@ -154,9 +169,39 @@
     private int getClockY() {
         // Dark: Align the bottom edge of the clock at one third:
         // clockBottomEdge = result - mKeyguardStatusHeight / 2 + mClockBottom
-        float clockYDark = (0.33f * mHeight + (float) mKeyguardStatusHeight / 2 - mClockBottom);
+        float clockYDark = (0.33f * mHeight + (float) mKeyguardStatusHeight / 2 - mClockBottom)
+                + burnInPreventionOffsetY();
         float clockYRegular = getClockYFraction() * mHeight;
-        return (int) NotificationUtils.interpolate(clockYRegular, clockYDark, mDarkAmount);
+        return (int) interpolate(clockYRegular, clockYDark, mDarkAmount);
+    }
+
+    private float burnInPreventionOffsetY() {
+        return zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES,
+                mBurnInPreventionOffsetY * 2,
+                BURN_IN_PREVENTION_PERIOD_Y)
+                - mBurnInPreventionOffsetY;
+    }
+
+    private float burnInPreventionOffsetX() {
+        return zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES,
+                mBurnInPreventionOffsetX * 2,
+                BURN_IN_PREVENTION_PERIOD_X)
+                - 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);
     }
 
     private float getClockYExpansionAdjustment() {
@@ -230,5 +275,8 @@
          * the padding, but not the overall panel size.
          */
         public int stackScrollerPaddingAdjustment;
+
+        /** The x translation of the clock. */
+        public int clockX;
     }
 }
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 42b09df..a6691b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -16,35 +16,48 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.annotation.ColorInt;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.settingslib.Utils;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSPanel;
+import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
+import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
+import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener;
+import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 
 /**
  * The header group on Keyguard.
  */
 public class KeyguardStatusBarView extends RelativeLayout
-        implements BatteryStateChangeCallback, OnUserInfoChangedListener {
+        implements BatteryStateChangeCallback, OnUserInfoChangedListener, ConfigurationListener {
 
     private boolean mBatteryCharging;
     private boolean mKeyguardUserSwitcherShowing;
@@ -63,6 +76,7 @@
     private int mSystemIconsSwitcherHiddenExpandedMargin;
     private int mSystemIconsBaseMargin;
     private View mSystemIconsContainer;
+    private TintedIconManager mIconManager;
 
     public KeyguardStatusBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -203,12 +217,18 @@
         mUserSwitcherController = Dependency.get(UserSwitcherController.class);
         mMultiUserSwitch.setUserSwitcherController(mUserSwitcherController);
         userInfoController.reloadUserInfo();
+        Dependency.get(ConfigurationController.class).addCallback(this);
+        mIconManager = new TintedIconManager(findViewById(R.id.statusIcons));
+        Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager);
+        onOverlayChanged();
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         Dependency.get(UserInfoController.class).removeCallback(this);
+        Dependency.get(StatusBarIconController.class).removeIconGroup(mIconManager);
+        Dependency.get(ConfigurationController.class).removeCallback(this);
     }
 
     @Override
@@ -312,4 +332,30 @@
     public boolean hasOverlappingRendering() {
         return false;
     }
+
+    public void onOverlayChanged() {
+        @ColorInt int textColor = Utils.getColorAttr(mContext, R.attr.wallpaperTextColor);
+        @ColorInt int iconColor = Utils.getDefaultColor(mContext, Color.luminance(textColor) < 0.5 ?
+                R.color.dark_mode_icon_color_single_tone :
+                R.color.light_mode_icon_color_single_tone);
+        float intensity = textColor == Color.WHITE ? 0 : 1;
+        mCarrierLabel.setTextColor(iconColor);
+        mBatteryView.setFillColor(iconColor);
+        mIconManager.setTint(iconColor);
+        Rect tintArea = new Rect(0, 0, 0, 0);
+
+        applyDarkness(R.id.signal_cluster, tintArea, intensity, iconColor);
+        applyDarkness(R.id.battery, tintArea, intensity, iconColor);
+        applyDarkness(R.id.clock, tintArea, intensity, iconColor);
+        // Reload user avatar
+        ((UserInfoControllerImpl) Dependency.get(UserInfoController.class))
+                .onDensityOrFontScaleChanged();
+    }
+
+    private void applyDarkness(int id, Rect tintArea, float intensity, int color) {
+        View v = findViewById(id);
+        if (v instanceof DarkReceiver) {
+            ((DarkReceiver) v).onDarkChanged(tintArea, intensity, color);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index 9d699cf..917a56f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -16,11 +16,16 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.app.WallpaperColors;
+import android.content.Context;
+import android.graphics.Color;
 import android.graphics.Rect;
 import android.view.View;
 
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
+import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.DarkIconDispatcher;
 
@@ -49,6 +54,7 @@
     private boolean mDockedLight;
     private int mLastStatusBarMode;
     private int mLastNavigationBarMode;
+    private final Color mDarkModeColor;
 
     /**
      * Whether the navigation bar should be light factoring in already how much alpha the scrim has
@@ -61,12 +67,14 @@
      */
     private boolean mHasLightNavigationBar;
     private boolean mScrimAlphaBelowThreshold;
+    private boolean mInvertLightNavBarWithScrim;
     private float mScrimAlpha;
 
     private final Rect mLastFullscreenBounds = new Rect();
     private final Rect mLastDockedBounds = new Rect();
 
-    public LightBarController() {
+    public LightBarController(Context ctx) {
+        mDarkModeColor = Color.valueOf(ctx.getColor(R.color.dark_mode_icon_color_single_tone));
         mStatusBarIconController = Dependency.get(DarkIconDispatcher.class);
         mBatteryController = Dependency.get(BatteryController.class);
         mBatteryController.addCallback(this);
@@ -74,6 +82,7 @@
 
     public void setNavigationBar(LightBarTransitionsController navigationBar) {
         mNavigationBarController = navigationBar;
+        updateNavigation();
     }
 
     public void setFingerprintUnlockController(
@@ -119,7 +128,8 @@
             boolean last = mNavigationLight;
             mHasLightNavigationBar = isLight(vis, navigationBarMode,
                     View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
-            mNavigationLight = mHasLightNavigationBar && mScrimAlphaBelowThreshold;
+            mNavigationLight = mHasLightNavigationBar
+                    && (mScrimAlphaBelowThreshold || !mInvertLightNavBarWithScrim);
             if (mNavigationLight != last) {
                 updateNavigation();
             }
@@ -145,6 +155,15 @@
         }
     }
 
+    public void setScrimColor(GradientColors colors) {
+        boolean invertLightNavBarWithScrimBefore = mInvertLightNavBarWithScrim;
+        mInvertLightNavBarWithScrim = !colors.supportsDarkText();
+        if (mHasLightNavigationBar
+                && invertLightNavBarWithScrimBefore != mInvertLightNavBarWithScrim) {
+            reevaluate();
+        }
+    }
+
     private boolean isLight(int vis, int barMode, int flag) {
         boolean isTransparentBar = (barMode == MODE_TRANSPARENT
                 || barMode == MODE_LIGHTS_OUT_TRANSPARENT);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
index 6bd959f..b0ac6ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
@@ -23,8 +23,8 @@
 import android.os.SystemClock;
 import android.util.TimeUtils;
 
-import com.android.systemui.Dumpable;
 import com.android.systemui.Dependency;
+import com.android.systemui.Dumpable;
 import com.android.systemui.Interpolators;
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.statusbar.CommandQueue;
@@ -55,7 +55,6 @@
     private ValueAnimator mTintAnimator;
     private float mDarkIntensity;
     private float mNextDarkIntensity;
-
     private final Runnable mTransitionDeferringDoneRunnable = new Runnable() {
         @Override
         public void run() {
@@ -130,6 +129,7 @@
     public void setIconsDark(boolean dark, boolean animate) {
         if (!animate) {
             setIconTintInternal(dark ? 1.0f : 0.0f);
+            mNextDarkIntensity = dark ? 1.0f : 0.0f;
         } else if (mTransitionPending) {
             deferIconTintChange(dark ? 1.0f : 0.0f);
         } else if (mTransitionDeferring) {
@@ -155,19 +155,19 @@
 
     private void animateIconTint(float targetDarkIntensity, long delay,
             long duration) {
+        if (mNextDarkIntensity == targetDarkIntensity) {
+            return;
+        }
         if (mTintAnimator != null) {
             mTintAnimator.cancel();
         }
-        if (mDarkIntensity == targetDarkIntensity) {
-            return;
-        }
         mNextDarkIntensity = targetDarkIntensity;
         mTintAnimator = ValueAnimator.ofFloat(mDarkIntensity, targetDarkIntensity);
         mTintAnimator.addUpdateListener(
                 animation -> setIconTintInternal((Float) animation.getAnimatedValue()));
         mTintAnimator.setDuration(duration);
         mTintAnimator.setStartDelay(delay);
-        mTintAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+        mTintAnimator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
         mTintAnimator.start();
     }
 
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 bccc5d5..c241290 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -178,7 +178,7 @@
                     : 0);
             setRestingAlpha(
                     anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
-            setImageDrawable(icon);
+            setImageDrawable(icon, false);
             mHasFingerPrintIcon = anyFingerprintIcon;
             if (animation != null && isAnim) {
                 animation.forceAnimationOnUI();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
index 99b3aa8..87f5ca7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
@@ -36,6 +36,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.app.WallpaperColors;
 import android.util.Log;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
@@ -156,6 +157,11 @@
         postUpdateWallpaper();
     }
 
+    @Override
+    public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId) {
+
+    }
+
     private void postUpdateWallpaper() {
         mH.removeCallbacks(this);
         mH.post(this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index c30bb9a..f393dcd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -30,6 +30,8 @@
 import android.widget.FrameLayout;
 
 import com.android.systemui.Dependency;
+import com.android.systemui.Prefs;
+import com.android.systemui.Prefs.Key;
 import com.android.systemui.R;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.DetailAdapter;
@@ -74,7 +76,8 @@
         if (mUserListener == null) {
             return false;
         }
-        return mUserListener.getUserCount() != 0;
+        return mUserListener.getUserCount() != 0
+                && Prefs.getBoolean(getContext(), Key.SEEN_MULTI_USER, false);
     }
 
     public void setUserSwitcherController(UserSwitcherController userSwitcherController) {
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 d047fa9..fbad937 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -45,7 +45,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
-import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -94,7 +93,7 @@
  */
 public class NavigationBarFragment extends Fragment implements Callbacks {
 
-    private static final String TAG = "NavigationBar";
+    public static final String TAG = "NavigationBar";
     private static final boolean DEBUG = false;
     private static final String EXTRA_DISABLE_STATE = "disabled_state";
 
@@ -202,8 +201,7 @@
         IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
         filter.addAction(Intent.ACTION_SCREEN_ON);
         getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
-        PowerManager pm = getContext().getSystemService(PowerManager.class);
-        notifyNavigationBarScreenOn(pm.isScreenOn());
+        notifyNavigationBarScreenOn();
     }
 
     @Override
@@ -378,8 +376,8 @@
                 ((View) mNavigationBarView.getParent()).getLayoutParams());
     }
 
-    private void notifyNavigationBarScreenOn(boolean screenOn) {
-        mNavigationBarView.notifyScreenOn(screenOn);
+    private void notifyNavigationBarScreenOn() {
+        mNavigationBarView.notifyScreenOn();
     }
 
     private void prepareNavigationBarView() {
@@ -604,10 +602,6 @@
         return mNavigationBarMode == MODE_SEMI_TRANSPARENT;
     }
 
-    public void onKeyguardOccludedChanged(boolean keyguardOccluded) {
-        mNavigationBarView.onKeyguardOccludedChanged(keyguardOccluded);
-    }
-
     public void disableAnimationsDuringHide(long delay) {
         mNavigationBarView.setLayoutTransitionsEnabled(false);
         mNavigationBarView.postDelayed(() -> mNavigationBarView.setLayoutTransitionsEnabled(true),
@@ -663,10 +657,9 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
-            if (Intent.ACTION_SCREEN_OFF.equals(action)) {
-                notifyNavigationBarScreenOn(false);
-            } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
-                notifyNavigationBarScreenOn(true);
+            if (Intent.ACTION_SCREEN_OFF.equals(action)
+                    || Intent.ACTION_SCREEN_ON.equals(action)) {
+                notifyNavigationBarScreenOn();
             }
         }
     };
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 720ca14..aaa31b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -19,9 +19,11 @@
 import android.content.res.Configuration;
 import android.graphics.drawable.Icon;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.Display.Mode;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -35,6 +37,7 @@
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider;
+import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseFrameLayout;
 import com.android.systemui.statusbar.policy.KeyButtonView;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
@@ -43,6 +46,8 @@
 import java.util.List;
 import java.util.Objects;
 
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
 public class NavigationBarInflaterView extends FrameLayout
         implements Tunable, PluginListener<NavBarButtonProvider> {
 
@@ -71,6 +76,8 @@
     public static final String KEY_CODE_START = "(";
     public static final String KEY_IMAGE_DELIM = ":";
     public static final String KEY_CODE_END = ")";
+    private static final String WEIGHT_SUFFIX = "W";
+    private static final String WEIGHT_CENTERED_SUFFIX = "WC";
 
     private final List<NavBarButtonProvider> mPlugins = new ArrayList<>();
 
@@ -219,26 +226,27 @@
         String[] center = sets[1].split(BUTTON_SEPARATOR);
         String[] end = sets[2].split(BUTTON_SEPARATOR);
         // Inflate these in start to end order or accessibility traversal will be messed up.
-        inflateButtons(start, (ViewGroup) mRot0.findViewById(R.id.ends_group), isRot0Landscape);
-        inflateButtons(start, (ViewGroup) mRot90.findViewById(R.id.ends_group), !isRot0Landscape);
+        inflateButtons(start, mRot0.findViewById(R.id.ends_group), isRot0Landscape, true);
+        inflateButtons(start, mRot90.findViewById(R.id.ends_group), !isRot0Landscape, true);
 
-        inflateButtons(center, (ViewGroup) mRot0.findViewById(R.id.center_group), isRot0Landscape);
-        inflateButtons(center, (ViewGroup) mRot90.findViewById(R.id.center_group), !isRot0Landscape);
+        inflateButtons(center, mRot0.findViewById(R.id.center_group), isRot0Landscape, false);
+        inflateButtons(center, mRot90.findViewById(R.id.center_group), !isRot0Landscape, false);
 
-        addGravitySpacer((LinearLayout) mRot0.findViewById(R.id.ends_group));
-        addGravitySpacer((LinearLayout) mRot90.findViewById(R.id.ends_group));
+        addGravitySpacer(mRot0.findViewById(R.id.ends_group));
+        addGravitySpacer(mRot90.findViewById(R.id.ends_group));
 
-        inflateButtons(end, (ViewGroup) mRot0.findViewById(R.id.ends_group), isRot0Landscape);
-        inflateButtons(end, (ViewGroup) mRot90.findViewById(R.id.ends_group), !isRot0Landscape);
+        inflateButtons(end, mRot0.findViewById(R.id.ends_group), isRot0Landscape, false);
+        inflateButtons(end, mRot90.findViewById(R.id.ends_group), !isRot0Landscape, false);
     }
 
     private void addGravitySpacer(LinearLayout layout) {
         layout.addView(new Space(mContext), new LinearLayout.LayoutParams(0, 0, 1));
     }
 
-    private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape) {
+    private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape,
+            boolean start) {
         for (int i = 0; i < buttons.length; i++) {
-            inflateButton(buttons[i], parent, landscape);
+            inflateButton(buttons[i], parent, landscape, start);
         }
     }
 
@@ -251,40 +259,66 @@
     }
 
     @Nullable
-    protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape) {
+    protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape,
+            boolean start) {
         LayoutInflater inflater = landscape ? mLandscapeInflater : mLayoutInflater;
-        float size = extractSize(buttonSpec);
-        View v = createView(buttonSpec, parent, inflater, landscape);
+        View v = createView(buttonSpec, parent, inflater);
         if (v == null) return null;
 
-        if (size != 0) {
-            ViewGroup.LayoutParams params = v.getLayoutParams();
-            params.width = (int) (params.width * size);
-        }
+        v = applySize(v, buttonSpec, landscape, start);
         parent.addView(v);
         addToDispatchers(v);
         View lastView = landscape ? mLastLandscape : mLastPortrait;
+        View accessibilityView = v;
+        if (v instanceof ReverseFrameLayout) {
+            accessibilityView = ((ReverseFrameLayout) v).getChildAt(0);
+        }
         if (lastView != null) {
-            v.setAccessibilityTraversalAfter(lastView.getId());
+            accessibilityView.setAccessibilityTraversalAfter(lastView.getId());
         }
         if (landscape) {
-            mLastLandscape = v;
+            mLastLandscape = accessibilityView;
         } else {
-            mLastPortrait = v;
+            mLastPortrait = accessibilityView;
         }
         return v;
     }
 
-    private View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater,
-            boolean landscape) {
+    private View applySize(View v, String buttonSpec, boolean landscape, boolean start) {
+        String sizeStr = extractSize(buttonSpec);
+        if (sizeStr == null) return v;
+
+        if (sizeStr.contains(WEIGHT_SUFFIX)) {
+            float weight = Float.parseFloat(sizeStr.substring(0, sizeStr.indexOf(WEIGHT_SUFFIX)));
+            FrameLayout frame = new ReverseFrameLayout(mContext);
+            LayoutParams childParams = new LayoutParams(v.getLayoutParams());
+            if (sizeStr.endsWith(WEIGHT_CENTERED_SUFFIX)) {
+                childParams.gravity = Gravity.CENTER;
+            } else {
+                childParams.gravity = landscape ? (start ? Gravity.BOTTOM : Gravity.TOP)
+                        : (start ? Gravity.START : Gravity.END);
+            }
+            frame.addView(v, childParams);
+            frame.setLayoutParams(new LinearLayout.LayoutParams(0, MATCH_PARENT, weight));
+            frame.setClipChildren(false);
+            frame.setClipToPadding(false);
+            return frame;
+        }
+        float size = Float.parseFloat(sizeStr);
+        ViewGroup.LayoutParams params = v.getLayoutParams();
+        params.width = (int) (params.width * size);
+        return v;
+    }
+
+    private View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater) {
         View v = null;
         String button = extractButton(buttonSpec);
         if (LEFT.equals(button)) {
-            buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, NAVSPACE);
-            button = extractButton(buttonSpec);
+            String s = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, NAVSPACE);
+            button = extractButton(s);
         } else if (RIGHT.equals(button)) {
-            buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT, MENU_IME);
-            button = extractButton(buttonSpec);
+            String s = Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT, MENU_IME);
+            button = extractButton(s);
         }
         // Let plugins go first so they can override a standard view if they want.
         for (NavBarButtonProvider provider : mPlugins) {
@@ -340,13 +374,12 @@
         return Integer.parseInt(subStr);
     }
 
-    public static float extractSize(String buttonSpec) {
+    public static String extractSize(String buttonSpec) {
         if (!buttonSpec.contains(SIZE_MOD_START)) {
-            return 1;
+            return null;
         }
         final int sizeStart = buttonSpec.indexOf(SIZE_MOD_START);
-        String sizeStr = buttonSpec.substring(sizeStart + 1, buttonSpec.indexOf(SIZE_MOD_END));
-        return Float.parseFloat(sizeStr);
+        return buttonSpec.substring(sizeStart + 1, buttonSpec.indexOf(SIZE_MOD_END));
     }
 
     public static String extractButton(String buttonSpec) {
@@ -379,8 +412,8 @@
                 mButtonDispatchers.valueAt(i).clear();
             }
         }
-        clearAllChildren((ViewGroup) mRot0.findViewById(R.id.nav_buttons));
-        clearAllChildren((ViewGroup) mRot90.findViewById(R.id.nav_buttons));
+        clearAllChildren(mRot0.findViewById(R.id.nav_buttons));
+        clearAllChildren(mRot90.findViewById(R.id.nav_buttons));
     }
 
     private void clearAllChildren(ViewGroup group) {
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 0557cb1..d116bbf3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -59,6 +59,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.function.Consumer;
 
 public class NavigationBarView extends FrameLayout implements PluginListener<NavGesture> {
     final static boolean DEBUG = false;
@@ -74,7 +75,6 @@
     View[] mRotatedViews = new View[4];
 
     boolean mVertical;
-    boolean mScreenOn;
     private int mCurrentRotation = -1;
 
     boolean mShowMenu;
@@ -317,7 +317,8 @@
             mDockedIcon = getDrawable(ctx,
                     R.drawable.ic_sysbar_docked, R.drawable.ic_sysbar_docked_dark);
         }
-        if (oldConfig.densityDpi != newConfig.densityDpi) {
+        if (oldConfig.densityDpi != newConfig.densityDpi
+                || oldConfig.getLayoutDirection() != newConfig.getLayoutDirection()) {
             mBackIcon = getDrawable(ctx, R.drawable.ic_sysbar_back, R.drawable.ic_sysbar_back_dark);
             mBackLandIcon = mBackIcon;
             mBackAltIcon = getDrawable(ctx,
@@ -364,8 +365,7 @@
         super.setLayoutDirection(layoutDirection);
     }
 
-    public void notifyScreenOn(boolean screenOn) {
-        mScreenOn = screenOn;
+    public void notifyScreenOn() {
         setDisabledFlags(mDisabledFlags, true);
     }
 
@@ -565,10 +565,7 @@
 
         getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
 
-        DockedStackExistsListener.register(exists -> mHandler.post(() -> {
-            mDockedStackExists = exists;
-            updateRecentsIcon();
-        }));
+        DockedStackExistsListener.register(mDockedListener);
     }
 
     void updateRotatedViews() {
@@ -630,9 +627,6 @@
         getHomeButton().setVertical(mVertical);
     }
 
-    public void onKeyguardOccludedChanged(boolean keyguardOccluded) {
-    }
-
     private void updateTaskSwitchHelper() {
         if (mGestureHelper == null) return;
         boolean isRtl = (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
@@ -669,7 +663,8 @@
         updateTaskSwitchHelper();
         updateIcons(getContext(), mConfiguration, newConfig);
         updateRecentsIcon();
-        if (uiCarModeChanged || mConfiguration.densityDpi != newConfig.densityDpi) {
+        if (uiCarModeChanged || mConfiguration.densityDpi != newConfig.densityDpi
+                || mConfiguration.getLayoutDirection() != newConfig.getLayoutDirection()) {
             // If car mode or density changes, we need to reset the icons.
             setNavigationIconHints(mNavigationIconHints, true);
         }
@@ -836,4 +831,8 @@
         void onVerticalChanged(boolean isVertical);
     }
 
+    private final Consumer<Boolean> mDockedListener = exists -> mHandler.post(() -> {
+        mDockedStackExists = exists;
+        updateRecentsIcon();
+    });
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java
new file mode 100644
index 0000000..004a604
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java
@@ -0,0 +1,115 @@
+/*
+ * 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.statusbar.phone;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.support.annotation.VisibleForTesting;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Pair;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import com.android.systemui.R;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+
+/**
+ * Redirects touches that aren't handled by any child view to the nearest
+ * clickable child. Only takes effect on <sw600dp.
+ */
+public class NearestTouchFrame extends FrameLayout {
+
+    private final ArrayList<View> mClickableChildren = new ArrayList<>();
+    private final boolean mIsActive;
+    private final int[] mTmpInt = new int[2];
+    private final int[] mOffset = new int[2];
+    private View mTouchingChild;
+
+    public NearestTouchFrame(Context context, AttributeSet attrs) {
+        this(context, attrs, context.getResources().getConfiguration());
+    }
+
+    @VisibleForTesting
+    NearestTouchFrame(Context context, AttributeSet attrs, Configuration c) {
+        super(context, attrs);
+        mIsActive = c.smallestScreenWidthDp < 600;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        mClickableChildren.clear();
+        addClickableChildren(this);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        getLocationInWindow(mOffset);
+    }
+
+    private void addClickableChildren(ViewGroup group) {
+        final int N = group.getChildCount();
+        for (int i = 0; i < N; i++) {
+            View child = group.getChildAt(i);
+            if (child.isClickable()) {
+                mClickableChildren.add(child);
+            } else if (child instanceof ViewGroup) {
+                addClickableChildren((ViewGroup) child);
+            }
+        }
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        if (mIsActive) {
+            if (event.getAction() == MotionEvent.ACTION_DOWN) {
+                mTouchingChild = findNearestChild(event);
+            }
+            if (mTouchingChild != null) {
+                event.offsetLocation(mTouchingChild.getWidth() / 2 - event.getX(),
+                        mTouchingChild.getHeight() / 2 - event.getY());
+                return mTouchingChild.dispatchTouchEvent(event);
+            }
+        }
+        return super.onTouchEvent(event);
+    }
+
+    private View findNearestChild(MotionEvent event) {
+        return mClickableChildren.stream().map(v -> new Pair<>(distance(v, event), v))
+                .min(Comparator.comparingInt(f -> f.first)).get().second;
+    }
+
+    private int distance(View v, MotionEvent event) {
+        v.getLocationInWindow(mTmpInt);
+        int left = mTmpInt[0] - mOffset[0];
+        int top = mTmpInt[1] - mOffset[1];
+        int right = left + v.getWidth();
+        int bottom = top + v.getHeight();
+
+        int x = Math.min(Math.abs(left - (int) event.getX()),
+                Math.abs((int) event.getX() - right));
+        int y = Math.min(Math.abs(top - (int) event.getY()),
+                Math.abs((int) event.getY() - bottom));
+
+        return Math.max(x, y);
+    }
+}
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 dd84dea..b75c7e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -18,6 +18,7 @@
 
 import android.service.notification.StatusBarNotification;
 import android.support.annotation.Nullable;
+import android.util.Log;
 
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.NotificationData;
@@ -29,7 +30,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 
@@ -38,6 +38,7 @@
  */
 public class NotificationGroupManager implements OnHeadsUpChangedListener {
 
+    private static final String TAG = "NotificationGroupManager";
     private final HashMap<String, NotificationGroup> mGroupMap = new HashMap<>();
     private OnGroupChangeListener mListener;
     private int mBarState = -1;
@@ -96,7 +97,7 @@
             return;
         }
         if (isGroupChild(sbn)) {
-            group.children.remove(removed);
+            group.children.remove(removed.key);
         } else {
             group.summary = null;
         }
@@ -109,6 +110,9 @@
     }
 
     public void onEntryAdded(final NotificationData.Entry added) {
+        if (added.row.isRemoved()) {
+            added.setDebugThrowable(new Throwable());
+        }
         final StatusBarNotification sbn = added.notification;
         boolean isGroupChild = isGroupChild(sbn);
         String groupKey = getGroupKey(sbn);
@@ -118,15 +122,25 @@
             mGroupMap.put(groupKey, group);
         }
         if (isGroupChild) {
-            group.children.add(added);
+            NotificationData.Entry existing = group.children.get(added.key);
+            if (existing != null && existing != added) {
+                Throwable existingThrowable = existing.getDebugThrowable();
+                Log.wtf(TAG, "Inconsistent entries found with the same key " + added.key
+                        + "existing removed: " + existing.row.isRemoved()
+                        + (existingThrowable != null
+                                ? Log.getStackTraceString(existingThrowable) + "\n": "")
+                        + " added removed" + added.row.isRemoved()
+                        , new Throwable());
+            }
+            group.children.put(added.key, added);
             updateSuppression(group);
         } else {
             group.summary = added;
             group.expanded = added.row.areChildrenExpanded();
             updateSuppression(group);
             if (!group.children.isEmpty()) {
-                HashSet<NotificationData.Entry> childrenCopy =
-                        (HashSet<NotificationData.Entry>) group.children.clone();
+                ArrayList<NotificationData.Entry> childrenCopy
+                        = new ArrayList<>(group.children.values());
                 for (NotificationData.Entry child : childrenCopy) {
                     onEntryBecomingChild(child);
                 }
@@ -410,7 +424,8 @@
         // The parent of a suppressed group got huned, lets hun the child!
         NotificationGroup notificationGroup = mGroupMap.get(sbn.getGroupKey());
         if (notificationGroup != null) {
-            Iterator<NotificationData.Entry> iterator = notificationGroup.children.iterator();
+            Iterator<NotificationData.Entry> iterator
+                    = notificationGroup.children.values().iterator();
             NotificationData.Entry child = iterator.hasNext() ? iterator.next() : null;
             if (child == null) {
                 child = getIsolatedChild(sbn.getGroupKey());
@@ -463,7 +478,7 @@
     }
 
     public static class NotificationGroup {
-        public final HashSet<NotificationData.Entry> children = new HashSet<>();
+        public final HashMap<String, NotificationData.Entry> children = new HashMap<>();
         public NotificationData.Entry summary;
         public boolean expanded;
         /**
@@ -474,10 +489,16 @@
         @Override
         public String toString() {
             String result = "    summary:\n      "
-                    + (summary != null ? summary.notification : "null");
+                    + (summary != null ? summary.notification : "null")
+                    + (summary != null && summary.getDebugThrowable() != null
+                            ? Log.getStackTraceString(summary.getDebugThrowable())
+                            : "");
             result += "\n    children size: " + children.size();
-            for (NotificationData.Entry child : children) {
-                result += "\n      " + child.notification;
+            for (NotificationData.Entry child : children.values()) {
+                result += "\n      " + child.notification
+                + (child.getDebugThrowable() != null
+                        ? Log.getStackTraceString(child.getDebugThrowable())
+                        : "");
             }
             return result;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 5bfdd1f..41a69b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -280,4 +280,9 @@
             v.setDecorColor(mIconTint);
         }
     }
+
+    public void setDark(boolean dark) {
+        mNotificationIcons.setDark(dark, false, 0);
+        mShelfIcons.setDark(dark, false, 0);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index a4fadc4..6f5ad96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -123,6 +123,7 @@
     private boolean mDisallowNextAnimation;
     private boolean mAnimationsEnabled = true;
     private ArrayMap<String, ArrayList<StatusBarIcon>> mReplacingIcons;
+    private int mDarkOffsetX;
 
     public NotificationIconContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -389,6 +390,14 @@
                 iconState.xTranslation = getWidth() - iconState.xTranslation - view.getWidth();
             }
         }
+
+        if (mDark && mDarkOffsetX != 0) {
+            for (int i = 0; i < childCount; i++) {
+                View view = getChildAt(i);
+                IconState iconState = mIconStates.get(view);
+                iconState.xTranslation += mDarkOffsetX;
+            }
+        }
     }
 
     private float getLayoutEnd() {
@@ -512,7 +521,12 @@
         mReplacingIcons = replacingIcons;
     }
 
+    public void setDarkOffsetX(int offsetX) {
+        mDarkOffsetX = offsetX;
+    }
+
     public class IconState extends ViewState {
+        public static final int NO_VALUE = NotificationIconContainer.NO_VALUE;
         public float iconAppearAmount = 1.0f;
         public float clampedAppearAmount = 1.0f;
         public int visibleState;
@@ -525,6 +539,8 @@
         public boolean justUndarkened;
         public int iconColor = StatusBarIconView.NO_COLOR;
         public boolean noAnimations;
+        public boolean isLastExpandIcon;
+        public int customTransformHeight = NO_VALUE;
 
         @Override
         public void applyToView(View view) {
@@ -602,6 +618,10 @@
             justUndarkened = false;
         }
 
+        public boolean hasCustomTransformHeight() {
+            return isLastExpandIcon && customTransformHeight != NO_VALUE;
+        }
+
         @Override
         public void initFrom(View view) {
             super.initFrom(view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationListenerWithPlugins.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationListenerWithPlugins.java
new file mode 100644
index 0000000..9ff907b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationListenerWithPlugins.java
@@ -0,0 +1,152 @@
+/*
+ * 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.statusbar.phone;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.RemoteException;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+
+import com.android.systemui.Dependency;
+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 java.util.ArrayList;
+
+/**
+ * A version of NotificationListenerService that passes all info to
+ * any plugins connected. Also allows those plugins the chance to cancel
+ * any incoming callbacks or to trigger new ones.
+ */
+public class NotificationListenerWithPlugins extends NotificationListenerService implements
+        PluginListener<NotificationListenerController> {
+
+    private ArrayList<NotificationListenerController> mPlugins = new ArrayList<>();
+    private boolean mConnected;
+
+    @Override
+    public void registerAsSystemService(Context context, ComponentName componentName,
+            int currentUser) throws RemoteException {
+        super.registerAsSystemService(context, componentName, currentUser);
+        Dependency.get(PluginManager.class).addPluginListener(this,
+                NotificationListenerController.class);
+    }
+
+    @Override
+    public void unregisterAsSystemService() throws RemoteException {
+        super.unregisterAsSystemService();
+        Dependency.get(PluginManager.class).removePluginListener(this);
+    }
+
+    @Override
+    public StatusBarNotification[] getActiveNotifications() {
+        StatusBarNotification[] activeNotifications = super.getActiveNotifications();
+        for (NotificationListenerController plugin : mPlugins) {
+            activeNotifications = plugin.getActiveNotifications(activeNotifications);
+        }
+        return activeNotifications;
+    }
+
+    @Override
+    public RankingMap getCurrentRanking() {
+        RankingMap currentRanking = super.getCurrentRanking();
+        for (NotificationListenerController plugin : mPlugins) {
+            currentRanking = plugin.getCurrentRanking(currentRanking);
+        }
+        return currentRanking;
+    }
+
+    public void onPluginConnected() {
+        mConnected = true;
+        mPlugins.forEach(p -> p.onListenerConnected(getProvider()));
+    }
+
+    /**
+     * Called when listener receives a onNotificationPosted.
+     * Returns true to indicate this callback should be skipped.
+     */
+    public boolean onPluginNotificationPosted(StatusBarNotification sbn,
+            final RankingMap rankingMap) {
+        for (NotificationListenerController plugin : mPlugins) {
+            if (plugin.onNotificationPosted(sbn, rankingMap)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called when listener receives a onNotificationRemoved.
+     * Returns true to indicate this callback should be skipped.
+     */
+    public boolean onPluginNotificationRemoved(StatusBarNotification sbn,
+            final RankingMap rankingMap) {
+        for (NotificationListenerController plugin : mPlugins) {
+            if (plugin.onNotificationRemoved(sbn, rankingMap)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public RankingMap onPluginRankingUpdate(RankingMap rankingMap) {
+        return getCurrentRanking();
+    }
+
+    @Override
+    public void onPluginConnected(NotificationListenerController plugin, Context pluginContext) {
+        mPlugins.add(plugin);
+        if (mConnected) {
+            plugin.onListenerConnected(getProvider());
+        }
+    }
+
+    @Override
+    public void onPluginDisconnected(NotificationListenerController plugin) {
+        mPlugins.remove(plugin);
+    }
+
+    private NotificationProvider getProvider() {
+        return new NotificationProvider() {
+            @Override
+            public StatusBarNotification[] getActiveNotifications() {
+                return NotificationListenerWithPlugins.super.getActiveNotifications();
+            }
+
+            @Override
+            public RankingMap getRankingMap() {
+                return NotificationListenerWithPlugins.super.getCurrentRanking();
+            }
+
+            @Override
+            public void addNotification(StatusBarNotification sbn) {
+                onNotificationPosted(sbn, getRankingMap());
+            }
+
+            @Override
+            public void removeNotification(StatusBarNotification sbn) {
+                onNotificationRemoved(sbn, getRankingMap());
+            }
+
+            @Override
+            public void updateRanking() {
+                onNotificationRankingUpdate(getRankingMap());
+            }
+        };
+    }
+}
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 6aab8e1..cca6ae0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -18,6 +18,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.app.ActivityManager;
@@ -26,6 +27,7 @@
 import android.content.Context;
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
@@ -33,6 +35,7 @@
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.MathUtils;
+import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
@@ -41,7 +44,6 @@
 import android.view.WindowInsets;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.FrameLayout;
-import android.widget.TextView;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -58,7 +60,9 @@
 import com.android.systemui.statusbar.FlingAnimationUtils;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
+import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -111,7 +115,6 @@
     private QS mQs;
     private FrameLayout mQsFrame;
     private KeyguardStatusView mKeyguardStatusView;
-    private TextView mClockView;
     private View mReserveNotificationSpace;
     private View mQsNavbarScrim;
     protected NotificationsQuickSettingsContainer mNotificationContainerParent;
@@ -163,8 +166,9 @@
     private int mUnlockMoveDistance;
     private float mEmptyDragAmount;
 
-    private ObjectAnimator mClockAnimator;
-    private int mClockAnimationTarget = -1;
+    private Animator mClockAnimator;
+    private int mClockAnimationTargetX = Integer.MIN_VALUE;
+    private int mClockAnimationTargetY = Integer.MIN_VALUE;
     private int mTopPaddingAdjustment;
     private KeyguardClockPositionAlgorithm mClockPositionAlgorithm =
             new KeyguardClockPositionAlgorithm();
@@ -198,6 +202,7 @@
     private int mQsFalsingThreshold;
 
     private float mKeyguardStatusBarAnimateAlpha = 1f;
+    private float mQsClockAlphaOverride = 1f;
     private int mOldLayoutDirection;
     private HeadsUpTouchHelper mHeadsUpTouchHelper;
     private boolean mIsExpansionFromHeadsUp;
@@ -224,11 +229,15 @@
     private NotificationGroupManager mGroupManager;
     private boolean mShowIconsWhenExpanded;
     private int mIndicationBottomPadding;
+    private int mAmbientIndicationBottomPadding;
     private boolean mIsFullWidth;
     private float mDarkAmount;
+    private float mDarkAmountTarget;
     private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
     private boolean mNoVisibleNotifications = true;
     private ValueAnimator mDarkAnimator;
+    private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    private boolean mUserSetupComplete;
 
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -240,6 +249,7 @@
 
     public void setStatusBar(StatusBar bar) {
         mStatusBar = bar;
+        mKeyguardBottomArea.setStatusBar(mStatusBar);
     }
 
     @Override
@@ -247,7 +257,6 @@
         super.onFinishInflate();
         mKeyguardStatusBar = findViewById(R.id.keyguard_header);
         mKeyguardStatusView = findViewById(R.id.keyguard_status_view);
-        mClockView = findViewById(R.id.clock_view);
 
         mNotificationContainerParent = (NotificationsQuickSettingsContainer)
                 findViewById(R.id.notification_container_parent);
@@ -258,10 +267,10 @@
         mNotificationStackScroller.setOnEmptySpaceClickListener(this);
         mKeyguardBottomArea = findViewById(R.id.keyguard_bottom_area);
         mQsNavbarScrim = findViewById(R.id.qs_navbar_scrim);
-        mAffordanceHelper = new KeyguardAffordanceHelper(this, getContext());
-        mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
         mLastOrientation = getResources().getConfiguration().orientation;
 
+        initBottomArea();
+
         mQsFrame = findViewById(R.id.qs_frame);
     }
 
@@ -301,16 +310,18 @@
     }
 
     public void updateResources() {
-        int panelWidth = getResources().getDimensionPixelSize(R.dimen.notification_panel_width);
+        Resources res = getResources();
+        int qsWidth = res.getDimensionPixelSize(R.dimen.qs_panel_width);
         int panelGravity = getResources().getInteger(R.integer.notification_panel_layout_gravity);
         FrameLayout.LayoutParams lp =
                 (FrameLayout.LayoutParams) mQsFrame.getLayoutParams();
-        if (lp.width != panelWidth || lp.gravity != panelGravity) {
-            lp.width = panelWidth;
+        if (lp.width != qsWidth || lp.gravity != panelGravity) {
+            lp.width = qsWidth;
             lp.gravity = panelGravity;
             mQsFrame.setLayoutParams(lp);
         }
 
+        int panelWidth = res.getDimensionPixelSize(R.dimen.notification_panel_width);
         lp = (FrameLayout.LayoutParams) mNotificationStackScroller.getLayoutParams();
         if (lp.width != panelWidth || lp.gravity != panelGravity) {
             lp.width = panelWidth;
@@ -319,6 +330,42 @@
         }
     }
 
+    public void onOverlayChanged() {
+        // Re-inflate the status view group.
+        int index = indexOfChild(mKeyguardStatusView);
+        removeView(mKeyguardStatusView);
+        mKeyguardStatusView = (KeyguardStatusView) LayoutInflater.from(mContext).inflate(
+                R.layout.keyguard_status_view,
+                this,
+                false);
+        addView(mKeyguardStatusView, index);
+
+        // Update keyguard bottom area
+        index = indexOfChild(mKeyguardBottomArea);
+        removeView(mKeyguardBottomArea);
+        mKeyguardBottomArea = (KeyguardBottomAreaView) LayoutInflater.from(mContext).inflate(
+                R.layout.keyguard_bottom_area,
+                this,
+                false);
+        addView(mKeyguardBottomArea, index);
+        initBottomArea();
+        setDarkAmount(mDarkAmount);
+
+        setKeyguardStatusViewVisibility(mStatusBarState, false, false);
+        setKeyguardBottomAreaVisibility(mStatusBarState, false);
+    }
+
+    private void initBottomArea() {
+        mAffordanceHelper = new KeyguardAffordanceHelper(this, getContext());
+        mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
+        mKeyguardBottomArea.setStatusBar(mStatusBar);
+        mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete);
+    }
+
+    public void setKeyguardIndicationController(KeyguardIndicationController indicationController) {
+        mKeyguardBottomArea.setKeyguardIndicationController(indicationController);
+    }
+
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
@@ -326,7 +373,8 @@
 
         // Update Clock Pivot
         mKeyguardStatusView.setPivotX(getWidth() / 2);
-        mKeyguardStatusView.setPivotY((FONT_HEIGHT - CAP_HEIGHT) / 2048f * mClockView.getTextSize());
+        mKeyguardStatusView.setPivotY((FONT_HEIGHT - CAP_HEIGHT) / 2048f *
+                mKeyguardStatusView.getClockTextSize());
 
         // Calculate quick setting heights.
         int oldMaxHeight = mQsMaxExpansionHeight;
@@ -415,8 +463,9 @@
                     mDarkAmount);
             mClockPositionAlgorithm.run(mClockPositionResult);
             if (animate || mClockAnimator != null) {
-                startClockAnimation(mClockPositionResult.clockY);
+                startClockAnimation(mClockPositionResult.clockX, mClockPositionResult.clockY);
             } else {
+                mKeyguardStatusView.setX(mClockPositionResult.clockX);
                 mKeyguardStatusView.setY(mClockPositionResult.clockY);
             }
             updateClock(mClockPositionResult.clockAlpha, mClockPositionResult.clockScale);
@@ -424,6 +473,7 @@
             mTopPaddingAdjustment = mClockPositionResult.stackScrollerPaddingAdjustment;
         }
         mNotificationStackScroller.setIntrinsicPadding(stackScrollerPadding);
+        mNotificationStackScroller.setDarkShelfOffsetX(mClockPositionResult.clockX);
         requestScrollerTopPaddingUpdate(animate);
     }
 
@@ -436,10 +486,11 @@
                 mKeyguardStatusView.getHeight());
         int notificationPadding = Math.max(1, getResources().getDimensionPixelSize(
                 R.dimen.notification_divider_height));
-        float shelfSize = mNotificationStackScroller.getNotificationShelf().getIntrinsicHeight()
-                + notificationPadding;
+        NotificationShelf shelf = mNotificationStackScroller.getNotificationShelf();
+        float shelfSize = shelf.getVisibility() == GONE ? 0
+                : shelf.getIntrinsicHeight() + notificationPadding;
         float availableSpace = mNotificationStackScroller.getHeight() - minPadding - shelfSize
-                - mIndicationBottomPadding;
+                - Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding);
         int count = 0;
         for (int i = 0; i < mNotificationStackScroller.getChildCount(); i++) {
             ExpandableView child = (ExpandableView) mNotificationStackScroller.getChildAt(i);
@@ -478,11 +529,12 @@
         return count;
     }
 
-    private void startClockAnimation(int y) {
-        if (mClockAnimationTarget == y) {
+    private void startClockAnimation(int x, int y) {
+        if (mClockAnimationTargetX == x && mClockAnimationTargetY == y) {
             return;
         }
-        mClockAnimationTarget = y;
+        mClockAnimationTargetX = x;
+        mClockAnimationTargetY = y;
         getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
             @Override
             public boolean onPreDraw() {
@@ -491,15 +543,20 @@
                     mClockAnimator.removeAllListeners();
                     mClockAnimator.cancel();
                 }
-                mClockAnimator = ObjectAnimator
-                        .ofFloat(mKeyguardStatusView, View.Y, mClockAnimationTarget);
+                AnimatorSet set = new AnimatorSet();
+                set.play(ObjectAnimator.ofFloat(
+                        mKeyguardStatusView, View.Y, mClockAnimationTargetY))
+                        .with(ObjectAnimator.ofFloat(
+                                mKeyguardStatusView, View.X, mClockAnimationTargetX));
+                mClockAnimator = set;
                 mClockAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
                 mClockAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
                 mClockAnimator.addListener(new AnimatorListenerAdapter() {
                     @Override
                     public void onAnimationEnd(Animator animation) {
                         mClockAnimator = null;
-                        mClockAnimationTarget = -1;
+                        mClockAnimationTargetX = Integer.MIN_VALUE;
+                        mClockAnimationTargetY = Integer.MIN_VALUE;
                     }
                 });
                 mClockAnimator.start();
@@ -510,7 +567,7 @@
 
     private void updateClock(float alpha, float scale) {
         if (!mKeyguardStatusViewAnimating) {
-            mKeyguardStatusView.setAlpha(alpha);
+            mKeyguardStatusView.setAlpha(alpha * mQsClockAlphaOverride);
         }
         mKeyguardStatusView.setScaleX(scale);
         mKeyguardStatusView.setScaleY(scale);
@@ -1262,6 +1319,15 @@
             mQsNavbarScrim.setAlpha(getQsExpansionFraction());
         }
 
+        // Fade clock when QS is on top of it
+        float newClockAlpha = (height - mKeyguardStatusView.getY()) /
+                mKeyguardStatusView.getHeight();
+        newClockAlpha = 1 - MathUtils.constrain(newClockAlpha, 0, 1);
+        if (newClockAlpha != mQsClockAlphaOverride) {
+            mQsClockAlphaOverride = Interpolators.ALPHA_OUT.getInterpolation(newClockAlpha);
+            updateClock(mClockPositionResult.clockAlpha, mClockPositionResult.clockScale);
+        }
+
         // Upon initialisation when we are not layouted yet we don't want to announce that we are
         // fully expanded, hence the != 0.0f check.
         if (height != 0.0f && mQsFullyExpanded && !mLastAnnouncementWasQuickSettings) {
@@ -1657,6 +1723,10 @@
         mKeyguardBottomArea.setImportantForAccessibility(alpha == 0f
                 ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
                 : IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+        View ambientIndicationContainer = mStatusBar.getAmbientIndicationContainer();
+        if (ambientIndicationContainer != null) {
+            ambientIndicationContainer.setAlpha(alpha);
+        }
     }
 
     private float getNotificationsTopY() {
@@ -2375,6 +2445,8 @@
             mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP;
         } else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE) {
             mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_WIGGLE;
+        } else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER) {
+            mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER;
         } else {
 
             // Default.
@@ -2440,6 +2512,10 @@
      * @param keyguardIsShowing whether keyguard is being shown
      */
     public boolean canCameraGestureBeLaunched(boolean keyguardIsShowing) {
+        if (!mStatusBar.isCameraAllowedByAdmin()) {
+            return false;
+        }
+
         ResolveInfo resolveInfo = mKeyguardBottomArea.resolveCameraIntent();
         String packageToLaunch = (resolveInfo == null || resolveInfo.activityInfo == null)
                 ? null : resolveInfo.activityInfo.packageName;
@@ -2505,7 +2581,7 @@
     public void setTouchDisabled(boolean disabled) {
         super.setTouchDisabled(disabled);
         if (disabled && mAffordanceHelper.isSwipingInProgress() && !mIsLaunchTransitionRunning) {
-            mAffordanceHelper.resetImmediately();
+            mAffordanceHelper.reset(false /* animate */);
         }
     }
 
@@ -2515,8 +2591,13 @@
             return;
         }
         if (mDarkAnimator != null && mDarkAnimator.isRunning()) {
-            mDarkAnimator.cancel();
+            if (animate && mDarkAmountTarget == darkAmount) {
+                return;
+            } else {
+                mDarkAnimator.cancel();
+            }
         }
+        mDarkAmountTarget = darkAmount;
         if (animate) {
             mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, darkAmount);
             mDarkAnimator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
@@ -2529,7 +2610,7 @@
 
     private void setDarkAmount(float amount) {
         mDarkAmount = amount;
-        mKeyguardStatusView.setDark(amount == 1);
+        mKeyguardStatusView.setDark(mDarkAmount);
         positionClockAndNotifications();
     }
 
@@ -2543,4 +2624,41 @@
     public void setPulsing(boolean pulsing) {
         mKeyguardStatusView.setPulsing(pulsing);
     }
+
+    public void setAmbientIndicationBottomPadding(int ambientIndicationBottomPadding) {
+        if (mAmbientIndicationBottomPadding != ambientIndicationBottomPadding) {
+            mAmbientIndicationBottomPadding = ambientIndicationBottomPadding;
+            mStatusBar.updateKeyguardMaxNotifications();
+        }
+    }
+
+    public void refreshTime() {
+        mKeyguardStatusView.refreshTime();
+        if (mDarkAmount > 0) {
+            positionClockAndNotifications();
+        }
+    }
+
+    public void setStatusAccessibilityImportance(int mode) {
+         mKeyguardStatusView.setImportantForAccessibility(mode);
+    }
+
+    /**
+     * TODO: this should be removed.
+     * It's not correct to pass this view forward because other classes will end up adding
+     * children to it. Theme will be out of sync.
+     * @return bottom area view
+     */
+    public KeyguardBottomAreaView getKeyguardBottomAreaView() {
+        return mKeyguardBottomArea;
+    }
+
+    public void setUserSetupComplete(boolean userSetupComplete) {
+        mUserSetupComplete = userSetupComplete;
+        mKeyguardBottomArea.setUserSetupComplete(userSetupComplete);
+    }
+
+    public LockIcon getLockIcon() {
+        return mKeyguardBottomArea.getLockIcon();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index 646f3d8..76cc0ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Canvas;
+import android.support.annotation.DimenRes;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewStub;
@@ -32,20 +33,20 @@
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.plugins.qs.QS;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.statusbar.NotificationData.Entry;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+import com.android.systemui.statusbar.notification.AboveShelfObserver;
+import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 /**
  * The container with notification stack scroller and quick settings inside.
  */
 public class NotificationsQuickSettingsContainer extends FrameLayout
-        implements OnInflateListener, FragmentListener, OnHeadsUpChangedListener {
+        implements OnInflateListener, FragmentListener,
+        AboveShelfObserver.HasViewAboveShelfChangedListener {
 
     private FrameLayout mQsFrame;
     private View mUserSwitcher;
-    private View mStackScroller;
+    private NotificationStackScrollLayout mStackScroller;
     private View mKeyguardStatusBar;
     private boolean mInflated;
     private boolean mQsExpanded;
@@ -53,8 +54,7 @@
 
     private int mBottomPadding;
     private int mStackScrollerMargin;
-    private boolean mHeadsUp;
-    private HeadsUpManager mHeadsUpManager;
+    private boolean mHasViewsAboveShelf;
 
     public NotificationsQuickSettingsContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -76,29 +76,27 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         FragmentHostManager.get(this).addTagListener(QS.TAG, this);
-        mHeadsUpManager = SysUiServiceProvider.getComponent(getContext(), StatusBar.class)
-                .mHeadsUpManager;
-        mHeadsUpManager.addListener(this);
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         FragmentHostManager.get(this).removeTagListener(QS.TAG, this);
-        mHeadsUpManager.removeListener(this);
     }
 
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        reloadWidth(mQsFrame);
-        reloadWidth(mStackScroller);
+        reloadWidth(mQsFrame, R.dimen.qs_panel_width);
+        reloadWidth(mStackScroller, R.dimen.notification_panel_width);
     }
 
-    private void reloadWidth(View view) {
+    /**
+     * Loads the given width resource and sets it on the given View.
+     */
+    private void reloadWidth(View view, @DimenRes int width) {
         LayoutParams params = (LayoutParams) view.getLayoutParams();
-        params.width = getContext().getResources().getDimensionPixelSize(
-                R.dimen.notification_panel_width);
+        params.width = getResources().getDimensionPixelSize(width);
         view.setLayoutParams(params);
     }
 
@@ -114,7 +112,7 @@
         boolean userSwitcherVisible = mInflated && mUserSwitcher.getVisibility() == View.VISIBLE;
         boolean statusBarVisible = mKeyguardStatusBar.getVisibility() == View.VISIBLE;
 
-        final boolean qsBottom = mHeadsUp;
+        final boolean qsBottom = mHasViewsAboveShelf;
         View stackQsTop = qsBottom ? mStackScroller : mQsFrame;
         View stackQsBottom = !qsBottom ? mStackScroller : mQsFrame;
         // Invert the order of the scroll view and user switcher such that the notifications receive
@@ -181,7 +179,7 @@
             setPadding(0, 0, 0, mBottomPadding);
             setBottomMargin(mStackScroller, mStackScrollerMargin);
         }
-
+        mStackScroller.setQsCustomizerShowing(isShowing);
     }
 
     private void setBottomMargin(View v, int bottomMargin) {
@@ -191,12 +189,8 @@
     }
 
     @Override
-    public void onHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
-        boolean hasHeadsUp = mHeadsUpManager.getAllEntries().size() != 0;
-        if (mHeadsUp == hasHeadsUp) {
-            return;
-        }
-        mHeadsUp = hasHeadsUp;
+    public void onHasViewsAboveShelfChanged(boolean hasViewsAboveShelf) {
+        mHasViewsAboveShelf = hasViewsAboveShelf;
         invalidate();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 1ef784e..16d85be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -28,6 +28,7 @@
 import android.util.Log;
 import android.view.InputDevice;
 import android.view.MotionEvent;
+import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewTreeObserver;
 import android.view.animation.Interpolator;
@@ -1092,21 +1093,25 @@
         });
         animator.start();
         setAnimator(animator);
-        mKeyguardBottomArea.getIndicationArea().animate()
-                .translationY(-mHintDistance)
-                .setDuration(250)
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .withEndAction(new Runnable() {
-                    @Override
-                    public void run() {
-                        mKeyguardBottomArea.getIndicationArea().animate()
-                                .translationY(0)
-                                .setDuration(450)
-                                .setInterpolator(mBounceInterpolator)
-                                .start();
-                    }
-                })
-                .start();
+
+        View[] viewsToAnimate = {
+                mKeyguardBottomArea.getIndicationArea(),
+                mStatusBar.getAmbientIndicationContainer()};
+        for (View v : viewsToAnimate) {
+            if (v == null) {
+                continue;
+            }
+            v.animate()
+                    .translationY(-mHintDistance)
+                    .setDuration(250)
+                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                    .withEndAction(() -> v.animate()
+                            .translationY(0)
+                            .setDuration(450)
+                            .setInterpolator(mBounceInterpolator)
+                            .start())
+                    .start();
+        }
     }
 
     private void setAnimator(ValueAnimator animator) {
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 f3ba5aa..d1ef035 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -196,8 +196,7 @@
         }
 
         // TTY status
-        mIconController.setIcon(mSlotTty, R.drawable.stat_sys_tty_mode, null);
-        mIconController.setIconVisibility(mSlotTty, false);
+        updateTTY();
 
         // bluetooth status
         updateBluetooth();
@@ -419,9 +418,17 @@
         mIconController.setIconVisibility(mSlotBluetooth, bluetoothEnabled);
     }
 
-    private final void updateTTY(Intent intent) {
-        int currentTtyMode = intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
-                TelecomManager.TTY_MODE_OFF);
+    private final void updateTTY() {
+        TelecomManager telecomManager =
+                (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+        if (telecomManager == null) {
+            updateTTY(TelecomManager.TTY_MODE_OFF);
+        } else {
+            updateTTY(telecomManager.getCurrentTtyMode());
+        }
+    }
+
+    private final void updateTTY(int currentTtyMode) {
         boolean enabled = currentTtyMode != TelecomManager.TTY_MODE_OFF;
 
         if (DEBUG) Log.v(TAG, "updateTTY: enabled: " + enabled);
@@ -754,7 +761,8 @@
             } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
                 updateSimState(intent);
             } else if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) {
-                updateTTY(intent);
+                updateTTY(intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
+                        TelecomManager.TTY_MODE_OFF));
             } else if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) ||
                     action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) ||
                     action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
index f45967a..bcbc345 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
@@ -16,10 +16,10 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
-import android.content.res.Configuration;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 
 import java.util.ArrayList;
@@ -48,7 +48,7 @@
 
     @Override
     public void addView(View child) {
-        reversParams(child.getLayoutParams());
+        reverseParams(child.getLayoutParams(), child);
         if (mIsLayoutReverse) {
             super.addView(child, 0);
         } else {
@@ -58,7 +58,7 @@
 
     @Override
     public void addView(View child, ViewGroup.LayoutParams params) {
-        reversParams(params);
+        reverseParams(params, child);
         if (mIsLayoutReverse) {
             super.addView(child, 0, params);
         } else {
@@ -100,7 +100,15 @@
         }
     }
 
-    private void reversParams(ViewGroup.LayoutParams params) {
+    private static void reverseParams(ViewGroup.LayoutParams params, View child) {
+        if (child instanceof Reversable) {
+            ((Reversable) child).reverse();
+        }
+        if (child.getPaddingLeft() == child.getPaddingRight()
+                && child.getPaddingTop() == child.getPaddingBottom()) {
+            child.setPadding(child.getPaddingTop(), child.getPaddingLeft(),
+                    child.getPaddingTop(), child.getPaddingLeft());
+        }
         if (params == null) {
             return;
         }
@@ -109,4 +117,23 @@
         params.height = width;
     }
 
+    public interface Reversable {
+        void reverse();
+    }
+
+    public static class ReverseFrameLayout extends FrameLayout implements Reversable {
+
+        public ReverseFrameLayout(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void reverse() {
+            for (int i = 0; i < getChildCount(); i++) {
+                View child = getChildAt(i);
+                reverseParams(child.getLayoutParams(), child);
+            }
+        }
+    }
+
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 67d5b6a..1d64480 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -20,39 +20,56 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
+import android.app.WallpaperManager;
 import android.content.Context;
+import android.graphics.Color;
 import android.graphics.Rect;
-import android.support.v4.graphics.ColorUtils;
-import android.util.TypedValue;
+import android.graphics.drawable.Drawable;
+import android.os.Trace;
+import android.util.MathUtils;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener;
+import com.android.internal.graphics.ColorUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.ScrimView;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 import com.android.systemui.statusbar.stack.ViewState;
 
+import java.util.function.Consumer;
+
 /**
  * Controls both the scrim behind the notifications and in front of the notifications (when a
  * security method gets shown).
  */
 public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
-        OnHeadsUpChangedListener {
+        OnHeadsUpChangedListener, OnColorsChangedListener {
     public static final long ANIMATION_DURATION = 220;
     public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR
             = new PathInterpolator(0f, 0, 0.7f, 1f);
     public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR_LOCKED
             = new PathInterpolator(0.3f, 0f, 0.8f, 1f);
-    protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.45f;
+    // Default alpha value for most scrims, if unsure use this constant
+    public static final float GRADIENT_SCRIM_ALPHA = 0.45f;
+    // A scrim varies its opacity based on a busyness factor, for example
+    // how many notifications are currently visible.
+    public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.70f;
+    protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = GRADIENT_SCRIM_ALPHA;
     protected static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
-    private static final float SCRIM_IN_FRONT_ALPHA = 0.75f;
-    private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = 0.85f;
+    private static final float SCRIM_IN_FRONT_ALPHA = GRADIENT_SCRIM_ALPHA_BUSY;
+    private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA_BUSY;
     private static final int TAG_KEY_ANIM = R.id.scrim;
     private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target;
     private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
@@ -61,12 +78,18 @@
 
     private final LightBarController mLightBarController;
     protected final ScrimView mScrimBehind;
-    private final ScrimView mScrimInFront;
+    protected final ScrimView mScrimInFront;
     private final UnlockMethodCache mUnlockMethodCache;
     private final View mHeadsUpScrim;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
 
+    private final SysuiColorExtractor mColorExtractor;
+    private GradientColors mLockColors;
+    private GradientColors mSystemColors;
+    private boolean mNeedsDrawableColorUpdate;
+
     protected float mScrimBehindAlpha;
+    protected float mScrimBehindAlphaResValue;
     protected float mScrimBehindAlphaKeyguard = SCRIM_BEHIND_ALPHA_KEYGUARD;
     protected float mScrimBehindAlphaUnlocking = SCRIM_BEHIND_ALPHA_UNLOCKING;
 
@@ -84,6 +107,7 @@
     protected long mDurationOverride = -1;
     private long mAnimationDelay;
     private Runnable mOnAnimationFinished;
+    private boolean mDeferFinishedListener;
     private final Interpolator mInterpolator = new DecelerateInterpolator();
     private boolean mDozing;
     private float mDozeInFrontAlpha;
@@ -98,18 +122,40 @@
     private boolean mSkipFirstFrame;
     private boolean mDontAnimateBouncerChanges;
     private boolean mKeyguardFadingOutInProgress;
+    private boolean mAnimatingDozeUnlock;
     private ValueAnimator mKeyguardFadeoutAnimation;
+    /** Wake up from AOD transition is starting; need fully opaque front scrim */
+    private boolean mWakingUpFromAodStarting;
+    /** Wake up from AOD transition is in progress; need black tint */
+    private boolean mWakingUpFromAodInProgress;
+    /** Wake up from AOD transition is animating; need to reset when animation finishes */
+    private boolean mWakingUpFromAodAnimationRunning;
+    private boolean mScrimsVisble;
+    private final Consumer<Boolean> mScrimVisibleListener;
 
     public ScrimController(LightBarController lightBarController, ScrimView scrimBehind,
-            ScrimView scrimInFront, View headsUpScrim) {
+            ScrimView scrimInFront, View headsUpScrim,
+            Consumer<Boolean> scrimVisibleListener) {
         mScrimBehind = scrimBehind;
         mScrimInFront = scrimInFront;
         mHeadsUpScrim = headsUpScrim;
+        mScrimVisibleListener = scrimVisibleListener;
         final Context context = scrimBehind.getContext();
         mUnlockMethodCache = UnlockMethodCache.getInstance(context);
         mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
         mLightBarController = lightBarController;
-        mScrimBehindAlpha = context.getResources().getFloat(R.dimen.scrim_behind_alpha);
+        mScrimBehindAlphaResValue = context.getResources().getFloat(R.dimen.scrim_behind_alpha);
+        // Scrim alpha is initially set to the value on the resource but might be changed
+        // to make sure that text on top of it is legible.
+        mScrimBehindAlpha = mScrimBehindAlphaResValue;
+
+        mColorExtractor = Dependency.get(SysuiColorExtractor.class);
+        mColorExtractor.addOnColorsChangedListener(this);
+        mLockColors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
+                ColorExtractor.TYPE_DARK, true /* ignoreVisibility */);
+        mSystemColors = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
+                ColorExtractor.TYPE_DARK, true /* ignoreVisibility */);
+        mNeedsDrawableColorUpdate = true;
 
         updateHeadsUpScrim(false);
         updateScrims();
@@ -117,6 +163,9 @@
 
     public void setKeyguardShowing(boolean showing) {
         mKeyguardShowing = showing;
+
+        // Showing/hiding the keyguard means that scrim colors have to be switched
+        mNeedsDrawableColorUpdate = true;
         scheduleUpdate();
     }
 
@@ -151,12 +200,43 @@
 
     public void setBouncerShowing(boolean showing) {
         mBouncerShowing = showing;
-        mAnimateChange = !mTracking && !mDontAnimateBouncerChanges;
+        mAnimateChange = !mTracking && !mDontAnimateBouncerChanges && !mKeyguardFadingOutInProgress;
         scheduleUpdate();
     }
 
+    /** Prepares the wakeUpFromAod animation (while turning on screen); Forces black scrims. */
+    public void prepareWakeUpFromAod() {
+        if (mWakingUpFromAodInProgress) {
+            return;
+        }
+        mWakingUpFromAodInProgress = true;
+        mWakingUpFromAodStarting = true;
+        mAnimateChange = false;
+        scheduleUpdate();
+        onPreDraw();
+    }
+
+    /** Starts the wakeUpFromAod animation (once screen is on); animate to transparent scrims. */
+    public void wakeUpFromAod() {
+        if (mWakeAndUnlocking || mAnimateKeyguardFadingOut) {
+            // Wake and unlocking has a separate transition that must not be interfered with.
+            mWakingUpFromAodStarting = false;
+            mWakingUpFromAodInProgress = false;
+            return;
+        }
+        if (mWakingUpFromAodStarting) {
+            mWakingUpFromAodInProgress = true;
+            mWakingUpFromAodStarting = false;
+            mAnimateChange = true;
+            scheduleUpdate();
+        }
+    }
+
     public void setWakeAndUnlocking() {
         mWakeAndUnlocking = true;
+        mAnimatingDozeUnlock = true;
+        mWakingUpFromAodStarting = false;
+        mWakingUpFromAodInProgress = false;
         scheduleUpdate();
     }
 
@@ -192,7 +272,7 @@
 
     public void animateKeyguardUnoccluding(long duration) {
         mAnimateChange = false;
-        setScrimBehindColor(0f);
+        setScrimBehindAlpha(0f);
         mAnimateChange = true;
         scheduleUpdate();
         mDurationOverride = duration;
@@ -230,12 +310,33 @@
         return mDozeInFrontAlpha;
     }
 
+    public void setNotificationCount(int notificationCount) {
+        final float maxNotificationDensity = 3;
+        float notificationDensity = Math.min(notificationCount / maxNotificationDensity, 1f);
+        float newAlpha = MathUtils.map(0, 1,
+                GRADIENT_SCRIM_ALPHA, GRADIENT_SCRIM_ALPHA_BUSY,
+                notificationDensity);
+        if (mScrimBehindAlphaKeyguard != newAlpha) {
+            mScrimBehindAlphaKeyguard = newAlpha;
+            mAnimateChange = true;
+            scheduleUpdate();
+        }
+    }
+
     private float getScrimInFrontAlpha() {
         return mKeyguardUpdateMonitor.needsSlowUnlockTransition()
                 ? SCRIM_IN_FRONT_ALPHA_LOCKED
                 : SCRIM_IN_FRONT_ALPHA;
     }
 
+    /**
+     * Sets the given drawable as the background of the scrim that shows up behind the
+     * notifications.
+     */
+    public void setScrimBehindDrawable(Drawable drawable) {
+        mScrimBehind.setDrawable(drawable);
+    }
+
     protected void scheduleUpdate() {
         if (mUpdatePending) return;
 
@@ -246,27 +347,65 @@
     }
 
     protected void updateScrims() {
-        if (mAnimateKeyguardFadingOut || mForceHideScrims) {
-            setScrimInFrontColor(0f);
-            setScrimBehindColor(0f);
-        } else if (mWakeAndUnlocking) {
-
-            // During wake and unlock, we first hide everything behind a black scrim, which then
-            // gets faded out from animateKeyguardFadingOut.
-            if (mDozing) {
-                setScrimInFrontColor(0f);
-                setScrimBehindColor(1f);
+        // Make sure we have the right gradients and their opacities will satisfy GAR.
+        if (mNeedsDrawableColorUpdate) {
+            mNeedsDrawableColorUpdate = false;
+            final GradientColors currentScrimColors;
+            if (mKeyguardShowing) {
+                // Always animate color changes if we're seeing the keyguard
+                mScrimInFront.setColors(mLockColors, true /* animated */);
+                mScrimBehind.setColors(mLockColors, true /* animated */);
+                currentScrimColors = mLockColors;
             } else {
-                setScrimInFrontColor(1f);
-                setScrimBehindColor(0f);
+                // Only animate scrim color if the scrim view is actually visible
+                boolean animateScrimInFront = mScrimInFront.getViewAlpha() != 0;
+                boolean animateScrimBehind = mScrimBehind.getViewAlpha() != 0;
+                mScrimInFront.setColors(mSystemColors, animateScrimInFront);
+                mScrimBehind.setColors(mSystemColors, animateScrimBehind);
+                currentScrimColors = mSystemColors;
             }
-        } else if (!mKeyguardShowing && !mBouncerShowing) {
+
+            // Calculate minimum scrim opacity for white or black text.
+            int textColor = currentScrimColors.supportsDarkText() ? Color.BLACK : Color.WHITE;
+            int mainColor = currentScrimColors.getMainColor();
+            float minOpacity = ColorUtils.calculateMinimumBackgroundAlpha(textColor, mainColor,
+                    4.5f /* minimumContrast */) / 255f;
+            mScrimBehindAlpha = Math.max(mScrimBehindAlphaResValue, minOpacity);
+            mLightBarController.setScrimColor(mScrimInFront.getColors());
+        }
+
+        if (mAnimateKeyguardFadingOut || mForceHideScrims) {
+            setScrimInFrontAlpha(0f);
+            setScrimBehindAlpha(0f);
+        } else if (mWakeAndUnlocking) {
+            // During wake and unlock, we first hide everything behind a black scrim, which then
+            // gets faded out from animateKeyguardFadingOut. This must never be animated.
+            mAnimateChange = false;
+            if (mDozing) {
+                setScrimInFrontAlpha(0f);
+                setScrimBehindAlpha(1f);
+            } else {
+                setScrimInFrontAlpha(1f);
+                setScrimBehindAlpha(0f);
+            }
+        } else if (!mKeyguardShowing && !mBouncerShowing && !mWakingUpFromAodStarting) {
             updateScrimNormal();
-            setScrimInFrontColor(0);
+            setScrimInFrontAlpha(0);
         } else {
             updateScrimKeyguard();
         }
         mAnimateChange = false;
+        dispatchScrimsVisible();
+    }
+
+    private void dispatchScrimsVisible() {
+        boolean scrimsVisible = mScrimBehind.getViewAlpha() > 0 || mScrimInFront.getViewAlpha() > 0;
+
+        if (mScrimsVisble != scrimsVisible) {
+            mScrimsVisble = scrimsVisible;
+
+            mScrimVisibleListener.accept(scrimsVisible);
+        }
     }
 
     private void updateScrimKeyguard() {
@@ -275,18 +414,22 @@
             float fraction = 1 - behindFraction;
             fraction = (float) Math.pow(fraction, 0.8f);
             behindFraction = (float) Math.pow(behindFraction, 0.8f);
-            setScrimInFrontColor(fraction * getScrimInFrontAlpha());
-            setScrimBehindColor(behindFraction * mScrimBehindAlphaKeyguard);
+            setScrimInFrontAlpha(fraction * getScrimInFrontAlpha());
+            setScrimBehindAlpha(behindFraction * mScrimBehindAlphaKeyguard);
         } else if (mBouncerShowing && !mBouncerIsKeyguard) {
-            setScrimInFrontColor(getScrimInFrontAlpha());
+            setScrimInFrontAlpha(getScrimInFrontAlpha());
             updateScrimNormal();
         } else if (mBouncerShowing) {
-            setScrimInFrontColor(0f);
-            setScrimBehindColor(mScrimBehindAlpha);
+            setScrimInFrontAlpha(0f);
+            setScrimBehindAlpha(mScrimBehindAlpha);
         } else {
             float fraction = Math.max(0, Math.min(mFraction, 1));
-            setScrimInFrontColor(0f);
-            setScrimBehindColor(fraction
+            if (mWakingUpFromAodStarting) {
+                setScrimInFrontAlpha(1f);
+            } else {
+                setScrimInFrontAlpha(0f);
+            }
+            setScrimBehindAlpha(fraction
                     * (mScrimBehindAlphaKeyguard - mScrimBehindAlphaUnlocking)
                     + mScrimBehindAlphaUnlocking);
         }
@@ -297,30 +440,29 @@
         // let's start this 20% of the way down the screen
         frac = frac * 1.2f - 0.2f;
         if (frac <= 0) {
-            setScrimBehindColor(0);
+            setScrimBehindAlpha(0);
         } else {
             // woo, special effects
             final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f))));
-            setScrimBehindColor(k * mScrimBehindAlpha);
+            setScrimBehindAlpha(k * mScrimBehindAlpha);
         }
     }
 
-    private void setScrimBehindColor(float alpha) {
-        setScrimColor(mScrimBehind, alpha);
+    private void setScrimBehindAlpha(float alpha) {
+        setScrimAlpha(mScrimBehind, alpha);
     }
 
-    private void setScrimInFrontColor(float alpha) {
-        setScrimColor(mScrimInFront, alpha);
+    private void setScrimInFrontAlpha(float alpha) {
+        setScrimAlpha(mScrimInFront, alpha);
         if (alpha == 0f) {
             mScrimInFront.setClickable(false);
         } else {
-
             // Eat touch events (unless dozing).
             mScrimInFront.setClickable(!mDozing);
         }
     }
 
-    private void setScrimColor(View scrim, float alpha) {
+    private void setScrimAlpha(View scrim, float alpha) {
         updateScrim(mAnimateChange, scrim, alpha, getCurrentScrimAlpha(scrim));
     }
 
@@ -346,30 +488,45 @@
         }
     }
 
-    protected void updateScrimColor(View scrim) {
+    private void updateScrimColor(View scrim) {
         float alpha1 = getCurrentScrimAlpha(scrim);
         if (scrim instanceof ScrimView) {
-            float alpha2 = getDozeAlpha(scrim);
-            float alpha = 1 - (1 - alpha1) * (1 - alpha2);
+            ScrimView scrimView = (ScrimView) scrim;
+            float dozeAlpha = getDozeAlpha(scrim);
+            float alpha = 1 - (1 - alpha1) * (1 - dozeAlpha);
             alpha = Math.max(0, Math.min(1.0f, alpha));
-            int baseColor = ((ScrimView) scrim).getScrimColor();
-            ((ScrimView) scrim).setScrimColor(
-                    ColorUtils.setAlphaComponent(baseColor, (int) (alpha * 255)));
+            scrimView.setViewAlpha(alpha);
+
+            Trace.traceCounter(Trace.TRACE_TAG_APP,
+                    scrim == mScrimInFront ? "front_scrim_alpha" : "back_scrim_alpha",
+                    (int) (alpha * 255));
+
+            int dozeTint = Color.TRANSPARENT;
+
+            boolean dozing = mAnimatingDozeUnlock || mDozing;
+            boolean frontScrimDozing = mWakingUpFromAodInProgress;
+            if (dozing || frontScrimDozing && scrim == mScrimInFront) {
+                dozeTint = Color.BLACK;
+            }
+            Trace.traceCounter(Trace.TRACE_TAG_APP,
+                    scrim == mScrimInFront ? "front_scrim_tint" : "back_scrim_tint",
+                    dozeTint == Color.BLACK ? 1 : 0);
+
+            scrimView.setTint(dozeTint);
         } else {
             scrim.setAlpha(alpha1);
         }
+        dispatchScrimsVisible();
     }
 
     private void startScrimAnimation(final View scrim, float target) {
         float current = getCurrentScrimAlpha(scrim);
         ValueAnimator anim = ValueAnimator.ofFloat(current, target);
-        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                float alpha = (float) animation.getAnimatedValue();
-                setCurrentScrimAlpha(scrim, alpha);
-                updateScrimColor(scrim);
-            }
+        anim.addUpdateListener(animation -> {
+            float alpha = (float) animation.getAnimatedValue();
+            setCurrentScrimAlpha(scrim, alpha);
+            updateScrimColor(scrim);
+            dispatchScrimsVisible();
         });
         anim.setInterpolator(getInterpolator());
         anim.setStartDelay(mAnimationDelay);
@@ -377,16 +534,22 @@
         anim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                if (mOnAnimationFinished != null) {
+                if (!mDeferFinishedListener && mOnAnimationFinished != null) {
                     mOnAnimationFinished.run();
                     mOnAnimationFinished = null;
                 }
                 if (mKeyguardFadingOutInProgress) {
                     mKeyguardFadeoutAnimation = null;
                     mKeyguardFadingOutInProgress = false;
+                    mAnimatingDozeUnlock = false;
+                }
+                if (mWakingUpFromAodAnimationRunning && !mDeferFinishedListener) {
+                    mWakingUpFromAodAnimationRunning = false;
+                    mWakingUpFromAodInProgress = false;
                 }
                 scrim.setTag(TAG_KEY_ANIM, null);
                 scrim.setTag(TAG_KEY_ANIM_TARGET, null);
+                dispatchScrimsVisible();
             }
         });
         anim.start();
@@ -394,6 +557,9 @@
             mKeyguardFadingOutInProgress = true;
             mKeyguardFadeoutAnimation = anim;
         }
+        if (mWakingUpFromAodInProgress) {
+            mWakingUpFromAodAnimationRunning = true;
+        }
         if (mSkipFirstFrame) {
             anim.setCurrentPlayTime(16);
         }
@@ -436,6 +602,8 @@
                 mOnAnimationFinished = null;
             }
             mKeyguardFadingOutInProgress = false;
+            if (!mWakeAndUnlocking || force)
+                mAnimatingDozeUnlock = false;
         }
     }
 
@@ -485,7 +653,12 @@
         float animEndValue = -1;
         if (previousAnimator != null) {
             if (animate || alpha == currentAlpha) {
+                // We are not done yet! Defer calling the finished listener.
+                if (animate) {
+                    mDeferFinishedListener = true;
+                }
                 previousAnimator.cancel();
+                mDeferFinishedListener = false;
             } else {
                 animEndValue = ViewState.getChildTag(scrim, TAG_END_ALPHA);
             }
@@ -545,9 +718,9 @@
         return alpha * expandFactor;
     }
 
-    public void forceHideScrims(boolean hide) {
+    public void forceHideScrims(boolean hide, boolean animated) {
         mForceHideScrims = hide;
-        mAnimateChange = false;
+        mAnimateChange = animated;
         scheduleUpdate();
     }
 
@@ -559,8 +732,10 @@
         mScrimBehind.setExcludedArea(area);
     }
 
-    public int getScrimBehindColor() {
-        return mScrimBehind.getScrimColorWithAlpha();
+    public int getBackgroundColor() {
+        int color = mLockColors.getMainColor();
+        return Color.argb((int) (mScrimBehind.getAlpha() * Color.alpha(color)),
+                Color.red(color), Color.green(color), Color.blue(color));
     }
 
     public void setScrimBehindChangeRunnable(Runnable changeRunnable) {
@@ -577,4 +752,20 @@
     public void setCurrentUser(int currentUser) {
         // Don't care in the base class.
     }
+
+    @Override
+    public void onColorsChanged(ColorExtractor colorExtractor, int which) {
+        if ((which & WallpaperManager.FLAG_LOCK) != 0) {
+            mLockColors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
+                    ColorExtractor.TYPE_DARK, true /* ignoreVisibility */);
+            mNeedsDrawableColorUpdate = true;
+            scheduleUpdate();
+        }
+        if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
+            mSystemColors = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
+                    ColorExtractor.TYPE_DARK, mKeyguardShowing);
+            mNeedsDrawableColorUpdate = true;
+            scheduleUpdate();
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
index 983a796..15ef742 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
@@ -23,20 +23,20 @@
 import android.graphics.ColorFilter;
 import android.graphics.Matrix;
 import android.graphics.Paint;
-import android.graphics.Paint.Style;
 import android.graphics.Path;
 import android.graphics.Path.Direction;
 import android.graphics.Path.FillType;
 import android.graphics.Path.Op;
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.util.LayoutDirection;
-import android.util.Log;
 
 import com.android.settingslib.R;
 import com.android.settingslib.Utils;
+import com.android.systemui.qs.SlashDrawable;
 
 public class SignalDrawable extends Drawable {
 
@@ -85,12 +85,28 @@
             {-1.9f / VIEWPORT, -1.9f / VIEWPORT},
     };
 
-    // The easiest way to understand this is as if we set Style.STROKE and draw the triangle,
-    // but that is only theoretically right. Instead, draw the triangle and clip out a smaller
-    // one inset by this amount.
-    private final float mEmptyStrokeWidth;
+    // Rounded corners are achieved by arcing a circle of radius `R` from its tangent points along
+    // the curve (curve ≡ triangle). On the top and left corners of the triangle, the tangents are
+    // as follows:
+    //      1) Along the straight lines (y = 0 and x = width):
+    //          Ps = circleOffset + R
+    //      2) Along the diagonal line (y = x):
+    //          Pd = √((Ps^2) / 2)
+    //              or (remember: sin(π/4) ≈ 0.7071)
+    //          Pd = (circleOffset + R - 0.7071, height - R - 0.7071)
+    //         Where Pd is the (x,y) coords of the point that intersects the circle at the bottom
+    //         left of the triangle
+    private static final float RADIUS_RATIO = 0.75f / 17f;
+    private static final float DIAG_OFFSET_MULTIPLIER = 0.707107f;
+    // How far the circle defining the corners is inset from the edges
+    private final float mAppliedCornerInset;
+
     private static final float INV_TAN = 1f / (float) Math.tan(Math.PI / 8f);
-    private final float mEmptyDiagInset;  // == mEmptyStrokeWidth * INV_TAN
+    private static final float CUT_WIDTH_DP = 1f / 12f;
+
+    // Where the top and left points of the triangle would be if not for rounding
+    private final PointF mVirtualTop  = new PointF();
+    private final PointF mVirtualLeft = new PointF();
 
     private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     private final Paint mForegroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -126,13 +142,11 @@
                 Utils.getDefaultColor(context, R.color.light_mode_icon_color_dual_tone_fill);
         mIntrinsicSize = context.getResources().getDimensionPixelSize(R.dimen.signal_icon_size);
 
-        // mCutPath parameters
-        mEmptyStrokeWidth = context.getResources()
-                .getDimensionPixelSize(R.dimen.mobile_signal_empty_strokewidth);
-        mEmptyDiagInset = mEmptyStrokeWidth * INV_TAN;
-
         mHandler = new Handler();
         setDarkIntensity(0);
+
+        mAppliedCornerInset = context.getResources()
+                .getDimensionPixelSize(R.dimen.stat_sys_mobile_signal_circle_inset);
     }
 
     public void setIntrinsicSize(int size) {
@@ -185,6 +199,11 @@
         return true;
     }
 
+    public void setColors(int background, int foreground) {
+        mPaint.setColor(background);
+        mForegroundPaint.setColor(foreground);
+    }
+
     public void setDarkIntensity(float darkIntensity) {
         if (darkIntensity == mOldDarkIntensity) {
             return;
@@ -217,22 +236,57 @@
 
     @Override
     public void draw(@NonNull Canvas canvas) {
+        final float width = getBounds().width();
+        final float height = getBounds().height();
+
         boolean isRtl = getLayoutDirection() == LayoutDirection.RTL;
         if (isRtl) {
             canvas.save();
             // Mirror the drawable
-            canvas.translate(canvas.getWidth(), 0);
+            canvas.translate(width, 0);
             canvas.scale(-1.0f, 1.0f);
         }
         mFullPath.reset();
         mFullPath.setFillType(FillType.WINDING);
-        float width = getBounds().width();
-        float height = getBounds().height();
-        float padding = Math.round(PAD * width);
-        mFullPath.moveTo(width - padding, height - padding);
-        mFullPath.lineTo(width - padding, padding);
-        mFullPath.lineTo(padding, height - padding);
-        mFullPath.lineTo(width - padding, height - padding);
+
+        final float padding = Math.round(PAD * width);
+        final float cornerRadius = RADIUS_RATIO * height;
+        // Offset from circle where the hypotenuse meets the circle
+        final float diagOffset = DIAG_OFFSET_MULTIPLIER * cornerRadius;
+
+        // 1 - Bottom right, above corner
+        mFullPath.moveTo(width - padding, height - padding - cornerRadius);
+        // 2 - Line to top right, below corner
+        mFullPath.lineTo(width - padding, padding + cornerRadius + mAppliedCornerInset);
+        // 3 - Arc to top right, on hypotenuse
+        mFullPath.arcTo(
+                width - padding - (2 * cornerRadius),
+                padding + mAppliedCornerInset,
+                width - padding,
+                padding + mAppliedCornerInset + (2 * cornerRadius),
+                0.f, -135.f, false
+        );
+        // 4 - Line to bottom left, on hypotenuse
+        mFullPath.lineTo(padding + mAppliedCornerInset + cornerRadius - diagOffset,
+                height - padding - cornerRadius - diagOffset);
+        // 5 - Arc to bottom left, on leg
+        mFullPath.arcTo(
+                padding + mAppliedCornerInset,
+                height - padding - (2 * cornerRadius),
+                padding + mAppliedCornerInset + ( 2 * cornerRadius),
+                height - padding,
+                -135.f, -135.f, false
+        );
+        // 6 - Line to bottom rght, before corner
+        mFullPath.lineTo(width - padding - cornerRadius, height - padding);
+        // 7 - Arc to beginning (bottom right, above corner)
+        mFullPath.arcTo(
+                width - padding - (2 * cornerRadius),
+                height - padding - (2 * cornerRadius),
+                width - padding,
+                height - padding,
+                90.f, -90.f, false
+        );
 
         if (mState == STATE_CARRIER_CHANGE) {
             float cutWidth = (DOT_CUT_WIDTH * width);
@@ -262,25 +316,32 @@
         }
 
         if (mState == STATE_EMPTY) {
+            // Where the corners would be if this were a real triangle
+            mVirtualTop.set(
+                    width - padding,
+                    (padding + cornerRadius + mAppliedCornerInset) - (INV_TAN * cornerRadius));
+            mVirtualLeft.set(
+                    (padding + cornerRadius + mAppliedCornerInset) - (INV_TAN * cornerRadius),
+                    height - padding);
+
+            final float cutWidth = CUT_WIDTH_DP * height;
+            final float cutDiagInset = cutWidth * INV_TAN;
+
             // Cut out a smaller triangle from the center of mFullPath
             mCutPath.reset();
             mCutPath.setFillType(FillType.WINDING);
-            mCutPath.moveTo(width - padding - mEmptyStrokeWidth,
-                    height - padding - mEmptyStrokeWidth);
-            mCutPath.lineTo(width - padding - mEmptyStrokeWidth, padding + mEmptyDiagInset);
-            mCutPath.lineTo(padding + mEmptyDiagInset, height - padding - mEmptyStrokeWidth);
-            mCutPath.lineTo(width - padding - mEmptyStrokeWidth,
-                    height - padding - mEmptyStrokeWidth);
+            mCutPath.moveTo(width - padding - cutWidth, height - padding - cutWidth);
+            mCutPath.lineTo(width - padding - cutWidth, mVirtualTop.y + cutDiagInset);
+            mCutPath.lineTo(mVirtualLeft.x + cutDiagInset, height - padding - cutWidth);
+            mCutPath.lineTo(width - padding - cutWidth, height - padding - cutWidth);
 
-            // In empty state, draw the full path as the foreground paint
-            mForegroundPath.set(mFullPath);
-            mFullPath.reset();
-            mForegroundPath.op(mCutPath, Path.Op.DIFFERENCE);
+            // Draw empty state as only background
+            mForegroundPath.reset();
+            mFullPath.op(mCutPath, Path.Op.DIFFERENCE);
         } else if (mState == STATE_AIRPLANE) {
-            // Airplane mode is slashed, full-signal
-            mForegroundPath.set(mFullPath);
-            mFullPath.reset();
-            mSlash.draw((int) height, (int) width, canvas, mForegroundPaint);
+            // Airplane mode is slashed, fully drawn background
+            mForegroundPath.reset();
+            mSlash.draw((int) height, (int) width, canvas, mPaint);
         } else if (mState != STATE_CARRIER_CHANGE) {
             mForegroundPath.reset();
             int sigWidth = Math.round(calcFit(mLevel / (mNumLevels - 1)) * (width - 2 * padding));
@@ -417,6 +478,7 @@
 
         void draw(int height, int width, @NonNull Canvas canvas, Paint paint) {
             Matrix m = new Matrix();
+            final float radius = scale(SlashDrawable.CORNER_RADIUS, width);
             updateRect(
                     scale(LEFT, width),
                     scale(TOP, height),
@@ -425,7 +487,7 @@
 
             mPath.reset();
             // Draw the slash vertically
-            mPath.addRect(mSlashRect, Direction.CW);
+            mPath.addRoundRect(mSlashRect, radius, radius, Direction.CW);
             m.setRotate(ROTATION, width / 2, height / 2);
             mPath.transform(m);
             canvas.drawPath(mPath, paint);
@@ -435,7 +497,7 @@
             mPath.transform(m);
             m.setTranslate(mSlashRect.width(), 0);
             mPath.transform(m);
-            mPath.addRect(mSlashRect, Direction.CW);
+            mPath.addRoundRect(mSlashRect, radius, radius, Direction.CW);
             m.setRotate(ROTATION, width / 2, height / 2);
             mPath.transform(m);
             canvas.clipOutPath(mPath);
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 f58fe82..83880e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1,5 +1,3 @@
-
-
 /*
  * Copyright (C) 2010 The Android Open Source Project
  *
@@ -21,7 +19,11 @@
 import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 import static android.app.StatusBarManager.windowStateToString;
+import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
 
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
 import static com.android.systemui.statusbar.notification.NotificationInflater.InflationCallback;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
@@ -31,10 +33,10 @@
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
 
-import android.R.style;
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManager.StackId;
 import android.app.ActivityOptions;
@@ -47,6 +49,8 @@
 import android.app.RemoteInput;
 import android.app.StatusBarManager;
 import android.app.TaskStackBuilder;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentCallbacks2;
@@ -55,6 +59,8 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.IntentSender;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
@@ -112,8 +118,8 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
-import android.view.ContextThemeWrapper;
 import android.view.Display;
+import android.view.HapticFeedbackConstants;
 import android.view.IWindowManager;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -136,6 +142,9 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.graphics.ColorUtils;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
@@ -145,11 +154,11 @@
 import com.android.internal.util.NotificationMessagingUtil;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardHostView.OnDismissAction;
-import com.android.keyguard.KeyguardStatusView;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.ActivityStarterDelegate;
+import com.android.systemui.AutoReinflateContainer;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.DemoMode;
 import com.android.systemui.Dependency;
@@ -166,11 +175,15 @@
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.classifier.FalsingManager;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.doze.DozeLog;
+import com.android.systemui.doze.DozeReceiver;
+import com.android.systemui.fragments.ExtensionFragmentListener;
 import com.android.systemui.fragments.FragmentHostManager;
-import com.android.systemui.fragments.PluginFragmentListener;
 import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
@@ -206,10 +219,10 @@
 import com.android.systemui.statusbar.ScrimView;
 import com.android.systemui.statusbar.SignalClusterView;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.AboveShelfObserver;
 import com.android.systemui.statusbar.notification.InflationException;
 import com.android.systemui.statusbar.notification.RowInflaterTask;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
 import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
@@ -219,6 +232,7 @@
 import com.android.systemui.statusbar.policy.DarkIconDispatcher;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
+import com.android.systemui.statusbar.policy.ExtensionController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.KeyguardMonitorImpl;
@@ -257,7 +271,8 @@
         OnHeadsUpChangedListener, VisualStabilityManager.Callback, CommandQueue.Callbacks,
         ActivatableNotificationView.OnActivatedListener,
         ExpandableNotificationRow.ExpansionLogger, NotificationData.Environment,
-        ExpandableNotificationRow.OnExpandClickListener, InflationCallback {
+        ExpandableNotificationRow.OnExpandClickListener, InflationCallback,
+        ColorExtractor.OnColorsChangedListener, ConfigurationListener {
     public static final boolean MULTIUSER_DEBUG = false;
 
     public static final boolean ENABLE_REMOTE_INPUT =
@@ -301,6 +316,7 @@
     public static final boolean DEBUG_GESTURES = false;
     public static final boolean DEBUG_MEDIA = false;
     public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
+    public static final boolean DEBUG_CAMERA_LIFT = false;
 
     public static final boolean DEBUG_WINDOW_STATE = false;
 
@@ -415,7 +431,6 @@
     private DozeServiceHost mDozeServiceHost;
     private boolean mWakeUpComingFromTouch;
     private PointF mWakeUpTouchLocation;
-    private boolean mScreenTurningOn;
 
     int mPixelFormat;
     Object mQueueLock = new Object();
@@ -427,13 +442,18 @@
     View mExpandedContents;
     TextView mNotificationPanelDebugText;
 
+    /**
+     * {@code true} if notifications not part of a group should by default be rendered in their
+     * expanded state. If {@code false}, then only the first notification will be expanded if
+     * possible.
+     */
+    private boolean mAlwaysExpandNonGroupedNotification;
+
     // settings
     private QSPanel mQSPanel;
 
     // top bar
     protected KeyguardStatusBarView mKeyguardStatusBar;
-    KeyguardStatusView mKeyguardStatusView;
-    KeyguardBottomAreaView mKeyguardBottomArea;
     boolean mLeaveOpenOnKeyguardHide;
     KeyguardIndicationController mKeyguardIndicationController;
 
@@ -501,8 +521,8 @@
                 mUserSetup = userSetup;
                 if (!mUserSetup && mStatusBarView != null)
                     animateCollapseQuickSettings();
-                if (mKeyguardBottomArea != null) {
-                    mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
+                if (mNotificationPanel != null) {
+                    mNotificationPanel.setUserSetupComplete(mUserSetup);
                 }
                 updateQsExpansionEnabled();
             }
@@ -550,7 +570,7 @@
         }};
 
     private boolean mWaitingForKeyguardExit;
-    private boolean mDozing;
+    protected boolean mDozing;
     private boolean mDozingRequested;
     protected boolean mScrimSrcModeEnabled;
 
@@ -621,6 +641,10 @@
     // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
     private int mLastLoggedStateFingerprint;
 
+    public boolean isStartedGoingToSleep() {
+        return mStartedGoingToSleep;
+    }
+
     /**
      * If set, the device has started going to sleep but isn't fully non-interactive yet.
      */
@@ -710,14 +734,22 @@
     private NetworkController mNetworkController;
     private KeyguardMonitorImpl mKeyguardMonitor;
     private BatteryController mBatteryController;
-    private boolean mPanelExpanded;
+    protected boolean mPanelExpanded;
+    private IOverlayManager mOverlayManager;
+    private boolean mKeyguardRequested;
+    private boolean mIsKeyguard;
     private LogMaker mStatusBarStateLog;
     private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
     private NotificationIconAreaController mNotificationIconAreaController;
-    private ConfigurationListener mConfigurationListener;
     private boolean mReinflateNotificationsOnUserSwitched;
     private HashMap<String, Entry> mPendingNotifications = new HashMap<>();
+    private boolean mClearAllEnabled;
+    @Nullable private View mAmbientIndicationContainer;
+    private String mKeyToRemoveOnGutsClosed;
+    private SysuiColorExtractor mColorExtractor;
     private ForegroundServiceController mForegroundServiceController;
+    private ScreenLifecycle mScreenLifecycle;
+    @VisibleForTesting WakefulnessLifecycle mWakefulnessLifecycle;
 
     private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
         final int N = array.size();
@@ -756,25 +788,39 @@
         mNetworkController = Dependency.get(NetworkController.class);
         mUserSwitcherController = Dependency.get(UserSwitcherController.class);
         mKeyguardMonitor = (KeyguardMonitorImpl) Dependency.get(KeyguardMonitor.class);
+        mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
+        mScreenLifecycle.addObserver(mScreenObserver);
+        mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
+        mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
         mBatteryController = Dependency.get(BatteryController.class);
         mAssistManager = Dependency.get(AssistManager.class);
         mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
         mSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
+        mOverlayManager = IOverlayManager.Stub.asInterface(
+                ServiceManager.getService(Context.OVERLAY_SERVICE));
+
+        mColorExtractor = Dependency.get(SysuiColorExtractor.class);
+        mColorExtractor.addOnColorsChangedListener(this);
+
+        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
 
         mForegroundServiceController = Dependency.get(ForegroundServiceController.class);
 
-        mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
         mDisplay = mWindowManager.getDefaultDisplay();
         updateDisplaySize();
-        mScrimSrcModeEnabled = mContext.getResources().getBoolean(
-                R.bool.config_status_bar_scrim_behind_use_src);
+
+        Resources res = mContext.getResources();
+        mScrimSrcModeEnabled = res.getBoolean(R.bool.config_status_bar_scrim_behind_use_src);
+        mClearAllEnabled = res.getBoolean(R.bool.config_enableNotificationsClearAll);
+        mAlwaysExpandNonGroupedNotification =
+                res.getBoolean(R.bool.config_alwaysExpandNonGroupedNotifications);
 
         DateTimeView.setReceiverHandler(Dependency.get(Dependency.TIME_TICK_HANDLER));
         putComponent(StatusBar.class, this);
 
         // start old BaseStatusBar.start().
         mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
-        mDevicePolicyManager = (DevicePolicyManager)mContext.getSystemService(
+        mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
 
         mNotificationData = new NotificationData(this);
@@ -813,7 +859,7 @@
 
         mRecents = getComponent(Recents.class);
 
-        final Configuration currentConfig = mContext.getResources().getConfiguration();
+        final Configuration currentConfig = res.getConfiguration();
         mLocale = currentConfig.locale;
         mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale);
 
@@ -826,7 +872,7 @@
         mCommandQueue.addCallbacks(this);
 
         int[] switches = new int[9];
-        ArrayList<IBinder> binders = new ArrayList<IBinder>();
+        ArrayList<IBinder> binders = new ArrayList<>();
         ArrayList<String> iconSlots = new ArrayList<>();
         ArrayList<StatusBarIcon> icons = new ArrayList<>();
         Rect fullscreenStackBounds = new Rect();
@@ -850,7 +896,6 @@
 
         // Set up the initial icon state
         int N = iconSlots.size();
-        int viewIndex = 0;
         for (int i=0; i < N; i++) {
             mCommandQueue.setIcon(iconSlots.get(i), icons.get(i));
         }
@@ -907,8 +952,8 @@
             Slog.e(TAG, "Failed to register VR mode state listener: " + e);
         }
 
-        mNonBlockablePkgs = new HashSet<String>();
-        Collections.addAll(mNonBlockablePkgs, mContext.getResources().getStringArray(
+        mNonBlockablePkgs = new HashSet<>();
+        Collections.addAll(mNonBlockablePkgs, res.getStringArray(
                 com.android.internal.R.array.config_nonBlockableNotificationPackages));
         // end old BaseStatusBar.start().
 
@@ -945,18 +990,7 @@
 
         Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(this);
 
-        mConfigurationListener = new ConfigurationListener() {
-            @Override
-            public void onConfigChanged(Configuration newConfig) {
-                StatusBar.this.onConfigurationChanged(newConfig);
-            }
-
-            @Override
-            public void onDensityOrFontScaleChanged() {
-                StatusBar.this.onDensityOrFontScaleChanged();
-            }
-        };
-        Dependency.get(ConfigurationController.class).addCallback(mConfigurationListener);
+        Dependency.get(ConfigurationController.class).addCallback(this);
     }
 
     protected void createIconController() {
@@ -969,6 +1003,7 @@
         final Context context = mContext;
         updateDisplaySize(); // populates mDisplayMetrics
         updateResources();
+        updateTheme();
 
         inflateStatusBarWindow(context);
         mStatusBarWindow.setService(this);
@@ -982,6 +1017,9 @@
                 R.id.notification_stack_scroller);
         mNotificationPanel.setStatusBar(this);
         mNotificationPanel.setGroupManager(mGroupManager);
+        mAboveShelfObserver = new AboveShelfObserver(mStackScroller);
+        mAboveShelfObserver.setListener(mStatusBarWindow.findViewById(
+                R.id.notification_container_parent));
         mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
 
         mNotificationIconAreaController = SystemUIFactory.getInstance()
@@ -998,6 +1036,7 @@
                     mStatusBarView.setBar(this);
                     mStatusBarView.setPanel(mNotificationPanel);
                     mStatusBarView.setScrimController(mScrimController);
+                    mStatusBarView.setBouncerShowing(mBouncerShowing);
                     setAreThereNotifications();
                     checkBarModes();
                 }).getFragmentManager()
@@ -1005,16 +1044,8 @@
                 .replace(R.id.status_bar_container, new CollapsedStatusBarFragment(),
                         CollapsedStatusBarFragment.TAG)
                 .commit();
-        Dependency.get(StatusBarIconController.class).addIconGroup(
-                new IconManager((ViewGroup) mKeyguardStatusBar.findViewById(R.id.statusIcons)));
         mIconController = Dependency.get(StatusBarIconController.class);
 
-        if (!ActivityManager.isHighEndGfx()) {
-            mStatusBarWindow.setBackground(null);
-            mNotificationPanel.setBackground(new FastColorDrawable(context.getColor(
-                    R.color.notification_panel_solid_background)));
-        }
-
         mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow, mGroupManager);
         mHeadsUpManager.setBar(this);
         mHeadsUpManager.addListener(this);
@@ -1064,15 +1095,15 @@
             mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
         }
 
-        mKeyguardStatusView =
-                (KeyguardStatusView) mStatusBarWindow.findViewById(R.id.keyguard_status_view);
-        mKeyguardBottomArea =
-                (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
         mKeyguardIndicationController =
                 SystemUIFactory.getInstance().createKeyguardIndicationController(mContext,
                 (ViewGroup) mStatusBarWindow.findViewById(R.id.keyguard_indication_area),
-                mKeyguardBottomArea.getLockIcon());
-        mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
+                mNotificationPanel.getLockIcon());
+        mNotificationPanel.setKeyguardIndicationController(mKeyguardIndicationController);
+
+
+        mAmbientIndicationContainer = mStatusBarWindow.findViewById(
+                R.id.ambient_indication_container);
 
         // set the initial view visibility
         setAreThereNotifications();
@@ -1093,7 +1124,7 @@
             }
         });
 
-        mLightBarController = new LightBarController();
+        mLightBarController = new LightBarController(context);
         if (mNavigationBar != null) {
             mNavigationBar.setLightBarController(mLightBarController);
         }
@@ -1102,7 +1133,12 @@
         ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
         View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
         mScrimController = SystemUIFactory.getInstance().createScrimController(mLightBarController,
-                scrimBehind, scrimInFront, headsUpScrim, mLockscreenWallpaper);
+                scrimBehind, scrimInFront, headsUpScrim, mLockscreenWallpaper,
+                scrimsVisible -> {
+                    if (mStatusBarWindowManager != null) {
+                        mStatusBarWindowManager.setScrimsVisible(scrimsVisible);
+                    }
+                });
         if (mScrimSrcModeEnabled) {
             Runnable runnable = new Runnable() {
                 @Override
@@ -1122,8 +1158,7 @@
         // Other icons
         mVolumeComponent = getComponent(VolumeComponent.class);
 
-        mKeyguardBottomArea.setStatusBar(this);
-        mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
+        mNotificationPanel.setUserSetupComplete(mUserSetup);
         if (UserManager.get(mContext).isUserSwitcherEnabled()) {
             createUserSwitcher();
         }
@@ -1132,14 +1167,15 @@
         View container = mStatusBarWindow.findViewById(R.id.qs_frame);
         if (container != null) {
             FragmentHostManager fragmentHostManager = FragmentHostManager.get(container);
-            fragmentHostManager.getFragmentManager().beginTransaction()
-                    .replace(R.id.qs_frame, new QSFragment(), QS.TAG)
-                    .commit();
-            new PluginFragmentListener(container, QS.TAG, QSFragment.class, QS.class)
-                    .startListening();
+            ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame,
+                    Dependency.get(ExtensionController.class).newExtension(QS.class)
+                            .withPlugin(QS.class)
+                            .withDefault(() -> new QSFragment())
+                            .build());
             final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this,
                     mIconController);
-            mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
+            mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow,
+                    mScrimController);
             fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
                 QS qs = (QS) f;
                 if (qs instanceof QSFragment) {
@@ -1180,7 +1216,6 @@
             });
         }
 
-
         PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         if (!pm.isScreenOn()) {
             mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
@@ -1258,7 +1293,7 @@
         mNotificationShelf.setStatusBarState(mState);
     }
 
-    protected void onDensityOrFontScaleChanged() {
+    public void onDensityOrFontScaleChanged() {
         // start old BaseStatusBar.onDensityOrFontScaleChanged().
         if (!KeyguardUpdateMonitor.getInstance(mContext).isSwitchingUser()) {
             updateNotificationsOnDensityOrFontScaleChanged();
@@ -1272,12 +1307,6 @@
         if (mBrightnessMirrorController != null) {
             mBrightnessMirrorController.onDensityOrFontScaleChanged();
         }
-        inflateSignalClusters();
-        mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
-        inflateDismissView();
-        updateClearAll();
-        inflateEmptyShadeView();
-        updateEmptyShadeView();
         mStatusBarKeyguardViewManager.onDensityOrFontScaleChanged();
         // TODO: Bring these out of StatusBar.
         ((UserInfoControllerImpl) Dependency.get(UserInfoController.class))
@@ -1286,6 +1315,45 @@
         if (mKeyguardUserSwitcher != null) {
             mKeyguardUserSwitcher.onDensityOrFontScaleChanged();
         }
+        mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
+
+        reevaluateStyles();
+    }
+
+    private void reinflateViews() {
+        reevaluateStyles();
+
+        // Clock and bottom icons
+        mNotificationPanel.onOverlayChanged();
+        // The status bar on the keyguard is a special layout.
+        mKeyguardStatusBar.onOverlayChanged();
+        // Recreate Indication controller because internal references changed
+        mKeyguardIndicationController =
+                SystemUIFactory.getInstance().createKeyguardIndicationController(mContext,
+                        mStatusBarWindow.findViewById(R.id.keyguard_indication_area),
+                        mNotificationPanel.getLockIcon());
+        mNotificationPanel.setKeyguardIndicationController(mKeyguardIndicationController);
+        mKeyguardIndicationController
+                .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
+        mKeyguardIndicationController.setVisible(mState == StatusBarState.KEYGUARD);
+        mKeyguardIndicationController.setDozing(mDozing);
+        if (mBrightnessMirrorController != null) {
+            mBrightnessMirrorController.onOverlayChanged();
+        }
+        if (mStatusBarKeyguardViewManager != null) {
+            mStatusBarKeyguardViewManager.onOverlayChanged();
+        }
+        if (mAmbientIndicationContainer instanceof AutoReinflateContainer) {
+            ((AutoReinflateContainer) mAmbientIndicationContainer).inflateLayout();
+        }
+    }
+
+    protected void reevaluateStyles() {
+        inflateSignalClusters();
+        inflateDismissView();
+        updateClearAll();
+        inflateEmptyShadeView();
+        updateEmptyShadeView();
     }
 
     private void updateNotificationsOnDensityOrFontScaleChanged() {
@@ -1334,16 +1402,20 @@
     }
 
     private void inflateEmptyShadeView() {
+        if (mStackScroller == null) {
+            return;
+        }
         mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
                 R.layout.status_bar_no_notifications, mStackScroller, false);
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
     }
 
     private void inflateDismissView() {
-        // Always inflate with a dark theme, since this sits on the scrim.
-        ContextThemeWrapper themedContext = new ContextThemeWrapper(mContext,
-                style.Theme_DeviceDefault);
-        mDismissView = (DismissView) LayoutInflater.from(themedContext).inflate(
+        if (!mClearAllEnabled || mStackScroller == null) {
+            return;
+        }
+
+        mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
                 R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
         mDismissView.setOnButtonClickListener(new View.OnClickListener() {
             @Override
@@ -1440,6 +1512,11 @@
             }
         };
 
+        if (hideAnimatedList.isEmpty()) {
+            animationFinishAction.run();
+            return;
+        }
+
         // let's disable our normal animations
         mStackScroller.setDismissAllInProgress(true);
 
@@ -1479,10 +1556,8 @@
         mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
                 getBouncerContainer(), mScrimController,
                 mFingerprintUnlockController);
-        mKeyguardIndicationController.setStatusBarKeyguardViewManager(
-                mStatusBarKeyguardViewManager);
-        mKeyguardIndicationController.setUserInfoController(
-                Dependency.get(UserInfoController.class));
+        mKeyguardIndicationController
+                .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
         mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
         mRemoteInputController.addCallback(mStatusBarKeyguardViewManager);
 
@@ -1741,6 +1816,14 @@
             mRemoteInputEntriesToRemoveOnCollapse.add(entry);
             return;
         }
+        if (entry != null && mNotificationGutsExposed != null
+                && mNotificationGutsExposed == entry.row.getGuts() && entry.row.getGuts() != null
+                && !entry.row.getGuts().isLeavebehind()) {
+            Log.w(TAG, "Keeping notification because it's showing guts. " + key);
+            mLatestRankingMap = ranking;
+            mKeyToRemoveOnGutsClosed = key;
+            return;
+        }
 
         if (entry != null) {
             mForegroundServiceController.removeNotification(entry.notification);
@@ -1829,6 +1912,11 @@
         } catch (RemoteException ex) {
             // system process is dead if we're here.
         }
+        if (mStackScroller.hasPulsingNotifications() && mHeadsUpManager.getAllEntries().isEmpty()) {
+            // We were showing a pulse for a notification, but no notifications are pulsing anymore.
+            // Finish the pulse.
+            mDozeScrimController.pulseOutNow();
+        }
         // end old BaseStatusBar.performRemoveNotification.
     }
 
@@ -1865,9 +1953,6 @@
             boolean sensitive = userPublic && needsRedaction;
             boolean deviceSensitive = devicePublic
                     && !userAllowsPrivateNotificationsInPublic(mCurrentUserId);
-            if (sensitive) {
-                updatePublicContentView(ent, ent.notification);
-            }
             ent.row.setSensitive(sensitive, deviceSensitive);
             ent.row.setNeedsRedaction(needsRedaction);
             if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) {
@@ -2079,9 +2164,11 @@
     }
 
     private void updateClearAll() {
-        boolean showDismissView =
-                mState != StatusBarState.KEYGUARD &&
-               hasActiveClearableNotifications();
+        if (!mClearAllEnabled) {
+            return;
+        }
+        boolean showDismissView = mState != StatusBarState.KEYGUARD
+                && hasActiveClearableNotifications();
         mStackScroller.updateDismissView(showDismissView);
     }
 
@@ -2598,7 +2685,7 @@
 
     public void setQsExpanded(boolean expanded) {
         mStatusBarWindowManager.setQsExpanded(expanded);
-        mKeyguardStatusView.setImportantForAccessibility(expanded
+        mNotificationPanel.setStatusAccessibilityImportance(expanded
                 ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
                 : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
     }
@@ -2767,10 +2854,6 @@
         mRemoteInputEntriesToRemoveOnCollapse.clear();
     }
 
-    public void onScreenTurnedOff() {
-        mFalsingManager.onScreenOff();
-    }
-
     public NotificationStackScrollLayout getNotificationScrollLayout() {
         return mStackScroller;
     }
@@ -2792,6 +2875,27 @@
         return mNotificationPanel.hideStatusBarIconsWhenExpanded();
     }
 
+    @Override
+    public void onColorsChanged(ColorExtractor extractor, int which) {
+        updateTheme();
+    }
+
+    public boolean isUsingDarkTheme() {
+        OverlayInfo themeInfo = null;
+        try {
+            themeInfo = mOverlayManager.getOverlayInfo("com.android.systemui.theme.dark",
+                    mCurrentUserId);
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+        return themeInfo != null && themeInfo.isEnabled();
+    }
+
+    @Nullable
+    public View getAmbientIndicationContainer() {
+        return mAmbientIndicationContainer;
+    }
+
     /**
      * All changes to the status bar and notifications funnel through here and are batched.
      */
@@ -2848,8 +2952,8 @@
      * settings. Down action closes the entire panel.
      */
     @Override
-    public void handleSystemNavigationKey(int key) {
-        if (SPEW) Log.d(TAG, "handleSystemNavigationKey: " + key);
+    public void handleSystemKey(int key) {
+        if (SPEW) Log.d(TAG, "handleNavigationKey: " + key);
         if (!panelsEnabled() || !mKeyguardMonitor.isDeviceInteractive()
                 || mKeyguardMonitor.isShowing() && !mKeyguardMonitor.isOccluded()) {
             return;
@@ -3381,7 +3485,11 @@
         pw.println(Settings.Global.zenModeToString(mZenMode));
         pw.print("  mUseHeadsUp=");
         pw.println(mUseHeadsUp);
-        dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
+        pw.print("  mKeyToRemoveOnGutsClosed=");
+        pw.println(mKeyToRemoveOnGutsClosed);
+        if (mStatusBarView != null) {
+            dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
+        }
 
         pw.print("  mMediaSessionManager=");
         pw.println(mMediaSessionManager);
@@ -3407,6 +3515,19 @@
             pw.print  ("      ");
             mNotificationPanel.dump(fd, pw, args);
         }
+        pw.println("  mStackScroller: ");
+        if (mStackScroller != null) {
+            pw.print  ("      ");
+            mStackScroller.dump(fd, pw, args);
+        }
+        pw.println("  Theme:");
+        if (mOverlayManager == null) {
+            pw.println("    overlay manager not initialized!");
+        } else {
+            pw.println("    dark overlay on: " + isUsingDarkTheme());
+        }
+        final boolean lightWpTheme = mContext.getThemeResId() == R.style.Theme_SystemUI_Light;
+        pw.println("    light wallpaper theme: " + lightWpTheme);
 
         DozeLog.dump(pw);
 
@@ -3447,7 +3568,9 @@
             pw.println("  mGroupManager: null");
         }
 
-        mLightBarController.dump(fd, pw, args);
+        if (mLightBarController != null) {
+            mLightBarController.dump(fd, pw, args);
+        }
 
         if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
             KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
@@ -3608,7 +3731,6 @@
                 }
             }
             else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
-                notifyHeadsUpScreenOff();
                 finishBarAnimations();
                 resetUserExpandedStates();
             }
@@ -3660,6 +3782,15 @@
 
     private void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
             boolean afterKeyguardGone) {
+        if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP
+                && mUnlockMethodCache.canSkipBouncer()
+                && !mLeaveOpenOnKeyguardHide
+                && isPulsing()) {
+            // Reuse the fingerprint wake-and-unlock transition if we dismiss keyguard from a pulse.
+            // TODO: Factor this transition out of FingerprintUnlockController.
+            mFingerprintUnlockController.startWakeAndUnlock(
+                    FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING);
+        }
         if (mStatusBarKeyguardViewManager.isShowing()) {
             mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
                     afterKeyguardGone);
@@ -3670,7 +3801,7 @@
 
     // SystemUIService notifies SystemBars of configuration changes, which then calls down here
     @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
+    public void onConfigChanged(Configuration newConfig) {
         updateResources();
         updateDisplaySize(); // populates mDisplayMetrics
 
@@ -3841,10 +3972,6 @@
         }
     }
 
-    public void onKeyguardOccludedChanged(boolean keyguardOccluded) {
-        mNavigationBar.onKeyguardOccludedChanged(keyguardOccluded);
-    }
-
     // State logging
 
     private void logStateToEventlog() {
@@ -4012,7 +4139,7 @@
         }
         Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(null);
         mDeviceProvisionedController.removeCallback(mUserSetupObserver);
-        Dependency.get(ConfigurationController.class).removeCallback(mConfigurationListener);
+        Dependency.get(ConfigurationController.class).removeCallback(this);
     }
 
     private boolean mDemoModeAllowed;
@@ -4099,6 +4226,47 @@
     }
 
     public void showKeyguard() {
+        mKeyguardRequested = true;
+        mLeaveOpenOnKeyguardHide = false;
+        mPendingRemoteInputView = null;
+        updateIsKeyguard();
+        mAssistManager.onLockscreenShown();
+    }
+
+    public boolean hideKeyguard() {
+        mKeyguardRequested = false;
+        return updateIsKeyguard();
+    }
+
+    private boolean updateIsKeyguard() {
+        boolean wakeAndUnlocking = mFingerprintUnlockController.getMode()
+                == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
+
+        // For dozing, keyguard needs to be shown whenever the device is non-interactive. Otherwise
+        // there's no surface we can show to the user. Note that the device goes fully interactive
+        // late in the transition, so we also allow the device to start dozing once the screen has
+        // turned off fully.
+        boolean keyguardForDozing = mDozingRequested &&
+                (!mDeviceInteractive || isGoingToSleep() && (isScreenFullyOff() || mIsKeyguard));
+        boolean shouldBeKeyguard = (mKeyguardRequested || keyguardForDozing) && !wakeAndUnlocking;
+        if (keyguardForDozing) {
+            updatePanelExpansionForKeyguard();
+        }
+        if (shouldBeKeyguard) {
+            if (isGoingToSleep()
+                    && mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_TURNING_OFF) {
+                // Delay showing the keyguard until screen turned off.
+            } else {
+                showKeyguardImpl();
+            }
+        } else {
+            return hideKeyguardImpl();
+        }
+        return false;
+    }
+
+    public void showKeyguardImpl() {
+        mIsKeyguard = true;
         if (mLaunchTransitionFadingAway) {
             mNotificationPanel.animate().cancel();
             onLaunchTransitionFadingEnded();
@@ -4110,19 +4278,21 @@
             setBarState(StatusBarState.KEYGUARD);
         }
         updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
-        if (mState == StatusBarState.KEYGUARD) {
-            instantExpandNotificationsPanel();
-        } else if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
-            instantCollapseNotificationPanel();
-        }
-        mLeaveOpenOnKeyguardHide = false;
+        updatePanelExpansionForKeyguard();
         if (mDraggedDownRow != null) {
             mDraggedDownRow.setUserLocked(false);
             mDraggedDownRow.notifyHeightChanged(false  /* needsAnimation */);
             mDraggedDownRow = null;
         }
-        mPendingRemoteInputView = null;
-        mAssistManager.onLockscreenShown();
+    }
+
+    private void updatePanelExpansionForKeyguard() {
+        if (mState == StatusBarState.KEYGUARD && mFingerprintUnlockController.getMode()
+                != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK) {
+            instantExpandNotificationsPanel();
+        } else if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
+            instantCollapseNotificationPanel();
+        }
     }
 
     private void onLaunchTransitionFadingEnded() {
@@ -4131,7 +4301,7 @@
         releaseGestureWakeLock();
         runLaunchTransitionEndRunnable();
         mLaunchTransitionFadingAway = false;
-        mScrimController.forceHideScrims(false /* hide */);
+        mScrimController.forceHideScrims(false /* hide */, false /* animated */);
         updateMediaMetaData(true /* metaDataChanged */, true);
     }
 
@@ -4166,7 +4336,7 @@
                 if (beforeFading != null) {
                     beforeFading.run();
                 }
-                mScrimController.forceHideScrims(true /* hide */);
+                mScrimController.forceHideScrims(true /* hide */, false /* animated */);
                 updateMediaMetaData(false, true);
                 mNotificationPanel.setAlpha(1);
                 mStackScroller.setParentNotFullyVisible(true);
@@ -4246,21 +4416,26 @@
     /**
      * @return true if we would like to stay in the shade, false if it should go away entirely
      */
-    public boolean hideKeyguard() {
+    public boolean hideKeyguardImpl() {
+        mIsKeyguard = false;
         Trace.beginSection("StatusBar#hideKeyguard");
         boolean staying = mLeaveOpenOnKeyguardHide;
         setBarState(StatusBarState.SHADE);
         View viewToClick = null;
         if (mLeaveOpenOnKeyguardHide) {
-            mLeaveOpenOnKeyguardHide = false;
+            if (!mKeyguardRequested) {
+                mLeaveOpenOnKeyguardHide = false;
+            }
             long delay = calculateGoingToFullShadeDelay();
             mNotificationPanel.animateToFullShade(delay);
             if (mDraggedDownRow != null) {
                 mDraggedDownRow.setUserLocked(false);
                 mDraggedDownRow = null;
             }
-            viewToClick = mPendingRemoteInputView;
-            mPendingRemoteInputView = null;
+            if (!mKeyguardRequested) {
+                viewToClick = mPendingRemoteInputView;
+                mPendingRemoteInputView = null;
+            }
 
             // Disable layout transitions in navbar for this transition because the load is just
             // too heavy for the CPU and GPU on any device.
@@ -4385,6 +4560,9 @@
                 mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked);
             }
             mStatusBarView.removePendingHideExpandedRunnables();
+            if (mAmbientIndicationContainer != null) {
+                mAmbientIndicationContainer.setVisibility(View.VISIBLE);
+            }
         } else {
             mKeyguardIndicationController.setVisible(false);
             if (mKeyguardUserSwitcher != null) {
@@ -4393,6 +4571,9 @@
                         mState == StatusBarState.SHADE_LOCKED ||
                         fromShadeLocked);
             }
+            if (mAmbientIndicationContainer != null) {
+                mAmbientIndicationContainer.setVisibility(View.INVISIBLE);
+            }
         }
         if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
             mScrimController.setKeyguardShowing(true);
@@ -4400,6 +4581,7 @@
             mScrimController.setKeyguardShowing(false);
         }
         mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
+        updateTheme();
         updateDozingState();
         updatePublicMode();
         updateStackScrollerState(goingToFullShade, fromShadeLocked);
@@ -4412,7 +4594,56 @@
         Trace.endSection();
     }
 
+    /**
+     * Switches theme from light to dark and vice-versa.
+     */
+    private void updateTheme() {
+        final boolean inflated = mStackScroller != null;
+
+        // The system wallpaper defines if QS should be light or dark.
+        WallpaperColors systemColors = mColorExtractor
+                .getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+        final boolean useDarkTheme = systemColors != null
+                && (systemColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
+        if (isUsingDarkTheme() != useDarkTheme) {
+            try {
+                mOverlayManager.setEnabled("com.android.systemui.theme.dark",
+                        useDarkTheme, mCurrentUserId);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Can't change theme", e);
+            }
+        }
+
+        // Lock wallpaper defines the color of the majority of the views, hence we'll use it
+        // to set our default theme.
+        final boolean lockDarkText = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, true
+                /* ignoreVisibility */).supportsDarkText();
+        final int themeResId = lockDarkText ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI;
+        if (mContext.getThemeResId() != themeResId) {
+            mContext.setTheme(themeResId);
+            if (inflated) {
+                reinflateViews();
+            }
+        }
+
+        if (inflated) {
+            int which;
+            if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
+                which = WallpaperManager.FLAG_LOCK;
+            } else {
+                which = WallpaperManager.FLAG_SYSTEM;
+            }
+            final boolean useDarkText = mColorExtractor.getColors(which,
+                    true /* ignoreVisibility */).supportsDarkText();
+            mStackScroller.updateDecorViews(useDarkText);
+
+            // Make sure we have the correct navbar/statusbar colors.
+            mStatusBarWindowManager.setKeyguardDark(useDarkText);
+        }
+    }
+
     private void updateDozingState() {
+        Trace.traceCounter(Trace.TRACE_TAG_APP, "dozing", mDozing ? 1 : 0);
         Trace.beginSection("StatusBar#updateDozingState");
         boolean animate = !mDozing && mDozeServiceHost.shouldAnimateWakeup();
         mNotificationPanel.setDozing(mDozing, animate);
@@ -4486,7 +4717,7 @@
             animateCollapsePanels();
             return true;
         }
-        if (mKeyguardUserSwitcher.hideIfNotSimple(true)) {
+        if (mKeyguardUserSwitcher != null && mKeyguardUserSwitcher.hideIfNotSimple(true)) {
             return true;
         }
         return false;
@@ -4513,10 +4744,10 @@
     }
 
     private void instantExpandNotificationsPanel() {
-
         // Make our window larger and the panel expanded.
         makeExpandedVisible(true);
         mNotificationPanel.expand(false /* animate */);
+        recomputeDisableFlags(false /* animate */);
     }
 
     private void instantCollapseNotificationPanel() {
@@ -4525,6 +4756,11 @@
 
     @Override
     public void onActivated(ActivatableNotificationView view) {
+        onActivated((View)view);
+        mStackScroller.setActivatedChild(view);
+    }
+
+    public void onActivated(View view) {
         mLockscreenGestureLogger.write(
                 MetricsEvent.ACTION_LS_NOTE,
                 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
@@ -4533,7 +4769,6 @@
         if (previousView != null) {
             previousView.makeInactive(true /* animate */);
         }
-        mStackScroller.setActivatedChild(view);
     }
 
     /**
@@ -4560,17 +4795,22 @@
         mStackScroller.setStatusBarState(state);
         updateReportRejectedTouchVisibility();
         updateDozing();
+        updateTheme();
         mNotificationShelf.setStatusBarState(state);
     }
 
     @Override
     public void onActivationReset(ActivatableNotificationView view) {
         if (view == mStackScroller.getActivatedChild()) {
-            mKeyguardIndicationController.hideTransientIndication();
             mStackScroller.setActivatedChild(null);
+            onActivationReset((View)view);
         }
     }
 
+    public void onActivationReset(View view) {
+        mKeyguardIndicationController.hideTransientIndication();
+    }
+
     public void onTrackingStarted() {
         runPostCollapseRunnables();
     }
@@ -4631,9 +4871,21 @@
         return getMaxKeyguardNotifications(false /* recompute */);
     }
 
-    // TODO: Figure out way to remove this.
+    // TODO: Figure out way to remove these.
     public NavigationBarView getNavigationBarView() {
-        return (NavigationBarView) mNavigationBar.getView();
+        return (mNavigationBar != null ? (NavigationBarView) mNavigationBar.getView() : null);
+    }
+
+    public View getNavigationBarWindow() {
+        return mNavigationBarView;
+    }
+
+    /**
+     * TODO: Remove this method. Views should not be passed forward. Will cause theme issues.
+     * @return bottom area view
+     */
+    public KeyguardBottomAreaView getKeyguardBottomAreaView() {
+        return mNotificationPanel.getKeyguardBottomAreaView();
     }
 
     // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
@@ -4893,60 +5145,105 @@
 
     public void setBouncerShowing(boolean bouncerShowing) {
         mBouncerShowing = bouncerShowing;
-        mStatusBarView.setBouncerShowing(bouncerShowing);
+        if (mStatusBarView != null) mStatusBarView.setBouncerShowing(bouncerShowing);
         recomputeDisableFlags(true /* animate */);
     }
 
-    public void onStartedGoingToSleep() {
-        mStartedGoingToSleep = true;
-    }
 
-    public void onFinishedGoingToSleep() {
-        mNotificationPanel.onAffordanceLaunchEnded();
-        releaseGestureWakeLock();
-        mLaunchCameraOnScreenTurningOn = false;
-        mStartedGoingToSleep = false;
-        mDeviceInteractive = false;
-        mWakeUpComingFromTouch = false;
-        mWakeUpTouchLocation = null;
-        mStackScroller.setAnimationsEnabled(false);
-        mVisualStabilityManager.setScreenOn(false);
-        updateVisibleToUser();
-
-        // We need to disable touch events because these might
-        // collapse the panel after we expanded it, and thus we would end up with a blank
-        // Keyguard.
-        mNotificationPanel.setTouchDisabled(true);
-        mStatusBarWindow.cancelCurrentTouch();
-        if (mLaunchCameraOnFinishedGoingToSleep) {
-            mLaunchCameraOnFinishedGoingToSleep = false;
-
-            // This gets executed before we will show Keyguard, so post it in order that the state
-            // is correct.
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    onCameraLaunchGestureDetected(mLastCameraLaunchSource);
-                }
-            });
-        }
-    }
-
-    public void onStartedWakingUp() {
-        mDeviceInteractive = true;
-        mStackScroller.setAnimationsEnabled(true);
-        mVisualStabilityManager.setScreenOn(true);
-        mNotificationPanel.setTouchDisabled(false);
-        updateVisibleToUser();
-    }
-
-    public void onScreenTurningOn() {
-        mScreenTurningOn = true;
-        mFalsingManager.onScreenTurningOn();
-        mNotificationPanel.onScreenTurningOn();
-        if (mLaunchCameraOnScreenTurningOn) {
-            mNotificationPanel.launchCamera(false, mLastCameraLaunchSource);
+    WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
+        @Override
+        public void onFinishedGoingToSleep() {
+            mNotificationPanel.onAffordanceLaunchEnded();
+            releaseGestureWakeLock();
             mLaunchCameraOnScreenTurningOn = false;
+            mDeviceInteractive = false;
+            mWakeUpComingFromTouch = false;
+            mWakeUpTouchLocation = null;
+            mStackScroller.setAnimationsEnabled(false);
+            mVisualStabilityManager.setScreenOn(false);
+            updateVisibleToUser();
+
+            // We need to disable touch events because these might
+            // collapse the panel after we expanded it, and thus we would end up with a blank
+            // Keyguard.
+            mNotificationPanel.setTouchDisabled(true);
+            mStatusBarWindow.cancelCurrentTouch();
+            if (mLaunchCameraOnFinishedGoingToSleep) {
+                mLaunchCameraOnFinishedGoingToSleep = false;
+
+                // This gets executed before we will show Keyguard, so post it in order that the state
+                // is correct.
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        onCameraLaunchGestureDetected(mLastCameraLaunchSource);
+                    }
+                });
+            }
+            updateIsKeyguard();
+        }
+
+        @Override
+        public void onStartedGoingToSleep() {
+            notifyHeadsUpGoingToSleep();
+            dismissVolumeDialog();
+        }
+
+        @Override
+        public void onStartedWakingUp() {
+            mDeviceInteractive = true;
+            mStackScroller.setAnimationsEnabled(true);
+            mVisualStabilityManager.setScreenOn(true);
+            mNotificationPanel.setTouchDisabled(false);
+
+            maybePrepareWakeUpFromAod();
+
+            mDozeServiceHost.stopDozing();
+            updateVisibleToUser();
+            updateIsKeyguard();
+        }
+    };
+
+    ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
+        @Override
+        public void onScreenTurningOn() {
+            mFalsingManager.onScreenTurningOn();
+            mNotificationPanel.onScreenTurningOn();
+
+            maybePrepareWakeUpFromAod();
+
+            if (mLaunchCameraOnScreenTurningOn) {
+                mNotificationPanel.launchCamera(false, mLastCameraLaunchSource);
+                mLaunchCameraOnScreenTurningOn = false;
+            }
+        }
+
+        @Override
+        public void onScreenTurnedOn() {
+            mScrimController.wakeUpFromAod();
+            mDozeScrimController.onScreenTurnedOn();
+        }
+
+        @Override
+        public void onScreenTurnedOff() {
+            mFalsingManager.onScreenOff();
+            // 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();
+            }
+        }
+    };
+
+    public int getWakefulnessState() {
+        return mWakefulnessLifecycle.getWakefulness();
+    }
+
+    private void maybePrepareWakeUpFromAod() {
+        int wakefulness = mWakefulnessLifecycle.getWakefulness();
+        if (mDozing && (wakefulness == WAKEFULNESS_WAKING
+                || wakefulness == WAKEFULNESS_ASLEEP) && !isPulsing()) {
+            mScrimController.prepareWakeUpFromAod();
         }
     }
 
@@ -4955,9 +5252,12 @@
         mVibrator.vibrate(mCameraLaunchGestureVibePattern, -1 /* repeat */);
     }
 
-    public void onScreenTurnedOn() {
-        mScreenTurningOn = false;
-        mDozeScrimController.onScreenTurnedOn();
+    /**
+     * @return true if the screen is currently fully off, i.e. has finished turning off and has
+     *         since not started turning on.
+     */
+    public boolean isScreenFullyOff() {
+        return mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_OFF;
     }
 
     @Override
@@ -5004,12 +5304,15 @@
     @Override
     public void onCameraLaunchGestureDetected(int source) {
         mLastCameraLaunchSource = source;
-        if (mStartedGoingToSleep) {
+        if (isGoingToSleep()) {
+            if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Finish going to sleep before launching camera");
             mLaunchCameraOnFinishedGoingToSleep = true;
             return;
         }
         if (!mNotificationPanel.canCameraGestureBeLaunched(
                 mStatusBarKeyguardViewManager.isShowing() && mExpandedVisible)) {
+            if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Can't launch camera right now, mExpandedVisible: " +
+                    mExpandedVisible);
             return;
         }
         if (!mDeviceInteractive) {
@@ -5028,18 +5331,42 @@
                 mScrimController.dontAnimateBouncerChangesUntilNextFrame();
                 mGestureWakeLock.acquire(LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
             }
-            if (mScreenTurningOn || mStatusBarKeyguardViewManager.isScreenTurnedOn()) {
+            if (isScreenTurningOnOrOn()) {
+                if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Launching camera");
                 mNotificationPanel.launchCamera(mDeviceInteractive /* animate */, source);
             } else {
                 // We need to defer the camera launch until the screen comes on, since otherwise
                 // we will dismiss us too early since we are waiting on an activity to be drawn and
                 // incorrectly get notified because of the screen on event (which resumes and pauses
                 // some activities)
+                if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Deferring until screen turns on");
                 mLaunchCameraOnScreenTurningOn = true;
             }
         }
     }
 
+    boolean isCameraAllowedByAdmin() {
+        if (mDevicePolicyManager.getCameraDisabled(null, mCurrentUserId)) {
+            return false;
+        } else if (isKeyguardShowing() && isKeyguardSecure()) {
+            // Check if the admin has disabled the camera specifically for the keyguard
+            return (mDevicePolicyManager.getKeyguardDisabledFeatures(null, mCurrentUserId)
+                    & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0;
+        }
+
+        return true;
+    }
+
+    private boolean isGoingToSleep() {
+        return mWakefulnessLifecycle.getWakefulness()
+                == WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
+    }
+
+    private boolean isScreenTurningOnOrOn() {
+        return mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_TURNING_ON
+                || mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON;
+    }
+
     public void notifyFpAuthModeChanged() {
         updateDozing();
     }
@@ -5057,17 +5384,26 @@
             mDozing = false;
         }
         mStatusBarWindowManager.setDozing(mDozing);
+        mStatusBarKeyguardViewManager.setDozing(mDozing);
+        if (mAmbientIndicationContainer instanceof DozeReceiver) {
+            ((DozeReceiver) mAmbientIndicationContainer).setDozing(mDozing);
+        }
         updateDozingState();
         Trace.endSection();
     }
 
     public boolean isKeyguardShowing() {
+        if (mStatusBarKeyguardViewManager == null) {
+            Slog.i(TAG, "isKeyguardShowing() called before startKeyguard(), returning true");
+            return true;
+        }
         return mStatusBarKeyguardViewManager.isShowing();
     }
 
     private final class DozeServiceHost implements DozeHost {
         private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
         private boolean mAnimateWakeup;
+        private boolean mIgnoreTouchWhilePulsing;
 
         @Override
         public String toString() {
@@ -5102,11 +5438,18 @@
                 mDozingRequested = true;
                 DozeLog.traceDozing(mContext, mDozing);
                 updateDozing();
+                updateIsKeyguard();
             }
         }
 
         @Override
         public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
+            if (reason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS) {
+                mPowerManager.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:NODOZE");
+                startAssist(new Bundle());
+                return;
+            }
+
             mDozeScrimController.pulse(new PulseCallback() {
 
                 @Override
@@ -5131,6 +5474,7 @@
                     mStackScroller.setPulsing(pulsing);
                     mNotificationPanel.setPulsing(pulsing != null);
                     mVisualStabilityManager.setPulsing(pulsing != null);
+                    mIgnoreTouchWhilePulsing = false;
                 }
             }, reason);
         }
@@ -5145,8 +5489,19 @@
         }
 
         @Override
+        public void onIgnoreTouchWhilePulsing(boolean ignore) {
+            if (ignore != mIgnoreTouchWhilePulsing) {
+                DozeLog.tracePulseTouchDisabledByProx(mContext, ignore);
+            }
+            mIgnoreTouchWhilePulsing = ignore;
+            if (isDozing() && ignore) {
+                mStatusBarWindow.cancelCurrentTouch();
+            }
+        }
+
+        @Override
         public void dozeTimeTick() {
-            mKeyguardStatusView.refreshTime();
+            mNotificationPanel.refreshTime();
         }
 
         @Override
@@ -5161,6 +5516,21 @@
         }
 
         @Override
+        public boolean isProvisioned() {
+            return mDeviceProvisionedController.isDeviceProvisioned()
+                    && mDeviceProvisionedController.isCurrentUserSetup();
+        }
+
+        @Override
+        public boolean isBlockingDoze() {
+            if (mFingerprintUnlockController.hasPendingAuthentication()) {
+                Log.i(TAG, "Blocking AOD because fingerprint has authenticated");
+                return true;
+            }
+            return false;
+        }
+
+        @Override
         public void startPendingIntentDismissingKeyguard(PendingIntent intent) {
             StatusBar.this.startPendingIntentDismissingKeyguard(intent);
         }
@@ -5177,14 +5547,64 @@
 
         @Override
         public void setAnimateWakeup(boolean animateWakeup) {
+            if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_AWAKE
+                    || mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_WAKING) {
+                // Too late to change the wakeup animation.
+                return;
+            }
             mAnimateWakeup = animateWakeup;
         }
 
+        @Override
+        public void onDoubleTap(float screenX, float screenY) {
+            if (screenX > 0 && screenY > 0 && mAmbientIndicationContainer != null 
+                && mAmbientIndicationContainer.getVisibility() == View.VISIBLE) {
+                mAmbientIndicationContainer.getLocationOnScreen(mTmpInt2);
+                float viewX = screenX - mTmpInt2[0];
+                float viewY = screenY - mTmpInt2[1];
+                if (0 <= viewX && viewX <= mAmbientIndicationContainer.getWidth()
+                        && 0 <= viewY && viewY <= mAmbientIndicationContainer.getHeight()) {
+                    dispatchDoubleTap(viewX, viewY);
+                }
+            }
+        }
+
+        @Override
+        public void setDozeScreenBrightness(int value) {
+            mStatusBarWindowManager.setDozeScreenBrightness(value);
+        }
+
+        @Override
+        public void setAodDimmingScrim(float scrimOpacity) {
+            mDozeScrimController.setAodDimmingScrim(scrimOpacity);
+        }
+
+        public void dispatchDoubleTap(float viewX, float viewY) {
+            dispatchTap(mAmbientIndicationContainer, viewX, viewY);
+            dispatchTap(mAmbientIndicationContainer, viewX, viewY);
+        }
+
+        private void dispatchTap(View view, float x, float y) {
+            long now = SystemClock.elapsedRealtime();
+            dispatchTouchEvent(view, x, y, now, MotionEvent.ACTION_DOWN);
+            dispatchTouchEvent(view, x, y, now, MotionEvent.ACTION_UP);
+        }
+
+        private void dispatchTouchEvent(View view, float x, float y, long now, int action) {
+            MotionEvent ev = MotionEvent.obtain(now, now, action, x, y, 0 /* meta */);
+            view.dispatchTouchEvent(ev);
+            ev.recycle();
+        }
+
         private boolean shouldAnimateWakeup() {
             return mAnimateWakeup;
         }
     }
 
+    public boolean shouldIgnoreTouch() {
+        return isDozing() && mDozeServiceHost.mIgnoreTouchWhilePulsing;
+    }
+
     // Begin Extra BaseStatusBar methods.
 
     protected CommandQueue mCommandQueue;
@@ -5201,6 +5621,8 @@
     // for heads up notifications
     protected HeadsUpManager mHeadsUpManager;
 
+    private AboveShelfObserver mAboveShelfObserver;
+
     // handling reordering
     protected VisualStabilityManager mVisualStabilityManager = new VisualStabilityManager();
 
@@ -5277,6 +5699,10 @@
 
     private Set<String> mNonBlockablePkgs;
 
+    public boolean isDeviceInteractive() {
+        return mDeviceInteractive;
+    }
+
     @Override  // NotificationData.Environment
     public boolean isDeviceProvisioned() {
         return mDeviceProvisionedController.isDeviceProvisioned();
@@ -5365,15 +5791,18 @@
                         boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent);
 
                         // close the shade if it was open
-                        if (handled) {
+                        if (handled && !mNotificationPanel.isFullyCollapsed()) {
                             animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
                                     true /* force */);
                             visibilityChanged(false);
                             mAssistManager.hideAssist();
+
+                            // Wait for activity start.
+                            return true;
+                        } else {
+                            return false;
                         }
 
-                        // Wait for activity start.
-                        return handled;
                     }
                 }, afterKeyguardGone);
                 return true;
@@ -5622,11 +6051,12 @@
         }
     };
 
-    private final NotificationListenerService mNotificationListener =
-            new NotificationListenerService() {
+    private final NotificationListenerWithPlugins mNotificationListener =
+            new NotificationListenerWithPlugins() {
         @Override
         public void onListenerConnected() {
             if (DEBUG) Log.d(TAG, "onListenerConnected");
+            onPluginConnected();
             final StatusBarNotification[] notifications = getActiveNotifications();
             if (notifications == null) {
                 Log.w(TAG, "onListenerConnected unable to get active notifications.");
@@ -5651,7 +6081,7 @@
         public void onNotificationPosted(final StatusBarNotification sbn,
                 final RankingMap rankingMap) {
             if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn);
-            if (sbn != null) {
+            if (sbn != null && !onPluginNotificationPosted(sbn, rankingMap)) {
                 mHandler.post(new Runnable() {
                     @Override
                     public void run() {
@@ -5695,14 +6125,9 @@
         public void onNotificationRemoved(StatusBarNotification sbn,
                 final RankingMap rankingMap) {
             if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn);
-            if (sbn != null) {
+            if (sbn != null && !onPluginNotificationRemoved(sbn, rankingMap)) {
                 final String key = sbn.getKey();
-                mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        removeNotification(key, rankingMap);
-                    }
-                });
+                mHandler.post(() -> removeNotification(key, rankingMap));
             }
         }
 
@@ -5710,13 +6135,10 @@
         public void onNotificationRankingUpdate(final RankingMap rankingMap) {
             if (DEBUG) Log.d(TAG, "onRankingUpdate");
             if (rankingMap != null) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    updateNotificationRanking(rankingMap);
-                }
-            });
-        }                            }
+                RankingMap r = onPluginRankingUpdate(rankingMap);
+                mHandler.post(() -> updateNotificationRanking(r));
+            }
+        }
 
     };
 
@@ -5853,11 +6275,12 @@
     }
 
     public void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) {
-        if (snoozeOption.criterion != null) {
-            mNotificationListener.snoozeNotification(sbn.getKey(), snoozeOption.criterion.getId());
+        if (snoozeOption.getSnoozeCriterion() != null) {
+            mNotificationListener.snoozeNotification(sbn.getKey(),
+                    snoozeOption.getSnoozeCriterion().getId());
         } else {
             mNotificationListener.snoozeNotification(sbn.getKey(),
-                    snoozeOption.snoozeForMinutes * 60 * 1000);
+                    snoozeOption.getMinutesToSnoozeFor() * 60 * 1000);
         }
     }
 
@@ -5875,6 +6298,11 @@
                 mNotificationGutsExposed = null;
                 mGutsMenuItem = null;
             }
+            String key = sbn.getKey();
+            if (key.equals(mKeyToRemoveOnGutsClosed)) {
+                mKeyToRemoveOnGutsClosed = null;
+                removeNotification(key, mLatestRankingMap);
+            }
         });
 
         View gutsView = item.getGutsView();
@@ -5991,6 +6419,7 @@
                 if (row.isDark()) {
                     return false;
                 }
+                v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
                 if (row.areGutsExposed()) {
                     closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
                             true /* removeControls */, -1 /* x */, -1 /* y */,
@@ -6238,6 +6667,10 @@
      * Called when the notification panel layouts
      */
     public void onPanelLaidOut() {
+        updateKeyguardMaxNotifications();
+    }
+
+    public void updateKeyguardMaxNotifications() {
         if (mState == StatusBarState.KEYGUARD) {
             // Since the number of notifications is determined based on the height of the view, we
             // need to update them.
@@ -6272,6 +6705,7 @@
         row.setExpansionLogger(this, entry.notification.getKey());
         row.setGroupManager(mGroupManager);
         row.setHeadsUpManager(mHeadsUpManager);
+        row.setAboveShelfChangedListener(mAboveShelfObserver);
         row.setRemoteInputController(mRemoteInputController);
         row.setOnExpandClickListener(this);
         row.setRemoteViewClickHandler(mOnClickHandler);
@@ -6418,12 +6852,16 @@
                     }
                 }.start();
 
-                // close the shade if it was open
-                animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
-                        true /* force */, true /* delayed */);
-                visibilityChanged(false);
+                if (!mNotificationPanel.isFullyCollapsed()) {
+                    // close the shade if it was open
+                    animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+                            true /* force */, true /* delayed */);
+                    visibilityChanged(false);
 
-                return true;
+                    return true;
+                } else {
+                    return false;
+                }
             }
         }, afterKeyguardGone);
     }
@@ -6468,7 +6906,6 @@
                 }
             });
 
-            final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
             final boolean afterKeyguardGone = intent.isActivity()
                     && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
                             mCurrentUserId);
@@ -6495,7 +6932,7 @@
                         }
                     }
                     final StatusBarNotification parentToCancelFinal = parentToCancel;
-                    new Thread() {
+                    final Runnable runnable = new Runnable() {
                         @Override
                         public void run() {
                             try {
@@ -6567,14 +7004,25 @@
                                 });
                             }
                         }
-                    }.start();
+                    };
 
-                    // close the shade if it was open
-                    animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
-                            true /* force */, true /* delayed */);
-                    visibilityChanged(false);
+                    if (mStatusBarKeyguardViewManager.isShowing()
+                            && mStatusBarKeyguardViewManager.isOccluded()) {
+                        mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
+                    } else {
+                        new Thread(runnable).start();
+                    }
 
-                    return true;
+                    if (!mNotificationPanel.isFullyCollapsed()) {
+                        // close the shade if it was open
+                        animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+                                true /* force */, true /* delayed */);
+                        visibilityChanged(false);
+
+                        return true;
+                    } else {
+                        return false;
+                    }
                 }
             }, afterKeyguardGone);
         }
@@ -6712,13 +7160,18 @@
         while(!stack.isEmpty()) {
             ExpandableNotificationRow row = stack.pop();
             NotificationData.Entry entry = row.getEntry();
-            boolean childNotification = mGroupManager.isChildInGroupWithSummary(entry.notification);
-            if (onKeyguard) {
-                row.setOnKeyguard(true);
-            } else {
-                row.setOnKeyguard(false);
-                row.setSystemExpanded(visibleNotifications == 0 && !childNotification);
+            boolean isChildNotification =
+                    mGroupManager.isChildInGroupWithSummary(entry.notification);
+
+            row.setOnKeyguard(onKeyguard);
+
+            if (!onKeyguard) {
+                // If mAlwaysExpandNonGroupedNotification is false, then only expand the
+                // very first notification and if it's not a child of grouped notifications.
+                row.setSystemExpanded(mAlwaysExpandNonGroupedNotification
+                        || (visibleNotifications == 0 && !isChildNotification));
             }
+
             entry.row.setShowAmbient(isDozing());
             int userId = entry.notification.getUserId();
             boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup(
@@ -6733,7 +7186,7 @@
                 if (wasGone) {
                     entry.row.setVisibility(View.VISIBLE);
                 }
-                if (!childNotification && !entry.row.isRemoved()) {
+                if (!isChildNotification && !entry.row.isRemoved()) {
                     if (wasGone) {
                         // notify the scroller of a child addition
                         mStackScroller.generateAddAnimation(entry.row,
@@ -6753,9 +7206,26 @@
         }
         mNotificationPanel.setNoVisibleNotifications(visibleNotifications == 0);
 
-        mStackScroller.changeViewPosition(mDismissView, mStackScroller.getChildCount() - 1);
-        mStackScroller.changeViewPosition(mEmptyShadeView, mStackScroller.getChildCount() - 2);
-        mStackScroller.changeViewPosition(mNotificationShelf, mStackScroller.getChildCount() - 3);
+        // The following views will be moved to the end of mStackScroller. This counter represents
+        // the offset from the last child. Initialized to 1 for the very last position. It is post-
+        // incremented in the following "changeViewPosition" calls so that its value is correct for
+        // subsequent calls.
+        int offsetFromEnd = 1;
+        if (mDismissView != null) {
+            mStackScroller.changeViewPosition(mDismissView,
+                    mStackScroller.getChildCount() - offsetFromEnd++);
+        }
+
+        mStackScroller.changeViewPosition(mEmptyShadeView,
+                mStackScroller.getChildCount() - offsetFromEnd++);
+
+        // No post-increment for this call because it is the last one. Make sure to add one if
+        // another "changeViewPosition" call is ever added.
+        mStackScroller.changeViewPosition(mNotificationShelf,
+                mStackScroller.getChildCount() - offsetFromEnd);
+
+        // Scrim opacity varies based on notification count
+        mScrimController.setNotificationCount(mStackScroller.getNotGoneChildCount());
     }
 
     public boolean shouldShowOnKeyguard(StatusBarNotification sbn) {
@@ -6806,9 +7276,12 @@
         Entry entry = mNotificationData.get(key);
         if (entry == null) {
             return;
-        } else {
-            mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
-            mRemoteInputEntriesToRemoveOnCollapse.remove(entry);
+        }
+        mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
+        mRemoteInputEntriesToRemoveOnCollapse.remove(entry);
+        if (key.equals(mKeyToRemoveOnGutsClosed)) {
+            mKeyToRemoveOnGutsClosed = null;
+            Log.w(TAG, "Notification that was kept for guts was updated. " + key);
         }
 
         Notification n = notification.getNotification();
@@ -6845,25 +7318,7 @@
         setAreThereNotifications();
     }
 
-    protected void updatePublicContentView(Entry entry,
-            StatusBarNotification sbn) {
-        final RemoteViews publicContentView = entry.cachedPublicContentView;
-        View inflatedView = entry.getPublicContentView();
-        if (entry.autoRedacted && publicContentView != null && inflatedView != null) {
-            final boolean disabledByPolicy =
-                    !adminAllowsUnredactedNotifications(entry.notification.getUserId());
-            String notificationHiddenText = mContext.getString(disabledByPolicy
-                    ? com.android.internal.R.string.notification_hidden_by_policy_text
-                    : com.android.internal.R.string.notification_hidden_text);
-            TextView titleView = (TextView) inflatedView.findViewById(android.R.id.title);
-            if (titleView != null
-                    && !titleView.getText().toString().equals(notificationHiddenText)) {
-                titleView.setText(notificationHiddenText);
-            }
-        }
-    }
-
-    protected void notifyHeadsUpScreenOff() {
+    protected void notifyHeadsUpGoingToSleep() {
         maybeEscalateHeadsUp();
     }
 
@@ -6896,7 +7351,12 @@
             return false;
         }
 
-        if (mNotificationData.shouldSuppressScreenOn(sbn.getKey())) {
+        if (!isDozing() && mNotificationData.shouldSuppressScreenOn(sbn.getKey())) {
+            if (DEBUG) Log.d(TAG, "No peeking: suppressed by DND: " + sbn.getKey());
+            return false;
+        }
+
+        if (isDozing() && mNotificationData.shouldSuppressScreenOff(sbn.getKey())) {
             if (DEBUG) Log.d(TAG, "No peeking: suppressed by DND: " + sbn.getKey());
             return false;
         }
@@ -6923,6 +7383,9 @@
             if (mAccessibilityManager.isTouchExplorationEnabled()) {
                 if (DEBUG) Log.d(TAG, "No peeking: accessible fullscreen: " + sbn.getKey());
                 return false;
+            } else if (mDozing) {
+                // We never want heads up when we are dozing.
+                return false;
             } else {
                 // we only allow head-up on the lockscreen if it doesn't have a fullscreen intent
                 return !mStatusBarKeyguardViewManager.isShowing()
@@ -6998,6 +7461,10 @@
         }
     }
 
+    public NotificationPanelView getPanel() {
+        return mNotificationPanel;
+    }
+
     @Override
     public void startAssist(Bundle args) {
         if (mAssistManager != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index a3ef91d..c240765 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -14,7 +14,10 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.annotation.ColorInt;
 import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
 import android.support.annotation.VisibleForTesting;
 import android.text.TextUtils;
 import android.util.ArraySet;
@@ -26,6 +29,7 @@
 import android.widget.LinearLayout.LayoutParams;
 
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.StatusBarIconView;
@@ -57,7 +61,6 @@
         return ret;
     }
 
-
     /**
      * Version of ViewGroup that observers state from the DarkIconDispatcher.
      */
@@ -108,6 +111,31 @@
         }
     }
 
+    public static class TintedIconManager extends IconManager {
+        private int mColor;
+
+        public TintedIconManager(ViewGroup group) {
+            super(group);
+        }
+
+        @Override
+        protected void onIconAdded(int index, String slot, boolean blocked, StatusBarIcon icon) {
+            StatusBarIconView v = addIcon(index, slot, blocked, icon);
+            v.setStaticDrawableColor(mColor);
+        }
+
+        public void setTint(int color) {
+            mColor = color;
+            for (int i = 0; i < mGroup.getChildCount(); i++) {
+                View child = mGroup.getChildAt(i);
+                if (child instanceof StatusBarIconView) {
+                    StatusBarIconView icon = (StatusBarIconView) child;
+                    icon.setStaticDrawableColor(mColor);
+                }
+            }
+        }
+    }
+
     /**
      * Turns info from StatusBarIconController into ImageViews in a ViewGroup.
      */
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 47c4692..b4b859c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -16,6 +16,10 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.android.keyguard.KeyguardHostView.OnDismissAction;
+import static com.android.systemui.statusbar.phone.FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
+import static com.android.systemui.statusbar.phone.FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
+
 import android.content.ComponentCallbacks2;
 import android.content.Context;
 import android.os.Bundle;
@@ -30,18 +34,15 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.keyguard.LatencyTracker;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.DejankUtils;
-import com.android.keyguard.LatencyTracker;
 import com.android.systemui.Dependency;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.RemoteInputController;
 
-import static com.android.keyguard.KeyguardHostView.OnDismissAction;
-import static com.android.systemui.statusbar.phone.FingerprintUnlockController.*;
-
 import java.util.ArrayList;
 
 /**
@@ -70,6 +71,7 @@
 
     protected final Context mContext;
     private final StatusBarWindowManager mStatusBarWindowManager;
+    private final boolean mDisplayBlanksAfterDoze;
 
     protected LockPatternUtils mLockPatternUtils;
     protected ViewMediatorCallback mViewMediatorCallback;
@@ -79,12 +81,12 @@
 
     private ViewGroup mContainer;
 
-    private boolean mDeviceInteractive = false;
     private boolean mScreenTurnedOn;
     protected KeyguardBouncer mBouncer;
     protected boolean mShowing;
     protected boolean mOccluded;
     protected boolean mRemoteInputActive;
+    private boolean mDozing;
 
     protected boolean mFirstUpdate = true;
     protected boolean mLastShowing;
@@ -92,13 +94,17 @@
     private boolean mLastBouncerShowing;
     private boolean mLastBouncerDismissible;
     protected boolean mLastRemoteInputActive;
+    private boolean mLastDozing;
     private boolean mLastDeferScrimFadeOut;
+    private int mLastFpMode;
 
     private OnDismissAction mAfterKeyguardGoneAction;
     private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>();
-    private boolean mDeviceWillWakeUp;
     private boolean mDeferScrimFadeOut;
 
+    // Dismiss action to be launched when we stop dozing or the keyguard is gone.
+    private DismissWithActionRequest mPendingWakeupAction;
+
     private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
             new KeyguardUpdateMonitorCallback() {
         @Override
@@ -107,7 +113,7 @@
             // Since we won't get a setOccluded call we have to reset the view manually such that
             // the bouncer goes away.
             if (mOccluded) {
-                reset(false /* hideBouncerWhenShowing */);
+                reset(true /* hideBouncerWhenShowing */);
             }
         }
     };
@@ -119,6 +125,8 @@
         mLockPatternUtils = lockPatternUtils;
         mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class);
         KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitorCallback);
+        mDisplayBlanksAfterDoze = context.getResources().getBoolean(
+                com.android.internal.R.bool.config_displayBlanksAfterDoze);
     }
 
     public void registerStatusBar(StatusBar statusBar,
@@ -150,18 +158,23 @@
      * {@link KeyguardBouncer#needsFullscreenBouncer()}.
      */
     protected void showBouncerOrKeyguard(boolean hideBouncerWhenShowing) {
-        if (mBouncer.needsFullscreenBouncer()) {
-
+        if (mBouncer.needsFullscreenBouncer() && !mDozing) {
             // The keyguard might be showing (already). So we need to hide it.
             mStatusBar.hideKeyguard();
             mBouncer.show(true /* resetSecuritySelection */);
         } else {
             mStatusBar.showKeyguard();
             if (hideBouncerWhenShowing) {
-                mBouncer.hide(false /* destroyView */);
+                hideBouncer(false /* destroyView */);
                 mBouncer.prepare();
             }
         }
+        updateStates();
+    }
+
+    private void hideBouncer(boolean destroyView) {
+        mBouncer.hide(destroyView);
+        cancelPendingWakeupAction();
     }
 
     private void showBouncer() {
@@ -174,6 +187,15 @@
     public void dismissWithAction(OnDismissAction r, Runnable cancelAction,
             boolean afterKeyguardGone) {
         if (mShowing) {
+            cancelPendingWakeupAction();
+            // If we're dozing, this needs to be delayed until after we wake up - unless we're
+            // wake-and-unlocking, because there dozing will last until the end of the transition.
+            if (mDozing && !isWakeAndUnlocking()) {
+                mPendingWakeupAction = new DismissWithActionRequest(
+                        r, cancelAction, afterKeyguardGone);
+                return;
+            }
+
             if (!afterKeyguardGone) {
                 mBouncer.showWithDismissAction(r, cancelAction);
             } else {
@@ -184,6 +206,11 @@
         updateStates();
     }
 
+    private boolean isWakeAndUnlocking() {
+        int mode = mFingerprintUnlockController.getMode();
+        return mode == MODE_WAKE_AND_UNLOCK || mode == MODE_WAKE_AND_UNLOCK_PULSING;
+    }
+
     /**
      * Adds a {@param runnable} to be executed after Keyguard is gone.
      */
@@ -196,10 +223,12 @@
      */
     public void reset(boolean hideBouncerWhenShowing) {
         if (mShowing) {
-            if (mOccluded) {
+            if (mOccluded && !mDozing) {
                 mStatusBar.hideKeyguard();
                 mStatusBar.stopWaitingForKeyguardExit();
-                mBouncer.hide(false /* destroyView */);
+                if (hideBouncerWhenShowing || mBouncer.needsFullscreenBouncer()) {
+                    hideBouncer(false /* destroyView */);
+                }
             } else {
                 showBouncerOrKeyguard(hideBouncerWhenShowing);
             }
@@ -209,31 +238,19 @@
     }
 
     public void onStartedGoingToSleep() {
-        mStatusBar.onStartedGoingToSleep();
+        // TODO: remove
     }
 
     public void onFinishedGoingToSleep() {
-        mDeviceInteractive = false;
-        mStatusBar.onFinishedGoingToSleep();
         mBouncer.onScreenTurnedOff();
     }
 
     public void onStartedWakingUp() {
-        Trace.beginSection("StatusBarKeyguardViewManager#onStartedWakingUp");
-        mDeviceInteractive = true;
-        mDeviceWillWakeUp = false;
-        mStatusBar.onStartedWakingUp();
-        Trace.endSection();
+        // TODO: remove
     }
 
     public void onScreenTurningOn() {
-        Trace.beginSection("StatusBarKeyguardViewManager#onScreenTurningOn");
-        mStatusBar.onScreenTurningOn();
-        Trace.endSection();
-    }
-
-    public boolean isScreenTurnedOn() {
-        return mScreenTurnedOn;
+        // TODO: remove
     }
 
     public void onScreenTurnedOn() {
@@ -245,7 +262,6 @@
                     true /* skipFirstFrame */);
             updateStates();
         }
-        mStatusBar.onScreenTurnedOn();
         Trace.endSection();
     }
 
@@ -255,13 +271,26 @@
         updateStates();
     }
 
+    public void setDozing(boolean dozing) {
+        if (mDozing != dozing) {
+            mDozing = dozing;
+            if (dozing || mBouncer.needsFullscreenBouncer() || mOccluded) {
+                reset(dozing /* hideBouncerWhenShowing */);
+            }
+            updateStates();
+
+            if (!dozing) {
+                launchPendingWakeupAction();
+            }
+        }
+    }
+
     public void onScreenTurnedOff() {
         mScreenTurnedOn = false;
-        mStatusBar.onScreenTurnedOff();
     }
 
     public void notifyDeviceWakeUpRequested() {
-        mDeviceWillWakeUp = !mDeviceInteractive;
+        // TODO: remove
     }
 
     public void setNeedsInput(boolean needsInput) {
@@ -273,9 +302,6 @@
     }
 
     public void setOccluded(boolean occluded, boolean animate) {
-        if (occluded != mOccluded) {
-            mStatusBar.onKeyguardOccludedChanged(occluded);
-        }
         if (occluded && !mOccluded && mShowing) {
             if (mStatusBar.isInLaunchTransition()) {
                 mOccluded = true;
@@ -290,15 +316,19 @@
                 return;
             }
         }
+        boolean isOccluding = !mOccluded && occluded;
         mOccluded = occluded;
         if (mShowing) {
             mStatusBar.updateMediaMetaData(false, animate && !occluded);
         }
         mStatusBarWindowManager.setKeyguardOccluded(occluded);
 
-        // If Keyguard is reshown, don't hide the bouncer as it might just have been requested by
-        // a FLAG_DISMISS_KEYGUARD_ACTIVITY.
-        reset(false /* hideBouncerWhenShowing*/);
+        // setDozing(false) will call reset once we stop dozing.
+        if (!mDozing) {
+            // If Keyguard is reshown, don't hide the bouncer as it might just have been requested
+            // by a FLAG_DISMISS_KEYGUARD_ACTIVITY.
+            reset(isOccluding /* hideBouncerWhenShowing*/);
+        }
         if (animate && !occluded && mShowing) {
             mStatusBar.animateKeyguardUnoccluding();
         }
@@ -328,6 +358,7 @@
      */
     public void hide(long startTime, long fadeoutDuration) {
         mShowing = false;
+        launchPendingWakeupAction();
 
         if (KeyguardUpdateMonitor.getInstance(mContext).needsSlowUnlockTransition()) {
             fadeoutDuration = KEYGUARD_DISMISS_DURATION_LOCKED;
@@ -341,7 +372,7 @@
                 public void run() {
                     mStatusBarWindowManager.setKeyguardShowing(false);
                     mStatusBarWindowManager.setKeyguardFadingAway(true);
-                    mBouncer.hide(true /* destroyView */);
+                    hideBouncer(true /* destroyView */);
                     updateStates();
                     mScrimController.animateKeyguardFadingOut(
                             StatusBar.FADE_KEYGUARD_START_DELAY,
@@ -367,7 +398,7 @@
             }
             mStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
             mFingerprintUnlockController.startKeyguardFadingAway();
-            mBouncer.hide(true /* destroyView */);
+            hideBouncer(true /* destroyView */);
             if (wakeUnlockPulsing) {
                 mStatusBarWindowManager.setKeyguardFadingAway(true);
                 mStatusBar.fadeKeyguardWhilePulsing();
@@ -380,7 +411,11 @@
                 if (!staying) {
                     mStatusBarWindowManager.setKeyguardFadingAway(true);
                     if (mFingerprintUnlockController.getMode() == MODE_WAKE_AND_UNLOCK) {
-                        if (!mScreenTurnedOn) {
+                        boolean turnedOnSinceAuth =
+                                mFingerprintUnlockController.hasScreenTurnedOnSinceAuthenticating();
+                        if (!mScreenTurnedOn || mDisplayBlanksAfterDoze && !turnedOnSinceAuth) {
+                            // Not ready to animate yet; either because the screen is not on yet,
+                            // or it is on but will turn off before waking out of doze.
                             mDeferScrimFadeOut = true;
                         } else {
 
@@ -406,7 +441,12 @@
     }
 
     public void onDensityOrFontScaleChanged() {
-        mBouncer.hide(true /* destroyView */);
+        hideBouncer(true /* destroyView */);
+    }
+
+    public void onOverlayChanged() {
+        hideBouncer(true /* destroyView */);
+        mBouncer.prepare();
     }
 
     private void animateScrimControllerKeyguardFadingOut(long delay, long duration,
@@ -498,11 +538,11 @@
     private long getNavBarShowDelay() {
         if (mStatusBar.isKeyguardFadingAway()) {
             return mStatusBar.getKeyguardFadingAwayDelay();
-        } else {
-
-            // Keyguard is not going away, thus we are showing the navigation bar because the
-            // bouncer is appearing.
+        } else if (mBouncer.isShowing()) {
             return NAV_BAR_SHOW_DELAY_BOUNCER;
+        } else {
+            // No longer dozing, or remote input is active. No delay.
+            return 0;
         }
     }
 
@@ -570,7 +610,9 @@
         mLastBouncerShowing = bouncerShowing;
         mLastBouncerDismissible = bouncerDismissible;
         mLastRemoteInputActive = remoteInputActive;
+        mLastDozing = mDozing;
         mLastDeferScrimFadeOut = mDeferScrimFadeOut;
+        mLastFpMode = mFingerprintUnlockController.getMode();
         mStatusBar.onKeyguardViewManagerStatesUpdated();
     }
 
@@ -578,16 +620,21 @@
      * @return Whether the navigation bar should be made visible based on the current state.
      */
     protected boolean isNavBarVisible() {
-        return (!(mShowing && !mOccluded) || mBouncer.isShowing() || mRemoteInputActive)
-                && !mDeferScrimFadeOut;
+        int fpMode = mFingerprintUnlockController.getMode();
+        boolean keyguardShowing = mShowing && !mOccluded;
+        boolean hideWhileDozing = mDozing && fpMode != MODE_WAKE_AND_UNLOCK_PULSING;
+        return (!keyguardShowing && !hideWhileDozing || mBouncer.isShowing()
+                || mRemoteInputActive) && !mDeferScrimFadeOut;
     }
 
     /**
      * @return Whether the navigation bar was made visible based on the last known state.
      */
     protected boolean getLastNavBarVisible() {
-        return (!(mLastShowing && !mLastOccluded) || mLastBouncerShowing || mLastRemoteInputActive)
-                && !mLastDeferScrimFadeOut;
+        boolean keyguardShowing = mLastShowing && !mLastOccluded;
+        boolean hideWhileDozing = mLastDozing && mLastFpMode != MODE_WAKE_AND_UNLOCK_PULSING;
+        return (!keyguardShowing && !hideWhileDozing || mLastBouncerShowing
+                || mLastRemoteInputActive) && !mLastDeferScrimFadeOut;
     }
 
     public boolean shouldDismissOnMenuPressed() {
@@ -638,4 +685,38 @@
     public ViewRootImpl getViewRootImpl() {
         return mStatusBar.getStatusBarView().getViewRootImpl();
     }
+
+    public void launchPendingWakeupAction() {
+        DismissWithActionRequest request = mPendingWakeupAction;
+        mPendingWakeupAction = null;
+        if (request != null) {
+            if (mShowing) {
+                dismissWithAction(request.dismissAction, request.cancelAction,
+                        request.afterKeyguardGone);
+            } else if (request.dismissAction != null) {
+                request.dismissAction.onDismiss();
+            }
+        }
+    }
+
+    public void cancelPendingWakeupAction() {
+        DismissWithActionRequest request = mPendingWakeupAction;
+        mPendingWakeupAction = null;
+        if (request != null && request.cancelAction != null) {
+            request.cancelAction.run();
+        }
+    }
+
+    private static class DismissWithActionRequest {
+        final OnDismissAction dismissAction;
+        final Runnable cancelAction;
+        final boolean afterKeyguardGone;
+
+        DismissWithActionRequest(OnDismissAction dismissAction, Runnable cancelAction,
+                boolean afterKeyguardGone) {
+            this.dismissAction = dismissAction;
+            this.cancelAction = cancelAction;
+            this.afterKeyguardGone = afterKeyguardGone;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 0326e40..d886508 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -58,7 +58,7 @@
     private boolean mHasTopUiChanged;
     private int mBarHeight;
     private final boolean mKeyguardScreenRotation;
-    private final float mScreenBrightnessDoze;
+    private float mScreenBrightnessDoze;
     private final State mCurrentState = new State();
     private OtherwisedCollapsedListener mListener;
 
@@ -111,6 +111,22 @@
         mLpChanged.copyFrom(mLp);
     }
 
+    public void setDozeScreenBrightness(int value) {
+        mScreenBrightnessDoze = value / 255f;
+    }
+
+    public void setKeyguardDark(boolean dark) {
+        int vis = mStatusBarView.getSystemUiVisibility();
+        if (dark) {
+            vis = vis | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+            vis = vis | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+        } else {
+            vis = vis & ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+            vis = vis & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+        }
+        mStatusBarView.setSystemUiVisibility(vis);
+    }
+
     private void applyKeyguardFlags(State state) {
         if (state.keyguardShowing) {
             mLpChanged.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
@@ -126,7 +142,7 @@
     }
 
     private void adjustScreenOrientation(State state) {
-        if (state.isKeyguardShowingAndNotOccluded()) {
+        if (state.isKeyguardShowingAndNotOccluded() || state.dozing) {
             if (mKeyguardScreenRotation) {
                 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
             } else {
@@ -170,7 +186,7 @@
     private boolean isExpanded(State state) {
         return !state.forceCollapsed && (state.isKeyguardShowingAndNotOccluded()
                 || state.panelVisible || state.keyguardFadingAway || state.bouncerShowing
-                || state.headsUpShowing);
+                || state.headsUpShowing || state.scrimsVisible);
     }
 
     private void applyFitsSystemWindows(State state) {
@@ -309,6 +325,11 @@
         apply(mCurrentState);
     }
 
+    public void setScrimsVisible(boolean scrimsVisible) {
+        mCurrentState.scrimsVisible = scrimsVisible;
+        apply(mCurrentState);
+    }
+
     public void setHeadsUpShowing(boolean showing) {
         mCurrentState.headsUpShowing = showing;
         apply(mCurrentState);
@@ -410,6 +431,7 @@
         boolean remoteInputActive;
         boolean forcePluginOpen;
         boolean dozing;
+        boolean scrimsVisible;
 
         private boolean isKeyguardShowingAndNotOccluded() {
             return keyguardShowing && !keyguardOccluded;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index adc33a1..3d24bd0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -249,6 +249,10 @@
     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
         boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN;
+        boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL;
+        if (!isCancel && mService.shouldIgnoreTouch()) {
+            return false;
+        }
         if (isDown && mNotificationPanel.isFullyCollapsed()) {
             mNotificationPanel.startExpandLatencyTracking();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 2783ec5..9b0179d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -17,10 +17,18 @@
 package com.android.systemui.statusbar.phone;
 
 import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.UserHandle;
 import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
 
 /**
  * Base class for dialogs that should appear over panels and keyguard.
@@ -59,7 +67,7 @@
         setButton(BUTTON_NEGATIVE, mContext.getString(resId), onClick);
     }
 
-    public static void setShowForAllUsers(AlertDialog dialog, boolean show) {
+    public static void setShowForAllUsers(Dialog dialog, boolean show) {
         if (show) {
             dialog.getWindow().getAttributes().privateFlags |=
                     WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
@@ -69,9 +77,40 @@
         }
     }
 
-    public static void applyFlags(AlertDialog dialog) {
+    public static void setWindowOnTop(Dialog dialog) {
+        if (Dependency.get(KeyguardMonitor.class).isShowing()) {
+            dialog.getWindow().setType(LayoutParams.TYPE_STATUS_BAR_PANEL);
+        } else {
+            dialog.getWindow().setType(LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
+        }
+    }
+
+    public static AlertDialog applyFlags(AlertDialog dialog) {
         dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
         dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                 | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+        return dialog;
+    }
+
+    public static void registerDismissListener(Dialog dialog) {
+        boolean[] registered = new boolean[1];
+        Context context = dialog.getContext();
+        final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (dialog != null) {
+                    dialog.dismiss();
+                }
+            }
+        };
+        context.registerReceiverAsUser(mReceiver, UserHandle.CURRENT,
+                new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), null, null);
+        registered[0] = true;
+        dialog.setOnDismissListener(d -> {
+            if (registered[0]) {
+                context.unregisterReceiver(mReceiver);
+                registered[0] = false;
+            }
+        });
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java
index d5a91bb..028da86 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java
@@ -31,6 +31,7 @@
 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;
 
@@ -82,7 +83,7 @@
 
         mPaint = new Paint();
         mPaint.setStyle(Paint.Style.STROKE);
-        mPaint.setColor(Color.WHITE);
+        mPaint.setColor(Utils.getColorAttr(context, R.attr.wallpaperTextColor));
         mPaint.setAntiAlias(true);
         mPaint.setStrokeWidth(mThickness);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
index d1e4963..c0a6837 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
@@ -97,8 +97,9 @@
 
     @Override
     public void scanForAccessPoints() {
-        if (DEBUG) Log.d(TAG, "scan!");
-        mWifiTracker.forceScan();
+        if (DEBUG) Log.d(TAG, "force update APs!");
+        mWifiTracker.forceUpdate();
+        fireAcccessPointsCallback(mWifiTracker.getAccessPoints());
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index fc86ac3..e8d5af6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -207,14 +207,19 @@
             registerReceiver();
             updatePowerSave();
         } else if (mDemoMode && command.equals(COMMAND_BATTERY)) {
-           String level = args.getString("level");
-           String plugged = args.getString("plugged");
-           if (level != null) {
-               mLevel = Math.min(Math.max(Integer.parseInt(level), 0), 100);
-           }
-           if (plugged != null) {
-               mPluggedIn = Boolean.parseBoolean(plugged);
-           }
+            String level = args.getString("level");
+            String plugged = args.getString("plugged");
+            String powerSave = args.getString("powersave");
+            if (level != null) {
+                mLevel = Math.min(Math.max(Integer.parseInt(level), 0), 100);
+            }
+            if (plugged != null) {
+                mPluggedIn = Boolean.parseBoolean(plugged);
+            }
+            if (powerSave != null) {
+                mPowerSave = powerSave.equals("true");
+                firePowerSaveChanged();
+            }
             fireBatteryLevelChanged();
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index 21d03fd..42ce4c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -16,51 +16,56 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.util.ArraySet;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewPropertyAnimator;
 import android.widget.FrameLayout;
 
+import com.android.internal.util.Preconditions;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.statusbar.ScrimView;
+import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.StatusBarWindowView;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 /**
  * Controls showing and hiding of the brightness mirror.
  */
-public class BrightnessMirrorController {
+public class BrightnessMirrorController
+        implements CallbackController<BrightnessMirrorController.BrightnessMirrorListener> {
 
     private final NotificationStackScrollLayout mStackScroller;
     public long TRANSITION_DURATION_OUT = 150;
     public long TRANSITION_DURATION_IN = 200;
 
     private final StatusBarWindowView mStatusBarWindow;
-    private final ScrimView mScrimBehind;
+    private final ScrimController mScrimController;
     private final View mNotificationPanel;
+    private final ArraySet<BrightnessMirrorListener> mBrightnessMirrorListeners = new ArraySet<>();
     private final int[] mInt2Cache = new int[2];
     private View mBrightnessMirror;
 
-    public BrightnessMirrorController(StatusBarWindowView statusBarWindow) {
+    public BrightnessMirrorController(StatusBarWindowView statusBarWindow,
+            ScrimController scrimController) {
         mStatusBarWindow = statusBarWindow;
-        mScrimBehind = (ScrimView) statusBarWindow.findViewById(R.id.scrim_behind);
         mBrightnessMirror = statusBarWindow.findViewById(R.id.brightness_mirror);
         mNotificationPanel = statusBarWindow.findViewById(R.id.notification_panel);
         mStackScroller = (NotificationStackScrollLayout) statusBarWindow.findViewById(
                 R.id.notification_stack_scroller);
+        mScrimController = scrimController;
     }
 
     public void showMirror() {
         mBrightnessMirror.setVisibility(View.VISIBLE);
         mStackScroller.setFadingOut(true);
-        mScrimBehind.animateViewAlpha(0.0f, TRANSITION_DURATION_OUT, Interpolators.ALPHA_OUT);
+        mScrimController.forceHideScrims(true /* hide */, true /* animated */);
         outAnimation(mNotificationPanel.animate())
                 .withLayer();
     }
 
     public void hideMirror() {
-        mScrimBehind.animateViewAlpha(1.0f, TRANSITION_DURATION_IN, Interpolators.ALPHA_IN);
+        mScrimController.forceHideScrims(false /* hide */, true /* animated */);
         inAnimation(mNotificationPanel.animate())
                 .withLayer()
                 .withEndAction(new Runnable() {
@@ -84,7 +89,6 @@
                 .setInterpolator(Interpolators.ALPHA_IN);
     }
 
-
     public void setLocation(View original) {
         original.getLocationInWindow(mInt2Cache);
 
@@ -109,17 +113,44 @@
         FrameLayout.LayoutParams lp =
                 (FrameLayout.LayoutParams) mBrightnessMirror.getLayoutParams();
         lp.width = mBrightnessMirror.getResources().getDimensionPixelSize(
-                R.dimen.notification_panel_width);
+                R.dimen.qs_panel_width);
         lp.gravity = mBrightnessMirror.getResources().getInteger(
                 R.integer.notification_panel_layout_gravity);
         mBrightnessMirror.setLayoutParams(lp);
     }
 
+    public void onOverlayChanged() {
+        reinflate();
+    }
+
     public void onDensityOrFontScaleChanged() {
+        reinflate();
+    }
+
+    private void reinflate() {
         int index = mStatusBarWindow.indexOfChild(mBrightnessMirror);
         mStatusBarWindow.removeView(mBrightnessMirror);
         mBrightnessMirror = LayoutInflater.from(mBrightnessMirror.getContext()).inflate(
                 R.layout.brightness_mirror, mStatusBarWindow, false);
         mStatusBarWindow.addView(mBrightnessMirror, index);
+
+        for (int i = 0; i < mBrightnessMirrorListeners.size(); i++) {
+            mBrightnessMirrorListeners.valueAt(i).onBrightnessMirrorReinflated(mBrightnessMirror);
+        }
+    }
+
+    @Override
+    public void addCallback(BrightnessMirrorListener listener) {
+        Preconditions.checkNotNull(listener);
+        mBrightnessMirrorListeners.add(listener);
+    }
+
+    @Override
+    public void removeCallback(BrightnessMirrorListener listener) {
+        mBrightnessMirrorListeners.remove(listener);
+    }
+
+    public interface BrightnessMirrorListener {
+        void onBrightnessMirrorReinflated(View brightnessMirror);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index b89a77b..2bf62bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -182,7 +182,7 @@
                 Log.w(TAG, "Projection is no longer active: " + projection);
             }
         } else {
-            mMediaRouter.getDefaultRoute().select();
+            mMediaRouter.getFallbackRoute().select();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java
index 788fda8..3dca371 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java
@@ -27,5 +27,7 @@
     interface ConfigurationListener {
         default void onConfigChanged(Configuration newConfig) {}
         default void onDensityOrFontScaleChanged() {}
+        default void onOverlayChanged() {}
+        default void onLocaleListChanged() {}
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
index cfaca0d..f2283a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
@@ -102,15 +102,21 @@
     }
 
     private void notifyUserChanged() {
-        mListeners.forEach(c -> c.onUserSwitched());
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onUserSwitched();
+        }
     }
 
     private void notifySetupChanged() {
-        mListeners.forEach(c -> c.onUserSetupChanged());
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onUserSetupChanged();
+        }
     }
 
     private void notifyProvisionedChanged() {
-        mListeners.forEach(c -> c.onDeviceProvisionedChanged());
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onDeviceProvisionedChanged();
+        }
     }
 
     protected final ContentObserver mSettingsObserver = new ContentObserver(Dependency.get(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionController.java
index 78e0028..ede8411 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionController.java
@@ -14,6 +14,8 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.content.Context;
+
 import java.util.Map;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
@@ -28,12 +30,21 @@
 
     interface Extension<T> {
         T get();
+        Context getContext();
         void destroy();
+        void addCallback(Consumer<T> callback);
         /**
          * Triggers the extension to cycle through each of the sources again because something
          * (like configuration) may have changed.
          */
         T reload();
+
+        /**
+         * Null out the cached item for the purpose of memory saving, should only be done
+         * when any other references are already gotten.
+         * @param isDestroyed
+         */
+        void clearItem(boolean isDestroyed);
     }
 
     interface ExtensionBuilder<T> {
@@ -44,6 +55,7 @@
                 PluginConverter<T, P> converter);
         ExtensionBuilder<T> withDefault(Supplier<T> def);
         ExtensionBuilder<T> withCallback(Consumer<T> callback);
+        ExtensionBuilder<T> withUiMode(int mode, Supplier<T> def);
         Extension build();
     }
 
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 cfc1d56..6df2051 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionControllerImpl.java
@@ -14,23 +14,39 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.content.Context;
+import android.content.res.Configuration;
+import android.os.Handler;
+import android.util.ArrayMap;
+
 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.statusbar.policy.ConfigurationController.ConfigurationListener;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
-
-import android.content.Context;
-import android.util.ArrayMap;
+import com.android.systemui.util.leak.LeakDetector;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 
 public class ExtensionControllerImpl implements ExtensionController {
 
+    public static final int SORT_ORDER_PLUGIN  = 0;
+    public static final int SORT_ORDER_TUNER   = 1;
+    public static final int SORT_ORDER_UI_MODE = 2;
+    public static final int SORT_ORDER_DEFAULT = 3;
+
+    private final Context mDefaultContext;
+
+    public ExtensionControllerImpl(Context context) {
+        mDefaultContext = context;
+    }
+
     @Override
     public <T> ExtensionBuilder<T> newExtension(Class<T> cls) {
         return new ExtensionBuilder<>();
@@ -38,6 +54,7 @@
 
     private interface Producer<T> {
         T get();
+
         void destroy();
     }
 
@@ -75,6 +92,12 @@
             return this;
         }
 
+        public ExtensionController.ExtensionBuilder<T> withUiMode(int uiMode,
+                Supplier<T> supplier) {
+            mExtension.addUiMode(uiMode, supplier);
+            return this;
+        }
+
         @Override
         public ExtensionController.ExtensionBuilder<T> withCallback(
                 Consumer<T> callback) {
@@ -85,34 +108,21 @@
         @Override
         public ExtensionController.Extension build() {
             // Manually sort, plugins first, tuners second, defaults last.
-            Collections.sort(mExtension.mProducers, (o1, o2) -> {
-                if (o1 instanceof ExtensionImpl.PluginItem) {
-                    if (o2 instanceof ExtensionImpl.PluginItem) {
-                        return 0;
-                    } else {
-                        return -1;
-                    }
-                }
-                if (o1 instanceof ExtensionImpl.TunerItem) {
-                    if (o2 instanceof ExtensionImpl.PluginItem) {
-                        return 1;
-                    } else if (o2 instanceof ExtensionImpl.TunerItem) {
-                        return 0;
-                    } else {
-                        return -1;
-                    }
-                }
-                return 0;
-            });
+            Collections.sort(mExtension.mProducers, Comparator.comparingInt(Item::sortOrder));
             mExtension.notifyChanged();
             return mExtension;
         }
     }
 
     private class ExtensionImpl<T> implements ExtensionController.Extension<T> {
-        private final ArrayList<Producer<T>> mProducers = new ArrayList<>();
+        private final ArrayList<Item<T>> mProducers = new ArrayList<>();
         private final ArrayList<Consumer<T>> mCallbacks = new ArrayList<>();
         private T mItem;
+        private Context mPluginContext;
+
+        public void addCallback(Consumer<T> callback) {
+            mCallbacks.add(callback);
+        }
 
         @Override
         public T get() {
@@ -120,6 +130,11 @@
         }
 
         @Override
+        public Context getContext() {
+            return mPluginContext != null ? mPluginContext : mDefaultContext;
+        }
+
+        @Override
         public void destroy() {
             for (int i = 0; i < mProducers.size(); i++) {
                 mProducers.get(i).destroy();
@@ -132,7 +147,19 @@
             return get();
         }
 
+        @Override
+        public void clearItem(boolean isDestroyed) {
+            if (isDestroyed && mItem != null) {
+                Dependency.get(LeakDetector.class).trackGarbage(mItem);
+            }
+            mItem = null;
+        }
+
         private void notifyChanged() {
+            if (mItem != null) {
+                Dependency.get(LeakDetector.class).trackGarbage(mItem);
+            }
+            mItem = null;
             for (int i = 0; i < mProducers.size(); i++) {
                 final T item = mProducers.get(i).get();
                 if (item != null) {
@@ -154,10 +181,14 @@
         }
 
         public void addTunerFactory(TunerFactory<T> factory, String[] keys) {
-            mProducers.add(new TunerItem(factory, factory.keys()));
+            mProducers.add(new TunerItem(factory, keys));
         }
 
-        private class PluginItem<P extends Plugin> implements Producer<T>, PluginListener<P> {
+        public void addUiMode(int uiMode, Supplier<T> mode) {
+            mProducers.add(new UiModeItem(uiMode, mode));
+        }
+
+        private class PluginItem<P extends Plugin> implements Item<T>, PluginListener<P> {
             private final PluginConverter<T, P> mConverter;
             private T mItem;
 
@@ -168,6 +199,7 @@
 
             @Override
             public void onPluginConnected(P plugin, Context pluginContext) {
+                mPluginContext = pluginContext;
                 if (mConverter != null) {
                     mItem = mConverter.getInterfaceFromPlugin(plugin);
                 } else {
@@ -178,6 +210,7 @@
 
             @Override
             public void onPluginDisconnected(P plugin) {
+                mPluginContext = null;
                 mItem = null;
                 notifyChanged();
             }
@@ -191,9 +224,14 @@
             public void destroy() {
                 Dependency.get(PluginManager.class).removePluginListener(this);
             }
+
+            @Override
+            public int sortOrder() {
+                return SORT_ORDER_PLUGIN;
+            }
         }
 
-        private class TunerItem<T> implements Producer<T>, Tunable {
+        private class TunerItem<T> implements Item<T>, Tunable {
             private final TunerFactory<T> mFactory;
             private final ArrayMap<String, String> mSettings = new ArrayMap<>();
             private T mItem;
@@ -219,9 +257,54 @@
                 mItem = mFactory.create(mSettings);
                 notifyChanged();
             }
+
+            @Override
+            public int sortOrder() {
+                return SORT_ORDER_TUNER;
+            }
         }
 
-        private class Default<T> implements Producer<T> {
+        private class UiModeItem<T> implements Item<T>, ConfigurationListener {
+
+            private final int mDesiredUiMode;
+            private final Supplier<T> mSupplier;
+            private int mUiMode;
+            private Handler mHandler = new Handler();
+
+            public UiModeItem(int uiMode, Supplier<T> supplier) {
+                mDesiredUiMode = uiMode;
+                mSupplier = supplier;
+                mUiMode = mDefaultContext.getResources().getConfiguration().uiMode;
+                Dependency.get(ConfigurationController.class).addCallback(this);
+            }
+
+            @Override
+            public void onConfigChanged(Configuration newConfig) {
+                int newMode = newConfig.uiMode & Configuration.UI_MODE_TYPE_MASK;
+                if (newMode != mUiMode) {
+                    mUiMode = newMode;
+                    // Post to make sure we don't have concurrent modifications.
+                    mHandler.post(ExtensionImpl.this::notifyChanged);
+                }
+            }
+
+            @Override
+            public T get() {
+                return (mUiMode == mDesiredUiMode) ? mSupplier.get() : null;
+            }
+
+            @Override
+            public void destroy() {
+                Dependency.get(ConfigurationController.class).removeCallback(this);
+            }
+
+            @Override
+            public int sortOrder() {
+                return SORT_ORDER_UI_MODE;
+            }
+        }
+
+        private class Default<T> implements Item<T> {
             private final Supplier<T> mSupplier;
 
             public Default(Supplier<T> supplier) {
@@ -237,6 +320,15 @@
             public void destroy() {
 
             }
+
+            @Override
+            public int sortOrder() {
+                return SORT_ORDER_DEFAULT;
+            }
         }
     }
+
+    private interface Item<T> extends Producer<T> {
+        int sortOrder();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 5f7ac5d..53dfb24 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -20,6 +20,7 @@
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.support.v4.util.ArraySet;
@@ -65,7 +66,7 @@
     private final ArrayMap<String, Long> mSnoozedPackages;
     private final HashSet<OnHeadsUpChangedListener> mListeners = new HashSet<>();
     private final int mDefaultSnoozeLengthMs;
-    private final Handler mHandler = new Handler();
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
     private final Pools.Pool<HeadsUpEntry> mEntryPool = new Pools.Pool<HeadsUpEntry>() {
 
         private Stack<HeadsUpEntry> mPoolObjects = new Stack<>();
@@ -257,6 +258,12 @@
         mEntryPool.release(remove);
     }
 
+    public void removeAllHeadsUpEntries() {
+        for (String key : mHeadsUpEntries.keySet()) {
+            removeHeadsUpEntry(mHeadsUpEntries.get(key).entry);
+        }
+    }
+
     private void updatePinnedMode() {
         boolean hasPinnedNotification = hasPinnedNotificationInternal();
         if (hasPinnedNotification == mHasPinnedNotification) {
@@ -618,6 +625,7 @@
 
     @Override
     public void onReorderingAllowed() {
+        mBar.getNotificationScrollLayout().setHeadsUpGoingAwayAnimationsAllowed(false);
         for (NotificationData.Entry entry : mEntriesToRemoveWhenReorderingAllowed) {
             if (isHeadsUp(entry.key)) {
                 // Maybe the heads-up was removed already
@@ -625,6 +633,7 @@
             }
         }
         mEntriesToRemoveWhenReorderingAllowed.clear();
+        mBar.getNotificationScrollLayout().setHeadsUpGoingAwayAnimationsAllowed(true);
     }
 
     public void setVisualStabilityManager(VisualStabilityManager visualStabilityManager) {
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 d777961..65bfabd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -113,6 +113,11 @@
         setBackground(mRipple);
     }
 
+    @Override
+    public boolean isClickable() {
+        return mCode != 0 || super.isClickable();
+    }
+
     public void setCode(int code) {
         mCode = code;
     }
@@ -226,6 +231,11 @@
             case MotionEvent.ACTION_UP:
                 final boolean doIt = isPressed() && !mLongClicked;
                 setPressed(false);
+                // Always send a release ourselves because it doesn't seem to be sent elsewhere
+                // and it feels weird to sometimes get a release haptic and other times not.
+                if ((SystemClock.uptimeMillis() - mDownTime) > 150 && !mLongClicked) {
+                    performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
+                }
                 if (mCode != 0) {
                     if (doIt) {
                         sendEvent(KeyEvent.ACTION_UP, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
index 728005d..ccfbb26a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
@@ -21,12 +21,13 @@
     boolean isSecure();
     boolean canSkipBouncer();
     boolean isShowing();
+    boolean isOccluded();
     boolean isKeyguardFadingAway();
     boolean isKeyguardGoingAway();
     long getKeyguardFadingAwayDuration();
     long getKeyguardFadingAwayDelay();
 
-    public interface Callback {
+    interface Callback {
         void onKeyguardShowingChanged();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index 874f0d9..6d6aa52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -39,6 +39,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static com.android.settingslib.Utils.updateLocationMode;
+
 /**
  * A controller to manage changes of location related states and update the views accordingly.
  */
@@ -106,12 +108,13 @@
         final ContentResolver cr = mContext.getContentResolver();
         // When enabling location, a user consent dialog will pop up, and the
         // setting won't be fully enabled until the user accepts the agreement.
+        int currentMode = Settings.Secure.getIntForUser(cr, Settings.Secure.LOCATION_MODE,
+                Settings.Secure.LOCATION_MODE_OFF, currentUserId);
         int mode = enabled
                 ? Settings.Secure.LOCATION_MODE_PREVIOUS : Settings.Secure.LOCATION_MODE_OFF;
         // QuickSettings always runs as the owner, so specifically set the settings
         // for the current foreground user.
-        return Settings.Secure
-                .putIntForUser(cr, Settings.Secure.LOCATION_MODE, mode, currentUserId);
+        return updateLocationMode(mContext, currentMode, mode, currentUserId);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index efce871..b93fb22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -182,6 +182,7 @@
         mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_B, TelephonyIcons.THREE_G);
         mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EHRPD, TelephonyIcons.THREE_G);
         mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UMTS, TelephonyIcons.THREE_G);
+        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_TD_SCDMA, TelephonyIcons.THREE_G);
 
         if (!mConfig.showAtLeast3G) {
             mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN,
@@ -235,6 +236,9 @@
     }
 
     private int getNumLevels() {
+        if (mConfig.inflateSignalStrengths) {
+            return SignalStrength.NUM_SIGNAL_STRENGTH_BINS + 1;
+        }
         return SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
     }
 
@@ -243,7 +247,11 @@
         if (mCurrentState.iconGroup == TelephonyIcons.CARRIER_NETWORK_CHANGE) {
             return SignalDrawable.getCarrierChangeState(getNumLevels());
         } else if (mCurrentState.connected) {
-            return SignalDrawable.getState(mCurrentState.level, getNumLevels(),
+            int level = mCurrentState.level;
+            if (mConfig.inflateSignalStrengths) {
+                level++;
+            }
+            return SignalDrawable.getState(level, getNumLevels(),
                     mCurrentState.inetCondition == 0);
         } else if (mCurrentState.enabled) {
             return SignalDrawable.getEmptyState(getNumLevels());
@@ -334,6 +342,10 @@
     }
 
     private boolean isRoaming() {
+        // During a carrier change, roaming indications need to be supressed.
+        if (isCarrierNetworkChangeActive()) {
+            return false;
+        }
         if (isCdma()) {
             final int iconMode = mServiceState.getCdmaEriIconMode();
             return mServiceState.getCdmaEriIconIndex() != EriInfo.ROAMING_INDICATOR_OFF
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index c02ce0e..2771011 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -67,29 +67,15 @@
 
     public static class IconState {
         public final boolean visible;
-
         public final int icon;
-
-        /**
-         * Optional iconOverlay resource id.
-         *
-         * <p>Set to -1 if not present.
-         */
-        public final int iconOverlay;
-
         public final String contentDescription;
 
-        public IconState(boolean visible, int icon, int iconOverlay, String contentDescription) {
+        public IconState(boolean visible, int icon, String contentDescription) {
             this.visible = visible;
             this.icon = icon;
-            this.iconOverlay = iconOverlay;
             this.contentDescription = contentDescription;
         }
 
-        public IconState(boolean visible, int icon, String contentDescription) {
-            this(visible, icon, -1 /* iconOverlay */, contentDescription);
-        }
-
         public IconState(boolean visible, int icon, int contentDescription,
                 Context context) {
             this(visible, icon, context.getString(contentDescription));
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 c21f444..c217bda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -24,7 +24,6 @@
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
 import android.net.NetworkCapabilities;
-import android.net.NetworkScoreManager;
 import android.net.wifi.WifiManager;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -92,7 +91,6 @@
     private final DataSaverController mDataSaverController;
     private final CurrentUserTracker mUserTracker;
     private Config mConfig;
-    private final NetworkScoreManager mNetworkScoreManager;
 
     // Subcontrollers.
     @VisibleForTesting
@@ -149,12 +147,9 @@
     public NetworkControllerImpl(Context context, Looper bgLooper,
             DeviceProvisionedController deviceProvisionedController) {
         this(context, (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE),
-                context.getSystemService(NetworkScoreManager.class),
                 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
                 (WifiManager) context.getSystemService(Context.WIFI_SERVICE),
-                SubscriptionManager.from(context),
-                Config.readConfig(context),
-                bgLooper,
+                SubscriptionManager.from(context), Config.readConfig(context), bgLooper,
                 new CallbackHandler(),
                 new AccessPointControllerImpl(context, bgLooper),
                 new DataUsageController(context),
@@ -165,12 +160,8 @@
 
     @VisibleForTesting
     NetworkControllerImpl(Context context, ConnectivityManager connectivityManager,
-            NetworkScoreManager networkScoreManager,
-            TelephonyManager telephonyManager,
-            WifiManager wifiManager,
-            SubscriptionManager subManager,
-            Config config,
-            Looper bgLooper,
+            TelephonyManager telephonyManager, WifiManager wifiManager,
+            SubscriptionManager subManager, Config config, Looper bgLooper,
             CallbackHandler callbackHandler,
             AccessPointControllerImpl accessPointController,
             DataUsageController dataUsageController,
@@ -193,7 +184,6 @@
 
         // wifi
         mWifiManager = wifiManager;
-        mNetworkScoreManager = networkScoreManager;
 
         mLocale = mContext.getResources().getConfiguration().locale;
         mAccessPoints = accessPointController;
@@ -207,7 +197,7 @@
             }
         });
         mWifiSignalController = new WifiSignalController(mContext, mHasMobileDataFeature,
-                mCallbackHandler, this, mNetworkScoreManager);
+                mCallbackHandler, this);
 
         mEthernetSignalController = new EthernetSignalController(mContext, mCallbackHandler, this);
 
@@ -968,6 +958,7 @@
         boolean show4gForLte = false;
         boolean hideLtePlus = false;
         boolean hspaDataDistinguishable;
+        boolean inflateSignalStrengths = false;
 
         static Config readConfig(Context context) {
             Config config = new Config();
@@ -980,6 +971,7 @@
             config.hspaDataDistinguishable =
                     res.getBoolean(R.bool.config_hspa_data_distinguishable);
             config.hideLtePlus = res.getBoolean(R.bool.config_hideLtePlus);
+            config.inflateSignalStrengths = res.getBoolean(R.bool.config_inflateSignalStrength);
             return config;
         }
     }
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 efbf76b..b22ce18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -90,6 +90,10 @@
     private ArrayMap<Integer, Boolean> mHasCACerts = new ArrayMap<Integer, Boolean>();
 
     public SecurityControllerImpl(Context context) {
+        this(context, null);
+    }
+
+    public SecurityControllerImpl(Context context, SecurityControllerCallback callback) {
         super(context);
         mContext = context;
         mDevicePolicyManager = (DevicePolicyManager)
@@ -102,6 +106,8 @@
         mUserManager = (UserManager)
                 context.getSystemService(Context.USER_SERVICE);
 
+        addCallback(callback);
+
         IntentFilter filter = new IntentFilter();
         filter.addAction(KeyChain.ACTION_TRUST_STORE_CHANGED);
         context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
index b1e4b03..527addf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
@@ -131,6 +131,7 @@
         final int userId = userInfo.id;
         final boolean isGuest = userInfo.isGuest();
         final String userName = userInfo.name;
+        final boolean lightIcon = mContext.getThemeResId() != R.style.Theme_SystemUI_Light;
 
         final Resources res = mContext.getResources();
         final int avatarSize = Math.max(
@@ -154,7 +155,7 @@
                             .setIcon(rawAvatar).setBadgeIfManagedUser(mContext, userId).bake();
                 } else {
                     avatar = UserIcons.getDefaultUserIcon(isGuest? UserHandle.USER_NULL : userId,
-                            /* light= */ true);
+                            lightIcon);
                 }
 
                 // If it's a single-user device, get the profile name, since the nickname is not
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index e0f4429..700c01a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -57,6 +57,8 @@
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
 import com.android.systemui.GuestResumeSessionReceiver;
+import com.android.systemui.Prefs;
+import com.android.systemui.Prefs.Key;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUISecondaryUserService;
@@ -235,6 +237,9 @@
                         }
                     }
                 }
+                if (records.size() > 1 || guestRecord != null) {
+                    Prefs.putBoolean(mContext, Key.SEEN_MULTI_USER, true);
+                }
 
                 boolean systemCanCreateUsers = !mUserManager.hasBaseUserRestriction(
                                 UserManager.DISALLOW_ADD_USER, UserHandle.SYSTEM);
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 2104cb1..2819624 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -17,50 +17,33 @@
 
 import android.content.Context;
 import android.content.Intent;
-import android.database.ContentObserver;
-import android.net.NetworkBadging;
 import android.net.NetworkCapabilities;
-import android.net.NetworkKey;
-import android.net.NetworkScoreManager;
-import android.net.ScoredNetwork;
 import android.net.wifi.WifiManager;
-import android.net.wifi.WifiNetworkScoreCache;
-import android.net.wifi.WifiNetworkScoreCache.CacheListener;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
-import android.provider.Settings;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.AsyncChannel;
-import com.android.settingslib.Utils;
 import com.android.settingslib.wifi.WifiStatusTracker;
+import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
 
-import com.android.systemui.R;
-
 import java.util.Objects;
-import java.util.List;
 
 
 public class WifiSignalController extends
         SignalController<WifiSignalController.WifiState, SignalController.IconGroup> {
-
     private final WifiManager mWifiManager;
     private final AsyncChannel mWifiChannel;
     private final boolean mHasMobileData;
-    private final NetworkScoreManager mNetworkScoreManager;
-    private final WifiNetworkScoreCache mScoreCache;
     private final WifiStatusTracker mWifiTracker;
 
-    private boolean mScoringUiEnabled = false;
-
     public WifiSignalController(Context context, boolean hasMobileData,
-            CallbackHandler callbackHandler, NetworkControllerImpl networkController,
-            NetworkScoreManager networkScoreManager) {
+            CallbackHandler callbackHandler, NetworkControllerImpl networkController) {
         super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI,
                 callbackHandler, networkController);
         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
@@ -85,44 +68,6 @@
                 AccessibilityContentDescriptions.WIFI_NO_CONNECTION
                 );
 
-        mScoreCache = new WifiNetworkScoreCache(context, new CacheListener(handler) {
-            @Override
-            public void networkCacheUpdated(List<ScoredNetwork> networks) {
-                mCurrentState.badgeEnum = getWifiBadgeEnum();
-                notifyListenersIfNecessary();
-            }
-        });
-
-        // Setup scoring
-        mNetworkScoreManager = networkScoreManager;
-        configureScoringGating();
-        registerScoreCache();
-    }
-
-    private void configureScoringGating() {
-        ContentObserver observer = new ContentObserver(new Handler(Looper.getMainLooper())) {
-            @Override
-            public void onChange(boolean selfChange) {
-                mScoringUiEnabled =
-                        Settings.Global.getInt(
-                                mContext.getContentResolver(),
-                                Settings.Global.NETWORK_SCORING_UI_ENABLED, 0) == 1;
-            }
-        };
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.NETWORK_SCORING_UI_ENABLED),
-                false /* notifyForDescendants */,
-                observer);
-
-        observer.onChange(false /* selfChange */); // Set the initial values
-    }
-
-    private void registerScoreCache() {
-        Log.d(mTag, "Registered score cache");
-        mNetworkScoreManager.registerNetworkScoreCache(
-                NetworkKey.TYPE_WIFI,
-                mScoreCache,
-                NetworkScoreManager.CACHE_FILTER_CURRENT_NETWORK);
     }
 
     @Override
@@ -143,77 +88,27 @@
                     ("," + mContext.getString(R.string.accessibility_quick_settings_no_internet));
         }
 
-        IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(),
-                Utils.getWifiBadgeResource(mCurrentState.badgeEnum), contentDescription);
-        IconState qsIcon = new IconState(
-                mCurrentState.connected, getQsCurrentIconId(),
-                Utils.getWifiBadgeResource(mCurrentState.badgeEnum), contentDescription);
+        IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(), contentDescription);
+        IconState qsIcon = new IconState(mCurrentState.connected, getQsCurrentIconId(),
+                contentDescription);
         callback.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon,
                 ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut,
                 wifiDesc, mCurrentState.isTransient);
     }
 
-    @Override
-    public int getCurrentIconId() {
-        if (mCurrentState.badgeEnum != NetworkBadging.BADGING_NONE) {
-            return Utils.WIFI_PIE_FOR_BADGING[mCurrentState.level];
-        }
-        return super.getCurrentIconId();
-    }
-
     /**
      * Extract wifi state directly from broadcasts about changes in wifi state.
      */
     public void handleBroadcast(Intent intent) {
-        // Update the WifiStatusTracker with the new information and update the score cache.
-        NetworkKey previousNetworkKey = mWifiTracker.networkKey;
         mWifiTracker.handleBroadcast(intent);
-        updateScoreCacheIfNecessary(previousNetworkKey);
-
-        mCurrentState.isTransient = mWifiTracker.state == WifiManager.WIFI_STATE_ENABLING
-                || mWifiTracker.state == WifiManager.WIFI_AP_STATE_DISABLING
-                || mWifiTracker.connecting;
         mCurrentState.enabled = mWifiTracker.enabled;
         mCurrentState.connected = mWifiTracker.connected;
         mCurrentState.ssid = mWifiTracker.ssid;
         mCurrentState.rssi = mWifiTracker.rssi;
         mCurrentState.level = mWifiTracker.level;
-        mCurrentState.badgeEnum = getWifiBadgeEnum();
         notifyListenersIfNecessary();
     }
 
-    /**
-     * Clears old scores out of the cache and requests new scores if the network key has changed.
-     *
-     * <p>New scores are requested asynchronously.
-     */
-    private void updateScoreCacheIfNecessary(NetworkKey previousNetworkKey) {
-        if (mWifiTracker.networkKey == null) {
-            return;
-        }
-        if ((previousNetworkKey == null) || !mWifiTracker.networkKey.equals(previousNetworkKey)) {
-            mScoreCache.clearScores();
-            mNetworkScoreManager.requestScores(new NetworkKey[]{mWifiTracker.networkKey});
-        }
-    }
-
-    /**
-     * Returns the wifi badge enum for the current {@link #mWifiTracker} state.
-     *
-     * <p>{@link #updateScoreCacheIfNecessary} should be called prior to this method.
-     */
-    private int getWifiBadgeEnum() {
-        if (!mScoringUiEnabled || mWifiTracker.networkKey == null) {
-            return NetworkBadging.BADGING_NONE;
-        }
-        ScoredNetwork score = mScoreCache.getScoredNetwork(mWifiTracker.networkKey);
-
-        if (score != null) {
-            return score.calculateBadge(mWifiTracker.rssi);
-        }
-        return NetworkBadging.BADGING_NONE;
-    }
-
     @VisibleForTesting
     void setActivity(int wifiActivity) {
         mCurrentState.activityIn = wifiActivity == WifiManager.DATA_ACTIVITY_INOUT
@@ -254,7 +149,6 @@
 
     static class WifiState extends SignalController.State {
         String ssid;
-        int badgeEnum;
         boolean isTransient;
 
         @Override
@@ -262,7 +156,6 @@
             super.copyFrom(s);
             WifiState state = (WifiState) s;
             ssid = state.ssid;
-            badgeEnum = state.badgeEnum;
             isTransient = state.isTransient;
         }
 
@@ -270,7 +163,6 @@
         protected void toString(StringBuilder builder) {
             super.toString(builder);
             builder.append(',').append("ssid=").append(ssid);
-            builder.append(',').append("badgeEnum=").append(badgeEnum);
             builder.append(',').append("isTransient=").append(isTransient);
         }
 
@@ -278,7 +170,6 @@
         public boolean equals(Object o) {
             return super.equals(o)
                     && Objects.equals(((WifiState) o).ssid, ssid)
-                    && (((WifiState) o).badgeEnum == badgeEnum)
                     && (((WifiState) o).isTransient == isTransient);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
index 41ef781..4d8da44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
@@ -21,11 +21,15 @@
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.ActivatableNotificationView;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.ExpandableView;
+import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 
 import java.util.ArrayList;
+import java.util.Collection;
 
 /**
  * A global state to track all input states for the algorithm.
@@ -59,8 +63,10 @@
     private boolean mPanelTracking;
     private boolean mExpansionChanging;
     private boolean mPanelFullWidth;
-    private boolean mHasPulsingNotifications;
+    private Collection<HeadsUpManager.HeadsUpEntry> mPulsing;
     private boolean mUnlockHintRunning;
+    private boolean mQsCustomizerShowing;
+    private int mIntrinsicPadding;
 
     public AmbientState(Context context) {
         reload(context);
@@ -288,11 +294,23 @@
     }
 
     public boolean hasPulsingNotifications() {
-        return mHasPulsingNotifications;
+        return mPulsing != null;
     }
 
-    public void setHasPulsingNotifications(boolean hasPulsing) {
-        mHasPulsingNotifications = hasPulsing;
+    public void setPulsing(Collection<HeadsUpManager.HeadsUpEntry> hasPulsing) {
+        mPulsing = hasPulsing;
+    }
+
+    public boolean isPulsing(NotificationData.Entry entry) {
+        if (mPulsing == null) {
+            return false;
+        }
+        for (HeadsUpManager.HeadsUpEntry e : mPulsing) {
+            if (e.entry == entry) {
+                return true;
+            }
+        }
+        return false;
     }
 
     public boolean isPanelTracking() {
@@ -314,4 +332,50 @@
     public boolean isUnlockHintRunning() {
         return mUnlockHintRunning;
     }
+
+    public boolean isQsCustomizerShowing() {
+        return mQsCustomizerShowing;
+    }
+
+    public void setQsCustomizerShowing(boolean qsCustomizerShowing) {
+        mQsCustomizerShowing = qsCustomizerShowing;
+    }
+
+    public void setIntrinsicPadding(int intrinsicPadding) {
+        mIntrinsicPadding = intrinsicPadding;
+    }
+
+    public int getIntrinsicPadding() {
+        return mIntrinsicPadding;
+    }
+
+    /**
+     * Similar to the normal is above shelf logic but doesn't allow it to be above in AOD1.
+     *
+     * @param expandableView the view to check
+     */
+    public boolean isAboveShelf(ExpandableView expandableView) {
+        if (!(expandableView instanceof ExpandableNotificationRow)) {
+            return expandableView.isAboveShelf();
+        }
+        ExpandableNotificationRow row = (ExpandableNotificationRow) expandableView;
+        return row.isAboveShelf() && !isDozingAndNotPulsing(row);
+    }
+
+    /**
+     * @return whether a view is dozing and not pulsing right now
+     */
+    public boolean isDozingAndNotPulsing(ExpandableView view) {
+        if (view instanceof ExpandableNotificationRow) {
+            return isDozingAndNotPulsing((ExpandableNotificationRow) view);
+        }
+        return false;
+    }
+
+    /**
+     * @return whether a row is dozing and not pulsing right now
+     */
+    public boolean isDozingAndNotPulsing(ExpandableNotificationRow row) {
+        return isDark() && !isPulsing(row.getEntry());
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index b6964a03..fe53104 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -19,6 +19,7 @@
 import android.app.Notification;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.drawable.ColorDrawable;
 import android.service.notification.StatusBarNotification;
 import android.util.AttributeSet;
@@ -66,8 +67,9 @@
     private final HybridGroupManager mHybridGroupManager;
     private int mChildPadding;
     private int mDividerHeight;
-    private int mMaxNotificationHeight;
+    private float mDividerAlpha;
     private int mNotificationHeaderMargin;
+
     private int mNotificatonTopPadding;
     private float mCollapsedBottompadding;
     private boolean mChildrenExpanded;
@@ -80,6 +82,11 @@
     private boolean mNeverAppliedGroupState;
     private int mHeaderHeight;
 
+    /**
+     * Whether or not individual notifications that are part of this container will have shadows.
+     */
+    private boolean mEnableShadowOnChildNotifications;
+
     private NotificationHeaderView mNotificationHeader;
     private NotificationViewWrapper mNotificationHeaderWrapper;
     private NotificationHeaderView mNotificationHeaderLowPriority;
@@ -93,6 +100,9 @@
     private OnClickListener mHeaderClickListener;
     private ViewGroup mCurrentHeader;
 
+    private boolean mShowDividersWhenExpanded;
+    private boolean mHideDividersDuringExpand;
+
     public NotificationChildrenContainer(Context context) {
         this(context, null);
     }
@@ -113,19 +123,25 @@
     }
 
     private void initDimens() {
-        mChildPadding = getResources().getDimensionPixelSize(
-                R.dimen.notification_children_padding);
-        mDividerHeight = Math.max(1, getResources().getDimensionPixelSize(
-                R.dimen.notification_divider_height));
-        mHeaderHeight = getResources().getDimensionPixelSize(R.dimen.notification_header_height);
-        mMaxNotificationHeight = getResources().getDimensionPixelSize(
-                R.dimen.notification_max_height);
-        mNotificationHeaderMargin = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_content_margin_top);
-        mNotificatonTopPadding = getResources().getDimensionPixelSize(
+        Resources res = getResources();
+        mChildPadding = res.getDimensionPixelSize(R.dimen.notification_children_padding);
+        mDividerHeight = res.getDimensionPixelSize(
+                R.dimen.notification_children_container_divider_height);
+        mDividerAlpha = res.getFloat(R.dimen.notification_divider_alpha);
+        mHeaderHeight = res.getDimensionPixelSize(
+                R.dimen.notification_children_container_header_height);
+        mNotificationHeaderMargin = res.getDimensionPixelSize(
+                R.dimen.notification_children_container_margin_top);
+        mNotificatonTopPadding = res.getDimensionPixelSize(
                 R.dimen.notification_children_container_top_padding);
-        mCollapsedBottompadding = getResources().getDimensionPixelSize(
+        mCollapsedBottompadding = res.getDimensionPixelSize(
                 com.android.internal.R.dimen.notification_content_margin_bottom);
+        mEnableShadowOnChildNotifications =
+                res.getBoolean(R.bool.config_enableShadowOnChildNotifications);
+        mShowDividersWhenExpanded =
+                res.getBoolean(R.bool.config_showDividersWhenGroupNotificationExpanded);
+        mHideDividersDuringExpand =
+                res.getBoolean(R.bool.config_hideDividersDuringExpand);
     }
 
     @Override
@@ -566,7 +582,8 @@
             childState.hidden = false;
             // When the group is expanded, the children cast the shadows rather than the parent
             // so use the parent's elevation here.
-            childState.zTranslation = childrenExpandedAndNotAnimating
+            childState.zTranslation =
+                    (childrenExpandedAndNotAnimating && mEnableShadowOnChildNotifications)
                     ? mContainingNotification.getTranslationZ()
                     : 0;
             childState.dimmed = parentState.dimmed;
@@ -677,7 +694,9 @@
             expandFraction = getGroupExpandFraction();
         }
         final boolean dividersVisible = mUserLocked && !showingAsLowPriority()
-                || mContainingNotification.isGroupExpansionChanging();
+                || (mChildrenExpanded && mShowDividersWhenExpanded)
+                || (mContainingNotification.isGroupExpansionChanging()
+                && !mHideDividersDuringExpand);
         for (int i = 0; i < childCount; i++) {
             ExpandableNotificationRow child = mChildren.get(i);
             ExpandableViewState viewState = state.getViewStateForView(child);
@@ -687,7 +706,7 @@
             View divider = mDividers.get(i);
             tmpState.initFrom(divider);
             tmpState.yTranslation = viewState.yTranslation - mDividerHeight;
-            float alpha = mChildrenExpanded && viewState.alpha != 0 ? 0.5f : 0;
+            float alpha = mChildrenExpanded && viewState.alpha != 0 ? mDividerAlpha : 0;
             if (mUserLocked && !showingAsLowPriority() && viewState.alpha != 0) {
                 alpha = NotificationUtils.interpolate(0, 0.5f,
                         Math.min(viewState.alpha, expandFraction));
@@ -751,7 +770,9 @@
         ViewState tmpState = new ViewState();
         float expandFraction = getGroupExpandFraction();
         final boolean dividersVisible = mUserLocked && !showingAsLowPriority()
-                || mContainingNotification.isGroupExpansionChanging();
+                || (mChildrenExpanded && mShowDividersWhenExpanded)
+                || (mContainingNotification.isGroupExpansionChanging()
+                && !mHideDividersDuringExpand);
         for (int i = childCount - 1; i >= 0; i--) {
             ExpandableNotificationRow child = mChildren.get(i);
             ExpandableViewState viewState = state.getViewStateForView(child);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 3cc3604..291ec1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -23,6 +23,7 @@
 import android.animation.TimeAnimator;
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.annotation.ColorInt;
 import android.annotation.FloatRange;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -38,11 +39,13 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.service.notification.StatusBarNotification;
+import android.support.annotation.NonNull;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Property;
+import android.view.ContextThemeWrapper;
 import android.view.InputDevice;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
@@ -57,8 +60,10 @@
 import android.view.animation.Interpolator;
 import android.widget.OverScroller;
 import android.widget.ScrollView;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settingslib.Utils;
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
@@ -87,6 +92,10 @@
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.ScrollAdapter;
 
+import android.support.v4.graphics.ColorUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -147,6 +156,7 @@
     private int mPaddingBetweenElements;
     private int mIncreasedPaddingBetweenElements;
     private int mTopPadding;
+    private int mBottomMargin;
     private int mBottomInset = 0;
 
     /**
@@ -205,6 +215,7 @@
     protected DismissView mDismissView;
     protected EmptyShadeView mEmptyShadeView;
     private boolean mDismissAllInProgress;
+    private boolean mFadeNotificationsOnDismiss;
 
     /**
      * Was the scroller scrolled to the top when the down motion was observed?
@@ -355,12 +366,14 @@
                     return object.getBackgroundFadeAmount();
                 }
             };
+    private boolean mUsingLightTheme;
     private boolean mQsExpanded;
     private boolean mForwardScrollable;
     private boolean mBackwardScrollable;
     private NotificationShelf mShelf;
     private int mMaxDisplayedNotifications = -1;
     private int mStatusBarHeight;
+    private int mMinInteractionHeight;
     private boolean mNoAmbient;
     private final Rect mClipRect = new Rect();
     private boolean mIsClipped;
@@ -369,6 +382,7 @@
     private boolean mHeadsUpAnimatingAway;
     private int mStatusBarState;
     private int mCachedBackgroundColor;
+    private boolean mHeadsUpGoingAwayAnimationsAllowed = true;
     private Runnable mAnimateScroll = this::animateScroll;
 
     public NotificationStackScrollLayout(Context context) {
@@ -403,6 +417,8 @@
         mFalsingManager = FalsingManager.getInstance(context);
         mShouldDrawNotificationBackground =
                 res.getBoolean(R.bool.config_drawNotificationBackground);
+        mFadeNotificationsOnDismiss =
+                res.getBoolean(R.bool.config_fadeNotificationsOnDismiss);
 
         updateWillNotDraw();
         if (DEBUG) {
@@ -475,16 +491,8 @@
         float alpha = BACKGROUND_ALPHA_DIMMED + (1 - BACKGROUND_ALPHA_DIMMED) * (1.0f - mDimAmount);
         alpha *= mBackgroundFadeAmount;
         // We need to manually blend in the background color
-        int scrimColor = mScrimController.getScrimBehindColor();
-        // SRC_OVER blending Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc
-        float alphaInv = 1 - alpha;
-        int color = Color.argb((int) (alpha * 255 + alphaInv * Color.alpha(scrimColor)),
-                (int) (mBackgroundFadeAmount * Color.red(mBgColor)
-                        + alphaInv * Color.red(scrimColor)),
-                (int) (mBackgroundFadeAmount * Color.green(mBgColor)
-                        + alphaInv * Color.green(scrimColor)),
-                (int) (mBackgroundFadeAmount * Color.blue(mBgColor)
-                        + alphaInv * Color.blue(scrimColor)));
+        int scrimColor = mScrimController.getBackgroundColor();
+        int color = ColorUtils.blendARGB(scrimColor, mBgColor, alpha);
         if (mCachedBackgroundColor != color) {
             mCachedBackgroundColor = color;
             mBackgroundPaint.setColor(color);
@@ -501,17 +509,21 @@
         mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
         mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
         mOverflingDistance = configuration.getScaledOverflingDistance();
-        mCollapsedSize = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_min_height);
+
+        Resources res = context.getResources();
+        mCollapsedSize = res.getDimensionPixelSize(R.dimen.notification_min_height);
         mStackScrollAlgorithm.initView(context);
         mAmbientState.reload(context);
-        mPaddingBetweenElements = Math.max(1, context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_divider_height));
-        mIncreasedPaddingBetweenElements = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_divider_height_increased);
-        mMinTopOverScrollToEscape = getResources().getDimensionPixelSize(
+        mPaddingBetweenElements = Math.max(1,
+                res.getDimensionPixelSize(R.dimen.notification_divider_height));
+        mIncreasedPaddingBetweenElements =
+                res.getDimensionPixelSize(R.dimen.notification_divider_height_increased);
+        mMinTopOverScrollToEscape = res.getDimensionPixelSize(
                 R.dimen.min_top_overscroll_to_qs);
-        mStatusBarHeight = getResources().getDimensionPixelOffset(R.dimen.status_bar_height);
+        mStatusBarHeight = res.getDimensionPixelOffset(R.dimen.status_bar_height);
+        mBottomMargin = res.getDimensionPixelSize(R.dimen.notification_panel_margin_bottom);
+        mMinInteractionHeight = res.getDimensionPixelSize(
+                R.dimen.notification_min_interaction_height);
     }
 
     public void setDrawBackgroundAsSrc(boolean asSrc) {
@@ -800,7 +812,7 @@
      */
     private float getAppearStartPosition() {
         if (mTrackingHeadsUp && mFirstVisibleBackgroundChild != null) {
-            if (mFirstVisibleBackgroundChild.isAboveShelf()) {
+            if (mAmbientState.isAboveShelf(mFirstVisibleBackgroundChild)) {
                 // If we ever expanded beyond the first notification, it's allowed to merge into
                 // the shelf
                 return mFirstVisibleBackgroundChild.getPinnedHeadsUpHeight();
@@ -818,13 +830,15 @@
         int notGoneChildCount = getNotGoneChildCount();
         if (mEmptyShadeView.getVisibility() == GONE && notGoneChildCount != 0) {
             int minNotificationsForShelf = 1;
-            if (mTrackingHeadsUp || mHeadsUpManager.hasPinnedHeadsUp()) {
+            if (mTrackingHeadsUp
+                    || (mHeadsUpManager.hasPinnedHeadsUp() && !mAmbientState.isDark())) {
                 appearPosition = mHeadsUpManager.getTopHeadsUpPinnedHeight();
                 minNotificationsForShelf = 2;
             } else {
                 appearPosition = 0;
             }
-            if (notGoneChildCount >= minNotificationsForShelf) {
+            if (notGoneChildCount >= minNotificationsForShelf
+                    && mShelf.getVisibility() != GONE) {
                 appearPosition += mShelf.getIntrinsicHeight();
             }
         } else {
@@ -966,7 +980,8 @@
             mScrimController.setTopHeadsUpDragAmount(animView,
                     Math.min(Math.abs(swipeProgress / 2f - 1.0f), 1.0f));
         }
-        return true; // Don't fade out the notification
+        // Returning true prevents alpha fading.
+        return !mFadeNotificationsOnDismiss;
     }
 
     @Override
@@ -1071,7 +1086,7 @@
         final int count = getChildCount();
         for (int childIdx = 0; childIdx < count; childIdx++) {
             ExpandableView slidingChild = (ExpandableView) getChildAt(childIdx);
-            if (slidingChild.getVisibility() == GONE
+            if (slidingChild.getVisibility() != VISIBLE
                     || slidingChild instanceof StackScrollerDecorView) {
                 continue;
             }
@@ -1085,7 +1100,8 @@
             int left = 0;
             int right = getWidth();
 
-            if (touchY >= top && touchY <= bottom && touchX >= left && touchX <= right) {
+            if (bottom - top >= mMinInteractionHeight
+                    && touchY >= top && touchY <= bottom && touchX >= left && touchX <= right) {
                 if (slidingChild instanceof ExpandableNotificationRow) {
                     ExpandableNotificationRow row = (ExpandableNotificationRow) slidingChild;
                     if (!mIsExpanded && row.isHeadsUp() && row.isPinned()
@@ -1995,18 +2011,14 @@
                 }
             }
         }
-        mContentHeight = height + mTopPadding;
+        mContentHeight = height + mTopPadding + mBottomMargin;
         updateScrollability();
+        clampScrollPosition();
         mAmbientState.setLayoutMaxHeight(mContentHeight);
     }
 
     private boolean isPulsing(NotificationData.Entry entry) {
-        for (HeadsUpManager.HeadsUpEntry e : mPulsing) {
-            if (e.entry == entry) {
-                return true;
-            }
-        }
-        return false;
+        return mAmbientState.isPulsing(entry);
     }
 
     public boolean hasPulsingNotifications() {
@@ -2232,10 +2244,11 @@
                 top = (int) Math.ceil(firstView.getTranslationY());
             }
         }
-        ActivatableNotificationView lastView = mShelf.hasItemsInStableShelf()
-                ? mShelf
-                : mLastVisibleBackgroundChild;
-        int bottom = 0;
+        ActivatableNotificationView lastView =
+                mShelf.hasItemsInStableShelf() && mShelf.getVisibility() != GONE
+                        ? mShelf
+                        : mLastVisibleBackgroundChild;
+        int bottom;
         if (lastView != null) {
             int finalTranslationY;
             if (lastView == mShelf) {
@@ -2385,7 +2398,7 @@
     }
 
     public int getLayoutMinHeight() {
-        return mShelf.getIntrinsicHeight();
+        return mShelf.getVisibility() == GONE ? 0 : mShelf.getIntrinsicHeight();
     }
 
     public int getFirstChildIntrinsicHeight() {
@@ -2410,7 +2423,7 @@
         final int firstChildMinHeight = firstChild != null ? firstChild.getCollapsedHeight()
                 : mCollapsedSize;
         int shelfHeight = 0;
-        if (mLastVisibleBackgroundChild != null) {
+        if (mLastVisibleBackgroundChild != null && mShelf.getVisibility() != GONE) {
             shelfHeight = mShelf.getIntrinsicHeight();
         }
         return mIntrinsicPadding + firstChildMinHeight + shelfHeight;
@@ -2581,9 +2594,6 @@
         }
         updateAnimationState(false, child);
 
-        // Make sure the clipRect we might have set is removed
-        expandableView.setClipTopAmount(0);
-
         focusNextViewIfFocused(child);
     }
 
@@ -2729,7 +2739,7 @@
         return view.getHeight();
     }
 
-    private int getPositionInLinearLayout(View requestedView) {
+    public int getPositionInLinearLayout(View requestedView) {
         ExpandableNotificationRow childInGroup = null;
         ExpandableNotificationRow requestedRow = null;
         if (isChildInGroup(requestedView)) {
@@ -3030,10 +3040,6 @@
     private void generateChildRemovalEvents() {
         for (View child : mChildrenToRemoveAnimated) {
             boolean childWasSwipedOut = mSwipedOutViews.contains(child);
-            int animationType = childWasSwipedOut
-                    ? AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT
-                    : AnimationEvent.ANIMATION_TYPE_REMOVE;
-            AnimationEvent event = new AnimationEvent(child, animationType);
 
             // we need to know the view after this one
             float removedTranslation = child.getTranslationY();
@@ -3044,7 +3050,16 @@
                     removedTranslation = row.getTranslationWhenRemoved();
                     ignoreChildren = false;
                 }
+                childWasSwipedOut |= Math.abs(row.getTranslation()) == row.getWidth();
             }
+            if (!childWasSwipedOut) {
+                Rect clipBounds = child.getClipBounds();
+                childWasSwipedOut = clipBounds.height() == 0;
+            }
+            int animationType = childWasSwipedOut
+                    ? AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT
+                    : AnimationEvent.ANIMATION_TYPE_REMOVE;
+            AnimationEvent event = new AnimationEvent(child, animationType);
             event.viewAfterChangingView = getFirstChildBelowTranlsationY(removedTranslation,
                     ignoreChildren);
             mAnimationEvents.add(event);
@@ -3352,15 +3367,29 @@
         if (!mIsExpanded) {
             setOwnScrollY(0);
             mStatusBar.resetUserExpandedStates();
+            clearTemporaryViews();
+            clearUserLockedViews();
+        }
+    }
 
-            // lets make sure nothing is in the overlay / transient anymore
-            clearTemporaryViews(this);
-            for (int i = 0; i < getChildCount(); i++) {
-                ExpandableView child = (ExpandableView) getChildAt(i);
-                if (child instanceof ExpandableNotificationRow) {
-                    ExpandableNotificationRow row = (ExpandableNotificationRow) child;
-                    clearTemporaryViews(row.getChildrenContainer());
-                }
+    private void clearUserLockedViews() {
+        for (int i = 0; i < getChildCount(); i++) {
+            ExpandableView child = (ExpandableView) getChildAt(i);
+            if (child instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+                row.setUserLocked(false);
+            }
+        }
+    }
+
+    private void clearTemporaryViews() {
+        // lets make sure nothing is in the overlay / transient anymore
+        clearTemporaryViews(this);
+        for (int i = 0; i < getChildCount(); i++) {
+            ExpandableView child = (ExpandableView) getChildAt(i);
+            if (child instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+                clearTemporaryViews(row.getChildrenContainer());
             }
         }
     }
@@ -3395,6 +3424,7 @@
         if (changed) {
             if (!mIsExpanded) {
                 mGroupManager.collapseAllGroups();
+                mExpandHelper.cancelImmediately();
             }
             updateNotificationAnimationStates();
             updateChronometers();
@@ -3442,7 +3472,7 @@
     }
 
     private void updateScrollPositionOnExpandInBottom(ExpandableView view) {
-        if (view instanceof ExpandableNotificationRow) {
+        if (view instanceof ExpandableNotificationRow && !onKeyguard()) {
             ExpandableNotificationRow row = (ExpandableNotificationRow) view;
             if (row.isUserLocked() && row != getFirstChildNotGone()) {
                 if (row.isSummaryWithChildren()) {
@@ -3454,7 +3484,7 @@
                     endPosition += row.getNotificationParent().getTranslationY();
                 }
                 int layoutEnd = mMaxLayoutHeight + (int) mStackTranslation;
-                if (row != mLastVisibleBackgroundChild) {
+                if (row != mLastVisibleBackgroundChild && mShelf.getVisibility() != GONE) {
                     layoutEnd -= mShelf.getIntrinsicHeight() + mPaddingBetweenElements;
                 }
                 if (endPosition > layoutEnd) {
@@ -3627,8 +3657,27 @@
         mTmpSortedChildren.clear();
     }
 
+    /**
+     * Update colors of "dismiss" and "empty shade" views.
+     *
+     * @param lightTheme True if light theme should be used.
+     */
+    public void updateDecorViews(boolean lightTheme) {
+        if (lightTheme == mUsingLightTheme) {
+            return;
+        }
+        mUsingLightTheme = lightTheme;
+        Context context = new ContextThemeWrapper(mContext,
+                lightTheme ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI);
+        final int textColor = Utils.getColorAttr(context, R.attr.wallpaperTextColor);
+        mDismissView.setTextColor(textColor);
+        mEmptyShadeView.setTextColor(textColor);
+    }
+
     public void goToFullShade(long delay) {
-        mDismissView.setInvisible();
+        if (mDismissView != null) {
+            mDismissView.setInvisible();
+        }
         mEmptyShadeView.setInvisible();
         mGoToFullShadeNeedsAnimation = true;
         mGoToFullShadeDelay = delay;
@@ -3642,6 +3691,7 @@
 
     public void setIntrinsicPadding(int intrinsicPadding) {
         mIntrinsicPadding = intrinsicPadding;
+        mAmbientState.setIntrinsicPadding(intrinsicPadding);
     }
 
     public int getIntrinsicPadding() {
@@ -3664,6 +3714,9 @@
      * See {@link AmbientState#setDark}.
      */
     public void setDark(boolean dark, boolean animate, @Nullable PointF touchWakeUpScreenLocation) {
+        if (mAmbientState.isDark() == dark) {
+            return;
+        }
         mAmbientState.setDark(dark);
         if (animate && mAnimationsEnabled) {
             mDarkNeedsAnimation = true;
@@ -3741,7 +3794,7 @@
         return -1;
     }
 
-    public void setDismissView(DismissView dismissView) {
+    public void setDismissView(@NonNull DismissView dismissView) {
         int index = -1;
         if (mDismissView != null) {
             index = indexOfChild(mDismissView);
@@ -3797,6 +3850,10 @@
     }
 
     public void updateDismissView(boolean visible) {
+        if (mDismissView == null) {
+            return;
+        }
+
         int oldVisibility = mDismissView.willBeGone() ? GONE : mDismissView.getVisibility();
         int newVisibility = visible ? VISIBLE : GONE;
         if (oldVisibility != newVisibility) {
@@ -3854,15 +3911,17 @@
     }
 
     public boolean isDismissViewNotGone() {
-        return mDismissView.getVisibility() != View.GONE && !mDismissView.willBeGone();
+        return mDismissView != null
+                && mDismissView.getVisibility() != View.GONE
+                && !mDismissView.willBeGone();
     }
 
     public boolean isDismissViewVisible() {
-        return mDismissView.isVisible();
+        return mDismissView != null && mDismissView.isVisible();
     }
 
     public int getDismissViewHeight() {
-        return mDismissView.getHeight() + mPaddingBetweenElements;
+        return mDismissView == null ? 0 : mDismissView.getHeight() + mPaddingBetweenElements;
     }
 
     public int getEmptyShadeViewHeight() {
@@ -4047,7 +4106,7 @@
     }
 
     public void generateHeadsUpAnimation(ExpandableNotificationRow row, boolean isHeadsUp) {
-        if (mAnimationsEnabled) {
+        if (mAnimationsEnabled && (isHeadsUp || mHeadsUpGoingAwayAnimationsAllowed)) {
             mHeadsUpChangeAnimations.add(new Pair<>(row, isHeadsUp));
             mNeedsAnimation = true;
             if (!mIsExpanded && !isHeadsUp) {
@@ -4081,12 +4140,7 @@
 
     public void setScrimController(ScrimController scrimController) {
         mScrimController = scrimController;
-        mScrimController.setScrimBehindChangeRunnable(new Runnable() {
-            @Override
-            public void run() {
-                updateBackgroundDimming();
-            }
-        });
+        mScrimController.setScrimBehindChangeRunnable(this::updateBackgroundDimming);
     }
 
     public void forceNoOverlappingRendering(boolean force) {
@@ -4119,7 +4173,7 @@
             return;
         }
         mPulsing = pulsing;
-        mAmbientState.setHasPulsingNotifications(hasPulsingNotifications());
+        mAmbientState.setPulsing(pulsing);
         updateNotificationAnimationStates();
         updateContentHeight();
         notifyHeightChangeListener(mShelf);
@@ -4234,6 +4288,32 @@
         mAmbientState.setUnlockHintRunning(running);
     }
 
+    public void setQsCustomizerShowing(boolean isShowing) {
+        mAmbientState.setQsCustomizerShowing(isShowing);
+        requestChildrenUpdate();
+    }
+
+    public void setHeadsUpGoingAwayAnimationsAllowed(boolean headsUpGoingAwayAnimationsAllowed) {
+        mHeadsUpGoingAwayAnimationsAllowed = headsUpGoingAwayAnimationsAllowed;
+    }
+
+    public void setDarkShelfOffsetX(int shelfOffsetX) {
+        mShelf.setDarkOffsetX(shelfOffsetX);
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println(String.format("[%s: pulsing=%s qsCustomizerShowing=%s visibility=%s"
+                        + " alpha:%f scrollY:%d]",
+                this.getClass().getSimpleName(),
+                mPulsing != null ?"T":"f",
+                mAmbientState.isQsCustomizerShowing() ? "T":"f",
+                getVisibility() == View.VISIBLE ? "visible"
+                        : getVisibility() == View.GONE ? "gone"
+                                : "invisible",
+                getAlpha(),
+                mAmbientState.getScrollY()));
+    }
+
     /**
      * A listener that is notified when some child locations might have changed.
      */
@@ -4293,10 +4373,10 @@
         @Override
         public void onDownUpdate(View currView, MotionEvent ev) {
             mTranslatingParentView = currView;
-            mCurrMenuRow = null;
             if (mCurrMenuRow != null) {
                 mCurrMenuRow.onTouchEvent(currView, ev, 0 /* velocity */);
             }
+            mCurrMenuRow = null;
             mHandler.removeCallbacks(mFalsingCheck);
 
             // Slide back any notifications that might be showing a menu
@@ -4307,6 +4387,7 @@
                 mCurrMenuRow = row.createMenu();
                 mCurrMenuRow.setSwipeActionHelper(NotificationSwipeHelper.this);
                 mCurrMenuRow.setMenuClickListener(NotificationStackScrollLayout.this);
+                mCurrMenuRow.onTouchEvent(currView, ev, 0 /* velocity */);
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 5c10e7e..c060b08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -17,10 +17,10 @@
 package com.android.systemui.statusbar.stack;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
-
 import com.android.systemui.R;
 import com.android.systemui.statusbar.DismissView;
 import com.android.systemui.statusbar.EmptyShadeView;
@@ -48,6 +48,7 @@
 
     private StackScrollAlgorithmState mTempAlgorithmState = new StackScrollAlgorithmState();
     private boolean mIsExpanded;
+    private boolean mClipNotificationScrollToTop;
     private int mStatusBarHeight;
 
     public StackScrollAlgorithm(Context context) {
@@ -59,13 +60,14 @@
     }
 
     private void initConstants(Context context) {
-        mPaddingBetweenElements = context.getResources().getDimensionPixelSize(
+        Resources res = context.getResources();
+        mPaddingBetweenElements = res.getDimensionPixelSize(
                 R.dimen.notification_divider_height);
-        mIncreasedPaddingBetweenElements = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_divider_height_increased);
-        mCollapsedSize = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_min_height);
-        mStatusBarHeight = context.getResources().getDimensionPixelSize(R.dimen.status_bar_height);
+        mIncreasedPaddingBetweenElements =
+                res.getDimensionPixelSize(R.dimen.notification_divider_height_increased);
+        mCollapsedSize = res.getDimensionPixelSize(R.dimen.notification_min_height);
+        mStatusBarHeight = res.getDimensionPixelSize(R.dimen.status_bar_height);
+        mClipNotificationScrollToTop = res.getBoolean(R.bool.config_clipNotificationScrollToTop);
     }
 
     public void getStackScrollState(AmbientState ambientState, StackScrollState resultState) {
@@ -142,7 +144,8 @@
             float newNotificationEnd = newYTranslation + newHeight;
             boolean isHeadsUp = (child instanceof ExpandableNotificationRow)
                     && ((ExpandableNotificationRow) child).isPinned();
-            if (!state.inShelf && newYTranslation < previousNotificationEnd
+            if (mClipNotificationScrollToTop
+                    && !state.inShelf && newYTranslation < previousNotificationEnd
                     && (!isHeadsUp || ambientState.isShadeExpanded())) {
                 // The previous view is overlapping on top, clip!
                 float overlapAmount = previousNotificationEnd - newYTranslation;
@@ -246,14 +249,28 @@
         state.paddingMap.clear();
         int notGoneIndex = 0;
         ExpandableView lastView = null;
+        int firstHiddenIndex = ambientState.isDark()
+                ? (ambientState.hasPulsingNotifications() ? 1 : 0)
+                : childCount;
+
+        // The goal here is to fill the padding map, by iterating over how much padding each child
+        // needs. The map is thereby reused, by first filling it with the padding amount and when
+        // iterating over it again, it's filled with the actual resolved value.
+
         for (int i = 0; i < childCount; i++) {
             ExpandableView v = (ExpandableView) hostView.getChildAt(i);
             if (v.getVisibility() != View.GONE) {
                 if (v == ambientState.getShelf()) {
                     continue;
                 }
+                if (i >= firstHiddenIndex) {
+                    // we need normal padding now, to be in sync with what the stack calculates
+                    lastView = null;
+                    ExpandableViewState viewState = resultState.getViewStateForView(v);
+                    viewState.hidden = true;
+                }
                 notGoneIndex = updateNotGoneIndex(resultState, state, notGoneIndex, v);
-                float increasedPadding = v.getIncreasedPaddingAmount();;
+                float increasedPadding = v.getIncreasedPaddingAmount();
                 if (increasedPadding != 0.0f) {
                     state.paddingMap.put(v, increasedPadding);
                     if (lastView != null) {
@@ -276,6 +293,8 @@
                         state.paddingMap.put(lastView, newValue);
                     }
                 } else if (lastView != null) {
+
+                    // Let's now resolve the value to an actual padding
                     float newValue = getPaddingForValue(state.paddingMap.get(lastView));
                     state.paddingMap.put(lastView, newValue);
                 }
@@ -410,7 +429,7 @@
             if (mIsExpanded) {
                 // Ensure that the heads up is always visible even when scrolled off
                 clampHunToTop(ambientState, row, childState);
-                if (i == 0 && row.isAboveShelf()) {
+                if (i == 0 && ambientState.isAboveShelf(row)) {
                     // the first hun can't get off screen.
                     clampHunToMaxTranslation(ambientState, row, childState);
                     childState.hidden = false;
@@ -512,7 +531,7 @@
         ExpandableViewState childViewState = resultState.getViewStateForView(child);
         int zDistanceBetweenElements = ambientState.getZDistanceBetweenElements();
         float baseZ = ambientState.getBaseZHeight();
-        if (child.mustStayOnScreen()
+        if (child.mustStayOnScreen() && !ambientState.isDozingAndNotPulsing(child)
                 && childViewState.yTranslation < ambientState.getTopPadding()
                 + ambientState.getStackTranslation()) {
             if (childrenOnTop != 0.0f) {
@@ -524,7 +543,7 @@
             }
             childViewState.zTranslation = baseZ
                     + childrenOnTop * zDistanceBetweenElements;
-        } else if (i == 0 && child.isAboveShelf()) {
+        } else if (i == 0 && ambientState.isAboveShelf(child)) {
             // In case this is a new view that has never been measured before, we don't want to
             // elevate if we are currently expanded more then the notification
             int shelfHeight = ambientState.getShelf().getIntrinsicHeight();
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java b/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java
new file mode 100644
index 0000000..af99236
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java
@@ -0,0 +1,84 @@
+/*
+ * 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.tuner;
+
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+/**
+ * Version of Space that can be resized by a tunable setting.
+ */
+public class TunablePadding implements Tunable {
+
+    public static final int FLAG_START = 1;
+    public static final int FLAG_END = 2;
+    public static final int FLAG_TOP = 4;
+    public static final int FLAG_BOTTOM = 8;
+
+    private final int mFlags;
+    private final View mView;
+    private final int mDefaultSize;
+    private final float mDensity;
+
+    private TunablePadding(String key, int def, int flags, View view) {
+        mDefaultSize = def;
+        mFlags = flags;
+        mView = view;
+        DisplayMetrics metrics = new DisplayMetrics();
+        view.getContext().getSystemService(WindowManager.class)
+                .getDefaultDisplay().getMetrics(metrics);
+        mDensity = metrics.density;
+        Dependency.get(TunerService.class).addTunable(this, key);
+    }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        int dimen = mDefaultSize;
+        if (newValue != null) {
+            dimen = (int) (Integer.parseInt(newValue) * mDensity);
+        }
+        int left = mView.isLayoutRtl() ? FLAG_END : FLAG_START;
+        int right = mView.isLayoutRtl() ? FLAG_START : FLAG_END;
+        mView.setPadding(getPadding(dimen, left), getPadding(dimen, FLAG_TOP),
+                getPadding(dimen, right), getPadding(dimen, FLAG_BOTTOM));
+    }
+
+    private int getPadding(int dimen, int flag) {
+        return ((mFlags & flag) != 0) ? dimen : 0;
+    }
+
+    public void destroy() {
+        Dependency.get(TunerService.class).removeTunable(this);
+    }
+
+    // Exists for easy injecting in tests.
+    public static class TunablePaddingService {
+        public TunablePadding add(View view, String key, int defaultSize, int flags) {
+            if (view == null) {
+                throw new IllegalArgumentException();
+            }
+            return new TunablePadding(key, defaultSize, flags, view);
+        }
+    }
+
+    public static TunablePadding addTunablePadding(View view, String key, int defaultSize,
+            int flags) {
+        return Dependency.get(TunablePaddingService.class).add(view, key, defaultSize, flags);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java b/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java
new file mode 100644
index 0000000..f7f61af
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java
@@ -0,0 +1,93 @@
+/*
+ * 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.util;
+
+import android.app.AlarmManager;
+import android.os.Handler;
+import android.os.SystemClock;
+
+/**
+ * Schedules a timeout through AlarmManager. Ensures that the timeout is called even when
+ * the device is asleep.
+ */
+public class AlarmTimeout implements AlarmManager.OnAlarmListener {
+
+    public static final int MODE_CRASH_IF_SCHEDULED = 0;
+    public static final int MODE_IGNORE_IF_SCHEDULED = 1;
+    public static final int MODE_RESCHEDULE_IF_SCHEDULED = 2;
+
+    private final AlarmManager mAlarmManager;
+    private final AlarmManager.OnAlarmListener mListener;
+    private final String mTag;
+    private final Handler mHandler;
+    private boolean mScheduled;
+
+    public AlarmTimeout(AlarmManager alarmManager, AlarmManager.OnAlarmListener listener,
+            String tag, Handler handler) {
+        mAlarmManager = alarmManager;
+        mListener = listener;
+        mTag = tag;
+        mHandler = handler;
+    }
+
+    public void schedule(long timeout, int mode) {
+        switch (mode) {
+            case MODE_CRASH_IF_SCHEDULED:
+                if (mScheduled) {
+                    throw new IllegalStateException(mTag + " timeout is already scheduled");
+                }
+                break;
+            case MODE_IGNORE_IF_SCHEDULED:
+                if (mScheduled) {
+                    return;
+                }
+                break;
+            case MODE_RESCHEDULE_IF_SCHEDULED:
+                if (mScheduled) {
+                    cancel();
+                }
+                break;
+            default:
+                throw new IllegalArgumentException("Illegal mode: " + mode);
+        }
+
+        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                SystemClock.elapsedRealtime() + timeout, mTag, this, mHandler);
+        mScheduled = true;
+    }
+
+    public boolean isScheduled() {
+        return mScheduled;
+    }
+
+    public void cancel() {
+        if (mScheduled) {
+            mAlarmManager.cancel(this);
+            mScheduled = false;
+        }
+    }
+
+    @Override
+    public void onAlarm() {
+        if (!mScheduled) {
+            // We canceled the alarm, but it still fired. Ignore.
+            return;
+        }
+        mScheduled = false;
+        mListener.onAlarm();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
new file mode 100644
index 0000000..5790ba3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
@@ -0,0 +1,162 @@
+/*
+ * 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.util;
+
+import android.hardware.HardwareBuffer;
+import android.hardware.Sensor;
+import android.hardware.SensorAdditionalInfo;
+import android.hardware.SensorDirectChannel;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.hardware.TriggerEventListener;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.MemoryFile;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
+
+import java.util.List;
+
+/**
+ * Wrapper around sensor manager that hides potential sources of latency.
+ *
+ * Offloads fetching (non-dynamic) sensors and (un)registering listeners onto a background thread
+ * without blocking. Note that this means registering listeners now always appears successful even
+ * if it is not.
+ */
+public class AsyncSensorManager extends SensorManager {
+
+    private static final String TAG = "AsyncSensorManager";
+
+    private final SensorManager mInner;
+    private final List<Sensor> mSensorCache;
+    private final HandlerThread mHandlerThread = new HandlerThread("async_sensor");
+    @VisibleForTesting final Handler mHandler;
+
+    public AsyncSensorManager(SensorManager inner) {
+        mInner = inner;
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+        mSensorCache = mInner.getSensorList(Sensor.TYPE_ALL);
+    }
+
+    @Override
+    protected List<Sensor> getFullSensorList() {
+        return mSensorCache;
+    }
+
+    @Override
+    protected List<Sensor> getFullDynamicSensorList() {
+        return mInner.getDynamicSensorList(Sensor.TYPE_ALL);
+    }
+
+    @Override
+    protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, int delayUs,
+            Handler handler, int maxReportLatencyUs, int reservedFlags) {
+        mHandler.post(() -> {
+            if (!mInner.registerListener(listener, sensor, delayUs, maxReportLatencyUs, handler)) {
+                Log.e(TAG, "Registering " + listener + " for " + sensor + " failed.");
+            }
+        });
+        return true;
+    }
+
+    @Override
+    protected boolean flushImpl(SensorEventListener listener) {
+        return mInner.flush(listener);
+    }
+
+    @Override
+    protected SensorDirectChannel createDirectChannelImpl(MemoryFile memoryFile,
+            HardwareBuffer hardwareBuffer) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected void destroyDirectChannelImpl(SensorDirectChannel channel) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected int configureDirectChannelImpl(SensorDirectChannel channel, Sensor s, int rate) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected void registerDynamicSensorCallbackImpl(DynamicSensorCallback callback,
+            Handler handler) {
+        mHandler.post(() -> mInner.registerDynamicSensorCallback(callback, handler));
+    }
+
+    @Override
+    protected void unregisterDynamicSensorCallbackImpl(DynamicSensorCallback callback) {
+        mHandler.post(() -> mInner.unregisterDynamicSensorCallback(callback));
+    }
+
+    @Override
+    protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
+        mHandler.post(() -> {
+            if (!mInner.requestTriggerSensor(listener, sensor)) {
+                Log.e(TAG, "Requesting " + listener + " for " + sensor + " failed.");
+            }
+        });
+        return true;
+    }
+
+    @Override
+    protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor,
+            boolean disable) {
+        Preconditions.checkArgument(disable);
+
+        mHandler.post(() -> {
+            if (!mInner.cancelTriggerSensor(listener, sensor)) {
+                Log.e(TAG, "Canceling " + listener + " for " + sensor + " failed.");
+            }
+        });
+        return true;
+    }
+
+    @Override
+    protected boolean initDataInjectionImpl(boolean enable) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected boolean injectSensorDataImpl(Sensor sensor, float[] values, int accuracy,
+            long timestamp) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected boolean setOperationParameterImpl(SensorAdditionalInfo parameter) {
+        mHandler.post(() -> mInner.setOperationParameter(parameter));
+        return true;
+    }
+
+    @Override
+    protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
+        mHandler.post(() -> {
+            if (sensor == null) {
+                mInner.unregisterListener(listener);
+            } else {
+                mInner.unregisterListener(listener, sensor);
+            }
+        });
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index ba9e60a..021f9c4 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -21,6 +21,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.SystemProperties;
+import android.provider.Settings;
 import android.support.annotation.VisibleForTesting;
 
 import com.android.systemui.Dependency;
@@ -84,12 +85,15 @@
         // TODO(b/35345376): Turn this back on for debuggable builds after known leak fixed.
         private static final boolean ENABLED = Build.IS_DEBUGGABLE
                 && SystemProperties.getBoolean("debug.enable_leak_reporting", false);
+        private static final String FORCE_ENABLE = "sysui_force_garbage_monitor";
 
         private GarbageMonitor mGarbageMonitor;
 
         @Override
         public void start() {
-            if (!ENABLED) {
+            boolean forceEnable = Settings.Secure.getInt(mContext.getContentResolver(),
+                    FORCE_ENABLE, 0) != 0;
+            if (!ENABLED && !forceEnable) {
                 return;
             }
             mGarbageMonitor = Dependency.get(GarbageMonitor.class);
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java b/packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java
new file mode 100644
index 0000000..ad20900
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java
@@ -0,0 +1,39 @@
+/*
+ * 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.util.leak;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.view.Surface;
+
+public class RotationUtils {
+
+    public static final int ROTATION_NONE = 0;
+    public static final int ROTATION_LANDSCAPE = 1;
+    public static final int ROTATION_SEASCAPE = 2;
+
+    public static int getRotation(Context context) {
+        Configuration config = context.getResources().getConfiguration();
+        int rot = context.getDisplay().getRotation();
+        if (config.smallestScreenWidthDp < 600) {
+            if (rot == Surface.ROTATION_90) {
+                return ROTATION_LANDSCAPE;
+            } else if (rot == Surface.ROTATION_270) {
+                return ROTATION_SEASCAPE;
+            }
+        }
+        return ROTATION_NONE;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java
new file mode 100644
index 0000000..b8359097
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.wakelock;
+
+import android.os.Handler;
+
+/**
+ * A wake lock that has a built in delay when releasing to give the framebuffer time to update.
+ */
+public class DelayedWakeLock implements WakeLock {
+
+    private static final long RELEASE_DELAY_MS = 100;
+
+    private final Handler mHandler;
+    private final WakeLock mInner;
+    private final Runnable mRelease;
+
+    public DelayedWakeLock(Handler h, WakeLock inner) {
+        mHandler = h;
+        mInner = inner;
+        mRelease = mInner::release;
+    }
+
+    @Override
+    public void acquire() {
+        mInner.acquire();
+    }
+
+    @Override
+    public void release() {
+        mHandler.postDelayed(mRelease, RELEASE_DELAY_MS);
+    }
+
+    @Override
+    public Runnable wrap(Runnable r) {
+        return WakeLock.wrapImpl(this, r);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
index 215604b..edf294e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
@@ -42,6 +42,17 @@
                     .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, tag);
     }
 
+    static Runnable wrapImpl(WakeLock w, Runnable r) {
+        w.acquire();
+        return () -> {
+            try {
+                r.run();
+            } finally {
+                w.release();
+            }
+        };
+    }
+
     static WakeLock wrap(final PowerManager.WakeLock inner) {
         return new WakeLock() {
             /** @see PowerManager.WakeLock#acquire() */
@@ -56,7 +67,7 @@
 
             /** @see PowerManager.WakeLock#wrap(Runnable) */
             public Runnable wrap(Runnable runnable) {
-                return inner.wrap(runnable);
+                return wrapImpl(this, runnable);
             }
         };
     }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 5d51a33..b08b26d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -43,12 +43,17 @@
 import android.service.notification.Condition;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.view.accessibility.AccessibilityManager;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
+import com.android.systemui.SysUiServiceProvider;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.VolumeDialogController;
 import com.android.systemui.qs.tiles.DndTile;
+import com.android.systemui.statusbar.phone.StatusBar;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -88,13 +93,14 @@
     private final W mWorker;
     private final Context mContext;
     private AudioManager mAudio;
+    protected StatusBar mStatusBar;
     private final NotificationManager mNoMan;
     private final SettingObserver mObserver;
     private final Receiver mReceiver = new Receiver();
     private final MediaSessions mMediaSessions;
-    private final C mCallbacks = new C();
+    protected C mCallbacks = new C();
     private final State mState = new State();
-    private final MediaSessionsCallbacks mMediaSessionsCallbacksW = new MediaSessionsCallbacks();
+    protected final MediaSessionsCallbacks mMediaSessionsCallbacksW = new MediaSessionsCallbacks();
     private final Vibrator mVibrator;
     private final boolean mHasVibrator;
     private boolean mShowA11yStream;
@@ -122,6 +128,13 @@
         mReceiver.init();
         mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
         mHasVibrator = mVibrator != null && mVibrator.hasVibrator();
+        updateStatusBar();
+
+        boolean accessibilityVolumeStreamActive = context.getSystemService(
+                AccessibilityManager.class).isAccessibilityVolumeStreamActive();
+        mVolumeController.setA11yMode(accessibilityVolumeStreamActive ?
+                    VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME :
+                        VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME);
     }
 
     public AudioManager getAudioManager() {
@@ -210,6 +223,7 @@
 
     public void addCallback(Callbacks callback, Handler handler) {
         mCallbacks.add(callback, handler);
+        callback.onAccessibilityModeChanged(mShowA11yStream);
     }
 
     public void setUserActivityListener(UserActivityListener listener) {
@@ -318,8 +332,23 @@
         return changed;
     }
 
-    private boolean onVolumeChangedW(int stream, int flags) {
-        final boolean showUI = (flags & AudioManager.FLAG_SHOW_UI) != 0;
+    private void updateStatusBar() {
+        if (mStatusBar == null) {
+            mStatusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
+        }
+    }
+
+    private boolean shouldShowUI(int flags) {
+        updateStatusBar();
+        return mStatusBar != null
+                && mStatusBar.getWakefulnessState() != WakefulnessLifecycle.WAKEFULNESS_ASLEEP
+                && mStatusBar.getWakefulnessState() != WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP
+                && mStatusBar.isDeviceInteractive()
+                && (flags & AudioManager.FLAG_SHOW_UI) != 0;
+    }
+
+    boolean onVolumeChangedW(int stream, int flags) {
+        final boolean showUI = shouldShowUI(flags);
         final boolean fromKey = (flags & AudioManager.FLAG_FROM_KEY) != 0;
         final boolean showVibrateHint = (flags & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0;
         final boolean showSilentHint = (flags & AudioManager.FLAG_SHOW_SILENT_HINT) != 0;
@@ -630,7 +659,7 @@
         }
     }
 
-    private final class C implements Callbacks {
+    class C implements Callbacks {
         private final HashMap<Callbacks, Handler> mCallbackMap = new HashMap<>();
 
         public void add(Callbacks callback, Handler handler) {
@@ -877,18 +906,14 @@
         }
     }
 
-    private final class MediaSessionsCallbacks implements MediaSessions.Callbacks {
+    protected final class MediaSessionsCallbacks implements MediaSessions.Callbacks {
         private final HashMap<Token, Integer> mRemoteStreams = new HashMap<>();
 
         private int mNextStream = DYNAMIC_STREAM_START_INDEX;
 
         @Override
         public void onRemoteUpdate(Token token, String name, PlaybackInfo pi) {
-            if (!mRemoteStreams.containsKey(token)) {
-                mRemoteStreams.put(token, mNextStream);
-                if (D.BUG) Log.d(TAG, "onRemoteUpdate: " + name + " is stream " + mNextStream);
-                mNextStream++;
-            }
+            addStream(token, "onRemoteUpdate");
             final int stream = mRemoteStreams.get(token);
             boolean changed = mState.states.indexOfKey(stream) < 0;
             final StreamState ss = streamStateW(stream);
@@ -913,8 +938,9 @@
 
         @Override
         public void onRemoteVolumeChanged(Token token, int flags) {
+            addStream(token, "onRemoteVolumeChanged");
             final int stream = mRemoteStreams.get(token);
-            final boolean showUI = (flags & AudioManager.FLAG_SHOW_UI) != 0;
+            final boolean showUI = shouldShowUI(flags);
             boolean changed = updateActiveStreamW(stream);
             if (showUI) {
                 changed |= checkRoutedToBluetoothW(AudioManager.STREAM_MUSIC);
@@ -929,6 +955,11 @@
 
         @Override
         public void onRemoteRemoved(Token token) {
+            if (!mRemoteStreams.containsKey(token)) {
+                if (D.BUG) Log.d(TAG, "onRemoteRemoved: stream doesn't exist, "
+                        + "aborting remote removed for token:" +  token.toString());
+                return;
+            }
             final int stream = mRemoteStreams.get(token);
             mState.states.remove(stream);
             if (mState.activeStream == stream) {
@@ -954,6 +985,15 @@
             }
             return null;
         }
+
+        private void addStream(Token token, String triggeringMethod) {
+            if (!mRemoteStreams.containsKey(token)) {
+                mRemoteStreams.put(token, mNextStream);
+                if (D.BUG) Log.d(TAG, triggeringMethod + ": added stream " +  mNextStream
+                        + " from token + "+ token.toString());
+                mNextStream++;
+            }
+        }
     }
 
     public interface UserActivityListener {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 8d8931f..9e50e81 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -25,6 +25,7 @@
 import android.annotation.SuppressLint;
 import android.app.Dialog;
 import android.app.KeyguardManager;
+import android.app.WallpaperManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.ColorStateList;
@@ -32,6 +33,7 @@
 import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.PixelFormat;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.ColorDrawable;
@@ -51,6 +53,7 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
+import android.view.ContextThemeWrapper;
 import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.View;
@@ -149,7 +152,7 @@
     private TunerZenModePanel mZenPanel;
 
     public VolumeDialogImpl(Context context) {
-        mContext = context;
+        mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
         mZenModeController = Dependency.get(ZenModeController.class);
         mController = Dependency.get(VolumeDialogController.class);
         mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
@@ -178,7 +181,13 @@
 
     @Override
     public void destroy() {
+        mAccessibility.destroy();
         mController.removeCallback(mControllerCallbackH);
+        if (mZenFooter != null) {
+            mZenFooter.cleanup();
+        }
+        Dependency.get(TunerService.class).removeTunable(this);
+        mHandler.removeCallbacksAndMessages(null);
     }
 
     private void initDialog() {
@@ -694,11 +703,12 @@
         final boolean visible = mState.zenMode != Global.ZEN_MODE_OFF
                 && (mAudioManager.isStreamAffectedByRingerMode(mActiveStream) || mExpanded)
                 && !mZenPanel.isEditing();
-
-        if (wasVisible != visible) {
-            mZenFooter.update();
-            Util.setVisOrGone(mZenFooter, visible);
+        TransitionManager.beginDelayedTransition(mDialogView, getTransistion());
+        if (wasVisible != visible && !visible) {
+            prepareForCollapse();
         }
+        Util.setVisOrGone(mZenFooter, visible);
+        mZenFooter.update();
 
         final boolean fullWasVisible = mZenPanel.getVisibility() == View.VISIBLE;
         final boolean fullVisible = mShowFullZen && !visible;
@@ -1238,16 +1248,14 @@
                 }
             });
             mDialogView.setAccessibilityDelegate(this);
-            mAccessibilityMgr.addAccessibilityStateChangeListener(
-                    new AccessibilityStateChangeListener() {
-                        @Override
-                        public void onAccessibilityStateChanged(boolean enabled) {
-                            updateFeedbackEnabled();
-                        }
-                    });
+            mAccessibilityMgr.addAccessibilityStateChangeListener(mListener);
             updateFeedbackEnabled();
         }
 
+        public void destroy() {
+            mAccessibilityMgr.removeAccessibilityStateChangeListener(mListener);
+        }
+
         @Override
         public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child,
                 AccessibilityEvent event) {
@@ -1270,6 +1278,9 @@
             }
             return false;
         }
+
+        private final AccessibilityStateChangeListener mListener =
+                enabled -> updateFeedbackEnabled();
     }
 
     private static class VolumeRow {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
index d6d0f75..01d31e2 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
@@ -25,6 +25,7 @@
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnDismissListener;
 import android.content.DialogInterface.OnShowListener;
+import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.util.Log;
 import android.view.View;
@@ -132,12 +133,11 @@
                 .setDuration(scaledDuration(300))
                 .setInterpolator(new LogDecelerateInterpolator())
                 .setListener(null)
-                .setUpdateListener(new AnimatorUpdateListener() {
-                    @Override
-                    public void onAnimationUpdate(ValueAnimator animation) {
+                .setUpdateListener(animation -> {
+                    if (mChevronPositionAnimator != null) {
+                        final float v = (Float) mChevronPositionAnimator.getAnimatedValue();
                         if (mChevronPositionAnimator == null) return;
                         // reposition chevron
-                        final float v = (Float) mChevronPositionAnimator.getAnimatedValue();
                         final int posY = chevronPosY();
                         mChevron.setTranslationY(posY + v + -mDialogView.getTranslationY());
                     }
@@ -258,13 +258,13 @@
         return (int) (base * ANIMATION_SCALE);
     }
 
-    private static final class LogDecelerateInterpolator implements TimeInterpolator {
+    public static final class LogDecelerateInterpolator implements TimeInterpolator {
         private final float mBase;
         private final float mDrift;
         private final float mTimeScale;
         private final float mOutputScale;
 
-        private LogDecelerateInterpolator() {
+        public LogDecelerateInterpolator() {
             this(400f, 1.4f, 0);
         }
 
@@ -286,12 +286,12 @@
         }
     }
 
-    private static final class LogAccelerateInterpolator implements TimeInterpolator {
+    public static final class LogAccelerateInterpolator implements TimeInterpolator {
         private final int mBase;
         private final int mDrift;
         private final float mLogScale;
 
-        private LogAccelerateInterpolator() {
+        public LogAccelerateInterpolator() {
             this(100, 0);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
index 17d98b1..7464212 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
@@ -111,7 +111,9 @@
         if (mZen == zen) return;
         mZen = zen;
         update();
-        updateIntroduction();
+        post(() -> {
+            updateIntroduction();
+        });
     }
 
     private void setConfig(ZenModeConfig config) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index ecdea4f..4716552 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -144,7 +144,7 @@
         super(context, attrs);
         mContext = context;
         mPrefs = new ZenPrefs();
-        mInflater = LayoutInflater.from(mContext.getApplicationContext());
+        mInflater = LayoutInflater.from(mContext);
         mForeverId = Condition.newId(mContext).appendPath("forever").build();
         mConfigurableTexts = new ConfigurableTexts(mContext);
         mVoiceCapable = Util.isVoiceCapable(mContext);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenRadioLayout.java b/packages/SystemUI/src/com/android/systemui/volume/ZenRadioLayout.java
new file mode 100644
index 0000000..5dbcd8a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenRadioLayout.java
@@ -0,0 +1,62 @@
+/*
+ * 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.volume;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+/**
+ * Specialized layout for zen mode that allows the radio buttons to reside within
+ * a RadioGroup, but also makes sure that all the heights off the radio buttons align
+ * with the corresponding content in the second child of this view.
+ */
+public class ZenRadioLayout extends LinearLayout {
+
+    public ZenRadioLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    /**
+     * Run 2 measurement passes, 1 that figures out the size of the content, and another
+     * that sets the size of the radio buttons to the heights of the corresponding content.
+     */
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        ViewGroup radioGroup = (ViewGroup) getChildAt(0);
+        ViewGroup radioContent = (ViewGroup) getChildAt(1);
+        int size = radioGroup.getChildCount();
+        if (size != radioContent.getChildCount()) {
+            throw new IllegalStateException("Expected matching children");
+        }
+        boolean hasChanges = false;
+        for (int i = 0; i < size; i++) {
+            View radio = radioGroup.getChildAt(i);
+            View content = radioContent.getChildAt(i);
+            if (radio.getLayoutParams().height != content.getMeasuredHeight()) {
+                hasChanges = true;
+                radio.getLayoutParams().height = content.getMeasuredHeight();
+            }
+        }
+        // Measure again if any heights changed.
+        if (hasChanges) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index b12fd1c..adb3baf 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -38,6 +38,10 @@
     <uses-permission android:name="android.permission.CONTROL_VPN" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.TRUST_LISTENER" />
+    <uses-permission android:name="android.permission.USE_FINGERPRINT" />
+    <uses-permission android:name="android.permission.DEVICE_POWER" />
 
     <application>
         <uses-library android:name="android.test.runner" />
@@ -48,7 +52,7 @@
             android:process=":killable" />
     </application>
 
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+    <instrumentation android:name="android.testing.TestableInstrumentation"
         android:targetPackage="com.android.systemui.tests"
         android:label="Tests for SystemUI">
     </instrumentation>
diff --git a/packages/SystemUI/tests/AndroidTest.xml b/packages/SystemUI/tests/AndroidTest.xml
index ee78bcd..6ca42e8 100644
--- a/packages/SystemUI/tests/AndroidTest.xml
+++ b/packages/SystemUI/tests/AndroidTest.xml
@@ -19,8 +19,9 @@
     </target_preparer>
 
     <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="framework-base-presubmit" />
     <option name="test-tag" value="SystemUITests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.systemui.tests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
index 855adb4..e37ea95 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
@@ -16,6 +16,7 @@
 
 package com.android.keyguard;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -36,12 +37,17 @@
 public class KeyguardClockAccessibilityDelegateTest extends SysuiTestCase {
 
     private TextView mView;
+    private String m12HoursFormat;
+    private String m24HoursFormat;
 
     @Before
     public void setUp() throws Exception {
+        m12HoursFormat = mContext.getString(R.string.keyguard_widget_12_hours_format);
+        m24HoursFormat = mContext.getString(R.string.keyguard_widget_24_hours_format);
+
         mView = new TextView(mContext);
-        mView.setText(R.string.keyguard_widget_12_hours_format);
-        mView.setContentDescription(mContext.getString(R.string.keyguard_widget_12_hours_format));
+        mView.setText(m12HoursFormat);
+        mView.setContentDescription(m12HoursFormat);
         mView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
     }
 
@@ -77,6 +83,21 @@
         assertTrue(isAscii(info.getContentDescription()));
     }
 
+    @Test
+    public void isNeeded_returnsTrueIfDateFormatsContainNonAscii() {
+        if (!isAscii(m12HoursFormat) || !isAscii(m24HoursFormat)) {
+            assertTrue(KeyguardClockAccessibilityDelegate.isNeeded(mContext));
+        }
+    }
+
+    @Test
+    public void isNeeded_returnsWhetherFancyColonExists() {
+        boolean hasFancyColon = !TextUtils.isEmpty(mContext.getString(
+                R.string.keyguard_fancy_colon));
+
+        assertEquals(hasFancyColon, KeyguardClockAccessibilityDelegate.isNeeded(mContext));
+    }
+
     private boolean isAscii(CharSequence text) {
         return text.chars().allMatch((i) -> i < 128);
     }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
new file mode 100644
index 0000000..fcf327b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.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.keyguard;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.Context;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.UiThreadTest;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.systemui.SysuiTestCase;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class KeyguardSecurityContainerTest extends SysuiTestCase {
+
+    @UiThreadTest
+    @Test
+    public void showSecurityScreen_canInflateAllModes() {
+        KeyguardSecurityContainer keyguardSecurityContainer =
+                new KeyguardSecurityContainer(getContext());
+
+        Context context = getContext();
+
+        for (int theme : new int[] {R.style.Theme_SystemUI, R.style.Theme_SystemUI_Light}) {
+            context.setTheme(theme);
+            final LayoutInflater inflater = LayoutInflater.from(context);
+            KeyguardSecurityModel.SecurityMode[] modes =
+                    KeyguardSecurityModel.SecurityMode.values();
+            for (KeyguardSecurityModel.SecurityMode mode : modes) {
+                final int resId = keyguardSecurityContainer.getLayoutIdFor(mode);
+                if (resId == 0) {
+                    continue;
+                }
+                inflater.inflate(resId, null /* root */, false /* attach */);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java b/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java
new file mode 100644
index 0000000..2a44771
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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;
+
+import static com.android.systemui.tuner.TunablePadding.FLAG_END;
+import static com.android.systemui.tuner.TunablePadding.FLAG_START;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Fragment;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.view.Display;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.systemui.R.dimen;
+import com.android.systemui.RoundedCorners.TunablePaddingTagListener;
+import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarWindowView;
+import com.android.systemui.tuner.TunablePadding;
+import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
+import com.android.systemui.tuner.TunerService;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class RoundedCornersTest extends SysuiTestCase {
+
+    private RoundedCorners mRoundedCorners;
+    private StatusBar mStatusBar;
+    private WindowManager mWindowManager;
+    private FragmentService mFragmentService;
+    private FragmentHostManager mFragmentHostManager;
+    private TunerService mTunerService;
+    private StatusBarWindowView mView;
+    private TunablePaddingService mTunablePaddingService;
+
+    @Before
+    public void setup() {
+        mStatusBar = mock(StatusBar.class);
+        mWindowManager = mock(WindowManager.class);
+        mView = spy(new StatusBarWindowView(mContext, null));
+        when(mStatusBar.getStatusBarWindow()).thenReturn(mView);
+        when(mStatusBar.getNavigationBarWindow()).thenReturn(mView);
+        mContext.putComponent(StatusBar.class, mStatusBar);
+
+        Display display = mContext.getSystemService(WindowManager.class).getDefaultDisplay();
+        when(mWindowManager.getDefaultDisplay()).thenReturn(display);
+        mContext.addMockSystemService(WindowManager.class, mWindowManager);
+
+        mFragmentService = mDependency.injectMockDependency(FragmentService.class);
+        mFragmentHostManager = mock(FragmentHostManager.class);
+        when(mFragmentService.getFragmentHostManager(any())).thenReturn(mFragmentHostManager);
+
+        mTunerService = mDependency.injectMockDependency(TunerService.class);
+
+        mRoundedCorners = new RoundedCorners();
+        mRoundedCorners.mContext = mContext;
+        mRoundedCorners.mComponents = mContext.getComponents();
+
+        mTunablePaddingService = mDependency.injectMockDependency(TunablePaddingService.class);
+    }
+
+    @Test
+    public void testNoRounding() {
+        mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 0);
+        mContext.getOrCreateTestableResources()
+                .addOverride(dimen.rounded_corner_content_padding, 0);
+
+        mRoundedCorners.start();
+        // No views added.
+        verify(mWindowManager, never()).addView(any(), any());
+        // No Fragments watched.
+        verify(mFragmentHostManager, never()).addTagListener(any(), any());
+        // No Tuners tuned.
+        verify(mTunerService, never()).addTunable(any(), any());
+    }
+
+    @Test
+    public void testRounding() {
+        mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 20);
+        mContext.getOrCreateTestableResources()
+                .addOverride(dimen.rounded_corner_content_padding, 20);
+
+        mRoundedCorners.start();
+        // Add 2 windows for rounded corners (top and bottom).
+        verify(mWindowManager, times(2)).addView(any(), any());
+
+        // Add 2 tag listeners for each of the fragments that are needed.
+        verify(mFragmentHostManager, times(2)).addTagListener(any(), any());
+        // One tunable.
+        verify(mTunerService, times(1)).addTunable(any(), any());
+        // One TunablePadding.
+        verify(mTunablePaddingService, times(1)).add(any(), anyString(), anyInt(), anyInt());
+    }
+
+    @Test
+    public void testPaddingTagListener() {
+        TunablePaddingTagListener tagListener = new TunablePaddingTagListener(14, 5);
+        View v = mock(View.class);
+        View child = mock(View.class);
+        Fragment f = mock(Fragment.class);
+        TunablePadding padding = mock(TunablePadding.class);
+
+        when(mTunablePaddingService.add(any(), anyString(), anyInt(), anyInt()))
+                .thenReturn(padding);
+        when(f.getView()).thenReturn(v);
+        when(v.findViewById(5)).thenReturn(child);
+
+        // Trigger callback and verify we get a TunablePadding created.
+        tagListener.onFragmentViewCreated(null, f);
+        verify(mTunablePaddingService).add(eq(child), eq(RoundedCorners.PADDING), eq(14),
+                eq(FLAG_START | FLAG_END));
+
+        // Call again and verify destroy is called.
+        tagListener.onFragmentViewCreated(null, f);
+        verify(padding).destroy();
+    }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index 361a20f..66d00dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -31,6 +31,8 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -56,10 +58,14 @@
 
         mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
         Instrumentation inst = spy(mRealInstrumentation);
-        when(inst.getContext()).thenThrow(new RuntimeException(
-                "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"));
-        when(inst.getTargetContext()).thenThrow(new RuntimeException(
-                "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"));
+        when(inst.getContext()).thenAnswer(invocation -> {
+            throw new RuntimeException(
+                    "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext");
+        });
+        when(inst.getTargetContext()).thenAnswer(invocation -> {
+            throw new RuntimeException(
+                    "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext");
+        });
         InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments());
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
index b94a2fb..9d3124e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
@@ -31,6 +31,11 @@
         super(base, check);
     }
 
+    public ArrayMap<Class<?>, Object> getComponents() {
+        if (mComponents == null) mComponents = new ArrayMap<>();
+        return mComponents;
+    }
+
     @SuppressWarnings("unchecked")
     public <T> T getComponent(Class<T> interfaceType) {
         return (T) (mComponents != null ? mComponents.get(interfaceType) : null);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
new file mode 100644
index 0000000..d0f0bfd
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
@@ -0,0 +1,95 @@
+/*
+ * 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.colorextraction;
+
+import static org.junit.Assert.assertEquals;
+
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.graphics.Color;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.types.Tonal;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests color extraction generation.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SysuiColorExtractorTests extends SysuiTestCase {
+
+    private static int[] sWhich = new int[]{
+            WallpaperManager.FLAG_SYSTEM,
+            WallpaperManager.FLAG_LOCK};
+    private static int[] sTypes = new int[]{
+            ColorExtractor.TYPE_NORMAL,
+            ColorExtractor.TYPE_DARK,
+            ColorExtractor.TYPE_EXTRA_DARK};
+
+    @Test
+    public void getColors_usesGreyIfWallpaperNotVisible() {
+        SysuiColorExtractor extractor = new SysuiColorExtractor(getContext(),
+                new Tonal(getContext()), false);
+        simulateEvent(extractor);
+        extractor.setWallpaperVisible(false);
+
+        ColorExtractor.GradientColors fallbackColors = extractor.getFallbackColors();
+
+        for (int which : sWhich) {
+            for (int type : sTypes) {
+                assertEquals("Not using fallback!", extractor.getColors(which, type),
+                        fallbackColors);
+            }
+        }
+    }
+
+    @Test
+    public void getColors_doesntUseFallbackIfVisible() {
+        ColorExtractor.GradientColors colors = new ColorExtractor.GradientColors();
+        colors.setMainColor(Color.RED);
+        colors.setSecondaryColor(Color.RED);
+
+        SysuiColorExtractor extractor = new SysuiColorExtractor(getContext(),
+                (inWallpaperColors, outGradientColorsNormal, outGradientColorsDark,
+                        outGradientColorsExtraDark) -> {
+                    outGradientColorsNormal.set(colors);
+                    outGradientColorsDark.set(colors);
+                    outGradientColorsExtraDark.set(colors);
+                }, false);
+        simulateEvent(extractor);
+        extractor.setWallpaperVisible(true);
+
+        for (int which : sWhich) {
+            for (int type : sTypes) {
+                assertEquals("Not using extracted colors!",
+                        extractor.getColors(which, type), colors);
+            }
+        }
+    }
+
+    private void simulateEvent(SysuiColorExtractor extractor) {
+        // Let's fake a color event
+        extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.GREEN), null, null, 0),
+                WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK);
+    }
+}
\ No newline at end of file
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 bbe324d..64507be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.doze;
 
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -42,7 +42,7 @@
     }
 
     @Test
-    public void alwaysOn_offByDefault() throws Exception {
+    public void alwaysOn_onByDefault() throws Exception {
         if (!mDozeConfig.alwaysOnAvailable()) {
             return;
         }
@@ -50,6 +50,6 @@
         Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.DOZE_ALWAYS_ON,
                 null);
 
-        assertFalse(mDozeConfig.alwaysOnEnabled(UserHandle.USER_CURRENT));
+        assertTrue(mDozeConfig.alwaysOnEnabled(UserHandle.USER_CURRENT));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
index ee0fe7b..333e73d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
@@ -27,6 +27,9 @@
     boolean pulseAborted;
     boolean pulseExtended;
     boolean animateWakeup;
+    boolean dozing;
+    float doubleTapX;
+    float doubleTapY;
 
     @Override
     public void addCallback(@NonNull Callback callback) {
@@ -40,7 +43,7 @@
 
     @Override
     public void startDozing() {
-        throw new RuntimeException("not implemented");
+        dozing = true;
     }
 
     @Override
@@ -50,7 +53,7 @@
 
     @Override
     public void stopDozing() {
-        throw new RuntimeException("not implemented");
+        dozing = false;
     }
 
     @Override
@@ -69,11 +72,25 @@
     }
 
     @Override
+    public boolean isProvisioned() {
+        return false;
+    }
+
+    @Override
+    public boolean isBlockingDoze() {
+        return false;
+    }
+
+    @Override
     public void startPendingIntentDismissingKeyguard(PendingIntent intent) {
         throw new RuntimeException("not implemented");
     }
 
     @Override
+    public void onIgnoreTouchWhilePulsing(boolean ignore) {
+    }
+
+    @Override
     public void abortPulsing() {
         pulseAborted = true;
     }
@@ -87,4 +104,14 @@
     public void setAnimateWakeup(boolean animateWakeup) {
         this.animateWakeup = animateWakeup;
     }
+
+    @Override
+    public void onDoubleTap(float x, float y) {
+        doubleTapX = y;
+        doubleTapY = y;
+    }
+
+    @Override
+    public void setDozeScreenBrightness(int value) {
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index 7519b2d..368c814f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -215,54 +215,6 @@
     }
 
     @Test
-    public void testScreen_offInDoze() {
-        mMachine.requestState(INITIALIZED);
-
-        mMachine.requestState(DOZE);
-
-        assertEquals(Display.STATE_OFF, mServiceFake.screenState);
-    }
-
-    @Test
-    public void testScreen_onInAod() {
-        mMachine.requestState(INITIALIZED);
-
-        mMachine.requestState(DOZE_AOD);
-
-        assertEquals(Display.STATE_DOZE, mServiceFake.screenState);
-    }
-
-    @Test
-    public void testScreen_onInPulse() {
-        mMachine.requestState(INITIALIZED);
-
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
-        mMachine.requestState(DOZE_PULSING);
-
-        assertEquals(Display.STATE_DOZE, mServiceFake.screenState);
-    }
-
-    @Test
-    public void testScreen_offInRequestPulseWithoutAoD() {
-        mMachine.requestState(INITIALIZED);
-
-        mMachine.requestState(DOZE);
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
-
-        assertEquals(Display.STATE_OFF, mServiceFake.screenState);
-    }
-
-    @Test
-    public void testScreen_onInRequestPulseWithoutAoD() {
-        mMachine.requestState(INITIALIZED);
-
-        mMachine.requestState(DOZE_AOD);
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
-
-        assertEquals(Display.STATE_DOZE, mServiceFake.screenState);
-    }
-
-    @Test
     public void testTransitions_canRequestTransitions() {
         mMachine.requestState(INITIALIZED);
         mMachine.requestState(DOZE);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
new file mode 100644
index 0000000..c275806
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
@@ -0,0 +1,166 @@
+/*
+ * 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.doze;
+
+import static com.android.systemui.doze.DozeMachine.State.DOZE;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSED;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSE_DONE;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE;
+import static com.android.systemui.doze.DozeMachine.State.FINISH;
+import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
+import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.os.PowerManager;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.utils.hardware.FakeSensorManager;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Ignore
+public class DozeScreenBrightnessTest extends SysuiTestCase {
+
+    DozeServiceFake mServiceFake;
+    DozeScreenBrightness mScreen;
+    FakeSensorManager.FakeGenericSensor mSensor;
+    FakeSensorManager mSensorManager;
+    DozeHostFake mHostFake;
+
+    @Before
+    public void setUp() throws Exception {
+        mServiceFake = new DozeServiceFake();
+        mHostFake = new DozeHostFake();
+        mSensorManager = new FakeSensorManager(mContext);
+        mSensor = mSensorManager.getFakeLightSensor();
+        mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager,
+                mSensor.getSensor(), mHostFake, null /* handler */);
+    }
+
+    @Test
+    public void testInitialize_setsScreenBrightnessToValidValue() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+
+        assertNotEquals(PowerManager.BRIGHTNESS_DEFAULT, mServiceFake.screenBrightness);
+        assertTrue(mServiceFake.screenBrightness <= PowerManager.BRIGHTNESS_ON);
+    }
+
+    @Test
+    public void testAod_usesLightSensor() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        mSensor.sendSensorEvent(1000);
+
+        assertEquals(1000, mServiceFake.screenBrightness);
+    }
+
+    @Test
+    public void testPausingAod_pausesLightSensor() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        mSensor.sendSensorEvent(1000);
+
+        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSED);
+
+        mSensor.sendSensorEvent(1001);
+
+        assertNotEquals(1001, mServiceFake.screenBrightness);
+    }
+
+    @Test
+    public void testPausingAod_resetsBrightness() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        mSensor.sendSensorEvent(1000);
+
+        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSED);
+
+        assertNotEquals(1000, mServiceFake.screenBrightness);
+    }
+
+    @Test
+    public void testPulsing_usesLightSensor() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE);
+        mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE);
+
+        mSensor.sendSensorEvent(1000);
+
+        assertEquals(1000, mServiceFake.screenBrightness);
+    }
+
+    @Test
+    public void testDozingAfterPulsing_pausesLightSensor() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE);
+        mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE);
+        mScreen.transitionTo(DOZE_REQUEST_PULSE, DOZE_PULSING);
+        mScreen.transitionTo(DOZE_PULSING, DOZE_PULSE_DONE);
+        mScreen.transitionTo(DOZE_PULSE_DONE, DOZE);
+
+        mSensor.sendSensorEvent(1000);
+
+        assertNotEquals(1000, mServiceFake.screenBrightness);
+    }
+
+    @Test
+    public void testNullSensor() throws Exception {
+        mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager,
+                null /* sensor */, mHostFake, null /* handler */);
+
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSED);
+    }
+
+    @Test
+    public void testNoBrightnessDeliveredAfterFinish() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+        mScreen.transitionTo(DOZE_AOD, FINISH);
+
+        mSensor.sendSensorEvent(1000);
+
+        assertNotEquals(1000, mServiceFake.screenBrightness);
+    }
+
+    @Test
+    public void testBrightness_atLeastOne() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        mSensor.sendSensorEvent(0);
+
+        assertTrue("Brightness must be at least 1, but was " + mServiceFake.screenBrightness,
+                mServiceFake.screenBrightness >= 1);
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java
new file mode 100644
index 0000000..c787eff
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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.doze;
+
+import static com.android.systemui.doze.DozeMachine.State.DOZE;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE;
+import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
+import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.Display;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DozeScreenStateTest extends SysuiTestCase {
+
+    DozeServiceFake mServiceFake;
+    DozeScreenState mScreen;
+    private ImmediateHandler mHandler;
+
+    @Before
+    public void setUp() throws Exception {
+        mServiceFake = new DozeServiceFake();
+        mHandler = spy(new ImmediateHandler(Looper.getMainLooper()));
+        mScreen = new DozeScreenState(mServiceFake, mHandler);
+    }
+
+    @Test
+    public void testScreen_offInDoze() {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE);
+
+        assertEquals(Display.STATE_OFF, mServiceFake.screenState);
+    }
+
+    @Test
+    public void testScreen_onInAod() {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState);
+    }
+
+    @Test
+    public void testScreen_onInPulse() {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE);
+
+        mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE);
+        mScreen.transitionTo(DOZE_REQUEST_PULSE, DOZE_PULSING);
+
+        assertEquals(Display.STATE_ON, mServiceFake.screenState);
+    }
+
+    @Test
+    public void testScreen_offInRequestPulseWithoutAoD() {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE);
+
+        mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE);
+
+        assertEquals(Display.STATE_OFF, mServiceFake.screenState);
+    }
+
+    @Test
+    public void testScreen_offInRequestPulseWithAoD() {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE);
+
+        assertEquals(Display.STATE_OFF, mServiceFake.screenState);
+    }
+
+    @Test
+    public void test_postedToHandler() {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        verify(mHandler).sendMessageAtTime(any(), anyLong());
+    }
+
+    private static class ImmediateHandler extends Handler {
+
+        public ImmediateHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+            Runnable callback = msg.getCallback();
+            if (callback != null) {
+                callback.run();
+                return false;
+            }
+            return super.sendMessageAtTime(msg, uptimeMillis);
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeServiceFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeServiceFake.java
index c1e7fe4..34026b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeServiceFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeServiceFake.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.doze;
 
+import android.os.PowerManager;
 import android.view.Display;
 
 public class DozeServiceFake implements DozeMachine.Service {
@@ -23,6 +24,7 @@
     public boolean finished;
     public int screenState;
     public boolean requestedWakeup;
+    public int screenBrightness;
 
     public DozeServiceFake() {
         reset();
@@ -38,13 +40,19 @@
         screenState = state;
     }
 
-    public void reset() {
-        finished = false;
-        screenState = Display.STATE_UNKNOWN;
-    }
-
     @Override
     public void requestWakeUp() {
         requestedWakeup = true;
     }
+
+    @Override
+    public void setDozeScreenBrightness(int brightness) {
+        screenBrightness = brightness;
+    }
+
+    public void reset() {
+        finished = false;
+        screenState = Display.STATE_UNKNOWN;
+        screenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java
new file mode 100644
index 0000000..d78e739
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.doze;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.support.test.filters.SmallTest;
+import android.view.Display;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.phone.DozeParameters;
+
+import org.junit.Before;
+import org.junit.Test;
+
+@SmallTest
+public class DozeSuspendScreenStatePreventingAdapterTest extends SysuiTestCase {
+
+    private DozeMachine.Service mInner;
+    private DozeSuspendScreenStatePreventingAdapter mWrapper;
+
+    @Before
+    public void setup() throws Exception {
+        mInner = mock(DozeMachine.Service.class);
+        mWrapper = new DozeSuspendScreenStatePreventingAdapter(mInner);
+    }
+
+    @Test
+    public void forwards_finish() throws Exception {
+        mWrapper.finish();
+        verify(mInner).finish();
+    }
+
+    @Test
+    public void forwards_setDozeScreenState_on() throws Exception {
+        mWrapper.setDozeScreenState(Display.STATE_ON);
+        verify(mInner).setDozeScreenState(Display.STATE_ON);
+    }
+
+    @Test
+    public void forwards_setDozeScreenState_off() throws Exception {
+        mWrapper.setDozeScreenState(Display.STATE_OFF);
+        verify(mInner).setDozeScreenState(Display.STATE_OFF);
+    }
+
+    @Test
+    public void forwards_setDozeScreenState_doze() throws Exception {
+        mWrapper.setDozeScreenState(Display.STATE_DOZE);
+        verify(mInner).setDozeScreenState(Display.STATE_DOZE);
+    }
+
+    @Test
+    public void forwards_setDozeScreenState_doze_suspend() throws Exception {
+        mWrapper.setDozeScreenState(Display.STATE_DOZE_SUSPEND);
+        verify(mInner).setDozeScreenState(Display.STATE_DOZE);
+    }
+
+    @Test
+    public void forwards_requestWakeUp() throws Exception {
+        mWrapper.requestWakeUp();
+        verify(mInner).requestWakeUp();
+    }
+
+    @Test
+    public void wrapIfNeeded_needed() throws Exception {
+        DozeParameters params = mock(DozeParameters.class);
+        when(params.getDozeSuspendDisplayStateSupported()).thenReturn(false);
+
+        assertEquals(DozeSuspendScreenStatePreventingAdapter.class,
+                DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params).getClass());
+    }
+
+    @Test
+    public void wrapIfNeeded_not_needed() throws Exception {
+        DozeParameters params = mock(DozeParameters.class);
+        when(params.getDozeSuspendDisplayStateSupported()).thenReturn(true);
+
+        assertSame(mInner, DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params));
+    }
+}
\ No newline at end of file
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 b054690..a8ea1c0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -23,11 +23,11 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.AlarmManager;
 import android.app.Instrumentation;
 import android.os.Handler;
 import android.os.Looper;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
@@ -40,10 +40,12 @@
 
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @SmallTest
+@Ignore("failing")
 @RunWith(AndroidJUnit4.class)
 public class DozeTriggersTest extends SysuiTestCase {
     private DozeTriggers mTriggers;
@@ -55,6 +57,7 @@
     private Handler mHandler;
     private WakeLock mWakeLock;
     private Instrumentation mInstrumentation;
+    private AlarmManager mAlarmManager;
 
     @BeforeClass
     public static void setupSuite() {
@@ -66,6 +69,7 @@
     public void setUp() throws Exception {
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mMachine = mock(DozeMachine.class);
+        mAlarmManager = mock(AlarmManager.class);
         mHost = new DozeHostFake();
         mConfig = DozeConfigurationUtil.createMockConfig();
         mParameters = DozeConfigurationUtil.createMockParameters();
@@ -74,12 +78,11 @@
         mWakeLock = new WakeLockFake();
 
         mInstrumentation.runOnMainSync(() -> {
-            mTriggers = new DozeTriggers(mContext, mMachine, mHost,
+            mTriggers = new DozeTriggers(mContext, mMachine, mHost, mAlarmManager,
                     mConfig, mParameters, mSensors, mHandler, mWakeLock, true);
         });
     }
 
-    @FlakyTest
     @Test
     public void testOnNotification_stillWorksAfterOneFailedProxCheck() throws Exception {
         when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE);
@@ -109,4 +112,4 @@
         verify(mMachine).requestPulse(anyInt());
     }
 
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
new file mode 100644
index 0000000..19a30cc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.doze;
+
+import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSED;
+import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
+import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.app.AlarmManager;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.util.wakelock.WakeLockFake;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DozeUiTest extends SysuiTestCase {
+
+    private AlarmManager mAlarmManager;
+    private DozeMachine mMachine;
+    private WakeLockFake mWakeLock;
+    private DozeHostFake mHost;
+    private Handler mHandler;
+    private HandlerThread mHandlerThread;
+    private DozeUi mDozeUi;
+
+    @Before
+    public void setUp() throws Exception {
+        mHandlerThread = new HandlerThread("DozeUiTest");
+        mHandlerThread.start();
+        mAlarmManager = mock(AlarmManager.class);
+        mMachine = mock(DozeMachine.class);
+        mWakeLock = new WakeLockFake();
+        mHost = new DozeHostFake();
+        mHandler = mHandlerThread.getThreadHandler();
+
+        mDozeUi = new DozeUi(mContext, mAlarmManager, mMachine, mWakeLock, mHost, mHandler);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mHandlerThread.quit();
+        mHandler = null;
+        mHandlerThread = null;
+    }
+
+    @Test
+    public void pausingAndUnpausingAod_registersTimeTickAfterUnpausing() throws Exception {
+        mDozeUi.transitionTo(UNINITIALIZED, INITIALIZED);
+        mDozeUi.transitionTo(INITIALIZED, DOZE_AOD);
+        mDozeUi.transitionTo(DOZE_AOD, DOZE_AOD_PAUSED);
+
+        clearInvocations(mAlarmManager);
+
+        mDozeUi.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD);
+
+        verify(mAlarmManager).setExact(anyInt(), anyLong(), eq("doze_time_tick"), any(), any());
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LifecycleTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LifecycleTest.java
new file mode 100644
index 0000000..e0807d6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LifecycleTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.keyguard;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class LifecycleTest extends SysuiTestCase {
+
+    private final Object mObj1 = new Object();
+    private final Object mObj2 = new Object();
+
+    private Lifecycle<Object> mLifecycle;
+    private ArrayList<Object> mDispatchedObjects;
+
+    @Before
+    public void setUp() throws Exception {
+        mLifecycle = new Lifecycle<>();
+        mDispatchedObjects = new ArrayList<>();
+    }
+
+    @Test
+    public void addObserver_addsObserver() throws Exception {
+        mLifecycle.addObserver(mObj1);
+
+        mLifecycle.dispatch(mDispatchedObjects::add);
+
+        assertTrue(mDispatchedObjects.contains(mObj1));
+    }
+
+    @Test
+    public void removeObserver() throws Exception {
+        mLifecycle.addObserver(mObj1);
+        mLifecycle.removeObserver(mObj1);
+
+        mLifecycle.dispatch(mDispatchedObjects::add);
+
+        assertFalse(mDispatchedObjects.contains(mObj1));
+    }
+
+    @Test
+    public void dispatch() throws Exception {
+        mLifecycle.addObserver(mObj1);
+        mLifecycle.addObserver(mObj2);
+
+        mLifecycle.dispatch(mDispatchedObjects::add);
+
+        assertTrue(mDispatchedObjects.contains(mObj1));
+        assertTrue(mDispatchedObjects.contains(mObj2));
+    }
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ScreenLifecycleTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ScreenLifecycleTest.java
new file mode 100644
index 0000000..8c918f6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ScreenLifecycleTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.keyguard;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class ScreenLifecycleTest extends SysuiTestCase {
+
+    private ScreenLifecycle mScreen;
+    private ScreenLifecycle.Observer mScreenObserverMock;
+
+    @Before
+    public void setUp() throws Exception {
+        mScreen = new ScreenLifecycle();
+        mScreenObserverMock = mock(ScreenLifecycle.Observer.class);
+        mScreen.addObserver(mScreenObserverMock);
+    }
+
+    @Test
+    public void baseState() throws Exception {
+        assertEquals(ScreenLifecycle.SCREEN_OFF, mScreen.getScreenState());
+        verifyNoMoreInteractions(mScreenObserverMock);
+    }
+
+    @Test
+    public void screenTurningOn() throws Exception {
+        mScreen.dispatchScreenTurningOn();
+
+        assertEquals(ScreenLifecycle.SCREEN_TURNING_ON, mScreen.getScreenState());
+        verify(mScreenObserverMock).onScreenTurningOn();
+    }
+
+    @Test
+    public void screenTurnedOn() throws Exception {
+        mScreen.dispatchScreenTurningOn();
+        mScreen.dispatchScreenTurnedOn();
+
+        assertEquals(ScreenLifecycle.SCREEN_ON, mScreen.getScreenState());
+        verify(mScreenObserverMock).onScreenTurnedOn();
+    }
+
+    @Test
+    public void screenTurningOff() throws Exception {
+        mScreen.dispatchScreenTurningOn();
+        mScreen.dispatchScreenTurnedOn();
+        mScreen.dispatchScreenTurningOff();
+
+        assertEquals(ScreenLifecycle.SCREEN_TURNING_OFF, mScreen.getScreenState());
+        verify(mScreenObserverMock).onScreenTurningOff();
+    }
+
+    @Test
+    public void screenTurnedOff() throws Exception {
+        mScreen.dispatchScreenTurningOn();
+        mScreen.dispatchScreenTurnedOn();
+        mScreen.dispatchScreenTurningOff();
+        mScreen.dispatchScreenTurnedOff();
+
+        assertEquals(ScreenLifecycle.SCREEN_OFF, mScreen.getScreenState());
+        verify(mScreenObserverMock).onScreenTurnedOff();
+    }
+
+    @Test
+    public void dump() throws Exception {
+        mScreen.dump(null, new PrintWriter(new ByteArrayOutputStream()), new String[0]);
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java
new file mode 100644
index 0000000..e15e0b4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.keyguard;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class WakefulnessLifecycleTest extends SysuiTestCase {
+
+    private WakefulnessLifecycle mWakefulness;
+    private WakefulnessLifecycle.Observer mWakefulnessObserver;
+
+    @Before
+    public void setUp() throws Exception {
+        mWakefulness = new WakefulnessLifecycle();
+        mWakefulnessObserver = mock(WakefulnessLifecycle.Observer.class);
+        mWakefulness.addObserver(mWakefulnessObserver);
+    }
+
+    @Test
+    public void baseState() throws Exception {
+        assertEquals(WakefulnessLifecycle.WAKEFULNESS_ASLEEP, mWakefulness.getWakefulness());
+
+        verifyNoMoreInteractions(mWakefulnessObserver);
+    }
+
+    @Test
+    public void dispatchStartedWakingUp() throws Exception {
+        mWakefulness.dispatchStartedWakingUp();
+
+        assertEquals(WakefulnessLifecycle.WAKEFULNESS_WAKING, mWakefulness.getWakefulness());
+
+        verify(mWakefulnessObserver).onStartedWakingUp();
+    }
+
+    @Test
+    public void dispatchFinishedWakingUp() throws Exception {
+        mWakefulness.dispatchStartedWakingUp();
+        mWakefulness.dispatchFinishedWakingUp();
+
+        assertEquals(WakefulnessLifecycle.WAKEFULNESS_AWAKE, mWakefulness.getWakefulness());
+
+        verify(mWakefulnessObserver).onFinishedWakingUp();
+    }
+
+    @Test
+    public void dispatchStartedGoingToSleep() throws Exception {
+        mWakefulness.dispatchStartedWakingUp();
+        mWakefulness.dispatchFinishedWakingUp();
+        mWakefulness.dispatchStartedGoingToSleep();
+
+        assertEquals(WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP,
+                mWakefulness.getWakefulness());
+
+        verify(mWakefulnessObserver).onStartedGoingToSleep();
+    }
+
+    @Test
+    public void dispatchFinishedGoingToSleep() throws Exception {
+        mWakefulness.dispatchStartedWakingUp();
+        mWakefulness.dispatchFinishedWakingUp();
+        mWakefulness.dispatchStartedGoingToSleep();
+        mWakefulness.dispatchFinishedGoingToSleep();
+
+        assertEquals(WakefulnessLifecycle.WAKEFULNESS_ASLEEP,
+                mWakefulness.getWakefulness());
+
+        verify(mWakefulnessObserver).onFinishedGoingToSleep();
+    }
+
+    @Test
+    public void dump() throws Exception {
+        mWakefulness.dump(null, new PrintWriter(new ByteArrayOutputStream()), new String[0]);
+    }
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
index b8e9fcd..bba982c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
@@ -26,8 +26,6 @@
 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;
@@ -36,11 +34,10 @@
 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.annotations.ProvidesInterface;
 import com.android.systemui.plugins.PluginManagerImpl.PluginInstanceManagerFactory;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
index eb59a34..1b74ebb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
@@ -51,8 +51,8 @@
     @Before
     public void setUp() throws Exception {
         // Test Instance.
-        mPowerNotificationWarnings = new PowerNotificationWarnings(
-                mContext, mMockNotificationManager, null);
+        mContext.addMockSystemService(NotificationManager.class, mMockNotificationManager);
+        mPowerNotificationWarnings = new PowerNotificationWarnings(mContext);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
new file mode 100644
index 0000000..e4734a4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
@@ -0,0 +1,149 @@
+/*
+ * 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.power;
+
+import static android.os.HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN;
+import static android.os.HardwarePropertiesManager.TEMPERATURE_CURRENT;
+import static android.os.HardwarePropertiesManager.TEMPERATURE_SHUTDOWN;
+import static android.provider.Settings.Global.SHOW_TEMPERATURE_WARNING;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.HardwarePropertiesManager;
+import android.provider.Settings;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.testing.TestableResources;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.power.PowerUI.WarningsUI;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class PowerUITest extends SysuiTestCase {
+
+    private HardwarePropertiesManager mHardProps;
+    private WarningsUI mMockWarnings;
+    private PowerUI mPowerUI;
+
+    @Before
+    public void setup() {
+        mMockWarnings = mDependency.injectMockDependency(WarningsUI.class);
+        mHardProps = mock(HardwarePropertiesManager.class);
+        mContext.putComponent(StatusBar.class, mock(StatusBar.class));
+        mContext.addMockSystemService(Context.HARDWARE_PROPERTIES_SERVICE, mHardProps);
+
+        createPowerUi();
+    }
+
+    @Test
+    public void testNoConfig_NoWarnings() {
+        setOverThreshold();
+        Settings.Global.putString(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, null);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 0);
+        resources.addOverride(R.integer.config_warningTemperature, 55);
+
+        mPowerUI.start();
+        verify(mMockWarnings, never()).showHighTemperatureWarning();
+    }
+
+    @Test
+    public void testConfig_NoWarnings() {
+        setUnderThreshold();
+        Settings.Global.putString(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, null);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 1);
+        resources.addOverride(R.integer.config_warningTemperature, 55);
+
+        mPowerUI.start();
+        verify(mMockWarnings, never()).showHighTemperatureWarning();
+    }
+
+    @Test
+    public void testConfig_Warnings() {
+        setOverThreshold();
+        Settings.Global.putString(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, null);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 1);
+        resources.addOverride(R.integer.config_warningTemperature, 55);
+
+        mPowerUI.start();
+        verify(mMockWarnings).showHighTemperatureWarning();
+    }
+
+    @Test
+    public void testSettingOverrideConfig() {
+        setOverThreshold();
+        Settings.Global.putInt(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, 1);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 0);
+        resources.addOverride(R.integer.config_warningTemperature, 55);
+
+        mPowerUI.start();
+        verify(mMockWarnings).showHighTemperatureWarning();
+    }
+
+    @Test
+    public void testShutdownBasedThreshold() {
+        int tolerance = 2;
+        Settings.Global.putString(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, null);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 1);
+        resources.addOverride(R.integer.config_warningTemperature, -1);
+        resources.addOverride(R.integer.config_warningTemperatureTolerance, tolerance);
+        when(mHardProps.getDeviceTemperatures(DEVICE_TEMPERATURE_SKIN, TEMPERATURE_SHUTDOWN))
+                .thenReturn(new float[] { 55 + tolerance });
+
+        setCurrentTemp(54); // Below threshold.
+        mPowerUI.start();
+        verify(mMockWarnings, never()).showHighTemperatureWarning();
+
+        setCurrentTemp(56); // Above threshold.
+        mPowerUI.updateTemperatureWarning();
+        verify(mMockWarnings).showHighTemperatureWarning();
+    }
+
+    private void setCurrentTemp(float temp) {
+        when(mHardProps.getDeviceTemperatures(DEVICE_TEMPERATURE_SKIN, TEMPERATURE_CURRENT))
+                .thenReturn(new float[] { temp });
+    }
+
+    private void setOverThreshold() {
+        setCurrentTemp(50000);
+    }
+
+    private void setUnderThreshold() {
+        setCurrentTemp(5);
+    }
+
+    private void createPowerUi() {
+        mPowerUI = new PowerUI();
+        mPowerUI.mContext = mContext;
+        mPowerUI.mComponents = mContext.getComponents();
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java
new file mode 100644
index 0000000..40f8059
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.qs;
+
+import static com.android.systemui.statusbar.phone.AutoTileManager.INVERSION;
+import static com.android.systemui.statusbar.phone.AutoTileManager.SAVER;
+import static com.android.systemui.statusbar.phone.AutoTileManager.WORK;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.provider.Settings.Secure;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.systemui.Prefs;
+import com.android.systemui.Prefs.Key;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class AutoAddTrackerTest extends SysuiTestCase {
+
+    private AutoAddTracker mAutoTracker;
+
+    @Test
+    public void testMigration() {
+        Prefs.putBoolean(mContext, Key.QS_DATA_SAVER_ADDED, true);
+        Prefs.putBoolean(mContext, Key.QS_WORK_ADDED, true);
+        mAutoTracker = new AutoAddTracker(mContext);
+
+        assertTrue(mAutoTracker.isAdded(SAVER));
+        assertTrue(mAutoTracker.isAdded(WORK));
+        assertFalse(mAutoTracker.isAdded(INVERSION));
+
+        assertFalse(Prefs.getBoolean(mContext, Key.QS_DATA_SAVER_ADDED, false));
+        assertFalse(Prefs.getBoolean(mContext, Key.QS_WORK_ADDED, false));
+
+        mAutoTracker.destroy();
+    }
+
+    @Test
+    public void testChangeFromBackup() {
+        mAutoTracker = new AutoAddTracker(mContext);
+
+        assertFalse(mAutoTracker.isAdded(SAVER));
+
+        Secure.putString(mContext.getContentResolver(), Secure.QS_AUTO_ADDED_TILES, SAVER);
+        mAutoTracker.mObserver.onChange(false);
+
+        assertTrue(mAutoTracker.isAdded(SAVER));
+
+        mAutoTracker.destroy();
+    }
+
+    @Test
+    public void testSetAdded() {
+        mAutoTracker = new AutoAddTracker(mContext);
+
+        assertFalse(mAutoTracker.isAdded(SAVER));
+        mAutoTracker.setTileAdded(SAVER);
+
+        assertTrue(mAutoTracker.isAdded(SAVER));
+
+        mAutoTracker.destroy();
+    }
+
+    @Test
+    public void testPersist() {
+        mAutoTracker = new AutoAddTracker(mContext);
+
+        assertFalse(mAutoTracker.isAdded(SAVER));
+        mAutoTracker.setTileAdded(SAVER);
+
+        mAutoTracker.destroy();
+        mAutoTracker = new AutoAddTracker(mContext);
+
+        assertTrue(mAutoTracker.isAdded(SAVER));
+
+        mAutoTracker.destroy();
+    }
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
index d270de8..ed47fbb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
@@ -23,8 +23,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import org.junit.After;
-import org.junit.Ignore;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -40,12 +38,14 @@
 import com.android.systemui.plugins.qs.DetailAdapter;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 @SmallTest
+@Ignore("failing")
 public class QSDetailTest extends SysuiTestCase {
 
     private MetricsLogger mMetricsLogger;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
index 402b12d..d25bbe1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
@@ -41,6 +41,7 @@
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 @SmallTest
+@Ignore("failing")
 public class QSFooterTest extends LeakCheckedTest {
 
     private QSFooter mFooter;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 0b7da1f..8cece92 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -52,6 +52,7 @@
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
+@Ignore("failing")
 public class QSFragmentTest extends SysuiBaseFragmentTest {
 
     private MetricsLogger mMockMetricsLogger;
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 e5ff866..85cdfcc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -30,7 +30,6 @@
 import com.android.systemui.qs.customize.QSCustomizer;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
index ebd266b..a8487b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -16,12 +16,16 @@
 
 import static junit.framework.Assert.assertEquals;
 
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.content.pm.UserInfo;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.UserManager;
+import android.provider.Settings;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.SpannableStringBuilder;
@@ -39,6 +43,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
 
 /*
  * Compile and run the whole SystemUI test suite:
@@ -63,6 +68,7 @@
     private TestableImageView mFooterIcon;
     private QSSecurityFooter mFooter;
     private SecurityController mSecurityController = mock(SecurityController.class);
+    private UserManager mUserManager;
 
     @Before
     public void setUp() {
@@ -72,6 +78,8 @@
                 new LayoutInflaterBuilder(mContext)
                         .replace("ImageView", TestableImageView.class)
                         .build());
+        mUserManager = Mockito.mock(UserManager.class);
+        mContext.addMockSystemService(Context.USER_SERVICE, mUserManager);
         Handler h = new Handler(Looper.getMainLooper());
         h.post(() -> mFooter = new QSSecurityFooter(null, mContext));
         waitForIdleSync(h);
@@ -123,6 +131,21 @@
     }
 
     @Test
+    public void testManagedDemoMode() {
+        when(mSecurityController.isDeviceManaged()).thenReturn(true);
+        when(mSecurityController.getDeviceOwnerOrganizationName()).thenReturn(null);
+        final UserInfo mockUserInfo = Mockito.mock(UserInfo.class);
+        when(mockUserInfo.isDemo()).thenReturn(true);
+        when(mUserManager.getUserInfo(anyInt())).thenReturn(mockUserInfo);
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_DEMO_MODE, 1);
+
+        mFooter.refreshState();
+
+        waitForIdleSync(mFooter.mHandler);
+        assertEquals(View.GONE, mRootView.getVisibility());
+    }
+
+    @Test
     public void testNetworkLoggingEnabled() {
         when(mSecurityController.isDeviceManaged()).thenReturn(true);
         when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/SlashImageViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/SlashImageViewTest.java
new file mode 100644
index 0000000..9fe3e10
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/SlashImageViewTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.qs;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.qs.QSTile.SlashState;
+import com.android.systemui.qs.tileimpl.SlashImageView;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class SlashImageViewTest extends SysuiTestCase {
+    private TestableSlashImageView mSlashView;
+
+    @Test
+    public void testSetNonNullSlashStateCreatesSlashDrawable() {
+        SlashState mockState = mock(SlashState.class);
+        Drawable mockDrawable = mock(Drawable.class);
+        mSlashView = new TestableSlashImageView(mContext);
+        assertTrue(mSlashView.getSlashDrawable() == null);
+
+        mSlashView.setState(mockState, mockDrawable);
+
+        assertTrue(mSlashView.getSlashDrawable() != null);
+    }
+
+    @Test
+    public void testSetNullSlashStateRemovesSlashDrawable() {
+        SlashState mockState = mock(SlashState.class);
+        Drawable mockDrawable = mock(Drawable.class);
+        mSlashView = new TestableSlashImageView(mContext);
+        mSlashView.setState(mockState, mockDrawable);
+
+        assertTrue(mSlashView.getSlashDrawable() != null);
+
+        mSlashView.setState(null, mockDrawable);
+
+        assertTrue(mSlashView.getSlashDrawable() == null);
+    }
+
+    @Test
+    public void testSetNullDrawableRemovesSlashDrawable() {
+        SlashState mockState = mock(SlashState.class);
+        Drawable mockDrawable = mock(Drawable.class);
+
+        mSlashView = new TestableSlashImageView(mContext);
+        mSlashView.setImageDrawable(mockDrawable);
+        mSlashView.setState(mockState, mockDrawable);
+        mSlashView.setImageDrawable(null);
+
+        assertTrue(mSlashView.getSlashDrawable() == null);
+    }
+
+    // Expose getSlashDrawable
+    private static class TestableSlashImageView extends SlashImageView {
+        TestableSlashImageView(Context c) {
+            super(c);
+        }
+
+        private SlashDrawable getSlashDrawable() {
+            return mSlash;
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index ddd6615..c016a85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -29,6 +29,8 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.policy.BluetoothController;
+
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 
@@ -52,7 +54,7 @@
 
     @Before
     public void setUp() throws Exception {
-        TestableLooper.get(this).setAsMainLooper();
+        mDependency.injectMockDependency(BluetoothController.class);
         mManagers = new ArrayList<>();
         QSTileHost host = new QSTileHost(mContext, null,
                 mock(StatusBarIconController.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index 8cacb4b..9603207 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -269,9 +269,9 @@
     }
 
     @Test
-    public void testHandleSysnavKey() {
-        mCommandQueue.handleSystemNavigationKey(1);
+    public void testHandleSysKey() {
+        mCommandQueue.handleSystemKey(1);
         waitForIdleSync();
-        verify(mCallbacks).handleSystemNavigationKey(eq(1));
+        verify(mCallbacks).handleSystemKey(eq(1));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
index 2e547e1..2f6511c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
@@ -21,20 +21,16 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.View;
 
-import com.android.systemui.statusbar.stack.NotificationChildrenContainer;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
+import com.android.systemui.statusbar.stack.NotificationChildrenContainer;
 
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -102,4 +98,40 @@
         row.setDark(true, false, 0);
         verify(row).updateShelfIconColor();
     }
+
+    @Test
+    public void testAboveShelfChangedListenerCalled() throws Exception {
+        ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
+        row.setAboveShelfChangedListener(listener);
+        row.setHeadsUp(true);
+        verify(listener).onAboveShelfStateChanged(true);
+    }
+
+    @Test
+    public void testAboveShelfChangedListenerCalledPinned() throws Exception {
+        ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
+        row.setAboveShelfChangedListener(listener);
+        row.setPinned(true);
+        verify(listener).onAboveShelfStateChanged(true);
+    }
+
+    @Test
+    public void testAboveShelfChangedListenerCalledHeadsUpGoingAway() throws Exception {
+        ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
+        row.setAboveShelfChangedListener(listener);
+        row.setHeadsUpAnimatingAway(true);
+        verify(listener).onAboveShelfStateChanged(true);
+    }
+    @Test
+    public void testAboveShelfChangedListenerCalledWhenGoingBelow() throws Exception {
+        ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setHeadsUp(true);
+        AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
+        row.setAboveShelfChangedListener(listener);
+        row.setAboveShelf(false);
+        verify(listener).onAboveShelfStateChanged(false);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
index 8dcc408..436849c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
@@ -16,27 +16,23 @@
 
 package com.android.systemui.statusbar;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.view.View;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 
+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.SysuiTestCase;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class NotificationContentViewTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
index 917a9f5..6e59d10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
@@ -16,10 +16,7 @@
 
 package com.android.systemui.statusbar;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.View;
@@ -32,7 +29,6 @@
 
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 6380847..b6827ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -232,6 +232,17 @@
     }
 
     @Test
+    public void testBindNotification_UnblockablePackageDoesNotUseChannelName() throws Exception {
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+                mNotificationChannel.getImportance(), mSbn, null, null, null,
+                null, Collections.singleton(TEST_PACKAGE_NAME));
+        final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
+        assertEquals(mContext.getString(R.string.notification_header_default_channel),
+                textView.getText());
+    }
+
+    @Test
     public void testBindNotification_DefaultChannelUsesNameWhenMoreThanOneChannelExists()
             throws Exception {
         when(mMockINotificationManager.getNumNotificationChannelsForPackage(
@@ -332,6 +343,21 @@
     }
 
     @Test
+    public void testBindNotification_SettingsTextWithMultipleChannelsForUnblockableApp()
+            throws Exception {
+        when(mMockINotificationManager.getNumNotificationChannelsForPackage(
+                eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(2);
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+                mNotificationChannel.getImportance(), mSbn,
+                (View v, NotificationChannel c, int appUid) -> {
+                }, null, null, null, Collections.singleton(TEST_PACKAGE_NAME));
+        final TextView settingsButton =
+                (TextView) mNotificationInfo.findViewById(R.id.more_settings);
+        assertEquals(getStringById(R.string.notification_more_settings), settingsButton.getText());
+    }
+
+    @Test
     public void testBindNotification_SetsOnClickListenerForDone() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -502,6 +528,19 @@
     }
 
     @Test
+    public void testbindNotification_UnblockableTextVisibleWhenAppUnblockable() throws Exception {
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+                mNotificationChannel.getImportance(), mSbn, null, null, null,
+                null, Collections.singleton(TEST_PACKAGE_NAME));
+        final TextView numChannelsView =
+                (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
+        assertEquals(View.VISIBLE, numChannelsView.getVisibility());
+        assertEquals(mContext.getString(R.string.notification_unblockable_desc),
+                numChannelsView.getText());
+    }
+
+    @Test
     @UiThreadTest
     public void testBindNotification_ChannelDisabledTextShowsForDefaultChannel()
             throws Exception {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
index e0d8042..2a2acab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
@@ -42,7 +42,7 @@
     @Test
     public void testAttachDetach() {
         NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
-        row.createMenu(null);
+        row.createMenu(null, null);
         ViewUtils.attachView(row.getMenuView());
         TestableLooper.get(this).processAllMessages();
         ViewUtils.detachView(row.getMenuView());
@@ -52,9 +52,15 @@
     @Test
     public void testRecreateMenu() {
         NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
-        row.createMenu(null);
+        row.createMenu(null, null);
         assertTrue(row.getMenuView() != null);
-        row.createMenu(null);
+        row.createMenu(null, null);
         assertTrue(row.getMenuView() != null);
     }
+
+    @Test
+    public void testResetUncreatedMenu() {
+        NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
+        row.resetMenu();
+    }
 }
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 cb238dd..6e7477f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -24,12 +24,16 @@
 import android.service.notification.StatusBarNotification;
 import android.support.test.InstrumentationRegistry;
 import android.view.LayoutInflater;
+import android.widget.FrameLayout;
 import android.widget.RemoteViews;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
+import com.android.systemui.statusbar.notification.AboveShelfObserver;
 import com.android.systemui.statusbar.notification.InflationException;
 import com.android.systemui.statusbar.notification.NotificationInflaterTest;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
 
 /**
  * A helper class to create {@link ExpandableNotificationRow}
@@ -42,10 +46,12 @@
     private final NotificationGroupManager mGroupManager = new NotificationGroupManager();
     private ExpandableNotificationRow mRow;
     private InflationException mException;
+    private HeadsUpManager mHeadsUpManager;
 
     public NotificationTestHelper(Context context) {
         mContext = context;
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mHeadsUpManager = new HeadsUpManager(mContext, null, mGroupManager);
     }
 
     public ExpandableNotificationRow createRow() throws Exception {
@@ -73,6 +79,8 @@
         });
         ExpandableNotificationRow row = mRow;
         row.setGroupManager(mGroupManager);
+        row.setHeadsUpManager(mHeadsUpManager);
+        row.setAboveShelfChangedListener(aboveShelf -> {});
         UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
         StatusBarNotification sbn = new StatusBarNotification("com.android.systemui",
                 "com.android.systemui", mId++, null, 1000,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java
new file mode 100644
index 0000000..4c3bf10
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.statusbar;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.testing.ViewUtils;
+import android.view.View;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.drawable.GradientDrawable;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.utils.leaks.LeakCheckedTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class ScrimViewTest extends LeakCheckedTest {
+
+    ScrimView mView;
+
+    @Before
+    public void setUp() {
+        injectLeakCheckedDependency(ConfigurationController.class);
+        mView = new ScrimView(getContext());
+        mView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+        mView.layout(0, 0, 1920, 1080);
+    }
+
+    @Test
+    @RunWithLooper
+    public void testAttachDetach() {
+        ViewUtils.attachView(mView);
+        TestableLooper.get(this).processAllMessages();
+        ViewUtils.detachView(mView);
+        TestableLooper.get(this).processAllMessages();
+    }
+
+    @Test
+    public void testSetDrawable_UpdateDrawable() {
+        Drawable drawable = new ColorDrawable(Color.GREEN);
+        mView.setDrawable(drawable);
+        assertEquals(drawable, mView.getDrawable());
+    }
+
+    @Test
+    public void testCreation_initialColor() {
+        GradientDrawable drawable = (GradientDrawable) mView.getDrawable();
+        ColorExtractor.GradientColors colors = mView.getColors();
+        assertEquals("Main color should be set upon creation",
+                drawable.getMainColor(), colors.getMainColor());
+        assertEquals("Secondary color should be set upon creation",
+                drawable.getSecondaryColor(), colors.getSecondaryColor());
+    }
+
+    @Test
+    public void testSetViewAlpha_propagatesToDrawable() {
+        float alpha = 0.5f;
+        mView.setViewAlpha(alpha);
+        assertEquals(mView.getViewAlpha(), alpha);
+    }
+
+    @Test
+    public void testOnDraw_ExcludeRectDrawable() {
+        mView.setExcludedArea(new Rect(10, 10, 20, 20));
+        Canvas canvas = mock(Canvas.class);
+        mView.onDraw(canvas);
+        // One time for each rect side
+        verify(canvas, times(4)).clipRect(anyInt(), anyInt(), anyInt(), anyInt());
+    }
+
+    @Test
+    public void setTint_set() {
+        int tint = Color.BLUE;
+        mView.setTint(tint);
+        assertEquals(mView.getTint(), tint);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java
new file mode 100644
index 0000000..1ee9b32
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.statusbar.notification;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.widget.FrameLayout;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.NotificationTestHelper;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AboveShelfObserverTest extends SysuiTestCase {
+
+    private AboveShelfObserver mObserver;
+    private FrameLayout mHostLayout;
+    private NotificationTestHelper mNotificationTestHelper;
+    private AboveShelfObserver.HasViewAboveShelfChangedListener mListener;
+
+    @Before
+    public void setUp() throws Exception {
+        mNotificationTestHelper = new NotificationTestHelper(getContext());
+        mHostLayout = new FrameLayout(getContext());
+        mObserver = new AboveShelfObserver(mHostLayout);
+        ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setAboveShelfChangedListener(mObserver);
+        mHostLayout.addView(row);
+        row = mNotificationTestHelper.createRow();
+        row.setAboveShelfChangedListener(mObserver);
+        mHostLayout.addView(row);
+        mListener = mock(AboveShelfObserver.HasViewAboveShelfChangedListener.class);
+    }
+
+    @Test
+    public void testObserverChangesWhenGoingAbove() {
+        ExpandableNotificationRow row = (ExpandableNotificationRow) mHostLayout.getChildAt(0);
+        mObserver.setListener(mListener);
+        row.setHeadsUp(true);
+        verify(mListener).onHasViewsAboveShelfChanged(true);
+    }
+
+    @Test
+    public void testObserverChangesWhenGoingBelow() {
+        ExpandableNotificationRow row = (ExpandableNotificationRow) mHostLayout.getChildAt(0);
+        row.setHeadsUp(true);
+        mObserver.setListener(mListener);
+        row.setHeadsUp(false);
+        verify(mListener).onHasViewsAboveShelfChanged(false);
+    }
+
+    @Test
+    public void testStaysAboveWhenOneGoesAway() {
+        ExpandableNotificationRow row = (ExpandableNotificationRow) mHostLayout.getChildAt(0);
+        row.setHeadsUp(true);
+        row = (ExpandableNotificationRow) mHostLayout.getChildAt(1);
+        row.setHeadsUp(true);
+        row.setHeadsUp(false);
+        Assert.assertTrue("There are still views above the shelf but removing one cleared it",
+                mObserver.hasViewsAboveShelf());
+    }
+}
+
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java
index 3429d5c6..e7e6829 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java
@@ -28,7 +28,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.service.notification.StatusBarNotification;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
@@ -40,9 +39,9 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.InflationTask;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.NotificationTestHelper;
-import com.android.systemui.statusbar.InflationTask;
 
 import org.junit.Assert;
 import org.junit.Before;
@@ -56,6 +55,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
+@FlakyTest
 public class NotificationInflaterTest extends SysuiTestCase {
 
     private NotificationInflater mNotificationInflater;
@@ -149,6 +149,7 @@
     }
 
     @Test
+    @Ignore
     public void testInflationIsRetriedIfAsyncFails() throws Exception {
         NotificationInflater.InflationProgress result =
                 new NotificationInflater.InflationProgress();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 0937ce2..c0de004 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -19,12 +19,13 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+
 import com.android.internal.app.NightDisplayController;
 import com.android.systemui.Prefs;
 import com.android.systemui.Prefs.Key;
-
-import android.support.test.filters.SmallTest;
-import android.testing.AndroidTestingRunner;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.qs.QSTileHost;
 
@@ -35,6 +36,7 @@
 import org.mockito.Mockito;
 
 @RunWith(AndroidTestingRunner.class)
+@RunWithLooper
 @SmallTest
 public class AutoTileManagerTest extends SysuiTestCase {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NearestTouchFrameTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NearestTouchFrameTest.java
new file mode 100644
index 0000000..ed1491d3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NearestTouchFrameTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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.statusbar.phone;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+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.content.res.Configuration;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class NearestTouchFrameTest extends SysuiTestCase {
+
+    private NearestTouchFrame mNearestTouchFrame;
+
+    @Before
+    public void setup() {
+        Configuration c = new Configuration(mContext.getResources().getConfiguration());
+        c.smallestScreenWidthDp = 500;
+        mNearestTouchFrame = new NearestTouchFrame(mContext, null, c);
+    }
+
+    @Test
+    public void testNoActionOnLargeDevices() {
+        Configuration c = new Configuration(mContext.getResources().getConfiguration());
+        c.smallestScreenWidthDp = 700;
+        mNearestTouchFrame = new NearestTouchFrame(mContext, null, c);
+
+        View left = mockViewAt(0, 0, 10, 10);
+        View right = mockViewAt(20, 0, 10, 10);
+
+        mNearestTouchFrame.addView(left);
+        mNearestTouchFrame.addView(right);
+        mNearestTouchFrame.onMeasure(0, 0);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                12 /* x */, 5 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(left, never()).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testHorizontalSelection_Left() {
+        View left = mockViewAt(0, 0, 10, 10);
+        View right = mockViewAt(20, 0, 10, 10);
+
+        mNearestTouchFrame.addView(left);
+        mNearestTouchFrame.addView(right);
+        mNearestTouchFrame.onMeasure(0, 0);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                12 /* x */, 5 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(left).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testHorizontalSelection_Right() {
+        View left = mockViewAt(0, 0, 10, 10);
+        View right = mockViewAt(20, 0, 10, 10);
+
+        mNearestTouchFrame.addView(left);
+        mNearestTouchFrame.addView(right);
+        mNearestTouchFrame.onMeasure(0, 0);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                18 /* x */, 5 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(right).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testVerticalSelection_Top() {
+        View top = mockViewAt(0, 0, 10, 10);
+        View bottom = mockViewAt(0, 20, 10, 10);
+
+        mNearestTouchFrame.addView(top);
+        mNearestTouchFrame.addView(bottom);
+        mNearestTouchFrame.onMeasure(0, 0);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                5 /* x */, 12 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(top).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testVerticalSelection_Bottom() {
+        View top = mockViewAt(0, 0, 10, 10);
+        View bottom = mockViewAt(0, 20, 10, 10);
+
+        mNearestTouchFrame.addView(top);
+        mNearestTouchFrame.addView(bottom);
+        mNearestTouchFrame.onMeasure(0, 0);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                5 /* x */, 18 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(bottom).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    private View mockViewAt(int x, int y, int width, int height) {
+        View v = spy(new View(mContext));
+        doAnswer(invocation -> {
+            int[] pos = (int[]) invocation.getArguments()[0];
+            pos[0] = x;
+            pos[1] = y;
+            return null;
+        }).when(v).getLocationInWindow(any());
+        when(v.isClickable()).thenReturn(true);
+
+        // Stupid final methods.
+        v.setLeft(0);
+        v.setRight(width);
+        v.setTop(0);
+        v.setBottom(height);
+        return v;
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 0e3ea7a..a706368 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
@@ -38,6 +38,8 @@
 import static org.mockito.Mockito.verify;
 
 import android.app.Notification;
+import android.app.trust.TrustManager;
+import android.hardware.fingerprint.FingerprintManager;
 import android.metrics.LogMaker;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -55,6 +57,7 @@
 import android.testing.TestableLooper.MessageHandler;
 import android.testing.TestableLooper.RunWithLooper;
 import android.util.DisplayMetrics;
+import android.view.ViewGroup.LayoutParams;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -62,8 +65,10 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.keyguard.KeyguardHostView.OnDismissAction;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.statusbar.ActivatableNotificationView;
+import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.NotificationData.Entry;
@@ -75,6 +80,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 
 @SmallTest
@@ -99,6 +106,8 @@
 
     @Before
     public void setup() throws Exception {
+        mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
+        mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
         mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager.class);
         mUnlockMethodCache = mock(UnlockMethodCache.class);
         mKeyguardIndicationController = mock(KeyguardIndicationController.class);
@@ -108,6 +117,7 @@
         mNotificationData = mock(NotificationData.class);
         mSystemServicesProxy = mock(SystemServicesProxy.class);
         mNotificationPanelView = mock(NotificationPanelView.class);
+        when(mNotificationPanelView.getLayoutParams()).thenReturn(new LayoutParams(0, 0));
         mNotificationList = mock(ArrayList.class);
         IPowerManager powerManagerService = mock(IPowerManager.class);
         HandlerThread handlerThread = new HandlerThread("TestThread");
@@ -122,6 +132,7 @@
                 mKeyguardIndicationController, mStackScroller, mHeadsUpManager,
                 mNotificationData, mPowerManager, mSystemServicesProxy, mNotificationPanelView,
                 mBarService);
+        mStatusBar.mContext = mContext;
         doAnswer(invocation -> {
             OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
             onDismissAction.onDismiss();
@@ -147,6 +158,12 @@
     }
 
     @Test
+    public void testSetBouncerShowing_noCrash() {
+        mStatusBar.mCommandQueue = mock(CommandQueue.class);
+        mStatusBar.setBouncerShowing(true);
+    }
+
+    @Test
     public void executeRunnableDismissingKeyguard_nullRunnable_showingAndOccluded() {
         when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
         when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(true);
@@ -318,6 +335,83 @@
     }
 
     @Test
+    public void testShouldPeek_suppressedScreenOn_dozing() {
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
+        when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
+        when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+        when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+
+        mStatusBar.mDozing = true;
+        when(mNotificationData.shouldSuppressScreenOn(any())).thenReturn(true);
+        when(mNotificationData.shouldSuppressScreenOff(any())).thenReturn(false);
+
+        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);
+
+        assertTrue(mStatusBar.shouldPeek(entry, sbn));
+    }
+
+    @Test
+    public void testShouldPeek_suppressedScreenOn_noDoze() {
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
+        when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
+        when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+        when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+
+        mStatusBar.mDozing = false;
+        when(mNotificationData.shouldSuppressScreenOn(any())).thenReturn(true);
+        when(mNotificationData.shouldSuppressScreenOff(any())).thenReturn(false);
+
+        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);
+        assertFalse(mStatusBar.shouldPeek(entry, sbn));
+    }
+    @Test
+    public void testShouldPeek_suppressedScreenOff_dozing() {
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
+        when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
+        when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+        when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+
+        mStatusBar.mDozing = true;
+        when(mNotificationData.shouldSuppressScreenOn(any())).thenReturn(false);
+        when(mNotificationData.shouldSuppressScreenOff(any())).thenReturn(true);
+
+        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);
+        assertFalse(mStatusBar.shouldPeek(entry, sbn));
+    }
+
+    @Test
+    public void testShouldPeek_suppressedScreenOff_noDoze() {
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
+        when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
+        when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+        when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+
+        mStatusBar.mDozing = false;
+        when(mNotificationData.shouldSuppressScreenOn(any())).thenReturn(false);
+        when(mNotificationData.shouldSuppressScreenOff(any())).thenReturn(true);
+
+        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);
+        assertTrue(mStatusBar.shouldPeek(entry, sbn));
+    }
+
+
+    @Test
     public void testLogHidden() {
         try {
             mStatusBar.handleVisibleToUserChanged(false);
@@ -385,6 +479,11 @@
         TestableLooper.get(this).processAllMessages();
     }
 
+    @Test
+    public void testDump_DoesNotCrash() {
+        mStatusBar.dump(null, new PrintWriter(new ByteArrayOutputStream()), null);
+    }
+
     static class TestableStatusBar extends StatusBar {
         public TestableStatusBar(StatusBarKeyguardViewManager man,
                 UnlockMethodCache unlock, KeyguardIndicationController key,
@@ -402,6 +501,14 @@
             mSystemServicesProxy = ssp;
             mNotificationPanel = panelView;
             mBarService = barService;
+            mWakefulnessLifecycle = createAwakeWakefulnessLifecycle();
+        }
+
+        private WakefulnessLifecycle createAwakeWakefulnessLifecycle() {
+            WakefulnessLifecycle wakefulnessLifecycle = new WakefulnessLifecycle();
+            wakefulnessLifecycle.dispatchStartedWakingUp();
+            wakefulnessLifecycle.dispatchFinishedWakingUp();
+            return wakefulnessLifecycle;
         }
 
         public void setBarStateForTest(int state) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
index cb20639..51bd7bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
@@ -18,6 +18,7 @@
 import android.os.HandlerThread;
 import android.support.test.runner.AndroidJUnit4;
 import android.telephony.SubscriptionInfo;
+import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
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
new file mode 100644
index 0000000..a915cb20
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
@@ -0,0 +1,199 @@
+/*
+ * 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.statusbar.policy;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.res.Configuration;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.util.Log;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.SysuiTestCase;
+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.statusbar.policy.ConfigurationController.ConfigurationListener;
+import com.android.systemui.statusbar.policy.ExtensionController.Extension;
+import com.android.systemui.statusbar.policy.ExtensionController.TunerFactory;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+import java.util.Map;
+import java.util.function.Consumer;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class ExtensionControllerImplTest extends SysuiTestCase {
+
+    private PluginManager mPluginManager;
+    private TunerService mTunerService;
+    private ExtensionController mExtensionController;
+    private ConfigurationController mConfigurationController;
+
+    @Before
+    public void setup() {
+        mPluginManager = mDependency.injectMockDependency(PluginManager.class);
+        mTunerService = mDependency.injectMockDependency(TunerService.class);
+        mConfigurationController = mDependency.injectMockDependency(ConfigurationController.class);
+        mExtensionController = Dependency.get(ExtensionController.class);
+    }
+
+    @Test
+    public void testPlugin() {
+        OverlayPlugin plugin = mock(OverlayPlugin.class);
+
+        Extension ext = mExtensionController.newExtension(OverlayPlugin.class)
+                .withPlugin(OverlayPlugin.class)
+                .build();
+        ArgumentCaptor<PluginListener> listener = ArgumentCaptor.forClass(PluginListener.class);
+        verify(mPluginManager).addPluginListener(eq(OverlayPlugin.ACTION), listener.capture(),
+                eq(OverlayPlugin.class));
+
+        listener.getValue().onPluginConnected(plugin, null);
+        assertEquals(plugin, ext.get());
+
+        ext.destroy();
+        verify(mPluginManager).removePluginListener(any());
+    }
+
+    @Test
+    public void testTuner() {
+        String[] keys = new String[] { "key1", "key2" };
+        TunerFactory<Object> factory = new ExtensionController.TunerFactory() {
+            @Override
+            public String[] keys() {
+                return keys;
+            }
+
+            @Override
+            public Object create(Map settings) {
+                return null;
+            }
+        };
+        Extension ext = mExtensionController.newExtension(Object.class)
+                .withTunerFactory(factory)
+                .build();
+        verify(mTunerService).addTunable(any(), eq(keys[0]), eq(keys[1]));
+
+        ext.destroy();
+        verify(mTunerService).removeTunable(any());
+    }
+
+    @Test
+    @RunWithLooper
+    public void testUiMode() {
+        Object o = new Object();
+        Extension ext = mExtensionController.newExtension(Object.class)
+                .withUiMode(Configuration.UI_MODE_TYPE_CAR, () -> o)
+                .build();
+        ArgumentCaptor<ConfigurationListener> captor = ArgumentCaptor.forClass(
+                ConfigurationListener.class);
+        verify(mConfigurationController).addCallback(captor.capture());
+
+        Configuration c = new Configuration(mContext.getResources().getConfiguration());
+        c.uiMode = 0;
+        captor.getValue().onConfigChanged(c);
+        TestableLooper.get(this).processAllMessages();
+        assertNull(ext.get());
+
+        c.uiMode = Configuration.UI_MODE_TYPE_CAR;
+        captor.getValue().onConfigChanged(c);
+        TestableLooper.get(this).processAllMessages();
+        assertEquals(o, ext.get());
+
+        ext.destroy();
+        verify(mConfigurationController).removeCallback(eq(captor.getValue()));
+    }
+
+    @Test
+    public void testDefault() {
+        Object o = new Object();
+        Extension ext = mExtensionController.newExtension(Object.class)
+                .withDefault(() -> o)
+                .build();
+        assertEquals(o, ext.get());
+    }
+
+    @Test
+    @RunWithLooper
+    public void testSortOrder() {
+        Log.d("TestTest", "Config " + mContext.getResources().getConfiguration().uiMode);
+        Object def = new Object();
+        Object uiMode = new Object();
+        Object tuner = new Object();
+        Plugin plugin = mock(Plugin.class);
+        TunerFactory<Object> factory = mock(TunerFactory.class);
+        Extension ext = mExtensionController.newExtension(Object.class)
+                .withDefault(() -> def)
+                .withUiMode(Configuration.UI_MODE_TYPE_CAR, () -> uiMode)
+                .withTunerFactory(factory)
+                .withPlugin(Object.class, "some_action")
+                .build();
+
+        // Test default first.
+        assertEquals(def, ext.get());
+
+        // Enable a UI mode and check that.
+        ArgumentCaptor<ConfigurationListener> captor = ArgumentCaptor.forClass(
+                ConfigurationListener.class);
+        verify(mConfigurationController).addCallback(captor.capture());
+        Configuration c = new Configuration(mContext.getResources().getConfiguration());
+        c.uiMode |= Configuration.UI_MODE_TYPE_CAR;
+        captor.getValue().onConfigChanged(c);
+        TestableLooper.get(this).processAllMessages();
+        assertEquals(uiMode, ext.get());
+
+        // Turn on tuner item and check that.
+        when(factory.create(any())).thenReturn(tuner);
+        ArgumentCaptor<Tunable> tunable = ArgumentCaptor.forClass(Tunable.class);
+        verify(mTunerService).addTunable(tunable.capture(), any());
+        tunable.getValue().onTuningChanged(null, null);
+        assertEquals(tuner, ext.get());
+
+        // Lastly, check a plugin.
+        ArgumentCaptor<PluginListener> listener = ArgumentCaptor.forClass(PluginListener.class);
+        verify(mPluginManager).addPluginListener(any(), listener.capture(), any());
+        listener.getValue().onPluginConnected(plugin, null);
+        assertEquals(plugin, ext.get());
+    }
+
+    @Test
+    public void testCallback() {
+        Consumer<Object> callback = mock(Consumer.class);
+        final Object o = new Object();
+        mExtensionController.newExtension(Object.class)
+                .withDefault(() -> o)
+                .withCallback(callback)
+                .build();
+        verify(callback).accept(eq(o));
+    }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerTest.java
deleted file mode 100644
index 3d79d5b..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerTest.java
+++ /dev/null
@@ -1,108 +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.statusbar.policy;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.support.test.filters.SmallTest;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.OverlayPlugin;
-import com.android.systemui.plugins.PluginManager;
-import com.android.systemui.statusbar.policy.ExtensionController.Extension;
-import com.android.systemui.statusbar.policy.ExtensionController.TunerFactory;
-import com.android.systemui.tuner.TunerService;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Map;
-import java.util.function.Consumer;
-
-@SmallTest
-public class ExtensionControllerTest extends SysuiTestCase {
-
-    private PluginManager mPluginManager;
-    private TunerService mTunerService;
-    private ExtensionController mExtensionController;
-
-    @Before
-    public void setup() {
-        mPluginManager = mDependency.injectMockDependency(PluginManager.class);
-        mTunerService = mDependency.injectMockDependency(TunerService.class);
-        mExtensionController = Dependency.get(ExtensionController.class);
-    }
-
-    @Test
-    public void testPlugin() {
-        Extension ext = mExtensionController.newExtension(OverlayPlugin.class)
-                .withPlugin(OverlayPlugin.class)
-                .build();
-        verify(mPluginManager).addPluginListener(eq(OverlayPlugin.ACTION), any(),
-                eq(OverlayPlugin.class));
-
-        ext.destroy();
-        verify(mPluginManager).removePluginListener(any());
-    }
-
-    @Test
-    public void testTuner() {
-        String[] keys = new String[] { "key1", "key2" };
-        TunerFactory<Object> factory = new ExtensionController.TunerFactory() {
-            @Override
-            public String[] keys() {
-                return keys;
-            }
-
-            @Override
-            public Object create(Map settings) {
-                return null;
-            }
-        };
-        Extension ext = mExtensionController.newExtension(Object.class)
-                .withTunerFactory(factory)
-                .build();
-        verify(mTunerService).addTunable(any(), eq(keys[0]), eq(keys[1]));
-
-        ext.destroy();
-        verify(mTunerService).removeTunable(any());
-    }
-
-    @Test
-    public void testDefault() {
-        Object o = new Object();
-        Extension ext = mExtensionController.newExtension(Object.class)
-                .withDefault(() -> o)
-                .build();
-        assertEquals(o, ext.get());
-    }
-
-    @Test
-    public void testCallback() {
-        Consumer<Object> callback = mock(Consumer.class);
-        final Object o = new Object();
-        mExtensionController.newExtension(Object.class)
-                .withDefault(() -> o)
-                .withCallback(callback)
-                .build();
-        verify(callback).accept(eq(o));
-    }
-
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 505e1d8..a8319a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -19,7 +19,6 @@
 import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.NetworkCapabilities;
-import android.net.NetworkScoreManager;
 import android.net.wifi.WifiManager;
 import android.os.Looper;
 import android.telephony.PhoneStateListener;
@@ -84,7 +83,6 @@
     protected Config mConfig;
     protected CallbackHandler mCallbackHandler;
     protected SubscriptionDefaults mMockSubDefaults;
-    protected NetworkScoreManager mMockNetworkScoreManager;
     protected DeviceProvisionedController mMockProvisionController;
     protected DeviceProvisionedListener mUserCallback;
 
@@ -113,8 +111,6 @@
         mMockCm = mock(ConnectivityManager.class);
         mMockSubDefaults = mock(SubscriptionDefaults.class);
         mNetCapabilities = new NetworkCapabilities();
-        mMockNetworkScoreManager = mock(NetworkScoreManager.class);
-
         when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true);
         when(mMockCm.getDefaultNetworkCapabilitiesForUser(0)).thenReturn(
                 new NetworkCapabilities[] { mNetCapabilities });
@@ -135,8 +131,7 @@
             return null;
         }).when(mMockProvisionController).addCallback(any());
 
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockNetworkScoreManager,
-                mMockTm, mMockWm, mMockSm,
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults, mMockProvisionController);
@@ -177,8 +172,8 @@
     protected NetworkControllerImpl setUpNoMobileData() {
       when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
       NetworkControllerImpl networkControllerNoMobile
-              = new NetworkControllerImpl(mContext, mMockCm, mMockNetworkScoreManager, mMockTm,
-                        mMockWm, mMockSm, mConfig, mContext.getMainLooper(), mCallbackHandler,
+              = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
+                        mConfig, mContext.getMainLooper(), mCallbackHandler,
                         mock(AccessPointControllerImpl.class),
                         mock(DataUsageController.class), mMockSubDefaults,
                         mock(DeviceProvisionedController.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index dfe00f9..7708adb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -21,6 +21,7 @@
 public class NetworkControllerDataTest extends NetworkControllerBaseTest {
 
     @Test
+    @Ignore("Flaky")
     public void test3gDataIcon() {
         setupDefaultSignal();
 
@@ -29,6 +30,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void test2gDataIcon() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -39,6 +41,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testCdmaDataIcon() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -49,6 +52,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testEdgeDataIcon() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -59,6 +63,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testLteDataIcon() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -69,6 +74,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testHspaDataIcon() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -79,6 +85,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testWfcNoDataIcon() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -88,11 +95,11 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void test4gDataIcon() {
         // Switch to showing 4g icon and re-initialize the NetworkController.
         mConfig.show4gForLte = true;
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockNetworkScoreManager,
-                mMockTm, mMockWm, mMockSm,
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class),
                 mock(DataUsageController.class), mMockSubDefaults,
@@ -107,8 +114,8 @@
                 TelephonyIcons.QS_DATA_4G);
     }
 
-    @Ignore("Flaky")
     @Test
+    @Ignore("Flaky")
     public void testDataDisabledIcon() {
         setupNetworkController();
         when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
@@ -121,6 +128,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testDataDisabledIcon_UserNotSetup() {
         setupNetworkController();
         when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
@@ -135,6 +143,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void test4gDataIconConfigChange() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -152,6 +161,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testDataChangeWithoutConnectionState() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -168,6 +178,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testDataActivity() {
         setupDefaultSignal();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 1627925..9055022 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -32,6 +32,7 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.SignalDrawable;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -50,12 +51,12 @@
 public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
 
     @Test
+    @Ignore("Flaky")
     public void testNoIconWithoutMobile() {
         // Turn off mobile network support.
         Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockNetworkScoreManager,
-                mMockTm, mMockWm, mMockSm,
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults, mock(DeviceProvisionedController.class));
@@ -65,6 +66,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testNoSimsIconPresent() {
         // No Subscriptions.
         mNetworkController.mMobileSignalControllers.clear();
@@ -74,6 +76,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testEmergencyOnly() {
         setupDefaultSignal();
         mNetworkController.recalculateEmergency();
@@ -85,6 +88,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testEmergencyOnlyNoSubscriptions() {
         setupDefaultSignal();
         setSubscriptions();
@@ -95,6 +99,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testNoEmergencyOnlyWrongSubscription() {
         setupDefaultSignal();
         setDefaultSubId(42);
@@ -103,6 +108,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testNoEmengencyNoSubscriptions() {
         setupDefaultSignal();
         setSubscriptions();
@@ -113,12 +119,12 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testNoSimlessIconWithoutMobile() {
         // Turn off mobile network support.
         Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockNetworkScoreManager,
-                mMockTm, mMockWm, mMockSm,
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults, mock(DeviceProvisionedController.class));
@@ -132,6 +138,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testSignalStrength() {
         for (int testStrength = 0;
                 testStrength < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; testStrength++) {
@@ -149,6 +156,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testCdmaSignalStrength() {
         for (int testStrength = 0;
                 testStrength < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; testStrength++) {
@@ -163,6 +171,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testSignalRoaming() {
         for (int testStrength = 0;
                 testStrength < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; testStrength++) {
@@ -177,6 +186,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testCdmaSignalRoaming() {
         for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
                 testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
@@ -192,6 +202,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testQsSignalStrength() {
         for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
                 testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
@@ -205,6 +216,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testCdmaQsSignalStrength() {
         for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
                 testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
@@ -219,6 +231,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testNoBangWithWifi() {
         setupDefaultSignal();
         setConnectivity(mMobileSignalController.mTransportType, false, false);
@@ -230,6 +243,7 @@
     // Some tests of actual NetworkController code, just internals not display stuff
     // TODO: Put this somewhere else, maybe in its own file.
     @Test
+    @Ignore("Flaky")
     public void testHasCorrectMobileControllers() {
         int[] testSubscriptions = new int[] { 1, 5, 3 };
         int notTestSubscription = 0;
@@ -257,6 +271,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testSetCurrentSubscriptions() {
         // We will not add one controller to make sure it gets created.
         int indexToSkipController = 0;
@@ -310,6 +325,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testHistorySize() {
         // Verify valid history size, otherwise it gits printed out the wrong order and whatnot.
         assertEquals(0, SignalController.HISTORY_SIZE & (SignalController.HISTORY_SIZE - 1));
@@ -323,6 +339,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnReceive_stringsUpdatedAction_spn() {
         String expectedMNetworkName = "Test";
         Intent intent = createStringsUpdatedIntent(true /* showSpn */,
@@ -336,6 +353,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnReceive_stringsUpdatedAction_plmn() {
         String expectedMNetworkName = "Test";
 
@@ -350,6 +368,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnReceive_stringsUpdatedAction_bothFalse() {
         Intent intent = createStringsUpdatedIntent(false /* showSpn */,
               "Irrelevant" /* spn */,
@@ -365,6 +384,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnReceive_stringsUpdatedAction_bothTrueAndNull() {
         Intent intent = createStringsUpdatedIntent(true /* showSpn */,
             null /* spn */,
@@ -379,6 +399,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnReceive_stringsUpdatedAction_bothTrueAndNonNull() {
         String spn = "Test1";
         String plmn = "Test2";
@@ -413,6 +434,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnUpdateDataActivity_dataIn() {
         setupDefaultSignal();
 
@@ -427,6 +449,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnUpdateDataActivity_dataOut() {
       setupDefaultSignal();
 
@@ -440,6 +463,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnUpdateDataActivity_dataInOut() {
       setupDefaultSignal();
 
@@ -454,6 +478,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnUpdateDataActivity_dataActivityNone() {
       setupDefaultSignal();
 
@@ -468,6 +493,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testCarrierNetworkChange_carrierNetworkChange() {
       int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
 
@@ -496,6 +522,81 @@
               DEFAULT_ICON /* typeIcon */);
     }
 
+    @Test
+    @Ignore("Flaky")
+    public void testCarrierNetworkChange_roamingBeforeNetworkChange() {
+      int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
+
+      setupDefaultSignal();
+      setLevel(strength);
+      setGsmRoaming(true);
+
+      // Verify baseline
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              true /* roaming */);
+
+      // API call is made
+      setCarrierNetworkChange(true /* enabled */);
+
+      // Carrier network change is true, show special indicator, no roaming.
+      verifyLastMobileDataIndicators(true /* visible */,
+              SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+              0 /* typeIcon */,
+              false /* roaming */);
+
+      // Revert back
+      setCarrierNetworkChange(false /* enabled */);
+
+      // Verify back in previous state
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              true /* roaming */);
+    }
+
+    @Test
+    @Ignore("Flaky")
+    public void testCarrierNetworkChange_roamingAfterNetworkChange() {
+      int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
+
+      setupDefaultSignal();
+      setLevel(strength);
+
+      // Verify baseline
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              false /* roaming */);
+
+      // API call is made
+      setCarrierNetworkChange(true /* enabled */);
+
+      // Carrier network change is true, show special indicator, no roaming.
+      verifyLastMobileDataIndicators(true /* visible */,
+              SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+              0 /* typeIcon */,
+              false /* roaming */);
+
+      setGsmRoaming(true);
+
+      // Roaming should not show.
+      verifyLastMobileDataIndicators(true /* visible */,
+              SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+              0 /* typeIcon */,
+              false /* roaming */);
+
+      // Revert back
+      setCarrierNetworkChange(false /* enabled */);
+
+      // Verify back in previous state
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              true /* roaming */);
+    }
+
     private void verifyEmergencyOnly(boolean isEmergencyOnly) {
         ArgumentCaptor<Boolean> emergencyOnly = ArgumentCaptor.forClass(Boolean.class);
         Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setEmergencyCallsOnly(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
index dbaa2c5..ffd01651 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -1,47 +1,24 @@
 package com.android.systemui.statusbar.policy;
 
 import android.content.Intent;
-import android.net.NetworkBadging;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
-import android.net.NetworkKey;
-import android.net.RssiCurve;
-import android.net.ScoredNetwork;
-import android.net.WifiKey;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
-import android.net.wifi.WifiNetworkScoreCache;
-import android.os.Bundle;
-import android.provider.Settings;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.settingslib.Utils;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.Matchers;
 import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
 
 import static junit.framework.Assert.assertEquals;
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -50,13 +27,6 @@
     private static final int MIN_RSSI = -100;
     private static final int MAX_RSSI = -55;
 
-    private static final int LATCH_TIMEOUT = 2000;
-    private static final String TEST_SSID = "\"Test SSID\"";
-    private static final String TEST_BSSID = "00:00:00:00:00:00";
-
-    private final List<NetworkKey> mRequestedKeys = new ArrayList<>();
-    private CountDownLatch mRequestScoresLatch;
-
     @Test
     public void testWifiIcon() {
         String testSsid = "Test SSID";
@@ -77,79 +47,6 @@
     }
 
     @Test
-    public void testBadgedWifiIcon() throws Exception {
-        // TODO(sghuman): Refactor this setup code when creating a test for the badged QsIcon.
-        int testLevel = 1;
-        RssiCurve mockBadgeCurve = mock(RssiCurve.class);
-        Bundle attr = new Bundle();
-        attr.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve);
-        ScoredNetwork score =
-                new ScoredNetwork(
-                        new NetworkKey(new WifiKey(TEST_SSID, TEST_BSSID)),
-                        null,
-                        false /* meteredHint */,
-                        attr);
-
-        // Must set the Settings value before instantiating the NetworkControllerImpl due to bugs in
-        // TestableSettingsProvider.
-        Settings.Global.putString(mContext.getContentResolver(),
-                Settings.Global.NETWORK_SCORING_UI_ENABLED,
-                "1");
-        super.setUp(); // re-instantiate NetworkControllImpl now that setting has been updated
-        setupNetworkScoreManager();
-
-        // Test Requesting Scores
-        mRequestScoresLatch = new CountDownLatch(1);
-        setWifiEnabled(true);
-        setWifiState(true, TEST_SSID, TEST_BSSID);
-        mRequestScoresLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
-
-        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) NetworkBadging.BADGING_SD);
-
-        ArgumentCaptor<WifiNetworkScoreCache> scoreCacheCaptor =
-                ArgumentCaptor.forClass(WifiNetworkScoreCache.class);
-        verify(mMockNetworkScoreManager).registerNetworkScoreCache(
-                anyInt(),
-                scoreCacheCaptor.capture(),
-                Matchers.anyInt());
-        scoreCacheCaptor.getValue().updateScores(Arrays.asList(score));
-
-        //  Test badge is set
-        setWifiLevel(testLevel);
-
-        ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
-        Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
-                anyBoolean(), iconArg.capture(), any(), anyBoolean(), anyBoolean(),
-                any(), anyBoolean());
-        IconState iconState = iconArg.getValue();
-
-        assertEquals("Badged Wifi Resource is set",
-                Utils.WIFI_PIE_FOR_BADGING[testLevel],
-                iconState.icon);
-        assertEquals("SD Badge is set",
-                Utils.getWifiBadgeResource(NetworkBadging.BADGING_SD),
-                iconState.iconOverlay);
-    }
-
-    private void setupNetworkScoreManager() {
-        // Capture requested keys and count down latch if present
-        doAnswer(
-                new Answer<Boolean>() {
-                    @Override
-                    public Boolean answer(InvocationOnMock input) {
-                        if (mRequestScoresLatch != null) {
-                            mRequestScoresLatch.countDown();
-                        }
-                        NetworkKey[] keys = (NetworkKey[]) input.getArguments()[0];
-                        for (NetworkKey key : keys) {
-                            mRequestedKeys.add(key);
-                        }
-                        return true;
-                    }
-                }).when(mMockNetworkScoreManager).requestScores(Matchers.<NetworkKey[]>any());
-    }
-
-    @Test
     public void testQsWifiIcon() {
         String testSsid = "Test SSID";
 
@@ -200,7 +97,7 @@
     @Test
     public void testRoamingIconDuringWifi() {
         // Setup normal connection
-        String testSsid = "\"Test SSID\"";
+        String testSsid = "Test SSID";
         int testLevel = 2;
         setWifiEnabled(true);
         setWifiState(true, testSsid);
@@ -241,19 +138,12 @@
     }
 
     protected void setWifiState(boolean connected, String ssid) {
-        setWifiState(connected, ssid, null);
-    }
-
-    protected void setWifiState(boolean connected, String ssid, String bssid) {
         Intent i = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
         NetworkInfo networkInfo = Mockito.mock(NetworkInfo.class);
         Mockito.when(networkInfo.isConnected()).thenReturn(connected);
 
         WifiInfo wifiInfo = Mockito.mock(WifiInfo.class);
         Mockito.when(wifiInfo.getSSID()).thenReturn(ssid);
-        if (bssid != null) {
-            Mockito.when(wifiInfo.getBSSID()).thenReturn(bssid);
-        }
 
         i.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
         i.putExtra(WifiManager.EXTRA_WIFI_INFO, wifiInfo);
@@ -278,7 +168,7 @@
 
         Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
                 enabledArg.capture(), any(), iconArg.capture(), anyBoolean(),
-                anyBoolean(),  descArg.capture(), anyBoolean());
+                anyBoolean(), descArg.capture(), anyBoolean());
         IconState iconState = iconArg.getValue();
         assertEquals("WiFi enabled, in quick settings", enabled, (boolean) enabledArg.getValue());
         assertEquals("WiFi connected, in quick settings", connected, iconState.visible);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
index ae0509a..7ca9d73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.doThrow;
@@ -29,7 +30,9 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.StringParceledListSlice;
+import android.content.pm.UserInfo;
 import android.net.ConnectivityManager;
+import android.os.UserManager;
 import android.security.IKeyChainService;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -55,6 +58,7 @@
 public class SecurityControllerTest extends SysuiTestCase implements SecurityControllerCallback {
     private final DevicePolicyManager mDevicePolicyManager = mock(DevicePolicyManager.class);
     private final IKeyChainService.Stub mKeyChainService = mock(IKeyChainService.Stub.class);
+    private final UserManager mUserManager = mock(UserManager.class);
     private SecurityControllerImpl mSecurityController;
     private CountDownLatch mStateChangedLatch;
 
@@ -67,12 +71,15 @@
     @Before
     public void setUp() throws Exception {
         mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
+        mContext.addMockSystemService(Context.USER_SERVICE, mUserManager);
         mContext.addMockSystemService(Context.CONNECTIVITY_SERVICE, mock(ConnectivityManager.class));
 
         Intent intent = new Intent(IKeyChainService.class.getName());
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         mContext.addMockService(comp, mKeyChainService);
 
+        when(mUserManager.getUserInfo(anyInt())).thenReturn(new UserInfo());
+
         when(mKeyChainService.getUserCaAliases())
                 .thenReturn(new StringParceledListSlice(new ArrayList<String>()));
         // Without this line, mKeyChainService gets wrapped in a proxy when Stub.asInterface() is
@@ -80,12 +87,10 @@
         when(mKeyChainService.queryLocalInterface("android.security.IKeyChainService"))
                 .thenReturn(mKeyChainService);
 
-        mSecurityController = new SecurityControllerImpl(mContext);
-
-        // Wait for one or two state changes from the CACertLoader(s) in the constructor of
-        // mSecurityController
-        mStateChangedLatch = new CountDownLatch(mSecurityController.hasWorkProfile() ? 2 : 1);
-        mSecurityController.addCallback(this);
+        // Wait for callbacks from 1) the CACertLoader and 2) the onUserSwitched() function in the
+        // constructor of mSecurityController
+        mStateChangedLatch = new CountDownLatch(2);
+        mSecurityController = new SecurityControllerImpl(mContext, this);
     }
 
     @After
@@ -109,13 +114,40 @@
     }
 
     @Test
-    @Ignore("Flaky")
-    public void testCaCertLoader() throws Exception {
+    public void testWorkAccount() throws Exception {
+        // Wait for the callbacks from setUp()
+        assertTrue(mStateChangedLatch.await(1, TimeUnit.SECONDS));
+        assertFalse(mSecurityController.hasCACertInCurrentUser());
+
+        final int PRIMARY_USER_ID = 0;
+        final int MANAGED_USER_ID = 1;
+        List<UserInfo> profiles = Arrays.asList(new UserInfo(PRIMARY_USER_ID, "Primary",
+                                                             UserInfo.FLAG_PRIMARY),
+                                                new UserInfo(MANAGED_USER_ID, "Working",
+                                                             UserInfo.FLAG_MANAGED_PROFILE));
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+        assertTrue(mSecurityController.hasWorkProfile());
+        assertFalse(mSecurityController.hasCACertInWorkProfile());
+
+        mStateChangedLatch = new CountDownLatch(1);
+
+        when(mKeyChainService.getUserCaAliases())
+                .thenReturn(new StringParceledListSlice(Arrays.asList("One CA Alias")));
+
+        mSecurityController.new CACertLoader()
+                           .execute(MANAGED_USER_ID);
+
         assertTrue(mStateChangedLatch.await(3, TimeUnit.SECONDS));
+        assertTrue(mSecurityController.hasCACertInWorkProfile());
+    }
+
+    @Test
+    public void testCaCertLoader() throws Exception {
+        // Wait for the callbacks from setUp()
+        assertTrue(mStateChangedLatch.await(1, TimeUnit.SECONDS));
         assertFalse(mSecurityController.hasCACertInCurrentUser());
 
         // With a CA cert
-
         mStateChangedLatch = new CountDownLatch(1);
 
         when(mKeyChainService.getUserCaAliases())
@@ -138,7 +170,7 @@
         mSecurityController.new CACertLoader()
                            .execute(0);
 
-        assertFalse(mStateChangedLatch.await(3, TimeUnit.SECONDS));
+        assertFalse(mStateChangedLatch.await(1, TimeUnit.SECONDS));
         assertTrue(mSecurityController.hasCACertInCurrentUser());
         // The retry takes 30s
         //assertTrue(mStateChangedLatch.await(31, TimeUnit.SECONDS));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
index 2dd96b6..5ac965c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
@@ -16,10 +16,6 @@
 
 package com.android.systemui.statusbar.stack;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.NotificationHeaderView;
@@ -31,7 +27,6 @@
 
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java b/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java
new file mode 100644
index 0000000..9fd8cc3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.tuner;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
+
+import android.support.test.filters.SmallTest;
+import android.testing.LeakCheck.Tracker;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.systemui.utils.leaks.LeakCheckedTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+@SmallTest
+public class TunablePaddingTest extends LeakCheckedTest {
+
+    private static final String KEY = "KEY";
+    private static final int DEFAULT = 42;
+    private View mView;
+    private TunablePadding mTunablePadding;
+    private TunerService mTunerService;
+
+    @Before
+    public void setup() {
+        injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
+        mView = mock(View.class, withSettings().spiedInstance(new View(mContext)));
+
+        mTunerService = mDependency.injectMockDependency(TunerService.class);
+        Tracker tracker = mLeakCheck.getTracker("tuner");
+        doAnswer(invocation -> {
+            tracker.getLeakInfo(invocation.getArguments()[0]).addAllocation(new Throwable());
+            return null;
+        }).when(mTunerService).addTunable(any(), any());
+        doAnswer(invocation -> {
+            tracker.getLeakInfo(invocation.getArguments()[0]).clearAllocations();
+            return null;
+        }).when(mTunerService).removeTunable(any());
+    }
+
+    @Test
+    public void testFlags() {
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_START);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(DEFAULT), eq(0), eq(0), eq(0));
+        mTunablePadding.destroy();
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_TOP);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(0), eq(DEFAULT), eq(0), eq(0));
+        mTunablePadding.destroy();
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_END);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(0), eq(0), eq(DEFAULT), eq(0));
+        mTunablePadding.destroy();
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_BOTTOM);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(0), eq(0), eq(0), eq(DEFAULT));
+        mTunablePadding.destroy();
+    }
+
+    @Test
+    public void testRtl() {
+        when(mView.isLayoutRtl()).thenReturn(true);
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_END);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(DEFAULT), eq(0), eq(0), eq(0));
+        mTunablePadding.destroy();
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_START);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(0), eq(0), eq(DEFAULT), eq(0));
+        mTunablePadding.destroy();
+    }
+
+    @Test
+    public void testTuning() {
+        int value = 3;
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_START);
+        mTunablePadding.onTuningChanged(KEY, String.valueOf(value));
+
+        DisplayMetrics metrics = new DisplayMetrics();
+        mContext.getSystemService(WindowManager.class).getDefaultDisplay().getMetrics(metrics);
+        int output = (int) (metrics.density * value);
+        verify(mView).setPadding(eq(output), eq(0), eq(0), eq(0));
+
+        mTunablePadding.destroy();
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/AsyncSensorManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/AsyncSensorManagerTest.java
new file mode 100644
index 0000000..469bdc0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/AsyncSensorManagerTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.util;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.utils.hardware.FakeSensorManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class AsyncSensorManagerTest extends SysuiTestCase {
+
+    private TestableAsyncSensorManager mAsyncSensorManager;
+    private FakeSensorManager mFakeSensorManager;
+    private SensorEventListener mListener;
+    private FakeSensorManager.MockProximitySensor mSensor;
+
+    @Before
+    public void setUp() throws Exception {
+        mFakeSensorManager = new FakeSensorManager(mContext);
+        mAsyncSensorManager = new TestableAsyncSensorManager(mFakeSensorManager);
+        mSensor = mFakeSensorManager.getMockProximitySensor();
+        mListener = mock(SensorEventListener.class);
+    }
+
+    @Test
+    public void registerListenerImpl() throws Exception {
+        mAsyncSensorManager.registerListener(mListener, mSensor.getSensor(), 100);
+
+        mAsyncSensorManager.waitUntilRequestsCompleted();
+
+        // Verify listener was registered.
+        mSensor.sendProximityResult(true);
+        verify(mListener).onSensorChanged(any());
+    }
+
+    @Test
+    public void unregisterListenerImpl_withNullSensor() throws Exception {
+        mAsyncSensorManager.registerListener(mListener, mSensor.getSensor(), 100);
+        mAsyncSensorManager.unregisterListener(mListener);
+
+        mAsyncSensorManager.waitUntilRequestsCompleted();
+
+        // Verify listener was unregistered.
+        mSensor.sendProximityResult(true);
+        verifyNoMoreInteractions(mListener);
+    }
+
+    @Test
+    public void unregisterListenerImpl_withSensor() throws Exception {
+        mAsyncSensorManager.registerListener(mListener, mSensor.getSensor(), 100);
+        mAsyncSensorManager.unregisterListener(mListener, mSensor.getSensor());
+
+        mAsyncSensorManager.waitUntilRequestsCompleted();
+
+        // Verify listener was unregistered.
+        mSensor.sendProximityResult(true);
+        verifyNoMoreInteractions(mListener);
+    }
+
+    private class TestableAsyncSensorManager extends AsyncSensorManager {
+        public TestableAsyncSensorManager(SensorManager sensorManager) {
+            super(sensorManager);
+        }
+
+        public void waitUntilRequestsCompleted() {
+            assertTrue(mHandler.runWithScissors(() -> {}, 0));
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java b/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
index 30be665..a4ae166 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
@@ -30,13 +30,15 @@
 import android.os.SystemClock;
 import android.util.ArraySet;
 
-import com.google.android.collect.Lists;
+import com.android.internal.util.Preconditions;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * Rudimentary fake for SensorManager
@@ -49,6 +51,8 @@
 public class FakeSensorManager extends SensorManager {
 
     private final MockProximitySensor mMockProximitySensor;
+    private final FakeGenericSensor mFakeLightSensor;
+    private final FakeGenericSensor[] mSensors;
 
     public FakeSensorManager(Context context) throws Exception {
         Sensor proxSensor = context.getSystemService(SensorManager.class)
@@ -57,13 +61,21 @@
             // No prox? Let's create a fake one!
             proxSensor = createSensor(Sensor.TYPE_PROXIMITY);
         }
-        mMockProximitySensor = new MockProximitySensor(proxSensor);
+
+        mSensors = new FakeGenericSensor[]{
+                mMockProximitySensor = new MockProximitySensor(proxSensor),
+                mFakeLightSensor = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT)),
+        };
     }
 
     public MockProximitySensor getMockProximitySensor() {
         return mMockProximitySensor;
     }
 
+    public FakeGenericSensor getFakeLightSensor() {
+        return mFakeLightSensor;
+    }
+
     @Override
     public Sensor getDefaultSensor(int type) {
         Sensor s = super.getDefaultSensor(type);
@@ -77,7 +89,10 @@
 
     @Override
     protected List<Sensor> getFullSensorList() {
-        return Lists.newArrayList(mMockProximitySensor.sensor);
+        return Arrays
+                .stream(mSensors)
+                .map(i -> i.mSensor)
+                .collect(Collectors.toList());
     }
 
     @Override
@@ -87,8 +102,11 @@
 
     @Override
     protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
-        if (sensor == mMockProximitySensor.sensor || sensor == null) {
-            mMockProximitySensor.listeners.remove(listener);
+        Preconditions.checkNotNull(listener);
+        for (FakeGenericSensor s : mSensors) {
+            if (sensor == null || s.mSensor == sensor) {
+                s.mListeners.remove(listener);
+            }
         }
     }
 
@@ -96,9 +114,13 @@
     protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
             int delayUs,
             Handler handler, int maxReportLatencyUs, int reservedFlags) {
-        if (sensor == mMockProximitySensor.sensor) {
-            mMockProximitySensor.listeners.add(listener);
-            return true;
+        Preconditions.checkNotNull(sensor);
+        Preconditions.checkNotNull(listener);
+        for (FakeGenericSensor s : mSensors) {
+            if (s.mSensor == sensor) {
+                s.mListeners.add(listener);
+                return true;
+            }
         }
         return false;
     }
@@ -196,18 +218,35 @@
         setter.invoke(sensor, type);
     }
 
-    public class MockProximitySensor {
-        final Sensor sensor;
-        final ArraySet<SensorEventListener> listeners = new ArraySet<>();
+    public class MockProximitySensor extends FakeGenericSensor {
 
         private MockProximitySensor(Sensor sensor) {
-            this.sensor = sensor;
+            super(sensor);
         }
 
         public void sendProximityResult(boolean far) {
-            SensorEvent event = createSensorEvent(1);
-            event.values[0] = far ? sensor.getMaximumRange() : 0;
-            for (SensorEventListener listener : listeners) {
+            sendSensorEvent(far ? getSensor().getMaximumRange() : 0);
+        }
+    }
+
+    public class FakeGenericSensor {
+
+        private final Sensor mSensor;
+        private final ArraySet<SensorEventListener> mListeners = new ArraySet<>();
+
+        public FakeGenericSensor(
+                Sensor sensor) {
+            this.mSensor = sensor;
+        }
+
+        public Sensor getSensor() {
+            return mSensor;
+        }
+
+        public void sendSensorEvent(float... values) {
+            SensorEvent event = createSensorEvent(values.length);
+            System.arraycopy(values, 0, event.values, 0, values.length);
+            for (SensorEventListener listener : mListeners) {
                 listener.onSensorChanged(event);
             }
         }
@@ -222,7 +261,7 @@
             } catch (Exception e) {
                 throw new RuntimeException(e);
             }
-            event.sensor = sensor;
+            event.sensor = mSensor;
             event.timestamp = SystemClock.elapsedRealtimeNanos();
 
             return event;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java
new file mode 100644
index 0000000..9ef30c3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.utils.leaks;
+
+import com.android.systemui.statusbar.policy.ConfigurationController;
+
+public class FakeConfigurationController
+        extends BaseLeakChecker<ConfigurationController.ConfigurationListener>
+        implements ConfigurationController {
+
+    public FakeConfigurationController(LeakCheckedTest.SysuiLeakCheck sysuiLeakCheck) {
+        super(sysuiLeakCheck, "config");
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeExtensionController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeExtensionController.java
index 00846dc..586a424 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeExtensionController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeExtensionController.java
@@ -14,6 +14,7 @@
 
 package com.android.systemui.utils.leaks;
 
+import android.content.Context;
 import android.testing.LeakCheck;
 import android.testing.LeakCheck.Tracker;
 
@@ -75,6 +76,11 @@
         }
 
         @Override
+        public ExtensionBuilder<T> withUiMode(int mode, Supplier<T> def) {
+            return null;
+        }
+
+        @Override
         public Extension build() {
             return new FakeExtension(mAllocation);
         }
@@ -94,11 +100,24 @@
         }
 
         @Override
+        public void clearItem(boolean isDestroyed) {
+
+        }
+
+        @Override
+        public Context getContext() {
+            return null;
+        }
+
+        @Override
         public void destroy() {
             mTracker.getLeakInfo(mAllocation).clearAllocations();
         }
 
         @Override
+        public void addCallback(Consumer<T> callback) {
+        }
+
         public T reload() {
             return null;
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardMonitor.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardMonitor.java
index 51e35cc..3f952c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardMonitor.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardMonitor.java
@@ -47,6 +47,11 @@
     }
 
     @Override
+    public boolean isOccluded() {
+        return false;
+    }
+
+    @Override
     public boolean isKeyguardFadingAway() {
         return false;
     }
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..d1b1c5b 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,7 +14,6 @@
 
 package com.android.systemui.utils.leaks;
 
-import android.content.Context;
 import android.testing.LeakCheck;
 
 import com.android.systemui.plugins.Plugin;
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 94af7733..ecda9620 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
@@ -26,6 +26,7 @@
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.CastController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.FlashlightController;
 import com.android.systemui.statusbar.policy.HotspotController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
@@ -68,6 +69,7 @@
             PluginManager.class,
             TunerService.class,
             StatusBarIconController.class,
+            ConfigurationController.class,
     };
 
     @Rule
@@ -134,6 +136,8 @@
                     obj = new FakeTunerService(this);
                 } else if (cls == StatusBarIconController.class) {
                     obj = new FakeStatusBarIconController(this);
+                } else if (cls == ConfigurationController.class) {
+                    obj = new FakeConfigurationController(this);
                 } else {
                     Assert.fail(cls.getName() + " is not supported by LeakCheckedTest yet");
                 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
new file mode 100644
index 0000000..06568f7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.volume;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.media.session.MediaSession;
+import android.support.test.filters.SmallTest;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+import org.junit.Before;
+import org.junit.Test;
+
+@SmallTest
+public class VolumeDialogControllerImplTest extends SysuiTestCase {
+
+    TestableVolumeDialogControllerImpl mVolumeController;
+    VolumeDialogControllerImpl.C mCallback;
+    StatusBar mStatusBar;
+
+    @Before
+    public void setup() throws Exception {
+        mCallback = mock(VolumeDialogControllerImpl.C.class);
+        mStatusBar = mock(StatusBar.class);
+        mVolumeController = new TestableVolumeDialogControllerImpl(mContext, mCallback, mStatusBar);
+    }
+
+    @Test
+    public void testVolumeChangeW_deviceNotInteractiveAOD() {
+        when(mStatusBar.isDeviceInteractive()).thenReturn(false);
+        when(mStatusBar.getWakefulnessState()).thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE);
+        mVolumeController.onVolumeChangedW(0, AudioManager.FLAG_SHOW_UI);
+        verify(mCallback, never()).onShowRequested(Events.SHOW_REASON_VOLUME_CHANGED);
+    }
+
+    @Test
+    public void testVolumeChangeW_deviceInteractive() {
+        when(mStatusBar.isDeviceInteractive()).thenReturn(true);
+        when(mStatusBar.getWakefulnessState()).thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE);
+        mVolumeController.onVolumeChangedW(0, AudioManager.FLAG_SHOW_UI);
+        verify(mCallback, times(1)).onShowRequested(Events.SHOW_REASON_VOLUME_CHANGED);
+    }
+
+    @Test
+    public void testVolumeChangeW_deviceInteractive_StartedSleeping() {
+        when(mStatusBar.isDeviceInteractive()).thenReturn(true);
+        when(mStatusBar.getWakefulnessState()).thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE);
+        mVolumeController.onVolumeChangedW(0, AudioManager.FLAG_SHOW_UI);
+        when(mStatusBar.isDeviceInteractive()).thenReturn(false);
+        when(mStatusBar.getWakefulnessState()).thenReturn(WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP);
+        mVolumeController.onVolumeChangedW(0, AudioManager.FLAG_SHOW_UI);
+        verify(mCallback, times(1)).onShowRequested(Events.SHOW_REASON_VOLUME_CHANGED);
+    }
+
+    @Test
+    public void testOnRemoteVolumeChanged_newStream_noNullPointer() {
+        MediaSession.Token token = new MediaSession.Token(null);
+        mVolumeController.mMediaSessionsCallbacksW.onRemoteVolumeChanged(token, 0);
+    }
+
+    @Test
+    public void testOnRemoteRemove_newStream_noNullPointer() {
+        MediaSession.Token token = new MediaSession.Token(null);
+        mVolumeController.mMediaSessionsCallbacksW.onRemoteRemoved(token);
+    }
+
+    static class TestableVolumeDialogControllerImpl extends VolumeDialogControllerImpl {
+        public TestableVolumeDialogControllerImpl(Context context, C callback, StatusBar s) {
+            super(context);
+            mCallbacks = callback;
+            mStatusBar = s;
+        }
+    }
+
+}
diff --git a/packages/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml
index a3d27ce..8172e71 100644
--- a/packages/VpnDialogs/AndroidManifest.xml
+++ b/packages/VpnDialogs/AndroidManifest.xml
@@ -23,9 +23,10 @@
     <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
 
     <application android:label="VpnDialogs"
-            android:allowBackup="false" >
+                 android:allowBackup="false">
+
         <activity android:name=".ConfirmDialog"
-                android:theme="@android:style/Theme.Material.Light.Dialog.Alert">
+                  android:theme="@android:style/Theme.Material.Light.Dialog.Alert">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.intent.category.DEFAULT"/>
@@ -33,12 +34,21 @@
         </activity>
 
         <activity android:name=".ManageDialog"
-                android:theme="@android:style/Theme.Material.Light.Dialog.Alert"
-                android:noHistory="true">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.DEFAULT"/>
-            </intent-filter>
+                  android:theme="@android:style/Theme.Material.Light.Dialog.Alert"
+                  android:noHistory="true"
+                  android:excludeFromRecents="true"
+                  android:permission="android.permission.NETWORK_SETTINGS"
+                  android:exported="true">
         </activity>
+
+        <activity android:name=".AlwaysOnDisconnectedDialog"
+                  android:label="@string/always_on_disconnected_title"
+                  android:theme="@android:style/Theme.Material.Light.Dialog.Alert"
+                  android:noHistory="true"
+                  android:excludeFromRecents="true"
+                  android:permission="android.permission.NETWORK_SETTINGS"
+                  android:exported="true">
+        </activity>
+
     </application>
 </manifest>
diff --git a/packages/VpnDialogs/res/layout/always_on_disconnected.xml b/packages/VpnDialogs/res/layout/always_on_disconnected.xml
new file mode 100644
index 0000000..0f4a46d
--- /dev/null
+++ b/packages/VpnDialogs/res/layout/always_on_disconnected.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:padding="24dp">
+    <TextView android:id="@+id/message"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"/>
+</ScrollView>
diff --git a/packages/VpnDialogs/res/values-af/strings.xml b/packages/VpnDialogs/res/values-af/strings.xml
index 8c5739c..ac82b0e 100644
--- a/packages/VpnDialogs/res/values-af/strings.xml
+++ b/packages/VpnDialogs/res/values-af/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Verbindingversoek"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> wil \'n VPN-verbinding opstel wat dit sal toelaat om netwerkverkeer te monitor. Aanvaar dit net as jy die bron vertrou. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; verskyn boaan jou skerm as VPN aktief is."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN is gekoppel"</string>
-    <string name="configure" msgid="4905518375574791375">"Stel op"</string>
-    <string name="disconnect" msgid="971412338304200056">"Ontkoppel"</string>
     <string name="session" msgid="6470628549473641030">"Sessie:"</string>
     <string name="duration" msgid="3584782459928719435">"Tydsduur:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Gestuur:"</string>
     <string name="data_received" msgid="4062776929376067820">"Ontvang:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> grepe/<xliff:g id="NUMBER_1">%2$s</xliff:g> pakkies"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Kan nie aan altyd-aan-VPN koppel nie"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> is opgestel om ten alle tye gekoppel te bly, maar dit kan nie nou onmiddellik koppel nie. Jou foon sal \'n publieke netwerk gebruik totdat dit weer aan <xliff:g id="VPN_APP_1">%1$s</xliff:g> kan koppel."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> is opgestel om ten alle tye gekoppel te bly, maar dit kan nie nou onmiddellik koppel nie. Jy sal nie \'n verbinding hê totdat die VPN weer kan koppel nie."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Verander VPN-instellings"</string>
+    <string name="configure" msgid="4905518375574791375">"Stel op"</string>
+    <string name="disconnect" msgid="971412338304200056">"Ontkoppel"</string>
+    <string name="open_app" msgid="3717639178595958667">"Maak program oop"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Maak toe"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-am/strings.xml b/packages/VpnDialogs/res/values-am/strings.xml
index e6fc112..103f101 100644
--- a/packages/VpnDialogs/res/values-am/strings.xml
+++ b/packages/VpnDialogs/res/values-am/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"የግንኙነት ጥያቄ"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> የአውታረ መረብ መከታተል የሚያስችል የVPN ግንኑነት ማዋቀር ይፈልጋል። ምንጩን የሚያምኑት ብቻ ከሆኑ ይቀበሉ። &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; VPN ገቢር ሲሆን በማያ ገጽዎ ላይኛው ክፍል ላይ ይታያል።"</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN ተያይዟል"</string>
-    <string name="configure" msgid="4905518375574791375">"አዋቅር"</string>
-    <string name="disconnect" msgid="971412338304200056">"አለያይ"</string>
     <string name="session" msgid="6470628549473641030">"ክፍለ ጊዜ፡"</string>
     <string name="duration" msgid="3584782459928719435">"ጊዜ"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"ተልኳል ለ:"</string>
     <string name="data_received" msgid="4062776929376067820">"ተቀብሏል፡"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ባይትስ / <xliff:g id="NUMBER_1">%2$s</xliff:g> ፓኬቶች"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"ሁልጊዜ ከበራ ቪፒኤን ጋር መገናኘት አልተቻለም"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> ሁልጊዜ እንዲገናኝ የተዋቀረ ነው፣ ነገር ግን አሁን መገናኘት አይችልም። የእርስዎ ስልክ ከ<xliff:g id="VPN_APP_1">%1$s</xliff:g> ጋር ዳግም እስኪገናኝ ድረስ ይፋዊ አውታረ መረብ ይጠቀማል።"</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> ሁልጊዜ እንዲገናኝ የተዋቀረ ነው፣ ነገር ግን አሁን መገናኘት አይችልም። ቪፒኤኑ ዳግም መገናኘት እስኪችል ድረስ ግንኙነት አይኖረዎትም።"</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"የቪፒኤን ቅንብሮችን ይቀይሩ"</string>
+    <string name="configure" msgid="4905518375574791375">"አዋቅር"</string>
+    <string name="disconnect" msgid="971412338304200056">"አለያይ"</string>
+    <string name="open_app" msgid="3717639178595958667">"መተግበሪያን ክፈት"</string>
+    <string name="dismiss" msgid="6192859333764711227">"አሰናብት"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ar/strings.xml b/packages/VpnDialogs/res/values-ar/strings.xml
index e36eef4..808cde9 100644
--- a/packages/VpnDialogs/res/values-ar/strings.xml
+++ b/packages/VpnDialogs/res/values-ar/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"طلب الاتصال"</string>
     <string name="warning" msgid="809658604548412033">"‏يريد <xliff:g id="APP">%s</xliff:g> إعداد الاتصال بالشبكة الافتراضية الخاصة التي تتيح له مراقبة حركة المرور على الشبكة. فلا توافق إلا إذا كنت تثق في المصدر. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; يظهر في الجزء العلوي من الشاشة عندما تكون الشبكة الافتراضية الخاصة نشطة."</string>
     <string name="legacy_title" msgid="192936250066580964">"‏VPN متصلة"</string>
-    <string name="configure" msgid="4905518375574791375">"تهيئة"</string>
-    <string name="disconnect" msgid="971412338304200056">"قطع الاتصال"</string>
     <string name="session" msgid="6470628549473641030">"الجلسة"</string>
     <string name="duration" msgid="3584782459928719435">"المدة:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"مرسل:"</string>
     <string name="data_received" msgid="4062776929376067820">"تم الاستلام:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> بايت / <xliff:g id="NUMBER_1">%2$s</xliff:g> من الحزم"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"‏يتعذّر الاتصال بشبكة VPN التي يتم تشغيلها دائمًا"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"تم إعداد شبكة <xliff:g id="VPN_APP_0">%1$s</xliff:g> بحيث تبقى متصلة بالإنترنت دائمًا، ومع ذلك يتعذّر اتصالها بالإنترنت الآن. سيستخدم هاتفك شبكة عامة إلى أن يتمكّن من إعادة الاتصال بشبكة <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"‏تم إعداد شبكة <xliff:g id="VPN_APP">%1$s</xliff:g> بحيث تبقى متصلة بالإنترنت دائمًا، ومع ذلك يتعذّر اتصالها بالإنترنت الآن. لن تتوفر لديك إمكانية اتصال إلى أن تتمكّن الشبكة الافتراضية الخاصة (VPN) من إعادة الاتصال."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"‏تغيير إعدادات الشبكة الافتراضية الخاصة (VPN)"</string>
+    <string name="configure" msgid="4905518375574791375">"تهيئة"</string>
+    <string name="disconnect" msgid="971412338304200056">"قطع الاتصال"</string>
+    <string name="open_app" msgid="3717639178595958667">"فتح التطبيق"</string>
+    <string name="dismiss" msgid="6192859333764711227">"تجاهل"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-az/strings.xml b/packages/VpnDialogs/res/values-az/strings.xml
index c568e94..2bdf23e 100644
--- a/packages/VpnDialogs/res/values-az/strings.xml
+++ b/packages/VpnDialogs/res/values-az/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Bağlantı Sorğusu"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> VPN bağlantı yaratmaq istəyir ki, bu da şəbəkə trafikini izləyə bilər. Yalnız mənbəyə güvəndiyiniz halda qəbul edin. VPN aktiv olan zaman &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; ekranın yuxarısında görünür."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN qoşuludur"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfiqurasiya edin"</string>
-    <string name="disconnect" msgid="971412338304200056">"Əlaqəni kəs"</string>
     <string name="session" msgid="6470628549473641030">"Sessiya:"</string>
     <string name="duration" msgid="3584782459928719435">"Müddət:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Göndərilən:"</string>
     <string name="data_received" msgid="4062776929376067820">"Qəbul edilən:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bayt / <xliff:g id="NUMBER_1">%2$s</xliff:g> paket"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Həmişə aktiv VPN-ə qoşulmaq mümkün deyil"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> həmişə aktiv olacaq şəkildə ayarlanıb, lakin hazırda qoşulmaq mümkün deyil. Telefonunuz <xliff:g id="VPN_APP_1">%1$s</xliff:g> şəbəkəsinə qoşulana qədər ictimai şəbəkədən istifadə edəcək."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> həmişə aktiv olacaq şəkildə ayarlanıb, lakin hazırda qoşulmaq mümkün deyil. VPN təkrar qoşuluncaya qədər bağlantınız olmayacaq."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN ayarlarını dəyişin"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfiqurasiya edin"</string>
+    <string name="disconnect" msgid="971412338304200056">"Əlaqəni kəs"</string>
+    <string name="open_app" msgid="3717639178595958667">"Tətbiqi açın"</string>
+    <string name="dismiss" msgid="6192859333764711227">"İmtina edin"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-bg/strings.xml b/packages/VpnDialogs/res/values-bg/strings.xml
index d7b265f..9ac853d 100644
--- a/packages/VpnDialogs/res/values-bg/strings.xml
+++ b/packages/VpnDialogs/res/values-bg/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Заявка за свързване"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> иска да настрои връзка с виртуална частна мрежа (VPN), за да може да наблюдава мрежовия трафик. Приемете само ако източникът е надежден. Иконата &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; се показва в долната част на екрана при активирана VPN."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN е свързана"</string>
-    <string name="configure" msgid="4905518375574791375">"Конфигуриране"</string>
-    <string name="disconnect" msgid="971412338304200056">"Изключване"</string>
     <string name="session" msgid="6470628549473641030">"Сесия:"</string>
     <string name="duration" msgid="3584782459928719435">"Продължителност:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Изпратено:"</string>
     <string name="data_received" msgid="4062776929376067820">"Получено:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> байта/ <xliff:g id="NUMBER_1">%2$s</xliff:g> пакета"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Няма връзка с винаги включената VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Приложението <xliff:g id="VPN_APP_0">%1$s</xliff:g> е настроено за непрекъсната връзка, но в момента не може да се свърже. Телефонът ви ще използва обществена мрежа, докато връзката му с/ъс <xliff:g id="VPN_APP_1">%1$s</xliff:g> не бъде възстановена."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Приложението <xliff:g id="VPN_APP">%1$s</xliff:g> е настроено за непрекъсната връзка, но в момента не може да се свърже. Няма да имате достъп до интернет, докато връзката с VPN не бъде възстановена."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Промяна на настройките за VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Конфигуриране"</string>
+    <string name="disconnect" msgid="971412338304200056">"Изключване"</string>
+    <string name="open_app" msgid="3717639178595958667">"Към приложението"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Отхвърляне"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-bn/strings.xml b/packages/VpnDialogs/res/values-bn/strings.xml
index 90ce36e..2defd81 100644
--- a/packages/VpnDialogs/res/values-bn/strings.xml
+++ b/packages/VpnDialogs/res/values-bn/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"সংযোগের অনুরোধ"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> এমন একটি VPN সংযোগ সেট আপ করতে চাচ্ছে যেটি দিয়ে এটি নেটওয়ার্ক ট্রাফিক নিরীক্ষণ করতে পারবে। আপনি যদি উৎসটিকে বিশ্বাস করেন, তাহলেই কেবল এতে সম্মতি দিন। VPN সক্রিয় থাকলে আপনার স্ক্রীনের উপরে &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; দেখা যাবে।"</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN সংযুক্ত হয়েছে"</string>
-    <string name="configure" msgid="4905518375574791375">"কনফিগার করুন"</string>
-    <string name="disconnect" msgid="971412338304200056">"সংযোগ বিচ্ছিন্ন করুন"</string>
     <string name="session" msgid="6470628549473641030">"অধিবেশন:"</string>
     <string name="duration" msgid="3584782459928719435">"সময়কাল:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"পাঠানো হয়েছে:"</string>
     <string name="data_received" msgid="4062776929376067820">"গৃহিত ডেটার পরিমান:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> বাইট / <xliff:g id="NUMBER_1">%2$s</xliff:g> প্যাকেট"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"সবসময়-চালু VPN এর সাথে সংযোগ করা যাচ্ছে না"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> অ্যাপটি সবসময় সংযুক্ত থাকার জন্যেই সেট-আপ করা হয়েছে, কিন্তু এই মুহূর্তে এটি সংযুক্ত করা যাচ্ছে না। <xliff:g id="VPN_APP_1">%1$s</xliff:g> এ আবার সংযোগ না হওয়া পর্যন্ত আপনার ফোনে সর্বজনীন নেটওয়ার্ক ব্যবহার করা হবে।"</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> সবসময় সংযুক্ত থাকার জন্যেই সেট-আপ করা হয়েছে, কিন্তু এই মুহূর্তে এটি সংযুক্ত করা যাচ্ছে না। VPN সংযোগ আবার চালু না হওয়া পর্যন্ত আপনার ফোনে কোনও সংযোগ থাকবে না।"</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN সেটিংস পরিবর্তন করুন"</string>
+    <string name="configure" msgid="4905518375574791375">"কনফিগার করুন"</string>
+    <string name="disconnect" msgid="971412338304200056">"সংযোগ বিচ্ছিন্ন করুন"</string>
+    <string name="open_app" msgid="3717639178595958667">"অ্যাপটি খুলুন"</string>
+    <string name="dismiss" msgid="6192859333764711227">"খারিজ করুন"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ca/strings.xml b/packages/VpnDialogs/res/values-ca/strings.xml
index ab6b50a..97738c3 100644
--- a/packages/VpnDialogs/res/values-ca/strings.xml
+++ b/packages/VpnDialogs/res/values-ca/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Sol·licitud de connexió"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> vol configurar una connexió VPN que li permeti controlar el trànsit de xarxa. Accepta la sol·licitud només si prové d\'una font de confiança. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; es mostra a la part superior de la pantalla quan la VPN està activada."</string>
     <string name="legacy_title" msgid="192936250066580964">"La VPN està connectada"</string>
-    <string name="configure" msgid="4905518375574791375">"Configura"</string>
-    <string name="disconnect" msgid="971412338304200056">"Desconnecta"</string>
     <string name="session" msgid="6470628549473641030">"Sessió:"</string>
     <string name="duration" msgid="3584782459928719435">"Durada:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Enviat:"</string>
     <string name="data_received" msgid="4062776929376067820">"Rebut:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes/<xliff:g id="NUMBER_1">%2$s</xliff:g> paquets"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"No s\'ha pogut establir la connexió a la VPN sempre activada"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"S\'ha configurat <xliff:g id="VPN_APP_0">%1$s</xliff:g> perquè sempre tingui connexió, però ara mateix no es pot connectar. El telèfon utilitzarà una xarxa pública fins que no es pugui tornar a connectar a <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"S\'ha configurat <xliff:g id="VPN_APP">%1$s</xliff:g> perquè sempre tingui connexió, però ara mateix no es pot connectar. No tindràs connexió fins que no es pugui tornar a establir la connexió amb la VPN."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Canvia la configuració de la VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Configura"</string>
+    <string name="disconnect" msgid="971412338304200056">"Desconnecta"</string>
+    <string name="open_app" msgid="3717639178595958667">"Obre l\'aplicació"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Ignora"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-cs/strings.xml b/packages/VpnDialogs/res/values-cs/strings.xml
index 4f830fb..47d950f 100644
--- a/packages/VpnDialogs/res/values-cs/strings.xml
+++ b/packages/VpnDialogs/res/values-cs/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Žádost o připojení"</string>
     <string name="warning" msgid="809658604548412033">"Aplikace <xliff:g id="APP">%s</xliff:g> žádá o nastavení připojení VPN, pomocí kterého bude moci sledovat síťový provoz. Povolte, jen pokud zdroji důvěřujete. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; – když je síť VPN aktivní, v horní části obrazovky se zobrazuje tato ikona."</string>
     <string name="legacy_title" msgid="192936250066580964">"Síť VPN je připojena"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfigurovat"</string>
-    <string name="disconnect" msgid="971412338304200056">"Odpojit"</string>
     <string name="session" msgid="6470628549473641030">"Relace:"</string>
     <string name="duration" msgid="3584782459928719435">"Doba trvání:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Odesláno:"</string>
     <string name="data_received" msgid="4062776929376067820">"Přijato:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bajtů / <xliff:g id="NUMBER_1">%2$s</xliff:g> paketů"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Nelze se připojit k trvalé VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Aplikace <xliff:g id="VPN_APP_0">%1$s</xliff:g> je nastavena k trvalému připojení, ale nyní se nemůže připojit. Než se telefon bude moci připojit pomocí aplikace <xliff:g id="VPN_APP_1">%1$s</xliff:g>, použije veřejnou síť."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Aplikace <xliff:g id="VPN_APP">%1$s</xliff:g> je nastavena k trvalému připojení, ale nyní se nemůže připojit. Než se budete moci připojit pomocí VPN, zůstanete offline."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Změnit nastavení VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfigurovat"</string>
+    <string name="disconnect" msgid="971412338304200056">"Odpojit"</string>
+    <string name="open_app" msgid="3717639178595958667">"Do aplikace"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Zavřít"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-da/strings.xml b/packages/VpnDialogs/res/values-da/strings.xml
index 804982d..7641158 100644
--- a/packages/VpnDialogs/res/values-da/strings.xml
+++ b/packages/VpnDialogs/res/values-da/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Forbindelsesanmodning"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> vil konfigurere en VPN-forbindelse, der giver appen mulighed for at registrere netværkstrafik. Du bør kun acceptere dette, hvis du har tillid til kilden. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; vises øverst på din skærm, når VPN-forbindelsen er aktiv."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN er tilsluttet"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfigurer"</string>
-    <string name="disconnect" msgid="971412338304200056">"Fjern tilknytning"</string>
     <string name="session" msgid="6470628549473641030">"Session:"</string>
     <string name="duration" msgid="3584782459928719435">"Varighed:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Sendt:"</string>
     <string name="data_received" msgid="4062776929376067820">"Modtaget:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> pakker"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Der kan ikke oprettes forbindelse til konstant VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> er konfigureret til altid at være forbundet, men kan ikke oprette forbindelse lige nu. Din telefon benytter et offentligt netværk, indtil den kan få forbindelse til <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> er konfigureret til altid at være forbundet, men kan ikke oprette forbindelse lige nu. Du har ingen forbindelse, før VPN kan oprette den igen."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Skift VPN-indstillinger"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfigurer"</string>
+    <string name="disconnect" msgid="971412338304200056">"Fjern tilknytning"</string>
+    <string name="open_app" msgid="3717639178595958667">"Åbn app"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Luk"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-de/strings.xml b/packages/VpnDialogs/res/values-de/strings.xml
index 27b0196..b1cebf84 100644
--- a/packages/VpnDialogs/res/values-de/strings.xml
+++ b/packages/VpnDialogs/res/values-de/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Verbindungsanfrage"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> möchte eine VPN-Verbindung herstellen, über die der Netzwerkverkehr überwacht werden kann. Lasse die Verbindung nur zu, wenn die App vertrauenswürdig ist. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; wird oben am Display angezeigt, wenn VPN aktiv ist."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN ist verbunden"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfigurieren"</string>
-    <string name="disconnect" msgid="971412338304200056">"Verbindung trennen"</string>
     <string name="session" msgid="6470628549473641030">"Sitzung:"</string>
     <string name="duration" msgid="3584782459928719435">"Dauer:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Gesendet:"</string>
     <string name="data_received" msgid="4062776929376067820">"Empfangen:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> Byte/<xliff:g id="NUMBER_1">%2$s</xliff:g> Pakete"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Verbindung mit dauerhaft aktivem VPN nicht möglich"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> ist so eingerichtet, dass die Verbindung immer über das VPN geleitet wird, aber momentan kann keine Verbindung hergestellt werden. Bis die Verbindung über <xliff:g id="VPN_APP_1">%1$s</xliff:g> wiederhergestellt werden kann, verwendet dein Smartphone ein öffentliches Netzwerk."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> ist so eingerichtet, dass die Verbindung immer über das VPN geleitet wird, aber momentan kann keine Verbindung hergestellt werden. Solange die VPN-Verbindung nicht wiederhergestellt worden ist, bist du nicht verbunden."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN-Einstellungen ändern"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfigurieren"</string>
+    <string name="disconnect" msgid="971412338304200056">"Verbindung trennen"</string>
+    <string name="open_app" msgid="3717639178595958667">"App öffnen"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Schließen"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-el/strings.xml b/packages/VpnDialogs/res/values-el/strings.xml
index 97b4407..78bcc43 100644
--- a/packages/VpnDialogs/res/values-el/strings.xml
+++ b/packages/VpnDialogs/res/values-el/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Αίτημα σύνδεσης"</string>
     <string name="warning" msgid="809658604548412033">"Η εφαρμογή <xliff:g id="APP">%s</xliff:g> επιθυμεί να ρυθμίσει μια σύνδεση VPN που της επιτρέπει να παρακολουθεί την επισκεψιμότητα του δικτύου. Αποδεχτείτε το αίτημα μόνο εάν εμπιστεύεστε την πηγή. Το εικονίδιο &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; εμφανίζεται στο επάνω μέρος της οθόνης σας όταν είναι ενεργό το VPN."</string>
     <string name="legacy_title" msgid="192936250066580964">"Το VPN συνδέθηκε"</string>
-    <string name="configure" msgid="4905518375574791375">"Διαμόρφωση"</string>
-    <string name="disconnect" msgid="971412338304200056">"Αποσύνδεση"</string>
     <string name="session" msgid="6470628549473641030">"Περίοδος σύνδεσης"</string>
     <string name="duration" msgid="3584782459928719435">"Διάρκεια:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Στάλθηκε:"</string>
     <string name="data_received" msgid="4062776929376067820">"Λήφθηκε:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> πακέτα"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Δεν είναι δυνατή η σύνδεση σε πάντα ενεργό VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Το <xliff:g id="VPN_APP_0">%1$s</xliff:g> έχει ρυθμιστεί έτσι ώστε να είναι μόνιμα συνδεδεμένο, αλλά δεν είναι δυνατή η σύνδεση αυτήν τη στιγμή. Το τηλέφωνό σας θα χρησιμοποιεί ένα δημόσιο δίκτυο μέχρι να είναι δυνατή η επανασύνδεση στο <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Το <xliff:g id="VPN_APP">%1$s</xliff:g> έχει ρυθμιστεί έτσι ώστε να είναι μόνιμα συνδεδεμένο, αλλά δεν είναι δυνατή η σύνδεση αυτήν τη στιγμή. Δεν θα έχετε σύνδεση μέχρι να είναι δυνατή η επανασύνδεση του VPN."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Αλλαγή ρυθμίσεων VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Διαμόρφωση"</string>
+    <string name="disconnect" msgid="971412338304200056">"Αποσύνδεση"</string>
+    <string name="open_app" msgid="3717639178595958667">"Άνοιγμα εφαρμογής"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Παράβλεψη"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-en-rAU/strings.xml b/packages/VpnDialogs/res/values-en-rAU/strings.xml
index 2c93c78..6ed50a7 100644
--- a/packages/VpnDialogs/res/values-en-rAU/strings.xml
+++ b/packages/VpnDialogs/res/values-en-rAU/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Connection request"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> wants to set up a VPN connection that allows it to monitor network traffic. Only accept if you trust the source. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; appears at the top of your screen when VPN is active."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN is connected"</string>
-    <string name="configure" msgid="4905518375574791375">"Configure"</string>
-    <string name="disconnect" msgid="971412338304200056">"Disconnect"</string>
     <string name="session" msgid="6470628549473641030">"Session:"</string>
     <string name="duration" msgid="3584782459928719435">"Duration:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Sent:"</string>
     <string name="data_received" msgid="4062776929376067820">"Received:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> packets"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Can\'t connect to always-on VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> is set up to stay connected all the time, but it can\'t connect at the moment. Your phone will use a public network until it can reconnect to <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> is set up to stay connected all the time, but it can\'t connect at the moment. You won\'t have a connection until the VPN can reconnect."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Change VPN settings"</string>
+    <string name="configure" msgid="4905518375574791375">"Configure"</string>
+    <string name="disconnect" msgid="971412338304200056">"Disconnect"</string>
+    <string name="open_app" msgid="3717639178595958667">"Open app"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Dismiss"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-en-rGB/strings.xml b/packages/VpnDialogs/res/values-en-rGB/strings.xml
index 2c93c78..6ed50a7 100644
--- a/packages/VpnDialogs/res/values-en-rGB/strings.xml
+++ b/packages/VpnDialogs/res/values-en-rGB/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Connection request"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> wants to set up a VPN connection that allows it to monitor network traffic. Only accept if you trust the source. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; appears at the top of your screen when VPN is active."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN is connected"</string>
-    <string name="configure" msgid="4905518375574791375">"Configure"</string>
-    <string name="disconnect" msgid="971412338304200056">"Disconnect"</string>
     <string name="session" msgid="6470628549473641030">"Session:"</string>
     <string name="duration" msgid="3584782459928719435">"Duration:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Sent:"</string>
     <string name="data_received" msgid="4062776929376067820">"Received:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> packets"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Can\'t connect to always-on VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> is set up to stay connected all the time, but it can\'t connect at the moment. Your phone will use a public network until it can reconnect to <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> is set up to stay connected all the time, but it can\'t connect at the moment. You won\'t have a connection until the VPN can reconnect."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Change VPN settings"</string>
+    <string name="configure" msgid="4905518375574791375">"Configure"</string>
+    <string name="disconnect" msgid="971412338304200056">"Disconnect"</string>
+    <string name="open_app" msgid="3717639178595958667">"Open app"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Dismiss"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-en-rIN/strings.xml b/packages/VpnDialogs/res/values-en-rIN/strings.xml
index 2c93c78..6ed50a7 100644
--- a/packages/VpnDialogs/res/values-en-rIN/strings.xml
+++ b/packages/VpnDialogs/res/values-en-rIN/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Connection request"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> wants to set up a VPN connection that allows it to monitor network traffic. Only accept if you trust the source. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; appears at the top of your screen when VPN is active."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN is connected"</string>
-    <string name="configure" msgid="4905518375574791375">"Configure"</string>
-    <string name="disconnect" msgid="971412338304200056">"Disconnect"</string>
     <string name="session" msgid="6470628549473641030">"Session:"</string>
     <string name="duration" msgid="3584782459928719435">"Duration:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Sent:"</string>
     <string name="data_received" msgid="4062776929376067820">"Received:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> packets"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Can\'t connect to always-on VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> is set up to stay connected all the time, but it can\'t connect at the moment. Your phone will use a public network until it can reconnect to <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> is set up to stay connected all the time, but it can\'t connect at the moment. You won\'t have a connection until the VPN can reconnect."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Change VPN settings"</string>
+    <string name="configure" msgid="4905518375574791375">"Configure"</string>
+    <string name="disconnect" msgid="971412338304200056">"Disconnect"</string>
+    <string name="open_app" msgid="3717639178595958667">"Open app"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Dismiss"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-es-rUS/strings.xml b/packages/VpnDialogs/res/values-es-rUS/strings.xml
index 8f0a050..3732ebc 100644
--- a/packages/VpnDialogs/res/values-es-rUS/strings.xml
+++ b/packages/VpnDialogs/res/values-es-rUS/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Solicitud de conexión"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> quiere configurar una conexión VPN que permite controlar el tráfico de la red. Acéptala solo si confías en la fuente. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; aparece en la parte superior de la pantalla cuando la VPN está activa."</string>
     <string name="legacy_title" msgid="192936250066580964">"La VPN está conectada."</string>
-    <string name="configure" msgid="4905518375574791375">"Configurar"</string>
-    <string name="disconnect" msgid="971412338304200056">"Desconectar"</string>
     <string name="session" msgid="6470628549473641030">"Sesión:"</string>
     <string name="duration" msgid="3584782459928719435">"Duración:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Enviados:"</string>
     <string name="data_received" msgid="4062776929376067820">"Recibidos:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> paquetes"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"No se puede conectar a la VPN siempre activa"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Se configuró <xliff:g id="VPN_APP_0">%1$s</xliff:g> para que permaneciera activa, pero no puede establecer conexión en este momento. Tu teléfono usará una red pública hasta que pueda volver a conectarse a <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Se configuró <xliff:g id="VPN_APP">%1$s</xliff:g> para que permaneciera activa, pero no puede establecer conexión en este momento. No podrás conectarte hasta que la VPN vuelva a establecer la conexión."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Cambiar configuración de VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Configurar"</string>
+    <string name="disconnect" msgid="971412338304200056">"Desconectar"</string>
+    <string name="open_app" msgid="3717639178595958667">"Abrir app"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Descartar"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-es/strings.xml b/packages/VpnDialogs/res/values-es/strings.xml
index cc50abe..1cb5602 100644
--- a/packages/VpnDialogs/res/values-es/strings.xml
+++ b/packages/VpnDialogs/res/values-es/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Solicitud de conexión"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> quiere configurar una conexión VPN para controlar el tráfico de red. Solo debes aceptarla si confías en la fuente. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; aparece en la parte superior de la pantalla cuando se active la conexión VPN."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN conectada"</string>
-    <string name="configure" msgid="4905518375574791375">"Configurar"</string>
-    <string name="disconnect" msgid="971412338304200056">"Desconectar"</string>
     <string name="session" msgid="6470628549473641030">"Sesión:"</string>
     <string name="duration" msgid="3584782459928719435">"Duración:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Enviado:"</string>
     <string name="data_received" msgid="4062776929376067820">"Recibido:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> paquetes"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"No se puede establecer conexión con VPN siempre activada"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> se ha configurado para tener conexión siempre, pero no se puede conectar en este momento. El teléfono utilizará una red pública hasta que se pueda volver a conectar a <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> se ha configurado para tener conexión siempre, pero no se puede conectar en este momento. No tendrás conexión hasta que te puedas volver a conectar a la red VPN."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Cambiar ajustes de VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Configurar"</string>
+    <string name="disconnect" msgid="971412338304200056">"Desconectar"</string>
+    <string name="open_app" msgid="3717639178595958667">"Abrir aplicación"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Ignorar"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-et/strings.xml b/packages/VpnDialogs/res/values-et/strings.xml
index ee8f769..c328cd7 100644
--- a/packages/VpnDialogs/res/values-et/strings.xml
+++ b/packages/VpnDialogs/res/values-et/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Ühendamise taotlus"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> tahab seadistada VPN-i ühenduse, mis võimaldab jälgida võrguliiklust. Nõustuge ainult siis, kui usaldate seda allikat. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; kuvatakse ekraani ülaservas, kui VPN on aktiivne."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN on ühendatud"</string>
-    <string name="configure" msgid="4905518375574791375">"Seadistamine"</string>
-    <string name="disconnect" msgid="971412338304200056">"Katkesta ühendus"</string>
     <string name="session" msgid="6470628549473641030">"Seansid"</string>
     <string name="duration" msgid="3584782459928719435">"Kestus:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Saadetud:"</string>
     <string name="data_received" msgid="4062776929376067820">"Vastu on võetud:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> baiti / <xliff:g id="NUMBER_1">%2$s</xliff:g> paketti"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Alati sisselülitatud VPN-iga ei saa ühendada"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Rakendus <xliff:g id="VPN_APP_0">%1$s</xliff:g> on seadistatud pidevaks ühenduseks, kuid praegu ei saa ühendada. Seni, kuni teie telefon rakendusega <xliff:g id="VPN_APP_1">%1$s</xliff:g> ühenduse loob, kasutab see avalikku võrku."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Rakendus <xliff:g id="VPN_APP">%1$s</xliff:g> on seadistatud pidevaks ühenduseks, kuid praegu ei saa ühendada. Ühendus taastatakse siis, kui VPN-iga saab uuesti ühenduse luua."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN-i seadete muutmine"</string>
+    <string name="configure" msgid="4905518375574791375">"Seadistamine"</string>
+    <string name="disconnect" msgid="971412338304200056">"Katkesta ühendus"</string>
+    <string name="open_app" msgid="3717639178595958667">"Ava rakendus"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Loobu"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-eu/strings.xml b/packages/VpnDialogs/res/values-eu/strings.xml
index b716509..a3b7716e 100644
--- a/packages/VpnDialogs/res/values-eu/strings.xml
+++ b/packages/VpnDialogs/res/values-eu/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Konektatzeko eskaera"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> aplikazioak VPN bidezko konexioa ezarri nahi du sareko trafikoa kontrolatzeko. Iturburua fidagarria bada bakarrik baimendu. &lt;br /&gt; &lt;br /&gt; VPN konexioa aktibo dagoenean, &lt;img src=vpn_icon /&gt; agertuko da pantailaren goialdean."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN sarera konektatuta dago"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfiguratu"</string>
-    <string name="disconnect" msgid="971412338304200056">"Deskonektatu"</string>
     <string name="session" msgid="6470628549473641030">"Saioa:"</string>
     <string name="duration" msgid="3584782459928719435">"Iraupena:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Bidalita:"</string>
     <string name="data_received" msgid="4062776929376067820">"Jasota:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> pakete"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Ezin da konektatu beti aktibatuta dagoen VPN sarea"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Beti aktibatuta egoteko dago konfiguratuta <xliff:g id="VPN_APP_0">%1$s</xliff:g>, baina une honetan ezin da konektatu. <xliff:g id="VPN_APP_1">%1$s</xliff:g> sarera berriro konektatu ahal izan arte, sare publiko bat erabiliko du telefonoak."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Beti aktibatuta egoteko dago konfiguratuta <xliff:g id="VPN_APP">%1$s</xliff:g>, baina une honetan ezin da konektatu. VPN sarearen konexioa berreskuratu arte, ez duzu izango konexiorik."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Aldatu VPN ezarpenak"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfiguratu"</string>
+    <string name="disconnect" msgid="971412338304200056">"Deskonektatu"</string>
+    <string name="open_app" msgid="3717639178595958667">"Ireki aplikazioa"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Baztertu"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-fa/strings.xml b/packages/VpnDialogs/res/values-fa/strings.xml
index 7b17f42..56f847c 100644
--- a/packages/VpnDialogs/res/values-fa/strings.xml
+++ b/packages/VpnDialogs/res/values-fa/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"درخواست اتصال"</string>
     <string name="warning" msgid="809658604548412033">"‏<xliff:g id="APP">%s</xliff:g> می‌خواهد یک اتصال VPN راه‌اندازی کند که به آن امکان نظارت بر ترافیک شبکه را می‌دهد. فقط در صورتی بپذیرید که به منبع آن اطمینان دارید. هنگامی که VPN فعال شد، &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; در بالای صفحه نمایش شما نشان داده می‌شود."</string>
     <string name="legacy_title" msgid="192936250066580964">"‏VPN متصل است"</string>
-    <string name="configure" msgid="4905518375574791375">"پیکربندی"</string>
-    <string name="disconnect" msgid="971412338304200056">"قطع اتصال"</string>
     <string name="session" msgid="6470628549473641030">"جلسه:"</string>
     <string name="duration" msgid="3584782459928719435">"مدت زمان:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"ارسال شده:"</string>
     <string name="data_received" msgid="4062776929376067820">"دریافتی:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> بایت / <xliff:g id="NUMBER_1">%2$s</xliff:g> بسته"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"‏اتصال به VPN همیشه روشن امکان‌پذیر نیست"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> به‌گونه‌ای تنظیم شده است که همیشه متصل باشد، اما درحال‌ حاضر اتصال امکان‌پذیر نیست. تلفنتان تا زمان اتصال مجدد به <xliff:g id="VPN_APP_1">%1$s</xliff:g>، از یک شبکه عمومی استفاده خواهد کرد."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"‏<xliff:g id="VPN_APP">%1$s</xliff:g> به‌گونه‌ای تنظیم شده است که همیشه متصل باشد، اما درحال حاضر اتصال امکان‌پذیر نیست. تا زمان اتصال مجدد VPN، نمی‌توانید متصل شوید."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"‏تغییر تنظیمات VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"پیکربندی"</string>
+    <string name="disconnect" msgid="971412338304200056">"قطع اتصال"</string>
+    <string name="open_app" msgid="3717639178595958667">"باز کردن برنامه"</string>
+    <string name="dismiss" msgid="6192859333764711227">"رد کردن"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-fi/strings.xml b/packages/VpnDialogs/res/values-fi/strings.xml
index 23fae48..91c918a 100644
--- a/packages/VpnDialogs/res/values-fi/strings.xml
+++ b/packages/VpnDialogs/res/values-fi/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Yhteyspyyntö"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> haluaa tehdä asetukset VPN-yhteydellä, jonka kautta sovellus voi valvoa verkkoliikennettä. Hyväksy vain, jos lähde on luotettava. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; näkyy ruudun yläreunassa, kun VPN on käytössä."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN on yhdistetty"</string>
-    <string name="configure" msgid="4905518375574791375">"Asetukset"</string>
-    <string name="disconnect" msgid="971412338304200056">"Katkaise yhteys"</string>
     <string name="session" msgid="6470628549473641030">"Käyttökerta"</string>
     <string name="duration" msgid="3584782459928719435">"Kesto:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Lähetetty:"</string>
     <string name="data_received" msgid="4062776929376067820">"Vastaanotettu:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> tavua / <xliff:g id="NUMBER_1">%2$s</xliff:g> pakettia"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Ei yhteyttä aina päällä olevaan VPN:ään"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> on määritetty pitämään yhteys aina päällä, mutta se ei voi muodostaa yhteyttä tällä hetkellä. Puhelin käyttää julkista verkkoa, kunnes <xliff:g id="VPN_APP_1">%1$s</xliff:g> on taas käytettävissä."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> on määritetty pitämään yhteys aina päällä, mutta se ei voi muodostaa yhteyttä tällä hetkellä. Puhelimella ei ole internetyhteyttä, ennen kuin VPN-yhteys voidaan muodostaa."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Muuta VPN-asetuksia"</string>
+    <string name="configure" msgid="4905518375574791375">"Asetukset"</string>
+    <string name="disconnect" msgid="971412338304200056">"Katkaise yhteys"</string>
+    <string name="open_app" msgid="3717639178595958667">"Avaa sovellus"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Hylkää"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-fr-rCA/strings.xml b/packages/VpnDialogs/res/values-fr-rCA/strings.xml
index 0c434a0..aa86c7c 100644
--- a/packages/VpnDialogs/res/values-fr-rCA/strings.xml
+++ b/packages/VpnDialogs/res/values-fr-rCA/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Demande de connexion"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> veut configurer une connexion RPV qui permet de surveiller le trafic réseau. N\'acceptez que si vous faites confiance à la source. &lt;br /&gt;&lt;br /&gt;&lt;img src=vpn_icon/&gt; s\'affiche dans le haut de votre écran lorsqu\'une connexion  RPV est active."</string>
     <string name="legacy_title" msgid="192936250066580964">"RPV connecté"</string>
-    <string name="configure" msgid="4905518375574791375">"Configurer"</string>
-    <string name="disconnect" msgid="971412338304200056">"Déconnecter"</string>
     <string name="session" msgid="6470628549473641030">"Session :"</string>
     <string name="duration" msgid="3584782459928719435">"Durée :"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Date d\'envoi :"</string>
     <string name="data_received" msgid="4062776929376067820">"Reçu le :"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> octets / <xliff:g id="NUMBER_1">%2$s</xliff:g> paquets"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Impossible de se connecter au RPV permanent"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> est configuré pour rester connecté en permanence, mais n\'arrive pas à se connecter en ce moment. Votre téléphone utilisera un réseau public jusqu\'à ce qu\'il puisse se reconnecter à <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> est configuré pour rester connecté en permanence, mais n\'arrive pas à se connecter en ce moment. Vous n\'aurez pas de connexion jusqu\'à ce que le RPV arrive à se reconnecter."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Modifier les paramètres RPV"</string>
+    <string name="configure" msgid="4905518375574791375">"Configurer"</string>
+    <string name="disconnect" msgid="971412338304200056">"Déconnecter"</string>
+    <string name="open_app" msgid="3717639178595958667">"Ouvrir l\'application"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Ignorer"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-fr/strings.xml b/packages/VpnDialogs/res/values-fr/strings.xml
index dadb864..2b3eace 100644
--- a/packages/VpnDialogs/res/values-fr/strings.xml
+++ b/packages/VpnDialogs/res/values-fr/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Demande de connexion"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> souhaite configurer une connexion VPN qui permet de surveiller le trafic réseau. N\'acceptez que si vous faites confiance à la source. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; s\'affiche en haut de votre écran lorsqu\'une connexion VPN est active."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN connecté"</string>
-    <string name="configure" msgid="4905518375574791375">"Configurer"</string>
-    <string name="disconnect" msgid="971412338304200056">"Déconnecter"</string>
     <string name="session" msgid="6470628549473641030">"Session :"</string>
     <string name="duration" msgid="3584782459928719435">"Durée :"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Envoyé :"</string>
     <string name="data_received" msgid="4062776929376067820">"Reçu :"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> octets / <xliff:g id="NUMBER_1">%2$s</xliff:g> paquets"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Impossible de se connecter au VPN permanent"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Le VPN <xliff:g id="VPN_APP_0">%1$s</xliff:g> est configuré pour rester connecté en permanence, mais il ne peut pas se connecter actuellement. Votre téléphone utilisera un réseau public jusqu\'à ce qu\'il puisse se reconnecter à <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Le VPN <xliff:g id="VPN_APP">%1$s</xliff:g> est configuré pour rester connecté en permanence, mais il ne peut pas se connecter actuellement. Vous ne disposerez d\'aucune connexion jusqu\'à ce que le VPN puisse se reconnecter."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Modifier les paramètres VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Configurer"</string>
+    <string name="disconnect" msgid="971412338304200056">"Déconnecter"</string>
+    <string name="open_app" msgid="3717639178595958667">"Ouvrir l\'application"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Ignorer"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-gl/strings.xml b/packages/VpnDialogs/res/values-gl/strings.xml
index 40f54fc..8a66d08 100644
--- a/packages/VpnDialogs/res/values-gl/strings.xml
+++ b/packages/VpnDialogs/res/values-gl/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Solicitude de conexión"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> quere configurar unha conexión VPN que lle permite controlar o tráfico da rede. Acepta soamente se confías na fonte. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; aparece na parte superior da pantalla cando se activa a VPN."</string>
     <string name="legacy_title" msgid="192936250066580964">"A VPN está conectada"</string>
-    <string name="configure" msgid="4905518375574791375">"Configurar"</string>
-    <string name="disconnect" msgid="971412338304200056">"Desconectar"</string>
     <string name="session" msgid="6470628549473641030">"Sesión:"</string>
     <string name="duration" msgid="3584782459928719435">"Duración:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Datos enviados:"</string>
     <string name="data_received" msgid="4062776929376067820">"Recibido:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> paquetes"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Non se pode establecer conexión coa VPN sempre activada"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"A <xliff:g id="VPN_APP_0">%1$s</xliff:g> está configurada para permanecer conectada sempre, pero non se pode conectar neste momento. O teu teléfono utilizará unha rede pública ata que se poida conectar de novo á <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"A <xliff:g id="VPN_APP">%1$s</xliff:g> está configurada para permanecer conectada sempre, pero non se pode conectar neste momento. Non se establecerá conexión ata que a VPN se poida conectar de novo."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Cambiar a configuración da VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Configurar"</string>
+    <string name="disconnect" msgid="971412338304200056">"Desconectar"</string>
+    <string name="open_app" msgid="3717639178595958667">"Abrir aplicación"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Ignorar"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-gu/strings.xml b/packages/VpnDialogs/res/values-gu/strings.xml
index a0fb98a..961711c 100644
--- a/packages/VpnDialogs/res/values-gu/strings.xml
+++ b/packages/VpnDialogs/res/values-gu/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"કનેક્શન વિનંતી"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> VPN કનેક્શન સેટ કરવા માગે છે જે તેને નેટવર્ક ટ્રાફિક મૉનિટર કરવાની મંજૂરી આપે છે. જો તમને સ્રોત પર વિશ્વાસ હોય તો જ સ્વીકારો. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; તમારી સ્ક્રીનની ટોચ પર ત્યારે દેખાય છે જ્યારે VPN સક્રિય હોય છે."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN કનેક્ટ કરેલું છે"</string>
-    <string name="configure" msgid="4905518375574791375">"ગોઠવો"</string>
-    <string name="disconnect" msgid="971412338304200056">"ડિસ્કનેક્ટ કરો"</string>
     <string name="session" msgid="6470628549473641030">"સત્ર:"</string>
     <string name="duration" msgid="3584782459928719435">"અવધિ:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"મોકલ્યું:"</string>
     <string name="data_received" msgid="4062776929376067820">"પ્રાપ્ત કર્યુ:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> બાઇટ્સ / <xliff:g id="NUMBER_1">%2$s</xliff:g> પેકેટ્સ"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"હંમેશાં-ચાલુ VPN કનેક્ટ કરી શકાતું નથી"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g>ને હંમેશાં જોડાયેલ રહેવા માટે સેટ કરેલ છે, પરંતુ તે હાલમાં કનેક્ટ કરી શકાતું નથી. તમારો ફોન જ્યાં સુધી <xliff:g id="VPN_APP_1">%1$s</xliff:g> સાથે ફરીથી કનેક્ટ ન થાય ત્યાં સુધી તે સાર્વજનિક નેટવર્કનો ઉપયોગ કરશે."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g>ને હંમેશાં જોડાયેલ રહેવા માટે સેટ કરેલ છે, પરંતુ તે હાલમાં કનેક્ટ કરી શકાતું નથી. VPN ફરીથી કનેક્ટ ન થઈ શકે ત્યાં સુધી તમારી પાસે કોઈ કનેક્શન હશે નહીં."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN સેટિંગ્સ બદલો"</string>
+    <string name="configure" msgid="4905518375574791375">"ગોઠવો"</string>
+    <string name="disconnect" msgid="971412338304200056">"ડિસ્કનેક્ટ કરો"</string>
+    <string name="open_app" msgid="3717639178595958667">"ઍપ ખોલો"</string>
+    <string name="dismiss" msgid="6192859333764711227">"છોડી દો"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-hi/strings.xml b/packages/VpnDialogs/res/values-hi/strings.xml
index 15f69c6..7091ce7 100644
--- a/packages/VpnDialogs/res/values-hi/strings.xml
+++ b/packages/VpnDialogs/res/values-hi/strings.xml
@@ -17,13 +17,20 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="prompt" msgid="3183836924226407828">"कनेक्शन अनुरोध"</string>
-    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> VPN कनेक्‍शन सेट करना चाहता है जो उसे नेटवर्क ट्रैफ़िक मॉनीटर करने देता है. केवल तभी स्‍वीकार करें, जबकि आप स्रोत पर विश्वास करते हों. VPN सक्रिय होने पर आपकी स्‍क्रीन पर ऊपर &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; दिखाई देता है."</string>
+    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> VPN कनेक्‍शन सेट करना चाहता है जो उसे नेटवर्क ट्रैफ़िक मॉनीटर करने देता है. केवल तभी स्‍वीकार करें, जबकि आप स्रोत पर भरोसा करते हों. VPN सक्रिय होने पर आपकी स्‍क्रीन पर ऊपर &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; दिखाई देता है."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN कनेक्‍ट है"</string>
-    <string name="configure" msgid="4905518375574791375">"कॉन्फ़िगर करें"</string>
-    <string name="disconnect" msgid="971412338304200056">"डिस्‍कनेक्‍ट करें"</string>
     <string name="session" msgid="6470628549473641030">"सत्र:"</string>
     <string name="duration" msgid="3584782459928719435">"अवधि:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"भेजे गए:"</string>
     <string name="data_received" msgid="4062776929376067820">"प्राप्त:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> बाइट / <xliff:g id="NUMBER_1">%2$s</xliff:g> पैकेट"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"हमेशा चालू रहने वाले VPN से नहीं जुड़ पा रहा है"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> को हर समय जुड़े रहने के लिए सेट अप किया गया है, लेकिन वह इस समय नहीं जुड़ पा रहा है. जब तक आपका फ़ोन <xliff:g id="VPN_APP_1">%1$s</xliff:g> से नहीं जुड़ जाता, तब तक वह सार्वजनिक नेटवर्क का इस्तेमाल करेगा."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> को हर समय जुड़े रहने के लिए सेट अप किया गया है, लेकिन वह इस समय नहीं जुड़ पा रहा है. जब तक VPN फिर से नहीं जुड़ जाता, तब तक आपके पास कनेक्शन नहीं होगा."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN सेटिंग बदलें"</string>
+    <string name="configure" msgid="4905518375574791375">"कॉन्फ़िगर करें"</string>
+    <string name="disconnect" msgid="971412338304200056">"डिस्‍कनेक्‍ट करें"</string>
+    <string name="open_app" msgid="3717639178595958667">"ऐप खोलें"</string>
+    <string name="dismiss" msgid="6192859333764711227">"खारिज करें"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-hr/strings.xml b/packages/VpnDialogs/res/values-hr/strings.xml
index d58319d..aa9e436 100644
--- a/packages/VpnDialogs/res/values-hr/strings.xml
+++ b/packages/VpnDialogs/res/values-hr/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Zahtjev za povezivanje"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> želi postaviti VPN vezu pomoću koje će moći nadzirati mrežni promet. Prihvatite samo ako smatrate izvor pouzdanim. Kada je VPN aktivan, pri vrhu zaslona prikazuje se &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt;."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN je spojen"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfiguriraj"</string>
-    <string name="disconnect" msgid="971412338304200056">"Prekini vezu"</string>
     <string name="session" msgid="6470628549473641030">"Sesija"</string>
     <string name="duration" msgid="3584782459928719435">"Trajanje:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Poslano:"</string>
     <string name="data_received" msgid="4062776929376067820">"Primljeno:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Bajtova: <xliff:g id="NUMBER_0">%1$s</xliff:g>/paketa: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Povezivanje s uvijek uključenim VPN-om nije moguće"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Mreža <xliff:g id="VPN_APP_0">%1$s</xliff:g> postavljena je da bude stalno povezana, ali se trenutačno ne može povezati. Telefon će koristiti javnu mrežu dok povezivanje s mrežom <xliff:g id="VPN_APP_1">%1$s</xliff:g> ne bude ponovo moguće."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Mreža <xliff:g id="VPN_APP">%1$s</xliff:g> postavljena je da bude stalno povezana, ali se trenutačno ne može povezati. Telefon će koristiti javnu mrežu dok povezivanje s VPN-om ne bude ponovo moguće."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Promjena postavki VPN-a"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfiguriraj"</string>
+    <string name="disconnect" msgid="971412338304200056">"Prekini vezu"</string>
+    <string name="open_app" msgid="3717639178595958667">"Otvori aplikaciju"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Odbaci"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-hu/strings.xml b/packages/VpnDialogs/res/values-hu/strings.xml
index 2ffdff8..703aa79 100644
--- a/packages/VpnDialogs/res/values-hu/strings.xml
+++ b/packages/VpnDialogs/res/values-hu/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Kapcsolódási kérés"</string>
     <string name="warning" msgid="809658604548412033">"A(z) <xliff:g id="APP">%s</xliff:g> VPN kapcsolatot akar beállítani, amelynek segítségével figyelheti a hálózati forgalmat. Csak akkor fogadja el, ha megbízik a forrásban. &lt;br /&gt; &lt;br /&gt; Amikor a VPN aktív, &lt;img src=vpn_icon /&gt; ikon jelenik meg a képernyő tetején."</string>
     <string name="legacy_title" msgid="192936250066580964">"A VPN csatlakoztatva van"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfigurálás"</string>
-    <string name="disconnect" msgid="971412338304200056">"Kapcsolat bontása"</string>
     <string name="session" msgid="6470628549473641030">"Munkamenet:"</string>
     <string name="duration" msgid="3584782459928719435">"Időtartam:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Elküldve:"</string>
     <string name="data_received" msgid="4062776929376067820">"Érkezett:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bájt/<xliff:g id="NUMBER_1">%2$s</xliff:g> adatcsomag"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Nem lehet csatlakozni a mindig bekapcsolt állapotú VPN-hez"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"A(z) <xliff:g id="VPN_APP_0">%1$s</xliff:g> úgy van beállítva, hogy mindig fenntartsa a kapcsolatot, de jelenleg nem képes csatlakozni. Telefonja nyilvános hálózatot használ addig, amíg nem sikerül újra csatlakozni a következőhöz: <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"A(z) <xliff:g id="VPN_APP">%1$s</xliff:g> úgy van beállítva, hogy mindig fenntartsa a kapcsolatot, de jelenleg nem képes csatlakozni. Amíg a VPN újra nem csatlakozik, Önnek nem lesz internetkapcsolata."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN-beállítások módosítása"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfigurálás"</string>
+    <string name="disconnect" msgid="971412338304200056">"Kapcsolat bontása"</string>
+    <string name="open_app" msgid="3717639178595958667">"Alkalmazás indítása"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Bezárás"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-hy/strings.xml b/packages/VpnDialogs/res/values-hy/strings.xml
index 2a27a93..c296c85 100644
--- a/packages/VpnDialogs/res/values-hy/strings.xml
+++ b/packages/VpnDialogs/res/values-hy/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Միացման հայց"</string>
     <string name="warning" msgid="809658604548412033">"«<xliff:g id="APP">%s</xliff:g>» հավելվածը ցանկանում է VPN կապ հաստատել՝ ցանցային երթևեկը հսկելու համար: Թույլատրեք, միայն եթե վստահում եք աղբյուրին: Երբ VPN-ն ակտիվ լինի, ձեր էկրանի վերին հատվածում կհայտնվի &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; պատկերը:"</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN-ը կապակցված է"</string>
-    <string name="configure" msgid="4905518375574791375">"Կարգավորել"</string>
-    <string name="disconnect" msgid="971412338304200056">"Անջատել"</string>
     <string name="session" msgid="6470628549473641030">"Աշխատաշրջան`"</string>
     <string name="duration" msgid="3584782459928719435">"Տևողությունը՝"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Ուղարկվել է՝"</string>
     <string name="data_received" msgid="4062776929376067820">"Ստացվել է՝"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> բայթ / <xliff:g id="NUMBER_1">%2$s</xliff:g> փաթեթ"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Չի հաջողվում միանալ միշտ միացված VPN-ին"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g>-ն այնպես է կարգավորված, որ միշտ միացած մնա, սակայն ներկայումս կապակցման խնդիր կա: Ձեր հեռախոսը կօգտագործի հանրային ցանցը, մինչև նորից կարողանա միանալ <xliff:g id="VPN_APP_1">%1$s</xliff:g>-ին:"</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g>-ն այնպես է կարգավորված, որ միշտ միացած մնա, սակայն ներկայումս կապակցման խնդիր կա: Մինչև VPN-ը նորից չմիանա, դուք կապ չեք ունենա:"</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Փոխել VPN-ի կարգավորումները"</string>
+    <string name="configure" msgid="4905518375574791375">"Կարգավորել"</string>
+    <string name="disconnect" msgid="971412338304200056">"Անջատել"</string>
+    <string name="open_app" msgid="3717639178595958667">"Բացել հավելվածը"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Փակել"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-in/strings.xml b/packages/VpnDialogs/res/values-in/strings.xml
index 5553d70..386c24a 100644
--- a/packages/VpnDialogs/res/values-in/strings.xml
+++ b/packages/VpnDialogs/res/values-in/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Permintaan sambungan"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> ingin menyiapkan sambungan VPN yang memungkinkannya memantau lalu-lintas jaringan. Terima hanya jika Anda memercayai sumber. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; muncul di bagian atas layar Anda saat VPN aktif."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN tersambung"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfigurasikan"</string>
-    <string name="disconnect" msgid="971412338304200056">"Putuskan sambungan"</string>
     <string name="session" msgid="6470628549473641030">"Sesi:"</string>
     <string name="duration" msgid="3584782459928719435">"Durasi:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Terkirim:"</string>
     <string name="data_received" msgid="4062776929376067820">"Diterima:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bita / <xliff:g id="NUMBER_1">%2$s</xliff:g> paket"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Tidak dapat tersambung ke VPN yang selalu aktif"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> disiapkan untuk selalu tersambung, tetapi saat ini tidak dapat tersambung. Ponsel akan menggunakan jaringan publik sampai dapat tersambung ulang ke <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> disiapkan untuk selalu tersambung, tetapi saat ini tidak dapat tersambung. Anda akan tersambung jika VPN dapat tersambung ulang."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Ubah setelan VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfigurasikan"</string>
+    <string name="disconnect" msgid="971412338304200056">"Putuskan sambungan"</string>
+    <string name="open_app" msgid="3717639178595958667">"Buka aplikasi"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Tutup"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-is/strings.xml b/packages/VpnDialogs/res/values-is/strings.xml
index 059c6a9..70fb40f 100644
--- a/packages/VpnDialogs/res/values-is/strings.xml
+++ b/packages/VpnDialogs/res/values-is/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Beiðni um tengingu"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> vill setja upp VPN-tengingu til þess að geta fylgst með netumferð. Samþykktu þetta aðeins ef þú treystir upprunanum. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; birtist efst á skjánum þegar VPN er virkt."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN er tengt"</string>
-    <string name="configure" msgid="4905518375574791375">"Stilla"</string>
-    <string name="disconnect" msgid="971412338304200056">"Aftengja"</string>
     <string name="session" msgid="6470628549473641030">"Lota:"</string>
     <string name="duration" msgid="3584782459928719435">"Tímalengd:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Sent:"</string>
     <string name="data_received" msgid="4062776929376067820">"Móttekið:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bæti / <xliff:g id="NUMBER_1">%2$s</xliff:g> pakkar"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Ekki er hægt að tengjast sívirku VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> er sett upp til að halda tengingu öllum stundum, en það getur ekki tengst að svo stöddu. Síminn notast við opið netkerfi þar til hann getur endurtengst við <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> er sett upp til að halda tengingu öllum stundum, en það getur ekki tengst að svo stöddu. Þú verður án tengingar þar til VPN getur endurtengst."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Breyta stillingum VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Stilla"</string>
+    <string name="disconnect" msgid="971412338304200056">"Aftengja"</string>
+    <string name="open_app" msgid="3717639178595958667">"Opna forrit"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Hunsa"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-it/strings.xml b/packages/VpnDialogs/res/values-it/strings.xml
index e601a5f..2602493 100644
--- a/packages/VpnDialogs/res/values-it/strings.xml
+++ b/packages/VpnDialogs/res/values-it/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Richiesta di connessione"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> vuole impostare una connessione VPN che le consenta di monitorare il traffico di rete. Accetta soltanto se ritieni la fonte attendibile. Quando la connessione VPN è attiva, nella parte superiore dello schermo viene visualizzata l\'icona &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt;."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN connessa"</string>
-    <string name="configure" msgid="4905518375574791375">"Configura"</string>
-    <string name="disconnect" msgid="971412338304200056">"Disconnetti"</string>
     <string name="session" msgid="6470628549473641030">"Sessione:"</string>
     <string name="duration" msgid="3584782459928719435">"Durata:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Inviati:"</string>
     <string name="data_received" msgid="4062776929376067820">"Ricevuti:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte/<xliff:g id="NUMBER_1">%2$s</xliff:g> pacchetti"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Impossibile connettersi alla VPN sempre attiva"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> è impostata per rimanere sempre connessa, ma al momento non è possibile stabilire la connessione. Il telefono userà una rete pubblica finché potrà riconnettersi a <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> è impostata per rimanere sempre connessa, ma al momento non è possibile stabilire la connessione. Non avrai connessione finché non sarà possibile riconnettersi alla VPN."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Cambia le impostazioni VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Configura"</string>
+    <string name="disconnect" msgid="971412338304200056">"Disconnetti"</string>
+    <string name="open_app" msgid="3717639178595958667">"Apri app"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Ignora"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-iw/strings.xml b/packages/VpnDialogs/res/values-iw/strings.xml
index e5d2f89..55ac85f 100644
--- a/packages/VpnDialogs/res/values-iw/strings.xml
+++ b/packages/VpnDialogs/res/values-iw/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"בקשת חיבור"</string>
     <string name="warning" msgid="809658604548412033">"‏<xliff:g id="APP">%s</xliff:g> רוצה להגדיר חיבור VPN שיאפשר לו לפקח על תעבורת הרשת. אשר את הבקשה רק אם אתה נותן אמון במקור. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; מופיע בחלק העליון של המסך כאשר VPN פעיל."</string>
     <string name="legacy_title" msgid="192936250066580964">"‏VPN מחובר"</string>
-    <string name="configure" msgid="4905518375574791375">"הגדר"</string>
-    <string name="disconnect" msgid="971412338304200056">"נתק"</string>
     <string name="session" msgid="6470628549473641030">"הפעלה"</string>
     <string name="duration" msgid="3584782459928719435">"משך:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"נשלח:"</string>
     <string name="data_received" msgid="4062776929376067820">"התקבל:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> בתים / <xliff:g id="NUMBER_1">%2$s</xliff:g> מנות"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"‏לא ניתן להתחבר ל-VPN שפועל כל הזמן"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> מוגדרת כך שהיא לא מתנתקת אף פעם, אבל כרגע לא ניתן להתחבר. הטלפון יתחבר לרשת ציבורית עד שהוא יצליח להתחבר מחדש אל <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"‏<xliff:g id="VPN_APP">%1$s</xliff:g> מוגדרת כך שהיא לא מתנתקת אף פעם, אבל כרגע לא ניתן להתחבר. החיבור לאינטרנט יחזור רק כשהמכשיר יתחבר מחדש ל-VPN."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"‏לשינוי של הגדרות ה-VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"הגדר"</string>
+    <string name="disconnect" msgid="971412338304200056">"נתק"</string>
+    <string name="open_app" msgid="3717639178595958667">"לאפליקציה"</string>
+    <string name="dismiss" msgid="6192859333764711227">"סגירה"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ja/strings.xml b/packages/VpnDialogs/res/values-ja/strings.xml
index 0e65866..9dbf38b 100644
--- a/packages/VpnDialogs/res/values-ja/strings.xml
+++ b/packages/VpnDialogs/res/values-ja/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"接続リクエスト"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g>がネットワークトラフィックを監視するためVPN接続をセットアップしようとしています。ソースを信頼できる場合にのみ許可してください。&lt;br /&gt; &lt;br /&gt; VPNがアクティブになると画面の上部に&lt;img src=vpn_icon /&gt;が表示されます。"</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN接続済み"</string>
-    <string name="configure" msgid="4905518375574791375">"設定"</string>
-    <string name="disconnect" msgid="971412338304200056">"切断"</string>
     <string name="session" msgid="6470628549473641030">"セッション:"</string>
     <string name="duration" msgid="3584782459928719435">"期間:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"送信:"</string>
     <string name="data_received" msgid="4062776929376067820">"受信:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g>バイト/<xliff:g id="NUMBER_1">%2$s</xliff:g>パケット"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"常時接続 VPN に接続できません"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> は常時接続に設定されていますが、現在接続できません。<xliff:g id="VPN_APP_1">%1$s</xliff:g> への再接続が確立するまでの間、スマートフォンは公衆通信回線を使用します。"</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> は常時接続に設定されていますが、現在接続できません。VPN との再接続が確立するまでの間、インターネットは利用できません。"</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN の設定を変更する"</string>
+    <string name="configure" msgid="4905518375574791375">"設定"</string>
+    <string name="disconnect" msgid="971412338304200056">"切断"</string>
+    <string name="open_app" msgid="3717639178595958667">"アプリを開く"</string>
+    <string name="dismiss" msgid="6192859333764711227">"閉じる"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ka/strings.xml b/packages/VpnDialogs/res/values-ka/strings.xml
index 61f3b0f..e5a0753 100644
--- a/packages/VpnDialogs/res/values-ka/strings.xml
+++ b/packages/VpnDialogs/res/values-ka/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"კავშირის მოთხოვნა"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> სურს დააყენოს VPN კავშირი, რაც ქსელის ტრაფიკის მონიტორინგის საშუალებას იძლევა. მიიღოთ მხოლოდ ისეთ შემთხვევაში, თუ წყაროს ენდობით. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; თქვენი ეკრანის სიის თავში გამოჩნდება, როდესაც VPN აქტიურია."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN დაკავშირებულია"</string>
-    <string name="configure" msgid="4905518375574791375">"კონფიგურაცია"</string>
-    <string name="disconnect" msgid="971412338304200056">"კავშირის გაწყვეტა"</string>
     <string name="session" msgid="6470628549473641030">"სესია:"</string>
     <string name="duration" msgid="3584782459928719435">"ხანგრძლივობა:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"გაგზავნილი:"</string>
     <string name="data_received" msgid="4062776929376067820">"მიღებული:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ბაიტი / <xliff:g id="NUMBER_1">%2$s</xliff:g> პაკეტი"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"მუდმივად ჩართულ VPN-თან დაკავშირება ვერ ხერხდება"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> დაყენებულია იმგვარად, რომ მუდმივად დაკავშირებული იყოს, მაგრამ ამწუთას ის დაკავშირებას ვერ ახერხებს. თქვენი ტელეფონი საჯარო ქსელს გამოიყენებს, სანამ <xliff:g id="VPN_APP_1">%1$s</xliff:g>-თან ხელახლა დაკავშირებას შეძლებდეთ."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> დაყენებულია იმგვარად, რომ მუდმივად დაკავშირებული იყოს, მაგრამ ამწუთას ის დაკავშირებას ვერ ახერხებს. კავშირი მიუწვდომელი იქნება, სანამ VPN ხელახლა დაკავშირებას მოახერხებს."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN-ის პარამეტრების შეცვლა"</string>
+    <string name="configure" msgid="4905518375574791375">"კონფიგურაცია"</string>
+    <string name="disconnect" msgid="971412338304200056">"კავშირის გაწყვეტა"</string>
+    <string name="open_app" msgid="3717639178595958667">"გახსენით აპი"</string>
+    <string name="dismiss" msgid="6192859333764711227">"დახურვა"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-kk/strings.xml b/packages/VpnDialogs/res/values-kk/strings.xml
index 8514d3c..79f79c3 100644
--- a/packages/VpnDialogs/res/values-kk/strings.xml
+++ b/packages/VpnDialogs/res/values-kk/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Байланысты сұрау"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> VPN байланысын орнатқысы келеді, бұл оған желілік трафикті бақылауға мүмкіндік береді. Көзге сенсеңіз ғана қабылдаңыз. VPN белсенді болғанда экранның жоғарғы жағында &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; көрсетіледі."</string>
     <string name="legacy_title" msgid="192936250066580964">"ВЖЖ қосылған"</string>
-    <string name="configure" msgid="4905518375574791375">"Конфигурациялау"</string>
-    <string name="disconnect" msgid="971412338304200056">"Ажырату"</string>
     <string name="session" msgid="6470628549473641030">"Сессия:"</string>
     <string name="duration" msgid="3584782459928719435">"Ұзақтығы:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Жіберілді:"</string>
     <string name="data_received" msgid="4062776929376067820">"Қабылданды:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> байт / <xliff:g id="NUMBER_1">%2$s</xliff:g> жинақ"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Әрқашан қосулы VPN желісіне қосылу мүмкін емес"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> әрқашан қосулы болатын етіп реттелген, бірақ оны қазір қосу мүмкін емес. Телефоныңыз <xliff:g id="VPN_APP_1">%1$s</xliff:g> желісіне қосылғанша жалпыға ортақ желіні пайдаланады."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> әрқашан қосулы болатын етіп реттелген, бірақ оны қазір қосу мүмкін емес. VPN қайта қосылмайынша, байланыс орната алмайсыз."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN параметрлерін өзгерту"</string>
+    <string name="configure" msgid="4905518375574791375">"Конфигурациялау"</string>
+    <string name="disconnect" msgid="971412338304200056">"Ажырату"</string>
+    <string name="open_app" msgid="3717639178595958667">"Қолданбаны ашу"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Жабу"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-km/strings.xml b/packages/VpnDialogs/res/values-km/strings.xml
index 027f104..06f34db 100644
--- a/packages/VpnDialogs/res/values-km/strings.xml
+++ b/packages/VpnDialogs/res/values-km/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"សំណើ​សុំ​ការ​តភ្ជាប់"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> ចង់​បង្កើត​ការ​តភ្ជាប់ VPN ដែល​អនុញ្ញាត​ឲ្យ​វា​ត្រួតពិនិត្យ​ចរាចរ​បណ្ដាញ។ ព្រម​ទទួល ប្រសិនបើ​អ្នក​ទុកចិត្ត​លើ​ប្រភព​តែប៉ុណ្ណោះ។ &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; នឹង​លេចឡើង​នៅ​ផ្នែក​ខាងលើ​នៃ​អេក្រង់​របស់​អ្នក ពេល VPN សកម្ម។"</string>
     <string name="legacy_title" msgid="192936250066580964">"បា​ន​ភ្ជាប់ VPN"</string>
-    <string name="configure" msgid="4905518375574791375">"កំណត់​រចនាសម្ព័ន្ធ"</string>
-    <string name="disconnect" msgid="971412338304200056">"ផ្ដាច់"</string>
     <string name="session" msgid="6470628549473641030">"សម័យ៖"</string>
     <string name="duration" msgid="3584782459928719435">"ថិរវេលា៖"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"បាន​ផ្ញើ៖"</string>
     <string name="data_received" msgid="4062776929376067820">"បាន​ទទួល៖"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> បៃ / <xliff:g id="NUMBER_1">%2$s</xliff:g> កញ្ចប់​ព័ត៌មាន"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"មិនអាចភ្ជាប់ជាមួយ VPN បើកជានិច្ច"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> ត្រូវបានរៀបចំដើម្បីឱ្យវាអាចបន្តភ្ជាប់គ្រប់ពេល ប៉ុន្តែវាមិនអាចភ្ជាប់បានទេឥឡូវនេះ។ ទូរសព្ទរបស់អ្នកនឹងប្រើបណ្ដាញសាធារណៈរហូតដល់វាអាចភ្ជាប់ឡើងវិញបានជាមួយ <xliff:g id="VPN_APP_1">%1$s</xliff:g> ។"</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> ត្រូវបានរៀបចំដើម្បីឱ្យវាអាចបន្តភ្ជាប់គ្រប់ពេល ប៉ុន្តែវាមិនអាចភ្ជាប់បានទេឥឡូវនេះ។ អ្នកនឹងមិនអាចភ្ជាប់បានទេ រហូតដល់ VPN អាចភ្ជាប់ឡើងវិញបាន។"</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"ប្ដូរការកំណត់ VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"កំណត់​រចនាសម្ព័ន្ធ"</string>
+    <string name="disconnect" msgid="971412338304200056">"ផ្ដាច់"</string>
+    <string name="open_app" msgid="3717639178595958667">"បើកកម្មវិធី"</string>
+    <string name="dismiss" msgid="6192859333764711227">"បដិសេធ"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-kn/strings.xml b/packages/VpnDialogs/res/values-kn/strings.xml
index b3f5a10..040cd6c 100644
--- a/packages/VpnDialogs/res/values-kn/strings.xml
+++ b/packages/VpnDialogs/res/values-kn/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"ಸಂಪರ್ಕ ವಿನಂತಿ"</string>
     <string name="warning" msgid="809658604548412033">"ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಅನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಲು ಅನುಮತಿಸುವಂತಹ VPN ಸಂಪರ್ಕವನ್ನು ಹೊಂದಿಸಲು <xliff:g id="APP">%s</xliff:g> ಬಯಸುತ್ತದೆ. ನೀವು ಮೂಲವನ್ನು ನಂಬಿದರೆ ಮಾತ್ರ ಸಮ್ಮತಿಸಿ. VPN ಸಕ್ರಿಯವಾಗಿರುವಾಗ ನಿಮ್ಮ ಪರದೆಯ ಮೇಲ್ಭಾಗದಲ್ಲಿ &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; ಗೋರಿಸುತ್ತದೆ."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
-    <string name="configure" msgid="4905518375574791375">"ಕಾನ್ಫಿಗರ್ ಮಾಡು"</string>
-    <string name="disconnect" msgid="971412338304200056">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸು"</string>
     <string name="session" msgid="6470628549473641030">"ಸೆಷನ್:"</string>
     <string name="duration" msgid="3584782459928719435">"ಅವಧಿ:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"ಕಳುಹಿಸಲಾಗಿದೆ:"</string>
     <string name="data_received" msgid="4062776929376067820">"ಸ್ವೀಕರಿಸಲಾಗಿದೆ:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ಬೈಟ್‌ಗಳು / <xliff:g id="NUMBER_1">%2$s</xliff:g> ಪ್ಯಾಕೆಟ್‌ಗಳು"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"ಯಾವಾಗಲೂ ಆನ್ ಆಗಿರುವ VPN ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"ಎಲ್ಲಾ ಸಂದರ್ಭದಲ್ಲಿಯೂ ಸಂಪರ್ಕದಲ್ಲಿರಲು <xliff:g id="VPN_APP_0">%1$s</xliff:g> ಅನ್ನು ಹೊಂದಿಸಲಾಗಿದೆ, ಆದರೆ ಸದ್ಯಕ್ಕೆ ಇದನ್ನು ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. <xliff:g id="VPN_APP_1">%1$s</xliff:g> ಮರು ಸಂಪರ್ಕಿಸುವವರೆಗೆ ನಿಮ್ಮ ಫೋನ್ ಸಾರ್ವಜನಿಕ ನೆಟ್‌ವರ್ಕ್‌ ಅನ್ನು ಬಳಸುತ್ತದೆ."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"ಎಲ್ಲಾ ಸಂದರ್ಭದಲ್ಲಿಯೂ ಸಂಪರ್ಕದಲ್ಲಿರಲು <xliff:g id="VPN_APP">%1$s</xliff:g> ಅನ್ನು ಹೊಂದಿಸಲಾಗಿದೆ, ಆದರೆ ಸದ್ಯಕ್ಕೆ ಇದನ್ನು ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. VPN ಅನ್ನು ಮರು ಸಂಪರ್ಕಿಸುವವರೆಗೆ ನೀವು ಸಂಪರ್ಕವನ್ನು ಹೊಂದಿರುವುದಿಲ್ಲ."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಿ"</string>
+    <string name="configure" msgid="4905518375574791375">"ಕಾನ್ಫಿಗರ್ ಮಾಡು"</string>
+    <string name="disconnect" msgid="971412338304200056">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸು"</string>
+    <string name="open_app" msgid="3717639178595958667">"ಅಪ್ಲಿಕೇಶನ್ ತೆರೆಯಿರಿ"</string>
+    <string name="dismiss" msgid="6192859333764711227">"ವಜಾಗೊಳಿಸಿ"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ko/strings.xml b/packages/VpnDialogs/res/values-ko/strings.xml
index b9c7ba1..6ad4976 100644
--- a/packages/VpnDialogs/res/values-ko/strings.xml
+++ b/packages/VpnDialogs/res/values-ko/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"연결 요청"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g>에서 네트워크 트래픽을 모니터링하도록 허용하는 VPN 연결을 설정하려고 합니다. 출처를 신뢰할 수 있는 경우에만 수락하세요. VPN이 활성화되면 &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt;이 화면 위에 표시됩니다."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN이 연결되었습니다."</string>
-    <string name="configure" msgid="4905518375574791375">"설정"</string>
-    <string name="disconnect" msgid="971412338304200056">"연결 끊기"</string>
     <string name="session" msgid="6470628549473641030">"세션:"</string>
     <string name="duration" msgid="3584782459928719435">"기간:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"보냄:"</string>
     <string name="data_received" msgid="4062776929376067820">"수신됨:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g>바이트/<xliff:g id="NUMBER_1">%2$s</xliff:g>패킷"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"연결 유지 VPN에 연결할 수 없음"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g>은(는) 항상 연결된 상태를 유지하도록 설정되어 있지만, 지금은 연결할 수 없습니다. <xliff:g id="VPN_APP_1">%1$s</xliff:g>에 다시 연결할 수 있을 때까지 휴대전화에서 공용 네트워크가 사용됩니다."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g>은(는) 항상 연결된 상태를 유지하도록 설정되어 있지만, 지금은 연결할 수 없습니다. VPN이 다시 연결될 때까지 인터넷에 연결할 수 없습니다."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN 설정 변경"</string>
+    <string name="configure" msgid="4905518375574791375">"설정"</string>
+    <string name="disconnect" msgid="971412338304200056">"연결 끊기"</string>
+    <string name="open_app" msgid="3717639178595958667">"앱 열기"</string>
+    <string name="dismiss" msgid="6192859333764711227">"닫기"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ky/strings.xml b/packages/VpnDialogs/res/values-ky/strings.xml
index 44fbabd..4e2f698 100644
--- a/packages/VpnDialogs/res/values-ky/strings.xml
+++ b/packages/VpnDialogs/res/values-ky/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Туташуу сурамы"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> тармактык трафикти көзөмөлдөөгө уруксат берген VPN туташуусун орноткусу келет. Аны булакка ишенсеңиз гана кабыл алыңыз. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; VPN иштеп турганда экраныңыздын жогору жагынан көрүнөт."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN байланышта"</string>
-    <string name="configure" msgid="4905518375574791375">"Конфигурациялоо"</string>
-    <string name="disconnect" msgid="971412338304200056">"Ажыратуу"</string>
     <string name="session" msgid="6470628549473641030">"Сессия:"</string>
     <string name="duration" msgid="3584782459928719435">"Узактыгы:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Жөнөтүлдү:"</string>
     <string name="data_received" msgid="4062776929376067820">"Келди:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> байт / <xliff:g id="NUMBER_1">%2$s</xliff:g> пакет"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Ар дайым күйүк VPN\'ге туташа албай жатат"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> тармагына ар дайым туташып турсун деп жөндөлгөн, бирок учурда телефонуңуз ага туташа албай жатат. <xliff:g id="VPN_APP_1">%1$s</xliff:g> тармагына кайра туташканга чейин телефонуңуз жалпыга ачык тармакты пайдаланып турат."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> тармагына ар дайым туташып турсун деп жөндөлгөн, бирок учурда телефонуңуз ага туташа албай жатат. VPN тармагына кайра туташмайынча, Интернет байланышыңыз жок болот."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN жөндөөлөрүн өзгөртүү"</string>
+    <string name="configure" msgid="4905518375574791375">"Конфигурациялоо"</string>
+    <string name="disconnect" msgid="971412338304200056">"Ажыратуу"</string>
+    <string name="open_app" msgid="3717639178595958667">"Колдонмону ачуу"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Четке кагуу"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-lo/strings.xml b/packages/VpnDialogs/res/values-lo/strings.xml
index 6248f8d..c591308 100644
--- a/packages/VpnDialogs/res/values-lo/strings.xml
+++ b/packages/VpnDialogs/res/values-lo/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"ການ​ຮ້ອງ​ຂໍ​ການ​ເຊື່ອມ​ຕໍ່"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> ຕ້ອງ​ການ​ຕັ້​ງ​ຄ່າ​ການ​ເຊື່ອມ​ຕໍ່ VPN ທີ່​ອະ​ນຸ​ຍາດ​ໃຫ້​ຕິດ​ຕາມ​ທຣາບ​ຟິກ​ເຄືອ​ຂ່າຍ​ໄດ້. ​ທ່ານ​​ຄວນ​​ຍິນຍອມ​ສະ​ເພາະ​ໃນ​ກໍ​ລະ​ນີ​ທີ່​ທ່ານ​ເຊື່ອ​ຖື​ແຫລ່ງ​ຂໍ້​ມູນ​ເທົ່າ​ນັ້ນ. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; ຈະ​ປາ​ກົດ​ຢູ່​ດ້ານ​ເທິງ​ຂອງ​ໜ້າ​ຈໍ​ເມື່ອ​ມີ​ການ​ເປີດ​ໃຊ້ VPN."</string>
     <string name="legacy_title" msgid="192936250066580964">"ເຊື່ອມຕໍ່ VPN ແລ້ວ"</string>
-    <string name="configure" msgid="4905518375574791375">"ປັບຄ່າ"</string>
-    <string name="disconnect" msgid="971412338304200056">"ຕັດການເຊື່ອມຕໍ່"</string>
     <string name="session" msgid="6470628549473641030">"ເຊສຊັນ:"</string>
     <string name="duration" msgid="3584782459928719435">"ໄລຍະເວລາ:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"ສົ່ງ:"</string>
     <string name="data_received" msgid="4062776929376067820">"ຮັບ:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ໄບ / <xliff:g id="NUMBER_1">%2$s</xliff:g> ແພັກເກັດ"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"ບໍ່ສາມາດເຊື່ອມຕໍ່ຫາ VPN ແບບເປີດຕະຫຼອດໄດ້"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> ຖືກຕັ້ງຄ່າເພື່ອເຊື່ອມຕໍ່ໄດ້ຕະຫຼອດເວລາ, ແຕ່ມັນບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້ໃນຕອນນີ້. ໂທລະສັບຂອງທ່ານຈະໃຊ້ເຄືອຂ່າຍສາທາລະນະຈົນກວ່າມັນຈະສາມາດເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP_1">%1$s</xliff:g> ໄດ້ອີກຄັ້ງ."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> ຖືກຕັ້ງຄ່າເພື່ອເຊື່ອມຕໍ່ໄດ້ຕະຫຼອດເວລາ, ແຕ່ມັນບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້ໃນຕອນນີ້. ທ່ານຈະບໍ່ມີການເຊື່ອມຕໍ່ຈົນກວ່າ VPN ຈະສາມາດເຊື່ອມຕໍ່ຄືນໃໝ່ໄດ້."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"ປ່ຽນການຕັ້ງຄ່າ VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"ປັບຄ່າ"</string>
+    <string name="disconnect" msgid="971412338304200056">"ຕັດການເຊື່ອມຕໍ່"</string>
+    <string name="open_app" msgid="3717639178595958667">"ເປີດແອັບ"</string>
+    <string name="dismiss" msgid="6192859333764711227">"ປິດໄວ້"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-lt/strings.xml b/packages/VpnDialogs/res/values-lt/strings.xml
index f70d55d..8846310 100644
--- a/packages/VpnDialogs/res/values-lt/strings.xml
+++ b/packages/VpnDialogs/res/values-lt/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Ryšio užklausa"</string>
     <string name="warning" msgid="809658604548412033">"„<xliff:g id="APP">%s</xliff:g>“ nori nustatyti VPN ryšį, kad galėtų stebėti tinklo srautą. Sutikite, tik jei pasitikite šaltiniu. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; rodoma ekrano viršuje, kai VPN aktyvus."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN prijungtas"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfigūruoti"</string>
-    <string name="disconnect" msgid="971412338304200056">"Atsijungti"</string>
     <string name="session" msgid="6470628549473641030">"Sesija"</string>
     <string name="duration" msgid="3584782459928719435">"Trukmė:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Išsiųsta"</string>
     <string name="data_received" msgid="4062776929376067820">"Gauta"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Baitų: <xliff:g id="NUMBER_0">%1$s</xliff:g> baitų / paketų: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Prisijungti prie visada įjungto VPN nepavyko"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"„<xliff:g id="VPN_APP_0">%1$s</xliff:g>“ nustatyta taip, kad prie jos visada būtų galima prisijungti, bet šiuo metu prisijungti nepavyksta. Kol vėl galės prisijungti prie „<xliff:g id="VPN_APP_1">%1$s</xliff:g>“, telefonas naudos viešąjį tinklą."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"„<xliff:g id="VPN_APP">%1$s</xliff:g>“ nustatyta taip, kad prie jos visada būtų galima prisijungti, bet šiuo metu prisijungti nepavyksta. Kol prie VPN bus galima prisijungti iš naujo, ryšio neturėsite."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Keisti VPN nustatymus"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfigūruoti"</string>
+    <string name="disconnect" msgid="971412338304200056">"Atsijungti"</string>
+    <string name="open_app" msgid="3717639178595958667">"Atidaryti programą"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Atsisakyti"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-lv/strings.xml b/packages/VpnDialogs/res/values-lv/strings.xml
index ff59d18..07625b6 100644
--- a/packages/VpnDialogs/res/values-lv/strings.xml
+++ b/packages/VpnDialogs/res/values-lv/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Savienojuma pieprasījums"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> vēlas izveidot VPN savienojumu, kas ļaus pārraudzīt tīkla datplūsmu. Piekrītiet tikai tad, ja uzticaties avotam. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; tiek rādīta ekrāna augšdaļā, kad darbojas VPN."</string>
     <string name="legacy_title" msgid="192936250066580964">"Ir izveidots savienojums ar VPN"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfigurēt"</string>
-    <string name="disconnect" msgid="971412338304200056">"Pārtraukt savienojumu"</string>
     <string name="session" msgid="6470628549473641030">"Sesija:"</string>
     <string name="duration" msgid="3584782459928719435">"Ilgums:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Nosūtīts:"</string>
     <string name="data_received" msgid="4062776929376067820">"Saņemts:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> baiti/<xliff:g id="NUMBER_1">%2$s</xliff:g> paketes"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Nevar izveidot savienojumu ar vienmēr ieslēgtu VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Lietotnei <xliff:g id="VPN_APP_0">%1$s</xliff:g> ir iestatīts vienmēr ieslēgts savienojums, taču pašlaik nevar izveidot savienojumu. Jūsu tālrunī tiks izmantots publisks tīkls, līdz varēs izveidot savienojumu ar lietotni <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Lietotnei <xliff:g id="VPN_APP">%1$s</xliff:g> ir iestatīts vienmēr ieslēgts savienojums, taču pašlaik nevar izveidot savienojumu. Savienojums būs pieejams, kad atkal varēs izveidot savienojumu ar VPN."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Mainīt VPN iestatījumus"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfigurēt"</string>
+    <string name="disconnect" msgid="971412338304200056">"Pārtraukt savienojumu"</string>
+    <string name="open_app" msgid="3717639178595958667">"Atvērt lietotni"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Nerādīt"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-mk/strings.xml b/packages/VpnDialogs/res/values-mk/strings.xml
index d835cfc..b5a64f2 100644
--- a/packages/VpnDialogs/res/values-mk/strings.xml
+++ b/packages/VpnDialogs/res/values-mk/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Барање за поврзување"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> сака да постави поврзување со ВПН коешто му дозволува да го набљудува сообраќајот на мрежата. Прифатете само доколку му верувате на изворот. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; се појавува на врвот на екранот кога ВПН е активна."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN е поврзана"</string>
-    <string name="configure" msgid="4905518375574791375">"Конфигурирај"</string>
-    <string name="disconnect" msgid="971412338304200056">"Исклучи"</string>
     <string name="session" msgid="6470628549473641030">"Сесија:"</string>
     <string name="duration" msgid="3584782459928719435">"Времетраење:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Испратено:"</string>
     <string name="data_received" msgid="4062776929376067820">"Примени:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> бајти / <xliff:g id="NUMBER_1">%2$s</xliff:g> пакети"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Не може да се поврзе на секогаш вклучената VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> е поставена да биде поврзана цело време, но не може да се поврзе во моментов. Вашиот телефон ќе користи јавна мрежа додека да се поврзе на <xliff:g id="VPN_APP_1">%1$s</xliff:g> повторно."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> е поставена да биде поврзана цело време, но не може да се поврзе во моментов. Нема да имате интернет сѐ додека VPN не се поврзе повторно."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Променете ги поставките за VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Конфигурирај"</string>
+    <string name="disconnect" msgid="971412338304200056">"Исклучи"</string>
+    <string name="open_app" msgid="3717639178595958667">"Отвори ја апликацијата"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Отфрли"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ml/strings.xml b/packages/VpnDialogs/res/values-ml/strings.xml
index 3dd76d8..680d0ef 100644
--- a/packages/VpnDialogs/res/values-ml/strings.xml
+++ b/packages/VpnDialogs/res/values-ml/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"കണക്ഷൻ അഭ്യർത്ഥന"</string>
     <string name="warning" msgid="809658604548412033">"നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കാൻ അനുവദിക്കുന്ന ഒരു VPN കണക്ഷൻ <xliff:g id="APP">%s</xliff:g> സജ്ജീകരിക്കേണ്ടതുണ്ട്. ഉറവിടം പരിചിതമാണെങ്കിൽ മാത്രം അംഗീകരിക്കുക. VPN സജീവമാകുമ്പോൾ &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; നിങ്ങളുടെ സ്ക്രീനിന്റെ മുകളിൽ ദൃശ്യമാകുന്നു."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN കണക്‌റ്റുചെയ്‌തു"</string>
-    <string name="configure" msgid="4905518375574791375">"കോൺഫിഗർ ചെയ്യുക"</string>
-    <string name="disconnect" msgid="971412338304200056">"വിച്ഛേദിക്കുക"</string>
     <string name="session" msgid="6470628549473641030">"സെഷൻ:"</string>
     <string name="duration" msgid="3584782459928719435">"സമയദൈര്‍ഘ്യം:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"അയച്ചത്:"</string>
     <string name="data_received" msgid="4062776929376067820">"ലഭിച്ചത്:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ബൈറ്റുകൾ / <xliff:g id="NUMBER_1">%2$s</xliff:g> പാക്കറ്റുകൾ"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"എപ്പോഴും ഓണായിരിക്കുന്ന VPN-ലേക്ക് കണക്‌റ്റുചെയ്യാനായില്ല"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"എപ്പോഴും കണക്‌റ്റുചെയ്‌ത നിലയിൽ തുടരാൻ <xliff:g id="VPN_APP_0">%1$s</xliff:g> സജ്ജമാക്കിയിരിക്കുന്നു, പക്ഷേ ഇപ്പോൾ കണക്‌റ്റുചെയ്യാനാകില്ല. <xliff:g id="VPN_APP_1">%1$s</xliff:g>-ലേക്ക് വീണ്ടും കണക്റ്റുചെയ്യുന്നതുവരെ നിങ്ങളുടെ ഫോൺ ഒരു പൊതു നെറ്റ്‌വർക്ക് ഉപയോഗിക്കും."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"എപ്പോഴും കണക്‌റ്റുചെയ്‌ത നിലയിൽ തുടരാൻ <xliff:g id="VPN_APP">%1$s</xliff:g> സജ്ജമാക്കിയിരിക്കുന്നു, പക്ഷേ ഇപ്പോൾ കണക്‌റ്റുചെയ്യാനാകില്ല. VPN വീണ്ടും കണക്റ്റുചെയ്യുന്നതുവരെ നിങ്ങൾക്ക് കണക്ഷനുണ്ടാകില്ല."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN ക്രമീകരണം മാറ്റുക"</string>
+    <string name="configure" msgid="4905518375574791375">"കോൺഫിഗർ ചെയ്യുക"</string>
+    <string name="disconnect" msgid="971412338304200056">"വിച്ഛേദിക്കുക"</string>
+    <string name="open_app" msgid="3717639178595958667">"ആപ്പ് തുറക്കുക"</string>
+    <string name="dismiss" msgid="6192859333764711227">"നിരസിക്കുക"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-mn/strings.xml b/packages/VpnDialogs/res/values-mn/strings.xml
index 1b6cb6c..9aa104a 100644
--- a/packages/VpnDialogs/res/values-mn/strings.xml
+++ b/packages/VpnDialogs/res/values-mn/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Холболтын хүсэлт"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> нь сүлжээний трафикыг хянах боломж бүхий VPN холболт үүсгэхийг хүсэж байна. Та зөвхөн эх үүсвэрт итгэж байгаа бол зөвшөөрнө үү. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; таны дэлгэц дээр VPN идэвхтэй үед гарч ирнэ."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN холбогдов"</string>
-    <string name="configure" msgid="4905518375574791375">"Тохируулах"</string>
-    <string name="disconnect" msgid="971412338304200056">"Салгах"</string>
     <string name="session" msgid="6470628549473641030">"Сешн:"</string>
     <string name="duration" msgid="3584782459928719435">"Үргэлжлэх хугацаа:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Илгээсэн:"</string>
     <string name="data_received" msgid="4062776929376067820">"Хүлээн авсан:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> байт/ <xliff:g id="NUMBER_1">%2$s</xliff:g> пакет"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Тогтмол асаалттай VPN-д холбогдох боломжгүй"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g>-г тогтмол холбогдсон байхаар тохируулсан ч яг одоо холбогдох боломжгүй байна. Таны утас <xliff:g id="VPN_APP_1">%1$s</xliff:g>-д дахин холбогдох хүртэл нийтийн сүлжээ ашиглана."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g>-г тогтмол холбогдсон байхаар тохируулсан ч яг одоо холбогдох боломжгүй байна. VPN дахин холбогдох хүртэл та сүлжээгүй байна."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN тохиргоог өөрчлөх"</string>
+    <string name="configure" msgid="4905518375574791375">"Тохируулах"</string>
+    <string name="disconnect" msgid="971412338304200056">"Салгах"</string>
+    <string name="open_app" msgid="3717639178595958667">"Апп нээх"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Хаах"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-mr/strings.xml b/packages/VpnDialogs/res/values-mr/strings.xml
index a325b90..129b7b1 100644
--- a/packages/VpnDialogs/res/values-mr/strings.xml
+++ b/packages/VpnDialogs/res/values-mr/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"कनेक्‍शन विनंती"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> नेटवर्क रहदारीचे परीक्षण करण्‍यासाठी त्यास अनुमती देणारे VPN कनेक्‍शन सेट करू इच्‍छितो. आपल्याला स्त्रोत विश्वसनीय वाटत असेल तरच स्वीकार करा. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; VPN सक्रिय असताना आपल्‍या स्क्रीनच्या शीर्षावर दिसते."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN कनेक्‍ट केले"</string>
-    <string name="configure" msgid="4905518375574791375">"कॉन्फिगर करा"</string>
-    <string name="disconnect" msgid="971412338304200056">"‍डिस्कनेक्ट करा"</string>
     <string name="session" msgid="6470628549473641030">"सत्र:"</string>
     <string name="duration" msgid="3584782459928719435">"कालावधी:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"प्रेषित:"</string>
     <string name="data_received" msgid="4062776929376067820">"प्राप्त झाले:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> बाइट / <xliff:g id="NUMBER_1">%2$s</xliff:g> पॅकेट"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"कायम चालू असलेल्या VPN शी कनेक्ट करू शकत नाही"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> हे पूर्ण वेळ कनेक्ट राहण्यासाठी सेट अप केलेले आहे, पण हे आता कनेक्ट होऊ शकत नाही. <xliff:g id="VPN_APP_1">%1$s</xliff:g> शी पुन्हा कनेक्ट होईपर्यंत तुमचा फोन सार्वजनिक नेटवर्क वापरेल."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> हे पूर्ण वेळ कनेक्ट राहण्यासाठी सेट अप केलेले आहे, पण हे आता कनेक्ट होऊ शकत नाही. VPN पुन्हा कनेक्ट होईपर्यंत तुमच्याकडे कनेक्शन नसेल."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN सेटिंग्ज बदला"</string>
+    <string name="configure" msgid="4905518375574791375">"कॉन्फिगर करा"</string>
+    <string name="disconnect" msgid="971412338304200056">"‍डिस्कनेक्ट करा"</string>
+    <string name="open_app" msgid="3717639178595958667">"अ‍ॅप उघडा"</string>
+    <string name="dismiss" msgid="6192859333764711227">"डिसमिस करा"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ms/strings.xml b/packages/VpnDialogs/res/values-ms/strings.xml
index 8ea682f..b489f2e 100644
--- a/packages/VpnDialogs/res/values-ms/strings.xml
+++ b/packages/VpnDialogs/res/values-ms/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Permintaan sambungan"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> ingin menyediakan sambungan VPN yang membenarkan apl memantau trafik rangkaian. Terima hanya jika anda mempercayai sumber. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; terpapar pada bahagian atas skrin anda apabila VPN aktif."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN telah disambungkan"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfigurasikan"</string>
-    <string name="disconnect" msgid="971412338304200056">"Putuskan sambungan"</string>
     <string name="session" msgid="6470628549473641030">"Sesi:"</string>
     <string name="duration" msgid="3584782459928719435">"Tempoh:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Dihantar:"</string>
     <string name="data_received" msgid="4062776929376067820">"Diterima:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bait / <xliff:g id="NUMBER_1">%2$s</xliff:g> bingkisan"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Tidak dapat menyambung ke VPN sentiasa hidup"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> disediakan untuk kekal bersambung pada sepanjang masa tetapi sambungan tidak dapat dibuat sekarang. Telefon anda akan menggunakan rangkaian awam sehingga dapat disambung semula ke <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> disediakan untuk kekal bersambung pada sepanjang masa tetapi sambungan tidak dapat dibuat sekarang. Sambungan tidak akan tersedia sehingga VPN dapat bersambung semula."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Tukar tetapan VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfigurasikan"</string>
+    <string name="disconnect" msgid="971412338304200056">"Putuskan sambungan"</string>
+    <string name="open_app" msgid="3717639178595958667">"Buka apl"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Ketepikan"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-my/strings.xml b/packages/VpnDialogs/res/values-my/strings.xml
index 6456c5e..9d60ff4 100644
--- a/packages/VpnDialogs/res/values-my/strings.xml
+++ b/packages/VpnDialogs/res/values-my/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"ချိတ်ဆက်ရန် တောင်းဆိုချက်"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> က ကွန်ရက် လုပ်ငန်းကို စောင့်ကြည့်ခွင့် ပြုမည့် VPN ချိတ်ဆက်မှုကို ထူထောင်လိုသည်။ ရင်းမြစ်ကို သင်က ယုံကြည်မှသာ လက်ခံပါ။ &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; မှာ VPN အလုပ်လုပ်နေလျှင် သင်၏ မျက်နှာပြင် ထိပ်မှာ ပေါ်လာမည်။"</string>
     <string name="legacy_title" msgid="192936250066580964">"VPNနှင့်ချိတ်ဆက်ထားသည်"</string>
-    <string name="configure" msgid="4905518375574791375">"ပုံပေါ်စေသည်"</string>
-    <string name="disconnect" msgid="971412338304200056">"ချိတ်ဆက်ခြင်းရပ်ရန်"</string>
     <string name="session" msgid="6470628549473641030">"သတ်မှတ်ပေးထားသည့်အချိန်:"</string>
     <string name="duration" msgid="3584782459928719435">"အချိန်ကာလ-"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"ပို့သည်-"</string>
     <string name="data_received" msgid="4062776929376067820">"လက်ခံရရှိသည်"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> packets"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"အမြဲပွင့်နေသော VPN ကို ချိတ်ဆက်၍မရပါ"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"အချိန်ပြည့် ချိတ်ဆက်နေရန် <xliff:g id="VPN_APP_0">%1$s</xliff:g> ကို စနစ်ထည့်သွင်းထားသော်လည်း ၎င်းသည် ယခု ချိတ်ဆက်၍မရနိုင်ပါ။ သင်၏ဖုန်းသည် <xliff:g id="VPN_APP_1">%1$s</xliff:g> ကို ပြန်လည်ချိတ်ဆက်၍ မရသေးမီ အများသုံးကွန်ရက်ကို အသုံးပြုပါမည်။"</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"အချိန်ပြည့် ချိတ်ဆက်နေရန် <xliff:g id="VPN_APP">%1$s</xliff:g> ကို စနစ်ထည့်သွင်းထားသော်လည်း ၎င်းသည် ယခု ချိတ်ဆက်၍မရနိုင်ပါ။ VPN ကို ပြန်လည်ချိတ်ဆက်၍ မရသေးမီ ချိတ်ဆက်မှုရရှိမည် မဟုတ်ပါ။"</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN ဆက်တင်များ ပြောင်းရန်"</string>
+    <string name="configure" msgid="4905518375574791375">"ပုံပေါ်စေသည်"</string>
+    <string name="disconnect" msgid="971412338304200056">"ချိတ်ဆက်ခြင်းရပ်ရန်"</string>
+    <string name="open_app" msgid="3717639178595958667">"အက်ပ်ကို ဖွင့်ရန်"</string>
+    <string name="dismiss" msgid="6192859333764711227">"ပယ်ရန်"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-nb/strings.xml b/packages/VpnDialogs/res/values-nb/strings.xml
index f99c2e7..b45d3b9 100644
--- a/packages/VpnDialogs/res/values-nb/strings.xml
+++ b/packages/VpnDialogs/res/values-nb/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Tilkoblingsforespørsel"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> ønsker å bruke en VPN-tilkobling som tillater at appen overvåker nettverkstrafikken. Du bør bare godta dette hvis du stoler på kilden. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; vises øverst på skjermen din når VPN er aktivert."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN er tilkoblet"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfigurer"</string>
-    <string name="disconnect" msgid="971412338304200056">"Koble fra"</string>
     <string name="session" msgid="6470628549473641030">"Økt:"</string>
     <string name="duration" msgid="3584782459928719435">"Varighet:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Sendt:"</string>
     <string name="data_received" msgid="4062776929376067820">"Mottatt:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> pakker"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Kan ikke koble til alltid på-VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> er konfigurert til å være tilkoblet hele tiden, men kan ikke kobles til for øyeblikket. Telefonen din kommer til å bruke et offentlig nettverk til den kan koble til <xliff:g id="VPN_APP_1">%1$s</xliff:g> igjen."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> er konfigurert til å være tilkoblet hele tiden, men kan ikke kobles til for øyeblikket. Du har ingen tilkobling før VPN-et kan kobles til igjen."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Endre VPN-innstillingene"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfigurer"</string>
+    <string name="disconnect" msgid="971412338304200056">"Koble fra"</string>
+    <string name="open_app" msgid="3717639178595958667">"Åpne appen"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Avvis"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ne/strings.xml b/packages/VpnDialogs/res/values-ne/strings.xml
index d3cf4355..c19ae52 100644
--- a/packages/VpnDialogs/res/values-ne/strings.xml
+++ b/packages/VpnDialogs/res/values-ne/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"जडान अनुरोध"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> ले नेटवर्क यातायात अनुगमन गर्न अनुमति दिने VPN जडान स्थापना गर्न चाहन्छ। तपाईँले स्रोत भरोसा छ भने मात्र स्वीकार गर्नुहोस्। &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; जब VPN सक्रिय हुन्छ आफ्नो स्क्रिनको माथि देखा पर्छन्।"</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN जोडिएको छ"</string>
-    <string name="configure" msgid="4905518375574791375">"कन्फिगर गर्नुहोस्"</string>
-    <string name="disconnect" msgid="971412338304200056">"विच्छेदन गर्नुहोस्"</string>
     <string name="session" msgid="6470628549473641030">"सत्र:"</string>
     <string name="duration" msgid="3584782459928719435">"अवधि:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"पठाइयो:"</string>
     <string name="data_received" msgid="4062776929376067820">"प्राप्त भयो:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> बाइटहरू / <xliff:g id="NUMBER_1">%2$s</xliff:g> प्याकेटहरू"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"सधैँ-सक्रिय रहने VPN सेवामा जडान गर्न सकिँदैन"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> लाई सधैँ जडान भइरहनेगरि सेट अप गरिएको छ तर यसलाई अहिले नै जडान गर्न मिल्दैन। तपाईंको फोन <xliff:g id="VPN_APP_1">%1$s</xliff:g> मा पुन: जडान नहुँदासम्म यसले कुनै सार्वजनिक नेटवर्क प्रयोग गर्नेछ।"</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> लाई सधैँ पनि जडान भइरहनेगरि सेट अप गरिएको छ तर यसलाई अहिले नै जडान गर्न मिल्दैन। VPN पुन: जडान नहुँदासम्म तपाईंसँग कुनै पनि इन्टरनेट रहनेछैन।"</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN सम्बन्धी सेटिङहरू परिवर्तन गर्नुहोस्"</string>
+    <string name="configure" msgid="4905518375574791375">"कन्फिगर गर्नुहोस्"</string>
+    <string name="disconnect" msgid="971412338304200056">"विच्छेदन गर्नुहोस्"</string>
+    <string name="open_app" msgid="3717639178595958667">"अनुप्रयोग खोल्नुहोस्"</string>
+    <string name="dismiss" msgid="6192859333764711227">"खारेज गर्नुहोस्"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-nl/strings.xml b/packages/VpnDialogs/res/values-nl/strings.xml
index ae789b2..8073b09 100644
--- a/packages/VpnDialogs/res/values-nl/strings.xml
+++ b/packages/VpnDialogs/res/values-nl/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Verbindingsverzoek"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> wil een VPN-verbinding opzetten om netwerkverkeer te controleren. Accepteer het verzoek alleen als je de bron vertrouwt. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; wordt boven aan je scherm weergegeven wanneer VPN actief is."</string>
     <string name="legacy_title" msgid="192936250066580964">"Verbinding met VPN"</string>
-    <string name="configure" msgid="4905518375574791375">"Configureren"</string>
-    <string name="disconnect" msgid="971412338304200056">"Verbinding verbreken"</string>
     <string name="session" msgid="6470628549473641030">"Sessie:"</string>
     <string name="duration" msgid="3584782459928719435">"Duur:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Verzonden:"</string>
     <string name="data_received" msgid="4062776929376067820">"Ontvangen:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes/<xliff:g id="NUMBER_1">%2$s</xliff:g> pakketten"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Kan geen verbinding maken met Always-on VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> is ingesteld om doorlopend verbinding te houden, maar kan nu geen verbinding maken. Je telefoon gebruikt een openbaar netwerk totdat deze opnieuw verbinding kan maken met <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> is ingesteld om doorlopend verbinding te houden, maar kan nu geen verbinding maken. Je hebt geen verbinding totdat het VPN opnieuw verbinding kan maken."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN-instellingen wijzigen"</string>
+    <string name="configure" msgid="4905518375574791375">"Configureren"</string>
+    <string name="disconnect" msgid="971412338304200056">"Verbinding verbreken"</string>
+    <string name="open_app" msgid="3717639178595958667">"App openen"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Sluiten"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-pa/strings.xml b/packages/VpnDialogs/res/values-pa/strings.xml
index 8e7c73d..1815f4f 100644
--- a/packages/VpnDialogs/res/values-pa/strings.xml
+++ b/packages/VpnDialogs/res/values-pa/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"ਕਨੈਕਸ਼ਨ ਬੇਨਤੀ"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> ਇੱਕ VPN ਕਨੈਕਸ਼ਨ ਸੈਟ ਅਪ ਕਰਨਾ ਚਾਹੁੰਦਾ ਹੈ ਜੋ ਇਸਨੂੰ ਨੈੱਟਵਰਕ ਟ੍ਰੈਫਿਕ ਦਾ ਨਿਰੀਖਣ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਕੇਵਲ ਤਾਂ ਹੀ ਸਵੀਕਾਰ ਕਰੋ ਜੇਕਰ ਤੁਸੀਂ ਸਰੋਤ ਤੇ ਭਰੋਸਾ ਕਰਦੇ ਹੋ। &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ ਦੇ ਟੌਪ ਤੇ ਪ੍ਰਗਟ ਹੁੰਦਾ ਹੈ ਜਦੋਂ VPN ਸਕਿਰਿਆ ਹੁੰਦਾ ਹੈ।"</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
-    <string name="configure" msgid="4905518375574791375">"ਕੌਂਫਿਗਰ ਕਰੋ"</string>
-    <string name="disconnect" msgid="971412338304200056">"ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
     <string name="session" msgid="6470628549473641030">"ਸੈਸ਼ਨ:"</string>
     <string name="duration" msgid="3584782459928719435">"ਮਿਆਦ:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"ਭੇਜਿਆ:"</string>
     <string name="data_received" msgid="4062776929376067820">"ਪ੍ਰਾਪਤ ਕੀਤਾ:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ਬਾਈਟਸ / <xliff:g id="NUMBER_1">%2$s</xliff:g> ਪੈਕੇਟਸ"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"ਹਮੇਸ਼ਾ-ਚਾਲੂ VPN ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> ਨੂੰ ਹਰ ਸਮੇਂ ਕਨੈਕਟ ਰਹਿਣ ਲਈ ਸਥਾਪਤ ਕੀਤਾ ਗਿਆ ਹੈ, ਪਰ ਇਹ ਫਿਲਹਾਲ ਕਨੈਕਟ ਨਹੀਂ ਹੋ ਸਕਦੀ। ਤੁਹਾਡਾ ਫ਼ੋਨ <xliff:g id="VPN_APP_1">%1$s</xliff:g> ਨਾਲ ਮੁੜ-ਕਨੈਕਟ ਹੋਣ ਤੱਕ ਕਿਸੇ ਜਨਤਕ ਨੈੱਟਵਰਕ ਦੀ ਵਰਤੋਂ ਕਰੇਗਾ।"</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> ਨੂੰ ਹਰ ਸਮੇਂ ਕਨੈਕਟ ਰਹਿਣ ਲਈ ਸਥਾਪਤ ਕੀਤਾ ਗਿਆ ਹੈ, ਪਰ ਇਹ ਫਿਲਹਾਲ ਕਨੈਕਟ ਨਹੀਂ ਹੋ ਸਕਦੀ। VPN ਨਾਲ ਮੁੜ-ਕਨੈਕਟ ਹੋਣ ਤੱਕ ਤੁਸੀਂ ਕਨੈਕਟ ਨਹੀਂ ਕਰ ਸਕਦੇ।"</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Change VPN settings"</string>
+    <string name="configure" msgid="4905518375574791375">"ਰੂਪ-ਰੇਖਾ ਬਦਲੋ"</string>
+    <string name="disconnect" msgid="971412338304200056">"ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
+    <string name="open_app" msgid="3717639178595958667">"ਐਪ ਖੋਲ੍ਹੋ"</string>
+    <string name="dismiss" msgid="6192859333764711227">"ਖਾਰਜ ਕਰੋ"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-pl/strings.xml b/packages/VpnDialogs/res/values-pl/strings.xml
index a8c08d51..be6a4c2 100644
--- a/packages/VpnDialogs/res/values-pl/strings.xml
+++ b/packages/VpnDialogs/res/values-pl/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Żądanie połączenia"</string>
     <string name="warning" msgid="809658604548412033">"Aplikacja <xliff:g id="APP">%s</xliff:g> chce utworzyć połączenie VPN, które pozwoli jej na monitorowanie ruchu sieciowego. Zaakceptuj, tylko jeśli masz zaufanie do źródła. Gdy sieć VPN jest aktywna, u góry ekranu pojawia się &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt;."</string>
     <string name="legacy_title" msgid="192936250066580964">"Połączono z VPN"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfiguruj"</string>
-    <string name="disconnect" msgid="971412338304200056">"Rozłącz"</string>
     <string name="session" msgid="6470628549473641030">"Sesja:"</string>
     <string name="duration" msgid="3584782459928719435">"Czas trwania:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Wysłano:"</string>
     <string name="data_received" msgid="4062776929376067820">"Odebrano:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Bajty: <xliff:g id="NUMBER_0">%1$s</xliff:g> / pakiety: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Nie można połączyć się ze stałą siecią VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Aplikacja <xliff:g id="VPN_APP_0">%1$s</xliff:g> jest skonfigurowana tak, by była cały czas połączona, ale teraz nie może się połączyć. Telefon będzie korzystał z sieci publicznej, aż zdoła się ponownie połączyć z aplikacją <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Aplikacja <xliff:g id="VPN_APP">%1$s</xliff:g> jest skonfigurowana tak, by była cały czas połączona, ale teraz nie może się połączyć. Połączenie nie będzie dostępne, aż urządzenie zdoła ponownie połączyć się z siecią VPN."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Zmień ustawienia sieci VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfiguruj"</string>
+    <string name="disconnect" msgid="971412338304200056">"Rozłącz"</string>
+    <string name="open_app" msgid="3717639178595958667">"Otwórz aplikację"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Zamknij"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-pt-rBR/strings.xml b/packages/VpnDialogs/res/values-pt-rBR/strings.xml
index e4154bc..9fdca9b 100644
--- a/packages/VpnDialogs/res/values-pt-rBR/strings.xml
+++ b/packages/VpnDialogs/res/values-pt-rBR/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Solicitação de conexão"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> quer configurar uma conexão VPN que permite monitorar o tráfego da rede. Aceite se confiar na origem. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; é exibido na parte superior da tela quando a VPN estiver ativa."</string>
     <string name="legacy_title" msgid="192936250066580964">"O VPN está conectado"</string>
-    <string name="configure" msgid="4905518375574791375">"Configurar"</string>
-    <string name="disconnect" msgid="971412338304200056">"Desconectar"</string>
     <string name="session" msgid="6470628549473641030">"Sessão:"</string>
     <string name="duration" msgid="3584782459928719435">"Duração:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Enviado:"</string>
     <string name="data_received" msgid="4062776929376067820">"Recebido:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes/<xliff:g id="NUMBER_1">%2$s</xliff:g> pacotes"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Não é possível se conectar à VPN sempre ativa"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> está configurada para permanecer conectada o tempo todo, mas não é possível conectá-la no momento. Seu smartphone usará uma rede pública até que possa se reconectar a <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> está definida para permanecer conectada o tempo todo, mas não é possível conectá-la no momento. Você não terá uma conexão até que a VPN possa se reconectar."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Alterar configurações de VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Configurar"</string>
+    <string name="disconnect" msgid="971412338304200056">"Desconectar"</string>
+    <string name="open_app" msgid="3717639178595958667">"Abrir app"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Dispensar"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-pt-rPT/strings.xml b/packages/VpnDialogs/res/values-pt-rPT/strings.xml
index e3727c0..01beddb 100644
--- a/packages/VpnDialogs/res/values-pt-rPT/strings.xml
+++ b/packages/VpnDialogs/res/values-pt-rPT/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Pedido de ligação"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> pretende configurar uma ligação VPN que lhe permita monitorizar o tráfego de rede. Aceite apenas se confiar na fonte. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; aparece na parte superior do seu ecrã quando a VPN está ativa."</string>
     <string name="legacy_title" msgid="192936250066580964">"A VPN está ligada"</string>
-    <string name="configure" msgid="4905518375574791375">"Configurar"</string>
-    <string name="disconnect" msgid="971412338304200056">"Desligar"</string>
     <string name="session" msgid="6470628549473641030">"Sessão"</string>
     <string name="duration" msgid="3584782459928719435">"Duração:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Enviados:"</string>
     <string name="data_received" msgid="4062776929376067820">"Recebidos:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> pacotes"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Não é possível estabelecer ligação à VPN sempre ativada"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"A aplicação <xliff:g id="VPN_APP_0">%1$s</xliff:g> está configurada para se manter sempre ligada, mas, neste momento, não é possível estabelecer ligação. O seu telemóvel irá utilizar uma rede pública até conseguir restabelecer ligação à aplicação <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"A aplicação <xliff:g id="VPN_APP">%1$s</xliff:g> está configurada para se manter sempre ligada, mas, neste momento, não é possível estabelecer ligação. Não terá ligação até que a VPN a consiga restabelecer."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Alterar as definições da VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Configurar"</string>
+    <string name="disconnect" msgid="971412338304200056">"Desligar"</string>
+    <string name="open_app" msgid="3717639178595958667">"Abrir aplicação"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Ignorar"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-pt/strings.xml b/packages/VpnDialogs/res/values-pt/strings.xml
index e4154bc..9fdca9b 100644
--- a/packages/VpnDialogs/res/values-pt/strings.xml
+++ b/packages/VpnDialogs/res/values-pt/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Solicitação de conexão"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> quer configurar uma conexão VPN que permite monitorar o tráfego da rede. Aceite se confiar na origem. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; é exibido na parte superior da tela quando a VPN estiver ativa."</string>
     <string name="legacy_title" msgid="192936250066580964">"O VPN está conectado"</string>
-    <string name="configure" msgid="4905518375574791375">"Configurar"</string>
-    <string name="disconnect" msgid="971412338304200056">"Desconectar"</string>
     <string name="session" msgid="6470628549473641030">"Sessão:"</string>
     <string name="duration" msgid="3584782459928719435">"Duração:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Enviado:"</string>
     <string name="data_received" msgid="4062776929376067820">"Recebido:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes/<xliff:g id="NUMBER_1">%2$s</xliff:g> pacotes"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Não é possível se conectar à VPN sempre ativa"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> está configurada para permanecer conectada o tempo todo, mas não é possível conectá-la no momento. Seu smartphone usará uma rede pública até que possa se reconectar a <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> está definida para permanecer conectada o tempo todo, mas não é possível conectá-la no momento. Você não terá uma conexão até que a VPN possa se reconectar."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Alterar configurações de VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Configurar"</string>
+    <string name="disconnect" msgid="971412338304200056">"Desconectar"</string>
+    <string name="open_app" msgid="3717639178595958667">"Abrir app"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Dispensar"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ro/strings.xml b/packages/VpnDialogs/res/values-ro/strings.xml
index e2e1e44..4e60df2 100644
--- a/packages/VpnDialogs/res/values-ro/strings.xml
+++ b/packages/VpnDialogs/res/values-ro/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Solicitare de conexiune"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> dorește să configureze o conexiune VPN care să îi permită să monitorizeze traficul în rețea. Acceptați numai dacă aveți încredere în sursă. Atunci când conexiunea VPN este activă, &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; se afișează în partea de sus a ecranului."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN este conectat"</string>
-    <string name="configure" msgid="4905518375574791375">"Configurați"</string>
-    <string name="disconnect" msgid="971412338304200056">"Deconectați"</string>
     <string name="session" msgid="6470628549473641030">"Sesiune:"</string>
     <string name="duration" msgid="3584782459928719435">"Durată:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Trimise:"</string>
     <string name="data_received" msgid="4062776929376067820">"Primite:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g>   octeți/<xliff:g id="NUMBER_1">%2$s</xliff:g>   pachete"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Nu se poate conecta la rețeaua VPN activată permanent"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> este setată să rămână conectată permanent, dar momentan nu se poate conecta. Telefonul dvs. va folosi o rețea publică până când se va putea reconecta la <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> este setată să rămână conectată permanent, dar momentan nu se poate conecta. Nu veți avea conexiune până când se va putea reconecta rețeaua VPN."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Modificați setările VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Configurați"</string>
+    <string name="disconnect" msgid="971412338304200056">"Deconectați"</string>
+    <string name="open_app" msgid="3717639178595958667">"Deschideți aplicația"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Închideți"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ru/strings.xml b/packages/VpnDialogs/res/values-ru/strings.xml
index 0e89d8e..b9207a0 100644
--- a/packages/VpnDialogs/res/values-ru/strings.xml
+++ b/packages/VpnDialogs/res/values-ru/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Запрос на подключение"</string>
     <string name="warning" msgid="809658604548412033">"Приложение \"<xliff:g id="APP">%s</xliff:g>\" пытается подключиться к сети VPN, чтобы отслеживать трафик. Этот запрос следует принимать, только если вы доверяете источнику.<br/><br/>Когда подключение VPN активно, в верхней части экрана появляется значок &lt;img src=vpn_icon /&gt;."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN-подключение установлено"</string>
-    <string name="configure" msgid="4905518375574791375">"Настроить"</string>
-    <string name="disconnect" msgid="971412338304200056">"Разъединить"</string>
     <string name="session" msgid="6470628549473641030">"Сеанс:"</string>
     <string name="duration" msgid="3584782459928719435">"Продолжительность:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Отправлено:"</string>
     <string name="data_received" msgid="4062776929376067820">"Получено:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> Б; пакетов: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Нет подключения к постоянной VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"К сети \"<xliff:g id="VPN_APP_0">%1$s</xliff:g>\" настроено постоянное подключение, но сейчас установить его не удается. Телефон будет подключен к общедоступной сети до тех пор, пока сеть \"<xliff:g id="VPN_APP_1">%1$s</xliff:g>\" не станет доступна снова."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"К сети \"<xliff:g id="VPN_APP">%1$s</xliff:g>\" настроено постоянное подключение, но сейчас установить его не удается. Соединение будет отсутствовать до тех пор, пока сеть не станет доступна снова."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Изменить настройки VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Настроить"</string>
+    <string name="disconnect" msgid="971412338304200056">"Разъединить"</string>
+    <string name="open_app" msgid="3717639178595958667">"Открыть приложение"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Закрыть"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-si/strings.xml b/packages/VpnDialogs/res/values-si/strings.xml
index 5f54821..bb97a5d 100644
--- a/packages/VpnDialogs/res/values-si/strings.xml
+++ b/packages/VpnDialogs/res/values-si/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"සම්බන්ධතා ඉල්ලීම"</string>
     <string name="warning" msgid="809658604548412033">"ජාල තදබදය නිරීක්ෂණය කිරීමට ඉඩ දෙන VPN සම්බන්ධතාවක් සැකසීමට <xliff:g id="APP">%s</xliff:g> අවශ්‍යය වේ. ප්‍රභවය ඔබ විශ්වාස කරන්නේ නම් පමණක් පිළිගන්න. VPN සක්‍රිය විට &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt;."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN සම්බන්ධිතයි"</string>
-    <string name="configure" msgid="4905518375574791375">"වින්‍යාස කිරීම"</string>
-    <string name="disconnect" msgid="971412338304200056">"විසන්ධි කරන්න"</string>
     <string name="session" msgid="6470628549473641030">"සැසිය:"</string>
     <string name="duration" msgid="3584782459928719435">"කාල සීමාව:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"යවන ලද:"</string>
     <string name="data_received" msgid="4062776929376067820">"ලැබිණි:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"බයිට <xliff:g id="NUMBER_0">%1$s</xliff:g> / පැකැට්ටු <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"සැම විට ක්‍රියාත්මක VPN වෙත සම්බන්ධ විය නොහැක"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> සෑම විටම සම්බන්ධ වී තිබීමට සකසා ඇති නමුත් එය දැන් එයට සම්බන්ධ විය නොහැක. නැවත <xliff:g id="VPN_APP_1">%1$s</xliff:g> වෙත සම්බන්ධ වීමට හැකි වන තුරු ඔබේ දුරකථනය පොදු ජාලයක් භාවිතා කරනු ඇත."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> සෑම විටම සම්බන්ධ වී තිබීමට සකසා ඇති නමුත් එය දැන් එයට සම්බන්ධ විය නොහැක. නැවත VPN  වෙත සම්බන්ධ වීමට හැකි වන තුරු ඔබට සබැඳුමක් නොමැති වනු ඇත."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN සැකසීම් වෙනස් කරන්න"</string>
+    <string name="configure" msgid="4905518375574791375">"වින්‍යාස කිරීම"</string>
+    <string name="disconnect" msgid="971412338304200056">"විසන්ධි කරන්න"</string>
+    <string name="open_app" msgid="3717639178595958667">"යෙදුම විවෘත කරන්න"</string>
+    <string name="dismiss" msgid="6192859333764711227">"ඉවතලන්න"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sk/strings.xml b/packages/VpnDialogs/res/values-sk/strings.xml
index b7ce966..0002964 100644
--- a/packages/VpnDialogs/res/values-sk/strings.xml
+++ b/packages/VpnDialogs/res/values-sk/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Žiadosť o pripojenie"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> žiada o nastavenie pripojenia VPN, pomocou ktorého bude môcť sledovať sieťové prenosy. Povoľte iba v prípade, že zdroju dôverujete. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; sa zobrazuje v hornej časti obrazovky, keď je pripojenie VPN aktívne."</string>
     <string name="legacy_title" msgid="192936250066580964">"Sieť VPN je pripojená"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfigurovať"</string>
-    <string name="disconnect" msgid="971412338304200056">"Odpojiť"</string>
     <string name="session" msgid="6470628549473641030">"Relácia"</string>
     <string name="duration" msgid="3584782459928719435">"Trvanie:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Odoslané:"</string>
     <string name="data_received" msgid="4062776929376067820">"Prijaté:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> B/<xliff:g id="NUMBER_1">%2$s</xliff:g> paketov"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Nedá sa pripojiť k vždy zapnutej sieti VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Sieť <xliff:g id="VPN_APP_0">%1$s</xliff:g> je nastavená, aby bola neustále pripojená, ale momentálne sa nedokáže pripojiť. Než sa telefón bude môcť znova pripojiť k sieti <xliff:g id="VPN_APP_1">%1$s</xliff:g>, bude používať verejnú sieť."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Sieť <xliff:g id="VPN_APP">%1$s</xliff:g> je nastavená, aby bola neustále pripojená, ale momentálne sa nedokáže pripojiť. Než sa sieť VPN znova pripojí, nebudete mať pripojenie."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Zmeniť nastavenia VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfigurovať"</string>
+    <string name="disconnect" msgid="971412338304200056">"Odpojiť"</string>
+    <string name="open_app" msgid="3717639178595958667">"Otvoriť aplikáciu"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Zrušiť"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sl/strings.xml b/packages/VpnDialogs/res/values-sl/strings.xml
index 9955c89..d5014fa34 100644
--- a/packages/VpnDialogs/res/values-sl/strings.xml
+++ b/packages/VpnDialogs/res/values-sl/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Zahteva za povezavo"</string>
     <string name="warning" msgid="809658604548412033">"Aplikacija <xliff:g id="APP">%s</xliff:g> želi nastaviti povezavo VPN, ki omogoča nadzor omrežnega prometa. To sprejmite samo, če zaupate viru. Ko je povezava VPN aktivna, se na vrhu zaslona prikaže ikona &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt;."</string>
     <string name="legacy_title" msgid="192936250066580964">"Povezava z navideznim zasebnim omrežjem je vzpostavljena"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfiguriranje"</string>
-    <string name="disconnect" msgid="971412338304200056">"Prekini povezavo"</string>
     <string name="session" msgid="6470628549473641030">"Seja:"</string>
     <string name="duration" msgid="3584782459928719435">"Trajanje:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Poslano:"</string>
     <string name="data_received" msgid="4062776929376067820">"Prejeto:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Št. bajtov: <xliff:g id="NUMBER_0">%1$s</xliff:g>/št. paketov: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Povezave s stalno vklopljenim VPN-jem ni mogoče vzpostaviti"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Omrežje <xliff:g id="VPN_APP_0">%1$s</xliff:g> je nastavljeno na stalno povezanost, vendar povezave trenutno ni mogoče vzpostaviti. Telefon bo uporabljal javno omrežje, dokler znova ne vzpostavi povezave z omrežjem <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Omrežje <xliff:g id="VPN_APP">%1$s</xliff:g> je nastavljeno na stalno povezanost, vendar povezave trenutno ni mogoče vzpostaviti. Brez povezave boste, dokler se znova ne vzpostavi povezava z omrežjem VPN."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Spremenite nastavitve omrežja VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfiguriranje"</string>
+    <string name="disconnect" msgid="971412338304200056">"Prekini povezavo"</string>
+    <string name="open_app" msgid="3717639178595958667">"Odpri aplikacijo"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Opusti"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sq/strings.xml b/packages/VpnDialogs/res/values-sq/strings.xml
index 8dc8bfb..4a96e7b 100644
--- a/packages/VpnDialogs/res/values-sq/strings.xml
+++ b/packages/VpnDialogs/res/values-sq/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Kërkesë për lidhje"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> kërkon të vendosë një lidhje VPN-je që e lejon të monitorojë trafikun e rrjetit. Prano vetëm nëse i beson burimit. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; shfaqet në krye të ekranit kur VPN-ja është aktive."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN-ja është e lidhur"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfiguro"</string>
-    <string name="disconnect" msgid="971412338304200056">"Shkëputu"</string>
     <string name="session" msgid="6470628549473641030">"Sesioni:"</string>
     <string name="duration" msgid="3584782459928719435">"Kohëzgjatja:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Dërguar:"</string>
     <string name="data_received" msgid="4062776929376067820">"Marrë:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bajte / <xliff:g id="NUMBER_1">%2$s</xliff:g> paketa"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Nuk mund të lidhet me VPN-në gjithmonë të aktivizuar"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> është konfiguruar për të qëndruar i lidhur gjatë të gjithë kohës, por nuk mund të lidhet në këtë moment. Telefoni yt do të përdorë një rrjet publik derisa të arrijë të rilidhet me <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> është konfiguruar për të qëndruar i lidhur gjatë të gjithë kohës, por nuk mund të lidhet në këtë moment. Nuk do të kesh një lidhje derisa VPN të arrijë të rilidhet."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Ndrysho cilësimet e VPN-së"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfiguro"</string>
+    <string name="disconnect" msgid="971412338304200056">"Shkëputu"</string>
+    <string name="open_app" msgid="3717639178595958667">"Hap aplikacionin"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Largoje"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sr/strings.xml b/packages/VpnDialogs/res/values-sr/strings.xml
index 97d9d9a..8ce8060 100644
--- a/packages/VpnDialogs/res/values-sr/strings.xml
+++ b/packages/VpnDialogs/res/values-sr/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Захтев за повезивање"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> жели да подеси VPN везу која омогућава праћење саобраћаја на мрежи. Прихватите само ако верујете извору. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; се приказује у врху екрана када је VPN активан."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN је повезан"</string>
-    <string name="configure" msgid="4905518375574791375">"Конфигуриши"</string>
-    <string name="disconnect" msgid="971412338304200056">"Прекини везу"</string>
     <string name="session" msgid="6470628549473641030">"Сесија:"</string>
     <string name="duration" msgid="3584782459928719435">"Трајање:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Послато:"</string>
     <string name="data_received" msgid="4062776929376067820">"Примљенo:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> бајт(ов)а / <xliff:g id="NUMBER_1">%2$s</xliff:g> пакета"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Повезивање са увек укљученим VPN-ом није успело"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Мрежа <xliff:g id="VPN_APP_0">%1$s</xliff:g> је подешена да буде увек повезана, али тренутно не може да успостави везу. Телефон ће користити јавну мрежу док се поново не повеже са <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Мрежа <xliff:g id="VPN_APP">%1$s</xliff:g> је подешена да буде увек повезана, али тренутно не може да успостави везу. Нећете имати везу док се VPN поново не повеже."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Промени подешавања VPN-а"</string>
+    <string name="configure" msgid="4905518375574791375">"Конфигуриши"</string>
+    <string name="disconnect" msgid="971412338304200056">"Прекини везу"</string>
+    <string name="open_app" msgid="3717639178595958667">"Отвори апликацију"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Одбаци"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sv/strings.xml b/packages/VpnDialogs/res/values-sv/strings.xml
index 7204ff0..16b6a31 100644
--- a/packages/VpnDialogs/res/values-sv/strings.xml
+++ b/packages/VpnDialogs/res/values-sv/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Anslutningsförfrågan"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> vill starta en VPN-anslutning som tillåter att appen övervakar nätverkstrafiken. Godkänn endast detta om du litar på källan. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; visas längst upp på skärmen när VPN-anslutningen är aktiv."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN är anslutet"</string>
-    <string name="configure" msgid="4905518375574791375">"Konfigurera"</string>
-    <string name="disconnect" msgid="971412338304200056">"Koppla från"</string>
     <string name="session" msgid="6470628549473641030">"Session:"</string>
     <string name="duration" msgid="3584782459928719435">"Längd:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Skickat:"</string>
     <string name="data_received" msgid="4062776929376067820">"Mottaget:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte/<xliff:g id="NUMBER_1">%2$s</xliff:g> paket"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Det gick inte att ansluta till Always-on VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> är konfigurerad att vara ansluten hela tiden, men det går inte att ansluta just nu. Mobilen använder ett offentligt nätverk tills den kan ansluta till <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> är konfigurerad att vara ansluten hela tiden, men det går inte att ansluta just nu. Du har ingen anslutning tills VPN-nätverket kan ansluta igen."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Ändra inställningarna för VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfigurera"</string>
+    <string name="disconnect" msgid="971412338304200056">"Koppla från"</string>
+    <string name="open_app" msgid="3717639178595958667">"Öppna appen"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Ignorera"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sw/strings.xml b/packages/VpnDialogs/res/values-sw/strings.xml
index e48210c..ea26884 100644
--- a/packages/VpnDialogs/res/values-sw/strings.xml
+++ b/packages/VpnDialogs/res/values-sw/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Ombi la muunganisho"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> inataka kusanidi muunganisho wa VPN utakaoiruhusu kufuatilia shughuli kwenye mtandao. Kubali ikiwa tu unakiamini chanzo. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; huonekana sehemu ya juu ya skrini yako VPN inapofanya kazi."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN imeunganishwa"</string>
-    <string name="configure" msgid="4905518375574791375">"Sanidi"</string>
-    <string name="disconnect" msgid="971412338304200056">"Tenganisha"</string>
     <string name="session" msgid="6470628549473641030">"Kipindi:"</string>
     <string name="duration" msgid="3584782459928719435">"Muda:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Zilizotumwa:"</string>
     <string name="data_received" msgid="4062776929376067820">"Imepokelewa:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"baiti <xliff:g id="NUMBER_0">%1$s</xliff:g> / pakiti <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Imeshindwa kuunganisha kwenye VPN iliyowashwa kila wakati"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Mipangilio ya <xliff:g id="VPN_APP_0">%1$s</xliff:g> imewekwa ili ibaki kuwa imeunganishwa kila wakati, lakini haiwezi kuunganisha sasa hivi. Simu yako itatumia mtandao wa umma hadi itakapounganishwa tena kwenye <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Mipangilio ya <xliff:g id="VPN_APP">%1$s</xliff:g> imewekwa ili ibaki kuwa imeunganishwa kila wakati, lakini haiwezi kuunganisha sasa hivi. Hutapata muunganisho hadi VPN iunganishwe tena."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Badilisha mipangilio ya VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Sanidi"</string>
+    <string name="disconnect" msgid="971412338304200056">"Tenganisha"</string>
+    <string name="open_app" msgid="3717639178595958667">"Fungua programu"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Ondoa"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ta/strings.xml b/packages/VpnDialogs/res/values-ta/strings.xml
index f03d3e4..81a1984 100644
--- a/packages/VpnDialogs/res/values-ta/strings.xml
+++ b/packages/VpnDialogs/res/values-ta/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"இணைப்புக் கோரிக்கை"</string>
     <string name="warning" msgid="809658604548412033">"VPN இணைப்பை அமைக்க <xliff:g id="APP">%s</xliff:g> விழைகிறது அதன்மூலம் இது நெட்வொர்க் ட்ராஃபிக்கைக் கண்காணிக்கும் அனுமதியைப் பெறும். நம்பகமான மூலத்தை மட்டுமே ஏற்கவும். VPN இயக்கத்தில் உள்ளபோது திரையில் மேல் பகுதியில் &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; தோன்றும்."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN இணைக்கப்பட்டது"</string>
-    <string name="configure" msgid="4905518375574791375">"உள்ளமை"</string>
-    <string name="disconnect" msgid="971412338304200056">"தொடர்பைத் துண்டி"</string>
     <string name="session" msgid="6470628549473641030">"அமர்வு:"</string>
     <string name="duration" msgid="3584782459928719435">"காலஅளவு:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"அனுப்பியது:"</string>
     <string name="data_received" msgid="4062776929376067820">"பெறப்பட்டது:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> பைட்கள் / <xliff:g id="NUMBER_1">%2$s</xliff:g> தொகுப்பு"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"எப்போதும் இயக்கத்தில் இருக்கும்படி அமைத்த VPN உடன் இணைக்க முடியவில்லை"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"எப்போதும் இணைந்திருக்கும் வகையில் <xliff:g id="VPN_APP_0">%1$s</xliff:g> அமைக்கப்பட்டது, எனினும் இப்போது இணைக்க முடியவில்லை. <xliff:g id="VPN_APP_1">%1$s</xliff:g> உடன் மீண்டும் இணையும் வரை, பொது நெட்வொர்க்கை உங்கள் மொபைல் பயன்படுத்தும்."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"எப்போதும் இணைந்திருக்கும் வகையில் <xliff:g id="VPN_APP">%1$s</xliff:g> அமைக்கப்பட்டது, எனினும் இப்போது இணைக்க முடியவில்லை. VPN உடன் மீண்டும் இணையும் வரை, உங்களுக்கு இணைய இணைப்பு இருக்காது."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN அமைப்புகளை மாற்று"</string>
+    <string name="configure" msgid="4905518375574791375">"உள்ளமை"</string>
+    <string name="disconnect" msgid="971412338304200056">"தொடர்பைத் துண்டி"</string>
+    <string name="open_app" msgid="3717639178595958667">"பயன்பாட்டைத் திற"</string>
+    <string name="dismiss" msgid="6192859333764711227">"நிராகரி"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-te/strings.xml b/packages/VpnDialogs/res/values-te/strings.xml
index 609b74d..864c926 100644
--- a/packages/VpnDialogs/res/values-te/strings.xml
+++ b/packages/VpnDialogs/res/values-te/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"కనెక్షన్ అభ్యర్థన"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> నెట్‌వర్క్ ట్రాఫిక్‌ని పర్యవేక్షించగలగడానికి VPN కనెక్షన్‌ను సెటప్ చేయాలనుకుంటోంది. మీరు మూలాన్ని విశ్వసిస్తే మాత్రమే ఆమోదించండి. VPN సక్రియంగా ఉన్నప్పుడు మీ స్క్రీన్ ఎగువన &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; కనిపిస్తుంది."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN కనెక్ట్ చేయబడింది"</string>
-    <string name="configure" msgid="4905518375574791375">"కాన్ఫిగర్ చేయి"</string>
-    <string name="disconnect" msgid="971412338304200056">"డిస్‌కనెక్ట్ చేయి"</string>
     <string name="session" msgid="6470628549473641030">"సెషన్:"</string>
     <string name="duration" msgid="3584782459928719435">"వ్యవధి:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"పంపినది:"</string>
     <string name="data_received" msgid="4062776929376067820">"స్వీకరించినది:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> బైట్లు / <xliff:g id="NUMBER_1">%2$s</xliff:g> ప్యాకెట్‌లు"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"ఎల్లప్పుడూ ఆన్‌లో ఉండే VPNకి కనెక్ట్ చేయడం సాధ్యపడదు"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"ఎల్లప్పుడూ కనెక్ట్ అయి ఉండడానికి <xliff:g id="VPN_APP_0">%1$s</xliff:g> సెటప్ చేయబడింది, కానీ దాన్ని ఇప్పుడు కనెక్ట్ చేయడానికి సాధ్యపడదు. మీ ఫోన్ <xliff:g id="VPN_APP_1">%1$s</xliff:g>కి మళ్లీ కనెక్ట్ అయ్యేంతవరకు అది పబ్లిక్ నెట్‌వర్క్‌ని ఉపయోగిస్తుంది."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"ఎల్లప్పుడూ కనెక్ట్ అయి ఉండడానికి <xliff:g id="VPN_APP">%1$s</xliff:g> సెటప్ చేయబడింది, కానీ దాన్ని ఇప్పుడు కనెక్ట్ చేయడానికి సాధ్యపడదు. VPN మళ్లీ కనెక్ట్ అవగలిగేంతవరకు మీకు కనెక్షన్ ఉండదు."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN సెట్టింగ్‌లను మార్చండి"</string>
+    <string name="configure" msgid="4905518375574791375">"కాన్ఫిగర్ చేయి"</string>
+    <string name="disconnect" msgid="971412338304200056">"డిస్‌కనెక్ట్ చేయి"</string>
+    <string name="open_app" msgid="3717639178595958667">"యాప్‌ని తెరవండి"</string>
+    <string name="dismiss" msgid="6192859333764711227">"తీసివేయండి"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-th/strings.xml b/packages/VpnDialogs/res/values-th/strings.xml
index 1b5f0a8..f6dfca5 100644
--- a/packages/VpnDialogs/res/values-th/strings.xml
+++ b/packages/VpnDialogs/res/values-th/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"ขอการเชื่อมต่อ"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> ต้องการติดตั้งการเชื่อมต่อ VPN เพื่อให้แอปสามารถตรวจสอบการเข้าใช้งานเครือข่าย โปรดยอมรับหากคุณเชื่อถือแหล่งที่มานี้เท่านั้น &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; จะปรากฏที่ด้านบนหน้าจอเมื่อมีการใช้งาน VPN อยู่"</string>
     <string name="legacy_title" msgid="192936250066580964">"เชื่อมต่อ VPN แล้ว"</string>
-    <string name="configure" msgid="4905518375574791375">"กำหนดค่า"</string>
-    <string name="disconnect" msgid="971412338304200056">"ยกเลิกการเชื่อมต่อ"</string>
     <string name="session" msgid="6470628549473641030">"เซสชัน"</string>
     <string name="duration" msgid="3584782459928719435">"ระยะเวลา:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"ส่งแล้ว:"</string>
     <string name="data_received" msgid="4062776929376067820">"รับแล้ว:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ไบต์/<xliff:g id="NUMBER_1">%2$s</xliff:g> แพ็คเก็ต"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"ไม่สามารถเชื่อมต่อ VPN แบบเปิดตลอดเวลา"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> ตั้งค่าให้เชื่อมต่อตลอดเวลา แต่ไม่สามารถเชื่อมต่อได้ในขณะนี้ โทรศัพท์จะใช้เครือข่ายสาธารณะจนกว่าจะสามารถเชื่อมต่อ <xliff:g id="VPN_APP_1">%1$s</xliff:g> ได้อีกครั้ง"</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> ตั้งค่าให้เชื่อมต่อตลอดเวลา แต่ไม่สามารถเชื่อมต่อได้ในขณะนี้ คุณจะขาดการเชื่อมต่อจนกว่า VPN จะสามารถเชื่อมต่ออีกครั้ง"</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"เปลี่ยนการตั้งค่า VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"กำหนดค่า"</string>
+    <string name="disconnect" msgid="971412338304200056">"ยกเลิกการเชื่อมต่อ"</string>
+    <string name="open_app" msgid="3717639178595958667">"เปิดแอป"</string>
+    <string name="dismiss" msgid="6192859333764711227">"ปิด"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-tl/strings.xml b/packages/VpnDialogs/res/values-tl/strings.xml
index a115ae5..9c01c32 100644
--- a/packages/VpnDialogs/res/values-tl/strings.xml
+++ b/packages/VpnDialogs/res/values-tl/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Kahilingan sa koneksyon"</string>
     <string name="warning" msgid="809658604548412033">"Gusto ng <xliff:g id="APP">%s</xliff:g> na mag-set up ng koneksyon sa VPN na nagbibigay-daan ditong masubaybayan ang trapiko ng network. Tanggapin lang kung pinagkakatiwalaan mo ang pinagmulan. Lalabas ang &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; sa itaas ng iyong screen kapag aktibo ang VPN."</string>
     <string name="legacy_title" msgid="192936250066580964">"Nakakonekta ang VPN"</string>
-    <string name="configure" msgid="4905518375574791375">"I-configure"</string>
-    <string name="disconnect" msgid="971412338304200056">"Idiskonekta"</string>
     <string name="session" msgid="6470628549473641030">"Session:"</string>
     <string name="duration" msgid="3584782459928719435">"Tagal:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Ipinadala:"</string>
     <string name="data_received" msgid="4062776929376067820">"Natanggap:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> (na) byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> (na) packet"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Hindi makakonekta sa VPN na palaging naka-on"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Naka-set up ang <xliff:g id="VPN_APP_0">%1$s</xliff:g> na manatiling nakakonekta sa lahat ng oras, ngunit hindi ito makakonekta sa ngayon. Gagamit ng pampublikong network ang iyong telepono hanggang sa muli itong makakonekta sa <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Naka-set up ang <xliff:g id="VPN_APP">%1$s</xliff:g> na manatiling nakakonekta sa lahat ng oras, ngunit hindi ito makakonekta sa ngayon. Hindi ka magkakaroon ng koneksyon hanggang sa muling makakonekta ang VPN."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Baguhin ang mga setting ng VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"I-configure"</string>
+    <string name="disconnect" msgid="971412338304200056">"Idiskonekta"</string>
+    <string name="open_app" msgid="3717639178595958667">"Buksan ang app"</string>
+    <string name="dismiss" msgid="6192859333764711227">"I-dismiss"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-tr/strings.xml b/packages/VpnDialogs/res/values-tr/strings.xml
index abebeca..8665a47 100644
--- a/packages/VpnDialogs/res/values-tr/strings.xml
+++ b/packages/VpnDialogs/res/values-tr/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Bağlantı isteği"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> ağ trafiğini izlemesine olanak veren bir VPN bağlantısı oluşturmak istiyor. Sadece, ilgili kaynağa güveniyorsanız kabul edin. &lt;br /&gt; &lt;br /&gt; VPN aktif olduğunda ekranınızın üst tarafında &lt;img src=vpn_icon /&gt; simgesi görünür."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN bağlı"</string>
-    <string name="configure" msgid="4905518375574791375">"Yapılandır"</string>
-    <string name="disconnect" msgid="971412338304200056">"Bağlantıyı kes"</string>
     <string name="session" msgid="6470628549473641030">"Oturum:"</string>
     <string name="duration" msgid="3584782459928719435">"Süre:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Gönderilen:"</string>
     <string name="data_received" msgid="4062776929376067820">"Alınan:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bayt / <xliff:g id="NUMBER_1">%2$s</xliff:g> paket"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Her zaman açık VPN\'ye bağlanılamıyor"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> sürekli bağlantıda kalacak şekilde ayarlandı, ancak şu anda bağlanamıyor. <xliff:g id="VPN_APP_1">%1$s</xliff:g> uygulamasına bağlanana kadar telefonunuz genel bir ağı kullanacak."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> sürekli bağlantıda kalacak şekilde ayarlandı, ancak şu anda bağlanamıyor. VPN bağlanana kadar bağlantınız olmayacak."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN ayarlarını değiştir"</string>
+    <string name="configure" msgid="4905518375574791375">"Yapılandır"</string>
+    <string name="disconnect" msgid="971412338304200056">"Bağlantıyı kes"</string>
+    <string name="open_app" msgid="3717639178595958667">"Uygulamayı aç"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Kapat"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-uk/strings.xml b/packages/VpnDialogs/res/values-uk/strings.xml
index eed37ee..8f91abf 100644
--- a/packages/VpnDialogs/res/values-uk/strings.xml
+++ b/packages/VpnDialogs/res/values-uk/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Запит на під’єднання"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> хоче під’єднатися до мережі VPN, щоб контролювати мережевий трафік. Дозволяйте, якщо довіряєте джерелу. Коли мережа VPN активна, угорі екрана відображається значок &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt;."</string>
     <string name="legacy_title" msgid="192936250066580964">"Мережу VPN під’єднано"</string>
-    <string name="configure" msgid="4905518375574791375">"Налаштувати"</string>
-    <string name="disconnect" msgid="971412338304200056">"Від’єднати"</string>
     <string name="session" msgid="6470628549473641030">"Сеанс:"</string>
     <string name="duration" msgid="3584782459928719435">"Тривалість:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Надіслано:"</string>
     <string name="data_received" msgid="4062776929376067820">"Отримано:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Байтів: <xliff:g id="NUMBER_0">%1$s</xliff:g> / пакетів: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Не вдається під’єднатися до постійної мережі VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Для додатка <xliff:g id="VPN_APP_0">%1$s</xliff:g> налаштовано режим постійного з’єднання, однак наразі не вдається під’єднатися. Телефон використовуватиме загальнодоступну мережу, доки знову не під’єднається до <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Для додатка <xliff:g id="VPN_APP">%1$s</xliff:g> налаштовано режим постійного з’єднання, однак наразі не вдається під’єднатися. З’єднання не буде, доки не відновиться під’єднання до мережі VPN."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Змінити налаштування мережі VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Налаштувати"</string>
+    <string name="disconnect" msgid="971412338304200056">"Від’єднати"</string>
+    <string name="open_app" msgid="3717639178595958667">"Відкрити додаток"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Закрити"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ur/strings.xml b/packages/VpnDialogs/res/values-ur/strings.xml
index 34f72c8..db0c297 100644
--- a/packages/VpnDialogs/res/values-ur/strings.xml
+++ b/packages/VpnDialogs/res/values-ur/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"کنکشن کی درخواست"</string>
     <string name="warning" msgid="809658604548412033">"‏<xliff:g id="APP">%s</xliff:g> ایک ایسا VPN کنکشن ترتیب دینا چاہتی ہے جو اسے نیٹ ورک ٹریفک کو مانیٹر کرنے کی اجازت دیتا ہے۔ اگر آپ کو ماخذ پر بھروسہ ہے تبھی قبول کریں۔ &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; آپ کی اسکرین کے اوپر اس وقت ظاہر ہوتا ہے جب VPN فعال ہوتا ہے۔"</string>
     <string name="legacy_title" msgid="192936250066580964">"‏VPN مربوط ہے"</string>
-    <string name="configure" msgid="4905518375574791375">"ترتیب دیں"</string>
-    <string name="disconnect" msgid="971412338304200056">"منقطع کریں"</string>
     <string name="session" msgid="6470628549473641030">"سیشن:"</string>
     <string name="duration" msgid="3584782459928719435">"دورانیہ:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"ارسال کردہ:"</string>
     <string name="data_received" msgid="4062776929376067820">"موصولہ:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> بائٹس / <xliff:g id="NUMBER_1">%2$s</xliff:g> پیکٹس"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"‏ہمیشہ آن VPN سے منسلک نہیں کر سکتے"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> ہمہ وقت منسلک رہنے کے لئے سیٹ ہے۔ لیکن اسے فی الحال منسلک نہیں کیا جا سکتا۔ آپ کا فون <xliff:g id="VPN_APP_1">%1$s</xliff:g> سے دوبارہ منسلک ہونے تک ایک عوامی نیٹ ورک کا استعمال کرے گا۔"</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"‏<xliff:g id="VPN_APP">%1$s</xliff:g> ہمہ وقت منسلک رہنے کے لئے سیٹ ہے۔ لیکن اسے فی الحال منسلک نہیں کیا جا سکتا۔ آپ کے پاس VPN کے دوبارہ منسلک ہو پانے تک کنکشن نہیں ہوگا۔"</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"‏VPN کی ترتیبات تبدیل کریں"</string>
+    <string name="configure" msgid="4905518375574791375">"ترتیب دیں"</string>
+    <string name="disconnect" msgid="971412338304200056">"منقطع کریں"</string>
+    <string name="open_app" msgid="3717639178595958667">"ایپ کھولیں"</string>
+    <string name="dismiss" msgid="6192859333764711227">"برخاست کریں"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-uz/strings.xml b/packages/VpnDialogs/res/values-uz/strings.xml
index 69e3e29..5a348a0 100644
--- a/packages/VpnDialogs/res/values-uz/strings.xml
+++ b/packages/VpnDialogs/res/values-uz/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Ulanish uchun so‘rov"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> ilovasi trafikni kuzatish uchun VPN tarmog‘iga ulanmoqchi. Agar ilovaga ishonsangiz, so‘rovga rozi bo‘ling.&lt;br /&gt; &lt;br /&gt;VPN faol bo‘lsa, ekranning yuqori qismida &lt;img src=vpn_icon /&gt; belgisi paydo bo‘ladi."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN ulangan"</string>
-    <string name="configure" msgid="4905518375574791375">"Moslash"</string>
-    <string name="disconnect" msgid="971412338304200056">"Aloqani uzish"</string>
     <string name="session" msgid="6470628549473641030">"Seans:"</string>
     <string name="duration" msgid="3584782459928719435">"Davomiyligi:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Jo‘natildi:"</string>
     <string name="data_received" msgid="4062776929376067820">"Qabul qilingan:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bayt / <xliff:g id="NUMBER_1">%2$s</xliff:g> ta paket"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Doimiy VPN tarmoqqa ulanilmadi"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> ilovasi doim ulanib turiladigan qilib sozlangan, lekin hozirda ulana olmayapti. To <xliff:g id="VPN_APP_1">%1$s</xliff:g> ilovasiga qayta ulanmaguncha, telefoningiz ochiq tarmoqdan foydalanib turadi."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> ilovasi doim ulanib turiladigan qilib sozlangan, lekin hozirda ulana olmayapti. To VPN tarmoqqa qayta ulanmaguncha, hech qanday tarmoqqa ulanmay turiladi."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN sozlamalarini o‘zgartirish"</string>
+    <string name="configure" msgid="4905518375574791375">"Moslash"</string>
+    <string name="disconnect" msgid="971412338304200056">"Aloqani uzish"</string>
+    <string name="open_app" msgid="3717639178595958667">"Ilovani ochish"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Yopish"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-vi/strings.xml b/packages/VpnDialogs/res/values-vi/strings.xml
index c7df53f..fa5e114 100644
--- a/packages/VpnDialogs/res/values-vi/strings.xml
+++ b/packages/VpnDialogs/res/values-vi/strings.xml
@@ -17,13 +17,20 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="prompt" msgid="3183836924226407828">"Yêu cầu kết nối"</string>
-    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> muốn thiết lập kết nối VPN cho phép ứng dụng giám sát lưu lượng truy cập mạng. Chỉ chấp nhận nếu bạn tin tưởng nguồn. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; xuất hiện ở đầu màn hình của bạn khi VPN đang hoạt động."</string>
+    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> muốn thiết lập kết nối VPN cho phép ứng dụng giám sát lưu lượng truy cập mạng. Chỉ chấp nhận nếu bạn tin tưởng nguồn. Biểu tượng &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; xuất hiện ở đầu màn hình của bạn khi VPN đang hoạt động."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN được kết nối"</string>
-    <string name="configure" msgid="4905518375574791375">"Định cấu hình"</string>
-    <string name="disconnect" msgid="971412338304200056">"Ngắt kết nối"</string>
     <string name="session" msgid="6470628549473641030">"Phiên"</string>
     <string name="duration" msgid="3584782459928719435">"Thời lượng:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Đã gửi:"</string>
     <string name="data_received" msgid="4062776929376067820">"Đã nhận:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> gói"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Không thể kết nối với VPN luôn bật"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> được thiết lập để luôn duy trì kết nối nhưng hiện không thể kết nối. Điện thoại của bạn sẽ sử dụng mạng công cộng cho tới khi có thể kết nối lại với <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> được thiết lập để luôn duy trì kết nối nhưng hiện không thể kết nối. Bạn sẽ không có kết nối cho tới khi VPN này có thể kết nối lại."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Thay đổi cài đặt VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Định cấu hình"</string>
+    <string name="disconnect" msgid="971412338304200056">"Ngắt kết nối"</string>
+    <string name="open_app" msgid="3717639178595958667">"Mở ứng dụng"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Loại bỏ"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-zh-rCN/strings.xml b/packages/VpnDialogs/res/values-zh-rCN/strings.xml
index cdea95d6..2815312 100644
--- a/packages/VpnDialogs/res/values-zh-rCN/strings.xml
+++ b/packages/VpnDialogs/res/values-zh-rCN/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"网络连接请求"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g>想要设置一个VPN连接(可被用于监控网络流量)。请只在您信任该来源的情况下才接受此请求。在VPN处于活动状态时,您的屏幕顶部会显示 &lt;img src=vpn_icon /&gt; 图标。"</string>
     <string name="legacy_title" msgid="192936250066580964">"已连接VPN"</string>
-    <string name="configure" msgid="4905518375574791375">"配置"</string>
-    <string name="disconnect" msgid="971412338304200056">"断开连接"</string>
     <string name="session" msgid="6470628549473641030">"会话:"</string>
     <string name="duration" msgid="3584782459928719435">"时长:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"已发送:"</string>
     <string name="data_received" msgid="4062776929376067820">"已接收:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> 字节/<xliff:g id="NUMBER_1">%2$s</xliff:g> 个数据包"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"无法连接到始终开启的 VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g>已设为始终保持连接状态,但目前无法连接。您的手机将使用公共网络,直到能够重新连接到<xliff:g id="VPN_APP_1">%1$s</xliff:g>。"</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g>已设为始终保持连接状态,但目前无法连接。您将无法连接到网络,直到您能够重新连接该 VPN。"</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"更改 VPN 设置"</string>
+    <string name="configure" msgid="4905518375574791375">"配置"</string>
+    <string name="disconnect" msgid="971412338304200056">"断开连接"</string>
+    <string name="open_app" msgid="3717639178595958667">"打开应用"</string>
+    <string name="dismiss" msgid="6192859333764711227">"关闭"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-zh-rHK/strings.xml b/packages/VpnDialogs/res/values-zh-rHK/strings.xml
index fa77c6c..f70cd511 100644
--- a/packages/VpnDialogs/res/values-zh-rHK/strings.xml
+++ b/packages/VpnDialogs/res/values-zh-rHK/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"連線要求"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> 要求設定 VPN 連線以監控網絡流量。除非您信任要求來源,否則請勿隨意接受要求。&lt;br /&gt; &lt;br /&gt;VPN 啟用時,畫面頂端會顯示 &lt;img src=vpn_icon /&gt;。"</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN 已連線"</string>
-    <string name="configure" msgid="4905518375574791375">"設定"</string>
-    <string name="disconnect" msgid="971412338304200056">"中斷連線"</string>
     <string name="session" msgid="6470628549473641030">"時段:"</string>
     <string name="duration" msgid="3584782459928719435">"持續時間︰"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"已傳送:"</string>
     <string name="data_received" msgid="4062776929376067820">"已接收:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> 位元組 / <xliff:g id="NUMBER_1">%2$s</xliff:g> 封包"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"無法連線至永遠開啟的 VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> 已設定為隨時保持連線,但目前無法連線。在重新連線至 <xliff:g id="VPN_APP_1">%1$s</xliff:g> 前,您的手機將會使用公共網絡。"</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> 已設定為隨時保持連線,但目前無法連線。在重新連線至 VPN 前,您將無法連線至網絡。"</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"變更 VPN 設定"</string>
+    <string name="configure" msgid="4905518375574791375">"設定"</string>
+    <string name="disconnect" msgid="971412338304200056">"中斷連線"</string>
+    <string name="open_app" msgid="3717639178595958667">"開啟應用程式"</string>
+    <string name="dismiss" msgid="6192859333764711227">"關閉"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-zh-rTW/strings.xml b/packages/VpnDialogs/res/values-zh-rTW/strings.xml
index 6b35993..edd8e61 100644
--- a/packages/VpnDialogs/res/values-zh-rTW/strings.xml
+++ b/packages/VpnDialogs/res/values-zh-rTW/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"連線要求"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> 要求設定 VPN 連線,允許此要求即開放該來源監控網路流量。除非你信任該來源,否則請勿任意接受要求。&lt;br /&gt; &lt;br /&gt;VPN 啟用時,畫面頂端會顯示 &lt;img src=vpn_icon /&gt;。"</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN 已連線"</string>
-    <string name="configure" msgid="4905518375574791375">"設定"</string>
-    <string name="disconnect" msgid="971412338304200056">"中斷連線"</string>
     <string name="session" msgid="6470628549473641030">"工作階段:"</string>
     <string name="duration" msgid="3584782459928719435">"持續時間:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"已傳送:"</string>
     <string name="data_received" msgid="4062776929376067820">"已接收:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> 位元組 / <xliff:g id="NUMBER_1">%2$s</xliff:g> 個封包"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"無法連上永久連線的 VPN"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"「<xliff:g id="VPN_APP_0">%1$s</xliff:g>」設定為隨時保持連線,但目前無法連線。在重新連上「<xliff:g id="VPN_APP_1">%1$s</xliff:g>」之前,你的手機將會使用公用網路。"</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"「<xliff:g id="VPN_APP">%1$s</xliff:g>」設定為隨時保持連線,但目前無法連線。在重新連上 VPN 之前,你將無法連接網路。"</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"變更 VPN 設定"</string>
+    <string name="configure" msgid="4905518375574791375">"設定"</string>
+    <string name="disconnect" msgid="971412338304200056">"中斷連線"</string>
+    <string name="open_app" msgid="3717639178595958667">"開啟應用程式"</string>
+    <string name="dismiss" msgid="6192859333764711227">"關閉"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-zu/strings.xml b/packages/VpnDialogs/res/values-zu/strings.xml
index abe54a9..4ab1225 100644
--- a/packages/VpnDialogs/res/values-zu/strings.xml
+++ b/packages/VpnDialogs/res/values-zu/strings.xml
@@ -19,11 +19,18 @@
     <string name="prompt" msgid="3183836924226407828">"Isicelo soxhumo"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> ifuna ukusetha uxhumo lwe-VPN eyivumela ukwengamela ithrafikhi yenethiwekhi. Yamukela kuphela uma wethemba umthombo. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; ibonakala phezu kwesikrini sakho uma i-VPN isebenza."</string>
     <string name="legacy_title" msgid="192936250066580964">"I-VPN ixhunyiwe"</string>
-    <string name="configure" msgid="4905518375574791375">"Misa"</string>
-    <string name="disconnect" msgid="971412338304200056">"Ayixhumekile kwi-inthanethi"</string>
     <string name="session" msgid="6470628549473641030">"Iseshini:"</string>
     <string name="duration" msgid="3584782459928719435">"Ubude besikhathi:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Thunyelwe:"</string>
     <string name="data_received" msgid="4062776929376067820">"Okwamukelwe:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> amaphakethe/ <xliff:g id="NUMBER_1">%2$s</xliff:g> amabhayithi"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Ayikwazi ukuxhuma ku-VPN njalo"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> isethelwe ukuhlala ixhumekile ngazo zonke izikhathi, kodwa ayikwazi ukuxhuma manje. Ifoni yakho izosebenzisa inethiwekhi ize ikwazi ukuxhuma ku-<xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> isethelwe ukuhlala ixhumekile ngazo zonke izikhathi, kodwa ayikwazi ukuxhuma manje. Ngeke ube noxhumo i-VPN ize ikwazi ukuxhuma."</string>
+    <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Shintsha izilungiseleo ze-VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"Misa"</string>
+    <string name="disconnect" msgid="971412338304200056">"Ayixhumekile kwi-inthanethi"</string>
+    <string name="open_app" msgid="3717639178595958667">"Vula uhlelo lokusebenza"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Cashisa"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values/strings.xml b/packages/VpnDialogs/res/values/strings.xml
index 406bcc3..443a9bc 100644
--- a/packages/VpnDialogs/res/values/strings.xml
+++ b/packages/VpnDialogs/res/values/strings.xml
@@ -18,7 +18,6 @@
 
     <!-- Dialog title to identify the request from a VPN application. [CHAR LIMIT=60] -->
     <string name="prompt">Connection request</string>
-
     <!-- Dialog message to warn about the risk of using a VPN application. [CHAR LIMIT=NONE] -->
     <string name="warning"><xliff:g id="app">%s</xliff:g> wants to set up a VPN connection
         that allows it to monitor network traffic. Only accept if you trust the source.
@@ -31,11 +30,6 @@
 
     <!-- Dialog title for built-in VPN. [CHAR LIMIT=40]  -->
     <string name="legacy_title">VPN is connected</string>
-    <!-- Button label to configure the current VPN session. [CHAR LIMIT=20] -->
-    <string name="configure">Configure</string>
-    <!-- Button label to disconnect the current VPN session. [CHAR LIMIT=20] -->
-    <string name="disconnect">Disconnect</string>
-
     <!-- Label for the name of the current VPN session. [CHAR LIMIT=20] -->
     <string name="session">Session:</string>
     <!-- Label for the duration of the current VPN session. [CHAR LIMIT=20] -->
@@ -44,10 +38,55 @@
     <string name="data_transmitted">Sent:</string>
     <!-- Label for the network usage of data received over VPN. [CHAR LIMIT=20] -->
     <string name="data_received">Received:</string>
-
     <!-- Formatted string for the network usage over VPN. [CHAR LIMIT=40] -->
     <string name="data_value_format">
         <xliff:g id="number">%1$s</xliff:g> bytes /
         <xliff:g id="number">%2$s</xliff:g> packets
     </string>
+
+    <!-- This string is the title of a dialog. The dialog shows up for Android users when always-on
+     VPN, a VPN that's set to always stay connected, loses its connection. [CHAR LIMIT=60] -->
+    <string name="always_on_disconnected_title">Can\'t connect to always-on VPN</string>
+    <!-- This message is part of a dialog. The dialog shows up for users when always-on VPN, a VPN
+         that's set to always stay connected, loses its connection. Until the phone can reconnect to
+         the VPN, it'll automatically connect to a public network if possible. This text is followed
+         by a clickable link that leads to VPN settings. [CHAR LIMIT=NONE] -->
+    <string name="always_on_disconnected_message">
+        <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g> is set up to stay connected all
+        the time, but it can\'t connect right now. Your phone will use a public network until it can
+        reconnect to <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g>.
+    </string>
+    <!-- This message is part of a dialog. The dialog shows up for users when always-on VPN, a VPN
+         that's set to always stay connected, loses its connection while in the lockdown mode.
+         Until the phone can reconnect to the VPN, it won't be able to connect to the Internet. This
+         text is followed by a clickable link that leads to VPN settings. [CHAR LIMIT=NONE] -->
+    <string name="always_on_disconnected_message_lockdown">
+        <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g> is set up to stay connected all
+        the time, but it can\'t connect right now. You won\'t have a connection until the VPN can
+        reconnect.
+    </string>
+    <!-- This is a space separating the body text and the "Change VPN settings" link that follows
+         it. [CHAR LIMIT=5] -->
+    <string name="always_on_disconnected_message_separator">" "</string>
+    <!-- This is a clickable link appended at the end of the body text of a dialog. The dialog shows
+         up for users when always-on VPN, a VPN that's set to always stay connected, loses its
+         connection. This link takes the user to the VPN page in Settings. -->
+    <string name="always_on_disconnected_message_settings_link">Change VPN settings</string>
+
+    <!-- This is the label of a button in a dialog. The button takes the user to the VPN settings
+         screen. [CHAR LIMIT=20] -->
+    <string name="configure">Configure</string>
+    <!-- This is the label of a button in a dialog. The button lets the user disconnect from the
+         current VPN connection. [CHAR LIMIT=20] -->
+    <string name="disconnect">Disconnect</string>
+    <!-- This button is part of a dialog, and it opens the user's VPN app. The dialog shows up for
+         users when always-on VPN, a VPN that's set to always stay connected, loses its connection.
+         Until the phone can reconnect to the VPN, it may automatically connect to a public network.
+         If it doesn't, the user won't have a connection until the VPN reconnects. [CHAR LIMIT=20]
+         -->
+    <string name="open_app">Open app</string>
+    <!-- This is the label of a button in a dialog. The button lets the user dismiss the dialog
+         without any consequences. [CHAR LIMIT=20] -->
+    <string name="dismiss">Dismiss</string>
+
 </resources>
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/AlwaysOnDisconnectedDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/AlwaysOnDisconnectedDialog.java
new file mode 100644
index 0000000..846fcf8
--- /dev/null
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/AlwaysOnDisconnectedDialog.java
@@ -0,0 +1,139 @@
+/*
+ * 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.vpndialogs;
+
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.IConnectivityManager;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.SpannableStringBuilder;
+import android.text.method.LinkMovementMethod;
+import android.text.style.ClickableSpan;
+import android.util.Log;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import com.android.internal.app.AlertActivity;
+import com.android.internal.net.VpnConfig;
+
+public class AlwaysOnDisconnectedDialog extends AlertActivity
+        implements DialogInterface.OnClickListener{
+
+    private static final String TAG = "VpnDisconnected";
+
+    private IConnectivityManager mService;
+    private int mUserId;
+    private String mVpnPackage;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mService = IConnectivityManager.Stub.asInterface(
+                ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+        mUserId = UserHandle.myUserId();
+        mVpnPackage = getAlwaysOnVpnPackage();
+        if (mVpnPackage == null) {
+            finish();
+            return;
+        }
+
+        View view = View.inflate(this, R.layout.always_on_disconnected, null);
+        TextView messageView = view.findViewById(R.id.message);
+        messageView.setText(getMessage(getIntent().getBooleanExtra("lockdown", false)));
+        messageView.setMovementMethod(LinkMovementMethod.getInstance());
+
+        mAlertParams.mTitle = getString(R.string.always_on_disconnected_title);
+        mAlertParams.mPositiveButtonText = getString(R.string.open_app);
+        mAlertParams.mPositiveButtonListener = this;
+        mAlertParams.mNegativeButtonText = getString(R.string.dismiss);
+        mAlertParams.mNegativeButtonListener = this;
+        mAlertParams.mCancelable = false;
+        mAlertParams.mView = view;
+        setupAlert();
+
+        getWindow().setCloseOnTouchOutside(false);
+        getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        switch (which) {
+            case BUTTON_POSITIVE:
+                PackageManager pm = getPackageManager();
+                final Intent intent = pm.getLaunchIntentForPackage(mVpnPackage);
+                if (intent != null) {
+                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+                    startActivity(intent);
+                }
+                finish();
+                break;
+            case BUTTON_NEGATIVE:
+                finish();
+                break;
+            default:
+                break;
+        }
+    }
+
+    private String getAlwaysOnVpnPackage() {
+        try {
+            return mService.getAlwaysOnVpnPackage(mUserId);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Can't getAlwaysOnVpnPackage()", e);
+            return null;
+        }
+    }
+
+    private CharSequence getVpnLabel() {
+        try {
+            return VpnConfig.getVpnLabel(this, mVpnPackage);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "Can't getVpnLabel() for " + mVpnPackage, e);
+            return mVpnPackage;
+        }
+    }
+
+    private CharSequence getMessage(boolean isLockdown) {
+        final SpannableStringBuilder message = new SpannableStringBuilder();
+        final int baseMessageResId = isLockdown
+                ? R.string.always_on_disconnected_message_lockdown
+                : R.string.always_on_disconnected_message;
+        message.append(getString(baseMessageResId, getVpnLabel()));
+        message.append(getString(R.string.always_on_disconnected_message_separator));
+        message.append(getString(R.string.always_on_disconnected_message_settings_link),
+                new VpnSpan(), 0 /*flags*/);
+        return message;
+    }
+
+    private class VpnSpan extends ClickableSpan {
+        @Override
+        public void onClick(View unused) {
+            final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+            startActivity(intent);
+        }
+    }
+}
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
index 2fe6648..01dca7e 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
@@ -54,12 +54,6 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        if (getCallingPackage() != null) {
-            Log.e(TAG, getCallingPackage() + " cannot start this activity");
-            finish();
-            return;
-        }
-
         try {
 
             mService = IConnectivityManager.Stub.asInterface(
diff --git a/packages/overlays/SysuiDarkThemeOverlay/Android.mk b/packages/overlays/SysuiDarkThemeOverlay/Android.mk
new file mode 100644
index 0000000..4b83058
--- /dev/null
+++ b/packages/overlays/SysuiDarkThemeOverlay/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := SysuiDarkTheme
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := SysuiDarkThemeOverlay
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/SysuiDarkThemeOverlay/AndroidManifest.xml b/packages/overlays/SysuiDarkThemeOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..8b6ee2b
--- /dev/null
+++ b/packages/overlays/SysuiDarkThemeOverlay/AndroidManifest.xml
@@ -0,0 +1,8 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.systemui.theme.dark"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <overlay android:targetPackage="com.android.systemui" android:priority="1"/>
+
+    <application android:label="@string/sysui_overlay_dark" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/SysuiDarkThemeOverlay/res/values/strings.xml b/packages/overlays/SysuiDarkThemeOverlay/res/values/strings.xml
new file mode 100644
index 0000000..71f48d6
--- /dev/null
+++ b/packages/overlays/SysuiDarkThemeOverlay/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <string name="sysui_overlay_dark">Dark</string>
+
+</resources>
+
diff --git a/packages/overlays/SysuiDarkThemeOverlay/res/values/styles.xml b/packages/overlays/SysuiDarkThemeOverlay/res/values/styles.xml
new file mode 100644
index 0000000..0c1b0ef
--- /dev/null
+++ b/packages/overlays/SysuiDarkThemeOverlay/res/values/styles.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="qs_base" parent="android:Theme.DeviceDefault">
+        <item name="android:colorPrimary">@*android:color/primary_device_default_settings</item>
+        <item name="android:colorPrimaryDark">@*android:color/primary_dark_device_default_settings</item>
+        <item name="android:colorSecondary">@*android:color/secondary_device_default_settings</item>
+        <item name="android:colorAccent">@*android:color/accent_device_default_dark</item>
+        <item name="android:colorControlNormal">?android:attr/textColorPrimary</item>
+        <item name="android:colorBackgroundFloating">#000</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/preloaded-classes b/preloaded-classes
deleted file mode 100644
index 9612231..0000000
--- a/preloaded-classes
+++ /dev/null
@@ -1,4595 +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.
-#
-#
-#
-# Preloaded-classes filter file for phones.
-#
-# Classes in this file will be allocated into the boot image, and forcibly initialized in
-# the zygote during initialization. This is a trade-off, using virtual address space to share
-# common heap between apps.
-#
-# This file has been derived for mainline phone (and tablet) usage.
-#
-[B
-[C
-[D
-[F
-[I
-[J
-[Landroid.accounts.Account;
-[Landroid.animation.Animator;
-[Landroid.animation.Keyframe$FloatKeyframe;
-[Landroid.animation.Keyframe$IntKeyframe;
-[Landroid.animation.PropertyValuesHolder;
-[Landroid.app.LoaderManagerImpl;
-[Landroid.app.Notification$Action;
-[Landroid.app.NotificationChannel;
-[Landroid.app.RemoteInput;
-[Landroid.app.job.JobInfo$TriggerContentUri;
-[Landroid.bluetooth.BluetoothDevice;
-[Landroid.content.ContentProviderResult;
-[Landroid.content.ContentValues;
-[Landroid.content.Intent;
-[Landroid.content.UndoOwner;
-[Landroid.content.pm.ActivityInfo;
-[Landroid.content.pm.ConfigurationInfo;
-[Landroid.content.pm.FeatureGroupInfo;
-[Landroid.content.pm.FeatureInfo;
-[Landroid.content.pm.InstrumentationInfo;
-[Landroid.content.pm.PathPermission;
-[Landroid.content.pm.PermissionInfo;
-[Landroid.content.pm.ProviderInfo;
-[Landroid.content.pm.ServiceInfo;
-[Landroid.content.pm.Signature;
-[Landroid.content.res.Configuration;
-[Landroid.content.res.StringBlock;
-[Landroid.content.res.XmlBlock;
-[Landroid.database.CursorWindow;
-[Landroid.database.sqlite.SQLiteConnection$Operation;
-[Landroid.database.sqlite.SQLiteConnectionPool$AcquiredConnectionStatus;
-[Landroid.graphics.Bitmap$CompressFormat;
-[Landroid.graphics.Bitmap$Config;
-[Landroid.graphics.Bitmap;
-[Landroid.graphics.Canvas$EdgeType;
-[Landroid.graphics.ColorSpace$Model;
-[Landroid.graphics.ColorSpace$Named;
-[Landroid.graphics.ColorSpace;
-[Landroid.graphics.FontFamily;
-[Landroid.graphics.Interpolator$Result;
-[Landroid.graphics.Matrix$ScaleToFit;
-[Landroid.graphics.Paint$Align;
-[Landroid.graphics.Paint$Cap;
-[Landroid.graphics.Paint$Join;
-[Landroid.graphics.Paint$Style;
-[Landroid.graphics.Path$Direction;
-[Landroid.graphics.Path$FillType;
-[Landroid.graphics.Point;
-[Landroid.graphics.PorterDuff$Mode;
-[Landroid.graphics.Rect;
-[Landroid.graphics.Region$Op;
-[Landroid.graphics.Shader$TileMode;
-[Landroid.graphics.Typeface;
-[Landroid.graphics.drawable.Drawable;
-[Landroid.graphics.drawable.GradientDrawable$Orientation;
-[Landroid.graphics.drawable.LayerDrawable$ChildDrawable;
-[Landroid.graphics.drawable.RippleForeground;
-[Landroid.graphics.fonts.FontVariationAxis;
-[Landroid.hardware.camera2.marshal.MarshalQueryable;
-[Landroid.hardware.camera2.params.Face;
-[Landroid.hardware.camera2.params.HighSpeedVideoConfiguration;
-[Landroid.hardware.camera2.params.MeteringRectangle;
-[Landroid.hardware.camera2.params.StreamConfiguration;
-[Landroid.hardware.camera2.params.StreamConfigurationDuration;
-[Landroid.hardware.soundtrigger.SoundTrigger$ConfidenceLevel;
-[Landroid.hardware.soundtrigger.SoundTrigger$Keyphrase;
-[Landroid.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionExtra;
-[Landroid.icu.impl.CacheValue$Strength;
-[Landroid.icu.impl.CacheValue;
-[Landroid.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingPattern;
-[Landroid.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingType;
-[Landroid.icu.impl.ICUResourceBundle$OpenType;
-[Landroid.icu.impl.StandardPlural;
-[Landroid.icu.impl.Trie2$ValueWidth;
-[Landroid.icu.impl.UCharacterProperty$BinaryProperty;
-[Landroid.icu.impl.UCharacterProperty$IntProperty;
-[Landroid.icu.text.DisplayContext$Type;
-[Landroid.icu.text.DisplayContext;
-[Landroid.icu.text.PluralRules$Operand;
-[Landroid.icu.text.PluralRules$PluralType;
-[Landroid.icu.text.PluralRules$SampleType;
-[Landroid.icu.text.TimeZoneNames$NameType;
-[Landroid.icu.text.UnicodeSet;
-[Landroid.icu.util.Currency$CurrencyUsage;
-[Landroid.icu.util.ULocale$Category;
-[Landroid.icu.util.ULocale;
-[Landroid.icu.util.UResourceBundle$RootType;
-[Landroid.media.AudioGain;
-[Landroid.net.IpConfiguration$IpAssignment;
-[Landroid.net.IpConfiguration$ProxySettings;
-[Landroid.net.LocalSocketAddress$Namespace;
-[Landroid.net.NetworkInfo$DetailedState;
-[Landroid.net.NetworkInfo$State;
-[Landroid.net.NetworkKey;
-[Landroid.net.NetworkRequest$Type;
-[Landroid.net.ScoredNetwork;
-[Landroid.net.Uri;
-[Landroid.net.wifi.ScanResult$InformationElement;
-[Landroid.net.wifi.SupplicantState;
-[Landroid.os.AsyncTask$Status;
-[Landroid.os.MessageQueue$IdleHandler;
-[Landroid.os.Parcel;
-[Landroid.os.Parcelable;
-[Landroid.os.PatternMatcher;
-[Landroid.os.PersistableBundle;
-[Landroid.os.storage.StorageVolume;
-[Landroid.service.notification.StatusBarNotification;
-[Landroid.system.StructPollfd;
-[Landroid.telephony.TelephonyManager$MultiSimVariants;
-[Landroid.text.DynamicLayout$ChangeWatcher;
-[Landroid.text.FontConfig$Alias;
-[Landroid.text.FontConfig$Family;
-[Landroid.text.FontConfig$Font;
-[Landroid.text.Hyphenator$HyphenationData;
-[Landroid.text.InputFilter;
-[Landroid.text.Layout$Alignment;
-[Landroid.text.Layout$Directions;
-[Landroid.text.MeasuredText;
-[Landroid.text.SpanWatcher;
-[Landroid.text.TextLine;
-[Landroid.text.TextUtils$TruncateAt;
-[Landroid.text.TextWatcher;
-[Landroid.text.method.TextKeyListener$Capitalize;
-[Landroid.text.method.TextKeyListener;
-[Landroid.text.style.AlignmentSpan;
-[Landroid.text.style.CharacterStyle;
-[Landroid.text.style.LeadingMarginSpan;
-[Landroid.text.style.LineBackgroundSpan;
-[Landroid.text.style.LineHeightSpan;
-[Landroid.text.style.MetricAffectingSpan;
-[Landroid.text.style.ParagraphStyle;
-[Landroid.text.style.ReplacementSpan;
-[Landroid.text.style.SpellCheckSpan;
-[Landroid.text.style.SuggestionSpan;
-[Landroid.text.style.TabStopSpan;
-[Landroid.text.style.WrapTogetherSpan;
-[Landroid.util.LongSparseArray;
-[Landroid.util.Pair;
-[Landroid.util.Range;
-[Landroid.util.Rational;
-[Landroid.util.Size;
-[Landroid.view.Choreographer$CallbackQueue;
-[Landroid.view.Display$Mode;
-[Landroid.view.Display;
-[Landroid.view.HandlerActionQueue$HandlerAction;
-[Landroid.view.MenuItem;
-[Landroid.view.View;
-[Landroid.widget.Editor$TextViewPositionListener;
-[Landroid.widget.ImageView$ScaleType;
-[Landroid.widget.TextView$BufferType;
-[Landroid.widget.TextView$ChangeWatcher;
-[Lcom.android.internal.policy.PhoneWindow$PanelFeatureState;
-[Lcom.android.internal.telephony.IccCardConstants$State;
-[Lcom.android.internal.telephony.PhoneConstants$State;
-[Lcom.android.internal.util.StateMachine$SmHandler$StateInfo;
-[Lcom.android.okhttp.CipherSuite;
-[Lcom.android.okhttp.ConnectionSpec;
-[Lcom.android.okhttp.HttpUrl$Builder$ParseResult;
-[Lcom.android.okhttp.Protocol;
-[Lcom.android.okhttp.TlsVersion;
-[Lcom.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
-[Lcom.android.org.conscrypt.OpenSSLSignature$EngineType;
-[Lcom.android.org.conscrypt.OpenSSLX509CertPath$Encoding;
-[Lcom.android.org.conscrypt.OpenSSLX509Certificate;
-[Lcom.android.org.conscrypt.ct.CTLogInfo;
-[Ldalvik.system.DexPathList$Element;
-[Ldalvik.system.DexPathList$NativeLibraryElement;
-[Ljava.io.File$PathStatus;
-[Ljava.io.File;
-[Ljava.io.FileDescriptor;
-[Ljava.io.IOException;
-[Ljava.io.ObjectInputStream$HandleTable$HandleList;
-[Ljava.io.ObjectStreamField;
-[Ljava.lang.Byte;
-[Ljava.lang.CharSequence;
-[Ljava.lang.Character$UnicodeBlock;
-[Ljava.lang.Character;
-[Ljava.lang.Class;
-[Ljava.lang.Comparable;
-[Ljava.lang.Enum;
-[Ljava.lang.Integer;
-[Ljava.lang.Long;
-[Ljava.lang.Object;
-[Ljava.lang.Package;
-[Ljava.lang.Runnable;
-[Ljava.lang.Short;
-[Ljava.lang.StackTraceElement;
-[Ljava.lang.String;
-[Ljava.lang.Thread$State;
-[Ljava.lang.Thread;
-[Ljava.lang.ThreadGroup;
-[Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;
-[Ljava.lang.Throwable;
-[Ljava.lang.Void;
-[Ljava.lang.annotation.Annotation;
-[Ljava.lang.invoke.MethodType;
-[Ljava.lang.ref.WeakReference;
-[Ljava.lang.reflect.AccessibleObject;
-[Ljava.lang.reflect.Constructor;
-[Ljava.lang.reflect.Field;
-[Ljava.lang.reflect.Method;
-[Ljava.lang.reflect.Parameter;
-[Ljava.lang.reflect.Type;
-[Ljava.lang.reflect.TypeVariable;
-[Ljava.math.BigInteger;
-[Ljava.math.RoundingMode;
-[Ljava.net.InetAddress;
-[Ljava.net.Proxy$Type;
-[Ljava.nio.ByteBuffer;
-[Ljava.nio.file.attribute.FileAttribute;
-[Ljava.security.CryptoPrimitive;
-[Ljava.security.Provider;
-[Ljava.security.cert.Certificate;
-[Ljava.security.cert.X509Certificate;
-[Ljava.text.DateFormat$Field;
-[Ljava.text.Normalizer$Form;
-[Ljava.util.ArrayList;
-[Ljava.util.Comparators$NaturalOrderComparator;
-[Ljava.util.Enumeration;
-[Ljava.util.Formatter$Flags;
-[Ljava.util.Formatter$FormatString;
-[Ljava.util.HashMap$Node;
-[Ljava.util.Hashtable$HashtableEntry;
-[Ljava.util.Locale$Category;
-[Ljava.util.Locale;
-[Ljava.util.Map$Entry;
-[Ljava.util.WeakHashMap$Entry;
-[Ljava.util.concurrent.ConcurrentHashMap$CounterCell;
-[Ljava.util.concurrent.ConcurrentHashMap$Node;
-[Ljava.util.concurrent.ConcurrentHashMap$Segment;
-[Ljava.util.concurrent.ForkJoinTask$ExceptionNode;
-[Ljava.util.concurrent.RunnableScheduledFuture;
-[Ljava.util.concurrent.TimeUnit;
-[Ljava.util.logging.Handler;
-[Ljava.util.regex.Pattern;
-[Ljava.util.stream.StreamOpFlag$Type;
-[Ljava.util.stream.StreamOpFlag;
-[Ljava.util.stream.StreamShape;
-[Ljavax.crypto.Cipher$InitType;
-[Ljavax.crypto.Cipher$NeedToSet;
-[Ljavax.microedition.khronos.egl.EGLConfig;
-[Ljavax.net.ssl.KeyManager;
-[Ljavax.net.ssl.TrustManager;
-[Ljavax.security.cert.X509Certificate;
-[Llibcore.io.ClassPathURLStreamHandler;
-[Llibcore.io.IoTracker$Mode;
-[Llibcore.reflect.AnnotationMember$DefaultValues;
-[Llibcore.reflect.AnnotationMember;
-[Lorg.apache.http.Header;
-[Lorg.json.JSONStringer$Scope;
-[Lorg.kxml2.io.KXmlParser$ValueContext;
-[Lsun.invoke.util.Wrapper;
-[Lsun.misc.FDBigInteger;
-[Lsun.misc.FormattedFloatingDecimal$Form;
-[Lsun.security.jca.ProviderConfig;
-[Lsun.security.jca.ServiceId;
-[Lsun.security.pkcs.SignerInfo;
-[Lsun.security.util.DerOutputStream;
-[Lsun.security.util.DerValue;
-[Lsun.security.util.DisabledAlgorithmConstraints$Constraint$Operator;
-[Lsun.security.util.ObjectIdentifier;
-[Lsun.security.x509.AVA;
-[Lsun.security.x509.RDN;
-[Lsun.util.logging.PlatformLogger$Level;
-[S
-[Z
-[[B
-[[I
-[[Ljava.lang.Byte;
-[[Ljava.lang.Class;
-[[Ljava.lang.Object;
-[[Ljava.lang.String;
-[[Ljava.lang.annotation.Annotation;
-android.R$styleable
-android.accounts.Account
-android.accounts.Account$1
-android.accounts.AccountManager
-android.accounts.AccountManager$1
-android.accounts.AccountManager$19
-android.accounts.AccountManager$BaseFutureTask
-android.accounts.AccountManager$BaseFutureTask$1
-android.accounts.AccountManager$BaseFutureTask$Response
-android.accounts.AccountManager$Future2Task
-android.accounts.AccountManagerCallback
-android.accounts.AccountManagerFuture
-android.accounts.AccountsException
-android.accounts.AuthenticatorException
-android.accounts.IAccountManager
-android.accounts.IAccountManager$Stub
-android.accounts.IAccountManager$Stub$Proxy
-android.accounts.IAccountManagerResponse
-android.accounts.IAccountManagerResponse$Stub
-android.accounts.OnAccountsUpdateListener
-android.accounts.OperationCanceledException
-android.animation.AnimationHandler
-android.animation.AnimationHandler$1
-android.animation.AnimationHandler$AnimationFrameCallback
-android.animation.AnimationHandler$AnimationFrameCallbackProvider
-android.animation.AnimationHandler$MyFrameCallbackProvider
-android.animation.Animator
-android.animation.Animator$AnimatorConstantState
-android.animation.Animator$AnimatorListener
-android.animation.Animator$AnimatorPauseListener
-android.animation.AnimatorInflater
-android.animation.AnimatorListenerAdapter
-android.animation.AnimatorSet
-android.animation.AnimatorSet$1
-android.animation.AnimatorSet$2
-android.animation.AnimatorSet$3
-android.animation.AnimatorSet$AnimationEvent
-android.animation.AnimatorSet$Builder
-android.animation.AnimatorSet$Node
-android.animation.AnimatorSet$SeekState
-android.animation.FloatEvaluator
-android.animation.FloatKeyframeSet
-android.animation.IntEvaluator
-android.animation.IntKeyframeSet
-android.animation.Keyframe
-android.animation.Keyframe$FloatKeyframe
-android.animation.Keyframe$IntKeyframe
-android.animation.KeyframeSet
-android.animation.Keyframes
-android.animation.Keyframes$FloatKeyframes
-android.animation.Keyframes$IntKeyframes
-android.animation.LayoutTransition
-android.animation.LayoutTransition$TransitionListener
-android.animation.ObjectAnimator
-android.animation.PathKeyframes$FloatKeyframesBase
-android.animation.PathKeyframes$IntKeyframesBase
-android.animation.PathKeyframes$SimpleKeyframes
-android.animation.PropertyValuesHolder
-android.animation.PropertyValuesHolder$FloatPropertyValuesHolder
-android.animation.PropertyValuesHolder$IntPropertyValuesHolder
-android.animation.PropertyValuesHolder$PropertyValues
-android.animation.RectEvaluator
-android.animation.StateListAnimator
-android.animation.StateListAnimator$1
-android.animation.StateListAnimator$StateListAnimatorConstantState
-android.animation.StateListAnimator$Tuple
-android.animation.TimeInterpolator
-android.animation.TypeEvaluator
-android.animation.ValueAnimator
-android.animation.ValueAnimator$AnimatorUpdateListener
-android.app.-$Lambda$9I5WEMsoBc7l4QrNqZ4wx59yuHU
-android.app.-$Lambda$9I5WEMsoBc7l4QrNqZ4wx59yuHU$1
-android.app.-$Lambda$FilBqgnXJrN9Mgyks1XHeAxzSTk
-android.app.-$Lambda$c44uHH2WE4sJvw5tZZB6gRzEaHI
-android.app.-$Lambda$c44uHH2WE4sJvw5tZZB6gRzEaHI$1
-android.app.Activity
-android.app.Activity$HostCallbacks
-android.app.ActivityManager
-android.app.ActivityManager$1
-android.app.ActivityManager$RecentTaskInfo
-android.app.ActivityManager$RecentTaskInfo$1
-android.app.ActivityManager$RunningAppProcessInfo
-android.app.ActivityManager$RunningAppProcessInfo$1
-android.app.ActivityManager$RunningServiceInfo
-android.app.ActivityManager$RunningServiceInfo$1
-android.app.ActivityManager$RunningTaskInfo
-android.app.ActivityManager$RunningTaskInfo$1
-android.app.ActivityManager$StackId
-android.app.ActivityManager$TaskDescription
-android.app.ActivityManager$TaskDescription$1
-android.app.ActivityOptions
-android.app.ActivityThread
-android.app.ActivityThread$1
-android.app.ActivityThread$2
-android.app.ActivityThread$ActivityClientRecord
-android.app.ActivityThread$ActivityConfigChangeData
-android.app.ActivityThread$AppBindData
-android.app.ActivityThread$ApplicationThread
-android.app.ActivityThread$BindServiceData
-android.app.ActivityThread$ContextCleanupInfo
-android.app.ActivityThread$CreateServiceData
-android.app.ActivityThread$DropBoxReporter
-android.app.ActivityThread$EventLoggingReporter
-android.app.ActivityThread$GcIdler
-android.app.ActivityThread$H
-android.app.ActivityThread$Idler
-android.app.ActivityThread$Profiler
-android.app.ActivityThread$ProviderClientRecord
-android.app.ActivityThread$ProviderKey
-android.app.ActivityThread$ProviderRefCount
-android.app.ActivityThread$ReceiverData
-android.app.ActivityThread$ServiceArgsData
-android.app.ActivityThread$StopInfo
-android.app.ActivityTransitionState
-android.app.AlertDialog
-android.app.AppGlobals
-android.app.AppOpsManager
-android.app.AppOpsManager$OnOpChangedListener
-android.app.Application
-android.app.Application$ActivityLifecycleCallbacks
-android.app.ApplicationErrorReport$CrashInfo
-android.app.ApplicationLoaders
-android.app.ApplicationPackageManager
-android.app.ApplicationPackageManager$OnPermissionsChangeListenerDelegate
-android.app.ApplicationPackageManager$ResourceName
-android.app.ContentProviderHolder
-android.app.ContentProviderHolder$1
-android.app.ContextImpl
-android.app.ContextImpl$ApplicationContentResolver
-android.app.DexLoadReporter
-android.app.Dialog
-android.app.Dialog$ListenersHandler
-android.app.DownloadManager
-android.app.Fragment
-android.app.FragmentContainer
-android.app.FragmentController
-android.app.FragmentHostCallback
-android.app.FragmentManager
-android.app.FragmentManagerImpl
-android.app.FragmentManagerImpl$1
-android.app.IActivityManager
-android.app.IActivityManager$Stub
-android.app.IActivityManager$Stub$Proxy
-android.app.IAlarmManager
-android.app.IAlarmManager$Stub
-android.app.IAlarmManager$Stub$Proxy
-android.app.IApplicationThread
-android.app.IApplicationThread$Stub
-android.app.IInstrumentationWatcher
-android.app.IInstrumentationWatcher$Stub
-android.app.INotificationManager
-android.app.INotificationManager$Stub
-android.app.INotificationManager$Stub$Proxy
-android.app.IServiceConnection
-android.app.IServiceConnection$Stub
-android.app.IUiAutomationConnection
-android.app.IUiAutomationConnection$Stub
-android.app.IUiModeManager
-android.app.IUiModeManager$Stub
-android.app.IUiModeManager$Stub$Proxy
-android.app.IUserSwitchObserver
-android.app.IUserSwitchObserver$Stub
-android.app.IWallpaperManager
-android.app.IWallpaperManager$Stub
-android.app.IWallpaperManagerCallback
-android.app.IWallpaperManagerCallback$Stub
-android.app.Instrumentation
-android.app.IntentReceiverLeaked
-android.app.IntentService
-android.app.IntentService$ServiceHandler
-android.app.JobSchedulerImpl
-android.app.KeyguardManager
-android.app.LoadedApk
-android.app.LoadedApk$ReceiverDispatcher
-android.app.LoadedApk$ReceiverDispatcher$Args
-android.app.LoadedApk$ReceiverDispatcher$InnerReceiver
-android.app.LoadedApk$ServiceDispatcher
-android.app.LoadedApk$ServiceDispatcher$ConnectionInfo
-android.app.LoadedApk$ServiceDispatcher$DeathMonitor
-android.app.LoadedApk$ServiceDispatcher$InnerConnection
-android.app.LoadedApk$ServiceDispatcher$RunConnection
-android.app.LoadedApk$WarningContextClassLoader
-android.app.LoaderManager
-android.app.LoaderManagerImpl
-android.app.NativeActivity
-android.app.Notification
-android.app.Notification$1
-android.app.Notification$Action
-android.app.Notification$Action$1
-android.app.Notification$BigPictureStyle
-android.app.Notification$BigTextStyle
-android.app.Notification$Builder
-android.app.Notification$BuilderRemoteViews
-android.app.Notification$DecoratedCustomViewStyle
-android.app.Notification$DecoratedMediaCustomViewStyle
-android.app.Notification$InboxStyle
-android.app.Notification$MediaStyle
-android.app.Notification$MessagingStyle
-android.app.Notification$StandardTemplateParams
-android.app.Notification$Style
-android.app.NotificationChannel
-android.app.NotificationChannel$1
-android.app.NotificationChannelGroup
-android.app.NotificationChannelGroup$1
-android.app.NotificationManager
-android.app.PendingIntent
-android.app.PendingIntent$1
-android.app.PendingIntent$CanceledException
-android.app.PendingIntent$OnMarshaledListener
-android.app.QueuedWork
-android.app.QueuedWork$QueuedWorkHandler
-android.app.ReceiverRestrictedContext
-android.app.RemoteInput
-android.app.ResourcesManager
-android.app.ResourcesManager$1
-android.app.ResourcesManager$ActivityResources
-android.app.ResultInfo
-android.app.ResultInfo$1
-android.app.Service
-android.app.ServiceConnectionLeaked
-android.app.ServiceStartArgs
-android.app.ServiceStartArgs$1
-android.app.SharedElementCallback
-android.app.SharedElementCallback$1
-android.app.SharedPreferencesImpl
-android.app.SharedPreferencesImpl$1
-android.app.SharedPreferencesImpl$2
-android.app.SharedPreferencesImpl$EditorImpl
-android.app.SharedPreferencesImpl$EditorImpl$1
-android.app.SharedPreferencesImpl$EditorImpl$2
-android.app.SharedPreferencesImpl$MemoryCommitResult
-android.app.StatusBarManager
-android.app.SystemServiceRegistry
-android.app.SystemServiceRegistry$1
-android.app.SystemServiceRegistry$10
-android.app.SystemServiceRegistry$11
-android.app.SystemServiceRegistry$12
-android.app.SystemServiceRegistry$13
-android.app.SystemServiceRegistry$14
-android.app.SystemServiceRegistry$15
-android.app.SystemServiceRegistry$16
-android.app.SystemServiceRegistry$17
-android.app.SystemServiceRegistry$18
-android.app.SystemServiceRegistry$19
-android.app.SystemServiceRegistry$2
-android.app.SystemServiceRegistry$20
-android.app.SystemServiceRegistry$21
-android.app.SystemServiceRegistry$22
-android.app.SystemServiceRegistry$23
-android.app.SystemServiceRegistry$24
-android.app.SystemServiceRegistry$25
-android.app.SystemServiceRegistry$26
-android.app.SystemServiceRegistry$27
-android.app.SystemServiceRegistry$28
-android.app.SystemServiceRegistry$29
-android.app.SystemServiceRegistry$3
-android.app.SystemServiceRegistry$30
-android.app.SystemServiceRegistry$31
-android.app.SystemServiceRegistry$32
-android.app.SystemServiceRegistry$33
-android.app.SystemServiceRegistry$34
-android.app.SystemServiceRegistry$35
-android.app.SystemServiceRegistry$36
-android.app.SystemServiceRegistry$37
-android.app.SystemServiceRegistry$38
-android.app.SystemServiceRegistry$39
-android.app.SystemServiceRegistry$4
-android.app.SystemServiceRegistry$40
-android.app.SystemServiceRegistry$41
-android.app.SystemServiceRegistry$42
-android.app.SystemServiceRegistry$43
-android.app.SystemServiceRegistry$44
-android.app.SystemServiceRegistry$45
-android.app.SystemServiceRegistry$46
-android.app.SystemServiceRegistry$47
-android.app.SystemServiceRegistry$48
-android.app.SystemServiceRegistry$49
-android.app.SystemServiceRegistry$5
-android.app.SystemServiceRegistry$50
-android.app.SystemServiceRegistry$51
-android.app.SystemServiceRegistry$52
-android.app.SystemServiceRegistry$53
-android.app.SystemServiceRegistry$54
-android.app.SystemServiceRegistry$55
-android.app.SystemServiceRegistry$56
-android.app.SystemServiceRegistry$57
-android.app.SystemServiceRegistry$58
-android.app.SystemServiceRegistry$59
-android.app.SystemServiceRegistry$6
-android.app.SystemServiceRegistry$60
-android.app.SystemServiceRegistry$61
-android.app.SystemServiceRegistry$62
-android.app.SystemServiceRegistry$63
-android.app.SystemServiceRegistry$64
-android.app.SystemServiceRegistry$65
-android.app.SystemServiceRegistry$66
-android.app.SystemServiceRegistry$67
-android.app.SystemServiceRegistry$68
-android.app.SystemServiceRegistry$69
-android.app.SystemServiceRegistry$7
-android.app.SystemServiceRegistry$70
-android.app.SystemServiceRegistry$71
-android.app.SystemServiceRegistry$72
-android.app.SystemServiceRegistry$73
-android.app.SystemServiceRegistry$74
-android.app.SystemServiceRegistry$75
-android.app.SystemServiceRegistry$76
-android.app.SystemServiceRegistry$77
-android.app.SystemServiceRegistry$78
-android.app.SystemServiceRegistry$79
-android.app.SystemServiceRegistry$8
-android.app.SystemServiceRegistry$80
-android.app.SystemServiceRegistry$81
-android.app.SystemServiceRegistry$82
-android.app.SystemServiceRegistry$9
-android.app.SystemServiceRegistry$CachedServiceFetcher
-android.app.SystemServiceRegistry$ServiceFetcher
-android.app.SystemServiceRegistry$StaticApplicationContextServiceFetcher
-android.app.SystemServiceRegistry$StaticServiceFetcher
-android.app.UiModeManager
-android.app.UserSwitchObserver
-android.app.VrManager
-android.app.WallpaperManager
-android.app.admin.DevicePolicyManager
-android.app.admin.IDevicePolicyManager
-android.app.admin.IDevicePolicyManager$Stub
-android.app.admin.IDevicePolicyManager$Stub$Proxy
-android.app.admin.SecurityLog
-android.app.admin.SecurityLog$SecurityEvent
-android.app.admin.SecurityLog$SecurityEvent$1
-android.app.backup.BackupAgent
-android.app.backup.BackupDataInput
-android.app.backup.BackupDataInput$EntityHeader
-android.app.backup.BackupDataOutput
-android.app.backup.BackupHelperDispatcher
-android.app.backup.BackupHelperDispatcher$Header
-android.app.backup.BackupManager
-android.app.backup.FileBackupHelperBase
-android.app.backup.FullBackup
-android.app.backup.FullBackupDataOutput
-android.app.backup.IBackupManager
-android.app.backup.IBackupManager$Stub
-android.app.backup.IBackupManager$Stub$Proxy
-android.app.job.IJobCallback
-android.app.job.IJobCallback$Stub
-android.app.job.IJobCallback$Stub$Proxy
-android.app.job.IJobScheduler
-android.app.job.IJobScheduler$Stub
-android.app.job.IJobScheduler$Stub$Proxy
-android.app.job.IJobService
-android.app.job.IJobService$Stub
-android.app.job.JobInfo
-android.app.job.JobInfo$1
-android.app.job.JobInfo$Builder
-android.app.job.JobInfo$TriggerContentUri
-android.app.job.JobInfo$TriggerContentUri$1
-android.app.job.JobParameters
-android.app.job.JobParameters$1
-android.app.job.JobScheduler
-android.app.job.JobService
-android.app.job.JobService$1
-android.app.job.JobServiceEngine
-android.app.job.JobServiceEngine$JobHandler
-android.app.job.JobServiceEngine$JobInterface
-android.app.trust.ITrustManager
-android.app.trust.ITrustManager$Stub
-android.app.trust.ITrustManager$Stub$Proxy
-android.app.trust.TrustManager
-android.app.usage.IUsageStatsManager
-android.app.usage.IUsageStatsManager$Stub
-android.app.usage.NetworkStatsManager
-android.app.usage.StorageStatsManager
-android.app.usage.UsageEvents
-android.app.usage.UsageEvents$1
-android.app.usage.UsageStatsManager
-android.appwidget.AppWidgetManager
-android.appwidget.AppWidgetProvider
-android.bluetooth.BluetoothActivityEnergyInfo
-android.bluetooth.BluetoothAdapter
-android.bluetooth.BluetoothAdapter$1
-android.bluetooth.BluetoothDevice
-android.bluetooth.BluetoothDevice$1
-android.bluetooth.BluetoothDevice$2
-android.bluetooth.BluetoothHeadset
-android.bluetooth.BluetoothHeadset$1
-android.bluetooth.BluetoothHeadset$2
-android.bluetooth.BluetoothHeadset$3
-android.bluetooth.BluetoothManager
-android.bluetooth.BluetoothProfile
-android.bluetooth.BluetoothProfile$ServiceListener
-android.bluetooth.IBluetooth
-android.bluetooth.IBluetooth$Stub
-android.bluetooth.IBluetooth$Stub$Proxy
-android.bluetooth.IBluetoothA2dp
-android.bluetooth.IBluetoothA2dp$Stub
-android.bluetooth.IBluetoothGatt
-android.bluetooth.IBluetoothGatt$Stub
-android.bluetooth.IBluetoothHeadset
-android.bluetooth.IBluetoothHeadset$Stub
-android.bluetooth.IBluetoothHeadset$Stub$Proxy
-android.bluetooth.IBluetoothManager
-android.bluetooth.IBluetoothManager$Stub
-android.bluetooth.IBluetoothManager$Stub$Proxy
-android.bluetooth.IBluetoothManagerCallback
-android.bluetooth.IBluetoothManagerCallback$Stub
-android.bluetooth.IBluetoothProfileServiceConnection
-android.bluetooth.IBluetoothProfileServiceConnection$Stub
-android.bluetooth.IBluetoothStateChangeCallback
-android.bluetooth.IBluetoothStateChangeCallback$Stub
-android.companion.CompanionDeviceManager
-android.content.AbstractThreadedSyncAdapter
-android.content.AbstractThreadedSyncAdapter$ISyncAdapterImpl
-android.content.ActivityNotFoundException
-android.content.BroadcastReceiver
-android.content.BroadcastReceiver$PendingResult
-android.content.BroadcastReceiver$PendingResult$1
-android.content.ClipboardManager
-android.content.ComponentCallbacks
-android.content.ComponentCallbacks2
-android.content.ComponentName
-android.content.ComponentName$1
-android.content.ContentProvider
-android.content.ContentProvider$Transport
-android.content.ContentProviderClient
-android.content.ContentProviderNative
-android.content.ContentProviderProxy
-android.content.ContentProviderResult
-android.content.ContentResolver
-android.content.ContentResolver$CursorWrapperInner
-android.content.ContentUris
-android.content.ContentValues
-android.content.ContentValues$1
-android.content.Context
-android.content.ContextWrapper
-android.content.DialogInterface
-android.content.DialogInterface$OnCancelListener
-android.content.DialogInterface$OnClickListener
-android.content.DialogInterface$OnDismissListener
-android.content.IContentProvider
-android.content.IContentService
-android.content.IContentService$Stub
-android.content.IContentService$Stub$Proxy
-android.content.IIntentReceiver
-android.content.IIntentReceiver$Stub
-android.content.IIntentSender
-android.content.IIntentSender$Stub
-android.content.IIntentSender$Stub$Proxy
-android.content.ISyncAdapter
-android.content.ISyncAdapter$Stub
-android.content.ISyncContext
-android.content.ISyncContext$Stub
-android.content.Intent
-android.content.Intent$1
-android.content.Intent$FilterComparison
-android.content.IntentFilter
-android.content.IntentFilter$1
-android.content.IntentFilter$MalformedMimeTypeException
-android.content.IntentSender
-android.content.IntentSender$SendIntentException
-android.content.OperationApplicationException
-android.content.RestrictionsManager
-android.content.ServiceConnection
-android.content.SharedPreferences
-android.content.SharedPreferences$Editor
-android.content.SharedPreferences$OnSharedPreferenceChangeListener
-android.content.SyncResult
-android.content.SyncResult$1
-android.content.SyncStats
-android.content.SyncStats$1
-android.content.UndoManager
-android.content.UndoOwner
-android.content.UriMatcher
-android.content.pm.ActivityInfo
-android.content.pm.ActivityInfo$1
-android.content.pm.ApplicationInfo
-android.content.pm.ApplicationInfo$1
-android.content.pm.BaseParceledListSlice
-android.content.pm.ComponentInfo
-android.content.pm.ConfigurationInfo
-android.content.pm.ConfigurationInfo$1
-android.content.pm.FeatureGroupInfo
-android.content.pm.FeatureGroupInfo$1
-android.content.pm.FeatureInfo
-android.content.pm.FeatureInfo$1
-android.content.pm.IOnPermissionsChangeListener
-android.content.pm.IOnPermissionsChangeListener$Stub
-android.content.pm.IPackageInstaller
-android.content.pm.IPackageInstaller$Stub
-android.content.pm.IPackageManager
-android.content.pm.IPackageManager$Stub
-android.content.pm.IPackageManager$Stub$Proxy
-android.content.pm.IShortcutService
-android.content.pm.IShortcutService$Stub
-android.content.pm.InstrumentationInfo
-android.content.pm.InstrumentationInfo$1
-android.content.pm.LauncherApps
-android.content.pm.PackageInfo
-android.content.pm.PackageInfo$1
-android.content.pm.PackageItemInfo
-android.content.pm.PackageManager
-android.content.pm.PackageManager$NameNotFoundException
-android.content.pm.PackageManager$OnPermissionsChangedListener
-android.content.pm.PackageParser$PackageParserException
-android.content.pm.ParceledListSlice
-android.content.pm.ParceledListSlice$1
-android.content.pm.PathPermission
-android.content.pm.PathPermission$1
-android.content.pm.PermissionInfo
-android.content.pm.PermissionInfo$1
-android.content.pm.ProviderInfo
-android.content.pm.ProviderInfo$1
-android.content.pm.ResolveInfo
-android.content.pm.ResolveInfo$1
-android.content.pm.ServiceInfo
-android.content.pm.ServiceInfo$1
-android.content.pm.ShortcutInfo
-android.content.pm.ShortcutInfo$1
-android.content.pm.ShortcutManager
-android.content.pm.Signature
-android.content.pm.Signature$1
-android.content.pm.UserInfo
-android.content.pm.UserInfo$1
-android.content.res.AssetFileDescriptor
-android.content.res.AssetFileDescriptor$1
-android.content.res.AssetManager
-android.content.res.AssetManager$AssetInputStream
-android.content.res.ColorStateList
-android.content.res.ColorStateList$1
-android.content.res.ColorStateList$ColorStateListFactory
-android.content.res.CompatResources
-android.content.res.CompatibilityInfo
-android.content.res.CompatibilityInfo$1
-android.content.res.CompatibilityInfo$2
-android.content.res.ComplexColor
-android.content.res.Configuration
-android.content.res.Configuration$1
-android.content.res.ConfigurationBoundResourceCache
-android.content.res.ConstantState
-android.content.res.DrawableCache
-android.content.res.GradientColor
-android.content.res.ObbInfo
-android.content.res.ObbInfo$1
-android.content.res.ObbScanner
-android.content.res.Resources
-android.content.res.Resources$NotFoundException
-android.content.res.Resources$Theme
-android.content.res.Resources$ThemeKey
-android.content.res.ResourcesImpl
-android.content.res.ResourcesImpl$ThemeImpl
-android.content.res.ResourcesKey
-android.content.res.StringBlock
-android.content.res.ThemedResourceCache
-android.content.res.TypedArray
-android.content.res.XmlBlock
-android.content.res.XmlBlock$Parser
-android.content.res.XmlResourceParser
-android.database.AbstractCursor
-android.database.AbstractCursor$SelfContentObserver
-android.database.AbstractWindowedCursor
-android.database.BulkCursorDescriptor
-android.database.BulkCursorDescriptor$1
-android.database.BulkCursorNative
-android.database.BulkCursorProxy
-android.database.BulkCursorToCursorAdaptor
-android.database.CharArrayBuffer
-android.database.ContentObservable
-android.database.ContentObserver
-android.database.ContentObserver$NotificationRunnable
-android.database.ContentObserver$Transport
-android.database.CrossProcessCursor
-android.database.CrossProcessCursorWrapper
-android.database.Cursor
-android.database.CursorIndexOutOfBoundsException
-android.database.CursorToBulkCursorAdaptor
-android.database.CursorToBulkCursorAdaptor$ContentObserverProxy
-android.database.CursorWindow
-android.database.CursorWindow$1
-android.database.CursorWrapper
-android.database.DataSetObservable
-android.database.DataSetObserver
-android.database.DatabaseErrorHandler
-android.database.DatabaseUtils
-android.database.DefaultDatabaseErrorHandler
-android.database.IBulkCursor
-android.database.IContentObserver
-android.database.IContentObserver$Stub
-android.database.IContentObserver$Stub$Proxy
-android.database.MatrixCursor
-android.database.Observable
-android.database.SQLException
-android.database.sqlite.DatabaseObjectNotClosedException
-android.database.sqlite.SQLiteCantOpenDatabaseException
-android.database.sqlite.SQLiteClosable
-android.database.sqlite.SQLiteConnection
-android.database.sqlite.SQLiteConnection$Operation
-android.database.sqlite.SQLiteConnection$OperationLog
-android.database.sqlite.SQLiteConnection$PreparedStatement
-android.database.sqlite.SQLiteConnection$PreparedStatementCache
-android.database.sqlite.SQLiteConnectionPool
-android.database.sqlite.SQLiteConnectionPool$AcquiredConnectionStatus
-android.database.sqlite.SQLiteConnectionPool$ConnectionWaiter
-android.database.sqlite.SQLiteCursor
-android.database.sqlite.SQLiteCursorDriver
-android.database.sqlite.SQLiteCustomFunction
-android.database.sqlite.SQLiteDatabase
-android.database.sqlite.SQLiteDatabase$1
-android.database.sqlite.SQLiteDatabaseConfiguration
-android.database.sqlite.SQLiteDatabaseCorruptException
-android.database.sqlite.SQLiteDatabaseLockedException
-android.database.sqlite.SQLiteDebug
-android.database.sqlite.SQLiteDebug$PagerStats
-android.database.sqlite.SQLiteDirectCursorDriver
-android.database.sqlite.SQLiteDoneException
-android.database.sqlite.SQLiteException
-android.database.sqlite.SQLiteGlobal
-android.database.sqlite.SQLiteOpenHelper
-android.database.sqlite.SQLiteProgram
-android.database.sqlite.SQLiteQuery
-android.database.sqlite.SQLiteQueryBuilder
-android.database.sqlite.SQLiteSession
-android.database.sqlite.SQLiteSession$Transaction
-android.database.sqlite.SQLiteStatement
-android.database.sqlite.SQLiteStatementInfo
-android.database.sqlite.SQLiteTransactionListener
-android.ddm.DdmHandleAppName
-android.ddm.DdmHandleExit
-android.ddm.DdmHandleHeap
-android.ddm.DdmHandleHello
-android.ddm.DdmHandleNativeHeap
-android.ddm.DdmHandleProfiling
-android.ddm.DdmHandleThread
-android.ddm.DdmHandleViewDebug
-android.ddm.DdmRegister
-android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8
-android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$1
-android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$2
-android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$4
-android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$6
-android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$7
-android.graphics.-$Lambda$ZrP-zejiEXAqfwV-MyP5lE9mYC8$8
-android.graphics.BaseCanvas
-android.graphics.Bitmap
-android.graphics.Bitmap$1
-android.graphics.Bitmap$CompressFormat
-android.graphics.Bitmap$Config
-android.graphics.BitmapFactory
-android.graphics.BitmapFactory$Options
-android.graphics.BitmapRegionDecoder
-android.graphics.BitmapShader
-android.graphics.BlurMaskFilter
-android.graphics.Camera
-android.graphics.Canvas
-android.graphics.Canvas$EdgeType
-android.graphics.Canvas$NoImagePreloadHolder
-android.graphics.CanvasProperty
-android.graphics.Color
-android.graphics.ColorFilter
-android.graphics.ColorMatrixColorFilter
-android.graphics.ColorSpace
-android.graphics.ColorSpace$Lab
-android.graphics.ColorSpace$Model
-android.graphics.ColorSpace$Named
-android.graphics.ColorSpace$Rgb
-android.graphics.ColorSpace$Rgb$TransferParameters
-android.graphics.ColorSpace$Xyz
-android.graphics.ComposePathEffect
-android.graphics.ComposeShader
-android.graphics.CornerPathEffect
-android.graphics.DashPathEffect
-android.graphics.DiscretePathEffect
-android.graphics.DrawFilter
-android.graphics.EmbossMaskFilter
-android.graphics.FontFamily
-android.graphics.FontListParser
-android.graphics.GraphicBuffer
-android.graphics.GraphicBuffer$1
-android.graphics.Insets
-android.graphics.Interpolator
-android.graphics.Interpolator$Result
-android.graphics.LightingColorFilter
-android.graphics.LinearGradient
-android.graphics.MaskFilter
-android.graphics.Matrix
-android.graphics.Matrix$1
-android.graphics.Matrix$NoImagePreloadHolder
-android.graphics.Matrix$ScaleToFit
-android.graphics.Movie
-android.graphics.NinePatch
-android.graphics.NinePatch$InsetStruct
-android.graphics.Outline
-android.graphics.Paint
-android.graphics.Paint$Align
-android.graphics.Paint$Cap
-android.graphics.Paint$FontMetrics
-android.graphics.Paint$FontMetricsInt
-android.graphics.Paint$Join
-android.graphics.Paint$NoImagePreloadHolder
-android.graphics.Paint$Style
-android.graphics.PaintFlagsDrawFilter
-android.graphics.Path
-android.graphics.Path$Direction
-android.graphics.Path$FillType
-android.graphics.PathDashPathEffect
-android.graphics.PathEffect
-android.graphics.PathMeasure
-android.graphics.Picture
-android.graphics.Point
-android.graphics.Point$1
-android.graphics.PointF
-android.graphics.PointF$1
-android.graphics.PorterDuff
-android.graphics.PorterDuff$Mode
-android.graphics.PorterDuffColorFilter
-android.graphics.PorterDuffXfermode
-android.graphics.RadialGradient
-android.graphics.Rect
-android.graphics.Rect$1
-android.graphics.RectF
-android.graphics.RectF$1
-android.graphics.Region
-android.graphics.Region$1
-android.graphics.Region$Op
-android.graphics.RegionIterator
-android.graphics.Shader
-android.graphics.Shader$TileMode
-android.graphics.SumPathEffect
-android.graphics.SurfaceTexture
-android.graphics.SweepGradient
-android.graphics.TableMaskFilter
-android.graphics.TemporaryBuffer
-android.graphics.Typeface
-android.graphics.Xfermode
-android.graphics.YuvImage
-android.graphics.drawable.AdaptiveIconDrawable
-android.graphics.drawable.Animatable
-android.graphics.drawable.Animatable2
-android.graphics.drawable.AnimatedStateListDrawable
-android.graphics.drawable.AnimatedStateListDrawable$AnimatedStateListState
-android.graphics.drawable.AnimatedVectorDrawable
-android.graphics.drawable.AnimatedVectorDrawable$1
-android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState
-android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator
-android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimator
-android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT
-android.graphics.drawable.AnimationDrawable
-android.graphics.drawable.AnimationDrawable$AnimationState
-android.graphics.drawable.BitmapDrawable
-android.graphics.drawable.BitmapDrawable$BitmapState
-android.graphics.drawable.ColorDrawable
-android.graphics.drawable.ColorDrawable$ColorState
-android.graphics.drawable.Drawable
-android.graphics.drawable.Drawable$Callback
-android.graphics.drawable.Drawable$ConstantState
-android.graphics.drawable.DrawableContainer
-android.graphics.drawable.DrawableContainer$BlockInvalidateCallback
-android.graphics.drawable.DrawableContainer$DrawableContainerState
-android.graphics.drawable.DrawableInflater
-android.graphics.drawable.DrawableWrapper
-android.graphics.drawable.DrawableWrapper$DrawableWrapperState
-android.graphics.drawable.GradientDrawable
-android.graphics.drawable.GradientDrawable$GradientState
-android.graphics.drawable.GradientDrawable$Orientation
-android.graphics.drawable.Icon
-android.graphics.drawable.Icon$1
-android.graphics.drawable.InsetDrawable
-android.graphics.drawable.InsetDrawable$InsetState
-android.graphics.drawable.InsetDrawable$InsetValue
-android.graphics.drawable.LayerDrawable
-android.graphics.drawable.LayerDrawable$ChildDrawable
-android.graphics.drawable.LayerDrawable$LayerState
-android.graphics.drawable.NinePatchDrawable
-android.graphics.drawable.NinePatchDrawable$NinePatchState
-android.graphics.drawable.RippleBackground
-android.graphics.drawable.RippleBackground$1
-android.graphics.drawable.RippleBackground$BackgroundProperty
-android.graphics.drawable.RippleComponent
-android.graphics.drawable.RippleComponent$RenderNodeAnimatorSet
-android.graphics.drawable.RippleDrawable
-android.graphics.drawable.RippleDrawable$RippleState
-android.graphics.drawable.RippleForeground
-android.graphics.drawable.RippleForeground$1
-android.graphics.drawable.RippleForeground$2
-android.graphics.drawable.RippleForeground$3
-android.graphics.drawable.RippleForeground$4
-android.graphics.drawable.RippleForeground$LogDecelerateInterpolator
-android.graphics.drawable.ScaleDrawable
-android.graphics.drawable.ScaleDrawable$ScaleState
-android.graphics.drawable.ShapeDrawable
-android.graphics.drawable.ShapeDrawable$ShapeState
-android.graphics.drawable.StateListDrawable
-android.graphics.drawable.StateListDrawable$StateListState
-android.graphics.drawable.TransitionDrawable
-android.graphics.drawable.TransitionDrawable$TransitionState
-android.graphics.drawable.VectorDrawable
-android.graphics.drawable.VectorDrawable$VFullPath
-android.graphics.drawable.VectorDrawable$VFullPath$1
-android.graphics.drawable.VectorDrawable$VFullPath$10
-android.graphics.drawable.VectorDrawable$VFullPath$2
-android.graphics.drawable.VectorDrawable$VFullPath$3
-android.graphics.drawable.VectorDrawable$VFullPath$4
-android.graphics.drawable.VectorDrawable$VFullPath$5
-android.graphics.drawable.VectorDrawable$VFullPath$6
-android.graphics.drawable.VectorDrawable$VFullPath$7
-android.graphics.drawable.VectorDrawable$VFullPath$8
-android.graphics.drawable.VectorDrawable$VFullPath$9
-android.graphics.drawable.VectorDrawable$VGroup
-android.graphics.drawable.VectorDrawable$VGroup$1
-android.graphics.drawable.VectorDrawable$VGroup$2
-android.graphics.drawable.VectorDrawable$VGroup$3
-android.graphics.drawable.VectorDrawable$VGroup$4
-android.graphics.drawable.VectorDrawable$VGroup$5
-android.graphics.drawable.VectorDrawable$VGroup$6
-android.graphics.drawable.VectorDrawable$VGroup$7
-android.graphics.drawable.VectorDrawable$VGroup$8
-android.graphics.drawable.VectorDrawable$VGroup$9
-android.graphics.drawable.VectorDrawable$VObject
-android.graphics.drawable.VectorDrawable$VPath
-android.graphics.drawable.VectorDrawable$VPath$1
-android.graphics.drawable.VectorDrawable$VectorDrawableState
-android.graphics.drawable.VectorDrawable$VectorDrawableState$1
-android.graphics.drawable.shapes.OvalShape
-android.graphics.drawable.shapes.RectShape
-android.graphics.drawable.shapes.Shape
-android.graphics.fonts.FontVariationAxis
-android.graphics.pdf.PdfDocument
-android.graphics.pdf.PdfEditor
-android.graphics.pdf.PdfRenderer
-android.hardware.Camera
-android.hardware.Camera$CameraInfo
-android.hardware.Camera$Face
-android.hardware.ConsumerIrManager
-android.hardware.HardwareBuffer
-android.hardware.HardwareBuffer$1
-android.hardware.ICameraService
-android.hardware.ICameraService$Stub
-android.hardware.ICameraService$Stub$Proxy
-android.hardware.Sensor
-android.hardware.SensorEvent
-android.hardware.SensorEventListener
-android.hardware.SensorManager
-android.hardware.SerialManager
-android.hardware.SerialPort
-android.hardware.SystemSensorManager
-android.hardware.SystemSensorManager$BaseEventQueue
-android.hardware.SystemSensorManager$SensorEventQueue
-android.hardware.camera2.CameraAccessException
-android.hardware.camera2.CameraCharacteristics
-android.hardware.camera2.CameraCharacteristics$1
-android.hardware.camera2.CameraCharacteristics$2
-android.hardware.camera2.CameraCharacteristics$3
-android.hardware.camera2.CameraCharacteristics$4
-android.hardware.camera2.CameraCharacteristics$5
-android.hardware.camera2.CameraCharacteristics$Key
-android.hardware.camera2.CameraManager
-android.hardware.camera2.CameraMetadata
-android.hardware.camera2.CaptureRequest
-android.hardware.camera2.CaptureRequest$1
-android.hardware.camera2.CaptureRequest$2
-android.hardware.camera2.CaptureRequest$Key
-android.hardware.camera2.CaptureResult
-android.hardware.camera2.CaptureResult$1
-android.hardware.camera2.CaptureResult$2
-android.hardware.camera2.CaptureResult$3
-android.hardware.camera2.CaptureResult$Key
-android.hardware.camera2.DngCreator
-android.hardware.camera2.impl.CameraMetadataNative
-android.hardware.camera2.impl.CameraMetadataNative$1
-android.hardware.camera2.impl.CameraMetadataNative$10
-android.hardware.camera2.impl.CameraMetadataNative$11
-android.hardware.camera2.impl.CameraMetadataNative$12
-android.hardware.camera2.impl.CameraMetadataNative$13
-android.hardware.camera2.impl.CameraMetadataNative$14
-android.hardware.camera2.impl.CameraMetadataNative$15
-android.hardware.camera2.impl.CameraMetadataNative$16
-android.hardware.camera2.impl.CameraMetadataNative$17
-android.hardware.camera2.impl.CameraMetadataNative$18
-android.hardware.camera2.impl.CameraMetadataNative$19
-android.hardware.camera2.impl.CameraMetadataNative$2
-android.hardware.camera2.impl.CameraMetadataNative$3
-android.hardware.camera2.impl.CameraMetadataNative$4
-android.hardware.camera2.impl.CameraMetadataNative$5
-android.hardware.camera2.impl.CameraMetadataNative$6
-android.hardware.camera2.impl.CameraMetadataNative$7
-android.hardware.camera2.impl.CameraMetadataNative$8
-android.hardware.camera2.impl.CameraMetadataNative$9
-android.hardware.camera2.impl.CameraMetadataNative$Key
-android.hardware.camera2.impl.GetCommand
-android.hardware.camera2.impl.SetCommand
-android.hardware.camera2.legacy.LegacyCameraDevice
-android.hardware.camera2.legacy.PerfMeasurement
-android.hardware.camera2.marshal.MarshalQueryable
-android.hardware.camera2.marshal.MarshalRegistry
-android.hardware.camera2.marshal.impl.MarshalQueryableArray
-android.hardware.camera2.marshal.impl.MarshalQueryableBlackLevelPattern
-android.hardware.camera2.marshal.impl.MarshalQueryableBoolean
-android.hardware.camera2.marshal.impl.MarshalQueryableColorSpaceTransform
-android.hardware.camera2.marshal.impl.MarshalQueryableEnum
-android.hardware.camera2.marshal.impl.MarshalQueryableHighSpeedVideoConfiguration
-android.hardware.camera2.marshal.impl.MarshalQueryableMeteringRectangle
-android.hardware.camera2.marshal.impl.MarshalQueryableNativeByteToInteger
-android.hardware.camera2.marshal.impl.MarshalQueryablePair
-android.hardware.camera2.marshal.impl.MarshalQueryableParcelable
-android.hardware.camera2.marshal.impl.MarshalQueryablePrimitive
-android.hardware.camera2.marshal.impl.MarshalQueryableRange
-android.hardware.camera2.marshal.impl.MarshalQueryableRect
-android.hardware.camera2.marshal.impl.MarshalQueryableReprocessFormatsMap
-android.hardware.camera2.marshal.impl.MarshalQueryableRggbChannelVector
-android.hardware.camera2.marshal.impl.MarshalQueryableSize
-android.hardware.camera2.marshal.impl.MarshalQueryableSizeF
-android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfiguration
-android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfigurationDuration
-android.hardware.camera2.marshal.impl.MarshalQueryableString
-android.hardware.camera2.params.BlackLevelPattern
-android.hardware.camera2.params.ColorSpaceTransform
-android.hardware.camera2.params.Face
-android.hardware.camera2.params.HighSpeedVideoConfiguration
-android.hardware.camera2.params.LensShadingMap
-android.hardware.camera2.params.MeteringRectangle
-android.hardware.camera2.params.ReprocessFormatsMap
-android.hardware.camera2.params.RggbChannelVector
-android.hardware.camera2.params.StreamConfiguration
-android.hardware.camera2.params.StreamConfigurationDuration
-android.hardware.camera2.params.StreamConfigurationMap
-android.hardware.camera2.params.TonemapCurve
-android.hardware.camera2.utils.TypeReference
-android.hardware.camera2.utils.TypeReference$SpecializedTypeReference
-android.hardware.display.DisplayManager
-android.hardware.display.DisplayManager$DisplayListener
-android.hardware.display.DisplayManagerGlobal
-android.hardware.display.DisplayManagerGlobal$DisplayListenerDelegate
-android.hardware.display.DisplayManagerGlobal$DisplayManagerCallback
-android.hardware.display.IDisplayManager
-android.hardware.display.IDisplayManager$Stub
-android.hardware.display.IDisplayManager$Stub$Proxy
-android.hardware.display.IDisplayManagerCallback
-android.hardware.display.IDisplayManagerCallback$Stub
-android.hardware.fingerprint.FingerprintManager
-android.hardware.hdmi.HdmiControlManager
-android.hardware.input.IInputDevicesChangedListener
-android.hardware.input.IInputDevicesChangedListener$Stub
-android.hardware.input.IInputManager
-android.hardware.input.IInputManager$Stub
-android.hardware.input.IInputManager$Stub$Proxy
-android.hardware.input.InputDeviceIdentifier
-android.hardware.input.InputDeviceIdentifier$1
-android.hardware.input.InputManager
-android.hardware.input.InputManager$InputDevicesChangedListener
-android.hardware.location.ActivityRecognitionHardware
-android.hardware.location.ContextHubManager
-android.hardware.location.IActivityRecognitionHardware
-android.hardware.location.IActivityRecognitionHardware$Stub
-android.hardware.radio.RadioManager
-android.hardware.radio.RadioManager$AmBandConfig
-android.hardware.radio.RadioManager$AmBandConfig$1
-android.hardware.radio.RadioManager$AmBandDescriptor
-android.hardware.radio.RadioManager$AmBandDescriptor$1
-android.hardware.radio.RadioManager$BandConfig
-android.hardware.radio.RadioManager$BandConfig$1
-android.hardware.radio.RadioManager$BandDescriptor
-android.hardware.radio.RadioManager$BandDescriptor$1
-android.hardware.radio.RadioManager$FmBandConfig
-android.hardware.radio.RadioManager$FmBandConfig$1
-android.hardware.radio.RadioManager$FmBandDescriptor
-android.hardware.radio.RadioManager$FmBandDescriptor$1
-android.hardware.radio.RadioManager$ModuleProperties
-android.hardware.radio.RadioManager$ModuleProperties$1
-android.hardware.radio.RadioManager$ProgramInfo
-android.hardware.radio.RadioManager$ProgramInfo$1
-android.hardware.radio.RadioMetadata
-android.hardware.radio.RadioMetadata$1
-android.hardware.radio.RadioModule
-android.hardware.radio.RadioTuner
-android.hardware.soundtrigger.SoundTrigger
-android.hardware.soundtrigger.SoundTrigger$ConfidenceLevel
-android.hardware.soundtrigger.SoundTrigger$ConfidenceLevel$1
-android.hardware.soundtrigger.SoundTrigger$GenericRecognitionEvent
-android.hardware.soundtrigger.SoundTrigger$GenericRecognitionEvent$1
-android.hardware.soundtrigger.SoundTrigger$GenericSoundModel
-android.hardware.soundtrigger.SoundTrigger$Keyphrase
-android.hardware.soundtrigger.SoundTrigger$Keyphrase$1
-android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionEvent
-android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionEvent$1
-android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionExtra
-android.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionExtra$1
-android.hardware.soundtrigger.SoundTrigger$KeyphraseSoundModel
-android.hardware.soundtrigger.SoundTrigger$KeyphraseSoundModel$1
-android.hardware.soundtrigger.SoundTrigger$ModuleProperties
-android.hardware.soundtrigger.SoundTrigger$ModuleProperties$1
-android.hardware.soundtrigger.SoundTrigger$RecognitionConfig
-android.hardware.soundtrigger.SoundTrigger$RecognitionConfig$1
-android.hardware.soundtrigger.SoundTrigger$RecognitionEvent
-android.hardware.soundtrigger.SoundTrigger$RecognitionEvent$1
-android.hardware.soundtrigger.SoundTrigger$SoundModel
-android.hardware.soundtrigger.SoundTrigger$SoundModelEvent
-android.hardware.soundtrigger.SoundTrigger$SoundModelEvent$1
-android.hardware.soundtrigger.SoundTriggerModule
-android.hardware.usb.UsbDevice
-android.hardware.usb.UsbDeviceConnection
-android.hardware.usb.UsbManager
-android.hardware.usb.UsbRequest
-android.icu.impl.BMPSet
-android.icu.impl.CacheBase
-android.icu.impl.CacheValue
-android.icu.impl.CacheValue$NullValue
-android.icu.impl.CacheValue$SoftValue
-android.icu.impl.CacheValue$Strength
-android.icu.impl.CaseMapImpl
-android.icu.impl.CaseMapImpl$StringContextIterator
-android.icu.impl.CharTrie
-android.icu.impl.ClassLoaderUtil
-android.icu.impl.CurrencyData
-android.icu.impl.CurrencyData$CurrencyDisplayInfo
-android.icu.impl.CurrencyData$CurrencyDisplayInfoProvider
-android.icu.impl.CurrencyData$CurrencySpacingInfo
-android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingPattern
-android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingType
-android.icu.impl.ICUBinary
-android.icu.impl.ICUBinary$Authenticate
-android.icu.impl.ICUBinary$DatPackageReader
-android.icu.impl.ICUBinary$DatPackageReader$IsAcceptable
-android.icu.impl.ICUBinary$DataFile
-android.icu.impl.ICUBinary$PackageDataFile
-android.icu.impl.ICUCache
-android.icu.impl.ICUConfig
-android.icu.impl.ICUCurrencyDisplayInfoProvider
-android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo
-android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo$SpacingInfoSink
-android.icu.impl.ICUCurrencyMetaInfo
-android.icu.impl.ICUCurrencyMetaInfo$Collector
-android.icu.impl.ICUCurrencyMetaInfo$CurrencyCollector
-android.icu.impl.ICUCurrencyMetaInfo$UniqueList
-android.icu.impl.ICUData
-android.icu.impl.ICUDebug
-android.icu.impl.ICULocaleService
-android.icu.impl.ICULocaleService$ICUResourceBundleFactory
-android.icu.impl.ICULocaleService$LocaleKey
-android.icu.impl.ICULocaleService$LocaleKeyFactory
-android.icu.impl.ICUNotifier
-android.icu.impl.ICURWLock
-android.icu.impl.ICUResourceBundle
-android.icu.impl.ICUResourceBundle$1
-android.icu.impl.ICUResourceBundle$2
-android.icu.impl.ICUResourceBundle$3
-android.icu.impl.ICUResourceBundle$3$1
-android.icu.impl.ICUResourceBundle$4
-android.icu.impl.ICUResourceBundle$AvailEntry
-android.icu.impl.ICUResourceBundle$Loader
-android.icu.impl.ICUResourceBundle$OpenType
-android.icu.impl.ICUResourceBundle$WholeBundle
-android.icu.impl.ICUResourceBundleImpl
-android.icu.impl.ICUResourceBundleImpl$ResourceArray
-android.icu.impl.ICUResourceBundleImpl$ResourceContainer
-android.icu.impl.ICUResourceBundleImpl$ResourceInt
-android.icu.impl.ICUResourceBundleImpl$ResourceString
-android.icu.impl.ICUResourceBundleImpl$ResourceTable
-android.icu.impl.ICUResourceBundleReader
-android.icu.impl.ICUResourceBundleReader$Array
-android.icu.impl.ICUResourceBundleReader$Array16
-android.icu.impl.ICUResourceBundleReader$Array32
-android.icu.impl.ICUResourceBundleReader$Container
-android.icu.impl.ICUResourceBundleReader$IsAcceptable
-android.icu.impl.ICUResourceBundleReader$ReaderCache
-android.icu.impl.ICUResourceBundleReader$ReaderCacheKey
-android.icu.impl.ICUResourceBundleReader$ReaderValue
-android.icu.impl.ICUResourceBundleReader$ResourceCache
-android.icu.impl.ICUResourceBundleReader$ResourceCache$Level
-android.icu.impl.ICUResourceBundleReader$Table
-android.icu.impl.ICUResourceBundleReader$Table16
-android.icu.impl.ICUResourceBundleReader$Table1632
-android.icu.impl.ICUService
-android.icu.impl.ICUService$CacheEntry
-android.icu.impl.ICUService$Factory
-android.icu.impl.ICUService$Key
-android.icu.impl.IDNA2003
-android.icu.impl.LocaleIDParser
-android.icu.impl.LocaleIDs
-android.icu.impl.Norm2AllModes
-android.icu.impl.Norm2AllModes$1
-android.icu.impl.Norm2AllModes$ComposeNormalizer2
-android.icu.impl.Norm2AllModes$DecomposeNormalizer2
-android.icu.impl.Norm2AllModes$FCDNormalizer2
-android.icu.impl.Norm2AllModes$NFKCSingleton
-android.icu.impl.Norm2AllModes$NoopNormalizer2
-android.icu.impl.Norm2AllModes$Norm2AllModesSingleton
-android.icu.impl.Norm2AllModes$Normalizer2WithImpl
-android.icu.impl.Normalizer2Impl
-android.icu.impl.Normalizer2Impl$1
-android.icu.impl.Normalizer2Impl$IsAcceptable
-android.icu.impl.Pair
-android.icu.impl.PatternProps
-android.icu.impl.PluralRulesLoader
-android.icu.impl.ReplaceableUCharacterIterator
-android.icu.impl.RuleCharacterIterator
-android.icu.impl.SimpleCache
-android.icu.impl.SoftCache
-android.icu.impl.StandardPlural
-android.icu.impl.StringPrepDataReader
-android.icu.impl.Trie
-android.icu.impl.Trie$DataManipulate
-android.icu.impl.Trie$DefaultGetFoldingOffset
-android.icu.impl.Trie2
-android.icu.impl.Trie2$1
-android.icu.impl.Trie2$Range
-android.icu.impl.Trie2$Trie2Iterator
-android.icu.impl.Trie2$UTrie2Header
-android.icu.impl.Trie2$ValueMapper
-android.icu.impl.Trie2$ValueWidth
-android.icu.impl.Trie2_16
-android.icu.impl.UBiDiProps
-android.icu.impl.UBiDiProps$IsAcceptable
-android.icu.impl.UCaseProps
-android.icu.impl.UCaseProps$ContextIterator
-android.icu.impl.UCaseProps$IsAcceptable
-android.icu.impl.UCharacterProperty
-android.icu.impl.UCharacterProperty$1
-android.icu.impl.UCharacterProperty$10
-android.icu.impl.UCharacterProperty$11
-android.icu.impl.UCharacterProperty$12
-android.icu.impl.UCharacterProperty$13
-android.icu.impl.UCharacterProperty$14
-android.icu.impl.UCharacterProperty$15
-android.icu.impl.UCharacterProperty$16
-android.icu.impl.UCharacterProperty$17
-android.icu.impl.UCharacterProperty$18
-android.icu.impl.UCharacterProperty$19
-android.icu.impl.UCharacterProperty$2
-android.icu.impl.UCharacterProperty$20
-android.icu.impl.UCharacterProperty$21
-android.icu.impl.UCharacterProperty$22
-android.icu.impl.UCharacterProperty$23
-android.icu.impl.UCharacterProperty$3
-android.icu.impl.UCharacterProperty$4
-android.icu.impl.UCharacterProperty$5
-android.icu.impl.UCharacterProperty$6
-android.icu.impl.UCharacterProperty$7
-android.icu.impl.UCharacterProperty$8
-android.icu.impl.UCharacterProperty$9
-android.icu.impl.UCharacterProperty$BiDiIntProperty
-android.icu.impl.UCharacterProperty$BinaryProperty
-android.icu.impl.UCharacterProperty$CaseBinaryProperty
-android.icu.impl.UCharacterProperty$CombiningClassIntProperty
-android.icu.impl.UCharacterProperty$IntProperty
-android.icu.impl.UCharacterProperty$IsAcceptable
-android.icu.impl.UCharacterProperty$NormInertBinaryProperty
-android.icu.impl.UCharacterProperty$NormQuickCheckIntProperty
-android.icu.impl.URLHandler$URLVisitor
-android.icu.impl.UResource$Array
-android.icu.impl.UResource$Key
-android.icu.impl.UResource$Sink
-android.icu.impl.UResource$Table
-android.icu.impl.UResource$Value
-android.icu.impl.Utility
-android.icu.impl.locale.AsciiUtil
-android.icu.impl.locale.BaseLocale
-android.icu.impl.locale.BaseLocale$Cache
-android.icu.impl.locale.BaseLocale$Key
-android.icu.impl.locale.LocaleObjectCache
-android.icu.impl.locale.LocaleObjectCache$CacheEntry
-android.icu.impl.locale.LocaleSyntaxException
-android.icu.lang.UCharacter
-android.icu.lang.UCharacterEnums$ECharacterCategory
-android.icu.lang.UCharacterEnums$ECharacterDirection
-android.icu.math.BigDecimal
-android.icu.math.MathContext
-android.icu.text.BreakIterator
-android.icu.text.BreakIterator$BreakIteratorCache
-android.icu.text.BreakIterator$BreakIteratorServiceShim
-android.icu.text.BreakIteratorFactory
-android.icu.text.BreakIteratorFactory$BFService
-android.icu.text.BreakIteratorFactory$BFService$1RBBreakIteratorFactory
-android.icu.text.CaseMap
-android.icu.text.CaseMap$Upper
-android.icu.text.CurrencyDisplayNames
-android.icu.text.CurrencyMetaInfo
-android.icu.text.CurrencyMetaInfo$CurrencyDigits
-android.icu.text.CurrencyMetaInfo$CurrencyFilter
-android.icu.text.DecimalFormat
-android.icu.text.DecimalFormat$Unit
-android.icu.text.DecimalFormatSymbols
-android.icu.text.DecimalFormatSymbols$1
-android.icu.text.DecimalFormatSymbols$CacheData
-android.icu.text.DecimalFormatSymbols$DecFmtDataSink
-android.icu.text.DigitList
-android.icu.text.DisplayContext
-android.icu.text.DisplayContext$Type
-android.icu.text.IDNA
-android.icu.text.LanguageBreakEngine
-android.icu.text.Normalizer
-android.icu.text.Normalizer$FCDMode
-android.icu.text.Normalizer$Mode
-android.icu.text.Normalizer$ModeImpl
-android.icu.text.Normalizer$NFCMode
-android.icu.text.Normalizer$NFDMode
-android.icu.text.Normalizer$NFKCMode
-android.icu.text.Normalizer$NFKDMode
-android.icu.text.Normalizer$NFKDModeImpl
-android.icu.text.Normalizer$NONEMode
-android.icu.text.Normalizer$QuickCheckResult
-android.icu.text.Normalizer2
-android.icu.text.NumberFormat
-android.icu.text.NumberFormat$Field
-android.icu.text.NumberingSystem
-android.icu.text.NumberingSystem$1
-android.icu.text.NumberingSystem$2
-android.icu.text.NumberingSystem$LocaleLookupData
-android.icu.text.PluralRanges
-android.icu.text.PluralRanges$Matrix
-android.icu.text.PluralRules
-android.icu.text.PluralRules$1
-android.icu.text.PluralRules$AndConstraint
-android.icu.text.PluralRules$BinaryConstraint
-android.icu.text.PluralRules$Constraint
-android.icu.text.PluralRules$Factory
-android.icu.text.PluralRules$FixedDecimal
-android.icu.text.PluralRules$FixedDecimalRange
-android.icu.text.PluralRules$FixedDecimalSamples
-android.icu.text.PluralRules$Operand
-android.icu.text.PluralRules$PluralType
-android.icu.text.PluralRules$RangeConstraint
-android.icu.text.PluralRules$Rule
-android.icu.text.PluralRules$RuleList
-android.icu.text.PluralRules$SampleType
-android.icu.text.PluralRules$SimpleTokenizer
-android.icu.text.RBBIDataWrapper
-android.icu.text.RBBIDataWrapper$IsAcceptable
-android.icu.text.RBBIDataWrapper$RBBIDataHeader
-android.icu.text.RBBIDataWrapper$TrieFoldingFunc
-android.icu.text.Replaceable
-android.icu.text.ReplaceableString
-android.icu.text.RuleBasedBreakIterator
-android.icu.text.RuleBasedBreakIterator$LookAheadResults
-android.icu.text.StringPrep
-android.icu.text.StringPrepParseException
-android.icu.text.TimeZoneNames$NameType
-android.icu.text.UCharacterIterator
-android.icu.text.UFieldPosition
-android.icu.text.UFormat
-android.icu.text.UForwardCharacterIterator
-android.icu.text.UTF16
-android.icu.text.UnhandledBreakEngine
-android.icu.text.UnicodeFilter
-android.icu.text.UnicodeMatcher
-android.icu.text.UnicodeSet
-android.icu.util.Currency
-android.icu.util.Currency$1
-android.icu.util.Currency$CurrencyUsage
-android.icu.util.Currency$EquivalenceRelation
-android.icu.util.Freezable
-android.icu.util.MeasureUnit
-android.icu.util.MeasureUnit$1
-android.icu.util.MeasureUnit$2
-android.icu.util.MeasureUnit$3
-android.icu.util.MeasureUnit$Factory
-android.icu.util.TimeUnit
-android.icu.util.TimeZone
-android.icu.util.TimeZone$ConstantZone
-android.icu.util.ULocale
-android.icu.util.ULocale$1
-android.icu.util.ULocale$2
-android.icu.util.ULocale$Category
-android.icu.util.ULocale$JDKLocaleHelper
-android.icu.util.ULocale$Type
-android.icu.util.UResourceBundle
-android.icu.util.UResourceBundle$RootType
-android.icu.util.UResourceTypeMismatchException
-android.icu.util.VersionInfo
-android.location.BatchedLocationCallbackTransport
-android.location.BatchedLocationCallbackTransport$CallbackTransport
-android.location.CountryDetector
-android.location.GnssMeasurementCallbackTransport
-android.location.GnssMeasurementCallbackTransport$ListenerTransport
-android.location.GnssNavigationMessageCallbackTransport
-android.location.GnssNavigationMessageCallbackTransport$ListenerTransport
-android.location.IBatchedLocationCallback
-android.location.IBatchedLocationCallback$Stub
-android.location.IGnssMeasurementsListener
-android.location.IGnssMeasurementsListener$Stub
-android.location.IGnssNavigationMessageListener
-android.location.IGnssNavigationMessageListener$Stub
-android.location.ILocationManager
-android.location.ILocationManager$Stub
-android.location.ILocationManager$Stub$Proxy
-android.location.LocalListenerHelper
-android.location.Location
-android.location.LocationListener
-android.location.LocationManager
-android.location.LocationRequest
-android.location.LocationRequest$1
-android.media.AudioAttributes
-android.media.AudioAttributes$1
-android.media.AudioAttributes$Builder
-android.media.AudioDevicePort
-android.media.AudioDevicePortConfig
-android.media.AudioFormat
-android.media.AudioFormat$1
-android.media.AudioGain
-android.media.AudioGainConfig
-android.media.AudioHandle
-android.media.AudioManager
-android.media.AudioManager$1
-android.media.AudioManager$2
-android.media.AudioManager$3
-android.media.AudioManager$ServiceEventHandlerDelegate
-android.media.AudioManager$ServiceEventHandlerDelegate$1
-android.media.AudioMixPort
-android.media.AudioMixPortConfig
-android.media.AudioPatch
-android.media.AudioPort
-android.media.AudioPortConfig
-android.media.AudioPortEventHandler
-android.media.AudioRecord
-android.media.AudioRouting
-android.media.AudioSystem
-android.media.AudioTimestamp
-android.media.AudioTrack
-android.media.CamcorderProfile
-android.media.CameraProfile
-android.media.DecoderCapabilities
-android.media.EncoderCapabilities
-android.media.IAudioFocusDispatcher
-android.media.IAudioFocusDispatcher$Stub
-android.media.IAudioService
-android.media.IAudioService$Stub
-android.media.IAudioService$Stub$Proxy
-android.media.IMediaHTTPConnection
-android.media.IMediaHTTPConnection$Stub
-android.media.IPlaybackConfigDispatcher
-android.media.IPlaybackConfigDispatcher$Stub
-android.media.IPlayer
-android.media.IPlayer$Stub
-android.media.IRecordingConfigDispatcher
-android.media.IRecordingConfigDispatcher$Stub
-android.media.IRingtonePlayer
-android.media.IRingtonePlayer$Stub
-android.media.Image
-android.media.ImageReader
-android.media.ImageReader$SurfaceImage
-android.media.ImageWriter
-android.media.ImageWriter$WriterSurfaceImage
-android.media.JetPlayer
-android.media.MediaCodec
-android.media.MediaCodecList
-android.media.MediaCrypto
-android.media.MediaDescrambler
-android.media.MediaDrm
-android.media.MediaExtractor
-android.media.MediaFormat
-android.media.MediaHTTPConnection
-android.media.MediaMetadataRetriever
-android.media.MediaMuxer
-android.media.MediaPlayer
-android.media.MediaRecorder
-android.media.MediaRouter
-android.media.MediaScanner
-android.media.MediaSync
-android.media.PlaybackParams
-android.media.PlaybackParams$1
-android.media.PlayerBase
-android.media.PlayerBase$IAppOpsCallbackWrapper
-android.media.PlayerBase$IPlayerWrapper
-android.media.PlayerBase$PlayerIdCard
-android.media.PlayerBase$PlayerIdCard$1
-android.media.RemoteDisplay
-android.media.ResampleInputStream
-android.media.SoundPool
-android.media.SubtitleController$Listener
-android.media.ToneGenerator
-android.media.VolumeAutomation
-android.media.VolumeShaper$Configuration
-android.media.VolumeShaper$Configuration$1
-android.media.VolumeShaper$Configuration$Builder
-android.media.VolumeShaper$Operation
-android.media.VolumeShaper$Operation$1
-android.media.VolumeShaper$Operation$Builder
-android.media.VolumeShaper$State
-android.media.VolumeShaper$State$1
-android.media.audiopolicy.AudioMix
-android.media.audiopolicy.AudioMixingRule
-android.media.audiopolicy.AudioMixingRule$AudioMixMatchCriterion
-android.media.midi.MidiManager
-android.media.projection.MediaProjectionManager
-android.media.session.IActiveSessionsListener
-android.media.session.IActiveSessionsListener$Stub
-android.media.session.ISessionController
-android.media.session.ISessionController$Stub
-android.media.session.ISessionControllerCallback
-android.media.session.ISessionControllerCallback$Stub
-android.media.session.ISessionManager
-android.media.session.ISessionManager$Stub
-android.media.session.MediaController
-android.media.session.MediaController$CallbackStub
-android.media.session.MediaController$TransportControls
-android.media.session.MediaSession$Token
-android.media.session.MediaSession$Token$1
-android.media.session.MediaSessionManager
-android.media.session.PlaybackState
-android.media.session.PlaybackState$1
-android.media.session.PlaybackState$CustomAction
-android.media.session.PlaybackState$CustomAction$1
-android.media.soundtrigger.SoundTriggerManager
-android.media.tv.TvInputManager
-android.mtp.MtpDatabase
-android.mtp.MtpDevice
-android.mtp.MtpDeviceInfo
-android.mtp.MtpEvent
-android.mtp.MtpObjectInfo
-android.mtp.MtpPropertyGroup
-android.mtp.MtpPropertyList
-android.mtp.MtpServer
-android.mtp.MtpStorage
-android.mtp.MtpStorageInfo
-android.net.ConnectivityManager
-android.net.ConnectivityManager$CallbackHandler
-android.net.ConnectivityManager$NetworkCallback
-android.net.ConnectivityThread
-android.net.Credentials
-android.net.DhcpInfo
-android.net.DhcpInfo$1
-android.net.EthernetManager
-android.net.IConnectivityManager
-android.net.IConnectivityManager$Stub
-android.net.IConnectivityManager$Stub$Proxy
-android.net.INetworkPolicyManager
-android.net.INetworkPolicyManager$Stub
-android.net.INetworkScoreService
-android.net.INetworkScoreService$Stub
-android.net.INetworkScoreService$Stub$Proxy
-android.net.INetworkStatsService
-android.net.INetworkStatsService$Stub
-android.net.INetworkStatsService$Stub$Proxy
-android.net.IpConfiguration
-android.net.IpConfiguration$1
-android.net.IpConfiguration$IpAssignment
-android.net.IpConfiguration$ProxySettings
-android.net.IpPrefix
-android.net.IpPrefix$1
-android.net.IpSecManager
-android.net.LinkAddress
-android.net.LinkAddress$1
-android.net.LinkProperties
-android.net.LinkProperties$1
-android.net.LocalServerSocket
-android.net.LocalSocket
-android.net.LocalSocketAddress
-android.net.LocalSocketAddress$Namespace
-android.net.LocalSocketImpl
-android.net.LocalSocketImpl$SocketInputStream
-android.net.LocalSocketImpl$SocketOutputStream
-android.net.Network
-android.net.Network$1
-android.net.NetworkCapabilities
-android.net.NetworkCapabilities$1
-android.net.NetworkFactory
-android.net.NetworkInfo
-android.net.NetworkInfo$1
-android.net.NetworkInfo$DetailedState
-android.net.NetworkInfo$State
-android.net.NetworkKey
-android.net.NetworkKey$1
-android.net.NetworkPolicyManager
-android.net.NetworkRequest
-android.net.NetworkRequest$1
-android.net.NetworkRequest$Builder
-android.net.NetworkRequest$Type
-android.net.NetworkScoreManager
-android.net.NetworkSpecifier
-android.net.NetworkStats
-android.net.NetworkStats$1
-android.net.NetworkUtils
-android.net.Proxy
-android.net.ProxyInfo
-android.net.RouteInfo
-android.net.RouteInfo$1
-android.net.RssiCurve
-android.net.RssiCurve$1
-android.net.SSLCertificateSocketFactory
-android.net.SSLCertificateSocketFactory$1
-android.net.SSLSessionCache
-android.net.ScoredNetwork
-android.net.ScoredNetwork$1
-android.net.StaticIpConfiguration
-android.net.TrafficStats
-android.net.Uri
-android.net.Uri$1
-android.net.Uri$AbstractHierarchicalUri
-android.net.Uri$AbstractPart
-android.net.Uri$Builder
-android.net.Uri$HierarchicalUri
-android.net.Uri$OpaqueUri
-android.net.Uri$Part
-android.net.Uri$Part$EmptyPart
-android.net.Uri$PathPart
-android.net.Uri$PathSegments
-android.net.Uri$PathSegmentsBuilder
-android.net.Uri$StringUri
-android.net.WifiKey
-android.net.WifiKey$1
-android.net.nsd.NsdManager
-android.net.wifi.IWifiManager
-android.net.wifi.IWifiManager$Stub
-android.net.wifi.IWifiManager$Stub$Proxy
-android.net.wifi.ParcelUtil
-android.net.wifi.RttManager
-android.net.wifi.ScanResult
-android.net.wifi.ScanResult$1
-android.net.wifi.ScanResult$InformationElement
-android.net.wifi.SupplicantState
-android.net.wifi.SupplicantState$1
-android.net.wifi.WifiConfiguration
-android.net.wifi.WifiConfiguration$1
-android.net.wifi.WifiConfiguration$NetworkSelectionStatus
-android.net.wifi.WifiEnterpriseConfig
-android.net.wifi.WifiEnterpriseConfig$1
-android.net.wifi.WifiInfo
-android.net.wifi.WifiInfo$1
-android.net.wifi.WifiManager
-android.net.wifi.WifiManager$WifiLock
-android.net.wifi.WifiScanner
-android.net.wifi.WifiSsid
-android.net.wifi.WifiSsid$1
-android.net.wifi.aware.WifiAwareManager
-android.net.wifi.p2p.WifiP2pManager
-android.nfc.NfcManager
-android.opengl.EGL14
-android.opengl.EGLConfig
-android.opengl.EGLContext
-android.opengl.EGLDisplay
-android.opengl.EGLExt
-android.opengl.EGLObjectHandle
-android.opengl.EGLSurface
-android.opengl.ETC1
-android.opengl.GLES10
-android.opengl.GLES10Ext
-android.opengl.GLES11
-android.opengl.GLES11Ext
-android.opengl.GLES20
-android.opengl.GLES30
-android.opengl.GLES31
-android.opengl.GLES31Ext
-android.opengl.GLES32
-android.opengl.GLUtils
-android.opengl.Matrix
-android.opengl.Visibility
-android.os.-$Lambda$6x30vPJhBKUfNY8tswxuZo3DCe0
-android.os.AsyncResult
-android.os.AsyncTask$1
-android.os.AsyncTask$2
-android.os.AsyncTask$3
-android.os.AsyncTask$AsyncTaskResult
-android.os.AsyncTask$InternalHandler
-android.os.AsyncTask$SerialExecutor
-android.os.AsyncTask$SerialExecutor$1
-android.os.AsyncTask$Status
-android.os.AsyncTask$WorkerRunnable
-android.os.BadParcelableException
-android.os.BaseBundle
-android.os.BaseBundle$NoImagePreloadHolder
-android.os.BatteryManager
-android.os.Binder
-android.os.BinderProxy
-android.os.Build
-android.os.Build$VERSION
-android.os.Bundle
-android.os.Bundle$1
-android.os.CancellationSignal
-android.os.CancellationSignal$OnCancelListener
-android.os.CancellationSignal$Transport
-android.os.ConditionVariable
-android.os.DeadObjectException
-android.os.DeadSystemException
-android.os.Debug
-android.os.Debug$MemoryInfo
-android.os.Debug$MemoryInfo$1
-android.os.DropBoxManager
-android.os.Environment
-android.os.Environment$UserEnvironment
-android.os.FactoryTest
-android.os.FileObserver$ObserverThread
-android.os.FileUtils
-android.os.GraphicsEnvironment
-android.os.Handler
-android.os.Handler$Callback
-android.os.Handler$MessengerImpl
-android.os.HandlerThread
-android.os.HardwarePropertiesManager
-android.os.HwBinder
-android.os.HwBlob
-android.os.HwParcel
-android.os.HwRemoteBinder
-android.os.IBatteryPropertiesRegistrar
-android.os.IBatteryPropertiesRegistrar$Stub
-android.os.IBatteryPropertiesRegistrar$Stub$Proxy
-android.os.IBinder
-android.os.IBinder$DeathRecipient
-android.os.ICancellationSignal
-android.os.ICancellationSignal$Stub
-android.os.IDeviceIdleController
-android.os.IDeviceIdleController$Stub
-android.os.IHwBinder
-android.os.IInterface
-android.os.IMessenger
-android.os.IMessenger$Stub
-android.os.IMessenger$Stub$Proxy
-android.os.INetworkManagementService
-android.os.INetworkManagementService$Stub
-android.os.INetworkManagementService$Stub$Proxy
-android.os.IPowerManager
-android.os.IPowerManager$Stub
-android.os.IPowerManager$Stub$Proxy
-android.os.IRemoteCallback
-android.os.IServiceManager
-android.os.IUserManager
-android.os.IUserManager$Stub
-android.os.IUserManager$Stub$Proxy
-android.os.IVibratorService
-android.os.IVibratorService$Stub
-android.os.IncidentManager
-android.os.LocaleList
-android.os.LocaleList$1
-android.os.Looper
-android.os.MemoryFile
-android.os.Message
-android.os.Message$1
-android.os.MessageQueue
-android.os.MessageQueue$IdleHandler
-android.os.Messenger
-android.os.Messenger$1
-android.os.OperationCanceledException
-android.os.Parcel
-android.os.Parcel$1
-android.os.ParcelFileDescriptor
-android.os.ParcelFileDescriptor$1
-android.os.ParcelUuid
-android.os.ParcelUuid$1
-android.os.Parcelable
-android.os.Parcelable$ClassLoaderCreator
-android.os.Parcelable$Creator
-android.os.ParcelableException
-android.os.PatternMatcher
-android.os.PatternMatcher$1
-android.os.PersistableBundle
-android.os.PersistableBundle$1
-android.os.PowerManager
-android.os.PowerManager$WakeLock
-android.os.PowerManager$WakeLock$1
-android.os.Process
-android.os.RecoverySystem
-android.os.Registrant
-android.os.RemoteCallbackList
-android.os.RemoteException
-android.os.ResultReceiver
-android.os.SELinux
-android.os.Seccomp
-android.os.ServiceManager
-android.os.ServiceManager$ServiceNotFoundException
-android.os.ServiceManagerNative
-android.os.ServiceManagerProxy
-android.os.ServiceSpecificException
-android.os.ShellCallback
-android.os.StatFs
-android.os.StrictMode
-android.os.StrictMode$1
-android.os.StrictMode$2
-android.os.StrictMode$3
-android.os.StrictMode$4
-android.os.StrictMode$5
-android.os.StrictMode$6
-android.os.StrictMode$7
-android.os.StrictMode$8
-android.os.StrictMode$9
-android.os.StrictMode$AndroidBlockGuardPolicy
-android.os.StrictMode$AndroidBlockGuardPolicy$1
-android.os.StrictMode$AndroidCloseGuardReporter
-android.os.StrictMode$InstanceCountViolation
-android.os.StrictMode$InstanceTracker
-android.os.StrictMode$LogStackTrace
-android.os.StrictMode$Span
-android.os.StrictMode$StrictModeDiskReadViolation
-android.os.StrictMode$StrictModeDiskWriteViolation
-android.os.StrictMode$StrictModeViolation
-android.os.StrictMode$ThreadPolicy
-android.os.StrictMode$ThreadPolicy$Builder
-android.os.StrictMode$ThreadSpanState
-android.os.StrictMode$ViolationInfo
-android.os.StrictMode$ViolationInfo$1
-android.os.StrictMode$VmPolicy
-android.os.StrictMode$VmPolicy$Builder
-android.os.SystemClock
-android.os.SystemProperties
-android.os.SystemVibrator
-android.os.Trace
-android.os.Trace$1
-android.os.UEventObserver
-android.os.UpdateLock
-android.os.UserHandle
-android.os.UserHandle$1
-android.os.UserManager
-android.os.Vibrator
-android.os.VintfObject
-android.os.VintfRuntimeInfo
-android.os.WorkSource
-android.os.WorkSource$1
-android.os.ZygoteProcess
-android.os.ZygoteStartFailedEx
-android.os.health.SystemHealthManager
-android.os.storage.IObbActionListener
-android.os.storage.IObbActionListener$Stub
-android.os.storage.IStorageManager
-android.os.storage.IStorageManager$Stub
-android.os.storage.IStorageManager$Stub$Proxy
-android.os.storage.StorageManager
-android.os.storage.StorageManager$ObbActionListener
-android.os.storage.StorageVolume
-android.os.storage.StorageVolume$1
-android.preference.PreferenceManager
-android.print.PrintManager
-android.provider.-$Lambda$87WmhkvObehVg0OMBzwa_MTVV8g
-android.provider.-$Lambda$a7Jyr6j_Mb70hHJ2ssL1AAhKh4c
-android.provider.BaseColumns
-android.provider.CalendarContract$CalendarColumns
-android.provider.CalendarContract$CalendarSyncColumns
-android.provider.CalendarContract$EventsColumns
-android.provider.CalendarContract$SyncColumns
-android.provider.ContactsContract
-android.provider.ContactsContract$CommonDataKinds$BaseTypes
-android.provider.ContactsContract$CommonDataKinds$CommonColumns
-android.provider.ContactsContract$ContactCounts
-android.provider.ContactsContract$ContactNameColumns
-android.provider.ContactsContract$ContactOptionsColumns
-android.provider.ContactsContract$ContactStatusColumns
-android.provider.ContactsContract$ContactsColumns
-android.provider.ContactsContract$DataColumns
-android.provider.ContactsContract$DataColumnsWithJoins
-android.provider.ContactsContract$DataUsageStatColumns
-android.provider.ContactsContract$RawContactsColumns
-android.provider.ContactsContract$StatusColumns
-android.provider.Downloads$Impl
-android.provider.FontsContract
-android.provider.FontsContract$1
-android.provider.Settings
-android.provider.Settings$ContentProviderHolder
-android.provider.Settings$GenerationTracker
-android.provider.Settings$Global
-android.provider.Settings$NameValueCache
-android.provider.Settings$NameValueTable
-android.provider.Settings$Secure
-android.provider.Settings$SettingNotFoundException
-android.provider.Settings$System
-android.provider.Settings$System$1
-android.provider.Settings$System$2
-android.provider.Settings$System$3
-android.provider.Settings$System$4
-android.provider.Settings$System$5
-android.provider.Settings$System$6
-android.provider.Settings$System$7
-android.provider.Settings$System$8
-android.provider.Settings$System$9
-android.provider.Settings$System$DiscreteValueValidator
-android.provider.Settings$System$InclusiveFloatRangeValidator
-android.provider.Settings$System$InclusiveIntegerRangeValidator
-android.provider.Settings$System$Validator
-android.renderscript.RenderScriptCacheDir
-android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
-android.security.keystore.AndroidKeyStoreProvider
-android.security.net.config.ApplicationConfig
-android.security.net.config.CertificateSource
-android.security.net.config.CertificatesEntryRef
-android.security.net.config.ConfigNetworkSecurityPolicy
-android.security.net.config.ConfigSource
-android.security.net.config.DirectoryCertificateSource
-android.security.net.config.DirectoryCertificateSource$1
-android.security.net.config.DirectoryCertificateSource$3
-android.security.net.config.DirectoryCertificateSource$CertSelector
-android.security.net.config.ManifestConfigSource
-android.security.net.config.ManifestConfigSource$DefaultConfigSource
-android.security.net.config.NetworkSecurityConfig
-android.security.net.config.NetworkSecurityConfig$1
-android.security.net.config.NetworkSecurityConfig$Builder
-android.security.net.config.NetworkSecurityConfigProvider
-android.security.net.config.NetworkSecurityTrustManager
-android.security.net.config.PinSet
-android.security.net.config.RootTrustManager
-android.security.net.config.RootTrustManagerFactorySpi
-android.security.net.config.SystemCertificateSource
-android.security.net.config.TrustedCertificateStoreAdapter
-android.security.net.config.UserCertificateSource
-android.service.notification.StatusBarNotification
-android.service.oemlock.OemLockManager
-android.service.persistentdata.IPersistentDataBlockService
-android.service.persistentdata.IPersistentDataBlockService$Stub
-android.service.persistentdata.IPersistentDataBlockService$Stub$Proxy
-android.service.persistentdata.PersistentDataBlockManager
-android.system.ErrnoException
-android.system.GaiException
-android.system.NetlinkSocketAddress
-android.system.Os
-android.system.OsConstants
-android.system.PacketSocketAddress
-android.system.StructAddrinfo
-android.system.StructFlock
-android.system.StructGroupReq
-android.system.StructGroupSourceReq
-android.system.StructIfaddrs
-android.system.StructLinger
-android.system.StructPasswd
-android.system.StructPollfd
-android.system.StructStat
-android.system.StructStatVfs
-android.system.StructTimeval
-android.system.StructUcred
-android.system.StructUtsname
-android.system.UnixSocketAddress
-android.telecom.TelecomManager
-android.telephony.CarrierConfigManager
-android.telephony.CellIdentityWcdma
-android.telephony.CellIdentityWcdma$1
-android.telephony.CellInfo
-android.telephony.CellInfo$1
-android.telephony.CellInfoWcdma
-android.telephony.CellInfoWcdma$1
-android.telephony.CellLocation
-android.telephony.CellSignalStrength
-android.telephony.CellSignalStrengthWcdma
-android.telephony.CellSignalStrengthWcdma$1
-android.telephony.PhoneStateListener
-android.telephony.PhoneStateListener$1
-android.telephony.PhoneStateListener$IPhoneStateListenerStub
-android.telephony.Rlog
-android.telephony.ServiceState
-android.telephony.ServiceState$1
-android.telephony.SignalStrength
-android.telephony.SignalStrength$1
-android.telephony.SubscriptionInfo
-android.telephony.SubscriptionInfo$1
-android.telephony.SubscriptionManager
-android.telephony.SubscriptionManager$OnSubscriptionsChangedListener
-android.telephony.SubscriptionManager$OnSubscriptionsChangedListener$1
-android.telephony.SubscriptionManager$OnSubscriptionsChangedListener$2
-android.telephony.TelephonyManager
-android.telephony.TelephonyManager$MultiSimVariants
-android.text.AndroidBidi
-android.text.AndroidCharacter
-android.text.BoringLayout
-android.text.BoringLayout$Metrics
-android.text.ClipboardManager
-android.text.DynamicLayout
-android.text.DynamicLayout$ChangeWatcher
-android.text.Editable
-android.text.Editable$Factory
-android.text.FontConfig
-android.text.FontConfig$Alias
-android.text.FontConfig$Family
-android.text.FontConfig$Font
-android.text.GetChars
-android.text.GraphicsOperations
-android.text.Hyphenator
-android.text.Hyphenator$HyphenationData
-android.text.InputFilter
-android.text.InputType
-android.text.Layout
-android.text.Layout$Alignment
-android.text.Layout$Directions
-android.text.Layout$Ellipsizer
-android.text.MeasuredText
-android.text.NoCopySpan
-android.text.NoCopySpan$Concrete
-android.text.PackedIntVector
-android.text.PackedObjectVector
-android.text.ParcelableSpan
-android.text.Selection
-android.text.Selection$END
-android.text.Selection$START
-android.text.SpanSet
-android.text.SpanWatcher
-android.text.Spannable
-android.text.Spannable$Factory
-android.text.SpannableString
-android.text.SpannableStringBuilder
-android.text.SpannableStringInternal
-android.text.Spanned
-android.text.SpannedString
-android.text.StaticLayout
-android.text.StaticLayout$Builder
-android.text.StaticLayout$LineBreaks
-android.text.TextDirectionHeuristic
-android.text.TextDirectionHeuristics
-android.text.TextDirectionHeuristics$AnyStrong
-android.text.TextDirectionHeuristics$FirstStrong
-android.text.TextDirectionHeuristics$TextDirectionAlgorithm
-android.text.TextDirectionHeuristics$TextDirectionHeuristicImpl
-android.text.TextDirectionHeuristics$TextDirectionHeuristicInternal
-android.text.TextDirectionHeuristics$TextDirectionHeuristicLocale
-android.text.TextLine
-android.text.TextPaint
-android.text.TextUtils
-android.text.TextUtils$1
-android.text.TextUtils$EllipsizeCallback
-android.text.TextUtils$SimpleStringSplitter
-android.text.TextUtils$StringSplitter
-android.text.TextUtils$TruncateAt
-android.text.TextWatcher
-android.text.format.Time
-android.text.format.Time$TimeCalculator
-android.text.format.TimeFormatter
-android.text.method.AllCapsTransformationMethod
-android.text.method.ArrowKeyMovementMethod
-android.text.method.BaseKeyListener
-android.text.method.BaseMovementMethod
-android.text.method.KeyListener
-android.text.method.LinkMovementMethod
-android.text.method.MetaKeyKeyListener
-android.text.method.MovementMethod
-android.text.method.PasswordTransformationMethod
-android.text.method.ReplacementTransformationMethod
-android.text.method.ReplacementTransformationMethod$ReplacementCharSequence
-android.text.method.ReplacementTransformationMethod$SpannedReplacementCharSequence
-android.text.method.ScrollingMovementMethod
-android.text.method.SingleLineTransformationMethod
-android.text.method.TextKeyListener
-android.text.method.TextKeyListener$Capitalize
-android.text.method.TransformationMethod
-android.text.method.TransformationMethod2
-android.text.style.AlignmentSpan
-android.text.style.CharacterStyle
-android.text.style.EasyEditSpan
-android.text.style.LeadingMarginSpan
-android.text.style.LineBackgroundSpan
-android.text.style.LineHeightSpan
-android.text.style.MetricAffectingSpan
-android.text.style.ParagraphStyle
-android.text.style.ReplacementSpan
-android.text.style.SpellCheckSpan
-android.text.style.StyleSpan
-android.text.style.SuggestionSpan
-android.text.style.TabStopSpan
-android.text.style.UpdateAppearance
-android.text.style.UpdateLayout
-android.text.style.WrapTogetherSpan
-android.transition.AutoTransition
-android.transition.ChangeBounds
-android.transition.ChangeBounds$1
-android.transition.ChangeBounds$2
-android.transition.ChangeBounds$3
-android.transition.ChangeBounds$4
-android.transition.ChangeBounds$5
-android.transition.ChangeBounds$6
-android.transition.ChangeClipBounds
-android.transition.ChangeImageTransform
-android.transition.ChangeImageTransform$1
-android.transition.ChangeImageTransform$2
-android.transition.ChangeTransform
-android.transition.ChangeTransform$1
-android.transition.ChangeTransform$2
-android.transition.Fade
-android.transition.PathMotion
-android.transition.Transition
-android.transition.Transition$1
-android.transition.TransitionInflater
-android.transition.TransitionManager
-android.transition.TransitionSet
-android.transition.TransitionValuesMaps
-android.transition.Visibility
-android.util.AndroidException
-android.util.AndroidRuntimeException
-android.util.ArrayMap
-android.util.ArrayMap$1
-android.util.ArraySet
-android.util.ArraySet$1
-android.util.AtomicFile
-android.util.AttributeSet
-android.util.Base64
-android.util.Base64$Coder
-android.util.Base64$Decoder
-android.util.Base64$Encoder
-android.util.BootTimingsTraceLog
-android.util.ContainerHelpers
-android.util.DisplayMetrics
-android.util.EventLog
-android.util.EventLog$Event
-android.util.FloatProperty
-android.util.IntArray
-android.util.IntProperty
-android.util.Log
-android.util.Log$1
-android.util.Log$ImmediateLogWriter
-android.util.Log$TerribleFailure
-android.util.Log$TerribleFailureHandler
-android.util.LogPrinter
-android.util.LongArray
-android.util.LongSparseArray
-android.util.LongSparseLongArray
-android.util.LruCache
-android.util.MapCollections
-android.util.MapCollections$ArrayIterator
-android.util.MapCollections$EntrySet
-android.util.MapCollections$KeySet
-android.util.MapCollections$MapIterator
-android.util.MapCollections$ValuesCollection
-android.util.MathUtils
-android.util.MemoryIntArray
-android.util.MemoryIntArray$1
-android.util.MergedConfiguration
-android.util.MergedConfiguration$1
-android.util.MutableInt
-android.util.MutableLong
-android.util.Pair
-android.util.PathParser
-android.util.PathParser$PathData
-android.util.Pools$Pool
-android.util.Pools$SimplePool
-android.util.Pools$SynchronizedPool
-android.util.Printer
-android.util.Property
-android.util.Range
-android.util.Rational
-android.util.Singleton
-android.util.Size
-android.util.SizeF
-android.util.Slog
-android.util.SparseArray
-android.util.SparseBooleanArray
-android.util.SparseIntArray
-android.util.SparseLongArray
-android.util.StateSet
-android.util.SuperNotCalledException
-android.util.TimeUtils
-android.util.TypedValue
-android.util.Xml
-android.util.jar.StrictJarFile
-android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk
-android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk$1
-android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk$2
-android.view.-$Lambda$6k_RnLLpNi5zg27ubDxN4lDdBbk$3
-android.view.-$Lambda$iU_USrtPm1XIm5H9QYQvXfBGDE4
-android.view.-$Lambda$iU_USrtPm1XIm5H9QYQvXfBGDE4$1
-android.view.AbsSavedState
-android.view.AbsSavedState$1
-android.view.AbsSavedState$2
-android.view.ActionMode
-android.view.ActionMode$Callback
-android.view.ActionProvider
-android.view.Choreographer
-android.view.Choreographer$1
-android.view.Choreographer$2
-android.view.Choreographer$CallbackQueue
-android.view.Choreographer$CallbackRecord
-android.view.Choreographer$FrameCallback
-android.view.Choreographer$FrameDisplayEventReceiver
-android.view.Choreographer$FrameHandler
-android.view.ContextMenu
-android.view.ContextMenu$ContextMenuInfo
-android.view.ContextThemeWrapper
-android.view.Display
-android.view.Display$HdrCapabilities
-android.view.Display$HdrCapabilities$1
-android.view.Display$Mode
-android.view.Display$Mode$1
-android.view.DisplayAdjustments
-android.view.DisplayEventReceiver
-android.view.DisplayInfo
-android.view.DisplayInfo$1
-android.view.DisplayListCanvas
-android.view.FallbackEventHandler
-android.view.FocusFinder
-android.view.FocusFinder$1
-android.view.FocusFinder$FocusSorter
-android.view.FocusFinder$UserSpecifiedFocusComparator
-android.view.FocusFinder$UserSpecifiedFocusComparator$NextFocusGetter
-android.view.FrameInfo
-android.view.FrameMetrics
-android.view.FrameMetricsObserver
-android.view.FrameStats
-android.view.GestureDetector
-android.view.GestureDetector$GestureHandler
-android.view.GestureDetector$OnContextClickListener
-android.view.GestureDetector$OnDoubleTapListener
-android.view.GestureDetector$OnGestureListener
-android.view.GestureDetector$SimpleOnGestureListener
-android.view.Gravity
-android.view.HandlerActionQueue
-android.view.HandlerActionQueue$HandlerAction
-android.view.HardwareLayer
-android.view.IGraphicsStats
-android.view.IGraphicsStats$Stub
-android.view.IGraphicsStats$Stub$Proxy
-android.view.IGraphicsStatsCallback
-android.view.IGraphicsStatsCallback$Stub
-android.view.IRotationWatcher
-android.view.IRotationWatcher$Stub
-android.view.IWindow
-android.view.IWindow$Stub
-android.view.IWindowManager
-android.view.IWindowManager$Stub
-android.view.IWindowManager$Stub$Proxy
-android.view.IWindowSession
-android.view.IWindowSession$Stub
-android.view.IWindowSession$Stub$Proxy
-android.view.IWindowSessionCallback
-android.view.IWindowSessionCallback$Stub
-android.view.InflateException
-android.view.InputChannel
-android.view.InputChannel$1
-android.view.InputDevice
-android.view.InputDevice$1
-android.view.InputEvent
-android.view.InputEvent$1
-android.view.InputEventConsistencyVerifier
-android.view.InputEventReceiver
-android.view.InputEventSender
-android.view.InputQueue
-android.view.InputQueue$Callback
-android.view.InputQueue$FinishedInputEventCallback
-android.view.KeyCharacterMap
-android.view.KeyCharacterMap$1
-android.view.KeyCharacterMap$FallbackAction
-android.view.KeyEvent
-android.view.KeyEvent$1
-android.view.KeyEvent$Callback
-android.view.KeyEvent$DispatcherState
-android.view.LayoutInflater
-android.view.LayoutInflater$Factory
-android.view.LayoutInflater$Factory2
-android.view.LayoutInflater$FactoryMerger
-android.view.LayoutInflater$Filter
-android.view.Menu
-android.view.MenuInflater
-android.view.MenuItem
-android.view.MenuItem$OnActionExpandListener
-android.view.MenuItem$OnMenuItemClickListener
-android.view.MotionEvent
-android.view.MotionEvent$1
-android.view.MotionEvent$PointerCoords
-android.view.MotionEvent$PointerProperties
-android.view.PointerIcon
-android.view.PointerIcon$1
-android.view.RecordingCanvas
-android.view.RenderNode
-android.view.RenderNode$NoImagePreloadHolder
-android.view.RenderNodeAnimator
-android.view.RenderNodeAnimator$1
-android.view.RenderNodeAnimatorSetHelper
-android.view.SearchEvent
-android.view.SubMenu
-android.view.Surface
-android.view.Surface$1
-android.view.Surface$CompatibleCanvas
-android.view.Surface$OutOfResourcesException
-android.view.SurfaceControl
-android.view.SurfaceControl$PhysicalDisplayInfo
-android.view.SurfaceHolder$Callback
-android.view.SurfaceHolder$Callback2
-android.view.SurfaceSession
-android.view.SurfaceView
-android.view.TextureView
-android.view.ThreadedRenderer
-android.view.ThreadedRenderer$DrawCallbacks
-android.view.ThreadedRenderer$ProcessInitializer
-android.view.ThreadedRenderer$ProcessInitializer$1
-android.view.VelocityTracker
-android.view.VelocityTracker$Estimator
-android.view.View
-android.view.View$1
-android.view.View$10
-android.view.View$11
-android.view.View$12
-android.view.View$2
-android.view.View$3
-android.view.View$4
-android.view.View$5
-android.view.View$6
-android.view.View$7
-android.view.View$8
-android.view.View$9
-android.view.View$AccessibilityDelegate
-android.view.View$AttachInfo
-android.view.View$AttachInfo$Callbacks
-android.view.View$BaseSavedState
-android.view.View$BaseSavedState$1
-android.view.View$CheckForTap
-android.view.View$ForegroundInfo
-android.view.View$ListenerInfo
-android.view.View$MeasureSpec
-android.view.View$OnApplyWindowInsetsListener
-android.view.View$OnAttachStateChangeListener
-android.view.View$OnClickListener
-android.view.View$OnCreateContextMenuListener
-android.view.View$OnFocusChangeListener
-android.view.View$OnKeyListener
-android.view.View$OnLayoutChangeListener
-android.view.View$OnLongClickListener
-android.view.View$OnTouchListener
-android.view.View$PerformClick
-android.view.View$ScrollabilityCache
-android.view.View$TooltipInfo
-android.view.View$TransformationInfo
-android.view.View$UnsetPressedState
-android.view.ViewConfiguration
-android.view.ViewGroup
-android.view.ViewGroup$1
-android.view.ViewGroup$2
-android.view.ViewGroup$LayoutParams
-android.view.ViewGroup$MarginLayoutParams
-android.view.ViewGroup$OnHierarchyChangeListener
-android.view.ViewGroup$TouchTarget
-android.view.ViewManager
-android.view.ViewOutlineProvider
-android.view.ViewOutlineProvider$1
-android.view.ViewOutlineProvider$2
-android.view.ViewOutlineProvider$3
-android.view.ViewParent
-android.view.ViewPropertyAnimator
-android.view.ViewPropertyAnimator$1
-android.view.ViewPropertyAnimator$AnimatorEventListener
-android.view.ViewPropertyAnimator$NameValuesHolder
-android.view.ViewPropertyAnimator$PropertyBundle
-android.view.ViewRootImpl
-android.view.ViewRootImpl$1
-android.view.ViewRootImpl$4
-android.view.ViewRootImpl$AccessibilityInteractionConnectionManager
-android.view.ViewRootImpl$ActivityConfigCallback
-android.view.ViewRootImpl$AsyncInputStage
-android.view.ViewRootImpl$ConfigChangedCallback
-android.view.ViewRootImpl$ConsumeBatchedInputImmediatelyRunnable
-android.view.ViewRootImpl$ConsumeBatchedInputRunnable
-android.view.ViewRootImpl$EarlyPostImeInputStage
-android.view.ViewRootImpl$HighContrastTextManager
-android.view.ViewRootImpl$ImeInputStage
-android.view.ViewRootImpl$InputStage
-android.view.ViewRootImpl$InvalidateOnAnimationRunnable
-android.view.ViewRootImpl$NativePostImeInputStage
-android.view.ViewRootImpl$NativePreImeInputStage
-android.view.ViewRootImpl$QueuedInputEvent
-android.view.ViewRootImpl$SyntheticInputStage
-android.view.ViewRootImpl$SyntheticJoystickHandler
-android.view.ViewRootImpl$SyntheticKeyboardHandler
-android.view.ViewRootImpl$SyntheticTouchNavigationHandler
-android.view.ViewRootImpl$SyntheticTouchNavigationHandler$1
-android.view.ViewRootImpl$SyntheticTrackballHandler
-android.view.ViewRootImpl$TrackballAxis
-android.view.ViewRootImpl$TraversalRunnable
-android.view.ViewRootImpl$ViewPostImeInputStage
-android.view.ViewRootImpl$ViewPreImeInputStage
-android.view.ViewRootImpl$ViewRootHandler
-android.view.ViewRootImpl$W
-android.view.ViewRootImpl$WindowInputEventReceiver
-android.view.ViewRootImpl$WindowStoppedCallback
-android.view.ViewStub
-android.view.ViewTreeObserver
-android.view.ViewTreeObserver$CopyOnWriteArray
-android.view.ViewTreeObserver$CopyOnWriteArray$Access
-android.view.ViewTreeObserver$InternalInsetsInfo
-android.view.ViewTreeObserver$OnGlobalLayoutListener
-android.view.ViewTreeObserver$OnPreDrawListener
-android.view.ViewTreeObserver$OnScrollChangedListener
-android.view.ViewTreeObserver$OnTouchModeChangeListener
-android.view.Window
-android.view.Window$Callback
-android.view.Window$OnWindowDismissedCallback
-android.view.Window$OnWindowSwipeDismissedCallback
-android.view.Window$WindowControllerCallback
-android.view.WindowAnimationFrameStats
-android.view.WindowAnimationFrameStats$1
-android.view.WindowCallbacks
-android.view.WindowContentFrameStats
-android.view.WindowContentFrameStats$1
-android.view.WindowInsets
-android.view.WindowLeaked
-android.view.WindowManager
-android.view.WindowManager$BadTokenException
-android.view.WindowManager$LayoutParams
-android.view.WindowManager$LayoutParams$1
-android.view.WindowManagerGlobal
-android.view.WindowManagerGlobal$1
-android.view.WindowManagerGlobal$2
-android.view.WindowManagerImpl
-android.view.accessibility.AccessibilityEvent
-android.view.accessibility.AccessibilityEventSource
-android.view.accessibility.AccessibilityManager
-android.view.accessibility.AccessibilityManager$1
-android.view.accessibility.AccessibilityManager$AccessibilityStateChangeListener
-android.view.accessibility.AccessibilityManager$HighTextContrastChangeListener
-android.view.accessibility.AccessibilityManager$MyCallback
-android.view.accessibility.AccessibilityManager$TouchExplorationStateChangeListener
-android.view.accessibility.AccessibilityNodeInfo
-android.view.accessibility.AccessibilityNodeProvider
-android.view.accessibility.AccessibilityRecord
-android.view.accessibility.CaptioningManager
-android.view.accessibility.IAccessibilityManager
-android.view.accessibility.IAccessibilityManager$Stub
-android.view.accessibility.IAccessibilityManager$Stub$Proxy
-android.view.accessibility.IAccessibilityManagerClient
-android.view.accessibility.IAccessibilityManagerClient$Stub
-android.view.animation.AccelerateDecelerateInterpolator
-android.view.animation.AccelerateInterpolator
-android.view.animation.AlphaAnimation
-android.view.animation.Animation
-android.view.animation.Animation$AnimationListener
-android.view.animation.Animation$NoImagePreloadHolder
-android.view.animation.AnimationUtils
-android.view.animation.AnimationUtils$1
-android.view.animation.AnimationUtils$AnimationState
-android.view.animation.BaseInterpolator
-android.view.animation.DecelerateInterpolator
-android.view.animation.Interpolator
-android.view.animation.LinearInterpolator
-android.view.animation.PathInterpolator
-android.view.animation.Transformation
-android.view.autofill.AutofillManager
-android.view.autofill.AutofillManager$AutofillClient
-android.view.autofill.AutofillManager$AutofillManagerClient
-android.view.autofill.Helper
-android.view.autofill.IAutoFillManager
-android.view.autofill.IAutoFillManager$Stub
-android.view.autofill.IAutoFillManager$Stub$Proxy
-android.view.autofill.IAutoFillManagerClient
-android.view.autofill.IAutoFillManagerClient$Stub
-android.view.autofill.IAutofillWindowPresenter
-android.view.inputmethod.BaseInputConnection
-android.view.inputmethod.ComposingText
-android.view.inputmethod.CursorAnchorInfo$Builder
-android.view.inputmethod.EditorInfo
-android.view.inputmethod.EditorInfo$1
-android.view.inputmethod.InputConnection
-android.view.inputmethod.InputMethodManager
-android.view.inputmethod.InputMethodManager$1
-android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper
-android.view.inputmethod.InputMethodManager$FinishedInputEventCallback
-android.view.inputmethod.InputMethodManager$H
-android.view.textclassifier.TextClassificationManager
-android.view.textservice.TextServicesManager
-android.webkit.WebViewFactory
-android.webkit.WebViewFactory$MissingWebViewPackageException
-android.widget.AbsListView
-android.widget.AbsListView$AdapterDataSetObserver
-android.widget.AbsListView$LayoutParams
-android.widget.AbsListView$OnScrollListener
-android.widget.AbsListView$RecycleBin
-android.widget.AbsSeekBar
-android.widget.AbsSpinner
-android.widget.Adapter
-android.widget.AdapterView
-android.widget.AdapterView$AdapterDataSetObserver
-android.widget.AdapterView$OnItemClickListener
-android.widget.AdapterView$OnItemSelectedListener
-android.widget.AutoCompleteTextView
-android.widget.BaseAdapter
-android.widget.Button
-android.widget.CheckBox
-android.widget.Checkable
-android.widget.CheckedTextView
-android.widget.CompoundButton
-android.widget.EdgeEffect
-android.widget.EditText
-android.widget.Editor
-android.widget.Editor$1
-android.widget.Editor$2
-android.widget.Editor$CursorAnchorInfoNotifier
-android.widget.Editor$InputContentType
-android.widget.Editor$PositionListener
-android.widget.Editor$ProcessTextIntentActionsHandler
-android.widget.Editor$SpanController
-android.widget.Editor$SuggestionHelper
-android.widget.Editor$SuggestionHelper$SuggestionSpanComparator
-android.widget.Editor$TextViewPositionListener
-android.widget.Editor$UndoInputFilter
-android.widget.Filter$FilterListener
-android.widget.Filterable
-android.widget.FrameLayout
-android.widget.FrameLayout$LayoutParams
-android.widget.HorizontalScrollView
-android.widget.ImageButton
-android.widget.ImageView
-android.widget.ImageView$ScaleType
-android.widget.LinearLayout
-android.widget.LinearLayout$LayoutParams
-android.widget.ListAdapter
-android.widget.ListView
-android.widget.ListView$ArrowScrollFocusResult
-android.widget.MultiAutoCompleteTextView
-android.widget.OverScroller
-android.widget.OverScroller$SplineOverScroller
-android.widget.PopupWindow
-android.widget.ProgressBar
-android.widget.ProgressBar$1
-android.widget.RadioButton
-android.widget.RatingBar
-android.widget.RelativeLayout
-android.widget.RelativeLayout$DependencyGraph
-android.widget.RelativeLayout$DependencyGraph$Node
-android.widget.RelativeLayout$LayoutParams
-android.widget.RemoteViews
-android.widget.RemoteViews$1
-android.widget.RemoteViews$2
-android.widget.RemoteViews$3
-android.widget.RemoteViews$Action
-android.widget.RemoteViews$ActionException
-android.widget.RemoteViews$BitmapCache
-android.widget.RemoteViews$MemoryUsageCounter
-android.widget.RemoteViews$MutablePair
-android.widget.RemoteViews$OnClickHandler
-android.widget.RemoteViews$ReflectionAction
-android.widget.RemoteViews$RemoteView
-android.widget.RemoteViews$RuntimeAction
-android.widget.RemoteViews$SetOnClickPendingIntent
-android.widget.RemoteViewsAdapter$RemoteAdapterConnectionCallback
-android.widget.ScrollBarDrawable
-android.widget.ScrollView
-android.widget.Scroller
-android.widget.Scroller$ViscousFluidInterpolator
-android.widget.SeekBar
-android.widget.Space
-android.widget.Spinner
-android.widget.SpinnerAdapter
-android.widget.TextView
-android.widget.TextView$BufferType
-android.widget.TextView$ChangeWatcher
-android.widget.TextView$CharWrapper
-android.widget.TextView$Drawables
-android.widget.TextView$OnEditorActionListener
-com.android.internal.R$styleable
-com.android.internal.app.IAppOpsCallback
-com.android.internal.app.IAppOpsCallback$Stub
-com.android.internal.app.IAppOpsService
-com.android.internal.app.IAppOpsService$Stub
-com.android.internal.app.IAppOpsService$Stub$Proxy
-com.android.internal.app.IBatteryStats
-com.android.internal.app.IBatteryStats$Stub
-com.android.internal.app.IBatteryStats$Stub$Proxy
-com.android.internal.app.IVoiceInteractionManagerService
-com.android.internal.app.IVoiceInteractionManagerService$Stub
-com.android.internal.app.IVoiceInteractor
-com.android.internal.app.IVoiceInteractor$Stub
-com.android.internal.appwidget.IAppWidgetService
-com.android.internal.appwidget.IAppWidgetService$Stub
-com.android.internal.appwidget.IAppWidgetService$Stub$Proxy
-com.android.internal.content.NativeLibraryHelper
-com.android.internal.content.ReferrerIntent
-com.android.internal.content.ReferrerIntent$1
-com.android.internal.graphics.drawable.AnimationScaleListDrawable
-com.android.internal.graphics.drawable.AnimationScaleListDrawable$AnimationScaleListState
-com.android.internal.inputmethod.InputMethodUtils
-com.android.internal.inputmethod.InputMethodUtils$1
-com.android.internal.inputmethod.LocaleUtils$LocaleExtractor
-com.android.internal.logging.AndroidConfig
-com.android.internal.logging.AndroidHandler
-com.android.internal.logging.AndroidHandler$1
-com.android.internal.logging.MetricsLogger
-com.android.internal.net.NetworkStatsFactory
-com.android.internal.os.AndroidPrintStream
-com.android.internal.os.BinderInternal
-com.android.internal.os.BinderInternal$GcWatcher
-com.android.internal.os.FuseAppLoop
-com.android.internal.os.FuseAppLoop$1
-com.android.internal.os.FuseUnavailableMountException
-com.android.internal.os.HandlerCaller
-com.android.internal.os.HandlerCaller$Callback
-com.android.internal.os.HandlerCaller$MyHandler
-com.android.internal.os.LoggingPrintStream
-com.android.internal.os.LoggingPrintStream$1
-com.android.internal.os.PathClassLoaderFactory
-com.android.internal.os.RoSystemProperties
-com.android.internal.os.RuntimeInit
-com.android.internal.os.RuntimeInit$1
-com.android.internal.os.RuntimeInit$Arguments
-com.android.internal.os.RuntimeInit$KillApplicationHandler
-com.android.internal.os.RuntimeInit$LoggingHandler
-com.android.internal.os.SamplingProfilerIntegration
-com.android.internal.os.SomeArgs
-com.android.internal.os.Zygote
-com.android.internal.os.Zygote$MethodAndArgsCaller
-com.android.internal.os.ZygoteConnection
-com.android.internal.os.ZygoteConnection$Arguments
-com.android.internal.os.ZygoteInit
-com.android.internal.os.ZygoteSecurityException
-com.android.internal.os.ZygoteServer
-com.android.internal.policy.DecorContext
-com.android.internal.policy.DecorView
-com.android.internal.policy.DecorView$ColorViewAttributes
-com.android.internal.policy.DecorView$ColorViewState
-com.android.internal.policy.PhoneFallbackEventHandler
-com.android.internal.policy.PhoneLayoutInflater
-com.android.internal.policy.PhoneWindow
-com.android.internal.policy.PhoneWindow$1
-com.android.internal.policy.PhoneWindow$PanelFeatureState
-com.android.internal.policy.PhoneWindow$PhoneWindowMenuCallback
-com.android.internal.policy.PhoneWindow$RotationWatcher
-com.android.internal.policy.PhoneWindow$RotationWatcher$1
-com.android.internal.telecom.ITelecomService
-com.android.internal.telecom.ITelecomService$Stub
-com.android.internal.telephony.ICarrierConfigLoader
-com.android.internal.telephony.ICarrierConfigLoader$Stub
-com.android.internal.telephony.ICarrierConfigLoader$Stub$Proxy
-com.android.internal.telephony.IOnSubscriptionsChangedListener
-com.android.internal.telephony.IOnSubscriptionsChangedListener$Stub
-com.android.internal.telephony.IPhoneStateListener
-com.android.internal.telephony.IPhoneStateListener$Stub
-com.android.internal.telephony.IPhoneSubInfo
-com.android.internal.telephony.IPhoneSubInfo$Stub
-com.android.internal.telephony.IPhoneSubInfo$Stub$Proxy
-com.android.internal.telephony.ISms
-com.android.internal.telephony.ISms$Stub
-com.android.internal.telephony.ISub
-com.android.internal.telephony.ISub$Stub
-com.android.internal.telephony.ISub$Stub$Proxy
-com.android.internal.telephony.ITelephony
-com.android.internal.telephony.ITelephony$Stub
-com.android.internal.telephony.ITelephony$Stub$Proxy
-com.android.internal.telephony.ITelephonyRegistry
-com.android.internal.telephony.ITelephonyRegistry$Stub
-com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy
-com.android.internal.telephony.IccCardConstants$State
-com.android.internal.telephony.PhoneConstants$State
-com.android.internal.textservice.ITextServicesManager
-com.android.internal.textservice.ITextServicesManager$Stub
-com.android.internal.util.ArrayUtils
-com.android.internal.util.AsyncChannel
-com.android.internal.util.AsyncChannel$DeathMonitor
-com.android.internal.util.BitUtils
-com.android.internal.util.ExponentiallyBucketedHistogram
-com.android.internal.util.FastPrintWriter
-com.android.internal.util.FastPrintWriter$DummyWriter
-com.android.internal.util.FastXmlSerializer
-com.android.internal.util.GrowingArrayUtils
-com.android.internal.util.IState
-com.android.internal.util.IntPair
-com.android.internal.util.LineBreakBufferedWriter
-com.android.internal.util.Preconditions
-com.android.internal.util.State
-com.android.internal.util.StateMachine
-com.android.internal.util.StateMachine$LogRec
-com.android.internal.util.StateMachine$LogRecords
-com.android.internal.util.StateMachine$SmHandler
-com.android.internal.util.StateMachine$SmHandler$HaltingState
-com.android.internal.util.StateMachine$SmHandler$QuittingState
-com.android.internal.util.StateMachine$SmHandler$StateInfo
-com.android.internal.util.VirtualRefBasePtr
-com.android.internal.util.XmlUtils
-com.android.internal.util.XmlUtils$WriteMapCallback
-com.android.internal.view.IInputConnectionWrapper
-com.android.internal.view.IInputConnectionWrapper$MyHandler
-com.android.internal.view.IInputContext
-com.android.internal.view.IInputContext$Stub
-com.android.internal.view.IInputMethodClient
-com.android.internal.view.IInputMethodClient$Stub
-com.android.internal.view.IInputMethodManager
-com.android.internal.view.IInputMethodManager$Stub
-com.android.internal.view.IInputMethodManager$Stub$Proxy
-com.android.internal.view.IInputMethodSession
-com.android.internal.view.IInputMethodSession$Stub
-com.android.internal.view.IInputMethodSession$Stub$Proxy
-com.android.internal.view.InputBindResult
-com.android.internal.view.InputBindResult$1
-com.android.internal.view.RootViewSurfaceTaker
-com.android.internal.view.animation.FallbackLUTInterpolator
-com.android.internal.view.animation.HasNativeInterpolator
-com.android.internal.view.animation.NativeInterpolatorFactory
-com.android.internal.view.animation.NativeInterpolatorFactoryHelper
-com.android.internal.view.menu.MenuBuilder$Callback
-com.android.internal.view.menu.MenuPresenter$Callback
-com.android.internal.widget.BackgroundFallback
-com.android.internal.widget.DecorContentParent
-com.android.internal.widget.LockPatternUtils
-com.android.okhttp.Address
-com.android.okhttp.Authenticator
-com.android.okhttp.CacheControl
-com.android.okhttp.CacheControl$Builder
-com.android.okhttp.CertificatePinner
-com.android.okhttp.CertificatePinner$Builder
-com.android.okhttp.CipherSuite
-com.android.okhttp.ConfigAwareConnectionPool
-com.android.okhttp.ConfigAwareConnectionPool$1
-com.android.okhttp.Connection
-com.android.okhttp.ConnectionPool
-com.android.okhttp.ConnectionPool$1
-com.android.okhttp.ConnectionSpec
-com.android.okhttp.ConnectionSpec$Builder
-com.android.okhttp.Dispatcher
-com.android.okhttp.Dns
-com.android.okhttp.Dns$1
-com.android.okhttp.Handshake
-com.android.okhttp.Headers
-com.android.okhttp.Headers$Builder
-com.android.okhttp.HttpHandler
-com.android.okhttp.HttpHandler$CleartextURLFilter
-com.android.okhttp.HttpUrl
-com.android.okhttp.HttpUrl$Builder
-com.android.okhttp.HttpUrl$Builder$ParseResult
-com.android.okhttp.HttpsHandler
-com.android.okhttp.OkHttpClient
-com.android.okhttp.OkHttpClient$1
-com.android.okhttp.OkUrlFactory
-com.android.okhttp.Protocol
-com.android.okhttp.Request
-com.android.okhttp.Request$Builder
-com.android.okhttp.RequestBody
-com.android.okhttp.RequestBody$2
-com.android.okhttp.Response
-com.android.okhttp.Response$Builder
-com.android.okhttp.ResponseBody
-com.android.okhttp.Route
-com.android.okhttp.TlsVersion
-com.android.okhttp.internal.ConnectionSpecSelector
-com.android.okhttp.internal.Internal
-com.android.okhttp.internal.OptionalMethod
-com.android.okhttp.internal.Platform
-com.android.okhttp.internal.RouteDatabase
-com.android.okhttp.internal.URLFilter
-com.android.okhttp.internal.Util
-com.android.okhttp.internal.Util$1
-com.android.okhttp.internal.http.AuthenticatorAdapter
-com.android.okhttp.internal.http.CacheStrategy
-com.android.okhttp.internal.http.CacheStrategy$Factory
-com.android.okhttp.internal.http.Http1xStream
-com.android.okhttp.internal.http.Http1xStream$AbstractSource
-com.android.okhttp.internal.http.Http1xStream$ChunkedSource
-com.android.okhttp.internal.http.Http1xStream$FixedLengthSource
-com.android.okhttp.internal.http.HttpEngine
-com.android.okhttp.internal.http.HttpEngine$1
-com.android.okhttp.internal.http.HttpMethod
-com.android.okhttp.internal.http.HttpStream
-com.android.okhttp.internal.http.OkHeaders
-com.android.okhttp.internal.http.OkHeaders$1
-com.android.okhttp.internal.http.RealResponseBody
-com.android.okhttp.internal.http.RequestException
-com.android.okhttp.internal.http.RequestLine
-com.android.okhttp.internal.http.RetryableSink
-com.android.okhttp.internal.http.RouteException
-com.android.okhttp.internal.http.RouteSelector
-com.android.okhttp.internal.http.StatusLine
-com.android.okhttp.internal.http.StreamAllocation
-com.android.okhttp.internal.huc.DelegatingHttpsURLConnection
-com.android.okhttp.internal.huc.HttpURLConnectionImpl
-com.android.okhttp.internal.huc.HttpsURLConnectionImpl
-com.android.okhttp.internal.io.RealConnection
-com.android.okhttp.internal.tls.OkHostnameVerifier
-com.android.okhttp.okio.AsyncTimeout
-com.android.okhttp.okio.AsyncTimeout$1
-com.android.okhttp.okio.AsyncTimeout$2
-com.android.okhttp.okio.AsyncTimeout$Watchdog
-com.android.okhttp.okio.Buffer
-com.android.okhttp.okio.BufferedSink
-com.android.okhttp.okio.BufferedSource
-com.android.okhttp.okio.ForwardingTimeout
-com.android.okhttp.okio.GzipSource
-com.android.okhttp.okio.InflaterSource
-com.android.okhttp.okio.Okio
-com.android.okhttp.okio.Okio$1
-com.android.okhttp.okio.Okio$2
-com.android.okhttp.okio.Okio$3
-com.android.okhttp.okio.RealBufferedSink
-com.android.okhttp.okio.RealBufferedSink$1
-com.android.okhttp.okio.RealBufferedSource
-com.android.okhttp.okio.RealBufferedSource$1
-com.android.okhttp.okio.Segment
-com.android.okhttp.okio.SegmentPool
-com.android.okhttp.okio.Sink
-com.android.okhttp.okio.Source
-com.android.okhttp.okio.Timeout
-com.android.okhttp.okio.Timeout$1
-com.android.okhttp.okio.Util
-com.android.org.bouncycastle.asn1.ASN1Encodable
-com.android.org.bouncycastle.asn1.ASN1Object
-com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier
-com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier$OidHandle
-com.android.org.bouncycastle.asn1.ASN1Primitive
-com.android.org.bouncycastle.asn1.OIDTokenizer
-com.android.org.bouncycastle.asn1.bc.BCObjectIdentifiers
-com.android.org.bouncycastle.asn1.iana.IANAObjectIdentifiers
-com.android.org.bouncycastle.asn1.misc.MiscObjectIdentifiers
-com.android.org.bouncycastle.asn1.nist.NISTObjectIdentifiers
-com.android.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers
-com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers
-com.android.org.bouncycastle.asn1.x509.X509ObjectIdentifiers
-com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers
-com.android.org.bouncycastle.jcajce.provider.asymmetric.DH$Mappings
-com.android.org.bouncycastle.jcajce.provider.asymmetric.DSA$Mappings
-com.android.org.bouncycastle.jcajce.provider.asymmetric.EC$Mappings
-com.android.org.bouncycastle.jcajce.provider.asymmetric.RSA$Mappings
-com.android.org.bouncycastle.jcajce.provider.asymmetric.X509$Mappings
-com.android.org.bouncycastle.jcajce.provider.asymmetric.dh.KeyFactorySpi
-com.android.org.bouncycastle.jcajce.provider.asymmetric.dsa.DSAUtil
-com.android.org.bouncycastle.jcajce.provider.asymmetric.dsa.KeyFactorySpi
-com.android.org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi
-com.android.org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi$EC
-com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi
-com.android.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi
-com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider
-com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration
-com.android.org.bouncycastle.jcajce.provider.config.ProviderConfigurationPermission
-com.android.org.bouncycastle.jcajce.provider.digest.DigestAlgorithmProvider
-com.android.org.bouncycastle.jcajce.provider.digest.MD5
-com.android.org.bouncycastle.jcajce.provider.digest.MD5$Mappings
-com.android.org.bouncycastle.jcajce.provider.digest.SHA1
-com.android.org.bouncycastle.jcajce.provider.digest.SHA1$Mappings
-com.android.org.bouncycastle.jcajce.provider.digest.SHA224
-com.android.org.bouncycastle.jcajce.provider.digest.SHA224$Mappings
-com.android.org.bouncycastle.jcajce.provider.digest.SHA256
-com.android.org.bouncycastle.jcajce.provider.digest.SHA256$Mappings
-com.android.org.bouncycastle.jcajce.provider.digest.SHA384
-com.android.org.bouncycastle.jcajce.provider.digest.SHA384$Mappings
-com.android.org.bouncycastle.jcajce.provider.digest.SHA512
-com.android.org.bouncycastle.jcajce.provider.digest.SHA512$Mappings
-com.android.org.bouncycastle.jcajce.provider.keystore.BC$Mappings
-com.android.org.bouncycastle.jcajce.provider.keystore.PKCS12$Mappings
-com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi
-com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi$Std
-com.android.org.bouncycastle.jcajce.provider.symmetric.AES
-com.android.org.bouncycastle.jcajce.provider.symmetric.AES$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.ARC4
-com.android.org.bouncycastle.jcajce.provider.symmetric.ARC4$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.Blowfish
-com.android.org.bouncycastle.jcajce.provider.symmetric.Blowfish$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.DES
-com.android.org.bouncycastle.jcajce.provider.symmetric.DES$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.DESede
-com.android.org.bouncycastle.jcajce.provider.symmetric.DESede$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2
-com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12
-com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters
-com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.RC2
-com.android.org.bouncycastle.jcajce.provider.symmetric.RC2$Mappings
-com.android.org.bouncycastle.jcajce.provider.symmetric.SymmetricAlgorithmProvider
-com.android.org.bouncycastle.jcajce.provider.symmetric.Twofish
-com.android.org.bouncycastle.jcajce.provider.symmetric.Twofish$Mappings
-com.android.org.bouncycastle.jcajce.provider.util.AlgorithmProvider
-com.android.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider
-com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter
-com.android.org.bouncycastle.jcajce.util.BCJcaJceHelper
-com.android.org.bouncycastle.jcajce.util.JcaJceHelper
-com.android.org.bouncycastle.jcajce.util.ProviderJcaJceHelper
-com.android.org.bouncycastle.jce.interfaces.BCKeyStore
-com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
-com.android.org.bouncycastle.jce.provider.BouncyCastleProvider$1
-com.android.org.bouncycastle.jce.provider.BouncyCastleProviderConfiguration
-com.android.org.bouncycastle.util.Arrays
-com.android.org.bouncycastle.util.Encodable
-com.android.org.bouncycastle.util.Strings
-com.android.org.bouncycastle.util.Strings$1
-com.android.org.conscrypt.AbstractOpenSSLSession
-com.android.org.conscrypt.AbstractSessionContext
-com.android.org.conscrypt.AbstractSessionContext$1
-com.android.org.conscrypt.AddressUtils
-com.android.org.conscrypt.ArrayUtils
-com.android.org.conscrypt.ByteArray
-com.android.org.conscrypt.CertBlacklist
-com.android.org.conscrypt.CertificatePriorityComparator
-com.android.org.conscrypt.ChainStrengthAnalyzer
-com.android.org.conscrypt.ClientSessionContext
-com.android.org.conscrypt.ClientSessionContext$HostAndPort
-com.android.org.conscrypt.CryptoUpcalls
-com.android.org.conscrypt.EvpMdRef$MD5
-com.android.org.conscrypt.EvpMdRef$SHA1
-com.android.org.conscrypt.EvpMdRef$SHA256
-com.android.org.conscrypt.FileClientSessionCache
-com.android.org.conscrypt.FileClientSessionCache$Impl
-com.android.org.conscrypt.Hex
-com.android.org.conscrypt.JSSEProvider
-com.android.org.conscrypt.KeyManagerFactoryImpl
-com.android.org.conscrypt.KeyManagerImpl
-com.android.org.conscrypt.NativeCrypto
-com.android.org.conscrypt.NativeCrypto$SSLHandshakeCallbacks
-com.android.org.conscrypt.NativeCryptoJni
-com.android.org.conscrypt.NativeRef
-com.android.org.conscrypt.NativeRef$EC_GROUP
-com.android.org.conscrypt.NativeRef$EC_POINT
-com.android.org.conscrypt.NativeRef$EVP_MD_CTX
-com.android.org.conscrypt.NativeRef$EVP_PKEY
-com.android.org.conscrypt.OpenSSLBIOInputStream
-com.android.org.conscrypt.OpenSSLContextImpl
-com.android.org.conscrypt.OpenSSLContextImpl$TLSv12
-com.android.org.conscrypt.OpenSSLECGroupContext
-com.android.org.conscrypt.OpenSSLECPointContext
-com.android.org.conscrypt.OpenSSLECPublicKey
-com.android.org.conscrypt.OpenSSLExtendedSessionImpl
-com.android.org.conscrypt.OpenSSLKey
-com.android.org.conscrypt.OpenSSLKeyHolder
-com.android.org.conscrypt.OpenSSLMessageDigestJDK
-com.android.org.conscrypt.OpenSSLMessageDigestJDK$MD5
-com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA1
-com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA256
-com.android.org.conscrypt.OpenSSLProvider
-com.android.org.conscrypt.OpenSSLRSAKeyFactory
-com.android.org.conscrypt.OpenSSLRSAPublicKey
-com.android.org.conscrypt.OpenSSLRandom
-com.android.org.conscrypt.OpenSSLSessionImpl
-com.android.org.conscrypt.OpenSSLSignature
-com.android.org.conscrypt.OpenSSLSignature$EngineType
-com.android.org.conscrypt.OpenSSLSignature$RSAPKCS1Padding
-com.android.org.conscrypt.OpenSSLSignature$SHA1RSA
-com.android.org.conscrypt.OpenSSLSocketFactoryImpl
-com.android.org.conscrypt.OpenSSLSocketImpl
-com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream
-com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream
-com.android.org.conscrypt.OpenSSLSocketImplWrapper
-com.android.org.conscrypt.OpenSSLX509CertPath
-com.android.org.conscrypt.OpenSSLX509CertPath$Encoding
-com.android.org.conscrypt.OpenSSLX509Certificate
-com.android.org.conscrypt.OpenSSLX509CertificateFactory
-com.android.org.conscrypt.OpenSSLX509CertificateFactory$1
-com.android.org.conscrypt.OpenSSLX509CertificateFactory$2
-com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser
-com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException
-com.android.org.conscrypt.Platform
-com.android.org.conscrypt.SSLClientSessionCache
-com.android.org.conscrypt.SSLParametersImpl
-com.android.org.conscrypt.SSLParametersImpl$AliasChooser
-com.android.org.conscrypt.SSLParametersImpl$PSKCallbacks
-com.android.org.conscrypt.SSLUtils
-com.android.org.conscrypt.ServerSessionContext
-com.android.org.conscrypt.TrustManagerFactoryImpl
-com.android.org.conscrypt.TrustManagerImpl
-com.android.org.conscrypt.TrustManagerImpl$ExtendedKeyUsagePKIXCertPathChecker
-com.android.org.conscrypt.TrustManagerImpl$TrustAnchorComparator
-com.android.org.conscrypt.TrustedCertificateIndex
-com.android.org.conscrypt.TrustedCertificateKeyStoreSpi
-com.android.org.conscrypt.TrustedCertificateStore
-com.android.org.conscrypt.TrustedCertificateStore$PreloadHolder
-com.android.org.conscrypt.ct.CTLogInfo
-com.android.org.conscrypt.ct.CTLogStore
-com.android.org.conscrypt.ct.CTLogStoreImpl
-com.android.org.conscrypt.ct.CTLogStoreImpl$InvalidLogFileException
-com.android.org.conscrypt.ct.CTPolicy
-com.android.org.conscrypt.ct.CTPolicyImpl
-com.android.org.conscrypt.ct.CTVerifier
-com.android.org.conscrypt.ct.KnownLogs
-com.android.org.conscrypt.ct.SerializationException
-com.android.server.NetworkManagementSocketTagger
-com.android.server.NetworkManagementSocketTagger$1
-com.android.server.NetworkManagementSocketTagger$SocketTags
-com.google.android.collect.Lists
-com.google.android.collect.Maps
-com.google.android.gles_jni.EGLConfigImpl
-com.google.android.gles_jni.EGLContextImpl
-com.google.android.gles_jni.EGLDisplayImpl
-com.google.android.gles_jni.EGLImpl
-com.google.android.gles_jni.EGLSurfaceImpl
-com.google.android.gles_jni.GLImpl
-dalvik.annotation.optimization.CriticalNative
-dalvik.annotation.optimization.FastNative
-dalvik.system.-$Lambda$xxvwQBVHC44UYbpcpA8j0sUqLOo
-dalvik.system.BaseDexClassLoader
-dalvik.system.BaseDexClassLoader$Reporter
-dalvik.system.BlockGuard
-dalvik.system.BlockGuard$1
-dalvik.system.BlockGuard$2
-dalvik.system.BlockGuard$BlockGuardPolicyException
-dalvik.system.BlockGuard$Policy
-dalvik.system.ClassExt
-dalvik.system.CloseGuard
-dalvik.system.CloseGuard$DefaultReporter
-dalvik.system.CloseGuard$DefaultTracker
-dalvik.system.CloseGuard$Reporter
-dalvik.system.CloseGuard$Tracker
-dalvik.system.DalvikLogHandler
-dalvik.system.DalvikLogging
-dalvik.system.DexClassLoader
-dalvik.system.DexFile
-dalvik.system.DexFile$DFEnum
-dalvik.system.DexPathList
-dalvik.system.DexPathList$Element
-dalvik.system.DexPathList$NativeLibraryElement
-dalvik.system.EmulatedStackFrame
-dalvik.system.EmulatedStackFrame$Range
-dalvik.system.PathClassLoader
-dalvik.system.SocketTagger
-dalvik.system.SocketTagger$1
-dalvik.system.VMDebug
-dalvik.system.VMRuntime
-dalvik.system.VMStack
-dalvik.system.ZygoteHooks
-java.io.Bits
-java.io.BufferedInputStream
-java.io.BufferedOutputStream
-java.io.BufferedReader
-java.io.ByteArrayInputStream
-java.io.ByteArrayOutputStream
-java.io.CharArrayWriter
-java.io.Closeable
-java.io.Console
-java.io.DataInput
-java.io.DataInputStream
-java.io.DataOutput
-java.io.DataOutputStream
-java.io.DefaultFileSystem
-java.io.EOFException
-java.io.ExpiringCache
-java.io.ExpiringCache$1
-java.io.ExpiringCache$Entry
-java.io.Externalizable
-java.io.File
-java.io.File$PathStatus
-java.io.File$TempDirectory
-java.io.FileDescriptor
-java.io.FileDescriptor$1
-java.io.FileFilter
-java.io.FileInputStream
-java.io.FileInputStream$UseManualSkipException
-java.io.FileNotFoundException
-java.io.FileOutputStream
-java.io.FileReader
-java.io.FileSystem
-java.io.FilenameFilter
-java.io.FilterInputStream
-java.io.FilterOutputStream
-java.io.Flushable
-java.io.IOException
-java.io.InputStream
-java.io.InputStreamReader
-java.io.InterruptedIOException
-java.io.InvalidObjectException
-java.io.ObjectInput
-java.io.ObjectInputStream
-java.io.ObjectInputStream$BlockDataInputStream
-java.io.ObjectInputStream$HandleTable
-java.io.ObjectInputStream$HandleTable$HandleList
-java.io.ObjectInputStream$PeekInputStream
-java.io.ObjectInputStream$ValidationList
-java.io.ObjectOutput
-java.io.ObjectOutputStream
-java.io.ObjectOutputStream$PutField
-java.io.ObjectStreamClass
-java.io.ObjectStreamConstants
-java.io.ObjectStreamException
-java.io.ObjectStreamField
-java.io.OutputStream
-java.io.OutputStreamWriter
-java.io.PrintStream
-java.io.PrintWriter
-java.io.PushbackInputStream
-java.io.RandomAccessFile
-java.io.Reader
-java.io.Serializable
-java.io.SerializablePermission
-java.io.StringReader
-java.io.StringWriter
-java.io.UnixFileSystem
-java.io.UnsupportedEncodingException
-java.io.Writer
-java.lang.-$Lambda$S9HjrJh0nDg7IyU6wZdPArnZWRQ
-java.lang.-$Lambda$S9HjrJh0nDg7IyU6wZdPArnZWRQ$1
-java.lang.AbstractMethodError
-java.lang.AbstractStringBuilder
-java.lang.AndroidHardcodedSystemProperties
-java.lang.Appendable
-java.lang.ArithmeticException
-java.lang.ArrayIndexOutOfBoundsException
-java.lang.ArrayStoreException
-java.lang.AssertionError
-java.lang.AutoCloseable
-java.lang.Boolean
-java.lang.BootClassLoader
-java.lang.Byte
-java.lang.Byte$ByteCache
-java.lang.CaseMapper
-java.lang.CaseMapper$1
-java.lang.CharSequence
-java.lang.CharSequence$1CharIterator
-java.lang.CharSequence$1CodePointIterator
-java.lang.Character
-java.lang.Character$CharacterCache
-java.lang.Character$Subset
-java.lang.Character$UnicodeBlock
-java.lang.Class
-java.lang.Class$Caches
-java.lang.ClassCastException
-java.lang.ClassLoader
-java.lang.ClassLoader$SystemClassLoader
-java.lang.ClassNotFoundException
-java.lang.CloneNotSupportedException
-java.lang.Cloneable
-java.lang.Comparable
-java.lang.Daemons
-java.lang.Daemons$Daemon
-java.lang.Daemons$FinalizerDaemon
-java.lang.Daemons$FinalizerWatchdogDaemon
-java.lang.Daemons$HeapTaskDaemon
-java.lang.Daemons$ReferenceQueueDaemon
-java.lang.DexCache
-java.lang.Double
-java.lang.Enum
-java.lang.Enum$1
-java.lang.EnumConstantNotPresentException
-java.lang.Error
-java.lang.Exception
-java.lang.Float
-java.lang.IllegalAccessError
-java.lang.IllegalAccessException
-java.lang.IllegalArgumentException
-java.lang.IllegalStateException
-java.lang.IllegalThreadStateException
-java.lang.IncompatibleClassChangeError
-java.lang.IndexOutOfBoundsException
-java.lang.InheritableThreadLocal
-java.lang.InstantiationException
-java.lang.Integer
-java.lang.Integer$IntegerCache
-java.lang.InternalError
-java.lang.InterruptedException
-java.lang.Iterable
-java.lang.JavaLangAccess
-java.lang.LinkageError
-java.lang.Long
-java.lang.Long$LongCache
-java.lang.Math
-java.lang.Math$RandomNumberGeneratorHolder
-java.lang.NegativeArraySizeException
-java.lang.NoClassDefFoundError
-java.lang.NoSuchFieldError
-java.lang.NoSuchFieldException
-java.lang.NoSuchMethodError
-java.lang.NoSuchMethodException
-java.lang.NullPointerException
-java.lang.Number
-java.lang.NumberFormatException
-java.lang.Object
-java.lang.OutOfMemoryError
-java.lang.Package
-java.lang.Process
-java.lang.ProcessBuilder
-java.lang.ProcessEnvironment
-java.lang.Readable
-java.lang.ReflectiveOperationException
-java.lang.Runnable
-java.lang.Runtime
-java.lang.RuntimeException
-java.lang.RuntimePermission
-java.lang.SecurityException
-java.lang.SecurityManager
-java.lang.Short
-java.lang.Short$ShortCache
-java.lang.StackOverflowError
-java.lang.StackTraceElement
-java.lang.StrictMath
-java.lang.String
-java.lang.String$CaseInsensitiveComparator
-java.lang.StringBuffer
-java.lang.StringBuilder
-java.lang.StringFactory
-java.lang.StringIndexOutOfBoundsException
-java.lang.System
-java.lang.System$PropertiesWithNonOverrideableDefaults
-java.lang.Thread
-java.lang.Thread$1
-java.lang.Thread$Caches
-java.lang.Thread$State
-java.lang.Thread$UncaughtExceptionHandler
-java.lang.Thread$WeakClassKey
-java.lang.ThreadDeath
-java.lang.ThreadGroup
-java.lang.ThreadLocal
-java.lang.ThreadLocal$ThreadLocalMap
-java.lang.ThreadLocal$ThreadLocalMap$Entry
-java.lang.Throwable
-java.lang.Throwable$PrintStreamOrWriter
-java.lang.Throwable$SentinelHolder
-java.lang.Throwable$WrappedPrintStream
-java.lang.Throwable$WrappedPrintWriter
-java.lang.TypeNotPresentException
-java.lang.UNIXProcess
-java.lang.UnsatisfiedLinkError
-java.lang.UnsupportedOperationException
-java.lang.VMClassLoader
-java.lang.VerifyError
-java.lang.VirtualMachineError
-java.lang.Void
-java.lang.annotation.Annotation
-java.lang.annotation.AnnotationTypeMismatchException
-java.lang.annotation.IncompleteAnnotationException
-java.lang.annotation.Inherited
-java.lang.annotation.Retention
-java.lang.annotation.Target
-java.lang.invoke.CallSite
-java.lang.invoke.ConstantCallSite
-java.lang.invoke.MethodHandle
-java.lang.invoke.MethodHandleImpl
-java.lang.invoke.MethodHandleImpl$HandleInfo
-java.lang.invoke.MethodHandleInfo
-java.lang.invoke.MethodHandleStatics
-java.lang.invoke.MethodHandles
-java.lang.invoke.MethodHandles$Lookup
-java.lang.invoke.MethodType
-java.lang.invoke.MethodType$ConcurrentWeakInternSet
-java.lang.invoke.MethodType$ConcurrentWeakInternSet$WeakEntry
-java.lang.invoke.MethodTypeForm
-java.lang.invoke.Transformers$BindTo
-java.lang.invoke.Transformers$Collector
-java.lang.invoke.Transformers$Construct
-java.lang.invoke.Transformers$Spreader
-java.lang.invoke.Transformers$Transformer
-java.lang.invoke.Transformers$VarargsCollector
-java.lang.invoke.WrongMethodTypeException
-java.lang.ref.FinalizerReference
-java.lang.ref.FinalizerReference$Sentinel
-java.lang.ref.PhantomReference
-java.lang.ref.Reference
-java.lang.ref.ReferenceQueue
-java.lang.ref.SoftReference
-java.lang.ref.WeakReference
-java.lang.reflect.AccessibleObject
-java.lang.reflect.AnnotatedElement
-java.lang.reflect.Array
-java.lang.reflect.Constructor
-java.lang.reflect.Executable
-java.lang.reflect.Executable$GenericInfo
-java.lang.reflect.Field
-java.lang.reflect.GenericArrayType
-java.lang.reflect.GenericDeclaration
-java.lang.reflect.InvocationHandler
-java.lang.reflect.InvocationTargetException
-java.lang.reflect.MalformedParametersException
-java.lang.reflect.Member
-java.lang.reflect.Method
-java.lang.reflect.Method$1
-java.lang.reflect.Modifier
-java.lang.reflect.Parameter
-java.lang.reflect.ParameterizedType
-java.lang.reflect.Proxy
-java.lang.reflect.Proxy$1
-java.lang.reflect.Proxy$Key1
-java.lang.reflect.Proxy$Key2
-java.lang.reflect.Proxy$KeyFactory
-java.lang.reflect.Proxy$KeyX
-java.lang.reflect.Proxy$ProxyClassFactory
-java.lang.reflect.Type
-java.lang.reflect.TypeVariable
-java.lang.reflect.UndeclaredThrowableException
-java.lang.reflect.WeakCache
-java.lang.reflect.WeakCache$CacheKey
-java.lang.reflect.WeakCache$CacheValue
-java.lang.reflect.WeakCache$Factory
-java.lang.reflect.WeakCache$LookupValue
-java.lang.reflect.WeakCache$Value
-java.lang.reflect.WildcardType
-java.math.BigDecimal
-java.math.BigInt
-java.math.BigInteger
-java.math.NativeBN
-java.math.RoundingMode
-java.net.AbstractPlainSocketImpl
-java.net.AddressCache
-java.net.AddressCache$AddressCacheEntry
-java.net.AddressCache$AddressCacheKey
-java.net.ConnectException
-java.net.CookieHandler
-java.net.HttpURLConnection
-java.net.IDN
-java.net.Inet4Address
-java.net.Inet6Address
-java.net.Inet6Address$Inet6AddressHolder
-java.net.Inet6AddressImpl
-java.net.InetAddress
-java.net.InetAddress$1
-java.net.InetAddress$InetAddressHolder
-java.net.InetAddressImpl
-java.net.InetSocketAddress
-java.net.InetSocketAddress$InetSocketAddressHolder
-java.net.JarURLConnection
-java.net.MalformedURLException
-java.net.NetworkInterface
-java.net.Parts
-java.net.PlainSocketImpl
-java.net.Proxy
-java.net.Proxy$Type
-java.net.ProxySelector
-java.net.ResponseCache
-java.net.ServerSocket
-java.net.Socket
-java.net.Socket$2
-java.net.Socket$3
-java.net.SocketAddress
-java.net.SocketException
-java.net.SocketImpl
-java.net.SocketInputStream
-java.net.SocketOptions
-java.net.SocketOutputStream
-java.net.SocketTimeoutException
-java.net.SocksConsts
-java.net.SocksSocketImpl
-java.net.URI
-java.net.URI$Parser
-java.net.URISyntaxException
-java.net.URL
-java.net.URLConnection
-java.net.URLEncoder
-java.net.URLStreamHandler
-java.net.URLStreamHandlerFactory
-java.net.UnknownHostException
-java.nio.Bits
-java.nio.Buffer
-java.nio.BufferOverflowException
-java.nio.BufferUnderflowException
-java.nio.ByteBuffer
-java.nio.ByteBufferAsCharBuffer
-java.nio.ByteBufferAsDoubleBuffer
-java.nio.ByteBufferAsFloatBuffer
-java.nio.ByteBufferAsIntBuffer
-java.nio.ByteBufferAsLongBuffer
-java.nio.ByteBufferAsShortBuffer
-java.nio.ByteOrder
-java.nio.CharBuffer
-java.nio.DirectByteBuffer
-java.nio.DirectByteBuffer$MemoryRef
-java.nio.DoubleBuffer
-java.nio.FloatBuffer
-java.nio.HeapByteBuffer
-java.nio.HeapCharBuffer
-java.nio.IntBuffer
-java.nio.InvalidMarkException
-java.nio.LongBuffer
-java.nio.MappedByteBuffer
-java.nio.NIOAccess
-java.nio.ReadOnlyBufferException
-java.nio.ShortBuffer
-java.nio.StringCharBuffer
-java.nio.channels.AsynchronousCloseException
-java.nio.channels.ByteChannel
-java.nio.channels.Channel
-java.nio.channels.ClosedByInterruptException
-java.nio.channels.ClosedChannelException
-java.nio.channels.DatagramChannel
-java.nio.channels.FileChannel
-java.nio.channels.FileChannel$MapMode
-java.nio.channels.FileLock
-java.nio.channels.GatheringByteChannel
-java.nio.channels.InterruptibleChannel
-java.nio.channels.MulticastChannel
-java.nio.channels.NetworkChannel
-java.nio.channels.OverlappingFileLockException
-java.nio.channels.ReadableByteChannel
-java.nio.channels.ScatteringByteChannel
-java.nio.channels.SeekableByteChannel
-java.nio.channels.SelectableChannel
-java.nio.channels.ServerSocketChannel
-java.nio.channels.SocketChannel
-java.nio.channels.WritableByteChannel
-java.nio.channels.spi.AbstractInterruptibleChannel
-java.nio.channels.spi.AbstractInterruptibleChannel$1
-java.nio.channels.spi.AbstractSelectableChannel
-java.nio.charset.CharacterCodingException
-java.nio.charset.Charset
-java.nio.charset.CharsetDecoder
-java.nio.charset.CharsetDecoderICU
-java.nio.charset.CharsetEncoder
-java.nio.charset.CharsetEncoderICU
-java.nio.charset.CharsetICU
-java.nio.charset.CoderResult
-java.nio.charset.CoderResult$1
-java.nio.charset.CoderResult$2
-java.nio.charset.CoderResult$Cache
-java.nio.charset.CodingErrorAction
-java.nio.charset.IllegalCharsetNameException
-java.nio.charset.StandardCharsets
-java.nio.charset.UnsupportedCharsetException
-java.nio.file.attribute.FileAttribute
-java.security.AccessControlContext
-java.security.AccessControlException
-java.security.AccessController
-java.security.AlgorithmConstraints
-java.security.AlgorithmParameters
-java.security.AlgorithmParametersSpi
-java.security.BasicPermission
-java.security.CryptoPrimitive
-java.security.GeneralSecurityException
-java.security.Guard
-java.security.InvalidAlgorithmParameterException
-java.security.InvalidKeyException
-java.security.Key
-java.security.KeyException
-java.security.KeyFactory
-java.security.KeyFactorySpi
-java.security.KeyManagementException
-java.security.KeyStore
-java.security.KeyStore$1
-java.security.KeyStoreException
-java.security.KeyStoreSpi
-java.security.MessageDigest
-java.security.MessageDigest$Delegate
-java.security.MessageDigestSpi
-java.security.NoSuchAlgorithmException
-java.security.NoSuchProviderException
-java.security.Permission
-java.security.PermissionCollection
-java.security.Permissions
-java.security.Principal
-java.security.PrivateKey
-java.security.PrivilegedAction
-java.security.PrivilegedActionException
-java.security.PrivilegedExceptionAction
-java.security.ProtectionDomain
-java.security.Provider
-java.security.Provider$EngineDescription
-java.security.Provider$Service
-java.security.Provider$ServiceKey
-java.security.Provider$UString
-java.security.PublicKey
-java.security.SecureRandom
-java.security.SecureRandomSpi
-java.security.Security
-java.security.Signature
-java.security.Signature$Delegate
-java.security.SignatureException
-java.security.SignatureSpi
-java.security.UnrecoverableEntryException
-java.security.UnrecoverableKeyException
-java.security.cert.CRL
-java.security.cert.CRLException
-java.security.cert.CertPath
-java.security.cert.CertPathChecker
-java.security.cert.CertPathHelperImpl
-java.security.cert.CertPathParameters
-java.security.cert.CertPathValidator
-java.security.cert.CertPathValidatorException
-java.security.cert.CertPathValidatorResult
-java.security.cert.CertPathValidatorSpi
-java.security.cert.CertSelector
-java.security.cert.Certificate
-java.security.cert.CertificateEncodingException
-java.security.cert.CertificateException
-java.security.cert.CertificateExpiredException
-java.security.cert.CertificateFactory
-java.security.cert.CertificateFactorySpi
-java.security.cert.CertificateNotYetValidException
-java.security.cert.CertificateParsingException
-java.security.cert.Extension
-java.security.cert.PKIXCertPathChecker
-java.security.cert.PKIXCertPathValidatorResult
-java.security.cert.PKIXParameters
-java.security.cert.PKIXRevocationChecker
-java.security.cert.PolicyNode
-java.security.cert.TrustAnchor
-java.security.cert.X509CertSelector
-java.security.cert.X509Certificate
-java.security.cert.X509Extension
-java.security.interfaces.DSAKey
-java.security.interfaces.DSAPublicKey
-java.security.interfaces.ECKey
-java.security.interfaces.ECPrivateKey
-java.security.interfaces.ECPublicKey
-java.security.interfaces.RSAKey
-java.security.interfaces.RSAPrivateKey
-java.security.interfaces.RSAPublicKey
-java.security.spec.AlgorithmParameterSpec
-java.security.spec.ECField
-java.security.spec.ECFieldFp
-java.security.spec.ECParameterSpec
-java.security.spec.ECPoint
-java.security.spec.ECPublicKeySpec
-java.security.spec.EllipticCurve
-java.security.spec.EncodedKeySpec
-java.security.spec.InvalidKeySpecException
-java.security.spec.InvalidParameterSpecException
-java.security.spec.KeySpec
-java.security.spec.RSAPublicKeySpec
-java.security.spec.X509EncodedKeySpec
-java.text.AttributedCharacterIterator$Attribute
-java.text.CharacterIterator
-java.text.DateFormat
-java.text.DateFormat$Field
-java.text.DateFormatSymbols
-java.text.DecimalFormat
-java.text.DecimalFormatSymbols
-java.text.DontCareFieldPosition
-java.text.DontCareFieldPosition$1
-java.text.FieldPosition
-java.text.Format
-java.text.Format$Field
-java.text.Format$FieldDelegate
-java.text.Normalizer
-java.text.Normalizer$Form
-java.text.NumberFormat
-java.text.ParseException
-java.text.ParsePosition
-java.text.SimpleDateFormat
-java.text.StringCharacterIterator
-java.time.DateTimeException
-java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo
-java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$1
-java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$2
-java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$3
-java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$4
-java.util.-$Lambda$4EqhxufgNKat19m0CB0-toH_lzo$5
-java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw
-java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw$1
-java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw$2
-java.util.-$Lambda$aUGKT4ItCOku5-JSG-x8Aqj2pJw$3
-java.util.AbstractCollection
-java.util.AbstractList
-java.util.AbstractList$Itr
-java.util.AbstractList$ListItr
-java.util.AbstractMap
-java.util.AbstractMap$1
-java.util.AbstractMap$2
-java.util.AbstractMap$SimpleImmutableEntry
-java.util.AbstractQueue
-java.util.AbstractSequentialList
-java.util.AbstractSet
-java.util.ArrayDeque
-java.util.ArrayDeque$DeqIterator
-java.util.ArrayList
-java.util.ArrayList$ArrayListSpliterator
-java.util.ArrayList$Itr
-java.util.ArrayList$ListItr
-java.util.ArrayList$SubList
-java.util.ArrayList$SubList$1
-java.util.ArrayPrefixHelpers$CumulateTask
-java.util.ArrayPrefixHelpers$DoubleCumulateTask
-java.util.ArrayPrefixHelpers$IntCumulateTask
-java.util.ArrayPrefixHelpers$LongCumulateTask
-java.util.Arrays
-java.util.Arrays$ArrayList
-java.util.Arrays$NaturalOrder
-java.util.ArraysParallelSortHelpers$FJByte$Sorter
-java.util.ArraysParallelSortHelpers$FJChar$Sorter
-java.util.ArraysParallelSortHelpers$FJDouble$Sorter
-java.util.ArraysParallelSortHelpers$FJFloat$Sorter
-java.util.ArraysParallelSortHelpers$FJInt$Sorter
-java.util.ArraysParallelSortHelpers$FJLong$Sorter
-java.util.ArraysParallelSortHelpers$FJObject$Sorter
-java.util.ArraysParallelSortHelpers$FJShort$Sorter
-java.util.BitSet
-java.util.Calendar
-java.util.Collection
-java.util.Collections
-java.util.Collections$1
-java.util.Collections$2
-java.util.Collections$3
-java.util.Collections$AsLIFOQueue
-java.util.Collections$CheckedCollection
-java.util.Collections$CheckedList
-java.util.Collections$CheckedMap
-java.util.Collections$CheckedNavigableMap
-java.util.Collections$CheckedNavigableSet
-java.util.Collections$CheckedQueue
-java.util.Collections$CheckedRandomAccessList
-java.util.Collections$CheckedSet
-java.util.Collections$CheckedSortedMap
-java.util.Collections$CheckedSortedSet
-java.util.Collections$CopiesList
-java.util.Collections$EmptyEnumeration
-java.util.Collections$EmptyIterator
-java.util.Collections$EmptyList
-java.util.Collections$EmptyListIterator
-java.util.Collections$EmptyMap
-java.util.Collections$EmptySet
-java.util.Collections$ReverseComparator
-java.util.Collections$ReverseComparator2
-java.util.Collections$SetFromMap
-java.util.Collections$SingletonList
-java.util.Collections$SingletonMap
-java.util.Collections$SingletonSet
-java.util.Collections$SynchronizedCollection
-java.util.Collections$SynchronizedList
-java.util.Collections$SynchronizedMap
-java.util.Collections$SynchronizedNavigableMap
-java.util.Collections$SynchronizedNavigableSet
-java.util.Collections$SynchronizedRandomAccessList
-java.util.Collections$SynchronizedSet
-java.util.Collections$SynchronizedSortedMap
-java.util.Collections$SynchronizedSortedSet
-java.util.Collections$UnmodifiableCollection
-java.util.Collections$UnmodifiableCollection$1
-java.util.Collections$UnmodifiableList
-java.util.Collections$UnmodifiableList$1
-java.util.Collections$UnmodifiableMap
-java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet
-java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$1
-java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry
-java.util.Collections$UnmodifiableNavigableMap
-java.util.Collections$UnmodifiableNavigableMap$EmptyNavigableMap
-java.util.Collections$UnmodifiableNavigableSet
-java.util.Collections$UnmodifiableNavigableSet$EmptyNavigableSet
-java.util.Collections$UnmodifiableRandomAccessList
-java.util.Collections$UnmodifiableSet
-java.util.Collections$UnmodifiableSortedMap
-java.util.Collections$UnmodifiableSortedSet
-java.util.ComparableTimSort
-java.util.Comparator
-java.util.Comparators$NaturalOrderComparator
-java.util.Comparators$NullComparator
-java.util.ConcurrentModificationException
-java.util.Currency
-java.util.Date
-java.util.Deque
-java.util.Dictionary
-java.util.DualPivotQuicksort
-java.util.EnumMap
-java.util.EnumMap$1
-java.util.EnumSet
-java.util.Enumeration
-java.util.EventListener
-java.util.Formattable
-java.util.Formatter
-java.util.Formatter$Conversion
-java.util.Formatter$FixedString
-java.util.Formatter$Flags
-java.util.Formatter$FormatSpecifier
-java.util.Formatter$FormatSpecifierParser
-java.util.Formatter$FormatString
-java.util.FormatterClosedException
-java.util.GregorianCalendar
-java.util.HashMap
-java.util.HashMap$EntryIterator
-java.util.HashMap$EntrySet
-java.util.HashMap$HashIterator
-java.util.HashMap$KeyIterator
-java.util.HashMap$KeySet
-java.util.HashMap$Node
-java.util.HashMap$TreeNode
-java.util.HashMap$ValueIterator
-java.util.HashMap$Values
-java.util.HashSet
-java.util.Hashtable
-java.util.Hashtable$Enumerator
-java.util.Hashtable$HashtableEntry
-java.util.IdentityHashMap
-java.util.IdentityHashMap$KeySet
-java.util.IllegalFormatException
-java.util.IllformedLocaleException
-java.util.Iterator
-java.util.LinkedHashMap
-java.util.LinkedHashMap$LinkedEntryIterator
-java.util.LinkedHashMap$LinkedEntrySet
-java.util.LinkedHashMap$LinkedHashIterator
-java.util.LinkedHashMap$LinkedHashMapEntry
-java.util.LinkedHashMap$LinkedKeyIterator
-java.util.LinkedHashMap$LinkedKeySet
-java.util.LinkedHashMap$LinkedValueIterator
-java.util.LinkedHashMap$LinkedValues
-java.util.LinkedHashSet
-java.util.LinkedList
-java.util.LinkedList$ListItr
-java.util.LinkedList$Node
-java.util.List
-java.util.ListIterator
-java.util.Locale
-java.util.Locale$Builder
-java.util.Locale$Cache
-java.util.Locale$Category
-java.util.Locale$FilteringMode
-java.util.Locale$LanguageRange
-java.util.Locale$LocaleKey
-java.util.Locale$NoImagePreloadHolder
-java.util.Map
-java.util.Map$Entry
-java.util.MissingResourceException
-java.util.NavigableMap
-java.util.NavigableSet
-java.util.NoSuchElementException
-java.util.Objects
-java.util.PrimitiveIterator
-java.util.PrimitiveIterator$OfInt
-java.util.PriorityQueue
-java.util.PriorityQueue$Itr
-java.util.Properties
-java.util.Properties$LineReader
-java.util.Queue
-java.util.Random
-java.util.RandomAccess
-java.util.RandomAccessSubList
-java.util.RegularEnumSet
-java.util.ResourceBundle
-java.util.ResourceBundle$1
-java.util.Set
-java.util.SimpleTimeZone
-java.util.SortedMap
-java.util.SortedSet
-java.util.Spliterator
-java.util.Spliterator$OfDouble
-java.util.Spliterator$OfInt
-java.util.Spliterator$OfLong
-java.util.Spliterator$OfPrimitive
-java.util.Spliterators
-java.util.Spliterators$EmptySpliterator
-java.util.Spliterators$EmptySpliterator$OfDouble
-java.util.Spliterators$EmptySpliterator$OfInt
-java.util.Spliterators$EmptySpliterator$OfLong
-java.util.Spliterators$EmptySpliterator$OfRef
-java.util.Stack
-java.util.StringJoiner
-java.util.StringTokenizer
-java.util.SubList
-java.util.TimSort
-java.util.TimeZone
-java.util.TreeMap
-java.util.TreeMap$AscendingSubMap
-java.util.TreeMap$AscendingSubMap$AscendingEntrySetView
-java.util.TreeMap$EntryIterator
-java.util.TreeMap$EntrySet
-java.util.TreeMap$KeyIterator
-java.util.TreeMap$KeySet
-java.util.TreeMap$NavigableSubMap
-java.util.TreeMap$NavigableSubMap$EntrySetView
-java.util.TreeMap$NavigableSubMap$SubMapIterator
-java.util.TreeMap$PrivateEntryIterator
-java.util.TreeMap$TreeMapEntry
-java.util.TreeMap$ValueIterator
-java.util.TreeMap$Values
-java.util.TreeSet
-java.util.UUID
-java.util.UUID$Holder
-java.util.Vector
-java.util.Vector$1
-java.util.Vector$Itr
-java.util.WeakHashMap
-java.util.WeakHashMap$Entry
-java.util.WeakHashMap$EntrySet
-java.util.WeakHashMap$HashIterator
-java.util.WeakHashMap$KeyIterator
-java.util.WeakHashMap$KeySet
-java.util.WeakHashMap$Values
-java.util.concurrent.-$Lambda$xR9BLpu6SifNikvFgr4lEiECBsk
-java.util.concurrent.AbstractExecutorService
-java.util.concurrent.ArrayBlockingQueue
-java.util.concurrent.BlockingQueue
-java.util.concurrent.Callable
-java.util.concurrent.CancellationException
-java.util.concurrent.ConcurrentHashMap
-java.util.concurrent.ConcurrentHashMap$BaseIterator
-java.util.concurrent.ConcurrentHashMap$BulkTask
-java.util.concurrent.ConcurrentHashMap$CollectionView
-java.util.concurrent.ConcurrentHashMap$CounterCell
-java.util.concurrent.ConcurrentHashMap$EntryIterator
-java.util.concurrent.ConcurrentHashMap$EntrySetView
-java.util.concurrent.ConcurrentHashMap$ForEachEntryTask
-java.util.concurrent.ConcurrentHashMap$ForEachKeyTask
-java.util.concurrent.ConcurrentHashMap$ForEachMappingTask
-java.util.concurrent.ConcurrentHashMap$ForEachTransformedEntryTask
-java.util.concurrent.ConcurrentHashMap$ForEachTransformedKeyTask
-java.util.concurrent.ConcurrentHashMap$ForEachTransformedMappingTask
-java.util.concurrent.ConcurrentHashMap$ForEachTransformedValueTask
-java.util.concurrent.ConcurrentHashMap$ForEachValueTask
-java.util.concurrent.ConcurrentHashMap$ForwardingNode
-java.util.concurrent.ConcurrentHashMap$KeyIterator
-java.util.concurrent.ConcurrentHashMap$KeySetView
-java.util.concurrent.ConcurrentHashMap$MapReduceEntriesTask
-java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToDoubleTask
-java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToIntTask
-java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToLongTask
-java.util.concurrent.ConcurrentHashMap$MapReduceKeysTask
-java.util.concurrent.ConcurrentHashMap$MapReduceKeysToDoubleTask
-java.util.concurrent.ConcurrentHashMap$MapReduceKeysToIntTask
-java.util.concurrent.ConcurrentHashMap$MapReduceKeysToLongTask
-java.util.concurrent.ConcurrentHashMap$MapReduceMappingsTask
-java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToDoubleTask
-java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToIntTask
-java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToLongTask
-java.util.concurrent.ConcurrentHashMap$MapReduceValuesTask
-java.util.concurrent.ConcurrentHashMap$MapReduceValuesToDoubleTask
-java.util.concurrent.ConcurrentHashMap$MapReduceValuesToIntTask
-java.util.concurrent.ConcurrentHashMap$MapReduceValuesToLongTask
-java.util.concurrent.ConcurrentHashMap$Node
-java.util.concurrent.ConcurrentHashMap$ReduceEntriesTask
-java.util.concurrent.ConcurrentHashMap$ReduceKeysTask
-java.util.concurrent.ConcurrentHashMap$ReduceValuesTask
-java.util.concurrent.ConcurrentHashMap$ReservationNode
-java.util.concurrent.ConcurrentHashMap$SearchEntriesTask
-java.util.concurrent.ConcurrentHashMap$SearchKeysTask
-java.util.concurrent.ConcurrentHashMap$SearchMappingsTask
-java.util.concurrent.ConcurrentHashMap$SearchValuesTask
-java.util.concurrent.ConcurrentHashMap$Segment
-java.util.concurrent.ConcurrentHashMap$Traverser
-java.util.concurrent.ConcurrentHashMap$TreeBin
-java.util.concurrent.ConcurrentHashMap$TreeNode
-java.util.concurrent.ConcurrentHashMap$ValueIterator
-java.util.concurrent.ConcurrentHashMap$ValuesView
-java.util.concurrent.ConcurrentLinkedDeque
-java.util.concurrent.ConcurrentLinkedDeque$Node
-java.util.concurrent.ConcurrentLinkedQueue
-java.util.concurrent.ConcurrentLinkedQueue$Node
-java.util.concurrent.ConcurrentMap
-java.util.concurrent.CopyOnWriteArrayList
-java.util.concurrent.CopyOnWriteArrayList$COWIterator
-java.util.concurrent.CopyOnWriteArraySet
-java.util.concurrent.CountDownLatch
-java.util.concurrent.CountDownLatch$Sync
-java.util.concurrent.CountedCompleter
-java.util.concurrent.Delayed
-java.util.concurrent.ExecutionException
-java.util.concurrent.Executor
-java.util.concurrent.ExecutorService
-java.util.concurrent.Executors
-java.util.concurrent.Executors$DefaultThreadFactory
-java.util.concurrent.Executors$DelegatedExecutorService
-java.util.concurrent.Executors$DelegatedScheduledExecutorService
-java.util.concurrent.Executors$FinalizableDelegatedExecutorService
-java.util.concurrent.Executors$RunnableAdapter
-java.util.concurrent.ForkJoinPool
-java.util.concurrent.ForkJoinTask
-java.util.concurrent.ForkJoinTask$ExceptionNode
-java.util.concurrent.Future
-java.util.concurrent.FutureTask
-java.util.concurrent.FutureTask$WaitNode
-java.util.concurrent.LinkedBlockingQueue
-java.util.concurrent.LinkedBlockingQueue$Node
-java.util.concurrent.PriorityBlockingQueue
-java.util.concurrent.RejectedExecutionException
-java.util.concurrent.RejectedExecutionHandler
-java.util.concurrent.RunnableFuture
-java.util.concurrent.RunnableScheduledFuture
-java.util.concurrent.ScheduledExecutorService
-java.util.concurrent.ScheduledFuture
-java.util.concurrent.ScheduledThreadPoolExecutor
-java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue
-java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask
-java.util.concurrent.Semaphore
-java.util.concurrent.Semaphore$NonfairSync
-java.util.concurrent.Semaphore$Sync
-java.util.concurrent.SynchronousQueue
-java.util.concurrent.SynchronousQueue$TransferStack
-java.util.concurrent.SynchronousQueue$TransferStack$SNode
-java.util.concurrent.SynchronousQueue$Transferer
-java.util.concurrent.ThreadFactory
-java.util.concurrent.ThreadLocalRandom
-java.util.concurrent.ThreadPoolExecutor
-java.util.concurrent.ThreadPoolExecutor$AbortPolicy
-java.util.concurrent.ThreadPoolExecutor$DiscardPolicy
-java.util.concurrent.ThreadPoolExecutor$Worker
-java.util.concurrent.TimeUnit
-java.util.concurrent.TimeUnit$1
-java.util.concurrent.TimeUnit$2
-java.util.concurrent.TimeUnit$3
-java.util.concurrent.TimeUnit$4
-java.util.concurrent.TimeUnit$5
-java.util.concurrent.TimeUnit$6
-java.util.concurrent.TimeUnit$7
-java.util.concurrent.TimeoutException
-java.util.concurrent.atomic.AtomicBoolean
-java.util.concurrent.atomic.AtomicInteger
-java.util.concurrent.atomic.AtomicLong
-java.util.concurrent.atomic.AtomicReference
-java.util.concurrent.atomic.AtomicReferenceArray
-java.util.concurrent.atomic.AtomicReferenceFieldUpdater
-java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl
-java.util.concurrent.locks.AbstractOwnableSynchronizer
-java.util.concurrent.locks.AbstractQueuedSynchronizer
-java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject
-java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
-java.util.concurrent.locks.Condition
-java.util.concurrent.locks.Lock
-java.util.concurrent.locks.LockSupport
-java.util.concurrent.locks.ReadWriteLock
-java.util.concurrent.locks.ReentrantLock
-java.util.concurrent.locks.ReentrantLock$NonfairSync
-java.util.concurrent.locks.ReentrantLock$Sync
-java.util.concurrent.locks.ReentrantReadWriteLock
-java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync
-java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock
-java.util.concurrent.locks.ReentrantReadWriteLock$Sync
-java.util.concurrent.locks.ReentrantReadWriteLock$Sync$ThreadLocalHoldCounter
-java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock
-java.util.function.-$Lambda$1MZdIZ-DL_fjy9l0o8IMJk57T2g
-java.util.function.-$Lambda$VGDeaUHZQIZywZW2ttlyhwk3Cmk
-java.util.function.-$Lambda$VGDeaUHZQIZywZW2ttlyhwk3Cmk$1
-java.util.function.BiConsumer
-java.util.function.BiFunction
-java.util.function.BinaryOperator
-java.util.function.Consumer
-java.util.function.DoubleBinaryOperator
-java.util.function.DoubleUnaryOperator
-java.util.function.Function
-java.util.function.IntBinaryOperator
-java.util.function.IntConsumer
-java.util.function.IntFunction
-java.util.function.IntToDoubleFunction
-java.util.function.IntToLongFunction
-java.util.function.IntUnaryOperator
-java.util.function.LongBinaryOperator
-java.util.function.LongUnaryOperator
-java.util.function.Predicate
-java.util.function.Supplier
-java.util.function.ToDoubleBiFunction
-java.util.function.ToDoubleFunction
-java.util.function.ToIntBiFunction
-java.util.function.ToIntFunction
-java.util.function.ToLongBiFunction
-java.util.function.ToLongFunction
-java.util.function.UnaryOperator
-java.util.jar.JarEntry
-java.util.jar.JarFile
-java.util.jar.JarFile$JarEntryIterator
-java.util.jar.JarFile$JarFileEntry
-java.util.logging.ErrorManager
-java.util.logging.Formatter
-java.util.logging.Handler
-java.util.logging.Level
-java.util.logging.Level$KnownLevel
-java.util.logging.LogManager
-java.util.logging.LogManager$1
-java.util.logging.LogManager$2
-java.util.logging.LogManager$3
-java.util.logging.LogManager$5
-java.util.logging.LogManager$Cleaner
-java.util.logging.LogManager$LogNode
-java.util.logging.LogManager$LoggerContext
-java.util.logging.LogManager$LoggerContext$1
-java.util.logging.LogManager$LoggerWeakRef
-java.util.logging.LogManager$RootLogger
-java.util.logging.LogManager$SystemLoggerContext
-java.util.logging.LogRecord
-java.util.logging.Logger
-java.util.logging.Logger$LoggerBundle
-java.util.logging.LoggingPermission
-java.util.logging.LoggingProxyImpl
-java.util.prefs.AbstractPreferences
-java.util.prefs.FileSystemPreferences
-java.util.prefs.Preferences
-java.util.regex.MatchResult
-java.util.regex.Matcher
-java.util.regex.Pattern
-java.util.regex.PatternSyntaxException
-java.util.stream.AbstractPipeline
-java.util.stream.BaseStream
-java.util.stream.DoubleStream
-java.util.stream.IntStream
-java.util.stream.LongStream
-java.util.stream.PipelineHelper
-java.util.stream.ReferencePipeline
-java.util.stream.ReferencePipeline$Head
-java.util.stream.Sink
-java.util.stream.Sink$ChainedReference
-java.util.stream.Stream
-java.util.stream.StreamOpFlag
-java.util.stream.StreamOpFlag$MaskBuilder
-java.util.stream.StreamOpFlag$Type
-java.util.stream.StreamShape
-java.util.stream.StreamSupport
-java.util.stream.TerminalOp
-java.util.stream.TerminalSink
-java.util.zip.Adler32
-java.util.zip.CRC32
-java.util.zip.CheckedInputStream
-java.util.zip.Checksum
-java.util.zip.DataFormatException
-java.util.zip.Deflater
-java.util.zip.DeflaterOutputStream
-java.util.zip.GZIPInputStream
-java.util.zip.GZIPOutputStream
-java.util.zip.Inflater
-java.util.zip.InflaterInputStream
-java.util.zip.ZStreamRef
-java.util.zip.ZipCoder
-java.util.zip.ZipConstants
-java.util.zip.ZipEntry
-java.util.zip.ZipFile
-java.util.zip.ZipFile$ZipEntryIterator
-java.util.zip.ZipFile$ZipFileInflaterInputStream
-java.util.zip.ZipFile$ZipFileInputStream
-java.util.zip.ZipUtils
-javax.crypto.BadPaddingException
-javax.crypto.Cipher
-javax.crypto.Cipher$CipherSpiAndProvider
-javax.crypto.Cipher$InitParams
-javax.crypto.Cipher$InitType
-javax.crypto.Cipher$NeedToSet
-javax.crypto.Cipher$SpiAndProviderUpdater
-javax.crypto.Cipher$Transform
-javax.crypto.CipherSpi
-javax.crypto.IllegalBlockSizeException
-javax.crypto.JceSecurity
-javax.crypto.NoSuchPaddingException
-javax.crypto.SecretKey
-javax.crypto.ShortBufferException
-javax.crypto.spec.IvParameterSpec
-javax.crypto.spec.SecretKeySpec
-javax.microedition.khronos.egl.EGL
-javax.microedition.khronos.egl.EGL10
-javax.microedition.khronos.egl.EGLConfig
-javax.microedition.khronos.egl.EGLContext
-javax.microedition.khronos.egl.EGLDisplay
-javax.microedition.khronos.egl.EGLSurface
-javax.microedition.khronos.opengles.GL
-javax.microedition.khronos.opengles.GL10
-javax.microedition.khronos.opengles.GL10Ext
-javax.microedition.khronos.opengles.GL11
-javax.microedition.khronos.opengles.GL11Ext
-javax.microedition.khronos.opengles.GL11ExtensionPack
-javax.net.DefaultSocketFactory
-javax.net.ServerSocketFactory
-javax.net.SocketFactory
-javax.net.ssl.ExtendedSSLSession
-javax.net.ssl.HandshakeCompletedListener
-javax.net.ssl.HostnameVerifier
-javax.net.ssl.HttpsURLConnection
-javax.net.ssl.KeyManager
-javax.net.ssl.KeyManagerFactory
-javax.net.ssl.KeyManagerFactory$1
-javax.net.ssl.KeyManagerFactorySpi
-javax.net.ssl.SNIHostName
-javax.net.ssl.SNIServerName
-javax.net.ssl.SSLContext
-javax.net.ssl.SSLContextSpi
-javax.net.ssl.SSLEngine
-javax.net.ssl.SSLException
-javax.net.ssl.SSLParameters
-javax.net.ssl.SSLPeerUnverifiedException
-javax.net.ssl.SSLProtocolException
-javax.net.ssl.SSLServerSocketFactory
-javax.net.ssl.SSLSession
-javax.net.ssl.SSLSessionContext
-javax.net.ssl.SSLSocket
-javax.net.ssl.SSLSocketFactory
-javax.net.ssl.SSLSocketFactory$1
-javax.net.ssl.TrustManager
-javax.net.ssl.TrustManagerFactory
-javax.net.ssl.TrustManagerFactory$1
-javax.net.ssl.TrustManagerFactorySpi
-javax.net.ssl.X509ExtendedKeyManager
-javax.net.ssl.X509ExtendedTrustManager
-javax.net.ssl.X509KeyManager
-javax.net.ssl.X509TrustManager
-javax.security.auth.Destroyable
-javax.security.auth.callback.UnsupportedCallbackException
-javax.security.auth.x500.X500Principal
-javax.security.cert.Certificate
-javax.security.cert.CertificateException
-javax.security.cert.X509Certificate
-libcore.icu.ICU
-libcore.icu.LocaleData
-libcore.icu.NativeConverter
-libcore.icu.TimeZoneNames
-libcore.internal.StringPool
-libcore.io.AsynchronousCloseMonitor
-libcore.io.BlockGuardOs
-libcore.io.BufferIterator
-libcore.io.ClassPathURLStreamHandler
-libcore.io.ClassPathURLStreamHandler$ClassPathURLConnection
-libcore.io.ClassPathURLStreamHandler$ClassPathURLConnection$1
-libcore.io.DropBox
-libcore.io.DropBox$DefaultReporter
-libcore.io.DropBox$Reporter
-libcore.io.EventLogger
-libcore.io.EventLogger$DefaultReporter
-libcore.io.EventLogger$Reporter
-libcore.io.ForwardingOs
-libcore.io.IoBridge
-libcore.io.IoTracker
-libcore.io.IoTracker$Mode
-libcore.io.IoUtils
-libcore.io.Libcore
-libcore.io.Linux
-libcore.io.Memory
-libcore.io.MemoryMappedFile
-libcore.io.NioBufferIterator
-libcore.io.Os
-libcore.net.NetworkSecurityPolicy
-libcore.net.NetworkSecurityPolicy$DefaultNetworkSecurityPolicy
-libcore.net.UriCodec
-libcore.net.event.NetworkEventDispatcher
-libcore.net.event.NetworkEventListener
-libcore.reflect.AnnotatedElements
-libcore.reflect.AnnotationFactory
-libcore.reflect.AnnotationMember
-libcore.reflect.AnnotationMember$DefaultValues
-libcore.reflect.GenericArrayTypeImpl
-libcore.reflect.GenericSignatureParser
-libcore.reflect.ListOfTypes
-libcore.reflect.ListOfVariables
-libcore.reflect.ParameterizedTypeImpl
-libcore.reflect.Types
-libcore.util.BasicLruCache
-libcore.util.CharsetUtils
-libcore.util.CollectionUtils
-libcore.util.EmptyArray
-libcore.util.NativeAllocationRegistry
-libcore.util.NativeAllocationRegistry$CleanerRunner
-libcore.util.NativeAllocationRegistry$CleanerThunk
-libcore.util.TimeZoneDataFiles
-libcore.util.ZoneInfo
-libcore.util.ZoneInfo$CheckedArithmeticException
-libcore.util.ZoneInfo$OffsetInterval
-libcore.util.ZoneInfo$WallTime
-libcore.util.ZoneInfoDB
-libcore.util.ZoneInfoDB$TzData
-libcore.util.ZoneInfoDB$TzData$1
-org.apache.commons.logging.Log
-org.apache.commons.logging.LogFactory
-org.apache.commons.logging.impl.Jdk14Logger
-org.apache.commons.logging.impl.WeakHashtable
-org.apache.harmony.dalvik.NativeTestTarget
-org.apache.harmony.dalvik.ddmc.Chunk
-org.apache.harmony.dalvik.ddmc.ChunkHandler
-org.apache.harmony.dalvik.ddmc.DdmServer
-org.apache.harmony.dalvik.ddmc.DdmVmInternal
-org.apache.harmony.luni.internal.util.TimezoneGetter
-org.apache.harmony.xml.ExpatAttributes
-org.apache.harmony.xml.ExpatParser
-org.apache.http.Header
-org.apache.http.HttpEntity
-org.apache.http.HttpException
-org.apache.http.HttpHost
-org.apache.http.HttpMessage
-org.apache.http.HttpRequest
-org.apache.http.HttpRequestInterceptor
-org.apache.http.HttpResponse
-org.apache.http.ProtocolException
-org.apache.http.ProtocolVersion
-org.apache.http.StatusLine
-org.apache.http.client.HttpClient
-org.apache.http.client.ResponseHandler
-org.apache.http.client.methods.HttpUriRequest
-org.apache.http.client.params.HttpClientParams
-org.apache.http.conn.ClientConnectionManager
-org.apache.http.conn.ClientConnectionOperator
-org.apache.http.conn.ClientConnectionRequest
-org.apache.http.conn.ConnectTimeoutException
-org.apache.http.conn.ConnectionReleaseTrigger
-org.apache.http.conn.params.ConnManagerPNames
-org.apache.http.conn.params.ConnManagerParams
-org.apache.http.conn.params.ConnManagerParams$1
-org.apache.http.conn.params.ConnPerRoute
-org.apache.http.conn.scheme.LayeredSocketFactory
-org.apache.http.conn.scheme.PlainSocketFactory
-org.apache.http.conn.scheme.Scheme
-org.apache.http.conn.scheme.SchemeRegistry
-org.apache.http.conn.scheme.SocketFactory
-org.apache.http.conn.ssl.AbstractVerifier
-org.apache.http.conn.ssl.AllowAllHostnameVerifier
-org.apache.http.conn.ssl.BrowserCompatHostnameVerifier
-org.apache.http.conn.ssl.SSLSocketFactory
-org.apache.http.conn.ssl.StrictHostnameVerifier
-org.apache.http.conn.ssl.X509HostnameVerifier
-org.apache.http.entity.AbstractHttpEntity
-org.apache.http.impl.client.AbstractHttpClient
-org.apache.http.impl.client.DefaultHttpClient
-org.apache.http.impl.conn.DefaultClientConnectionOperator
-org.apache.http.impl.conn.IdleConnectionHandler
-org.apache.http.impl.conn.tsccm.AbstractConnPool
-org.apache.http.impl.conn.tsccm.ConnPoolByRoute
-org.apache.http.impl.conn.tsccm.RefQueueHandler
-org.apache.http.impl.conn.tsccm.RefQueueWorker
-org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager
-org.apache.http.message.AbstractHttpMessage
-org.apache.http.message.BasicHeader
-org.apache.http.message.BasicHttpResponse
-org.apache.http.message.BasicStatusLine
-org.apache.http.message.HeaderGroup
-org.apache.http.params.AbstractHttpParams
-org.apache.http.params.BasicHttpParams
-org.apache.http.params.CoreConnectionPNames
-org.apache.http.params.CoreProtocolPNames
-org.apache.http.params.HttpConnectionParams
-org.apache.http.params.HttpParams
-org.apache.http.params.HttpProtocolParams
-org.apache.http.protocol.HttpContext
-org.ccil.cowan.tagsoup.AttributesImpl
-org.ccil.cowan.tagsoup.AutoDetector
-org.ccil.cowan.tagsoup.Element
-org.ccil.cowan.tagsoup.ElementType
-org.ccil.cowan.tagsoup.HTMLModels
-org.ccil.cowan.tagsoup.HTMLScanner
-org.ccil.cowan.tagsoup.HTMLSchema
-org.ccil.cowan.tagsoup.Parser
-org.ccil.cowan.tagsoup.Parser$1
-org.ccil.cowan.tagsoup.ScanHandler
-org.ccil.cowan.tagsoup.Scanner
-org.ccil.cowan.tagsoup.Schema
-org.json.JSON
-org.json.JSONArray
-org.json.JSONException
-org.json.JSONObject
-org.json.JSONObject$1
-org.json.JSONStringer
-org.json.JSONStringer$Scope
-org.json.JSONTokener
-org.kxml2.io.KXmlParser
-org.kxml2.io.KXmlParser$ValueContext
-org.xml.sax.Attributes
-org.xml.sax.ContentHandler
-org.xml.sax.DTDHandler
-org.xml.sax.EntityResolver
-org.xml.sax.ErrorHandler
-org.xml.sax.InputSource
-org.xml.sax.Locator
-org.xml.sax.SAXException
-org.xml.sax.SAXNotRecognizedException
-org.xml.sax.SAXNotSupportedException
-org.xml.sax.XMLReader
-org.xml.sax.helpers.DefaultHandler
-org.xmlpull.v1.XmlPullParser
-org.xmlpull.v1.XmlPullParserException
-org.xmlpull.v1.XmlSerializer
-sun.invoke.util.BytecodeDescriptor
-sun.invoke.util.VerifyAccess
-sun.invoke.util.Wrapper
-sun.invoke.util.Wrapper$Format
-sun.misc.Cleaner
-sun.misc.CompoundEnumeration
-sun.misc.FDBigInteger
-sun.misc.FloatingDecimal
-sun.misc.FloatingDecimal$1
-sun.misc.FloatingDecimal$ASCIIToBinaryBuffer
-sun.misc.FloatingDecimal$ASCIIToBinaryConverter
-sun.misc.FloatingDecimal$BinaryToASCIIBuffer
-sun.misc.FloatingDecimal$BinaryToASCIIConverter
-sun.misc.FloatingDecimal$ExceptionalBinaryToASCIIBuffer
-sun.misc.FloatingDecimal$PreparedASCIIToBinaryBuffer
-sun.misc.FormattedFloatingDecimal
-sun.misc.FormattedFloatingDecimal$1
-sun.misc.FormattedFloatingDecimal$Form
-sun.misc.IOUtils
-sun.misc.JavaIOFileDescriptorAccess
-sun.misc.REException
-sun.misc.SharedSecrets
-sun.misc.Unsafe
-sun.misc.VM
-sun.misc.Version
-sun.net.ConnectionResetException
-sun.net.NetHooks
-sun.net.NetProperties
-sun.net.NetProperties$1
-sun.net.spi.DefaultProxySelector
-sun.net.spi.DefaultProxySelector$1
-sun.net.spi.DefaultProxySelector$NonProxyInfo
-sun.net.spi.nameservice.NameService
-sun.net.util.IPAddressUtil
-sun.net.www.ParseUtil
-sun.net.www.protocol.file.Handler
-sun.net.www.protocol.jar.Handler
-sun.nio.ch.DatagramChannelImpl
-sun.nio.ch.DatagramDispatcher
-sun.nio.ch.DirectBuffer
-sun.nio.ch.FileChannelImpl
-sun.nio.ch.FileChannelImpl$Unmapper
-sun.nio.ch.FileDispatcher
-sun.nio.ch.FileDispatcherImpl
-sun.nio.ch.FileKey
-sun.nio.ch.FileLockImpl
-sun.nio.ch.FileLockTable
-sun.nio.ch.IOStatus
-sun.nio.ch.IOUtil
-sun.nio.ch.Interruptible
-sun.nio.ch.NativeDispatcher
-sun.nio.ch.NativeThread
-sun.nio.ch.NativeThreadSet
-sun.nio.ch.Net
-sun.nio.ch.SelChImpl
-sun.nio.ch.ServerSocketChannelImpl
-sun.nio.ch.SharedFileLockTable
-sun.nio.ch.SharedFileLockTable$FileLockReference
-sun.nio.ch.SocketChannelImpl
-sun.nio.ch.Util
-sun.nio.ch.Util$1
-sun.nio.ch.Util$BufferCache
-sun.nio.cs.ArrayDecoder
-sun.nio.cs.ArrayEncoder
-sun.nio.cs.StreamDecoder
-sun.nio.cs.StreamEncoder
-sun.security.action.GetBooleanAction
-sun.security.action.GetPropertyAction
-sun.security.jca.GetInstance
-sun.security.jca.GetInstance$Instance
-sun.security.jca.ProviderConfig
-sun.security.jca.ProviderConfig$2
-sun.security.jca.ProviderList
-sun.security.jca.ProviderList$1
-sun.security.jca.ProviderList$2
-sun.security.jca.ProviderList$3
-sun.security.jca.ProviderList$ServiceList
-sun.security.jca.ProviderList$ServiceList$1
-sun.security.jca.Providers
-sun.security.jca.ServiceId
-sun.security.pkcs.PKCS9Attribute
-sun.security.pkcs.SignerInfo
-sun.security.provider.CertPathProvider
-sun.security.provider.X509Factory
-sun.security.provider.certpath.AdaptableX509CertSelector
-sun.security.provider.certpath.AlgorithmChecker
-sun.security.provider.certpath.BasicChecker
-sun.security.provider.certpath.CertPathHelper
-sun.security.provider.certpath.ConstraintsChecker
-sun.security.provider.certpath.KeyChecker
-sun.security.provider.certpath.PKIX
-sun.security.provider.certpath.PKIX$ValidatorParams
-sun.security.provider.certpath.PKIXCertPathValidator
-sun.security.provider.certpath.PKIXMasterCertPathValidator
-sun.security.provider.certpath.PolicyChecker
-sun.security.provider.certpath.PolicyNodeImpl
-sun.security.util.AbstractAlgorithmConstraints
-sun.security.util.AbstractAlgorithmConstraints$1
-sun.security.util.AlgorithmDecomposer
-sun.security.util.BitArray
-sun.security.util.ByteArrayLexOrder
-sun.security.util.ByteArrayTagOrder
-sun.security.util.Cache
-sun.security.util.Cache$EqualByteArray
-sun.security.util.CertConstraintParameters
-sun.security.util.Debug
-sun.security.util.DerEncoder
-sun.security.util.DerIndefLenConverter
-sun.security.util.DerInputBuffer
-sun.security.util.DerInputStream
-sun.security.util.DerOutputStream
-sun.security.util.DerValue
-sun.security.util.DisabledAlgorithmConstraints
-sun.security.util.DisabledAlgorithmConstraints$Constraint
-sun.security.util.DisabledAlgorithmConstraints$Constraint$Operator
-sun.security.util.DisabledAlgorithmConstraints$Constraints
-sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraint
-sun.security.util.KeyUtil
-sun.security.util.Length
-sun.security.util.MemoryCache
-sun.security.util.MemoryCache$CacheEntry
-sun.security.util.MemoryCache$SoftCacheEntry
-sun.security.util.ObjectIdentifier
-sun.security.x509.AVA
-sun.security.x509.AVAKeyword
-sun.security.x509.AccessDescription
-sun.security.x509.AlgorithmId
-sun.security.x509.AuthorityInfoAccessExtension
-sun.security.x509.AuthorityKeyIdentifierExtension
-sun.security.x509.BasicConstraintsExtension
-sun.security.x509.CRLDistributionPointsExtension
-sun.security.x509.CRLNumberExtension
-sun.security.x509.CRLReasonCodeExtension
-sun.security.x509.CertAttrSet
-sun.security.x509.CertificateAlgorithmId
-sun.security.x509.CertificateExtensions
-sun.security.x509.CertificateIssuerExtension
-sun.security.x509.CertificatePoliciesExtension
-sun.security.x509.CertificatePolicyId
-sun.security.x509.CertificateSerialNumber
-sun.security.x509.CertificateValidity
-sun.security.x509.CertificateVersion
-sun.security.x509.CertificateX509Key
-sun.security.x509.DNSName
-sun.security.x509.DeltaCRLIndicatorExtension
-sun.security.x509.DistributionPoint
-sun.security.x509.ExtendedKeyUsageExtension
-sun.security.x509.Extension
-sun.security.x509.FreshestCRLExtension
-sun.security.x509.GeneralName
-sun.security.x509.GeneralNameInterface
-sun.security.x509.GeneralNames
-sun.security.x509.InhibitAnyPolicyExtension
-sun.security.x509.IssuerAlternativeNameExtension
-sun.security.x509.IssuingDistributionPointExtension
-sun.security.x509.KeyIdentifier
-sun.security.x509.KeyUsageExtension
-sun.security.x509.NameConstraintsExtension
-sun.security.x509.NetscapeCertTypeExtension
-sun.security.x509.OCSPNoCheckExtension
-sun.security.x509.OIDMap
-sun.security.x509.OIDMap$OIDInfo
-sun.security.x509.PKIXExtensions
-sun.security.x509.PolicyConstraintsExtension
-sun.security.x509.PolicyInformation
-sun.security.x509.PolicyMappingsExtension
-sun.security.x509.PrivateKeyUsageExtension
-sun.security.x509.RDN
-sun.security.x509.SerialNumber
-sun.security.x509.SubjectAlternativeNameExtension
-sun.security.x509.SubjectInfoAccessExtension
-sun.security.x509.SubjectKeyIdentifierExtension
-sun.security.x509.URIName
-sun.security.x509.X500Name
-sun.security.x509.X500Name$1
-sun.security.x509.X509AttributeName
-sun.security.x509.X509CertImpl
-sun.security.x509.X509CertInfo
-sun.security.x509.X509Key
-sun.util.calendar.AbstractCalendar
-sun.util.calendar.BaseCalendar
-sun.util.calendar.BaseCalendar$Date
-sun.util.calendar.CalendarDate
-sun.util.calendar.CalendarSystem
-sun.util.calendar.CalendarUtils
-sun.util.calendar.Gregorian
-sun.util.calendar.Gregorian$Date
-sun.util.calendar.JulianCalendar
-sun.util.calendar.LocalGregorianCalendar
-sun.util.locale.BaseLocale
-sun.util.locale.BaseLocale$Cache
-sun.util.locale.BaseLocale$Key
-sun.util.locale.InternalLocaleBuilder
-sun.util.locale.InternalLocaleBuilder$CaseInsensitiveChar
-sun.util.locale.LanguageTag
-sun.util.locale.LocaleObjectCache
-sun.util.locale.LocaleObjectCache$CacheEntry
-sun.util.locale.LocaleSyntaxException
-sun.util.locale.LocaleUtils
-sun.util.locale.ParseStatus
-sun.util.locale.StringTokenIterator
-sun.util.logging.LoggingProxy
-sun.util.logging.LoggingSupport
-sun.util.logging.LoggingSupport$1
-sun.util.logging.PlatformLogger
-sun.util.logging.PlatformLogger$1
-sun.util.logging.PlatformLogger$Level
diff --git a/proto/Android.bp b/proto/Android.bp
new file mode 100644
index 0000000..95f453c
--- /dev/null
+++ b/proto/Android.bp
@@ -0,0 +1,17 @@
+java_library_static {
+    name: "framework-protos",
+    host_supported: true,
+    proto: {
+        type: "nano",
+    },
+    srcs: ["src/**/*.proto"],
+    no_framework_libs: true,
+    target: {
+        android: {
+            jarjar_rules: "jarjar-rules.txt",
+        },
+        host: {
+            static_libs: ["libprotobuf-java-nano"],
+        },
+    },
+}
diff --git a/proto/Android.mk b/proto/Android.mk
deleted file mode 100644
index 1c03d161..0000000
--- a/proto/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := framework-protos
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := nano
-LOCAL_SRC_FILES:= $(call all-proto-files-under, src)
-LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt
-
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-oj core-libart
-
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/jarjar-rules.txt
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-# Host-side version of framework-protos
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := host-framework-protos
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := nano
-LOCAL_SRC_FILES:= $(call all-proto-files-under, src)
-
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_STATIC_JAVA_LIBRARIES := host-libprotobuf-java-nano
-
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/jarjar-rules.txt
-
-include $(BUILD_HOST_JAVA_LIBRARY)
\ No newline at end of file
diff --git a/proto/src/gnss.proto b/proto/src/gnss.proto
new file mode 100644
index 0000000..c54ddad
--- /dev/null
+++ b/proto/src/gnss.proto
@@ -0,0 +1,45 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+// Author: siddharthr@google.com (Siddharth Ray)
+// Protos for uploading GNSS metrics.
+
+syntax = "proto2";
+
+package clearcut.connectivity;
+
+option java_package = "com.android.internal.location";
+option java_outer_classname = "GnssLogsProto";
+
+message GnssLog {
+  // Number of location reports processed
+  optional int32 num_location_report_processed = 1;
+
+  // Location failure (in percent)
+  optional int32 percentage_location_failure = 2;
+
+  // Number of time to first fix processed
+  optional int32 num_time_to_first_fix_processed = 3;
+
+  // Mean time to first fix (in seconds)
+  optional int32 mean_time_to_first_fix_secs = 4;
+
+  // Standard deviation of time to first fix (in seconds)
+  optional int32 standard_deviation_time_to_first_fix_secs = 5;
+
+  // Number of position accuracy processed
+  optional int32 num_position_accuracy_processed = 6;
+
+  // Mean position accuracy (in meters)
+  optional int32 mean_position_accuracy_meters = 7;
+
+  // Standard deviation of position accuracy (in meters)
+  optional int32 standard_deviation_position_accuracy_meters = 8;
+
+  // Number of top 4 average CN0 processed
+  optional int32 num_top_four_average_cn0_processed = 9;
+
+  // Mean of top 4 average CN0 (dB-Hz)
+  optional double mean_top_four_average_cn0_db_hz = 10;
+
+  // Standard deviation of top 4 average CN0 (dB-Hz)
+  optional double standard_deviation_top_four_average_cn0_db_hz = 11;
+}
\ No newline at end of file
diff --git a/proto/src/ipconnectivity.proto b/proto/src/ipconnectivity.proto
index 76c5418..7979302 100644
--- a/proto/src/ipconnectivity.proto
+++ b/proto/src/ipconnectivity.proto
@@ -23,7 +23,7 @@
 // It is not intended to map one to one to the TRANSPORT_* constants defined in
 // android.net.NetworkCapabilities. Instead it is intended to be used as
 // a dimension field for metrics events and aggregated metrics.
-// Next tag: 7
+// Next tag: 10
 enum LinkLayer {
   // An unknown link layer technology.
   UNKNOWN   = 0;
@@ -32,6 +32,9 @@
   CELLULAR  = 2;
   ETHERNET  = 3;
   WIFI      = 4;
+  WIFI_P2P  = 7;
+  WIFI_NAN  = 8; // Also known as WiFi Aware
+  LOWPAN    = 9;
 
   // Indicates that the link layer dimension is not relevant for the metrics or
   // event considered.
@@ -47,16 +50,19 @@
   optional int32 value = 2;
 };
 
-// Logs changes in the system default network. Changes can be 1) acquiring a
-// default network with no previous default, 2) a switch of the system default
-// network to a new default network, 3) a loss of the system default network.
-// This message is associated to android.net.metrics.DefaultNetworkEvent.
+// An event recorded when the system default network disconnects or the system
+// switches to a new default network. An event is also recorded to cover gaps
+// without a default network.
+// Next tag: 12
 message DefaultNetworkEvent {
-  // A value of 0 means this is a loss of the system default network.
-  optional NetworkId network_id = 1;
 
-  // A value of 0 means there was no previous default network.
-  optional NetworkId previous_network_id = 2;
+  // Reason why this network stopped being the default.
+  enum LostReason {
+    UNKNOWN       = 0;
+    OUTSCORED     = 1;
+    INVALIDATION  = 2;
+    DISCONNECT    = 3;
+  };
 
   // Whether the network supports IPv4, IPv6, or both.
   enum IPSupport {
@@ -66,17 +72,65 @@
     DUAL = 3;
   };
 
+  // Duration in milliseconds when this network was the default.
+  // Since P.
+  optional int64 default_network_duration_ms = 5;
+
+  // Duration in milliseconds when this default network Internet access was
+  // validated. This field is equal to 0 for DefaultNetworkEvents representing
+  // lack of a default network.
+  // Since P.
+  optional int64 validation_duration_ms = 11;
+
+  // Network score of this network when it became the default network.
+  // Or 0 if this event represents a period without a default network.
+  // Since P.
+  optional int64 initial_score = 7;
+
+  // Network score of this network when it stopped being the default network.
+  // Or 0 if this event represents a period without a default network.
+  // Since P.
+  optional int64 final_score = 8;
+
+  // Best available information about IP support of this default network.
+  // Or NONE if this event represents a period without a default network.
+  // Since P.
+  optional IPSupport ip_support = 9;
+
+  // LinkLayer of the previous default network. Ignores any previous period
+  // without a default network.
+  // Since P
+  optional LinkLayer previous_default_network_link_layer = 10;
+
+  // Deprecated fields
+
+  // A value of 0 means this is a loss of the system default network.
+  // Deprecated since version 3. Replaced by top level network_id.
+  optional NetworkId network_id = 1 [deprecated = true];
+
+  // A value of 0 means there was no previous default network.
+  // Deprecated since version 3. Replaced by previous_default_network_id.
+  optional NetworkId previous_network_id = 2 [deprecated = true];
+
   // Best available information about IP support of the previous network when
   // disconnecting or switching to a new default network.
-  optional IPSupport previous_network_ip_support = 3;
+  // Deprecated since version 3. Replaced by ip_support field.
+  optional IPSupport previous_network_ip_support = 3 [deprecated = true];
 
   // The transport types of the new default network, represented by
   // TRANSPORT_* constants as defined in NetworkCapabilities.
-  repeated int32 transport_types = 4;
+  // Deprecated since version 3. Replaced by top-level transports field.
+  repeated int32 transport_types = 4 [deprecated = true];
+
+  // Duration in milliseconds without a default network. This field is non-zero
+  // only for DefaultNetworkEvents representing lack of a default network.
+  // Since P.
+  optional int64 no_default_network_duration_ms = 6 [deprecated = true];
 };
 
 // Logs IpReachabilityMonitor probe events and NUD_FAILED events.
 // This message is associated to android.net.metrics.IpReachabilityEvent.
+// Next tag: 3.
 message IpReachabilityEvent {
   // The interface name (wlan, rmnet, lo, ...) on which the probe was sent.
   // Deprecated since version 2, to be replaced by link_layer field.
@@ -91,6 +145,7 @@
 // Logs NetworkMonitor and ConnectivityService events related to the state of
 // a network: connection, evaluation, validation, lingering, and disconnection.
 // This message is associated to android.net.metrics.NetworkEvent.
+// Next tag: 4.
 message NetworkEvent {
   // The id of the network on which this event happened.
   // Deprecated since version 3.
@@ -108,6 +163,7 @@
 // Logs individual captive portal probing events that are performed when
 // evaluating or reevaluating networks for Internet connectivity.
 // This message is associated to android.net.metrics.ValidationProbeEvent.
+// Next tag: 5.
 message ValidationProbeEvent {
   // The id of the network for which the probe was sent.
   // Deprecated since version 3.
@@ -124,26 +180,64 @@
   optional int32 probe_result = 4;
 }
 
-// Logs DNS lookup latencies. Repeated fields must have the same length.
+// Logs DNS lookup latencies.
 // This message is associated to android.net.metrics.DnsEvent.
-// Deprecated since version 2.
+// Next tag: 11
 message DNSLookupBatch {
+
+  // The time it took for successful DNS lookups to complete.
+  // The number of repeated values can be less than getaddrinfo_query_count
+  // + gethostbyname_query_count in case of event rate-limiting.
+  repeated int32 latencies_ms = 4;
+
+  // The total number of getaddrinfo queries.
+  // Since version 4.
+  optional int64 getaddrinfo_query_count = 5;
+
+  // The total number of gethostbyname queries.
+  // Since version 4.
+  optional int64 gethostbyname_query_count = 6;
+
+  // The total number of getaddrinfo errors.
+  // Since version 4.
+  optional int64 getaddrinfo_error_count = 7;
+
+  // The total number of gethostbyname errors.
+  // Since version 4.
+  optional int64 gethostbyname_error_count = 8;
+
+  // Counts of all errors returned by getaddrinfo.
+  // The Pair key field is the getaddrinfo error value.
+  // The value field is the count for that return value.
+  // Since version 4
+  repeated Pair getaddrinfo_errors = 9;
+
+  // Counts of all errors returned by gethostbyname.
+  // The Pair key field is the gethostbyname errno value.
+  // the Pair value field is the count for that errno code.
+  // Since version 4
+  repeated Pair gethostbyname_errors = 10;
+
+
+  // Deprecated fields
+
   // The id of the network on which the DNS lookups took place.
-  optional NetworkId network_id = 1;
+  // Deprecated since version 3.
+  optional NetworkId network_id = 1 [deprecated = true];
 
   // The types of the DNS lookups, as defined in android.net.metrics.DnsEvent.
-  repeated int32 event_types = 2;
+  // Deprecated since version 3.
+  repeated int32 event_types = 2 [deprecated = true];
 
   // The return values of the DNS resolver for each DNS lookups.
-  repeated int32 return_codes = 3;
-
-  // The time it took for each DNS lookups to complete.
-  repeated int32 latencies_ms = 4;
+  // Deprecated since version 3.
+  repeated int32 return_codes = 3 [deprecated = true];
 };
 
 // Represents a collections of DNS lookup latencies and counters for a
 // particular combination of DNS query type and return code.
 // Since version 2.
+// Next tag: 7.
 message DNSLatencies {
   // The type of the DNS lookups, as defined in android.net.metrics.DnsEvent.
   // Acts as a key for a set of DNS query results.
@@ -203,6 +297,7 @@
 // state transition or a response packet parsing error.
 // This message is associated to android.net.metrics.DhcpClientEvent and
 // android.net.metrics.DhcpErrorEvent.
+// Next tag: 5
 message DHCPEvent {
   // The interface name (wlan, rmnet, lo, ...) on which the event happened.
   // Deprecated since version 2, to be replaced by link_layer field.
@@ -255,7 +350,7 @@
 // Represents Router Advertisement listening statistics for an interface with
 // Android Packet Filter enabled.
 // Since version 1.
-// Next tag: 12
+// Next tag: 15
 message ApfStatistics {
   // The time interval in milliseconds these stastistics cover.
   optional int64 duration_ms = 1;
@@ -288,12 +383,28 @@
 
   // The total number of APF program updates triggered when disabling the
   // multicast filter. Since version 3.
+  // Since version 4.
   optional int32 program_updates_allowing_multicast = 11;
+
+  // The total number of packets processed by the APF interpreter.
+  // Since version 4.
+  optional int32 total_packet_processed = 12;
+
+  // The total number of packets dropped by the APF interpreter.
+  // Since version 4.
+  optional int32 total_packet_dropped = 13;
+
+  // List of hardware counters collected by the APF interpreter.
+  // The Pair key is the counter id, defined in android.net.metrics.ApfStats.
+  // The Pair value is the counter value.
+  // Since version 4.
+  repeated Pair hardware_counters = 14;
 }
 
 // Represents the reception of a Router Advertisement packet for an interface
 // with Android Packet Filter enabled.
 // Since version 1.
+// Next tag: 7.
 message RaEvent {
   // All lifetime values are expressed in seconds. The default value for an
   // option lifetime that was not present in the RA option list is -1.
@@ -322,6 +433,7 @@
 // Represents an IP provisioning event in IpManager and how long the
 // provisioning action took.
 // This message is associated to android.net.metrics.IpManagerEvent.
+// Next tag: 4.
 message IpProvisioningEvent {
   // The interface name (wlan, rmnet, lo, ...) on which the probe was sent.
   // Deprecated since version 2, to be replaced by link_layer field.
@@ -335,8 +447,98 @@
   optional int32 latency_ms = 3;
 }
 
+// Represents statistics from a single android Network.
+// Since version 4. Replace NetworkEvent.
+// Next tag: 9.
+message NetworkStats {
+
+  // Duration of this Network lifecycle in milliseconds.
+  optional int64 duration_ms = 1;
+
+  // Information about IP support of this network.
+  optional DefaultNetworkEvent.IPSupport ip_support = 2;
+
+  // True if the network was validated at least once.
+  optional bool ever_validated = 3;
+
+  // True if a captive portal was found at least once on this network.
+  optional bool portal_found = 4;
+
+  // Total number of times no connectivity was reported for this network.
+  optional int32 no_connectivity_reports = 5;
+
+  // Total number of validation attempts.
+  optional int32 validation_attempts = 6;
+
+  // Results from all validation attempts.
+  // The Pair key is the result:
+  //    0 -> unvalidated
+  //    1 -> validated
+  //    2 -> captive portal
+  // The Pair value is the duration of the validation attempts in milliseconds.
+  repeated Pair validation_events = 7;
+
+  // Time series of validation states in time order.
+  // The Pair key is the state:
+  //    0 -> unvalidated
+  //    1 -> validated
+  //    2 -> captive portal,
+  // The Pair value is the duration of that state in milliseconds.
+  repeated Pair validation_states = 8;
+}
+
+// Represents statistics from NFLOG wakeup events due to ingress packets.
+// Since oc-mr1.
+// Next tag: 13.
+message WakeupStats {
+  // The time duration in seconds covered by these stats, for deriving
+  // exact wakeup rates.
+  optional int64 duration_sec = 1;
+
+  // The total number of ingress packets waking up the device.
+  optional int64 total_wakeups = 2;
+
+  // The total number of wakeup packets routed to a socket belonging to
+  // the root uid (uid 0).
+  optional int64 root_wakeups = 3;
+
+  // The total number of wakeup packets routed to a socket belonging to
+  // the system server (uid 1000).
+  optional int64 system_wakeups = 4;
+
+  // The total number of wakeup packets routed to a socket belonging to
+  // an application (uid > 9999).
+  optional int64 application_wakeups = 5;
+
+  // The total number of wakeup packets routed to a socket belonging to another
+  // uid than the root uid, system uid, or an application uid (any uid in
+  // between [1001, 9999]. See android.os.Process for possible uids.
+  optional int64 non_application_wakeups = 6;
+
+  // The total number of wakeup packets with no associated socket or uid.
+  optional int64 no_uid_wakeups = 7;
+
+  // Counts of all different ethertype values from wakeup packets received.
+  repeated Pair ethertype_counts = 8;
+
+  // Counts of all different IP next header values from wakeup packets received.
+  repeated Pair ip_next_header_counts = 9;
+
+  // The total number of wakeup packets whose destination hardware address was
+  // a unicast address.
+  optional int64 l2_unicast_count = 10;
+
+  // The total number of wakeup packets whose destination hardware address was
+  // a multicast address.
+  optional int64 l2_multicast_count = 11;
+
+  // The total number of wakeup packets whose destination hardware address was
+  // a broadcast address.
+  optional int64 l2_broadcast_count = 12;
+}
+
 // Represents one of the IP connectivity event defined in this file.
-// Next tag: 19
+// Next tag: 20
 message IpConnectivityEvent {
   // Time in ms when the event was recorded.
   optional int64 time_ms = 1;
@@ -370,14 +572,13 @@
   oneof event {
 
     // An event about the system default network.
-    // The link_layer field is not relevant for this event and set to NONE.
     DefaultNetworkEvent default_network_event = 2;
 
     // An IP reachability probe event.
     IpReachabilityEvent ip_reachability_event = 3;
 
     // A network lifecycle event.
-    NetworkEvent network_event = 4;
+    NetworkEvent network_event = 4 [deprecated = true];
 
     // A batch of DNS lookups.
     // Deprecated in the nyc-mr2 release since version 2,and replaced by
@@ -407,10 +608,17 @@
 
     // An RA packet reception event.
     RaEvent ra_event = 11;
+
+    // Network statistics.
+    NetworkStats network_stats = 19;
+
+    // Ingress packet wakeup statistics.
+    WakeupStats wakeup_stats = 20;
   };
 };
 
 // The information about IP connectivity events.
+// Next tag: 4.
 message IpConnectivityLog {
   // An array of IP connectivity events.
   repeated IpConnectivityEvent events = 1;
@@ -424,5 +632,6 @@
   //  nyc-mr1: not populated, implicitly 1.
   //  nyc-mr2: 2.
   //  oc:      3.
+  //  oc-dr1:  4.
   optional int32 version = 3;
 };
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index dd84d84..0e2c46b 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -138,6 +138,18 @@
     REASON_TIMEOUT = 19;
   }
 
+  // Subtypes of camera events for ACTION_CAMERA_EVENT
+  enum CameraEvent {
+    // A back-facing camera was used
+    CAMERA_BACK_USED = 0;
+
+    // A front-facing camera was used
+    CAMERA_FRONT_USED = 1;
+
+    // An external camera was used
+    CAMERA_EXTERNAL_USED = 2;
+  }
+
   // Known visual elements: views or controls.
   enum View {
     // Unknown view
@@ -3974,6 +3986,81 @@
 
     // ---- End O Constants, all O constants go above this line ----
 
+    // OPEN: Settings > System > Languages & input > Advanced > Lift to open camera
+    SETTINGS_GESTURE_CAMERA_LIFT_TRIGGER = 986;
+
+    // OPEN: Settings > Battery > High Usage > Abnormal app page
+    // CATEGORY: SETTINGS
+    FUELGAUGE_ANOMALY_DETAIL = 987;
+
+    // OPEN: Settings > Battery > High Usage
+    DIALOG_HANDLE_ANOMALY = 988;
+
+    // ACTION: Camera lift gesture
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: O
+    ACTION_CAMERA_LIFT_TRIGGER = 989;
+
+    // OPEN: Choose screen lock dialog in Settings
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    SETTINGS_CHOOSE_LOCK_DIALOG = 990;
+
+    // OPEN: Assist Gesture training intro in Settings
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    SETTINGS_ASSIST_GESTURE_TRAINING_INTRO = 991;
+
+    // OPEN: Assist Gesture training enrolling in Settings
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    SETTINGS_ASSIST_GESTURE_TRAINING_ENROLLING = 992;
+
+    // OPEN: Assist Gesture training finished in Settings
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    SETTINGS_ASSIST_GESTURE_TRAINING_FINISHED = 993;
+
+    // FIELD: The numeric preference value (of type long) when it is changed in Settings
+    FIELD_SETTINGS_PREFERENCE_CHANGE_LONG_VALUE = 994;
+
+    // FIELD: The numeric preference value (of type float) when it is changed in Settings
+    FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE = 995;
+
+    // OPEN: Settings > System > Languages & input > Assist gesture
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    SETTINGS_ASSIST_GESTURE = 996;
+
+    // ACTION: Assist gesture released without triggering
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: O DR
+    ASSIST_GESTURE_RELEASED = 997;
+
+    // ACTION: Assist gesture primed
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: O DR
+    ASSIST_GESTURE_PRIMED = 998;
+
+    // ACTION: Assist gesture triggered
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: O DR
+    ASSIST_GESTURE_TRIGGERED = 999;
+
+    // ACTION: Update default app from Settings
+    ACTION_SETTINGS_UPDATE_DEFAULT_APP = 1000;
+
+    // FIELD - Query length when Settings search result is clicked
+    FIELD_SETTINGS_SERACH_QUERY_LENGTH = 1001;
+
+    // FIELD - Number of results when Settings search result is clicked
+    FIELD_SETTINGS_SERACH_RESULT_COUNT = 1002;
+
+    // OPEN: Settings > Display > Ambient Display
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    AMBIENT_DISPLAY_SETTINGS = 1003;
+
     // ACTION: CaptivePortalLoginActivity starts
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: O DR
@@ -3999,11 +4086,151 @@
     // OS: O DR
     ACTION_WIFI_SIGNIN = 1008;
 
+    // OPEN: Settings->Connected Devices->Bluetooth->(click on details link for a paired device)
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    BLUETOOTH_DEVICE_DETAILS = 1009;
+
+    // OPEN: Settings > credential pages - prompt for key guard configuration confirmation
+    CONFIGURE_KEYGUARD_DIALOG = 1010;
+
+    // Open: Settings > Search > No Result View
+    SETTINGS_SEARCH_NO_RESULT = 1011;
+
+    // OPEN: Assist Gesture before training
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    SETTINGS_ASSIST_GESTURE_FIRST_TIME = 1012;
+
     // CaptivePortalLoginActivity displays SSL error page
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: O DR
     CAPTIVE_PORTAL_LOGIN_ACTIVITY_SSL_ERROR = 1013;
 
+    // OPEN: Settings > Network > Tether > Wi-Fi hotspot
+    WIFI_TETHER_SETTINGS = 1014;
+
+    // OPEN: Settings->Connected Devices->Bluetooth->(click on details link for a paired device)
+    // -> Edit name button.
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    DIALOG_BLUETOOTH_PAIRED_DEVICE_RENAME = 1015;
+
+    // ACTION: Settings > Notification Settings > Open application notification
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    ACTION_OPEN_APP_NOTIFICATION_SETTING = 1016;
+
+    // ACTION: Settings > App Info > Open app settings
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    ACTION_OPEN_APP_SETTING = 1017;
+
+    // OPEN: Settings > Connected devices > Bluetooth > Pair new device
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    BLUETOOTH_PAIRING = 1018;
+
+    // ACTION: Collect PSD Signals
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    ACTION_PSD_LOADER = 1019;
+
+    // ACTION: Background check action on an app
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    ACTION_APP_BACKGROUND_CHECK = 1020;
+
+    // ACTION: Location check action on an app
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    ACTION_APP_LOCATION_CHECK = 1021;
+
+    // Device headset status
+    // CATEGORY: OTHER
+    //  SUBTYPE: 1 is DON, 2 is DOFF
+    // OS: O DR
+    ACTION_HEADSET_STATUS = 1022;
+
+    // Device Headset Plug status
+    // CATEGORY: OTHER
+    //  SUBTYPE: 1 is AC power, 2 is USB power, 3 is Unplug
+    // OS: O DR
+    ACTION_HEADSET_PLUG = 1023;
+
+    // Device Headset battery level on Plug
+    // CATEGORY: OTHER
+    // FIELD - The battery percentage when the user decided to plug in
+    // Type: integer
+    // OS: O DR
+    FIELD_PLUG_BATTERY_PERCENTAGE = 1024;
+
+    // Device Headset battery level on Plug
+    // CATEGORY: OTHER
+    // FIELD - The battery percentage when the user decided to plug in
+    // Type: integer
+    // OS: O DR
+    FIELD_UNPLUG_BATTERY_PERCENTAGE = 1025;
+
+    // Device Headset Pose status
+    // CATEGORY: OTHER
+    //  SUBTYPE: 1 is 6DOF, 2 is 3DOF
+    // OS: O DR
+    ACTION_HEADSET_POSE_STATUS = 1026;
+
+    // Device Headset Usage session time
+    // CATEGORY: OTHER
+    // FIELD - The time the headset was used in a session
+    // OS: O DR
+    FIELD_SESSION_TIME_MS = 1027;
+
+    // Device Headset Idle time
+    // CATEGORY: OTHER
+    // FIELD - The time in between each session
+    // OS: O DR
+    FIELD_TIME_ELAPSED_BETWEEN_SESSION_MS = 1028;
+
+    // Device Headset charge session time
+    // CATEGORY: OTHER
+    // FIELD - The time taken for each charge
+    // OS: O DR
+    FIELD_TIME_OF_CHARGE_MS = 1029;
+
+    // Device Headset time between charge
+    // CATEGORY: OTHER
+    // FIELD - The time in between each charge
+    // OS: O DR
+    FIELD_TIME_ELAPSED_BETWEEN_CHARGE_MS = 1030;
+
+    // OPEN: Settings->Connected Devices->Bluetooth->(click on details link for a paired device)
+    // -> Forget button.
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    DIALOG_BLUETOOTH_PAIRED_DEVICE_FORGET = 1031;
+
+    // An event from the camera service
+    // CATEGORY: OTHER
+    //  SUBTYPE: CameraEvent
+    // OS: O DR
+    ACTION_CAMERA_EVENT = 1032;
+
+    // OPEN: Settings > Trampoline Intent > Settings page
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    TRAMPOLINE_SETTINGS_EVENT = 1033;
+
+    // ---- End O-DR1 Constants, all O-DR1 constants go above this line ----
+
+    // ACTION: Settings > Network & Internet > Mobile network > Mobile data
+    // CATEGORY: SETTINGS
+    // OS: O MR
+    ACTION_MOBILE_NETWORK_MOBILE_DATA_TOGGLE = 1081;
+
+    // ACTION: Settings > Network & Internet > Mobile network > Data usage
+    // CATEGORY: SETTINGS
+    // OS: O MR
+    ACTION_MOBILE_NETWORK_DATA_USAGE = 1082;
+
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
   }
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index 2f6b7e6..52f721b 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -180,6 +180,13 @@
     // Package: android
     NOTE_FOREGROUND_SERVICES = 40;
 
+    // Inform the user that the connected audio accessory is not supported
+    NOTE_USB_AUDIO_ACCESSORY_NOT_SUPPORTED = 41;
+
+    // Inform the user that a wrong password was detected while attempting to connect
+    // to a Wi-Fi network
+    NOTE_WIFI_WRONG_PASSWORD = 42;
+
     // ADD_NEW_IDS_ABOVE_THIS_LINE
     // Legacy IDs with arbitrary values appear below
     // Legacy IDs existed as stable non-conflicting constants prior to the O release
@@ -216,6 +223,10 @@
     // Package: com.android.systemui
     NOTE_TV_PIP = 1100;
 
+    // Notify the user that open Wi-Fi networks are available.
+    // Package: android
+    NOTE_NETWORK_AVAILABLE = 17303299;
+
     // Communicate to the user about remote bugreports.
     // Package: android
     NOTE_REMOTE_BUGREPORT = 678432343;
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index 564d135..c4dc506 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -255,6 +255,63 @@
   // Indicates the number of times an error was encountered in
   // Wificond when wifi was turned on.
   optional int32 num_wifi_on_failure_due_to_wificond = 56;
+
+  // Wi-Fi Aware metrics
+  optional WifiAwareLog wifi_aware_log = 57;
+
+  // Number of saved Passpoint providers in user profile.
+  optional int32 num_passpoint_providers = 58;
+
+  // Count of times Passpoint provider being installed.
+  optional int32 num_passpoint_provider_installation = 59;
+
+  // Count of times Passpoint provivider is installed successfully.
+  optional int32 num_passpoint_provider_install_success = 60;
+
+  // Count of times Passpoint provider is being uninstalled.
+  optional int32 num_passpoint_provider_uninstallation = 61;
+
+  // Count of times Passpoint provider is uninstalled successfully.
+  optional int32 num_passpoint_provider_uninstall_success = 62;
+
+  // Count of saved Passpoint providers device has ever connected to.
+  optional int32 num_passpoint_providers_successfully_connected = 63;
+
+  // Histogram counting instances of scans with N many ScanResults with unique ssids
+  repeated NumConnectableNetworksBucket total_ssids_in_scan_histogram = 64;
+
+  // Histogram counting instances of scans with N many ScanResults/bssids
+  repeated NumConnectableNetworksBucket total_bssids_in_scan_histogram = 65;
+
+  // Histogram counting instances of scans with N many unique open ssids
+  repeated NumConnectableNetworksBucket available_open_ssids_in_scan_histogram = 66;
+
+  // Histogram counting instances of scans with N many bssids for open networks
+  repeated NumConnectableNetworksBucket available_open_bssids_in_scan_histogram = 67;
+
+  // Histogram counting instances of scans with N many unique ssids for saved networks
+  repeated NumConnectableNetworksBucket available_saved_ssids_in_scan_histogram = 68;
+
+  // Histogram counting instances of scans with N many bssids for saved networks
+  repeated NumConnectableNetworksBucket available_saved_bssids_in_scan_histogram = 69;
+
+  // Histogram counting instances of scans with N many unique SSIDs for open or saved networks
+  repeated NumConnectableNetworksBucket available_open_or_saved_ssids_in_scan_histogram = 70;
+
+  // Histogram counting instances of scans with N many BSSIDs for open or saved networks
+  repeated NumConnectableNetworksBucket available_open_or_saved_bssids_in_scan_histogram = 71;
+
+  // Histogram counting instances of scans with N many ScanResults matching unique saved passpoint providers
+  repeated NumConnectableNetworksBucket available_saved_passpoint_provider_profiles_in_scan_histogram = 72;
+
+  // Histogram counting instances of scans with N many ScanResults BSSIDs matching a saved passpoint provider
+  repeated NumConnectableNetworksBucket available_saved_passpoint_provider_bssids_in_scan_histogram = 73;
+
+  // Counts the number of AllSingleScanLister.onResult calls with a full band scan result
+  optional int32 full_band_all_single_scan_listener_results = 74;
+
+  // Counts the number of AllSingleScanLister.onResult calls with a partial (channels) scan result
+  optional int32 partial_all_single_scan_listener_results = 75;
 }
 
 // Information that gets logged for every WiFi connection.
@@ -676,3 +733,197 @@
   // Authentication failure reason, as reported by WifiManager (calculated from state & deauth code)
   optional AuthFailureReason auth_failure_reason = 13 [default = AUTH_FAILURE_UNKNOWN];
 }
+
+// Wi-Fi Aware metrics
+message WifiAwareLog {
+  // total number of unique apps that used Aware (measured on attach)
+  optional int32 num_apps = 1;
+
+  // total number of unique apps that used an identity callback when attaching
+  optional int32 num_apps_using_identity_callback = 2;
+
+  // maximum number of attaches for an app
+  optional int32 max_concurrent_attach_sessions_in_app = 3;
+
+  // histogram of attach request results
+  repeated NanStatusHistogramBucket histogram_attach_session_status = 4;
+
+  // maximum number of concurrent publish sessions in a single app
+  optional int32 max_concurrent_publish_in_app = 5;
+
+  // maximum number of concurrent subscribe sessions in a single app
+  optional int32 max_concurrent_subscribe_in_app = 6;
+
+  // maximum number of concurrent discovery (publish+subscribe) sessions in a single app
+  optional int32 max_concurrent_discovery_sessions_in_app = 7;
+
+  // maximum number of concurrent publish sessions in the system
+  optional int32 max_concurrent_publish_in_system = 8;
+
+  // maximum number of concurrent subscribe sessions in the system
+  optional int32 max_concurrent_subscribe_in_system = 9;
+
+  // maximum number of concurrent discovery (publish+subscribe) sessions in the system
+  optional int32 max_concurrent_discovery_sessions_in_system = 10;
+
+  // histogram of publish request results
+  repeated NanStatusHistogramBucket histogram_publish_status = 11;
+
+  // histogram of subscribe request results
+  repeated NanStatusHistogramBucket histogram_subscribe_status = 12;
+
+  // number of unique apps which experienced a discovery session creation failure due to lack of
+  // resources
+  optional int32 num_apps_with_discovery_session_failure_out_of_resources = 13;
+
+  // histogram of create ndp request results
+  repeated NanStatusHistogramBucket histogram_request_ndp_status = 14;
+
+  // histogram of create ndp out-of-band (OOB) request results
+  repeated NanStatusHistogramBucket histogram_request_ndp_oob_status = 15;
+
+  // maximum number of concurrent active data-interfaces (NDI) in a single app
+  optional int32 max_concurrent_ndi_in_app = 19;
+
+  // maximum number of concurrent active data-interfaces (NDI) in the system
+  optional int32 max_concurrent_ndi_in_system = 20;
+
+  // maximum number of concurrent data-paths (NDP) in a single app
+  optional int32 max_concurrent_ndp_in_app = 21;
+
+  // maximum number of concurrent data-paths (NDP) in the system
+  optional int32 max_concurrent_ndp_in_system = 22;
+
+  // maximum number of concurrent secure data-paths (NDP) in a single app
+  optional int32 max_concurrent_secure_ndp_in_app = 23;
+
+  // maximum number of concurrent secure data-paths (NDP) in the system
+  optional int32 max_concurrent_secure_ndp_in_system = 24;
+
+  // maximum number of concurrent data-paths (NDP) per data-interface (NDI)
+  optional int32 max_concurrent_ndp_per_ndi = 25;
+
+  // histogram of durations of Aware being available
+  repeated HistogramBucket histogram_aware_available_duration_ms = 26;
+
+  // histogram of durations of Aware being enabled
+  repeated HistogramBucket histogram_aware_enabled_duration_ms = 27;
+
+  // histogram of duration (in ms) of attach sessions
+  repeated HistogramBucket histogram_attach_duration_ms = 28;
+
+  // histogram of duration (in ms) of publish sessions
+  repeated HistogramBucket histogram_publish_session_duration_ms = 29;
+
+  // histogram of duration (in ms) of subscribe sessions
+  repeated HistogramBucket histogram_subscribe_session_duration_ms = 30;
+
+  // histogram of duration (in ms) of data-paths (NDP)
+  repeated HistogramBucket histogram_ndp_session_duration_ms = 31;
+
+  // histogram of usage (in MB) of data-paths (NDP)
+  repeated HistogramBucket histogram_ndp_session_data_usage_mb = 32;
+
+  // histogram of usage (in MB) of data-path creation time (in ms) measured as request -> confirm
+  repeated HistogramBucket histogram_ndp_creation_time_ms = 33;
+
+  // statistics for data-path (NDP) creation time (in ms) measured as request -> confirm: minimum
+  optional int64 ndp_creation_time_ms_min = 34;
+
+  // statistics for data-path (NDP) creation time (in ms) measured as request -> confirm: maximum
+  optional int64 ndp_creation_time_ms_max = 35;
+
+  // statistics for data-path (NDP) creation time (in ms) measured as request -> confirm: sum
+  optional int64 ndp_creation_time_ms_sum = 36;
+
+  // statistics for data-path (NDP) creation time (in ms) measured as request -> confirm: sum of sq
+  optional int64 ndp_creation_time_ms_sum_of_sq = 37;
+
+  // statistics for data-path (NDP) creation time (in ms) measured as request -> confirm: number of
+  // samples
+  optional int64 ndp_creation_time_ms_num_samples = 38;
+
+  // total time within the logging window that aware was available
+  optional int64 available_time_ms = 39;
+
+  // total time within the logging window that aware was enabled
+  optional int64 enabled_time_ms = 40;
+
+  // Histogram bucket for Wi-Fi Aware logs. Range is [start, end)
+  message HistogramBucket {
+    // lower range of the bucket (inclusive)
+    optional int64 start = 1;
+
+    // upper range of the bucket (exclusive)
+    optional int64 end = 2;
+
+    // number of samples in the bucket
+    optional int32 count = 3;
+  }
+
+  // Status of various NAN operations
+  enum NanStatusTypeEnum {
+    // constant to be used by proto
+    UNKNOWN = 0;
+
+    // NAN operation succeeded
+    SUCCESS = 1;
+
+    // NAN Discovery Engine/Host driver failures
+    INTERNAL_FAILURE = 2;
+
+    // NAN OTA failures
+    PROTOCOL_FAILURE = 3;
+
+    // The publish/subscribe discovery session id is invalid
+    INVALID_SESSION_ID = 4;
+
+    // Out of resources to fufill request
+    NO_RESOURCES_AVAILABLE = 5;
+
+    // Invalid arguments passed
+    INVALID_ARGS = 6;
+
+    // Invalid peer id
+    INVALID_PEER_ID = 7;
+
+    // Invalid NAN data-path (ndp) id
+    INVALID_NDP_ID = 8;
+
+    // Attempting to enable NAN when not available, e.g. wifi is disabled
+    NAN_NOT_ALLOWED = 9;
+
+    // Over the air ACK not received
+    NO_OTA_ACK = 10;
+
+    // Attempting to enable NAN when already enabled
+    ALREADY_ENABLED = 11;
+
+    // Can't queue tx followup message foor transmission
+    FOLLOWUP_TX_QUEUE_FULL = 12;
+
+    // Unsupported concurrency of NAN and another feature - NAN disabled
+    UNSUPPORTED_CONCURRENCY_NAN_DISABLED = 13;
+
+    // Unknown NanStatusType
+    UNKNOWN_HAL_STATUS = 14;
+  }
+
+  // Histogram bucket for Wi-Fi Aware (NAN) status.
+  message NanStatusHistogramBucket {
+    // status type defining the bucket
+    optional NanStatusTypeEnum nan_status_type = 1;
+
+    // number of samples in the bucket
+    optional int32 count = 2;
+  }
+}
+
+// Data point used to build 'Number of Connectable Network' histograms
+message NumConnectableNetworksBucket {
+  // Number of connectable networks seen in a scan result
+  optional int32 num_connectable_networks = 1 [default = 0];
+
+  // Number of scan results with num_connectable_networks
+  optional int32 count = 2 [default = 0];
+}
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 5070e39..f9f6bf7 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -1325,12 +1325,10 @@
     SkBitmap bitmap;
     GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
 
-    bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
     jlong id = (jlong)(uintptr_t)rsAllocationCreateFromBitmap((RsContext)con,
                                                   (RsType)type, (RsAllocationMipmapControl)mip,
                                                   ptr, bitmap.getSize(), usage);
-    bitmap.unlockPixels();
     return id;
 }
 
@@ -1341,12 +1339,10 @@
     SkBitmap bitmap;
     GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
 
-    bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
     jlong id = (jlong)(uintptr_t)rsAllocationCreateTyped((RsContext)con,
                                             (RsType)type, (RsAllocationMipmapControl)mip,
                                             (uint32_t)usage, (uintptr_t)ptr);
-    bitmap.unlockPixels();
     return id;
 }
 
@@ -1357,12 +1353,10 @@
     SkBitmap bitmap;
     GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
 
-    bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
     jlong id = (jlong)(uintptr_t)rsAllocationCubeCreateFromBitmap((RsContext)con,
                                                       (RsType)type, (RsAllocationMipmapControl)mip,
                                                       ptr, bitmap.getSize(), usage);
-    bitmap.unlockPixels();
     return id;
 }
 
@@ -1374,12 +1368,10 @@
     int w = bitmap.width();
     int h = bitmap.height();
 
-    bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
     rsAllocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0,
                        0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
                        w, h, ptr, bitmap.getSize(), 0);
-    bitmap.unlockPixels();
 }
 
 static void
@@ -1388,10 +1380,8 @@
     SkBitmap bitmap;
     GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
 
-    bitmap.lockPixels();
     void* ptr = bitmap.getPixels();
     rsAllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, ptr, bitmap.getSize());
-    bitmap.unlockPixels();
     bitmap.notifyPixelsChanged();
 }
 
diff --git a/services/Android.mk b/services/Android.mk
index 17fc468..b811b0d 100644
--- a/services/Android.mk
+++ b/services/Android.mk
@@ -34,7 +34,6 @@
     net \
     print \
     restrictions \
-    retaildemo \
     usage \
     usb \
     voiceinteraction
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 9e4d89c..0e42e6d 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -271,6 +271,7 @@
 
     private void processKeyEvent(EventStreamState state, KeyEvent event, int policyFlags) {
         if (!state.shouldProcessKeyEvent(event)) {
+            super.onInputEvent(event, policyFlags);
             return;
         }
         mEventHandler.onKeyEvent(event, policyFlags);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 7ddc1a2..a58ba09 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -489,15 +489,6 @@
                 if (pip != null) {
                     int pipId = pip.getId();
                     event.setWindowId(pipId);
-                    event.setSealed(true);
-                    AccessibilityNodeInfo info = event.getSource();
-                    info.setSealed(false);
-                    event.setSealed(false);
-                    if (info != null) {
-                        info.setSourceNodeId(info.getSourceNodeId(), pipId);
-                        event.setSource(info);
-                        info.recycle();
-                    }
                 }
             }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
index 7e82eda..b1ac589 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
@@ -690,6 +690,7 @@
                 }
                 break;
                 case MotionEvent.ACTION_UP: {
+                    mHandler.removeMessages(MESSAGE_ON_ACTION_TAP_AND_HOLD);
                     if (!mMagnificationController.magnificationRegionContains(
                             event.getX(), event.getY())) {
                         transitionToDelegatingState(!mShortcutTriggered);
@@ -703,7 +704,6 @@
                     if (mLastDownEvent == null) {
                         return;
                     }
-                    mHandler.removeMessages(MESSAGE_ON_ACTION_TAP_AND_HOLD);
                     if (!GestureUtils.isTap(mLastDownEvent, event, mTapTimeSlop,
                             mTapDistanceSlop, 0)) {
                         transitionToDelegatingState(true);
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index aad4431..16a927c3 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -2426,14 +2426,14 @@
             out.attribute(null, "p", Integer.toHexString(widget.provider.tag));
         }
         if (widget.options != null) {
-            out.attribute(null, "min_width", Integer.toHexString(widget.options.getInt(
-                    AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)));
-            out.attribute(null, "min_height", Integer.toHexString(widget.options.getInt(
-                    AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)));
-            out.attribute(null, "max_width", Integer.toHexString(widget.options.getInt(
-                    AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)));
-            out.attribute(null, "max_height", Integer.toHexString(widget.options.getInt(
-                    AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT)));
+            int minWidth = widget.options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
+            int minHeight = widget.options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
+            int maxWidth = widget.options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH);
+            int maxHeight = widget.options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT);
+            out.attribute(null, "min_width", Integer.toHexString((minWidth > 0) ? minWidth : 0));
+            out.attribute(null, "min_height", Integer.toHexString((minHeight > 0) ? minHeight : 0));
+            out.attribute(null, "max_width", Integer.toHexString((maxWidth > 0) ? maxWidth : 0));
+            out.attribute(null, "max_height", Integer.toHexString((maxHeight > 0) ? maxHeight : 0));
             out.attribute(null, "host_category", Integer.toHexString(widget.options.getInt(
                     AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY)));
         }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index cb91f93..e37347a 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -499,6 +499,16 @@
         }
 
         @Override
+        public void removeClient(IAutoFillManagerClient client, int userId) {
+            synchronized (mLock) {
+                final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
+                if (service != null) {
+                    service.removeClientLocked(client);
+                }
+            }
+        }
+
+        @Override
         public void setAuthenticationResult(Bundle data, int sessionId, int authenticationId,
                 int userId) {
             synchronized (mLock) {
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 751c054..5c63b90 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -261,6 +261,12 @@
         return isEnabled();
     }
 
+    void removeClientLocked(IAutoFillManagerClient client) {
+        if (mClients != null) {
+            mClients.unregister(client);
+        }
+    }
+
     void setAuthenticationResultLocked(Bundle data, int sessionId, int authenticationId, int uid) {
         if (!isEnabled()) {
             return;
@@ -478,6 +484,10 @@
         }
 
         sendStateToClients(true);
+        if (mClients != null) {
+            mClients.kill();
+            mClients = null;
+        }
     }
 
     CharSequence getServiceLabel() {
@@ -605,6 +615,9 @@
             }
         }
 
+        pw.print(prefix); pw.println("Clients");
+        mClients.dump(pw, prefix2);
+
         if (mEventHistory == null || mEventHistory.getEvents() == null
                 || mEventHistory.getEvents().size() == 0) {
             pw.print(prefix); pw.println("No event on last fill response");
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 72ad752..6bc9c9c 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -217,7 +217,12 @@
                     fillContextWithAllowedValues(mContexts.get(i), flags);
                 }
 
-                request = new FillRequest(requestId, mContexts, mClientState, flags);
+                // Dispatch a snapshot of the current contexts list since it may change
+                // until the dispatch happens. The items in the list don't need to be cloned
+                // since we don't hold on them anywhere else. The client state is not touched
+                // by us, so no need to copy.
+                request = new FillRequest(requestId, new ArrayList<>(mContexts),
+                        mClientState, flags);
             }
 
             mRemoteFillService.onFillRequest(request);
@@ -932,7 +937,11 @@
         // Remove pending fill requests as the session is finished.
         cancelCurrentRequestLocked();
 
-        final SaveRequest saveRequest = new SaveRequest(mContexts, mClientState);
+        // Dispatch a snapshot of the current contexts list since it may change
+        // until the dispatch happens. The items in the list don't need to be cloned
+        // since we don't hold on them anywhere else. The client state is not touched
+        // by us, so no need to copy.
+        final SaveRequest saveRequest = new SaveRequest(new ArrayList<>(mContexts), mClientState);
         mRemoteFillService.onSaveRequest(saveRequest);
     }
 
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 30de4ba..1bb147c 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -123,8 +123,8 @@
 import com.android.server.SystemConfig;
 import com.android.server.SystemService;
 import com.android.server.backup.PackageManagerBackupAgent.Metadata;
-
 import com.android.server.power.BatterySaverPolicy.ServiceType;
+
 import libcore.io.IoUtils;
 
 import java.io.BufferedInputStream;
@@ -189,7 +189,7 @@
 import javax.crypto.spec.PBEKeySpec;
 import javax.crypto.spec.SecretKeySpec;
 
-public class BackupManagerService {
+public class BackupManagerService implements BackupManagerServiceInterface {
 
     private static final String TAG = "BackupManagerService";
     static final boolean DEBUG = true;
@@ -306,6 +306,7 @@
     private PowerManager mPowerManager;
     private AlarmManager mAlarmManager;
     private IStorageManager mStorageManager;
+
     IBackupManager mBackupManagerBinder;
 
     private final TransportManager mTransportManager;
@@ -690,6 +691,7 @@
     final SparseArray<Operation> mCurrentOperations = new SparseArray<Operation>();
     final Object mCurrentOpLock = new Object();
     final Random mTokenGenerator = new Random();
+    final AtomicInteger mNextToken = new AtomicInteger();
 
     final SparseArray<AdbParams> mAdbBackupRestoreConfirmations = new SparseArray<AdbParams>();
 
@@ -762,14 +764,15 @@
     @GuardedBy("mQueueLock")
     ArrayList<FullBackupEntry> mFullBackupQueue;
 
-    // Utility: build a new random integer token
-    int generateToken() {
-        int token;
-        do {
-            synchronized (mTokenGenerator) {
-                token = mTokenGenerator.nextInt();
-            }
-        } while (token < 0);
+    // Utility: build a new random integer token.  The low bits are the ordinal of the
+    // operation for near-time uniqueness, and the upper bits are random for app-
+    // side unpredictability.
+    @Override
+    public int generateRandomIntegerToken() {
+        int token = mTokenGenerator.nextInt();
+        if (token < 0) token = -token;
+        token &= ~0xFF;
+        token |= (mNextToken.incrementAndGet() & 0xFF);
         return token;
     }
 
@@ -837,6 +840,29 @@
         return !appGetsFullBackup(pkg);
     }
 
+    /*
+     * Construct a backup agent instance for the metadata pseudopackage.  This is a
+     * process-local non-lifecycle agent instance, so we manually set up the context
+     * topology for it.
+     */
+    PackageManagerBackupAgent makeMetadataAgent() {
+        PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(mPackageManager);
+        pmAgent.attach(mContext);
+        pmAgent.onCreate();
+        return pmAgent;
+    }
+
+    /*
+     * Same as above but with the explicit package-set configuration.
+     */
+    PackageManagerBackupAgent makeMetadataAgent(List<PackageInfo> packages) {
+        PackageManagerBackupAgent pmAgent =
+                new PackageManagerBackupAgent(mPackageManager, packages);
+        pmAgent.attach(mContext);
+        pmAgent.onCreate();
+        return pmAgent;
+    }
+
     // ----- Asynchronous backup/restore handler thread -----
 
     private class BackupHandler extends Handler {
@@ -1752,6 +1778,7 @@
         return false;
     }
 
+    @Override
     public boolean setBackupPassword(String currentPw, String newPw) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "setBackupPassword");
@@ -1832,6 +1859,7 @@
         return false;
     }
 
+    @Override
     public boolean hasBackupPassword() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "hasBackupPassword");
@@ -2297,7 +2325,8 @@
     }
 
     // fire off a backup agent, blocking until it attaches or times out
-    IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode) {
+    @Override
+    public IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode) {
         IBackupAgent agent = null;
         synchronized(mAgentConnectLock) {
             mConnecting = true;
@@ -2393,6 +2422,7 @@
 
     // Get the restore-set token for the best-available restore set for this package:
     // the active set if possible, else the ancestral one.  Returns zero if none available.
+    @Override
     public long getAvailableRestoreToken(String packageName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getAvailableRestoreToken");
@@ -2410,10 +2440,12 @@
         return token;
     }
 
+    @Override
     public int requestBackup(String[] packages, IBackupObserver observer, int flags) {
         return requestBackup(packages, observer, null, flags);
     }
 
+    @Override
     public int requestBackup(String[] packages, IBackupObserver observer,
             IBackupManagerMonitor monitor, int flags) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "requestBackup");
@@ -2485,6 +2517,7 @@
     }
 
     // Cancel all running backups.
+    @Override
     public void cancelBackups(){
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "cancelBackups");
         if (MORE_DEBUG) {
@@ -2514,22 +2547,9 @@
         }
     }
 
-    // -----
-    // Interface and methods used by the asynchronous-with-timeout backup/restore operations
-
-    interface BackupRestoreTask {
-        // Execute one tick of whatever state machine the task implements
-        void execute();
-
-        // An operation that wanted a callback has completed
-        void operationComplete(long result);
-
-        // An operation that wanted a callback has timed out
-        void handleCancel(boolean cancelAll);
-    }
-
-    void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
-            int operationType) {
+    @Override
+    public void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
+        int operationType) {
         if (operationType != OP_TYPE_BACKUP_WAIT && operationType != OP_TYPE_RESTORE_WAIT) {
             Slog.wtf(TAG, "prepareOperationTimeout() doesn't support operation " +
                     Integer.toHexString(token) + " of type " + operationType);
@@ -2573,7 +2593,8 @@
     }
 
     // synchronous waiter case
-    boolean waitUntilOperationComplete(int token) {
+    @Override
+    public boolean waitUntilOperationComplete(int token) {
         if (MORE_DEBUG) Slog.i(TAG, "Blocking until operation complete for "
                 + Integer.toHexString(token));
         int finalState = OP_PENDING;
@@ -2739,7 +2760,7 @@
             mNonIncremental = nonIncremental;
 
             mStateDir = new File(mBaseStateDir, dirName);
-            mCurrentOpToken = generateToken();
+            mCurrentOpToken = generateRandomIntegerToken();
 
             mFinished = false;
 
@@ -2802,11 +2823,11 @@
                         break;
 
                     case FINAL:
-                        if (!mFinished) finalizeBackup();
-                        else {
-                            Slog.e(TAG, "Duplicate finish");
+                        if (!mFinished) {
+                            finalizeBackup();
+                        } else {
+                            Slog.e(TAG, "Duplicate finish of K/V pass");
                         }
-                        mFinished = true;
                         break;
                 }
             }
@@ -2896,8 +2917,7 @@
                     // because it's cheap and this way we guarantee that we don't get out of
                     // step even if we're selecting among various transports at run time.
                     if (mStatus == BackupTransport.TRANSPORT_OK) {
-                        PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(
-                                mPackageManager);
+                        PackageManagerBackupAgent pmAgent = makeMetadataAgent();
                         mStatus = invokeAgentForBackup(PACKAGE_MANAGER_SENTINEL,
                                 IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport);
                         addBackupTrace("PMBA invoke: " + mStatus);
@@ -3161,6 +3181,7 @@
                         break;
                 }
             }
+            mFinished = true;
             Slog.i(BackupManagerService.TAG, "K/V backup pass finished.");
             // Only once we're entirely finished do we release the wakelock for k/v backup.
             mWakelock.release();
@@ -3190,7 +3211,7 @@
             mNewState = null;
 
             boolean callingAgent = false;
-            mEphemeralOpToken = generateToken();
+            mEphemeralOpToken = generateRandomIntegerToken();
             try {
                 // Look up the package info & signatures.  This is first so that if it
                 // throws an exception, there's no file setup yet that would need to
@@ -3687,7 +3708,7 @@
             ParcelFileDescriptor[] pipes = null;
             try {
                 pipes = ParcelFileDescriptor.createPipe();
-                int token = generateToken();
+                int token = generateRandomIntegerToken();
                 prepareOperationTimeout(token, TIMEOUT_FULL_BACKUP_INTERVAL,
                         null, OP_TYPE_BACKUP_WAIT);
                 mService.backupObbs(pkg.packageName, pipes[1], token, mBackupManagerBinder);
@@ -3773,7 +3794,8 @@
         }
     }
 
-    void tearDownAgentAndKill(ApplicationInfo app) {
+    @Override
+    public void tearDownAgentAndKill(ApplicationInfo app) {
         if (app == null) {
             // Null means the system package, so just quietly move on.  :)
             return;
@@ -4225,7 +4247,7 @@
                 String curPassword, String encryptPassword, boolean doAllApps, boolean doSystem,
                 boolean doCompress, boolean doKeyValue, String[] packages, AtomicBoolean latch) {
             super(observer);
-            mCurrentOpToken = generateToken();
+            mCurrentOpToken = generateRandomIntegerToken();
             mLatch = latch;
 
             mOutputFile = fd;
@@ -4675,8 +4697,8 @@
             mBackupObserver = backupObserver;
             mMonitor = monitor;
             mUserInitiated = userInitiated;
-            mCurrentOpToken = generateToken();
-            mBackupRunnerOpToken = generateToken();
+            mCurrentOpToken = generateRandomIntegerToken();
+            mBackupRunnerOpToken = generateRandomIntegerToken();
 
             if (isBackupOperationInProgress()) {
                 if (DEBUG) {
@@ -4850,6 +4872,7 @@
                 final int N = mPackages.size();
                 final byte[] buffer = new byte[8192];
                 for (int i = 0; i < N; i++) {
+                    mBackupRunner = null;
                     PackageInfo currentPackage = mPackages.get(i);
                     String packageName = currentPackage.packageName;
                     if (DEBUG) {
@@ -5033,7 +5056,13 @@
                         }
                         EventLog.writeEvent(EventLogTags.FULL_BACKUP_AGENT_FAILURE, packageName,
                                 "transport rejected");
-                        // Do nothing, clean up, and continue looping.
+                        // This failure state can come either a-priori from the transport, or
+                        // from the preflight pass.  If we got as far as preflight, we now need
+                        // to tear down the target process.
+                        if (mBackupRunner != null) {
+                            tearDownAgentAndKill(currentPackage.applicationInfo);
+                        }
+                        // ... and continue looping.
                     } else if (backupPackageStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
                         sendBackupOnPackageResult(mBackupObserver, packageName,
                                 BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
@@ -5042,6 +5071,7 @@
                             EventLog.writeEvent(EventLogTags.FULL_BACKUP_QUOTA_EXCEEDED,
                                     packageName);
                         }
+                        tearDownAgentAndKill(currentPackage.applicationInfo);
                         // Do nothing, clean up, and continue looping.
                     } else if (backupPackageStatus == BackupTransport.AGENT_ERROR) {
                         sendBackupOnPackageResult(mBackupObserver, packageName,
@@ -5065,6 +5095,7 @@
                         EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
                         // Abort entire backup pass.
                         backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
+                        tearDownAgentAndKill(currentPackage.applicationInfo);
                         return;
                     } else {
                         // Success!
@@ -5269,7 +5300,7 @@
                 mOutput = ParcelFileDescriptor.dup(output.getFileDescriptor());
                 mTarget = target;
                 mCurrentOpToken = currentOpToken;
-                mEphemeralToken = generateToken();
+                mEphemeralToken = generateRandomIntegerToken();
                 mPreflight = new SinglePackageBackupPreflight(transport, quota, mEphemeralToken);
                 mPreflightLatch = new CountDownLatch(1);
                 mBackupLatch = new CountDownLatch(1);
@@ -5499,7 +5530,8 @@
      * @return Whether ongoing work will continue.  The return value here will be passed
      *         along as the return value to the scheduled job's onStartJob() callback.
      */
-    boolean beginFullBackup(FullBackupJob scheduledJob) {
+    @Override
+    public boolean beginFullBackup(FullBackupJob scheduledJob) {
         long now = System.currentTimeMillis();
         FullBackupEntry entry = null;
         long latency = MIN_FULL_BACKUP_INTERVAL;
@@ -5657,7 +5689,8 @@
 
     // The job scheduler says our constraints don't hold any more,
     // so tear down any ongoing backup task right away.
-    void endFullBackup() {
+    @Override
+    public void endFullBackup() {
         // offload the mRunningFullBackupTask.handleCancel() call to another thread,
         // as we might have to wait for mCancelLock
         Runnable endFullBackupRunnable = new Runnable() {
@@ -5666,13 +5699,15 @@
                 PerformFullTransportBackupTask pftbt = null;
                 synchronized (mQueueLock) {
                     if (mRunningFullBackupTask != null) {
-                        if (DEBUG_SCHEDULING) {
-                            Slog.i(TAG, "Telling running backup to stop");
-                        }
                         pftbt = mRunningFullBackupTask;
                     }
                 }
-                pftbt.handleCancel(true);
+                if (pftbt != null) {
+                    if (DEBUG_SCHEDULING) {
+                        Slog.i(TAG, "Telling running backup to stop");
+                    }
+                    pftbt.handleCancel(true);
+                }
             }
         };
         new Thread(endFullBackupRunnable, "end-full-backup").start();
@@ -5725,30 +5760,6 @@
 
     // ----- Full restore from a file/socket -----
 
-    // Description of a file in the restore datastream
-    static class FileMetadata {
-        String packageName;             // name of the owning app
-        String installerPackageName;    // name of the market-type app that installed the owner
-        int type;                       // e.g. BackupAgent.TYPE_DIRECTORY
-        String domain;                  // e.g. FullBackup.DATABASE_TREE_TOKEN
-        String path;                    // subpath within the semantic domain
-        long mode;                      // e.g. 0666 (actually int)
-        long mtime;                     // last mod time, UTC time_t (actually int)
-        long size;                      // bytes of content
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder(128);
-            sb.append("FileMetadata{");
-            sb.append(packageName); sb.append(',');
-            sb.append(type); sb.append(',');
-            sb.append(domain); sb.append(':'); sb.append(path); sb.append(',');
-            sb.append(size);
-            sb.append('}');
-            return sb.toString();
-        }
-    }
-
     enum RestorePolicy {
         IGNORE,
         ACCEPT,
@@ -7179,7 +7190,7 @@
             mObserver = observer;
             mLatchObject = latch;
             mAgent = null;
-            mPackageManagerBackupAgent = new PackageManagerBackupAgent(mPackageManager);
+            mPackageManagerBackupAgent = makeMetadataAgent();
             mAgentPackage = null;
             mTargetApp = null;
             mObbConnection = new FullBackupObbConnection();
@@ -7598,7 +7609,7 @@
                             final boolean isSharedStorage = pkg.equals(SHARED_BACKUP_AGENT_PACKAGE);
                             final long timeout = isSharedStorage ?
                                     TIMEOUT_SHARED_BACKUP_INTERVAL : TIMEOUT_RESTORE_INTERVAL;
-                            final int token = generateToken();
+                            final int token = generateRandomIntegerToken();
                             try {
                                 prepareOperationTimeout(token, timeout, null,
                                         OP_TYPE_RESTORE_WAIT);
@@ -7742,7 +7753,7 @@
                 try {
                     // In the adb restore case, we do restore-finished here
                     if (doRestoreFinished) {
-                        final int token = generateToken();
+                        final int token = generateRandomIntegerToken();
                         final AdbRestoreFinishedLatch latch = new AdbRestoreFinishedLatch(token);
                         prepareOperationTimeout(token, TIMEOUT_FULL_BACKUP_INTERVAL, latch,
                                 OP_TYPE_RESTORE_WAIT);
@@ -8621,7 +8632,7 @@
         PerformUnifiedRestoreTask(IBackupTransport transport, IRestoreObserver observer,
                 IBackupManagerMonitor monitor, long restoreSetToken, PackageInfo targetPackage,
                 int pmToken, boolean isFullSystemRestore, String[] filterSet) {
-            mEphemeralOpToken = generateToken();
+            mEphemeralOpToken = generateRandomIntegerToken();
             mState = UnifiedRestoreState.INITIAL;
             mStartRealtime = SystemClock.elapsedRealtime();
 
@@ -8841,7 +8852,7 @@
                 // Pull the Package Manager metadata from the restore set first
                 mCurrentPackage = new PackageInfo();
                 mCurrentPackage.packageName = PACKAGE_MANAGER_SENTINEL;
-                mPmAgent = new PackageManagerBackupAgent(mPackageManager, null);
+                mPmAgent = makeMetadataAgent(null);
                 mAgent = IBackupAgent.Stub.asInterface(mPmAgent.onBind());
                 if (MORE_DEBUG) {
                     Slog.v(TAG, "initiating restore for PMBA");
@@ -9254,7 +9265,7 @@
             private final int mEphemeralOpToken;
 
             public StreamFeederThread() throws IOException {
-                mEphemeralOpToken = generateToken();
+                mEphemeralOpToken = generateRandomIntegerToken();
                 mTransportPipes = ParcelFileDescriptor.createPipe();
                 mEnginePipes = ParcelFileDescriptor.createPipe();
                 setRunning(true);
@@ -9909,6 +9920,7 @@
 
     // ----- IBackupManager binder interface -----
 
+    @Override
     public void dataChanged(final String packageName) {
         final int callingUserHandle = UserHandle.getCallingUserId();
         if (callingUserHandle != UserHandle.USER_SYSTEM) {
@@ -9939,6 +9951,7 @@
     }
 
     // Clear the given package's backup data from the current transport
+    @Override
     public void clearBackupData(String transportName, String packageName) {
         if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName + " on " + transportName);
         PackageInfo info;
@@ -9996,6 +10009,7 @@
 
     // Run a backup pass immediately for any applications that have declared
     // that they have pending updates.
+    @Override
     public void backupNow() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "backupNow");
 
@@ -10032,6 +10046,7 @@
     //
     // This is the variant used by 'adb backup'; it requires on-screen confirmation
     // by the user because it can be used to offload data over untrusted USB.
+    @Override
     public void adbBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs,
             boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem,
             boolean compress, boolean doKeyValue, String[] pkgList) {
@@ -10072,7 +10087,7 @@
             AdbBackupParams params = new AdbBackupParams(fd, includeApks, includeObbs,
                     includeShared, doWidgets, doAllApps, includeSystem, compress, doKeyValue,
                     pkgList);
-            final int token = generateToken();
+            final int token = generateRandomIntegerToken();
             synchronized (mAdbBackupRestoreConfirmations) {
                 mAdbBackupRestoreConfirmations.put(token, params);
             }
@@ -10107,6 +10122,7 @@
         }
     }
 
+    @Override
     public void fullTransportBackup(String[] pkgNames) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP,
                 "fullTransportBackup");
@@ -10156,6 +10172,7 @@
         }
     }
 
+    @Override
     public void adbRestore(ParcelFileDescriptor fd) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "adbRestore");
 
@@ -10178,7 +10195,7 @@
             Slog.i(TAG, "Beginning restore...");
 
             AdbRestoreParams params = new AdbRestoreParams(fd);
-            final int token = generateToken();
+            final int token = generateRandomIntegerToken();
             synchronized (mAdbBackupRestoreConfirmations) {
                 mAdbBackupRestoreConfirmations.put(token, params);
             }
@@ -10254,6 +10271,7 @@
 
     // Confirm that the previously-requested full backup/restore operation can proceed.  This
     // is used to require a user-facing disclosure about the operation.
+    @Override
     public void acknowledgeAdbBackupOrRestore(int token, boolean allow,
             String curPassword, String encPpassword, IFullBackupRestoreObserver observer) {
         if (DEBUG) Slog.d(TAG, "acknowledgeAdbBackupOrRestore : token=" + token
@@ -10354,6 +10372,7 @@
     }
 
     // Enable/disable backups
+    @Override
     public void setBackupEnabled(boolean enable) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "setBackupEnabled");
@@ -10401,6 +10420,7 @@
     }
 
     // Enable/disable automatic restore of app data at install time
+    @Override
     public void setAutoRestore(boolean doAutoRestore) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "setAutoRestore");
@@ -10420,6 +10440,7 @@
     }
 
     // Mark the backup service as having been provisioned
+    @Override
     public void setBackupProvisioned(boolean available) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "setBackupProvisioned");
@@ -10429,12 +10450,14 @@
     }
 
     // Report whether the backup mechanism is currently enabled
+    @Override
     public boolean isBackupEnabled() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "isBackupEnabled");
         return mEnabled;    // no need to synchronize just to read it
     }
 
     // Report the name of the currently active transport
+    @Override
     public String getCurrentTransport() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getCurrentTransport");
@@ -10444,18 +10467,21 @@
     }
 
     // Report all known, available backup transports
+    @Override
     public String[] listAllTransports() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "listAllTransports");
 
         return mTransportManager.getBoundTransportNames();
     }
 
+    @Override
     public ComponentName[] listAllTransportComponents() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "listAllTransportComponents");
         return mTransportManager.getAllTransportCompenents();
     }
 
+    @Override
     public String[] getTransportWhitelist() {
         // No permission check, intentionally.
         Set<ComponentName> whitelistedComponents = mTransportManager.getTransportWhitelist();
@@ -10469,6 +10495,7 @@
     }
 
     // Select which transport to use for the next backup operation.
+    @Override
     public String selectBackupTransport(String transport) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "selectBackupTransport");
@@ -10485,6 +10512,7 @@
         }
     }
 
+    @Override
     public void selectBackupTransportAsync(final ComponentName transport,
             final ISelectBackupTransportCallback listener) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
@@ -10547,6 +10575,7 @@
     // Supply the configuration Intent for the given transport.  If the name is not one
     // of the available transports, or if the transport does not supply any configuration
     // UI, the method returns null.
+    @Override
     public Intent getConfigurationIntent(String transportName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getConfigurationIntent");
@@ -10572,6 +10601,7 @@
     // summary / destination string, the method can return null.
     //
     // This string is used VERBATIM as the summary text of the relevant Settings item!
+    @Override
     public String getDestinationString(String transportName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getDestinationString");
@@ -10592,6 +10622,7 @@
     }
 
     // Supply the manage-data intent for the given transport.
+    @Override
     public Intent getDataManagementIntent(String transportName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getDataManagementIntent");
@@ -10614,6 +10645,7 @@
 
     // Supply the menu label for affordances that fire the manage-data intent
     // for the given transport.
+    @Override
     public String getDataManagementLabel(String transportName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getDataManagementLabel");
@@ -10635,6 +10667,7 @@
 
     // Callback: a requested backup agent has been instantiated.  This should only
     // be called from the Activity Manager.
+    @Override
     public void agentConnected(String packageName, IBinder agentBinder) {
         synchronized(mAgentConnectLock) {
             if (Binder.getCallingUid() == Process.SYSTEM_UID) {
@@ -10653,6 +10686,7 @@
     // Callback: a backup agent has failed to come up, or has unexpectedly quit.
     // If the agent failed to come up in the first place, the agentBinder argument
     // will be null.  This should only be called from the Activity Manager.
+    @Override
     public void agentDisconnected(String packageName) {
         // TODO: handle backup being interrupted
         synchronized(mAgentConnectLock) {
@@ -10669,6 +10703,7 @@
 
     // An application being installed will need a restore pass, then the Package Manager
     // will need to be told when the restore is finished.
+    @Override
     public void restoreAtInstall(String packageName, int token) {
         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
             Slog.w(TAG, "Non-system process uid=" + Binder.getCallingUid()
@@ -10736,6 +10771,7 @@
     }
 
     // Hand off a restore session
+    @Override
     public IRestoreSession beginRestoreSession(String packageName, String transport) {
         if (DEBUG) Slog.v(TAG, "beginRestoreSession: pkg=" + packageName
                 + " transport=" + transport);
@@ -10799,6 +10835,7 @@
 
     // Note that a currently-active backup agent has notified us that it has
     // completed the given outstanding asynchronous backup/restore operation.
+    @Override
     public void opComplete(int token, long result) {
         if (MORE_DEBUG) {
             Slog.v(TAG, "opComplete: " + Integer.toHexString(token) + " result=" + result);
@@ -10836,6 +10873,7 @@
         }
     }
 
+    @Override
     public boolean isAppEligibleForBackup(String packageName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "isAppEligibleForBackup");
@@ -11200,6 +11238,7 @@
         }
     }
 
+    @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
 
@@ -11425,4 +11464,10 @@
         }
         return null;
     }
+
+    @Override
+    public IBackupManager getBackupManagerBinder() {
+        return mBackupManagerBinder;
+    }
+
 }
diff --git a/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java b/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
new file mode 100644
index 0000000..e4154943
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup;
+
+import android.app.IBackupAgent;
+import android.app.backup.IBackupManager;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
+import android.app.backup.IFullBackupRestoreObserver;
+import android.app.backup.IRestoreSession;
+import android.app.backup.ISelectBackupTransportCallback;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Interface for BackupManagerService.
+ *
+ * Current and future implementations of BackupManagerService should use this interface, so that
+ * Trampoline is able to switch between them.
+ */
+public interface BackupManagerServiceInterface {
+
+  // Utility: build a new random integer token
+  int generateRandomIntegerToken();
+
+  boolean setBackupPassword(String currentPw, String newPw);
+
+  boolean hasBackupPassword();
+
+  // fire off a backup agent, blocking until it attaches or times out
+  IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode);
+
+  // Get the restore-set token for the best-available restore set for this package:
+  // the active set if possible, else the ancestral one.  Returns zero if none available.
+  long getAvailableRestoreToken(String packageName);
+
+  int requestBackup(String[] packages, IBackupObserver observer, int flags);
+
+  int requestBackup(String[] packages, IBackupObserver observer,
+      IBackupManagerMonitor monitor, int flags);
+
+  // Cancel all running backups.
+  void cancelBackups();
+
+  void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
+      int operationType);
+
+  // synchronous waiter case
+  boolean waitUntilOperationComplete(int token);
+
+  void tearDownAgentAndKill(ApplicationInfo app);
+
+  boolean beginFullBackup(FullBackupJob scheduledJob);
+
+  // The job scheduler says our constraints don't hold any more,
+  // so tear down any ongoing backup task right away.
+  void endFullBackup();
+
+  void dataChanged(String packageName);
+
+  // Clear the given package's backup data from the current transport
+  void clearBackupData(String transportName, String packageName);
+
+  // Run a backup pass immediately for any applications that have declared
+  // that they have pending updates.
+  void backupNow();
+
+  // Run a backup pass for the given packages, writing the resulting data stream
+  // to the supplied file descriptor.  This method is synchronous and does not return
+  // to the caller until the backup has been completed.
+  //
+  // This is the variant used by 'adb backup'; it requires on-screen confirmation
+  // by the user because it can be used to offload data over untrusted USB.
+  void adbBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs,
+      boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem,
+      boolean compress, boolean doKeyValue, String[] pkgList);
+
+  void fullTransportBackup(String[] pkgNames);
+
+  void adbRestore(ParcelFileDescriptor fd);
+
+  // Confirm that the previously-requested full backup/restore operation can proceed.  This
+  // is used to require a user-facing disclosure about the operation.
+  void acknowledgeAdbBackupOrRestore(int token, boolean allow,
+      String curPassword, String encPpassword, IFullBackupRestoreObserver observer);
+
+  // Enable/disable backups
+  void setBackupEnabled(boolean enable);
+
+  // Enable/disable automatic restore of app data at install time
+  void setAutoRestore(boolean doAutoRestore);
+
+  // Mark the backup service as having been provisioned
+  void setBackupProvisioned(boolean available);
+
+  // Report whether the backup mechanism is currently enabled
+  boolean isBackupEnabled();
+
+  // Report the name of the currently active transport
+  String getCurrentTransport();
+
+  // Report all known, available backup transports
+  String[] listAllTransports();
+
+  ComponentName[] listAllTransportComponents();
+
+  String[] getTransportWhitelist();
+
+  // Select which transport to use for the next backup operation.
+  String selectBackupTransport(String transport);
+
+  void selectBackupTransportAsync(ComponentName transport,
+      ISelectBackupTransportCallback listener);
+
+  // Supply the configuration Intent for the given transport.  If the name is not one
+  // of the available transports, or if the transport does not supply any configuration
+  // UI, the method returns null.
+  Intent getConfigurationIntent(String transportName);
+
+  // Supply the configuration summary string for the given transport.  If the name is
+  // not one of the available transports, or if the transport does not supply any
+  // summary / destination string, the method can return null.
+  //
+  // This string is used VERBATIM as the summary text of the relevant Settings item!
+  String getDestinationString(String transportName);
+
+  // Supply the manage-data intent for the given transport.
+  Intent getDataManagementIntent(String transportName);
+
+  // Supply the menu label for affordances that fire the manage-data intent
+  // for the given transport.
+  String getDataManagementLabel(String transportName);
+
+  // Callback: a requested backup agent has been instantiated.  This should only
+  // be called from the Activity Manager.
+  void agentConnected(String packageName, IBinder agentBinder);
+
+  // Callback: a backup agent has failed to come up, or has unexpectedly quit.
+  // If the agent failed to come up in the first place, the agentBinder argument
+  // will be null.  This should only be called from the Activity Manager.
+  void agentDisconnected(String packageName);
+
+  // An application being installed will need a restore pass, then the Package Manager
+  // will need to be told when the restore is finished.
+  void restoreAtInstall(String packageName, int token);
+
+  // Hand off a restore session
+  IRestoreSession beginRestoreSession(String packageName, String transport);
+
+  // Note that a currently-active backup agent has notified us that it has
+  // completed the given outstanding asynchronous backup/restore operation.
+  void opComplete(int token, long result);
+
+  boolean isAppEligibleForBackup(String packageName);
+
+  void dump(FileDescriptor fd, PrintWriter pw, String[] args);
+
+  IBackupManager getBackupManagerBinder();
+}
diff --git a/services/backup/java/com/android/server/backup/BackupRestoreTask.java b/services/backup/java/com/android/server/backup/BackupRestoreTask.java
new file mode 100644
index 0000000..acaab0c
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/BackupRestoreTask.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup;
+
+/**
+ * Interface and methods used by the asynchronous-with-timeout backup/restore operations.
+ */
+public interface BackupRestoreTask {
+
+    // Execute one tick of whatever state machine the task implements
+    void execute();
+
+    // An operation that wanted a callback has completed
+    void operationComplete(long result);
+
+    // An operation that wanted a callback has timed out
+    void handleCancel(boolean cancelAll);
+}
diff --git a/services/backup/java/com/android/server/backup/FileMetadata.java b/services/backup/java/com/android/server/backup/FileMetadata.java
new file mode 100644
index 0000000..5465609
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/FileMetadata.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup;
+
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.backup.BackupAgent;
+import android.util.Slog;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Description of a file in the restore datastream.
+ */
+public class FileMetadata {
+    public String packageName;             // name of the owning app
+    public String installerPackageName;    // name of the market-type app that installed the owner
+    public int type;                       // e.g. BackupAgent.TYPE_DIRECTORY
+    public String domain;                  // e.g. FullBackup.DATABASE_TREE_TOKEN
+    public String path;                    // subpath within the semantic domain
+    public long mode;                      // e.g. 0666 (actually int)
+    public long mtime;                     // last mod time, UTC time_t (actually int)
+    public long size;                      // bytes of content
+    public int version;                    // App version.
+    public boolean hasApk;                 // Whether backup file contains apk.
+
+    @Override
+    public String toString() {
+        // TODO: Clean this up.
+        StringBuilder sb = new StringBuilder(128);
+        sb.append("FileMetadata{");
+        sb.append(packageName);
+        sb.append(',');
+        sb.append(type);
+        sb.append(',');
+        sb.append(domain);
+        sb.append(':');
+        sb.append(path);
+        sb.append(',');
+        sb.append(size);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    public void dump() {
+        StringBuilder b = new StringBuilder(128);
+
+        // mode string
+        b.append((type == BackupAgent.TYPE_DIRECTORY) ? 'd' : '-');
+        b.append(((mode & 0400) != 0) ? 'r' : '-');
+        b.append(((mode & 0200) != 0) ? 'w' : '-');
+        b.append(((mode & 0100) != 0) ? 'x' : '-');
+        b.append(((mode & 0040) != 0) ? 'r' : '-');
+        b.append(((mode & 0020) != 0) ? 'w' : '-');
+        b.append(((mode & 0010) != 0) ? 'x' : '-');
+        b.append(((mode & 0004) != 0) ? 'r' : '-');
+        b.append(((mode & 0002) != 0) ? 'w' : '-');
+        b.append(((mode & 0001) != 0) ? 'x' : '-');
+        b.append(String.format(" %9d ", size));
+
+        Date stamp = new Date(mtime);
+        b.append(new SimpleDateFormat("MMM dd HH:mm:ss ").format(stamp));
+
+        b.append(packageName);
+        b.append(" :: ");
+        b.append(domain);
+        b.append(" :: ");
+        b.append(path);
+
+        Slog.i(TAG, b.toString());
+    }
+
+}
diff --git a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
index cd13760..279c828 100644
--- a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
@@ -35,7 +35,7 @@
  * TODO: We should create unified backup/restore engines that can be used for both transport and
  * adb backup/restore, and for fullbackup and key-value backup.
  */
-class KeyValueAdbBackupEngine {
+public class KeyValueAdbBackupEngine {
     private static final String TAG = "KeyValueAdbBackupEngine";
     private static final boolean DEBUG = false;
 
@@ -44,7 +44,7 @@
     private static final String BACKUP_KEY_VALUE_BACKUP_DATA_FILENAME_SUFFIX = ".data";
     private static final String BACKUP_KEY_VALUE_NEW_STATE_FILENAME_SUFFIX = ".new";
 
-    private BackupManagerService mBackupManagerService;
+    private BackupManagerServiceInterface mBackupManagerService;
     private final PackageManager mPackageManager;
     private final OutputStream mOutput;
     private final PackageInfo mCurrentPackage;
@@ -58,8 +58,8 @@
     private ParcelFileDescriptor mBackupData;
     private ParcelFileDescriptor mNewState;
 
-    KeyValueAdbBackupEngine(OutputStream output, PackageInfo packageInfo,
-            BackupManagerService backupManagerService, PackageManager packageManager,
+    public KeyValueAdbBackupEngine(OutputStream output, PackageInfo packageInfo,
+            BackupManagerServiceInterface backupManagerService, PackageManager packageManager,
             File baseStateDir, File dataDir) {
         mOutput = output;
         mCurrentPackage = packageInfo;
@@ -81,7 +81,7 @@
         mManifestFile = new File(mDataDir, BackupManagerService.BACKUP_MANIFEST_FILENAME);
     }
 
-    void backupOnePackage() throws IOException {
+    public void backupOnePackage() throws IOException {
         ApplicationInfo targetApp = mCurrentPackage.applicationInfo;
 
         try {
@@ -145,14 +145,14 @@
 
     // Return true on backup success, false otherwise
     private boolean invokeAgentForAdbBackup(String packageName, IBackupAgent agent) {
-        int token = mBackupManagerService.generateToken();
+        int token = mBackupManagerService.generateRandomIntegerToken();
         try {
             mBackupManagerService.prepareOperationTimeout(token, TIMEOUT_BACKUP_INTERVAL, null,
                     OP_TYPE_BACKUP_WAIT);
 
             // Start backup and wait for BackupManagerService to get callback for success or timeout
             agent.doBackup(mSavedState, mBackupData, mNewState, Long.MAX_VALUE, token,
-                    mBackupManagerService.mBackupManagerBinder);
+                    mBackupManagerService.getBackupManagerBinder());
             if (!mBackupManagerService.waitUntilOperationComplete(token)) {
                 Slog.e(TAG, "Key-value backup failed on package " + packageName);
                 return false;
@@ -214,7 +214,7 @@
                 }
 
                 try {
-                    mBackupManagerService.mBackupManagerBinder.opComplete(mToken, 0);
+                    mBackupManagerService.getBackupManagerBinder().opComplete(mToken, 0);
                 } catch (RemoteException e) {
                     // we'll time out anyway, so we're safe
                 }
@@ -229,7 +229,7 @@
 
     private void writeBackupData() throws IOException {
 
-        int token = mBackupManagerService.generateToken();
+        int token = mBackupManagerService.generateRandomIntegerToken();
 
         ParcelFileDescriptor[] pipes = null;
         try {
diff --git a/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java b/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java
index 6fb9355..b62bb5c 100644
--- a/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java
@@ -13,7 +13,6 @@
 import android.os.RemoteException;
 import android.util.Slog;
 
-import com.android.server.backup.BackupManagerService.FileMetadata;
 import libcore.io.IoUtils;
 
 import java.io.File;
@@ -34,11 +33,11 @@
  * TODO: We should create unified backup/restore engines that can be used for both transport and
  * adb backup/restore, and for fullbackup and key-value backup.
  */
-class KeyValueAdbRestoreEngine implements Runnable {
+public class KeyValueAdbRestoreEngine implements Runnable {
     private static final String TAG = "KeyValueAdbRestoreEngine";
     private static final boolean DEBUG = false;
 
-    private final BackupManagerService mBackupManagerService;
+    private final BackupManagerServiceInterface mBackupManagerService;
     private final File mDataDir;
 
     FileMetadata mInfo;
@@ -47,8 +46,9 @@
     IBackupAgent mAgent;
     int mToken;
 
-    KeyValueAdbRestoreEngine(BackupManagerService backupManagerService, File dataDir,
-            FileMetadata info, ParcelFileDescriptor inFD, IBackupAgent agent, int token) {
+    public KeyValueAdbRestoreEngine(BackupManagerServiceInterface backupManagerService,
+            File dataDir, FileMetadata info, ParcelFileDescriptor inFD, IBackupAgent agent,
+            int token) {
         mBackupManagerService = backupManagerService;
         mDataDir = dataDir;
         mInfo = info;
@@ -96,7 +96,7 @@
                         + versionCode);
             }
             agent.doRestore(backupData, versionCode, newState, mToken,
-                    mBackupManagerService.mBackupManagerBinder);
+                    mBackupManagerService.getBackupManagerBinder());
         } catch (IOException e) {
             Slog.e(TAG, "Exception opening file. " + e);
         } catch (RemoteException e) {
diff --git a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
index 642b8bf..8d91e0d 100644
--- a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
+++ b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
@@ -108,11 +108,11 @@
 
     // We're constructed with the set of applications that are participating
     // in backup.  This set changes as apps are installed & removed.
-    PackageManagerBackupAgent(PackageManager packageMgr, List<PackageInfo> packages) {
+    public PackageManagerBackupAgent(PackageManager packageMgr, List<PackageInfo> packages) {
         init(packageMgr, packages);
     }
 
-    PackageManagerBackupAgent(PackageManager packageMgr) {
+    public PackageManagerBackupAgent(PackageManager packageMgr) {
         init(packageMgr, null);
 
         evaluateStorablePackages();
diff --git a/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java b/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java
new file mode 100644
index 0000000..b57c0bc
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java
@@ -0,0 +1,3652 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup;
+
+import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND;
+
+import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_OPERATION_TIMEOUT;
+import static com.android.server.backup.internal.BackupHandler.MSG_FULL_CONFIRMATION_TIMEOUT;
+import static com.android.server.backup.internal.BackupHandler.MSG_OP_COMPLETE;
+import static com.android.server.backup.internal.BackupHandler.MSG_REQUEST_BACKUP;
+import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
+import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;
+import static com.android.server.backup.internal.BackupHandler.MSG_RETRY_CLEAR;
+import static com.android.server.backup.internal.BackupHandler.MSG_RETRY_INIT;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_ADB_BACKUP;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_ADB_RESTORE;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_BACKUP;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_CLEAR;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_INITIALIZE;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_RESTORE;
+import static com.android.server.backup.internal.BackupHandler.MSG_SCHEDULE_BACKUP_PACKAGE;
+
+import android.app.ActivityManager;
+import android.app.AlarmManager;
+import android.app.AppGlobals;
+import android.app.IActivityManager;
+import android.app.IBackupAgent;
+import android.app.PendingIntent;
+import android.app.backup.BackupManager;
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.FullBackup;
+import android.app.backup.IBackupManager;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
+import android.app.backup.IFullBackupRestoreObserver;
+import android.app.backup.IRestoreSession;
+import android.app.backup.ISelectBackupTransportCallback;
+import android.app.backup.SelectBackupTransportCallback;
+import android.content.ActivityNotFoundException;
+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.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.PowerManager;
+import android.os.PowerSaveState;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.SELinux;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.storage.IStorageManager;
+import android.os.storage.StorageManager;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.AtomicFile;
+import android.util.EventLog;
+import android.util.Pair;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.backup.IBackupTransport;
+import com.android.internal.util.DumpUtils;
+import com.android.server.AppWidgetBackupBridge;
+import com.android.server.EventLogTags;
+import com.android.server.SystemConfig;
+import com.android.server.SystemService;
+import com.android.server.backup.fullbackup.FullBackupEntry;
+import com.android.server.backup.fullbackup.PerformFullTransportBackupTask;
+import com.android.server.backup.internal.BackupHandler;
+import com.android.server.backup.internal.BackupRequest;
+import com.android.server.backup.internal.ClearDataObserver;
+import com.android.server.backup.internal.Operation;
+import com.android.server.backup.internal.ProvisionedObserver;
+import com.android.server.backup.internal.RunBackupReceiver;
+import com.android.server.backup.internal.RunInitializeReceiver;
+import com.android.server.backup.params.AdbBackupParams;
+import com.android.server.backup.params.AdbParams;
+import com.android.server.backup.params.AdbRestoreParams;
+import com.android.server.backup.params.BackupParams;
+import com.android.server.backup.params.ClearParams;
+import com.android.server.backup.params.ClearRetryParams;
+import com.android.server.backup.params.RestoreParams;
+import com.android.server.backup.restore.ActiveRestoreSession;
+import com.android.server.backup.restore.PerformUnifiedRestoreTask;
+import com.android.server.backup.utils.AppBackupUtils;
+import com.android.server.backup.utils.BackupManagerMonitorUtils;
+import com.android.server.backup.utils.BackupObserverUtils;
+import com.android.server.backup.utils.PasswordUtils;
+import com.android.server.power.BatterySaverPolicy.ServiceType;
+
+import libcore.io.IoUtils;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.RandomAccessFile;
+import java.security.SecureRandom;
+import java.text.SimpleDateFormat;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Queue;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+
+public class RefactoredBackupManagerService implements BackupManagerServiceInterface {
+
+    public static final String TAG = "BackupManagerService";
+    public static final boolean DEBUG = true;
+    public static final boolean MORE_DEBUG = false;
+    public static final boolean DEBUG_SCHEDULING = MORE_DEBUG || true;
+
+    // File containing backup-enabled state.  Contains a single byte;
+    // nonzero == enabled.  File missing or contains a zero byte == disabled.
+    private static final String BACKUP_ENABLE_FILE = "backup_enabled";
+
+    // System-private key used for backing up an app's widget state.  Must
+    // begin with U+FFxx by convention (we reserve all keys starting
+    // with U+FF00 or higher for system use).
+    public static final String KEY_WIDGET_STATE = "\uffed\uffedwidget";
+
+    // Historical and current algorithm names
+    public static final String PBKDF_CURRENT = "PBKDF2WithHmacSHA1";
+    public static final String PBKDF_FALLBACK = "PBKDF2WithHmacSHA1And8bit";
+
+    // Name and current contents version of the full-backup manifest file
+    //
+    // Manifest version history:
+    //
+    // 1 : initial release
+    public static final String BACKUP_MANIFEST_FILENAME = "_manifest";
+    public static final int BACKUP_MANIFEST_VERSION = 1;
+
+    // External archive format version history:
+    //
+    // 1 : initial release
+    // 2 : no format change per se; version bump to facilitate PBKDF2 version skew detection
+    // 3 : introduced "_meta" metadata file; no other format change per se
+    // 4 : added support for new device-encrypted storage locations
+    // 5 : added support for key-value packages
+    public static final int BACKUP_FILE_VERSION = 5;
+    public static final String BACKUP_FILE_HEADER_MAGIC = "ANDROID BACKUP\n";
+    private static final int BACKUP_PW_FILE_VERSION = 2;
+    public static final String BACKUP_METADATA_FILENAME = "_meta";
+    public static final int BACKUP_METADATA_VERSION = 1;
+    public static final int BACKUP_WIDGET_METADATA_TOKEN = 0x01FFED01;
+
+    private static final boolean COMPRESS_FULL_BACKUPS = true; // should be true in production
+
+    public static final String SETTINGS_PACKAGE = "com.android.providers.settings";
+    public static final String SHARED_BACKUP_AGENT_PACKAGE = "com.android.sharedstoragebackup";
+    private static final String SERVICE_ACTION_TRANSPORT_HOST = "android.backup.TRANSPORT_HOST";
+
+    // Retry interval for clear/init when the transport is unavailable
+    private static final long TRANSPORT_RETRY_INTERVAL = 1 * AlarmManager.INTERVAL_HOUR;
+
+    public static final String RUN_BACKUP_ACTION = "android.app.backup.intent.RUN";
+    public static final String RUN_INITIALIZE_ACTION = "android.app.backup.intent.INIT";
+
+    // Timeout interval for deciding that a bind or clear-data has taken too long
+    private static final long TIMEOUT_INTERVAL = 10 * 1000;
+
+    // Timeout intervals for agent backup & restore operations
+    public static final long TIMEOUT_BACKUP_INTERVAL = 30 * 1000;
+    public static final long TIMEOUT_FULL_BACKUP_INTERVAL = 5 * 60 * 1000;
+    public static final long TIMEOUT_SHARED_BACKUP_INTERVAL = 30 * 60 * 1000;
+    public static final long TIMEOUT_RESTORE_INTERVAL = 60 * 1000;
+    public static final long TIMEOUT_RESTORE_FINISHED_INTERVAL = 30 * 1000;
+
+    // User confirmation timeout for a full backup/restore operation.  It's this long in
+    // order to give them time to enter the backup password.
+    private static final long TIMEOUT_FULL_CONFIRMATION = 60 * 1000;
+
+    // How long between attempts to perform a full-data backup of any given app
+    private static final long MIN_FULL_BACKUP_INTERVAL = 1000 * 60 * 60 * 24; // one day
+
+    // If an app is busy when we want to do a full-data backup, how long to defer the retry.
+    // This is fuzzed, so there are two parameters; backoff_min + Rand[0, backoff_fuzz)
+    private static final long BUSY_BACKOFF_MIN_MILLIS = 1000 * 60 * 60;  // one hour
+    private static final int BUSY_BACKOFF_FUZZ = 1000 * 60 * 60 * 2;  // two hours
+
+    private Context mContext;
+    private PackageManager mPackageManager;
+    private IPackageManager mPackageManagerBinder;
+    private IActivityManager mActivityManager;
+    private PowerManager mPowerManager;
+    private AlarmManager mAlarmManager;
+    private IStorageManager mStorageManager;
+
+    private IBackupManager mBackupManagerBinder;
+
+    private final TransportManager mTransportManager;
+
+    private boolean mEnabled;   // access to this is synchronized on 'this'
+    private boolean mProvisioned;
+    private boolean mAutoRestore;
+    private PowerManager.WakeLock mWakelock;
+    private HandlerThread mHandlerThread;
+    private BackupHandler mBackupHandler;
+    private PendingIntent mRunBackupIntent;
+    private PendingIntent mRunInitIntent;
+    private BroadcastReceiver mRunBackupReceiver;
+    private BroadcastReceiver mRunInitReceiver;
+    // map UIDs to the set of participating packages under that UID
+    private final SparseArray<HashSet<String>> mBackupParticipants
+            = new SparseArray<>();
+
+    // Backups that we haven't started yet.  Keys are package names.
+    private HashMap<String, BackupRequest> mPendingBackups
+            = new HashMap<>();
+
+    // Pseudoname that we use for the Package Manager metadata "package"
+    public static final String PACKAGE_MANAGER_SENTINEL = "@pm@";
+
+    // locking around the pending-backup management
+    private final Object mQueueLock = new Object();
+
+    // The thread performing the sequence of queued backups binds to each app's agent
+    // in succession.  Bind notifications are asynchronously delivered through the
+    // Activity Manager; use this lock object to signal when a requested binding has
+    // completed.
+    private final Object mAgentConnectLock = new Object();
+    private IBackupAgent mConnectedAgent;
+    private volatile boolean mBackupRunning;
+    private volatile boolean mConnecting;
+    private volatile long mLastBackupPass;
+
+    // For debugging, we maintain a progress trace of operations during backup
+    public static final boolean DEBUG_BACKUP_TRACE = true;
+    private final List<String> mBackupTrace = new ArrayList<>();
+
+    // A similar synchronization mechanism around clearing apps' data for restore
+    private final Object mClearDataLock = new Object();
+    private volatile boolean mClearingData;
+
+    @GuardedBy("mPendingRestores")
+    private boolean mIsRestoreInProgress;
+    @GuardedBy("mPendingRestores")
+    private final Queue<PerformUnifiedRestoreTask> mPendingRestores = new ArrayDeque<>();
+
+    private ActiveRestoreSession mActiveRestoreSession;
+
+    // Watch the device provisioning operation during setup
+    private ContentObserver mProvisionedObserver;
+
+    // The published binder is actually to a singleton trampoline object that calls
+    // through to the proper code.  This indirection lets us turn down the heavy
+    // implementation object on the fly without disturbing binders that have been
+    // cached elsewhere in the system.
+    static Trampoline sInstance;
+
+    static Trampoline getInstance() {
+        // Always constructed during system bringup, so no need to lazy-init
+        return sInstance;
+    }
+
+    public Context getContext() {
+        return mContext;
+    }
+
+    public void setContext(Context context) {
+        mContext = context;
+    }
+
+    public PackageManager getPackageManager() {
+        return mPackageManager;
+    }
+
+    public void setPackageManager(PackageManager packageManager) {
+        mPackageManager = packageManager;
+    }
+
+    public IPackageManager getPackageManagerBinder() {
+        return mPackageManagerBinder;
+    }
+
+    public void setPackageManagerBinder(IPackageManager packageManagerBinder) {
+        mPackageManagerBinder = packageManagerBinder;
+    }
+
+    public IActivityManager getActivityManager() {
+        return mActivityManager;
+    }
+
+    public void setActivityManager(IActivityManager activityManager) {
+        mActivityManager = activityManager;
+    }
+
+    public AlarmManager getAlarmManager() {
+        return mAlarmManager;
+    }
+
+    public void setAlarmManager(AlarmManager alarmManager) {
+        mAlarmManager = alarmManager;
+    }
+
+    public void setBackupManagerBinder(IBackupManager backupManagerBinder) {
+        mBackupManagerBinder = backupManagerBinder;
+    }
+
+    public TransportManager getTransportManager() {
+        return mTransportManager;
+    }
+
+    public boolean isEnabled() {
+        return mEnabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        mEnabled = enabled;
+    }
+
+    public boolean isProvisioned() {
+        return mProvisioned;
+    }
+
+    public void setProvisioned(boolean provisioned) {
+        mProvisioned = provisioned;
+    }
+
+    public PowerManager.WakeLock getWakelock() {
+        return mWakelock;
+    }
+
+    public void setWakelock(PowerManager.WakeLock wakelock) {
+        mWakelock = wakelock;
+    }
+
+    public BackupHandler getBackupHandler() {
+        return mBackupHandler;
+    }
+
+    public void setBackupHandler(BackupHandler backupHandler) {
+        mBackupHandler = backupHandler;
+    }
+
+    public PendingIntent getRunInitIntent() {
+        return mRunInitIntent;
+    }
+
+    public void setRunInitIntent(PendingIntent runInitIntent) {
+        mRunInitIntent = runInitIntent;
+    }
+
+    public HashMap<String, BackupRequest> getPendingBackups() {
+        return mPendingBackups;
+    }
+
+    public void setPendingBackups(
+            HashMap<String, BackupRequest> pendingBackups) {
+        mPendingBackups = pendingBackups;
+    }
+
+    public Object getQueueLock() {
+        return mQueueLock;
+    }
+
+    public boolean isBackupRunning() {
+        return mBackupRunning;
+    }
+
+    public void setBackupRunning(boolean backupRunning) {
+        mBackupRunning = backupRunning;
+    }
+
+    public long getLastBackupPass() {
+        return mLastBackupPass;
+    }
+
+    public void setLastBackupPass(long lastBackupPass) {
+        mLastBackupPass = lastBackupPass;
+    }
+
+    public Object getClearDataLock() {
+        return mClearDataLock;
+    }
+
+    public boolean isClearingData() {
+        return mClearingData;
+    }
+
+    public void setClearingData(boolean clearingData) {
+        mClearingData = clearingData;
+    }
+
+    public boolean isRestoreInProgress() {
+        return mIsRestoreInProgress;
+    }
+
+    public void setRestoreInProgress(boolean restoreInProgress) {
+        mIsRestoreInProgress = restoreInProgress;
+    }
+
+    public Queue<PerformUnifiedRestoreTask> getPendingRestores() {
+        return mPendingRestores;
+    }
+
+    public ActiveRestoreSession getActiveRestoreSession() {
+        return mActiveRestoreSession;
+    }
+
+    public void setActiveRestoreSession(
+            ActiveRestoreSession activeRestoreSession) {
+        mActiveRestoreSession = activeRestoreSession;
+    }
+
+    public SparseArray<Operation> getCurrentOperations() {
+        return mCurrentOperations;
+    }
+
+    public Object getCurrentOpLock() {
+        return mCurrentOpLock;
+    }
+
+    public SparseArray<AdbParams> getAdbBackupRestoreConfirmations() {
+        return mAdbBackupRestoreConfirmations;
+    }
+
+    public File getBaseStateDir() {
+        return mBaseStateDir;
+    }
+
+    public void setBaseStateDir(File baseStateDir) {
+        mBaseStateDir = baseStateDir;
+    }
+
+    public File getDataDir() {
+        return mDataDir;
+    }
+
+    public void setDataDir(File dataDir) {
+        mDataDir = dataDir;
+    }
+
+    public File getJournal() {
+        return mJournal;
+    }
+
+    public void setJournal(File journal) {
+        mJournal = journal;
+    }
+
+    public SecureRandom getRng() {
+        return mRng;
+    }
+
+    public Set<String> getAncestralPackages() {
+        return mAncestralPackages;
+    }
+
+    public void setAncestralPackages(Set<String> ancestralPackages) {
+        mAncestralPackages = ancestralPackages;
+    }
+
+    public long getAncestralToken() {
+        return mAncestralToken;
+    }
+
+    public void setAncestralToken(long ancestralToken) {
+        mAncestralToken = ancestralToken;
+    }
+
+    public long getCurrentToken() {
+        return mCurrentToken;
+    }
+
+    public void setCurrentToken(long currentToken) {
+        mCurrentToken = currentToken;
+    }
+
+    public HashSet<String> getPendingInits() {
+        return mPendingInits;
+    }
+
+    public void setPendingInits(HashSet<String> pendingInits) {
+        mPendingInits = pendingInits;
+    }
+
+    public PerformFullTransportBackupTask getRunningFullBackupTask() {
+        return mRunningFullBackupTask;
+    }
+
+    public void setRunningFullBackupTask(
+            PerformFullTransportBackupTask runningFullBackupTask) {
+        mRunningFullBackupTask = runningFullBackupTask;
+    }
+
+    public static final class Lifecycle extends SystemService {
+
+        public Lifecycle(Context context) {
+            super(context);
+            sInstance = new Trampoline(context);
+        }
+
+        @Override
+        public void onStart() {
+            publishBinderService(Context.BACKUP_SERVICE, sInstance);
+        }
+
+        @Override
+        public void onUnlockUser(int userId) {
+            if (userId == UserHandle.USER_SYSTEM) {
+                sInstance.initialize(userId);
+
+                // Migrate legacy setting
+                if (!backupSettingMigrated(userId)) {
+                    if (DEBUG) {
+                        Slog.i(TAG, "Backup enable apparently not migrated");
+                    }
+                    final ContentResolver r = sInstance.mContext.getContentResolver();
+                    final int enableState = Settings.Secure.getIntForUser(r,
+                            Settings.Secure.BACKUP_ENABLED, -1, userId);
+                    if (enableState >= 0) {
+                        if (DEBUG) {
+                            Slog.i(TAG, "Migrating enable state " + (enableState != 0));
+                        }
+                        writeBackupEnableState(enableState != 0, userId);
+                        Settings.Secure.putStringForUser(r,
+                                Settings.Secure.BACKUP_ENABLED, null, userId);
+                    } else {
+                        if (DEBUG) {
+                            Slog.i(TAG, "Backup not yet configured; retaining null enable state");
+                        }
+                    }
+                }
+
+                try {
+                    sInstance.setBackupEnabled(readBackupEnableState(userId));
+                } catch (RemoteException e) {
+                    // can't happen; it's a local object
+                }
+            }
+        }
+    }
+
+    // Bookkeeping of in-flight operations for timeout etc. purposes.  The operation
+    // token is the index of the entry in the pending-operations list.
+    public static final int OP_PENDING = 0;
+    private static final int OP_ACKNOWLEDGED = 1;
+    private static final int OP_TIMEOUT = -1;
+
+    // Waiting for backup agent to respond during backup operation.
+    public static final int OP_TYPE_BACKUP_WAIT = 0;
+
+    // Waiting for backup agent to respond during restore operation.
+    public static final int OP_TYPE_RESTORE_WAIT = 1;
+
+    // An entire backup operation spanning multiple packages.
+    public static final int OP_TYPE_BACKUP = 2;
+
+    /**
+     * mCurrentOperations contains the list of currently active operations.
+     *
+     * If type of operation is OP_TYPE_WAIT, it are waiting for an ack or timeout.
+     * An operation wraps a BackupRestoreTask within it.
+     * It's the responsibility of this task to remove the operation from this array.
+     *
+     * A BackupRestore task gets notified of ack/timeout for the operation via
+     * BackupRestoreTask#handleCancel, BackupRestoreTask#operationComplete and notifyAll called
+     * on the mCurrentOpLock.
+     * {@link RefactoredBackupManagerService#waitUntilOperationComplete(int)} is
+     * used in various places to 'wait' for notifyAll and detect change of pending state of an
+     * operation. So typically, an operation will be removed from this array by:
+     *   - BackupRestoreTask#handleCancel and
+     *   - BackupRestoreTask#operationComplete OR waitUntilOperationComplete. Do not remove at both
+     *     these places because waitUntilOperationComplete relies on the operation being present to
+     *     determine its completion status.
+     *
+     * If type of operation is OP_BACKUP, it is a task running backups. It provides a handle to
+     * cancel backup tasks.
+     */
+    @GuardedBy("mCurrentOpLock")
+    private final SparseArray<Operation> mCurrentOperations = new SparseArray<>();
+    private final Object mCurrentOpLock = new Object();
+    private final Random mTokenGenerator = new Random();
+
+    private final SparseArray<AdbParams> mAdbBackupRestoreConfirmations = new SparseArray<>();
+
+    // Where we keep our journal files and other bookkeeping
+    private File mBaseStateDir;
+    private File mDataDir;
+    private File mJournalDir;
+    private File mJournal;
+
+    // Backup password, if any, and the file where it's saved.  What is stored is not the
+    // password text itself; it's the result of a PBKDF2 hash with a randomly chosen (but
+    // persisted) salt.  Validation is performed by running the challenge text through the
+    // same PBKDF2 cycle with the persisted salt; if the resulting derived key string matches
+    // the saved hash string, then the challenge text matches the originally supplied
+    // password text.
+    private final SecureRandom mRng = new SecureRandom();
+    private String mPasswordHash;
+    private File mPasswordHashFile;
+    private int mPasswordVersion;
+    private File mPasswordVersionFile;
+    private byte[] mPasswordSalt;
+
+    // Keep a log of all the apps we've ever backed up, and what the
+    // dataset tokens are for both the current backup dataset and
+    // the ancestral dataset.
+    private File mEverStored;
+    private HashSet<String> mEverStoredApps = new HashSet<>();
+
+    private static final int CURRENT_ANCESTRAL_RECORD_VERSION = 1;
+    // increment when the schema changes
+    private File mTokenFile;
+    private Set<String> mAncestralPackages = null;
+    private long mAncestralToken = 0;
+    private long mCurrentToken = 0;
+
+    // Persistently track the need to do a full init
+    private static final String INIT_SENTINEL_FILE_NAME = "_need_init_";
+    private HashSet<String> mPendingInits = new HashSet<>();  // transport names
+
+    // Round-robin queue for scheduling full backup passes
+    private static final int SCHEDULE_FILE_VERSION = 1; // current version of the schedule file
+
+    private File mFullBackupScheduleFile;
+    // If we're running a schedule-driven full backup, this is the task instance doing it
+
+    @GuardedBy("mQueueLock")
+    private PerformFullTransportBackupTask mRunningFullBackupTask;
+
+    @GuardedBy("mQueueLock")
+    private ArrayList<FullBackupEntry> mFullBackupQueue;
+
+    // Utility: build a new random integer token
+    @Override
+    public int generateRandomIntegerToken() {
+        int token;
+        do {
+            synchronized (mTokenGenerator) {
+                token = mTokenGenerator.nextInt();
+            }
+        } while (token < 0);
+        return token;
+    }
+
+    // ----- Debug-only backup operation trace -----
+    public void addBackupTrace(String s) {
+        if (DEBUG_BACKUP_TRACE) {
+            synchronized (mBackupTrace) {
+                mBackupTrace.add(s);
+            }
+        }
+    }
+
+    public void clearBackupTrace() {
+        if (DEBUG_BACKUP_TRACE) {
+            synchronized (mBackupTrace) {
+                mBackupTrace.clear();
+            }
+        }
+    }
+
+    // ----- Main service implementation -----
+
+    public RefactoredBackupManagerService(Context context, Trampoline parent) {
+        mContext = context;
+        mPackageManager = context.getPackageManager();
+        mPackageManagerBinder = AppGlobals.getPackageManager();
+        mActivityManager = ActivityManager.getService();
+
+        mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+        mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        mStorageManager = IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
+
+        mBackupManagerBinder = Trampoline.asInterface(parent.asBinder());
+
+        // spin up the backup/restore handler thread
+        mHandlerThread = new HandlerThread("backup", Process.THREAD_PRIORITY_BACKGROUND);
+        mHandlerThread.start();
+        mBackupHandler = new BackupHandler(this, mHandlerThread.getLooper());
+
+        // Set up our bookkeeping
+        final ContentResolver resolver = context.getContentResolver();
+        mProvisioned = Settings.Global.getInt(resolver,
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+        mAutoRestore = Settings.Secure.getInt(resolver,
+                Settings.Secure.BACKUP_AUTO_RESTORE, 1) != 0;
+
+        mProvisionedObserver = new ProvisionedObserver(this, mBackupHandler);
+        resolver.registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
+                false, mProvisionedObserver);
+
+        // If Encrypted file systems is enabled or disabled, this call will return the
+        // correct directory.
+        mBaseStateDir = new File(Environment.getDataDirectory(), "backup");
+        mBaseStateDir.mkdirs();
+        if (!SELinux.restorecon(mBaseStateDir)) {
+            Slog.e(TAG, "SELinux restorecon failed on " + mBaseStateDir);
+        }
+
+        // This dir on /cache is managed directly in init.rc
+        mDataDir = new File(Environment.getDownloadCacheDirectory(), "backup_stage");
+
+        mPasswordVersion = 1;       // unless we hear otherwise
+        mPasswordVersionFile = new File(mBaseStateDir, "pwversion");
+        if (mPasswordVersionFile.exists()) {
+            FileInputStream fin = null;
+            DataInputStream in = null;
+            try {
+                fin = new FileInputStream(mPasswordVersionFile);
+                in = new DataInputStream(fin);
+                mPasswordVersion = in.readInt();
+            } catch (IOException e) {
+                Slog.e(TAG, "Unable to read backup pw version");
+            } finally {
+                try {
+                    if (in != null) in.close();
+                    if (fin != null) fin.close();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Error closing pw version files");
+                }
+            }
+        }
+
+        mPasswordHashFile = new File(mBaseStateDir, "pwhash");
+        if (mPasswordHashFile.exists()) {
+            FileInputStream fin = null;
+            DataInputStream in = null;
+            try {
+                fin = new FileInputStream(mPasswordHashFile);
+                in = new DataInputStream(new BufferedInputStream(fin));
+                // integer length of the salt array, followed by the salt,
+                // then the hex pw hash string
+                int saltLen = in.readInt();
+                byte[] salt = new byte[saltLen];
+                in.readFully(salt);
+                mPasswordHash = in.readUTF();
+                mPasswordSalt = salt;
+            } catch (IOException e) {
+                Slog.e(TAG, "Unable to read saved backup pw hash");
+            } finally {
+                try {
+                    if (in != null) in.close();
+                    if (fin != null) fin.close();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Unable to close streams");
+                }
+            }
+        }
+
+        // Alarm receivers for scheduled backups & initialization operations
+        mRunBackupReceiver = new RunBackupReceiver(this);
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(RUN_BACKUP_ACTION);
+        context.registerReceiver(mRunBackupReceiver, filter,
+                android.Manifest.permission.BACKUP, null);
+
+        mRunInitReceiver = new RunInitializeReceiver(this);
+        filter = new IntentFilter();
+        filter.addAction(RUN_INITIALIZE_ACTION);
+        context.registerReceiver(mRunInitReceiver, filter,
+                android.Manifest.permission.BACKUP, null);
+
+        Intent backupIntent = new Intent(RUN_BACKUP_ACTION);
+        backupIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+        mRunBackupIntent = PendingIntent.getBroadcast(context, MSG_RUN_BACKUP, backupIntent, 0);
+
+        Intent initIntent = new Intent(RUN_INITIALIZE_ACTION);
+        backupIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+        mRunInitIntent = PendingIntent.getBroadcast(context, MSG_RUN_INITIALIZE, initIntent, 0);
+
+        // Set up the backup-request journaling
+        mJournalDir = new File(mBaseStateDir, "pending");
+        mJournalDir.mkdirs();   // creates mBaseStateDir along the way
+        mJournal = null;        // will be created on first use
+
+        // Set up the various sorts of package tracking we do
+        mFullBackupScheduleFile = new File(mBaseStateDir, "fb-schedule");
+        initPackageTracking();
+
+        // Build our mapping of uid to backup client services.  This implicitly
+        // schedules a backup pass on the Package Manager metadata the first
+        // time anything needs to be backed up.
+        synchronized (mBackupParticipants) {
+            addPackageParticipantsLocked(null);
+        }
+
+        // Set up our transport options and initialize the default transport
+        // TODO: Don't create transports that we don't need to?
+        SystemConfig systemConfig = SystemConfig.getInstance();
+        Set<ComponentName> transportWhitelist = systemConfig.getBackupTransportWhitelist();
+
+        String transport = Settings.Secure.getString(context.getContentResolver(),
+                Settings.Secure.BACKUP_TRANSPORT);
+        if (TextUtils.isEmpty(transport)) {
+            transport = null;
+        }
+        String currentTransport = transport;
+        if (DEBUG) Slog.v(TAG, "Starting with transport " + currentTransport);
+
+        mTransportManager = new TransportManager(context, transportWhitelist, currentTransport,
+                mTransportBoundListener, mHandlerThread.getLooper());
+        mTransportManager.registerAllTransports();
+
+        // Now that we know about valid backup participants, parse any
+        // leftover journal files into the pending backup set
+        mBackupHandler.post(() -> parseLeftoverJournals());
+
+        // Power management
+        mWakelock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*");
+    }
+
+    private void initPackageTracking() {
+        if (MORE_DEBUG) Slog.v(TAG, "` tracking");
+
+        // Remember our ancestral dataset
+        mTokenFile = new File(mBaseStateDir, "ancestral");
+        try {
+            RandomAccessFile tf = new RandomAccessFile(mTokenFile, "r");
+            int version = tf.readInt();
+            if (version == CURRENT_ANCESTRAL_RECORD_VERSION) {
+                mAncestralToken = tf.readLong();
+                mCurrentToken = tf.readLong();
+
+                int numPackages = tf.readInt();
+                if (numPackages >= 0) {
+                    mAncestralPackages = new HashSet<>();
+                    for (int i = 0; i < numPackages; i++) {
+                        String pkgName = tf.readUTF();
+                        mAncestralPackages.add(pkgName);
+                    }
+                }
+            }
+            tf.close();
+        } catch (FileNotFoundException fnf) {
+            // Probably innocuous
+            Slog.v(TAG, "No ancestral data");
+        } catch (IOException e) {
+            Slog.w(TAG, "Unable to read token file", e);
+        }
+
+        // Keep a log of what apps we've ever backed up.  Because we might have
+        // rebooted in the middle of an operation that was removing something from
+        // this log, we sanity-check its contents here and reconstruct it.
+        mEverStored = new File(mBaseStateDir, "processed");
+        File tempProcessedFile = new File(mBaseStateDir, "processed.new");
+
+        // If we were in the middle of removing something from the ever-backed-up
+        // file, there might be a transient "processed.new" file still present.
+        // Ignore it -- we'll validate "processed" against the current package set.
+        if (tempProcessedFile.exists()) {
+            tempProcessedFile.delete();
+        }
+
+        // If there are previous contents, parse them out then start a new
+        // file to continue the recordkeeping.
+        if (mEverStored.exists()) {
+            RandomAccessFile temp = null;
+            RandomAccessFile in = null;
+
+            try {
+                temp = new RandomAccessFile(tempProcessedFile, "rws");
+                in = new RandomAccessFile(mEverStored, "r");
+
+                // Loop until we hit EOF
+                while (true) {
+                    String pkg = in.readUTF();
+                    try {
+                        // is this package still present?
+                        mPackageManager.getPackageInfo(pkg, 0);
+                        // if we get here then yes it is; remember it
+                        mEverStoredApps.add(pkg);
+                        temp.writeUTF(pkg);
+                        if (MORE_DEBUG) Slog.v(TAG, "   + " + pkg);
+                    } catch (NameNotFoundException e) {
+                        // nope, this package was uninstalled; don't include it
+                        if (MORE_DEBUG) Slog.v(TAG, "   - " + pkg);
+                    }
+                }
+            } catch (EOFException e) {
+                // Once we've rewritten the backup history log, atomically replace the
+                // old one with the new one then reopen the file for continuing use.
+                if (!tempProcessedFile.renameTo(mEverStored)) {
+                    Slog.e(TAG, "Error renaming " + tempProcessedFile + " to " + mEverStored);
+                }
+            } catch (IOException e) {
+                Slog.e(TAG, "Error in processed file", e);
+            } finally {
+                try {
+                    if (temp != null) temp.close();
+                } catch (IOException e) {
+                }
+                try {
+                    if (in != null) in.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+
+        synchronized (mQueueLock) {
+            // Resume the full-data backup queue
+            mFullBackupQueue = readFullBackupSchedule();
+        }
+
+        // Register for broadcasts about package install, etc., so we can
+        // update the provider list.
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        filter.addDataScheme("package");
+        mContext.registerReceiver(mBroadcastReceiver, filter);
+        // Register for events related to sdcard installation.
+        IntentFilter sdFilter = new IntentFilter();
+        sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
+        sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
+        mContext.registerReceiver(mBroadcastReceiver, sdFilter);
+    }
+
+    private ArrayList<FullBackupEntry> readFullBackupSchedule() {
+        boolean changed = false;
+        ArrayList<FullBackupEntry> schedule = null;
+        List<PackageInfo> apps =
+                PackageManagerBackupAgent.getStorableApplications(mPackageManager);
+
+        if (mFullBackupScheduleFile.exists()) {
+            FileInputStream fstream = null;
+            BufferedInputStream bufStream = null;
+            DataInputStream in = null;
+            try {
+                fstream = new FileInputStream(mFullBackupScheduleFile);
+                bufStream = new BufferedInputStream(fstream);
+                in = new DataInputStream(bufStream);
+
+                int version = in.readInt();
+                if (version != SCHEDULE_FILE_VERSION) {
+                    Slog.e(TAG, "Unknown backup schedule version " + version);
+                    return null;
+                }
+
+                final int N = in.readInt();
+                schedule = new ArrayList<>(N);
+
+                // HashSet instead of ArraySet specifically because we want the eventual
+                // lookups against O(hundreds) of entries to be as fast as possible, and
+                // we discard the set immediately after the scan so the extra memory
+                // overhead is transient.
+                HashSet<String> foundApps = new HashSet<>(N);
+
+                for (int i = 0; i < N; i++) {
+                    String pkgName = in.readUTF();
+                    long lastBackup = in.readLong();
+                    foundApps.add(pkgName); // all apps that we've addressed already
+                    try {
+                        PackageInfo pkg = mPackageManager.getPackageInfo(pkgName, 0);
+                        if (AppBackupUtils.appGetsFullBackup(pkg)
+                                && AppBackupUtils.appIsEligibleForBackup(
+                                pkg.applicationInfo)) {
+                            schedule.add(new FullBackupEntry(pkgName, lastBackup));
+                        } else {
+                            if (DEBUG) {
+                                Slog.i(TAG, "Package " + pkgName
+                                        + " no longer eligible for full backup");
+                            }
+                        }
+                    } catch (NameNotFoundException e) {
+                        if (DEBUG) {
+                            Slog.i(TAG, "Package " + pkgName
+                                    + " not installed; dropping from full backup");
+                        }
+                    }
+                }
+
+                // New apps can arrive "out of band" via OTA and similar, so we also need to
+                // scan to make sure that we're tracking all full-backup candidates properly
+                for (PackageInfo app : apps) {
+                    if (AppBackupUtils.appGetsFullBackup(app)
+                            && AppBackupUtils.appIsEligibleForBackup(
+                            app.applicationInfo)) {
+                        if (!foundApps.contains(app.packageName)) {
+                            if (MORE_DEBUG) {
+                                Slog.i(TAG, "New full backup app " + app.packageName + " found");
+                            }
+                            schedule.add(new FullBackupEntry(app.packageName, 0));
+                            changed = true;
+                        }
+                    }
+                }
+
+                Collections.sort(schedule);
+            } catch (Exception e) {
+                Slog.e(TAG, "Unable to read backup schedule", e);
+                mFullBackupScheduleFile.delete();
+                schedule = null;
+            } finally {
+                IoUtils.closeQuietly(in);
+                IoUtils.closeQuietly(bufStream);
+                IoUtils.closeQuietly(fstream);
+            }
+        }
+
+        if (schedule == null) {
+            // no prior queue record, or unable to read it.  Set up the queue
+            // from scratch.
+            changed = true;
+            schedule = new ArrayList<>(apps.size());
+            for (PackageInfo info : apps) {
+                if (AppBackupUtils.appGetsFullBackup(info) && AppBackupUtils.appIsEligibleForBackup(
+                        info.applicationInfo)) {
+                    schedule.add(new FullBackupEntry(info.packageName, 0));
+                }
+            }
+        }
+
+        if (changed) {
+            writeFullBackupScheduleAsync();
+        }
+        return schedule;
+    }
+
+    private Runnable mFullBackupScheduleWriter = new Runnable() {
+        @Override
+        public void run() {
+            synchronized (mQueueLock) {
+                try {
+                    ByteArrayOutputStream bufStream = new ByteArrayOutputStream(4096);
+                    DataOutputStream bufOut = new DataOutputStream(bufStream);
+                    bufOut.writeInt(SCHEDULE_FILE_VERSION);
+
+                    // version 1:
+                    //
+                    // [int] # of packages in the queue = N
+                    // N * {
+                    //     [utf8] package name
+                    //     [long] last backup time for this package
+                    //     }
+                    int N = mFullBackupQueue.size();
+                    bufOut.writeInt(N);
+
+                    for (int i = 0; i < N; i++) {
+                        FullBackupEntry entry = mFullBackupQueue.get(i);
+                        bufOut.writeUTF(entry.packageName);
+                        bufOut.writeLong(entry.lastBackup);
+                    }
+                    bufOut.flush();
+
+                    AtomicFile af = new AtomicFile(mFullBackupScheduleFile);
+                    FileOutputStream out = af.startWrite();
+                    out.write(bufStream.toByteArray());
+                    af.finishWrite(out);
+                } catch (Exception e) {
+                    Slog.e(TAG, "Unable to write backup schedule!", e);
+                }
+            }
+        }
+    };
+
+    private void writeFullBackupScheduleAsync() {
+        mBackupHandler.removeCallbacks(mFullBackupScheduleWriter);
+        mBackupHandler.post(mFullBackupScheduleWriter);
+    }
+
+    private void parseLeftoverJournals() {
+        for (File f : mJournalDir.listFiles()) {
+            if (mJournal == null || f.compareTo(mJournal) != 0) {
+                // This isn't the current journal, so it must be a leftover.  Read
+                // out the package names mentioned there and schedule them for
+                // backup.
+                DataInputStream in = null;
+                try {
+                    Slog.i(TAG, "Found stale backup journal, scheduling");
+                    // Journals will tend to be on the order of a few kilobytes(around 4k), hence,
+                    // setting the buffer size to 8192.
+                    InputStream bufferedInputStream = new BufferedInputStream(
+                            new FileInputStream(f), 8192);
+                    in = new DataInputStream(bufferedInputStream);
+                    while (true) {
+                        String packageName = in.readUTF();
+                        if (MORE_DEBUG) Slog.i(TAG, "  " + packageName);
+                        dataChangedImpl(packageName);
+                    }
+                } catch (EOFException e) {
+                    // no more data; we're done
+                } catch (Exception e) {
+                    Slog.e(TAG, "Can't read " + f, e);
+                } finally {
+                    // close/delete the file
+                    try {
+                        if (in != null) in.close();
+                    } catch (IOException e) {
+                    }
+                    f.delete();
+                }
+            }
+        }
+    }
+
+    // Used for generating random salts or passwords
+    public byte[] randomBytes(int bits) {
+        byte[] array = new byte[bits / 8];
+        mRng.nextBytes(array);
+        return array;
+    }
+
+    private boolean passwordMatchesSaved(String algorithm, String candidatePw, int rounds) {
+        if (mPasswordHash == null) {
+            // no current password case -- require that 'currentPw' be null or empty
+            if (candidatePw == null || "".equals(candidatePw)) {
+                return true;
+            } // else the non-empty candidate does not match the empty stored pw
+        } else {
+            // hash the stated current pw and compare to the stored one
+            if (candidatePw != null && candidatePw.length() > 0) {
+                String currentPwHash = PasswordUtils.buildPasswordHash(algorithm, candidatePw,
+                        mPasswordSalt,
+                        rounds);
+                if (mPasswordHash.equalsIgnoreCase(currentPwHash)) {
+                    // candidate hash matches the stored hash -- the password matches
+                    return true;
+                }
+            } // else the stored pw is nonempty but the candidate is empty; no match
+        }
+        return false;
+    }
+
+    @Override
+    public boolean setBackupPassword(String currentPw, String newPw) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "setBackupPassword");
+
+        // When processing v1 passwords we may need to try two different PBKDF2 checksum regimes
+        final boolean pbkdf2Fallback = (mPasswordVersion < BACKUP_PW_FILE_VERSION);
+
+        // If the supplied pw doesn't hash to the the saved one, fail.  The password
+        // might be caught in the legacy crypto mismatch; verify that too.
+        if (!passwordMatchesSaved(PBKDF_CURRENT, currentPw, PasswordUtils.PBKDF2_HASH_ROUNDS)
+                && !(pbkdf2Fallback && passwordMatchesSaved(PBKDF_FALLBACK,
+                currentPw, PasswordUtils.PBKDF2_HASH_ROUNDS))) {
+            return false;
+        }
+
+        // Snap up to current on the pw file version
+        mPasswordVersion = BACKUP_PW_FILE_VERSION;
+        FileOutputStream pwFout = null;
+        DataOutputStream pwOut = null;
+        try {
+            pwFout = new FileOutputStream(mPasswordVersionFile);
+            pwOut = new DataOutputStream(pwFout);
+            pwOut.writeInt(mPasswordVersion);
+        } catch (IOException e) {
+            Slog.e(TAG, "Unable to write backup pw version; password not changed");
+            return false;
+        } finally {
+            try {
+                if (pwOut != null) pwOut.close();
+                if (pwFout != null) pwFout.close();
+            } catch (IOException e) {
+                Slog.w(TAG, "Unable to close pw version record");
+            }
+        }
+
+        // Clearing the password is okay
+        if (newPw == null || newPw.isEmpty()) {
+            if (mPasswordHashFile.exists()) {
+                if (!mPasswordHashFile.delete()) {
+                    // Unable to delete the old pw file, so fail
+                    Slog.e(TAG, "Unable to clear backup password");
+                    return false;
+                }
+            }
+            mPasswordHash = null;
+            mPasswordSalt = null;
+            return true;
+        }
+
+        try {
+            // Okay, build the hash of the new backup password
+            byte[] salt = randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);
+            String newPwHash = PasswordUtils.buildPasswordHash(PBKDF_CURRENT, newPw, salt,
+                    PasswordUtils.PBKDF2_HASH_ROUNDS);
+
+            OutputStream pwf = null, buffer = null;
+            DataOutputStream out = null;
+            try {
+                pwf = new FileOutputStream(mPasswordHashFile);
+                buffer = new BufferedOutputStream(pwf);
+                out = new DataOutputStream(buffer);
+                // integer length of the salt array, followed by the salt,
+                // then the hex pw hash string
+                out.writeInt(salt.length);
+                out.write(salt);
+                out.writeUTF(newPwHash);
+                out.flush();
+                mPasswordHash = newPwHash;
+                mPasswordSalt = salt;
+                return true;
+            } finally {
+                if (out != null) out.close();
+                if (buffer != null) buffer.close();
+                if (pwf != null) pwf.close();
+            }
+        } catch (IOException e) {
+            Slog.e(TAG, "Unable to set backup password");
+        }
+        return false;
+    }
+
+    @Override
+    public boolean hasBackupPassword() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "hasBackupPassword");
+
+        return mPasswordHash != null && mPasswordHash.length() > 0;
+    }
+
+    public boolean backupPasswordMatches(String currentPw) {
+        if (hasBackupPassword()) {
+            final boolean pbkdf2Fallback = (mPasswordVersion < BACKUP_PW_FILE_VERSION);
+            if (!passwordMatchesSaved(PBKDF_CURRENT, currentPw, PasswordUtils.PBKDF2_HASH_ROUNDS)
+                    && !(pbkdf2Fallback && passwordMatchesSaved(PBKDF_FALLBACK,
+                    currentPw, PasswordUtils.PBKDF2_HASH_ROUNDS))) {
+                if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting");
+                return false;
+            }
+        }
+        return true;
+    }
+
+    // Maintain persistent state around whether need to do an initialize operation.
+    // Must be called with the queue lock held.
+    public void recordInitPendingLocked(boolean isPending, String transportName) {
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "recordInitPendingLocked: " + isPending
+                    + " on transport " + transportName);
+        }
+        mBackupHandler.removeMessages(MSG_RETRY_INIT);
+
+        try {
+            IBackupTransport transport = mTransportManager.getTransportBinder(transportName);
+            if (transport != null) {
+                String transportDirName = transport.transportDirName();
+                File stateDir = new File(mBaseStateDir, transportDirName);
+                File initPendingFile = new File(stateDir, INIT_SENTINEL_FILE_NAME);
+
+                if (isPending) {
+                    // We need an init before we can proceed with sending backup data.
+                    // Record that with an entry in our set of pending inits, as well as
+                    // journaling it via creation of a sentinel file.
+                    mPendingInits.add(transportName);
+                    try {
+                        (new FileOutputStream(initPendingFile)).close();
+                    } catch (IOException ioe) {
+                        // Something is badly wrong with our permissions; just try to move on
+                    }
+                } else {
+                    // No more initialization needed; wipe the journal and reset our state.
+                    initPendingFile.delete();
+                    mPendingInits.remove(transportName);
+                }
+                return; // done; don't fall through to the error case
+            }
+        } catch (Exception e) {
+            // transport threw when asked its name; fall through to the lookup-failed case
+            Slog.e(TAG, "Transport " + transportName + " failed to report name: "
+                    + e.getMessage());
+        }
+
+        // The named transport doesn't exist or threw.  This operation is
+        // important, so we record the need for a an init and post a message
+        // to retry the init later.
+        if (isPending) {
+            mPendingInits.add(transportName);
+            mBackupHandler.sendMessageDelayed(
+                    mBackupHandler.obtainMessage(MSG_RETRY_INIT,
+                            (isPending ? 1 : 0),
+                            0,
+                            transportName),
+                    TRANSPORT_RETRY_INTERVAL);
+        }
+    }
+
+    // Reset all of our bookkeeping, in response to having been told that
+    // the backend data has been wiped [due to idle expiry, for example],
+    // so we must re-upload all saved settings.
+    public void resetBackupState(File stateFileDir) {
+        synchronized (mQueueLock) {
+            // Wipe the "what we've ever backed up" tracking
+            mEverStoredApps.clear();
+            mEverStored.delete();
+
+            mCurrentToken = 0;
+            writeRestoreTokens();
+
+            // Remove all the state files
+            for (File sf : stateFileDir.listFiles()) {
+                // ... but don't touch the needs-init sentinel
+                if (!sf.getName().equals(INIT_SENTINEL_FILE_NAME)) {
+                    sf.delete();
+                }
+            }
+        }
+
+        // Enqueue a new backup of every participant
+        synchronized (mBackupParticipants) {
+            final int N = mBackupParticipants.size();
+            for (int i = 0; i < N; i++) {
+                HashSet<String> participants = mBackupParticipants.valueAt(i);
+                if (participants != null) {
+                    for (String packageName : participants) {
+                        dataChangedImpl(packageName);
+                    }
+                }
+            }
+        }
+    }
+
+    private TransportManager.TransportBoundListener mTransportBoundListener =
+            new TransportManager.TransportBoundListener() {
+                @Override
+                public boolean onTransportBound(IBackupTransport transport) {
+                    // If the init sentinel file exists, we need to be sure to perform the init
+                    // as soon as practical.  We also create the state directory at registration
+                    // time to ensure it's present from the outset.
+                    String name = null;
+                    try {
+                        name = transport.name();
+                        String transportDirName = transport.transportDirName();
+                        File stateDir = new File(mBaseStateDir, transportDirName);
+                        stateDir.mkdirs();
+
+                        File initSentinel = new File(stateDir, INIT_SENTINEL_FILE_NAME);
+                        if (initSentinel.exists()) {
+                            synchronized (mQueueLock) {
+                                mPendingInits.add(name);
+
+                                // TODO: pick a better starting time than now + 1 minute
+                                long delay = 1000 * 60; // one minute, in milliseconds
+                                mAlarmManager.set(AlarmManager.RTC_WAKEUP,
+                                        System.currentTimeMillis() + delay, mRunInitIntent);
+                            }
+                        }
+                        return true;
+                    } catch (Exception e) {
+                        // the transport threw when asked its file naming prefs; declare it invalid
+                        Slog.w(TAG, "Failed to regiser transport: " + name);
+                        return false;
+                    }
+                }
+            };
+
+    // ----- Track installation/removal of packages -----
+    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            if (MORE_DEBUG) Slog.d(TAG, "Received broadcast " + intent);
+
+            String action = intent.getAction();
+            boolean replacing = false;
+            boolean added = false;
+            boolean changed = false;
+            Bundle extras = intent.getExtras();
+            String pkgList[] = null;
+            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
+                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
+                    Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
+                Uri uri = intent.getData();
+                if (uri == null) {
+                    return;
+                }
+                String pkgName = uri.getSchemeSpecificPart();
+                if (pkgName != null) {
+                    pkgList = new String[]{pkgName};
+                }
+                changed = Intent.ACTION_PACKAGE_CHANGED.equals(action);
+
+                // At package-changed we only care about looking at new transport states
+                if (changed) {
+                    String[] components =
+                            intent.getStringArrayExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
+
+                    if (MORE_DEBUG) {
+                        Slog.i(TAG, "Package " + pkgName + " changed; rechecking");
+                        for (int i = 0; i < components.length; i++) {
+                            Slog.i(TAG, "   * " + components[i]);
+                        }
+                    }
+
+                    mTransportManager.onPackageChanged(pkgName, components);
+                    return; // nothing more to do in the PACKAGE_CHANGED case
+                }
+
+                added = Intent.ACTION_PACKAGE_ADDED.equals(action);
+                replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false);
+            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
+                added = true;
+                pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
+                added = false;
+                pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+            }
+
+            if (pkgList == null || pkgList.length == 0) {
+                return;
+            }
+
+            final int uid = extras.getInt(Intent.EXTRA_UID);
+            if (added) {
+                synchronized (mBackupParticipants) {
+                    if (replacing) {
+                        // This is the package-replaced case; we just remove the entry
+                        // under the old uid and fall through to re-add.  If an app
+                        // just added key/value backup participation, this picks it up
+                        // as a known participant.
+                        removePackageParticipantsLocked(pkgList, uid);
+                    }
+                    addPackageParticipantsLocked(pkgList);
+                }
+                // If they're full-backup candidates, add them there instead
+                final long now = System.currentTimeMillis();
+                for (String packageName : pkgList) {
+                    try {
+                        PackageInfo app = mPackageManager.getPackageInfo(packageName, 0);
+                        if (AppBackupUtils.appGetsFullBackup(app)
+                                && AppBackupUtils.appIsEligibleForBackup(
+                                app.applicationInfo)) {
+                            enqueueFullBackup(packageName, now);
+                            scheduleNextFullBackupJob(0);
+                        } else {
+                            // The app might have just transitioned out of full-data into
+                            // doing key/value backups, or might have just disabled backups
+                            // entirely.  Make sure it is no longer in the full-data queue.
+                            synchronized (mQueueLock) {
+                                dequeueFullBackupLocked(packageName);
+                            }
+                            writeFullBackupScheduleAsync();
+                        }
+
+                        mTransportManager.onPackageAdded(packageName);
+
+                    } catch (NameNotFoundException e) {
+                        // doesn't really exist; ignore it
+                        if (DEBUG) {
+                            Slog.w(TAG, "Can't resolve new app " + packageName);
+                        }
+                    }
+                }
+
+                // Whenever a package is added or updated we need to update
+                // the package metadata bookkeeping.
+                dataChangedImpl(PACKAGE_MANAGER_SENTINEL);
+            } else {
+                if (replacing) {
+                    // The package is being updated.  We'll receive a PACKAGE_ADDED shortly.
+                } else {
+                    // Outright removal.  In the full-data case, the app will be dropped
+                    // from the queue when its (now obsolete) name comes up again for
+                    // backup.
+                    synchronized (mBackupParticipants) {
+                        removePackageParticipantsLocked(pkgList, uid);
+                    }
+                }
+                for (String pkgName : pkgList) {
+                    mTransportManager.onPackageRemoved(pkgName);
+                }
+            }
+        }
+    };
+
+    // Add the backup agents in the given packages to our set of known backup participants.
+    // If 'packageNames' is null, adds all backup agents in the whole system.
+    private void addPackageParticipantsLocked(String[] packageNames) {
+        // Look for apps that define the android:backupAgent attribute
+        List<PackageInfo> targetApps = allAgentPackages();
+        if (packageNames != null) {
+            if (MORE_DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: #" + packageNames.length);
+            for (String packageName : packageNames) {
+                addPackageParticipantsLockedInner(packageName, targetApps);
+            }
+        } else {
+            if (MORE_DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: all");
+            addPackageParticipantsLockedInner(null, targetApps);
+        }
+    }
+
+    private void addPackageParticipantsLockedInner(String packageName,
+            List<PackageInfo> targetPkgs) {
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "Examining " + packageName + " for backup agent");
+        }
+
+        for (PackageInfo pkg : targetPkgs) {
+            if (packageName == null || pkg.packageName.equals(packageName)) {
+                int uid = pkg.applicationInfo.uid;
+                HashSet<String> set = mBackupParticipants.get(uid);
+                if (set == null) {
+                    set = new HashSet<>();
+                    mBackupParticipants.put(uid, set);
+                }
+                set.add(pkg.packageName);
+                if (MORE_DEBUG) Slog.v(TAG, "Agent found; added");
+
+                // Schedule a backup for it on general principles
+                if (MORE_DEBUG) Slog.i(TAG, "Scheduling backup for new app " + pkg.packageName);
+                Message msg = mBackupHandler
+                        .obtainMessage(MSG_SCHEDULE_BACKUP_PACKAGE, pkg.packageName);
+                mBackupHandler.sendMessage(msg);
+            }
+        }
+    }
+
+    // Remove the given packages' entries from our known active set.
+    private void removePackageParticipantsLocked(String[] packageNames, int oldUid) {
+        if (packageNames == null) {
+            Slog.w(TAG, "removePackageParticipants with null list");
+            return;
+        }
+
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "removePackageParticipantsLocked: uid=" + oldUid
+                    + " #" + packageNames.length);
+        }
+        for (String pkg : packageNames) {
+            // Known previous UID, so we know which package set to check
+            HashSet<String> set = mBackupParticipants.get(oldUid);
+            if (set != null && set.contains(pkg)) {
+                removePackageFromSetLocked(set, pkg);
+                if (set.isEmpty()) {
+                    if (MORE_DEBUG) Slog.v(TAG, "  last one of this uid; purging set");
+                    mBackupParticipants.remove(oldUid);
+                }
+            }
+        }
+    }
+
+    private void removePackageFromSetLocked(final HashSet<String> set,
+            final String packageName) {
+        if (set.contains(packageName)) {
+            // Found it.  Remove this one package from the bookkeeping, and
+            // if it's the last participating app under this uid we drop the
+            // (now-empty) set as well.
+            // Note that we deliberately leave it 'known' in the "ever backed up"
+            // bookkeeping so that its current-dataset data will be retrieved
+            // if the app is subsequently reinstalled
+            if (MORE_DEBUG) Slog.v(TAG, "  removing participant " + packageName);
+            set.remove(packageName);
+            mPendingBackups.remove(packageName);
+        }
+    }
+
+    // Returns the set of all applications that define an android:backupAgent attribute
+    private List<PackageInfo> allAgentPackages() {
+        // !!! TODO: cache this and regenerate only when necessary
+        int flags = PackageManager.GET_SIGNATURES;
+        List<PackageInfo> packages = mPackageManager.getInstalledPackages(flags);
+        int N = packages.size();
+        for (int a = N - 1; a >= 0; a--) {
+            PackageInfo pkg = packages.get(a);
+            try {
+                ApplicationInfo app = pkg.applicationInfo;
+                if (((app.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0)
+                        || app.backupAgentName == null
+                        || (app.flags & ApplicationInfo.FLAG_FULL_BACKUP_ONLY) != 0) {
+                    packages.remove(a);
+                } else {
+                    // we will need the shared library path, so look that up and store it here.
+                    // This is used implicitly when we pass the PackageInfo object off to
+                    // the Activity Manager to launch the app for backup/restore purposes.
+                    app = mPackageManager.getApplicationInfo(pkg.packageName,
+                            PackageManager.GET_SHARED_LIBRARY_FILES);
+                    pkg.applicationInfo.sharedLibraryFiles = app.sharedLibraryFiles;
+                }
+            } catch (NameNotFoundException e) {
+                packages.remove(a);
+            }
+        }
+        return packages;
+    }
+
+    // Called from the backup tasks: record that the given app has been successfully
+    // backed up at least once.  This includes both key/value and full-data backups
+    // through the transport.
+    public void logBackupComplete(String packageName) {
+        if (packageName.equals(PACKAGE_MANAGER_SENTINEL)) return;
+
+        synchronized (mEverStoredApps) {
+            if (!mEverStoredApps.add(packageName)) return;
+
+            RandomAccessFile out = null;
+            try {
+                out = new RandomAccessFile(mEverStored, "rws");
+                out.seek(out.length());
+                out.writeUTF(packageName);
+            } catch (IOException e) {
+                Slog.e(TAG, "Can't log backup of " + packageName + " to " + mEverStored);
+            } finally {
+                try {
+                    if (out != null) out.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    // Remove our awareness of having ever backed up the given package
+    void removeEverBackedUp(String packageName) {
+        if (DEBUG) Slog.v(TAG, "Removing backed-up knowledge of " + packageName);
+        if (MORE_DEBUG) Slog.v(TAG, "New set:");
+
+        synchronized (mEverStoredApps) {
+            // Rewrite the file and rename to overwrite.  If we reboot in the middle,
+            // we'll recognize on initialization time that the package no longer
+            // exists and fix it up then.
+            File tempKnownFile = new File(mBaseStateDir, "processed.new");
+            RandomAccessFile known = null;
+            try {
+                known = new RandomAccessFile(tempKnownFile, "rws");
+                mEverStoredApps.remove(packageName);
+                for (String s : mEverStoredApps) {
+                    known.writeUTF(s);
+                    if (MORE_DEBUG) Slog.v(TAG, "    " + s);
+                }
+                known.close();
+                known = null;
+                if (!tempKnownFile.renameTo(mEverStored)) {
+                    throw new IOException("Can't rename " + tempKnownFile + " to " + mEverStored);
+                }
+            } catch (IOException e) {
+                // Bad: we couldn't create the new copy.  For safety's sake we
+                // abandon the whole process and remove all what's-backed-up
+                // state entirely, meaning we'll force a backup pass for every
+                // participant on the next boot or [re]install.
+                Slog.w(TAG, "Error rewriting " + mEverStored, e);
+                mEverStoredApps.clear();
+                tempKnownFile.delete();
+                mEverStored.delete();
+            } finally {
+                try {
+                    if (known != null) known.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    // Persistently record the current and ancestral backup tokens as well
+    // as the set of packages with data [supposedly] available in the
+    // ancestral dataset.
+    public void writeRestoreTokens() {
+        try {
+            RandomAccessFile af = new RandomAccessFile(mTokenFile, "rwd");
+
+            // First, the version number of this record, for futureproofing
+            af.writeInt(CURRENT_ANCESTRAL_RECORD_VERSION);
+
+            // Write the ancestral and current tokens
+            af.writeLong(mAncestralToken);
+            af.writeLong(mCurrentToken);
+
+            // Now write the set of ancestral packages
+            if (mAncestralPackages == null) {
+                af.writeInt(-1);
+            } else {
+                af.writeInt(mAncestralPackages.size());
+                if (DEBUG) Slog.v(TAG, "Ancestral packages:  " + mAncestralPackages.size());
+                for (String pkgName : mAncestralPackages) {
+                    af.writeUTF(pkgName);
+                    if (MORE_DEBUG) Slog.v(TAG, "   " + pkgName);
+                }
+            }
+            af.close();
+        } catch (IOException e) {
+            Slog.w(TAG, "Unable to write token file:", e);
+        }
+    }
+
+    // What name is this transport registered under...?
+    private String getTransportName(IBackupTransport transport) {
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "Searching for transport name of " + transport);
+        }
+        return mTransportManager.getTransportName(transport);
+    }
+
+    // fire off a backup agent, blocking until it attaches or times out
+    @Override
+    public IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode) {
+        IBackupAgent agent = null;
+        synchronized (mAgentConnectLock) {
+            mConnecting = true;
+            mConnectedAgent = null;
+            try {
+                if (mActivityManager.bindBackupAgent(app.packageName, mode,
+                        UserHandle.USER_OWNER)) {
+                    Slog.d(TAG, "awaiting agent for " + app);
+
+                    // success; wait for the agent to arrive
+                    // only wait 10 seconds for the bind to happen
+                    long timeoutMark = System.currentTimeMillis() + TIMEOUT_INTERVAL;
+                    while (mConnecting && mConnectedAgent == null
+                            && (System.currentTimeMillis() < timeoutMark)) {
+                        try {
+                            mAgentConnectLock.wait(5000);
+                        } catch (InterruptedException e) {
+                            // just bail
+                            Slog.w(TAG, "Interrupted: " + e);
+                            mConnecting = false;
+                            mConnectedAgent = null;
+                        }
+                    }
+
+                    // if we timed out with no connect, abort and move on
+                    if (mConnecting == true) {
+                        Slog.w(TAG, "Timeout waiting for agent " + app);
+                        mConnectedAgent = null;
+                    }
+                    if (DEBUG) Slog.i(TAG, "got agent " + mConnectedAgent);
+                    agent = mConnectedAgent;
+                }
+            } catch (RemoteException e) {
+                // can't happen - ActivityManager is local
+            }
+        }
+        if (agent == null) {
+            try {
+                mActivityManager.clearPendingBackup();
+            } catch (RemoteException e) {
+                // can't happen - ActivityManager is local
+            }
+        }
+        return agent;
+    }
+
+    // clear an application's data, blocking until the operation completes or times out
+    public void clearApplicationDataSynchronous(String packageName) {
+        // Don't wipe packages marked allowClearUserData=false
+        try {
+            PackageInfo info = mPackageManager.getPackageInfo(packageName, 0);
+            if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) == 0) {
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "allowClearUserData=false so not wiping "
+                            + packageName);
+                }
+                return;
+            }
+        } catch (NameNotFoundException e) {
+            Slog.w(TAG, "Tried to clear data for " + packageName + " but not found");
+            return;
+        }
+
+        ClearDataObserver observer = new ClearDataObserver(this);
+
+        synchronized (mClearDataLock) {
+            mClearingData = true;
+            try {
+                mActivityManager.clearApplicationUserData(packageName, observer, 0);
+            } catch (RemoteException e) {
+                // can't happen because the activity manager is in this process
+            }
+
+            // only wait 10 seconds for the clear data to happen
+            long timeoutMark = System.currentTimeMillis() + TIMEOUT_INTERVAL;
+            while (mClearingData && (System.currentTimeMillis() < timeoutMark)) {
+                try {
+                    mClearDataLock.wait(5000);
+                } catch (InterruptedException e) {
+                    // won't happen, but still.
+                    mClearingData = false;
+                }
+            }
+        }
+    }
+
+    // Get the restore-set token for the best-available restore set for this package:
+    // the active set if possible, else the ancestral one.  Returns zero if none available.
+    @Override
+    public long getAvailableRestoreToken(String packageName) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "getAvailableRestoreToken");
+
+        long token = mAncestralToken;
+        synchronized (mQueueLock) {
+            if (mEverStoredApps.contains(packageName)) {
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "App in ever-stored, so using current token");
+                }
+                token = mCurrentToken;
+            }
+        }
+        if (MORE_DEBUG) Slog.i(TAG, "getAvailableRestoreToken() == " + token);
+        return token;
+    }
+
+    @Override
+    public int requestBackup(String[] packages, IBackupObserver observer, int flags) {
+        return requestBackup(packages, observer, null, flags);
+    }
+
+    @Override
+    public int requestBackup(String[] packages, IBackupObserver observer,
+            IBackupManagerMonitor monitor, int flags) {
+        mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "requestBackup");
+
+        if (packages == null || packages.length < 1) {
+            Slog.e(TAG, "No packages named for backup request");
+            BackupObserverUtils.sendBackupFinished(observer, BackupManager.ERROR_TRANSPORT_ABORTED);
+            monitor = BackupManagerMonitorUtils.monitorEvent(monitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_NO_PACKAGES,
+                    null, BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, null);
+            throw new IllegalArgumentException("No packages are provided for backup");
+        }
+
+        IBackupTransport transport = mTransportManager.getCurrentTransportBinder();
+        if (transport == null) {
+            BackupObserverUtils.sendBackupFinished(observer, BackupManager.ERROR_TRANSPORT_ABORTED);
+            monitor = BackupManagerMonitorUtils.monitorEvent(monitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_IS_NULL,
+                    null, BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, null);
+            return BackupManager.ERROR_TRANSPORT_ABORTED;
+        }
+
+        ArrayList<String> fullBackupList = new ArrayList<>();
+        ArrayList<String> kvBackupList = new ArrayList<>();
+        for (String packageName : packages) {
+            if (PACKAGE_MANAGER_SENTINEL.equals(packageName)) {
+                kvBackupList.add(packageName);
+                continue;
+            }
+            try {
+                PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName,
+                        PackageManager.GET_SIGNATURES);
+                if (!AppBackupUtils.appIsEligibleForBackup(packageInfo.applicationInfo)) {
+                    BackupObserverUtils.sendBackupOnPackageResult(observer, packageName,
+                            BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                    continue;
+                }
+                if (AppBackupUtils.appGetsFullBackup(packageInfo)) {
+                    fullBackupList.add(packageInfo.packageName);
+                } else {
+                    kvBackupList.add(packageInfo.packageName);
+                }
+            } catch (NameNotFoundException e) {
+                BackupObserverUtils.sendBackupOnPackageResult(observer, packageName,
+                        BackupManager.ERROR_PACKAGE_NOT_FOUND);
+            }
+        }
+        EventLog.writeEvent(EventLogTags.BACKUP_REQUESTED, packages.length, kvBackupList.size(),
+                fullBackupList.size());
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "Backup requested for " + packages.length + " packages, of them: " +
+                    fullBackupList.size() + " full backups, " + kvBackupList.size()
+                    + " k/v backups");
+        }
+
+        String dirName;
+        try {
+            dirName = transport.transportDirName();
+        } catch (Exception e) {
+            Slog.e(TAG, "Transport unavailable while attempting backup: " + e.getMessage());
+            BackupObserverUtils.sendBackupFinished(observer, BackupManager.ERROR_TRANSPORT_ABORTED);
+            return BackupManager.ERROR_TRANSPORT_ABORTED;
+        }
+
+        boolean nonIncrementalBackup = (flags & BackupManager.FLAG_NON_INCREMENTAL_BACKUP) != 0;
+
+        Message msg = mBackupHandler.obtainMessage(MSG_REQUEST_BACKUP);
+        msg.obj = new BackupParams(transport, dirName, kvBackupList, fullBackupList, observer,
+                monitor, true, nonIncrementalBackup);
+        mBackupHandler.sendMessage(msg);
+        return BackupManager.SUCCESS;
+    }
+
+    // Cancel all running backups.
+    @Override
+    public void cancelBackups() {
+        mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "cancelBackups");
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "cancelBackups() called.");
+        }
+        final long oldToken = Binder.clearCallingIdentity();
+        try {
+            List<Integer> operationsToCancel = new ArrayList<>();
+            synchronized (mCurrentOpLock) {
+                for (int i = 0; i < mCurrentOperations.size(); i++) {
+                    Operation op = mCurrentOperations.valueAt(i);
+                    int token = mCurrentOperations.keyAt(i);
+                    if (op.type == OP_TYPE_BACKUP) {
+                        operationsToCancel.add(token);
+                    }
+                }
+            }
+            for (Integer token : operationsToCancel) {
+                handleCancel(token, true /* cancelAll */);
+            }
+            // We don't want the backup jobs to kick in any time soon.
+            // Reschedules them to run in the distant future.
+            KeyValueBackupJob.schedule(mContext, BUSY_BACKOFF_MIN_MILLIS);
+            FullBackupJob.schedule(mContext, 2 * BUSY_BACKOFF_MIN_MILLIS);
+        } finally {
+            Binder.restoreCallingIdentity(oldToken);
+        }
+    }
+
+    @Override
+    public void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
+            int operationType) {
+        if (operationType != OP_TYPE_BACKUP_WAIT && operationType != OP_TYPE_RESTORE_WAIT) {
+            Slog.wtf(TAG, "prepareOperationTimeout() doesn't support operation " +
+                    Integer.toHexString(token) + " of type " + operationType);
+            return;
+        }
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "starting timeout: token=" + Integer.toHexString(token)
+                    + " interval=" + interval + " callback=" + callback);
+        }
+
+        synchronized (mCurrentOpLock) {
+            mCurrentOperations.put(token, new Operation(OP_PENDING, callback, operationType));
+            Message msg = mBackupHandler.obtainMessage(getMessageIdForOperationType(operationType),
+                    token, 0, callback);
+            mBackupHandler.sendMessageDelayed(msg, interval);
+        }
+    }
+
+    private int getMessageIdForOperationType(int operationType) {
+        switch (operationType) {
+            case OP_TYPE_BACKUP_WAIT:
+                return MSG_BACKUP_OPERATION_TIMEOUT;
+            case OP_TYPE_RESTORE_WAIT:
+                return MSG_RESTORE_OPERATION_TIMEOUT;
+            default:
+                Slog.wtf(TAG, "getMessageIdForOperationType called on invalid operation type: " +
+                        operationType);
+                return -1;
+        }
+    }
+
+    public void removeOperation(int token) {
+        if (MORE_DEBUG) {
+            Slog.d(TAG, "Removing operation token=" + Integer.toHexString(token));
+        }
+        synchronized (mCurrentOpLock) {
+            if (mCurrentOperations.get(token) == null) {
+                Slog.w(TAG, "Duplicate remove for operation. token=" +
+                        Integer.toHexString(token));
+            }
+            mCurrentOperations.remove(token);
+        }
+    }
+
+    // synchronous waiter case
+    @Override
+    public boolean waitUntilOperationComplete(int token) {
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "Blocking until operation complete for "
+                    + Integer.toHexString(token));
+        }
+        int finalState = OP_PENDING;
+        Operation op = null;
+        synchronized (mCurrentOpLock) {
+            while (true) {
+                op = mCurrentOperations.get(token);
+                if (op == null) {
+                    // mysterious disappearance: treat as success with no callback
+                    break;
+                } else {
+                    if (op.state == OP_PENDING) {
+                        try {
+                            mCurrentOpLock.wait();
+                        } catch (InterruptedException e) {
+                        }
+                        // When the wait is notified we loop around and recheck the current state
+                    } else {
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "Unblocked waiting for operation token=" +
+                                    Integer.toHexString(token));
+                        }
+                        // No longer pending; we're done
+                        finalState = op.state;
+                        break;
+                    }
+                }
+            }
+        }
+
+        removeOperation(token);
+        if (op != null) {
+            mBackupHandler.removeMessages(getMessageIdForOperationType(op.type));
+        }
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "operation " + Integer.toHexString(token)
+                    + " complete: finalState=" + finalState);
+        }
+        return finalState == OP_ACKNOWLEDGED;
+    }
+
+    public void handleCancel(int token, boolean cancelAll) {
+        // Notify any synchronous waiters
+        Operation op = null;
+        synchronized (mCurrentOpLock) {
+            op = mCurrentOperations.get(token);
+            if (MORE_DEBUG) {
+                if (op == null) {
+                    Slog.w(TAG, "Cancel of token " + Integer.toHexString(token)
+                            + " but no op found");
+                }
+            }
+            int state = (op != null) ? op.state : OP_TIMEOUT;
+            if (state == OP_ACKNOWLEDGED) {
+                // The operation finished cleanly, so we have nothing more to do.
+                if (DEBUG) {
+                    Slog.w(TAG, "Operation already got an ack." +
+                            "Should have been removed from mCurrentOperations.");
+                }
+                op = null;
+                mCurrentOperations.delete(token);
+            } else if (state == OP_PENDING) {
+                if (DEBUG) Slog.v(TAG, "Cancel: token=" + Integer.toHexString(token));
+                op.state = OP_TIMEOUT;
+                // Can't delete op from mCurrentOperations here. waitUntilOperationComplete may be
+                // called after we receive cancel here. We need this op's state there.
+
+                // Remove all pending timeout messages for this operation type.
+                mBackupHandler.removeMessages(getMessageIdForOperationType(op.type));
+            }
+            mCurrentOpLock.notifyAll();
+        }
+
+        // If there's a TimeoutHandler for this event, call it
+        if (op != null && op.callback != null) {
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "   Invoking cancel on " + op.callback);
+            }
+            op.callback.handleCancel(cancelAll);
+        }
+    }
+
+    // ----- Back up a set of applications via a worker thread -----
+
+    public boolean isBackupOperationInProgress() {
+        synchronized (mCurrentOpLock) {
+            for (int i = 0; i < mCurrentOperations.size(); i++) {
+                Operation op = mCurrentOperations.valueAt(i);
+                if (op.type == OP_TYPE_BACKUP && op.state == OP_PENDING) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+
+    @Override
+    public void tearDownAgentAndKill(ApplicationInfo app) {
+        if (app == null) {
+            // Null means the system package, so just quietly move on.  :)
+            return;
+        }
+
+        try {
+            // unbind and tidy up even on timeout or failure, just in case
+            mActivityManager.unbindBackupAgent(app);
+
+            // The agent was running with a stub Application object, so shut it down.
+            // !!! We hardcode the confirmation UI's package name here rather than use a
+            //     manifest flag!  TODO something less direct.
+            if (app.uid >= Process.FIRST_APPLICATION_UID
+                    && !app.packageName.equals("com.android.backupconfirm")) {
+                if (MORE_DEBUG) Slog.d(TAG, "Killing agent host process");
+                mActivityManager.killApplicationProcess(app.processName, app.uid);
+            } else {
+                if (MORE_DEBUG) Slog.d(TAG, "Not killing after operation: " + app.processName);
+            }
+        } catch (RemoteException e) {
+            Slog.d(TAG, "Lost app trying to shut down");
+        }
+    }
+
+    public boolean deviceIsEncrypted() {
+        try {
+            return mStorageManager.getEncryptionState()
+                    != StorageManager.ENCRYPTION_STATE_NONE
+                    && mStorageManager.getPasswordType()
+                    != StorageManager.CRYPT_TYPE_DEFAULT;
+        } catch (Exception e) {
+            // If we can't talk to the storagemanager service we have a serious problem; fail
+            // "secure" i.e. assuming that the device is encrypted.
+            Slog.e(TAG, "Unable to communicate with storagemanager service: " + e.getMessage());
+            return true;
+        }
+    }
+
+    // ----- Full-data backup scheduling -----
+
+    /**
+     * Schedule a job to tell us when it's a good time to run a full backup
+     */
+    public void scheduleNextFullBackupJob(long transportMinLatency) {
+        synchronized (mQueueLock) {
+            if (mFullBackupQueue.size() > 0) {
+                // schedule the next job at the point in the future when the least-recently
+                // backed up app comes due for backup again; or immediately if it's already
+                // due.
+                final long upcomingLastBackup = mFullBackupQueue.get(0).lastBackup;
+                final long timeSinceLast = System.currentTimeMillis() - upcomingLastBackup;
+                final long appLatency = (timeSinceLast < MIN_FULL_BACKUP_INTERVAL)
+                        ? (MIN_FULL_BACKUP_INTERVAL - timeSinceLast) : 0;
+                final long latency = Math.max(transportMinLatency, appLatency);
+                Runnable r = new Runnable() {
+                    @Override
+                    public void run() {
+                        FullBackupJob.schedule(mContext, latency);
+                    }
+                };
+                mBackupHandler.postDelayed(r, 2500);
+            } else {
+                if (DEBUG_SCHEDULING) {
+                    Slog.i(TAG, "Full backup queue empty; not scheduling");
+                }
+            }
+        }
+    }
+
+    /**
+     * Remove a package from the full-data queue.
+     */
+    private void dequeueFullBackupLocked(String packageName) {
+        final int N = mFullBackupQueue.size();
+        for (int i = N - 1; i >= 0; i--) {
+            final FullBackupEntry e = mFullBackupQueue.get(i);
+            if (packageName.equals(e.packageName)) {
+                mFullBackupQueue.remove(i);
+            }
+        }
+    }
+
+    /**
+     * Enqueue full backup for the given app, with a note about when it last ran.
+     */
+    public void enqueueFullBackup(String packageName, long lastBackedUp) {
+        FullBackupEntry newEntry = new FullBackupEntry(packageName, lastBackedUp);
+        synchronized (mQueueLock) {
+            // First, sanity check that we aren't adding a duplicate.  Slow but
+            // straightforward; we'll have at most on the order of a few hundred
+            // items in this list.
+            dequeueFullBackupLocked(packageName);
+
+            // This is also slow but easy for modest numbers of apps: work backwards
+            // from the end of the queue until we find an item whose last backup
+            // time was before this one, then insert this new entry after it.  If we're
+            // adding something new we don't bother scanning, and just prepend.
+            int which = -1;
+            if (lastBackedUp > 0) {
+                for (which = mFullBackupQueue.size() - 1; which >= 0; which--) {
+                    final FullBackupEntry entry = mFullBackupQueue.get(which);
+                    if (entry.lastBackup <= lastBackedUp) {
+                        mFullBackupQueue.add(which + 1, newEntry);
+                        break;
+                    }
+                }
+            }
+            if (which < 0) {
+                // this one is earlier than any existing one, so prepend
+                mFullBackupQueue.add(0, newEntry);
+            }
+        }
+        writeFullBackupScheduleAsync();
+    }
+
+    private boolean fullBackupAllowable(IBackupTransport transport) {
+        if (transport == null) {
+            Slog.w(TAG, "Transport not present; full data backup not performed");
+            return false;
+        }
+
+        // Don't proceed unless we have already established package metadata
+        // for the current dataset via a key/value backup pass.
+        try {
+            File stateDir = new File(mBaseStateDir, transport.transportDirName());
+            File pmState = new File(stateDir, PACKAGE_MANAGER_SENTINEL);
+            if (pmState.length() <= 0) {
+                if (DEBUG) {
+                    Slog.i(TAG, "Full backup requested but dataset not yet initialized");
+                }
+                return false;
+            }
+        } catch (Exception e) {
+            Slog.w(TAG, "Unable to get transport name: " + e.getMessage());
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Conditions are right for a full backup operation, so run one.  The model we use is
+     * to perform one app backup per scheduled job execution, and to reschedule the job
+     * with zero latency as long as conditions remain right and we still have work to do.
+     *
+     * <p>This is the "start a full backup operation" entry point called by the scheduled job.
+     *
+     * @return Whether ongoing work will continue.  The return value here will be passed
+     *         along as the return value to the scheduled job's onStartJob() callback.
+     */
+    @Override
+    public boolean beginFullBackup(FullBackupJob scheduledJob) {
+        long now = System.currentTimeMillis();
+        FullBackupEntry entry = null;
+        long latency = MIN_FULL_BACKUP_INTERVAL;
+
+        if (!mEnabled || !mProvisioned) {
+            // Backups are globally disabled, so don't proceed.  We also don't reschedule
+            // the job driving automatic backups; that job will be scheduled again when
+            // the user enables backup.
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "beginFullBackup but e=" + mEnabled
+                        + " p=" + mProvisioned + "; ignoring");
+            }
+            return false;
+        }
+
+        // Don't run the backup if we're in battery saver mode, but reschedule
+        // to try again in the not-so-distant future.
+        final PowerSaveState result =
+                mPowerManager.getPowerSaveState(ServiceType.FULL_BACKUP);
+        if (result.batterySaverEnabled) {
+            if (DEBUG) Slog.i(TAG, "Deferring scheduled full backups in battery saver mode");
+            FullBackupJob.schedule(mContext, KeyValueBackupJob.BATCH_INTERVAL);
+            return false;
+        }
+
+        if (DEBUG_SCHEDULING) {
+            Slog.i(TAG, "Beginning scheduled full backup operation");
+        }
+
+        // Great; we're able to run full backup jobs now.  See if we have any work to do.
+        synchronized (mQueueLock) {
+            if (mRunningFullBackupTask != null) {
+                Slog.e(TAG, "Backup triggered but one already/still running!");
+                return false;
+            }
+
+            // At this point we think that we have work to do, but possibly not right now.
+            // Any exit without actually running backups will also require that we
+            // reschedule the job.
+            boolean runBackup = true;
+            boolean headBusy;
+
+            do {
+                // Recheck each time, because culling due to ineligibility may
+                // have emptied the queue.
+                if (mFullBackupQueue.size() == 0) {
+                    // no work to do so just bow out
+                    if (DEBUG) {
+                        Slog.i(TAG, "Backup queue empty; doing nothing");
+                    }
+                    runBackup = false;
+                    break;
+                }
+
+                headBusy = false;
+
+                if (!fullBackupAllowable(mTransportManager.getCurrentTransportBinder())) {
+                    if (MORE_DEBUG) {
+                        Slog.i(TAG, "Preconditions not met; not running full backup");
+                    }
+                    runBackup = false;
+                    // Typically this means we haven't run a key/value backup yet.  Back off
+                    // full-backup operations by the key/value job's run interval so that
+                    // next time we run, we are likely to be able to make progress.
+                    latency = KeyValueBackupJob.BATCH_INTERVAL;
+                }
+
+                if (runBackup) {
+                    entry = mFullBackupQueue.get(0);
+                    long timeSinceRun = now - entry.lastBackup;
+                    runBackup = (timeSinceRun >= MIN_FULL_BACKUP_INTERVAL);
+                    if (!runBackup) {
+                        // It's too early to back up the next thing in the queue, so bow out
+                        if (MORE_DEBUG) {
+                            Slog.i(TAG, "Device ready but too early to back up next app");
+                        }
+                        // Wait until the next app in the queue falls due for a full data backup
+                        latency = MIN_FULL_BACKUP_INTERVAL - timeSinceRun;
+                        break;  // we know we aren't doing work yet, so bail.
+                    }
+
+                    try {
+                        PackageInfo appInfo = mPackageManager.getPackageInfo(entry.packageName, 0);
+                        if (!AppBackupUtils.appGetsFullBackup(appInfo)) {
+                            // The head app isn't supposed to get full-data backups [any more];
+                            // so we cull it and force a loop around to consider the new head
+                            // app.
+                            if (MORE_DEBUG) {
+                                Slog.i(TAG, "Culling package " + entry.packageName
+                                        + " in full-backup queue but not eligible");
+                            }
+                            mFullBackupQueue.remove(0);
+                            headBusy = true; // force the while() condition
+                            continue;
+                        }
+
+                        final int privFlags = appInfo.applicationInfo.privateFlags;
+                        headBusy = (privFlags & PRIVATE_FLAG_BACKUP_IN_FOREGROUND) == 0
+                                && mActivityManager.isAppForeground(appInfo.applicationInfo.uid);
+
+                        if (headBusy) {
+                            final long nextEligible = System.currentTimeMillis()
+                                    + BUSY_BACKOFF_MIN_MILLIS
+                                    + mTokenGenerator.nextInt(BUSY_BACKOFF_FUZZ);
+                            if (DEBUG_SCHEDULING) {
+                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                                Slog.i(TAG, "Full backup time but " + entry.packageName
+                                        + " is busy; deferring to "
+                                        + sdf.format(new Date(nextEligible)));
+                            }
+                            // This relocates the app's entry from the head of the queue to
+                            // its order-appropriate position further down, so upon looping
+                            // a new candidate will be considered at the head.
+                            enqueueFullBackup(entry.packageName,
+                                    nextEligible - MIN_FULL_BACKUP_INTERVAL);
+                        }
+                    } catch (NameNotFoundException nnf) {
+                        // So, we think we want to back this up, but it turns out the package
+                        // in question is no longer installed.  We want to drop it from the
+                        // queue entirely and move on, but if there's nothing else in the queue
+                        // we should bail entirely.  headBusy cannot have been set to true yet.
+                        runBackup = (mFullBackupQueue.size() > 1);
+                    } catch (RemoteException e) {
+                        // Cannot happen; the Activity Manager is in the same process
+                    }
+                }
+            } while (headBusy);
+
+            if (!runBackup) {
+                if (DEBUG_SCHEDULING) {
+                    Slog.i(TAG, "Nothing pending full backup; rescheduling +" + latency);
+                }
+                final long deferTime = latency;     // pin for the closure
+                mBackupHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        FullBackupJob.schedule(mContext, deferTime);
+                    }
+                });
+                return false;
+            }
+
+            // Okay, the top thing is ready for backup now.  Do it.
+            mFullBackupQueue.remove(0);
+            CountDownLatch latch = new CountDownLatch(1);
+            String[] pkg = new String[]{entry.packageName};
+            mRunningFullBackupTask = new PerformFullTransportBackupTask(this, null, pkg, true,
+                    scheduledJob, latch, null, null, false /* userInitiated */);
+            // Acquiring wakelock for PerformFullTransportBackupTask before its start.
+            mWakelock.acquire();
+            (new Thread(mRunningFullBackupTask)).start();
+        }
+
+        return true;
+    }
+
+    // The job scheduler says our constraints don't hold any more,
+    // so tear down any ongoing backup task right away.
+    @Override
+    public void endFullBackup() {
+        synchronized (mQueueLock) {
+            if (mRunningFullBackupTask != null) {
+                if (DEBUG_SCHEDULING) {
+                    Slog.i(TAG, "Telling running backup to stop");
+                }
+                mRunningFullBackupTask.handleCancel(true);
+            }
+        }
+    }
+
+    // Used by both incremental and full restore
+    public void restoreWidgetData(String packageName, byte[] widgetData) {
+        // Apply the restored widget state and generate the ID update for the app
+        // TODO: http://b/22388012
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "Incorporating restored widget data");
+        }
+        AppWidgetBackupBridge.restoreWidgetState(packageName, widgetData, UserHandle.USER_SYSTEM);
+    }
+
+    // *****************************
+    // NEW UNIFIED RESTORE IMPLEMENTATION
+    // *****************************
+
+    public void dataChangedImpl(String packageName) {
+        HashSet<String> targets = dataChangedTargets(packageName);
+        dataChangedImpl(packageName, targets);
+    }
+
+    private void dataChangedImpl(String packageName, HashSet<String> targets) {
+        // Record that we need a backup pass for the caller.  Since multiple callers
+        // may share a uid, we need to note all candidates within that uid and schedule
+        // a backup pass for each of them.
+        if (targets == null) {
+            Slog.w(TAG, "dataChanged but no participant pkg='" + packageName + "'"
+                    + " uid=" + Binder.getCallingUid());
+            return;
+        }
+
+        synchronized (mQueueLock) {
+            // Note that this client has made data changes that need to be backed up
+            if (targets.contains(packageName)) {
+                // Add the caller to the set of pending backups.  If there is
+                // one already there, then overwrite it, but no harm done.
+                BackupRequest req = new BackupRequest(packageName);
+                if (mPendingBackups.put(packageName, req) == null) {
+                    if (MORE_DEBUG) Slog.d(TAG, "Now staging backup of " + packageName);
+
+                    // Journal this request in case of crash.  The put()
+                    // operation returned null when this package was not already
+                    // in the set; we want to avoid touching the disk redundantly.
+                    writeToJournalLocked(packageName);
+                }
+            }
+        }
+
+        // ...and schedule a backup pass if necessary
+        KeyValueBackupJob.schedule(mContext);
+    }
+
+    // Note: packageName is currently unused, but may be in the future
+    private HashSet<String> dataChangedTargets(String packageName) {
+        // If the caller does not hold the BACKUP permission, it can only request a
+        // backup of its own data.
+        if ((mContext.checkPermission(android.Manifest.permission.BACKUP, Binder.getCallingPid(),
+                Binder.getCallingUid())) == PackageManager.PERMISSION_DENIED) {
+            synchronized (mBackupParticipants) {
+                return mBackupParticipants.get(Binder.getCallingUid());
+            }
+        }
+
+        // a caller with full permission can ask to back up any participating app
+        HashSet<String> targets = new HashSet<>();
+        if (PACKAGE_MANAGER_SENTINEL.equals(packageName)) {
+            targets.add(PACKAGE_MANAGER_SENTINEL);
+        } else {
+            synchronized (mBackupParticipants) {
+                int N = mBackupParticipants.size();
+                for (int i = 0; i < N; i++) {
+                    HashSet<String> s = mBackupParticipants.valueAt(i);
+                    if (s != null) {
+                        targets.addAll(s);
+                    }
+                }
+            }
+        }
+        return targets;
+    }
+
+    private void writeToJournalLocked(String str) {
+        RandomAccessFile out = null;
+        try {
+            if (mJournal == null) mJournal = File.createTempFile("journal", null, mJournalDir);
+            out = new RandomAccessFile(mJournal, "rws");
+            out.seek(out.length());
+            out.writeUTF(str);
+        } catch (IOException e) {
+            Slog.e(TAG, "Can't write " + str + " to backup journal", e);
+            mJournal = null;
+        } finally {
+            try {
+                if (out != null) out.close();
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    // ----- IBackupManager binder interface -----
+
+    @Override
+    public void dataChanged(final String packageName) {
+        final int callingUserHandle = UserHandle.getCallingUserId();
+        if (callingUserHandle != UserHandle.USER_SYSTEM) {
+            // TODO: http://b/22388012
+            // App is running under a non-owner user profile.  For now, we do not back
+            // up data from secondary user profiles.
+            // TODO: backups for all user profiles although don't add backup for profiles
+            // without adding admin control in DevicePolicyManager.
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "dataChanged(" + packageName + ") ignored because it's user "
+                        + callingUserHandle);
+            }
+            return;
+        }
+
+        final HashSet<String> targets = dataChangedTargets(packageName);
+        if (targets == null) {
+            Slog.w(TAG, "dataChanged but no participant pkg='" + packageName + "'"
+                    + " uid=" + Binder.getCallingUid());
+            return;
+        }
+
+        mBackupHandler.post(new Runnable() {
+            public void run() {
+                dataChangedImpl(packageName, targets);
+            }
+        });
+    }
+
+    // Clear the given package's backup data from the current transport
+    @Override
+    public void clearBackupData(String transportName, String packageName) {
+        if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName + " on " + transportName);
+        PackageInfo info;
+        try {
+            info = mPackageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+        } catch (NameNotFoundException e) {
+            Slog.d(TAG, "No such package '" + packageName + "' - not clearing backup data");
+            return;
+        }
+
+        // If the caller does not hold the BACKUP permission, it can only request a
+        // wipe of its own backed-up data.
+        HashSet<String> apps;
+        if ((mContext.checkPermission(android.Manifest.permission.BACKUP, Binder.getCallingPid(),
+                Binder.getCallingUid())) == PackageManager.PERMISSION_DENIED) {
+            apps = mBackupParticipants.get(Binder.getCallingUid());
+        } else {
+            // a caller with full permission can ask to back up any participating app
+            // !!! TODO: allow data-clear of ANY app?
+            if (MORE_DEBUG) Slog.v(TAG, "Privileged caller, allowing clear of other apps");
+            apps = new HashSet<>();
+            int N = mBackupParticipants.size();
+            for (int i = 0; i < N; i++) {
+                HashSet<String> s = mBackupParticipants.valueAt(i);
+                if (s != null) {
+                    apps.addAll(s);
+                }
+            }
+        }
+
+        // Is the given app an available participant?
+        if (apps.contains(packageName)) {
+            // found it; fire off the clear request
+            if (MORE_DEBUG) Slog.v(TAG, "Found the app - running clear process");
+            mBackupHandler.removeMessages(MSG_RETRY_CLEAR);
+            synchronized (mQueueLock) {
+                final IBackupTransport transport =
+                        mTransportManager.getTransportBinder(transportName);
+                if (transport == null) {
+                    // transport is currently unavailable -- make sure to retry
+                    Message msg = mBackupHandler.obtainMessage(MSG_RETRY_CLEAR,
+                            new ClearRetryParams(transportName, packageName));
+                    mBackupHandler.sendMessageDelayed(msg, TRANSPORT_RETRY_INTERVAL);
+                    return;
+                }
+                long oldId = Binder.clearCallingIdentity();
+                mWakelock.acquire();
+                Message msg = mBackupHandler.obtainMessage(MSG_RUN_CLEAR,
+                        new ClearParams(transport, info));
+                mBackupHandler.sendMessage(msg);
+                Binder.restoreCallingIdentity(oldId);
+            }
+        }
+    }
+
+    // Run a backup pass immediately for any applications that have declared
+    // that they have pending updates.
+    @Override
+    public void backupNow() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "backupNow");
+
+        final PowerSaveState result =
+                mPowerManager.getPowerSaveState(ServiceType.KEYVALUE_BACKUP);
+        if (result.batterySaverEnabled) {
+            if (DEBUG) Slog.v(TAG, "Not running backup while in battery save mode");
+            KeyValueBackupJob.schedule(mContext);   // try again in several hours
+        } else {
+            if (DEBUG) Slog.v(TAG, "Scheduling immediate backup pass");
+            synchronized (mQueueLock) {
+                // Fire the intent that kicks off the whole shebang...
+                try {
+                    mRunBackupIntent.send();
+                } catch (PendingIntent.CanceledException e) {
+                    // should never happen
+                    Slog.e(TAG, "run-backup intent cancelled!");
+                }
+
+                // ...and cancel any pending scheduled job, because we've just superseded it
+                KeyValueBackupJob.cancel(mContext);
+            }
+        }
+    }
+
+    public boolean deviceIsProvisioned() {
+        final ContentResolver resolver = mContext.getContentResolver();
+        return (Settings.Global.getInt(resolver, Settings.Global.DEVICE_PROVISIONED, 0) != 0);
+    }
+
+    // Run a backup pass for the given packages, writing the resulting data stream
+    // to the supplied file descriptor.  This method is synchronous and does not return
+    // to the caller until the backup has been completed.
+    //
+    // This is the variant used by 'adb backup'; it requires on-screen confirmation
+    // by the user because it can be used to offload data over untrusted USB.
+    @Override
+    public void adbBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs,
+            boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem,
+            boolean compress, boolean doKeyValue, String[] pkgList) {
+        mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "adbBackup");
+
+        final int callingUserHandle = UserHandle.getCallingUserId();
+        // TODO: http://b/22388012
+        if (callingUserHandle != UserHandle.USER_SYSTEM) {
+            throw new IllegalStateException("Backup supported only for the device owner");
+        }
+
+        // Validate
+        if (!doAllApps) {
+            if (!includeShared) {
+                // If we're backing up shared data (sdcard or equivalent), then we can run
+                // without any supplied app names.  Otherwise, we'd be doing no work, so
+                // report the error.
+                if (pkgList == null || pkgList.length == 0) {
+                    throw new IllegalArgumentException(
+                            "Backup requested but neither shared nor any apps named");
+                }
+            }
+        }
+
+        long oldId = Binder.clearCallingIdentity();
+        try {
+            // Doesn't make sense to do a full backup prior to setup
+            if (!deviceIsProvisioned()) {
+                Slog.i(TAG, "Backup not supported before setup");
+                return;
+            }
+
+            if (DEBUG) {
+                Slog.v(TAG, "Requesting backup: apks=" + includeApks + " obb=" + includeObbs
+                        + " shared=" + includeShared + " all=" + doAllApps + " system="
+                        + includeSystem + " includekeyvalue=" + doKeyValue + " pkgs=" + pkgList);
+            }
+            Slog.i(TAG, "Beginning adb backup...");
+
+            AdbBackupParams params = new AdbBackupParams(fd, includeApks, includeObbs,
+                    includeShared, doWidgets, doAllApps, includeSystem, compress, doKeyValue,
+                    pkgList);
+            final int token = generateRandomIntegerToken();
+            synchronized (mAdbBackupRestoreConfirmations) {
+                mAdbBackupRestoreConfirmations.put(token, params);
+            }
+
+            // start up the confirmation UI
+            if (DEBUG) Slog.d(TAG, "Starting backup confirmation UI, token=" + token);
+            if (!startConfirmationUi(token, FullBackup.FULL_BACKUP_INTENT_ACTION)) {
+                Slog.e(TAG, "Unable to launch backup confirmation UI");
+                mAdbBackupRestoreConfirmations.delete(token);
+                return;
+            }
+
+            // make sure the screen is lit for the user interaction
+            mPowerManager.userActivity(SystemClock.uptimeMillis(),
+                    PowerManager.USER_ACTIVITY_EVENT_OTHER,
+                    0);
+
+            // start the confirmation countdown
+            startConfirmationTimeout(token, params);
+
+            // wait for the backup to be performed
+            if (DEBUG) Slog.d(TAG, "Waiting for backup completion...");
+            waitForCompletion(params);
+        } finally {
+            try {
+                fd.close();
+            } catch (IOException e) {
+                // just eat it
+            }
+            Binder.restoreCallingIdentity(oldId);
+            Slog.d(TAG, "Adb backup processing complete.");
+        }
+    }
+
+    @Override
+    public void fullTransportBackup(String[] pkgNames) {
+        mContext.enforceCallingPermission(android.Manifest.permission.BACKUP,
+                "fullTransportBackup");
+
+        final int callingUserHandle = UserHandle.getCallingUserId();
+        // TODO: http://b/22388012
+        if (callingUserHandle != UserHandle.USER_SYSTEM) {
+            throw new IllegalStateException("Restore supported only for the device owner");
+        }
+
+        if (!fullBackupAllowable(mTransportManager.getCurrentTransportBinder())) {
+            Slog.i(TAG, "Full backup not currently possible -- key/value backup not yet run?");
+        } else {
+            if (DEBUG) {
+                Slog.d(TAG, "fullTransportBackup()");
+            }
+
+            final long oldId = Binder.clearCallingIdentity();
+            try {
+                CountDownLatch latch = new CountDownLatch(1);
+                PerformFullTransportBackupTask task = new PerformFullTransportBackupTask(this, null,
+                        pkgNames, false, null, latch, null, null, false /* userInitiated */);
+                // Acquiring wakelock for PerformFullTransportBackupTask before its start.
+                mWakelock.acquire();
+                (new Thread(task, "full-transport-master")).start();
+                do {
+                    try {
+                        latch.await();
+                        break;
+                    } catch (InterruptedException e) {
+                        // Just go back to waiting for the latch to indicate completion
+                    }
+                } while (true);
+
+                // We just ran a backup on these packages, so kick them to the end of the queue
+                final long now = System.currentTimeMillis();
+                for (String pkg : pkgNames) {
+                    enqueueFullBackup(pkg, now);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(oldId);
+            }
+        }
+
+        if (DEBUG) {
+            Slog.d(TAG, "Done with full transport backup.");
+        }
+    }
+
+    @Override
+    public void adbRestore(ParcelFileDescriptor fd) {
+        mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "adbRestore");
+
+        final int callingUserHandle = UserHandle.getCallingUserId();
+        // TODO: http://b/22388012
+        if (callingUserHandle != UserHandle.USER_SYSTEM) {
+            throw new IllegalStateException("Restore supported only for the device owner");
+        }
+
+        long oldId = Binder.clearCallingIdentity();
+
+        try {
+            // Check whether the device has been provisioned -- we don't handle
+            // full restores prior to completing the setup process.
+            if (!deviceIsProvisioned()) {
+                Slog.i(TAG, "Full restore not permitted before setup");
+                return;
+            }
+
+            Slog.i(TAG, "Beginning restore...");
+
+            AdbRestoreParams params = new AdbRestoreParams(fd);
+            final int token = generateRandomIntegerToken();
+            synchronized (mAdbBackupRestoreConfirmations) {
+                mAdbBackupRestoreConfirmations.put(token, params);
+            }
+
+            // start up the confirmation UI
+            if (DEBUG) Slog.d(TAG, "Starting restore confirmation UI, token=" + token);
+            if (!startConfirmationUi(token, FullBackup.FULL_RESTORE_INTENT_ACTION)) {
+                Slog.e(TAG, "Unable to launch restore confirmation");
+                mAdbBackupRestoreConfirmations.delete(token);
+                return;
+            }
+
+            // make sure the screen is lit for the user interaction
+            mPowerManager.userActivity(SystemClock.uptimeMillis(),
+                    PowerManager.USER_ACTIVITY_EVENT_OTHER,
+                    0);
+
+            // start the confirmation countdown
+            startConfirmationTimeout(token, params);
+
+            // wait for the restore to be performed
+            if (DEBUG) Slog.d(TAG, "Waiting for restore completion...");
+            waitForCompletion(params);
+        } finally {
+            try {
+                fd.close();
+            } catch (IOException e) {
+                Slog.w(TAG, "Error trying to close fd after adb restore: " + e);
+            }
+            Binder.restoreCallingIdentity(oldId);
+            Slog.i(TAG, "adb restore processing complete.");
+        }
+    }
+
+    private boolean startConfirmationUi(int token, String action) {
+        try {
+            Intent confIntent = new Intent(action);
+            confIntent.setClassName("com.android.backupconfirm",
+                    "com.android.backupconfirm.BackupRestoreConfirmation");
+            confIntent.putExtra(FullBackup.CONF_TOKEN_INTENT_EXTRA, token);
+            confIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            mContext.startActivityAsUser(confIntent, UserHandle.SYSTEM);
+        } catch (ActivityNotFoundException e) {
+            return false;
+        }
+        return true;
+    }
+
+    private void startConfirmationTimeout(int token, AdbParams params) {
+        if (MORE_DEBUG) {
+            Slog.d(TAG, "Posting conf timeout msg after "
+                    + TIMEOUT_FULL_CONFIRMATION + " millis");
+        }
+        Message msg = mBackupHandler.obtainMessage(MSG_FULL_CONFIRMATION_TIMEOUT,
+                token, 0, params);
+        mBackupHandler.sendMessageDelayed(msg, TIMEOUT_FULL_CONFIRMATION);
+    }
+
+    private void waitForCompletion(AdbParams params) {
+        synchronized (params.latch) {
+            while (params.latch.get() == false) {
+                try {
+                    params.latch.wait();
+                } catch (InterruptedException e) { /* never interrupted */ }
+            }
+        }
+    }
+
+    public void signalAdbBackupRestoreCompletion(AdbParams params) {
+        synchronized (params.latch) {
+            params.latch.set(true);
+            params.latch.notifyAll();
+        }
+    }
+
+    // Confirm that the previously-requested full backup/restore operation can proceed.  This
+    // is used to require a user-facing disclosure about the operation.
+    @Override
+    public void acknowledgeAdbBackupOrRestore(int token, boolean allow,
+            String curPassword, String encPpassword, IFullBackupRestoreObserver observer) {
+        if (DEBUG) {
+            Slog.d(TAG, "acknowledgeAdbBackupOrRestore : token=" + token
+                    + " allow=" + allow);
+        }
+
+        // TODO: possibly require not just this signature-only permission, but even
+        // require that the specific designated confirmation-UI app uid is the caller?
+        mContext.enforceCallingPermission(android.Manifest.permission.BACKUP,
+                "acknowledgeAdbBackupOrRestore");
+
+        long oldId = Binder.clearCallingIdentity();
+        try {
+
+            AdbParams params;
+            synchronized (mAdbBackupRestoreConfirmations) {
+                params = mAdbBackupRestoreConfirmations.get(token);
+                if (params != null) {
+                    mBackupHandler.removeMessages(MSG_FULL_CONFIRMATION_TIMEOUT, params);
+                    mAdbBackupRestoreConfirmations.delete(token);
+
+                    if (allow) {
+                        final int verb = params instanceof AdbBackupParams
+                                ? MSG_RUN_ADB_BACKUP
+                                : MSG_RUN_ADB_RESTORE;
+
+                        params.observer = observer;
+                        params.curPassword = curPassword;
+
+                        params.encryptPassword = encPpassword;
+
+                        if (MORE_DEBUG) Slog.d(TAG, "Sending conf message with verb " + verb);
+                        mWakelock.acquire();
+                        Message msg = mBackupHandler.obtainMessage(verb, params);
+                        mBackupHandler.sendMessage(msg);
+                    } else {
+                        Slog.w(TAG, "User rejected full backup/restore operation");
+                        // indicate completion without having actually transferred any data
+                        signalAdbBackupRestoreCompletion(params);
+                    }
+                } else {
+                    Slog.w(TAG, "Attempted to ack full backup/restore with invalid token");
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(oldId);
+        }
+    }
+
+    private static boolean backupSettingMigrated(int userId) {
+        File base = new File(Environment.getDataDirectory(), "backup");
+        File enableFile = new File(base, BACKUP_ENABLE_FILE);
+        return enableFile.exists();
+    }
+
+    private static boolean readBackupEnableState(int userId) {
+        File base = new File(Environment.getDataDirectory(), "backup");
+        File enableFile = new File(base, BACKUP_ENABLE_FILE);
+        if (enableFile.exists()) {
+            try (FileInputStream fin = new FileInputStream(enableFile)) {
+                int state = fin.read();
+                return state != 0;
+            } catch (IOException e) {
+                // can't read the file; fall through to assume disabled
+                Slog.e(TAG, "Cannot read enable state; assuming disabled");
+            }
+        } else {
+            if (DEBUG) {
+                Slog.i(TAG, "isBackupEnabled() => false due to absent settings file");
+            }
+        }
+        return false;
+    }
+
+    private static void writeBackupEnableState(boolean enable, int userId) {
+        File base = new File(Environment.getDataDirectory(), "backup");
+        File enableFile = new File(base, BACKUP_ENABLE_FILE);
+        File stage = new File(base, BACKUP_ENABLE_FILE + "-stage");
+        FileOutputStream fout = null;
+        try {
+            fout = new FileOutputStream(stage);
+            fout.write(enable ? 1 : 0);
+            fout.close();
+            stage.renameTo(enableFile);
+            // will be synced immediately by the try-with-resources call to close()
+        } catch (IOException | RuntimeException e) {
+            // Whoops; looks like we're doomed.  Roll everything out, disabled,
+            // including the legacy state.
+            Slog.e(TAG, "Unable to record backup enable state; reverting to disabled: "
+                    + e.getMessage());
+
+            final ContentResolver r = sInstance.mContext.getContentResolver();
+            Settings.Secure.putStringForUser(r,
+                    Settings.Secure.BACKUP_ENABLED, null, userId);
+            enableFile.delete();
+            stage.delete();
+        } finally {
+            IoUtils.closeQuietly(fout);
+        }
+    }
+
+    // Enable/disable backups
+    @Override
+    public void setBackupEnabled(boolean enable) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "setBackupEnabled");
+
+        Slog.i(TAG, "Backup enabled => " + enable);
+
+        long oldId = Binder.clearCallingIdentity();
+        try {
+            boolean wasEnabled = mEnabled;
+            synchronized (this) {
+                writeBackupEnableState(enable, UserHandle.USER_SYSTEM);
+                mEnabled = enable;
+            }
+
+            synchronized (mQueueLock) {
+                if (enable && !wasEnabled && mProvisioned) {
+                    // if we've just been enabled, start scheduling backup passes
+                    KeyValueBackupJob.schedule(mContext);
+                    scheduleNextFullBackupJob(0);
+                } else if (!enable) {
+                    // No longer enabled, so stop running backups
+                    if (MORE_DEBUG) Slog.i(TAG, "Opting out of backup");
+
+                    KeyValueBackupJob.cancel(mContext);
+
+                    // This also constitutes an opt-out, so we wipe any data for
+                    // this device from the backend.  We start that process with
+                    // an alarm in order to guarantee wakelock states.
+                    if (wasEnabled && mProvisioned) {
+                        // NOTE: we currently flush every registered transport, not just
+                        // the currently-active one.
+                        String[] allTransports = mTransportManager.getBoundTransportNames();
+                        // build the set of transports for which we are posting an init
+                        for (String transport : allTransports) {
+                            recordInitPendingLocked(true, transport);
+                        }
+                        mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
+                                mRunInitIntent);
+                    }
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(oldId);
+        }
+    }
+
+    // Enable/disable automatic restore of app data at install time
+    @Override
+    public void setAutoRestore(boolean doAutoRestore) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "setAutoRestore");
+
+        Slog.i(TAG, "Auto restore => " + doAutoRestore);
+
+        final long oldId = Binder.clearCallingIdentity();
+        try {
+            synchronized (this) {
+                Settings.Secure.putInt(mContext.getContentResolver(),
+                        Settings.Secure.BACKUP_AUTO_RESTORE, doAutoRestore ? 1 : 0);
+                mAutoRestore = doAutoRestore;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(oldId);
+        }
+    }
+
+    // Mark the backup service as having been provisioned
+    @Override
+    public void setBackupProvisioned(boolean available) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "setBackupProvisioned");
+        /*
+         * This is now a no-op; provisioning is simply the device's own setup state.
+         */
+    }
+
+    // Report whether the backup mechanism is currently enabled
+    @Override
+    public boolean isBackupEnabled() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "isBackupEnabled");
+        return mEnabled;    // no need to synchronize just to read it
+    }
+
+    // Report the name of the currently active transport
+    @Override
+    public String getCurrentTransport() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "getCurrentTransport");
+        String currentTransport = mTransportManager.getCurrentTransportName();
+        if (MORE_DEBUG) Slog.v(TAG, "... getCurrentTransport() returning " + currentTransport);
+        return currentTransport;
+    }
+
+    // Report all known, available backup transports
+    @Override
+    public String[] listAllTransports() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "listAllTransports");
+
+        return mTransportManager.getBoundTransportNames();
+    }
+
+    @Override
+    public ComponentName[] listAllTransportComponents() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "listAllTransportComponents");
+        return mTransportManager.getAllTransportCompenents();
+    }
+
+    @Override
+    public String[] getTransportWhitelist() {
+        // No permission check, intentionally.
+        Set<ComponentName> whitelistedComponents = mTransportManager.getTransportWhitelist();
+        String[] whitelistedTransports = new String[whitelistedComponents.size()];
+        int i = 0;
+        for (ComponentName component : whitelistedComponents) {
+            whitelistedTransports[i] = component.flattenToShortString();
+            i++;
+        }
+        return whitelistedTransports;
+    }
+
+    // Select which transport to use for the next backup operation.
+    @Override
+    public String selectBackupTransport(String transport) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "selectBackupTransport");
+
+        final long oldId = Binder.clearCallingIdentity();
+        try {
+            String prevTransport = mTransportManager.selectTransport(transport);
+            Settings.Secure.putString(mContext.getContentResolver(),
+                    Settings.Secure.BACKUP_TRANSPORT, transport);
+            Slog.v(TAG, "selectBackupTransport() set " + mTransportManager.getCurrentTransportName()
+                    + " returning " + prevTransport);
+            return prevTransport;
+        } finally {
+            Binder.restoreCallingIdentity(oldId);
+        }
+    }
+
+    @Override
+    public void selectBackupTransportAsync(final ComponentName transport,
+            final ISelectBackupTransportCallback listener) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "selectBackupTransportAsync");
+
+        final long oldId = Binder.clearCallingIdentity();
+
+        Slog.v(TAG, "selectBackupTransportAsync() called with transport " +
+                transport.flattenToShortString());
+
+        mTransportManager.ensureTransportReady(transport, new SelectBackupTransportCallback() {
+            @Override
+            public void onSuccess(String transportName) {
+                mTransportManager.selectTransport(transportName);
+                Settings.Secure.putString(mContext.getContentResolver(),
+                        Settings.Secure.BACKUP_TRANSPORT,
+                        mTransportManager.getCurrentTransportName());
+                Slog.v(TAG, "Transport successfully selected: " + transport.flattenToShortString());
+                try {
+                    listener.onSuccess(transportName);
+                } catch (RemoteException e) {
+                    // Nothing to do here.
+                }
+            }
+
+            @Override
+            public void onFailure(int reason) {
+                Slog.v(TAG, "Failed to select transport: " + transport.flattenToShortString());
+                try {
+                    listener.onFailure(reason);
+                } catch (RemoteException e) {
+                    // Nothing to do here.
+                }
+            }
+        });
+
+        Binder.restoreCallingIdentity(oldId);
+    }
+
+    // Supply the configuration Intent for the given transport.  If the name is not one
+    // of the available transports, or if the transport does not supply any configuration
+    // UI, the method returns null.
+    @Override
+    public Intent getConfigurationIntent(String transportName) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "getConfigurationIntent");
+
+        final IBackupTransport transport = mTransportManager.getTransportBinder(transportName);
+        if (transport != null) {
+            try {
+                final Intent intent = transport.configurationIntent();
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "getConfigurationIntent() returning config intent "
+                            + intent);
+                }
+                return intent;
+            } catch (Exception e) {
+                /* fall through to return null */
+                Slog.e(TAG, "Unable to get configuration intent from transport: " + e.getMessage());
+            }
+        }
+
+        return null;
+    }
+
+    // Supply the configuration summary string for the given transport.  If the name is
+    // not one of the available transports, or if the transport does not supply any
+    // summary / destination string, the method can return null.
+    //
+    // This string is used VERBATIM as the summary text of the relevant Settings item!
+    @Override
+    public String getDestinationString(String transportName) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "getDestinationString");
+
+        final IBackupTransport transport = mTransportManager.getTransportBinder(transportName);
+        if (transport != null) {
+            try {
+                final String text = transport.currentDestinationString();
+                if (MORE_DEBUG) Slog.d(TAG, "getDestinationString() returning " + text);
+                return text;
+            } catch (Exception e) {
+                /* fall through to return null */
+                Slog.e(TAG, "Unable to get string from transport: " + e.getMessage());
+            }
+        }
+
+        return null;
+    }
+
+    // Supply the manage-data intent for the given transport.
+    @Override
+    public Intent getDataManagementIntent(String transportName) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "getDataManagementIntent");
+
+        final IBackupTransport transport = mTransportManager.getTransportBinder(transportName);
+        if (transport != null) {
+            try {
+                final Intent intent = transport.dataManagementIntent();
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "getDataManagementIntent() returning intent "
+                            + intent);
+                }
+                return intent;
+            } catch (Exception e) {
+                /* fall through to return null */
+                Slog.e(TAG, "Unable to get management intent from transport: " + e.getMessage());
+            }
+        }
+
+        return null;
+    }
+
+    // Supply the menu label for affordances that fire the manage-data intent
+    // for the given transport.
+    @Override
+    public String getDataManagementLabel(String transportName) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "getDataManagementLabel");
+
+        final IBackupTransport transport = mTransportManager.getTransportBinder(transportName);
+        if (transport != null) {
+            try {
+                final String text = transport.dataManagementLabel();
+                if (MORE_DEBUG) Slog.d(TAG, "getDataManagementLabel() returning " + text);
+                return text;
+            } catch (Exception e) {
+                /* fall through to return null */
+                Slog.e(TAG, "Unable to get management label from transport: " + e.getMessage());
+            }
+        }
+
+        return null;
+    }
+
+    // Callback: a requested backup agent has been instantiated.  This should only
+    // be called from the Activity Manager.
+    @Override
+    public void agentConnected(String packageName, IBinder agentBinder) {
+        synchronized (mAgentConnectLock) {
+            if (Binder.getCallingUid() == Process.SYSTEM_UID) {
+                Slog.d(TAG, "agentConnected pkg=" + packageName + " agent=" + agentBinder);
+                IBackupAgent agent = IBackupAgent.Stub.asInterface(agentBinder);
+                mConnectedAgent = agent;
+                mConnecting = false;
+            } else {
+                Slog.w(TAG, "Non-system process uid=" + Binder.getCallingUid()
+                        + " claiming agent connected");
+            }
+            mAgentConnectLock.notifyAll();
+        }
+    }
+
+    // Callback: a backup agent has failed to come up, or has unexpectedly quit.
+    // If the agent failed to come up in the first place, the agentBinder argument
+    // will be null.  This should only be called from the Activity Manager.
+    @Override
+    public void agentDisconnected(String packageName) {
+        // TODO: handle backup being interrupted
+        synchronized (mAgentConnectLock) {
+            if (Binder.getCallingUid() == Process.SYSTEM_UID) {
+                mConnectedAgent = null;
+                mConnecting = false;
+            } else {
+                Slog.w(TAG, "Non-system process uid=" + Binder.getCallingUid()
+                        + " claiming agent disconnected");
+            }
+            mAgentConnectLock.notifyAll();
+        }
+    }
+
+    // An application being installed will need a restore pass, then the Package Manager
+    // will need to be told when the restore is finished.
+    @Override
+    public void restoreAtInstall(String packageName, int token) {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            Slog.w(TAG, "Non-system process uid=" + Binder.getCallingUid()
+                    + " attemping install-time restore");
+            return;
+        }
+
+        boolean skip = false;
+
+        long restoreSet = getAvailableRestoreToken(packageName);
+        if (DEBUG) {
+            Slog.v(TAG, "restoreAtInstall pkg=" + packageName
+                    + " token=" + Integer.toHexString(token)
+                    + " restoreSet=" + Long.toHexString(restoreSet));
+        }
+        if (restoreSet == 0) {
+            if (MORE_DEBUG) Slog.i(TAG, "No restore set");
+            skip = true;
+        }
+
+        // Do we have a transport to fetch data for us?
+        IBackupTransport transport = mTransportManager.getCurrentTransportBinder();
+        if (transport == null) {
+            if (DEBUG) Slog.w(TAG, "No transport");
+            skip = true;
+        }
+
+        if (!mAutoRestore) {
+            if (DEBUG) {
+                Slog.w(TAG, "Non-restorable state: auto=" + mAutoRestore);
+            }
+            skip = true;
+        }
+
+        if (!skip) {
+            try {
+                // okay, we're going to attempt a restore of this package from this restore set.
+                // The eventual message back into the Package Manager to run the post-install
+                // steps for 'token' will be issued from the restore handling code.
+
+                // This can throw and so *must* happen before the wakelock is acquired
+                String dirName = transport.transportDirName();
+
+                mWakelock.acquire();
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Restore at install of " + packageName);
+                }
+                Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
+                msg.obj = new RestoreParams(transport, dirName, null, null,
+                        restoreSet, packageName, token);
+                mBackupHandler.sendMessage(msg);
+            } catch (Exception e) {
+                // Calling into the transport broke; back off and proceed with the installation.
+                Slog.e(TAG, "Unable to contact transport: " + e.getMessage());
+                skip = true;
+            }
+        }
+
+        if (skip) {
+            // Auto-restore disabled or no way to attempt a restore; just tell the Package
+            // Manager to proceed with the post-install handling for this package.
+            if (DEBUG) Slog.v(TAG, "Finishing install immediately");
+            try {
+                mPackageManagerBinder.finishPackageInstall(token, false);
+            } catch (RemoteException e) { /* can't happen */ }
+        }
+    }
+
+    // Hand off a restore session
+    @Override
+    public IRestoreSession beginRestoreSession(String packageName, String transport) {
+        if (DEBUG) {
+            Slog.v(TAG, "beginRestoreSession: pkg=" + packageName
+                    + " transport=" + transport);
+        }
+
+        boolean needPermission = true;
+        if (transport == null) {
+            transport = mTransportManager.getCurrentTransportName();
+
+            if (packageName != null) {
+                PackageInfo app = null;
+                try {
+                    app = mPackageManager.getPackageInfo(packageName, 0);
+                } catch (NameNotFoundException nnf) {
+                    Slog.w(TAG, "Asked to restore nonexistent pkg " + packageName);
+                    throw new IllegalArgumentException("Package " + packageName + " not found");
+                }
+
+                if (app.applicationInfo.uid == Binder.getCallingUid()) {
+                    // So: using the current active transport, and the caller has asked
+                    // that its own package will be restored.  In this narrow use case
+                    // we do not require the caller to hold the permission.
+                    needPermission = false;
+                }
+            }
+        }
+
+        if (needPermission) {
+            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                    "beginRestoreSession");
+        } else {
+            if (DEBUG) Slog.d(TAG, "restoring self on current transport; no permission needed");
+        }
+
+        synchronized (this) {
+            if (mActiveRestoreSession != null) {
+                Slog.i(TAG, "Restore session requested but one already active");
+                return null;
+            }
+            if (mBackupRunning) {
+                Slog.i(TAG, "Restore session requested but currently running backups");
+                return null;
+            }
+            mActiveRestoreSession = new ActiveRestoreSession(this, packageName, transport);
+            mBackupHandler.sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT,
+                    TIMEOUT_RESTORE_INTERVAL);
+        }
+        return mActiveRestoreSession;
+    }
+
+    public void clearRestoreSession(ActiveRestoreSession currentSession) {
+        synchronized (this) {
+            if (currentSession != mActiveRestoreSession) {
+                Slog.e(TAG, "ending non-current restore session");
+            } else {
+                if (DEBUG) Slog.v(TAG, "Clearing restore session and halting timeout");
+                mActiveRestoreSession = null;
+                mBackupHandler.removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
+            }
+        }
+    }
+
+    // Note that a currently-active backup agent has notified us that it has
+    // completed the given outstanding asynchronous backup/restore operation.
+    @Override
+    public void opComplete(int token, long result) {
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "opComplete: " + Integer.toHexString(token) + " result=" + result);
+        }
+        Operation op = null;
+        synchronized (mCurrentOpLock) {
+            op = mCurrentOperations.get(token);
+            if (op != null) {
+                if (op.state == OP_TIMEOUT) {
+                    // The operation already timed out, and this is a late response.  Tidy up
+                    // and ignore it; we've already dealt with the timeout.
+                    op = null;
+                    mCurrentOperations.delete(token);
+                } else if (op.state == OP_ACKNOWLEDGED) {
+                    if (DEBUG) {
+                        Slog.w(TAG, "Received duplicate ack for token=" +
+                                Integer.toHexString(token));
+                    }
+                    op = null;
+                    mCurrentOperations.remove(token);
+                } else if (op.state == OP_PENDING) {
+                    // Can't delete op from mCurrentOperations. waitUntilOperationComplete can be
+                    // called after we we receive this call.
+                    op.state = OP_ACKNOWLEDGED;
+                }
+            }
+            mCurrentOpLock.notifyAll();
+        }
+
+        // The completion callback, if any, is invoked on the handler
+        if (op != null && op.callback != null) {
+            Pair<BackupRestoreTask, Long> callbackAndResult = Pair.create(op.callback, result);
+            Message msg = mBackupHandler.obtainMessage(MSG_OP_COMPLETE, callbackAndResult);
+            mBackupHandler.sendMessage(msg);
+        }
+    }
+
+    // We also avoid backups of 'disabled' apps
+    private static boolean appIsDisabled(ApplicationInfo app, PackageManager pm) {
+        switch (pm.getApplicationEnabledSetting(app.packageName)) {
+            case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
+            case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
+            case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    public boolean isAppEligibleForBackup(String packageName) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "isAppEligibleForBackup");
+        try {
+            PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName,
+                    PackageManager.GET_SIGNATURES);
+            if (!AppBackupUtils.appIsEligibleForBackup(packageInfo.applicationInfo) ||
+                    AppBackupUtils.appIsStopped(packageInfo.applicationInfo) ||
+                    appIsDisabled(packageInfo.applicationInfo, mPackageManager)) {
+                return false;
+            }
+            IBackupTransport transport = mTransportManager.getCurrentTransportBinder();
+            if (transport != null) {
+                try {
+                    return transport.isAppEligibleForBackup(packageInfo,
+                            AppBackupUtils.appGetsFullBackup(packageInfo));
+                } catch (Exception e) {
+                    Slog.e(TAG, "Unable to ask about eligibility: " + e.getMessage());
+                }
+            }
+            // If transport is not present we couldn't tell that the package is not eligible.
+            return true;
+        } catch (NameNotFoundException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
+
+        long identityToken = Binder.clearCallingIdentity();
+        try {
+            if (args != null) {
+                for (String arg : args) {
+                    if ("-h".equals(arg)) {
+                        pw.println("'dumpsys backup' optional arguments:");
+                        pw.println("  -h       : this help text");
+                        pw.println("  a[gents] : dump information about defined backup agents");
+                        return;
+                    } else if ("agents".startsWith(arg)) {
+                        dumpAgents(pw);
+                        return;
+                    }
+                }
+            }
+            dumpInternal(pw);
+        } finally {
+            Binder.restoreCallingIdentity(identityToken);
+        }
+    }
+
+    private void dumpAgents(PrintWriter pw) {
+        List<PackageInfo> agentPackages = allAgentPackages();
+        pw.println("Defined backup agents:");
+        for (PackageInfo pkg : agentPackages) {
+            pw.print("  ");
+            pw.print(pkg.packageName);
+            pw.println(':');
+            pw.print("      ");
+            pw.println(pkg.applicationInfo.backupAgentName);
+        }
+    }
+
+    private void dumpInternal(PrintWriter pw) {
+        synchronized (mQueueLock) {
+            pw.println("Backup Manager is " + (mEnabled ? "enabled" : "disabled")
+                    + " / " + (!mProvisioned ? "not " : "") + "provisioned / "
+                    + (this.mPendingInits.size() == 0 ? "not " : "") + "pending init");
+            pw.println("Auto-restore is " + (mAutoRestore ? "enabled" : "disabled"));
+            if (mBackupRunning) pw.println("Backup currently running");
+            pw.println("Last backup pass started: " + mLastBackupPass
+                    + " (now = " + System.currentTimeMillis() + ')');
+            pw.println("  next scheduled: " + KeyValueBackupJob.nextScheduled());
+
+            pw.println("Transport whitelist:");
+            for (ComponentName transport : mTransportManager.getTransportWhitelist()) {
+                pw.print("    ");
+                pw.println(transport.flattenToShortString());
+            }
+
+            pw.println("Available transports:");
+            final String[] transports = listAllTransports();
+            if (transports != null) {
+                for (String t : listAllTransports()) {
+                    pw.println((t.equals(mTransportManager.getCurrentTransportName()) ? "  * "
+                            : "    ") + t);
+                    try {
+                        IBackupTransport transport = mTransportManager.getTransportBinder(t);
+                        File dir = new File(mBaseStateDir, transport.transportDirName());
+                        pw.println("       destination: " + transport.currentDestinationString());
+                        pw.println("       intent: " + transport.configurationIntent());
+                        for (File f : dir.listFiles()) {
+                            pw.println(
+                                    "       " + f.getName() + " - " + f.length() + " state bytes");
+                        }
+                    } catch (Exception e) {
+                        Slog.e(TAG, "Error in transport", e);
+                        pw.println("        Error: " + e);
+                    }
+                }
+            }
+
+            pw.println("Pending init: " + mPendingInits.size());
+            for (String s : mPendingInits) {
+                pw.println("    " + s);
+            }
+
+            if (DEBUG_BACKUP_TRACE) {
+                synchronized (mBackupTrace) {
+                    if (!mBackupTrace.isEmpty()) {
+                        pw.println("Most recent backup trace:");
+                        for (String s : mBackupTrace) {
+                            pw.println("   " + s);
+                        }
+                    }
+                }
+            }
+
+            pw.print("Ancestral: ");
+            pw.println(Long.toHexString(mAncestralToken));
+            pw.print("Current:   ");
+            pw.println(Long.toHexString(mCurrentToken));
+
+            int N = mBackupParticipants.size();
+            pw.println("Participants:");
+            for (int i = 0; i < N; i++) {
+                int uid = mBackupParticipants.keyAt(i);
+                pw.print("  uid: ");
+                pw.println(uid);
+                HashSet<String> participants = mBackupParticipants.valueAt(i);
+                for (String app : participants) {
+                    pw.println("    " + app);
+                }
+            }
+
+            pw.println("Ancestral packages: "
+                    + (mAncestralPackages == null ? "none" : mAncestralPackages.size()));
+            if (mAncestralPackages != null) {
+                for (String pkg : mAncestralPackages) {
+                    pw.println("    " + pkg);
+                }
+            }
+
+            pw.println("Ever backed up: " + mEverStoredApps.size());
+            for (String pkg : mEverStoredApps) {
+                pw.println("    " + pkg);
+            }
+
+            pw.println("Pending key/value backup: " + mPendingBackups.size());
+            for (BackupRequest req : mPendingBackups.values()) {
+                pw.println("    " + req);
+            }
+
+            pw.println("Full backup queue:" + mFullBackupQueue.size());
+            for (FullBackupEntry entry : mFullBackupQueue) {
+                pw.print("    ");
+                pw.print(entry.lastBackup);
+                pw.print(" : ");
+                pw.println(entry.packageName);
+            }
+        }
+    }
+
+
+    @Override
+    public IBackupManager getBackupManagerBinder() {
+        return mBackupManagerBinder;
+    }
+
+}
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index aafa88a..9e7a29e 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -34,6 +34,7 @@
 import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.Slog;
 
 import com.android.internal.util.DumpUtils;
@@ -43,6 +44,22 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 
+
+/**
+ * A proxy to BackupManagerService implementation.
+ *
+ * This is an external interface to the BackupManagerService which is being accessed via published
+ * binder (see BackupManagerService$Lifecycle). This lets us turn down the heavy implementation
+ * object on the fly without disturbing binders that have been cached somewhere in the system.
+ *
+ * This is where it is decided whether backup subsystem is available. It can be disabled with the
+ * following two methods:
+ *
+ * <ul>
+ * <li> Temporarily - create a file named Trampoline.BACKUP_SUPPRESS_FILENAME, or
+ * <li> Product level - set Trampoline.BACKUP_DISABLE_PROPERTY system property to true.
+ * </ul>
+ */
 public class Trampoline extends IBackupManager.Stub {
     static final String TAG = "BackupManagerService";
     static final boolean DEBUG_TRAMPOLINE = false;
@@ -56,14 +73,49 @@
     final Context mContext;
     final File mSuppressFile;   // existence testing & creating synchronized on 'this'
     final boolean mGlobalDisable;
-    volatile BackupManagerService mService;
+    volatile BackupManagerServiceInterface mService;
 
     public Trampoline(Context context) {
         mContext = context;
-        File dir = new File(Environment.getDataDirectory(), "backup");
-        dir.mkdirs();
-        mSuppressFile = new File(dir, BACKUP_SUPPRESS_FILENAME);
-        mGlobalDisable = SystemProperties.getBoolean(BACKUP_DISABLE_PROPERTY, false);
+        mGlobalDisable = isBackupDisabled();
+        mSuppressFile = getSuppressFile();
+        mSuppressFile.getParentFile().mkdirs();
+    }
+
+    protected BackupManagerServiceInterface createService() {
+        if (isRefactoredServiceEnabled()) {
+            Slog.i(TAG, "Instantiating RefactoredBackupManagerService");
+            return createRefactoredBackupManagerService();
+        }
+
+        Slog.i(TAG, "Instantiating BackupManagerService");
+        return createBackupManagerService();
+    }
+
+    protected boolean isBackupDisabled() {
+        return SystemProperties.getBoolean(BACKUP_DISABLE_PROPERTY, false);
+    }
+
+    protected boolean isRefactoredServiceEnabled() {
+        return Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.BACKUP_REFACTORED_SERVICE_DISABLED, 1) == 0;
+    }
+
+    protected int binderGetCallingUid() {
+        return Binder.getCallingUid();
+    }
+
+    protected File getSuppressFile() {
+        return new File(new File(Environment.getDataDirectory(), "backup"),
+                BACKUP_SUPPRESS_FILENAME);
+    }
+
+    protected BackupManagerServiceInterface createRefactoredBackupManagerService() {
+        return new RefactoredBackupManagerService(mContext, this);
+    }
+
+    protected BackupManagerServiceInterface createBackupManagerService() {
+        return new BackupManagerService(mContext, this);
     }
 
     // internal control API
@@ -79,7 +131,7 @@
 
             synchronized (this) {
                 if (!mSuppressFile.exists()) {
-                    mService = new BackupManagerService(mContext, this);
+                    mService = createService();
                 } else {
                     Slog.i(TAG, "Backup inactive in user " + whichUser);
                 }
@@ -89,7 +141,7 @@
 
     public void setBackupServiceActive(final int userHandle, boolean makeActive) {
         // Only the DPM should be changing the active state of backup
-        final int caller = Binder.getCallingUid();
+        final int caller = binderGetCallingUid();
         if (caller != Process.SYSTEM_UID
                 && caller != Process.ROOT_UID) {
             throw new SecurityException("No permission to configure backup activity");
@@ -106,7 +158,7 @@
                     Slog.i(TAG, "Making backup "
                             + (makeActive ? "" : "in") + "active in user " + userHandle);
                     if (makeActive) {
-                        mService = new BackupManagerService(mContext, this);
+                        mService = createService();
                         mSuppressFile.delete();
                     } else {
                         mService = null;
@@ -140,7 +192,7 @@
     // IBackupManager binder API
     @Override
     public void dataChanged(String packageName) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.dataChanged(packageName);
         }
@@ -149,7 +201,7 @@
     @Override
     public void clearBackupData(String transportName, String packageName)
             throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.clearBackupData(transportName, packageName);
         }
@@ -157,7 +209,7 @@
 
     @Override
     public void agentConnected(String packageName, IBinder agent) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.agentConnected(packageName, agent);
         }
@@ -165,7 +217,7 @@
 
     @Override
     public void agentDisconnected(String packageName) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.agentDisconnected(packageName);
         }
@@ -173,7 +225,7 @@
 
     @Override
     public void restoreAtInstall(String packageName, int token) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.restoreAtInstall(packageName, token);
         }
@@ -181,7 +233,7 @@
 
     @Override
     public void setBackupEnabled(boolean isEnabled) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.setBackupEnabled(isEnabled);
         }
@@ -189,7 +241,7 @@
 
     @Override
     public void setAutoRestore(boolean doAutoRestore) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.setAutoRestore(doAutoRestore);
         }
@@ -197,7 +249,7 @@
 
     @Override
     public void setBackupProvisioned(boolean isProvisioned) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.setBackupProvisioned(isProvisioned);
         }
@@ -205,25 +257,25 @@
 
     @Override
     public boolean isBackupEnabled() throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.isBackupEnabled() : false;
     }
 
     @Override
     public boolean setBackupPassword(String currentPw, String newPw) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.setBackupPassword(currentPw, newPw) : false;
     }
 
     @Override
     public boolean hasBackupPassword() throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.hasBackupPassword() : false;
     }
 
     @Override
     public void backupNow() throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.backupNow();
         }
@@ -234,7 +286,7 @@
             boolean includeShared, boolean doWidgets, boolean allApps,
             boolean allIncludesSystem, boolean doCompress, boolean doKeyValue, String[] packageNames)
                     throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.adbBackup(fd, includeApks, includeObbs, includeShared, doWidgets,
                     allApps, allIncludesSystem, doCompress, doKeyValue, packageNames);
@@ -243,7 +295,7 @@
 
     @Override
     public void fullTransportBackup(String[] packageNames) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.fullTransportBackup(packageNames);
         }
@@ -251,7 +303,7 @@
 
     @Override
     public void adbRestore(ParcelFileDescriptor fd) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.adbRestore(fd);
         }
@@ -261,7 +313,7 @@
     public void acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword,
             String encryptionPassword, IFullBackupRestoreObserver observer)
                     throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.acknowledgeAdbBackupOrRestore(token, allow,
                     curPassword, encryptionPassword, observer);
@@ -270,38 +322,38 @@
 
     @Override
     public String getCurrentTransport() throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.getCurrentTransport() : null;
     }
 
     @Override
     public String[] listAllTransports() throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.listAllTransports() : null;
     }
 
     @Override
     public ComponentName[] listAllTransportComponents() throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.listAllTransportComponents() : null;
     }
 
     @Override
     public String[] getTransportWhitelist() {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.getTransportWhitelist() : null;
     }
 
     @Override
     public String selectBackupTransport(String transport) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.selectBackupTransport(transport) : null;
     }
 
     @Override
     public void selectBackupTransportAsync(ComponentName transport,
             ISelectBackupTransportCallback listener) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.selectBackupTransportAsync(transport, listener);
         } else {
@@ -309,7 +361,7 @@
                 try {
                     listener.onFailure(BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                 } catch (RemoteException ex) {
-                    // Ignore
+                    // ignore
                 }
             }
         }
@@ -317,38 +369,38 @@
 
     @Override
     public Intent getConfigurationIntent(String transport) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.getConfigurationIntent(transport) : null;
     }
 
     @Override
     public String getDestinationString(String transport) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.getDestinationString(transport) : null;
     }
 
     @Override
     public Intent getDataManagementIntent(String transport) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.getDataManagementIntent(transport) : null;
     }
 
     @Override
     public String getDataManagementLabel(String transport) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.getDataManagementLabel(transport) : null;
     }
 
     @Override
     public IRestoreSession beginRestoreSession(String packageName, String transportID)
             throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.beginRestoreSession(packageName, transportID) : null;
     }
 
     @Override
     public void opComplete(int token, long result) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.opComplete(token, result);
         }
@@ -356,20 +408,20 @@
 
     @Override
     public long getAvailableRestoreToken(String packageName) {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.getAvailableRestoreToken(packageName) : 0;
     }
 
     @Override
     public boolean isAppEligibleForBackup(String packageName) {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.isAppEligibleForBackup(packageName) : false;
     }
 
     @Override
     public int requestBackup(String[] packages, IBackupObserver observer,
             IBackupManagerMonitor monitor, int flags) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc == null) {
             return BackupManager.ERROR_BACKUP_NOT_ALLOWED;
         }
@@ -378,7 +430,7 @@
 
     @Override
     public void cancelBackups() throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.cancelBackups();
         }
@@ -388,7 +440,7 @@
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.dump(fd, pw, args);
         } else {
@@ -399,12 +451,12 @@
     // Full backup/restore entry points - non-Binder; called directly
     // by the full-backup scheduled job
     /* package */ boolean beginFullBackup(FullBackupJob scheduledJob) {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.beginFullBackup(scheduledJob) : false;
     }
 
     /* package */ void endFullBackup() {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.endFullBackup();
         }
diff --git a/services/backup/java/com/android/server/backup/TransportManager.java b/services/backup/java/com/android/server/backup/TransportManager.java
index da1f32c..fb2982e 100644
--- a/services/backup/java/com/android/server/backup/TransportManager.java
+++ b/services/backup/java/com/android/server/backup/TransportManager.java
@@ -53,7 +53,7 @@
 /**
  * Handles in-memory bookkeeping of all BackupTransport objects.
  */
-class TransportManager {
+public class TransportManager {
 
     private static final String TAG = "BackupTransportManager";
 
@@ -149,7 +149,7 @@
         }
     }
 
-    IBackupTransport getTransportBinder(String transportName) {
+    public IBackupTransport getTransportBinder(String transportName) {
         synchronized (mTransportLock) {
             ComponentName component = mBoundTransports.get(transportName);
             if (component == null) {
@@ -165,11 +165,11 @@
         }
     }
 
-    IBackupTransport getCurrentTransportBinder() {
+    public IBackupTransport getCurrentTransportBinder() {
         return getTransportBinder(mCurrentTransportName);
     }
 
-    String getTransportName(IBackupTransport binder) {
+    public String getTransportName(IBackupTransport binder) {
         synchronized (mTransportLock) {
             for (TransportConnection conn : mValidTransports.values()) {
                 if (conn.getBinder() == binder) {
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
new file mode 100644
index 0000000..3bf77e8
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.fullbackup;
+
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_WIDGET_METADATA_TOKEN;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+import static com.android.server.backup.RefactoredBackupManagerService
+        .TIMEOUT_SHARED_BACKUP_INTERVAL;
+
+import android.app.ApplicationThreadConstants;
+import android.app.IBackupAgent;
+import android.app.backup.BackupTransport;
+import android.app.backup.FullBackup;
+import android.app.backup.FullBackupDataOutput;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.os.Environment.UserEnvironment;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.Slog;
+import android.util.StringBuilderPrinter;
+
+import com.android.server.AppWidgetBackupBridge;
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.utils.FullBackupUtils;
+
+import java.io.BufferedOutputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Core logic for performing one package's full backup, gathering the tarball from the
+ * application and emitting it to the designated OutputStream.
+ */
+public class FullBackupEngine {
+
+    private RefactoredBackupManagerService backupManagerService;
+    OutputStream mOutput;
+    FullBackupPreflight mPreflightHook;
+    BackupRestoreTask mTimeoutMonitor;
+    IBackupAgent mAgent;
+    File mFilesDir;
+    File mManifestFile;
+    File mMetadataFile;
+    boolean mIncludeApks;
+    PackageInfo mPkg;
+    private final long mQuota;
+    private final int mOpToken;
+
+    class FullBackupRunner implements Runnable {
+
+        PackageInfo mPackage;
+        byte[] mWidgetData;
+        IBackupAgent mAgent;
+        ParcelFileDescriptor mPipe;
+        int mToken;
+        boolean mSendApk;
+        boolean mWriteManifest;
+
+        FullBackupRunner(PackageInfo pack, IBackupAgent agent, ParcelFileDescriptor pipe,
+                int token, boolean sendApk, boolean writeManifest, byte[] widgetData)
+                throws IOException {
+            mPackage = pack;
+            mWidgetData = widgetData;
+            mAgent = agent;
+            mPipe = ParcelFileDescriptor.dup(pipe.getFileDescriptor());
+            mToken = token;
+            mSendApk = sendApk;
+            mWriteManifest = writeManifest;
+        }
+
+        @Override
+        public void run() {
+            try {
+                FullBackupDataOutput output = new FullBackupDataOutput(mPipe);
+
+                if (mWriteManifest) {
+                    final boolean writeWidgetData = mWidgetData != null;
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Writing manifest for " + mPackage.packageName);
+                    }
+                    FullBackupUtils
+                            .writeAppManifest(mPackage, backupManagerService.getPackageManager(),
+                                    mManifestFile, mSendApk,
+                                    writeWidgetData);
+                    FullBackup.backupToTar(mPackage.packageName, null, null,
+                            mFilesDir.getAbsolutePath(),
+                            mManifestFile.getAbsolutePath(),
+                            output);
+                    mManifestFile.delete();
+
+                    // We only need to write a metadata file if we have widget data to stash
+                    if (writeWidgetData) {
+                        writeMetadata(mPackage, mMetadataFile, mWidgetData);
+                        FullBackup.backupToTar(mPackage.packageName, null, null,
+                                mFilesDir.getAbsolutePath(),
+                                mMetadataFile.getAbsolutePath(),
+                                output);
+                        mMetadataFile.delete();
+                    }
+                }
+
+                if (mSendApk) {
+                    writeApkToBackup(mPackage, output);
+                }
+
+                final boolean isSharedStorage =
+                        mPackage.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
+                final long timeout = isSharedStorage ?
+                        TIMEOUT_SHARED_BACKUP_INTERVAL :
+                        TIMEOUT_FULL_BACKUP_INTERVAL;
+
+                if (DEBUG) {
+                    Slog.d(TAG, "Calling doFullBackup() on " + mPackage.packageName);
+                }
+                backupManagerService
+                        .prepareOperationTimeout(mToken,
+                                timeout,
+                                mTimeoutMonitor /* in parent class */,
+                                OP_TYPE_BACKUP_WAIT);
+                mAgent.doFullBackup(mPipe, mQuota, mToken,
+                        backupManagerService.getBackupManagerBinder());
+            } catch (IOException e) {
+                Slog.e(TAG, "Error running full backup for " + mPackage.packageName);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote agent vanished during full backup of " + mPackage.packageName);
+            } finally {
+                try {
+                    mPipe.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    public FullBackupEngine(RefactoredBackupManagerService backupManagerService,
+            OutputStream output,
+            FullBackupPreflight preflightHook, PackageInfo pkg,
+            boolean alsoApks, BackupRestoreTask timeoutMonitor, long quota, int opToken) {
+        this.backupManagerService = backupManagerService;
+        mOutput = output;
+        mPreflightHook = preflightHook;
+        mPkg = pkg;
+        mIncludeApks = alsoApks;
+        mTimeoutMonitor = timeoutMonitor;
+        mFilesDir = new File("/data/system");
+        mManifestFile = new File(mFilesDir, BACKUP_MANIFEST_FILENAME);
+        mMetadataFile = new File(mFilesDir, BACKUP_METADATA_FILENAME);
+        mQuota = quota;
+        mOpToken = opToken;
+    }
+
+    public int preflightCheck() throws RemoteException {
+        if (mPreflightHook == null) {
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "No preflight check");
+            }
+            return BackupTransport.TRANSPORT_OK;
+        }
+        if (initializeAgent()) {
+            int result = mPreflightHook.preflightFullBackup(mPkg, mAgent);
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "preflight returned " + result);
+            }
+            return result;
+        } else {
+            Slog.w(TAG, "Unable to bind to full agent for " + mPkg.packageName);
+            return BackupTransport.AGENT_ERROR;
+        }
+    }
+
+    public int backupOnePackage() throws RemoteException {
+        int result = BackupTransport.AGENT_ERROR;
+
+        if (initializeAgent()) {
+            ParcelFileDescriptor[] pipes = null;
+            try {
+                pipes = ParcelFileDescriptor.createPipe();
+
+                ApplicationInfo app = mPkg.applicationInfo;
+                final boolean isSharedStorage =
+                        mPkg.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
+                final boolean sendApk = mIncludeApks
+                        && !isSharedStorage
+                        && ((app.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) == 0)
+                        && ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 0 ||
+                        (app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
+
+                // TODO: http://b/22388012
+                byte[] widgetBlob = AppWidgetBackupBridge.getWidgetState(mPkg.packageName,
+                        UserHandle.USER_SYSTEM);
+
+                FullBackupRunner runner = new FullBackupRunner(mPkg, mAgent, pipes[1],
+                        mOpToken, sendApk, !isSharedStorage, widgetBlob);
+                pipes[1].close();   // the runner has dup'd it
+                pipes[1] = null;
+                Thread t = new Thread(runner, "app-data-runner");
+                t.start();
+
+                // Now pull data from the app and stuff it into the output
+                FullBackupUtils.routeSocketDataToOutput(pipes[0], mOutput);
+
+                if (!backupManagerService.waitUntilOperationComplete(mOpToken)) {
+                    Slog.e(TAG, "Full backup failed on package " + mPkg.packageName);
+                } else {
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Full package backup success: " + mPkg.packageName);
+                    }
+                    result = BackupTransport.TRANSPORT_OK;
+                }
+            } catch (IOException e) {
+                Slog.e(TAG, "Error backing up " + mPkg.packageName + ": " + e.getMessage());
+                result = BackupTransport.AGENT_ERROR;
+            } finally {
+                try {
+                    // flush after every package
+                    mOutput.flush();
+                    if (pipes != null) {
+                        if (pipes[0] != null) {
+                            pipes[0].close();
+                        }
+                        if (pipes[1] != null) {
+                            pipes[1].close();
+                        }
+                    }
+                } catch (IOException e) {
+                    Slog.w(TAG, "Error bringing down backup stack");
+                    result = BackupTransport.TRANSPORT_ERROR;
+                }
+            }
+        } else {
+            Slog.w(TAG, "Unable to bind to full agent for " + mPkg.packageName);
+        }
+        tearDown();
+        return result;
+    }
+
+    public void sendQuotaExceeded(final long backupDataBytes, final long quotaBytes) {
+        if (initializeAgent()) {
+            try {
+                mAgent.doQuotaExceeded(backupDataBytes, quotaBytes);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception while telling agent about quota exceeded");
+            }
+        }
+    }
+
+    private boolean initializeAgent() {
+        if (mAgent == null) {
+            if (MORE_DEBUG) {
+                Slog.d(TAG, "Binding to full backup agent : " + mPkg.packageName);
+            }
+            mAgent = backupManagerService.bindToAgentSynchronous(mPkg.applicationInfo,
+                    ApplicationThreadConstants.BACKUP_MODE_FULL);
+        }
+        return mAgent != null;
+    }
+
+    private void writeApkToBackup(PackageInfo pkg, FullBackupDataOutput output) {
+        // Forward-locked apps, system-bundled .apks, etc are filtered out before we get here
+        // TODO: handle backing up split APKs
+        final String appSourceDir = pkg.applicationInfo.getBaseCodePath();
+        final String apkDir = new File(appSourceDir).getParent();
+        FullBackup.backupToTar(pkg.packageName, FullBackup.APK_TREE_TOKEN, null,
+                apkDir, appSourceDir, output);
+
+        // TODO: migrate this to SharedStorageBackup, since AID_SYSTEM
+        // doesn't have access to external storage.
+
+        // Save associated .obb content if it exists and we did save the apk
+        // check for .obb and save those too
+        // TODO: http://b/22388012
+        final UserEnvironment userEnv = new UserEnvironment(UserHandle.USER_SYSTEM);
+        final File obbDir = userEnv.buildExternalStorageAppObbDirs(pkg.packageName)[0];
+        if (obbDir != null) {
+            if (MORE_DEBUG) {
+                Log.i(TAG, "obb dir: " + obbDir.getAbsolutePath());
+            }
+            File[] obbFiles = obbDir.listFiles();
+            if (obbFiles != null) {
+                final String obbDirName = obbDir.getAbsolutePath();
+                for (File obb : obbFiles) {
+                    FullBackup.backupToTar(pkg.packageName, FullBackup.OBB_TREE_TOKEN, null,
+                            obbDirName, obb.getAbsolutePath(), output);
+                }
+            }
+        }
+    }
+
+    // Widget metadata format. All header entries are strings ending in LF:
+    //
+    // Version 1 header:
+    //     BACKUP_METADATA_VERSION, currently "1"
+    //     package name
+    //
+    // File data (all integers are binary in network byte order)
+    // *N: 4 : integer token identifying which metadata blob
+    //     4 : integer size of this blob = N
+    //     N : raw bytes of this metadata blob
+    //
+    // Currently understood blobs (always in network byte order):
+    //
+    //     widgets : metadata token = 0x01FFED01 (BACKUP_WIDGET_METADATA_TOKEN)
+    //
+    // Unrecognized blobs are *ignored*, not errors.
+    private void writeMetadata(PackageInfo pkg, File destination, byte[] widgetData)
+            throws IOException {
+        StringBuilder b = new StringBuilder(512);
+        StringBuilderPrinter printer = new StringBuilderPrinter(b);
+        printer.println(Integer.toString(BACKUP_METADATA_VERSION));
+        printer.println(pkg.packageName);
+
+        FileOutputStream fout = new FileOutputStream(destination);
+        BufferedOutputStream bout = new BufferedOutputStream(fout);
+        DataOutputStream out = new DataOutputStream(bout);
+        bout.write(b.toString().getBytes());    // bypassing DataOutputStream
+
+        if (widgetData != null && widgetData.length > 0) {
+            out.writeInt(BACKUP_WIDGET_METADATA_TOKEN);
+            out.writeInt(widgetData.length);
+            out.write(widgetData);
+        }
+        bout.flush();
+        out.close();
+
+        // As with the manifest file, guarantee idempotence of the archive metadata
+        // for the widget block by using a fixed mtime on the transient file.
+        destination.setLastModified(0);
+    }
+
+    private void tearDown() {
+        if (mPkg != null) {
+            backupManagerService.tearDownAgentAndKill(mPkg.applicationInfo);
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEntry.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEntry.java
new file mode 100644
index 0000000..a62f1c0
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEntry.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.fullbackup;
+
+public class FullBackupEntry implements Comparable<FullBackupEntry> {
+
+    public String packageName;
+    public long lastBackup;
+
+    public FullBackupEntry(String pkg, long when) {
+        packageName = pkg;
+        lastBackup = when;
+    }
+
+    @Override
+    public int compareTo(FullBackupEntry other) {
+        if (lastBackup < other.lastBackup) {
+            return -1;
+        } else if (lastBackup > other.lastBackup) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
new file mode 100644
index 0000000..da8a66a
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.fullbackup;
+
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+
+import android.app.backup.IBackupManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageInfo;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.backup.IObbBackupService;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.utils.FullBackupUtils;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Full backup/restore to a file/socket.
+ */
+public class FullBackupObbConnection implements ServiceConnection {
+
+    private RefactoredBackupManagerService backupManagerService;
+    volatile IObbBackupService mService;
+
+    public FullBackupObbConnection(RefactoredBackupManagerService backupManagerService) {
+        this.backupManagerService = backupManagerService;
+        mService = null;
+    }
+
+    public void establish() {
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "Initiating bind of OBB service on " + this);
+        }
+        Intent obbIntent = new Intent().setComponent(new ComponentName(
+                "com.android.sharedstoragebackup",
+                "com.android.sharedstoragebackup.ObbBackupService"));
+        backupManagerService.getContext().bindServiceAsUser(
+                obbIntent, this, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
+    }
+
+    public void tearDown() {
+        backupManagerService.getContext().unbindService(this);
+    }
+
+    public boolean backupObbs(PackageInfo pkg, OutputStream out) {
+        boolean success = false;
+        waitForConnection();
+
+        ParcelFileDescriptor[] pipes = null;
+        try {
+            pipes = ParcelFileDescriptor.createPipe();
+            int token = backupManagerService.generateRandomIntegerToken();
+            backupManagerService.prepareOperationTimeout(
+                    token, TIMEOUT_FULL_BACKUP_INTERVAL, null, OP_TYPE_BACKUP_WAIT);
+            mService.backupObbs(pkg.packageName, pipes[1], token,
+                    backupManagerService.getBackupManagerBinder());
+            FullBackupUtils.routeSocketDataToOutput(pipes[0], out);
+            success = backupManagerService.waitUntilOperationComplete(token);
+        } catch (Exception e) {
+            Slog.w(TAG, "Unable to back up OBBs for " + pkg, e);
+        } finally {
+            try {
+                out.flush();
+                if (pipes != null) {
+                    if (pipes[0] != null) {
+                        pipes[0].close();
+                    }
+                    if (pipes[1] != null) {
+                        pipes[1].close();
+                    }
+                }
+            } catch (IOException e) {
+                Slog.w(TAG, "I/O error closing down OBB backup", e);
+            }
+        }
+        return success;
+    }
+
+    public void restoreObbFile(String pkgName, ParcelFileDescriptor data,
+            long fileSize, int type, String path, long mode, long mtime,
+            int token, IBackupManager callbackBinder) {
+        waitForConnection();
+
+        try {
+            mService.restoreObbFile(pkgName, data, fileSize, type, path, mode, mtime,
+                    token, callbackBinder);
+        } catch (Exception e) {
+            Slog.w(TAG, "Unable to restore OBBs for " + pkgName, e);
+        }
+    }
+
+    private void waitForConnection() {
+        synchronized (this) {
+            while (mService == null) {
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "...waiting for OBB service binding...");
+                }
+                try {
+                    this.wait();
+                } catch (InterruptedException e) { /* never interrupted */ }
+            }
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Connected to OBB service; continuing");
+            }
+        }
+    }
+
+    @Override
+    public void onServiceConnected(ComponentName name, IBinder service) {
+        synchronized (this) {
+            mService = IObbBackupService.Stub.asInterface(service);
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "OBB service connection " + mService + " connected on " + this);
+            }
+            this.notifyAll();
+        }
+    }
+
+    @Override
+    public void onServiceDisconnected(ComponentName name) {
+        synchronized (this) {
+            mService = null;
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "OBB service connection disconnected on " + this);
+            }
+            this.notifyAll();
+        }
+    }
+
+}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupPreflight.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupPreflight.java
new file mode 100644
index 0000000..f12587f
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupPreflight.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.fullbackup;
+
+import android.app.IBackupAgent;
+import android.content.pm.PackageInfo;
+
+/**
+ * Callout from the engine to an interested participant that might need to communicate with the
+ * agent prior to asking it to move data.
+ */
+public interface FullBackupPreflight {
+
+    /**
+     * Perform the preflight operation necessary for the given package.
+     *
+     * @param pkg The name of the package being proposed for full-data backup
+     * @param agent Live BackupAgent binding to the target app's agent
+     * @return BackupTransport.TRANSPORT_OK to proceed with the backup operation, or one of the
+     * other BackupTransport.* error codes as appropriate
+     */
+    int preflightFullBackup(PackageInfo pkg, IBackupAgent agent);
+
+    long getExpectedSizeOrErrorCode();
+}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupTask.java
new file mode 100644
index 0000000..37961f9
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupTask.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.fullbackup;
+
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.backup.IFullBackupRestoreObserver;
+import android.os.RemoteException;
+import android.util.Slog;
+
+/**
+ * Generic driver skeleton for full backup operations.
+ */
+public abstract class FullBackupTask implements Runnable {
+
+    IFullBackupRestoreObserver mObserver;
+
+    FullBackupTask(IFullBackupRestoreObserver observer) {
+        mObserver = observer;
+    }
+
+    // wrappers for observer use
+    final void sendStartBackup() {
+        if (mObserver != null) {
+            try {
+                mObserver.onStartBackup();
+            } catch (RemoteException e) {
+                Slog.w(TAG, "full backup observer went away: startBackup");
+                mObserver = null;
+            }
+        }
+    }
+
+    final void sendOnBackupPackage(String name) {
+        if (mObserver != null) {
+            try {
+                // TODO: use a more user-friendly name string
+                mObserver.onBackupPackage(name);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "full backup observer went away: backupPackage");
+                mObserver = null;
+            }
+        }
+    }
+
+    final void sendEndBackup() {
+        if (mObserver != null) {
+            try {
+                mObserver.onEndBackup();
+            } catch (RemoteException e) {
+                Slog.w(TAG, "full backup observer went away: endBackup");
+                mObserver = null;
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
new file mode 100644
index 0000000..007d930
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.fullbackup;
+
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_FILE_HEADER_MAGIC;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_FILE_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.PBKDF_CURRENT;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.backup.IFullBackupRestoreObserver;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.server.AppWidgetBackupBridge;
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.KeyValueAdbBackupEngine;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.utils.AppBackupUtils;
+import com.android.server.backup.utils.PasswordUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherOutputStream;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Full backup task variant used for adb backup.
+ */
+public class PerformAdbBackupTask extends FullBackupTask implements BackupRestoreTask {
+
+    private RefactoredBackupManagerService backupManagerService;
+    FullBackupEngine mBackupEngine;
+    final AtomicBoolean mLatch;
+
+    ParcelFileDescriptor mOutputFile;
+    DeflaterOutputStream mDeflater;
+    boolean mIncludeApks;
+    boolean mIncludeObbs;
+    boolean mIncludeShared;
+    boolean mDoWidgets;
+    boolean mAllApps;
+    boolean mIncludeSystem;
+    boolean mCompress;
+    boolean mKeyValue;
+    ArrayList<String> mPackages;
+    PackageInfo mCurrentTarget;
+    String mCurrentPassword;
+    String mEncryptPassword;
+    private final int mCurrentOpToken;
+
+    public PerformAdbBackupTask(RefactoredBackupManagerService backupManagerService,
+            ParcelFileDescriptor fd, IFullBackupRestoreObserver observer,
+            boolean includeApks, boolean includeObbs, boolean includeShared, boolean doWidgets,
+            String curPassword, String encryptPassword, boolean doAllApps, boolean doSystem,
+            boolean doCompress, boolean doKeyValue, String[] packages, AtomicBoolean latch) {
+        super(observer);
+        this.backupManagerService = backupManagerService;
+        mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
+        mLatch = latch;
+
+        mOutputFile = fd;
+        mIncludeApks = includeApks;
+        mIncludeObbs = includeObbs;
+        mIncludeShared = includeShared;
+        mDoWidgets = doWidgets;
+        mAllApps = doAllApps;
+        mIncludeSystem = doSystem;
+        mPackages = (packages == null)
+                ? new ArrayList<String>()
+                : new ArrayList<>(Arrays.asList(packages));
+        mCurrentPassword = curPassword;
+        // when backing up, if there is a current backup password, we require that
+        // the user use a nonempty encryption password as well.  if one is supplied
+        // in the UI we use that, but if the UI was left empty we fall back to the
+        // current backup password (which was supplied by the user as well).
+        if (encryptPassword == null || "".equals(encryptPassword)) {
+            mEncryptPassword = curPassword;
+        } else {
+            mEncryptPassword = encryptPassword;
+        }
+        if (MORE_DEBUG) {
+            Slog.w(TAG, "Encrypting backup with passphrase=" + mEncryptPassword);
+        }
+        mCompress = doCompress;
+        mKeyValue = doKeyValue;
+    }
+
+    void addPackagesToSet(TreeMap<String, PackageInfo> set, List<String> pkgNames) {
+        for (String pkgName : pkgNames) {
+            if (!set.containsKey(pkgName)) {
+                try {
+                    PackageInfo info = backupManagerService.getPackageManager().getPackageInfo(
+                            pkgName,
+                            PackageManager.GET_SIGNATURES);
+                    set.put(pkgName, info);
+                } catch (NameNotFoundException e) {
+                    Slog.w(TAG, "Unknown package " + pkgName + ", skipping");
+                }
+            }
+        }
+    }
+
+    private OutputStream emitAesBackupHeader(StringBuilder headerbuf,
+            OutputStream ofstream) throws Exception {
+        // User key will be used to encrypt the master key.
+        byte[] newUserSalt = backupManagerService
+                .randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);
+        SecretKey userKey = PasswordUtils
+                .buildPasswordKey(PBKDF_CURRENT, mEncryptPassword,
+                        newUserSalt,
+                        PasswordUtils.PBKDF2_HASH_ROUNDS);
+
+        // the master key is random for each backup
+        byte[] masterPw = new byte[256 / 8];
+        backupManagerService.getRng().nextBytes(masterPw);
+        byte[] checksumSalt = backupManagerService
+                .randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);
+
+        // primary encryption of the datastream with the random key
+        Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
+        SecretKeySpec masterKeySpec = new SecretKeySpec(masterPw, "AES");
+        c.init(Cipher.ENCRYPT_MODE, masterKeySpec);
+        OutputStream finalOutput = new CipherOutputStream(ofstream, c);
+
+        // line 4: name of encryption algorithm
+        headerbuf.append(PasswordUtils.ENCRYPTION_ALGORITHM_NAME);
+        headerbuf.append('\n');
+        // line 5: user password salt [hex]
+        headerbuf.append(PasswordUtils.byteArrayToHex(newUserSalt));
+        headerbuf.append('\n');
+        // line 6: master key checksum salt [hex]
+        headerbuf.append(PasswordUtils.byteArrayToHex(checksumSalt));
+        headerbuf.append('\n');
+        // line 7: number of PBKDF2 rounds used [decimal]
+        headerbuf.append(PasswordUtils.PBKDF2_HASH_ROUNDS);
+        headerbuf.append('\n');
+
+        // line 8: IV of the user key [hex]
+        Cipher mkC = Cipher.getInstance("AES/CBC/PKCS5Padding");
+        mkC.init(Cipher.ENCRYPT_MODE, userKey);
+
+        byte[] IV = mkC.getIV();
+        headerbuf.append(PasswordUtils.byteArrayToHex(IV));
+        headerbuf.append('\n');
+
+        // line 9: master IV + key blob, encrypted by the user key [hex].  Blob format:
+        //    [byte] IV length = Niv
+        //    [array of Niv bytes] IV itself
+        //    [byte] master key length = Nmk
+        //    [array of Nmk bytes] master key itself
+        //    [byte] MK checksum hash length = Nck
+        //    [array of Nck bytes] master key checksum hash
+        //
+        // The checksum is the (master key + checksum salt), run through the
+        // stated number of PBKDF2 rounds
+        IV = c.getIV();
+        byte[] mk = masterKeySpec.getEncoded();
+        byte[] checksum = PasswordUtils
+                .makeKeyChecksum(PBKDF_CURRENT,
+                        masterKeySpec.getEncoded(),
+                        checksumSalt, PasswordUtils.PBKDF2_HASH_ROUNDS);
+
+        ByteArrayOutputStream blob = new ByteArrayOutputStream(IV.length + mk.length
+                + checksum.length + 3);
+        DataOutputStream mkOut = new DataOutputStream(blob);
+        mkOut.writeByte(IV.length);
+        mkOut.write(IV);
+        mkOut.writeByte(mk.length);
+        mkOut.write(mk);
+        mkOut.writeByte(checksum.length);
+        mkOut.write(checksum);
+        mkOut.flush();
+        byte[] encryptedMk = mkC.doFinal(blob.toByteArray());
+        headerbuf.append(PasswordUtils.byteArrayToHex(encryptedMk));
+        headerbuf.append('\n');
+
+        return finalOutput;
+    }
+
+    private void finalizeBackup(OutputStream out) {
+        try {
+            // A standard 'tar' EOF sequence: two 512-byte blocks of all zeroes.
+            byte[] eof = new byte[512 * 2]; // newly allocated == zero filled
+            out.write(eof);
+        } catch (IOException e) {
+            Slog.w(TAG, "Error attempting to finalize backup stream");
+        }
+    }
+
+    @Override
+    public void run() {
+        String includeKeyValue = mKeyValue ? ", including key-value backups" : "";
+        Slog.i(TAG, "--- Performing adb backup" + includeKeyValue + " ---");
+
+        TreeMap<String, PackageInfo> packagesToBackup = new TreeMap<>();
+        FullBackupObbConnection obbConnection = new FullBackupObbConnection(
+                backupManagerService);
+        obbConnection.establish();  // we'll want this later
+
+        sendStartBackup();
+
+        // doAllApps supersedes the package set if any
+        if (mAllApps) {
+            List<PackageInfo> allPackages =
+                    backupManagerService.getPackageManager().getInstalledPackages(
+                            PackageManager.GET_SIGNATURES);
+            for (int i = 0; i < allPackages.size(); i++) {
+                PackageInfo pkg = allPackages.get(i);
+                // Exclude system apps if we've been asked to do so
+                if (mIncludeSystem == true
+                        || ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0)) {
+                    packagesToBackup.put(pkg.packageName, pkg);
+                }
+            }
+        }
+
+        // If we're doing widget state as well, ensure that we have all the involved
+        // host & provider packages in the set
+        if (mDoWidgets) {
+            // TODO: http://b/22388012
+            List<String> pkgs =
+                    AppWidgetBackupBridge.getWidgetParticipants(UserHandle.USER_SYSTEM);
+            if (pkgs != null) {
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "Adding widget participants to backup set:");
+                    StringBuilder sb = new StringBuilder(128);
+                    sb.append("   ");
+                    for (String s : pkgs) {
+                        sb.append(' ');
+                        sb.append(s);
+                    }
+                    Slog.i(TAG, sb.toString());
+                }
+                addPackagesToSet(packagesToBackup, pkgs);
+            }
+        }
+
+        // Now process the command line argument packages, if any. Note that explicitly-
+        // named system-partition packages will be included even if includeSystem was
+        // set to false.
+        if (mPackages != null) {
+            addPackagesToSet(packagesToBackup, mPackages);
+        }
+
+        // Now we cull any inapplicable / inappropriate packages from the set.  This
+        // includes the special shared-storage agent package; we handle that one
+        // explicitly at the end of the backup pass. Packages supporting key-value backup are
+        // added to their own queue, and handled after packages supporting fullbackup.
+        ArrayList<PackageInfo> keyValueBackupQueue = new ArrayList<>();
+        Iterator<Entry<String, PackageInfo>> iter = packagesToBackup.entrySet().iterator();
+        while (iter.hasNext()) {
+            PackageInfo pkg = iter.next().getValue();
+            if (!AppBackupUtils.appIsEligibleForBackup(pkg.applicationInfo)
+                    || AppBackupUtils.appIsStopped(pkg.applicationInfo)) {
+                iter.remove();
+                if (DEBUG) {
+                    Slog.i(TAG, "Package " + pkg.packageName
+                            + " is not eligible for backup, removing.");
+                }
+            } else if (AppBackupUtils.appIsKeyValueOnly(pkg)) {
+                iter.remove();
+                if (DEBUG) {
+                    Slog.i(TAG, "Package " + pkg.packageName
+                            + " is key-value.");
+                }
+                keyValueBackupQueue.add(pkg);
+            }
+        }
+
+        // flatten the set of packages now so we can explicitly control the ordering
+        ArrayList<PackageInfo> backupQueue =
+                new ArrayList<>(packagesToBackup.values());
+        FileOutputStream ofstream = new FileOutputStream(mOutputFile.getFileDescriptor());
+        OutputStream out = null;
+
+        PackageInfo pkg = null;
+        try {
+            boolean encrypting = (mEncryptPassword != null && mEncryptPassword.length() > 0);
+
+            // Only allow encrypted backups of encrypted devices
+            if (backupManagerService.deviceIsEncrypted() && !encrypting) {
+                Slog.e(TAG, "Unencrypted backup of encrypted device; aborting");
+                return;
+            }
+
+            OutputStream finalOutput = ofstream;
+
+            // Verify that the given password matches the currently-active
+            // backup password, if any
+            if (!backupManagerService.backupPasswordMatches(mCurrentPassword)) {
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup password mismatch; aborting");
+                }
+                return;
+            }
+
+            // Write the global file header.  All strings are UTF-8 encoded; lines end
+            // with a '\n' byte.  Actual backup data begins immediately following the
+            // final '\n'.
+            //
+            // line 1: "ANDROID BACKUP"
+            // line 2: backup file format version, currently "5"
+            // line 3: compressed?  "0" if not compressed, "1" if compressed.
+            // line 4: name of encryption algorithm [currently only "none" or "AES-256"]
+            //
+            // When line 4 is not "none", then additional header data follows:
+            //
+            // line 5: user password salt [hex]
+            // line 6: master key checksum salt [hex]
+            // line 7: number of PBKDF2 rounds to use (same for user & master) [decimal]
+            // line 8: IV of the user key [hex]
+            // line 9: master key blob [hex]
+            //     IV of the master key, master key itself, master key checksum hash
+            //
+            // The master key checksum is the master key plus its checksum salt, run through
+            // 10k rounds of PBKDF2.  This is used to verify that the user has supplied the
+            // correct password for decrypting the archive:  the master key decrypted from
+            // the archive using the user-supplied password is also run through PBKDF2 in
+            // this way, and if the result does not match the checksum as stored in the
+            // archive, then we know that the user-supplied password does not match the
+            // archive's.
+            StringBuilder headerbuf = new StringBuilder(1024);
+
+            headerbuf.append(BACKUP_FILE_HEADER_MAGIC);
+            headerbuf.append(BACKUP_FILE_VERSION); // integer, no trailing \n
+            headerbuf.append(mCompress ? "\n1\n" : "\n0\n");
+
+            try {
+                // Set up the encryption stage if appropriate, and emit the correct header
+                if (encrypting) {
+                    finalOutput = emitAesBackupHeader(headerbuf, finalOutput);
+                } else {
+                    headerbuf.append("none\n");
+                }
+
+                byte[] header = headerbuf.toString().getBytes("UTF-8");
+                ofstream.write(header);
+
+                // Set up the compression stage feeding into the encryption stage (if any)
+                if (mCompress) {
+                    Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION);
+                    finalOutput = new DeflaterOutputStream(finalOutput, deflater, true);
+                }
+
+                out = finalOutput;
+            } catch (Exception e) {
+                // Should never happen!
+                Slog.e(TAG, "Unable to emit archive header", e);
+                return;
+            }
+
+            // Shared storage if requested
+            if (mIncludeShared) {
+                try {
+                    pkg = backupManagerService.getPackageManager().getPackageInfo(
+                            SHARED_BACKUP_AGENT_PACKAGE, 0);
+                    backupQueue.add(pkg);
+                } catch (NameNotFoundException e) {
+                    Slog.e(TAG, "Unable to find shared-storage backup handler");
+                }
+            }
+
+            // Now actually run the constructed backup sequence for full backup
+            int N = backupQueue.size();
+            for (int i = 0; i < N; i++) {
+                pkg = backupQueue.get(i);
+                if (DEBUG) {
+                    Slog.i(TAG, "--- Performing full backup for package " + pkg.packageName
+                            + " ---");
+                }
+                final boolean isSharedStorage =
+                        pkg.packageName.equals(
+                                SHARED_BACKUP_AGENT_PACKAGE);
+
+                mBackupEngine = new FullBackupEngine(backupManagerService, out,
+                        null, pkg, mIncludeApks, this, Long.MAX_VALUE, mCurrentOpToken);
+                sendOnBackupPackage(isSharedStorage ? "Shared storage" : pkg.packageName);
+
+                // Don't need to check preflight result as there is no preflight hook.
+                mCurrentTarget = pkg;
+                mBackupEngine.backupOnePackage();
+
+                // after the app's agent runs to handle its private filesystem
+                // contents, back up any OBB content it has on its behalf.
+                if (mIncludeObbs) {
+                    boolean obbOkay = obbConnection.backupObbs(pkg, out);
+                    if (!obbOkay) {
+                        throw new RuntimeException("Failure writing OBB stack for " + pkg);
+                    }
+                }
+            }
+            // And for key-value backup if enabled
+            if (mKeyValue) {
+                for (PackageInfo keyValuePackage : keyValueBackupQueue) {
+                    if (DEBUG) {
+                        Slog.i(TAG, "--- Performing key-value backup for package "
+                                + keyValuePackage.packageName + " ---");
+                    }
+                    KeyValueAdbBackupEngine kvBackupEngine =
+                            new KeyValueAdbBackupEngine(out, keyValuePackage,
+                                    backupManagerService,
+                                    backupManagerService.getPackageManager(),
+                                    backupManagerService.getBaseStateDir(),
+                                    backupManagerService.getDataDir());
+                    sendOnBackupPackage(keyValuePackage.packageName);
+                    kvBackupEngine.backupOnePackage();
+                }
+            }
+
+            // Done!
+            finalizeBackup(out);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "App died during full backup");
+        } catch (Exception e) {
+            Slog.e(TAG, "Internal exception during full backup", e);
+        } finally {
+            try {
+                if (out != null) {
+                    out.flush();
+                    out.close();
+                }
+                mOutputFile.close();
+            } catch (IOException e) {
+                /* nothing we can do about this */
+            }
+            synchronized (mLatch) {
+                mLatch.set(true);
+                mLatch.notifyAll();
+            }
+            sendEndBackup();
+            obbConnection.tearDown();
+            if (DEBUG) {
+                Slog.d(TAG, "Full backup pass complete.");
+            }
+            backupManagerService.getWakelock().release();
+        }
+    }
+
+    // BackupRestoreTask methods, used for timeout handling
+    @Override
+    public void execute() {
+        // Unused
+    }
+
+    @Override
+    public void operationComplete(long result) {
+        // Unused
+    }
+
+    @Override
+    public void handleCancel(boolean cancelAll) {
+        final PackageInfo target = mCurrentTarget;
+        if (DEBUG) {
+            Slog.w(TAG, "adb backup cancel of " + target);
+        }
+        if (target != null) {
+            backupManagerService.tearDownAgentAndKill(mCurrentTarget.applicationInfo);
+        }
+        backupManagerService.removeOperation(mCurrentOpToken);
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
new file mode 100644
index 0000000..0f1e485
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -0,0 +1,855 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.fullbackup;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG_SCHEDULING;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_PENDING;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+
+import android.app.IBackupAgent;
+import android.app.backup.BackupManager;
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.BackupProgress;
+import android.app.backup.BackupTransport;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
+import android.app.backup.IFullBackupRestoreObserver;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.util.EventLog;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.EventLogTags;
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.FullBackupJob;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.internal.Operation;
+import com.android.server.backup.utils.AppBackupUtils;
+import com.android.server.backup.utils.BackupManagerMonitorUtils;
+import com.android.server.backup.utils.BackupObserverUtils;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Full backup task extension used for transport-oriented operation.
+ *
+ * Flow:
+ * For each requested package:
+ *     - Spin off a new SinglePackageBackupRunner (mBackupRunner) for the current package.
+ *     - Wait until preflight is complete. (mBackupRunner.getPreflightResultBlocking())
+ *     - If preflight data size is within limit, start reading data from agent pipe and writing
+ *       to transport pipe. While there is data to send, call transport.sendBackupData(int) to
+ *       tell the transport how many bytes to expect on its pipe.
+ *     - After sending all data, call transport.finishBackup() if things went well. And
+ *       transport.cancelFullBackup() otherwise.
+ *
+ * Interactions with mCurrentOperations:
+ *     - An entry for this object is added to mCurrentOperations for the entire lifetime of this
+ *       object. Used to cancel the operation.
+ *     - SinglePackageBackupRunner and SinglePackageBackupPreflight will put ephemeral entries
+ *       to get timeouts or operation complete callbacks.
+ *
+ * Handling cancels:
+ *     - The contract we provide is that the task won't interact with the transport after
+ *       handleCancel() is done executing.
+ *     - This task blocks at 3 points: 1. Preflight result check 2. Reading on agent side pipe
+ *       and 3. Get backup result from mBackupRunner.
+ *     - Bubbling up handleCancel to mBackupRunner handles all 3: 1. Calls handleCancel on the
+ *       preflight operation which counts down on the preflight latch. 2. Tears down the agent,
+ *       so read() returns -1. 3. Notifies mCurrentOpLock which unblocks
+ *       mBackupRunner.getBackupResultBlocking().
+ */
+public class PerformFullTransportBackupTask extends FullBackupTask implements BackupRestoreTask {
+    private static final String TAG = "PFTBT";
+
+    private RefactoredBackupManagerService backupManagerService;
+    private final Object mCancelLock = new Object();
+
+    ArrayList<PackageInfo> mPackages;
+    PackageInfo mCurrentPackage;
+    boolean mUpdateSchedule;
+    CountDownLatch mLatch;
+    FullBackupJob mJob;             // if a scheduled job needs to be finished afterwards
+    IBackupObserver mBackupObserver;
+    IBackupManagerMonitor mMonitor;
+    boolean mUserInitiated;
+    private volatile IBackupTransport mTransport;
+    SinglePackageBackupRunner mBackupRunner;
+    private final int mBackupRunnerOpToken;
+
+    // This is true when a backup operation for some package is in progress.
+    private volatile boolean mIsDoingBackup;
+    private volatile boolean mCancelAll;
+    private final int mCurrentOpToken;
+
+    public PerformFullTransportBackupTask(RefactoredBackupManagerService backupManagerService,
+            IFullBackupRestoreObserver observer,
+            String[] whichPackages, boolean updateSchedule,
+            FullBackupJob runningJob, CountDownLatch latch, IBackupObserver backupObserver,
+            IBackupManagerMonitor monitor, boolean userInitiated) {
+        super(observer);
+        this.backupManagerService = backupManagerService;
+        mUpdateSchedule = updateSchedule;
+        mLatch = latch;
+        mJob = runningJob;
+        mPackages = new ArrayList<>(whichPackages.length);
+        mBackupObserver = backupObserver;
+        mMonitor = monitor;
+        mUserInitiated = userInitiated;
+        mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
+        mBackupRunnerOpToken = backupManagerService.generateRandomIntegerToken();
+
+        if (backupManagerService.isBackupOperationInProgress()) {
+            if (DEBUG) {
+                Slog.d(TAG, "Skipping full backup. A backup is already in progress.");
+            }
+            mCancelAll = true;
+            return;
+        }
+
+        registerTask();
+
+        for (String pkg : whichPackages) {
+            try {
+                PackageInfo info = backupManagerService.getPackageManager().getPackageInfo(pkg,
+                        PackageManager.GET_SIGNATURES);
+                mCurrentPackage = info;
+                if (!AppBackupUtils.appIsEligibleForBackup(info.applicationInfo)) {
+                    // Cull any packages that have indicated that backups are not permitted,
+                    // that run as system-domain uids but do not define their own backup agents,
+                    // as well as any explicit mention of the 'special' shared-storage agent
+                    // package (we handle that one at the end).
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Ignoring ineligible package " + pkg);
+                    }
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                            BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_INELIGIBLE,
+                            mCurrentPackage,
+                            BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            null);
+                    BackupObserverUtils.sendBackupOnPackageResult(mBackupObserver, pkg,
+                            BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                    continue;
+                } else if (!AppBackupUtils.appGetsFullBackup(info)) {
+                    // Cull any packages that are found in the queue but now aren't supposed
+                    // to get full-data backup operations.
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Ignoring full-data backup of key/value participant "
+                                + pkg);
+                    }
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                            BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_KEY_VALUE_PARTICIPANT,
+                            mCurrentPackage,
+                            BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            null);
+                    BackupObserverUtils.sendBackupOnPackageResult(mBackupObserver, pkg,
+                            BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                    continue;
+                } else if (AppBackupUtils.appIsStopped(info.applicationInfo)) {
+                    // Cull any packages in the 'stopped' state: they've either just been
+                    // installed or have explicitly been force-stopped by the user.  In both
+                    // cases we do not want to launch them for backup.
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Ignoring stopped package " + pkg);
+                    }
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                            BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_STOPPED,
+                            mCurrentPackage,
+                            BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            null);
+                    BackupObserverUtils.sendBackupOnPackageResult(mBackupObserver, pkg,
+                            BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                    continue;
+                }
+                mPackages.add(info);
+            } catch (NameNotFoundException e) {
+                Slog.i(TAG, "Requested package " + pkg + " not found; ignoring");
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_NOT_FOUND,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        null);
+            }
+        }
+    }
+
+    private void registerTask() {
+        synchronized (backupManagerService.getCurrentOpLock()) {
+            Slog.d(TAG, "backupmanager pftbt token=" + Integer.toHexString(mCurrentOpToken));
+            backupManagerService.getCurrentOperations().put(
+                    mCurrentOpToken,
+                    new Operation(OP_PENDING, this, OP_TYPE_BACKUP));
+        }
+    }
+
+    public void unregisterTask() {
+        backupManagerService.removeOperation(mCurrentOpToken);
+    }
+
+    @Override
+    public void execute() {
+        // Nothing to do.
+    }
+
+    @Override
+    public void handleCancel(boolean cancelAll) {
+        synchronized (mCancelLock) {
+            // We only support 'cancelAll = true' case for this task. Cancelling of a single package
+
+            // due to timeout is handled by SinglePackageBackupRunner and
+            // SinglePackageBackupPreflight.
+
+            if (!cancelAll) {
+                Slog.wtf(TAG, "Expected cancelAll to be true.");
+            }
+
+            if (mCancelAll) {
+                Slog.d(TAG, "Ignoring duplicate cancel call.");
+                return;
+            }
+
+            mCancelAll = true;
+            if (mIsDoingBackup) {
+                backupManagerService.handleCancel(mBackupRunnerOpToken, cancelAll);
+                try {
+                    mTransport.cancelFullBackup();
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Error calling cancelFullBackup() on transport: " + e);
+                    // Can't do much.
+                }
+            }
+        }
+    }
+
+    @Override
+    public void operationComplete(long result) {
+        // Nothing to do.
+    }
+
+    @Override
+    public void run() {
+
+        // data from the app, passed to us for bridging to the transport
+        ParcelFileDescriptor[] enginePipes = null;
+
+        // Pipe through which we write data to the transport
+        ParcelFileDescriptor[] transportPipes = null;
+
+        long backoff = 0;
+        int backupRunStatus = BackupManager.SUCCESS;
+
+        try {
+            if (!backupManagerService.isEnabled() || !backupManagerService.isProvisioned()) {
+                // Backups are globally disabled, so don't proceed.
+                if (DEBUG) {
+                    Slog.i(TAG, "full backup requested but enabled=" + backupManagerService
+                            .isEnabled()
+                            + " provisioned=" + backupManagerService.isProvisioned()
+                            + "; ignoring");
+                }
+                int monitoringEvent;
+                if (!backupManagerService.isEnabled()) {
+                    monitoringEvent = BackupManagerMonitor.LOG_EVENT_ID_BACKUP_DISABLED;
+                } else {
+                    monitoringEvent = BackupManagerMonitor.LOG_EVENT_ID_DEVICE_NOT_PROVISIONED;
+                }
+                mMonitor = BackupManagerMonitorUtils
+                        .monitorEvent(mMonitor, monitoringEvent, null,
+                                BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                null);
+                mUpdateSchedule = false;
+                backupRunStatus = BackupManager.ERROR_BACKUP_NOT_ALLOWED;
+                return;
+            }
+
+            mTransport = backupManagerService.getTransportManager().getCurrentTransportBinder();
+            if (mTransport == null) {
+                Slog.w(TAG, "Transport not present; full data backup not performed");
+                backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_TRANSPORT_NOT_PRESENT,
+                        mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
+                        null);
+                return;
+            }
+
+            // Set up to send data to the transport
+            final int N = mPackages.size();
+            final byte[] buffer = new byte[8192];
+            for (int i = 0; i < N; i++) {
+                PackageInfo currentPackage = mPackages.get(i);
+                String packageName = currentPackage.packageName;
+                if (DEBUG) {
+                    Slog.i(TAG, "Initiating full-data transport backup of " + packageName
+                            + " token: " + mCurrentOpToken);
+                }
+                EventLog.writeEvent(EventLogTags.FULL_BACKUP_PACKAGE, packageName);
+
+                transportPipes = ParcelFileDescriptor.createPipe();
+
+                // Tell the transport the data's coming
+                int flags = mUserInitiated ? BackupTransport.FLAG_USER_INITIATED : 0;
+                int backupPackageStatus;
+                long quota = Long.MAX_VALUE;
+                synchronized (mCancelLock) {
+                    if (mCancelAll) {
+                        break;
+                    }
+                    backupPackageStatus = mTransport.performFullBackup(currentPackage,
+                            transportPipes[0], flags);
+
+                    if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
+                        quota = mTransport.getBackupQuota(currentPackage.packageName,
+                                true /* isFullBackup */);
+                        // Now set up the backup engine / data source end of things
+                        enginePipes = ParcelFileDescriptor.createPipe();
+                        mBackupRunner =
+                                new SinglePackageBackupRunner(enginePipes[1], currentPackage,
+                                        mTransport, quota, mBackupRunnerOpToken);
+                        // The runner dup'd the pipe half, so we close it here
+                        enginePipes[1].close();
+                        enginePipes[1] = null;
+
+                        mIsDoingBackup = true;
+                    }
+                }
+                if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
+
+                    // The transport has its own copy of the read end of the pipe,
+                    // so close ours now
+                    transportPipes[0].close();
+                    transportPipes[0] = null;
+
+                    // Spin off the runner to fetch the app's data and pipe it
+                    // into the engine pipes
+                    (new Thread(mBackupRunner, "package-backup-bridge")).start();
+
+                    // Read data off the engine pipe and pass it to the transport
+                    // pipe until we hit EOD on the input stream.  We do not take
+                    // close() responsibility for these FDs into these stream wrappers.
+                    FileInputStream in = new FileInputStream(
+                            enginePipes[0].getFileDescriptor());
+                    FileOutputStream out = new FileOutputStream(
+                            transportPipes[1].getFileDescriptor());
+                    long totalRead = 0;
+                    final long preflightResult = mBackupRunner.getPreflightResultBlocking();
+                    // Preflight result is negative if some error happened on preflight.
+                    if (preflightResult < 0) {
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "Backup error after preflight of package "
+                                    + packageName + ": " + preflightResult
+                                    + ", not running backup.");
+                        }
+                        mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                                BackupManagerMonitor.LOG_EVENT_ID_ERROR_PREFLIGHT,
+                                mCurrentPackage,
+                                BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                BackupManagerMonitorUtils.putMonitoringExtra(null,
+                                        BackupManagerMonitor.EXTRA_LOG_PREFLIGHT_ERROR,
+                                        preflightResult));
+                        backupPackageStatus = (int) preflightResult;
+                    } else {
+                        int nRead = 0;
+                        do {
+                            nRead = in.read(buffer);
+                            if (MORE_DEBUG) {
+                                Slog.v(TAG, "in.read(buffer) from app: " + nRead);
+                            }
+                            if (nRead > 0) {
+                                out.write(buffer, 0, nRead);
+                                synchronized (mCancelLock) {
+                                    if (!mCancelAll) {
+                                        backupPackageStatus = mTransport.sendBackupData(nRead);
+                                    }
+                                }
+                                totalRead += nRead;
+                                if (mBackupObserver != null && preflightResult > 0) {
+                                    BackupObserverUtils
+                                            .sendBackupOnUpdate(mBackupObserver, packageName,
+                                                    new BackupProgress(preflightResult, totalRead));
+                                }
+                            }
+                        } while (nRead > 0
+                                && backupPackageStatus == BackupTransport.TRANSPORT_OK);
+                        // Despite preflight succeeded, package still can hit quota on flight.
+                        if (backupPackageStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                            Slog.w(TAG, "Package hit quota limit in-flight " + packageName
+                                    + ": " + totalRead + " of " + quota);
+                            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                                    BackupManagerMonitor.LOG_EVENT_ID_QUOTA_HIT_PREFLIGHT,
+                                    mCurrentPackage,
+                                    BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
+                                    null);
+                            mBackupRunner.sendQuotaExceeded(totalRead, quota);
+                        }
+                    }
+
+                    final int backupRunnerResult = mBackupRunner.getBackupResultBlocking();
+
+                    synchronized (mCancelLock) {
+                        mIsDoingBackup = false;
+                        // If mCancelCurrent is true, we have already called cancelFullBackup().
+                        if (!mCancelAll) {
+                            if (backupRunnerResult == BackupTransport.TRANSPORT_OK) {
+                                // If we were otherwise in a good state, now interpret the final
+                                // result based on what finishBackup() returns.  If we're in a
+                                // failure case already, preserve that result and ignore whatever
+                                // finishBackup() reports.
+                                final int finishResult = mTransport.finishBackup();
+                                if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
+                                    backupPackageStatus = finishResult;
+                                }
+                            } else {
+                                mTransport.cancelFullBackup();
+                            }
+                        }
+                    }
+
+                    // A transport-originated error here means that we've hit an error that the
+                    // runner doesn't know about, so it's still moving data but we're pulling the
+                    // rug out from under it.  Don't ask for its result:  we already know better
+                    // and we'll hang if we block waiting for it, since it relies on us to
+                    // read back the data it's writing into the engine.  Just proceed with
+                    // a graceful failure.  The runner/engine mechanism will tear itself
+                    // down cleanly when we close the pipes from this end.  Transport-level
+                    // errors take precedence over agent/app-specific errors for purposes of
+                    // determining our course of action.
+                    if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
+                        // We still could fail in backup runner thread.
+                        if (backupRunnerResult != BackupTransport.TRANSPORT_OK) {
+                            // If there was an error in runner thread and
+                            // not TRANSPORT_ERROR here, overwrite it.
+                            backupPackageStatus = backupRunnerResult;
+                        }
+                    } else {
+                        if (MORE_DEBUG) {
+                            Slog.i(TAG, "Transport-level failure; cancelling agent work");
+                        }
+                    }
+
+                    if (MORE_DEBUG) {
+                        Slog.i(TAG, "Done delivering backup data: result="
+                                + backupPackageStatus);
+                    }
+
+                    if (backupPackageStatus != BackupTransport.TRANSPORT_OK) {
+                        Slog.e(TAG, "Error " + backupPackageStatus + " backing up "
+                                + packageName);
+                    }
+
+                    // Also ask the transport how long it wants us to wait before
+                    // moving on to the next package, if any.
+                    backoff = mTransport.requestFullBackupTime();
+                    if (DEBUG_SCHEDULING) {
+                        Slog.i(TAG, "Transport suggested backoff=" + backoff);
+                    }
+
+                }
+
+                // Roll this package to the end of the backup queue if we're
+                // in a queue-driven mode (regardless of success/failure)
+                if (mUpdateSchedule) {
+                    backupManagerService.enqueueFullBackup(packageName, System.currentTimeMillis());
+                }
+
+                if (backupPackageStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mBackupObserver, packageName,
+                                    BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
+                    if (DEBUG) {
+                        Slog.i(TAG, "Transport rejected backup of " + packageName
+                                + ", skipping");
+                    }
+                    EventLog.writeEvent(EventLogTags.FULL_BACKUP_AGENT_FAILURE, packageName,
+                            "transport rejected");
+                    // Do nothing, clean up, and continue looping.
+                } else if (backupPackageStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mBackupObserver, packageName,
+                                    BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
+                    if (DEBUG) {
+                        Slog.i(TAG, "Transport quota exceeded for package: " + packageName);
+                        EventLog.writeEvent(EventLogTags.FULL_BACKUP_QUOTA_EXCEEDED,
+                                packageName);
+                    }
+                    // Do nothing, clean up, and continue looping.
+                } else if (backupPackageStatus == BackupTransport.AGENT_ERROR) {
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mBackupObserver, packageName,
+                                    BackupManager.ERROR_AGENT_FAILURE);
+                    Slog.w(TAG, "Application failure for package: " + packageName);
+                    EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
+                    backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+                    // Do nothing, clean up, and continue looping.
+                } else if (backupPackageStatus == BackupManager.ERROR_BACKUP_CANCELLED) {
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mBackupObserver, packageName,
+                                    BackupManager.ERROR_BACKUP_CANCELLED);
+                    Slog.w(TAG, "Backup cancelled. package=" + packageName +
+                            ", cancelAll=" + mCancelAll);
+                    EventLog.writeEvent(EventLogTags.FULL_BACKUP_CANCELLED, packageName);
+                    backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+                    // Do nothing, clean up, and continue looping.
+                } else if (backupPackageStatus != BackupTransport.TRANSPORT_OK) {
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mBackupObserver, packageName,
+                                    BackupManager.ERROR_TRANSPORT_ABORTED);
+                    Slog.w(TAG, "Transport failed; aborting backup: " + backupPackageStatus);
+                    EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
+                    // Abort entire backup pass.
+                    backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
+                    return;
+                } else {
+                    // Success!
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mBackupObserver, packageName,
+                                    BackupManager.SUCCESS);
+                    EventLog.writeEvent(EventLogTags.FULL_BACKUP_SUCCESS, packageName);
+                    backupManagerService.logBackupComplete(packageName);
+                }
+                cleanUpPipes(transportPipes);
+                cleanUpPipes(enginePipes);
+                if (currentPackage.applicationInfo != null) {
+                    Slog.i(TAG, "Unbinding agent in " + packageName);
+                    backupManagerService.addBackupTrace("unbinding " + packageName);
+                    try {
+                        backupManagerService.getActivityManager().unbindBackupAgent(
+                                currentPackage.applicationInfo);
+                    } catch (RemoteException e) { /* can't happen; activity manager is local */ }
+                }
+            }
+        } catch (Exception e) {
+            backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
+            Slog.w(TAG, "Exception trying full transport backup", e);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_EXCEPTION_FULL_BACKUP,
+                    mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    BackupManagerMonitorUtils.putMonitoringExtra(null,
+                            BackupManagerMonitor.EXTRA_LOG_EXCEPTION_FULL_BACKUP,
+                            Log.getStackTraceString(e)));
+
+        } finally {
+
+            if (mCancelAll) {
+                backupRunStatus = BackupManager.ERROR_BACKUP_CANCELLED;
+            }
+
+            if (DEBUG) {
+                Slog.i(TAG, "Full backup completed with status: " + backupRunStatus);
+            }
+            BackupObserverUtils.sendBackupFinished(mBackupObserver, backupRunStatus);
+
+            cleanUpPipes(transportPipes);
+            cleanUpPipes(enginePipes);
+
+            unregisterTask();
+
+            if (mJob != null) {
+                mJob.finishBackupPass();
+            }
+
+            synchronized (backupManagerService.getQueueLock()) {
+                backupManagerService.setRunningFullBackupTask(null);
+            }
+
+            mLatch.countDown();
+
+            // Now that we're actually done with schedule-driven work, reschedule
+            // the next pass based on the new queue state.
+            if (mUpdateSchedule) {
+                backupManagerService.scheduleNextFullBackupJob(backoff);
+            }
+
+            Slog.i(TAG, "Full data backup pass finished.");
+            backupManagerService.getWakelock().release();
+        }
+    }
+
+    void cleanUpPipes(ParcelFileDescriptor[] pipes) {
+        if (pipes != null) {
+            if (pipes[0] != null) {
+                ParcelFileDescriptor fd = pipes[0];
+                pipes[0] = null;
+                try {
+                    fd.close();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Unable to close pipe!");
+                }
+            }
+            if (pipes[1] != null) {
+                ParcelFileDescriptor fd = pipes[1];
+                pipes[1] = null;
+                try {
+                    fd.close();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Unable to close pipe!");
+                }
+            }
+        }
+    }
+
+    // Run the backup and pipe it back to the given socket -- expects to run on
+    // a standalone thread.  The  runner owns this half of the pipe, and closes
+    // it to indicate EOD to the other end.
+    class SinglePackageBackupPreflight implements BackupRestoreTask, FullBackupPreflight {
+        final AtomicLong mResult = new AtomicLong(BackupTransport.AGENT_ERROR);
+        final CountDownLatch mLatch = new CountDownLatch(1);
+        final IBackupTransport mTransport;
+        final long mQuota;
+        private final int mCurrentOpToken;
+
+        SinglePackageBackupPreflight(IBackupTransport transport, long quota, int currentOpToken) {
+            mTransport = transport;
+            mQuota = quota;
+            mCurrentOpToken = currentOpToken;
+        }
+
+        @Override
+        public int preflightFullBackup(PackageInfo pkg, IBackupAgent agent) {
+            int result;
+            try {
+                backupManagerService.prepareOperationTimeout(
+                        mCurrentOpToken, TIMEOUT_FULL_BACKUP_INTERVAL, this, OP_TYPE_BACKUP_WAIT);
+                backupManagerService.addBackupTrace("preflighting");
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Preflighting full payload of " + pkg.packageName);
+                }
+                agent.doMeasureFullBackup(mQuota, mCurrentOpToken,
+                        backupManagerService.getBackupManagerBinder());
+
+                // Now wait to get our result back.  If this backstop timeout is reached without
+                // the latch being thrown, flow will continue as though a result or "normal"
+                // timeout had been produced.  In case of a real backstop timeout, mResult
+                // will still contain the value it was constructed with, AGENT_ERROR, which
+                // intentionaly falls into the "just report failure" code.
+                mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+
+                long totalSize = mResult.get();
+                // If preflight timed out, mResult will contain error code as int.
+                if (totalSize < 0) {
+                    return (int) totalSize;
+                }
+                if (MORE_DEBUG) {
+                    Slog.v(TAG, "Got preflight response; size=" + totalSize);
+                }
+
+                result = mTransport.checkFullBackupSize(totalSize);
+                if (result == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Package hit quota limit on preflight " +
+                                pkg.packageName + ": " + totalSize + " of " + mQuota);
+                    }
+                    agent.doQuotaExceeded(totalSize, mQuota);
+                }
+            } catch (Exception e) {
+                Slog.w(TAG, "Exception preflighting " + pkg.packageName + ": " + e.getMessage());
+                result = BackupTransport.AGENT_ERROR;
+            }
+            return result;
+        }
+
+        @Override
+        public void execute() {
+            // Unused.
+        }
+
+        @Override
+        public void operationComplete(long result) {
+            // got the callback, and our preflightFullBackup() method is waiting for the result
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Preflight op complete, result=" + result);
+            }
+            mResult.set(result);
+            mLatch.countDown();
+            backupManagerService.removeOperation(mCurrentOpToken);
+        }
+
+        @Override
+        public void handleCancel(boolean cancelAll) {
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Preflight cancelled; failing");
+            }
+            mResult.set(BackupTransport.AGENT_ERROR);
+            mLatch.countDown();
+            backupManagerService.removeOperation(mCurrentOpToken);
+        }
+
+        @Override
+        public long getExpectedSizeOrErrorCode() {
+            try {
+                mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+                return mResult.get();
+            } catch (InterruptedException e) {
+                return BackupTransport.NO_MORE_DATA;
+            }
+        }
+    }
+
+    class SinglePackageBackupRunner implements Runnable, BackupRestoreTask {
+        final ParcelFileDescriptor mOutput;
+        final PackageInfo mTarget;
+        final SinglePackageBackupPreflight mPreflight;
+        final CountDownLatch mPreflightLatch;
+        final CountDownLatch mBackupLatch;
+        private final int mCurrentOpToken;
+        private final int mEphemeralToken;
+        private FullBackupEngine mEngine;
+        private volatile int mPreflightResult;
+        private volatile int mBackupResult;
+        private final long mQuota;
+        private volatile boolean mIsCancelled;
+
+        SinglePackageBackupRunner(ParcelFileDescriptor output, PackageInfo target,
+                IBackupTransport transport, long quota, int currentOpToken) throws IOException {
+            mOutput = ParcelFileDescriptor.dup(output.getFileDescriptor());
+            mTarget = target;
+            mCurrentOpToken = currentOpToken;
+            mEphemeralToken = backupManagerService.generateRandomIntegerToken();
+            mPreflight = new SinglePackageBackupPreflight(transport, quota, mEphemeralToken);
+            mPreflightLatch = new CountDownLatch(1);
+            mBackupLatch = new CountDownLatch(1);
+            mPreflightResult = BackupTransport.AGENT_ERROR;
+            mBackupResult = BackupTransport.AGENT_ERROR;
+            mQuota = quota;
+            registerTask();
+        }
+
+        void registerTask() {
+            synchronized (backupManagerService.getCurrentOpLock()) {
+                backupManagerService.getCurrentOperations().put(
+                        mCurrentOpToken, new Operation(OP_PENDING, this, OP_TYPE_BACKUP_WAIT));
+            }
+        }
+
+        void unregisterTask() {
+            synchronized (backupManagerService.getCurrentOpLock()) {
+                backupManagerService.getCurrentOperations().remove(mCurrentOpToken);
+            }
+        }
+
+        @Override
+        public void run() {
+            FileOutputStream out = new FileOutputStream(mOutput.getFileDescriptor());
+            mEngine = new FullBackupEngine(backupManagerService, out, mPreflight, mTarget, false,
+                    this, mQuota, mCurrentOpToken);
+            try {
+                try {
+                    if (!mIsCancelled) {
+                        mPreflightResult = mEngine.preflightCheck();
+                    }
+                } finally {
+                    mPreflightLatch.countDown();
+                }
+                // If there is no error on preflight, continue backup.
+                if (mPreflightResult == BackupTransport.TRANSPORT_OK) {
+                    if (!mIsCancelled) {
+                        mBackupResult = mEngine.backupOnePackage();
+                    }
+                }
+            } catch (Exception e) {
+                Slog.e(TAG, "Exception during full package backup of " + mTarget.packageName);
+            } finally {
+                unregisterTask();
+                mBackupLatch.countDown();
+                try {
+                    mOutput.close();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Error closing transport pipe in runner");
+                }
+            }
+        }
+
+        public void sendQuotaExceeded(final long backupDataBytes, final long quotaBytes) {
+            mEngine.sendQuotaExceeded(backupDataBytes, quotaBytes);
+        }
+
+        // If preflight succeeded, returns positive number - preflight size,
+        // otherwise return negative error code.
+        long getPreflightResultBlocking() {
+            try {
+                mPreflightLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+                if (mIsCancelled) {
+                    return BackupManager.ERROR_BACKUP_CANCELLED;
+                }
+                if (mPreflightResult == BackupTransport.TRANSPORT_OK) {
+                    return mPreflight.getExpectedSizeOrErrorCode();
+                } else {
+                    return mPreflightResult;
+                }
+            } catch (InterruptedException e) {
+                return BackupTransport.AGENT_ERROR;
+            }
+        }
+
+        int getBackupResultBlocking() {
+            try {
+                mBackupLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+                if (mIsCancelled) {
+                    return BackupManager.ERROR_BACKUP_CANCELLED;
+                }
+                return mBackupResult;
+            } catch (InterruptedException e) {
+                return BackupTransport.AGENT_ERROR;
+            }
+        }
+
+
+        // BackupRestoreTask interface: specifically, timeout detection
+
+        @Override
+        public void execute() { /* intentionally empty */ }
+
+        @Override
+        public void operationComplete(long result) { /* intentionally empty */ }
+
+        @Override
+        public void handleCancel(boolean cancelAll) {
+            if (DEBUG) {
+                Slog.w(TAG, "Full backup cancel of " + mTarget.packageName);
+            }
+
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_FULL_BACKUP_CANCEL,
+                    mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, null);
+            mIsCancelled = true;
+            // Cancel tasks spun off by this task.
+            backupManagerService.handleCancel(mEphemeralToken, cancelAll);
+            backupManagerService.tearDownAgentAndKill(mTarget.applicationInfo);
+            // Free up everyone waiting on this task and its children.
+            mPreflightLatch.countDown();
+            mBackupLatch.countDown();
+            // We are done with this operation.
+            backupManagerService.removeOperation(mCurrentOpToken);
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/BackupHandler.java b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
new file mode 100644
index 0000000..886d1f8
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.internal;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL;
+
+import android.app.AlarmManager;
+import android.app.backup.RestoreSet;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.EventLog;
+import android.util.Pair;
+import android.util.Slog;
+
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.EventLogTags;
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.fullbackup.PerformAdbBackupTask;
+import com.android.server.backup.fullbackup.PerformFullTransportBackupTask;
+import com.android.server.backup.params.AdbBackupParams;
+import com.android.server.backup.params.AdbParams;
+import com.android.server.backup.params.AdbRestoreParams;
+import com.android.server.backup.params.BackupParams;
+import com.android.server.backup.params.ClearParams;
+import com.android.server.backup.params.ClearRetryParams;
+import com.android.server.backup.params.RestoreGetSetsParams;
+import com.android.server.backup.params.RestoreParams;
+import com.android.server.backup.restore.PerformAdbRestoreTask;
+import com.android.server.backup.restore.PerformUnifiedRestoreTask;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+
+/**
+ * Asynchronous backup/restore handler thread.
+ */
+public class BackupHandler extends Handler {
+
+    public static final int MSG_RUN_BACKUP = 1;
+    public static final int MSG_RUN_ADB_BACKUP = 2;
+    public static final int MSG_RUN_RESTORE = 3;
+    public static final int MSG_RUN_CLEAR = 4;
+    public static final int MSG_RUN_INITIALIZE = 5;
+    public static final int MSG_RUN_GET_RESTORE_SETS = 6;
+    public static final int MSG_RESTORE_SESSION_TIMEOUT = 8;
+    public static final int MSG_FULL_CONFIRMATION_TIMEOUT = 9;
+    public static final int MSG_RUN_ADB_RESTORE = 10;
+    public static final int MSG_RETRY_INIT = 11;
+    public static final int MSG_RETRY_CLEAR = 12;
+    public static final int MSG_WIDGET_BROADCAST = 13;
+    public static final int MSG_RUN_FULL_TRANSPORT_BACKUP = 14;
+    public static final int MSG_REQUEST_BACKUP = 15;
+    public static final int MSG_SCHEDULE_BACKUP_PACKAGE = 16;
+    public static final int MSG_BACKUP_OPERATION_TIMEOUT = 17;
+    public static final int MSG_RESTORE_OPERATION_TIMEOUT = 18;
+    // backup task state machine tick
+    public static final int MSG_BACKUP_RESTORE_STEP = 20;
+    public static final int MSG_OP_COMPLETE = 21;
+
+    private RefactoredBackupManagerService backupManagerService;
+
+    public BackupHandler(
+            RefactoredBackupManagerService backupManagerService, Looper looper) {
+        super(looper);
+        this.backupManagerService = backupManagerService;
+    }
+
+    public void handleMessage(Message msg) {
+
+        switch (msg.what) {
+            case MSG_RUN_BACKUP: {
+                backupManagerService.setLastBackupPass(System.currentTimeMillis());
+
+                IBackupTransport transport =
+                        backupManagerService.getTransportManager().getCurrentTransportBinder();
+                if (transport == null) {
+                    Slog.v(TAG, "Backup requested but no transport available");
+                    synchronized (backupManagerService.getQueueLock()) {
+                        backupManagerService.setBackupRunning(false);
+                    }
+                    backupManagerService.getWakelock().release();
+                    break;
+                }
+
+                // snapshot the pending-backup set and work on that
+                ArrayList<BackupRequest> queue = new ArrayList<>();
+                File oldJournal = backupManagerService.getJournal();
+                synchronized (backupManagerService.getQueueLock()) {
+                    // Do we have any work to do?  Construct the work queue
+                    // then release the synchronization lock to actually run
+                    // the backup.
+                    if (backupManagerService.getPendingBackups().size() > 0) {
+                        for (BackupRequest b : backupManagerService.getPendingBackups().values()) {
+                            queue.add(b);
+                        }
+                        if (DEBUG) {
+                            Slog.v(TAG, "clearing pending backups");
+                        }
+                        backupManagerService.getPendingBackups().clear();
+
+                        // Start a new backup-queue journal file too
+                        backupManagerService.setJournal(null);
+
+                    }
+                }
+
+                // At this point, we have started a new journal file, and the old
+                // file identity is being passed to the backup processing task.
+                // When it completes successfully, that old journal file will be
+                // deleted.  If we crash prior to that, the old journal is parsed
+                // at next boot and the journaled requests fulfilled.
+                boolean staged = true;
+                if (queue.size() > 0) {
+                    // Spin up a backup state sequence and set it running
+                    try {
+                        String dirName = transport.transportDirName();
+                        PerformBackupTask pbt = new PerformBackupTask(
+                                backupManagerService, transport, dirName, queue,
+                                oldJournal, null, null, Collections.<String>emptyList(), false,
+                                false /* nonIncremental */);
+                        Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
+                        sendMessage(pbtMessage);
+                    } catch (Exception e) {
+                        // unable to ask the transport its dir name -- transient failure, since
+                        // the above check succeeded.  Try again next time.
+                        Slog.e(TAG, "Transport became unavailable attempting backup"
+                                + " or error initializing backup task", e);
+                        staged = false;
+                    }
+                } else {
+                    Slog.v(TAG, "Backup requested but nothing pending");
+                    staged = false;
+                }
+
+                if (!staged) {
+                    // if we didn't actually hand off the wakelock, rewind until next time
+                    synchronized (backupManagerService.getQueueLock()) {
+                        backupManagerService.setBackupRunning(false);
+                    }
+                    backupManagerService.getWakelock().release();
+                }
+                break;
+            }
+
+            case MSG_BACKUP_RESTORE_STEP: {
+                try {
+                    BackupRestoreTask task = (BackupRestoreTask) msg.obj;
+                    if (MORE_DEBUG) {
+                        Slog.v(TAG, "Got next step for " + task + ", executing");
+                    }
+                    task.execute();
+                } catch (ClassCastException e) {
+                    Slog.e(TAG, "Invalid backup task in flight, obj=" + msg.obj);
+                }
+                break;
+            }
+
+            case MSG_OP_COMPLETE: {
+                try {
+                    Pair<BackupRestoreTask, Long> taskWithResult =
+                            (Pair<BackupRestoreTask, Long>) msg.obj;
+                    taskWithResult.first.operationComplete(taskWithResult.second);
+                } catch (ClassCastException e) {
+                    Slog.e(TAG, "Invalid completion in flight, obj=" + msg.obj);
+                }
+                break;
+            }
+
+            case MSG_RUN_ADB_BACKUP: {
+                // TODO: refactor full backup to be a looper-based state machine
+                // similar to normal backup/restore.
+                AdbBackupParams params = (AdbBackupParams) msg.obj;
+                PerformAdbBackupTask task = new PerformAdbBackupTask(backupManagerService,
+                        params.fd,
+                        params.observer, params.includeApks, params.includeObbs,
+                        params.includeShared, params.doWidgets, params.curPassword,
+                        params.encryptPassword, params.allApps, params.includeSystem,
+                        params.doCompress, params.includeKeyValue, params.packages, params.latch);
+                (new Thread(task, "adb-backup")).start();
+                break;
+            }
+
+            case MSG_RUN_FULL_TRANSPORT_BACKUP: {
+                PerformFullTransportBackupTask task = (PerformFullTransportBackupTask) msg.obj;
+                (new Thread(task, "transport-backup")).start();
+                break;
+            }
+
+            case MSG_RUN_RESTORE: {
+                RestoreParams params = (RestoreParams) msg.obj;
+                Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer);
+
+                PerformUnifiedRestoreTask task = new PerformUnifiedRestoreTask(backupManagerService,
+                        params.transport,
+                        params.observer, params.monitor, params.token, params.pkgInfo,
+                        params.pmToken, params.isSystemRestore, params.filterSet);
+
+                synchronized (backupManagerService.getPendingRestores()) {
+                    if (backupManagerService.isRestoreInProgress()) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Restore in progress, queueing.");
+                        }
+                        backupManagerService.getPendingRestores().add(task);
+                        // This task will be picked up and executed when the the currently running
+                        // restore task finishes.
+                    } else {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Starting restore.");
+                        }
+                        backupManagerService.setRestoreInProgress(true);
+                        Message restoreMsg = obtainMessage(MSG_BACKUP_RESTORE_STEP, task);
+                        sendMessage(restoreMsg);
+                    }
+                }
+                break;
+            }
+
+            case MSG_RUN_ADB_RESTORE: {
+                // TODO: refactor full restore to be a looper-based state machine
+                // similar to normal backup/restore.
+                AdbRestoreParams params = (AdbRestoreParams) msg.obj;
+                PerformAdbRestoreTask task = new PerformAdbRestoreTask(backupManagerService,
+                        params.fd,
+                        params.curPassword, params.encryptPassword,
+                        params.observer, params.latch);
+                (new Thread(task, "adb-restore")).start();
+                break;
+            }
+
+            case MSG_RUN_CLEAR: {
+                ClearParams params = (ClearParams) msg.obj;
+                (new PerformClearTask(backupManagerService, params.transport,
+                        params.packageInfo)).run();
+                break;
+            }
+
+            case MSG_RETRY_CLEAR: {
+                // reenqueues if the transport remains unavailable
+                ClearRetryParams params = (ClearRetryParams) msg.obj;
+                backupManagerService.clearBackupData(params.transportName, params.packageName);
+                break;
+            }
+
+            case MSG_RUN_INITIALIZE: {
+                HashSet<String> queue;
+
+                // Snapshot the pending-init queue and work on that
+                synchronized (backupManagerService.getQueueLock()) {
+                    queue = new HashSet<>(backupManagerService.getPendingInits());
+                    backupManagerService.getPendingInits().clear();
+                }
+
+                (new PerformInitializeTask(backupManagerService, queue)).run();
+                break;
+            }
+
+            case MSG_RETRY_INIT: {
+                synchronized (backupManagerService.getQueueLock()) {
+                    backupManagerService.recordInitPendingLocked(msg.arg1 != 0, (String) msg.obj);
+                    backupManagerService.getAlarmManager().set(AlarmManager.RTC_WAKEUP,
+                            System.currentTimeMillis(),
+                            backupManagerService.getRunInitIntent());
+                }
+                break;
+            }
+
+            case MSG_RUN_GET_RESTORE_SETS: {
+                // Like other async operations, this is entered with the wakelock held
+                RestoreSet[] sets = null;
+                RestoreGetSetsParams params = (RestoreGetSetsParams) msg.obj;
+                try {
+                    sets = params.transport.getAvailableRestoreSets();
+                    // cache the result in the active session
+                    synchronized (params.session) {
+                        params.session.mRestoreSets = sets;
+                    }
+                    if (sets == null) {
+                        EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
+                    }
+                } catch (Exception e) {
+                    Slog.e(TAG, "Error from transport getting set list: " + e.getMessage());
+                } finally {
+                    if (params.observer != null) {
+                        try {
+                            params.observer.restoreSetsAvailable(sets);
+                        } catch (RemoteException re) {
+                            Slog.e(TAG, "Unable to report listing to observer");
+                        } catch (Exception e) {
+                            Slog.e(TAG, "Restore observer threw: " + e.getMessage());
+                        }
+                    }
+
+                    // Done: reset the session timeout clock
+                    removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
+                    sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT, TIMEOUT_RESTORE_INTERVAL);
+
+                    backupManagerService.getWakelock().release();
+                }
+                break;
+            }
+
+            case MSG_BACKUP_OPERATION_TIMEOUT:
+            case MSG_RESTORE_OPERATION_TIMEOUT: {
+                Slog.d(TAG, "Timeout message received for token=" + Integer.toHexString(msg.arg1));
+                backupManagerService.handleCancel(msg.arg1, false);
+                break;
+            }
+
+            case MSG_RESTORE_SESSION_TIMEOUT: {
+                synchronized (backupManagerService) {
+                    if (backupManagerService.getActiveRestoreSession() != null) {
+                        // Client app left the restore session dangling.  We know that it
+                        // can't be in the middle of an actual restore operation because
+                        // the timeout is suspended while a restore is in progress.  Clean
+                        // up now.
+                        Slog.w(TAG, "Restore session timed out; aborting");
+                        backupManagerService.getActiveRestoreSession().markTimedOut();
+                        post(backupManagerService.getActiveRestoreSession().new EndRestoreRunnable(
+                                backupManagerService,
+                                backupManagerService.getActiveRestoreSession()));
+                    }
+                }
+                break;
+            }
+
+            case MSG_FULL_CONFIRMATION_TIMEOUT: {
+                synchronized (backupManagerService.getAdbBackupRestoreConfirmations()) {
+                    AdbParams params = backupManagerService.getAdbBackupRestoreConfirmations().get(
+                            msg.arg1);
+                    if (params != null) {
+                        Slog.i(TAG, "Full backup/restore timed out waiting for user confirmation");
+
+                        // Release the waiter; timeout == completion
+                        backupManagerService.signalAdbBackupRestoreCompletion(params);
+
+                        // Remove the token from the set
+                        backupManagerService.getAdbBackupRestoreConfirmations().delete(msg.arg1);
+
+                        // Report a timeout to the observer, if any
+                        if (params.observer != null) {
+                            try {
+                                params.observer.onTimeout();
+                            } catch (RemoteException e) {
+                            /* don't care if the app has gone away */
+                            }
+                        }
+                    } else {
+                        Slog.d(TAG, "couldn't find params for token " + msg.arg1);
+                    }
+                }
+                break;
+            }
+
+            case MSG_WIDGET_BROADCAST: {
+                final Intent intent = (Intent) msg.obj;
+                backupManagerService.getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
+                break;
+            }
+
+            case MSG_REQUEST_BACKUP: {
+                BackupParams params = (BackupParams) msg.obj;
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "MSG_REQUEST_BACKUP observer=" + params.observer);
+                }
+                ArrayList<BackupRequest> kvQueue = new ArrayList<>();
+                for (String packageName : params.kvPackages) {
+                    kvQueue.add(new BackupRequest(packageName));
+                }
+                backupManagerService.setBackupRunning(true);
+                backupManagerService.getWakelock().acquire();
+
+                PerformBackupTask pbt = new PerformBackupTask(
+                        backupManagerService,
+                        params.transport, params.dirName,
+                        kvQueue, null, params.observer, params.monitor, params.fullPackages, true,
+                        params.nonIncrementalBackup);
+                Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
+                sendMessage(pbtMessage);
+                break;
+            }
+
+            case MSG_SCHEDULE_BACKUP_PACKAGE: {
+                String pkgName = (String) msg.obj;
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "MSG_SCHEDULE_BACKUP_PACKAGE " + pkgName);
+                }
+                backupManagerService.dataChangedImpl(pkgName);
+                break;
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/BackupRequest.java b/services/backup/java/com/android/server/backup/internal/BackupRequest.java
new file mode 100644
index 0000000..20c3cc4
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/BackupRequest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.internal;
+
+/**
+ * Set of backup services that have pending changes.
+ */
+public class BackupRequest {
+
+    public String packageName;
+
+    public BackupRequest(String pkgName) {
+        packageName = pkgName;
+    }
+
+    public String toString() {
+        return "BackupRequest{pkg=" + packageName + "}";
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/BackupState.java b/services/backup/java/com/android/server/backup/internal/BackupState.java
new file mode 100644
index 0000000..4d42c240
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/BackupState.java
@@ -0,0 +1,10 @@
+package com.android.server.backup.internal;
+
+/**
+ * Current state of the backup.
+ */
+enum BackupState {
+    INITIAL,
+    RUNNING_QUEUE,
+    FINAL
+}
diff --git a/services/backup/java/com/android/server/backup/internal/ClearDataObserver.java b/services/backup/java/com/android/server/backup/internal/ClearDataObserver.java
new file mode 100644
index 0000000..d82c865
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/ClearDataObserver.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.internal;
+
+import android.content.pm.IPackageDataObserver;
+
+import com.android.server.backup.RefactoredBackupManagerService;
+
+public class ClearDataObserver extends IPackageDataObserver.Stub {
+
+    private RefactoredBackupManagerService backupManagerService;
+
+    public ClearDataObserver(RefactoredBackupManagerService backupManagerService) {
+        this.backupManagerService = backupManagerService;
+    }
+
+    public void onRemoveCompleted(String packageName, boolean succeeded) {
+        synchronized (backupManagerService.getClearDataLock()) {
+            backupManagerService.setClearingData(false);
+            backupManagerService.getClearDataLock().notifyAll();
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/Operation.java b/services/backup/java/com/android/server/backup/internal/Operation.java
new file mode 100644
index 0000000..fd5ad92
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/Operation.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.internal;
+
+import com.android.server.backup.BackupRestoreTask;
+
+public class Operation {
+
+    public int state;
+    public final BackupRestoreTask callback;
+    public final int type;
+
+    public Operation(int initialState, BackupRestoreTask callbackObj, int type) {
+        state = initialState;
+        callback = callbackObj;
+        this.type = type;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
new file mode 100644
index 0000000..a996e2d
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
@@ -0,0 +1,1118 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.internal;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG_BACKUP_TRACE;
+import static com.android.server.backup.RefactoredBackupManagerService.KEY_WIDGET_STATE;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_PENDING;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_BACKUP_INTERVAL;
+import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_OPERATION_TIMEOUT;
+import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTORE_STEP;
+
+import android.app.ApplicationThreadConstants;
+import android.app.IBackupAgent;
+import android.app.backup.BackupDataInput;
+import android.app.backup.BackupDataOutput;
+import android.app.backup.BackupManager;
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.BackupTransport;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.SELinux;
+import android.os.UserHandle;
+import android.os.WorkSource;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.util.EventLog;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.AppWidgetBackupBridge;
+import com.android.server.EventLogTags;
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.KeyValueBackupJob;
+import com.android.server.backup.PackageManagerBackupAgent;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.fullbackup.PerformFullTransportBackupTask;
+import com.android.server.backup.utils.AppBackupUtils;
+import com.android.server.backup.utils.BackupManagerMonitorUtils;
+import com.android.server.backup.utils.BackupObserverUtils;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * This class handles the process of backing up a given list of key/value backup packages.
+ * Also takes in a list of pending dolly backups and kicks them off when key/value backups
+ * are done.
+ *
+ * Flow:
+ * If required, backup @pm@.
+ * For each pending key/value backup package:
+ *     - Bind to agent.
+ *     - Call agent.doBackup()
+ *     - Wait either for cancel/timeout or operationComplete() callback from the agent.
+ * Start task to perform dolly backups.
+ *
+ * There are three entry points into this class:
+ *     - execute() [Called from the handler thread]
+ *     - operationComplete(long result) [Called from the handler thread]
+ *     - handleCancel(boolean cancelAll) [Can be called from any thread]
+ * These methods synchronize on mCancelLock.
+ *
+ * Interaction with mCurrentOperations:
+ *     - An entry for this task is put into mCurrentOperations for the entire lifetime of the
+ *       task. This is useful to cancel the task if required.
+ *     - An ephemeral entry is put into mCurrentOperations each time we are waiting on for
+ *       response from a backup agent. This is used to plumb timeouts and completion callbacks.
+ */
+public class PerformBackupTask implements BackupRestoreTask {
+    private static final String TAG = "PerformBackupTask";
+
+    private RefactoredBackupManagerService backupManagerService;
+    private final Object mCancelLock = new Object();
+
+    IBackupTransport mTransport;
+    ArrayList<BackupRequest> mQueue;
+    ArrayList<BackupRequest> mOriginalQueue;
+    File mStateDir;
+    File mJournal;
+    BackupState mCurrentState;
+    List<String> mPendingFullBackups;
+    IBackupObserver mObserver;
+    IBackupManagerMonitor mMonitor;
+
+    private final PerformFullTransportBackupTask mFullBackupTask;
+    private final int mCurrentOpToken;
+    private volatile int mEphemeralOpToken;
+
+    // carried information about the current in-flight operation
+    IBackupAgent mAgentBinder;
+    PackageInfo mCurrentPackage;
+    File mSavedStateName;
+    File mBackupDataName;
+    File mNewStateName;
+    ParcelFileDescriptor mSavedState;
+    ParcelFileDescriptor mBackupData;
+    ParcelFileDescriptor mNewState;
+    int mStatus;
+    boolean mFinished;
+    final boolean mUserInitiated;
+    final boolean mNonIncremental;
+
+    private volatile boolean mCancelAll;
+
+    public PerformBackupTask(RefactoredBackupManagerService backupManagerService,
+            IBackupTransport transport, String dirName,
+            ArrayList<BackupRequest> queue, File journal, IBackupObserver observer,
+            IBackupManagerMonitor monitor, List<String> pendingFullBackups,
+            boolean userInitiated, boolean nonIncremental) {
+        this.backupManagerService = backupManagerService;
+        mTransport = transport;
+        mOriginalQueue = queue;
+        mQueue = new ArrayList<>();
+        mJournal = journal;
+        mObserver = observer;
+        mMonitor = monitor;
+        mPendingFullBackups = pendingFullBackups;
+        mUserInitiated = userInitiated;
+        mNonIncremental = nonIncremental;
+
+        mStateDir = new File(backupManagerService.getBaseStateDir(), dirName);
+        mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
+
+        mFinished = false;
+
+        synchronized (backupManagerService.getCurrentOpLock()) {
+            if (backupManagerService.isBackupOperationInProgress()) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Skipping backup since one is already in progress.");
+                }
+                mCancelAll = true;
+                mFullBackupTask = null;
+                mCurrentState = BackupState.FINAL;
+                backupManagerService.addBackupTrace("Skipped. Backup already in progress.");
+            } else {
+                mCurrentState = BackupState.INITIAL;
+                CountDownLatch latch = new CountDownLatch(1);
+                String[] fullBackups =
+                        mPendingFullBackups.toArray(new String[mPendingFullBackups.size()]);
+                mFullBackupTask =
+                        new PerformFullTransportBackupTask(backupManagerService,
+                                /*fullBackupRestoreObserver*/
+                                null,
+                                fullBackups, /*updateSchedule*/ false, /*runningJob*/ null,
+                                latch,
+                                mObserver, mMonitor, mUserInitiated);
+
+                registerTask();
+                backupManagerService.addBackupTrace("STATE => INITIAL");
+            }
+        }
+    }
+
+    /**
+     * Put this task in the repository of running tasks.
+     */
+    private void registerTask() {
+        synchronized (backupManagerService.getCurrentOpLock()) {
+            backupManagerService.getCurrentOperations().put(
+                    mCurrentOpToken, new Operation(OP_PENDING, this, OP_TYPE_BACKUP));
+        }
+    }
+
+    /**
+     * Remove this task from repository of running tasks.
+     */
+    private void unregisterTask() {
+        backupManagerService.removeOperation(mCurrentOpToken);
+    }
+
+    // Main entry point: perform one chunk of work, updating the state as appropriate
+    // and reposting the next chunk to the primary backup handler thread.
+    @Override
+    @GuardedBy("mCancelLock")
+    public void execute() {
+        synchronized (mCancelLock) {
+            switch (mCurrentState) {
+                case INITIAL:
+                    beginBackup();
+                    break;
+
+                case RUNNING_QUEUE:
+                    invokeNextAgent();
+                    break;
+
+                case FINAL:
+                    if (!mFinished) {
+                        finalizeBackup();
+                    } else {
+                        Slog.e(TAG, "Duplicate finish");
+                    }
+                    mFinished = true;
+                    break;
+            }
+        }
+    }
+
+    // We're starting a backup pass.  Initialize the transport and send
+    // the PM metadata blob if we haven't already.
+    void beginBackup() {
+        if (DEBUG_BACKUP_TRACE) {
+            backupManagerService.clearBackupTrace();
+            StringBuilder b = new StringBuilder(256);
+            b.append("beginBackup: [");
+            for (BackupRequest req : mOriginalQueue) {
+                b.append(' ');
+                b.append(req.packageName);
+            }
+            b.append(" ]");
+            backupManagerService.addBackupTrace(b.toString());
+        }
+
+        mAgentBinder = null;
+        mStatus = BackupTransport.TRANSPORT_OK;
+
+        // Sanity check: if the queue is empty we have no work to do.
+        if (mOriginalQueue.isEmpty() && mPendingFullBackups.isEmpty()) {
+            Slog.w(TAG, "Backup begun with an empty queue - nothing to do.");
+            backupManagerService.addBackupTrace("queue empty at begin");
+            BackupObserverUtils.sendBackupFinished(mObserver, BackupManager.SUCCESS);
+            executeNextState(BackupState.FINAL);
+            return;
+        }
+
+        // We need to retain the original queue contents in case of transport
+        // failure, but we want a working copy that we can manipulate along
+        // the way.
+        mQueue = (ArrayList<BackupRequest>) mOriginalQueue.clone();
+
+        // When the transport is forcing non-incremental key/value payloads, we send the
+        // metadata only if it explicitly asks for it.
+        boolean skipPm = mNonIncremental;
+
+        // The app metadata pseudopackage might also be represented in the
+        // backup queue if apps have been added/removed since the last time
+        // we performed a backup.  Drop it from the working queue now that
+        // we're committed to evaluating it for backup regardless.
+        for (int i = 0; i < mQueue.size(); i++) {
+            if (PACKAGE_MANAGER_SENTINEL.equals(
+                    mQueue.get(i).packageName)) {
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "Metadata in queue; eliding");
+                }
+                mQueue.remove(i);
+                skipPm = false;
+                break;
+            }
+        }
+
+        if (DEBUG) {
+            Slog.v(TAG, "Beginning backup of " + mQueue.size() + " targets");
+        }
+
+        File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL);
+        try {
+            final String transportName = mTransport.transportDirName();
+            EventLog.writeEvent(EventLogTags.BACKUP_START, transportName);
+
+            // If we haven't stored package manager metadata yet, we must init the transport.
+            if (mStatus == BackupTransport.TRANSPORT_OK && pmState.length() <= 0) {
+                Slog.i(TAG, "Initializing (wiping) backup state and transport storage");
+                backupManagerService.addBackupTrace("initializing transport " + transportName);
+                backupManagerService.resetBackupState(mStateDir);  // Just to make sure.
+                mStatus = mTransport.initializeDevice();
+
+                backupManagerService.addBackupTrace("transport.initializeDevice() == " + mStatus);
+                if (mStatus == BackupTransport.TRANSPORT_OK) {
+                    EventLog.writeEvent(EventLogTags.BACKUP_INITIALIZE);
+                } else {
+                    EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, "(initialize)");
+                    Slog.e(TAG, "Transport error in initializeDevice()");
+                }
+            }
+
+            if (skipPm) {
+                Slog.d(TAG, "Skipping backup of package metadata.");
+                executeNextState(BackupState.RUNNING_QUEUE);
+            } else {
+                // The package manager doesn't have a proper <application> etc, but since
+                // it's running here in the system process we can just set up its agent
+                // directly and use a synthetic BackupRequest.  We always run this pass
+                // because it's cheap and this way we guarantee that we don't get out of
+                // step even if we're selecting among various transports at run time.
+                if (mStatus == BackupTransport.TRANSPORT_OK) {
+                    PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(
+                            backupManagerService.getPackageManager());
+                    mStatus = invokeAgentForBackup(
+                            PACKAGE_MANAGER_SENTINEL,
+                            IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport);
+                    backupManagerService.addBackupTrace("PMBA invoke: " + mStatus);
+
+                    // Because the PMBA is a local instance, it has already executed its
+                    // backup callback and returned.  Blow away the lingering (spurious)
+                    // pending timeout message for it.
+                    backupManagerService.getBackupHandler().removeMessages(
+                            MSG_BACKUP_OPERATION_TIMEOUT);
+                }
+            }
+
+            if (mStatus == BackupTransport.TRANSPORT_NOT_INITIALIZED) {
+                // The backend reports that our dataset has been wiped.  Note this in
+                // the event log; the no-success code below will reset the backup
+                // state as well.
+                EventLog.writeEvent(EventLogTags.BACKUP_RESET, mTransport.transportDirName());
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "Error in backup thread", e);
+            backupManagerService.addBackupTrace("Exception in backup thread: " + e);
+            mStatus = BackupTransport.TRANSPORT_ERROR;
+        } finally {
+            // If we've succeeded so far, invokeAgentForBackup() will have run the PM
+            // metadata and its completion/timeout callback will continue the state
+            // machine chain.  If it failed that won't happen; we handle that now.
+            backupManagerService.addBackupTrace("exiting prelim: " + mStatus);
+            if (mStatus != BackupTransport.TRANSPORT_OK) {
+                // if things went wrong at this point, we need to
+                // restage everything and try again later.
+                backupManagerService.resetBackupState(mStateDir);  // Just to make sure.
+                // In case of any other error, it's backup transport error.
+                BackupObserverUtils.sendBackupFinished(mObserver,
+                        BackupManager.ERROR_TRANSPORT_ABORTED);
+                executeNextState(BackupState.FINAL);
+            }
+        }
+    }
+
+    // Transport has been initialized and the PM metadata submitted successfully
+    // if that was warranted.  Now we process the single next thing in the queue.
+    void invokeNextAgent() {
+        mStatus = BackupTransport.TRANSPORT_OK;
+        backupManagerService.addBackupTrace("invoke q=" + mQueue.size());
+
+        // Sanity check that we have work to do.  If not, skip to the end where
+        // we reestablish the wakelock invariants etc.
+        if (mQueue.isEmpty()) {
+            if (MORE_DEBUG) Slog.i(TAG, "queue now empty");
+            executeNextState(BackupState.FINAL);
+            return;
+        }
+
+        // pop the entry we're going to process on this step
+        BackupRequest request = mQueue.get(0);
+        mQueue.remove(0);
+
+        Slog.d(TAG, "starting key/value backup of " + request);
+        backupManagerService.addBackupTrace("launch agent for " + request.packageName);
+
+        // Verify that the requested app exists; it might be something that
+        // requested a backup but was then uninstalled.  The request was
+        // journalled and rather than tamper with the journal it's safer
+        // to sanity-check here.  This also gives us the classname of the
+        // package's backup agent.
+        try {
+            mCurrentPackage = backupManagerService.getPackageManager().getPackageInfo(
+                    request.packageName,
+                    PackageManager.GET_SIGNATURES);
+            if (!AppBackupUtils.appIsEligibleForBackup(
+                    mCurrentPackage.applicationInfo)) {
+                // The manifest has changed but we had a stale backup request pending.
+                // This won't happen again because the app won't be requesting further
+                // backups.
+                Slog.i(TAG, "Package " + request.packageName
+                        + " no longer supports backup; skipping");
+                backupManagerService.addBackupTrace("skipping - not eligible, completion is noop");
+                // Shouldn't happen in case of requested backup, as pre-check was done in
+                // #requestBackup(), except to app update done concurrently
+                BackupObserverUtils.sendBackupOnPackageResult(mObserver,
+                        mCurrentPackage.packageName,
+                        BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                executeNextState(BackupState.RUNNING_QUEUE);
+                return;
+            }
+
+            if (AppBackupUtils.appGetsFullBackup(mCurrentPackage)) {
+                // It's possible that this app *formerly* was enqueued for key/value backup,
+                // but has since been updated and now only supports the full-data path.
+                // Don't proceed with a key/value backup for it in this case.
+                Slog.i(TAG, "Package " + request.packageName
+                        + " requests full-data rather than key/value; skipping");
+                backupManagerService.addBackupTrace(
+                        "skipping - fullBackupOnly, completion is noop");
+                // Shouldn't happen in case of requested backup, as pre-check was done in
+                // #requestBackup()
+                BackupObserverUtils.sendBackupOnPackageResult(mObserver,
+                        mCurrentPackage.packageName,
+                        BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                executeNextState(BackupState.RUNNING_QUEUE);
+                return;
+            }
+
+            if (AppBackupUtils.appIsStopped(mCurrentPackage.applicationInfo)) {
+                // The app has been force-stopped or cleared or just installed,
+                // and not yet launched out of that state, so just as it won't
+                // receive broadcasts, we won't run it for backup.
+                backupManagerService.addBackupTrace("skipping - stopped");
+                BackupObserverUtils.sendBackupOnPackageResult(mObserver,
+                        mCurrentPackage.packageName,
+                        BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                executeNextState(BackupState.RUNNING_QUEUE);
+                return;
+            }
+
+            IBackupAgent agent = null;
+            try {
+                backupManagerService.getWakelock().setWorkSource(
+                        new WorkSource(mCurrentPackage.applicationInfo.uid));
+                agent = backupManagerService.bindToAgentSynchronous(mCurrentPackage.applicationInfo,
+                        ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL);
+                backupManagerService.addBackupTrace("agent bound; a? = " + (agent != null));
+                if (agent != null) {
+                    mAgentBinder = agent;
+                    mStatus = invokeAgentForBackup(request.packageName, agent, mTransport);
+                    // at this point we'll either get a completion callback from the
+                    // agent, or a timeout message on the main handler.  either way, we're
+                    // done here as long as we're successful so far.
+                } else {
+                    // Timeout waiting for the agent
+                    mStatus = BackupTransport.AGENT_ERROR;
+                }
+            } catch (SecurityException ex) {
+                // Try for the next one.
+                Slog.d(TAG, "error in bind/backup", ex);
+                mStatus = BackupTransport.AGENT_ERROR;
+                backupManagerService.addBackupTrace("agent SE");
+            }
+        } catch (NameNotFoundException e) {
+            Slog.d(TAG, "Package does not exist; skipping");
+            backupManagerService.addBackupTrace("no such package");
+            mStatus = BackupTransport.AGENT_UNKNOWN;
+        } finally {
+            backupManagerService.getWakelock().setWorkSource(null);
+
+            // If there was an agent error, no timeout/completion handling will occur.
+            // That means we need to direct to the next state ourselves.
+            if (mStatus != BackupTransport.TRANSPORT_OK) {
+                BackupState nextState = BackupState.RUNNING_QUEUE;
+                mAgentBinder = null;
+
+                // An agent-level failure means we reenqueue this one agent for
+                // a later retry, but otherwise proceed normally.
+                if (mStatus == BackupTransport.AGENT_ERROR) {
+                    if (MORE_DEBUG) {
+                        Slog.i(TAG, "Agent failure for " + request.packageName
+                                + " - restaging");
+                    }
+                    backupManagerService.dataChangedImpl(request.packageName);
+                    mStatus = BackupTransport.TRANSPORT_OK;
+                    if (mQueue.isEmpty()) nextState = BackupState.FINAL;
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mObserver, mCurrentPackage.packageName,
+                                    BackupManager.ERROR_AGENT_FAILURE);
+                } else if (mStatus == BackupTransport.AGENT_UNKNOWN) {
+                    // Failed lookup of the app, so we couldn't bring up an agent, but
+                    // we're otherwise fine.  Just drop it and go on to the next as usual.
+                    mStatus = BackupTransport.TRANSPORT_OK;
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mObserver, mCurrentPackage.packageName,
+                                    BackupManager.ERROR_PACKAGE_NOT_FOUND);
+                } else {
+                    // Transport-level failure means we reenqueue everything
+                    revertAndEndBackup();
+                    nextState = BackupState.FINAL;
+                }
+
+                executeNextState(nextState);
+            } else {
+                // success case
+                backupManagerService.addBackupTrace("expecting completion/timeout callback");
+            }
+        }
+    }
+
+    void finalizeBackup() {
+        backupManagerService.addBackupTrace("finishing");
+
+        // Mark packages that we didn't backup (because backup was cancelled, etc.) as needing
+        // backup.
+        for (BackupRequest req : mQueue) {
+            backupManagerService.dataChangedImpl(req.packageName);
+        }
+
+        // Either backup was successful, in which case we of course do not need
+        // this pass's journal any more; or it failed, in which case we just
+        // re-enqueued all of these packages in the current active journal.
+        // Either way, we no longer need this pass's journal.
+        if (mJournal != null && !mJournal.delete()) {
+            Slog.e(TAG, "Unable to remove backup journal file " + mJournal);
+        }
+
+        // If everything actually went through and this is the first time we've
+        // done a backup, we can now record what the current backup dataset token
+        // is.
+        if ((backupManagerService.getCurrentToken() == 0) && (mStatus
+                == BackupTransport.TRANSPORT_OK)) {
+            backupManagerService.addBackupTrace("success; recording token");
+            try {
+                backupManagerService.setCurrentToken(mTransport.getCurrentRestoreSet());
+                backupManagerService.writeRestoreTokens();
+            } catch (Exception e) {
+                // nothing for it at this point, unfortunately, but this will be
+                // recorded the next time we fully succeed.
+                Slog.e(TAG, "Transport threw reporting restore set: " + e.getMessage());
+                backupManagerService.addBackupTrace("transport threw returning token");
+            }
+        }
+
+        // Set up the next backup pass - at this point we can set mBackupRunning
+        // to false to allow another pass to fire, because we're done with the
+        // state machine sequence and the wakelock is refcounted.
+        synchronized (backupManagerService.getQueueLock()) {
+            backupManagerService.setBackupRunning(false);
+            if (mStatus == BackupTransport.TRANSPORT_NOT_INITIALIZED) {
+                // Make sure we back up everything and perform the one-time init
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Server requires init; rerunning");
+                }
+                backupManagerService.addBackupTrace("init required; rerunning");
+                try {
+                    final String name = backupManagerService.getTransportManager().getTransportName(
+                            mTransport);
+                    if (name != null) {
+                        backupManagerService.getPendingInits().add(name);
+                    } else {
+                        if (DEBUG) {
+                            Slog.w(TAG, "Couldn't find name of transport " + mTransport
+                                    + " for init");
+                        }
+                    }
+                } catch (Exception e) {
+                    Slog.w(TAG, "Failed to query transport name for init: " + e.getMessage());
+                    // swallow it and proceed; we don't rely on this
+                }
+                clearMetadata();
+                backupManagerService.backupNow();
+            }
+        }
+
+        backupManagerService.clearBackupTrace();
+
+        unregisterTask();
+
+        if (!mCancelAll && mStatus == BackupTransport.TRANSPORT_OK &&
+                mPendingFullBackups != null && !mPendingFullBackups.isEmpty()) {
+            Slog.d(TAG, "Starting full backups for: " + mPendingFullBackups);
+            // Acquiring wakelock for PerformFullTransportBackupTask before its start.
+            backupManagerService.getWakelock().acquire();
+            (new Thread(mFullBackupTask, "full-transport-requested")).start();
+        } else if (mCancelAll) {
+            if (mFullBackupTask != null) {
+                mFullBackupTask.unregisterTask();
+            }
+            BackupObserverUtils.sendBackupFinished(mObserver,
+                    BackupManager.ERROR_BACKUP_CANCELLED);
+        } else {
+            mFullBackupTask.unregisterTask();
+            switch (mStatus) {
+                case BackupTransport.TRANSPORT_OK:
+                    BackupObserverUtils.sendBackupFinished(mObserver,
+                            BackupManager.SUCCESS);
+                    break;
+                case BackupTransport.TRANSPORT_NOT_INITIALIZED:
+                    BackupObserverUtils.sendBackupFinished(mObserver,
+                            BackupManager.ERROR_TRANSPORT_ABORTED);
+                    break;
+                case BackupTransport.TRANSPORT_ERROR:
+                default:
+                    BackupObserverUtils.sendBackupFinished(mObserver,
+                            BackupManager.ERROR_TRANSPORT_ABORTED);
+                    break;
+            }
+        }
+        Slog.i(TAG, "K/V backup pass finished.");
+        // Only once we're entirely finished do we release the wakelock for k/v backup.
+        backupManagerService.getWakelock().release();
+    }
+
+    // Remove the PM metadata state. This will generate an init on the next pass.
+    void clearMetadata() {
+        final File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL);
+        if (pmState.exists()) pmState.delete();
+    }
+
+    // Invoke an agent's doBackup() and start a timeout message spinning on the main
+    // handler in case it doesn't get back to us.
+    int invokeAgentForBackup(String packageName, IBackupAgent agent,
+            IBackupTransport transport) {
+        if (DEBUG) {
+            Slog.d(TAG, "invokeAgentForBackup on " + packageName);
+        }
+        backupManagerService.addBackupTrace("invoking " + packageName);
+
+        File blankStateName = new File(mStateDir, "blank_state");
+        mSavedStateName = new File(mStateDir, packageName);
+        mBackupDataName = new File(backupManagerService.getDataDir(), packageName + ".data");
+        mNewStateName = new File(mStateDir, packageName + ".new");
+        if (MORE_DEBUG) Slog.d(TAG, "data file: " + mBackupDataName);
+
+        mSavedState = null;
+        mBackupData = null;
+        mNewState = null;
+
+        boolean callingAgent = false;
+        mEphemeralOpToken = backupManagerService.generateRandomIntegerToken();
+        try {
+            // Look up the package info & signatures.  This is first so that if it
+            // throws an exception, there's no file setup yet that would need to
+            // be unraveled.
+            if (packageName.equals(PACKAGE_MANAGER_SENTINEL)) {
+                // The metadata 'package' is synthetic; construct one and make
+                // sure our global state is pointed at it
+                mCurrentPackage = new PackageInfo();
+                mCurrentPackage.packageName = packageName;
+            }
+
+            // In a full backup, we pass a null ParcelFileDescriptor as
+            // the saved-state "file". For key/value backups we pass the old state if
+            // an incremental backup is required, and a blank state otherwise.
+            mSavedState = ParcelFileDescriptor.open(
+                    mNonIncremental ? blankStateName : mSavedStateName,
+                    ParcelFileDescriptor.MODE_READ_ONLY |
+                            ParcelFileDescriptor.MODE_CREATE);  // Make an empty file if necessary
+
+            mBackupData = ParcelFileDescriptor.open(mBackupDataName,
+                    ParcelFileDescriptor.MODE_READ_WRITE |
+                            ParcelFileDescriptor.MODE_CREATE |
+                            ParcelFileDescriptor.MODE_TRUNCATE);
+
+            if (!SELinux.restorecon(mBackupDataName)) {
+                Slog.e(TAG, "SELinux restorecon failed on " + mBackupDataName);
+            }
+
+            mNewState = ParcelFileDescriptor.open(mNewStateName,
+                    ParcelFileDescriptor.MODE_READ_WRITE |
+                            ParcelFileDescriptor.MODE_CREATE |
+                            ParcelFileDescriptor.MODE_TRUNCATE);
+
+            final long quota = mTransport.getBackupQuota(packageName, false /* isFullBackup */);
+            callingAgent = true;
+
+            // Initiate the target's backup pass
+            backupManagerService.addBackupTrace("setting timeout");
+            backupManagerService.prepareOperationTimeout(
+                    mEphemeralOpToken, TIMEOUT_BACKUP_INTERVAL, this, OP_TYPE_BACKUP_WAIT);
+            backupManagerService.addBackupTrace("calling agent doBackup()");
+
+            agent.doBackup(mSavedState, mBackupData, mNewState, quota, mEphemeralOpToken,
+                    backupManagerService.getBackupManagerBinder());
+        } catch (Exception e) {
+            Slog.e(TAG, "Error invoking for backup on " + packageName + ". " + e);
+            backupManagerService.addBackupTrace("exception: " + e);
+            EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName,
+                    e.toString());
+            errorCleanup();
+            return callingAgent ? BackupTransport.AGENT_ERROR
+                    : BackupTransport.TRANSPORT_ERROR;
+        } finally {
+            if (mNonIncremental) {
+                blankStateName.delete();
+            }
+        }
+
+        // At this point the agent is off and running.  The next thing to happen will
+        // either be a callback from the agent, at which point we'll process its data
+        // for transport, or a timeout.  Either way the next phase will happen in
+        // response to the TimeoutHandler interface callbacks.
+        backupManagerService.addBackupTrace("invoke success");
+        return BackupTransport.TRANSPORT_OK;
+    }
+
+    public void failAgent(IBackupAgent agent, String message) {
+        try {
+            agent.fail(message);
+        } catch (Exception e) {
+            Slog.w(TAG, "Error conveying failure to " + mCurrentPackage.packageName);
+        }
+    }
+
+    // SHA-1 a byte array and return the result in hex
+    private String SHA1Checksum(byte[] input) {
+        final byte[] checksum;
+        try {
+            MessageDigest md = MessageDigest.getInstance("SHA-1");
+            checksum = md.digest(input);
+        } catch (NoSuchAlgorithmException e) {
+            Slog.e(TAG, "Unable to use SHA-1!");
+            return "00";
+        }
+
+        StringBuffer sb = new StringBuffer(checksum.length * 2);
+        for (int i = 0; i < checksum.length; i++) {
+            sb.append(Integer.toHexString(checksum[i]));
+        }
+        return sb.toString();
+    }
+
+    private void writeWidgetPayloadIfAppropriate(FileDescriptor fd, String pkgName)
+            throws IOException {
+        // TODO: http://b/22388012
+        byte[] widgetState = AppWidgetBackupBridge.getWidgetState(pkgName,
+                UserHandle.USER_SYSTEM);
+        // has the widget state changed since last time?
+        final File widgetFile = new File(mStateDir, pkgName + "_widget");
+        final boolean priorStateExists = widgetFile.exists();
+
+        if (MORE_DEBUG) {
+            if (priorStateExists || widgetState != null) {
+                Slog.i(TAG, "Checking widget update: state=" + (widgetState != null)
+                        + " prior=" + priorStateExists);
+            }
+        }
+
+        if (!priorStateExists && widgetState == null) {
+            // no prior state, no new state => nothing to do
+            return;
+        }
+
+        // if the new state is not null, we might need to compare checksums to
+        // determine whether to update the widget blob in the archive.  If the
+        // widget state *is* null, we know a priori at this point that we simply
+        // need to commit a deletion for it.
+        String newChecksum = null;
+        if (widgetState != null) {
+            newChecksum = SHA1Checksum(widgetState);
+            if (priorStateExists) {
+                final String priorChecksum;
+                try (
+                        FileInputStream fin = new FileInputStream(widgetFile);
+                        DataInputStream in = new DataInputStream(fin)
+                ) {
+                    priorChecksum = in.readUTF();
+                }
+                if (Objects.equals(newChecksum, priorChecksum)) {
+                    // Same checksum => no state change => don't rewrite the widget data
+                    return;
+                }
+            }
+        } // else widget state *became* empty, so we need to commit a deletion
+
+        BackupDataOutput out = new BackupDataOutput(fd);
+        if (widgetState != null) {
+            try (
+                    FileOutputStream fout = new FileOutputStream(widgetFile);
+                    DataOutputStream stateOut = new DataOutputStream(fout)
+            ) {
+                stateOut.writeUTF(newChecksum);
+            }
+
+            out.writeEntityHeader(KEY_WIDGET_STATE, widgetState.length);
+            out.writeEntityData(widgetState, widgetState.length);
+        } else {
+            // Widget state for this app has been removed; commit a deletion
+            out.writeEntityHeader(KEY_WIDGET_STATE, -1);
+            widgetFile.delete();
+        }
+    }
+
+    @Override
+    @GuardedBy("mCancelLock")
+    public void operationComplete(long unusedResult) {
+        backupManagerService.removeOperation(mEphemeralOpToken);
+        synchronized (mCancelLock) {
+            // The agent reported back to us!
+            if (mFinished) {
+                Slog.d(TAG, "operationComplete received after task finished.");
+                return;
+            }
+
+            if (mBackupData == null) {
+                // This callback was racing with our timeout, so we've cleaned up the
+                // agent state already and are on to the next thing.  We have nothing
+                // further to do here: agent state having been cleared means that we've
+                // initiated the appropriate next operation.
+                final String pkg = (mCurrentPackage != null)
+                        ? mCurrentPackage.packageName : "[none]";
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "Callback after agent teardown: " + pkg);
+                }
+                backupManagerService.addBackupTrace("late opComplete; curPkg = " + pkg);
+                return;
+            }
+
+            final String pkgName = mCurrentPackage.packageName;
+            final long filepos = mBackupDataName.length();
+            FileDescriptor fd = mBackupData.getFileDescriptor();
+            try {
+                // If it's a 3rd party app, see whether they wrote any protected keys
+                // and complain mightily if they are attempting shenanigans.
+                if (mCurrentPackage.applicationInfo != null &&
+                        (mCurrentPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
+                                == 0) {
+                    ParcelFileDescriptor readFd = ParcelFileDescriptor.open(mBackupDataName,
+                            ParcelFileDescriptor.MODE_READ_ONLY);
+                    BackupDataInput in = new BackupDataInput(readFd.getFileDescriptor());
+                    try {
+                        while (in.readNextHeader()) {
+                            final String key = in.getKey();
+                            if (key != null && key.charAt(0) >= 0xff00) {
+                                // Not okay: crash them and bail.
+                                failAgent(mAgentBinder, "Illegal backup key: " + key);
+                                backupManagerService
+                                        .addBackupTrace("illegal key " + key + " from " + pkgName);
+                                EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, pkgName,
+                                        "bad key");
+                                mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                                        BackupManagerMonitor.LOG_EVENT_ID_ILLEGAL_KEY,
+                                        mCurrentPackage,
+                                        BackupManagerMonitor
+                                                .LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                        BackupManagerMonitorUtils.putMonitoringExtra(null,
+                                                BackupManagerMonitor.EXTRA_LOG_ILLEGAL_KEY,
+                                                key));
+                                backupManagerService.getBackupHandler().removeMessages(
+                                        MSG_BACKUP_OPERATION_TIMEOUT);
+                                BackupObserverUtils
+                                        .sendBackupOnPackageResult(mObserver, pkgName,
+                                                BackupManager.ERROR_AGENT_FAILURE);
+                                errorCleanup();
+                                // agentErrorCleanup() implicitly executes next state properly
+                                return;
+                            }
+                            in.skipEntityData();
+                        }
+                    } finally {
+                        if (readFd != null) {
+                            readFd.close();
+                        }
+                    }
+                }
+
+                // Piggyback the widget state payload, if any
+                writeWidgetPayloadIfAppropriate(fd, pkgName);
+            } catch (IOException e) {
+                // Hard disk error; recovery/failure policy TBD.  For now roll back,
+                // but we may want to consider this a transport-level failure (i.e.
+                // we're in such a bad state that we can't contemplate doing backup
+                // operations any more during this pass).
+                Slog.w(TAG, "Unable to save widget state for " + pkgName);
+                try {
+                    Os.ftruncate(fd, filepos);
+                } catch (ErrnoException ee) {
+                    Slog.w(TAG, "Unable to roll back!");
+                }
+            }
+
+            // Spin the data off to the transport and proceed with the next stage.
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "operationComplete(): sending data to transport for "
+                        + pkgName);
+            }
+            backupManagerService.getBackupHandler().removeMessages(MSG_BACKUP_OPERATION_TIMEOUT);
+            clearAgentState();
+            backupManagerService.addBackupTrace("operation complete");
+
+            ParcelFileDescriptor backupData = null;
+            mStatus = BackupTransport.TRANSPORT_OK;
+            long size = 0;
+            try {
+                size = mBackupDataName.length();
+                if (size > 0) {
+                    if (mStatus == BackupTransport.TRANSPORT_OK) {
+                        backupData = ParcelFileDescriptor.open(mBackupDataName,
+                                ParcelFileDescriptor.MODE_READ_ONLY);
+                        backupManagerService.addBackupTrace("sending data to transport");
+                        int flags = mUserInitiated ? BackupTransport.FLAG_USER_INITIATED : 0;
+                        mStatus = mTransport.performBackup(mCurrentPackage, backupData, flags);
+                    }
+
+                    // TODO - We call finishBackup() for each application backed up, because
+                    // we need to know now whether it succeeded or failed.  Instead, we should
+                    // hold off on finishBackup() until the end, which implies holding off on
+                    // renaming *all* the output state files (see below) until that happens.
+
+                    backupManagerService.addBackupTrace("data delivered: " + mStatus);
+                    if (mStatus == BackupTransport.TRANSPORT_OK) {
+                        backupManagerService.addBackupTrace("finishing op on transport");
+                        mStatus = mTransport.finishBackup();
+                        backupManagerService.addBackupTrace("finished: " + mStatus);
+                    } else if (mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+                        backupManagerService.addBackupTrace("transport rejected package");
+                    }
+                } else {
+                    if (MORE_DEBUG) {
+                        Slog.i(TAG, "no backup data written; not calling transport");
+                    }
+                    backupManagerService.addBackupTrace("no data to send");
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                            BackupManagerMonitor.LOG_EVENT_ID_NO_DATA_TO_SEND,
+                            mCurrentPackage,
+                            BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            null);
+                }
+
+                if (mStatus == BackupTransport.TRANSPORT_OK) {
+                    // After successful transport, delete the now-stale data
+                    // and juggle the files so that next time we supply the agent
+                    // with the new state file it just created.
+                    mBackupDataName.delete();
+                    mNewStateName.renameTo(mSavedStateName);
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mObserver, pkgName, BackupManager.SUCCESS);
+                    EventLog.writeEvent(EventLogTags.BACKUP_PACKAGE, pkgName, size);
+                    backupManagerService.logBackupComplete(pkgName);
+                } else if (mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+                    // The transport has rejected backup of this specific package.  Roll it
+                    // back but proceed with running the rest of the queue.
+                    mBackupDataName.delete();
+                    mNewStateName.delete();
+                    BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+                            BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
+                    EventLogTags.writeBackupAgentFailure(pkgName, "Transport rejected");
+                } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                    BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+                            BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
+                    EventLog.writeEvent(EventLogTags.BACKUP_QUOTA_EXCEEDED, pkgName);
+                } else {
+                    // Actual transport-level failure to communicate the data to the backend
+                    BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+                            BackupManager.ERROR_TRANSPORT_ABORTED);
+                    EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
+                }
+            } catch (Exception e) {
+                BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+                        BackupManager.ERROR_TRANSPORT_ABORTED);
+                Slog.e(TAG, "Transport error backing up " + pkgName, e);
+                EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
+                mStatus = BackupTransport.TRANSPORT_ERROR;
+            } finally {
+                try {
+                    if (backupData != null) backupData.close();
+                } catch (IOException e) {
+                }
+            }
+
+            final BackupState nextState;
+            if (mStatus == BackupTransport.TRANSPORT_OK
+                    || mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+                // Success or single-package rejection.  Proceed with the next app if any,
+                // otherwise we're done.
+                nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE;
+            } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Package " + mCurrentPackage.packageName +
+                            " hit quota limit on k/v backup");
+                }
+                if (mAgentBinder != null) {
+                    try {
+                        long quota = mTransport.getBackupQuota(mCurrentPackage.packageName,
+                                false);
+                        mAgentBinder.doQuotaExceeded(size, quota);
+                    } catch (Exception e) {
+                        Slog.e(TAG, "Unable to notify about quota exceeded: " + e.getMessage());
+                    }
+                }
+                nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE;
+            } else {
+                // Any other error here indicates a transport-level failure.  That means
+                // we need to halt everything and reschedule everything for next time.
+                revertAndEndBackup();
+                nextState = BackupState.FINAL;
+            }
+
+            executeNextState(nextState);
+        }
+    }
+
+
+    @Override
+    @GuardedBy("mCancelLock")
+    public void handleCancel(boolean cancelAll) {
+        backupManagerService.removeOperation(mEphemeralOpToken);
+        synchronized (mCancelLock) {
+            if (mFinished) {
+                // We have already cancelled this operation.
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Ignoring stale cancel. cancelAll=" + cancelAll);
+                }
+                return;
+            }
+            mCancelAll = cancelAll;
+            final String logPackageName = (mCurrentPackage != null)
+                    ? mCurrentPackage.packageName
+                    : "no_package_yet";
+            Slog.i(TAG, "Cancel backing up " + logPackageName);
+            EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, logPackageName);
+            backupManagerService.addBackupTrace(
+                    "cancel of " + logPackageName + ", cancelAll=" + cancelAll);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL,
+                    mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
+                    BackupManagerMonitorUtils.putMonitoringExtra(null,
+                            BackupManagerMonitor.EXTRA_LOG_CANCEL_ALL,
+                            mCancelAll));
+            errorCleanup();
+            if (!cancelAll) {
+                // The current agent either timed out or was cancelled running doBackup().
+                // Restage it for the next time we run a backup pass.
+                // !!! TODO: keep track of failure counts per agent, and blacklist those which
+                // fail repeatedly (i.e. have proved themselves to be buggy).
+                executeNextState(
+                        mQueue.isEmpty() ? BackupState.FINAL : BackupState.RUNNING_QUEUE);
+                backupManagerService.dataChangedImpl(mCurrentPackage.packageName);
+            } else {
+                finalizeBackup();
+            }
+        }
+    }
+
+    void revertAndEndBackup() {
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "Reverting backup queue - restaging everything");
+        }
+        backupManagerService.addBackupTrace("transport error; reverting");
+
+        // We want to reset the backup schedule based on whatever the transport suggests
+        // by way of retry/backoff time.
+        long delay;
+        try {
+            delay = mTransport.requestBackupTime();
+        } catch (Exception e) {
+            Slog.w(TAG, "Unable to contact transport for recommended backoff: " + e.getMessage());
+            delay = 0;  // use the scheduler's default
+        }
+        KeyValueBackupJob.schedule(backupManagerService.getContext(), delay);
+
+        for (BackupRequest request : mOriginalQueue) {
+            backupManagerService.dataChangedImpl(request.packageName);
+        }
+
+    }
+
+    void errorCleanup() {
+        mBackupDataName.delete();
+        mNewStateName.delete();
+        clearAgentState();
+    }
+
+    // Cleanup common to both success and failure cases
+    void clearAgentState() {
+        try {
+            if (mSavedState != null) mSavedState.close();
+        } catch (IOException e) {
+        }
+        try {
+            if (mBackupData != null) mBackupData.close();
+        } catch (IOException e) {
+        }
+        try {
+            if (mNewState != null) mNewState.close();
+        } catch (IOException e) {
+        }
+        synchronized (backupManagerService.getCurrentOpLock()) {
+            // Current-operation callback handling requires the validity of these various
+            // bits of internal state as an invariant of the operation still being live.
+            // This means we make sure to clear all of the state in unison inside the lock.
+            backupManagerService.getCurrentOperations().remove(mEphemeralOpToken);
+            mSavedState = mBackupData = mNewState = null;
+        }
+
+        // If this was a pseudopackage there's no associated Activity Manager state
+        if (mCurrentPackage.applicationInfo != null) {
+            backupManagerService.addBackupTrace("unbinding " + mCurrentPackage.packageName);
+            try {  // unbind even on timeout, just in case
+                backupManagerService.getActivityManager().unbindBackupAgent(
+                        mCurrentPackage.applicationInfo);
+            } catch (RemoteException e) { /* can't happen; activity manager is local */ }
+        }
+    }
+
+    void executeNextState(BackupState nextState) {
+        if (MORE_DEBUG) {
+            Slog.i(TAG, " => executing next step on "
+                    + this + " nextState=" + nextState);
+        }
+        backupManagerService.addBackupTrace("executeNextState => " + nextState);
+        mCurrentState = nextState;
+        Message msg = backupManagerService.getBackupHandler().obtainMessage(
+                MSG_BACKUP_RESTORE_STEP, this);
+        backupManagerService.getBackupHandler().sendMessage(msg);
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/PerformClearTask.java b/services/backup/java/com/android/server/backup/internal/PerformClearTask.java
new file mode 100644
index 0000000..7af01ea
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/PerformClearTask.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.internal;
+
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.content.pm.PackageInfo;
+import android.util.Slog;
+
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.backup.RefactoredBackupManagerService;
+
+import java.io.File;
+
+public class PerformClearTask implements Runnable {
+
+    private RefactoredBackupManagerService backupManagerService;
+    IBackupTransport mTransport;
+    PackageInfo mPackage;
+
+    PerformClearTask(RefactoredBackupManagerService backupManagerService,
+            IBackupTransport transport, PackageInfo packageInfo) {
+        this.backupManagerService = backupManagerService;
+        mTransport = transport;
+        mPackage = packageInfo;
+    }
+
+    public void run() {
+        try {
+            // Clear the on-device backup state to ensure a full backup next time
+            File stateDir = new File(backupManagerService.getBaseStateDir(),
+                    mTransport.transportDirName());
+            File stateFile = new File(stateDir, mPackage.packageName);
+            stateFile.delete();
+
+            // Tell the transport to remove all the persistent storage for the app
+            // TODO - need to handle failures
+            mTransport.clearBackupData(mPackage);
+        } catch (Exception e) {
+            Slog.e(TAG, "Transport threw clearing data for " + mPackage + ": " + e.getMessage());
+        } finally {
+            try {
+                // TODO - need to handle failures
+                mTransport.finishBackup();
+            } catch (Exception e) {
+                // Nothing we can do here, alas
+                Slog.e(TAG, "Unable to mark clear operation finished: " + e.getMessage());
+            }
+
+            // Last but not least, release the cpu
+            backupManagerService.getWakelock().release();
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/PerformInitializeTask.java b/services/backup/java/com/android/server/backup/internal/PerformInitializeTask.java
new file mode 100644
index 0000000..5a75b66
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/PerformInitializeTask.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.internal;
+
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.AlarmManager;
+import android.app.backup.BackupTransport;
+import android.os.SystemClock;
+import android.util.EventLog;
+import android.util.Slog;
+
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.EventLogTags;
+import com.android.server.backup.RefactoredBackupManagerService;
+
+import java.io.File;
+import java.util.HashSet;
+
+public class PerformInitializeTask implements Runnable {
+
+    private RefactoredBackupManagerService backupManagerService;
+    HashSet<String> mQueue;
+
+    PerformInitializeTask(RefactoredBackupManagerService backupManagerService,
+            HashSet<String> transportNames) {
+        this.backupManagerService = backupManagerService;
+        mQueue = transportNames;
+    }
+
+    public void run() {
+        try {
+            for (String transportName : mQueue) {
+                IBackupTransport transport =
+                        backupManagerService.getTransportManager().getTransportBinder(
+                                transportName);
+                if (transport == null) {
+                    Slog.e(TAG, "Requested init for " + transportName + " but not found");
+                    continue;
+                }
+
+                Slog.i(TAG, "Initializing (wiping) backup transport storage: " + transportName);
+                EventLog.writeEvent(EventLogTags.BACKUP_START, transport.transportDirName());
+                long startRealtime = SystemClock.elapsedRealtime();
+                int status = transport.initializeDevice();
+
+                if (status == BackupTransport.TRANSPORT_OK) {
+                    status = transport.finishBackup();
+                }
+
+                // Okay, the wipe really happened.  Clean up our local bookkeeping.
+                if (status == BackupTransport.TRANSPORT_OK) {
+                    Slog.i(TAG, "Device init successful");
+                    int millis = (int) (SystemClock.elapsedRealtime() - startRealtime);
+                    EventLog.writeEvent(EventLogTags.BACKUP_INITIALIZE);
+                    backupManagerService
+                            .resetBackupState(new File(backupManagerService.getBaseStateDir(),
+                                    transport.transportDirName()));
+                    EventLog.writeEvent(EventLogTags.BACKUP_SUCCESS, 0, millis);
+                    synchronized (backupManagerService.getQueueLock()) {
+                        backupManagerService.recordInitPendingLocked(false, transportName);
+                    }
+                } else {
+                    // If this didn't work, requeue this one and try again
+                    // after a suitable interval
+                    Slog.e(TAG, "Transport error in initializeDevice()");
+                    EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, "(initialize)");
+                    synchronized (backupManagerService.getQueueLock()) {
+                        backupManagerService.recordInitPendingLocked(true, transportName);
+                    }
+                    // do this via another alarm to make sure of the wakelock states
+                    long delay = transport.requestBackupTime();
+                    Slog.w(TAG, "Init failed on " + transportName + " resched in " + delay);
+                    backupManagerService.getAlarmManager().set(AlarmManager.RTC_WAKEUP,
+                            System.currentTimeMillis() + delay,
+                            backupManagerService.getRunInitIntent());
+                }
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "Unexpected error performing init", e);
+        } finally {
+            // Done; release the wakelock
+            backupManagerService.getWakelock().release();
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/ProvisionedObserver.java b/services/backup/java/com/android/server/backup/internal/ProvisionedObserver.java
new file mode 100644
index 0000000..e92b8be
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/ProvisionedObserver.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.internal;
+
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.util.Slog;
+
+import com.android.server.backup.KeyValueBackupJob;
+import com.android.server.backup.RefactoredBackupManagerService;
+
+public class ProvisionedObserver extends ContentObserver {
+
+    private RefactoredBackupManagerService backupManagerService;
+
+    public ProvisionedObserver(
+            RefactoredBackupManagerService backupManagerService, Handler handler) {
+        super(handler);
+        this.backupManagerService = backupManagerService;
+    }
+
+    public void onChange(boolean selfChange) {
+        final boolean wasProvisioned = backupManagerService.isProvisioned();
+        final boolean isProvisioned = backupManagerService.deviceIsProvisioned();
+        // latch: never unprovision
+        backupManagerService.setProvisioned(wasProvisioned || isProvisioned);
+        if (MORE_DEBUG) {
+            Slog.d(TAG, "Provisioning change: was=" + wasProvisioned
+                    + " is=" + isProvisioned + " now=" + backupManagerService.isProvisioned());
+        }
+
+        synchronized (backupManagerService.getQueueLock()) {
+            if (backupManagerService.isProvisioned() && !wasProvisioned
+                    && backupManagerService.isEnabled()) {
+                // we're now good to go, so start the backup alarms
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Now provisioned, so starting backups");
+                }
+                KeyValueBackupJob.schedule(backupManagerService.getContext());
+                backupManagerService.scheduleNextFullBackupJob(0);
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/RunBackupReceiver.java b/services/backup/java/com/android/server/backup/internal/RunBackupReceiver.java
new file mode 100644
index 0000000..f1fa7eb
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/RunBackupReceiver.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.internal;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.RUN_BACKUP_ACTION;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_BACKUP;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Message;
+import android.util.Slog;
+
+import com.android.server.backup.RefactoredBackupManagerService;
+
+public class RunBackupReceiver extends BroadcastReceiver {
+
+    private RefactoredBackupManagerService backupManagerService;
+
+    public RunBackupReceiver(RefactoredBackupManagerService backupManagerService) {
+        this.backupManagerService = backupManagerService;
+    }
+
+    public void onReceive(Context context, Intent intent) {
+        if (RUN_BACKUP_ACTION.equals(intent.getAction())) {
+            synchronized (backupManagerService.getQueueLock()) {
+                if (backupManagerService.getPendingInits().size() > 0) {
+                    // If there are pending init operations, we process those
+                    // and then settle into the usual periodic backup schedule.
+                    if (MORE_DEBUG) {
+                        Slog.v(TAG, "Init pending at scheduled backup");
+                    }
+                    try {
+                        backupManagerService.getAlarmManager().cancel(
+                                backupManagerService.getRunInitIntent());
+                        backupManagerService.getRunInitIntent().send();
+                    } catch (PendingIntent.CanceledException ce) {
+                        Slog.e(TAG, "Run init intent cancelled");
+                        // can't really do more than bail here
+                    }
+                } else {
+                    // Don't run backups now if we're disabled or not yet
+                    // fully set up.
+                    if (backupManagerService.isEnabled() && backupManagerService.isProvisioned()) {
+                        if (!backupManagerService.isBackupRunning()) {
+                            if (DEBUG) {
+                                Slog.v(TAG, "Running a backup pass");
+                            }
+
+                            // Acquire the wakelock and pass it to the backup thread.  it will
+                            // be released once backup concludes.
+                            backupManagerService.setBackupRunning(true);
+                            backupManagerService.getWakelock().acquire();
+
+                            Message msg = backupManagerService.getBackupHandler().obtainMessage(
+                                    MSG_RUN_BACKUP);
+                            backupManagerService.getBackupHandler().sendMessage(msg);
+                        } else {
+                            Slog.i(TAG, "Backup time but one already running");
+                        }
+                    } else {
+                        Slog.w(TAG, "Backup pass but e=" + backupManagerService.isEnabled() + " p="
+                                + backupManagerService.isProvisioned());
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/RunInitializeReceiver.java b/services/backup/java/com/android/server/backup/internal/RunInitializeReceiver.java
new file mode 100644
index 0000000..1621a91
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/RunInitializeReceiver.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.internal;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.RUN_INITIALIZE_ACTION;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_INITIALIZE;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Message;
+import android.util.Slog;
+
+import com.android.server.backup.RefactoredBackupManagerService;
+
+public class RunInitializeReceiver extends BroadcastReceiver {
+
+    private RefactoredBackupManagerService backupManagerService;
+
+    public RunInitializeReceiver(RefactoredBackupManagerService backupManagerService) {
+        this.backupManagerService = backupManagerService;
+    }
+
+    public void onReceive(Context context, Intent intent) {
+        if (RUN_INITIALIZE_ACTION.equals(intent.getAction())) {
+            synchronized (backupManagerService.getQueueLock()) {
+                if (DEBUG) {
+                    Slog.v(TAG, "Running a device init");
+                }
+
+                // Acquire the wakelock and pass it to the init thread.  it will
+                // be released once init concludes.
+                backupManagerService.getWakelock().acquire();
+
+                Message msg = backupManagerService.getBackupHandler().obtainMessage(
+                        MSG_RUN_INITIALIZE);
+                backupManagerService.getBackupHandler().sendMessage(msg);
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/AdbBackupParams.java b/services/backup/java/com/android/server/backup/params/AdbBackupParams.java
new file mode 100644
index 0000000..5c1ba24
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/AdbBackupParams.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.params;
+
+import android.os.ParcelFileDescriptor;
+
+public class AdbBackupParams extends AdbParams {
+
+    public boolean includeApks;
+    public boolean includeObbs;
+    public boolean includeShared;
+    public boolean doWidgets;
+    public boolean allApps;
+    public boolean includeSystem;
+    public boolean doCompress;
+    public boolean includeKeyValue;
+    public String[] packages;
+
+    public AdbBackupParams(ParcelFileDescriptor output, boolean saveApks, boolean saveObbs,
+            boolean saveShared, boolean alsoWidgets, boolean doAllApps, boolean doSystem,
+            boolean compress, boolean doKeyValue, String[] pkgList) {
+        fd = output;
+        includeApks = saveApks;
+        includeObbs = saveObbs;
+        includeShared = saveShared;
+        doWidgets = alsoWidgets;
+        allApps = doAllApps;
+        includeSystem = doSystem;
+        doCompress = compress;
+        includeKeyValue = doKeyValue;
+        packages = pkgList;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/AdbParams.java b/services/backup/java/com/android/server/backup/params/AdbParams.java
new file mode 100644
index 0000000..392f40d
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/AdbParams.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.params;
+
+import android.app.backup.IFullBackupRestoreObserver;
+import android.os.ParcelFileDescriptor;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Parameters used by adbBackup() and adbRestore().
+ */
+public class AdbParams {
+
+    public ParcelFileDescriptor fd;
+    public final AtomicBoolean latch;
+    public IFullBackupRestoreObserver observer;
+    public String curPassword;     // filled in by the confirmation step
+    public String encryptPassword;
+
+    AdbParams() {
+        latch = new AtomicBoolean(false);
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/AdbRestoreParams.java b/services/backup/java/com/android/server/backup/params/AdbRestoreParams.java
new file mode 100644
index 0000000..0142fe0
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/AdbRestoreParams.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.params;
+
+import android.os.ParcelFileDescriptor;
+
+public class AdbRestoreParams extends AdbParams {
+
+    public AdbRestoreParams(ParcelFileDescriptor input) {
+        fd = input;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/BackupParams.java b/services/backup/java/com/android/server/backup/params/BackupParams.java
new file mode 100644
index 0000000..4fd7ddb
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/BackupParams.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.params;
+
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
+
+import com.android.internal.backup.IBackupTransport;
+
+import java.util.ArrayList;
+
+public class BackupParams {
+
+    public IBackupTransport transport;
+    public String dirName;
+    public ArrayList<String> kvPackages;
+    public ArrayList<String> fullPackages;
+    public IBackupObserver observer;
+    public IBackupManagerMonitor monitor;
+    public boolean userInitiated;
+    public boolean nonIncrementalBackup;
+
+    public BackupParams(IBackupTransport transport, String dirName, ArrayList<String> kvPackages,
+            ArrayList<String> fullPackages, IBackupObserver observer,
+            IBackupManagerMonitor monitor, boolean userInitiated, boolean nonIncrementalBackup) {
+        this.transport = transport;
+        this.dirName = dirName;
+        this.kvPackages = kvPackages;
+        this.fullPackages = fullPackages;
+        this.observer = observer;
+        this.monitor = monitor;
+        this.userInitiated = userInitiated;
+        this.nonIncrementalBackup = nonIncrementalBackup;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/ClearParams.java b/services/backup/java/com/android/server/backup/params/ClearParams.java
new file mode 100644
index 0000000..d744efc
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/ClearParams.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.params;
+
+import android.content.pm.PackageInfo;
+
+import com.android.internal.backup.IBackupTransport;
+
+public class ClearParams {
+
+    public IBackupTransport transport;
+    public PackageInfo packageInfo;
+
+    public ClearParams(IBackupTransport _transport, PackageInfo _info) {
+        transport = _transport;
+        packageInfo = _info;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/ClearRetryParams.java b/services/backup/java/com/android/server/backup/params/ClearRetryParams.java
new file mode 100644
index 0000000..fcf66e4
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/ClearRetryParams.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.params;
+
+public class ClearRetryParams {
+
+    public String transportName;
+    public String packageName;
+
+    public ClearRetryParams(String transport, String pkg) {
+        transportName = transport;
+        packageName = pkg;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/RestoreGetSetsParams.java b/services/backup/java/com/android/server/backup/params/RestoreGetSetsParams.java
new file mode 100644
index 0000000..bff476b
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/RestoreGetSetsParams.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.params;
+
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IRestoreObserver;
+
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.backup.restore.ActiveRestoreSession;
+
+public class RestoreGetSetsParams {
+
+    public IBackupTransport transport;
+    public ActiveRestoreSession session;
+    public IRestoreObserver observer;
+    public IBackupManagerMonitor monitor;
+
+    public RestoreGetSetsParams(IBackupTransport _transport, ActiveRestoreSession _session,
+            IRestoreObserver _observer, IBackupManagerMonitor _monitor) {
+        transport = _transport;
+        session = _session;
+        observer = _observer;
+        monitor = _monitor;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/RestoreParams.java b/services/backup/java/com/android/server/backup/params/RestoreParams.java
new file mode 100644
index 0000000..93ce00d
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/RestoreParams.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.params;
+
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IRestoreObserver;
+import android.content.pm.PackageInfo;
+
+import com.android.internal.backup.IBackupTransport;
+
+public class RestoreParams {
+
+    public IBackupTransport transport;
+    public String dirName;
+    public IRestoreObserver observer;
+    public IBackupManagerMonitor monitor;
+    public long token;
+    public PackageInfo pkgInfo;
+    public int pmToken; // in post-install restore, the PM's token for this transaction
+    public boolean isSystemRestore;
+    public String[] filterSet;
+
+    /**
+     * Restore a single package; no kill after restore
+     */
+    public RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
+            IBackupManagerMonitor _monitor, long _token, PackageInfo _pkg) {
+        transport = _transport;
+        dirName = _dirName;
+        observer = _obs;
+        monitor = _monitor;
+        token = _token;
+        pkgInfo = _pkg;
+        pmToken = 0;
+        isSystemRestore = false;
+        filterSet = null;
+    }
+
+    /**
+     * Restore at install: PM token needed, kill after restore
+     */
+    public RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
+            IBackupManagerMonitor _monitor, long _token, String _pkgName, int _pmToken) {
+        transport = _transport;
+        dirName = _dirName;
+        observer = _obs;
+        monitor = _monitor;
+        token = _token;
+        pkgInfo = null;
+        pmToken = _pmToken;
+        isSystemRestore = false;
+        filterSet = new String[]{_pkgName};
+    }
+
+    /**
+     * Restore everything possible.  This is the form that Setup Wizard or similar
+     * restore UXes use.
+     */
+    public RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
+            IBackupManagerMonitor _monitor, long _token) {
+        transport = _transport;
+        dirName = _dirName;
+        observer = _obs;
+        monitor = _monitor;
+        token = _token;
+        pkgInfo = null;
+        pmToken = 0;
+        isSystemRestore = true;
+        filterSet = null;
+    }
+
+    /**
+     * Restore some set of packages.  Leave this one up to the caller to specify
+     * whether it's to be considered a system-level restore.
+     */
+    public RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
+            IBackupManagerMonitor _monitor, long _token,
+            String[] _filterSet, boolean _isSystemRestore) {
+        transport = _transport;
+        dirName = _dirName;
+        observer = _obs;
+        monitor = _monitor;
+        token = _token;
+        pkgInfo = null;
+        pmToken = 0;
+        isSystemRestore = _isSystemRestore;
+        filterSet = _filterSet;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java b/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
new file mode 100644
index 0000000..8d8a013
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.restore;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_GET_RESTORE_SETS;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_RESTORE;
+
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IRestoreObserver;
+import android.app.backup.IRestoreSession;
+import android.app.backup.RestoreSet;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Binder;
+import android.os.Message;
+import android.util.Slog;
+
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.params.RestoreGetSetsParams;
+import com.android.server.backup.params.RestoreParams;
+
+/**
+ * Restore session.
+ */
+public class ActiveRestoreSession extends IRestoreSession.Stub {
+
+    private static final String TAG = "RestoreSession";
+
+    private RefactoredBackupManagerService backupManagerService;
+    private String mPackageName;
+    private IBackupTransport mRestoreTransport = null;
+    public RestoreSet[] mRestoreSets = null;
+    boolean mEnded = false;
+    boolean mTimedOut = false;
+
+    public ActiveRestoreSession(RefactoredBackupManagerService backupManagerService,
+            String packageName, String transport) {
+        this.backupManagerService = backupManagerService;
+        mPackageName = packageName;
+        mRestoreTransport = backupManagerService.getTransportManager().getTransportBinder(
+                transport);
+    }
+
+    public void markTimedOut() {
+        mTimedOut = true;
+    }
+
+    // --- Binder interface ---
+    public synchronized int getAvailableRestoreSets(IRestoreObserver observer,
+            IBackupManagerMonitor monitor) {
+        backupManagerService.getContext().enforceCallingOrSelfPermission(
+                android.Manifest.permission.BACKUP,
+                "getAvailableRestoreSets");
+        if (observer == null) {
+            throw new IllegalArgumentException("Observer must not be null");
+        }
+
+        if (mEnded) {
+            throw new IllegalStateException("Restore session already ended");
+        }
+
+        if (mTimedOut) {
+            Slog.i(TAG, "Session already timed out");
+            return -1;
+        }
+
+        long oldId = Binder.clearCallingIdentity();
+        try {
+            if (mRestoreTransport == null) {
+                Slog.w(TAG, "Null transport getting restore sets");
+                return -1;
+            }
+
+            // We know we're doing legit work now, so halt the timeout
+            // until we're done.  It gets started again when the result
+            // comes in.
+            backupManagerService.getBackupHandler().removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
+
+            // spin off the transport request to our service thread
+            backupManagerService.getWakelock().acquire();
+            Message msg = backupManagerService.getBackupHandler().obtainMessage(
+                    MSG_RUN_GET_RESTORE_SETS,
+                    new RestoreGetSetsParams(mRestoreTransport, this, observer,
+                            monitor));
+            backupManagerService.getBackupHandler().sendMessage(msg);
+            return 0;
+        } catch (Exception e) {
+            Slog.e(TAG, "Error in getAvailableRestoreSets", e);
+            return -1;
+        } finally {
+            Binder.restoreCallingIdentity(oldId);
+        }
+    }
+
+    public synchronized int restoreAll(long token, IRestoreObserver observer,
+            IBackupManagerMonitor monitor) {
+        backupManagerService.getContext().enforceCallingOrSelfPermission(
+                android.Manifest.permission.BACKUP,
+                "performRestore");
+
+        if (DEBUG) {
+            Slog.d(TAG, "restoreAll token=" + Long.toHexString(token)
+                    + " observer=" + observer);
+        }
+
+        if (mEnded) {
+            throw new IllegalStateException("Restore session already ended");
+        }
+
+        if (mTimedOut) {
+            Slog.i(TAG, "Session already timed out");
+            return -1;
+        }
+
+        if (mRestoreTransport == null || mRestoreSets == null) {
+            Slog.e(TAG, "Ignoring restoreAll() with no restore set");
+            return -1;
+        }
+
+        if (mPackageName != null) {
+            Slog.e(TAG, "Ignoring restoreAll() on single-package session");
+            return -1;
+        }
+
+        String dirName;
+        try {
+            dirName = mRestoreTransport.transportDirName();
+        } catch (Exception e) {
+            // Transport went AWOL; fail.
+            Slog.e(TAG, "Unable to get transport dir for restore: " + e.getMessage());
+            return -1;
+        }
+
+        synchronized (backupManagerService.getQueueLock()) {
+            for (int i = 0; i < mRestoreSets.length; i++) {
+                if (token == mRestoreSets[i].token) {
+                    // Real work, so stop the session timeout until we finalize the restore
+                    backupManagerService.getBackupHandler().removeMessages(
+                            MSG_RESTORE_SESSION_TIMEOUT);
+
+                    long oldId = Binder.clearCallingIdentity();
+                    backupManagerService.getWakelock().acquire();
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "restoreAll() kicking off");
+                    }
+                    Message msg = backupManagerService.getBackupHandler().obtainMessage(
+                            MSG_RUN_RESTORE);
+                    msg.obj = new RestoreParams(mRestoreTransport, dirName,
+                            observer, monitor, token);
+                    backupManagerService.getBackupHandler().sendMessage(msg);
+                    Binder.restoreCallingIdentity(oldId);
+                    return 0;
+                }
+            }
+        }
+
+        Slog.w(TAG, "Restore token " + Long.toHexString(token) + " not found");
+        return -1;
+    }
+
+    // Restores of more than a single package are treated as 'system' restores
+    public synchronized int restoreSome(long token, IRestoreObserver observer,
+            IBackupManagerMonitor monitor, String[] packages) {
+        backupManagerService.getContext().enforceCallingOrSelfPermission(
+                android.Manifest.permission.BACKUP,
+                "performRestore");
+
+        if (DEBUG) {
+            StringBuilder b = new StringBuilder(128);
+            b.append("restoreSome token=");
+            b.append(Long.toHexString(token));
+            b.append(" observer=");
+            b.append(observer.toString());
+            b.append(" monitor=");
+            if (monitor == null) {
+                b.append("null");
+            } else {
+                b.append(monitor.toString());
+            }
+            b.append(" packages=");
+            if (packages == null) {
+                b.append("null");
+            } else {
+                b.append('{');
+                boolean first = true;
+                for (String s : packages) {
+                    if (!first) {
+                        b.append(", ");
+                    } else {
+                        first = false;
+                    }
+                    b.append(s);
+                }
+                b.append('}');
+            }
+            Slog.d(TAG, b.toString());
+        }
+
+        if (mEnded) {
+            throw new IllegalStateException("Restore session already ended");
+        }
+
+        if (mTimedOut) {
+            Slog.i(TAG, "Session already timed out");
+            return -1;
+        }
+
+        if (mRestoreTransport == null || mRestoreSets == null) {
+            Slog.e(TAG, "Ignoring restoreAll() with no restore set");
+            return -1;
+        }
+
+        if (mPackageName != null) {
+            Slog.e(TAG, "Ignoring restoreAll() on single-package session");
+            return -1;
+        }
+
+        String dirName;
+        try {
+            dirName = mRestoreTransport.transportDirName();
+        } catch (Exception e) {
+            // Transport went AWOL; fail.
+            Slog.e(TAG, "Unable to get transport name for restoreSome: " + e.getMessage());
+            return -1;
+        }
+
+        synchronized (backupManagerService.getQueueLock()) {
+            for (int i = 0; i < mRestoreSets.length; i++) {
+                if (token == mRestoreSets[i].token) {
+                    // Stop the session timeout until we finalize the restore
+                    backupManagerService.getBackupHandler().removeMessages(
+                            MSG_RESTORE_SESSION_TIMEOUT);
+
+                    long oldId = Binder.clearCallingIdentity();
+                    backupManagerService.getWakelock().acquire();
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "restoreSome() of " + packages.length + " packages");
+                    }
+                    Message msg = backupManagerService.getBackupHandler().obtainMessage(
+                            MSG_RUN_RESTORE);
+                    msg.obj = new RestoreParams(mRestoreTransport, dirName, observer, monitor,
+                            token, packages, packages.length > 1);
+                    backupManagerService.getBackupHandler().sendMessage(msg);
+                    Binder.restoreCallingIdentity(oldId);
+                    return 0;
+                }
+            }
+        }
+
+        Slog.w(TAG, "Restore token " + Long.toHexString(token) + " not found");
+        return -1;
+    }
+
+    public synchronized int restorePackage(String packageName, IRestoreObserver observer,
+            IBackupManagerMonitor monitor) {
+        if (DEBUG) {
+            Slog.v(TAG, "restorePackage pkg=" + packageName + " obs=" + observer
+                    + "monitor=" + monitor);
+        }
+
+        if (mEnded) {
+            throw new IllegalStateException("Restore session already ended");
+        }
+
+        if (mTimedOut) {
+            Slog.i(TAG, "Session already timed out");
+            return -1;
+        }
+
+        if (mPackageName != null) {
+            if (!mPackageName.equals(packageName)) {
+                Slog.e(TAG, "Ignoring attempt to restore pkg=" + packageName
+                        + " on session for package " + mPackageName);
+                return -1;
+            }
+        }
+
+        PackageInfo app = null;
+        try {
+            app = backupManagerService.getPackageManager().getPackageInfo(packageName, 0);
+        } catch (NameNotFoundException nnf) {
+            Slog.w(TAG, "Asked to restore nonexistent pkg " + packageName);
+            return -1;
+        }
+
+        // If the caller is not privileged and is not coming from the target
+        // app's uid, throw a permission exception back to the caller.
+        int perm = backupManagerService.getContext().checkPermission(
+                android.Manifest.permission.BACKUP,
+                Binder.getCallingPid(), Binder.getCallingUid());
+        if ((perm == PackageManager.PERMISSION_DENIED) &&
+                (app.applicationInfo.uid != Binder.getCallingUid())) {
+            Slog.w(TAG, "restorePackage: bad packageName=" + packageName
+                    + " or calling uid=" + Binder.getCallingUid());
+            throw new SecurityException("No permission to restore other packages");
+        }
+
+        // So far so good; we're allowed to try to restore this package.
+        long oldId = Binder.clearCallingIdentity();
+        try {
+            // Check whether there is data for it in the current dataset, falling back
+            // to the ancestral dataset if not.
+            long token = backupManagerService.getAvailableRestoreToken(packageName);
+            if (DEBUG) {
+                Slog.v(TAG, "restorePackage pkg=" + packageName
+                        + " token=" + Long.toHexString(token));
+            }
+
+            // If we didn't come up with a place to look -- no ancestral dataset and
+            // the app has never been backed up from this device -- there's nothing
+            // to do but return failure.
+            if (token == 0) {
+                if (DEBUG) {
+                    Slog.w(TAG, "No data available for this package; not restoring");
+                }
+                return -1;
+            }
+
+            String dirName;
+            try {
+                dirName = mRestoreTransport.transportDirName();
+            } catch (Exception e) {
+                // Transport went AWOL; fail.
+                Slog.e(TAG, "Unable to get transport dir for restorePackage: " + e.getMessage());
+                return -1;
+            }
+
+            // Stop the session timeout until we finalize the restore
+            backupManagerService.getBackupHandler().removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
+
+            // Ready to go:  enqueue the restore request and claim success
+            backupManagerService.getWakelock().acquire();
+            if (MORE_DEBUG) {
+                Slog.d(TAG, "restorePackage() : " + packageName);
+            }
+            Message msg = backupManagerService.getBackupHandler().obtainMessage(MSG_RUN_RESTORE);
+            msg.obj = new RestoreParams(mRestoreTransport, dirName, observer, monitor,
+                    token, app);
+            backupManagerService.getBackupHandler().sendMessage(msg);
+        } finally {
+            Binder.restoreCallingIdentity(oldId);
+        }
+        return 0;
+    }
+
+    // Posted to the handler to tear down a restore session in a cleanly synchronized way
+    public class EndRestoreRunnable implements Runnable {
+
+        RefactoredBackupManagerService mBackupManager;
+        ActiveRestoreSession mSession;
+
+        public EndRestoreRunnable(RefactoredBackupManagerService manager,
+                ActiveRestoreSession session) {
+            mBackupManager = manager;
+            mSession = session;
+        }
+
+        public void run() {
+            // clean up the session's bookkeeping
+            synchronized (mSession) {
+                mSession.mRestoreTransport = null;
+                mSession.mEnded = true;
+            }
+
+            // clean up the BackupManagerImpl side of the bookkeeping
+            // and cancel any pending timeout message
+            mBackupManager.clearRestoreSession(mSession);
+        }
+    }
+
+    public synchronized void endRestoreSession() {
+        if (DEBUG) {
+            Slog.d(TAG, "endRestoreSession");
+        }
+
+        if (mTimedOut) {
+            Slog.i(TAG, "Session already timed out");
+            return;
+        }
+
+        if (mEnded) {
+            throw new IllegalStateException("Restore session already ended");
+        }
+
+        backupManagerService.getBackupHandler().post(
+                new EndRestoreRunnable(backupManagerService, this));
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java b/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
new file mode 100644
index 0000000..6353d1f
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.restore;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+
+import android.util.Slog;
+
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.RefactoredBackupManagerService;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Used for synchronizing doRestoreFinished during adb restore.
+ */
+public class AdbRestoreFinishedLatch implements BackupRestoreTask {
+
+    private static final String TAG = "AdbRestoreFinishedLatch";
+    private RefactoredBackupManagerService backupManagerService;
+    final CountDownLatch mLatch;
+    private final int mCurrentOpToken;
+
+    public AdbRestoreFinishedLatch(RefactoredBackupManagerService backupManagerService,
+            int currentOpToken) {
+        this.backupManagerService = backupManagerService;
+        mLatch = new CountDownLatch(1);
+        mCurrentOpToken = currentOpToken;
+    }
+
+    void await() {
+        boolean latched = false;
+        try {
+            latched = mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            Slog.w(TAG, "Interrupted!");
+        }
+    }
+
+    @Override
+    public void execute() {
+        // Unused
+    }
+
+    @Override
+    public void operationComplete(long result) {
+        if (MORE_DEBUG) {
+            Slog.w(TAG, "adb onRestoreFinished() complete");
+        }
+        mLatch.countDown();
+        backupManagerService.removeOperation(mCurrentOpToken);
+    }
+
+    @Override
+    public void handleCancel(boolean cancelAll) {
+        if (DEBUG) {
+            Slog.w(TAG, "adb onRestoreFinished() timed out");
+        }
+        mLatch.countDown();
+        backupManagerService.removeOperation(mCurrentOpToken);
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
new file mode 100644
index 0000000..888dcd7e
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -0,0 +1,634 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.restore;
+
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_RESTORE_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL;
+import static com.android.server.backup.RefactoredBackupManagerService
+        .TIMEOUT_SHARED_BACKUP_INTERVAL;
+import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
+
+import android.app.ApplicationThreadConstants;
+import android.app.IBackupAgent;
+import android.app.backup.FullBackup;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IFullBackupRestoreObserver;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.Signature;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.FileMetadata;
+import com.android.server.backup.KeyValueAdbRestoreEngine;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.fullbackup.FullBackupObbConnection;
+import com.android.server.backup.utils.BytesReadListener;
+import com.android.server.backup.utils.FullBackupRestoreObserverUtils;
+import com.android.server.backup.utils.RestoreUtils;
+import com.android.server.backup.utils.TarBackupReader;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.HashSet;
+
+/**
+ * Full restore engine, used by both adb restore and transport-based full restore.
+ */
+public class FullRestoreEngine extends RestoreEngine {
+
+    private final RefactoredBackupManagerService mBackupManagerService;
+    // Task in charge of monitoring timeouts
+    private final BackupRestoreTask mMonitorTask;
+
+    private final RestoreInstallObserver mInstallObserver = new RestoreInstallObserver();
+    private final RestoreDeleteObserver mDeleteObserver = new RestoreDeleteObserver();
+
+    // Dedicated observer, if any
+    private IFullBackupRestoreObserver mObserver;
+
+    final IBackupManagerMonitor mMonitor;
+
+    // Where we're delivering the file data as we go
+    private IBackupAgent mAgent;
+
+    // Are we permitted to only deliver a specific package's metadata?
+    final PackageInfo mOnlyPackage;
+
+    final boolean mAllowApks;
+    private final boolean mAllowObbs;
+
+    // Which package are we currently handling data for?
+    private String mAgentPackage;
+
+    // Info for working with the target app process
+    private ApplicationInfo mTargetApp;
+
+    // Machinery for restoring OBBs
+    private FullBackupObbConnection mObbConnection = null;
+
+    // possible handling states for a given package in the restore dataset
+    private final HashMap<String, RestorePolicy> mPackagePolicies
+            = new HashMap<>();
+
+    // installer package names for each encountered app, derived from the manifests
+    private final HashMap<String, String> mPackageInstallers = new HashMap<>();
+
+    // Signatures for a given package found in its manifest file
+    private final HashMap<String, Signature[]> mManifestSignatures
+            = new HashMap<>();
+
+    // Packages we've already wiped data on when restoring their first file
+    private final HashSet<String> mClearedPackages = new HashSet<>();
+
+    // How much data have we moved?
+    private long mBytes;
+
+    // Working buffer
+    final byte[] mBuffer;
+
+    // Pipes for moving data
+    private ParcelFileDescriptor[] mPipes = null;
+
+    // Widget blob to be restored out-of-band
+    private byte[] mWidgetData = null;
+
+    final int mEphemeralOpToken;
+
+    public FullRestoreEngine(RefactoredBackupManagerService backupManagerService,
+            BackupRestoreTask monitorTask, IFullBackupRestoreObserver observer,
+            IBackupManagerMonitor monitor, PackageInfo onlyPackage, boolean allowApks,
+            boolean allowObbs, int ephemeralOpToken) {
+        mBackupManagerService = backupManagerService;
+        mEphemeralOpToken = ephemeralOpToken;
+        mMonitorTask = monitorTask;
+        mObserver = observer;
+        mMonitor = monitor;
+        mOnlyPackage = onlyPackage;
+        mAllowApks = allowApks;
+        mAllowObbs = allowObbs;
+        mBuffer = new byte[32 * 1024];
+        mBytes = 0;
+    }
+
+    public IBackupAgent getAgent() {
+        return mAgent;
+    }
+
+    public byte[] getWidgetData() {
+        return mWidgetData;
+    }
+
+    public boolean restoreOneFile(InputStream instream, boolean mustKillAgent, byte[] buffer,
+            PackageInfo onlyPackage, boolean allowApks, int token, IBackupManagerMonitor monitor) {
+        if (!isRunning()) {
+            Slog.w(TAG, "Restore engine used after halting");
+            return false;
+        }
+
+        BytesReadListener bytesReadListener = new BytesReadListener() {
+            @Override
+            public void onBytesRead(long bytesRead) {
+                mBytes += bytesRead;
+            }
+        };
+
+        TarBackupReader tarBackupReader = new TarBackupReader(instream,
+                bytesReadListener, monitor);
+
+        FileMetadata info;
+        try {
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "Reading tar header for restoring file");
+            }
+            info = tarBackupReader.readTarHeaders();
+            if (info != null) {
+                if (MORE_DEBUG) {
+                    info.dump();
+                }
+
+                final String pkg = info.packageName;
+                if (!pkg.equals(mAgentPackage)) {
+                    // In the single-package case, it's a semantic error to expect
+                    // one app's data but see a different app's on the wire
+                    if (onlyPackage != null) {
+                        if (!pkg.equals(onlyPackage.packageName)) {
+                            Slog.w(TAG, "Expected data for " + onlyPackage + " but saw " + pkg);
+                            setResult(RestoreEngine.TRANSPORT_FAILURE);
+                            setRunning(false);
+                            return false;
+                        }
+                    }
+
+                    // okay, change in package; set up our various
+                    // bookkeeping if we haven't seen it yet
+                    if (!mPackagePolicies.containsKey(pkg)) {
+                        mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                    }
+
+                    // Clean up the previous agent relationship if necessary,
+                    // and let the observer know we're considering a new app.
+                    if (mAgent != null) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Saw new package; finalizing old one");
+                        }
+                        // Now we're really done
+                        tearDownPipes();
+                        tearDownAgent(mTargetApp);
+                        mTargetApp = null;
+                        mAgentPackage = null;
+                    }
+                }
+
+                if (info.path.equals(BACKUP_MANIFEST_FILENAME)) {
+                    Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(
+                            info);
+                    RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
+                            mBackupManagerService.getPackageManager(), allowApks, info, signatures);
+                    mManifestSignatures.put(info.packageName, signatures);
+                    mPackagePolicies.put(pkg, restorePolicy);
+                    mPackageInstallers.put(pkg, info.installerPackageName);
+                    // We've read only the manifest content itself at this point,
+                    // so consume the footer before looping around to the next
+                    // input file
+                    tarBackupReader.skipTarPadding(info.size);
+                    mObserver = FullBackupRestoreObserverUtils.sendOnRestorePackage(mObserver, pkg);
+                } else if (info.path.equals(BACKUP_METADATA_FILENAME)) {
+                    // Metadata blobs!
+                    tarBackupReader.readMetadata(info);
+
+                    // The following only exist because we want to keep refactoring as safe as
+                    // possible, without changing too much.
+                    // TODO: Refactor, so that there are no funny things like this.
+                    // This is read during TarBackupReader.readMetadata().
+                    mWidgetData = tarBackupReader.getWidgetData();
+                    // This can be nulled during TarBackupReader.readMetadata().
+                    monitor = tarBackupReader.getMonitor();
+
+                    tarBackupReader.skipTarPadding(info.size);
+                } else {
+                    // Non-manifest, so it's actual file data.  Is this a package
+                    // we're ignoring?
+                    boolean okay = true;
+                    RestorePolicy policy = mPackagePolicies.get(pkg);
+                    switch (policy) {
+                        case IGNORE:
+                            okay = false;
+                            break;
+
+                        case ACCEPT_IF_APK:
+                            // If we're in accept-if-apk state, then the first file we
+                            // see MUST be the apk.
+                            if (info.domain.equals(FullBackup.APK_TREE_TOKEN)) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "APK file; installing");
+                                }
+                                // Try to install the app.
+                                String installerName = mPackageInstallers.get(pkg);
+                                boolean isSuccessfullyInstalled = RestoreUtils.installApk(
+                                        instream, mBackupManagerService.getPackageManager(),
+                                        mInstallObserver, mDeleteObserver, mManifestSignatures,
+                                        mPackagePolicies, info, installerName,
+                                        bytesReadListener, mBackupManagerService.getDataDir()
+                                                                                         );
+                                // good to go; promote to ACCEPT
+                                mPackagePolicies.put(pkg, isSuccessfullyInstalled
+                                        ? RestorePolicy.ACCEPT
+                                        : RestorePolicy.IGNORE);
+                                // At this point we've consumed this file entry
+                                // ourselves, so just strip the tar footer and
+                                // go on to the next file in the input stream
+                                tarBackupReader.skipTarPadding(info.size);
+                                return true;
+                            } else {
+                                // File data before (or without) the apk.  We can't
+                                // handle it coherently in this case so ignore it.
+                                mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                                okay = false;
+                            }
+                            break;
+
+                        case ACCEPT:
+                            if (info.domain.equals(FullBackup.APK_TREE_TOKEN)) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "apk present but ACCEPT");
+                                }
+                                // we can take the data without the apk, so we
+                                // *want* to do so.  skip the apk by declaring this
+                                // one file not-okay without changing the restore
+                                // policy for the package.
+                                okay = false;
+                            }
+                            break;
+
+                        default:
+                            // Something has gone dreadfully wrong when determining
+                            // the restore policy from the manifest.  Ignore the
+                            // rest of this package's data.
+                            Slog.e(TAG, "Invalid policy from manifest");
+                            okay = false;
+                            mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                            break;
+                    }
+
+                    // Is it a *file* we need to drop or is it not a canonical path?
+                    if (!isRestorableFile(info) || !isCanonicalFilePath(info.path)) {
+                        okay = false;
+                    }
+
+                    // If the policy is satisfied, go ahead and set up to pipe the
+                    // data to the agent.
+                    if (MORE_DEBUG && okay && mAgent != null) {
+                        Slog.i(TAG, "Reusing existing agent instance");
+                    }
+                    if (okay && mAgent == null) {
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "Need to launch agent for " + pkg);
+                        }
+
+                        try {
+                            mTargetApp =
+                                    mBackupManagerService.getPackageManager().getApplicationInfo(
+                                            pkg, 0);
+
+                            // If we haven't sent any data to this app yet, we probably
+                            // need to clear it first.  Check that.
+                            if (!mClearedPackages.contains(pkg)) {
+                                // apps with their own backup agents are
+                                // responsible for coherently managing a full
+                                // restore.
+                                if (mTargetApp.backupAgentName == null) {
+                                    if (DEBUG) {
+                                        Slog.d(TAG,
+                                                "Clearing app data preparatory to full restore");
+                                    }
+                                    mBackupManagerService.clearApplicationDataSynchronous(pkg);
+                                } else {
+                                    if (MORE_DEBUG) {
+                                        Slog.d(TAG, "backup agent ("
+                                                + mTargetApp.backupAgentName + ") => no clear");
+                                    }
+                                }
+                                mClearedPackages.add(pkg);
+                            } else {
+                                if (MORE_DEBUG) {
+                                    Slog.d(TAG, "We've initialized this app already; no clear "
+                                            + "required");
+                                }
+                            }
+
+                            // All set; now set up the IPC and launch the agent
+                            setUpPipes();
+                            mAgent = mBackupManagerService.bindToAgentSynchronous(mTargetApp,
+                                    ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL);
+                            mAgentPackage = pkg;
+                        } catch (IOException e) {
+                            // fall through to error handling
+                        } catch (NameNotFoundException e) {
+                            // fall through to error handling
+                        }
+
+                        if (mAgent == null) {
+                            Slog.e(TAG, "Unable to create agent for " + pkg);
+                            okay = false;
+                            tearDownPipes();
+                            mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                        }
+                    }
+
+                    // Sanity check: make sure we never give data to the wrong app.  This
+                    // should never happen but a little paranoia here won't go amiss.
+                    if (okay && !pkg.equals(mAgentPackage)) {
+                        Slog.e(TAG, "Restoring data for " + pkg
+                                + " but agent is for " + mAgentPackage);
+                        okay = false;
+                    }
+
+                    // At this point we have an agent ready to handle the full
+                    // restore data as well as a pipe for sending data to
+                    // that agent.  Tell the agent to start reading from the
+                    // pipe.
+                    if (okay) {
+                        boolean agentSuccess = true;
+                        long toCopy = info.size;
+                        final boolean isSharedStorage = pkg.equals(SHARED_BACKUP_AGENT_PACKAGE);
+                        final long timeout = isSharedStorage ?
+                                TIMEOUT_SHARED_BACKUP_INTERVAL :
+                                TIMEOUT_RESTORE_INTERVAL;
+                        try {
+                            mBackupManagerService.prepareOperationTimeout(token,
+                                    timeout,
+                                    mMonitorTask,
+                                    OP_TYPE_RESTORE_WAIT);
+
+                            if (FullBackup.OBB_TREE_TOKEN.equals(info.domain)) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Restoring OBB file for " + pkg
+                                            + " : " + info.path);
+                                }
+                                mObbConnection.restoreObbFile(pkg, mPipes[0],
+                                        info.size, info.type, info.path, info.mode,
+                                        info.mtime, token,
+                                        mBackupManagerService.getBackupManagerBinder());
+                            } else if (FullBackup.KEY_VALUE_DATA_TOKEN.equals(info.domain)) {
+                                // This is only possible during adb restore.
+                                // TODO: Refactor to clearly separate the flows.
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Restoring key-value file for " + pkg
+                                            + " : " + info.path);
+                                }
+                                KeyValueAdbRestoreEngine restoreEngine =
+                                        new KeyValueAdbRestoreEngine(
+                                                mBackupManagerService,
+                                                mBackupManagerService.getDataDir(), info, mPipes[0],
+                                                mAgent, token);
+                                new Thread(restoreEngine, "restore-key-value-runner").start();
+                            } else {
+                                if (MORE_DEBUG) {
+                                    Slog.d(TAG, "Invoking agent to restore file " + info.path);
+                                }
+                                // fire up the app's agent listening on the socket.  If
+                                // the agent is running in the system process we can't
+                                // just invoke it asynchronously, so we provide a thread
+                                // for it here.
+                                if (mTargetApp.processName.equals("system")) {
+                                    Slog.d(TAG, "system process agent - spinning a thread");
+                                    RestoreFileRunnable runner = new RestoreFileRunnable(
+                                            mBackupManagerService, mAgent, info, mPipes[0], token);
+                                    new Thread(runner, "restore-sys-runner").start();
+                                } else {
+                                    mAgent.doRestoreFile(mPipes[0], info.size, info.type,
+                                            info.domain, info.path, info.mode, info.mtime,
+                                            token, mBackupManagerService.getBackupManagerBinder());
+                                }
+                            }
+                        } catch (IOException e) {
+                            // couldn't dup the socket for a process-local restore
+                            Slog.d(TAG, "Couldn't establish restore");
+                            agentSuccess = false;
+                            okay = false;
+                        } catch (RemoteException e) {
+                            // whoops, remote entity went away.  We'll eat the content
+                            // ourselves, then, and not copy it over.
+                            Slog.e(TAG, "Agent crashed during full restore");
+                            agentSuccess = false;
+                            okay = false;
+                        }
+
+                        // Copy over the data if the agent is still good
+                        if (okay) {
+                            if (MORE_DEBUG) {
+                                Slog.v(TAG, "  copying to restore agent: " + toCopy + " bytes");
+                            }
+                            boolean pipeOkay = true;
+                            FileOutputStream pipe = new FileOutputStream(
+                                    mPipes[1].getFileDescriptor());
+                            while (toCopy > 0) {
+                                int toRead = (toCopy > buffer.length)
+                                        ? buffer.length : (int) toCopy;
+                                int nRead = instream.read(buffer, 0, toRead);
+                                if (nRead >= 0) {
+                                    mBytes += nRead;
+                                }
+                                if (nRead <= 0) {
+                                    break;
+                                }
+                                toCopy -= nRead;
+
+                                // send it to the output pipe as long as things
+                                // are still good
+                                if (pipeOkay) {
+                                    try {
+                                        pipe.write(buffer, 0, nRead);
+                                    } catch (IOException e) {
+                                        Slog.e(TAG, "Failed to write to restore pipe: "
+                                                + e.getMessage());
+                                        pipeOkay = false;
+                                    }
+                                }
+                            }
+
+                            // done sending that file!  Now we just need to consume
+                            // the delta from info.size to the end of block.
+                            tarBackupReader.skipTarPadding(info.size);
+
+                            // and now that we've sent it all, wait for the remote
+                            // side to acknowledge receipt
+                            agentSuccess = mBackupManagerService.waitUntilOperationComplete(token);
+                        }
+
+                        // okay, if the remote end failed at any point, deal with
+                        // it by ignoring the rest of the restore on it
+                        if (!agentSuccess) {
+                            Slog.w(TAG, "Agent failure restoring " + pkg + "; ending restore");
+                            mBackupManagerService.getBackupHandler().removeMessages(
+                                    MSG_RESTORE_OPERATION_TIMEOUT);
+                            tearDownPipes();
+                            tearDownAgent(mTargetApp);
+                            mAgent = null;
+                            mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+
+                            // If this was a single-package restore, we halt immediately
+                            // with an agent error under these circumstances
+                            if (onlyPackage != null) {
+                                setResult(RestoreEngine.TARGET_FAILURE);
+                                setRunning(false);
+                                return false;
+                            }
+                        }
+                    }
+
+                    // Problems setting up the agent communication, an explicitly
+                    // dropped file, or an already-ignored package: skip to the
+                    // next stream entry by reading and discarding this file.
+                    if (!okay) {
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "[discarding file content]");
+                        }
+                        long bytesToConsume = (info.size + 511) & ~511;
+                        while (bytesToConsume > 0) {
+                            int toRead = (bytesToConsume > buffer.length)
+                                    ? buffer.length : (int) bytesToConsume;
+                            long nRead = instream.read(buffer, 0, toRead);
+                            if (nRead >= 0) {
+                                mBytes += nRead;
+                            }
+                            if (nRead <= 0) {
+                                break;
+                            }
+                            bytesToConsume -= nRead;
+                        }
+                    }
+                }
+            }
+        } catch (IOException e) {
+            if (DEBUG) {
+                Slog.w(TAG, "io exception on restore socket read: " + e.getMessage());
+            }
+            setResult(RestoreEngine.TRANSPORT_FAILURE);
+            info = null;
+        }
+
+        // If we got here we're either running smoothly or we've finished
+        if (info == null) {
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "No [more] data for this package; tearing down");
+            }
+            tearDownPipes();
+            setRunning(false);
+            if (mustKillAgent) {
+                tearDownAgent(mTargetApp);
+            }
+        }
+        return (info != null);
+    }
+
+    private void setUpPipes() throws IOException {
+        mPipes = ParcelFileDescriptor.createPipe();
+    }
+
+    private void tearDownPipes() {
+        // Teardown might arise from the inline restore processing or from the asynchronous
+        // timeout mechanism, and these might race.  Make sure we don't try to close and
+        // null out the pipes twice.
+        synchronized (this) {
+            if (mPipes != null) {
+                try {
+                    mPipes[0].close();
+                    mPipes[0] = null;
+                    mPipes[1].close();
+                    mPipes[1] = null;
+                } catch (IOException e) {
+                    Slog.w(TAG, "Couldn't close agent pipes", e);
+                }
+                mPipes = null;
+            }
+        }
+    }
+
+    private void tearDownAgent(ApplicationInfo app) {
+        if (mAgent != null) {
+            mBackupManagerService.tearDownAgentAndKill(app);
+            mAgent = null;
+        }
+    }
+
+    void handleTimeout() {
+        tearDownPipes();
+        setResult(RestoreEngine.TARGET_FAILURE);
+        setRunning(false);
+    }
+
+    private static boolean isRestorableFile(FileMetadata info) {
+        if (FullBackup.CACHE_TREE_TOKEN.equals(info.domain)) {
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Dropping cache file path " + info.path);
+            }
+            return false;
+        }
+
+        if (FullBackup.ROOT_TREE_TOKEN.equals(info.domain)) {
+            // It's possible this is "no-backup" dir contents in an archive stream
+            // produced on a device running a version of the OS that predates that
+            // API.  Respect the no-backup intention and don't let the data get to
+            // the app.
+            if (info.path.startsWith("no_backup/")) {
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "Dropping no_backup file path " + info.path);
+                }
+                return false;
+            }
+        }
+
+        // Otherwise we think this file is good to go
+        return true;
+    }
+
+    private static boolean isCanonicalFilePath(String path) {
+        if (path.contains("..") || path.contains("//")) {
+            if (MORE_DEBUG) {
+                Slog.w(TAG, "Dropping invalid path " + path);
+            }
+            return false;
+        }
+
+        return true;
+    }
+
+    void sendOnRestorePackage(String name) {
+        if (mObserver != null) {
+            try {
+                // TODO: use a more user-friendly name string
+                mObserver.onRestorePackage(name);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "full restore observer went away: restorePackage");
+                mObserver = null;
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
new file mode 100644
index 0000000..d5c62af
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
@@ -0,0 +1,848 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.restore;
+
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_FILE_HEADER_MAGIC;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_FILE_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_RESTORE_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.PBKDF_CURRENT;
+import static com.android.server.backup.RefactoredBackupManagerService.PBKDF_FALLBACK;
+import static com.android.server.backup.RefactoredBackupManagerService.SETTINGS_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL;
+import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
+
+import android.app.ApplicationThreadConstants;
+import android.app.IBackupAgent;
+import android.app.backup.FullBackup;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IFullBackupRestoreObserver;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.Signature;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.backup.FileMetadata;
+import com.android.server.backup.KeyValueAdbRestoreEngine;
+import com.android.server.backup.PackageManagerBackupAgent;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.fullbackup.FullBackupObbConnection;
+import com.android.server.backup.utils.BytesReadListener;
+import com.android.server.backup.utils.FullBackupRestoreObserverUtils;
+import com.android.server.backup.utils.PasswordUtils;
+import com.android.server.backup.utils.RestoreUtils;
+import com.android.server.backup.utils.TarBackupReader;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.zip.InflaterInputStream;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+public class PerformAdbRestoreTask implements Runnable {
+
+    private final RefactoredBackupManagerService mBackupManagerService;
+    private final ParcelFileDescriptor mInputFile;
+    private final String mCurrentPassword;
+    private final String mDecryptPassword;
+    private final AtomicBoolean mLatchObject;
+    private final PackageManagerBackupAgent mPackageManagerBackupAgent;
+    private final RestoreInstallObserver mInstallObserver = new RestoreInstallObserver();
+    private final RestoreDeleteObserver mDeleteObserver = new RestoreDeleteObserver();
+
+    private IFullBackupRestoreObserver mObserver;
+    private IBackupAgent mAgent;
+    private String mAgentPackage;
+    private ApplicationInfo mTargetApp;
+    private FullBackupObbConnection mObbConnection = null;
+    private ParcelFileDescriptor[] mPipes = null;
+    private byte[] mWidgetData = null;
+
+    private long mBytes;
+
+    // Runner that can be placed on a separate thread to do in-process invocation
+    // of the "restore finished" API asynchronously.  Used by adb restore.
+    private static class RestoreFinishedRunnable implements Runnable {
+
+        private final IBackupAgent mAgent;
+        private final int mToken;
+        private final RefactoredBackupManagerService mBackupManagerService;
+
+        RestoreFinishedRunnable(IBackupAgent agent, int token,
+                RefactoredBackupManagerService backupManagerService) {
+            mAgent = agent;
+            mToken = token;
+            mBackupManagerService = backupManagerService;
+        }
+
+        @Override
+        public void run() {
+            try {
+                mAgent.doRestoreFinished(mToken, mBackupManagerService.getBackupManagerBinder());
+            } catch (RemoteException e) {
+                // never happens; this is used only for local binder calls
+            }
+        }
+    }
+
+    // possible handling states for a given package in the restore dataset
+    private final HashMap<String, RestorePolicy> mPackagePolicies
+            = new HashMap<>();
+
+    // installer package names for each encountered app, derived from the manifests
+    private final HashMap<String, String> mPackageInstallers = new HashMap<>();
+
+    // Signatures for a given package found in its manifest file
+    private final HashMap<String, Signature[]> mManifestSignatures
+            = new HashMap<>();
+
+    // Packages we've already wiped data on when restoring their first file
+    private final HashSet<String> mClearedPackages = new HashSet<>();
+
+    public PerformAdbRestoreTask(RefactoredBackupManagerService backupManagerService,
+            ParcelFileDescriptor fd, String curPassword, String decryptPassword,
+            IFullBackupRestoreObserver observer, AtomicBoolean latch) {
+        this.mBackupManagerService = backupManagerService;
+        mInputFile = fd;
+        mCurrentPassword = curPassword;
+        mDecryptPassword = decryptPassword;
+        mObserver = observer;
+        mLatchObject = latch;
+        mAgent = null;
+        mPackageManagerBackupAgent = new PackageManagerBackupAgent(
+                backupManagerService.getPackageManager());
+        mAgentPackage = null;
+        mTargetApp = null;
+        mObbConnection = new FullBackupObbConnection(backupManagerService);
+
+        // Which packages we've already wiped data on.  We prepopulate this
+        // with a whitelist of packages known to be unclearable.
+        mClearedPackages.add("android");
+        mClearedPackages.add(SETTINGS_PACKAGE);
+    }
+
+    @Override
+    public void run() {
+        Slog.i(TAG, "--- Performing full-dataset restore ---");
+        mObbConnection.establish();
+        mObserver = FullBackupRestoreObserverUtils.sendStartRestore(mObserver);
+
+        // Are we able to restore shared-storage data?
+        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+            mPackagePolicies.put(SHARED_BACKUP_AGENT_PACKAGE, RestorePolicy.ACCEPT);
+        }
+
+        FileInputStream rawInStream = null;
+        try {
+            if (!mBackupManagerService.backupPasswordMatches(mCurrentPassword)) {
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup password mismatch; aborting");
+                }
+                return;
+            }
+
+            mBytes = 0;
+
+            rawInStream = new FileInputStream(mInputFile.getFileDescriptor());
+
+            InputStream tarInputStream = parseBackupFileHeaderAndReturnTarStream(rawInStream,
+                    mDecryptPassword);
+            if (tarInputStream == null) {
+                // There was an error reading the backup file, which is already handled and logged.
+                // Just abort.
+                return;
+            }
+
+            byte[] buffer = new byte[32 * 1024];
+            boolean didRestore;
+            do {
+                didRestore = restoreOneFile(tarInputStream, false /* mustKillAgent */, buffer,
+                        null /* onlyPackage */, true /* allowApks */,
+                        mBackupManagerService.generateRandomIntegerToken(), null /* monitor */);
+            } while (didRestore);
+
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "Done consuming input tarfile, total bytes=" + mBytes);
+            }
+        } catch (IOException e) {
+            Slog.e(TAG, "Unable to read restore input");
+        } finally {
+            tearDownPipes();
+            tearDownAgent(mTargetApp, true);
+
+            try {
+                if (rawInStream != null) {
+                    rawInStream.close();
+                }
+                mInputFile.close();
+            } catch (IOException e) {
+                Slog.w(TAG, "Close of restore data pipe threw", e);
+                /* nothing we can do about this */
+            }
+            synchronized (mLatchObject) {
+                mLatchObject.set(true);
+                mLatchObject.notifyAll();
+            }
+            mObbConnection.tearDown();
+            mObserver = FullBackupRestoreObserverUtils.sendEndRestore(mObserver);
+            Slog.d(TAG, "Full restore pass complete.");
+            mBackupManagerService.getWakelock().release();
+        }
+    }
+
+    private static void readFullyOrThrow(InputStream in, byte[] buffer) throws IOException {
+        int offset = 0;
+        while (offset < buffer.length) {
+            int bytesRead = in.read(buffer, offset, buffer.length - offset);
+            if (bytesRead <= 0) {
+                throw new IOException("Couldn't fully read data");
+            }
+            offset += bytesRead;
+        }
+    }
+
+    @VisibleForTesting
+    public static InputStream parseBackupFileHeaderAndReturnTarStream(
+            InputStream rawInputStream,
+            String decryptPassword)
+            throws IOException {
+        // First, parse out the unencrypted/uncompressed header
+        boolean compressed = false;
+        InputStream preCompressStream = rawInputStream;
+
+        boolean okay = false;
+        final int headerLen = BACKUP_FILE_HEADER_MAGIC.length();
+        byte[] streamHeader = new byte[headerLen];
+        readFullyOrThrow(rawInputStream, streamHeader);
+        byte[] magicBytes = BACKUP_FILE_HEADER_MAGIC.getBytes(
+                "UTF-8");
+        if (Arrays.equals(magicBytes, streamHeader)) {
+            // okay, header looks good.  now parse out the rest of the fields.
+            String s = readHeaderLine(rawInputStream);
+            final int archiveVersion = Integer.parseInt(s);
+            if (archiveVersion <= BACKUP_FILE_VERSION) {
+                // okay, it's a version we recognize.  if it's version 1, we may need
+                // to try two different PBKDF2 regimes to compare checksums.
+                final boolean pbkdf2Fallback = (archiveVersion == 1);
+
+                s = readHeaderLine(rawInputStream);
+                compressed = (Integer.parseInt(s) != 0);
+                s = readHeaderLine(rawInputStream);
+                if (s.equals("none")) {
+                    // no more header to parse; we're good to go
+                    okay = true;
+                } else if (decryptPassword != null && decryptPassword.length() > 0) {
+                    preCompressStream = decodeAesHeaderAndInitialize(
+                            decryptPassword, s, pbkdf2Fallback,
+                            rawInputStream);
+                    if (preCompressStream != null) {
+                        okay = true;
+                    }
+                } else {
+                    Slog.w(TAG, "Archive is encrypted but no password given");
+                }
+            } else {
+                Slog.w(TAG, "Wrong header version: " + s);
+            }
+        } else {
+            Slog.w(TAG, "Didn't read the right header magic");
+        }
+
+        if (!okay) {
+            Slog.w(TAG, "Invalid restore data; aborting.");
+            return null;
+        }
+
+        // okay, use the right stream layer based on compression
+        return compressed ? new InflaterInputStream(preCompressStream) : preCompressStream;
+    }
+
+    private static String readHeaderLine(InputStream in) throws IOException {
+        int c;
+        StringBuilder buffer = new StringBuilder(80);
+        while ((c = in.read()) >= 0) {
+            if (c == '\n') {
+                break;   // consume and discard the newlines
+            }
+            buffer.append((char) c);
+        }
+        return buffer.toString();
+    }
+
+    private static InputStream attemptMasterKeyDecryption(String decryptPassword, String algorithm,
+            byte[] userSalt, byte[] ckSalt,
+            int rounds, String userIvHex, String masterKeyBlobHex, InputStream rawInStream,
+            boolean doLog) {
+        InputStream result = null;
+
+        try {
+            Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
+            SecretKey userKey = PasswordUtils
+                    .buildPasswordKey(algorithm, decryptPassword, userSalt,
+                            rounds);
+            byte[] IV = PasswordUtils.hexToByteArray(userIvHex);
+            IvParameterSpec ivSpec = new IvParameterSpec(IV);
+            c.init(Cipher.DECRYPT_MODE,
+                    new SecretKeySpec(userKey.getEncoded(), "AES"),
+                    ivSpec);
+            byte[] mkCipher = PasswordUtils.hexToByteArray(masterKeyBlobHex);
+            byte[] mkBlob = c.doFinal(mkCipher);
+
+            // first, the master key IV
+            int offset = 0;
+            int len = mkBlob[offset++];
+            IV = Arrays.copyOfRange(mkBlob, offset, offset + len);
+            offset += len;
+            // then the master key itself
+            len = mkBlob[offset++];
+            byte[] mk = Arrays.copyOfRange(mkBlob,
+                    offset, offset + len);
+            offset += len;
+            // and finally the master key checksum hash
+            len = mkBlob[offset++];
+            byte[] mkChecksum = Arrays.copyOfRange(mkBlob,
+                    offset, offset + len);
+
+            // now validate the decrypted master key against the checksum
+            byte[] calculatedCk = PasswordUtils.makeKeyChecksum(algorithm, mk, ckSalt,
+                    rounds);
+            if (Arrays.equals(calculatedCk, mkChecksum)) {
+                ivSpec = new IvParameterSpec(IV);
+                c.init(Cipher.DECRYPT_MODE,
+                        new SecretKeySpec(mk, "AES"),
+                        ivSpec);
+                // Only if all of the above worked properly will 'result' be assigned
+                result = new CipherInputStream(rawInStream, c);
+            } else if (doLog) {
+                Slog.w(TAG, "Incorrect password");
+            }
+        } catch (InvalidAlgorithmParameterException e) {
+            if (doLog) {
+                Slog.e(TAG, "Needed parameter spec unavailable!", e);
+            }
+        } catch (BadPaddingException e) {
+            // This case frequently occurs when the wrong password is used to decrypt
+            // the master key.  Use the identical "incorrect password" log text as is
+            // used in the checksum failure log in order to avoid providing additional
+            // information to an attacker.
+            if (doLog) {
+                Slog.w(TAG, "Incorrect password");
+            }
+        } catch (IllegalBlockSizeException e) {
+            if (doLog) {
+                Slog.w(TAG, "Invalid block size in master key");
+            }
+        } catch (NoSuchAlgorithmException e) {
+            if (doLog) {
+                Slog.e(TAG, "Needed decryption algorithm unavailable!");
+            }
+        } catch (NoSuchPaddingException e) {
+            if (doLog) {
+                Slog.e(TAG, "Needed padding mechanism unavailable!");
+            }
+        } catch (InvalidKeyException e) {
+            if (doLog) {
+                Slog.w(TAG, "Illegal password; aborting");
+            }
+        }
+
+        return result;
+    }
+
+    private static InputStream decodeAesHeaderAndInitialize(String decryptPassword,
+            String encryptionName,
+            boolean pbkdf2Fallback,
+            InputStream rawInStream) {
+        InputStream result = null;
+        try {
+            if (encryptionName.equals(PasswordUtils.ENCRYPTION_ALGORITHM_NAME)) {
+
+                String userSaltHex = readHeaderLine(rawInStream); // 5
+                byte[] userSalt = PasswordUtils.hexToByteArray(userSaltHex);
+
+                String ckSaltHex = readHeaderLine(rawInStream); // 6
+                byte[] ckSalt = PasswordUtils.hexToByteArray(ckSaltHex);
+
+                int rounds = Integer.parseInt(readHeaderLine(rawInStream)); // 7
+                String userIvHex = readHeaderLine(rawInStream); // 8
+
+                String masterKeyBlobHex = readHeaderLine(rawInStream); // 9
+
+                // decrypt the master key blob
+                result = attemptMasterKeyDecryption(decryptPassword, PBKDF_CURRENT,
+                        userSalt, ckSalt, rounds, userIvHex, masterKeyBlobHex, rawInStream, false);
+                if (result == null && pbkdf2Fallback) {
+                    result = attemptMasterKeyDecryption(
+                            decryptPassword, PBKDF_FALLBACK, userSalt, ckSalt,
+                            rounds, userIvHex, masterKeyBlobHex, rawInStream, true);
+                }
+            } else {
+                Slog.w(TAG, "Unsupported encryption method: " + encryptionName);
+            }
+        } catch (NumberFormatException e) {
+            Slog.w(TAG, "Can't parse restore data header");
+        } catch (IOException e) {
+            Slog.w(TAG, "Can't read input header");
+        }
+
+        return result;
+    }
+
+    boolean restoreOneFile(InputStream instream, boolean mustKillAgent, byte[] buffer,
+            PackageInfo onlyPackage, boolean allowApks, int token, IBackupManagerMonitor monitor) {
+        BytesReadListener bytesReadListener = new BytesReadListener() {
+            @Override
+            public void onBytesRead(long bytesRead) {
+                mBytes += bytesRead;
+            }
+        };
+        TarBackupReader tarBackupReader = new TarBackupReader(instream,
+                bytesReadListener, monitor);
+        FileMetadata info;
+        try {
+            info = tarBackupReader.readTarHeaders();
+            if (info != null) {
+                if (MORE_DEBUG) {
+                    info.dump();
+                }
+
+                final String pkg = info.packageName;
+                if (!pkg.equals(mAgentPackage)) {
+                    // okay, change in package; set up our various
+                    // bookkeeping if we haven't seen it yet
+                    if (!mPackagePolicies.containsKey(pkg)) {
+                        mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                    }
+
+                    // Clean up the previous agent relationship if necessary,
+                    // and let the observer know we're considering a new app.
+                    if (mAgent != null) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Saw new package; finalizing old one");
+                        }
+                        // Now we're really done
+                        tearDownPipes();
+                        tearDownAgent(mTargetApp, true);
+                        mTargetApp = null;
+                        mAgentPackage = null;
+                    }
+                }
+
+                if (info.path.equals(BACKUP_MANIFEST_FILENAME)) {
+                    Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(
+                            info);
+                    RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
+                            mBackupManagerService.getPackageManager(), allowApks,
+                            info, signatures);
+                    mManifestSignatures.put(info.packageName, signatures);
+                    mPackagePolicies.put(pkg, restorePolicy);
+                    mPackageInstallers.put(pkg, info.installerPackageName);
+                    // We've read only the manifest content itself at this point,
+                    // so consume the footer before looping around to the next
+                    // input file
+                    tarBackupReader.skipTarPadding(info.size);
+                    mObserver = FullBackupRestoreObserverUtils.sendOnRestorePackage(mObserver, pkg);
+                } else if (info.path.equals(BACKUP_METADATA_FILENAME)) {
+                    // Metadata blobs!
+                    tarBackupReader.readMetadata(info);
+
+                    // The following only exist because we want to keep refactoring as safe as
+                    // possible, without changing too much.
+                    // TODO: Refactor, so that there are no funny things like this.
+                    // This is read during TarBackupReader.readMetadata().
+                    mWidgetData = tarBackupReader.getWidgetData();
+                    // This can be nulled during TarBackupReader.readMetadata().
+                    monitor = tarBackupReader.getMonitor();
+
+                    tarBackupReader.skipTarPadding(info.size);
+                } else {
+                    // Non-manifest, so it's actual file data.  Is this a package
+                    // we're ignoring?
+                    boolean okay = true;
+                    RestorePolicy policy = mPackagePolicies.get(pkg);
+                    switch (policy) {
+                        case IGNORE:
+                            okay = false;
+                            break;
+
+                        case ACCEPT_IF_APK:
+                            // If we're in accept-if-apk state, then the first file we
+                            // see MUST be the apk.
+                            if (info.domain.equals(FullBackup.APK_TREE_TOKEN)) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "APK file; installing");
+                                }
+                                // Try to install the app.
+                                String installerName = mPackageInstallers.get(pkg);
+                                boolean isSuccessfullyInstalled = RestoreUtils.installApk(
+                                        instream, mBackupManagerService.getPackageManager(),
+                                        mInstallObserver, mDeleteObserver, mManifestSignatures,
+                                        mPackagePolicies, info, installerName,
+                                        bytesReadListener, mBackupManagerService.getDataDir()
+                                                                                         );
+                                // good to go; promote to ACCEPT
+                                mPackagePolicies.put(pkg, isSuccessfullyInstalled
+                                        ? RestorePolicy.ACCEPT
+                                        : RestorePolicy.IGNORE);
+                                // At this point we've consumed this file entry
+                                // ourselves, so just strip the tar footer and
+                                // go on to the next file in the input stream
+                                tarBackupReader.skipTarPadding(info.size);
+                                return true;
+                            } else {
+                                // File data before (or without) the apk.  We can't
+                                // handle it coherently in this case so ignore it.
+                                mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                                okay = false;
+                            }
+                            break;
+
+                        case ACCEPT:
+                            if (info.domain.equals(FullBackup.APK_TREE_TOKEN)) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "apk present but ACCEPT");
+                                }
+                                // we can take the data without the apk, so we
+                                // *want* to do so.  skip the apk by declaring this
+                                // one file not-okay without changing the restore
+                                // policy for the package.
+                                okay = false;
+                            }
+                            break;
+
+                        default:
+                            // Something has gone dreadfully wrong when determining
+                            // the restore policy from the manifest.  Ignore the
+                            // rest of this package's data.
+                            Slog.e(TAG, "Invalid policy from manifest");
+                            okay = false;
+                            mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                            break;
+                    }
+
+                    // The path needs to be canonical
+                    if (!isCanonicalFilePath(info.path)) {
+                        okay = false;
+                    }
+
+                    // If the policy is satisfied, go ahead and set up to pipe the
+                    // data to the agent.
+                    if (DEBUG && okay && mAgent != null) {
+                        Slog.i(TAG, "Reusing existing agent instance");
+                    }
+                    if (okay && mAgent == null) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Need to launch agent for " + pkg);
+                        }
+
+                        try {
+                            mTargetApp =
+                                    mBackupManagerService.getPackageManager().getApplicationInfo(
+                                            pkg, 0);
+
+                            // If we haven't sent any data to this app yet, we probably
+                            // need to clear it first.  Check that.
+                            if (!mClearedPackages.contains(pkg)) {
+                                // apps with their own backup agents are
+                                // responsible for coherently managing a full
+                                // restore.
+                                if (mTargetApp.backupAgentName == null) {
+                                    if (DEBUG) {
+                                        Slog.d(TAG,
+                                                "Clearing app data preparatory to full restore");
+                                    }
+                                    mBackupManagerService.clearApplicationDataSynchronous(pkg);
+                                } else {
+                                    if (DEBUG) {
+                                        Slog.d(TAG, "backup agent ("
+                                                + mTargetApp.backupAgentName + ") => no clear");
+                                    }
+                                }
+                                mClearedPackages.add(pkg);
+                            } else {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "We've initialized this app already; no clear "
+                                            + "required");
+                                }
+                            }
+
+                            // All set; now set up the IPC and launch the agent
+                            setUpPipes();
+                            mAgent = mBackupManagerService.bindToAgentSynchronous(mTargetApp,
+                                    ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL);
+                            mAgentPackage = pkg;
+                        } catch (IOException e) {
+                            // fall through to error handling
+                        } catch (NameNotFoundException e) {
+                            // fall through to error handling
+                        }
+
+                        if (mAgent == null) {
+                            Slog.e(TAG, "Unable to create agent for " + pkg);
+                            okay = false;
+                            tearDownPipes();
+                            mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                        }
+                    }
+
+                    // Sanity check: make sure we never give data to the wrong app.  This
+                    // should never happen but a little paranoia here won't go amiss.
+                    if (okay && !pkg.equals(mAgentPackage)) {
+                        Slog.e(TAG, "Restoring data for " + pkg
+                                + " but agent is for " + mAgentPackage);
+                        okay = false;
+                    }
+
+                    // At this point we have an agent ready to handle the full
+                    // restore data as well as a pipe for sending data to
+                    // that agent.  Tell the agent to start reading from the
+                    // pipe.
+                    if (okay) {
+                        boolean agentSuccess = true;
+                        long toCopy = info.size;
+                        try {
+                            mBackupManagerService.prepareOperationTimeout(
+                                    token, TIMEOUT_RESTORE_INTERVAL, null, OP_TYPE_RESTORE_WAIT);
+
+                            if (FullBackup.OBB_TREE_TOKEN.equals(info.domain)) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Restoring OBB file for " + pkg
+                                            + " : " + info.path);
+                                }
+                                mObbConnection.restoreObbFile(pkg, mPipes[0],
+                                        info.size, info.type, info.path, info.mode,
+                                        info.mtime, token,
+                                        mBackupManagerService.getBackupManagerBinder());
+                            } else if (FullBackup.KEY_VALUE_DATA_TOKEN.equals(info.domain)) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Restoring key-value file for " + pkg
+                                            + " : " + info.path);
+                                }
+                                KeyValueAdbRestoreEngine restoreEngine =
+                                        new KeyValueAdbRestoreEngine(
+                                                mBackupManagerService,
+                                                mBackupManagerService.getDataDir(), info, mPipes[0],
+                                                mAgent, token);
+                                new Thread(restoreEngine, "restore-key-value-runner").start();
+                            } else {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Invoking agent to restore file " + info.path);
+                                }
+                                // fire up the app's agent listening on the socket.  If
+                                // the agent is running in the system process we can't
+                                // just invoke it asynchronously, so we provide a thread
+                                // for it here.
+                                if (mTargetApp.processName.equals("system")) {
+                                    Slog.d(TAG, "system process agent - spinning a thread");
+                                    RestoreFileRunnable runner = new RestoreFileRunnable(
+                                            mBackupManagerService, mAgent, info, mPipes[0], token);
+                                    new Thread(runner, "restore-sys-runner").start();
+                                } else {
+                                    mAgent.doRestoreFile(mPipes[0], info.size, info.type,
+                                            info.domain, info.path, info.mode, info.mtime,
+                                            token, mBackupManagerService.getBackupManagerBinder());
+                                }
+                            }
+                        } catch (IOException e) {
+                            // couldn't dup the socket for a process-local restore
+                            Slog.d(TAG, "Couldn't establish restore");
+                            agentSuccess = false;
+                            okay = false;
+                        } catch (RemoteException e) {
+                            // whoops, remote entity went away.  We'll eat the content
+                            // ourselves, then, and not copy it over.
+                            Slog.e(TAG, "Agent crashed during full restore");
+                            agentSuccess = false;
+                            okay = false;
+                        }
+
+                        // Copy over the data if the agent is still good
+                        if (okay) {
+                            boolean pipeOkay = true;
+                            FileOutputStream pipe = new FileOutputStream(
+                                    mPipes[1].getFileDescriptor());
+                            while (toCopy > 0) {
+                                int toRead = (toCopy > buffer.length)
+                                        ? buffer.length : (int) toCopy;
+                                int nRead = instream.read(buffer, 0, toRead);
+                                if (nRead >= 0) {
+                                    mBytes += nRead;
+                                }
+                                if (nRead <= 0) {
+                                    break;
+                                }
+                                toCopy -= nRead;
+
+                                // send it to the output pipe as long as things
+                                // are still good
+                                if (pipeOkay) {
+                                    try {
+                                        pipe.write(buffer, 0, nRead);
+                                    } catch (IOException e) {
+                                        Slog.e(TAG, "Failed to write to restore pipe", e);
+                                        pipeOkay = false;
+                                    }
+                                }
+                            }
+
+                            // done sending that file!  Now we just need to consume
+                            // the delta from info.size to the end of block.
+                            tarBackupReader.skipTarPadding(info.size);
+
+                            // and now that we've sent it all, wait for the remote
+                            // side to acknowledge receipt
+                            agentSuccess = mBackupManagerService.waitUntilOperationComplete(token);
+                        }
+
+                        // okay, if the remote end failed at any point, deal with
+                        // it by ignoring the rest of the restore on it
+                        if (!agentSuccess) {
+                            if (DEBUG) {
+                                Slog.d(TAG, "Agent failure restoring " + pkg + "; now ignoring");
+                            }
+                            mBackupManagerService.getBackupHandler().removeMessages(
+                                    MSG_RESTORE_OPERATION_TIMEOUT);
+                            tearDownPipes();
+                            tearDownAgent(mTargetApp, false);
+                            mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                        }
+                    }
+
+                    // Problems setting up the agent communication, or an already-
+                    // ignored package: skip to the next tar stream entry by
+                    // reading and discarding this file.
+                    if (!okay) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "[discarding file content]");
+                        }
+                        long bytesToConsume = (info.size + 511) & ~511;
+                        while (bytesToConsume > 0) {
+                            int toRead = (bytesToConsume > buffer.length)
+                                    ? buffer.length : (int) bytesToConsume;
+                            long nRead = instream.read(buffer, 0, toRead);
+                            if (nRead >= 0) {
+                                mBytes += nRead;
+                            }
+                            if (nRead <= 0) {
+                                break;
+                            }
+                            bytesToConsume -= nRead;
+                        }
+                    }
+                }
+            }
+        } catch (IOException e) {
+            if (DEBUG) {
+                Slog.w(TAG, "io exception on restore socket read", e);
+            }
+            // treat as EOF
+            info = null;
+        }
+
+        return (info != null);
+    }
+
+    private static boolean isCanonicalFilePath(String path) {
+        if (path.contains("..") || path.contains("//")) {
+            if (MORE_DEBUG) {
+                Slog.w(TAG, "Dropping invalid path " + path);
+            }
+            return false;
+        }
+
+        return true;
+    }
+
+    private void setUpPipes() throws IOException {
+        mPipes = ParcelFileDescriptor.createPipe();
+    }
+
+    private void tearDownPipes() {
+        if (mPipes != null) {
+            try {
+                mPipes[0].close();
+                mPipes[0] = null;
+                mPipes[1].close();
+                mPipes[1] = null;
+            } catch (IOException e) {
+                Slog.w(TAG, "Couldn't close agent pipes", e);
+            }
+            mPipes = null;
+        }
+    }
+
+    private void tearDownAgent(ApplicationInfo app, boolean doRestoreFinished) {
+        if (mAgent != null) {
+            try {
+                // In the adb restore case, we do restore-finished here
+                if (doRestoreFinished) {
+                    final int token = mBackupManagerService.generateRandomIntegerToken();
+                    final AdbRestoreFinishedLatch latch = new AdbRestoreFinishedLatch(
+                            mBackupManagerService, token);
+                    mBackupManagerService.prepareOperationTimeout(
+                            token, TIMEOUT_FULL_BACKUP_INTERVAL, latch, OP_TYPE_RESTORE_WAIT);
+                    if (mTargetApp.processName.equals("system")) {
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "system agent - restoreFinished on thread");
+                        }
+                        Runnable runner = new RestoreFinishedRunnable(mAgent, token,
+                                mBackupManagerService);
+                        new Thread(runner, "restore-sys-finished-runner").start();
+                    } else {
+                        mAgent.doRestoreFinished(token,
+                                mBackupManagerService.getBackupManagerBinder());
+                    }
+
+                    latch.await();
+                }
+
+                mBackupManagerService.tearDownAgentAndKill(app);
+            } catch (RemoteException e) {
+                Slog.d(TAG, "Lost app trying to shut down");
+            }
+            mAgent = null;
+        }
+    }
+
+}
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
new file mode 100644
index 0000000..21d5dc2
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -0,0 +1,1324 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.restore;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.KEY_WIDGET_STATE;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_RESTORE_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL;
+import static com.android.server.backup.RefactoredBackupManagerService.SETTINGS_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService
+        .TIMEOUT_RESTORE_FINISHED_INTERVAL;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL;
+import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTORE_STEP;
+import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
+import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;
+
+import android.app.ApplicationThreadConstants;
+import android.app.IBackupAgent;
+import android.app.backup.BackupDataInput;
+import android.app.backup.BackupDataOutput;
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.BackupTransport;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IRestoreObserver;
+import android.app.backup.RestoreDescription;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.EventLog;
+import android.util.Slog;
+
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.AppWidgetBackupBridge;
+import com.android.server.EventLogTags;
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.BackupUtils;
+import com.android.server.backup.PackageManagerBackupAgent;
+import com.android.server.backup.PackageManagerBackupAgent.Metadata;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.utils.AppBackupUtils;
+import com.android.server.backup.utils.BackupManagerMonitorUtils;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PerformUnifiedRestoreTask implements BackupRestoreTask {
+
+    private RefactoredBackupManagerService backupManagerService;
+    // Transport we're working with to do the restore
+    private IBackupTransport mTransport;
+
+    // Where per-transport saved state goes
+    File mStateDir;
+
+    // Restore observer; may be null
+    private IRestoreObserver mObserver;
+
+    // BackuoManagerMonitor; may be null
+    private IBackupManagerMonitor mMonitor;
+
+    // Token identifying the dataset to the transport
+    private long mToken;
+
+    // When this is a restore-during-install, this is the token identifying the
+    // operation to the Package Manager, and we must ensure that we let it know
+    // when we're finished.
+    private int mPmToken;
+
+    // When this is restore-during-install, we need to tell the package manager
+    // whether we actually launched the app, because this affects notifications
+    // around externally-visible state transitions.
+    private boolean mDidLaunch;
+
+    // Is this a whole-system restore, i.e. are we establishing a new ancestral
+    // dataset to base future restore-at-install operations from?
+    private boolean mIsSystemRestore;
+
+    // If this is a single-package restore, what package are we interested in?
+    private PackageInfo mTargetPackage;
+
+    // In all cases, the calculated list of packages that we are trying to restore
+    private List<PackageInfo> mAcceptSet;
+
+    // Our bookkeeping about the ancestral dataset
+    private PackageManagerBackupAgent mPmAgent;
+
+    // Currently-bound backup agent for restore + restoreFinished purposes
+    private IBackupAgent mAgent;
+
+    // What sort of restore we're doing now
+    private RestoreDescription mRestoreDescription;
+
+    // The package we're currently restoring
+    private PackageInfo mCurrentPackage;
+
+    // Widget-related data handled as part of this restore operation
+    private byte[] mWidgetData;
+
+    // Number of apps restored in this pass
+    private int mCount;
+
+    // When did we start?
+    private long mStartRealtime;
+
+    // State machine progress
+    private UnifiedRestoreState mState;
+
+    // How are things going?
+    private int mStatus;
+
+    // Done?
+    private boolean mFinished;
+
+    // Key/value: bookkeeping about staged data and files for agent access
+    private File mBackupDataName;
+    private File mStageName;
+    private File mSavedStateName;
+    private File mNewStateName;
+    ParcelFileDescriptor mBackupData;
+    ParcelFileDescriptor mNewState;
+
+    private final int mEphemeralOpToken;
+
+    // Invariant: mWakelock is already held, and this task is responsible for
+    // releasing it at the end of the restore operation.
+    public PerformUnifiedRestoreTask(RefactoredBackupManagerService backupManagerService,
+            IBackupTransport transport, IRestoreObserver observer,
+            IBackupManagerMonitor monitor, long restoreSetToken, PackageInfo targetPackage,
+            int pmToken, boolean isFullSystemRestore, String[] filterSet) {
+        this.backupManagerService = backupManagerService;
+        mEphemeralOpToken = backupManagerService.generateRandomIntegerToken();
+        mState = UnifiedRestoreState.INITIAL;
+        mStartRealtime = SystemClock.elapsedRealtime();
+
+        mTransport = transport;
+        mObserver = observer;
+        mMonitor = monitor;
+        mToken = restoreSetToken;
+        mPmToken = pmToken;
+        mTargetPackage = targetPackage;
+        mIsSystemRestore = isFullSystemRestore;
+        mFinished = false;
+        mDidLaunch = false;
+
+        if (targetPackage != null) {
+            // Single package restore
+            mAcceptSet = new ArrayList<>();
+            mAcceptSet.add(targetPackage);
+        } else {
+            // Everything possible, or a target set
+            if (filterSet == null) {
+                // We want everything and a pony
+                List<PackageInfo> apps =
+                        PackageManagerBackupAgent.getStorableApplications(
+                                backupManagerService.getPackageManager());
+                filterSet = packagesToNames(apps);
+                if (DEBUG) {
+                    Slog.i(TAG, "Full restore; asking about " + filterSet.length + " apps");
+                }
+            }
+
+            mAcceptSet = new ArrayList<>(filterSet.length);
+
+            // Pro tem, we insist on moving the settings provider package to last place.
+            // Keep track of whether it's in the list, and bump it down if so.  We also
+            // want to do the system package itself first if it's called for.
+            boolean hasSystem = false;
+            boolean hasSettings = false;
+            for (int i = 0; i < filterSet.length; i++) {
+                try {
+                    PackageInfo info = backupManagerService.getPackageManager().getPackageInfo(
+                            filterSet[i], 0);
+                    if ("android".equals(info.packageName)) {
+                        hasSystem = true;
+                        continue;
+                    }
+                    if (SETTINGS_PACKAGE.equals(info.packageName)) {
+                        hasSettings = true;
+                        continue;
+                    }
+
+                    if (AppBackupUtils.appIsEligibleForBackup(
+                            info.applicationInfo)) {
+                        mAcceptSet.add(info);
+                    }
+                } catch (NameNotFoundException e) {
+                    // requested package name doesn't exist; ignore it
+                }
+            }
+            if (hasSystem) {
+                try {
+                    mAcceptSet.add(0,
+                            backupManagerService.getPackageManager().getPackageInfo("android", 0));
+                } catch (NameNotFoundException e) {
+                    // won't happen; we know a priori that it's valid
+                }
+            }
+            if (hasSettings) {
+                try {
+                    mAcceptSet.add(backupManagerService.getPackageManager().getPackageInfo(
+                            SETTINGS_PACKAGE, 0));
+                } catch (NameNotFoundException e) {
+                    // this one is always valid too
+                }
+            }
+        }
+
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "Restore; accept set size is " + mAcceptSet.size());
+            for (PackageInfo info : mAcceptSet) {
+                Slog.v(TAG, "   " + info.packageName);
+            }
+        }
+    }
+
+    private String[] packagesToNames(List<PackageInfo> apps) {
+        final int N = apps.size();
+        String[] names = new String[N];
+        for (int i = 0; i < N; i++) {
+            names[i] = apps.get(i).packageName;
+        }
+        return names;
+    }
+
+    // Execute one tick of whatever state machine the task implements
+    @Override
+    public void execute() {
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "*** Executing restore step " + mState);
+        }
+        switch (mState) {
+            case INITIAL:
+                startRestore();
+                break;
+
+            case RUNNING_QUEUE:
+                dispatchNextRestore();
+                break;
+
+            case RESTORE_KEYVALUE:
+                restoreKeyValue();
+                break;
+
+            case RESTORE_FULL:
+                restoreFull();
+                break;
+
+            case RESTORE_FINISHED:
+                restoreFinished();
+                break;
+
+            case FINAL:
+                if (!mFinished) {
+                    finalizeRestore();
+                } else {
+                    Slog.e(TAG, "Duplicate finish");
+                }
+                mFinished = true;
+                break;
+        }
+    }
+
+    /*
+     * SKETCH OF OPERATION
+     *
+     * create one of these PerformUnifiedRestoreTask objects, telling it which
+     * dataset & transport to address, and then parameters within the restore
+     * operation: single target package vs many, etc.
+     *
+     * 1. transport.startRestore(token, list-of-packages).  If we need @pm@  it is
+     * always placed first and the settings provider always placed last [for now].
+     *
+     * 1a [if we needed @pm@ then nextRestorePackage() and restore the PMBA inline]
+     *
+     *   [ state change => RUNNING_QUEUE ]
+     *
+     * NOW ITERATE:
+     *
+     * { 3. t.nextRestorePackage()
+     *   4. does the metadata for this package allow us to restore it?
+     *      does the on-disk app permit us to restore it? [re-check allowBackup etc]
+     *   5. is this a key/value dataset?  => key/value agent restore
+     *       [ state change => RESTORE_KEYVALUE ]
+     *       5a. spin up agent
+     *       5b. t.getRestoreData() to stage it properly
+     *       5c. call into agent to perform restore
+     *       5d. tear down agent
+     *       [ state change => RUNNING_QUEUE ]
+     *
+     *   6. else it's a stream dataset:
+     *       [ state change => RESTORE_FULL ]
+     *       6a. instantiate the engine for a stream restore: engine handles agent lifecycles
+     *       6b. spin off engine runner on separate thread
+     *       6c. ITERATE getNextFullRestoreDataChunk() and copy data to engine runner socket
+     *       [ state change => RUNNING_QUEUE ]
+     * }
+     *
+     *   [ state change => FINAL ]
+     *
+     * 7. t.finishRestore(), release wakelock, etc.
+     *
+     *
+     */
+
+    // state INITIAL : set up for the restore and read the metadata if necessary
+    private void startRestore() {
+        sendStartRestore(mAcceptSet.size());
+
+        // If we're starting a full-system restore, set up to begin widget ID remapping
+        if (mIsSystemRestore) {
+            // TODO: http://b/22388012
+            AppWidgetBackupBridge.restoreStarting(UserHandle.USER_SYSTEM);
+        }
+
+        try {
+            String transportDir = mTransport.transportDirName();
+            mStateDir = new File(backupManagerService.getBaseStateDir(), transportDir);
+
+            // Fetch the current metadata from the dataset first
+            PackageInfo pmPackage = new PackageInfo();
+            pmPackage.packageName = PACKAGE_MANAGER_SENTINEL;
+            mAcceptSet.add(0, pmPackage);
+
+            PackageInfo[] packages = mAcceptSet.toArray(new PackageInfo[0]);
+            mStatus = mTransport.startRestore(mToken, packages);
+            if (mStatus != BackupTransport.TRANSPORT_OK) {
+                Slog.e(TAG, "Transport error " + mStatus + "; no restore possible");
+                mStatus = BackupTransport.TRANSPORT_ERROR;
+                executeNextState(UnifiedRestoreState.FINAL);
+                return;
+            }
+
+            RestoreDescription desc = mTransport.nextRestorePackage();
+            if (desc == null) {
+                Slog.e(TAG, "No restore metadata available; halting");
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_NO_RESTORE_METADATA_AVAILABLE,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, null);
+                mStatus = BackupTransport.TRANSPORT_ERROR;
+                executeNextState(UnifiedRestoreState.FINAL);
+                return;
+            }
+            if (!PACKAGE_MANAGER_SENTINEL.equals(
+                    desc.getPackageName())) {
+                Slog.e(TAG, "Required package metadata but got "
+                        + desc.getPackageName());
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_NO_PM_METADATA_RECEIVED,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, null);
+                mStatus = BackupTransport.TRANSPORT_ERROR;
+                executeNextState(UnifiedRestoreState.FINAL);
+                return;
+            }
+
+            // Pull the Package Manager metadata from the restore set first
+            mCurrentPackage = new PackageInfo();
+            mCurrentPackage.packageName = PACKAGE_MANAGER_SENTINEL;
+            mPmAgent = new PackageManagerBackupAgent(backupManagerService.getPackageManager(),
+                    null);
+            mAgent = IBackupAgent.Stub.asInterface(mPmAgent.onBind());
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "initiating restore for PMBA");
+            }
+            initiateOneRestore(mCurrentPackage, 0);
+            // The PM agent called operationComplete() already, because our invocation
+            // of it is process-local and therefore synchronous.  That means that the
+            // next-state message (RUNNING_QUEUE) is already enqueued.  Only if we're
+            // unable to proceed with running the queue do we remove that pending
+            // message and jump straight to the FINAL state.  Because this was
+            // synchronous we also know that we should cancel the pending timeout
+            // message.
+            backupManagerService.getBackupHandler().removeMessages(
+                    MSG_RESTORE_OPERATION_TIMEOUT);
+
+            // Verify that the backup set includes metadata.  If not, we can't do
+            // signature/version verification etc, so we simply do not proceed with
+            // the restore operation.
+            if (!mPmAgent.hasMetadata()) {
+                Slog.e(TAG, "PM agent has no metadata, so not restoring");
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_PM_AGENT_HAS_NO_METADATA,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, null);
+                EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+                        PACKAGE_MANAGER_SENTINEL,
+                        "Package manager restore metadata missing");
+                mStatus = BackupTransport.TRANSPORT_ERROR;
+                backupManagerService.getBackupHandler().removeMessages(
+                        MSG_BACKUP_RESTORE_STEP, this);
+                executeNextState(UnifiedRestoreState.FINAL);
+                return;
+            }
+
+            // Success; cache the metadata and continue as expected with the
+            // next state already enqueued
+
+        } catch (Exception e) {
+            // If we lost the transport at any time, halt
+            Slog.e(TAG, "Unable to contact transport for restore: " + e.getMessage());
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_LOST_TRANSPORT,
+                    null,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, null);
+            mStatus = BackupTransport.TRANSPORT_ERROR;
+            backupManagerService.getBackupHandler().removeMessages(
+                    MSG_BACKUP_RESTORE_STEP, this);
+            executeNextState(UnifiedRestoreState.FINAL);
+            return;
+        }
+    }
+
+    // state RUNNING_QUEUE : figure out what the next thing to be restored is,
+    // and fire the appropriate next step
+    private void dispatchNextRestore() {
+        UnifiedRestoreState nextState = UnifiedRestoreState.FINAL;
+        try {
+            mRestoreDescription = mTransport.nextRestorePackage();
+            final String pkgName = (mRestoreDescription != null)
+                    ? mRestoreDescription.getPackageName() : null;
+            if (pkgName == null) {
+                Slog.e(TAG, "Failure getting next package name");
+                EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
+                nextState = UnifiedRestoreState.FINAL;
+                return;
+            } else if (mRestoreDescription == RestoreDescription.NO_MORE_PACKAGES) {
+                // Yay we've reached the end cleanly
+                if (DEBUG) {
+                    Slog.v(TAG, "No more packages; finishing restore");
+                }
+                int millis = (int) (SystemClock.elapsedRealtime() - mStartRealtime);
+                EventLog.writeEvent(EventLogTags.RESTORE_SUCCESS, mCount, millis);
+                nextState = UnifiedRestoreState.FINAL;
+                return;
+            }
+
+            if (DEBUG) {
+                Slog.i(TAG, "Next restore package: " + mRestoreDescription);
+            }
+            sendOnRestorePackage(pkgName);
+
+            Metadata metaInfo = mPmAgent.getRestoredMetadata(pkgName);
+            if (metaInfo == null) {
+                Slog.e(TAG, "No metadata for " + pkgName);
+                EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, pkgName,
+                        "Package metadata missing");
+                nextState = UnifiedRestoreState.RUNNING_QUEUE;
+                return;
+            }
+
+            try {
+                mCurrentPackage = backupManagerService.getPackageManager().getPackageInfo(
+                        pkgName, PackageManager.GET_SIGNATURES);
+            } catch (NameNotFoundException e) {
+                // Whoops, we thought we could restore this package but it
+                // turns out not to be present.  Skip it.
+                Slog.e(TAG, "Package not present: " + pkgName);
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_NOT_PRESENT,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        null);
+                EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, pkgName,
+                        "Package missing on device");
+                nextState = UnifiedRestoreState.RUNNING_QUEUE;
+                return;
+            }
+
+            if (metaInfo.versionCode > mCurrentPackage.versionCode) {
+                // Data is from a "newer" version of the app than we have currently
+                // installed.  If the app has not declared that it is prepared to
+                // handle this case, we do not attempt the restore.
+                if ((mCurrentPackage.applicationInfo.flags
+                        & ApplicationInfo.FLAG_RESTORE_ANY_VERSION) == 0) {
+                    String message = "Source version " + metaInfo.versionCode
+                            + " > installed version " + mCurrentPackage.versionCode;
+                    Slog.w(TAG, "Package " + pkgName + ": " + message);
+                    Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
+                            BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION,
+                            metaInfo.versionCode);
+                    monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
+                            monitoringExtras,
+                            BackupManagerMonitor.EXTRA_LOG_RESTORE_ANYWAY, false);
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                            BackupManagerMonitor.LOG_EVENT_ID_RESTORE_VERSION_HIGHER,
+                            mCurrentPackage,
+                            BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            monitoringExtras);
+                    EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+                            pkgName, message);
+                    nextState = UnifiedRestoreState.RUNNING_QUEUE;
+                    return;
+                } else {
+                    if (DEBUG) {
+                        Slog.v(TAG, "Source version " + metaInfo.versionCode
+                                + " > installed version " + mCurrentPackage.versionCode
+                                + " but restoreAnyVersion");
+                    }
+                    Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
+                            BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION,
+                            metaInfo.versionCode);
+                    monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
+                            monitoringExtras,
+                            BackupManagerMonitor.EXTRA_LOG_RESTORE_ANYWAY, true);
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                            BackupManagerMonitor.LOG_EVENT_ID_RESTORE_VERSION_HIGHER,
+                            mCurrentPackage,
+                            BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            monitoringExtras);
+                }
+            }
+
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "Package " + pkgName
+                        + " restore version [" + metaInfo.versionCode
+                        + "] is compatible with installed version ["
+                        + mCurrentPackage.versionCode + "]");
+            }
+
+            // Reset per-package preconditions and fire the appropriate next state
+            mWidgetData = null;
+            final int type = mRestoreDescription.getDataType();
+            if (type == RestoreDescription.TYPE_KEY_VALUE) {
+                nextState = UnifiedRestoreState.RESTORE_KEYVALUE;
+            } else if (type == RestoreDescription.TYPE_FULL_STREAM) {
+                nextState = UnifiedRestoreState.RESTORE_FULL;
+            } else {
+                // Unknown restore type; ignore this package and move on
+                Slog.e(TAG, "Unrecognized restore type " + type);
+                nextState = UnifiedRestoreState.RUNNING_QUEUE;
+                return;
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "Can't get next restore target from transport; halting: "
+                    + e.getMessage());
+            EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
+            nextState = UnifiedRestoreState.FINAL;
+            return;
+        } finally {
+            executeNextState(nextState);
+        }
+    }
+
+    // state RESTORE_KEYVALUE : restore one package via key/value API set
+    private void restoreKeyValue() {
+        // Initiating the restore will pass responsibility for the state machine's
+        // progress to the agent callback, so we do not always execute the
+        // next state here.
+        final String packageName = mCurrentPackage.packageName;
+        // Validate some semantic requirements that apply in this way
+        // only to the key/value restore API flow
+        if (mCurrentPackage.applicationInfo.backupAgentName == null
+                || "".equals(mCurrentPackage.applicationInfo.backupAgentName)) {
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Data exists for package " + packageName
+                        + " but app has no agent; skipping");
+            }
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_APP_HAS_NO_AGENT, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, null);
+            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName,
+                    "Package has no agent");
+            executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+            return;
+        }
+
+        Metadata metaInfo = mPmAgent.getRestoredMetadata(packageName);
+        if (!BackupUtils.signaturesMatch(metaInfo.sigHashes, mCurrentPackage)) {
+            Slog.w(TAG, "Signature mismatch restoring " + packageName);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_SIGNATURE_MISMATCH, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, null);
+            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName,
+                    "Signature mismatch");
+            executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+            return;
+        }
+
+        // Good to go!  Set up and bind the agent...
+        mAgent = backupManagerService.bindToAgentSynchronous(
+                mCurrentPackage.applicationInfo,
+                ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL);
+        if (mAgent == null) {
+            Slog.w(TAG, "Can't find backup agent for " + packageName);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_CANT_FIND_AGENT, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, null);
+            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName,
+                    "Restore agent missing");
+            executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+            return;
+        }
+
+        // Whatever happens next, we've launched the target app now; remember that.
+        mDidLaunch = true;
+
+        // And then finally start the restore on this agent
+        try {
+            initiateOneRestore(mCurrentPackage, metaInfo.versionCode);
+            ++mCount;
+        } catch (Exception e) {
+            Slog.e(TAG, "Error when attempting restore: " + e.toString());
+            keyValueAgentErrorCleanup();
+            executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+        }
+    }
+
+    // Guts of a key/value restore operation
+    void initiateOneRestore(PackageInfo app, int appVersionCode) {
+        final String packageName = app.packageName;
+
+        if (DEBUG) {
+            Slog.d(TAG, "initiateOneRestore packageName=" + packageName);
+        }
+
+        // !!! TODO: get the dirs from the transport
+        mBackupDataName = new File(backupManagerService.getDataDir(), packageName + ".restore");
+        mStageName = new File(backupManagerService.getDataDir(), packageName + ".stage");
+        mNewStateName = new File(mStateDir, packageName + ".new");
+        mSavedStateName = new File(mStateDir, packageName);
+
+        // don't stage the 'android' package where the wallpaper data lives.  this is
+        // an optimization: we know there's no widget data hosted/published by that
+        // package, and this way we avoid doing a spurious copy of MB-sized wallpaper
+        // data following the download.
+        boolean staging = !packageName.equals("android");
+        ParcelFileDescriptor stage;
+        File downloadFile = (staging) ? mStageName : mBackupDataName;
+
+        try {
+            // Run the transport's restore pass
+            stage = ParcelFileDescriptor.open(downloadFile,
+                    ParcelFileDescriptor.MODE_READ_WRITE |
+                            ParcelFileDescriptor.MODE_CREATE |
+                            ParcelFileDescriptor.MODE_TRUNCATE);
+
+            if (mTransport.getRestoreData(stage) != BackupTransport.TRANSPORT_OK) {
+                // Transport-level failure, so we wind everything up and
+                // terminate the restore operation.
+                Slog.e(TAG, "Error getting restore data for " + packageName);
+                EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
+                stage.close();
+                downloadFile.delete();
+                executeNextState(UnifiedRestoreState.FINAL);
+                return;
+            }
+
+            // We have the data from the transport. Now we extract and strip
+            // any per-package metadata (typically widget-related information)
+            // if appropriate
+            if (staging) {
+                stage.close();
+                stage = ParcelFileDescriptor.open(downloadFile,
+                        ParcelFileDescriptor.MODE_READ_ONLY);
+
+                mBackupData = ParcelFileDescriptor.open(mBackupDataName,
+                        ParcelFileDescriptor.MODE_READ_WRITE |
+                                ParcelFileDescriptor.MODE_CREATE |
+                                ParcelFileDescriptor.MODE_TRUNCATE);
+
+                BackupDataInput in = new BackupDataInput(stage.getFileDescriptor());
+                BackupDataOutput out = new BackupDataOutput(mBackupData.getFileDescriptor());
+                byte[] buffer = new byte[8192]; // will grow when needed
+                while (in.readNextHeader()) {
+                    final String key = in.getKey();
+                    final int size = in.getDataSize();
+
+                    // is this a special key?
+                    if (key.equals(KEY_WIDGET_STATE)) {
+                        if (DEBUG) {
+                            Slog.i(TAG, "Restoring widget state for " + packageName);
+                        }
+                        mWidgetData = new byte[size];
+                        in.readEntityData(mWidgetData, 0, size);
+                    } else {
+                        if (size > buffer.length) {
+                            buffer = new byte[size];
+                        }
+                        in.readEntityData(buffer, 0, size);
+                        out.writeEntityHeader(key, size);
+                        out.writeEntityData(buffer, size);
+                    }
+                }
+
+                mBackupData.close();
+            }
+
+            // Okay, we have the data.  Now have the agent do the restore.
+            stage.close();
+
+            mBackupData = ParcelFileDescriptor.open(mBackupDataName,
+                    ParcelFileDescriptor.MODE_READ_ONLY);
+
+            mNewState = ParcelFileDescriptor.open(mNewStateName,
+                    ParcelFileDescriptor.MODE_READ_WRITE |
+                            ParcelFileDescriptor.MODE_CREATE |
+                            ParcelFileDescriptor.MODE_TRUNCATE);
+
+            // Kick off the restore, checking for hung agents.  The timeout or
+            // the operationComplete() callback will schedule the next step,
+            // so we do not do that here.
+            backupManagerService.prepareOperationTimeout(
+                    mEphemeralOpToken, TIMEOUT_RESTORE_INTERVAL, this, OP_TYPE_RESTORE_WAIT);
+            mAgent.doRestore(mBackupData, appVersionCode, mNewState,
+                    mEphemeralOpToken, backupManagerService.getBackupManagerBinder());
+        } catch (Exception e) {
+            Slog.e(TAG, "Unable to call app for restore: " + packageName, e);
+            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+                    packageName, e.toString());
+            keyValueAgentErrorCleanup();    // clears any pending timeout messages as well
+
+            // After a restore failure we go back to running the queue.  If there
+            // are no more packages to be restored that will be handled by the
+            // next step.
+            executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+        }
+    }
+
+    // state RESTORE_FULL : restore one package via streaming engine
+    private void restoreFull() {
+        // None of this can run on the work looper here, so we spin asynchronous
+        // work like this:
+        //
+        //   StreamFeederThread: read data from mTransport.getNextFullRestoreDataChunk()
+        //                       write it into the pipe to the engine
+        //   EngineThread: FullRestoreEngine thread communicating with the target app
+        //
+        // When finished, StreamFeederThread executes next state as appropriate on the
+        // backup looper, and the overall unified restore task resumes
+        try {
+            StreamFeederThread feeder = new StreamFeederThread();
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Spinning threads for stream restore of "
+                        + mCurrentPackage.packageName);
+            }
+            new Thread(feeder, "unified-stream-feeder").start();
+
+            // At this point the feeder is responsible for advancing the restore
+            // state, so we're done here.
+        } catch (IOException e) {
+            // Unable to instantiate the feeder thread -- we need to bail on the
+            // current target.  We haven't asked the transport for data yet, though,
+            // so we can do that simply by going back to running the restore queue.
+            Slog.e(TAG, "Unable to construct pipes for stream restore!");
+            executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+        }
+    }
+
+    // state RESTORE_FINISHED : provide the "no more data" signpost callback at the end
+    private void restoreFinished() {
+        try {
+            backupManagerService
+                    .prepareOperationTimeout(mEphemeralOpToken,
+                            TIMEOUT_RESTORE_FINISHED_INTERVAL, this,
+                            OP_TYPE_RESTORE_WAIT);
+            mAgent.doRestoreFinished(mEphemeralOpToken,
+                    backupManagerService.getBackupManagerBinder());
+            // If we get this far, the callback or timeout will schedule the
+            // next restore state, so we're done
+        } catch (Exception e) {
+            final String packageName = mCurrentPackage.packageName;
+            Slog.e(TAG, "Unable to finalize restore of " + packageName);
+            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+                    packageName, e.toString());
+            keyValueAgentErrorCleanup();
+            executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+        }
+    }
+
+    class StreamFeederThread extends RestoreEngine implements Runnable, BackupRestoreTask {
+
+        final String TAG = "StreamFeederThread";
+        FullRestoreEngine mEngine;
+        EngineThread mEngineThread;
+
+        // pipe through which we read data from the transport. [0] read, [1] write
+        ParcelFileDescriptor[] mTransportPipes;
+
+        // pipe through which the engine will read data.  [0] read, [1] write
+        ParcelFileDescriptor[] mEnginePipes;
+
+        private final int mEphemeralOpToken;
+
+        public StreamFeederThread() throws IOException {
+            mEphemeralOpToken = backupManagerService.generateRandomIntegerToken();
+            mTransportPipes = ParcelFileDescriptor.createPipe();
+            mEnginePipes = ParcelFileDescriptor.createPipe();
+            setRunning(true);
+        }
+
+        @Override
+        public void run() {
+            UnifiedRestoreState nextState = UnifiedRestoreState.RUNNING_QUEUE;
+            int status = BackupTransport.TRANSPORT_OK;
+
+            EventLog.writeEvent(EventLogTags.FULL_RESTORE_PACKAGE,
+                    mCurrentPackage.packageName);
+
+            mEngine = new FullRestoreEngine(backupManagerService, this, null,
+                    mMonitor, mCurrentPackage, false, false, mEphemeralOpToken);
+            mEngineThread = new EngineThread(mEngine, mEnginePipes[0]);
+
+            ParcelFileDescriptor eWriteEnd = mEnginePipes[1];
+            ParcelFileDescriptor tReadEnd = mTransportPipes[0];
+            ParcelFileDescriptor tWriteEnd = mTransportPipes[1];
+
+            int bufferSize = 32 * 1024;
+            byte[] buffer = new byte[bufferSize];
+            FileOutputStream engineOut = new FileOutputStream(eWriteEnd.getFileDescriptor());
+            FileInputStream transportIn = new FileInputStream(tReadEnd.getFileDescriptor());
+
+            // spin up the engine and start moving data to it
+            new Thread(mEngineThread, "unified-restore-engine").start();
+
+            try {
+                while (status == BackupTransport.TRANSPORT_OK) {
+                    // have the transport write some of the restoring data to us
+                    int result = mTransport.getNextFullRestoreDataChunk(tWriteEnd);
+                    if (result > 0) {
+                        // The transport wrote this many bytes of restore data to the
+                        // pipe, so pass it along to the engine.
+                        if (MORE_DEBUG) {
+                            Slog.v(TAG, "  <- transport provided chunk size " + result);
+                        }
+                        if (result > bufferSize) {
+                            bufferSize = result;
+                            buffer = new byte[bufferSize];
+                        }
+                        int toCopy = result;
+                        while (toCopy > 0) {
+                            int n = transportIn.read(buffer, 0, toCopy);
+                            engineOut.write(buffer, 0, n);
+                            toCopy -= n;
+                            if (MORE_DEBUG) {
+                                Slog.v(TAG, "  -> wrote " + n + " to engine, left=" + toCopy);
+                            }
+                        }
+                    } else if (result == BackupTransport.NO_MORE_DATA) {
+                        // Clean finish.  Wind up and we're done!
+                        if (MORE_DEBUG) {
+                            Slog.i(TAG, "Got clean full-restore EOF for "
+                                    + mCurrentPackage.packageName);
+                        }
+                        status = BackupTransport.TRANSPORT_OK;
+                        break;
+                    } else {
+                        // Transport reported some sort of failure; the fall-through
+                        // handling will deal properly with that.
+                        Slog.e(TAG, "Error " + result + " streaming restore for "
+                                + mCurrentPackage.packageName);
+                        EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
+                        status = result;
+                    }
+                }
+                if (MORE_DEBUG) {
+                    Slog.v(TAG, "Done copying to engine, falling through");
+                }
+            } catch (IOException e) {
+                // We lost our ability to communicate via the pipes.  That's worrying
+                // but potentially recoverable; abandon this package's restore but
+                // carry on with the next restore target.
+                Slog.e(TAG, "Unable to route data for restore");
+                EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+                        mCurrentPackage.packageName, "I/O error on pipes");
+                status = BackupTransport.AGENT_ERROR;
+            } catch (Exception e) {
+                // The transport threw; terminate the whole operation.  Closing
+                // the sockets will wake up the engine and it will then tidy up the
+                // remote end.
+                Slog.e(TAG, "Transport failed during restore: " + e.getMessage());
+                EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
+                status = BackupTransport.TRANSPORT_ERROR;
+            } finally {
+                // Close the transport pipes and *our* end of the engine pipe,
+                // but leave the engine thread's end open so that it properly
+                // hits EOF and winds up its operations.
+                IoUtils.closeQuietly(mEnginePipes[1]);
+                IoUtils.closeQuietly(mTransportPipes[0]);
+                IoUtils.closeQuietly(mTransportPipes[1]);
+
+                // Don't proceed until the engine has wound up operations
+                mEngineThread.waitForResult();
+
+                // Now we're really done with this one too
+                IoUtils.closeQuietly(mEnginePipes[0]);
+
+                // In all cases we want to remember whether we launched
+                // the target app as part of our work so far.
+                mDidLaunch = (mEngine.getAgent() != null);
+
+                // If we hit a transport-level error, we are done with everything;
+                // if we hit an agent error we just go back to running the queue.
+                if (status == BackupTransport.TRANSPORT_OK) {
+                    // Clean finish means we issue the restore-finished callback
+                    nextState = UnifiedRestoreState.RESTORE_FINISHED;
+
+                    // the engine bound the target's agent, so recover that binding
+                    // to use for the callback.
+                    mAgent = mEngine.getAgent();
+
+                    // and the restored widget data, if any
+                    mWidgetData = mEngine.getWidgetData();
+                } else {
+                    // Something went wrong somewhere.  Whether it was at the transport
+                    // level is immaterial; we need to tell the transport to bail
+                    try {
+                        mTransport.abortFullRestore();
+                    } catch (Exception e) {
+                        // transport itself is dead; make sure we handle this as a
+                        // fatal error
+                        Slog.e(TAG, "Transport threw from abortFullRestore: " + e.getMessage());
+                        status = BackupTransport.TRANSPORT_ERROR;
+                    }
+
+                    // We also need to wipe the current target's data, as it's probably
+                    // in an incoherent state.
+                    backupManagerService.clearApplicationDataSynchronous(
+                            mCurrentPackage.packageName);
+
+                    // Schedule the next state based on the nature of our failure
+                    if (status == BackupTransport.TRANSPORT_ERROR) {
+                        nextState = UnifiedRestoreState.FINAL;
+                    } else {
+                        nextState = UnifiedRestoreState.RUNNING_QUEUE;
+                    }
+                }
+                executeNextState(nextState);
+                setRunning(false);
+            }
+        }
+
+        // BackupRestoreTask interface, specifically for timeout handling
+
+        @Override
+        public void execute() { /* intentionally empty */ }
+
+        @Override
+        public void operationComplete(long result) { /* intentionally empty */ }
+
+        // The app has timed out handling a restoring file
+        @Override
+        public void handleCancel(boolean cancelAll) {
+            backupManagerService.removeOperation(mEphemeralOpToken);
+            if (DEBUG) {
+                Slog.w(TAG, "Full-data restore target timed out; shutting down");
+            }
+
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_TIMEOUT,
+                    mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, null);
+            mEngineThread.handleTimeout();
+
+            IoUtils.closeQuietly(mEnginePipes[1]);
+            mEnginePipes[1] = null;
+            IoUtils.closeQuietly(mEnginePipes[0]);
+            mEnginePipes[0] = null;
+        }
+    }
+
+    class EngineThread implements Runnable {
+
+        FullRestoreEngine mEngine;
+        FileInputStream mEngineStream;
+
+        EngineThread(FullRestoreEngine engine, ParcelFileDescriptor engineSocket) {
+            mEngine = engine;
+            engine.setRunning(true);
+            // We *do* want this FileInputStream to own the underlying fd, so that
+            // when we are finished with it, it closes this end of the pipe in a way
+            // that signals its other end.
+            mEngineStream = new FileInputStream(engineSocket.getFileDescriptor(), true);
+        }
+
+        public boolean isRunning() {
+            return mEngine.isRunning();
+        }
+
+        public int waitForResult() {
+            return mEngine.waitForResult();
+        }
+
+        @Override
+        public void run() {
+            try {
+                while (mEngine.isRunning()) {
+                    // Tell it to be sure to leave the agent instance up after finishing
+                    mEngine.restoreOneFile(mEngineStream, false, mEngine.mBuffer,
+                            mEngine.mOnlyPackage, mEngine.mAllowApks, mEngine.mEphemeralOpToken,
+                            mEngine.mMonitor);
+                }
+            } finally {
+                // Because mEngineStream adopted its underlying FD, this also
+                // closes this end of the pipe.
+                IoUtils.closeQuietly(mEngineStream);
+            }
+        }
+
+        public void handleTimeout() {
+            IoUtils.closeQuietly(mEngineStream);
+            mEngine.handleTimeout();
+        }
+    }
+
+    // state FINAL : tear everything down and we're done.
+    private void finalizeRestore() {
+        if (MORE_DEBUG) {
+            Slog.d(TAG, "finishing restore mObserver=" + mObserver);
+        }
+
+        try {
+            mTransport.finishRestore();
+        } catch (Exception e) {
+            Slog.e(TAG, "Error finishing restore", e);
+        }
+
+        // Tell the observer we're done
+        if (mObserver != null) {
+            try {
+                mObserver.restoreFinished(mStatus);
+            } catch (RemoteException e) {
+                Slog.d(TAG, "Restore observer died at restoreFinished");
+            }
+        }
+
+        // Clear any ongoing session timeout.
+        backupManagerService.getBackupHandler().removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
+
+        // If we have a PM token, we must under all circumstances be sure to
+        // handshake when we've finished.
+        if (mPmToken > 0) {
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "finishing PM token " + mPmToken);
+            }
+            try {
+                backupManagerService.getPackageManagerBinder().finishPackageInstall(mPmToken,
+                        mDidLaunch);
+            } catch (RemoteException e) { /* can't happen */ }
+        } else {
+            // We were invoked via an active restore session, not by the Package
+            // Manager, so start up the session timeout again.
+            backupManagerService.getBackupHandler().sendEmptyMessageDelayed(
+                    MSG_RESTORE_SESSION_TIMEOUT,
+                    TIMEOUT_RESTORE_INTERVAL);
+        }
+
+        // Kick off any work that may be needed regarding app widget restores
+        // TODO: http://b/22388012
+        AppWidgetBackupBridge.restoreFinished(UserHandle.USER_SYSTEM);
+
+        // If this was a full-system restore, record the ancestral
+        // dataset information
+        if (mIsSystemRestore && mPmAgent != null) {
+            backupManagerService.setAncestralPackages(mPmAgent.getRestoredPackages());
+            backupManagerService.setAncestralToken(mToken);
+            backupManagerService.writeRestoreTokens();
+        }
+
+        // done; we can finally release the wakelock and be legitimately done.
+        Slog.i(TAG, "Restore complete.");
+
+        synchronized (backupManagerService.getPendingRestores()) {
+            if (backupManagerService.getPendingRestores().size() > 0) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Starting next pending restore.");
+                }
+                PerformUnifiedRestoreTask task = backupManagerService.getPendingRestores().remove();
+                backupManagerService.getBackupHandler().sendMessage(
+                        backupManagerService.getBackupHandler().obtainMessage(
+                                MSG_BACKUP_RESTORE_STEP, task));
+
+            } else {
+                backupManagerService.setRestoreInProgress(false);
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "No pending restores.");
+                }
+            }
+        }
+
+        backupManagerService.getWakelock().release();
+    }
+
+    void keyValueAgentErrorCleanup() {
+        // If the agent fails restore, it might have put the app's data
+        // into an incoherent state.  For consistency we wipe its data
+        // again in this case before continuing with normal teardown
+        backupManagerService.clearApplicationDataSynchronous(mCurrentPackage.packageName);
+        keyValueAgentCleanup();
+    }
+
+    // TODO: clean up naming; this is now used at finish by both k/v and stream restores
+    void keyValueAgentCleanup() {
+        mBackupDataName.delete();
+        mStageName.delete();
+        try {
+            if (mBackupData != null) {
+                mBackupData.close();
+            }
+        } catch (IOException e) {
+        }
+        try {
+            if (mNewState != null) {
+                mNewState.close();
+            }
+        } catch (IOException e) {
+        }
+        mBackupData = mNewState = null;
+
+        // if everything went okay, remember the recorded state now
+        //
+        // !!! TODO: the restored data could be migrated on the server
+        // side into the current dataset.  In that case the new state file
+        // we just created would reflect the data already extant in the
+        // backend, so there'd be nothing more to do.  Until that happens,
+        // however, we need to make sure that we record the data to the
+        // current backend dataset.  (Yes, this means shipping the data over
+        // the wire in both directions.  That's bad, but consistency comes
+        // first, then efficiency.)  Once we introduce server-side data
+        // migration to the newly-restored device's dataset, we will change
+        // the following from a discard of the newly-written state to the
+        // "correct" operation of renaming into the canonical state blob.
+        mNewStateName.delete();                      // TODO: remove; see above comment
+        //mNewStateName.renameTo(mSavedStateName);   // TODO: replace with this
+
+        // If this wasn't the PM pseudopackage, tear down the agent side
+        if (mCurrentPackage.applicationInfo != null) {
+            // unbind and tidy up even on timeout or failure
+            try {
+                backupManagerService.getActivityManager().unbindBackupAgent(
+                        mCurrentPackage.applicationInfo);
+
+                // The agent was probably running with a stub Application object,
+                // which isn't a valid run mode for the main app logic.  Shut
+                // down the app so that next time it's launched, it gets the
+                // usual full initialization.  Note that this is only done for
+                // full-system restores: when a single app has requested a restore,
+                // it is explicitly not killed following that operation.
+                //
+                // We execute this kill when these conditions hold:
+                //    1. it's not a system-uid process,
+                //    2. the app did not request its own restore (mTargetPackage == null), and
+                // either
+                //    3a. the app is a full-data target (TYPE_FULL_STREAM) or
+                //     b. the app does not state android:killAfterRestore="false" in its manifest
+                final int appFlags = mCurrentPackage.applicationInfo.flags;
+                final boolean killAfterRestore =
+                        (mCurrentPackage.applicationInfo.uid >= Process.FIRST_APPLICATION_UID)
+                                && ((mRestoreDescription.getDataType()
+                                == RestoreDescription.TYPE_FULL_STREAM)
+                                || ((appFlags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0));
+
+                if (mTargetPackage == null && killAfterRestore) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "Restore complete, killing host process of "
+                                + mCurrentPackage.applicationInfo.processName);
+                    }
+                    backupManagerService.getActivityManager().killApplicationProcess(
+                            mCurrentPackage.applicationInfo.processName,
+                            mCurrentPackage.applicationInfo.uid);
+                }
+            } catch (RemoteException e) {
+                // can't happen; we run in the same process as the activity manager
+            }
+        }
+
+        // The caller is responsible for reestablishing the state machine; our
+        // responsibility here is to clear the decks for whatever comes next.
+        backupManagerService.getBackupHandler().removeMessages(MSG_RESTORE_OPERATION_TIMEOUT, this);
+    }
+
+    @Override
+    public void operationComplete(long unusedResult) {
+        backupManagerService.removeOperation(mEphemeralOpToken);
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "operationComplete() during restore: target="
+                    + mCurrentPackage.packageName
+                    + " state=" + mState);
+        }
+
+        final UnifiedRestoreState nextState;
+        switch (mState) {
+            case INITIAL:
+                // We've just (manually) restored the PMBA.  It doesn't need the
+                // additional restore-finished callback so we bypass that and go
+                // directly to running the queue.
+                nextState = UnifiedRestoreState.RUNNING_QUEUE;
+                break;
+
+            case RESTORE_KEYVALUE:
+            case RESTORE_FULL: {
+                // Okay, we've just heard back from the agent that it's done with
+                // the restore itself.  We now have to send the same agent its
+                // doRestoreFinished() callback, so roll into that state.
+                nextState = UnifiedRestoreState.RESTORE_FINISHED;
+                break;
+            }
+
+            case RESTORE_FINISHED: {
+                // Okay, we're done with this package.  Tidy up and go on to the next
+                // app in the queue.
+                int size = (int) mBackupDataName.length();
+                EventLog.writeEvent(EventLogTags.RESTORE_PACKAGE,
+                        mCurrentPackage.packageName, size);
+
+                // Just go back to running the restore queue
+                keyValueAgentCleanup();
+
+                // If there was widget state associated with this app, get the OS to
+                // incorporate it into current bookeeping and then pass that along to
+                // the app as part of the restore-time work.
+                if (mWidgetData != null) {
+                    backupManagerService.restoreWidgetData(mCurrentPackage.packageName,
+                            mWidgetData);
+                }
+
+                nextState = UnifiedRestoreState.RUNNING_QUEUE;
+                break;
+            }
+
+            default: {
+                // Some kind of horrible semantic error; we're in an unexpected state.
+                // Back off hard and wind up.
+                Slog.e(TAG, "Unexpected restore callback into state " + mState);
+                keyValueAgentErrorCleanup();
+                nextState = UnifiedRestoreState.FINAL;
+                break;
+            }
+        }
+
+        executeNextState(nextState);
+    }
+
+    // A call to agent.doRestore() or agent.doRestoreFinished() has timed out
+    @Override
+    public void handleCancel(boolean cancelAll) {
+        backupManagerService.removeOperation(mEphemeralOpToken);
+        Slog.e(TAG, "Timeout restoring application " + mCurrentPackage.packageName);
+        mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_RESTORE_TIMEOUT,
+                mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, null);
+        EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+                mCurrentPackage.packageName, "restore timeout");
+        // Handle like an agent that threw on invocation: wipe it and go on to the next
+        keyValueAgentErrorCleanup();
+        executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+    }
+
+    void executeNextState(UnifiedRestoreState nextState) {
+        if (MORE_DEBUG) {
+            Slog.i(TAG, " => executing next step on "
+                    + this + " nextState=" + nextState);
+        }
+        mState = nextState;
+        Message msg = backupManagerService.getBackupHandler().obtainMessage(
+                MSG_BACKUP_RESTORE_STEP, this);
+        backupManagerService.getBackupHandler().sendMessage(msg);
+    }
+
+    // restore observer support
+    void sendStartRestore(int numPackages) {
+        if (mObserver != null) {
+            try {
+                mObserver.restoreStarting(numPackages);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Restore observer went away: startRestore");
+                mObserver = null;
+            }
+        }
+    }
+
+    void sendOnRestorePackage(String name) {
+        if (mObserver != null) {
+            if (mObserver != null) {
+                try {
+                    mObserver.onUpdate(mCount, name);
+                } catch (RemoteException e) {
+                    Slog.d(TAG, "Restore observer died in onUpdate");
+                    mObserver = null;
+                }
+            }
+        }
+    }
+
+    void sendEndRestore() {
+        if (mObserver != null) {
+            try {
+                mObserver.restoreFinished(mStatus);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Restore observer went away: endRestore");
+                mObserver = null;
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/RestoreDeleteObserver.java b/services/backup/java/com/android/server/backup/restore/RestoreDeleteObserver.java
new file mode 100644
index 0000000..12be84c
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/RestoreDeleteObserver.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.restore;
+
+import android.content.pm.IPackageDeleteObserver;
+import android.os.RemoteException;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Synchronous implementation of IPackageDeleteObserver.Stub.
+ *
+ * Allows the caller to synchronously wait for package deleted event.
+ */
+public class RestoreDeleteObserver extends IPackageDeleteObserver.Stub {
+
+    @GuardedBy("mDone")
+    private final AtomicBoolean mDone = new AtomicBoolean();
+
+    public RestoreDeleteObserver() {
+    }
+
+    /**
+     * Resets the observer to prepare for another removal.
+     */
+    public void reset() {
+        synchronized (mDone) {
+            mDone.set(false);
+        }
+    }
+
+    /**
+     * Synchronously waits for completion.
+     */
+    public void waitForCompletion() {
+        synchronized (mDone) {
+            while (mDone.get() == false) {
+                try {
+                    mDone.wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+    }
+
+    @Override
+    public void packageDeleted(String packageName, int returnCode) throws RemoteException {
+        synchronized (mDone) {
+            mDone.set(true);
+            mDone.notifyAll();
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/RestoreEngine.java b/services/backup/java/com/android/server/backup/restore/RestoreEngine.java
new file mode 100644
index 0000000..b2fdbb8
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/RestoreEngine.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.restore;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Restore infrastructure.
+ */
+public abstract class RestoreEngine {
+
+    private static final String TAG = "RestoreEngine";
+
+    public static final int SUCCESS = 0;
+    public static final int TARGET_FAILURE = -2;
+    public static final int TRANSPORT_FAILURE = -3;
+
+    private AtomicBoolean mRunning = new AtomicBoolean(false);
+    private AtomicInteger mResult = new AtomicInteger(SUCCESS);
+
+    public boolean isRunning() {
+        return mRunning.get();
+    }
+
+    public void setRunning(boolean stillRunning) {
+        synchronized (mRunning) {
+            mRunning.set(stillRunning);
+            mRunning.notifyAll();
+        }
+    }
+
+    public int waitForResult() {
+        synchronized (mRunning) {
+            while (isRunning()) {
+                try {
+                    mRunning.wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+        return getResult();
+    }
+
+    public int getResult() {
+        return mResult.get();
+    }
+
+    public void setResult(int result) {
+        mResult.set(result);
+    }
+
+    // TODO: abstract restore state and APIs
+}
diff --git a/services/backup/java/com/android/server/backup/restore/RestoreFileRunnable.java b/services/backup/java/com/android/server/backup/restore/RestoreFileRunnable.java
new file mode 100644
index 0000000..6c9a222
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/RestoreFileRunnable.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.restore;
+
+import android.app.IBackupAgent;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+
+import com.android.server.backup.FileMetadata;
+import com.android.server.backup.RefactoredBackupManagerService;
+
+import java.io.IOException;
+
+/**
+ * Runner that can be placed in a separate thread to do in-process invocations of the full restore
+ * API asynchronously. Used by adb restore.
+ */
+class RestoreFileRunnable implements Runnable {
+
+    private final IBackupAgent mAgent;
+    private final FileMetadata mInfo;
+    private final ParcelFileDescriptor mSocket;
+    private final int mToken;
+    private final RefactoredBackupManagerService mBackupManagerService;
+
+    RestoreFileRunnable(RefactoredBackupManagerService backupManagerService, IBackupAgent agent,
+            FileMetadata info, ParcelFileDescriptor socket, int token) throws IOException {
+        mAgent = agent;
+        mInfo = info;
+        mToken = token;
+
+        // This class is used strictly for process-local binder invocations.  The
+        // semantics of ParcelFileDescriptor differ in this case; in particular, we
+        // do not automatically get a 'dup'ed descriptor that we can can continue
+        // to use asynchronously from the caller.  So, we make sure to dup it ourselves
+        // before proceeding to do the restore.
+        mSocket = ParcelFileDescriptor.dup(socket.getFileDescriptor());
+        this.mBackupManagerService = backupManagerService;
+    }
+
+    @Override
+    public void run() {
+        try {
+            mAgent.doRestoreFile(mSocket, mInfo.size, mInfo.type,
+                    mInfo.domain, mInfo.path, mInfo.mode, mInfo.mtime,
+                    mToken, mBackupManagerService.getBackupManagerBinder());
+        } catch (RemoteException e) {
+            // never happens; this is used strictly for local binder calls
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/RestoreInstallObserver.java b/services/backup/java/com/android/server/backup/restore/RestoreInstallObserver.java
new file mode 100644
index 0000000..3d506f1
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/RestoreInstallObserver.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.restore;
+
+import android.app.PackageInstallObserver;
+import android.os.Bundle;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Synchronous implementation of PackageInstallObserver.
+ *
+ * Allows the caller to synchronously wait for package install event.
+ */
+public class RestoreInstallObserver extends PackageInstallObserver {
+
+    @GuardedBy("mDone")
+    private final AtomicBoolean mDone = new AtomicBoolean();
+
+    private String mPackageName;
+    private int mResult;
+
+    public RestoreInstallObserver() {
+    }
+
+    /**
+     * Resets the observer to prepare for another installation.
+     */
+    public void reset() {
+        synchronized (mDone) {
+            mDone.set(false);
+        }
+    }
+
+    /**
+     * Synchronously waits for completion.
+     */
+    public void waitForCompletion() {
+        synchronized (mDone) {
+            while (mDone.get() == false) {
+                try {
+                    mDone.wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns result code.
+     */
+    public int getResult() {
+        return mResult;
+    }
+
+    /**
+     * Returns installed package name.
+     */
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    @Override
+    public void onPackageInstalled(String packageName, int returnCode,
+            String msg, Bundle extras) {
+        synchronized (mDone) {
+            mResult = returnCode;
+            mPackageName = packageName;
+            mDone.set(true);
+            mDone.notifyAll();
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/RestorePolicy.java b/services/backup/java/com/android/server/backup/restore/RestorePolicy.java
new file mode 100644
index 0000000..db25472
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/RestorePolicy.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.restore;
+
+/**
+ * Full restore from a file/socket.
+ */
+public enum RestorePolicy {
+    IGNORE,
+    ACCEPT,
+    ACCEPT_IF_APK
+}
diff --git a/services/backup/java/com/android/server/backup/restore/UnifiedRestoreState.java b/services/backup/java/com/android/server/backup/restore/UnifiedRestoreState.java
new file mode 100644
index 0000000..f5bff5e
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/UnifiedRestoreState.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.restore;
+
+/**
+ * States of the unified-restore state machine.
+ */
+public enum UnifiedRestoreState {
+    INITIAL,
+    RUNNING_QUEUE,
+    RESTORE_KEYVALUE,
+    RESTORE_FULL,
+    RESTORE_FINISHED,
+    FINAL
+}
diff --git a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
new file mode 100644
index 0000000..c033d98
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.Signature;
+import android.os.Process;
+import android.util.Slog;
+
+/**
+ * Utility methods wrapping operations on ApplicationInfo and PackageInfo.
+ */
+public class AppBackupUtils {
+    /**
+     * Returns whether app is eligible for backup.
+     *
+     * High level policy: apps are generally ineligible for backup if certain conditions apply. The
+     * conditions are:
+     *
+     * <ol>
+     *     <li>their manifest states android:allowBackup="false"
+     *     <li>they run as a system-level uid but do not supply their own backup agent
+     *     <li>it is the special shared-storage backup package used for 'adb backup'
+     * </ol>
+     */
+    public static boolean appIsEligibleForBackup(ApplicationInfo app) {
+        // 1. their manifest states android:allowBackup="false"
+        if ((app.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) {
+            return false;
+        }
+
+        // 2. they run as a system-level uid but do not supply their own backup agent
+        if ((app.uid < Process.FIRST_APPLICATION_UID) && (app.backupAgentName == null)) {
+            return false;
+        }
+
+        // 3. it is the special shared-storage backup package used for 'adb backup'
+        if (app.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Checks if the app is in a stopped state, that means it won't receive broadcasts.
+     */
+    public static boolean appIsStopped(ApplicationInfo app) {
+        return ((app.flags & ApplicationInfo.FLAG_STOPPED) != 0);
+    }
+
+    /**
+     * Returns whether the app can get full backup. Does *not* check overall backup eligibility
+     * policy!
+     */
+    public static boolean appGetsFullBackup(PackageInfo pkg) {
+        if (pkg.applicationInfo.backupAgentName != null) {
+            // If it has an agent, it gets full backups only if it says so
+            return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FULL_BACKUP_ONLY) != 0;
+        }
+
+        // No agent or fullBackupOnly="true" means we do indeed perform full-data backups for it
+        return true;
+    }
+
+    /**
+     * Returns whether the app is only capable of doing key/value. We say it's not if it allows full
+     * backup, and it is otherwise.
+     */
+    public static boolean appIsKeyValueOnly(PackageInfo pkg) {
+        return !appGetsFullBackup(pkg);
+    }
+
+    /**
+     * Old style: directly match the stored vs on device signature blocks.
+     */
+    // TODO(b/37977154): Resolve questionable policies.
+    public static boolean signaturesMatch(Signature[] storedSigs, PackageInfo target) {
+        if (target == null) {
+            return false;
+        }
+
+        // If the target resides on the system partition, we allow it to restore
+        // data from the like-named package in a restore set even if the signatures
+        // do not match.  (Unlike general applications, those flashed to the system
+        // partition will be signed with the device's platform certificate, so on
+        // different phones the same system app will have different signatures.)
+        if ((target.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "System app " + target.packageName + " - skipping sig check");
+            }
+            return true;
+        }
+
+        // Allow unsigned apps, but not signed on one device and unsigned on the other
+        // TODO(b/37977154): is this the right policy?
+        Signature[] deviceSigs = target.signatures;
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "signaturesMatch(): stored=" + storedSigs + " device=" + deviceSigs);
+        }
+        if ((storedSigs == null || storedSigs.length == 0)
+                && (deviceSigs == null || deviceSigs.length == 0)) {
+            return true;
+        }
+        // TODO(b/37977154): This allows empty stored signature, is this right?
+        if (storedSigs == null || deviceSigs == null) {
+            return false;
+        }
+
+        // TODO(b/37977154): this demands that every stored signature match one
+        // that is present on device, and does not demand the converse.
+        // Is this this right policy?
+        int nStored = storedSigs.length;
+        int nDevice = deviceSigs.length;
+
+        for (int i = 0; i < nStored; i++) {
+            boolean match = false;
+            for (int j = 0; j < nDevice; j++) {
+                if (storedSigs[i].equals(deviceSigs[j])) {
+                    match = true;
+                    break;
+                }
+            }
+            if (!match) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
new file mode 100644
index 0000000..734fa1d
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.IBackupManagerMonitor;
+import android.content.pm.PackageInfo;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Slog;
+
+/**
+ * Utility methods to communicate with BackupManagerMonitor.
+ */
+public class BackupManagerMonitorUtils {
+    /**
+     * Notifies monitor about the event.
+     *
+     * Calls {@link IBackupManagerMonitor#onEvent(Bundle)} with a bundle representing current event.
+     *
+     * @param monitor - implementation of {@link IBackupManagerMonitor} to notify.
+     * @param id - event id.
+     * @param pkg - package event is related to.
+     * @param category - event category.
+     * @param extras - additional event data.
+     * @return <code>monitor</code> if call succeeded and <code>null</code> otherwise.
+     */
+    public static IBackupManagerMonitor monitorEvent(IBackupManagerMonitor monitor, int id,
+            PackageInfo pkg, int category, Bundle extras) {
+        if (monitor != null) {
+            try {
+                Bundle bundle = new Bundle();
+                bundle.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID, id);
+                bundle.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY, category);
+                if (pkg != null) {
+                    bundle.putString(EXTRA_LOG_EVENT_PACKAGE_NAME,
+                            pkg.packageName);
+                    bundle.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_VERSION,
+                            pkg.versionCode);
+                }
+                if (extras != null) {
+                    bundle.putAll(extras);
+                }
+                monitor.onEvent(bundle);
+                return monitor;
+            } catch (RemoteException e) {
+                if (DEBUG) {
+                    Slog.w(TAG, "backup manager monitor went away");
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Adds given key-value pair in the bundle and returns the bundle. If bundle was null it will
+     * be created.
+     *
+     * @param extras - bundle where to add key-value to, if null a new bundle will be created.
+     * @param key - key.
+     * @param value - value.
+     * @return extras if it was not null and new bundle otherwise.
+     */
+    public static Bundle putMonitoringExtra(Bundle extras, String key, String value) {
+        if (extras == null) {
+            extras = new Bundle();
+        }
+        extras.putString(key, value);
+        return extras;
+    }
+
+    /**
+     * Adds given key-value pair in the bundle and returns the bundle. If bundle was null it will
+     * be created.
+     *
+     * @param extras - bundle where to add key-value to, if null a new bundle will be created.
+     * @param key - key.
+     * @param value - value.
+     * @return extras if it was not null and new bundle otherwise.
+     */
+    public static Bundle putMonitoringExtra(Bundle extras, String key, long value) {
+        if (extras == null) {
+            extras = new Bundle();
+        }
+        extras.putLong(key, value);
+        return extras;
+    }
+
+    /**
+     * Adds given key-value pair in the bundle and returns the bundle. If bundle was null it will
+     * be created.
+     *
+     * @param extras - bundle where to add key-value to, if null a new bundle will be created.
+     * @param key - key.
+     * @param value - value.
+     * @return extras if it was not null and new bundle otherwise.
+     */
+    public static Bundle putMonitoringExtra(Bundle extras, String key, boolean value) {
+        if (extras == null) {
+            extras = new Bundle();
+        }
+        extras.putBoolean(key, value);
+        return extras;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/BackupObserverUtils.java b/services/backup/java/com/android/server/backup/utils/BackupObserverUtils.java
new file mode 100644
index 0000000..3be1e33
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/BackupObserverUtils.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.backup.BackupProgress;
+import android.app.backup.IBackupObserver;
+import android.os.RemoteException;
+import android.util.Slog;
+
+/**
+ * Utility methods to communicate with BackupObserver.
+ */
+public class BackupObserverUtils {
+    /**
+     * Wraps {@link IBackupObserver#onUpdate(String, BackupProgress)} to handle RemoteException,
+     * so that the caller doesn't have to.
+     */
+    public static void sendBackupOnUpdate(IBackupObserver observer, String packageName,
+            BackupProgress progress) {
+        if (observer != null) {
+            try {
+                observer.onUpdate(packageName, progress);
+            } catch (RemoteException e) {
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup observer went away: onUpdate");
+                }
+            }
+        }
+    }
+
+    /**
+     * Wraps {@link IBackupObserver#onResult(String, int)} to handle RemoteException, so that the
+     * caller doesn't have to.
+     */
+    public static void sendBackupOnPackageResult(IBackupObserver observer, String packageName,
+            int status) {
+        if (observer != null) {
+            try {
+                observer.onResult(packageName, status);
+            } catch (RemoteException e) {
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup observer went away: onResult");
+                }
+            }
+        }
+    }
+
+    /**
+     * Wraps {@link IBackupObserver#backupFinished(int)} to handle RemoteException, so that the
+     * caller doesn't have to.
+     */
+    public static void sendBackupFinished(IBackupObserver observer, int status) {
+        if (observer != null) {
+            try {
+                observer.backupFinished(status);
+            } catch (RemoteException e) {
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup observer went away: backupFinished");
+                }
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/BytesReadListener.java b/services/backup/java/com/android/server/backup/utils/BytesReadListener.java
new file mode 100644
index 0000000..34d85ff
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/BytesReadListener.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+/**
+ * Listener for bytes reading.
+ */
+public interface BytesReadListener {
+    /**
+     * Will be called on each read operation.
+     * @param bytesRead - number of bytes read with the most recent read operation.
+     */
+    void onBytesRead(long bytesRead);
+}
diff --git a/services/backup/java/com/android/server/backup/utils/FullBackupRestoreObserverUtils.java b/services/backup/java/com/android/server/backup/utils/FullBackupRestoreObserverUtils.java
new file mode 100644
index 0000000..089109e
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/FullBackupRestoreObserverUtils.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.backup.IFullBackupRestoreObserver;
+import android.os.RemoteException;
+import android.util.Slog;
+
+/**
+ * Utility methods to communicate with FullBackupRestoreObserver.
+ */
+public class FullBackupRestoreObserverUtils {
+    /**
+     * Wraps {@link IFullBackupRestoreObserver#onStartRestore()} to handle RemoteException, so that
+     * the caller doesn't have to.
+     *
+     * @param observer - IFullBackupRestoreObserver to communicate with.
+     * @return observer if the call worked and null if there was a communication problem.
+     */
+    public static IFullBackupRestoreObserver sendStartRestore(IFullBackupRestoreObserver observer) {
+        if (observer != null) {
+            try {
+                observer.onStartRestore();
+            } catch (RemoteException e) {
+                Slog.w(TAG, "full restore observer went away: startRestore");
+                observer = null;
+            }
+        }
+        return observer;
+    }
+
+    /**
+     * Wraps {@link IFullBackupRestoreObserver#onRestorePackage(String)} to handle RemoteException,
+     * so that the caller doesn't have to.
+     *
+     * @param observer - IFullBackupRestoreObserver to communicate with.
+     * @param name - package name.
+     * @return observer if the call worked and null if there was a communication problem.
+     */
+    public static IFullBackupRestoreObserver sendOnRestorePackage(
+            IFullBackupRestoreObserver observer, String name) {
+        if (observer != null) {
+            try {
+                // TODO: use a more user-friendly name string
+                observer.onRestorePackage(name);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "full restore observer went away: restorePackage");
+                observer = null;
+            }
+        }
+        return observer;
+    }
+
+    /**
+     * Wraps {@link IFullBackupRestoreObserver#onEndRestore()} ()} to handle RemoteException, so
+     * that the caller doesn't have to.
+     *
+     * @param observer - IFullBackupRestoreObserver to communicate with.
+     * @return observer if the call worked and null if there was a communication problem.
+     */
+    public static IFullBackupRestoreObserver sendEndRestore(IFullBackupRestoreObserver observer) {
+        if (observer != null) {
+            try {
+                observer.onEndRestore();
+            } catch (RemoteException e) {
+                Slog.w(TAG, "full restore observer went away: endRestore");
+                observer = null;
+            }
+        }
+        return observer;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java b/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
new file mode 100644
index 0000000..b3e20dc
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
+import android.os.Build;
+import android.os.ParcelFileDescriptor;
+import android.util.Slog;
+import android.util.StringBuilderPrinter;
+
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Low-level utility methods for full backup.
+ */
+public class FullBackupUtils {
+    /**
+     * Reads data from pipe and writes it to the stream in chunks of up to 32KB.
+     *
+     * @param inPipe - pipe to read the data from.
+     * @param out - stream to write the data to.
+     * @throws IOException - in case of an error.
+     */
+    public static void routeSocketDataToOutput(ParcelFileDescriptor inPipe, OutputStream out)
+            throws IOException {
+        // We do not take close() responsibility for the pipe FD
+        FileInputStream raw = new FileInputStream(inPipe.getFileDescriptor());
+        DataInputStream in = new DataInputStream(raw);
+
+        byte[] buffer = new byte[32 * 1024];
+        int chunkTotal;
+        while ((chunkTotal = in.readInt()) > 0) {
+            while (chunkTotal > 0) {
+                int toRead = (chunkTotal > buffer.length) ? buffer.length : chunkTotal;
+                int nRead = in.read(buffer, 0, toRead);
+                if (nRead < 0) {
+                    Slog.e(TAG, "Unexpectedly reached end of file while reading data");
+                    throw new EOFException();
+                }
+                out.write(buffer, 0, nRead);
+                chunkTotal -= nRead;
+            }
+        }
+    }
+
+    /**
+     * Writes app manifest to the given manifest file.
+     *
+     * @param pkg - app package, which manifest to write.
+     * @param packageManager - {@link PackageManager} instance.
+     * @param manifestFile - target manifest file.
+     * @param withApk - whether include apk or not.
+     * @param withWidgets - whether to write widgets data.
+     * @throws IOException - in case of an error.
+     */
+    // TODO: withWidgets is not used, decide whether it is needed.
+    public static void writeAppManifest(PackageInfo pkg, PackageManager packageManager,
+            File manifestFile, boolean withApk, boolean withWidgets) throws IOException {
+        // Manifest format. All data are strings ending in LF:
+        //     BACKUP_MANIFEST_VERSION, currently 1
+        //
+        // Version 1:
+        //     package name
+        //     package's versionCode
+        //     platform versionCode
+        //     getInstallerPackageName() for this package (maybe empty)
+        //     boolean: "1" if archive includes .apk; any other string means not
+        //     number of signatures == N
+        // N*:    signature byte array in ascii format per Signature.toCharsString()
+        StringBuilder builder = new StringBuilder(4096);
+        StringBuilderPrinter printer = new StringBuilderPrinter(builder);
+
+        printer.println(Integer.toString(BACKUP_MANIFEST_VERSION));
+        printer.println(pkg.packageName);
+        printer.println(Integer.toString(pkg.versionCode));
+        printer.println(Integer.toString(Build.VERSION.SDK_INT));
+
+        String installerName = packageManager.getInstallerPackageName(pkg.packageName);
+        printer.println((installerName != null) ? installerName : "");
+
+        printer.println(withApk ? "1" : "0");
+        if (pkg.signatures == null) {
+            printer.println("0");
+        } else {
+            printer.println(Integer.toString(pkg.signatures.length));
+            for (Signature sig : pkg.signatures) {
+                printer.println(sig.toCharsString());
+            }
+        }
+
+        FileOutputStream outstream = new FileOutputStream(manifestFile);
+        outstream.write(builder.toString().getBytes());
+        outstream.close();
+
+        // We want the manifest block in the archive stream to be idempotent:
+        // each time we generate a backup stream for the app, we want the manifest
+        // block to be identical.  The underlying tar mechanism sees it as a file,
+        // though, and will propagate its mtime, causing the tar header to vary.
+        // Avoid this problem by pinning the mtime to zero.
+        manifestFile.setLastModified(0);
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/PasswordUtils.java b/services/backup/java/com/android/server/backup/utils/PasswordUtils.java
new file mode 100644
index 0000000..12fc927
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/PasswordUtils.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.util.Slog;
+
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+/**
+ * Passwords related utility methods.
+ */
+public class PasswordUtils {
+    // Configuration of PBKDF2 that we use for generating pw hashes and intermediate keys
+    public static final int PBKDF2_HASH_ROUNDS = 10000;
+    private static final int PBKDF2_KEY_SIZE = 256;     // bits
+    public static final int PBKDF2_SALT_SIZE = 512;    // bits
+    public static final String ENCRYPTION_ALGORITHM_NAME = "AES-256";
+
+    /**
+     * Creates {@link SecretKey} instance from given parameters.
+     *
+     * @param algorithm - key generation algorithm.
+     * @param pw - password.
+     * @param salt - salt.
+     * @param rounds - number of rounds to run in key generation.
+     * @return {@link SecretKey} instance or null in case of an error.
+     */
+    public static SecretKey buildPasswordKey(String algorithm, String pw, byte[] salt, int rounds) {
+        return buildCharArrayKey(algorithm, pw.toCharArray(), salt, rounds);
+    }
+
+    /**
+     * Generates {@link SecretKey} instance from given parameters and returns it's hex
+     * representation.
+     *
+     * @param algorithm - key generation algorithm.
+     * @param pw - password.
+     * @param salt - salt.
+     * @param rounds - number of rounds to run in key generation.
+     * @return Hex representation of the generated key, or null if generation failed.
+     */
+    public static String buildPasswordHash(String algorithm, String pw, byte[] salt, int rounds) {
+        SecretKey key = buildPasswordKey(algorithm, pw, salt, rounds);
+        if (key != null) {
+            return byteArrayToHex(key.getEncoded());
+        }
+        return null;
+    }
+
+    /**
+     * Creates hex string representation of the byte array.
+     */
+    public static String byteArrayToHex(byte[] data) {
+        StringBuilder buf = new StringBuilder(data.length * 2);
+        for (int i = 0; i < data.length; i++) {
+            buf.append(Byte.toHexString(data[i], true));
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Creates byte array from it's hex string representation.
+     */
+    public static byte[] hexToByteArray(String digits) {
+        final int bytes = digits.length() / 2;
+        if (2 * bytes != digits.length()) {
+            throw new IllegalArgumentException("Hex string must have an even number of digits");
+        }
+
+        byte[] result = new byte[bytes];
+        for (int i = 0; i < digits.length(); i += 2) {
+            result[i / 2] = (byte) Integer.parseInt(digits.substring(i, i + 2), 16);
+        }
+        return result;
+    }
+
+    /**
+     * Generates {@link SecretKey} instance from given parameters and returns it's checksum.
+     *
+     * Current implementation returns the key in its primary encoding format.
+     *
+     * @param algorithm - key generation algorithm.
+     * @param pwBytes - password.
+     * @param salt - salt.
+     * @param rounds - number of rounds to run in key generation.
+     * @return Hex representation of the generated key, or null if generation failed.
+     */
+    public static byte[] makeKeyChecksum(String algorithm, byte[] pwBytes, byte[] salt,
+            int rounds) {
+        char[] mkAsChar = new char[pwBytes.length];
+        for (int i = 0; i < pwBytes.length; i++) {
+            mkAsChar[i] = (char) pwBytes[i];
+        }
+
+        Key checksum = buildCharArrayKey(algorithm, mkAsChar, salt, rounds);
+        return checksum.getEncoded();
+    }
+
+    private static SecretKey buildCharArrayKey(String algorithm, char[] pwArray, byte[] salt,
+            int rounds) {
+        try {
+            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
+            KeySpec
+                    ks = new PBEKeySpec(pwArray, salt, rounds, PBKDF2_KEY_SIZE);
+            return keyFactory.generateSecret(ks);
+        } catch (InvalidKeySpecException e) {
+            Slog.e(TAG, "Invalid key spec for PBKDF2!");
+        } catch (NoSuchAlgorithmException e) {
+            Slog.e(TAG, "PBKDF2 unavailable!");
+        }
+        return null;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/RestoreUtils.java b/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
new file mode 100644
index 0000000..ee4201e
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
+import android.net.Uri;
+import android.os.Process;
+import android.util.Slog;
+
+import com.android.server.backup.FileMetadata;
+import com.android.server.backup.restore.RestoreDeleteObserver;
+import com.android.server.backup.restore.RestoreInstallObserver;
+import com.android.server.backup.restore.RestorePolicy;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+
+/**
+ * Utility methods used by {@link com.android.server.backup.restore.PerformAdbRestoreTask} and
+ * {@link com.android.server.backup.restore.FullRestoreEngine}.
+ */
+public class RestoreUtils {
+    /**
+     * Reads apk contents from input stream and installs the apk.
+     *
+     * @param instream - input stream to read apk data from.
+     * @param packageManager - {@link PackageManager} instance.
+     * @param installObserver - {@link RestoreInstallObserver} instance.
+     * @param deleteObserver - {@link RestoreDeleteObserver} instance.
+     * @param manifestSignatures - manifest signatures.
+     * @param packagePolicies - package policies.
+     * @param info - backup file info.
+     * @param installerPackage - installer package.
+     * @param bytesReadListener - listener to be called for counting bytes read.
+     * @param dataDir - directory where to create apk file.
+     * @return true if apk was successfully read and installed and false otherwise.
+     */
+    // TODO: Refactor to get rid of unneeded params.
+    public static boolean installApk(InputStream instream, PackageManager packageManager,
+            RestoreInstallObserver installObserver, RestoreDeleteObserver deleteObserver,
+            HashMap<String, Signature[]> manifestSignatures,
+            HashMap<String, RestorePolicy> packagePolicies,
+            FileMetadata info,
+            String installerPackage, BytesReadListener bytesReadListener,
+            File dataDir) {
+        boolean okay = true;
+
+        if (DEBUG) {
+            Slog.d(TAG, "Installing from backup: " + info.packageName);
+        }
+
+        // The file content is an .apk file.  Copy it out to a staging location and
+        // attempt to install it.
+        File apkFile = new File(dataDir, info.packageName);
+        try {
+            FileOutputStream apkStream = new FileOutputStream(apkFile);
+            byte[] buffer = new byte[32 * 1024];
+            long size = info.size;
+            while (size > 0) {
+                long toRead = (buffer.length < size) ? buffer.length : size;
+                int didRead = instream.read(buffer, 0, (int) toRead);
+                if (didRead >= 0) {
+                    bytesReadListener.onBytesRead(didRead);
+                }
+                apkStream.write(buffer, 0, didRead);
+                size -= didRead;
+            }
+            apkStream.close();
+
+            // make sure the installer can read it
+            apkFile.setReadable(true, false);
+
+            // Now install it
+            Uri packageUri = Uri.fromFile(apkFile);
+            installObserver.reset();
+            // TODO: PackageManager.installPackage() is deprecated, refactor.
+            packageManager.installPackage(packageUri, installObserver,
+                    PackageManager.INSTALL_REPLACE_EXISTING | PackageManager.INSTALL_FROM_ADB,
+                    installerPackage);
+            installObserver.waitForCompletion();
+
+            if (installObserver.getResult() != PackageManager.INSTALL_SUCCEEDED) {
+                // The only time we continue to accept install of data even if the
+                // apk install failed is if we had already determined that we could
+                // accept the data regardless.
+                if (packagePolicies.get(info.packageName) != RestorePolicy.ACCEPT) {
+                    okay = false;
+                }
+            } else {
+                // Okay, the install succeeded.  Make sure it was the right app.
+                boolean uninstall = false;
+                if (!installObserver.getPackageName().equals(info.packageName)) {
+                    Slog.w(TAG, "Restore stream claimed to include apk for "
+                            + info.packageName + " but apk was really "
+                            + installObserver.getPackageName());
+                    // delete the package we just put in place; it might be fraudulent
+                    okay = false;
+                    uninstall = true;
+                } else {
+                    try {
+                        PackageInfo pkg = packageManager.getPackageInfo(
+                                info.packageName,
+                                PackageManager.GET_SIGNATURES);
+                        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP)
+                                == 0) {
+                            Slog.w(TAG, "Restore stream contains apk of package "
+                                    + info.packageName
+                                    + " but it disallows backup/restore");
+                            okay = false;
+                        } else {
+                            // So far so good -- do the signatures match the manifest?
+                            Signature[] sigs = manifestSignatures.get(info.packageName);
+                            if (AppBackupUtils.signaturesMatch(sigs, pkg)) {
+                                // If this is a system-uid app without a declared backup agent,
+                                // don't restore any of the file data.
+                                if ((pkg.applicationInfo.uid < Process.FIRST_APPLICATION_UID)
+                                        && (pkg.applicationInfo.backupAgentName == null)) {
+                                    Slog.w(TAG, "Installed app " + info.packageName
+                                            + " has restricted uid and no agent");
+                                    okay = false;
+                                }
+                            } else {
+                                Slog.w(TAG, "Installed app " + info.packageName
+                                        + " signatures do not match restore manifest");
+                                okay = false;
+                                uninstall = true;
+                            }
+                        }
+                    } catch (PackageManager.NameNotFoundException e) {
+                        Slog.w(TAG, "Install of package " + info.packageName
+                                + " succeeded but now not found");
+                        okay = false;
+                    }
+                }
+
+                // If we're not okay at this point, we need to delete the package
+                // that we just installed.
+                if (uninstall) {
+                    deleteObserver.reset();
+                    packageManager.deletePackage(
+                            installObserver.getPackageName(),
+                            deleteObserver, 0);
+                    deleteObserver.waitForCompletion();
+                }
+            }
+        } catch (IOException e) {
+            Slog.e(TAG, "Unable to transcribe restored apk for install");
+            okay = false;
+        } finally {
+            apkFile.delete();
+        }
+
+        return okay;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
new file mode 100644
index 0000000..2910ba2
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
@@ -0,0 +1,798 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_VERSION;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_MANIFEST_PACKAGE_NAME;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_OLD_VERSION;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_POLICY_ALLOW_APKS;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_APK_NOT_INSTALLED;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_EXPECTED_DIFFERENT_PACKAGE;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_MISSING_SIGNATURE;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_RESTORE_ANY_VERSION;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_SYSTEM_APP_NO_AGENT;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSIONS_MATCH;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER;
+
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_WIDGET_METADATA_TOKEN;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.backup.BackupAgent;
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.FullBackup;
+import android.app.backup.IBackupManagerMonitor;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
+import android.os.Bundle;
+import android.os.Process;
+import android.util.Slog;
+
+import com.android.server.backup.FileMetadata;
+import com.android.server.backup.restore.RestorePolicy;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Utility methods to read backup tar file.
+ */
+public class TarBackupReader {
+    private static final int TAR_HEADER_OFFSET_TYPE_CHAR = 156;
+    private static final int TAR_HEADER_LENGTH_PATH = 100;
+    private static final int TAR_HEADER_OFFSET_PATH = 0;
+    private static final int TAR_HEADER_LENGTH_PATH_PREFIX = 155;
+    private static final int TAR_HEADER_OFFSET_PATH_PREFIX = 345;
+    private static final int TAR_HEADER_LENGTH_MODE = 8;
+    private static final int TAR_HEADER_OFFSET_MODE = 100;
+    private static final int TAR_HEADER_LENGTH_MODTIME = 12;
+    private static final int TAR_HEADER_OFFSET_MODTIME = 136;
+    private static final int TAR_HEADER_LENGTH_FILESIZE = 12;
+    private static final int TAR_HEADER_OFFSET_FILESIZE = 124;
+    private static final int TAR_HEADER_LONG_RADIX = 8;
+
+    private final InputStream mInputStream;
+    private final BytesReadListener mBytesReadListener;
+
+    private IBackupManagerMonitor mMonitor;
+
+    // Widget blob to be restored out-of-band.
+    private byte[] mWidgetData = null;
+
+    public TarBackupReader(InputStream inputStream, BytesReadListener bytesReadListener,
+            IBackupManagerMonitor monitor) {
+        mInputStream = inputStream;
+        mBytesReadListener = bytesReadListener;
+        mMonitor = monitor;
+    }
+
+    /**
+     * Consumes a tar file header block [sequence] and accumulates the relevant metadata.
+     */
+    public FileMetadata readTarHeaders() throws IOException {
+        byte[] block = new byte[512];
+        FileMetadata info = null;
+
+        boolean gotHeader = readTarHeader(block);
+        if (gotHeader) {
+            try {
+                // okay, presume we're okay, and extract the various metadata
+                info = new FileMetadata();
+                info.size = extractRadix(block,
+                        TAR_HEADER_OFFSET_FILESIZE,
+                        TAR_HEADER_LENGTH_FILESIZE,
+                        TAR_HEADER_LONG_RADIX);
+                info.mtime = extractRadix(block,
+                        TAR_HEADER_OFFSET_MODTIME,
+                        TAR_HEADER_LENGTH_MODTIME,
+                        TAR_HEADER_LONG_RADIX);
+                info.mode = extractRadix(block,
+                        TAR_HEADER_OFFSET_MODE,
+                        TAR_HEADER_LENGTH_MODE,
+                        TAR_HEADER_LONG_RADIX);
+
+                info.path = extractString(block,
+                        TAR_HEADER_OFFSET_PATH_PREFIX,
+                        TAR_HEADER_LENGTH_PATH_PREFIX);
+                String path = extractString(block,
+                        TAR_HEADER_OFFSET_PATH,
+                        TAR_HEADER_LENGTH_PATH);
+                if (path.length() > 0) {
+                    if (info.path.length() > 0) {
+                        info.path += '/';
+                    }
+                    info.path += path;
+                }
+
+                // tar link indicator field: 1 byte at offset 156 in the header.
+                int typeChar = block[TAR_HEADER_OFFSET_TYPE_CHAR];
+                if (typeChar == 'x') {
+                    // pax extended header, so we need to read that
+                    gotHeader = readPaxExtendedHeader(info);
+                    if (gotHeader) {
+                        // and after a pax extended header comes another real header -- read
+                        // that to find the real file type
+                        gotHeader = readTarHeader(block);
+                    }
+                    if (!gotHeader) {
+                        throw new IOException("Bad or missing pax header");
+                    }
+
+                    typeChar = block[TAR_HEADER_OFFSET_TYPE_CHAR];
+                }
+
+                switch (typeChar) {
+                    case '0':
+                        info.type = BackupAgent.TYPE_FILE;
+                        break;
+                    case '5': {
+                        info.type = BackupAgent.TYPE_DIRECTORY;
+                        if (info.size != 0) {
+                            Slog.w(TAG, "Directory entry with nonzero size in header");
+                            info.size = 0;
+                        }
+                        break;
+                    }
+                    case 0: {
+                        // presume EOF
+                        if (MORE_DEBUG) {
+                            Slog.w(TAG, "Saw type=0 in tar header block, info=" + info);
+                        }
+                        return null;
+                    }
+                    default: {
+                        Slog.e(TAG, "Unknown tar entity type: " + typeChar);
+                        throw new IOException("Unknown entity type " + typeChar);
+                    }
+                }
+
+                // Parse out the path
+                //
+                // first: apps/shared/unrecognized
+                if (FullBackup.SHARED_PREFIX.regionMatches(0,
+                        info.path, 0, FullBackup.SHARED_PREFIX.length())) {
+                    // File in shared storage.  !!! TODO: implement this.
+                    info.path = info.path.substring(FullBackup.SHARED_PREFIX.length());
+                    info.packageName = SHARED_BACKUP_AGENT_PACKAGE;
+                    info.domain = FullBackup.SHARED_STORAGE_TOKEN;
+                    if (DEBUG) {
+                        Slog.i(TAG, "File in shared storage: " + info.path);
+                    }
+                } else if (FullBackup.APPS_PREFIX.regionMatches(0,
+                        info.path, 0, FullBackup.APPS_PREFIX.length())) {
+                    // App content!  Parse out the package name and domain
+
+                    // strip the apps/ prefix
+                    info.path = info.path.substring(FullBackup.APPS_PREFIX.length());
+
+                    // extract the package name
+                    int slash = info.path.indexOf('/');
+                    if (slash < 0) {
+                        throw new IOException("Illegal semantic path in " + info.path);
+                    }
+                    info.packageName = info.path.substring(0, slash);
+                    info.path = info.path.substring(slash + 1);
+
+                    // if it's a manifest or metadata payload we're done, otherwise parse
+                    // out the domain into which the file will be restored
+                    if (!info.path.equals(BACKUP_MANIFEST_FILENAME) &&
+                            !info.path.equals(BACKUP_METADATA_FILENAME)) {
+                        slash = info.path.indexOf('/');
+                        if (slash < 0) {
+                            throw new IOException("Illegal semantic path in non-manifest "
+                                    + info.path);
+                        }
+                        info.domain = info.path.substring(0, slash);
+                        info.path = info.path.substring(slash + 1);
+                    }
+                }
+            } catch (IOException e) {
+                if (DEBUG) {
+                    Slog.e(TAG, "Parse error in header: " + e.getMessage());
+                    if (MORE_DEBUG) {
+                        hexLog(block);
+                    }
+                }
+                throw e;
+            }
+        }
+        return info;
+    }
+
+    /**
+     * Tries to read exactly the given number of bytes into a buffer at the stated offset.
+     *
+     * @param in - input stream to read bytes from..
+     * @param buffer - where to write bytes to.
+     * @param offset - offset in buffer to write bytes to.
+     * @param size - number of bytes to read.
+     * @return number of bytes actually read.
+     * @throws IOException in case of an error.
+     */
+    private static int readExactly(InputStream in, byte[] buffer, int offset, int size)
+            throws IOException {
+        if (size <= 0) {
+            throw new IllegalArgumentException("size must be > 0");
+        }
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "  ... readExactly(" + size + ") called");
+        }
+        int soFar = 0;
+        while (soFar < size) {
+            int nRead = in.read(buffer, offset + soFar, size - soFar);
+            if (nRead <= 0) {
+                if (MORE_DEBUG) {
+                    Slog.w(TAG, "- wanted exactly " + size + " but got only " + soFar);
+                }
+                break;
+            }
+            soFar += nRead;
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "   + got " + nRead + "; now wanting " + (size - soFar));
+            }
+        }
+        return soFar;
+    }
+
+    /**
+     * Reads app manifest, filling version and hasApk fields in the metadata, and returns array of
+     * signatures.
+     *
+     * @param info - file metadata.
+     * @return array of signatures or null, in case of an error.
+     * @throws IOException in case of an error.
+     */
+    public Signature[] readAppManifestAndReturnSignatures(FileMetadata info)
+            throws IOException {
+        // Fail on suspiciously large manifest files
+        if (info.size > 64 * 1024) {
+            throw new IOException("Restore manifest too big; corrupt? size=" + info.size);
+        }
+
+        byte[] buffer = new byte[(int) info.size];
+        if (MORE_DEBUG) {
+            Slog.i(TAG,
+                    "   readAppManifestAndReturnSignatures() looking for " + info.size + " bytes");
+        }
+        if (readExactly(mInputStream, buffer, 0, (int) info.size) == info.size) {
+            mBytesReadListener.onBytesRead(info.size);
+        } else {
+            throw new IOException("Unexpected EOF in manifest");
+        }
+
+        String[] str = new String[1];
+        int offset = 0;
+
+        try {
+            offset = extractLine(buffer, offset, str);
+            int version = Integer.parseInt(str[0]);
+            if (version == BACKUP_MANIFEST_VERSION) {
+                offset = extractLine(buffer, offset, str);
+                String manifestPackage = str[0];
+                // TODO: handle <original-package>
+                if (manifestPackage.equals(info.packageName)) {
+                    offset = extractLine(buffer, offset, str);
+                    info.version = Integer.parseInt(str[0]);  // app version
+                    offset = extractLine(buffer, offset, str);
+                    // This is the platform version, which we don't use, but we parse it
+                    // as a safety against corruption in the manifest.
+                    Integer.parseInt(str[0]);
+                    offset = extractLine(buffer, offset, str);
+                    info.installerPackageName = (str[0].length() > 0) ? str[0] : null;
+                    offset = extractLine(buffer, offset, str);
+                    info.hasApk = str[0].equals("1");
+                    offset = extractLine(buffer, offset, str);
+                    int numSigs = Integer.parseInt(str[0]);
+                    if (numSigs > 0) {
+                        Signature[] sigs = new Signature[numSigs];
+                        for (int i = 0; i < numSigs; i++) {
+                            offset = extractLine(buffer, offset, str);
+                            sigs[i] = new Signature(str[0]);
+                        }
+                        return sigs;
+                    } else {
+                        Slog.i(TAG, "Missing signature on backed-up package " + info.packageName);
+                        mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                                mMonitor,
+                                LOG_EVENT_ID_MISSING_SIGNATURE,
+                                null,
+                                LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                BackupManagerMonitorUtils.putMonitoringExtra(null,
+                                        EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName));
+                    }
+                } else {
+                    Slog.i(TAG, "Expected package " + info.packageName
+                            + " but restore manifest claims " + manifestPackage);
+                    Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
+                            EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName);
+                    monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
+                            monitoringExtras,
+                            EXTRA_LOG_MANIFEST_PACKAGE_NAME, manifestPackage);
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                            mMonitor,
+                            LOG_EVENT_ID_EXPECTED_DIFFERENT_PACKAGE,
+                            null,
+                            LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            monitoringExtras);
+                }
+            } else {
+                Slog.i(TAG, "Unknown restore manifest version " + version
+                        + " for package " + info.packageName);
+                Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
+                        EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName);
+                monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(monitoringExtras,
+                        EXTRA_LOG_EVENT_PACKAGE_VERSION, version);
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                        mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_UNKNOWN_VERSION,
+                        null,
+                        LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        monitoringExtras);
+
+            }
+        } catch (NumberFormatException e) {
+            Slog.w(TAG, "Corrupt restore manifest for package " + info.packageName);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                    mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_CORRUPT_MANIFEST,
+                    null,
+                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    BackupManagerMonitorUtils.putMonitoringExtra(null, EXTRA_LOG_EVENT_PACKAGE_NAME,
+                            info.packageName));
+        } catch (IllegalArgumentException e) {
+            Slog.w(TAG, e.getMessage());
+        }
+
+        return null;
+    }
+
+    /**
+     * Chooses restore policy.
+     *
+     * @param packageManager - PackageManager instance.
+     * @param allowApks - allow restore set to include apks.
+     * @param info - file metadata.
+     * @param signatures - array of signatures parsed from backup file.
+     * @return a restore policy constant.
+     */
+    public RestorePolicy chooseRestorePolicy(PackageManager packageManager,
+            boolean allowApks, FileMetadata info, Signature[] signatures) {
+        if (signatures == null) {
+            return RestorePolicy.IGNORE;
+        }
+
+        RestorePolicy policy = RestorePolicy.IGNORE;
+
+        // Okay, got the manifest info we need...
+        try {
+            PackageInfo pkgInfo = packageManager.getPackageInfo(
+                    info.packageName, PackageManager.GET_SIGNATURES);
+            // Fall through to IGNORE if the app explicitly disallows backup
+            final int flags = pkgInfo.applicationInfo.flags;
+            if ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0) {
+                // Restore system-uid-space packages only if they have
+                // defined a custom backup agent
+                if ((pkgInfo.applicationInfo.uid
+                        >= Process.FIRST_APPLICATION_UID)
+                        || (pkgInfo.applicationInfo.backupAgentName != null)) {
+                    // Verify signatures against any installed version; if they
+                    // don't match, then we fall though and ignore the data.  The
+                    // signatureMatch() method explicitly ignores the signature
+                    // check for packages installed on the system partition, because
+                    // such packages are signed with the platform cert instead of
+                    // the app developer's cert, so they're different on every
+                    // device.
+                    if (AppBackupUtils.signaturesMatch(signatures, pkgInfo)) {
+                        if ((pkgInfo.applicationInfo.flags
+                                & ApplicationInfo.FLAG_RESTORE_ANY_VERSION) != 0) {
+                            Slog.i(TAG, "Package has restoreAnyVersion; taking data");
+                            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                                    mMonitor,
+                                    LOG_EVENT_ID_RESTORE_ANY_VERSION,
+                                    pkgInfo,
+                                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                    null);
+                            policy = RestorePolicy.ACCEPT;
+                        } else if (pkgInfo.versionCode >= info.version) {
+                            Slog.i(TAG, "Sig + version match; taking data");
+                            policy = RestorePolicy.ACCEPT;
+                            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                                    mMonitor,
+                                    LOG_EVENT_ID_VERSIONS_MATCH,
+                                    pkgInfo,
+                                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                    null);
+                        } else {
+                            // The data is from a newer version of the app than
+                            // is presently installed.  That means we can only
+                            // use it if the matching apk is also supplied.
+                            if (allowApks) {
+                                Slog.i(TAG, "Data version " + info.version
+                                        + " is newer than installed "
+                                        + "version "
+                                        + pkgInfo.versionCode
+                                        + " - requiring apk");
+                                policy = RestorePolicy.ACCEPT_IF_APK;
+                            } else {
+                                Slog.i(TAG, "Data requires newer version "
+                                        + info.version + "; ignoring");
+                                mMonitor = BackupManagerMonitorUtils
+                                        .monitorEvent(mMonitor,
+                                                LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER,
+                                                pkgInfo,
+                                                LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                                BackupManagerMonitorUtils
+                                                        .putMonitoringExtra(
+                                                                null,
+                                                                EXTRA_LOG_OLD_VERSION,
+                                                                info.version));
+
+                                policy = RestorePolicy.IGNORE;
+                            }
+                        }
+                    } else {
+                        Slog.w(TAG, "Restore manifest signatures do not match "
+                                + "installed application for "
+                                + info.packageName);
+                        mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                                mMonitor,
+                                LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH,
+                                pkgInfo,
+                                LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                null);
+                    }
+                } else {
+                    Slog.w(TAG, "Package " + info.packageName
+                            + " is system level with no agent");
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                            mMonitor,
+                            LOG_EVENT_ID_SYSTEM_APP_NO_AGENT,
+                            pkgInfo,
+                            LOG_EVENT_CATEGORY_AGENT,
+                            null);
+                }
+            } else {
+                if (DEBUG) {
+                    Slog.i(TAG,
+                            "Restore manifest from " + info.packageName + " but allowBackup=false");
+                }
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                        mMonitor,
+                        LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE,
+                        pkgInfo,
+                        LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        null);
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            // Okay, the target app isn't installed.  We can process
+            // the restore properly only if the dataset provides the
+            // apk file and we can successfully install it.
+            if (allowApks) {
+                if (DEBUG) {
+                    Slog.i(TAG, "Package " + info.packageName
+                            + " not installed; requiring apk in dataset");
+                }
+                policy = RestorePolicy.ACCEPT_IF_APK;
+            } else {
+                policy = RestorePolicy.IGNORE;
+            }
+            Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
+                    null,
+                    EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName);
+            monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
+                    monitoringExtras,
+                    EXTRA_LOG_POLICY_ALLOW_APKS, allowApks);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                    mMonitor,
+                    LOG_EVENT_ID_APK_NOT_INSTALLED,
+                    null,
+                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    monitoringExtras);
+        }
+
+        if (policy == RestorePolicy.ACCEPT_IF_APK && !info.hasApk) {
+            Slog.i(TAG, "Cannot restore package " + info.packageName
+                    + " without the matching .apk");
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                    mMonitor,
+                    LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK,
+                    null,
+                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    BackupManagerMonitorUtils.putMonitoringExtra(null,
+                            EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName));
+        }
+
+        return policy;
+    }
+
+    // Given an actual file content size, consume the post-content padding mandated
+    // by the tar format.
+    public void skipTarPadding(long size) throws IOException {
+        long partial = (size + 512) % 512;
+        if (partial > 0) {
+            final int needed = 512 - (int) partial;
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Skipping tar padding: " + needed + " bytes");
+            }
+            byte[] buffer = new byte[needed];
+            if (readExactly(mInputStream, buffer, 0, needed) == needed) {
+                mBytesReadListener.onBytesRead(needed);
+            } else {
+                throw new IOException("Unexpected EOF in padding");
+            }
+        }
+    }
+
+    /**
+     * Read a widget metadata file, returning the restored blob.
+     */
+    public void readMetadata(FileMetadata info) throws IOException {
+        // Fail on suspiciously large widget dump files
+        if (info.size > 64 * 1024) {
+            throw new IOException("Metadata too big; corrupt? size=" + info.size);
+        }
+
+        byte[] buffer = new byte[(int) info.size];
+        if (readExactly(mInputStream, buffer, 0, (int) info.size) == info.size) {
+            mBytesReadListener.onBytesRead(info.size);
+        } else {
+            throw new IOException("Unexpected EOF in widget data");
+        }
+
+        String[] str = new String[1];
+        int offset = extractLine(buffer, 0, str);
+        int version = Integer.parseInt(str[0]);
+        if (version == BACKUP_MANIFEST_VERSION) {
+            offset = extractLine(buffer, offset, str);
+            final String pkg = str[0];
+            if (info.packageName.equals(pkg)) {
+                // Data checks out -- the rest of the buffer is a concatenation of
+                // binary blobs as described in the comment at writeAppWidgetData()
+                ByteArrayInputStream bin = new ByteArrayInputStream(buffer,
+                        offset, buffer.length - offset);
+                DataInputStream in = new DataInputStream(bin);
+                while (bin.available() > 0) {
+                    int token = in.readInt();
+                    int size = in.readInt();
+                    if (size > 64 * 1024) {
+                        throw new IOException("Datum " + Integer.toHexString(token)
+                                + " too big; corrupt? size=" + info.size);
+                    }
+                    switch (token) {
+                        case BACKUP_WIDGET_METADATA_TOKEN: {
+                            if (MORE_DEBUG) {
+                                Slog.i(TAG, "Got widget metadata for " + info.packageName);
+                            }
+                            mWidgetData = new byte[size];
+                            in.read(mWidgetData);
+                            break;
+                        }
+                        default: {
+                            if (DEBUG) {
+                                Slog.i(TAG, "Ignoring metadata blob " + Integer.toHexString(token)
+                                        + " for " + info.packageName);
+                            }
+                            in.skipBytes(size);
+                            break;
+                        }
+                    }
+                }
+            } else {
+                Slog.w(TAG,
+                        "Metadata mismatch: package " + info.packageName + " but widget data for "
+                                + pkg);
+
+                Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
+                        EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName);
+                monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(monitoringExtras,
+                        BackupManagerMonitor.EXTRA_LOG_WIDGET_PACKAGE_NAME, pkg);
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                        mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_WIDGET_METADATA_MISMATCH,
+                        null,
+                        LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        monitoringExtras);
+            }
+        } else {
+            Slog.w(TAG, "Unsupported metadata version " + version);
+
+            Bundle monitoringExtras = BackupManagerMonitorUtils
+                    .putMonitoringExtra(null, EXTRA_LOG_EVENT_PACKAGE_NAME,
+                            info.packageName);
+            monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(monitoringExtras,
+                    EXTRA_LOG_EVENT_PACKAGE_VERSION, version);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                    mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_WIDGET_UNKNOWN_VERSION,
+                    null,
+                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    monitoringExtras);
+        }
+    }
+
+    /**
+     * Builds a line from a byte buffer starting at 'offset'.
+     *
+     * @param buffer - where to read a line from.
+     * @param offset - offset in buffer to read a line from.
+     * @param outStr - an output parameter, the result will be put in outStr.
+     * @return the index of the next unconsumed data in the buffer.
+     * @throws IOException in case of an error.
+     */
+    private static int extractLine(byte[] buffer, int offset, String[] outStr) throws IOException {
+        final int end = buffer.length;
+        if (offset >= end) {
+            throw new IOException("Incomplete data");
+        }
+
+        int pos;
+        for (pos = offset; pos < end; pos++) {
+            byte c = buffer[pos];
+            // at LF we declare end of line, and return the next char as the
+            // starting point for the next time through
+            if (c == '\n') {
+                break;
+            }
+        }
+        outStr[0] = new String(buffer, offset, pos - offset);
+        pos++;  // may be pointing an extra byte past the end but that's okay
+        return pos;
+    }
+
+    private boolean readTarHeader(byte[] block) throws IOException {
+        final int got = readExactly(mInputStream, block, 0, 512);
+        if (got == 0) {
+            return false;     // Clean EOF
+        }
+        if (got < 512) {
+            throw new IOException("Unable to read full block header");
+        }
+        mBytesReadListener.onBytesRead(512);
+        return true;
+    }
+
+    // overwrites 'info' fields based on the pax extended header
+    private boolean readPaxExtendedHeader(FileMetadata info)
+            throws IOException {
+        // We should never see a pax extended header larger than this
+        if (info.size > 32 * 1024) {
+            Slog.w(TAG, "Suspiciously large pax header size " + info.size + " - aborting");
+            throw new IOException("Sanity failure: pax header size " + info.size);
+        }
+
+        // read whole blocks, not just the content size
+        int numBlocks = (int) ((info.size + 511) >> 9);
+        byte[] data = new byte[numBlocks * 512];
+        if (readExactly(mInputStream, data, 0, data.length) < data.length) {
+            throw new IOException("Unable to read full pax header");
+        }
+        mBytesReadListener.onBytesRead(data.length);
+
+        final int contentSize = (int) info.size;
+        int offset = 0;
+        do {
+            // extract the line at 'offset'
+            int eol = offset + 1;
+            while (eol < contentSize && data[eol] != ' ') {
+                eol++;
+            }
+            if (eol >= contentSize) {
+                // error: we just hit EOD looking for the end of the size field
+                throw new IOException("Invalid pax data");
+            }
+            // eol points to the space between the count and the key
+            int linelen = (int) extractRadix(data, offset, eol - offset, 10);
+            int key = eol + 1;  // start of key=value
+            eol = offset + linelen - 1; // trailing LF
+            int value;
+            for (value = key + 1; data[value] != '=' && value <= eol; value++) {
+                ;
+            }
+            if (value > eol) {
+                throw new IOException("Invalid pax declaration");
+            }
+
+            // pax requires that key/value strings be in UTF-8
+            String keyStr = new String(data, key, value - key, "UTF-8");
+            // -1 to strip the trailing LF
+            String valStr = new String(data, value + 1, eol - value - 1, "UTF-8");
+
+            if ("path".equals(keyStr)) {
+                info.path = valStr;
+            } else if ("size".equals(keyStr)) {
+                info.size = Long.parseLong(valStr);
+            } else {
+                if (DEBUG) {
+                    Slog.i(TAG, "Unhandled pax key: " + key);
+                }
+            }
+
+            offset += linelen;
+        } while (offset < contentSize);
+
+        return true;
+    }
+
+    private static long extractRadix(byte[] data, int offset, int maxChars, int radix)
+            throws IOException {
+        long value = 0;
+        final int end = offset + maxChars;
+        for (int i = offset; i < end; i++) {
+            final byte b = data[i];
+            // Numeric fields in tar can terminate with either NUL or SPC
+            if (b == 0 || b == ' ') {
+                break;
+            }
+            if (b < '0' || b > ('0' + radix - 1)) {
+                throw new IOException("Invalid number in header: '" + (char) b
+                        + "' for radix " + radix);
+            }
+            value = radix * value + (b - '0');
+        }
+        return value;
+    }
+
+    private static String extractString(byte[] data, int offset, int maxChars) throws IOException {
+        final int end = offset + maxChars;
+        int eos = offset;
+        // tar string fields terminate early with a NUL
+        while (eos < end && data[eos] != 0) {
+            eos++;
+        }
+        return new String(data, offset, eos - offset, "US-ASCII");
+    }
+
+    private static void hexLog(byte[] block) {
+        int offset = 0;
+        int todo = block.length;
+        StringBuilder buf = new StringBuilder(64);
+        while (todo > 0) {
+            buf.append(String.format("%04x   ", offset));
+            int numThisLine = (todo > 16) ? 16 : todo;
+            for (int i = 0; i < numThisLine; i++) {
+                buf.append(String.format("%02x ", block[offset + i]));
+            }
+            Slog.i("hexdump", buf.toString());
+            buf.setLength(0);
+            todo -= numThisLine;
+            offset += numThisLine;
+        }
+    }
+
+    public IBackupManagerMonitor getMonitor() {
+        return mMonitor;
+    }
+
+    public byte[] getWidgetData() {
+        return mWidgetData;
+    }
+}
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 4810f4f..f47b0d3 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -383,7 +383,7 @@
                                     findDeviceCallback,
                                     getServiceCallback());
                 } catch (RemoteException e) {
-                    throw new RuntimeException(e);
+                    Log.e(LOG_TAG, "Error while initiating device discovery", e);
                 }
             }
 
diff --git a/services/core/Android.mk b/services/core/Android.mk
index 7fca21f..5ec5370 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -4,7 +4,10 @@
 
 LOCAL_MODULE := services.core
 
-LOCAL_AIDL_INCLUDES := system/netd/server/binder
+LOCAL_AIDL_INCLUDES := \
+    frameworks/native/aidl/binder \
+    system/netd/server/binder
+
 
 LOCAL_SRC_FILES += \
     $(call all-java-files-under,java) \
@@ -28,9 +31,12 @@
     time_zone_distro \
     time_zone_distro_installer \
     android.hidl.base-V1.0-java \
+    android.hardware.weaver-V1.0-java \
     android.hardware.biometrics.fingerprint-V2.1-java \
+    android.hardware.oemlock-V1.0-java \
     android.hardware.tetheroffload.control-V1.0-java \
     android.hardware.vibrator-V1.0-java \
+    android.hardware.configstore-V1.0-java
 
 ifneq ($(INCREMENTAL_BUILDS),)
     LOCAL_PROGUARD_ENABLED := disabled
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index a378d02..a15992d 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -31,7 +31,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PermissionInfo;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Binder;
@@ -154,6 +158,20 @@
     long mAllowWhileIdleMinTime;
     int mNumTimeChanged;
 
+    // Bookkeeping about the identity of the "System UI" package, determined at runtime.
+
+    /**
+     * This permission must be defined by the canonical System UI package,
+     * with protection level "signature".
+     */
+    private static final String SYSTEM_UI_SELF_PERMISSION =
+            "android.permission.systemui.IDENTITY";
+
+    /**
+     * At boot we use SYSTEM_UI_SELF_PERMISSION to look up the definer's uid.
+     */
+    int mSystemUiUid;
+
     /**
      * The current set of user whitelisted apps for device idle mode, meaning these are allowed
      * to freely schedule alarms.
@@ -961,6 +979,25 @@
             }
         }
 
+        // Determine SysUI's uid
+        final PackageManager packMan = getContext().getPackageManager();
+        try {
+            PermissionInfo sysUiPerm = packMan.getPermissionInfo(SYSTEM_UI_SELF_PERMISSION, 0);
+            ApplicationInfo sysUi = packMan.getApplicationInfo(sysUiPerm.packageName, 0);
+            if ((sysUi.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
+                mSystemUiUid = sysUi.uid;
+            } else {
+                Slog.e(TAG, "SysUI permission " + SYSTEM_UI_SELF_PERMISSION
+                        + " defined by non-privileged app " + sysUi.packageName
+                        + " - ignoring");
+            }
+        } catch (NameNotFoundException e) {
+        }
+
+        if (mSystemUiUid <= 0) {
+            Slog.wtf(TAG, "SysUI package not found!");
+        }
+
         PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*alarm*");
 
@@ -1335,6 +1372,7 @@
             // This means we will allow these alarms to go off as normal even while idle, with no
             // timing restrictions.
             } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID
+                    || callingUid == mSystemUiUid
                     || Arrays.binarySearch(mDeviceIdleUserWhitelist,
                             UserHandle.getAppId(callingUid)) >= 0)) {
                 flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 1a5ec61..c8e6e2e 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -2445,6 +2445,28 @@
         }
     }
 
+    @Override
+    public boolean isOperationActive(int code, int uid, String packageName) {
+        verifyIncomingUid(uid);
+        verifyIncomingOp(code);
+        String resolvedPackageName = resolvePackageName(uid, packageName);
+        if (resolvedPackageName == null) {
+            return false;
+        }
+        synchronized (this) {
+            for (int i = mClients.size() - 1; i >= 0; i--) {
+                final ClientState client = mClients.valueAt(i);
+                if (client.mStartedOps == null) continue;
+
+                for (int j = client.mStartedOps.size() - 1; j >= 0; j--) {
+                    final Op op = client.mStartedOps.get(j);
+                    if (op.op == code && op.uid == uid) return true;
+                }
+            }
+        }
+        return false;
+    }
+
     private void removeUidsForUserLocked(int userHandle) {
         for (int i = mUidStates.size() - 1; i >= 0; --i) {
             final int uid = mUidStates.keyAt(i);
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 61057dd..c34c30c 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -86,6 +86,8 @@
     private static final int ACTIVE_LOG_MAX_SIZE = 20;
     private static final int CRASH_LOG_MAX_SIZE = 100;
     private static final String REASON_AIRPLANE_MODE = "airplane mode";
+    private static final String REASON_DISALLOWED = "disallowed by system";
+    private static final String REASON_SHARING_DISALLOWED = "sharing disallowed by system";
     private static final String REASON_RESTARTED = "automatic restart";
     private static final String REASON_START_CRASH = "turn-on crash";
     private static final String REASON_SYSTEM_BOOT = "system boot";
@@ -193,6 +195,7 @@
     private LinkedList<ActiveLog> mActiveLogs;
     private LinkedList<Long> mCrashTimestamps;
     private int mCrashes;
+    private long mLastEnabledTime;
 
     // configuration from external IBinder call which is used to
     // synchronize with broadcast receiver.
@@ -227,25 +230,26 @@
         @Override
         public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
                 Bundle prevRestrictions) {
-            if (!UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
-                    UserManager.DISALLOW_BLUETOOTH, UserManager.DISALLOW_BLUETOOTH_SHARING)) {
-                return; // No relevant changes, nothing to do.
+
+            if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
+                    UserManager.DISALLOW_BLUETOOTH_SHARING)) {
+                updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
+                        UserManager.DISALLOW_BLUETOOTH_SHARING));
             }
 
-            final boolean disallowed = newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH);
-
-            // DISALLOW_BLUETOOTH is a global restriction that can only be set by DO or PO on the
-            // system user, so we only look at the system user.
-            if (userId == UserHandle.USER_SYSTEM && disallowed && (mEnable || mEnableExternal)) {
-                try {
-                    disable(null /* packageName */, true /* persist */);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Exception when disabling Bluetooth", e);
+            // DISALLOW_BLUETOOTH can only be set by DO or PO on the system user.
+            if (userId == UserHandle.USER_SYSTEM &&
+                UserRestrictionsUtils.restrictionsChanged(
+                    prevRestrictions, newRestrictions, UserManager.DISALLOW_BLUETOOTH)) {
+                if (userId == UserHandle.USER_SYSTEM && newRestrictions.getBoolean(
+                        UserManager.DISALLOW_BLUETOOTH)) {
+                    updateOppLauncherComponentState(userId, true); // Sharing disallowed
+                    sendDisableMsg(REASON_DISALLOWED);
+                } else {
+                    updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
+                            UserManager.DISALLOW_BLUETOOTH_SHARING));
                 }
             }
-            final boolean sharingDisallowed = disallowed
-                    || newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH_SHARING);
-            updateOppLauncherComponentState(userId, sharingDisallowed);
         }
     };
 
@@ -2018,6 +2022,7 @@
         mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,
                              quietMode ? 1 : 0, 0));
         addActiveLog(packageName, true);
+        mLastEnabledTime = SystemClock.elapsedRealtime();
     }
 
     private void addActiveLog(String packageName, boolean enable) {
@@ -2118,7 +2123,8 @@
                 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
         try {
             final IPackageManager imp = AppGlobals.getPackageManager();
-            imp.setComponentEnabledSetting(oppLauncherComponent, newState, 0 /* flags */, userId);
+            imp.setComponentEnabledSetting(oppLauncherComponent, newState,
+                    PackageManager.DONT_KILL_APP, userId);
         } catch (Exception e) {
             // The component was not found, do nothing.
         }
@@ -2138,7 +2144,7 @@
             writer.println("  address: " + mAddress);
             writer.println("  name: " + mName);
             if (mEnable) {
-                long onDuration = System.currentTimeMillis() - mActiveLogs.getLast().getTime();
+                long onDuration = SystemClock.elapsedRealtime() - mLastEnabledTime;
                 String onDurationString = String.format("%02d:%02d:%02d.%03d",
                                           (int)(onDuration / (1000 * 60 * 60)),
                                           (int)((onDuration / (1000 * 60)) % 60),
diff --git a/services/core/java/com/android/server/CommonTimeManagementService.java b/services/core/java/com/android/server/CommonTimeManagementService.java
index 07c8679..5cebfa5 100644
--- a/services/core/java/com/android/server/CommonTimeManagementService.java
+++ b/services/core/java/com/android/server/CommonTimeManagementService.java
@@ -92,12 +92,12 @@
      * Internal state
      */
     private final Context mContext;
+    private final Object mLock = new Object();
     private INetworkManagementService mNetMgr;
     private CommonTimeConfig mCTConfig;
     private String mCurIface;
     private Handler mReconnectHandler = new Handler();
     private Handler mNoInterfaceHandler = new Handler();
-    private Object mLock = new Object();
     private boolean mDetectedAtStartup = false;
     private byte mEffectivePrio = BASE_SERVER_PRIO;
 
@@ -105,15 +105,19 @@
      * Callback handler implementations.
      */
     private INetworkManagementEventObserver mIfaceObserver = new BaseNetworkObserver() {
+        @Override
         public void interfaceStatusChanged(String iface, boolean up) {
             reevaluateServiceState();
         }
+        @Override
         public void interfaceLinkStateChanged(String iface, boolean up) {
             reevaluateServiceState();
         }
+        @Override
         public void interfaceAdded(String iface) {
             reevaluateServiceState();
         }
+        @Override
         public void interfaceRemoved(String iface) {
             reevaluateServiceState();
         }
@@ -127,19 +131,11 @@
     };
 
     private CommonTimeConfig.OnServerDiedListener mCTServerDiedListener =
-        new CommonTimeConfig.OnServerDiedListener() {
-            public void onServerDied() {
-                scheduleTimeConfigReconnect();
-            }
-        };
+            () -> scheduleTimeConfigReconnect();
 
-    private Runnable mReconnectRunnable = new Runnable() {
-        public void run() { connectToTimeConfig(); }
-    };
+    private Runnable mReconnectRunnable = () -> connectToTimeConfig();
 
-    private Runnable mNoInterfaceRunnable = new Runnable() {
-        public void run() { handleNoInterfaceTimeout(); }
-    };
+    private Runnable mNoInterfaceRunnable = () -> handleNoInterfaceTimeout();
 
     /*
      * Public interface (constructor, systemReady and dump)
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index e184288..ce19a1c 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -19,6 +19,7 @@
 import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.NETID_UNSET;
+import static android.net.ConnectivityManager.TYPE_ETHERNET;
 import static android.net.ConnectivityManager.TYPE_NONE;
 import static android.net.ConnectivityManager.TYPE_VPN;
 import static android.net.ConnectivityManager.getNetworkTypeName;
@@ -28,7 +29,10 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.net.NetworkCapabilities.TRANSPORT_VPN;
+
 import static com.android.internal.util.Preconditions.checkNotNull;
 
 import android.annotation.Nullable;
@@ -52,10 +56,10 @@
 import android.net.INetworkStatsService;
 import android.net.LinkProperties;
 import android.net.LinkProperties.CompareResult;
+import android.net.MatchAllNetworkSpecifier;
 import android.net.Network;
 import android.net.NetworkAgent;
 import android.net.NetworkCapabilities;
-import android.net.MatchAllNetworkSpecifier;
 import android.net.NetworkConfig;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
@@ -70,7 +74,7 @@
 import android.net.RouteInfo;
 import android.net.UidRange;
 import android.net.Uri;
-import android.net.metrics.DefaultNetworkEvent;
+import android.net.VpnService;
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.NetworkEvent;
 import android.net.util.MultinetworkPolicyTracker;
@@ -91,6 +95,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
+import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -127,10 +132,10 @@
 import com.android.server.LocalServices;
 import com.android.server.am.BatteryStatsService;
 import com.android.server.connectivity.DataConnectionStats;
+import com.android.server.connectivity.IpConnectivityMetrics;
 import com.android.server.connectivity.KeepaliveTracker;
-import com.android.server.connectivity.MockableSystemProperties;
-import com.android.server.connectivity.Nat464Xlat;
 import com.android.server.connectivity.LingerMonitor;
+import com.android.server.connectivity.MockableSystemProperties;
 import com.android.server.connectivity.NetworkAgentInfo;
 import com.android.server.connectivity.NetworkDiagnostics;
 import com.android.server.connectivity.NetworkMonitor;
@@ -139,8 +144,8 @@
 import com.android.server.connectivity.PacManager;
 import com.android.server.connectivity.PermissionMonitor;
 import com.android.server.connectivity.Tethering;
-import com.android.server.connectivity.tethering.TetheringDependencies;
 import com.android.server.connectivity.Vpn;
+import com.android.server.connectivity.tethering.TetheringDependencies;
 import com.android.server.net.BaseNetworkObserver;
 import com.android.server.net.LockdownVpnTracker;
 import com.android.server.net.NetworkPolicyManagerInternal;
@@ -458,6 +463,11 @@
 
     private static final int MAX_WAKELOCK_LOGS = 20;
     private final LocalLog mWakelockLogs = new LocalLog(MAX_WAKELOCK_LOGS);
+    private int mTotalWakelockAcquisitions = 0;
+    private int mTotalWakelockReleases = 0;
+    private long mTotalWakelockDurationMs = 0;
+    private long mMaxWakelockDurationMs = 0;
+    private long mLastWakeLockAcquireTimestamp = 0;
 
     // Array of <Network,ReadOnlyLocalLogs> tracking network validation and results
     private static final int MAX_VALIDATION_LOGS = 10;
@@ -778,6 +788,13 @@
             mNetworksDefined++;  // used only in the log() statement below.
         }
 
+        // Do the same for Ethernet, since it's often not specified in the configs, although many
+        // devices can use it via USB host adapters.
+        if (mNetConfigs[TYPE_ETHERNET] == null && hasService(Context.ETHERNET_SERVICE)) {
+            mLegacyTypeTracker.addSupportedType(TYPE_ETHERNET);
+            mNetworksDefined++;
+        }
+
         if (VDBG) log("mNetworksDefined=" + mNetworksDefined);
 
         mProtectedNetworks = new ArrayList<Integer>();
@@ -1510,6 +1527,12 @@
         ConnectivityManager.enforceChangePermission(mContext);
     }
 
+    private void enforceSettingsPermission() {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.NETWORK_SETTINGS,
+                "ConnectivityService");
+    }
+
     private void enforceTetherAccessPermission() {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE,
@@ -1959,6 +1982,14 @@
             pw.println();
             pw.println("NetTransition WakeLock activity (most recent first):");
             pw.increaseIndent();
+            pw.println("total acquisitions: " + mTotalWakelockAcquisitions);
+            pw.println("total releases: " + mTotalWakelockReleases);
+            pw.println("cumulative duration: " + (mTotalWakelockDurationMs / 1000) + "s");
+            pw.println("longest duration: " + (mMaxWakelockDurationMs / 1000) + "s");
+            if (mTotalWakelockAcquisitions > mTotalWakelockReleases) {
+                long duration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
+                pw.println("currently holding WakeLock for: " + (duration / 1000) + "s");
+            }
             mWakelockLogs.reverseDump(fd, pw, args);
             pw.decreaseIndent();
         }
@@ -2023,16 +2054,7 @@
                     break;
                 }
                 case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: {
-                    if (VDBG) {
-                        log("Update of LinkProperties for " + nai.name() +
-                                "; created=" + nai.created +
-                                "; everConnected=" + nai.everConnected);
-                    }
-                    LinkProperties oldLp = nai.linkProperties;
-                    synchronized (nai) {
-                        nai.linkProperties = (LinkProperties)msg.obj;
-                    }
-                    if (nai.everConnected) updateLinkProperties(nai, oldLp);
+                    handleUpdateLinkProperties(nai, (LinkProperties) msg.obj);
                     break;
                 }
                 case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: {
@@ -2091,9 +2113,14 @@
                         final boolean valid =
                                 (msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID);
                         final boolean wasValidated = nai.lastValidated;
+                        final boolean wasDefault = isDefaultNetwork(nai);
                         if (DBG) log(nai.name() + " validation " + (valid ? "passed" : "failed") +
                                 (msg.obj == null ? "" : " with redirect to " + (String)msg.obj));
                         if (valid != nai.lastValidated) {
+                            if (wasDefault) {
+                                metricsLogger().defaultNetworkMetrics().logDefaultNetworkValidity(
+                                        SystemClock.elapsedRealtime(), valid);
+                            }
                             final int oldScore = nai.getCurrentScore();
                             nai.lastValidated = valid;
                             nai.everValidated |= valid;
@@ -2213,7 +2240,7 @@
                 // A network factory has connected.  Send it all current NetworkRequests.
                 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
                     if (nri.request.isListen()) continue;
-                    NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
+                    NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId);
                     ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK,
                             (nai != null ? nai.getCurrentScore() : 0), 0, nri.request);
                 }
@@ -2265,7 +2292,8 @@
                 // Let rematchAllNetworksAndRequests() below record a new default network event
                 // if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence
                 // whose timestamps tell how long it takes to recover a default network.
-                logDefaultNetworkEvent(null, nai);
+                long now = SystemClock.elapsedRealtime();
+                metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai);
             }
             notifyIfacesChangedForNetworkStats();
             // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied
@@ -2281,7 +2309,7 @@
             }
             nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
             mNetworkAgentInfos.remove(msg.replyTo);
-            updateClat(null, nai.linkProperties, nai);
+            nai.maybeStopClat();
             synchronized (mNetworkForNetId) {
                 // Remove the NetworkAgent, but don't mark the netId as
                 // available until we've told netd to delete it below.
@@ -2290,9 +2318,9 @@
             // Remove all previously satisfied requests.
             for (int i = 0; i < nai.numNetworkRequests(); i++) {
                 NetworkRequest request = nai.requestAt(i);
-                NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(request.requestId);
+                NetworkAgentInfo currentNetwork = getNetworkForRequest(request.requestId);
                 if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
-                    mNetworkForRequestId.remove(request.requestId);
+                    clearNetworkForRequest(request.requestId);
                     sendUpdatedScoreToFactories(request, 0);
                 }
             }
@@ -2368,7 +2396,7 @@
             }
         }
         rematchAllNetworksAndRequests(null, 0);
-        if (nri.request.isRequest() && mNetworkForRequestId.get(nri.request.requestId) == null) {
+        if (nri.request.isRequest() && getNetworkForRequest(nri.request.requestId) == null) {
             sendUpdatedScoreToFactories(nri.request, 0);
         }
     }
@@ -2423,7 +2451,7 @@
                     // 2. Unvalidated WiFi will not be reaped when validated cellular
                     //    is currently satisfying the request.  This is desirable when
                     //    WiFi ends up validating and out scoring cellular.
-                    mNetworkForRequestId.get(nri.request.requestId).getCurrentScore() <
+                    getNetworkForRequest(nri.request.requestId).getCurrentScore() <
                             nai.getCurrentScoreAsValidated())) {
                 return false;
             }
@@ -2450,7 +2478,7 @@
         if (mNetworkRequests.get(nri.request) == null) {
             return;
         }
-        if (mNetworkForRequestId.get(nri.request.requestId) != null) {
+        if (getNetworkForRequest(nri.request.requestId) != null) {
             return;
         }
         if (VDBG || (DBG && nri.request.isRequest())) {
@@ -2490,7 +2518,7 @@
         mNetworkRequestInfoLogs.log("RELEASE " + nri);
         if (nri.request.isRequest()) {
             boolean wasKept = false;
-            NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
+            NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId);
             if (nai != null) {
                 boolean wasBackgroundNetwork = nai.isBackgroundNetwork();
                 nai.removeRequest(nri.request.requestId);
@@ -2507,7 +2535,7 @@
                 } else {
                     wasKept = true;
                 }
-                mNetworkForRequestId.remove(nri.request.requestId);
+                clearNetworkForRequest(nri.request.requestId);
                 if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) {
                     // Went from foreground to background.
                     updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
@@ -2970,12 +2998,16 @@
         return mTethering.getTetheredDhcpRanges();
     }
 
+    @Override
+    public boolean isTetheringSupported(String callerPkg) {
+        ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
+        return isTetheringSupported();
+    }
+
     // if ro.tether.denied = true we default to no tethering
     // gservices could set the secure setting to 1 though to enable it on a build where it
     // had previously been turned off.
-    @Override
-    public boolean isTetheringSupported() {
-        enforceTetherAccessPermission();
+    private boolean isTetheringSupported() {
         int defaultVal = encodeBool(!mSystemProperties.get("ro.tether.denied").equals("true"));
         boolean tetherSupported = toBool(Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.TETHER_SUPPORTED, defaultVal));
@@ -3021,6 +3053,8 @@
                 return;
             }
             mNetTransitionWakeLock.acquire();
+            mLastWakeLockAcquireTimestamp = SystemClock.elapsedRealtime();
+            mTotalWakelockAcquisitions++;
         }
         mWakelockLogs.log("ACQUIRE for " + forWhom);
         Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
@@ -3053,6 +3087,10 @@
                 return;
             }
             mNetTransitionWakeLock.release();
+            long lockDuration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
+            mTotalWakelockDurationMs += lockDuration;
+            mMaxWakelockDurationMs = Math.max(mMaxWakelockDurationMs, lockDuration);
+            mTotalWakelockReleases++;
         }
         mWakelockLogs.log(String.format("RELEASE (%s)", event));
     }
@@ -3636,6 +3674,21 @@
     }
 
     @Override
+    public boolean isAlwaysOnVpnPackageSupported(int userId, String packageName) {
+        enforceSettingsPermission();
+        enforceCrossUserPermission(userId);
+
+        synchronized (mVpns) {
+            Vpn vpn = mVpns.get(userId);
+            if (vpn == null) {
+                Slog.w(TAG, "User " + userId + " has no Vpn configuration");
+                return false;
+            }
+            return vpn.isAlwaysOnPackageSupported(packageName);
+        }
+    }
+
+    @Override
     public boolean setAlwaysOnVpnPackage(int userId, String packageName, boolean lockdown) {
         enforceConnectivityInternalPermission();
         enforceCrossUserPermission(userId);
@@ -4278,7 +4331,8 @@
      * and the are the highest scored network available.
      * the are keyed off the Requests requestId.
      */
-    // TODO: Yikes, this is accessed on multiple threads: add synchronization.
+    // NOTE: Accessed on multiple threads, must be synchronized on itself.
+    @GuardedBy("mNetworkForRequestId")
     private final SparseArray<NetworkAgentInfo> mNetworkForRequestId =
             new SparseArray<NetworkAgentInfo>();
 
@@ -4308,8 +4362,26 @@
     // priority networks like Wi-Fi are active.
     private final NetworkRequest mDefaultMobileDataRequest;
 
+    private NetworkAgentInfo getNetworkForRequest(int requestId) {
+        synchronized (mNetworkForRequestId) {
+            return mNetworkForRequestId.get(requestId);
+        }
+    }
+
+    private void clearNetworkForRequest(int requestId) {
+        synchronized (mNetworkForRequestId) {
+            mNetworkForRequestId.remove(requestId);
+        }
+    }
+
+    private void setNetworkForRequest(int requestId, NetworkAgentInfo nai) {
+        synchronized (mNetworkForRequestId) {
+            mNetworkForRequestId.put(requestId, nai);
+        }
+    }
+
     private NetworkAgentInfo getDefaultNetwork() {
-        return mNetworkForRequestId.get(mDefaultRequest.requestId);
+        return getNetworkForRequest(mDefaultRequest.requestId);
     }
 
     private boolean isDefaultNetwork(NetworkAgentInfo nai) {
@@ -4325,11 +4397,13 @@
             int currentScore, NetworkMisc networkMisc) {
         enforceConnectivityInternalPermission();
 
+        LinkProperties lp = new LinkProperties(linkProperties);
+        lp.ensureDirectlyConnectedRoutes();
         // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
         // satisfies mDefaultRequest.
         final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
-                new Network(reserveNetId()), new NetworkInfo(networkInfo), new LinkProperties(
-                linkProperties), new NetworkCapabilities(networkCapabilities), currentScore,
+                new Network(reserveNetId()), new NetworkInfo(networkInfo), lp,
+                new NetworkCapabilities(networkCapabilities), currentScore,
                 mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this);
         synchronized (this) {
             nai.networkMonitor.systemReady = mSystemReady;
@@ -4374,7 +4448,8 @@
         updateRoutes(newLp, oldLp, netId);
         updateDnses(newLp, oldLp, netId);
 
-        updateClat(newLp, oldLp, networkAgent);
+        // Start or stop clat accordingly to network state.
+        networkAgent.updateClat(mNetd);
         if (isDefaultNetwork(networkAgent)) {
             handleApplyDefaultProxy(newLp.getHttpProxy());
         } else {
@@ -4389,18 +4464,6 @@
         mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent);
     }
 
-    private void updateClat(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai) {
-        final boolean wasRunningClat = nai.clatd != null && nai.clatd.isStarted();
-        final boolean shouldRunClat = Nat464Xlat.requiresClat(nai);
-
-        if (!wasRunningClat && shouldRunClat) {
-            nai.clatd = new Nat464Xlat(mContext, mNetd, mTrackerHandler, nai);
-            nai.clatd.start();
-        } else if (wasRunningClat && !shouldRunClat) {
-            nai.clatd.stop();
-        }
-    }
-
     private void wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add) {
         // Marks are only available on WiFi interaces. Checking for
         // marks on unsupported interfaces is harmless.
@@ -4434,12 +4497,9 @@
 
     private void updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId,
                                   NetworkCapabilities caps) {
-        CompareResult<String> interfaceDiff = new CompareResult<String>();
-        if (oldLp != null) {
-            interfaceDiff = oldLp.compareAllInterfaceNames(newLp);
-        } else if (newLp != null) {
-            interfaceDiff.added = newLp.getAllInterfaceNames();
-        }
+        CompareResult<String> interfaceDiff = new CompareResult<String>(
+                oldLp != null ? oldLp.getAllInterfaceNames() : null,
+                newLp != null ? newLp.getAllInterfaceNames() : null);
         for (String iface : interfaceDiff.added) {
             try {
                 if (DBG) log("Adding iface " + iface + " to network " + netId);
@@ -4465,12 +4525,10 @@
      * @return true if routes changed between oldLp and newLp
      */
     private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
-        CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>();
-        if (oldLp != null) {
-            routeDiff = oldLp.compareAllRoutes(newLp);
-        } else if (newLp != null) {
-            routeDiff.added = newLp.getAllRoutes();
-        }
+        // Compare the route diff to determine which routes should be added and removed.
+        CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>(
+                oldLp != null ? oldLp.getAllRoutes() : null,
+                newLp != null ? newLp.getAllRoutes() : null);
 
         // add routes before removing old in case it helps with continuous connectivity
 
@@ -4616,10 +4674,12 @@
             }
         }
 
-        final NetworkCapabilities prevNc = nai.networkCapabilities;
+        final NetworkCapabilities prevNc;
         synchronized (nai) {
+            prevNc = nai.networkCapabilities;
             nai.networkCapabilities = networkCapabilities;
         }
+
         if (nai.getCurrentScore() == oldScore &&
                 networkCapabilities.equalRequestableCapabilities(prevNc)) {
             // If the requestable capabilities haven't changed, and the score hasn't changed, then
@@ -4633,6 +4693,49 @@
             rematchAllNetworksAndRequests(nai, oldScore);
             notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
         }
+
+        // Report changes that are interesting for network statistics tracking.
+        if (prevNc != null) {
+            final boolean meteredChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_METERED) !=
+                    networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED);
+            final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) !=
+                    networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING);
+            if (meteredChanged || roamingChanged) {
+                notifyIfacesChangedForNetworkStats();
+            }
+        }
+
+        if (!networkCapabilities.hasTransport(TRANSPORT_VPN)) {
+            // Tell VPNs about updated capabilities, since they may need to
+            // bubble those changes through.
+            synchronized (mVpns) {
+                for (int i = 0; i < mVpns.size(); i++) {
+                    final Vpn vpn = mVpns.valueAt(i);
+                    vpn.updateCapabilities();
+                }
+            }
+        }
+    }
+
+    public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) {
+        if (mNetworkForNetId.get(nai.network.netId) != nai) {
+            // Ignore updates for disconnected networks
+            return;
+        }
+        // newLp is already a defensive copy.
+        newLp.ensureDirectlyConnectedRoutes();
+        if (VDBG) {
+            log("Update of LinkProperties for " + nai.name() +
+                    "; created=" + nai.created +
+                    "; everConnected=" + nai.everConnected);
+        }
+        LinkProperties oldLp = nai.linkProperties;
+        synchronized (nai) {
+            nai.linkProperties = newLp;
+        }
+        if (nai.everConnected) {
+            updateLinkProperties(nai, oldLp);
+        }
     }
 
     private void sendUpdatedScoreToFactories(NetworkAgentInfo nai) {
@@ -4856,7 +4959,7 @@
             // requests or not, and doesn't affect the network's score.
             if (nri.request.isListen()) continue;
 
-            final NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId);
+            final NetworkAgentInfo currentNetwork = getNetworkForRequest(nri.request.requestId);
             final boolean satisfies = newNetwork.satisfies(nri.request);
             if (newNetwork == currentNetwork && satisfies) {
                 if (VDBG) {
@@ -4888,7 +4991,7 @@
                         if (VDBG) log("   accepting network in place of null");
                     }
                     newNetwork.unlingerRequest(nri.request);
-                    mNetworkForRequestId.put(nri.request.requestId, newNetwork);
+                    setNetworkForRequest(nri.request.requestId, newNetwork);
                     if (!newNetwork.addRequest(nri.request)) {
                         Slog.wtf(TAG, "BUG: " + newNetwork.name() + " already has " + nri.request);
                     }
@@ -4922,7 +5025,7 @@
                 }
                 newNetwork.removeRequest(nri.request.requestId);
                 if (currentNetwork == newNetwork) {
-                    mNetworkForRequestId.remove(nri.request.requestId);
+                    clearNetworkForRequest(nri.request.requestId);
                     sendUpdatedScoreToFactories(nri.request, 0);
                 } else {
                     Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " +
@@ -4943,7 +5046,8 @@
             // 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.
-            logDefaultNetworkEvent(newNetwork, oldDefaultNetwork);
+            metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(
+                    now, newNetwork, oldDefaultNetwork);
             // Have a new default network, release the transition wakelock in
             scheduleReleaseNetworkTransitionWakelock();
         }
@@ -5144,14 +5248,6 @@
         }
         notifyLockdownVpn(networkAgent);
 
-        if (oldInfo != null && oldInfo.getState() == state) {
-            if (oldInfo.isRoaming() != newInfo.isRoaming()) {
-                if (VDBG) log("roaming status changed, notifying NetworkStatsService");
-                notifyIfacesChangedForNetworkStats();
-            } else if (VDBG) log("ignoring duplicate network state non-change");
-            // In either case, no further work should be needed.
-            return;
-        }
         if (DBG) {
             log(networkAgent.name() + " EVENT_NETWORK_INFO_CHANGED, going from " +
                     (oldInfo == null ? "null" : oldInfo.getState()) +
@@ -5399,6 +5495,7 @@
 
     @Override
     public String getCaptivePortalServerUrl() {
+        enforceConnectivityInternalPermission();
         return NetworkMonitor.getCaptivePortalServerHttpUrl(mContext);
     }
 
@@ -5496,29 +5593,20 @@
         return new WakeupMessage(c, h, s, cmd, 0, 0, obj);
     }
 
-    private void logDefaultNetworkEvent(NetworkAgentInfo newNai, NetworkAgentInfo prevNai) {
-        int newNetid = NETID_UNSET;
-        int prevNetid = NETID_UNSET;
-        int[] transports = new int[0];
-        boolean hadIPv4 = false;
-        boolean hadIPv6 = false;
+    @VisibleForTesting
+    public boolean hasService(String name) {
+        return ServiceManager.checkService(name) != null;
+    }
 
-        if (newNai != null) {
-            newNetid = newNai.network.netId;
-            transports = newNai.networkCapabilities.getTransportTypes();
-        }
-        if (prevNai != null) {
-            prevNetid = prevNai.network.netId;
-            final LinkProperties lp = prevNai.linkProperties;
-            hadIPv4 = lp.hasIPv4Address() && lp.hasIPv4DefaultRoute();
-            hadIPv6 = lp.hasGlobalIPv6Address() && lp.hasIPv6DefaultRoute();
-        }
-
-        mMetricsLog.log(new DefaultNetworkEvent(newNetid, transports, prevNetid, hadIPv4, hadIPv6));
+    @VisibleForTesting
+    protected IpConnectivityMetrics.Logger metricsLogger() {
+        return checkNotNull(LocalServices.getService(IpConnectivityMetrics.Logger.class),
+                "no IpConnectivityMetrics service");
     }
 
     private void logNetworkEvent(NetworkAgentInfo nai, int evtype) {
-        mMetricsLog.log(new NetworkEvent(nai.network.netId, evtype));
+        int[] transports = nai.networkCapabilities.getTransportTypes();
+        mMetricsLog.log(nai.network.netId, transports, new NetworkEvent(evtype));
     }
 
     private static boolean toBool(int encodedBoolean) {
diff --git a/services/core/java/com/android/server/ContextHubSystemService.java b/services/core/java/com/android/server/ContextHubSystemService.java
index 5d4317c..110847d 100644
--- a/services/core/java/com/android/server/ContextHubSystemService.java
+++ b/services/core/java/com/android/server/ContextHubSystemService.java
@@ -16,17 +16,25 @@
 
 package com.android.server;
 
+import com.android.internal.util.ConcurrentUtils;
 import com.android.server.location.ContextHubService;
+import com.android.server.SystemServerInitThreadPool;
 import android.content.Context;
 import android.util.Log;
 
+import java.util.concurrent.Future;
+
 class ContextHubSystemService extends SystemService {
     private static final String TAG = "ContextHubSystemService";
-    private final ContextHubService mContextHubService;
+    private ContextHubService mContextHubService;
+
+    private Future<?> mInit;
 
     public ContextHubSystemService(Context context) {
         super(context);
-        mContextHubService = new ContextHubService(context);
+        mInit = SystemServerInitThreadPool.get().submit(() -> {
+            mContextHubService = new ContextHubService(context);
+        }, "Init ContextHubSystemService");
     }
 
     @Override
@@ -37,6 +45,9 @@
     public void onBootPhase(int phase) {
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
             Log.d(TAG, "onBootPhase: PHASE_SYSTEM_SERVICES_READY");
+            ConcurrentUtils.waitForFutureNoInterrupt(mInit,
+                    "Wait for ContextHubSystemService init");
+            mInit = null;
             publishBinderService(Context.CONTEXTHUB_SERVICE, mContextHubService);
         }
     }
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index 830a6ed..a903f3d 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -28,6 +28,8 @@
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
+import android.hardware.TriggerEvent;
+import android.hardware.TriggerEventListener;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
@@ -38,9 +40,12 @@
 import android.util.MutableBoolean;
 import android.util.Slog;
 import android.view.KeyEvent;
+import android.view.WindowManagerInternal;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.server.LocalServices;
 import com.android.server.statusbar.StatusBarManagerInternal;
 
 /**
@@ -52,23 +57,39 @@
  */
 public class GestureLauncherService extends SystemService {
     private static final boolean DBG = false;
+    private static final boolean DBG_CAMERA_LIFT = false;
     private static final String TAG = "GestureLauncherService";
 
     /**
      * Time in milliseconds in which the power button must be pressed twice so it will be considered
      * as a camera launch.
      */
-    private static final long CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS = 300;
+    @VisibleForTesting static final long CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS = 300;
+
+    /**
+     * Interval in milliseconds in which the power button must be depressed in succession to be
+     * considered part of an extended sequence of taps. Note that this is a looser threshold than
+     * the camera launch gesture, because the purpose of this threshold is to measure the
+     * frequency of consecutive taps, for evaluation for future gestures.
+     */
+    @VisibleForTesting static final long POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS = 500;
 
     /** The listener that receives the gesture event. */
     private final GestureEventListener mGestureListener = new GestureEventListener();
+    private final CameraLiftTriggerEventListener mCameraLiftTriggerListener =
+            new CameraLiftTriggerEventListener();
 
     private Sensor mCameraLaunchSensor;
+    private Sensor mCameraLiftTriggerSensor;
     private Context mContext;
+    private final MetricsLogger mMetricsLogger;
+    private PowerManager mPowerManager;
+    private WindowManagerInternal mWindowManagerInternal;
 
     /** The wake lock held when a gesture is detected. */
     private WakeLock mWakeLock;
-    private boolean mRegistered;
+    private boolean mCameraLaunchRegistered;
+    private boolean mCameraLiftRegistered;
     private int mUserId;
 
     // Below are fields used for event logging only.
@@ -106,10 +127,17 @@
      */
     private boolean mCameraDoubleTapPowerEnabled;
     private long mLastPowerDown;
+    private int mPowerButtonConsecutiveTaps;
 
     public GestureLauncherService(Context context) {
+        this(context, new MetricsLogger());
+    }
+
+    @VisibleForTesting
+    GestureLauncherService(Context context, MetricsLogger metricsLogger) {
         super(context);
         mContext = context;
+        mMetricsLogger = metricsLogger;
     }
 
     public void onStart() {
@@ -124,9 +152,10 @@
                 return;
             }
 
-            PowerManager powerManager = (PowerManager) mContext.getSystemService(
+            mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+            mPowerManager = (PowerManager) mContext.getSystemService(
                     Context.POWER_SERVICE);
-            mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+            mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                     "GestureLauncherService");
             updateCameraRegistered();
             updateCameraDoubleTapPowerEnabled();
@@ -144,6 +173,9 @@
         mContext.getContentResolver().registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED),
                 false, mSettingObserver, mUserId);
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED),
+                false, mSettingObserver, mUserId);
     }
 
     private void updateCameraRegistered() {
@@ -153,9 +185,16 @@
         } else {
             unregisterCameraLaunchGesture();
         }
+
+        if (isCameraLiftTriggerSettingEnabled(mContext, mUserId)) {
+            registerCameraLiftTrigger(resources);
+        } else {
+            unregisterCameraLiftTrigger();
+        }
     }
 
-    private void updateCameraDoubleTapPowerEnabled() {
+    @VisibleForTesting
+    void updateCameraDoubleTapPowerEnabled() {
         boolean enabled = isCameraDoubleTapPowerSettingEnabled(mContext, mUserId);
         synchronized (this) {
             mCameraDoubleTapPowerEnabled = enabled;
@@ -163,8 +202,8 @@
     }
 
     private void unregisterCameraLaunchGesture() {
-        if (mRegistered) {
-            mRegistered = false;
+        if (mCameraLaunchRegistered) {
+            mCameraLaunchRegistered = false;
             mCameraGestureOnTimeMs = 0L;
             mCameraGestureLastEventTime = 0L;
             mCameraGestureSensor1LastOnTimeMs = 0;
@@ -181,7 +220,7 @@
      * Registers for the camera launch gesture.
      */
     private void registerCameraLaunchGesture(Resources resources) {
-        if (mRegistered) {
+        if (mCameraLaunchRegistered) {
             return;
         }
         mCameraGestureOnTimeMs = SystemClock.elapsedRealtime();
@@ -191,7 +230,7 @@
         int cameraLaunchGestureId = resources.getInteger(
                 com.android.internal.R.integer.config_cameraLaunchGestureSensorType);
         if (cameraLaunchGestureId != -1) {
-            mRegistered = false;
+            mCameraLaunchRegistered = false;
             String sensorName = resources.getString(
                 com.android.internal.R.string.config_cameraLaunchGestureSensorStringType);
             mCameraLaunchSensor = sensorManager.getDefaultSensor(
@@ -203,7 +242,7 @@
             // makes the code more robust.
             if (mCameraLaunchSensor != null) {
                 if (sensorName.equals(mCameraLaunchSensor.getStringType())) {
-                    mRegistered = sensorManager.registerListener(mGestureListener,
+                    mCameraLaunchRegistered = sensorManager.registerListener(mGestureListener,
                             mCameraLaunchSensor, 0);
                 } else {
                     String message = String.format("Wrong configuration. Sensor type and sensor "
@@ -212,12 +251,61 @@
                     throw new RuntimeException(message);
                 }
             }
-            if (DBG) Slog.d(TAG, "Camera launch sensor registered: " + mRegistered);
+            if (DBG) Slog.d(TAG, "Camera launch sensor registered: " + mCameraLaunchRegistered);
         } else {
             if (DBG) Slog.d(TAG, "Camera launch sensor is not specified.");
         }
     }
 
+    private void unregisterCameraLiftTrigger() {
+        if (mCameraLiftRegistered) {
+            mCameraLiftRegistered = false;
+
+            SensorManager sensorManager = (SensorManager) mContext.getSystemService(
+                    Context.SENSOR_SERVICE);
+            sensorManager.cancelTriggerSensor(mCameraLiftTriggerListener, mCameraLiftTriggerSensor);
+        }
+    }
+
+    /**
+     * Registers for the camera lift trigger.
+     */
+    private void registerCameraLiftTrigger(Resources resources) {
+        if (mCameraLiftRegistered) {
+            return;
+        }
+        SensorManager sensorManager = (SensorManager) mContext.getSystemService(
+                Context.SENSOR_SERVICE);
+        int cameraLiftTriggerId = resources.getInteger(
+                com.android.internal.R.integer.config_cameraLiftTriggerSensorType);
+        if (cameraLiftTriggerId != -1) {
+            mCameraLiftRegistered = false;
+            String sensorName = resources.getString(
+                com.android.internal.R.string.config_cameraLiftTriggerSensorStringType);
+            mCameraLiftTriggerSensor = sensorManager.getDefaultSensor(
+                    cameraLiftTriggerId,
+                    true /*wakeUp*/);
+
+            // Compare the camera lift trigger string type to that in the resource file to make
+            // sure we are registering the correct sensor. This is redundant check, it
+            // makes the code more robust.
+            if (mCameraLiftTriggerSensor != null) {
+                if (sensorName.equals(mCameraLiftTriggerSensor.getStringType())) {
+                    mCameraLiftRegistered = sensorManager.requestTriggerSensor(mCameraLiftTriggerListener,
+                            mCameraLiftTriggerSensor);
+                } else {
+                    String message = String.format("Wrong configuration. Sensor type and sensor "
+                            + "string type don't match: %s in resources, %s in the sensor.",
+                            sensorName, mCameraLiftTriggerSensor.getStringType());
+                    throw new RuntimeException(message);
+                }
+            }
+            if (DBG) Slog.d(TAG, "Camera lift trigger sensor registered: " + mCameraLiftRegistered);
+        } else {
+            if (DBG) Slog.d(TAG, "Camera lift trigger sensor is not specified.");
+        }
+    }
+
     public static boolean isCameraLaunchSettingEnabled(Context context, int userId) {
         return isCameraLaunchEnabled(context.getResources())
                 && (Settings.Secure.getIntForUser(context.getContentResolver(),
@@ -230,6 +318,13 @@
                         Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0, userId) == 0);
     }
 
+    public static boolean isCameraLiftTriggerSettingEnabled(Context context, int userId) {
+        return isCameraLiftTriggerEnabled(context.getResources())
+                && (Settings.Secure.getIntForUser(context.getContentResolver(),
+                        Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED,
+                        Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED_DEFAULT, userId) != 0);
+    }
+
     /**
      * Whether to enable the camera launch gesture.
      */
@@ -245,38 +340,55 @@
                 com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled);
     }
 
+    public static boolean isCameraLiftTriggerEnabled(Resources resources) {
+        boolean configSet = resources.getInteger(
+                com.android.internal.R.integer.config_cameraLiftTriggerSensorType) != -1;
+        return configSet;
+    }
+
     /**
      * Whether GestureLauncherService should be enabled according to system properties.
      */
     public static boolean isGestureLauncherEnabled(Resources resources) {
-        return isCameraLaunchEnabled(resources) || isCameraDoubleTapPowerEnabled(resources);
+        return isCameraLaunchEnabled(resources) || isCameraDoubleTapPowerEnabled(resources) ||
+                isCameraLiftTriggerEnabled(resources);
     }
 
     public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive,
             MutableBoolean outLaunched) {
         boolean launched = false;
         boolean intercept = false;
-        long doubleTapInterval;
+        long powerTapInterval;
         synchronized (this) {
-            doubleTapInterval = event.getEventTime() - mLastPowerDown;
+            powerTapInterval = event.getEventTime() - mLastPowerDown;
             if (mCameraDoubleTapPowerEnabled
-                    && doubleTapInterval < CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS) {
+                    && powerTapInterval < CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS) {
                 launched = true;
                 intercept = interactive;
+                mPowerButtonConsecutiveTaps++;
+            } else if (powerTapInterval < POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS) {
+                mPowerButtonConsecutiveTaps++;
+            } else {
+                mPowerButtonConsecutiveTaps = 1;
             }
             mLastPowerDown = event.getEventTime();
         }
+        if (DBG && mPowerButtonConsecutiveTaps > 1) {
+            Slog.i(TAG, Long.valueOf(mPowerButtonConsecutiveTaps) +
+                    " consecutive power button taps detected");
+        }
         if (launched) {
             Slog.i(TAG, "Power button double tap gesture detected, launching camera. Interval="
-                    + doubleTapInterval + "ms");
-            launched = handleCameraLaunchGesture(false /* useWakelock */,
+                    + powerTapInterval + "ms");
+            launched = handleCameraGesture(false /* useWakelock */,
                     StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
             if (launched) {
-                MetricsLogger.action(mContext, MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE,
-                        (int) doubleTapInterval);
+                mMetricsLogger.action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE,
+                        (int) powerTapInterval);
             }
         }
-        MetricsLogger.histogram(mContext, "power_double_tap_interval", (int) doubleTapInterval);
+        mMetricsLogger.histogram("power_consecutive_short_tap_count", mPowerButtonConsecutiveTaps);
+        mMetricsLogger.histogram("power_double_tap_interval", (int) powerTapInterval);
         outLaunched.value = launched;
         return intercept && launched;
     }
@@ -284,17 +396,18 @@
     /**
      * @return true if camera was launched, false otherwise.
      */
-    private boolean handleCameraLaunchGesture(boolean useWakelock, int source) {
+    @VisibleForTesting
+    boolean handleCameraGesture(boolean useWakelock, int source) {
         boolean userSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                 Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
         if (!userSetupComplete) {
             if (DBG) Slog.d(TAG, String.format(
-                    "userSetupComplete = %s, ignoring camera launch gesture.",
+                    "userSetupComplete = %s, ignoring camera gesture.",
                     userSetupComplete));
             return false;
         }
         if (DBG) Slog.d(TAG, String.format(
-                "userSetupComplete = %s, performing camera launch gesture.",
+                "userSetupComplete = %s, performing camera gesture.",
                 userSetupComplete));
 
         if (useWakelock) {
@@ -332,7 +445,7 @@
     private final class GestureEventListener implements SensorEventListener {
         @Override
         public void onSensorChanged(SensorEvent event) {
-            if (!mRegistered) {
+            if (!mCameraLaunchRegistered) {
               if (DBG) Slog.d(TAG, "Ignoring gesture event because it's unregistered.");
               return;
             }
@@ -342,9 +455,9 @@
                     Slog.d(TAG, String.format("Received a camera launch event: " +
                             "values=[%.4f, %.4f, %.4f].", values[0], values[1], values[2]));
                 }
-                if (handleCameraLaunchGesture(true /* useWakelock */,
+                if (handleCameraGesture(true /* useWakelock */,
                         StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE)) {
-                    MetricsLogger.action(mContext, MetricsEvent.ACTION_WIGGLE_CAMERA_GESTURE);
+                    mMetricsLogger.action(MetricsEvent.ACTION_WIGGLE_CAMERA_GESTURE);
                     trackCameraLaunchEvent(event);
                 }
                 return;
@@ -401,4 +514,46 @@
             mCameraLaunchLastEventExtra = extra;
         }
     }
+
+    private final class CameraLiftTriggerEventListener extends TriggerEventListener {
+        @Override
+        public void onTrigger(TriggerEvent event) {
+            if (DBG_CAMERA_LIFT) Slog.d(TAG, String.format("onTrigger event - time: %d, name: %s",
+                    event.timestamp, event.sensor.getName()));
+            if (!mCameraLiftRegistered) {
+              if (DBG_CAMERA_LIFT) Slog.d(TAG, "Ignoring camera lift event because it's " +
+                      "unregistered.");
+              return;
+            }
+            if (event.sensor == mCameraLiftTriggerSensor) {
+                Resources resources = mContext.getResources();
+                SensorManager sensorManager = (SensorManager) mContext.getSystemService(
+                        Context.SENSOR_SERVICE);
+                boolean keyguardShowingAndNotOccluded =
+                        mWindowManagerInternal.isKeyguardShowingAndNotOccluded();
+                boolean interactive = mPowerManager.isInteractive();
+                if (DBG_CAMERA_LIFT) {
+                    float[] values = event.values;
+                    Slog.d(TAG, String.format("Received a camera lift trigger " +
+                            "event: values=[%.4f], keyguard showing: %b, interactive: %b", values[0],
+                            keyguardShowingAndNotOccluded, interactive));
+                }
+                if (keyguardShowingAndNotOccluded || !interactive) {
+                    if (handleCameraGesture(true /* useWakelock */,
+                            StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER)) {
+                        MetricsLogger.action(mContext, MetricsEvent.ACTION_CAMERA_LIFT_TRIGGER);
+                    }
+                } else {
+                    if (DBG_CAMERA_LIFT) Slog.d(TAG, "Ignoring lift event");
+                }
+
+                mCameraLiftRegistered = sensorManager.requestTriggerSensor(
+                        mCameraLiftTriggerListener, mCameraLiftTriggerSensor);
+
+                if (DBG_CAMERA_LIFT) Slog.d(TAG, "Camera lift trigger sensor re-registered: " +
+                        mCameraLiftRegistered);
+                return;
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index bff39b3..6339c9e 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -1447,7 +1447,9 @@
                 broadcastFilter.addAction(Intent.ACTION_LOCALE_CHANGED);
                 mContext.registerReceiver(new ImmsBroadcastReceiver(), broadcastFilter);
 
-                buildInputMethodListLocked(true /* resetDefaultEnabledIme */);
+                final String defaultImiId = mSettings.getSelectedInputMethod();
+                final boolean imeSelectedOnBoot = !TextUtils.isEmpty(defaultImiId);
+                buildInputMethodListLocked(!imeSelectedOnBoot /* resetDefaultEnabledIme */);
                 resetDefaultImeLocked(mContext);
                 updateFromSettingsLocked(true);
                 InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mIPackageManager,
@@ -2088,7 +2090,8 @@
     private boolean shouldShowImeSwitcherLocked(int visibility) {
         if (!mShowOngoingImeSwitcherForPhones) return false;
         if (mSwitchingDialog != null) return false;
-        if (isScreenLocked()) return false;
+        if (mWindowManagerInternal.isKeyguardShowingAndNotOccluded()
+                && mKeyguardManager != null && mKeyguardManager.isKeyguardSecure()) return false;
         if ((visibility & InputMethodService.IME_ACTIVE) == 0) return false;
         if (mWindowManagerInternal.isHardKeyboardAvailable()) {
             if (mHardKeyboardBehavior == HardKeyboardBehavior.WIRELESS_AFFORDANCE) {
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 3056831..1154fbe 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -33,6 +33,7 @@
 import android.net.IpSecTransform;
 import android.net.IpSecTransformResponse;
 import android.net.IpSecUdpEncapResponse;
+import android.net.NetworkUtils;
 import android.net.util.NetdService;
 import android.os.Binder;
 import android.os.IBinder;
@@ -42,11 +43,14 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -54,6 +58,7 @@
 import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
 import java.util.concurrent.atomic.AtomicInteger;
+
 import libcore.io.IoUtils;
 
 /** @hide */
@@ -252,7 +257,11 @@
             return (mReferenceCount.get() > 0);
         }
 
-        public void checkOwnerOrSystemAndThrow() {
+        /**
+         * Ensures that the caller is either the owner of this resource or has the system UID and
+         * throws a SecurityException otherwise.
+         */
+        public void checkOwnerOrSystem() {
             if (uid != Binder.getCallingUid()
                     && android.os.Process.SYSTEM_UID != Binder.getCallingUid()) {
                 throw new SecurityException("Only the owner may access managed resources!");
@@ -335,12 +344,12 @@
     private class ManagedResourceArray<T extends ManagedResource> {
         SparseArray<T> mArray = new SparseArray<>();
 
-        T get(int key) {
+        T getAndCheckOwner(int key) {
             T val = mArray.get(key);
             // The value should never be null unless the resource doesn't exist
             // (since we do not allow null resources to be added).
             if (val != null) {
-                val.checkOwnerOrSystemAndThrow();
+                val.checkOwnerOrSystem();
             }
             return val;
         }
@@ -405,12 +414,8 @@
                             .ipSecDeleteSecurityAssociation(
                                     mResourceId,
                                     direction,
-                                    (mConfig.getLocalAddress() != null)
-                                            ? mConfig.getLocalAddress().getHostAddress()
-                                            : "",
-                                    (mConfig.getRemoteAddress() != null)
-                                            ? mConfig.getRemoteAddress().getHostAddress()
-                                            : "",
+                                    mConfig.getLocalAddress(),
+                                    mConfig.getRemoteAddress(),
                                     spi);
                 } catch (ServiceSpecificException e) {
                     // FIXME: get the error code and throw is at an IOException from Errno Exception
@@ -638,11 +643,45 @@
         }
     }
 
+    /**
+     * Checks that the provided InetAddress is valid for use in an IPsec SA. The address must not be
+     * a wildcard address and must be in a numeric form such as 1.2.3.4 or 2001::1.
+     */
+    private static void checkInetAddress(String inetAddress) {
+        if (TextUtils.isEmpty(inetAddress)) {
+            throw new IllegalArgumentException("Unspecified address");
+        }
+
+        InetAddress checkAddr = NetworkUtils.numericToInetAddress(inetAddress);
+
+        if (checkAddr.isAnyLocalAddress()) {
+            throw new IllegalArgumentException("Inappropriate wildcard address: " + inetAddress);
+        }
+    }
+
+    /**
+     * Checks the user-provided direction field and throws an IllegalArgumentException if it is not
+     * DIRECTION_IN or DIRECTION_OUT
+     */
+    private static void checkDirection(int direction) {
+        switch (direction) {
+            case IpSecTransform.DIRECTION_OUT:
+            case IpSecTransform.DIRECTION_IN:
+                return;
+        }
+        throw new IllegalArgumentException("Invalid Direction: " + direction);
+    }
+
     @Override
     /** Get a new SPI and maintain the reservation in the system server */
     public synchronized IpSecSpiResponse reserveSecurityParameterIndex(
             int direction, String remoteAddress, int requestedSpi, IBinder binder)
             throws RemoteException {
+        checkDirection(direction);
+        checkInetAddress(remoteAddress);
+        /* requestedSpi can be anything in the int range, so no check is needed. */
+        checkNotNull(binder, "Null Binder passed to reserveSecurityParameterIndex");
+
         int resourceId = mNextResourceId.getAndIncrement();
 
         int spi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX;
@@ -651,9 +690,7 @@
         try {
             if (!mUserQuotaTracker.getUserRecord(Binder.getCallingUid()).spi.isAvailable()) {
                 return new IpSecSpiResponse(
-                        IpSecManager.Status.RESOURCE_UNAVAILABLE,
-                        INVALID_RESOURCE_ID,
-                        spi);
+                        IpSecManager.Status.RESOURCE_UNAVAILABLE, INVALID_RESOURCE_ID, spi);
             }
             spi =
                     mSrvConfig
@@ -686,7 +723,7 @@
             throws RemoteException {
         // We want to non-destructively get so that we can check credentials before removing
         // this from the records.
-        T record = resArray.get(resourceId);
+        T record = resArray.getAndCheckOwner(resourceId);
 
         if (record == null) {
             throw new IllegalArgumentException(
@@ -717,7 +754,7 @@
      * and re-binding, during which the system could *technically* hand that port out to someone
      * else.
      */
-    private void bindToRandomPort(FileDescriptor sockFd) throws IOException {
+    private int bindToRandomPort(FileDescriptor sockFd) throws IOException {
         for (int i = MAX_PORT_BIND_ATTEMPTS; i > 0; i--) {
             try {
                 FileDescriptor probeSocket = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
@@ -726,7 +763,7 @@
                 Os.close(probeSocket);
                 Log.v(TAG, "Binding to port " + port);
                 Os.bind(sockFd, INADDR_ANY, port);
-                return;
+                return port;
             } catch (ErrnoException e) {
                 // Someone miraculously claimed the port just after we closed probeSocket.
                 if (e.errno == OsConstants.EADDRINUSE) {
@@ -751,6 +788,8 @@
             throw new IllegalArgumentException(
                     "Specified port number must be a valid non-reserved UDP port");
         }
+        checkNotNull(binder, "Null Binder passed to openUdpEncapsulationSocket");
+
         int resourceId = mNextResourceId.getAndIncrement();
         FileDescriptor sockFd = null;
         try {
@@ -764,7 +803,7 @@
                 Log.v(TAG, "Binding to port " + port);
                 Os.bind(sockFd, INADDR_ANY, port);
             } else {
-                bindToRandomPort(sockFd);
+                port = bindToRandomPort(sockFd);
             }
             // This code is common to both the unspecified and specified port cases
             Os.setsockoptInt(
@@ -792,6 +831,74 @@
     }
 
     /**
+     * Checks an IpSecConfig parcel to ensure that the contents are sane and throws an
+     * IllegalArgumentException if they are not.
+     */
+    private void checkIpSecConfig(IpSecConfig config) {
+        if (config.getLocalAddress() == null) {
+            throw new IllegalArgumentException("Invalid null Local InetAddress");
+        }
+
+        if (config.getRemoteAddress() == null) {
+            throw new IllegalArgumentException("Invalid null Remote InetAddress");
+        }
+
+        switch (config.getMode()) {
+            case IpSecTransform.MODE_TRANSPORT:
+                if (!config.getLocalAddress().isEmpty()) {
+                    throw new IllegalArgumentException("Non-empty Local Address");
+                }
+                // Must be valid, and not a wildcard
+                checkInetAddress(config.getRemoteAddress());
+                break;
+            case IpSecTransform.MODE_TUNNEL:
+                break;
+            default:
+                throw new IllegalArgumentException(
+                        "Invalid IpSecTransform.mode: " + config.getMode());
+        }
+
+        switch (config.getEncapType()) {
+            case IpSecTransform.ENCAP_NONE:
+                break;
+            case IpSecTransform.ENCAP_ESPINUDP:
+            case IpSecTransform.ENCAP_ESPINUDP_NON_IKE:
+                if (mUdpSocketRecords.getAndCheckOwner(
+                            config.getEncapSocketResourceId()) == null) {
+                    throw new IllegalStateException(
+                            "No Encapsulation socket for Resource Id: "
+                                    + config.getEncapSocketResourceId());
+                }
+
+                int port = config.getEncapRemotePort();
+                if (port <= 0 || port > 0xFFFF) {
+                    throw new IllegalArgumentException("Invalid remote UDP port: " + port);
+                }
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid Encap Type: " + config.getEncapType());
+        }
+
+        for (int direction : DIRECTIONS) {
+            IpSecAlgorithm crypt = config.getEncryption(direction);
+            IpSecAlgorithm auth = config.getAuthentication(direction);
+            IpSecAlgorithm authenticatedEncryption = config.getAuthenticatedEncryption(direction);
+            if (authenticatedEncryption == null && crypt == null && auth == null) {
+                throw new IllegalArgumentException(
+                        "No Encryption or Authentication algorithms specified");
+            } else if (authenticatedEncryption != null && (auth != null || crypt != null)) {
+                throw new IllegalArgumentException(
+                        "Authenticated Encryption is mutually"
+                                + " exclusive with other Authentication or Encryption algorithms");
+            }
+
+            if (mSpiRecords.getAndCheckOwner(config.getSpiResourceId(direction)) == null) {
+                throw new IllegalStateException("No SPI for specified Resource Id");
+            }
+        }
+    }
+
+    /**
      * Create a transport mode transform, which represent two security associations (one in each
      * direction) in the kernel. The transform will be cached by the system server and must be freed
      * when no longer needed. It is possible to free one, deleting the SA from underneath sockets
@@ -801,17 +908,19 @@
     @Override
     public synchronized IpSecTransformResponse createTransportModeTransform(
             IpSecConfig c, IBinder binder) throws RemoteException {
+        checkIpSecConfig(c);
+        checkNotNull(binder, "Null Binder passed to createTransportModeTransform");
         int resourceId = mNextResourceId.getAndIncrement();
         if (!mUserQuotaTracker.getUserRecord(Binder.getCallingUid()).transform.isAvailable()) {
             return new IpSecTransformResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE);
         }
         SpiRecord[] spis = new SpiRecord[DIRECTIONS.length];
-        // TODO: Basic input validation here since it's coming over the Binder
+
         int encapType, encapLocalPort = 0, encapRemotePort = 0;
         UdpSocketRecord socketRecord = null;
         encapType = c.getEncapType();
         if (encapType != IpSecTransform.ENCAP_NONE) {
-            socketRecord = mUdpSocketRecords.get(c.getEncapLocalResourceId());
+            socketRecord = mUdpSocketRecords.getAndCheckOwner(c.getEncapSocketResourceId());
             encapLocalPort = socketRecord.getPort();
             encapRemotePort = c.getEncapRemotePort();
         }
@@ -819,31 +928,30 @@
         for (int direction : DIRECTIONS) {
             IpSecAlgorithm auth = c.getAuthentication(direction);
             IpSecAlgorithm crypt = c.getEncryption(direction);
+            IpSecAlgorithm authCrypt = c.getAuthenticatedEncryption(direction);
 
-            spis[direction] = mSpiRecords.get(c.getSpiResourceId(direction));
+            spis[direction] = mSpiRecords.getAndCheckOwner(c.getSpiResourceId(direction));
             int spi = spis[direction].getSpi();
             try {
-                mSrvConfig.getNetdInstance()
+                mSrvConfig
+                        .getNetdInstance()
                         .ipSecAddSecurityAssociation(
                                 resourceId,
                                 c.getMode(),
                                 direction,
-                                (c.getLocalAddress() != null)
-                                        ? c.getLocalAddress().getHostAddress()
-                                        : "",
-                                (c.getRemoteAddress() != null)
-                                        ? c.getRemoteAddress().getHostAddress()
-                                        : "",
-                                (c.getNetwork() != null)
-                                        ? c.getNetwork().getNetworkHandle()
-                                        : 0,
+                                c.getLocalAddress(),
+                                c.getRemoteAddress(),
+                                (c.getNetwork() != null) ? c.getNetwork().getNetworkHandle() : 0,
                                 spi,
                                 (auth != null) ? auth.getName() : "",
-                                (auth != null) ? auth.getKey() : null,
+                                (auth != null) ? auth.getKey() : new byte[] {},
                                 (auth != null) ? auth.getTruncationLengthBits() : 0,
                                 (crypt != null) ? crypt.getName() : "",
-                                (crypt != null) ? crypt.getKey() : null,
+                                (crypt != null) ? crypt.getKey() : new byte[] {},
                                 (crypt != null) ? crypt.getTruncationLengthBits() : 0,
+                                (authCrypt != null) ? authCrypt.getName() : "",
+                                (authCrypt != null) ? authCrypt.getKey() : new byte[] {},
+                                (authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0,
                                 encapType,
                                 encapLocalPort,
                                 encapRemotePort);
@@ -879,7 +987,7 @@
         // Synchronize liberally here because we are using ManagedResources in this block
         TransformRecord info;
         // FIXME: this code should be factored out into a security check + getter
-        info = mTransformRecords.get(resourceId);
+        info = mTransformRecords.getAndCheckOwner(resourceId);
 
         if (info == null) {
             throw new IllegalArgumentException("Transform " + resourceId + " is not active");
@@ -899,12 +1007,8 @@
                                 socket.getFileDescriptor(),
                                 resourceId,
                                 direction,
-                                (c.getLocalAddress() != null)
-                                        ? c.getLocalAddress().getHostAddress()
-                                        : "",
-                                (c.getRemoteAddress() != null)
-                                        ? c.getRemoteAddress().getHostAddress()
-                                        : "",
+                                c.getLocalAddress(),
+                                c.getRemoteAddress(),
                                 info.getSpiRecord(direction).getSpi());
             }
         } catch (ServiceSpecificException e) {
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 3460419..a4e673d 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -243,6 +243,8 @@
 
     private GnssLocationProvider.GnssSystemInfoProvider mGnssSystemInfoProvider;
 
+    private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider;
+
     private GnssLocationProvider.GnssBatchingProvider mGnssBatchingProvider;
     private IBatchedLocationCallback mGnssBatchingCallback;
     private LinkedCallback mGnssBatchingDeathCallback;
@@ -587,6 +589,7 @@
                     mLocationHandler.getLooper());
             mGnssSystemInfoProvider = gnssProvider.getGnssSystemInfoProvider();
             mGnssBatchingProvider = gnssProvider.getGnssBatchingProvider();
+            mGnssMetricsProvider = gnssProvider.getGnssMetricsProvider();
             mGnssStatusProvider = gnssProvider.getGnssStatusProvider();
             mNetInitiatedListener = gnssProvider.getNetInitiatedListener();
             addProviderLocked(gnssProvider);
@@ -3036,6 +3039,12 @@
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
         synchronized (mLock) {
+            if (args.length > 0 && args[0].equals("--gnssmetrics")) {
+                if (mGnssMetricsProvider != null) {
+                    pw.append(mGnssMetricsProvider.getGnssMetricsAsProtoString());
+                }
+                return;
+            }
             pw.println("Current Location Manager state:");
             pw.println("  Location Listeners:");
             for (Receiver receiver : mReceivers.values()) {
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
deleted file mode 100644
index 773a1ee..0000000
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ /dev/null
@@ -1,2259 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
-import static android.Manifest.permission.READ_CONTACTS;
-import static android.content.Context.KEYGUARD_SERVICE;
-import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
-
-import android.annotation.UserIdInt;
-import android.app.ActivityManager;
-import android.app.IActivityManager;
-import android.app.KeyguardManager;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.admin.DevicePolicyManager;
-import android.app.admin.PasswordMetrics;
-import android.app.backup.BackupManager;
-import android.app.trust.IStrongAuthTracker;
-import android.app.trust.TrustManager;
-import android.content.BroadcastReceiver;
-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.content.res.Resources;
-import android.database.sqlite.SQLiteDatabase;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IProgressListener;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.os.ServiceManager;
-import android.os.ShellCallback;
-import android.os.StrictMode;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.os.storage.IStorageManager;
-import android.os.storage.StorageManager;
-import android.provider.Settings;
-import android.provider.Settings.Secure;
-import android.provider.Settings.SettingNotFoundException;
-import android.security.GateKeeper;
-import android.security.KeyStore;
-import android.security.keystore.AndroidKeyStoreProvider;
-import android.security.keystore.KeyProperties;
-import android.security.keystore.KeyProtection;
-import android.service.gatekeeper.GateKeeperResponse;
-import android.service.gatekeeper.IGateKeeperService;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.internal.notification.SystemNotificationChannels;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.DumpUtils;
-import com.android.internal.widget.ICheckCredentialProgressCallback;
-import com.android.internal.widget.ILockSettings;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.VerifyCredentialResponse;
-import com.android.server.LockSettingsStorage.CredentialHash;
-import com.android.server.SyntheticPasswordManager.AuthenticationResult;
-import com.android.server.SyntheticPasswordManager.AuthenticationToken;
-
-import libcore.util.HexEncoding;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyStoreException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.KeyGenerator;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
-
-/**
- * Keeps the lock pattern/password data and related settings for each user. Used by
- * LockPatternUtils. Needs to be a service because Settings app also needs to be able to save
- * lockscreen information for secondary users.
- *
- * @hide
- */
-public class LockSettingsService extends ILockSettings.Stub {
-    private static final String TAG = "LockSettingsService";
-    private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE;
-    private static final boolean DEBUG = false;
-
-    private static final int PROFILE_KEY_IV_SIZE = 12;
-    private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
-
-    // Order of holding lock: mSeparateChallengeLock -> mSpManager -> this
-    private final Object mSeparateChallengeLock = new Object();
-
-    private final Injector mInjector;
-    private final Context mContext;
-    private final Handler mHandler;
-    @VisibleForTesting
-    protected final LockSettingsStorage mStorage;
-    private final LockSettingsStrongAuth mStrongAuth;
-    private final SynchronizedStrongAuthTracker mStrongAuthTracker;
-
-    private final LockPatternUtils mLockPatternUtils;
-    private final NotificationManager mNotificationManager;
-    private final UserManager mUserManager;
-    private final IActivityManager mActivityManager;
-
-    private final KeyStore mKeyStore;
-
-    private boolean mFirstCallToVold;
-    protected IGateKeeperService mGateKeeperService;
-    private SyntheticPasswordManager mSpManager;
-
-    /**
-     * The UIDs that are used for system credential storage in keystore.
-     */
-    private static final int[] SYSTEM_CREDENTIAL_UIDS = {
-            Process.WIFI_UID, Process.VPN_UID,
-            Process.ROOT_UID, Process.SYSTEM_UID };
-
-    // This class manages life cycle events for encrypted users on File Based Encryption (FBE)
-    // devices. The most basic of these is to show/hide notifications about missing features until
-    // the user unlocks the account and credential-encrypted storage is available.
-    public static final class Lifecycle extends SystemService {
-        private LockSettingsService mLockSettingsService;
-
-        public Lifecycle(Context context) {
-            super(context);
-        }
-
-        @Override
-        public void onStart() {
-            AndroidKeyStoreProvider.install();
-            mLockSettingsService = new LockSettingsService(getContext());
-            publishBinderService("lock_settings", mLockSettingsService);
-        }
-
-        @Override
-        public void onStartUser(int userHandle) {
-            mLockSettingsService.onStartUser(userHandle);
-        }
-
-        @Override
-        public void onUnlockUser(int userHandle) {
-            mLockSettingsService.onUnlockUser(userHandle);
-        }
-
-        @Override
-        public void onCleanupUser(int userHandle) {
-            mLockSettingsService.onCleanupUser(userHandle);
-        }
-    }
-
-    @VisibleForTesting
-    protected static class SynchronizedStrongAuthTracker
-            extends LockPatternUtils.StrongAuthTracker {
-        public SynchronizedStrongAuthTracker(Context context) {
-            super(context);
-        }
-
-        @Override
-        protected void handleStrongAuthRequiredChanged(int strongAuthFlags, int userId) {
-            synchronized (this) {
-                super.handleStrongAuthRequiredChanged(strongAuthFlags, userId);
-            }
-        }
-
-        @Override
-        public int getStrongAuthForUser(int userId) {
-            synchronized (this) {
-                return super.getStrongAuthForUser(userId);
-            }
-        }
-
-        void register(LockSettingsStrongAuth strongAuth) {
-            strongAuth.registerStrongAuthTracker(this.mStub);
-        }
-    }
-
-    /**
-     * Tie managed profile to primary profile if it is in unified mode and not tied before.
-     *
-     * @param managedUserId Managed profile user Id
-     * @param managedUserPassword Managed profile original password (when it has separated lock).
-     *            NULL when it does not have a separated lock before.
-     */
-    public void tieManagedProfileLockIfNecessary(int managedUserId, String managedUserPassword) {
-        if (DEBUG) Slog.v(TAG, "Check child profile lock for user: " + managedUserId);
-        // Only for managed profile
-        if (!mUserManager.getUserInfo(managedUserId).isManagedProfile()) {
-            return;
-        }
-        // Do not tie managed profile when work challenge is enabled
-        if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
-            return;
-        }
-        // Do not tie managed profile to parent when it's done already
-        if (mStorage.hasChildProfileLock(managedUserId)) {
-            return;
-        }
-        // Do not tie it to parent when parent does not have a screen lock
-        final int parentId = mUserManager.getProfileParent(managedUserId).id;
-        if (!isUserSecure(parentId)) {
-            if (DEBUG) Slog.v(TAG, "Parent does not have a screen lock");
-            return;
-        }
-        // Do not tie when the parent has no SID (but does have a screen lock).
-        // This can only happen during an upgrade path where SID is yet to be
-        // generated when the user unlocks for the first time.
-        try {
-            if (getGateKeeperService().getSecureUserId(parentId) == 0) {
-                return;
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to talk to GateKeeper service", e);
-            return;
-        }
-        if (DEBUG) Slog.v(TAG, "Tie managed profile to parent now!");
-        byte[] randomLockSeed = new byte[] {};
-        try {
-            randomLockSeed = SecureRandom.getInstance("SHA1PRNG").generateSeed(40);
-            String newPassword = String.valueOf(HexEncoding.encode(randomLockSeed));
-            setLockCredentialInternal(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    managedUserPassword, managedUserId);
-            // We store a private credential for the managed user that's unlocked by the primary
-            // account holder's credential. As such, the user will never be prompted to enter this
-            // password directly, so we always store a password.
-            setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                    DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, managedUserId);
-            tieProfileLockToParent(managedUserId, newPassword);
-        } catch (NoSuchAlgorithmException | RemoteException e) {
-            Slog.e(TAG, "Fail to tie managed profile", e);
-            // Nothing client can do to fix this issue, so we do not throw exception out
-        }
-    }
-
-    static class Injector {
-
-        protected Context mContext;
-
-        public Injector(Context context) {
-            mContext = context;
-        }
-
-        public Context getContext() {
-            return mContext;
-        }
-
-        public Handler getHandler() {
-            return new Handler();
-        }
-
-        public LockSettingsStorage getStorage() {
-            final LockSettingsStorage storage = new LockSettingsStorage(mContext);
-            storage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
-                @Override
-                public void initialize(SQLiteDatabase db) {
-                    // Get the lockscreen default from a system property, if available
-                    boolean lockScreenDisable = SystemProperties.getBoolean(
-                            "ro.lockscreen.disable.default", false);
-                    if (lockScreenDisable) {
-                        storage.writeKeyValue(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0);
-                    }
-                }
-            });
-            return storage;
-        }
-
-        public LockSettingsStrongAuth getStrongAuth() {
-            return new LockSettingsStrongAuth(mContext);
-        }
-
-        public SynchronizedStrongAuthTracker getStrongAuthTracker() {
-            return new SynchronizedStrongAuthTracker(mContext);
-        }
-
-        public IActivityManager getActivityManager() {
-            return ActivityManager.getService();
-        }
-
-        public LockPatternUtils getLockPatternUtils() {
-            return new LockPatternUtils(mContext);
-        }
-
-        public NotificationManager getNotificationManager() {
-            return (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
-        }
-
-        public UserManager getUserManager() {
-            return (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        }
-
-        public DevicePolicyManager getDevicePolicyManager() {
-            return (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-        }
-
-        public KeyStore getKeyStore() {
-            return KeyStore.getInstance();
-        }
-
-        public IStorageManager getStorageManager() {
-            final IBinder service = ServiceManager.getService("mount");
-            if (service != null) {
-                return IStorageManager.Stub.asInterface(service);
-            }
-            return null;
-        }
-
-        public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) {
-            return new SyntheticPasswordManager(storage);
-        }
-
-        public int binderGetCallingUid() {
-            return Binder.getCallingUid();
-        }
-    }
-
-    public LockSettingsService(Context context) {
-        this(new Injector(context));
-    }
-
-    @VisibleForTesting
-    protected LockSettingsService(Injector injector) {
-        mInjector = injector;
-        mContext = injector.getContext();
-        mKeyStore = injector.getKeyStore();
-        mHandler = injector.getHandler();
-        mStrongAuth = injector.getStrongAuth();
-        mActivityManager = injector.getActivityManager();
-
-        mLockPatternUtils = injector.getLockPatternUtils();
-        mFirstCallToVold = true;
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_USER_ADDED);
-        filter.addAction(Intent.ACTION_USER_STARTING);
-        filter.addAction(Intent.ACTION_USER_REMOVED);
-        injector.getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter,
-                null, null);
-
-        mStorage = injector.getStorage();
-        mNotificationManager = injector.getNotificationManager();
-        mUserManager = injector.getUserManager();
-        mStrongAuthTracker = injector.getStrongAuthTracker();
-        mStrongAuthTracker.register(mStrongAuth);
-
-        mSpManager = injector.getSyntheticPasswordManager(mStorage);
-    }
-
-    /**
-     * If the account is credential-encrypted, show notification requesting the user to unlock the
-     * device.
-     */
-    private void maybeShowEncryptionNotificationForUser(@UserIdInt int userId) {
-        final UserInfo user = mUserManager.getUserInfo(userId);
-        if (!user.isManagedProfile()) {
-            // When the user is locked, we communicate it loud-and-clear
-            // on the lockscreen; we only show a notification below for
-            // locked managed profiles.
-            return;
-        }
-
-        final UserHandle userHandle = user.getUserHandle();
-        final boolean isSecure = isUserSecure(userId);
-        if (isSecure && !mUserManager.isUserUnlockingOrUnlocked(userHandle)) {
-            UserInfo parent = mUserManager.getProfileParent(userId);
-            if (parent != null &&
-                    mUserManager.isUserUnlockingOrUnlocked(parent.getUserHandle()) &&
-                    !mUserManager.isQuietModeEnabled(userHandle)) {
-                // Only show notifications for managed profiles once their parent
-                // user is unlocked.
-                showEncryptionNotificationForProfile(userHandle);
-            }
-        }
-    }
-
-    private void showEncryptionNotificationForProfile(UserHandle user) {
-        Resources r = mContext.getResources();
-        CharSequence title = r.getText(
-                com.android.internal.R.string.user_encrypted_title);
-        CharSequence message = r.getText(
-                com.android.internal.R.string.profile_encrypted_message);
-        CharSequence detail = r.getText(
-                com.android.internal.R.string.profile_encrypted_detail);
-
-        final KeyguardManager km = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE);
-        final Intent unlockIntent = km.createConfirmDeviceCredentialIntent(null, null,
-                user.getIdentifier());
-        if (unlockIntent == null) {
-            return;
-        }
-        unlockIntent.setFlags(
-                Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-        PendingIntent intent = PendingIntent.getActivity(mContext, 0, unlockIntent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
-
-        showEncryptionNotification(user, title, message, detail, intent);
-    }
-
-    private void showEncryptionNotification(UserHandle user, CharSequence title,
-            CharSequence message, CharSequence detail, PendingIntent intent) {
-        if (DEBUG) Slog.v(TAG, "showing encryption notification, user: " + user.getIdentifier());
-
-        // Suppress all notifications on non-FBE devices for now
-        if (!StorageManager.isFileEncryptedNativeOrEmulated()) return;
-
-        Notification notification =
-                new Notification.Builder(mContext, SystemNotificationChannels.SECURITY)
-                        .setSmallIcon(com.android.internal.R.drawable.ic_user_secure)
-                        .setWhen(0)
-                        .setOngoing(true)
-                        .setTicker(title)
-                        .setColor(mContext.getColor(
-                                com.android.internal.R.color.system_notification_accent_color))
-                        .setContentTitle(title)
-                        .setContentText(message)
-                        .setSubText(detail)
-                        .setVisibility(Notification.VISIBILITY_PUBLIC)
-                        .setContentIntent(intent)
-                        .build();
-        mNotificationManager.notifyAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION,
-            notification, user);
-    }
-
-    private void hideEncryptionNotification(UserHandle userHandle) {
-        if (DEBUG) Slog.v(TAG, "hide encryption notification, user: " + userHandle.getIdentifier());
-        mNotificationManager.cancelAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION,
-            userHandle);
-    }
-
-    public void onCleanupUser(int userId) {
-        hideEncryptionNotification(new UserHandle(userId));
-    }
-
-    public void onStartUser(final int userId) {
-        maybeShowEncryptionNotificationForUser(userId);
-    }
-
-    public void onUnlockUser(final int userId) {
-        // Perform tasks which require locks in LSS on a handler, as we are callbacks from
-        // ActivityManager.unlockUser()
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                // Hide notification first, as tie managed profile lock takes time
-                hideEncryptionNotification(new UserHandle(userId));
-
-                // Now we have unlocked the parent user we should show notifications
-                // about any profiles that exist.
-                List<UserInfo> profiles = mUserManager.getProfiles(userId);
-                for (int i = 0; i < profiles.size(); i++) {
-                    UserInfo profile = profiles.get(i);
-                    final boolean isSecure = isUserSecure(profile.id);
-                    if (isSecure && profile.isManagedProfile()) {
-                        UserHandle userHandle = profile.getUserHandle();
-                        if (!mUserManager.isUserUnlockingOrUnlocked(userHandle) &&
-                                !mUserManager.isQuietModeEnabled(userHandle)) {
-                            showEncryptionNotificationForProfile(userHandle);
-                        }
-                    }
-                }
-
-                if (mUserManager.getUserInfo(userId).isManagedProfile()) {
-                    tieManagedProfileLockIfNecessary(userId, null);
-                }
-            }
-        });
-    }
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) {
-                // Notify keystore that a new user was added.
-                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                if (userHandle > UserHandle.USER_SYSTEM) {
-                    removeUser(userHandle, /* unknownUser= */ true);
-                }
-                final KeyStore ks = KeyStore.getInstance();
-                final UserInfo parentInfo = mUserManager.getProfileParent(userHandle);
-                final int parentHandle = parentInfo != null ? parentInfo.id : -1;
-                ks.onUserAdded(userHandle, parentHandle);
-            } else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
-                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                mStorage.prefetchUser(userHandle);
-            } else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
-                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                if (userHandle > 0) {
-                    removeUser(userHandle, /* unknownUser= */ false);
-                }
-            }
-        }
-    };
-
-    @Override // binder interface
-    public void systemReady() {
-        migrateOldData();
-        try {
-            getGateKeeperService();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failure retrieving IGateKeeperService", e);
-        }
-        // TODO: maybe skip this for split system user mode.
-        mStorage.prefetchUser(UserHandle.USER_SYSTEM);
-    }
-
-    private void migrateOldData() {
-        try {
-            // These Settings moved before multi-user was enabled, so we only have to do it for the
-            // root user.
-            if (getString("migrated", null, 0) == null) {
-                final ContentResolver cr = mContext.getContentResolver();
-                for (String validSetting : VALID_SETTINGS) {
-                    String value = Settings.Secure.getString(cr, validSetting);
-                    if (value != null) {
-                        setString(validSetting, value, 0);
-                    }
-                }
-                // No need to move the password / pattern files. They're already in the right place.
-                setString("migrated", "true", 0);
-                Slog.i(TAG, "Migrated lock settings to new location");
-            }
-
-            // These Settings changed after multi-user was enabled, hence need to be moved per user.
-            if (getString("migrated_user_specific", null, 0) == null) {
-                final ContentResolver cr = mContext.getContentResolver();
-                List<UserInfo> users = mUserManager.getUsers();
-                for (int user = 0; user < users.size(); user++) {
-                    // Migrate owner info
-                    final int userId = users.get(user).id;
-                    final String OWNER_INFO = Secure.LOCK_SCREEN_OWNER_INFO;
-                    String ownerInfo = Settings.Secure.getStringForUser(cr, OWNER_INFO, userId);
-                    if (!TextUtils.isEmpty(ownerInfo)) {
-                        setString(OWNER_INFO, ownerInfo, userId);
-                        Settings.Secure.putStringForUser(cr, OWNER_INFO, "", userId);
-                    }
-
-                    // Migrate owner info enabled. Note there was a bug where older platforms only
-                    // stored this value if the checkbox was toggled at least once. The code detects
-                    // this case by handling the exception.
-                    final String OWNER_INFO_ENABLED = Secure.LOCK_SCREEN_OWNER_INFO_ENABLED;
-                    boolean enabled;
-                    try {
-                        int ivalue = Settings.Secure.getIntForUser(cr, OWNER_INFO_ENABLED, userId);
-                        enabled = ivalue != 0;
-                        setLong(OWNER_INFO_ENABLED, enabled ? 1 : 0, userId);
-                    } catch (SettingNotFoundException e) {
-                        // Setting was never stored. Store it if the string is not empty.
-                        if (!TextUtils.isEmpty(ownerInfo)) {
-                            setLong(OWNER_INFO_ENABLED, 1, userId);
-                        }
-                    }
-                    Settings.Secure.putIntForUser(cr, OWNER_INFO_ENABLED, 0, userId);
-                }
-                // No need to move the password / pattern files. They're already in the right place.
-                setString("migrated_user_specific", "true", 0);
-                Slog.i(TAG, "Migrated per-user lock settings to new location");
-            }
-
-            // Migrates biometric weak such that the fallback mechanism becomes the primary.
-            if (getString("migrated_biometric_weak", null, 0) == null) {
-                List<UserInfo> users = mUserManager.getUsers();
-                for (int i = 0; i < users.size(); i++) {
-                    int userId = users.get(i).id;
-                    long type = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
-                            userId);
-                    long alternateType = getLong(LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
-                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
-                            userId);
-                    if (type == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) {
-                        setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                                alternateType,
-                                userId);
-                    }
-                    setLong(LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
-                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
-                            userId);
-                }
-                setString("migrated_biometric_weak", "true", 0);
-                Slog.i(TAG, "Migrated biometric weak to use the fallback instead");
-            }
-
-            // Migrates lockscreen.disabled. Prior to M, the flag was ignored when more than one
-            // user was present on the system, so if we're upgrading to M and there is more than one
-            // user we disable the flag to remain consistent.
-            if (getString("migrated_lockscreen_disabled", null, 0) == null) {
-                final List<UserInfo> users = mUserManager.getUsers();
-                final int userCount = users.size();
-                int switchableUsers = 0;
-                for (int i = 0; i < userCount; i++) {
-                    if (users.get(i).supportsSwitchTo()) {
-                        switchableUsers++;
-                    }
-                }
-
-                if (switchableUsers > 1) {
-                    for (int i = 0; i < userCount; i++) {
-                        int id = users.get(i).id;
-
-                        if (getBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id)) {
-                            setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
-                        }
-                    }
-                }
-
-                setString("migrated_lockscreen_disabled", "true", 0);
-                Slog.i(TAG, "Migrated lockscreen disabled flag");
-            }
-
-            final List<UserInfo> users = mUserManager.getUsers();
-            for (int i = 0; i < users.size(); i++) {
-                final UserInfo userInfo = users.get(i);
-                if (userInfo.isManagedProfile() && mStorage.hasChildProfileLock(userInfo.id)) {
-                    // When managed profile has a unified lock, the password quality stored has 2
-                    // possibilities only.
-                    // 1). PASSWORD_QUALITY_UNSPECIFIED, which is upgraded from dp2, and we are
-                    // going to set it back to PASSWORD_QUALITY_ALPHANUMERIC.
-                    // 2). PASSWORD_QUALITY_ALPHANUMERIC, which is the actual password quality for
-                    // unified lock.
-                    final long quality = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userInfo.id);
-                    if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
-                        // Only possible when it's upgraded from nyc dp3
-                        Slog.i(TAG, "Migrated tied profile lock type");
-                        setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                                DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, userInfo.id);
-                    } else if (quality != DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC) {
-                        // It should not happen
-                        Slog.e(TAG, "Invalid tied profile lock type: " + quality);
-                    }
-                }
-                try {
-                    final String alias = LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userInfo.id;
-                    java.security.KeyStore keyStore =
-                            java.security.KeyStore.getInstance("AndroidKeyStore");
-                    keyStore.load(null);
-                    if (keyStore.containsAlias(alias)) {
-                        keyStore.deleteEntry(alias);
-                    }
-                } catch (KeyStoreException | NoSuchAlgorithmException |
-                        CertificateException | IOException e) {
-                    Slog.e(TAG, "Unable to remove tied profile key", e);
-                }
-            }
-
-            boolean isWatch = mContext.getPackageManager().hasSystemFeature(
-                    PackageManager.FEATURE_WATCH);
-            // Wear used to set DISABLE_LOCKSCREEN to 'true', but because Wear now allows accounts
-            // and device management the lockscreen must be re-enabled now for users that upgrade.
-            if (isWatch && getString("migrated_wear_lockscreen_disabled", null, 0) == null) {
-                final int userCount = users.size();
-                for (int i = 0; i < userCount; i++) {
-                    int id = users.get(i).id;
-                    setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
-                }
-                setString("migrated_wear_lockscreen_disabled", "true", 0);
-                Slog.i(TAG, "Migrated lockscreen_disabled for Wear devices");
-            }
-        } catch (RemoteException re) {
-            Slog.e(TAG, "Unable to migrate old data", re);
-        }
-    }
-
-    private final void checkWritePermission(int userId) {
-        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsWrite");
-    }
-
-    private final void checkPasswordReadPermission(int userId) {
-        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsRead");
-    }
-
-    private final void checkReadPermission(String requestedKey, int userId) {
-        final int callingUid = Binder.getCallingUid();
-
-        for (int i = 0; i < READ_CONTACTS_PROTECTED_SETTINGS.length; i++) {
-            String key = READ_CONTACTS_PROTECTED_SETTINGS[i];
-            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_CONTACTS)
-                    != PackageManager.PERMISSION_GRANTED) {
-                throw new SecurityException("uid=" + callingUid
-                        + " needs permission " + READ_CONTACTS + " to read "
-                        + requestedKey + " for user " + userId);
-            }
-        }
-
-        for (int i = 0; i < READ_PASSWORD_PROTECTED_SETTINGS.length; i++) {
-            String key = READ_PASSWORD_PROTECTED_SETTINGS[i];
-            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(PERMISSION)
-                    != PackageManager.PERMISSION_GRANTED) {
-                throw new SecurityException("uid=" + callingUid
-                        + " needs permission " + PERMISSION + " to read "
-                        + requestedKey + " for user " + userId);
-            }
-        }
-    }
-
-    @Override
-    public boolean getSeparateProfileChallengeEnabled(int userId) throws RemoteException {
-        checkReadPermission(SEPARATE_PROFILE_CHALLENGE_KEY, userId);
-        synchronized (mSeparateChallengeLock) {
-            return getBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, false, userId);
-        }
-    }
-
-    @Override
-    public void setSeparateProfileChallengeEnabled(int userId, boolean enabled,
-            String managedUserPassword) throws RemoteException {
-        checkWritePermission(userId);
-        synchronized (mSeparateChallengeLock) {
-            setBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, enabled, userId);
-            if (enabled) {
-                mStorage.removeChildProfileLock(userId);
-                removeKeystoreProfileKey(userId);
-            } else {
-                tieManagedProfileLockIfNecessary(userId, managedUserPassword);
-            }
-        }
-    }
-
-    @Override
-    public void setBoolean(String key, boolean value, int userId) throws RemoteException {
-        checkWritePermission(userId);
-        setStringUnchecked(key, userId, value ? "1" : "0");
-    }
-
-    @Override
-    public void setLong(String key, long value, int userId) throws RemoteException {
-        checkWritePermission(userId);
-        setStringUnchecked(key, userId, Long.toString(value));
-    }
-
-    @Override
-    public void setString(String key, String value, int userId) throws RemoteException {
-        checkWritePermission(userId);
-        setStringUnchecked(key, userId, value);
-    }
-
-    private void setStringUnchecked(String key, int userId, String value) {
-        mStorage.writeKeyValue(key, value, userId);
-        if (ArrayUtils.contains(SETTINGS_TO_BACKUP, key)) {
-            BackupManager.dataChanged("com.android.providers.settings");
-        }
-    }
-
-    @Override
-    public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException {
-        checkReadPermission(key, userId);
-        String value = getStringUnchecked(key, null, userId);
-        return TextUtils.isEmpty(value) ?
-                defaultValue : (value.equals("1") || value.equals("true"));
-    }
-
-    @Override
-    public long getLong(String key, long defaultValue, int userId) throws RemoteException {
-        checkReadPermission(key, userId);
-        String value = getStringUnchecked(key, null, userId);
-        return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value);
-    }
-
-    @Override
-    public String getString(String key, String defaultValue, int userId) throws RemoteException {
-        checkReadPermission(key, userId);
-        return getStringUnchecked(key, defaultValue, userId);
-    }
-
-    public String getStringUnchecked(String key, String defaultValue, int userId) {
-        if (Settings.Secure.LOCK_PATTERN_ENABLED.equals(key)) {
-            long ident = Binder.clearCallingIdentity();
-            try {
-                return mLockPatternUtils.isLockPatternEnabled(userId) ? "1" : "0";
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
-
-        if (LockPatternUtils.LEGACY_LOCK_PATTERN_ENABLED.equals(key)) {
-            key = Settings.Secure.LOCK_PATTERN_ENABLED;
-        }
-
-        return mStorage.readKeyValue(key, defaultValue, userId);
-    }
-
-    @Override
-    public boolean havePassword(int userId) throws RemoteException {
-        synchronized (mSpManager) {
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                long handle = getSyntheticPasswordHandleLocked(userId);
-                return mSpManager.getCredentialType(handle, userId) ==
-                        LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
-            }
-        }
-        // Do we need a permissions check here?
-        return mStorage.hasPassword(userId);
-    }
-
-    @Override
-    public boolean havePattern(int userId) throws RemoteException {
-        synchronized (mSpManager) {
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                long handle = getSyntheticPasswordHandleLocked(userId);
-                return mSpManager.getCredentialType(handle, userId) ==
-                        LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
-            }
-        }
-        // Do we need a permissions check here?
-        return mStorage.hasPattern(userId);
-    }
-
-    private boolean isUserSecure(int userId) {
-        synchronized (mSpManager) {
-            try {
-                if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                    long handle = getSyntheticPasswordHandleLocked(userId);
-                    return mSpManager.getCredentialType(handle, userId) !=
-                            LockPatternUtils.CREDENTIAL_TYPE_NONE;
-                }
-            } catch (RemoteException e) {
-                // fall through
-            }
-        }
-        return mStorage.hasCredential(userId);
-    }
-
-    private void setKeystorePassword(String password, int userHandle) {
-        final KeyStore ks = KeyStore.getInstance();
-        ks.onUserPasswordChanged(userHandle, password);
-    }
-
-    private void unlockKeystore(String password, int userHandle) {
-        if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle);
-        final KeyStore ks = KeyStore.getInstance();
-        ks.unlock(userHandle, password);
-    }
-
-    @VisibleForTesting
-    protected String getDecryptedPasswordForTiedProfile(int userId)
-            throws KeyStoreException, UnrecoverableKeyException,
-            NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
-            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException,
-            CertificateException, IOException {
-        if (DEBUG) Slog.v(TAG, "Get child profile decrytped key");
-        byte[] storedData = mStorage.readChildProfileLock(userId);
-        if (storedData == null) {
-            throw new FileNotFoundException("Child profile lock file not found");
-        }
-        byte[] iv = Arrays.copyOfRange(storedData, 0, PROFILE_KEY_IV_SIZE);
-        byte[] encryptedPassword = Arrays.copyOfRange(storedData, PROFILE_KEY_IV_SIZE,
-                storedData.length);
-        byte[] decryptionResult;
-        java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
-        keyStore.load(null);
-        SecretKey decryptionKey = (SecretKey) keyStore.getKey(
-                LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId, null);
-
-        Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
-                + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
-
-        cipher.init(Cipher.DECRYPT_MODE, decryptionKey, new GCMParameterSpec(128, iv));
-        decryptionResult = cipher.doFinal(encryptedPassword);
-        return new String(decryptionResult, StandardCharsets.UTF_8);
-    }
-
-    private void unlockChildProfile(int profileHandle) throws RemoteException {
-        try {
-            doVerifyCredential(getDecryptedPasswordForTiedProfile(profileHandle),
-                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    false, 0 /* no challenge */, profileHandle, null /* progressCallback */);
-        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                | NoSuchAlgorithmException | NoSuchPaddingException
-                | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                | BadPaddingException | CertificateException | IOException e) {
-            if (e instanceof FileNotFoundException) {
-                Slog.i(TAG, "Child profile key not found");
-            } else {
-                Slog.e(TAG, "Failed to decrypt child profile key", e);
-            }
-        }
-    }
-
-    private void unlockUser(int userId, byte[] token, byte[] secret) {
-        // TODO: make this method fully async so we can update UI with progress strings
-        final CountDownLatch latch = new CountDownLatch(1);
-        final IProgressListener listener = new IProgressListener.Stub() {
-            @Override
-            public void onStarted(int id, Bundle extras) throws RemoteException {
-                Log.d(TAG, "unlockUser started");
-            }
-
-            @Override
-            public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
-                Log.d(TAG, "unlockUser progress " + progress);
-            }
-
-            @Override
-            public void onFinished(int id, Bundle extras) throws RemoteException {
-                Log.d(TAG, "unlockUser finished");
-                latch.countDown();
-            }
-        };
-
-        try {
-            mActivityManager.unlockUser(userId, token, secret, listener);
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        }
-
-        try {
-            latch.await(15, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-        }
-        try {
-            if (!mUserManager.getUserInfo(userId).isManagedProfile()) {
-                final List<UserInfo> profiles = mUserManager.getProfiles(userId);
-                for (UserInfo pi : profiles) {
-                    // Unlock managed profile with unified lock
-                    if (pi.isManagedProfile()
-                            && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
-                            && mStorage.hasChildProfileLock(pi.id)
-                            && mUserManager.isUserRunning(pi.id)) {
-                        unlockChildProfile(pi.id);
-                    }
-                }
-            }
-        } catch (RemoteException e) {
-            Log.d(TAG, "Failed to unlock child profile", e);
-        }
-    }
-
-    private Map<Integer, String> getDecryptedPasswordsForAllTiedProfiles(int userId) {
-        if (mUserManager.getUserInfo(userId).isManagedProfile()) {
-            return null;
-        }
-        Map<Integer, String> result = new ArrayMap<Integer, String>();
-        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
-        final int size = profiles.size();
-        for (int i = 0; i < size; i++) {
-            final UserInfo profile = profiles.get(i);
-            if (!profile.isManagedProfile()) {
-                continue;
-            }
-            final int managedUserId = profile.id;
-            if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
-                continue;
-            }
-            try {
-                result.put(userId, getDecryptedPasswordForTiedProfile(userId));
-            } catch (KeyStoreException | UnrecoverableKeyException | NoSuchAlgorithmException
-                    | NoSuchPaddingException | InvalidKeyException
-                    | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                    | BadPaddingException | CertificateException | IOException e) {
-                // ignore
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Synchronize all profile's work challenge of the given user if it's unified: tie or clear them
-     * depending on the parent user's secure state.
-     *
-     * When clearing tied work challenges, a pre-computed password table for profiles are required,
-     * since changing password for profiles requires existing password, and existing passwords can
-     * only be computed before the parent user's password is cleared.
-     *
-     * Strictly this is a recursive function, since setLockCredentialInternal ends up calling this
-     * method again on profiles. However the recursion is guaranteed to terminate as this method
-     * terminates when the user is a managed profile.
-     */
-    private void synchronizeUnifiedWorkChallengeForProfiles(int userId,
-            Map<Integer, String> profilePasswordMap) throws RemoteException {
-        if (mUserManager.getUserInfo(userId).isManagedProfile()) {
-            return;
-        }
-        final boolean isSecure = isUserSecure(userId);
-        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
-        final int size = profiles.size();
-        for (int i = 0; i < size; i++) {
-            final UserInfo profile = profiles.get(i);
-            if (profile.isManagedProfile()) {
-                final int managedUserId = profile.id;
-                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
-                    continue;
-                }
-                if (isSecure) {
-                    tieManagedProfileLockIfNecessary(managedUserId, null);
-                } else {
-                    // We use cached work profile password computed before clearing the parent's
-                    // credential, otherwise they get lost
-                    if (profilePasswordMap != null && profilePasswordMap.containsKey(managedUserId)) {
-                        setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
-                                profilePasswordMap.get(managedUserId), managedUserId);
-                    } else {
-                        Slog.wtf(TAG, "clear tied profile challenges, but no password supplied.");
-                        // Supplying null here would lead to untrusted credential change
-                        setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, null,
-                                managedUserId);
-                    }
-                    mStorage.removeChildProfileLock(managedUserId);
-                    removeKeystoreProfileKey(managedUserId);
-                }
-            }
-        }
-    }
-
-    private boolean isManagedProfileWithUnifiedLock(int userId) {
-        return mUserManager.getUserInfo(userId).isManagedProfile()
-                && !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
-    }
-
-    private boolean isManagedProfileWithSeparatedLock(int userId) {
-        return mUserManager.getUserInfo(userId).isManagedProfile()
-                && mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
-    }
-
-    // This method should be called by LockPatternUtil only, all internal methods in this class
-    // should call setLockCredentialInternal.
-    @Override
-    public void setLockCredential(String credential, int type, String savedCredential, int userId)
-            throws RemoteException {
-        checkWritePermission(userId);
-        synchronized (mSeparateChallengeLock) {
-            setLockCredentialInternal(credential, type, savedCredential, userId);
-            setSeparateProfileChallengeEnabled(userId, true, null);
-            notifyPasswordChanged(userId);
-        }
-    }
-
-    private void setLockCredentialInternal(String credential, int credentialType,
-            String savedCredential, int userId) throws RemoteException {
-        // Normalize savedCredential and credential such that empty string is always represented
-        // as null.
-        if (TextUtils.isEmpty(savedCredential)) {
-            savedCredential = null;
-        }
-        if (TextUtils.isEmpty(credential)) {
-            credential = null;
-        }
-        synchronized (mSpManager) {
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
-                        userId);
-                return;
-            }
-        }
-        if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-            if (credential != null) {
-                Slog.wtf(TAG, "CredentialType is none, but credential is non-null.");
-            }
-            clearUserKeyProtection(userId);
-            getGateKeeperService().clearSecureUserId(userId);
-            mStorage.writeCredentialHash(CredentialHash.createEmptyHash(), userId);
-            setKeystorePassword(null, userId);
-            fixateNewestUserKeyAuth(userId);
-            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
-            notifyActivePasswordMetricsAvailable(null, userId);
-            return;
-        }
-        if (credential == null) {
-            throw new RemoteException("Null credential with mismatched credential type");
-        }
-
-        CredentialHash currentHandle = mStorage.readCredentialHash(userId);
-        if (isManagedProfileWithUnifiedLock(userId)) {
-            // get credential from keystore when managed profile has unified lock
-            if (savedCredential == null) {
-                try {
-                    savedCredential = getDecryptedPasswordForTiedProfile(userId);
-                } catch (FileNotFoundException e) {
-                    Slog.i(TAG, "Child profile key not found");
-                } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                        | NoSuchAlgorithmException | NoSuchPaddingException
-                        | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                        | BadPaddingException | CertificateException | IOException e) {
-                    Slog.e(TAG, "Failed to decrypt child profile key", e);
-                }
-            }
-        } else {
-            if (currentHandle.hash == null) {
-                if (savedCredential != null) {
-                    Slog.w(TAG, "Saved credential provided, but none stored");
-                }
-                savedCredential = null;
-            }
-        }
-        synchronized (mSpManager) {
-            if (shouldMigrateToSyntheticPasswordLocked(userId)) {
-                initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential,
-                        currentHandle.type, userId);
-                spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
-                        userId);
-                return;
-            }
-        }
-        if (DEBUG) Slog.d(TAG, "setLockCredentialInternal: user=" + userId);
-        byte[] enrolledHandle = enrollCredential(currentHandle.hash, savedCredential, credential,
-                userId);
-        if (enrolledHandle != null) {
-            CredentialHash willStore = CredentialHash.create(enrolledHandle, credentialType);
-            mStorage.writeCredentialHash(willStore, userId);
-            // push new secret and auth token to vold
-            GateKeeperResponse gkResponse = getGateKeeperService()
-                    .verifyChallenge(userId, 0, willStore.hash, credential.getBytes());
-            setUserKeyProtection(userId, credential, convertResponse(gkResponse));
-            fixateNewestUserKeyAuth(userId);
-            // Refresh the auth token
-            doVerifyCredential(credential, credentialType, true, 0, userId, null /* progressCallback */);
-            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
-        } else {
-            throw new RemoteException("Failed to enroll " +
-                    (credentialType == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD ? "password"
-                            : "pattern"));
-        }
-    }
-
-    private VerifyCredentialResponse convertResponse(GateKeeperResponse gateKeeperResponse) {
-        VerifyCredentialResponse response;
-        int responseCode = gateKeeperResponse.getResponseCode();
-        if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
-            response = new VerifyCredentialResponse(gateKeeperResponse.getTimeout());
-        } else if (responseCode == GateKeeperResponse.RESPONSE_OK) {
-            byte[] token = gateKeeperResponse.getPayload();
-            if (token == null) {
-                // something's wrong if there's no payload with a challenge
-                Slog.e(TAG, "verifyChallenge response had no associated payload");
-                response = VerifyCredentialResponse.ERROR;
-            } else {
-                response = new VerifyCredentialResponse(token);
-            }
-        } else {
-            response = VerifyCredentialResponse.ERROR;
-        }
-        return response;
-    }
-
-    @VisibleForTesting
-    protected void tieProfileLockToParent(int userId, String password) {
-        if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId);
-        byte[] randomLockSeed = password.getBytes(StandardCharsets.UTF_8);
-        byte[] encryptionResult;
-        byte[] iv;
-        try {
-            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
-            keyGenerator.init(new SecureRandom());
-            SecretKey secretKey = keyGenerator.generateKey();
-            java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-            try {
-                keyStore.setEntry(
-                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId,
-                        new java.security.KeyStore.SecretKeyEntry(secretKey),
-                        new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
-                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
-                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
-                                .build());
-                keyStore.setEntry(
-                        LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId,
-                        new java.security.KeyStore.SecretKeyEntry(secretKey),
-                        new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
-                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
-                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
-                                .setUserAuthenticationRequired(true)
-                                .setUserAuthenticationValidityDurationSeconds(30)
-                                .build());
-                // Key imported, obtain a reference to it.
-                SecretKey keyStoreEncryptionKey = (SecretKey) keyStore.getKey(
-                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId, null);
-                Cipher cipher = Cipher.getInstance(
-                        KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
-                                + KeyProperties.ENCRYPTION_PADDING_NONE);
-                cipher.init(Cipher.ENCRYPT_MODE, keyStoreEncryptionKey);
-                encryptionResult = cipher.doFinal(randomLockSeed);
-                iv = cipher.getIV();
-            } finally {
-                // The original key can now be discarded.
-                keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId);
-            }
-        } catch (CertificateException | UnrecoverableKeyException
-                | IOException | BadPaddingException | IllegalBlockSizeException | KeyStoreException
-                | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
-            throw new RuntimeException("Failed to encrypt key", e);
-        }
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        try {
-            if (iv.length != PROFILE_KEY_IV_SIZE) {
-                throw new RuntimeException("Invalid iv length: " + iv.length);
-            }
-            outputStream.write(iv);
-            outputStream.write(encryptionResult);
-        } catch (IOException e) {
-            throw new RuntimeException("Failed to concatenate byte arrays", e);
-        }
-        mStorage.writeChildProfileLock(userId, outputStream.toByteArray());
-    }
-
-    private byte[] enrollCredential(byte[] enrolledHandle,
-            String enrolledCredential, String toEnroll, int userId)
-            throws RemoteException {
-        checkWritePermission(userId);
-        byte[] enrolledCredentialBytes = enrolledCredential == null
-                ? null
-                : enrolledCredential.getBytes();
-        byte[] toEnrollBytes = toEnroll == null
-                ? null
-                : toEnroll.getBytes();
-        GateKeeperResponse response = getGateKeeperService().enroll(userId, enrolledHandle,
-                enrolledCredentialBytes, toEnrollBytes);
-
-        if (response == null) {
-            return null;
-        }
-
-        byte[] hash = response.getPayload();
-        if (hash != null) {
-            setKeystorePassword(toEnroll, userId);
-        } else {
-            // Should not happen
-            Slog.e(TAG, "Throttled while enrolling a password");
-        }
-        return hash;
-    }
-
-    private void setAuthlessUserKeyProtection(int userId, byte[] key) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "setAuthlessUserKeyProtectiond: user=" + userId);
-        addUserKeyAuth(userId, null, key);
-    }
-
-    private void setUserKeyProtection(int userId, String credential, VerifyCredentialResponse vcr)
-            throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "setUserKeyProtection: user=" + userId);
-        if (vcr == null) {
-            throw new RemoteException("Null response verifying a credential we just set");
-        }
-        if (vcr.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
-            throw new RemoteException("Non-OK response verifying a credential we just set: "
-                    + vcr.getResponseCode());
-        }
-        byte[] token = vcr.getPayload();
-        if (token == null) {
-            throw new RemoteException("Empty payload verifying a credential we just set");
-        }
-        addUserKeyAuth(userId, token, secretFromCredential(credential));
-    }
-
-    private void clearUserKeyProtection(int userId) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "clearUserKeyProtection user=" + userId);
-        addUserKeyAuth(userId, null, null);
-    }
-
-    private static byte[] secretFromCredential(String credential) throws RemoteException {
-        try {
-            MessageDigest digest = MessageDigest.getInstance("SHA-512");
-            // Personalize the hash
-            byte[] personalization = "Android FBE credential hash"
-                    .getBytes(StandardCharsets.UTF_8);
-            // Pad it to the block size of the hash function
-            personalization = Arrays.copyOf(personalization, 128);
-            digest.update(personalization);
-            digest.update(credential.getBytes(StandardCharsets.UTF_8));
-            return digest.digest();
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("NoSuchAlgorithmException for SHA-512");
-        }
-    }
-
-    private void addUserKeyAuth(int userId, byte[] token, byte[] secret)
-            throws RemoteException {
-        final UserInfo userInfo = mUserManager.getUserInfo(userId);
-        final IStorageManager storageManager = mInjector.getStorageManager();
-        final long callingId = Binder.clearCallingIdentity();
-        try {
-            storageManager.addUserKeyAuth(userId, userInfo.serialNumber, token, secret);
-        } finally {
-            Binder.restoreCallingIdentity(callingId);
-        }
-    }
-
-    private void fixateNewestUserKeyAuth(int userId)
-            throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "fixateNewestUserKeyAuth: user=" + userId);
-        final IStorageManager storageManager = mInjector.getStorageManager();
-        final long callingId = Binder.clearCallingIdentity();
-        try {
-            storageManager.fixateNewestUserKeyAuth(userId);
-        } finally {
-            Binder.restoreCallingIdentity(callingId);
-        }
-    }
-
-    @Override
-    public void resetKeyStore(int userId) throws RemoteException {
-        checkWritePermission(userId);
-        if (DEBUG) Slog.v(TAG, "Reset keystore for user: " + userId);
-        int managedUserId = -1;
-        String managedUserDecryptedPassword = null;
-        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
-        for (UserInfo pi : profiles) {
-            // Unlock managed profile with unified lock
-            if (pi.isManagedProfile()
-                    && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
-                    && mStorage.hasChildProfileLock(pi.id)) {
-                try {
-                    if (managedUserId == -1) {
-                        managedUserDecryptedPassword = getDecryptedPasswordForTiedProfile(pi.id);
-                        managedUserId = pi.id;
-                    } else {
-                        // Should not happen
-                        Slog.e(TAG, "More than one managed profile, uid1:" + managedUserId
-                                + ", uid2:" + pi.id);
-                    }
-                } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                        | NoSuchAlgorithmException | NoSuchPaddingException
-                        | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                        | BadPaddingException | CertificateException | IOException e) {
-                    Slog.e(TAG, "Failed to decrypt child profile key", e);
-                }
-            }
-        }
-        try {
-            // Clear all the users credentials could have been installed in for this user.
-            for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) {
-                for (int uid : SYSTEM_CREDENTIAL_UIDS) {
-                    mKeyStore.clearUid(UserHandle.getUid(profileId, uid));
-                }
-            }
-        } finally {
-            if (managedUserId != -1 && managedUserDecryptedPassword != null) {
-                if (DEBUG) Slog.v(TAG, "Restore tied profile lock");
-                tieProfileLockToParent(managedUserId, managedUserDecryptedPassword);
-            }
-        }
-    }
-
-    @Override
-    public VerifyCredentialResponse checkCredential(String credential, int type, int userId,
-            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        checkPasswordReadPermission(userId);
-        return doVerifyCredential(credential, type, false, 0, userId, progressCallback);
-    }
-
-    @Override
-    public VerifyCredentialResponse verifyCredential(String credential, int type, long challenge,
-            int userId) throws RemoteException {
-        checkPasswordReadPermission(userId);
-        return doVerifyCredential(credential, type, true, challenge, userId,
-                null /* progressCallback */);
-    }
-
-    /**
-     * Verify user credential and unlock the user. Fix pattern bug by deprecating the old base zero
-     * format.
-     */
-    private VerifyCredentialResponse doVerifyCredential(String credential, int credentialType,
-            boolean hasChallenge, long challenge, int userId,
-            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        if (TextUtils.isEmpty(credential)) {
-            throw new IllegalArgumentException("Credential can't be null or empty");
-        }
-        synchronized (mSpManager) {
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                VerifyCredentialResponse response = spBasedDoVerifyCredentialLocked(credential,
-                        credentialType, hasChallenge, challenge, userId, progressCallback);
-                if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-                    mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
-                }
-                return response;
-            }
-        }
-        CredentialHash storedHash = mStorage.readCredentialHash(userId);
-        if (storedHash.type != credentialType) {
-            Slog.wtf(TAG, "doVerifyCredential type mismatch with stored credential??"
-                    + " stored: " + storedHash.type + " passed in: " + credentialType);
-            return VerifyCredentialResponse.ERROR;
-        }
-
-        boolean shouldReEnrollBaseZero = storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
-                && storedHash.isBaseZeroPattern;
-
-        String credentialToVerify;
-        if (shouldReEnrollBaseZero) {
-            credentialToVerify = LockPatternUtils.patternStringToBaseZero(credential);
-        } else {
-            credentialToVerify = credential;
-        }
-
-        VerifyCredentialResponse response = verifyCredential(userId, storedHash, credentialToVerify,
-                hasChallenge, challenge, progressCallback);
-
-        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-            mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
-            if (shouldReEnrollBaseZero) {
-                setLockCredentialInternal(credential, storedHash.type, credentialToVerify, userId);
-            }
-        }
-
-        return response;
-    }
-
-    @Override
-    public VerifyCredentialResponse verifyTiedProfileChallenge(String credential, int type,
-            long challenge, int userId) throws RemoteException {
-        checkPasswordReadPermission(userId);
-        if (!isManagedProfileWithUnifiedLock(userId)) {
-            throw new RemoteException("User id must be managed profile with unified lock");
-        }
-        final int parentProfileId = mUserManager.getProfileParent(userId).id;
-        // Unlock parent by using parent's challenge
-        final VerifyCredentialResponse parentResponse = doVerifyCredential(
-                credential,
-                type,
-                true /* hasChallenge */,
-                challenge,
-                parentProfileId,
-                null /* progressCallback */);
-        if (parentResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
-            // Failed, just return parent's response
-            return parentResponse;
-        }
-
-        try {
-            // Unlock work profile, and work profile with unified lock must use password only
-            return doVerifyCredential(getDecryptedPasswordForTiedProfile(userId),
-                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    true,
-                    challenge,
-                    userId, null /* progressCallback */);
-        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                | NoSuchAlgorithmException | NoSuchPaddingException
-                | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                | BadPaddingException | CertificateException | IOException e) {
-            Slog.e(TAG, "Failed to decrypt child profile key", e);
-            throw new RemoteException("Unable to get tied profile token");
-        }
-    }
-
-    /**
-     * Lowest-level credential verification routine that talks to GateKeeper. If verification
-     * passes, unlock the corresponding user and keystore. Also handles the migration from legacy
-     * hash to GK.
-     */
-    private VerifyCredentialResponse verifyCredential(int userId, CredentialHash storedHash,
-            String credential, boolean hasChallenge, long challenge,
-            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        if ((storedHash == null || storedHash.hash.length == 0) && TextUtils.isEmpty(credential)) {
-            // don't need to pass empty credentials to GateKeeper
-            return VerifyCredentialResponse.OK;
-        }
-
-        if (storedHash == null || TextUtils.isEmpty(credential)) {
-            return VerifyCredentialResponse.ERROR;
-        }
-
-        // We're potentially going to be doing a bunch of disk I/O below as part
-        // of unlocking the user, so yell if calling from the main thread.
-        StrictMode.noteDiskRead();
-
-        if (storedHash.version == CredentialHash.VERSION_LEGACY) {
-            final byte[] hash;
-            if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
-                hash = LockPatternUtils.patternToHash(LockPatternUtils.stringToPattern(credential));
-            } else {
-                hash = mLockPatternUtils.passwordToHash(credential, userId);
-            }
-            if (Arrays.equals(hash, storedHash.hash)) {
-                if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
-                    unlockKeystore(LockPatternUtils.patternStringToBaseZero(credential), userId);
-                } else {
-                    unlockKeystore(credential, userId);
-                }
-                // Users with legacy credentials don't have credential-backed
-                // FBE keys, so just pass through a fake token/secret
-                Slog.i(TAG, "Unlocking user with fake token: " + userId);
-                final byte[] fakeToken = String.valueOf(userId).getBytes();
-                unlockUser(userId, fakeToken, fakeToken);
-
-                // migrate credential to GateKeeper
-                setLockCredentialInternal(credential, storedHash.type, null, userId);
-                if (!hasChallenge) {
-                    notifyActivePasswordMetricsAvailable(credential, userId);
-                    return VerifyCredentialResponse.OK;
-                }
-                // Fall through to get the auth token. Technically this should never happen,
-                // as a user that had a legacy credential would have to unlock their device
-                // before getting to a flow with a challenge, but supporting for consistency.
-            } else {
-                return VerifyCredentialResponse.ERROR;
-            }
-        }
-        GateKeeperResponse gateKeeperResponse = getGateKeeperService()
-                .verifyChallenge(userId, challenge, storedHash.hash, credential.getBytes());
-        VerifyCredentialResponse response = convertResponse(gateKeeperResponse);
-        boolean shouldReEnroll = gateKeeperResponse.getShouldReEnroll();
-
-        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-
-            // credential has matched
-
-            if (progressCallback != null) {
-                progressCallback.onCredentialVerified();
-            }
-            notifyActivePasswordMetricsAvailable(credential, userId);
-            unlockKeystore(credential, userId);
-
-            Slog.i(TAG, "Unlocking user " + userId + " with token length "
-                    + response.getPayload().length);
-            unlockUser(userId, response.getPayload(), secretFromCredential(credential));
-
-            if (isManagedProfileWithSeparatedLock(userId)) {
-                TrustManager trustManager =
-                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
-                trustManager.setDeviceLockedForUser(userId, false);
-            }
-            if (shouldReEnroll) {
-                setLockCredentialInternal(credential, storedHash.type, credential, userId);
-            } else {
-                // Now that we've cleared of all required GK migration, let's do the final
-                // migration to synthetic password.
-                synchronized (mSpManager) {
-                    if (shouldMigrateToSyntheticPasswordLocked(userId)) {
-                        AuthenticationToken auth = initializeSyntheticPasswordLocked(
-                                storedHash.hash, credential, storedHash.type, userId);
-                        activateEscrowTokens(auth, userId);
-                    }
-                }
-            }
-        } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
-            if (response.getTimeout() > 0) {
-                requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
-            }
-        }
-
-        return response;
-    }
-
-    private void notifyActivePasswordMetricsAvailable(String password, @UserIdInt int userId) {
-        final PasswordMetrics metrics;
-        if (password == null) {
-            metrics = new PasswordMetrics();
-        } else {
-            metrics = PasswordMetrics.computeForPassword(password);
-            metrics.quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(userId);
-        }
-
-        // Asynchronous to avoid dead lock
-        mHandler.post(() -> {
-            DevicePolicyManager dpm = (DevicePolicyManager)
-                    mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-            dpm.setActivePasswordState(metrics, userId);
-        });
-    }
-
-    /**
-     * Call after {@link #notifyActivePasswordMetricsAvailable} so metrics are updated before
-     * reporting the password changed.
-     */
-    private void notifyPasswordChanged(@UserIdInt int userId) {
-        // Same handler as notifyActivePasswordMetricsAvailable to ensure correct ordering
-        mHandler.post(() -> {
-            DevicePolicyManager dpm = (DevicePolicyManager)
-                    mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-            dpm.reportPasswordChanged(userId);
-        });
-    }
-
-    @Override
-    public boolean checkVoldPassword(int userId) throws RemoteException {
-        if (!mFirstCallToVold) {
-            return false;
-        }
-        mFirstCallToVold = false;
-
-        checkPasswordReadPermission(userId);
-
-        // There's no guarantee that this will safely connect, but if it fails
-        // we will simply show the lock screen when we shouldn't, so relatively
-        // benign. There is an outside chance something nasty would happen if
-        // this service restarted before vold stales out the password in this
-        // case. The nastiness is limited to not showing the lock screen when
-        // we should, within the first minute of decrypting the phone if this
-        // service can't connect to vold, it restarts, and then the new instance
-        // does successfully connect.
-        final IStorageManager service = mInjector.getStorageManager();
-        String password;
-        long identity = Binder.clearCallingIdentity();
-        try {
-            password = service.getPassword();
-            service.clearPassword();
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-        if (password == null) {
-            return false;
-        }
-
-        try {
-            if (mLockPatternUtils.isLockPatternEnabled(userId)) {
-                if (checkCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, userId,
-                        null /* progressCallback */)
-                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
-                    return true;
-                }
-            }
-        } catch (Exception e) {
-        }
-
-        try {
-            if (mLockPatternUtils.isLockPasswordEnabled(userId)) {
-                if (checkCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, userId,
-                        null /* progressCallback */)
-                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
-                    return true;
-                }
-            }
-        } catch (Exception e) {
-        }
-
-        return false;
-    }
-
-    private void removeUser(int userId, boolean unknownUser) {
-        mStorage.removeUser(userId);
-        mStrongAuth.removeUser(userId);
-
-        final KeyStore ks = KeyStore.getInstance();
-        ks.onUserRemoved(userId);
-
-        try {
-            final IGateKeeperService gk = getGateKeeperService();
-            if (gk != null) {
-                gk.clearSecureUserId(userId);
-            }
-        } catch (RemoteException ex) {
-            Slog.w(TAG, "unable to clear GK secure user id");
-        }
-        if (unknownUser || mUserManager.getUserInfo(userId).isManagedProfile()) {
-            removeKeystoreProfileKey(userId);
-        }
-    }
-
-    private void removeKeystoreProfileKey(int targetUserId) {
-        if (DEBUG) Slog.v(TAG, "Remove keystore profile key for user: " + targetUserId);
-        try {
-            java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + targetUserId);
-            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + targetUserId);
-        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
-                | IOException e) {
-            // We have tried our best to remove all keys
-            Slog.e(TAG, "Unable to remove keystore profile key for user:" + targetUserId, e);
-        }
-    }
-
-    @Override
-    public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
-        checkPasswordReadPermission(UserHandle.USER_ALL);
-        mStrongAuth.registerStrongAuthTracker(tracker);
-    }
-
-    @Override
-    public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
-        checkPasswordReadPermission(UserHandle.USER_ALL);
-        mStrongAuth.unregisterStrongAuthTracker(tracker);
-    }
-
-    @Override
-    public void requireStrongAuth(int strongAuthReason, int userId) {
-        checkWritePermission(userId);
-        mStrongAuth.requireStrongAuth(strongAuthReason, userId);
-    }
-
-    @Override
-    public void userPresent(int userId) {
-        checkWritePermission(userId);
-        mStrongAuth.reportUnlock(userId);
-    }
-
-    @Override
-    public int getStrongAuthForUser(int userId) {
-        checkPasswordReadPermission(userId);
-        return mStrongAuthTracker.getStrongAuthForUser(userId);
-    }
-
-    private boolean isCallerShell() {
-        final int callingUid = Binder.getCallingUid();
-        return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID;
-    }
-
-    private void enforceShell() {
-        if (!isCallerShell()) {
-            throw new SecurityException("Caller must be shell");
-        }
-    }
-
-    @Override
-    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
-            String[] args, ShellCallback callback, ResultReceiver resultReceiver)
-            throws RemoteException {
-        enforceShell();
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            (new LockSettingsShellCommand(mContext, new LockPatternUtils(mContext))).exec(
-                    this, in, out, err, args, callback, resultReceiver);
-        } finally {
-            Binder.restoreCallingIdentity(origId);
-        }
-    }
-
-    private static final String[] VALID_SETTINGS = new String[] {
-            LockPatternUtils.LOCKOUT_PERMANENT_KEY,
-            LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
-            LockPatternUtils.PATTERN_EVER_CHOSEN_KEY,
-            LockPatternUtils.PASSWORD_TYPE_KEY,
-            LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
-            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
-            LockPatternUtils.DISABLE_LOCKSCREEN_KEY,
-            LockPatternUtils.LOCKSCREEN_OPTIONS,
-            LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
-            LockPatternUtils.BIOMETRIC_WEAK_EVER_CHOSEN_KEY,
-            LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS,
-            LockPatternUtils.PASSWORD_HISTORY_KEY,
-            Secure.LOCK_PATTERN_ENABLED,
-            Secure.LOCK_BIOMETRIC_WEAK_FLAGS,
-            Secure.LOCK_PATTERN_VISIBLE,
-            Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED
-    };
-
-    // Reading these settings needs the contacts permission
-    private static final String[] READ_CONTACTS_PROTECTED_SETTINGS = new String[] {
-            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
-            Secure.LOCK_SCREEN_OWNER_INFO
-    };
-
-    // Reading these settings needs the same permission as checking the password
-    private static final String[] READ_PASSWORD_PROTECTED_SETTINGS = new String[] {
-            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
-            LockPatternUtils.PASSWORD_HISTORY_KEY,
-            LockPatternUtils.PASSWORD_TYPE_KEY,
-            SEPARATE_PROFILE_CHALLENGE_KEY
-    };
-
-    private static final String[] SETTINGS_TO_BACKUP = new String[] {
-            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
-            Secure.LOCK_SCREEN_OWNER_INFO
-    };
-
-    private class GateKeeperDiedRecipient implements IBinder.DeathRecipient {
-        @Override
-        public void binderDied() {
-            mGateKeeperService.asBinder().unlinkToDeath(this, 0);
-            mGateKeeperService = null;
-        }
-    }
-
-    protected synchronized IGateKeeperService getGateKeeperService()
-            throws RemoteException {
-        if (mGateKeeperService != null) {
-            return mGateKeeperService;
-        }
-
-        final IBinder service = ServiceManager.getService(Context.GATEKEEPER_SERVICE);
-        if (service != null) {
-            service.linkToDeath(new GateKeeperDiedRecipient(), 0);
-            mGateKeeperService = IGateKeeperService.Stub.asInterface(service);
-            return mGateKeeperService;
-        }
-
-        Slog.e(TAG, "Unable to acquire GateKeeperService");
-        return null;
-    }
-
-    /**
-     * Precondition: vold and keystore unlocked.
-     *
-     * Create new synthetic password, set up synthetic password blob protected by the supplied
-     * user credential, and make the newly-created SP blob active.
-     *
-     * The invariant under a synthetic password is:
-     * 1. If user credential exists, then both vold and keystore and protected with keys derived
-     *     from the synthetic password.
-     * 2. If user credential does not exist, vold and keystore protection are cleared. This is to
-     *     make it consistent with current behaviour. It also allows ActivityManager to call
-     *     unlockUser() with empty secret.
-     * 3. Once a user is migrated to have synthetic password, its value will never change, no matter
-     *     whether the user changes his lockscreen PIN or clear/reset it. When the user clears its
-     *     lockscreen PIN, we still maintain the existing synthetic password in a password blob
-     *     protected by a default PIN. The only exception is when the DPC performs an untrusted
-     *     credential change, in which case we have no way to derive the existing synthetic password
-     *     and has to create a new one.
-     * 4. The user SID is linked with synthetic password, but its cleared/re-created when the user
-     *     clears/re-creates his lockscreen PIN.
-     *
-     *
-     * Different cases of calling this method:
-     * 1. credentialHash != null
-     *     This implies credential != null, a new SP blob will be provisioned, and existing SID
-     *     migrated to associate with the new SP.
-     *     This happens during a normal migration case when the user currently has password.
-     *
-     * 2. credentialhash == null and credential == null
-     *     A new SP blob and a new SID will be created, while the user has no credentials.
-     *     This can happens when we are activating an escrow token on a unsecured device, during
-     *     which we want to create the SP structure with an empty user credential.
-     *
-     * 3. credentialhash == null and credential != null
-     *     This is the untrusted credential reset, OR the user sets a new lockscreen password
-     *     FOR THE FIRST TIME on a SP-enabled device. New credential and new SID will be created
-     */
-    private AuthenticationToken initializeSyntheticPasswordLocked(byte[] credentialHash,
-            String credential, int credentialType, int userId) throws RemoteException {
-        Slog.i(TAG, "Initialize SyntheticPassword for user: " + userId);
-        AuthenticationToken auth = mSpManager.newSyntheticPasswordAndSid(getGateKeeperService(),
-                credentialHash, credential, userId);
-        if (auth == null) {
-            Slog.wtf(TAG, "initializeSyntheticPasswordLocked returns null auth token");
-            return null;
-        }
-        long handle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
-                credential, credentialType, auth, userId);
-        if (credential != null) {
-            if (credentialHash == null) {
-                // Since when initializing SP, we didn't provide an existing password handle
-                // for it to migrate SID, we need to create a new SID for the user.
-                mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
-            }
-            mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
-            setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
-            setKeystorePassword(auth.deriveKeyStorePassword(), userId);
-        } else {
-            clearUserKeyProtection(userId);
-            setKeystorePassword(null, userId);
-            getGateKeeperService().clearSecureUserId(userId);
-        }
-        fixateNewestUserKeyAuth(userId);
-        setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, handle, userId);
-        return auth;
-    }
-
-    private long getSyntheticPasswordHandleLocked(int userId) {
-        try {
-            return getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId);
-        } catch (RemoteException e) {
-            return SyntheticPasswordManager.DEFAULT_HANDLE;
-        }
-    }
-
-    private boolean isSyntheticPasswordBasedCredentialLocked(int userId) throws RemoteException {
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        // This is a global setting
-        long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
-      return enabled != 0 && handle != SyntheticPasswordManager.DEFAULT_HANDLE;
-    }
-
-    private boolean shouldMigrateToSyntheticPasswordLocked(int userId) throws RemoteException {
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        // This is a global setting
-        long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
-        return enabled != 0 && handle == SyntheticPasswordManager.DEFAULT_HANDLE;
-    }
-
-    private void enableSyntheticPasswordLocked() throws RemoteException {
-        setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
-    }
-
-    private VerifyCredentialResponse spBasedDoVerifyCredentialLocked(String userCredential, int
-            credentialType, boolean hasChallenge, long challenge, int userId,
-            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredentialLocked: user=" + userId);
-        if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-            userCredential = null;
-        }
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
-                getGateKeeperService(), handle, userCredential, userId);
-
-        VerifyCredentialResponse response = authResult.gkResponse;
-        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-            // credential has matched
-            // perform verifyChallenge with synthetic password which generates the real auth
-            // token for the current user
-            response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken,
-                    challenge, userId);
-            if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
-                Slog.wtf(TAG, "verifyChallenge with SP failed.");
-                return VerifyCredentialResponse.ERROR;
-            }
-            if (progressCallback != null) {
-                progressCallback.onCredentialVerified();
-            }
-            notifyActivePasswordMetricsAvailable(userCredential, userId);
-            unlockKeystore(authResult.authToken.deriveKeyStorePassword(), userId);
-
-            final byte[] secret = authResult.authToken.deriveDiskEncryptionKey();
-            Slog.i(TAG, "Unlocking user " + userId + " with secret only, length " + secret.length);
-            unlockUser(userId, null, secret);
-
-            if (isManagedProfileWithSeparatedLock(userId)) {
-                TrustManager trustManager =
-                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
-                trustManager.setDeviceLockedForUser(userId, false);
-            }
-            activateEscrowTokens(authResult.authToken, userId);
-        } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
-            if (response.getTimeout() > 0) {
-                requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
-            }
-        }
-
-        return response;
-    }
-
-    /**
-     * Change the user's lockscreen password by creating a new SP blob and update the handle, based
-     * on an existing authentication token. Even though a new SP blob is created, the underlying
-     * synthetic password is never changed.
-     *
-     * When clearing credential, we keep the SP unchanged, but clear its password handle so its
-     * SID is gone. We also clear password from (software-based) keystore and vold, which will be
-     * added back when new password is set in future.
-     */
-    private long setLockCredentialWithAuthTokenLocked(String credential, int credentialType,
-            AuthenticationToken auth, int userId) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "setLockCredentialWithAuthTokenLocked: user=" + userId);
-        long newHandle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
-                credential, credentialType, auth, userId);
-        final Map<Integer, String> profilePasswords;
-        if (credential != null) {
-            // // not needed by synchronizeUnifiedWorkChallengeForProfiles()
-            profilePasswords = null;
-
-            if (mSpManager.hasSidForUser(userId)) {
-                // We are changing password of a secured device, nothing more needed as
-                // createPasswordBasedSyntheticPassword has already taken care of maintaining
-                // the password handle and SID unchanged.
-
-                //refresh auth token
-                mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
-            } else {
-                // A new password is set on a previously-unsecured device, we need to generate
-                // a new SID, and re-add keys to vold and keystore.
-                mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
-                mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
-                setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
-                fixateNewestUserKeyAuth(userId);
-                setKeystorePassword(auth.deriveKeyStorePassword(), userId);
-            }
-        } else {
-            // Cache all profile password if they use unified work challenge. This will later be
-            // used to clear the profile's password in synchronizeUnifiedWorkChallengeForProfiles()
-            profilePasswords = getDecryptedPasswordsForAllTiedProfiles(userId);
-
-            // we are clearing password of a secured device, so need to nuke SID as well.
-            mSpManager.clearSidForUser(userId);
-            getGateKeeperService().clearSecureUserId(userId);
-            // Clear key from vold so ActivityManager can just unlock the user with empty secret
-            // during boot.
-            clearUserKeyProtection(userId);
-            fixateNewestUserKeyAuth(userId);
-            setKeystorePassword(null, userId);
-        }
-        setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, newHandle, userId);
-        synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords);
-        return newHandle;
-    }
-
-    private void spBasedSetLockCredentialInternalLocked(String credential, int credentialType,
-            String savedCredential, int userId) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "spBasedSetLockCredentialInternalLocked: user=" + userId);
-        if (isManagedProfileWithUnifiedLock(userId)) {
-            // get credential from keystore when managed profile has unified lock
-            try {
-                savedCredential = getDecryptedPasswordForTiedProfile(userId);
-            } catch (FileNotFoundException e) {
-                Slog.i(TAG, "Child profile key not found");
-            } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                    | NoSuchAlgorithmException | NoSuchPaddingException
-                    | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                    | BadPaddingException | CertificateException | IOException e) {
-                Slog.e(TAG, "Failed to decrypt child profile key", e);
-            }
-        }
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
-                getGateKeeperService(), handle, savedCredential, userId);
-        VerifyCredentialResponse response = authResult.gkResponse;
-        AuthenticationToken auth = authResult.authToken;
-        if (auth != null) {
-            // We are performing a trusted credential change i.e. a correct existing credential
-            // is provided
-            setLockCredentialWithAuthTokenLocked(credential, credentialType, auth, userId);
-            mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId);
-        } else if (response != null
-                && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR){
-            // We are performing an untrusted credential change i.e. by DevicePolicyManager.
-            // So provision a new SP and SID. This would invalidate existing escrow tokens.
-            // Still support this for now but this flow will be removed in the next release.
-
-            Slog.w(TAG, "Untrusted credential change invoked");
-            initializeSyntheticPasswordLocked(null, credential, credentialType, userId);
-            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
-            mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId);
-        } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ {
-            Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " +
-                    (response != null ? "rate limit exceeded" : "failed"));
-            return;
-        }
-        notifyActivePasswordMetricsAvailable(credential, userId);
-
-    }
-
-    @Override
-    public long addEscrowToken(byte[] token, int userId) throws RemoteException {
-        ensureCallerSystemUid();
-        if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId);
-        synchronized (mSpManager) {
-            enableSyntheticPasswordLocked();
-            // Migrate to synthetic password based credentials if the user has no password,
-            // the token can then be activated immediately.
-            AuthenticationToken auth = null;
-            if (!isUserSecure(userId)) {
-                if (shouldMigrateToSyntheticPasswordLocked(userId)) {
-                    auth = initializeSyntheticPasswordLocked(null, null,
-                            LockPatternUtils.CREDENTIAL_TYPE_NONE, userId);
-                } else /* isSyntheticPasswordBasedCredentialLocked(userId) */ {
-                    long pwdHandle = getSyntheticPasswordHandleLocked(userId);
-                    auth = mSpManager.unwrapPasswordBasedSyntheticPassword(getGateKeeperService(),
-                            pwdHandle, null, userId).authToken;
-                }
-            }
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
-                if (!mSpManager.hasEscrowData(userId)) {
-                    throw new SecurityException("Escrow token is disabled on the current user");
-                }
-            }
-            long handle = mSpManager.createTokenBasedSyntheticPassword(token, userId);
-            if (auth != null) {
-                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
-            }
-            return handle;
-        }
-    }
-
-    private void activateEscrowTokens(AuthenticationToken auth, int userId) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId);
-        disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
-        synchronized (mSpManager) {
-            for (long handle : mSpManager.getPendingTokensForUser(userId)) {
-                Slog.i(TAG, String.format("activateEscrowTokens: %x %d ", handle, userId));
-                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
-            }
-        }
-    }
-
-    @Override
-    public boolean isEscrowTokenActive(long handle, int userId) throws RemoteException {
-        ensureCallerSystemUid();
-        synchronized (mSpManager) {
-            return mSpManager.existsHandle(handle, userId);
-        }
-    }
-
-    @Override
-    public boolean removeEscrowToken(long handle, int userId) throws RemoteException {
-        ensureCallerSystemUid();
-        synchronized (mSpManager) {
-            if (handle == getSyntheticPasswordHandleLocked(userId)) {
-                Slog.w(TAG, "Cannot remove password handle");
-                return false;
-            }
-            if (mSpManager.removePendingToken(handle, userId)) {
-                return true;
-            }
-            if (mSpManager.existsHandle(handle, userId)) {
-                mSpManager.destroyTokenBasedSyntheticPassword(handle, userId);
-                return true;
-            } else {
-                return false;
-            }
-        }
-    }
-
-    @Override
-    public boolean setLockCredentialWithToken(String credential, int type, long tokenHandle,
-            byte[] token, int userId) throws RemoteException {
-        ensureCallerSystemUid();
-        boolean result;
-        synchronized (mSpManager) {
-            if (!mSpManager.hasEscrowData(userId)) {
-                throw new SecurityException("Escrow token is disabled on the current user");
-            }
-            result = setLockCredentialWithTokenInternal(credential, type, tokenHandle, token,
-                    userId);
-        }
-        if (result) {
-            synchronized (mSeparateChallengeLock) {
-                setSeparateProfileChallengeEnabled(userId, true, null);
-            }
-            notifyPasswordChanged(userId);
-        }
-        return result;
-    }
-
-    private boolean setLockCredentialWithTokenInternal(String credential, int type,
-            long tokenHandle, byte[] token, int userId) throws RemoteException {
-        synchronized (mSpManager) {
-            AuthenticationResult result = mSpManager.unwrapTokenBasedSyntheticPassword(
-                    getGateKeeperService(), tokenHandle, token, userId);
-            if (result.authToken == null) {
-                Slog.w(TAG, "Invalid escrow token supplied");
-                return false;
-            }
-            long oldHandle = getSyntheticPasswordHandleLocked(userId);
-            setLockCredentialWithAuthTokenLocked(credential, type, result.authToken, userId);
-            mSpManager.destroyPasswordBasedSyntheticPassword(oldHandle, userId);
-            return true;
-        }
-    }
-
-    @Override
-    public void unlockUserWithToken(long tokenHandle, byte[] token, int userId)
-            throws RemoteException {
-        ensureCallerSystemUid();
-        AuthenticationResult authResult;
-        synchronized (mSpManager) {
-            if (!mSpManager.hasEscrowData(userId)) {
-                throw new SecurityException("Escrow token is disabled on the current user");
-            }
-            authResult = mSpManager.unwrapTokenBasedSyntheticPassword(getGateKeeperService(),
-                    tokenHandle, token, userId);
-            if (authResult.authToken == null) {
-                Slog.w(TAG, "Invalid escrow token supplied");
-                return;
-            }
-        }
-        unlockUser(userId, null, authResult.authToken.deriveDiskEncryptionKey());
-    }
-
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args){
-        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
-
-        pw.println("Current lock settings service state:");
-        pw.println(String.format("SP Enabled = %b",
-                mLockPatternUtils.isSyntheticPasswordEnabled()));
-
-        List<UserInfo> users = mUserManager.getUsers();
-        for (int user = 0; user < users.size(); user++) {
-            final int userId = users.get(user).id;
-            pw.println("    User " + userId);
-            synchronized (mSpManager) {
-                pw.println(String.format("        SP Handle = %x",
-                        getSyntheticPasswordHandleLocked(userId)));
-            }
-            try {
-                pw.println(String.format("        SID = %x",
-                        getGateKeeperService().getSecureUserId(userId)));
-            } catch (RemoteException e) {
-                // ignore.
-            }
-        }
-    }
-
-    private void disableEscrowTokenOnNonManagedDevicesIfNeeded(int userId) {
-        long ident = Binder.clearCallingIdentity();
-        try {
-            // Managed profile should have escrow enabled
-            if (mUserManager.getUserInfo(userId).isManagedProfile()) {
-                Slog.i(TAG, "Managed profile can have escrow token");
-                return;
-            }
-            DevicePolicyManager dpm = mInjector.getDevicePolicyManager();
-            // Devices with Device Owner should have escrow enabled on all users.
-            if (dpm.getDeviceOwnerComponentOnAnyUser() != null) {
-                Slog.i(TAG, "Corp-owned device can have escrow token");
-                return;
-            }
-            // We could also have a profile owner on the given (non-managed) user for unicorn cases
-            if (dpm.getProfileOwnerAsUser(userId) != null) {
-                Slog.i(TAG, "User with profile owner can have escrow token");
-                return;
-            }
-            // If the device is yet to be provisioned (still in SUW), there is still
-            // a chance that Device Owner will be set on the device later, so postpone
-            // disabling escrow token for now.
-            if (!dpm.isDeviceProvisioned()) {
-                Slog.i(TAG, "Postpone disabling escrow tokens until device is provisioned");
-                return;
-            }
-
-            // Escrow tokens are enabled on automotive builds.
-            if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
-                return;
-            }
-
-            // Disable escrow token permanently on all other device/user types.
-            Slog.i(TAG, "Disabling escrow token on user " + userId);
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                mSpManager.destroyEscrowData(userId);
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "disableEscrowTokenOnNonManagedDevices", e);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    private void ensureCallerSystemUid() throws SecurityException {
-        final int callingUid = mInjector.binderGetCallingUid();
-        if (callingUid != Process.SYSTEM_UID) {
-            throw new SecurityException("Only system can call this API.");
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/LockSettingsShellCommand.java b/services/core/java/com/android/server/LockSettingsShellCommand.java
deleted file mode 100644
index 9d671e39..0000000
--- a/services/core/java/com/android/server/LockSettingsShellCommand.java
+++ /dev/null
@@ -1,166 +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.server;
-
-import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
-import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
-import static com.android.internal.widget.LockPatternUtils.stringToPattern;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.os.RemoteException;
-import android.os.ShellCommand;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
-
-class LockSettingsShellCommand extends ShellCommand {
-
-    private static final String COMMAND_SET_PATTERN = "set-pattern";
-    private static final String COMMAND_SET_PIN = "set-pin";
-    private static final String COMMAND_SET_PASSWORD = "set-password";
-    private static final String COMMAND_CLEAR = "clear";
-    private static final String COMMAND_SP = "sp";
-    private static final String COMMAND_SET_DISABLED = "set-disabled";
-
-    private int mCurrentUserId;
-    private final LockPatternUtils mLockPatternUtils;
-    private final Context mContext;
-    private String mOld = "";
-    private String mNew = "";
-
-    LockSettingsShellCommand(Context context, LockPatternUtils lockPatternUtils) {
-        mContext = context;
-        mLockPatternUtils = lockPatternUtils;
-    }
-
-    @Override
-    public int onCommand(String cmd) {
-        try {
-            mCurrentUserId = ActivityManager.getService().getCurrentUser().id;
-
-            parseArgs();
-            if (!checkCredential()) {
-                return -1;
-            }
-            switch (cmd) {
-                case COMMAND_SET_PATTERN:
-                    runSetPattern();
-                    break;
-                case COMMAND_SET_PASSWORD:
-                    runSetPassword();
-                    break;
-                case COMMAND_SET_PIN:
-                    runSetPin();
-                    break;
-                case COMMAND_CLEAR:
-                    runClear();
-                    break;
-                case COMMAND_SP:
-                    runEnableSp();
-                    break;
-                case COMMAND_SET_DISABLED:
-                    runSetDisabled();
-                    break;
-                default:
-                    getErrPrintWriter().println("Unknown command: " + cmd);
-                    break;
-            }
-            return 0;
-        } catch (Exception e) {
-            getErrPrintWriter().println("Error while executing command: " + cmd);
-            e.printStackTrace(getErrPrintWriter());
-            return -1;
-        }
-    }
-
-    @Override
-    public void onHelp() {
-    }
-
-    private void parseArgs() {
-        String opt;
-        while ((opt = getNextOption()) != null) {
-            if ("--old".equals(opt)) {
-                mOld = getNextArgRequired();
-            } else if ("--user".equals(opt)) {
-                mCurrentUserId = Integer.parseInt(getNextArgRequired());
-            } else {
-                getErrPrintWriter().println("Unknown option: " + opt);
-                throw new IllegalArgumentException();
-            }
-        }
-        mNew = getNextArg();
-    }
-
-    private void runEnableSp() {
-        if (mNew != null) {
-            mLockPatternUtils.enableSyntheticPassword();
-            getOutPrintWriter().println("Synthetic password enabled");
-        }
-        getOutPrintWriter().println(String.format("SP Enabled = %b",
-                mLockPatternUtils.isSyntheticPasswordEnabled()));
-    }
-
-    private void runSetPattern() throws RemoteException {
-        mLockPatternUtils.saveLockPattern(stringToPattern(mNew), mOld, mCurrentUserId);
-        getOutPrintWriter().println("Pattern set to '" + mNew + "'");
-    }
-
-    private void runSetPassword() throws RemoteException {
-        mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_ALPHABETIC, mCurrentUserId);
-        getOutPrintWriter().println("Password set to '" + mNew + "'");
-    }
-
-    private void runSetPin() throws RemoteException {
-        mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_NUMERIC, mCurrentUserId);
-        getOutPrintWriter().println("Pin set to '" + mNew + "'");
-    }
-
-    private void runClear() throws RemoteException {
-        mLockPatternUtils.clearLock(mOld, mCurrentUserId);
-        getOutPrintWriter().println("Lock credential cleared");
-    }
-
-    private void runSetDisabled() throws RemoteException {
-        final boolean disabled = Boolean.parseBoolean(mNew);
-        mLockPatternUtils.setLockScreenDisabled(disabled, mCurrentUserId);
-        getOutPrintWriter().println("Lock screen disabled set to " + disabled);
-    }
-
-    private boolean checkCredential() throws RemoteException, RequestThrottledException {
-        final boolean havePassword = mLockPatternUtils.isLockPasswordEnabled(mCurrentUserId);
-        final boolean havePattern = mLockPatternUtils.isLockPatternEnabled(mCurrentUserId);
-        if (havePassword || havePattern) {
-            boolean result;
-            if (havePassword) {
-                result = mLockPatternUtils.checkPassword(mOld, mCurrentUserId);
-            } else {
-                result = mLockPatternUtils.checkPattern(stringToPattern(mOld),
-                        mCurrentUserId);
-            }
-            if (result) {
-                return true;
-            } else {
-                getOutPrintWriter().println("Old password '" + mOld + "' didn't match");
-                return false;
-            }
-        } else {
-            return true;
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/LockSettingsStorage.java b/services/core/java/com/android/server/LockSettingsStorage.java
deleted file mode 100644
index fe9bfd0..0000000
--- a/services/core/java/com/android/server/LockSettingsStorage.java
+++ /dev/null
@@ -1,717 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import static android.content.Context.USER_SERVICE;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.os.Environment;
-import android.os.UserManager;
-import android.os.storage.StorageManager;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.widget.LockPatternUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-
-/**
- * Storage for the lock settings service.
- */
-class LockSettingsStorage {
-
-    private static final String TAG = "LockSettingsStorage";
-    private static final String TABLE = "locksettings";
-    private static final boolean DEBUG = false;
-
-    private static final String COLUMN_KEY = "name";
-    private static final String COLUMN_USERID = "user";
-    private static final String COLUMN_VALUE = "value";
-
-    private static final String[] COLUMNS_FOR_QUERY = {
-            COLUMN_VALUE
-    };
-    private static final String[] COLUMNS_FOR_PREFETCH = {
-            COLUMN_KEY, COLUMN_VALUE
-    };
-
-    private static final String SYSTEM_DIRECTORY = "/system/";
-    private static final String LOCK_PATTERN_FILE = "gatekeeper.pattern.key";
-    private static final String BASE_ZERO_LOCK_PATTERN_FILE = "gatekeeper.gesture.key";
-    private static final String LEGACY_LOCK_PATTERN_FILE = "gesture.key";
-    private static final String LOCK_PASSWORD_FILE = "gatekeeper.password.key";
-    private static final String LEGACY_LOCK_PASSWORD_FILE = "password.key";
-    private static final String CHILD_PROFILE_LOCK_FILE = "gatekeeper.profile.key";
-
-    private static final String SYNTHETIC_PASSWORD_DIRECTORY = "spblob/";
-
-    private static final Object DEFAULT = new Object();
-
-    private final DatabaseHelper mOpenHelper;
-    private final Context mContext;
-    private final Cache mCache = new Cache();
-    private final Object mFileWriteLock = new Object();
-
-    @VisibleForTesting
-    public static class CredentialHash {
-        static final int VERSION_LEGACY = 0;
-        static final int VERSION_GATEKEEPER = 1;
-
-        private CredentialHash(byte[] hash, int type, int version) {
-            if (type != LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-                if (hash == null) {
-                    throw new RuntimeException("Empty hash for CredentialHash");
-                }
-            } else /* type == LockPatternUtils.CREDENTIAL_TYPE_NONE */ {
-                if (hash != null) {
-                    throw new RuntimeException("None type CredentialHash should not have hash");
-                }
-            }
-            this.hash = hash;
-            this.type = type;
-            this.version = version;
-            this.isBaseZeroPattern = false;
-        }
-
-        private CredentialHash(byte[] hash, boolean isBaseZeroPattern) {
-            this.hash = hash;
-            this.type = LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
-            this.version = VERSION_GATEKEEPER;
-            this.isBaseZeroPattern = isBaseZeroPattern;
-        }
-
-        static CredentialHash create(byte[] hash, int type) {
-            if (type == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-                throw new RuntimeException("Bad type for CredentialHash");
-            }
-            return new CredentialHash(hash, type, VERSION_GATEKEEPER);
-        }
-
-        static CredentialHash createEmptyHash() {
-            return new CredentialHash(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
-                    VERSION_GATEKEEPER);
-        }
-
-        byte[] hash;
-        int type;
-        int version;
-        boolean isBaseZeroPattern;
-    }
-
-    public LockSettingsStorage(Context context) {
-        mContext = context;
-        mOpenHelper = new DatabaseHelper(context);
-    }
-
-    public void setDatabaseOnCreateCallback(Callback callback) {
-        mOpenHelper.setCallback(callback);
-    }
-
-    public void writeKeyValue(String key, String value, int userId) {
-        writeKeyValue(mOpenHelper.getWritableDatabase(), key, value, userId);
-    }
-
-    public void writeKeyValue(SQLiteDatabase db, String key, String value, int userId) {
-        ContentValues cv = new ContentValues();
-        cv.put(COLUMN_KEY, key);
-        cv.put(COLUMN_USERID, userId);
-        cv.put(COLUMN_VALUE, value);
-
-        db.beginTransaction();
-        try {
-            db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
-                    new String[] {key, Integer.toString(userId)});
-            db.insert(TABLE, null, cv);
-            db.setTransactionSuccessful();
-            mCache.putKeyValue(key, value, userId);
-        } finally {
-            db.endTransaction();
-        }
-
-    }
-
-    public String readKeyValue(String key, String defaultValue, int userId) {
-        int version;
-        synchronized (mCache) {
-            if (mCache.hasKeyValue(key, userId)) {
-                return mCache.peekKeyValue(key, defaultValue, userId);
-            }
-            version = mCache.getVersion();
-        }
-
-        Cursor cursor;
-        Object result = DEFAULT;
-        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY,
-                COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?",
-                new String[] { Integer.toString(userId), key },
-                null, null, null)) != null) {
-            if (cursor.moveToFirst()) {
-                result = cursor.getString(0);
-            }
-            cursor.close();
-        }
-        mCache.putKeyValueIfUnchanged(key, result, userId, version);
-        return result == DEFAULT ? defaultValue : (String) result;
-    }
-
-    public void prefetchUser(int userId) {
-        int version;
-        synchronized (mCache) {
-            if (mCache.isFetched(userId)) {
-                return;
-            }
-            mCache.setFetched(userId);
-            version = mCache.getVersion();
-        }
-
-        Cursor cursor;
-        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        if ((cursor = db.query(TABLE, COLUMNS_FOR_PREFETCH,
-                COLUMN_USERID + "=?",
-                new String[] { Integer.toString(userId) },
-                null, null, null)) != null) {
-            while (cursor.moveToNext()) {
-                String key = cursor.getString(0);
-                String value = cursor.getString(1);
-                mCache.putKeyValueIfUnchanged(key, value, userId, version);
-            }
-            cursor.close();
-        }
-
-        // Populate cache by reading the password and pattern files.
-        readCredentialHash(userId);
-    }
-
-    private CredentialHash readPasswordHashIfExists(int userId) {
-        byte[] stored = readFile(getLockPasswordFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    CredentialHash.VERSION_GATEKEEPER);
-        }
-
-        stored = readFile(getLegacyLockPasswordFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    CredentialHash.VERSION_LEGACY);
-        }
-        return null;
-    }
-
-    private CredentialHash readPatternHashIfExists(int userId) {
-        byte[] stored = readFile(getLockPatternFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
-                    CredentialHash.VERSION_GATEKEEPER);
-        }
-
-        stored = readFile(getBaseZeroLockPatternFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, true);
-        }
-
-        stored = readFile(getLegacyLockPatternFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
-                    CredentialHash.VERSION_LEGACY);
-        }
-        return null;
-    }
-
-    public CredentialHash readCredentialHash(int userId) {
-        CredentialHash passwordHash = readPasswordHashIfExists(userId);
-        CredentialHash patternHash = readPatternHashIfExists(userId);
-        if (passwordHash != null && patternHash != null) {
-            if (passwordHash.version == CredentialHash.VERSION_GATEKEEPER) {
-                return passwordHash;
-            } else {
-                return patternHash;
-            }
-        } else if (passwordHash != null) {
-            return passwordHash;
-        } else if (patternHash != null) {
-            return patternHash;
-        } else {
-            return CredentialHash.createEmptyHash();
-        }
-    }
-
-    public void removeChildProfileLock(int userId) {
-        if (DEBUG)
-            Slog.e(TAG, "Remove child profile lock for user: " + userId);
-        try {
-            deleteFile(getChildProfileLockFile(userId));
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    public void writeChildProfileLock(int userId, byte[] lock) {
-        writeFile(getChildProfileLockFile(userId), lock);
-    }
-
-    public byte[] readChildProfileLock(int userId) {
-        return readFile(getChildProfileLockFile(userId));
-    }
-
-    public boolean hasChildProfileLock(int userId) {
-        return hasFile(getChildProfileLockFile(userId));
-    }
-
-    public boolean hasPassword(int userId) {
-        return hasFile(getLockPasswordFilename(userId)) ||
-            hasFile(getLegacyLockPasswordFilename(userId));
-    }
-
-    public boolean hasPattern(int userId) {
-        return hasFile(getLockPatternFilename(userId)) ||
-            hasFile(getBaseZeroLockPatternFilename(userId)) ||
-            hasFile(getLegacyLockPatternFilename(userId));
-    }
-
-    public boolean hasCredential(int userId) {
-        return hasPassword(userId) || hasPattern(userId);
-    }
-
-    private boolean hasFile(String name) {
-        byte[] contents = readFile(name);
-        return contents != null && contents.length > 0;
-    }
-
-    private byte[] readFile(String name) {
-        int version;
-        synchronized (mCache) {
-            if (mCache.hasFile(name)) {
-                return mCache.peekFile(name);
-            }
-            version = mCache.getVersion();
-        }
-
-        RandomAccessFile raf = null;
-        byte[] stored = null;
-        try {
-            raf = new RandomAccessFile(name, "r");
-            stored = new byte[(int) raf.length()];
-            raf.readFully(stored, 0, stored.length);
-            raf.close();
-        } catch (IOException e) {
-            Slog.e(TAG, "Cannot read file " + e);
-        } finally {
-            if (raf != null) {
-                try {
-                    raf.close();
-                } catch (IOException e) {
-                    Slog.e(TAG, "Error closing file " + e);
-                }
-            }
-        }
-        mCache.putFileIfUnchanged(name, stored, version);
-        return stored;
-    }
-
-    private void writeFile(String name, byte[] hash) {
-        synchronized (mFileWriteLock) {
-            RandomAccessFile raf = null;
-            try {
-                // Write the hash to file, requiring each write to be synchronized to the
-                // underlying storage device immediately to avoid data loss in case of power loss.
-                // This also ensures future secdiscard operation on the file succeeds since the
-                // file would have been allocated on flash.
-                raf = new RandomAccessFile(name, "rws");
-                // Truncate the file if pattern is null, to clear the lock
-                if (hash == null || hash.length == 0) {
-                    raf.setLength(0);
-                } else {
-                    raf.write(hash, 0, hash.length);
-                }
-                raf.close();
-            } catch (IOException e) {
-                Slog.e(TAG, "Error writing to file " + e);
-            } finally {
-                if (raf != null) {
-                    try {
-                        raf.close();
-                    } catch (IOException e) {
-                        Slog.e(TAG, "Error closing file " + e);
-                    }
-                }
-            }
-            mCache.putFile(name, hash);
-        }
-    }
-
-    private void deleteFile(String name) {
-        if (DEBUG) Slog.e(TAG, "Delete file " + name);
-        synchronized (mFileWriteLock) {
-            File file = new File(name);
-            if (file.exists()) {
-                file.delete();
-                mCache.putFile(name, null);
-            }
-        }
-    }
-
-    public void writeCredentialHash(CredentialHash hash, int userId) {
-        byte[] patternHash = null;
-        byte[] passwordHash = null;
-
-        if (hash.type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
-            passwordHash = hash.hash;
-        } else if (hash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
-            patternHash = hash.hash;
-        }
-        writeFile(getLockPasswordFilename(userId), passwordHash);
-        writeFile(getLockPatternFilename(userId), patternHash);
-    }
-
-    @VisibleForTesting
-    String getLockPatternFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, LOCK_PATTERN_FILE);
-    }
-
-    @VisibleForTesting
-    String getLockPasswordFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, LOCK_PASSWORD_FILE);
-    }
-
-    @VisibleForTesting
-    String getLegacyLockPatternFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PATTERN_FILE);
-    }
-
-    @VisibleForTesting
-    String getLegacyLockPasswordFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PASSWORD_FILE);
-    }
-
-    private String getBaseZeroLockPatternFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, BASE_ZERO_LOCK_PATTERN_FILE);
-    }
-
-    @VisibleForTesting
-    String getChildProfileLockFile(int userId) {
-        return getLockCredentialFilePathForUser(userId, CHILD_PROFILE_LOCK_FILE);
-    }
-
-    private String getLockCredentialFilePathForUser(int userId, String basename) {
-        String dataSystemDirectory = Environment.getDataDirectory().getAbsolutePath() +
-                        SYSTEM_DIRECTORY;
-        if (userId == 0) {
-            // Leave it in the same place for user 0
-            return dataSystemDirectory + basename;
-        } else {
-            return new File(Environment.getUserSystemDirectory(userId), basename).getAbsolutePath();
-        }
-    }
-
-    public void writeSyntheticPasswordState(int userId, long handle, String name, byte[] data) {
-        writeFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name), data);
-    }
-
-    public byte[] readSyntheticPasswordState(int userId, long handle, String name) {
-        return readFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name));
-    }
-
-    public void deleteSyntheticPasswordState(int userId, long handle, String name) {
-        String path = getSynthenticPasswordStateFilePathForUser(userId, handle, name);
-        File file = new File(path);
-        if (file.exists()) {
-            try {
-                mContext.getSystemService(StorageManager.class).secdiscard(file.getAbsolutePath());
-            } catch (Exception e) {
-                Slog.w(TAG, "Failed to secdiscard " + path, e);
-            } finally {
-                file.delete();
-            }
-            mCache.putFile(path, null);
-        }
-    }
-
-    @VisibleForTesting
-    protected File getSyntheticPasswordDirectoryForUser(int userId) {
-        return new File(Environment.getDataSystemDeDirectory(userId) ,SYNTHETIC_PASSWORD_DIRECTORY);
-    }
-
-    @VisibleForTesting
-    protected String getSynthenticPasswordStateFilePathForUser(int userId, long handle,
-            String name) {
-        File baseDir = getSyntheticPasswordDirectoryForUser(userId);
-        String baseName = String.format("%016x.%s", handle, name);
-        if (!baseDir.exists()) {
-            baseDir.mkdir();
-        }
-        return new File(baseDir, baseName).getAbsolutePath();
-    }
-
-    public void removeUser(int userId) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-
-        final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
-        final UserInfo parentInfo = um.getProfileParent(userId);
-
-        if (parentInfo == null) {
-            // This user owns its lock settings files - safe to delete them
-            synchronized (mFileWriteLock) {
-                String name = getLockPasswordFilename(userId);
-                File file = new File(name);
-                if (file.exists()) {
-                    file.delete();
-                    mCache.putFile(name, null);
-                }
-                name = getLockPatternFilename(userId);
-                file = new File(name);
-                if (file.exists()) {
-                    file.delete();
-                    mCache.putFile(name, null);
-                }
-            }
-        } else {
-            // Managed profile
-            removeChildProfileLock(userId);
-        }
-
-        File spStateDir = getSyntheticPasswordDirectoryForUser(userId);
-        try {
-            db.beginTransaction();
-            db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null);
-            db.setTransactionSuccessful();
-            mCache.removeUser(userId);
-            // The directory itself will be deleted as part of user deletion operation by the
-            // framework, so only need to purge cache here.
-            //TODO: (b/34600579) invoke secdiscardable
-            mCache.purgePath(spStateDir.getAbsolutePath());
-        } finally {
-            db.endTransaction();
-        }
-    }
-
-    @VisibleForTesting
-    void closeDatabase() {
-        mOpenHelper.close();
-    }
-
-    @VisibleForTesting
-    void clearCache() {
-        mCache.clear();
-    }
-
-    public interface Callback {
-        void initialize(SQLiteDatabase db);
-    }
-
-    class DatabaseHelper extends SQLiteOpenHelper {
-        private static final String TAG = "LockSettingsDB";
-        private static final String DATABASE_NAME = "locksettings.db";
-
-        private static final int DATABASE_VERSION = 2;
-
-        private Callback mCallback;
-
-        public DatabaseHelper(Context context) {
-            super(context, DATABASE_NAME, null, DATABASE_VERSION);
-            setWriteAheadLoggingEnabled(true);
-        }
-
-        public void setCallback(Callback callback) {
-            mCallback = callback;
-        }
-
-        private void createTable(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE " + TABLE + " (" +
-                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
-                    COLUMN_KEY + " TEXT," +
-                    COLUMN_USERID + " INTEGER," +
-                    COLUMN_VALUE + " TEXT" +
-                    ");");
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            createTable(db);
-            if (mCallback != null) {
-                mCallback.initialize(db);
-            }
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
-            int upgradeVersion = oldVersion;
-            if (upgradeVersion == 1) {
-                // Previously migrated lock screen widget settings. Now defunct.
-                upgradeVersion = 2;
-            }
-
-            if (upgradeVersion != DATABASE_VERSION) {
-                Log.w(TAG, "Failed to upgrade database!");
-            }
-        }
-    }
-
-    /**
-     * Cache consistency model:
-     * - Writes to storage write directly to the cache, but this MUST happen within the atomic
-     *   section either provided by the database transaction or mWriteLock, such that writes to the
-     *   cache and writes to the backing storage are guaranteed to occur in the same order
-     *
-     * - Reads can populate the cache, but because they are no strong ordering guarantees with
-     *   respect to writes this precaution is taken:
-     *   - The cache is assigned a version number that increases every time the cache is modified.
-     *     Reads from backing storage can only populate the cache if the backing storage
-     *     has not changed since the load operation has begun.
-     *     This guarantees that no read operation can shadow a write to the cache that happens
-     *     after it had begun.
-     */
-    private static class Cache {
-        private final ArrayMap<CacheKey, Object> mCache = new ArrayMap<>();
-        private final CacheKey mCacheKey = new CacheKey();
-        private int mVersion = 0;
-
-        String peekKeyValue(String key, String defaultValue, int userId) {
-            Object cached = peek(CacheKey.TYPE_KEY_VALUE, key, userId);
-            return cached == DEFAULT ? defaultValue : (String) cached;
-        }
-
-        boolean hasKeyValue(String key, int userId) {
-            return contains(CacheKey.TYPE_KEY_VALUE, key, userId);
-        }
-
-        void putKeyValue(String key, String value, int userId) {
-            put(CacheKey.TYPE_KEY_VALUE, key, value, userId);
-        }
-
-        void putKeyValueIfUnchanged(String key, Object value, int userId, int version) {
-            putIfUnchanged(CacheKey.TYPE_KEY_VALUE, key, value, userId, version);
-        }
-
-        byte[] peekFile(String fileName) {
-            return (byte[]) peek(CacheKey.TYPE_FILE, fileName, -1 /* userId */);
-        }
-
-        boolean hasFile(String fileName) {
-            return contains(CacheKey.TYPE_FILE, fileName, -1 /* userId */);
-        }
-
-        void putFile(String key, byte[] value) {
-            put(CacheKey.TYPE_FILE, key, value, -1 /* userId */);
-        }
-
-        void putFileIfUnchanged(String key, byte[] value, int version) {
-            putIfUnchanged(CacheKey.TYPE_FILE, key, value, -1 /* userId */, version);
-        }
-
-        void setFetched(int userId) {
-            put(CacheKey.TYPE_FETCHED, "isFetched", "true", userId);
-        }
-
-        boolean isFetched(int userId) {
-            return contains(CacheKey.TYPE_FETCHED, "", userId);
-        }
-
-
-        private synchronized void put(int type, String key, Object value, int userId) {
-            // Create a new CachKey here because it may be saved in the map if the key is absent.
-            mCache.put(new CacheKey().set(type, key, userId), value);
-            mVersion++;
-        }
-
-        private synchronized void putIfUnchanged(int type, String key, Object value, int userId,
-                int version) {
-            if (!contains(type, key, userId) && mVersion == version) {
-                put(type, key, value, userId);
-            }
-        }
-
-        private synchronized boolean contains(int type, String key, int userId) {
-            return mCache.containsKey(mCacheKey.set(type, key, userId));
-        }
-
-        private synchronized Object peek(int type, String key, int userId) {
-            return mCache.get(mCacheKey.set(type, key, userId));
-        }
-
-        private synchronized int getVersion() {
-            return mVersion;
-        }
-
-        synchronized void removeUser(int userId) {
-            for (int i = mCache.size() - 1; i >= 0; i--) {
-                if (mCache.keyAt(i).userId == userId) {
-                    mCache.removeAt(i);
-                }
-            }
-
-            // Make sure in-flight loads can't write to cache.
-            mVersion++;
-        }
-
-        synchronized void purgePath(String path) {
-            for (int i = mCache.size() - 1; i >= 0; i--) {
-                CacheKey entry = mCache.keyAt(i);
-                if (entry.type == CacheKey.TYPE_FILE && entry.key.startsWith(path)) {
-                    mCache.removeAt(i);
-                }
-            }
-            mVersion++;
-        }
-
-        synchronized void clear() {
-            mCache.clear();
-            mVersion++;
-        }
-
-        private static final class CacheKey {
-            static final int TYPE_KEY_VALUE = 0;
-            static final int TYPE_FILE = 1;
-            static final int TYPE_FETCHED = 2;
-
-            String key;
-            int userId;
-            int type;
-
-            public CacheKey set(int type, String key, int userId) {
-                this.type = type;
-                this.key = key;
-                this.userId = userId;
-                return this;
-            }
-
-            @Override
-            public boolean equals(Object obj) {
-                if (!(obj instanceof CacheKey))
-                    return false;
-                CacheKey o = (CacheKey) obj;
-                return userId == o.userId && type == o.type && key.equals(o.key);
-            }
-
-            @Override
-            public int hashCode() {
-                return key.hashCode() ^ userId ^ type;
-            }
-        }
-    }
-
-}
diff --git a/services/core/java/com/android/server/LockSettingsStrongAuth.java b/services/core/java/com/android/server/LockSettingsStrongAuth.java
deleted file mode 100644
index f5fe3db..0000000
--- a/services/core/java/com/android/server/LockSettingsStrongAuth.java
+++ /dev/null
@@ -1,231 +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.server;
-
-import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
-import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
-
-import android.app.AlarmManager;
-import android.app.AlarmManager.OnAlarmListener;
-import android.app.admin.DevicePolicyManager;
-import android.app.trust.IStrongAuthTracker;
-import android.content.Context;
-import android.os.Binder;
-import android.os.DeadObjectException;
-import android.os.Handler;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.Slog;
-import android.util.SparseIntArray;
-
-import java.util.ArrayList;
-
-/**
- * Keeps track of requests for strong authentication.
- */
-public class LockSettingsStrongAuth {
-
-    private static final String TAG = "LockSettings";
-
-    private static final int MSG_REQUIRE_STRONG_AUTH = 1;
-    private static final int MSG_REGISTER_TRACKER = 2;
-    private static final int MSG_UNREGISTER_TRACKER = 3;
-    private static final int MSG_REMOVE_USER = 4;
-    private static final int MSG_SCHEDULE_STRONG_AUTH_TIMEOUT = 5;
-
-    private static final String STRONG_AUTH_TIMEOUT_ALARM_TAG =
-            "LockSettingsStrongAuth.timeoutForUser";
-
-    private final ArrayList<IStrongAuthTracker> mStrongAuthTrackers = new ArrayList<>();
-    private final SparseIntArray mStrongAuthForUser = new SparseIntArray();
-    private final ArrayMap<Integer, StrongAuthTimeoutAlarmListener>
-            mStrongAuthTimeoutAlarmListenerForUser = new ArrayMap<>();
-    private final int mDefaultStrongAuthFlags;
-    private final Context mContext;
-
-    private AlarmManager mAlarmManager;
-
-    public LockSettingsStrongAuth(Context context) {
-        mContext = context;
-        mDefaultStrongAuthFlags = StrongAuthTracker.getDefaultFlags(context);
-        mAlarmManager = context.getSystemService(AlarmManager.class);
-    }
-
-    private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) {
-        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
-            if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
-                return;
-            }
-        }
-        mStrongAuthTrackers.add(tracker);
-
-        for (int i = 0; i < mStrongAuthForUser.size(); i++) {
-            int key = mStrongAuthForUser.keyAt(i);
-            int value = mStrongAuthForUser.valueAt(i);
-            try {
-                tracker.onStrongAuthRequiredChanged(value, key);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Exception while adding StrongAuthTracker.", e);
-            }
-        }
-    }
-
-    private void handleRemoveStrongAuthTracker(IStrongAuthTracker tracker) {
-        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
-            if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
-                mStrongAuthTrackers.remove(i);
-                return;
-            }
-        }
-    }
-
-    private void handleRequireStrongAuth(int strongAuthReason, int userId) {
-        if (userId == UserHandle.USER_ALL) {
-            for (int i = 0; i < mStrongAuthForUser.size(); i++) {
-                int key = mStrongAuthForUser.keyAt(i);
-                handleRequireStrongAuthOneUser(strongAuthReason, key);
-            }
-        } else {
-            handleRequireStrongAuthOneUser(strongAuthReason, userId);
-        }
-    }
-
-    private void handleRequireStrongAuthOneUser(int strongAuthReason, int userId) {
-        int oldValue = mStrongAuthForUser.get(userId, mDefaultStrongAuthFlags);
-        int newValue = strongAuthReason == STRONG_AUTH_NOT_REQUIRED
-                ? STRONG_AUTH_NOT_REQUIRED
-                : (oldValue | strongAuthReason);
-        if (oldValue != newValue) {
-            mStrongAuthForUser.put(userId, newValue);
-            notifyStrongAuthTrackers(newValue, userId);
-        }
-    }
-
-    private void handleRemoveUser(int userId) {
-        int index = mStrongAuthForUser.indexOfKey(userId);
-        if (index >= 0) {
-            mStrongAuthForUser.removeAt(index);
-            notifyStrongAuthTrackers(mDefaultStrongAuthFlags, userId);
-        }
-    }
-
-    private void handleScheduleStrongAuthTimeout(int userId) {
-        final DevicePolicyManager dpm =
-                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-        long when = SystemClock.elapsedRealtime() + dpm.getRequiredStrongAuthTimeout(null, userId);
-        // cancel current alarm listener for the user (if there was one)
-        StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId);
-        if (alarm != null) {
-            mAlarmManager.cancel(alarm);
-        } else {
-            alarm = new StrongAuthTimeoutAlarmListener(userId);
-            mStrongAuthTimeoutAlarmListenerForUser.put(userId, alarm);
-        }
-        // schedule a new alarm listener for the user
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, STRONG_AUTH_TIMEOUT_ALARM_TAG,
-                alarm, mHandler);
-    }
-
-    private void notifyStrongAuthTrackers(int strongAuthReason, int userId) {
-        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
-            try {
-                mStrongAuthTrackers.get(i).onStrongAuthRequiredChanged(strongAuthReason, userId);
-            } catch (DeadObjectException e) {
-                Slog.d(TAG, "Removing dead StrongAuthTracker.");
-                mStrongAuthTrackers.remove(i);
-                i--;
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Exception while notifying StrongAuthTracker.", e);
-            }
-        }
-    }
-
-    public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
-        mHandler.obtainMessage(MSG_REGISTER_TRACKER, tracker).sendToTarget();
-    }
-
-    public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
-        mHandler.obtainMessage(MSG_UNREGISTER_TRACKER, tracker).sendToTarget();
-    }
-
-    public void removeUser(int userId) {
-        final int argNotUsed = 0;
-        mHandler.obtainMessage(MSG_REMOVE_USER, userId, argNotUsed).sendToTarget();
-    }
-
-    public void requireStrongAuth(int strongAuthReason, int userId) {
-        if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_SYSTEM) {
-            mHandler.obtainMessage(MSG_REQUIRE_STRONG_AUTH, strongAuthReason,
-                    userId).sendToTarget();
-        } else {
-            throw new IllegalArgumentException(
-                    "userId must be an explicit user id or USER_ALL");
-        }
-    }
-
-    public void reportUnlock(int userId) {
-        requireStrongAuth(STRONG_AUTH_NOT_REQUIRED, userId);
-    }
-
-    public void reportSuccessfulStrongAuthUnlock(int userId) {
-        final int argNotUsed = 0;
-        mHandler.obtainMessage(MSG_SCHEDULE_STRONG_AUTH_TIMEOUT, userId, argNotUsed).sendToTarget();
-    }
-
-    private class StrongAuthTimeoutAlarmListener implements OnAlarmListener {
-
-        private final int mUserId;
-
-        public StrongAuthTimeoutAlarmListener(int userId) {
-            mUserId = userId;
-        }
-
-        @Override
-        public void onAlarm() {
-            requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, mUserId);
-        }
-    }
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_REGISTER_TRACKER:
-                    handleAddStrongAuthTracker((IStrongAuthTracker) msg.obj);
-                    break;
-                case MSG_UNREGISTER_TRACKER:
-                    handleRemoveStrongAuthTracker((IStrongAuthTracker) msg.obj);
-                    break;
-                case MSG_REQUIRE_STRONG_AUTH:
-                    handleRequireStrongAuth(msg.arg1, msg.arg2);
-                    break;
-                case MSG_REMOVE_USER:
-                    handleRemoveUser(msg.arg1);
-                    break;
-                case MSG_SCHEDULE_STRONG_AUTH_TIMEOUT:
-                    handleScheduleStrongAuthTimeout(msg.arg1);
-                    break;
-            }
-        }
-    };
-}
diff --git a/services/core/java/com/android/server/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java
index 26e471e..06c46b9 100644
--- a/services/core/java/com/android/server/MasterClearReceiver.java
+++ b/services/core/java/com/android/server/MasterClearReceiver.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.app.PendingIntent;
 import android.app.ProgressDialog;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -23,6 +24,8 @@
 import android.os.AsyncTask;
 import android.os.RecoverySystem;
 import android.os.storage.StorageManager;
+import android.provider.Settings;
+import android.telephony.euicc.EuiccManager;
 import android.util.Log;
 import android.util.Slog;
 import android.view.WindowManager;
@@ -30,9 +33,13 @@
 import com.android.internal.R;
 
 import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 public class MasterClearReceiver extends BroadcastReceiver {
     private static final String TAG = "MasterClear";
+    private boolean mWipeExternalStorage;
+    private boolean mWipeEsims;
 
     @Override
     public void onReceive(final Context context, final Intent intent) {
@@ -53,8 +60,8 @@
 
         final boolean shutdown = intent.getBooleanExtra("shutdown", false);
         final String reason = intent.getStringExtra(Intent.EXTRA_REASON);
-        final boolean wipeExternalStorage = intent.getBooleanExtra(
-                Intent.EXTRA_WIPE_EXTERNAL_STORAGE, false);
+        mWipeExternalStorage = intent.getBooleanExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, false);
+        mWipeEsims = intent.getBooleanExtra(Intent.EXTRA_WIPE_ESIMS, false);
         final boolean forceWipe = intent.getBooleanExtra(Intent.EXTRA_FORCE_MASTER_CLEAR, false)
                 || intent.getBooleanExtra(Intent.EXTRA_FORCE_FACTORY_RESET, false);
 
@@ -64,7 +71,8 @@
             @Override
             public void run() {
                 try {
-                    RecoverySystem.rebootWipeUserData(context, shutdown, reason, forceWipe);
+                    RecoverySystem
+                            .rebootWipeUserData(context, shutdown, reason, forceWipe, mWipeEsims);
                     Log.wtf(TAG, "Still running after master clear?!");
                 } catch (IOException e) {
                     Slog.e(TAG, "Can't perform master clear/factory reset", e);
@@ -74,20 +82,20 @@
             }
         };
 
-        if (wipeExternalStorage) {
+        if (mWipeExternalStorage || mWipeEsims) {
             // thr will be started at the end of this task.
-            new WipeAdoptableDisksTask(context, thr).execute();
+            new WipeDataTask(context, thr).execute();
         } else {
             thr.start();
         }
     }
 
-    private class WipeAdoptableDisksTask extends AsyncTask<Void, Void, Void> {
+    private class WipeDataTask extends AsyncTask<Void, Void, Void> {
         private final Thread mChainedTask;
         private final Context mContext;
         private final ProgressDialog mProgressDialog;
 
-        public WipeAdoptableDisksTask(Context context, Thread chainedTask) {
+        public WipeDataTask(Context context, Thread chainedTask) {
             mContext = context;
             mChainedTask = chainedTask;
             mProgressDialog = new ProgressDialog(context);
@@ -104,9 +112,11 @@
         @Override
         protected Void doInBackground(Void... params) {
             Slog.w(TAG, "Wiping adoptable disks");
-            StorageManager sm = (StorageManager) mContext.getSystemService(
-                    Context.STORAGE_SERVICE);
-            sm.wipeAdoptableDisks();
+            if (mWipeExternalStorage) {
+                StorageManager sm = (StorageManager) mContext.getSystemService(
+                        Context.STORAGE_SERVICE);
+                sm.wipeAdoptableDisks();
+            }
             return null;
         }
 
diff --git a/services/core/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java
index f5f7732..b5a8332 100644
--- a/services/core/java/com/android/server/NativeDaemonConnector.java
+++ b/services/core/java/com/android/server/NativeDaemonConnector.java
@@ -24,11 +24,13 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.util.LocalLog;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
+import com.android.server.power.ShutdownThread;
 import com.google.android.collect.Lists;
 
 import java.io.FileDescriptor;
@@ -136,6 +138,12 @@
                 listenToSocket();
             } catch (Exception e) {
                 loge("Error in NativeDaemonConnector: " + e);
+                String shutdownAct = SystemProperties.get(
+                        ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
+                if (shutdownAct != null && shutdownAct.length() > 0) {
+                    // The device is in middle of shutdown.
+                    break;
+                }
                 SystemClock.sleep(5000);
             }
         }
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 3e44532..7c73818 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -20,6 +20,9 @@
 import static android.Manifest.permission.DUMP;
 import static android.Manifest.permission.NETWORK_STACK;
 import static android.Manifest.permission.SHUTDOWN;
+import static android.net.ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_NONE;
@@ -76,6 +79,7 @@
 import android.os.IBinder;
 import android.os.INetworkActivityListener;
 import android.os.INetworkManagementService;
+import android.os.PersistableBundle;
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteCallbackList;
@@ -91,6 +95,7 @@
 import android.telephony.PhoneStateListener;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
@@ -1139,17 +1144,6 @@
     }
 
     @Override
-    public void setInterfaceIpv6NdOffload(String iface, boolean enable) {
-        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-        try {
-            mConnector.execute(
-                    "interface", "ipv6ndoffload", iface, (enable ? "enable" : "disable"));
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
-        }
-    }
-
-    @Override
     public void addRoute(int netId, RouteInfo route) {
         modifyRoute("add", "" + netId, route);
     }
@@ -1897,38 +1891,34 @@
                 return new NetworkStats(SystemClock.elapsedRealtime(), 0);
             }
 
-            final NativeDaemonEvent[] events;
+            final PersistableBundle bundle;
             try {
-                events = mConnector.executeForList("bandwidth", "gettetherstats");
-            } catch (NativeDaemonConnectorException e) {
-                throw e.rethrowAsParcelableException();
+                bundle = mNetdService.tetherGetStats();
+            } catch (RemoteException | ServiceSpecificException e) {
+                throw new IllegalStateException("problem parsing tethering stats: ", e);
             }
-            final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
-            for (NativeDaemonEvent event : events) {
-                if (event.getCode() != TetheringStatsListResult) continue;
 
-                // 114 ifaceIn ifaceOut rx_bytes rx_packets tx_bytes tx_packets
-                final StringTokenizer tok = new StringTokenizer(event.getMessage());
+            final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(),
+                    bundle.size());
+            final NetworkStats.Entry entry = new NetworkStats.Entry();
+
+            for (String iface : bundle.keySet()) {
+                long[] statsArray = bundle.getLongArray(iface);
                 try {
-                    final String ifaceIn = tok.nextToken();
-                    final String ifaceOut = tok.nextToken();
-
-                    final NetworkStats.Entry entry = new NetworkStats.Entry();
-                    entry.iface = ifaceOut;
+                    entry.iface = iface;
                     entry.uid = UID_TETHERING;
                     entry.set = SET_DEFAULT;
                     entry.tag = TAG_NONE;
-                    entry.rxBytes = Long.parseLong(tok.nextToken());
-                    entry.rxPackets = Long.parseLong(tok.nextToken());
-                    entry.txBytes = Long.parseLong(tok.nextToken());
-                    entry.txPackets = Long.parseLong(tok.nextToken());
+                    entry.rxBytes   = statsArray[INetd.TETHER_STATS_RX_BYTES];
+                    entry.rxPackets = statsArray[INetd.TETHER_STATS_RX_PACKETS];
+                    entry.txBytes   = statsArray[INetd.TETHER_STATS_TX_BYTES];
+                    entry.txPackets = statsArray[INetd.TETHER_STATS_TX_PACKETS];
                     stats.combineValues(entry);
-                } catch (NoSuchElementException e) {
-                    throw new IllegalStateException("problem parsing tethering stats: " + event);
-                } catch (NumberFormatException e) {
-                    throw new IllegalStateException("problem parsing tethering stats: " + event);
+                } catch (ArrayIndexOutOfBoundsException e) {
+                    throw new IllegalStateException("invalid tethering stats for " + iface, e);
                 }
             }
+
             return stats;
         }
 
@@ -1960,9 +1950,9 @@
     public void setDnsConfigurationForNetwork(int netId, String[] servers, String domains) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
-        ContentResolver resolver = mContext.getContentResolver();
+        final ContentResolver cr = mContext.getContentResolver();
 
-        int sampleValidity = Settings.Global.getInt(resolver,
+        int sampleValidity = Settings.Global.getInt(cr,
                 Settings.Global.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS,
                 DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS);
         if (sampleValidity < 0 || sampleValidity > 65535) {
@@ -1971,7 +1961,7 @@
             sampleValidity = DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS;
         }
 
-        int successThreshold = Settings.Global.getInt(resolver,
+        int successThreshold = Settings.Global.getInt(cr,
                 Settings.Global.DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT,
                 DNS_RESOLVER_DEFAULT_SUCCESS_THRESHOLD_PERCENT);
         if (successThreshold < 0 || successThreshold > 100) {
@@ -1980,9 +1970,9 @@
             successThreshold = DNS_RESOLVER_DEFAULT_SUCCESS_THRESHOLD_PERCENT;
         }
 
-        int minSamples = Settings.Global.getInt(resolver,
+        int minSamples = Settings.Global.getInt(cr,
                 Settings.Global.DNS_RESOLVER_MIN_SAMPLES, DNS_RESOLVER_DEFAULT_MIN_SAMPLES);
-        int maxSamples = Settings.Global.getInt(resolver,
+        int maxSamples = Settings.Global.getInt(cr,
                 Settings.Global.DNS_RESOLVER_MAX_SAMPLES, DNS_RESOLVER_DEFAULT_MAX_SAMPLES);
         if (minSamples < 0 || minSamples > maxSamples || maxSamples > 64) {
             Slog.w(TAG, "Invalid sample count (min, max)=(" + minSamples + ", " + maxSamples +
@@ -1994,13 +1984,43 @@
 
         final String[] domainStrs = domains == null ? new String[0] : domains.split(" ");
         final int[] params = { sampleValidity, successThreshold, minSamples, maxSamples };
+        final boolean useTls = shouldUseTls(cr);
+        // TODO: Populate tlsHostname once it's decided how the hostname's IP
+        // addresses will be resolved:
+        //
+        //     [1] network-provided DNS servers are included here with the
+        //         hostname and netd will use the network-provided servers to
+        //         resolve the hostname and fix up its internal structures, or
+        //
+        //     [2] network-provided DNS servers are included here without the
+        //         hostname, the ConnectivityService layer resolves the given
+        //         hostname, and then reconfigures netd with this information.
+        //
+        // In practice, there will always be a need for ConnectivityService or
+        // the captive portal app to use the network-provided services to make
+        // some queries. This argues in favor of [1], in concert with another
+        // mechanism, perhaps setting a high bit in the netid, to indicate
+        // via existing DNS APIs which set of servers (network-provided or
+        // non-network-provided private DNS) should be queried.
+        final String tlsHostname = "";
+        final String[] tlsFingerprints = new String[0];
         try {
-            mNetdService.setResolverConfiguration(netId, servers, domainStrs, params);
+            mNetdService.setResolverConfiguration(netId, servers, domainStrs, params,
+                    useTls, tlsHostname, tlsFingerprints);
         } catch (RemoteException e) {
             throw new RuntimeException(e);
         }
     }
 
+    private static boolean shouldUseTls(ContentResolver cr) {
+        String privateDns = Settings.Global.getString(cr, Settings.Global.PRIVATE_DNS_MODE);
+        if (TextUtils.isEmpty(privateDns)) {
+            privateDns = PRIVATE_DNS_DEFAULT_MODE;
+        }
+        return privateDns.equals(PRIVATE_DNS_MODE_OPPORTUNISTIC) ||
+               privateDns.startsWith(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+    }
+
     @Override
     public void addVpnUidRanges(int netId, UidRange[] ranges) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
diff --git a/services/core/java/com/android/server/OemLockService.java b/services/core/java/com/android/server/OemLockService.java
deleted file mode 100644
index 03f82a8..0000000
--- a/services/core/java/com/android/server/OemLockService.java
+++ /dev/null
@@ -1,147 +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;
-
-import android.Manifest;
-import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.content.Context;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.service.oemlock.IOemLockService;
-import android.service.persistentdata.PersistentDataBlockManager;
-
-/**
- * Service for managing the OEM lock state of the device.
- *
- * The current implementation is a wrapper around the previous implementation of OEM lock.
- *  - the DISALLOW_OEM_UNLOCK user restriction was set if the carrier disallowed unlock
- *  - the user allows unlock in settings which calls PDBM.setOemUnlockEnabled()
- */
-public class OemLockService extends SystemService {
-    private Context mContext;
-
-    public OemLockService(Context context) {
-        super(context);
-        mContext = context;
-    }
-
-    @Override
-    public void onStart() {
-        publishBinderService(Context.OEM_LOCK_SERVICE, mService);
-    }
-
-    private boolean doIsOemUnlockAllowedByCarrier() {
-        return !UserManager.get(mContext).hasUserRestriction(UserManager.DISALLOW_OEM_UNLOCK);
-    }
-
-    private boolean doIsOemUnlockAllowedByUser() {
-        final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
-            mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
-
-        final long token = Binder.clearCallingIdentity();
-        try {
-            return pdbm.getOemUnlockEnabled();
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    /**
-     * Implements the binder interface for the service.
-     */
-    private final IBinder mService = new IOemLockService.Stub() {
-        @Override
-        public void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) {
-            enforceManageCarrierOemUnlockPermission();
-            enforceUserIsAdmin();
-
-            // Note: this implementation does not require a signature
-
-            // Continue using user restriction for backwards compatibility
-            final UserHandle userHandle = UserHandle.of(UserHandle.getCallingUserId());
-            final long token = Binder.clearCallingIdentity();
-            try {
-                UserManager.get(mContext)
-                        .setUserRestriction(UserManager.DISALLOW_OEM_UNLOCK, !allowed, userHandle);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public boolean isOemUnlockAllowedByCarrier() {
-            enforceManageCarrierOemUnlockPermission();
-            return doIsOemUnlockAllowedByCarrier();
-        }
-
-        @Override
-        public void setOemUnlockAllowedByUser(boolean allowedByUser) {
-            if (ActivityManager.isUserAMonkey()) {
-                // Prevent a monkey from changing this
-                return;
-            }
-
-            enforceManageUserOemUnlockPermission();
-            enforceUserIsAdmin();
-
-            final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
-                    mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
-
-            final long token = Binder.clearCallingIdentity();
-            try {
-                // The method name is misleading as it really just means whether or not the device
-                // can be unlocked but doesn't actually do any unlocking.
-                pdbm.setOemUnlockEnabled(allowedByUser);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public boolean isOemUnlockAllowedByUser() {
-            enforceManageUserOemUnlockPermission();
-            return doIsOemUnlockAllowedByUser();
-        }
-    };
-
-    private void enforceManageCarrierOemUnlockPermission() {
-        mContext.enforceCallingOrSelfPermission(
-                Manifest.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE,
-                "Can't manage OEM unlock allowed by carrier");
-    }
-
-    private void enforceManageUserOemUnlockPermission() {
-        mContext.enforceCallingOrSelfPermission(
-                Manifest.permission.MANAGE_USER_OEM_UNLOCK_STATE,
-                "Can't manage OEM unlock allowed by user");
-    }
-
-    private void enforceUserIsAdmin() {
-        final int userId = UserHandle.getCallingUserId();
-        final long token = Binder.clearCallingIdentity();
-        try {
-            if (!UserManager.get(mContext).isUserAdmin(userId)) {
-                throw new SecurityException("Must be an admin user");
-            }
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/PersistentDataBlockManagerInternal.java b/services/core/java/com/android/server/PersistentDataBlockManagerInternal.java
new file mode 100644
index 0000000..80f8e51
--- /dev/null
+++ b/services/core/java/com/android/server/PersistentDataBlockManagerInternal.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+/**
+ * Internal interface for storing and retrieving persistent data.
+ */
+public interface PersistentDataBlockManagerInternal {
+
+    /** Stores the handle to a lockscreen credential to be used for Factory Reset Protection. */
+    void setFrpCredentialHandle(byte[] handle);
+
+    /** Retrieves handle to a lockscreen credential to be used for Factory Reset Protection. */
+    byte[] getFrpCredentialHandle();
+}
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index e3cd87c..1d4c3db 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -32,6 +32,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
 
 import libcore.io.IoUtils;
 
@@ -71,8 +72,13 @@
     private static final int HEADER_SIZE = 8;
     // Magic number to mark block device as adhering to the format consumed by this service
     private static final int PARTITION_TYPE_MARKER = 0x19901873;
+    /** Size of the block reserved for FPR credential, including 4 bytes for the size header. */
+    private static final int FRP_CREDENTIAL_RESERVED_SIZE = 1000;
+    /** Maximum size of the FRP credential handle that can be stored. */
+    private static final int MAX_FRP_CREDENTIAL_HANDLE_SIZE = FRP_CREDENTIAL_RESERVED_SIZE - 4;
     // Limit to 100k as blocks larger than this might cause strain on Binder.
     private static final int MAX_DATA_BLOCK_SIZE = 1024 * 100;
+
     public static final int DIGEST_SIZE_BYTES = 32;
     private static final String OEM_UNLOCK_PROP = "sys.oem_unlock_allowed";
     private static final String FLASH_LOCK_PROP = "ro.boot.flash.locked";
@@ -136,6 +142,7 @@
                 Thread.currentThread().interrupt();
                 throw new IllegalStateException("Service " + TAG + " init interrupted", e);
             }
+            LocalServices.addService(PersistentDataBlockManagerInternal.class, mInternalService);
         }
         super.onBootPhase(phase);
     }
@@ -382,7 +389,7 @@
             enforceUid(Binder.getCallingUid());
 
             // Need to ensure we don't write over the last byte
-            long maxBlockSize = getBlockDeviceSize() - HEADER_SIZE - 1;
+            long maxBlockSize = getMaximumDataBlockSize();
             if (data.length > maxBlockSize) {
                 // partition is ~500k so shouldn't be a problem to downcast
                 return (int) -maxBlockSize;
@@ -562,8 +569,99 @@
 
         @Override
         public long getMaximumDataBlockSize() {
-            long actualSize = getBlockDeviceSize() - HEADER_SIZE - 1;
+            long actualSize = getBlockDeviceSize() - HEADER_SIZE - DIGEST_SIZE_BYTES
+                    - FRP_CREDENTIAL_RESERVED_SIZE - 1;
             return actualSize <= MAX_DATA_BLOCK_SIZE ? actualSize : MAX_DATA_BLOCK_SIZE;
         }
+
+        @Override
+        public boolean hasFrpCredentialHandle() {
+            enforcePersistentDataBlockAccess();
+            return mInternalService.getFrpCredentialHandle() != null;
+        }
+    };
+
+    private PersistentDataBlockManagerInternal mInternalService =
+            new PersistentDataBlockManagerInternal() {
+
+        @Override
+        public void setFrpCredentialHandle(byte[] handle) {
+            Preconditions.checkArgument(handle == null || handle.length > 0,
+                    "handle must be null or non-empty");
+            Preconditions.checkArgument(handle == null
+                            || handle.length <= MAX_FRP_CREDENTIAL_HANDLE_SIZE,
+                    "handle must not be longer than " + MAX_FRP_CREDENTIAL_HANDLE_SIZE);
+
+            FileOutputStream outputStream;
+            try {
+                outputStream = new FileOutputStream(new File(mDataBlockFile));
+            } catch (FileNotFoundException e) {
+                Slog.e(TAG, "partition not available", e);
+                return;
+            }
+
+            ByteBuffer data = ByteBuffer.allocate(FRP_CREDENTIAL_RESERVED_SIZE);
+            data.putInt(handle == null ? 0 : handle.length);
+            if (handle != null) {
+                data.put(handle);
+            }
+            data.flip();
+
+            synchronized (mLock) {
+                if (!mIsWritable) {
+                    IoUtils.closeQuietly(outputStream);
+                    return;
+                }
+
+                try {
+                    FileChannel channel = outputStream.getChannel();
+
+                    channel.position(getBlockDeviceSize() - 1 - FRP_CREDENTIAL_RESERVED_SIZE);
+                    channel.write(data);
+                    outputStream.flush();
+                } catch (IOException e) {
+                    Slog.e(TAG, "unable to access persistent partition", e);
+                    return;
+                } finally {
+                    IoUtils.closeQuietly(outputStream);
+                }
+
+                computeAndWriteDigestLocked();
+            }
+        }
+
+        @Override
+        public byte[] getFrpCredentialHandle() {
+            if (!enforceChecksumValidity()) {
+                return null;
+            }
+
+            DataInputStream inputStream;
+            try {
+                inputStream = new DataInputStream(
+                        new FileInputStream(new File(mDataBlockFile)));
+            } catch (FileNotFoundException e) {
+                Slog.e(TAG, "partition not available");
+                return null;
+            }
+
+            try {
+                synchronized (mLock) {
+                    inputStream.skip(getBlockDeviceSize() - 1 - FRP_CREDENTIAL_RESERVED_SIZE);
+                    int length = inputStream.readInt();
+                    if (length <= 0 || length > MAX_FRP_CREDENTIAL_HANDLE_SIZE) {
+                        return null;
+                    }
+                    byte[] bytes = new byte[length];
+                    inputStream.readFully(bytes);
+                    return bytes;
+                }
+            } catch (IOException e) {
+                Slog.e(TAG, "unable to access persistent partition", e);
+                return null;
+            } finally {
+                IoUtils.closeQuietly(inputStream);
+            }
+        }
     };
 }
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index 45f9025..3d7408e 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -267,9 +267,10 @@
 
         // determine the ABI from either ApplicationInfo or Build
         String arch = "arm";
-        if (cameraInfo.primaryCpuAbi != null
-            && VMRuntime.is64BitAbi(cameraInfo.primaryCpuAbi)) {
-            arch = arch + "64";
+        if (cameraInfo.primaryCpuAbi != null) {
+            if (VMRuntime.is64BitAbi(cameraInfo.primaryCpuAbi)) {
+                arch = arch + "64";
+            }
         } else {
             if (VMRuntime.is64BitAbi(Build.SUPPORTED_ABIS[0])) {
                 arch = arch + "64";
diff --git a/services/core/java/com/android/server/RecoverySystemService.java b/services/core/java/com/android/server/RecoverySystemService.java
index 3c8c699..1517887 100644
--- a/services/core/java/com/android/server/RecoverySystemService.java
+++ b/services/core/java/com/android/server/RecoverySystemService.java
@@ -285,8 +285,9 @@
 
                 // Send the BCB commands if it's to setup BCB.
                 if (isSetup) {
-                    dos.writeInt(command.length());
-                    dos.writeBytes(command);
+                    byte[] cmdUtf8 = command.getBytes("UTF-8");
+                    dos.writeInt(cmdUtf8.length);
+                    dos.write(cmdUtf8, 0, cmdUtf8.length);
                     dos.flush();
                 }
 
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 35b452a..383cc8b 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -90,14 +90,12 @@
 import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
-import android.util.SparseArray;
 import android.util.TimeUtils;
 import android.util.Xml;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IMediaContainerService;
 import com.android.internal.os.AppFuseMount;
-import com.android.internal.os.FuseAppLoop;
 import com.android.internal.os.FuseUnavailableMountException;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.os.Zygote;
@@ -143,7 +141,6 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
-import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -2958,6 +2955,11 @@
         synchronized (mLock) {
             mLocalUnlockedUsers = ArrayUtils.appendInt(mLocalUnlockedUsers, userId);
         }
+        if (userId == UserHandle.USER_SYSTEM) {
+            String propertyName = "sys.user." + userId + ".ce_available";
+            Slog.d(TAG, "Setting property: " + propertyName + "=true");
+            SystemProperties.set(propertyName, "true");
+        }
     }
 
     @Override
@@ -3291,20 +3293,41 @@
         }
     }
 
-    @Override
-    public long getAllocatableBytes(String volumeUuid, int flags) {
-        final StorageManager storage = mContext.getSystemService(StorageManager.class);
-        final StorageStatsManager stats = mContext.getSystemService(StorageStatsManager.class);
-
-        // Apps can't defy reserved space
-        flags &= ~StorageManager.FLAG_ALLOCATE_DEFY_RESERVED;
-
-        final boolean aggressive = (flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
-        if (aggressive) {
+    private int adjustAllocateFlags(int flags, int callingUid, String callingPackage) {
+        // Require permission to allocate aggressively
+        if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.ALLOCATE_AGGRESSIVE, TAG);
         }
 
+        // Apps normally can't directly defy reserved space
+        flags &= ~StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED;
+        flags &= ~StorageManager.FLAG_ALLOCATE_DEFY_HALF_RESERVED;
+
+        // However, if app is actively using the camera, then we're willing to
+        // clear up to half of the reserved cache space, since the user might be
+        // trying to capture an important memory.
+        final AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            if (appOps.isOperationActive(AppOpsManager.OP_CAMERA, callingUid, callingPackage)) {
+                Slog.d(TAG, "UID " + callingUid + " is actively using camera;"
+                        + " letting them defy reserved cached data");
+                flags |= StorageManager.FLAG_ALLOCATE_DEFY_HALF_RESERVED;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+
+        return flags;
+    }
+
+    @Override
+    public long getAllocatableBytes(String volumeUuid, int flags, String callingPackage) {
+        flags = adjustAllocateFlags(flags, Binder.getCallingUid(), callingPackage);
+
+        final StorageManager storage = mContext.getSystemService(StorageManager.class);
+        final StorageStatsManager stats = mContext.getSystemService(StorageStatsManager.class);
         final long token = Binder.clearCallingIdentity();
         try {
             // In general, apps can allocate as much space as they want, except
@@ -3319,18 +3342,18 @@
 
             if (stats.isQuotaSupported(volumeUuid)) {
                 final long cacheTotal = stats.getCacheBytes(volumeUuid);
-                final long cacheReserved = storage.getStorageCacheBytes(path);
+                final long cacheReserved = storage.getStorageCacheBytes(path, flags);
                 final long cacheClearable = Math.max(0, cacheTotal - cacheReserved);
 
-                if (aggressive) {
-                    return Math.max(0, (usable + cacheTotal) - fullReserved);
+                if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) {
+                    return Math.max(0, (usable + cacheClearable) - fullReserved);
                 } else {
                     return Math.max(0, (usable + cacheClearable) - lowReserved);
                 }
             } else {
                 // When we don't have fast quota information, we ignore cached
                 // data and only consider unused bytes.
-                if (aggressive) {
+                if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) {
                     return Math.max(0, usable - fullReserved);
                 } else {
                     return Math.max(0, usable - lowReserved);
@@ -3344,20 +3367,16 @@
     }
 
     @Override
-    public void allocateBytes(String volumeUuid, long bytes, int flags) {
-        final StorageManager storage = mContext.getSystemService(StorageManager.class);
+    public void allocateBytes(String volumeUuid, long bytes, int flags, String callingPackage) {
+        flags = adjustAllocateFlags(flags, Binder.getCallingUid(), callingPackage);
 
-        // Apps can't defy reserved space
-        flags &= ~StorageManager.FLAG_ALLOCATE_DEFY_RESERVED;
-
-        // This method call will enforce FLAG_ALLOCATE_AGGRESSIVE permissions so
-        // we don't have to enforce them locally
-        final long allocatableBytes = getAllocatableBytes(volumeUuid, flags);
+        final long allocatableBytes = getAllocatableBytes(volumeUuid, flags, callingPackage);
         if (bytes > allocatableBytes) {
             throw new ParcelableException(new IOException("Failed to allocate " + bytes
                     + " because only " + allocatableBytes + " allocatable"));
         }
 
+        final StorageManager storage = mContext.getSystemService(StorageManager.class);
         final long token = Binder.clearCallingIdentity();
         try {
             // Free up enough disk space to satisfy both the requested allocation
diff --git a/services/core/java/com/android/server/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/SyntheticPasswordCrypto.java
deleted file mode 100644
index 71ab2a5..0000000
--- a/services/core/java/com/android/server/SyntheticPasswordCrypto.java
+++ /dev/null
@@ -1,196 +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;
-
-import android.security.keystore.KeyProperties;
-import android.security.keystore.KeyProtection;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.util.Arrays;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.KeyGenerator;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-public class SyntheticPasswordCrypto {
-    private static final int PROFILE_KEY_IV_SIZE = 12;
-    private static final int AES_KEY_LENGTH = 32; // 256-bit AES key
-    private static final byte[] APPLICATION_ID_PERSONALIZATION = "application-id".getBytes();
-    // Time between the user credential is verified with GK and the decryption of synthetic password
-    // under the auth-bound key. This should always happen one after the other, but give it 15
-    // seconds just to be sure.
-    private static final int USER_AUTHENTICATION_VALIDITY = 15;
-
-    private static byte[] decrypt(SecretKey key, byte[] blob)
-            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
-            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
-        if (blob == null) {
-            return null;
-        }
-        byte[] iv = Arrays.copyOfRange(blob, 0, PROFILE_KEY_IV_SIZE);
-        byte[] ciphertext = Arrays.copyOfRange(blob, PROFILE_KEY_IV_SIZE, blob.length);
-        Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
-                + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
-        cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(128, iv));
-        return cipher.doFinal(ciphertext);
-    }
-
-    private static byte[] encrypt(SecretKey key, byte[] blob)
-            throws IOException, NoSuchAlgorithmException, NoSuchPaddingException,
-            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
-        if (blob == null) {
-            return null;
-        }
-        Cipher cipher = Cipher.getInstance(
-                KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
-                        + KeyProperties.ENCRYPTION_PADDING_NONE);
-        cipher.init(Cipher.ENCRYPT_MODE, key);
-        byte[] ciphertext = cipher.doFinal(blob);
-        byte[] iv = cipher.getIV();
-        if (iv.length != PROFILE_KEY_IV_SIZE) {
-            throw new RuntimeException("Invalid iv length: " + iv.length);
-        }
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        outputStream.write(iv);
-        outputStream.write(ciphertext);
-        return outputStream.toByteArray();
-    }
-
-    public static byte[] encrypt(byte[] keyBytes, byte[] personalisation, byte[] message) {
-        byte[] keyHash = personalisedHash(personalisation, keyBytes);
-        SecretKeySpec key = new SecretKeySpec(Arrays.copyOf(keyHash, AES_KEY_LENGTH),
-                KeyProperties.KEY_ALGORITHM_AES);
-        try {
-            return encrypt(key, message);
-        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
-                | IllegalBlockSizeException | BadPaddingException | IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    public static byte[] decrypt(byte[] keyBytes, byte[] personalisation, byte[] ciphertext) {
-        byte[] keyHash = personalisedHash(personalisation, keyBytes);
-        SecretKeySpec key = new SecretKeySpec(Arrays.copyOf(keyHash, AES_KEY_LENGTH),
-                KeyProperties.KEY_ALGORITHM_AES);
-        try {
-            return decrypt(key, ciphertext);
-        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
-                | IllegalBlockSizeException | BadPaddingException
-                | InvalidAlgorithmParameterException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] applicationId) {
-        try {
-            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-
-            SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
-            byte[] intermediate = decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, blob);
-            return decrypt(decryptionKey, intermediate);
-        } catch (CertificateException | IOException | BadPaddingException
-                | IllegalBlockSizeException
-                | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
-                | InvalidKeyException | UnrecoverableKeyException
-                | InvalidAlgorithmParameterException e) {
-            e.printStackTrace();
-            throw new RuntimeException("Failed to decrypt blob", e);
-        }
-    }
-
-    public static byte[] createBlob(String keyAlias, byte[] data, byte[] applicationId, long sid) {
-        try {
-            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
-            keyGenerator.init(new SecureRandom());
-            SecretKey secretKey = keyGenerator.generateKey();
-            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-            KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
-                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
-                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
-                    .setCriticalToDeviceEncryption(true);
-            if (sid != 0) {
-                builder.setUserAuthenticationRequired(true)
-                        .setBoundToSpecificSecureUserId(sid)
-                        .setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_VALIDITY);
-            }
-
-            keyStore.setEntry(keyAlias,
-                    new KeyStore.SecretKeyEntry(secretKey),
-                    builder.build());
-            byte[] intermediate = encrypt(secretKey, data);
-            return encrypt(applicationId, APPLICATION_ID_PERSONALIZATION, intermediate);
-
-        } catch (CertificateException | IOException | BadPaddingException
-                | IllegalBlockSizeException
-                | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
-                | InvalidKeyException e) {
-            e.printStackTrace();
-            throw new RuntimeException("Failed to encrypt blob", e);
-        }
-    }
-
-    public static void destroyBlobKey(String keyAlias) {
-        KeyStore keyStore;
-        try {
-            keyStore = KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-            keyStore.deleteEntry(keyAlias);
-        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
-                | IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    protected static byte[] personalisedHash(byte[] personalisation, byte[]... message) {
-        try {
-            final int PADDING_LENGTH = 128;
-            MessageDigest digest = MessageDigest.getInstance("SHA-512");
-            if (personalisation.length > PADDING_LENGTH) {
-                throw new RuntimeException("Personalisation too long");
-            }
-            // Personalize the hash
-            // Pad it to the block size of the hash function
-            personalisation = Arrays.copyOf(personalisation, PADDING_LENGTH);
-            digest.update(personalisation);
-            for (byte[] data : message) {
-                digest.update(data);
-            }
-            return digest.digest();
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("NoSuchAlgorithmException for SHA-512", e);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/SyntheticPasswordManager.java b/services/core/java/com/android/server/SyntheticPasswordManager.java
deleted file mode 100644
index 1d17ff7..0000000
--- a/services/core/java/com/android/server/SyntheticPasswordManager.java
+++ /dev/null
@@ -1,707 +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;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.RemoteException;
-import android.service.gatekeeper.GateKeeperResponse;
-import android.service.gatekeeper.IGateKeeperService;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.VerifyCredentialResponse;
-
-import libcore.util.HexEncoding;
-
-import java.nio.ByteBuffer;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Set;
-
-
-/**
- * A class that maintains the wrapping of synthetic password by user credentials or escrow tokens.
- * It's (mostly) a pure storage for synthetic passwords, providing APIs to creating and destroying
- * synthetic password blobs which are wrapped by user credentials or escrow tokens.
- *
- * Here is the assumptions it makes:
- *   Each user has one single synthetic password at any time.
- *   The SP has an associated password handle, which binds to the SID for that user. The password
- *   handle is persisted by SyntheticPasswordManager internally.
- *   If the user credential is null, it's treated as if the credential is DEFAULT_PASSWORD
- *
- * Information persisted on disk:
- *   for each user (stored under DEFAULT_HANDLE):
- *     SP_HANDLE_NAME: GateKeeper password handle of synthetic password. Only available if user
- *                     credential exists, cleared when user clears their credential.
- *     SP_E0_NAME, SP_P1_NAME: Secret to derive synthetic password when combined with escrow
- *                     tokens. Destroyed when escrow support is turned off for the given user.
- *
- *     for each SP blob under the user (stored under the corresponding handle):
- *       SP_BLOB_NAME: The encrypted synthetic password. Always exists.
- *       PASSWORD_DATA_NAME: Metadata about user credential. Only exists for password based SP.
- *       SECDISCARDABLE_NAME: Part of the necessary ingredient to decrypt SP_BLOB_NAME for the
- *                            purpose of secure deletion.
- *
- */
-public class SyntheticPasswordManager {
-    private static final String SP_BLOB_NAME = "spblob";
-    private static final String SP_E0_NAME = "e0";
-    private static final String SP_P1_NAME = "p1";
-    private static final String SP_HANDLE_NAME = "handle";
-    private static final String SECDISCARDABLE_NAME = "secdis";
-    private static final int SECDISCARDABLE_LENGTH = 16 * 1024;
-    private static final String PASSWORD_DATA_NAME = "pwd";
-
-    public static final long DEFAULT_HANDLE = 0;
-    private static final String DEFAULT_PASSWORD = "default-password";
-
-    private static final byte SYNTHETIC_PASSWORD_VERSION = 1;
-    private static final byte SYNTHETIC_PASSWORD_PASSWORD_BASED = 0;
-    private static final byte SYNTHETIC_PASSWORD_TOKEN_BASED = 1;
-
-    // 256-bit synthetic password
-    private static final byte SYNTHETIC_PASSWORD_LENGTH = 256 / 8;
-
-    private static final int PASSWORD_SCRYPT_N = 11;
-    private static final int PASSWORD_SCRYPT_R = 3;
-    private static final int PASSWORD_SCRYPT_P = 1;
-    private static final int PASSWORD_SALT_LENGTH = 16;
-    private static final int PASSWORD_TOKEN_LENGTH = 32;
-    private static final String TAG = "SyntheticPasswordManager";
-
-    private static final byte[] PERSONALISATION_SECDISCARDABLE = "secdiscardable-transform".getBytes();
-    private static final byte[] PERSONALIZATION_KEY_STORE_PASSWORD = "keystore-password".getBytes();
-    private static final byte[] PERSONALIZATION_USER_GK_AUTH = "user-gk-authentication".getBytes();
-    private static final byte[] PERSONALIZATION_SP_GK_AUTH = "sp-gk-authentication".getBytes();
-    private static final byte[] PERSONALIZATION_FBE_KEY = "fbe-key".getBytes();
-    private static final byte[] PERSONALIZATION_SP_SPLIT = "sp-split".getBytes();
-    private static final byte[] PERSONALIZATION_E0 = "e0-encryption".getBytes();
-
-    static class AuthenticationResult {
-        public AuthenticationToken authToken;
-        public VerifyCredentialResponse gkResponse;
-    }
-
-    static class AuthenticationToken {
-        /*
-         * Here is the relationship between all three fields:
-         * P0 and P1 are two randomly-generated blocks. P1 is stored on disk but P0 is not.
-         * syntheticPassword = hash(P0 || P1)
-         * E0 = P0 encrypted under syntheticPassword, stored on disk.
-         */
-        private @Nullable byte[] E0;
-        private @Nullable byte[] P1;
-        private @NonNull String syntheticPassword;
-
-        public String deriveKeyStorePassword() {
-            return bytesToHex(SyntheticPasswordCrypto.personalisedHash(
-                    PERSONALIZATION_KEY_STORE_PASSWORD, syntheticPassword.getBytes()));
-        }
-
-        public byte[] deriveGkPassword() {
-            return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_SP_GK_AUTH,
-                    syntheticPassword.getBytes());
-        }
-
-        public byte[] deriveDiskEncryptionKey() {
-            return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_FBE_KEY,
-                    syntheticPassword.getBytes());
-        }
-
-        private void initialize(byte[] P0, byte[] P1) {
-            this.P1 = P1;
-            this.syntheticPassword = String.valueOf(HexEncoding.encode(
-                    SyntheticPasswordCrypto.personalisedHash(
-                            PERSONALIZATION_SP_SPLIT, P0, P1)));
-            this.E0 = SyntheticPasswordCrypto.encrypt(this.syntheticPassword.getBytes(),
-                    PERSONALIZATION_E0, P0);
-        }
-
-        public void recreate(byte[] secret) {
-            initialize(secret, this.P1);
-        }
-
-        protected static AuthenticationToken create() {
-            AuthenticationToken result = new AuthenticationToken();
-            result.initialize(secureRandom(SYNTHETIC_PASSWORD_LENGTH),
-                    secureRandom(SYNTHETIC_PASSWORD_LENGTH));
-            return result;
-        }
-
-        public byte[] computeP0() {
-            if (E0 == null) {
-                return null;
-            }
-            return SyntheticPasswordCrypto.decrypt(syntheticPassword.getBytes(), PERSONALIZATION_E0,
-                    E0);
-        }
-    }
-
-    static class PasswordData {
-        byte scryptN;
-        byte scryptR;
-        byte scryptP;
-        public int passwordType;
-        byte[] salt;
-        public byte[] passwordHandle;
-
-        public static PasswordData create(int passwordType) {
-            PasswordData result = new PasswordData();
-            result.scryptN = PASSWORD_SCRYPT_N;
-            result.scryptR = PASSWORD_SCRYPT_R;
-            result.scryptP = PASSWORD_SCRYPT_P;
-            result.passwordType = passwordType;
-            result.salt = secureRandom(PASSWORD_SALT_LENGTH);
-            return result;
-        }
-
-        public static PasswordData fromBytes(byte[] data) {
-            PasswordData result = new PasswordData();
-            ByteBuffer buffer = ByteBuffer.allocate(data.length);
-            buffer.put(data, 0, data.length);
-            buffer.flip();
-            result.passwordType = buffer.getInt();
-            result.scryptN = buffer.get();
-            result.scryptR = buffer.get();
-            result.scryptP = buffer.get();
-            int saltLen = buffer.getInt();
-            result.salt = new byte[saltLen];
-            buffer.get(result.salt);
-            int handleLen = buffer.getInt();
-            result.passwordHandle = new byte[handleLen];
-            buffer.get(result.passwordHandle);
-            return result;
-        }
-
-        public byte[] toBytes() {
-            ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + 3 * Byte.BYTES
-                    + Integer.BYTES + salt.length + Integer.BYTES + passwordHandle.length);
-            buffer.putInt(passwordType);
-            buffer.put(scryptN);
-            buffer.put(scryptR);
-            buffer.put(scryptP);
-            buffer.putInt(salt.length);
-            buffer.put(salt);
-            buffer.putInt(passwordHandle.length);
-            buffer.put(passwordHandle);
-            return buffer.array();
-        }
-    }
-
-    private LockSettingsStorage mStorage;
-
-    public SyntheticPasswordManager(LockSettingsStorage storage) {
-        mStorage = storage;
-    }
-
-
-    public int getCredentialType(long handle, int userId) {
-        byte[] passwordData = loadState(PASSWORD_DATA_NAME, handle, userId);
-        if (passwordData == null) {
-            Log.w(TAG, "getCredentialType: encountered empty password data for user " + userId);
-            return LockPatternUtils.CREDENTIAL_TYPE_NONE;
-        }
-        return PasswordData.fromBytes(passwordData).passwordType;
-    }
-
-    /**
-     * Initializing a new Authentication token, possibly from an existing credential and hash.
-     *
-     * The authentication token would bear a randomly-generated synthetic password.
-     *
-     * This method has the side effect of rebinding the SID of the given user to the
-     * newly-generated SP.
-     *
-     * If the existing credential hash is non-null, the existing SID mill be migrated so
-     * the synthetic password in the authentication token will produce the same SID
-     * (the corresponding synthetic password handle is persisted by SyntheticPasswordManager
-     * in a per-user data storage.)
-     *
-     * If the existing credential hash is null, it means the given user should have no SID so
-     * SyntheticPasswordManager will nuke any SP handle previously persisted. In this case,
-     * the supplied credential parameter is also ignored.
-     *
-     * Also saves the escrow information necessary to re-generate the synthetic password under
-     * an escrow scheme. This information can be removed with {@link #destroyEscrowData} if
-     * password escrow should be disabled completely on the given user.
-     *
-     */
-    public AuthenticationToken newSyntheticPasswordAndSid(IGateKeeperService gatekeeper,
-            byte[] hash, String credential, int userId) throws RemoteException {
-        AuthenticationToken result = AuthenticationToken.create();
-        GateKeeperResponse response;
-        if (hash != null) {
-            response = gatekeeper.enroll(userId, hash, credential.getBytes(),
-                    result.deriveGkPassword());
-            if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
-                Log.w(TAG, "Fail to migrate SID, assuming no SID, user " + userId);
-                clearSidForUser(userId);
-            } else {
-                saveSyntheticPasswordHandle(response.getPayload(), userId);
-            }
-        } else {
-            clearSidForUser(userId);
-        }
-        saveEscrowData(result, userId);
-        return result;
-    }
-
-    /**
-     * Enroll a new password handle and SID for the given synthetic password and persist it on disk.
-     * Used when adding password to previously-unsecured devices.
-     */
-    public void newSidForUser(IGateKeeperService gatekeeper, AuthenticationToken authToken,
-            int userId) throws RemoteException {
-        GateKeeperResponse response = gatekeeper.enroll(userId, null, null,
-                authToken.deriveGkPassword());
-        if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
-            Log.e(TAG, "Fail to create new SID for user " + userId);
-            return;
-        }
-        saveSyntheticPasswordHandle(response.getPayload(), userId);
-    }
-
-    // Nuke the SP handle (and as a result, its SID) for the given user.
-    public void clearSidForUser(int userId) {
-        destroyState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
-    }
-
-    public boolean hasSidForUser(int userId) {
-        return hasState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
-    }
-
-    // if null, it means there is no SID associated with the user
-    // This can happen if the user is migrated to SP but currently
-    // do not have a lockscreen password.
-    private byte[] loadSyntheticPasswordHandle(int userId) {
-        return loadState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
-    }
-
-    private void saveSyntheticPasswordHandle(byte[] spHandle, int userId) {
-        saveState(SP_HANDLE_NAME, spHandle, DEFAULT_HANDLE, userId);
-    }
-
-    private boolean loadEscrowData(AuthenticationToken authToken, int userId) {
-        authToken.E0 = loadState(SP_E0_NAME, DEFAULT_HANDLE, userId);
-        authToken.P1 = loadState(SP_P1_NAME, DEFAULT_HANDLE, userId);
-        return authToken.E0 != null && authToken.P1 != null;
-    }
-
-    private void saveEscrowData(AuthenticationToken authToken, int userId) {
-        saveState(SP_E0_NAME, authToken.E0, DEFAULT_HANDLE, userId);
-        saveState(SP_P1_NAME, authToken.P1, DEFAULT_HANDLE, userId);
-    }
-
-    public boolean hasEscrowData(int userId) {
-        return hasState(SP_E0_NAME, DEFAULT_HANDLE, userId)
-                && hasState(SP_P1_NAME, DEFAULT_HANDLE, userId);
-    }
-
-    public void destroyEscrowData(int userId) {
-        destroyState(SP_E0_NAME, DEFAULT_HANDLE, userId);
-        destroyState(SP_P1_NAME, DEFAULT_HANDLE, userId);
-    }
-
-    /**
-     * Create a new password based SP blob based on the supplied authentication token, such that
-     * a future successful authentication with unwrapPasswordBasedSyntheticPassword() would result
-     * in the same authentication token.
-     *
-     * This method only creates SP blob wrapping around the given synthetic password and does not
-     * handle logic around SID or SP handle. The caller should separately ensure that the user's SID
-     * is consistent with the device state by calling other APIs in this class.
-     *
-     * @see #newSidForUser
-     * @see #clearSidForUser
-     */
-    public long createPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
-            String credential, int credentialType, AuthenticationToken authToken, int userId)
-                    throws RemoteException {
-        if (credential == null || credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-            credentialType = LockPatternUtils.CREDENTIAL_TYPE_NONE;
-            credential = DEFAULT_PASSWORD;
-        }
-
-        long handle = generateHandle();
-        PasswordData pwd = PasswordData.create(credentialType);
-        byte[] pwdToken = computePasswordToken(credential, pwd);
-
-        // In case GK enrollment leaves persistent state around (in RPMB), this will nuke them
-        // to prevent them from accumulating and causing problems.
-        gatekeeper.clearSecureUserId(fakeUid(userId));
-        GateKeeperResponse response = gatekeeper.enroll(fakeUid(userId), null, null,
-                passwordTokenToGkInput(pwdToken));
-        if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
-            Log.e(TAG, "Fail to enroll user password when creating SP for user " + userId);
-            return DEFAULT_HANDLE;
-        }
-        pwd.passwordHandle = response.getPayload();
-        long sid = sidFromPasswordHandle(pwd.passwordHandle);
-        saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
-
-        byte[] applicationId = transformUnderSecdiscardable(pwdToken,
-                createSecdiscardable(handle, userId));
-        createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED, authToken,
-                applicationId, sid, userId);
-        return handle;
-    }
-
-    private ArrayMap<Integer, ArrayMap<Long, byte[]>> tokenMap = new ArrayMap<>();
-
-    public long createTokenBasedSyntheticPassword(byte[] token, int userId) {
-        long handle = generateHandle();
-        byte[] applicationId = transformUnderSecdiscardable(token,
-                createSecdiscardable(handle, userId));
-        if (!tokenMap.containsKey(userId)) {
-            tokenMap.put(userId, new ArrayMap<>());
-        }
-        tokenMap.get(userId).put(handle, applicationId);
-        return handle;
-    }
-
-    public Set<Long> getPendingTokensForUser(int userId) {
-        if (!tokenMap.containsKey(userId)) {
-            return Collections.emptySet();
-        }
-        return tokenMap.get(userId).keySet();
-    }
-
-    public boolean removePendingToken(long handle, int userId) {
-        if (!tokenMap.containsKey(userId)) {
-            return false;
-        }
-        return tokenMap.get(userId).remove(handle) != null;
-    }
-
-    public boolean activateTokenBasedSyntheticPassword(long handle, AuthenticationToken authToken,
-            int userId) {
-        if (!tokenMap.containsKey(userId)) {
-            return false;
-        }
-        byte[] applicationId = tokenMap.get(userId).get(handle);
-        if (applicationId == null) {
-            return false;
-        }
-        if (!loadEscrowData(authToken, userId)) {
-            Log.w(TAG, "User is not escrowable");
-            return false;
-        }
-        createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED, authToken,
-                applicationId, 0L, userId);
-        tokenMap.get(userId).remove(handle);
-        return true;
-    }
-
-    private void createSyntheticPasswordBlob(long handle, byte type, AuthenticationToken authToken,
-            byte[] applicationId, long sid, int userId) {
-        final byte[] secret;
-        if (type == SYNTHETIC_PASSWORD_TOKEN_BASED) {
-            secret = authToken.computeP0();
-        } else {
-            secret = authToken.syntheticPassword.getBytes();
-        }
-        byte[] content = createSPBlob(getHandleName(handle), secret, applicationId, sid);
-        byte[] blob = new byte[content.length + 1 + 1];
-        blob[0] = SYNTHETIC_PASSWORD_VERSION;
-        blob[1] = type;
-        System.arraycopy(content, 0, blob, 2, content.length);
-        saveState(SP_BLOB_NAME, blob, handle, userId);
-    }
-
-    /**
-     * Decrypt a synthetic password by supplying the user credential and corresponding password
-     * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
-     * verification to referesh the SID & Auth token maintained by the system.
-     */
-    public AuthenticationResult unwrapPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
-            long handle, String credential, int userId) throws RemoteException {
-        if (credential == null) {
-            credential = DEFAULT_PASSWORD;
-        }
-        AuthenticationResult result = new AuthenticationResult();
-        PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, handle, userId));
-        byte[] pwdToken = computePasswordToken(credential, pwd);
-        byte[] gkPwdToken = passwordTokenToGkInput(pwdToken);
-
-        GateKeeperResponse response = gatekeeper.verifyChallenge(fakeUid(userId), 0L,
-                pwd.passwordHandle, gkPwdToken);
-        int responseCode = response.getResponseCode();
-        if (responseCode == GateKeeperResponse.RESPONSE_OK) {
-            result.gkResponse = VerifyCredentialResponse.OK;
-            if (response.getShouldReEnroll()) {
-                GateKeeperResponse reenrollResponse = gatekeeper.enroll(fakeUid(userId),
-                        pwd.passwordHandle, gkPwdToken, gkPwdToken);
-                if (reenrollResponse.getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
-                    pwd.passwordHandle = reenrollResponse.getPayload();
-                    saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
-                } else {
-                    Log.w(TAG, "Fail to re-enroll user password for user " + userId);
-                    // continue the flow anyway
-                }
-            }
-        } else if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
-            result.gkResponse = new VerifyCredentialResponse(response.getTimeout());
-            return result;
-        } else  {
-            result.gkResponse = VerifyCredentialResponse.ERROR;
-            return result;
-        }
-
-
-        byte[] applicationId = transformUnderSecdiscardable(pwdToken,
-                loadSecdiscardable(handle, userId));
-        result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED,
-                applicationId, userId);
-
-        // Perform verifyChallenge to refresh auth tokens for GK if user password exists.
-        result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
-        return result;
-    }
-
-    /**
-     * Decrypt a synthetic password by supplying an escrow token and corresponding token
-     * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
-     * verification to referesh the SID & Auth token maintained by the system.
-     */
-    public @NonNull AuthenticationResult unwrapTokenBasedSyntheticPassword(
-            IGateKeeperService gatekeeper, long handle, byte[] token, int userId)
-                    throws RemoteException {
-        AuthenticationResult result = new AuthenticationResult();
-        byte[] applicationId = transformUnderSecdiscardable(token,
-                loadSecdiscardable(handle, userId));
-        result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED,
-                applicationId, userId);
-        if (result.authToken != null) {
-            result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
-            if (result.gkResponse == null) {
-                // The user currently has no password. return OK with null payload so null
-                // is propagated to unlockUser()
-                result.gkResponse = VerifyCredentialResponse.OK;
-            }
-        } else {
-            result.gkResponse = VerifyCredentialResponse.ERROR;
-        }
-        return result;
-    }
-
-    private AuthenticationToken unwrapSyntheticPasswordBlob(long handle, byte type,
-            byte[] applicationId, int userId) {
-        byte[] blob = loadState(SP_BLOB_NAME, handle, userId);
-        if (blob == null) {
-            return null;
-        }
-        if (blob[0] != SYNTHETIC_PASSWORD_VERSION) {
-            throw new RuntimeException("Unknown blob version");
-        }
-        if (blob[1] != type) {
-            throw new RuntimeException("Invalid blob type");
-        }
-        byte[] secret = decryptSPBlob(getHandleName(handle),
-                Arrays.copyOfRange(blob, 2, blob.length), applicationId);
-        if (secret == null) {
-            Log.e(TAG, "Fail to decrypt SP for user " + userId);
-            return null;
-        }
-        AuthenticationToken result = new AuthenticationToken();
-        if (type == SYNTHETIC_PASSWORD_TOKEN_BASED) {
-            if (!loadEscrowData(result, userId)) {
-                Log.e(TAG, "User is not escrowable: " + userId);
-                return null;
-            }
-            result.recreate(secret);
-        } else {
-            result.syntheticPassword = new String(secret);
-        }
-        return result;
-    }
-
-    /**
-     * performs GK verifyChallenge and returns auth token, re-enrolling SP password handle
-     * if required.
-     *
-     * Normally performing verifyChallenge with an AuthenticationToken should always return
-     * RESPONSE_OK, since user authentication failures are detected earlier when trying to
-     * decrypt SP.
-     */
-    public @Nullable VerifyCredentialResponse verifyChallenge(IGateKeeperService gatekeeper,
-            @NonNull AuthenticationToken auth, long challenge, int userId) throws RemoteException {
-        byte[] spHandle = loadSyntheticPasswordHandle(userId);
-        if (spHandle == null) {
-            // There is no password handle associated with the given user, i.e. the user is not
-            // secured by lockscreen and has no SID, so just return here;
-            return null;
-        }
-        VerifyCredentialResponse result;
-        GateKeeperResponse response = gatekeeper.verifyChallenge(userId, challenge,
-                spHandle, auth.deriveGkPassword());
-        int responseCode = response.getResponseCode();
-        if (responseCode == GateKeeperResponse.RESPONSE_OK) {
-            result = new VerifyCredentialResponse(response.getPayload());
-            if (response.getShouldReEnroll()) {
-                response = gatekeeper.enroll(userId, spHandle,
-                        spHandle, auth.deriveGkPassword());
-                if (response.getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
-                    spHandle = response.getPayload();
-                    saveSyntheticPasswordHandle(spHandle, userId);
-                    // Call self again to re-verify with updated handle
-                    return verifyChallenge(gatekeeper, auth, challenge, userId);
-                } else {
-                    Log.w(TAG, "Fail to re-enroll SP handle for user " + userId);
-                    // Fall through, return existing handle
-                }
-            }
-        } else if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
-            result = new VerifyCredentialResponse(response.getTimeout());
-        } else {
-            result = VerifyCredentialResponse.ERROR;
-        }
-        return result;
-    }
-
-    public boolean existsHandle(long handle, int userId) {
-        return hasState(SP_BLOB_NAME, handle, userId);
-    }
-
-    public void destroyTokenBasedSyntheticPassword(long handle, int userId) {
-        destroySyntheticPassword(handle, userId);
-        destroyState(SECDISCARDABLE_NAME, handle, userId);
-    }
-
-    public void destroyPasswordBasedSyntheticPassword(long handle, int userId) {
-        destroySyntheticPassword(handle, userId);
-        destroyState(SECDISCARDABLE_NAME, handle, userId);
-        destroyState(PASSWORD_DATA_NAME, handle, userId);
-    }
-
-    private void destroySyntheticPassword(long handle, int userId) {
-        destroyState(SP_BLOB_NAME, handle, userId);
-        destroySPBlobKey(getHandleName(handle));
-    }
-
-    private byte[] transformUnderSecdiscardable(byte[] data, byte[] rawSecdiscardable) {
-        byte[] secdiscardable = SyntheticPasswordCrypto.personalisedHash(
-                PERSONALISATION_SECDISCARDABLE, rawSecdiscardable);
-        byte[] result = new byte[data.length + secdiscardable.length];
-        System.arraycopy(data, 0, result, 0, data.length);
-        System.arraycopy(secdiscardable, 0, result, data.length, secdiscardable.length);
-        return result;
-    }
-
-    private byte[] createSecdiscardable(long handle, int userId) {
-        byte[] data = secureRandom(SECDISCARDABLE_LENGTH);
-        saveState(SECDISCARDABLE_NAME, data, handle, userId);
-        return data;
-    }
-
-    private byte[] loadSecdiscardable(long handle, int userId) {
-        return loadState(SECDISCARDABLE_NAME, handle, userId);
-    }
-
-    private boolean hasState(String stateName, long handle, int userId) {
-        return !ArrayUtils.isEmpty(loadState(stateName, handle, userId));
-    }
-
-    private byte[] loadState(String stateName, long handle, int userId) {
-        return mStorage.readSyntheticPasswordState(userId, handle, stateName);
-    }
-
-    private void saveState(String stateName, byte[] data, long handle, int userId) {
-        mStorage.writeSyntheticPasswordState(userId, handle, stateName, data);
-    }
-
-    private void destroyState(String stateName, long handle, int userId) {
-        mStorage.deleteSyntheticPasswordState(userId, handle, stateName);
-    }
-
-    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
-        return SyntheticPasswordCrypto.decryptBlob(blobKeyName, blob, applicationId);
-    }
-
-    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
-        return SyntheticPasswordCrypto.createBlob(blobKeyName, data, applicationId, sid);
-    }
-
-    protected void destroySPBlobKey(String keyAlias) {
-        SyntheticPasswordCrypto.destroyBlobKey(keyAlias);
-    }
-
-    public static long generateHandle() {
-        SecureRandom rng = new SecureRandom();
-        long result;
-        do {
-            result = rng.nextLong();
-        } while (result == DEFAULT_HANDLE);
-        return result;
-    }
-
-    private int fakeUid(int uid) {
-        return 100000 + uid;
-    }
-
-    protected static byte[] secureRandom(int length) {
-        try {
-            return SecureRandom.getInstance("SHA1PRNG").generateSeed(length);
-        } catch (NoSuchAlgorithmException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    private String getHandleName(long handle) {
-        return String.format("%s%x", LockPatternUtils.SYNTHETIC_PASSWORD_KEY_PREFIX, handle);
-    }
-
-    private byte[] computePasswordToken(String password, PasswordData data) {
-        return scrypt(password, data.salt, 1 << data.scryptN, 1 << data.scryptR, 1 << data.scryptP,
-                PASSWORD_TOKEN_LENGTH);
-    }
-
-    private byte[] passwordTokenToGkInput(byte[] token) {
-        return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_USER_GK_AUTH, token);
-    }
-
-    protected long sidFromPasswordHandle(byte[] handle) {
-        return nativeSidFromPasswordHandle(handle);
-    }
-
-    protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) {
-        return nativeScrypt(password.getBytes(), salt, N, r, p, outLen);
-    }
-
-    native long nativeSidFromPasswordHandle(byte[] handle);
-    native byte[] nativeScrypt(byte[] password, byte[] salt, int N, int r, int p, int outLen);
-
-    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
-    public static String bytesToHex(byte[] bytes) {
-        if (bytes == null) {
-            return "null";
-        }
-        char[] hexChars = new char[bytes.length * 2];
-        for ( int j = 0; j < bytes.length; j++ ) {
-            int v = bytes[j] & 0xFF;
-            hexChars[j * 2] = hexArray[v >>> 4];
-            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
-        }
-        return new String(hexChars);
-    }
-}
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index 72ff606..581914d 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.os.SystemClock;
 import android.os.Trace;
 import android.util.Slog;
 
@@ -118,14 +119,14 @@
         // Register it.
         mServices.add(service);
         // Start it.
-        long time = System.currentTimeMillis();
+        long time = SystemClock.elapsedRealtime();
         try {
             service.onStart();
         } catch (RuntimeException ex) {
             throw new RuntimeException("Failed to start service " + service.getClass().getName()
                     + ": onStart threw an exception", ex);
         }
-        warnIfTooLong(System.currentTimeMillis() - time, service, "onStart");
+        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
     }
 
     /**
@@ -146,7 +147,7 @@
             final int serviceLen = mServices.size();
             for (int i = 0; i < serviceLen; i++) {
                 final SystemService service = mServices.get(i);
-                long time = System.currentTimeMillis();
+                long time = SystemClock.elapsedRealtime();
                 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, service.getClass().getName());
                 try {
                     service.onBootPhase(mCurrentPhase);
@@ -156,7 +157,7 @@
                             + ": onBootPhase threw an exception during phase "
                             + mCurrentPhase, ex);
                 }
-                warnIfTooLong(System.currentTimeMillis() - time, service, "onBootPhase");
+                warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onBootPhase");
                 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
         } finally {
@@ -178,14 +179,14 @@
             final SystemService service = mServices.get(i);
             Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onStartUser "
                     + service.getClass().getName());
-            long time = System.currentTimeMillis();
+            long time = SystemClock.elapsedRealtime();
             try {
                 service.onStartUser(userHandle);
             } catch (Exception ex) {
                 Slog.wtf(TAG, "Failure reporting start of user " + userHandle
                         + " to service " + service.getClass().getName(), ex);
             }
-            warnIfTooLong(System.currentTimeMillis() - time, service, "onStartUser ");
+            warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStartUser ");
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
     }
@@ -197,14 +198,14 @@
             final SystemService service = mServices.get(i);
             Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onUnlockUser "
                     + service.getClass().getName());
-            long time = System.currentTimeMillis();
+            long time = SystemClock.elapsedRealtime();
             try {
                 service.onUnlockUser(userHandle);
             } catch (Exception ex) {
                 Slog.wtf(TAG, "Failure reporting unlock of user " + userHandle
                         + " to service " + service.getClass().getName(), ex);
             }
-            warnIfTooLong(System.currentTimeMillis() - time, service, "onUnlockUser ");
+            warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onUnlockUser ");
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
     }
@@ -216,14 +217,14 @@
             final SystemService service = mServices.get(i);
             Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onSwitchUser "
                     + service.getClass().getName());
-            long time = System.currentTimeMillis();
+            long time = SystemClock.elapsedRealtime();
             try {
                 service.onSwitchUser(userHandle);
             } catch (Exception ex) {
                 Slog.wtf(TAG, "Failure reporting switch of user " + userHandle
                         + " to service " + service.getClass().getName(), ex);
             }
-            warnIfTooLong(System.currentTimeMillis() - time, service, "onSwitchUser");
+            warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onSwitchUser");
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
     }
@@ -235,14 +236,14 @@
             final SystemService service = mServices.get(i);
             Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onStopUser "
                     + service.getClass().getName());
-            long time = System.currentTimeMillis();
+            long time = SystemClock.elapsedRealtime();
             try {
                 service.onStopUser(userHandle);
             } catch (Exception ex) {
                 Slog.wtf(TAG, "Failure reporting stop of user " + userHandle
                         + " to service " + service.getClass().getName(), ex);
             }
-            warnIfTooLong(System.currentTimeMillis() - time, service, "onStopUser");
+            warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStopUser");
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
     }
@@ -254,14 +255,14 @@
             final SystemService service = mServices.get(i);
             Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onCleanupUser "
                     + service.getClass().getName());
-            long time = System.currentTimeMillis();
+            long time = SystemClock.elapsedRealtime();
             try {
                 service.onCleanupUser(userHandle);
             } catch (Exception ex) {
                 Slog.wtf(TAG, "Failure reporting cleanup of user " + userHandle
                         + " to service " + service.getClass().getName(), ex);
             }
-            warnIfTooLong(System.currentTimeMillis() - time, service, "onCleanupUser");
+            warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onCleanupUser");
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
     }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index e609bd7..831c9cb 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1356,31 +1356,6 @@
         }
     }
 
-    public void notifyOemHookRawEventForSubscriber(int subId, byte[] rawData) {
-        if (!checkNotifyPermission("notifyOemHookRawEventForSubscriber")) {
-            return;
-        }
-
-        synchronized (mRecords) {
-            for (Record r : mRecords) {
-                if (VDBG) {
-                    log("notifyOemHookRawEventForSubscriber:  r=" + r + " subId=" + subId);
-                }
-                if ((r.matchPhoneStateListenerEvent(
-                        PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT)) &&
-                        ((r.subId == subId) ||
-                        (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID))) {
-                    try {
-                        r.callback.onOemHookRawEvent(rawData);
-                    } catch (RemoteException ex) {
-                        mRemoveList.add(r.binder);
-                    }
-                }
-            }
-            handleRemoveListLocked();
-        }
-    }
-
     @Override
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
@@ -1673,11 +1648,6 @@
                     android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
 
         }
-
-        if ((events & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
-        }
     }
 
     private void handleRemoveListLocked() {
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 16e63b3..4733840 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -48,6 +48,7 @@
 import android.os.WorkSource;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
+import android.util.DebugUtils;
 import android.util.Slog;
 import android.view.InputDevice;
 import android.media.AudioAttributes;
@@ -60,10 +61,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
 import java.util.LinkedList;
-import java.util.ListIterator;
 
 public class VibratorService extends IVibratorService.Stub
         implements InputManager.InputDeviceListener {
@@ -225,19 +223,24 @@
 
         long[] clickEffectTimings = getLongIntArray(context.getResources(),
                 com.android.internal.R.array.config_virtualKeyVibePattern);
-        VibrationEffect clickEffect;
-        if (clickEffectTimings.length == 0) {
-            clickEffect = null;
-        } else if (clickEffectTimings.length == 1) {
-            clickEffect = VibrationEffect.createOneShot(
-                    clickEffectTimings[0], VibrationEffect.DEFAULT_AMPLITUDE);
-        } else {
-            clickEffect = VibrationEffect.createWaveform(clickEffectTimings, -1);
-        }
+        VibrationEffect clickEffect = createEffect(clickEffectTimings);
         VibrationEffect doubleClickEffect = VibrationEffect.createWaveform(
                 new long[] {0, 30, 100, 30} /*timings*/, -1);
+        long[] tickEffectTimings = getLongIntArray(context.getResources(),
+                com.android.internal.R.array.config_clockTickVibePattern);
+        VibrationEffect tickEffect = createEffect(tickEffectTimings);
 
-        mFallbackEffects = new VibrationEffect[] { clickEffect, doubleClickEffect };
+        mFallbackEffects = new VibrationEffect[] { clickEffect, doubleClickEffect, tickEffect };
+    }
+
+    private static VibrationEffect createEffect(long[] timings) {
+        if (timings == null || timings.length == 0) {
+            return null;
+        } else if (timings.length == 1) {
+            return VibrationEffect.createOneShot(timings[0], VibrationEffect.DEFAULT_AMPLITUDE);
+        } else {
+            return VibrationEffect.createWaveform(timings, -1);
+        }
     }
 
     public void systemReady() {
@@ -943,6 +946,21 @@
         }
 
         private int runVibrate() {
+            try {
+                final int zenMode = Settings.Global.getInt(mContext.getContentResolver(),
+                        Settings.Global.ZEN_MODE);
+                if (zenMode != Settings.Global.ZEN_MODE_OFF) {
+                    try (PrintWriter pw = getOutPrintWriter();) {
+                        pw.print("Ignoring because device is on DND mode ");
+                        pw.println(DebugUtils.flagsToString(Settings.Global.class, "ZEN_MODE_",
+                                zenMode));
+                        return 0;
+                    }
+                }
+            } catch (SettingNotFoundException e) {
+                // ignore
+            }
+
             final long duration = Long.parseLong(getNextArgRequired());
             if (duration > MAX_VIBRATION_MS) {
                 throw new IllegalArgumentException("maximum duration is " + MAX_VIBRATION_MS);
@@ -967,7 +985,8 @@
                 pw.println("    Prints this help text.");
                 pw.println("");
                 pw.println("  vibrate duration [description]");
-                pw.println("    Vibrates for duration milliseconds.");
+                pw.println("    Vibrates for duration milliseconds; ignored when device is on DND ");
+                pw.println("    (Do Not Disturb) mode.");
                 pw.println("");
             }
         }
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 93e29c1..6a81d32 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -91,8 +91,9 @@
         "android.hardware.bluetooth@1.0::IBluetoothHci",
         "android.hardware.camera.provider@2.4::ICameraProvider",
         "android.hardware.graphics.composer@2.1::IComposer",
-        "android.hardware.vr@1.0::IVr",
-        "android.hardware.media.omx@1.0::IOmx"
+        "android.hardware.media.omx@1.0::IOmx",
+        "android.hardware.sensors@1.0::ISensors",
+        "android.hardware.vr@1.0::IVr"
     );
 
     static Watchdog sWatchdog;
diff --git a/services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java b/services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java
index 7552368..b9453db 100644
--- a/services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java
+++ b/services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java
@@ -53,6 +53,7 @@
                 AccountManager.AUTHENTICATOR_ATTRIBUTES_NAME, sSerializer);
     }
 
+    @Override
     public AuthenticatorDescription parseServiceAttributes(Resources res,
             String packageName, AttributeSet attrs) {
         TypedArray sa = res.obtainAttributes(attrs,
@@ -81,11 +82,13 @@
     }
 
     private static class MySerializer implements XmlSerializerAndParser<AuthenticatorDescription> {
+        @Override
         public void writeAsXml(AuthenticatorDescription item, XmlSerializer out)
                 throws IOException {
             out.attribute(null, "type", item.type);
         }
 
+        @Override
         public AuthenticatorDescription createFromXml(XmlPullParser parser)
                 throws IOException, XmlPullParserException {
             return AuthenticatorDescription.newKey(parser.getAttributeValue(null, "type"));
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index f0b1b3b..86ce12e 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -1372,6 +1372,7 @@
         if (accounts != null) {
             synchronized (accounts.dbLock) {
                 synchronized (accounts.cacheLock) {
+                    accounts.statementForLogging.close();
                     accounts.accountsDb.close();
                 }
             }
@@ -2233,12 +2234,10 @@
                         Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response "
                                 + response);
                     }
-                    Bundle result2 = new Bundle();
-                    result2.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, removalAllowed);
                     try {
-                        response.onResult(result2);
+                        response.onResult(result);
                     } catch (RemoteException e) {
-                        // ignore
+                        Slog.e(TAG, "Error calling onResult()", e);
                     }
                 }
             }
@@ -5060,6 +5059,7 @@
                 this.userDebugDbInsertionPoint = userDebugDbInsertionPoint;
             }
 
+            @Override
             public void run() {
                 SQLiteStatement logStatement = userAccount.statementForLogging;
                 logStatement.bindLong(1, accountId);
@@ -5068,8 +5068,16 @@
                 logStatement.bindLong(4, callingUid);
                 logStatement.bindString(5, tableName);
                 logStatement.bindLong(6, userDebugDbInsertionPoint);
-                logStatement.execute();
-                logStatement.clearBindings();
+                try {
+                    logStatement.execute();
+                } catch (IllegalStateException e) {
+                    // Guard against crash, DB can already be closed
+                    // since this statement is executed on a handler thread
+                    Slog.w(TAG, "Failed to insert a log record. accountId=" + accountId
+                            + " action=" + action + " tableName=" + tableName + " Error: " + e);
+                } finally {
+                    logStatement.clearBindings();
+                }
             }
         }
 
@@ -5287,25 +5295,25 @@
         long identityToken = Binder.clearCallingIdentity();
         try {
             packages = mPackageManager.getPackagesForUid(callingUid);
-        } finally {
-            Binder.restoreCallingIdentity(identityToken);
-        }
-        if (packages == null) {
-            Log.d(TAG, "No packages for callingUid " + callingUid);
-            return false;
-        }
-        for (String name : packages) {
-            try {
-                PackageInfo packageInfo = mPackageManager.getPackageInfo(name, 0 /* flags */);
-                if (packageInfo != null
-                        && (packageInfo.applicationInfo.privateFlags
-                                & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
-                    return true;
-                }
-            } catch (PackageManager.NameNotFoundException e) {
-                Log.d(TAG, "Package not found " + e.getMessage());
+            if (packages == null) {
+                Log.d(TAG, "No packages for callingUid " + callingUid);
                 return false;
             }
+            for (String name : packages) {
+                try {
+                    PackageInfo packageInfo =
+                        mPackageManager.getPackageInfo(name, 0 /* flags */);
+                    if (packageInfo != null
+                        && (packageInfo.applicationInfo.privateFlags
+                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
+                        return true;
+                    }
+                } catch (PackageManager.NameNotFoundException e) {
+                    Log.d(TAG, "Package not found " + e.getMessage());
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identityToken);
         }
         return false;
     }
@@ -6176,7 +6184,7 @@
         }
     }
 
-    private class NotificationId {
+    private static class NotificationId {
         final String mTag;
         private final int mId;
 
diff --git a/services/core/java/com/android/server/accounts/AccountsDb.java b/services/core/java/com/android/server/accounts/AccountsDb.java
index 8ca7ea1..0c3d268 100644
--- a/services/core/java/com/android/server/accounts/AccountsDb.java
+++ b/services/core/java/com/android/server/accounts/AccountsDb.java
@@ -1321,6 +1321,7 @@
         }
     }
 
+    @Override
     public void close() {
         mDeDatabase.close();
     }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5f679db..70c08c92 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -20,6 +20,7 @@
 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
 import static android.Manifest.permission.READ_FRAME_BUFFER;
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
@@ -606,6 +607,8 @@
     // the notification will not be legible to the user.
     private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
 
+    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
+
     /** All system services */
     SystemServiceManager mSystemServiceManager;
     AssistUtils mAssistUtils;
@@ -716,7 +719,9 @@
 
     public boolean canShowErrorDialogs() {
         return mShowDialogs && !mSleeping && !mShuttingDown
-                && !mKeyguardController.isKeyguardShowing();
+                && !mKeyguardController.isKeyguardShowing()
+                && !(UserManager.isDeviceInDemoMode(mContext)
+                        && mUserController.getCurrentUser().isDemo());
     }
 
     private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
@@ -1462,12 +1467,6 @@
             = new ProcessMap<ArrayList<ProcessRecord>>();
 
     /**
-     * This is set if we had to do a delayed dexopt of an app before launching
-     * it, to increase the ANR timeouts in that case.
-     */
-    boolean mDidDexOpt;
-
-    /**
      * Set if the systemServer made a call to enterSafeMode.
      */
     boolean mSafeMode;
@@ -1963,13 +1962,6 @@
                 }
             } break;
             case SERVICE_TIMEOUT_MSG: {
-                if (mDidDexOpt) {
-                    mDidDexOpt = false;
-                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
-                    nmsg.obj = msg.obj;
-                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
-                    return;
-                }
                 mServices.serviceTimeout((ProcessRecord)msg.obj);
             } break;
             case SERVICE_FOREGROUND_TIMEOUT_MSG: {
@@ -2045,13 +2037,6 @@
                 }
             } break;
             case PROC_START_TIMEOUT_MSG: {
-                if (mDidDexOpt) {
-                    mDidDexOpt = false;
-                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
-                    nmsg.obj = msg.obj;
-                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
-                    return;
-                }
                 ProcessRecord app = (ProcessRecord)msg.obj;
                 synchronized (ActivityManagerService.this) {
                     processStartTimedOutLocked(app);
@@ -3823,6 +3808,10 @@
                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
+
+                // Replace any invalid GIDs
+                if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
+                if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
             }
             checkTime(startTime, "startProcess: building args");
             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
@@ -3836,41 +3825,47 @@
                     uid = 0;
                 }
             }
-            int debugFlags = 0;
+            int runtimeFlags = 0;
             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
-                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
-                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
+                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
+                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
                 // Also turn on CheckJNI for debuggable apps. It's quite
                 // awkward to turn on otherwise.
-                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
+                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
             }
             // Run the app in safe mode if its manifest requests so or the
             // system is booted in safe mode.
             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
                 mSafeMode == true) {
-                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
+                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
             }
             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
-                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
+                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
             }
             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
             if ("true".equals(genDebugInfoProperty)) {
-                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
+                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
             }
             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
-                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
+                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
             }
             if ("1".equals(SystemProperties.get("debug.assert"))) {
-                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
+                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
             }
             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
                 // Enable all debug flags required by the native debugger.
-                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
-                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
-                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
+                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
+                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
+                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
                 mNativeDebuggingApp = null;
             }
 
+            if (app.info.isPrivilegedApp() &&
+                    SystemProperties.getBoolean("pm.dexopt.priv-apps-oob", false)) {
+                runtimeFlags |= Zygote.DISABLE_VERIFIER;
+                runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
+            }
+
             String invokeWith = null;
             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
                 // Debuggable apps may include a wrapper script with their library directory.
@@ -3917,12 +3912,12 @@
             ProcessStartResult startResult;
             if (hostingType.equals("webview_service")) {
                 startResult = startWebView(entryPoint,
-                        app.processName, uid, uid, gids, debugFlags, mountExternal,
+                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                         app.info.dataDir, null, entryPointArgs);
             } else {
                 startResult = Process.start(entryPoint,
-                        app.processName, uid, uid, gids, debugFlags, mountExternal,
+                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                         app.info.dataDir, invokeWith, entryPointArgs);
             }
@@ -5454,34 +5449,103 @@
      * @param firstPids of dalvik VM processes to dump stack traces for first
      * @param lastPids of dalvik VM processes to dump stack traces for last
      * @param nativePids optional list of native pids to dump stack crawls
-     * @return file containing stack traces, or null if no dump file is configured
      */
     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
             ArrayList<Integer> nativePids) {
-        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
-        if (tracesPath == null || tracesPath.length() == 0) {
-            return null;
+        ArrayList<Integer> extraPids = null;
+
+        // Measure CPU usage as soon as we're called in order to get a realistic sampling
+        // of the top users at the time of the request.
+        if (processCpuTracker != null) {
+            processCpuTracker.init();
+            try {
+                Thread.sleep(200);
+            } catch (InterruptedException ignored) {
+            }
+
+            processCpuTracker.update();
+
+            // We'll take the stack crawls of just the top apps using CPU.
+            final int N = processCpuTracker.countWorkingStats();
+            extraPids = new ArrayList<>();
+            for (int i = 0; i < N && extraPids.size() < 5; i++) {
+                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
+                if (lastPids.indexOfKey(stats.pid) >= 0) {
+                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
+
+                    extraPids.add(stats.pid);
+                } else if (DEBUG_ANR) {
+                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
+                            + stats.pid);
+                }
+            }
         }
 
-        File tracesFile = new File(tracesPath);
-        try {
-            if (clearTraces && tracesFile.exists()) tracesFile.delete();
-            tracesFile.createNewFile();
-            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
-        } catch (IOException e) {
-            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
-            return null;
+        boolean useTombstonedForJavaTraces = false;
+        File tracesFile;
+
+        final String tracesDir = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
+        if (tracesDir.isEmpty()) {
+            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
+            // dumping scheme. All traces are written to a global trace file (usually
+            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
+            // the file if requested.
+            //
+            // This mode of operation will be removed in the near future.
+
+
+            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
+            if (globalTracesPath.isEmpty()) {
+                Slog.w(TAG, "dumpStackTraces: no trace path configured");
+                return null;
+            }
+
+            tracesFile = new File(globalTracesPath);
+            try {
+                if (clearTraces && tracesFile.exists()) {
+                    tracesFile.delete();
+                }
+
+                tracesFile.createNewFile();
+                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
+            } catch (IOException e) {
+                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
+                return null;
+            }
+        } else {
+            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
+            // Each set of ANR traces is written to a separate file and dumpstate will process
+            // all such files and add them to a captured bug report if they're recent enough.
+            //
+            // NOTE: We should consider creating the file in native code atomically once we've
+            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
+            // can be removed.
+            try {
+                tracesFile = File.createTempFile("anr_", "", new File(tracesDir));
+                FileUtils.setPermissions(tracesFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
+            } catch (IOException ioe) {
+                Slog.w(TAG, "Unable to create ANR traces file: ", ioe);
+                return null;
+            }
+
+            useTombstonedForJavaTraces = true;
         }
 
-        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativePids);
+        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
+                useTombstonedForJavaTraces);
         return tracesFile;
     }
 
+    /**
+     * Legacy code, do not use. Existing users will be deleted.
+     *
+     * @deprecated
+     */
+    @Deprecated
     public static class DumpStackFileObserver extends FileObserver {
         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
-        static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
 
         private final String mTracesPath;
         private boolean mClosed;
@@ -5535,17 +5599,45 @@
         }
     }
 
-    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
-            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
-            ArrayList<Integer> nativePids) {
-        // Use a FileObserver to detect when traces finish writing.
-        // The order of traces is considered important to maintain for legibility.
-        DumpStackFileObserver observer = new DumpStackFileObserver(tracesPath);
+    /**
+     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
+     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
+     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
+     * attempting to obtain native traces in the case of a failure. Returns the total time spent
+     * capturing traces.
+     */
+    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
+        final long timeStart = SystemClock.elapsedRealtime();
+        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
+            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
+                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
+        }
+
+        return SystemClock.elapsedRealtime() - timeStart;
+    }
+
+    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
+            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
+            boolean useTombstonedForJavaTraces) {
+
+        // We don't need any sort of inotify based monitoring when we're dumping traces via
+        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
+        // control of all writes to the file in question.
+        final DumpStackFileObserver observer;
+        if (useTombstonedForJavaTraces) {
+            observer = null;
+        } else {
+            // Use a FileObserver to detect when traces finish writing.
+            // The order of traces is considered important to maintain for legibility.
+            observer = new DumpStackFileObserver(tracesFile);
+        }
 
         // We must complete all stack dumps within 20 seconds.
         long remainingTime = 20 * 1000;
         try {
-            observer.startWatching();
+            if (observer != null) {
+                observer.startWatching();
+            }
 
             // First collect all of the stacks of the most important pids.
             if (firstPids != null) {
@@ -5553,7 +5645,12 @@
                 for (int i = 0; i < num; i++) {
                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
                             + firstPids.get(i));
-                    final long timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
+                    final long timeTaken;
+                    if (useTombstonedForJavaTraces) {
+                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
+                    } else {
+                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
+                    }
 
                     remainingTime -= timeTaken;
                     if (remainingTime <= 0) {
@@ -5572,12 +5669,11 @@
             if (nativePids != null) {
                 for (int pid : nativePids) {
                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
-                    final long nativeDumpTimeoutMs = Math.min(
-                            DumpStackFileObserver.NATIVE_DUMP_TIMEOUT_MS, remainingTime);
+                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
 
                     final long start = SystemClock.elapsedRealtime();
                     Debug.dumpNativeBacktraceToFileTimeout(
-                            pid, tracesPath, (int) (nativeDumpTimeoutMs / 1000));
+                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
                     final long timeTaken = SystemClock.elapsedRealtime() - start;
 
                     remainingTime -= timeTaken;
@@ -5593,48 +5689,34 @@
                 }
             }
 
-            // Lastly, measure CPU usage.
-            if (processCpuTracker != null) {
-                processCpuTracker.init();
-                System.gc();
-                processCpuTracker.update();
-                try {
-                    synchronized (processCpuTracker) {
-                        processCpuTracker.wait(500); // measure over 1/2 second.
+            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
+            if (extraPids != null) {
+                for (int pid : extraPids) {
+                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
+
+                    final long timeTaken;
+                    if (useTombstonedForJavaTraces) {
+                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
+                    } else {
+                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
                     }
-                } catch (InterruptedException e) {
-                }
-                processCpuTracker.update();
 
-                // We'll take the stack crawls of just the top apps using CPU.
-                final int N = processCpuTracker.countWorkingStats();
-                int numProcs = 0;
-                for (int i=0; i<N && numProcs<5; i++) {
-                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
-                    if (lastPids.indexOfKey(stats.pid) >= 0) {
-                        numProcs++;
-
-                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
-
-                        final long timeTaken = observer.dumpWithTimeout(stats.pid, remainingTime);
-                        remainingTime -= timeTaken;
-                        if (remainingTime <= 0) {
-                            Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + stats.pid +
+                    remainingTime -= timeTaken;
+                    if (remainingTime <= 0) {
+                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
                                 "); deadline exceeded.");
-                            return;
-                        }
+                        return;
+                    }
 
-                        if (DEBUG_ANR) {
-                            Slog.d(TAG, "Done with extra pid " + stats.pid + " in " + timeTaken + "ms");
-                        }
-                    } else if (DEBUG_ANR) {
-                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
-                                + stats.pid);
+                    if (DEBUG_ANR) {
+                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
                     }
                 }
             }
         } finally {
-            observer.stopWatching();
+            if (observer != null) {
+                observer.stopWatching();
+            }
         }
     }
 
@@ -5681,7 +5763,7 @@
             if (app != null) {
                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
                 firstPids.add(app.pid);
-                dumpStackTraces(tracesPath, firstPids, null, null, null);
+                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
             }
 
             File lastTracesFile = null;
@@ -10228,7 +10310,7 @@
 
     @Override
     public void moveStackToDisplay(int stackId, int displayId) {
-        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
+        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
 
         synchronized (this) {
             final long ident = Binder.clearCallingIdentity();
@@ -12390,10 +12472,10 @@
         switch (mWakefulness) {
             case PowerManagerInternal.WAKEFULNESS_AWAKE:
             case PowerManagerInternal.WAKEFULNESS_DREAMING:
-            case PowerManagerInternal.WAKEFULNESS_DOZING:
                 // Pause applications whenever the lock screen is shown or any sleep
                 // tokens have been acquired.
                 return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
+            case PowerManagerInternal.WAKEFULNESS_DOZING:
             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
             default:
                 // If we're asleep then pause applications unconditionally.
@@ -12852,7 +12934,7 @@
             timeout = getInputDispatchingTimeoutLocked(proc);
         }
 
-        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
+        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
             return -1;
         }
 
@@ -12885,12 +12967,6 @@
                     return false;
                 }
 
-                if (mDidDexOpt) {
-                    // Give more time since we were dexopting.
-                    mDidDexOpt = false;
-                    return false;
-                }
-
                 if (proc.instr != null) {
                     Bundle info = new Bundle();
                     info.putString("shortMsg", "keyDispatchingTimedOut");
@@ -13301,7 +13377,6 @@
                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
                 if (r != null) {
                     final ActivityOptions activityOptions = r.pendingOptions;
-                    r.pendingOptions = null;
                     return activityOptions == null ? null : activityOptions.toBundle();
                 }
                 return null;
@@ -23873,7 +23948,9 @@
                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
                 return;
             }
-            ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
+            synchronized (ActivityManagerService.this) {
+                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
+            }
         }
 
         @Override
@@ -23939,9 +24016,19 @@
 
                 // We might change the visibilities here, so prepare an empty app transition which
                 // might be overridden later if we actually change visibilities.
-                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
+                final boolean wasTransitionSet =
+                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
+                if (!wasTransitionSet) {
+                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
+                            false /* alwaysKeepCurrent */);
+                }
                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
-                mWindowManager.executeAppTransition();
+
+                // If there was a transition set already we don't want to interfere with it as we
+                // might be starting it too early.
+                if (!wasTransitionSet) {
+                    mWindowManager.executeAppTransition();
+                }
             }
             if (callback != null) {
                 callback.run();
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 68f4d0d..253bdc5 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -74,6 +74,7 @@
 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.WindowManagerPolicy.NAV_BAR_LEFT;
 
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
@@ -132,7 +133,6 @@
 import android.graphics.Bitmap;
 import android.graphics.GraphicBuffer;
 import android.graphics.Rect;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.IBinder;
@@ -154,6 +154,7 @@
 import android.view.IApplicationToken;
 import android.view.WindowManager.LayoutParams;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.ResolverActivity;
 import com.android.internal.content.ReferrerIntent;
 import com.android.internal.util.XmlUtils;
@@ -895,7 +896,15 @@
 
         Entry ent = AttributeCache.instance().get(packageName,
                 realTheme, com.android.internal.R.styleable.Window, userId);
-        fullscreen = ent != null && !ActivityInfo.isTranslucentOrFloating(ent.array);
+        final boolean translucent = ent != null && (ent.array.getBoolean(
+                com.android.internal.R.styleable.Window_windowIsTranslucent, false)
+                || (!ent.array.hasValue(
+                        com.android.internal.R.styleable.Window_windowIsTranslucent)
+                        && ent.array.getBoolean(
+                                com.android.internal.R.styleable.Window_windowSwipeToDismiss,
+                                        false)));
+        fullscreen = ent != null && !ent.array.getBoolean(
+                com.android.internal.R.styleable.Window_windowIsFloating, false) && !translucent;
         noDisplay = ent != null && ent.array.getBoolean(
                 com.android.internal.R.styleable.Window_windowNoDisplay, false);
 
@@ -2193,11 +2202,6 @@
     }
 
     void setRequestedOrientation(int requestedOrientation) {
-        if (ActivityInfo.isFixedOrientation(requestedOrientation) && !fullscreen
-                && appInfo.targetSdkVersion > O) {
-            throw new IllegalStateException("Only fullscreen activities can request orientation");
-        }
-
         final int displayId = getDisplayId();
         final Configuration displayConfig =
                 mStackSupervisor.getDisplayOverrideConfiguration(displayId);
@@ -2319,10 +2323,12 @@
         outBounds.setEmpty();
         final float maxAspectRatio = info.maxAspectRatio;
         final ActivityStack stack = getStack();
-        if (task == null || stack == null || !task.mFullscreen || maxAspectRatio == 0) {
+        if (task == null || stack == null || !task.mFullscreen || maxAspectRatio == 0
+                || isInVrUiMode(getConfiguration())) {
             // We don't set override configuration if that activity task isn't fullscreen. I.e. the
             // activity is in multi-window mode. Or, there isn't a max aspect ratio specified for
-            // the activity. This is indicated by an empty {@link outBounds}.
+            // the activity. This is indicated by an empty {@link outBounds}. We also don't set it
+            // if we are in VR mode.
             return;
         }
 
@@ -2358,6 +2364,17 @@
 
         // Compute configuration based on max supported width and height.
         outBounds.set(0, 0, maxActivityWidth, maxActivityHeight);
+        // Position the activity frame on the opposite side of the nav bar.
+        final int navBarPosition = service.mWindowManager.getNavBarPosition();
+        final int left = navBarPosition == NAV_BAR_LEFT
+                ? configuration.appBounds.right - outBounds.width() : 0;
+        outBounds.offsetTo(left, 0 /* top */);
+    }
+
+    /** Get bounds of the activity. */
+    @VisibleForTesting
+    Rect getBounds() {
+        return new Rect(mBounds);
     }
 
     /**
@@ -2581,6 +2598,7 @@
                 changes &= ~CONFIG_SMALLEST_SCREEN_SIZE;
             }
         }
+
         return changes;
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index bde317a..3620ddb 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -659,6 +659,13 @@
         return topRunningActivityLocked(false /* focusableOnly */);
     }
 
+    void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
+        outActivities.clear();
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            mTaskHistory.get(taskNdx).getAllRunningVisibleActivitiesLocked(outActivities);
+        }
+    }
+
     private ActivityRecord topRunningActivityLocked(boolean focusableOnly) {
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
             ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked();
@@ -745,6 +752,13 @@
         return null;
     }
 
+    final TaskRecord bottomTask() {
+        if (mTaskHistory.isEmpty()) {
+            return null;
+        }
+        return mTaskHistory.get(0);
+    }
+
     TaskRecord taskForIdLocked(int id) {
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
             final TaskRecord task = mTaskHistory.get(taskNdx);
@@ -1690,14 +1704,20 @@
         }
         final int stackBehindTopId = (stackBehindTopIndex >= 0)
                 ? mStacks.get(stackBehindTopIndex).mStackId : INVALID_STACK_ID;
-        if ((topStackId == DOCKED_STACK_ID || topStackId == PINNED_STACK_ID)
-                && (stackIndex == stackBehindTopIndex
-                || (stackBehindTopId == DOCKED_STACK_ID
-                && stackIndex == stackBehindTopIndex - 1))) {
-            // Stacks directly behind the docked or pinned stack are always visible.
-            // Also this stack is visible if behind docked stack and the docked stack is behind the
-            // top-most pinned stack
-            return STACK_VISIBLE;
+        if (topStackId == DOCKED_STACK_ID || StackId.isAlwaysOnTop(topStackId)) {
+            if (stackIndex == stackBehindTopIndex) {
+                // Stacks directly behind the docked or pinned stack are always visible.
+                return STACK_VISIBLE;
+            } else if (StackId.isAlwaysOnTop(topStackId) && stackIndex == stackBehindTopIndex - 1) {
+                // Otherwise, this stack can also be visible if it is directly behind a docked stack
+                // or translucent assistant stack behind an always-on-top top-most stack
+                if (stackBehindTopId == DOCKED_STACK_ID) {
+                    return STACK_VISIBLE;
+                } else if (stackBehindTopId == ASSISTANT_STACK_ID) {
+                    return mStacks.get(stackBehindTopIndex).isStackTranslucent(starting, mStackId)
+                            ? STACK_VISIBLE : STACK_INVISIBLE;
+                }
+            }
         }
 
         if (StackId.isBackdropToTranslucentActivity(topStackId)
@@ -1896,7 +1916,16 @@
                         // the recents activity from an app.
                         behindFullscreenActivity = true;
                     }
-
+                } else if (mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
+                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Skipping after task=" + task
+                            + " returning to non-application type=" + task.getTaskToReturnTo());
+                    // Once we reach a fullscreen stack task that has a running activity and should
+                    // return to another stack task, then no other activities behind that one should
+                    // be visible.
+                    if (task.topRunningActivityLocked() != null &&
+                            task.getTaskToReturnTo() != APPLICATION_ACTIVITY_TYPE) {
+                        behindFullscreenActivity = true;
+                    }
                 }
             }
 
@@ -2881,9 +2910,13 @@
                         transit = TRANSIT_TASK_OPEN_BEHIND;
                     } else {
                         // If a new task is being launched, then mark the existing top activity as
-                        // supporting picture-in-picture while pausing
-                        if (focusedTopActivity != null &&
-                                focusedTopActivity.getStack().getStackId() != PINNED_STACK_ID) {
+                        // supporting picture-in-picture while pausing only if the starting activity
+                        // would not be considered an overlay on top of the current activity
+                        // (eg. not fullscreen, or the assistant)
+                        if (focusedTopActivity != null
+                                && focusedTopActivity.getStackId() != PINNED_STACK_ID
+                                && r.getStackId() != ASSISTANT_STACK_ID
+                                && r.fullscreen) {
                             focusedTopActivity.supportsPictureInPictureWhilePausing = true;
                         }
                         transit = TRANSIT_TASK_OPEN;
@@ -3365,6 +3398,16 @@
      * @param allowFocusSelf Is the focus allowed to remain on the same stack.
      */
     private boolean adjustFocusToNextFocusableStackLocked(String reason, boolean allowFocusSelf) {
+        if (isAssistantStack() && bottomTask() != null &&
+                bottomTask().getTaskToReturnTo() == HOME_ACTIVITY_TYPE) {
+            // If the current stack is the assistant stack, then use the return-to type to determine
+            // whether to return to the home screen. This is needed to workaround an issue where
+            // launching a fullscreen task (and subequently returning from that task) will cause
+            // the fullscreen stack to be found as the next focusable stack below, even if the
+            // assistant was launched over home.
+            return mStackSupervisor.moveHomeStackTaskToTop(reason);
+        }
+
         final ActivityStack stack = mStackSupervisor.getNextFocusableStackLocked(
                 allowFocusSelf ? null : this);
         final String myReason = reason + " adjustFocusToNextFocusableStack";
@@ -3381,6 +3424,15 @@
             return mStackSupervisor.moveHomeStackTaskToTop(reason);
         }
 
+        if (stack.isAssistantStack() && top != null
+                && top.getTask().getTaskToReturnTo() == HOME_ACTIVITY_TYPE) {
+            // It is possible for the home stack to not be directly underneath the assistant stack.
+            // For example, the assistant may start an activity in the fullscreen stack. Upon
+            // returning to the assistant stack, we must ensure that the home stack is underneath
+            // when appropriate.
+            mStackSupervisor.moveHomeStackTaskToTop("adjustAssistantReturnToHome");
+        }
+
         stack.moveToFront(myReason);
         return true;
     }
@@ -3650,7 +3702,7 @@
 
             finishActivityResultsLocked(r, resultCode, resultData);
 
-            final boolean endTask = index <= 0;
+            final boolean endTask = index <= 0 && !task.isClearingToReuseTask();
             final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
             if (mResumedActivity == r) {
                 if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
@@ -4548,8 +4600,10 @@
             updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
         }
         // If a new task is moved to the front, then mark the existing top activity as supporting
-        // picture-in-picture while paused
-        if (topActivity != null && topActivity.getStack().getStackId() != PINNED_STACK_ID) {
+        // picture-in-picture while paused only if the task would not be considered an oerlay on top
+        // of the current activity (eg. not fullscreen, or the assistant)
+        if (topActivity != null && topActivity.getStackId() != PINNED_STACK_ID
+                && tr.getStackId() != ASSISTANT_STACK_ID && tr.containsOnlyFullscreenActivities()) {
             topActivity.supportsPictureInPictureWhilePausing = true;
         }
 
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index fe0e07e..ce86624 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
 import static android.Manifest.permission.START_ANY_ACTIVITY;
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
@@ -38,11 +39,13 @@
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.Process.SYSTEM_UID;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.FLAG_PRIVATE;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
+import static android.view.Display.TYPE_VIRTUAL;
 
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
@@ -454,6 +457,8 @@
 
     final ActivityMetricsLogger mActivityMetricsLogger;
 
+    private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>();
+
     @Override
     protected int getChildCount() {
         return mActivityDisplays.size();
@@ -961,17 +966,21 @@
                 if (!isFocusedStack(stack)) {
                     continue;
                 }
-                ActivityRecord hr = stack.topRunningActivityLocked();
-                if (hr != null) {
-                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
-                            && processName.equals(hr.processName)) {
+                stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
+                final ActivityRecord top = stack.topRunningActivityLocked();
+                final int size = mTmpActivityList.size();
+                for (int i = 0; i < size; i++) {
+                    final ActivityRecord activity = mTmpActivityList.get(i);
+                    if (activity.app == null && app.uid == activity.info.applicationInfo.uid
+                            && processName.equals(activity.processName)) {
                         try {
-                            if (realStartActivityLocked(hr, app, true, true)) {
+                            if (realStartActivityLocked(activity, app,
+                                    top == activity /* andResume */, true /* checkConfig */)) {
                                 didSomething = true;
                             }
                         } catch (RemoteException e) {
                             Slog.w(TAG, "Exception in new application when starting activity "
-                                  + hr.intent.getComponent().flattenToShortString(), e);
+                                    + top.intent.getComponent().flattenToShortString(), e);
                             throw e;
                         }
                     }
@@ -1461,6 +1470,7 @@
                     mService.getGlobalConfiguration(), r.getMergedOverrideConfiguration());
             r.setLastReportedConfiguration(mergedConfiguration);
 
+            logIfTransactionTooLarge(r.intent, r.icicle);
             app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                     System.identityHashCode(r), r.info,
                     // TODO: Have this take the merged configuration instead of separate global and
@@ -1546,6 +1556,21 @@
         return true;
     }
 
+    private void logIfTransactionTooLarge(Intent intent, Bundle icicle) {
+        int extrasSize = 0;
+        if (intent != null) {
+            final Bundle extras = intent.getExtras();
+            if (extras != null) {
+                extrasSize = extras.getSize();
+            }
+        }
+        int icicleSize = (icicle == null ? 0 : icicle.getSize());
+        if (extrasSize + icicleSize > 200000) {
+            Slog.e(TAG, "Transaction too large, intent: " + intent + ", extras size: " + extrasSize
+                    + ", icicle size: " + icicleSize);
+        }
+    }
+
     void startSpecificActivityLocked(ActivityRecord r,
             boolean andResume, boolean checkConfig) {
         // Is this activity's application already running?
@@ -1678,6 +1703,24 @@
             return false;
         }
 
+        // Check if the caller can manage activity stacks.
+        final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid,
+                callingUid);
+        if (startAnyPerm == PERMISSION_GRANTED) {
+            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+                    + " allow launch any on display");
+            return true;
+        }
+
+        if (activityDisplay.mDisplay.getType() == TYPE_VIRTUAL
+                && activityDisplay.mDisplay.getOwnerUid() != SYSTEM_UID) {
+            // Limit launching on virtual displays, because their contents can be read from Surface
+            // by apps that created them.
+            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+                    + " disallow launch on virtual display for not-embedded activity");
+            return false;
+        }
+
         if (!activityDisplay.isPrivate()) {
             // Anyone can launch on a public display.
             if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
@@ -1699,15 +1742,6 @@
             return true;
         }
 
-        // Check if the caller can manage activity stacks.
-        final int startAnyPerm = mService.checkPermission(MANAGE_ACTIVITY_STACKS, callingPid,
-                callingUid);
-        if (startAnyPerm == PERMISSION_GRANTED) {
-            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
-                    + " allow launch any on display");
-            return true;
-        }
-
         Slog.w(TAG, "Launch on display check: denied");
         return false;
     }
@@ -4440,13 +4474,6 @@
                 case IDLE_TIMEOUT_MSG: {
                     if (DEBUG_IDLE) Slog.d(TAG_IDLE,
                             "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
-                    if (mService.mDidDexOpt) {
-                        mService.mDidDexOpt = false;
-                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
-                        nmsg.obj = msg.obj;
-                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
-                        return;
-                    }
                     // We don't at this point know if the activity is fullscreen,
                     // so we need to be conservative and assume it isn't.
                     activityIdleInternal((ActivityRecord) msg.obj,
@@ -4472,11 +4499,6 @@
                     }
                 } break;
                 case LAUNCH_TIMEOUT_MSG: {
-                    if (mService.mDidDexOpt) {
-                        mService.mDidDexOpt = false;
-                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
-                        return;
-                    }
                     synchronized (mService) {
                         if (mLaunchingActivity.isHeld()) {
                             Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
@@ -5154,11 +5176,14 @@
             // Work Challenge is present) let startActivityInPackage handle the intercepting.
             if (!mService.mUserController.shouldConfirmCredentials(task.userId)
                     && task.getRootActivity() != null) {
-                mService.mActivityStarter.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */);
+                final ActivityRecord targetActivity = task.getTopActivity();
+
+                mService.mActivityStarter.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */,
+                        targetActivity);
                 mActivityMetricsLogger.notifyActivityLaunching();
                 mService.moveTaskToFrontLocked(task.taskId, 0, bOptions, true /* fromRecents */);
                 mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT,
-                        task.getTopActivity());
+                        targetActivity);
 
                 // If we are launching the task in the docked stack, put it into resizing mode so
                 // the window renders full-screen with the background filling the void. Also only
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index a145435..76f65e2 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import static android.app.Activity.RESULT_CANCELED;
+import static android.app.ActivityManager.START_ABORTED;
 import static android.app.ActivityManager.START_CANCELED;
 import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
@@ -279,7 +280,9 @@
             // mLastStartActivityRecord[0] is set in the call to startActivity above.
             outActivity[0] = mLastStartActivityRecord[0];
         }
-        return mLastStartActivityResult;
+
+        // Aborted results are treated as successes externally, but we must track them internally.
+        return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
     }
 
     /** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */
@@ -465,7 +468,7 @@
             // We pretend to the caller that it was really started, but
             // they will just get a cancel result.
             ActivityOptions.abort(options);
-            return START_SUCCESS;
+            return START_ABORTED;
         }
 
         // If permissions need a review before any of the app components can run, we
@@ -966,7 +969,7 @@
         return START_SUCCESS;
     }
 
-    void sendPowerHintForLaunchStartIfNeeded(boolean forceSend) {
+    void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
         boolean sendHint = forceSend;
 
         if (!sendHint) {
@@ -975,7 +978,7 @@
             final ActivityRecord resumedActivity = mSupervisor.getResumedActivityLocked();
             sendHint = resumedActivity == null
                 || resumedActivity.app == null
-                || !resumedActivity.app.equals(mStartActivity.app);
+                || !resumedActivity.app.equals(targetActivity.app);
         }
 
         if (sendHint && mService.mLocalPowerManager != null) {
@@ -1095,7 +1098,7 @@
                 }
             }
 
-            sendPowerHintForLaunchStartIfNeeded(false /* forceSend */);
+            sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);
 
             reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
 
@@ -1124,6 +1127,7 @@
                 if (outActivity != null && outActivity.length > 0) {
                     outActivity[0] = reusedActivity;
                 }
+
                 return START_TASK_TO_FRONT;
             }
         }
@@ -1215,7 +1219,7 @@
                 EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
         mTargetStack.mLastPausedActivity = null;
 
-        sendPowerHintForLaunchStartIfNeeded(false /* forceSend */);
+        sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);
 
         mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                 mOptions);
@@ -1517,7 +1521,8 @@
             if (mLaunchSingleInstance) {
                 // There can be one and only one instance of single instance activity in the
                 // history, and it is always in its own unique task, so we do a special search.
-               intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info, false);
+               intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
+                       mStartActivity.isHomeActivity());
             } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
                 // For the launch adjacent case we only want to put the activity in an existing
                 // task if the activity already exists in the history.
@@ -1637,6 +1642,16 @@
                                 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
                                 "reparentToDisplay");
                         mMovedToFront = true;
+                    } else if (launchStack.getStackId() == StackId.HOME_STACK_ID
+                        && mTargetStack.getStackId() != StackId.HOME_STACK_ID) {
+                        // It is possible for the home activity to be in another stack initially.
+                        // For example, the activity may have been initially started with an intent
+                        // which placed it in the fullscreen stack. To ensure the proper handling of
+                        // the activity based on home stack assumptions, we must move it over.
+                        intentActivity.getTask().reparent(launchStack.mStackId, ON_TOP,
+                                REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
+                                "reparentingHome");
+                        mMovedToFront = true;
                     }
                     mOptions = null;
 
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 8991537..0d1c579 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -55,6 +55,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Set;
 
 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
@@ -908,10 +909,11 @@
 
         // For background ANRs, don't pass the ProcessCpuTracker to
         // avoid spending 1/2 second collecting stats to rank lastPids.
-        File tracesFile = mService.dumpStackTraces(true, firstPids,
-                                                   (isSilentANR) ? null : processCpuTracker,
-                                                   (isSilentANR) ? null : lastPids,
-                                                   nativePids);
+        File tracesFile = ActivityManagerService.dumpStackTraces(
+                true, firstPids,
+                (isSilentANR) ? null : processCpuTracker,
+                (isSilentANR) ? null : lastPids,
+                nativePids);
 
         String cpuInfo = null;
         if (ActivityManagerService.MONITOR_CPU_USAGE) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index c20221b..65697e9 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -188,6 +188,7 @@
     }
 
     private native int getPlatformLowPowerStats(ByteBuffer outBuffer);
+    private native int getSubsystemLowPowerStats(ByteBuffer outBuffer);
     private CharsetDecoder mDecoderStat = StandardCharsets.UTF_8
                     .newDecoder()
                     .onMalformedInput(CodingErrorAction.REPLACE)
@@ -219,6 +220,28 @@
         }
     }
 
+    @Override
+    public String getSubsystemLowPowerStats() {
+        Slog.d(TAG, "begin getSubsystemLowPowerStats");
+        try {
+            mUtf8BufferStat.clear();
+            mUtf16BufferStat.clear();
+            mDecoderStat.reset();
+            int bytesWritten = getSubsystemLowPowerStats(mUtf8BufferStat);
+            if (bytesWritten < 0) {
+                return null;
+            } else if (bytesWritten == 0) {
+                return "Empty";
+            }
+            mUtf8BufferStat.limit(bytesWritten);
+            mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true);
+            mUtf16BufferStat.flip();
+            return mUtf16BufferStat.toString();
+        } finally {
+            Slog.d(TAG, "end getSubsystemLowPowerStats");
+        }
+    }
+
     BatteryStatsService(File systemDir, Handler handler) {
         // Our handler here will be accessing the disk, use a different thread than
         // what the ActivityManagerService gave us (no I/O on that one!).
@@ -962,10 +985,10 @@
     }
 
     @Override
-    public void noteBleScanStopped(WorkSource ws) {
+    public void noteBleScanStopped(WorkSource ws, boolean isUnoptimized) {
         enforceCallingPermission();
         synchronized (mStats) {
-            mStats.noteBluetoothScanStoppedFromSourceLocked(ws);
+            mStats.noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index b3a2c29..da196e2 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -802,7 +802,7 @@
         IPackageManager pm = AppGlobals.getPackageManager();
         for (int i = perms.length-1; i >= 0; i--) {
             try {
-                PermissionInfo pi = pm.getPermissionInfo(perms[i], 0);
+                PermissionInfo pi = pm.getPermissionInfo(perms[i], "android", 0);
                 if ((pi.protectionLevel & (PermissionInfo.PROTECTION_MASK_BASE
                         | PermissionInfo.PROTECTION_FLAG_PRIVILEGED))
                         != PermissionInfo.PROTECTION_SIGNATURE) {
@@ -1404,13 +1404,6 @@
         long now = SystemClock.uptimeMillis();
         BroadcastRecord r = mOrderedBroadcasts.get(0);
         if (fromMsg) {
-            if (mService.mDidDexOpt) {
-                // Delay timeouts until dexopt finishes.
-                mService.mDidDexOpt = false;
-                long timeoutTime = SystemClock.uptimeMillis() + mTimeoutPeriod;
-                setBroadcastTimeoutLocked(timeoutTime);
-                return;
-            }
             if (!mService.mProcessesReady) {
                 // Only process broadcast timeouts if the system is ready. That way
                 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index a46c851..d10f9fb 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -144,6 +144,7 @@
             failCallback(callback);
             return;
         }
+        Slog.i(TAG, "Activity requesting to dismiss Keyguard: " + activityRecord);
         mWindowManager.dismissKeyguard(callback);
     }
 
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 40a62bd..c009dde 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1112,6 +1112,19 @@
         return intent != null ? intent : affinityIntent;
     }
 
+    /**
+     * @return Whether there are only fullscreen activities in this task.
+     */
+    boolean containsOnlyFullscreenActivities() {
+        for (int i = 0; i < mActivities.size(); i++) {
+            final ActivityRecord r = mActivities.get(i);
+            if (!r.finishing && !r.fullscreen) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     /** Returns the first non-finishing activity from the root. */
     ActivityRecord getRootActivity() {
         for (int i = 0; i < mActivities.size(); i++) {
@@ -1147,6 +1160,17 @@
         return null;
     }
 
+    void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
+        if (mStack != null) {
+            for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
+                ActivityRecord r = mActivities.get(activityNdx);
+                if (!r.finishing && r.okToShowLocked() && r.visibleIgnoringKeyguard) {
+                    outActivities.add(r);
+                }
+            }
+        }
+    }
+
     ActivityRecord topRunningActivityWithStartingWindowLocked() {
         if (mStack != null) {
             for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
@@ -1592,6 +1616,13 @@
     }
 
     /**
+     * @return {@code true} if the task is being cleared for the purposes of being reused.
+     */
+    boolean isClearingToReuseTask() {
+        return mReuseTask;
+    }
+
+    /**
      * Find the activity in the history stack within the given task.  Returns
      * the index within the history at which it's found, or < 0 if not found.
      */
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index eeab605..f720cd51 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -123,12 +123,13 @@
     private final Injector mInjector;
     private final Handler mHandler;
 
-    // Holds the current foreground user's id
+    // Holds the current foreground user's id. Use mLock when updating
     @GuardedBy("mLock")
-    private int mCurrentUserId = UserHandle.USER_SYSTEM;
-    // Holds the target user's id during a user switch
+    private volatile int mCurrentUserId = UserHandle.USER_SYSTEM;
+    // Holds the target user's id during a user switch. The value of mCurrentUserId will be updated
+    // once target user goes into the foreground. Use mLock when updating
     @GuardedBy("mLock")
-    private int mTargetUserId = UserHandle.USER_NULL;
+    private volatile int mTargetUserId = UserHandle.USER_NULL;
 
     /**
      * Which users have been started, so are allowed to run code.
@@ -1506,6 +1507,11 @@
             Slog.w(TAG, msg);
             throw new SecurityException(msg);
         }
+
+        // Optimization - if there is no pending user switch, return current id
+        if (mTargetUserId == UserHandle.USER_NULL) {
+            return getUserInfo(mCurrentUserId);
+        }
         synchronized (mLock) {
             return getCurrentUserLocked();
         }
diff --git a/services/core/java/com/android/server/am/VrController.java b/services/core/java/com/android/server/am/VrController.java
index 048bef7..feddfe3 100644
--- a/services/core/java/com/android/server/am/VrController.java
+++ b/services/core/java/com/android/server/am/VrController.java
@@ -163,6 +163,7 @@
         ComponentName requestedPackage;
         ComponentName callingPackage;
         int userId;
+        int processId = -1;
         boolean changed = false;
         synchronized (mGlobalAmLock) {
             vrMode = record.requestedVrComponent != null;
@@ -172,11 +173,15 @@
 
             // Tell the VrController that a VR mode change is requested.
             changed = changeVrModeLocked(vrMode, record.app);
+
+            if (record.app != null) {
+                processId = record.app.pid;
+            }
         }
 
         // Tell VrManager that a VR mode changed is requested, VrManager will handle
         // notifying all non-AM dependencies if needed.
-        vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
+        vrService.setVrMode(vrMode, requestedPackage, userId, processId, callingPackage);
         return changed;
     }
 
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index e5c3106..0326299 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -166,7 +166,6 @@
 
     /** debug calls to devices APIs */
     protected static final boolean DEBUG_DEVICES = Log.isLoggable(TAG + ".DEVICES", Log.DEBUG);
-
     /** How long to delay before persisting a change in volume/ringer mode. */
     private static final int PERSIST_DELAY = 500;
 
@@ -240,6 +239,7 @@
     private static final int MSG_SET_A2DP_SRC_CONNECTION_STATE = 101;
     private static final int MSG_SET_A2DP_SINK_CONNECTION_STATE = 102;
     private static final int MSG_A2DP_DEVICE_CONFIG_CHANGE = 103;
+    private static final int MSG_DISABLE_AUDIO_FOR_UID = 104;
     // end of messages handled under wakelock
 
     private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;
@@ -352,7 +352,7 @@
         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
         AudioSystem.STREAM_MUSIC            // STREAM_ACCESSIBILITY
     };
-    private int[] mStreamVolumeAlias;
+    protected static int[] mStreamVolumeAlias;
 
     /**
      * Map AudioSystem.STREAM_* constants to app ops.  This should be used
@@ -648,20 +648,29 @@
         mHasVibrator = vibrator == null ? false : vibrator.hasVibrator();
 
         // Initialize volume
-        int maxVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps",
-                MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]);
-        if (maxVolume != MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) {
-            MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxVolume;
-            AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = (maxVolume * 3) / 4;
+        int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
+        if (maxCallVolume != -1) {
+            MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume;
+            AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] =
+                    (maxCallVolume * 3) / 4;
         }
-        maxVolume = SystemProperties.getInt("ro.config.media_vol_steps",
-                MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]);
-        if (maxVolume != MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
-            MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxVolume;
+
+        int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1);
+        if (maxMusicVolume != -1) {
+            MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume;
+        }
+
+        int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
+        if (defaultMusicVolume != -1 &&
+                defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
+            AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
+        } else {
             if (isPlatformTelevision()) {
-                AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxVolume / 4;
+                AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
+                        MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;
             } else {
-                AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = (maxVolume * 3) / 4;
+                AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
+                        MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;
             }
         }
 
@@ -704,6 +713,10 @@
         mSettingsObserver = new SettingsObserver();
         createStreamStates();
 
+        // mSafeUsbMediaVolumeIndex must be initialized after createStreamStates() because it
+        // relies on audio policy having correct ranges for volume indexes.
+        mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
+
         mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor);
 
         readAndSetLowRamDevice();
@@ -978,6 +991,19 @@
         checkAllFixedVolumeDevices();
         checkAllAliasStreamVolumes();
         checkMuteAffectedStreams();
+        updateDefaultVolumes();
+    }
+
+    // Update default indexes from aliased streams. Must be called after mStreamStates is created
+    private void updateDefaultVolumes() {
+        for (int stream = 0; stream < mStreamStates.length; stream++) {
+            if (stream != mStreamVolumeAlias[stream]) {
+                AudioSystem.DEFAULT_STREAM_VOLUME[stream] = rescaleIndex(
+                        AudioSystem.DEFAULT_STREAM_VOLUME[mStreamVolumeAlias[stream]],
+                        mStreamVolumeAlias[stream],
+                        stream);
+            }
+        }
     }
 
     private void dumpStreamStates(PrintWriter pw) {
@@ -1026,7 +1052,9 @@
         mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
         mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias;
 
-        if (updateVolumes) {
+        if (updateVolumes && mStreamStates != null) {
+            updateDefaultVolumes();
+
             mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias],
                     caller);
 
@@ -1347,7 +1375,7 @@
             // This is simulated by stepping by the full allowed volume range
             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
                     (device & mSafeMediaVolumeDevices) != 0) {
-                step = mSafeMediaVolumeIndex;
+                step = safeMediaVolumeIndex(device);
             } else {
                 step = streamState.getMaxIndex();
             }
@@ -1693,7 +1721,7 @@
                 if (index != 0) {
                     if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
                             (device & mSafeMediaVolumeDevices) != 0) {
-                        index = mSafeMediaVolumeIndex;
+                        index = safeMediaVolumeIndex(device);
                     } else {
                         index = streamState.getMaxIndex();
                     }
@@ -1817,7 +1845,7 @@
     }
 
     // UI update and Broadcast Intent
-    private void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) {
+    protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) {
         streamType = mStreamVolumeAlias[streamType];
 
         if (streamType == AudioSystem.STREAM_MUSIC) {
@@ -3436,7 +3464,7 @@
                             MUSIC_ACTIVE_POLL_PERIOD_MS);
                     int index = mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(device);
                     if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0) &&
-                            (index > mSafeMediaVolumeIndex)) {
+                            (index > safeMediaVolumeIndex(device))) {
                         // Approximate cumulative active music time
                         mMusicActiveMs += MUSIC_ACTIVE_POLL_PERIOD_MS;
                         if (mMusicActiveMs > UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX) {
@@ -3454,12 +3482,40 @@
         mAudioHandler.obtainMessage(MSG_PERSIST_MUSIC_ACTIVE_MS, mMusicActiveMs, 0).sendToTarget();
     }
 
+    private int getSafeUsbMediaVolumeIndex()
+    {
+        // determine UI volume index corresponding to the wanted safe gain in dBFS
+        int min = MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
+        int max = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
+
+        while (Math.abs(max-min) > 1) {
+            int index = (max + min) / 2;
+            float gainDB = AudioSystem.getStreamVolumeDB(
+                    AudioSystem.STREAM_MUSIC, index, AudioSystem.DEVICE_OUT_USB_HEADSET);
+            if (Float.isNaN(gainDB)) {
+                //keep last min in case of read error
+                break;
+            } else if (gainDB == SAFE_VOLUME_GAIN_DBFS) {
+                min = index;
+                break;
+            } else if (gainDB < SAFE_VOLUME_GAIN_DBFS) {
+                min = index;
+            } else {
+                max = index;
+            }
+        }
+        return min * 10;
+    }
+
     private void onConfigureSafeVolume(boolean force, String caller) {
         synchronized (mSafeMediaVolumeState) {
             int mcc = mContext.getResources().getConfiguration().mcc;
             if ((mMcc != mcc) || ((mMcc == 0) && force)) {
                 mSafeMediaVolumeIndex = mContext.getResources().getInteger(
                         com.android.internal.R.integer.config_safe_media_volume_index) * 10;
+
+                mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
+
                 boolean safeMediaVolumeEnabled =
                         SystemProperties.getBoolean("audio.safemedia.force", false)
                         || mContext.getResources().getBoolean(
@@ -4843,6 +4899,12 @@
                     mAudioEventWakeLock.release();
                     break;
 
+                case MSG_DISABLE_AUDIO_FOR_UID:
+                    mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */,
+                            msg.arg2 /* uid */);
+                    mAudioEventWakeLock.release();
+                    break;
+
                 case MSG_REPORT_NEW_ROUTES: {
                     int N = mRoutesObservers.beginBroadcast();
                     if (N > 0) {
@@ -5302,38 +5364,20 @@
         return delay;
     }
 
-    private void sendDeviceConnectionIntent(int device, int state, String address,
-            String deviceName) {
-        if (DEBUG_DEVICES) {
-            Slog.i(TAG, "sendDeviceConnectionIntent(dev:0x" + Integer.toHexString(device) +
-                    " state:0x" + Integer.toHexString(state) + " address:" + address +
-                    " name:" + deviceName + ");");
-        }
-        Intent intent = new Intent();
-
-        intent.putExtra(CONNECT_INTENT_KEY_STATE, state);
-        intent.putExtra(CONNECT_INTENT_KEY_ADDRESS, address);
-        intent.putExtra(CONNECT_INTENT_KEY_PORT_NAME, deviceName);
-
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-
+    private void updateAudioRoutes(int device, int state)
+    {
         int connType = 0;
 
         if (device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) {
             connType = AudioRoutesInfo.MAIN_HEADSET;
-            intent.setAction(Intent.ACTION_HEADSET_PLUG);
-            intent.putExtra("microphone", 1);
         } else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE ||
                    device == AudioSystem.DEVICE_OUT_LINE) {
-            /*do apps care about line-out vs headphones?*/
             connType = AudioRoutesInfo.MAIN_HEADPHONES;
-            intent.setAction(Intent.ACTION_HEADSET_PLUG);
-            intent.putExtra("microphone", 0);
         } else if (device == AudioSystem.DEVICE_OUT_HDMI ||
                 device == AudioSystem.DEVICE_OUT_HDMI_ARC) {
             connType = AudioRoutesInfo.MAIN_HDMI;
-            configureHdmiPlugIntent(intent, state);
-        } else if (device == AudioSystem.DEVICE_OUT_USB_DEVICE) {
+        } else if (device == AudioSystem.DEVICE_OUT_USB_DEVICE||
+                device == AudioSystem.DEVICE_OUT_USB_HEADSET) {
             connType = AudioRoutesInfo.MAIN_USB;
         }
 
@@ -5352,6 +5396,52 @@
                 }
             }
         }
+    }
+
+    private void sendDeviceConnectionIntent(int device, int state, String address,
+            String deviceName) {
+        if (DEBUG_DEVICES) {
+            Slog.i(TAG, "sendDeviceConnectionIntent(dev:0x" + Integer.toHexString(device) +
+                    " state:0x" + Integer.toHexString(state) + " address:" + address +
+                    " name:" + deviceName + ");");
+        }
+        Intent intent = new Intent();
+
+        if (device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) {
+            intent.setAction(Intent.ACTION_HEADSET_PLUG);
+            intent.putExtra("microphone", 1);
+        } else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE ||
+                   device == AudioSystem.DEVICE_OUT_LINE) {
+            intent.setAction(Intent.ACTION_HEADSET_PLUG);
+            intent.putExtra("microphone",  0);
+        } else if (device == AudioSystem.DEVICE_OUT_USB_HEADSET) {
+            intent.setAction(Intent.ACTION_HEADSET_PLUG);
+            intent.putExtra("microphone",
+                    AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_IN_USB_HEADSET, "")
+                        == AudioSystem.DEVICE_STATE_AVAILABLE ? 1 : 0);
+        } else if (device == AudioSystem.DEVICE_IN_USB_HEADSET) {
+            if (AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_USB_HEADSET, "")
+                    == AudioSystem.DEVICE_STATE_AVAILABLE) {
+                intent.setAction(Intent.ACTION_HEADSET_PLUG);
+                intent.putExtra("microphone", 1);
+            } else {
+                // do not send ACTION_HEADSET_PLUG when only the input side is seen as changing
+                return;
+            }
+        } else if (device == AudioSystem.DEVICE_OUT_HDMI ||
+                device == AudioSystem.DEVICE_OUT_HDMI_ARC) {
+            configureHdmiPlugIntent(intent, state);
+        }
+
+        if (intent.getAction() == null) {
+            return;
+        }
+
+        intent.putExtra(CONNECT_INTENT_KEY_STATE, state);
+        intent.putExtra(CONNECT_INTENT_KEY_ADDRESS, address);
+        intent.putExtra(CONNECT_INTENT_KEY_PORT_NAME, deviceName);
+
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
 
         final long ident = Binder.clearCallingIdentity();
         try {
@@ -5380,9 +5470,7 @@
             if ((state == 0) && ((device & DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG) != 0)) {
                 setBluetoothA2dpOnInt(true);
             }
-            boolean isUsb = ((device & ~AudioSystem.DEVICE_OUT_ALL_USB) == 0) ||
-                            (((device & AudioSystem.DEVICE_BIT_IN) != 0) &&
-                             ((device & ~AudioSystem.DEVICE_IN_ALL_USB) == 0));
+
             if (!handleDeviceConnection(state == 1, device, address, deviceName)) {
                 // change of connection state failed, bailout
                 return;
@@ -5422,9 +5510,8 @@
                     }
                 }
             }
-            if (!isUsb && device != AudioSystem.DEVICE_IN_WIRED_HEADSET) {
-                sendDeviceConnectionIntent(device, state, address, deviceName);
-            }
+            sendDeviceConnectionIntent(device, state, address, deviceName);
+            updateAudioRoutes(device, state);
         }
     }
 
@@ -5950,9 +6037,18 @@
     private int mMcc = 0;
     // mSafeMediaVolumeIndex is the cached value of config_safe_media_volume_index property
     private int mSafeMediaVolumeIndex;
+    // mSafeUsbMediaVolumeIndex is used for USB Headsets and is the music volume UI index
+    // corresponding to a gain of -30 dBFS in audio flinger mixer.
+    // We remove -15 dBs from the theoretical -15dB to account for the EQ boost when bands are set
+    // to max gain.
+    // This level corresponds to a loudness of 85 dB SPL for the warning to be displayed when
+    // the headset is compliant to EN 60950 with a max loudness of 100dB SPL.
+    private int mSafeUsbMediaVolumeIndex;
+    private static final float SAFE_VOLUME_GAIN_DBFS = -30.0f;
     // mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced,
     private final int mSafeMediaVolumeDevices = AudioSystem.DEVICE_OUT_WIRED_HEADSET |
-                                                AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;
+                                                AudioSystem.DEVICE_OUT_WIRED_HEADPHONE |
+                                                AudioSystem.DEVICE_OUT_USB_HEADSET;
     // mMusicActiveMs is the cumulative time of music activity since safe volume was disabled.
     // When this time reaches UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX, the safe media volume is re-enabled
     // automatically. mMusicActiveMs is rounded to a multiple of MUSIC_ACTIVE_POLL_PERIOD_MS.
@@ -5961,6 +6057,17 @@
     private static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000;  // 1 minute polling interval
     private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000;  // 30s after boot completed
 
+    private int safeMediaVolumeIndex(int device) {
+        if ((device & mSafeMediaVolumeDevices) == 0) {
+            return MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
+        }
+        if (device == AudioSystem.DEVICE_OUT_USB_HEADSET) {
+            return mSafeUsbMediaVolumeIndex;
+        } else {
+            return mSafeMediaVolumeIndex;
+        }
+    }
+
     private void setSafeMediaVolumeEnabled(boolean on, String caller) {
         synchronized (mSafeMediaVolumeState) {
             if ((mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) &&
@@ -5995,8 +6102,8 @@
                 continue;
             }
             int index = streamState.getIndex(device);
-            if (index > mSafeMediaVolumeIndex) {
-                streamState.setIndex(mSafeMediaVolumeIndex, device, caller);
+            if (index > safeMediaVolumeIndex(device)) {
+                streamState.setIndex(safeMediaVolumeIndex(device), device, caller);
                 sendMsg(mAudioHandler,
                         MSG_SET_DEVICE_VOLUME,
                         SENDMSG_QUEUE,
@@ -6014,7 +6121,7 @@
             if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) &&
                     (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
                     ((device & mSafeMediaVolumeDevices) != 0) &&
-                    (index > mSafeMediaVolumeIndex)) {
+                    (index > safeMediaVolumeIndex(device))) {
                 return false;
             }
             return true;
@@ -6240,6 +6347,7 @@
         pw.print("  mSafeMediaVolumeState=");
         pw.println(safeMediaVolumeStateToString(mSafeMediaVolumeState));
         pw.print("  mSafeMediaVolumeIndex="); pw.println(mSafeMediaVolumeIndex);
+        pw.print("  mSafeUsbMediaVolumeIndex="); pw.println(mSafeUsbMediaVolumeIndex);
         pw.print("  sIndependentA11yVolume="); pw.println(sIndependentA11yVolume);
         pw.print("  mPendingVolumeCommand="); pw.println(mPendingVolumeCommand);
         pw.print("  mMusicActiveMs="); pw.println(mMusicActiveMs);
@@ -6534,6 +6642,13 @@
                 }
             }
         }
+
+        @Override
+        public void disableAudioForUid(boolean disable, int uid) {
+            queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID,
+                    disable ? 1 : 0 /* arg1 */,  uid /* arg2 */,
+                    null /* obj */,  0 /* delay */);
+        }
     }
 
     //==========================================================================================
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 702cbbe..663559f 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -29,6 +29,8 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.android.internal.util.ArrayUtils;
+
 import java.io.PrintWriter;
 import java.text.DateFormat;
 import java.util.ArrayList;
@@ -67,6 +69,12 @@
                     .createIfNeeded()
                     .build();
 
+    // TODO support VolumeShaper on those players
+    private static final int[] UNDUCKABLE_PLAYER_TYPES = {
+            AudioPlaybackConfiguration.PLAYER_TYPE_AAUDIO,
+            AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL,
+    };
+
     // like a PLAY_CREATE_IF_NEEDED operation but with a skip to the end of the ramp
     private static final VolumeShaper.Operation PLAY_SKIP_RAMP =
             new VolumeShaper.Operation.Builder(PLAY_CREATE_IF_NEEDED).setXOffset(1.0f).build();
@@ -87,6 +95,43 @@
     }
 
     //=================================================================
+    private final ArrayList<Integer> mBannedUids = new ArrayList<Integer>();
+
+    // see AudioManagerInternal.disableAudioForUid(boolean disable, int uid)
+    public void disableAudioForUid(boolean disable, int uid) {
+        synchronized(mPlayerLock) {
+            final int index = mBannedUids.indexOf(new Integer(uid));
+            if (index >= 0) {
+                if (!disable) {
+                    mBannedUids.remove(index);
+                    // nothing else to do, future playback requests from this uid are ok
+                } // no else to handle, uid already present, so disabling again is no-op
+            } else {
+                if (disable) {
+                    for (AudioPlaybackConfiguration apc : mPlayers.values()) {
+                        checkBanPlayer(apc, uid);
+                    }
+                    mBannedUids.add(new Integer(uid));
+                } // no else to handle, uid already not in list, so enabling again is no-op
+            }
+        }
+    }
+
+    private boolean checkBanPlayer(@NonNull AudioPlaybackConfiguration apc, int uid) {
+        final boolean toBan = (apc.getClientUid() == uid);
+        if (toBan) {
+            final int piid = apc.getPlayerInterfaceId();
+            try {
+                Log.v(TAG, "banning player " + piid + " uid:" + uid);
+                apc.getPlayerProxy().pause();
+            } catch (Exception e) {
+                Log.e(TAG, "error banning player " + piid + " uid:" + uid, e);
+            }
+        }
+        return toBan;
+    }
+
+    //=================================================================
     // Track players and their states
     // methods playerAttributes, playerEvent, releasePlayer are all oneway calls
     //  into AudioService. They trigger synchronous dispatchPlaybackChange() which updates
@@ -129,6 +174,14 @@
             if (apc == null) {
                 return;
             }
+            if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
+                for (Integer uidInteger: mBannedUids) {
+                    if (checkBanPlayer(apc, uidInteger.intValue())) {
+                        // player was banned, do not update its state
+                        return;
+                    }
+                }
+            }
             if (apc.getPlayerType() == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
                 // FIXME SoundPool not ready for state reporting
                 return;
@@ -178,10 +231,17 @@
             pw.println("\n  ducked players:");
             mDuckingManager.dump(pw);
             // players muted due to the device ringing or being in a call
-            pw.println("\n  muted player piids:");
+            pw.print("\n  muted player piids:");
             for (int piid : mMutedPlayers) {
-                pw.println(" " + piid);
+                pw.print(" " + piid);
             }
+            pw.println();
+            // banned players:
+            pw.print("\n  banned uids:");
+            for (int uid : mBannedUids) {
+                pw.print(" " + uid);
+            }
+            pw.println();
         }
     }
 
@@ -298,12 +358,12 @@
                                 + " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid()
                                 + " - SPEECH");
                         return false;
-                    } else if (apc.getPlayerType()
-                            == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
-                        // TODO support ducking of SoundPool players
+                    } else if (ArrayUtils.contains(UNDUCKABLE_PLAYER_TYPES, apc.getPlayerType())) {
                         Log.v(TAG, "not ducking player " + apc.getPlayerInterfaceId()
                                 + " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid()
-                                + " - SoundPool");
+                                + " due to type:"
+                                + AudioPlaybackConfiguration.toLogFriendlyPlayerType(
+                                        apc.getPlayerType()));
                         return false;
                     }
                     apcsToDuck.add(apc);
diff --git a/services/core/java/com/android/server/audio/RotationHelper.java b/services/core/java/com/android/server/audio/RotationHelper.java
index 359cc36..ad20ed8 100644
--- a/services/core/java/com/android/server/audio/RotationHelper.java
+++ b/services/core/java/com/android/server/audio/RotationHelper.java
@@ -17,15 +17,13 @@
 package com.android.server.audio;
 
 import android.content.Context;
+import android.hardware.display.DisplayManager;
 import android.media.AudioSystem;
 import android.os.Handler;
 import android.util.Log;
-import android.view.OrientationEventListener;
 import android.view.Surface;
 import android.view.WindowManager;
 
-import com.android.server.policy.WindowOrientationListener;
-
 /**
  * Class to handle device rotation events for AudioService, and forward device rotation
  * to the audio HALs through AudioSystem.
@@ -42,18 +40,17 @@
 
     private static final String TAG = "AudioService.RotationHelper";
 
-    private static AudioOrientationListener sOrientationListener;
-    private static AudioWindowOrientationListener sWindowOrientationListener;
+    private static AudioDisplayListener sDisplayListener;
 
     private static final Object sRotationLock = new Object();
     private static int sDeviceRotation = Surface.ROTATION_0; // R/W synchronized on sRotationLock
 
     private static Context sContext;
+    private static Handler sHandler;
 
     /**
      * post conditions:
-     * - (sWindowOrientationListener != null) xor (sOrientationListener != null)
-     * - sWindowOrientationListener xor sOrientationListener is enabled
+     * - sDisplayListener != null
      * - sContext != null
      */
     static void init(Context context, Handler handler) {
@@ -61,34 +58,20 @@
             throw new IllegalArgumentException("Invalid null context");
         }
         sContext = context;
-        sWindowOrientationListener = new AudioWindowOrientationListener(context, handler);
-        sWindowOrientationListener.enable();
-        if (!sWindowOrientationListener.canDetectOrientation()) {
-            // cannot use com.android.server.policy.WindowOrientationListener, revert to public
-            // orientation API
-            Log.i(TAG, "Not using WindowOrientationListener, reverting to OrientationListener");
-            sWindowOrientationListener.disable();
-            sWindowOrientationListener = null;
-            sOrientationListener = new AudioOrientationListener(context);
-            sOrientationListener.enable();
-        }
+        sHandler = handler;
+        sDisplayListener = new AudioDisplayListener();
+        enable();
     }
 
     static void enable() {
-        if (sWindowOrientationListener != null) {
-            sWindowOrientationListener.enable();
-        } else {
-            sOrientationListener.enable();
-        }
+        ((DisplayManager) sContext.getSystemService(Context.DISPLAY_SERVICE))
+                .registerDisplayListener(sDisplayListener, sHandler);
         updateOrientation();
     }
 
     static void disable() {
-        if (sWindowOrientationListener != null) {
-            sWindowOrientationListener.disable();
-        } else {
-            sOrientationListener.disable();
-        }
+        ((DisplayManager) sContext.getSystemService(Context.DISPLAY_SERVICE))
+                .unregisterDisplayListener(sDisplayListener);
     }
 
     /**
@@ -128,84 +111,21 @@
     }
 
     /**
-     * Uses android.view.OrientationEventListener
+     * Uses android.hardware.display.DisplayManager.DisplayListener
      */
-    final static class AudioOrientationListener extends OrientationEventListener {
-        AudioOrientationListener(Context context) {
-            super(context);
+    final static class AudioDisplayListener implements DisplayManager.DisplayListener {
+
+        @Override
+        public void onDisplayAdded(int displayId) {
         }
 
         @Override
-        public void onOrientationChanged(int orientation) {
+        public void onDisplayRemoved(int displayId) {
+        }
+
+        @Override
+        public void onDisplayChanged(int displayId) {
             updateOrientation();
         }
     }
-
-    /**
-     * Uses com.android.server.policy.WindowOrientationListener
-     */
-    final static class AudioWindowOrientationListener extends WindowOrientationListener {
-        private static RotationCheckThread sRotationCheckThread;
-
-        AudioWindowOrientationListener(Context context, Handler handler) {
-            super(context, handler);
-        }
-
-        public void onProposedRotationChanged(int rotation) {
-            updateOrientation();
-            if (sRotationCheckThread != null) {
-                sRotationCheckThread.endCheck();
-            }
-            sRotationCheckThread = new RotationCheckThread();
-            sRotationCheckThread.beginCheck();
-        }
-    }
-
-    /**
-     * When com.android.server.policy.WindowOrientationListener report an orientation change,
-     * the UI may not have rotated yet. This thread polls with gradually increasing delays
-     * the new orientation.
-     */
-    final static class RotationCheckThread extends Thread {
-        // how long to wait between each rotation check
-        private final int[] WAIT_TIMES_MS = { 10, 20, 50, 100, 100, 200, 200, 500 };
-        private int mWaitCounter;
-        private final Object mCounterLock = new Object();
-
-        RotationCheckThread() {
-            super("RotationCheck");
-        }
-
-        void beginCheck() {
-            synchronized(mCounterLock) {
-                mWaitCounter = 0;
-            }
-            try {
-                start();
-            } catch (IllegalStateException e) { }
-        }
-
-        void endCheck() {
-            synchronized(mCounterLock) {
-                mWaitCounter = WAIT_TIMES_MS.length;
-            }
-        }
-
-        public void run() {
-            while (mWaitCounter < WAIT_TIMES_MS.length) {
-                int waitTimeMs;
-                synchronized(mCounterLock) {
-                    waitTimeMs = mWaitCounter < WAIT_TIMES_MS.length ?
-                            WAIT_TIMES_MS[mWaitCounter] : 0;
-                    mWaitCounter++;
-                }
-                try {
-                    if (waitTimeMs > 0) {
-                        sleep(waitTimeMs);
-                        updateOrientation();
-                    }
-                } catch (InterruptedException e) { }
-            }
-        }
-    }
 }
\ No newline at end of file
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index d155825..3133a51 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -21,6 +21,7 @@
 import android.content.IntentFilter;
 import android.hardware.ICameraService;
 import android.hardware.ICameraServiceProxy;
+import android.metrics.LogMaker;
 import android.nfc.INfcAdapter;
 import android.os.Binder;
 import android.os.Handler;
@@ -28,15 +29,23 @@
 import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserManager;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
 
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -56,12 +65,6 @@
 
     public static final String CAMERA_SERVICE_PROXY_BINDER_NAME = "media.camera.proxy";
 
-    // State arguments to use with the notifyCameraState call from camera service:
-    public static final int CAMERA_STATE_OPEN = 0;
-    public static final int CAMERA_STATE_ACTIVE = 1;
-    public static final int CAMERA_STATE_IDLE = 2;
-    public static final int CAMERA_STATE_CLOSED = 3;
-
     // Flags arguments to NFC adapter to enable/disable NFC
     public static final int DISABLE_POLLING_FLAGS = 0x1000;
     public static final int ENABLE_POLLING_FLAGS = 0x0000;
@@ -71,6 +74,9 @@
 
     private static final int RETRY_DELAY_TIME = 20; //ms
 
+    // Maximum entries to keep in usage history before dumping out
+    private static final int MAX_USAGE_HISTORY = 100;
+
     private final Context mContext;
     private final ServiceThread mHandlerThread;
     private final Handler mHandler;
@@ -82,14 +88,52 @@
 
     private ICameraService mCameraServiceRaw;
 
-    private final ArraySet<String> mActiveCameraIds = new ArraySet<>();
-
+    private final ArrayMap<String, CameraUsageEvent> mActiveCameraUsage = new ArrayMap<>();
+    private final List<CameraUsageEvent> mCameraUsageHistory = new ArrayList<>();
+    private final MetricsLogger mLogger = new MetricsLogger();
     private static final String NFC_NOTIFICATION_PROP = "ro.camera.notify_nfc";
     private static final String NFC_SERVICE_BINDER_NAME = "nfc";
     private static final IBinder nfcInterfaceToken = new Binder();
 
     private final boolean mNotifyNfc;
-    private int mActiveCameraCount = 0;
+
+    /**
+     * Structure to track camera usage
+     */
+    private static class CameraUsageEvent {
+        public final int mCameraFacing;
+        public final String mClientName;
+
+        private boolean mCompleted;
+        private long mDurationOrStartTimeMs;  // Either start time, or duration once completed
+
+        public CameraUsageEvent(int facing, String clientName) {
+            mCameraFacing = facing;
+            mClientName = clientName;
+            mDurationOrStartTimeMs = SystemClock.elapsedRealtime();
+            mCompleted = false;
+        }
+
+        public void markCompleted() {
+            if (mCompleted) {
+                return;
+            }
+            mCompleted = true;
+            mDurationOrStartTimeMs = SystemClock.elapsedRealtime() - mDurationOrStartTimeMs;
+            if (CameraServiceProxy.DEBUG) {
+                Slog.v(TAG, "A camera facing " + cameraFacingToString(mCameraFacing) +
+                        " was in use by " + mClientName + " for " +
+                        mDurationOrStartTimeMs + " ms");
+            }
+        }
+
+        /**
+         * Return duration of camera usage event, or 0 if the event is not done
+         */
+        public long getDuration() {
+            return mCompleted ? mDurationOrStartTimeMs : 0;
+        }
+    }
 
     private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
         @Override
@@ -123,11 +167,14 @@
         }
 
         @Override
-        public void notifyCameraState(String cameraId, int newCameraState) {
+        public void notifyCameraState(String cameraId, int newCameraState, int facing,
+                String clientName) {
             String state = cameraStateToString(newCameraState);
-            if (DEBUG) Slog.v(TAG, "Camera " + cameraId + " state now " + state);
+            String facingStr = cameraFacingToString(facing);
+            if (DEBUG) Slog.v(TAG, "Camera " + cameraId + " facing " + facingStr + " state now " +
+                    state + " for client " + clientName);
 
-            updateActivityCount(cameraId, newCameraState);
+            updateActivityCount(cameraId, newCameraState, facing, clientName);
         }
     };
 
@@ -173,6 +220,9 @@
         mContext.registerReceiver(mIntentReceiver, filter);
 
         publishBinderService(CAMERA_SERVICE_PROXY_BINDER_NAME, mCameraServiceProxy);
+        publishLocalService(CameraServiceProxy.class, this);
+
+        CameraStatsJobService.schedule(mContext);
     }
 
     @Override
@@ -202,8 +252,8 @@
             mCameraServiceRaw = null;
 
             // All cameras reset to idle on camera service death
-            boolean wasEmpty = mActiveCameraIds.isEmpty();
-            mActiveCameraIds.clear();
+            boolean wasEmpty = mActiveCameraUsage.isEmpty();
+            mActiveCameraUsage.clear();
 
             if ( mNotifyNfc && !wasEmpty ) {
                 notifyNfcService(/*enablePolling*/ true);
@@ -211,6 +261,46 @@
         }
     }
 
+    /**
+     * Dump camera usage events to log.
+     * Package-private
+     */
+    void dumpUsageEvents() {
+        synchronized(mLock) {
+            // Randomize order of events so that it's not meaningful
+            Collections.shuffle(mCameraUsageHistory);
+            for (CameraUsageEvent e : mCameraUsageHistory) {
+                if (DEBUG) {
+                    Slog.v(TAG, "Camera: " + e.mClientName + " used a camera facing " +
+                            cameraFacingToString(e.mCameraFacing) + " for " +
+                            e.getDuration() + " ms");
+                }
+                int subtype = 0;
+                switch(e.mCameraFacing) {
+                    case ICameraServiceProxy.CAMERA_FACING_BACK:
+                        subtype = MetricsEvent.CAMERA_BACK_USED;
+                        break;
+                    case ICameraServiceProxy.CAMERA_FACING_FRONT:
+                        subtype = MetricsEvent.CAMERA_FRONT_USED;
+                        break;
+                    case ICameraServiceProxy.CAMERA_FACING_EXTERNAL:
+                        subtype = MetricsEvent.CAMERA_EXTERNAL_USED;
+                        break;
+                    default:
+                        continue;
+                }
+                LogMaker l = new LogMaker(MetricsEvent.ACTION_CAMERA_EVENT)
+                        .setType(MetricsEvent.TYPE_ACTION)
+                        .setSubtype(subtype)
+                        .setLatency(e.getDuration())
+                        .setPackageName(e.mClientName);
+                mLogger.write(l);
+            }
+            mCameraUsageHistory.clear();
+        }
+        CameraStatsJobService.schedule(mContext);
+    }
+
     private void switchUserLocked(int userHandle) {
         Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle);
         mLastUser = userHandle;
@@ -278,21 +368,35 @@
         return true;
     }
 
-    private void updateActivityCount(String cameraId, int newCameraState) {
+    private void updateActivityCount(String cameraId, int newCameraState, int facing, String clientName) {
         synchronized(mLock) {
-            boolean wasEmpty = mActiveCameraIds.isEmpty();
+            // Update active camera list and notify NFC if necessary
+            boolean wasEmpty = mActiveCameraUsage.isEmpty();
             switch (newCameraState) {
-                case CAMERA_STATE_OPEN:
+                case ICameraServiceProxy.CAMERA_STATE_OPEN:
                     break;
-                case CAMERA_STATE_ACTIVE:
-                    mActiveCameraIds.add(cameraId);
+                case ICameraServiceProxy.CAMERA_STATE_ACTIVE:
+                    CameraUsageEvent newEvent = new CameraUsageEvent(facing, clientName);
+                    CameraUsageEvent oldEvent = mActiveCameraUsage.put(cameraId, newEvent);
+                    if (oldEvent != null) {
+                        Slog.w(TAG, "Camera " + cameraId + " was already marked as active");
+                        oldEvent.markCompleted();
+                        mCameraUsageHistory.add(oldEvent);
+                    }
                     break;
-                case CAMERA_STATE_IDLE:
-                case CAMERA_STATE_CLOSED:
-                    mActiveCameraIds.remove(cameraId);
+                case ICameraServiceProxy.CAMERA_STATE_IDLE:
+                case ICameraServiceProxy.CAMERA_STATE_CLOSED:
+                    CameraUsageEvent doneEvent = mActiveCameraUsage.remove(cameraId);
+                    if (doneEvent != null) {
+                        doneEvent.markCompleted();
+                        mCameraUsageHistory.add(doneEvent);
+                        if (mCameraUsageHistory.size() > MAX_USAGE_HISTORY) {
+                            dumpUsageEvents();
+                        }
+                    }
                     break;
             }
-            boolean isEmpty = mActiveCameraIds.isEmpty();
+            boolean isEmpty = mActiveCameraUsage.isEmpty();
             if ( mNotifyNfc && (wasEmpty != isEmpty) ) {
                 notifyNfcService(isEmpty);
             }
@@ -328,12 +432,23 @@
 
     private static String cameraStateToString(int newCameraState) {
         switch (newCameraState) {
-            case CAMERA_STATE_OPEN: return "CAMERA_STATE_OPEN";
-            case CAMERA_STATE_ACTIVE: return "CAMERA_STATE_ACTIVE";
-            case CAMERA_STATE_IDLE: return "CAMERA_STATE_IDLE";
-            case CAMERA_STATE_CLOSED: return "CAMERA_STATE_CLOSED";
+            case ICameraServiceProxy.CAMERA_STATE_OPEN: return "CAMERA_STATE_OPEN";
+            case ICameraServiceProxy.CAMERA_STATE_ACTIVE: return "CAMERA_STATE_ACTIVE";
+            case ICameraServiceProxy.CAMERA_STATE_IDLE: return "CAMERA_STATE_IDLE";
+            case ICameraServiceProxy.CAMERA_STATE_CLOSED: return "CAMERA_STATE_CLOSED";
             default: break;
         }
         return "CAMERA_STATE_UNKNOWN";
     }
+
+    private static String cameraFacingToString(int cameraFacing) {
+        switch (cameraFacing) {
+            case ICameraServiceProxy.CAMERA_FACING_BACK: return "CAMERA_FACING_BACK";
+            case ICameraServiceProxy.CAMERA_FACING_FRONT: return "CAMERA_FACING_FRONT";
+            case ICameraServiceProxy.CAMERA_FACING_EXTERNAL: return "CAMERA_FACING_EXTERNAL";
+            default: break;
+        }
+        return "CAMERA_FACING_UNKNOWN";
+    }
+
 }
diff --git a/services/core/java/com/android/server/camera/CameraStatsJobService.java b/services/core/java/com/android/server/camera/CameraStatsJobService.java
new file mode 100644
index 0000000..b8a6846
--- /dev/null
+++ b/services/core/java/com/android/server/camera/CameraStatsJobService.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS 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.camera;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.util.Slog;
+
+import java.util.concurrent.TimeUnit;
+
+import com.android.server.LocalServices;
+
+/**
+ * A JobService to periodically collect camera usage stats.
+ */
+public class CameraStatsJobService extends JobService {
+    private static final String TAG = "CameraStatsJobService";
+
+    // Must be unique within UID (system service)
+    private static final int CAMERA_REPORTING_JOB_ID = 0xCA3E7A;
+
+    private static ComponentName sCameraStatsJobServiceName = new ComponentName(
+            "android",
+            CameraStatsJobService.class.getName());
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        CameraServiceProxy serviceProxy = LocalServices.getService(CameraServiceProxy.class);
+        if (serviceProxy == null) {
+            Slog.w(TAG, "Can't collect camera usage stats - no camera service proxy found");
+            return false;
+        }
+
+        serviceProxy.dumpUsageEvents();
+        return false;
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        // All work is done in onStartJob, so nothing to stop here
+        return false;
+    }
+
+    public static void schedule(Context context) {
+
+        JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+        if (js == null) {
+            Slog.e(TAG, "Can't collect camera usage stats - no Job Scheduler");
+            return;
+        }
+        js.schedule(new JobInfo.Builder(CAMERA_REPORTING_JOB_ID, sCameraStatsJobServiceName)
+                .setMinimumLatency(TimeUnit.DAYS.toMillis(1))
+                .setRequiresDeviceIdle(true)
+                .build());
+
+    }
+
+}
diff --git a/services/core/java/com/android/server/car/CarServiceHelperService.java b/services/core/java/com/android/server/car/CarServiceHelperService.java
new file mode 100644
index 0000000..9392a6a
--- /dev/null
+++ b/services/core/java/com/android/server/car/CarServiceHelperService.java
@@ -0,0 +1,91 @@
+/*
+ * 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.car;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.car.ICarServiceHelper;
+import com.android.server.SystemService;
+
+/**
+ * System service side companion service for CarService.
+ * Starts car service and provide necessary API for CarService. Only for car product.
+ */
+public class CarServiceHelperService extends SystemService {
+    private static final String TAG = "CarServiceHelper";
+    private static final String CAR_SERVICE_INTERFACE = "android.car.ICar";
+    private final ICarServiceHelperImpl mHelper = new ICarServiceHelperImpl();
+    private IBinder mCarService;
+    private final ServiceConnection mCarServiceConnection = new ServiceConnection() {
+
+        @Override
+        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
+            Slog.i(TAG, "**CarService connected**");
+            mCarService = iBinder;
+            // Cannot depend on ICar which is defined in CarService, so handle binder call directly
+            // instead.
+            // void setCarServiceHelper(in IBinder helper)
+            Parcel data = Parcel.obtain();
+            data.writeInterfaceToken(CAR_SERVICE_INTERFACE);
+            data.writeStrongBinder(mHelper.asBinder());
+            try {
+                mCarService.transact(IBinder.FIRST_CALL_TRANSACTION, // setCarServiceHelper
+                        data, null, Binder.FLAG_ONEWAY);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "RemoteException from car service", e);
+                handleCarServiceCrash();
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName componentName) {
+            handleCarServiceCrash();
+        }
+    };
+
+    public CarServiceHelperService(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void onStart() {
+        Intent intent = new Intent();
+        intent.setPackage("com.android.car");
+        intent.setAction(CAR_SERVICE_INTERFACE);
+        if (!getContext().bindServiceAsUser(intent, mCarServiceConnection, Context.BIND_AUTO_CREATE,
+                UserHandle.SYSTEM)) {
+            Slog.wtf(TAG, "cannot start car service");
+        }
+    }
+
+    private void handleCarServiceCrash() {
+        //TODO define recovery bahavior
+    }
+
+    private class ICarServiceHelperImpl extends ICarServiceHelper.Stub {
+        //TODO
+    }
+}
diff --git a/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java b/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java
new file mode 100644
index 0000000..28c3585
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity;
+
+import android.net.LinkProperties;
+import android.net.metrics.DefaultNetworkEvent;
+import android.os.SystemClock;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.BitUtils;
+import com.android.internal.util.RingBuffer;
+import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tracks events related to the default network for the purpose of default network metrics.
+ * {@hide}
+ */
+public class DefaultNetworkMetrics {
+
+    private static final int ROLLING_LOG_SIZE = 64;
+
+    public final long creationTimeMs = SystemClock.elapsedRealtime();
+
+    // Event buffer used for metrics upload. The buffer is cleared when events are collected.
+    @GuardedBy("this")
+    private final List<DefaultNetworkEvent> mEvents = new ArrayList<>();
+
+    // Rolling event buffer used for dumpsys and bugreports.
+    @GuardedBy("this")
+    private final RingBuffer<DefaultNetworkEvent> mEventsLog =
+            new RingBuffer(DefaultNetworkEvent.class, ROLLING_LOG_SIZE);
+
+    // Information about the current status of the default network.
+    @GuardedBy("this")
+    private DefaultNetworkEvent mCurrentDefaultNetwork;
+    @GuardedBy("this")
+    private boolean mIsCurrentlyValid;
+    @GuardedBy("this")
+    private long mLastValidationTimeMs;
+    // Transport information about the last default network.
+    @GuardedBy("this")
+    private int mLastTransports;
+
+    public DefaultNetworkMetrics() {
+        newDefaultNetwork(creationTimeMs, null);
+    }
+
+    public synchronized void listEvents(PrintWriter pw) {
+        pw.println("default network events:");
+        long localTimeMs = System.currentTimeMillis();
+        long timeMs = SystemClock.elapsedRealtime();
+        for (DefaultNetworkEvent ev : mEventsLog.toArray()) {
+            printEvent(localTimeMs, pw, ev);
+        }
+        mCurrentDefaultNetwork.updateDuration(timeMs);
+        if (mIsCurrentlyValid) {
+            updateValidationTime(timeMs);
+            mLastValidationTimeMs = timeMs;
+        }
+        printEvent(localTimeMs, pw, mCurrentDefaultNetwork);
+    }
+
+    public synchronized void listEventsAsProto(PrintWriter pw) {
+        for (DefaultNetworkEvent ev : mEventsLog.toArray()) {
+            pw.print(IpConnectivityEventBuilder.toProto(ev));
+        }
+    }
+
+    public synchronized void flushEvents(List<IpConnectivityEvent> out) {
+        for (DefaultNetworkEvent ev : mEvents) {
+            out.add(IpConnectivityEventBuilder.toProto(ev));
+        }
+        mEvents.clear();
+    }
+
+    public synchronized void logDefaultNetworkValidity(long timeMs, boolean isValid) {
+        if (!isValid && mIsCurrentlyValid) {
+            mIsCurrentlyValid = false;
+            updateValidationTime(timeMs);
+        }
+
+        if (isValid && !mIsCurrentlyValid) {
+            mIsCurrentlyValid = true;
+            mLastValidationTimeMs = timeMs;
+        }
+    }
+
+    private void updateValidationTime(long timeMs) {
+        mCurrentDefaultNetwork.validatedMs += timeMs - mLastValidationTimeMs;
+    }
+
+    public synchronized void logDefaultNetworkEvent(
+            long timeMs, NetworkAgentInfo newNai, NetworkAgentInfo oldNai) {
+        logCurrentDefaultNetwork(timeMs, oldNai);
+        newDefaultNetwork(timeMs, newNai);
+    }
+
+    private void logCurrentDefaultNetwork(long timeMs, NetworkAgentInfo oldNai) {
+        DefaultNetworkEvent ev = mCurrentDefaultNetwork;
+        ev.updateDuration(timeMs);
+        ev.previousTransports = mLastTransports;
+        // oldNai is null if the system had no default network before the transition.
+        if (oldNai != null) {
+            // The system acquired a new default network.
+            fillLinkInfo(ev, oldNai);
+            ev.finalScore = oldNai.getCurrentScore();
+            ev.validatedMs = ev.durationMs;
+        }
+        // Only change transport of the previous default network if the event currently logged
+        // corresponds to an existing default network, and not to the absence of a default network.
+        // This allows to log pairs of transports for successive default networks regardless of
+        // whether or not the system experienced a period without any default network.
+        if (ev.transports != 0) {
+            mLastTransports = ev.transports;
+        }
+        mEvents.add(ev);
+        mEventsLog.append(ev);
+    }
+
+    private void newDefaultNetwork(long timeMs, NetworkAgentInfo newNai) {
+        DefaultNetworkEvent ev = new DefaultNetworkEvent(timeMs);
+        ev.durationMs = timeMs;
+        // newNai is null if the system has no default network after the transition.
+        if (newNai != null) {
+            fillLinkInfo(ev, newNai);
+            ev.initialScore = newNai.getCurrentScore();
+            if (newNai.lastValidated) {
+                mIsCurrentlyValid = true;
+                mLastValidationTimeMs = timeMs;
+            }
+        }
+        mCurrentDefaultNetwork = ev;
+    }
+
+    private static void fillLinkInfo(DefaultNetworkEvent ev, NetworkAgentInfo nai) {
+        LinkProperties lp = nai.linkProperties;
+        ev.netId = nai.network().netId;
+        ev.transports |= BitUtils.packBits(nai.networkCapabilities.getTransportTypes());
+        ev.ipv4 |= lp.hasIPv4Address() && lp.hasIPv4DefaultRoute();
+        ev.ipv6 |= lp.hasGlobalIPv6Address() && lp.hasIPv6DefaultRoute();
+    }
+
+    private static void printEvent(long localTimeMs, PrintWriter pw, DefaultNetworkEvent ev) {
+        long localCreationTimeMs = localTimeMs - ev.durationMs;
+        pw.println(String.format("%tT.%tL: %s", localCreationTimeMs, localCreationTimeMs, ev));
+    }
+}
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
index 5dee91d..397af7b 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
@@ -20,10 +20,12 @@
 import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_LOWPAN;
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
 
+import android.net.ConnectivityManager;
 import android.net.ConnectivityMetricsEvent;
 import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.ApfStats;
@@ -37,13 +39,13 @@
 import android.net.metrics.NetworkEvent;
 import android.net.metrics.RaEvent;
 import android.net.metrics.ValidationProbeEvent;
+import android.net.metrics.WakeupStats;
 import android.os.Parcelable;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog;
-import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.NetworkId;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.Pair;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -114,6 +116,45 @@
         return out;
     }
 
+    public static IpConnectivityEvent toProto(WakeupStats in) {
+        IpConnectivityLogClass.WakeupStats wakeupStats =
+                new IpConnectivityLogClass.WakeupStats();
+        in.updateDuration();
+        wakeupStats.durationSec = in.durationSec;
+        wakeupStats.totalWakeups = in.totalWakeups;
+        wakeupStats.rootWakeups = in.rootWakeups;
+        wakeupStats.systemWakeups = in.systemWakeups;
+        wakeupStats.nonApplicationWakeups = in.nonApplicationWakeups;
+        wakeupStats.applicationWakeups = in.applicationWakeups;
+        wakeupStats.noUidWakeups = in.noUidWakeups;
+        wakeupStats.l2UnicastCount = in.l2UnicastCount;
+        wakeupStats.l2MulticastCount = in.l2MulticastCount;
+        wakeupStats.l2BroadcastCount = in.l2BroadcastCount;
+        wakeupStats.ethertypeCounts = toPairArray(in.ethertypes);
+        wakeupStats.ipNextHeaderCounts = toPairArray(in.ipNextHeaders);
+        final IpConnectivityEvent out = buildEvent(0, 0, in.iface);
+        out.setWakeupStats(wakeupStats);
+        return out;
+    }
+
+    public static IpConnectivityEvent toProto(DefaultNetworkEvent in) {
+        IpConnectivityLogClass.DefaultNetworkEvent ev =
+                new IpConnectivityLogClass.DefaultNetworkEvent();
+        ev.finalScore = in.finalScore;
+        ev.initialScore = in.initialScore;
+        ev.ipSupport = ipSupportOf(in);
+        ev.defaultNetworkDurationMs = in.durationMs;
+        ev.validationDurationMs = in.validatedMs;
+        ev.previousDefaultNetworkLinkLayer = transportsToLinkLayer(in.previousTransports);
+        final IpConnectivityEvent out = buildEvent(in.netId, in.transports, null);
+        if (in.transports == 0) {
+            // Set link layer to NONE for events representing the absence of a default network.
+            out.linkLayer = IpConnectivityLogClass.NONE;
+        }
+        out.setDefaultNetworkEvent(ev);
+        return out;
+    }
+
     private static IpConnectivityEvent buildEvent(int netId, long transports, String ifname) {
         final IpConnectivityEvent ev = new IpConnectivityEvent();
         ev.networkId = netId;
@@ -146,11 +187,6 @@
             return true;
         }
 
-        if (in instanceof DefaultNetworkEvent) {
-            setDefaultNetworkEvent(out, (DefaultNetworkEvent) in);
-            return true;
-        }
-
         if (in instanceof NetworkEvent) {
             setNetworkEvent(out, (NetworkEvent) in);
             return true;
@@ -207,20 +243,9 @@
         out.setIpReachabilityEvent(ipReachabilityEvent);
     }
 
-    private static void setDefaultNetworkEvent(IpConnectivityEvent out, DefaultNetworkEvent in) {
-        IpConnectivityLogClass.DefaultNetworkEvent defaultNetworkEvent =
-                new IpConnectivityLogClass.DefaultNetworkEvent();
-        defaultNetworkEvent.networkId = netIdOf(in.netId);
-        defaultNetworkEvent.previousNetworkId = netIdOf(in.prevNetId);
-        defaultNetworkEvent.transportTypes = in.transportTypes;
-        defaultNetworkEvent.previousNetworkIpSupport = ipSupportOf(in);
-        out.setDefaultNetworkEvent(defaultNetworkEvent);
-    }
-
     private static void setNetworkEvent(IpConnectivityEvent out, NetworkEvent in) {
         IpConnectivityLogClass.NetworkEvent networkEvent =
                 new IpConnectivityLogClass.NetworkEvent();
-        networkEvent.networkId = netIdOf(in.netId);
         networkEvent.eventType = in.eventType;
         networkEvent.latencyMs = (int) in.durationMs;
         out.setNetworkEvent(networkEvent);
@@ -299,20 +324,14 @@
         return pairs;
     }
 
-    private static NetworkId netIdOf(int netid) {
-        final NetworkId ni = new NetworkId();
-        ni.networkId = netid;
-        return ni;
-    }
-
     private static int ipSupportOf(DefaultNetworkEvent in) {
-        if (in.prevIPv4 && in.prevIPv6) {
+        if (in.ipv4 && in.ipv6) {
             return IpConnectivityLogClass.DefaultNetworkEvent.DUAL;
         }
-        if (in.prevIPv6) {
+        if (in.ipv6) {
             return IpConnectivityLogClass.DefaultNetworkEvent.IPV6;
         }
-        if (in.prevIPv4) {
+        if (in.ipv4) {
             return IpConnectivityLogClass.DefaultNetworkEvent.IPV4;
         }
         return IpConnectivityLogClass.DefaultNetworkEvent.NONE;
@@ -362,29 +381,46 @@
         TRANSPORT_LINKLAYER_MAP[TRANSPORT_BLUETOOTH]  = IpConnectivityLogClass.BLUETOOTH;
         TRANSPORT_LINKLAYER_MAP[TRANSPORT_ETHERNET]   = IpConnectivityLogClass.ETHERNET;
         TRANSPORT_LINKLAYER_MAP[TRANSPORT_VPN]        = IpConnectivityLogClass.UNKNOWN;
-        // TODO: change mapping TRANSPORT_WIFI_AWARE -> WIFI_AWARE
-        TRANSPORT_LINKLAYER_MAP[TRANSPORT_WIFI_AWARE] = IpConnectivityLogClass.UNKNOWN;
+        TRANSPORT_LINKLAYER_MAP[TRANSPORT_WIFI_AWARE] = IpConnectivityLogClass.WIFI_NAN;
+        TRANSPORT_LINKLAYER_MAP[TRANSPORT_LOWPAN]     = IpConnectivityLogClass.LOWPAN;
     };
 
     private static int ifnameToLinkLayer(String ifname) {
         // Do not try to catch all interface names with regexes, instead only catch patterns that
         // are cheap to check, and otherwise fallback on postprocessing in aggregation layer.
-        for (int i = 0; i < IFNAME_LINKLAYER_MAP.size(); i++) {
-            String pattern = IFNAME_LINKLAYER_MAP.valueAt(i);
+        for (int i = 0; i < KNOWN_PREFIX; i++) {
+            String pattern = IFNAME_PREFIXES[i];
             if (ifname.startsWith(pattern)) {
-                return IFNAME_LINKLAYER_MAP.keyAt(i);
+                return IFNAME_LINKLAYERS[i];
             }
         }
         return IpConnectivityLogClass.UNKNOWN;
     }
 
-    private static final SparseArray<String> IFNAME_LINKLAYER_MAP = new SparseArray<String>();
+    private static final int KNOWN_PREFIX = 7;
+    private static final String[] IFNAME_PREFIXES = new String[KNOWN_PREFIX];
+    private static final int[] IFNAME_LINKLAYERS = new int[KNOWN_PREFIX];
     static {
-        IFNAME_LINKLAYER_MAP.put(IpConnectivityLogClass.CELLULAR, "rmnet");
-        IFNAME_LINKLAYER_MAP.put(IpConnectivityLogClass.WIFI, "wlan");
-        IFNAME_LINKLAYER_MAP.put(IpConnectivityLogClass.BLUETOOTH, "bt-pan");
-        // TODO: rekey to USB
-        IFNAME_LINKLAYER_MAP.put(IpConnectivityLogClass.ETHERNET, "usb");
-        // TODO: add mappings for nan -> WIFI_AWARE and p2p -> WIFI_P2P
+        // Ordered from most likely link layer to least likely.
+        IFNAME_PREFIXES[0] = "rmnet";
+        IFNAME_LINKLAYERS[0] = IpConnectivityLogClass.CELLULAR;
+
+        IFNAME_PREFIXES[1] = "wlan";
+        IFNAME_LINKLAYERS[1] = IpConnectivityLogClass.WIFI;
+
+        IFNAME_PREFIXES[2] = "bt-pan";
+        IFNAME_LINKLAYERS[2] = IpConnectivityLogClass.BLUETOOTH;
+
+        IFNAME_PREFIXES[3] = "p2p";
+        IFNAME_LINKLAYERS[3] = IpConnectivityLogClass.WIFI_P2P;
+
+        IFNAME_PREFIXES[4] = "aware";
+        IFNAME_LINKLAYERS[4] = IpConnectivityLogClass.WIFI_NAN;
+
+        IFNAME_PREFIXES[5] = "eth";
+        IFNAME_LINKLAYERS[5] = IpConnectivityLogClass.ETHERNET;
+
+        IFNAME_PREFIXES[6] = "wpan";
+        IFNAME_LINKLAYERS[6] = IpConnectivityLogClass.LOWPAN;
     }
 }
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
index 475d786..f427819 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
@@ -23,8 +23,6 @@
 import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.IpConnectivityLog;
 import android.os.Binder;
-import android.os.IBinder;
-import android.os.Parcelable;
 import android.os.Process;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -32,19 +30,28 @@
 import android.util.ArrayMap;
 import android.util.Base64;
 import android.util.Log;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.RingBuffer;
 import com.android.internal.util.TokenBucket;
+import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
+
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.function.ToIntFunction;
 
-/** {@hide} */
+/**
+ * Event buffering service for core networking and connectivity metrics.
+ *
+ * {@hide}
+ */
 final public class IpConnectivityMetrics extends SystemService {
     private static final String TAG = IpConnectivityMetrics.class.getSimpleName();
     private static final boolean DBG = false;
@@ -58,7 +65,10 @@
 
     private static final String SERVICE_NAME = IpConnectivityLog.SERVICE_NAME;
 
-    // Default size of the event buffer. Once the buffer is full, incoming events are dropped.
+    // Default size of the event rolling log for bug report dumps.
+    private static final int DEFAULT_LOG_SIZE = 500;
+    // Default size of the event buffer for metrics reporting.
+    // Once the buffer is full, incoming events are dropped.
     private static final int DEFAULT_BUFFER_SIZE = 2000;
     // Maximum size of the event buffer.
     private static final int MAXIMUM_BUFFER_SIZE = DEFAULT_BUFFER_SIZE * 10;
@@ -67,29 +77,46 @@
 
     private static final int ERROR_RATE_LIMITED = -1;
 
-    // Lock ensuring that concurrent manipulations of the event buffer are correct.
+    // Lock ensuring that concurrent manipulations of the event buffers are correct.
     // There are three concurrent operations to synchronize:
     //  - appending events to the buffer.
     //  - iterating throught the buffer.
     //  - flushing the buffer content and replacing it by a new buffer.
     private final Object mLock = new Object();
 
+    // Implementation instance of IIpConnectivityMetrics.aidl.
     @VisibleForTesting
     public final Impl impl = new Impl();
+    // Subservice listening to Netd events via INetdEventListener.aidl.
     @VisibleForTesting
     NetdEventListenerService mNetdListener;
 
+    // Rolling log of the most recent events. This log is used for dumping
+    // connectivity events in bug reports.
+    @GuardedBy("mLock")
+    private final RingBuffer<ConnectivityMetricsEvent> mEventLog =
+            new RingBuffer(ConnectivityMetricsEvent.class, DEFAULT_LOG_SIZE);
+    // Buffer of connectivity events used for metrics reporting. This buffer
+    // does not rotate automatically and instead saturates when it becomes full.
+    // It is flushed at metrics reporting.
     @GuardedBy("mLock")
     private ArrayList<ConnectivityMetricsEvent> mBuffer;
+    // Total number of events dropped from mBuffer since last metrics reporting.
     @GuardedBy("mLock")
     private int mDropped;
+    // Capacity of mBuffer
     @GuardedBy("mLock")
     private int mCapacity;
+    // A list of rate limiting counters keyed by connectivity event types for
+    // metrics reporting mBuffer.
     @GuardedBy("mLock")
     private final ArrayMap<Class<?>, TokenBucket> mBuckets = makeRateLimitingBuckets();
 
     private final ToIntFunction<Context> mCapacityGetter;
 
+    @VisibleForTesting
+    final DefaultNetworkMetrics mDefaultNetworkMetrics = new DefaultNetworkMetrics();
+
     public IpConnectivityMetrics(Context ctx, ToIntFunction<Context> capacityGetter) {
         super(ctx);
         mCapacityGetter = capacityGetter;
@@ -113,6 +140,8 @@
 
             publishBinderService(SERVICE_NAME, impl);
             publishBinderService(mNetdListener.SERVICE_NAME, mNetdListener);
+
+            LocalServices.addService(Logger.class, new LoggerImpl());
         }
     }
 
@@ -132,6 +161,7 @@
     private int append(ConnectivityMetricsEvent event) {
         if (DBG) Log.d(TAG, "logEvent: " + event);
         synchronized (mLock) {
+            mEventLog.append(event);
             final int left = mCapacity - mBuffer.size();
             if (event == null) {
                 return left;
@@ -165,6 +195,8 @@
 
         final List<IpConnectivityEvent> protoEvents = IpConnectivityEventBuilder.toProto(events);
 
+        mDefaultNetworkMetrics.flushEvents(protoEvents);
+
         if (mNetdListener != null) {
             mNetdListener.flushStatistics(protoEvents);
         }
@@ -181,66 +213,66 @@
     }
 
     /**
-     * Clears the event buffer and prints its content as a protobuf serialized byte array
+     * Clear the event buffer and prints its content as a protobuf serialized byte array
      * inside a base64 encoded string.
      */
-    private void cmdFlush(FileDescriptor fd, PrintWriter pw, String[] args) {
+    private void cmdFlush(PrintWriter pw) {
         pw.print(flushEncodedOutput());
     }
 
     /**
-     * Prints the content of the event buffer, either using the events ASCII representation
-     * or using protobuf text format.
+     * Print the content of the rolling event buffer in human readable format.
+     * Also print network dns/connect statistics and recent default network events.
      */
-    private void cmdList(FileDescriptor fd, PrintWriter pw, String[] args) {
-        final ArrayList<ConnectivityMetricsEvent> events;
-        synchronized (mLock) {
-            events = new ArrayList(mBuffer);
-        }
-
-        if (args.length > 1 && args[1].equals("proto")) {
-            for (IpConnectivityEvent ev : IpConnectivityEventBuilder.toProto(events)) {
-                pw.print(ev.toString());
-            }
-            if (mNetdListener != null) {
-                mNetdListener.listAsProtos(pw);
-            }
-            return;
-        }
-
+    private void cmdList(PrintWriter pw) {
+        pw.println("metrics events:");
+        final List<ConnectivityMetricsEvent> events = getEvents();
         for (ConnectivityMetricsEvent ev : events) {
             pw.println(ev.toString());
         }
+        pw.println("");
         if (mNetdListener != null) {
             mNetdListener.list(pw);
         }
+        pw.println("");
+        mDefaultNetworkMetrics.listEvents(pw);
     }
 
-    private void cmdStats(FileDescriptor fd, PrintWriter pw, String[] args) {
-        synchronized (mLock) {
-            pw.println("Buffered events: " + mBuffer.size());
-            pw.println("Buffer capacity: " + mCapacity);
-            pw.println("Dropped events: " + mDropped);
+    /*
+     * Print the content of the rolling event buffer in text proto format.
+     */
+    private void cmdListAsProto(PrintWriter pw) {
+        final List<ConnectivityMetricsEvent> events = getEvents();
+        for (IpConnectivityEvent ev : IpConnectivityEventBuilder.toProto(events)) {
+            pw.print(ev.toString());
         }
         if (mNetdListener != null) {
-            mNetdListener.dump(pw);
+            mNetdListener.listAsProtos(pw);
         }
+        mDefaultNetworkMetrics.listEventsAsProto(pw);
     }
 
-    private void cmdDefault(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (args.length == 0) {
-            pw.println("No command");
-            return;
+    /*
+     * Return a copy of metrics events stored in buffer for metrics uploading.
+     */
+    private List<ConnectivityMetricsEvent> getEvents() {
+        synchronized (mLock) {
+            return Arrays.asList(mEventLog.toArray());
         }
-        pw.println("Unknown command " + TextUtils.join(" ", args));
     }
 
     public final class Impl extends IIpConnectivityMetrics.Stub {
-        static final String CMD_FLUSH   = "flush";
-        static final String CMD_LIST    = "list";
-        static final String CMD_STATS   = "stats";
-        static final String CMD_DUMPSYS = "-a"; // dumpsys.cpp dumps services with "-a" as arguments
-        static final String CMD_DEFAULT = CMD_STATS;
+        // Dump and flushes the metrics event buffer in base64 encoded serialized proto output.
+        static final String CMD_FLUSH = "flush";
+        // Dump the rolling buffer of metrics event in human readable proto text format.
+        static final String CMD_PROTO = "proto";
+        // Dump the rolling buffer of metrics event and pretty print events using a human readable
+        // format. Also print network dns/connect statistics and default network event time series.
+        static final String CMD_LIST = "list";
+        // By default any other argument will fall into the default case which is remapped to the
+        // "list" command. This includes most notably bug reports collected by dumpsys.cpp with
+        // the "-a" argument.
+        static final String CMD_DEFAULT = CMD_LIST;
 
         @Override
         public int logEvent(ConnectivityMetricsEvent event) {
@@ -255,18 +287,15 @@
             final String cmd = (args.length > 0) ? args[0] : CMD_DEFAULT;
             switch (cmd) {
                 case CMD_FLUSH:
-                    cmdFlush(fd, pw, args);
+                    cmdFlush(pw);
                     return;
-                case CMD_DUMPSYS:
-                    // Fallthrough to CMD_LIST when dumpsys.cpp dumps services states (bug reports)
-                case CMD_LIST:
-                    cmdList(fd, pw, args);
+                case CMD_PROTO:
+                    cmdListAsProto(pw);
                     return;
-                case CMD_STATS:
-                    cmdStats(fd, pw, args);
-                    return;
+                case CMD_LIST: // fallthrough
                 default:
-                    cmdDefault(fd, pw, args);
+                    cmdList(pw);
+                    return;
             }
         }
 
@@ -291,22 +320,22 @@
         }
 
         @Override
-        public boolean registerNetdEventCallback(INetdEventCallback callback) {
+        public boolean addNetdEventCallback(int callerType, INetdEventCallback callback) {
             enforceNetdEventListeningPermission();
             if (mNetdListener == null) {
                 return false;
             }
-            return mNetdListener.registerNetdEventCallback(callback);
+            return mNetdListener.addNetdEventCallback(callerType, callback);
         }
 
         @Override
-        public boolean unregisterNetdEventCallback() {
+        public boolean removeNetdEventCallback(int callerType) {
             enforceNetdEventListeningPermission();
             if (mNetdListener == null) {
                 // if the service is null, we aren't registered anyway
                 return true;
             }
-            return mNetdListener.unregisterNetdEventCallback();
+            return mNetdListener.removeNetdEventCallback(callerType);
         }
     };
 
@@ -325,4 +354,15 @@
         map.put(ApfProgramEvent.class, new TokenBucket((int)DateUtils.MINUTE_IN_MILLIS, 50));
         return map;
     }
+
+    /** Direct non-Binder interface for event producer clients within the system servers. */
+    public interface Logger {
+        DefaultNetworkMetrics defaultNetworkMetrics();
+    }
+
+    private class LoggerImpl implements Logger {
+        public DefaultNetworkMetrics defaultNetworkMetrics() {
+            return mDefaultNetworkMetrics;
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index b390884..fceacba 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -16,71 +16,68 @@
 
 package com.android.server.connectivity;
 
-import java.net.Inet4Address;
-
-import android.content.Context;
 import android.net.InterfaceConfiguration;
 import android.net.ConnectivityManager;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
-import android.net.NetworkAgent;
+import android.net.NetworkInfo;
 import android.net.RouteInfo;
-import android.os.Handler;
-import android.os.Message;
 import android.os.INetworkManagementService;
 import android.os.RemoteException;
 import android.util.Slog;
 
-import com.android.server.net.BaseNetworkObserver;
 import com.android.internal.util.ArrayUtils;
+import com.android.server.net.BaseNetworkObserver;
+
+import java.net.Inet4Address;
+import java.util.Objects;
 
 /**
- * @hide
+ * Class to manage a 464xlat CLAT daemon. Nat464Xlat is not thread safe and should be manipulated
+ * from a consistent and unique thread context. It is the responsibility of ConnectivityService to
+ * call into this class from its own Handler thread.
  *
- * Class to manage a 464xlat CLAT daemon.
+ * @hide
  */
 public class Nat464Xlat extends BaseNetworkObserver {
-    private static final String TAG = "Nat464Xlat";
+    private static final String TAG = Nat464Xlat.class.getSimpleName();
 
     // This must match the interface prefix in clatd.c.
     private static final String CLAT_PREFIX = "v4-";
 
-    // The network types we will start clatd on.
+    // The network types on which we will start clatd,
+    // allowing clat only on networks for which we can support IPv6-only.
     private static final int[] NETWORK_TYPES = {
-            ConnectivityManager.TYPE_MOBILE,
-            ConnectivityManager.TYPE_WIFI,
-            ConnectivityManager.TYPE_ETHERNET,
+        ConnectivityManager.TYPE_MOBILE,
+        ConnectivityManager.TYPE_WIFI,
+        ConnectivityManager.TYPE_ETHERNET,
+    };
+
+    // The network states in which running clatd is supported.
+    private static final NetworkInfo.State[] NETWORK_STATES = {
+        NetworkInfo.State.CONNECTED,
+        NetworkInfo.State.SUSPENDED,
     };
 
     private final INetworkManagementService mNMService;
 
-    // ConnectivityService Handler for LinkProperties updates.
-    private final Handler mHandler;
-
     // The network we're running on, and its type.
     private final NetworkAgentInfo mNetwork;
 
-    // Internal state variables.
-    //
-    // The possible states are:
-    //  - Idle: start() not called. Everything is null.
-    //  - Starting: start() called. Interfaces are non-null. isStarted() returns true.
-    //    mIsRunning is false.
-    //  - Running: start() called, and interfaceLinkStateChanged() told us that mIface is up.
-    //    mIsRunning is true.
-    //
-    // Once mIface is non-null and isStarted() is true, methods called by ConnectivityService on
-    // its handler thread must not modify any internal state variables; they are only updated by the
-    // interface observers, called on the notification threads.
+    private enum State {
+        IDLE,       // start() not called. Base iface and stacked iface names are null.
+        STARTING,   // start() called. Base iface and stacked iface names are known.
+        RUNNING,    // start() called, and the stacked iface is known to be up.
+        STOPPING;   // stop() called, this Nat464Xlat is still registered as a network observer for
+                    // the stacked interface.
+    }
+
     private String mBaseIface;
     private String mIface;
-    private boolean mIsRunning;
+    private State mState = State.IDLE;
 
-    public Nat464Xlat(
-            Context context, INetworkManagementService nmService,
-            Handler handler, NetworkAgentInfo nai) {
+    public Nat464Xlat(INetworkManagementService nmService, NetworkAgentInfo nai) {
         mNMService = nmService;
-        mHandler = handler;
         mNetwork = nai;
     }
 
@@ -90,34 +87,104 @@
      * @return true if the network requires clat, false otherwise.
      */
     public static boolean requiresClat(NetworkAgentInfo nai) {
-        final int netType = nai.networkInfo.getType();
-        final boolean connected = nai.networkInfo.isConnected();
+        // TODO: migrate to NetworkCapabilities.TRANSPORT_*.
+        final boolean supported = ArrayUtils.contains(NETWORK_TYPES, nai.networkInfo.getType());
+        final boolean connected = ArrayUtils.contains(NETWORK_STATES, nai.networkInfo.getState());
+        // We only run clat on networks that don't have a native IPv4 address.
         final boolean hasIPv4Address =
-                (nai.linkProperties != null) ? nai.linkProperties.hasIPv4Address() : false;
-        // Only support clat on mobile and wifi for now, because these are the only IPv6-only
-        // networks we can connect to.
-        return connected && !hasIPv4Address && ArrayUtils.contains(NETWORK_TYPES, netType);
+                (nai.linkProperties != null) && nai.linkProperties.hasIPv4Address();
+        return supported && connected && !hasIPv4Address;
     }
 
     /**
-     * Determines whether clatd is started. Always true, except a) if start has not yet been called,
-     * or b) if our interface was removed.
+     * @return true if clatd has been started and has not yet stopped.
+     * A true result corresponds to internal states STARTING and RUNNING.
      */
     public boolean isStarted() {
-        return mIface != null;
+        return mState != State.IDLE;
     }
 
     /**
-     * Clears internal state. Must not be called by ConnectivityService.
+     * @return true if clatd has been started but the stacked interface is not yet up.
      */
-    private void clear() {
+    public boolean isStarting() {
+        return mState == State.STARTING;
+    }
+
+    /**
+     * @return true if clatd has been started and the stacked interface is up.
+     */
+    public boolean isRunning() {
+        return mState == State.RUNNING;
+    }
+
+    /**
+     * @return true if clatd has been stopped.
+     */
+    public boolean isStopping() {
+        return mState == State.STOPPING;
+    }
+
+    /**
+     * Start clatd, register this Nat464Xlat as a network observer for the stacked interface,
+     * and set internal state.
+     */
+    private void enterStartingState(String baseIface) {
+        try {
+            mNMService.registerObserver(this);
+        } catch(RemoteException e) {
+            Slog.e(TAG,
+                    "startClat: Can't register interface observer for clat on " + mNetwork.name());
+            return;
+        }
+        try {
+            mNMService.startClatd(baseIface);
+        } catch(RemoteException|IllegalStateException e) {
+            Slog.e(TAG, "Error starting clatd on " + baseIface, e);
+        }
+        mIface = CLAT_PREFIX + baseIface;
+        mBaseIface = baseIface;
+        mState = State.STARTING;
+    }
+
+    /**
+     * Enter running state just after getting confirmation that the stacked interface is up, and
+     * turn ND offload off if on WiFi.
+     */
+    private void enterRunningState() {
+        mState = State.RUNNING;
+    }
+
+    /**
+     * Stop clatd, and turn ND offload on if it had been turned off.
+     */
+    private void enterStoppingState() {
+        try {
+            mNMService.stopClatd(mBaseIface);
+        } catch(RemoteException|IllegalStateException e) {
+            Slog.e(TAG, "Error stopping clatd on " + mBaseIface, e);
+        }
+
+        mState = State.STOPPING;
+    }
+
+    /**
+     * Unregister as a base observer for the stacked interface, and clear internal state.
+     */
+    private void enterIdleState() {
+        try {
+            mNMService.unregisterObserver(this);
+        } catch(RemoteException|IllegalStateException e) {
+            Slog.e(TAG, "Error unregistering clatd observer on " + mBaseIface, e);
+        }
+
         mIface = null;
         mBaseIface = null;
-        mIsRunning = false;
+        mState = State.IDLE;
     }
 
     /**
-     * Starts the clat daemon. Called by ConnectivityService on the handler thread.
+     * Starts the clat daemon.
      */
     public void start() {
         if (isStarted()) {
@@ -130,52 +197,30 @@
             return;
         }
 
-        try {
-            mNMService.registerObserver(this);
-        } catch(RemoteException e) {
-            Slog.e(TAG, "startClat: Can't register interface observer for clat on " + mNetwork);
-            return;
-        }
-
-        mBaseIface = mNetwork.linkProperties.getInterfaceName();
-        if (mBaseIface == null) {
+        String baseIface = mNetwork.linkProperties.getInterfaceName();
+        if (baseIface == null) {
             Slog.e(TAG, "startClat: Can't start clat on null interface");
             return;
         }
-        mIface = CLAT_PREFIX + mBaseIface;
-        // From now on, isStarted() will return true.
-
-        Slog.i(TAG, "Starting clatd on " + mBaseIface);
-        try {
-            mNMService.startClatd(mBaseIface);
-        } catch(RemoteException|IllegalStateException e) {
-            Slog.e(TAG, "Error starting clatd: " + e);
-        }
+        // TODO: should we only do this if mNMService.startClatd() succeeds?
+        Slog.i(TAG, "Starting clatd on " + baseIface);
+        enterStartingState(baseIface);
     }
 
     /**
-     * Stops the clat daemon. Called by ConnectivityService on the handler thread.
+     * Stops the clat daemon.
      */
     public void stop() {
-        if (isStarted()) {
-            Slog.i(TAG, "Stopping clatd");
-            try {
-                mNMService.stopClatd(mBaseIface);
-            } catch(RemoteException|IllegalStateException e) {
-                Slog.e(TAG, "Error stopping clatd: " + e);
-            }
-            // When clatd stops and its interface is deleted, interfaceRemoved() will notify
-            // ConnectivityService and call clear().
-        } else {
-            Slog.e(TAG, "clatd: already stopped");
+        if (!isStarted()) {
+            return;
         }
-    }
+        Slog.i(TAG, "Stopping clatd on " + mBaseIface);
 
-    private void updateConnectivityService(LinkProperties lp) {
-        Message msg = mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED, lp);
-        msg.replyTo = mNetwork.messenger;
-        Slog.i(TAG, "sending message to ConnectivityService: " + msg);
-        msg.sendToTarget();
+        boolean wasStarting = isStarting();
+        enterStoppingState();
+        if (wasStarting) {
+            enterIdleState();
+        }
     }
 
     /**
@@ -184,16 +229,19 @@
      * has no idea that 464xlat is running on top of it.
      */
     public void fixupLinkProperties(LinkProperties oldLp) {
-        if (mNetwork.clatd != null &&
-                mIsRunning &&
-                mNetwork.linkProperties != null &&
-                !mNetwork.linkProperties.getAllInterfaceNames().contains(mIface)) {
-            Slog.d(TAG, "clatd running, updating NAI for " + mIface);
-            for (LinkProperties stacked: oldLp.getStackedLinks()) {
-                if (mIface.equals(stacked.getInterfaceName())) {
-                    mNetwork.linkProperties.addStackedLink(stacked);
-                    break;
-                }
+        if (!isRunning()) {
+            return;
+        }
+        LinkProperties lp = mNetwork.linkProperties;
+        if (lp == null || lp.getAllInterfaceNames().contains(mIface)) {
+            return;
+        }
+
+        Slog.d(TAG, "clatd running, updating NAI for " + mIface);
+        for (LinkProperties stacked: oldLp.getStackedLinks()) {
+            if (Objects.equals(mIface, stacked.getInterfaceName())) {
+                lp.addStackedLink(stacked);
+                return;
             }
         }
     }
@@ -226,64 +274,63 @@
         }
     }
 
-    private void maybeSetIpv6NdOffload(String iface, boolean on) {
-        if (mNetwork.networkInfo.getType() != ConnectivityManager.TYPE_WIFI) {
+    /**
+     * Adds stacked link on base link and transitions to RUNNING state.
+     */
+    private void handleInterfaceLinkStateChanged(String iface, boolean up) {
+        if (!isStarting() || !up || !Objects.equals(mIface, iface)) {
             return;
         }
-        try {
-            Slog.d(TAG, (on ? "En" : "Dis") + "abling ND offload on " + iface);
-            mNMService.setInterfaceIpv6NdOffload(iface, on);
-        } catch(RemoteException|IllegalStateException e) {
-            Slog.w(TAG, "Changing IPv6 ND offload on " + iface + "failed: " + e);
+
+        LinkAddress clatAddress = getLinkAddress(iface);
+        if (clatAddress == null) {
+            Slog.e(TAG, "clatAddress was null for stacked iface " + iface);
+            return;
         }
+
+        Slog.i(TAG, String.format("interface %s is up, adding stacked link %s on top of %s",
+                mIface, mIface, mBaseIface));
+        enterRunningState();
+        LinkProperties lp = new LinkProperties(mNetwork.linkProperties);
+        lp.addStackedLink(makeLinkProperties(clatAddress));
+        mNetwork.connService().handleUpdateLinkProperties(mNetwork, lp);
+    }
+
+    /**
+     * Removes stacked link on base link and transitions to IDLE state.
+     */
+    private void handleInterfaceRemoved(String iface) {
+        if (!Objects.equals(mIface, iface)) {
+            return;
+        }
+        if (!isRunning() && !isStopping()) {
+            return;
+        }
+
+        Slog.i(TAG, "interface " + iface + " removed");
+        if (!isStopping()) {
+            // Ensure clatd is stopped if stop() has not been called: this likely means that clatd
+            // has crashed.
+            enterStoppingState();
+        }
+        enterIdleState();
+        LinkProperties lp = new LinkProperties(mNetwork.linkProperties);
+        lp.removeStackedLink(iface);
+        mNetwork.connService().handleUpdateLinkProperties(mNetwork, lp);
     }
 
     @Override
     public void interfaceLinkStateChanged(String iface, boolean up) {
-        // Called by the InterfaceObserver on its own thread, so can race with stop().
-        if (isStarted() && up && mIface.equals(iface)) {
-            Slog.i(TAG, "interface " + iface + " is up, mIsRunning " + mIsRunning + "->true");
-
-            if (!mIsRunning) {
-                LinkAddress clatAddress = getLinkAddress(iface);
-                if (clatAddress == null) {
-                    return;
-                }
-                mIsRunning = true;
-                maybeSetIpv6NdOffload(mBaseIface, false);
-                LinkProperties lp = new LinkProperties(mNetwork.linkProperties);
-                lp.addStackedLink(makeLinkProperties(clatAddress));
-                Slog.i(TAG, "Adding stacked link " + mIface + " on top of " + mBaseIface);
-                updateConnectivityService(lp);
-            }
-        }
+        mNetwork.handler().post(() -> { handleInterfaceLinkStateChanged(iface, up); });
     }
 
     @Override
     public void interfaceRemoved(String iface) {
-        if (isStarted() && mIface.equals(iface)) {
-            Slog.i(TAG, "interface " + iface + " removed, mIsRunning " + mIsRunning + "->false");
+        mNetwork.handler().post(() -> { handleInterfaceRemoved(iface); });
+    }
 
-            if (mIsRunning) {
-                // The interface going away likely means clatd has crashed. Ask netd to stop it,
-                // because otherwise when we try to start it again on the same base interface netd
-                // will complain that it's already started.
-                //
-                // Note that this method can be called by the interface observer at the same time
-                // that ConnectivityService calls stop(). In this case, the second call to
-                // stopClatd() will just throw IllegalStateException, which we'll ignore.
-                try {
-                    mNMService.unregisterObserver(this);
-                    mNMService.stopClatd(mBaseIface);
-                } catch (RemoteException|IllegalStateException e) {
-                    // Well, we tried.
-                }
-                maybeSetIpv6NdOffload(mBaseIface, true);
-                LinkProperties lp = new LinkProperties(mNetwork.linkProperties);
-                lp.removeStackedLink(mIface);
-                clear();
-                updateConnectivityService(lp);
-            }
-        }
+    @Override
+    public String toString() {
+        return "mBaseIface: " + mBaseIface + ", mIface: " + mIface + ", mState: " + mState;
     }
 }
diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
index 4094083..6f2d77f 100644
--- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
+++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
@@ -16,29 +16,39 @@
 
 package com.android.server.connectivity;
 
+import static android.util.TimeUtils.NANOS_PER_MS;
+
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.INetdEventCallback;
+import android.net.MacAddress;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.metrics.ConnectStats;
 import android.net.metrics.DnsEvent;
 import android.net.metrics.INetdEventListener;
 import android.net.metrics.IpConnectivityLog;
+import android.net.metrics.NetworkMetrics;
+import android.net.metrics.WakeupEvent;
+import android.net.metrics.WakeupStats;
 import android.os.RemoteException;
 import android.text.format.DateUtils;
 import android.util.Log;
+import android.util.ArrayMap;
 import android.util.SparseArray;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.BitUtils;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.RingBuffer;
 import com.android.internal.util.TokenBucket;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
+
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.List;
-import java.util.function.Function;
-import java.util.function.IntFunction;
+import java.util.StringJoiner;
 
 /**
  * Implementation of the INetdEventListener interface.
@@ -49,42 +59,94 @@
 
     private static final String TAG = NetdEventListenerService.class.getSimpleName();
     private static final boolean DBG = false;
-    private static final boolean VDBG = false;
-
-    private static final int INITIAL_DNS_BATCH_SIZE = 100;
 
     // Rate limit connect latency logging to 1 measurement per 15 seconds (5760 / day) with maximum
     // bursts of 5000 measurements.
     private static final int CONNECT_LATENCY_BURST_LIMIT  = 5000;
     private static final int CONNECT_LATENCY_FILL_RATE    = 15 * (int) DateUtils.SECOND_IN_MILLIS;
-    private static final int CONNECT_LATENCY_MAXIMUM_RECORDS = 20000;
 
-    // Sparse arrays of DNS and connect events, grouped by net id.
+    private static final long METRICS_SNAPSHOT_SPAN_MS = 5 * DateUtils.MINUTE_IN_MILLIS;
+    private static final int METRICS_SNAPSHOT_BUFFER_SIZE = 48; // 4 hours
+
+    @VisibleForTesting
+    static final int WAKEUP_EVENT_BUFFER_LENGTH = 1024;
+    // TODO: dedup this String constant with the one used in
+    // ConnectivityService#wakeupModifyInterface().
+    @VisibleForTesting
+    static final String WAKEUP_EVENT_IFACE_PREFIX = "iface:";
+
+    // Array of aggregated DNS and connect events sent by netd, grouped by net id.
     @GuardedBy("this")
-    private final SparseArray<DnsEvent> mDnsEvents = new SparseArray<>();
+    private final SparseArray<NetworkMetrics> mNetworkMetrics = new SparseArray<>();
+
     @GuardedBy("this")
-    private final SparseArray<ConnectStats> mConnectEvents = new SparseArray<>();
+    private final RingBuffer<NetworkMetricsSnapshot> mNetworkMetricsSnapshots =
+            new RingBuffer<>(NetworkMetricsSnapshot.class, METRICS_SNAPSHOT_BUFFER_SIZE);
+    @GuardedBy("this")
+    private long mLastSnapshot = 0;
+
+    // Array of aggregated wakeup event stats, grouped by interface name.
+    @GuardedBy("this")
+    private final ArrayMap<String, WakeupStats> mWakeupStats = new ArrayMap<>();
+    // Ring buffer array for storing packet wake up events sent by Netd.
+    @GuardedBy("this")
+    private final RingBuffer<WakeupEvent> mWakeupEvents =
+            new RingBuffer<>(WakeupEvent.class, WAKEUP_EVENT_BUFFER_LENGTH);
 
     private final ConnectivityManager mCm;
 
     @GuardedBy("this")
     private final TokenBucket mConnectTb =
             new TokenBucket(CONNECT_LATENCY_FILL_RATE, CONNECT_LATENCY_BURST_LIMIT);
-    // Callback should only be registered/unregistered when logging is being enabled/disabled in DPM
-    // by the device owner. It's DevicePolicyManager's responsibility to ensure that.
-    @GuardedBy("this")
-    private INetdEventCallback mNetdEventCallback;
 
-    public synchronized boolean registerNetdEventCallback(INetdEventCallback callback) {
-        mNetdEventCallback = callback;
+
+    /**
+     * There are only 2 possible callbacks.
+     *
+     * mNetdEventCallbackList[CALLBACK_CALLER_DEVICE_POLICY].
+     * Callback registered/unregistered when logging is being enabled/disabled in DPM
+     * by the device owner. It's DevicePolicyManager's responsibility to ensure that.
+     *
+     * mNetdEventCallbackList[CALLBACK_CALLER_NETWORK_WATCHLIST]
+     * Callback registered/unregistered by NetworkWatchlistService.
+     */
+    @GuardedBy("this")
+    private static final int[] ALLOWED_CALLBACK_TYPES = {
+        INetdEventCallback.CALLBACK_CALLER_DEVICE_POLICY,
+        INetdEventCallback.CALLBACK_CALLER_NETWORK_WATCHLIST
+    };
+
+    @GuardedBy("this")
+    private INetdEventCallback[] mNetdEventCallbackList =
+            new INetdEventCallback[ALLOWED_CALLBACK_TYPES.length];
+
+    public synchronized boolean addNetdEventCallback(int callerType, INetdEventCallback callback) {
+        if (!isValidCallerType(callerType)) {
+            Log.e(TAG, "Invalid caller type: " + callerType);
+            return false;
+        }
+        mNetdEventCallbackList[callerType] = callback;
         return true;
     }
 
-    public synchronized boolean unregisterNetdEventCallback() {
-        mNetdEventCallback = null;
+    public synchronized boolean removeNetdEventCallback(int callerType) {
+        if (!isValidCallerType(callerType)) {
+            Log.e(TAG, "Invalid caller type: " + callerType);
+            return false;
+        }
+        mNetdEventCallbackList[callerType] = null;
         return true;
     }
 
+    private static boolean isValidCallerType(int callerType) {
+        for (int i = 0; i < ALLOWED_CALLBACK_TYPES.length; i++) {
+            if (callerType == ALLOWED_CALLBACK_TYPES[i]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     public NetdEventListenerService(Context context) {
         this(context.getSystemService(ConnectivityManager.class));
     }
@@ -95,24 +157,54 @@
         mCm = cm;
     }
 
+    private static long projectSnapshotTime(long timeMs) {
+        return (timeMs / METRICS_SNAPSHOT_SPAN_MS) * METRICS_SNAPSHOT_SPAN_MS;
+    }
+
+    private NetworkMetrics getMetricsForNetwork(long timeMs, int netId) {
+        collectPendingMetricsSnapshot(timeMs);
+        NetworkMetrics metrics = mNetworkMetrics.get(netId);
+        if (metrics == null) {
+            // TODO: allow to change transport for a given netid.
+            metrics = new NetworkMetrics(netId, getTransports(netId), mConnectTb);
+            mNetworkMetrics.put(netId, metrics);
+        }
+        return metrics;
+    }
+
+    private NetworkMetricsSnapshot[] getNetworkMetricsSnapshots() {
+        collectPendingMetricsSnapshot(System.currentTimeMillis());
+        return mNetworkMetricsSnapshots.toArray();
+    }
+
+    private void collectPendingMetricsSnapshot(long timeMs) {
+        // Detects time differences larger than the snapshot collection period.
+        // This is robust against clock jumps and long inactivity periods.
+        if (Math.abs(timeMs - mLastSnapshot) <= METRICS_SNAPSHOT_SPAN_MS) {
+            return;
+        }
+        mLastSnapshot = projectSnapshotTime(timeMs);
+        NetworkMetricsSnapshot snapshot =
+                NetworkMetricsSnapshot.collect(mLastSnapshot, mNetworkMetrics);
+        if (snapshot.stats.isEmpty()) {
+            return;
+        }
+        mNetworkMetricsSnapshots.append(snapshot);
+    }
+
     @Override
     // Called concurrently by multiple binder threads.
     // This method must not block or perform long-running operations.
     public synchronized void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs,
             String hostname, String[] ipAddresses, int ipAddressesCount, int uid)
             throws RemoteException {
-        maybeVerboseLog("onDnsEvent(%d, %d, %d, %dms)", netId, eventType, returnCode, latencyMs);
+        long timestamp = System.currentTimeMillis();
+        getMetricsForNetwork(timestamp, netId).addDnsResult(eventType, returnCode, latencyMs);
 
-        DnsEvent dnsEvent = mDnsEvents.get(netId);
-        if (dnsEvent == null) {
-            dnsEvent = makeDnsEvent(netId);
-            mDnsEvents.put(netId, dnsEvent);
-        }
-        dnsEvent.addResult((byte) eventType, (byte) returnCode, latencyMs);
-
-        if (mNetdEventCallback != null) {
-            long timestamp = System.currentTimeMillis();
-            mNetdEventCallback.onDnsEvent(hostname, ipAddresses, ipAddressesCount, timestamp, uid);
+        for (INetdEventCallback callback : mNetdEventCallbackList) {
+            if (callback != null) {
+                callback.onDnsEvent(hostname, ipAddresses, ipAddressesCount, timestamp, uid);
+            }
         }
     }
 
@@ -121,70 +213,111 @@
     // This method must not block or perform long-running operations.
     public synchronized void onConnectEvent(int netId, int error, int latencyMs, String ipAddr,
             int port, int uid) throws RemoteException {
-        maybeVerboseLog("onConnectEvent(%d, %d, %dms)", netId, error, latencyMs);
+        long timestamp = System.currentTimeMillis();
+        getMetricsForNetwork(timestamp, netId).addConnectResult(error, latencyMs, ipAddr);
 
-        ConnectStats connectStats = mConnectEvents.get(netId);
-        if (connectStats == null) {
-            connectStats = makeConnectStats(netId);
-            mConnectEvents.put(netId, connectStats);
-        }
-        connectStats.addEvent(error, latencyMs, ipAddr);
-
-        if (mNetdEventCallback != null) {
-            mNetdEventCallback.onConnectEvent(ipAddr, port, System.currentTimeMillis(), uid);
+        for (INetdEventCallback callback : mNetdEventCallbackList) {
+            if (callback != null) {
+                // TODO(rickywai): Remove this checking to collect ip in watchlist.
+                if (callback ==
+                        mNetdEventCallbackList[INetdEventCallback.CALLBACK_CALLER_DEVICE_POLICY]) {
+                    callback.onConnectEvent(ipAddr, port, timestamp, uid);
+                }
+            }
         }
     }
 
     @Override
-    public synchronized void onWakeupEvent(String prefix, int uid, int gid, long timestampNs) {
+    public synchronized void onWakeupEvent(String prefix, int uid, int ethertype, int ipNextHeader,
+            byte[] dstHw, String srcIp, String dstIp, int srcPort, int dstPort, long timestampNs) {
+        String iface = prefix.replaceFirst(WAKEUP_EVENT_IFACE_PREFIX, "");
+        final long timestampMs;
+        if (timestampNs > 0) {
+            timestampMs = timestampNs / NANOS_PER_MS;
+        } else {
+            timestampMs = System.currentTimeMillis();
+        }
+
+        WakeupEvent event = new WakeupEvent();
+        event.iface = iface;
+        event.timestampMs = timestampMs;
+        event.uid = uid;
+        event.ethertype = ethertype;
+        event.dstHwAddr = new MacAddress(dstHw);
+        event.srcIp = srcIp;
+        event.dstIp = dstIp;
+        event.ipNextHeader = ipNextHeader;
+        event.srcPort = srcPort;
+        event.dstPort = dstPort;
+        addWakeupEvent(event);
+    }
+
+    private void addWakeupEvent(WakeupEvent event) {
+        String iface = event.iface;
+        mWakeupEvents.append(event);
+        WakeupStats stats = mWakeupStats.get(iface);
+        if (stats == null) {
+            stats = new WakeupStats(iface);
+            mWakeupStats.put(iface, stats);
+        }
+        stats.countEvent(event);
     }
 
     public synchronized void flushStatistics(List<IpConnectivityEvent> events) {
-        flushProtos(events, mConnectEvents, IpConnectivityEventBuilder::toProto);
-        flushProtos(events, mDnsEvents, IpConnectivityEventBuilder::toProto);
-    }
-
-    public synchronized void dump(PrintWriter writer) {
-        IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
-        pw.println(TAG + ":");
-        pw.increaseIndent();
-        list(pw);
-        pw.decreaseIndent();
+        for (int i = 0; i < mNetworkMetrics.size(); i++) {
+            ConnectStats stats = mNetworkMetrics.valueAt(i).connectMetrics;
+            if (stats.eventCount == 0) {
+                continue;
+            }
+            events.add(IpConnectivityEventBuilder.toProto(stats));
+        }
+        for (int i = 0; i < mNetworkMetrics.size(); i++) {
+            DnsEvent ev = mNetworkMetrics.valueAt(i).dnsMetrics;
+            if (ev.eventCount == 0) {
+                continue;
+            }
+            events.add(IpConnectivityEventBuilder.toProto(ev));
+        }
+        for (int i = 0; i < mWakeupStats.size(); i++) {
+            events.add(IpConnectivityEventBuilder.toProto(mWakeupStats.valueAt(i)));
+        }
+        mNetworkMetrics.clear();
+        mWakeupStats.clear();
     }
 
     public synchronized void list(PrintWriter pw) {
-        listEvents(pw, mConnectEvents, (x) -> x);
-        listEvents(pw, mDnsEvents, (x) -> x);
+        pw.println("dns/connect events:");
+        for (int i = 0; i < mNetworkMetrics.size(); i++) {
+            pw.println(mNetworkMetrics.valueAt(i).connectMetrics);
+        }
+        for (int i = 0; i < mNetworkMetrics.size(); i++) {
+            pw.println(mNetworkMetrics.valueAt(i).dnsMetrics);
+        }
+        pw.println("");
+        pw.println("network statistics:");
+        for (NetworkMetricsSnapshot s : getNetworkMetricsSnapshots()) {
+            pw.println(s);
+        }
+        pw.println("");
+        pw.println("packet wakeup events:");
+        for (int i = 0; i < mWakeupStats.size(); i++) {
+            pw.println(mWakeupStats.valueAt(i));
+        }
+        for (WakeupEvent wakeup : mWakeupEvents.toArray()) {
+            pw.println(wakeup);
+        }
     }
 
     public synchronized void listAsProtos(PrintWriter pw) {
-        listEvents(pw, mConnectEvents, IpConnectivityEventBuilder::toProto);
-        listEvents(pw, mDnsEvents, IpConnectivityEventBuilder::toProto);
-    }
-
-    private static <T> void flushProtos(List<IpConnectivityEvent> out, SparseArray<T> in,
-            Function<T, IpConnectivityEvent> mapper) {
-        for (int i = 0; i < in.size(); i++) {
-            out.add(mapper.apply(in.valueAt(i)));
+        for (int i = 0; i < mNetworkMetrics.size(); i++) {
+            pw.print(IpConnectivityEventBuilder.toProto(mNetworkMetrics.valueAt(i).connectMetrics));
         }
-        in.clear();
-    }
-
-    public static <T> void listEvents(
-            PrintWriter pw, SparseArray<T> events, Function<T, Object> mapper) {
-        for (int i = 0; i < events.size(); i++) {
-            pw.println(mapper.apply(events.valueAt(i)).toString());
+        for (int i = 0; i < mNetworkMetrics.size(); i++) {
+            pw.print(IpConnectivityEventBuilder.toProto(mNetworkMetrics.valueAt(i).dnsMetrics));
         }
-    }
-
-    private ConnectStats makeConnectStats(int netId) {
-        long transports = getTransports(netId);
-        return new ConnectStats(netId, transports, mConnectTb, CONNECT_LATENCY_MAXIMUM_RECORDS);
-    }
-
-    private DnsEvent makeDnsEvent(int netId) {
-        long transports = getTransports(netId);
-        return new DnsEvent(netId, transports, INITIAL_DNS_BATCH_SIZE);
+        for (int i = 0; i < mWakeupStats.size(); i++) {
+            pw.print(IpConnectivityEventBuilder.toProto(mWakeupStats.valueAt(i)));
+        }
     }
 
     private long getTransports(int netId) {
@@ -200,7 +333,31 @@
         if (DBG) Log.d(TAG, String.format(s, args));
     }
 
-    private static void maybeVerboseLog(String s, Object... args) {
-        if (VDBG) Log.d(TAG, String.format(s, args));
+    /** Helper class for buffering summaries of NetworkMetrics at regular time intervals */
+    static class NetworkMetricsSnapshot {
+
+        public long timeMs;
+        public List<NetworkMetrics.Summary> stats = new ArrayList<>();
+
+        static NetworkMetricsSnapshot collect(long timeMs, SparseArray<NetworkMetrics> networkMetrics) {
+            NetworkMetricsSnapshot snapshot = new NetworkMetricsSnapshot();
+            snapshot.timeMs = timeMs;
+            for (int i = 0; i < networkMetrics.size(); i++) {
+                NetworkMetrics.Summary s = networkMetrics.valueAt(i).getPendingStats();
+                if (s != null) {
+                    snapshot.stats.add(s);
+                }
+            }
+            return snapshot;
+        }
+
+        @Override
+        public String toString() {
+            StringJoiner j = new StringJoiner(", ");
+            for (NetworkMetrics.Summary s : stats) {
+                j.add(s.toString());
+            }
+            return String.format("%tT.%tL: %s", timeMs, timeMs, j.toString());
+        }
     }
 }
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 2a618bc..a4d7242 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -27,7 +27,9 @@
 import android.net.NetworkRequest;
 import android.net.NetworkState;
 import android.os.Handler;
+import android.os.INetworkManagementService;
 import android.os.Messenger;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.Log;
 import android.util.SparseArray;
@@ -268,6 +270,18 @@
         networkMisc = misc;
     }
 
+    public ConnectivityService connService() {
+        return mConnService;
+    }
+
+    public Handler handler() {
+        return mHandler;
+    }
+
+    public Network network() {
+        return network;
+    }
+
     // Functions for manipulating the requests satisfied by this network.
     //
     // These functions must only called on ConnectivityService's main thread.
@@ -551,6 +565,32 @@
         for (LingerTimer timer : mLingerTimers) { pw.println(timer); }
     }
 
+    public void updateClat(INetworkManagementService netd) {
+        if (Nat464Xlat.requiresClat(this)) {
+            maybeStartClat(netd);
+        } else {
+            maybeStopClat();
+        }
+    }
+
+    /** Ensure clat has started for this network. */
+    public void maybeStartClat(INetworkManagementService netd) {
+        if (clatd != null && clatd.isStarted()) {
+            return;
+        }
+        clatd = new Nat464Xlat(netd, this);
+        clatd.start();
+    }
+
+    /** Ensure clat has stopped for this network. */
+    public void maybeStopClat() {
+        if (clatd == null) {
+            return;
+        }
+        clatd.stop();
+        clatd = null;
+    }
+
     public String toString() {
         return "NetworkAgentInfo{ ni{" + networkInfo + "}  " +
                 "network{" + network + "}  nethandle{" + network.getNetworkHandle() + "}  " +
@@ -562,13 +602,13 @@
                 "acceptUnvalidated{" + networkMisc.acceptUnvalidated + "} " +
                 "everCaptivePortalDetected{" + everCaptivePortalDetected + "} " +
                 "lastCaptivePortalDetected{" + lastCaptivePortalDetected + "} " +
+                "clat{" + clatd + "} " +
                 "}";
     }
 
     public String name() {
         return "NetworkAgentInfo [" + networkInfo.getTypeName() + " (" +
-                networkInfo.getSubtypeName() + ") - " +
-                (network == null ? "null" : network.toString()) + "]";
+                networkInfo.getSubtypeName() + ") - " + Objects.toString(network) + "]";
     }
 
     // Enables sorting in descending order of score.
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index d3a9354..7684030 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -20,7 +20,6 @@
 import static android.net.CaptivePortal.APP_RETURN_UNWANTED;
 import static android.net.CaptivePortal.APP_RETURN_WANTED_AS_IS;
 
-import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -229,6 +228,8 @@
     // Delay between reevaluations once a captive portal has been found.
     private static final int CAPTIVE_PORTAL_REEVALUATE_DELAY_MS = 10*60*1000;
 
+    private static final int NUM_VALIDATION_LOG_LINES = 20;
+
     private final Context mContext;
     private final Handler mConnectivityServiceHandler;
     private final NetworkAgentInfo mNetworkAgentInfo;
@@ -236,9 +237,15 @@
     private final int mNetId;
     private final TelephonyManager mTelephonyManager;
     private final WifiManager mWifiManager;
-    private final AlarmManager mAlarmManager;
     private final NetworkRequest mDefaultRequest;
     private final IpConnectivityLog mMetricsLog;
+    private final NetworkMonitorSettings mSettings;
+
+    // Configuration values for captive portal detection probes.
+    private final String mCaptivePortalUserAgent;
+    private final URL mCaptivePortalHttpsUrl;
+    private final URL mCaptivePortalHttpUrl;
+    private final URL[] mCaptivePortalFallbackUrls;
 
     @VisibleForTesting
     protected boolean mIsCaptivePortalCheckEnabled;
@@ -262,40 +269,37 @@
 
     private CustomIntentReceiver mLaunchCaptivePortalAppBroadcastReceiver = null;
 
-    private final LocalLog validationLogs = new LocalLog(20); // 20 lines
+    private final LocalLog validationLogs = new LocalLog(NUM_VALIDATION_LOG_LINES);
 
     private final Stopwatch mEvaluationTimer = new Stopwatch();
 
     // This variable is set before transitioning to the mCaptivePortalState.
     private CaptivePortalProbeResult mLastPortalProbeResult = CaptivePortalProbeResult.FAILED;
 
-    // Configuration values for captive portal detection probes.
-    private final String mCaptivePortalUserAgent;
-    private final URL mCaptivePortalHttpsUrl;
-    private final URL mCaptivePortalHttpUrl;
-    private final URL[] mCaptivePortalFallbackUrls;
     private int mNextFallbackUrlIndex = 0;
 
     public NetworkMonitor(Context context, Handler handler, NetworkAgentInfo networkAgentInfo,
             NetworkRequest defaultRequest) {
-        this(context, handler, networkAgentInfo, defaultRequest, new IpConnectivityLog());
+        this(context, handler, networkAgentInfo, defaultRequest, new IpConnectivityLog(),
+                NetworkMonitorSettings.DEFAULT);
     }
 
     @VisibleForTesting
     protected NetworkMonitor(Context context, Handler handler, NetworkAgentInfo networkAgentInfo,
-            NetworkRequest defaultRequest, IpConnectivityLog logger) {
+            NetworkRequest defaultRequest, IpConnectivityLog logger,
+            NetworkMonitorSettings settings) {
         // Add suffix indicating which NetworkMonitor we're talking about.
         super(TAG + networkAgentInfo.name());
 
         mContext = context;
         mMetricsLog = logger;
         mConnectivityServiceHandler = handler;
+        mSettings = settings;
         mNetworkAgentInfo = networkAgentInfo;
-        mNetwork = new OneAddressPerFamilyNetwork(networkAgentInfo.network);
+        mNetwork = new OneAddressPerFamilyNetwork(networkAgentInfo.network());
         mNetId = mNetwork.netId;
         mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-        mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         mDefaultRequest = defaultRequest;
 
         addState(mDefaultState);
@@ -305,16 +309,12 @@
             addState(mCaptivePortalState, mMaybeNotifyState);
         setInitialState(mDefaultState);
 
-        mIsCaptivePortalCheckEnabled = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.CAPTIVE_PORTAL_MODE, Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT)
-                != Settings.Global.CAPTIVE_PORTAL_MODE_IGNORE;
-        mUseHttps = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.CAPTIVE_PORTAL_USE_HTTPS, 1) == 1;
-
-        mCaptivePortalUserAgent = getCaptivePortalUserAgent(context);
-        mCaptivePortalHttpsUrl = makeURL(getCaptivePortalServerHttpsUrl(context));
-        mCaptivePortalHttpUrl = makeURL(getCaptivePortalServerHttpUrl(context));
-        mCaptivePortalFallbackUrls = makeCaptivePortalFallbackUrls(context);
+        mIsCaptivePortalCheckEnabled = getIsCaptivePortalCheckEnabled();
+        mUseHttps = getUseHttpsValidation();
+        mCaptivePortalUserAgent = getCaptivePortalUserAgent();
+        mCaptivePortalHttpsUrl = makeURL(getCaptivePortalServerHttpsUrl());
+        mCaptivePortalHttpUrl = makeURL(getCaptivePortalServerHttpUrl(settings, context));
+        mCaptivePortalFallbackUrls = makeCaptivePortalFallbackUrls();
 
         start();
     }
@@ -705,19 +705,42 @@
         }
     }
 
-    private static String getCaptivePortalServerHttpsUrl(Context context) {
-        return getSetting(context, Settings.Global.CAPTIVE_PORTAL_HTTPS_URL, DEFAULT_HTTPS_URL);
+    public boolean getIsCaptivePortalCheckEnabled() {
+        String symbol = Settings.Global.CAPTIVE_PORTAL_MODE;
+        int defaultValue = Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT;
+        int mode = mSettings.getSetting(mContext, symbol, defaultValue);
+        return mode != Settings.Global.CAPTIVE_PORTAL_MODE_IGNORE;
     }
 
+    public boolean getUseHttpsValidation() {
+        return mSettings.getSetting(mContext, Settings.Global.CAPTIVE_PORTAL_USE_HTTPS, 1) == 1;
+    }
+
+    public boolean getWifiScansAlwaysAvailableDisabled() {
+        return mSettings.getSetting(mContext, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 0;
+    }
+
+    private String getCaptivePortalServerHttpsUrl() {
+        return mSettings.getSetting(mContext,
+                Settings.Global.CAPTIVE_PORTAL_HTTPS_URL, DEFAULT_HTTPS_URL);
+    }
+
+    // Static for direct access by ConnectivityService
     public static String getCaptivePortalServerHttpUrl(Context context) {
-        return getSetting(context, Settings.Global.CAPTIVE_PORTAL_HTTP_URL, DEFAULT_HTTP_URL);
+        return getCaptivePortalServerHttpUrl(NetworkMonitorSettings.DEFAULT, context);
     }
 
-    private URL[] makeCaptivePortalFallbackUrls(Context context) {
+    public static String getCaptivePortalServerHttpUrl(
+            NetworkMonitorSettings settings, Context context) {
+        return settings.getSetting(
+                context, Settings.Global.CAPTIVE_PORTAL_HTTP_URL, DEFAULT_HTTP_URL);
+    }
+
+    private URL[] makeCaptivePortalFallbackUrls() {
         String separator = ",";
-        String firstUrl = getSetting(context,
+        String firstUrl = mSettings.getSetting(mContext,
                 Settings.Global.CAPTIVE_PORTAL_FALLBACK_URL, DEFAULT_FALLBACK_URL);
-        String joinedUrls = firstUrl + separator + getSetting(context,
+        String joinedUrls = firstUrl + separator + mSettings.getSetting(mContext,
                 Settings.Global.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS, DEFAULT_OTHER_FALLBACK_URLS);
         List<URL> urls = new ArrayList<>();
         for (String s : joinedUrls.split(separator)) {
@@ -733,13 +756,9 @@
         return urls.toArray(new URL[urls.size()]);
     }
 
-    private static String getCaptivePortalUserAgent(Context context) {
-        return getSetting(context, Settings.Global.CAPTIVE_PORTAL_USER_AGENT, DEFAULT_USER_AGENT);
-    }
-
-    private static String getSetting(Context context, String symbol, String defaultValue) {
-        final String value = Settings.Global.getString(context.getContentResolver(), symbol);
-        return value != null ? value : defaultValue;
+    private String getCaptivePortalUserAgent() {
+        return mSettings.getSetting(mContext,
+                Settings.Global.CAPTIVE_PORTAL_USER_AGENT, DEFAULT_USER_AGENT);
     }
 
     private URL nextFallbackUrl() {
@@ -1035,12 +1054,13 @@
      */
     private void sendNetworkConditionsBroadcast(boolean responseReceived, boolean isCaptivePortal,
             long requestTimestampMs, long responseTimestampMs) {
-        if (Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 0) {
+        if (getWifiScansAlwaysAvailableDisabled()) {
             return;
         }
 
-        if (systemReady == false) return;
+        if (!systemReady) {
+            return;
+        }
 
         Intent latencyBroadcast = new Intent(ACTION_NETWORK_CONDITIONS_MEASURED);
         switch (mNetworkAgentInfo.networkInfo.getType()) {
@@ -1109,7 +1129,8 @@
     }
 
     private void logNetworkEvent(int evtype) {
-        mMetricsLog.log(new NetworkEvent(mNetId, evtype));
+        int[] transports = mNetworkAgentInfo.networkCapabilities.getTransportTypes();
+        mMetricsLog.log(mNetId, transports, new NetworkEvent(evtype));
     }
 
     private int networkEventType(ValidationStage s, EvaluationResult r) {
@@ -1130,7 +1151,8 @@
 
     private void maybeLogEvaluationResult(int evtype) {
         if (mEvaluationTimer.isRunning()) {
-            mMetricsLog.log(new NetworkEvent(mNetId, evtype, mEvaluationTimer.stop()));
+            int[] transports = mNetworkAgentInfo.networkCapabilities.getTransportTypes();
+            mMetricsLog.log(mNetId, transports, new NetworkEvent(evtype, mEvaluationTimer.stop()));
             mEvaluationTimer.reset();
         }
     }
@@ -1144,4 +1166,24 @@
         ev.durationMs = durationMs;
         mMetricsLog.log(mNetId, transports, ev);
     }
+
+    @VisibleForTesting
+    public interface NetworkMonitorSettings {
+        int getSetting(Context context, String symbol, int defaultValue);
+        String getSetting(Context context, String symbol, String defaultValue);
+
+        static NetworkMonitorSettings DEFAULT = new DefaultNetworkMonitorSettings();
+    }
+
+    @VisibleForTesting
+    public static class DefaultNetworkMonitorSettings implements NetworkMonitorSettings {
+        public int getSetting(Context context, String symbol, int defaultValue) {
+            return Settings.Global.getInt(context.getContentResolver(), symbol, defaultValue);
+        }
+
+        public String getSetting(Context context, String symbol, String defaultValue) {
+            final String value = Settings.Global.getString(context.getContentResolver(), symbol);
+            return value != null ? value : defaultValue;
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 5583e86..d1bab89 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -28,6 +28,7 @@
 import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
 import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED;
 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
+import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
 import static com.android.server.ConnectivityService.SHORT_ARG;
 
 import android.app.Notification;
@@ -60,6 +61,7 @@
 import android.net.RouteInfo;
 import android.net.util.PrefixUtils;
 import android.net.util.SharedLog;
+import android.net.util.VersionedBroadcastListener;
 import android.net.wifi.WifiManager;
 import android.os.Binder;
 import android.os.Bundle;
@@ -68,12 +70,10 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.Parcel;
+import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.UserHandle;
-import android.os.UserManager;
-import android.os.UserManagerInternal;
-import android.os.UserManagerInternal.UserRestrictionsListener;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
 import android.telephony.TelephonyManager;
@@ -93,7 +93,6 @@
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
-import com.android.server.LocalServices;
 import com.android.server.connectivity.tethering.IControlsTethering;
 import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
 import com.android.server.connectivity.tethering.OffloadController;
@@ -184,6 +183,8 @@
     // TODO: Figure out how to merge this and other downstream-tracking objects
     // into a single coherent structure.
     private final HashSet<TetherInterfaceStateMachine> mForwardedDownstreams;
+    private final VersionedBroadcastListener mCarrierConfigChange;
+    // TODO: Delete SimChangeListener; it's obsolete.
     private final SimChangeListener mSimChange;
 
     private volatile TetheringConfiguration mConfig;
@@ -224,11 +225,26 @@
         mUpstreamNetworkMonitor = new UpstreamNetworkMonitor(
                 mContext, mTetherMasterSM, mLog, TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
         mForwardedDownstreams = new HashSet<>();
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
+        mCarrierConfigChange = new VersionedBroadcastListener(
+                "CarrierConfigChangeListener", mContext, smHandler, filter,
+                (Intent ignored) -> {
+                    mLog.log("OBSERVED carrier config change");
+                    reevaluateSimCardProvisioning();
+                });
+        // TODO: Remove SimChangeListener altogether. For now, we retain it
+        // for logging purposes in case we need to debug something that might
+        // be related to changing signals from ACTION_SIM_STATE_CHANGED to
+        // ACTION_CARRIER_CONFIG_CHANGED.
         mSimChange = new SimChangeListener(
-                mContext, smHandler, () -> reevaluateSimCardProvisioning());
+                mContext, smHandler, () -> {
+                    mLog.log("OBSERVED SIM card change");
+                });
 
         mStateReceiver = new StateReceiver();
-        IntentFilter filter = new IntentFilter();
+        filter = new IntentFilter();
         filter.addAction(UsbManager.ACTION_USB_STATE);
         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
         filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
@@ -241,13 +257,6 @@
         filter.addDataScheme("file");
         mContext.registerReceiver(mStateReceiver, filter, null, smHandler);
 
-        UserManagerInternal userManager = LocalServices.getService(UserManagerInternal.class);
-
-        // this check is useful only for some unit tests; example: ConnectivityServiceTest
-        if (userManager != null) {
-            userManager.addUserRestrictionsListener(new TetheringUserRestrictionListener(this));
-        }
-
         // load device config info
         updateConfiguration();
     }
@@ -364,18 +373,30 @@
             return false;
         }
 
+        if (carrierConfigAffirmsEntitlementCheckNotRequired()) {
+            return false;
+        }
+        return (provisionApp.length == 2);
+    }
+
+    // The logic here is aimed solely at confirming that a CarrierConfig exists
+    // and affirms that entitlement checks are not required.
+    //
+    // TODO: find a better way to express this, or alter the checking process
+    // entirely so that this is more intuitive.
+    private boolean carrierConfigAffirmsEntitlementCheckNotRequired() {
         // Check carrier config for entitlement checks
         final CarrierConfigManager configManager = (CarrierConfigManager) mContext
              .getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        if (configManager != null && configManager.getConfig() != null) {
-            // we do have a CarrierConfigManager and it has a config.
-            boolean isEntitlementCheckRequired = configManager.getConfig().getBoolean(
-                    CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL);
-            if (!isEntitlementCheckRequired) {
-                return false;
-            }
-        }
-        return (provisionApp.length == 2);
+        if (configManager == null) return false;
+
+        final PersistableBundle carrierConfig = configManager.getConfig();
+        if (carrierConfig == null) return false;
+
+        // A CarrierConfigManager was found and it has a config.
+        final boolean isEntitlementCheckRequired = carrierConfig.getBoolean(
+                CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL);
+        return !isEntitlementCheckRequired;
     }
 
     // Used by the SIM card change observation code.
@@ -722,11 +743,6 @@
     }
 
     private void showTetheredNotification(int id) {
-        showTetheredNotification(id, true);
-    }
-
-    @VisibleForTesting
-    protected void showTetheredNotification(int id, boolean tetheringOn) {
         NotificationManager notificationManager =
                 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
         if (notificationManager == null) {
@@ -763,16 +779,9 @@
                 null, UserHandle.CURRENT);
 
         Resources r = Resources.getSystem();
-        final CharSequence title;
-        final CharSequence message;
-
-        if (tetheringOn) {
-            title = r.getText(com.android.internal.R.string.tethered_notification_title);
-            message = r.getText(com.android.internal.R.string.tethered_notification_message);
-        } else {
-            title = r.getText(com.android.internal.R.string.disable_tether_notification_title);
-            message = r.getText(com.android.internal.R.string.disable_tether_notification_message);
-        }
+        CharSequence title = r.getText(com.android.internal.R.string.tethered_notification_title);
+        CharSequence message = r.getText(com.android.internal.R.string.
+                tethered_notification_message);
 
         if (mTetheredNotificationBuilder == null) {
             mTetheredNotificationBuilder =
@@ -794,8 +803,7 @@
                 mTetheredNotificationBuilder.buildInto(new Notification()), UserHandle.ALL);
     }
 
-    @VisibleForTesting
-    protected void clearTetheredNotification() {
+    private void clearTetheredNotification() {
         NotificationManager notificationManager =
             (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
         if (notificationManager != null && mLastNotificationId != 0) {
@@ -818,6 +826,7 @@
             } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
                 handleWifiApAction(intent);
             } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
+                mLog.log("OBSERVED configuration changed");
                 updateConfiguration();
             }
         }
@@ -912,38 +921,6 @@
         }
     }
 
-    @VisibleForTesting
-    protected static class TetheringUserRestrictionListener implements UserRestrictionsListener {
-        private final Tethering mWrapper;
-
-        public TetheringUserRestrictionListener(Tethering wrapper) {
-            mWrapper = wrapper;
-        }
-
-        public void onUserRestrictionsChanged(int userId,
-                                              Bundle newRestrictions,
-                                              Bundle prevRestrictions) {
-            final boolean newlyDisallowed =
-                    newRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
-            final boolean previouslyDisallowed =
-                    prevRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
-            final boolean tetheringDisallowedChanged = (newlyDisallowed != previouslyDisallowed);
-
-            if (!tetheringDisallowedChanged) {
-                return;
-            }
-
-            mWrapper.clearTetheredNotification();
-            final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0);
-
-            if (newlyDisallowed && isTetheringActiveOnDevice) {
-                mWrapper.showTetheredNotification(
-                        com.android.internal.R.drawable.stat_sys_tether_general, false);
-                mWrapper.untetherAll();
-            }
-        }
-    }
-
     private void disableWifiIpServingLocked(String ifname, int apState) {
         mLog.log("Canceling WiFi tethering request - AP_STATE=" + apState);
 
@@ -1192,6 +1169,7 @@
 
     private void reevaluateSimCardProvisioning() {
         if (!hasMobileHotspotProvisionApp()) return;
+        if (carrierConfigAffirmsEntitlementCheckNotRequired()) return;
 
         ArrayList<Integer> tethered = new ArrayList<>();
         synchronized (mPublicSync) {
@@ -1371,6 +1349,7 @@
                     sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
                 }
             }
+            mUpstreamNetworkMonitor.setCurrentUpstream((ns != null) ? ns.network : null);
             setUpstreamNetwork(ns);
         }
 
@@ -1558,6 +1537,7 @@
                     return;
                 }
 
+                mCarrierConfigChange.startListening();
                 mSimChange.startListening();
                 mUpstreamNetworkMonitor.start();
 
@@ -1575,6 +1555,7 @@
                 mOffload.stop();
                 mUpstreamNetworkMonitor.stop();
                 mSimChange.stopListening();
+                mCarrierConfigChange.stopListening();
                 notifyDownstreamsOfNewUpstreamIface(null);
                 handleNewUpstreamNetworkState(null);
             }
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 27968a9..7715727 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -18,6 +18,8 @@
 
 import static android.Manifest.permission.BIND_VPN_SERVICE;
 import static android.net.ConnectivityManager.NETID_UNSET;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
 import static android.net.RouteInfo.RTN_THROW;
 import static android.net.RouteInfo.RTN_UNREACHABLE;
 
@@ -36,6 +38,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
@@ -56,7 +59,10 @@
 import android.net.RouteInfo;
 import android.net.UidRange;
 import android.net.Uri;
+import android.net.VpnService;
 import android.os.Binder;
+import android.os.Build.VERSION_CODES;
+import android.os.Bundle;
 import android.os.FileUtils;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
@@ -86,6 +92,8 @@
 import com.android.internal.net.VpnInfo;
 import com.android.internal.net.VpnProfile;
 import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.util.ArrayUtils;
+import com.android.server.ConnectivityService;
 import com.android.server.DeviceIdleController;
 import com.android.server.LocalServices;
 import com.android.server.net.BaseNetworkObserver;
@@ -241,10 +249,10 @@
         }
 
         mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_VPN, 0, NETWORKTYPE, "");
-        // TODO: Copy metered attribute and bandwidths from physical transport, b/16207332
         mNetworkCapabilities = new NetworkCapabilities();
         mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_VPN);
         mNetworkCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
+        updateCapabilities();
 
         loadAlwaysOnPackage();
     }
@@ -271,6 +279,62 @@
         updateAlwaysOnNotification(detailedState);
     }
 
+    public void updateCapabilities() {
+        final Network[] underlyingNetworks = (mConfig != null) ? mConfig.underlyingNetworks : null;
+        updateCapabilities(mContext.getSystemService(ConnectivityManager.class), underlyingNetworks,
+                mNetworkCapabilities);
+
+        if (mNetworkAgent != null) {
+            mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
+        }
+    }
+
+    @VisibleForTesting
+    public static void updateCapabilities(ConnectivityManager cm, Network[] underlyingNetworks,
+            NetworkCapabilities caps) {
+        int[] transportTypes = new int[] { NetworkCapabilities.TRANSPORT_VPN };
+        int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
+        int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
+        boolean metered = false;
+        boolean roaming = false;
+
+        if (ArrayUtils.isEmpty(underlyingNetworks)) {
+            // No idea what the underlying networks are; assume sane defaults
+            metered = true;
+            roaming = false;
+        } else {
+            for (Network underlying : underlyingNetworks) {
+                final NetworkCapabilities underlyingCaps = cm.getNetworkCapabilities(underlying);
+                for (int underlyingType : underlyingCaps.getTransportTypes()) {
+                    transportTypes = ArrayUtils.appendInt(transportTypes, underlyingType);
+                }
+
+                // When we have multiple networks, we have to assume the
+                // worst-case link speed and restrictions.
+                downKbps = NetworkCapabilities.minBandwidth(downKbps,
+                        underlyingCaps.getLinkDownstreamBandwidthKbps());
+                upKbps = NetworkCapabilities.minBandwidth(upKbps,
+                        underlyingCaps.getLinkUpstreamBandwidthKbps());
+                metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED);
+                roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING);
+            }
+        }
+
+        caps.setTransportTypes(transportTypes);
+        caps.setLinkDownstreamBandwidthKbps(downKbps);
+        caps.setLinkUpstreamBandwidthKbps(upKbps);
+        if (metered) {
+            caps.removeCapability(NET_CAPABILITY_NOT_METERED);
+        } else {
+            caps.addCapability(NET_CAPABILITY_NOT_METERED);
+        }
+        if (roaming) {
+            caps.removeCapability(NET_CAPABILITY_NOT_ROAMING);
+        } else {
+            caps.addCapability(NET_CAPABILITY_NOT_ROAMING);
+        }
+    }
+
     /**
      * Chooses whether to force all connections to go though VPN.
      *
@@ -296,6 +360,56 @@
     }
 
     /**
+     * Checks if a VPN app supports always-on mode.
+     *
+     * In order to support the always-on feature, an app has to
+     * <ul>
+     *     <li>target {@link VERSION_CODES#N API 24} or above, and
+     *     <li>not opt out through the {@link VpnService#SERVICE_META_DATA_SUPPORTS_ALWAYS_ON}
+     *         meta-data field.
+     * </ul>
+     *
+     * @param packageName the canonical package name of the VPN app
+     * @return {@code true} if and only if the VPN app exists and supports always-on mode
+     */
+    public boolean isAlwaysOnPackageSupported(String packageName) {
+        enforceSettingsPermission();
+
+        if (packageName == null) {
+            return false;
+        }
+
+        PackageManager pm = mContext.getPackageManager();
+        ApplicationInfo appInfo = null;
+        try {
+            appInfo = pm.getApplicationInfoAsUser(packageName, 0 /*flags*/, mUserHandle);
+        } catch (NameNotFoundException unused) {
+            Log.w(TAG, "Can't find \"" + packageName + "\" when checking always-on support");
+        }
+        if (appInfo == null || appInfo.targetSdkVersion < VERSION_CODES.N) {
+            return false;
+        }
+
+        final Intent intent = new Intent(VpnConfig.SERVICE_INTERFACE);
+        intent.setPackage(packageName);
+        List<ResolveInfo> services =
+                pm.queryIntentServicesAsUser(intent, PackageManager.GET_META_DATA, mUserHandle);
+        if (services == null || services.size() == 0) {
+            return false;
+        }
+
+        for (ResolveInfo rInfo : services) {
+            final Bundle metaData = rInfo.serviceInfo.metaData;
+            if (metaData != null &&
+                    !metaData.getBoolean(VpnService.SERVICE_META_DATA_SUPPORTS_ALWAYS_ON, true)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
      * Configures an always-on VPN connection through a specific application.
      * This connection is automatically granted and persisted after a reboot.
      *
@@ -303,6 +417,10 @@
      *    manifest guarded by {@link android.Manifest.permission.BIND_VPN_SERVICE},
      *    otherwise the call will fail.
      *
+     * <p>Note that this method does not check if the VPN app supports always-on mode. The check is
+     *    delayed to {@link #startAlwaysOnVpn()}, which is always called immediately after this
+     *    method in {@link android.net.IConnectivityManager#setAlwaysOnVpnPackage}.
+     *
      * @param packageName the package to designate as always-on VPN supplier.
      * @param lockdown whether to prevent traffic outside of a VPN, for example while connecting.
      * @return {@code true} if the package has been set as always-on, {@code false} otherwise.
@@ -443,6 +561,11 @@
             if (alwaysOnPackage == null) {
                 return true;
             }
+            // Remove always-on VPN if it's not supported.
+            if (!isAlwaysOnPackageSupported(alwaysOnPackage)) {
+                setAlwaysOnPackage(null, false);
+                return false;
+            }
             // Skip if the service is already established. This isn't bulletproof: it's not bound
             // until after establish(), so if it's mid-setup onStartCommand will be sent twice,
             // which may restart the connection.
@@ -1219,6 +1342,11 @@
                 "Unauthorized Caller");
     }
 
+    private void enforceSettingsPermission() {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.NETWORK_SETTINGS,
+                "Unauthorized Caller");
+    }
+
     private class Connection implements ServiceConnection {
         private IBinder mService;
 
@@ -1276,6 +1404,7 @@
                 }
             }
         }
+        updateCapabilities();
         return true;
     }
 
@@ -1348,7 +1477,11 @@
                 notificationManager.cancelAsUser(TAG, SystemMessage.NOTE_VPN_DISCONNECTED, user);
                 return;
             }
-            final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
+            final Intent intent = new Intent();
+            intent.setComponent(ComponentName.unflattenFromString(mContext.getString(
+                    R.string.config_customVpnAlwaysOnDisconnectedDialogComponent)));
+            intent.putExtra("lockdown", mLockdown);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             final PendingIntent configIntent = mSystemServices.pendingIntentGetActivityAsUser(
                     intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT, user);
             final Notification.Builder builder =
diff --git a/services/core/java/com/android/server/connectivity/tethering/OffloadController.java b/services/core/java/com/android/server/connectivity/tethering/OffloadController.java
index 6d5c428..cff216c 100644
--- a/services/core/java/com/android/server/connectivity/tethering/OffloadController.java
+++ b/services/core/java/com/android/server/connectivity/tethering/OffloadController.java
@@ -30,6 +30,10 @@
 import android.net.LinkProperties;
 import android.net.NetworkStats;
 import android.net.RouteInfo;
+import android.net.netlink.ConntrackMessage;
+import android.net.netlink.NetlinkConstants;
+import android.net.netlink.NetlinkSocket;
+import android.net.util.IpUtils;
 import android.net.util.SharedLog;
 import android.os.Handler;
 import android.os.Looper;
@@ -37,15 +41,18 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.provider.Settings;
+import android.system.ErrnoException;
+import android.system.OsConstants;
 import android.text.TextUtils;
-import com.android.server.connectivity.tethering.OffloadHardwareInterface.ForwardedStats;
 
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.connectivity.tethering.OffloadHardwareInterface.ForwardedStats;
 
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -63,6 +70,11 @@
  */
 public class OffloadController {
     private static final String TAG = OffloadController.class.getSimpleName();
+    private static final boolean DBG = false;
+    private static final String ANYIP = "0.0.0.0";
+    private static final ForwardedStats EMPTY_STATS = new ForwardedStats();
+
+    private static enum UpdateType { IF_NEEDED, FORCE };
 
     private final Handler mHandler;
     private final OffloadHardwareInterface mHwInterface;
@@ -94,6 +106,9 @@
     // includes upstream interfaces that have a quota set.
     private HashMap<String, Long> mInterfaceQuotas = new HashMap<>();
 
+    private int mNatUpdateCallbacksReceived;
+    private int mNatUpdateNetlinkErrors;
+
     public OffloadController(Handler h, OffloadHardwareInterface hwi,
             ContentResolver contentResolver, INetworkManagementService nms, SharedLog log) {
         mHandler = h;
@@ -113,12 +128,12 @@
         }
     }
 
-    public void start() {
-        if (started()) return;
+    public boolean start() {
+        if (started()) return true;
 
         if (isOffloadDisabled()) {
             mLog.i("tethering offload disabled");
-            return;
+            return false;
         }
 
         if (!mConfigInitialized) {
@@ -126,11 +141,14 @@
             if (!mConfigInitialized) {
                 mLog.i("tethering offload config not supported");
                 stop();
-                return;
+                return false;
             }
         }
 
         mControlInitialized = mHwInterface.initOffloadControl(
+                // OffloadHardwareInterface guarantees that these callback
+                // methods are called on the handler passed to it, which is the
+                // same as mHandler, as coordinated by the setup in Tethering.
                 new OffloadHardwareInterface.ControlCallback() {
                     @Override
                     public void onStarted() {
@@ -148,6 +166,14 @@
                     public void onStoppedUnsupported() {
                         if (!started()) return;
                         mLog.log("onStoppedUnsupported");
+                        // Poll for statistics and trigger a sweep of tethering
+                        // stats by observers. This might not succeed, but it's
+                        // worth trying anyway. We need to do this because from
+                        // this point on we continue with software forwarding,
+                        // and we need to synchronize stats and limits between
+                        // software and hardware forwarding.
+                        updateStatsForAllUpstreams();
+                        forceTetherStatsPoll();
                     }
 
                     @Override
@@ -155,11 +181,15 @@
                         if (!started()) return;
                         mLog.log("onSupportAvailable");
 
-                        // [1] Poll for statistics and notify NetworkStats
-                        // [2] (Re)Push all state:
-                        //     [a] push local prefixes
-                        //     [b] push downstreams
-                        //     [c] push upstream parameters
+                        // [1] Poll for statistics and trigger a sweep of stats
+                        // by observers. We need to do this to ensure that any
+                        // limits set take into account any software tethering
+                        // traffic that has been happening in the meantime.
+                        updateStatsForAllUpstreams();
+                        forceTetherStatsPoll();
+                        // [2] (Re)Push all state.
+                        computeAndPushLocalPrefixes(UpdateType.FORCE);
+                        pushAllDownstreamState();
                         pushUpstreamParameters(null);
                     }
 
@@ -181,12 +211,7 @@
                         // The stats for the previous upstream were already updated on this thread
                         // just after the upstream was changed, so they are also up-to-date.
                         updateStatsForCurrentUpstream();
-
-                        try {
-                            mNms.tetherLimitReached(mStatsProvider);
-                        } catch (RemoteException e) {
-                            mLog.e("Cannot report data limit reached: " + e);
-                        }
+                        forceTetherStatsPoll();
                     }
 
                     @Override
@@ -194,15 +219,20 @@
                                                    String srcAddr, int srcPort,
                                                    String dstAddr, int dstPort) {
                         if (!started()) return;
-                        mLog.log(String.format("NAT timeout update: %s (%s,%s) -> (%s,%s)",
-                                proto, srcAddr, srcPort, dstAddr, dstPort));
+                        updateNatTimeout(proto, srcAddr, srcPort, dstAddr, dstPort);
                     }
                 });
-        if (!mControlInitialized) {
+
+        final boolean isStarted = started();
+        if (!isStarted) {
             mLog.i("tethering offload control not supported");
             stop();
+        } else {
+            mLog.log("tethering offload started");
+            mNatUpdateCallbacksReceived = 0;
+            mNatUpdateNetlinkErrors = 0;
         }
-        mLog.log("tethering offload started");
+        return isStarted;
     }
 
     public void stop() {
@@ -218,6 +248,10 @@
         if (wasStarted) mLog.log("tethering offload stopped");
     }
 
+    private boolean started() {
+        return mConfigInitialized && mControlInitialized;
+    }
+
     private class OffloadTetheringStatsProvider extends ITetheringStatsProvider.Stub {
         @Override
         public NetworkStats getTetherStats(int how) {
@@ -288,7 +322,7 @@
     }
 
     private boolean maybeUpdateDataLimit(String iface) {
-        // setDataLimit may only be called while offload is occuring on this upstream.
+        // setDataLimit may only be called while offload is occurring on this upstream.
         if (!started() || !TextUtils.equals(iface, currentUpstreamInterface())) {
             return true;
         }
@@ -305,27 +339,47 @@
         maybeUpdateStats(currentUpstreamInterface());
     }
 
+    private void updateStatsForAllUpstreams() {
+        // In practice, there should only ever be a single digit number of
+        // upstream interfaces over the lifetime of an active tethering session.
+        // Roughly speaking, imagine a very ambitious one or two of each of the
+        // following interface types: [ "rmnet_data", "wlan", "eth", "rndis" ].
+        for (Map.Entry<String, ForwardedStats> kv : mForwardedStats.entrySet()) {
+            maybeUpdateStats(kv.getKey());
+        }
+    }
+
+    private void forceTetherStatsPoll() {
+        try {
+            mNms.tetherLimitReached(mStatsProvider);
+        } catch (RemoteException e) {
+            mLog.e("Cannot report data limit reached: " + e);
+        }
+    }
+
     public void setUpstreamLinkProperties(LinkProperties lp) {
         if (!started() || Objects.equals(mUpstreamLinkProperties, lp)) return;
 
-        String prevUpstream = (mUpstreamLinkProperties != null) ?
-                mUpstreamLinkProperties.getInterfaceName() : null;
+        final String prevUpstream = currentUpstreamInterface();
 
         mUpstreamLinkProperties = (lp != null) ? new LinkProperties(lp) : null;
+        // Make sure we record this interface in the ForwardedStats map.
+        final String iface = currentUpstreamInterface();
+        if (!TextUtils.isEmpty(iface)) mForwardedStats.putIfAbsent(iface, EMPTY_STATS);
 
         // TODO: examine return code and decide what to do if programming
         // upstream parameters fails (probably just wait for a subsequent
         // onOffloadEvent() callback to tell us offload is available again and
         // then reapply all state).
-        computeAndPushLocalPrefixes();
+        computeAndPushLocalPrefixes(UpdateType.IF_NEEDED);
         pushUpstreamParameters(prevUpstream);
     }
 
     public void setLocalPrefixes(Set<IpPrefix> localPrefixes) {
-        if (!started()) return;
-
         mExemptPrefixes = localPrefixes;
-        computeAndPushLocalPrefixes();
+
+        if (!started()) return;
+        computeAndPushLocalPrefixes(UpdateType.IF_NEEDED);
     }
 
     public void notifyDownstreamLinkProperties(LinkProperties lp) {
@@ -334,27 +388,38 @@
         if (Objects.equals(oldLp, lp)) return;
 
         if (!started()) return;
+        pushDownstreamState(oldLp, lp);
+    }
 
-        final List<RouteInfo> oldRoutes = (oldLp != null) ? oldLp.getRoutes() : new ArrayList<>();
-        final List<RouteInfo> newRoutes = lp.getRoutes();
+    private void pushDownstreamState(LinkProperties oldLp, LinkProperties newLp) {
+        final String ifname = newLp.getInterfaceName();
+        final List<RouteInfo> oldRoutes =
+                (oldLp != null) ? oldLp.getRoutes() : Collections.EMPTY_LIST;
+        final List<RouteInfo> newRoutes = newLp.getRoutes();
 
         // For each old route, if not in new routes: remove.
-        for (RouteInfo oldRoute : oldRoutes) {
-            if (shouldIgnoreDownstreamRoute(oldRoute)) continue;
-            if (!newRoutes.contains(oldRoute)) {
-                mHwInterface.removeDownstreamPrefix(ifname, oldRoute.getDestination().toString());
+        for (RouteInfo ri : oldRoutes) {
+            if (shouldIgnoreDownstreamRoute(ri)) continue;
+            if (!newRoutes.contains(ri)) {
+                mHwInterface.removeDownstreamPrefix(ifname, ri.getDestination().toString());
             }
         }
 
         // For each new route, if not in old routes: add.
-        for (RouteInfo newRoute : newRoutes) {
-            if (shouldIgnoreDownstreamRoute(newRoute)) continue;
-            if (!oldRoutes.contains(newRoute)) {
-                mHwInterface.addDownstreamPrefix(ifname, newRoute.getDestination().toString());
+        for (RouteInfo ri : newRoutes) {
+            if (shouldIgnoreDownstreamRoute(ri)) continue;
+            if (!oldRoutes.contains(ri)) {
+                mHwInterface.addDownstreamPrefix(ifname, ri.getDestination().toString());
             }
         }
     }
 
+    private void pushAllDownstreamState() {
+        for (LinkProperties lp : mDownstreams.values()) {
+            pushDownstreamState(null, lp);
+        }
+    }
+
     public void removeDownstreamInterface(String ifname) {
         final LinkProperties lp = mDownstreams.remove(ifname);
         if (lp == null) return;
@@ -373,21 +438,21 @@
                 mContentResolver, TETHER_OFFLOAD_DISABLED, defaultDisposition) != 0);
     }
 
-    private boolean started() {
-        return mConfigInitialized && mControlInitialized;
-    }
-
     private boolean pushUpstreamParameters(String prevUpstream) {
-        if (mUpstreamLinkProperties == null) {
+        final String iface = currentUpstreamInterface();
+
+        if (TextUtils.isEmpty(iface)) {
+            final boolean rval = mHwInterface.setUpstreamParameters("", ANYIP, ANYIP, null);
+            // Update stats after we've told the hardware to stop forwarding so
+            // we don't miss packets.
             maybeUpdateStats(prevUpstream);
-            return mHwInterface.setUpstreamParameters(null, null, null, null);
+            return rval;
         }
 
         // A stacked interface cannot be an upstream for hardware offload.
         // Consequently, we examine only the primary interface name, look at
         // getAddresses() rather than getAllAddresses(), and check getRoutes()
         // rather than getAllRoutes().
-        final String iface = mUpstreamLinkProperties.getInterfaceName();
         final ArrayList<String> v6gateways = new ArrayList<>();
         String v4addr = null;
         String v4gateway = null;
@@ -433,10 +498,11 @@
         return success;
     }
 
-    private boolean computeAndPushLocalPrefixes() {
+    private boolean computeAndPushLocalPrefixes(UpdateType how) {
+        final boolean force = (how == UpdateType.FORCE);
         final Set<String> localPrefixStrs = computeLocalPrefixStrings(
                 mExemptPrefixes, mUpstreamLinkProperties);
-        if (mLastLocalPrefixStrs.equals(localPrefixStrs)) return true;
+        if (!force && mLastLocalPrefixStrs.equals(localPrefixStrs)) return true;
 
         mLastLocalPrefixStrs = localPrefixStrs;
         return mHwInterface.setLocalPrefixes(new ArrayList<>(localPrefixStrs));
@@ -483,10 +549,114 @@
             pw.println("Offload disabled");
             return;
         }
-        pw.println("Offload HALs " + (started() ? "started" : "not started"));
+        final boolean isStarted = started();
+        pw.println("Offload HALs " + (isStarted ? "started" : "not started"));
         LinkProperties lp = mUpstreamLinkProperties;
         String upstream = (lp != null) ? lp.getInterfaceName() : null;
         pw.println("Current upstream: " + upstream);
         pw.println("Exempt prefixes: " + mLastLocalPrefixStrs);
+        pw.println("NAT timeout update callbacks received during the "
+                + (isStarted ? "current" : "last")
+                + " offload session: "
+                + mNatUpdateCallbacksReceived);
+        pw.println("NAT timeout update netlink errors during the "
+                + (isStarted ? "current" : "last")
+                + " offload session: "
+                + mNatUpdateNetlinkErrors);
+    }
+
+    private void updateNatTimeout(
+            int proto, String srcAddr, int srcPort, String dstAddr, int dstPort) {
+        final String protoName = protoNameFor(proto);
+        if (protoName == null) {
+            mLog.e("Unknown NAT update callback protocol: " + proto);
+            return;
+        }
+
+        final Inet4Address src = parseIPv4Address(srcAddr);
+        if (src == null) {
+            mLog.e("Failed to parse IPv4 address: " + srcAddr);
+            return;
+        }
+
+        if (!IpUtils.isValidUdpOrTcpPort(srcPort)) {
+            mLog.e("Invalid src port: " + srcPort);
+            return;
+        }
+
+        final Inet4Address dst = parseIPv4Address(dstAddr);
+        if (dst == null) {
+            mLog.e("Failed to parse IPv4 address: " + dstAddr);
+            return;
+        }
+
+        if (!IpUtils.isValidUdpOrTcpPort(dstPort)) {
+            mLog.e("Invalid dst port: " + dstPort);
+            return;
+        }
+
+        mNatUpdateCallbacksReceived++;
+        final String natDescription = String.format("%s (%s, %s) -> (%s, %s)",
+                protoName, srcAddr, srcPort, dstAddr, dstPort);
+        if (DBG) {
+            mLog.log("NAT timeout update: " + natDescription);
+        }
+
+        final int timeoutSec = connectionTimeoutUpdateSecondsFor(proto);
+        final byte[] msg = ConntrackMessage.newIPv4TimeoutUpdateRequest(
+                proto, src, srcPort, dst, dstPort, timeoutSec);
+
+        try {
+            NetlinkSocket.sendOneShotKernelMessage(OsConstants.NETLINK_NETFILTER, msg);
+        } catch (ErrnoException e) {
+            mNatUpdateNetlinkErrors++;
+            mLog.e("Error updating NAT conntrack entry >" + natDescription + "<: " + e
+                    + ", msg: " + NetlinkConstants.hexify(msg));
+            mLog.log("NAT timeout update callbacks received: " + mNatUpdateCallbacksReceived);
+            mLog.log("NAT timeout update netlink errors: " + mNatUpdateNetlinkErrors);
+        }
+    }
+
+    private static Inet4Address parseIPv4Address(String addrString) {
+        try {
+            final InetAddress ip = InetAddress.parseNumericAddress(addrString);
+            // TODO: Consider other sanitization steps here, including perhaps:
+            //           not eql to 0.0.0.0
+            //           not within 169.254.0.0/16
+            //           not within ::ffff:0.0.0.0/96
+            //           not within ::/96
+            // et cetera.
+            if (ip instanceof Inet4Address) {
+                return (Inet4Address) ip;
+            }
+        } catch (IllegalArgumentException iae) {}
+        return null;
+    }
+
+    private static String protoNameFor(int proto) {
+        // OsConstants values are not constant expressions; no switch statement.
+        if (proto == OsConstants.IPPROTO_UDP) {
+            return "UDP";
+        } else if (proto == OsConstants.IPPROTO_TCP) {
+            return "TCP";
+        }
+        return null;
+    }
+
+    private static int connectionTimeoutUpdateSecondsFor(int proto) {
+        // TODO: Replace this with more thoughtful work, perhaps reading from
+        // and maybe writing to any required
+        //
+        //     /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_*
+        //     /proc/sys/net/netfilter/nf_conntrack_udp_timeout{,_stream}
+        //
+        // entries.  TBD.
+        if (proto == OsConstants.IPPROTO_TCP) {
+            // Cf. /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
+            return 432000;
+        } else {
+            // Cf. /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream
+            return 180;
+        }
     }
 }
diff --git a/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java b/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
index 865a989..f8c6582 100644
--- a/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
+++ b/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
@@ -21,10 +21,12 @@
 import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
 import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback;
 import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
+import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
 import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.net.util.SharedLog;
+import android.system.OsConstants;
 
 import java.util.ArrayList;
 
@@ -40,7 +42,7 @@
     // Change this value to control whether tether offload is enabled or
     // disabled by default in the absence of an explicit Settings value.
     // See accompanying unittest to distinguish 0 from non-0 values.
-    private static final int DEFAULT_TETHER_OFFLOAD_DISABLED = 0;
+    private static final int DEFAULT_TETHER_OFFLOAD_DISABLED = 1;
     private static final String NO_INTERFACE_NAME = "";
     private static final String NO_IPV4_ADDRESS = "";
     private static final String NO_IPV4_GATEWAY = "";
@@ -107,6 +109,10 @@
                 mLog.e("tethering offload control not supported: " + e);
                 return false;
             }
+            if (mOffloadControl == null) {
+                mLog.e("tethering IOffloadControl.getService() returned null");
+                return false;
+            }
         }
 
         final String logmsg = String.format("initOffloadControl(%s)",
@@ -327,13 +333,24 @@
         public void updateTimeout(NatTimeoutUpdate params) {
             handler.post(() -> {
                     controlCb.onNatTimeoutUpdate(
-                        params.proto,
+                        networkProtocolToOsConstant(params.proto),
                         params.src.addr, uint16(params.src.port),
                         params.dst.addr, uint16(params.dst.port));
             });
         }
     }
 
+    private static int networkProtocolToOsConstant(int proto) {
+        switch (proto) {
+            case NetworkProtocol.TCP: return OsConstants.IPPROTO_TCP;
+            case NetworkProtocol.UDP: return OsConstants.IPPROTO_UDP;
+            default:
+                // The caller checks this value and will log an error. Just make
+                // sure it won't collide with valid OsContants.IPPROTO_* values.
+                return -Math.abs(proto);
+        }
+    }
+
     private static class CbResults {
         boolean success;
         String errMsg;
diff --git a/services/core/java/com/android/server/connectivity/tethering/SimChangeListener.java b/services/core/java/com/android/server/connectivity/tethering/SimChangeListener.java
index 3e60f9f..33c9355 100644
--- a/services/core/java/com/android/server/connectivity/tethering/SimChangeListener.java
+++ b/services/core/java/com/android/server/connectivity/tethering/SimChangeListener.java
@@ -23,12 +23,15 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.util.VersionedBroadcastListener;
+import android.net.util.VersionedBroadcastListener.IntentCallback;
 import android.os.Handler;
 import android.util.Log;
 
 import com.android.internal.telephony.TelephonyIntents;
 
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
 
 
 /**
@@ -37,88 +40,40 @@
  *
  * @hide
  */
-public class SimChangeListener {
+public class SimChangeListener extends VersionedBroadcastListener {
     private static final String TAG = SimChangeListener.class.getSimpleName();
     private static final boolean DBG = false;
 
-    private final Context mContext;
-    private final Handler mTarget;
-    private final AtomicInteger mSimBcastGenerationNumber;
-    private final Runnable mCallback;
-    private BroadcastReceiver mBroadcastReceiver;
-
     public SimChangeListener(Context ctx, Handler handler, Runnable onSimCardLoadedCallback) {
-        mContext = ctx;
-        mTarget = handler;
-        mCallback = onSimCardLoadedCallback;
-        mSimBcastGenerationNumber = new AtomicInteger(0);
+        super(TAG, ctx, handler, makeIntentFilter(), makeCallback(onSimCardLoadedCallback));
     }
 
-    public int generationNumber() {
-        return mSimBcastGenerationNumber.get();
-    }
-
-    public void startListening() {
-        if (DBG) Log.d(TAG, "startListening for SIM changes");
-
-        if (mBroadcastReceiver != null) return;
-
-        mBroadcastReceiver = new SimChangeBroadcastReceiver(
-                mSimBcastGenerationNumber.incrementAndGet());
+    private static IntentFilter makeIntentFilter() {
         final IntentFilter filter = new IntentFilter();
         filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
-
-        mContext.registerReceiver(mBroadcastReceiver, filter, null, mTarget);
+        return filter;
     }
 
-    public void stopListening() {
-        if (DBG) Log.d(TAG, "stopListening for SIM changes");
+    private static Consumer<Intent> makeCallback(Runnable onSimCardLoadedCallback) {
+        return new Consumer<Intent>() {
+            private boolean mSimNotLoadedSeen = false;
 
-        if (mBroadcastReceiver == null) return;
+            @Override
+            public void accept(Intent intent) {
+                final String state = intent.getStringExtra(INTENT_KEY_ICC_STATE);
+                Log.d(TAG, "got Sim changed to state " + state + ", mSimNotLoadedSeen=" +
+                        mSimNotLoadedSeen);
 
-        mSimBcastGenerationNumber.incrementAndGet();
-        mContext.unregisterReceiver(mBroadcastReceiver);
-        mBroadcastReceiver = null;
-    }
+                if (!INTENT_VALUE_ICC_LOADED.equals(state)) {
+                    mSimNotLoadedSeen = true;
+                    return;
+                }
 
-    private boolean isSimCardLoaded(String state) {
-        return INTENT_VALUE_ICC_LOADED.equals(state);
-    }
-
-    private class SimChangeBroadcastReceiver extends BroadcastReceiver {
-        // used to verify this receiver is still current
-        final private int mGenerationNumber;
-
-        // used to check the sim state transition from non-loaded to loaded
-        private boolean mSimNotLoadedSeen = false;
-
-        public SimChangeBroadcastReceiver(int generationNumber) {
-            mGenerationNumber = generationNumber;
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final int currentGenerationNumber = mSimBcastGenerationNumber.get();
-
-            if (DBG) {
-                Log.d(TAG, "simchange mGenerationNumber=" + mGenerationNumber +
-                        ", current generationNumber=" + currentGenerationNumber);
+                if (mSimNotLoadedSeen) {
+                    mSimNotLoadedSeen = false;
+                    onSimCardLoadedCallback.run();
+                }
             }
-            if (mGenerationNumber != currentGenerationNumber) return;
-
-            final String state = intent.getStringExtra(INTENT_KEY_ICC_STATE);
-            Log.d(TAG, "got Sim changed to state " + state + ", mSimNotLoadedSeen=" +
-                    mSimNotLoadedSeen);
-
-            if (!isSimCardLoaded(state)) {
-                mSimNotLoadedSeen = true;
-                return;
-            }
-
-            if (mSimNotLoadedSeen) {
-                mSimNotLoadedSeen = false;
-                mCallback.run();
-            }
-        }
+        };
     }
 }
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
index 57d2502..17adb1a 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -27,6 +27,7 @@
 import android.net.LinkProperties;
 import android.net.NetworkUtils;
 import android.net.RouteInfo;
+import android.net.ip.InterfaceController;
 import android.net.ip.RouterAdvertisementDaemon;
 import android.net.ip.RouterAdvertisementDaemon.RaParams;
 import android.net.util.NetdService;
@@ -107,8 +108,10 @@
 
     private final SharedLog mLog;
     private final INetworkManagementService mNMService;
+    private final INetd mNetd;
     private final INetworkStatsService mStatsService;
     private final IControlsTethering mTetherController;
+    private final InterfaceController mInterfaceCtrl;
 
     private final String mIfaceName;
     private final int mInterfaceType;
@@ -136,8 +139,11 @@
         super(ifaceName, looper);
         mLog = log.forSubComponent(ifaceName);
         mNMService = nMService;
+        // TODO: This should be passed in for testability.
+        mNetd = NetdService.getInstance();
         mStatsService = statsService;
         mTetherController = tetherController;
+        mInterfaceCtrl = new InterfaceController(ifaceName, nMService, mNetd, mLog);
         mIfaceName = ifaceName;
         mInterfaceType = interfaceType;
         mLinkProperties = new LinkProperties();
@@ -179,6 +185,7 @@
 
     private void stopIPv4() { configureIPv4(false); }
 
+    // TODO: Refactor this in terms of calls to InterfaceController.
     private boolean configureIPv4(boolean enabled) {
         if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")");
 
@@ -381,8 +388,8 @@
 
     private void configureLocalIPv6Dns(
             HashSet<Inet6Address> deprecatedDnses, HashSet<Inet6Address> newDnses) {
-        final INetd netd = NetdService.getInstance();
-        if (netd == null) {
+        // TODO: Is this really necessary? Can we not fail earlier if INetd cannot be located?
+        if (mNetd == null) {
             if (newDnses != null) newDnses.clear();
             mLog.e("No netd service instance available; not setting local IPv6 addresses");
             return;
@@ -391,11 +398,8 @@
         // [1] Remove deprecated local DNS IP addresses.
         if (!deprecatedDnses.isEmpty()) {
             for (Inet6Address dns : deprecatedDnses) {
-                final String dnsString = dns.getHostAddress();
-                try {
-                    netd.interfaceDelAddress(mIfaceName, dnsString, RFC7421_PREFIX_LENGTH);
-                } catch (ServiceSpecificException | RemoteException e) {
-                    mLog.e("Failed to remove local dns IP " + dnsString + ": " + e);
+                if (!mInterfaceCtrl.removeAddress(dns, RFC7421_PREFIX_LENGTH)) {
+                    mLog.e("Failed to remove local dns IP " + dns);
                 }
 
                 mLinkProperties.removeLinkAddress(new LinkAddress(dns, RFC7421_PREFIX_LENGTH));
@@ -410,11 +414,8 @@
             }
 
             for (Inet6Address dns : addedDnses) {
-                final String dnsString = dns.getHostAddress();
-                try {
-                    netd.interfaceAddAddress(mIfaceName, dnsString, RFC7421_PREFIX_LENGTH);
-                } catch (ServiceSpecificException | RemoteException e) {
-                    mLog.e("Failed to add local dns IP " + dnsString + ": " + e);
+                if (!mInterfaceCtrl.addAddress(dns, RFC7421_PREFIX_LENGTH)) {
+                    mLog.e("Failed to add local dns IP " + dns);
                     newDnses.remove(dns);
                 }
 
@@ -423,7 +424,7 @@
         }
 
         try {
-            netd.tetherApplyDnsInterfaces();
+            mNetd.tetherApplyDnsInterfaces();
         } catch (ServiceSpecificException | RemoteException e) {
             mLog.e("Failed to update local DNS caching server");
             if (newDnses != null) newDnses.clear();
diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
index c5f7528..b35ed75 100644
--- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
@@ -95,7 +95,10 @@
     private NetworkCallback mDefaultNetworkCallback;
     private NetworkCallback mMobileNetworkCallback;
     private boolean mDunRequired;
-    private Network mCurrentDefault;
+    // The current system default network (not really used yet).
+    private Network mDefaultInternetNetwork;
+    // The current upstream network used for tethering.
+    private Network mTetheringUpstreamNetwork;
 
     public UpstreamNetworkMonitor(Context ctx, StateMachine tgt, SharedLog log, int what) {
         mContext = ctx;
@@ -130,10 +133,12 @@
 
         releaseCallback(mDefaultNetworkCallback);
         mDefaultNetworkCallback = null;
+        mDefaultInternetNetwork = null;
 
         releaseCallback(mListenAllCallback);
         mListenAllCallback = null;
 
+        mTetheringUpstreamNetwork = null;
         mNetworkMap.clear();
     }
 
@@ -207,7 +212,7 @@
                 break;
             default:
                 /* If we've found an active upstream connection that's not DUN/HIPRI
-                 * we should stop any outstanding DUN/HIPRI start requests.
+                 * we should stop any outstanding DUN/HIPRI requests.
                  *
                  * If we found NONE we don't want to do this as we want any previous
                  * requests to keep trying to bring up something we can use.
@@ -219,6 +224,10 @@
         return typeStatePair.ns;
     }
 
+    public void setCurrentUpstream(Network upstream) {
+        mTetheringUpstreamNetwork = upstream;
+    }
+
     public Set<IpPrefix> getLocalPrefixes() {
         return (Set<IpPrefix>) mLocalPrefixes.clone();
     }
@@ -250,7 +259,7 @@
                     // These request*() calls can be deleted post oag/339444.
                     return;
                 }
-                mCurrentDefault = network;
+                mDefaultInternetNetwork = network;
                 break;
 
             case CALLBACK_MOBILE_REQUEST:
@@ -302,6 +311,13 @@
                     network, newNc));
         }
 
+        // Log changes in upstream network signal strength, if available.
+        if (network.equals(mTetheringUpstreamNetwork) && newNc.hasSignalStrength()) {
+            final int newSignal = newNc.getSignalStrength();
+            final String prevSignal = getSignalStrength(prev.networkCapabilities);
+            mLog.logf("upstream network signal strength: %s -> %s", prevSignal, newSignal);
+        }
+
         mNetworkMap.put(network, new NetworkState(
                 null, prev.linkProperties, newNc, network, null, null));
         // TODO: If sufficient information is available to select a more
@@ -330,9 +346,21 @@
         notifyTarget(EVENT_ON_LINKPROPERTIES, network);
     }
 
+    private void handleSuspended(int callbackType, Network network) {
+        if (callbackType != CALLBACK_LISTEN_ALL) return;
+        if (!network.equals(mTetheringUpstreamNetwork)) return;
+        mLog.log("SUSPENDED current upstream: " + network);
+    }
+
+    private void handleResumed(int callbackType, Network network) {
+        if (callbackType != CALLBACK_LISTEN_ALL) return;
+        if (!network.equals(mTetheringUpstreamNetwork)) return;
+        mLog.log("RESUMED current upstream: " + network);
+    }
+
     private void handleLost(int callbackType, Network network) {
         if (callbackType == CALLBACK_TRACK_DEFAULT) {
-            mCurrentDefault = null;
+            mDefaultInternetNetwork = null;
             // Receiving onLost() for a default network does not necessarily
             // mean the network is gone.  We wait for a separate notification
             // on either the LISTEN_ALL or MOBILE_REQUEST callbacks before
@@ -401,8 +429,15 @@
             recomputeLocalPrefixes();
         }
 
-        // TODO: Handle onNetworkSuspended();
-        // TODO: Handle onNetworkResumed();
+        @Override
+        public void onNetworkSuspended(Network network) {
+            handleSuspended(mCallbackType, network);
+        }
+
+        @Override
+        public void onNetworkResumed(Network network) {
+            handleResumed(mCallbackType, network);
+        }
 
         @Override
         public void onLost(Network network) {
@@ -467,4 +502,9 @@
 
         return prefixSet;
     }
+
+    private static String getSignalStrength(NetworkCapabilities nc) {
+        if (nc == null || !nc.hasSignalStrength()) return "unknown";
+        return Integer.toString(nc.getSignalStrength());
+    }
 }
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 13054a6..ad74ff8 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -60,6 +60,7 @@
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
@@ -101,6 +102,22 @@
             }
         }
 
+
+        @Override
+        public void onStartUser(int userHandle) {
+            mService.onStartUser(userHandle);
+        }
+
+        @Override
+        public void onUnlockUser(int userHandle) {
+            mService.onUnlockUser(userHandle);
+        }
+
+        @Override
+        public void onStopUser(int userHandle) {
+            mService.onStopUser(userHandle);
+        }
+
         @Override
         public void onCleanupUser(int userHandle) {
             synchronized (mService.mCache) {
@@ -161,11 +178,25 @@
         }
     }
 
+    void onStartUser(int userHandle) {
+        if (mSyncManager != null) mSyncManager.onStartUser(userHandle);
+    }
+
+    void onUnlockUser(int userHandle) {
+        if (mSyncManager != null) mSyncManager.onUnlockUser(userHandle);
+    }
+
+    void onStopUser(int userHandle) {
+        if (mSyncManager != null) mSyncManager.onStopUser(userHandle);
+    }
+
     @Override
     protected synchronized void dump(FileDescriptor fd, PrintWriter pw_, String[] args) {
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw_)) return;
         final IndentingPrintWriter pw = new IndentingPrintWriter(pw_, "  ");
 
+        final boolean dumpAll = ArrayUtils.contains(args, "-a");
+
         // This makes it so that future permission checks will be in the context of this
         // process rather than the caller's process. We will restore this before returning.
         final long identityToken = clearCallingIdentity();
@@ -173,7 +204,7 @@
             if (mSyncManager == null) {
                 pw.println("No SyncManager created!  (Disk full?)");
             } else {
-                mSyncManager.dump(fd, pw);
+                mSyncManager.dump(fd, pw, dumpAll);
             }
             pw.println();
             pw.println("Observer tree:");
@@ -603,7 +634,7 @@
                 SyncStorageEngine.EndPoint info;
                 info = new SyncStorageEngine.EndPoint(account, authority, userId);
                 syncManager.clearScheduledSyncOperations(info);
-                syncManager.cancelActiveSync(info, null /* all syncs for this adapter */);
+                syncManager.cancelActiveSync(info, null /* all syncs for this adapter */, "API");
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -631,7 +662,7 @@
             }
             // Cancel active syncs and clear pending syncs from the queue.
             syncManager.cancelScheduledSyncOperation(info, extras);
-            syncManager.cancelActiveSync(info, extras);
+            syncManager.cancelActiveSync(info, extras, "API");
         } finally {
             restoreCallingIdentity(identityToken);
         }
diff --git a/services/core/java/com/android/server/content/SyncJobService.java b/services/core/java/com/android/server/content/SyncJobService.java
index a621d73..07f04b1 100644
--- a/services/core/java/com/android/server/content/SyncJobService.java
+++ b/services/core/java/com/android/server/content/SyncJobService.java
@@ -34,6 +34,8 @@
     private Messenger mMessenger;
     private SparseArray<JobParameters> jobParamsMap = new SparseArray<JobParameters>();
 
+    private final SyncLogger mLogger = SyncLogger.getInstance();
+
     /**
      * This service is started by the SyncManager which passes a messenger object to
      * communicate back with it. It never stops while the device is running.
@@ -63,6 +65,9 @@
 
     @Override
     public boolean onStartJob(JobParameters params) {
+
+        mLogger.purgeOldLogs();
+
         boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
         synchronized (jobParamsMap) {
             jobParamsMap.put(params.getJobId(), params);
@@ -70,6 +75,9 @@
         Message m = Message.obtain();
         m.what = SyncManager.SyncHandler.MESSAGE_START_SYNC;
         SyncOperation op = SyncOperation.maybeCreateFromJobExtras(params.getExtras());
+
+        mLogger.log("onStartJob() jobid=", params.getJobId(), " op=", op);
+
         if (op == null) {
             Slog.e(TAG, "Got invalid job " + params.getJobId());
             return false;
@@ -88,7 +96,7 @@
             Slog.v(TAG, "onStopJob called " + params.getJobId() + ", reason: "
                     + params.getStopReason());
         }
-
+        mLogger.log("onStopJob() ", mLogger.jobParametersToString(params));
         synchronized (jobParamsMap) {
             jobParamsMap.remove(params.getJobId());
         }
@@ -108,9 +116,13 @@
         return false;
     }
 
-    public void callJobFinished(int jobId, boolean needsReschedule) {
+    public void callJobFinished(int jobId, boolean needsReschedule, String why) {
         synchronized (jobParamsMap) {
             JobParameters params = jobParamsMap.get(jobId);
+            mLogger.log("callJobFinished()",
+                    " needsReschedule=", needsReschedule,
+                    " ", mLogger.jobParametersToString(params),
+                    " why=", why);
             if (params != null) {
                 jobFinished(params, needsReschedule);
                 jobParamsMap.remove(jobId);
@@ -119,4 +131,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/content/SyncLogger.java b/services/core/java/com/android/server/content/SyncLogger.java
new file mode 100644
index 0000000..8503768
--- /dev/null
+++ b/services/core/java/com/android/server/content/SyncLogger.java
@@ -0,0 +1,274 @@
+/*
+ * 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.content;
+
+import android.app.job.JobParameters;
+import android.os.Build;
+import android.os.Environment;
+import android.os.FileUtils;
+import android.os.SystemProperties;
+import android.text.format.DateUtils;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import libcore.io.IoUtils;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implements a rotating file logger for the sync manager, which is enabled only on userdebug/eng
+ * builds (unless debug.synclog is set to 1).
+ *
+ * Note this class could be used for other purposes too, but in general we don't want various
+ * system components to log to files, so it's put in a local package here.
+ */
+public class SyncLogger {
+    private static final String TAG = "SyncLogger";
+
+    private static SyncLogger sInstance;
+
+    SyncLogger() {
+    }
+
+    /**
+     * @return the singleton instance.
+     */
+    public static synchronized SyncLogger getInstance() {
+        if (sInstance == null) {
+            final boolean enable = "1".equals(SystemProperties.get("debug.synclog",
+                    Build.IS_DEBUGGABLE ? "1" : "0"));
+            if (enable) {
+                sInstance = new RotatingFileLogger();
+            } else {
+                sInstance = new SyncLogger();
+            }
+        }
+        return sInstance;
+    }
+
+    /**
+     * Write strings to the log file.
+     */
+    public void log(Object... message) {
+    }
+
+    /**
+     * Remove old log files.
+     */
+    public void purgeOldLogs() {
+        // The default implementation is no-op.
+    }
+
+    public String jobParametersToString(JobParameters params) {
+        // The default implementation is no-op.
+        return "";
+    }
+
+    /**
+     * Dump all existing log files into a given writer.
+     */
+    public void dumpAll(PrintWriter pw) {
+    }
+
+    /**
+     * @return whether log is enabled or not.
+     */
+    public boolean enabled() {
+        return false;
+    }
+
+    /**
+     * Actual implementation which is only used on userdebug/eng builds (by default).
+     */
+    private static class RotatingFileLogger extends SyncLogger {
+        private final Object mLock = new Object();
+
+        private final long mKeepAgeMs = TimeUnit.DAYS.toMillis(7);
+
+        private static final SimpleDateFormat sTimestampFormat
+                = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+        private static final SimpleDateFormat sFilenameDateFormat
+                = new SimpleDateFormat("yyyy-MM-dd");
+
+        @GuardedBy("mLock")
+        private final Date mCachedDate = new Date();
+
+        @GuardedBy("mLock")
+        private final StringBuilder mStringBuilder = new StringBuilder();
+
+        private final File mLogPath;
+
+        @GuardedBy("mLock")
+        private long mCurrentLogFileDayTimestamp;
+
+        @GuardedBy("mLock")
+        private Writer mLogWriter;
+
+        @GuardedBy("mLock")
+        private boolean mErrorShown;
+
+        private static final boolean DO_LOGCAT = Log.isLoggable(TAG, Log.DEBUG);
+
+        RotatingFileLogger() {
+            mLogPath = new File(Environment.getDataSystemDirectory(), "syncmanager-log");
+        }
+
+        @Override
+        public boolean enabled() {
+            return true;
+        }
+
+        private void handleException(String message, Exception e) {
+            if (!mErrorShown) {
+                Slog.e(TAG, message, e);
+                mErrorShown = true;
+            }
+        }
+
+        @Override
+        public void log(Object... message) {
+            if (message == null) {
+                return;
+            }
+            synchronized (mLock) {
+                final long now = System.currentTimeMillis();
+                openLogLocked(now);
+                if (mLogWriter == null) {
+                    return; // Couldn't open log file?
+                }
+
+                mStringBuilder.setLength(0);
+                mCachedDate.setTime(now);
+                mStringBuilder.append(sTimestampFormat.format(mCachedDate));
+                mStringBuilder.append(' ');
+
+                mStringBuilder.append(android.os.Process.myTid());
+                mStringBuilder.append(' ');
+
+                final int messageStart = mStringBuilder.length();
+
+                for (Object o : message) {
+                    mStringBuilder.append(o);
+                }
+                mStringBuilder.append('\n');
+
+                try {
+                    mLogWriter.append(mStringBuilder);
+                    mLogWriter.flush();
+
+                    // Also write on logcat.
+                    if (DO_LOGCAT) {
+                        Log.d(TAG, mStringBuilder.substring(messageStart));
+                    }
+                } catch (IOException e) {
+                    handleException("Failed to write log", e);
+                }
+            }
+        }
+
+        private void openLogLocked(long now) {
+            // If we already have a log file opened and the date has't changed, just use it.
+            final long day = now % DateUtils.DAY_IN_MILLIS;
+            if ((mLogWriter != null) && (day == mCurrentLogFileDayTimestamp)) {
+                return;
+            }
+
+            // Otherwise create a new log file.
+            closeCurrentLogLocked();
+
+            mCurrentLogFileDayTimestamp = day;
+
+            mCachedDate.setTime(now);
+            final String filename = "synclog-" + sFilenameDateFormat.format(mCachedDate) + ".log";
+            final File file = new File(mLogPath, filename);
+
+            file.getParentFile().mkdirs();
+
+            try {
+                mLogWriter = new FileWriter(file, /* append= */ true);
+            } catch (IOException e) {
+                handleException("Failed to open log file: " + file, e);
+            }
+        }
+
+        private void closeCurrentLogLocked() {
+            IoUtils.closeQuietly(mLogWriter);
+            mLogWriter = null;
+        }
+
+        @Override
+        public void purgeOldLogs() {
+            synchronized (mLock) {
+                FileUtils.deleteOlderFiles(mLogPath, /* keepCount= */ 1, mKeepAgeMs);
+            }
+        }
+
+        @Override
+        public String jobParametersToString(JobParameters params) {
+            if (params == null) {
+                return "job:null";
+            } else {
+                return "job:#" + params.getJobId() + ":"
+                        + SyncOperation.maybeCreateFromJobExtras(params.getExtras());
+            }
+        }
+
+        @Override
+        public void dumpAll(PrintWriter pw) {
+            synchronized (mLock) {
+                final String[] files = mLogPath.list();
+                if (files == null || (files.length == 0)) {
+                    return;
+                }
+                Arrays.sort(files);
+
+                for (String file : files) {
+                    dumpFile(pw, new File(mLogPath, file));
+                }
+            }
+        }
+
+        private void dumpFile(PrintWriter pw, File file) {
+            Slog.w(TAG, "Dumping " + file);
+            final char[] buffer = new char[32 * 1024];
+
+            try (Reader in = new BufferedReader(new FileReader(file))) {
+                int read;
+                while ((read = in.read(buffer)) >= 0) {
+                    if (read > 0) {
+                        pw.write(buffer, 0, read);
+                    }
+                }
+            } catch (IOException e) {
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 3ca65cd..a9c0cb0 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -58,6 +58,7 @@
 import android.net.NetworkInfo;
 import android.net.TrafficStats;
 import android.os.BatteryStats;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -74,7 +75,6 @@
 import android.os.UserManager;
 import android.os.WorkSource;
 import android.provider.Settings;
-import android.text.format.DateUtils;
 import android.text.format.Time;
 import android.util.EventLog;
 import android.util.Log;
@@ -113,6 +113,7 @@
 import java.util.Objects;
 import java.util.Random;
 import java.util.Set;
+import java.util.function.Predicate;
 
 /**
  * Implementation details:
@@ -241,6 +242,8 @@
 
     private final Random mRand;
 
+    private final SyncLogger mLogger;
+
     private boolean isJobIdInUseLockedH(int jobId, List<JobInfo> pendingJobs) {
         for (JobInfo job: pendingJobs) {
             if (job.getId() == jobId) {
@@ -289,13 +292,15 @@
                         mStorageIsLow = true;
                         cancelActiveSync(
                                 SyncStorageEngine.EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL,
-                                null /* any sync */);
+                                null /* any sync */,
+                                "storage low");
                     } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Slog.v(TAG, "Internal storage is ok.");
                         }
                         mStorageIsLow = false;
-                        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL);
+                        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL,
+                                "storage ok");
                     }
                 }
             };
@@ -378,15 +383,16 @@
                             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                                 Slog.v(TAG, "Reconnection detected: clearing all backoffs");
                             }
+                            // Note the location of this code was wrong from nyc to oc; fixed in DR.
+                            clearAllBackoffs("network reconnect");
                         }
-                        clearAllBackoffs();
                     }
                 }
             };
 
-    private void clearAllBackoffs() {
+    private void clearAllBackoffs(String why) {
         mSyncStorageEngine.clearAllBackoffsLocked();
-        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL);
+        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL, why);
     }
 
     private boolean readDataConnectionState() {
@@ -400,6 +406,7 @@
                 public void onReceive(Context context, Intent intent) {
                     Log.w(TAG, "Writing sync state before shutdown...");
                     getSyncStorageEngine().writeAllState();
+                    mLogger.log("Shutting down.");
                 }
             };
 
@@ -455,6 +462,7 @@
                             continue;
                         }
                         if (opx.key.equals(opy.key)) {
+                            mLogger.log("Removing duplicate sync: ", opy);
                             mJobScheduler.cancel(opy.jobId);
                         }
                     }
@@ -467,25 +475,57 @@
         if (mJobScheduler != null) {
             return;
         }
-        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-            Log.d(TAG, "initializing JobScheduler object.");
-        }
-        mJobScheduler = (JobScheduler) mContext.getSystemService(
-                Context.JOB_SCHEDULER_SERVICE);
-        mJobSchedulerInternal = LocalServices.getService(JobSchedulerInternal.class);
-        // Get all persisted syncs from JobScheduler
-        List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs();
-        for (JobInfo job : pendingJobs) {
-            SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras());
-            if (op != null) {
-                if (!op.isPeriodic) {
-                    // Set the pending status of this EndPoint to true. Pending icon is
-                    // shown on the settings activity.
-                    mSyncStorageEngine.markPending(op.target, true);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.d(TAG, "initializing JobScheduler object.");
+            }
+            mJobScheduler = (JobScheduler) mContext.getSystemService(
+                    Context.JOB_SCHEDULER_SERVICE);
+            mJobSchedulerInternal = LocalServices.getService(JobSchedulerInternal.class);
+            // Get all persisted syncs from JobScheduler
+            List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs();
+
+            int numPersistedPeriodicSyncs = 0;
+            int numPersistedOneshotSyncs = 0;
+            for (JobInfo job : pendingJobs) {
+                SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras());
+                if (op != null) {
+                    if (op.isPeriodic) {
+                        numPersistedPeriodicSyncs++;
+                    } else {
+                        numPersistedOneshotSyncs++;
+                        // Set the pending status of this EndPoint to true. Pending icon is
+                        // shown on the settings activity.
+                        mSyncStorageEngine.markPending(op.target, true);
+                    }
                 }
             }
+            if (mLogger.enabled()) {
+                mLogger.log("Connected to JobScheduler: "
+                        + numPersistedPeriodicSyncs + " periodic syncs "
+                        + numPersistedOneshotSyncs + " oneshot syncs.");
+            }
+            cleanupJobs();
+
+            if ((numPersistedPeriodicSyncs == 0) && likelyHasPeriodicSyncs()) {
+                Slog.wtf(TAG, "Device booted with no persisted periodic syncs.");
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
-        cleanupJobs();
+    }
+
+    /**
+     * @return whether the device most likely has some periodic syncs.
+     */
+    private boolean likelyHasPeriodicSyncs() {
+        try {
+            return AccountManager.get(mContext).getAccountsByType("com.google").length > 0;
+        } catch (Throwable th) {
+            // Just in case.
+        }
+        return false;
     }
 
     private JobScheduler getJobScheduler() {
@@ -502,6 +542,8 @@
         // and creating threads and so on; it may fail if the disk is full.
         mContext = context;
 
+        mLogger = SyncLogger.getInstance();
+
         SyncStorageEngine.init(context);
         mSyncStorageEngine = SyncStorageEngine.getSingleton();
         mSyncStorageEngine.setOnSyncRequestListener(new OnSyncRequestListener() {
@@ -667,8 +709,23 @@
         // before we started checking for account access because they already know
         // the account (they run before) which is the genie is out of the bottle.
         whiteListExistingSyncAdaptersIfNeeded();
+
+        mLogger.log("Sync manager initialized.");
     }
 
+    public void onStartUser(int userHandle) {
+        mLogger.log("onStartUser: user=", userHandle);
+    }
+
+    public void onUnlockUser(int userHandle) {
+        mLogger.log("onUnlockUser: user=", userHandle);
+    }
+
+    public void onStopUser(int userHandle) {
+        mLogger.log("onStopUser: user=", userHandle);
+    }
+
+
     private void whiteListExistingSyncAdaptersIfNeeded() {
         if (!mSyncStorageEngine.shouldGrantSyncAdaptersAccountAccess()) {
             return;
@@ -1062,11 +1119,13 @@
     }
 
     private void removeSyncsForAuthority(EndPoint info) {
+        mLogger.log("removeSyncsForAuthority: ", info);
         verifyJobScheduler();
         List<SyncOperation> ops = getAllPendingSyncs();
         for (SyncOperation op: ops) {
             if (op.target.matchesSpec(info)) {
-                 getJobScheduler().cancel(op.jobId);
+                mLogger.log("canceling: ", op);
+                getJobScheduler().cancel(op.jobId);
             }
         }
     }
@@ -1145,8 +1204,12 @@
         mSyncHandler.sendMessage(msg);
     }
 
-    private void sendCancelSyncsMessage(final SyncStorageEngine.EndPoint info, Bundle extras) {
+    private void sendCancelSyncsMessage(final SyncStorageEngine.EndPoint info, Bundle extras,
+            String why) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) Slog.v(TAG, "sending MESSAGE_CANCEL");
+
+        mLogger.log("sendCancelSyncsMessage() ep=", info, " why=", why);
+
         Message msg = mSyncHandler.obtainMessage();
         msg.what = SyncHandler.MESSAGE_CANCEL;
         msg.setData(extras);
@@ -1227,7 +1290,7 @@
         }
     }
 
-    private void clearBackoffSetting(EndPoint target) {
+    private void clearBackoffSetting(EndPoint target, String why) {
         Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(target);
         if (backoff != null && backoff.first == SyncStorageEngine.NOT_IN_BACKOFF_MODE &&
                 backoff.second == SyncStorageEngine.NOT_IN_BACKOFF_MODE) {
@@ -1240,7 +1303,7 @@
                 SyncStorageEngine.NOT_IN_BACKOFF_MODE,
                 SyncStorageEngine.NOT_IN_BACKOFF_MODE);
 
-        rescheduleSyncs(target);
+        rescheduleSyncs(target, why);
     }
 
     private void increaseBackoffSetting(EndPoint target) {
@@ -1281,14 +1344,16 @@
             Slog.v(TAG, "Backoff until: " + backoff + ", delayTime: " + newDelayInMs);
         }
         mSyncStorageEngine.setBackoff(target, backoff, newDelayInMs);
-        rescheduleSyncs(target);
+        rescheduleSyncs(target, "increaseBackoffSetting");
     }
 
     /**
      * Reschedule all scheduled syncs for this EndPoint. The syncs will be scheduled according
      * to current backoff and delayUntil values of this EndPoint.
      */
-    private void rescheduleSyncs(EndPoint target) {
+    private void rescheduleSyncs(EndPoint target, String why) {
+        mLogger.log("rescheduleSyncs() ep=", target, " why=", why);
+
         List<SyncOperation> ops = getAllPendingSyncs();
         int count = 0;
         for (SyncOperation op: ops) {
@@ -1316,7 +1381,7 @@
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Slog.v(TAG, "Delay Until time set to " + newDelayUntilTime + " for " + target);
         }
-        rescheduleSyncs(target);
+        rescheduleSyncs(target, "delayUntil newDelayUntilTime: " + newDelayUntilTime);
     }
 
     private boolean isAdapterDelayed(EndPoint target) {
@@ -1338,8 +1403,8 @@
      * have null account/provider info to specify all accounts/providers.
      * @param extras if non-null, specifies the exact sync to remove.
      */
-    public void cancelActiveSync(SyncStorageEngine.EndPoint info, Bundle extras) {
-        sendCancelSyncsMessage(info, extras);
+    public void cancelActiveSync(SyncStorageEngine.EndPoint info, Bundle extras, String why) {
+        sendCancelSyncsMessage(info, extras, why);
     }
 
     /**
@@ -1599,11 +1664,13 @@
                         null /* any account */,
                         null /* any authority */,
                         userId),
-                null /* any sync. */
+                null /* any sync. */,
+                "onUserStopped"
         );
     }
 
     private void onUserRemoved(int userId) {
+        mLogger.log("onUserRemoved: u", userId);
         updateRunningAccounts(null /* Don't sync any target */);
 
         // Clean up the storage engine database
@@ -1674,6 +1741,8 @@
             // Include "this" in the message so that the handler can ignore it if this
             // ActiveSyncContext is no longer the mActiveSyncContext at message handling
             // time.
+            mLogger.log("onFinished result=", result, " endpoint=",
+                    (mSyncOperation == null ? "null" : mSyncOperation.target));
             sendSyncFinishedOrCanceledMessage(this, result);
         }
 
@@ -1715,6 +1784,7 @@
                     Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
                             | Context.BIND_ALLOW_OOM_MANAGEMENT,
                     new UserHandle(mSyncOperation.target.userId));
+            mLogger.log("bindService() returned=", mBound, " for ", this);
             if (!bindResult) {
                 mBound = false;
             } else {
@@ -1737,6 +1807,7 @@
             }
             if (mBound) {
                 mBound = false;
+                mLogger.log("unbindService for ", this);
                 mContext.unbindService(this);
                 try {
                     mBatteryStats.noteSyncFinish(mEventName, mSyncAdapterUid);
@@ -1759,13 +1830,15 @@
         }
     }
 
-    protected void dump(FileDescriptor fd, PrintWriter pw) {
+    protected void dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
-        dumpPendingSyncs(pw);
-        dumpPeriodicSyncs(pw);
         dumpSyncState(ipw);
-        dumpSyncHistory(ipw);
         dumpSyncAdapters(ipw);
+
+        if (dumpAll) {
+            ipw.println("Detailed Sync History");
+            mLogger.dumpAll(pw);
+        }
     }
 
     static String formatTime(long time) {
@@ -1774,9 +1847,58 @@
         return tobj.format("%Y-%m-%d %H:%M:%S");
     }
 
+    private final static Comparator<SyncOperation> sOpDumpComparator = (op1, op2) -> {
+        int res = Integer.compare(op1.target.userId, op2.target.userId);
+        if (res != 0) return res;
+
+        final Comparator<String> stringComparator = String.CASE_INSENSITIVE_ORDER;
+
+        res = stringComparator.compare(op1.target.account.type, op2.target.account.type);
+        if (res != 0) return res;
+
+        res = stringComparator.compare(op1.target.account.name, op2.target.account.name);
+        if (res != 0) return res;
+
+        res = stringComparator.compare(op1.target.provider, op2.target.provider);
+        if (res != 0) return res;
+
+        res = Integer.compare(op1.reason, op2.reason);
+        if (res != 0) return res;
+
+        res = Long.compare(op1.periodMillis, op2.periodMillis);
+        if (res != 0) return res;
+
+        res = Long.compare(op1.expectedRuntime, op2.expectedRuntime);
+        if (res != 0) return res;
+
+        res = Long.compare(op1.jobId, op2.jobId);
+        if (res != 0) return res;
+
+        return 0;
+    };
+
+    private final static Comparator<SyncOperation> sOpRuntimeComparator = (op1, op2) -> {
+        int res = Long.compare(op1.expectedRuntime, op2.expectedRuntime);
+        if (res != 0) return res;
+
+        return sOpDumpComparator.compare(op1, op2);
+    };
+
+    private static <T> int countIf(Collection<T> col, Predicate<T> p) {
+        int ret = 0;
+        for (T item : col) {
+            if (p.test(item)) ret++;
+        }
+        return ret;
+    }
+
     protected void dumpPendingSyncs(PrintWriter pw) {
-        pw.println("Pending Syncs:");
         List<SyncOperation> pendingSyncs = getAllPendingSyncs();
+
+        pw.print("Pending Syncs: ");
+        pw.println(countIf(pendingSyncs, op -> !op.isPeriodic));
+
+        Collections.sort(pendingSyncs, sOpRuntimeComparator);
         int count = 0;
         for (SyncOperation op: pendingSyncs) {
             if (!op.isPeriodic) {
@@ -1784,13 +1906,16 @@
                 count++;
             }
         }
-        pw.println("Total: " + count);
         pw.println();
     }
 
     protected void dumpPeriodicSyncs(PrintWriter pw) {
-        pw.println("Periodic Syncs:");
         List<SyncOperation> pendingSyncs = getAllPendingSyncs();
+
+        pw.print("Periodic Syncs: ");
+        pw.println(countIf(pendingSyncs, op -> op.isPeriodic));
+
+        Collections.sort(pendingSyncs, sOpDumpComparator);
         int count = 0;
         for (SyncOperation op: pendingSyncs) {
             if (op.isPeriodic) {
@@ -1798,11 +1923,62 @@
                 count++;
             }
         }
-        pw.println("Total: " + count);
         pw.println();
     }
 
+    /**
+     * Similar to {@link android.util.TimeUtils#formatDuration}, but it's more suitable and concise
+     * for the sync manager dumpsys.  (Don't add the leading + sign, don't show milliseconds.)
+     */
+    public static StringBuilder formatDurationHMS(StringBuilder sb, long duration) {
+        duration /= 1000;
+        if (duration < 0) {
+            sb.append('-');
+            duration = -duration;
+        }
+        final long seconds = duration % 60;
+        duration /= 60;
+
+        final long minutes = duration % 60;
+        duration /= 60;
+
+        final long hours = duration % 24;
+        duration /= 24;
+
+        final long days = duration;
+
+        boolean print = false;
+        if (days > 0) {
+            sb.append(days);
+            sb.append('d');
+            print = true;
+        }
+        print = printTwoDigitNumber(sb, hours, 'h', print);
+        print = printTwoDigitNumber(sb, minutes, 'm', print);
+        print = printTwoDigitNumber(sb, seconds, 's', print);
+        if (!print) {
+            sb.append("0s");
+        }
+
+        return sb;
+    }
+
+    private static boolean printTwoDigitNumber(StringBuilder sb, long value, char unit,
+            boolean always) {
+        if (!always && (value == 0)) {
+            return false;
+        }
+        if (always && (value < 10)) {
+            sb.append('0');
+        }
+        sb.append(value);
+        sb.append(unit);
+        return true;
+    }
+
     protected void dumpSyncState(PrintWriter pw) {
+        final StringBuilder sb = new StringBuilder();
+
         pw.print("data connected: "); pw.println(mDataConnectionIsConnected);
         pw.print("auto sync: ");
         List<UserInfo> users = getAllUsers();
@@ -1828,13 +2004,16 @@
         final long now = SystemClock.elapsedRealtime();
         pw.print("now: "); pw.print(now);
         pw.println(" (" + formatTime(System.currentTimeMillis()) + ")");
-        pw.println(" (HH:MM:SS)");
-        pw.print("uptime: "); pw.print(DateUtils.formatElapsedTime(now / 1000));
-        pw.println(" (HH:MM:SS)");
+
+        sb.setLength(0);
+        pw.print("uptime: "); pw.print(formatDurationHMS(sb, now));
+        pw.println();
         pw.print("time spent syncing: ");
-        pw.print(DateUtils.formatElapsedTime(
-                mSyncHandler.mSyncTimeTracker.timeSpentSyncing() / 1000));
-        pw.print(" (HH:MM:SS), sync ");
+
+        sb.setLength(0);
+        pw.print(formatDurationHMS(sb,
+                mSyncHandler.mSyncTimeTracker.timeSpentSyncing()));
+        pw.print(", sync ");
         pw.print(mSyncHandler.mSyncTimeTracker.mLastWasSyncing ? "" : "not ");
         pw.println("in progress");
 
@@ -1842,17 +2021,24 @@
         pw.println("Active Syncs: " + mActiveSyncContexts.size());
         final PackageManager pm = mContext.getPackageManager();
         for (SyncManager.ActiveSyncContext activeSyncContext : mActiveSyncContexts) {
-            final long durationInSeconds = (now - activeSyncContext.mStartTime) / 1000;
+            final long durationInSeconds = (now - activeSyncContext.mStartTime);
             pw.print("  ");
-            pw.print(DateUtils.formatElapsedTime(durationInSeconds));
+            sb.setLength(0);
+            pw.print(formatDurationHMS(sb, durationInSeconds));
             pw.print(" - ");
             pw.print(activeSyncContext.mSyncOperation.dump(pm, false));
             pw.println();
         }
+        pw.println();
+
+        dumpPendingSyncs(pw);
+        dumpPeriodicSyncs(pw);
 
         // Join the installed sync adapter with the accounts list and emit for everything.
-        pw.println();
         pw.println("Sync Status");
+
+        final ArrayList<Pair<EndPoint, SyncStatusInfo>> statuses = new ArrayList<>();
+
         for (AccountAndUser account : accounts) {
             pw.printf("Account %s u%d %s\n",
                     account.account.name, account.userId, account.account.type);
@@ -1872,7 +2058,7 @@
                     "Tot",       // 9
                     "Time",      // 10
                     "Last Sync", // 11
-                    "Etc"        // 12
+                    "Backoff"    // 12
             );
 
             final List<RegisteredServicesCache.ServiceInfo<SyncAdapterType>> sorted =
@@ -1899,11 +2085,14 @@
                                         account.userId));
                 SyncStorageEngine.AuthorityInfo settings = syncAuthoritySyncStatus.first;
                 SyncStatusInfo status = syncAuthoritySyncStatus.second;
+                statuses.add(Pair.create(settings.target, status));
                 String authority = settings.target.provider;
                 if (authority.length() > 50) {
                     authority = authority.substring(authority.length() - 50);
                 }
                 table.set(row, 0, authority, settings.syncable, settings.enabled);
+
+                sb.setLength(0);
                 table.set(row, 4,
                         status.numSourceLocal,
                         status.numSourcePoll,
@@ -1911,7 +2100,7 @@
                         status.numSourceServer,
                         status.numSourceUser,
                         status.numSyncs,
-                        DateUtils.formatElapsedTime(status.totalElapsedTime / 1000));
+                        formatDurationHMS(sb, status.totalElapsedTime));
 
                 int row1 = row;
                 if (settings.delayUntil > now) {
@@ -1938,6 +2127,34 @@
             }
             table.writeTo(pw);
         }
+
+        dumpSyncHistory(pw);
+
+        pw.println();
+        pw.println("Per Adapter History");
+
+        for (int i = 0; i < statuses.size(); i++) {
+            final Pair<EndPoint, SyncStatusInfo> event = statuses.get(i);
+
+            pw.print("  ");
+            pw.print(event.first.account.name);
+            pw.print('/');
+            pw.print(event.first.account.type);
+            pw.print(" u");
+            pw.print(event.first.userId);
+            pw.print(" [");
+            pw.print(event.first.provider);
+            pw.print("]");
+            pw.println();
+
+            for (int j = 0; j < event.second.getEventCount(); j++) {
+                pw.print("    ");
+                pw.print(formatTime(event.second.getEventTime(j)));
+                pw.print(' ');
+                pw.print(event.second.getEvent(j));
+                pw.println();
+            }
+        }
     }
 
     private void dumpTimeSec(PrintWriter pw, long time) {
@@ -2503,7 +2720,7 @@
                             Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_CANCEL: "
                                     + endpoint + " bundle: " + extras);
                         }
-                        cancelActiveSyncH(endpoint, extras);
+                        cancelActiveSyncH(endpoint, extras, "MESSAGE_CANCEL");
                         break;
 
                     case SyncHandler.MESSAGE_SYNC_FINISHED:
@@ -2519,7 +2736,8 @@
                             Slog.v(TAG, "syncFinished" + payload.activeSyncContext.mSyncOperation);
                         }
                         mSyncJobService.callJobFinished(
-                                payload.activeSyncContext.mSyncOperation.jobId, false);
+                                payload.activeSyncContext.mSyncOperation.jobId, false,
+                                "sync finished");
                         runSyncFinishedOrCanceledH(payload.syncResult,
                                 payload.activeSyncContext);
                         break;
@@ -2552,9 +2770,14 @@
                             // outstanding
                             try {
                                 if (currentSyncContext.mSyncAdapter != null) {
+                                    mLogger.log("Calling cancelSync for SERVICE_DISCONNECTED ",
+                                            currentSyncContext,
+                                            " adapter=", currentSyncContext.mSyncAdapter);
                                     currentSyncContext.mSyncAdapter.cancelSync(currentSyncContext);
+                                    mLogger.log("Canceled");
                                 }
                             } catch (RemoteException e) {
+                                mLogger.log("RemoteException ", Log.getStackTraceString(e));
                                 // We don't need to retry this in this case.
                             }
 
@@ -2563,7 +2786,8 @@
                             SyncResult syncResult = new SyncResult();
                             syncResult.stats.numIoExceptions++;
                             mSyncJobService.callJobFinished(
-                                    currentSyncContext.mSyncOperation.jobId, false);
+                                    currentSyncContext.mSyncOperation.jobId, false,
+                                    "service disconnected");
                             runSyncFinishedOrCanceledH(syncResult, currentSyncContext);
                         }
                         break;
@@ -2581,7 +2805,8 @@
                                     "Detected sync making no progress for %s. cancelling.",
                                     monitoredSyncContext));
                             mSyncJobService.callJobFinished(
-                                    monitoredSyncContext.mSyncOperation.jobId, false);
+                                    monitoredSyncContext.mSyncOperation.jobId, false,
+                                    "no network activity");
                             runSyncFinishedOrCanceledH(
                                     null /* cancel => no result */, monitoredSyncContext);
                         } else {
@@ -2613,8 +2838,10 @@
          * delay. This is equivalent to a failure. If this is a periodic sync, a delayed one-off
          * sync will be scheduled.
          */
-        private void deferSyncH(SyncOperation op, long delay) {
-            mSyncJobService.callJobFinished(op.jobId, false);
+        private void deferSyncH(SyncOperation op, long delay, String why) {
+            mLogger.log("deferSyncH() ", (op.isPeriodic ? "periodic " : ""),
+                    "sync.  op=", op, " delay=", delay, " why=", why);
+            mSyncJobService.callJobFinished(op.jobId, false, why);
             if (op.isPeriodic) {
                 scheduleSyncOperationH(op.createOneTimeSyncOperation(), delay);
             } else {
@@ -2638,10 +2865,10 @@
         /**
          * Cancel an active sync and reschedule it on the JobScheduler with some delay.
          */
-        private void deferActiveSyncH(ActiveSyncContext asc) {
+        private void deferActiveSyncH(ActiveSyncContext asc, String why) {
             SyncOperation op = asc.mSyncOperation;
             runSyncFinishedOrCanceledH(null, asc);
-            deferSyncH(op, SYNC_DELAY_ON_CONFLICT);
+            deferSyncH(op, SYNC_DELAY_ON_CONFLICT, why);
         }
 
         private void startSyncH(SyncOperation op) {
@@ -2649,7 +2876,7 @@
             if (isLoggable) Slog.v(TAG, op.toString());
 
             if (mStorageIsLow) {
-                deferSyncH(op, SYNC_DELAY_ON_LOW_STORAGE);
+                deferSyncH(op, SYNC_DELAY_ON_LOW_STORAGE, "storage low");
                 return;
             }
 
@@ -2659,7 +2886,8 @@
                 List<SyncOperation> ops = getAllPendingSyncs();
                 for (SyncOperation syncOperation: ops) {
                     if (syncOperation.sourcePeriodicId == op.jobId) {
-                        mSyncJobService.callJobFinished(op.jobId, false);
+                        mSyncJobService.callJobFinished(op.jobId, false,
+                                "periodic sync, pending");
                         return;
                     }
                 }
@@ -2667,13 +2895,14 @@
                 // executing according to some backoff criteria.
                 for (ActiveSyncContext asc: mActiveSyncContexts) {
                     if (asc.mSyncOperation.sourcePeriodicId == op.jobId) {
-                        mSyncJobService.callJobFinished(op.jobId, false);
+                        mSyncJobService.callJobFinished(op.jobId, false,
+                                "periodic sync, already running");
                         return;
                     }
                 }
                 // Check for adapter delays.
                 if (isAdapterDelayed(op.target)) {
-                    deferSyncH(op, 0 /* No minimum delay */);
+                    deferSyncH(op, 0 /* No minimum delay */, "backing off");
                     return;
                 }
             }
@@ -2687,13 +2916,13 @@
                         if (isLoggable) {
                             Slog.v(TAG, "Rescheduling sync due to conflict " + op.toString());
                         }
-                        deferSyncH(op, SYNC_DELAY_ON_CONFLICT);
+                        deferSyncH(op, SYNC_DELAY_ON_CONFLICT, "delay on conflict");
                         return;
                     } else {
                         if (isLoggable) {
                             Slog.v(TAG, "Pushing back running sync due to a higher priority sync");
                         }
-                        deferActiveSyncH(asc);
+                        deferActiveSyncH(asc, "preempted");
                         break;
                     }
                 }
@@ -2703,12 +2932,13 @@
             switch (syncOpState) {
                 case SYNC_OP_STATE_INVALID_NO_ACCOUNT_ACCESS:
                 case SYNC_OP_STATE_INVALID: {
-                    mSyncJobService.callJobFinished(op.jobId, false);
+                    mSyncJobService.callJobFinished(op.jobId, false,
+                            "invalid op state: " + syncOpState);
                 } return;
             }
 
             if (!dispatchSyncOperation(op)) {
-                mSyncJobService.callJobFinished(op.jobId, false);
+                mSyncJobService.callJobFinished(op.jobId, false, "dispatchSyncOperation() failed");
             }
 
             setAuthorityPendingState(op.target);
@@ -2733,6 +2963,9 @@
                     Slog.v(TAG, acc.toString());
                 }
             }
+            if (mLogger.enabled()) {
+                mLogger.log("updateRunningAccountsH: ", Arrays.toString(mRunningAccounts));
+            }
             if (mBootCompleted) {
                 doDatabaseCleanup();
             }
@@ -2764,6 +2997,7 @@
             List<SyncOperation> ops = getAllPendingSyncs();
             for (SyncOperation op: ops) {
                 if (!containsAccountAndUser(allAccounts, op.target.account, op.target.userId)) {
+                    mLogger.log("canceling: ", op);
                     getJobScheduler().cancel(op.jobId);
                 }
             }
@@ -2878,9 +3112,11 @@
                 if (op.sourcePeriodicId == syncOperation.jobId || op.jobId == syncOperation.jobId) {
                     ActiveSyncContext asc = findActiveSyncContextH(syncOperation.jobId);
                     if (asc != null) {
-                        mSyncJobService.callJobFinished(syncOperation.jobId, false);
+                        mSyncJobService.callJobFinished(syncOperation.jobId, false,
+                                "removePeriodicSyncInternalH");
                         runSyncFinishedOrCanceledH(null, asc);
                     }
+                    mLogger.log("removePeriodicSyncInternalH-canceling: ", op);
                     getJobScheduler().cancel(op.jobId);
                 }
             }
@@ -2990,6 +3226,8 @@
             final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
             syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, info.userId);
             if (syncAdapterInfo == null) {
+                mLogger.log("dispatchSyncOperation() failed: no sync adapter info for ",
+                        syncAdapterType);
                 Log.d(TAG, "can't find a sync adapter for " + syncAdapterType
                         + ", removing settings for it");
                 mSyncStorageEngine.removeAuthority(info);
@@ -3010,6 +3248,8 @@
             postMonitorSyncProgressMessage(activeSyncContext);
 
             if (!activeSyncContext.bindToSyncAdapter(targetComponent, info.userId)) {
+                mLogger.log("dispatchSyncOperation() failed: bind failed. target: ",
+                        targetComponent);
                 Slog.e(TAG, "Bind attempt failed - target: " + targetComponent);
                 closeActiveSyncContext(activeSyncContext);
                 return false;
@@ -3025,16 +3265,26 @@
                 activeSyncContext.mIsLinkedToDeath = true;
                 syncAdapter.linkToDeath(activeSyncContext, 0);
 
+                mLogger.log("Sync start: account=" + syncOperation.target.account,
+                        " authority=", syncOperation.target.provider,
+                        " reason=", SyncOperation.reasonToString(null, syncOperation.reason),
+                        " extras=", SyncOperation.extrasToString(syncOperation.extras),
+                        " adapter=", activeSyncContext.mSyncAdapter);
+
                 activeSyncContext.mSyncAdapter = ISyncAdapter.Stub.asInterface(syncAdapter);
                 activeSyncContext.mSyncAdapter
                         .startSync(activeSyncContext, syncOperation.target.provider,
                                 syncOperation.target.account, syncOperation.extras);
+
+                mLogger.log("Sync is running now...");
             } catch (RemoteException remoteExc) {
+                mLogger.log("Sync failed with RemoteException: ", remoteExc.toString());
                 Log.d(TAG, "maybeStartNextSync: caught a RemoteException, rescheduling", remoteExc);
                 closeActiveSyncContext(activeSyncContext);
                 increaseBackoffSetting(syncOperation.target);
                 scheduleSyncOperationH(syncOperation);
             } catch (RuntimeException exc) {
+                mLogger.log("Sync failed with RuntimeException: ", exc.toString());
                 closeActiveSyncContext(activeSyncContext);
                 Slog.e(TAG, "Caught RuntimeException while starting the sync " + syncOperation, exc);
             }
@@ -3045,7 +3295,8 @@
          * @param info Can have null fields to indicate all the active syncs for that field.
          * @param extras Can be null to indicate <strong>all</strong> syncs for the given endpoint.
          */
-        private void cancelActiveSyncH(SyncStorageEngine.EndPoint info, Bundle extras) {
+        private void cancelActiveSyncH(SyncStorageEngine.EndPoint info, Bundle extras,
+                String why) {
             ArrayList<ActiveSyncContext> activeSyncs =
                     new ArrayList<ActiveSyncContext>(mActiveSyncContexts);
             for (ActiveSyncContext activeSyncContext : activeSyncs) {
@@ -3061,7 +3312,8 @@
                                     false /* no config settings */)) {
                         continue;
                     }
-                    mSyncJobService.callJobFinished(activeSyncContext.mSyncOperation.jobId, false);
+                    mSyncJobService.callJobFinished(activeSyncContext.mSyncOperation.jobId, false,
+                            why);
                     runSyncFinishedOrCanceledH(null /* cancel => no result */, activeSyncContext);
                 }
             }
@@ -3097,18 +3349,12 @@
                 activeSyncContext.mSyncAdapter.asBinder().unlinkToDeath(activeSyncContext, 0);
                 activeSyncContext.mIsLinkedToDeath = false;
             }
-            closeActiveSyncContext(activeSyncContext);
             final long elapsedTime = SystemClock.elapsedRealtime() - activeSyncContext.mStartTime;
             String historyMessage;
             int downstreamActivity;
             int upstreamActivity;
 
-            if (!syncOperation.isPeriodic) {
-                // mSyncJobService.jobFinidhed is async, we need to ensure that this job is
-                // removed from JobScheduler's pending jobs list before moving forward and
-                // potentially rescheduling all pending jobs to respect new backoff values.
-                getJobScheduler().cancel(syncOperation.jobId);
-            }
+            mLogger.log("runSyncFinishedOrCanceledH() op=", syncOperation, " result=", syncResult);
 
             if (syncResult != null) {
                 if (isLoggable) {
@@ -3116,12 +3362,22 @@
                             + syncOperation + ", result " + syncResult);
                 }
 
+                // In the non-canceled case, close the active sync context before doing the rest
+                // of the stuff.
+                closeActiveSyncContext(activeSyncContext);
+
+                // Note this part is probably okay to do before closeActiveSyncContext()...
+                // But moved here to restore OC-dev's behavior.  See b/64597061.
+                if (!syncOperation.isPeriodic) {
+                    getJobScheduler().cancel(syncOperation.jobId);
+                }
+
                 if (!syncResult.hasError()) {
                     historyMessage = SyncStorageEngine.MESG_SUCCESS;
                     // TODO: set these correctly when the SyncResult is extended to include it
                     downstreamActivity = 0;
                     upstreamActivity = 0;
-                    clearBackoffSetting(syncOperation.target);
+                    clearBackoffSetting(syncOperation.target, "sync success");
 
                     // If the operation completes successfully and it was scheduled due to
                     // a periodic operation failing, we reschedule the periodic operation to
@@ -3152,16 +3408,28 @@
                 if (isLoggable) {
                     Slog.v(TAG, "runSyncFinishedOrCanceled [canceled]: " + syncOperation);
                 }
+
+                if (!syncOperation.isPeriodic) {
+                    getJobScheduler().cancel(syncOperation.jobId);
+                }
+
                 if (activeSyncContext.mSyncAdapter != null) {
                     try {
+                        mLogger.log("Calling cancelSync for runSyncFinishedOrCanceled ",
+                                activeSyncContext, "  adapter=", activeSyncContext.mSyncAdapter);
                         activeSyncContext.mSyncAdapter.cancelSync(activeSyncContext);
+                        mLogger.log("Canceled");
                     } catch (RemoteException e) {
+                        mLogger.log("RemoteException ", Log.getStackTraceString(e));
                         // we don't need to retry this in this case
                     }
                 }
                 historyMessage = SyncStorageEngine.MESG_CANCELED;
                 downstreamActivity = 0;
                 upstreamActivity = 0;
+
+                // In the cancel sync case, close it after calling cancelSync().
+                closeActiveSyncContext(activeSyncContext);
             }
 
             stopSyncEvent(activeSyncContext.mHistoryRowId, syncOperation, historyMessage,
@@ -3198,6 +3466,8 @@
                         + activeSyncContext.toString());
             }
             mSyncHandler.removeMessages(SyncHandler.MESSAGE_MONITOR_SYNC, activeSyncContext);
+
+            mLogger.log("closeActiveSyncContext: ", activeSyncContext);
         }
 
         /**
@@ -3403,7 +3673,7 @@
     }
 
     static class PrintTable {
-        private ArrayList<Object[]> mTable = Lists.newArrayList();
+        private ArrayList<String[]> mTable = Lists.newArrayList();
         private final int mCols;
 
         PrintTable(int cols) {
@@ -3416,13 +3686,17 @@
                         " columns. can't set " + values.length + " at column " + col);
             }
             for (int i = mTable.size(); i <= row; i++) {
-                final Object[] list = new Object[mCols];
+                final String[] list = new String[mCols];
                 mTable.add(list);
                 for (int j = 0; j < mCols; j++) {
                     list[j] = "";
                 }
             }
-            System.arraycopy(values, 0, mTable.get(row), col, values.length);
+            final String[] rowArray = mTable.get(row);
+            for (int i = 0; i < values.length; i++) {
+                final Object value = values[i];
+                rowArray[col + i] = (value == null) ? "" : value.toString();
+            }
         }
 
         void writeTo(PrintWriter out) {
diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java
index c371f97..7d2cc00 100644
--- a/services/core/java/com/android/server/content/SyncOperation.java
+++ b/services/core/java/com/android/server/content/SyncOperation.java
@@ -18,10 +18,11 @@
 
 import android.accounts.Account;
 import android.app.job.JobInfo;
-import android.content.pm.PackageManager;
 import android.content.ContentResolver;
+import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.os.PersistableBundle;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.Slog;
 
@@ -236,6 +237,9 @@
      * contain a valid sync operation.
      */
     static SyncOperation maybeCreateFromJobExtras(PersistableBundle jobExtras) {
+        if (jobExtras == null) {
+            return null;
+        }
         String accountName, accountType;
         String provider;
         int userId, owningUid;
@@ -350,37 +354,46 @@
         return dump(null, true);
     }
 
-    String dump(PackageManager pm, boolean useOneLine) {
+    String dump(PackageManager pm, boolean shorter) {
         StringBuilder sb = new StringBuilder();
-        sb.append("JobId: ").append(jobId)
-                .append(", ")
+        sb.append("JobId=").append(jobId)
+                .append(" ")
                 .append(target.account.name)
-                .append(" u")
-                .append(target.userId).append(" (")
+                .append("/")
                 .append(target.account.type)
-                .append(")")
-                .append(", ")
+                .append(" u")
+                .append(target.userId)
+                .append(" [")
                 .append(target.provider)
-                .append(", ");
+                .append("] ");
         sb.append(SyncStorageEngine.SOURCES[syncSource]);
-        if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
-            sb.append(", EXPEDITED");
+        if (expectedRuntime != 0) {
+            sb.append(" ExpectedIn=");
+            SyncManager.formatDurationHMS(sb,
+                    (expectedRuntime - SystemClock.elapsedRealtime()));
         }
-        sb.append(", reason: ");
+        if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
+            sb.append(" EXPEDITED");
+        }
+        sb.append(" Reason=");
         sb.append(reasonToString(pm, reason));
         if (isPeriodic) {
-            sb.append(", period: " + periodMillis).append(", flexMillis: " + flexMillis);
+            sb.append(" (period=");
+            SyncManager.formatDurationHMS(sb, periodMillis);
+            sb.append(" flex=");
+            SyncManager.formatDurationHMS(sb, flexMillis);
+            sb.append(")");
         }
-        if (!useOneLine) {
-            sb.append("\n    ");
-            sb.append("owningUid=");
+        if (!shorter) {
+            sb.append(" Owner={");
             UserHandle.formatUid(sb, owningUid);
-            sb.append(" owningPackage=");
+            sb.append(" ");
             sb.append(owningPackage);
-        }
-        if (!useOneLine && !extras.keySet().isEmpty()) {
-            sb.append("\n    ");
-            extrasToStringBuilder(extras, sb);
+            sb.append("}");
+            if (!extras.keySet().isEmpty()) {
+                sb.append(" ");
+                extrasToStringBuilder(extras, sb);
+            }
         }
         return sb.toString();
     }
@@ -434,7 +447,11 @@
         return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false);
     }
 
-    private static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) {
+    static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) {
+        if (bundle == null) {
+            sb.append("null");
+            return;
+        }
         sb.append("[");
         for (String key : bundle.keySet()) {
             sb.append(key).append("=").append(bundle.get(key)).append(" ");
@@ -442,6 +459,12 @@
         sb.append("]");
     }
 
+    static String extrasToString(Bundle bundle) {
+        final StringBuilder sb = new StringBuilder();
+        extrasToStringBuilder(bundle, sb);
+        return sb.toString();
+    }
+
     String wakeLockName() {
         if (wakeLockName != null) {
             return wakeLockName;
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index f804fa1c..7b277c0 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -1183,6 +1183,16 @@
                 ds.failureCount++;
                 ds.failureTime += elapsedTime;
             }
+            final StringBuilder event = new StringBuilder();
+            event.append("" + resultMessage + " Source=" + SyncStorageEngine.SOURCES[item.source]
+                    + " Elapsed=");
+            SyncManager.formatDurationHMS(event, elapsedTime);
+            event.append(" Reason=");
+            event.append(SyncOperation.reasonToString(null, item.reason));
+            event.append(" Extras=");
+            SyncOperation.extrasToStringBuilder(item.extras, event);
+
+            status.addEvent(event.toString());
 
             if (writeStatusNow) {
                 writeStatusLocked();
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 168744b..9aabdab 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -32,8 +32,8 @@
 import android.text.format.DateUtils;
 import android.util.EventLog;
 import android.util.MathUtils;
-import android.util.Spline;
 import android.util.Slog;
+import android.util.Spline;
 import android.util.TimeUtils;
 
 import java.io.PrintWriter;
@@ -59,6 +59,13 @@
     private static final int MSG_UPDATE_AMBIENT_LUX = 1;
     private static final int MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE = 2;
 
+    // Length of the ambient light horizon used to calculate the long term estimate of ambient
+    // light.
+    private static final int AMBIENT_LIGHT_LONG_HORIZON_MILLIS = 10000;
+
+    // Length of the ambient light horizon used to calculate short-term estimate of ambient light.
+    private static final int AMBIENT_LIGHT_SHORT_HORIZON_MILLIS = 2000;
+
     // Callbacks for requesting updates to the display's power state
     private final Callbacks mCallbacks;
 
@@ -229,13 +236,13 @@
         // debugging purposes.
         mDozing = dozing;
         boolean changed = setLightSensorEnabled(enable && !dozing);
+        if (enable && !dozing && userInitiatedChange) {
+            prepareBrightnessAdjustmentSample();
+        }
         changed |= setScreenAutoBrightnessAdjustment(adjustment);
         if (changed) {
             updateAutoBrightness(false /*sendUpdate*/);
         }
-        if (enable && !dozing && userInitiatedChange) {
-            prepareBrightnessAdjustmentSample();
-        }
     }
 
     public void dump(PrintWriter pw) {
@@ -345,22 +352,51 @@
     }
 
     private void setAmbientLux(float lux) {
+        if (DEBUG) {
+            Slog.d(TAG, "setAmbientLux(" + lux + ")");
+        }
         mAmbientLux = lux;
         mBrighteningLuxThreshold = mDynamicHysteresis.getBrighteningThreshold(lux);
         mDarkeningLuxThreshold = mDynamicHysteresis.getDarkeningThreshold(lux);
     }
 
-    private float calculateAmbientLux(long now) {
+    private float calculateAmbientLux(long now, long horizon) {
+        if (DEBUG) {
+            Slog.d(TAG, "calculateAmbientLux(" + now + ", " + horizon + ")");
+        }
         final int N = mAmbientLightRingBuffer.size();
         if (N == 0) {
             Slog.e(TAG, "calculateAmbientLux: No ambient light readings available");
             return -1;
         }
+
+        // Find the first measurement that is just outside of the horizon.
+        int endIndex = 0;
+        final long horizonStartTime = now - horizon;
+        for (int i = 0; i < N-1; i++) {
+            if (mAmbientLightRingBuffer.getTime(i + 1) <= horizonStartTime) {
+                endIndex++;
+            } else {
+                break;
+            }
+        }
+        if (DEBUG) {
+            Slog.d(TAG, "calculateAmbientLux: selected endIndex=" + endIndex + ", point=("
+                    + mAmbientLightRingBuffer.getTime(endIndex) + ", "
+                    + mAmbientLightRingBuffer.getLux(endIndex)
+                    + ")");
+        }
         float sum = 0;
         float totalWeight = 0;
         long endTime = AMBIENT_LIGHT_PREDICTION_TIME_MILLIS;
-        for (int i = N - 1; i >= 0; i--) {
-            long startTime = (mAmbientLightRingBuffer.getTime(i) - now);
+        for (int i = N - 1; i >= endIndex; i--) {
+            long eventTime = mAmbientLightRingBuffer.getTime(i);
+            if (i == endIndex && eventTime < horizonStartTime) {
+                // If we're at the final value, make sure we only consider the part of the sample
+                // within our desired horizon.
+                eventTime = horizonStartTime;
+            }
+            final long startTime = eventTime - now;
             float weight = calculateWeight(startTime, endTime);
             float lux = mAmbientLightRingBuffer.getLux(i);
             if (DEBUG) {
@@ -435,7 +471,7 @@
                         timeWhenSensorWarmedUp);
                 return;
             }
-            setAmbientLux(calculateAmbientLux(time));
+            setAmbientLux(calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS));
             mAmbientLuxValid = true;
             if (DEBUG) {
                 Slog.d(TAG, "updateAmbientLux: Initializing: "
@@ -447,14 +483,25 @@
 
         long nextBrightenTransition = nextAmbientLightBrighteningTransition(time);
         long nextDarkenTransition = nextAmbientLightDarkeningTransition(time);
-        float ambientLux = calculateAmbientLux(time);
+        // Essentially, we calculate both a slow ambient lux, to ensure there's a true long-term
+        // change in lighting conditions, and a fast ambient lux to determine what the new
+        // brightness situation is since the slow lux can be quite slow to converge.
+        //
+        // Note that both values need to be checked for sufficient change before updating the
+        // proposed ambient light value since the slow value might be sufficiently far enough away
+        // from the fast value to cause a recalculation while its actually just converging on
+        // the fast value still.
+        float slowAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_LONG_HORIZON_MILLIS);
+        float fastAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS);
 
-        if (ambientLux >= mBrighteningLuxThreshold && nextBrightenTransition <= time
-                || ambientLux <= mDarkeningLuxThreshold && nextDarkenTransition <= time) {
-            setAmbientLux(ambientLux);
+        if (slowAmbientLux >= mBrighteningLuxThreshold &&
+                fastAmbientLux >= mBrighteningLuxThreshold && nextBrightenTransition <= time
+                || slowAmbientLux <= mDarkeningLuxThreshold
+                && fastAmbientLux <= mDarkeningLuxThreshold && nextDarkenTransition <= time) {
+            setAmbientLux(fastAmbientLux);
             if (DEBUG) {
                 Slog.d(TAG, "updateAmbientLux: "
-                        + ((ambientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": "
+                        + ((fastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": "
                         + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold
                         + ", mAmbientLightRingBuffer=" + mAmbientLightRingBuffer
                         + ", mAmbientLux=" + mAmbientLux);
@@ -616,6 +663,12 @@
         void updateBrightness();
     }
 
+    /**
+     * A ring buffer of ambient light measurements sorted by time.
+     *
+     * Each entry consists of a timestamp and a lux measurement, and the overall buffer is sorted
+     * from oldest to newest.
+     */
     private static final class AmbientLightRingBuffer {
         // Proportional extra capacity of the buffer beyond the expected number of light samples
         // in the horizon
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 8129f45..8269042 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -132,7 +132,7 @@
 
     private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
 
-    private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER = 1;
+    private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
     private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
     private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
     private static final int MSG_REQUEST_TRAVERSAL = 4;
@@ -266,7 +266,6 @@
 
         PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
-
     }
 
     public void setupSchedulerPolicies() {
@@ -284,9 +283,9 @@
         // We need to pre-load the persistent data store so it's ready before the default display
         // adapter is up so that we have it's configuration. We could load it lazily, but since
         // we're going to have to read it in eventually we may as well do it here rather than after
-        // we've waited for the diplay to register itself with us.
+        // we've waited for the display to register itself with us.
         mPersistentDataStore.loadIfNeeded();
-        mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
+        mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
 
         publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
                 true /*allowIsolated*/);
@@ -298,12 +297,16 @@
     public void onBootPhase(int phase) {
         if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
             synchronized (mSyncRoot) {
-                long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
-                while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) {
+                long timeout = SystemClock.uptimeMillis()
+                        + mInjector.getDefaultDisplayDelayTimeout();
+                while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null ||
+                        mVirtualDisplayAdapter == null) {
                     long delay = timeout - SystemClock.uptimeMillis();
                     if (delay <= 0) {
                         throw new RuntimeException("Timeout waiting for default display "
-                                + "to be initialized.");
+                                + "to be initialized. DefaultDisplay="
+                                + mLogicalDisplays.get(Display.DEFAULT_DISPLAY)
+                                + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter);
                     }
                     if (DEBUG) {
                         Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
@@ -685,11 +688,23 @@
         }
     }
 
-    private void registerDefaultDisplayAdapter() {
-        // Register default display adapter.
+    private void registerDefaultDisplayAdapters() {
+        // Register default display adapters.
         synchronized (mSyncRoot) {
+            // main display adapter
             registerDisplayAdapterLocked(new LocalDisplayAdapter(
                     mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
+
+            // Standalone VR devices rely on a virtual display as their primary display for
+            // 2D UI. We register virtual display adapter along side the main display adapter
+            // here so that it is ready by the time the system sends the home Intent for
+            // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
+            // the virtual display inside VR before any VR-specific apps even run.
+            mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
+                    mHandler, mDisplayAdapterListener);
+            if (mVirtualDisplayAdapter != null) {
+                registerDisplayAdapterLocked(mVirtualDisplayAdapter);
+            }
         }
     }
 
@@ -698,7 +713,6 @@
             if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
                 registerOverlayDisplayAdapterLocked();
                 registerWifiDisplayAdapterLocked();
-                registerVirtualDisplayAdapterLocked();
             }
         }
     }
@@ -719,12 +733,6 @@
         }
     }
 
-    private void registerVirtualDisplayAdapterLocked() {
-        mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext, mHandler,
-                mDisplayAdapterListener);
-        registerDisplayAdapterLocked(mVirtualDisplayAdapter);
-    }
-
     private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
         // In safe mode, we disable non-essential display adapters to give the user
         // an opportunity to fix broken settings or other problems that might affect
@@ -1219,6 +1227,22 @@
                 Handler handler, DisplayAdapter.Listener displayAdapterListener) {
             return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener);
         }
+
+        long getDefaultDisplayDelayTimeout() {
+            return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
+        }
+    }
+
+    @VisibleForTesting
+    DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) {
+        synchronized (mSyncRoot) {
+            LogicalDisplay display = mLogicalDisplays.get(displayId);
+            if (display != null) {
+                DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
+                return displayDevice.getDisplayDeviceInfoLocked();
+            }
+            return null;
+        }
     }
 
     private final class DisplayManagerHandler extends Handler {
@@ -1229,8 +1253,8 @@
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-                case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER:
-                    registerDefaultDisplayAdapter();
+                case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS:
+                    registerDefaultDisplayAdapters();
                     break;
 
                 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index e82724d..6e6e7d1 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -165,6 +165,18 @@
     // a stylish color fade animation instead.
     private boolean mColorFadeFadesConfig;
 
+    // True if we need to fake a transition to off when coming out of a doze state.
+    // Some display hardware will blank itself when coming out of doze in order to hide
+    // artifacts. For these displays we fake a transition into OFF so that policy can appropriately
+    // blank itself and begin an appropriate power on animation.
+    private boolean mDisplayBlanksAfterDozeConfig;
+
+    // True if there are only buckets of brightness values when the display is in the doze state,
+    // rather than a full range of values. If this is true, then we'll avoid animating the screen
+    // brightness since it'd likely be multiple jarring brightness transitions instead of just one
+    // to reach the final state.
+    private boolean mBrightnessBucketsInDozeConfig;
+
     // The pending power request.
     // Initially null until the first call to requestPowerState.
     // Guarded by mLock.
@@ -410,6 +422,12 @@
         mColorFadeFadesConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_animateScreenLights);
 
+        mDisplayBlanksAfterDozeConfig = resources.getBoolean(
+                com.android.internal.R.bool.config_displayBlanksAfterDoze);
+
+        mBrightnessBucketsInDozeConfig = resources.getBoolean(
+                com.android.internal.R.bool.config_displayBrightnessBucketsInDoze);
+
         if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
             mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
             if (mProximitySensor != null) {
@@ -771,7 +789,7 @@
             boolean wasOrWillBeInVr = (state == Display.STATE_VR || oldState == Display.STATE_VR);
             if ((state == Display.STATE_ON
                     && mSkipRampState == RAMP_STATE_SKIP_NONE
-                    || state == Display.STATE_DOZE)
+                    || state == Display.STATE_DOZE && !mBrightnessBucketsInDozeConfig)
                     && !wasOrWillBeInVr) {
                 animateScreenBrightness(brightness,
                         slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
@@ -794,7 +812,7 @@
         // Notify policy about screen turned on.
         if (ready && state != Display.STATE_OFF
                 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
-            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_ON;
+            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);
             mWindowManagerPolicy.screenTurnedOn();
         }
 
@@ -877,6 +895,10 @@
     }
 
     private boolean setScreenState(int state) {
+        return setScreenState(state, false /*reportOnly*/);
+    }
+
+    private boolean setScreenState(int state, boolean reportOnly) {
         final boolean isOff = (state == Display.STATE_OFF);
         if (mPowerState.getScreenState() != state) {
 
@@ -884,24 +906,24 @@
             // actually turn the screen off.
             if (isOff && !mScreenOffBecauseOfProximity) {
                 if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
-                    mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_OFF;
+                    setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
                     blockScreenOff();
                     mWindowManagerPolicy.screenTurningOff(mPendingScreenOffUnblocker);
-                    return false;
+                    unblockScreenOff();
                 } else if (mPendingScreenOffUnblocker != null) {
-
                     // Abort doing the state change until screen off is unblocked.
                     return false;
                 }
             }
 
-            mPowerState.setScreenState(state);
-
-            // Tell battery stats about the transition.
-            try {
-                mBatteryStats.noteScreenState(state);
-            } catch (RemoteException ex) {
-                // same process
+            if (!reportOnly) {
+                mPowerState.setScreenState(state);
+                // Tell battery stats about the transition.
+                try {
+                    mBatteryStats.noteScreenState(state);
+                } catch (RemoteException ex) {
+                    // same process
+                }
             }
         }
 
@@ -913,7 +935,7 @@
         // finished drawing underneath.
         if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
                 && !mScreenOffBecauseOfProximity) {
-            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
+            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
             unblockScreenOn();
             mWindowManagerPolicy.screenTurnedOff();
         } else if (!isOff
@@ -923,10 +945,10 @@
             // Complete the full state transition on -> turningOff -> off.
             unblockScreenOff();
             mWindowManagerPolicy.screenTurnedOff();
-            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
+            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
         }
         if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
-            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_ON;
+            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
             if (mPowerState.getColorFadeLevel() == 0.0f) {
                 blockScreenOn();
             } else {
@@ -939,6 +961,11 @@
         return mPendingScreenOnUnblocker == null;
     }
 
+    private void setReportedScreenState(int state) {
+        Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state);
+        mReportedScreenStateToPolicy = state;
+    }
+
     private int clampScreenBrightness(int value) {
         return MathUtils.constrain(
                 value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
@@ -968,6 +995,22 @@
             mPendingScreenOff = false;
         }
 
+        if (mDisplayBlanksAfterDozeConfig
+                && Display.isDozeState(mPowerState.getScreenState())
+                && !Display.isDozeState(target)) {
+            // Skip the screen off animation and add a black surface to hide the
+            // contents of the screen.
+            mPowerState.prepareColorFade(mContext,
+                    mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP);
+            mColorFadeOffAnimator.end();
+            // Some display hardware will blank itself on the transition between doze and non-doze
+            // but still on display states. In this case we want to report to policy that the
+            // display has turned off so it can prepare the appropriate power on animation, but we
+            // don't want to actually transition to the fully off state since that takes
+            // significantly longer to transition from.
+            setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/);
+        }
+
         // If we were in the process of turning off the screen but didn't quite
         // finish.  Then finish up now to prevent a jarring transition back
         // to screen on if we skipped blocking screen on as usual.
@@ -1263,7 +1306,8 @@
         pw.println("  mAppliedLowPower=" + mAppliedLowPower);
         pw.println("  mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
         pw.println("  mPendingScreenOff=" + mPendingScreenOff);
-        pw.println("  mReportedToPolicy=" + reportedToPolicyToString(mReportedScreenStateToPolicy));
+        pw.println("  mReportedToPolicy=" +
+                reportedToPolicyToString(mReportedScreenStateToPolicy));
 
         pw.println("  mScreenBrightnessRampAnimator.isAnimating()=" +
                 mScreenBrightnessRampAnimator.isAnimating());
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index e2fd0ac..efa4a1d 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -20,6 +20,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.PowerManager;
+import android.os.Trace;
 import android.util.FloatProperty;
 import android.util.IntProperty;
 import android.util.Slog;
@@ -49,6 +50,7 @@
     private static final String TAG = "DisplayPowerState";
 
     private static boolean DEBUG = false;
+    private static String COUNTER_COLOR_FADE = "ColorFadeLevel";
 
     private final Handler mHandler;
     private final Choreographer mChoreographer;
@@ -190,6 +192,7 @@
      * Dismisses the color fade surface.
      */
     public void dismissColorFade() {
+        Trace.traceCounter(Trace.TRACE_TAG_POWER, COUNTER_COLOR_FADE, 100);
         mColorFade.dismiss();
         mColorFadePrepared = false;
         mColorFadeReady = true;
@@ -328,6 +331,8 @@
 
             if (mColorFadePrepared) {
                 mColorFade.draw(mColorFadeLevel);
+                Trace.traceCounter(Trace.TRACE_TAG_POWER,
+                        COUNTER_COLOR_FADE, Math.round(mColorFadeLevel * 100));
             }
 
             mColorFadeReady = true;
diff --git a/services/core/java/com/android/server/display/DisplayTransformManager.java b/services/core/java/com/android/server/display/DisplayTransformManager.java
index 6902b1a..dbbb318 100644
--- a/services/core/java/com/android/server/display/DisplayTransformManager.java
+++ b/services/core/java/com/android/server/display/DisplayTransformManager.java
@@ -23,7 +23,6 @@
 import android.os.ServiceManager;
 import android.util.Slog;
 import android.util.SparseArray;
-
 import com.android.internal.annotations.GuardedBy;
 
 import java.util.Arrays;
@@ -48,6 +47,9 @@
      */
     public static final int LEVEL_COLOR_MATRIX_INVERT_COLOR = 300;
 
+    private static final int SURFACE_FLINGER_TRANSACTION_COLOR_MATRIX = 1015;
+    private static final int SURFACE_FLINGER_TRANSACTION_DALTONIZER = 1014;
+
     /**
      * Map of level -> color transformation matrix.
      */
@@ -172,7 +174,7 @@
                 data.writeInt(0);
             }
             try {
-                flinger.transact(1015, data, null, 0);
+                flinger.transact(SURFACE_FLINGER_TRANSACTION_COLOR_MATRIX, data, null, 0);
             } catch (RemoteException ex) {
                 Slog.e(TAG, "Failed to set color transform", ex);
             } finally {
@@ -191,7 +193,7 @@
             data.writeInterfaceToken("android.ui.ISurfaceComposer");
             data.writeInt(mode);
             try {
-                flinger.transact(1014, data, null, 0);
+                flinger.transact(SURFACE_FLINGER_TRANSACTION_DALTONIZER, data, null, 0);
             } catch (RemoteException ex) {
                 Slog.e(TAG, "Failed to set Daltonizer mode", ex);
             } finally {
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index cdc973b..ce5f430 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -515,6 +515,7 @@
                         try {
                             final int mode = getPowerModeForState(state);
                             SurfaceControl.setDisplayPowerMode(token, mode);
+                            Trace.traceCounter(Trace.TRACE_TAG_POWER, "DisplayPowerMode", mode);
                         } finally {
                             Trace.traceEnd(Trace.TRACE_TAG_POWER);
                         }
@@ -530,6 +531,8 @@
                                 + "id=" + displayId + ", brightness=" + brightness + ")");
                         try {
                             mBacklight.setBrightness(brightness);
+                            Trace.traceCounter(Trace.TRACE_TAG_POWER,
+                                    "DisplayBrightness", brightness);
                         } finally {
                             Trace.traceEnd(Trace.TRACE_TAG_POWER);
                         }
diff --git a/services/core/java/com/android/server/display/NightDisplayService.java b/services/core/java/com/android/server/display/NightDisplayService.java
index b3cf57b..026921d 100644
--- a/services/core/java/com/android/server/display/NightDisplayService.java
+++ b/services/core/java/com/android/server/display/NightDisplayService.java
@@ -111,11 +111,7 @@
     private float[] mMatrixNight = new float[16];
 
     /**
-     *  These coefficients were generated by an LLS quadratic regression fitted to the
-     *  overdetermined system based on experimental readings (and subsequent conversion from xy
-     *  chromaticity coordinates to gamma-corrected RGB values): { (temperature, R, G, B) } ->
-     *  { (7304, 1.0, 1.0, 1.0), (4082, 1.0, 0.857, 0.719), (2850, 1.0, .754, .516),
-     *  (2596, 1.0, 0.722, 0.454) }. The 3x3 matrix is formatted like so:
+     *  The 3x3 color transformation matrix is formatted like so:
      *  <table>
      *      <tr><td>R: a coefficient</td><td>G: a coefficient</td><td>B: a coefficient</td></tr>
      *      <tr><td>R: b coefficient</td><td>G: b coefficient</td><td>B: b coefficient</td></tr>
@@ -123,9 +119,9 @@
      *  </table>
      */
     private static final float[] mColorTempCoefficients = new float[] {
-            0.0f, -0.00000000962353339f, -0.0000000189359041f,
-            0.0f, 0.000153045476f, 0.000302412211f,
-            1.0f, 0.390782778f, -0.198650895f
+            0.0f, -0.000000014365268757f, -0.000000000910931179f,
+            0.0f, 0.000255092801250106f, 0.000207598323269139f,
+            1.0f, -0.064156942434907716f, -0.349361641294833436f
     };
 
     private int mCurrentUser = UserHandle.USER_NULL;
@@ -410,7 +406,7 @@
             return;
         }
 
-        Matrix.setIdentityM(mMatrixNight, 0);
+        Matrix.setIdentityM(outTemp, 0);
 
         final float squareTemperature = colorTemperature * colorTemperature;
         final float red = squareTemperature * mColorTempCoefficients[0]
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 9d3021a..d6ab888 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -23,6 +23,7 @@
 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 android.content.Context;
 import android.hardware.display.IVirtualDisplayCallback;
@@ -359,6 +360,10 @@
                 if ((mFlags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
                     mInfo.flags |= DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
                 }
+                if ((mFlags & VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT) != 0) {
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+                }
+
                 mInfo.type = Display.TYPE_VIRTUAL;
                 mInfo.touch = ((mFlags & VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH) == 0) ?
                         DisplayDeviceInfo.TOUCH_NONE : DisplayDeviceInfo.TOUCH_VIRTUAL;
diff --git a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
index 5339bac..370e569 100644
--- a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
+++ b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
@@ -79,7 +79,7 @@
         }
         if (!authenticated) {
             if (receiver != null) {
-                FingerprintUtils.vibrateFingerprintError(getContext());
+                vibrateError();
             }
             // allow system-defined limit of number of attempts before giving up
             int lockoutMode =  handleFailedAttempt();
@@ -99,7 +99,7 @@
             result |= lockoutMode != LOCKOUT_NONE; // in a lockout mode
         } else {
             if (receiver != null) {
-                FingerprintUtils.vibrateFingerprintSuccess(getContext());
+                vibrateSuccess();
             }
             result |= true; // we have a valid fingerprint, done
             resetFailedAttempts();
diff --git a/services/core/java/com/android/server/fingerprint/ClientMonitor.java b/services/core/java/com/android/server/fingerprint/ClientMonitor.java
index 1a2e144..3eae157 100644
--- a/services/core/java/com/android/server/fingerprint/ClientMonitor.java
+++ b/services/core/java/com/android/server/fingerprint/ClientMonitor.java
@@ -23,6 +23,8 @@
 import android.hardware.fingerprint.IFingerprintServiceReceiver;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
 import android.util.Slog;
 
 import java.util.NoSuchElementException;
@@ -36,14 +38,18 @@
     protected static final String TAG = FingerprintService.TAG; // TODO: get specific name
     protected static final int ERROR_ESRCH = 3; // Likely fingerprint HAL is dead. See errno.h.
     protected static final boolean DEBUG = FingerprintService.DEBUG;
+    private static final long[] DEFAULT_SUCCESS_VIBRATION_PATTERN = new long[] {0, 30};
+    private final Context mContext;
+    private final long mHalDeviceId;
+    private final int mTargetUserId;
+    private final int mGroupId;
+    // True if client does not have MANAGE_FINGERPRINT permission
+    private final boolean mIsRestricted;
+    private final String mOwner;
+    private final VibrationEffect mSuccessVibrationEffect;
+    private final VibrationEffect mErrorVibrationEffect;
     private IBinder mToken;
     private IFingerprintServiceReceiver mReceiver;
-    private int mTargetUserId;
-    private int mGroupId;
-    private boolean mIsRestricted; // True if client does not have MANAGE_FINGERPRINT permission
-    private String mOwner;
-    private Context mContext;
-    private long mHalDeviceId;
     protected boolean mAlreadyCancelled;
 
     /**
@@ -68,6 +74,8 @@
         mGroupId = groupId;
         mIsRestricted = restricted;
         mOwner = owner;
+        mSuccessVibrationEffect = getSuccessVibrationEffect(context);
+        mErrorVibrationEffect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
         try {
             if (token != null) {
                 token.linkToDeath(this, 0);
@@ -79,7 +87,7 @@
 
     /**
      * Contacts fingerprint HAL to start the client.
-     * @return 0 on succes, errno from driver on failure
+     * @return 0 on success, errno from driver on failure
      */
     public abstract int start();
 
@@ -211,4 +219,39 @@
     public final IBinder getToken() {
         return mToken;
     }
+
+    public final void vibrateSuccess() {
+        Vibrator vibrator = mContext.getSystemService(Vibrator.class);
+        if (vibrator != null) {
+            vibrator.vibrate(mSuccessVibrationEffect);
+        }
+    }
+
+    public final void vibrateError() {
+        Vibrator vibrator = mContext.getSystemService(Vibrator.class);
+        if (vibrator != null) {
+            vibrator.vibrate(mErrorVibrationEffect);
+        }
+    }
+
+    private static VibrationEffect getSuccessVibrationEffect(Context ctx) {
+        int[] arr = ctx.getResources().getIntArray(
+                com.android.internal.R.array.config_longPressVibePattern);
+        final long[] vibePattern;
+        if (arr == null || arr.length == 0) {
+            vibePattern = DEFAULT_SUCCESS_VIBRATION_PATTERN;
+        } else {
+            vibePattern = new long[arr.length];
+            for (int i = 0; i < arr.length; i++) {
+                vibePattern[i] = arr[i];
+            }
+        }
+        if (vibePattern.length == 1) {
+            return VibrationEffect.createOneShot(
+                    vibePattern[0], VibrationEffect.DEFAULT_AMPLITUDE);
+        } else {
+            return VibrationEffect.createWaveform(vibePattern, -1);
+        }
+    }
+
 }
diff --git a/services/core/java/com/android/server/fingerprint/EnrollClient.java b/services/core/java/com/android/server/fingerprint/EnrollClient.java
index 6170894..c9efcf2 100644
--- a/services/core/java/com/android/server/fingerprint/EnrollClient.java
+++ b/services/core/java/com/android/server/fingerprint/EnrollClient.java
@@ -65,7 +65,7 @@
         if (receiver == null)
             return true; // client not listening
 
-        FingerprintUtils.vibrateFingerprintSuccess(getContext());
+        vibrateSuccess();
         MetricsLogger.action(getContext(), MetricsEvent.ACTION_FINGERPRINT_ENROLL);
         try {
             receiver.onEnrollResult(getHalDeviceId(), fpId, groupId, remaining);
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintUtils.java b/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
index 49dc8e4..5fbd735 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.hardware.fingerprint.Fingerprint;
-import android.os.Vibrator;
 import android.text.TextUtils;
 import android.util.SparseArray;
 
@@ -31,9 +30,6 @@
  */
 public class FingerprintUtils {
 
-    private static final long[] FP_ERROR_VIBRATE_PATTERN = new long[] {0, 30, 100, 30};
-    private static final long[] FP_SUCCESS_VIBRATE_PATTERN = new long[] {0, 30};
-
     private static final Object sInstanceLock = new Object();
     private static FingerprintUtils sInstance;
 
@@ -72,20 +68,6 @@
         getStateForUser(ctx, userId).renameFingerprint(fingerId, name);
     }
 
-    public static void vibrateFingerprintError(Context context) {
-        Vibrator vibrator = context.getSystemService(Vibrator.class);
-        if (vibrator != null) {
-            vibrator.vibrate(FP_ERROR_VIBRATE_PATTERN, -1);
-        }
-    }
-
-    public static void vibrateFingerprintSuccess(Context context) {
-        Vibrator vibrator = context.getSystemService(Vibrator.class);
-        if (vibrator != null) {
-            vibrator.vibrate(FP_SUCCESS_VIBRATE_PATTERN, -1);
-        }
-    }
-
     private FingerprintsUserState getStateForUser(Context ctx, int userId) {
         synchronized (this) {
             FingerprintsUserState state = mUsers.get(userId);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 907b5c1..717efbf 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -232,6 +232,9 @@
     private static native void nativeReloadDeviceAliases(long ptr);
     private static native String nativeDump(long ptr);
     private static native void nativeMonitor(long ptr);
+    private static native boolean nativeIsInputDeviceEnabled(long ptr, int deviceId);
+    private static native void nativeEnableInputDevice(long ptr, int deviceId);
+    private static native void nativeDisableInputDevice(long ptr, int deviceId);
     private static native void nativeSetPointerIconType(long ptr, int iconId);
     private static native void nativeReloadPointerIcons(long ptr);
     private static native void nativeSetCustomPointerIcon(long ptr, PointerIcon icon);
@@ -650,6 +653,32 @@
         return null;
     }
 
+    // Binder call
+    @Override
+    public boolean isInputDeviceEnabled(int deviceId) {
+        return nativeIsInputDeviceEnabled(mPtr, deviceId);
+    }
+
+    // Binder call
+    @Override
+    public void enableInputDevice(int deviceId) {
+        if (!checkCallingPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE,
+                "enableInputDevice()")) {
+            throw new SecurityException("Requires DISABLE_INPUT_DEVICE permission");
+        }
+        nativeEnableInputDevice(mPtr, deviceId);
+    }
+
+    // Binder call
+    @Override
+    public void disableInputDevice(int deviceId) {
+        if (!checkCallingPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE,
+                "disableInputDevice()")) {
+            throw new SecurityException("Requires DISABLE_INPUT_DEVICE permission");
+        }
+        nativeDisableInputDevice(mPtr, deviceId);
+    }
+
     /**
      * Gets the ids of all input devices in the system.
      * @return The input device ids.
diff --git a/services/core/java/com/android/server/job/JobPackageTracker.java b/services/core/java/com/android/server/job/JobPackageTracker.java
index 8ad1bea..ba92295 100644
--- a/services/core/java/com/android/server/job/JobPackageTracker.java
+++ b/services/core/java/com/android/server/job/JobPackageTracker.java
@@ -39,19 +39,23 @@
     public static final int EVENT_NULL = 0;
     public static final int EVENT_START_JOB = 1;
     public static final int EVENT_STOP_JOB = 2;
+    public static final int EVENT_START_PERIODIC_JOB = 3;
+    public static final int EVENT_STOP_PERIODIC_JOB = 4;
 
     private final RingBufferIndices mEventIndices = new RingBufferIndices(EVENT_BUFFER_SIZE);
     private final int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
     private final long[] mEventTimes = new long[EVENT_BUFFER_SIZE];
     private final int[] mEventUids = new int[EVENT_BUFFER_SIZE];
     private final String[] mEventTags = new String[EVENT_BUFFER_SIZE];
+    private final int[] mEventJobIds = new int[EVENT_BUFFER_SIZE];
 
-    public void addEvent(int cmd, int uid, String tag) {
+    public void addEvent(int cmd, int uid, String tag, int jobId) {
         int index = mEventIndices.add();
         mEventCmds[index] = cmd;
         mEventTimes[index] = SystemClock.elapsedRealtime();
         mEventUids[index] = uid;
         mEventTags[index] = tag;
+        mEventJobIds[index] = jobId;
     }
 
     DataSet mCurDataSet = new DataSet();
@@ -365,7 +369,8 @@
         } else {
             mCurDataSet.incActive(job.getSourceUid(), job.getSourcePackageName(), now);
         }
-        addEvent(EVENT_START_JOB, job.getSourceUid(), job.getBatteryName());
+        addEvent(job.getJob().isPeriodic() ? EVENT_START_PERIODIC_JOB :  EVENT_START_JOB,
+                job.getSourceUid(), job.getBatteryName(), job.getJobId());
     }
 
     public void noteInactive(JobStatus job) {
@@ -376,7 +381,8 @@
             mCurDataSet.decActive(job.getSourceUid(), job.getSourcePackageName(), now);
         }
         rebatchIfNeeded(now);
-        addEvent(EVENT_STOP_JOB, job.getSourceUid(), job.getBatteryName());
+        addEvent(job.getJob().isPeriodic() ? EVENT_STOP_JOB :  EVENT_STOP_PERIODIC_JOB,
+                job.getSourceUid(), job.getBatteryName(), job.getJobId());
     }
 
     public void noteConcurrency(int totalActive, int fgActive) {
@@ -448,16 +454,20 @@
             }
             final String label;
             switch (mEventCmds[index]) {
-                case EVENT_START_JOB:           label = "START"; break;
-                case EVENT_STOP_JOB:            label = " STOP"; break;
-                default:                        label = "   ??"; break;
+                case EVENT_START_JOB:           label = "  START"; break;
+                case EVENT_STOP_JOB:            label = "   STOP"; break;
+                case EVENT_START_PERIODIC_JOB:  label = "START-P"; break;
+                case EVENT_STOP_PERIODIC_JOB:   label = " STOP-P"; break;
+                default:                        label = "     ??"; break;
             }
             pw.print(prefix);
             TimeUtils.formatDuration(mEventTimes[index]-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
             pw.print(" ");
             pw.print(label);
-            pw.print(": ");
+            pw.print(": #");
             UserHandle.formatUid(pw, uid);
+            pw.print("/");
+            pw.print(mEventJobIds[index]);
             pw.print(" ");
             pw.println(mEventTags[index]);
         }
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index b8fe884..af51525 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -355,11 +355,11 @@
             synchronized (mLock) {
                 try {
                     mParser.setString(Settings.Global.getString(mResolver,
-                            Settings.Global.ALARM_MANAGER_CONSTANTS));
+                            Settings.Global.JOB_SCHEDULER_CONSTANTS));
                 } catch (IllegalArgumentException e) {
                     // Failed to parse the settings string, log this and move on
                     // with defaults.
-                    Slog.e(TAG, "Bad device idle settings", e);
+                    Slog.e(TAG, "Bad jobscheduler settings", e);
                 }
 
                 MIN_IDLE_COUNT = mParser.getInt(KEY_MIN_IDLE_COUNT,
@@ -500,11 +500,12 @@
             if (DEBUG) {
                 Slog.d(TAG, "Receieved: " + action);
             }
+            final String pkgName = getPackageName(intent);
+            final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+
             if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
                 // Purge the app's jobs if the whole package was just disabled.  When this is
                 // the case the component name will be a bare package name.
-                final String pkgName = getPackageName(intent);
-                final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
                 if (pkgName != null && pkgUid != -1) {
                     final String[] changedComponents = intent.getStringArrayExtra(
                             Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
@@ -524,7 +525,8 @@
                                             Slog.d(TAG, "Removing jobs for package " + pkgName
                                                     + " in user " + userId);
                                         }
-                                        cancelJobsForUid(pkgUid, "app package state changed");
+                                        cancelJobsForPackageAndUid(pkgName, pkgUid,
+                                                "app disabled");
                                     }
                                 } catch (RemoteException|IllegalArgumentException e) {
                                     /*
@@ -553,7 +555,7 @@
                     if (DEBUG) {
                         Slog.d(TAG, "Removing jobs for uid: " + uidRemoved);
                     }
-                    cancelJobsForUid(uidRemoved, "app uninstalled");
+                    cancelJobsForPackageAndUid(pkgName, uidRemoved, "app uninstalled");
                 }
             } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
@@ -564,8 +566,6 @@
             } else if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) {
                 // Has this package scheduled any jobs, such that we will take action
                 // if it were to be force-stopped?
-                final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
-                final String pkgName = intent.getData().getSchemeSpecificPart();
                 if (pkgUid != -1) {
                     List<JobStatus> jobsForUid;
                     synchronized (mLock) {
@@ -584,13 +584,11 @@
                 }
             } else if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
                 // possible force-stop
-                final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
-                final String pkgName = intent.getData().getSchemeSpecificPart();
                 if (pkgUid != -1) {
                     if (DEBUG) {
                         Slog.d(TAG, "Removing jobs for pkg " + pkgName + " at uid " + pkgUid);
                     }
-                    cancelJobsForPackageAndUid(pkgName, pkgUid);
+                    cancelJobsForPackageAndUid(pkgName, pkgUid, "app force stopped");
                 }
             }
         }
@@ -759,13 +757,17 @@
         }
     }
 
-    void cancelJobsForPackageAndUid(String pkgName, int uid) {
+    void cancelJobsForPackageAndUid(String pkgName, int uid, String reason) {
+        if ("android".equals(pkgName)) {
+            Slog.wtfStack(TAG, "Can't cancel all jobs for system package");
+            return;
+        }
         synchronized (mLock) {
             final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid);
             for (int i = jobsForUid.size() - 1; i >= 0; i--) {
                 final JobStatus job = jobsForUid.get(i);
                 if (job.getSourcePackageName().equals(pkgName)) {
-                    cancelJobImplLocked(job, null, "app force stopped");
+                    cancelJobImplLocked(job, null, reason);
                 }
             }
         }
@@ -779,6 +781,10 @@
      *
      */
     public void cancelJobsForUid(int uid, String reason) {
+        if (uid == Process.SYSTEM_UID) {
+            Slog.wtfStack(TAG, "Can't cancel all jobs for system uid");
+            return;
+        }
         synchronized (mLock) {
             final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid);
             for (int i=0; i<jobsForUid.size(); i++) {
@@ -1122,7 +1128,8 @@
         delayMillis =
                 Math.min(delayMillis, JobInfo.MAX_BACKOFF_DELAY_MILLIS);
         JobStatus newJob = new JobStatus(failureToReschedule, elapsedNowMillis + delayMillis,
-                JobStatus.NO_LATEST_RUNTIME, backoffAttempts);
+                JobStatus.NO_LATEST_RUNTIME, backoffAttempts,
+                failureToReschedule.getLastSuccessfulRunTime(), System.currentTimeMillis());
         for (int ic=0; ic<mControllers.size(); ic++) {
             StateController controller = mControllers.get(ic);
             controller.rescheduleForFailureLocked(newJob, failureToReschedule);
@@ -1160,7 +1167,9 @@
                     newEarliestRunTimeElapsed/1000 + ", " + newLatestRuntimeElapsed/1000 + "]s");
         }
         return new JobStatus(periodicToReschedule, newEarliestRunTimeElapsed,
-                newLatestRuntimeElapsed, 0 /* backoffAttempt */);
+                newLatestRuntimeElapsed, 0 /* backoffAttempt */,
+                System.currentTimeMillis() /* lastSuccessfulRunTime */,
+                periodicToReschedule.getLastFailedRunTime());
     }
 
     // JobCompletedListener implementations.
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index f0cd8a8..84810be 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -345,6 +345,11 @@
             out.attribute(null, "uid", Integer.toString(jobStatus.getUid()));
             out.attribute(null, "priority", String.valueOf(jobStatus.getPriority()));
             out.attribute(null, "flags", String.valueOf(jobStatus.getFlags()));
+
+            out.attribute(null, "lastSuccessfulRunTime",
+                    String.valueOf(jobStatus.getLastSuccessfulRunTime()));
+            out.attribute(null, "lastFailedRunTime",
+                    String.valueOf(jobStatus.getLastFailedRunTime()));
         }
 
         private void writeBundleToXml(PersistableBundle extras, XmlSerializer out)
@@ -555,6 +560,8 @@
                 IOException {
             JobInfo.Builder jobBuilder;
             int uid, sourceUserId;
+            long lastSuccessfulRunTime;
+            long lastFailedRunTime;
 
             // Read out job identifier attributes and priority.
             try {
@@ -572,6 +579,12 @@
                 }
                 val = parser.getAttributeValue(null, "sourceUserId");
                 sourceUserId = val == null ? -1 : Integer.parseInt(val);
+
+                val = parser.getAttributeValue(null, "lastSuccessfulRunTime");
+                lastSuccessfulRunTime = val == null ? 0 : Long.parseLong(val);
+
+                val = parser.getAttributeValue(null, "lastFailedRunTime");
+                lastFailedRunTime = val == null ? 0 : Long.parseLong(val);
             } catch (NumberFormatException e) {
                 Slog.e(TAG, "Error parsing job's required fields, skipping");
                 return null;
@@ -708,7 +721,8 @@
             // And now we're done
             JobStatus js = new JobStatus(
                     jobBuilder.build(), uid, sourcePackageName, sourceUserId, sourceTag,
-                    elapsedRuntimes.first, elapsedRuntimes.second);
+                    elapsedRuntimes.first, elapsedRuntimes.second,
+                    lastSuccessfulRunTime, lastFailedRunTime);
             return js;
         }
 
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index 446b0d6..9658da7 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -26,6 +26,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.text.format.Time;
 import android.util.ArraySet;
 import android.util.Slog;
 import android.util.TimeUtils;
@@ -184,6 +185,17 @@
     public long madeActive;
 
     /**
+     * Last time a job finished successfully for a periodic job, in the currentTimeMillis time,
+     * for dumpsys.
+     */
+    private long mLastSuccessfulRunTime;
+
+    /**
+     * Last time a job finished unsuccessfully, in the currentTimeMillis time, for dumpsys.
+     */
+    private long mLastFailedRunTime;
+
+    /**
      * For use only by ContentObserverController: state it is maintaining about content URIs
      * being observed.
      */
@@ -196,7 +208,7 @@
 
     private JobStatus(JobInfo job, int callingUid, String sourcePackageName,
             int sourceUserId, String tag, int numFailures, long earliestRunTimeElapsedMillis,
-            long latestRunTimeElapsedMillis) {
+            long latestRunTimeElapsedMillis, long lastSuccessfulRunTime, long lastFailedRunTime) {
         this.job = job;
         this.callingUid = callingUid;
 
@@ -263,6 +275,9 @@
             requiredConstraints |= CONSTRAINT_CONTENT_TRIGGER;
         }
         this.requiredConstraints = requiredConstraints;
+
+        mLastSuccessfulRunTime = lastSuccessfulRunTime;
+        mLastFailedRunTime = lastFailedRunTime;
     }
 
     /** Copy constructor. */
@@ -270,7 +285,8 @@
         this(jobStatus.getJob(), jobStatus.getUid(),
                 jobStatus.getSourcePackageName(), jobStatus.getSourceUserId(),
                 jobStatus.getSourceTag(), jobStatus.getNumFailures(),
-                jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed());
+                jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed(),
+                jobStatus.getLastSuccessfulRunTime(), jobStatus.getLastFailedRunTime());
     }
 
     /**
@@ -281,18 +297,22 @@
      * We consider a freshly loaded job to no longer be in back-off.
      */
     public JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId,
-            String sourceTag, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) {
+            String sourceTag, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis,
+            long lastSuccessfulRunTime, long lastFailedRunTime) {
         this(job, callingUid, sourcePackageName, sourceUserId, sourceTag, 0,
-                earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis);
+                earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis,
+                lastSuccessfulRunTime, lastFailedRunTime);
     }
 
     /** Create a new job to be rescheduled with the provided parameters. */
     public JobStatus(JobStatus rescheduling, long newEarliestRuntimeElapsedMillis,
-                      long newLatestRuntimeElapsedMillis, int backoffAttempt) {
+            long newLatestRuntimeElapsedMillis, int backoffAttempt,
+            long lastSuccessfulRunTime, long lastFailedRunTime) {
         this(rescheduling.job, rescheduling.getUid(),
                 rescheduling.getSourcePackageName(), rescheduling.getSourceUserId(),
                 rescheduling.getSourceTag(), backoffAttempt, newEarliestRuntimeElapsedMillis,
-                newLatestRuntimeElapsedMillis);
+                newLatestRuntimeElapsedMillis,
+                lastSuccessfulRunTime, lastFailedRunTime);
     }
 
     /**
@@ -316,7 +336,8 @@
                     elapsedNow + job.getMaxExecutionDelayMillis() : NO_LATEST_RUNTIME;
         }
         return new JobStatus(job, callingUid, sourcePackageName, sourceUserId, tag, 0,
-                earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis);
+                earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis,
+                0 /* lastSuccessfulRunTime */, 0 /* lastFailedRunTime */);
     }
 
     public void enqueueWorkLocked(IActivityManager am, JobWorkItem work) {
@@ -669,6 +690,14 @@
         trackingControllers |= which;
     }
 
+    public long getLastSuccessfulRunTime() {
+        return mLastSuccessfulRunTime;
+    }
+
+    public long getLastFailedRunTime() {
+        return mLastFailedRunTime;
+    }
+
     public boolean shouldDump(int filterUid) {
         return filterUid == -1 || UserHandle.getAppId(getUid()) == filterUid
                 || UserHandle.getAppId(getSourceUid()) == filterUid;
@@ -1041,5 +1070,17 @@
         if (numFailures != 0) {
             pw.print(prefix); pw.print("Num failures: "); pw.println(numFailures);
         }
+        final Time t = new Time();
+        final String format = "%Y-%m-%d %H:%M:%S";
+        if (mLastSuccessfulRunTime != 0) {
+            pw.print(prefix); pw.print("Last successful run: ");
+            t.set(mLastSuccessfulRunTime);
+            pw.println(t.format(format));
+        }
+        if (mLastFailedRunTime != 0) {
+            pw.print(prefix); pw.print("Last failed run: ");
+            t.set(mLastFailedRunTime);
+            pw.println(t.format(format));
+        }
     }
 }
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 20711c0..11a4eb4 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -77,10 +77,12 @@
 
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.app.IBatteryStats;
+import com.android.internal.location.gnssmetrics.GnssMetrics;
 import com.android.internal.location.GpsNetInitiatedHandler;
 import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
 import com.android.internal.location.ProviderProperties;
 import com.android.internal.location.ProviderRequest;
+
 import com.android.server.power.BatterySaverPolicy;
 import com.android.server.power.BatterySaverPolicy.ServiceType;
 
@@ -417,6 +419,9 @@
     private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
     private boolean mItarSpeedLimitExceeded = false;
 
+    // GNSS Metrics
+    private GnssMetrics mGnssMetrics;
+
     private final IGnssStatusProvider mGnssStatusProvider = new IGnssStatusProvider.Stub() {
         @Override
         public void registerGnssStatusCallback(IGnssStatusListener callback) {
@@ -461,6 +466,11 @@
             // Always on, notify HAL so it can get data it needs
             sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
         }
+
+        @Override
+        public void onLost(Network network) {
+            sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
+        }
     };
 
     /**
@@ -533,7 +543,9 @@
                     loadPropertiesFromResource(context, mProperties);
                     String lpp_profile = mProperties.getProperty("LPP_PROFILE");
                     // set the persist property LPP_PROFILE for the value
-                    SystemProperties.set(LPP_PROFILE, lpp_profile);
+                    if (lpp_profile != null) {
+                        SystemProperties.set(LPP_PROFILE, lpp_profile);
+                    }
                 } else {
                     // reset the persist property
                     SystemProperties.set(LPP_PROFILE, "");
@@ -778,6 +790,7 @@
                 return isEnabled();
             }
         };
+        mGnssMetrics = new GnssMetrics();
 
         /*
         * A cycle of native_init() and native_cleanup() is needed so that callbacks are registered
@@ -808,11 +821,21 @@
     private void handleUpdateNetworkState(Network network) {
         // retrieve NetworkInfo for this UID
         NetworkInfo info = mConnMgr.getNetworkInfo(network);
-        if (info == null) {
-            return;
+
+        boolean networkAvailable = false;
+        boolean isConnected = false;
+        int type = ConnectivityManager.TYPE_NONE;
+        boolean isRoaming = false;
+        String apnName = null;
+
+        if (info != null) {
+            networkAvailable = info.isAvailable() && TelephonyManager.getDefault().getDataEnabled();
+            isConnected = info.isConnected();
+            type = info.getType();
+            isRoaming = info.isRoaming();
+            apnName = info.getExtraInfo();
         }
 
-        boolean isConnected = info.isConnected();
         if (DEBUG) {
             String message = String.format(
                     "UpdateNetworkState, state=%s, connected=%s, info=%s, capabilities=%S",
@@ -824,8 +847,6 @@
         }
 
         if (native_is_agps_ril_supported()) {
-            boolean dataEnabled = TelephonyManager.getDefault().getDataEnabled();
-            boolean networkAvailable = info.isAvailable() && dataEnabled;
             String defaultApn = getSelectedApn();
             if (defaultApn == null) {
                 defaultApn = "dummy-apn";
@@ -833,10 +854,10 @@
 
             native_update_network_state(
                     isConnected,
-                    info.getType(),
-                    info.isRoaming(),
+                    type,
+                    isRoaming,
                     networkAvailable,
-                    info.getExtraInfo(),
+                    apnName,
                     defaultApn);
         } else if (DEBUG) {
             Log.d(TAG, "Skipped network state update because GPS HAL AGPS-RIL is not  supported");
@@ -844,7 +865,6 @@
 
         if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
             if (isConnected) {
-                String apnName = info.getExtraInfo();
                 if (apnName == null) {
                     // assign a dummy value in the case of C2K as otherwise we will have a runtime
                     // exception in the following call to native_agps_data_conn_open
@@ -1190,21 +1210,29 @@
 
     @Override
     public int getStatus(Bundle extras) {
-        if (extras != null) {
-            extras.putInt("satellites", mSvCount);
-        }
+        setLocationExtras(extras);
         return mStatus;
     }
 
-    private void updateStatus(int status, int svCount) {
-        if (status != mStatus || svCount != mSvCount) {
+    private void updateStatus(int status, int svCount, int meanCn0, int maxCn0) {
+        if (status != mStatus || svCount != mSvCount || meanCn0 != mMeanCn0 || maxCn0 != mMaxCn0 ) {
             mStatus = status;
             mSvCount = svCount;
-            mLocationExtras.putInt("satellites", svCount);
+            mMeanCn0 = meanCn0;
+            mMaxCn0 = maxCn0;
+            setLocationExtras(mLocationExtras);
             mStatusUpdateTime = SystemClock.elapsedRealtime();
         }
     }
 
+    private void setLocationExtras(Bundle extras) {
+        if (extras != null) {
+            extras.putInt("satellites", mSvCount);
+            extras.putInt("meanCn0", mMeanCn0);
+            extras.putInt("maxCn0", mMaxCn0);
+        }
+    }
+
     @Override
     public long getStatusUpdateTime() {
         return mStatusUpdateTime;
@@ -1455,9 +1483,8 @@
             }
 
             // reset SV count to zero
-            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0);
+            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0, 0, 0);
             mFixRequestTime = SystemClock.elapsedRealtime();
-
             if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
                 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
                 // and our fix interval is not short
@@ -1479,7 +1506,7 @@
             mLastFixTime = 0;
 
             // reset SV count to zero
-            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0);
+            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0, 0, 0);
         }
     }
 
@@ -1508,6 +1535,7 @@
         if (mItarSpeedLimitExceeded) {
             Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
                     "  GPS/GNSS Navigation output blocked.");
+            mGnssMetrics.logReceivedLocationStatus(false);
             return;  // No output of location allowed
         }
 
@@ -1527,11 +1555,23 @@
             }
         }
 
+        mGnssMetrics.logReceivedLocationStatus(hasLatLong);
+        if (hasLatLong) {
+            if (location.hasAccuracy()) {
+                mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
+            }
+            if (mTimeToFirstFix > 0) {
+                int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
+                mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
+            }
+        }
+
         mLastFixTime = SystemClock.elapsedRealtime();
         // report time to first fix
         if (mTimeToFirstFix == 0 && hasLatLong) {
             mTimeToFirstFix = (int)(mLastFixTime - mFixRequestTime);
             if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
+            mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
 
             // notify status listeners
             mListenerHelper.onFirstFix(mTimeToFirstFix);
@@ -1552,7 +1592,7 @@
             Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
             intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);
             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-            updateStatus(LocationProvider.AVAILABLE, mSvCount);
+            updateStatus(LocationProvider.AVAILABLE, mSvCount, mMeanCn0, mMaxCn0);
         }
 
        if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
@@ -1613,18 +1653,27 @@
                 mSvAzimuths,
                 mSvCarrierFreqs);
 
+        // Log CN0 as part of GNSS metrics
+        mGnssMetrics.logCn0(mCn0s, svCount);
+
         if (VERBOSE) {
             Log.v(TAG, "SV count: " + svCount);
         }
-        // Calculate number of sets used in fix.
+        // Calculate number of satellites used in fix.
         int usedInFixCount = 0;
+        int maxCn0 = 0;
+        int meanCn0 = 0;
         for (int i = 0; i < svCount; i++) {
             if ((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
                 ++usedInFixCount;
+                if (mCn0s[i] > maxCn0) {
+                    maxCn0 = (int)mCn0s[i];
+                }
+                meanCn0 += mCn0s[i];
             }
             if (VERBOSE) {
                 Log.v(TAG, "svid: " + (mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
-                        " cn0: " + mCn0s[i]/10 +
+                        " cn0: " + mCn0s[i] +
                         " elev: " + mSvElevations[i] +
                         " azimuth: " + mSvAzimuths[i] +
                         " carrier frequency: " + mSvCarrierFreqs[i] +
@@ -1638,8 +1687,11 @@
                         ? "" : "F"));
             }
         }
-        // return number of sets used in fix instead of total
-        updateStatus(mStatus, usedInFixCount);
+        if (usedInFixCount > 0) {
+            meanCn0 /= usedInFixCount;
+        }
+        // return number of sats used in fix instead of total reported
+        updateStatus(mStatus, usedInFixCount, meanCn0, maxCn0);
 
         if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
             SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
@@ -1647,7 +1699,7 @@
             Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
             intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false);
             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount);
+            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount, mMeanCn0, mMaxCn0);
         }
     }
 
@@ -1704,20 +1756,32 @@
     }
 
     /**
-     * called from native code - Gps measurements callback
+     * called from native code - GNSS measurements callback
      */
     private void reportMeasurementData(GnssMeasurementsEvent event) {
         if (!mItarSpeedLimitExceeded) {
-            mGnssMeasurementsProvider.onMeasurementsAvailable(event);
+            // send to handler to allow native to return quickly
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mGnssMeasurementsProvider.onMeasurementsAvailable(event);
+                }
+            });
         }
     }
 
     /**
-     * called from native code - GPS navigation message callback
+     * called from native code - GNSS navigation message callback
      */
     private void reportNavigationMessage(GnssNavigationMessage event) {
         if (!mItarSpeedLimitExceeded) {
-            mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
+            // send to handler to allow native to return quickly
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
+                }
+            });
         }
     }
 
@@ -1813,6 +1877,25 @@
         };
     }
 
+    public interface GnssMetricsProvider {
+        /**
+         * Returns GNSS metrics as proto string
+         */
+        String getGnssMetricsAsProtoString();
+    }
+
+    /**
+     * @hide
+     */
+    public GnssMetricsProvider getGnssMetricsProvider() {
+        return new GnssMetricsProvider() {
+            @Override
+            public String getGnssMetricsAsProtoString() {
+                return mGnssMetrics.dumpGnssMetricsAsProtoString();
+            }
+        };
+    }
+
     /**
      * Initialize Batching if enabled
      */
@@ -2442,9 +2525,12 @@
         }
     }
 
+
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         StringBuilder s = new StringBuilder();
+        s.append("  mStarted=").append(mStarted).append('\n');
         s.append("  mFixInterval=").append(mFixInterval).append('\n');
         s.append("  mDisableGps (battery saver mode)=").append(mDisableGps).append('\n');
         s.append("  mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities));
@@ -2458,10 +2544,9 @@
         if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
         if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
         s.append(")\n");
-
-        s.append("  internal state: ").append(native_get_internal_state());
+        s.append(mGnssMetrics.dumpGnssMetricsAsText());
+        s.append("  native internal state: ").append(native_get_internal_state());
         s.append("\n");
-
         pw.append(s);
     }
 
@@ -2505,6 +2590,8 @@
     private float mSvAzimuths[] = new float[MAX_SVS];
     private float mSvCarrierFreqs[] = new float[MAX_SVS];
     private int mSvCount;
+    private int mMeanCn0;
+    private int mMaxCn0;
     // preallocated to avoid memory allocation in reportNmea()
     private byte[] mNmeaBuffer = new byte[120];
 
diff --git a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
index caf1d6c..924520b 100644
--- a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
@@ -54,9 +54,8 @@
     }
 
     public void onGpsEnabledChanged() {
-        if (tryUpdateRegistrationWithService()) {
-            updateResult();
-        }
+        tryUpdateRegistrationWithService();
+        updateResult();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
index 8d21928..df3c49b 100644
--- a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
+++ b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
@@ -55,9 +55,8 @@
     }
 
     public void onGpsEnabledChanged() {
-        if (tryUpdateRegistrationWithService()) {
-            updateResult();
-        }
+        tryUpdateRegistrationWithService();
+        updateResult();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/location/GpsXtraDownloader.java b/services/core/java/com/android/server/location/GpsXtraDownloader.java
index 62332c9..c012ee4 100644
--- a/services/core/java/com/android/server/location/GpsXtraDownloader.java
+++ b/services/core/java/com/android/server/location/GpsXtraDownloader.java
@@ -41,6 +41,7 @@
     private static final long MAXIMUM_CONTENT_LENGTH_BYTES = 1000000;  // 1MB.
     private static final String DEFAULT_USER_AGENT = "Android";
     private static final int CONNECTION_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(30);
+    private static final int READ_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(60);
 
     private final String[] mXtraServers;
     // to load balance our server requests
@@ -123,6 +124,7 @@
                     "x-wap-profile",
                     "http://www.openmobilealliance.org/tech/profiles/UAPROF/ccppschema-20021212#");
             connection.setConnectTimeout(CONNECTION_TIMEOUT_MS);
+            connection.setReadTimeout(READ_TIMEOUT_MS);
 
             connection.connect();
             int statusCode = connection.getResponseCode();
diff --git a/services/core/java/com/android/server/location/RemoteListenerHelper.java b/services/core/java/com/android/server/location/RemoteListenerHelper.java
index ec2828b..f51bc87 100644
--- a/services/core/java/com/android/server/location/RemoteListenerHelper.java
+++ b/services/core/java/com/android/server/location/RemoteListenerHelper.java
@@ -25,6 +25,7 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import java.lang.Runnable;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -45,7 +46,7 @@
 
     private final Map<IBinder, LinkedListener> mListenerMap = new HashMap<>();
 
-    private boolean mIsRegistered;
+    private boolean mIsRegistered;  // must access only on handler thread
     private boolean mHasIsSupported;
     private boolean mIsSupported;
 
@@ -83,12 +84,12 @@
             } else if (mHasIsSupported && !mIsSupported) {
                 result = RESULT_NOT_SUPPORTED;
             } else if (!isGpsEnabled()) {
-                result = RESULT_GPS_LOCATION_DISABLED;
-            } else if (!tryRegister()) {
                 // only attempt to register if GPS is enabled, otherwise we will register once GPS
                 // becomes available
-                result = RESULT_INTERNAL_ERROR;
+                result = RESULT_GPS_LOCATION_DISABLED;
             } else if (mHasIsSupported && mIsSupported) {
+                tryRegister();
+                // initially presume success, possible internal error could follow asynchornously
                 result = RESULT_SUCCESS;
             } else {
                 // at this point if the supported flag is not set, the notification will be sent
@@ -117,8 +118,8 @@
 
     protected abstract boolean isAvailableInPlatform();
     protected abstract boolean isGpsEnabled();
-    protected abstract boolean registerWithService();
-    protected abstract void unregisterFromService();
+    protected abstract boolean registerWithService(); // must access only on handler thread
+    protected abstract void unregisterFromService(); // must access only on handler thread
     protected abstract ListenerOperation<TListener> getHandlerOperation(int result);
 
     protected interface ListenerOperation<TListener extends IInterface> {
@@ -138,22 +139,16 @@
         }
     }
 
-    protected boolean tryUpdateRegistrationWithService() {
+    protected void tryUpdateRegistrationWithService() {
         synchronized (mListenerMap) {
             if (!isGpsEnabled()) {
                 tryUnregister();
-                return true;
+                return;
             }
             if (mListenerMap.isEmpty()) {
-                return true;
+                return;
             }
-            if (tryRegister()) {
-                // registration was successful, there is no need to update the state
-                return true;
-            }
-            ListenerOperation<TListener> operation = getHandlerOperation(RESULT_INTERNAL_ERROR);
-            foreachUnsafe(operation);
-            return false;
+            tryRegister();
         }
     }
 
@@ -180,19 +175,40 @@
         }
     }
 
-    private boolean tryRegister() {
-        if (!mIsRegistered) {
-            mIsRegistered = registerWithService();
-        }
-        return mIsRegistered;
+    private void tryRegister() {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                if (!mIsRegistered) {
+                    mIsRegistered = registerWithService();
+                }
+                if (!mIsRegistered) {
+                    // post back a failure
+                    mHandler.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            synchronized (mListenerMap) {
+                                ListenerOperation<TListener> operation = getHandlerOperation(RESULT_INTERNAL_ERROR);
+                                foreachUnsafe(operation);
+                            }
+                        }
+                    });
+                }
+            }
+        });
     }
 
     private void tryUnregister() {
-        if (!mIsRegistered) {
-            return;
-        }
-        unregisterFromService();
-        mIsRegistered = false;
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                if (!mIsRegistered) {
+                    return;
+                }
+                unregisterFromService();
+                mIsRegistered = false;
+            }
+        });
     }
 
     private int calculateCurrentResultUnsafe() {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
new file mode 100644
index 0000000..f8f8ffb
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -0,0 +1,2436 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.locksettings;
+
+import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
+import static android.Manifest.permission.READ_CONTACTS;
+import static android.content.Context.KEYGUARD_SERVICE;
+
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
+import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
+import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
+import static com.android.internal.widget.LockPatternUtils.USER_FRP;
+import static com.android.internal.widget.LockPatternUtils.frpCredentialEnabled;
+
+import android.annotation.UserIdInt;
+import android.app.ActivityManager;
+import android.app.IActivityManager;
+import android.app.KeyguardManager;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
+import android.app.admin.PasswordMetrics;
+import android.app.backup.BackupManager;
+import android.app.trust.IStrongAuthTracker;
+import android.app.trust.TrustManager;
+import android.content.BroadcastReceiver;
+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.content.res.Resources;
+import android.database.ContentObserver;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IProgressListener;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ServiceManager;
+import android.os.ShellCallback;
+import android.os.StrictMode;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.storage.IStorageManager;
+import android.os.storage.StorageManager;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.provider.Settings.SettingNotFoundException;
+import android.security.KeyStore;
+import android.security.keystore.AndroidKeyStoreProvider;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+import android.service.gatekeeper.GateKeeperResponse;
+import android.service.gatekeeper.IGateKeeperService;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.util.Preconditions;
+import com.android.internal.widget.ICheckCredentialProgressCallback;
+import com.android.internal.widget.ILockSettings;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.VerifyCredentialResponse;
+import com.android.server.SystemService;
+import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
+import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;
+import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationToken;
+import com.android.server.locksettings.LockSettingsStorage.PersistentData;
+
+import libcore.util.HexEncoding;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+
+/**
+ * Keeps the lock pattern/password data and related settings for each user. Used by
+ * LockPatternUtils. Needs to be a service because Settings app also needs to be able to save
+ * lockscreen information for secondary users.
+ *
+ * @hide
+ */
+public class LockSettingsService extends ILockSettings.Stub {
+    private static final String TAG = "LockSettingsService";
+    private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE;
+    private static final boolean DEBUG = false;
+
+    private static final int PROFILE_KEY_IV_SIZE = 12;
+    private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
+    private static final int SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT = 1;
+
+    // Order of holding lock: mSeparateChallengeLock -> mSpManager -> this
+    // Do not call into ActivityManager while holding mSpManager lock.
+    private final Object mSeparateChallengeLock = new Object();
+
+    private final DeviceProvisionedObserver mDeviceProvisionedObserver =
+            new DeviceProvisionedObserver();
+
+    private final Injector mInjector;
+    private final Context mContext;
+    private final Handler mHandler;
+    @VisibleForTesting
+    protected final LockSettingsStorage mStorage;
+    private final LockSettingsStrongAuth mStrongAuth;
+    private final SynchronizedStrongAuthTracker mStrongAuthTracker;
+
+    private final LockPatternUtils mLockPatternUtils;
+    private final NotificationManager mNotificationManager;
+    private final UserManager mUserManager;
+    private final IActivityManager mActivityManager;
+    private final SyntheticPasswordManager mSpManager;
+
+    private final KeyStore mKeyStore;
+
+    private boolean mFirstCallToVold;
+    protected IGateKeeperService mGateKeeperService;
+
+    /**
+     * The UIDs that are used for system credential storage in keystore.
+     */
+    private static final int[] SYSTEM_CREDENTIAL_UIDS = {
+            Process.WIFI_UID, Process.VPN_UID,
+            Process.ROOT_UID, Process.SYSTEM_UID };
+
+    // This class manages life cycle events for encrypted users on File Based Encryption (FBE)
+    // devices. The most basic of these is to show/hide notifications about missing features until
+    // the user unlocks the account and credential-encrypted storage is available.
+    public static final class Lifecycle extends SystemService {
+        private LockSettingsService mLockSettingsService;
+
+        public Lifecycle(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onStart() {
+            AndroidKeyStoreProvider.install();
+            mLockSettingsService = new LockSettingsService(getContext());
+            publishBinderService("lock_settings", mLockSettingsService);
+        }
+
+        @Override
+        public void onStartUser(int userHandle) {
+            mLockSettingsService.onStartUser(userHandle);
+        }
+
+        @Override
+        public void onUnlockUser(int userHandle) {
+            mLockSettingsService.onUnlockUser(userHandle);
+        }
+
+        @Override
+        public void onCleanupUser(int userHandle) {
+            mLockSettingsService.onCleanupUser(userHandle);
+        }
+    }
+
+    @VisibleForTesting
+    protected static class SynchronizedStrongAuthTracker
+            extends LockPatternUtils.StrongAuthTracker {
+        public SynchronizedStrongAuthTracker(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected void handleStrongAuthRequiredChanged(int strongAuthFlags, int userId) {
+            synchronized (this) {
+                super.handleStrongAuthRequiredChanged(strongAuthFlags, userId);
+            }
+        }
+
+        @Override
+        public int getStrongAuthForUser(int userId) {
+            synchronized (this) {
+                return super.getStrongAuthForUser(userId);
+            }
+        }
+
+        void register(LockSettingsStrongAuth strongAuth) {
+            strongAuth.registerStrongAuthTracker(this.mStub);
+        }
+    }
+
+    /**
+     * Tie managed profile to primary profile if it is in unified mode and not tied before.
+     *
+     * @param managedUserId Managed profile user Id
+     * @param managedUserPassword Managed profile original password (when it has separated lock).
+     *            NULL when it does not have a separated lock before.
+     */
+    public void tieManagedProfileLockIfNecessary(int managedUserId, String managedUserPassword) {
+        if (DEBUG) Slog.v(TAG, "Check child profile lock for user: " + managedUserId);
+        // Only for managed profile
+        if (!mUserManager.getUserInfo(managedUserId).isManagedProfile()) {
+            return;
+        }
+        // Do not tie managed profile when work challenge is enabled
+        if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
+            return;
+        }
+        // Do not tie managed profile to parent when it's done already
+        if (mStorage.hasChildProfileLock(managedUserId)) {
+            return;
+        }
+        // Do not tie it to parent when parent does not have a screen lock
+        final int parentId = mUserManager.getProfileParent(managedUserId).id;
+        if (!isUserSecure(parentId)) {
+            if (DEBUG) Slog.v(TAG, "Parent does not have a screen lock");
+            return;
+        }
+        // Do not tie when the parent has no SID (but does have a screen lock).
+        // This can only happen during an upgrade path where SID is yet to be
+        // generated when the user unlocks for the first time.
+        try {
+            if (getGateKeeperService().getSecureUserId(parentId) == 0) {
+                return;
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to talk to GateKeeper service", e);
+            return;
+        }
+        if (DEBUG) Slog.v(TAG, "Tie managed profile to parent now!");
+        byte[] randomLockSeed = new byte[] {};
+        try {
+            randomLockSeed = SecureRandom.getInstance("SHA1PRNG").generateSeed(40);
+            String newPassword = String.valueOf(HexEncoding.encode(randomLockSeed));
+            final int quality = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
+            setLockCredentialInternal(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    managedUserPassword, quality, managedUserId);
+            // We store a private credential for the managed user that's unlocked by the primary
+            // account holder's credential. As such, the user will never be prompted to enter this
+            // password directly, so we always store a password.
+            setLong(LockPatternUtils.PASSWORD_TYPE_KEY, quality, managedUserId);
+            tieProfileLockToParent(managedUserId, newPassword);
+        } catch (NoSuchAlgorithmException | RemoteException e) {
+            Slog.e(TAG, "Fail to tie managed profile", e);
+            // Nothing client can do to fix this issue, so we do not throw exception out
+        }
+    }
+
+    static class Injector {
+
+        protected Context mContext;
+
+        public Injector(Context context) {
+            mContext = context;
+        }
+
+        public Context getContext() {
+            return mContext;
+        }
+
+        public Handler getHandler() {
+            return new Handler();
+        }
+
+        public LockSettingsStorage getStorage() {
+            final LockSettingsStorage storage = new LockSettingsStorage(mContext);
+            storage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
+                @Override
+                public void initialize(SQLiteDatabase db) {
+                    // Get the lockscreen default from a system property, if available
+                    boolean lockScreenDisable = SystemProperties.getBoolean(
+                            "ro.lockscreen.disable.default", false);
+                    if (lockScreenDisable) {
+                        storage.writeKeyValue(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0);
+                    }
+                }
+            });
+            return storage;
+        }
+
+        public LockSettingsStrongAuth getStrongAuth() {
+            return new LockSettingsStrongAuth(mContext);
+        }
+
+        public SynchronizedStrongAuthTracker getStrongAuthTracker() {
+            return new SynchronizedStrongAuthTracker(mContext);
+        }
+
+        public IActivityManager getActivityManager() {
+            return ActivityManager.getService();
+        }
+
+        public LockPatternUtils getLockPatternUtils() {
+            return new LockPatternUtils(mContext);
+        }
+
+        public NotificationManager getNotificationManager() {
+            return (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        }
+
+        public UserManager getUserManager() {
+            return (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        }
+
+        public DevicePolicyManager getDevicePolicyManager() {
+            return (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        }
+
+        public KeyStore getKeyStore() {
+            return KeyStore.getInstance();
+        }
+
+        public IStorageManager getStorageManager() {
+            final IBinder service = ServiceManager.getService("mount");
+            if (service != null) {
+                return IStorageManager.Stub.asInterface(service);
+            }
+            return null;
+        }
+
+        public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) {
+            return new SyntheticPasswordManager(storage, getUserManager());
+        }
+
+        public int binderGetCallingUid() {
+            return Binder.getCallingUid();
+        }
+    }
+
+    public LockSettingsService(Context context) {
+        this(new Injector(context));
+    }
+
+    @VisibleForTesting
+    protected LockSettingsService(Injector injector) {
+        mInjector = injector;
+        mContext = injector.getContext();
+        mKeyStore = injector.getKeyStore();
+        mHandler = injector.getHandler();
+        mStrongAuth = injector.getStrongAuth();
+        mActivityManager = injector.getActivityManager();
+
+        mLockPatternUtils = injector.getLockPatternUtils();
+        mFirstCallToVold = true;
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_USER_ADDED);
+        filter.addAction(Intent.ACTION_USER_STARTING);
+        filter.addAction(Intent.ACTION_USER_REMOVED);
+        injector.getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter,
+                null, null);
+
+        mStorage = injector.getStorage();
+        mNotificationManager = injector.getNotificationManager();
+        mUserManager = injector.getUserManager();
+        mStrongAuthTracker = injector.getStrongAuthTracker();
+        mStrongAuthTracker.register(mStrongAuth);
+
+        mSpManager = injector.getSyntheticPasswordManager(mStorage);
+    }
+
+    /**
+     * If the account is credential-encrypted, show notification requesting the user to unlock the
+     * device.
+     */
+    private void maybeShowEncryptionNotificationForUser(@UserIdInt int userId) {
+        final UserInfo user = mUserManager.getUserInfo(userId);
+        if (!user.isManagedProfile()) {
+            // When the user is locked, we communicate it loud-and-clear
+            // on the lockscreen; we only show a notification below for
+            // locked managed profiles.
+            return;
+        }
+
+        final UserHandle userHandle = user.getUserHandle();
+        final boolean isSecure = isUserSecure(userId);
+        if (isSecure && !mUserManager.isUserUnlockingOrUnlocked(userHandle)) {
+            UserInfo parent = mUserManager.getProfileParent(userId);
+            if (parent != null &&
+                    mUserManager.isUserUnlockingOrUnlocked(parent.getUserHandle()) &&
+                    !mUserManager.isQuietModeEnabled(userHandle)) {
+                // Only show notifications for managed profiles once their parent
+                // user is unlocked.
+                showEncryptionNotificationForProfile(userHandle);
+            }
+        }
+    }
+
+    private void showEncryptionNotificationForProfile(UserHandle user) {
+        Resources r = mContext.getResources();
+        CharSequence title = r.getText(
+                com.android.internal.R.string.user_encrypted_title);
+        CharSequence message = r.getText(
+                com.android.internal.R.string.profile_encrypted_message);
+        CharSequence detail = r.getText(
+                com.android.internal.R.string.profile_encrypted_detail);
+
+        final KeyguardManager km = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE);
+        final Intent unlockIntent = km.createConfirmDeviceCredentialIntent(null, null,
+                user.getIdentifier());
+        if (unlockIntent == null) {
+            return;
+        }
+        unlockIntent.setFlags(
+                Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        PendingIntent intent = PendingIntent.getActivity(mContext, 0, unlockIntent,
+                PendingIntent.FLAG_UPDATE_CURRENT);
+
+        showEncryptionNotification(user, title, message, detail, intent);
+    }
+
+    private void showEncryptionNotification(UserHandle user, CharSequence title,
+            CharSequence message, CharSequence detail, PendingIntent intent) {
+        if (DEBUG) Slog.v(TAG, "showing encryption notification, user: " + user.getIdentifier());
+
+        // Suppress all notifications on non-FBE devices for now
+        if (!StorageManager.isFileEncryptedNativeOrEmulated()) return;
+
+        Notification notification =
+                new Notification.Builder(mContext, SystemNotificationChannels.SECURITY)
+                        .setSmallIcon(com.android.internal.R.drawable.ic_user_secure)
+                        .setWhen(0)
+                        .setOngoing(true)
+                        .setTicker(title)
+                        .setColor(mContext.getColor(
+                                com.android.internal.R.color.system_notification_accent_color))
+                        .setContentTitle(title)
+                        .setContentText(message)
+                        .setSubText(detail)
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .setContentIntent(intent)
+                        .build();
+        mNotificationManager.notifyAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION,
+            notification, user);
+    }
+
+    private void hideEncryptionNotification(UserHandle userHandle) {
+        if (DEBUG) Slog.v(TAG, "hide encryption notification, user: " + userHandle.getIdentifier());
+        mNotificationManager.cancelAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION,
+            userHandle);
+    }
+
+    public void onCleanupUser(int userId) {
+        hideEncryptionNotification(new UserHandle(userId));
+    }
+
+    public void onStartUser(final int userId) {
+        maybeShowEncryptionNotificationForUser(userId);
+    }
+
+    public void onUnlockUser(final int userId) {
+        // Perform tasks which require locks in LSS on a handler, as we are callbacks from
+        // ActivityManager.unlockUser()
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                // Hide notification first, as tie managed profile lock takes time
+                hideEncryptionNotification(new UserHandle(userId));
+
+                // Now we have unlocked the parent user we should show notifications
+                // about any profiles that exist.
+                List<UserInfo> profiles = mUserManager.getProfiles(userId);
+                for (int i = 0; i < profiles.size(); i++) {
+                    UserInfo profile = profiles.get(i);
+                    final boolean isSecure = isUserSecure(profile.id);
+                    if (isSecure && profile.isManagedProfile()) {
+                        UserHandle userHandle = profile.getUserHandle();
+                        if (!mUserManager.isUserUnlockingOrUnlocked(userHandle) &&
+                                !mUserManager.isQuietModeEnabled(userHandle)) {
+                            showEncryptionNotificationForProfile(userHandle);
+                        }
+                    }
+                }
+
+                if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+                    tieManagedProfileLockIfNecessary(userId, null);
+                }
+            }
+        });
+    }
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) {
+                // Notify keystore that a new user was added.
+                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                if (userHandle > UserHandle.USER_SYSTEM) {
+                    removeUser(userHandle, /* unknownUser= */ true);
+                }
+                final KeyStore ks = KeyStore.getInstance();
+                final UserInfo parentInfo = mUserManager.getProfileParent(userHandle);
+                final int parentHandle = parentInfo != null ? parentInfo.id : -1;
+                ks.onUserAdded(userHandle, parentHandle);
+            } else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
+                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                mStorage.prefetchUser(userHandle);
+            } else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
+                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                if (userHandle > 0) {
+                    removeUser(userHandle, /* unknownUser= */ false);
+                }
+            }
+        }
+    };
+
+    @Override // binder interface
+    public void systemReady() {
+        migrateOldData();
+        try {
+            getGateKeeperService();
+            mSpManager.initWeaverService();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failure retrieving IGateKeeperService", e);
+        }
+        mDeviceProvisionedObserver.onSystemReady();
+        // TODO: maybe skip this for split system user mode.
+        mStorage.prefetchUser(UserHandle.USER_SYSTEM);
+    }
+
+    private void migrateOldData() {
+        try {
+            // These Settings moved before multi-user was enabled, so we only have to do it for the
+            // root user.
+            if (getString("migrated", null, 0) == null) {
+                final ContentResolver cr = mContext.getContentResolver();
+                for (String validSetting : VALID_SETTINGS) {
+                    String value = Settings.Secure.getString(cr, validSetting);
+                    if (value != null) {
+                        setString(validSetting, value, 0);
+                    }
+                }
+                // No need to move the password / pattern files. They're already in the right place.
+                setString("migrated", "true", 0);
+                Slog.i(TAG, "Migrated lock settings to new location");
+            }
+
+            // These Settings changed after multi-user was enabled, hence need to be moved per user.
+            if (getString("migrated_user_specific", null, 0) == null) {
+                final ContentResolver cr = mContext.getContentResolver();
+                List<UserInfo> users = mUserManager.getUsers();
+                for (int user = 0; user < users.size(); user++) {
+                    // Migrate owner info
+                    final int userId = users.get(user).id;
+                    final String OWNER_INFO = Secure.LOCK_SCREEN_OWNER_INFO;
+                    String ownerInfo = Settings.Secure.getStringForUser(cr, OWNER_INFO, userId);
+                    if (!TextUtils.isEmpty(ownerInfo)) {
+                        setString(OWNER_INFO, ownerInfo, userId);
+                        Settings.Secure.putStringForUser(cr, OWNER_INFO, "", userId);
+                    }
+
+                    // Migrate owner info enabled. Note there was a bug where older platforms only
+                    // stored this value if the checkbox was toggled at least once. The code detects
+                    // this case by handling the exception.
+                    final String OWNER_INFO_ENABLED = Secure.LOCK_SCREEN_OWNER_INFO_ENABLED;
+                    boolean enabled;
+                    try {
+                        int ivalue = Settings.Secure.getIntForUser(cr, OWNER_INFO_ENABLED, userId);
+                        enabled = ivalue != 0;
+                        setLong(OWNER_INFO_ENABLED, enabled ? 1 : 0, userId);
+                    } catch (SettingNotFoundException e) {
+                        // Setting was never stored. Store it if the string is not empty.
+                        if (!TextUtils.isEmpty(ownerInfo)) {
+                            setLong(OWNER_INFO_ENABLED, 1, userId);
+                        }
+                    }
+                    Settings.Secure.putIntForUser(cr, OWNER_INFO_ENABLED, 0, userId);
+                }
+                // No need to move the password / pattern files. They're already in the right place.
+                setString("migrated_user_specific", "true", 0);
+                Slog.i(TAG, "Migrated per-user lock settings to new location");
+            }
+
+            // Migrates biometric weak such that the fallback mechanism becomes the primary.
+            if (getString("migrated_biometric_weak", null, 0) == null) {
+                List<UserInfo> users = mUserManager.getUsers();
+                for (int i = 0; i < users.size(); i++) {
+                    int userId = users.get(i).id;
+                    long type = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+                            userId);
+                    long alternateType = getLong(LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+                            userId);
+                    if (type == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) {
+                        setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                                alternateType,
+                                userId);
+                    }
+                    setLong(LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+                            userId);
+                }
+                setString("migrated_biometric_weak", "true", 0);
+                Slog.i(TAG, "Migrated biometric weak to use the fallback instead");
+            }
+
+            // Migrates lockscreen.disabled. Prior to M, the flag was ignored when more than one
+            // user was present on the system, so if we're upgrading to M and there is more than one
+            // user we disable the flag to remain consistent.
+            if (getString("migrated_lockscreen_disabled", null, 0) == null) {
+                final List<UserInfo> users = mUserManager.getUsers();
+                final int userCount = users.size();
+                int switchableUsers = 0;
+                for (int i = 0; i < userCount; i++) {
+                    if (users.get(i).supportsSwitchTo()) {
+                        switchableUsers++;
+                    }
+                }
+
+                if (switchableUsers > 1) {
+                    for (int i = 0; i < userCount; i++) {
+                        int id = users.get(i).id;
+
+                        if (getBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id)) {
+                            setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
+                        }
+                    }
+                }
+
+                setString("migrated_lockscreen_disabled", "true", 0);
+                Slog.i(TAG, "Migrated lockscreen disabled flag");
+            }
+
+            final List<UserInfo> users = mUserManager.getUsers();
+            for (int i = 0; i < users.size(); i++) {
+                final UserInfo userInfo = users.get(i);
+                if (userInfo.isManagedProfile() && mStorage.hasChildProfileLock(userInfo.id)) {
+                    // When managed profile has a unified lock, the password quality stored has 2
+                    // possibilities only.
+                    // 1). PASSWORD_QUALITY_UNSPECIFIED, which is upgraded from dp2, and we are
+                    // going to set it back to PASSWORD_QUALITY_ALPHANUMERIC.
+                    // 2). PASSWORD_QUALITY_ALPHANUMERIC, which is the actual password quality for
+                    // unified lock.
+                    final long quality = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userInfo.id);
+                    if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
+                        // Only possible when it's upgraded from nyc dp3
+                        Slog.i(TAG, "Migrated tied profile lock type");
+                        setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                                DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, userInfo.id);
+                    } else if (quality != DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC) {
+                        // It should not happen
+                        Slog.e(TAG, "Invalid tied profile lock type: " + quality);
+                    }
+                }
+                try {
+                    final String alias = LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userInfo.id;
+                    java.security.KeyStore keyStore =
+                            java.security.KeyStore.getInstance("AndroidKeyStore");
+                    keyStore.load(null);
+                    if (keyStore.containsAlias(alias)) {
+                        keyStore.deleteEntry(alias);
+                    }
+                } catch (KeyStoreException | NoSuchAlgorithmException |
+                        CertificateException | IOException e) {
+                    Slog.e(TAG, "Unable to remove tied profile key", e);
+                }
+            }
+
+            boolean isWatch = mContext.getPackageManager().hasSystemFeature(
+                    PackageManager.FEATURE_WATCH);
+            // Wear used to set DISABLE_LOCKSCREEN to 'true', but because Wear now allows accounts
+            // and device management the lockscreen must be re-enabled now for users that upgrade.
+            if (isWatch && getString("migrated_wear_lockscreen_disabled", null, 0) == null) {
+                final int userCount = users.size();
+                for (int i = 0; i < userCount; i++) {
+                    int id = users.get(i).id;
+                    setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
+                }
+                setString("migrated_wear_lockscreen_disabled", "true", 0);
+                Slog.i(TAG, "Migrated lockscreen_disabled for Wear devices");
+            }
+        } catch (RemoteException re) {
+            Slog.e(TAG, "Unable to migrate old data", re);
+        }
+    }
+
+    private final void checkWritePermission(int userId) {
+        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsWrite");
+    }
+
+    private final void checkPasswordReadPermission(int userId) {
+        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsRead");
+    }
+
+    private final void checkReadPermission(String requestedKey, int userId) {
+        final int callingUid = Binder.getCallingUid();
+
+        for (int i = 0; i < READ_CONTACTS_PROTECTED_SETTINGS.length; i++) {
+            String key = READ_CONTACTS_PROTECTED_SETTINGS[i];
+            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_CONTACTS)
+                    != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException("uid=" + callingUid
+                        + " needs permission " + READ_CONTACTS + " to read "
+                        + requestedKey + " for user " + userId);
+            }
+        }
+
+        for (int i = 0; i < READ_PASSWORD_PROTECTED_SETTINGS.length; i++) {
+            String key = READ_PASSWORD_PROTECTED_SETTINGS[i];
+            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(PERMISSION)
+                    != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException("uid=" + callingUid
+                        + " needs permission " + PERMISSION + " to read "
+                        + requestedKey + " for user " + userId);
+            }
+        }
+    }
+
+    @Override
+    public boolean getSeparateProfileChallengeEnabled(int userId) throws RemoteException {
+        checkReadPermission(SEPARATE_PROFILE_CHALLENGE_KEY, userId);
+        synchronized (mSeparateChallengeLock) {
+            return getBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, false, userId);
+        }
+    }
+
+    @Override
+    public void setSeparateProfileChallengeEnabled(int userId, boolean enabled,
+            String managedUserPassword) throws RemoteException {
+        checkWritePermission(userId);
+        synchronized (mSeparateChallengeLock) {
+            setBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, enabled, userId);
+            if (enabled) {
+                mStorage.removeChildProfileLock(userId);
+                removeKeystoreProfileKey(userId);
+            } else {
+                tieManagedProfileLockIfNecessary(userId, managedUserPassword);
+            }
+        }
+    }
+
+    @Override
+    public void setBoolean(String key, boolean value, int userId) throws RemoteException {
+        checkWritePermission(userId);
+        setStringUnchecked(key, userId, value ? "1" : "0");
+    }
+
+    @Override
+    public void setLong(String key, long value, int userId) throws RemoteException {
+        checkWritePermission(userId);
+        setStringUnchecked(key, userId, Long.toString(value));
+    }
+
+    @Override
+    public void setString(String key, String value, int userId) throws RemoteException {
+        checkWritePermission(userId);
+        setStringUnchecked(key, userId, value);
+    }
+
+    private void setStringUnchecked(String key, int userId, String value) {
+        Preconditions.checkArgument(userId != USER_FRP, "cannot store lock settings for FRP user");
+
+        mStorage.writeKeyValue(key, value, userId);
+        if (ArrayUtils.contains(SETTINGS_TO_BACKUP, key)) {
+            BackupManager.dataChanged("com.android.providers.settings");
+        }
+    }
+
+    @Override
+    public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException {
+        checkReadPermission(key, userId);
+        String value = getStringUnchecked(key, null, userId);
+        return TextUtils.isEmpty(value) ?
+                defaultValue : (value.equals("1") || value.equals("true"));
+    }
+
+    @Override
+    public long getLong(String key, long defaultValue, int userId) throws RemoteException {
+        checkReadPermission(key, userId);
+        String value = getStringUnchecked(key, null, userId);
+        return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value);
+    }
+
+    @Override
+    public String getString(String key, String defaultValue, int userId) throws RemoteException {
+        checkReadPermission(key, userId);
+        return getStringUnchecked(key, defaultValue, userId);
+    }
+
+    public String getStringUnchecked(String key, String defaultValue, int userId) {
+        if (Settings.Secure.LOCK_PATTERN_ENABLED.equals(key)) {
+            long ident = Binder.clearCallingIdentity();
+            try {
+                return mLockPatternUtils.isLockPatternEnabled(userId) ? "1" : "0";
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        if (userId == USER_FRP) {
+            return getFrpStringUnchecked(key);
+        }
+
+        if (LockPatternUtils.LEGACY_LOCK_PATTERN_ENABLED.equals(key)) {
+            key = Settings.Secure.LOCK_PATTERN_ENABLED;
+        }
+
+        return mStorage.readKeyValue(key, defaultValue, userId);
+    }
+
+    private String getFrpStringUnchecked(String key) {
+        if (LockPatternUtils.PASSWORD_TYPE_KEY.equals(key)) {
+            return String.valueOf(readFrpPasswordQuality());
+        }
+        return null;
+    }
+
+    private int readFrpPasswordQuality() {
+        return mStorage.readPersistentDataBlock().qualityForUi;
+    }
+
+    @Override
+    public boolean havePassword(int userId) throws RemoteException {
+        synchronized (mSpManager) {
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                long handle = getSyntheticPasswordHandleLocked(userId);
+                return mSpManager.getCredentialType(handle, userId) ==
+                        LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+            }
+        }
+        // Do we need a permissions check here?
+        return mStorage.hasPassword(userId);
+    }
+
+    @Override
+    public boolean havePattern(int userId) throws RemoteException {
+        synchronized (mSpManager) {
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                long handle = getSyntheticPasswordHandleLocked(userId);
+                return mSpManager.getCredentialType(handle, userId) ==
+                        LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+            }
+        }
+        // Do we need a permissions check here?
+        return mStorage.hasPattern(userId);
+    }
+
+    private boolean isUserSecure(int userId) {
+        synchronized (mSpManager) {
+            try {
+                if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                    long handle = getSyntheticPasswordHandleLocked(userId);
+                    return mSpManager.getCredentialType(handle, userId) !=
+                            LockPatternUtils.CREDENTIAL_TYPE_NONE;
+                }
+            } catch (RemoteException e) {
+                // fall through
+            }
+        }
+        return mStorage.hasCredential(userId);
+    }
+
+    private void setKeystorePassword(String password, int userHandle) {
+        final KeyStore ks = KeyStore.getInstance();
+        ks.onUserPasswordChanged(userHandle, password);
+    }
+
+    private void unlockKeystore(String password, int userHandle) {
+        if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle);
+        final KeyStore ks = KeyStore.getInstance();
+        ks.unlock(userHandle, password);
+    }
+
+    @VisibleForTesting
+    protected String getDecryptedPasswordForTiedProfile(int userId)
+            throws KeyStoreException, UnrecoverableKeyException,
+            NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException,
+            CertificateException, IOException {
+        if (DEBUG) Slog.v(TAG, "Get child profile decrytped key");
+        byte[] storedData = mStorage.readChildProfileLock(userId);
+        if (storedData == null) {
+            throw new FileNotFoundException("Child profile lock file not found");
+        }
+        byte[] iv = Arrays.copyOfRange(storedData, 0, PROFILE_KEY_IV_SIZE);
+        byte[] encryptedPassword = Arrays.copyOfRange(storedData, PROFILE_KEY_IV_SIZE,
+                storedData.length);
+        byte[] decryptionResult;
+        java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
+        keyStore.load(null);
+        SecretKey decryptionKey = (SecretKey) keyStore.getKey(
+                LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId, null);
+
+        Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+                + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
+
+        cipher.init(Cipher.DECRYPT_MODE, decryptionKey, new GCMParameterSpec(128, iv));
+        decryptionResult = cipher.doFinal(encryptedPassword);
+        return new String(decryptionResult, StandardCharsets.UTF_8);
+    }
+
+    private void unlockChildProfile(int profileHandle) throws RemoteException {
+        try {
+            doVerifyCredential(getDecryptedPasswordForTiedProfile(profileHandle),
+                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    false, 0 /* no challenge */, profileHandle, null /* progressCallback */);
+        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                | NoSuchAlgorithmException | NoSuchPaddingException
+                | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                | BadPaddingException | CertificateException | IOException e) {
+            if (e instanceof FileNotFoundException) {
+                Slog.i(TAG, "Child profile key not found");
+            } else {
+                Slog.e(TAG, "Failed to decrypt child profile key", e);
+            }
+        }
+    }
+
+    private void unlockUser(int userId, byte[] token, byte[] secret) {
+        // TODO: make this method fully async so we can update UI with progress strings
+        final CountDownLatch latch = new CountDownLatch(1);
+        final IProgressListener listener = new IProgressListener.Stub() {
+            @Override
+            public void onStarted(int id, Bundle extras) throws RemoteException {
+                Log.d(TAG, "unlockUser started");
+            }
+
+            @Override
+            public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
+                Log.d(TAG, "unlockUser progress " + progress);
+            }
+
+            @Override
+            public void onFinished(int id, Bundle extras) throws RemoteException {
+                Log.d(TAG, "unlockUser finished");
+                latch.countDown();
+            }
+        };
+
+        try {
+            mActivityManager.unlockUser(userId, token, secret, listener);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+
+        try {
+            latch.await(15, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+        try {
+            if (!mUserManager.getUserInfo(userId).isManagedProfile()) {
+                final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+                for (UserInfo pi : profiles) {
+                    // Unlock managed profile with unified lock
+                    if (pi.isManagedProfile()
+                            && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
+                            && mStorage.hasChildProfileLock(pi.id)
+                            && mUserManager.isUserRunning(pi.id)) {
+                        unlockChildProfile(pi.id);
+                    }
+                }
+            }
+        } catch (RemoteException e) {
+            Log.d(TAG, "Failed to unlock child profile", e);
+        }
+    }
+
+    private Map<Integer, String> getDecryptedPasswordsForAllTiedProfiles(int userId) {
+        if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+            return null;
+        }
+        Map<Integer, String> result = new ArrayMap<Integer, String>();
+        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+        final int size = profiles.size();
+        for (int i = 0; i < size; i++) {
+            final UserInfo profile = profiles.get(i);
+            if (!profile.isManagedProfile()) {
+                continue;
+            }
+            final int managedUserId = profile.id;
+            if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
+                continue;
+            }
+            try {
+                result.put(userId, getDecryptedPasswordForTiedProfile(userId));
+            } catch (KeyStoreException | UnrecoverableKeyException | NoSuchAlgorithmException
+                    | NoSuchPaddingException | InvalidKeyException
+                    | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                    | BadPaddingException | CertificateException | IOException e) {
+                // ignore
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Synchronize all profile's work challenge of the given user if it's unified: tie or clear them
+     * depending on the parent user's secure state.
+     *
+     * When clearing tied work challenges, a pre-computed password table for profiles are required,
+     * since changing password for profiles requires existing password, and existing passwords can
+     * only be computed before the parent user's password is cleared.
+     *
+     * Strictly this is a recursive function, since setLockCredentialInternal ends up calling this
+     * method again on profiles. However the recursion is guaranteed to terminate as this method
+     * terminates when the user is a managed profile.
+     */
+    private void synchronizeUnifiedWorkChallengeForProfiles(int userId,
+            Map<Integer, String> profilePasswordMap) throws RemoteException {
+        if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+            return;
+        }
+        final boolean isSecure = isUserSecure(userId);
+        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+        final int size = profiles.size();
+        for (int i = 0; i < size; i++) {
+            final UserInfo profile = profiles.get(i);
+            if (profile.isManagedProfile()) {
+                final int managedUserId = profile.id;
+                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
+                    continue;
+                }
+                if (isSecure) {
+                    tieManagedProfileLockIfNecessary(managedUserId, null);
+                } else {
+                    // We use cached work profile password computed before clearing the parent's
+                    // credential, otherwise they get lost
+                    if (profilePasswordMap != null && profilePasswordMap.containsKey(managedUserId)) {
+                        setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
+                                profilePasswordMap.get(managedUserId),
+                                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId);
+                    } else {
+                        Slog.wtf(TAG, "clear tied profile challenges, but no password supplied.");
+                        // Supplying null here would lead to untrusted credential change
+                        setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, null,
+                                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId);
+                    }
+                    mStorage.removeChildProfileLock(managedUserId);
+                    removeKeystoreProfileKey(managedUserId);
+                }
+            }
+        }
+    }
+
+    private boolean isManagedProfileWithUnifiedLock(int userId) {
+        return mUserManager.getUserInfo(userId).isManagedProfile()
+                && !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
+    }
+
+    private boolean isManagedProfileWithSeparatedLock(int userId) {
+        return mUserManager.getUserInfo(userId).isManagedProfile()
+                && mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
+    }
+
+    // This method should be called by LockPatternUtil only, all internal methods in this class
+    // should call setLockCredentialInternal.
+    @Override
+    public void setLockCredential(String credential, int type, String savedCredential,
+            int requestedQuality, int userId)
+            throws RemoteException {
+        checkWritePermission(userId);
+        synchronized (mSeparateChallengeLock) {
+            setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId);
+            setSeparateProfileChallengeEnabled(userId, true, null);
+            notifyPasswordChanged(userId);
+        }
+    }
+
+    private void setLockCredentialInternal(String credential, int credentialType,
+            String savedCredential, int requestedQuality, int userId) throws RemoteException {
+        // Normalize savedCredential and credential such that empty string is always represented
+        // as null.
+        if (TextUtils.isEmpty(savedCredential)) {
+            savedCredential = null;
+        }
+        if (TextUtils.isEmpty(credential)) {
+            credential = null;
+        }
+        synchronized (mSpManager) {
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
+                        requestedQuality, userId);
+                return;
+            }
+        }
+
+        if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+            if (credential != null) {
+                Slog.wtf(TAG, "CredentialType is none, but credential is non-null.");
+            }
+            clearUserKeyProtection(userId);
+            getGateKeeperService().clearSecureUserId(userId);
+            mStorage.writeCredentialHash(CredentialHash.createEmptyHash(), userId);
+            setKeystorePassword(null, userId);
+            fixateNewestUserKeyAuth(userId);
+            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
+            notifyActivePasswordMetricsAvailable(null, userId);
+
+            if (mStorage.getPersistentDataBlock() != null
+                    && LockPatternUtils.userOwnsFrpCredential(mUserManager.getUserInfo(userId))) {
+                // If owner, write to persistent storage for FRP
+                mStorage.writePersistentDataBlock(PersistentData.TYPE_NONE, userId, 0, null);
+            }
+            return;
+        }
+        if (credential == null) {
+            throw new RemoteException("Null credential with mismatched credential type");
+        }
+
+        CredentialHash currentHandle = mStorage.readCredentialHash(userId);
+        if (isManagedProfileWithUnifiedLock(userId)) {
+            // get credential from keystore when managed profile has unified lock
+            if (savedCredential == null) {
+                try {
+                    savedCredential = getDecryptedPasswordForTiedProfile(userId);
+                } catch (FileNotFoundException e) {
+                    Slog.i(TAG, "Child profile key not found");
+                } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                        | NoSuchAlgorithmException | NoSuchPaddingException
+                        | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                        | BadPaddingException | CertificateException | IOException e) {
+                    Slog.e(TAG, "Failed to decrypt child profile key", e);
+                }
+            }
+        } else {
+            if (currentHandle.hash == null) {
+                if (savedCredential != null) {
+                    Slog.w(TAG, "Saved credential provided, but none stored");
+                }
+                savedCredential = null;
+            }
+        }
+        synchronized (mSpManager) {
+            if (shouldMigrateToSyntheticPasswordLocked(userId)) {
+                initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential,
+                        currentHandle.type, requestedQuality, userId);
+                spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
+                        requestedQuality, userId);
+                return;
+            }
+        }
+        if (DEBUG) Slog.d(TAG, "setLockCredentialInternal: user=" + userId);
+        byte[] enrolledHandle = enrollCredential(currentHandle.hash, savedCredential, credential,
+                userId);
+        if (enrolledHandle != null) {
+            CredentialHash willStore = CredentialHash.create(enrolledHandle, credentialType);
+            mStorage.writeCredentialHash(willStore, userId);
+            // push new secret and auth token to vold
+            GateKeeperResponse gkResponse = getGateKeeperService()
+                    .verifyChallenge(userId, 0, willStore.hash, credential.getBytes());
+            setUserKeyProtection(userId, credential, convertResponse(gkResponse));
+            fixateNewestUserKeyAuth(userId);
+            // Refresh the auth token
+            doVerifyCredential(credential, credentialType, true, 0, userId, null /* progressCallback */);
+            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
+            if (mStorage.getPersistentDataBlock() != null
+                    && LockPatternUtils.userOwnsFrpCredential(mUserManager.getUserInfo(userId))) {
+                // If owner, write to persistent storage for FRP
+                mStorage.writePersistentDataBlock(PersistentData.TYPE_GATEKEEPER, userId,
+                        requestedQuality, willStore.toBytes());
+            }
+        } else {
+            throw new RemoteException("Failed to enroll " +
+                    (credentialType == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD ? "password"
+                            : "pattern"));
+        }
+    }
+
+    private VerifyCredentialResponse convertResponse(GateKeeperResponse gateKeeperResponse) {
+        return VerifyCredentialResponse.fromGateKeeperResponse(gateKeeperResponse);
+    }
+
+    @VisibleForTesting
+    protected void tieProfileLockToParent(int userId, String password) {
+        if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId);
+        byte[] randomLockSeed = password.getBytes(StandardCharsets.UTF_8);
+        byte[] encryptionResult;
+        byte[] iv;
+        try {
+            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
+            keyGenerator.init(new SecureRandom());
+            SecretKey secretKey = keyGenerator.generateKey();
+            java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            try {
+                keyStore.setEntry(
+                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId,
+                        new java.security.KeyStore.SecretKeyEntry(secretKey),
+                        new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
+                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                                .build());
+                keyStore.setEntry(
+                        LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId,
+                        new java.security.KeyStore.SecretKeyEntry(secretKey),
+                        new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
+                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                                .setUserAuthenticationRequired(true)
+                                .setUserAuthenticationValidityDurationSeconds(30)
+                                .setCriticalToDeviceEncryption(true)
+                                .build());
+                // Key imported, obtain a reference to it.
+                SecretKey keyStoreEncryptionKey = (SecretKey) keyStore.getKey(
+                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId, null);
+                Cipher cipher = Cipher.getInstance(
+                        KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
+                                + KeyProperties.ENCRYPTION_PADDING_NONE);
+                cipher.init(Cipher.ENCRYPT_MODE, keyStoreEncryptionKey);
+                encryptionResult = cipher.doFinal(randomLockSeed);
+                iv = cipher.getIV();
+            } finally {
+                // The original key can now be discarded.
+                keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId);
+            }
+        } catch (CertificateException | UnrecoverableKeyException
+                | IOException | BadPaddingException | IllegalBlockSizeException | KeyStoreException
+                | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
+            throw new RuntimeException("Failed to encrypt key", e);
+        }
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        try {
+            if (iv.length != PROFILE_KEY_IV_SIZE) {
+                throw new RuntimeException("Invalid iv length: " + iv.length);
+            }
+            outputStream.write(iv);
+            outputStream.write(encryptionResult);
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to concatenate byte arrays", e);
+        }
+        mStorage.writeChildProfileLock(userId, outputStream.toByteArray());
+    }
+
+    private byte[] enrollCredential(byte[] enrolledHandle,
+            String enrolledCredential, String toEnroll, int userId)
+            throws RemoteException {
+        checkWritePermission(userId);
+        byte[] enrolledCredentialBytes = enrolledCredential == null
+                ? null
+                : enrolledCredential.getBytes();
+        byte[] toEnrollBytes = toEnroll == null
+                ? null
+                : toEnroll.getBytes();
+        GateKeeperResponse response = getGateKeeperService().enroll(userId, enrolledHandle,
+                enrolledCredentialBytes, toEnrollBytes);
+
+        if (response == null) {
+            return null;
+        }
+
+        byte[] hash = response.getPayload();
+        if (hash != null) {
+            setKeystorePassword(toEnroll, userId);
+        } else {
+            // Should not happen
+            Slog.e(TAG, "Throttled while enrolling a password");
+        }
+        return hash;
+    }
+
+    private void setAuthlessUserKeyProtection(int userId, byte[] key) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "setAuthlessUserKeyProtectiond: user=" + userId);
+        addUserKeyAuth(userId, null, key);
+    }
+
+    private void setUserKeyProtection(int userId, String credential, VerifyCredentialResponse vcr)
+            throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "setUserKeyProtection: user=" + userId);
+        if (vcr == null) {
+            throw new RemoteException("Null response verifying a credential we just set");
+        }
+        if (vcr.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+            throw new RemoteException("Non-OK response verifying a credential we just set: "
+                    + vcr.getResponseCode());
+        }
+        byte[] token = vcr.getPayload();
+        if (token == null) {
+            throw new RemoteException("Empty payload verifying a credential we just set");
+        }
+        addUserKeyAuth(userId, token, secretFromCredential(credential));
+    }
+
+    private void clearUserKeyProtection(int userId) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "clearUserKeyProtection user=" + userId);
+        addUserKeyAuth(userId, null, null);
+    }
+
+    private static byte[] secretFromCredential(String credential) throws RemoteException {
+        try {
+            MessageDigest digest = MessageDigest.getInstance("SHA-512");
+            // Personalize the hash
+            byte[] personalization = "Android FBE credential hash"
+                    .getBytes(StandardCharsets.UTF_8);
+            // Pad it to the block size of the hash function
+            personalization = Arrays.copyOf(personalization, 128);
+            digest.update(personalization);
+            digest.update(credential.getBytes(StandardCharsets.UTF_8));
+            return digest.digest();
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("NoSuchAlgorithmException for SHA-512");
+        }
+    }
+
+    private void addUserKeyAuth(int userId, byte[] token, byte[] secret)
+            throws RemoteException {
+        final UserInfo userInfo = mUserManager.getUserInfo(userId);
+        final IStorageManager storageManager = mInjector.getStorageManager();
+        final long callingId = Binder.clearCallingIdentity();
+        try {
+            storageManager.addUserKeyAuth(userId, userInfo.serialNumber, token, secret);
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+    }
+
+    private void fixateNewestUserKeyAuth(int userId)
+            throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "fixateNewestUserKeyAuth: user=" + userId);
+        final IStorageManager storageManager = mInjector.getStorageManager();
+        final long callingId = Binder.clearCallingIdentity();
+        try {
+            storageManager.fixateNewestUserKeyAuth(userId);
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+    }
+
+    @Override
+    public void resetKeyStore(int userId) throws RemoteException {
+        checkWritePermission(userId);
+        if (DEBUG) Slog.v(TAG, "Reset keystore for user: " + userId);
+        int managedUserId = -1;
+        String managedUserDecryptedPassword = null;
+        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+        for (UserInfo pi : profiles) {
+            // Unlock managed profile with unified lock
+            if (pi.isManagedProfile()
+                    && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
+                    && mStorage.hasChildProfileLock(pi.id)) {
+                try {
+                    if (managedUserId == -1) {
+                        managedUserDecryptedPassword = getDecryptedPasswordForTiedProfile(pi.id);
+                        managedUserId = pi.id;
+                    } else {
+                        // Should not happen
+                        Slog.e(TAG, "More than one managed profile, uid1:" + managedUserId
+                                + ", uid2:" + pi.id);
+                    }
+                } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                        | NoSuchAlgorithmException | NoSuchPaddingException
+                        | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                        | BadPaddingException | CertificateException | IOException e) {
+                    Slog.e(TAG, "Failed to decrypt child profile key", e);
+                }
+            }
+        }
+        try {
+            // Clear all the users credentials could have been installed in for this user.
+            for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) {
+                for (int uid : SYSTEM_CREDENTIAL_UIDS) {
+                    mKeyStore.clearUid(UserHandle.getUid(profileId, uid));
+                }
+            }
+        } finally {
+            if (managedUserId != -1 && managedUserDecryptedPassword != null) {
+                if (DEBUG) Slog.v(TAG, "Restore tied profile lock");
+                tieProfileLockToParent(managedUserId, managedUserDecryptedPassword);
+            }
+        }
+    }
+
+    @Override
+    public VerifyCredentialResponse checkCredential(String credential, int type, int userId,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        checkPasswordReadPermission(userId);
+        return doVerifyCredential(credential, type, false, 0, userId, progressCallback);
+    }
+
+    @Override
+    public VerifyCredentialResponse verifyCredential(String credential, int type, long challenge,
+            int userId) throws RemoteException {
+        checkPasswordReadPermission(userId);
+        return doVerifyCredential(credential, type, true, challenge, userId,
+                null /* progressCallback */);
+    }
+
+    /**
+     * Verify user credential and unlock the user. Fix pattern bug by deprecating the old base zero
+     * format.
+     */
+    private VerifyCredentialResponse doVerifyCredential(String credential, int credentialType,
+            boolean hasChallenge, long challenge, int userId,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        if (TextUtils.isEmpty(credential)) {
+            throw new IllegalArgumentException("Credential can't be null or empty");
+        }
+        if (userId == USER_FRP && Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
+            Slog.e(TAG, "FRP credential can only be verified prior to provisioning.");
+            return VerifyCredentialResponse.ERROR;
+        }
+        VerifyCredentialResponse response = null;
+        response = spBasedDoVerifyCredential(credential, credentialType, hasChallenge, challenge,
+                userId, progressCallback);
+        // The user employs synthetic password based credential.
+        if (response != null) {
+            return response;
+        }
+
+        final CredentialHash storedHash;
+        if (userId == USER_FRP) {
+            PersistentData data = mStorage.readPersistentDataBlock();
+            if (data.type != PersistentData.TYPE_GATEKEEPER) {
+                Slog.wtf(TAG, "Expected PersistentData.TYPE_GATEKEEPER, but was: " + data.type);
+                return VerifyCredentialResponse.ERROR;
+            }
+            return verifyFrpCredential(credential, credentialType, data, progressCallback);
+        } else {
+            storedHash = mStorage.readCredentialHash(userId);
+        }
+
+        if (storedHash.type != credentialType) {
+            Slog.wtf(TAG, "doVerifyCredential type mismatch with stored credential??"
+                    + " stored: " + storedHash.type + " passed in: " + credentialType);
+            return VerifyCredentialResponse.ERROR;
+        }
+
+        boolean shouldReEnrollBaseZero = storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
+                && storedHash.isBaseZeroPattern;
+
+        String credentialToVerify;
+        if (shouldReEnrollBaseZero) {
+            credentialToVerify = LockPatternUtils.patternStringToBaseZero(credential);
+        } else {
+            credentialToVerify = credential;
+        }
+
+        response = verifyCredential(userId, storedHash, credentialToVerify,
+                hasChallenge, challenge, progressCallback);
+
+        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+            mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
+            if (shouldReEnrollBaseZero) {
+                setLockCredentialInternal(credential, storedHash.type, credentialToVerify,
+                        DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId);
+            }
+        }
+
+        return response;
+    }
+
+    private VerifyCredentialResponse verifyFrpCredential(String credential, int credentialType,
+            PersistentData data, ICheckCredentialProgressCallback progressCallback)
+            throws RemoteException {
+        CredentialHash storedHash = CredentialHash.fromBytes(data.payload);
+        if (storedHash.type != credentialType) {
+            Slog.wtf(TAG, "doVerifyCredential type mismatch with stored credential??"
+                    + " stored: " + storedHash.type + " passed in: " + credentialType);
+            return VerifyCredentialResponse.ERROR;
+        }
+        if (ArrayUtils.isEmpty(storedHash.hash) || TextUtils.isEmpty(credential)) {
+            Slog.e(TAG, "Stored hash or credential is empty");
+            return VerifyCredentialResponse.ERROR;
+        }
+        VerifyCredentialResponse response = VerifyCredentialResponse.fromGateKeeperResponse(
+                getGateKeeperService().verifyChallenge(data.userId, 0 /* challenge */,
+                        storedHash.hash, credential.getBytes()));
+        if (progressCallback != null
+                && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+            progressCallback.onCredentialVerified();
+        }
+        return response;
+    }
+
+    @Override
+    public VerifyCredentialResponse verifyTiedProfileChallenge(String credential, int type,
+            long challenge, int userId) throws RemoteException {
+        checkPasswordReadPermission(userId);
+        if (!isManagedProfileWithUnifiedLock(userId)) {
+            throw new RemoteException("User id must be managed profile with unified lock");
+        }
+        final int parentProfileId = mUserManager.getProfileParent(userId).id;
+        // Unlock parent by using parent's challenge
+        final VerifyCredentialResponse parentResponse = doVerifyCredential(
+                credential,
+                type,
+                true /* hasChallenge */,
+                challenge,
+                parentProfileId,
+                null /* progressCallback */);
+        if (parentResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+            // Failed, just return parent's response
+            return parentResponse;
+        }
+
+        try {
+            // Unlock work profile, and work profile with unified lock must use password only
+            return doVerifyCredential(getDecryptedPasswordForTiedProfile(userId),
+                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    true,
+                    challenge,
+                    userId, null /* progressCallback */);
+        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                | NoSuchAlgorithmException | NoSuchPaddingException
+                | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                | BadPaddingException | CertificateException | IOException e) {
+            Slog.e(TAG, "Failed to decrypt child profile key", e);
+            throw new RemoteException("Unable to get tied profile token");
+        }
+    }
+
+    /**
+     * Lowest-level credential verification routine that talks to GateKeeper. If verification
+     * passes, unlock the corresponding user and keystore. Also handles the migration from legacy
+     * hash to GK.
+     */
+    private VerifyCredentialResponse verifyCredential(int userId, CredentialHash storedHash,
+            String credential, boolean hasChallenge, long challenge,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        if ((storedHash == null || storedHash.hash.length == 0) && TextUtils.isEmpty(credential)) {
+            // don't need to pass empty credentials to GateKeeper
+            return VerifyCredentialResponse.OK;
+        }
+
+        if (storedHash == null || TextUtils.isEmpty(credential)) {
+            return VerifyCredentialResponse.ERROR;
+        }
+
+        // We're potentially going to be doing a bunch of disk I/O below as part
+        // of unlocking the user, so yell if calling from the main thread.
+        StrictMode.noteDiskRead();
+
+        if (storedHash.version == CredentialHash.VERSION_LEGACY) {
+            final byte[] hash;
+            if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
+                hash = LockPatternUtils.patternToHash(LockPatternUtils.stringToPattern(credential));
+            } else {
+                hash = mLockPatternUtils.passwordToHash(credential, userId);
+            }
+            if (Arrays.equals(hash, storedHash.hash)) {
+                if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
+                    unlockKeystore(LockPatternUtils.patternStringToBaseZero(credential), userId);
+                } else {
+                    unlockKeystore(credential, userId);
+                }
+                // Users with legacy credentials don't have credential-backed
+                // FBE keys, so just pass through a fake token/secret
+                Slog.i(TAG, "Unlocking user with fake token: " + userId);
+                final byte[] fakeToken = String.valueOf(userId).getBytes();
+                unlockUser(userId, fakeToken, fakeToken);
+
+                // migrate credential to GateKeeper
+                setLockCredentialInternal(credential, storedHash.type, null,
+                        storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
+                                ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
+                                : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
+                                /* TODO(roosa): keep the same password quality */, userId);
+                if (!hasChallenge) {
+                    notifyActivePasswordMetricsAvailable(credential, userId);
+                    return VerifyCredentialResponse.OK;
+                }
+                // Fall through to get the auth token. Technically this should never happen,
+                // as a user that had a legacy credential would have to unlock their device
+                // before getting to a flow with a challenge, but supporting for consistency.
+            } else {
+                return VerifyCredentialResponse.ERROR;
+            }
+        }
+        GateKeeperResponse gateKeeperResponse = getGateKeeperService()
+                .verifyChallenge(userId, challenge, storedHash.hash, credential.getBytes());
+        VerifyCredentialResponse response = convertResponse(gateKeeperResponse);
+        boolean shouldReEnroll = gateKeeperResponse.getShouldReEnroll();
+
+        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+
+            // credential has matched
+
+            if (progressCallback != null) {
+                progressCallback.onCredentialVerified();
+            }
+            notifyActivePasswordMetricsAvailable(credential, userId);
+            unlockKeystore(credential, userId);
+
+            Slog.i(TAG, "Unlocking user " + userId + " with token length "
+                    + response.getPayload().length);
+            unlockUser(userId, response.getPayload(), secretFromCredential(credential));
+
+            if (isManagedProfileWithSeparatedLock(userId)) {
+                TrustManager trustManager =
+                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
+                trustManager.setDeviceLockedForUser(userId, false);
+            }
+            int reEnrollQuality = storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
+                    ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
+                    : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
+                    /* TODO(roosa): keep the same password quality */;
+            if (shouldReEnroll) {
+                setLockCredentialInternal(credential, storedHash.type, credential,
+                        reEnrollQuality, userId);
+            } else {
+                // Now that we've cleared of all required GK migration, let's do the final
+                // migration to synthetic password.
+                synchronized (mSpManager) {
+                    if (shouldMigrateToSyntheticPasswordLocked(userId)) {
+                        AuthenticationToken auth = initializeSyntheticPasswordLocked(
+                                storedHash.hash, credential, storedHash.type, reEnrollQuality,
+                                userId);
+                        activateEscrowTokens(auth, userId);
+                    }
+                }
+            }
+        } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
+            if (response.getTimeout() > 0) {
+                requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
+            }
+        }
+
+        return response;
+    }
+
+    private void notifyActivePasswordMetricsAvailable(String password, @UserIdInt int userId) {
+        final PasswordMetrics metrics;
+        if (password == null) {
+            metrics = new PasswordMetrics();
+        } else {
+            metrics = PasswordMetrics.computeForPassword(password);
+            metrics.quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(userId);
+        }
+
+        // Asynchronous to avoid dead lock
+        mHandler.post(() -> {
+            DevicePolicyManager dpm = (DevicePolicyManager)
+                    mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+            dpm.setActivePasswordState(metrics, userId);
+        });
+    }
+
+    /**
+     * Call after {@link #notifyActivePasswordMetricsAvailable} so metrics are updated before
+     * reporting the password changed.
+     */
+    private void notifyPasswordChanged(@UserIdInt int userId) {
+        // Same handler as notifyActivePasswordMetricsAvailable to ensure correct ordering
+        mHandler.post(() -> {
+            DevicePolicyManager dpm = (DevicePolicyManager)
+                    mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+            dpm.reportPasswordChanged(userId);
+        });
+    }
+
+    @Override
+    public boolean checkVoldPassword(int userId) throws RemoteException {
+        if (!mFirstCallToVold) {
+            return false;
+        }
+        mFirstCallToVold = false;
+
+        checkPasswordReadPermission(userId);
+
+        // There's no guarantee that this will safely connect, but if it fails
+        // we will simply show the lock screen when we shouldn't, so relatively
+        // benign. There is an outside chance something nasty would happen if
+        // this service restarted before vold stales out the password in this
+        // case. The nastiness is limited to not showing the lock screen when
+        // we should, within the first minute of decrypting the phone if this
+        // service can't connect to vold, it restarts, and then the new instance
+        // does successfully connect.
+        final IStorageManager service = mInjector.getStorageManager();
+        String password;
+        long identity = Binder.clearCallingIdentity();
+        try {
+            password = service.getPassword();
+            service.clearPassword();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        if (password == null) {
+            return false;
+        }
+
+        try {
+            if (mLockPatternUtils.isLockPatternEnabled(userId)) {
+                if (checkCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, userId,
+                        null /* progressCallback */)
+                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
+                    return true;
+                }
+            }
+        } catch (Exception e) {
+        }
+
+        try {
+            if (mLockPatternUtils.isLockPasswordEnabled(userId)) {
+                if (checkCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, userId,
+                        null /* progressCallback */)
+                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
+                    return true;
+                }
+            }
+        } catch (Exception e) {
+        }
+
+        return false;
+    }
+
+    private void removeUser(int userId, boolean unknownUser) {
+        mSpManager.removeUser(userId);
+        mStorage.removeUser(userId);
+        mStrongAuth.removeUser(userId);
+
+        final KeyStore ks = KeyStore.getInstance();
+        ks.onUserRemoved(userId);
+
+        try {
+            final IGateKeeperService gk = getGateKeeperService();
+            if (gk != null) {
+                gk.clearSecureUserId(userId);
+            }
+        } catch (RemoteException ex) {
+            Slog.w(TAG, "unable to clear GK secure user id");
+        }
+        if (unknownUser || mUserManager.getUserInfo(userId).isManagedProfile()) {
+            removeKeystoreProfileKey(userId);
+        }
+    }
+
+    private void removeKeystoreProfileKey(int targetUserId) {
+        if (DEBUG) Slog.v(TAG, "Remove keystore profile key for user: " + targetUserId);
+        try {
+            java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + targetUserId);
+            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + targetUserId);
+        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
+                | IOException e) {
+            // We have tried our best to remove all keys
+            Slog.e(TAG, "Unable to remove keystore profile key for user:" + targetUserId, e);
+        }
+    }
+
+    @Override
+    public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
+        checkPasswordReadPermission(UserHandle.USER_ALL);
+        mStrongAuth.registerStrongAuthTracker(tracker);
+    }
+
+    @Override
+    public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
+        checkPasswordReadPermission(UserHandle.USER_ALL);
+        mStrongAuth.unregisterStrongAuthTracker(tracker);
+    }
+
+    @Override
+    public void requireStrongAuth(int strongAuthReason, int userId) {
+        checkWritePermission(userId);
+        mStrongAuth.requireStrongAuth(strongAuthReason, userId);
+    }
+
+    @Override
+    public void userPresent(int userId) {
+        checkWritePermission(userId);
+        mStrongAuth.reportUnlock(userId);
+    }
+
+    @Override
+    public int getStrongAuthForUser(int userId) {
+        checkPasswordReadPermission(userId);
+        return mStrongAuthTracker.getStrongAuthForUser(userId);
+    }
+
+    private boolean isCallerShell() {
+        final int callingUid = Binder.getCallingUid();
+        return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID;
+    }
+
+    private void enforceShell() {
+        if (!isCallerShell()) {
+            throw new SecurityException("Caller must be shell");
+        }
+    }
+
+    @Override
+    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+            String[] args, ShellCallback callback, ResultReceiver resultReceiver)
+            throws RemoteException {
+        enforceShell();
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            (new LockSettingsShellCommand(mContext, new LockPatternUtils(mContext))).exec(
+                    this, in, out, err, args, callback, resultReceiver);
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    private static final String[] VALID_SETTINGS = new String[] {
+            LockPatternUtils.LOCKOUT_PERMANENT_KEY,
+            LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
+            LockPatternUtils.PATTERN_EVER_CHOSEN_KEY,
+            LockPatternUtils.PASSWORD_TYPE_KEY,
+            LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
+            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
+            LockPatternUtils.DISABLE_LOCKSCREEN_KEY,
+            LockPatternUtils.LOCKSCREEN_OPTIONS,
+            LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
+            LockPatternUtils.BIOMETRIC_WEAK_EVER_CHOSEN_KEY,
+            LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS,
+            LockPatternUtils.PASSWORD_HISTORY_KEY,
+            Secure.LOCK_PATTERN_ENABLED,
+            Secure.LOCK_BIOMETRIC_WEAK_FLAGS,
+            Secure.LOCK_PATTERN_VISIBLE,
+            Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED
+    };
+
+    // Reading these settings needs the contacts permission
+    private static final String[] READ_CONTACTS_PROTECTED_SETTINGS = new String[] {
+            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
+            Secure.LOCK_SCREEN_OWNER_INFO
+    };
+
+    // Reading these settings needs the same permission as checking the password
+    private static final String[] READ_PASSWORD_PROTECTED_SETTINGS = new String[] {
+            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
+            LockPatternUtils.PASSWORD_HISTORY_KEY,
+            LockPatternUtils.PASSWORD_TYPE_KEY,
+            SEPARATE_PROFILE_CHALLENGE_KEY
+    };
+
+    private static final String[] SETTINGS_TO_BACKUP = new String[] {
+            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
+            Secure.LOCK_SCREEN_OWNER_INFO,
+            Secure.LOCK_PATTERN_VISIBLE,
+            LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS
+    };
+
+    private class GateKeeperDiedRecipient implements IBinder.DeathRecipient {
+        @Override
+        public void binderDied() {
+            mGateKeeperService.asBinder().unlinkToDeath(this, 0);
+            mGateKeeperService = null;
+        }
+    }
+
+    protected synchronized IGateKeeperService getGateKeeperService()
+            throws RemoteException {
+        if (mGateKeeperService != null) {
+            return mGateKeeperService;
+        }
+
+        final IBinder service = ServiceManager.getService(Context.GATEKEEPER_SERVICE);
+        if (service != null) {
+            service.linkToDeath(new GateKeeperDiedRecipient(), 0);
+            mGateKeeperService = IGateKeeperService.Stub.asInterface(service);
+            return mGateKeeperService;
+        }
+
+        Slog.e(TAG, "Unable to acquire GateKeeperService");
+        return null;
+    }
+
+    /**
+     * Precondition: vold and keystore unlocked.
+     *
+     * Create new synthetic password, set up synthetic password blob protected by the supplied
+     * user credential, and make the newly-created SP blob active.
+     *
+     * The invariant under a synthetic password is:
+     * 1. If user credential exists, then both vold and keystore and protected with keys derived
+     *     from the synthetic password.
+     * 2. If user credential does not exist, vold and keystore protection are cleared. This is to
+     *     make it consistent with current behaviour. It also allows ActivityManager to call
+     *     unlockUser() with empty secret.
+     * 3. Once a user is migrated to have synthetic password, its value will never change, no matter
+     *     whether the user changes his lockscreen PIN or clear/reset it. When the user clears its
+     *     lockscreen PIN, we still maintain the existing synthetic password in a password blob
+     *     protected by a default PIN. The only exception is when the DPC performs an untrusted
+     *     credential change, in which case we have no way to derive the existing synthetic password
+     *     and has to create a new one.
+     * 4. The user SID is linked with synthetic password, but its cleared/re-created when the user
+     *     clears/re-creates his lockscreen PIN.
+     *
+     *
+     * Different cases of calling this method:
+     * 1. credentialHash != null
+     *     This implies credential != null, a new SP blob will be provisioned, and existing SID
+     *     migrated to associate with the new SP.
+     *     This happens during a normal migration case when the user currently has password.
+     *
+     * 2. credentialhash == null and credential == null
+     *     A new SP blob and a new SID will be created, while the user has no credentials.
+     *     This can happens when we are activating an escrow token on a unsecured device, during
+     *     which we want to create the SP structure with an empty user credential.
+     *
+     * 3. credentialhash == null and credential != null
+     *     This is the untrusted credential reset, OR the user sets a new lockscreen password
+     *     FOR THE FIRST TIME on a SP-enabled device. New credential and new SID will be created
+     */
+    private AuthenticationToken initializeSyntheticPasswordLocked(byte[] credentialHash,
+            String credential, int credentialType, int requestedQuality,
+            int userId) throws RemoteException {
+        Slog.i(TAG, "Initialize SyntheticPassword for user: " + userId);
+        AuthenticationToken auth = mSpManager.newSyntheticPasswordAndSid(getGateKeeperService(),
+                credentialHash, credential, userId);
+        if (auth == null) {
+            Slog.wtf(TAG, "initializeSyntheticPasswordLocked returns null auth token");
+            return null;
+        }
+        long handle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
+                credential, credentialType, auth, requestedQuality, userId);
+        if (credential != null) {
+            if (credentialHash == null) {
+                // Since when initializing SP, we didn't provide an existing password handle
+                // for it to migrate SID, we need to create a new SID for the user.
+                mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
+            }
+            mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
+            setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
+            setKeystorePassword(auth.deriveKeyStorePassword(), userId);
+        } else {
+            clearUserKeyProtection(userId);
+            setKeystorePassword(null, userId);
+            getGateKeeperService().clearSecureUserId(userId);
+        }
+        fixateNewestUserKeyAuth(userId);
+        setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, handle, userId);
+        return auth;
+    }
+
+    private long getSyntheticPasswordHandleLocked(int userId) {
+        try {
+            return getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId);
+        } catch (RemoteException e) {
+            return SyntheticPasswordManager.DEFAULT_HANDLE;
+        }
+    }
+
+    private boolean isSyntheticPasswordBasedCredentialLocked(int userId) throws RemoteException {
+        if (userId == USER_FRP) {
+            final int type = mStorage.readPersistentDataBlock().type;
+            return type == PersistentData.TYPE_SP || type == PersistentData.TYPE_SP_WEAVER;
+        }
+        long handle = getSyntheticPasswordHandleLocked(userId);
+        // This is a global setting
+        long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY,
+                SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT, UserHandle.USER_SYSTEM);
+      return enabled != 0 && handle != SyntheticPasswordManager.DEFAULT_HANDLE;
+    }
+
+    private boolean shouldMigrateToSyntheticPasswordLocked(int userId) throws RemoteException {
+        long handle = getSyntheticPasswordHandleLocked(userId);
+        // This is a global setting
+        long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY,
+                SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT, UserHandle.USER_SYSTEM);
+        return enabled != 0 && handle == SyntheticPasswordManager.DEFAULT_HANDLE;
+    }
+
+    private void enableSyntheticPasswordLocked() throws RemoteException {
+        setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
+    }
+
+    private VerifyCredentialResponse spBasedDoVerifyCredential(String userCredential, int
+            credentialType, boolean hasChallenge, long challenge, int userId,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredential: user=" + userId);
+        if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+            userCredential = null;
+        }
+
+        final AuthenticationResult authResult;
+        VerifyCredentialResponse response;
+        synchronized (mSpManager) {
+            if (!isSyntheticPasswordBasedCredentialLocked(userId)) {
+                return null;
+            }
+            if (userId == USER_FRP) {
+                return mSpManager.verifyFrpCredential(getGateKeeperService(),
+                        userCredential, credentialType, progressCallback);
+            }
+
+            long handle = getSyntheticPasswordHandleLocked(userId);
+            authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
+                    getGateKeeperService(), handle, userCredential, userId);
+
+            response = authResult.gkResponse;
+            // credential has matched
+            if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+                // perform verifyChallenge with synthetic password which generates the real GK auth
+                // token and response for the current user
+                response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken,
+                        challenge, userId);
+                if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+                    // This shouldn't really happen: the unwrapping of SP succeeds, but SP doesn't
+                    // match the recorded GK password handle.
+                    Slog.wtf(TAG, "verifyChallenge with SP failed.");
+                    return VerifyCredentialResponse.ERROR;
+                }
+            }
+        }
+
+        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+            if (progressCallback != null) {
+                progressCallback.onCredentialVerified();
+            }
+            notifyActivePasswordMetricsAvailable(userCredential, userId);
+            unlockKeystore(authResult.authToken.deriveKeyStorePassword(), userId);
+
+            final byte[] secret = authResult.authToken.deriveDiskEncryptionKey();
+            Slog.i(TAG, "Unlocking user " + userId + " with secret only, length " + secret.length);
+            unlockUser(userId, null, secret);
+
+            activateEscrowTokens(authResult.authToken, userId);
+
+            if (isManagedProfileWithSeparatedLock(userId)) {
+                TrustManager trustManager =
+                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
+                trustManager.setDeviceLockedForUser(userId, false);
+            }
+            mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
+        } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
+            if (response.getTimeout() > 0) {
+                requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
+            }
+        }
+
+        return response;
+    }
+
+    /**
+     * Change the user's lockscreen password by creating a new SP blob and update the handle, based
+     * on an existing authentication token. Even though a new SP blob is created, the underlying
+     * synthetic password is never changed.
+     *
+     * When clearing credential, we keep the SP unchanged, but clear its password handle so its
+     * SID is gone. We also clear password from (software-based) keystore and vold, which will be
+     * added back when new password is set in future.
+     */
+    private long setLockCredentialWithAuthTokenLocked(String credential, int credentialType,
+            AuthenticationToken auth, int requestedQuality, int userId) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "setLockCredentialWithAuthTokenLocked: user=" + userId);
+        long newHandle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
+                credential, credentialType, auth, requestedQuality, userId);
+        final Map<Integer, String> profilePasswords;
+        if (credential != null) {
+            // // not needed by synchronizeUnifiedWorkChallengeForProfiles()
+            profilePasswords = null;
+
+            if (mSpManager.hasSidForUser(userId)) {
+                // We are changing password of a secured device, nothing more needed as
+                // createPasswordBasedSyntheticPassword has already taken care of maintaining
+                // the password handle and SID unchanged.
+
+                //refresh auth token
+                mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
+            } else {
+                // A new password is set on a previously-unsecured device, we need to generate
+                // a new SID, and re-add keys to vold and keystore.
+                mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
+                mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
+                setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
+                fixateNewestUserKeyAuth(userId);
+                setKeystorePassword(auth.deriveKeyStorePassword(), userId);
+            }
+        } else {
+            // Cache all profile password if they use unified work challenge. This will later be
+            // used to clear the profile's password in synchronizeUnifiedWorkChallengeForProfiles()
+            profilePasswords = getDecryptedPasswordsForAllTiedProfiles(userId);
+
+            // we are clearing password of a secured device, so need to nuke SID as well.
+            mSpManager.clearSidForUser(userId);
+            getGateKeeperService().clearSecureUserId(userId);
+            // Clear key from vold so ActivityManager can just unlock the user with empty secret
+            // during boot.
+            clearUserKeyProtection(userId);
+            fixateNewestUserKeyAuth(userId);
+            setKeystorePassword(null, userId);
+        }
+        setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, newHandle, userId);
+        synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords);
+        return newHandle;
+    }
+
+    private void spBasedSetLockCredentialInternalLocked(String credential, int credentialType,
+            String savedCredential, int requestedQuality, int userId) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "spBasedSetLockCredentialInternalLocked: user=" + userId);
+        if (isManagedProfileWithUnifiedLock(userId)) {
+            // get credential from keystore when managed profile has unified lock
+            try {
+                savedCredential = getDecryptedPasswordForTiedProfile(userId);
+            } catch (FileNotFoundException e) {
+                Slog.i(TAG, "Child profile key not found");
+            } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                    | NoSuchAlgorithmException | NoSuchPaddingException
+                    | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                    | BadPaddingException | CertificateException | IOException e) {
+                Slog.e(TAG, "Failed to decrypt child profile key", e);
+            }
+        }
+        long handle = getSyntheticPasswordHandleLocked(userId);
+        AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
+                getGateKeeperService(), handle, savedCredential, userId);
+        VerifyCredentialResponse response = authResult.gkResponse;
+        AuthenticationToken auth = authResult.authToken;
+        if (auth != null) {
+            // We are performing a trusted credential change i.e. a correct existing credential
+            // is provided
+            setLockCredentialWithAuthTokenLocked(credential, credentialType, auth, requestedQuality,
+                    userId);
+            mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId);
+        } else if (response != null
+                && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR){
+            // We are performing an untrusted credential change i.e. by DevicePolicyManager.
+            // So provision a new SP and SID. This would invalidate existing escrow tokens.
+            // Still support this for now but this flow will be removed in the next release.
+
+            Slog.w(TAG, "Untrusted credential change invoked");
+            initializeSyntheticPasswordLocked(null, credential, credentialType, requestedQuality,
+                    userId);
+            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
+            mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId);
+        } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ {
+            Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " +
+                    (response != null ? "rate limit exceeded" : "failed"));
+            return;
+        }
+        notifyActivePasswordMetricsAvailable(credential, userId);
+
+    }
+
+    @Override
+    public long addEscrowToken(byte[] token, int userId) throws RemoteException {
+        ensureCallerSystemUid();
+        if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId);
+        synchronized (mSpManager) {
+            enableSyntheticPasswordLocked();
+            // Migrate to synthetic password based credentials if the user has no password,
+            // the token can then be activated immediately.
+            AuthenticationToken auth = null;
+            if (!isUserSecure(userId)) {
+                if (shouldMigrateToSyntheticPasswordLocked(userId)) {
+                    auth = initializeSyntheticPasswordLocked(null, null,
+                            LockPatternUtils.CREDENTIAL_TYPE_NONE,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId);
+                } else /* isSyntheticPasswordBasedCredentialLocked(userId) */ {
+                    long pwdHandle = getSyntheticPasswordHandleLocked(userId);
+                    auth = mSpManager.unwrapPasswordBasedSyntheticPassword(getGateKeeperService(),
+                            pwdHandle, null, userId).authToken;
+                }
+            }
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
+                if (!mSpManager.hasEscrowData(userId)) {
+                    throw new SecurityException("Escrow token is disabled on the current user");
+                }
+            }
+            long handle = mSpManager.createTokenBasedSyntheticPassword(token, userId);
+            if (auth != null) {
+                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
+            }
+            return handle;
+        }
+    }
+
+    private void activateEscrowTokens(AuthenticationToken auth, int userId) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId);
+        synchronized (mSpManager) {
+            disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
+            for (long handle : mSpManager.getPendingTokensForUser(userId)) {
+                Slog.i(TAG, String.format("activateEscrowTokens: %x %d ", handle, userId));
+                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
+            }
+        }
+    }
+
+    @Override
+    public boolean isEscrowTokenActive(long handle, int userId) throws RemoteException {
+        ensureCallerSystemUid();
+        synchronized (mSpManager) {
+            return mSpManager.existsHandle(handle, userId);
+        }
+    }
+
+    @Override
+    public boolean removeEscrowToken(long handle, int userId) throws RemoteException {
+        ensureCallerSystemUid();
+        synchronized (mSpManager) {
+            if (handle == getSyntheticPasswordHandleLocked(userId)) {
+                Slog.w(TAG, "Cannot remove password handle");
+                return false;
+            }
+            if (mSpManager.removePendingToken(handle, userId)) {
+                return true;
+            }
+            if (mSpManager.existsHandle(handle, userId)) {
+                mSpManager.destroyTokenBasedSyntheticPassword(handle, userId);
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    @Override
+    public boolean setLockCredentialWithToken(String credential, int type, long tokenHandle,
+            byte[] token, int requestedQuality, int userId) throws RemoteException {
+        ensureCallerSystemUid();
+        boolean result;
+        synchronized (mSpManager) {
+            if (!mSpManager.hasEscrowData(userId)) {
+                throw new SecurityException("Escrow token is disabled on the current user");
+            }
+            result = setLockCredentialWithTokenInternal(credential, type, tokenHandle, token,
+                    requestedQuality, userId);
+        }
+        if (result) {
+            synchronized (mSeparateChallengeLock) {
+                setSeparateProfileChallengeEnabled(userId, true, null);
+            }
+            notifyPasswordChanged(userId);
+        }
+        return result;
+    }
+
+    private boolean setLockCredentialWithTokenInternal(String credential, int type,
+            long tokenHandle, byte[] token, int requestedQuality, int userId) throws RemoteException {
+        synchronized (mSpManager) {
+            AuthenticationResult result = mSpManager.unwrapTokenBasedSyntheticPassword(
+                    getGateKeeperService(), tokenHandle, token, userId);
+            if (result.authToken == null) {
+                Slog.w(TAG, "Invalid escrow token supplied");
+                return false;
+            }
+            long oldHandle = getSyntheticPasswordHandleLocked(userId);
+            setLockCredentialWithAuthTokenLocked(credential, type, result.authToken,
+                    requestedQuality, userId);
+            mSpManager.destroyPasswordBasedSyntheticPassword(oldHandle, userId);
+            return true;
+        }
+    }
+
+    @Override
+    public void unlockUserWithToken(long tokenHandle, byte[] token, int userId)
+            throws RemoteException {
+        ensureCallerSystemUid();
+        AuthenticationResult authResult;
+        synchronized (mSpManager) {
+            if (!mSpManager.hasEscrowData(userId)) {
+                throw new SecurityException("Escrow token is disabled on the current user");
+            }
+            authResult = mSpManager.unwrapTokenBasedSyntheticPassword(getGateKeeperService(),
+                    tokenHandle, token, userId);
+            if (authResult.authToken == null) {
+                Slog.w(TAG, "Invalid escrow token supplied");
+                return;
+            }
+        }
+        unlockUser(userId, null, authResult.authToken.deriveDiskEncryptionKey());
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args){
+        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+
+        pw.println("Current lock settings service state:");
+        pw.println(String.format("SP Enabled = %b",
+                mLockPatternUtils.isSyntheticPasswordEnabled()));
+
+        List<UserInfo> users = mUserManager.getUsers();
+        for (int user = 0; user < users.size(); user++) {
+            final int userId = users.get(user).id;
+            pw.println("    User " + userId);
+            synchronized (mSpManager) {
+                pw.println(String.format("        SP Handle = %x",
+                        getSyntheticPasswordHandleLocked(userId)));
+            }
+            try {
+                pw.println(String.format("        SID = %x",
+                        getGateKeeperService().getSecureUserId(userId)));
+            } catch (RemoteException e) {
+                // ignore.
+            }
+        }
+    }
+
+    private void disableEscrowTokenOnNonManagedDevicesIfNeeded(int userId) {
+        long ident = Binder.clearCallingIdentity();
+        try {
+            // Managed profile should have escrow enabled
+            if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+                Slog.i(TAG, "Managed profile can have escrow token");
+                return;
+            }
+            DevicePolicyManager dpm = mInjector.getDevicePolicyManager();
+            // Devices with Device Owner should have escrow enabled on all users.
+            if (dpm.getDeviceOwnerComponentOnAnyUser() != null) {
+                Slog.i(TAG, "Corp-owned device can have escrow token");
+                return;
+            }
+            // We could also have a profile owner on the given (non-managed) user for unicorn cases
+            if (dpm.getProfileOwnerAsUser(userId) != null) {
+                Slog.i(TAG, "User with profile owner can have escrow token");
+                return;
+            }
+            // If the device is yet to be provisioned (still in SUW), there is still
+            // a chance that Device Owner will be set on the device later, so postpone
+            // disabling escrow token for now.
+            if (!dpm.isDeviceProvisioned()) {
+                Slog.i(TAG, "Postpone disabling escrow tokens until device is provisioned");
+                return;
+            }
+
+            // Escrow tokens are enabled on automotive builds.
+            if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+                return;
+            }
+
+            // Disable escrow token permanently on all other device/user types.
+            Slog.i(TAG, "Disabling escrow token on user " + userId);
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                mSpManager.destroyEscrowData(userId);
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "disableEscrowTokenOnNonManagedDevices", e);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private void ensureCallerSystemUid() throws SecurityException {
+        final int callingUid = mInjector.binderGetCallingUid();
+        if (callingUid != Process.SYSTEM_UID) {
+            throw new SecurityException("Only system can call this API.");
+        }
+    }
+
+    private class DeviceProvisionedObserver extends ContentObserver {
+        private final Uri mDeviceProvisionedUri = Settings.Global.getUriFor(
+                Settings.Global.DEVICE_PROVISIONED);
+
+        private boolean mRegistered;
+
+        public DeviceProvisionedObserver() {
+            super(null);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (mDeviceProvisionedUri.equals(uri)) {
+                updateRegistration();
+
+                if (isProvisioned()) {
+                    Slog.i(TAG, "Reporting device setup complete to IGateKeeperService");
+                    reportDeviceSetupComplete();
+                }
+            }
+        }
+
+        public void onSystemReady() {
+            if (frpCredentialEnabled()) {
+                updateRegistration();
+            } else {
+                // If we don't intend to use frpCredentials and we're not provisioned yet, send
+                // deviceSetupComplete immediately, so gatekeeper can discard any lingering
+                // credentials immediately.
+                if (!isProvisioned()) {
+                    Slog.i(TAG, "FRP credential disabled, reporting device setup complete "
+                            + "to Gatekeeper immediately");
+                    reportDeviceSetupComplete();
+                }
+            }
+        }
+
+        private void reportDeviceSetupComplete() {
+            try {
+                getGateKeeperService().reportDeviceSetupComplete();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Failure reporting to IGateKeeperService", e);
+            }
+        }
+
+        private void updateRegistration() {
+            boolean register = !isProvisioned();
+            if (register == mRegistered) {
+                return;
+            }
+            if (register) {
+                mContext.getContentResolver().registerContentObserver(mDeviceProvisionedUri,
+                        false, this);
+            } else {
+                mContext.getContentResolver().unregisterContentObserver(this);
+            }
+            mRegistered = register;
+        }
+
+        private boolean isProvisioned() {
+            return Settings.Global.getInt(mContext.getContentResolver(),
+                    Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
new file mode 100644
index 0000000..d730c56
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
@@ -0,0 +1,171 @@
+/*
+ * 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.server.locksettings;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
+import static com.android.internal.widget.LockPatternUtils.stringToPattern;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ShellCommand;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
+
+class LockSettingsShellCommand extends ShellCommand {
+
+    private static final String COMMAND_SET_PATTERN = "set-pattern";
+    private static final String COMMAND_SET_PIN = "set-pin";
+    private static final String COMMAND_SET_PASSWORD = "set-password";
+    private static final String COMMAND_CLEAR = "clear";
+    private static final String COMMAND_SP = "sp";
+    private static final String COMMAND_SET_DISABLED = "set-disabled";
+
+    private int mCurrentUserId;
+    private final LockPatternUtils mLockPatternUtils;
+    private final Context mContext;
+    private String mOld = "";
+    private String mNew = "";
+
+    LockSettingsShellCommand(Context context, LockPatternUtils lockPatternUtils) {
+        mContext = context;
+        mLockPatternUtils = lockPatternUtils;
+    }
+
+    @Override
+    public int onCommand(String cmd) {
+        try {
+            mCurrentUserId = ActivityManager.getService().getCurrentUser().id;
+
+            parseArgs();
+            if (!checkCredential()) {
+                return -1;
+            }
+            switch (cmd) {
+                case COMMAND_SET_PATTERN:
+                    runSetPattern();
+                    break;
+                case COMMAND_SET_PASSWORD:
+                    runSetPassword();
+                    break;
+                case COMMAND_SET_PIN:
+                    runSetPin();
+                    break;
+                case COMMAND_CLEAR:
+                    runClear();
+                    break;
+                case COMMAND_SP:
+                    runChangeSp();
+                    break;
+                case COMMAND_SET_DISABLED:
+                    runSetDisabled();
+                    break;
+                default:
+                    getErrPrintWriter().println("Unknown command: " + cmd);
+                    break;
+            }
+            return 0;
+        } catch (Exception e) {
+            getErrPrintWriter().println("Error while executing command: " + cmd);
+            e.printStackTrace(getErrPrintWriter());
+            return -1;
+        }
+    }
+
+    @Override
+    public void onHelp() {
+    }
+
+    private void parseArgs() {
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            if ("--old".equals(opt)) {
+                mOld = getNextArgRequired();
+            } else if ("--user".equals(opt)) {
+                mCurrentUserId = Integer.parseInt(getNextArgRequired());
+            } else {
+                getErrPrintWriter().println("Unknown option: " + opt);
+                throw new IllegalArgumentException();
+            }
+        }
+        mNew = getNextArg();
+    }
+
+    private void runChangeSp() {
+        if (mNew != null ) {
+            if ("1".equals(mNew)) {
+                mLockPatternUtils.enableSyntheticPassword();
+                getOutPrintWriter().println("Synthetic password enabled");
+            } else if ("0".equals(mNew)) {
+                mLockPatternUtils.disableSyntheticPassword();
+                getOutPrintWriter().println("Synthetic password disabled");
+            }
+        }
+        getOutPrintWriter().println(String.format("SP Enabled = %b",
+                mLockPatternUtils.isSyntheticPasswordEnabled()));
+    }
+
+    private void runSetPattern() throws RemoteException {
+        mLockPatternUtils.saveLockPattern(stringToPattern(mNew), mOld, mCurrentUserId);
+        getOutPrintWriter().println("Pattern set to '" + mNew + "'");
+    }
+
+    private void runSetPassword() throws RemoteException {
+        mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_ALPHABETIC, mCurrentUserId);
+        getOutPrintWriter().println("Password set to '" + mNew + "'");
+    }
+
+    private void runSetPin() throws RemoteException {
+        mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_NUMERIC, mCurrentUserId);
+        getOutPrintWriter().println("Pin set to '" + mNew + "'");
+    }
+
+    private void runClear() throws RemoteException {
+        mLockPatternUtils.clearLock(mOld, mCurrentUserId);
+        getOutPrintWriter().println("Lock credential cleared");
+    }
+
+    private void runSetDisabled() throws RemoteException {
+        final boolean disabled = Boolean.parseBoolean(mNew);
+        mLockPatternUtils.setLockScreenDisabled(disabled, mCurrentUserId);
+        getOutPrintWriter().println("Lock screen disabled set to " + disabled);
+    }
+
+    private boolean checkCredential() throws RemoteException, RequestThrottledException {
+        final boolean havePassword = mLockPatternUtils.isLockPasswordEnabled(mCurrentUserId);
+        final boolean havePattern = mLockPatternUtils.isLockPatternEnabled(mCurrentUserId);
+        if (havePassword || havePattern) {
+            boolean result;
+            if (havePassword) {
+                result = mLockPatternUtils.checkPassword(mOld, mCurrentUserId);
+            } else {
+                result = mLockPatternUtils.checkPattern(stringToPattern(mOld),
+                        mCurrentUserId);
+            }
+            if (result) {
+                return true;
+            } else {
+                getOutPrintWriter().println("Old password '" + mOld + "' didn't match");
+                return false;
+            }
+        } else {
+            return true;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
new file mode 100644
index 0000000..79372e48
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
@@ -0,0 +1,903 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static android.content.Context.USER_SERVICE;
+
+import android.annotation.Nullable;
+import android.app.admin.DevicePolicyManager;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.os.Environment;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.Preconditions;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.server.LocalServices;
+import com.android.server.PersistentDataBlockManagerInternal;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Storage for the lock settings service.
+ */
+class LockSettingsStorage {
+
+    private static final String TAG = "LockSettingsStorage";
+    private static final String TABLE = "locksettings";
+    private static final boolean DEBUG = false;
+
+    private static final String COLUMN_KEY = "name";
+    private static final String COLUMN_USERID = "user";
+    private static final String COLUMN_VALUE = "value";
+
+    private static final String[] COLUMNS_FOR_QUERY = {
+            COLUMN_VALUE
+    };
+    private static final String[] COLUMNS_FOR_PREFETCH = {
+            COLUMN_KEY, COLUMN_VALUE
+    };
+
+    private static final String SYSTEM_DIRECTORY = "/system/";
+    private static final String LOCK_PATTERN_FILE = "gatekeeper.pattern.key";
+    private static final String BASE_ZERO_LOCK_PATTERN_FILE = "gatekeeper.gesture.key";
+    private static final String LEGACY_LOCK_PATTERN_FILE = "gesture.key";
+    private static final String LOCK_PASSWORD_FILE = "gatekeeper.password.key";
+    private static final String LEGACY_LOCK_PASSWORD_FILE = "password.key";
+    private static final String CHILD_PROFILE_LOCK_FILE = "gatekeeper.profile.key";
+
+    private static final String SYNTHETIC_PASSWORD_DIRECTORY = "spblob/";
+
+    private static final Object DEFAULT = new Object();
+
+    private final DatabaseHelper mOpenHelper;
+    private final Context mContext;
+    private final Cache mCache = new Cache();
+    private final Object mFileWriteLock = new Object();
+
+    private PersistentDataBlockManagerInternal mPersistentDataBlockManagerInternal;
+
+    @VisibleForTesting
+    public static class CredentialHash {
+        static final int VERSION_LEGACY = 0;
+        static final int VERSION_GATEKEEPER = 1;
+
+        private CredentialHash(byte[] hash, int type, int version) {
+            this(hash, type, version, false /* isBaseZeroPattern */);
+        }
+
+        private CredentialHash(byte[] hash, int type, int version, boolean isBaseZeroPattern) {
+            if (type != LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+                if (hash == null) {
+                    throw new RuntimeException("Empty hash for CredentialHash");
+                }
+            } else /* type == LockPatternUtils.CREDENTIAL_TYPE_NONE */ {
+                if (hash != null) {
+                    throw new RuntimeException("None type CredentialHash should not have hash");
+                }
+            }
+            this.hash = hash;
+            this.type = type;
+            this.version = version;
+            this.isBaseZeroPattern = isBaseZeroPattern;
+        }
+
+        private static CredentialHash createBaseZeroPattern(byte[] hash) {
+            return new CredentialHash(hash, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                    VERSION_GATEKEEPER, true /* isBaseZeroPattern */);
+        }
+
+        static CredentialHash create(byte[] hash, int type) {
+            if (type == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+                throw new RuntimeException("Bad type for CredentialHash");
+            }
+            return new CredentialHash(hash, type, VERSION_GATEKEEPER);
+        }
+
+        static CredentialHash createEmptyHash() {
+            return new CredentialHash(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
+                    VERSION_GATEKEEPER);
+        }
+
+        byte[] hash;
+        int type;
+        int version;
+        boolean isBaseZeroPattern;
+
+        public byte[] toBytes() {
+            Preconditions.checkState(!isBaseZeroPattern, "base zero patterns are not serializable");
+
+            try {
+                ByteArrayOutputStream os = new ByteArrayOutputStream();
+                DataOutputStream dos = new DataOutputStream(os);
+                dos.write(version);
+                dos.write(type);
+                if (hash != null && hash.length > 0) {
+                    dos.writeInt(hash.length);
+                    dos.write(hash);
+                } else {
+                    dos.writeInt(0);
+                }
+                dos.close();
+                return os.toByteArray();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public static CredentialHash fromBytes(byte[] bytes) {
+            try {
+                DataInputStream is = new DataInputStream(new ByteArrayInputStream(bytes));
+                int version = is.read();
+                int type = is.read();
+                int hashSize = is.readInt();
+                byte[] hash = null;
+                if (hashSize > 0) {
+                    hash = new byte[hashSize];
+                    is.readFully(hash);
+                }
+                return new CredentialHash(hash, type, version);
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public LockSettingsStorage(Context context) {
+        mContext = context;
+        mOpenHelper = new DatabaseHelper(context);
+    }
+
+    public void setDatabaseOnCreateCallback(Callback callback) {
+        mOpenHelper.setCallback(callback);
+    }
+
+    public void writeKeyValue(String key, String value, int userId) {
+        writeKeyValue(mOpenHelper.getWritableDatabase(), key, value, userId);
+    }
+
+    public void writeKeyValue(SQLiteDatabase db, String key, String value, int userId) {
+        ContentValues cv = new ContentValues();
+        cv.put(COLUMN_KEY, key);
+        cv.put(COLUMN_USERID, userId);
+        cv.put(COLUMN_VALUE, value);
+
+        db.beginTransaction();
+        try {
+            db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
+                    new String[] {key, Integer.toString(userId)});
+            db.insert(TABLE, null, cv);
+            db.setTransactionSuccessful();
+            mCache.putKeyValue(key, value, userId);
+        } finally {
+            db.endTransaction();
+        }
+
+    }
+
+    public String readKeyValue(String key, String defaultValue, int userId) {
+        int version;
+        synchronized (mCache) {
+            if (mCache.hasKeyValue(key, userId)) {
+                return mCache.peekKeyValue(key, defaultValue, userId);
+            }
+            version = mCache.getVersion();
+        }
+
+        Cursor cursor;
+        Object result = DEFAULT;
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY,
+                COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?",
+                new String[] { Integer.toString(userId), key },
+                null, null, null)) != null) {
+            if (cursor.moveToFirst()) {
+                result = cursor.getString(0);
+            }
+            cursor.close();
+        }
+        mCache.putKeyValueIfUnchanged(key, result, userId, version);
+        return result == DEFAULT ? defaultValue : (String) result;
+    }
+
+    public void prefetchUser(int userId) {
+        int version;
+        synchronized (mCache) {
+            if (mCache.isFetched(userId)) {
+                return;
+            }
+            mCache.setFetched(userId);
+            version = mCache.getVersion();
+        }
+
+        Cursor cursor;
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        if ((cursor = db.query(TABLE, COLUMNS_FOR_PREFETCH,
+                COLUMN_USERID + "=?",
+                new String[] { Integer.toString(userId) },
+                null, null, null)) != null) {
+            while (cursor.moveToNext()) {
+                String key = cursor.getString(0);
+                String value = cursor.getString(1);
+                mCache.putKeyValueIfUnchanged(key, value, userId, version);
+            }
+            cursor.close();
+        }
+
+        // Populate cache by reading the password and pattern files.
+        readCredentialHash(userId);
+    }
+
+    private CredentialHash readPasswordHashIfExists(int userId) {
+        byte[] stored = readFile(getLockPasswordFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    CredentialHash.VERSION_GATEKEEPER);
+        }
+
+        stored = readFile(getLegacyLockPasswordFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    CredentialHash.VERSION_LEGACY);
+        }
+        return null;
+    }
+
+    private CredentialHash readPatternHashIfExists(int userId) {
+        byte[] stored = readFile(getLockPatternFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                    CredentialHash.VERSION_GATEKEEPER);
+        }
+
+        stored = readFile(getBaseZeroLockPatternFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return CredentialHash.createBaseZeroPattern(stored);
+        }
+
+        stored = readFile(getLegacyLockPatternFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                    CredentialHash.VERSION_LEGACY);
+        }
+        return null;
+    }
+
+    public CredentialHash readCredentialHash(int userId) {
+        CredentialHash passwordHash = readPasswordHashIfExists(userId);
+        CredentialHash patternHash = readPatternHashIfExists(userId);
+        if (passwordHash != null && patternHash != null) {
+            if (passwordHash.version == CredentialHash.VERSION_GATEKEEPER) {
+                return passwordHash;
+            } else {
+                return patternHash;
+            }
+        } else if (passwordHash != null) {
+            return passwordHash;
+        } else if (patternHash != null) {
+            return patternHash;
+        } else {
+            return CredentialHash.createEmptyHash();
+        }
+    }
+
+    public void removeChildProfileLock(int userId) {
+        if (DEBUG)
+            Slog.e(TAG, "Remove child profile lock for user: " + userId);
+        try {
+            deleteFile(getChildProfileLockFile(userId));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void writeChildProfileLock(int userId, byte[] lock) {
+        writeFile(getChildProfileLockFile(userId), lock);
+    }
+
+    public byte[] readChildProfileLock(int userId) {
+        return readFile(getChildProfileLockFile(userId));
+    }
+
+    public boolean hasChildProfileLock(int userId) {
+        return hasFile(getChildProfileLockFile(userId));
+    }
+
+    public boolean hasPassword(int userId) {
+        return hasFile(getLockPasswordFilename(userId)) ||
+            hasFile(getLegacyLockPasswordFilename(userId));
+    }
+
+    public boolean hasPattern(int userId) {
+        return hasFile(getLockPatternFilename(userId)) ||
+            hasFile(getBaseZeroLockPatternFilename(userId)) ||
+            hasFile(getLegacyLockPatternFilename(userId));
+    }
+
+    public boolean hasCredential(int userId) {
+        return hasPassword(userId) || hasPattern(userId);
+    }
+
+    private boolean hasFile(String name) {
+        byte[] contents = readFile(name);
+        return contents != null && contents.length > 0;
+    }
+
+    private byte[] readFile(String name) {
+        int version;
+        synchronized (mCache) {
+            if (mCache.hasFile(name)) {
+                return mCache.peekFile(name);
+            }
+            version = mCache.getVersion();
+        }
+
+        RandomAccessFile raf = null;
+        byte[] stored = null;
+        try {
+            raf = new RandomAccessFile(name, "r");
+            stored = new byte[(int) raf.length()];
+            raf.readFully(stored, 0, stored.length);
+            raf.close();
+        } catch (IOException e) {
+            Slog.e(TAG, "Cannot read file " + e);
+        } finally {
+            if (raf != null) {
+                try {
+                    raf.close();
+                } catch (IOException e) {
+                    Slog.e(TAG, "Error closing file " + e);
+                }
+            }
+        }
+        mCache.putFileIfUnchanged(name, stored, version);
+        return stored;
+    }
+
+    private void writeFile(String name, byte[] hash) {
+        synchronized (mFileWriteLock) {
+            RandomAccessFile raf = null;
+            try {
+                // Write the hash to file, requiring each write to be synchronized to the
+                // underlying storage device immediately to avoid data loss in case of power loss.
+                // This also ensures future secdiscard operation on the file succeeds since the
+                // file would have been allocated on flash.
+                raf = new RandomAccessFile(name, "rws");
+                // Truncate the file if pattern is null, to clear the lock
+                if (hash == null || hash.length == 0) {
+                    raf.setLength(0);
+                } else {
+                    raf.write(hash, 0, hash.length);
+                }
+                raf.close();
+            } catch (IOException e) {
+                Slog.e(TAG, "Error writing to file " + e);
+            } finally {
+                if (raf != null) {
+                    try {
+                        raf.close();
+                    } catch (IOException e) {
+                        Slog.e(TAG, "Error closing file " + e);
+                    }
+                }
+            }
+            mCache.putFile(name, hash);
+        }
+    }
+
+    private void deleteFile(String name) {
+        if (DEBUG) Slog.e(TAG, "Delete file " + name);
+        synchronized (mFileWriteLock) {
+            File file = new File(name);
+            if (file.exists()) {
+                file.delete();
+                mCache.putFile(name, null);
+            }
+        }
+    }
+
+    public void writeCredentialHash(CredentialHash hash, int userId) {
+        byte[] patternHash = null;
+        byte[] passwordHash = null;
+
+        if (hash.type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
+            passwordHash = hash.hash;
+        } else if (hash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
+            patternHash = hash.hash;
+        }
+        writeFile(getLockPasswordFilename(userId), passwordHash);
+        writeFile(getLockPatternFilename(userId), patternHash);
+    }
+
+    @VisibleForTesting
+    String getLockPatternFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, LOCK_PATTERN_FILE);
+    }
+
+    @VisibleForTesting
+    String getLockPasswordFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, LOCK_PASSWORD_FILE);
+    }
+
+    @VisibleForTesting
+    String getLegacyLockPatternFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PATTERN_FILE);
+    }
+
+    @VisibleForTesting
+    String getLegacyLockPasswordFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PASSWORD_FILE);
+    }
+
+    private String getBaseZeroLockPatternFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, BASE_ZERO_LOCK_PATTERN_FILE);
+    }
+
+    @VisibleForTesting
+    String getChildProfileLockFile(int userId) {
+        return getLockCredentialFilePathForUser(userId, CHILD_PROFILE_LOCK_FILE);
+    }
+
+    private String getLockCredentialFilePathForUser(int userId, String basename) {
+        String dataSystemDirectory = Environment.getDataDirectory().getAbsolutePath() +
+                        SYSTEM_DIRECTORY;
+        if (userId == 0) {
+            // Leave it in the same place for user 0
+            return dataSystemDirectory + basename;
+        } else {
+            return new File(Environment.getUserSystemDirectory(userId), basename).getAbsolutePath();
+        }
+    }
+
+    public void writeSyntheticPasswordState(int userId, long handle, String name, byte[] data) {
+        writeFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name), data);
+    }
+
+    public byte[] readSyntheticPasswordState(int userId, long handle, String name) {
+        return readFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name));
+    }
+
+    public void deleteSyntheticPasswordState(int userId, long handle, String name) {
+        String path = getSynthenticPasswordStateFilePathForUser(userId, handle, name);
+        File file = new File(path);
+        if (file.exists()) {
+            try {
+                mContext.getSystemService(StorageManager.class).secdiscard(file.getAbsolutePath());
+            } catch (Exception e) {
+                Slog.w(TAG, "Failed to secdiscard " + path, e);
+            } finally {
+                file.delete();
+            }
+            mCache.putFile(path, null);
+        }
+    }
+
+    public Map<Integer, List<Long>> listSyntheticPasswordHandlesForAllUsers(String stateName) {
+        Map<Integer, List<Long>> result = new ArrayMap<>();
+        final UserManager um = UserManager.get(mContext);
+        for (UserInfo user : um.getUsers(false)) {
+            result.put(user.id, listSyntheticPasswordHandlesForUser(stateName, user.id));
+        }
+        return result;
+    }
+
+    public List<Long> listSyntheticPasswordHandlesForUser(String stateName, int userId) {
+        File baseDir = getSyntheticPasswordDirectoryForUser(userId);
+        List<Long> result = new ArrayList<>();
+        File[] files = baseDir.listFiles();
+        if (files == null) {
+            return result;
+        }
+        for (File file : files) {
+            String[] parts = file.getName().split("\\.");
+            if (parts.length == 2 && parts[1].equals(stateName)) {
+                try {
+                    result.add(Long.parseUnsignedLong(parts[0], 16));
+                } catch (NumberFormatException e) {
+                    Slog.e(TAG, "Failed to parse handle " + parts[0]);
+                }
+            }
+        }
+        return result;
+    }
+
+    @VisibleForTesting
+    protected File getSyntheticPasswordDirectoryForUser(int userId) {
+        return new File(Environment.getDataSystemDeDirectory(userId) ,SYNTHETIC_PASSWORD_DIRECTORY);
+    }
+
+    @VisibleForTesting
+    protected String getSynthenticPasswordStateFilePathForUser(int userId, long handle,
+            String name) {
+        File baseDir = getSyntheticPasswordDirectoryForUser(userId);
+        String baseName = String.format("%016x.%s", handle, name);
+        if (!baseDir.exists()) {
+            baseDir.mkdir();
+        }
+        return new File(baseDir, baseName).getAbsolutePath();
+    }
+
+    public void removeUser(int userId) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
+        final UserInfo parentInfo = um.getProfileParent(userId);
+
+        if (parentInfo == null) {
+            // This user owns its lock settings files - safe to delete them
+            synchronized (mFileWriteLock) {
+                String name = getLockPasswordFilename(userId);
+                File file = new File(name);
+                if (file.exists()) {
+                    file.delete();
+                    mCache.putFile(name, null);
+                }
+                name = getLockPatternFilename(userId);
+                file = new File(name);
+                if (file.exists()) {
+                    file.delete();
+                    mCache.putFile(name, null);
+                }
+            }
+        } else {
+            // Managed profile
+            removeChildProfileLock(userId);
+        }
+
+        File spStateDir = getSyntheticPasswordDirectoryForUser(userId);
+        try {
+            db.beginTransaction();
+            db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null);
+            db.setTransactionSuccessful();
+            mCache.removeUser(userId);
+            // The directory itself will be deleted as part of user deletion operation by the
+            // framework, so only need to purge cache here.
+            //TODO: (b/34600579) invoke secdiscardable
+            mCache.purgePath(spStateDir.getAbsolutePath());
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    @VisibleForTesting
+    void closeDatabase() {
+        mOpenHelper.close();
+    }
+
+    @VisibleForTesting
+    void clearCache() {
+        mCache.clear();
+    }
+
+    @Nullable
+    public PersistentDataBlockManagerInternal getPersistentDataBlock() {
+        if (mPersistentDataBlockManagerInternal == null) {
+            mPersistentDataBlockManagerInternal =
+                    LocalServices.getService(PersistentDataBlockManagerInternal.class);
+        }
+        return mPersistentDataBlockManagerInternal;
+    }
+
+    public void writePersistentDataBlock(int persistentType, int userId, int qualityForUi,
+            byte[] payload) {
+        PersistentDataBlockManagerInternal persistentDataBlock = getPersistentDataBlock();
+        if (persistentDataBlock == null) {
+            return;
+        }
+        persistentDataBlock.setFrpCredentialHandle(PersistentData.toBytes(
+                persistentType, userId, qualityForUi, payload));
+    }
+
+    public PersistentData readPersistentDataBlock() {
+        PersistentDataBlockManagerInternal persistentDataBlock = getPersistentDataBlock();
+        if (persistentDataBlock == null) {
+            return PersistentData.NONE;
+        }
+        return PersistentData.fromBytes(persistentDataBlock.getFrpCredentialHandle());
+    }
+
+    public static class PersistentData {
+        static final byte VERSION_1 = 1;
+        static final int VERSION_1_HEADER_SIZE = 1 + 1 + 4 + 4;
+
+        public static final int TYPE_NONE = 0;
+        public static final int TYPE_GATEKEEPER = 1;
+        public static final int TYPE_SP = 2;
+        public static final int TYPE_SP_WEAVER = 3;
+
+        public static final PersistentData NONE = new PersistentData(TYPE_NONE,
+                UserHandle.USER_NULL, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, null);
+
+        final int type;
+        final int userId;
+        final int qualityForUi;
+        final byte[] payload;
+
+        private PersistentData(int type, int userId, int qualityForUi, byte[] payload) {
+            this.type = type;
+            this.userId = userId;
+            this.qualityForUi = qualityForUi;
+            this.payload = payload;
+        }
+
+        public static PersistentData fromBytes(byte[] frpData) {
+            if (frpData == null || frpData.length == 0) {
+                return NONE;
+            }
+
+            DataInputStream is = new DataInputStream(new ByteArrayInputStream(frpData));
+            try {
+                byte version = is.readByte();
+                if (version == PersistentData.VERSION_1) {
+                    int type = is.readByte() & 0xFF;
+                    int userId = is.readInt();
+                    int qualityForUi = is.readInt();
+                    byte[] payload = new byte[frpData.length - VERSION_1_HEADER_SIZE];
+                    System.arraycopy(frpData, VERSION_1_HEADER_SIZE, payload, 0, payload.length);
+                    return new PersistentData(type, userId, qualityForUi, payload);
+                } else {
+                    Slog.wtf(TAG, "Unknown PersistentData version code: " + version);
+                    return null;
+                }
+            } catch (IOException e) {
+                Slog.wtf(TAG, "Could not parse PersistentData", e);
+                return null;
+            }
+        }
+
+        public static byte[] toBytes(int persistentType, int userId, int qualityForUi,
+                byte[] payload) {
+            if (persistentType == PersistentData.TYPE_NONE) {
+                Preconditions.checkArgument(payload == null,
+                        "TYPE_NONE must have empty payload");
+                return null;
+            }
+            Preconditions.checkArgument(payload != null && payload.length > 0,
+                    "empty payload must only be used with TYPE_NONE");
+
+            ByteArrayOutputStream os = new ByteArrayOutputStream(
+                    VERSION_1_HEADER_SIZE + payload.length);
+            DataOutputStream dos = new DataOutputStream(os);
+            try {
+                dos.writeByte(PersistentData.VERSION_1);
+                dos.writeByte(persistentType);
+                dos.writeInt(userId);
+                dos.writeInt(qualityForUi);
+                dos.write(payload);
+            } catch (IOException e) {
+                throw new RuntimeException("ByteArrayOutputStream cannot throw IOException");
+            }
+            return os.toByteArray();
+        }
+    }
+
+    public interface Callback {
+        void initialize(SQLiteDatabase db);
+    }
+
+    static class DatabaseHelper extends SQLiteOpenHelper {
+        private static final String TAG = "LockSettingsDB";
+        private static final String DATABASE_NAME = "locksettings.db";
+
+        private static final int DATABASE_VERSION = 2;
+
+        private Callback mCallback;
+
+        public DatabaseHelper(Context context) {
+            super(context, DATABASE_NAME, null, DATABASE_VERSION);
+            setWriteAheadLoggingEnabled(true);
+        }
+
+        public void setCallback(Callback callback) {
+            mCallback = callback;
+        }
+
+        private void createTable(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE " + TABLE + " (" +
+                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
+                    COLUMN_KEY + " TEXT," +
+                    COLUMN_USERID + " INTEGER," +
+                    COLUMN_VALUE + " TEXT" +
+                    ");");
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            createTable(db);
+            if (mCallback != null) {
+                mCallback.initialize(db);
+            }
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
+            int upgradeVersion = oldVersion;
+            if (upgradeVersion == 1) {
+                // Previously migrated lock screen widget settings. Now defunct.
+                upgradeVersion = 2;
+            }
+
+            if (upgradeVersion != DATABASE_VERSION) {
+                Log.w(TAG, "Failed to upgrade database!");
+            }
+        }
+    }
+
+    /**
+     * Cache consistency model:
+     * - Writes to storage write directly to the cache, but this MUST happen within the atomic
+     *   section either provided by the database transaction or mWriteLock, such that writes to the
+     *   cache and writes to the backing storage are guaranteed to occur in the same order
+     *
+     * - Reads can populate the cache, but because they are no strong ordering guarantees with
+     *   respect to writes this precaution is taken:
+     *   - The cache is assigned a version number that increases every time the cache is modified.
+     *     Reads from backing storage can only populate the cache if the backing storage
+     *     has not changed since the load operation has begun.
+     *     This guarantees that no read operation can shadow a write to the cache that happens
+     *     after it had begun.
+     */
+    private static class Cache {
+        private final ArrayMap<CacheKey, Object> mCache = new ArrayMap<>();
+        private final CacheKey mCacheKey = new CacheKey();
+        private int mVersion = 0;
+
+        String peekKeyValue(String key, String defaultValue, int userId) {
+            Object cached = peek(CacheKey.TYPE_KEY_VALUE, key, userId);
+            return cached == DEFAULT ? defaultValue : (String) cached;
+        }
+
+        boolean hasKeyValue(String key, int userId) {
+            return contains(CacheKey.TYPE_KEY_VALUE, key, userId);
+        }
+
+        void putKeyValue(String key, String value, int userId) {
+            put(CacheKey.TYPE_KEY_VALUE, key, value, userId);
+        }
+
+        void putKeyValueIfUnchanged(String key, Object value, int userId, int version) {
+            putIfUnchanged(CacheKey.TYPE_KEY_VALUE, key, value, userId, version);
+        }
+
+        byte[] peekFile(String fileName) {
+            return (byte[]) peek(CacheKey.TYPE_FILE, fileName, -1 /* userId */);
+        }
+
+        boolean hasFile(String fileName) {
+            return contains(CacheKey.TYPE_FILE, fileName, -1 /* userId */);
+        }
+
+        void putFile(String key, byte[] value) {
+            put(CacheKey.TYPE_FILE, key, value, -1 /* userId */);
+        }
+
+        void putFileIfUnchanged(String key, byte[] value, int version) {
+            putIfUnchanged(CacheKey.TYPE_FILE, key, value, -1 /* userId */, version);
+        }
+
+        void setFetched(int userId) {
+            put(CacheKey.TYPE_FETCHED, "isFetched", "true", userId);
+        }
+
+        boolean isFetched(int userId) {
+            return contains(CacheKey.TYPE_FETCHED, "", userId);
+        }
+
+
+        private synchronized void put(int type, String key, Object value, int userId) {
+            // Create a new CachKey here because it may be saved in the map if the key is absent.
+            mCache.put(new CacheKey().set(type, key, userId), value);
+            mVersion++;
+        }
+
+        private synchronized void putIfUnchanged(int type, String key, Object value, int userId,
+                int version) {
+            if (!contains(type, key, userId) && mVersion == version) {
+                put(type, key, value, userId);
+            }
+        }
+
+        private synchronized boolean contains(int type, String key, int userId) {
+            return mCache.containsKey(mCacheKey.set(type, key, userId));
+        }
+
+        private synchronized Object peek(int type, String key, int userId) {
+            return mCache.get(mCacheKey.set(type, key, userId));
+        }
+
+        private synchronized int getVersion() {
+            return mVersion;
+        }
+
+        synchronized void removeUser(int userId) {
+            for (int i = mCache.size() - 1; i >= 0; i--) {
+                if (mCache.keyAt(i).userId == userId) {
+                    mCache.removeAt(i);
+                }
+            }
+
+            // Make sure in-flight loads can't write to cache.
+            mVersion++;
+        }
+
+        synchronized void purgePath(String path) {
+            for (int i = mCache.size() - 1; i >= 0; i--) {
+                CacheKey entry = mCache.keyAt(i);
+                if (entry.type == CacheKey.TYPE_FILE && entry.key.startsWith(path)) {
+                    mCache.removeAt(i);
+                }
+            }
+            mVersion++;
+        }
+
+        synchronized void clear() {
+            mCache.clear();
+            mVersion++;
+        }
+
+        private static final class CacheKey {
+            static final int TYPE_KEY_VALUE = 0;
+            static final int TYPE_FILE = 1;
+            static final int TYPE_FETCHED = 2;
+
+            String key;
+            int userId;
+            int type;
+
+            public CacheKey set(int type, String key, int userId) {
+                this.type = type;
+                this.key = key;
+                this.userId = userId;
+                return this;
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                if (!(obj instanceof CacheKey))
+                    return false;
+                CacheKey o = (CacheKey) obj;
+                return userId == o.userId && type == o.type && key.equals(o.key);
+            }
+
+            @Override
+            public int hashCode() {
+                return key.hashCode() ^ userId ^ type;
+            }
+        }
+    }
+
+}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
new file mode 100644
index 0000000..0966153
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
@@ -0,0 +1,231 @@
+/*
+ * 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.server.locksettings;
+
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
+
+import android.app.AlarmManager;
+import android.app.AlarmManager.OnAlarmListener;
+import android.app.admin.DevicePolicyManager;
+import android.app.trust.IStrongAuthTracker;
+import android.content.Context;
+import android.os.Binder;
+import android.os.DeadObjectException;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.Slog;
+import android.util.SparseIntArray;
+
+import java.util.ArrayList;
+
+/**
+ * Keeps track of requests for strong authentication.
+ */
+public class LockSettingsStrongAuth {
+
+    private static final String TAG = "LockSettings";
+
+    private static final int MSG_REQUIRE_STRONG_AUTH = 1;
+    private static final int MSG_REGISTER_TRACKER = 2;
+    private static final int MSG_UNREGISTER_TRACKER = 3;
+    private static final int MSG_REMOVE_USER = 4;
+    private static final int MSG_SCHEDULE_STRONG_AUTH_TIMEOUT = 5;
+
+    private static final String STRONG_AUTH_TIMEOUT_ALARM_TAG =
+            "LockSettingsStrongAuth.timeoutForUser";
+
+    private final ArrayList<IStrongAuthTracker> mStrongAuthTrackers = new ArrayList<>();
+    private final SparseIntArray mStrongAuthForUser = new SparseIntArray();
+    private final ArrayMap<Integer, StrongAuthTimeoutAlarmListener>
+            mStrongAuthTimeoutAlarmListenerForUser = new ArrayMap<>();
+    private final int mDefaultStrongAuthFlags;
+    private final Context mContext;
+
+    private AlarmManager mAlarmManager;
+
+    public LockSettingsStrongAuth(Context context) {
+        mContext = context;
+        mDefaultStrongAuthFlags = StrongAuthTracker.getDefaultFlags(context);
+        mAlarmManager = context.getSystemService(AlarmManager.class);
+    }
+
+    private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) {
+        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+            if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
+                return;
+            }
+        }
+        mStrongAuthTrackers.add(tracker);
+
+        for (int i = 0; i < mStrongAuthForUser.size(); i++) {
+            int key = mStrongAuthForUser.keyAt(i);
+            int value = mStrongAuthForUser.valueAt(i);
+            try {
+                tracker.onStrongAuthRequiredChanged(value, key);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Exception while adding StrongAuthTracker.", e);
+            }
+        }
+    }
+
+    private void handleRemoveStrongAuthTracker(IStrongAuthTracker tracker) {
+        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+            if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
+                mStrongAuthTrackers.remove(i);
+                return;
+            }
+        }
+    }
+
+    private void handleRequireStrongAuth(int strongAuthReason, int userId) {
+        if (userId == UserHandle.USER_ALL) {
+            for (int i = 0; i < mStrongAuthForUser.size(); i++) {
+                int key = mStrongAuthForUser.keyAt(i);
+                handleRequireStrongAuthOneUser(strongAuthReason, key);
+            }
+        } else {
+            handleRequireStrongAuthOneUser(strongAuthReason, userId);
+        }
+    }
+
+    private void handleRequireStrongAuthOneUser(int strongAuthReason, int userId) {
+        int oldValue = mStrongAuthForUser.get(userId, mDefaultStrongAuthFlags);
+        int newValue = strongAuthReason == STRONG_AUTH_NOT_REQUIRED
+                ? STRONG_AUTH_NOT_REQUIRED
+                : (oldValue | strongAuthReason);
+        if (oldValue != newValue) {
+            mStrongAuthForUser.put(userId, newValue);
+            notifyStrongAuthTrackers(newValue, userId);
+        }
+    }
+
+    private void handleRemoveUser(int userId) {
+        int index = mStrongAuthForUser.indexOfKey(userId);
+        if (index >= 0) {
+            mStrongAuthForUser.removeAt(index);
+            notifyStrongAuthTrackers(mDefaultStrongAuthFlags, userId);
+        }
+    }
+
+    private void handleScheduleStrongAuthTimeout(int userId) {
+        final DevicePolicyManager dpm =
+                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        long when = SystemClock.elapsedRealtime() + dpm.getRequiredStrongAuthTimeout(null, userId);
+        // cancel current alarm listener for the user (if there was one)
+        StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId);
+        if (alarm != null) {
+            mAlarmManager.cancel(alarm);
+        } else {
+            alarm = new StrongAuthTimeoutAlarmListener(userId);
+            mStrongAuthTimeoutAlarmListenerForUser.put(userId, alarm);
+        }
+        // schedule a new alarm listener for the user
+        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, STRONG_AUTH_TIMEOUT_ALARM_TAG,
+                alarm, mHandler);
+    }
+
+    private void notifyStrongAuthTrackers(int strongAuthReason, int userId) {
+        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+            try {
+                mStrongAuthTrackers.get(i).onStrongAuthRequiredChanged(strongAuthReason, userId);
+            } catch (DeadObjectException e) {
+                Slog.d(TAG, "Removing dead StrongAuthTracker.");
+                mStrongAuthTrackers.remove(i);
+                i--;
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Exception while notifying StrongAuthTracker.", e);
+            }
+        }
+    }
+
+    public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
+        mHandler.obtainMessage(MSG_REGISTER_TRACKER, tracker).sendToTarget();
+    }
+
+    public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
+        mHandler.obtainMessage(MSG_UNREGISTER_TRACKER, tracker).sendToTarget();
+    }
+
+    public void removeUser(int userId) {
+        final int argNotUsed = 0;
+        mHandler.obtainMessage(MSG_REMOVE_USER, userId, argNotUsed).sendToTarget();
+    }
+
+    public void requireStrongAuth(int strongAuthReason, int userId) {
+        if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_SYSTEM) {
+            mHandler.obtainMessage(MSG_REQUIRE_STRONG_AUTH, strongAuthReason,
+                    userId).sendToTarget();
+        } else {
+            throw new IllegalArgumentException(
+                    "userId must be an explicit user id or USER_ALL");
+        }
+    }
+
+    public void reportUnlock(int userId) {
+        requireStrongAuth(STRONG_AUTH_NOT_REQUIRED, userId);
+    }
+
+    public void reportSuccessfulStrongAuthUnlock(int userId) {
+        final int argNotUsed = 0;
+        mHandler.obtainMessage(MSG_SCHEDULE_STRONG_AUTH_TIMEOUT, userId, argNotUsed).sendToTarget();
+    }
+
+    private class StrongAuthTimeoutAlarmListener implements OnAlarmListener {
+
+        private final int mUserId;
+
+        public StrongAuthTimeoutAlarmListener(int userId) {
+            mUserId = userId;
+        }
+
+        @Override
+        public void onAlarm() {
+            requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, mUserId);
+        }
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_REGISTER_TRACKER:
+                    handleAddStrongAuthTracker((IStrongAuthTracker) msg.obj);
+                    break;
+                case MSG_UNREGISTER_TRACKER:
+                    handleRemoveStrongAuthTracker((IStrongAuthTracker) msg.obj);
+                    break;
+                case MSG_REQUIRE_STRONG_AUTH:
+                    handleRequireStrongAuth(msg.arg1, msg.arg2);
+                    break;
+                case MSG_REMOVE_USER:
+                    handleRemoveUser(msg.arg1);
+                    break;
+                case MSG_SCHEDULE_STRONG_AUTH_TIMEOUT:
+                    handleScheduleStrongAuthTimeout(msg.arg1);
+                    break;
+            }
+        }
+    };
+}
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
new file mode 100644
index 0000000..b7bca1fb
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
@@ -0,0 +1,196 @@
+/*
+ * 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.locksettings;
+
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.Arrays;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+public class SyntheticPasswordCrypto {
+    private static final int PROFILE_KEY_IV_SIZE = 12;
+    private static final int AES_KEY_LENGTH = 32; // 256-bit AES key
+    private static final byte[] APPLICATION_ID_PERSONALIZATION = "application-id".getBytes();
+    // Time between the user credential is verified with GK and the decryption of synthetic password
+    // under the auth-bound key. This should always happen one after the other, but give it 15
+    // seconds just to be sure.
+    private static final int USER_AUTHENTICATION_VALIDITY = 15;
+
+    private static byte[] decrypt(SecretKey key, byte[] blob)
+            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
+        if (blob == null) {
+            return null;
+        }
+        byte[] iv = Arrays.copyOfRange(blob, 0, PROFILE_KEY_IV_SIZE);
+        byte[] ciphertext = Arrays.copyOfRange(blob, PROFILE_KEY_IV_SIZE, blob.length);
+        Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+                + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
+        cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(128, iv));
+        return cipher.doFinal(ciphertext);
+    }
+
+    private static byte[] encrypt(SecretKey key, byte[] blob)
+            throws IOException, NoSuchAlgorithmException, NoSuchPaddingException,
+            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
+        if (blob == null) {
+            return null;
+        }
+        Cipher cipher = Cipher.getInstance(
+                KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
+                        + KeyProperties.ENCRYPTION_PADDING_NONE);
+        cipher.init(Cipher.ENCRYPT_MODE, key);
+        byte[] ciphertext = cipher.doFinal(blob);
+        byte[] iv = cipher.getIV();
+        if (iv.length != PROFILE_KEY_IV_SIZE) {
+            throw new RuntimeException("Invalid iv length: " + iv.length);
+        }
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        outputStream.write(iv);
+        outputStream.write(ciphertext);
+        return outputStream.toByteArray();
+    }
+
+    public static byte[] encrypt(byte[] keyBytes, byte[] personalisation, byte[] message) {
+        byte[] keyHash = personalisedHash(personalisation, keyBytes);
+        SecretKeySpec key = new SecretKeySpec(Arrays.copyOf(keyHash, AES_KEY_LENGTH),
+                KeyProperties.KEY_ALGORITHM_AES);
+        try {
+            return encrypt(key, message);
+        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
+                | IllegalBlockSizeException | BadPaddingException | IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static byte[] decrypt(byte[] keyBytes, byte[] personalisation, byte[] ciphertext) {
+        byte[] keyHash = personalisedHash(personalisation, keyBytes);
+        SecretKeySpec key = new SecretKeySpec(Arrays.copyOf(keyHash, AES_KEY_LENGTH),
+                KeyProperties.KEY_ALGORITHM_AES);
+        try {
+            return decrypt(key, ciphertext);
+        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
+                | IllegalBlockSizeException | BadPaddingException
+                | InvalidAlgorithmParameterException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] applicationId) {
+        try {
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+
+            SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
+            byte[] intermediate = decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, blob);
+            return decrypt(decryptionKey, intermediate);
+        } catch (CertificateException | IOException | BadPaddingException
+                | IllegalBlockSizeException
+                | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
+                | InvalidKeyException | UnrecoverableKeyException
+                | InvalidAlgorithmParameterException e) {
+            e.printStackTrace();
+            throw new RuntimeException("Failed to decrypt blob", e);
+        }
+    }
+
+    public static byte[] createBlob(String keyAlias, byte[] data, byte[] applicationId, long sid) {
+        try {
+            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
+            keyGenerator.init(new SecureRandom());
+            SecretKey secretKey = keyGenerator.generateKey();
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
+                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                    .setCriticalToDeviceEncryption(true);
+            if (sid != 0) {
+                builder.setUserAuthenticationRequired(true)
+                        .setBoundToSpecificSecureUserId(sid)
+                        .setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_VALIDITY);
+            }
+
+            keyStore.setEntry(keyAlias,
+                    new KeyStore.SecretKeyEntry(secretKey),
+                    builder.build());
+            byte[] intermediate = encrypt(secretKey, data);
+            return encrypt(applicationId, APPLICATION_ID_PERSONALIZATION, intermediate);
+
+        } catch (CertificateException | IOException | BadPaddingException
+                | IllegalBlockSizeException
+                | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
+                | InvalidKeyException e) {
+            e.printStackTrace();
+            throw new RuntimeException("Failed to encrypt blob", e);
+        }
+    }
+
+    public static void destroyBlobKey(String keyAlias) {
+        KeyStore keyStore;
+        try {
+            keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            keyStore.deleteEntry(keyAlias);
+        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
+                | IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    protected static byte[] personalisedHash(byte[] personalisation, byte[]... message) {
+        try {
+            final int PADDING_LENGTH = 128;
+            MessageDigest digest = MessageDigest.getInstance("SHA-512");
+            if (personalisation.length > PADDING_LENGTH) {
+                throw new RuntimeException("Personalisation too long");
+            }
+            // Personalize the hash
+            // Pad it to the block size of the hash function
+            personalisation = Arrays.copyOf(personalisation, PADDING_LENGTH);
+            digest.update(personalisation);
+            for (byte[] data : message) {
+                digest.update(data);
+            }
+            return digest.digest();
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("NoSuchAlgorithmException for SHA-512", e);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
new file mode 100644
index 0000000..f45c208
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -0,0 +1,1107 @@
+/*
+ * 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.locksettings;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.admin.DevicePolicyManager;
+import android.hardware.weaver.V1_0.IWeaver;
+import android.hardware.weaver.V1_0.WeaverConfig;
+import android.hardware.weaver.V1_0.WeaverReadResponse;
+import android.hardware.weaver.V1_0.WeaverReadStatus;
+import android.hardware.weaver.V1_0.WeaverStatus;
+import android.security.GateKeeper;
+import android.os.RemoteException;
+import android.os.UserManager;
+import android.service.gatekeeper.GateKeeperResponse;
+import android.service.gatekeeper.IGateKeeperService;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.widget.ICheckCredentialProgressCallback;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.VerifyCredentialResponse;
+import com.android.server.locksettings.LockSettingsStorage.PersistentData;
+
+import libcore.util.HexEncoding;
+
+import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+
+/**
+ * A class that maintains the wrapping of synthetic password by user credentials or escrow tokens.
+ * It's (mostly) a pure storage for synthetic passwords, providing APIs to creating and destroying
+ * synthetic password blobs which are wrapped by user credentials or escrow tokens.
+ *
+ * Here is the assumptions it makes:
+ *   Each user has one single synthetic password at any time.
+ *   The SP has an associated password handle, which binds to the SID for that user. The password
+ *   handle is persisted by SyntheticPasswordManager internally.
+ *   If the user credential is null, it's treated as if the credential is DEFAULT_PASSWORD
+ *
+ * Information persisted on disk:
+ *   for each user (stored under DEFAULT_HANDLE):
+ *     SP_HANDLE_NAME: GateKeeper password handle of synthetic password. Only available if user
+ *                     credential exists, cleared when user clears their credential.
+ *     SP_E0_NAME, SP_P1_NAME: Secret to derive synthetic password when combined with escrow
+ *                     tokens. Destroyed when escrow support is turned off for the given user.
+ *
+ *     for each SP blob under the user (stored under the corresponding handle):
+ *       SP_BLOB_NAME: The encrypted synthetic password. Always exists.
+ *       PASSWORD_DATA_NAME: Metadata about user credential. Only exists for password based SP.
+ *       SECDISCARDABLE_NAME: Part of the necessary ingredient to decrypt SP_BLOB_NAME for the
+ *                            purpose of secure deletion. Exists if this is a non-weaver SP
+ *                            (both password and token based), or it's a token-based SP under weaver.
+ *       WEAVER_SLOT: Metadata about the weaver slot used. Only exists if this is a SP under weaver.
+ *
+ *
+ */
+public class SyntheticPasswordManager {
+    private static final String SP_BLOB_NAME = "spblob";
+    private static final String SP_E0_NAME = "e0";
+    private static final String SP_P1_NAME = "p1";
+    private static final String SP_HANDLE_NAME = "handle";
+    private static final String SECDISCARDABLE_NAME = "secdis";
+    private static final int SECDISCARDABLE_LENGTH = 16 * 1024;
+    private static final String PASSWORD_DATA_NAME = "pwd";
+    private static final String WEAVER_SLOT_NAME = "weaver";
+
+    public static final long DEFAULT_HANDLE = 0L;
+    private static final String DEFAULT_PASSWORD = "default-password";
+
+    private static final byte WEAVER_VERSION = 1;
+    private static final int INVALID_WEAVER_SLOT = -1;
+
+    private static final byte SYNTHETIC_PASSWORD_VERSION = 1;
+    private static final byte SYNTHETIC_PASSWORD_PASSWORD_BASED = 0;
+    private static final byte SYNTHETIC_PASSWORD_TOKEN_BASED = 1;
+
+    // 256-bit synthetic password
+    private static final byte SYNTHETIC_PASSWORD_LENGTH = 256 / 8;
+
+    private static final int PASSWORD_SCRYPT_N = 11;
+    private static final int PASSWORD_SCRYPT_R = 3;
+    private static final int PASSWORD_SCRYPT_P = 1;
+    private static final int PASSWORD_SALT_LENGTH = 16;
+    private static final int PASSWORD_TOKEN_LENGTH = 32;
+    private static final String TAG = "SyntheticPasswordManager";
+
+    private static final byte[] PERSONALISATION_SECDISCARDABLE = "secdiscardable-transform".getBytes();
+    private static final byte[] PERSONALIZATION_KEY_STORE_PASSWORD = "keystore-password".getBytes();
+    private static final byte[] PERSONALIZATION_USER_GK_AUTH = "user-gk-authentication".getBytes();
+    private static final byte[] PERSONALIZATION_SP_GK_AUTH = "sp-gk-authentication".getBytes();
+    private static final byte[] PERSONALIZATION_FBE_KEY = "fbe-key".getBytes();
+    private static final byte[] PERSONALIZATION_SP_SPLIT = "sp-split".getBytes();
+    private static final byte[] PERSONALIZATION_E0 = "e0-encryption".getBytes();
+    private static final byte[] PERSONALISATION_WEAVER_PASSWORD = "weaver-pwd".getBytes();
+    private static final byte[] PERSONALISATION_WEAVER_KEY = "weaver-key".getBytes();
+    private static final byte[] PERSONALISATION_WEAVER_TOKEN = "weaver-token".getBytes();
+
+    static class AuthenticationResult {
+        public AuthenticationToken authToken;
+        public VerifyCredentialResponse gkResponse;
+    }
+
+    static class AuthenticationToken {
+        /*
+         * Here is the relationship between all three fields:
+         * P0 and P1 are two randomly-generated blocks. P1 is stored on disk but P0 is not.
+         * syntheticPassword = hash(P0 || P1)
+         * E0 = P0 encrypted under syntheticPassword, stored on disk.
+         */
+        private @Nullable byte[] E0;
+        private @Nullable byte[] P1;
+        private @NonNull String syntheticPassword;
+
+        public String deriveKeyStorePassword() {
+            return bytesToHex(SyntheticPasswordCrypto.personalisedHash(
+                    PERSONALIZATION_KEY_STORE_PASSWORD, syntheticPassword.getBytes()));
+        }
+
+        public byte[] deriveGkPassword() {
+            return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_SP_GK_AUTH,
+                    syntheticPassword.getBytes());
+        }
+
+        public byte[] deriveDiskEncryptionKey() {
+            return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_FBE_KEY,
+                    syntheticPassword.getBytes());
+        }
+
+        private void initialize(byte[] P0, byte[] P1) {
+            this.P1 = P1;
+            this.syntheticPassword = String.valueOf(HexEncoding.encode(
+                    SyntheticPasswordCrypto.personalisedHash(
+                            PERSONALIZATION_SP_SPLIT, P0, P1)));
+            this.E0 = SyntheticPasswordCrypto.encrypt(this.syntheticPassword.getBytes(),
+                    PERSONALIZATION_E0, P0);
+        }
+
+        public void recreate(byte[] secret) {
+            initialize(secret, this.P1);
+        }
+
+        protected static AuthenticationToken create() {
+            AuthenticationToken result = new AuthenticationToken();
+            result.initialize(secureRandom(SYNTHETIC_PASSWORD_LENGTH),
+                    secureRandom(SYNTHETIC_PASSWORD_LENGTH));
+            return result;
+        }
+
+        public byte[] computeP0() {
+            if (E0 == null) {
+                return null;
+            }
+            return SyntheticPasswordCrypto.decrypt(syntheticPassword.getBytes(), PERSONALIZATION_E0,
+                    E0);
+        }
+    }
+
+    static class PasswordData {
+        byte scryptN;
+        byte scryptR;
+        byte scryptP;
+        public int passwordType;
+        byte[] salt;
+        // For GateKeeper-based credential, this is the password handle returned by GK,
+        // for weaver-based credential, this is empty.
+        public byte[] passwordHandle;
+
+        public static PasswordData create(int passwordType) {
+            PasswordData result = new PasswordData();
+            result.scryptN = PASSWORD_SCRYPT_N;
+            result.scryptR = PASSWORD_SCRYPT_R;
+            result.scryptP = PASSWORD_SCRYPT_P;
+            result.passwordType = passwordType;
+            result.salt = secureRandom(PASSWORD_SALT_LENGTH);
+            return result;
+        }
+
+        public static PasswordData fromBytes(byte[] data) {
+            PasswordData result = new PasswordData();
+            ByteBuffer buffer = ByteBuffer.allocate(data.length);
+            buffer.put(data, 0, data.length);
+            buffer.flip();
+            result.passwordType = buffer.getInt();
+            result.scryptN = buffer.get();
+            result.scryptR = buffer.get();
+            result.scryptP = buffer.get();
+            int saltLen = buffer.getInt();
+            result.salt = new byte[saltLen];
+            buffer.get(result.salt);
+            int handleLen = buffer.getInt();
+            if (handleLen > 0) {
+                result.passwordHandle = new byte[handleLen];
+                buffer.get(result.passwordHandle);
+            } else {
+                result.passwordHandle = null;
+            }
+            return result;
+        }
+
+        public byte[] toBytes() {
+
+            ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + 3 * Byte.BYTES
+                    + Integer.BYTES + salt.length + Integer.BYTES +
+                    (passwordHandle != null ? passwordHandle.length : 0));
+            buffer.putInt(passwordType);
+            buffer.put(scryptN);
+            buffer.put(scryptR);
+            buffer.put(scryptP);
+            buffer.putInt(salt.length);
+            buffer.put(salt);
+            if (passwordHandle != null && passwordHandle.length > 0) {
+                buffer.putInt(passwordHandle.length);
+                buffer.put(passwordHandle);
+            } else {
+                buffer.putInt(0);
+            }
+            return buffer.array();
+        }
+    }
+
+    static class TokenData {
+        byte[] secdiscardableOnDisk;
+        byte[] weaverSecret;
+        byte[] aggregatedSecret;
+    }
+
+    private LockSettingsStorage mStorage;
+    private IWeaver mWeaver;
+    private WeaverConfig mWeaverConfig;
+
+    private final UserManager mUserManager;
+
+    public SyntheticPasswordManager(LockSettingsStorage storage, UserManager userManager) {
+        mStorage = storage;
+        mUserManager = userManager;
+    }
+
+    @VisibleForTesting
+    protected IWeaver getWeaverService() throws RemoteException {
+        try {
+            return IWeaver.getService();
+        } catch (NoSuchElementException e) {
+            Slog.i(TAG, "Device does not support weaver");
+            return null;
+        }
+    }
+
+    public synchronized void initWeaverService() {
+        if (mWeaver != null) {
+            return;
+        }
+        try {
+            mWeaverConfig = null;
+            mWeaver = getWeaverService();
+            if (mWeaver != null) {
+                mWeaver.getConfig((int status, WeaverConfig config) -> {
+                    if (status == WeaverStatus.OK && config.slots > 0) {
+                        mWeaverConfig = config;
+                    } else {
+                        Slog.e(TAG, "Failed to get weaver config, status " + status
+                                + " slots: " + config.slots);
+                        mWeaver = null;
+                    }
+                });
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to get weaver service", e);
+        }
+    }
+
+    private synchronized boolean isWeaverAvailable() {
+        if (mWeaver == null) {
+            //Re-initializing weaver in case there was a transient error preventing access to it.
+            initWeaverService();
+        }
+        return mWeaver != null && mWeaverConfig.slots > 0;
+    }
+
+    /**
+     * Enroll the given key value pair into the specified weaver slot. if the given key is null,
+     * a default all-zero key is used. If the value is not specified, a fresh random secret is
+     * generated as the value.
+     *
+     * @return the value stored in the weaver slot
+     * @throws RemoteException
+     */
+    private byte[] weaverEnroll(int slot, byte[] key, @Nullable byte[] value)
+            throws RemoteException {
+        if (slot == INVALID_WEAVER_SLOT || slot >= mWeaverConfig.slots) {
+            throw new RuntimeException("Invalid slot for weaver");
+        }
+        if (key == null) {
+            key = new byte[mWeaverConfig.keySize];
+        } else if (key.length != mWeaverConfig.keySize) {
+            throw new RuntimeException("Invalid key size for weaver");
+        }
+        if (value == null) {
+            value = secureRandom(mWeaverConfig.valueSize);
+        }
+        int writeStatus = mWeaver.write(slot, toByteArrayList(key), toByteArrayList(value));
+        if (writeStatus != WeaverStatus.OK) {
+            Log.e(TAG, "weaver write failed, slot: " + slot + " status: " + writeStatus);
+            return null;
+        }
+        return value;
+    }
+
+    /**
+     * Verify the supplied key against a weaver slot, returning a response indicating whether
+     * the verification is successful, throttled or failed. If successful, the bound secret
+     * is also returned.
+     * @throws RemoteException
+     */
+    private VerifyCredentialResponse weaverVerify(int slot, byte[] key) throws RemoteException {
+        if (slot == INVALID_WEAVER_SLOT || slot >= mWeaverConfig.slots) {
+            throw new RuntimeException("Invalid slot for weaver");
+        }
+        if (key == null) {
+            key = new byte[mWeaverConfig.keySize];
+        } else if (key.length != mWeaverConfig.keySize) {
+            throw new RuntimeException("Invalid key size for weaver");
+        }
+        final VerifyCredentialResponse[] response = new VerifyCredentialResponse[1];
+        mWeaver.read(slot, toByteArrayList(key), (int status, WeaverReadResponse readResponse) -> {
+            switch (status) {
+                case WeaverReadStatus.OK:
+                    response[0] = new VerifyCredentialResponse(
+                            fromByteArrayList(readResponse.value));
+                    break;
+                case WeaverReadStatus.THROTTLE:
+                    response[0] = new VerifyCredentialResponse(readResponse.timeout);
+                    Log.e(TAG, "weaver read failed (THROTTLE), slot: " + slot);
+                    break;
+                case WeaverReadStatus.INCORRECT_KEY:
+                    if (readResponse.timeout == 0) {
+                        response[0] = VerifyCredentialResponse.ERROR;
+                        Log.e(TAG, "weaver read failed (INCORRECT_KEY), slot: " + slot);
+                    } else {
+                        response[0] = new VerifyCredentialResponse(readResponse.timeout);
+                        Log.e(TAG, "weaver read failed (INCORRECT_KEY/THROTTLE), slot: " + slot);
+                    }
+                    break;
+                case WeaverReadStatus.FAILED:
+                    response[0] = VerifyCredentialResponse.ERROR;
+                    Log.e(TAG, "weaver read failed (FAILED), slot: " + slot);
+                    break;
+               default:
+                   response[0] = VerifyCredentialResponse.ERROR;
+                   Log.e(TAG, "weaver read unknown status " + status + ", slot: " + slot);
+                   break;
+            }
+        });
+        return response[0];
+    }
+
+    public void removeUser(int userId) {
+        if (isWeaverAvailable()) {
+            for (long handle : mStorage.listSyntheticPasswordHandlesForUser(WEAVER_SLOT_NAME,
+                    userId)) {
+                destroyWeaverSlot(handle, userId);
+            }
+        }
+    }
+
+    public int getCredentialType(long handle, int userId) {
+        byte[] passwordData = loadState(PASSWORD_DATA_NAME, handle, userId);
+        if (passwordData == null) {
+            Log.w(TAG, "getCredentialType: encountered empty password data for user " + userId);
+            return LockPatternUtils.CREDENTIAL_TYPE_NONE;
+        }
+        return PasswordData.fromBytes(passwordData).passwordType;
+    }
+
+    /**
+     * Initializing a new Authentication token, possibly from an existing credential and hash.
+     *
+     * The authentication token would bear a randomly-generated synthetic password.
+     *
+     * This method has the side effect of rebinding the SID of the given user to the
+     * newly-generated SP.
+     *
+     * If the existing credential hash is non-null, the existing SID mill be migrated so
+     * the synthetic password in the authentication token will produce the same SID
+     * (the corresponding synthetic password handle is persisted by SyntheticPasswordManager
+     * in a per-user data storage.)
+     *
+     * If the existing credential hash is null, it means the given user should have no SID so
+     * SyntheticPasswordManager will nuke any SP handle previously persisted. In this case,
+     * the supplied credential parameter is also ignored.
+     *
+     * Also saves the escrow information necessary to re-generate the synthetic password under
+     * an escrow scheme. This information can be removed with {@link #destroyEscrowData} if
+     * password escrow should be disabled completely on the given user.
+     *
+     */
+    public AuthenticationToken newSyntheticPasswordAndSid(IGateKeeperService gatekeeper,
+            byte[] hash, String credential, int userId) throws RemoteException {
+        AuthenticationToken result = AuthenticationToken.create();
+        GateKeeperResponse response;
+        if (hash != null) {
+            response = gatekeeper.enroll(userId, hash, credential.getBytes(),
+                    result.deriveGkPassword());
+            if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
+                Log.w(TAG, "Fail to migrate SID, assuming no SID, user " + userId);
+                clearSidForUser(userId);
+            } else {
+                saveSyntheticPasswordHandle(response.getPayload(), userId);
+            }
+        } else {
+            clearSidForUser(userId);
+        }
+        saveEscrowData(result, userId);
+        return result;
+    }
+
+    /**
+     * Enroll a new password handle and SID for the given synthetic password and persist it on disk.
+     * Used when adding password to previously-unsecured devices.
+     */
+    public void newSidForUser(IGateKeeperService gatekeeper, AuthenticationToken authToken,
+            int userId) throws RemoteException {
+        GateKeeperResponse response = gatekeeper.enroll(userId, null, null,
+                authToken.deriveGkPassword());
+        if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
+            Log.e(TAG, "Fail to create new SID for user " + userId);
+            return;
+        }
+        saveSyntheticPasswordHandle(response.getPayload(), userId);
+    }
+
+    // Nuke the SP handle (and as a result, its SID) for the given user.
+    public void clearSidForUser(int userId) {
+        destroyState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
+    }
+
+    public boolean hasSidForUser(int userId) {
+        return hasState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
+    }
+
+    // if null, it means there is no SID associated with the user
+    // This can happen if the user is migrated to SP but currently
+    // do not have a lockscreen password.
+    private byte[] loadSyntheticPasswordHandle(int userId) {
+        return loadState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
+    }
+
+    private void saveSyntheticPasswordHandle(byte[] spHandle, int userId) {
+        saveState(SP_HANDLE_NAME, spHandle, DEFAULT_HANDLE, userId);
+    }
+
+    private boolean loadEscrowData(AuthenticationToken authToken, int userId) {
+        authToken.E0 = loadState(SP_E0_NAME, DEFAULT_HANDLE, userId);
+        authToken.P1 = loadState(SP_P1_NAME, DEFAULT_HANDLE, userId);
+        return authToken.E0 != null && authToken.P1 != null;
+    }
+
+    private void saveEscrowData(AuthenticationToken authToken, int userId) {
+        saveState(SP_E0_NAME, authToken.E0, DEFAULT_HANDLE, userId);
+        saveState(SP_P1_NAME, authToken.P1, DEFAULT_HANDLE, userId);
+    }
+
+    public boolean hasEscrowData(int userId) {
+        return hasState(SP_E0_NAME, DEFAULT_HANDLE, userId)
+                && hasState(SP_P1_NAME, DEFAULT_HANDLE, userId);
+    }
+
+    public void destroyEscrowData(int userId) {
+        destroyState(SP_E0_NAME, DEFAULT_HANDLE, userId);
+        destroyState(SP_P1_NAME, DEFAULT_HANDLE, userId);
+    }
+
+    private int loadWeaverSlot(long handle, int userId) {
+        final int LENGTH = Byte.BYTES + Integer.BYTES;
+        byte[] data = loadState(WEAVER_SLOT_NAME, handle, userId);
+        if (data == null || data.length != LENGTH) {
+            return INVALID_WEAVER_SLOT;
+        }
+        ByteBuffer buffer = ByteBuffer.allocate(LENGTH);
+        buffer.put(data, 0, data.length);
+        buffer.flip();
+        if (buffer.get() != WEAVER_VERSION) {
+            Log.e(TAG, "Invalid weaver slot version of handle " + handle);
+            return INVALID_WEAVER_SLOT;
+        }
+        return buffer.getInt();
+    }
+
+    private void saveWeaverSlot(int slot, long handle, int userId) {
+        ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES + Integer.BYTES);
+        buffer.put(WEAVER_VERSION);
+        buffer.putInt(slot);
+        saveState(WEAVER_SLOT_NAME, buffer.array(), handle, userId);
+    }
+
+    private void destroyWeaverSlot(long handle, int userId) {
+        int slot = loadWeaverSlot(handle, userId);
+        if (slot != INVALID_WEAVER_SLOT) {
+            try {
+                weaverEnroll(slot, null, null);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to destroy slot", e);
+            }
+        }
+        destroyState(WEAVER_SLOT_NAME, handle, userId);
+    }
+
+    private int getNextAvailableWeaverSlot() {
+        Map<Integer, List<Long>> slotHandles = mStorage.listSyntheticPasswordHandlesForAllUsers(
+                WEAVER_SLOT_NAME);
+        HashSet<Integer> slots = new HashSet<>();
+        for (Map.Entry<Integer, List<Long>> entry : slotHandles.entrySet()) {
+            for (Long handle : entry.getValue()) {
+                int slot = loadWeaverSlot(handle, entry.getKey());
+                slots.add(slot);
+            }
+        }
+        for (int i = 0; i < mWeaverConfig.slots; i++) {
+            if (!slots.contains(i)) {
+                return i;
+            }
+        }
+        throw new RuntimeException("Run out of weaver slots.");
+    }
+
+    /**
+     * Create a new password based SP blob based on the supplied authentication token, such that
+     * a future successful authentication with unwrapPasswordBasedSyntheticPassword() would result
+     * in the same authentication token.
+     *
+     * This method only creates SP blob wrapping around the given synthetic password and does not
+     * handle logic around SID or SP handle. The caller should separately ensure that the user's SID
+     * is consistent with the device state by calling other APIs in this class.
+     *
+     * @see #newSidForUser
+     * @see #clearSidForUser
+     */
+    public long createPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
+            String credential, int credentialType, AuthenticationToken authToken,
+            int requestedQuality, int userId)
+                    throws RemoteException {
+        if (credential == null || credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+            credentialType = LockPatternUtils.CREDENTIAL_TYPE_NONE;
+            credential = DEFAULT_PASSWORD;
+        }
+
+        long handle = generateHandle();
+        PasswordData pwd = PasswordData.create(credentialType);
+        byte[] pwdToken = computePasswordToken(credential, pwd);
+        final long sid;
+        final byte[] applicationId;
+
+        if (isWeaverAvailable()) {
+            // Weaver based user password
+            int weaverSlot = getNextAvailableWeaverSlot();
+            byte[] weaverSecret = weaverEnroll(weaverSlot, passwordTokenToWeaverKey(pwdToken), null);
+            if (weaverSecret == null) {
+                Log.e(TAG, "Fail to enroll user password under weaver " + userId);
+                return DEFAULT_HANDLE;
+            }
+            saveWeaverSlot(weaverSlot, handle, userId);
+            synchronizeWeaverFrpPassword(pwd, requestedQuality, userId, weaverSlot);
+
+            pwd.passwordHandle = null;
+            sid = GateKeeper.INVALID_SECURE_USER_ID;
+            applicationId = transformUnderWeaverSecret(pwdToken, weaverSecret);
+        } else {
+            // In case GK enrollment leaves persistent state around (in RPMB), this will nuke them
+            // to prevent them from accumulating and causing problems.
+            gatekeeper.clearSecureUserId(fakeUid(userId));
+            // GateKeeper based user password
+            GateKeeperResponse response = gatekeeper.enroll(fakeUid(userId), null, null,
+                    passwordTokenToGkInput(pwdToken));
+            if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
+                Log.e(TAG, "Fail to enroll user password when creating SP for user " + userId);
+                return DEFAULT_HANDLE;
+            }
+            pwd.passwordHandle = response.getPayload();
+            sid = sidFromPasswordHandle(pwd.passwordHandle);
+            applicationId = transformUnderSecdiscardable(pwdToken,
+                    createSecdiscardable(handle, userId));
+            synchronizeFrpPassword(pwd, requestedQuality, userId);
+        }
+        saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
+
+        createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED, authToken,
+                applicationId, sid, userId);
+        return handle;
+    }
+
+    public VerifyCredentialResponse verifyFrpCredential(IGateKeeperService gatekeeper,
+            String userCredential, int credentialType,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        PersistentData persistentData = mStorage.readPersistentDataBlock();
+        if (persistentData.type == PersistentData.TYPE_SP) {
+            PasswordData pwd = PasswordData.fromBytes(persistentData.payload);
+            byte[] pwdToken = computePasswordToken(userCredential, pwd);
+
+            GateKeeperResponse response = gatekeeper.verify(fakeUid(persistentData.userId),
+                    pwd.passwordHandle, passwordTokenToGkInput(pwdToken));
+            return VerifyCredentialResponse.fromGateKeeperResponse(response);
+        } else if (persistentData.type == PersistentData.TYPE_SP_WEAVER) {
+            PasswordData pwd = PasswordData.fromBytes(persistentData.payload);
+            byte[] pwdToken = computePasswordToken(userCredential, pwd);
+            int weaverSlot = persistentData.userId;
+
+            return weaverVerify(weaverSlot, passwordTokenToWeaverKey(pwdToken)).stripPayload();
+        } else {
+            Log.e(TAG, "persistentData.type must be TYPE_SP or TYPE_SP_WEAVER, but is "
+                    + persistentData.type);
+            return VerifyCredentialResponse.ERROR;
+        }
+    }
+
+
+    private void synchronizeFrpPassword(PasswordData pwd,
+            int requestedQuality, int userId) {
+        if (mStorage.getPersistentDataBlock() != null
+                && LockPatternUtils.userOwnsFrpCredential(mUserManager.getUserInfo(userId))) {
+            if (pwd.passwordType != LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+                mStorage.writePersistentDataBlock(PersistentData.TYPE_SP, userId, requestedQuality,
+                        pwd.toBytes());
+            } else {
+                mStorage.writePersistentDataBlock(PersistentData.TYPE_NONE, userId, 0, null);
+            }
+        }
+    }
+
+    private void synchronizeWeaverFrpPassword(PasswordData pwd, int requestedQuality, int userId,
+            int weaverSlot) {
+        if (mStorage.getPersistentDataBlock() != null
+                && LockPatternUtils.userOwnsFrpCredential(mUserManager.getUserInfo(userId))) {
+            if (pwd.passwordType != LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+                mStorage.writePersistentDataBlock(PersistentData.TYPE_SP_WEAVER, weaverSlot,
+                        requestedQuality, pwd.toBytes());
+            } else {
+                mStorage.writePersistentDataBlock(PersistentData.TYPE_NONE, 0, 0, null);
+            }
+        }
+    }
+
+    private ArrayMap<Integer, ArrayMap<Long, TokenData>> tokenMap = new ArrayMap<>();
+
+    public long createTokenBasedSyntheticPassword(byte[] token, int userId) {
+        long handle = generateHandle();
+        if (!tokenMap.containsKey(userId)) {
+            tokenMap.put(userId, new ArrayMap<>());
+        }
+        TokenData tokenData = new TokenData();
+        final byte[] secdiscardable = secureRandom(SECDISCARDABLE_LENGTH);
+        if (isWeaverAvailable()) {
+            tokenData.weaverSecret = secureRandom(mWeaverConfig.valueSize);
+            tokenData.secdiscardableOnDisk = SyntheticPasswordCrypto.encrypt(tokenData.weaverSecret,
+                            PERSONALISATION_WEAVER_TOKEN, secdiscardable);
+        } else {
+            tokenData.secdiscardableOnDisk = secdiscardable;
+            tokenData.weaverSecret = null;
+        }
+        tokenData.aggregatedSecret = transformUnderSecdiscardable(token, secdiscardable);
+
+        tokenMap.get(userId).put(handle, tokenData);
+        return handle;
+    }
+
+    public Set<Long> getPendingTokensForUser(int userId) {
+        if (!tokenMap.containsKey(userId)) {
+            return Collections.emptySet();
+        }
+        return tokenMap.get(userId).keySet();
+    }
+
+    public boolean removePendingToken(long handle, int userId) {
+        if (!tokenMap.containsKey(userId)) {
+            return false;
+        }
+        return tokenMap.get(userId).remove(handle) != null;
+    }
+
+    public boolean activateTokenBasedSyntheticPassword(long handle, AuthenticationToken authToken,
+            int userId) {
+        if (!tokenMap.containsKey(userId)) {
+            return false;
+        }
+        TokenData tokenData = tokenMap.get(userId).get(handle);
+        if (tokenData == null) {
+            return false;
+        }
+        if (!loadEscrowData(authToken, userId)) {
+            Log.w(TAG, "User is not escrowable");
+            return false;
+        }
+        if (isWeaverAvailable()) {
+            int slot = getNextAvailableWeaverSlot();
+            try {
+                weaverEnroll(slot, null, tokenData.weaverSecret);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to enroll weaver secret when activating token", e);
+                return false;
+            }
+            saveWeaverSlot(slot, handle, userId);
+        }
+        saveSecdiscardable(handle, tokenData.secdiscardableOnDisk, userId);
+        createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED, authToken,
+                tokenData.aggregatedSecret, 0L, userId);
+        tokenMap.get(userId).remove(handle);
+        return true;
+    }
+
+    private void createSyntheticPasswordBlob(long handle, byte type, AuthenticationToken authToken,
+            byte[] applicationId, long sid, int userId) {
+        final byte[] secret;
+        if (type == SYNTHETIC_PASSWORD_TOKEN_BASED) {
+            secret = authToken.computeP0();
+        } else {
+            secret = authToken.syntheticPassword.getBytes();
+        }
+        byte[] content = createSPBlob(getHandleName(handle), secret, applicationId, sid);
+        byte[] blob = new byte[content.length + 1 + 1];
+        blob[0] = SYNTHETIC_PASSWORD_VERSION;
+        blob[1] = type;
+        System.arraycopy(content, 0, blob, 2, content.length);
+        saveState(SP_BLOB_NAME, blob, handle, userId);
+    }
+
+    /**
+     * Decrypt a synthetic password by supplying the user credential and corresponding password
+     * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
+     * verification to referesh the SID & Auth token maintained by the system.
+     */
+    public AuthenticationResult unwrapPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
+            long handle, String credential, int userId) throws RemoteException {
+        if (credential == null) {
+            credential = DEFAULT_PASSWORD;
+        }
+        AuthenticationResult result = new AuthenticationResult();
+        PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, handle, userId));
+        byte[] pwdToken = computePasswordToken(credential, pwd);
+
+        final byte[] applicationId;
+        int weaverSlot = loadWeaverSlot(handle, userId);
+        if (weaverSlot != INVALID_WEAVER_SLOT) {
+            // Weaver based user password
+            if (!isWeaverAvailable()) {
+                Log.e(TAG, "No weaver service to unwrap password based SP");
+                result.gkResponse = VerifyCredentialResponse.ERROR;
+                return result;
+            }
+            result.gkResponse = weaverVerify(weaverSlot, passwordTokenToWeaverKey(pwdToken));
+            if (result.gkResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+                return result;
+            }
+            applicationId = transformUnderWeaverSecret(pwdToken, result.gkResponse.getPayload());
+        } else {
+            byte[] gkPwdToken = passwordTokenToGkInput(pwdToken);
+            GateKeeperResponse response = gatekeeper.verifyChallenge(fakeUid(userId), 0L,
+                    pwd.passwordHandle, gkPwdToken);
+            int responseCode = response.getResponseCode();
+            if (responseCode == GateKeeperResponse.RESPONSE_OK) {
+                result.gkResponse = VerifyCredentialResponse.OK;
+                if (response.getShouldReEnroll()) {
+                    GateKeeperResponse reenrollResponse = gatekeeper.enroll(fakeUid(userId),
+                            pwd.passwordHandle, gkPwdToken, gkPwdToken);
+                    if (reenrollResponse.getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
+                        pwd.passwordHandle = reenrollResponse.getPayload();
+                        saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
+                        synchronizeFrpPassword(pwd,
+                                pwd.passwordType == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
+                                ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
+                                : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
+                                /* TODO(roosa): keep the same password quality */,
+                                userId);
+                    } else {
+                        Log.w(TAG, "Fail to re-enroll user password for user " + userId);
+                        // continue the flow anyway
+                    }
+                }
+            } else if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
+                result.gkResponse = new VerifyCredentialResponse(response.getTimeout());
+                return result;
+            } else  {
+                result.gkResponse = VerifyCredentialResponse.ERROR;
+                return result;
+            }
+            applicationId = transformUnderSecdiscardable(pwdToken,
+                    loadSecdiscardable(handle, userId));
+        }
+
+        result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED,
+                applicationId, userId);
+
+        // Perform verifyChallenge to refresh auth tokens for GK if user password exists.
+        result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
+        return result;
+    }
+
+    /**
+     * Decrypt a synthetic password by supplying an escrow token and corresponding token
+     * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
+     * verification to referesh the SID & Auth token maintained by the system.
+     */
+    public @NonNull AuthenticationResult unwrapTokenBasedSyntheticPassword(
+            IGateKeeperService gatekeeper, long handle, byte[] token, int userId)
+                    throws RemoteException {
+        AuthenticationResult result = new AuthenticationResult();
+        byte[] secdiscardable = loadSecdiscardable(handle, userId);
+        int slotId = loadWeaverSlot(handle, userId);
+        if (slotId != INVALID_WEAVER_SLOT) {
+            if (!isWeaverAvailable()) {
+                Log.e(TAG, "No weaver service to unwrap token based SP");
+                result.gkResponse = VerifyCredentialResponse.ERROR;
+                return result;
+            }
+            VerifyCredentialResponse response = weaverVerify(slotId, null);
+            if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK ||
+                    response.getPayload() == null) {
+                Log.e(TAG, "Failed to retrieve weaver secret when unwrapping token");
+                result.gkResponse = VerifyCredentialResponse.ERROR;
+                return result;
+            }
+            secdiscardable = SyntheticPasswordCrypto.decrypt(response.getPayload(),
+                    PERSONALISATION_WEAVER_TOKEN, secdiscardable);
+        }
+        byte[] applicationId = transformUnderSecdiscardable(token, secdiscardable);
+        result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED,
+                applicationId, userId);
+        if (result.authToken != null) {
+            result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
+            if (result.gkResponse == null) {
+                // The user currently has no password. return OK with null payload so null
+                // is propagated to unlockUser()
+                result.gkResponse = VerifyCredentialResponse.OK;
+            }
+        } else {
+            result.gkResponse = VerifyCredentialResponse.ERROR;
+        }
+        return result;
+    }
+
+    private AuthenticationToken unwrapSyntheticPasswordBlob(long handle, byte type,
+            byte[] applicationId, int userId) {
+        byte[] blob = loadState(SP_BLOB_NAME, handle, userId);
+        if (blob == null) {
+            return null;
+        }
+        if (blob[0] != SYNTHETIC_PASSWORD_VERSION) {
+            throw new RuntimeException("Unknown blob version");
+        }
+        if (blob[1] != type) {
+            throw new RuntimeException("Invalid blob type");
+        }
+        byte[] secret = decryptSPBlob(getHandleName(handle),
+                Arrays.copyOfRange(blob, 2, blob.length), applicationId);
+        if (secret == null) {
+            Log.e(TAG, "Fail to decrypt SP for user " + userId);
+            return null;
+        }
+        AuthenticationToken result = new AuthenticationToken();
+        if (type == SYNTHETIC_PASSWORD_TOKEN_BASED) {
+            if (!loadEscrowData(result, userId)) {
+                Log.e(TAG, "User is not escrowable: " + userId);
+                return null;
+            }
+            result.recreate(secret);
+        } else {
+            result.syntheticPassword = new String(secret);
+        }
+        return result;
+    }
+
+    /**
+     * performs GK verifyChallenge and returns auth token, re-enrolling SP password handle
+     * if required.
+     *
+     * Normally performing verifyChallenge with an AuthenticationToken should always return
+     * RESPONSE_OK, since user authentication failures are detected earlier when trying to
+     * decrypt SP.
+     */
+    public @Nullable VerifyCredentialResponse verifyChallenge(IGateKeeperService gatekeeper,
+            @NonNull AuthenticationToken auth, long challenge, int userId) throws RemoteException {
+        byte[] spHandle = loadSyntheticPasswordHandle(userId);
+        if (spHandle == null) {
+            // There is no password handle associated with the given user, i.e. the user is not
+            // secured by lockscreen and has no SID, so just return here;
+            return null;
+        }
+        VerifyCredentialResponse result;
+        GateKeeperResponse response = gatekeeper.verifyChallenge(userId, challenge,
+                spHandle, auth.deriveGkPassword());
+        int responseCode = response.getResponseCode();
+        if (responseCode == GateKeeperResponse.RESPONSE_OK) {
+            result = new VerifyCredentialResponse(response.getPayload());
+            if (response.getShouldReEnroll()) {
+                response = gatekeeper.enroll(userId, spHandle,
+                        spHandle, auth.deriveGkPassword());
+                if (response.getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
+                    spHandle = response.getPayload();
+                    saveSyntheticPasswordHandle(spHandle, userId);
+                    // Call self again to re-verify with updated handle
+                    return verifyChallenge(gatekeeper, auth, challenge, userId);
+                } else {
+                    Log.w(TAG, "Fail to re-enroll SP handle for user " + userId);
+                    // Fall through, return existing handle
+                }
+            }
+        } else if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
+            result = new VerifyCredentialResponse(response.getTimeout());
+        } else {
+            result = VerifyCredentialResponse.ERROR;
+        }
+        return result;
+    }
+
+    public boolean existsHandle(long handle, int userId) {
+        return hasState(SP_BLOB_NAME, handle, userId);
+    }
+
+    public void destroyTokenBasedSyntheticPassword(long handle, int userId) {
+        destroySyntheticPassword(handle, userId);
+        destroyState(SECDISCARDABLE_NAME, handle, userId);
+    }
+
+    public void destroyPasswordBasedSyntheticPassword(long handle, int userId) {
+        destroySyntheticPassword(handle, userId);
+        destroyState(SECDISCARDABLE_NAME, handle, userId);
+        destroyState(PASSWORD_DATA_NAME, handle, userId);
+    }
+
+    private void destroySyntheticPassword(long handle, int userId) {
+        destroyState(SP_BLOB_NAME, handle, userId);
+        destroySPBlobKey(getHandleName(handle));
+        if (hasState(WEAVER_SLOT_NAME, handle, userId)) {
+            destroyWeaverSlot(handle, userId);
+        }
+    }
+
+    private byte[] transformUnderWeaverSecret(byte[] data, byte[] secret) {
+        byte[] weaverSecret = SyntheticPasswordCrypto.personalisedHash(
+                PERSONALISATION_WEAVER_PASSWORD, secret);
+        byte[] result = new byte[data.length + weaverSecret.length];
+        System.arraycopy(data, 0, result, 0, data.length);
+        System.arraycopy(weaverSecret, 0, result, data.length, weaverSecret.length);
+        return result;
+    }
+
+    private byte[] transformUnderSecdiscardable(byte[] data, byte[] rawSecdiscardable) {
+        byte[] secdiscardable = SyntheticPasswordCrypto.personalisedHash(
+                PERSONALISATION_SECDISCARDABLE, rawSecdiscardable);
+        byte[] result = new byte[data.length + secdiscardable.length];
+        System.arraycopy(data, 0, result, 0, data.length);
+        System.arraycopy(secdiscardable, 0, result, data.length, secdiscardable.length);
+        return result;
+    }
+
+    private byte[] createSecdiscardable(long handle, int userId) {
+        byte[] data = secureRandom(SECDISCARDABLE_LENGTH);
+        saveSecdiscardable(handle, data, userId);
+        return data;
+    }
+
+    private void saveSecdiscardable(long handle, byte[] secdiscardable, int userId) {
+        saveState(SECDISCARDABLE_NAME, secdiscardable, handle, userId);
+    }
+
+    private byte[] loadSecdiscardable(long handle, int userId) {
+        return loadState(SECDISCARDABLE_NAME, handle, userId);
+    }
+
+    private boolean hasState(String stateName, long handle, int userId) {
+        return !ArrayUtils.isEmpty(loadState(stateName, handle, userId));
+    }
+
+    private byte[] loadState(String stateName, long handle, int userId) {
+        return mStorage.readSyntheticPasswordState(userId, handle, stateName);
+    }
+
+    private void saveState(String stateName, byte[] data, long handle, int userId) {
+        mStorage.writeSyntheticPasswordState(userId, handle, stateName, data);
+    }
+
+    private void destroyState(String stateName, long handle, int userId) {
+        mStorage.deleteSyntheticPasswordState(userId, handle, stateName);
+    }
+
+    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
+        return SyntheticPasswordCrypto.decryptBlob(blobKeyName, blob, applicationId);
+    }
+
+    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
+        return SyntheticPasswordCrypto.createBlob(blobKeyName, data, applicationId, sid);
+    }
+
+    protected void destroySPBlobKey(String keyAlias) {
+        SyntheticPasswordCrypto.destroyBlobKey(keyAlias);
+    }
+
+    public static long generateHandle() {
+        SecureRandom rng = new SecureRandom();
+        long result;
+        do {
+            result = rng.nextLong();
+        } while (result == DEFAULT_HANDLE);
+        return result;
+    }
+
+    private int fakeUid(int uid) {
+        return 100000 + uid;
+    }
+
+    protected static byte[] secureRandom(int length) {
+        try {
+            return SecureRandom.getInstance("SHA1PRNG").generateSeed(length);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    private String getHandleName(long handle) {
+        return String.format("%s%x", LockPatternUtils.SYNTHETIC_PASSWORD_KEY_PREFIX, handle);
+    }
+
+    private byte[] computePasswordToken(String password, PasswordData data) {
+        return scrypt(password, data.salt, 1 << data.scryptN, 1 << data.scryptR, 1 << data.scryptP,
+                PASSWORD_TOKEN_LENGTH);
+    }
+
+    private byte[] passwordTokenToGkInput(byte[] token) {
+        return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_USER_GK_AUTH, token);
+    }
+
+    private byte[] passwordTokenToWeaverKey(byte[] token) {
+        byte[] key = SyntheticPasswordCrypto.personalisedHash(PERSONALISATION_WEAVER_KEY, token);
+        if (key.length < mWeaverConfig.keySize) {
+            throw new RuntimeException("weaver key length too small");
+        }
+        return Arrays.copyOf(key, mWeaverConfig.keySize);
+    }
+
+    protected long sidFromPasswordHandle(byte[] handle) {
+        return nativeSidFromPasswordHandle(handle);
+    }
+
+    protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) {
+        return nativeScrypt(password.getBytes(), salt, N, r, p, outLen);
+    }
+
+    native long nativeSidFromPasswordHandle(byte[] handle);
+    native byte[] nativeScrypt(byte[] password, byte[] salt, int N, int r, int p, int outLen);
+
+    protected static ArrayList<Byte> toByteArrayList(byte[] data) {
+        ArrayList<Byte> result = new ArrayList<Byte>(data.length);
+        for (int i = 0; i < data.length; i++) {
+            result.add(data[i]);
+        }
+        return result;
+    }
+
+    protected static byte[] fromByteArrayList(ArrayList<Byte> data) {
+        byte[] result = new byte[data.size()];
+        for (int i = 0; i < data.size(); i++) {
+            result[i] = data.get(i);
+        }
+        return result;
+    }
+
+    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
+    public static String bytesToHex(byte[] bytes) {
+        if (bytes == null) {
+            return "null";
+        }
+        char[] hexChars = new char[bytes.length * 2];
+        for ( int j = 0; j < bytes.length; j++ ) {
+            int v = bytes[j] & 0xFF;
+            hexChars[j * 2] = hexArray[v >>> 4];
+            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
+        }
+        return new String(hexChars);
+    }
+}
diff --git a/services/core/java/com/android/server/media/AudioPlaybackMonitor.java b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java
index c6dc11c..f6f7676 100644
--- a/services/core/java/com/android/server/media/AudioPlaybackMonitor.java
+++ b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java
@@ -31,17 +31,22 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
- * Monitors changes in audio playback and notify the newly started audio playback through the
- * {@link OnAudioPlaybackStartedListener}.
+ * Monitors changes in audio playback, and notify the newly started audio playback through the
+ * {@link OnAudioPlaybackStartedListener} and the activeness change through the
+ * {@link OnAudioPlaybackActiveStateListener}.
  */
 class AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub {
     private static boolean DEBUG = MediaSessionService.DEBUG;
     private static String TAG = "AudioPlaybackMonitor";
 
+    private static AudioPlaybackMonitor sInstance;
+
     /**
      * Called when audio playback is started for a given UID.
      */
@@ -49,22 +54,36 @@
         void onAudioPlaybackStarted(int uid);
     }
 
+    /**
+     * Called when audio player state is changed.
+     */
+    interface OnAudioPlayerActiveStateChangedListener {
+        void onAudioPlayerActiveStateChanged(int uid, boolean active);
+    }
+
     private final Object mLock = new Object();
     private final Context mContext;
-    private final OnAudioPlaybackStartedListener mListener;
-
-    private Set<Integer> mActiveAudioPlaybackPlayerInterfaceIds = new HashSet<>();
-    private Set<Integer> mActiveAudioPlaybackClientUids = new HashSet<>();
+    private final List<OnAudioPlaybackStartedListener> mAudioPlaybackStartedListeners
+            = new ArrayList<>();
+    private final List<OnAudioPlayerActiveStateChangedListener>
+            mAudioPlayerActiveStateChangedListeners = new ArrayList<>();
+    private final Map<Integer, Integer> mAudioPlaybackStates = new HashMap<>();
+    private final Set<Integer> mActiveAudioPlaybackClientUids = new HashSet<>();
 
     // Sorted array of UIDs that had active audio playback. (i.e. playing an audio/video)
     // The UID whose audio playback becomes active at the last comes first.
     // TODO(b/35278867): Find and use unique identifier for apps because apps may share the UID.
     private final IntArray mSortedAudioPlaybackClientUids = new IntArray();
 
-    AudioPlaybackMonitor(Context context, IAudioService audioService,
-            OnAudioPlaybackStartedListener listener) {
+    static AudioPlaybackMonitor getInstance(Context context, IAudioService audioService) {
+        if (sInstance == null) {
+            sInstance = new AudioPlaybackMonitor(context, audioService);
+        }
+        return sInstance;
+    }
+
+    private AudioPlaybackMonitor(Context context, IAudioService audioService) {
         mContext = context;
-        mListener = listener;
         try {
             audioService.registerPlaybackCallback(this);
         } catch (RemoteException e) {
@@ -84,9 +103,12 @@
     public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
         final long token = Binder.clearCallingIdentity();
         try {
-            Set<Integer> newActiveAudioPlaybackPlayerInterfaceIds = new HashSet<>();
             List<Integer> newActiveAudioPlaybackClientUids = new ArrayList<>();
+            List<OnAudioPlayerActiveStateChangedListener> audioPlayerActiveStateChangedListeners;
+            List<OnAudioPlaybackStartedListener> audioPlaybackStartedListeners;
             synchronized (mLock) {
+                // Update mActiveAudioPlaybackClientUids and mSortedAudioPlaybackClientUids,
+                // and find newly activated audio playbacks.
                 mActiveAudioPlaybackClientUids.clear();
                 for (AudioPlaybackConfiguration config : configs) {
                     // Ignore inactive (i.e. not playing) or PLAYER_TYPE_JAM_SOUNDPOOL
@@ -94,16 +116,14 @@
                     // playback.
                     // Note that we shouldn't ignore PLAYER_TYPE_UNKNOWN because it might be OEM
                     // specific audio/video players.
-                    if (!config.isActive()
-                            || config.getPlayerType()
+                    if (!config.isActive() || config.getPlayerType()
                             == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
                         continue;
                     }
-                    mActiveAudioPlaybackClientUids.add(config.getClientUid());
 
-                    newActiveAudioPlaybackPlayerInterfaceIds.add(config.getPlayerInterfaceId());
-                    if (!mActiveAudioPlaybackPlayerInterfaceIds.contains(
-                            config.getPlayerInterfaceId())) {
+                    mActiveAudioPlaybackClientUids.add(config.getClientUid());
+                    Integer oldState = mAudioPlaybackStates.get(config.getPlayerInterfaceId());
+                    if (!isActiveState(oldState)) {
                         if (DEBUG) {
                             Log.d(TAG, "Found a new active media playback. " +
                                     AudioPlaybackConfiguration.toLogFriendlyString(config));
@@ -120,11 +140,32 @@
                         mSortedAudioPlaybackClientUids.add(0, config.getClientUid());
                     }
                 }
-                mActiveAudioPlaybackPlayerInterfaceIds.clear();
-                mActiveAudioPlaybackPlayerInterfaceIds = newActiveAudioPlaybackPlayerInterfaceIds;
+                audioPlayerActiveStateChangedListeners = new ArrayList<>(
+                        mAudioPlayerActiveStateChangedListeners);
+                audioPlaybackStartedListeners = new ArrayList<>(mAudioPlaybackStartedListeners);
             }
+            // Notify the change of audio playback states.
+            for (AudioPlaybackConfiguration config : configs) {
+                boolean wasActive = isActiveState(
+                        mAudioPlaybackStates.get(config.getPlayerInterfaceId()));
+                boolean isActive = config.isActive();
+                if (wasActive != isActive) {
+                    for (OnAudioPlayerActiveStateChangedListener listener
+                            : audioPlayerActiveStateChangedListeners) {
+                        listener.onAudioPlayerActiveStateChanged(config.getClientUid(),
+                                isActive);
+                    }
+                }
+            }
+            // Notify the start of audio playback
             for (int uid : newActiveAudioPlaybackClientUids) {
-                mListener.onAudioPlaybackStarted(uid);
+                for (OnAudioPlaybackStartedListener listener : audioPlaybackStartedListeners) {
+                    listener.onAudioPlaybackStarted(uid);
+                }
+            }
+            mAudioPlaybackStates.clear();
+            for (AudioPlaybackConfiguration config : configs) {
+                mAudioPlaybackStates.put(config.getPlayerInterfaceId(), config.getPlayerState());
             }
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -132,6 +173,44 @@
     }
 
     /**
+     * Registers OnAudioPlaybackStartedListener.
+     */
+    public void registerOnAudioPlaybackStartedListener(OnAudioPlaybackStartedListener listener) {
+        synchronized (mLock) {
+            mAudioPlaybackStartedListeners.add(listener);
+        }
+    }
+
+    /**
+     * Unregisters OnAudioPlaybackStartedListener.
+     */
+    public void unregisterOnAudioPlaybackStartedListener(OnAudioPlaybackStartedListener listener) {
+        synchronized (mLock) {
+            mAudioPlaybackStartedListeners.remove(listener);
+        }
+    }
+
+    /**
+     * Registers OnAudioPlayerActiveStateChangedListener.
+     */
+    public void registerOnAudioPlayerActiveStateChangedListener(
+            OnAudioPlayerActiveStateChangedListener listener) {
+        synchronized (mLock) {
+            mAudioPlayerActiveStateChangedListeners.add(listener);
+        }
+    }
+
+    /**
+     * Unregisters OnAudioPlayerActiveStateChangedListener.
+     */
+    public void unregisterOnAudioPlayerActiveStateChangedListener(
+            OnAudioPlayerActiveStateChangedListener listener) {
+        synchronized (mLock) {
+            mAudioPlayerActiveStateChangedListeners.remove(listener);
+        }
+    }
+
+    /**
      * Returns the sorted list of UIDs that have had active audio playback. (i.e. playing an
      * audio/video) The UID whose audio playback becomes active at the last comes first.
      */
@@ -167,7 +246,8 @@
                 if (mSortedAudioPlaybackClientUids.get(i) == mediaButtonSessionUid) {
                     break;
                 }
-                if (userId == UserHandle.getUserId(mSortedAudioPlaybackClientUids.get(i))) {
+                int uid = mSortedAudioPlaybackClientUids.get(i);
+                if (userId == UserHandle.getUserId(uid) && !isPlaybackActive(uid)) {
                     // Clean up unnecessary UIDs.
                     // It doesn't need to be managed profile aware because it's just to prevent
                     // the list from increasing indefinitely. The media button session updating
@@ -198,4 +278,8 @@
             }
         }
     }
+
+    private boolean isActiveState(Integer state) {
+        return state != null && state.equals(AudioPlaybackConfiguration.PLAYER_STATE_STARTED);
+    }
 }
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 7b0e51e..922df1e 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.util.DumpUtils;
 import com.android.server.Watchdog;
+import com.android.server.media.AudioPlaybackMonitor.OnAudioPlayerActiveStateChangedListener;
 
 import android.Manifest;
 import android.app.ActivityManager;
@@ -26,7 +27,10 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.media.AudioRoutesInfo;
 import android.media.AudioSystem;
+import android.media.IAudioRoutesObserver;
+import android.media.IAudioService;
 import android.media.IMediaRouterClient;
 import android.media.IMediaRouterService;
 import android.media.MediaRouter;
@@ -39,9 +43,12 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.IntArray;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -89,10 +96,54 @@
     private final ArrayMap<IBinder, ClientRecord> mAllClientRecords =
             new ArrayMap<IBinder, ClientRecord>();
     private int mCurrentUserId = -1;
+    private boolean mHasBluetoothRoute = false;
+    private final IAudioService mAudioService;
+    private final AudioPlaybackMonitor mAudioPlaybackMonitor;
 
     public MediaRouterService(Context context) {
         mContext = context;
         Watchdog.getInstance().addMonitor(this);
+
+        mAudioService = IAudioService.Stub.asInterface(
+                ServiceManager.getService(Context.AUDIO_SERVICE));
+
+        mAudioPlaybackMonitor = AudioPlaybackMonitor.getInstance(context, mAudioService);
+        mAudioPlaybackMonitor.registerOnAudioPlayerActiveStateChangedListener(
+                new AudioPlaybackMonitor.OnAudioPlayerActiveStateChangedListener() {
+            @Override
+            public void onAudioPlayerActiveStateChanged(int uid, boolean active) {
+                if (active) {
+                    restoreRoute(uid);
+                } else {
+                    IntArray sortedAudioPlaybackClientUids =
+                            mAudioPlaybackMonitor.getSortedAudioPlaybackClientUids();
+                    boolean restored = false;
+                    for (int i = 0; i < sortedAudioPlaybackClientUids.size(); i++) {
+                        if (mAudioPlaybackMonitor.isPlaybackActive(
+                                sortedAudioPlaybackClientUids.get(i))) {
+                            restoreRoute(sortedAudioPlaybackClientUids.get(i));
+                            restored = true;
+                            break;
+                        }
+                    }
+                    if (!restored) {
+                        restoreBluetoothA2dp();
+                    }
+                }
+            }
+        });
+        AudioRoutesInfo audioRoutes = null;
+        try {
+            audioRoutes = mAudioService.startWatchingRoutes(new IAudioRoutesObserver.Stub() {
+                @Override
+                public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) {
+                    mHasBluetoothRoute = newRoutes.bluetoothName != null;
+                }
+            });
+        } catch (RemoteException e) {
+            Slog.w(TAG, "RemoteException in the audio service.");
+        }
+        mHasBluetoothRoute = (audioRoutes != null && audioRoutes.bluetoothName != null);
     }
 
     public void systemRunning() {
@@ -135,7 +186,7 @@
         final long token = Binder.clearCallingIdentity();
         try {
             synchronized (mLock) {
-                registerClientLocked(client, pid, packageName, resolvedUserId, trusted);
+                registerClientLocked(client, uid, pid, packageName, resolvedUserId, trusted);
             }
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -178,6 +229,23 @@
 
     // Binder call
     @Override
+    public boolean isPlaybackActive(IMediaRouterClient client) {
+        if (client == null) {
+            throw new IllegalArgumentException("client must not be null");
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                return isPlaybackActiveLocked(client);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    // Binder call
+    @Override
     public void setDiscoveryRequest(IMediaRouterClient client,
             int routeTypes, boolean activeScan) {
         if (client == null) {
@@ -198,7 +266,7 @@
     // A null routeId means that the client wants to unselect its current route.
     // The explicit flag indicates whether the change was explicitly requested by the
     // user or the application which may cause changes to propagate out to the rest
-    // of the system.  Should be false when the change is in response to a new globally
+    // of the system.  Should be false when the change is in response to a new
     // selected route or a default selection.
     @Override
     public void setSelectedRoute(IMediaRouterClient client, String routeId, boolean explicit) {
@@ -276,6 +344,36 @@
         }
     }
 
+    void restoreBluetoothA2dp() {
+        try {
+            mAudioService.setBluetoothA2dpOn(mHasBluetoothRoute);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "RemoteException while calling setBluetoothA2dpOn.");
+        }
+    }
+
+    void restoreRoute(int uid) {
+        ClientRecord clientRecord = null;
+        UserRecord userRecord = mUserRecords.get(UserHandle.getUserId(uid));
+        if (userRecord != null && userRecord.mClientRecords != null) {
+            for (ClientRecord cr : userRecord.mClientRecords) {
+                if (validatePackageName(uid, cr.mPackageName)) {
+                    clientRecord = cr;
+                    break;
+                }
+            }
+        }
+        if (clientRecord != null) {
+            try {
+                clientRecord.mClient.onRestoreRoute();
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Failed to call onRestoreRoute. Client probably died.");
+            }
+        } else {
+            restoreBluetoothA2dp();
+        }
+    }
+
     void switchUser() {
         synchronized (mLock) {
             int userId = ActivityManager.getCurrentUser();
@@ -304,7 +402,7 @@
     }
 
     private void registerClientLocked(IMediaRouterClient client,
-            int pid, String packageName, int userId, boolean trusted) {
+            int uid, int pid, String packageName, int userId, boolean trusted) {
         final IBinder binder = client.asBinder();
         ClientRecord clientRecord = mAllClientRecords.get(binder);
         if (clientRecord == null) {
@@ -314,7 +412,7 @@
                 userRecord = new UserRecord(userId);
                 newUser = true;
             }
-            clientRecord = new ClientRecord(userRecord, client, pid, packageName, trusted);
+            clientRecord = new ClientRecord(userRecord, client, uid, pid, packageName, trusted);
             try {
                 binder.linkToDeath(clientRecord, 0);
             } catch (RemoteException ex) {
@@ -350,6 +448,14 @@
         return null;
     }
 
+    private boolean isPlaybackActiveLocked(IMediaRouterClient client) {
+        ClientRecord clientRecord = mAllClientRecords.get(client.asBinder());
+        if (clientRecord != null) {
+            return mAudioPlaybackMonitor.isPlaybackActive(clientRecord.mUid);
+        }
+        return false;
+    }
+
     private void setDiscoveryRequestLocked(IMediaRouterClient client,
             int routeTypes, boolean activeScan) {
         final IBinder binder = client.asBinder();
@@ -387,15 +493,14 @@
                 }
 
                 clientRecord.mSelectedRouteId = routeId;
-                if (explicit) {
-                    // Any app can disconnect from the globally selected route.
+                // Only let the system connect to new global routes for now.
+                // A similar check exists in the display manager for wifi display.
+                if (explicit && clientRecord.mTrusted) {
                     if (oldRouteId != null) {
                         clientRecord.mUserRecord.mHandler.obtainMessage(
                                 UserHandler.MSG_UNSELECT_ROUTE, oldRouteId).sendToTarget();
                     }
-                    // Only let the system connect to new global routes for now.
-                    // A similar check exists in the display manager for wifi display.
-                    if (routeId != null && clientRecord.mTrusted) {
+                    if (routeId != null) {
                         clientRecord.mUserRecord.mHandler.obtainMessage(
                                 UserHandler.MSG_SELECT_ROUTE, routeId).sendToTarget();
                     }
@@ -490,6 +595,7 @@
     final class ClientRecord implements DeathRecipient {
         public final UserRecord mUserRecord;
         public final IMediaRouterClient mClient;
+        public final int mUid;
         public final int mPid;
         public final String mPackageName;
         public final boolean mTrusted;
@@ -499,9 +605,10 @@
         public String mSelectedRouteId;
 
         public ClientRecord(UserRecord userRecord, IMediaRouterClient client,
-                int pid, String packageName, boolean trusted) {
+                int uid, int pid, String packageName, boolean trusted) {
             mUserRecord = userRecord;
             mClient = client;
+            mUid = uid;
             mPid = pid;
             mPackageName = packageName;
             mTrusted = trusted;
@@ -517,7 +624,7 @@
         }
 
         MediaRouterClientState getState() {
-            return mTrusted ? mUserRecord.mTrustedState : mUserRecord.mUntrustedState;
+            return mTrusted ? mUserRecord.mRouterState : null;
         }
 
         public void dump(PrintWriter pw, String prefix) {
@@ -544,8 +651,7 @@
         public final int mUserId;
         public final ArrayList<ClientRecord> mClientRecords = new ArrayList<ClientRecord>();
         public final UserHandler mHandler;
-        public MediaRouterClientState mTrustedState;
-        public MediaRouterClientState mUntrustedState;
+        public MediaRouterClientState mRouterState;
 
         public UserRecord(int userId) {
             mUserId = userId;
@@ -566,8 +672,7 @@
             }
 
             pw.println(indent + "State");
-            pw.println(indent + "mTrustedState=" + mTrustedState);
-            pw.println(indent + "mUntrustedState=" + mUntrustedState);
+            pw.println(indent + "mRouterState=" + mRouterState);
 
             if (!mHandler.runWithScissors(new Runnable() {
                 @Override
@@ -592,13 +697,6 @@
      * this class encapsulates all of the associated functionality and exports state
      * to the service as it evolves.
      * </p><p>
-     * One important task of this class is to keep track of the current globally selected
-     * route id for certain routes that have global effects, such as remote displays.
-     * Global route selections override local selections made within apps.  The change
-     * is propagated to all apps so that they are all in sync.  Synchronization works
-     * both ways.  Whenever the globally selected route is explicitly unselected by any
-     * app, then it becomes unselected globally and all apps are informed.
-     * </p><p>
      * This class is currently hardcoded to work with remote display providers but
      * it is intended to be eventually extended to support more general route providers
      * similar to the support library media router.
@@ -639,7 +737,7 @@
 
         private boolean mRunning;
         private int mDiscoveryMode = RemoteDisplayState.DISCOVERY_MODE_NONE;
-        private RouteRecord mGloballySelectedRouteRecord;
+        private RouteRecord mSelectedRouteRecord;
         private int mConnectionPhase = PHASE_NOT_AVAILABLE;
         private int mConnectionTimeoutReason;
         private long mConnectionTimeoutStartTime;
@@ -701,7 +799,7 @@
             final String indent = prefix + "  ";
             pw.println(indent + "mRunning=" + mRunning);
             pw.println(indent + "mDiscoveryMode=" + mDiscoveryMode);
-            pw.println(indent + "mGloballySelectedRouteRecord=" + mGloballySelectedRouteRecord);
+            pw.println(indent + "mSelectedRouteRecord=" + mSelectedRouteRecord);
             pw.println(indent + "mConnectionPhase=" + mConnectionPhase);
             pw.println(indent + "mConnectionTimeoutReason=" + mConnectionTimeoutReason);
             pw.println(indent + "mConnectionTimeoutStartTime=" + (mConnectionTimeoutReason != 0 ?
@@ -729,7 +827,7 @@
         private void stop() {
             if (mRunning) {
                 mRunning = false;
-                unselectGloballySelectedRoute();
+                unselectSelectedRoute();
                 mWatcher.stop(); // also stops all providers
             }
         }
@@ -768,15 +866,15 @@
 
         private void selectRoute(String routeId) {
             if (routeId != null
-                    && (mGloballySelectedRouteRecord == null
-                            || !routeId.equals(mGloballySelectedRouteRecord.getUniqueId()))) {
+                    && (mSelectedRouteRecord == null
+                            || !routeId.equals(mSelectedRouteRecord.getUniqueId()))) {
                 RouteRecord routeRecord = findRouteRecord(routeId);
                 if (routeRecord != null) {
-                    unselectGloballySelectedRoute();
+                    unselectSelectedRoute();
 
-                    Slog.i(TAG, "Selected global route:" + routeRecord);
-                    mGloballySelectedRouteRecord = routeRecord;
-                    checkGloballySelectedRouteState();
+                    Slog.i(TAG, "Selected route:" + routeRecord);
+                    mSelectedRouteRecord = routeRecord;
+                    checkSelectedRouteState();
                     routeRecord.getProvider().setSelectedDisplay(routeRecord.getDescriptorId());
 
                     scheduleUpdateClientState();
@@ -786,34 +884,34 @@
 
         private void unselectRoute(String routeId) {
             if (routeId != null
-                    && mGloballySelectedRouteRecord != null
-                    && routeId.equals(mGloballySelectedRouteRecord.getUniqueId())) {
-                unselectGloballySelectedRoute();
+                    && mSelectedRouteRecord != null
+                    && routeId.equals(mSelectedRouteRecord.getUniqueId())) {
+                unselectSelectedRoute();
             }
         }
 
-        private void unselectGloballySelectedRoute() {
-            if (mGloballySelectedRouteRecord != null) {
-                Slog.i(TAG, "Unselected global route:" + mGloballySelectedRouteRecord);
-                mGloballySelectedRouteRecord.getProvider().setSelectedDisplay(null);
-                mGloballySelectedRouteRecord = null;
-                checkGloballySelectedRouteState();
+        private void unselectSelectedRoute() {
+            if (mSelectedRouteRecord != null) {
+                Slog.i(TAG, "Unselected route:" + mSelectedRouteRecord);
+                mSelectedRouteRecord.getProvider().setSelectedDisplay(null);
+                mSelectedRouteRecord = null;
+                checkSelectedRouteState();
 
                 scheduleUpdateClientState();
             }
         }
 
         private void requestSetVolume(String routeId, int volume) {
-            if (mGloballySelectedRouteRecord != null
-                    && routeId.equals(mGloballySelectedRouteRecord.getUniqueId())) {
-                mGloballySelectedRouteRecord.getProvider().setDisplayVolume(volume);
+            if (mSelectedRouteRecord != null
+                    && routeId.equals(mSelectedRouteRecord.getUniqueId())) {
+                mSelectedRouteRecord.getProvider().setDisplayVolume(volume);
             }
         }
 
         private void requestUpdateVolume(String routeId, int direction) {
-            if (mGloballySelectedRouteRecord != null
-                    && routeId.equals(mGloballySelectedRouteRecord.getUniqueId())) {
-                mGloballySelectedRouteRecord.getProvider().adjustDisplayVolume(direction);
+            if (mSelectedRouteRecord != null
+                    && routeId.equals(mSelectedRouteRecord.getUniqueId())) {
+                mSelectedRouteRecord.getProvider().adjustDisplayVolume(direction);
             }
         }
 
@@ -839,7 +937,7 @@
                 provider.setCallback(null);
                 provider.setDiscoveryMode(RemoteDisplayState.DISCOVERY_MODE_NONE);
 
-                checkGloballySelectedRouteState();
+                checkSelectedRouteState();
                 scheduleUpdateClientState();
             }
         }
@@ -856,35 +954,34 @@
             if (index >= 0) {
                 ProviderRecord providerRecord = mProviderRecords.get(index);
                 if (providerRecord.updateDescriptor(state)) {
-                    checkGloballySelectedRouteState();
+                    checkSelectedRouteState();
                     scheduleUpdateClientState();
                 }
             }
         }
 
         /**
-         * This function is called whenever the state of the globally selected route
-         * may have changed.  It checks the state and updates timeouts or unselects
-         * the route as appropriate.
+         * This function is called whenever the state of the selected route may have changed.
+         * It checks the state and updates timeouts or unselects the route as appropriate.
          */
-        private void checkGloballySelectedRouteState() {
+        private void checkSelectedRouteState() {
             // Unschedule timeouts when the route is unselected.
-            if (mGloballySelectedRouteRecord == null) {
+            if (mSelectedRouteRecord == null) {
                 mConnectionPhase = PHASE_NOT_AVAILABLE;
                 updateConnectionTimeout(0);
                 return;
             }
 
             // Ensure that the route is still present and enabled.
-            if (!mGloballySelectedRouteRecord.isValid()
-                    || !mGloballySelectedRouteRecord.isEnabled()) {
+            if (!mSelectedRouteRecord.isValid()
+                    || !mSelectedRouteRecord.isEnabled()) {
                 updateConnectionTimeout(TIMEOUT_REASON_NOT_AVAILABLE);
                 return;
             }
 
             // Make sure we haven't lost our connection.
             final int oldPhase = mConnectionPhase;
-            mConnectionPhase = getConnectionPhase(mGloballySelectedRouteRecord.getStatus());
+            mConnectionPhase = getConnectionPhase(mSelectedRouteRecord.getStatus());
             if (oldPhase >= PHASE_CONNECTING && mConnectionPhase < PHASE_CONNECTING) {
                 updateConnectionTimeout(TIMEOUT_REASON_CONNECTION_LOST);
                 return;
@@ -894,15 +991,13 @@
             switch (mConnectionPhase) {
                 case PHASE_CONNECTED:
                     if (oldPhase != PHASE_CONNECTED) {
-                        Slog.i(TAG, "Connected to global route: "
-                                + mGloballySelectedRouteRecord);
+                        Slog.i(TAG, "Connected to route: " + mSelectedRouteRecord);
                     }
                     updateConnectionTimeout(0);
                     break;
                 case PHASE_CONNECTING:
                     if (oldPhase != PHASE_CONNECTING) {
-                        Slog.i(TAG, "Connecting to global route: "
-                                + mGloballySelectedRouteRecord);
+                        Slog.i(TAG, "Connecting to route: " + mSelectedRouteRecord);
                     }
                     updateConnectionTimeout(TIMEOUT_REASON_WAITING_FOR_CONNECTED);
                     break;
@@ -943,7 +1038,7 @@
         }
 
         private void connectionTimedOut() {
-            if (mConnectionTimeoutReason == 0 || mGloballySelectedRouteRecord == null) {
+            if (mConnectionTimeoutReason == 0 || mSelectedRouteRecord == null) {
                 // Shouldn't get here.  There must be a bug somewhere.
                 Log.wtf(TAG, "Handled connection timeout for no reason.");
                 return;
@@ -951,28 +1046,28 @@
 
             switch (mConnectionTimeoutReason) {
                 case TIMEOUT_REASON_NOT_AVAILABLE:
-                    Slog.i(TAG, "Global route no longer available: "
-                            + mGloballySelectedRouteRecord);
+                    Slog.i(TAG, "Selected route no longer available: "
+                            + mSelectedRouteRecord);
                     break;
                 case TIMEOUT_REASON_CONNECTION_LOST:
-                    Slog.i(TAG, "Global route connection lost: "
-                            + mGloballySelectedRouteRecord);
+                    Slog.i(TAG, "Selected route connection lost: "
+                            + mSelectedRouteRecord);
                     break;
                 case TIMEOUT_REASON_WAITING_FOR_CONNECTING:
-                    Slog.i(TAG, "Global route timed out while waiting for "
+                    Slog.i(TAG, "Selected route timed out while waiting for "
                             + "connection attempt to begin after "
                             + (SystemClock.uptimeMillis() - mConnectionTimeoutStartTime)
-                            + " ms: " + mGloballySelectedRouteRecord);
+                            + " ms: " + mSelectedRouteRecord);
                     break;
                 case TIMEOUT_REASON_WAITING_FOR_CONNECTED:
-                    Slog.i(TAG, "Global route timed out while connecting after "
+                    Slog.i(TAG, "Selected route timed out while connecting after "
                             + (SystemClock.uptimeMillis() - mConnectionTimeoutStartTime)
-                            + " ms: " + mGloballySelectedRouteRecord);
+                            + " ms: " + mSelectedRouteRecord);
                     break;
             }
             mConnectionTimeoutReason = 0;
 
-            unselectGloballySelectedRoute();
+            unselectSelectedRoute();
         }
 
         private void scheduleUpdateClientState() {
@@ -985,30 +1080,17 @@
         private void updateClientState() {
             mClientStateUpdateScheduled = false;
 
-            final String globallySelectedRouteId = mGloballySelectedRouteRecord != null ?
-                    mGloballySelectedRouteRecord.getUniqueId() : null;
-
             // Build a new client state for trusted clients.
-            MediaRouterClientState trustedState = new MediaRouterClientState();
-            trustedState.globallySelectedRouteId = globallySelectedRouteId;
+            MediaRouterClientState routerState = new MediaRouterClientState();
             final int providerCount = mProviderRecords.size();
             for (int i = 0; i < providerCount; i++) {
-                mProviderRecords.get(i).appendClientState(trustedState);
-            }
-
-            // Build a new client state for untrusted clients that can only see
-            // the currently selected route.
-            MediaRouterClientState untrustedState = new MediaRouterClientState();
-            untrustedState.globallySelectedRouteId = globallySelectedRouteId;
-            if (globallySelectedRouteId != null) {
-                untrustedState.routes.add(trustedState.getRoute(globallySelectedRouteId));
+                mProviderRecords.get(i).appendClientState(routerState);
             }
 
             try {
                 synchronized (mService.mLock) {
                     // Update the UserRecord.
-                    mUserRecord.mTrustedState = trustedState;
-                    mUserRecord.mUntrustedState = untrustedState;
+                    mUserRecord.mRouterState = routerState;
 
                     // Collect all clients.
                     final int count = mUserRecord.mClientRecords.size();
@@ -1023,7 +1105,7 @@
                     try {
                         mTempClients.get(i).onStateChanged();
                     } catch (RemoteException ex) {
-                        // ignore errors, client probably died
+                        Slog.w(TAG, "Failed to call onStateChanged. Client probably died.");
                     }
                 }
             } finally {
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 38c6157..adb50f0 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -138,19 +138,20 @@
         mKeyguardManager =
                 (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
         mAudioService = getAudioService();
-        mAudioPlaybackMonitor = new AudioPlaybackMonitor(getContext(), mAudioService,
+        mAudioPlaybackMonitor = AudioPlaybackMonitor.getInstance(getContext(), mAudioService);
+        mAudioPlaybackMonitor.registerOnAudioPlaybackStartedListener(
                 new AudioPlaybackMonitor.OnAudioPlaybackStartedListener() {
-                    @Override
-                    public void onAudioPlaybackStarted(int uid) {
-                        synchronized (mLock) {
-                            FullUserRecord user =
-                                    getFullUserRecordLocked(UserHandle.getUserId(uid));
-                            if (user != null) {
-                                user.mPriorityStack.updateMediaButtonSessionIfNeeded();
-                            }
-                        }
+            @Override
+            public void onAudioPlaybackStarted(int uid) {
+                synchronized (mLock) {
+                    FullUserRecord user =
+                            getFullUserRecordLocked(UserHandle.getUserId(uid));
+                    if (user != null) {
+                        user.mPriorityStack.updateMediaButtonSessionIfNeeded();
                     }
-                });
+                }
+            }
+        });
         mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
         mContentResolver = getContext().getContentResolver();
         mSettingsObserver = new SettingsObserver();
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 9d92cbc..a6ea6b2 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -111,7 +111,7 @@
             mProjectionGrant.stop();
         }
         if (mMediaRouteInfo != null) {
-            mMediaRouter.getDefaultRoute().select();
+            mMediaRouter.getFallbackRoute().select();
         }
         mProjectionToken = projection.asBinder();
         mProjectionGrant = projection;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index d9ca00c..0f1cfa5 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -3332,7 +3332,7 @@
 
         // Second step: apply bw changes based on change of state.
         if (newRule != oldRule) {
-            if ((newRule & RULE_TEMPORARY_ALLOW_METERED) != 0) {
+            if (hasRule(newRule, RULE_TEMPORARY_ALLOW_METERED)) {
                 // Temporarily whitelist foreground app, removing from blacklist if necessary
                 // (since bw_penalty_box prevails over bw_happy_box).
 
@@ -3343,7 +3343,7 @@
                 if (isBlacklisted) {
                     setMeteredNetworkBlacklist(uid, false);
                 }
-            } else if ((oldRule & RULE_TEMPORARY_ALLOW_METERED) != 0) {
+            } else if (hasRule(oldRule, RULE_TEMPORARY_ALLOW_METERED)) {
                 // Remove temporary whitelist from app that is not on foreground anymore.
 
                 // TODO: if statements below are used to avoid unnecessary calls to netd / iptables,
@@ -3356,18 +3356,18 @@
                 if (isBlacklisted) {
                     setMeteredNetworkBlacklist(uid, true);
                 }
-            } else if ((newRule & RULE_REJECT_METERED) != 0
-                    || (oldRule & RULE_REJECT_METERED) != 0) {
+            } else if (hasRule(newRule, RULE_REJECT_METERED)
+                    || hasRule(oldRule, RULE_REJECT_METERED)) {
                 // Flip state because app was explicitly added or removed to blacklist.
                 setMeteredNetworkBlacklist(uid, isBlacklisted);
-                if ((oldRule & RULE_REJECT_METERED) != 0 && isWhitelisted) {
+                if (hasRule(oldRule, RULE_REJECT_METERED) && isWhitelisted) {
                     // Since blacklist prevails over whitelist, we need to handle the special case
                     // where app is whitelisted and blacklisted at the same time (although such
                     // scenario should be blocked by the UI), then blacklist is removed.
                     setMeteredNetworkWhitelist(uid, isWhitelisted);
                 }
-            } else if ((newRule & RULE_ALLOW_METERED) != 0
-                    || (oldRule & RULE_ALLOW_METERED) != 0) {
+            } else if (hasRule(newRule, RULE_ALLOW_METERED)
+                    || hasRule(oldRule, RULE_ALLOW_METERED)) {
                 // Flip state because app was explicitly added or removed to whitelist.
                 setMeteredNetworkWhitelist(uid, isWhitelisted);
             } else {
@@ -3480,9 +3480,9 @@
 
         // Second step: notify listeners if state changed.
         if (newRule != oldRule) {
-            if (newRule == RULE_NONE || (newRule & RULE_ALLOW_ALL) != 0) {
+            if (newRule == RULE_NONE || hasRule(newRule, RULE_ALLOW_ALL)) {
                 if (LOGV) Log.v(TAG, "Allowing non-metered access for UID " + uid);
-            } else if ((newRule & RULE_REJECT_ALL) != 0) {
+            } else if (hasRule(newRule, RULE_REJECT_ALL)) {
                 if (LOGV) Log.v(TAG, "Rejecting non-metered access for UID " + uid);
             } else {
                 // All scenarios should have been covered above
@@ -4184,7 +4184,7 @@
         }
 
         public static String getString(int uid, long procStateSeq) {
-            return "UID=" + uid + " procStateSeq=" + procStateSeq;
+            return "UID=" + uid + " Seq=" + procStateSeq;
         }
 
         private int increaseNext(int next, int increment) {
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 3ad2dca..421db40 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -18,7 +18,6 @@
 
 import static android.Manifest.permission.ACCESS_NETWORK_STATE;
 import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
-import static android.Manifest.permission.DUMP;
 import static android.Manifest.permission.MODIFY_NETWORK_ACCOUNTING;
 import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
 import static android.content.Intent.ACTION_SHUTDOWN;
diff --git a/services/core/java/com/android/server/net/OWNERS b/services/core/java/com/android/server/net/OWNERS
index 061fd8d..6b77d83 100644
--- a/services/core/java/com/android/server/net/OWNERS
+++ b/services/core/java/com/android/server/net/OWNERS
@@ -2,7 +2,7 @@
 
 ek@google.com
 hugobenichi@google.com
-jsharkey@google.com
+jsharkey@android.com
 lorenzo@google.com
 satk@google.com
 silberst@google.com
diff --git a/services/core/java/com/android/server/notification/AlertRateLimiter.java b/services/core/java/com/android/server/notification/AlertRateLimiter.java
new file mode 100644
index 0000000..4b168c5
--- /dev/null
+++ b/services/core/java/com/android/server/notification/AlertRateLimiter.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.notification;
+
+
+/**
+ * {@hide}
+ */
+public class AlertRateLimiter {
+    static final long ALLOWED_ALERT_INTERVAL = 1000;
+    private long mLastNotificationMillis = 0;
+
+    boolean shouldRateLimitAlert(long now) {
+        final long millisSinceLast = now - mLastNotificationMillis;
+        if (millisSinceLast < 0 || millisSinceLast < ALLOWED_ALERT_INTERVAL) {
+            return true;
+        }
+        mLastNotificationMillis = now;
+        return false;
+    }
+}
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 73a365b..5251c78 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -139,6 +139,19 @@
                         || Objects.equals(element, mConfig.secondarySettingName)) {
                     String prevValue = intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE);
                     String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE);
+                    int restoredFromSdkInt = intent.getIntExtra(
+                            Intent.EXTRA_SETTING_RESTORED_FROM_SDK_INT, 0);
+                    if (restoredFromSdkInt < Build.VERSION_CODES.O) {
+                        // automatic system grants were added in O, so append the approved apps
+                        // rather than wiping out the setting
+                        if (!TextUtils.isEmpty(prevValue)) {
+                            if (!TextUtils.isEmpty(newValue)) {
+                                newValue = newValue + ENABLED_SERVICES_SEPARATOR + prevValue;
+                            } else {
+                                newValue = prevValue;
+                            }
+                        }
+                    }
                     settingRestored(element, prevValue, newValue, getSendingUserId());
                 }
             }
diff --git a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
index 4981d5c..12b29cf 100644
--- a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
@@ -58,6 +58,10 @@
             }
         }
 
+        if (!record.isRecentlyIntrusive()) {
+            return null;
+        }
+
         return new RankingReconsideration(record.getKey(), HANG_TIME_MS) {
             @Override
             public void work() {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5ee7ac4..90b3853 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -20,6 +20,7 @@
 import static android.app.NotificationManager.IMPORTANCE_NONE;
 import static android.content.pm.PackageManager.FEATURE_LEANBACK;
 import static android.content.pm.PackageManager.FEATURE_TELEVISION;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.service.notification.NotificationListenerService
         .NOTIFICATION_CHANNEL_OR_GROUP_ADDED;
 import static android.service.notification.NotificationListenerService
@@ -132,6 +133,7 @@
 import android.service.notification.StatusBarNotification;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeProto;
+import android.telecom.TelecomManager;
 import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
@@ -208,7 +210,7 @@
             = SystemProperties.getBoolean("debug.child_notifs", true);
 
     static final int MAX_PACKAGE_NOTIFICATIONS = 50;
-    static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 10f;
+    static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 5f;
 
     // message codes
     static final int MESSAGE_TIMEOUT = 2;
@@ -519,7 +521,8 @@
         }
     }
 
-    private final NotificationDelegate mNotificationDelegate = new NotificationDelegate() {
+    @VisibleForTesting
+    final NotificationDelegate mNotificationDelegate = new NotificationDelegate() {
 
         @Override
         public void onSetDisabled(int status) {
@@ -1011,6 +1014,25 @@
     }
 
     @VisibleForTesting
+    int getNotificationRecordCount() {
+        synchronized (mNotificationLock) {
+            int count = mNotificationList.size() + mNotificationsByKey.size()
+                    + mSummaryByGroupKey.size() + mEnqueuedNotifications.size();
+            // subtract duplicates
+            for (NotificationRecord posted : mNotificationList) {
+                if (mNotificationsByKey.containsKey(posted.getKey())) {
+                    count--;
+                }
+                if (posted.sbn.isGroup() && posted.getNotification().isGroupSummary()) {
+                    count --;
+                }
+            }
+
+            return count;
+        }
+    }
+
+    @VisibleForTesting
     void addNotification(NotificationRecord r) {
         mNotificationList.add(r);
         mNotificationsByKey.put(r.sbn.getKey(), r);
@@ -1054,7 +1076,12 @@
         mIsTelevision = isTelevision;
     }
 
-    // TODO: Tests should call onStart instead once the methods above are removed.
+    @VisibleForTesting
+    void setUsageStats(NotificationUsageStats us) {
+        mUsageStats = us;
+    }
+
+    // TODO: All tests should use this init instead of the one-off setters above.
     @VisibleForTesting
     void init(Looper looper, IPackageManager packageManager, PackageManager packageManagerClient,
             LightsManager lightsManager, NotificationListeners notificationListeners,
@@ -1185,6 +1212,37 @@
         mUserProfiles.updateCache(getContext());
         listenForCallState();
 
+        mSettingsObserver = new SettingsObserver(mHandler);
+
+        mArchive = new Archive(resources.getInteger(
+                R.integer.config_notificationServiceArchiveSize));
+
+        mIsTelevision = mPackageManagerClient.hasSystemFeature(FEATURE_LEANBACK)
+                || mPackageManagerClient.hasSystemFeature(FEATURE_TELEVISION);
+    }
+
+    @Override
+    public void onStart() {
+        SnoozeHelper snoozeHelper = new SnoozeHelper(getContext(), new SnoozeHelper.Callback() {
+            @Override
+            public void repost(int userId, NotificationRecord r) {
+                try {
+                    if (DBG) {
+                        Slog.d(TAG, "Reposting " + r.getKey());
+                    }
+                    enqueueNotificationInternal(r.sbn.getPackageName(), r.sbn.getOpPkg(),
+                            r.sbn.getUid(), r.sbn.getInitialPid(), r.sbn.getTag(), r.sbn.getId(),
+                            r.sbn.getNotification(), userId);
+                } catch (Exception e) {
+                    Slog.e(TAG, "Cannot un-snooze notification", e);
+                }
+            }
+        }, mUserProfiles);
+
+        init(Looper.myLooper(), AppGlobals.getPackageManager(), getContext().getPackageManager(),
+                getLocalService(LightsManager.class), new NotificationListeners(),
+                null, snoozeHelper, new NotificationUsageStats(getContext()));
+
         // register for various Intents
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_ON);
@@ -1222,36 +1280,6 @@
         timeoutFilter.addDataScheme(SCHEME_TIMEOUT);
         getContext().registerReceiver(mNotificationTimeoutReceiver, timeoutFilter);
 
-        mSettingsObserver = new SettingsObserver(mHandler);
-
-        mArchive = new Archive(resources.getInteger(
-                R.integer.config_notificationServiceArchiveSize));
-
-        mIsTelevision = mPackageManagerClient.hasSystemFeature(FEATURE_LEANBACK)
-                || mPackageManagerClient.hasSystemFeature(FEATURE_TELEVISION);
-    }
-
-    @Override
-    public void onStart() {
-        SnoozeHelper snoozeHelper = new SnoozeHelper(getContext(), new SnoozeHelper.Callback() {
-            @Override
-            public void repost(int userId, NotificationRecord r) {
-                try {
-                    if (DBG) {
-                        Slog.d(TAG, "Reposting " + r.getKey());
-                    }
-                    enqueueNotificationInternal(r.sbn.getPackageName(), r.sbn.getOpPkg(),
-                            r.sbn.getUid(), r.sbn.getInitialPid(), r.sbn.getTag(), r.sbn.getId(),
-                            r.sbn.getNotification(), userId);
-                } catch (Exception e) {
-                    Slog.e(TAG, "Cannot un-snooze notification", e);
-                }
-            }
-        }, mUserProfiles);
-
-        init(Looper.myLooper(), AppGlobals.getPackageManager(), getContext().getPackageManager(),
-                getLocalService(LightsManager.class), new NotificationListeners(),
-                null, snoozeHelper, new NotificationUsageStats(getContext()));
         publishBinderService(Context.NOTIFICATION_SERVICE, mService);
         publishLocalService(NotificationManagerInternal.class, mInternalService);
     }
@@ -3174,6 +3202,15 @@
                     pkg, PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
                     (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
             Notification.addFieldsFromContext(ai, notification);
+
+            int canColorize = mPackageManagerClient.checkPermission(
+                    android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, pkg);
+            if (canColorize == PERMISSION_GRANTED) {
+                notification.flags |= Notification.FLAG_CAN_COLORIZE;
+            } else {
+                notification.flags &= ~Notification.FLAG_CAN_COLORIZE;
+            }
+
         } catch (NameNotFoundException e) {
             Slog.e(TAG, "Cannot create a context for sending app", e);
             return;
@@ -3269,16 +3306,30 @@
     private boolean checkDisqualifyingFeatures(int userId, int callingUid, int id, String tag,
             NotificationRecord r) {
         final String pkg = r.sbn.getPackageName();
+        final String dialerPackage =
+                getContext().getSystemService(TelecomManager.class).getSystemDialerPackage();
         final boolean isSystemNotification =
-                isUidSystemOrPhone(callingUid) || ("android".equals(pkg));
+                isUidSystemOrPhone(callingUid) || ("android".equals(pkg))
+                || TextUtils.equals(pkg, dialerPackage);
         final boolean isNotificationFromListener = mListeners.isListenerPackage(pkg);
 
         // Limit the number of notifications that any given package except the android
         // package or a registered listener can enqueue.  Prevents DOS attacks and deals with leaks.
         if (!isSystemNotification && !isNotificationFromListener) {
             synchronized (mNotificationLock) {
-                if (mNotificationsByKey.get(r.sbn.getKey()) != null) {
-                    // this is an update, rate limit updates only
+                if (mNotificationsByKey.get(r.sbn.getKey()) == null && isCallerInstantApp(pkg)) {
+                    // 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
+                    // notification).
+                    throw new SecurityException("Instant app " + pkg
+                            + " cannot create notifications");
+                }
+
+                // rate limit updates that aren't completed progress notifications
+                if (mNotificationsByKey.get(r.sbn.getKey()) != null
+                        && !r.getNotification().hasCompletedProgress()) {
+
                     final float appEnqueueRate = mUsageStats.getAppEnqueueRate(pkg);
                     if (appEnqueueRate > mMaxPackageEnqueueRate) {
                         mUsageStats.registerOverRateQuota(pkg);
@@ -3290,33 +3341,15 @@
                         }
                         return false;
                     }
-                } else if (isCallerInstantApp(pkg)) {
-                    // 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
-                    // notification).
-                    throw new SecurityException("Instant app " + pkg
-                            + " cannot create notifications");
                 }
 
-                int count = 0;
-                final int N = mNotificationList.size();
-                for (int i=0; i<N; i++) {
-                    final NotificationRecord existing = mNotificationList.get(i);
-                    if (existing.sbn.getPackageName().equals(pkg)
-                            && existing.sbn.getUserId() == userId) {
-                        if (existing.sbn.getId() == id
-                                && TextUtils.equals(existing.sbn.getTag(), tag)) {
-                            break;  // Allow updating existing notification
-                        }
-                        count++;
-                        if (count >= MAX_PACKAGE_NOTIFICATIONS) {
-                            mUsageStats.registerOverCountQuota(pkg);
-                            Slog.e(TAG, "Package has already posted " + count
-                                    + " notifications.  Not showing more.  package=" + pkg);
-                            return false;
-                        }
-                    }
+                // limit the number of outstanding notificationrecords an app can have
+                int count = getNotificationCountLocked(pkg, userId, id, tag);
+                if (count >= MAX_PACKAGE_NOTIFICATIONS) {
+                    mUsageStats.registerOverCountQuota(pkg);
+                    Slog.e(TAG, "Package has already posted or enqueued " + count
+                            + " notifications.  Not showing more.  package=" + pkg);
+                    return false;
                 }
             }
         }
@@ -3343,6 +3376,32 @@
         return true;
     }
 
+    protected int getNotificationCountLocked(String pkg, int userId, int excludedId,
+            String excludedTag) {
+        int count = 0;
+        final int N = mNotificationList.size();
+        for (int i = 0; i < N; i++) {
+            final NotificationRecord existing = mNotificationList.get(i);
+            if (existing.sbn.getPackageName().equals(pkg)
+                    && existing.sbn.getUserId() == userId) {
+                if (existing.sbn.getId() == excludedId
+                        && TextUtils.equals(existing.sbn.getTag(), excludedTag)) {
+                    continue;
+                }
+                count++;
+            }
+        }
+        final int M = mEnqueuedNotifications.size();
+        for (int i = 0; i < M; i++) {
+            final NotificationRecord existing = mEnqueuedNotifications.get(i);
+            if (existing.sbn.getPackageName().equals(pkg)
+                    && existing.sbn.getUserId() == userId) {
+                count++;
+            }
+        }
+        return count;
+    }
+
     protected boolean isBlocked(NotificationRecord r, NotificationUsageStats usageStats) {
         final String pkg = r.sbn.getPackageName();
         final int callingUid = r.sbn.getUid();
@@ -3678,18 +3737,6 @@
         // Should this notification make noise, vibe, or use the LED?
         final boolean aboveThreshold =
                 record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT;
-        final boolean canInterrupt = aboveThreshold && !record.isIntercepted();
-        if (DBG)
-            Slog.v(TAG,
-                    "pkg=" + record.sbn.getPackageName() + " canInterrupt=" + canInterrupt +
-                            " intercept=" + record.isIntercepted()
-            );
-
-        // If we're not supposed to beep, vibrate, etc. then don't.
-        final String disableEffects = disableNotificationEffects(record);
-        if (disableEffects != null) {
-            ZenLog.traceDisableEffects(record, disableEffects);
-        }
 
         // Remember if this notification already owns the notification channels.
         boolean wasBeep = key != null && key.equals(mSoundNotificationKey);
@@ -3699,19 +3746,18 @@
         boolean hasValidSound = false;
 
         if (isNotificationForCurrentUser(record)) {
-            // If the notification will appear in the status bar, it should send an accessibility
-            // event
-            if (!record.isUpdate && record.getImportance() > IMPORTANCE_MIN) {
+            // If the notification icon will appear in the status bar, AND it hasn't been blocked
+            // by do-not-disturb, it should generate an accessibility event
+            if (!record.isUpdate
+                    && !record.isIntercepted()
+                    && record.getImportance() > IMPORTANCE_MIN) {
                 sendAccessibilityEvent(notification, record.sbn.getPackageName());
             }
-
-            if (disableEffects == null
-                    && canInterrupt
-                    && mSystemReady
-                    && mAudioManager != null) {
-                if (DBG) Slog.v(TAG, "Interrupting!");
+            if (aboveThreshold && mSystemReady && mAudioManager != null) {
+                // this notification wants to make noise & is allowed to make noise
                 Uri soundUri = record.getSound();
                 hasValidSound = soundUri != null && !Uri.EMPTY.equals(soundUri);
+
                 long[] vibration = record.getVibration();
                 // Demote sound to vibration if vibration missing & phone in vibration mode.
                 if (vibration == null
@@ -3722,7 +3768,10 @@
                 }
                 hasValidVibrate = vibration != null;
 
-                if (!shouldMuteNotificationLocked(record)) {
+                boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
+
+                if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
+                    if (DBG) Slog.v(TAG, "Interrupting!");
                     if (hasValidSound) {
                         mSoundNotificationKey = key;
                         if (mInCall) {
@@ -3779,14 +3828,37 @@
 
     @GuardedBy("mNotificationLock")
     boolean shouldMuteNotificationLocked(final NotificationRecord record) {
+        // Suppressed because it's a silent update
         final Notification notification = record.getNotification();
         if(record.isUpdate
                 && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0) {
             return true;
         }
+
+        // muted by listener
+        final String disableEffects = disableNotificationEffects(record);
+        if (disableEffects != null) {
+            ZenLog.traceDisableEffects(record, disableEffects);
+            return true;
+        }
+
+        // suppressed due to DND
+        if (record.isIntercepted()) {
+            return true;
+        }
+
+        // Suppressed because another notification in its group handles alerting
         if (record.sbn.isGroup()) {
             return notification.suppressAlertingDueToGrouping();
         }
+
+        // Suppressed for being too recently noisy
+        final String pkg = record.sbn.getPackageName();
+        if (mUsageStats.isAlertRateLimited(pkg)) {
+            Slog.e(TAG, "Muting recently noisy " + record.getKey());
+            return true;
+        }
+
         return false;
     }
 
@@ -4004,16 +4076,19 @@
             }
             int indexBefore = findNotificationRecordIndexLocked(record);
             boolean interceptBefore = record.isIntercepted();
+            float contactAffinityBefore = record.getContactAffinity();
             int visibilityBefore = record.getPackageVisibilityOverride();
             recon.applyChangesLocked(record);
             applyZenModeLocked(record);
             mRankingHelper.sort(mNotificationList);
             int indexAfter = findNotificationRecordIndexLocked(record);
             boolean interceptAfter = record.isIntercepted();
+            float contactAffinityAfter = record.getContactAffinity();
             int visibilityAfter = record.getPackageVisibilityOverride();
             changed = indexBefore != indexAfter || interceptBefore != interceptAfter
                     || visibilityBefore != visibilityAfter;
-            if (interceptBefore && !interceptAfter) {
+            if (interceptBefore && !interceptAfter
+                    && Float.compare(contactAffinityBefore, contactAffinityAfter) != 0) {
                 buzzBeepBlinkLocked(record);
             }
         }
@@ -4193,9 +4268,11 @@
         return (x < low) ? low : ((x > high) ? high : x);
     }
 
+    @VisibleForTesting
     void sendAccessibilityEvent(Notification notification, CharSequence packageName) {
-        AccessibilityManager manager = AccessibilityManager.getInstance(getContext());
-        if (!manager.isEnabled()) {
+        final AccessibilityManager accessibilityManager
+                = AccessibilityManager.getInstance(getContext());
+        if (accessibilityManager == null || !accessibilityManager.isEnabled()) {
             return;
         }
 
@@ -4209,7 +4286,7 @@
             event.getText().add(tickerText);
         }
 
-        manager.sendAccessibilityEvent(event);
+        accessibilityManager.sendAccessibilityEvent(event);
     }
 
     /**
@@ -4506,6 +4583,7 @@
                 canceledNotifications = new ArrayList<>();
             }
             notificationList.remove(i);
+            mNotificationsByKey.remove(r.getKey());
             canceledNotifications.add(r);
             cancelNotificationLocked(r, sendDelete, reason, wasPosted);
         }
@@ -4615,6 +4693,7 @@
                 EventLogTags.writeNotificationCancel(callingUid, callingPid, pkg, childSbn.getId(),
                         childSbn.getTag(), userId, 0, 0, reason, listenerName);
                 notificationList.remove(i);
+                mNotificationsByKey.remove(childR.getKey());
                 cancelNotificationLocked(childR, sendDelete, reason, wasPosted);
             }
         }
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 6953ffd..1dee71c 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -386,6 +386,7 @@
         prefix = prefix + "  ";
         pw.println(prefix + "uid=" + sbn.getUid() + " userId=" + sbn.getUserId());
         pw.println(prefix + "icon=" + iconStr);
+        pw.println(prefix + "flags=0x" + Integer.toHexString(notification.flags));
         pw.println(prefix + "pri=" + notification.priority);
         pw.println(prefix + "key=" + sbn.getKey());
         pw.println(prefix + "seen=" + mIsSeen);
@@ -495,6 +496,7 @@
         pw.println(prefix + "mAttributes= " + mAttributes);
         pw.println(prefix + "mLight= " + mLight);
         pw.println(prefix + "mShowBadge=" + mShowBadge);
+        pw.println(prefix + "mColorized=" + notification.isColorized());
         pw.println(prefix + "effectiveNotificationChannel=" + getChannel());
         if (getPeopleOverride() != null) {
             pw.println(prefix + "overridePeople= " + TextUtils.join(",", getPeopleOverride()));
@@ -530,10 +532,10 @@
     public final String toString() {
         return String.format(
                 "NotificationRecord(0x%08x: pkg=%s user=%s id=%d tag=%s importance=%d key=%s" +
-                        " channel=%s: %s)",
+                        ": %s)",
                 System.identityHashCode(this),
                 this.sbn.getPackageName(), this.sbn.getUser(), this.sbn.getId(),
-                this.sbn.getTag(), this.mImportance, this.sbn.getKey(), this.getChannel().getId(),
+                this.sbn.getTag(), this.mImportance, this.sbn.getKey(),
                 this.sbn.getNotification());
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index 365321c..c8f4d31 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -115,6 +115,18 @@
     }
 
     /**
+     * Called when a notification wants to alert.
+     */
+    public synchronized boolean isAlertRateLimited(String packageName) {
+        AggregatedStats stats = getOrCreateAggregatedStatsLocked(packageName);
+        if (stats != null) {
+            return stats.isAlertRateLimited();
+        } else {
+            return false;
+        }
+    }
+
+    /**
      * Called when a notification is tentatively enqueued by an app, before rate checking.
      */
     public synchronized void registerEnqueuedByApp(String packageName) {
@@ -387,7 +399,9 @@
         public ImportanceHistogram quietImportance;
         public ImportanceHistogram finalImportance;
         public RateEstimator enqueueRate;
+        public AlertRateLimiter alertRate;
         public int numRateViolations;
+        public int numAlertViolations;
         public int numQuotaViolations;
         public long mLastAccessTime;
 
@@ -399,6 +413,7 @@
             quietImportance = new ImportanceHistogram(context, "note_imp_quiet_");
             finalImportance = new ImportanceHistogram(context, "note_importance_");
             enqueueRate = new RateEstimator();
+            alertRate = new AlertRateLimiter();
         }
 
         public AggregatedStats getPrevious() {
@@ -511,6 +526,7 @@
             maybeCount("note_sub_text", (numWithSubText - previous.numWithSubText));
             maybeCount("note_info_text", (numWithInfoText - previous.numWithInfoText));
             maybeCount("note_over_rate", (numRateViolations - previous.numRateViolations));
+            maybeCount("note_over_alert_rate", (numAlertViolations - previous.numAlertViolations));
             maybeCount("note_over_quota", (numQuotaViolations - previous.numQuotaViolations));
             noisyImportance.maybeCount(previous.noisyImportance);
             quietImportance.maybeCount(previous.quietImportance);
@@ -543,6 +559,7 @@
             previous.numWithSubText = numWithSubText;
             previous.numWithInfoText = numWithInfoText;
             previous.numRateViolations = numRateViolations;
+            previous.numAlertViolations = numAlertViolations;
             previous.numQuotaViolations = numQuotaViolations;
             noisyImportance.update(previous.noisyImportance);
             quietImportance.update(previous.quietImportance);
@@ -577,6 +594,14 @@
             enqueueRate.update(now);
         }
 
+        public boolean isAlertRateLimited() {
+            boolean limited = alertRate.shouldRateLimitAlert(SystemClock.elapsedRealtime());
+            if (limited) {
+                numAlertViolations++;
+            }
+            return limited;
+        }
+
         private String toStringWithIndent(String indent) {
             StringBuilder output = new StringBuilder();
             output.append(indent).append("AggregatedStats{\n");
@@ -635,7 +660,11 @@
             output.append("numWithSubText=").append(numWithSubText).append("\n");
             output.append(indentPlusTwo);
             output.append("numWithInfoText=").append(numWithInfoText).append("\n");
+            output.append(indentPlusTwo);
             output.append("numRateViolations=").append(numRateViolations).append("\n");
+            output.append(indentPlusTwo);
+            output.append("numAlertViolations=").append(numAlertViolations).append("\n");
+            output.append(indentPlusTwo);
             output.append("numQuotaViolations=").append(numQuotaViolations).append("\n");
             output.append(indentPlusTwo).append(noisyImportance.toString()).append("\n");
             output.append(indentPlusTwo).append(quietImportance.toString()).append("\n");
@@ -678,6 +707,7 @@
             maybePut(dump, "numRateViolations", numRateViolations);
             maybePut(dump, "numQuotaLViolations", numQuotaViolations);
             maybePut(dump, "notificationEnqueueRate", getEnqueueRate());
+            maybePut(dump, "numAlertViolations", numAlertViolations);
             noisyImportance.maybePut(dump, previous.noisyImportance);
             quietImportance.maybePut(dump, previous.quietImportance);
             finalImportance.maybePut(dump, previous.finalImportance);
diff --git a/services/core/java/com/android/server/oemlock/OemLock.java b/services/core/java/com/android/server/oemlock/OemLock.java
new file mode 100644
index 0000000..ee70c29
--- /dev/null
+++ b/services/core/java/com/android/server/oemlock/OemLock.java
@@ -0,0 +1,27 @@
+/*
+ * 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.oemlock;
+
+import android.annotation.Nullable;
+
+abstract class OemLock {
+    abstract void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature);
+    abstract boolean isOemUnlockAllowedByCarrier();
+
+    abstract void setOemUnlockAllowedByDevice(boolean allowedByDevice);
+    abstract boolean isOemUnlockAllowedByDevice();
+}
diff --git a/services/core/java/com/android/server/oemlock/OemLockService.java b/services/core/java/com/android/server/oemlock/OemLockService.java
new file mode 100644
index 0000000..5e19b13
--- /dev/null
+++ b/services/core/java/com/android/server/oemlock/OemLockService.java
@@ -0,0 +1,251 @@
+/*
+ * 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.oemlock;
+
+import android.Manifest;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.oemlock.V1_0.IOemLock;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.UserManagerInternal;
+import android.os.UserManagerInternal.UserRestrictionsListener;
+import android.service.oemlock.IOemLockService;
+import android.util.Slog;
+
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.pm.UserRestrictionsUtils;
+
+/**
+ * Service for managing the OEM lock state of the device.
+ *
+ * The OemLock HAL will be used if it is available, otherwise the persistent data block will be
+ * used.
+ */
+public class OemLockService extends SystemService {
+    private static final String TAG = "OemLock";
+
+    private static final String FLASH_LOCK_PROP = "ro.boot.flash.locked";
+    private static final String FLASH_LOCK_UNLOCKED = "0";
+
+    private Context mContext;
+    private OemLock mOemLock;
+
+    public static boolean isHalPresent() {
+        return VendorLock.getOemLockHalService() != null;
+    }
+
+    /** Select the OEM lock implementation */
+    private static OemLock getOemLock(Context context) {
+        final IOemLock oemLockHal = VendorLock.getOemLockHalService();
+        if (oemLockHal != null) {
+            Slog.i(TAG, "Using vendor lock via the HAL");
+            return new VendorLock(context, oemLockHal);
+        } else {
+            Slog.i(TAG, "Using persistent data block based lock");
+            return new PersistentDataBlockLock(context);
+        }
+    }
+
+    public OemLockService(Context context) {
+        this(context, getOemLock(context));
+    }
+
+    OemLockService(Context context, OemLock oemLock) {
+        super(context);
+        mContext = context;
+        mOemLock = oemLock;
+
+        LocalServices.getService(UserManagerInternal.class)
+                .addUserRestrictionsListener(mUserRestrictionsListener);
+    }
+
+    @Override
+    public void onStart() {
+        publishBinderService(Context.OEM_LOCK_SERVICE, mService);
+    }
+
+    private final UserRestrictionsListener mUserRestrictionsListener =
+            new UserRestrictionsListener() {
+        @Override
+        public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
+                Bundle prevRestrictions) {
+            // The admin can prevent OEM unlock with the DISALLOW_FACTORY_RESET user restriction
+            if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
+                     UserManager.DISALLOW_FACTORY_RESET)) {
+                final boolean unlockAllowedByAdmin =
+                        !newRestrictions.getBoolean(UserManager.DISALLOW_FACTORY_RESET);
+                if (!unlockAllowedByAdmin) {
+                    mOemLock.setOemUnlockAllowedByDevice(false);
+                }
+            }
+        }
+    };
+
+    /**
+     * Implements the binder interface for the service.
+     *
+     * This checks for the relevant permissions before forwarding the call to the OEM lock
+     * implementation being used on this device.
+     */
+    private final IBinder mService = new IOemLockService.Stub() {
+        @Override
+        public void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) {
+            enforceManageCarrierOemUnlockPermission();
+            enforceUserIsAdmin();
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mOemLock.setOemUnlockAllowedByCarrier(allowed, signature);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public boolean isOemUnlockAllowedByCarrier() {
+            enforceManageCarrierOemUnlockPermission();
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+              return mOemLock.isOemUnlockAllowedByCarrier();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        // The user has the final say so if they allow unlock, then the device allows the bootloader
+        // to OEM unlock it.
+        @Override
+        public void setOemUnlockAllowedByUser(boolean allowedByUser) {
+            if (ActivityManager.isUserAMonkey()) {
+                // Prevent a monkey from changing this
+                return;
+            }
+
+            enforceManageUserOemUnlockPermission();
+            enforceUserIsAdmin();
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+                if (!canUserAllowOemUnlock()) {
+                    throw new SecurityException("User cannot allow OEM unlock");
+                }
+
+                mOemLock.setOemUnlockAllowedByDevice(allowedByUser);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public boolean isOemUnlockAllowedByUser() {
+            enforceManageUserOemUnlockPermission();
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+                return mOemLock.isOemUnlockAllowedByDevice();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public boolean canUserAllowOemUnlock() {
+            enforceOemUnlockReadPermission();
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+                return isOemUnlockAllowedByAdmin() && mOemLock.isOemUnlockAllowedByCarrier();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public boolean isOemUnlockAllowed() {
+            enforceOemUnlockReadPermission();
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+                return mOemLock.isOemUnlockAllowedByCarrier() &&
+                        mOemLock.isOemUnlockAllowedByDevice();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public boolean isDeviceOemUnlocked() {
+            enforceOemUnlockReadPermission();
+
+            String locked = SystemProperties.get(FLASH_LOCK_PROP);
+            switch (locked) {
+                case FLASH_LOCK_UNLOCKED:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+    };
+
+    private boolean isOemUnlockAllowedByAdmin() {
+        return !UserManager.get(mContext)
+                .hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET, UserHandle.SYSTEM);
+    }
+
+    private void enforceManageCarrierOemUnlockPermission() {
+        mContext.enforceCallingOrSelfPermission(
+                Manifest.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE,
+                "Can't manage OEM unlock allowed by carrier");
+    }
+
+    private void enforceManageUserOemUnlockPermission() {
+        mContext.enforceCallingOrSelfPermission(
+                Manifest.permission.MANAGE_USER_OEM_UNLOCK_STATE,
+                "Can't manage OEM unlock allowed by user");
+    }
+
+    private void enforceOemUnlockReadPermission() {
+        if (mContext.checkCallingOrSelfPermission(Manifest.permission.READ_OEM_UNLOCK_STATE)
+                == PackageManager.PERMISSION_DENIED
+                && mContext.checkCallingOrSelfPermission(Manifest.permission.OEM_UNLOCK_STATE)
+                == PackageManager.PERMISSION_DENIED) {
+            throw new SecurityException("Can't access OEM unlock state. Requires "
+                    + "READ_OEM_UNLOCK_STATE or OEM_UNLOCK_STATE permission.");
+        }
+    }
+
+    private void enforceUserIsAdmin() {
+        final int userId = UserHandle.getCallingUserId();
+        final long token = Binder.clearCallingIdentity();
+        try {
+            if (!UserManager.get(mContext).isUserAdmin(userId)) {
+                throw new SecurityException("Must be an admin user");
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/oemlock/PersistentDataBlockLock.java b/services/core/java/com/android/server/oemlock/PersistentDataBlockLock.java
new file mode 100644
index 0000000..d9362d4
--- /dev/null
+++ b/services/core/java/com/android/server/oemlock/PersistentDataBlockLock.java
@@ -0,0 +1,92 @@
+/*
+ * 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.oemlock;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.service.persistentdata.PersistentDataBlockManager;
+import android.util.Slog;
+
+/**
+ * Implementation of the OEM lock using the persistent data block to communicate with the
+ * bootloader.
+ *
+ * The carrier flag is stored as a user restriction on the system user. The user flag is set in the
+ * presistent data block but depends on the carrier flag.
+ */
+class PersistentDataBlockLock extends OemLock {
+    private static final String TAG = "OemLock";
+
+    private Context mContext;
+
+    PersistentDataBlockLock(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) {
+        // Note: this implementation does not require a signature
+        if (signature != null) {
+            Slog.w(TAG, "Signature provided but is not being used");
+        }
+
+        // Continue using user restriction for backwards compatibility
+        UserManager.get(mContext).setUserRestriction(
+                UserManager.DISALLOW_OEM_UNLOCK, !allowed, UserHandle.SYSTEM);
+
+        if (!allowed) {
+            disallowUnlockIfNotUnlocked();
+        }
+    }
+
+    @Override
+    boolean isOemUnlockAllowedByCarrier() {
+        return !UserManager.get(mContext)
+                .hasUserRestriction(UserManager.DISALLOW_OEM_UNLOCK, UserHandle.SYSTEM);
+    }
+
+    @Override
+    void setOemUnlockAllowedByDevice(boolean allowedByDevice) {
+        // The method name is misleading as it really just means whether or not the device can be
+        // unlocked but doesn't actually do any unlocking.
+        final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
+                mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+        pdbm.setOemUnlockEnabled(allowedByDevice);
+    }
+
+    @Override
+    boolean isOemUnlockAllowedByDevice() {
+        final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
+            mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+        return pdbm.getOemUnlockEnabled();
+    }
+
+    /**
+     * Update state to prevent the bootloader from being able to unlock the device unless the device
+     * has already been unlocked by the bootloader in which case it is too late as it would remain
+     * unlocked.
+     */
+    private void disallowUnlockIfNotUnlocked() {
+        final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
+            mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+        if (pdbm.getFlashLockState() != PersistentDataBlockManager.FLASH_LOCK_UNLOCKED) {
+            pdbm.setOemUnlockEnabled(false);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/oemlock/VendorLock.java b/services/core/java/com/android/server/oemlock/VendorLock.java
new file mode 100644
index 0000000..1b9de36
--- /dev/null
+++ b/services/core/java/com/android/server/oemlock/VendorLock.java
@@ -0,0 +1,167 @@
+/*
+ * 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.oemlock;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.oemlock.V1_0.IOemLock;
+import android.hardware.oemlock.V1_0.OemLockSecureStatus;
+import android.hardware.oemlock.V1_0.OemLockStatus;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+
+/**
+ * Uses the OEM lock HAL.
+ */
+class VendorLock extends OemLock {
+    private static final String TAG = "OemLock";
+
+    private Context mContext;
+    private IOemLock mOemLock;
+
+    static IOemLock getOemLockHalService() {
+        try {
+            return IOemLock.getService();
+        } catch (NoSuchElementException e) {
+            Slog.i(TAG, "OemLock HAL not present on device");
+            return null;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    VendorLock(Context context, IOemLock oemLock) {
+        mContext = context;
+        mOemLock = oemLock;
+    }
+
+    @Override
+    void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) {
+        try {
+            switch (mOemLock.setOemUnlockAllowedByCarrier(allowed, toByteArrayList(signature))) {
+                case OemLockSecureStatus.OK:
+                    Slog.i(TAG, "Updated carrier allows OEM lock state to: " + allowed);
+                    return;
+
+                case OemLockSecureStatus.INVALID_SIGNATURE:
+                    throw new SecurityException(
+                            "Invalid signature used in attempt to carrier unlock");
+
+                default:
+                    Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
+                    // Fallthrough
+                case OemLockSecureStatus.FAILED:
+                    throw new RuntimeException("Failed to set carrier OEM unlock state");
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to set carrier state with HAL", e);
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    @Override
+    boolean isOemUnlockAllowedByCarrier() {
+        final Integer[] requestStatus = new Integer[1];
+        final Boolean[] allowedByCarrier = new Boolean[1];
+
+        try {
+            mOemLock.isOemUnlockAllowedByCarrier((status, allowed) -> {
+                requestStatus[0] = status;
+                allowedByCarrier[0] = allowed;
+            });
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to get carrier state from HAL");
+            throw e.rethrowFromSystemServer();
+        }
+
+        switch (requestStatus[0]) {
+            case OemLockStatus.OK:
+                // Success
+                return allowedByCarrier[0];
+
+            default:
+                Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
+                // Fallthrough
+            case OemLockStatus.FAILED:
+                throw new RuntimeException("Failed to get carrier OEM unlock state");
+        }
+    }
+
+    @Override
+    void setOemUnlockAllowedByDevice(boolean allowedByDevice) {
+        try {
+            switch (mOemLock.setOemUnlockAllowedByDevice(allowedByDevice)) {
+                case OemLockSecureStatus.OK:
+                    Slog.i(TAG, "Updated device allows OEM lock state to: " + allowedByDevice);
+                    return;
+
+                default:
+                    Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
+                    // Fallthrough
+                case OemLockSecureStatus.FAILED:
+                    throw new RuntimeException("Failed to set device OEM unlock state");
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to set device state with HAL", e);
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    @Override
+    boolean isOemUnlockAllowedByDevice() {
+        final Integer[] requestStatus = new Integer[1];
+        final Boolean[] allowedByDevice = new Boolean[1];
+
+        try {
+            mOemLock.isOemUnlockAllowedByDevice((status, allowed) -> {
+                requestStatus[0] = status;
+                allowedByDevice[0] = allowed;
+            });
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to get devie state from HAL");
+            throw e.rethrowFromSystemServer();
+        }
+
+        switch (requestStatus[0]) {
+            case OemLockStatus.OK:
+                // Success
+                return allowedByDevice[0];
+
+            default:
+                Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
+                // Fallthrough
+            case OemLockStatus.FAILED:
+                throw new RuntimeException("Failed to get device OEM unlock state");
+        }
+    }
+
+    private ArrayList toByteArrayList(byte[] data) {
+        if (data == null) {
+            return null;
+        }
+        ArrayList<Byte> result = new ArrayList<Byte>(data.length);
+        for (final byte b : data) {
+            result.add(b);
+        }
+        return result;
+    }
+}
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index 04d91f8..807c343 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -92,26 +92,10 @@
         return new File(getIdmapPath(overlayPackage.applicationInfo.getBaseCodePath())).isFile();
     }
 
-    boolean isDangerous(@NonNull final PackageInfo overlayPackage, final int userId) {
-        // unused userId: see comment in OverlayManagerServiceImpl.removeIdmapIfPossible
-        return isDangerous(getIdmapPath(overlayPackage.applicationInfo.getBaseCodePath()));
-    }
-
     private String getIdmapPath(@NonNull final String baseCodePath) {
         final StringBuilder sb = new StringBuilder("/data/resource-cache/");
         sb.append(baseCodePath.substring(1).replace('/', '@'));
         sb.append("@idmap");
         return sb.toString();
     }
-
-    private boolean isDangerous(@NonNull final String idmapPath) {
-        try (DataInputStream dis = new DataInputStream(new FileInputStream(idmapPath))) {
-            final int magic = dis.readInt();
-            final int version = dis.readInt();
-            final int dangerous = dis.readInt();
-            return dangerous != 0;
-        } catch (IOException e) {
-            return true;
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/os/SchedulingPolicyService.java b/services/core/java/com/android/server/os/SchedulingPolicyService.java
index 46be232..e0b8426 100644
--- a/services/core/java/com/android/server/os/SchedulingPolicyService.java
+++ b/services/core/java/com/android/server/os/SchedulingPolicyService.java
@@ -57,7 +57,7 @@
             try {
                 // make good use of our CAP_SYS_NICE capability
                 Process.setThreadGroup(tid, !isForApp ?
-                  Process.THREAD_GROUP_AUDIO_SYS : Process.THREAD_GROUP_AUDIO_APP);
+                  Process.THREAD_GROUP_AUDIO_SYS : Process.THREAD_GROUP_RT_APP);
             } catch (RuntimeException e) {
                 Log.e(TAG, "Failed setThreadGroup: " + e);
                 return PackageManager.PERMISSION_DENIED;
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index 6749afb..e5c48cc 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -18,7 +18,6 @@
 
 import static com.android.server.pm.PackageManagerService.DEBUG_DEXOPT;
 
-import android.app.AlarmManager;
 import android.app.job.JobInfo;
 import android.app.job.JobParameters;
 import android.app.job.JobScheduler;
@@ -38,8 +37,10 @@
 import com.android.server.pm.dex.DexManager;
 import com.android.server.LocalServices;
 import com.android.server.PinnerService;
+import com.android.server.pm.dex.DexoptOptions;
 
 import java.io.File;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.TimeUnit;
 
@@ -73,6 +74,9 @@
     // Optimizations should be aborted. No space left on device.
     private static final int OPTIMIZE_ABORT_NO_SPACE_LEFT = 3;
 
+    // Used for calculating space threshold for downgrading unused apps.
+    private static final int LOW_THRESHOLD_MULTIPLIER_FOR_DOWNGRADE = 2;
+
     /**
      * Set of failed packages remembered across job runs.
      */
@@ -92,6 +96,9 @@
 
     private final File mDataDir = Environment.getDataDirectory();
 
+    private static final long mDowngradeUnusedAppsThresholdInMillis =
+            getDowngradeUnusedAppsThresholdInMillis();
+
     public static void schedule(Context context) {
         JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
 
@@ -211,11 +218,10 @@
             // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
             // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
             // trade-off worth doing to save boot time work.
-            int result = pm.performDexOptWithStatus(pkg,
-                    /* checkProfiles */ false,
+            int result = pm.performDexOptWithStatus(new DexoptOptions(
+                    pkg,
                     PackageManagerService.REASON_BOOT,
-                    /* force */ false,
-                    /* bootComplete */ true);
+                    DexoptOptions.DEXOPT_BOOT_COMPLETE));
             if (result == PackageDexOptimizer.DEX_OPT_PERFORMED)  {
                 updatedPackages.add(pkg);
             }
@@ -243,7 +249,8 @@
     }
 
     // Optimize the given packages and return the optimization result (one of the OPTIMIZE_* codes).
-    private int idleOptimization(PackageManagerService pm, ArraySet<String> pkgs, Context context) {
+    private int idleOptimization(PackageManagerService pm, ArraySet<String> pkgs,
+            Context context) {
         Log.i(TAG, "Performing idle optimizations");
         // If post-boot update is still running, request that it exits early.
         mExitPostBootUpdate.set(true);
@@ -274,9 +281,16 @@
             long lowStorageThreshold, boolean is_for_primary_dex,
             ArraySet<String> failedPackageNames) {
         ArraySet<String> updatedPackages = new ArraySet<>();
+        Set<String> unusedPackages = pm.getUnusedPackages(mDowngradeUnusedAppsThresholdInMillis);
+        // Only downgrade apps when space is low on device.
+        // Threshold is selected above the lowStorageThreshold so that we can pro-actively clean
+        // up disk before user hits the actual lowStorageThreshold.
+        final long lowStorageThresholdForDowngrade = LOW_THRESHOLD_MULTIPLIER_FOR_DOWNGRADE *
+                lowStorageThreshold;
+        boolean shouldDowngrade = shouldDowngrade(lowStorageThresholdForDowngrade);
         for (String pkg : pkgs) {
             int abort_code = abortIdleOptimizations(lowStorageThreshold);
-            if (abort_code != OPTIMIZE_CONTINUE) {
+            if (abort_code == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
                 return abort_code;
             }
 
@@ -284,30 +298,58 @@
                 if (failedPackageNames.contains(pkg)) {
                     // Skip previously failing package
                     continue;
-                } else {
-                    // Conservatively add package to the list of failing ones in case performDexOpt
-                    // never returns.
-                    failedPackageNames.add(pkg);
                 }
             }
 
+            int reason;
+            boolean downgrade;
+            // Downgrade unused packages.
+            if (unusedPackages.contains(pkg) && shouldDowngrade) {
+                // This applies for system apps or if packages location is not a directory, i.e.
+                // monolithic install.
+                if (is_for_primary_dex && !pm.canHaveOatDir(pkg)) {
+                    // For apps that don't have the oat directory, instead of downgrading,
+                    // remove their compiler artifacts from dalvik cache.
+                    pm.deleteOatArtifactsOfPackage(pkg);
+                    continue;
+                } else {
+                    reason = PackageManagerService.REASON_INACTIVE_PACKAGE_DOWNGRADE;
+                    downgrade = true;
+                }
+            } else if (abort_code != OPTIMIZE_ABORT_NO_SPACE_LEFT) {
+                reason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
+                downgrade = false;
+            } else {
+                // can't dexopt because of low space.
+                continue;
+            }
+
+            synchronized (failedPackageNames) {
+                // Conservatively add package to the list of failing ones in case
+                // performDexOpt never returns.
+                failedPackageNames.add(pkg);
+            }
+
             // Optimize package if needed. Note that there can be no race between
             // concurrent jobs because PackageDexOptimizer.performDexOpt is synchronized.
             boolean success;
+            int dexoptFlags =
+                    DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
+                    DexoptOptions.DEXOPT_BOOT_COMPLETE |
+                    (downgrade ? DexoptOptions.DEXOPT_DOWNGRADE : 0) |
+                    DexoptOptions.DEXOPT_IDLE_BACKGROUND_JOB;
             if (is_for_primary_dex) {
-                int result = pm.performDexOptWithStatus(pkg,
-                        /* checkProfiles */ true,
+                int result = pm.performDexOptWithStatus(new DexoptOptions(pkg,
                         PackageManagerService.REASON_BACKGROUND_DEXOPT,
-                        /* force */ false,
-                        /* bootComplete */ true);
+                        dexoptFlags));
                 success = result != PackageDexOptimizer.DEX_OPT_FAILED;
                 if (result == PackageDexOptimizer.DEX_OPT_PERFORMED) {
                     updatedPackages.add(pkg);
                 }
             } else {
-                success = pm.performDexOptSecondary(pkg,
+                success = pm.performDexOpt(new DexoptOptions(pkg,
                         PackageManagerService.REASON_BACKGROUND_DEXOPT,
-                        /* force */ false);
+                        dexoptFlags | DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX));
             }
             if (success) {
                 // Dexopt succeeded, remove package from the list of failing ones.
@@ -347,6 +389,16 @@
         return OPTIMIZE_CONTINUE;
     }
 
+    // Evaluate whether apps should be downgraded.
+    private boolean shouldDowngrade(long lowStorageThresholdForDowngrade) {
+        long usableSpace = mDataDir.getUsableSpace();
+        if (usableSpace < lowStorageThresholdForDowngrade) {
+            return true;
+        }
+
+        return false;
+    }
+
     /**
      * Execute the idle optimizations immediately.
      */
@@ -415,4 +467,14 @@
             pinnerService.update(updatedPackages);
         }
     }
+
+    private static long getDowngradeUnusedAppsThresholdInMillis() {
+        final String sysPropKey = "pm.dexopt.downgrade_after_inactive_days";
+        String sysPropValue = SystemProperties.get(sysPropKey);
+        if (sysPropValue == null || sysPropValue.isEmpty()) {
+            Log.w(TAG, "SysProp " + sysPropKey + " not set");
+            return Long.MAX_VALUE;
+        }
+        return TimeUnit.DAYS.toMillis(Long.parseLong(sysPropValue));
+    }
 }
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index d1aecb1..b217677 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -30,6 +30,7 @@
 import android.content.pm.PackageParser;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
+import android.media.RingtoneManager;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Environment;
@@ -701,6 +702,16 @@
                         LOCATION_PERMISSIONS, true, userId);
             }
 
+            // Ringtone Picker
+            Intent ringtonePickerIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
+            PackageParser.Package ringtonePickerPackage =
+                    getDefaultSystemHandlerActivityPackageLPr(ringtonePickerIntent, userId);
+            if (ringtonePickerPackage != null
+                    && doesPackageSupportRuntimePermissions(ringtonePickerPackage)) {
+                grantRuntimePermissionsLPw(ringtonePickerPackage,
+                        STORAGE_PERMISSIONS, true, userId);
+            }
+
             mService.mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
         }
     }
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index c95b5c5..210eb13 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -56,6 +56,8 @@
     public static final int DEXOPT_STORAGE_CE     = 1 << 7;
     /** Indicates that the dex file passed to dexopt in on DE storage. */
     public static final int DEXOPT_STORAGE_DE     = 1 << 8;
+    /** Indicates that dexopt is invoked from the background service. */
+    public static final int DEXOPT_IDLE_BACKGROUND_JOB = 1 << 9;
 
     // NOTE: keep in sync with installd
     public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 8;
@@ -258,7 +260,7 @@
 
     public long[] getExternalSize(String uuid, int userId, int flags, int[] appIds)
             throws InstallerException {
-        if (!checkBeforeRemote()) return new long[4];
+        if (!checkBeforeRemote()) return new long[6];
         try {
             return mInstalld.getExternalSize(uuid, userId, flags, appIds);
         } catch (Exception e) {
@@ -279,13 +281,13 @@
     public void dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet,
             int dexoptNeeded, @Nullable String outputPath, int dexFlags,
             String compilerFilter, @Nullable String volumeUuid, @Nullable String sharedLibraries,
-            @Nullable String seInfo)
+            @Nullable String seInfo, boolean downgrade)
             throws InstallerException {
         assertValidInstructionSet(instructionSet);
         if (!checkBeforeRemote()) return;
         try {
             mInstalld.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath,
-                    dexFlags, compilerFilter, volumeUuid, sharedLibraries, seInfo);
+                    dexFlags, compilerFilter, volumeUuid, sharedLibraries, seInfo, downgrade);
         } catch (Exception e) {
             throw InstallerException.from(e);
         }
@@ -310,6 +312,16 @@
         }
     }
 
+    public boolean copySystemProfile(String systemProfile, int uid, String packageName)
+            throws InstallerException {
+        if (!checkBeforeRemote()) return false;
+        try {
+            return mInstalld.copySystemProfile(systemProfile, uid, packageName);
+        } catch (Exception e) {
+            throw InstallerException.from(e);
+        }
+    }
+
     public void idmap(String targetApkPath, String overlayApkPath, int uid)
             throws InstallerException {
         if (!checkBeforeRemote()) return;
diff --git a/services/core/java/com/android/server/pm/InstructionSets.java b/services/core/java/com/android/server/pm/InstructionSets.java
index 5092ebf..f326f1d 100644
--- a/services/core/java/com/android/server/pm/InstructionSets.java
+++ b/services/core/java/com/android/server/pm/InstructionSets.java
@@ -34,7 +34,7 @@
  */
 public class InstructionSets {
     private static final String PREFERRED_INSTRUCTION_SET =
-            VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);;
+            VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
     public static String[] getAppDexInstructionSets(ApplicationInfo info) {
         if (info.primaryCpuAbi != null) {
             if (info.secondaryCpuAbi != null) {
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 54ca6b9..73ac057 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -18,7 +18,6 @@
 
 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
-import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
 
 import android.annotation.Nullable;
 import android.content.Context;
@@ -30,17 +29,16 @@
 import android.os.ServiceManager;
 import android.os.ShellCallback;
 import android.os.storage.StorageManager;
-import android.text.TextUtils;
 import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.server.pm.Installer.InstallerException;
+import com.android.server.pm.dex.DexoptOptions;
 
 import java.io.File;
 import java.io.FileDescriptor;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
@@ -55,7 +53,8 @@
     private final static boolean DEBUG_DEXOPT = true;
 
     // The synthetic library dependencies denoting "no checks."
-    private final static String[] NO_LIBRARIES = new String[] { "&" };
+    private final static String[] NO_LIBRARIES =
+            new String[] { PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK };
 
     // The amount of "available" (free - low threshold) space necessary at the start of an OTA to
     // not bulk-delete unused apps' odex files.
@@ -152,7 +151,7 @@
             Log.i(TAG, "Low on space, deleting oat files in an attempt to free up space: "
                     + PackageManagerServiceUtils.packagesToString(others));
             for (PackageParser.Package pkg : others) {
-                deleteOatArtifactsOfPackage(pkg);
+                mPackageManagerService.deleteOatArtifactsOfPackage(pkg.packageName);
             }
         }
         long spaceAvailableNow = getAvailableSpace();
@@ -242,30 +241,6 @@
         return usableSpace - lowThreshold;
     }
 
-    private static String getOatDir(PackageParser.Package pkg) {
-        if (!pkg.canHaveOatDir()) {
-            return null;
-        }
-        File codePath = new File(pkg.codePath);
-        if (codePath.isDirectory()) {
-            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
-        }
-        return null;
-    }
-
-    private void deleteOatArtifactsOfPackage(PackageParser.Package pkg) {
-        String[] instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
-        for (String codePath : pkg.getAllCodePaths()) {
-            for (String isa : instructionSets) {
-                try {
-                    mPackageManagerService.mInstaller.deleteOdex(codePath, isa, getOatDir(pkg));
-                } catch (InstallerException e) {
-                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
-                }
-            }
-        }
-    }
-
     /**
      * Generate all dexopt commands for the given package.
      */
@@ -285,11 +260,12 @@
             public void dexopt(String apkPath, int uid, @Nullable String pkgName,
                     String instructionSet, int dexoptNeeded, @Nullable String outputPath,
                     int dexFlags, String compilerFilter, @Nullable String volumeUuid,
-                    @Nullable String sharedLibraries, @Nullable String seInfo) throws InstallerException {
+                    @Nullable String sharedLibraries, @Nullable String seInfo, boolean downgrade)
+                    throws InstallerException {
                 final StringBuilder builder = new StringBuilder();
 
-                // The version. Right now it's 2.
-                builder.append("2 ");
+                // The version. Right now it's 3.
+                builder.append("3 ");
 
                 builder.append("dexopt");
 
@@ -304,6 +280,7 @@
                 encodeParameter(builder, volumeUuid);
                 encodeParameter(builder, sharedLibraries);
                 encodeParameter(builder, seInfo);
+                encodeParameter(builder, downgrade);
 
                 commands.add(builder.toString());
             }
@@ -338,12 +315,18 @@
             libraryDependencies = NO_LIBRARIES;
         }
 
+
         optimizer.performDexOpt(pkg, libraryDependencies,
-                null /* ISAs */, false /* checkProfiles */,
-                getCompilerFilterForReason(compilationReason),
+                null /* ISAs */,
                 null /* CompilerStats.PackageStats */,
-                mPackageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName),
-                true /* bootComplete */);
+                mPackageManagerService.getDexManager().getPackageUseInfoOrDefault(pkg.packageName),
+                new DexoptOptions(pkg.packageName, compilationReason,
+                        DexoptOptions.DEXOPT_BOOT_COMPLETE));
+
+        mPackageManagerService.getDexManager().dexoptSecondaryDex(
+                new DexoptOptions(pkg.packageName, compilationReason,
+                        DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
+                                DexoptOptions.DEXOPT_BOOT_COMPLETE));
 
         return commands;
     }
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 5021f2f..bf1c4c3 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -19,27 +19,30 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageParser;
-import android.os.Environment;
 import android.os.FileUtils;
 import android.os.PowerManager;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.util.Log;
 import android.util.Slog;
-import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.pm.Installer.InstallerException;
+import com.android.server.pm.dex.DexManager;
+import com.android.server.pm.dex.DexoptOptions;
+import com.android.server.pm.dex.DexoptUtils;
+import com.android.server.pm.dex.PackageDexUsage;
 
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
-import java.util.Set;
+import java.util.Map;
 
 import dalvik.system.DexFile;
 
@@ -51,6 +54,7 @@
 import static com.android.server.pm.Installer.DEXOPT_FORCE;
 import static com.android.server.pm.Installer.DEXOPT_STORAGE_CE;
 import static com.android.server.pm.Installer.DEXOPT_STORAGE_DE;
+import static com.android.server.pm.Installer.DEXOPT_IDLE_BACKGROUND_JOB;
 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
 
@@ -101,7 +105,17 @@
     }
 
     static boolean canOptimizePackage(PackageParser.Package pkg) {
-        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
+        // We do not dexopt a package with no code.
+        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) {
+            return false;
+        }
+
+        // We do not dexopt a priv-app package when pm.dexopt.priv-apps-oob is true.
+        if (pkg.isPrivilegedApp()) {
+            return !SystemProperties.getBoolean("pm.dexopt.priv-apps-oob", false);
+        }
+
+        return true;
     }
 
     /**
@@ -112,17 +126,16 @@
      * synchronized on {@link #mInstallLock}.
      */
     int performDexOpt(PackageParser.Package pkg, String[] sharedLibraries,
-            String[] instructionSets, boolean checkProfiles, String targetCompilationFilter,
-            CompilerStats.PackageStats packageStats, boolean isUsedByOtherApps,
-            boolean bootComplete) {
+            String[] instructionSets, CompilerStats.PackageStats packageStats,
+            PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) {
         if (!canOptimizePackage(pkg)) {
             return DEX_OPT_SKIPPED;
         }
         synchronized (mInstallLock) {
             final long acquireTime = acquireWakeLockLI(pkg.applicationInfo.uid);
             try {
-                return performDexOptLI(pkg, sharedLibraries, instructionSets, checkProfiles,
-                        targetCompilationFilter, packageStats, isUsedByOtherApps, bootComplete);
+                return performDexOptLI(pkg, sharedLibraries, instructionSets,
+                        packageStats, packageUseInfo, options);
             } finally {
                 releaseWakeLockLI(acquireTime);
             }
@@ -135,46 +148,79 @@
      */
     @GuardedBy("mInstallLock")
     private int performDexOptLI(PackageParser.Package pkg, String[] sharedLibraries,
-            String[] targetInstructionSets, boolean checkForProfileUpdates,
-            String targetCompilerFilter, CompilerStats.PackageStats packageStats,
-            boolean isUsedByOtherApps, boolean bootComplete) {
+            String[] targetInstructionSets, CompilerStats.PackageStats packageStats,
+            PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) {
         final String[] instructionSets = targetInstructionSets != null ?
                 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
         final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
         final List<String> paths = pkg.getAllCodePaths();
-        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
 
-        final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo,
-                targetCompilerFilter, isUsedByOtherApps);
-        final boolean profileUpdated = checkForProfileUpdates &&
-                isProfileUpdated(pkg, sharedGid, compilerFilter);
+        int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
+        if (sharedGid == -1) {
+            Slog.wtf(TAG, "Well this is awkward; package " + pkg.applicationInfo.name + " had UID "
+                    + pkg.applicationInfo.uid, new Throwable());
+            sharedGid = android.os.Process.NOBODY_UID;
+        }
 
-        final String sharedLibrariesPath = getSharedLibrariesPath(sharedLibraries);
-        // Get the dexopt flags after getRealCompilerFilter to make sure we get the correct flags.
-        final int dexoptFlags = getDexFlags(pkg, compilerFilter, bootComplete);
-        // Get the dependencies of each split in the package. For each code path in the package,
-        // this array contains the relative paths of each split it depends on, separated by colons.
-        String[] splitDependencies = getSplitDependencies(pkg);
+        // Get the class loader context dependencies.
+        // For each code path in the package, this array contains the class loader context that
+        // needs to be passed to dexopt in order to ensure correct optimizations.
+        boolean[] pathsWithCode = new boolean[paths.size()];
+        pathsWithCode[0] = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
+        for (int i = 1; i < paths.size(); i++) {
+            pathsWithCode[i] = (pkg.splitFlags[i - 1] & ApplicationInfo.FLAG_HAS_CODE) != 0;
+        }
+        String[] classLoaderContexts = DexoptUtils.getClassLoaderContexts(
+                pkg.applicationInfo, sharedLibraries, pathsWithCode);
+
+        // Sanity check that we do not call dexopt with inconsistent data.
+        if (paths.size() != classLoaderContexts.length) {
+            String[] splitCodePaths = pkg.applicationInfo.getSplitCodePaths();
+            throw new IllegalStateException("Inconsistent information "
+                + "between PackageParser.Package and its ApplicationInfo. "
+                + "pkg.getAllCodePaths=" + paths
+                + " pkg.applicationInfo.getBaseCodePath=" + pkg.applicationInfo.getBaseCodePath()
+                + " pkg.applicationInfo.getSplitCodePaths="
+                + (splitCodePaths == null ? "null" : Arrays.toString(splitCodePaths)));
+        }
 
         int result = DEX_OPT_SKIPPED;
         for (int i = 0; i < paths.size(); i++) {
             // Skip paths that have no code.
-            if ((i == 0 && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) ||
-                    (i != 0 && (pkg.splitFlags[i - 1] & ApplicationInfo.FLAG_HAS_CODE) == 0)) {
+            if (!pathsWithCode[i]) {
                 continue;
             }
+            if (classLoaderContexts[i] == null) {
+                throw new IllegalStateException("Inconsistent information in the "
+                        + "package structure. A split is marked to contain code "
+                        + "but has no dependency listed. Index=" + i + " path=" + paths.get(i));
+            }
+
             // Append shared libraries with split dependencies for this split.
             String path = paths.get(i);
-            String sharedLibrariesPathWithSplits;
-            if (sharedLibrariesPath != null && splitDependencies[i] != null) {
-                sharedLibrariesPathWithSplits = sharedLibrariesPath + ":" + splitDependencies[i];
-            } else {
-                sharedLibrariesPathWithSplits =
-                        splitDependencies[i] != null ? splitDependencies[i] : sharedLibrariesPath;
+            if (options.getSplitName() != null) {
+                // We are asked to compile only a specific split. Check that the current path is
+                // what we are looking for.
+                if (!options.getSplitName().equals(new File(path).getName())) {
+                    continue;
+                }
             }
+
+            final boolean isUsedByOtherApps = options.isDexoptAsSharedLibrary()
+                    || packageUseInfo.isUsedByOtherApps(path);
+            final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo,
+                options.getCompilerFilter(), isUsedByOtherApps);
+            final boolean profileUpdated = options.isCheckForProfileUpdates() &&
+                isProfileUpdated(pkg, sharedGid, compilerFilter);
+
+            // Get the dexopt flags after getRealCompilerFilter to make sure we get the correct
+            // flags.
+            final int dexoptFlags = getDexFlags(pkg, compilerFilter, options);
+
             for (String dexCodeIsa : dexCodeInstructionSets) {
-                int newResult = dexOptPath(pkg, path, dexCodeIsa, compilerFilter, profileUpdated,
-                        sharedLibrariesPathWithSplits, dexoptFlags, sharedGid, packageStats);
+                int newResult = dexOptPath(pkg, path, dexCodeIsa, compilerFilter,
+                        profileUpdated, classLoaderContexts[i], dexoptFlags, sharedGid,
+                        packageStats, options.isDowngrade());
                 // The end result is:
                 //  - FAILED if any path failed,
                 //  - PERFORMED if at least one path needed compilation,
@@ -197,9 +243,10 @@
      */
     @GuardedBy("mInstallLock")
     private int dexOptPath(PackageParser.Package pkg, String path, String isa,
-            String compilerFilter, boolean profileUpdated, String sharedLibrariesPath,
-            int dexoptFlags, int uid, CompilerStats.PackageStats packageStats) {
-        int dexoptNeeded = getDexoptNeeded(path, isa, compilerFilter, profileUpdated);
+            String compilerFilter, boolean profileUpdated, String classLoaderContext,
+            int dexoptFlags, int uid, CompilerStats.PackageStats packageStats, boolean downgrade) {
+        int dexoptNeeded = getDexoptNeeded(path, isa, compilerFilter, classLoaderContext,
+                profileUpdated, downgrade);
         if (Math.abs(dexoptNeeded) == DexFile.NO_DEXOPT_NEEDED) {
             return DEX_OPT_SKIPPED;
         }
@@ -212,14 +259,18 @@
         Log.i(TAG, "Running dexopt (dexoptNeeded=" + dexoptNeeded + ") on: " + path
                 + " pkg=" + pkg.applicationInfo.packageName + " isa=" + isa
                 + " dexoptFlags=" + printDexoptFlags(dexoptFlags)
-                + " target-filter=" + compilerFilter + " oatDir=" + oatDir
-                + " sharedLibraries=" + sharedLibrariesPath);
+                + " targetFilter=" + compilerFilter + " oatDir=" + oatDir
+                + " classLoaderContext=" + classLoaderContext);
 
         try {
             long startTime = System.currentTimeMillis();
 
+            // TODO: Consider adding 2 different APIs for primary and secondary dexopt.
+            // installd only uses downgrade flag for secondary dex files and ignores it for
+            // primary dex files.
             mInstaller.dexopt(path, uid, pkg.packageName, isa, dexoptNeeded, oatDir, dexoptFlags,
-                    compilerFilter, pkg.volumeUuid, sharedLibrariesPath, pkg.applicationInfo.seInfo);
+                    compilerFilter, pkg.volumeUuid, classLoaderContext, pkg.applicationInfo.seInfo,
+                    false /* downgrade*/);
 
             if (packageStats != null) {
                 long endTime = System.currentTimeMillis();
@@ -246,13 +297,12 @@
      * throwing exceptions). Or maybe make a separate call to installd to get DexOptNeeded, though
      * that seems wasteful.
      */
-    public int dexOptSecondaryDexPath(ApplicationInfo info, String path, Set<String> isas,
-            String compilerFilter, boolean isUsedByOtherApps) {
+    public int dexOptSecondaryDexPath(ApplicationInfo info, String path,
+            PackageDexUsage.DexUseInfo dexUseInfo, DexoptOptions options) {
         synchronized (mInstallLock) {
             final long acquireTime = acquireWakeLockLI(info.uid);
             try {
-                return dexOptSecondaryDexPathLI(info, path, isas, compilerFilter,
-                        isUsedByOtherApps);
+                return dexOptSecondaryDexPathLI(info, path, dexUseInfo, options);
             } finally {
                 releaseWakeLockLI(acquireTime);
             }
@@ -293,13 +343,19 @@
     }
 
     @GuardedBy("mInstallLock")
-    private int dexOptSecondaryDexPathLI(ApplicationInfo info, String path, Set<String> isas,
-            String compilerFilter, boolean isUsedByOtherApps) {
-        compilerFilter = getRealCompilerFilter(info, compilerFilter, isUsedByOtherApps);
+    private int dexOptSecondaryDexPathLI(ApplicationInfo info, String path,
+            PackageDexUsage.DexUseInfo dexUseInfo, DexoptOptions options) {
+        if (options.isDexoptOnlySharedDex() && !dexUseInfo.isUsedByOtherApps()) {
+            // We are asked to optimize only the dex files used by other apps and this is not
+            // on of them: skip it.
+            return DEX_OPT_SKIPPED;
+        }
+
+        String compilerFilter = getRealCompilerFilter(info, options.getCompilerFilter(),
+                dexUseInfo.isUsedByOtherApps());
         // Get the dexopt flags after getRealCompilerFilter to make sure we get the correct flags.
         // Secondary dex files are currently not compiled at boot.
-        int dexoptFlags = getDexFlags(info, compilerFilter, /* bootComplete */ true)
-                | DEXOPT_SECONDARY_DEX;
+        int dexoptFlags = getDexFlags(info, compilerFilter, options) | DEXOPT_SECONDARY_DEX;
         // Check the app storage and add the appropriate flags.
         if (info.deviceProtectedDataDir != null &&
                 FileUtils.contains(info.deviceProtectedDataDir, path)) {
@@ -312,19 +368,27 @@
             return DEX_OPT_FAILED;
         }
         Log.d(TAG, "Running dexopt on: " + path
-                + " pkg=" + info.packageName + " isa=" + isas
+                + " pkg=" + info.packageName + " isa=" + dexUseInfo.getLoaderIsas()
                 + " dexoptFlags=" + printDexoptFlags(dexoptFlags)
                 + " target-filter=" + compilerFilter);
 
+        // TODO(calin): b/64530081 b/66984396. Use SKIP_SHARED_LIBRARY_CHECK for the context
+        // (instead of dexUseInfo.getClassLoaderContext()) in order to compile secondary dex files
+        // in isolation (and avoid to extract/verify the main apk if it's in the class path).
+        // Note this trades correctness for performance since the resulting slow down is
+        // unacceptable in some cases until b/64530081 is fixed.
+        String classLoaderContext = SKIP_SHARED_LIBRARY_CHECK;
+
         try {
-            for (String isa : isas) {
+            for (String isa : dexUseInfo.getLoaderIsas()) {
                 // Reuse the same dexopt path as for the primary apks. We don't need all the
                 // arguments as some (dexopNeeded and oatDir) will be computed by installd because
                 // system server cannot read untrusted app content.
                 // TODO(calin): maybe add a separate call.
                 mInstaller.dexopt(path, info.uid, info.packageName, isa, /*dexoptNeeded*/ 0,
                         /*oatDir*/ null, dexoptFlags,
-                        compilerFilter, info.volumeUuid, SKIP_SHARED_LIBRARY_CHECK, info.seInfoUser);
+                        compilerFilter, info.volumeUuid, classLoaderContext, info.seInfoUser,
+                        options.isDowngrade());
             }
 
             return DEX_OPT_PERFORMED;
@@ -352,26 +416,51 @@
     /**
      * Dumps the dexopt state of the given package {@code pkg} to the given {@code PrintWriter}.
      */
-    void dumpDexoptState(IndentingPrintWriter pw, PackageParser.Package pkg) {
+    void dumpDexoptState(IndentingPrintWriter pw, PackageParser.Package pkg,
+            PackageDexUsage.PackageUseInfo useInfo) {
         final String[] instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
         final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
 
         final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
 
-        for (String instructionSet : dexCodeInstructionSets) {
-             pw.println("Instruction Set: " + instructionSet);
-             pw.increaseIndent();
-             for (String path : paths) {
-                  String status = null;
-                  try {
-                      status = DexFile.getDexFileStatus(path, instructionSet);
-                  } catch (IOException ioe) {
-                      status = "[Exception]: " + ioe.getMessage();
-                  }
-                  pw.println("path: " + path);
-                  pw.println("status: " + status);
-             }
-             pw.decreaseIndent();
+        for (String path : paths) {
+            pw.println("path: " + path);
+            pw.increaseIndent();
+
+            for (String isa : dexCodeInstructionSets) {
+                String status = null;
+                try {
+                    status = DexFile.getDexFileStatus(path, isa);
+                } catch (IOException ioe) {
+                     status = "[Exception]: " + ioe.getMessage();
+                }
+                pw.println(isa + ": " + status);
+            }
+
+            if (useInfo.isUsedByOtherApps(path)) {
+                pw.println("used by other apps: " + useInfo.getLoadingPackages(path));
+            }
+
+            Map<String, PackageDexUsage.DexUseInfo> dexUseInfoMap = useInfo.getDexUseInfoMap();
+
+            if (!dexUseInfoMap.isEmpty()) {
+                pw.println("known secondary dex files:");
+                pw.increaseIndent();
+                for (Map.Entry<String, PackageDexUsage.DexUseInfo> e : dexUseInfoMap.entrySet()) {
+                    String dex = e.getKey();
+                    PackageDexUsage.DexUseInfo dexUseInfo = e.getValue();
+                    pw.println(dex);
+                    pw.increaseIndent();
+                    // TODO(calin): get the status of the oat file (needs installd call)
+                    pw.println("class loader context: " + dexUseInfo.getClassLoaderContext());
+                    if (dexUseInfo.isUsedByOtherApps()) {
+                        pw.println("used by other apps: " + dexUseInfo.getLoadingPackages());
+                    }
+                    pw.decreaseIndent();
+                }
+                pw.decreaseIndent();
+            }
+            pw.decreaseIndent();
         }
     }
 
@@ -389,8 +478,9 @@
         }
 
         if (isProfileGuidedCompilerFilter(targetCompilerFilter) && isUsedByOtherApps) {
-            // If the dex files is used by other apps, we cannot use profile-guided compilation.
-            return getNonProfileGuidedCompilerFilter(targetCompilerFilter);
+            // If the dex files is used by other apps, apply the shared filter.
+            return PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
+                    PackageManagerService.REASON_SHARED);
         }
 
         return targetCompilerFilter;
@@ -401,11 +491,11 @@
      * filter.
      */
     private int getDexFlags(PackageParser.Package pkg, String compilerFilter,
-            boolean bootComplete) {
-        return getDexFlags(pkg.applicationInfo, compilerFilter, bootComplete);
+            DexoptOptions options) {
+        return getDexFlags(pkg.applicationInfo, compilerFilter, options);
     }
 
-    private int getDexFlags(ApplicationInfo info, String compilerFilter, boolean bootComplete) {
+    private int getDexFlags(ApplicationInfo info, String compilerFilter, DexoptOptions options) {
         int flags = info.flags;
         boolean debuggable = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
         // Profile guide compiled oat files should not be public.
@@ -416,7 +506,8 @@
                 (isPublic ? DEXOPT_PUBLIC : 0)
                 | (debuggable ? DEXOPT_DEBUGGABLE : 0)
                 | profileFlag
-                | (bootComplete ? DEXOPT_BOOTCOMPLETE : 0);
+                | (options.isBootComplete() ? DEXOPT_BOOTCOMPLETE : 0)
+                | (options.isDexoptIdleBackgroundJob() ? DEXOPT_IDLE_BACKGROUND_JOB : 0);
         return adjustDexoptFlags(dexFlags);
     }
 
@@ -425,11 +516,11 @@
      * configuration (isa, compiler filter, profile).
      */
     private int getDexoptNeeded(String path, String isa, String compilerFilter,
-            boolean newProfile) {
+            String classLoaderContext, boolean newProfile, boolean downgrade) {
         int dexoptNeeded;
         try {
-          dexoptNeeded = DexFile.getDexOptNeeded(path, isa, compilerFilter, newProfile,
-              false /* downgrade */);
+            dexoptNeeded = DexFile.getDexOptNeeded(path, isa, compilerFilter, classLoaderContext,
+                    newProfile, downgrade);
         } catch (IOException ioe) {
             Slog.w(TAG, "IOException reading apk: " + path, ioe);
             return DEX_OPT_FAILED;
@@ -438,86 +529,6 @@
     }
 
     /**
-     * Computes the shared libraries path that should be passed to dexopt.
-     */
-    private String getSharedLibrariesPath(String[] sharedLibraries) {
-        if (sharedLibraries == null || sharedLibraries.length == 0) {
-            return null;
-        }
-        StringBuilder sb = new StringBuilder();
-        for (String lib : sharedLibraries) {
-            if (sb.length() != 0) {
-                sb.append(":");
-            }
-            sb.append(lib);
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Walks dependency tree and gathers the dependencies for each split in a split apk.
-     * The split paths are stored as relative paths, separated by colons.
-     */
-    private String[] getSplitDependencies(PackageParser.Package pkg) {
-        // Convert all the code paths to relative paths.
-        String baseCodePath = new File(pkg.baseCodePath).getParent();
-        List<String> paths = pkg.getAllCodePaths();
-        String[] splitDependencies = new String[paths.size()];
-        for (int i = 0; i < paths.size(); i++) {
-            File pathFile = new File(paths.get(i));
-            String fileName = pathFile.getName();
-            paths.set(i, fileName);
-
-            // Sanity check that the base paths of the splits are all the same.
-            String basePath = pathFile.getParent();
-            if (!basePath.equals(baseCodePath)) {
-                Slog.wtf(TAG, "Split paths have different base paths: " + basePath + " and " +
-                        baseCodePath);
-            }
-        }
-
-        // If there are no other dependencies, fill in the implicit dependency on the base apk.
-        SparseArray<int[]> dependencies = pkg.applicationInfo.splitDependencies;
-        if (dependencies == null) {
-            for (int i = 1; i < paths.size(); i++) {
-                splitDependencies[i] = paths.get(0);
-            }
-            return splitDependencies;
-        }
-
-        // Fill in the dependencies, skipping the base apk which has no dependencies.
-        for (int i = 1; i < dependencies.size(); i++) {
-            getParentDependencies(dependencies.keyAt(i), paths, dependencies, splitDependencies);
-        }
-
-        return splitDependencies;
-    }
-
-    /**
-     * Recursive method to generate dependencies for a particular split.
-     * The index is a key from the package's splitDependencies.
-     */
-    private String getParentDependencies(int index, List<String> paths,
-            SparseArray<int[]> dependencies, String[] splitDependencies) {
-        // The base apk is always first, and has no dependencies.
-        if (index == 0) {
-            return null;
-        }
-        // Return the result if we've computed the dependencies for this index already.
-        if (splitDependencies[index] != null) {
-            return splitDependencies[index];
-        }
-        // Get the dependencies for the parent of this index and append its path to it.
-        int parent = dependencies.get(index)[0];
-        String parentDependencies =
-                getParentDependencies(parent, paths, dependencies, splitDependencies);
-        String path = parentDependencies == null ? paths.get(parent) :
-                parentDependencies + ":" + paths.get(parent);
-        splitDependencies[index] = path;
-        return path;
-    }
-
-    /**
      * Checks if there is an update on the profile information of the {@code pkg}.
      * If the compiler filter is not profile guided the method returns false.
      *
@@ -608,6 +619,9 @@
         if ((flags & DEXOPT_STORAGE_DE) == DEXOPT_STORAGE_DE) {
             flagsList.add("storage_de");
         }
+        if ((flags & DEXOPT_IDLE_BACKGROUND_JOB) == DEXOPT_IDLE_BACKGROUND_JOB) {
+            flagsList.add("idle_background_job");
+        }
 
         return String.join(",", flagsList);
     }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 62b563a..bf64f64 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -865,7 +865,7 @@
             for (int i = 0; i < mSessions.size(); i++) {
                 final PackageInstallerSession session = mSessions.valueAt(i);
                 if (session.userId == userId) {
-                    result.add(session.generateInfo());
+                    result.add(session.generateInfo(false));
                 }
             }
         }
@@ -883,7 +883,7 @@
                 final PackageInstallerSession session = mSessions.valueAt(i);
                 if (Objects.equals(session.installerPackageName, installerPackageName)
                         && session.userId == userId) {
-                    result.add(session.generateInfo());
+                    result.add(session.generateInfo(false));
                 }
             }
         }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index f111db1..a4fb98d 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -78,7 +78,6 @@
 import com.android.server.pm.PackageInstallerService.PackageInstallObserverAdapter;
 
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -288,6 +287,10 @@
     }
 
     public SessionInfo generateInfo() {
+        return generateInfo(true);
+    }
+
+    public SessionInfo generateInfo(boolean includeIcon) {
         final SessionInfo info = new SessionInfo();
         synchronized (mLock) {
             info.sessionId = sessionId;
@@ -302,7 +305,9 @@
             info.installReason = params.installReason;
             info.sizeBytes = params.sizeBytes;
             info.appPackageName = params.appPackageName;
-            info.appIcon = params.appIcon;
+            if (includeIcon) {
+                info.appIcon = params.appIcon;
+            }
             info.appLabel = params.appLabel;
         }
         return info;
@@ -463,7 +468,7 @@
 
             // TODO: this should delegate to DCS so the system process avoids
             // holding open FDs into containers.
-            final FileDescriptor targetFd = Libcore.os.open(target.getAbsolutePath(),
+            final FileDescriptor targetFd = Os.open(target.getAbsolutePath(),
                     O_CREAT | O_WRONLY, 0644);
             Os.chmod(target.getAbsolutePath(), 0644);
 
@@ -475,7 +480,7 @@
             }
 
             if (offsetBytes > 0) {
-                Libcore.os.lseek(targetFd, offsetBytes, OsConstants.SEEK_SET);
+                Os.lseek(targetFd, offsetBytes, OsConstants.SEEK_SET);
             }
 
             if (PackageInstaller.ENABLE_REVOCABLE_FD) {
@@ -510,7 +515,7 @@
             }
             final File target = new File(resolveStageDir(), name);
 
-            final FileDescriptor targetFd = Libcore.os.open(target.getAbsolutePath(), O_RDONLY, 0);
+            final FileDescriptor targetFd = Os.open(target.getAbsolutePath(), O_RDONLY, 0);
             return new ParcelFileDescriptor(targetFd);
 
         } catch (ErrnoException e) {
@@ -856,15 +861,8 @@
 
                         mResolvedInstructionSets.add(archSubDir.getName());
                         List<File> oatFiles = Arrays.asList(archSubDir.listFiles());
-
-                        // Only add compiled files associated with the base.
-                        // Once b/62269291 is resolved, we can add all compiled files again.
-                        for (File oatFile : oatFiles) {
-                            if (oatFile.getName().equals("base.art")
-                                    || oatFile.getName().equals("base.odex")
-                                    || oatFile.getName().equals("base.vdex")) {
-                                mResolvedInheritedFiles.add(oatFile);
-                            }
+                        if (!oatFiles.isEmpty()) {
+                            mResolvedInheritedFiles.addAll(oatFiles);
                         }
                     }
                 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 9f518c3..93d8894 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -132,6 +132,7 @@
 import android.content.pm.ChangedPackages;
 import android.content.pm.FallbackCategoryProvider;
 import android.content.pm.FeatureInfo;
+import android.content.pm.IDexModuleRegisterCallback;
 import android.content.pm.IOnPermissionsChangeListener;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
@@ -279,6 +280,8 @@
 import com.android.server.pm.Settings.DatabaseVersion;
 import com.android.server.pm.Settings.VersionInfo;
 import com.android.server.pm.dex.DexManager;
+import com.android.server.pm.dex.DexoptOptions;
+import com.android.server.pm.dex.PackageDexUsage;
 import com.android.server.storage.DeviceStorageMonitorInternal;
 
 import dalvik.system.CloseGuard;
@@ -325,6 +328,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -557,8 +561,10 @@
     public static final int REASON_INSTALL = 2;
     public static final int REASON_BACKGROUND_DEXOPT = 3;
     public static final int REASON_AB_OTA = 4;
+    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
+    public static final int REASON_SHARED = 6;
 
-    public static final int REASON_LAST = REASON_AB_OTA;
+    public static final int REASON_LAST = REASON_SHARED;
 
     /** All dangerous permission names in the same order as the events in MetricsEvent */
     private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
@@ -3457,7 +3463,7 @@
         final int N = list.size();
         for (int i = 0; i < N; i++) {
             ResolveInfo info = list.get(i);
-            if (packageName.equals(info.activityInfo.packageName)) {
+            if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
                 return true;
             }
         }
@@ -3996,20 +4002,69 @@
     }
 
     @Override
-    public PermissionInfo getPermissionInfo(String name, int flags) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
+        final int callingUid = Binder.getCallingUid();
+        if (getInstantAppPackageName(callingUid) != null) {
             return null;
         }
         // reader
         synchronized (mPackages) {
             final BasePermission p = mSettings.mPermissions.get(name);
-            if (p != null) {
-                return generatePermissionInfo(p, flags);
+            if (p == null) {
+                return null;
             }
-            return null;
+            // If the caller is an app that targets pre 26 SDK drop protection flags.
+            final PermissionInfo permissionInfo = generatePermissionInfo(p, flags);
+            if (permissionInfo != null) {
+                permissionInfo.protectionLevel = adjustPermissionProtectionFlagsLPr(
+                        permissionInfo.protectionLevel, packageName, callingUid);
+            }
+            return permissionInfo;
         }
     }
 
+    private int adjustPermissionProtectionFlagsLPr(int protectionLevel,
+            String packageName, int uid) {
+        // Signature permission flags area always reported
+        final int protectionLevelMasked = protectionLevel
+                & (PermissionInfo.PROTECTION_NORMAL
+                | PermissionInfo.PROTECTION_DANGEROUS
+                | PermissionInfo.PROTECTION_SIGNATURE);
+        if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
+            return protectionLevel;
+        }
+
+        // System sees all flags.
+        final int appId = UserHandle.getAppId(uid);
+        if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
+                || appId == Process.SHELL_UID) {
+            return protectionLevel;
+        }
+
+        // Normalize package name to handle renamed packages and static libs
+        packageName = resolveInternalPackageNameLPr(packageName,
+                PackageManager.VERSION_CODE_HIGHEST);
+
+        // Apps that target O see flags for all protection levels.
+        final PackageSetting ps = mSettings.mPackages.get(packageName);
+        if (ps == null) {
+            return protectionLevel;
+        }
+        if (ps.appId != appId) {
+            return protectionLevel;
+        }
+
+        final PackageParser.Package pkg = mPackages.get(packageName);
+        if (pkg == null) {
+            return protectionLevel;
+        }
+        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
+            return protectionLevelMasked;
+        }
+
+        return protectionLevel;
+    }
+
     @Override
     public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
             int flags) {
@@ -4228,10 +4283,7 @@
                     volumeUuid);
             final boolean aggressive = (storageFlags
                     & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
-            final boolean defyReserved = (storageFlags
-                    & StorageManager.FLAG_ALLOCATE_DEFY_RESERVED) != 0;
-            final long reservedBytes = (aggressive || defyReserved) ? 0
-                    : storage.getStorageCacheBytes(file);
+            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
 
             // 1. Pre-flight to determine if we have any chance to succeed
             // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
@@ -8891,9 +8943,12 @@
             }
         }
 
-        boolean updatedPkgBetter = false;
+        final boolean isUpdatedPkg = updatedPkg != null;
+        final boolean isUpdatedSystemPkg = isUpdatedPkg
+                && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0;
+        boolean isUpdatedPkgBetter = false;
         // First check if this is a system package that may involve an update
-        if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
+        if (isUpdatedSystemPkg) {
             // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
             // it needs to drop FLAG_PRIVILEGED.
             if (locationIsPrivileged(scanFile)) {
@@ -8937,10 +8992,6 @@
                             updatedChildPkg.versionCode = pkg.mVersionCode;
                         }
                     }
-
-                    throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
-                            + scanFile + " ignored: updated version " + ps.versionCode
-                            + " better than this " + pkg.mVersionCode);
                 } else {
                     // The current app on the system partition is better than
                     // what we have updated to on the data partition; switch
@@ -8967,12 +9018,44 @@
                     synchronized (mPackages) {
                         mSettings.enableSystemPackageLPw(ps.name);
                     }
-                    updatedPkgBetter = true;
+                    isUpdatedPkgBetter = true;
                 }
             }
         }
 
-        if (updatedPkg != null) {
+        String resourcePath = null;
+        String baseResourcePath = null;
+        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !isUpdatedPkgBetter) {
+            if (ps != null && ps.resourcePathString != null) {
+                resourcePath = ps.resourcePathString;
+                baseResourcePath = ps.resourcePathString;
+            } else {
+                // Should not happen at all. Just log an error.
+                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
+            }
+        } else {
+            resourcePath = pkg.codePath;
+            baseResourcePath = pkg.baseCodePath;
+        }
+
+        // Set application objects path explicitly.
+        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
+        pkg.setApplicationInfoCodePath(pkg.codePath);
+        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
+        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
+        pkg.setApplicationInfoResourcePath(resourcePath);
+        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
+        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
+
+        // throw an exception if we have an update to a system application, but, it's not more
+        // recent than the package we've already scanned
+        if (isUpdatedSystemPkg && !isUpdatedPkgBetter) {
+            throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
+                    + scanFile + " ignored: updated version " + ps.versionCode
+                    + " better than this " + pkg.mVersionCode);
+        }
+
+        if (isUpdatedPkg) {
             // An updated system app will not have the PARSE_IS_SYSTEM flag set
             // initially
             policyFlags |= PackageParser.PARSE_IS_SYSTEM;
@@ -8992,7 +9075,7 @@
          * same name installed earlier.
          */
         boolean shouldHideSystemApp = false;
-        if (updatedPkg == null && ps != null
+        if (!isUpdatedPkg && ps != null
                 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
             /*
              * Check to make sure the signatures match first. If they don't,
@@ -9047,31 +9130,6 @@
             }
         }
 
-        // TODO: extend to support forward-locked splits
-        String resourcePath = null;
-        String baseResourcePath = null;
-        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
-            if (ps != null && ps.resourcePathString != null) {
-                resourcePath = ps.resourcePathString;
-                baseResourcePath = ps.resourcePathString;
-            } else {
-                // Should not happen at all. Just log an error.
-                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
-            }
-        } else {
-            resourcePath = pkg.codePath;
-            baseResourcePath = pkg.baseCodePath;
-        }
-
-        // Set application objects path explicitly.
-        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
-        pkg.setApplicationInfoCodePath(pkg.codePath);
-        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
-        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
-        pkg.setApplicationInfoResourcePath(resourcePath);
-        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
-        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
-
         final int userId = ((user == null) ? 0 : user.getIdentifier());
         if (ps != null && ps.getInstantApp(userId)) {
             scanFlags |= SCAN_AS_INSTANT_APP;
@@ -9249,6 +9307,13 @@
         MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
     }
 
+    /*
+     * Return the prebuilt profile path given a package base code path.
+     */
+    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
+        return pkg.baseCodePath + ".prof";
+    }
+
     /**
      * Performs dexopt on the set of packages in {@code packages} and returns an int array
      * containing statistics about the invocation. The array consists of three elements,
@@ -9267,6 +9332,27 @@
         for (PackageParser.Package pkg : pkgs) {
             numberOfPackagesVisited++;
 
+            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
+                // Copy over initial preopt profiles since we won't get any JIT samples for methods
+                // that are already compiled.
+                File profileFile = new File(getPrebuildProfilePath(pkg));
+                // Copy profile if it exists.
+                if (profileFile.exists()) {
+                    try {
+                        // We could also do this lazily before calling dexopt in
+                        // PackageDexOptimizer to prevent this happening on first boot. The issue
+                        // is that we don't have a good way to say "do this only once".
+                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
+                                pkg.applicationInfo.uid, pkg.packageName)) {
+                            Log.e(TAG, "Installer failed to copy system profile!");
+                        }
+                    } catch (Exception e) {
+                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
+                                e);
+                    }
+                }
+            }
+
             if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
                 if (DEBUG_DEXOPT) {
                     Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
@@ -9310,24 +9396,42 @@
             // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
             // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
             // trade-off worth doing to save boot time work.
-            int dexOptStatus = performDexOptTraced(pkg.packageName,
-                    false /* checkProfiles */,
+            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
+            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
+                    pkg.packageName,
                     compilerFilter,
-                    false /* force */,
-                    bootComplete);
-            switch (dexOptStatus) {
-                case PackageDexOptimizer.DEX_OPT_PERFORMED:
-                    numberOfPackagesOptimized++;
-                    break;
-                case PackageDexOptimizer.DEX_OPT_SKIPPED:
-                    numberOfPackagesSkipped++;
-                    break;
-                case PackageDexOptimizer.DEX_OPT_FAILED:
-                    numberOfPackagesFailed++;
-                    break;
-                default:
-                    Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
-                    break;
+                    dexoptFlags));
+
+            boolean secondaryDexOptStatus = true;
+            if (pkg.isSystemApp()) {
+                // Only dexopt shared secondary dex files belonging to system apps to not slow down
+                // too much boot after an OTA.
+                int secondaryDexoptFlags = dexoptFlags |
+                        DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
+                        DexoptOptions.DEXOPT_ONLY_SHARED_DEX;
+                mDexManager.dexoptSecondaryDex(new DexoptOptions(
+                        pkg.packageName,
+                        compilerFilter,
+                        secondaryDexoptFlags));
+            }
+
+            if (secondaryDexOptStatus) {
+                switch (primaryDexOptStaus) {
+                    case PackageDexOptimizer.DEX_OPT_PERFORMED:
+                        numberOfPackagesOptimized++;
+                        break;
+                    case PackageDexOptimizer.DEX_OPT_SKIPPED:
+                        numberOfPackagesSkipped++;
+                        break;
+                    case PackageDexOptimizer.DEX_OPT_FAILED:
+                        numberOfPackagesFailed++;
+                        break;
+                    default:
+                        Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
+                        break;
+                }
+            } else {
+                numberOfPackagesFailed++;
             }
         }
 
@@ -9358,7 +9462,8 @@
     }
 
     @Override
-    public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
+    public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
+            List<String> classPaths, String loaderIsa) {
         int userId = UserHandle.getCallingUserId();
         ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
         if (ai == null) {
@@ -9366,20 +9471,81 @@
                 + loadingPackageName + ", user=" + userId);
             return;
         }
-        mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
+        mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
     }
 
     @Override
-    public boolean performDexOpt(String packageName,
-            boolean checkProfiles, int compileReason, boolean force, boolean bootComplete) {
+    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
+            IDexModuleRegisterCallback callback) {
+        int userId = UserHandle.getCallingUserId();
+        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
+        DexManager.RegisterDexModuleResult result;
+        if (ai == null) {
+            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
+                     " calling user. package=" + packageName + ", user=" + userId);
+            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
+        } else {
+            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
+        }
+
+        if (callback != null) {
+            mHandler.post(() -> {
+                try {
+                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
+                }
+            });
+        }
+    }
+
+    /**
+     * Ask the package manager to perform a dex-opt with the given compiler filter.
+     *
+     * Note: exposed only for the shell command to allow moving packages explicitly to a
+     *       definite state.
+     */
+    @Override
+    public boolean performDexOptMode(String packageName,
+            boolean checkProfiles, String targetCompilerFilter, boolean force,
+            boolean bootComplete, String splitName) {
+        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
+                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
+                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
+        return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter,
+                splitName, flags));
+    }
+
+    /**
+     * Ask the package manager to perform a dex-opt with the given compiler filter on the
+     * secondary dex files belonging to the given package.
+     *
+     * Note: exposed only for the shell command to allow moving packages explicitly to a
+     *       definite state.
+     */
+    @Override
+    public boolean performDexOptSecondary(String packageName, String compilerFilter,
+            boolean force) {
+        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
+                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
+                DexoptOptions.DEXOPT_BOOT_COMPLETE |
+                (force ? DexoptOptions.DEXOPT_FORCE : 0);
+        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
+    }
+
+    /*package*/ boolean performDexOpt(DexoptOptions options) {
         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
             return false;
-        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
+        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
             return false;
         }
-        int dexoptStatus = performDexOptWithStatus(
-              packageName, checkProfiles, compileReason, force, bootComplete);
-        return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
+
+        if (options.isDexoptOnlySecondaryDex()) {
+            return mDexManager.dexoptSecondaryDex(options);
+        } else {
+            int dexoptStatus = performDexOptWithStatus(options);
+            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
+        }
     }
 
     /**
@@ -9388,33 +9554,14 @@
      *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
      *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
      */
-    /* package */ int performDexOptWithStatus(String packageName,
-            boolean checkProfiles, int compileReason, boolean force, boolean bootComplete) {
-        return performDexOptTraced(packageName, checkProfiles,
-                getCompilerFilterForReason(compileReason), force, bootComplete);
+    /* package */ int performDexOptWithStatus(DexoptOptions options) {
+        return performDexOptTraced(options);
     }
 
-    @Override
-    public boolean performDexOptMode(String packageName,
-            boolean checkProfiles, String targetCompilerFilter, boolean force,
-            boolean bootComplete) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return false;
-        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
-            return false;
-        }
-        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
-                targetCompilerFilter, force, bootComplete);
-        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
-    }
-
-    private int performDexOptTraced(String packageName,
-                boolean checkProfiles, String targetCompilerFilter, boolean force,
-                boolean bootComplete) {
+    private int performDexOptTraced(DexoptOptions options) {
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
         try {
-            return performDexOptInternal(packageName, checkProfiles,
-                    targetCompilerFilter, force, bootComplete);
+            return performDexOptInternal(options);
         } finally {
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
@@ -9422,12 +9569,10 @@
 
     // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
     // if the package can now be considered up to date for the given filter.
-    private int performDexOptInternal(String packageName,
-                boolean checkProfiles, String targetCompilerFilter, boolean force,
-                boolean bootComplete) {
+    private int performDexOptInternal(DexoptOptions options) {
         PackageParser.Package p;
         synchronized (mPackages) {
-            p = mPackages.get(packageName);
+            p = mPackages.get(options.getPackageName());
             if (p == null) {
                 // Package could not be found. Report failure.
                 return PackageDexOptimizer.DEX_OPT_FAILED;
@@ -9438,8 +9583,7 @@
         long callingId = Binder.clearCallingIdentity();
         try {
             synchronized (mInstallLock) {
-                return performDexOptInternalWithDependenciesLI(p, checkProfiles,
-                        targetCompilerFilter, force, bootComplete);
+                return performDexOptInternalWithDependenciesLI(p, options);
             }
         } finally {
             Binder.restoreCallingIdentity(callingId);
@@ -9459,12 +9603,11 @@
     }
 
     private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
-            boolean checkProfiles, String targetCompilerFilter,
-            boolean force, boolean bootComplete) {
+            DexoptOptions options) {
         // Select the dex optimizer based on the force parameter.
         // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
         //       allocate an object here.
-        PackageDexOptimizer pdo = force
+        PackageDexOptimizer pdo = options.isForce()
                 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
                 : mPackageDexOptimizer;
 
@@ -9478,39 +9621,19 @@
         Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
         final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
         if (!deps.isEmpty()) {
+            DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
+                    options.getCompilerFilter(), options.getSplitName(),
+                    options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
             for (PackageParser.Package depPackage : deps) {
                 // TODO: Analyze and investigate if we (should) profile libraries.
                 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
-                        false /* checkProfiles */,
-                        targetCompilerFilter,
                         getOrCreateCompilerPackageStats(depPackage),
-                        true /* isUsedByOtherApps */,
-                        bootComplete);
+                    mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
             }
         }
-        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
-                targetCompilerFilter, getOrCreateCompilerPackageStats(p),
-                mDexManager.isUsedByOtherApps(p.packageName), bootComplete);
-    }
-
-    // Performs dexopt on the used secondary dex files belonging to the given package.
-    // Returns true if all dex files were process successfully (which could mean either dexopt or
-    // skip). Returns false if any of the files caused errors.
-    @Override
-    public boolean performDexOptSecondary(String packageName, String compilerFilter,
-            boolean force) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return false;
-        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
-            return false;
-        }
-        mDexManager.reconcileSecondaryDexFiles(packageName);
-        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
-    }
-
-    public boolean performDexOptSecondary(String packageName, int compileReason,
-            boolean force) {
-        return mDexManager.dexoptSecondaryDex(packageName, compileReason, force);
+        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
+                getOrCreateCompilerPackageStats(p),
+                mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
     }
 
     /**
@@ -9636,6 +9759,7 @@
     public void shutdown() {
         mPackageUsage.writeNow(mPackages);
         mCompilerStats.writeNow();
+        mDexManager.writePackageDexUsageNow();
     }
 
     @Override
@@ -9686,10 +9810,11 @@
 
             // Whoever is calling forceDexOpt wants a compiled package.
             // Don't use profiles since that may cause compilation to be skipped.
-            final int res = performDexOptInternalWithDependenciesLI(pkg,
-                    false /* checkProfiles */, getDefaultCompilerFilter(),
-                    true /* force */,
-                    true /* bootComplete */);
+            final int res = performDexOptInternalWithDependenciesLI(
+                    pkg,
+                    new DexoptOptions(packageName,
+                            getDefaultCompilerFilter(),
+                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
 
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
@@ -9846,7 +9971,8 @@
         }
     }
 
-    private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
+    private void addSharedLibraryLPr(Set<String> usesLibraryFiles,
+            SharedLibraryEntry file,
             PackageParser.Package changingLib) {
         if (file.path != null) {
             usesLibraryFiles.add(file.path);
@@ -9875,7 +10001,10 @@
         if (pkg == null) {
             return;
         }
-        ArraySet<String> usesLibraryFiles = null;
+        // The collection used here must maintain the order of addition (so
+        // that libraries are searched in the correct order) and must have no
+        // duplicates.
+        Set<String> usesLibraryFiles = null;
         if (pkg.usesLibraries != null) {
             usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
                     null, null, pkg.packageName, changingLib, true, null);
@@ -9896,10 +10025,10 @@
         }
     }
 
-    private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
+    private Set<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
             @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests,
             @NonNull String packageName, @Nullable PackageParser.Package changingLib,
-            boolean required, @Nullable ArraySet<String> outUsedLibraries)
+            boolean required, @Nullable Set<String> outUsedLibraries)
             throws PackageManagerException {
         final int libCount = requestedLibraries.size();
         for (int i = 0; i < libCount; i++) {
@@ -9944,7 +10073,9 @@
                 }
 
                 if (outUsedLibraries == null) {
-                    outUsedLibraries = new ArraySet<>();
+                    // Use LinkedHashSet to preserve the order of files added to
+                    // usesLibraryFiles while eliminating duplicates.
+                    outUsedLibraries = new LinkedHashSet<>();
                 }
                 addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
             }
@@ -10137,6 +10268,12 @@
 
         assertPackageIsValid(pkg, policyFlags, scanFlags);
 
+        if (Build.IS_DEBUGGABLE &&
+                pkg.isPrivilegedApp() &&
+                SystemProperties.getBoolean("pm.dexopt.priv-apps-oob", false)) {
+            PackageManagerServiceUtils.logPackageHasUncompressedCode(pkg);
+        }
+
         // Initialize package source and resource directories
         final File scanFile = new File(pkg.codePath);
         final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
@@ -16108,7 +16245,7 @@
         }
     }
 
-    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
+    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
         if (!allCodePaths.isEmpty()) {
             if (instructionSets == null) {
                 throw new IllegalStateException("instructionSet == null");
@@ -18127,34 +18264,6 @@
                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
                 }
             }
-
-            // dexopt can take some time to complete, so, for instant apps, we skip this
-            // step during installation. Instead, we'll take extra time the first time the
-            // instant app starts. It's preferred to do it this way to provide continuous
-            // progress to the user instead of mysteriously blocking somewhere in the
-            // middle of running an instant app. The default behaviour can be overridden
-            // via gservices.
-            if (!instantApp || Global.getInt(
-                        mContext.getContentResolver(), Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0) {
-                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
-                // Do not run PackageDexOptimizer through the local performDexOpt
-                // method because `pkg` may not be in `mPackages` yet.
-                //
-                // Also, don't fail application installs if the dexopt step fails.
-                mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
-                        null /* instructionSets */, false /* checkProfiles */,
-                        getCompilerFilterForReason(REASON_INSTALL),
-                        getOrCreateCompilerPackageStats(pkg),
-                        mDexManager.isUsedByOtherApps(pkg.packageName),
-                        true /* bootComplete */);
-                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-            }
-
-            // Notify BackgroundDexOptService that the package has been changed.
-            // If this is an update of a package which used to fail to compile,
-            // BDOS will remove it from its blacklist.
-            // TODO: Layering violation
-            BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
         }
 
         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
@@ -18162,6 +18271,50 @@
             return;
         }
 
+        // Verify if we need to dexopt the app.
+        //
+        // NOTE: it is *important* to call dexopt after doRename which will sync the
+        // package data from PackageParser.Package and its corresponding ApplicationInfo.
+        //
+        // We only need to dexopt if the package meets ALL of the following conditions:
+        //   1) it is not forward locked.
+        //   2) it is not on on an external ASEC container.
+        //   3) it is not an instant app or if it is then dexopt is enabled via gservices.
+        //
+        // Note that we do not dexopt instant apps by default. dexopt can take some time to
+        // complete, so we skip this step during installation. Instead, we'll take extra time
+        // the first time the instant app starts. It's preferred to do it this way to provide
+        // continuous progress to the useur instead of mysteriously blocking somewhere in the
+        // middle of running an instant app. The default behaviour can be overridden
+        // via gservices.
+        final boolean performDexopt = !forwardLocked
+            && !pkg.applicationInfo.isExternalAsec()
+            && (!instantApp || Global.getInt(mContext.getContentResolver(),
+                    Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
+
+        if (performDexopt) {
+            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
+            // Do not run PackageDexOptimizer through the local performDexOpt
+            // method because `pkg` may not be in `mPackages` yet.
+            //
+            // Also, don't fail application installs if the dexopt step fails.
+            DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
+                REASON_INSTALL,
+                DexoptOptions.DEXOPT_BOOT_COMPLETE);
+            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
+                null /* instructionSets */,
+                getOrCreateCompilerPackageStats(pkg),
+                mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
+                dexoptOptions);
+            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+        }
+
+        // Notify BackgroundDexOptService that the package has been changed.
+        // If this is an update of a package which used to fail to compile,
+        // BackgroundDexOptService will remove it from its blacklist.
+        // TODO: Layering violation
+        BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
+
         startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
 
         try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
@@ -18948,8 +19101,9 @@
                 }
             }
             if (removedAppId >= 0) {
-                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras,
-                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, broadcastUsers);
+                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
+                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
+                    null, null, broadcastUsers);
             }
         }
 
@@ -22416,7 +22570,8 @@
         for (PackageParser.Package pkg : packages) {
             ipw.println("[" + pkg.packageName + "]");
             ipw.increaseIndent();
-            mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
+            mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
+                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
             ipw.decreaseIndent();
         }
     }
@@ -23503,7 +23658,10 @@
         @Override
         protected void finalize() throws Throwable {
             try {
-                mCloseGuard.warnIfOpen();
+                if (mCloseGuard != null) {
+                    mCloseGuard.warnIfOpen();
+                }
+
                 close();
             } finally {
                 super.finalize();
@@ -24872,6 +25030,73 @@
             return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
         }
     }
+
+    boolean canHaveOatDir(String packageName) {
+        synchronized (mPackages) {
+            PackageParser.Package p = mPackages.get(packageName);
+            if (p == null) {
+                return false;
+            }
+            return p.canHaveOatDir();
+        }
+    }
+
+    private String getOatDir(PackageParser.Package pkg) {
+        if (!pkg.canHaveOatDir()) {
+            return null;
+        }
+        File codePath = new File(pkg.codePath);
+        if (codePath.isDirectory()) {
+            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
+        }
+        return null;
+    }
+
+    void deleteOatArtifactsOfPackage(String packageName) {
+        final String[] instructionSets;
+        final List<String> codePaths;
+        final String oatDir;
+        final PackageParser.Package pkg;
+        synchronized (mPackages) {
+            pkg = mPackages.get(packageName);
+        }
+        instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
+        codePaths = pkg.getAllCodePaths();
+        oatDir = getOatDir(pkg);
+
+        for (String codePath : codePaths) {
+            for (String isa : instructionSets) {
+                try {
+                    mInstaller.deleteOdex(codePath, isa, oatDir);
+                } catch (InstallerException e) {
+                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
+                }
+            }
+        }
+    }
+
+    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
+        Set<String> unusedPackages = new HashSet<>();
+        long currentTimeInMillis = System.currentTimeMillis();
+        synchronized (mPackages) {
+            for (PackageParser.Package pkg : mPackages.values()) {
+                PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
+                if (ps == null) {
+                    continue;
+                }
+                PackageDexUsage.PackageUseInfo packageUseInfo =
+                      getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
+                if (PackageManagerServiceUtils
+                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
+                                downgradeTimeThresholdMillis, packageUseInfo,
+                                pkg.getLatestPackageUseTimeInMills(),
+                                pkg.getLatestForegroundPackageUseTimeInMills())) {
+                    unusedPackages.add(pkg.packageName);
+                }
+            }
+        }
+        return unusedPackages;
+    }
 }
 
 interface PackageSender {
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
index ec248f5..19b0d9b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
@@ -26,14 +26,19 @@
 public class PackageManagerServiceCompilerMapping {
     // Names for compilation reasons.
     static final String REASON_STRINGS[] = {
-            "first-boot", "boot", "install", "bg-dexopt", "ab-ota"
+            "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "inactive", "shared"
     };
 
+    static final int REASON_SHARED_INDEX = 6;
+
     // Static block to ensure the strings array is of the right length.
     static {
         if (PackageManagerService.REASON_LAST + 1 != REASON_STRINGS.length) {
             throw new IllegalStateException("REASON_STRINGS not correct");
         }
+        if (!"shared".equals(REASON_STRINGS[REASON_SHARED_INDEX])) {
+            throw new IllegalStateException("REASON_STRINGS not correct because of shared index");
+        }
     }
 
     private static String getSystemPropertyName(int reason) {
@@ -52,11 +57,18 @@
                 !DexFile.isValidCompilerFilter(sysPropValue)) {
             throw new IllegalStateException("Value \"" + sysPropValue +"\" not valid "
                     + "(reason " + REASON_STRINGS[reason] + ")");
+        } else if (!isFilterAllowedForReason(reason, sysPropValue)) {
+            throw new IllegalStateException("Value \"" + sysPropValue +"\" not allowed "
+                    + "(reason " + REASON_STRINGS[reason] + ")");
         }
 
         return sysPropValue;
     }
 
+    private static boolean isFilterAllowedForReason(int reason, String filter) {
+        return reason != REASON_SHARED_INDEX || !DexFile.isProfileGuidedCompilerFilter(filter);
+    }
+
     // Check that the properties are set and valid.
     // Note: this is done in a separate method so this class can be statically initialized.
     static void checkProperties() {
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 9feee8c..1e0ce7a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -16,9 +16,14 @@
 
 package com.android.server.pm;
 
+import com.android.server.pm.dex.DexManager;
+import com.android.server.pm.dex.PackageDexUsage;
+
 import static com.android.server.pm.PackageManagerService.DEBUG_DEXOPT;
 import static com.android.server.pm.PackageManagerService.TAG;
 
+import com.android.internal.util.ArrayUtils;
+
 import android.annotation.NonNull;
 import android.app.AppGlobals;
 import android.content.Intent;
@@ -28,8 +33,11 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.system.ErrnoException;
+import android.system.Os;
 import android.util.ArraySet;
 import android.util.Log;
+import android.util.Slog;
+import android.util.jar.StrictJarFile;
 import dalvik.system.VMRuntime;
 import libcore.io.Libcore;
 
@@ -38,9 +46,11 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.function.Predicate;
+import java.util.zip.ZipEntry;
 
 /**
  * Class containing helper methods for the PackageManagerService.
@@ -133,9 +143,11 @@
                 sortTemp, packageManagerService);
 
         // Give priority to apps used by other apps.
+        DexManager dexManager = packageManagerService.getDexManager();
         applyPackageFilter((pkg) ->
-                packageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName), result,
-                remainingPkgs, sortTemp, packageManagerService);
+                dexManager.getPackageUseInfoOrDefault(pkg.packageName)
+                        .isAnyCodePathUsedByOtherApps(),
+                result, remainingPkgs, sortTemp, packageManagerService);
 
         // Filter out packages that aren't recently used, add all remaining apps.
         // TODO: add a property to control this?
@@ -179,12 +191,47 @@
     }
 
     /**
+     * Checks if the package was inactive during since <code>thresholdTimeinMillis</code>.
+     * Package is considered active, if:
+     * 1) It was active in foreground.
+     * 2) It was active in background and also used by other apps.
+     *
+     * If it doesn't have sufficient information about the package, it return <code>false</code>.
+     */
+    static boolean isUnusedSinceTimeInMillis(long firstInstallTime, long currentTimeInMillis,
+            long thresholdTimeinMillis, PackageDexUsage.PackageUseInfo packageUseInfo,
+            long latestPackageUseTimeInMillis, long latestForegroundPackageUseTimeInMillis) {
+
+        if (currentTimeInMillis - firstInstallTime < thresholdTimeinMillis) {
+            return false;
+        }
+
+        // If the app was active in foreground during the threshold period.
+        boolean isActiveInForeground = (currentTimeInMillis
+                - latestForegroundPackageUseTimeInMillis)
+                < thresholdTimeinMillis;
+
+        if (isActiveInForeground) {
+            return false;
+        }
+
+        // If the app was active in background during the threshold period and was used
+        // by other packages.
+        boolean isActiveInBackgroundAndUsedByOtherPackages = ((currentTimeInMillis
+                - latestPackageUseTimeInMillis)
+                < thresholdTimeinMillis)
+                && packageUseInfo.isAnyCodePathUsedByOtherApps();
+
+        return !isActiveInBackgroundAndUsedByOtherPackages;
+    }
+
+    /**
      * Returns the canonicalized path of {@code path} as per {@code realpath(3)}
      * semantics.
      */
     public static String realpath(File path) throws IOException {
         try {
-            return Libcore.os.realpath(path.getAbsolutePath());
+            return Os.realpath(path.getAbsolutePath());
         } catch (ErrnoException ee) {
             throw ee.rethrowAsIOException();
         }
@@ -213,4 +260,59 @@
         }
         return false;
     }
+
+    /**
+     * Checks that the archive located at {@code fileName} has uncompressed dex file and so
+     * files that can be direclty mapped.
+     */
+    public static void logApkHasUncompressedCode(String fileName) {
+        StrictJarFile jarFile = null;
+        try {
+            jarFile = new StrictJarFile(fileName,
+                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
+            Iterator<ZipEntry> it = jarFile.iterator();
+            while (it.hasNext()) {
+                ZipEntry entry = it.next();
+                if (entry.getName().endsWith(".dex")) {
+                    if (entry.getMethod() != ZipEntry.STORED) {
+                        Slog.wtf(TAG, "APK " + fileName + " has compressed dex code " +
+                                entry.getName());
+                    } else if ((entry.getDataOffset() & 0x3) != 0) {
+                        Slog.wtf(TAG, "APK " + fileName + " has unaligned dex code " +
+                                entry.getName());
+                    }
+                } else if (entry.getName().endsWith(".so")) {
+                    if (entry.getMethod() != ZipEntry.STORED) {
+                        Slog.wtf(TAG, "APK " + fileName + " has compressed native code " +
+                                entry.getName());
+                    } else if ((entry.getDataOffset() & (0x1000 - 1)) != 0) {
+                        Slog.wtf(TAG, "APK " + fileName + " has unaligned native code " +
+                                entry.getName());
+                    }
+                }
+            }
+        } catch (IOException ignore) {
+            Slog.wtf(TAG, "Error when parsing APK " + fileName);
+        } finally {
+            try {
+                if (jarFile != null) {
+                    jarFile.close();
+                }
+            } catch (IOException ignore) {}
+        }
+        return;
+    }
+
+    /**
+     * Checks that the APKs in the given package have uncompressed dex file and so
+     * files that can be direclty mapped.
+     */
+    public static void logPackageHasUncompressedCode(PackageParser.Package pkg) {
+        logApkHasUncompressedCode(pkg.baseCodePath);
+        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
+            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
+                logApkHasUncompressedCode(pkg.splitCodePaths[i]);
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index f3a292b..0ec61df 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -365,6 +365,7 @@
         String compilationReason = null;
         String checkProfilesRaw = null;
         boolean secondaryDex = false;
+        String split = null;
 
         String opt;
         while ((opt = getNextOption()) != null) {
@@ -395,6 +396,9 @@
                 case "--secondary-dex":
                     secondaryDex = true;
                     break;
+                case "--split":
+                    split = getNextArgRequired();
+                    break;
                 default:
                     pw.println("Error: Unknown option: " + opt);
                     return 1;
@@ -423,6 +427,16 @@
             return 1;
         }
 
+        if (allPackages && split != null) {
+            pw.println("-a cannot be specified together with --split");
+            return 1;
+        }
+
+        if (secondaryDex && split != null) {
+            pw.println("--secondary-dex cannot be specified together with --split");
+            return 1;
+        }
+
         String targetCompilerFilter;
         if (compilerFilter != null) {
             if (!DexFile.isValidCompilerFilter(compilerFilter)) {
@@ -462,17 +476,23 @@
         }
 
         List<String> failedPackages = new ArrayList<>();
+        int index = 0;
         for (String packageName : packageNames) {
             if (clearProfileData) {
                 mInterface.clearApplicationProfileData(packageName);
             }
 
+            if (allPackages) {
+                pw.println(++index + "/" + packageNames.size() + ": " + packageName);
+                pw.flush();
+            }
+
             boolean result = secondaryDex
                     ? mInterface.performDexOptSecondary(packageName,
                             targetCompilerFilter, forceCompilation)
                     : mInterface.performDexOptMode(packageName,
                             checkProfiles, targetCompilerFilter, forceCompilation,
-                            true /* bootComplete */);
+                            true /* bootComplete */, split);
             if (!result) {
                 failedPackages.add(packageName);
             }
@@ -1018,7 +1038,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            ResolveInfo ri = mInterface.resolveIntent(intent, null, 0, mTargetUser);
+            ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), 0, mTargetUser);
             PrintWriter pw = getOutPrintWriter();
             if (ri == null) {
                 pw.println("No activity found");
@@ -1040,7 +1060,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentActivities(intent, null, 0,
+            List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(), 0,
                     mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
@@ -1074,7 +1094,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentServices(intent, null, 0,
+            List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(), 0,
                     mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
@@ -1108,7 +1128,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, null, 0,
+            List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(), 0,
                     mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
@@ -1609,7 +1629,7 @@
         pw.println("  help");
         pw.println("    Print this help text.");
         pw.println("");
-        pw.println("  compile [-m MODE | -r REASON] [-f] [-c]");
+        pw.println("  compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]");
         pw.println("          [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)");
         pw.println("    Trigger compilation of TARGET-PACKAGE or all packages if \"-a\".");
         pw.println("    Options:");
@@ -1635,6 +1655,7 @@
         pw.println("      --reset: restore package to its post-install state");
         pw.println("      --check-prof (true | false): look at profiles when doing dexopt?");
         pw.println("      --secondary-dex: compile app secondary dex files");
+        pw.println("      --split SPLIT: compile only the given split name");
         pw.println("  bg-dexopt-job");
         pw.println("    Execute the background optimizations immediately.");
         pw.println("    Note that the command only runs the background optimizer logic. It may");
diff --git a/services/core/java/com/android/server/pm/ShortcutDumpFiles.java b/services/core/java/com/android/server/pm/ShortcutDumpFiles.java
new file mode 100644
index 0000000..dc380cc
--- /dev/null
+++ b/services/core/java/com/android/server/pm/ShortcutDumpFiles.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.server.pm;
+
+import android.util.Slog;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.function.Consumer;
+
+public class ShortcutDumpFiles {
+    private static final String TAG = ShortcutService.TAG;
+    private static final boolean DEBUG = ShortcutService.DEBUG;
+    private final ShortcutService mService;
+
+    public ShortcutDumpFiles(ShortcutService service) {
+        mService = service;
+    }
+
+    public boolean save(String filename, Consumer<PrintWriter> dumper) {
+        try {
+            final File directory = mService.getDumpPath();
+            directory.mkdirs();
+            if (!directory.exists()) {
+                Slog.e(TAG, "Failed to create directory: " + directory);
+                return false;
+            }
+
+            final File path = new File(directory, filename);
+
+            if (DEBUG) {
+                Slog.d(TAG, "Dumping to " + path);
+            }
+
+            try (PrintWriter pw = new PrintWriter(new BufferedOutputStream(
+                    new FileOutputStream(path)))) {
+                dumper.accept(pw);
+            }
+            return true;
+        } catch (RuntimeException|IOException e) {
+            Slog.w(TAG, "Failed to create dump file: " + filename, e);
+            return false;
+        }
+    }
+
+    public boolean save(String filename, byte[] utf8bytes) {
+        return save(filename, pw -> pw.println(StandardCharsets.UTF_8.decode(
+                ByteBuffer.wrap(utf8bytes)).toString()));
+    }
+
+    public void dumpAll(PrintWriter pw) {
+        try {
+            final File directory = mService.getDumpPath();
+            final File[] files = directory.listFiles(f -> f.isFile());
+            if (!directory.exists() || ArrayUtils.isEmpty(files)) {
+                pw.print("  No dump files found.");
+                return;
+            }
+            Arrays.sort(files, Comparator.comparing(f -> f.getName()));
+
+            for (File path : files) {
+                pw.print("*** Dumping: ");
+                pw.println(path.getName());
+
+                pw.print("mtime: ");
+                pw.println(ShortcutService.formatTime(path.lastModified()));
+
+                try (BufferedReader reader = new BufferedReader(new InputStreamReader(
+                        new FileInputStream(path)))) {
+                    String line = null;
+                    while ((line = reader.readLine()) != null) {
+                        pw.println(line);
+                    }
+                }
+            }
+        } catch (RuntimeException|IOException e) {
+            Slog.w(TAG, "Failed to print dump files", e);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 103b25d..6f70f4c 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -150,6 +150,10 @@
                 getPackageName(), getPackageUserId());
     }
 
+    public int getShortcutCount() {
+        return mShortcuts.size();
+    }
+
     @Override
     protected void onRestoreBlocked() {
         // Can't restore due to version/signature mismatch.  Remove all shortcuts.
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 6d48a05..7911972 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -181,6 +181,9 @@
     static final String DIRECTORY_PER_USER = "shortcut_service";
 
     @VisibleForTesting
+    static final String DIRECTORY_DUMP = "shortcut_dump";
+
+    @VisibleForTesting
     static final String FILENAME_USER_PACKAGES = "shortcuts.xml";
 
     static final String DIRECTORY_BITMAPS = "bitmaps";
@@ -308,6 +311,7 @@
 
     private final ShortcutRequestPinProcessor mShortcutRequestPinProcessor;
     private final ShortcutBitmapSaver mShortcutBitmapSaver;
+    private final ShortcutDumpFiles mShortcutDumpFiles;
 
     @GuardedBy("mLock")
     final SparseIntArray mUidState = new SparseIntArray();
@@ -429,6 +433,7 @@
 
         mShortcutRequestPinProcessor = new ShortcutRequestPinProcessor(this, mLock);
         mShortcutBitmapSaver = new ShortcutBitmapSaver(this);
+        mShortcutDumpFiles = new ShortcutDumpFiles(this);
 
         if (onlyForPackageManagerApis) {
             return; // Don't do anything further.  For unit tests only.
@@ -3395,6 +3400,16 @@
                 wtf("Can't restore: user " + userId + " is locked or not running");
                 return;
             }
+
+            // Note we print the file timestamps in dumpsys too, but also printing the timestamp
+            // in the files anyway.
+            mShortcutDumpFiles.save("restore-0-start.txt", pw -> {
+                pw.print("Start time: ");
+                dumpCurrentTime(pw);
+                pw.println();
+            });
+            mShortcutDumpFiles.save("restore-1-payload.xml", payload);
+
             // Actually do restore.
             final ShortcutUser restored;
             final ByteArrayInputStream is = new ByteArrayInputStream(payload);
@@ -3404,13 +3419,25 @@
                 Slog.w(TAG, "Restoration failed.", e);
                 return;
             }
+            mShortcutDumpFiles.save("restore-2.txt", this::dumpInner);
+
             getUserShortcutsLocked(userId).mergeRestoredFile(restored);
 
+            mShortcutDumpFiles.save("restore-3.txt", this::dumpInner);
+
             // Rescan all packages to re-publish manifest shortcuts and do other checks.
             rescanUpdatedPackagesLocked(userId,
                     0 // lastScanTime = 0; rescan all packages.
                     );
 
+            mShortcutDumpFiles.save("restore-4.txt", this::dumpInner);
+
+            mShortcutDumpFiles.save("restore-5-finish.txt", pw -> {
+                pw.print("Finish time: ");
+                dumpCurrentTime(pw);
+                pw.println();
+            });
+
             saveUserLocked(userId);
         }
     }
@@ -3425,23 +3452,54 @@
 
     @VisibleForTesting
     void dumpNoCheck(FileDescriptor fd, PrintWriter pw, String[] args) {
+
+        boolean dumpMain = true;
         boolean checkin = false;
         boolean clear = false;
+        boolean dumpUid = false;
+        boolean dumpFiles = false;
+
         if (args != null) {
             for (String arg : args) {
                 if ("-c".equals(arg)) {
                     checkin = true;
+
                 } else if ("--checkin".equals(arg)) {
                     checkin = true;
                     clear = true;
+
+                } else if ("-a".equals(arg) || "--all".equals(arg)) {
+                    dumpUid = true;
+                    dumpFiles = true;
+
+                } else if ("-u".equals(arg) || "--uid".equals(arg)) {
+                    dumpUid = true;
+
+                } else if ("-f".equals(arg) || "--files".equals(arg)) {
+                    dumpFiles = true;
+
+                } else if ("-n".equals(arg) || "--no-main".equals(arg)) {
+                    dumpMain = false;
                 }
             }
         }
 
         if (checkin) {
+            // Other flags are not supported for checkin.
             dumpCheckin(pw, clear);
         } else {
-            dumpInner(pw);
+            if (dumpMain) {
+                dumpInner(pw);
+                pw.println();
+            }
+            if (dumpUid) {
+                dumpUid(pw);
+                pw.println();
+            }
+            if (dumpFiles) {
+                dumpDumpFiles(pw);
+                pw.println();
+            }
         }
     }
 
@@ -3510,9 +3568,12 @@
                 pw.println();
                 mUsers.valueAt(i).dump(pw, "  ");
             }
+        }
+    }
 
-            pw.println();
-            pw.println("  UID state:");
+    private void dumpUid(PrintWriter pw) {
+        synchronized (mLock) {
+            pw.println("** SHORTCUT MANAGER UID STATES (dumpsys shortcut -n -u)");
 
             for (int i = 0; i < mUidState.size(); i++) {
                 final int uid = mUidState.keyAt(i);
@@ -3537,6 +3598,10 @@
         return tobj.format("%Y-%m-%d %H:%M:%S");
     }
 
+    private void dumpCurrentTime(PrintWriter pw) {
+        pw.print(formatTime(injectCurrentTimeMillis()));
+    }
+
     private void dumpStatLS(PrintWriter pw, String prefix, int statId) {
         pw.print(prefix);
         final int count = mCountStats[statId];
@@ -3574,6 +3639,13 @@
         }
     }
 
+    private void dumpDumpFiles(PrintWriter pw) {
+        synchronized (mLock) {
+            pw.println("** SHORTCUT MANAGER FILES (dumpsys shortcut -n -f)");
+            mShortcutDumpFiles.dumpAll(pw);
+        }
+    }
+
     // === Shell support ===
 
     @Override
@@ -3876,6 +3948,10 @@
         return new File(Environment.getDataSystemCeDirectory(userId), DIRECTORY_PER_USER);
     }
 
+    public File getDumpPath() {
+        return new File(injectUserDataPath(UserHandle.USER_SYSTEM), DIRECTORY_DUMP);
+    }
+
     @VisibleForTesting
     boolean injectIsLowRamDevice() {
         return ActivityManager.isLowRamDeviceStatic();
diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java
index 5d4bfa4..2c388c4 100644
--- a/services/core/java/com/android/server/pm/ShortcutUser.java
+++ b/services/core/java/com/android/server/pm/ShortcutUser.java
@@ -25,9 +25,7 @@
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
-import android.util.SparseArray;
 
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
 import com.android.server.pm.ShortcutService.InvalidFileFormatException;
@@ -492,6 +490,10 @@
         // without users interaction it's really not a big deal, so we just clear existing
         // ShortcutLauncher instances in mLaunchers and add all the restored ones here.
 
+        int[] restoredLaunchers = new int[1];
+        int[] restoredPackages = new int[1];
+        int[] restoredShortcuts = new int[1];
+
         mLaunchers.clear();
         restored.forAllLaunchers(sl -> {
             // If the app is already installed and allowbackup = false, then ignore the restored
@@ -501,6 +503,7 @@
                 return;
             }
             addLauncher(sl);
+            restoredLaunchers[0]++;
         });
         restored.forAllPackages(sp -> {
             // If the app is already installed and allowbackup = false, then ignore the restored
@@ -516,10 +519,16 @@
                         + " Existing non-manifeset shortcuts will be overwritten.");
             }
             addPackage(sp);
+            restoredPackages[0]++;
+            restoredShortcuts[0] += sp.getShortcutCount();
         });
         // Empty the launchers and packages in restored to avoid accidentally using them.
         restored.mLaunchers.clear();
         restored.mPackages.clear();
+
+        Slog.i(TAG, "Restored: L=" + restoredLaunchers[0]
+                + " P=" + restoredPackages[0]
+                + " S=" + restoredShortcuts[0]);
     }
 
     public void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index b115422..62f4a30 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -223,6 +223,7 @@
     // Tron counters
     private static final String TRON_GUEST_CREATED = "users_guest_created";
     private static final String TRON_USER_CREATED = "users_user_created";
+    private static final String TRON_DEMO_CREATED = "users_demo_created";
 
     private final Context mContext;
     private final PackageManagerService mPm;
@@ -713,6 +714,19 @@
         }
     }
 
+    @Override
+    public int getProfileParentId(int userHandle) {
+        checkManageUsersPermission("get the profile parent");
+        synchronized (mUsersLock) {
+            UserInfo profileParent = getProfileParentLU(userHandle);
+            if (profileParent == null) {
+                return userHandle;
+            }
+
+            return profileParent.id;
+        }
+    }
+
     private UserInfo getProfileParentLU(int userHandle) {
         UserInfo profile = getUserInfoLU(userHandle);
         if (profile == null) {
@@ -2523,7 +2537,8 @@
             addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
             mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
                     android.Manifest.permission.MANAGE_USERS);
-            MetricsLogger.count(mContext, isGuest ? TRON_GUEST_CREATED : TRON_USER_CREATED, 1);
+            MetricsLogger.count(mContext, isGuest ? TRON_GUEST_CREATED
+                    : (isDemo ? TRON_DEMO_CREATED : TRON_USER_CREATED), 1);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
@@ -3650,7 +3665,7 @@
         public UserInfo createUserEvenWhenDisallowed(String name, int flags) {
             UserInfo user = createUserInternalUnchecked(name, flags, UserHandle.USER_NULL, null);
             // Keep this in sync with UserManager.createUser
-            if (user != null && !user.isAdmin()) {
+            if (user != null && !user.isAdmin() && !user.isDemo()) {
                 setUserRestriction(UserManager.DISALLOW_SMS, true, user.id);
                 setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, true, user.id);
             }
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index c6667a7..a6b05d7 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -31,7 +31,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
-import android.service.persistentdata.PersistentDataBlockManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.util.Log;
@@ -519,22 +518,6 @@
                             android.provider.Settings.Global.SAFE_BOOT_DISALLOWED,
                             newValue ? 1 : 0);
                     break;
-                case UserManager.DISALLOW_FACTORY_RESET:
-                case UserManager.DISALLOW_OEM_UNLOCK:
-                    if (newValue) {
-                        PersistentDataBlockManager manager = (PersistentDataBlockManager) context
-                                .getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
-                        if (manager != null
-                                && manager.getOemUnlockEnabled()
-                                && manager.getFlashLockState()
-                                        != PersistentDataBlockManager.FLASH_LOCK_UNLOCKED) {
-                            // Only disable OEM unlock if the bootloader is locked. If it's already
-                            // unlocked, setting the OEM unlock enabled flag to false has no effect
-                            // (the bootloader would remain unlocked).
-                            manager.setOemUnlockEnabled(false);
-                        }
-                    }
-                    break;
             }
         } finally {
             Binder.restoreCallingIdentity(id);
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index 9b44646..6274754 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -30,17 +30,21 @@
 import com.android.server.pm.Installer;
 import com.android.server.pm.Installer.InstallerException;
 import com.android.server.pm.PackageDexOptimizer;
+import com.android.server.pm.PackageManagerService;
 import com.android.server.pm.PackageManagerServiceUtils;
 import com.android.server.pm.PackageManagerServiceCompilerMapping;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
+import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
 import static com.android.server.pm.dex.PackageDexUsage.PackageUseInfo;
 import static com.android.server.pm.dex.PackageDexUsage.DexUseInfo;
 
@@ -79,6 +83,19 @@
     private static int DEX_SEARCH_FOUND_SPLIT = 2;  // dex file is a split apk
     private static int DEX_SEARCH_FOUND_SECONDARY = 3;  // dex file is a secondary dex
 
+    /**
+     * We do not record packages that have no secondary dex files or that are not used by other
+     * apps. This is an optimization to reduce the amount of data that needs to be written to
+     * disk (apps will not usually be shared so this trims quite a bit the number we record).
+     *
+     * To make this behaviour transparent to the callers which need use information on packages,
+     * DexManager will return this DEFAULT instance from
+     * {@link DexManager#getPackageUseInfoOrDefault}. It has no data about secondary dex files and
+     * is marked as not being used by other apps. This reflects the intended behaviour when we don't
+     * find the package in the underlying data file.
+     */
+    private final static PackageUseInfo DEFAULT_USE_INFO = new PackageUseInfo();
+
     public DexManager(IPackageManager pms, PackageDexOptimizer pdo,
             Installer installer, Object installLock) {
       mPackageCodeLocationsCache = new HashMap<>();
@@ -95,29 +112,55 @@
      * return as fast as possible.
      *
      * @param loadingAppInfo the package performing the load
-     * @param dexPaths the list of dex files being loaded
+     * @param classLoadersNames the names of the class loaders present in the loading chain. The
+     *    list encodes the class loader chain in the natural order. The first class loader has
+     *    the second one as its parent and so on. The dex files present in the class path of the
+     *    first class loader will be recorded in the usage file.
+     * @param classPaths the class paths corresponding to the class loaders names from
+     *     {@param classLoadersNames}. The the first element corresponds to the first class loader
+     *     and so on. A classpath is represented as a list of dex files separated by
+     *     {@code File.pathSeparator}.
+     *     The dex files found in the first class path will be recorded in the usage file.
      * @param loaderIsa the ISA of the app loading the dex files
      * @param loaderUserId the user id which runs the code loading the dex files
      */
-    public void notifyDexLoad(ApplicationInfo loadingAppInfo, List<String> dexPaths,
-            String loaderIsa, int loaderUserId) {
+    public void notifyDexLoad(ApplicationInfo loadingAppInfo, List<String> classLoadersNames,
+            List<String> classPaths, String loaderIsa, int loaderUserId) {
         try {
-            notifyDexLoadInternal(loadingAppInfo, dexPaths, loaderIsa, loaderUserId);
+            notifyDexLoadInternal(loadingAppInfo, classLoadersNames, classPaths, loaderIsa,
+                    loaderUserId);
         } catch (Exception e) {
             Slog.w(TAG, "Exception while notifying dex load for package " +
                     loadingAppInfo.packageName, e);
         }
     }
 
-    private void notifyDexLoadInternal(ApplicationInfo loadingAppInfo, List<String> dexPaths,
-            String loaderIsa, int loaderUserId) {
+    private void notifyDexLoadInternal(ApplicationInfo loadingAppInfo,
+            List<String> classLoaderNames, List<String> classPaths, String loaderIsa,
+            int loaderUserId) {
+        if (classLoaderNames.size() != classPaths.size()) {
+            Slog.wtf(TAG, "Bad call to noitfyDexLoad: args have different size");
+            return;
+        }
+        if (classLoaderNames.isEmpty()) {
+            Slog.wtf(TAG, "Bad call to notifyDexLoad: class loaders list is empty");
+            return;
+        }
         if (!PackageManagerServiceUtils.checkISA(loaderIsa)) {
-            Slog.w(TAG, "Loading dex files " + dexPaths + " in unsupported ISA: " +
+            Slog.w(TAG, "Loading dex files " + classPaths + " in unsupported ISA: " +
                     loaderIsa + "?");
             return;
         }
 
-        for (String dexPath : dexPaths) {
+        // The classpath is represented as a list of dex files separated by File.pathSeparator.
+        String[] dexPathsToRegister = classPaths.get(0).split(File.pathSeparator);
+
+        // Encode the class loader contexts for the dexPathsToRegister.
+        String[] classLoaderContexts = DexoptUtils.processContextForDexLoad(
+                classLoaderNames, classPaths);
+
+        int dexPathIndex = 0;
+        for (String dexPath : dexPathsToRegister) {
             // Find the owning package name.
             DexSearchResult searchResult = getDexPackage(loadingAppInfo, dexPath, loaderUserId);
 
@@ -145,23 +188,25 @@
                 // Record dex file usage. If the current usage is a new pattern (e.g. new secondary,
                 // or UsedBytOtherApps), record will return true and we trigger an async write
                 // to disk to make sure we don't loose the data in case of a reboot.
+
+                // A null classLoaderContexts means that there are unsupported class loaders in the
+                // chain.
+                String classLoaderContext = classLoaderContexts == null
+                        ? PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT
+                        : classLoaderContexts[dexPathIndex];
                 if (mPackageDexUsage.record(searchResult.mOwningPackageName,
-                        dexPath, loaderUserId, loaderIsa, isUsedByOtherApps, primaryOrSplit)) {
+                        dexPath, loaderUserId, loaderIsa, isUsedByOtherApps, primaryOrSplit,
+                        loadingAppInfo.packageName, classLoaderContext)) {
                     mPackageDexUsage.maybeWriteAsync();
                 }
             } else {
-                // This can happen in a few situations:
-                // - bogus dex loads
-                // - recent installs/uninstalls that we didn't detect.
-                // - new installed splits
                 // If we can't find the owner of the dex we simply do not track it. The impact is
                 // that the dex file will not be considered for offline optimizations.
-                // TODO(calin): add hooks for move/uninstall notifications to
-                // capture package moves or obsolete packages.
                 if (DEBUG) {
                     Slog.i(TAG, "Could not find owning package for dex file: " + dexPath);
                 }
             }
+            dexPathIndex++;
         }
     }
 
@@ -267,6 +312,8 @@
 
     private void loadInternal(Map<Integer, List<PackageInfo>> existingPackages) {
         Map<String, Set<Integer>> packageToUsersMap = new HashMap<>();
+        Map<String, Set<String>> packageToCodePaths = new HashMap<>();
+
         // Cache the code locations for the installed packages. This allows for
         // faster lookups (no locks) when finding what package owns the dex file.
         for (Map.Entry<Integer, List<PackageInfo>> entry : existingPackages.entrySet()) {
@@ -276,54 +323,72 @@
                 // Cache the code locations.
                 cachePackageInfo(pi, userId);
 
-                // Cache a map from package name to the set of user ids who installed the package.
+                // Cache two maps:
+                //   - from package name to the set of user ids who installed the package.
+                //   - from package name to the set of code paths.
                 // We will use it to sync the data and remove obsolete entries from
                 // mPackageDexUsage.
                 Set<Integer> users = putIfAbsent(
                         packageToUsersMap, pi.packageName, new HashSet<>());
                 users.add(userId);
+
+                Set<String> codePaths = putIfAbsent(
+                    packageToCodePaths, pi.packageName, new HashSet<>());
+                codePaths.add(pi.applicationInfo.sourceDir);
+                if (pi.applicationInfo.splitSourceDirs != null) {
+                    Collections.addAll(codePaths, pi.applicationInfo.splitSourceDirs);
+                }
             }
         }
 
         mPackageDexUsage.read();
-        mPackageDexUsage.syncData(packageToUsersMap);
+        mPackageDexUsage.syncData(packageToUsersMap, packageToCodePaths);
     }
 
     /**
      * Get the package dex usage for the given package name.
-     * @return the package data or null if there is no data available for this package.
+     * If there is no usage info the method will return a default {@code PackageUseInfo} with
+     * no data about secondary dex files and marked as not being used by other apps.
+     *
+     * Note that no use info means the package was not used or it was used but not by other apps.
+     * Also, note that right now we might prune packages which are not used by other apps.
+     * TODO(calin): maybe we should not (prune) so we can have an accurate view when we try
+     * to access the package use.
      */
-    public PackageUseInfo getPackageUseInfo(String packageName) {
-        return mPackageDexUsage.getPackageUseInfo(packageName);
+    public PackageUseInfo getPackageUseInfoOrDefault(String packageName) {
+        PackageUseInfo useInfo = mPackageDexUsage.getPackageUseInfo(packageName);
+        return useInfo == null ? DEFAULT_USE_INFO : useInfo;
     }
 
     /**
-     * Perform dexopt on the package {@code packageName} secondary dex files.
-     * @return true if all secondary dex files were processed successfully (compiled or skipped
-     *         because they don't need to be compiled)..
+     * Return whether or not the manager has usage information on the give package.
+     *
+     * Note that no use info means the package was not used or it was used but not by other apps.
+     * Also, note that right now we might prune packages which are not used by other apps.
+     * TODO(calin): maybe we should not (prune) so we can have an accurate view when we try
+     * to access the package use.
      */
-    public boolean dexoptSecondaryDex(String packageName, int compilerReason, boolean force) {
-        return dexoptSecondaryDex(packageName,
-                PackageManagerServiceCompilerMapping.getCompilerFilterForReason(compilerReason),
-                force);
+    /*package*/ boolean hasInfoOnPackage(String packageName) {
+        return mPackageDexUsage.getPackageUseInfo(packageName) != null;
     }
 
     /**
-     * Perform dexopt on the package {@code packageName} secondary dex files.
+     * Perform dexopt on with the given {@code options} on the secondary dex files.
      * @return true if all secondary dex files were processed successfully (compiled or skipped
      *         because they don't need to be compiled)..
      */
-    public boolean dexoptSecondaryDex(String packageName, String compilerFilter, boolean force) {
+    public boolean dexoptSecondaryDex(DexoptOptions options) {
         // Select the dex optimizer based on the force parameter.
         // Forced compilation is done through ForcedUpdatePackageDexOptimizer which will adjust
         // the necessary dexopt flags to make sure that compilation is not skipped. This avoid
         // passing the force flag through the multitude of layers.
         // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
         //       allocate an object here.
-        PackageDexOptimizer pdo = force
+        PackageDexOptimizer pdo = options.isForce()
                 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
                 : mPackageDexOptimizer;
-        PackageUseInfo useInfo = getPackageUseInfo(packageName);
+        String packageName = options.getPackageName();
+        PackageUseInfo useInfo = getPackageUseInfoOrDefault(packageName);
         if (useInfo == null || useInfo.getDexUseInfoMap().isEmpty()) {
             if (DEBUG) {
                 Slog.d(TAG, "No secondary dex use for package:" + packageName);
@@ -335,7 +400,8 @@
         for (Map.Entry<String, DexUseInfo> entry : useInfo.getDexUseInfoMap().entrySet()) {
             String dexPath = entry.getKey();
             DexUseInfo dexUseInfo = entry.getValue();
-            PackageInfo pkg = null;
+
+            PackageInfo pkg;
             try {
                 pkg = mPackageManager.getPackageInfo(packageName, /*flags*/0,
                     dexUseInfo.getOwnerUserId());
@@ -354,7 +420,7 @@
             }
 
             int result = pdo.dexOptSecondaryDexPath(pkg.applicationInfo, dexPath,
-                    dexUseInfo.getLoaderIsas(), compilerFilter, dexUseInfo.isUsedByOtherApps());
+                    dexUseInfo, options);
             success = success && (result != PackageDexOptimizer.DEX_OPT_FAILED);
         }
         return success;
@@ -366,7 +432,7 @@
      * deleted, update the internal records and delete any generated oat files.
      */
     public void reconcileSecondaryDexFiles(String packageName) {
-        PackageUseInfo useInfo = getPackageUseInfo(packageName);
+        PackageUseInfo useInfo = getPackageUseInfoOrDefault(packageName);
         if (useInfo == null || useInfo.getDexUseInfoMap().isEmpty()) {
             if (DEBUG) {
                 Slog.d(TAG, "No secondary dex use for package:" + packageName);
@@ -437,6 +503,59 @@
         }
     }
 
+    // TODO(calin): questionable API in the presence of class loaders context. Needs amends as the
+    // compilation happening here will use a pessimistic context.
+    public RegisterDexModuleResult registerDexModule(ApplicationInfo info, String dexPath,
+            boolean isUsedByOtherApps, int userId) {
+        // Find the owning package record.
+        DexSearchResult searchResult = getDexPackage(info, dexPath, userId);
+
+        if (searchResult.mOutcome == DEX_SEARCH_NOT_FOUND) {
+            return new RegisterDexModuleResult(false, "Package not found");
+        }
+        if (!info.packageName.equals(searchResult.mOwningPackageName)) {
+            return new RegisterDexModuleResult(false, "Dex path does not belong to package");
+        }
+        if (searchResult.mOutcome == DEX_SEARCH_FOUND_PRIMARY ||
+                searchResult.mOutcome == DEX_SEARCH_FOUND_SPLIT) {
+            return new RegisterDexModuleResult(false, "Main apks cannot be registered");
+        }
+
+        // We found the package. Now record the usage for all declared ISAs.
+        boolean update = false;
+        for (String isa : getAppDexInstructionSets(info)) {
+            boolean newUpdate = mPackageDexUsage.record(searchResult.mOwningPackageName,
+                    dexPath, userId, isa, isUsedByOtherApps, /*primaryOrSplit*/ false,
+                    searchResult.mOwningPackageName,
+                    PackageDexUsage.UNKNOWN_CLASS_LOADER_CONTEXT);
+            update |= newUpdate;
+        }
+        if (update) {
+            mPackageDexUsage.maybeWriteAsync();
+        }
+
+        // Try to optimize the package according to the install reason.
+        String compilerFilter = PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
+                PackageManagerService.REASON_INSTALL);
+        DexUseInfo dexUseInfo = mPackageDexUsage.getPackageUseInfo(searchResult.mOwningPackageName)
+                .getDexUseInfoMap().get(dexPath);
+
+        DexoptOptions options = new DexoptOptions(info.packageName, compilerFilter, /*flags*/0);
+
+        int result = mPackageDexOptimizer.dexOptSecondaryDexPath(info, dexPath, dexUseInfo,
+                options);
+
+        // If we fail to optimize the package log an error but don't propagate the error
+        // back to the app. The app cannot do much about it and the background job
+        // will rety again when it executes.
+        // TODO(calin): there might be some value to return the error here but it may
+        // cause red herrings since that doesn't mean the app cannot use the module.
+        if (result != PackageDexOptimizer.DEX_OPT_FAILED) {
+            Slog.e(TAG, "Failed to optimize dex module " + dexPath);
+        }
+        return new RegisterDexModuleResult(true, "Dex module registered successfully");
+    }
+
     /**
      * Return all packages that contain records of secondary dex files.
      */
@@ -445,23 +564,6 @@
     }
 
     /**
-     * Return true if the profiling data collected for the given app indicate
-     * that the apps's APK has been loaded by another app.
-     * Note that this returns false for all apps without any collected profiling data.
-    */
-    public boolean isUsedByOtherApps(String packageName) {
-        PackageUseInfo useInfo = getPackageUseInfo(packageName);
-        if (useInfo == null) {
-            // No use info, means the package was not used or it was used but not by other apps.
-            // Note that right now we might prune packages which are not used by other apps.
-            // TODO(calin): maybe we should not (prune) so we can have an accurate view when we try
-            // to access the package use.
-            return false;
-        }
-        return useInfo.isUsedByOtherApps();
-    }
-
-    /**
      * Retrieves the package which owns the given dexPath.
      */
     private DexSearchResult getDexPackage(
@@ -519,6 +621,27 @@
     }
 
     /**
+     * Writes the in-memory package dex usage to disk right away.
+     */
+    public void writePackageDexUsageNow() {
+        mPackageDexUsage.writeNow();
+    }
+
+    public static class RegisterDexModuleResult {
+        public RegisterDexModuleResult() {
+            this(false, null);
+        }
+
+        public RegisterDexModuleResult(boolean success, String message) {
+            this.success = success;
+            this.message = message;
+        }
+
+        public final boolean success;
+        public final String message;
+    }
+
+    /**
      * Convenience class to store the different locations where a package might
      * own code.
      */
@@ -597,6 +720,4 @@
             return mOwningPackageName + "-" + mOutcome;
         }
     }
-
-
 }
diff --git a/services/core/java/com/android/server/pm/dex/DexoptOptions.java b/services/core/java/com/android/server/pm/dex/DexoptOptions.java
new file mode 100644
index 0000000..0966770
--- /dev/null
+++ b/services/core/java/com/android/server/pm/dex/DexoptOptions.java
@@ -0,0 +1,151 @@
+/*
+ * 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.pm.dex;
+
+import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
+
+import android.annotation.Nullable;
+
+/**
+ * Options used for dexopt invocations.
+ */
+public final class DexoptOptions {
+    // When set, the profiles will be checked for updates before calling dexopt. If
+    // the apps profiles didn't update in a meaningful way (decided by the compiler), dexopt
+    // will be skipped.
+    // Currently this only affects the optimization of primary apks. Secondary dex files
+    // will always check the profiles for updates.
+    public static final int DEXOPT_CHECK_FOR_PROFILES_UPDATES = 1 << 0;
+
+    // When set, dexopt will execute unconditionally (even if not needed).
+    public static final int DEXOPT_FORCE = 1 << 1;
+
+    // Whether or not the invocation of dexopt is done after the boot is completed. This is used
+    // in order to adjust the priority of the compilation thread.
+    public static final int DEXOPT_BOOT_COMPLETE = 1 << 2;
+
+    // When set, the dexopt invocation will optimize only the secondary dex files. If false, dexopt
+    // will only consider the primary apk.
+    public static final int DEXOPT_ONLY_SECONDARY_DEX = 1 << 3;
+
+    // When set, dexopt will optimize only dex files that are used by other apps.
+    // Currently, this flag is ignored for primary apks.
+    public static final int DEXOPT_ONLY_SHARED_DEX = 1 << 4;
+
+    // When set, dexopt will attempt to scale down the optimizations previously applied in order
+    // save disk space.
+    public static final int DEXOPT_DOWNGRADE = 1 << 5;
+
+    // When set, dexopt will compile the dex file as a shared library even if it is not actually
+    // used by other apps. This is used to force the compilation or shared libraries declared
+    // with in the manifest with ''uses-library' before we have a chance to detect they are
+    // actually shared at runtime.
+    public static final int DEXOPT_AS_SHARED_LIBRARY = 1 << 6;
+
+    // When set, indicates that dexopt is invoked from the background service.
+    public static final int DEXOPT_IDLE_BACKGROUND_JOB = 1 << 9;
+
+    // The name of package to optimize.
+    private final String mPackageName;
+
+    // The intended target compiler filter. Note that dexopt might adjust the filter before the
+    // execution based on factors like: vmSafeMode and packageUsedByOtherApps.
+    private final String mCompilerFilter;
+
+    // The set of flags for the dexopt options. It's a mix of the DEXOPT_* flags.
+    private final int mFlags;
+
+    // When not null, dexopt will optimize only the split identified by this name.
+    // It only applies for primary apk and it's always null if mOnlySecondaryDex is true.
+    private final String mSplitName;
+
+    public DexoptOptions(String packageName, String compilerFilter, int flags) {
+        this(packageName, compilerFilter, /*splitName*/ null, flags);
+    }
+
+    public DexoptOptions(String packageName, int compilerReason, int flags) {
+        this(packageName, getCompilerFilterForReason(compilerReason), flags);
+    }
+
+    public DexoptOptions(String packageName, String compilerFilter, String splitName, int flags) {
+        int validityMask =
+                DEXOPT_CHECK_FOR_PROFILES_UPDATES |
+                DEXOPT_FORCE |
+                DEXOPT_BOOT_COMPLETE |
+                DEXOPT_ONLY_SECONDARY_DEX |
+                DEXOPT_ONLY_SHARED_DEX |
+                DEXOPT_DOWNGRADE |
+                DEXOPT_AS_SHARED_LIBRARY |
+                DEXOPT_IDLE_BACKGROUND_JOB;
+        if ((flags & (~validityMask)) != 0) {
+            throw new IllegalArgumentException("Invalid flags : " + Integer.toHexString(flags));
+        }
+
+        mPackageName = packageName;
+        mCompilerFilter = compilerFilter;
+        mFlags = flags;
+        mSplitName = splitName;
+    }
+
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    public boolean isCheckForProfileUpdates() {
+        return (mFlags & DEXOPT_CHECK_FOR_PROFILES_UPDATES) != 0;
+    }
+
+    public String getCompilerFilter() {
+        return mCompilerFilter;
+    }
+
+    public boolean isForce() {
+        return (mFlags & DEXOPT_FORCE) != 0;
+    }
+
+    public boolean isBootComplete() {
+        return (mFlags & DEXOPT_BOOT_COMPLETE) != 0;
+    }
+
+    public boolean isDexoptOnlySecondaryDex() {
+        return (mFlags & DEXOPT_ONLY_SECONDARY_DEX) != 0;
+    }
+
+    public boolean isDexoptOnlySharedDex() {
+        return (mFlags & DEXOPT_ONLY_SHARED_DEX) != 0;
+    }
+
+    public boolean isDowngrade() {
+        return (mFlags & DEXOPT_DOWNGRADE) != 0;
+    }
+
+    public boolean isDexoptAsSharedLibrary() {
+        return (mFlags & DEXOPT_AS_SHARED_LIBRARY) != 0;
+    }
+
+    public boolean isDexoptIdleBackgroundJob() {
+        return (mFlags & DEXOPT_IDLE_BACKGROUND_JOB) != 0;
+    }
+
+    public String getSplitName() {
+        return mSplitName;
+    }
+
+    public int getFlags() {
+        return mFlags;
+    }
+}
diff --git a/services/core/java/com/android/server/pm/dex/DexoptUtils.java b/services/core/java/com/android/server/pm/dex/DexoptUtils.java
new file mode 100644
index 0000000..c23b031
--- /dev/null
+++ b/services/core/java/com/android/server/pm/dex/DexoptUtils.java
@@ -0,0 +1,369 @@
+/*
+ * 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.pm.dex;
+
+import android.content.pm.ApplicationInfo;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import com.android.server.pm.PackageDexOptimizer;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public final class DexoptUtils {
+    private static final String TAG = "DexoptUtils";
+
+    private DexoptUtils() {}
+
+    /**
+     * Creates the class loader context dependencies for each of the application code paths.
+     * The returned array contains the class loader contexts that needs to be passed to dexopt in
+     * order to ensure correct optimizations. "Code" paths with no actual code, as specified by
+     * {@param pathsWithCode}, are ignored and will have null as their context in the returned array
+     * (configuration splits are an example of paths without code).
+     *
+     * A class loader context describes how the class loader chain should be built by dex2oat
+     * in order to ensure that classes are resolved during compilation as they would be resolved
+     * at runtime. The context will be encoded in the compiled code. If at runtime the dex file is
+     * loaded in a different context (with a different set of class loaders or a different
+     * classpath), the compiled code will be rejected.
+     *
+     * Note that the class loader context only includes dependencies and not the code path itself.
+     * The contexts are created based on the application split dependency list and
+     * the provided shared libraries.
+     *
+     * All the code paths encoded in the context will be relative to the base directory. This
+     * enables stage compilation where compiler artifacts may be moved around.
+     *
+     * The result is indexed as follows:
+     *   - index 0 contains the context for the base apk
+     *   - index 1 to n contain the context for the splits in the order determined by
+     *     {@code info.getSplitCodePaths()}
+     *
+     * IMPORTANT: keep this logic in sync with the loading code in {@link android.app.LoadedApk}
+     * and pay attention to the way the classpath is created for the non isolated mode in:
+     * {@link android.app.LoadedApk#makePaths(
+     * android.app.ActivityThread, boolean, ApplicationInfo, List, List)}.
+     */
+    public static String[] getClassLoaderContexts(ApplicationInfo info,
+            String[] sharedLibraries, boolean[] pathsWithCode) {
+        // The base class loader context contains only the shared library.
+        String sharedLibrariesClassPath = encodeClasspath(sharedLibraries);
+        String baseApkContextClassLoader = encodeClassLoader(
+                sharedLibrariesClassPath, "dalvik.system.PathClassLoader");
+
+        if (info.getSplitCodePaths() == null) {
+            // The application has no splits.
+            return new String[] {baseApkContextClassLoader};
+        }
+
+        // The application has splits. Compute their class loader contexts.
+
+        // First, cache the relative paths of the splits and do some sanity checks
+        String[] splitRelativeCodePaths = getSplitRelativeCodePaths(info);
+
+        // The splits have an implicit dependency on the base apk.
+        // This means that we have to add the base apk file in addition to the shared libraries.
+        String baseApkName = new File(info.getBaseCodePath()).getName();
+        String sharedLibrariesAndBaseClassPath =
+                encodeClasspath(sharedLibrariesClassPath, baseApkName);
+
+        // The result is stored in classLoaderContexts.
+        // Index 0 is the class loaded context for the base apk.
+        // Index `i` is the class loader context encoding for split `i`.
+        String[] classLoaderContexts = new String[/*base apk*/ 1 + splitRelativeCodePaths.length];
+        classLoaderContexts[0] = pathsWithCode[0] ? baseApkContextClassLoader : null;
+
+        if (!info.requestsIsolatedSplitLoading() || info.splitDependencies == null) {
+            // If the app didn't request for the splits to be loaded in isolation or if it does not
+            // declare inter-split dependencies, then all the splits will be loaded in the base
+            // apk class loader (in the order of their definition).
+            String classpath = sharedLibrariesAndBaseClassPath;
+            for (int i = 1; i < classLoaderContexts.length; i++) {
+                classLoaderContexts[i] = pathsWithCode[i]
+                        ? encodeClassLoader(classpath, "dalvik.system.PathClassLoader") : null;
+                // Note that the splits with no code are not removed from the classpath computation.
+                // i.e. split_n might get the split_n-1 in its classpath dependency even
+                // if split_n-1 has no code.
+                // The splits with no code do not matter for the runtime which ignores
+                // apks without code when doing the classpath checks. As such we could actually
+                // filter them but we don't do it in order to keep consistency with how the apps
+                // are loaded.
+                classpath = encodeClasspath(classpath, splitRelativeCodePaths[i - 1]);
+            }
+        } else {
+            // In case of inter-split dependencies, we need to walk the dependency chain of each
+            // split. We do this recursively and store intermediate results in classLoaderContexts.
+
+            // First, look at the split class loaders and cache their individual contexts (i.e.
+            // the class loader + the name of the split). This is an optimization to avoid
+            // re-computing them during the recursive call.
+            // The cache is stored in splitClassLoaderEncodingCache. The difference between this and
+            // classLoaderContexts is that the later contains the full chain of class loaders for
+            // a given split while splitClassLoaderEncodingCache only contains a single class loader
+            // encoding.
+            String[] splitClassLoaderEncodingCache = new String[splitRelativeCodePaths.length];
+            for (int i = 0; i < splitRelativeCodePaths.length; i++) {
+                splitClassLoaderEncodingCache[i] = encodeClassLoader(splitRelativeCodePaths[i],
+                        "dalvik.system.PathClassLoader");
+            }
+            String splitDependencyOnBase = encodeClassLoader(
+                    sharedLibrariesAndBaseClassPath, "dalvik.system.PathClassLoader");
+            SparseArray<int[]> splitDependencies = info.splitDependencies;
+
+            // Note that not all splits have dependencies (e.g. configuration splits)
+            // The splits without dependencies will have classLoaderContexts[config_split_index]
+            // set to null after this step.
+            for (int i = 1; i < splitDependencies.size(); i++) {
+                int splitIndex = splitDependencies.keyAt(i);
+                if (pathsWithCode[splitIndex]) {
+                    // Compute the class loader context only for the splits with code.
+                    getParentDependencies(splitIndex, splitClassLoaderEncodingCache,
+                            splitDependencies, classLoaderContexts, splitDependencyOnBase);
+                }
+            }
+
+            // At this point classLoaderContexts contains only the parent dependencies.
+            // We also need to add the class loader of the current split which should
+            // come first in the context.
+            for (int i = 1; i < classLoaderContexts.length; i++) {
+                String splitClassLoader = encodeClassLoader("", "dalvik.system.PathClassLoader");
+                if (pathsWithCode[i]) {
+                    // If classLoaderContexts[i] is null it means that the split does not have
+                    // any dependency. In this case its context equals its declared class loader.
+                    classLoaderContexts[i] = classLoaderContexts[i] == null
+                            ? splitClassLoader
+                            : encodeClassLoaderChain(splitClassLoader, classLoaderContexts[i]);
+                } else {
+                    // This is a split without code, it has no dependency and it is not compiled.
+                    // Its context will be null.
+                    classLoaderContexts[i] = null;
+                }
+            }
+        }
+
+        return classLoaderContexts;
+    }
+
+    /**
+     * Recursive method to generate the class loader context dependencies for the split with the
+     * given index. {@param classLoaderContexts} acts as an accumulator. Upton return
+     * {@code classLoaderContexts[index]} will contain the split dependency.
+     * During computation, the method may resolve the dependencies of other splits as it traverses
+     * the entire parent chain. The result will also be stored in {@param classLoaderContexts}.
+     *
+     * Note that {@code index 0} denotes the base apk and it is special handled. When the
+     * recursive call hits {@code index 0} the method returns {@code splitDependencyOnBase}.
+     * {@code classLoaderContexts[0]} is not modified in this method.
+     *
+     * @param index the index of the split (Note that index 0 denotes the base apk)
+     * @param splitClassLoaderEncodingCache the class loader encoding for the individual splits.
+     *    It contains only the split class loader and not the the base. The split
+     *    with {@code index} has its context at {@code splitClassLoaderEncodingCache[index - 1]}.
+     * @param splitDependencies the dependencies for all splits. Note that in this array index 0
+     *    is the base and splits start from index 1.
+     * @param classLoaderContexts the result accumulator. index 0 is the base and never set. Splits
+     *    start at index 1.
+     * @param splitDependencyOnBase the encoding of the implicit split dependency on base.
+     */
+    private static String getParentDependencies(int index, String[] splitClassLoaderEncodingCache,
+            SparseArray<int[]> splitDependencies, String[] classLoaderContexts,
+            String splitDependencyOnBase) {
+        // If we hit the base apk return its custom dependency list which is
+        // sharedLibraries + base.apk
+        if (index == 0) {
+            return splitDependencyOnBase;
+        }
+        // Return the result if we've computed the splitDependencies for this index already.
+        if (classLoaderContexts[index] != null) {
+            return classLoaderContexts[index];
+        }
+        // Get the splitDependencies for the parent of this index and append its path to it.
+        int parent = splitDependencies.get(index)[0];
+        String parentDependencies = getParentDependencies(parent, splitClassLoaderEncodingCache,
+                splitDependencies, classLoaderContexts, splitDependencyOnBase);
+
+        // The split context is: `parent context + parent dependencies context`.
+        String splitContext = (parent == 0) ?
+                parentDependencies :
+                encodeClassLoaderChain(splitClassLoaderEncodingCache[parent - 1], parentDependencies);
+        classLoaderContexts[index] = splitContext;
+        return splitContext;
+    }
+
+    /**
+     * Encodes the shared libraries classpathElements in a format accepted by dexopt.
+     * NOTE: Keep this in sync with the dexopt expectations! Right now that is
+     * a list separated by ':'.
+     */
+    private static String encodeClasspath(String[] classpathElements) {
+        if (classpathElements == null || classpathElements.length == 0) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder();
+        for (String element : classpathElements) {
+            if (sb.length() != 0) {
+                sb.append(":");
+            }
+            sb.append(element);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Adds an element to the encoding of an existing classpath.
+     * {@see PackageDexOptimizer.encodeClasspath(String[])}
+     */
+    private static String encodeClasspath(String classpath, String newElement) {
+        return classpath.isEmpty() ? newElement : (classpath + ":" + newElement);
+    }
+
+    /**
+     * Encodes a single class loader dependency starting from {@param path} and
+     * {@param classLoaderName}.
+     * When classpath is {@link PackageDexOptimizer#SKIP_SHARED_LIBRARY_CHECK}, the method returns
+     * the same. This special property is used only during OTA.
+     * NOTE: Keep this in sync with the dexopt expectations! Right now that is either "PCL[path]"
+     * for a PathClassLoader or "DLC[path]" for a DelegateLastClassLoader.
+     */
+    /*package*/ static String encodeClassLoader(String classpath, String classLoaderName) {
+        if (classpath.equals(PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK)) {
+            return classpath;
+        }
+        String classLoaderDexoptEncoding = classLoaderName;
+        if ("dalvik.system.PathClassLoader".equals(classLoaderName)) {
+            classLoaderDexoptEncoding = "PCL";
+        } else {
+            Slog.wtf(TAG, "Unsupported classLoaderName: " + classLoaderName);
+        }
+        return classLoaderDexoptEncoding + "[" + classpath + "]";
+    }
+
+    /**
+     * Links to dependencies together in a format accepted by dexopt.
+     * For the special case when either of cl1 or cl2 equals
+     * {@link PackageDexOptimizer#SKIP_SHARED_LIBRARY_CHECK}, the method returns the same. This
+     * property is used only during OTA.
+     * NOTE: Keep this in sync with the dexopt expectations! Right now that is a list of split
+     * dependencies {@see encodeClassLoader} separated by ';'.
+     */
+    /*package*/ static String encodeClassLoaderChain(String cl1, String cl2) {
+        if (cl1.equals(PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK) ||
+                cl2.equals(PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK)) {
+            return PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK;
+        }
+        if (cl1.isEmpty()) return cl2;
+        if (cl2.isEmpty()) return cl1;
+        return cl1 + ";" + cl2;
+    }
+
+    /**
+     * Compute the class loader context for the dex files present in the classpath of the first
+     * class loader from the given list (referred in the code as the {@code loadingClassLoader}).
+     * Each dex files gets its own class loader context in the returned array.
+     *
+     * Example:
+     *    If classLoadersNames = {"dalvik.system.DelegateLastClassLoader",
+     *    "dalvik.system.PathClassLoader"} and classPaths = {"foo.dex:bar.dex", "other.dex"}
+     *    The output will be
+     *    {"DLC[];PCL[other.dex]", "DLC[foo.dex];PCL[other.dex]"}
+     *    with "DLC[];PCL[other.dex]" being the context for "foo.dex"
+     *    and "DLC[foo.dex];PCL[other.dex]" the context for "bar.dex".
+     *
+     * If any of the class loaders names is unsupported the method will return null.
+     *
+     * The argument lists must be non empty and of the same size.
+     *
+     * @param classLoadersNames the names of the class loaders present in the loading chain. The
+     *    list encodes the class loader chain in the natural order. The first class loader has
+     *    the second one as its parent and so on.
+     * @param classPaths the class paths for the elements of {@param classLoadersNames}. The
+     *     the first element corresponds to the first class loader and so on. A classpath is
+     *     represented as a list of dex files separated by {@code File.pathSeparator}.
+     *     The return context will be for the dex files found in the first class path.
+     */
+    /*package*/ static String[] processContextForDexLoad(List<String> classLoadersNames,
+            List<String> classPaths) {
+        if (classLoadersNames.size() != classPaths.size()) {
+            throw new IllegalArgumentException(
+                    "The size of the class loader names and the dex paths do not match.");
+        }
+        if (classLoadersNames.isEmpty()) {
+            throw new IllegalArgumentException("Empty classLoadersNames");
+        }
+
+        // Compute the context for the parent class loaders.
+        String parentContext = "";
+        // We know that these lists are actually ArrayLists so getting the elements by index
+        // is fine (they come over binder). Even if something changes we expect the sizes to be
+        // very small and it shouldn't matter much.
+        for (int i = 1; i < classLoadersNames.size(); i++) {
+            if (!isValidClassLoaderName(classLoadersNames.get(i))) {
+                return null;
+            }
+            String classpath = encodeClasspath(classPaths.get(i).split(File.pathSeparator));
+            parentContext = encodeClassLoaderChain(parentContext,
+                    encodeClassLoader(classpath, classLoadersNames.get(i)));
+        }
+
+        // Now compute the class loader context for each dex file from the first classpath.
+        String loadingClassLoader = classLoadersNames.get(0);
+        if (!isValidClassLoaderName(loadingClassLoader)) {
+            return null;
+        }
+        String[] loadedDexPaths = classPaths.get(0).split(File.pathSeparator);
+        String[] loadedDexPathsContext = new String[loadedDexPaths.length];
+        String currentLoadedDexPathClasspath = "";
+        for (int i = 0; i < loadedDexPaths.length; i++) {
+            String dexPath = loadedDexPaths[i];
+            String currentContext = encodeClassLoader(
+                    currentLoadedDexPathClasspath, loadingClassLoader);
+            loadedDexPathsContext[i] = encodeClassLoaderChain(currentContext, parentContext);
+            currentLoadedDexPathClasspath = encodeClasspath(currentLoadedDexPathClasspath, dexPath);
+        }
+        return loadedDexPathsContext;
+    }
+
+    // AOSP-only hack.
+    private static boolean isValidClassLoaderName(String name) {
+        return "dalvik.system.PathClassLoader".equals(name) || "dalvik.system.DexClassLoader".equals(name);
+    }
+
+    /**
+     * Returns the relative paths of the splits declared by the application {@code info}.
+     * Assumes that the application declares a non-null array of splits.
+     */
+    private static String[] getSplitRelativeCodePaths(ApplicationInfo info) {
+        String baseCodePath = new File(info.getBaseCodePath()).getParent();
+        String[] splitCodePaths = info.getSplitCodePaths();
+        String[] splitRelativeCodePaths = new String[splitCodePaths.length];
+        for (int i = 0; i < splitCodePaths.length; i++) {
+            File pathFile = new File(splitCodePaths[i]);
+            splitRelativeCodePaths[i] = pathFile.getName();
+            // Sanity check that the base paths of the splits are all the same.
+            String basePath = pathFile.getParent();
+            if (!basePath.equals(baseCodePath)) {
+                Slog.wtf(TAG, "Split paths have different base paths: " + basePath + " and " +
+                        baseCodePath);
+            }
+        }
+        return splitRelativeCodePaths;
+    }
+}
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 8a66f12..a4a0a54 100644
--- a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
+++ b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
@@ -26,7 +26,6 @@
 import com.android.server.pm.PackageManagerServiceUtils;
 
 import java.io.BufferedReader;
-import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.InputStreamReader;
@@ -35,14 +34,19 @@
 import java.io.Reader;
 import java.io.StringWriter;
 import java.io.Writer;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import dalvik.system.VMRuntime;
 import libcore.io.IoUtils;
+import libcore.util.Objects;
 
 /**
  * Stat file which store usage information about dex files.
@@ -50,19 +54,44 @@
 public class PackageDexUsage extends AbstractStatsBase<Void> {
     private final static String TAG = "PackageDexUsage";
 
-    private final static int PACKAGE_DEX_USAGE_VERSION = 1;
+    // We support previous version to ensure that the usage list remains valid cross OTAs.
+    private final static int PACKAGE_DEX_USAGE_SUPPORTED_VERSION_1 = 1;
+    // Version 2 added:
+    //  - the list of packages that load the dex files
+    //  - class loader contexts for secondary dex files
+    //  - usage for all code paths (including splits)
+    private final static int PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2 = 2;
+
+    private final static int PACKAGE_DEX_USAGE_VERSION = PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2;
+
     private final static String PACKAGE_DEX_USAGE_VERSION_HEADER =
             "PACKAGE_MANAGER__PACKAGE_DEX_USAGE__";
 
     private final static String SPLIT_CHAR = ",";
+    private final static String CODE_PATH_LINE_CHAR = "+";
     private final static String DEX_LINE_CHAR = "#";
+    private final static String LOADING_PACKAGE_CHAR = "@";
+
+    // One of the things we record about dex files is the class loader context that was used to
+    // load them. That should be stable but if it changes we don't keep track of variable contexts.
+    // Instead we put a special marker in the dex usage file in order to recognize the case and
+    // skip optimizations on that dex files.
+    /*package*/ static final String VARIABLE_CLASS_LOADER_CONTEXT =
+            "=VariableClassLoaderContext=";
+    // The marker used for unsupported class loader contexts.
+    /*package*/ static final String UNSUPPORTED_CLASS_LOADER_CONTEXT =
+            "=UnsupportedClassLoaderContext=";
+    // The markers used for unknown class loader contexts. This can happen if the dex file was
+    // recorded in a previous version and we didn't have a chance to update its usage.
+    /*package*/ static final String UNKNOWN_CLASS_LOADER_CONTEXT =
+            "=UnknownClassLoaderContext=";
 
     // Map which structures the information we have on a package.
     // Maps package name to package data (which stores info about UsedByOtherApps and
     // secondary dex files.).
     // Access to this map needs synchronized.
     @GuardedBy("mPackageUseInfoMap")
-    private Map<String, PackageUseInfo> mPackageUseInfoMap;
+    private final Map<String, PackageUseInfo> mPackageUseInfoMap;
 
     public PackageDexUsage() {
         super("package-dex-usage.list", "PackageDexUsage_DiskWriter", /*lock*/ false);
@@ -75,21 +104,28 @@
      * Note this is called when apps load dex files and as such it should return
      * as fast as possible.
      *
-     * @param loadingPackage the package performing the load
+     * @param owningPackageName the package owning the dex path
      * @param dexPath the path of the dex files being loaded
      * @param ownerUserId the user id which runs the code loading the dex files
      * @param loaderIsa the ISA of the app loading the dex files
      * @param isUsedByOtherApps whether or not this dex file was not loaded by its owning package
      * @param primaryOrSplit whether or not the dex file is a primary/split dex. True indicates
      *        the file is either primary or a split. False indicates the file is secondary dex.
+     * @param loadingPackageName the package performing the load. Recorded only if it is different
+     *        than {@param owningPackageName}.
      * @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,
-            String loaderIsa, boolean isUsedByOtherApps, boolean primaryOrSplit) {
+            String loaderIsa, boolean isUsedByOtherApps, boolean primaryOrSplit,
+            String loadingPackageName, String classLoaderContext) {
         if (!PackageManagerServiceUtils.checkISA(loaderIsa)) {
             throw new IllegalArgumentException("loaderIsa " + loaderIsa + " is unsupported");
         }
+        if (classLoaderContext == null) {
+            throw new IllegalArgumentException("Null classLoaderContext");
+        }
+
         synchronized (mPackageUseInfoMap) {
             PackageUseInfo packageUseInfo = mPackageUseInfoMap.get(owningPackageName);
             if (packageUseInfo == null) {
@@ -99,12 +135,16 @@
                     // If we have a primary or a split apk, set isUsedByOtherApps.
                     // We do not need to record the loaderIsa or the owner because we compile
                     // primaries for all users and all ISAs.
-                    packageUseInfo.mIsUsedByOtherApps = isUsedByOtherApps;
+                    packageUseInfo.mergeCodePathUsedByOtherApps(dexPath, isUsedByOtherApps,
+                            owningPackageName, loadingPackageName);
                 } else {
                     // For secondary dex files record the loaderISA and the owner. We'll need
                     // to know under which user to compile and for what ISA.
-                    packageUseInfo.mDexUseInfoMap.put(
-                            dexPath, new DexUseInfo(isUsedByOtherApps, ownerUserId, loaderIsa));
+                    DexUseInfo newData = new DexUseInfo(isUsedByOtherApps, ownerUserId,
+                            classLoaderContext, loaderIsa);
+                    packageUseInfo.mDexUseInfoMap.put(dexPath, newData);
+                    maybeAddLoadingPackage(owningPackageName, loadingPackageName,
+                            newData.mLoadingPackages);
                 }
                 mPackageUseInfoMap.put(owningPackageName, packageUseInfo);
                 return true;
@@ -113,10 +153,14 @@
                 if (primaryOrSplit) {
                     // We have a possible update on the primary apk usage. Merge
                     // isUsedByOtherApps information and return if there was an update.
-                    return packageUseInfo.merge(isUsedByOtherApps);
+                    return packageUseInfo.mergeCodePathUsedByOtherApps(
+                            dexPath, isUsedByOtherApps, owningPackageName, loadingPackageName);
                 } else {
                     DexUseInfo newData = new DexUseInfo(
-                            isUsedByOtherApps, ownerUserId, loaderIsa);
+                            isUsedByOtherApps, ownerUserId, classLoaderContext, loaderIsa);
+                    boolean updateLoadingPackages = maybeAddLoadingPackage(owningPackageName,
+                            loadingPackageName, newData.mLoadingPackages);
+
                     DexUseInfo existingData = packageUseInfo.mDexUseInfoMap.get(dexPath);
                     if (existingData == null) {
                         // It's the first time we see this dex file.
@@ -138,7 +182,7 @@
                         }
                         // Merge the information into the existing data.
                         // Returns true if there was an update.
-                        return existingData.merge(newData);
+                        return existingData.merge(newData) || updateLoadingPackages;
                     }
                 }
             }
@@ -157,8 +201,12 @@
      * Convenience method for async writes which does not force the user to pass a useless
      * (Void) null.
      */
-    public void maybeWriteAsync() {
-      maybeWriteAsync((Void) null);
+    /*package*/ void maybeWriteAsync() {
+      maybeWriteAsync(null);
+    }
+
+    /*package*/ void writeNow() {
+        writeInternal(null);
     }
 
     @Override
@@ -185,16 +233,18 @@
      *
      * file_magic_version
      * package_name_1
+     * +code_path1
+     * @ loading_package_1_1, loading_package_1_2...
+     * +code_path2
+     * @ loading_package_2_1, loading_package_2_2...
      * #dex_file_path_1_1
      * user_1_1, used_by_other_app_1_1, user_isa_1_1_1, user_isa_1_1_2
+     * @ loading_package_1_1_1, loading_package_1_1_2...
+     * class_loader_context_1_1
      * #dex_file_path_1_2
      * user_1_2, used_by_other_app_1_2, user_isa_1_2_1, user_isa_1_2_2
-     * ...
-     * package_name_2
-     * #dex_file_path_2_1
-     * user_2_1, used_by_other_app_2_1, user_isa_2_1_1, user_isa_2_1_2
-     * #dex_file_path_2_2,
-     * user_2_2, used_by_other_app_2_2, user_isa_2_2_1, user_isa_2_2_2
+     * @ loading_package_1_2_1, loading_package_1_2_2...
+     * class_loader_context_1_2
      * ...
     */
     /* package */ void write(Writer out) {
@@ -211,9 +261,16 @@
             // Write the package line.
             String packageName = pEntry.getKey();
             PackageUseInfo packageUseInfo = pEntry.getValue();
+            fpw.println(packageName);
 
-            fpw.println(String.join(SPLIT_CHAR, packageName,
-                    writeBoolean(packageUseInfo.mIsUsedByOtherApps)));
+            // Write the code paths used by other apps.
+            for (Map.Entry<String, Set<String>> codeEntry :
+                    packageUseInfo.mCodePathsUsedByOtherApps.entrySet()) {
+                String codePath = codeEntry.getKey();
+                Set<String> loadingPackages = codeEntry.getValue();
+                fpw.println(CODE_PATH_LINE_CHAR + codePath);
+                fpw.println(LOADING_PACKAGE_CHAR + String.join(SPLIT_CHAR, loadingPackages));
+            }
 
             // Write dex file lines.
             for (Map.Entry<String, DexUseInfo> dEntry : packageUseInfo.mDexUseInfoMap.entrySet()) {
@@ -221,11 +278,14 @@
                 DexUseInfo dexUseInfo = dEntry.getValue();
                 fpw.println(DEX_LINE_CHAR + dexPath);
                 fpw.print(String.join(SPLIT_CHAR, Integer.toString(dexUseInfo.mOwnerUserId),
-                        writeBoolean(dexUseInfo.mIsUsedByOtherApps)));
+                    writeBoolean(dexUseInfo.mIsUsedByOtherApps)));
                 for (String isa : dexUseInfo.mLoaderIsas) {
                     fpw.print(SPLIT_CHAR + isa);
                 }
                 fpw.println();
+                fpw.println(LOADING_PACKAGE_CHAR
+                        + String.join(SPLIT_CHAR, dexUseInfo.mLoadingPackages));
+                fpw.println(dexUseInfo.getClassLoaderContext());
             }
         }
         fpw.flush();
@@ -252,6 +312,7 @@
         BufferedReader in = new BufferedReader(reader);
         // Read header, do version check.
         String versionLine = in.readLine();
+        int version;
         if (versionLine == null) {
             throw new IllegalStateException("No version line found.");
         } else {
@@ -259,48 +320,56 @@
                 // TODO(calin): the caller is responsible to clear the file.
                 throw new IllegalStateException("Invalid version line: " + versionLine);
             }
-            int version = Integer.parseInt(
+            version = Integer.parseInt(
                     versionLine.substring(PACKAGE_DEX_USAGE_VERSION_HEADER.length()));
-            if (version != PACKAGE_DEX_USAGE_VERSION) {
+            if (!isSupportedVersion(version)) {
                 throw new IllegalStateException("Unexpected version: " + version);
             }
         }
 
-        String s = null;
-        String currentPakage = null;
-        PackageUseInfo currentPakageData = null;
+        String line;
+        String currentPackage = null;
+        PackageUseInfo currentPackageData = null;
 
         Set<String> supportedIsas = new HashSet<>();
         for (String abi : Build.SUPPORTED_ABIS) {
             supportedIsas.add(VMRuntime.getInstructionSet(abi));
         }
-        while ((s = in.readLine()) != null) {
-            if (s.startsWith(DEX_LINE_CHAR)) {
+        while ((line = in.readLine()) != null) {
+            if (line.startsWith(DEX_LINE_CHAR)) {
                 // This is the start of the the dex lines.
-                // We expect two lines for each dex entry:
+                // We expect 4 lines for each dex entry:
                 // #dexPaths
+                // @loading_package_1,loading_package_2,...
+                // class_loader_context
                 // onwerUserId,isUsedByOtherApps,isa1,isa2
-                if (currentPakage == null) {
+                if (currentPackage == null) {
                     throw new IllegalStateException(
                         "Malformed PackageDexUsage file. Expected package line before dex line.");
                 }
 
-                // First line is the dex path.
-                String dexPath = s.substring(DEX_LINE_CHAR.length());
-                // Next line is the dex data.
-                s = in.readLine();
-                if (s == null) {
-                    throw new IllegalStateException("Could not fine dexUseInfo for line: " + s);
+                // Line 1 is the dex path.
+                String dexPath = line.substring(DEX_LINE_CHAR.length());
+
+                // Line 2 is the dex data: (userId, isUsedByOtherApps, isa).
+                line = in.readLine();
+                if (line == null) {
+                    throw new IllegalStateException("Could not find dexUseInfo line");
+                }
+                String[] elems = line.split(SPLIT_CHAR);
+                if (elems.length < 3) {
+                    throw new IllegalStateException("Invalid PackageDexUsage line: " + line);
                 }
 
-                // We expect at least 3 elements (isUsedByOtherApps, userId, isa).
-                String[] elems = s.split(SPLIT_CHAR);
-                if (elems.length < 3) {
-                    throw new IllegalStateException("Invalid PackageDexUsage line: " + s);
-                }
+                // In version 2 we added the loading packages and class loader context.
+                Set<String> loadingPackages = maybeReadLoadingPackages(in, version);
+                String classLoaderContext = maybeReadClassLoaderContext(in, version);
+
                 int ownerUserId = Integer.parseInt(elems[0]);
                 boolean isUsedByOtherApps = readBoolean(elems[1]);
-                DexUseInfo dexUseInfo = new DexUseInfo(isUsedByOtherApps, ownerUserId);
+                DexUseInfo dexUseInfo = new DexUseInfo(isUsedByOtherApps, ownerUserId,
+                        classLoaderContext, /*isa*/ null);
+                dexUseInfo.mLoadingPackages.addAll(loadingPackages);
                 for (int i = 2; i < elems.length; i++) {
                     String isa = elems[i];
                     if (supportedIsas.contains(isa)) {
@@ -317,18 +386,37 @@
                             "unsupported isas. dexPath=" + dexPath);
                     continue;
                 }
-                currentPakageData.mDexUseInfoMap.put(dexPath, dexUseInfo);
+                currentPackageData.mDexUseInfoMap.put(dexPath, dexUseInfo);
+            } else if (line.startsWith(CODE_PATH_LINE_CHAR)) {
+                // This is a code path used by other apps line.
+                if (version < PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2) {
+                    throw new IllegalArgumentException("Unexpected code path line when parsing " +
+                            "PackageDexUseData: " + line);
+                }
+
+                // Expects 2 lines:
+                //    +code_paths
+                //    @loading_packages
+                String codePath = line.substring(CODE_PATH_LINE_CHAR.length());
+                Set<String> loadingPackages = maybeReadLoadingPackages(in, version);
+                currentPackageData.mCodePathsUsedByOtherApps.put(codePath, loadingPackages);
             } else {
                 // This is a package line.
-                // We expect it to be: `packageName,isUsedByOtherApps`.
-                String[] elems = s.split(SPLIT_CHAR);
-                if (elems.length != 2) {
-                    throw new IllegalStateException("Invalid PackageDexUsage line: " + s);
+                if (version >= PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2) {
+                    currentPackage = line;
+                    currentPackageData = new PackageUseInfo();
+                } else {
+                    // Old version (<2)
+                    // We expect it to be: `packageName,isUsedByOtherApps`.
+                    String[] elems = line.split(SPLIT_CHAR);
+                    if (elems.length != 2) {
+                        throw new IllegalStateException("Invalid PackageDexUsage line: " + line);
+                    }
+                    currentPackage = elems[0];
+                    currentPackageData = new PackageUseInfo();
+                    currentPackageData.mUsedByOtherAppsBeforeUpgrade = readBoolean(elems[1]);
                 }
-                currentPakage = elems[0];
-                currentPakageData = new PackageUseInfo();
-                currentPakageData.mIsUsedByOtherApps = readBoolean(elems[1]);
-                data.put(currentPakage, currentPakageData);
+                data.put(currentPackage, currentPackageData);
             }
         }
 
@@ -339,9 +427,67 @@
     }
 
     /**
+     * Reads the class loader context encoding from the buffer {@code in} if
+     * {@code version} is at least {PACKAGE_DEX_USAGE_VERSION}.
+     */
+    private String maybeReadClassLoaderContext(BufferedReader in, int version) throws IOException {
+        String context = null;
+        if (version >= PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2) {
+            context = in.readLine();
+            if (context == null) {
+                throw new IllegalStateException("Could not find the classLoaderContext line.");
+            }
+        }
+        // The context might be empty if we didn't have the chance to update it after a version
+        // upgrade. In this case return the special marker so that we recognize this is an unknown
+        // context.
+        return context == null ? UNKNOWN_CLASS_LOADER_CONTEXT : context;
+    }
+
+    /**
+     * Reads the list of loading packages from the buffer {@code in} if
+     * {@code version} is at least {PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2}.
+     */
+    private Set<String> maybeReadLoadingPackages(BufferedReader in, int version)
+            throws IOException {
+        if (version >= PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2) {
+            String line = in.readLine();
+            if (line == null) {
+                throw new IllegalStateException("Could not find the loadingPackages line.");
+            }
+            // We expect that most of the times the list of loading packages will be empty.
+            if (line.length() == LOADING_PACKAGE_CHAR.length()) {
+                return Collections.emptySet();
+            } else {
+                Set<String> result = new HashSet<>();
+                Collections.addAll(result,
+                        line.substring(LOADING_PACKAGE_CHAR.length()).split(SPLIT_CHAR));
+                return result;
+            }
+        } else {
+            return Collections.emptySet();
+        }
+    }
+
+    /**
+     * Utility method which adds {@param loadingPackage} to {@param loadingPackages} only if it's
+     * not equal to {@param owningPackage}
+     */
+    private boolean maybeAddLoadingPackage(String owningPackage, String loadingPackage,
+            Set<String> loadingPackages) {
+        return !owningPackage.equals(loadingPackage) && loadingPackages.add(loadingPackage);
+    }
+
+    private boolean isSupportedVersion(int version) {
+        return version == PACKAGE_DEX_USAGE_SUPPORTED_VERSION_1
+                || version == PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2;
+    }
+
+    /**
      * Syncs the existing data with the set of available packages by removing obsolete entries.
      */
-    public void syncData(Map<String, Set<Integer>> packageToUsersMap) {
+    /*package*/ void syncData(Map<String, Set<Integer>> packageToUsersMap,
+            Map<String, Set<String>> packageToCodePaths) {
         synchronized (mPackageUseInfoMap) {
             Iterator<Map.Entry<String, PackageUseInfo>> pIt =
                     mPackageUseInfoMap.entrySet().iterator();
@@ -365,8 +511,26 @@
                             dIt.remove();
                         }
                     }
-                    if (!packageUseInfo.mIsUsedByOtherApps
-                            && packageUseInfo.mDexUseInfoMap.isEmpty()) {
+
+                    // Sync the code paths.
+                    Set<String> codePaths = packageToCodePaths.get(packageName);
+                    Iterator<Map.Entry<String, Set<String>>> codeIt =
+                        packageUseInfo.mCodePathsUsedByOtherApps.entrySet().iterator();
+                    while (codeIt.hasNext()) {
+                        if (!codePaths.contains(codeIt.next().getKey())) {
+                            codeIt.remove();
+                        }
+                    }
+
+                    // In case the package was marked as used by other apps in a previous version
+                    // propagate the flag to all the code paths.
+                    // See mUsedByOtherAppsBeforeUpgrade docs on why it is important to do it.
+                    if (packageUseInfo.mUsedByOtherAppsBeforeUpgrade) {
+                        for (String codePath : codePaths) {
+                            packageUseInfo.mergeCodePathUsedByOtherApps(codePath, true, null, null);
+                        }
+                    } else if (!packageUseInfo.isAnyCodePathUsedByOtherApps()
+                        && packageUseInfo.mDexUseInfoMap.isEmpty()) {
                         // The package is not used by other apps and we removed all its dex files
                         // records. Remove the entire package record as well.
                         pIt.remove();
@@ -380,14 +544,13 @@
      * Clears the {@code usesByOtherApps} marker for the package {@code packageName}.
      * @return true if the package usage info was updated.
      */
-    public boolean clearUsedByOtherApps(String packageName) {
+    /*package*/ boolean clearUsedByOtherApps(String packageName) {
         synchronized (mPackageUseInfoMap) {
             PackageUseInfo packageUseInfo = mPackageUseInfoMap.get(packageName);
-            if (packageUseInfo == null || !packageUseInfo.mIsUsedByOtherApps) {
+            if (packageUseInfo == null) {
                 return false;
             }
-            packageUseInfo.mIsUsedByOtherApps = false;
-            return true;
+            return packageUseInfo.clearCodePathUsedByOtherApps();
         }
     }
 
@@ -408,7 +571,7 @@
      * @return true if the record was found and actually deleted,
      *         false if the record doesn't exist
      */
-    public boolean removeUserPackage(String packageName, int userId) {
+    /*package*/ boolean removeUserPackage(String packageName, int userId) {
         synchronized (mPackageUseInfoMap) {
             PackageUseInfo packageUseInfo = mPackageUseInfoMap.get(packageName);
             if (packageUseInfo == null) {
@@ -426,7 +589,8 @@
             }
             // If no secondary dex info is left and the package is not used by other apps
             // remove the data since it is now useless.
-            if (packageUseInfo.mDexUseInfoMap.isEmpty() && !packageUseInfo.mIsUsedByOtherApps) {
+            if (packageUseInfo.mDexUseInfoMap.isEmpty()
+                    && !packageUseInfo.isAnyCodePathUsedByOtherApps()) {
                 mPackageUseInfoMap.remove(packageName);
                 updated = true;
             }
@@ -440,7 +604,7 @@
      * @return true if the record was found and actually deleted,
      *         false if the record doesn't exist
      */
-    public boolean removeDexFile(String packageName, String dexFile, int userId) {
+    /*package*/ boolean removeDexFile(String packageName, String dexFile, int userId) {
         synchronized (mPackageUseInfoMap) {
             PackageUseInfo packageUseInfo = mPackageUseInfoMap.get(packageName);
             if (packageUseInfo == null) {
@@ -462,7 +626,7 @@
         return false;
     }
 
-    public PackageUseInfo getPackageUseInfo(String packageName) {
+    /*package*/ PackageUseInfo getPackageUseInfo(String packageName) {
         synchronized (mPackageUseInfoMap) {
             PackageUseInfo useInfo = mPackageUseInfoMap.get(packageName);
             // The useInfo contains a map for secondary dex files which could be modified
@@ -477,7 +641,7 @@
     /**
      * Return all packages that contain records of secondary dex files.
      */
-    public Set<String> getAllPackagesWithSecondaryDexFiles() {
+    /*package*/ Set<String> getAllPackagesWithSecondaryDexFiles() {
         Set<String> packages = new HashSet<>();
         synchronized (mPackageUseInfoMap) {
             for (Map.Entry<String, PackageUseInfo> entry : mPackageUseInfoMap.entrySet()) {
@@ -515,15 +679,6 @@
         throw new IllegalArgumentException("Unknown bool encoding: " + bool);
     }
 
-    private boolean contains(int[] array, int elem) {
-        for (int i = 0; i < array.length; i++) {
-            if (elem == array[i]) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     public String dump() {
         StringWriter sw = new StringWriter();
         write(sw);
@@ -534,39 +689,95 @@
      * Stores data on how a package and its dex files are used.
      */
     public static class PackageUseInfo {
-        // This flag is for the primary and split apks. It is set to true whenever one of them
-        // is loaded by another app.
-        private boolean mIsUsedByOtherApps;
+        // The app's code paths that are used by other apps.
+        // The key is the code path and the value is the set of loading packages.
+        private final Map<String, Set<String>> mCodePathsUsedByOtherApps;
         // Map dex paths to their data (isUsedByOtherApps, owner id, loader isa).
         private final Map<String, DexUseInfo> mDexUseInfoMap;
 
+        // Keeps track of whether or not this package was used by other apps before
+        // we upgraded to VERSION 4 which records the info for each code path separately.
+        // This is unwanted complexity but without it we risk to profile guide compile
+        // something that supposed to be shared. For example:
+        //   1) we determine that chrome is used by another app
+        //   2) we take an OTA which upgrades the way we keep track of usage data
+        //   3) chrome doesn't get used until the background job executes
+        //   4) as part of the backgound job we now think that chrome is not used by others
+        //      and we speed-profile.
+        //   5) as a result the next time someone uses chrome it will extract from apk since
+        //      the compiled code will be private.
+        private boolean mUsedByOtherAppsBeforeUpgrade;
+
         public PackageUseInfo() {
-            mIsUsedByOtherApps = false;
+            mCodePathsUsedByOtherApps = new HashMap<>();
             mDexUseInfoMap = new HashMap<>();
         }
 
         // Creates a deep copy of the `other`.
         public PackageUseInfo(PackageUseInfo other) {
-            mIsUsedByOtherApps = other.mIsUsedByOtherApps;
+            mCodePathsUsedByOtherApps = new HashMap<>();
+            for (Map.Entry<String, Set<String>> e : other.mCodePathsUsedByOtherApps.entrySet()) {
+                mCodePathsUsedByOtherApps.put(e.getKey(), new HashSet<>(e.getValue()));
+            }
+
             mDexUseInfoMap = new HashMap<>();
             for (Map.Entry<String, DexUseInfo> e : other.mDexUseInfoMap.entrySet()) {
                 mDexUseInfoMap.put(e.getKey(), new DexUseInfo(e.getValue()));
             }
         }
 
-        private boolean merge(boolean isUsedByOtherApps) {
-            boolean oldIsUsedByOtherApps = mIsUsedByOtherApps;
-            mIsUsedByOtherApps = mIsUsedByOtherApps || isUsedByOtherApps;
-            return oldIsUsedByOtherApps != this.mIsUsedByOtherApps;
+        private boolean mergeCodePathUsedByOtherApps(String codePath, boolean isUsedByOtherApps,
+                String owningPackageName, String loadingPackage) {
+            if (!isUsedByOtherApps) {
+                // Nothing to update if the the code path is not used by other apps.
+                return false;
+            }
+
+            boolean newCodePath = false;
+            Set<String> loadingPackages = mCodePathsUsedByOtherApps.get(codePath);
+            if (loadingPackages == null) {
+                loadingPackages = new HashSet<>();
+                mCodePathsUsedByOtherApps.put(codePath, loadingPackages);
+                newCodePath = true;
+            }
+            boolean newLoadingPackage = loadingPackage != null
+                    && !loadingPackage.equals(owningPackageName)
+                    && loadingPackages.add(loadingPackage);
+            return newCodePath || newLoadingPackage;
         }
 
-        public boolean isUsedByOtherApps() {
-            return mIsUsedByOtherApps;
+        public boolean isUsedByOtherApps(String codePath) {
+            return mCodePathsUsedByOtherApps.containsKey(codePath);
         }
 
         public Map<String, DexUseInfo> getDexUseInfoMap() {
             return mDexUseInfoMap;
         }
+
+        public Set<String> getLoadingPackages(String codePath) {
+            return mCodePathsUsedByOtherApps.getOrDefault(codePath, null);
+        }
+
+        public boolean isAnyCodePathUsedByOtherApps() {
+            return !mCodePathsUsedByOtherApps.isEmpty();
+        }
+
+        /**
+         * Clears the usedByOtherApps markers from all code paths.
+         * Returns whether or not there was an update.
+         */
+        /*package*/ boolean clearCodePathUsedByOtherApps() {
+            // Update mUsedByOtherAppsBeforeUpgrade as well to be consistent with
+            // the new data. This is not saved to disk so we don't need to return it.
+            mUsedByOtherAppsBeforeUpgrade = true;
+
+            if (mCodePathsUsedByOtherApps.isEmpty()) {
+                return false;
+            } else {
+                mCodePathsUsedByOtherApps.clear();
+                return true;
+            }
+        }
     }
 
     /**
@@ -575,33 +786,59 @@
     public static class DexUseInfo {
         private boolean mIsUsedByOtherApps;
         private final int mOwnerUserId;
+        // The class loader context for the dex file. This encodes the class loader chain
+        // (class loader type + class path) in a format compatible to dex2oat.
+        // See {@code DexoptUtils.processContextForDexLoad}.
+        private String mClassLoaderContext;
+        // The instructions sets of the applications loading the dex file.
         private final Set<String> mLoaderIsas;
+        // Packages who load this dex file.
+        private final Set<String> mLoadingPackages;
 
-        public DexUseInfo(boolean isUsedByOtherApps, int ownerUserId) {
-            this(isUsedByOtherApps, ownerUserId, null);
-        }
-
-        public DexUseInfo(boolean isUsedByOtherApps, int ownerUserId, String loaderIsa) {
+        public DexUseInfo(boolean isUsedByOtherApps, int ownerUserId, String classLoaderContext,
+                String loaderIsa) {
             mIsUsedByOtherApps = isUsedByOtherApps;
             mOwnerUserId = ownerUserId;
+            mClassLoaderContext = classLoaderContext;
             mLoaderIsas = new HashSet<>();
             if (loaderIsa != null) {
                 mLoaderIsas.add(loaderIsa);
             }
+            mLoadingPackages = new HashSet<>();
         }
 
         // Creates a deep copy of the `other`.
         public DexUseInfo(DexUseInfo other) {
             mIsUsedByOtherApps = other.mIsUsedByOtherApps;
             mOwnerUserId = other.mOwnerUserId;
+            mClassLoaderContext = other.mClassLoaderContext;
             mLoaderIsas = new HashSet<>(other.mLoaderIsas);
+            mLoadingPackages = new HashSet<>(other.mLoadingPackages);
         }
 
         private boolean merge(DexUseInfo dexUseInfo) {
             boolean oldIsUsedByOtherApps = mIsUsedByOtherApps;
             mIsUsedByOtherApps = mIsUsedByOtherApps || dexUseInfo.mIsUsedByOtherApps;
             boolean updateIsas = mLoaderIsas.addAll(dexUseInfo.mLoaderIsas);
-            return updateIsas || (oldIsUsedByOtherApps != mIsUsedByOtherApps);
+            boolean updateLoadingPackages = mLoadingPackages.addAll(dexUseInfo.mLoadingPackages);
+
+            String oldClassLoaderContext = mClassLoaderContext;
+            if (UNKNOWN_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext)) {
+                // Can happen if we read a previous version.
+                mClassLoaderContext = dexUseInfo.mClassLoaderContext;
+            } else if (UNSUPPORTED_CLASS_LOADER_CONTEXT.equals(dexUseInfo.mClassLoaderContext)) {
+                // We detected an unsupported context.
+                mClassLoaderContext = UNSUPPORTED_CLASS_LOADER_CONTEXT;
+            } else if (!UNSUPPORTED_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext) &&
+                    !Objects.equal(mClassLoaderContext, dexUseInfo.mClassLoaderContext)) {
+                // We detected a context change.
+                mClassLoaderContext = VARIABLE_CLASS_LOADER_CONTEXT;
+            }
+
+            return updateIsas ||
+                    (oldIsUsedByOtherApps != mIsUsedByOtherApps) ||
+                    updateLoadingPackages
+                    || !Objects.equal(oldClassLoaderContext, mClassLoaderContext);
         }
 
         public boolean isUsedByOtherApps() {
@@ -615,5 +852,25 @@
         public Set<String> getLoaderIsas() {
             return mLoaderIsas;
         }
+
+        public Set<String> getLoadingPackages() {
+            return mLoadingPackages;
+        }
+
+        public String getClassLoaderContext() { return mClassLoaderContext; }
+
+        public boolean isUnsupportedClassLoaderContext() {
+            return UNSUPPORTED_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
+        }
+
+        public boolean isUnknownClassLoaderContext() {
+            // The class loader context may be unknown if we loaded the data from a previous version
+            // which didn't save the context.
+            return UNKNOWN_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
+        }
+
+        public boolean isVariableClassLoaderContext() {
+            return VARIABLE_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/pm/permission/OWNERS b/services/core/java/com/android/server/pm/permission/OWNERS
new file mode 100644
index 0000000..6c8c9b2
--- /dev/null
+++ b/services/core/java/com/android/server/pm/permission/OWNERS
@@ -0,0 +1,7 @@
+per-file DefaultPermissionGrantPolicy.java = bpoiesz@google.com
+per-file DefaultPermissionGrantPolicy.java = fkupolov@google.com
+per-file DefaultPermissionGrantPolicy.java = hackbod@android.com
+per-file DefaultPermissionGrantPolicy.java = jsharkey@android.com
+per-file DefaultPermissionGrantPolicy.java = svetoslavganov@google.com
+per-file DefaultPermissionGrantPolicy.java = toddke@google.com
+per-file DefaultPermissionGrantPolicy.java = yamasani@google.com
diff --git a/services/core/java/com/android/server/policy/AccessibilityShortcutController.java b/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
index 3e5e57b..0b54e5e 100644
--- a/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
+++ b/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
@@ -78,6 +78,7 @@
 
     public AccessibilityShortcutController(Context context, Handler handler, int initialUserId) {
         mContext = context;
+        mUserId = initialUserId;
 
         // Keep track of state of shortcut settings
         final ContentObserver co = new ContentObserver(handler) {
@@ -153,7 +154,7 @@
             // Don't check if haptics are disabled, as we need to alert the user that their
             // way of interacting with the phone may change if they activate the shortcut
             long[] vibePattern = PhoneWindowManager.getLongIntArray(mContext.getResources(),
-                    R.array.config_safeModeDisabledVibePattern);
+                    R.array.config_longPressVibePattern);
             vibrator.vibrate(vibePattern, -1, VIBRATION_ATTRIBUTES);
         }
 
diff --git a/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
index ebb9450..c6ec287 100644
--- a/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
+++ b/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
@@ -19,6 +19,7 @@
 import android.animation.ArgbEvaluator;
 import android.animation.ValueAnimator;
 import android.app.ActivityManager;
+import android.app.ActivityThread;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -79,7 +80,7 @@
     boolean mVrModeEnabled = false;
 
     public ImmersiveModeConfirmation(Context context) {
-        mContext = context;
+        mContext = ActivityThread.currentActivityThread().getSystemUiContext();
         mHandler = new H();
         mShowDelayMs = getNavBarExitDuration() * 3;
         mPanicThresholdMs = context.getResources()
diff --git a/services/core/java/com/android/server/policy/LegacyGlobalActions.java b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
index a71bc4c..14fabc5 100644
--- a/services/core/java/com/android/server/policy/LegacyGlobalActions.java
+++ b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
@@ -228,6 +228,7 @@
                 R.string.global_actions_airplane_mode_on_status,
                 R.string.global_actions_airplane_mode_off_status) {
 
+            @Override
             void onToggle(boolean on) {
                 if (mHasTelephony && Boolean.parseBoolean(
                         SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
@@ -254,10 +255,12 @@
                 }
             }
 
+            @Override
             public boolean showDuringKeyguard() {
                 return true;
             }
 
+            @Override
             public boolean showBeforeProvisioning() {
                 return false;
             }
@@ -457,6 +460,7 @@
             return false;
         }
 
+        @Override
         public boolean showDuringKeyguard() {
             return true;
         }
@@ -616,6 +620,7 @@
                             com.android.internal.R.drawable.ic_menu_cc, icon,
                             (user.name != null ? user.name : "Primary")
                             + (isCurrentUser ? " \u2714" : "")) {
+                        @Override
                         public void onPress() {
                             try {
                                 ActivityManager.getService().switchUser(user.id);
@@ -624,10 +629,12 @@
                             }
                         }
 
+                        @Override
                         public boolean showDuringKeyguard() {
                             return true;
                         }
 
+                        @Override
                         public boolean showBeforeProvisioning() {
                             return false;
                         }
@@ -659,6 +666,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public void onDismiss(DialogInterface dialog) {
         if (mOnDismiss != null) {
             mOnDismiss.run();
@@ -674,6 +682,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public void onClick(DialogInterface dialog, int which) {
         if (!(mAdapter.getItem(which) instanceof SilentModeTriStateAction)) {
             dialog.dismiss();
@@ -689,6 +698,7 @@
      */
     private class MyAdapter extends BaseAdapter {
 
+        @Override
         public int getCount() {
             int count = 0;
 
@@ -716,6 +726,7 @@
             return false;
         }
 
+        @Override
         public Action getItem(int position) {
 
             int filteredPos = 0;
@@ -740,11 +751,12 @@
                     + ", provisioned=" + mDeviceProvisioned);
         }
 
-
+        @Override
         public long getItemId(int position) {
             return position;
         }
 
+        @Override
         public View getView(int position, View convertView, ViewGroup parent) {
             Action action = getItem(position);
             return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
@@ -817,6 +829,7 @@
             mIcon = icon;
         }
 
+        @Override
         public boolean isEnabled() {
             return true;
         }
@@ -825,8 +838,10 @@
             return null;
         }
 
+        @Override
         abstract public void onPress();
 
+        @Override
         public CharSequence getLabelForAccessibility(Context context) {
             if (mMessage != null) {
                 return mMessage;
@@ -835,6 +850,7 @@
             }
         }
 
+        @Override
         public View create(
                 Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
             View v = inflater.inflate(R.layout.global_actions_item, parent, false);
@@ -929,6 +945,7 @@
             return context.getString(mMessageResId);
         }
 
+        @Override
         public View create(Context context, View convertView, ViewGroup parent,
                 LayoutInflater inflater) {
             willCreate();
@@ -963,6 +980,7 @@
             return v;
         }
 
+        @Override
         public final void onPress() {
             if (mState.inTransition()) {
                 Log.w(TAG, "shouldn't be able to toggle when in transition");
@@ -974,6 +992,7 @@
             changeStateFromPress(nowOn);
         }
 
+        @Override
         public boolean isEnabled() {
             return !mState.inTransition();
         }
@@ -1004,6 +1023,7 @@
                     R.string.global_action_silent_mode_off_status);
         }
 
+        @Override
         void onToggle(boolean on) {
             if (on) {
                 mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
@@ -1012,10 +1032,12 @@
             }
         }
 
+        @Override
         public boolean showDuringKeyguard() {
             return true;
         }
 
+        @Override
         public boolean showBeforeProvisioning() {
             return false;
         }
@@ -1050,6 +1072,7 @@
             return null;
         }
 
+        @Override
         public View create(Context context, View convertView, ViewGroup parent,
                 LayoutInflater inflater) {
             View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false);
@@ -1065,17 +1088,21 @@
             return v;
         }
 
+        @Override
         public void onPress() {
         }
 
+        @Override
         public boolean showDuringKeyguard() {
             return true;
         }
 
+        @Override
         public boolean showBeforeProvisioning() {
             return false;
         }
 
+        @Override
         public boolean isEnabled() {
             return true;
         }
@@ -1083,6 +1110,7 @@
         void willCreate() {
         }
 
+        @Override
         public void onClick(View v) {
             if (!(v.getTag() instanceof Integer)) return;
 
@@ -1093,6 +1121,7 @@
     }
 
     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
@@ -1146,6 +1175,7 @@
     private static final int DIALOG_DISMISS_DELAY = 300; // ms
 
     private Handler mHandler = new Handler() {
+        @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
             case MESSAGE_DISMISS:
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 8112f99..ae78d7c 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -358,10 +358,6 @@
     private static final String SYSUI_SCREENSHOT_ERROR_RECEIVER =
             "com.android.systemui.screenshot.ScreenshotServiceErrorReceiver";
 
-    private static final int NAV_BAR_BOTTOM = 0;
-    private static final int NAV_BAR_RIGHT = 1;
-    private static final int NAV_BAR_LEFT = 2;
-
     /**
      * Keyguard stuff
      */
@@ -432,27 +428,12 @@
     // Vibrator pattern for haptic feedback of a long press.
     long[] mLongPressVibePattern;
 
-    // Vibrator pattern for haptic feedback of virtual key press.
-    long[] mVirtualKeyVibePattern;
-
-    // Vibrator pattern for a short vibration.
-    long[] mKeyboardTapVibePattern;
-
-    // Vibrator pattern for a short vibration when tapping on an hour/minute tick of a Clock.
-    long[] mClockTickVibePattern;
-
     // Vibrator pattern for a short vibration when tapping on a day/month/year date of a Calendar.
     long[] mCalendarDateVibePattern;
 
-    // Vibrator pattern for haptic feedback during boot when safe mode is disabled.
-    long[] mSafeModeDisabledVibePattern;
-
     // Vibrator pattern for haptic feedback during boot when safe mode is enabled.
     long[] mSafeModeEnabledVibePattern;
 
-    // Vibrator pattern for haptic feedback of a context click.
-    long[] mContextClickVibePattern;
-
     /** If true, hitting shift & menu will broadcast Intent.ACTION_BUG_REPORT */
     boolean mEnableShiftMenuBugReports = false;
 
@@ -515,6 +496,7 @@
     volatile boolean mEndCallKeyHandled;
     volatile boolean mCameraGestureTriggeredDuringGoingToSleep;
     volatile boolean mGoingToSleep;
+    volatile boolean mRequestedOrGoingToSleep;
     volatile boolean mRecentsVisible;
     volatile boolean mPictureInPictureVisible;
     // Written by vr manager thread, only read in this class.
@@ -575,7 +557,7 @@
     int mPanicPressOnBackBehavior;
     int mShortPressOnSleepBehavior;
     int mShortPressWindowBehavior;
-    boolean mAwake;
+    volatile boolean mAwake;
     boolean mScreenOnEarly;
     boolean mScreenOnFully;
     ScreenOnListener mScreenOnListener;
@@ -835,6 +817,7 @@
     private static final int MSG_BUGREPORT_TV = 22;
     private static final int MSG_ACCESSIBILITY_TV = 23;
     private static final int MSG_DISPATCH_BACK_KEY_TO_AUTOFILL = 24;
+    private static final int MSG_SYSTEM_KEY_PRESS = 25;
 
     private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
     private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
@@ -924,6 +907,9 @@
                 case MSG_DISPATCH_BACK_KEY_TO_AUTOFILL:
                     mAutofillManagerInternal.onBackKeyPressed();
                     break;
+                case MSG_SYSTEM_KEY_PRESS:
+                    sendSystemKeyToStatusBar(msg.arg1);
+                    break;
             }
         }
     }
@@ -1289,11 +1275,14 @@
         if (gestureService != null) {
             gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive,
                     mTmpBoolean);
-            if (mTmpBoolean.value && mGoingToSleep) {
+            if (mTmpBoolean.value && mRequestedOrGoingToSleep) {
                 mCameraGestureTriggeredDuringGoingToSleep = true;
             }
         }
 
+        // Inform the StatusBar; but do not allow it to consume the event.
+        sendSystemKeyToStatusBarAsync(event.getKeyCode());
+
         // If the power key has still not yet been handled, then detect short
         // press, long press, or multi press and decide what to do.
         mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered
@@ -1348,7 +1337,7 @@
                 Message msg = mHandler.obtainMessage(MSG_POWER_DELAYED_PRESS,
                         interactive ? 1 : 0, mPowerKeyPressCounter, eventTime);
                 msg.setAsynchronous(true);
-                mHandler.sendMessageDelayed(msg, ViewConfiguration.getDoubleTapTimeout());
+                mHandler.sendMessageDelayed(msg, ViewConfiguration.getMultiPressTimeout());
                 return;
             }
 
@@ -1414,17 +1403,14 @@
                 case SHORT_PRESS_POWER_NOTHING:
                     break;
                 case SHORT_PRESS_POWER_GO_TO_SLEEP:
-                    mPowerManager.goToSleep(eventTime,
-                            PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
+                    goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
                     break;
                 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
-                    mPowerManager.goToSleep(eventTime,
-                            PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
+                    goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
                             PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
                     break;
                 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
-                    mPowerManager.goToSleep(eventTime,
-                            PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
+                    goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
                             PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
                     launchHomeFromHotKey();
                     break;
@@ -1449,6 +1435,11 @@
         }
     }
 
+    private void goToSleep(long eventTime, int reason, int flags) {
+        mRequestedOrGoingToSleep = true;
+        mPowerManager.goToSleep(eventTime, reason, flags);
+    }
+
     private void shortPressPowerGoHome() {
         launchHomeFromHotKey(true /* awakenFromDreams */, false /*respectKeyguard*/);
         if (isKeyguardShowingAndNotOccluded()) {
@@ -1481,8 +1472,7 @@
                             Settings.Global.THEATER_MODE_ON, 1);
 
                     if (mGoToSleepOnButtonPressTheaterMode && interactive) {
-                        mPowerManager.goToSleep(eventTime,
-                                PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
+                        goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
                     }
                 }
                 break;
@@ -1565,8 +1555,7 @@
             case SHORT_PRESS_SLEEP_GO_TO_SLEEP:
             case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME:
                 Slog.i(TAG, "sleepRelease() calling goToSleep(GO_TO_SLEEP_REASON_SLEEP_BUTTON)");
-                mPowerManager.goToSleep(eventTime,
-                       PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0);
+                goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0);
                 break;
         }
     }
@@ -1689,8 +1678,17 @@
     }
 
     boolean isUserSetupComplete() {
-        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+        boolean isSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                 Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
+        if (mHasFeatureLeanback) {
+            isSetupComplete &= isTvUserSetupComplete();
+        }
+        return isSetupComplete;
+    }
+
+    private boolean isTvUserSetupComplete() {
+        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.TV_USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
     }
 
     private void handleShortPressOnHome() {
@@ -2071,20 +2069,10 @@
         mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
         mLongPressVibePattern = getLongIntArray(mContext.getResources(),
                 com.android.internal.R.array.config_longPressVibePattern);
-        mVirtualKeyVibePattern = getLongIntArray(mContext.getResources(),
-                com.android.internal.R.array.config_virtualKeyVibePattern);
-        mKeyboardTapVibePattern = getLongIntArray(mContext.getResources(),
-                com.android.internal.R.array.config_keyboardTapVibePattern);
-        mClockTickVibePattern = getLongIntArray(mContext.getResources(),
-                com.android.internal.R.array.config_clockTickVibePattern);
         mCalendarDateVibePattern = getLongIntArray(mContext.getResources(),
                 com.android.internal.R.array.config_calendarDateVibePattern);
-        mSafeModeDisabledVibePattern = getLongIntArray(mContext.getResources(),
-                com.android.internal.R.array.config_safeModeDisabledVibePattern);
         mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(),
                 com.android.internal.R.array.config_safeModeEnabledVibePattern);
-        mContextClickVibePattern = getLongIntArray(mContext.getResources(),
-                com.android.internal.R.array.config_contextClickVibePattern);
 
         mScreenshotChordEnabled = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_enableScreenshotChord);
@@ -3173,10 +3161,18 @@
 
     @Override
     public void selectRotationAnimationLw(int anim[]) {
+        // If the screen is off or non-interactive, force a jumpcut.
+        final boolean forceJumpcut = !mScreenOnFully || !okToAnimate();
         if (PRINT_ANIM) Slog.i(TAG, "selectRotationAnimation mTopFullscreen="
                 + mTopFullscreenOpaqueWindowState + " rotationAnimation="
                 + (mTopFullscreenOpaqueWindowState == null ?
-                        "0" : mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation));
+                        "0" : mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation)
+                + " forceJumpcut=" + forceJumpcut);
+        if (forceJumpcut) {
+            anim[0] = R.anim.rotation_animation_jump_exit;
+            anim[1] = R.anim.rotation_animation_enter;
+            return;
+        }
         if (mTopFullscreenOpaqueWindowState != null) {
             int animationHint = mTopFullscreenOpaqueWindowState.getRotationAnimationHint();
             if (animationHint < 0 && mTopIsFullscreen) {
@@ -4189,7 +4185,7 @@
         }
 
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             boolean handled = false;
             try {
                 if (event instanceof MotionEvent
@@ -5059,17 +5055,27 @@
                 // A window that has requested to fill the entire screen just
                 // gets everything, period.
                 if (attrs.type == TYPE_STATUS_BAR_PANEL
-                        || attrs.type == TYPE_STATUS_BAR_SUB_PANEL
-                        || attrs.type == TYPE_VOLUME_OVERLAY) {
+                        || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) {
                     pf.left = df.left = of.left = cf.left = hasNavBar
                             ? mDockLeft : mUnrestrictedScreenLeft;
                     pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop;
                     pf.right = df.right = of.right = cf.right = hasNavBar
-                                        ? mRestrictedScreenLeft+mRestrictedScreenWidth
-                                        : mUnrestrictedScreenLeft + mUnrestrictedScreenWidth;
+                            ? mRestrictedScreenLeft + mRestrictedScreenWidth
+                            : mUnrestrictedScreenLeft + mUnrestrictedScreenWidth;
                     pf.bottom = df.bottom = of.bottom = cf.bottom = hasNavBar
-                                          ? mRestrictedScreenTop+mRestrictedScreenHeight
-                                          : mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
+                            ? mRestrictedScreenTop + mRestrictedScreenHeight
+                            : mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
+                    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));
+                } else if (attrs.type == TYPE_VOLUME_OVERLAY) {
+                    // Volume overlay covers everything, including the status and navbar
+                    pf.left = df.left = of.left = cf.left = mUnrestrictedScreenLeft;
+                    pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop;
+                    pf.right = df.right = of.right = cf.right =
+                            mUnrestrictedScreenLeft + mUnrestrictedScreenWidth;
+                    pf.bottom = df.bottom = of.bottom = cf.bottom =
+                            mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
                     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));
@@ -5404,7 +5410,7 @@
             // represent should be hidden or if we should hide the lockscreen. For attached app
             // windows we defer the decision to the window it is attached to.
             if (appWindow && attached == null) {
-                if (isFullscreen(attrs) && StackId.normallyFullscreenWindows(stackId)) {
+                if (attrs.isFullscreen() && StackId.normallyFullscreenWindows(stackId)) {
                     if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
                     mTopFullscreenOpaqueWindowState = win;
                     if (mTopFullscreenOpaqueOrDimmingWindowState == null) {
@@ -5443,7 +5449,7 @@
         // separately, because both the "real fullscreen" opaque window and the one for the docked
         // stack can control View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.
         if (mTopDockedOpaqueWindowState == null && affectsSystemUi && appWindow && attached == null
-                && isFullscreen(attrs) && stackId == DOCKED_STACK_ID) {
+                && attrs.isFullscreen() && stackId == DOCKED_STACK_ID) {
             mTopDockedOpaqueWindowState = win;
             if (mTopDockedOpaqueOrDimmingWindowState == null) {
                 mTopDockedOpaqueOrDimmingWindowState = win;
@@ -5468,12 +5474,6 @@
         }
     }
 
-    private boolean isFullscreen(WindowManager.LayoutParams attrs) {
-        return attrs.x == 0 && attrs.y == 0
-                && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
-                && attrs.height == WindowManager.LayoutParams.MATCH_PARENT;
-    }
-
     /** {@inheritDoc} */
     @Override
     public int finishPostLayoutPolicyLw() {
@@ -5980,6 +5980,8 @@
                     }
                 }
                 if (down) {
+                    sendSystemKeyToStatusBarAsync(event.getKeyCode());
+
                     TelecomManager telecomManager = getTelecommService();
                     if (telecomManager != null) {
                         if (telecomManager.isRinging()) {
@@ -6017,7 +6019,6 @@
                                 event, AudioManager.USE_DEFAULT_STREAM_TYPE, false);
                         break;
                     }
-
                 }
                 if (mUseTvRouting || mHandleVolumeKeysInWM) {
                     // Defer special key handlings to
@@ -6060,7 +6061,7 @@
                             }
                             if ((mEndcallBehavior
                                     & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
-                                mPowerManager.goToSleep(event.getEventTime(),
+                                goToSleep(event.getEventTime(),
                                         PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
                                 isWakeKey = false;
                             }
@@ -6223,20 +6224,36 @@
             if (!mAccessibilityManager.isEnabled()
                     || !mAccessibilityManager.sendFingerprintGesture(event.getKeyCode())) {
                 if (areSystemNavigationKeysEnabled()) {
-                    IStatusBarService sbar = getStatusBarService();
-                    if (sbar != null) {
-                        try {
-                            sbar.handleSystemNavigationKey(event.getKeyCode());
-                        } catch (RemoteException e1) {
-                            // oops, no statusbar. Ignore event.
-                        }
-                    }
+                    sendSystemKeyToStatusBarAsync(event.getKeyCode());
                 }
             }
         }
     }
 
     /**
+     * Notify the StatusBar that a system key was pressed.
+     */
+    private void sendSystemKeyToStatusBar(int keyCode) {
+        IStatusBarService statusBar = getStatusBarService();
+        if (statusBar != null) {
+            try {
+                statusBar.handleSystemKey(keyCode);
+            } catch (RemoteException e) {
+                // Oh well.
+            }
+        }
+    }
+
+    /**
+     * Notify the StatusBar that a system key was pressed without blocking the current thread.
+     */
+    private void sendSystemKeyToStatusBarAsync(int keyCode) {
+        Message message = mHandler.obtainMessage(MSG_SYSTEM_KEY_PRESS, keyCode, 0);
+        message.setAsynchronous(true);
+        mHandler.sendMessage(message);
+    }
+
+    /**
      * Returns true if the key can have global actions attached to it.
      * We reserve all power management keys for the system since they require
      * very careful handling.
@@ -6553,8 +6570,10 @@
     @Override
     public void startedGoingToSleep(int why) {
         if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")");
-        mCameraGestureTriggeredDuringGoingToSleep = false;
+
         mGoingToSleep = true;
+        mRequestedOrGoingToSleep = true;
+
         if (mKeyguardDelegate != null) {
             mKeyguardDelegate.onStartedGoingToSleep(why);
         }
@@ -6568,6 +6587,7 @@
         MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);
 
         mGoingToSleep = false;
+        mRequestedOrGoingToSleep = false;
 
         // We must get this work done here because the power manager will drop
         // the wake lock and let the system suspend once this function returns.
@@ -6611,6 +6631,10 @@
     @Override
     public void finishedWakingUp() {
         if (DEBUG_WAKEUP) Slog.i(TAG, "Finished waking up...");
+
+        if (mKeyguardDelegate != null) {
+            mKeyguardDelegate.onFinishedWakingUp();
+        }
     }
 
     private void wakeUpFromPowerKey(long eventTime) {
@@ -6719,6 +6743,11 @@
     @Override
     public void screenTurningOff(ScreenOffListener screenOffListener) {
         mWindowManagerFuncs.screenTurningOff(screenOffListener);
+        synchronized (mLock) {
+            if (mKeyguardDelegate != null) {
+                mKeyguardDelegate.onScreenTurningOff();
+            }
+        }
     }
 
     private void reportScreenStateToVrManager(boolean isScreenOn) {
@@ -6814,6 +6843,11 @@
         }
     }
 
+    @Override
+    public boolean okToAnimate() {
+        return mAwake && !mGoingToSleep;
+    }
+
     /** {@inheritDoc} */
     @Override
     public void enableKeyguard(boolean enabled) {
@@ -6939,6 +6973,12 @@
     }
 
     @Override
+    public int getNavBarPosition() {
+        // TODO(multi-display): Support system decor on secondary displays.
+        return mNavigationBarPosition;
+    }
+
+    @Override
     public boolean isDockSideAllowed(int dockSide) {
 
         // We do not allow all dock sides at which the navigation bar touches the docked stack.
@@ -7013,6 +7053,12 @@
                 // Ignore sensor when demo rotation lock is enabled.
                 // Note that the dock orientation and HDMI rotation lock override this.
                 preferredRotation = mDemoRotation;
+            } else if (mPersistentVrModeEnabled) {
+                // While in VR, apps always prefer a portrait rotation. This does not change
+                // any apps that explicitly set landscape, but does cause sensors be ignored,
+                // and ignored any orientation lock that the user has set (this conditional
+                // should remain above the ORIENTATION_LOCKED conditional below).
+                preferredRotation = mPortraitRotation;
             } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
                 // Application just wants to remain locked in the last rotation.
                 preferredRotation = lastRotation;
@@ -7043,13 +7089,7 @@
                         || mAllowAllRotations == 1
                         || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
                         || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {
-                    // In VrMode, we report the sensor as always being in default orientation so:
-                    // 1) The orientation doesn't change as the user moves their head.
-                    // 2) 2D apps within VR show in the device's default orientation.
-                    // This only overwrites the sensor-provided orientation and does not affect any
-                    // explicit orientation preferences specified by any activities.
-                    preferredRotation =
-                            mPersistentVrModeEnabled ? Surface.ROTATION_0 : sensorRotation;
+                    preferredRotation = sensorRotation;
                 } else {
                     preferredRotation = lastRotation;
                 }
@@ -7193,9 +7233,9 @@
     @Override
     public void setSafeMode(boolean safeMode) {
         mSafeMode = safeMode;
-        performHapticFeedbackLw(null, safeMode
-                ? HapticFeedbackConstants.SAFE_MODE_ENABLED
-                : HapticFeedbackConstants.SAFE_MODE_DISABLED, true);
+        if (safeMode) {
+            performHapticFeedbackLw(null, HapticFeedbackConstants.SAFE_MODE_ENABLED, true);
+        }
     }
 
     static long[] getLongIntArray(Resources r, int resid) {
@@ -7462,8 +7502,7 @@
 
     private void applyLidSwitchState() {
         if (mLidState == LID_CLOSED && mLidControlsSleep) {
-            mPowerManager.goToSleep(SystemClock.uptimeMillis(),
-                    PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH,
+            goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH,
                     PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
         } else if (mLidState == LID_CLOSED && mLidControlsScreenLock) {
             mWindowManagerFuncs.lockDeviceNow();
@@ -7710,20 +7749,19 @@
             case HapticFeedbackConstants.KEYBOARD_TAP:
                 return VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
             case HapticFeedbackConstants.CLOCK_TICK:
-                pattern = mClockTickVibePattern;
-                break;
+                return VibrationEffect.get(VibrationEffect.EFFECT_TICK);
             case HapticFeedbackConstants.CALENDAR_DATE:
                 pattern = mCalendarDateVibePattern;
                 break;
-            case HapticFeedbackConstants.SAFE_MODE_DISABLED:
-                pattern = mSafeModeDisabledVibePattern;
-                break;
             case HapticFeedbackConstants.SAFE_MODE_ENABLED:
                 pattern = mSafeModeEnabledVibePattern;
                 break;
             case HapticFeedbackConstants.CONTEXT_CLICK:
-                pattern = mContextClickVibePattern;
-                break;
+                return VibrationEffect.get(VibrationEffect.EFFECT_TICK);
+            case HapticFeedbackConstants.VIRTUAL_KEY_RELEASE:
+                return VibrationEffect.get(VibrationEffect.EFFECT_TICK);
+            case HapticFeedbackConstants.TEXT_HANDLE_MOVE:
+                return VibrationEffect.get(VibrationEffect.EFFECT_TICK);
             default:
                 return null;
         }
@@ -7824,21 +7862,17 @@
     }
 
     private int updateLightStatusBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming) {
-        WindowState statusColorWin = isStatusBarKeyguard() && !mKeyguardOccluded
-                ? mStatusBar
-                : opaqueOrDimming;
-
-        if (statusColorWin != null) {
-            if (statusColorWin == opaque) {
-                // If the top fullscreen-or-dimming window is also the top fullscreen, respect
-                // its light flag.
-                vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-                vis |= PolicyControl.getSystemUiVisibility(statusColorWin, null)
-                        & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-            } else if (statusColorWin != null && statusColorWin.isDimming()) {
-                // Otherwise if it's dimming, clear the light flag.
-                vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-            }
+        final boolean onKeyguard = isStatusBarKeyguard() && !mKeyguardOccluded;
+        final WindowState statusColorWin = onKeyguard ? mStatusBar : opaqueOrDimming;
+        if (statusColorWin != null && (statusColorWin == opaque || onKeyguard)) {
+            // If the top fullscreen-or-dimming window is also the top fullscreen, respect
+            // its light flag.
+            vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+            vis |= PolicyControl.getSystemUiVisibility(statusColorWin, null)
+                    & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+        } else if (statusColorWin != null && statusColorWin.isDimming()) {
+            // Otherwise if it's dimming, clear the light flag.
+            vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
         }
         return vis;
     }
@@ -7848,7 +7882,7 @@
         final WindowState imeWin = mWindowManagerFuncs.getInputMethodWindowLw();
 
         final WindowState navColorWin;
-        if (imeWin != null && imeWin.isVisibleLw()) {
+        if (imeWin != null && imeWin.isVisibleLw() && mNavigationBarPosition == NAV_BAR_BOTTOM) {
             navColorWin = imeWin;
         } else {
             navColorWin = opaqueOrDimming;
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 0121ee1..50e5e7b 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -35,10 +35,12 @@
     private static final int SCREEN_STATE_OFF = 0;
     private static final int SCREEN_STATE_TURNING_ON = 1;
     private static final int SCREEN_STATE_ON = 2;
+    private static final int SCREEN_STATE_TURNING_OFF = 3;
 
     private static final int INTERACTIVE_STATE_SLEEP = 0;
-    private static final int INTERACTIVE_STATE_AWAKE = 1;
-    private static final int INTERACTIVE_STATE_GOING_TO_SLEEP = 2;
+    private static final int INTERACTIVE_STATE_WAKING = 1;
+    private static final int INTERACTIVE_STATE_AWAKE = 2;
+    private static final int INTERACTIVE_STATE_GOING_TO_SLEEP = 3;
 
     protected KeyguardServiceWrapper mKeyguardService;
     private final Context mContext;
@@ -164,9 +166,13 @@
                     mKeyguardService.setCurrentUser(mKeyguardState.currentUser);
                 }
                 // This is used to hide the scrim once keyguard displays.
-                if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) {
+                if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE
+                        || mKeyguardState.interactiveState == INTERACTIVE_STATE_WAKING) {
                     mKeyguardService.onStartedWakingUp();
                 }
+                if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) {
+                    mKeyguardService.onFinishedWakingUp();
+                }
                 if (mKeyguardState.screenState == SCREEN_STATE_ON
                         || mKeyguardState.screenState == SCREEN_STATE_TURNING_ON) {
                     mKeyguardService.onScreenTurningOn(
@@ -277,9 +283,25 @@
             if (DEBUG) Log.v(TAG, "onStartedWakingUp()");
             mKeyguardService.onStartedWakingUp();
         }
+        mKeyguardState.interactiveState = INTERACTIVE_STATE_WAKING;
+    }
+
+    public void onFinishedWakingUp() {
+        if (mKeyguardService != null) {
+            if (DEBUG) Log.v(TAG, "onFinishedWakingUp()");
+            mKeyguardService.onFinishedWakingUp();
+        }
         mKeyguardState.interactiveState = INTERACTIVE_STATE_AWAKE;
     }
 
+    public void onScreenTurningOff() {
+        if (mKeyguardService != null) {
+            if (DEBUG) Log.v(TAG, "onScreenTurningOff()");
+            mKeyguardService.onScreenTurningOff();
+        }
+        mKeyguardState.screenState = SCREEN_STATE_TURNING_OFF;
+    }
+
     public void onScreenTurnedOff() {
         if (mKeyguardService != null) {
             if (DEBUG) Log.v(TAG, "onScreenTurnedOff()");
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
index 425be54..952e0b0 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
@@ -128,6 +128,15 @@
     }
 
     @Override
+    public void onFinishedWakingUp() {
+        try {
+            mService.onFinishedWakingUp();
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    @Override
     public void onScreenTurningOn(IKeyguardDrawnCallback callback) {
         try {
             mService.onScreenTurningOn(callback);
@@ -146,6 +155,15 @@
     }
 
     @Override
+    public void onScreenTurningOff() {
+        try {
+            mService.onScreenTurningOff();
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    @Override
     public void onScreenTurnedOff() {
         try {
             mService.onScreenTurnedOff();
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index f5bb082..0ecf0e1e 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -18,7 +18,6 @@
 
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
-import android.app.RetailDemoModeServiceInternal;
 
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.app.IBatteryStats;
@@ -94,7 +93,6 @@
     private final ActivityManagerInternal mActivityManagerInternal;
     private final InputManagerInternal mInputManagerInternal;
     private final InputMethodManagerInternal mInputMethodManagerInternal;
-    private final RetailDemoModeServiceInternal mRetailDemoModeServiceInternal;
 
     private final NotifierHandler mHandler;
     private final Intent mScreenOnIntent;
@@ -140,7 +138,6 @@
         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
         mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
         mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
-        mRetailDemoModeServiceInternal = LocalServices.getService(RetailDemoModeServiceInternal.class);
 
         mHandler = new NotifierHandler(looper);
         mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
@@ -587,9 +584,6 @@
             }
             mUserActivityPending = false;
         }
-        if (mRetailDemoModeServiceInternal != null) {
-            mRetailDemoModeServiceInternal.onUserActivity();
-        }
         mPolicy.userActivity();
     }
 
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 3b5db29..855c055 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -53,6 +53,7 @@
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.WorkSource;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
@@ -197,11 +198,14 @@
     // System property indicating that the screen should remain off until an explicit user action
     private static final String SYSTEM_PROPERTY_QUIESCENT = "ro.boot.quiescent";
 
+    // System Property indicating that retail demo mode is currently enabled.
+    private static final String SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED = "sys.retaildemo.enabled";
+
     // Possible reasons for shutting down for use in data/misc/reboot/last_shutdown_reason
     private static final String REASON_SHUTDOWN = "shutdown";
     private static final String REASON_REBOOT = "reboot";
-    private static final String REASON_USERREQUESTED = "userrequested";
-    private static final String REASON_THERMAL_SHUTDOWN = "thermal-shutdown";
+    private static final String REASON_USERREQUESTED = "shutdown,userrequested";
+    private static final String REASON_THERMAL_SHUTDOWN = "shutdown,thermal";
 
     private static final String TRACE_SCREEN_ON = "Screen turning on";
 
@@ -216,8 +220,8 @@
     private static final int HALT_MODE_REBOOT = 1;
     private static final int HALT_MODE_REBOOT_SAFE_MODE = 2;
 
-    // File location for last reboot reason
-    private static final String LAST_REBOOT_LOCATION = "/data/misc/reboot/last_reboot_reason";
+    // Persistent property for last reboot reason
+    private static final String LAST_REBOOT_PROPERTY = "persist.sys.boot.reason";
 
     private final Context mContext;
     private final ServiceThread mHandlerThread;
@@ -805,6 +809,9 @@
         resolver.registerContentObserver(Settings.Secure.getUriFor(
                 Settings.Secure.DOUBLE_TAP_TO_WAKE),
                 false, mSettingsObserver, UserHandle.USER_ALL);
+        resolver.registerContentObserver(Settings.Global.getUriFor(
+                Settings.Global.DEVICE_DEMO_MODE),
+                false, mSettingsObserver, UserHandle.USER_SYSTEM);
         IVrManager vrManager = (IVrManager) getBinderService(Context.VR_SERVICE);
         if (vrManager != null) {
             try {
@@ -912,6 +919,11 @@
             }
         }
 
+        final String retailDemoValue = UserManager.isDeviceInDemoMode(mContext) ? "1" : "0";
+        if (!retailDemoValue.equals(SystemProperties.get(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED))) {
+            SystemProperties.set(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, retailDemoValue);
+        }
+
         final int oldScreenBrightnessSetting = getCurrentBrightnessSettingLocked();
 
         mScreenBrightnessForVrSetting = Settings.System.getIntForUser(resolver,
@@ -1398,13 +1410,16 @@
         try {
             switch (mWakefulness) {
                 case WAKEFULNESS_ASLEEP:
-                    Slog.i(TAG, "Waking up from sleep (uid " + reasonUid +")...");
+                    Slog.i(TAG, "Waking up from sleep (uid=" + reasonUid + " reason=" + reason
+                            + ")...");
                     break;
                 case WAKEFULNESS_DREAMING:
-                    Slog.i(TAG, "Waking up from dream (uid " + reasonUid +")...");
+                    Slog.i(TAG, "Waking up from dream (uid=" + reasonUid + " reason=" + reason
+                            + ")...");
                     break;
                 case WAKEFULNESS_DOZING:
-                    Slog.i(TAG, "Waking up from dozing (uid " + reasonUid +")...");
+                    Slog.i(TAG, "Waking up from dozing (uid=" + reasonUid + " reason=" + reason
+                            + ")...");
                     break;
             }
 
@@ -4373,7 +4388,7 @@
 
             final long ident = Binder.clearCallingIdentity();
             try {
-                return getLastShutdownReasonInternal(new File(LAST_REBOOT_LOCATION));
+                return getLastShutdownReasonInternal(LAST_REBOOT_PROPERTY);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -4607,13 +4622,9 @@
     }
 
     @VisibleForTesting
-    int getLastShutdownReasonInternal(File lastRebootReason) {
-        String line = "";
-        try (BufferedReader bufferedReader = new BufferedReader(new FileReader(lastRebootReason))){
-            line = bufferedReader.readLine();
-        } catch (IOException e) {
-            Slog.e(TAG, "Failed to read last_reboot_reason file", e);
-        }
+    // lastRebootReasonProperty argument to permit testing
+    int getLastShutdownReasonInternal(String lastRebootReasonProperty) {
+        String line = SystemProperties.get(lastRebootReasonProperty);
         if (line == null) {
             return PowerManager.SHUTDOWN_REASON_UNKNOWN;
         }
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 02f2afc..0f61171 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -20,17 +20,22 @@
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.IActivityManager;
+import android.app.KeyguardManager;
 import android.app.ProgressDialog;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.IBluetoothManager;
-import android.media.AudioAttributes;
-import android.nfc.NfcAdapter;
-import android.nfc.INfcAdapter;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.media.AudioAttributes;
+import android.nfc.INfcAdapter;
+import android.nfc.NfcAdapter;
 import android.os.FileUtils;
 import android.os.Handler;
 import android.os.PowerManager;
@@ -39,24 +44,24 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.SystemVibrator;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.Vibrator;
-import android.os.SystemVibrator;
-import android.os.storage.IStorageShutdownObserver;
 import android.os.storage.IStorageManager;
-import android.system.ErrnoException;
-import android.system.Os;
+import android.os.storage.IStorageShutdownObserver;
+import android.util.Log;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.ProgressBar;
+import android.widget.TextView;
 
 import com.android.internal.telephony.ITelephony;
+import com.android.server.LocalServices;
 import com.android.server.pm.PackageManagerService;
+import com.android.server.statusbar.StatusBarManagerInternal;
 
-import android.util.Log;
-import android.view.WindowManager;
-
-import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileReader;
 import java.io.IOException;
 
 public final class ShutdownThread extends Thread {
@@ -243,15 +248,7 @@
         shutdownInner(context, confirm);
     }
 
-    private static void beginShutdownSequence(Context context) {
-        synchronized (sIsStartedGuard) {
-            if (sIsStarted) {
-                Log.d(TAG, "Shutdown sequence already running, returning.");
-                return;
-            }
-            sIsStarted = true;
-        }
-
+    private static ProgressDialog showShutdownDialog(Context context) {
         // Throw up a system dialog to indicate the device is rebooting / shutting down.
         ProgressDialog pd = new ProgressDialog(context);
 
@@ -293,6 +290,9 @@
                 pd.setMessage(context.getText(
                             com.android.internal.R.string.reboot_to_update_prepare));
             } else {
+                if (showSysuiReboot()) {
+                    return null;
+                }
                 pd.setIndeterminate(true);
                 pd.setMessage(context.getText(
                             com.android.internal.R.string.reboot_to_update_reboot));
@@ -301,9 +301,12 @@
             // Factory reset path. Set the dialog message accordingly.
             pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_reset_title));
             pd.setMessage(context.getText(
-                        com.android.internal.R.string.reboot_to_reset_message));
+                    com.android.internal.R.string.reboot_to_reset_message));
             pd.setIndeterminate(true);
         } else {
+            if (showSysuiReboot()) {
+                return null;
+            }
             pd.setTitle(context.getText(com.android.internal.R.string.power_off));
             pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
             pd.setIndeterminate(true);
@@ -312,8 +315,36 @@
         pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
 
         pd.show();
+        return pd;
+    }
 
-        sInstance.mProgressDialog = pd;
+    private static boolean showSysuiReboot() {
+        Log.d(TAG, "Attempting to use SysUI shutdown UI");
+        try {
+            StatusBarManagerInternal service = LocalServices.getService(
+                    StatusBarManagerInternal.class);
+            if (service.showShutdownUi(mReboot, mReason)) {
+                // Sysui will handle shutdown UI.
+                Log.d(TAG, "SysUI handling shutdown UI");
+                return true;
+            }
+        } catch (Exception e) {
+            // If anything went wrong, ignore it and use fallback ui
+        }
+        Log.d(TAG, "SysUI is unavailable");
+        return false;
+    }
+
+    private static void beginShutdownSequence(Context context) {
+        synchronized (sIsStartedGuard) {
+            if (sIsStarted) {
+                Log.d(TAG, "Shutdown sequence already running, returning.");
+                return;
+            }
+            sIsStarted = true;
+        }
+
+        sInstance.mProgressDialog = showShutdownDialog(context);
         sInstance.mContext = context;
         sInstance.mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
 
@@ -525,7 +556,7 @@
         Thread t = new Thread() {
             public void run() {
                 boolean nfcOff;
-                boolean bluetoothOff;
+                boolean bluetoothReadyForShutdown;
                 boolean radioOff;
 
                 final INfcAdapter nfc =
@@ -549,15 +580,15 @@
                 }
 
                 try {
-                    bluetoothOff = bluetooth == null ||
+                    bluetoothReadyForShutdown = bluetooth == null ||
                             bluetooth.getState() == BluetoothAdapter.STATE_OFF;
-                    if (!bluetoothOff) {
+                    if (!bluetoothReadyForShutdown) {
                         Log.w(TAG, "Disabling Bluetooth...");
                         bluetooth.disable(mContext.getPackageName(), false);  // disable but don't persist new state
                     }
                 } catch (RemoteException ex) {
                     Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
-                    bluetoothOff = true;
+                    bluetoothReadyForShutdown = true;
                 }
 
                 try {
@@ -582,14 +613,19 @@
                         sInstance.setRebootProgress(status, null);
                     }
 
-                    if (!bluetoothOff) {
+                    if (!bluetoothReadyForShutdown) {
                         try {
-                            bluetoothOff = bluetooth.getState() == BluetoothAdapter.STATE_OFF;
+                          // BLE only mode can happen when BT is turned off
+                          // We will continue shutting down in such case
+                          bluetoothReadyForShutdown =
+                                  bluetooth.getState() == BluetoothAdapter.STATE_OFF ||
+                                  bluetooth.getState() == BluetoothAdapter.STATE_BLE_TURNING_OFF ||
+                                  bluetooth.getState() == BluetoothAdapter.STATE_BLE_ON;
                         } catch (RemoteException ex) {
                             Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
-                            bluetoothOff = true;
+                            bluetoothReadyForShutdown = true;
                         }
-                        if (bluetoothOff) {
+                        if (bluetoothReadyForShutdown) {
                             Log.i(TAG, "Bluetooth turned off.");
                         }
                     }
@@ -616,7 +652,7 @@
                         }
                     }
 
-                    if (radioOff && bluetoothOff && nfcOff) {
+                    if (radioOff && bluetoothReadyForShutdown && nfcOff) {
                         Log.i(TAG, "NFC, Radio and Bluetooth shutdown complete.");
                         done[0] = true;
                         break;
diff --git a/services/core/java/com/android/server/radio/RadioService.java b/services/core/java/com/android/server/radio/RadioService.java
new file mode 100644
index 0000000..34bbffd
--- /dev/null
+++ b/services/core/java/com/android/server/radio/RadioService.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.radio;
+
+import android.content.Context;
+import android.hardware.radio.IRadioService;
+import android.hardware.radio.ITuner;
+import android.hardware.radio.ITunerCallback;
+import android.hardware.radio.RadioManager;
+import android.util.Slog;
+
+import com.android.server.SystemService;
+
+public class RadioService extends SystemService {
+    // TODO(b/36863239): rename to RadioService when native service goes away
+    private static final String TAG = "RadioServiceJava";
+
+    private final RadioServiceImpl mServiceImpl = new RadioServiceImpl();
+
+    /**
+     * This field is used by native code, do not access or modify.
+     */
+    private final long mNativeContext = nativeInit();
+
+    private final Object mLock = new Object();
+
+    public RadioService(Context context) {
+        super(context);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        nativeFinalize(mNativeContext);
+        super.finalize();
+    }
+
+    private native long nativeInit();
+    private native void nativeFinalize(long nativeContext);
+    private native Tuner nativeOpenTuner(long nativeContext, int moduleId,
+            RadioManager.BandConfig config, boolean withAudio, ITunerCallback callback);
+
+    @Override
+    public void onStart() {
+        publishBinderService(Context.RADIO_SERVICE, mServiceImpl);
+        Slog.v(TAG, "RadioService started");
+    }
+
+    private class RadioServiceImpl extends IRadioService.Stub {
+        @Override
+        public ITuner openTuner(int moduleId, RadioManager.BandConfig bandConfig,
+                boolean withAudio, ITunerCallback callback) {
+            if (callback == null) {
+                throw new IllegalArgumentException("Callback must not be empty");
+            }
+            synchronized (mLock) {
+                // TODO(b/36863239): add death monitoring for binder
+                return nativeOpenTuner(mNativeContext, moduleId, bandConfig, withAudio, callback);
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/radio/Tuner.java b/services/core/java/com/android/server/radio/Tuner.java
new file mode 100644
index 0000000..9915c34
--- /dev/null
+++ b/services/core/java/com/android/server/radio/Tuner.java
@@ -0,0 +1,225 @@
+/**
+ * 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.radio;
+
+import android.annotation.NonNull;
+import android.hardware.radio.ITuner;
+import android.hardware.radio.ITunerCallback;
+import android.hardware.radio.RadioManager;
+import android.util.Slog;
+
+import java.util.List;
+
+class Tuner extends ITuner.Stub {
+    // TODO(b/36863239): rename to RadioService.Tuner when native service goes away
+    private static final String TAG = "RadioServiceJava.Tuner";
+
+    /**
+     * This field is used by native code, do not access or modify.
+     */
+    private final long mNativeContext;
+
+    @NonNull private final TunerCallback mTunerCallback;
+    private final Object mLock = new Object();
+    private boolean mIsClosed = false;
+    private boolean mIsMuted = false;
+    private int mRegion;  // TODO(b/36863239): find better solution to manage regions
+    private final boolean mWithAudio;
+
+    Tuner(@NonNull ITunerCallback clientCallback, int halRev, int region, boolean withAudio) {
+        mTunerCallback = new TunerCallback(this, clientCallback, halRev);
+        mRegion = region;
+        mWithAudio = withAudio;
+        mNativeContext = nativeInit(halRev);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        nativeFinalize(mNativeContext);
+        super.finalize();
+    }
+
+    private native long nativeInit(int halRev);
+    private native void nativeFinalize(long nativeContext);
+    private native void nativeClose(long nativeContext);
+
+    private native void nativeSetConfiguration(long nativeContext,
+            @NonNull RadioManager.BandConfig config);
+    private native RadioManager.BandConfig nativeGetConfiguration(long nativeContext, int region);
+
+    private native void nativeStep(long nativeContext, boolean directionDown, boolean skipSubChannel);
+    private native void nativeScan(long nativeContext, boolean directionDown, boolean skipSubChannel);
+    private native void nativeTune(long nativeContext, int channel, int subChannel);
+    private native void nativeCancel(long nativeContext);
+
+    private native RadioManager.ProgramInfo nativeGetProgramInformation(long nativeContext);
+    private native boolean nativeStartBackgroundScan(long nativeContext);
+    private native List<RadioManager.ProgramInfo> nativeGetProgramList(long nativeContext,
+            String filter);
+
+    private native boolean nativeIsAnalogForced(long nativeContext);
+    private native void nativeSetAnalogForced(long nativeContext, boolean isForced);
+
+    private native boolean nativeIsAntennaConnected(long nativeContext);
+
+    @Override
+    public void close() {
+        synchronized (mLock) {
+            if (mIsClosed) return;
+            mTunerCallback.detach();
+            nativeClose(mNativeContext);
+            mIsClosed = true;
+        }
+    }
+
+    private void checkNotClosedLocked() {
+        if (mIsClosed) {
+            throw new IllegalStateException("Tuner is closed, no further operations are allowed");
+        }
+    }
+
+    @Override
+    public void setConfiguration(RadioManager.BandConfig config) {
+        if (config == null) {
+            throw new IllegalArgumentException("The argument must not be a null pointer");
+        }
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            nativeSetConfiguration(mNativeContext, config);
+            mRegion = config.getRegion();
+        }
+    }
+
+    @Override
+    public RadioManager.BandConfig getConfiguration() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return nativeGetConfiguration(mNativeContext, mRegion);
+        }
+    }
+
+    @Override
+    public void setMuted(boolean mute) {
+        if (!mWithAudio) {
+            throw new IllegalStateException("Can't operate on mute - no audio requested");
+        }
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            if (mIsMuted == mute) return;
+            mIsMuted = mute;
+
+            // TODO(b/34348946): notifify audio policy manager of media activity on radio audio
+            // device. This task is pulled directly from previous implementation of native service.
+        }
+    }
+
+    @Override
+    public boolean isMuted() {
+        if (!mWithAudio) {
+            Slog.w(TAG, "Tuner did not request audio, pretending it was muted");
+            return true;
+        }
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return mIsMuted;
+        }
+    }
+
+    @Override
+    public void step(boolean directionDown, boolean skipSubChannel) {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            nativeStep(mNativeContext, directionDown, skipSubChannel);
+        }
+    }
+
+    @Override
+    public void scan(boolean directionDown, boolean skipSubChannel) {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            nativeScan(mNativeContext, directionDown, skipSubChannel);
+        }
+    }
+
+    @Override
+    public void tune(int channel, int subChannel) {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            nativeTune(mNativeContext, channel, subChannel);
+        }
+    }
+
+    @Override
+    public void cancel() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            nativeCancel(mNativeContext);
+        }
+    }
+
+    @Override
+    public RadioManager.ProgramInfo getProgramInformation() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return nativeGetProgramInformation(mNativeContext);
+        }
+    }
+
+    @Override
+    public boolean startBackgroundScan() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return nativeStartBackgroundScan(mNativeContext);
+        }
+    }
+
+    @Override
+    public List<RadioManager.ProgramInfo> getProgramList(String filter) {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            List<RadioManager.ProgramInfo> list = nativeGetProgramList(mNativeContext, filter);
+            if (list == null) {
+                throw new IllegalStateException("Program list is not ready");
+            }
+            return list;
+        }
+    }
+
+    @Override
+    public boolean isAnalogForced() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return nativeIsAnalogForced(mNativeContext);
+        }
+    }
+
+    @Override
+    public void setAnalogForced(boolean isForced) {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            nativeSetAnalogForced(mNativeContext, isForced);
+        }
+    }
+
+    @Override
+    public boolean isAntennaConnected() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return nativeIsAntennaConnected(mNativeContext);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/radio/TunerCallback.java b/services/core/java/com/android/server/radio/TunerCallback.java
new file mode 100644
index 0000000..fcc874b
--- /dev/null
+++ b/services/core/java/com/android/server/radio/TunerCallback.java
@@ -0,0 +1,97 @@
+/**
+ * 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.radio;
+
+import android.annotation.NonNull;
+import android.hardware.radio.ITuner;
+import android.hardware.radio.ITunerCallback;
+import android.hardware.radio.RadioManager;
+import android.hardware.radio.RadioTuner;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
+
+class TunerCallback implements ITunerCallback {
+    // TODO(b/36863239): rename to RadioService.TunerCallback when native service goes away
+    private static final String TAG = "RadioServiceJava.TunerCallback";
+
+    /**
+     * This field is used by native code, do not access or modify.
+     */
+    private final long mNativeContext;
+
+    @NonNull private final Tuner mTuner;
+    @NonNull private final ITunerCallback mClientCallback;
+
+    TunerCallback(@NonNull Tuner tuner, @NonNull ITunerCallback clientCallback, int halRev) {
+        mTuner = tuner;
+        mClientCallback = clientCallback;
+        mNativeContext = nativeInit(tuner, halRev);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        nativeFinalize(mNativeContext);
+        super.finalize();
+    }
+
+    private native long nativeInit(@NonNull Tuner tuner, int halRev);
+    private native void nativeFinalize(long nativeContext);
+    private native void nativeDetach(long nativeContext);
+
+    public void detach() {
+        nativeDetach(mNativeContext);
+    }
+
+    // called from native side
+    private void handleHwFailure() {
+        onError(RadioTuner.ERROR_HARDWARE_FAILURE);
+        mTuner.close();
+    }
+
+    @Override
+    public void onError(int status) {
+        try {
+            mClientCallback.onError(status);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "client died", e);
+        }
+    }
+
+    @Override
+    public void onConfigurationChanged(RadioManager.BandConfig config) {
+        try {
+            mClientCallback.onConfigurationChanged(config);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "client died", e);
+        }
+    }
+
+    @Override
+    public void onProgramInfoChanged(RadioManager.ProgramInfo info) {
+        try {
+            mClientCallback.onProgramInfoChanged(info);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "client died", e);
+        }
+    }
+
+    @Override
+    public IBinder asBinder() {
+        throw new RuntimeException("Not a binder");
+    }
+}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 5e322da..866fdad 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -80,6 +80,8 @@
     void setGlobalActionsListener(GlobalActionsListener listener);
     void showGlobalActions();
 
+    boolean showShutdownUi(boolean isReboot, String requestString);
+
     public interface GlobalActionsListener {
         /**
          * Called when sysui starts and connects its status bar, or when the status bar binder
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 32871bb..5b252e8 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -36,6 +36,7 @@
 import android.util.ArrayMap;
 import android.util.Slog;
 
+import com.android.internal.R;
 import com.android.internal.statusbar.IStatusBar;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.NotificationVisibility;
@@ -329,6 +330,20 @@
                 } catch (RemoteException ex) {}
             }
         }
+
+        @Override
+        public boolean showShutdownUi(boolean isReboot, String reason) {
+            if (!mContext.getResources().getBoolean(R.bool.config_showSysuiShutdown)) {
+                return false;
+            }
+            if (mBar != null) {
+                try {
+                    mBar.showShutdownUi(isReboot, reason);
+                    return true;
+                } catch (RemoteException ex) {}
+            }
+            return false;
+        }
     };
 
     // ================================================================================
@@ -404,12 +419,12 @@
     }
 
     @Override
-    public void handleSystemNavigationKey(int key) throws RemoteException {
+    public void handleSystemKey(int key) throws RemoteException {
         enforceExpandStatusBar();
 
         if (mBar != null) {
             try {
-                mBar.handleSystemNavigationKey(key);
+                mBar.handleSystemKey(key);
             } catch (RemoteException ex) {
             }
         }
@@ -783,7 +798,7 @@
             mHandler.post(() -> {
                 // ShutdownThread displays UI, so give it a UI context.
                 if (safeMode) {
-                    ShutdownThread.rebootSafeMode(getUiContext(), false);
+                    ShutdownThread.rebootSafeMode(getUiContext(), true);
                 } else {
                     ShutdownThread.reboot(getUiContext(),
                             PowerManager.SHUTDOWN_USER_REQUESTED, false);
diff --git a/services/core/java/com/android/server/timezone/IntentHelper.java b/services/core/java/com/android/server/timezone/IntentHelper.java
index 0cb9065..5de5432 100644
--- a/services/core/java/com/android/server/timezone/IntentHelper.java
+++ b/services/core/java/com/android/server/timezone/IntentHelper.java
@@ -23,15 +23,22 @@
  */
 interface IntentHelper {
 
-    void initialize(String updateAppPackageName, String dataAppPackageName, Listener listener);
+    void initialize(String updateAppPackageName, String dataAppPackageName,
+            PackageTracker packageTracker);
 
     void sendTriggerUpdateCheck(CheckToken checkToken);
 
-    void enableReliabilityTriggering();
+    /**
+     * Schedule a "reliability trigger" after at least minimumDelayMillis, replacing any existing
+     * scheduled one. A reliability trigger ensures that the {@link PackageTracker} can pick up
+     * reliably if a previous update check did not complete for some reason. It can happen when
+     * the device is idle. The trigger is expected to call
+     * {@link PackageTracker#triggerUpdateIfNeeded(boolean)} with a {@code false} value.
+     */
+    void scheduleReliabilityTrigger(long minimumDelayMillis);
 
-    void disableReliabilityTriggering();
-
-    interface Listener {
-        void triggerUpdateIfNeeded(boolean packageUpdated);
-    }
+    /**
+     * Make sure there is no reliability trigger scheduled. No-op if there wasn't one.
+     */
+    void unscheduleReliabilityTrigger();
 }
diff --git a/services/core/java/com/android/server/timezone/IntentHelperImpl.java b/services/core/java/com/android/server/timezone/IntentHelperImpl.java
index 11928b9..6e6259d 100644
--- a/services/core/java/com/android/server/timezone/IntentHelperImpl.java
+++ b/services/core/java/com/android/server/timezone/IntentHelperImpl.java
@@ -24,6 +24,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.PatternMatcher;
+import android.os.UserHandle;
 import android.util.Slog;
 
 /**
@@ -36,16 +37,13 @@
     private final Context mContext;
     private String mUpdaterAppPackageName;
 
-    private boolean mReliabilityReceiverEnabled;
-    private Receiver mReliabilityReceiver;
-
     IntentHelperImpl(Context context) {
         mContext = context;
     }
 
     @Override
-    public void initialize(
-            String updaterAppPackageName, String dataAppPackageName, Listener listener) {
+    public void initialize(String updaterAppPackageName, String dataAppPackageName,
+            PackageTracker packageTracker) {
         mUpdaterAppPackageName = updaterAppPackageName;
 
         // Register for events of interest.
@@ -53,21 +51,35 @@
         // The intent filter that triggers when package update events happen that indicate there may
         // be work to do.
         IntentFilter packageIntentFilter = new IntentFilter();
-        // Either of these mean a downgrade?
-        packageIntentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-        packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+
         packageIntentFilter.addDataScheme("package");
         packageIntentFilter.addDataSchemeSpecificPart(
                 updaterAppPackageName, PatternMatcher.PATTERN_LITERAL);
         packageIntentFilter.addDataSchemeSpecificPart(
                 dataAppPackageName, PatternMatcher.PATTERN_LITERAL);
-        Receiver packageUpdateReceiver = new Receiver(listener, true /* packageUpdated */);
-        mContext.registerReceiver(packageUpdateReceiver, packageIntentFilter);
 
-        // TODO(nfuller): Add more exotic intents as needed. e.g.
-        // packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-        // Also, disabled...?
-        mReliabilityReceiver = new Receiver(listener, false /* packageUpdated */);
+        // ACTION_PACKAGE_ADDED is fired when a package is upgraded or downgraded (in addition to
+        // ACTION_PACKAGE_REMOVED and ACTION_PACKAGE_REPLACED). A system/priv-app can never be
+        // removed entirely so we do not need to trigger on ACTION_PACKAGE_REMOVED or
+        // ACTION_PACKAGE_FULLY_REMOVED.
+        packageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+
+        // ACTION_PACKAGE_CHANGED is used when a package is disabled / re-enabled. It is not
+        // strictly necessary to trigger on this but it won't hurt anything and may catch some cases
+        // where a package has changed while disabled.
+        // Note: ACTION_PACKAGE_CHANGED is not fired when updating a suspended app, but
+        // ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and ACTION_PACKAGE_REPLACED are (and the app
+        // is left in an unsuspended state after this).
+        packageIntentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+
+        // We do not register for ACTION_PACKAGE_RESTARTED because it doesn't imply an update.
+        // We do not register for ACTION_PACKAGE_DATA_CLEARED because the updater / data apps are
+        // not expected to need local data.
+
+        Receiver packageUpdateReceiver = new Receiver(packageTracker);
+        mContext.registerReceiverAsUser(
+                packageUpdateReceiver, UserHandle.SYSTEM, packageIntentFilter,
+                null /* broadcastPermission */, null /* default handler */);
     }
 
     /** Sends an intent to trigger an update check. */
@@ -79,39 +91,26 @@
     }
 
     @Override
-    public synchronized void enableReliabilityTriggering() {
-        if (!mReliabilityReceiverEnabled) {
-            // The intent filter that exists to make updates reliable in the event of failures /
-            // reboots.
-            IntentFilter reliabilityIntentFilter = new IntentFilter();
-            reliabilityIntentFilter.addAction(Intent.ACTION_IDLE_MAINTENANCE_START);
-            mContext.registerReceiver(mReliabilityReceiver, reliabilityIntentFilter);
-            mReliabilityReceiverEnabled = true;
-        }
+    public synchronized void scheduleReliabilityTrigger(long minimumDelayMillis) {
+        TimeZoneUpdateIdler.schedule(mContext, minimumDelayMillis);
     }
 
     @Override
-    public synchronized void disableReliabilityTriggering() {
-        if (mReliabilityReceiverEnabled) {
-            mContext.unregisterReceiver(mReliabilityReceiver);
-            mReliabilityReceiverEnabled = false;
-        }
+    public synchronized void unscheduleReliabilityTrigger() {
+        TimeZoneUpdateIdler.unschedule(mContext);
     }
 
     private static class Receiver extends BroadcastReceiver {
-        private final Listener mListener;
-        private final boolean mPackageUpdated;
+        private final PackageTracker mPackageTracker;
 
-        private Receiver(Listener listener, boolean packageUpdated) {
-            mListener = listener;
-            mPackageUpdated = packageUpdated;
+        private Receiver(PackageTracker packageTracker) {
+            mPackageTracker = packageTracker;
         }
 
         @Override
         public void onReceive(Context context, Intent intent) {
             Slog.d(TAG, "Received intent: " + intent.toString());
-            mListener.triggerUpdateIfNeeded(mPackageUpdated);
+            mPackageTracker.triggerUpdateIfNeeded(true /* packageChanged */);
         }
     }
-
 }
diff --git a/services/core/java/com/android/server/timezone/PackageTracker.java b/services/core/java/com/android/server/timezone/PackageTracker.java
index 24e0fe4..f0306b9 100644
--- a/services/core/java/com/android/server/timezone/PackageTracker.java
+++ b/services/core/java/com/android/server/timezone/PackageTracker.java
@@ -51,7 +51,7 @@
  */
 // Also made non-final so it can be mocked.
 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-public class PackageTracker implements IntentHelper.Listener {
+public class PackageTracker {
     private static final String TAG = "timezone.PackageTracker";
 
     private final PackageManagerHelper mPackageManagerHelper;
@@ -72,6 +72,13 @@
     // The number of failed checks in a row before reliability checks should stop happening.
     private long mFailedCheckRetryCount;
 
+    /*
+     * The minimum delay between a successive reliability triggers / other operations. Should to be
+     * larger than mCheckTimeAllowedMillis to avoid reliability triggers happening during package
+     * update checks.
+     */
+    private int mDelayBeforeReliabilityCheckMillis;
+
     // Reliability check state: If a check was triggered but not acknowledged within
     // mCheckTimeAllowedMillis then another one can be triggered.
     private Long mLastTriggerTimestamp = null;
@@ -122,6 +129,7 @@
         mDataAppPackageName = mConfigHelper.getDataAppPackageName();
         mCheckTimeAllowedMillis = mConfigHelper.getCheckTimeAllowedMillis();
         mFailedCheckRetryCount = mConfigHelper.getFailedCheckRetryCount();
+        mDelayBeforeReliabilityCheckMillis = mCheckTimeAllowedMillis + (60 * 1000);
 
         // Validate the device configuration including the application packages.
         // The manifest entries in the apps themselves are not validated until use as they can
@@ -135,9 +143,10 @@
         // Initialize the intent helper.
         mIntentHelper.initialize(mUpdateAppPackageName, mDataAppPackageName, this);
 
-        // Enable the reliability triggering so we will have at least one reliability trigger if
-        // a package isn't updated.
-        mIntentHelper.enableReliabilityTriggering();
+        // Schedule a reliability trigger so we will have at least one after boot. This will allow
+        // us to catch if a package updated wasn't handled to completion. There's no hurry: it's ok
+        // to delay for a while before doing this even if idle.
+        mIntentHelper.scheduleReliabilityTrigger(mDelayBeforeReliabilityCheckMillis);
 
         Slog.i(TAG, "Time zone updater / data package tracking enabled");
     }
@@ -195,7 +204,6 @@
      * @param packageChanged true if this method was called because a known packaged definitely
      *     changed, false if the cause is a reliability trigger
      */
-    @Override
     public synchronized void triggerUpdateIfNeeded(boolean packageChanged) {
         if (!mTrackingEnabled) {
             throw new IllegalStateException("Unexpected call. Tracking is disabled.");
@@ -212,8 +220,8 @@
                     + " updaterApp=" + updaterAppManifestValid
                     + ", dataApp=" + dataAppManifestValid);
 
-            // There's no point in doing reliability checks if the current packages are bad.
-            mIntentHelper.disableReliabilityTriggering();
+            // There's no point in doing any reliability triggers if the current packages are bad.
+            mIntentHelper.unscheduleReliabilityTrigger();
             return;
         }
 
@@ -238,7 +246,8 @@
                     Slog.d(TAG,
                             "triggerUpdateIfNeeded: checkComplete call is not yet overdue."
                                     + " Not triggering.");
-                    // Not doing any work, but also not disabling future reliability triggers.
+                    // Don't do any work now but we do schedule a future reliability trigger.
+                    mIntentHelper.scheduleReliabilityTrigger(mDelayBeforeReliabilityCheckMillis);
                     return;
                 }
             } else if (mCheckFailureCount > mFailedCheckRetryCount) {
@@ -247,13 +256,13 @@
                 Slog.i(TAG, "triggerUpdateIfNeeded: number of allowed consecutive check failures"
                         + " exceeded. Stopping reliability triggers until next reboot or package"
                         + " update.");
-                mIntentHelper.disableReliabilityTriggering();
+                mIntentHelper.unscheduleReliabilityTrigger();
                 return;
             } else if (mCheckFailureCount == 0) {
                 // Case 4.
                 Slog.i(TAG, "triggerUpdateIfNeeded: No reliability check required. Last check was"
                         + " successful.");
-                mIntentHelper.disableReliabilityTriggering();
+                mIntentHelper.unscheduleReliabilityTrigger();
                 return;
             }
         }
@@ -263,7 +272,7 @@
         if (currentInstalledVersions == null) {
             // This should not happen if the device is configured in a valid way.
             Slog.e(TAG, "triggerUpdateIfNeeded: currentInstalledVersions was null");
-            mIntentHelper.disableReliabilityTriggering();
+            mIntentHelper.unscheduleReliabilityTrigger();
             return;
         }
 
@@ -288,7 +297,7 @@
                 // The last check succeeded and nothing has changed. Do nothing and disable
                 // reliability checks.
                 Slog.i(TAG, "triggerUpdateIfNeeded: Prior check succeeded. No need to trigger.");
-                mIntentHelper.disableReliabilityTriggering();
+                mIntentHelper.unscheduleReliabilityTrigger();
                 return;
             }
         }
@@ -299,6 +308,8 @@
         if (checkToken == null) {
             Slog.w(TAG, "triggerUpdateIfNeeded: Unable to generate check token."
                     + " Not sending check request.");
+            // Trigger again later: perhaps we'll have better luck.
+            mIntentHelper.scheduleReliabilityTrigger(mDelayBeforeReliabilityCheckMillis);
             return;
         }
 
@@ -309,9 +320,9 @@
         // Update the reliability check state in case the update fails.
         setCheckInProgress();
 
-        // Enable reliability triggering in case the check doesn't succeed and there is no
-        // response at all. Enabling reliability triggering is idempotent.
-        mIntentHelper.enableReliabilityTriggering();
+        // Schedule a reliability trigger in case the update check doesn't succeed and there is no
+        // response at all. It will be cancelled if the check is successful in recordCheckResult.
+        mIntentHelper.scheduleReliabilityTrigger(mDelayBeforeReliabilityCheckMillis);
     }
 
     /**
@@ -370,9 +381,9 @@
                     + " storage state.");
             mPackageStatusStorage.resetCheckState();
 
-            // Enable reliability triggering and reset the failure count so we know that the
+            // Schedule a reliability trigger and reset the failure count so we know that the
             // next reliability trigger will do something.
-            mIntentHelper.enableReliabilityTriggering();
+            mIntentHelper.scheduleReliabilityTrigger(mDelayBeforeReliabilityCheckMillis);
             mCheckFailureCount = 0;
         } else {
             // This is the expected case when tracking is enabled: a check was triggered and it has
@@ -385,13 +396,13 @@
                 setCheckComplete();
 
                 if (success) {
-                    // Since the check was successful, no more reliability checks are required until
+                    // Since the check was successful, no reliability trigger is required until
                     // there is a package change.
-                    mIntentHelper.disableReliabilityTriggering();
+                    mIntentHelper.unscheduleReliabilityTrigger();
                     mCheckFailureCount = 0;
                 } else {
-                    // Enable reliability triggering to potentially check again in future.
-                    mIntentHelper.enableReliabilityTriggering();
+                    // Enable schedule a reliability trigger to check again in future.
+                    mIntentHelper.scheduleReliabilityTrigger(mDelayBeforeReliabilityCheckMillis);
                     mCheckFailureCount++;
                 }
             } else {
@@ -400,8 +411,8 @@
                 Slog.i(TAG, "recordCheckResult: could not update token=" + checkToken
                         + " with success=" + success + ". Optimistic lock failure");
 
-                // Enable reliability triggering to potentially try again in future.
-                mIntentHelper.enableReliabilityTriggering();
+                // Schedule a reliability trigger to potentially try again in future.
+                mIntentHelper.scheduleReliabilityTrigger(mDelayBeforeReliabilityCheckMillis);
                 mCheckFailureCount++;
             }
         }
@@ -515,6 +526,7 @@
                 ", mUpdateAppPackageName='" + mUpdateAppPackageName + '\'' +
                 ", mDataAppPackageName='" + mDataAppPackageName + '\'' +
                 ", mCheckTimeAllowedMillis=" + mCheckTimeAllowedMillis +
+                ", mDelayBeforeReliabilityCheckMillis=" + mDelayBeforeReliabilityCheckMillis +
                 ", mFailedCheckRetryCount=" + mFailedCheckRetryCount +
                 ", mLastTriggerTimestamp=" + mLastTriggerTimestamp +
                 ", mCheckTriggered=" + mCheckTriggered +
diff --git a/services/core/java/com/android/server/timezone/PackageTrackerHelperImpl.java b/services/core/java/com/android/server/timezone/PackageTrackerHelperImpl.java
index 2e0c21b..b89dd38 100644
--- a/services/core/java/com/android/server/timezone/PackageTrackerHelperImpl.java
+++ b/services/core/java/com/android/server/timezone/PackageTrackerHelperImpl.java
@@ -26,6 +26,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.os.SystemClock;
+import android.os.UserHandle;
 import android.util.Slog;
 
 import java.util.List;
@@ -114,8 +115,8 @@
     @Override
     public boolean contentProviderRegistered(String authority, String requiredPackageName) {
         int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
-        ProviderInfo providerInfo =
-                mPackageManager.resolveContentProvider(authority, flags);
+        ProviderInfo providerInfo = mPackageManager.resolveContentProviderAsUser(
+                authority, flags, UserHandle.SYSTEM.getIdentifier());
         if (providerInfo == null) {
             Slog.i(TAG, "contentProviderRegistered: No content provider registered with authority="
                     + authority);
@@ -136,7 +137,8 @@
             throws PackageManager.NameNotFoundException {
 
         int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
-        List<ResolveInfo> resolveInfo = mPackageManager.queryBroadcastReceivers(intent, flags);
+        List<ResolveInfo> resolveInfo = mPackageManager.queryBroadcastReceiversAsUser(
+                intent, flags, UserHandle.SYSTEM);
         if (resolveInfo.size() != 1) {
             Slog.i(TAG, "receiverRegistered: Zero or multiple broadcast receiver registered for"
                     + " intent=" + intent + ", found=" + resolveInfo);
diff --git a/services/core/java/com/android/server/timezone/RulesManagerService.java b/services/core/java/com/android/server/timezone/RulesManagerService.java
index 50f27ed..52b49ba 100644
--- a/services/core/java/com/android/server/timezone/RulesManagerService.java
+++ b/services/core/java/com/android/server/timezone/RulesManagerService.java
@@ -47,6 +47,7 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
 import libcore.icu.ICU;
+import libcore.util.TimeZoneFinder;
 import libcore.util.ZoneInfoDB;
 
 import static android.app.timezone.RulesState.DISTRO_STATUS_INSTALLED;
@@ -69,18 +70,22 @@
                     DistroVersion.CURRENT_FORMAT_MINOR_VERSION);
 
     public static class Lifecycle extends SystemService {
-        private RulesManagerService mService;
-
         public Lifecycle(Context context) {
             super(context);
         }
 
         @Override
         public void onStart() {
-            mService = RulesManagerService.create(getContext());
-            mService.start();
+            RulesManagerService service = RulesManagerService.create(getContext());
+            service.start();
 
-            publishBinderService(Context.TIME_ZONE_RULES_MANAGER_SERVICE, mService);
+            // Publish the binder service so it can be accessed from other (appropriately
+            // permissioned) processes.
+            publishBinderService(Context.TIME_ZONE_RULES_MANAGER_SERVICE, service);
+
+            // Publish the service instance locally so we can use it directly from within the system
+            // server from TimeZoneUpdateIdler.
+            publishLocalService(RulesManagerService.class, service);
         }
     }
 
@@ -343,16 +348,20 @@
         @Override
         public void run() {
             EventLogTags.writeTimezoneUninstallStarted(toStringOrNull(mCheckToken));
-            boolean success = false;
+            boolean packageTrackerStatus = false;
             try {
-                success = mInstaller.stageUninstall();
-                // Right now we just have success (0) / failure (1). All clients should be checking
-                // against SUCCESS. More granular failures may be added in future.
-                int resultCode = success ? Callback.SUCCESS
-                        : Callback.ERROR_UNKNOWN_FAILURE;
+                int uninstallResult = mInstaller.stageUninstall();
+                packageTrackerStatus = (uninstallResult == TimeZoneDistroInstaller.UNINSTALL_SUCCESS
+                        || uninstallResult == TimeZoneDistroInstaller.UNINSTALL_NOTHING_INSTALLED);
+
+                // Right now we just have Callback.SUCCESS / Callback.ERROR_UNKNOWN_FAILURE for
+                // uninstall. All clients should be checking against SUCCESS. More granular failures
+                // may be added in future.
+                int callbackResultCode =
+                        packageTrackerStatus ? Callback.SUCCESS : Callback.ERROR_UNKNOWN_FAILURE;
                 EventLogTags.writeTimezoneUninstallComplete(
-                        toStringOrNull(mCheckToken), resultCode);
-                sendFinishedStatus(mCallback, resultCode);
+                        toStringOrNull(mCheckToken), callbackResultCode);
+                sendFinishedStatus(mCallback, callbackResultCode);
             } catch (Exception e) {
                 EventLogTags.writeTimezoneUninstallComplete(
                         toStringOrNull(mCheckToken), Callback.ERROR_UNKNOWN_FAILURE);
@@ -360,7 +369,7 @@
                 sendFinishedStatus(mCallback, Callback.ERROR_UNKNOWN_FAILURE);
             } finally {
                 // Notify the package tracker that the operation is now complete.
-                mPackageTracker.recordCheckResult(mCheckToken, success);
+                mPackageTracker.recordCheckResult(mCheckToken, packageTrackerStatus);
 
                 mOperationInProgress.set(false);
             }
@@ -471,9 +480,10 @@
                         case 'a': {
                             // Report the active rules version (i.e. the rules in use by the current
                             // process).
-                            pw.println("Active rules version (ICU, libcore): "
+                            pw.println("Active rules version (ICU, ZoneInfoDB, TimeZoneFinder): "
                                     + ICU.getTZDataVersion() + ","
-                                    + ZoneInfoDB.getInstance().getVersion());
+                                    + ZoneInfoDB.getInstance().getVersion() + ","
+                                    + TimeZoneFinder.getInstance().getIanaVersion());
                             break;
                         }
                         default: {
@@ -486,12 +496,24 @@
         }
 
         pw.println("RulesManagerService state: " + toString());
-        pw.println("Active rules version (ICU, libcore): " + ICU.getTZDataVersion() + ","
-                + ZoneInfoDB.getInstance().getVersion());
+        pw.println("Active rules version (ICU, ZoneInfoDB, TimeZoneFinder): "
+                + ICU.getTZDataVersion() + ","
+                + ZoneInfoDB.getInstance().getVersion() + ","
+                + TimeZoneFinder.getInstance().getIanaVersion());
         pw.println("Distro state: " + rulesState.toString());
         mPackageTracker.dump(pw);
     }
 
+    /**
+     * Called when the device is considered idle.
+     */
+    void notifyIdle() {
+        // No package has changed: we are just triggering because the device is idle and there
+        // *might* be work to do.
+        final boolean packageChanged = false;
+        mPackageTracker.triggerUpdateIfNeeded(packageChanged);
+    }
+
     @Override
     public String toString() {
         return "RulesManagerService{" +
diff --git a/services/core/java/com/android/server/timezone/TimeZoneUpdateIdler.java b/services/core/java/com/android/server/timezone/TimeZoneUpdateIdler.java
new file mode 100644
index 0000000..a7767a4
--- /dev/null
+++ b/services/core/java/com/android/server/timezone/TimeZoneUpdateIdler.java
@@ -0,0 +1,100 @@
+/*
+ * 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.timezone;
+
+import com.android.server.LocalServices;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Slog;
+
+/**
+ * A JobService used to trigger time zone rules update work when a device falls idle.
+ */
+public final class TimeZoneUpdateIdler extends JobService {
+
+    private static final String TAG = "timezone.TimeZoneUpdateIdler";
+
+    /** The static job ID used to handle on-idle work. */
+    // Must be unique within UID (system service)
+    private static final int TIME_ZONE_UPDATE_IDLE_JOB_ID = 27042305;
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        RulesManagerService rulesManagerService =
+                LocalServices.getService(RulesManagerService.class);
+
+        Slog.d(TAG, "onStartJob() called");
+
+        // Note: notifyIdle() explicitly handles canceling / re-scheduling so no need to reschedule
+        // here.
+        rulesManagerService.notifyIdle();
+
+        // Everything is handled synchronously. We are done.
+        return false;
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        // Reschedule if stopped unless it was cancelled due to unschedule().
+        boolean reschedule = params.getStopReason() != JobParameters.REASON_CANCELED;
+        Slog.d(TAG, "onStopJob() called: Reschedule=" + reschedule);
+        return reschedule;
+    }
+
+    /**
+     * Schedules the TimeZoneUpdateIdler job service to run once.
+     *
+     * @param context Context to use to get a job scheduler.
+     */
+    public static void schedule(Context context, long minimumDelayMillis) {
+        // Request that the JobScheduler tell us when the device falls idle.
+        JobScheduler jobScheduler =
+                (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+
+        // The TimeZoneUpdateIdler will send an intent that will trigger the Receiver.
+        ComponentName idlerJobServiceName =
+                new ComponentName(context, TimeZoneUpdateIdler.class);
+
+        // We require the device is idle, but also that it is charging to be as non-invasive as
+        // we can.
+        JobInfo.Builder jobInfoBuilder =
+                new JobInfo.Builder(TIME_ZONE_UPDATE_IDLE_JOB_ID, idlerJobServiceName)
+                        .setRequiresDeviceIdle(true)
+                        .setRequiresCharging(true)
+                        .setMinimumLatency(minimumDelayMillis);
+
+        Slog.d(TAG, "schedule() called: minimumDelayMillis=" + minimumDelayMillis);
+        jobScheduler.schedule(jobInfoBuilder.build());
+    }
+
+    /**
+     * Unschedules the TimeZoneUpdateIdler job service.
+     *
+     * @param context Context to use to get a job scheduler.
+     */
+    public static void unschedule(Context context) {
+        JobScheduler jobScheduler =
+                (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+        Slog.d(TAG, "unschedule() called");
+        jobScheduler.cancel(TIME_ZONE_UPDATE_IDLE_JOB_ID);
+    }
+}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index e12dc1d..8ce59ed 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -49,6 +49,7 @@
 import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.service.trust.TrustAgentService;
+import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -104,6 +105,7 @@
     private static final int MSG_UNLOCK_USER = 11;
     private static final int MSG_STOP_USER = 12;
     private static final int MSG_DISPATCH_UNLOCK_LOCKOUT = 13;
+    private static final int MSG_REFRESH_DEVICE_LOCKED_FOR_USER = 14;
 
     private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
 
@@ -123,9 +125,13 @@
     @GuardedBy("mDeviceLockedForUser")
     private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
 
-    @GuardedBy("mDeviceLockedForUser")
+    @GuardedBy("mTrustUsuallyManagedForUser")
     private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
 
+    // set to true only if user can skip bouncer
+    @GuardedBy("mUsersUnlockedByFingerprint")
+    private final SparseBooleanArray mUsersUnlockedByFingerprint = new SparseBooleanArray();
+
     private final StrongAuthTracker mStrongAuthTracker;
 
     private boolean mTrustAgentsCanRun = false;
@@ -407,7 +413,6 @@
                     + " must be USER_ALL or a specific user.", new Throwable("here"));
             userId = UserHandle.USER_ALL;
         }
-
         List<UserInfo> userInfos;
         if (userId == UserHandle.USER_ALL) {
             userInfos = mUserManager.getUsers(true /* excludeDying */);
@@ -430,13 +435,19 @@
             boolean secure = mLockPatternUtils.isSecure(id);
             boolean trusted = aggregateIsTrusted(id);
             boolean showingKeyguard = true;
+            boolean fingerprintAuthenticated = false;
+
             if (mCurrentUser == id) {
+                synchronized(mUsersUnlockedByFingerprint) {
+                    fingerprintAuthenticated = mUsersUnlockedByFingerprint.get(id, false);
+                }
                 try {
                     showingKeyguard = wm.isKeyguardLocked();
                 } catch (RemoteException e) {
                 }
             }
-            boolean deviceLocked = secure && showingKeyguard && !trusted;
+            boolean deviceLocked = secure && showingKeyguard && !trusted &&
+                    !fingerprintAuthenticated;
             setDeviceLockedForUser(id, deviceLocked);
         }
     }
@@ -583,16 +594,24 @@
         }
         PackageManager pm = mContext.getPackageManager();
         List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
+        ComponentName defaultAgent = getDefaultFactoryTrustAgent(mContext);
+        boolean shouldUseDefaultAgent = defaultAgent != null;
         ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
-        for (ResolveInfo resolveInfo : resolveInfos) {
-            ComponentName componentName = getComponentName(resolveInfo);
-            int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
-            if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
-                Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
-                        + "is not a system package.");
-                continue;
+
+        if (shouldUseDefaultAgent) {
+            discoveredAgents.add(defaultAgent);
+            Log.i(TAG, "Enabling " + defaultAgent + " because it is a default agent.");
+        } else { // A default agent is not set; perform regular trust agent discovery
+            for (ResolveInfo resolveInfo : resolveInfos) {
+                ComponentName componentName = getComponentName(resolveInfo);
+                int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
+                if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+                    Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
+                            + "is not a system package.");
+                    continue;
+                }
+                discoveredAgents.add(componentName);
             }
-            discoveredAgents.add(componentName);
         }
 
         List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
@@ -604,6 +623,19 @@
                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
     }
 
+    /**
+     * Returns the {@link ComponentName} for the default trust agent, or {@code null} if there
+     * is no trust agent set.
+     */
+    private static ComponentName getDefaultFactoryTrustAgent(Context context) {
+        String defaultTrustAgent = context.getResources()
+            .getString(com.android.internal.R.string.config_defaultTrustAgent);
+        if (TextUtils.isEmpty(defaultTrustAgent)) {
+            return null;
+        }
+        return ComponentName.unflattenFromString(defaultTrustAgent);
+    }
+
     private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
         List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
                 PackageManager.GET_META_DATA |
@@ -965,6 +997,26 @@
                     "query trust state");
             return isTrustUsuallyManagedInternal(userId);
         }
+
+        @Override
+        public void unlockedByFingerprintForUser(int userId) {
+            enforceReportPermission();
+            synchronized(mUsersUnlockedByFingerprint) {
+                mUsersUnlockedByFingerprint.put(userId, true);
+            }
+            mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, userId,
+                    0 /* arg2 */).sendToTarget();
+        }
+
+        @Override
+        public void clearAllFingerprints() {
+            enforceReportPermission();
+            synchronized(mUsersUnlockedByFingerprint) {
+                mUsersUnlockedByFingerprint.clear();
+            }
+            mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, UserHandle.USER_ALL,
+                    0 /* arg2 */).sendToTarget();
+        }
     };
 
     private boolean isTrustUsuallyManagedInternal(int userId) {
@@ -1052,6 +1104,9 @@
                         }
                     }
                     break;
+                case MSG_REFRESH_DEVICE_LOCKED_FOR_USER:
+                    refreshDeviceLockedForUser(msg.arg1);
+                    break;
             }
         }
     };
@@ -1111,6 +1166,9 @@
                     synchronized (mTrustUsuallyManagedForUser) {
                         mTrustUsuallyManagedForUser.delete(userId);
                     }
+                    synchronized (mUsersUnlockedByFingerprint) {
+                        mUsersUnlockedByFingerprint.delete(userId);
+                    }
                     refreshAgentList(userId);
                     refreshDeviceLockedForUser(userId);
                 }
diff --git a/services/core/java/com/android/server/tv/UinputBridge.java b/services/core/java/com/android/server/tv/UinputBridge.java
index f910332..1a984f9 100644
--- a/services/core/java/com/android/server/tv/UinputBridge.java
+++ b/services/core/java/com/android/server/tv/UinputBridge.java
@@ -63,7 +63,7 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            if (mPtr != 0) {
+            if (mCloseGuard != null) {
                 mCloseGuard.warnIfOpen();
             }
             close(mToken);
diff --git a/services/core/java/com/android/server/vr/Vr2dDisplay.java b/services/core/java/com/android/server/vr/Vr2dDisplay.java
index 4a1297f..8f50a39 100644
--- a/services/core/java/com/android/server/vr/Vr2dDisplay.java
+++ b/services/core/java/com/android/server/vr/Vr2dDisplay.java
@@ -24,6 +24,7 @@
 import android.service.vr.IVrManager;
 import android.util.Log;
 import android.view.Surface;
+import android.view.WindowManagerInternal;
 
 import com.android.server.vr.VrManagerService;
 
@@ -35,7 +36,6 @@
     private final static String TAG = "Vr2dDisplay";
     private final static boolean DEBUG = false;
 
-    // TODO: Go over these values and figure out what is best
     private int mVirtualDisplayHeight;
     private int mVirtualDisplayWidth;
     private int mVirtualDisplayDpi;
@@ -55,17 +55,17 @@
     /**
      * The default width of the VR virtual display
      */
-    public static final int DEFAULT_VR_DISPLAY_WIDTH = 1400;
+    public static final int DEFAULT_VIRTUAL_DISPLAY_WIDTH = 1400;
 
     /**
      * The default height of the VR virtual display
      */
-    public static final int DEFAULT_VR_DISPLAY_HEIGHT = 1800;
+    public static final int DEFAULT_VIRTUAL_DISPLAY_HEIGHT = 1800;
 
     /**
      * The default height of the VR virtual dpi.
      */
-    public static final int DEFAULT_VR_DISPLAY_DPI = 320;
+    public static final int DEFAULT_VIRTUAL_DISPLAY_DPI = 320;
 
     /**
      * The minimum height, width and dpi of VR virtual display.
@@ -75,6 +75,7 @@
     public static final int MIN_VR_DISPLAY_DPI = 1;
 
     private final ActivityManagerInternal mActivityManagerInternal;
+    private final WindowManagerInternal mWindowManagerInternal;
     private final DisplayManager mDisplayManager;
     private final IVrManager mVrManager;
     private final Object mVdLock = new Object();
@@ -87,8 +88,8 @@
             new IPersistentVrStateCallbacks.Stub() {
         @Override
         public void onPersistentVrStateChanged(boolean enabled) {
-            if (enabled != mIsVrModeEnabled) {
-                mIsVrModeEnabled = enabled;
+            if (enabled != mIsPersistentVrModeEnabled) {
+                mIsPersistentVrModeEnabled = enabled;
                 updateVirtualDisplay();
             }
         }
@@ -98,25 +99,35 @@
     private Surface mSurface;
     private ImageReader mImageReader;
     private Runnable mStopVDRunnable;
-    private boolean mIsVrModeOverrideEnabled;
-    private boolean mIsVrModeEnabled;
+    private boolean mIsVrModeOverrideEnabled;  // debug override to set vr mode.
+    private boolean mIsVirtualDisplayAllowed = true;  // Virtual-display feature toggle
+    private boolean mIsPersistentVrModeEnabled;  // indicates we are in vr persistent mode.
+    private boolean mBootsToVr = false;  // The device boots into VR (standalone VR device)
 
     public Vr2dDisplay(DisplayManager displayManager,
-           ActivityManagerInternal activityManagerInternal, IVrManager vrManager) {
+           ActivityManagerInternal activityManagerInternal,
+           WindowManagerInternal windowManagerInternal, IVrManager vrManager) {
         mDisplayManager = displayManager;
         mActivityManagerInternal = activityManagerInternal;
+        mWindowManagerInternal = windowManagerInternal;
         mVrManager = vrManager;
-        mVirtualDisplayWidth = DEFAULT_VR_DISPLAY_WIDTH;
-        mVirtualDisplayHeight = DEFAULT_VR_DISPLAY_HEIGHT;
-        mVirtualDisplayDpi = DEFAULT_VR_DISPLAY_DPI;
+        mVirtualDisplayWidth = DEFAULT_VIRTUAL_DISPLAY_WIDTH;
+        mVirtualDisplayHeight = DEFAULT_VIRTUAL_DISPLAY_HEIGHT;
+        mVirtualDisplayDpi = DEFAULT_VIRTUAL_DISPLAY_DPI;
     }
 
     /**
      * Initializes the compabilitiy display by listening to VR mode changes.
      */
-    public void init(Context context) {
+    public void init(Context context, boolean bootsToVr) {
         startVrModeListener();
         startDebugOnlyBroadcastReceiver(context);
+        mBootsToVr = bootsToVr;
+        if (mBootsToVr) {
+          // If we are booting into VR, we need to start the virtual display immediately. This
+          // ensures that the virtual display is up by the time Setup Wizard is started.
+          updateVirtualDisplay();
+        }
     }
 
     /**
@@ -124,10 +135,13 @@
      */
     private void updateVirtualDisplay() {
         if (DEBUG) {
-            Log.i(TAG, "isVrMode: " + mIsVrModeEnabled + ", override: " + mIsVrModeOverrideEnabled);
+            Log.i(TAG, "isVrMode: " + mIsPersistentVrModeEnabled + ", override: "
+                    + mIsVrModeOverrideEnabled + ", isAllowed: " + mIsVirtualDisplayAllowed
+                    + ", bootsToVr: " + mBootsToVr);
         }
 
-        if (mIsVrModeEnabled || mIsVrModeOverrideEnabled) {
+        if (shouldRunVirtualDisplay()) {
+            Log.i(TAG, "Attempting to start virtual display");
             // TODO: Consider not creating the display until ActivityManager needs one on
             // which to display a 2D application.
             startVirtualDisplay();
@@ -190,33 +204,43 @@
      *
      * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
      *
-     * @param compatDisplayProperties Properties of the virtual display for 2D applications
+     * @param displayProperties Properties of the virtual display for 2D applications
      * in VR mode.
      */
-    public void setVirtualDisplayProperties(Vr2dDisplayProperties compatDisplayProperties) {
+    public void setVirtualDisplayProperties(Vr2dDisplayProperties displayProperties) {
         synchronized(mVdLock) {
             if (DEBUG) {
-                Log.i(TAG, "VD setVirtualDisplayProperties: res = "
-                        + compatDisplayProperties.getWidth() + "X"
-                        + compatDisplayProperties.getHeight() + ", dpi = "
-                        + compatDisplayProperties.getDpi());
+                Log.i(TAG, "VD setVirtualDisplayProperties: " +
+                        displayProperties.toString());
             }
 
-            if (compatDisplayProperties.getWidth() < MIN_VR_DISPLAY_WIDTH ||
-                compatDisplayProperties.getHeight() < MIN_VR_DISPLAY_HEIGHT ||
-                compatDisplayProperties.getDpi() < MIN_VR_DISPLAY_DPI) {
-                throw new IllegalArgumentException (
-                        "Illegal argument: height, width, dpi cannot be negative. res = "
-                        + compatDisplayProperties.getWidth() + "X"
-                        + compatDisplayProperties.getHeight()
-                        + ", dpi = " + compatDisplayProperties.getDpi());
+            int width = displayProperties.getWidth();
+            int height = displayProperties.getHeight();
+            int dpi = displayProperties.getDpi();
+            boolean resized = false;
+
+            if (width < MIN_VR_DISPLAY_WIDTH || height < MIN_VR_DISPLAY_HEIGHT ||
+                    dpi < MIN_VR_DISPLAY_DPI) {
+                Log.i(TAG, "Ignoring Width/Height/Dpi values of " + width + "," + height + ","
+                        + dpi);
+            } else {
+                Log.i(TAG, "Setting width/height/dpi to " + width + "," + height + "," + dpi);
+                mVirtualDisplayWidth = width;
+                mVirtualDisplayHeight = height;
+                mVirtualDisplayDpi = dpi;
+                resized = true;
             }
 
-            mVirtualDisplayWidth = compatDisplayProperties.getWidth();
-            mVirtualDisplayHeight = compatDisplayProperties.getHeight();
-            mVirtualDisplayDpi = compatDisplayProperties.getDpi();
+            if ((displayProperties.getFlags() & Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED)
+                    == Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED) {
+                mIsVirtualDisplayAllowed = true;
+            } else if ((displayProperties.getRemovedFlags() &
+                    Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED)
+                    == Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED) {
+                mIsVirtualDisplayAllowed = false;
+            }
 
-            if (mVirtualDisplay != null) {
+            if (mVirtualDisplay != null && resized && mIsVirtualDisplayAllowed) {
                 mVirtualDisplay.resize(mVirtualDisplayWidth, mVirtualDisplayHeight,
                     mVirtualDisplayDpi);
                 ImageReader oldImageReader = mImageReader;
@@ -224,6 +248,9 @@
                 startImageReader();
                 oldImageReader.close();
             }
+
+            // Start/Stop the virtual display in case the updates indicated that we should.
+            updateVirtualDisplay();
         }
     }
 
@@ -266,19 +293,19 @@
             }
 
             int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
+            flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
             mVirtualDisplay = mDisplayManager.createVirtualDisplay(null /* projection */,
                     DISPLAY_NAME, mVirtualDisplayWidth, mVirtualDisplayHeight, mVirtualDisplayDpi,
                     null /* surface */, flags, null /* callback */, null /* handler */,
                     UNIQUE_DISPLAY_ID);
 
             if (mVirtualDisplay != null) {
-                mActivityManagerInternal.setVr2dDisplayId(
-                    mVirtualDisplay.getDisplay().getDisplayId());
+                updateDisplayId(mVirtualDisplay.getDisplay().getDisplayId());
                 // Now create the ImageReader to supply a Surface to the new virtual display.
                 startImageReader();
             } else {
                 Log.w(TAG, "Virtual display id is null after createVirtualDisplay");
-                mActivityManagerInternal.setVr2dDisplayId(INVALID_DISPLAY);
+                updateDisplayId(INVALID_DISPLAY);
                 return;
             }
         }
@@ -286,6 +313,11 @@
         Log.i(TAG, "VD created: " + mVirtualDisplay);
     }
 
+    private void updateDisplayId(int displayId) {
+        mActivityManagerInternal.setVr2dDisplayId(displayId);
+        mWindowManagerInternal.setVr2dDisplayId(displayId);
+    }
+
     /**
      * Stops the virtual display with a {@link #STOP_VIRTUAL_DISPLAY_DELAY_MILLIS} timeout.
      * The timeout prevents the virtual display from bouncing in cases where VrMode goes in and out
@@ -296,12 +328,12 @@
            mStopVDRunnable = new Runnable() {
                @Override
                public void run() {
-                    if (mIsVrModeEnabled) {
+                    if (shouldRunVirtualDisplay()) {
                         Log.i(TAG, "Virtual Display destruction stopped: VrMode is back on.");
                     } else {
                         Log.i(TAG, "Stopping Virtual Display");
                         synchronized (mVdLock) {
-                            mActivityManagerInternal.setVr2dDisplayId(INVALID_DISPLAY);
+                            updateDisplayId(INVALID_DISPLAY);
                             setSurfaceLocked(null); // clean up and release the surface first.
                             if (mVirtualDisplay != null) {
                                 mVirtualDisplay.release();
@@ -365,4 +397,14 @@
             mImageReader = null;
         }
     }
+
+    private boolean shouldRunVirtualDisplay() {
+        // Virtual Display should run whenever:
+        // * Virtual Display is allowed/enabled AND
+        // (1) BootsToVr is set indicating the device never leaves VR
+        // (2) VR (persistent) mode is enabled
+        // (3) VR mode is overridden to be enabled.
+        return mIsVirtualDisplayAllowed &&
+                (mBootsToVr || mIsPersistentVrModeEnabled || mIsVrModeOverrideEnabled);
+    }
 }
diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java
index 1f75640..bdd9de0 100644
--- a/services/core/java/com/android/server/vr/VrManagerInternal.java
+++ b/services/core/java/com/android/server/vr/VrManagerInternal.java
@@ -52,10 +52,11 @@
      * @param enabled {@code true} to enable VR mode.
      * @param packageName The package name of the requested VrListenerService to bind.
      * @param userId the user requesting the VrListenerService component.
+     * @param processId the process the component is running in.
      * @param calling the component currently using VR mode, or null to leave unchanged.
      */
     public abstract void setVrMode(boolean enabled, @NonNull ComponentName packageName,
-            int userId, @NonNull ComponentName calling);
+            int userId, int processId, @NonNull ComponentName calling);
 
     /**
      * Set whether the system has acquired a sleep token.
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index b937f9d..030b74c 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -24,9 +24,12 @@
 import android.app.Vr2dDisplayProperties;
 import android.app.NotificationManager;
 import android.annotation.NonNull;
+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.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -39,6 +42,7 @@
 import android.os.Message;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
@@ -52,6 +56,7 @@
 import android.util.ArraySet;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.WindowManagerInternal;
 
 import com.android.internal.R;
 import com.android.internal.util.DumpUtils;
@@ -121,6 +126,8 @@
     private boolean mVrModeAllowed;
     private boolean mVrModeEnabled;
     private boolean mPersistentVrModeEnabled;
+    private boolean mRunning2dInVr;
+    private int mVrAppProcessId;
     private EnabledComponentsObserver mComponentObserver;
     private ManagedApplicationService mCurrentVrService;
     private ComponentName mDefaultVrService;
@@ -140,7 +147,13 @@
     private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager();
     /** Tracks the state of the screen and keyguard UI.*/
     private int mSystemSleepFlags = FLAG_AWAKE;
+    /**
+     * Set when ACTION_USER_UNLOCKED is fired. We shouldn't try to bind to the
+     * vr service before then.
+     */
+    private boolean mUserUnlocked;
     private Vr2dDisplay mVr2dDisplay;
+    private boolean mBootsToVr;
 
     private static final int MSG_VR_STATE_CHANGE = 0;
     private static final int MSG_PENDING_VR_STATE_CHANGE = 1;
@@ -152,15 +165,20 @@
      * If VR mode is not allowed to be enabled, calls to set VR mode will be cached.  When VR mode
      * is again allowed to be enabled, the most recent cached state will be applied.
      *
-     * @param allowed {@code true} if calling any of the setVrMode methods may cause the device to
-     *   enter VR mode.
      */
-    private void setVrModeAllowedLocked(boolean allowed) {
+    private void updateVrModeAllowedLocked() {
+        boolean allowed = mSystemSleepFlags == FLAG_ALL && mUserUnlocked;
         if (mVrModeAllowed != allowed) {
             mVrModeAllowed = allowed;
             if (DBG) Slog.d(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed"));
             if (mVrModeAllowed) {
+                if (mBootsToVr) {
+                    setPersistentVrModeEnabled(true);
+                }
                 consumeAndApplyPendingStateLocked();
+                if (mBootsToVr && !mVrModeEnabled) {
+                  setVrMode(true, mDefaultVrService, 0, -1, null);
+                }
             } else {
                 // Disable persistent mode when VR mode isn't allowed, allows an escape hatch to
                 // exit persistent VR mode when screen is turned off.
@@ -168,12 +186,12 @@
 
                 // Set pending state to current state.
                 mPendingState = (mVrModeEnabled && mCurrentVrService != null)
-                    ? new VrState(mVrModeEnabled, mCurrentVrService.getComponent(),
-                        mCurrentVrService.getUserId(), mCurrentVrModeComponent)
+                    ? new VrState(mVrModeEnabled, mRunning2dInVr, mCurrentVrService.getComponent(),
+                        mCurrentVrService.getUserId(), mVrAppProcessId, mCurrentVrModeComponent)
                     : null;
 
                 // Unbind current VR service and do necessary callbacks.
-                updateCurrentVrServiceLocked(false, null, 0, null);
+                updateCurrentVrServiceLocked(false, false, null, 0, -1, null);
             }
         }
     }
@@ -187,7 +205,7 @@
                 mSystemSleepFlags &= ~FLAG_AWAKE;
             }
 
-            setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL);
+            updateVrModeAllowedLocked();
         }
     }
 
@@ -198,7 +216,14 @@
             } else {
                 mSystemSleepFlags &= ~FLAG_SCREEN_ON;
             }
-            setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL);
+            updateVrModeAllowedLocked();
+        }
+    }
+
+    private void setUserUnlocked() {
+        synchronized(mLock) {
+            mUserUnlocked = true;
+            updateVrModeAllowedLocked();
         }
     }
 
@@ -248,26 +273,33 @@
 
     private static class VrState {
         final boolean enabled;
+        final boolean running2dInVr;
         final int userId;
+        final int processId;
         final ComponentName targetPackageName;
         final ComponentName callingPackage;
         final long timestamp;
         final boolean defaultPermissionsGranted;
 
-        VrState(boolean enabled, ComponentName targetPackageName, int userId,
-                ComponentName callingPackage) {
+
+        VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId,
+                int processId, ComponentName callingPackage) {
             this.enabled = enabled;
+            this.running2dInVr = running2dInVr;
             this.userId = userId;
+            this.processId = processId;
             this.targetPackageName = targetPackageName;
             this.callingPackage = callingPackage;
             this.defaultPermissionsGranted = false;
             this.timestamp = System.currentTimeMillis();
         }
 
-        VrState(boolean enabled, ComponentName targetPackageName, int userId,
-            ComponentName callingPackage, boolean defaultPermissionsGranted) {
+        VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId,
+            int processId, ComponentName callingPackage, boolean defaultPermissionsGranted) {
             this.enabled = enabled;
+            this.running2dInVr = running2dInVr;
             this.userId = userId;
+            this.processId = processId;
             this.targetPackageName = targetPackageName;
             this.callingPackage = callingPackage;
             this.defaultPermissionsGranted = defaultPermissionsGranted;
@@ -368,8 +400,9 @@
             }
 
             // There is an active service, update it if needed
-            updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(),
-                    mCurrentVrService.getUserId(), mCurrentVrModeComponent);
+            updateCurrentVrServiceLocked(mVrModeEnabled, mRunning2dInVr,
+                    mCurrentVrService.getComponent(), mCurrentVrService.getUserId(),
+                    mVrAppProcessId, mCurrentVrModeComponent);
         }
     }
 
@@ -505,9 +538,9 @@
      */
     private final class LocalService extends VrManagerInternal {
         @Override
-        public void setVrMode(boolean enabled, ComponentName packageName, int userId,
+        public void setVrMode(boolean enabled, ComponentName packageName, int userId, int processId,
                 ComponentName callingPackage) {
-            VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage);
+            VrManagerService.this.setVrMode(enabled, packageName, userId, processId, callingPackage);
         }
 
         @Override
@@ -563,6 +596,7 @@
             mContext = getContext();
         }
 
+        mBootsToVr = SystemProperties.getBoolean("ro.boot.vr", false);
         publishLocalService(VrManagerInternal.class, new LocalService());
         publishBinderService(Context.VR_SERVICE, mVrManager.asBinder());
     }
@@ -594,13 +628,23 @@
 
             DisplayManager dm =
                     (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
-            ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class);
-            mVr2dDisplay = new Vr2dDisplay(dm, ami, mVrManager);
-            mVr2dDisplay.init(getContext());
-        } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
-            synchronized (mLock) {
-                mVrModeAllowed = true;
-            }
+            mVr2dDisplay = new Vr2dDisplay(
+                    dm,
+                    LocalServices.getService(ActivityManagerInternal.class),
+                    LocalServices.getService(WindowManagerInternal.class),
+                    mVrManager);
+            mVr2dDisplay.init(getContext(), mBootsToVr);
+
+            IntentFilter intentFilter = new IntentFilter();
+            intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
+            getContext().registerReceiver(new BroadcastReceiver() {
+                    @Override
+                    public void onReceive(Context context, Intent intent) {
+                        if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
+                            VrManagerService.this.setUserUnlocked();
+                        }
+                    }
+                }, intentFilter);
         }
     }
 
@@ -674,14 +718,16 @@
      * Note: Must be called while holding {@code mLock}.
      *
      * @param enabled new state for VR mode.
+     * @param running2dInVr true if we have a top-level 2D intent.
      * @param component new component to be bound as a VR listener.
      * @param userId user owning the component to be bound.
-     * @param calling the component currently using VR mode.
+     * @param processId the process hosting the activity specified by calling.
+     * @param calling the component currently using VR mode or a 2D intent.
      *
      * @return {@code true} if the component/user combination specified is valid.
      */
-    private boolean updateCurrentVrServiceLocked(boolean enabled, @NonNull ComponentName component,
-            int userId, ComponentName calling) {
+    private boolean updateCurrentVrServiceLocked(boolean enabled, boolean running2dInVr,
+            @NonNull ComponentName component, int userId, int processId, ComponentName calling) {
 
         boolean sendUpdatedCaller = false;
         final long identity = Binder.clearCallingIdentity();
@@ -737,10 +783,13 @@
             }
 
             if ((calling != null || mPersistentVrModeEnabled)
-                    && !Objects.equals(calling, mCurrentVrModeComponent)) {
+                    && !Objects.equals(calling, mCurrentVrModeComponent)
+                    || mRunning2dInVr != running2dInVr) {
                 sendUpdatedCaller = true;
             }
             mCurrentVrModeComponent = calling;
+            mRunning2dInVr = running2dInVr;
+            mVrAppProcessId = processId;
 
             if (mCurrentVrModeUser != userId) {
                 mCurrentVrModeUser = userId;
@@ -758,11 +807,13 @@
 
             if (mCurrentVrService != null && sendUpdatedCaller) {
                 final ComponentName c = mCurrentVrModeComponent;
+                final boolean b = running2dInVr;
+                final int pid = processId;
                 mCurrentVrService.sendEvent(new PendingEvent() {
                     @Override
                     public void runEvent(IInterface service) throws RemoteException {
                         IVrListener l = (IVrListener) service;
-                        l.focusedActivityChanged(c);
+                        l.focusedActivityChanged(c, b, pid);
                     }
                 });
             }
@@ -987,20 +1038,20 @@
      */
     private void consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState) {
         if (mPendingState != null) {
-            updateCurrentVrServiceLocked(mPendingState.enabled,
-                    mPendingState.targetPackageName, mPendingState.userId,
+            updateCurrentVrServiceLocked(mPendingState.enabled, mPendingState.running2dInVr,
+                    mPendingState.targetPackageName, mPendingState.userId, mPendingState.processId,
                     mPendingState.callingPackage);
             mPendingState = null;
         } else if (disconnectIfNoPendingState) {
-            updateCurrentVrServiceLocked(false, null, 0, null);
+            updateCurrentVrServiceLocked(false, false, null, 0, -1, null);
         }
     }
 
     private void logStateLocked() {
         ComponentName currentBoundService = (mCurrentVrService == null) ? null :
             mCurrentVrService.getComponent();
-        VrState current = new VrState(mVrModeEnabled, currentBoundService, mCurrentVrModeUser,
-            mCurrentVrModeComponent, mWasDefaultGranted);
+        VrState current = new VrState(mVrModeEnabled, mRunning2dInVr, currentBoundService,
+            mCurrentVrModeUser, mVrAppProcessId, mCurrentVrModeComponent, mWasDefaultGranted);
         if (mLoggingDeque.size() == EVENT_LOG_SIZE) {
             mLoggingDeque.removeFirst();
         }
@@ -1044,27 +1095,24 @@
      * Implementation of VrManagerInternal calls.  These are callable from system services.
      */
     private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
-            int userId, @NonNull ComponentName callingPackage) {
+            int userId, int processId, @NonNull ComponentName callingPackage) {
 
         synchronized (mLock) {
             VrState pending;
             ComponentName targetListener;
-            ComponentName foregroundVrComponent;
 
             // If the device is in persistent VR mode, then calls to disable VR mode are ignored,
             // and the system default VR listener is used.
             boolean targetEnabledState = enabled || mPersistentVrModeEnabled;
-            if (!enabled && mPersistentVrModeEnabled) {
+            boolean running2dInVr = !enabled && mPersistentVrModeEnabled;
+            if (running2dInVr) {
                 targetListener = mDefaultVrService;
-
-                // Current foreground component isn't a VR one (in 2D app case)
-                foregroundVrComponent = null;
             } else {
                 targetListener = targetPackageName;
-                foregroundVrComponent = callingPackage;
             }
-            pending = new VrState(
-                    targetEnabledState, targetListener, userId, foregroundVrComponent);
+
+            pending = new VrState(targetEnabledState, running2dInVr, targetListener,
+                    userId, processId, callingPackage);
 
             if (!mVrModeAllowed) {
                 // We're not allowed to be in VR mode.  Make this state pending.  This will be
@@ -1089,17 +1137,17 @@
                 mPendingState = null;
             }
 
-            updateCurrentVrServiceLocked(
-                    targetEnabledState, targetListener, userId, foregroundVrComponent);
+            updateCurrentVrServiceLocked(targetEnabledState, running2dInVr, targetListener,
+                    userId, processId, callingPackage);
         }
     }
 
     private void setPersistentVrModeEnabled(boolean enabled) {
         synchronized(mLock) {
             setPersistentModeAndNotifyListenersLocked(enabled);
-            // Disabling persistent mode when not showing a VR should disable the overall vr mode.
-            if (!enabled && mCurrentVrModeComponent == null) {
-                setVrMode(false, null, 0, null);
+            // Disabling persistent mode should disable the overall vr mode.
+            if (!enabled) {
+                setVrMode(false, null, 0, -1, null);
             }
         }
     }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 39b902e..e0ad8f5 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -25,6 +25,7 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
+import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
@@ -32,6 +33,7 @@
 import android.app.IWallpaperManagerCallback;
 import android.app.PendingIntent;
 import android.app.UserSwitchObserver;
+import android.app.WallpaperColors;
 import android.app.WallpaperInfo;
 import android.app.WallpaperManager;
 import android.app.admin.DevicePolicyManager;
@@ -52,6 +54,7 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.BitmapRegionDecoder;
+import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Binder;
@@ -61,9 +64,10 @@
 import android.os.FileUtils;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.IInterface;
 import android.os.IRemoteCallback;
-import android.os.Process;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.SELinux;
@@ -111,6 +115,7 @@
 import java.io.InputStream;
 import java.io.PrintWriter;
 import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
@@ -220,6 +225,7 @@
             // lock-only changes happen on the dedicated lock wallpaper input file
             final boolean sysWallpaperChanged = (mWallpaperFile.equals(changedFile));
             final boolean lockWallpaperChanged = (mWallpaperLockFile.equals(changedFile));
+            int notifyColorsWhich = 0;
             WallpaperData wallpaper = dataForEvent(sysWallpaperChanged, lockWallpaperChanged);
 
             if (DEBUG) {
@@ -241,6 +247,7 @@
                 }
                 SELinux.restorecon(changedFile);
                 notifyLockWallpaperChanged();
+                notifyWallpaperColorsChanged(wallpaper, FLAG_LOCK);
                 return;
             }
 
@@ -285,6 +292,7 @@
                                 // If this was the system wallpaper, rebind...
                                 bindWallpaperComponentLocked(mImageWallpaper, true,
                                         false, wallpaper, null);
+                                notifyColorsWhich |= FLAG_SYSTEM;
                             }
                             if (lockWallpaperChanged
                                     || (wallpaper.whichPending & FLAG_LOCK) != 0) {
@@ -299,12 +307,19 @@
                                 }
                                 // and in any case, tell keyguard about it
                                 notifyLockWallpaperChanged();
+                                notifyColorsWhich |= FLAG_LOCK;
                             }
+
                             saveSettingsLocked(wallpaper.userId);
                         }
                     }
                 }
             }
+
+            // Outside of the lock since it will synchronize itself
+            if (notifyColorsWhich != 0) {
+                notifyWallpaperColorsChanged(wallpaper, notifyColorsWhich);
+            }
         }
     }
 
@@ -319,6 +334,139 @@
         }
     }
 
+    private void notifyWallpaperColorsChanged(@NonNull WallpaperData wallpaper, int which) {
+        boolean needsExtraction;
+        synchronized (mLock) {
+            final RemoteCallbackList<IWallpaperManagerCallback> currentUserColorListeners =
+                    mColorsChangedListeners.get(wallpaper.userId);
+            final RemoteCallbackList<IWallpaperManagerCallback> userAllColorListeners =
+                    mColorsChangedListeners.get(UserHandle.USER_ALL);
+            // No-op until someone is listening to it.
+            if (emptyCallbackList(currentUserColorListeners)  &&
+                    emptyCallbackList(userAllColorListeners)) {
+                return;
+            }
+
+            if (DEBUG) {
+                Slog.v(TAG, "notifyWallpaperColorsChanged " + which);
+            }
+
+            needsExtraction = wallpaper.primaryColors == null;
+        }
+
+        // Let's notify the current values, it's fine if it's null, it just means
+        // that we don't know yet.
+        notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId);
+
+        if (needsExtraction) {
+            extractColors(wallpaper);
+            synchronized (mLock) {
+                // Don't need to notify if nothing changed.
+                if (wallpaper.primaryColors == null) {
+                    return;
+                }
+            }
+            notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId);
+        }
+    }
+
+    private static <T extends IInterface> boolean emptyCallbackList(RemoteCallbackList<T> list) {
+        return (list == null || list.getRegisteredCallbackCount() == 0);
+    }
+
+    private void notifyColorListeners(@NonNull WallpaperColors wallpaperColors, int which,
+            int userId) {
+        final IWallpaperManagerCallback keyguardListener;
+        final ArrayList<IWallpaperManagerCallback> colorListeners = new ArrayList<>();
+        synchronized (mLock) {
+            final RemoteCallbackList<IWallpaperManagerCallback> currentUserColorListeners =
+                    mColorsChangedListeners.get(userId);
+            final RemoteCallbackList<IWallpaperManagerCallback> userAllColorListeners =
+                    mColorsChangedListeners.get(UserHandle.USER_ALL);
+            keyguardListener = mKeyguardListener;
+
+            if (currentUserColorListeners != null) {
+                final int count = currentUserColorListeners.beginBroadcast();
+                for (int i = 0; i < count; i++) {
+                    colorListeners.add(currentUserColorListeners.getBroadcastItem(i));
+                }
+                currentUserColorListeners.finishBroadcast();
+            }
+
+            if (userAllColorListeners != null) {
+                final int count = userAllColorListeners.beginBroadcast();
+                for (int i = 0; i < count; i++) {
+                    colorListeners.add(userAllColorListeners.getBroadcastItem(i));
+                }
+                userAllColorListeners.finishBroadcast();
+            }
+        }
+
+        final int count = colorListeners.size();
+        for (int i = 0; i < count; i++) {
+            try {
+                colorListeners.get(i).onWallpaperColorsChanged(wallpaperColors, which, userId);
+            } catch (RemoteException e) {
+                // Callback is gone, it's not necessary to unregister it since
+                // RemoteCallbackList#getBroadcastItem will take care of it.
+            }
+        }
+
+        if (keyguardListener != null) {
+            try {
+                keyguardListener.onWallpaperColorsChanged(wallpaperColors, which, userId);
+            } catch (RemoteException e) {
+                // Oh well it went away; no big deal
+            }
+        }
+    }
+
+    /**
+     * We can easily extract colors from an ImageWallpaper since it's only a bitmap.
+     * In this case, using the crop is more than enough. Live wallpapers are just ignored.
+     *
+     * @param wallpaper a wallpaper representation
+     */
+    private void extractColors(WallpaperData wallpaper) {
+        String cropFile = null;
+        int wallpaperId;
+
+        synchronized (mLock) {
+            // Not having a wallpaperComponent means it's a lock screen wallpaper.
+            final boolean imageWallpaper = mImageWallpaper.equals(wallpaper.wallpaperComponent)
+                    || wallpaper.wallpaperComponent == null;
+            if (imageWallpaper && wallpaper.cropFile != null && wallpaper.cropFile.exists()) {
+                cropFile = wallpaper.cropFile.getAbsolutePath();
+            }
+            wallpaperId = wallpaper.wallpaperId;
+        }
+
+        WallpaperColors colors = null;
+        if (cropFile != null) {
+            Bitmap bitmap = BitmapFactory.decodeFile(cropFile);
+            if (bitmap != null) {
+                colors = WallpaperColors.fromBitmap(bitmap);
+                bitmap.recycle();
+            }
+        }
+
+        if (colors == null) {
+            Slog.w(TAG, "Cannot extract colors because wallpaper could not be read.");
+            return;
+        }
+
+        synchronized (mLock) {
+            if (wallpaper.wallpaperId == wallpaperId) {
+                wallpaper.primaryColors = colors;
+                // Now that we have the colors, let's save them into the xml
+                // to avoid having to run this again.
+                saveSettingsLocked(wallpaper.userId);
+            } else {
+                Slog.w(TAG, "Not setting primary colors since wallpaper changed");
+            }
+        }
+    }
+
     /**
      * Once a new wallpaper has been written via setWallpaper(...), it needs to be cropped
      * for display.
@@ -482,6 +630,11 @@
     final IPackageManager mIPackageManager;
     final MyPackageMonitor mMonitor;
     final AppOpsManager mAppOpsManager;
+    /**
+     * Map of color listeners per user id.
+     * The key will be the id of a user or UserHandle.USER_ALL - for wildcard listeners.
+     */
+    final SparseArray<RemoteCallbackList<IWallpaperManagerCallback>> mColorsChangedListeners;
     WallpaperData mLastWallpaper;
     IWallpaperManagerCallback mKeyguardListener;
     boolean mWaitingForUnlock;
@@ -558,6 +711,11 @@
          */
         int wallpaperId;
 
+        /**
+         * Primary colors histogram
+         */
+        WallpaperColors primaryColors;
+
         WallpaperConnection connection;
         long lastDiedTime;
         boolean wallpaperUpdating;
@@ -733,6 +891,35 @@
             }
         }
 
+        /**
+         * Called by a live wallpaper if its colors have changed.
+         * @param primaryColors representation of wallpaper primary colors
+         */
+        @Override
+        public void onWallpaperColorsChanged(WallpaperColors primaryColors) {
+            int which;
+            synchronized (mLock) {
+                // Do not broadcast changes on ImageWallpaper since it's handled
+                // internally by this class.
+                if (mImageWallpaper.equals(mWallpaper.wallpaperComponent)) {
+                    return;
+                }
+
+                mWallpaper.primaryColors = primaryColors;
+
+                // Live wallpapers always are system wallpapers.
+                which = FLAG_SYSTEM;
+                // It's also the lock screen wallpaper when we don't have a bitmap in there
+                WallpaperData lockedWallpaper = mLockWallpaperMap.get(mWallpaper.userId);
+                if (lockedWallpaper == null) {
+                    which |= FLAG_LOCK;
+                }
+            }
+            if (which != 0) {
+                notifyWallpaperColorsChanged(mWallpaper, which);
+            }
+        }
+
         @Override
         public void attachEngine(IWallpaperEngine engine) {
             synchronized (mLock) {
@@ -753,6 +940,13 @@
                     }
                     mPaddingChanged = false;
                 }
+                try {
+                    // This will trigger onComputeColors in the wallpaper engine.
+                    // It's fine to be locked in here since the binder is oneway.
+                    mEngine.requestWallpaperColors();
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Failed to request wallpaper colors", e);
+                }
             }
         }
 
@@ -943,6 +1137,7 @@
         mMonitor.register(context, null, UserHandle.ALL, true);
         getWallpaperDir(UserHandle.USER_SYSTEM).mkdirs();
         loadSettingsLocked(UserHandle.USER_SYSTEM, false);
+        mColorsChangedListeners = new SparseArray<>();
     }
 
     private static File getWallpaperDir(int userId) {
@@ -1098,16 +1293,24 @@
     }
 
     void switchUser(int userId, IRemoteCallback reply) {
+        WallpaperData systemWallpaper;
+        WallpaperData lockWallpaper;
         synchronized (mLock) {
             mCurrentUserId = userId;
-            WallpaperData wallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
-            // Not started watching yet, in case wallpaper data was loaded for other reasons.
-            if (wallpaper.wallpaperObserver == null) {
-                wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
-                wallpaper.wallpaperObserver.startWatching();
+            systemWallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
+            lockWallpaper = mLockWallpaperMap.get(userId);
+            if (lockWallpaper == null) {
+                lockWallpaper = systemWallpaper;
             }
-            switchWallpaper(wallpaper, reply);
+            // Not started watching yet, in case wallpaper data was loaded for other reasons.
+            if (systemWallpaper.wallpaperObserver == null) {
+                systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper);
+                systemWallpaper.wallpaperObserver.startWatching();
+            }
+            switchWallpaper(systemWallpaper, reply);
         }
+        notifyWallpaperColorsChanged(systemWallpaper, FLAG_SYSTEM);
+        notifyWallpaperColorsChanged(lockWallpaper, FLAG_LOCK);
     }
 
     void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) {
@@ -1154,8 +1357,21 @@
         userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                 Binder.getCallingUid(), userId, false, true, "clearWallpaper", null);
 
+        WallpaperData data = null;
         synchronized (mLock) {
             clearWallpaperLocked(false, which, userId, null);
+
+            if (which == FLAG_LOCK) {
+                data = mLockWallpaperMap.get(userId);
+            }
+            if (which == FLAG_SYSTEM || data == null) {
+                data = mWallpaperMap.get(userId);
+            }
+        }
+
+        // When clearing a wallpaper, broadcast new valid colors
+        if (data != null) {
+            notifyWallpaperColorsChanged(data, which);
         }
     }
 
@@ -1211,6 +1427,7 @@
 
             RuntimeException e = null;
             try {
+                wallpaper.primaryColors = null;
                 wallpaper.imageWallpaperPending = false;
                 if (userId != mCurrentUserId) return;
                 if (bindWallpaperComponentLocked(defaultFailed
@@ -1449,6 +1666,34 @@
     }
 
     @Override
+    public void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId) {
+        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+                userId, true, true, "registerWallpaperColorsCallback", null);
+        synchronized (mLock) {
+            RemoteCallbackList<IWallpaperManagerCallback> userColorsChangedListeners =
+                    mColorsChangedListeners.get(userId);
+            if (userColorsChangedListeners == null) {
+                userColorsChangedListeners = new RemoteCallbackList<>();
+                mColorsChangedListeners.put(userId, userColorsChangedListeners);
+            }
+            userColorsChangedListeners.register(cb);
+        }
+    }
+
+    @Override
+    public void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId) {
+        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+                userId, true, true, "unregisterWallpaperColorsCallback", null);
+        synchronized (mLock) {
+            final RemoteCallbackList<IWallpaperManagerCallback> userColorsChangedListeners =
+                    mColorsChangedListeners.get(userId);
+            if (userColorsChangedListeners != null) {
+                userColorsChangedListeners.unregister(cb);
+            }
+        }
+    }
+
+    @Override
     public boolean setLockWallpaperCallback(IWallpaperManagerCallback cb) {
         checkPermission(android.Manifest.permission.INTERNAL_SYSTEM_WINDOW);
         synchronized (mLock) {
@@ -1458,6 +1703,43 @@
     }
 
     @Override
+    public WallpaperColors getWallpaperColors(int which, int userId) throws RemoteException {
+        if (which != FLAG_LOCK && which != FLAG_SYSTEM) {
+            throw new IllegalArgumentException("which should be either FLAG_LOCK or FLAG_SYSTEM");
+        }
+        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+                userId, false, true, "getWallpaperColors", null);
+
+        WallpaperData wallpaperData = null;
+        boolean shouldExtract;
+
+        synchronized (mLock) {
+            if (which == FLAG_LOCK) {
+                wallpaperData = mLockWallpaperMap.get(userId);
+            }
+
+            // Try to get the system wallpaper anyway since it might
+            // also be the lock screen wallpaper
+            if (wallpaperData == null) {
+                wallpaperData = mWallpaperMap.get(userId);
+            }
+
+            if (wallpaperData == null) {
+                return null;
+            }
+            shouldExtract = wallpaperData.primaryColors == null;
+        }
+
+        if (shouldExtract) {
+            extractColors(wallpaperData);
+        }
+
+        synchronized (mLock) {
+            return wallpaperData.primaryColors;
+        }
+    }
+
+    @Override
     public ParcelFileDescriptor setWallpaper(String name, String callingPackage,
             Rect cropHint, boolean allowBackup, Bundle extras, int which,
             IWallpaperManagerCallback completion, int userId) {
@@ -1536,6 +1818,7 @@
         lockWP.width = sysWP.width;
         lockWP.height = sysWP.height;
         lockWP.allowBackup = sysWP.allowBackup;
+        lockWP.primaryColors = sysWP.primaryColors;
 
         // Migrate the bitmap files outright; no need to copy
         try {
@@ -1573,6 +1856,8 @@
             if (extras != null) {
                 extras.putInt(WallpaperManager.EXTRA_NEW_WALLPAPER_ID, wallpaper.wallpaperId);
             }
+            // Nullify field to require new computation
+            wallpaper.primaryColors = null;
             if (DEBUG) {
                 Slog.v(TAG, "updateWallpaperBitmapLocked() : id=" + wallpaper.wallpaperId
                         + " name=" + name + " file=" + wallpaper.wallpaperFile.getName());
@@ -1604,9 +1889,13 @@
                 false /* all */, true /* full */, "changing live wallpaper", null /* pkg */);
         checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
 
+        int which = FLAG_SYSTEM;
+        boolean shouldNotifyColors = false;
+        WallpaperData wallpaper;
+
         synchronized (mLock) {
             if (DEBUG) Slog.v(TAG, "setWallpaperComponent name=" + name);
-            WallpaperData wallpaper = mWallpaperMap.get(userId);
+            wallpaper = mWallpaperMap.get(userId);
             if (wallpaper == null) {
                 throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
             }
@@ -1624,16 +1913,47 @@
                 }
             }
 
+            // New live wallpaper is also a lock wallpaper if nothing is set
+            if (mLockWallpaperMap.get(userId) == null) {
+                which |= FLAG_LOCK;
+            }
+
             try {
                 wallpaper.imageWallpaperPending = false;
+                boolean same = changingToSame(name, wallpaper);
                 if (bindWallpaperComponentLocked(name, false, true, wallpaper, null)) {
+                    if (!same) {
+                        wallpaper.primaryColors = null;
+                    }
                     wallpaper.wallpaperId = makeWallpaperIdLocked();
                     notifyCallbacksLocked(wallpaper);
+                    shouldNotifyColors = true;
                 }
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
         }
+
+        if (shouldNotifyColors) {
+            notifyWallpaperColorsChanged(wallpaper, which);
+        }
+    }
+
+    private boolean changingToSame(ComponentName componentName, WallpaperData wallpaper) {
+        if (wallpaper.connection != null) {
+            if (wallpaper.wallpaperComponent == null) {
+                if (componentName == null) {
+                    if (DEBUG) Slog.v(TAG, "changingToSame: still using default");
+                    // Still using default wallpaper.
+                    return true;
+                }
+            } else if (wallpaper.wallpaperComponent.equals(componentName)) {
+                // Changing to same wallpaper.
+                if (DEBUG) Slog.v(TAG, "same wallpaper");
+                return true;
+            }
+        }
+        return false;
     }
 
     boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
@@ -1642,20 +1962,8 @@
             Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
         }
         // Has the component changed?
-        if (!force) {
-            if (wallpaper.connection != null) {
-                if (wallpaper.wallpaperComponent == null) {
-                    if (componentName == null) {
-                        if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
-                        // Still using default wallpaper.
-                        return true;
-                    }
-                } else if (wallpaper.wallpaperComponent.equals(componentName)) {
-                    // Changing to same wallpaper.
-                    if (DEBUG) Slog.v(TAG, "same wallpaper");
-                    return true;
-                }
-            }
+        if (!force && changingToSame(componentName, wallpaper)) {
+            return true;
         }
 
         try {
@@ -1837,6 +2145,7 @@
             }
         }
         wallpaper.callbacks.finishBroadcast();
+
         final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
         mContext.sendBroadcastAsUser(intent, new UserHandle(mCurrentUserId));
     }
@@ -1927,6 +2236,9 @@
 
     private void writeWallpaperAttributes(XmlSerializer out, String tag, WallpaperData wallpaper)
             throws IllegalArgumentException, IllegalStateException, IOException {
+        if (DEBUG) {
+            Slog.v(TAG, "writeWallpaperAttributes");
+        }
         out.startTag(null, tag);
         out.attribute(null, "id", Integer.toString(wallpaper.wallpaperId));
         out.attribute(null, "width", Integer.toString(wallpaper.width));
@@ -1950,6 +2262,19 @@
             out.attribute(null, "paddingBottom", Integer.toString(wallpaper.padding.bottom));
         }
 
+        if (wallpaper.primaryColors != null) {
+            int colorsCount = wallpaper.primaryColors.getMainColors().size();
+            out.attribute(null, "colorsCount", Integer.toString(colorsCount));
+            if (colorsCount > 0) {
+                for (int i = 0; i < colorsCount; i++) {
+                    final Color wc = wallpaper.primaryColors.getMainColors().get(i);
+                    out.attribute(null, "colorValue"+i, Integer.toString(wc.toArgb()));
+                }
+            }
+            out.attribute(null, "colorHints",
+                    Integer.toString(wallpaper.primaryColors.getColorHints()));
+        }
+
         out.attribute(null, "name", wallpaper.name);
         if (wallpaper.wallpaperComponent != null
                 && !wallpaper.wallpaperComponent.equals(mImageWallpaper)) {
@@ -2081,6 +2406,7 @@
                             Slog.v(TAG, "mWidth:" + wallpaper.width);
                             Slog.v(TAG, "mHeight:" + wallpaper.height);
                             Slog.v(TAG, "cropRect:" + wallpaper.cropHint);
+                            Slog.v(TAG, "primaryColors:" + wallpaper.primaryColors);
                             Slog.v(TAG, "mName:" + wallpaper.name);
                             Slog.v(TAG, "mNextWallpaperComponent:"
                                     + wallpaper.nextWallpaperComponent);
@@ -2179,6 +2505,24 @@
         wallpaper.padding.top = getAttributeInt(parser, "paddingTop", 0);
         wallpaper.padding.right = getAttributeInt(parser, "paddingRight", 0);
         wallpaper.padding.bottom = getAttributeInt(parser, "paddingBottom", 0);
+        int colorsCount = getAttributeInt(parser, "colorsCount", 0);
+        if (colorsCount > 0) {
+            Color primary = null, secondary = null, tertiary = null;
+            for (int i = 0; i < colorsCount; i++) {
+                Color color = Color.valueOf(getAttributeInt(parser, "colorValue" + i, 0));
+                if (i == 0) {
+                    primary = color;
+                } else if (i == 1) {
+                    secondary = color;
+                } else if (i == 2) {
+                    tertiary = color;
+                } else {
+                    break;
+                }
+            }
+            int colorHints = getAttributeInt(parser, "colorHints", 0);
+            wallpaper.primaryColors = new WallpaperColors(primary, secondary, tertiary, colorHints);
+        }
         wallpaper.name = parser.getAttributeValue(null, "name");
         wallpaper.allowBackup = "true".equals(parser.getAttributeValue(null, "backup"));
     }
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index fe90ba9..d4949b6 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -278,6 +278,7 @@
         pw.println("Current WebView Update Service state");
         pw.println(String.format("  Fallback logic enabled: %b",
                 mSystemInterface.isFallbackLogicEnabled()));
+        pw.println(String.format("  Multiprocess enabled: %b", isMultiProcessEnabled()));
         mWebViewUpdater.dumpState(pw);
     }
 }
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdater.java b/services/core/java/com/android/server/webkit/WebViewUpdater.java
index 37479c8..203bbf6 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdater.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdater.java
@@ -68,7 +68,7 @@
     // The WebView package currently in use (or the one we are preparing).
     private PackageInfo mCurrentWebViewPackage = null;
 
-    private Object mLock = new Object();
+    private final Object mLock = new Object();
 
     WebViewUpdater(Context context, SystemInterface systemInterface) {
         mContext = context;
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index f138add..805250a 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -16,6 +16,9 @@
 
 package com.android.server.wm;
 
+import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
+
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
@@ -418,13 +421,7 @@
         public MagnificationSpec getMagnificationSpecForWindowLocked(WindowState windowState) {
             MagnificationSpec spec = mMagnifedViewport.getMagnificationSpecLocked();
             if (spec != null && !spec.isNop()) {
-                WindowManagerPolicy policy = mWindowManagerService.mPolicy;
-                final int windowType = windowState.mAttrs.type;
-                if (!policy.isTopLevelWindow(windowType) && windowState.isChildWindow()
-                        && !policy.canMagnifyWindow(windowType)) {
-                    return null;
-                }
-                if (!policy.canMagnifyWindow(windowState.mAttrs.type)) {
+                if (!mWindowManagerService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) {
                     return null;
                 }
             }
@@ -540,8 +537,9 @@
                 final int visibleWindowCount = visibleWindows.size();
                 for (int i = visibleWindowCount - 1; i >= 0; i--) {
                     WindowState windowState = visibleWindows.valueAt(i);
-                    if (windowState.mAttrs.type == WindowManager
-                            .LayoutParams.TYPE_MAGNIFICATION_OVERLAY) {
+                    if ((windowState.mAttrs.type == TYPE_MAGNIFICATION_OVERLAY)
+                            || ((windowState.mAttrs.privateFlags
+                            & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0)) {
                         continue;
                     }
 
@@ -715,7 +713,7 @@
                     mSurfaceControl.setLayerStack(mWindowManager.getDefaultDisplay()
                             .getLayerStack());
                     mSurfaceControl.setLayer(mWindowManagerService.mPolicy.getWindowLayerFromTypeLw(
-                            WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY)
+                            TYPE_MAGNIFICATION_OVERLAY)
                             * WindowManagerService.TYPE_LAYER_MULTIPLIER);
                     mSurfaceControl.setPosition(0, 0);
                     mSurface.copyFrom(mSurfaceControl);
@@ -1313,7 +1311,7 @@
                     && windowType != WindowManager.LayoutParams.TYPE_DRAG
                     && windowType != WindowManager.LayoutParams.TYPE_INPUT_CONSUMER
                     && windowType != WindowManager.LayoutParams.TYPE_POINTER
-                    && windowType != WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY
+                    && windowType != TYPE_MAGNIFICATION_OVERLAY
                     && windowType != WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
                     && windowType != WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY
                     && windowType != WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION);
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index f769261..ddbbde1 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -198,6 +198,14 @@
         return animation != null || mAppToken.inPendingTransaction;
     }
 
+    /**
+     * @return whether an animation is about to start, i.e. the animation is set already but we
+     *         haven't processed the first frame yet.
+     */
+    boolean isAnimationStarting() {
+        return animation != null && !animating;
+    }
+
     public int getTransit() {
         return mTransit;
     }
@@ -350,7 +358,7 @@
 
     // This must be called while inside a transaction.
     boolean stepAnimationLocked(long currentTime) {
-        if (mService.okToDisplay()) {
+        if (mService.okToAnimate()) {
             // We will run animations as long as the display isn't frozen.
 
             if (animation == sDummyAnimation) {
@@ -416,6 +424,7 @@
         if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + mAppToken
                 + ": reportedVisible=" + mAppToken.reportedVisible
                 + " okToDisplay=" + mService.okToDisplay()
+                + " okToAnimate=" + mService.okToAnimate()
                 + " startingDisplayed=" + mAppToken.startingDisplayed);
 
         transformation.clear();
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 5f34c60..e9696d2 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -115,41 +115,6 @@
         mListener.onWindowsGone();
     };
 
-    private final Runnable mRemoveStartingWindow = () -> {
-        StartingSurface surface = null;
-        synchronized (mWindowMap) {
-            if (mContainer == null) {
-                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "mContainer was null while trying to"
-                        + " remove starting window");
-                return;
-            }
-            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Remove starting " + mContainer
-                    + ": startingWindow=" + mContainer.startingWindow
-                    + " startingView=" + mContainer.startingSurface);
-            if (mContainer.startingData != null) {
-                surface = mContainer.startingSurface;
-                mContainer.startingData = null;
-                mContainer.startingSurface = null;
-                mContainer.startingWindow = null;
-                mContainer.startingDisplayed = false;
-                if (surface == null && DEBUG_STARTING_WINDOW) {
-                    Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't "
-                            + "remove");
-                }
-            } else if (DEBUG_STARTING_WINDOW) {
-                Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:"
-                        + mContainer);
-            }
-        }
-        if (surface != null) {
-            try {
-                surface.remove();
-            } catch (Exception e) {
-                Slog.w(TAG_WM, "Exception when removing starting window", e);
-            }
-        }
-    };
-
     private final Runnable mAddStartingWindow = () -> {
         final StartingData startingData;
         final AppWindowToken container;
@@ -436,7 +401,7 @@
 
             // If we are preparing an app transition, then delay changing
             // the visibility of this token until we execute that transition.
-            if (mService.okToDisplay() && mService.mAppTransition.isTransitionSet()) {
+            if (mService.okToAnimate() && mService.mAppTransition.isTransitionSet()) {
                 // A dummy animation is a placeholder animation which informs others that an
                 // animation is going on (in this case an application transition). If the animation
                 // was transferred from another application/animator, no dummy animator should be
@@ -522,9 +487,8 @@
             }
 
             final WindowState mainWin = mContainer.findMainWindow();
-            if (mainWin != null && mainWin.isVisible() && mainWin.isDrawnLw()) {
-                // App already has a visible window that is drawn...why would you want a starting
-                // window?
+            if (mainWin != null && mainWin.mWinAnimator.getShown()) {
+                // App already has a visible window...why would you want a starting window?
                 return false;
             }
 
@@ -614,7 +578,7 @@
             return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
         } else if (taskSwitch && allowTaskSnapshot) {
             return snapshot == null ? STARTING_WINDOW_TYPE_NONE
-                    : snapshotOrientationSameAsDisplay(snapshot) || fromRecents
+                    : snapshotOrientationSameAsTask(snapshot) || fromRecents
                             ? STARTING_WINDOW_TYPE_SNAPSHOT : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
         } else {
             return STARTING_WINDOW_TYPE_NONE;
@@ -640,35 +604,15 @@
         return true;
     }
 
-    private boolean snapshotOrientationSameAsDisplay(TaskSnapshot snapshot) {
+    private boolean snapshotOrientationSameAsTask(TaskSnapshot snapshot) {
         if (snapshot == null) {
             return false;
         }
-        final Rect rect = new Rect(0, 0, snapshot.getSnapshot().getWidth(),
-                snapshot.getSnapshot().getHeight());
-        rect.inset(snapshot.getContentInsets());
-        final Rect taskBoundsWithoutInsets = new Rect();
-        mContainer.getTask().getBounds(taskBoundsWithoutInsets);
-        final DisplayInfo di = mContainer.getDisplayContent().getDisplayInfo();
-        final Rect displayBounds = new Rect(0, 0, di.logicalWidth, di.logicalHeight);
-        final Rect stableInsets = new Rect();
-        mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
-                stableInsets);
-        displayBounds.inset(stableInsets);
-        final boolean snapshotInLandscape = rect.width() >= rect.height();
-        final boolean displayInLandscape = displayBounds.width() >= displayBounds.height();
-        return snapshotInLandscape == displayInLandscape;
+        return mContainer.getTask().getConfiguration().orientation == snapshot.getOrientation();
     }
 
     public void removeStartingWindow() {
         synchronized (mWindowMap) {
-            if (mHandler.hasCallbacks(mRemoveStartingWindow)) {
-                // Already scheduled.
-                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Trying to remove starting window but "
-                        + "already scheduled");
-                return;
-            }
-
             if (mContainer.startingWindow == null) {
                 if (mContainer.startingData != null) {
                     // Starting window has not been added yet, but it is scheduled to be added.
@@ -680,9 +624,39 @@
                 return;
             }
 
+            final StartingSurface surface;
+            if (mContainer.startingData != null) {
+                surface = mContainer.startingSurface;
+                mContainer.startingData = null;
+                mContainer.startingSurface = null;
+                mContainer.startingWindow = null;
+                mContainer.startingDisplayed = false;
+                if (surface == null && DEBUG_STARTING_WINDOW) {
+                    Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't "
+                            + "remove");
+                }
+            } else {
+                if (DEBUG_STARTING_WINDOW) {
+                    Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:"
+                            + mContainer);
+                }
+                return;
+            }
+
             if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Schedule remove starting " + mContainer
-                    + " startingWindow=" + mContainer.startingWindow);
-            mHandler.post(mRemoveStartingWindow);
+                    + " startingWindow=" + mContainer.startingWindow
+                    + " startingView=" + mContainer.startingSurface);
+
+            // Use the same thread to remove the window as we used to add it, as otherwise we end up
+            // with things in the view hierarchy being called from different threads.
+            mHandler.post(() -> {
+                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Removing startingView=" + surface);
+                try {
+                    surface.remove();
+                } catch (Exception e) {
+                    Slog.w(TAG_WM, "Exception when removing starting window", e);
+                }
+            });
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index bd37934..d176d94 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -72,8 +72,6 @@
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 
-import static android.os.Build.VERSION_CODES.O;
-
 class AppTokenList extends ArrayList<AppWindowToken> {
 }
 
@@ -193,6 +191,11 @@
 
     Task mLastParent;
 
+    /**
+     * See {@link #canTurnScreenOn()}
+     */
+    private boolean mCanTurnScreenOn = true;
+
     AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
             DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen,
             boolean showForAllUsers, int targetSdk, int orientation, int rotationAnimationHint,
@@ -290,7 +293,7 @@
         boolean nowGone = mReportedVisibilityResults.nowGone;
 
         boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
-        boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
+        boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting && !hidden;
         if (!nowGone) {
             // If the app is not yet gone, then it can only become visible/drawn.
             if (!nowDrawn) {
@@ -431,11 +434,18 @@
                 mEnteringAnimation = true;
                 mService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(token);
             }
+
             // If we are hidden but there is no delay needed we immediately
             // apply the Surface transaction so that the ActivityManager
-            // can have some guarantee on the Surface state
-            // following setting the visibility.
-            if (hidden && !delayed) {
+            // can have some guarantee on the Surface state following
+            // setting the visibility. This captures cases like dismissing
+            // the docked or pinned stack where there is no app transition.
+            //
+            // In the case of a "Null" animation, there will be
+            // no animation but there will still be a transition set.
+            // We still need to delay hiding the surface such that it
+            // can be synchronized with showing the next surface in the transition.
+            if (hidden && !delayed && !mService.mAppTransition.isTransitionSet()) {
                 SurfaceControl.openTransaction();
                 for (int i = mChildren.size() - 1; i >= 0; i--) {
                     mChildren.get(i).mWinAnimator.hide("immediately hidden");
@@ -637,6 +647,8 @@
         if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
                 + " " + this);
         mAppStopped = false;
+        // Allow the window to turn the screen on once the app is resumed again.
+        setCanTurnScreenOn(true);
         if (!wasStopped) {
             destroySurfaces(true /*cleanupOnResume*/);
         }
@@ -937,8 +949,6 @@
             // Update keyguard flags upon finishing relaunch.
             checkKeyguardFlagsChanged();
         }
-
-        updateAllDrawn();
     }
 
     void clearRelaunching() {
@@ -1281,15 +1291,6 @@
      */
     @Override
     int getOrientation(int candidate) {
-        // We do not allow non-fullscreen apps to influence orientation beyond O. While we do
-        // throw an exception in {@link Activity#onCreate} and
-        // {@link Activity#setRequestedOrientation}, we also ignore the orientation here so that
-        // other calculations aren't affected.
-        if (!fillsParent() && mTargetSdk > O) {
-            // Can't specify orientation if app doesn't fill parent.
-            return SCREEN_ORIENTATION_UNSET;
-        }
-
         if (candidate == SCREEN_ORIENTATION_BEHIND) {
             // Allow app to specify orientation regardless of its visibility state if the current
             // candidate want us to use orientation behind. I.e. the visible app on-top of this one
@@ -1301,7 +1302,7 @@
         // going to the bottom. Allowing closing {@link AppWindowToken} to participate can lead to
         // an Activity in another task being started in the wrong orientation during the transition.
         if (!(sendingToBottom || mService.mClosingApps.contains(this))
-                && (isVisible() || mService.mOpeningApps.contains(this))) {
+                && (isVisible() || mService.mOpeningApps.contains(this) || isOnTop())) {
             return mOrientation;
         }
 
@@ -1344,12 +1345,41 @@
         }
     }
 
+    /**
+     * Returns whether the drawn window states of this {@link AppWindowToken} has considered every
+     * child {@link WindowState}. A child is considered if it has been passed into
+     * {@link #updateDrawnWindowStates(WindowState)} after being added. This is used to determine
+     * whether states, such as {@code allDrawn}, can be set, which relies on state variables such as
+     * {@code mNumInterestingWindows}, which depend on all {@link WindowState}s being considered.
+     *
+     * @return {@code true} If all children have been considered, {@code false}.
+     */
+    private boolean allDrawnStatesConsidered() {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowState child = mChildren.get(i);
+            if (child.mightAffectAllDrawn(false /*visibleOnly*/ )
+                    && !child.getDrawnStateEvaluated()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     *  Determines if the token has finished drawing. This should only be called from
+     *  {@link DisplayContent#applySurfaceChangesTransaction}
+     */
     void updateAllDrawn() {
         if (!allDrawn) {
             // Number of drawn windows can be less when a window is being relaunched, wait for
-            // all windows to be launched and drawn for this token be considered all drawn
+            // all windows to be launched and drawn for this token be considered all drawn.
             final int numInteresting = mNumInterestingWindows;
-            if (numInteresting > 0 && mNumDrawnWindows >= numInteresting && !isRelaunching()) {
+
+            // We must make sure that all present children have been considered (determined by
+            // {@link #allDrawnStatesConsidered}) before evaluating whether everything has been
+            // drawn.
+            if (numInteresting > 0 && allDrawnStatesConsidered()
+                    && mNumDrawnWindows >= numInteresting && !isRelaunching()) {
                 if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawn: " + this
                         + " interesting=" + numInteresting + " drawn=" + mNumDrawnWindows);
                 allDrawn = true;
@@ -1394,6 +1424,8 @@
      *         windows in this app token where not considered drawn as of the last pass.
      */
     boolean updateDrawnWindowStates(WindowState w) {
+        w.setDrawnStateEvaluated(true /*evaluated*/);
+
         if (DEBUG_STARTING_WINDOW_VERBOSE && w == startingWindow) {
             Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + w.isOnScreen()
                     + " allDrawn=" + allDrawn + " freezingScreen=" + mAppAnimator.freezingScreen);
@@ -1571,6 +1603,17 @@
         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--) {
@@ -1594,6 +1637,24 @@
     }
 
     /**
+     * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()}
+     */
+    void setCanTurnScreenOn(boolean canTurnScreenOn) {
+        mCanTurnScreenOn = canTurnScreenOn;
+    }
+
+    /**
+     * Indicates whether the current launch can turn the screen on. This is to prevent multiple
+     * relayouts from turning the screen back on. The screen should only turn on at most
+     * once per activity resume.
+     *
+     * @return true if the screen can be turned on.
+     */
+    boolean canTurnScreenOn() {
+        return mCanTurnScreenOn;
+    }
+
+    /**
      * Retrieves whether we'd like to generate a snapshot that's based solely on the theme. This is
      * the case when preview screenshots are disabled {@link #setDisablePreviewScreenshots} or when
      * we can't take a snapshot for other reasons, for example, if we have a secure window.
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java
index 015c084..708973d 100644
--- a/services/core/java/com/android/server/wm/DimLayer.java
+++ b/services/core/java/com/android/server/wm/DimLayer.java
@@ -81,6 +81,12 @@
         boolean isAttachedToDisplay();
         /** Gets the bounds of the dim layer user. */
         void getDimBounds(Rect outBounds);
+        /** Returns the layer to place a dim layer. */
+        default int getLayerForDim(WindowStateAnimator animator, int layerOffset,
+                int defaultLayer) {
+            return defaultLayer;
+        }
+
         String toShortString();
     }
     /** The user of this dim layer. */
diff --git a/services/core/java/com/android/server/wm/DimLayerController.java b/services/core/java/com/android/server/wm/DimLayerController.java
index d44cd13..7414928 100644
--- a/services/core/java/com/android/server/wm/DimLayerController.java
+++ b/services/core/java/com/android/server/wm/DimLayerController.java
@@ -261,7 +261,8 @@
                 dimLayer = state.animator.mAnimLayer + LAYER_OFFSET_DIM;
                 dimAmount = DEFAULT_DIM_AMOUNT_DEAD_WINDOW;
             } else {
-                dimLayer = state.animator.mAnimLayer - LAYER_OFFSET_DIM;
+                dimLayer = dimLayerUser.getLayerForDim(state.animator, LAYER_OFFSET_DIM,
+                        state.animator.mAnimLayer - LAYER_OFFSET_DIM);
                 dimAmount = state.animator.mWin.mAttrs.dimAmount;
             }
         }
@@ -289,7 +290,7 @@
             state.dimLayer.setLayer(dimLayer);
         }
         if (state.dimLayer.isAnimating()) {
-            if (!mDisplayContent.mService.okToDisplay()) {
+            if (!mDisplayContent.mService.okToAnimate()) {
                 // Jump to the end of the animation.
                 state.dimLayer.show();
             } else {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 54983c8..5bc4a6b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -210,6 +210,7 @@
     final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
     /** @see #computeCompatSmallestWidth(boolean, int, int, int, int) */
     private final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
+
     /**
      * Compat metrics computed based on {@link #mDisplayMetrics}.
      * @see #updateDisplayAndOrientation(int)
@@ -226,6 +227,7 @@
      * @see #updateRotationUnchecked(boolean)
      */
     private int mRotation = 0;
+
     /**
      * Last applied orientation of the display.
      * Constants as per {@link android.content.pm.ActivityInfo.ScreenOrientation}.
@@ -233,6 +235,7 @@
      * @see WindowManagerService#updateOrientationFromAppTokensLocked(boolean, int)
      */
     private int mLastOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+
     /**
      * Flag indicating that the application is receiving an orientation that has different metrics
      * than it expected. E.g. Portrait instead of Landscape.
@@ -240,6 +243,7 @@
      * @see #updateRotationUnchecked(boolean)
      */
     private boolean mAltOrientation = false;
+
     /**
      * Orientation forced by some window. If there is no visible window that specifies orientation
      * it is set to {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}.
@@ -247,6 +251,7 @@
      * @see NonAppWindowContainers#getOrientation()
      */
     private int mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+
     /**
      * Last orientation forced by the keyguard. It is applied when keyguard is shown and is not
      * occluded.
@@ -255,6 +260,11 @@
      */
     private int mLastKeyguardForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
 
+    /**
+     * Keep track of wallpaper visibility to notify changes.
+     */
+    private boolean mLastWallpaperVisible = false;
+
     private Rect mBaseDisplayRect = new Rect();
     private Rect mContentRect = new Rect();
 
@@ -1063,7 +1073,7 @@
             }
             if (w.mHasSurface && !rotateSeamlessly) {
                 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Set mOrientationChanging of " + w);
-                w.mOrientationChanging = true;
+                w.setOrientationChanging(true);
                 mService.mRoot.mOrientationChangeComplete = false;
                 w.mLastFreezeDuration = 0;
             }
@@ -1173,6 +1183,7 @@
         final int dh = displayInfo.logicalHeight;
         config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
                 Configuration.ORIENTATION_LANDSCAPE;
+
         config.screenWidthDp =
                 (int)(mService.mPolicy.getConfigDisplayWidth(dw, dh, displayInfo.rotation,
                         config.uiMode, mDisplayId) / mDisplayMetrics.density);
@@ -1207,7 +1218,7 @@
                 (displayInfo.isHdr()
                         ? Configuration.COLOR_MODE_HDR_YES
                         : Configuration.COLOR_MODE_HDR_NO)
-                        | (displayInfo.isWideColorGamut()
+                        | (displayInfo.isWideColorGamut() && mService.hasWideColorGamutSupport()
                         ? Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_YES
                         : Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_NO);
 
@@ -2667,10 +2678,10 @@
         mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
 
         forAllWindows(w -> {
-            if (!w.mOrientationChanging) {
+            if (!w.getOrientationChanging()) {
                 return;
             }
-            w.mOrientationChanging = false;
+            w.orientationChangeTimedOut();
             w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                     - mService.mDisplayFreezeTime);
             Slog.w(TAG_WM, "Force clearing orientation change: " + w);
@@ -2765,6 +2776,12 @@
 
         stopDimmingIfNeeded();
 
+        final boolean wallpaperVisible = mWallpaperController.isWallpaperVisible();
+        if (wallpaperVisible != mLastWallpaperVisible) {
+            mLastWallpaperVisible = wallpaperVisible;
+            mService.mWallpaperVisibilityListeners.notifyWallpaperVisibilityChanged(this);
+        }
+
         while (!mTmpUpdateAllDrawn.isEmpty()) {
             final AppWindowToken atoken = mTmpUpdateAllDrawn.removeLast();
             // See if any windows have been drawn, so they (and others associated with them)
@@ -2974,14 +2991,14 @@
                 // Don't include wallpaper in bounds calculation
                 if (!w.mIsWallpaper && !mutableIncludeFullDisplay.value) {
                     if (includeDecor) {
-                        final TaskStack stack = w.getStack();
-                        if (stack != null) {
-                            stack.getBounds(frame);
-                        }
+                        final Task task = w.getTask();
+                        if (task != null) {
+                            task.getBounds(frame);
+                        } else {
 
-                        // We want to screenshot with the exact bounds of the surface of the app. Thus,
-                        // intersect it with the frame.
-                        frame.intersect(w.mFrame);
+                            // No task bounds? Too bad! Ain't no screenshot then.
+                            return true;
+                        }
                     } else {
                         final Rect wf = w.mFrame;
                         final Rect cr = w.mContentInsets;
@@ -3291,6 +3308,13 @@
             setLayoutNeeded();
         }
 
+
+        @Override
+        boolean isOnTop() {
+            // Considered always on top
+            return true;
+        }
+
         @Override
         void positionChildAt(int position, TaskStack child, boolean includingParents) {
             if (StackId.isAlwaysOnTop(child.mStackId) && position != POSITION_TOP) {
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 2d7fc68..6b51455 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -427,8 +427,9 @@
                 inputMethodManagerInternal.hideCurrentInputMethod();
                 mImeHideRequested = true;
             }
+            return;
         }
-        setMinimizedDockedStack(false, false /* animate */);
+        setMinimizedDockedStack(false /* minimizedDock */, false /* animate */);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/PointerEventDispatcher.java b/services/core/java/com/android/server/wm/PointerEventDispatcher.java
index 6b0e4c9..484987e 100644
--- a/services/core/java/com/android/server/wm/PointerEventDispatcher.java
+++ b/services/core/java/com/android/server/wm/PointerEventDispatcher.java
@@ -36,11 +36,11 @@
     }
 
     @Override
-    public void onInputEvent(InputEvent event) {
+    public void onInputEvent(InputEvent event, int displayId) {
         try {
             if (event instanceof MotionEvent
                     && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-                final MotionEvent motionEvent = (MotionEvent)event;
+                final MotionEvent motionEvent = (MotionEvent) event;
                 PointerEventListener[] listeners;
                 synchronized (mListeners) {
                     if (mListenersArray == null) {
@@ -50,7 +50,7 @@
                     listeners = mListenersArray;
                 }
                 for (int i = 0; i < listeners.length; ++i) {
-                    listeners[i].onPointerEvent(motionEvent);
+                    listeners[i].onPointerEvent(motionEvent, displayId);
                 }
             }
         } finally {
diff --git a/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java b/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java
index 0508fdf..a12c2c4 100644
--- a/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java
+++ b/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java
@@ -32,7 +32,7 @@
 // the surface control.
 //
 // See cts/hostsidetests/../../SurfaceTraceReceiver.java for parsing side.
-class RemoteSurfaceTrace extends SurfaceControl {
+class RemoteSurfaceTrace extends SurfaceControlWithBackground {
     static final String TAG = "RemoteSurfaceTrace";
 
     final FileDescriptor mWriteFd;
@@ -41,7 +41,8 @@
     final WindowManagerService mService;
     final WindowState mWindow;
 
-    RemoteSurfaceTrace(FileDescriptor fd, SurfaceControl wrapped, WindowState window) {
+    RemoteSurfaceTrace(FileDescriptor fd, SurfaceControlWithBackground wrapped,
+            WindowState window) {
         super(wrapped);
 
         mWriteFd = fd;
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 233e75b..7bcad9f 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -18,6 +18,7 @@
 
 import android.content.res.Configuration;
 import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
 import android.hardware.power.V1_0.PowerHint;
 import android.os.Binder;
 import android.os.Debug;
@@ -51,6 +52,7 @@
 import static android.app.AppOpsManager.MODE_DEFAULT;
 import static android.app.AppOpsManager.OP_NONE;
 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;
@@ -243,12 +245,24 @@
                     displayId, displayInfo);
             mService.configureDisplayPolicyLocked(dc);
 
-            // TODO(multi-display): Create an input channel for each display with touch capability.
-            if (displayId == DEFAULT_DISPLAY && mService.canDispatchPointerEvents()) {
-                dc.mTapDetector = new TaskTapPointerEventListener(
-                        mService, dc);
+            // Tap Listeners are supported for:
+            // 1. All physical displays (multi-display).
+            // 2. VirtualDisplays that support virtual touch input. (Only VR for now)
+            // TODO(multi-display): Support VirtualDisplays with no virtual touch input.
+            if ((display.getType() != Display.TYPE_VIRTUAL
+                    || (display.getType() == Display.TYPE_VIRTUAL
+                        // Only VR VirtualDisplays
+                        && displayId == mService.mVr2dDisplayId))
+                    && mService.canDispatchPointerEvents()) {
+                if (DEBUG_DISPLAY) {
+                    Slog.d(TAG,
+                            "Registering PointerEventListener for DisplayId: " + displayId);
+                }
+                dc.mTapDetector = new TaskTapPointerEventListener(mService, dc);
                 mService.registerPointerEventListener(dc.mTapDetector);
-                mService.registerPointerEventListener(mService.mMousePositionTracker);
+                if (displayId == DEFAULT_DISPLAY) {
+                    mService.registerPointerEventListener(mService.mMousePositionTracker);
+                }
             }
         }
 
@@ -754,6 +768,15 @@
             } else {
                 mUpdateRotation = false;
             }
+            // Update rotation of VR virtual display separately. Currently this is the only kind of
+            // secondary display that can be rotated because of the single-display limitations in
+            // PhoneWindowManager.
+            final DisplayContent vrDisplay = mService.mVr2dDisplayId != INVALID_DISPLAY
+                    ? getDisplayContent(mService.mVr2dDisplayId) : null;
+            if (vrDisplay != null && vrDisplay.updateRotationUnchecked(false /* inTransaction */)) {
+                mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, mService.mVr2dDisplayId)
+                        .sendToTarget();
+            }
         }
 
         if (mService.mWaitingForDrawnCallback != null ||
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 7e575bf..22b0f5b 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -162,6 +162,7 @@
         }
     }
 
+    @Override
     public void binderDied() {
         // Note: it is safe to call in to the input method manager
         // here because we are not holding our lock.
@@ -208,6 +209,7 @@
             outContentInsets, outStableInsets, null /* outOutsets */, null);
     }
 
+    @Override
     public void remove(IWindow window) {
         mService.removeWindow(this, window);
     }
@@ -217,6 +219,7 @@
         mService.setWillReplaceWindows(appToken, childrenOnly);
     }
 
+    @Override
     public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
             int requestedWidth, int requestedHeight, int viewFlags,
             int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
@@ -235,42 +238,50 @@
         return res;
     }
 
+    @Override
     public boolean outOfMemory(IWindow window) {
         return mService.outOfMemoryWindow(this, window);
     }
 
+    @Override
     public void setTransparentRegion(IWindow window, Region region) {
         mService.setTransparentRegionWindow(this, window, region);
     }
 
+    @Override
     public void setInsets(IWindow window, int touchableInsets,
             Rect contentInsets, Rect visibleInsets, Region touchableArea) {
         mService.setInsetsWindow(this, window, touchableInsets, contentInsets,
                 visibleInsets, touchableArea);
     }
 
+    @Override
     public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
         mService.getWindowDisplayFrame(this, window, outDisplayFrame);
     }
 
+    @Override
     public void finishDrawing(IWindow window) {
         if (WindowManagerService.localLOGV) Slog.v(
             TAG_WM, "IWindow finishDrawing called for " + window);
         mService.finishDrawingWindow(this, window);
     }
 
+    @Override
     public void setInTouchMode(boolean mode) {
         synchronized(mService.mWindowMap) {
             mService.mInTouchMode = mode;
         }
     }
 
+    @Override
     public boolean getInTouchMode() {
         synchronized(mService.mWindowMap) {
             return mService.mInTouchMode;
         }
     }
 
+    @Override
     public boolean performHapticFeedback(IWindow window, int effectId,
             boolean always) {
         synchronized(mService.mWindowMap) {
@@ -286,12 +297,14 @@
     }
 
     /* Drag/drop */
+    @Override
     public IBinder prepareDrag(IWindow window, int flags,
             int width, int height, Surface outSurface) {
         return mService.prepareDragSurface(window, mSurfaceSession, flags,
                 width, height, outSurface);
     }
 
+    @Override
     public boolean performDrag(IWindow window, IBinder dragToken,
             int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
             ClipData data) {
@@ -375,6 +388,7 @@
         return true;    // success!
     }
 
+    @Override
     public boolean startMovingTask(IWindow window, float startX, float startY) {
         if (DEBUG_TASK_POSITIONING) Slog.d(
                 TAG_WM, "startMovingTask: {" + startX + "," + startY + "}");
@@ -387,6 +401,7 @@
         }
     }
 
+    @Override
     public void reportDropResult(IWindow window, boolean consumed) {
         IBinder token = window.asBinder();
         if (DEBUG_DRAG) {
@@ -427,6 +442,7 @@
         }
     }
 
+    @Override
     public void cancelDragAndDrop(IBinder dragToken) {
         if (DEBUG_DRAG) {
             Slog.d(TAG_WM, "cancelDragAndDrop");
@@ -455,18 +471,21 @@
         }
     }
 
+    @Override
     public void dragRecipientEntered(IWindow window) {
         if (DEBUG_DRAG) {
             Slog.d(TAG_WM, "Drag into new candidate view @ " + window.asBinder());
         }
     }
 
+    @Override
     public void dragRecipientExited(IWindow window) {
         if (DEBUG_DRAG) {
             Slog.d(TAG_WM, "Drag from old candidate view @ " + window.asBinder());
         }
     }
 
+    @Override
     public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
         synchronized(mService.mWindowMap) {
             long ident = Binder.clearCallingIdentity();
@@ -480,12 +499,14 @@
         }
     }
 
+    @Override
     public void wallpaperOffsetsComplete(IBinder window) {
         synchronized (mService.mWindowMap) {
             mService.mRoot.mWallpaperController.wallpaperOffsetsComplete(window);
         }
     }
 
+    @Override
     public void setWallpaperDisplayOffset(IBinder window, int x, int y) {
         synchronized(mService.mWindowMap) {
             long ident = Binder.clearCallingIdentity();
@@ -498,6 +519,7 @@
         }
     }
 
+    @Override
     public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
             int z, Bundle extras, boolean sync) {
         synchronized(mService.mWindowMap) {
@@ -512,12 +534,14 @@
         }
     }
 
+    @Override
     public void wallpaperCommandComplete(IBinder window, Bundle result) {
         synchronized (mService.mWindowMap) {
             mService.mRoot.mWallpaperController.wallpaperCommandComplete(window);
         }
     }
 
+    @Override
     public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
         synchronized(mService.mWindowMap) {
             final long identity = Binder.clearCallingIdentity();
@@ -529,6 +553,7 @@
         }
     }
 
+    @Override
     public IWindowId getWindowId(IBinder window) {
         return mService.getWindowId(window);
     }
diff --git a/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java b/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java
new file mode 100644
index 0000000..b0eaf14
--- /dev/null
+++ b/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java
@@ -0,0 +1,333 @@
+/*
+ * 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.wm;
+
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.view.Surface;
+import android.view.Surface.OutOfResourcesException;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManagerPolicy.NAV_BAR_BOTTOM;
+import static android.view.WindowManagerPolicy.NAV_BAR_LEFT;
+import static android.view.WindowManagerPolicy.NAV_BAR_RIGHT;
+
+/**
+ * SurfaceControl extension that has black background behind navigation bar area for fullscreen
+ * letterboxed apps.
+ */
+class SurfaceControlWithBackground extends SurfaceControl {
+    // SurfaceControl that holds the background.
+    private SurfaceControl mBackgroundControl;
+
+    // Flag that defines whether the background should be shown.
+    private boolean mVisible;
+
+    // Way to communicate with corresponding window.
+    private WindowSurfaceController mWindowSurfaceController;
+
+    // Rect to hold task bounds when computing metrics for background.
+    private Rect mTmpContainerRect = new Rect();
+
+    // Last metrics applied to the main SurfaceControl.
+    private float mLastWidth, mLastHeight;
+    private float mLastDsDx = 1, mLastDsDy = 1;
+    private float mLastX, mLastY;
+
+    // SurfaceFlinger doesn't support crop rectangles where width or height is non-positive.
+    // If we just set an empty crop it will behave as if there is no crop at all.
+    // To fix this we explicitly hide the surface and won't let it to be shown.
+    private boolean mHiddenForCrop = false;
+
+    public SurfaceControlWithBackground(SurfaceControlWithBackground other) {
+        super(other);
+        mBackgroundControl = other.mBackgroundControl;
+        mVisible = other.mVisible;
+        mWindowSurfaceController = other.mWindowSurfaceController;
+    }
+
+    public SurfaceControlWithBackground(SurfaceSession s, String name, int w, int h, int format,
+            int flags, int windowType, int ownerUid,
+            WindowSurfaceController windowSurfaceController) throws OutOfResourcesException {
+        super(s, name, w, h, format, flags, windowType, ownerUid);
+
+        // We should only show background behind app windows that are letterboxed in a task.
+        if ((windowType != TYPE_BASE_APPLICATION && windowType != TYPE_APPLICATION_STARTING)
+                || !windowSurfaceController.mAnimator.mWin.isLetterboxedAppWindow()) {
+            return;
+        }
+        mWindowSurfaceController = windowSurfaceController;
+        mLastWidth = w;
+        mLastHeight = h;
+        mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+        mBackgroundControl = new SurfaceControl(s, "Background for - " + name,
+                mTmpContainerRect.width(), mTmpContainerRect.height(), PixelFormat.OPAQUE,
+                flags | SurfaceControl.FX_SURFACE_DIM);
+    }
+
+    @Override
+    public void setAlpha(float alpha) {
+        super.setAlpha(alpha);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.setAlpha(alpha);
+    }
+
+    @Override
+    public void setLayer(int zorder) {
+        super.setLayer(zorder);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        // TODO: Use setRelativeLayer(Integer.MIN_VALUE) when it's fixed.
+        mBackgroundControl.setLayer(zorder - 1);
+    }
+
+    @Override
+    public void setPosition(float x, float y) {
+        super.setPosition(x, y);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mLastX = x;
+        mLastY = y;
+        updateBgPosition();
+    }
+
+    private void updateBgPosition() {
+        mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+        final Rect winFrame = mWindowSurfaceController.mAnimator.mWin.mFrame;
+        final float offsetX = (mTmpContainerRect.left - winFrame.left) * mLastDsDx;
+        final float offsetY = (mTmpContainerRect.top - winFrame.top) * mLastDsDy;
+        mBackgroundControl.setPosition(mLastX + offsetX, mLastY + offsetY);
+    }
+
+    @Override
+    public void setSize(int w, int h) {
+        super.setSize(w, h);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mLastWidth = w;
+        mLastHeight = h;
+        mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+        mBackgroundControl.setSize(mTmpContainerRect.width(), mTmpContainerRect.height());
+    }
+
+    @Override
+    public void setWindowCrop(Rect crop) {
+        super.setWindowCrop(crop);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        calculateBgCrop(crop);
+        mBackgroundControl.setWindowCrop(mTmpContainerRect);
+        mHiddenForCrop = mTmpContainerRect.isEmpty();
+        updateBackgroundVisibility();
+    }
+
+    @Override
+    public void setFinalCrop(Rect crop) {
+        super.setFinalCrop(crop);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+        mBackgroundControl.setFinalCrop(mTmpContainerRect);
+    }
+
+    /**
+     * Compute background crop based on current animation progress for main surface control and
+     * update {@link #mTmpContainerRect} with new values.
+     */
+    private void calculateBgCrop(Rect crop) {
+        // Track overall progress of animation by computing cropped portion of status bar.
+        final Rect contentInsets = mWindowSurfaceController.mAnimator.mWin.mContentInsets;
+        float d = contentInsets.top == 0 ? 0 : (float) crop.top / contentInsets.top;
+        if (d > 1.f) {
+            // We're running expand animation from launcher, won't compute custom bg crop here.
+            mTmpContainerRect.setEmpty();
+            return;
+        }
+
+        // Compute new scaled width and height for background that will depend on current animation
+        // progress. Those consist of current crop rect for the main surface + scaled areas outside
+        // of letterboxed area.
+        // TODO: Because the progress is computed with low precision we're getting smaller values
+        // for background width/height then screen size at the end of the animation. Will round when
+        // the value is smaller then some empiric epsilon. However, this should be fixed by
+        // computing correct frames for letterboxed windows in WindowState.
+        d = d < 0.025f ? 0 : d;
+        mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+        int backgroundWidth = 0, backgroundHeight = 0;
+        // Compute additional offset for the background when app window is positioned not at (0,0).
+        // E.g. landscape with navigation bar on the left.
+        final Rect winFrame = mWindowSurfaceController.mAnimator.mWin.mFrame;
+        int offsetX = (int)((winFrame.left - mTmpContainerRect.left) * mLastDsDx),
+                offsetY = (int) ((winFrame.top - mTmpContainerRect.top) * mLastDsDy);
+
+        // Position and size background.
+        final int bgPosition = mWindowSurfaceController.mAnimator.mService.getNavBarPosition();
+
+        switch (bgPosition) {
+            case NAV_BAR_LEFT:
+                backgroundWidth = (int) ((mTmpContainerRect.width() - mLastWidth) * (1 - d) + 0.5);
+                backgroundHeight = crop.height();
+                offsetX += crop.left - backgroundWidth;
+                offsetY += crop.top;
+                break;
+            case NAV_BAR_RIGHT:
+                backgroundWidth = (int) ((mTmpContainerRect.width() - mLastWidth) * (1 - d) + 0.5);
+                backgroundHeight = crop.height();
+                offsetX += crop.right;
+                offsetY += crop.top;
+                break;
+            case NAV_BAR_BOTTOM:
+                backgroundWidth = crop.width();
+                backgroundHeight = (int) ((mTmpContainerRect.height() - mLastHeight) * (1 - d)
+                        + 0.5);
+                offsetX += crop.left;
+                offsetY += crop.bottom;
+                break;
+        }
+        mTmpContainerRect.set(offsetX, offsetY, offsetX + backgroundWidth,
+                offsetY + backgroundHeight);
+    }
+
+    @Override
+    public void setLayerStack(int layerStack) {
+        super.setLayerStack(layerStack);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.setLayerStack(layerStack);
+    }
+
+    @Override
+    public void setOpaque(boolean isOpaque) {
+        super.setOpaque(isOpaque);
+        updateBackgroundVisibility();
+    }
+
+    @Override
+    public void setSecure(boolean isSecure) {
+        super.setSecure(isSecure);
+    }
+
+    @Override
+    public void setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) {
+        super.setMatrix(dsdx, dtdx, dtdy, dsdy);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.setMatrix(dsdx, dtdx, dtdy, dsdy);
+        mLastDsDx = dsdx;
+        mLastDsDy = dsdy;
+        updateBgPosition();
+    }
+
+    @Override
+    public void hide() {
+        super.hide();
+        mVisible = false;
+        updateBackgroundVisibility();
+    }
+
+    @Override
+    public void show() {
+        super.show();
+        mVisible = true;
+        updateBackgroundVisibility();
+    }
+
+    @Override
+    public void destroy() {
+        super.destroy();
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.destroy();
+    }
+
+    @Override
+    public void release() {
+        super.release();
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.release();
+    }
+
+    @Override
+    public void setTransparentRegionHint(Region region) {
+        super.setTransparentRegionHint(region);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.setTransparentRegionHint(region);
+    }
+
+    @Override
+    public void deferTransactionUntil(IBinder handle, long frame) {
+        super.deferTransactionUntil(handle, frame);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.deferTransactionUntil(handle, frame);
+    }
+
+    @Override
+    public void deferTransactionUntil(Surface barrier, long frame) {
+        super.deferTransactionUntil(barrier, frame);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.deferTransactionUntil(barrier, frame);
+    }
+
+    private void updateBackgroundVisibility() {
+        if (mBackgroundControl == null) {
+            return;
+        }
+        final AppWindowToken appWindowToken = mWindowSurfaceController.mAnimator.mWin.mAppToken;
+        if (!mHiddenForCrop && mVisible && appWindowToken != null && appWindowToken.fillsParent()) {
+            mBackgroundControl.show();
+        } else {
+            mBackgroundControl.hide();
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index bfebca8..e5055e9 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -23,6 +23,8 @@
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+
 import static com.android.server.EventLogTags.WM_TASK_REMOVED;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -39,6 +41,7 @@
 import android.view.Surface;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wm.DimLayer.DimLayerUser;
 
 import java.io.PrintWriter;
 import java.util.function.Consumer;
@@ -621,6 +624,17 @@
         return token != null ? token.findMainWindow() : null;
     }
 
+    AppWindowToken getTopFullscreenAppToken() {
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final AppWindowToken token = mChildren.get(i);
+            final WindowState win = token.findMainWindow();
+            if (win != null && win.mAttrs.isFullscreen()) {
+                return token;
+            }
+        }
+        return null;
+    }
+
     AppWindowToken getTopVisibleAppToken() {
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final AppWindowToken token = mChildren.get(i);
@@ -637,6 +651,18 @@
         return isFullscreen();
     }
 
+    @Override
+    public int getLayerForDim(WindowStateAnimator animator, int layerOffset, int defaultLayer) {
+        // If the dim layer is for a starting window, move the dim layer back in the z-order behind
+        // the lowest activity window to ensure it does not occlude the main window if it is
+        // translucent
+        final AppWindowToken appToken = animator.mWin.mAppToken;
+        if (animator.mAttrType == TYPE_APPLICATION_STARTING && hasChild(appToken) ) {
+            return Math.min(defaultLayer, appToken.getLowestAnimLayer() - layerOffset);
+        }
+        return defaultLayer;
+    }
+
     boolean isFullscreen() {
         if (useCurrentBounds()) {
             return mFillsParent;
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 0c68e2c..c58212c 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -133,7 +133,7 @@
         }
 
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             if (!(event instanceof MotionEvent)
                     || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
                 return;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index bf8fabd..b8b9b9a 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -18,6 +18,9 @@
 
 import static android.app.ActivityManager.ENABLE_TASK_SNAPSHOTS;
 
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManager.StackId;
@@ -29,6 +32,7 @@
 import android.os.Environment;
 import android.os.Handler;
 import android.util.ArraySet;
+import android.util.Slog;
 import android.view.DisplayListCanvas;
 import android.view.RenderNode;
 import android.view.ThreadedRenderer;
@@ -57,6 +61,7 @@
  * To access this class, acquire the global window manager lock.
  */
 class TaskSnapshotController {
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskSnapshotController" : TAG_WM;
 
     /**
      * Return value for {@link #getSnapshotMode}: We are allowed to take a real screenshot to be
@@ -147,10 +152,17 @@
                     break;
             }
             if (snapshot != null) {
-                mCache.putSnapshot(task, snapshot);
-                mPersister.persistSnapshot(task.mTaskId, task.mUserId, snapshot);
-                if (task.getController() != null) {
-                    task.getController().reportSnapshotChanged(snapshot);
+                final GraphicBuffer buffer = snapshot.getSnapshot();
+                if (buffer.getWidth() == 0 || buffer.getHeight() == 0) {
+                    buffer.destroy();
+                    Slog.e(TAG, "Invalid task snapshot dimensions " + buffer.getWidth() + "x"
+                            + buffer.getHeight());
+                } else {
+                    mCache.putSnapshot(task, snapshot);
+                    mPersister.persistSnapshot(task.mTaskId, task.mUserId, snapshot);
+                    if (task.getController() != null) {
+                        task.getController().reportSnapshotChanged(snapshot);
+                    }
                 }
             }
         }
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 297e288..f90b3fb 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -25,6 +25,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.CompressFormat;
 import android.graphics.Bitmap.Config;
+import android.graphics.GraphicBuffer;
 import android.os.Process;
 import android.os.SystemClock;
 import android.util.ArraySet;
@@ -290,7 +291,6 @@
                 failed = true;
             }
             if (!writeBuffer()) {
-                writeBuffer();
                 failed = true;
             }
             if (failed) {
@@ -325,6 +325,11 @@
             final File file = getBitmapFile(mTaskId, mUserId);
             final File reducedFile = getReducedResolutionBitmapFile(mTaskId, mUserId);
             final Bitmap bitmap = Bitmap.createHardwareBitmap(mSnapshot.getSnapshot());
+            if (bitmap == null) {
+                Slog.e(TAG, "Invalid task snapshot hw bitmap");
+                return false;
+            }
+
             final Bitmap swBitmap = bitmap.copy(Config.ARGB_8888, false /* isMutable */);
             final Bitmap reduced = Bitmap.createScaledBitmap(swBitmap,
                     (int) (bitmap.getWidth() * REDUCED_SCALE),
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index a96d224..d7f0496 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -20,6 +20,7 @@
 import static android.graphics.Color.alpha;
 import static android.view.SurfaceControl.HIDDEN;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
 import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
 import static android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
 import static android.view.WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE;
@@ -150,15 +151,29 @@
         final int currentOrientation;
         synchronized (service.mWindowMap) {
             final WindowState mainWindow = token.findMainWindow();
-            if (mainWindow == null) {
+            final Task task = token.getTask();
+            if (task == null) {
+                Slog.w(TAG, "TaskSnapshotSurface.create: Failed to find task for token="
+                        + token);
+                return null;
+            }
+            final AppWindowToken topFullscreenToken = token.getTask().getTopFullscreenAppToken();
+            if (topFullscreenToken == null) {
+                Slog.w(TAG, "TaskSnapshotSurface.create: Failed to find top fullscreen for task="
+                        + task);
+                return null;
+            }
+            final WindowState topFullscreenWindow = topFullscreenToken.findMainWindow();
+            if (mainWindow == null || topFullscreenWindow == null) {
                 Slog.w(TAG, "TaskSnapshotSurface.create: Failed to find main window for token="
                         + token);
                 return null;
             }
-            sysUiVis = mainWindow.getSystemUiVisibility();
-            windowFlags = mainWindow.getAttrs().flags;
-            windowPrivateFlags = mainWindow.getAttrs().privateFlags;
+            sysUiVis = topFullscreenWindow.getSystemUiVisibility();
+            windowFlags = topFullscreenWindow.getAttrs().flags;
+            windowPrivateFlags = topFullscreenWindow.getAttrs().privateFlags;
 
+            layoutParams.dimAmount = mainWindow.getAttrs().dimAmount;
             layoutParams.type = TYPE_APPLICATION_STARTING;
             layoutParams.format = snapshot.getSnapshot().getFormat();
             layoutParams.flags = (windowFlags & ~FLAG_INHERIT_EXCLUDES)
@@ -170,22 +185,17 @@
             layoutParams.width = LayoutParams.MATCH_PARENT;
             layoutParams.height = LayoutParams.MATCH_PARENT;
             layoutParams.systemUiVisibility = sysUiVis;
-            final Task task = token.getTask();
-            if (task != null) {
-                layoutParams.setTitle(String.format(TITLE_FORMAT, task.mTaskId));
+            layoutParams.setTitle(String.format(TITLE_FORMAT, task.mTaskId));
 
-                final TaskDescription taskDescription = task.getTaskDescription();
-                if (taskDescription != null) {
-                    backgroundColor = taskDescription.getBackgroundColor();
-                    statusBarColor = taskDescription.getStatusBarColor();
-                    navigationBarColor = taskDescription.getNavigationBarColor();
-                }
-                taskBounds = new Rect();
-                task.getBounds(taskBounds);
-            } else {
-                taskBounds = null;
+            final TaskDescription taskDescription = task.getTaskDescription();
+            if (taskDescription != null) {
+                backgroundColor = taskDescription.getBackgroundColor();
+                statusBarColor = taskDescription.getStatusBarColor();
+                navigationBarColor = taskDescription.getNavigationBarColor();
             }
-            currentOrientation = mainWindow.getConfiguration().orientation;
+            taskBounds = new Rect();
+            task.getBounds(taskBounds);
+            currentOrientation = topFullscreenWindow.getConfiguration().orientation;
         }
         try {
             final int res = session.addToDisplay(window, window.mSeq, layoutParams,
diff --git a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
index dd9ba73..42a2d9d 100644
--- a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
@@ -24,6 +24,7 @@
 
 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;
@@ -45,6 +46,13 @@
     }
 
     @Override
+    public void onPointerEvent(MotionEvent motionEvent, int displayId) {
+        if (displayId == getDisplayId()) {
+            onPointerEvent(motionEvent);
+        }
+    }
+
+    @Override
     public void onPointerEvent(MotionEvent motionEvent) {
         final int action = motionEvent.getAction();
         switch (action & MotionEvent.ACTION_MASK) {
@@ -104,4 +112,8 @@
            mTouchExcludeRegion.set(newRegion);
         }
     }
+
+    private int getDisplayId() {
+        return mDisplayContent.getDisplayId();
+    }
 }
diff --git a/services/core/java/com/android/server/wm/TaskWindowContainerController.java b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
index 9f02485..54a6cc0 100644
--- a/services/core/java/com/android/server/wm/TaskWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
@@ -80,7 +80,9 @@
             final Task task = createTask(taskId, stack, userId, bounds, overrideConfig, resizeMode,
                     supportsPictureInPicture, homeTask, taskDescription);
             final int position = toTop ? POSITION_TOP : POSITION_BOTTOM;
-            stack.addTask(task, position, showForAllUsers, true /* moveParents */);
+            // We only want to move the parents to the parents if we are creating this task at the
+            // top of its stack.
+            stack.addTask(task, position, showForAllUsers, toTop /* moveParents */);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WallpaperVisibilityListeners.java b/services/core/java/com/android/server/wm/WallpaperVisibilityListeners.java
new file mode 100644
index 0000000..2c06851
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WallpaperVisibilityListeners.java
@@ -0,0 +1,79 @@
+/*
+ * 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.wm;
+
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.util.SparseArray;
+import android.view.IWallpaperVisibilityListener;
+
+/**
+ * Manages and trigger wallpaper visibility listeners.
+ */
+class WallpaperVisibilityListeners {
+
+    /**
+     * A map of displayIds and its listeners.
+     */
+    private final SparseArray<RemoteCallbackList<IWallpaperVisibilityListener>> mDisplayListeners =
+            new SparseArray<>();
+
+    void registerWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
+            int displayId) {
+        RemoteCallbackList<IWallpaperVisibilityListener> listeners =
+                mDisplayListeners.get(displayId);
+        if (listeners == null) {
+            listeners = new RemoteCallbackList<>();
+            mDisplayListeners.append(displayId, listeners);
+        }
+        listeners.register(listener);
+    }
+
+    void unregisterWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
+            int displayId) {
+        RemoteCallbackList<IWallpaperVisibilityListener> listeners =
+                mDisplayListeners.get(displayId);
+        if (listeners == null) {
+            return;
+        }
+        listeners.unregister(listener);
+    }
+
+    void notifyWallpaperVisibilityChanged(DisplayContent displayContent) {
+        final int displayId = displayContent.getDisplayId();
+        final boolean visible = displayContent.mWallpaperController.isWallpaperVisible();
+        RemoteCallbackList<IWallpaperVisibilityListener> displayListeners =
+                mDisplayListeners.get(displayId);
+
+        // No listeners for this display.
+        if (displayListeners == null) {
+            return;
+        }
+
+        int i = displayListeners.beginBroadcast();
+        while (i > 0) {
+            i--;
+            IWallpaperVisibilityListener listener = displayListeners.getBroadcastItem(i);
+            try {
+                listener.onWallpaperVisibilityChanged(visible, displayId);
+            } catch (RemoteException e) {
+                // Nothing to do in here, RemoteCallbackListener will clean it up.
+            }
+        }
+        displayListeners.finishBroadcast();
+    }
+}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index fe5b7f2..079ae40 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -33,7 +33,6 @@
 import android.view.SurfaceControl;
 import android.view.WindowManagerPolicy;
 
-import com.android.internal.view.SurfaceFlingerVsyncChoreographer;
 import com.android.server.AnimationThread;
 
 import java.io.PrintWriter;
@@ -134,26 +133,38 @@
      * sure other threads can make progress if this happens.
      */
     private void animate(long frameTimeNs) {
-        boolean transactionOpen = false;
-        try {
-            synchronized (mService.mWindowMap) {
-                if (!mInitialized) {
-                    return;
-                }
 
-                mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;
-                mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
-                mAnimating = false;
-                mAppWindowAnimating = false;
-                if (DEBUG_WINDOW_TRACE) {
-                    Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
-                }
+        synchronized (mService.mWindowMap) {
+            if (!mInitialized) {
+                return;
+            }
 
-                if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION animate");
-                mService.openSurfaceTransaction();
-                transactionOpen = true;
-                SurfaceControl.setAnimationTransaction();
+            // Schedule next frame already such that back-pressure happens continuously
+            scheduleAnimation();
+        }
 
+        // Simulate back-pressure by opening and closing an empty animation transaction. This makes
+        // sure that an animation frame is at least presented once on the screen. We do this outside
+        // of the regular transaction such that we can avoid holding the window manager lock in case
+        // we receive back-pressure from SurfaceFlinger. Since closing an animation transaction
+        // without the window manager locks leads to ordering issues (as the transaction will be
+        // processed only at the beginning of the next frame which may result in another transaction
+        // that was executed later in WM side gets executed first on SF side), we don't update any
+        // Surface properties here such that reordering doesn't cause issues.
+        mService.executeEmptyAnimationTransaction();
+
+        synchronized (mService.mWindowMap) {
+            mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;
+            mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
+            mAnimating = false;
+            mAppWindowAnimating = false;
+            if (DEBUG_WINDOW_TRACE) {
+                Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
+            }
+
+            if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION animate");
+            mService.openSurfaceTransaction();
+            try {
                 final AccessibilityController accessibilityController =
                         mService.mAccessibilityController;
                 final int numDisplays = mDisplayContentsAnimators.size();
@@ -216,27 +227,20 @@
                     mAnimating |= mService.mDragState.stepAnimationLocked(mCurrentTime);
                 }
 
-                if (mAnimating) {
-                    mService.scheduleAnimationLocked();
+                if (!mAnimating) {
+                    cancelAnimation();
                 }
 
                 if (mService.mWatermark != null) {
                     mService.mWatermark.drawIfNeeded();
                 }
-            }
-        } catch (RuntimeException e) {
-            Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
-        } finally {
-            if (transactionOpen) {
-
-                // Do not hold window manager lock while closing the transaction, as this might be
-                // blocking until the next frame, which can lead to total lock starvation.
-                mService.closeSurfaceTransaction(false /* withLockHeld */);
+            } catch (RuntimeException e) {
+                Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
+            } finally {
+                mService.closeSurfaceTransaction();
                 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION animate");
             }
-        }
 
-        synchronized (mService.mWindowMap) {
             boolean hasPendingLayoutChanges = mService.mRoot.hasPendingLayoutChanges(this);
             boolean doRequest = false;
             if (mBulkUpdateParams != 0) {
@@ -404,6 +408,13 @@
         }
     }
 
+    private void cancelAnimation() {
+        if (mAnimationFrameCallbackScheduled) {
+            mAnimationFrameCallbackScheduled = false;
+            mChoreographer.removeFrameCallback(mAnimationFrameCallback);
+        }
+    }
+
     private class DisplayContentsAnimator {
         ScreenRotationAnimation mScreenRotationAnimation = null;
     }
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 600bc5c..3df73d7 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -472,6 +472,13 @@
         return false;
     }
 
+    /**
+a     * Returns whether this child is on top of the window hierarchy.
+     */
+    boolean isOnTop() {
+        return getParent().getTopChild() == this && getParent().isOnTop();
+    }
+
     /** Returns the top child container. */
     E getTopChild() {
         return mChildren.peekLast();
diff --git a/services/core/java/com/android/server/wm/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java
index 01a3143..5dc79f8 100644
--- a/services/core/java/com/android/server/wm/WindowLayersController.java
+++ b/services/core/java/com/android/server/wm/WindowLayersController.java
@@ -17,13 +17,14 @@
 package com.android.server.wm;
 
 import android.util.Slog;
-import android.view.Display;
 
 import java.util.ArrayDeque;
 import java.util.function.Consumer;
 
+import static android.app.ActivityManager.StackId;
 import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
@@ -56,7 +57,6 @@
         mService = service;
     }
 
-    private int mHighestApplicationLayer = 0;
     private ArrayDeque<WindowState> mPinnedWindows = new ArrayDeque<>();
     private ArrayDeque<WindowState> mDockedWindows = new ArrayDeque<>();
     private ArrayDeque<WindowState> mAssistantWindows = new ArrayDeque<>();
@@ -66,6 +66,8 @@
     private int mCurBaseLayer;
     private int mCurLayer;
     private boolean mAnyLayerChanged;
+    private int mHighestApplicationLayer;
+    private int mHighestDockedAffectedLayer;
     private int mHighestLayerInImeTargetBaseLayer;
     private WindowState mImeTarget;
     private boolean mAboveImeTarget;
@@ -98,6 +100,10 @@
             mHighestLayerInImeTargetBaseLayer = Math.max(mHighestLayerInImeTargetBaseLayer,
                     w.mWinAnimator.mAnimLayer);
         }
+        if (w.getAppToken() != null && StackId.isResizeableByDockedStack(w.getStackId())) {
+            mHighestDockedAffectedLayer = Math.max(mHighestDockedAffectedLayer,
+                    w.mWinAnimator.mAnimLayer);
+        }
 
         collectSpecialWindows(w);
 
@@ -135,7 +141,6 @@
     }
 
     private void reset() {
-        mHighestApplicationLayer = 0;
         mPinnedWindows.clear();
         mInputMethodWindows.clear();
         mDockedWindows.clear();
@@ -147,8 +152,10 @@
         mCurLayer = 0;
         mAnyLayerChanged = false;
 
-        mImeTarget = mService.mInputMethodTarget;
+        mHighestApplicationLayer = 0;
+        mHighestDockedAffectedLayer = 0;
         mHighestLayerInImeTargetBaseLayer = (mImeTarget != null) ? mImeTarget.mBaseLayer : 0;
+        mImeTarget = mService.mInputMethodTarget;
         mAboveImeTarget = false;
         mAboveImeTargetAppWindows.clear();
     }
@@ -179,32 +186,41 @@
             }
         }
 
-        final Task task = w.getTask();
-        if (task == null) {
-            return;
-        }
-        final TaskStack stack = task.mStack;
-        if (stack == null) {
-            return;
-        }
-        if (stack.mStackId == PINNED_STACK_ID) {
+        final int stackId = w.getAppToken() != null ? w.getStackId() : INVALID_STACK_ID;
+        if (stackId == PINNED_STACK_ID) {
             mPinnedWindows.add(w);
-        } else if (stack.mStackId == DOCKED_STACK_ID) {
+        } else if (stackId == DOCKED_STACK_ID) {
             mDockedWindows.add(w);
-        } else if (stack.mStackId == ASSISTANT_STACK_ID) {
+        } else if (stackId == ASSISTANT_STACK_ID) {
             mAssistantWindows.add(w);
         }
     }
 
     private void adjustSpecialWindows() {
-        int layer = mHighestApplicationLayer + WINDOW_LAYER_MULTIPLIER;
-        // For pinned and docked stack window, we want to make them above other windows also when
-        // these windows are animating.
-        while (!mDockedWindows.isEmpty()) {
-            layer = assignAndIncreaseLayerIfNeeded(mDockedWindows.remove(), layer);
+        // The following adjustments are beyond the highest docked-affected layer
+        int layer = mHighestDockedAffectedLayer +  WINDOW_LAYER_MULTIPLIER;
+
+        // Adjust the docked stack windows and dock divider above only the windows that are affected
+        // by the docked stack. When this happens, also boost the assistant window layers, otherwise
+        // the docked stack windows & divider would be promoted above the assistant.
+        if (!mDockedWindows.isEmpty() && mHighestDockedAffectedLayer > 0) {
+            while (!mDockedWindows.isEmpty()) {
+                final WindowState window = mDockedWindows.remove();
+                layer = assignAndIncreaseLayerIfNeeded(window, layer);
+            }
+
+            layer = assignAndIncreaseLayerIfNeeded(mDockDivider, layer);
+
+            while (!mAssistantWindows.isEmpty()) {
+                final WindowState window = mAssistantWindows.remove();
+                if (window.mLayer > mHighestDockedAffectedLayer) {
+                    layer = assignAndIncreaseLayerIfNeeded(window, layer);
+                }
+            }
         }
 
-        layer = assignAndIncreaseLayerIfNeeded(mDockDivider, layer);
+        // The following adjustments are beyond the highest app layer or boosted layer
+        layer = Math.max(layer, mHighestApplicationLayer + WINDOW_LAYER_MULTIPLIER);
 
         // We know that we will be animating a relaunching window in the near future, which will
         // receive a z-order increase. We want the replaced window to immediately receive the same
@@ -213,12 +229,6 @@
             layer = assignAndIncreaseLayerIfNeeded(mReplacingWindows.remove(), layer);
         }
 
-        // Adjust the assistant stack windows to be above the docked and fullscreen stack windows,
-        // but under the pinned stack windows
-        while (!mAssistantWindows.isEmpty()) {
-            layer = assignAndIncreaseLayerIfNeeded(mAssistantWindows.remove(), layer);
-        }
-
         while (!mPinnedWindows.isEmpty()) {
             layer = assignAndIncreaseLayerIfNeeded(mPinnedWindows.remove(), layer);
         }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 7a91d1e..8ba36d5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -19,16 +19,17 @@
 import static android.Manifest.permission.MANAGE_APP_TOKENS;
 import static android.Manifest.permission.READ_FRAME_BUFFER;
 import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
+import static android.Manifest.permission.RESTRICTED_VR_ACCESS;
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
 import static android.app.StatusBarManager.DISABLE_MASK;
 import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
 import static android.content.Intent.ACTION_USER_REMOVED;
 import static android.content.Intent.EXTRA_USER_HANDLE;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Process.ROOT_UID;
 import static android.os.Process.SHELL_UID;
 import static android.os.Process.SYSTEM_UID;
-import static android.os.Process.THREAD_PRIORITY_DISPLAY;
 import static android.os.Process.myPid;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.os.UserHandle.USER_NULL;
@@ -48,7 +49,6 @@
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TASK_SNAPSHOT;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
@@ -79,6 +79,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
@@ -132,6 +133,8 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Region;
+import android.hardware.configstore.V1_0.ISurfaceFlingerConfigs;
+import android.hardware.configstore.V1_0.OptionalBool;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.input.InputManager;
@@ -182,6 +185,7 @@
 import android.view.IOnKeyguardExitResult;
 import android.view.IPinnedStackListener;
 import android.view.IRotationWatcher;
+import android.view.IWallpaperVisibilityListener;
 import android.view.IWindow;
 import android.view.IWindowId;
 import android.view.IWindowManager;
@@ -228,7 +232,6 @@
 import com.android.server.EventLogTags;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
-import com.android.server.ThreadPriorityBooster;
 import com.android.server.UiThread;
 import com.android.server.Watchdog;
 import com.android.server.input.InputManagerService;
@@ -355,6 +358,8 @@
 
     final private KeyguardDisableHandler mKeyguardDisableHandler;
     boolean mKeyguardGoingAway;
+    // VR Vr2d Display Id.
+    int mVr2dDisplayId = INVALID_DISPLAY;
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -550,9 +555,9 @@
     }
 
     class RotationWatcher {
-        IRotationWatcher mWatcher;
-        IBinder.DeathRecipient mDeathRecipient;
-        int mDisplayId;
+        final IRotationWatcher mWatcher;
+        final IBinder.DeathRecipient mDeathRecipient;
+        final int mDisplayId;
         RotationWatcher(IRotationWatcher watcher, IBinder.DeathRecipient deathRecipient,
                 int displayId) {
             mWatcher = watcher;
@@ -563,6 +568,8 @@
 
     ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<>();
     int mDeferredRotationPauseCount;
+    final WallpaperVisibilityListeners mWallpaperVisibilityListeners =
+            new WallpaperVisibilityListeners();
 
     int mSystemDecorLayer = 0;
     final Rect mScreenRect = new Rect();
@@ -713,6 +720,9 @@
     final DisplayManager mDisplayManager;
     private final Display[] mDisplays;
 
+    // Indicates whether this device supports wide color gamut rendering
+    private boolean mHasWideColorGamutSupport;
+
     // Who is holding the screen on.
     private Session mHoldingScreenOn;
     private PowerManager.WakeLock mHoldingScreenWakeLock;
@@ -757,7 +767,7 @@
         }
 
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             boolean handled = false;
             try {
                 if (mDragState == null) {
@@ -898,29 +908,16 @@
         }
     }
 
-    void closeSurfaceTransaction() {
-        closeSurfaceTransaction(true /* withLockHeld */);
-    }
-
     /**
      * Closes a surface transaction.
-     *
-     * @param withLockHeld Whether to acquire the window manager while doing so. In some cases
-     *                     holding the lock my lead to starvation in WM in case closeTransaction
-     *                     blocks and we call it repeatedly, like we do for animations.
      */
-    void closeSurfaceTransaction(boolean withLockHeld) {
+    void closeSurfaceTransaction() {
         try {
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction");
             synchronized (mWindowMap) {
                 if (mRoot.mSurfaceTraceEnabled) {
                     mRoot.mRemoteEventTrace.closeSurfaceTransaction();
                 }
-                if (withLockHeld) {
-                    SurfaceControl.closeTransaction();
-                }
-            }
-            if (!withLockHeld) {
                 SurfaceControl.closeTransaction();
             }
         } finally {
@@ -928,6 +925,34 @@
         }
     }
 
+    /**
+     * Executes an empty animation transaction without holding the WM lock to simulate
+     * back-pressure. See {@link WindowAnimator#animate} why this is needed.
+     */
+    void executeEmptyAnimationTransaction() {
+        try {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "openSurfaceTransaction");
+            synchronized (mWindowMap) {
+                if (mRoot.mSurfaceTraceEnabled) {
+                    mRoot.mRemoteEventTrace.openSurfaceTransaction();
+                }
+                SurfaceControl.openTransaction();
+                SurfaceControl.setAnimationTransaction();
+                if (mRoot.mSurfaceTraceEnabled) {
+                    mRoot.mRemoteEventTrace.closeSurfaceTransaction();
+                }
+            }
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
+        try {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction");
+            SurfaceControl.closeTransaction();
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
+    }
+
     /** Listener to notify activity manager about app transitions. */
     final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier
             = new WindowManagerInternal.AppTransitionListener() {
@@ -2010,8 +2035,7 @@
                     win.setDisplayLayoutNeeded();
                     mWindowPlacerLocked.performSurfacePlacement(true);
                 }
-                result = win.relayoutVisibleWindow(mergedConfiguration, result, attrChanges,
-                        oldVisibility);
+                result = win.relayoutVisibleWindow(result, attrChanges, oldVisibility);
 
                 try {
                     result = createSurfaceControl(outSurface, result, win, winAnimator);
@@ -2149,6 +2173,15 @@
             if (!win.isGoneForLayoutLw()) {
                 win.mResizedWhileGone = false;
             }
+
+            // We must always send the latest {@link MergedConfiguration}, regardless of whether we
+            // have already reported it. The client might not have processed the previous value yet
+            // and needs process it before handling the corresponding window frame. the variable
+            // {@code mergedConfiguration} is an out parameter that will be passed back to the
+            // client over IPC and checked there.
+            win.getMergedConfiguration(mergedConfiguration);
+            win.setReportedConfiguration(mergedConfiguration);
+
             outFrame.set(win.mCompatFrame);
             outOverscanInsets.set(win.mOverscanInsets);
             outContentInsets.set(win.mContentInsets);
@@ -2307,7 +2340,7 @@
         // artifacts when we unfreeze the display if some different animation
         // is running.
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WM#applyAnimationLocked");
-        if (okToDisplay()) {
+        if (okToAnimate()) {
             final DisplayContent displayContent = atoken.getTask().getDisplayContent();
             final DisplayInfo displayInfo = displayContent.getDisplayInfo();
             final int width = displayInfo.appWidth;
@@ -2387,6 +2420,10 @@
         return !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn();
     }
 
+    boolean okToAnimate() {
+        return okToDisplay() && mPolicy.okToAnimate();
+    }
+
     @Override
     public void addWindowToken(IBinder binder, int type, int displayId) {
         if (!checkCallingPermission(MANAGE_APP_TOKENS, "addWindowToken()")) {
@@ -2653,7 +2690,7 @@
         synchronized(mWindowMap) {
             boolean prepared = mAppTransition.prepareAppTransitionLocked(transit, alwaysKeepCurrent,
                     flags, forceOverride);
-            if (prepared && okToDisplay()) {
+            if (prepared && okToAnimate()) {
                 mSkipAppTransitionAnimation = false;
             }
         }
@@ -3071,6 +3108,10 @@
         return mPolicy.isKeyguardLocked();
     }
 
+    public boolean isKeyguardShowingAndNotOccluded() {
+        return mPolicy.isKeyguardShowingAndNotOccluded();
+    }
+
     @Override
     public boolean isKeyguardSecure() {
         int userId = UserHandle.getCallingUserId();
@@ -3445,21 +3486,11 @@
             }
 
             if (!mBootAnimationStopped) {
-                // Do this one time.
                 Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
-                try {
-                    IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
-                    if (surfaceFlinger != null) {
-                        Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
-                        Parcel data = Parcel.obtain();
-                        data.writeInterfaceToken("android.ui.ISurfaceComposer");
-                        surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
-                                data, null, 0);
-                        data.recycle();
-                    }
-                } catch (RemoteException ex) {
-                    Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!");
-                }
+                // stop boot animation
+                // formerly we would just kill the process, but we now ask it to exit so it
+                // can choose where to stop the animation.
+                SystemProperties.set("service.bootanim.exit", "1");
                 mBootAnimationStopped = true;
             }
 
@@ -3468,6 +3499,20 @@
                 return;
             }
 
+            try {
+                IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
+                if (surfaceFlinger != null) {
+                    Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
+                    Parcel data = Parcel.obtain();
+                    data.writeInterfaceToken("android.ui.ISurfaceComposer");
+                    surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
+                            data, null, 0);
+                    data.recycle();
+                }
+            } catch (RemoteException ex) {
+                Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!");
+            }
+
             EventLog.writeEvent(EventLogTags.WM_BOOT_ANIMATION_DONE, SystemClock.uptimeMillis());
             Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
             mDisplayEnabled = true;
@@ -3989,6 +4034,29 @@
         }
     }
 
+    @Override
+    public boolean registerWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
+            int displayId) {
+        synchronized (mWindowMap) {
+            final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+            if (displayContent == null) {
+                throw new IllegalArgumentException("Trying to register visibility event "
+                        + "for invalid display: " + displayId);
+            }
+            mWallpaperVisibilityListeners.registerWallpaperVisibilityListener(listener, displayId);
+            return displayContent.mWallpaperController.isWallpaperVisible();
+        }
+    }
+
+    @Override
+    public void unregisterWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
+            int displayId) {
+        synchronized (mWindowMap) {
+            mWallpaperVisibilityListeners
+                    .unregisterWallpaperVisibilityListener(listener, displayId);
+        }
+    }
+
     /**
      * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
      * theme attribute) on devices that feature a physical options menu key attempt to position
@@ -4740,6 +4808,20 @@
     public void systemReady() {
         mPolicy.systemReady();
         mTaskSnapshotController.systemReady();
+        mHasWideColorGamutSupport = queryWideColorGamutSupport();
+    }
+
+    private static boolean queryWideColorGamutSupport() {
+        try {
+            ISurfaceFlingerConfigs surfaceFlinger = ISurfaceFlingerConfigs.getService();
+            OptionalBool hasWideColor = surfaceFlinger.hasWideColorDisplay();
+            if (hasWideColor != null) {
+                return hasWideColor.value;
+            }
+        } catch (RemoteException e) {
+            // Ignore, we're in big trouble if we can't talk to SurfaceFlinger's config store
+        }
+        return false;
     }
 
     // -------------------------------------------------------------
@@ -5729,7 +5811,7 @@
         // orientation.
         if (!okToDisplay() && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
             if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Changing surface while display frozen: " + w);
-            w.mOrientationChanging = true;
+            w.setOrientationChanging(true);
             w.mLastFreezeDuration = 0;
             mRoot.mOrientationChangeComplete = false;
             if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) {
@@ -5943,9 +6025,9 @@
             return;
         }
 
-        if (!displayContent.isReady() || !mPolicy.isScreenOn()) {
-            // No need to freeze the screen before the display is ready, system is ready, or if
-            // the screen is off.
+        if (!displayContent.isReady() || !mPolicy.isScreenOn() || !okToAnimate()) {
+            // No need to freeze the screen before the display is ready,  if the screen is off,
+            // or we can't currently animate.
             return;
         }
 
@@ -6232,6 +6314,22 @@
         }
     }
 
+    /**
+     * Used by ActivityManager to determine where to position an app with aspect ratio shorter then
+     * the screen is.
+     * @see WindowManagerPolicy#getNavBarPosition()
+     */
+    public int getNavBarPosition() {
+        synchronized (mWindowMap) {
+            // Perform layout if it was scheduled before to make sure that we get correct nav bar
+            // position when doing rotations.
+            final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
+            defaultDisplayContent.performLayout(false /* initial */,
+                    false /* updateInputWindows */);
+            return mPolicy.getNavBarPosition();
+        }
+    }
+
     @Override
     public WindowManagerPolicy.InputConsumer createInputConsumer(Looper looper, String name,
             InputEventReceiver.Factory inputEventReceiverFactory) {
@@ -6255,6 +6353,20 @@
     }
 
     @Override
+    public Region getCurrentImeTouchRegion() {
+        if (mContext.checkCallingOrSelfPermission(RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
+            throw new SecurityException("getCurrentImeTouchRegion is restricted to VR services");
+        }
+        synchronized (mWindowMap) {
+            final Region r = new Region();
+            if (mInputMethodWindow != null) {
+                mInputMethodWindow.getTouchableRegion(r);
+            }
+            return r;
+        }
+    }
+
+    @Override
     public boolean hasNavigationBar() {
         return mPolicy.hasNavigationBar();
     }
@@ -7298,6 +7410,11 @@
         }
 
         @Override
+        public boolean isKeyguardShowingAndNotOccluded() {
+            return WindowManagerService.this.isKeyguardShowingAndNotOccluded();
+        }
+
+        @Override
         public void showGlobalActions() {
             WindowManagerService.this.showGlobalActions();
         }
@@ -7447,6 +7564,16 @@
                 accessibilityController.performComputeChangedWindowsNotLocked();
             }
         }
+
+        @Override
+        public void setVr2dDisplayId(int vr2dDisplayId) {
+            if (DEBUG_DISPLAY) {
+                Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
+            }
+            synchronized (WindowManagerService.this) {
+                mVr2dDisplayId = vr2dDisplayId;
+            }
+        }
     }
 
     void registerAppFreezeListener(AppFreezeListener listener) {
@@ -7519,4 +7646,8 @@
             }
         }
     }
+
+    boolean hasWideColorGamutSupport() {
+        return mHasWideColorGamutSupport;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index f74948f..96582fc 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -441,7 +441,18 @@
      * Set when the orientation is changing and this window has not yet
      * been updated for the new orientation.
      */
-    boolean mOrientationChanging;
+    private boolean mOrientationChanging;
+
+    /**
+     * Sometimes in addition to the mOrientationChanging
+     * flag we report that the orientation is changing
+     * due to a mismatch in current and reported configuration.
+     *
+     * In the case of timeout we still need to make sure we
+     * leave the orientation changing state though, so we
+     * use this as a special time out escape hatch.
+     */
+    private boolean mOrientationChangeTimedOut;
 
     /**
      * The orientation during the last visible call to relayout. If our
@@ -560,6 +571,13 @@
     final Rect mLastSurfaceInsets = new Rect();
 
     /**
+     * A flag set by the {@link WindowState} parent to indicate that the parent has examined this
+     * {@link WindowState} in its overall drawing context. This book-keeping allows the parent to
+     * make sure all children have been considered.
+     */
+    private boolean mDrawnStateEvaluated;
+
+    /**
      * Compares two window sub-layers and returns -1 if the first is lesser than the second in terms
      * of z-order and 1 otherwise.
      */
@@ -675,6 +693,27 @@
         mSession.windowAddedLocked(mAttrs.packageName);
     }
 
+    /**
+     * Returns whether this {@link WindowState} has been considered for drawing by its parent.
+     */
+    boolean getDrawnStateEvaluated() {
+        return mDrawnStateEvaluated;
+    }
+
+    /**
+     * Sets whether this {@link WindowState} has been considered for drawing by its parent. Should
+     * be cleared when detached from parent.
+     */
+    void setDrawnStateEvaluated(boolean evaluated) {
+        mDrawnStateEvaluated = evaluated;
+    }
+
+    @Override
+    void onParentSet() {
+        super.onParentSet();
+        setDrawnStateEvaluated(false /*evaluated*/);
+    }
+
     @Override
     public int getOwningUid() {
         return mOwnerUid;
@@ -726,7 +765,7 @@
         // If the task has temp inset bounds set, we have to make sure all its windows uses
         // the temp inset frame. Otherwise different display frames get applied to the main
         // window and the child window, making them misaligned.
-        if (inFullscreenContainer) {
+        if (inFullscreenContainer || isLetterboxedAppWindow()) {
             mInsetFrame.setEmpty();
         } else if (task != null && isInMultiWindowMode()) {
             task.getTempInsetBounds(mInsetFrame);
@@ -1156,7 +1195,8 @@
             // then we need to hold off on unfreezing the display until this window has been
             // redrawn; to do that, we need to go through the process of getting informed by the
             // application when it has finished drawing.
-            if (mOrientationChanging || dragResizingChanged || isResizedWhileNotDragResizing()) {
+            if (getOrientationChanging() || dragResizingChanged
+                    || isResizedWhileNotDragResizing()) {
                 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) {
                     Slog.v(TAG_WM, "Orientation or resize start waiting for draw"
                             + ", mDrawState=DRAW_PENDING in " + this
@@ -1171,17 +1211,40 @@
                 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG_WM, "Resizing window " + this);
                 mService.mResizingWindows.add(this);
             }
-        } else if (mOrientationChanging) {
+        } else if (getOrientationChanging()) {
             if (isDrawnLw()) {
                 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Orientation not waiting for draw in "
                         + this + ", surfaceController " + winAnimator.mSurfaceController);
-                mOrientationChanging = false;
+                setOrientationChanging(false);
                 mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                         - mService.mDisplayFreezeTime);
             }
         }
     }
 
+    boolean getOrientationChanging() {
+        // In addition to the local state flag, we must also consider the difference in the last
+        // reported configuration vs. the current state. If the client code has not been informed of
+        // the change, logic dependent on having finished processing the orientation, such as
+        // unfreezing, could be improperly triggered.
+        // TODO(b/62846907): Checking against {@link mLastReportedConfiguration} could be flaky as
+        //                   this is not necessarily what the client has processed yet. Find a
+        //                   better indicator consistent with the client.
+        return (mOrientationChanging || (isVisible()
+                && getConfiguration().orientation != mLastReportedConfiguration.orientation))
+                && !mSeamlesslyRotated
+                && !mOrientationChangeTimedOut;
+    }
+
+    void setOrientationChanging(boolean changing) {
+        mOrientationChanging = changing;
+        mOrientationChangeTimedOut = false;
+    }
+
+    void orientationChangeTimedOut() {
+        mOrientationChangeTimedOut = true;
+    }
+
     DisplayContent getDisplayContent() {
         return mToken.getDisplayContent();
     }
@@ -1412,8 +1475,18 @@
     @Override
     public boolean canAffectSystemUiFlags() {
         final boolean shown = mWinAnimator.getShown();
-        final boolean exiting = mAnimatingExit || mDestroying
-                || mAppToken != null && mAppToken.hidden;
+
+        // We only consider the app to be exiting when the animation has started. After the app
+        // transition is executed the windows are marked exiting before the new windows have been
+        // shown. Thus, wait considering a window to be exiting after the animation has actually
+        // started.
+        final boolean appAnimationStarting = mAppToken != null
+                && mAppToken.mAppAnimator.isAnimationStarting();
+        final boolean exitingSelf = mAnimatingExit && (!mWinAnimator.isAnimationStarting()
+                && !appAnimationStarting);
+        final boolean appExiting = mAppToken != null && mAppToken.hidden && !appAnimationStarting;
+
+        final boolean exiting = exitingSelf || mDestroying || appExiting;
         final boolean translucent = mAttrs.alpha == 0.0f;
         return shown && !exiting && !translucent;
     }
@@ -1633,7 +1706,7 @@
         final boolean adjustedForMinimizedDockOrIme = task != null
                 && (task.mStack.isAdjustedForMinimizedDockedStack()
                 || task.mStack.isAdjustedForIme());
-        if (mService.okToDisplay()
+        if (mService.okToAnimate()
                 && (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
                 && !isDragResizing() && !adjustedForMinimizedDockOrIme
                 && (task == null || getTask().mStack.hasMovementAnimations())
@@ -1802,7 +1875,7 @@
         // First, see if we need to run an animation. If we do, we have to hold off on removing the
         // window until the animation is done. If the display is frozen, just remove immediately,
         // since the animation wouldn't be seen.
-        if (mHasSurface && mService.okToDisplay()) {
+        if (mHasSurface && mService.okToAnimate()) {
             if (mWillReplaceWindow) {
                 // This window is going to be replaced. We need to keep it around until the new one
                 // gets added, then we will get rid of this one.
@@ -1942,6 +2015,12 @@
             return false;
         }
 
+        final boolean windowsAreFocusable = mAppToken == null || mAppToken.windowsAreFocusable();
+        if (!windowsAreFocusable) {
+            // This window can't be an IME target if the app's windows should not be focusable.
+            return false;
+        }
+
         final int fl = mAttrs.flags & (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
         final int type = mAttrs.type;
 
@@ -1975,6 +2054,11 @@
         if (dc == null) {
             return;
         }
+
+        // If layout is currently deferred, we want to hold of with updating the layers.
+        if (mService.mWindowPlacerLocked.isLayoutDeferred()) {
+            return;
+        }
         final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser();
         if (dimLayerUser != null && dc.mDimLayerController.isDimming(dimLayerUser, mWinAnimator)) {
             // Force an animation pass just to update the mDimLayer layer.
@@ -1987,7 +2071,7 @@
             super(inputChannel, mService.mH.getLooper());
         }
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             finishInputEvent(event, true);
         }
     }
@@ -2207,8 +2291,7 @@
         }
     }
 
-    void prepareWindowToDisplayDuringRelayout(MergedConfiguration mergedConfiguration,
-            boolean wasVisible) {
+    void prepareWindowToDisplayDuringRelayout(boolean wasVisible) {
         // We need to turn on screen regardless of visibility.
         if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) {
             if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this);
@@ -2227,19 +2310,19 @@
             mLayoutNeeded = true;
         }
 
-        if (isDrawnLw() && mService.okToDisplay()) {
+        if (isDrawnLw() && mService.okToAnimate()) {
             mWinAnimator.applyEnterAnimationLocked();
         }
+    }
 
-        if (isConfigChanged()) {
-            final Configuration globalConfig = mService.mRoot.getConfiguration();
-            final Configuration overrideConfig = getMergedOverrideConfiguration();
-            mergedConfiguration.setConfiguration(globalConfig, overrideConfig);
-            if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this
-                    + " visible with new global config: " + globalConfig
-                    + " merged override config: " + overrideConfig);
-            mLastReportedConfiguration.setTo(getConfiguration());
-        }
+    void getMergedConfiguration(MergedConfiguration outConfiguration) {
+        final Configuration globalConfig = mService.mRoot.getConfiguration();
+        final Configuration overrideConfig = getMergedOverrideConfiguration();
+        outConfiguration.setConfiguration(globalConfig, overrideConfig);
+    }
+
+    void setReportedConfiguration(MergedConfiguration config) {
+        mLastReportedConfiguration.setTo(config.getMergedConfiguration());
     }
 
     void adjustStartingWindowFlags() {
@@ -2379,7 +2462,7 @@
         if (doAnimation) {
             if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
                     + mPolicyVisibility + " mAnimation=" + mWinAnimator.mAnimation);
-            if (!mService.okToDisplay()) {
+            if (!mService.okToAnimate()) {
                 doAnimation = false;
             } else if (mPolicyVisibility && mWinAnimator.mAnimation == null) {
                 // Check for the case where we are currently visible and
@@ -2409,7 +2492,7 @@
 
     boolean hideLw(boolean doAnimation, boolean requestAnim) {
         if (doAnimation) {
-            if (!mService.okToDisplay()) {
+            if (!mService.okToAnimate()) {
                 doAnimation = false;
             }
         }
@@ -2636,10 +2719,10 @@
 
         mAppFreezing = false;
 
-        if (mHasSurface && !mOrientationChanging
+        if (mHasSurface && !getOrientationChanging()
                 && mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
             if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + this);
-            mOrientationChanging = true;
+            setOrientationChanging(true);
             mService.mRoot.mOrientationChangeComplete = false;
         }
         mLastFreezeDuration = 0;
@@ -3005,14 +3088,12 @@
         try {
             if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this
                     + ": " + mCompatFrame);
-            final MergedConfiguration mergedConfiguration;
-            if (isConfigChanged()) {
-                mergedConfiguration = new MergedConfiguration(mService.mRoot.getConfiguration(),
-                        getMergedOverrideConfiguration());
-                mLastReportedConfiguration.setTo(mergedConfiguration.getMergedConfiguration());
-            } else {
-                mergedConfiguration = null;
-            }
+            final MergedConfiguration mergedConfiguration =
+                    new MergedConfiguration(mService.mRoot.getConfiguration(),
+                    getMergedOverrideConfiguration());
+
+            setReportedConfiguration(mergedConfiguration);
+
             if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == DRAW_PENDING)
                 Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING");
 
@@ -3060,7 +3141,7 @@
             mWinAnimator.mSurfaceResized = false;
             mReportOrientationChanged = false;
         } catch (RemoteException e) {
-            mOrientationChanging = false;
+            setOrientationChanging(false);
             mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                     - mService.mDisplayFreezeTime);
             // We are assuming the hosting process is dead or in a zombie state.
@@ -3155,6 +3236,15 @@
         return !isInMultiWindowMode();
     }
 
+    /** @return true when the window is in fullscreen task, but has non-fullscreen bounds set. */
+    boolean isLetterboxedAppWindow() {
+        final Task task = getTask();
+        final boolean taskIsFullscreen = task != null && task.isFullscreen();
+        final boolean appWindowIsFullscreen = mAppToken != null && !mAppToken.hasBounds();
+
+        return taskIsFullscreen && !appWindowIsFullscreen;
+    }
+
     /** Returns the appropriate bounds to use for computing frames. */
     private void getContainerBounds(Rect outBounds) {
         if (isInMultiWindowMode()) {
@@ -3319,7 +3409,11 @@
                 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
                 pw.print(prefix); pw.print(" isAnimatingWithSavedSurface()=");
                 pw.print(isAnimatingWithSavedSurface());
-                pw.print(" mAppDied=");pw.println(mAppDied);
+                pw.print(" mAppDied=");pw.print(mAppDied);
+                pw.print(prefix); pw.print("drawnStateEvaluated=");
+                        pw.print(getDrawnStateEvaluated());
+                pw.print(prefix); pw.print("mightAffectAllDrawn=");
+                        pw.println(mightAffectAllDrawn(false /*visibleOnly*/));
             }
             pw.print(prefix); pw.print("mViewVisibility=0x");
             pw.print(Integer.toHexString(mViewVisibility));
@@ -3419,10 +3513,13 @@
                     pw.print(" mDestroying="); pw.print(mDestroying);
                     pw.print(" mRemoved="); pw.println(mRemoved);
         }
-        if (mOrientationChanging || mAppFreezing || mTurnOnScreen
+        if (getOrientationChanging() || mAppFreezing || mTurnOnScreen
                 || mReportOrientationChanged) {
             pw.print(prefix); pw.print("mOrientationChanging=");
                     pw.print(mOrientationChanging);
+                    pw.print(" configOrientationChanging=");
+                    pw.print(mLastReportedConfiguration.orientation
+                            != getConfiguration().orientation);
                     pw.print(" mAppFreezing="); pw.print(mAppFreezing);
                     pw.print(" mTurnOnScreen="); pw.print(mTurnOnScreen);
                     pw.print(" mReportOrientationChanged="); pw.println(mReportOrientationChanged);
@@ -3459,6 +3556,8 @@
         if (computeDragResizing()) {
             pw.print(prefix); pw.println("computeDragResizing=" + computeDragResizing());
         }
+        pw.print(prefix); pw.println("isOnScreen=" + isOnScreen());
+        pw.print(prefix); pw.println("isVisible=" + isVisible());
     }
 
     @Override
@@ -4342,8 +4441,7 @@
         return !mLastSurfaceInsets.equals(mAttrs.surfaceInsets);
     }
 
-    int relayoutVisibleWindow(MergedConfiguration mergedConfiguration, int result, int attrChanges,
-            int oldVisibility) {
+    int relayoutVisibleWindow(int result, int attrChanges, int oldVisibility) {
         final boolean wasVisible = isVisibleLw();
 
         result |= (!wasVisible || !isDrawnLw()) ? RELAYOUT_RES_FIRST_TIME : 0;
@@ -4366,7 +4464,7 @@
 
         mWinAnimator.mEnteringAnimation = true;
 
-        prepareWindowToDisplayDuringRelayout(mergedConfiguration, wasVisible);
+        prepareWindowToDisplayDuringRelayout(wasVisible);
 
         if ((attrChanges & FORMAT_CHANGED) != 0) {
             // If the format can't be changed in place, preserve the old surface until the app draws
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 33cb908..86265c29 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -20,6 +20,7 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
 import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
@@ -368,7 +369,7 @@
         // we just started or just stopped animating by comparing mWasAnimating with isAnimationSet().
         mWasAnimating = mAnimating;
         final DisplayContent displayContent = mWin.getDisplayContent();
-        if (displayContent != null && mService.okToDisplay()) {
+        if (displayContent != null && mService.okToAnimate()) {
             // We will run animations as long as the display isn't frozen.
 
             if (mWin.isDrawnLw() && mAnimation != null) {
@@ -631,6 +632,10 @@
             return mSurfaceController;
         }
 
+        if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
+            windowType = SurfaceControl.WINDOW_TYPE_DONT_SCREENSHOT;
+        }
+
         w.setHasSurface(false);
 
         if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
@@ -1195,7 +1200,8 @@
         if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame="
                 + w.mDecorFrame + " mSystemDecorRect=" + mSystemDecorRect);
 
-        final boolean fullscreen = w.fillsDisplay();
+        final Task task = w.getTask();
+        final boolean fullscreen = w.fillsDisplay() || (task != null && task.isFullscreen());
         final boolean isFreeformResizing =
                 w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
 
@@ -1521,17 +1527,30 @@
         }
     }
 
+    /**
+     * Get rect of the task this window is currently in. If there is no task, rect will be set to
+     * empty.
+     */
+    void getContainerRect(Rect rect) {
+        final Task task = mWin.getTask();
+        if (task != null) {
+            task.getDimBounds(rect);
+        } else {
+            rect.left = rect.top = rect.right = rect.bottom = 0;
+        }
+    }
+
     void prepareSurfaceLocked(final boolean recoveringMemory) {
         final WindowState w = mWin;
         if (!hasSurface()) {
 
             // There is no need to wait for an animation change if our window is gone for layout
             // already as we'll never be visible.
-            if (w.mOrientationChanging && w.isGoneForLayoutLw()) {
+            if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
                 if (DEBUG_ORIENTATION) {
                     Slog.v(TAG, "Orientation change skips hidden " + w);
                 }
-                w.mOrientationChanging = false;
+                w.setOrientationChanging(false);
             }
             return;
         }
@@ -1564,8 +1583,8 @@
             // really hidden (gone for layout), there is no point in still waiting for it.
             // Note that this does introduce a potential glitch if the window becomes unhidden
             // before it has drawn for the new orientation.
-            if (w.mOrientationChanging && w.isGoneForLayoutLw()) {
-                w.mOrientationChanging = false;
+            if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
+                w.setOrientationChanging(false);
                 if (DEBUG_ORIENTATION) Slog.v(TAG,
                         "Orientation change skips hidden " + w);
             }
@@ -1604,21 +1623,38 @@
                         recoveringMemory);
             mSurfaceController.setLayer(mAnimLayer);
 
-            if (prepared && mLastHidden && mDrawState == HAS_DRAWN) {
-                if (showSurfaceRobustlyLocked()) {
-                    markPreservedSurfaceForDestroy();
-                    mAnimator.requestRemovalOfReplacedWindows(w);
-                    mLastHidden = false;
-                    if (mIsWallpaper) {
-                        w.dispatchWallpaperVisibility(true);
+            if (prepared && mDrawState == HAS_DRAWN) {
+                if (mLastHidden) {
+                    if (showSurfaceRobustlyLocked()) {
+                        markPreservedSurfaceForDestroy();
+                        mAnimator.requestRemovalOfReplacedWindows(w);
+                        mLastHidden = false;
+                        if (mIsWallpaper) {
+                            w.dispatchWallpaperVisibility(true);
+                        }
+                        // This draw means the difference between unique content and mirroring.
+                        // Run another pass through performLayout to set mHasContent in the
+                        // LogicalDisplay.
+                        mAnimator.setPendingLayoutChanges(w.getDisplayId(),
+                                WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
+                    } else {
+                        w.setOrientationChanging(false);
                     }
-                    // This draw means the difference between unique content and mirroring.
-                    // Run another pass through performLayout to set mHasContent in the
-                    // LogicalDisplay.
-                    mAnimator.setPendingLayoutChanges(w.getDisplayId(),
-                            WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
-                } else {
-                    w.mOrientationChanging = false;
+                }
+                // We process mTurnOnScreen even for windows which have already
+                // been shown, to handle cases where windows are not necessarily
+                // hidden while the screen is turning off.
+                // TODO(b/63773439): These cases should be eliminated, though we probably still
+                // want to process mTurnOnScreen in this way for clarity.
+                if (mWin.mTurnOnScreen && mWin.mAppToken.canTurnScreenOn()) {
+                    if (DEBUG_VISIBILITY) Slog.v(TAG, "Show surface turning screen on: " + mWin);
+                    mWin.mTurnOnScreen = false;
+
+                    // The window should only turn the screen on once per resume, but
+                    // prepareSurfaceLocked can be called multiple times. Set canTurnScreenOn to
+                    // false so the window doesn't turn the screen on again during this resume.
+                    mWin.mAppToken.setCanTurnScreenOn(false);
+                    mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
                 }
             }
             if (hasSurface()) {
@@ -1631,14 +1667,14 @@
             displayed = true;
         }
 
-        if (w.mOrientationChanging) {
+        if (w.getOrientationChanging()) {
             if (!w.isDrawnLw()) {
                 mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
                 mAnimator.mLastWindowFreezeSource = w;
                 if (DEBUG_ORIENTATION) Slog.v(TAG,
                         "Orientation continue waiting for draw in " + w);
             } else {
-                w.mOrientationChanging = false;
+                w.setOrientationChanging(false);
                 if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
             }
         }
@@ -1730,11 +1766,6 @@
         if (!shown)
             return false;
 
-        if (mWin.mTurnOnScreen) {
-            if (DEBUG_VISIBILITY) Slog.v(TAG, "Show surface turning screen on: " + mWin);
-            mWin.mTurnOnScreen = false;
-            mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
-        }
         return true;
     }
 
@@ -1781,7 +1812,7 @@
         // artifacts when we unfreeze the display if some different animation
         // is running.
         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WSA#applyAnimationLocked");
-        if (mService.okToDisplay()) {
+        if (mService.okToAnimate()) {
             int anim = mPolicy.selectAnimationLw(mWin, transit);
             int attr = -1;
             Animation a = null;
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 27927e6..4819c0f 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -52,7 +52,7 @@
 
     final WindowStateAnimator mAnimator;
 
-    private SurfaceControl mSurfaceControl;
+    private SurfaceControlWithBackground mSurfaceControl;
 
     // Should only be set from within setShown().
     private boolean mSurfaceShown = false;
@@ -99,15 +99,10 @@
         mWindowType = windowType;
         mWindowSession = win.mSession;
 
-        if (DEBUG_SURFACE_TRACE) {
-            mSurfaceControl = new SurfaceTrace(
-                    s, name, w, h, format, flags, windowType, ownerUid);
-        } else {
-            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
-            mSurfaceControl = new SurfaceControl(
-                    s, name, w, h, format, flags, windowType, ownerUid);
-            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-        }
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
+        mSurfaceControl = new SurfaceControlWithBackground(
+                s, name, w, h, format, flags, windowType, ownerUid, this);
+        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
 
         if (mService.mRoot.mSurfaceTraceEnabled) {
             mSurfaceControl = new RemoteSurfaceTrace(
@@ -120,7 +115,7 @@
     }
 
     void removeRemoteTrace() {
-        mSurfaceControl = new SurfaceControl(mSurfaceControl);
+        mSurfaceControl = new SurfaceControlWithBackground(mSurfaceControl);
     }
 
 
@@ -293,30 +288,30 @@
         mSurfaceControl.setGeometryAppliesWithResize();
     }
 
-    void setMatrixInTransaction(float dsdx, float dtdx, float dsdy, float dtdy,
+    void setMatrixInTransaction(float dsdx, float dtdx, float dtdy, float dsdy,
             boolean recoveringMemory) {
         final boolean matrixChanged = mLastDsdx != dsdx || mLastDtdx != dtdx ||
-                                      mLastDsdy != dsdy || mLastDtdy != dtdy;
+                                      mLastDtdy != dtdy || mLastDsdy != dsdy;
         if (!matrixChanged) {
             return;
         }
 
         mLastDsdx = dsdx;
         mLastDtdx = dtdx;
-        mLastDsdy = dsdy;
         mLastDtdy = dtdy;
+        mLastDsdy = dsdy;
 
         try {
             if (SHOW_TRANSACTIONS) logSurface(
-                    "MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null);
+                    "MATRIX [" + dsdx + "," + dtdx + "," + dtdy + "," + dsdy + "]", null);
             mSurfaceControl.setMatrix(
-                    dsdx, dtdx, dsdy, dtdy);
+                    dsdx, dtdx, dtdy, dsdy);
         } catch (RuntimeException e) {
             // If something goes wrong with the surface (such
             // as running out of memory), don't take down the
             // entire system.
             Slog.e(TAG, "Error setting matrix on surface surface" + title
-                    + " MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null);
+                    + " MATRIX [" + dsdx + "," + dtdx + "," + dtdy + "," + dsdy + "]", null);
             if (!recoveringMemory) {
                 mAnimator.reclaimSomeSurfaceMemory("matrix", true);
             }
@@ -423,6 +418,10 @@
         }
     }
 
+    void getContainerRect(Rect rect) {
+        mAnimator.getContainerRect(rect);
+    }
+
     boolean showRobustlyInTransaction() {
         if (SHOW_TRANSACTIONS) logSurface(
                 "SHOW (performLayout)", null);
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 82c862f..581b044 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -127,6 +127,10 @@
         }
     }
 
+    boolean isLayoutDeferred() {
+        return mDeferDepth > 0;
+    }
+
     final void performSurfacePlacement() {
         performSurfacePlacement(false /* force */);
     }
@@ -233,7 +237,7 @@
      */
     int handleAppTransitionReadyLocked() {
         int appsCount = mService.mOpeningApps.size();
-        if (!transitionGoodToGo(appsCount)) {
+        if (!transitionGoodToGo(appsCount, mTempTransitionReasons)) {
             return 0;
         }
         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "AppTransitionReady");
@@ -375,6 +379,9 @@
                 true /*updateInputWindows*/);
         mService.mFocusMayChange = false;
 
+        mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING,
+                mTempTransitionReasons.clone()).sendToTarget();
+
         Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
 
         return layoutRedo | FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
@@ -499,7 +506,7 @@
         }
     }
 
-    private boolean transitionGoodToGo(int appsCount) {
+    private boolean transitionGoodToGo(int appsCount, SparseIntArray outReasons) {
         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                 "Checking " + appsCount + " opening apps (frozen="
                         + mService.mDisplayFrozen + " timeout="
@@ -508,7 +515,7 @@
             mService.mAnimator.getScreenRotationAnimationLocked(
                     Display.DEFAULT_DISPLAY);
 
-        final SparseIntArray reasons = mTempTransitionReasons;
+        outReasons.clear();
         if (!mService.mAppTransition.isTimeout()) {
             // Imagine the case where we are changing orientation due to an app transition, but a previous
             // orientation change is still in progress. We won't process the orientation change
@@ -542,10 +549,10 @@
                 final TaskStack stack = wtoken.getStack();
                 final int stackId = stack != null ? stack.mStackId : INVALID_STACK_ID;
                 if (allDrawn) {
-                    reasons.put(stackId, drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN
+                    outReasons.put(stackId, drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN
                             : APP_TRANSITION_SAVED_SURFACE);
                 } else {
-                    reasons.put(stackId, wtoken.startingData instanceof SplashScreenStartingData
+                    outReasons.put(stackId, wtoken.startingData instanceof SplashScreenStartingData
                             ? APP_TRANSITION_SPLASH_SCREEN
                             : APP_TRANSITION_SNAPSHOT);
                 }
@@ -569,13 +576,10 @@
             boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
                     mWallpaperControllerLocked.wallpaperTransitionReady();
             if (wallpaperReady) {
-                mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reasons.clone())
-                        .sendToTarget();
                 return true;
             }
             return false;
         }
-        mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reasons.clone()).sendToTarget();
         return true;
     }
 
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index c0757ce..e2a82b7 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -5,6 +5,8 @@
 LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter
 
 LOCAL_SRC_FILES += \
+    $(LOCAL_REL_DIR)/JavaRef.cpp \
+    $(LOCAL_REL_DIR)/NativeCallbackThread.cpp \
     $(LOCAL_REL_DIR)/com_android_server_AlarmManagerService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_am_BatteryStatsService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_connectivity_Vpn.cpp \
@@ -18,15 +20,20 @@
     $(LOCAL_REL_DIR)/com_android_server_lights_LightsService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_location_ContextHubService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_location_GnssLocationProvider.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_locksettings_SyntheticPasswordManager.cpp \
     $(LOCAL_REL_DIR)/com_android_server_power_PowerManagerService.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_radio_RadioService.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_radio_Tuner.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_radio_Tuner_TunerCallback.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_radio_convert.cpp \
     $(LOCAL_REL_DIR)/com_android_server_SerialService.cpp \
-    $(LOCAL_REL_DIR)/com_android_server_SyntheticPasswordManager.cpp \
     $(LOCAL_REL_DIR)/com_android_server_storage_AppFuseBridge.cpp \
     $(LOCAL_REL_DIR)/com_android_server_SystemServer.cpp \
     $(LOCAL_REL_DIR)/com_android_server_tv_TvUinputBridge.cpp \
     $(LOCAL_REL_DIR)/com_android_server_tv_TvInputHal.cpp \
     $(LOCAL_REL_DIR)/com_android_server_vr_VrManagerService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_UsbDeviceManager.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_UsbDescriptorParser.cpp \
     $(LOCAL_REL_DIR)/com_android_server_UsbMidiDevice.cpp \
     $(LOCAL_REL_DIR)/com_android_server_UsbHostManager.cpp \
     $(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp \
@@ -59,7 +66,6 @@
     libhardware \
     libhardware_legacy \
     libhidlbase \
-    libhidltransport \
     libkeystore_binder \
     libnativehelper \
     libutils \
@@ -77,19 +83,26 @@
     libEGL \
     libGLESv2 \
     libnetutils \
+    libhidlbase \
+    libhidltransport \
     libhwbinder \
+    libutils \
     libhwui \
     android.hardware.audio.common@2.0 \
+    android.hardware.broadcastradio@1.0 \
+    android.hardware.broadcastradio@1.1 \
     android.hardware.contexthub@1.0 \
     android.hardware.gnss@1.0 \
     android.hardware.ir@1.0 \
     android.hardware.light@2.0 \
     android.hardware.power@1.0 \
+    android.hardware.power@1.1 \
     android.hardware.tetheroffload.config@1.0 \
     android.hardware.thermal@1.0 \
     android.hardware.tv.cec@1.0 \
     android.hardware.tv.input@1.0 \
     android.hardware.vibrator@1.0 \
+    android.hardware.vibrator@1.1 \
     android.hardware.vr@1.0 \
     android.frameworks.schedulerservice@1.0 \
     android.frameworks.sensorservice@1.0 \
diff --git a/services/core/jni/JavaRef.cpp b/services/core/jni/JavaRef.cpp
new file mode 100644
index 0000000..ad07afa
--- /dev/null
+++ b/services/core/jni/JavaRef.cpp
@@ -0,0 +1,30 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "JavaRef"
+//#define LOG_NDEBUG 0
+
+#include "JavaRef.h"
+
+#include <utils/Log.h>
+
+namespace android {
+
+EnvWrapper::EnvWrapper(JNIEnv *env) : mEnv(env) {
+    ALOGE_IF(env == nullptr, "Environment is a nullptr");
+}
+
+} // namespace android
diff --git a/services/core/jni/JavaRef.h b/services/core/jni/JavaRef.h
new file mode 100644
index 0000000..8a572e2
--- /dev/null
+++ b/services/core/jni/JavaRef.h
@@ -0,0 +1,57 @@
+/**
+ * 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.
+ */
+
+#ifndef _ANDROID_JAVA_REF_H
+#define _ANDROID_JAVA_REF_H
+
+#include <android-base/macros.h>
+#include <functional>
+#include <jni.h>
+#include <memory>
+#include <type_traits>
+
+namespace android {
+
+template <typename T>
+using JavaRef = std::unique_ptr<typename std::remove_pointer<T>::type, std::function<void(T)>>;
+
+template <typename T>
+JavaRef<T> make_javaref(JNIEnv *env, T ref) {
+    return JavaRef<T>(ref, [env](T ref) {
+        if (env && ref) {
+            env->DeleteLocalRef(ref);
+        }
+    });
+}
+
+class EnvWrapper {
+public:
+    EnvWrapper(JNIEnv *env);
+
+    template <typename T>
+    JavaRef<T> operator() (T ref) const {
+        return make_javaref(mEnv, ref);
+    }
+
+private:
+    JNIEnv *mEnv;
+
+    DISALLOW_COPY_AND_ASSIGN(EnvWrapper);
+};
+
+} // namespace android
+
+#endif // _ANDROID_JAVA_REF_H
diff --git a/services/core/jni/NativeCallbackThread.cpp b/services/core/jni/NativeCallbackThread.cpp
new file mode 100644
index 0000000..7d668e3
--- /dev/null
+++ b/services/core/jni/NativeCallbackThread.cpp
@@ -0,0 +1,116 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "NativeCallbackThread"
+//#define LOG_NDEBUG 0
+
+#include "NativeCallbackThread.h"
+
+#include <utils/Log.h>
+
+namespace android {
+
+NativeCallbackThread::NativeCallbackThread(JavaVM *vm) : mExitting(false), mvm(vm) {
+    auto res = pthread_create(&mThread, nullptr, main, this);
+    if (res != 0) {
+        ALOGE("Couldn't start NativeCallbackThread");
+        mThread = 0;
+        return;
+    }
+    ALOGD("Started native callback thread %p", this);
+}
+
+NativeCallbackThread::~NativeCallbackThread() {
+    ALOGV("~NativeCallbackThread %p", this);
+    stop();
+}
+
+void* NativeCallbackThread::main(void *args) {
+    auto self = reinterpret_cast<NativeCallbackThread*>(args);
+    self->main();
+    return nullptr;
+}
+
+void NativeCallbackThread::main() {
+    ALOGV("NativeCallbackThread::main()");
+
+    JNIEnv *env = nullptr;
+    JavaVMAttachArgs aargs = {JNI_VERSION_1_4, "NativeCallbackThread", nullptr};
+    if (mvm->AttachCurrentThread(&env, &aargs) != JNI_OK || env == nullptr) {
+        ALOGE("Couldn't attach thread");
+        return;
+    }
+
+    while (!mExitting) {
+        ALOGV("Waiting for task...");
+        Task task;
+        {
+            AutoMutex _l(mQueueMutex);
+            auto res = mQueueCond.wait(mQueueMutex);
+            ALOGE_IF(res != 0, "Wait failed: %d", res);
+            if (mExitting || res != 0) break;
+
+            if (mQueue.empty()) continue;
+            task = mQueue.front();
+            mQueue.pop();
+        }
+
+        ALOGV("Executing task...");
+        task(env);
+        if (env->ExceptionCheck()) {
+            ALOGE("Unexpected exception:");
+            env->ExceptionDescribe();
+            env->ExceptionClear();
+        }
+    }
+
+    auto res = mvm->DetachCurrentThread();
+    ALOGE_IF(res != JNI_OK, "Couldn't detach thread");
+
+    ALOGV("Native callback thread %p finished", this);
+}
+
+void NativeCallbackThread::enqueue(const Task &task) {
+    AutoMutex _l(mQueueMutex);
+
+    if (mThread == 0 || mExitting) {
+        ALOGW("Callback thread %p is not serving calls", this);
+        return;
+    }
+
+    mQueue.push(task);
+    mQueueCond.signal();
+}
+
+void NativeCallbackThread::stop() {
+    ALOGV("stop() %p", this);
+
+    {
+        AutoMutex _l(mQueueMutex);
+
+        if (mThread == 0 || mExitting) return;
+
+        mExitting = true;
+        mQueueCond.signal();
+    }
+
+    auto ret = pthread_join(mThread, nullptr);
+    ALOGE_IF(ret != 0, "Couldn't join thread: %d", ret);
+
+    ALOGD("Stopped native callback thread %p", this);
+}
+
+} // namespace android
diff --git a/services/core/jni/NativeCallbackThread.h b/services/core/jni/NativeCallbackThread.h
new file mode 100644
index 0000000..4e03b11
--- /dev/null
+++ b/services/core/jni/NativeCallbackThread.h
@@ -0,0 +1,56 @@
+/**
+ * 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.
+ */
+
+#ifndef _ANDROID_NATIVE_CALLBACK_THREAD_H
+#define _ANDROID_NATIVE_CALLBACK_THREAD_H
+
+#include <android-base/macros.h>
+#include <functional>
+#include <jni.h>
+#include <pthread.h>
+#include <queue>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+
+namespace android {
+
+class NativeCallbackThread {
+    typedef std::function<void(JNIEnv*)> Task;
+
+    pthread_t mThread;
+    Mutex mQueueMutex;
+    Condition mQueueCond;
+    std::atomic<bool> mExitting;
+
+    JavaVM *mvm;
+    std::queue<Task> mQueue;
+
+    static void* main(void *args);
+    void main();
+
+    DISALLOW_COPY_AND_ASSIGN(NativeCallbackThread);
+
+public:
+    NativeCallbackThread(JavaVM *vm);
+    virtual ~NativeCallbackThread();
+
+    void enqueue(const Task &task);
+    void stop();
+};
+
+} // namespace android
+
+#endif // _ANDROID_NATIVE_CALLBACK_THREAD_H
diff --git a/services/core/jni/com_android_server_GraphicsStatsService.cpp b/services/core/jni/com_android_server_GraphicsStatsService.cpp
index 7d779a6..8385020 100644
--- a/services/core/jni/com_android_server_GraphicsStatsService.cpp
+++ b/services/core/jni/com_android_server_GraphicsStatsService.cpp
@@ -43,8 +43,9 @@
     std::string path;
     const ProfileData* data = nullptr;
     LOG_ALWAYS_FATAL_IF(jdata == nullptr && jpath == nullptr, "Path and data can't both be null");
+    ScopedByteArrayRO buffer{env};
     if (jdata != nullptr) {
-        ScopedByteArrayRO buffer(env, jdata);
+        buffer.reset(jdata);
         LOG_ALWAYS_FATAL_IF(buffer.size() != sizeof(ProfileData),
                 "Buffer size %zu doesn't match expected %zu!", buffer.size(), sizeof(ProfileData));
         data = reinterpret_cast<const ProfileData*>(buffer.get());
diff --git a/services/core/jni/com_android_server_SyntheticPasswordManager.cpp b/services/core/jni/com_android_server_SyntheticPasswordManager.cpp
deleted file mode 100644
index a9f7b9f..0000000
--- a/services/core/jni/com_android_server_SyntheticPasswordManager.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SyntheticPasswordManager"
-
-#include "JNIHelp.h"
-#include "jni.h"
-
-#include <android_runtime/Log.h>
-#include <utils/Timers.h>
-#include <utils/misc.h>
-#include <utils/String8.h>
-#include <utils/Log.h>
-#include <gatekeeper/password_handle.h>
-
-
-extern "C" {
-#include "crypto_scrypt.h"
-}
-
-namespace android {
-
-static jlong android_server_SyntheticPasswordManager_nativeSidFromPasswordHandle(JNIEnv* env, jobject, jbyteArray handleArray) {
-
-    jbyte* data = (jbyte*)env->GetPrimitiveArrayCritical(handleArray, NULL);
-
-    if (data != NULL) {
-        const gatekeeper::password_handle_t *handle =
-                reinterpret_cast<const gatekeeper::password_handle_t *>(data);
-        jlong sid = handle->user_id;
-        env->ReleasePrimitiveArrayCritical(handleArray, data, JNI_ABORT);
-        return sid;
-    } else {
-        return 0;
-    }
-}
-
-static jbyteArray android_server_SyntheticPasswordManager_nativeScrypt(JNIEnv* env, jobject, jbyteArray password, jbyteArray salt, jint N, jint r, jint p, jint outLen) {
-    if (!password || !salt) {
-        return NULL;
-    }
-
-    int passwordLen = env->GetArrayLength(password);
-    int saltLen = env->GetArrayLength(salt);
-    jbyteArray ret = env->NewByteArray(outLen);
-
-    jbyte* passwordPtr = (jbyte*)env->GetByteArrayElements(password, NULL);
-    jbyte* saltPtr = (jbyte*)env->GetByteArrayElements(salt, NULL);
-    jbyte* retPtr = (jbyte*)env->GetByteArrayElements(ret, NULL);
-
-    int rc = crypto_scrypt((const uint8_t *)passwordPtr, passwordLen,
-                       (const uint8_t *)saltPtr, saltLen, N, r, p, (uint8_t *)retPtr,
-                       outLen);
-    env->ReleaseByteArrayElements(password, passwordPtr, JNI_ABORT);
-    env->ReleaseByteArrayElements(salt, saltPtr, JNI_ABORT);
-    env->ReleaseByteArrayElements(ret, retPtr, 0);
-
-    if (!rc) {
-        return ret;
-    } else {
-        SLOGE("scrypt failed");
-        return NULL;
-    }
-}
-
-static const JNINativeMethod sMethods[] = {
-     /* name, signature, funcPtr */
-    {"nativeSidFromPasswordHandle", "([B)J", (void*)android_server_SyntheticPasswordManager_nativeSidFromPasswordHandle},
-    {"nativeScrypt", "([B[BIIII)[B", (void*)android_server_SyntheticPasswordManager_nativeScrypt},
-};
-
-int register_android_server_SyntheticPasswordManager(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "com/android/server/SyntheticPasswordManager",
-                                    sMethods, NELEM(sMethods));
-}
-
-} /* namespace android */
diff --git a/services/core/jni/com_android_server_UsbDescriptorParser.cpp b/services/core/jni/com_android_server_UsbDescriptorParser.cpp
new file mode 100644
index 0000000..98c5ec1
--- /dev/null
+++ b/services/core/jni/com_android_server_UsbDescriptorParser.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "UsbHostManagerJNI"
+#include "utils/Log.h"
+
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include <usbhost/usbhost.h>
+
+#define MAX_DESCRIPTORS_LENGTH 16384
+
+// com.android.server.usb.descriptors
+extern "C" {
+jbyteArray JNICALL Java_com_android_server_usb_descriptors_UsbDescriptorParser_getRawDescriptors(
+        JNIEnv* env, jobject thiz, jstring deviceAddr) {
+    const char *deviceAddrStr = env->GetStringUTFChars(deviceAddr, NULL);
+    struct usb_device* device = usb_device_open(deviceAddrStr);
+    env->ReleaseStringUTFChars(deviceAddr, deviceAddrStr);
+
+    if (!device) {
+        ALOGE("usb_device_open failed");
+        return NULL;
+    }
+
+    int fd = usb_device_get_fd(device);
+    if (fd < 0) {
+        return NULL;
+    }
+
+    // from android_hardware_UsbDeviceConnection_get_desc()
+    jbyte buffer[MAX_DESCRIPTORS_LENGTH];
+    lseek(fd, 0, SEEK_SET);
+    int numBytes = read(fd, buffer, sizeof(buffer));
+
+    usb_device_close(device);
+
+    jbyteArray ret = NULL;
+    if (numBytes != 0) {
+        ret = env->NewByteArray(numBytes);
+        env->SetByteArrayRegion(ret, 0, numBytes, buffer);
+    }
+    return ret;
+}
+
+} // extern "C"
+
+
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index 810d785..0370490 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -18,6 +18,7 @@
 
 #include <android/hardware/vibrator/1.0/IVibrator.h>
 #include <android/hardware/vibrator/1.0/types.h>
+#include <android/hardware/vibrator/1.1/IVibrator.h>
 
 #include "jni.h"
 #include <nativehelper/JNIHelp.h>
@@ -35,96 +36,129 @@
 using android::hardware::vibrator::V1_0::EffectStrength;
 using android::hardware::vibrator::V1_0::IVibrator;
 using android::hardware::vibrator::V1_0::Status;
+using android::hardware::vibrator::V1_1::Effect_1_1;
+using IVibrator_1_1 = android::hardware::vibrator::V1_1::IVibrator;
 
 namespace android
 {
 
-static sp<IVibrator> mHal;
+static constexpr int NUM_TRIES = 2;
+
+// Creates a Return<R> with STATUS::EX_NULL_POINTER.
+template<class R>
+inline Return<R> NullptrStatus() {
+    using ::android::hardware::Status;
+    return Return<R>{Status::fromExceptionCode(Status::EX_NULL_POINTER)};
+}
+
+// Helper used to transparently deal with the vibrator HAL becoming unavailable.
+template<class R, class I, class... Args0, class... Args1>
+Return<R> halCall(Return<R> (I::* fn)(Args0...), Args1&&... args1) {
+    // Assume that if getService returns a nullptr, HAL is not available on the
+    // device.
+    static sp<I> sHal = I::getService();
+    static bool sAvailable = sHal != nullptr;
+
+    if (!sAvailable) {
+        return NullptrStatus<R>();
+    }
+
+    // Return<R> doesn't have a default constructor, so make a Return<R> with
+    // STATUS::EX_NONE.
+    using ::android::hardware::Status;
+    Return<R> ret{Status::fromExceptionCode(Status::EX_NONE)};
+
+    // Note that ret is guaranteed to be changed after this loop.
+    for (int i = 0; i < NUM_TRIES; ++i) {
+        ret = (sHal == nullptr) ? NullptrStatus<R>()
+                : (*sHal.*fn)(std::forward<Args1>(args1)...);
+
+        if (ret.isOk()) {
+            break;
+        }
+
+        ALOGE("Failed to issue command to vibrator HAL. Retrying.");
+        // Restoring connection to the HAL.
+        sHal = I::tryGetService();
+    }
+    return ret;
+}
 
 static void vibratorInit(JNIEnv /* env */, jobject /* clazz */)
 {
-    /* TODO(b/31632518) */
-    if (mHal != nullptr) {
-        return;
-    }
-    mHal = IVibrator::getService();
+    halCall(&IVibrator::ping).isOk();
 }
 
 static jboolean vibratorExists(JNIEnv* /* env */, jobject /* clazz */)
 {
-    if (mHal != nullptr) {
-        return JNI_TRUE;
-    } else {
-        return JNI_FALSE;
-    }
+    return halCall(&IVibrator::ping).isOk() ? JNI_TRUE : JNI_FALSE;
 }
 
 static void vibratorOn(JNIEnv* /* env */, jobject /* clazz */, jlong timeout_ms)
 {
-    if (mHal != nullptr) {
-        Status retStatus = mHal->on(timeout_ms);
-        if (retStatus != Status::OK) {
-            ALOGE("vibratorOn command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
-        }
-    } else {
-        ALOGW("Tried to vibrate but there is no vibrator device.");
+    Status retStatus = halCall(&IVibrator::on, timeout_ms).withDefault(Status::UNKNOWN_ERROR);
+    if (retStatus != Status::OK) {
+        ALOGE("vibratorOn command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
     }
 }
 
 static void vibratorOff(JNIEnv* /* env */, jobject /* clazz */)
 {
-    if (mHal != nullptr) {
-        Status retStatus = mHal->off();
-        if (retStatus != Status::OK) {
-            ALOGE("vibratorOff command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
-        }
-    } else {
-        ALOGW("Tried to stop vibrating but there is no vibrator device.");
+    Status retStatus = halCall(&IVibrator::off).withDefault(Status::UNKNOWN_ERROR);
+    if (retStatus != Status::OK) {
+        ALOGE("vibratorOff command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
     }
 }
 
 static jlong vibratorSupportsAmplitudeControl(JNIEnv*, jobject) {
-    if (mHal != nullptr) {
-        return mHal->supportsAmplitudeControl();
-    } else {
-        ALOGW("Unable to get max vibration amplitude, there is no vibrator device.");
-    }
-    return false;
+    return halCall(&IVibrator::supportsAmplitudeControl).withDefault(false);
 }
 
 static void vibratorSetAmplitude(JNIEnv*, jobject, jint amplitude) {
-    if (mHal != nullptr) {
-        Status status = mHal->setAmplitude(static_cast<uint32_t>(amplitude));
-        if (status != Status::OK) {
-            ALOGE("Failed to set vibrator amplitude (%" PRIu32 ").",
-                    static_cast<uint32_t>(status));
-        }
-    } else {
-        ALOGW("Unable to set vibration amplitude, there is no vibrator device.");
+    Status status = halCall(&IVibrator::setAmplitude, static_cast<uint32_t>(amplitude))
+        .withDefault(Status::UNKNOWN_ERROR);
+    if (status != Status::OK) {
+      ALOGE("Failed to set vibrator amplitude (%" PRIu32 ").",
+            static_cast<uint32_t>(status));
     }
 }
 
 static jlong vibratorPerformEffect(JNIEnv*, jobject, jlong effect, jint strength) {
-    if (mHal != nullptr) {
-        Status status;
-        uint32_t lengthMs;
-        mHal->perform(static_cast<Effect>(effect), static_cast<EffectStrength>(strength),
-                [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) {
-                    status = retStatus;
-                    lengthMs = retLengthMs;
-                });
-        if (status == Status::OK) {
-            return lengthMs;
-        } else if (status != Status::UNSUPPORTED_OPERATION) {
-            // Don't warn on UNSUPPORTED_OPERATION, that's a normal even and just means the motor
-            // doesn't have a pre-defined waveform to perform for it, so we should just fall back
-            // to the framework waveforms.
-            ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32
-                    ", error=%" PRIu32 ").", static_cast<int64_t>(effect),
-                    static_cast<int32_t>(strength), static_cast<uint32_t>(status));
+    Status status;
+    uint32_t lengthMs;
+    auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) {
+        status = retStatus;
+        lengthMs = retLengthMs;
+    };
+    EffectStrength effectStrength(static_cast<EffectStrength>(strength));
+
+    if (effect < 0  || effect > static_cast<uint32_t>(Effect_1_1::TICK)) {
+        ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")",
+                static_cast<int32_t>(effect));
+    } else if (effect == static_cast<uint32_t>(Effect_1_1::TICK)) {
+        auto ret = halCall(&IVibrator_1_1::perform_1_1, static_cast<Effect_1_1>(effect),
+                           effectStrength, callback);
+        if (!ret.isOk()) {
+            ALOGW("Failed to perform effect (%" PRId32 "), insufficient HAL version",
+                    static_cast<int32_t>(effect));
         }
     } else {
-        ALOGW("Unable to perform haptic effect, there is no vibrator device.");
+        auto ret = halCall(&IVibrator::perform, static_cast<Effect>(effect), effectStrength,
+                           callback);
+        if (!ret.isOk()) {
+            ALOGW("Failed to perform effect (%" PRId32 ")", static_cast<int32_t>(effect));
+        }
+    }
+
+    if (status == Status::OK) {
+        return lengthMs;
+    } else if (status != Status::UNSUPPORTED_OPERATION) {
+        // Don't warn on UNSUPPORTED_OPERATION, that's a normal even and just means the motor
+        // doesn't have a pre-defined waveform to perform for it, so we should just fall back
+        // to the framework waveforms.
+        ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32
+                ", error=%" PRIu32 ").", static_cast<int64_t>(effect),
+                static_cast<int32_t>(strength), static_cast<uint32_t>(status));
     }
     return -1;
 }
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index fbd4141..2dc388a 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -29,6 +29,7 @@
 #include <unistd.h>
 
 #include <android/hardware/power/1.0/IPower.h>
+#include <android/hardware/power/1.1/IPower.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <jni.h>
 
@@ -46,6 +47,8 @@
 using android::hardware::power::V1_0::PowerStatePlatformSleepState;
 using android::hardware::power::V1_0::PowerStateVoter;
 using android::hardware::power::V1_0::Status;
+using android::hardware::power::V1_1::PowerStateSubsystem;
+using android::hardware::power::V1_1::PowerStateSubsystemSleepState;
 using android::hardware::hidl_vec;
 
 namespace android
@@ -56,7 +59,7 @@
 
 static bool wakeup_init = false;
 static sem_t wakeup_sem;
-extern sp<IPower> gPowerHal;
+extern sp<android::hardware::power::V1_0::IPower> gPowerHalV1_0;
 extern std::mutex gPowerHalMutex;
 extern bool getPowerHal();
 
@@ -200,7 +203,7 @@
             return -1;
         }
 
-        Return<void> ret = gPowerHal->getPlatformLowPowerStats(
+        Return<void> ret = gPowerHalV1_0->getPlatformLowPowerStats(
             [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states,
                     Status status) {
                 if (status != Status::SUCCESS)
@@ -254,7 +257,7 @@
 
         if (!ret.isOk()) {
             ALOGE("getPlatformLowPowerStats() failed: power HAL service not available");
-            gPowerHal = nullptr;
+            gPowerHalV1_0 = nullptr;
             return -1;
         }
     }
@@ -263,9 +266,111 @@
     return total_added;
 }
 
+static jint getSubsystemLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject outBuf) {
+    char *output = (char*)env->GetDirectBufferAddress(outBuf);
+    char *offset = output;
+    int remaining = (int)env->GetDirectBufferCapacity(outBuf);
+    int total_added = -1;
+
+	//This is a IPower 1.1 API
+    sp<android::hardware::power::V1_1::IPower> gPowerHal_1_1 = nullptr;
+
+    if (outBuf == NULL) {
+        jniThrowException(env, "java/lang/NullPointerException", "null argument");
+        return -1;
+    }
+
+    {
+        std::lock_guard<std::mutex> lock(gPowerHalMutex);
+        if (!getPowerHal()) {
+            ALOGE("Power Hal not loaded");
+            return -1;
+        }
+
+        //Trying to cast to 1.1, this will succeed only for devices supporting 1.1
+        gPowerHal_1_1 = android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0);
+    	if (gPowerHal_1_1 == nullptr) {
+            //This device does not support IPower@1.1, exiting gracefully
+            return 0;
+    	}
+
+        Return<void> ret = gPowerHal_1_1->getSubsystemLowPowerStats(
+           [&offset, &remaining, &total_added](hidl_vec<PowerStateSubsystem> subsystems,
+                Status status) {
+
+            if (status != Status::SUCCESS)
+                return;
+
+            if (subsystems.size() > 0) {
+                int added = snprintf(offset, remaining, "SubsystemPowerState ");
+                offset += added;
+                remaining -= added;
+                total_added += added;
+
+                for (size_t i = 0; i < subsystems.size(); i++) {
+                    const PowerStateSubsystem &subsystem = subsystems[i];
+
+                    added = snprintf(offset, remaining,
+                                     "subsystem_%zu name=%s ", i + 1, subsystem.name.c_str());
+                    if (added < 0) {
+                        break;
+                    }
+
+                    if (added > remaining) {
+                        added = remaining;
+                    }
+
+                    offset += added;
+                    remaining -= added;
+                    total_added += added;
+
+                    for (size_t j = 0; j < subsystem.states.size(); j++) {
+                        const PowerStateSubsystemSleepState& state = subsystem.states[j];
+                        added = snprintf(offset, remaining,
+                                         "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " last entry=%" PRIu64 " ",
+                                         j + 1, state.name.c_str(), state.residencyInMsecSinceBoot,
+                                         state.totalTransitions, state.lastEntryTimestampMs);
+                        if (added < 0) {
+                            break;
+                        }
+
+                        if (added > remaining) {
+                            added = remaining;
+                        }
+
+                        offset += added;
+                        remaining -= added;
+                        total_added += added;
+                    }
+
+                    if (remaining <= 0) {
+                        /* rewrite NULL character*/
+                        offset--;
+                        total_added--;
+                        ALOGE("PowerHal: buffer not enough");
+                        break;
+                    }
+                }
+            }
+        }
+        );
+
+        if (!ret.isOk()) {
+            ALOGE("getSubsystemLowPowerStats() failed: power HAL service not available");
+            gPowerHalV1_0 = nullptr;
+            return -1;
+        }
+    }
+
+    *offset = 0;
+    total_added += 1;
+    return total_added;
+}
+
 static const JNINativeMethod method_table[] = {
     { "nativeWaitWakeup", "(Ljava/nio/ByteBuffer;)I", (void*)nativeWaitWakeup },
     { "getPlatformLowPowerStats", "(Ljava/nio/ByteBuffer;)I", (void*)getPlatformLowPowerStats },
+    { "getSubsystemLowPowerStats", "(Ljava/nio/ByteBuffer;)I", (void*)getSubsystemLowPowerStats },
 };
 
 int register_android_server_BatteryStatsService(JNIEnv *env)
diff --git a/services/core/jni/com_android_server_connectivity_tethering_OffloadHardwareInterface.cpp b/services/core/jni/com_android_server_connectivity_tethering_OffloadHardwareInterface.cpp
index 87312f8..3eaf488 100644
--- a/services/core/jni/com_android_server_connectivity_tethering_OffloadHardwareInterface.cpp
+++ b/services/core/jni/com_android_server_connectivity_tethering_OffloadHardwareInterface.cpp
@@ -74,10 +74,9 @@
 hidl_handle handleFromFileDescriptor(base::unique_fd fd) {
     hidl_handle h;
 
-    NATIVE_HANDLE_DECLARE_STORAGE(storage, 0, 0);
     static constexpr int kNumFds = 1;
     static constexpr int kNumInts = 0;
-    native_handle_t *nh = native_handle_init(storage, kNumFds, kNumInts);
+    native_handle_t *nh = native_handle_create(kNumFds, kNumInts);
     nh->data[0] = fd.release();
 
     static constexpr bool kTakeOwnership = true;
@@ -104,8 +103,8 @@
     // fd2   A file descriptor bound to the following netlink groups
     //       (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY).
     base::unique_fd
-            fd1(conntrackSocket(NFNLGRP_CONNTRACK_NEW | NFNLGRP_CONNTRACK_DESTROY)),
-            fd2(conntrackSocket(NFNLGRP_CONNTRACK_UPDATE | NFNLGRP_CONNTRACK_DESTROY));
+            fd1(conntrackSocket(NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY)),
+            fd2(conntrackSocket(NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY));
     if (fd1.get() < 0 || fd2.get() < 0) {
         ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
         return false;
@@ -114,7 +113,7 @@
     hidl_handle h1(handleFromFileDescriptor(std::move(fd1))),
                 h2(handleFromFileDescriptor(std::move(fd2)));
 
-    bool rval;
+    bool rval(false);
     hidl_string msg;
     const auto status = configInterface->setHandles(h1, h2,
             [&rval, &msg](bool success, const hidl_string& errMsg) {
@@ -124,6 +123,8 @@
     if (!status.isOk() || !rval) {
         ALOGE("IOffloadConfig::setHandles() error: '%s' / '%s'",
               status.description().c_str(), msg.c_str());
+        // If status is somehow not ok, make sure rval captures this too.
+        rval = false;
     }
 
     return rval;
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index ad617bc..c210e14 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -36,6 +36,7 @@
 #include <utils/Log.h>
 #include <utils/Looper.h>
 #include <utils/threads.h>
+#include <utils/SortedVector.h>
 
 #include <input/PointerController.h>
 #include <input/SpriteController.h>
@@ -158,7 +159,12 @@
     status_t status = android_view_PointerIcon_loadSystemIcon(env,
             contextObj, style, outPointerIcon);
     if (!status) {
-        outPointerIcon->bitmap.copyTo(&outSpriteIcon->bitmap, kN32_SkColorType);
+        SkBitmap* bitmapCopy = &outSpriteIcon->bitmap;
+        SkImageInfo bitmapCopyInfo = outPointerIcon->bitmap.info().makeColorType(kN32_SkColorType);
+        if (bitmapCopy->tryAllocPixels(bitmapCopyInfo)) {
+            outPointerIcon->bitmap.readPixels(bitmapCopy->info(), bitmapCopy->getPixels(),
+                    bitmapCopy->rowBytes(), 0, 0);
+        }
         outSpriteIcon->hotSpotX = outPointerIcon->hotSpotX;
         outSpriteIcon->hotSpotY = outPointerIcon->hotSpotY;
     }
@@ -203,6 +209,7 @@
     void setInputDispatchMode(bool enabled, bool frozen);
     void setSystemUiVisibility(int32_t visibility);
     void setPointerSpeed(int32_t speed);
+    void setInputDeviceEnabled(uint32_t deviceId, bool enabled);
     void setShowTouches(bool enabled);
     void setInteractive(bool interactive);
     void reloadCalibration();
@@ -288,6 +295,9 @@
 
         // Pointer controller singleton, created and destroyed as needed.
         wp<PointerController> pointerController;
+
+        // Input devices to be disabled
+        SortedVector<int32_t> disabledInputDevices;
     } mLocked;
 
     std::atomic<bool> mInteractive;
@@ -512,6 +522,8 @@
         outConfig->setPhysicalDisplayViewport(ViewportType::VIEWPORT_EXTERNAL,
                 mLocked.externalViewport);
         outConfig->setVirtualDisplayViewports(mLocked.virtualViewports);
+
+        outConfig->disabledDevices = mLocked.disabledInputDevices;
     } // release lock
 }
 
@@ -801,6 +813,24 @@
             InputReaderConfiguration::CHANGE_POINTER_SPEED);
 }
 
+void NativeInputManager::setInputDeviceEnabled(uint32_t deviceId, bool enabled) {
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        ssize_t index = mLocked.disabledInputDevices.indexOf(deviceId);
+        bool currentlyEnabled = index < 0;
+        if (!enabled && currentlyEnabled) {
+            mLocked.disabledInputDevices.add(deviceId);
+        }
+        if (enabled && !currentlyEnabled) {
+            mLocked.disabledInputDevices.remove(deviceId);
+        }
+    } // release lock
+
+    mInputManager->getReader()->requestRefreshConfiguration(
+            InputReaderConfiguration::CHANGE_ENABLED_STATE);
+}
+
 void NativeInputManager::setShowTouches(bool enabled) {
     { // acquire lock
         AutoMutex _l(mLock);
@@ -1382,6 +1412,7 @@
 static void nativeToggleCapsLock(JNIEnv* env, jclass /* clazz */,
          jlong ptr, jint deviceId) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
     im->getInputManager()->getReader()->toggleCapsLockState(deviceId);
 }
 
@@ -1402,6 +1433,7 @@
 static void nativeSetPointerCapture(JNIEnv* env, jclass /* clazz */, jlong ptr,
         jboolean enabled) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
     im->setPointerCapture(enabled);
 }
 
@@ -1463,6 +1495,7 @@
 
 static void nativeReloadCalibration(JNIEnv* env, jclass clazz, jlong ptr) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
     im->reloadCalibration();
 }
 
@@ -1529,13 +1562,36 @@
     im->getInputManager()->getDispatcher()->monitor();
 }
 
+static jboolean nativeIsInputDeviceEnabled(JNIEnv* env /* env */,
+        jclass /* clazz */, jlong ptr, jint deviceId) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+    return im->getInputManager()->getReader()->isInputDeviceEnabled(deviceId);
+}
+
+static void nativeEnableInputDevice(JNIEnv* /* env */,
+        jclass /* clazz */, jlong ptr, jint deviceId) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+    im->setInputDeviceEnabled(deviceId, true);
+}
+
+static void nativeDisableInputDevice(JNIEnv* /* env */,
+        jclass /* clazz */, jlong ptr, jint deviceId) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+    im->setInputDeviceEnabled(deviceId, false);
+}
+
 static void nativeSetPointerIconType(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint iconId) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
     im->setPointerIconType(iconId);
 }
 
 static void nativeReloadPointerIcons(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
     im->reloadPointerIcons();
 }
 
@@ -1551,7 +1607,11 @@
     }
 
     SpriteIcon spriteIcon;
-    pointerIcon.bitmap.copyTo(&spriteIcon.bitmap, kN32_SkColorType);
+    SkImageInfo spriteInfo = pointerIcon.bitmap.info().makeColorType(kN32_SkColorType);
+    if (spriteIcon.bitmap.tryAllocPixels(spriteInfo)) {
+        pointerIcon.bitmap.readPixels(spriteInfo, spriteIcon.bitmap.getPixels(),
+                spriteIcon.bitmap.rowBytes(), 0, 0);
+    }
     spriteIcon.hotSpotX = pointerIcon.hotSpotX;
     spriteIcon.hotSpotY = pointerIcon.hotSpotY;
     im->setCustomPointerIcon(spriteIcon);
@@ -1621,6 +1681,12 @@
             (void*) nativeDump },
     { "nativeMonitor", "(J)V",
             (void*) nativeMonitor },
+    { "nativeIsInputDeviceEnabled", "(JI)Z",
+            (void*) nativeIsInputDeviceEnabled },
+    { "nativeEnableInputDevice", "(JI)V",
+            (void*) nativeEnableInputDevice },
+    { "nativeDisableInputDevice", "(JI)V",
+            (void*) nativeDisableInputDevice },
     { "nativeSetPointerIconType", "(JI)V",
             (void*) nativeSetPointerIconType },
     { "nativeReloadPointerIcons", "(J)V",
diff --git a/services/core/jni/com_android_server_location_ContextHubService.cpp b/services/core/jni/com_android_server_location_ContextHubService.cpp
index 09ccf6b..d90b011 100644
--- a/services/core/jni/com_android_server_location_ContextHubService.cpp
+++ b/services/core/jni/com_android_server_location_ContextHubService.cpp
@@ -513,7 +513,7 @@
 
     if (!txnInfo || instanceId < 0) {
         returnId(instanceId);
-        free(txnInfo);
+        delete txnInfo;
         return -1;
     }
 
@@ -526,7 +526,7 @@
 
     if (db.txnManager.addTxn(CONTEXT_HUB_LOAD_APP, txnInfo) != 0) {
         returnId(instanceId);
-        free(txnInfo);
+        delete txnInfo;
         return -1;
     }
 
@@ -543,7 +543,7 @@
     *txnData = appInstanceHandle;
 
     if (db.txnManager.addTxn(CONTEXT_HUB_UNLOAD_APP, txnData) != 0) {
-        free(txnData);
+        delete txnData;
         ALOGW("Cannot start transaction to unload app");
         return -1;
     }
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 2b1225c..1f1324a 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -1523,6 +1523,10 @@
                           << " satellites:: " << std::endl;
         }
 
+        internalState << "constellation: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
+                      << "ephemerisType: 0=Eph, 1=Alm, 2=?; "
+                      << "ephemerisSource: 0=Demod, 1=Supl, 2=Server, 3=?; "
+                      << "ephemerisHealth: 0=Good, 1=Bad, 2=?" << std::endl;
         for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
             internalState << "svid: " << data.satelliteDataArray[i].svid
                           << ", constellation: "
diff --git a/services/core/jni/com_android_server_locksettings_SyntheticPasswordManager.cpp b/services/core/jni/com_android_server_locksettings_SyntheticPasswordManager.cpp
new file mode 100644
index 0000000..248dedb
--- /dev/null
+++ b/services/core/jni/com_android_server_locksettings_SyntheticPasswordManager.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SyntheticPasswordManager"
+
+#include "JNIHelp.h"
+#include "jni.h"
+
+#include <android_runtime/Log.h>
+#include <utils/Timers.h>
+#include <utils/misc.h>
+#include <utils/String8.h>
+#include <utils/Log.h>
+#include <gatekeeper/password_handle.h>
+
+
+extern "C" {
+#include "crypto_scrypt.h"
+}
+
+namespace android {
+
+static jlong android_server_SyntheticPasswordManager_nativeSidFromPasswordHandle(JNIEnv* env, jobject, jbyteArray handleArray) {
+
+    jbyte* data = (jbyte*)env->GetPrimitiveArrayCritical(handleArray, NULL);
+
+    if (data != NULL) {
+        const gatekeeper::password_handle_t *handle =
+                reinterpret_cast<const gatekeeper::password_handle_t *>(data);
+        jlong sid = handle->user_id;
+        env->ReleasePrimitiveArrayCritical(handleArray, data, JNI_ABORT);
+        return sid;
+    } else {
+        return 0;
+    }
+}
+
+static jbyteArray android_server_SyntheticPasswordManager_nativeScrypt(JNIEnv* env, jobject, jbyteArray password, jbyteArray salt, jint N, jint r, jint p, jint outLen) {
+    if (!password || !salt) {
+        return NULL;
+    }
+
+    int passwordLen = env->GetArrayLength(password);
+    int saltLen = env->GetArrayLength(salt);
+    jbyteArray ret = env->NewByteArray(outLen);
+
+    jbyte* passwordPtr = (jbyte*)env->GetByteArrayElements(password, NULL);
+    jbyte* saltPtr = (jbyte*)env->GetByteArrayElements(salt, NULL);
+    jbyte* retPtr = (jbyte*)env->GetByteArrayElements(ret, NULL);
+
+    int rc = crypto_scrypt((const uint8_t *)passwordPtr, passwordLen,
+                       (const uint8_t *)saltPtr, saltLen, N, r, p, (uint8_t *)retPtr,
+                       outLen);
+    env->ReleaseByteArrayElements(password, passwordPtr, JNI_ABORT);
+    env->ReleaseByteArrayElements(salt, saltPtr, JNI_ABORT);
+    env->ReleaseByteArrayElements(ret, retPtr, 0);
+
+    if (!rc) {
+        return ret;
+    } else {
+        SLOGE("scrypt failed");
+        return NULL;
+    }
+}
+
+static const JNINativeMethod sMethods[] = {
+     /* name, signature, funcPtr */
+    {"nativeSidFromPasswordHandle", "([B)J", (void*)android_server_SyntheticPasswordManager_nativeSidFromPasswordHandle},
+    {"nativeScrypt", "([B[BIIII)[B", (void*)android_server_SyntheticPasswordManager_nativeScrypt},
+};
+
+int register_android_server_SyntheticPasswordManager(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "com/android/server/locksettings/SyntheticPasswordManager",
+                                    sMethods, NELEM(sMethods));
+}
+
+} /* namespace android */
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index 935ced9..39f90ca 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -18,7 +18,7 @@
 
 //#define LOG_NDEBUG 0
 
-#include <android/hardware/power/1.0/IPower.h>
+#include <android/hardware/power/1.1/IPower.h>
 #include "JNIHelp.h"
 #include "jni.h"
 
@@ -41,7 +41,7 @@
 
 using android::hardware::Return;
 using android::hardware::Void;
-using android::hardware::power::V1_0::IPower;
+using android::hardware::power::V1_1::IPower;
 using android::hardware::power::V1_0::PowerHint;
 using android::hardware::power::V1_0::Feature;
 using android::String8;
@@ -57,13 +57,14 @@
 // ----------------------------------------------------------------------------
 
 static jobject gPowerManagerServiceObj;
-sp<IPower> gPowerHal = nullptr;
+sp<android::hardware::power::V1_0::IPower> gPowerHalV1_0 = nullptr;
+sp<android::hardware::power::V1_1::IPower> gPowerHalV1_1 = nullptr;
 bool gPowerHalExists = true;
 std::mutex gPowerHalMutex;
 static nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1];
 
 // Throttling interval for user activity calls.
-static const nsecs_t MIN_TIME_BETWEEN_USERACTIVITIES = 500 * 1000000L; // 500ms
+static const nsecs_t MIN_TIME_BETWEEN_USERACTIVITIES = 100 * 1000000L; // 100ms
 
 // ----------------------------------------------------------------------------
 
@@ -80,16 +81,17 @@
 // Check validity of current handle to the power HAL service, and call getService() if necessary.
 // The caller must be holding gPowerHalMutex.
 bool getPowerHal() {
-    if (gPowerHalExists && gPowerHal == nullptr) {
-        gPowerHal = IPower::getService();
-        if (gPowerHal != nullptr) {
+    if (gPowerHalExists && gPowerHalV1_0 == nullptr) {
+        gPowerHalV1_0 = android::hardware::power::V1_0::IPower::getService();
+        if (gPowerHalV1_0 != nullptr) {
+            gPowerHalV1_1 =  android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0);
             ALOGI("Loaded power HAL service");
         } else {
             ALOGI("Couldn't load power HAL service");
             gPowerHalExists = false;
         }
     }
-    return gPowerHal != nullptr;
+    return gPowerHalV1_0 != nullptr;
 }
 
 // Check if a call to a power HAL function failed; if so, log the failure and invalidate the
@@ -97,19 +99,11 @@
 static void processReturn(const Return<void> &ret, const char* functionName) {
     if (!ret.isOk()) {
         ALOGE("%s() failed: power HAL service not available.", functionName);
-        gPowerHal = nullptr;
+        gPowerHalV1_0 = nullptr;
     }
 }
 
 void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) {
-    // Tell the power HAL when user activity occurs.
-    gPowerHalMutex.lock();
-    if (getPowerHal()) {
-        Return<void> ret = gPowerHal->powerHint(PowerHint::INTERACTION, 0);
-        processReturn(ret, "powerHint");
-    }
-    gPowerHalMutex.unlock();
-
     if (gPowerManagerServiceObj) {
         // Throttle calls into user activity by event type.
         // We're a little conservative about argument checking here in case the caller
@@ -124,6 +118,21 @@
                 return;
             }
             gLastEventTime[eventType] = eventTime;
+
+
+            // Tell the power HAL when user activity occurs.
+            gPowerHalMutex.lock();
+            if (getPowerHal()) {
+              Return<void> ret;
+              if (gPowerHalV1_1 != nullptr) {
+                ret = gPowerHalV1_1->powerHintAsync(PowerHint::INTERACTION, 0);
+              } else {
+                ret = gPowerHalV1_0->powerHint(PowerHint::INTERACTION, 0);
+              }
+              processReturn(ret, "powerHint");
+            }
+            gPowerHalMutex.unlock();
+
         }
 
         JNIEnv* env = AndroidRuntime::getJNIEnv();
@@ -159,7 +168,7 @@
     std::lock_guard<std::mutex> lock(gPowerHalMutex);
     if (getPowerHal()) {
         android::base::Timer t;
-        Return<void> ret = gPowerHal->setInteractive(enable);
+        Return<void> ret = gPowerHalV1_0->setInteractive(enable);
         processReturn(ret, "setInteractive");
         if (t.duration() > 20ms) {
             ALOGD("Excessive delay in setInteractive(%s) while turning screen %s",
@@ -187,7 +196,12 @@
 static void nativeSendPowerHint(JNIEnv *env, jclass clazz, jint hintId, jint data) {
     std::lock_guard<std::mutex> lock(gPowerHalMutex);
     if (getPowerHal()) {
-        Return<void> ret =  gPowerHal->powerHint((PowerHint)hintId, data);
+        Return<void> ret;
+        if (gPowerHalV1_1 != nullptr) {
+            ret =  gPowerHalV1_1->powerHintAsync((PowerHint)hintId, data);
+        } else {
+            ret =  gPowerHalV1_0->powerHint((PowerHint)hintId, data);
+        }
         processReturn(ret, "powerHint");
     }
 }
@@ -195,7 +209,7 @@
 static void nativeSetFeature(JNIEnv *env, jclass clazz, jint featureId, jint data) {
     std::lock_guard<std::mutex> lock(gPowerHalMutex);
     if (getPowerHal()) {
-        Return<void> ret = gPowerHal->setFeature((Feature)featureId, static_cast<bool>(data));
+        Return<void> ret = gPowerHalV1_0->setFeature((Feature)featureId, static_cast<bool>(data));
         processReturn(ret, "setFeature");
     }
 }
diff --git a/services/core/jni/com_android_server_radio_RadioService.cpp b/services/core/jni/com_android_server_radio_RadioService.cpp
new file mode 100644
index 0000000..73887bb
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_RadioService.cpp
@@ -0,0 +1,208 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "radio.RadioService.jni"
+#define LOG_NDEBUG 0
+
+#include "com_android_server_radio_RadioService.h"
+
+#include "com_android_server_radio_Tuner.h"
+#include "com_android_server_radio_convert.h"
+
+#include <android/hardware/broadcastradio/1.1/IBroadcastRadio.h>
+#include <android/hardware/broadcastradio/1.1/IBroadcastRadioFactory.h>
+#include <core_jni_helpers.h>
+#include <utils/Log.h>
+#include <JNIHelp.h>
+
+namespace android {
+namespace server {
+namespace radio {
+namespace RadioService {
+
+using hardware::Return;
+using hardware::hidl_vec;
+
+namespace V1_0 = hardware::broadcastradio::V1_0;
+namespace V1_1 = hardware::broadcastradio::V1_1;
+
+using V1_0::Class;
+using V1_0::Result;
+
+using V1_0::BandConfig;
+using V1_0::ProgramInfo;
+using V1_0::MetaData;
+using V1_0::ITuner;
+
+static Mutex gContextMutex;
+
+static struct {
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+    } Tuner;
+} gjni;
+
+struct ServiceContext {
+    ServiceContext() {}
+
+    sp<V1_0::IBroadcastRadio> mModule;
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(ServiceContext);
+};
+
+
+/**
+ * Always lock gContextMutex when using native context.
+ */
+static ServiceContext& getNativeContext(jlong nativeContextHandle) {
+    auto nativeContext = reinterpret_cast<ServiceContext*>(nativeContextHandle);
+    LOG_ALWAYS_FATAL_IF(nativeContext == nullptr, "Native context not initialized");
+    return *nativeContext;
+}
+
+static jlong nativeInit(JNIEnv *env, jobject obj) {
+    ALOGV("nativeInit()");
+    AutoMutex _l(gContextMutex);
+
+    auto nativeContext = new ServiceContext();
+    static_assert(sizeof(jlong) >= sizeof(nativeContext), "jlong is smaller than a pointer");
+    return reinterpret_cast<jlong>(nativeContext);
+}
+
+static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeFinalize()");
+    AutoMutex _l(gContextMutex);
+
+    auto ctx = reinterpret_cast<ServiceContext*>(nativeContext);
+    delete ctx;
+}
+
+static sp<V1_0::IBroadcastRadio> getModule(jlong nativeContext) {
+    ALOGV("getModule()");
+    AutoMutex _l(gContextMutex);
+    auto& ctx = getNativeContext(nativeContext);
+
+    if (ctx.mModule != nullptr) {
+        return ctx.mModule;
+    }
+
+    // TODO(b/36863239): what about other HAL implementations?
+    auto factory = V1_0::IBroadcastRadioFactory::getService();
+    if (factory == nullptr) {
+        ALOGE("Can't retrieve radio HAL implementation");
+        return nullptr;
+    }
+
+    sp<V1_0::IBroadcastRadio> module = nullptr;
+    // TODO(b/36863239): not only AM/FM
+    factory->connectModule(Class::AM_FM, [&](Result retval,
+            const sp<V1_0::IBroadcastRadio>& result) {
+        if (retval == Result::OK) {
+            module = result;
+        }
+    });
+
+    ALOGE_IF(module == nullptr, "Couldn't connect module");
+    ctx.mModule = module;
+    return module;
+}
+
+static jobject nativeOpenTuner(JNIEnv *env, jobject obj, long nativeContext, jint moduleId,
+        jobject bandConfig, bool withAudio, jobject callback) {
+    ALOGV("nativeOpenTuner()");
+    EnvWrapper wrap(env);
+
+    if (callback == nullptr) {
+        ALOGE("Callback is empty");
+        return nullptr;
+    }
+
+    // TODO(b/36863239): use moduleId
+    auto module = getModule(nativeContext);
+    if (module == nullptr) {
+        return nullptr;
+    }
+
+    HalRevision halRev;
+    if (V1_1::IBroadcastRadio::castFrom(module).withDefault(nullptr) != nullptr) {
+        ALOGI("Opening tuner with broadcast radio HAL 1.1");
+        halRev = HalRevision::V1_1;
+    } else {
+        ALOGI("Opening tuner with broadcast radio HAL 1.0");
+        halRev = HalRevision::V1_0;
+    }
+
+    Region region;
+    BandConfig bandConfigHal = convert::BandConfigToHal(env, bandConfig, region);
+
+    auto tuner = wrap(env->NewObject(gjni.Tuner.clazz, gjni.Tuner.cstor,
+            callback, halRev, region, withAudio));
+    if (tuner == nullptr) {
+        ALOGE("Unable to create new tuner object.");
+        return nullptr;
+    }
+
+    auto tunerCb = Tuner::getNativeCallback(env, tuner);
+    Result halResult;
+    sp<ITuner> halTuner = nullptr;
+
+    auto hidlResult = module->openTuner(bandConfigHal, withAudio, tunerCb,
+            [&](Result result, const sp<ITuner>& tuner) {
+                halResult = result;
+                halTuner = tuner;
+            });
+    if (!hidlResult.isOk() || halResult != Result::OK || halTuner == nullptr) {
+        ALOGE("Couldn't open tuner");
+        ALOGE_IF(hidlResult.isOk(), "halResult = %d", halResult);
+        ALOGE_IF(!hidlResult.isOk(), "hidlResult = %s", hidlResult.description().c_str());
+        return nullptr;
+    }
+
+    Tuner::setHalTuner(env, tuner, halTuner);
+    ALOGI("Opened tuner %p", halTuner.get());
+    return tuner.release();
+}
+
+static const JNINativeMethod gRadioServiceMethods[] = {
+    { "nativeInit", "()J", (void*)nativeInit },
+    { "nativeFinalize", "(J)V", (void*)nativeFinalize },
+    { "nativeOpenTuner", "(JILandroid/hardware/radio/RadioManager$BandConfig;Z"
+            "Landroid/hardware/radio/ITunerCallback;)Lcom/android/server/radio/Tuner;",
+            (void*)nativeOpenTuner },
+};
+
+} // namespace RadioService
+} // namespace radio
+} // namespace server
+
+void register_android_server_radio_RadioService(JNIEnv *env) {
+    using namespace server::radio::RadioService;
+
+    register_android_server_radio_convert(env);
+
+    auto tunerClass = FindClassOrDie(env, "com/android/server/radio/Tuner");
+    gjni.Tuner.clazz = MakeGlobalRefOrDie(env, tunerClass);
+    gjni.Tuner.cstor = GetMethodIDOrDie(env, tunerClass, "<init>",
+            "(Landroid/hardware/radio/ITunerCallback;IIZ)V");
+
+    auto res = jniRegisterNativeMethods(env, "com/android/server/radio/RadioService",
+            gRadioServiceMethods, NELEM(gRadioServiceMethods));
+    LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
+}
+
+} // namespace android
diff --git a/services/core/jni/com_android_server_radio_RadioService.h b/services/core/jni/com_android_server_radio_RadioService.h
new file mode 100644
index 0000000..91e119c
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_RadioService.h
@@ -0,0 +1,28 @@
+/**
+ * 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.
+ */
+
+#ifndef _ANDROID_SERVER_RADIO_RADIOSERVICE_H
+#define _ANDROID_SERVER_RADIO_RADIOSERVICE_H
+
+#include <jni.h>
+
+namespace android {
+
+void register_android_server_radio_RadioService(JNIEnv *env);
+
+} // namespace android
+
+#endif // _ANDROID_SERVER_RADIO_RADIOSERVICE_H
diff --git a/services/core/jni/com_android_server_radio_Tuner.cpp b/services/core/jni/com_android_server_radio_Tuner.cpp
new file mode 100644
index 0000000..b92136a
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_Tuner.cpp
@@ -0,0 +1,384 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "radio.Tuner.jni"
+#define LOG_NDEBUG 0
+
+#include "com_android_server_radio_Tuner.h"
+
+#include "com_android_server_radio_convert.h"
+#include "com_android_server_radio_Tuner_TunerCallback.h"
+
+#include <android/hardware/broadcastradio/1.1/IBroadcastRadioFactory.h>
+#include <core_jni_helpers.h>
+#include <utils/Log.h>
+#include <JNIHelp.h>
+
+namespace android {
+namespace server {
+namespace radio {
+namespace Tuner {
+
+using hardware::Return;
+using hardware::hidl_vec;
+
+namespace V1_0 = hardware::broadcastradio::V1_0;
+namespace V1_1 = hardware::broadcastradio::V1_1;
+
+using V1_0::BandConfig;
+using V1_0::MetaData;
+using V1_0::Result;
+using V1_1::ITunerCallback;
+using V1_1::ProgramListResult;
+
+static Mutex gContextMutex;
+
+static struct {
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+        jmethodID add;
+    } ArrayList;
+    struct {
+        jfieldID nativeContext;
+        jfieldID region;
+        jfieldID tunerCallback;
+    } Tuner;
+} gjni;
+
+struct TunerContext {
+    TunerContext() {}
+
+    HalRevision mHalRev;
+    sp<V1_0::ITuner> mHalTuner;
+    sp<V1_1::ITuner> mHalTuner11;
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(TunerContext);
+};
+
+static TunerContext& getNativeContext(jlong nativeContextHandle) {
+    auto nativeContext = reinterpret_cast<TunerContext*>(nativeContextHandle);
+    LOG_ALWAYS_FATAL_IF(nativeContext == nullptr, "Native context not initialized");
+    return *nativeContext;
+}
+
+/**
+ * Always lock gContextMutex when using native context.
+ */
+static TunerContext& getNativeContext(JNIEnv *env, JavaRef<jobject> const &jTuner) {
+    return getNativeContext(env->GetLongField(jTuner.get(), gjni.Tuner.nativeContext));
+}
+
+static jlong nativeInit(JNIEnv *env, jobject obj, jint halRev) {
+    ALOGV("nativeInit()");
+    AutoMutex _l(gContextMutex);
+
+    auto ctx = new TunerContext();
+    ctx->mHalRev = static_cast<HalRevision>(halRev);
+
+    static_assert(sizeof(jlong) >= sizeof(ctx), "jlong is smaller than a pointer");
+    return reinterpret_cast<jlong>(ctx);
+}
+
+static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeFinalize()");
+    AutoMutex _l(gContextMutex);
+
+    auto ctx = reinterpret_cast<TunerContext*>(nativeContext);
+    delete ctx;
+}
+
+void setHalTuner(JNIEnv *env, JavaRef<jobject> const &jTuner, sp<V1_0::ITuner> halTuner) {
+    ALOGV("setHalTuner(%p)", halTuner.get());
+    ALOGE_IF(halTuner == nullptr, "HAL tuner is a nullptr");
+
+    AutoMutex _l(gContextMutex);
+    auto& ctx = getNativeContext(env, jTuner);
+
+    ctx.mHalTuner = halTuner;
+    ctx.mHalTuner11 = V1_1::ITuner::castFrom(halTuner).withDefault(nullptr);
+    ALOGW_IF(ctx.mHalRev >= HalRevision::V1_1 && ctx.mHalTuner11 == nullptr,
+            "Provided tuner does not implement 1.1 HAL");
+}
+
+sp<V1_0::ITuner> getHalTuner(jlong nativeContext) {
+    AutoMutex _l(gContextMutex);
+    auto tuner = getNativeContext(nativeContext).mHalTuner;
+    LOG_ALWAYS_FATAL_IF(tuner == nullptr, "HAL tuner is not open");
+    return tuner;
+}
+
+sp<V1_1::ITuner> getHalTuner11(jlong nativeContext) {
+    AutoMutex _l(gContextMutex);
+    return getNativeContext(nativeContext).mHalTuner11;
+}
+
+sp<ITunerCallback> getNativeCallback(JNIEnv *env, JavaRef<jobject> const &tuner) {
+    return TunerCallback::getNativeCallback(env,
+            env->GetObjectField(tuner.get(), gjni.Tuner.tunerCallback));
+}
+
+Region getRegion(JNIEnv *env, jobject obj) {
+    return static_cast<Region>(env->GetIntField(obj, gjni.Tuner.region));
+}
+
+static void nativeClose(JNIEnv *env, jobject obj, jlong nativeContext) {
+    AutoMutex _l(gContextMutex);
+    auto& ctx = getNativeContext(nativeContext);
+    if (ctx.mHalTuner == nullptr) return;
+    ALOGI("Closing tuner %p", ctx.mHalTuner.get());
+    ctx.mHalTuner11 = nullptr;
+    ctx.mHalTuner = nullptr;
+}
+
+static void nativeSetConfiguration(JNIEnv *env, jobject obj, jlong nativeContext, jobject config) {
+    ALOGV("nativeSetConfiguration()");
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return;
+
+    Region region_unused;
+    BandConfig bandConfigHal = convert::BandConfigToHal(env, config, region_unused);
+
+    convert::ThrowIfFailed(env, halTuner->setConfiguration(bandConfigHal));
+}
+
+static jobject nativeGetConfiguration(JNIEnv *env, jobject obj, jlong nativeContext,
+        Region region) {
+    ALOGV("nativeSetConfiguration()");
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return nullptr;
+
+    BandConfig halConfig;
+    Result halResult;
+    auto hidlResult = halTuner->getConfiguration([&](Result result, const BandConfig& config) {
+        halResult = result;
+        halConfig = config;
+    });
+    if (convert::ThrowIfFailed(env, hidlResult, halResult)) {
+        return nullptr;
+    }
+
+    return convert::BandConfigFromHal(env, halConfig, region).release();
+}
+
+static void nativeStep(JNIEnv *env, jobject obj, jlong nativeContext,
+        bool directionDown, bool skipSubChannel) {
+    ALOGV("nativeStep()");
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return;
+
+    auto dir = convert::DirectionToHal(directionDown);
+    convert::ThrowIfFailed(env, halTuner->step(dir, skipSubChannel));
+}
+
+static void nativeScan(JNIEnv *env, jobject obj, jlong nativeContext,
+        bool directionDown, bool skipSubChannel) {
+    ALOGV("nativeScan()");
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return;
+
+    auto dir = convert::DirectionToHal(directionDown);
+    convert::ThrowIfFailed(env, halTuner->scan(dir, skipSubChannel));
+}
+
+static void nativeTune(JNIEnv *env, jobject obj, jlong nativeContext,
+        jint channel, jint subChannel) {
+    ALOGV("nativeTune(%d, %d)", channel, subChannel);
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return;
+
+    convert::ThrowIfFailed(env, halTuner->tune(channel, subChannel));
+}
+
+static void nativeCancel(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeCancel()");
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return;
+
+    convert::ThrowIfFailed(env, halTuner->cancel());
+}
+
+static jobject nativeGetProgramInformation(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeGetProgramInformation()");
+    auto halTuner10 = getHalTuner(nativeContext);
+    auto halTuner11 = getHalTuner11(nativeContext);
+    if (halTuner10 == nullptr) return nullptr;
+
+    JavaRef<jobject> jInfo;
+    Result halResult;
+    Return<void> hidlResult;
+    if (halTuner11 != nullptr) {
+        hidlResult = halTuner11->getProgramInformation_1_1([&](Result result,
+                const V1_1::ProgramInfo& info) {
+            halResult = result;
+            if (result != Result::OK) return;
+            jInfo = convert::ProgramInfoFromHal(env, info);
+        });
+    } else {
+        hidlResult = halTuner10->getProgramInformation([&](Result result,
+                const V1_0::ProgramInfo& info) {
+            halResult = result;
+            if (result != Result::OK) return;
+            jInfo = convert::ProgramInfoFromHal(env, info);
+        });
+    }
+
+    if (jInfo != nullptr) return jInfo.release();
+    convert::ThrowIfFailed(env, hidlResult, halResult);
+    return nullptr;
+}
+
+static bool nativeStartBackgroundScan(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeStartBackgroundScan()");
+    auto halTuner = getHalTuner11(nativeContext);
+    if (halTuner == nullptr) {
+        ALOGI("Background scan is not supported with HAL < 1.1");
+        return false;
+    }
+
+    auto halResult = halTuner->startBackgroundScan();
+
+    if (halResult.isOk() && halResult == ProgramListResult::UNAVAILABLE) return false;
+    return !convert::ThrowIfFailed(env, halResult);
+}
+
+static jobject nativeGetProgramList(JNIEnv *env, jobject obj, jlong nativeContext, jstring jFilter) {
+    ALOGV("nativeGetProgramList()");
+    EnvWrapper wrap(env);
+    auto halTuner = getHalTuner11(nativeContext);
+    if (halTuner == nullptr) {
+        ALOGI("Program list is not supported with HAL < 1.1");
+        return nullptr;
+    }
+
+    JavaRef<jobject> jList;
+    ProgramListResult halResult = ProgramListResult::NOT_INITIALIZED;
+    auto filter = env->GetStringUTFChars(jFilter, nullptr);
+    auto hidlResult = halTuner->getProgramList(filter,
+            [&](ProgramListResult result, const hidl_vec<V1_1::ProgramInfo>& programList) {
+        halResult = result;
+        if (halResult != ProgramListResult::OK) return;
+
+        jList = wrap(env->NewObject(gjni.ArrayList.clazz, gjni.ArrayList.cstor));
+        for (auto& program : programList) {
+            auto jProgram = convert::ProgramInfoFromHal(env, program);
+            env->CallBooleanMethod(jList.get(), gjni.ArrayList.add, jProgram.get());
+        }
+    });
+
+    if (convert::ThrowIfFailed(env, hidlResult, halResult)) return nullptr;
+
+    return jList.release();
+}
+
+static bool nativeIsAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeIsAnalogForced()");
+    auto halTuner = getHalTuner11(nativeContext);
+    if (halTuner == nullptr) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Forced analog switch is not supported with HAL < 1.1");
+        return false;
+    }
+
+    bool isForced;
+    Result halResult;
+    auto hidlResult = halTuner->isAnalogForced([&](Result result, bool isForcedRet) {
+        halResult = result;
+        isForced = isForcedRet;
+    });
+
+    if (convert::ThrowIfFailed(env, hidlResult, halResult)) return false;
+
+    return isForced;
+}
+
+static void nativeSetAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext, bool isForced) {
+    ALOGV("nativeSetAnalogForced()");
+    auto halTuner = getHalTuner11(nativeContext);
+    if (halTuner == nullptr) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Forced analog switch is not supported with HAL < 1.1");
+        return;
+    }
+
+    auto halResult = halTuner->setAnalogForced(isForced);
+    convert::ThrowIfFailed(env, halResult);
+}
+
+static bool nativeIsAntennaConnected(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeIsAntennaConnected()");
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return false;
+
+    bool isConnected = false;
+    Result halResult;
+    auto hidlResult = halTuner->getConfiguration([&](Result result, const BandConfig& config) {
+        halResult = result;
+        isConnected = config.antennaConnected;
+    });
+    convert::ThrowIfFailed(env, hidlResult, halResult);
+    return isConnected;
+}
+
+static const JNINativeMethod gTunerMethods[] = {
+    { "nativeInit", "(I)J", (void*)nativeInit },
+    { "nativeFinalize", "(J)V", (void*)nativeFinalize },
+    { "nativeClose", "(J)V", (void*)nativeClose },
+    { "nativeSetConfiguration", "(JLandroid/hardware/radio/RadioManager$BandConfig;)V",
+            (void*)nativeSetConfiguration },
+    { "nativeGetConfiguration", "(JI)Landroid/hardware/radio/RadioManager$BandConfig;",
+            (void*)nativeGetConfiguration },
+    { "nativeStep", "(JZZ)V", (void*)nativeStep },
+    { "nativeScan", "(JZZ)V", (void*)nativeScan },
+    { "nativeTune", "(JII)V", (void*)nativeTune },
+    { "nativeCancel", "(J)V", (void*)nativeCancel },
+    { "nativeGetProgramInformation", "(J)Landroid/hardware/radio/RadioManager$ProgramInfo;",
+            (void*)nativeGetProgramInformation },
+    { "nativeStartBackgroundScan", "(J)Z", (void*)nativeStartBackgroundScan },
+    { "nativeGetProgramList", "(JLjava/lang/String;)Ljava/util/List;",
+            (void*)nativeGetProgramList },
+    { "nativeIsAnalogForced", "(J)Z", (void*)nativeIsAnalogForced },
+    { "nativeSetAnalogForced", "(JZ)V", (void*)nativeSetAnalogForced },
+    { "nativeIsAntennaConnected", "(J)Z", (void*)nativeIsAntennaConnected },
+};
+
+} // namespace Tuner
+} // namespace radio
+} // namespace server
+
+void register_android_server_radio_Tuner(JavaVM *vm, JNIEnv *env) {
+    using namespace server::radio::Tuner;
+
+    register_android_server_radio_TunerCallback(vm, env);
+
+    auto tunerClass = FindClassOrDie(env, "com/android/server/radio/Tuner");
+    gjni.Tuner.nativeContext = GetFieldIDOrDie(env, tunerClass, "mNativeContext", "J");
+    gjni.Tuner.region = GetFieldIDOrDie(env, tunerClass, "mRegion", "I");
+    gjni.Tuner.tunerCallback = GetFieldIDOrDie(env, tunerClass, "mTunerCallback",
+            "Lcom/android/server/radio/TunerCallback;");
+
+    auto arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
+    gjni.ArrayList.clazz = MakeGlobalRefOrDie(env, arrayListClass);
+    gjni.ArrayList.cstor = GetMethodIDOrDie(env, arrayListClass, "<init>", "()V");
+    gjni.ArrayList.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
+
+    auto res = jniRegisterNativeMethods(env, "com/android/server/radio/Tuner",
+            gTunerMethods, NELEM(gTunerMethods));
+    LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
+}
+
+} // namespace android
diff --git a/services/core/jni/com_android_server_radio_Tuner.h b/services/core/jni/com_android_server_radio_Tuner.h
new file mode 100644
index 0000000..f653832
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_Tuner.h
@@ -0,0 +1,50 @@
+/**
+ * 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.
+ */
+
+#ifndef _ANDROID_SERVER_RADIO_TUNER_H
+#define _ANDROID_SERVER_RADIO_TUNER_H
+
+#include "com_android_server_radio_types.h"
+
+#include "JavaRef.h"
+
+#include <android/hardware/broadcastradio/1.1/ITuner.h>
+#include <android/hardware/broadcastradio/1.1/ITunerCallback.h>
+#include <jni.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+void register_android_server_radio_Tuner(JavaVM *vm, JNIEnv *env);
+
+namespace server {
+namespace radio {
+namespace Tuner {
+
+void setHalTuner(JNIEnv *env, JavaRef<jobject> const &jTuner,
+        sp<hardware::broadcastradio::V1_0::ITuner> halTuner);
+
+sp<hardware::broadcastradio::V1_1::ITunerCallback>
+getNativeCallback(JNIEnv *env, JavaRef<jobject> const &tuner);
+
+Region getRegion(JNIEnv *env, jobject obj);
+
+} // namespace Tuner
+} // namespace radio
+} // namespace server
+} // namespace android
+
+#endif // _ANDROID_SERVER_RADIO_TUNER_H
diff --git a/services/core/jni/com_android_server_radio_Tuner_TunerCallback.cpp b/services/core/jni/com_android_server_radio_Tuner_TunerCallback.cpp
new file mode 100644
index 0000000..1290c7a
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_Tuner_TunerCallback.cpp
@@ -0,0 +1,319 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "radio.TunerCallback.jni"
+#define LOG_NDEBUG 0
+
+#include "com_android_server_radio_Tuner_TunerCallback.h"
+
+#include "com_android_server_radio_convert.h"
+#include "com_android_server_radio_Tuner.h"
+
+#include <core_jni_helpers.h>
+#include <utils/Log.h>
+#include <JNIHelp.h>
+
+namespace android {
+namespace server {
+namespace radio {
+namespace TunerCallback {
+
+using hardware::Return;
+using hardware::hidl_vec;
+
+namespace V1_0 = hardware::broadcastradio::V1_0;
+namespace V1_1 = hardware::broadcastradio::V1_1;
+
+using V1_0::BandConfig;
+using V1_0::MetaData;
+using V1_0::Result;
+using V1_1::ITunerCallback;
+using V1_1::ProgramListResult;
+
+static JavaVM *gvm = nullptr;
+
+static struct {
+    struct {
+        jclass clazz;
+        jfieldID nativeContext;
+        jmethodID handleHwFailure;
+        jmethodID onError;
+        jmethodID onConfigurationChanged;
+        jmethodID onProgramInfoChanged;
+    } TunerCallback;
+} gjni;
+
+// from frameworks/base/core/java/android/hardware/radio/RadioTuner.java
+enum class TunerError : jint {
+    HARDWARE_FAILURE = 0,
+    SERVER_DIED = 1,
+    CANCELLED = 2,
+    SCAN_TIMEOUT = 3,
+    CONFIG = 4,
+};
+
+static Mutex gContextMutex;
+
+class NativeCallback : public ITunerCallback {
+    jobject mJTuner;
+    jobject mJCallback;
+    NativeCallbackThread mCallbackThread;
+    HalRevision mHalRev;
+
+    DISALLOW_COPY_AND_ASSIGN(NativeCallback);
+
+public:
+    NativeCallback(JNIEnv *env, jobject jTuner, jobject jCallback, HalRevision halRev);
+    virtual ~NativeCallback();
+
+    void detach();
+
+    virtual Return<void> hardwareFailure();
+    virtual Return<void> configChange(Result result, const BandConfig& config);
+    virtual Return<void> tuneComplete(Result result, const V1_0::ProgramInfo& info);
+    virtual Return<void> afSwitch(const V1_0::ProgramInfo& info);
+    virtual Return<void> antennaStateChange(bool connected);
+    virtual Return<void> trafficAnnouncement(bool active);
+    virtual Return<void> emergencyAnnouncement(bool active);
+    virtual Return<void> newMetadata(uint32_t channel, uint32_t subChannel,
+            const hidl_vec<MetaData>& metadata);
+    virtual Return<void> tuneComplete_1_1(Result result, const V1_1::ProgramInfo& info);
+    virtual Return<void> afSwitch_1_1(const V1_1::ProgramInfo& info);
+    virtual Return<void> backgroundScanAvailable(bool isAvailable);
+    virtual Return<void> backgroundScanComplete(ProgramListResult result);
+    virtual Return<void> programListChanged();
+};
+
+struct TunerCallbackContext {
+    TunerCallbackContext() {}
+
+    sp<NativeCallback> mNativeCallback;
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(TunerCallbackContext);
+};
+
+NativeCallback::NativeCallback(JNIEnv *env, jobject jTuner, jobject jCallback, HalRevision halRev)
+        : mCallbackThread(gvm), mHalRev(halRev) {
+    ALOGV("NativeCallback()");
+    mJTuner = env->NewGlobalRef(jTuner);
+    mJCallback = env->NewGlobalRef(jCallback);
+}
+
+NativeCallback::~NativeCallback() {
+    ALOGV("~NativeCallback()");
+
+    // stop callback thread before dereferencing client callback
+    mCallbackThread.stop();
+
+    JNIEnv *env = nullptr;
+    gvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_4);
+    if (env != nullptr) {
+        env->DeleteGlobalRef(mJTuner);
+        env->DeleteGlobalRef(mJCallback);
+    }
+}
+
+void NativeCallback::detach() {
+    // stop callback thread to ignore further calls
+    mCallbackThread.stop();
+}
+
+Return<void> NativeCallback::hardwareFailure() {
+    mCallbackThread.enqueue([this](JNIEnv *env) {
+        env->CallVoidMethod(mJCallback, gjni.TunerCallback.handleHwFailure);
+    });
+
+    return Return<void>();
+}
+
+Return<void> NativeCallback::configChange(Result result, const BandConfig& config) {
+    ALOGV("configChange(%d)", result);
+
+    mCallbackThread.enqueue([result, config, this](JNIEnv *env) {
+        if (result == Result::OK) {
+            auto region = Tuner::getRegion(env, mJTuner);
+            auto jConfig = convert::BandConfigFromHal(env, config, region);
+            if (jConfig == nullptr) return;
+            env->CallVoidMethod(mJCallback, gjni.TunerCallback.onConfigurationChanged,
+                    jConfig.get());
+        } else {
+            env->CallVoidMethod(mJCallback, gjni.TunerCallback.onError, TunerError::CONFIG);
+        }
+    });
+
+    return Return<void>();
+}
+
+Return<void> NativeCallback::tuneComplete(Result result, const V1_0::ProgramInfo& info) {
+    ALOGV("tuneComplete(%d)", result);
+
+    if (mHalRev > HalRevision::V1_0) {
+        ALOGD("1.0 callback was ignored");
+        return Return<void>();
+    }
+
+    V1_1::ProgramInfo info_1_1 {
+        .base = info,
+    };
+    return tuneComplete_1_1(result, info_1_1);
+}
+
+Return<void> NativeCallback::tuneComplete_1_1(Result result, const V1_1::ProgramInfo& info) {
+    ALOGV("tuneComplete_1_1(%d)", result);
+
+    mCallbackThread.enqueue([result, info, this](JNIEnv *env) {
+        if (result == Result::OK) {
+            auto jInfo = convert::ProgramInfoFromHal(env, info);
+            if (jInfo == nullptr) return;
+            env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramInfoChanged, jInfo.get());
+        } else {
+            TunerError cause = TunerError::CANCELLED;
+            if (result == Result::TIMEOUT) cause = TunerError::SCAN_TIMEOUT;
+            env->CallVoidMethod(mJCallback, gjni.TunerCallback.onError, cause);
+        }
+    });
+
+    return Return<void>();
+}
+
+Return<void> NativeCallback::afSwitch(const V1_0::ProgramInfo& info) {
+    ALOGE("Not implemented: afSwitch");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::afSwitch_1_1(const V1_1::ProgramInfo& info) {
+    ALOGE("Not implemented: afSwitch_1_1");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::antennaStateChange(bool connected) {
+    ALOGE("Not implemented: antennaStateChange");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::trafficAnnouncement(bool active) {
+    ALOGE("Not implemented: trafficAnnouncement");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::emergencyAnnouncement(bool active) {
+    ALOGE("Not implemented: emergencyAnnouncement");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::newMetadata(uint32_t channel, uint32_t subChannel,
+        const hidl_vec<MetaData>& metadata) {
+    ALOGE("Not implemented: newMetadata");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::backgroundScanAvailable(bool isAvailable) {
+    ALOGE("Not implemented: backgroundScanAvailable");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::backgroundScanComplete(ProgramListResult result) {
+    ALOGE("Not implemented: backgroundScanComplete");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::programListChanged() {
+    ALOGE("Not implemented: programListChanged");
+    return Return<void>();
+}
+
+static TunerCallbackContext& getNativeContext(jlong nativeContextHandle) {
+    auto nativeContext = reinterpret_cast<TunerCallbackContext*>(nativeContextHandle);
+    LOG_ALWAYS_FATAL_IF(nativeContext == nullptr, "Native context not initialized");
+    return *nativeContext;
+}
+
+/**
+ * Always lock gContextMutex when using native context.
+ */
+static TunerCallbackContext& getNativeContext(JNIEnv *env, jobject jTunerCb) {
+    return getNativeContext(env->GetLongField(jTunerCb, gjni.TunerCallback.nativeContext));
+}
+
+static jlong nativeInit(JNIEnv *env, jobject obj, jobject jTuner, jint jHalRev) {
+    ALOGV("nativeInit()");
+    AutoMutex _l(gContextMutex);
+
+    auto halRev = static_cast<HalRevision>(jHalRev);
+
+    auto ctx = new TunerCallbackContext();
+    ctx->mNativeCallback = new NativeCallback(env, jTuner, obj, halRev);
+
+    static_assert(sizeof(jlong) >= sizeof(ctx), "jlong is smaller than a pointer");
+    return reinterpret_cast<jlong>(ctx);
+}
+
+static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeFinalize()");
+    AutoMutex _l(gContextMutex);
+
+    auto ctx = reinterpret_cast<TunerCallbackContext*>(nativeContext);
+    delete ctx;
+}
+
+static void nativeDetach(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeDetach()");
+    AutoMutex _l(gContextMutex);
+    auto& ctx = getNativeContext(nativeContext);
+
+    if (ctx.mNativeCallback == nullptr) return;
+    ctx.mNativeCallback->detach();
+    ctx.mNativeCallback = nullptr;
+}
+
+sp<ITunerCallback> getNativeCallback(JNIEnv *env, jobject jTunerCallback) {
+    AutoMutex _l(gContextMutex);
+    auto& ctx = getNativeContext(env, jTunerCallback);
+    return ctx.mNativeCallback;
+}
+
+static const JNINativeMethod gTunerCallbackMethods[] = {
+    { "nativeInit", "(Lcom/android/server/radio/Tuner;I)J", (void*)nativeInit },
+    { "nativeFinalize", "(J)V", (void*)nativeFinalize },
+    { "nativeDetach", "(J)V", (void*)nativeDetach },
+};
+
+} // namespace TunerCallback
+} // namespace radio
+} // namespace server
+
+void register_android_server_radio_TunerCallback(JavaVM *vm, JNIEnv *env) {
+    using namespace server::radio::TunerCallback;
+
+    gvm = vm;
+
+    auto tunerCbClass = FindClassOrDie(env, "com/android/server/radio/TunerCallback");
+    gjni.TunerCallback.clazz = MakeGlobalRefOrDie(env, tunerCbClass);
+    gjni.TunerCallback.nativeContext = GetFieldIDOrDie(env, tunerCbClass, "mNativeContext", "J");
+    gjni.TunerCallback.handleHwFailure = GetMethodIDOrDie(env, tunerCbClass, "handleHwFailure", "()V");
+    gjni.TunerCallback.onError = GetMethodIDOrDie(env, tunerCbClass, "onError", "(I)V");
+    gjni.TunerCallback.onConfigurationChanged = GetMethodIDOrDie(env, tunerCbClass,
+            "onConfigurationChanged", "(Landroid/hardware/radio/RadioManager$BandConfig;)V");
+    gjni.TunerCallback.onProgramInfoChanged = GetMethodIDOrDie(env, tunerCbClass,
+            "onProgramInfoChanged", "(Landroid/hardware/radio/RadioManager$ProgramInfo;)V");
+
+    auto res = jniRegisterNativeMethods(env, "com/android/server/radio/TunerCallback",
+            gTunerCallbackMethods, NELEM(gTunerCallbackMethods));
+    LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
+}
+
+} // namespace android
diff --git a/services/core/jni/com_android_server_radio_Tuner_TunerCallback.h b/services/core/jni/com_android_server_radio_Tuner_TunerCallback.h
new file mode 100644
index 0000000..35a4d69
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_Tuner_TunerCallback.h
@@ -0,0 +1,45 @@
+/**
+ * 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.
+ */
+
+// TODO(b/36863239): rename s/_Tuner_TunerCallback/_TunerCallback/, as this
+// module is no longer a part of Tuner - it's an independent java class.
+#ifndef _ANDROID_SERVER_RADIO_TUNERCALLBACK_H
+#define _ANDROID_SERVER_RADIO_TUNERCALLBACK_H
+
+#include "JavaRef.h"
+#include "NativeCallbackThread.h"
+#include "com_android_server_radio_types.h"
+
+#include <android/hardware/broadcastradio/1.1/ITunerCallback.h>
+#include <jni.h>
+
+namespace android {
+
+void register_android_server_radio_TunerCallback(JavaVM *vm, JNIEnv *env);
+
+namespace server {
+namespace radio {
+namespace TunerCallback {
+
+sp<hardware::broadcastradio::V1_1::ITunerCallback>
+getNativeCallback(JNIEnv *env, jobject jTunerCallback);
+
+} // namespace TunerCallback
+} // namespace radio
+} // namespace server
+} // namespace android
+
+#endif // _ANDROID_SERVER_RADIO_TUNERCALLBACK_H
diff --git a/services/core/jni/com_android_server_radio_convert.cpp b/services/core/jni/com_android_server_radio_convert.cpp
new file mode 100644
index 0000000..19abf8a
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_convert.cpp
@@ -0,0 +1,397 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "radio.convert.jni"
+#define LOG_NDEBUG 0
+
+#include "com_android_server_radio_convert.h"
+
+#include <core_jni_helpers.h>
+#include <utils/Log.h>
+#include <JNIHelp.h>
+
+namespace android {
+namespace server {
+namespace radio {
+namespace convert {
+
+using hardware::Return;
+using hardware::hidl_vec;
+
+using V1_0::Band;
+using V1_0::Deemphasis;
+using V1_0::Direction;
+using V1_0::MetadataType;
+using V1_0::Result;
+using V1_0::Rds;
+using V1_1::ProgramListResult;
+
+static struct {
+    struct {
+        jfieldID descriptor;
+    } BandConfig;
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+        jfieldID stereo;
+        jfieldID rds;
+        jfieldID ta;
+        jfieldID af;
+        jfieldID ea;
+    } FmBandConfig;
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+        jfieldID stereo;
+    } AmBandConfig;
+
+    struct {
+        jfieldID region;
+        jfieldID type;
+        jfieldID lowerLimit;
+        jfieldID upperLimit;
+        jfieldID spacing;
+    } BandDescriptor;
+
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+    } ProgramInfo;
+
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+        jmethodID putIntFromNative;
+        jmethodID putStringFromNative;
+        jmethodID putBitmapFromNative;
+        jmethodID putClockFromNative;
+    } RadioMetadata;
+
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+    } RuntimeException;
+
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+    } ParcelableException;
+} gjni;
+
+bool __ThrowIfFailedHidl(JNIEnv *env, const hardware::details::return_status &hidlResult) {
+    if (hidlResult.isOk()) return false;
+
+    ThrowParcelableRuntimeException(env, "HIDL call failed: " + hidlResult.description());
+    return true;
+}
+
+bool __ThrowIfFailed(JNIEnv *env, const Result halResult) {
+    switch (halResult) {
+        case Result::OK:
+            return false;
+        case Result::NOT_INITIALIZED:
+            ThrowParcelableRuntimeException(env, "Result::NOT_INITIALIZED");
+            return true;
+        case Result::INVALID_ARGUMENTS:
+            jniThrowException(env, "java/lang/IllegalArgumentException",
+                    "Result::INVALID_ARGUMENTS");
+            return true;
+        case Result::INVALID_STATE:
+            jniThrowException(env, "java/lang/IllegalStateException", "Result::INVALID_STATE");
+            return true;
+        case Result::TIMEOUT:
+            ThrowParcelableRuntimeException(env, "Result::TIMEOUT (unexpected here)");
+            return true;
+        default:
+            ThrowParcelableRuntimeException(env, "Unknown failure, result: "
+                    + std::to_string(static_cast<int32_t>(halResult)));
+            return true;
+    }
+}
+
+bool __ThrowIfFailed(JNIEnv *env, const ProgramListResult halResult) {
+    switch (halResult) {
+        case ProgramListResult::NOT_READY:
+            jniThrowException(env, "java/lang/IllegalStateException", "Scan is in progress");
+            return true;
+        case ProgramListResult::NOT_STARTED:
+            jniThrowException(env, "java/lang/IllegalStateException", "Scan has not been started");
+            return true;
+        case ProgramListResult::UNAVAILABLE:
+            ThrowParcelableRuntimeException(env,
+                    "ProgramListResult::UNAVAILABLE (unexpected here)");
+            return true;
+        default:
+            return __ThrowIfFailed(env, static_cast<Result>(halResult));
+    }
+}
+
+void ThrowParcelableRuntimeException(JNIEnv *env, const std::string& msg) {
+    EnvWrapper wrap(env);
+
+    auto jMsg = wrap(env->NewStringUTF(msg.c_str()));
+    auto runtimeExc = wrap(env->NewObject(gjni.RuntimeException.clazz,
+            gjni.RuntimeException.cstor, jMsg.get()));
+    auto parcelableExc = wrap(env->NewObject(gjni.ParcelableException.clazz,
+            gjni.ParcelableException.cstor, runtimeExc.get()));
+
+    auto res = env->Throw(static_cast<jthrowable>(parcelableExc.get()));
+    ALOGE_IF(res != JNI_OK, "Couldn't throw parcelable runtime exception");
+}
+
+static Rds RdsForRegion(bool rds, Region region) {
+    if (!rds) return Rds::NONE;
+
+    switch(region) {
+        case Region::ITU_1:
+        case Region::OIRT:
+        case Region::JAPAN:
+        case Region::KOREA:
+            return Rds::WORLD;
+        case Region::ITU_2:
+            return Rds::US;
+        default:
+            ALOGE("Unexpected region: %d", region);
+            return Rds::NONE;
+    }
+}
+
+static Deemphasis DeemphasisForRegion(Region region) {
+    switch(region) {
+        case Region::KOREA:
+        case Region::ITU_2:
+            return Deemphasis::D75;
+        case Region::ITU_1:
+        case Region::OIRT:
+        case Region::JAPAN:
+            return Deemphasis::D50;
+        default:
+            ALOGE("Unexpected region: %d", region);
+            return Deemphasis::D50;
+    }
+}
+
+JavaRef<jobject> BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region) {
+    ALOGV("BandConfigFromHal()");
+    EnvWrapper wrap(env);
+
+    jint spacing = config.spacings.size() > 0 ? config.spacings[0] : 0;
+    ALOGW_IF(config.spacings.size() == 0, "No channel spacing specified");
+
+    switch (config.type) {
+        case Band::FM:
+        case Band::FM_HD: {
+            auto& fm = config.ext.fm;
+            return wrap(env->NewObject(gjni.FmBandConfig.clazz, gjni.FmBandConfig.cstor,
+                    region, config.type, config.lowerLimit, config.upperLimit, spacing,
+                    fm.stereo, fm.rds != Rds::NONE, fm.ta, fm.af, fm.ea));
+        }
+        case Band::AM:
+        case Band::AM_HD: {
+            auto& am = config.ext.am;
+            return wrap(env->NewObject(gjni.AmBandConfig.clazz, gjni.AmBandConfig.cstor,
+                    region, config.type, config.lowerLimit, config.upperLimit, spacing,
+                    am.stereo));
+        }
+        default:
+            ALOGE("Unsupported band type: %d", config.type);
+            return nullptr;
+    }
+}
+
+V1_0::BandConfig BandConfigToHal(JNIEnv *env, jobject jConfig, Region &region) {
+    ALOGV("BandConfigToHal()");
+    auto jDescriptor = env->GetObjectField(jConfig, gjni.BandConfig.descriptor);
+    if (jDescriptor == nullptr) {
+        ALOGE("Descriptor is missing");
+        return {};
+    }
+
+    region = static_cast<Region>(env->GetIntField(jDescriptor, gjni.BandDescriptor.region));
+
+    V1_0::BandConfig config = {};
+    config.type = static_cast<Band>(env->GetIntField(jDescriptor, gjni.BandDescriptor.type));
+    config.antennaConnected = false;  // just don't set it
+    config.lowerLimit = env->GetIntField(jDescriptor, gjni.BandDescriptor.lowerLimit);
+    config.upperLimit = env->GetIntField(jDescriptor, gjni.BandDescriptor.upperLimit);
+    config.spacings = hidl_vec<uint32_t>({
+        static_cast<uint32_t>(env->GetIntField(jDescriptor, gjni.BandDescriptor.spacing))
+    });
+
+    if (env->IsInstanceOf(jConfig, gjni.FmBandConfig.clazz)) {
+        auto& fm = config.ext.fm;
+        fm.deemphasis = DeemphasisForRegion(region);
+        fm.stereo = env->GetBooleanField(jConfig, gjni.FmBandConfig.stereo);
+        fm.rds = RdsForRegion(env->GetBooleanField(jConfig, gjni.FmBandConfig.rds), region);
+        fm.ta = env->GetBooleanField(jConfig, gjni.FmBandConfig.ta);
+        fm.af = env->GetBooleanField(jConfig, gjni.FmBandConfig.af);
+        fm.ea = env->GetBooleanField(jConfig, gjni.FmBandConfig.ea);
+    } else if (env->IsInstanceOf(jConfig, gjni.AmBandConfig.clazz)) {
+        auto& am = config.ext.am;
+        am.stereo = env->GetBooleanField(jConfig, gjni.AmBandConfig.stereo);
+    } else {
+        ALOGE("Unexpected band config type");
+        return {};
+    }
+
+    return config;
+}
+
+Direction DirectionToHal(bool directionDown) {
+    return directionDown ? Direction::DOWN : Direction::UP;
+}
+
+static JavaRef<jobject> MetadataFromHal(JNIEnv *env, const hidl_vec<V1_0::MetaData> metadata) {
+    ALOGV("MetadataFromHal()");
+    EnvWrapper wrap(env);
+
+    if (metadata.size() == 0) return nullptr;
+
+    auto jMetadata = wrap(env->NewObject(gjni.RadioMetadata.clazz, gjni.RadioMetadata.cstor));
+
+    for (auto& item : metadata) {
+        jint key = static_cast<jint>(item.key);
+        jint status = 0;
+        switch (item.type) {
+            case MetadataType::INT:
+                ALOGV("metadata INT %d", key);
+                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putIntFromNative,
+                        key, item.intValue);
+                break;
+            case MetadataType::TEXT: {
+                ALOGV("metadata TEXT %d", key);
+                auto value = wrap(env->NewStringUTF(item.stringValue.c_str()));
+                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putStringFromNative,
+                        key, value.get());
+                break;
+            }
+            case MetadataType::RAW: {
+                ALOGV("metadata RAW %d", key);
+                auto len = item.rawValue.size();
+                if (len == 0) break;
+                auto value = wrap(env->NewByteArray(len));
+                if (value == nullptr) {
+                    ALOGE("Failed to allocate byte array of len %zu", len);
+                    break;
+                }
+                env->SetByteArrayRegion(value.get(), 0, len,
+                        reinterpret_cast<const jbyte*>(item.rawValue.data()));
+                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putBitmapFromNative,
+                        key, value.get());
+                break;
+            }
+            case MetadataType::CLOCK:
+                ALOGV("metadata CLOCK %d", key);
+                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putClockFromNative,
+                        key, item.clockValue.utcSecondsSinceEpoch,
+                        item.clockValue.timezoneOffsetInMinutes);
+                break;
+            default:
+                ALOGW("invalid metadata type %d", item.type);
+        }
+        ALOGE_IF(status != 0, "Failed inserting metadata %d (of type %d)", key, item.type);
+    }
+
+    return jMetadata;
+}
+
+static JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info10,
+        const V1_1::ProgramInfo *info11) {
+    ALOGV("ProgramInfoFromHal()");
+    EnvWrapper wrap(env);
+
+    auto jMetadata = MetadataFromHal(env, info10.metadata);
+    auto jVendorExtension = info11 ?
+            wrap(env->NewStringUTF(info11->vendorExension.c_str())) : nullptr;
+
+    return wrap(env->NewObject(gjni.ProgramInfo.clazz, gjni.ProgramInfo.cstor, info10.channel,
+            info10.subChannel, info10.tuned, info10.stereo, info10.digital, info10.signalStrength,
+            jMetadata.get(), info11 ? info11->flags : 0, jVendorExtension.get()));
+}
+
+JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info) {
+    return ProgramInfoFromHal(env, info, nullptr);
+}
+
+JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_1::ProgramInfo &info) {
+    return ProgramInfoFromHal(env, info.base, &info);
+}
+
+} // namespace convert
+} // namespace radio
+} // namespace server
+
+void register_android_server_radio_convert(JNIEnv *env) {
+    using namespace server::radio::convert;
+
+    auto bandConfigClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$BandConfig");
+    gjni.BandConfig.descriptor = GetFieldIDOrDie(env, bandConfigClass,
+            "mDescriptor", "Landroid/hardware/radio/RadioManager$BandDescriptor;");
+
+    auto fmBandConfigClass = FindClassOrDie(env,
+            "android/hardware/radio/RadioManager$FmBandConfig");
+    gjni.FmBandConfig.clazz = MakeGlobalRefOrDie(env, fmBandConfigClass);
+    gjni.FmBandConfig.cstor = GetMethodIDOrDie(env, fmBandConfigClass,
+            "<init>", "(IIIIIZZZZZ)V");
+    gjni.FmBandConfig.stereo = GetFieldIDOrDie(env, fmBandConfigClass, "mStereo", "Z");
+    gjni.FmBandConfig.rds = GetFieldIDOrDie(env, fmBandConfigClass, "mRds", "Z");
+    gjni.FmBandConfig.ta = GetFieldIDOrDie(env, fmBandConfigClass, "mTa", "Z");
+    gjni.FmBandConfig.af = GetFieldIDOrDie(env, fmBandConfigClass, "mAf", "Z");
+    gjni.FmBandConfig.ea = GetFieldIDOrDie(env, fmBandConfigClass, "mEa", "Z");
+
+    auto amBandConfigClass = FindClassOrDie(env,
+            "android/hardware/radio/RadioManager$AmBandConfig");
+    gjni.AmBandConfig.clazz = MakeGlobalRefOrDie(env, amBandConfigClass);
+    gjni.AmBandConfig.cstor = GetMethodIDOrDie(env, amBandConfigClass, "<init>", "(IIIIIZ)V");
+    gjni.AmBandConfig.stereo = GetFieldIDOrDie(env, amBandConfigClass, "mStereo", "Z");
+
+    auto bandDescriptorClass = FindClassOrDie(env,
+            "android/hardware/radio/RadioManager$BandDescriptor");
+    gjni.BandDescriptor.region = GetFieldIDOrDie(env, bandDescriptorClass, "mRegion", "I");
+    gjni.BandDescriptor.type = GetFieldIDOrDie(env, bandDescriptorClass, "mType", "I");
+    gjni.BandDescriptor.lowerLimit = GetFieldIDOrDie(env, bandDescriptorClass, "mLowerLimit", "I");
+    gjni.BandDescriptor.upperLimit = GetFieldIDOrDie(env, bandDescriptorClass, "mUpperLimit", "I");
+    gjni.BandDescriptor.spacing = GetFieldIDOrDie(env, bandDescriptorClass, "mSpacing", "I");
+
+    auto programInfoClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$ProgramInfo");
+    gjni.ProgramInfo.clazz = MakeGlobalRefOrDie(env, programInfoClass);
+    gjni.ProgramInfo.cstor = GetMethodIDOrDie(env, programInfoClass, "<init>",
+            "(IIZZZILandroid/hardware/radio/RadioMetadata;ILjava/lang/String;)V");
+
+    auto radioMetadataClass = FindClassOrDie(env, "android/hardware/radio/RadioMetadata");
+    gjni.RadioMetadata.clazz = MakeGlobalRefOrDie(env, radioMetadataClass);
+    gjni.RadioMetadata.cstor = GetMethodIDOrDie(env, radioMetadataClass, "<init>", "()V");
+    gjni.RadioMetadata.putIntFromNative = GetMethodIDOrDie(env, radioMetadataClass,
+            "putIntFromNative", "(II)I");
+    gjni.RadioMetadata.putStringFromNative = GetMethodIDOrDie(env, radioMetadataClass,
+            "putStringFromNative", "(ILjava/lang/String;)I");
+    gjni.RadioMetadata.putBitmapFromNative = GetMethodIDOrDie(env, radioMetadataClass,
+            "putBitmapFromNative", "(I[B)I");
+    gjni.RadioMetadata.putClockFromNative = GetMethodIDOrDie(env, radioMetadataClass,
+            "putClockFromNative", "(IJI)I");
+
+    auto runtimeExcClass = FindClassOrDie(env, "java/lang/RuntimeException");
+    gjni.RuntimeException.clazz = MakeGlobalRefOrDie(env, runtimeExcClass);
+    gjni.RuntimeException.cstor = GetMethodIDOrDie(env, runtimeExcClass, "<init>",
+            "(Ljava/lang/String;)V");
+
+    auto parcelableExcClass = FindClassOrDie(env, "android/os/ParcelableException");
+    gjni.ParcelableException.clazz = MakeGlobalRefOrDie(env, parcelableExcClass);
+    gjni.ParcelableException.cstor = GetMethodIDOrDie(env, parcelableExcClass, "<init>",
+            "(Ljava/lang/Throwable;)V");
+}
+
+} // namespace android
diff --git a/services/core/jni/com_android_server_radio_convert.h b/services/core/jni/com_android_server_radio_convert.h
new file mode 100644
index 0000000..6f6774b
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_convert.h
@@ -0,0 +1,69 @@
+/**
+ * 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.
+ */
+
+#ifndef _ANDROID_SERVER_RADIO_CONVERT_H
+#define _ANDROID_SERVER_RADIO_CONVERT_H
+
+#include "JavaRef.h"
+#include "com_android_server_radio_types.h"
+
+#include <android/hardware/broadcastradio/1.1/types.h>
+#include <jni.h>
+
+namespace android {
+
+void register_android_server_radio_convert(JNIEnv *env);
+
+namespace server {
+namespace radio {
+namespace convert {
+
+namespace V1_0 = hardware::broadcastradio::V1_0;
+namespace V1_1 = hardware::broadcastradio::V1_1;
+
+JavaRef<jobject> BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region);
+V1_0::BandConfig BandConfigToHal(JNIEnv *env, jobject jConfig, Region &region);
+
+V1_0::Direction DirectionToHal(bool directionDown);
+
+JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info);
+JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_1::ProgramInfo &info);
+
+
+void ThrowParcelableRuntimeException(JNIEnv *env, const std::string& msg);
+
+// These three are only for internal use by template functions below.
+bool __ThrowIfFailedHidl(JNIEnv *env,
+        const hardware::details::return_status &hidlResult);
+bool __ThrowIfFailed(JNIEnv *env, const V1_0::Result halResult);
+bool __ThrowIfFailed(JNIEnv *env, const V1_1::ProgramListResult halResult);
+
+template <typename T>
+bool ThrowIfFailed(JNIEnv *env, const hardware::Return<void> &hidlResult, const T halResult) {
+    return __ThrowIfFailedHidl(env, hidlResult) || __ThrowIfFailed(env, halResult);
+}
+
+template <typename T>
+bool ThrowIfFailed(JNIEnv *env, const hardware::Return<T> &hidlResult) {
+    return __ThrowIfFailedHidl(env, hidlResult) || __ThrowIfFailed(env, static_cast<T>(hidlResult));
+}
+
+} // namespace convert
+} // namespace radio
+} // namespace server
+} // namespace android
+
+#endif // _ANDROID_SERVER_RADIO_CONVERT_H
diff --git a/services/core/jni/com_android_server_radio_types.h b/services/core/jni/com_android_server_radio_types.h
new file mode 100644
index 0000000..36f7643
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_types.h
@@ -0,0 +1,60 @@
+/**
+ * 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.
+ */
+
+#ifndef _ANDROID_SERVER_RADIO_TYPES_H
+#define _ANDROID_SERVER_RADIO_TYPES_H
+
+#include <jni.h>
+
+namespace android {
+namespace server {
+namespace radio {
+
+/* Most of these enums are dereived from Java code, based at
+ * frameworks/base/core/java/android/hardware/radio/RadioManager.java.
+ */
+
+enum class HalRevision : jint {
+    V1_0,
+    V1_1,
+};
+
+// Keep in sync with STATUS_* constants from RadioManager.java.
+enum class Status : jint {
+    OK = 0,
+    ERROR = -0x80000000ll,  // Integer.MIN_VALUE
+    PERMISSION_DENIED = -1,  // -EPERM
+    NO_INIT = -19,  // -ENODEV
+    BAD_VALUE = -22,  // -EINVAL
+    DEAD_OBJECT = -32,  // -EPIPE
+    INVALID_OPERATION = -38,  // -ENOSYS
+    TIMED_OUT = -110,  // -ETIMEDOUT
+};
+
+// Keep in sync with REGION_* constants from RadioManager.java.
+enum class Region : jint {
+    ITU_1 = 0,
+    ITU_2 = 1,
+    OIRT = 2,
+    JAPAN = 3,
+    KOREA = 4,
+};
+
+} // namespace radio
+} // namespace server
+} // namespace android
+
+#endif // _ANDROID_SERVER_RADIO_TYPES_H
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 69e46e7..6e648c9 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -19,6 +19,9 @@
 #include "utils/Log.h"
 #include "utils/misc.h"
 
+#include "com_android_server_radio_RadioService.h"
+#include "com_android_server_radio_Tuner.h"
+
 namespace android {
 int register_android_server_AlarmManagerService(JNIEnv* env);
 int register_android_server_BatteryStatsService(JNIEnv* env);
@@ -64,6 +67,8 @@
     }
     ALOG_ASSERT(env, "Could not retrieve the env!");
 
+    register_android_server_radio_RadioService(env);
+    register_android_server_radio_Tuner(vm, env);
     register_android_server_PowerManagerService(env);
     register_android_server_SerialService(env);
     register_android_server_InputApplicationHandle(env);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 911bb2a..d249b0a9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -43,6 +43,7 @@
 import static android.app.admin.DevicePolicyManager.DELEGATION_PERMISSION_GRANT;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
 import static android.app.admin.DevicePolicyManager.PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER;
+import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
 import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE;
 import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
@@ -254,6 +255,8 @@
 
     private static final String TAG_PASSWORD_TOKEN_HANDLE = "password-token";
 
+    private static final String TAG_PASSWORD_VALIDITY = "password-validity";
+
     private static final int REQUEST_EXPIRE_PASSWORD = 5571;
 
     private static final long MS_PER_DAY = TimeUnit.DAYS.toMillis(1);
@@ -478,6 +481,8 @@
     public static class DevicePolicyData {
         @NonNull PasswordMetrics mActivePasswordMetrics = new PasswordMetrics();
         int mFailedPasswordAttempts = 0;
+        boolean mPasswordStateHasBeenSetSinceBoot = false;
+        boolean mPasswordValidAtLastCheckpoint = false;
 
         int mUserHandle;
         int mPasswordOwner = -1;
@@ -521,7 +526,7 @@
         // TODO(b/35385311): Keep track of metadata in TrustedCertificateStore instead.
         Set<String> mOwnerInstalledCaCerts = new ArraySet<>();
 
-        // Used for initialization of users created by createAndManageUsers.
+        // Used for initialization of users created by createAndManageUser.
         boolean mAdminBroadcastPending = false;
         PersistableBundle mInitBundle = null;
 
@@ -1687,9 +1692,9 @@
             mContext.getSystemService(PowerManager.class).reboot(reason);
         }
 
-        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force)
-                throws IOException {
-            RecoverySystem.rebootWipeUserData(mContext, shutdown, reason, force);
+        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force,
+                boolean wipeEuicc) throws IOException {
+            RecoverySystem.rebootWipeUserData(mContext, shutdown, reason, force, wipeEuicc);
         }
 
         boolean systemPropertiesGetBoolean(String key, boolean def) {
@@ -2379,6 +2384,9 @@
             BroadcastReceiver result) {
         Intent intent = new Intent(action);
         intent.setComponent(admin.info.getComponent());
+        if (UserManager.isDeviceInDemoMode(mContext)) {
+            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        }
         if (action.equals(DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING)) {
             intent.putExtra("expiration", admin.passwordExpirationDate);
         }
@@ -2574,19 +2582,14 @@
                 out.endTag(null, "failed-password-attempts");
             }
 
-            // Don't save metrics for FBE devices
-            final PasswordMetrics metrics = policy.mActivePasswordMetrics;
-            if (!mInjector.storageManagerIsFileBasedEncryptionEnabled() && !metrics.isDefault()) {
-                out.startTag(null, "active-password");
-                out.attribute(null, "quality", Integer.toString(metrics.quality));
-                out.attribute(null, "length", Integer.toString(metrics.length));
-                out.attribute(null, "uppercase", Integer.toString(metrics.upperCase));
-                out.attribute(null, "lowercase", Integer.toString(metrics.lowerCase));
-                out.attribute(null, "letters", Integer.toString(metrics.letters));
-                out.attribute(null, "numeric", Integer.toString(metrics.numeric));
-                out.attribute(null, "symbols", Integer.toString(metrics.symbols));
-                out.attribute(null, "nonletter", Integer.toString(metrics.nonLetter));
-                out.endTag(null, "active-password");
+            // For FDE devices only, we save this flag so we can report on password sufficiency
+            // before the user enters their password for the first time after a reboot.  For
+            // security reasons, we don't want to store the full set of active password metrics.
+            if (!mInjector.storageManagerIsFileBasedEncryptionEnabled()) {
+                out.startTag(null, TAG_PASSWORD_VALIDITY);
+                out.attribute(null, ATTR_VALUE,
+                        Boolean.toString(policy.mPasswordValidAtLastCheckpoint));
+                out.endTag(null, TAG_PASSWORD_VALIDITY);
             }
 
             for (int i = 0; i < policy.mAcceptedCaCertificates.size(); i++) {
@@ -2864,19 +2867,14 @@
                 } else if (TAG_INITIALIZATION_BUNDLE.equals(tag)) {
                     policy.mInitBundle = PersistableBundle.restoreFromXml(parser);
                 } else if ("active-password".equals(tag)) {
-                    if (mInjector.storageManagerIsFileBasedEncryptionEnabled()) {
-                        // Remove this from FBE devices
-                        needsRewrite = true;
-                    } else {
-                        final PasswordMetrics m = policy.mActivePasswordMetrics;
-                        m.quality = Integer.parseInt(parser.getAttributeValue(null, "quality"));
-                        m.length = Integer.parseInt(parser.getAttributeValue(null, "length"));
-                        m.upperCase = Integer.parseInt(parser.getAttributeValue(null, "uppercase"));
-                        m.lowerCase = Integer.parseInt(parser.getAttributeValue(null, "lowercase"));
-                        m.letters = Integer.parseInt(parser.getAttributeValue(null, "letters"));
-                        m.numeric = Integer.parseInt(parser.getAttributeValue(null, "numeric"));
-                        m.symbols = Integer.parseInt(parser.getAttributeValue(null, "symbols"));
-                        m.nonLetter = Integer.parseInt(parser.getAttributeValue(null, "nonletter"));
+                    // Remove password metrics from saved settings, as we no longer wish to store
+                    // these on disk
+                    needsRewrite = true;
+                } else if (TAG_PASSWORD_VALIDITY.equals(tag)) {
+                    if (!mInjector.storageManagerIsFileBasedEncryptionEnabled()) {
+                        // This flag is only used for FDE devices
+                        policy.mPasswordValidAtLastCheckpoint = Boolean.parseBoolean(
+                                parser.getAttributeValue(null, ATTR_VALUE));
                     }
                 } else if (TAG_PASSWORD_TOKEN_HANDLE.equals(tag)) {
                     policy.mPasswordTokenHandle = Long.parseLong(
@@ -3453,11 +3451,24 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.quality != quality) {
                 ap.minimumPasswordMetrics.quality = quality;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
     }
 
+    /**
+     * Updates flag in memory that tells us whether the user's password currently satisfies the
+     * requirements set by all of the user's active admins.  This should be called before
+     * {@link #saveSettingsLocked} whenever the password or the admin policies have changed.
+     */
+    @GuardedBy("DevicePolicyManagerService.this")
+    private void updatePasswordValidityCheckpointLocked(int userHandle) {
+        DevicePolicyData policy = getUserData(userHandle);
+        policy.mPasswordValidAtLastCheckpoint = isActivePasswordSufficientForUserLocked(
+                policy, policy.mUserHandle, false);
+    }
+
     @Override
     public int getPasswordQuality(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
@@ -3540,6 +3551,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.length != length) {
                 ap.minimumPasswordMetrics.length = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3584,6 +3596,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.passwordHistoryLength != length) {
                 ap.passwordHistoryLength = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3796,6 +3809,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.upperCase != length) {
                 ap.minimumPasswordMetrics.upperCase = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3837,6 +3851,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.lowerCase != length) {
                 ap.minimumPasswordMetrics.lowerCase = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3881,6 +3896,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.letters != length) {
                 ap.minimumPasswordMetrics.letters = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3928,6 +3944,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.numeric != length) {
                 ap.minimumPasswordMetrics.numeric = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3975,6 +3992,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.symbols != length) {
                 ap.minimumPasswordMetrics.symbols = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -4022,6 +4040,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.nonLetter != length) {
                 ap.minimumPasswordMetrics.nonLetter = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -4093,6 +4112,16 @@
             DevicePolicyData policy, int userHandle, boolean parent) {
         enforceUserUnlocked(userHandle, parent);
 
+        if (!mInjector.storageManagerIsFileBasedEncryptionEnabled()
+                && !policy.mPasswordStateHasBeenSetSinceBoot) {
+            // Before user enters their password for the first time after a reboot, return the
+            // value of this flag, which tells us whether the password was valid the last time
+            // settings were saved.  If DPC changes password requirements on boot so that the
+            // current password no longer meets the requirements, this value will be stale until
+            // the next time the password is entered.
+            return policy.mPasswordValidAtLastCheckpoint;
+        }
+
         final int requiredPasswordQuality = getPasswordQuality(null, userHandle, parent);
         if (policy.mActivePasswordMetrics.quality < requiredPasswordQuality) {
             return false;
@@ -4229,6 +4258,7 @@
             mInjector.binderRestoreCallingIdentity(token);
         }
     }
+
     @Override
     public boolean resetPassword(String passwordOrNull, int flags) throws RemoteException {
         final int callingUid = mInjector.binderGetCallingUid();
@@ -5277,7 +5307,7 @@
         }
     }
 
-    private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason) {
+    private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason, boolean wipeEuicc) {
         wtfIfInLock();
 
         if (wipeExtRequested) {
@@ -5287,7 +5317,7 @@
         }
         try {
             mInjector.recoverySystemRebootWipeUserData(
-                    /*shutdown=*/ false, reason, /*force=*/ true);
+                    /*shutdown=*/ false, reason, /*force=*/ true, /*wipeEuicc=*/ wipeEuicc);
         } catch (IOException | SecurityException e) {
             Slog.w(LOG_TAG, "Failed requesting data wipe", e);
         }
@@ -5364,7 +5394,7 @@
             // removes that user (but still clears FRP...)
             if (userId == UserHandle.USER_SYSTEM) {
                 forceWipeDeviceNoLock(/*wipeExtRequested=*/ (flags & WIPE_EXTERNAL_STORAGE) != 0,
-                        reason);
+                        reason, /*wipeEuicc=*/ (flags & WIPE_EUICC) != 0);
             } else {
                 forceWipeUser(userId);
             }
@@ -5436,6 +5466,7 @@
         DevicePolicyData policy = getUserData(userHandle);
         synchronized (this) {
             policy.mActivePasswordMetrics = metrics;
+            policy.mPasswordStateHasBeenSetSinceBoot = true;
         }
     }
 
@@ -5460,6 +5491,7 @@
         try {
             synchronized (this) {
                 policy.mFailedPasswordAttempts = 0;
+                updatePasswordValidityCheckpointLocked(userId);
                 saveSettingsLocked(userId);
                 updatePasswordExpirationsLocked(userId);
                 setExpirationAlarmCheckLocked(mContext, userId, /* parent */ false);
@@ -7347,9 +7379,8 @@
 
     private void enableIfNecessary(String packageName, int userId) {
         try {
-            ApplicationInfo ai = mIPackageManager.getApplicationInfo(packageName,
-                    PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
-                    userId);
+            final ApplicationInfo ai = mIPackageManager.getApplicationInfo(packageName,
+                    PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, userId);
             if (ai.enabledSetting
                     == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
                 mIPackageManager.setApplicationEnabledSetting(packageName,
@@ -8103,8 +8134,10 @@
         if (!mInjector.binderGetCallingUserHandle().isSystem()) {
             throw new SecurityException("createAndManageUser was called from non-system user");
         }
-        if (!mInjector.userManagerIsSplitSystemUser()
-                && (flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0) {
+        final boolean ephemeral = (flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0;
+        final boolean demo = (flags & DevicePolicyManager.MAKE_USER_DEMO) != 0
+                && UserManager.isDeviceInDemoMode(mContext);
+        if (ephemeral && !mInjector.userManagerIsSplitSystemUser() && !demo) {
             throw new IllegalArgumentException(
                     "Ephemeral users are only supported on systems with a split system user.");
         }
@@ -8116,9 +8149,12 @@
             final long id = mInjector.binderClearCallingIdentity();
             try {
                 int userInfoFlags = 0;
-                if ((flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0) {
+                if (ephemeral) {
                     userInfoFlags |= UserInfo.FLAG_EPHEMERAL;
                 }
+                if (demo) {
+                    userInfoFlags |= UserInfo.FLAG_DEMO;
+                }
                 UserInfo userInfo = mUserManagerInternal.createUserEvenWhenDisallowed(name,
                         userInfoFlags);
                 if (userInfo != null) {
@@ -8443,6 +8479,8 @@
             enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER,
                     DELEGATION_ENABLE_SYSTEM_APP);
 
+            final boolean isDemo = isCurrentUserDemo();
+
             int userId = UserHandle.getCallingUserId();
             long id = mInjector.binderClearCallingIdentity();
 
@@ -8453,14 +8491,19 @@
                 }
 
                 int parentUserId = getProfileParentId(userId);
-                if (!isSystemApp(mIPackageManager, packageName, parentUserId)) {
+                if (!isDemo && !isSystemApp(mIPackageManager, packageName, parentUserId)) {
                     throw new IllegalArgumentException("Only system apps can be enabled this way.");
                 }
 
                 // Install the app.
                 mIPackageManager.installExistingPackageAsUser(packageName, userId,
                         0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY);
-
+                if (isDemo) {
+                    // Ensure the app is also ENABLED for demo users.
+                    mIPackageManager.setApplicationEnabledSetting(packageName,
+                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+                            PackageManager.DONT_KILL_APP, userId, "DevicePolicyManager");
+                }
             } catch (RemoteException re) {
                 // shouldn't happen
                 Slog.wtf(LOG_TAG, "Failed to install " + packageName, re);
@@ -8905,7 +8948,8 @@
                 return;
             }
 
-            if (!GLOBAL_SETTINGS_WHITELIST.contains(setting)) {
+            if (!GLOBAL_SETTINGS_WHITELIST.contains(setting)
+                    && !UserManager.isDeviceInDemoMode(mContext)) {
                 throw new SecurityException(String.format(
                         "Permission denial: device owners cannot update %1$s", setting));
             }
@@ -8937,11 +8981,12 @@
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
             if (isDeviceOwner(who, callingUserId)) {
-                if (!SECURE_SETTINGS_DEVICEOWNER_WHITELIST.contains(setting)) {
+                if (!SECURE_SETTINGS_DEVICEOWNER_WHITELIST.contains(setting)
+                        && !isCurrentUserDemo()) {
                     throw new SecurityException(String.format(
                             "Permission denial: Device owners cannot update %1$s", setting));
                 }
-            } else if (!SECURE_SETTINGS_WHITELIST.contains(setting)) {
+            } else if (!SECURE_SETTINGS_WHITELIST.contains(setting) && !isCurrentUserDemo()) {
                 throw new SecurityException(String.format(
                         "Permission denial: Profile owners cannot update %1$s", setting));
             }
@@ -9392,12 +9437,6 @@
 
     @Override
     public SystemUpdatePolicy getSystemUpdatePolicy() {
-        if (UserManager.isDeviceInDemoMode(mContext)) {
-            // Pretending to have an automatic update policy when the device is in retail demo
-            // mode. This will allow the device to download and install an ota without
-            // any user interaction.
-            return SystemUpdatePolicy.createAutomaticInstallPolicy();
-        }
         synchronized (this) {
             SystemUpdatePolicy policy =  mOwners.getSystemUpdatePolicy();
             if (policy != null && !policy.isValid()) {
@@ -10404,6 +10443,19 @@
         }
     }
 
+    private boolean isCurrentUserDemo() {
+        if (UserManager.isDeviceInDemoMode(mContext)) {
+            final int userId = mInjector.userHandleGetCallingUserId();
+            final long callingIdentity = mInjector.binderClearCallingIdentity();
+            try {
+                return mUserManager.getUserInfo(userId).isDemo();
+            } finally {
+                mInjector.binderRestoreCallingIdentity(callingIdentity);
+            }
+        }
+        return false;
+    }
+
     private void removePackageIfRequired(final String packageName, final int userId) {
         if (!packageHasActiveAdmins(packageName, userId)) {
             // Will not do anything if uninstall was not requested or was already started.
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java
index 0085931..e097fac 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java
@@ -107,7 +107,8 @@
             return false;
         }
         try {
-           if (mIpConnectivityMetrics.registerNetdEventCallback(mNetdEventCallback)) {
+           if (mIpConnectivityMetrics.addNetdEventCallback(
+                    INetdEventCallback.CALLBACK_CALLER_DEVICE_POLICY, mNetdEventCallback)) {
                 mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND,
                         /* allowIo */ false);
                 mHandlerThread.start();
@@ -138,7 +139,8 @@
                 // logging is forcefully disabled even if unregistering fails
                 return true;
             }
-            return mIpConnectivityMetrics.unregisterNetdEventCallback();
+            return mIpConnectivityMetrics.removeNetdEventCallback(
+                    INetdEventCallback.CALLBACK_CALLER_DEVICE_POLICY);
         } catch (RemoteException re) {
             Slog.wtf(TAG, "Failed to make remote calls to unregister the callback", re);
             return true;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
index 70c7e58..6086354 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
@@ -25,8 +25,8 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.SystemClock;
-import android.util.Log;
 import android.util.LongSparseArray;
+import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -60,16 +60,21 @@
     /** Delay after which older batches get discarded after a retrieval. */
     private static final long RETRIEVED_BATCH_DISCARD_DELAY_MS = 5 * 60 * 1000; // 5m
 
+    /** Do not call into mDpm with locks held */
     private final DevicePolicyManagerService mDpm;
     private final AlarmManager mAlarmManager;
 
     private final OnAlarmListener mBatchTimeoutAlarmListener = new OnAlarmListener() {
         @Override
         public void onAlarm() {
-            Log.d(TAG, "Received a batch finalization timeout alarm, finalizing "
+            Slog.d(TAG, "Received a batch finalization timeout alarm, finalizing "
                     + mNetworkEvents.size() + " pending events.");
+            Bundle notificationExtras = null;
             synchronized (NetworkLoggingHandler.this) {
-                finalizeBatchAndNotifyDeviceOwnerLocked();
+                notificationExtras = finalizeBatchAndBuildDeviceOwnerMessageLocked();
+            }
+            if (notificationExtras != null) {
+                notifyDeviceOwner(notificationExtras);
             }
         }
     };
@@ -110,17 +115,21 @@
             case LOG_NETWORK_EVENT_MSG: {
                 final NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY);
                 if (networkEvent != null) {
+                    Bundle notificationExtras = null;
                     synchronized (NetworkLoggingHandler.this) {
                         mNetworkEvents.add(networkEvent);
                         if (mNetworkEvents.size() >= MAX_EVENTS_PER_BATCH) {
-                            finalizeBatchAndNotifyDeviceOwnerLocked();
+                            notificationExtras = finalizeBatchAndBuildDeviceOwnerMessageLocked();
                         }
                     }
+                    if (notificationExtras != null) {
+                        notifyDeviceOwner(notificationExtras);
+                    }
                 }
                 break;
             }
             default: {
-                Log.d(TAG, "NetworkLoggingHandler received an unknown of message.");
+                Slog.d(TAG, "NetworkLoggingHandler received an unknown of message.");
                 break;
             }
         }
@@ -133,40 +142,48 @@
         mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,
                 BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS, NETWORK_LOGGING_TIMEOUT_ALARM_TAG,
                 mBatchTimeoutAlarmListener, this);
-        Log.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS
+        Slog.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS
                 + "ms from now.");
     }
 
     synchronized void pause() {
-        Log.d(TAG, "Paused network logging");
+        Slog.d(TAG, "Paused network logging");
         mPaused = true;
     }
 
-    synchronized void resume() {
-        if (!mPaused) {
-            Log.d(TAG, "Attempted to resume network logging, but logging is not paused.");
-            return;
+    void resume() {
+        Bundle notificationExtras = null;
+        synchronized (this) {
+            if (!mPaused) {
+                Slog.d(TAG, "Attempted to resume network logging, but logging is not paused.");
+                return;
+            }
+
+            Slog.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken
+                    + ", LastRetrievedBatch=" + mLastRetrievedBatchToken);
+            mPaused = false;
+
+            // If there is a batch ready that the device owner hasn't been notified about, do it now.
+            if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) {
+                scheduleBatchFinalization();
+                notificationExtras = buildDeviceOwnerMessageLocked();
+            }
         }
-
-        Log.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken
-                + ", LastRetrievedBatch=" + mLastRetrievedBatchToken);
-        mPaused = false;
-
-        // If there is a batch ready that the device owner hasn't been notified about, do it now.
-        if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) {
-            scheduleBatchFinalization();
-            notifyDeviceOwnerLocked();
+        if (notificationExtras != null) {
+            notifyDeviceOwner(notificationExtras);
         }
     }
 
     synchronized void discardLogs() {
         mBatches.clear();
         mNetworkEvents = new ArrayList<>();
-        Log.d(TAG, "Discarded all network logs");
+        Slog.d(TAG, "Discarded all network logs");
     }
 
     @GuardedBy("this")
-    private void finalizeBatchAndNotifyDeviceOwnerLocked() {
+    /** @returns extras if a message should be sent to the device owner */
+    private Bundle finalizeBatchAndBuildDeviceOwnerMessageLocked() {
+        Bundle notificationExtras = null;
         if (mNetworkEvents.size() > 0) {
             // Finalize the batch and start a new one from scratch.
             if (mBatches.size() >= MAX_BATCHES) {
@@ -177,27 +194,39 @@
             mBatches.append(mCurrentBatchToken, mNetworkEvents);
             mNetworkEvents = new ArrayList<>();
             if (!mPaused) {
-                notifyDeviceOwnerLocked();
+                notificationExtras = buildDeviceOwnerMessageLocked();
             }
         } else {
             // Don't notify the DO, since there are no events; DPC can still retrieve
             // the last full batch if not paused.
-            Log.d(TAG, "Was about to finalize the batch, but there were no events to send to"
+            Slog.d(TAG, "Was about to finalize the batch, but there were no events to send to"
                     + " the DPC, the batchToken of last available batch: " + mCurrentBatchToken);
         }
         // Regardless of whether the batch was non-empty schedule a new finalization after timeout.
         scheduleBatchFinalization();
+        return notificationExtras;
     }
 
-    /** Sends a notification to the DO. Should only be called when there is a batch available. */
     @GuardedBy("this")
-    private void notifyDeviceOwnerLocked() {
+    /** Build extras notification to the DO. Should only be called when there
+        is a batch available. */
+    private Bundle buildDeviceOwnerMessageLocked() {
         final Bundle extras = new Bundle();
         final int lastBatchSize = mBatches.valueAt(mBatches.size() - 1).size();
         extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentBatchToken);
         extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, lastBatchSize);
-        Log.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: "
-                + mCurrentBatchToken);
+        return extras;
+    }
+
+    /** Sends a notification to the DO. Should not hold locks as DevicePolicyManagerService may
+        call into NetworkLoggingHandler. */
+    private void notifyDeviceOwner(Bundle extras) {
+        Slog.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: "
+                + extras.getLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, -1));
+        if (Thread.holdsLock(this)) {
+            Slog.wtfStack(TAG, "Shouldn't be called with NetworkLoggingHandler lock held");
+            return;
+        }
         mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras);
     }
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index f92f83a..d89f6d0 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -34,6 +34,7 @@
 import android.os.FileUtils;
 import android.os.IIncidentManager;
 import android.os.Looper;
+import android.os.Message;
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
@@ -62,6 +63,7 @@
 import com.android.server.am.ActivityManagerService;
 import com.android.server.audio.AudioService;
 import com.android.server.camera.CameraServiceProxy;
+import com.android.server.car.CarServiceHelperService;
 import com.android.server.clipboard.ClipboardService;
 import com.android.server.connectivity.IpConnectivityMetrics;
 import com.android.server.coverage.CoverageService;
@@ -82,6 +84,7 @@
 import com.android.server.net.NetworkPolicyManagerService;
 import com.android.server.net.NetworkStatsService;
 import com.android.server.notification.NotificationManagerService;
+import com.android.server.oemlock.OemLockService;
 import com.android.server.om.OverlayManagerService;
 import com.android.server.os.DeviceIdentifiersPolicyService;
 import com.android.server.os.SchedulingPolicyService;
@@ -95,8 +98,8 @@
 import com.android.server.policy.PhoneWindowManager;
 import com.android.server.power.PowerManagerService;
 import com.android.server.power.ShutdownThread;
+import com.android.server.radio.RadioService;
 import com.android.server.restrictions.RestrictionsManagerService;
-import com.android.server.retaildemo.RetailDemoModeService;
 import com.android.server.security.KeyAttestationApplicationIdProviderService;
 import com.android.server.security.KeyChainSystemService;
 import com.android.server.soundtrigger.SoundTriggerService;
@@ -173,7 +176,7 @@
     private static final String JOB_SCHEDULER_SERVICE_CLASS =
             "com.android.server.job.JobSchedulerService";
     private static final String LOCK_SETTINGS_SERVICE_CLASS =
-            "com.android.server.LockSettingsService$Lifecycle";
+            "com.android.server.locksettings.LockSettingsService$Lifecycle";
     private static final String STORAGE_MANAGER_SERVICE_CLASS =
             "com.android.server.StorageManagerService$Lifecycle";
     private static final String STORAGE_STATS_SERVICE_CLASS =
@@ -184,6 +187,8 @@
             "com.google.android.clockwork.ThermalObserver";
     private static final String WEAR_CONNECTIVITY_SERVICE_CLASS =
             "com.google.android.clockwork.connectivity.WearConnectivityService";
+    private static final String WEAR_DISPLAY_SERVICE_CLASS =
+            "com.google.android.clockwork.display.WearDisplayService";
     private static final String WEAR_TIME_SERVICE_CLASS =
             "com.google.android.clockwork.time.WearTimeService";
     private static final String ACCOUNT_SERVICE_CLASS =
@@ -455,7 +460,20 @@
                     }
                 }
             }
-            ShutdownThread.rebootOrShutdown(null, reboot, reason);
+            Runnable runnable = new Runnable() {
+                @Override
+                public void run() {
+                    synchronized (this) {
+                        ShutdownThread.rebootOrShutdown(null, reboot, reason);
+                    }
+                }
+            };
+
+            // ShutdownThread must run on a looper capable of displaying the UI.
+            Message msg = Message.obtain(UiThread.getHandler(), runnable);
+            msg.setAsynchronous(true);
+            UiThread.getHandler().sendMessage(msg);
+
         }
     }
 
@@ -660,6 +678,7 @@
         VibratorService vibrator = null;
         IStorageManager storageManager = null;
         NetworkManagementService networkManagement = null;
+        IpSecService ipSecService = null;
         NetworkStatsService networkStats = null;
         NetworkPolicyManagerService networkPolicy = null;
         ConnectivityService connectivity = null;
@@ -696,6 +715,8 @@
         boolean disableVrManager = SystemProperties.getBoolean("config.disable_vrmanager", false);
         boolean disableCameraService = SystemProperties.getBoolean("config.disable_cameraservice",
                 false);
+        // TODO(b/36863239): Remove when transitioned from native service.
+        boolean enableRadioService = SystemProperties.getBoolean("config.enable_java_radio", false);
 
         boolean isEmulator = SystemProperties.get("ro.kernel.qemu").equals("1");
 
@@ -753,13 +774,6 @@
 
             mContentResolver = context.getContentResolver();
 
-            if (!disableCameraService) {
-                Slog.i(TAG, "Camera Service Proxy");
-                traceBeginAndSlog("StartCameraServiceProxy");
-                mSystemServiceManager.startService(CameraServiceProxy.class);
-                traceEnd();
-            }
-
             // The AccountManager must come before the ContentService
             traceBeginAndSlog("StartAccountManagerService");
             mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS);
@@ -962,12 +976,15 @@
                 }
                 traceEnd();
 
-                if (!SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("")) {
+                final boolean hasPdb = !SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("");
+                if (hasPdb) {
                     traceBeginAndSlog("StartPersistentDataBlock");
                     mSystemServiceManager.startService(PersistentDataBlockService.class);
                     traceEnd();
+                }
 
-                    // Implementation depends on persistent data block
+                if (hasPdb || OemLockService.isHalPresent()) {
+                    // Implementation depends on pdb or the OemLock HAL
                     traceBeginAndSlog("StartOemLockService");
                     mSystemServiceManager.startService(OemLockService.class);
                     traceEnd();
@@ -1010,6 +1027,15 @@
                     reportWtf("starting NetworkManagement Service", e);
                 }
                 traceEnd();
+
+                traceBeginAndSlog("StartIpSecService");
+                try {
+                    ipSecService = IpSecService.create(context);
+                    ServiceManager.addService(Context.IPSEC_SERVICE, ipSecService);
+                } catch (Throwable e) {
+                    reportWtf("starting IpSec Service", e);
+                }
+                traceEnd();
             }
 
             if (!disableNonCoreServices && !disableTextServices) {
@@ -1182,22 +1208,17 @@
                 traceEnd();
             }
 
-            // timezone.RulesManagerService will prevent a device starting up if the chain of trust
-            // required for safe time zone updates might be broken. RuleManagerService cannot do
-            // this check when mOnlyCore == true, so we don't enable the service in this case.
-            final boolean startRulesManagerService =
-                    !mOnlyCore && context.getResources().getBoolean(
-                            R.bool.config_enableUpdateableTimeZoneRules);
-            if (startRulesManagerService) {
-                traceBeginAndSlog("StartTimeZoneRulesManagerService");
-                mSystemServiceManager.startService(TIME_ZONE_RULES_MANAGER_SERVICE_CLASS);
-                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
-            }
-
             traceBeginAndSlog("StartAudioService");
             mSystemServiceManager.startService(AudioService.Lifecycle.class);
             traceEnd();
 
+            if (enableRadioService &&
+                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_RADIO)) {
+                traceBeginAndSlog("StartRadioService");
+                mSystemServiceManager.startService(RadioService.class);
+                traceEnd();
+            }
+
             if (!disableNonCoreServices) {
                 traceBeginAndSlog("StartDockObserver");
                 mSystemServiceManager.startService(DockObserver.class);
@@ -1326,6 +1347,19 @@
             }
             traceEnd();
 
+            // timezone.RulesManagerService will prevent a device starting up if the chain of trust
+            // required for safe time zone updates might be broken. RuleManagerService cannot do
+            // this check when mOnlyCore == true, so we don't enable the service in this case.
+            // This service requires that JobSchedulerService is already started when it starts.
+            final boolean startRulesManagerService =
+                    !mOnlyCore && context.getResources().getBoolean(
+                            R.bool.config_enableUpdateableTimeZoneRules);
+            if (startRulesManagerService) {
+                traceBeginAndSlog("StartTimeZoneRulesManagerService");
+                mSystemServiceManager.startService(TIME_ZONE_RULES_MANAGER_SERVICE_CLASS);
+                traceEnd();
+            }
+
             if (!disableNetwork && !disableNetworkTime) {
                 traceBeginAndSlog("StartNetworkTimeUpdateService");
                 try {
@@ -1483,11 +1517,18 @@
 
             if (!disableNonCoreServices) {
                 traceBeginAndSlog("StartWearTimeService");
+                mSystemServiceManager.startService(WEAR_DISPLAY_SERVICE_CLASS);
                 mSystemServiceManager.startService(WEAR_TIME_SERVICE_CLASS);
                 traceEnd();
             }
         }
 
+        if (!disableCameraService) {
+            traceBeginAndSlog("StartCameraServiceProxy");
+            mSystemServiceManager.startService(CameraServiceProxy.class);
+            traceEnd();
+        }
+
         // Before things start rolling, be sure we have decided whether
         // we are in safe mode.
         final boolean safeMode = wm.detectSafeMode();
@@ -1509,10 +1550,6 @@
         mmsService = mSystemServiceManager.startService(MmsServiceBroker.class);
         traceEnd();
 
-        traceBeginAndSlog("StartRetailDemoModeService");
-        mSystemServiceManager.startService(RetailDemoModeService.class);
-        traceEnd();
-
         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOFILL)) {
             traceBeginAndSlog("StartAutoFillService");
             mSystemServiceManager.startService(AUTO_FILL_MANAGER_SERVICE_CLASS);
@@ -1617,6 +1654,7 @@
         final TelephonyRegistry telephonyRegistryF = telephonyRegistry;
         final MediaRouterService mediaRouterF = mediaRouter;
         final MmsServiceBroker mmsServiceF = mmsService;
+        final IpSecService ipSecServiceF = ipSecService;
         final WindowManagerService windowManagerF = wm;
 
         // We now tell the activity manager it is okay to run third party
@@ -1655,6 +1693,12 @@
                 }, WEBVIEW_PREPARATION);
             }
 
+            if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+                traceBeginAndSlog("StartCarServiceHelperService");
+                mSystemServiceManager.startService(CarServiceHelperService.class);
+                traceEnd();
+            }
+
             traceBeginAndSlog("StartSystemUI");
             try {
                 startSystemUi(context, windowManagerF);
@@ -1681,6 +1725,13 @@
                         .networkScoreAndNetworkManagementServiceReady();
             }
             traceEnd();
+            traceBeginAndSlog("MakeIpSecServiceReady");
+            try {
+                if (ipSecServiceF != null) ipSecServiceF.systemReady();
+            } catch (Throwable e) {
+                reportWtf("making IpSec Service ready", e);
+            }
+            traceEnd();
             traceBeginAndSlog("MakeNetworkStatsServiceReady");
             try {
                 if (networkStatsF != null) networkStatsF.systemReady();
diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java
index 100e459..51478b3 100644
--- a/services/midi/java/com/android/server/midi/MidiService.java
+++ b/services/midi/java/com/android/server/midi/MidiService.java
@@ -325,9 +325,6 @@
                 }
                 IBinder binder = server.asBinder();
                 try {
-                    if (mDeviceInfo == null) {
-                        mDeviceInfo = server.getDeviceInfo();
-                    }
                     binder.linkToDeath(this, 0);
                     mServer = server;
                 } catch (RemoteException e) {
diff --git a/services/net/java/android/net/apf/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java
index 8cb2df7..31a1abb 100644
--- a/services/net/java/android/net/apf/ApfFilter.java
+++ b/services/net/java/android/net/apf/ApfFilter.java
@@ -33,7 +33,7 @@
 import android.net.apf.ApfGenerator;
 import android.net.apf.ApfGenerator.IllegalInstructionException;
 import android.net.apf.ApfGenerator.Register;
-import android.net.ip.IpManager;
+import android.net.ip.IpClient;
 import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.ApfStats;
 import android.net.metrics.IpConnectivityLog;
@@ -86,6 +86,14 @@
  */
 public class ApfFilter {
 
+    // Helper class for specifying functional filter parameters.
+    public static class ApfConfiguration {
+        public ApfCapabilities apfCapabilities;
+        public boolean multicastFilter;
+        public boolean ieee802_3Filter;
+        public int[] ethTypeBlackList;
+    }
+
     // Enums describing the outcome of receiving an RA packet.
     private static enum ProcessRaResult {
         MATCH,          // Received RA matched a known RA
@@ -180,6 +188,7 @@
     private static final int ETH_DEST_ADDR_OFFSET = 0;
     private static final int ETH_ETHERTYPE_OFFSET = 12;
     private static final int ETH_TYPE_MIN = 0x0600;
+    private static final int ETH_TYPE_MAX = 0xFFFF;
     private static final byte[] ETH_BROADCAST_MAC_ADDRESS =
             {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
     // TODO: Make these offsets relative to end of link-layer header; don't include ETH_HEADER_LEN.
@@ -232,9 +241,12 @@
     private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24;
     // Do not log ApfProgramEvents whose actual lifetimes was less than this.
     private static final int APF_PROGRAM_EVENT_LIFETIME_THRESHOLD = 2;
+    // Limit on the Black List size to cap on program usage for this
+    // TODO: Select a proper max length
+    private static final int APF_MAX_ETH_TYPE_BLACK_LIST_LEN = 20;
 
     private final ApfCapabilities mApfCapabilities;
-    private final IpManager.Callback mIpManagerCallback;
+    private final IpClient.Callback mIpClientCallback;
     private final NetworkInterface mNetworkInterface;
     private final IpConnectivityLog mMetricsLog;
 
@@ -247,6 +259,8 @@
     @GuardedBy("this")
     private boolean mMulticastFilter;
     private final boolean mDrop802_3Frames;
+    private final int[] mEthTypeBlackList;
+
     // Our IPv4 address, if we have just one, otherwise null.
     @GuardedBy("this")
     private byte[] mIPv4Address;
@@ -255,17 +269,20 @@
     private int mIPv4PrefixLength;
 
     @VisibleForTesting
-    ApfFilter(ApfCapabilities apfCapabilities, NetworkInterface networkInterface,
-            IpManager.Callback ipManagerCallback, boolean multicastFilter,
-            boolean ieee802_3Filter, IpConnectivityLog log) {
-        mApfCapabilities = apfCapabilities;
-        mIpManagerCallback = ipManagerCallback;
+    ApfFilter(ApfConfiguration config, NetworkInterface networkInterface,
+            IpClient.Callback ipClientCallback, IpConnectivityLog log) {
+        mApfCapabilities = config.apfCapabilities;
+        mIpClientCallback = ipClientCallback;
         mNetworkInterface = networkInterface;
-        mMulticastFilter = multicastFilter;
-        mDrop802_3Frames = ieee802_3Filter;
+        mMulticastFilter = config.multicastFilter;
+        mDrop802_3Frames = config.ieee802_3Filter;
+
+        // Now fill the black list from the passed array
+        mEthTypeBlackList = filterEthTypeBlackList(config.ethTypeBlackList);
+
         mMetricsLog = log;
 
-        // TODO: ApfFilter should not generate programs until IpManager sends provisioning success.
+        // TODO: ApfFilter should not generate programs until IpClient sends provisioning success.
         maybeStartFilter();
     }
 
@@ -278,6 +295,35 @@
         return mUniqueCounter++;
     }
 
+    @GuardedBy("this")
+    private static int[] filterEthTypeBlackList(int[] ethTypeBlackList) {
+        ArrayList<Integer> bl = new ArrayList<Integer>();
+
+        for (int p : ethTypeBlackList) {
+            // Check if the protocol is a valid ether type
+            if ((p < ETH_TYPE_MIN) || (p > ETH_TYPE_MAX)) {
+                continue;
+            }
+
+            // Check if the protocol is not repeated in the passed array
+            if (bl.contains(p)) {
+                continue;
+            }
+
+            // Check if list reach its max size
+            if (bl.size() == APF_MAX_ETH_TYPE_BLACK_LIST_LEN) {
+                Log.w(TAG, "Passed EthType Black List size too large (" + bl.size() +
+                        ") using top " + APF_MAX_ETH_TYPE_BLACK_LIST_LEN + " protocols");
+                break;
+            }
+
+            // Now add the protocol to the list
+            bl.add(p);
+        }
+
+        return bl.stream().mapToInt(Integer::intValue).toArray();
+    }
+
     /**
      * Attempt to start listening for RAs and, if RAs are received, generating and installing
      * filters to ignore useless RAs.
@@ -891,6 +937,7 @@
      * Begin generating an APF program to:
      * <ul>
      * <li>Drop/Pass 802.3 frames (based on policy)
+     * <li>Drop packets with EtherType within the Black List
      * <li>Drop ARP requests not for us, if mIPv4Address is set,
      * <li>Drop IPv4 broadcast packets, except DHCP destined to our MAC,
      * <li>Drop IPv4 multicast packets, if mMulticastFilter,
@@ -914,6 +961,8 @@
         //
         // if it's a 802.3 Frame (ethtype < 0x0600):
         //    drop or pass based on configurations
+        // if it has a ether-type that belongs to the black list
+        //    drop
         // if it's ARP:
         //   insert ARP filter to drop or pass these appropriately
         // if it's IPv4:
@@ -931,6 +980,11 @@
             gen.addJumpIfR0LessThan(ETH_TYPE_MIN, gen.DROP_LABEL);
         }
 
+        // Handle ether-type black list
+        for (int p : mEthTypeBlackList) {
+            gen.addJumpIfR0Equals(p, gen.DROP_LABEL);
+        }
+
         // Add ARP filters:
         String skipArpFiltersLabel = "skipArpFilters";
         gen.addJumpIfR0NotEquals(ETH_P_ARP, skipArpFiltersLabel);
@@ -1004,7 +1058,7 @@
         if (VDBG) {
             hexDump("Installing filter: ", program, program.length);
         }
-        mIpManagerCallback.installPacketFilter(program);
+        mIpClientCallback.installPacketFilter(program);
         logApfProgramEventLocked(now);
         mLastInstallEvent = new ApfProgramEvent();
         mLastInstallEvent.lifetime = programMinLifetime;
@@ -1113,9 +1167,10 @@
      * Create an {@link ApfFilter} if {@code apfCapabilities} indicates support for packet
      * filtering using APF programs.
      */
-    public static ApfFilter maybeCreate(ApfCapabilities apfCapabilities,
-            NetworkInterface networkInterface, IpManager.Callback ipManagerCallback,
-            boolean multicastFilter, boolean ieee802_3Filter) {
+    public static ApfFilter maybeCreate(ApfConfiguration config,
+            NetworkInterface networkInterface, IpClient.Callback ipClientCallback) {
+        if (config == null) return null;
+        ApfCapabilities apfCapabilities =  config.apfCapabilities;
         if (apfCapabilities == null || networkInterface == null) return null;
         if (apfCapabilities.apfVersionSupported == 0) return null;
         if (apfCapabilities.maximumApfProgramSize < 512) {
@@ -1131,8 +1186,7 @@
             Log.e(TAG, "Unsupported APF version: " + apfCapabilities.apfVersionSupported);
             return null;
         }
-        return new ApfFilter(apfCapabilities, networkInterface, ipManagerCallback,
-                multicastFilter, ieee802_3Filter, new IpConnectivityLog());
+        return new ApfFilter(config, networkInterface, ipClientCallback, new IpConnectivityLog());
     }
 
     public synchronized void shutdown() {
diff --git a/services/net/java/android/net/ip/ConnectivityPacketTracker.java b/services/net/java/android/net/ip/ConnectivityPacketTracker.java
index 884a8a7..1925c39 100644
--- a/services/net/java/android/net/ip/ConnectivityPacketTracker.java
+++ b/services/net/java/android/net/ip/ConnectivityPacketTracker.java
@@ -25,6 +25,7 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.PacketSocketAddress;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.LocalLog;
 
@@ -59,13 +60,16 @@
     private static final boolean DBG = false;
     private static final String MARK_START = "--- START ---";
     private static final String MARK_STOP = "--- STOP ---";
+    private static final String MARK_NAMED_START = "--- START (%s) ---";
+    private static final String MARK_NAMED_STOP = "--- STOP (%s) ---";
 
     private final String mTag;
-    private final Handler mHandler;
     private final LocalLog mLog;
     private final BlockingSocketReader mPacketListener;
+    private boolean mRunning;
+    private String mDisplayName;
 
-    public ConnectivityPacketTracker(NetworkInterface netif, LocalLog log) {
+    public ConnectivityPacketTracker(Handler h, NetworkInterface netif, LocalLog log) {
         final String ifname;
         final int ifindex;
         final byte[] hwaddr;
@@ -81,44 +85,42 @@
         }
 
         mTag = TAG + "." + ifname;
-        mHandler = new Handler();
         mLog = log;
-        mPacketListener = new PacketListener(ifindex, hwaddr, mtu);
+        mPacketListener = new PacketListener(h, ifindex, hwaddr, mtu);
     }
 
-    public void start() {
-        mLog.log(MARK_START);
+    public void start(String displayName) {
+        mRunning = true;
+        mDisplayName = displayName;
         mPacketListener.start();
     }
 
     public void stop() {
         mPacketListener.stop();
-        mLog.log(MARK_STOP);
+        mRunning = false;
+        mDisplayName = null;
     }
 
     private final class PacketListener extends BlockingSocketReader {
         private final int mIfIndex;
         private final byte mHwAddr[];
 
-        PacketListener(int ifindex, byte[] hwaddr, int mtu) {
-            super(mtu);
+        PacketListener(Handler h, int ifindex, byte[] hwaddr, int mtu) {
+            super(h, mtu);
             mIfIndex = ifindex;
             mHwAddr = hwaddr;
         }
 
         @Override
-        protected FileDescriptor createSocket() {
+        protected FileDescriptor createFd() {
             FileDescriptor s = null;
             try {
-                // TODO: Evaluate switching to SOCK_DGRAM and changing the
-                // BlockingSocketReader's read() to recvfrom(), so that this
-                // might work on non-ethernet-like links (via SLL).
                 s = Os.socket(AF_PACKET, SOCK_RAW, 0);
                 NetworkUtils.attachControlPacketFilter(s, ARPHRD_ETHER);
                 Os.bind(s, new PacketSocketAddress((short) ETH_P_ALL, mIfIndex));
             } catch (ErrnoException | IOException e) {
                 logError("Failed to create packet tracking socket: ", e);
-                closeSocket(s);
+                closeFd(s);
                 return null;
             }
             return s;
@@ -136,13 +138,30 @@
         }
 
         @Override
+        protected void onStart() {
+            final String msg = TextUtils.isEmpty(mDisplayName)
+                    ? MARK_START
+                    : String.format(MARK_NAMED_START, mDisplayName);
+            mLog.log(msg);
+        }
+
+        @Override
+        protected void onStop() {
+            String msg = TextUtils.isEmpty(mDisplayName)
+                    ? MARK_STOP
+                    : String.format(MARK_NAMED_STOP, mDisplayName);
+            if (!mRunning) msg += " (packet listener stopped unexpectedly)";
+            mLog.log(msg);
+        }
+
+        @Override
         protected void logError(String msg, Exception e) {
             Log.e(mTag, msg, e);
             addLogEntry(msg + e);
         }
 
         private void addLogEntry(String entry) {
-            mHandler.post(() -> mLog.log(entry));
+            mLog.log(entry);
         }
     }
 }
diff --git a/services/net/java/android/net/ip/InterfaceController.java b/services/net/java/android/net/ip/InterfaceController.java
new file mode 100644
index 0000000..02e4f87
--- /dev/null
+++ b/services/net/java/android/net/ip/InterfaceController.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ip;
+
+import android.net.INetd;
+import android.net.InterfaceConfiguration;
+import android.net.LinkAddress;
+import android.net.util.NetdService;
+import android.net.util.SharedLog;
+import android.os.INetworkManagementService;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.system.OsConstants;
+
+import java.net.InetAddress;
+
+
+/**
+ * Encapsulates the multiple IP configuration operations performed on an interface.
+ *
+ * TODO: refactor/eliminate the redundant ways to set and clear addresses.
+ *
+ * @hide
+ */
+public class InterfaceController {
+    private final static boolean DBG = false;
+
+    private final String mIfName;
+    private final INetworkManagementService mNMS;
+    private final INetd mNetd;
+    private final SharedLog mLog;
+
+    public InterfaceController(String ifname, INetworkManagementService nms, INetd netd,
+            SharedLog log) {
+        mIfName = ifname;
+        mNMS = nms;
+        mNetd = netd;
+        mLog = log;
+    }
+
+    public boolean setIPv4Address(LinkAddress address) {
+        final InterfaceConfiguration ifcg = new InterfaceConfiguration();
+        ifcg.setLinkAddress(address);
+        try {
+            mNMS.setInterfaceConfig(mIfName, ifcg);
+            if (DBG) mLog.log("IPv4 configuration succeeded");
+        } catch (IllegalStateException | RemoteException e) {
+            logError("IPv4 configuration failed: %s", e);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean clearIPv4Address() {
+        try {
+            final InterfaceConfiguration ifcg = new InterfaceConfiguration();
+            ifcg.setLinkAddress(new LinkAddress("0.0.0.0/0"));
+            mNMS.setInterfaceConfig(mIfName, ifcg);
+        } catch (IllegalStateException | RemoteException e) {
+            logError("Failed to clear IPv4 address on interface %s: %s", mIfName, e);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean enableIPv6() {
+        try {
+            mNMS.enableIpv6(mIfName);
+        } catch (IllegalStateException | RemoteException e) {
+            logError("enabling IPv6 failed: %s", e);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean disableIPv6() {
+        try {
+            mNMS.disableIpv6(mIfName);
+        } catch (IllegalStateException | RemoteException e) {
+            logError("disabling IPv6 failed: %s", e);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean setIPv6PrivacyExtensions(boolean enabled) {
+        try {
+            mNMS.setInterfaceIpv6PrivacyExtensions(mIfName, enabled);
+        } catch (IllegalStateException | RemoteException e) {
+            logError("error setting IPv6 privacy extensions: %s", e);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean setIPv6AddrGenModeIfSupported(int mode) {
+        try {
+            mNMS.setIPv6AddrGenMode(mIfName, mode);
+        } catch (RemoteException e) {
+            logError("Unable to set IPv6 addrgen mode: %s", e);
+            return false;
+        } catch (ServiceSpecificException e) {
+            if (e.errorCode != OsConstants.EOPNOTSUPP) {
+                logError("Unable to set IPv6 addrgen mode: %s", e);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public boolean addAddress(LinkAddress addr) {
+        return addAddress(addr.getAddress(), addr.getPrefixLength());
+    }
+
+    public boolean addAddress(InetAddress ip, int prefixLen) {
+        try {
+            mNetd.interfaceAddAddress(mIfName, ip.getHostAddress(), prefixLen);
+        } catch (ServiceSpecificException | RemoteException e) {
+            logError("failed to add %s/%d: %s", ip, prefixLen, e);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean removeAddress(InetAddress ip, int prefixLen) {
+        try {
+            mNetd.interfaceDelAddress(mIfName, ip.getHostAddress(), prefixLen);
+        } catch (ServiceSpecificException | RemoteException e) {
+            logError("failed to remove %s/%d: %s", ip, prefixLen, e);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean clearAllAddresses() {
+        try {
+            mNMS.clearInterfaceAddresses(mIfName);
+        } catch (Exception e) {
+            logError("Failed to clear addresses: %s", e);
+            return false;
+        }
+        return true;
+    }
+
+    private void logError(String fmt, Object... args) {
+        mLog.e(String.format(fmt, args));
+    }
+}
diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java
new file mode 100644
index 0000000..70983c8
--- /dev/null
+++ b/services/net/java/android/net/ip/IpClient.java
@@ -0,0 +1,1712 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ip;
+
+import com.android.internal.util.MessageUtils;
+import com.android.internal.util.WakeupMessage;
+
+import android.content.Context;
+import android.net.DhcpResults;
+import android.net.INetd;
+import android.net.IpPrefix;
+import android.net.LinkAddress;
+import android.net.LinkProperties.ProvisioningChange;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.ProxyInfo;
+import android.net.RouteInfo;
+import android.net.StaticIpConfiguration;
+import android.net.apf.ApfCapabilities;
+import android.net.apf.ApfFilter;
+import android.net.dhcp.DhcpClient;
+import android.net.metrics.IpConnectivityLog;
+import android.net.metrics.IpManagerEvent;
+import android.net.util.MultinetworkPolicyTracker;
+import android.net.util.NetdService;
+import android.net.util.NetworkConstants;
+import android.net.util.SharedLog;
+import android.os.INetworkManagementService;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.LocalLog;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.R;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.IState;
+import com.android.internal.util.Preconditions;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+import com.android.server.net.NetlinkTracker;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.List;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+
+/**
+ * IpClient
+ *
+ * This class provides the interface to IP-layer provisioning and maintenance
+ * functionality that can be used by transport layers like Wi-Fi, Ethernet,
+ * et cetera.
+ *
+ * [ Lifetime ]
+ * IpClient is designed to be instantiated as soon as the interface name is
+ * known and can be as long-lived as the class containing it (i.e. declaring
+ * it "private final" is okay).
+ *
+ * @hide
+ */
+public class IpClient extends StateMachine {
+    private static final boolean DBG = false;
+
+    // For message logging.
+    private static final Class[] sMessageClasses = { IpClient.class, DhcpClient.class };
+    private static final SparseArray<String> sWhatToString =
+            MessageUtils.findMessageNames(sMessageClasses);
+
+    /**
+     * Callbacks for handling IpClient events.
+     */
+    public static class Callback {
+        // In order to receive onPreDhcpAction(), call #withPreDhcpAction()
+        // when constructing a ProvisioningConfiguration.
+        //
+        // Implementations of onPreDhcpAction() must call
+        // IpClient#completedPreDhcpAction() to indicate that DHCP is clear
+        // to proceed.
+        public void onPreDhcpAction() {}
+        public void onPostDhcpAction() {}
+
+        // This is purely advisory and not an indication of provisioning
+        // success or failure.  This is only here for callers that want to
+        // expose DHCPv4 results to other APIs (e.g., WifiInfo#setInetAddress).
+        // DHCPv4 or static IPv4 configuration failure or success can be
+        // determined by whether or not the passed-in DhcpResults object is
+        // null or not.
+        public void onNewDhcpResults(DhcpResults dhcpResults) {}
+
+        public void onProvisioningSuccess(LinkProperties newLp) {}
+        public void onProvisioningFailure(LinkProperties newLp) {}
+
+        // Invoked on LinkProperties changes.
+        public void onLinkPropertiesChange(LinkProperties newLp) {}
+
+        // Called when the internal IpReachabilityMonitor (if enabled) has
+        // detected the loss of a critical number of required neighbors.
+        public void onReachabilityLost(String logMsg) {}
+
+        // Called when the IpClient state machine terminates.
+        public void onQuit() {}
+
+        // Install an APF program to filter incoming packets.
+        public void installPacketFilter(byte[] filter) {}
+
+        // If multicast filtering cannot be accomplished with APF, this function will be called to
+        // actuate multicast filtering using another means.
+        public void setFallbackMulticastFilter(boolean enabled) {}
+
+        // Enabled/disable Neighbor Discover offload functionality. This is
+        // called, for example, whenever 464xlat is being started or stopped.
+        public void setNeighborDiscoveryOffload(boolean enable) {}
+    }
+
+    // Use a wrapper class to log in order to ensure complete and detailed
+    // logging. This method is lighter weight than annotations/reflection
+    // and has the following benefits:
+    //
+    //     - No invoked method can be forgotten.
+    //       Any new method added to IpClient.Callback must be overridden
+    //       here or it will never be called.
+    //
+    //     - No invoking call site can be forgotten.
+    //       Centralized logging in this way means call sites don't need to
+    //       remember to log, and therefore no call site can be forgotten.
+    //
+    //     - No variation in log format among call sites.
+    //       Encourages logging of any available arguments, and all call sites
+    //       are necessarily logged identically.
+    //
+    // TODO: Find an lighter weight approach.
+    private class LoggingCallbackWrapper extends Callback {
+        private static final String PREFIX = "INVOKE ";
+        private Callback mCallback;
+
+        public LoggingCallbackWrapper(Callback callback) {
+            mCallback = callback;
+        }
+
+        private void log(String msg) {
+            mLog.log(PREFIX + msg);
+        }
+
+        @Override
+        public void onPreDhcpAction() {
+            mCallback.onPreDhcpAction();
+            log("onPreDhcpAction()");
+        }
+        @Override
+        public void onPostDhcpAction() {
+            mCallback.onPostDhcpAction();
+            log("onPostDhcpAction()");
+        }
+        @Override
+        public void onNewDhcpResults(DhcpResults dhcpResults) {
+            mCallback.onNewDhcpResults(dhcpResults);
+            log("onNewDhcpResults({" + dhcpResults + "})");
+        }
+        @Override
+        public void onProvisioningSuccess(LinkProperties newLp) {
+            mCallback.onProvisioningSuccess(newLp);
+            log("onProvisioningSuccess({" + newLp + "})");
+        }
+        @Override
+        public void onProvisioningFailure(LinkProperties newLp) {
+            mCallback.onProvisioningFailure(newLp);
+            log("onProvisioningFailure({" + newLp + "})");
+        }
+        @Override
+        public void onLinkPropertiesChange(LinkProperties newLp) {
+            mCallback.onLinkPropertiesChange(newLp);
+            log("onLinkPropertiesChange({" + newLp + "})");
+        }
+        @Override
+        public void onReachabilityLost(String logMsg) {
+            mCallback.onReachabilityLost(logMsg);
+            log("onReachabilityLost(" + logMsg + ")");
+        }
+        @Override
+        public void onQuit() {
+            mCallback.onQuit();
+            log("onQuit()");
+        }
+        @Override
+        public void installPacketFilter(byte[] filter) {
+            mCallback.installPacketFilter(filter);
+            log("installPacketFilter(byte[" + filter.length + "])");
+        }
+        @Override
+        public void setFallbackMulticastFilter(boolean enabled) {
+            mCallback.setFallbackMulticastFilter(enabled);
+            log("setFallbackMulticastFilter(" + enabled + ")");
+        }
+        @Override
+        public void setNeighborDiscoveryOffload(boolean enable) {
+            mCallback.setNeighborDiscoveryOffload(enable);
+            log("setNeighborDiscoveryOffload(" + enable + ")");
+        }
+    }
+
+    /**
+     * This class encapsulates parameters to be passed to
+     * IpClient#startProvisioning(). A defensive copy is made by IpClient
+     * and the values specified herein are in force until IpClient#stop()
+     * is called.
+     *
+     * Example use:
+     *
+     *     final ProvisioningConfiguration config =
+     *             mIpClient.buildProvisioningConfiguration()
+     *                     .withPreDhcpAction()
+     *                     .withProvisioningTimeoutMs(36 * 1000)
+     *                     .build();
+     *     mIpClient.startProvisioning(config);
+     *     ...
+     *     mIpClient.stop();
+     *
+     * The specified provisioning configuration will only be active until
+     * IpClient#stop() is called. Future calls to IpClient#startProvisioning()
+     * must specify the configuration again.
+     */
+    public static class ProvisioningConfiguration {
+        // TODO: Delete this default timeout once those callers that care are
+        // fixed to pass in their preferred timeout.
+        //
+        // We pick 36 seconds so we can send DHCP requests at
+        //
+        //     t=0, t=2, t=6, t=14, t=30
+        //
+        // allowing for 10% jitter.
+        private static final int DEFAULT_TIMEOUT_MS = 36 * 1000;
+
+        public static class Builder {
+            private ProvisioningConfiguration mConfig = new ProvisioningConfiguration();
+
+            public Builder withoutIPv4() {
+                mConfig.mEnableIPv4 = false;
+                return this;
+            }
+
+            public Builder withoutIPv6() {
+                mConfig.mEnableIPv6 = false;
+                return this;
+            }
+
+            public Builder withoutIpReachabilityMonitor() {
+                mConfig.mUsingIpReachabilityMonitor = false;
+                return this;
+            }
+
+            public Builder withPreDhcpAction() {
+                mConfig.mRequestedPreDhcpActionMs = DEFAULT_TIMEOUT_MS;
+                return this;
+            }
+
+            public Builder withPreDhcpAction(int dhcpActionTimeoutMs) {
+                mConfig.mRequestedPreDhcpActionMs = dhcpActionTimeoutMs;
+                return this;
+            }
+
+            public Builder withInitialConfiguration(InitialConfiguration initialConfig) {
+                mConfig.mInitialConfig = initialConfig;
+                return this;
+            }
+
+            public Builder withStaticConfiguration(StaticIpConfiguration staticConfig) {
+                mConfig.mStaticIpConfig = staticConfig;
+                return this;
+            }
+
+            public Builder withApfCapabilities(ApfCapabilities apfCapabilities) {
+                mConfig.mApfCapabilities = apfCapabilities;
+                return this;
+            }
+
+            public Builder withProvisioningTimeoutMs(int timeoutMs) {
+                mConfig.mProvisioningTimeoutMs = timeoutMs;
+                return this;
+            }
+
+            public Builder withRandomMacAddress() {
+                mConfig.mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_EUI64;
+                return this;
+            }
+
+            public Builder withStableMacAddress() {
+                mConfig.mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_STABLE_PRIVACY;
+                return this;
+            }
+
+            public Builder withNetwork(Network network) {
+                mConfig.mNetwork = network;
+                return this;
+            }
+
+            public Builder withDisplayName(String displayName) {
+                mConfig.mDisplayName = displayName;
+                return this;
+            }
+
+            public ProvisioningConfiguration build() {
+                return new ProvisioningConfiguration(mConfig);
+            }
+        }
+
+        /* package */ boolean mEnableIPv4 = true;
+        /* package */ boolean mEnableIPv6 = true;
+        /* package */ boolean mUsingIpReachabilityMonitor = true;
+        /* package */ int mRequestedPreDhcpActionMs;
+        /* package */ InitialConfiguration mInitialConfig;
+        /* package */ StaticIpConfiguration mStaticIpConfig;
+        /* package */ ApfCapabilities mApfCapabilities;
+        /* package */ int mProvisioningTimeoutMs = DEFAULT_TIMEOUT_MS;
+        /* package */ int mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_STABLE_PRIVACY;
+        /* package */ Network mNetwork = null;
+        /* package */ String mDisplayName = null;
+
+        public ProvisioningConfiguration() {} // used by Builder
+
+        public ProvisioningConfiguration(ProvisioningConfiguration other) {
+            mEnableIPv4 = other.mEnableIPv4;
+            mEnableIPv6 = other.mEnableIPv6;
+            mUsingIpReachabilityMonitor = other.mUsingIpReachabilityMonitor;
+            mRequestedPreDhcpActionMs = other.mRequestedPreDhcpActionMs;
+            mInitialConfig = InitialConfiguration.copy(other.mInitialConfig);
+            mStaticIpConfig = other.mStaticIpConfig;
+            mApfCapabilities = other.mApfCapabilities;
+            mProvisioningTimeoutMs = other.mProvisioningTimeoutMs;
+            mIPv6AddrGenMode = other.mIPv6AddrGenMode;
+            mNetwork = other.mNetwork;
+            mDisplayName = other.mDisplayName;
+        }
+
+        @Override
+        public String toString() {
+            return new StringJoiner(", ", getClass().getSimpleName() + "{", "}")
+                    .add("mEnableIPv4: " + mEnableIPv4)
+                    .add("mEnableIPv6: " + mEnableIPv6)
+                    .add("mUsingIpReachabilityMonitor: " + mUsingIpReachabilityMonitor)
+                    .add("mRequestedPreDhcpActionMs: " + mRequestedPreDhcpActionMs)
+                    .add("mInitialConfig: " + mInitialConfig)
+                    .add("mStaticIpConfig: " + mStaticIpConfig)
+                    .add("mApfCapabilities: " + mApfCapabilities)
+                    .add("mProvisioningTimeoutMs: " + mProvisioningTimeoutMs)
+                    .add("mIPv6AddrGenMode: " + mIPv6AddrGenMode)
+                    .add("mNetwork: " + mNetwork)
+                    .add("mDisplayName: " + mDisplayName)
+                    .toString();
+        }
+
+        public boolean isValid() {
+            return (mInitialConfig == null) || mInitialConfig.isValid();
+        }
+    }
+
+    public static class InitialConfiguration {
+        public final Set<LinkAddress> ipAddresses = new HashSet<>();
+        public final Set<IpPrefix> directlyConnectedRoutes = new HashSet<>();
+        public final Set<InetAddress> dnsServers = new HashSet<>();
+        public Inet4Address gateway; // WiFi legacy behavior with static ipv4 config
+
+        public static InitialConfiguration copy(InitialConfiguration config) {
+            if (config == null) {
+                return null;
+            }
+            InitialConfiguration configCopy = new InitialConfiguration();
+            configCopy.ipAddresses.addAll(config.ipAddresses);
+            configCopy.directlyConnectedRoutes.addAll(config.directlyConnectedRoutes);
+            configCopy.dnsServers.addAll(config.dnsServers);
+            return configCopy;
+        }
+
+        @Override
+        public String toString() {
+            return String.format(
+                    "InitialConfiguration(IPs: {%s}, prefixes: {%s}, DNS: {%s}, v4 gateway: %s)",
+                    join(", ", ipAddresses), join(", ", directlyConnectedRoutes),
+                    join(", ", dnsServers), gateway);
+        }
+
+        public boolean isValid() {
+            if (ipAddresses.isEmpty()) {
+                return false;
+            }
+
+            // For every IP address, there must be at least one prefix containing that address.
+            for (LinkAddress addr : ipAddresses) {
+                if (!any(directlyConnectedRoutes, (p) -> p.contains(addr.getAddress()))) {
+                    return false;
+                }
+            }
+            // For every dns server, there must be at least one prefix containing that address.
+            for (InetAddress addr : dnsServers) {
+                if (!any(directlyConnectedRoutes, (p) -> p.contains(addr))) {
+                    return false;
+                }
+            }
+            // All IPv6 LinkAddresses have an RFC7421-suitable prefix length
+            // (read: compliant with RFC4291#section2.5.4).
+            if (any(ipAddresses, not(InitialConfiguration::isPrefixLengthCompliant))) {
+                return false;
+            }
+            // If directlyConnectedRoutes contains an IPv6 default route
+            // then ipAddresses MUST contain at least one non-ULA GUA.
+            if (any(directlyConnectedRoutes, InitialConfiguration::isIPv6DefaultRoute)
+                    && all(ipAddresses, not(InitialConfiguration::isIPv6GUA))) {
+                return false;
+            }
+            // The prefix length of routes in directlyConnectedRoutes be within reasonable
+            // bounds for IPv6: /48-/64 just as we’d accept in RIOs.
+            if (any(directlyConnectedRoutes, not(InitialConfiguration::isPrefixLengthCompliant))) {
+                return false;
+            }
+            // There no more than one IPv4 address
+            if (ipAddresses.stream().filter(Inet4Address.class::isInstance).count() > 1) {
+                return false;
+            }
+
+            return true;
+        }
+
+        /**
+         * @return true if the given list of addressess and routes satisfies provisioning for this
+         * InitialConfiguration. LinkAddresses and RouteInfo objects are not compared with equality
+         * because addresses and routes seen by Netlink will contain additional fields like flags,
+         * interfaces, and so on. If this InitialConfiguration has no IP address specified, the
+         * provisioning check always fails.
+         *
+         * If the given list of routes is null, only addresses are taken into considerations.
+         */
+        public boolean isProvisionedBy(List<LinkAddress> addresses, List<RouteInfo> routes) {
+            if (ipAddresses.isEmpty()) {
+                return false;
+            }
+
+            for (LinkAddress addr : ipAddresses) {
+                if (!any(addresses, (addrSeen) -> addr.isSameAddressAs(addrSeen))) {
+                    return false;
+                }
+            }
+
+            if (routes != null) {
+                for (IpPrefix prefix : directlyConnectedRoutes) {
+                    if (!any(routes, (routeSeen) -> isDirectlyConnectedRoute(routeSeen, prefix))) {
+                        return false;
+                    }
+                }
+            }
+
+            return true;
+        }
+
+        private static boolean isDirectlyConnectedRoute(RouteInfo route, IpPrefix prefix) {
+            return !route.hasGateway() && prefix.equals(route.getDestination());
+        }
+
+        private static boolean isPrefixLengthCompliant(LinkAddress addr) {
+            return addr.isIPv4() || isCompliantIPv6PrefixLength(addr.getPrefixLength());
+        }
+
+        private static boolean isPrefixLengthCompliant(IpPrefix prefix) {
+            return prefix.isIPv4() || isCompliantIPv6PrefixLength(prefix.getPrefixLength());
+        }
+
+        private static boolean isCompliantIPv6PrefixLength(int prefixLength) {
+            return (NetworkConstants.RFC6177_MIN_PREFIX_LENGTH <= prefixLength)
+                    && (prefixLength <= NetworkConstants.RFC7421_PREFIX_LENGTH);
+        }
+
+        private static boolean isIPv6DefaultRoute(IpPrefix prefix) {
+            return prefix.getAddress().equals(Inet6Address.ANY);
+        }
+
+        private static boolean isIPv6GUA(LinkAddress addr) {
+            return addr.isIPv6() && addr.isGlobalPreferred();
+        }
+    }
+
+    public static final String DUMP_ARG = "ipclient";
+    public static final String DUMP_ARG_CONFIRM = "confirm";
+
+    private static final int CMD_TERMINATE_AFTER_STOP             = 1;
+    private static final int CMD_STOP                             = 2;
+    private static final int CMD_START                            = 3;
+    private static final int CMD_CONFIRM                          = 4;
+    private static final int EVENT_PRE_DHCP_ACTION_COMPLETE       = 5;
+    // Sent by NetlinkTracker to communicate netlink events.
+    private static final int EVENT_NETLINK_LINKPROPERTIES_CHANGED = 6;
+    private static final int CMD_UPDATE_TCP_BUFFER_SIZES          = 7;
+    private static final int CMD_UPDATE_HTTP_PROXY                = 8;
+    private static final int CMD_SET_MULTICAST_FILTER             = 9;
+    private static final int EVENT_PROVISIONING_TIMEOUT           = 10;
+    private static final int EVENT_DHCPACTION_TIMEOUT             = 11;
+
+    private static final int MAX_LOG_RECORDS = 500;
+    private static final int MAX_PACKET_RECORDS = 100;
+
+    private static final boolean NO_CALLBACKS = false;
+    private static final boolean SEND_CALLBACKS = true;
+
+    // This must match the interface prefix in clatd.c.
+    // TODO: Revert this hack once IpClient and Nat464Xlat work in concert.
+    private static final String CLAT_PREFIX = "v4-";
+
+    private final State mStoppedState = new StoppedState();
+    private final State mStoppingState = new StoppingState();
+    private final State mStartedState = new StartedState();
+    private final State mRunningState = new RunningState();
+
+    private final String mTag;
+    private final Context mContext;
+    private final String mInterfaceName;
+    private final String mClatInterfaceName;
+    @VisibleForTesting
+    protected final Callback mCallback;
+    private final INetworkManagementService mNwService;
+    private final NetlinkTracker mNetlinkTracker;
+    private final WakeupMessage mProvisioningTimeoutAlarm;
+    private final WakeupMessage mDhcpActionTimeoutAlarm;
+    private final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
+    private final SharedLog mLog;
+    private final LocalLog mConnectivityPacketLog;
+    private final MessageHandlingLogger mMsgStateLogger;
+    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
+    private final InterfaceController mInterfaceCtrl;
+
+    private NetworkInterface mNetworkInterface;
+
+    /**
+     * Non-final member variables accessed only from within our StateMachine.
+     */
+    private LinkProperties mLinkProperties;
+    private ProvisioningConfiguration mConfiguration;
+    private IpReachabilityMonitor mIpReachabilityMonitor;
+    private DhcpClient mDhcpClient;
+    private DhcpResults mDhcpResults;
+    private String mTcpBufferSizes;
+    private ProxyInfo mHttpProxy;
+    private ApfFilter mApfFilter;
+    private boolean mMulticastFiltering;
+    private long mStartTimeMillis;
+
+    public IpClient(Context context, String ifName, Callback callback) {
+        this(context, ifName, callback, INetworkManagementService.Stub.asInterface(
+                ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)),
+                NetdService.getInstance());
+    }
+
+    /**
+     * An expanded constructor, useful for dependency injection.
+     * TODO: migrate all test users to mock IpClient directly and remove this ctor.
+     */
+    public IpClient(Context context, String ifName, Callback callback,
+            INetworkManagementService nwService) {
+        this(context, ifName, callback, nwService, NetdService.getInstance());
+    }
+
+    @VisibleForTesting
+    IpClient(Context context, String ifName, Callback callback,
+            INetworkManagementService nwService, INetd netd) {
+        super(IpClient.class.getSimpleName() + "." + ifName);
+        mTag = getName();
+
+        mContext = context;
+        mInterfaceName = ifName;
+        mClatInterfaceName = CLAT_PREFIX + ifName;
+        mCallback = new LoggingCallbackWrapper(callback);
+        mNwService = nwService;
+
+        mLog = new SharedLog(MAX_LOG_RECORDS, mTag);
+        mConnectivityPacketLog = new LocalLog(MAX_PACKET_RECORDS);
+        mMsgStateLogger = new MessageHandlingLogger();
+
+        mInterfaceCtrl = new InterfaceController(mInterfaceName, mNwService, netd, mLog);
+
+        mNetlinkTracker = new NetlinkTracker(
+                mInterfaceName,
+                new NetlinkTracker.Callback() {
+                    @Override
+                    public void update() {
+                        sendMessage(EVENT_NETLINK_LINKPROPERTIES_CHANGED);
+                    }
+                }) {
+            @Override
+            public void interfaceAdded(String iface) {
+                super.interfaceAdded(iface);
+                if (mClatInterfaceName.equals(iface)) {
+                    mCallback.setNeighborDiscoveryOffload(false);
+                } else if (!mInterfaceName.equals(iface)) {
+                    return;
+                }
+
+                final String msg = "interfaceAdded(" + iface +")";
+                logMsg(msg);
+            }
+
+            @Override
+            public void interfaceRemoved(String iface) {
+                super.interfaceRemoved(iface);
+                // TODO: Also observe mInterfaceName going down and take some
+                // kind of appropriate action.
+                if (mClatInterfaceName.equals(iface)) {
+                    // TODO: consider sending a message to the IpClient main
+                    // StateMachine thread, in case "NDO enabled" state becomes
+                    // tied to more things that 464xlat operation.
+                    mCallback.setNeighborDiscoveryOffload(true);
+                } else if (!mInterfaceName.equals(iface)) {
+                    return;
+                }
+
+                final String msg = "interfaceRemoved(" + iface +")";
+                logMsg(msg);
+            }
+
+            private void logMsg(String msg) {
+                Log.d(mTag, msg);
+                getHandler().post(() -> { mLog.log("OBSERVED " + msg); });
+            }
+        };
+
+        mLinkProperties = new LinkProperties();
+        mLinkProperties.setInterfaceName(mInterfaceName);
+
+        mMultinetworkPolicyTracker = new MultinetworkPolicyTracker(mContext, getHandler(),
+                () -> { mLog.log("OBSERVED AvoidBadWifi changed"); });
+
+        mProvisioningTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
+                mTag + ".EVENT_PROVISIONING_TIMEOUT", EVENT_PROVISIONING_TIMEOUT);
+        mDhcpActionTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
+                mTag + ".EVENT_DHCPACTION_TIMEOUT", EVENT_DHCPACTION_TIMEOUT);
+
+        // Anything the StateMachine may access must have been instantiated
+        // before this point.
+        configureAndStartStateMachine();
+
+        // Anything that may send messages to the StateMachine must only be
+        // configured to do so after the StateMachine has started (above).
+        startStateMachineUpdaters();
+    }
+
+    private void configureAndStartStateMachine() {
+        addState(mStoppedState);
+        addState(mStartedState);
+            addState(mRunningState, mStartedState);
+        addState(mStoppingState);
+
+        setInitialState(mStoppedState);
+
+        super.start();
+    }
+
+    private void startStateMachineUpdaters() {
+        try {
+            mNwService.registerObserver(mNetlinkTracker);
+        } catch (RemoteException e) {
+            logError("Couldn't register NetlinkTracker: %s", e);
+        }
+
+        mMultinetworkPolicyTracker.start();
+    }
+
+    private void stopStateMachineUpdaters() {
+        try {
+            mNwService.unregisterObserver(mNetlinkTracker);
+        } catch (RemoteException e) {
+            logError("Couldn't unregister NetlinkTracker: %s", e);
+        }
+
+        mMultinetworkPolicyTracker.shutdown();
+    }
+
+    @Override
+    protected void onQuitting() {
+        mCallback.onQuit();
+    }
+
+    // Shut down this IpClient instance altogether.
+    public void shutdown() {
+        stop();
+        sendMessage(CMD_TERMINATE_AFTER_STOP);
+    }
+
+    public static ProvisioningConfiguration.Builder buildProvisioningConfiguration() {
+        return new ProvisioningConfiguration.Builder();
+    }
+
+    public void startProvisioning(ProvisioningConfiguration req) {
+        if (!req.isValid()) {
+            doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
+            return;
+        }
+
+        getNetworkInterface();
+
+        mCallback.setNeighborDiscoveryOffload(true);
+        sendMessage(CMD_START, new ProvisioningConfiguration(req));
+    }
+
+    // TODO: Delete this.
+    public void startProvisioning(StaticIpConfiguration staticIpConfig) {
+        startProvisioning(buildProvisioningConfiguration()
+                .withStaticConfiguration(staticIpConfig)
+                .build());
+    }
+
+    public void startProvisioning() {
+        startProvisioning(new ProvisioningConfiguration());
+    }
+
+    public void stop() {
+        sendMessage(CMD_STOP);
+    }
+
+    public void confirmConfiguration() {
+        sendMessage(CMD_CONFIRM);
+    }
+
+    public void completedPreDhcpAction() {
+        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
+    }
+
+    /**
+     * Set the TCP buffer sizes to use.
+     *
+     * This may be called, repeatedly, at any time before or after a call to
+     * #startProvisioning(). The setting is cleared upon calling #stop().
+     */
+    public void setTcpBufferSizes(String tcpBufferSizes) {
+        sendMessage(CMD_UPDATE_TCP_BUFFER_SIZES, tcpBufferSizes);
+    }
+
+    /**
+     * Set the HTTP Proxy configuration to use.
+     *
+     * This may be called, repeatedly, at any time before or after a call to
+     * #startProvisioning(). The setting is cleared upon calling #stop().
+     */
+    public void setHttpProxy(ProxyInfo proxyInfo) {
+        sendMessage(CMD_UPDATE_HTTP_PROXY, proxyInfo);
+    }
+
+    /**
+     * Enable or disable the multicast filter.  Attempts to use APF to accomplish the filtering,
+     * if not, Callback.setFallbackMulticastFilter() is called.
+     */
+    public void setMulticastFilter(boolean enabled) {
+        sendMessage(CMD_SET_MULTICAST_FILTER, enabled);
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+        if (args != null && args.length > 0 && DUMP_ARG_CONFIRM.equals(args[0])) {
+            // Execute confirmConfiguration() and take no further action.
+            confirmConfiguration();
+            return;
+        }
+
+        // Thread-unsafe access to mApfFilter but just used for debugging.
+        final ApfFilter apfFilter = mApfFilter;
+        final ProvisioningConfiguration provisioningConfig = mConfiguration;
+        final ApfCapabilities apfCapabilities = (provisioningConfig != null)
+                ? provisioningConfig.mApfCapabilities : null;
+
+        IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
+        pw.println(mTag + " APF dump:");
+        pw.increaseIndent();
+        if (apfFilter != null) {
+            apfFilter.dump(pw);
+        } else {
+            pw.print("No active ApfFilter; ");
+            if (provisioningConfig == null) {
+                pw.println("IpClient not yet started.");
+            } else if (apfCapabilities == null || apfCapabilities.apfVersionSupported == 0) {
+                pw.println("Hardware does not support APF.");
+            } else {
+                pw.println("ApfFilter not yet started, APF capabilities: " + apfCapabilities);
+            }
+        }
+        pw.decreaseIndent();
+
+        pw.println();
+        pw.println(mTag + " current ProvisioningConfiguration:");
+        pw.increaseIndent();
+        pw.println(Objects.toString(provisioningConfig, "N/A"));
+        pw.decreaseIndent();
+
+        pw.println();
+        pw.println(mTag + " StateMachine dump:");
+        pw.increaseIndent();
+        mLog.dump(fd, pw, args);
+        pw.decreaseIndent();
+
+        pw.println();
+        pw.println(mTag + " connectivity packet log:");
+        pw.println();
+        pw.println("Debug with python and scapy via:");
+        pw.println("shell$ python");
+        pw.println(">>> from scapy import all as scapy");
+        pw.println(">>> scapy.Ether(\"<paste_hex_string>\".decode(\"hex\")).show2()");
+        pw.println();
+
+        pw.increaseIndent();
+        mConnectivityPacketLog.readOnlyLocalLog().dump(fd, pw, args);
+        pw.decreaseIndent();
+    }
+
+
+    /**
+     * Internals.
+     */
+
+    @Override
+    protected String getWhatToString(int what) {
+        return sWhatToString.get(what, "UNKNOWN: " + Integer.toString(what));
+    }
+
+    @Override
+    protected String getLogRecString(Message msg) {
+        final String logLine = String.format(
+                "%s/%d %d %d %s [%s]",
+                mInterfaceName, mNetworkInterface == null ? -1 : mNetworkInterface.getIndex(),
+                msg.arg1, msg.arg2, Objects.toString(msg.obj), mMsgStateLogger);
+
+        final String richerLogLine = getWhatToString(msg.what) + " " + logLine;
+        mLog.log(richerLogLine);
+        if (DBG) {
+            Log.d(mTag, richerLogLine);
+        }
+
+        mMsgStateLogger.reset();
+        return logLine;
+    }
+
+    @Override
+    protected boolean recordLogRec(Message msg) {
+        // Don't log EVENT_NETLINK_LINKPROPERTIES_CHANGED. They can be noisy,
+        // and we already log any LinkProperties change that results in an
+        // invocation of IpClient.Callback#onLinkPropertiesChange().
+        final boolean shouldLog = (msg.what != EVENT_NETLINK_LINKPROPERTIES_CHANGED);
+        if (!shouldLog) {
+            mMsgStateLogger.reset();
+        }
+        return shouldLog;
+    }
+
+    private void logError(String fmt, Object... args) {
+        final String msg = "ERROR " + String.format(fmt, args);
+        Log.e(mTag, msg);
+        mLog.log(msg);
+    }
+
+    private void getNetworkInterface() {
+        try {
+            mNetworkInterface = NetworkInterface.getByName(mInterfaceName);
+        } catch (SocketException | NullPointerException e) {
+            // TODO: throw new IllegalStateException.
+            logError("Failed to get interface object: %s", e);
+        }
+    }
+
+    // This needs to be called with care to ensure that our LinkProperties
+    // are in sync with the actual LinkProperties of the interface. For example,
+    // we should only call this if we know for sure that there are no IP addresses
+    // assigned to the interface, etc.
+    private void resetLinkProperties() {
+        mNetlinkTracker.clearLinkProperties();
+        mConfiguration = null;
+        mDhcpResults = null;
+        mTcpBufferSizes = "";
+        mHttpProxy = null;
+
+        mLinkProperties = new LinkProperties();
+        mLinkProperties.setInterfaceName(mInterfaceName);
+    }
+
+    private void recordMetric(final int type) {
+        if (mStartTimeMillis <= 0) { Log.wtf(mTag, "Start time undefined!"); }
+        final long duration = SystemClock.elapsedRealtime() - mStartTimeMillis;
+        mMetricsLog.log(mInterfaceName, new IpManagerEvent(type, duration));
+    }
+
+    // For now: use WifiStateMachine's historical notion of provisioned.
+    @VisibleForTesting
+    static boolean isProvisioned(LinkProperties lp, InitialConfiguration config) {
+        // For historical reasons, we should connect even if all we have is
+        // an IPv4 address and nothing else.
+        if (lp.hasIPv4Address() || lp.isProvisioned()) {
+            return true;
+        }
+        if (config == null) {
+            return false;
+        }
+
+        // When an InitialConfiguration is specified, ignore any difference with previous
+        // properties and instead check if properties observed match the desired properties.
+        return config.isProvisionedBy(lp.getLinkAddresses(), lp.getRoutes());
+    }
+
+    // TODO: Investigate folding all this into the existing static function
+    // LinkProperties.compareProvisioning() or some other single function that
+    // takes two LinkProperties objects and returns a ProvisioningChange
+    // object that is a correct and complete assessment of what changed, taking
+    // account of the asymmetries described in the comments in this function.
+    // Then switch to using it everywhere (IpReachabilityMonitor, etc.).
+    private ProvisioningChange compareProvisioning(LinkProperties oldLp, LinkProperties newLp) {
+        ProvisioningChange delta;
+        InitialConfiguration config = mConfiguration != null ? mConfiguration.mInitialConfig : null;
+        final boolean wasProvisioned = isProvisioned(oldLp, config);
+        final boolean isProvisioned = isProvisioned(newLp, config);
+
+        if (!wasProvisioned && isProvisioned) {
+            delta = ProvisioningChange.GAINED_PROVISIONING;
+        } else if (wasProvisioned && isProvisioned) {
+            delta = ProvisioningChange.STILL_PROVISIONED;
+        } else if (!wasProvisioned && !isProvisioned) {
+            delta = ProvisioningChange.STILL_NOT_PROVISIONED;
+        } else {
+            // (wasProvisioned && !isProvisioned)
+            //
+            // Note that this is true even if we lose a configuration element
+            // (e.g., a default gateway) that would not be required to advance
+            // into provisioned state. This is intended: if we have a default
+            // router and we lose it, that's a sure sign of a problem, but if
+            // we connect to a network with no IPv4 DNS servers, we consider
+            // that to be a network without DNS servers and connect anyway.
+            //
+            // See the comment below.
+            delta = ProvisioningChange.LOST_PROVISIONING;
+        }
+
+        final boolean lostIPv6 = oldLp.isIPv6Provisioned() && !newLp.isIPv6Provisioned();
+        final boolean lostIPv4Address = oldLp.hasIPv4Address() && !newLp.hasIPv4Address();
+        final boolean lostIPv6Router = oldLp.hasIPv6DefaultRoute() && !newLp.hasIPv6DefaultRoute();
+
+        // If bad wifi avoidance is disabled, then ignore IPv6 loss of
+        // provisioning. Otherwise, when a hotspot that loses Internet
+        // access sends out a 0-lifetime RA to its clients, the clients
+        // will disconnect and then reconnect, avoiding the bad hotspot,
+        // instead of getting stuck on the bad hotspot. http://b/31827713 .
+        //
+        // This is incorrect because if the hotspot then regains Internet
+        // access with a different prefix, TCP connections on the
+        // deprecated addresses will remain stuck.
+        //
+        // Note that we can still be disconnected by IpReachabilityMonitor
+        // if the IPv6 default gateway (but not the IPv6 DNS servers; see
+        // accompanying code in IpReachabilityMonitor) is unreachable.
+        final boolean ignoreIPv6ProvisioningLoss = !mMultinetworkPolicyTracker.getAvoidBadWifi();
+
+        // Additionally:
+        //
+        // Partial configurations (e.g., only an IPv4 address with no DNS
+        // servers and no default route) are accepted as long as DHCPv4
+        // succeeds. On such a network, isProvisioned() will always return
+        // false, because the configuration is not complete, but we want to
+        // connect anyway. It might be a disconnected network such as a
+        // Chromecast or a wireless printer, for example.
+        //
+        // Because on such a network isProvisioned() will always return false,
+        // delta will never be LOST_PROVISIONING. So check for loss of
+        // provisioning here too.
+        if (lostIPv4Address || (lostIPv6 && !ignoreIPv6ProvisioningLoss)) {
+            delta = ProvisioningChange.LOST_PROVISIONING;
+        }
+
+        // Additionally:
+        //
+        // If the previous link properties had a global IPv6 address and an
+        // IPv6 default route then also consider the loss of that default route
+        // to be a loss of provisioning. See b/27962810.
+        if (oldLp.hasGlobalIPv6Address() && (lostIPv6Router && !ignoreIPv6ProvisioningLoss)) {
+            delta = ProvisioningChange.LOST_PROVISIONING;
+        }
+
+        return delta;
+    }
+
+    private void dispatchCallback(ProvisioningChange delta, LinkProperties newLp) {
+        switch (delta) {
+            case GAINED_PROVISIONING:
+                if (DBG) { Log.d(mTag, "onProvisioningSuccess()"); }
+                recordMetric(IpManagerEvent.PROVISIONING_OK);
+                mCallback.onProvisioningSuccess(newLp);
+                break;
+
+            case LOST_PROVISIONING:
+                if (DBG) { Log.d(mTag, "onProvisioningFailure()"); }
+                recordMetric(IpManagerEvent.PROVISIONING_FAIL);
+                mCallback.onProvisioningFailure(newLp);
+                break;
+
+            default:
+                if (DBG) { Log.d(mTag, "onLinkPropertiesChange()"); }
+                mCallback.onLinkPropertiesChange(newLp);
+                break;
+        }
+    }
+
+    // Updates all IpClient-related state concerned with LinkProperties.
+    // Returns a ProvisioningChange for possibly notifying other interested
+    // parties that are not fronted by IpClient.
+    private ProvisioningChange setLinkProperties(LinkProperties newLp) {
+        if (mApfFilter != null) {
+            mApfFilter.setLinkProperties(newLp);
+        }
+        if (mIpReachabilityMonitor != null) {
+            mIpReachabilityMonitor.updateLinkProperties(newLp);
+        }
+
+        ProvisioningChange delta = compareProvisioning(mLinkProperties, newLp);
+        mLinkProperties = new LinkProperties(newLp);
+
+        if (delta == ProvisioningChange.GAINED_PROVISIONING) {
+            // TODO: Add a proper ProvisionedState and cancel the alarm in
+            // its enter() method.
+            mProvisioningTimeoutAlarm.cancel();
+        }
+
+        return delta;
+    }
+
+    private LinkProperties assembleLinkProperties() {
+        // [1] Create a new LinkProperties object to populate.
+        LinkProperties newLp = new LinkProperties();
+        newLp.setInterfaceName(mInterfaceName);
+
+        // [2] Pull in data from netlink:
+        //         - IPv4 addresses
+        //         - IPv6 addresses
+        //         - IPv6 routes
+        //         - IPv6 DNS servers
+        //
+        // N.B.: this is fundamentally race-prone and should be fixed by
+        // changing NetlinkTracker from a hybrid edge/level model to an
+        // edge-only model, or by giving IpClient its own netlink socket(s)
+        // so as to track all required information directly.
+        LinkProperties netlinkLinkProperties = mNetlinkTracker.getLinkProperties();
+        newLp.setLinkAddresses(netlinkLinkProperties.getLinkAddresses());
+        for (RouteInfo route : netlinkLinkProperties.getRoutes()) {
+            newLp.addRoute(route);
+        }
+        addAllReachableDnsServers(newLp, netlinkLinkProperties.getDnsServers());
+
+        // [3] Add in data from DHCPv4, if available.
+        //
+        // mDhcpResults is never shared with any other owner so we don't have
+        // to worry about concurrent modification.
+        if (mDhcpResults != null) {
+            for (RouteInfo route : mDhcpResults.getRoutes(mInterfaceName)) {
+                newLp.addRoute(route);
+            }
+            addAllReachableDnsServers(newLp, mDhcpResults.dnsServers);
+            newLp.setDomains(mDhcpResults.domains);
+
+            if (mDhcpResults.mtu != 0) {
+                newLp.setMtu(mDhcpResults.mtu);
+            }
+        }
+
+        // [4] Add in TCP buffer sizes and HTTP Proxy config, if available.
+        if (!TextUtils.isEmpty(mTcpBufferSizes)) {
+            newLp.setTcpBufferSizes(mTcpBufferSizes);
+        }
+        if (mHttpProxy != null) {
+            newLp.setHttpProxy(mHttpProxy);
+        }
+
+        // [5] Add data from InitialConfiguration
+        if (mConfiguration != null && mConfiguration.mInitialConfig != null) {
+            InitialConfiguration config = mConfiguration.mInitialConfig;
+            // Add InitialConfiguration routes and dns server addresses once all addresses
+            // specified in the InitialConfiguration have been observed with Netlink.
+            if (config.isProvisionedBy(newLp.getLinkAddresses(), null)) {
+                for (IpPrefix prefix : config.directlyConnectedRoutes) {
+                    newLp.addRoute(new RouteInfo(prefix, null, mInterfaceName));
+                }
+            }
+            addAllReachableDnsServers(newLp, config.dnsServers);
+        }
+        final LinkProperties oldLp = mLinkProperties;
+        if (DBG) {
+            Log.d(mTag, String.format("Netlink-seen LPs: %s, new LPs: %s; old LPs: %s",
+                    netlinkLinkProperties, newLp, oldLp));
+        }
+
+        // TODO: also learn via netlink routes specified by an InitialConfiguration and specified
+        // from a static IP v4 config instead of manually patching them in in steps [3] and [5].
+        return newLp;
+    }
+
+    private static void addAllReachableDnsServers(
+            LinkProperties lp, Iterable<InetAddress> dnses) {
+        // TODO: Investigate deleting this reachability check.  We should be
+        // able to pass everything down to netd and let netd do evaluation
+        // and RFC6724-style sorting.
+        for (InetAddress dns : dnses) {
+            if (!dns.isAnyLocalAddress() && lp.isReachable(dns)) {
+                lp.addDnsServer(dns);
+            }
+        }
+    }
+
+    // Returns false if we have lost provisioning, true otherwise.
+    private boolean handleLinkPropertiesUpdate(boolean sendCallbacks) {
+        final LinkProperties newLp = assembleLinkProperties();
+        if (Objects.equals(newLp, mLinkProperties)) {
+            return true;
+        }
+        final ProvisioningChange delta = setLinkProperties(newLp);
+        if (sendCallbacks) {
+            dispatchCallback(delta, newLp);
+        }
+        return (delta != ProvisioningChange.LOST_PROVISIONING);
+    }
+
+    private void handleIPv4Success(DhcpResults dhcpResults) {
+        mDhcpResults = new DhcpResults(dhcpResults);
+        final LinkProperties newLp = assembleLinkProperties();
+        final ProvisioningChange delta = setLinkProperties(newLp);
+
+        if (DBG) {
+            Log.d(mTag, "onNewDhcpResults(" + Objects.toString(dhcpResults) + ")");
+        }
+        mCallback.onNewDhcpResults(dhcpResults);
+        dispatchCallback(delta, newLp);
+    }
+
+    private void handleIPv4Failure() {
+        // TODO: Investigate deleting this clearIPv4Address() call.
+        //
+        // DhcpClient will send us CMD_CLEAR_LINKADDRESS in all circumstances
+        // that could trigger a call to this function. If we missed handling
+        // that message in StartedState for some reason we would still clear
+        // any addresses upon entry to StoppedState.
+        mInterfaceCtrl.clearIPv4Address();
+        mDhcpResults = null;
+        if (DBG) { Log.d(mTag, "onNewDhcpResults(null)"); }
+        mCallback.onNewDhcpResults(null);
+
+        handleProvisioningFailure();
+    }
+
+    private void handleProvisioningFailure() {
+        final LinkProperties newLp = assembleLinkProperties();
+        ProvisioningChange delta = setLinkProperties(newLp);
+        // If we've gotten here and we're still not provisioned treat that as
+        // a total loss of provisioning.
+        //
+        // Either (a) static IP configuration failed or (b) DHCPv4 failed AND
+        // there was no usable IPv6 obtained before a non-zero provisioning
+        // timeout expired.
+        //
+        // Regardless: GAME OVER.
+        if (delta == ProvisioningChange.STILL_NOT_PROVISIONED) {
+            delta = ProvisioningChange.LOST_PROVISIONING;
+        }
+
+        dispatchCallback(delta, newLp);
+        if (delta == ProvisioningChange.LOST_PROVISIONING) {
+            transitionTo(mStoppingState);
+        }
+    }
+
+    private void doImmediateProvisioningFailure(int failureType) {
+        logError("onProvisioningFailure(): %s", failureType);
+        recordMetric(failureType);
+        mCallback.onProvisioningFailure(new LinkProperties(mLinkProperties));
+    }
+
+    private boolean startIPv4() {
+        // If we have a StaticIpConfiguration attempt to apply it and
+        // handle the result accordingly.
+        if (mConfiguration.mStaticIpConfig != null) {
+            if (mInterfaceCtrl.setIPv4Address(mConfiguration.mStaticIpConfig.ipAddress)) {
+                handleIPv4Success(new DhcpResults(mConfiguration.mStaticIpConfig));
+            } else {
+                return false;
+            }
+        } else {
+            // Start DHCPv4.
+            mDhcpClient = DhcpClient.makeDhcpClient(mContext, IpClient.this, mInterfaceName);
+            mDhcpClient.registerForPreDhcpNotification();
+            mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP);
+        }
+
+        return true;
+    }
+
+    private boolean startIPv6() {
+        return mInterfaceCtrl.setIPv6PrivacyExtensions(true) &&
+               mInterfaceCtrl.setIPv6AddrGenModeIfSupported(mConfiguration.mIPv6AddrGenMode) &&
+               mInterfaceCtrl.enableIPv6();
+    }
+
+    private boolean applyInitialConfig(InitialConfiguration config) {
+        // TODO: also support specifying a static IPv4 configuration in InitialConfiguration.
+        for (LinkAddress addr : findAll(config.ipAddresses, LinkAddress::isIPv6)) {
+            if (!mInterfaceCtrl.addAddress(addr)) return false;
+        }
+
+        return true;
+    }
+
+    private boolean startIpReachabilityMonitor() {
+        try {
+            mIpReachabilityMonitor = new IpReachabilityMonitor(
+                    mContext,
+                    mInterfaceName,
+                    mLog,
+                    new IpReachabilityMonitor.Callback() {
+                        @Override
+                        public void notifyLost(InetAddress ip, String logMsg) {
+                            mCallback.onReachabilityLost(logMsg);
+                        }
+                    },
+                    mMultinetworkPolicyTracker);
+        } catch (IllegalArgumentException iae) {
+            // Failed to start IpReachabilityMonitor. Log it and call
+            // onProvisioningFailure() immediately.
+            //
+            // See http://b/31038971.
+            logError("IpReachabilityMonitor failure: %s", iae);
+            mIpReachabilityMonitor = null;
+        }
+
+        return (mIpReachabilityMonitor != null);
+    }
+
+    private void stopAllIP() {
+        // We don't need to worry about routes, just addresses, because:
+        //     - disableIpv6() will clear autoconf IPv6 routes as well, and
+        //     - we don't get IPv4 routes from netlink
+        // so we neither react to nor need to wait for changes in either.
+
+        mInterfaceCtrl.disableIPv6();
+        mInterfaceCtrl.clearAllAddresses();
+    }
+
+    class StoppedState extends State {
+        @Override
+        public void enter() {
+            stopAllIP();
+
+            resetLinkProperties();
+            if (mStartTimeMillis > 0) {
+                recordMetric(IpManagerEvent.COMPLETE_LIFECYCLE);
+                mStartTimeMillis = 0;
+            }
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case CMD_TERMINATE_AFTER_STOP:
+                    stopStateMachineUpdaters();
+                    quit();
+                    break;
+
+                case CMD_STOP:
+                    break;
+
+                case CMD_START:
+                    mConfiguration = (ProvisioningConfiguration) msg.obj;
+                    transitionTo(mStartedState);
+                    break;
+
+                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
+                    handleLinkPropertiesUpdate(NO_CALLBACKS);
+                    break;
+
+                case CMD_UPDATE_TCP_BUFFER_SIZES:
+                    mTcpBufferSizes = (String) msg.obj;
+                    handleLinkPropertiesUpdate(NO_CALLBACKS);
+                    break;
+
+                case CMD_UPDATE_HTTP_PROXY:
+                    mHttpProxy = (ProxyInfo) msg.obj;
+                    handleLinkPropertiesUpdate(NO_CALLBACKS);
+                    break;
+
+                case CMD_SET_MULTICAST_FILTER:
+                    mMulticastFiltering = (boolean) msg.obj;
+                    break;
+
+                case DhcpClient.CMD_ON_QUIT:
+                    // Everything is already stopped.
+                    logError("Unexpected CMD_ON_QUIT (already stopped).");
+                    break;
+
+                default:
+                    return NOT_HANDLED;
+            }
+
+            mMsgStateLogger.handled(this, getCurrentState());
+            return HANDLED;
+        }
+    }
+
+    class StoppingState extends State {
+        @Override
+        public void enter() {
+            if (mDhcpClient == null) {
+                // There's no DHCPv4 for which to wait; proceed to stopped.
+                transitionTo(mStoppedState);
+            }
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case CMD_STOP:
+                    break;
+
+                case DhcpClient.CMD_CLEAR_LINKADDRESS:
+                    mInterfaceCtrl.clearIPv4Address();
+                    break;
+
+                case DhcpClient.CMD_ON_QUIT:
+                    mDhcpClient = null;
+                    transitionTo(mStoppedState);
+                    break;
+
+                default:
+                    deferMessage(msg);
+            }
+
+            mMsgStateLogger.handled(this, getCurrentState());
+            return HANDLED;
+        }
+    }
+
+    class StartedState extends State {
+        @Override
+        public void enter() {
+            mStartTimeMillis = SystemClock.elapsedRealtime();
+
+            if (mConfiguration.mProvisioningTimeoutMs > 0) {
+                final long alarmTime = SystemClock.elapsedRealtime() +
+                        mConfiguration.mProvisioningTimeoutMs;
+                mProvisioningTimeoutAlarm.schedule(alarmTime);
+            }
+
+            if (readyToProceed()) {
+                transitionTo(mRunningState);
+            } else {
+                // Clear all IPv4 and IPv6 before proceeding to RunningState.
+                // Clean up any leftover state from an abnormal exit from
+                // tethering or during an IpClient restart.
+                stopAllIP();
+            }
+        }
+
+        @Override
+        public void exit() {
+            mProvisioningTimeoutAlarm.cancel();
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case CMD_STOP:
+                    transitionTo(mStoppingState);
+                    break;
+
+                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
+                    handleLinkPropertiesUpdate(NO_CALLBACKS);
+                    if (readyToProceed()) {
+                        transitionTo(mRunningState);
+                    }
+                    break;
+
+                case EVENT_PROVISIONING_TIMEOUT:
+                    handleProvisioningFailure();
+                    break;
+
+                default:
+                    // It's safe to process messages out of order because the
+                    // only message that can both
+                    //     a) be received at this time and
+                    //     b) affect provisioning state
+                    // is EVENT_NETLINK_LINKPROPERTIES_CHANGED (handled above).
+                    deferMessage(msg);
+            }
+
+            mMsgStateLogger.handled(this, getCurrentState());
+            return HANDLED;
+        }
+
+        boolean readyToProceed() {
+            return (!mLinkProperties.hasIPv4Address() &&
+                    !mLinkProperties.hasGlobalIPv6Address());
+        }
+    }
+
+    class RunningState extends State {
+        private ConnectivityPacketTracker mPacketTracker;
+        private boolean mDhcpActionInFlight;
+
+        @Override
+        public void enter() {
+            ApfFilter.ApfConfiguration apfConfig = new ApfFilter.ApfConfiguration();
+            apfConfig.apfCapabilities = mConfiguration.mApfCapabilities;
+            apfConfig.multicastFilter = mMulticastFiltering;
+            // Get the Configuration for ApfFilter from Context
+            apfConfig.ieee802_3Filter =
+                    mContext.getResources().getBoolean(R.bool.config_apfDrop802_3Frames);
+            apfConfig.ethTypeBlackList =
+                    mContext.getResources().getIntArray(R.array.config_apfEthTypeBlackList);
+            mApfFilter = ApfFilter.maybeCreate(apfConfig, mNetworkInterface, mCallback);
+            // TODO: investigate the effects of any multicast filtering racing/interfering with the
+            // rest of this IP configuration startup.
+            if (mApfFilter == null) {
+                mCallback.setFallbackMulticastFilter(mMulticastFiltering);
+            }
+
+            mPacketTracker = createPacketTracker();
+            if (mPacketTracker != null) mPacketTracker.start(mConfiguration.mDisplayName);
+
+            if (mConfiguration.mEnableIPv6 && !startIPv6()) {
+                doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6);
+                transitionTo(mStoppingState);
+                return;
+            }
+
+            if (mConfiguration.mEnableIPv4 && !startIPv4()) {
+                doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4);
+                transitionTo(mStoppingState);
+                return;
+            }
+
+            final InitialConfiguration config = mConfiguration.mInitialConfig;
+            if ((config != null) && !applyInitialConfig(config)) {
+                // TODO introduce a new IpManagerEvent constant to distinguish this error case.
+                doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
+                transitionTo(mStoppingState);
+                return;
+            }
+
+            if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) {
+                doImmediateProvisioningFailure(
+                        IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR);
+                transitionTo(mStoppingState);
+                return;
+            }
+        }
+
+        @Override
+        public void exit() {
+            stopDhcpAction();
+
+            if (mIpReachabilityMonitor != null) {
+                mIpReachabilityMonitor.stop();
+                mIpReachabilityMonitor = null;
+            }
+
+            if (mDhcpClient != null) {
+                mDhcpClient.sendMessage(DhcpClient.CMD_STOP_DHCP);
+                mDhcpClient.doQuit();
+            }
+
+            if (mPacketTracker != null) {
+                mPacketTracker.stop();
+                mPacketTracker = null;
+            }
+
+            if (mApfFilter != null) {
+                mApfFilter.shutdown();
+                mApfFilter = null;
+            }
+
+            resetLinkProperties();
+        }
+
+        private ConnectivityPacketTracker createPacketTracker() {
+            try {
+                return new ConnectivityPacketTracker(
+                        getHandler(), mNetworkInterface, mConnectivityPacketLog);
+            } catch (IllegalArgumentException e) {
+                return null;
+            }
+        }
+
+        private void ensureDhcpAction() {
+            if (!mDhcpActionInFlight) {
+                mCallback.onPreDhcpAction();
+                mDhcpActionInFlight = true;
+                final long alarmTime = SystemClock.elapsedRealtime() +
+                        mConfiguration.mRequestedPreDhcpActionMs;
+                mDhcpActionTimeoutAlarm.schedule(alarmTime);
+            }
+        }
+
+        private void stopDhcpAction() {
+            mDhcpActionTimeoutAlarm.cancel();
+            if (mDhcpActionInFlight) {
+                mCallback.onPostDhcpAction();
+                mDhcpActionInFlight = false;
+            }
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case CMD_STOP:
+                    transitionTo(mStoppingState);
+                    break;
+
+                case CMD_START:
+                    logError("ALERT: START received in StartedState. Please fix caller.");
+                    break;
+
+                case CMD_CONFIRM:
+                    // TODO: Possibly introduce a second type of confirmation
+                    // that both probes (a) on-link neighbors and (b) does
+                    // a DHCPv4 RENEW.  We used to do this on Wi-Fi framework
+                    // roams.
+                    if (mIpReachabilityMonitor != null) {
+                        mIpReachabilityMonitor.probeAll();
+                    }
+                    break;
+
+                case EVENT_PRE_DHCP_ACTION_COMPLETE:
+                    // It's possible to reach here if, for example, someone
+                    // calls completedPreDhcpAction() after provisioning with
+                    // a static IP configuration.
+                    if (mDhcpClient != null) {
+                        mDhcpClient.sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE);
+                    }
+                    break;
+
+                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
+                    if (!handleLinkPropertiesUpdate(SEND_CALLBACKS)) {
+                        transitionTo(mStoppingState);
+                    }
+                    break;
+
+                case CMD_UPDATE_TCP_BUFFER_SIZES:
+                    mTcpBufferSizes = (String) msg.obj;
+                    // This cannot possibly change provisioning state.
+                    handleLinkPropertiesUpdate(SEND_CALLBACKS);
+                    break;
+
+                case CMD_UPDATE_HTTP_PROXY:
+                    mHttpProxy = (ProxyInfo) msg.obj;
+                    // This cannot possibly change provisioning state.
+                    handleLinkPropertiesUpdate(SEND_CALLBACKS);
+                    break;
+
+                case CMD_SET_MULTICAST_FILTER: {
+                    mMulticastFiltering = (boolean) msg.obj;
+                    if (mApfFilter != null) {
+                        mApfFilter.setMulticastFilter(mMulticastFiltering);
+                    } else {
+                        mCallback.setFallbackMulticastFilter(mMulticastFiltering);
+                    }
+                    break;
+                }
+
+                case EVENT_DHCPACTION_TIMEOUT:
+                    stopDhcpAction();
+                    break;
+
+                case DhcpClient.CMD_PRE_DHCP_ACTION:
+                    if (mConfiguration.mRequestedPreDhcpActionMs > 0) {
+                        ensureDhcpAction();
+                    } else {
+                        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
+                    }
+                    break;
+
+                case DhcpClient.CMD_CLEAR_LINKADDRESS:
+                    mInterfaceCtrl.clearIPv4Address();
+                    break;
+
+                case DhcpClient.CMD_CONFIGURE_LINKADDRESS: {
+                    final LinkAddress ipAddress = (LinkAddress) msg.obj;
+                    if (mInterfaceCtrl.setIPv4Address(ipAddress)) {
+                        mDhcpClient.sendMessage(DhcpClient.EVENT_LINKADDRESS_CONFIGURED);
+                    } else {
+                        logError("Failed to set IPv4 address.");
+                        dispatchCallback(ProvisioningChange.LOST_PROVISIONING,
+                                new LinkProperties(mLinkProperties));
+                        transitionTo(mStoppingState);
+                    }
+                    break;
+                }
+
+                // This message is only received when:
+                //
+                //     a) initial address acquisition succeeds,
+                //     b) renew succeeds or is NAK'd,
+                //     c) rebind succeeds or is NAK'd, or
+                //     c) the lease expires,
+                //
+                // but never when initial address acquisition fails. The latter
+                // condition is now governed by the provisioning timeout.
+                case DhcpClient.CMD_POST_DHCP_ACTION:
+                    stopDhcpAction();
+
+                    switch (msg.arg1) {
+                        case DhcpClient.DHCP_SUCCESS:
+                            handleIPv4Success((DhcpResults) msg.obj);
+                            break;
+                        case DhcpClient.DHCP_FAILURE:
+                            handleIPv4Failure();
+                            break;
+                        default:
+                            logError("Unknown CMD_POST_DHCP_ACTION status: %s", msg.arg1);
+                    }
+                    break;
+
+                case DhcpClient.CMD_ON_QUIT:
+                    // DHCPv4 quit early for some reason.
+                    logError("Unexpected CMD_ON_QUIT.");
+                    mDhcpClient = null;
+                    break;
+
+                default:
+                    return NOT_HANDLED;
+            }
+
+            mMsgStateLogger.handled(this, getCurrentState());
+            return HANDLED;
+        }
+    }
+
+    private static class MessageHandlingLogger {
+        public String processedInState;
+        public String receivedInState;
+
+        public void reset() {
+            processedInState = null;
+            receivedInState = null;
+        }
+
+        public void handled(State processedIn, IState receivedIn) {
+            processedInState = processedIn.getClass().getSimpleName();
+            receivedInState = receivedIn.getName();
+        }
+
+        public String toString() {
+            return String.format("rcvd_in=%s, proc_in=%s",
+                                 receivedInState, processedInState);
+        }
+    }
+
+    // TODO: extract out into CollectionUtils.
+    static <T> boolean any(Iterable<T> coll, Predicate<T> fn) {
+        for (T t : coll) {
+            if (fn.test(t)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    static <T> boolean all(Iterable<T> coll, Predicate<T> fn) {
+        return !any(coll, not(fn));
+    }
+
+    static <T> Predicate<T> not(Predicate<T> fn) {
+        return (t) -> !fn.test(t);
+    }
+
+    static <T> String join(String delimiter, Collection<T> coll) {
+        return coll.stream().map(Object::toString).collect(Collectors.joining(delimiter));
+    }
+
+    static <T> T find(Iterable<T> coll, Predicate<T> fn) {
+        for (T t: coll) {
+            if (fn.test(t)) {
+              return t;
+            }
+        }
+        return null;
+    }
+
+    static <T> List<T> findAll(Collection<T> coll, Predicate<T> fn) {
+        return coll.stream().filter(fn).collect(Collectors.toList());
+    }
+}
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index facdb85..3898145 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,135 +16,102 @@
 
 package android.net.ip;
 
-import com.android.internal.util.MessageUtils;
-import com.android.internal.util.WakeupMessage;
-
 import android.content.Context;
-import android.net.DhcpResults;
 import android.net.INetd;
-import android.net.InterfaceConfiguration;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties.ProvisioningChange;
 import android.net.LinkProperties;
-import android.net.ProxyInfo;
-import android.net.RouteInfo;
+import android.net.Network;
 import android.net.StaticIpConfiguration;
 import android.net.apf.ApfCapabilities;
-import android.net.apf.ApfFilter;
-import android.net.dhcp.DhcpClient;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.IpManagerEvent;
-import android.net.util.MultinetworkPolicyTracker;
 import android.net.util.NetdService;
-import android.net.util.NetworkConstants;
-import android.net.util.SharedLog;
 import android.os.INetworkManagementService;
-import android.os.Message;
-import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.ServiceSpecificException;
-import android.os.SystemClock;
-import android.system.OsConstants;
-import android.text.TextUtils;
-import android.util.LocalLog;
-import android.util.Log;
-import android.util.SparseArray;
+import android.net.apf.ApfCapabilities;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.R;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.internal.util.IState;
-import com.android.internal.util.Preconditions;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.server.net.NetlinkTracker;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.List;
-import java.util.Set;
-import java.util.StringJoiner;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
 
 
-/**
- * IpManager
- *
- * This class provides the interface to IP-layer provisioning and maintenance
- * functionality that can be used by transport layers like Wi-Fi, Ethernet,
- * et cetera.
- *
- * [ Lifetime ]
- * IpManager is designed to be instantiated as soon as the interface name is
- * known and can be as long-lived as the class containing it (i.e. declaring
- * it "private final" is okay).
+/*
+ * TODO: Delete this altogether in favor of its renamed successor: IpClient.
  *
  * @hide
  */
-public class IpManager extends StateMachine {
-    private static final boolean DBG = false;
-    private static final boolean VDBG = false;
+public class IpManager extends IpClient {
+    public static class ProvisioningConfiguration extends IpClient.ProvisioningConfiguration {
+        public ProvisioningConfiguration(IpClient.ProvisioningConfiguration ipcConfig) {
+            super(ipcConfig);
+        }
 
-    // For message logging.
-    private static final Class[] sMessageClasses = { IpManager.class, DhcpClient.class };
-    private static final SparseArray<String> sWhatToString =
-            MessageUtils.findMessageNames(sMessageClasses);
+        public static class Builder extends IpClient.ProvisioningConfiguration.Builder {
+            @Override
+            public Builder withoutIPv4() {
+                super.withoutIPv4();
+                return this;
+            }
+            @Override
+            public Builder withoutIPv6() {
+                super.withoutIPv6();
+                return this;
+            }
+            @Override
+            public Builder withoutIpReachabilityMonitor() {
+                super.withoutIpReachabilityMonitor();
+                return this;
+            }
+            @Override
+            public Builder withPreDhcpAction() {
+                super.withPreDhcpAction();
+                return this;
+            }
+            @Override
+            public Builder withPreDhcpAction(int dhcpActionTimeoutMs) {
+                super.withPreDhcpAction(dhcpActionTimeoutMs);
+                return this;
+            }
+            // No Override; locally defined type.
+            public Builder withInitialConfiguration(InitialConfiguration initialConfig) {
+                super.withInitialConfiguration((IpClient.InitialConfiguration) initialConfig);
+                return this;
+            }
+            @Override
+            public Builder withStaticConfiguration(StaticIpConfiguration staticConfig) {
+                super.withStaticConfiguration(staticConfig);
+                return this;
+            }
+            @Override
+            public Builder withApfCapabilities(ApfCapabilities apfCapabilities) {
+                super.withApfCapabilities(apfCapabilities);
+                return this;
+            }
+            @Override
+            public Builder withProvisioningTimeoutMs(int timeoutMs) {
+                super.withProvisioningTimeoutMs(timeoutMs);
+                return this;
+            }
+            @Override
+            public Builder withNetwork(Network network) {
+                super.withNetwork(network);
+                return this;
+            }
+            @Override
+            public Builder withDisplayName(String displayName) {
+                super.withDisplayName(displayName);
+                return this;
+            }
+            @Override
+            public ProvisioningConfiguration build() {
+                return new ProvisioningConfiguration(super.build());
+            }
+        }
+    }
 
-    /**
-     * Callbacks for handling IpManager events.
-     */
-    public static class Callback {
-        // In order to receive onPreDhcpAction(), call #withPreDhcpAction()
-        // when constructing a ProvisioningConfiguration.
-        //
-        // Implementations of onPreDhcpAction() must call
-        // IpManager#completedPreDhcpAction() to indicate that DHCP is clear
-        // to proceed.
-        public void onPreDhcpAction() {}
-        public void onPostDhcpAction() {}
+    public static ProvisioningConfiguration.Builder buildProvisioningConfiguration() {
+        return new ProvisioningConfiguration.Builder();
+    }
 
-        // This is purely advisory and not an indication of provisioning
-        // success or failure.  This is only here for callers that want to
-        // expose DHCPv4 results to other APIs (e.g., WifiInfo#setInetAddress).
-        // DHCPv4 or static IPv4 configuration failure or success can be
-        // determined by whether or not the passed-in DhcpResults object is
-        // null or not.
-        public void onNewDhcpResults(DhcpResults dhcpResults) {}
+    public static class InitialConfiguration extends IpClient.InitialConfiguration {
+    }
 
-        public void onProvisioningSuccess(LinkProperties newLp) {}
-        public void onProvisioningFailure(LinkProperties newLp) {}
-
-        // Invoked on LinkProperties changes.
-        public void onLinkPropertiesChange(LinkProperties newLp) {}
-
-        // Called when the internal IpReachabilityMonitor (if enabled) has
-        // detected the loss of a critical number of required neighbors.
-        public void onReachabilityLost(String logMsg) {}
-
-        // Called when the IpManager state machine terminates.
-        public void onQuit() {}
-
-        // Install an APF program to filter incoming packets.
-        public void installPacketFilter(byte[] filter) {}
-
-        // If multicast filtering cannot be accomplished with APF, this function will be called to
-        // actuate multicast filtering using another means.
-        public void setFallbackMulticastFilter(boolean enabled) {}
-
-        // Enabled/disable Neighbor Discover offload functionality. This is
-        // called, for example, whenever 464xlat is being started or stopped.
-        public void setNeighborDiscoveryOffload(boolean enable) {}
+    public static class Callback extends IpClient.Callback {
     }
 
     public static class WaitForProvisioningCallback extends Callback {
@@ -176,1594 +143,24 @@
         }
     }
 
-    // Use a wrapper class to log in order to ensure complete and detailed
-    // logging. This method is lighter weight than annotations/reflection
-    // and has the following benefits:
-    //
-    //     - No invoked method can be forgotten.
-    //       Any new method added to IpManager.Callback must be overridden
-    //       here or it will never be called.
-    //
-    //     - No invoking call site can be forgotten.
-    //       Centralized logging in this way means call sites don't need to
-    //       remember to log, and therefore no call site can be forgotten.
-    //
-    //     - No variation in log format among call sites.
-    //       Encourages logging of any available arguments, and all call sites
-    //       are necessarily logged identically.
-    //
-    // TODO: Find an lighter weight approach.
-    private class LoggingCallbackWrapper extends Callback {
-        private static final String PREFIX = "INVOKE ";
-        private Callback mCallback;
-
-        public LoggingCallbackWrapper(Callback callback) {
-            mCallback = callback;
-        }
-
-        private void log(String msg) {
-            mLog.log(PREFIX + msg);
-        }
-
-        @Override
-        public void onPreDhcpAction() {
-            mCallback.onPreDhcpAction();
-            log("onPreDhcpAction()");
-        }
-        @Override
-        public void onPostDhcpAction() {
-            mCallback.onPostDhcpAction();
-            log("onPostDhcpAction()");
-        }
-        @Override
-        public void onNewDhcpResults(DhcpResults dhcpResults) {
-            mCallback.onNewDhcpResults(dhcpResults);
-            log("onNewDhcpResults({" + dhcpResults + "})");
-        }
-        @Override
-        public void onProvisioningSuccess(LinkProperties newLp) {
-            mCallback.onProvisioningSuccess(newLp);
-            log("onProvisioningSuccess({" + newLp + "})");
-        }
-        @Override
-        public void onProvisioningFailure(LinkProperties newLp) {
-            mCallback.onProvisioningFailure(newLp);
-            log("onProvisioningFailure({" + newLp + "})");
-        }
-        @Override
-        public void onLinkPropertiesChange(LinkProperties newLp) {
-            mCallback.onLinkPropertiesChange(newLp);
-            log("onLinkPropertiesChange({" + newLp + "})");
-        }
-        @Override
-        public void onReachabilityLost(String logMsg) {
-            mCallback.onReachabilityLost(logMsg);
-            log("onReachabilityLost(" + logMsg + ")");
-        }
-        @Override
-        public void onQuit() {
-            mCallback.onQuit();
-            log("onQuit()");
-        }
-        @Override
-        public void installPacketFilter(byte[] filter) {
-            mCallback.installPacketFilter(filter);
-            log("installPacketFilter(byte[" + filter.length + "])");
-        }
-        @Override
-        public void setFallbackMulticastFilter(boolean enabled) {
-            mCallback.setFallbackMulticastFilter(enabled);
-            log("setFallbackMulticastFilter(" + enabled + ")");
-        }
-        @Override
-        public void setNeighborDiscoveryOffload(boolean enable) {
-            mCallback.setNeighborDiscoveryOffload(enable);
-            log("setNeighborDiscoveryOffload(" + enable + ")");
-        }
-    }
-
-    /**
-     * This class encapsulates parameters to be passed to
-     * IpManager#startProvisioning(). A defensive copy is made by IpManager
-     * and the values specified herein are in force until IpManager#stop()
-     * is called.
-     *
-     * Example use:
-     *
-     *     final ProvisioningConfiguration config =
-     *             mIpManager.buildProvisioningConfiguration()
-     *                     .withPreDhcpAction()
-     *                     .withProvisioningTimeoutMs(36 * 1000)
-     *                     .build();
-     *     mIpManager.startProvisioning(config);
-     *     ...
-     *     mIpManager.stop();
-     *
-     * The specified provisioning configuration will only be active until
-     * IpManager#stop() is called. Future calls to IpManager#startProvisioning()
-     * must specify the configuration again.
-     */
-    public static class ProvisioningConfiguration {
-        // TODO: Delete this default timeout once those callers that care are
-        // fixed to pass in their preferred timeout.
-        //
-        // We pick 36 seconds so we can send DHCP requests at
-        //
-        //     t=0, t=2, t=6, t=14, t=30
-        //
-        // allowing for 10% jitter.
-        private static final int DEFAULT_TIMEOUT_MS = 36 * 1000;
-
-        public static class Builder {
-            private ProvisioningConfiguration mConfig = new ProvisioningConfiguration();
-
-            public Builder withoutIPv4() {
-                mConfig.mEnableIPv4 = false;
-                return this;
-            }
-
-            public Builder withoutIPv6() {
-                mConfig.mEnableIPv6 = false;
-                return this;
-            }
-
-            public Builder withoutIpReachabilityMonitor() {
-                mConfig.mUsingIpReachabilityMonitor = false;
-                return this;
-            }
-
-            public Builder withPreDhcpAction() {
-                mConfig.mRequestedPreDhcpActionMs = DEFAULT_TIMEOUT_MS;
-                return this;
-            }
-
-            public Builder withPreDhcpAction(int dhcpActionTimeoutMs) {
-                mConfig.mRequestedPreDhcpActionMs = dhcpActionTimeoutMs;
-                return this;
-            }
-
-            public Builder withInitialConfiguration(InitialConfiguration initialConfig) {
-                mConfig.mInitialConfig = initialConfig;
-                return this;
-            }
-
-            public Builder withStaticConfiguration(StaticIpConfiguration staticConfig) {
-                mConfig.mStaticIpConfig = staticConfig;
-                return this;
-            }
-
-            public Builder withApfCapabilities(ApfCapabilities apfCapabilities) {
-                mConfig.mApfCapabilities = apfCapabilities;
-                return this;
-            }
-
-            public Builder withProvisioningTimeoutMs(int timeoutMs) {
-                mConfig.mProvisioningTimeoutMs = timeoutMs;
-                return this;
-            }
-
-            public Builder withIPv6AddrGenModeEUI64() {
-                mConfig.mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_EUI64;
-                return this;
-            }
-
-            public Builder withIPv6AddrGenModeStablePrivacy() {
-                mConfig.mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_STABLE_PRIVACY;
-                return this;
-            }
-
-            public ProvisioningConfiguration build() {
-                return new ProvisioningConfiguration(mConfig);
-            }
-        }
-
-        /* package */ boolean mEnableIPv4 = true;
-        /* package */ boolean mEnableIPv6 = true;
-        /* package */ boolean mUsingIpReachabilityMonitor = true;
-        /* package */ int mRequestedPreDhcpActionMs;
-        /* package */ InitialConfiguration mInitialConfig;
-        /* package */ StaticIpConfiguration mStaticIpConfig;
-        /* package */ ApfCapabilities mApfCapabilities;
-        /* package */ int mProvisioningTimeoutMs = DEFAULT_TIMEOUT_MS;
-        /* package */ int mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_STABLE_PRIVACY;
-
-        public ProvisioningConfiguration() {} // used by Builder
-
-        public ProvisioningConfiguration(ProvisioningConfiguration other) {
-            mEnableIPv4 = other.mEnableIPv4;
-            mEnableIPv6 = other.mEnableIPv6;
-            mUsingIpReachabilityMonitor = other.mUsingIpReachabilityMonitor;
-            mRequestedPreDhcpActionMs = other.mRequestedPreDhcpActionMs;
-            mInitialConfig = InitialConfiguration.copy(other.mInitialConfig);
-            mStaticIpConfig = other.mStaticIpConfig;
-            mApfCapabilities = other.mApfCapabilities;
-            mProvisioningTimeoutMs = other.mProvisioningTimeoutMs;
-        }
-
-        @Override
-        public String toString() {
-            return new StringJoiner(", ", getClass().getSimpleName() + "{", "}")
-                    .add("mEnableIPv4: " + mEnableIPv4)
-                    .add("mEnableIPv6: " + mEnableIPv6)
-                    .add("mUsingIpReachabilityMonitor: " + mUsingIpReachabilityMonitor)
-                    .add("mRequestedPreDhcpActionMs: " + mRequestedPreDhcpActionMs)
-                    .add("mInitialConfig: " + mInitialConfig)
-                    .add("mStaticIpConfig: " + mStaticIpConfig)
-                    .add("mApfCapabilities: " + mApfCapabilities)
-                    .add("mProvisioningTimeoutMs: " + mProvisioningTimeoutMs)
-                    .add("mIPv6AddrGenMode: " + mIPv6AddrGenMode)
-                    .toString();
-        }
-
-        public boolean isValid() {
-            return (mInitialConfig == null) || mInitialConfig.isValid();
-        }
-    }
-
-    public static class InitialConfiguration {
-        public final Set<LinkAddress> ipAddresses = new HashSet<>();
-        public final Set<IpPrefix> directlyConnectedRoutes = new HashSet<>();
-        public final Set<InetAddress> dnsServers = new HashSet<>();
-        public Inet4Address gateway; // WiFi legacy behavior with static ipv4 config
-
-        public static InitialConfiguration copy(InitialConfiguration config) {
-            if (config == null) {
-                return null;
-            }
-            InitialConfiguration configCopy = new InitialConfiguration();
-            configCopy.ipAddresses.addAll(config.ipAddresses);
-            configCopy.directlyConnectedRoutes.addAll(config.directlyConnectedRoutes);
-            configCopy.dnsServers.addAll(config.dnsServers);
-            return configCopy;
-        }
-
-        @Override
-        public String toString() {
-            return String.format(
-                    "InitialConfiguration(IPs: {%s}, prefixes: {%s}, DNS: {%s}, v4 gateway: %s)",
-                    join(", ", ipAddresses), join(", ", directlyConnectedRoutes),
-                    join(", ", dnsServers), gateway);
-        }
-
-        public boolean isValid() {
-            if (ipAddresses.isEmpty()) {
-                return false;
-            }
-
-            // For every IP address, there must be at least one prefix containing that address.
-            for (LinkAddress addr : ipAddresses) {
-                if (!any(directlyConnectedRoutes, (p) -> p.contains(addr.getAddress()))) {
-                    return false;
-                }
-            }
-            // For every dns server, there must be at least one prefix containing that address.
-            for (InetAddress addr : dnsServers) {
-                if (!any(directlyConnectedRoutes, (p) -> p.contains(addr))) {
-                    return false;
-                }
-            }
-            // All IPv6 LinkAddresses have an RFC7421-suitable prefix length
-            // (read: compliant with RFC4291#section2.5.4).
-            if (any(ipAddresses, not(InitialConfiguration::isPrefixLengthCompliant))) {
-                return false;
-            }
-            // If directlyConnectedRoutes contains an IPv6 default route
-            // then ipAddresses MUST contain at least one non-ULA GUA.
-            if (any(directlyConnectedRoutes, InitialConfiguration::isIPv6DefaultRoute)
-                    && all(ipAddresses, not(InitialConfiguration::isIPv6GUA))) {
-                return false;
-            }
-            // The prefix length of routes in directlyConnectedRoutes be within reasonable
-            // bounds for IPv6: /48-/64 just as we’d accept in RIOs.
-            if (any(directlyConnectedRoutes, not(InitialConfiguration::isPrefixLengthCompliant))) {
-                return false;
-            }
-            // There no more than one IPv4 address
-            if (ipAddresses.stream().filter(Inet4Address.class::isInstance).count() > 1) {
-                return false;
-            }
-
-            return true;
-        }
-
-        /**
-         * @return true if the given list of addressess and routes satisfies provisioning for this
-         * InitialConfiguration. LinkAddresses and RouteInfo objects are not compared with equality
-         * because addresses and routes seen by Netlink will contain additional fields like flags,
-         * interfaces, and so on. If this InitialConfiguration has no IP address specified, the
-         * provisioning check always fails.
-         *
-         * If the given list of routes is null, only addresses are taken into considerations.
-         */
-        public boolean isProvisionedBy(List<LinkAddress> addresses, List<RouteInfo> routes) {
-            if (ipAddresses.isEmpty()) {
-                return false;
-            }
-
-            for (LinkAddress addr : ipAddresses) {
-                if (!any(addresses, (addrSeen) -> addr.isSameAddressAs(addrSeen))) {
-                    return false;
-                }
-            }
-
-            if (routes != null) {
-                for (IpPrefix prefix : directlyConnectedRoutes) {
-                    if (!any(routes, (routeSeen) -> isDirectlyConnectedRoute(routeSeen, prefix))) {
-                        return false;
-                    }
-                }
-            }
-
-            return true;
-        }
-
-        private static boolean isDirectlyConnectedRoute(RouteInfo route, IpPrefix prefix) {
-            return !route.hasGateway() && prefix.equals(route.getDestination());
-        }
-
-        private static boolean isPrefixLengthCompliant(LinkAddress addr) {
-            return addr.isIPv4() || isCompliantIPv6PrefixLength(addr.getPrefixLength());
-        }
-
-        private static boolean isPrefixLengthCompliant(IpPrefix prefix) {
-            return prefix.isIPv4() || isCompliantIPv6PrefixLength(prefix.getPrefixLength());
-        }
-
-        private static boolean isCompliantIPv6PrefixLength(int prefixLength) {
-            return (NetworkConstants.RFC6177_MIN_PREFIX_LENGTH <= prefixLength)
-                    && (prefixLength <= NetworkConstants.RFC7421_PREFIX_LENGTH);
-        }
-
-        private static boolean isIPv6DefaultRoute(IpPrefix prefix) {
-            return prefix.getAddress().equals(Inet6Address.ANY);
-        }
-
-        private static boolean isIPv6GUA(LinkAddress addr) {
-            return addr.isIPv6() && addr.isGlobalPreferred();
-        }
-    }
-
-    public static final String DUMP_ARG = "ipmanager";
-    public static final String DUMP_ARG_CONFIRM = "confirm";
-
-    private static final int CMD_STOP = 1;
-    private static final int CMD_START = 2;
-    private static final int CMD_CONFIRM = 3;
-    private static final int EVENT_PRE_DHCP_ACTION_COMPLETE = 4;
-    // Sent by NetlinkTracker to communicate netlink events.
-    private static final int EVENT_NETLINK_LINKPROPERTIES_CHANGED = 5;
-    private static final int CMD_UPDATE_TCP_BUFFER_SIZES = 6;
-    private static final int CMD_UPDATE_HTTP_PROXY = 7;
-    private static final int CMD_SET_MULTICAST_FILTER = 8;
-    private static final int EVENT_PROVISIONING_TIMEOUT = 9;
-    private static final int EVENT_DHCPACTION_TIMEOUT = 10;
-
-    private static final int MAX_LOG_RECORDS = 500;
-    private static final int MAX_PACKET_RECORDS = 100;
-
-    private static final boolean NO_CALLBACKS = false;
-    private static final boolean SEND_CALLBACKS = true;
-
-    // This must match the interface prefix in clatd.c.
-    // TODO: Revert this hack once IpManager and Nat464Xlat work in concert.
-    private static final String CLAT_PREFIX = "v4-";
-
-    private final State mStoppedState = new StoppedState();
-    private final State mStoppingState = new StoppingState();
-    private final State mStartedState = new StartedState();
-    private final State mRunningState = new RunningState();
-
-    private final String mTag;
-    private final Context mContext;
-    private final String mInterfaceName;
-    private final String mClatInterfaceName;
-    @VisibleForTesting
-    protected final Callback mCallback;
-    private final INetworkManagementService mNwService;
-    private final NetlinkTracker mNetlinkTracker;
-    private final WakeupMessage mProvisioningTimeoutAlarm;
-    private final WakeupMessage mDhcpActionTimeoutAlarm;
-    private final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
-    private final SharedLog mLog;
-    private final LocalLog mConnectivityPacketLog;
-    private final MessageHandlingLogger mMsgStateLogger;
-    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
-    private final INetd mNetd;
-
-    private NetworkInterface mNetworkInterface;
-
-    /**
-     * Non-final member variables accessed only from within our StateMachine.
-     */
-    private LinkProperties mLinkProperties;
-    private ProvisioningConfiguration mConfiguration;
-    private IpReachabilityMonitor mIpReachabilityMonitor;
-    private DhcpClient mDhcpClient;
-    private DhcpResults mDhcpResults;
-    private String mTcpBufferSizes;
-    private ProxyInfo mHttpProxy;
-    private ApfFilter mApfFilter;
-    private boolean mMulticastFiltering;
-    private long mStartTimeMillis;
-
     public IpManager(Context context, String ifName, Callback callback) {
         this(context, ifName, callback, INetworkManagementService.Stub.asInterface(
                 ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)),
                 NetdService.getInstance());
     }
 
-    /**
-     * An expanded constructor, useful for dependency injection.
-     * TODO: migrate all test users to mock IpManager directly and remove this ctor.
-     */
     public IpManager(Context context, String ifName, Callback callback,
             INetworkManagementService nwService) {
         this(context, ifName, callback, nwService, NetdService.getInstance());
     }
 
     @VisibleForTesting
-    IpManager(Context context, String ifName, Callback callback,
+    public IpManager(Context context, String ifName, Callback callback,
             INetworkManagementService nwService, INetd netd) {
-        super(IpManager.class.getSimpleName() + "." + ifName);
-        mTag = getName();
-
-        mContext = context;
-        mInterfaceName = ifName;
-        mClatInterfaceName = CLAT_PREFIX + ifName;
-        mCallback = new LoggingCallbackWrapper(callback);
-        mNwService = nwService;
-        mNetd = netd;
-
-        mLog = new SharedLog(MAX_LOG_RECORDS, mTag);
-        mConnectivityPacketLog = new LocalLog(MAX_PACKET_RECORDS);
-        mMsgStateLogger = new MessageHandlingLogger();
-
-        mNetlinkTracker = new NetlinkTracker(
-                mInterfaceName,
-                new NetlinkTracker.Callback() {
-                    @Override
-                    public void update() {
-                        sendMessage(EVENT_NETLINK_LINKPROPERTIES_CHANGED);
-                    }
-                }) {
-            @Override
-            public void interfaceAdded(String iface) {
-                super.interfaceAdded(iface);
-                if (mClatInterfaceName.equals(iface)) {
-                    mCallback.setNeighborDiscoveryOffload(false);
-                } else if (!mInterfaceName.equals(iface)) {
-                    return;
-                }
-
-                final String msg = "interfaceAdded(" + iface +")";
-                logMsg(msg);
-            }
-
-            @Override
-            public void interfaceRemoved(String iface) {
-                super.interfaceRemoved(iface);
-                // TODO: Also observe mInterfaceName going down and take some
-                // kind of appropriate action.
-                if (mClatInterfaceName.equals(iface)) {
-                    // TODO: consider sending a message to the IpManager main
-                    // StateMachine thread, in case "NDO enabled" state becomes
-                    // tied to more things that 464xlat operation.
-                    mCallback.setNeighborDiscoveryOffload(true);
-                } else if (!mInterfaceName.equals(iface)) {
-                    return;
-                }
-
-                final String msg = "interfaceRemoved(" + iface +")";
-                logMsg(msg);
-            }
-
-            private void logMsg(String msg) {
-                Log.d(mTag, msg);
-                getHandler().post(() -> { mLog.log("OBSERVED " + msg); });
-            }
-        };
-
-        mLinkProperties = new LinkProperties();
-        mLinkProperties.setInterfaceName(mInterfaceName);
-
-        mMultinetworkPolicyTracker = new MultinetworkPolicyTracker(mContext, getHandler(),
-                () -> { mLog.log("OBSERVED AvoidBadWifi changed"); });
-
-        mProvisioningTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
-                mTag + ".EVENT_PROVISIONING_TIMEOUT", EVENT_PROVISIONING_TIMEOUT);
-        mDhcpActionTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
-                mTag + ".EVENT_DHCPACTION_TIMEOUT", EVENT_DHCPACTION_TIMEOUT);
-
-        // Anything the StateMachine may access must have been instantiated
-        // before this point.
-        configureAndStartStateMachine();
-
-        // Anything that may send messages to the StateMachine must only be
-        // configured to do so after the StateMachine has started (above).
-        startStateMachineUpdaters();
-    }
-
-    private void configureAndStartStateMachine() {
-        addState(mStoppedState);
-        addState(mStartedState);
-            addState(mRunningState, mStartedState);
-        addState(mStoppingState);
-
-        setInitialState(mStoppedState);
-
-        super.start();
-    }
-
-    private void startStateMachineUpdaters() {
-        try {
-            mNwService.registerObserver(mNetlinkTracker);
-        } catch (RemoteException e) {
-            logError("Couldn't register NetlinkTracker: %s", e);
-        }
-
-        mMultinetworkPolicyTracker.start();
-    }
-
-    @Override
-    protected void onQuitting() {
-        mCallback.onQuit();
-    }
-
-    // Shut down this IpManager instance altogether.
-    public void shutdown() {
-        stop();
-        mMultinetworkPolicyTracker.shutdown();
-        quit();
-    }
-
-    public static ProvisioningConfiguration.Builder buildProvisioningConfiguration() {
-        return new ProvisioningConfiguration.Builder();
+        super(context, ifName, callback, nwService, netd);
     }
 
     public void startProvisioning(ProvisioningConfiguration req) {
-        if (!req.isValid()) {
-            doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
-            return;
-        }
-
-        getNetworkInterface();
-
-        mCallback.setNeighborDiscoveryOffload(true);
-        sendMessage(CMD_START, new ProvisioningConfiguration(req));
-    }
-
-    // TODO: Delete this.
-    public void startProvisioning(StaticIpConfiguration staticIpConfig) {
-        startProvisioning(buildProvisioningConfiguration()
-                .withStaticConfiguration(staticIpConfig)
-                .build());
-    }
-
-    public void startProvisioning() {
-        startProvisioning(new ProvisioningConfiguration());
-    }
-
-    public void stop() {
-        sendMessage(CMD_STOP);
-    }
-
-    public void confirmConfiguration() {
-        sendMessage(CMD_CONFIRM);
-    }
-
-    public void completedPreDhcpAction() {
-        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
-    }
-
-    /**
-     * Set the TCP buffer sizes to use.
-     *
-     * This may be called, repeatedly, at any time before or after a call to
-     * #startProvisioning(). The setting is cleared upon calling #stop().
-     */
-    public void setTcpBufferSizes(String tcpBufferSizes) {
-        sendMessage(CMD_UPDATE_TCP_BUFFER_SIZES, tcpBufferSizes);
-    }
-
-    /**
-     * Set the HTTP Proxy configuration to use.
-     *
-     * This may be called, repeatedly, at any time before or after a call to
-     * #startProvisioning(). The setting is cleared upon calling #stop().
-     */
-    public void setHttpProxy(ProxyInfo proxyInfo) {
-        sendMessage(CMD_UPDATE_HTTP_PROXY, proxyInfo);
-    }
-
-    /**
-     * Enable or disable the multicast filter.  Attempts to use APF to accomplish the filtering,
-     * if not, Callback.setFallbackMulticastFilter() is called.
-     */
-    public void setMulticastFilter(boolean enabled) {
-        sendMessage(CMD_SET_MULTICAST_FILTER, enabled);
-    }
-
-    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        if (args != null && args.length > 0 && DUMP_ARG_CONFIRM.equals(args[0])) {
-            // Execute confirmConfiguration() and take no further action.
-            confirmConfiguration();
-            return;
-        }
-
-        // Thread-unsafe access to mApfFilter but just used for debugging.
-        final ApfFilter apfFilter = mApfFilter;
-        final ProvisioningConfiguration provisioningConfig = mConfiguration;
-        final ApfCapabilities apfCapabilities = (provisioningConfig != null)
-                ? provisioningConfig.mApfCapabilities : null;
-
-        IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
-        pw.println(mTag + " APF dump:");
-        pw.increaseIndent();
-        if (apfFilter != null) {
-            apfFilter.dump(pw);
-        } else {
-            pw.print("No active ApfFilter; ");
-            if (provisioningConfig == null) {
-                pw.println("IpManager not yet started.");
-            } else if (apfCapabilities == null || apfCapabilities.apfVersionSupported == 0) {
-                pw.println("Hardware does not support APF.");
-            } else {
-                pw.println("ApfFilter not yet started, APF capabilities: " + apfCapabilities);
-            }
-        }
-        pw.decreaseIndent();
-
-        pw.println();
-        pw.println(mTag + " current ProvisioningConfiguration:");
-        pw.increaseIndent();
-        pw.println(Objects.toString(provisioningConfig, "N/A"));
-        pw.decreaseIndent();
-
-        pw.println();
-        pw.println(mTag + " StateMachine dump:");
-        pw.increaseIndent();
-        mLog.dump(fd, pw, args);
-        pw.decreaseIndent();
-
-        pw.println();
-        pw.println(mTag + " connectivity packet log:");
-        pw.println();
-        pw.println("Debug with python and scapy via:");
-        pw.println("shell$ python");
-        pw.println(">>> from scapy import all as scapy");
-        pw.println(">>> scapy.Ether(\"<paste_hex_string>\".decode(\"hex\")).show2()");
-        pw.println();
-
-        pw.increaseIndent();
-        mConnectivityPacketLog.readOnlyLocalLog().dump(fd, pw, args);
-        pw.decreaseIndent();
-    }
-
-
-    /**
-     * Internals.
-     */
-
-    @Override
-    protected String getWhatToString(int what) {
-        return sWhatToString.get(what, "UNKNOWN: " + Integer.toString(what));
-    }
-
-    @Override
-    protected String getLogRecString(Message msg) {
-        final String logLine = String.format(
-                "%s/%d %d %d %s [%s]",
-                mInterfaceName, mNetworkInterface == null ? -1 : mNetworkInterface.getIndex(),
-                msg.arg1, msg.arg2, Objects.toString(msg.obj), mMsgStateLogger);
-
-        final String richerLogLine = getWhatToString(msg.what) + " " + logLine;
-        mLog.log(richerLogLine);
-        if (VDBG) {
-            Log.d(mTag, richerLogLine);
-        }
-
-        mMsgStateLogger.reset();
-        return logLine;
-    }
-
-    @Override
-    protected boolean recordLogRec(Message msg) {
-        // Don't log EVENT_NETLINK_LINKPROPERTIES_CHANGED. They can be noisy,
-        // and we already log any LinkProperties change that results in an
-        // invocation of IpManager.Callback#onLinkPropertiesChange().
-        final boolean shouldLog = (msg.what != EVENT_NETLINK_LINKPROPERTIES_CHANGED);
-        if (!shouldLog) {
-            mMsgStateLogger.reset();
-        }
-        return shouldLog;
-    }
-
-    private void logError(String fmt, Object... args) {
-        final String msg = "ERROR " + String.format(fmt, args);
-        Log.e(mTag, msg);
-        mLog.log(msg);
-    }
-
-    private void getNetworkInterface() {
-        try {
-            mNetworkInterface = NetworkInterface.getByName(mInterfaceName);
-        } catch (SocketException | NullPointerException e) {
-            // TODO: throw new IllegalStateException.
-            logError("Failed to get interface object: %s", e);
-        }
-    }
-
-    // This needs to be called with care to ensure that our LinkProperties
-    // are in sync with the actual LinkProperties of the interface. For example,
-    // we should only call this if we know for sure that there are no IP addresses
-    // assigned to the interface, etc.
-    private void resetLinkProperties() {
-        mNetlinkTracker.clearLinkProperties();
-        mConfiguration = null;
-        mDhcpResults = null;
-        mTcpBufferSizes = "";
-        mHttpProxy = null;
-
-        mLinkProperties = new LinkProperties();
-        mLinkProperties.setInterfaceName(mInterfaceName);
-    }
-
-    private void recordMetric(final int type) {
-        if (mStartTimeMillis <= 0) { Log.wtf(mTag, "Start time undefined!"); }
-        final long duration = SystemClock.elapsedRealtime() - mStartTimeMillis;
-        mMetricsLog.log(mInterfaceName, new IpManagerEvent(type, duration));
-    }
-
-    // For now: use WifiStateMachine's historical notion of provisioned.
-    @VisibleForTesting
-    static boolean isProvisioned(LinkProperties lp, InitialConfiguration config) {
-        // For historical reasons, we should connect even if all we have is
-        // an IPv4 address and nothing else.
-        if (lp.hasIPv4Address() || lp.isProvisioned()) {
-            return true;
-        }
-        if (config == null) {
-            return false;
-        }
-
-        // When an InitialConfiguration is specified, ignore any difference with previous
-        // properties and instead check if properties observed match the desired properties.
-        return config.isProvisionedBy(lp.getLinkAddresses(), lp.getRoutes());
-    }
-
-    // TODO: Investigate folding all this into the existing static function
-    // LinkProperties.compareProvisioning() or some other single function that
-    // takes two LinkProperties objects and returns a ProvisioningChange
-    // object that is a correct and complete assessment of what changed, taking
-    // account of the asymmetries described in the comments in this function.
-    // Then switch to using it everywhere (IpReachabilityMonitor, etc.).
-    private ProvisioningChange compareProvisioning(LinkProperties oldLp, LinkProperties newLp) {
-        ProvisioningChange delta;
-        InitialConfiguration config = mConfiguration != null ? mConfiguration.mInitialConfig : null;
-        final boolean wasProvisioned = isProvisioned(oldLp, config);
-        final boolean isProvisioned = isProvisioned(newLp, config);
-
-        if (!wasProvisioned && isProvisioned) {
-            delta = ProvisioningChange.GAINED_PROVISIONING;
-        } else if (wasProvisioned && isProvisioned) {
-            delta = ProvisioningChange.STILL_PROVISIONED;
-        } else if (!wasProvisioned && !isProvisioned) {
-            delta = ProvisioningChange.STILL_NOT_PROVISIONED;
-        } else {
-            // (wasProvisioned && !isProvisioned)
-            //
-            // Note that this is true even if we lose a configuration element
-            // (e.g., a default gateway) that would not be required to advance
-            // into provisioned state. This is intended: if we have a default
-            // router and we lose it, that's a sure sign of a problem, but if
-            // we connect to a network with no IPv4 DNS servers, we consider
-            // that to be a network without DNS servers and connect anyway.
-            //
-            // See the comment below.
-            delta = ProvisioningChange.LOST_PROVISIONING;
-        }
-
-        final boolean lostIPv6 = oldLp.isIPv6Provisioned() && !newLp.isIPv6Provisioned();
-        final boolean lostIPv4Address = oldLp.hasIPv4Address() && !newLp.hasIPv4Address();
-        final boolean lostIPv6Router = oldLp.hasIPv6DefaultRoute() && !newLp.hasIPv6DefaultRoute();
-
-        // If bad wifi avoidance is disabled, then ignore IPv6 loss of
-        // provisioning. Otherwise, when a hotspot that loses Internet
-        // access sends out a 0-lifetime RA to its clients, the clients
-        // will disconnect and then reconnect, avoiding the bad hotspot,
-        // instead of getting stuck on the bad hotspot. http://b/31827713 .
-        //
-        // This is incorrect because if the hotspot then regains Internet
-        // access with a different prefix, TCP connections on the
-        // deprecated addresses will remain stuck.
-        //
-        // Note that we can still be disconnected by IpReachabilityMonitor
-        // if the IPv6 default gateway (but not the IPv6 DNS servers; see
-        // accompanying code in IpReachabilityMonitor) is unreachable.
-        final boolean ignoreIPv6ProvisioningLoss = !mMultinetworkPolicyTracker.getAvoidBadWifi();
-
-        // Additionally:
-        //
-        // Partial configurations (e.g., only an IPv4 address with no DNS
-        // servers and no default route) are accepted as long as DHCPv4
-        // succeeds. On such a network, isProvisioned() will always return
-        // false, because the configuration is not complete, but we want to
-        // connect anyway. It might be a disconnected network such as a
-        // Chromecast or a wireless printer, for example.
-        //
-        // Because on such a network isProvisioned() will always return false,
-        // delta will never be LOST_PROVISIONING. So check for loss of
-        // provisioning here too.
-        if (lostIPv4Address || (lostIPv6 && !ignoreIPv6ProvisioningLoss)) {
-            delta = ProvisioningChange.LOST_PROVISIONING;
-        }
-
-        // Additionally:
-        //
-        // If the previous link properties had a global IPv6 address and an
-        // IPv6 default route then also consider the loss of that default route
-        // to be a loss of provisioning. See b/27962810.
-        if (oldLp.hasGlobalIPv6Address() && (lostIPv6Router && !ignoreIPv6ProvisioningLoss)) {
-            delta = ProvisioningChange.LOST_PROVISIONING;
-        }
-
-        return delta;
-    }
-
-    private void dispatchCallback(ProvisioningChange delta, LinkProperties newLp) {
-        switch (delta) {
-            case GAINED_PROVISIONING:
-                if (VDBG) { Log.d(mTag, "onProvisioningSuccess()"); }
-                recordMetric(IpManagerEvent.PROVISIONING_OK);
-                mCallback.onProvisioningSuccess(newLp);
-                break;
-
-            case LOST_PROVISIONING:
-                if (VDBG) { Log.d(mTag, "onProvisioningFailure()"); }
-                recordMetric(IpManagerEvent.PROVISIONING_FAIL);
-                mCallback.onProvisioningFailure(newLp);
-                break;
-
-            default:
-                if (VDBG) { Log.d(mTag, "onLinkPropertiesChange()"); }
-                mCallback.onLinkPropertiesChange(newLp);
-                break;
-        }
-    }
-
-    // Updates all IpManager-related state concerned with LinkProperties.
-    // Returns a ProvisioningChange for possibly notifying other interested
-    // parties that are not fronted by IpManager.
-    private ProvisioningChange setLinkProperties(LinkProperties newLp) {
-        if (mApfFilter != null) {
-            mApfFilter.setLinkProperties(newLp);
-        }
-        if (mIpReachabilityMonitor != null) {
-            mIpReachabilityMonitor.updateLinkProperties(newLp);
-        }
-
-        ProvisioningChange delta = compareProvisioning(mLinkProperties, newLp);
-        mLinkProperties = new LinkProperties(newLp);
-
-        if (delta == ProvisioningChange.GAINED_PROVISIONING) {
-            // TODO: Add a proper ProvisionedState and cancel the alarm in
-            // its enter() method.
-            mProvisioningTimeoutAlarm.cancel();
-        }
-
-        return delta;
-    }
-
-    private LinkProperties assembleLinkProperties() {
-        // [1] Create a new LinkProperties object to populate.
-        LinkProperties newLp = new LinkProperties();
-        newLp.setInterfaceName(mInterfaceName);
-
-        // [2] Pull in data from netlink:
-        //         - IPv4 addresses
-        //         - IPv6 addresses
-        //         - IPv6 routes
-        //         - IPv6 DNS servers
-        //
-        // N.B.: this is fundamentally race-prone and should be fixed by
-        // changing NetlinkTracker from a hybrid edge/level model to an
-        // edge-only model, or by giving IpManager its own netlink socket(s)
-        // so as to track all required information directly.
-        LinkProperties netlinkLinkProperties = mNetlinkTracker.getLinkProperties();
-        newLp.setLinkAddresses(netlinkLinkProperties.getLinkAddresses());
-        for (RouteInfo route : netlinkLinkProperties.getRoutes()) {
-            newLp.addRoute(route);
-        }
-        addAllReachableDnsServers(newLp, netlinkLinkProperties.getDnsServers());
-
-        // [3] Add in data from DHCPv4, if available.
-        //
-        // mDhcpResults is never shared with any other owner so we don't have
-        // to worry about concurrent modification.
-        if (mDhcpResults != null) {
-            for (RouteInfo route : mDhcpResults.getRoutes(mInterfaceName)) {
-                newLp.addRoute(route);
-            }
-            addAllReachableDnsServers(newLp, mDhcpResults.dnsServers);
-            newLp.setDomains(mDhcpResults.domains);
-
-            if (mDhcpResults.mtu != 0) {
-                newLp.setMtu(mDhcpResults.mtu);
-            }
-        }
-
-        // [4] Add in TCP buffer sizes and HTTP Proxy config, if available.
-        if (!TextUtils.isEmpty(mTcpBufferSizes)) {
-            newLp.setTcpBufferSizes(mTcpBufferSizes);
-        }
-        if (mHttpProxy != null) {
-            newLp.setHttpProxy(mHttpProxy);
-        }
-
-        // [5] Add data from InitialConfiguration
-        if (mConfiguration != null && mConfiguration.mInitialConfig != null) {
-            InitialConfiguration config = mConfiguration.mInitialConfig;
-            // Add InitialConfiguration routes and dns server addresses once all addresses
-            // specified in the InitialConfiguration have been observed with Netlink.
-            if (config.isProvisionedBy(newLp.getLinkAddresses(), null)) {
-                for (IpPrefix prefix : config.directlyConnectedRoutes) {
-                    newLp.addRoute(new RouteInfo(prefix, null, mInterfaceName));
-                }
-            }
-            addAllReachableDnsServers(newLp, config.dnsServers);
-        }
-        final LinkProperties oldLp = mLinkProperties;
-        if (VDBG) {
-            Log.d(mTag, String.format("Netlink-seen LPs: %s, new LPs: %s; old LPs: %s",
-                    netlinkLinkProperties, newLp, oldLp));
-        }
-
-        // TODO: also learn via netlink routes specified by an InitialConfiguration and specified
-        // from a static IP v4 config instead of manually patching them in in steps [3] and [5].
-        return newLp;
-    }
-
-    private static void addAllReachableDnsServers(
-            LinkProperties lp, Iterable<InetAddress> dnses) {
-        // TODO: Investigate deleting this reachability check.  We should be
-        // able to pass everything down to netd and let netd do evaluation
-        // and RFC6724-style sorting.
-        for (InetAddress dns : dnses) {
-            if (!dns.isAnyLocalAddress() && lp.isReachable(dns)) {
-                lp.addDnsServer(dns);
-            }
-        }
-    }
-
-    // Returns false if we have lost provisioning, true otherwise.
-    private boolean handleLinkPropertiesUpdate(boolean sendCallbacks) {
-        final LinkProperties newLp = assembleLinkProperties();
-        if (Objects.equals(newLp, mLinkProperties)) {
-            return true;
-        }
-        final ProvisioningChange delta = setLinkProperties(newLp);
-        if (sendCallbacks) {
-            dispatchCallback(delta, newLp);
-        }
-        return (delta != ProvisioningChange.LOST_PROVISIONING);
-    }
-
-    private boolean setIPv4Address(LinkAddress address) {
-        final InterfaceConfiguration ifcg = new InterfaceConfiguration();
-        ifcg.setLinkAddress(address);
-        try {
-            mNwService.setInterfaceConfig(mInterfaceName, ifcg);
-            if (VDBG) Log.d(mTag, "IPv4 configuration succeeded");
-        } catch (IllegalStateException | RemoteException e) {
-            logError("IPv4 configuration failed: %s", e);
-            return false;
-        }
-        return true;
-    }
-
-    private void clearIPv4Address() {
-        try {
-            final InterfaceConfiguration ifcg = new InterfaceConfiguration();
-            ifcg.setLinkAddress(new LinkAddress("0.0.0.0/0"));
-            mNwService.setInterfaceConfig(mInterfaceName, ifcg);
-        } catch (IllegalStateException | RemoteException e) {
-            logError("Failed to clear IPv4 address on interface %s: %s", mInterfaceName, e);
-        }
-    }
-
-    private void handleIPv4Success(DhcpResults dhcpResults) {
-        mDhcpResults = new DhcpResults(dhcpResults);
-        final LinkProperties newLp = assembleLinkProperties();
-        final ProvisioningChange delta = setLinkProperties(newLp);
-
-        if (VDBG) {
-            Log.d(mTag, "onNewDhcpResults(" + Objects.toString(dhcpResults) + ")");
-        }
-        mCallback.onNewDhcpResults(dhcpResults);
-        dispatchCallback(delta, newLp);
-    }
-
-    private void handleIPv4Failure() {
-        // TODO: Investigate deleting this clearIPv4Address() call.
-        //
-        // DhcpClient will send us CMD_CLEAR_LINKADDRESS in all circumstances
-        // that could trigger a call to this function. If we missed handling
-        // that message in StartedState for some reason we would still clear
-        // any addresses upon entry to StoppedState.
-        clearIPv4Address();
-        mDhcpResults = null;
-        if (VDBG) { Log.d(mTag, "onNewDhcpResults(null)"); }
-        mCallback.onNewDhcpResults(null);
-
-        handleProvisioningFailure();
-    }
-
-    private void handleProvisioningFailure() {
-        final LinkProperties newLp = assembleLinkProperties();
-        ProvisioningChange delta = setLinkProperties(newLp);
-        // If we've gotten here and we're still not provisioned treat that as
-        // a total loss of provisioning.
-        //
-        // Either (a) static IP configuration failed or (b) DHCPv4 failed AND
-        // there was no usable IPv6 obtained before a non-zero provisioning
-        // timeout expired.
-        //
-        // Regardless: GAME OVER.
-        if (delta == ProvisioningChange.STILL_NOT_PROVISIONED) {
-            delta = ProvisioningChange.LOST_PROVISIONING;
-        }
-
-        dispatchCallback(delta, newLp);
-        if (delta == ProvisioningChange.LOST_PROVISIONING) {
-            transitionTo(mStoppingState);
-        }
-    }
-
-    private void doImmediateProvisioningFailure(int failureType) {
-        logError("onProvisioningFailure(): %s", failureType);
-        recordMetric(failureType);
-        mCallback.onProvisioningFailure(new LinkProperties(mLinkProperties));
-    }
-
-    private boolean startIPv4() {
-        // If we have a StaticIpConfiguration attempt to apply it and
-        // handle the result accordingly.
-        if (mConfiguration.mStaticIpConfig != null) {
-            if (setIPv4Address(mConfiguration.mStaticIpConfig.ipAddress)) {
-                handleIPv4Success(new DhcpResults(mConfiguration.mStaticIpConfig));
-            } else {
-                return false;
-            }
-        } else {
-            // Start DHCPv4.
-            mDhcpClient = DhcpClient.makeDhcpClient(mContext, IpManager.this, mInterfaceName);
-            mDhcpClient.registerForPreDhcpNotification();
-            mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP);
-        }
-
-        return true;
-    }
-
-    private void setIPv6AddrGenModeIfSupported() throws RemoteException {
-        try {
-            mNwService.setIPv6AddrGenMode(mInterfaceName, mConfiguration.mIPv6AddrGenMode);
-        } catch (ServiceSpecificException e) {
-            if (e.errorCode != OsConstants.EOPNOTSUPP) {
-                logError("Unable to set IPv6 addrgen mode: %s", e);
-            }
-        }
-    }
-
-    private boolean startIPv6() {
-        // Set privacy extensions.
-        try {
-            mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
-
-            setIPv6AddrGenModeIfSupported();
-            mNwService.enableIpv6(mInterfaceName);
-        } catch (IllegalStateException | RemoteException | ServiceSpecificException e) {
-            logError("Unable to change interface settings: %s", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    private boolean applyInitialConfig(InitialConfiguration config) {
-        if (mNetd == null) {
-            logError("tried to add %s to %s but INetd was null", config, mInterfaceName);
-            return false;
-        }
-
-        // TODO: also support specifying a static IPv4 configuration in InitialConfiguration.
-        for (LinkAddress addr : findAll(config.ipAddresses, LinkAddress::isIPv6)) {
-            try {
-                mNetd.interfaceAddAddress(
-                        mInterfaceName, addr.getAddress().getHostAddress(), addr.getPrefixLength());
-            } catch (ServiceSpecificException | RemoteException e) {
-                logError("failed to add %s to %s: %s", addr, mInterfaceName, e);
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    private boolean startIpReachabilityMonitor() {
-        try {
-            mIpReachabilityMonitor = new IpReachabilityMonitor(
-                    mContext,
-                    mInterfaceName,
-                    mLog,
-                    new IpReachabilityMonitor.Callback() {
-                        @Override
-                        public void notifyLost(InetAddress ip, String logMsg) {
-                            mCallback.onReachabilityLost(logMsg);
-                        }
-                    },
-                    mMultinetworkPolicyTracker);
-        } catch (IllegalArgumentException iae) {
-            // Failed to start IpReachabilityMonitor. Log it and call
-            // onProvisioningFailure() immediately.
-            //
-            // See http://b/31038971.
-            logError("IpReachabilityMonitor failure: %s", iae);
-            mIpReachabilityMonitor = null;
-        }
-
-        return (mIpReachabilityMonitor != null);
-    }
-
-    private void stopAllIP() {
-        // We don't need to worry about routes, just addresses, because:
-        //     - disableIpv6() will clear autoconf IPv6 routes as well, and
-        //     - we don't get IPv4 routes from netlink
-        // so we neither react to nor need to wait for changes in either.
-
-        try {
-            mNwService.disableIpv6(mInterfaceName);
-        } catch (Exception e) {
-            logError("Failed to disable IPv6: %s", e);
-        }
-
-        try {
-            mNwService.clearInterfaceAddresses(mInterfaceName);
-        } catch (Exception e) {
-            logError("Failed to clear addresses: %s", e);
-        }
-    }
-
-    class StoppedState extends State {
-        @Override
-        public void enter() {
-            stopAllIP();
-
-            resetLinkProperties();
-            if (mStartTimeMillis > 0) {
-                recordMetric(IpManagerEvent.COMPLETE_LIFECYCLE);
-                mStartTimeMillis = 0;
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_STOP:
-                    break;
-
-                case CMD_START:
-                    mConfiguration = (ProvisioningConfiguration) msg.obj;
-                    transitionTo(mStartedState);
-                    break;
-
-                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_TCP_BUFFER_SIZES:
-                    mTcpBufferSizes = (String) msg.obj;
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_HTTP_PROXY:
-                    mHttpProxy = (ProxyInfo) msg.obj;
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    break;
-
-                case CMD_SET_MULTICAST_FILTER:
-                    mMulticastFiltering = (boolean) msg.obj;
-                    break;
-
-                case DhcpClient.CMD_ON_QUIT:
-                    // Everything is already stopped.
-                    logError("Unexpected CMD_ON_QUIT (already stopped).");
-                    break;
-
-                default:
-                    return NOT_HANDLED;
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-    }
-
-    class StoppingState extends State {
-        @Override
-        public void enter() {
-            if (mDhcpClient == null) {
-                // There's no DHCPv4 for which to wait; proceed to stopped.
-                transitionTo(mStoppedState);
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_STOP:
-                    break;
-
-                case DhcpClient.CMD_CLEAR_LINKADDRESS:
-                    clearIPv4Address();
-                    break;
-
-                case DhcpClient.CMD_ON_QUIT:
-                    mDhcpClient = null;
-                    transitionTo(mStoppedState);
-                    break;
-
-                default:
-                    deferMessage(msg);
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-    }
-
-    class StartedState extends State {
-        @Override
-        public void enter() {
-            mStartTimeMillis = SystemClock.elapsedRealtime();
-
-            if (mConfiguration.mProvisioningTimeoutMs > 0) {
-                final long alarmTime = SystemClock.elapsedRealtime() +
-                        mConfiguration.mProvisioningTimeoutMs;
-                mProvisioningTimeoutAlarm.schedule(alarmTime);
-            }
-
-            if (readyToProceed()) {
-                transitionTo(mRunningState);
-            } else {
-                // Clear all IPv4 and IPv6 before proceeding to RunningState.
-                // Clean up any leftover state from an abnormal exit from
-                // tethering or during an IpManager restart.
-                stopAllIP();
-            }
-        }
-
-        @Override
-        public void exit() {
-            mProvisioningTimeoutAlarm.cancel();
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_STOP:
-                    transitionTo(mStoppingState);
-                    break;
-
-                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    if (readyToProceed()) {
-                        transitionTo(mRunningState);
-                    }
-                    break;
-
-                case EVENT_PROVISIONING_TIMEOUT:
-                    handleProvisioningFailure();
-                    break;
-
-                default:
-                    // It's safe to process messages out of order because the
-                    // only message that can both
-                    //     a) be received at this time and
-                    //     b) affect provisioning state
-                    // is EVENT_NETLINK_LINKPROPERTIES_CHANGED (handled above).
-                    deferMessage(msg);
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-
-        boolean readyToProceed() {
-            return (!mLinkProperties.hasIPv4Address() &&
-                    !mLinkProperties.hasGlobalIPv6Address());
-        }
-    }
-
-    class RunningState extends State {
-        private ConnectivityPacketTracker mPacketTracker;
-        private boolean mDhcpActionInFlight;
-
-        @Override
-        public void enter() {
-            // Get the Configuration for ApfFilter from Context
-            boolean filter802_3Frames =
-                    mContext.getResources().getBoolean(R.bool.config_apfDrop802_3Frames);
-
-            mApfFilter = ApfFilter.maybeCreate(mConfiguration.mApfCapabilities, mNetworkInterface,
-                    mCallback, mMulticastFiltering, filter802_3Frames);
-            // TODO: investigate the effects of any multicast filtering racing/interfering with the
-            // rest of this IP configuration startup.
-            if (mApfFilter == null) {
-                mCallback.setFallbackMulticastFilter(mMulticastFiltering);
-            }
-
-            mPacketTracker = createPacketTracker();
-            if (mPacketTracker != null) mPacketTracker.start();
-
-            if (mConfiguration.mEnableIPv6 && !startIPv6()) {
-                doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6);
-                transitionTo(mStoppingState);
-                return;
-            }
-
-            if (mConfiguration.mEnableIPv4 && !startIPv4()) {
-                doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4);
-                transitionTo(mStoppingState);
-                return;
-            }
-
-            InitialConfiguration config = mConfiguration.mInitialConfig;
-            if ((config != null) && !applyInitialConfig(config)) {
-                // TODO introduce a new IpManagerEvent constant to distinguish this error case.
-                doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
-                transitionTo(mStoppingState);
-                return;
-            }
-
-            if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) {
-                doImmediateProvisioningFailure(
-                        IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR);
-                transitionTo(mStoppingState);
-                return;
-            }
-        }
-
-        @Override
-        public void exit() {
-            stopDhcpAction();
-
-            if (mIpReachabilityMonitor != null) {
-                mIpReachabilityMonitor.stop();
-                mIpReachabilityMonitor = null;
-            }
-
-            if (mDhcpClient != null) {
-                mDhcpClient.sendMessage(DhcpClient.CMD_STOP_DHCP);
-                mDhcpClient.doQuit();
-            }
-
-            if (mPacketTracker != null) {
-                mPacketTracker.stop();
-                mPacketTracker = null;
-            }
-
-            if (mApfFilter != null) {
-                mApfFilter.shutdown();
-                mApfFilter = null;
-            }
-
-            resetLinkProperties();
-        }
-
-        private ConnectivityPacketTracker createPacketTracker() {
-            try {
-                return new ConnectivityPacketTracker(mNetworkInterface, mConnectivityPacketLog);
-            } catch (IllegalArgumentException e) {
-                return null;
-            }
-        }
-
-        private void ensureDhcpAction() {
-            if (!mDhcpActionInFlight) {
-                mCallback.onPreDhcpAction();
-                mDhcpActionInFlight = true;
-                final long alarmTime = SystemClock.elapsedRealtime() +
-                        mConfiguration.mRequestedPreDhcpActionMs;
-                mDhcpActionTimeoutAlarm.schedule(alarmTime);
-            }
-        }
-
-        private void stopDhcpAction() {
-            mDhcpActionTimeoutAlarm.cancel();
-            if (mDhcpActionInFlight) {
-                mCallback.onPostDhcpAction();
-                mDhcpActionInFlight = false;
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_STOP:
-                    transitionTo(mStoppingState);
-                    break;
-
-                case CMD_START:
-                    logError("ALERT: START received in StartedState. Please fix caller.");
-                    break;
-
-                case CMD_CONFIRM:
-                    // TODO: Possibly introduce a second type of confirmation
-                    // that both probes (a) on-link neighbors and (b) does
-                    // a DHCPv4 RENEW.  We used to do this on Wi-Fi framework
-                    // roams.
-                    if (mIpReachabilityMonitor != null) {
-                        mIpReachabilityMonitor.probeAll();
-                    }
-                    break;
-
-                case EVENT_PRE_DHCP_ACTION_COMPLETE:
-                    // It's possible to reach here if, for example, someone
-                    // calls completedPreDhcpAction() after provisioning with
-                    // a static IP configuration.
-                    if (mDhcpClient != null) {
-                        mDhcpClient.sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE);
-                    }
-                    break;
-
-                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                    if (!handleLinkPropertiesUpdate(SEND_CALLBACKS)) {
-                        transitionTo(mStoppingState);
-                    }
-                    break;
-
-                case CMD_UPDATE_TCP_BUFFER_SIZES:
-                    mTcpBufferSizes = (String) msg.obj;
-                    // This cannot possibly change provisioning state.
-                    handleLinkPropertiesUpdate(SEND_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_HTTP_PROXY:
-                    mHttpProxy = (ProxyInfo) msg.obj;
-                    // This cannot possibly change provisioning state.
-                    handleLinkPropertiesUpdate(SEND_CALLBACKS);
-                    break;
-
-                case CMD_SET_MULTICAST_FILTER: {
-                    mMulticastFiltering = (boolean) msg.obj;
-                    if (mApfFilter != null) {
-                        mApfFilter.setMulticastFilter(mMulticastFiltering);
-                    } else {
-                        mCallback.setFallbackMulticastFilter(mMulticastFiltering);
-                    }
-                    break;
-                }
-
-                case EVENT_DHCPACTION_TIMEOUT:
-                    stopDhcpAction();
-                    break;
-
-                case DhcpClient.CMD_PRE_DHCP_ACTION:
-                    if (mConfiguration.mRequestedPreDhcpActionMs > 0) {
-                        ensureDhcpAction();
-                    } else {
-                        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
-                    }
-                    break;
-
-                case DhcpClient.CMD_CLEAR_LINKADDRESS:
-                    clearIPv4Address();
-                    break;
-
-                case DhcpClient.CMD_CONFIGURE_LINKADDRESS: {
-                    final LinkAddress ipAddress = (LinkAddress) msg.obj;
-                    if (setIPv4Address(ipAddress)) {
-                        mDhcpClient.sendMessage(DhcpClient.EVENT_LINKADDRESS_CONFIGURED);
-                    } else {
-                        logError("Failed to set IPv4 address.");
-                        dispatchCallback(ProvisioningChange.LOST_PROVISIONING,
-                                new LinkProperties(mLinkProperties));
-                        transitionTo(mStoppingState);
-                    }
-                    break;
-                }
-
-                // This message is only received when:
-                //
-                //     a) initial address acquisition succeeds,
-                //     b) renew succeeds or is NAK'd,
-                //     c) rebind succeeds or is NAK'd, or
-                //     c) the lease expires,
-                //
-                // but never when initial address acquisition fails. The latter
-                // condition is now governed by the provisioning timeout.
-                case DhcpClient.CMD_POST_DHCP_ACTION:
-                    stopDhcpAction();
-
-                    switch (msg.arg1) {
-                        case DhcpClient.DHCP_SUCCESS:
-                            handleIPv4Success((DhcpResults) msg.obj);
-                            break;
-                        case DhcpClient.DHCP_FAILURE:
-                            handleIPv4Failure();
-                            break;
-                        default:
-                            logError("Unknown CMD_POST_DHCP_ACTION status: %s", msg.arg1);
-                    }
-                    break;
-
-                case DhcpClient.CMD_ON_QUIT:
-                    // DHCPv4 quit early for some reason.
-                    logError("Unexpected CMD_ON_QUIT.");
-                    mDhcpClient = null;
-                    break;
-
-                default:
-                    return NOT_HANDLED;
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-    }
-
-    private static class MessageHandlingLogger {
-        public String processedInState;
-        public String receivedInState;
-
-        public void reset() {
-            processedInState = null;
-            receivedInState = null;
-        }
-
-        public void handled(State processedIn, IState receivedIn) {
-            processedInState = processedIn.getClass().getSimpleName();
-            receivedInState = receivedIn.getName();
-        }
-
-        public String toString() {
-            return String.format("rcvd_in=%s, proc_in=%s",
-                                 receivedInState, processedInState);
-        }
-    }
-
-    // TODO: extract out into CollectionUtils.
-    static <T> boolean any(Iterable<T> coll, Predicate<T> fn) {
-        for (T t : coll) {
-            if (fn.test(t)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    static <T> boolean all(Iterable<T> coll, Predicate<T> fn) {
-        return !any(coll, not(fn));
-    }
-
-    static <T> Predicate<T> not(Predicate<T> fn) {
-        return (t) -> !fn.test(t);
-    }
-
-    static <T> String join(String delimiter, Collection<T> coll) {
-        return coll.stream().map(Object::toString).collect(Collectors.joining(delimiter));
-    }
-
-    static <T> T find(Iterable<T> coll, Predicate<T> fn) {
-        for (T t: coll) {
-            if (fn.test(t)) {
-              return t;
-            }
-        }
-        return null;
-    }
-
-    static <T> List<T> findAll(Collection<T> coll, Predicate<T> fn) {
-        return coll.stream().filter(fn).collect(Collectors.toList());
+        super.startProvisioning((IpClient.ProvisioningConfiguration) req);
     }
 }
diff --git a/services/net/java/android/net/ip/IpReachabilityMonitor.java b/services/net/java/android/net/ip/IpReachabilityMonitor.java
index e833f6a..714b35a 100644
--- a/services/net/java/android/net/ip/IpReachabilityMonitor.java
+++ b/services/net/java/android/net/ip/IpReachabilityMonitor.java
@@ -205,44 +205,14 @@
         final byte[] msg = RtNetlinkNeighborMessage.newNewNeighborMessage(
                 1, ip, StructNdMsg.NUD_PROBE, ifIndex, null);
 
-        int errno = -OsConstants.EPROTO;
-        try (NetlinkSocket nlSocket = new NetlinkSocket(OsConstants.NETLINK_ROUTE)) {
-            final long IO_TIMEOUT = 300L;
-            nlSocket.connectToKernel();
-            nlSocket.sendMessage(msg, 0, msg.length, IO_TIMEOUT);
-            final ByteBuffer bytes = nlSocket.recvMessage(IO_TIMEOUT);
-            // recvMessage() guaranteed to not return null if it did not throw.
-            final NetlinkMessage response = NetlinkMessage.parse(bytes);
-            if (response != null && response instanceof NetlinkErrorMessage &&
-                    (((NetlinkErrorMessage) response).getNlMsgError() != null)) {
-                errno = ((NetlinkErrorMessage) response).getNlMsgError().error;
-                if (errno != 0) {
-                    // TODO: consider ignoring EINVAL (-22), which appears to be
-                    // normal when probing a neighbor for which the kernel does
-                    // not already have / no longer has a link layer address.
-                    Log.e(TAG, "Error " + msgSnippet + ", errmsg=" + response.toString());
-                }
-            } else {
-                String errmsg;
-                if (response == null) {
-                    bytes.position(0);
-                    errmsg = "raw bytes: " + NetlinkConstants.hexify(bytes);
-                } else {
-                    errmsg = response.toString();
-                }
-                Log.e(TAG, "Error " + msgSnippet + ", errmsg=" + errmsg);
-            }
+        try {
+            NetlinkSocket.sendOneShotKernelMessage(OsConstants.NETLINK_ROUTE, msg);
         } catch (ErrnoException e) {
-            Log.e(TAG, "Error " + msgSnippet, e);
-            errno = -e.errno;
-        } catch (InterruptedIOException e) {
-            Log.e(TAG, "Error " + msgSnippet, e);
-            errno = -OsConstants.ETIMEDOUT;
-        } catch (SocketException e) {
-            Log.e(TAG, "Error " + msgSnippet, e);
-            errno = -OsConstants.EIO;
+            Log.e(TAG, "Error " + msgSnippet + ": " + e);
+            return -e.errno;
         }
-        return errno;
+
+        return 0;
     }
 
     public IpReachabilityMonitor(Context context, String ifName, SharedLog log, Callback callback) {
diff --git a/services/net/java/android/net/netlink/ConntrackMessage.java b/services/net/java/android/net/netlink/ConntrackMessage.java
new file mode 100644
index 0000000..605c46b
--- /dev/null
+++ b/services/net/java/android/net/netlink/ConntrackMessage.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import static android.net.netlink.NetlinkConstants.alignedLengthOf;
+import static android.net.netlink.StructNlAttr.makeNestedType;
+import static android.net.netlink.StructNlAttr.NLA_HEADERLEN;
+import static android.net.netlink.StructNlMsgHdr.NLM_F_ACK;
+import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
+import static android.net.netlink.StructNlMsgHdr.NLM_F_REPLACE;
+import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
+import static android.net.util.NetworkConstants.IPV4_ADDR_LEN;
+import static java.nio.ByteOrder.BIG_ENDIAN;
+
+import android.system.OsConstants;
+import android.util.Log;
+import libcore.io.SizeOf;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+
+/**
+ * A NetlinkMessage subclass for netlink conntrack messages.
+ *
+ * see also: &lt;linux_src&gt;/include/uapi/linux/netfilter/nfnetlink_conntrack.h
+ *
+ * @hide
+ */
+public class ConntrackMessage extends NetlinkMessage {
+    public static final int STRUCT_SIZE = StructNlMsgHdr.STRUCT_SIZE + StructNfGenMsg.STRUCT_SIZE;
+
+    public static final short NFNL_SUBSYS_CTNETLINK = 1;
+    public static final short IPCTNL_MSG_CT_NEW = 0;
+
+    // enum ctattr_type
+    public static final short CTA_TUPLE_ORIG  = 1;
+    public static final short CTA_TUPLE_REPLY = 2;
+    public static final short CTA_TIMEOUT     = 7;
+
+    // enum ctattr_tuple
+    public static final short CTA_TUPLE_IP    = 1;
+    public static final short CTA_TUPLE_PROTO = 2;
+
+    // enum ctattr_ip
+    public static final short CTA_IP_V4_SRC = 1;
+    public static final short CTA_IP_V4_DST = 2;
+
+    // enum ctattr_l4proto
+    public static final short CTA_PROTO_NUM      = 1;
+    public static final short CTA_PROTO_SRC_PORT = 2;
+    public static final short CTA_PROTO_DST_PORT = 3;
+
+    public static byte[] newIPv4TimeoutUpdateRequest(
+            int proto, Inet4Address src, int sport, Inet4Address dst, int dport, int timeoutSec) {
+        // *** STYLE WARNING ***
+        //
+        // Code below this point uses extra block indentation to highlight the
+        // packing of nested tuple netlink attribute types.
+        final StructNlAttr ctaTupleOrig = new StructNlAttr(CTA_TUPLE_ORIG,
+                new StructNlAttr(CTA_TUPLE_IP,
+                        new StructNlAttr(CTA_IP_V4_SRC, src),
+                        new StructNlAttr(CTA_IP_V4_DST, dst)),
+                new StructNlAttr(CTA_TUPLE_PROTO,
+                        new StructNlAttr(CTA_PROTO_NUM, (byte) proto),
+                        new StructNlAttr(CTA_PROTO_SRC_PORT, (short) sport, BIG_ENDIAN),
+                        new StructNlAttr(CTA_PROTO_DST_PORT, (short) dport, BIG_ENDIAN)));
+
+        final StructNlAttr ctaTimeout = new StructNlAttr(CTA_TIMEOUT, timeoutSec, BIG_ENDIAN);
+
+        final int payloadLength = ctaTupleOrig.getAlignedLength() + ctaTimeout.getAlignedLength();
+        final byte[] bytes = new byte[STRUCT_SIZE + payloadLength];
+        final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
+        byteBuffer.order(ByteOrder.nativeOrder());
+
+        final ConntrackMessage ctmsg = new ConntrackMessage();
+        ctmsg.mHeader.nlmsg_len = bytes.length;
+        ctmsg.mHeader.nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_NEW;
+        ctmsg.mHeader.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE;
+        ctmsg.mHeader.nlmsg_seq = 1;
+        ctmsg.pack(byteBuffer);
+
+        ctaTupleOrig.pack(byteBuffer);
+        ctaTimeout.pack(byteBuffer);
+
+        return bytes;
+    }
+
+    protected StructNfGenMsg mNfGenMsg;
+
+    private ConntrackMessage() {
+        super(new StructNlMsgHdr());
+        mNfGenMsg = new StructNfGenMsg((byte) OsConstants.AF_INET);
+    }
+
+    public void pack(ByteBuffer byteBuffer) {
+        mHeader.pack(byteBuffer);
+        mNfGenMsg.pack(byteBuffer);
+    }
+}
diff --git a/services/net/java/android/net/netlink/NetlinkSocket.java b/services/net/java/android/net/netlink/NetlinkSocket.java
index 657d48c..f5f211d 100644
--- a/services/net/java/android/net/netlink/NetlinkSocket.java
+++ b/services/net/java/android/net/netlink/NetlinkSocket.java
@@ -51,11 +51,52 @@
     private long mLastRecvTimeoutMs;
     private long mLastSendTimeoutMs;
 
+    public static void sendOneShotKernelMessage(int nlProto, byte[] msg) throws ErrnoException {
+        final String errPrefix = "Error in NetlinkSocket.sendOneShotKernelMessage";
+
+        try (NetlinkSocket nlSocket = new NetlinkSocket(nlProto)) {
+            final long IO_TIMEOUT = 300L;
+            nlSocket.connectToKernel();
+            nlSocket.sendMessage(msg, 0, msg.length, IO_TIMEOUT);
+            final ByteBuffer bytes = nlSocket.recvMessage(IO_TIMEOUT);
+            // recvMessage() guaranteed to not return null if it did not throw.
+            final NetlinkMessage response = NetlinkMessage.parse(bytes);
+            if (response != null && response instanceof NetlinkErrorMessage &&
+                    (((NetlinkErrorMessage) response).getNlMsgError() != null)) {
+                final int errno = ((NetlinkErrorMessage) response).getNlMsgError().error;
+                if (errno != 0) {
+                    // TODO: consider ignoring EINVAL (-22), which appears to be
+                    // normal when probing a neighbor for which the kernel does
+                    // not already have / no longer has a link layer address.
+                    Log.e(TAG, errPrefix + ", errmsg=" + response.toString());
+                    // Note: convert kernel errnos (negative) into userspace errnos (positive).
+                    throw new ErrnoException(response.toString(), Math.abs(errno));
+                }
+            } else {
+                final String errmsg;
+                if (response == null) {
+                    bytes.position(0);
+                    errmsg = "raw bytes: " + NetlinkConstants.hexify(bytes);
+                } else {
+                    errmsg = response.toString();
+                }
+                Log.e(TAG, errPrefix + ", errmsg=" + errmsg);
+                throw new ErrnoException(errmsg, OsConstants.EPROTO);
+            }
+        } catch (InterruptedIOException e) {
+            Log.e(TAG, errPrefix, e);
+            throw new ErrnoException(errPrefix, OsConstants.ETIMEDOUT, e);
+        } catch (SocketException e) {
+            Log.e(TAG, errPrefix, e);
+            throw new ErrnoException(errPrefix, OsConstants.EIO, e);
+        }
+    }
+
     public NetlinkSocket(int nlProto) throws ErrnoException {
         mDescriptor = Os.socket(
                 OsConstants.AF_NETLINK, OsConstants.SOCK_DGRAM, nlProto);
 
-        Libcore.os.setsockoptInt(
+        Os.setsockoptInt(
                 mDescriptor, OsConstants.SOL_SOCKET,
                 OsConstants.SO_RCVBUF, SOCKET_RECV_BUFSIZE);
     }
diff --git a/services/net/java/android/net/netlink/RtNetlinkNeighborMessage.java b/services/net/java/android/net/netlink/RtNetlinkNeighborMessage.java
index 02df131..e784fbb 100644
--- a/services/net/java/android/net/netlink/RtNetlinkNeighborMessage.java
+++ b/services/net/java/android/net/netlink/RtNetlinkNeighborMessage.java
@@ -36,7 +36,7 @@
 
 
 /**
- * A NetlinkMessage subclass for netlink error messages.
+ * A NetlinkMessage subclass for rtnetlink neighbor messages.
  *
  * see also: &lt;linux_src&gt;/include/uapi/linux/neighbour.h
  *
diff --git a/services/net/java/android/net/netlink/StructNfGenMsg.java b/services/net/java/android/net/netlink/StructNfGenMsg.java
new file mode 100644
index 0000000..99695e2
--- /dev/null
+++ b/services/net/java/android/net/netlink/StructNfGenMsg.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import libcore.io.SizeOf;
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * struct nfgenmsg
+ *
+ * see &lt;linux_src&gt;/include/uapi/linux/netfilter/nfnetlink.h
+ *
+ * @hide
+ */
+public class StructNfGenMsg {
+    public static final int STRUCT_SIZE = 2 + SizeOf.SHORT;
+
+    public static final int NFNETLINK_V0 = 0;
+
+    final public byte nfgen_family;
+    final public byte version;
+    final public short res_id;  // N.B.: this is big endian in the kernel
+
+    public StructNfGenMsg(byte family) {
+        nfgen_family = family;
+        version = (byte) NFNETLINK_V0;
+        res_id = (short) 0;
+    }
+
+    public void pack(ByteBuffer byteBuffer) {
+        byteBuffer.put(nfgen_family);
+        byteBuffer.put(version);
+        byteBuffer.putShort(res_id);
+    }
+}
diff --git a/services/net/java/android/net/netlink/StructNlAttr.java b/services/net/java/android/net/netlink/StructNlAttr.java
index 597a6aa..811bdbb 100644
--- a/services/net/java/android/net/netlink/StructNlAttr.java
+++ b/services/net/java/android/net/netlink/StructNlAttr.java
@@ -34,7 +34,12 @@
  */
 public class StructNlAttr {
     // Already aligned.
-    public static final int NLA_HEADERLEN         = 4;
+    public static final int NLA_HEADERLEN  = 4;
+    public static final int NLA_F_NESTED   = (1 << 15);
+
+    public static short makeNestedType(short type) {
+        return (short) (type | NLA_F_NESTED);
+    }
 
     // Return a (length, type) object only, without consuming any bytes in
     // |byteBuffer| and without copying or interpreting any value bytes.
@@ -46,10 +51,17 @@
         }
         final int baseOffset = byteBuffer.position();
 
-        final StructNlAttr struct = new StructNlAttr();
-        struct.nla_len = byteBuffer.getShort();
-        struct.nla_type = byteBuffer.getShort();
-        struct.mByteOrder = byteBuffer.order();
+        // Assume the byte order of the buffer is the expected byte order of the value.
+        final StructNlAttr struct = new StructNlAttr(byteBuffer.order());
+        // The byte order of nla_len and nla_type is always native.
+        final ByteOrder originalOrder = byteBuffer.order();
+        byteBuffer.order(ByteOrder.nativeOrder());
+        try {
+            struct.nla_len = byteBuffer.getShort();
+            struct.nla_type = byteBuffer.getShort();
+        } finally {
+            byteBuffer.order(originalOrder);
+        }
 
         byteBuffer.position(baseOffset);
         if (struct.nla_len < NLA_HEADERLEN) {
@@ -78,13 +90,65 @@
         return struct;
     }
 
-    public short nla_len;
+    public short nla_len = (short) NLA_HEADERLEN;
     public short nla_type;
     public byte[] nla_value;
-    public ByteOrder mByteOrder;
 
-    public StructNlAttr() {
-        mByteOrder = ByteOrder.nativeOrder();
+    // The byte order used to read/write the value member. Netlink length and
+    // type members are always read/written in native order.
+    private ByteOrder mByteOrder = ByteOrder.nativeOrder();
+
+    public StructNlAttr() {}
+
+    public StructNlAttr(ByteOrder byteOrder) {
+        mByteOrder = byteOrder;
+    }
+
+    public StructNlAttr(short type, byte value) {
+        nla_type = type;
+        setValue(new byte[1]);
+        nla_value[0] = value;
+    }
+
+    public StructNlAttr(short type, short value) {
+        this(type, value, ByteOrder.nativeOrder());
+    }
+
+    public StructNlAttr(short type, short value, ByteOrder order) {
+        this(order);
+        nla_type = type;
+        setValue(new byte[SizeOf.SHORT]);
+        getValueAsByteBuffer().putShort(value);
+    }
+
+    public StructNlAttr(short type, int value) {
+        this(type, value, ByteOrder.nativeOrder());
+    }
+
+    public StructNlAttr(short type, int value, ByteOrder order) {
+        this(order);
+        nla_type = type;
+        setValue(new byte[SizeOf.INT]);
+        getValueAsByteBuffer().putInt(value);
+    }
+
+    public StructNlAttr(short type, InetAddress ip) {
+        nla_type = type;
+        setValue(ip.getAddress());
+    }
+
+    public StructNlAttr(short type, StructNlAttr... nested) {
+        this();
+        nla_type = makeNestedType(type);
+
+        int payloadLength = 0;
+        for (StructNlAttr nla : nested) payloadLength += nla.getAlignedLength();
+        setValue(new byte[payloadLength]);
+
+        final ByteBuffer buf = getValueAsByteBuffer();
+        for (StructNlAttr nla : nested) {
+            nla.pack(buf);
+        }
     }
 
     public int getAlignedLength() {
@@ -117,13 +181,25 @@
     }
 
     public void pack(ByteBuffer byteBuffer) {
+        final ByteOrder originalOrder = byteBuffer.order();
         final int originalPosition = byteBuffer.position();
-        byteBuffer.putShort(nla_len);
-        byteBuffer.putShort(nla_type);
-        byteBuffer.put(nla_value);
+
+        byteBuffer.order(ByteOrder.nativeOrder());
+        try {
+            byteBuffer.putShort(nla_len);
+            byteBuffer.putShort(nla_type);
+            if (nla_value != null) byteBuffer.put(nla_value);
+        } finally {
+            byteBuffer.order(originalOrder);
+        }
         byteBuffer.position(originalPosition + getAlignedLength());
     }
 
+    private void setValue(byte[] value) {
+        nla_value = value;
+        nla_len = (short) (NLA_HEADERLEN + ((nla_value != null) ? nla_value.length : 0));
+    }
+
     @Override
     public String toString() {
         return "StructNlAttr{ "
diff --git a/services/net/java/android/net/util/BlockingSocketReader.java b/services/net/java/android/net/util/BlockingSocketReader.java
index 12fa1e5..99bf469 100644
--- a/services/net/java/android/net/util/BlockingSocketReader.java
+++ b/services/net/java/android/net/util/BlockingSocketReader.java
@@ -16,81 +16,106 @@
 
 package android.net.util;
 
+import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
+import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
+
 import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.MessageQueue;
+import android.os.MessageQueue.OnFileDescriptorEventListener;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
 
-import libcore.io.IoBridge;
+import libcore.io.IoUtils;
 
 import java.io.FileDescriptor;
-import java.io.InterruptedIOException;
 import java.io.IOException;
 
 
 /**
- * A thread that reads from a socket and passes the received packets to a
- * subclass's handlePacket() method.  The packet receive buffer is recycled
- * on every read call, so subclasses should make any copies they would like
- * inside their handlePacket() implementation.
+ * This class encapsulates the mechanics of registering a file descriptor
+ * with a thread's Looper and handling read events (and errors).
  *
- * All public methods may be called from any thread.
+ * Subclasses MUST implement createFd() and SHOULD override handlePacket().
+
+ * Subclasses can expect a call life-cycle like the following:
+ *
+ *     [1] start() calls createFd() and (if all goes well) onStart()
+ *
+ *     [2] yield, waiting for read event or error notification:
+ *
+ *             [a] readPacket() && handlePacket()
+ *
+ *             [b] if (no error):
+ *                     goto 2
+ *                 else:
+ *                     goto 3
+ *
+ *     [3] stop() calls onStop() if not previously stopped
+ *
+ * The packet receive buffer is recycled on every read call, so subclasses
+ * should make any copies they would like inside their handlePacket()
+ * implementation.
+ *
+ * All public methods MUST only be called from the same thread with which
+ * the Handler constructor argument is associated.
+ *
+ * TODO: rename this class to something more correctly descriptive (something
+ * like [or less horrible than] FdReadEventsHandler?).
  *
  * @hide
  */
 public abstract class BlockingSocketReader {
+    private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR;
+    private static final int UNREGISTER_THIS_FD = 0;
+
     public static final int DEFAULT_RECV_BUF_SIZE = 2 * 1024;
 
+    private final Handler mHandler;
+    private final MessageQueue mQueue;
     private final byte[] mPacket;
-    private final Thread mThread;
-    private volatile FileDescriptor mSocket;
-    private volatile boolean mRunning;
-    private volatile long mPacketsReceived;
+    private FileDescriptor mFd;
+    private long mPacketsReceived;
 
-    // Make it slightly easier for subclasses to properly close a socket
-    // without having to know this incantation.
-    public static final void closeSocket(@Nullable FileDescriptor fd) {
-        try {
-            IoBridge.closeAndSignalBlockedThreads(fd);
-        } catch (IOException ignored) {}
+    protected static void closeFd(FileDescriptor fd) {
+        IoUtils.closeQuietly(fd);
     }
 
-    protected BlockingSocketReader() {
-        this(DEFAULT_RECV_BUF_SIZE);
+    protected BlockingSocketReader(Handler h) {
+        this(h, DEFAULT_RECV_BUF_SIZE);
     }
 
-    protected BlockingSocketReader(int recvbufsize) {
-        if (recvbufsize < DEFAULT_RECV_BUF_SIZE) {
-            recvbufsize = DEFAULT_RECV_BUF_SIZE;
+    protected BlockingSocketReader(Handler h, int recvbufsize) {
+        mHandler = h;
+        mQueue = mHandler.getLooper().getQueue();
+        mPacket = new byte[Math.max(recvbufsize, DEFAULT_RECV_BUF_SIZE)];
+    }
+
+    public final void start() {
+        if (onCorrectThread()) {
+            createAndRegisterFd();
+        } else {
+            mHandler.post(() -> {
+                logError("start() called from off-thread", null);
+                createAndRegisterFd();
+            });
         }
-        mPacket = new byte[recvbufsize];
-        mThread = new Thread(() -> { mainLoop(); });
-    }
-
-    public final boolean start() {
-        if (mSocket != null) return false;
-
-        try {
-            mSocket = createSocket();
-        } catch (Exception e) {
-            logError("Failed to create socket: ", e);
-            return false;
-        }
-
-        if (mSocket == null) return false;
-
-        mRunning = true;
-        mThread.start();
-        return true;
     }
 
     public final void stop() {
-        mRunning = false;
-        closeSocket(mSocket);
-        mSocket = null;
+        if (onCorrectThread()) {
+            unregisterAndDestroyFd();
+        } else {
+            mHandler.post(() -> {
+                logError("stop() called from off-thread", null);
+                unregisterAndDestroyFd();
+            });
+        }
     }
 
-    public final boolean isRunning() { return mRunning; }
+    public final int recvBufSize() { return mPacket.length; }
 
     public final long numPacketsReceived() { return mPacketsReceived; }
 
@@ -98,11 +123,21 @@
      * Subclasses MUST create the listening socket here, including setting
      * all desired socket options, interface or address/port binding, etc.
      */
-    protected abstract FileDescriptor createSocket();
+    protected abstract FileDescriptor createFd();
+
+    /**
+     * Subclasses MAY override this to change the default read() implementation
+     * in favour of, say, recvfrom().
+     *
+     * Implementations MUST return the bytes read or throw an Exception.
+     */
+    protected int readPacket(FileDescriptor fd, byte[] packetBuffer) throws Exception {
+        return Os.read(fd, packetBuffer, 0, packetBuffer.length);
+    }
 
     /**
      * Called by the main loop for every packet.  Any desired copies of
-     * |recvbuf| should be made in here, and the underlying byte array is
+     * |recvbuf| should be made in here, as the underlying byte array is
      * reused across all reads.
      */
     protected void handlePacket(byte[] recvbuf, int length) {}
@@ -113,43 +148,102 @@
     protected void logError(String msg, Exception e) {}
 
     /**
-     * Called by the main loop just prior to exiting.
+     * Called by start(), if successful, just prior to returning.
      */
-    protected void onExit() {}
+    protected void onStart() {}
 
-    private final void mainLoop() {
+    /**
+     * Called by stop() just prior to returning.
+     */
+    protected void onStop() {}
+
+    private void createAndRegisterFd() {
+        if (mFd != null) return;
+
+        try {
+            mFd = createFd();
+            if (mFd != null) {
+                // Force the socket to be non-blocking.
+                IoUtils.setBlocking(mFd, false);
+            }
+        } catch (Exception e) {
+            logError("Failed to create socket: ", e);
+            closeFd(mFd);
+            mFd = null;
+            return;
+        }
+
+        if (mFd == null) return;
+
+        mQueue.addOnFileDescriptorEventListener(
+                mFd,
+                FD_EVENTS,
+                new OnFileDescriptorEventListener() {
+                    @Override
+                    public int onFileDescriptorEvents(FileDescriptor fd, int events) {
+                        // Always call handleInput() so read/recvfrom are given
+                        // a proper chance to encounter a meaningful errno and
+                        // perhaps log a useful error message.
+                        if (!isRunning() || !handleInput()) {
+                            unregisterAndDestroyFd();
+                            return UNREGISTER_THIS_FD;
+                        }
+                        return FD_EVENTS;
+                    }
+                });
+        onStart();
+    }
+
+    private boolean isRunning() { return (mFd != null) && mFd.valid(); }
+
+    // Keep trying to read until we get EAGAIN/EWOULDBLOCK or some fatal error.
+    private boolean handleInput() {
         while (isRunning()) {
             final int bytesRead;
 
             try {
-                // Blocking read.
-                // TODO: See if this can be converted to recvfrom.
-                bytesRead = Os.read(mSocket, mPacket, 0, mPacket.length);
+                bytesRead = readPacket(mFd, mPacket);
                 if (bytesRead < 1) {
                     if (isRunning()) logError("Socket closed, exiting", null);
                     break;
                 }
                 mPacketsReceived++;
             } catch (ErrnoException e) {
-                if (e.errno != OsConstants.EINTR) {
-                    if (isRunning()) logError("read error: ", e);
+                if (e.errno == OsConstants.EAGAIN) {
+                    // We've read everything there is to read this time around.
+                    return true;
+                } else if (e.errno == OsConstants.EINTR) {
+                    continue;
+                } else {
+                    if (isRunning()) logError("readPacket error: ", e);
                     break;
                 }
-                continue;
-            } catch (IOException ioe) {
-                if (isRunning()) logError("read error: ", ioe);
-                continue;
+            } catch (Exception e) {
+                if (isRunning()) logError("readPacket error: ", e);
+                break;
             }
 
             try {
                 handlePacket(mPacket, bytesRead);
             } catch (Exception e) {
-                logError("Unexpected exception: ", e);
+                logError("handlePacket error: ", e);
                 break;
             }
         }
 
-        stop();
-        onExit();
+        return false;
+    }
+
+    private void unregisterAndDestroyFd() {
+        if (mFd == null) return;
+
+        mQueue.removeOnFileDescriptorEventListener(mFd);
+        closeFd(mFd);
+        mFd = null;
+        onStop();
+    }
+
+    private boolean onCorrectThread() {
+        return (mHandler.getLooper() == Looper.myLooper());
     }
 }
diff --git a/services/net/java/android/net/util/NetworkConstants.java b/services/net/java/android/net/util/NetworkConstants.java
index 6065268..5a3a8be 100644
--- a/services/net/java/android/net/util/NetworkConstants.java
+++ b/services/net/java/android/net/util/NetworkConstants.java
@@ -107,6 +107,20 @@
     public static final int RFC6177_MIN_PREFIX_LENGTH = 48;
 
     /**
+     * ICMP common (v4/v6) constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc792
+     *     - https://tools.ietf.org/html/rfc4443
+     */
+    public static final int ICMP_HEADER_TYPE_OFFSET = 0;
+    public static final int ICMP_HEADER_CODE_OFFSET = 1;
+    public static final int ICMP_HEADER_CHECKSUM_OFFSET = 2;
+    public static final int ICMP_ECHO_IDENTIFIER_OFFSET = 4;
+    public static final int ICMP_ECHO_SEQUENCE_NUMBER_OFFSET = 6;
+    public static final int ICMP_ECHO_DATA_OFFSET = 8;
+
+    /**
      * ICMPv6 constants.
      *
      * See also:
diff --git a/services/net/java/android/net/util/SharedLog.java b/services/net/java/android/net/util/SharedLog.java
index 343d237..bbd3d13 100644
--- a/services/net/java/android/net/util/SharedLog.java
+++ b/services/net/java/android/net/util/SharedLog.java
@@ -106,6 +106,10 @@
         record(Category.NONE, msg);
     }
 
+    public void logf(String fmt, Object... args) {
+        log(String.format(fmt, args));
+    }
+
     public void mark(String msg) {
         record(Category.MARK, msg);
     }
diff --git a/services/net/java/android/net/util/VersionedBroadcastListener.java b/services/net/java/android/net/util/VersionedBroadcastListener.java
new file mode 100644
index 0000000..107c404
--- /dev/null
+++ b/services/net/java/android/net/util/VersionedBroadcastListener.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.util;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Handler;
+import android.util.Log;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+
+
+/**
+ * A utility class that runs the provided callback on the provided handler when
+ * intents matching the provided filter arrive. Intents received by a stale
+ * receiver are safely ignored.
+ *
+ * Calls to startListening() and stopListening() must happen on the same thread.
+ *
+ * @hide
+ */
+public class VersionedBroadcastListener {
+    private static final boolean DBG = false;
+
+    public interface IntentCallback {
+        public void run(Intent intent);
+    }
+
+    private final String mTag;
+    private final Context mContext;
+    private final Handler mHandler;
+    private final IntentFilter mFilter;
+    private final Consumer<Intent> mCallback;
+    private final AtomicInteger mGenerationNumber;
+    private BroadcastReceiver mReceiver;
+
+    public VersionedBroadcastListener(String tag, Context ctx, Handler handler,
+            IntentFilter filter, Consumer<Intent> callback) {
+        mTag = tag;
+        mContext = ctx;
+        mHandler = handler;
+        mFilter = filter;
+        mCallback = callback;
+        mGenerationNumber = new AtomicInteger(0);
+    }
+
+    public void startListening() {
+        if (DBG) Log.d(mTag, "startListening");
+        if (mReceiver != null) return;
+
+        mReceiver = new Receiver(mTag, mGenerationNumber, mCallback);
+        mContext.registerReceiver(mReceiver, mFilter, null, mHandler);
+    }
+
+    public void stopListening() {
+        if (DBG) Log.d(mTag, "stopListening");
+        if (mReceiver == null) return;
+
+        mGenerationNumber.incrementAndGet();
+        mContext.unregisterReceiver(mReceiver);
+        mReceiver = null;
+    }
+
+    private static class Receiver extends BroadcastReceiver {
+        public final String tag;
+        public final AtomicInteger atomicGenerationNumber;
+        public final Consumer<Intent> callback;
+        // Used to verify this receiver is still current.
+        public final int generationNumber;
+
+        public Receiver(
+                String tag, AtomicInteger atomicGenerationNumber, Consumer<Intent> callback) {
+            this.tag = tag;
+            this.atomicGenerationNumber = atomicGenerationNumber;
+            this.callback = callback;
+            generationNumber = atomicGenerationNumber.incrementAndGet();
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final int currentGenerationNumber = atomicGenerationNumber.get();
+
+            if (DBG) {
+                Log.d(tag, "receiver generationNumber=" + generationNumber +
+                        ", current generationNumber=" + currentGenerationNumber);
+            }
+            if (generationNumber != currentGenerationNumber) return;
+
+            callback.accept(intent);
+        }
+    }
+}
diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java
index 5770c50..fcc6f52 100644
--- a/services/print/java/com/android/server/print/UserState.java
+++ b/services/print/java/com/android/server/print/UserState.java
@@ -586,6 +586,7 @@
                 PrintJobStateChangeListenerRecord record =
                         mPrintJobStateChangeListenerRecords.get(i);
                 if (record.listener.asBinder().equals(listener.asBinder())) {
+                    record.destroy();
                     mPrintJobStateChangeListenerRecords.remove(i);
                     break;
                 }
@@ -628,6 +629,7 @@
                 ListenerRecord<IPrintServicesChangeListener> record =
                         mPrintServicesChangeListenerRecords.get(i);
                 if (record.listener.asBinder().equals(listener.asBinder())) {
+                    record.destroy();
                     mPrintServicesChangeListenerRecords.remove(i);
                     break;
                 }
@@ -675,6 +677,7 @@
                 ListenerRecord<IRecommendationsChangeListener> record =
                         mPrintServiceRecommendationsChangeListenerRecords.get(i);
                 if (record.listener.asBinder().equals(listener.asBinder())) {
+                    record.destroy();
                     mPrintServiceRecommendationsChangeListenerRecords.remove(i);
                     break;
                 }
@@ -1222,6 +1225,10 @@
             listener.asBinder().linkToDeath(this, 0);
         }
 
+        public void destroy() {
+            listener.asBinder().unlinkToDeath(this, 0);
+        }
+
         @Override
         public void binderDied() {
             listener.asBinder().unlinkToDeath(this, 0);
@@ -1239,6 +1246,10 @@
             listener.asBinder().linkToDeath(this, 0);
         }
 
+        public void destroy() {
+            listener.asBinder().unlinkToDeath(this, 0);
+        }
+
         @Override
         public void binderDied() {
             listener.asBinder().unlinkToDeath(this, 0);
diff --git a/services/profile-classes b/services/profile-classes
index b0d2da7..a2189bc 100644
--- a/services/profile-classes
+++ b/services/profile-classes
@@ -277,7 +277,6 @@
 Landroid/app/ResourcesManager$1;
 Landroid/app/ResultInfo;
 Landroid/app/ResultInfo$1;
-Landroid/app/RetailDemoModeServiceInternal;
 Landroid/app/SearchableInfo;
 Landroid/app/SearchableInfo$1;
 Landroid/app/SearchManager;
@@ -5085,11 +5084,6 @@
 Lcom/android/server/RescueParty$Threshold;
 Lcom/android/server/restrictions/RestrictionsManagerService;
 Lcom/android/server/restrictions/RestrictionsManagerService$RestrictionsManagerImpl;
-Lcom/android/server/retaildemo/RetailDemoModeService;
-Lcom/android/server/retaildemo/RetailDemoModeService$1;
-Lcom/android/server/retaildemo/RetailDemoModeService$Injector;
-Lcom/android/server/retaildemo/RetailDemoModeService$MainHandler;
-Lcom/android/server/retaildemo/RetailDemoModeService$SettingsObserver;
 Lcom/android/server/SamplingProfilerService;
 Lcom/android/server/SamplingProfilerService$1;
 Lcom/android/server/SamplingProfilerService$SamplingProfilerSettingsObserver;
diff --git a/services/retaildemo/Android.mk b/services/retaildemo/Android.mk
deleted file mode 100644
index 670c6bf..0000000
--- a/services/retaildemo/Android.mk
+++ /dev/null
@@ -1,12 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := services.retaildemo
-
-LOCAL_SRC_FILES += \
-      $(call all-java-files-under,java)
-
-LOCAL_JAVA_LIBRARIES := services.core
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java
deleted file mode 100644
index 90c58d0..0000000
--- a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java
+++ /dev/null
@@ -1,178 +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.server.retaildemo;
-
-import android.app.AppGlobals;
-import android.app.PackageInstallObserver;
-import android.content.Context;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * Helper class for installing preloaded APKs
- */
-class PreloadAppsInstaller {
-    private static final String SYSTEM_SERVER_PACKAGE_NAME = "android";
-    private static String TAG = PreloadAppsInstaller.class.getSimpleName();
-    private static final String PRELOAD_APK_EXT = ".apk.preload";
-    private static boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private final IPackageManager mPackageManager;
-    private final File preloadsAppsDirectory;
-    private final Context mContext;
-
-    private final Map<String, String> mApkToPackageMap;
-
-    PreloadAppsInstaller(Context context) {
-        this(context, AppGlobals.getPackageManager(), Environment.getDataPreloadsAppsDirectory());
-    }
-
-    @VisibleForTesting
-    PreloadAppsInstaller(Context context, IPackageManager packageManager, File preloadsAppsDirectory) {
-        mContext = context;
-        mPackageManager = packageManager;
-        mApkToPackageMap = Collections.synchronizedMap(new ArrayMap<>());
-        this.preloadsAppsDirectory = preloadsAppsDirectory;
-    }
-
-    void installApps(int userId) {
-        File[] files = preloadsAppsDirectory.listFiles();
-        AppInstallCounter counter = new AppInstallCounter(mContext, userId);
-        if (ArrayUtils.isEmpty(files)) {
-            counter.setExpectedAppsCount(0);
-            return;
-        }
-        int expectedCount = 0;
-        for (File file : files) {
-            String apkName = file.getName();
-            if (apkName.endsWith(PRELOAD_APK_EXT) && file.isFile()) {
-                String packageName = mApkToPackageMap.get(apkName);
-                if (packageName != null) {
-                    try {
-                        expectedCount++;
-                        installExistingPackage(packageName, userId, counter);
-                    } catch (Exception e) {
-                        Slog.e(TAG, "Failed to install existing package " + packageName, e);
-                    }
-                } else {
-                    try {
-                        installPackage(file, userId, counter);
-                        expectedCount++;
-                    } catch (Exception e) {
-                        Slog.e(TAG, "Failed to install package from " + file, e);
-                    }
-                }
-            }
-        }
-        counter.setExpectedAppsCount(expectedCount);
-    }
-
-    private void installExistingPackage(String packageName, int userId,
-            AppInstallCounter counter) {
-        if (DEBUG) {
-            Log.d(TAG, "installExistingPackage " + packageName + " u" + userId);
-        }
-        try {
-            mPackageManager.installExistingPackageAsUser(packageName, userId,
-                    0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        } finally {
-            counter.appInstallFinished();
-        }
-    }
-
-    private void installPackage(File file, final int userId, AppInstallCounter counter)
-            throws IOException, RemoteException {
-        final String apkName = file.getName();
-        if (DEBUG) {
-            Log.d(TAG, "installPackage " + apkName + " u" + userId);
-        }
-        mPackageManager.installPackageAsUser(file.getPath(), new PackageInstallObserver() {
-            @Override
-            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
-                    Bundle extras) {
-                if (DEBUG) {
-                    Log.d(TAG, "Package " + basePackageName + " installed u" + userId
-                            + " returnCode: " + returnCode + " msg: " + msg);
-                }
-                // Don't notify the counter for now, we'll do it in installExistingPackage
-                if (returnCode == PackageManager.INSTALL_SUCCEEDED) {
-                    mApkToPackageMap.put(apkName, basePackageName);
-                    // Install on user 0 so that the package is cached when demo user is re-created
-                    installExistingPackage(basePackageName, UserHandle.USER_SYSTEM, counter);
-                } else if (returnCode == PackageManager.INSTALL_FAILED_ALREADY_EXISTS) {
-                    // This can only happen in first session after a reboot
-                    if (!mApkToPackageMap.containsKey(apkName)) {
-                        mApkToPackageMap.put(apkName, basePackageName);
-                    }
-                    installExistingPackage(basePackageName, userId, counter);
-                } else {
-                    Log.e(TAG, "Package " + basePackageName + " cannot be installed from "
-                            + apkName + ": " + msg + " (returnCode " + returnCode + ")");
-                    counter.appInstallFinished();
-                }
-            }
-        }.getBinder(), 0, SYSTEM_SERVER_PACKAGE_NAME, userId);
-    }
-
-    private static class AppInstallCounter {
-        private int expectedCount = -1; // -1 means expectedCount not set
-        private int finishedCount;
-        private final Context mContext;
-        private final int userId;
-
-        AppInstallCounter(Context context, int userId) {
-            mContext = context;
-            this.userId = userId;
-        }
-
-        synchronized void appInstallFinished() {
-            this.finishedCount++;
-            checkIfAllFinished();
-        }
-
-        synchronized void setExpectedAppsCount(int expectedCount) {
-            this.expectedCount = expectedCount;
-            checkIfAllFinished();
-        }
-
-        private void checkIfAllFinished() {
-            if (expectedCount == finishedCount) {
-                Log.i(TAG, "All preloads finished installing for user " + userId);
-                Settings.Secure.putStringForUser(mContext.getContentResolver(),
-                        Settings.Secure.DEMO_USER_SETUP_COMPLETE, "1", userId);
-            }
-        }
-    }
-}
diff --git a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
deleted file mode 100644
index 711d4d9d..0000000
--- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
+++ /dev/null
@@ -1,868 +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.server.retaildemo;
-
-import android.Manifest;
-import android.app.ActivityManager;
-import android.app.ActivityManagerInternal;
-import android.app.AppGlobals;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.RetailDemoModeServiceInternal;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
-import android.content.res.Configuration;
-import android.database.ContentObserver;
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraManager;
-import android.media.AudioManager;
-import android.media.AudioSystem;
-import android.net.Uri;
-import android.net.wifi.WifiManager;
-import android.os.Environment;
-import android.os.FileUtils;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.CallLog;
-import android.provider.MediaStore;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.KeyValueListParser;
-import android.util.Slog;
-
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.internal.notification.SystemNotificationChannels;
-import com.android.internal.os.BackgroundThread;
-import com.android.internal.R;
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.server.LocalServices;
-import com.android.server.PreloadsFileCacheExpirationJobService;
-import com.android.server.ServiceThread;
-import com.android.server.SystemService;
-import com.android.server.am.ActivityManagerService;
-import com.android.server.retaildemo.UserInactivityCountdownDialog.OnCountDownExpiredListener;
-
-import java.io.File;
-import java.util.ArrayList;
-
-public class RetailDemoModeService extends SystemService {
-    private static final boolean DEBUG = false;
-
-    private static final String TAG = RetailDemoModeService.class.getSimpleName();
-    private static final String DEMO_USER_NAME = "Demo";
-    private static final String ACTION_RESET_DEMO =
-            "com.android.server.retaildemo.ACTION_RESET_DEMO";
-    @VisibleForTesting
-    static final String SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED = "sys.retaildemo.enabled";
-
-    private static final int MSG_TURN_SCREEN_ON = 0;
-    private static final int MSG_INACTIVITY_TIME_OUT = 1;
-    private static final int MSG_START_NEW_SESSION = 2;
-
-    private static final long SCREEN_WAKEUP_DELAY = 2500;
-    private static final long USER_INACTIVITY_TIMEOUT_MIN = 10000;
-    private static final long USER_INACTIVITY_TIMEOUT_DEFAULT = 90000;
-    private static final long WARNING_DIALOG_TIMEOUT_DEFAULT = 0;
-    private static final long MILLIS_PER_SECOND = 1000;
-
-    @VisibleForTesting
-    static final int[] VOLUME_STREAMS_TO_MUTE = {
-            AudioSystem.STREAM_RING,
-            AudioSystem.STREAM_MUSIC
-    };
-
-    // Tron Vars
-    private static final String DEMO_SESSION_COUNT = "retail_demo_session_count";
-    private static final String DEMO_SESSION_DURATION = "retail_demo_session_duration";
-
-    boolean mDeviceInDemoMode;
-    boolean mIsCarrierDemoMode;
-    int mCurrentUserId = UserHandle.USER_SYSTEM;
-    long mUserInactivityTimeout;
-    long mWarningDialogTimeout;
-    private Injector mInjector;
-    Handler mHandler;
-    private ServiceThread mHandlerThread;
-    private String[] mCameraIdsWithFlash;
-    private PreloadAppsInstaller mPreloadAppsInstaller;
-
-    final Object mActivityLock = new Object();
-    // Whether the newly created demo user has interacted with the screen yet
-    @GuardedBy("mActivityLock")
-    boolean mUserUntouched;
-    @GuardedBy("mActivityLock")
-    long mFirstUserActivityTime;
-    @GuardedBy("mActivityLock")
-    long mLastUserActivityTime;
-
-    private boolean mSafeBootRestrictionInitialState;
-    private int mPackageVerifierEnableInitialState;
-
-    private IntentReceiver mBroadcastReceiver = null;
-
-    private final class IntentReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (!mDeviceInDemoMode) {
-                return;
-            }
-            final String action = intent.getAction();
-            switch (action) {
-                case Intent.ACTION_SCREEN_OFF:
-                    mHandler.removeMessages(MSG_TURN_SCREEN_ON);
-                    mHandler.sendEmptyMessageDelayed(MSG_TURN_SCREEN_ON, SCREEN_WAKEUP_DELAY);
-                    break;
-                case ACTION_RESET_DEMO:
-                    mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
-                    break;
-            }
-        }
-    };
-
-    final class MainHandler extends Handler {
-
-        MainHandler(Looper looper) {
-            super(looper, null, true);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            if (!mDeviceInDemoMode) {
-                return;
-            }
-            switch (msg.what) {
-                case MSG_TURN_SCREEN_ON:
-                    if (mInjector.isWakeLockHeld()) {
-                        mInjector.releaseWakeLock();
-                    }
-                    mInjector.acquireWakeLock();
-                    break;
-                case MSG_INACTIVITY_TIME_OUT:
-                    if (!mIsCarrierDemoMode && isDemoLauncherDisabled()) {
-                        Slog.i(TAG, "User inactivity timeout reached");
-                        showInactivityCountdownDialog();
-                    }
-                    break;
-                case MSG_START_NEW_SESSION:
-                    if (DEBUG) {
-                        Slog.d(TAG, "Switching to a new demo user");
-                    }
-                    removeMessages(MSG_START_NEW_SESSION);
-                    removeMessages(MSG_INACTIVITY_TIME_OUT);
-                    if (!mIsCarrierDemoMode && mCurrentUserId != UserHandle.USER_SYSTEM) {
-                        logSessionDuration();
-                    }
-
-                    final UserManager um = mInjector.getUserManager();
-                    UserInfo demoUser = null;
-                    if (mIsCarrierDemoMode) {
-                        // Re-use the existing demo user in carrier demo mode.
-                        for (UserInfo user : um.getUsers()) {
-                            if (user.isDemo()) {
-                                demoUser = user;
-                                break;
-                            }
-                        }
-                    }
-
-                    if (demoUser == null) {
-                        // User in carrier demo mode should survive reboots.
-                        final int flags = UserInfo.FLAG_DEMO
-                                | (mIsCarrierDemoMode ? 0 : UserInfo.FLAG_EPHEMERAL);
-                        demoUser = um.createUser(DEMO_USER_NAME, flags);
-                    }
-
-                    if (demoUser != null && mCurrentUserId != demoUser.id) {
-                        setupDemoUser(demoUser);
-                        mInjector.switchUser(demoUser.id);
-                    }
-                    break;
-            }
-        }
-    }
-
-    @VisibleForTesting
-    class SettingsObserver extends ContentObserver {
-
-        private final static String KEY_USER_INACTIVITY_TIMEOUT = "user_inactivity_timeout_ms";
-        private final static String KEY_WARNING_DIALOG_TIMEOUT = "warning_dialog_timeout_ms";
-
-        private final Uri mDeviceDemoModeUri = Settings.Global
-                .getUriFor(Settings.Global.DEVICE_DEMO_MODE);
-        private final Uri mDeviceProvisionedUri = Settings.Global
-                .getUriFor(Settings.Global.DEVICE_PROVISIONED);
-        private final Uri mRetailDemoConstantsUri = Settings.Global
-                .getUriFor(Settings.Global.RETAIL_DEMO_MODE_CONSTANTS);
-
-        private final KeyValueListParser mParser = new KeyValueListParser(',');
-
-        public SettingsObserver(Handler handler) {
-            super(handler);
-        }
-
-        public void register() {
-            final ContentResolver cr = mInjector.getContentResolver();
-            cr.registerContentObserver(mDeviceDemoModeUri, false, this, UserHandle.USER_SYSTEM);
-            cr.registerContentObserver(mDeviceProvisionedUri, false, this, UserHandle.USER_SYSTEM);
-            cr.registerContentObserver(mRetailDemoConstantsUri, false, this,
-                    UserHandle.USER_SYSTEM);
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            if (mRetailDemoConstantsUri.equals(uri)) {
-                refreshTimeoutConstants();
-                return;
-            }
-
-            // If device is provisioned and left demo mode - run the cleanup in demo folder
-            if (isDeviceProvisioned()) {
-                if (UserManager.isDeviceInDemoMode(getContext())) {
-                    startDemoMode();
-                } else {
-                    mInjector.systemPropertiesSet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, "0");
-
-                    // Run on the bg thread to not block the fg thread
-                    BackgroundThread.getHandler().post(() -> {
-                        if (!deletePreloadsFolderContents()) {
-                            Slog.w(TAG, "Failed to delete preloads folder contents");
-                        }
-                        PreloadsFileCacheExpirationJobService.schedule(mInjector.getContext());
-                    });
-
-                    stopDemoMode();
-
-                    if (mInjector.isWakeLockHeld()) {
-                        mInjector.releaseWakeLock();
-                    }
-                }
-            }
-        }
-
-        private void refreshTimeoutConstants() {
-            try {
-                mParser.setString(Settings.Global.getString(mInjector.getContentResolver(),
-                        Settings.Global.RETAIL_DEMO_MODE_CONSTANTS));
-            } catch (IllegalArgumentException exc) {
-                Slog.e(TAG, "Invalid string passed to KeyValueListParser");
-                // Consuming the exception to fall back to default values.
-            }
-            mWarningDialogTimeout = mParser.getLong(KEY_WARNING_DIALOG_TIMEOUT,
-                    WARNING_DIALOG_TIMEOUT_DEFAULT);
-            mUserInactivityTimeout = mParser.getLong(KEY_USER_INACTIVITY_TIMEOUT,
-                    USER_INACTIVITY_TIMEOUT_DEFAULT);
-            mUserInactivityTimeout = Math.max(mUserInactivityTimeout, USER_INACTIVITY_TIMEOUT_MIN);
-        }
-    }
-
-    private void showInactivityCountdownDialog() {
-        UserInactivityCountdownDialog dialog = new UserInactivityCountdownDialog(getContext(),
-                mWarningDialogTimeout, MILLIS_PER_SECOND);
-        dialog.setNegativeButtonClickListener(null);
-        dialog.setPositiveButtonClickListener(new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
-            }
-        });
-        dialog.setOnCountDownExpiredListener(new OnCountDownExpiredListener() {
-            @Override
-            public void onCountDownExpired() {
-                mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
-            }
-        });
-        dialog.show();
-    }
-
-    public RetailDemoModeService(Context context) {
-        this(new Injector(context));
-    }
-
-    @VisibleForTesting
-    RetailDemoModeService(Injector injector) {
-        super(injector.getContext());
-
-        mInjector = injector;
-        synchronized (mActivityLock) {
-            mFirstUserActivityTime = mLastUserActivityTime = SystemClock.uptimeMillis();
-        }
-    }
-
-    boolean isDemoLauncherDisabled() {
-        int enabledState = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
-        try {
-            final IPackageManager iPm = mInjector.getIPackageManager();
-            final String demoLauncherComponent =
-                    getContext().getString(R.string.config_demoModeLauncherComponent);
-            enabledState = iPm.getComponentEnabledSetting(
-                    ComponentName.unflattenFromString(demoLauncherComponent), mCurrentUserId);
-        } catch (RemoteException re) {
-            Slog.e(TAG, "Error retrieving demo launcher enabled setting", re);
-        }
-        return enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
-    }
-
-    private void setupDemoUser(UserInfo userInfo) {
-        final UserManager um = mInjector.getUserManager();
-        final UserHandle user = UserHandle.of(userInfo.id);
-        um.setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, user);
-        um.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true, user);
-        um.setUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, true, user);
-        um.setUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER, true, user);
-        um.setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user);
-        um.setUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, true, user);
-        // Set this to false because the default is true on user creation
-        um.setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, false, user);
-        // Disallow rebooting in safe mode - controlled by user 0
-        um.setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, true, UserHandle.SYSTEM);
-        if (mIsCarrierDemoMode) {
-            // Enable SMS in carrier demo mode.
-            um.setUserRestriction(UserManager.DISALLOW_SMS, false, user);
-        }
-
-        Settings.Secure.putIntForUser(mInjector.getContentResolver(),
-                Settings.Secure.SKIP_FIRST_USE_HINTS, 1, userInfo.id);
-        Settings.Global.putInt(mInjector.getContentResolver(),
-                Settings.Global.PACKAGE_VERIFIER_ENABLE, 0);
-
-        grantRuntimePermissionToCamera(user);
-        clearPrimaryCallLog();
-
-        if (!mIsCarrierDemoMode) {
-            // Enable demo launcher.
-            final String demoLauncher = getContext().getString(
-                    R.string.config_demoModeLauncherComponent);
-            if (!TextUtils.isEmpty(demoLauncher)) {
-                final ComponentName componentToEnable =
-                        ComponentName.unflattenFromString(demoLauncher);
-                final String packageName = componentToEnable.getPackageName();
-                try {
-                    final IPackageManager iPm = AppGlobals.getPackageManager();
-                    iPm.setComponentEnabledSetting(componentToEnable,
-                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id);
-                    iPm.setApplicationEnabledSetting(packageName,
-                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id, null);
-                } catch (RemoteException re) {
-                    // Internal, shouldn't happen
-                }
-            }
-        } else {
-            // Set the carrier demo mode setting for the demo user.
-            final String carrierDemoModeSetting = getContext().getString(
-                    R.string.config_carrierDemoModeSetting);
-            Settings.Secure.putIntForUser(getContext().getContentResolver(),
-                    carrierDemoModeSetting, 1, userInfo.id);
-
-            // Enable packages for carrier demo mode.
-            final String packageList = getContext().getString(
-                    R.string.config_carrierDemoModePackages);
-            final String[] packageNames = packageList == null ? new String[0]
-                    : TextUtils.split(packageList, ",");
-            final IPackageManager iPm = AppGlobals.getPackageManager();
-            for (String packageName : packageNames) {
-                try {
-                    iPm.setApplicationEnabledSetting(packageName,
-                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id, null);
-                } catch (RemoteException re) {
-                    Slog.e(TAG, "Error enabling application: " + packageName, re);
-                }
-            }
-        }
-    }
-
-    private void grantRuntimePermissionToCamera(UserHandle user) {
-        final Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
-        final PackageManager pm = mInjector.getPackageManager();
-        final ResolveInfo handler = pm.resolveActivityAsUser(cameraIntent,
-                PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                user.getIdentifier());
-        if (handler == null || handler.activityInfo == null) {
-            return;
-        }
-        try {
-            pm.grantRuntimePermission(handler.activityInfo.packageName,
-                    Manifest.permission.ACCESS_FINE_LOCATION, user);
-        } catch (Exception e) {
-            // Ignore
-        }
-    }
-
-    private void clearPrimaryCallLog() {
-        final ContentResolver resolver = mInjector.getContentResolver();
-
-        // Deleting primary user call log so that it doesn't get copied to the new demo user
-        final Uri uri = CallLog.Calls.CONTENT_URI;
-        try {
-            resolver.delete(uri, null, null);
-        } catch (Exception e) {
-            Slog.w(TAG, "Deleting call log failed: " + e);
-        }
-    }
-
-    void logSessionDuration() {
-        final int sessionDuration;
-        synchronized (mActivityLock) {
-            sessionDuration = (int) ((mLastUserActivityTime - mFirstUserActivityTime) / 1000);
-        }
-        mInjector.logSessionDuration(sessionDuration);
-    }
-
-    private boolean isDeviceProvisioned() {
-        return Settings.Global.getInt(
-                mInjector.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
-    }
-
-    /**
-     * Deletes contents of {@link Environment#getDataPreloadsDirectory()},
-     * but leave {@link Environment#getDataPreloadsFileCacheDirectory()}
-     * @return true if contents was sucessfully deleted
-     */
-    private boolean deletePreloadsFolderContents() {
-        final File dir = mInjector.getDataPreloadsDirectory();
-        final File[] files = FileUtils.listFilesOrEmpty(dir);
-        final File fileCacheDirectory = mInjector.getDataPreloadsFileCacheDirectory();
-        Slog.i(TAG, "Deleting contents of " + dir);
-        boolean success = true;
-        for (File file : files) {
-            if (file.isFile()) {
-                if (!file.delete()) {
-                    success = false;
-                    Slog.w(TAG, "Cannot delete file " + file);
-                }
-            } else {
-                // Do not remove file_cache dir
-                if (!file.equals(fileCacheDirectory)) {
-                    if (!FileUtils.deleteContentsAndDir(file)) {
-                        success = false;
-                        Slog.w(TAG, "Cannot delete dir and its content " + file);
-                    }
-                } else {
-                    Slog.i(TAG, "Skipping directory with file cache " + file);
-                }
-            }
-        }
-        return success;
-    }
-
-    private void registerBroadcastReceiver() {
-        if (mBroadcastReceiver != null) {
-            return;
-        }
-
-        final IntentFilter filter = new IntentFilter();
-        if (!mIsCarrierDemoMode) {
-            filter.addAction(Intent.ACTION_SCREEN_OFF);
-        }
-        filter.addAction(ACTION_RESET_DEMO);
-        mBroadcastReceiver = new IntentReceiver();
-        getContext().registerReceiver(mBroadcastReceiver, filter);
-    }
-
-    private void unregisterBroadcastReceiver() {
-        if (mBroadcastReceiver != null) {
-            getContext().unregisterReceiver(mBroadcastReceiver);
-            mBroadcastReceiver = null;
-        }
-    }
-
-    private String[] getCameraIdsWithFlash() {
-        ArrayList<String> cameraIdsList = new ArrayList<String>();
-        final CameraManager cm = mInjector.getCameraManager();
-        if (cm != null) {
-            try {
-                for (String cameraId : cm.getCameraIdList()) {
-                    CameraCharacteristics c = cm.getCameraCharacteristics(cameraId);
-                    if (Boolean.TRUE.equals(c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE))) {
-                        cameraIdsList.add(cameraId);
-                    }
-                }
-            } catch (CameraAccessException e) {
-                Slog.e(TAG, "Unable to access camera while getting camera id list", e);
-            }
-        }
-        return cameraIdsList.toArray(new String[cameraIdsList.size()]);
-    }
-
-    private void muteVolumeStreams() {
-        for (int stream : VOLUME_STREAMS_TO_MUTE) {
-            mInjector.getAudioManager().setStreamVolume(stream,
-                    mInjector.getAudioManager().getStreamMinVolume(stream), 0);
-        }
-    }
-
-    private void startDemoMode() {
-        mDeviceInDemoMode = true;
-
-        mPreloadAppsInstaller = mInjector.getPreloadAppsInstaller();
-        mInjector.initializeWakeLock();
-        if (mCameraIdsWithFlash == null) {
-            mCameraIdsWithFlash = getCameraIdsWithFlash();
-        }
-        registerBroadcastReceiver();
-
-        final String carrierDemoModeSetting =
-                getContext().getString(R.string.config_carrierDemoModeSetting);
-        mIsCarrierDemoMode = !TextUtils.isEmpty(carrierDemoModeSetting)
-                && (Settings.Secure.getInt(getContext().getContentResolver(),
-                        carrierDemoModeSetting, 0) == 1);
-
-        mInjector.systemPropertiesSet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, "1");
-        mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
-
-        mSafeBootRestrictionInitialState = mInjector.getUserManager().hasUserRestriction(
-                UserManager.DISALLOW_SAFE_BOOT, UserHandle.SYSTEM);
-        mPackageVerifierEnableInitialState = Settings.Global.getInt(mInjector.getContentResolver(),
-                Settings.Global.PACKAGE_VERIFIER_ENABLE, 1);
-    }
-
-    private void stopDemoMode() {
-        mPreloadAppsInstaller = null;
-        mCameraIdsWithFlash = null;
-        mInjector.destroyWakeLock();
-        unregisterBroadcastReceiver();
-
-        if (mDeviceInDemoMode) {
-            mInjector.getUserManager().setUserRestriction(UserManager.DISALLOW_SAFE_BOOT,
-                    mSafeBootRestrictionInitialState, UserHandle.SYSTEM);
-            Settings.Global.putInt(mInjector.getContentResolver(),
-                        Settings.Global.PACKAGE_VERIFIER_ENABLE,
-                        mPackageVerifierEnableInitialState);
-        }
-
-        mDeviceInDemoMode = false;
-        mIsCarrierDemoMode = false;
-    }
-
-    @Override
-    public void onStart() {
-        if (DEBUG) {
-            Slog.d(TAG, "Service starting up");
-        }
-        mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND,
-                false);
-        mHandlerThread.start();
-        mHandler = new MainHandler(mHandlerThread.getLooper());
-        mInjector.publishLocalService(this, mLocalService);
-    }
-
-    @Override
-    public void onBootPhase(int bootPhase) {
-        switch (bootPhase) {
-            case PHASE_THIRD_PARTY_APPS_CAN_START:
-                final SettingsObserver settingsObserver = new SettingsObserver(mHandler);
-                settingsObserver.register();
-                settingsObserver.refreshTimeoutConstants();
-                break;
-            case PHASE_BOOT_COMPLETED:
-                if (UserManager.isDeviceInDemoMode(getContext())) {
-                    startDemoMode();
-                }
-                break;
-        }
-    }
-
-    @Override
-    public void onSwitchUser(int userId) {
-        if (!mDeviceInDemoMode) {
-            return;
-        }
-        if (DEBUG) {
-            Slog.d(TAG, "onSwitchUser: " + userId);
-        }
-        final UserInfo ui = mInjector.getUserManager().getUserInfo(userId);
-        if (!ui.isDemo()) {
-            Slog.wtf(TAG, "Should not allow switch to non-demo user in demo mode");
-            return;
-        }
-        if (!mIsCarrierDemoMode && !mInjector.isWakeLockHeld()) {
-            mInjector.acquireWakeLock();
-        }
-        mCurrentUserId = userId;
-        mInjector.getActivityManagerInternal().updatePersistentConfigurationForUser(
-                mInjector.getSystemUsersConfiguration(), userId);
-
-        mInjector.turnOffAllFlashLights(mCameraIdsWithFlash);
-        muteVolumeStreams();
-        if (!mInjector.getWifiManager().isWifiEnabled()) {
-            mInjector.getWifiManager().setWifiEnabled(true);
-        }
-
-        // Disable lock screen for demo users.
-        mInjector.getLockPatternUtils().setLockScreenDisabled(true, userId);
-
-        if (!mIsCarrierDemoMode) {
-            // Show reset notification (except in carrier demo mode).
-            mInjector.getNotificationManager().notifyAsUser(TAG, SystemMessage.NOTE_RETAIL_RESET,
-                    mInjector.createResetNotification(), UserHandle.of(userId));
-
-            synchronized (mActivityLock) {
-                mUserUntouched = true;
-            }
-            mInjector.logSessionCount(1);
-            mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT);
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mPreloadAppsInstaller.installApps(userId);
-                }
-            });
-        }
-    }
-
-    private RetailDemoModeServiceInternal mLocalService = new RetailDemoModeServiceInternal() {
-        private static final long USER_ACTIVITY_DEBOUNCE_TIME = 2000;
-
-        @Override
-        public void onUserActivity() {
-            if (!mDeviceInDemoMode || mIsCarrierDemoMode) {
-                return;
-            }
-            long timeOfActivity = SystemClock.uptimeMillis();
-            synchronized (mActivityLock) {
-                if (timeOfActivity < mLastUserActivityTime + USER_ACTIVITY_DEBOUNCE_TIME) {
-                    return;
-                }
-                mLastUserActivityTime = timeOfActivity;
-                if (mUserUntouched && isDemoLauncherDisabled()) {
-                    Slog.d(TAG, "retail_demo first touch");
-                    mUserUntouched = false;
-                    mFirstUserActivityTime = timeOfActivity;
-                }
-            }
-            mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT);
-            mHandler.sendEmptyMessageDelayed(MSG_INACTIVITY_TIME_OUT, mUserInactivityTimeout);
-        }
-    };
-
-    static class Injector {
-        private Context mContext;
-        private UserManager mUm;
-        private PackageManager mPm;
-        private NotificationManager mNm;
-        private ActivityManagerService mAms;
-        private ActivityManagerInternal mAmi;
-        private AudioManager mAudioManager;
-        private PowerManager mPowerManager;
-        private CameraManager mCameraManager;
-        private PowerManager.WakeLock mWakeLock;
-        private WifiManager mWifiManager;
-        private Configuration mSystemUserConfiguration;
-        private PendingIntent mResetDemoPendingIntent;
-        private PreloadAppsInstaller mPreloadAppsInstaller;
-
-        Injector(Context context) {
-            mContext = context;
-        }
-
-        Context getContext() {
-            return mContext;
-        }
-
-        WifiManager getWifiManager() {
-            if (mWifiManager == null) {
-                mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
-            }
-            return mWifiManager;
-        }
-
-        UserManager getUserManager() {
-            if (mUm == null) {
-                mUm = getContext().getSystemService(UserManager.class);
-            }
-            return mUm;
-        }
-
-        void switchUser(int userId) {
-            if (mAms == null) {
-                mAms = (ActivityManagerService) ActivityManager.getService();
-            }
-            mAms.switchUser(userId);
-        }
-
-        AudioManager getAudioManager() {
-            if (mAudioManager == null) {
-                mAudioManager = getContext().getSystemService(AudioManager.class);
-            }
-            return mAudioManager;
-        }
-
-        private PowerManager getPowerManager() {
-            if (mPowerManager == null) {
-                mPowerManager = (PowerManager) getContext().getSystemService(
-                        Context.POWER_SERVICE);
-            }
-            return mPowerManager;
-        }
-
-        NotificationManager getNotificationManager() {
-            if (mNm == null) {
-                mNm = NotificationManager.from(getContext());
-            }
-            return mNm;
-        }
-
-        ActivityManagerInternal getActivityManagerInternal() {
-            if (mAmi == null) {
-                mAmi = LocalServices.getService(ActivityManagerInternal.class);
-            }
-            return mAmi;
-        }
-
-        CameraManager getCameraManager() {
-            if (mCameraManager == null) {
-                mCameraManager = (CameraManager) getContext().getSystemService(
-                        Context.CAMERA_SERVICE);
-            }
-            return mCameraManager;
-        }
-
-        PackageManager getPackageManager() {
-            if (mPm == null) {
-                mPm = getContext().getPackageManager();
-            }
-            return mPm;
-        }
-
-        IPackageManager getIPackageManager() {
-            return AppGlobals.getPackageManager();
-        }
-
-        ContentResolver getContentResolver() {
-            return getContext().getContentResolver();
-        }
-
-        PreloadAppsInstaller getPreloadAppsInstaller() {
-            if (mPreloadAppsInstaller == null) {
-                mPreloadAppsInstaller = new PreloadAppsInstaller(getContext());
-            }
-            return mPreloadAppsInstaller;
-        }
-
-        void systemPropertiesSet(String key, String value) {
-            SystemProperties.set(key, value);
-        }
-
-        void turnOffAllFlashLights(String[] cameraIdsWithFlash) {
-            for (String cameraId : cameraIdsWithFlash) {
-                try {
-                    getCameraManager().setTorchMode(cameraId, false);
-                } catch (CameraAccessException e) {
-                    Slog.e(TAG, "Unable to access camera " + cameraId
-                            + " while turning off flash", e);
-                }
-            }
-        }
-
-        void initializeWakeLock() {
-            if (mWakeLock == null) {
-                mWakeLock = getPowerManager().newWakeLock(
-                        PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG);
-            }
-        }
-
-        void destroyWakeLock() {
-            mWakeLock = null;
-        }
-
-        boolean isWakeLockHeld() {
-            return mWakeLock != null && mWakeLock.isHeld();
-        }
-
-        void acquireWakeLock() {
-            mWakeLock.acquire();
-        }
-
-        void releaseWakeLock() {
-            mWakeLock.release();
-        }
-
-        void logSessionDuration(int duration) {
-            MetricsLogger.histogram(getContext(), DEMO_SESSION_DURATION, duration);
-        }
-
-        void logSessionCount(int count) {
-            MetricsLogger.count(getContext(), DEMO_SESSION_COUNT, count);
-        }
-
-        Configuration getSystemUsersConfiguration() {
-            if (mSystemUserConfiguration == null) {
-                Settings.System.getConfiguration(getContentResolver(),
-                        mSystemUserConfiguration = new Configuration());
-            }
-            return mSystemUserConfiguration;
-        }
-
-        LockPatternUtils getLockPatternUtils() {
-            return new LockPatternUtils(getContext());
-        }
-
-        Notification createResetNotification() {
-            return new Notification.Builder(getContext(), SystemNotificationChannels.RETAIL_MODE)
-                    .setContentTitle(getContext().getString(R.string.reset_retail_demo_mode_title))
-                    .setContentText(getContext().getString(R.string.reset_retail_demo_mode_text))
-                    .setOngoing(true)
-                    .setSmallIcon(R.drawable.platlogo)
-                    .setShowWhen(false)
-                    .setVisibility(Notification.VISIBILITY_PUBLIC)
-                    .setContentIntent(getResetDemoPendingIntent())
-                    .setColor(getContext().getColor(R.color.system_notification_accent_color))
-                    .build();
-        }
-
-        private PendingIntent getResetDemoPendingIntent() {
-            if (mResetDemoPendingIntent == null) {
-                Intent intent = new Intent(ACTION_RESET_DEMO);
-                mResetDemoPendingIntent = PendingIntent.getBroadcast(getContext(), 0, intent, 0);
-            }
-            return mResetDemoPendingIntent;
-        }
-
-        File getDataPreloadsDirectory() {
-            return Environment.getDataPreloadsDirectory();
-        }
-
-        File getDataPreloadsFileCacheDirectory() {
-            return Environment.getDataPreloadsFileCacheDirectory();
-        }
-
-        void publishLocalService(RetailDemoModeService service,
-                RetailDemoModeServiceInternal localService) {
-            service.publishLocalService(RetailDemoModeServiceInternal.class, localService);
-        }
-    }
-}
diff --git a/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java b/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java
deleted file mode 100644
index 013eab8..0000000
--- a/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java
+++ /dev/null
@@ -1,105 +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.server.retaildemo;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.os.CountDownTimer;
-import android.view.WindowManager;
-import android.widget.TextView;
-
-import com.android.internal.R;
-
-public class UserInactivityCountdownDialog extends AlertDialog {
-
-    private OnCountDownExpiredListener mOnCountDownExpiredListener;
-    private CountDownTimer mCountDownTimer;
-    private long mCountDownDuration;
-    private long mRefreshInterval;
-
-    UserInactivityCountdownDialog(Context context, long duration, long refreshInterval) {
-        super(context);
-        mCountDownDuration = duration;
-        mRefreshInterval = refreshInterval;
-
-        getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
-        WindowManager.LayoutParams attrs = getWindow().getAttributes();
-        attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-        getWindow().setAttributes(attrs);
-
-        setTitle(R.string.demo_user_inactivity_timeout_title);
-        setMessage(getContext().getString(R.string.demo_user_inactivity_timeout_countdown,
-                duration));
-    }
-
-    public void setOnCountDownExpiredListener(
-            OnCountDownExpiredListener onCountDownExpiredListener) {
-        mOnCountDownExpiredListener = onCountDownExpiredListener;
-    }
-
-    public void setPositiveButtonClickListener(OnClickListener onClickListener) {
-        setButton(Dialog.BUTTON_POSITIVE,
-                getContext().getString(R.string.demo_user_inactivity_timeout_right_button),
-                onClickListener);
-    }
-
-    public void setNegativeButtonClickListener(OnClickListener onClickListener) {
-        setButton(Dialog.BUTTON_NEGATIVE,
-                getContext().getString(R.string.demo_user_inactivity_timeout_left_button),
-                onClickListener);
-    }
-
-    @Override
-    public void show() {
-        super.show();
-        final TextView messageView = findViewById(R.id.message);
-        messageView.post(new Runnable() {
-            @Override
-            public void run() {
-                mCountDownTimer = new CountDownTimer(mCountDownDuration, mRefreshInterval) {
-
-                    @Override
-                    public void onTick(long millisUntilFinished) {
-                        String msg = getContext().getString(
-                                R.string.demo_user_inactivity_timeout_countdown,
-                                millisUntilFinished / 1000);
-                        messageView.setText(msg);
-                    }
-
-                    @Override
-                    public void onFinish() {
-                        dismiss();
-                        if (mOnCountDownExpiredListener != null)
-                            mOnCountDownExpiredListener.onCountDownExpired();
-                    }
-                }.start();
-            }
-        });
-    }
-
-    @Override
-    public void onStop() {
-        if (mCountDownTimer != null) {
-            mCountDownTimer.cancel();
-        }
-    }
-
-    interface OnCountDownExpiredListener {
-        void onCountDownExpired();
-    }
-}
diff --git a/services/tests/notification/Android.mk b/services/tests/notification/Android.mk
index 0ffe6e4..597a584 100644
--- a/services/tests/notification/Android.mk
+++ b/services/tests/notification/Android.mk
@@ -18,7 +18,6 @@
     services.core \
     services.devicepolicy \
     services.net \
-    services.retaildemo \
     services.usage \
     guava \
     android-support-test \
diff --git a/services/tests/notification/AndroidManifest.xml b/services/tests/notification/AndroidManifest.xml
index 99d9c7b..c20020a 100644
--- a/services/tests/notification/AndroidManifest.xml
+++ b/services/tests/notification/AndroidManifest.xml
@@ -31,7 +31,7 @@
     </application>
 
     <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:name="android.testing.TestableInstrumentation"
         android:targetPackage="com.android.frameworks.tests.notification"
         android:label="Notification Tests" />
 </manifest>
diff --git a/services/tests/notification/AndroidTest.xml b/services/tests/notification/AndroidTest.xml
index 46fdccc..fa77407 100644
--- a/services/tests/notification/AndroidTest.xml
+++ b/services/tests/notification/AndroidTest.xml
@@ -19,8 +19,9 @@
     </target_preparer>
 
     <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="framework-base-presubmit" />
     <option name="test-tag" value="FrameworksNotificationTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.tests.notification" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/services/tests/notification/src/com/android/server/notification/AlertRateLimiterTest.java b/services/tests/notification/src/com/android/server/notification/AlertRateLimiterTest.java
new file mode 100644
index 0000000..faf6a9b
--- /dev/null
+++ b/services/tests/notification/src/com/android/server/notification/AlertRateLimiterTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.server.notification;
+
+import static com.android.server.notification.AlertRateLimiter.ALLOWED_ALERT_INTERVAL;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AlertRateLimiterTest extends NotificationTestCase {
+
+    private long mTestStartTime;
+    private
+    AlertRateLimiter mLimiter;
+
+    @Before
+    public void setUp() {
+        mTestStartTime = 1225731600000L;
+        mLimiter = new AlertRateLimiter();
+    }
+
+    @Test
+    public void testFirstAlertAllowed() throws Exception {
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime));
+    }
+
+    @Test
+    public void testAllowedAfterSecond() throws Exception {
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime));
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime + ALLOWED_ALERT_INTERVAL));
+    }
+
+    @Test
+    public void testAllowedAfterSecondEvenWithBlockedEntries() throws Exception {
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime));
+        assertTrue(mLimiter.shouldRateLimitAlert(mTestStartTime + ALLOWED_ALERT_INTERVAL - 1));
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime + ALLOWED_ALERT_INTERVAL));
+    }
+
+    @Test
+    public void testAllowedDisallowedBeforeSecond() throws Exception {
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime));
+        assertTrue(mLimiter.shouldRateLimitAlert(mTestStartTime + ALLOWED_ALERT_INTERVAL - 1));
+    }
+
+    @Test
+    public void testDisallowedTimePast() throws Exception {
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime));
+        assertTrue(mLimiter.shouldRateLimitAlert(mTestStartTime - ALLOWED_ALERT_INTERVAL));
+    }
+}
diff --git a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
index ae98274..ef347fd 100644
--- a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -23,18 +23,14 @@
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 
+import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyObject;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.argThat;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
 
 import android.app.ActivityManager;
 import android.app.Notification;
@@ -56,6 +52,8 @@
 import android.service.notification.StatusBarNotification;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
 
 import com.android.server.lights.Light;
 
@@ -76,6 +74,7 @@
     @Mock android.media.IRingtonePlayer mRingtonePlayer;
     @Mock Light mLight;
     @Mock Handler mHandler;
+    @Mock NotificationUsageStats mUsageStats;
 
     private NotificationManagerService mService;
     private String mPkg = "com.android.server.notification";
@@ -108,6 +107,9 @@
 
     @Before
     public void setUp() {
+        // Magic to allow spying package-private methods on system classes
+        System.setProperty("dexmaker.share_classloader", "true");
+
         MockitoAnnotations.initMocks(this);
 
         when(mAudioManager.isAudioFocusExclusive()).thenReturn(false);
@@ -115,7 +117,10 @@
         when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10);
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
 
-        mService = new NotificationManagerService(getContext());
+        when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
+
+        mService = spy(new NotificationManagerService(getContext()));
+        doNothing().when(mService).sendAccessibilityEvent((Notification) any(), anyString());
         mService.setAudioManager(mAudioManager);
         mService.setVibrator(mVibrator);
         mService.setSystemReady(true);
@@ -123,6 +128,7 @@
         mService.setLights(mLight);
         mService.setScreenOn(false);
         mService.setFallbackVibrationPattern(FALLBACK_VIBRATION_PATTERN);
+        mService.setUsageStats(mUsageStats);
     }
 
     //
@@ -352,6 +358,16 @@
                 eq(CUSTOM_LIGHT_COLOR), anyInt(), eq(CUSTOM_LIGHT_ON), eq(CUSTOM_LIGHT_OFF));
     }
 
+    private void verifySendAccessibilityEvent() {
+        verify(mService, times(1))
+                .sendAccessibilityEvent((Notification) anyObject(), anyString());
+    }
+
+    private void verifyNoAccessibilityEvent() {
+        verify(mService, never())
+                .sendAccessibilityEvent((Notification) anyObject(), anyString());
+    }
+
     //
     // Tests
     //
@@ -374,6 +390,7 @@
 
         verifyBeepLooped();
         verifyNeverVibrate();
+        verifySendAccessibilityEvent();
     }
 
     @Test
@@ -383,6 +400,7 @@
         mService.buzzBeepBlinkLocked(r);
 
         verifyBeep();
+        verifySendAccessibilityEvent();
     }
 
     @Test
@@ -403,6 +421,7 @@
 
         verifyNeverBeep();
         verifyNeverVibrate();
+        verifyNoAccessibilityEvent();
     }
 
     @Test
@@ -414,6 +433,7 @@
 
         verifyNeverBeep();
         verifyNeverVibrate();
+        verifyNoAccessibilityEvent();
     }
 
     @Test
@@ -439,10 +459,12 @@
         // set up internal state
         mService.buzzBeepBlinkLocked(r);
         Mockito.reset(mRingtonePlayer);
+        Mockito.reset(mService);
 
         // update should not beep
         mService.buzzBeepBlinkLocked(s);
         verifyNeverBeep();
+        verifyNoAccessibilityEvent();
     }
 
     @Test
@@ -585,6 +607,7 @@
 
         verifyNeverBeep();
         verifyVibrate();
+        verifySendAccessibilityEvent();
     }
 
     @Test
@@ -683,10 +706,12 @@
         // set up internal state
         mService.buzzBeepBlinkLocked(r);
         Mockito.reset(mVibrator);
+        Mockito.reset(mService);
 
         // update should not beep
         mService.buzzBeepBlinkLocked(s);
         verifyNeverVibrate();
+        verifyNoAccessibilityEvent();
     }
 
     @Test
@@ -806,6 +831,49 @@
         verifyNeverBeep();
     }
 
+    @Test
+    public void testRepeatedSoundOverLimitMuted() throws Exception {
+        when(mUsageStats.isAlertRateLimited(any())).thenReturn(true);
+
+        NotificationRecord r = getBeepyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+        verifyNeverBeep();
+    }
+
+    @Test
+    public void testPostingSilentNotificationDoesNotAffectRateLimiting() throws Exception {
+        NotificationRecord r = getQuietNotification();
+        mService.buzzBeepBlinkLocked(r);
+
+        verify(mUsageStats, never()).isAlertRateLimited(any());
+    }
+
+    @Test
+    public void testPostingGroupSuppressedDoesNotAffectRateLimiting() throws Exception {
+        NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_CHILDREN);
+        summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
+
+        mService.buzzBeepBlinkLocked(summary);
+
+        verify(mUsageStats, never()).isAlertRateLimited(any());
+    }
+
+    @Test
+    public void testCrossUserSoundMuted() throws Exception {
+        final Notification n = new Builder(getContext(), "test")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
+
+        int userId = mUser.getIdentifier() + 1;
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
+                mPid, n, UserHandle.of(userId), null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(getContext(), sbn,
+                new NotificationChannel("test", "test", IMPORTANCE_HIGH));
+
+        mService.buzzBeepBlinkLocked(r);
+        verifyNeverBeep();
+    }
+
     static class VibrateRepeatMatcher implements ArgumentMatcher<VibrationEffect> {
         private final int mRepeatIndex;
 
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationChannelTest.java b/services/tests/notification/src/com/android/server/notification/NotificationChannelTest.java
index 3007cb1..f457f6a 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationChannelTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationChannelTest.java
@@ -25,8 +25,14 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.internal.util.FastXmlSerializer;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -50,4 +56,15 @@
         channel.setBlockableSystem(true);
         assertEquals(true, channel.isBlockableSystem());
     }
+
+    @Test
+    public void testEmptyVibration_noException() throws Exception {
+        NotificationChannel channel = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
+        channel.setVibrationPattern(new long[0]);
+
+        XmlSerializer serializer = new FastXmlSerializer();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
+        channel.writeXml(serializer);
+    }
 }
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
index 46c536c..3801697 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -18,6 +18,7 @@
 
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_NONE;
+import static android.content.pm.PackageManager.PERMISSION_DENIED;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
@@ -50,12 +51,14 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.graphics.Color;
+import android.media.AudioManager;
 import android.os.Binder;
 import android.os.Process;
 import android.os.UserHandle;
 import android.provider.Settings.Secure;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
@@ -73,12 +76,12 @@
 import com.android.server.lights.Light;
 import com.android.server.lights.LightsManager;
 
+@SmallTest
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 public class NotificationManagerServiceTest extends NotificationTestCase {
-    private static final long WAIT_FOR_IDLE_TIMEOUT = 2;
     private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
-    private final int uid = Binder.getCallingUid();
+    private final int mUid = Binder.getCallingUid();
     private NotificationManagerService mNotificationManagerService;
     private INotificationManager mBinderService;
     private NotificationManagerInternal mInternalService;
@@ -93,6 +96,8 @@
     private RankingHelper mRankingHelper;
     @Mock
     private NotificationUsageStats mUsageStats;
+    @Mock
+    private AudioManager mAudioManager;
     private NotificationChannel mTestNotificationChannel = new NotificationChannel(
             TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
     @Mock
@@ -128,29 +133,36 @@
         // most tests assume badging is enabled
         Secure.putIntForUser(getContext().getContentResolver(),
                 Secure.NOTIFICATION_BADGING, 1,
-                UserHandle.getUserHandleForUid(uid).getIdentifier());
+                UserHandle.getUserHandleForUid(mUid).getIdentifier());
 
         mNotificationManagerService = new TestableNotificationManagerService(mContext);
 
         // MockPackageManager - default returns ApplicationInfo with matching calling UID
         final ApplicationInfo applicationInfo = new ApplicationInfo();
-        applicationInfo.uid = uid;
+        applicationInfo.uid = mUid;
         when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
                 .thenReturn(applicationInfo);
         when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
                 .thenReturn(applicationInfo);
         final LightsManager mockLightsManager = mock(LightsManager.class);
         when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class));
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
         // Use this testable looper.
         mTestableLooper = TestableLooper.get(this);
 
         mListener = mNotificationListeners.new ManagedServiceInfo(
-                null, new ComponentName(PKG, "test_class"), uid, true, null, 0);
+                null, new ComponentName(PKG, "test_class"), mUid, true, null, 0);
         when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
-        mNotificationManagerService.init(mTestableLooper.getLooper(), mPackageManager,
-                mPackageManagerClient, mockLightsManager, mNotificationListeners, mCompanionMgr,
-                mSnoozeHelper, mUsageStats);
-
+        try {
+            mNotificationManagerService.init(mTestableLooper.getLooper(), mPackageManager,
+                    mPackageManagerClient, mockLightsManager, mNotificationListeners,
+                    mCompanionMgr, mSnoozeHelper, mUsageStats);
+        } catch (SecurityException e) {
+            if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
+                throw e;
+            }
+        }
+        mNotificationManagerService.setAudioManager(mAudioManager);
         // Tests call directly into the Binder.
         mBinderService = mNotificationManagerService.getBinderService();
         mInternalService = mNotificationManagerService.getInternalService();
@@ -171,8 +183,8 @@
                 .setGroup(groupKey)
                 .setGroupSummary(isSummary);
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id, "tag", uid, 0,
-                nb.build(), new UserHandle(uid), null, 0);
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id, "tag", mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
         return new NotificationRecord(mContext, sbn, channel);
     }
     private NotificationRecord generateNotificationRecord(NotificationChannel channel) {
@@ -190,8 +202,8 @@
         if (extender != null) {
             nb.extend(extender);
         }
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", uid, 0,
-                nb.build(), new UserHandle(uid), null, 0);
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
         return new NotificationRecord(mContext, sbn, channel);
     }
 
@@ -199,17 +211,17 @@
     public void testCreateNotificationChannels_SingleChannel() throws Exception {
         final NotificationChannel channel =
                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
-        mBinderService.createNotificationChannels("test_pkg",
+        mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(channel)));
         final NotificationChannel createdChannel =
-                mBinderService.getNotificationChannel("test_pkg", "id");
+                mBinderService.getNotificationChannel(PKG, "id");
         assertTrue(createdChannel != null);
     }
 
     @Test
     public void testCreateNotificationChannels_NullChannelThrowsException() throws Exception {
         try {
-            mBinderService.createNotificationChannels("test_pkg",
+            mBinderService.createNotificationChannels(PKG,
                     new ParceledListSlice(Arrays.asList(null)));
             fail("Exception should be thrown immediately.");
         } catch (NullPointerException e) {
@@ -223,28 +235,33 @@
                 new NotificationChannel("id1", "name", NotificationManager.IMPORTANCE_DEFAULT);
         final NotificationChannel channel2 =
                 new NotificationChannel("id2", "name", NotificationManager.IMPORTANCE_DEFAULT);
-        mBinderService.createNotificationChannels("test_pkg",
+        mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(channel1, channel2)));
-        assertTrue(mBinderService.getNotificationChannel("test_pkg", "id1") != null);
-        assertTrue(mBinderService.getNotificationChannel("test_pkg", "id2") != null);
+        assertTrue(mBinderService.getNotificationChannel(PKG, "id1") != null);
+        assertTrue(mBinderService.getNotificationChannel(PKG, "id2") != null);
     }
 
     @Test
-    public void testCreateNotificationChannels_SecondCreateDoesNotChangeImportance()
+    public void testCreateNotificationChannels_CannotDowngradeImportanceIfAlreadyUpdated()
             throws Exception {
         final NotificationChannel channel =
                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
-        mBinderService.createNotificationChannels("test_pkg",
+        mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(channel)));
 
-        // Recreating the channel doesn't throw, but ignores importance.
-        final NotificationChannel dupeChannel =
+        // The user modifies importance directly, can no longer be changed by the app.
+        final NotificationChannel updatedChannel =
                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_HIGH);
-        mBinderService.createNotificationChannels("test_pkg",
+        mBinderService.updateNotificationChannelForPackage(PKG, mUid, updatedChannel);
+
+        // Recreating with a lower importance leaves channel unchanged.
+        final NotificationChannel dupeChannel =
+                new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW);
+        mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(dupeChannel)));
         final NotificationChannel createdChannel =
-                mBinderService.getNotificationChannel("test_pkg", "id");
-        assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
+                mBinderService.getNotificationChannel(PKG, "id");
+        assertEquals(NotificationManager.IMPORTANCE_HIGH, createdChannel.getImportance());
     }
 
     @Test
@@ -254,10 +271,10 @@
                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
         final NotificationChannel channel2 =
                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_HIGH);
-        mBinderService.createNotificationChannels("test_pkg",
+        mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(channel1, channel2)));
         final NotificationChannel createdChannel =
-                mBinderService.getNotificationChannel("test_pkg", "id");
+                mBinderService.getNotificationChannel(PKG, "id");
         assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
     }
 
@@ -288,7 +305,7 @@
     public void testEnqueuedBlockedNotifications_blockedApp() throws Exception {
         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
 
-        mBinderService.setNotificationsEnabledForPackage(PKG, uid, false);
+        mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
 
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
@@ -302,9 +319,9 @@
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
                 generateNotificationRecord(null).getNotification(), 0);
         waitForIdle();
-        StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
         assertEquals(1, notifs.length);
+        assertEquals(1, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -316,6 +333,7 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(PKG);
         assertEquals(0, notifs.length);
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -330,6 +348,7 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(PKG);
         assertEquals(0, notifs.length);
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -342,6 +361,7 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
         assertEquals(0, notifs.length);
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -354,6 +374,43 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
         assertEquals(0, notifs.length);
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
+    }
+
+    @Test
+    public void testUserInitiatedClearAll_noLeak() throws Exception {
+        final NotificationRecord n = generateNotificationRecord(
+                mTestNotificationChannel, 1, "group", true);
+
+        mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+                n.sbn.getId(), n.sbn.getNotification(), n.sbn.getUserId());
+        waitForIdle();
+
+        mNotificationManagerService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
+                n.getUserId());
+        waitForIdle();
+        StatusBarNotification[] notifs =
+                mBinderService.getActiveNotifications(n.sbn.getPackageName());
+        assertEquals(0, notifs.length);
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
+    }
+
+    @Test
+    public void testCancelAllNotificationsCancelsChildren() throws Exception {
+        final NotificationRecord parent = generateNotificationRecord(
+                mTestNotificationChannel, 1, "group1", true);
+        final NotificationRecord child = generateNotificationRecord(
+                mTestNotificationChannel, 2, "group1", false);
+
+        mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+                parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+                child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
+        waitForIdle();
+
+        mBinderService.cancelAllNotifications(PKG, parent.sbn.getUserId());
+        waitForIdle();
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -365,6 +422,8 @@
         }
         mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
         waitForIdle();
+
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -391,6 +450,8 @@
                 parentAsChild.sbn.getId(), parentAsChild.sbn.getNotification(),
                 parentAsChild.sbn.getUserId());
         waitForIdle();
+
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -404,6 +465,7 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
         assertEquals(1, notifs.length);
+        assertEquals(1, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -417,6 +479,7 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
         assertEquals(1, notifs.length);
+        assertEquals(1, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -429,6 +492,7 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
         assertEquals(0, notifs.length);
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -442,6 +506,7 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
         assertEquals(1, notifs.length);
+        assertEquals(1, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -471,6 +536,7 @@
         mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
         waitForIdle();
         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -546,7 +612,7 @@
     public void testCreateChannelNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
@@ -571,7 +637,7 @@
     public void testCreateChannelGroupNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         NotificationChannelGroup group1 = new NotificationChannelGroup("a", "b");
         NotificationChannelGroup group2 = new NotificationChannelGroup("n", "m");
@@ -591,7 +657,7 @@
     public void testUpdateChannelNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         mTestNotificationChannel.setLightColor(Color.CYAN);
         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
@@ -609,7 +675,7 @@
     public void testDeleteChannelNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
@@ -625,7 +691,7 @@
     public void testDeleteChannelGroupNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         NotificationChannelGroup ncg = new NotificationChannelGroup("a", "b/c");
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         when(mRankingHelper.getNotificationChannelGroup(eq(ncg.getId()), eq(PKG), anyInt()))
@@ -642,7 +708,7 @@
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
 
         mBinderService.updateNotificationChannelFromPrivilegedListener(
                 null, PKG, Process.myUserHandle(), mTestNotificationChannel);
@@ -658,7 +724,7 @@
     public void testUpdateNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
 
         try {
             mBinderService.updateNotificationChannelFromPrivilegedListener(
@@ -680,7 +746,7 @@
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
         mListener.component = new ComponentName(PKG, PKG);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
@@ -706,7 +772,7 @@
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
 
         mBinderService.getNotificationChannelsFromPrivilegedListener(
                 null, PKG, Process.myUserHandle());
@@ -719,7 +785,7 @@
     public void testGetNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
 
         try {
             mBinderService.getNotificationChannelsFromPrivilegedListener(
@@ -738,7 +804,7 @@
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
         when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
@@ -760,7 +826,7 @@
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
 
         mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
                 null, PKG, Process.myUserHandle());
@@ -772,7 +838,7 @@
     public void testGetNotificationChannelGroupsFromPrivilegedListener_noAccess() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
 
         try {
             mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
@@ -789,7 +855,7 @@
     public void testGetNotificationChannelGroupsFromPrivilegedListener_badUser() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
         when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
@@ -949,4 +1015,66 @@
 
         verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString());
     }
+
+    @Test
+    public void testNoFakeColorizedPermission() throws Exception {
+        when(mPackageManagerClient.checkPermission(any(), any())).thenReturn(PERMISSION_DENIED);
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setContentTitle("foo")
+                .setColorized(true)
+                .setFlag(Notification.FLAG_CAN_COLORIZE, true)
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        NotificationRecord posted = mNotificationManagerService.findNotificationLocked(
+                PKG, null, nr.sbn.getId(), nr.sbn.getUserId());
+
+        assertFalse(posted.getNotification().isColorized());
+    }
+
+    @Test
+    public void testGetNotificationCountLocked() throws Exception {
+        for (int i = 0; i < 20; i++) {
+            NotificationRecord r =
+                    generateNotificationRecord(mTestNotificationChannel, i, null, false);
+            mNotificationManagerService.addEnqueuedNotification(r);
+        }
+        for (int i = 0; i < 20; i++) {
+            NotificationRecord r =
+                    generateNotificationRecord(mTestNotificationChannel, i, null, false);
+            mNotificationManagerService.addNotification(r);
+        }
+
+        // another package
+        Notification n =
+                new Notification.Builder(mContext, mTestNotificationChannel.getId())
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "tag", mUid, 0,
+                n, new UserHandle(mUid), null, 0);
+        NotificationRecord otherPackage =
+                new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+        mNotificationManagerService.addEnqueuedNotification(otherPackage);
+        mNotificationManagerService.addNotification(otherPackage);
+
+        // Same notifications are enqueued as posted, everything counts b/c id and tag don't match
+        assertEquals(40, mNotificationManagerService.getNotificationCountLocked(
+                PKG, new UserHandle(mUid).getIdentifier(), 0, null));
+        assertEquals(40, mNotificationManagerService.getNotificationCountLocked(
+                PKG, new UserHandle(mUid).getIdentifier(), 0, "tag2"));
+        assertEquals(2, mNotificationManagerService.getNotificationCountLocked(
+                "a", new UserHandle(mUid).getIdentifier(), 0, "banana"));
+
+        // exclude a known notification - it's excluded from only the posted list, not enqueued
+        assertEquals(39, mNotificationManagerService.getNotificationCountLocked(
+                PKG, new UserHandle(mUid).getIdentifier(), 0, "tag"));
+    }
 }
diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk
index 0167232..507b483 100644
--- a/services/tests/servicestests/Android.mk
+++ b/services/tests/servicestests/Android.mk
@@ -15,10 +15,10 @@
     frameworks-base-testutils \
     services.accessibility \
     services.appwidget \
+    services.backup \
     services.core \
     services.devicepolicy \
     services.net \
-    services.retaildemo \
     services.usage \
     guava \
     android-support-test \
diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml
index 4622d50..63f3b756 100644
--- a/services/tests/servicestests/AndroidTest.xml
+++ b/services/tests/servicestests/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="FrameworksServicesTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.servicestests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/services/tests/servicestests/res/raw/backup_file_with_long_name b/services/tests/servicestests/res/raw/backup_file_with_long_name
new file mode 100644
index 0000000..265a0ba
--- /dev/null
+++ b/services/tests/servicestests/res/raw/backup_file_with_long_name
Binary files differ
diff --git a/services/tests/servicestests/res/raw/backup_telephony_no_password b/services/tests/servicestests/res/raw/backup_telephony_no_password
new file mode 100644
index 0000000..12b6cbf
--- /dev/null
+++ b/services/tests/servicestests/res/raw/backup_telephony_no_password
Binary files differ
diff --git a/services/tests/servicestests/res/raw/backup_telephony_with_password b/services/tests/servicestests/res/raw/backup_telephony_with_password
new file mode 100644
index 0000000..ce847a3
--- /dev/null
+++ b/services/tests/servicestests/res/raw/backup_telephony_with_password
Binary files differ
diff --git a/services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java
deleted file mode 100644
index d9d06ae..0000000
--- a/services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java
+++ /dev/null
@@ -1,161 +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.server;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.app.IActivityManager;
-import android.app.NotificationManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
-import android.content.pm.UserInfo;
-import android.os.FileUtils;
-import android.os.IProgressListener;
-import android.os.UserManager;
-import android.os.storage.StorageManager;
-import android.security.KeyStore;
-import android.test.AndroidTestCase;
-
-import com.android.internal.widget.LockPatternUtils;
-
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-
-public class BaseLockSettingsServiceTests extends AndroidTestCase {
-    protected static final int PRIMARY_USER_ID = 0;
-    protected static final int MANAGED_PROFILE_USER_ID = 12;
-    protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
-    protected static final int SECONDARY_USER_ID = 20;
-
-    private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER_ID, null, null,
-            UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
-    private static final UserInfo SECONDARY_USER_INFO = new UserInfo(SECONDARY_USER_ID, null, null,
-            UserInfo.FLAG_INITIALIZED);
-
-    private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
-
-    LockSettingsService mService;
-
-    MockLockSettingsContext mContext;
-    LockSettingsStorageTestable mStorage;
-
-    LockPatternUtils mLockPatternUtils;
-    MockGateKeeperService mGateKeeperService;
-    NotificationManager mNotificationManager;
-    UserManager mUserManager;
-    MockStorageManager mStorageManager;
-    IActivityManager mActivityManager;
-    DevicePolicyManager mDevicePolicyManager;
-    KeyStore mKeyStore;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mLockPatternUtils = mock(LockPatternUtils.class);
-        mGateKeeperService = new MockGateKeeperService();
-        mNotificationManager = mock(NotificationManager.class);
-        mUserManager = mock(UserManager.class);
-        mStorageManager = new MockStorageManager();
-        mActivityManager = mock(IActivityManager.class);
-        mDevicePolicyManager = mock(DevicePolicyManager.class);
-        mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager,
-                mDevicePolicyManager, mock(StorageManager.class));
-        mStorage = new LockSettingsStorageTestable(mContext,
-                new File(getContext().getFilesDir(), "locksettings"));
-        File storageDir = mStorage.mStorageDir;
-        if (storageDir.exists()) {
-            FileUtils.deleteContents(storageDir);
-        } else {
-            storageDir.mkdirs();
-        }
-
-        mService = new LockSettingsServiceTestable(mContext, mLockPatternUtils,
-                mStorage, mGateKeeperService, mKeyStore, mStorageManager, mActivityManager);
-        when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO);
-        mPrimaryUserProfiles.add(PRIMARY_USER_INFO);
-        installChildProfile(MANAGED_PROFILE_USER_ID);
-        installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
-        when(mUserManager.getProfiles(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserProfiles);
-        when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO);
-
-        when(mActivityManager.unlockUser(anyInt(), any(), any(), any())).thenAnswer(
-                new Answer<Boolean>() {
-            @Override
-            public Boolean answer(InvocationOnMock invocation) throws Throwable {
-                Object[] args = invocation.getArguments();
-                mStorageManager.unlockUser((int)args[0], (byte[])args[2],
-                        (IProgressListener) args[3]);
-                return true;
-            }
-        });
-
-        when(mLockPatternUtils.getLockSettings()).thenReturn(mService);
-
-        // Adding a fake Device Owner app which will enable escrow token support in LSS.
-        when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(
-                new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
-    }
-
-    private UserInfo installChildProfile(int profileId) {
-        final UserInfo userInfo = new UserInfo(
-            profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE);
-        mPrimaryUserProfiles.add(userInfo);
-        when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
-        when(mUserManager.getProfileParent(eq(profileId))).thenReturn(PRIMARY_USER_INFO);
-        when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true);
-        when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true);
-        return userInfo;
-    }
-
-    private UserInfo installAndTurnOffChildProfile(int profileId) {
-        final UserInfo userInfo = installChildProfile(profileId);
-        userInfo.flags |= UserInfo.FLAG_QUIET_MODE;
-        when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false);
-        when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false);
-        return userInfo;
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mStorage.closeDatabase();
-        File db = getContext().getDatabasePath("locksettings.db");
-        assertTrue(!db.exists() || db.delete());
-
-        File storageDir = mStorage.mStorageDir;
-        assertTrue(FileUtils.deleteContents(storageDir));
-    }
-
-    protected static void assertArrayEquals(byte[] expected, byte[] actual) {
-        assertTrue(Arrays.equals(expected, actual));
-    }
-
-    protected static void assertArrayNotSame(byte[] expected, byte[] actual) {
-        assertFalse(Arrays.equals(expected, actual));
-    }
-}
-
diff --git a/services/tests/servicestests/src/com/android/server/BootReceiverFixFsckFsStatTest.java b/services/tests/servicestests/src/com/android/server/BootReceiverFixFsckFsStatTest.java
index 362c47a..69c1499 100644
--- a/services/tests/servicestests/src/com/android/server/BootReceiverFixFsckFsStatTest.java
+++ b/services/tests/servicestests/src/com/android/server/BootReceiverFixFsckFsStatTest.java
@@ -52,13 +52,13 @@
                 " ",
                 "/dev/block/platform/soc/624000.ufshc/by-name/userdata: ***** FILE SYSTEM WAS MODIFIED *****"
         };
-        doTestFsckFsStat(logs, 0x405, 5, 0, logs.length);
+        doTestFsckFsStat(logs, 0x405, 0x5, 0, logs.length);
 
         final String[] doubleLogs = new String[logs.length * 2];
         System.arraycopy(logs, 0, doubleLogs, 0, logs.length);
         System.arraycopy(logs, 0, doubleLogs, logs.length, logs.length);
-        doTestFsckFsStat(doubleLogs, 0x401, 1, 0, logs.length);
-        doTestFsckFsStat(doubleLogs, 0x402, 2, logs.length, logs.length * 2);
+        doTestFsckFsStat(doubleLogs, 0x401, 0x1, 0, logs.length);
+        doTestFsckFsStat(doubleLogs, 0x402, 0x2, logs.length, logs.length * 2);
     }
 
     @Test
@@ -79,6 +79,7 @@
                 " ",
                 "/dev/block/platform/soc/624000.ufshc/by-name/userdata: ***** FILE SYSTEM WAS MODIFIED *****"
         };
+        // quota fix without tree optimization is an error.
         doTestFsckFsStat(logs, 0x405, 0x405, 0, logs.length);
     }
 
@@ -103,6 +104,92 @@
         doTestFsckFsStat(logs, 0x405, 0x405, 0, logs.length);
     }
 
+    @Test
+    public void testTimestampAdjustment() {
+        final String[] logs = {
+                "e2fsck 1.43.3 (04-Sep-2016)",
+                "Pass 1: Checking inodes, blocks, and sizes",
+                "Timestamp(s) on inode 508580 beyond 2310-04-04 are likely pre-1970.",
+                "Fix? yes",
+                " ",
+                "Pass 1E: Optimizing extent trees",
+                "Pass 2: Checking directory structure",
+                "Pass 3: Checking directory connectivity",
+                "Pass 4: Checking reference counts",
+                "Pass 5: Checking group summary information",
+                " ",
+                "/dev/block/platform/soc/624000.ufshc/by-name/userdata: ***** FILE SYSTEM WAS MODIFIED *****"
+        };
+        doTestFsckFsStat(logs, 0x405, 0x5, 0, logs.length);
+    }
+
+    @Test
+    public void testTimestampAdjustmentNoFixLine() {
+        final String[] logs = {
+                "e2fsck 1.43.3 (04-Sep-2016)",
+                "Pass 1: Checking inodes, blocks, and sizes",
+                "Timestamp(s) on inode 508580 beyond 2310-04-04 are likely pre-1970.",
+                " ",
+                "Pass 1E: Optimizing extent trees",
+                "Pass 2: Checking directory structure",
+                "Pass 3: Checking directory connectivity",
+                "Pass 4: Checking reference counts",
+                "Pass 5: Checking group summary information",
+                " ",
+                "/dev/block/platform/soc/624000.ufshc/by-name/userdata: ***** FILE SYSTEM WAS MODIFIED *****"
+        };
+        doTestFsckFsStat(logs, 0x405, 0x5, 0, logs.length);
+    }
+
+    @Test
+    public void testTimestampAdjustmentWithQuotaFix() {
+        final String[] logs = {
+                "e2fsck 1.43.3 (04-Sep-2016)",
+                "Pass 1: Checking inodes, blocks, and sizes",
+                "Timestamp(s) on inode 508580 beyond 2310-04-04 are likely pre-1970.",
+                "Fix? yes",
+                " ",
+                "Pass 1E: Optimizing extent trees",
+                "Pass 2: Checking directory structure",
+                "Pass 3: Checking directory connectivity",
+                "Pass 4: Checking reference counts",
+                "Pass 5: Checking group summary information",
+                "[QUOTA WARNING] Usage inconsistent for ID 10038:actual (71667712, 1000) != expected (71671808, 1000)",
+                "Update quota info for quota type 0? yes",
+                " ",
+                "[QUOTA WARNING] Usage inconsistent for ID 10038:actual (59555840, 953) != expected (59559936, 953)",
+                "Update quota info for quota type 1? yes",
+                " ",
+                "/dev/block/platform/soc/624000.ufshc/by-name/userdata: ***** FILE SYSTEM WAS MODIFIED *****"
+        };
+        doTestFsckFsStat(logs, 0x405, 0x405, 0, logs.length);
+    }
+
+    @Test
+    public void testAllNonFixes() {
+        final String[] logs = {
+                "e2fsck 1.43.3 (04-Sep-2016)",
+                "Pass 1: Checking inodes, blocks, and sizes",
+                "Timestamp(s) on inode 508580 beyond 2310-04-04 are likely pre-1970.",
+                "Fix? yes",
+                "Inode 877141 extent tree (at level 1) could be shorter.  Fix? yes",
+                " ",
+                "Pass 1E: Optimizing extent trees",
+                "Pass 2: Checking directory structure",
+                "Pass 3: Checking directory connectivity",
+                "Pass 4: Checking reference counts",
+                "Pass 5: Checking group summary information",
+                "[QUOTA WARNING] Usage inconsistent for ID 10038:actual (71667712, 1000) != expected (71671808, 1000)",
+                "Update quota info for quota type 0? yes",
+                " ",
+                "[QUOTA WARNING] Usage inconsistent for ID 10038:actual (59555840, 953) != expected (59559936, 953)",
+                "Update quota info for quota type 1? yes",
+                " ",
+                "/dev/block/platform/soc/624000.ufshc/by-name/userdata: ***** FILE SYSTEM WAS MODIFIED *****"
+        };
+        doTestFsckFsStat(logs, 0x405, 0x5, 0, logs.length);
+    }
+
     private void doTestFsckFsStat(String[] lines, int statOrg, int statUpdated, int startLineNumber,
             int endLineNumber) {
         assertEquals(statUpdated, BootReceiver.fixFsckFsStat(PARTITION, statOrg, lines,
diff --git a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
new file mode 100644
index 0000000..33e4165
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
@@ -0,0 +1,846 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.StatusBarManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.mock.MockContentResolver;
+import android.view.KeyEvent;
+import android.util.MutableBoolean;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.server.LocalServices;
+import com.android.server.statusbar.StatusBarManagerInternal;
+
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests for {@link GestureLauncherService}.
+ * runtest frameworks-services -c com.android.server.GestureLauncherServiceTest
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class GestureLauncherServiceTest {
+
+    private static final int FAKE_USER_ID = 1337;
+    private static final int FAKE_SOURCE = 1982;
+    private static final long INITIAL_EVENT_TIME_MILLIS = 20000L;
+    private static final long IGNORED_DOWN_TIME = 1234L;
+    private static final int IGNORED_ACTION = 13;
+    private static final int IGNORED_CODE = 1999;
+    private static final int IGNORED_REPEAT = 42;
+
+    private @Mock Context mContext;
+    private @Mock Resources mResources;
+    private @Mock StatusBarManagerInternal mStatusBarManagerInternal;
+    private @Mock MetricsLogger mMetricsLogger;
+    private MockContentResolver mContentResolver;
+    private GestureLauncherService mGestureLauncherService;
+
+    @BeforeClass
+    public static void oneTimeInitialization() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+    }
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+        LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
+        LocalServices.addService(StatusBarManagerInternal.class, mStatusBarManagerInternal);
+
+        final Context originalContext = InstrumentationRegistry.getContext();
+        when(mContext.getApplicationInfo()).thenReturn(originalContext.getApplicationInfo());
+        when(mContext.getResources()).thenReturn(mResources);
+        mContentResolver = new MockContentResolver(mContext);
+        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        when(mContext.getContentResolver()).thenReturn(mContentResolver);
+
+        mGestureLauncherService = new GestureLauncherService(mContext, mMetricsLogger);
+    }
+
+    @Test
+    public void testIsCameraDoubleTapPowerEnabled_configFalse() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        assertFalse(mGestureLauncherService.isCameraDoubleTapPowerEnabled(mResources));
+    }
+
+    @Test
+    public void testIsCameraDoubleTapPowerEnabled_configTrue() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        assertTrue(mGestureLauncherService.isCameraDoubleTapPowerEnabled(mResources));
+    }
+
+    @Test
+    public void testIsCameraDoubleTapPowerSettingEnabled_configFalseSettingDisabled() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
+                mContext, FAKE_USER_ID));
+    }
+
+    @Test
+    public void testIsCameraDoubleTapPowerSettingEnabled_configFalseSettingEnabled() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
+                mContext, FAKE_USER_ID));
+    }
+
+    @Test
+    public void testIsCameraDoubleTapPowerSettingEnabled_configTrueSettingDisabled() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
+                mContext, FAKE_USER_ID));
+    }
+
+    @Test
+    public void testIsCameraDoubleTapPowerSettingEnabled_configTrueSettingEnabled() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        assertTrue(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
+                mContext, FAKE_USER_ID));
+    }
+
+    @Test
+    public void testHandleCameraLaunchGesture_userSetupComplete() {
+        withUserSetupCompleteValue(true);
+
+        boolean useWakeLock = false;
+        assertTrue(mGestureLauncherService.handleCameraGesture(useWakeLock, FAKE_SOURCE));
+        verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(FAKE_SOURCE);
+    }
+
+    @Test
+    public void testHandleCameraLaunchGesture_userSetupNotComplete() {
+        withUserSetupCompleteValue(false);
+
+        boolean useWakeLock = false;
+        assertFalse(mGestureLauncherService.handleCameraGesture(useWakeLock, FAKE_SOURCE));
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_firstPowerDownCameraPowerGestureOnInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS +
+                GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+        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);
+        verify(mMetricsLogger).histogram("power_consecutive_short_tap_count", 1);
+        verify(mMetricsLogger).histogram("power_double_tap_interval", (int) eventTime);
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOffInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        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);
+        outLaunched.value = true;
+        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(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOffInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        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;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        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(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        // The interval is too long to launch the camera, but short enough to count as a
+        // sequential tap.
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOffInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        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);
+
+        long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        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(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(1, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void
+    testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnInteractiveSetupComplete() {
+        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);
+        outLaunched.value = false;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertTrue(intercepted);
+        assertTrue(outLaunched.value);
+
+        verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(
+                StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
+        verify(mMetricsLogger)
+            .action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, (int) interval);
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void
+    testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnInteractiveSetupIncomplete() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+        withUserSetupCompleteValue(false);
+
+        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);
+        outLaunched.value = true;
+        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(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        // The interval is too long to launch the camera, but short enough to count as a
+        // sequential tap.
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOnInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        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;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        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(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        // The interval is too long to launch the camera, but short enough to count as a
+        // sequential tap.
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOnInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        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);
+
+        long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        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(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(1, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOffNotInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = false;
+        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);
+        outLaunched.value = true;
+        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(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOffNotInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = false;
+        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;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        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(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        // The interval is too long to launch the camera, but short enough to count as a
+        // sequential tap.
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOffNotInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = false;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        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(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(1, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void
+    testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnNotInteractiveSetupComplete() {
+        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 = false;
+        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);
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertTrue(outLaunched.value);
+
+        verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(
+                StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
+        verify(mMetricsLogger)
+            .action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, (int) interval);
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void
+    testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnNotInteractiveSetupIncomplete() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+        withUserSetupCompleteValue(false);
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = false;
+        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);
+        outLaunched.value = true;
+        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(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOnNotInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = false;
+        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;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        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(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        // The interval is too long to launch the camera, but short enough to count as a
+        // sequential tap.
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOnNotInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = false;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        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(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(1, tapCounts.get(1).intValue());
+    }
+
+    private void withCameraDoubleTapPowerEnableConfigValue(boolean enableConfigValue) {
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled))
+                .thenReturn(enableConfigValue);
+    }
+
+    private void withCameraDoubleTapPowerDisableSettingValue(int disableSettingValue) {
+        Settings.Secure.putIntForUser(
+                mContentResolver,
+                Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
+                disableSettingValue,
+                UserHandle.USER_CURRENT);
+    }
+
+    private void withUserSetupCompleteValue(boolean userSetupComplete) {
+        int userSetupCompleteValue = userSetupComplete ? 1 : 0;
+        Settings.Secure.putIntForUser(
+                mContentResolver,
+                Settings.Secure.USER_SETUP_COMPLETE,
+                userSetupCompleteValue,
+                UserHandle.USER_CURRENT);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/LockSettingsServiceTestable.java
deleted file mode 100644
index cfdb5b1..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsServiceTestable.java
+++ /dev/null
@@ -1,138 +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;
-
-import static org.mockito.Mockito.mock;
-
-import android.app.IActivityManager;
-import android.content.Context;
-import android.os.Handler;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.storage.IStorageManager;
-import android.security.KeyStore;
-import android.security.keystore.KeyPermanentlyInvalidatedException;
-
-import com.android.internal.widget.LockPatternUtils;
-
-import java.io.FileNotFoundException;
-
-public class LockSettingsServiceTestable extends LockSettingsService {
-
-    private static class MockInjector extends LockSettingsService.Injector {
-
-        private LockSettingsStorage mLockSettingsStorage;
-        private KeyStore mKeyStore;
-        private IActivityManager mActivityManager;
-        private LockPatternUtils mLockPatternUtils;
-        private IStorageManager mStorageManager;
-        private MockGateKeeperService mGatekeeper;
-
-        public MockInjector(Context context, LockSettingsStorage storage, KeyStore keyStore,
-                IActivityManager activityManager, LockPatternUtils lockPatternUtils,
-                IStorageManager storageManager, MockGateKeeperService gatekeeper) {
-            super(context);
-            mLockSettingsStorage = storage;
-            mKeyStore = keyStore;
-            mActivityManager = activityManager;
-            mLockPatternUtils = lockPatternUtils;
-            mStorageManager = storageManager;
-            mGatekeeper = gatekeeper;
-        }
-
-        @Override
-        public Handler getHandler() {
-            return mock(Handler.class);
-        }
-
-        @Override
-        public LockSettingsStorage getStorage() {
-            return mLockSettingsStorage;
-        }
-
-        @Override
-        public LockSettingsStrongAuth getStrongAuth() {
-            return mock(LockSettingsStrongAuth.class);
-        }
-
-        @Override
-        public SynchronizedStrongAuthTracker getStrongAuthTracker() {
-            return mock(SynchronizedStrongAuthTracker.class);
-        }
-
-        @Override
-        public IActivityManager getActivityManager() {
-            return mActivityManager;
-        }
-
-        @Override
-        public LockPatternUtils getLockPatternUtils() {
-            return mLockPatternUtils;
-        }
-
-        @Override
-        public KeyStore getKeyStore() {
-            return mKeyStore;
-        }
-
-        @Override
-        public IStorageManager getStorageManager() {
-            return mStorageManager;
-        }
-
-        @Override
-        public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) {
-            return new MockSyntheticPasswordManager(storage, mGatekeeper);
-        }
-
-        @Override
-        public int binderGetCallingUid() {
-            return Process.SYSTEM_UID;
-        }
-
-
-    }
-
-    protected LockSettingsServiceTestable(Context context, LockPatternUtils lockPatternUtils,
-            LockSettingsStorage storage, MockGateKeeperService gatekeeper, KeyStore keystore,
-            IStorageManager storageManager, IActivityManager mActivityManager) {
-        super(new MockInjector(context, storage, keystore, mActivityManager, lockPatternUtils,
-                storageManager, gatekeeper));
-        mGateKeeperService = gatekeeper;
-    }
-
-    @Override
-    protected void tieProfileLockToParent(int userId, String password) {
-        mStorage.writeChildProfileLock(userId, password.getBytes());
-    }
-
-    @Override
-    protected String getDecryptedPasswordForTiedProfile(int userId) throws FileNotFoundException, KeyPermanentlyInvalidatedException {
-        byte[] storedData = mStorage.readChildProfileLock(userId);
-        if (storedData == null) {
-            throw new FileNotFoundException("Child profile lock file not found");
-        }
-        try {
-            if (mGateKeeperService.getSecureUserId(userId) == 0) {
-                throw new KeyPermanentlyInvalidatedException();
-            }
-        } catch (RemoteException e) {
-            // shouldn't happen.
-        }
-        return new String(storedData);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/LockSettingsServiceTests.java
deleted file mode 100644
index 25cc426..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsServiceTests.java
+++ /dev/null
@@ -1,245 +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.server;
-
-import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
-import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
-import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
-
-import android.os.RemoteException;
-import android.service.gatekeeper.GateKeeperResponse;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.VerifyCredentialResponse;
-import com.android.server.LockSettingsStorage.CredentialHash;
-import com.android.server.MockGateKeeperService.VerifyHandle;
-
-/**
- * runtest frameworks-services -c com.android.server.LockSettingsServiceTests
- */
-public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    public void testCreatePasswordPrimaryUser() throws RemoteException {
-        testCreateCredential(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD);
-    }
-
-    public void testCreatePatternPrimaryUser() throws RemoteException {
-        testCreateCredential(PRIMARY_USER_ID, "123456789", CREDENTIAL_TYPE_PATTERN);
-    }
-
-    public void testChangePasswordPrimaryUser() throws RemoteException {
-        testChangeCredentials(PRIMARY_USER_ID, "78963214", CREDENTIAL_TYPE_PATTERN,
-                "asdfghjk", CREDENTIAL_TYPE_PASSWORD);
-    }
-
-    public void testChangePatternPrimaryUser() throws RemoteException {
-        testChangeCredentials(PRIMARY_USER_ID, "!£$%^&*(())", CREDENTIAL_TYPE_PASSWORD,
-                "1596321", CREDENTIAL_TYPE_PATTERN);
-    }
-
-    public void testChangePasswordFailPrimaryUser() throws RemoteException {
-        final long sid = 1234;
-        final String FAILED_MESSAGE = "Failed to enroll password";
-        initializeStorageWithCredential(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid);
-
-        try {
-            mService.setLockCredential("newpwd", CREDENTIAL_TYPE_PASSWORD, "badpwd",
-                    PRIMARY_USER_ID);
-            fail("Did not fail when enrolling using incorrect credential");
-        } catch (RemoteException expected) {
-            assertTrue(expected.getMessage().equals(FAILED_MESSAGE));
-        }
-        try {
-            mService.setLockCredential("newpwd", CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-            fail("Did not fail when enrolling using incorrect credential");
-        } catch (RemoteException expected) {
-            assertTrue(expected.getMessage().equals(FAILED_MESSAGE));
-        }
-        assertVerifyCredentials(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid);
-    }
-
-    public void testClearPasswordPrimaryUser() throws RemoteException {
-        final String PASSWORD = "password";
-        initializeStorageWithCredential(PRIMARY_USER_ID, PASSWORD, CREDENTIAL_TYPE_PASSWORD, 1234);
-        mService.setLockCredential(null, CREDENTIAL_TYPE_NONE, PASSWORD, PRIMARY_USER_ID);
-        assertFalse(mService.havePassword(PRIMARY_USER_ID));
-        assertFalse(mService.havePattern(PRIMARY_USER_ID));
-        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-    }
-
-    public void testManagedProfileUnifiedChallenge() throws RemoteException {
-        final String UnifiedPassword = "testManagedProfileUnifiedChallenge-pwd";
-        mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PRIMARY_USER_ID);
-        mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
-        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
-        final long turnedOffProfileSid =
-                mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID);
-        assertTrue(primarySid != 0);
-        assertTrue(profileSid != 0);
-        assertTrue(profileSid != primarySid);
-        assertTrue(turnedOffProfileSid != 0);
-        assertTrue(turnedOffProfileSid != primarySid);
-        assertTrue(turnedOffProfileSid != profileSid);
-
-        // clear auth token and wait for verify challenge from primary user to re-generate it.
-        mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
-        mGateKeeperService.clearAuthToken(TURNED_OFF_PROFILE_USER_ID);
-        // verify credential
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
-                UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
-                .getResponseCode());
-
-        // Verify that we have a new auth token for the profile
-        assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-
-        // Verify that profile which aren't running (e.g. turn off work) don't get unlocked
-        assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
-
-        /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
-         * credential as part of verifyCredential() before the new credential is committed in
-         * StorageManager. So we relax the check in our mock StorageManager to allow that.
-         */
-        mStorageManager.setIgnoreBadUnlock(true);
-        // Change primary password and verify that profile SID remains
-        mService.setLockCredential("pwd", LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                UnifiedPassword, PRIMARY_USER_ID);
-        mStorageManager.setIgnoreBadUnlock(false);
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-        assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
-
-        // Clear unified challenge
-        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, UnifiedPassword,
-                PRIMARY_USER_ID);
-        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-        assertEquals(0, mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID));
-    }
-
-    public void testManagedProfileSeparateChallenge() throws RemoteException {
-        final String primaryPassword = "testManagedProfileSeparateChallenge-primary";
-        final String profilePassword = "testManagedProfileSeparateChallenge-profile";
-        mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PRIMARY_USER_ID);
-        /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
-         * credential as part of verifyCredential() before the new credential is committed in
-         * StorageManager. So we relax the check in our mock StorageManager to allow that.
-         */
-        mStorageManager.setIgnoreBadUnlock(true);
-        mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                MANAGED_PROFILE_USER_ID);
-        mStorageManager.setIgnoreBadUnlock(false);
-
-        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
-        assertTrue(primarySid != 0);
-        assertTrue(profileSid != 0);
-        assertTrue(profileSid != primarySid);
-
-        // clear auth token and make sure verify challenge from primary user does not regenerate it.
-        mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
-        // verify primary credential
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
-                primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
-                .getResponseCode());
-        assertNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
-
-        // verify profile credential
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
-                profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
-                MANAGED_PROFILE_USER_ID).getResponseCode());
-        assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-
-        // Change primary credential and make sure we don't affect profile
-        mStorageManager.setIgnoreBadUnlock(true);
-        mService.setLockCredential("pwd", LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                primaryPassword, PRIMARY_USER_ID);
-        mStorageManager.setIgnoreBadUnlock(false);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
-                profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
-                MANAGED_PROFILE_USER_ID).getResponseCode());
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-    }
-
-    private void testCreateCredential(int userId, String credential, int type)
-            throws RemoteException {
-        mService.setLockCredential(credential, type, null, userId);
-        assertVerifyCredentials(userId, credential, type, -1);
-    }
-
-    private void testChangeCredentials(int userId, String newCredential, int newType,
-            String oldCredential, int oldType) throws RemoteException {
-        final long sid = 1234;
-        initializeStorageWithCredential(userId, oldCredential, oldType, sid);
-        mService.setLockCredential(newCredential, newType, oldCredential, userId);
-        assertVerifyCredentials(userId, newCredential, newType, sid);
-    }
-
-    private void assertVerifyCredentials(int userId, String credential, int type, long sid)
-            throws RemoteException{
-        final long challenge = 54321;
-        VerifyCredentialResponse response = mService.verifyCredential(credential, type, challenge,
-                userId);
-
-        assertEquals(GateKeeperResponse.RESPONSE_OK, response.getResponseCode());
-        if (sid != -1) assertEquals(sid, mGateKeeperService.getSecureUserId(userId));
-        final int incorrectType;
-        if (type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
-            assertTrue(mService.havePassword(userId));
-            assertFalse(mService.havePattern(userId));
-            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
-        } else if (type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN){
-            assertFalse(mService.havePassword(userId));
-            assertTrue(mService.havePattern(userId));
-            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
-        } else {
-            assertFalse(mService.havePassword(userId));
-            assertFalse(mService.havePassword(userId));
-            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
-        }
-        // check for bad type
-        assertEquals(GateKeeperResponse.RESPONSE_ERROR, mService.verifyCredential(credential,
-                incorrectType, challenge, userId).getResponseCode());
-        // check for bad credential
-        assertEquals(GateKeeperResponse.RESPONSE_ERROR, mService.verifyCredential("0" + credential,
-                type, challenge, userId).getResponseCode());
-    }
-
-    private void initializeStorageWithCredential(int userId, String credential, int type, long sid) {
-        byte[] oldHash = new VerifyHandle(credential.getBytes(), sid).toBytes();
-        if (type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
-            mStorage.writeCredentialHash(CredentialHash.create(oldHash,
-                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
-        } else {
-            mStorage.writeCredentialHash(CredentialHash.create(oldHash,
-                    LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsShellCommandTest.java b/services/tests/servicestests/src/com/android/server/LockSettingsShellCommandTest.java
deleted file mode 100644
index 84ebb19..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsShellCommandTest.java
+++ /dev/null
@@ -1,142 +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.server;
-
-import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
-import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
-
-import static com.android.internal.widget.LockPatternUtils.stringToPattern;
-
-import static junit.framework.Assert.*;
-
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import static java.io.FileDescriptor.*;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.os.Binder;
-import android.os.Debug;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.ResultReceiver;
-import android.os.ShellCallback;
-import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import com.android.internal.widget.LockPatternUtils;
-
-import junit.framework.Assert;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.FileDescriptor;
-
-/**
- * Test class for {@link LockSettingsShellCommand}.
- *
- * runtest frameworks-services -c com.android.server.LockSettingsShellCommandTest
- */
-@SmallTest
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-public class LockSettingsShellCommandTest {
-
-    private LockSettingsShellCommand mCommand;
-
-    private @Mock LockPatternUtils mLockPatternUtils;
-    private int mUserId;
-    private final Binder mBinder = new Binder();
-    private final ShellCallback mShellCallback = new ShellCallback();
-    private final ResultReceiver mResultReceiver = new ResultReceiver(
-            new Handler(Looper.getMainLooper()));
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        final Context context = InstrumentationRegistry.getTargetContext();
-        mUserId = ActivityManager.getCurrentUser();
-        mCommand = new LockSettingsShellCommand(context, mLockPatternUtils);
-    }
-
-    @Test
-    public void testWrongPassword() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(false);
-        assertEquals(-1, mCommand.exec(mBinder, in, out, err,
-                new String[] { "set-pin", "--old", "1234" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils, never()).saveLockPassword(any(), any(), anyInt(), anyInt());
-    }
-
-    @Test
-    public void testChangePin() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(true);
-        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
-                new String[] { "set-pin", "--old", "1234", "4321" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils).saveLockPassword("4321", "1234", PASSWORD_QUALITY_NUMERIC,
-                mUserId);
-    }
-
-    @Test
-    public void testChangePassword() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(true);
-        assertEquals(0,  mCommand.exec(new Binder(), in, out, err,
-                new String[] { "set-password", "--old", "1234", "4321" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils).saveLockPassword("4321", "1234", PASSWORD_QUALITY_ALPHABETIC,
-                mUserId);
-    }
-
-    @Test
-    public void testChangePattern() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.checkPattern(stringToPattern("1234"), mUserId)).thenReturn(true);
-        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
-                new String[] { "set-pattern", "--old", "1234", "4321" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils).saveLockPattern(stringToPattern("4321"), "1234", mUserId);
-    }
-
-    @Test
-    public void testClear() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.checkPattern(stringToPattern("1234"), mUserId)).thenReturn(true);
-        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
-                new String[] { "clear", "--old", "1234" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils).clearLock("1234", mUserId);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsStorageTestable.java b/services/tests/servicestests/src/com/android/server/LockSettingsStorageTestable.java
deleted file mode 100644
index 18da1a5..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsStorageTestable.java
+++ /dev/null
@@ -1,66 +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;
-
-import android.content.Context;
-
-import java.io.File;
-
-public class LockSettingsStorageTestable extends LockSettingsStorage {
-
-    public File mStorageDir;
-
-    public LockSettingsStorageTestable(Context context, File storageDir) {
-        super(context);
-        mStorageDir = storageDir;
-    }
-
-    @Override
-    String getLockPatternFilename(int userId) {
-        return makeDirs(mStorageDir,
-                super.getLockPatternFilename(userId)).getAbsolutePath();
-    }
-
-    @Override
-    String getLockPasswordFilename(int userId) {
-        return makeDirs(mStorageDir,
-                super.getLockPasswordFilename(userId)).getAbsolutePath();
-    }
-
-    @Override
-    String getChildProfileLockFile(int userId) {
-        return makeDirs(mStorageDir,
-                super.getChildProfileLockFile(userId)).getAbsolutePath();
-    }
-
-    @Override
-    protected File getSyntheticPasswordDirectoryForUser(int userId) {
-        return makeDirs(mStorageDir, super.getSyntheticPasswordDirectoryForUser(
-                userId).getAbsolutePath());
-    }
-
-    private File makeDirs(File baseDir, String filePath) {
-        File path = new File(filePath);
-        if (path.getParent() == null) {
-            return new File(baseDir, filePath);
-        } else {
-            File mappedDir = new File(baseDir, path.getParent());
-            mappedDir.mkdirs();
-            return new File(mappedDir, path.getName());
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/LockSettingsStorageTests.java
deleted file mode 100644
index f242b26..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsStorageTests.java
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.app.NotificationManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.pm.UserInfo;
-import android.database.sqlite.SQLiteDatabase;
-import android.os.FileUtils;
-import android.os.UserManager;
-import android.os.storage.StorageManager;
-import android.test.AndroidTestCase;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.server.LockSettingsStorage.CredentialHash;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * runtest frameworks-services -c com.android.server.LockSettingsStorageTests
- */
-public class LockSettingsStorageTests extends AndroidTestCase {
-    private final byte[] PASSWORD_0 = "thepassword0".getBytes();
-    private final byte[] PASSWORD_1 = "password1".getBytes();
-    private final byte[] PATTERN_0 = "123654".getBytes();
-    private final byte[] PATTERN_1 = "147852369".getBytes();
-
-    LockSettingsStorage mStorage;
-    File mStorageDir;
-
-    private File mDb;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mStorageDir = new File(getContext().getFilesDir(), "locksettings");
-        mDb = getContext().getDatabasePath("locksettings.db");
-
-        assertTrue(mStorageDir.exists() || mStorageDir.mkdirs());
-        assertTrue(FileUtils.deleteContents(mStorageDir));
-        assertTrue(!mDb.exists() || mDb.delete());
-
-        final UserManager mockUserManager = mock(UserManager.class);
-        // User 2 is a profile of user 1.
-        when(mockUserManager.getProfileParent(eq(2))).thenReturn(new UserInfo(1, "name", 0));
-        // User 3 is a profile of user 0.
-        when(mockUserManager.getProfileParent(eq(3))).thenReturn(new UserInfo(0, "name", 0));
-
-        MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager,
-                mock(NotificationManager.class), mock(DevicePolicyManager.class),
-                mock(StorageManager.class));
-        mStorage = new LockSettingsStorageTestable(context,
-                new File(getContext().getFilesDir(), "locksettings"));
-        mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
-                    @Override
-                    public void initialize(SQLiteDatabase db) {
-                        mStorage.writeKeyValue(db, "initializedKey", "initialValue", 0);
-                    }
-                });
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mStorage.closeDatabase();
-    }
-
-    public void testKeyValue_InitializeWorked() {
-        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
-        mStorage.clearCache();
-        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
-    }
-
-    public void testKeyValue_WriteThenRead() {
-        mStorage.writeKeyValue("key", "value", 0);
-        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
-        mStorage.clearCache();
-        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
-    }
-
-    public void testKeyValue_DefaultValue() {
-        assertEquals("default", mStorage.readKeyValue("unititialized key", "default", 0));
-        assertEquals("default2", mStorage.readKeyValue("unititialized key", "default2", 0));
-    }
-
-    public void testKeyValue_Concurrency() {
-        final Object monitor = new Object();
-        List<Thread> threads = new ArrayList<>();
-        for (int i = 0; i < 100; i++) {
-            final int threadId = i;
-            threads.add(new Thread() {
-                @Override
-                public void run() {
-                    synchronized (monitor) {
-                        try {
-                            monitor.wait();
-                        } catch (InterruptedException e) {
-                            return;
-                        }
-                        mStorage.writeKeyValue("key", "1 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                        mStorage.writeKeyValue("key", "2 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                        mStorage.writeKeyValue("key", "3 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                        mStorage.writeKeyValue("key", "4 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                        mStorage.writeKeyValue("key", "5 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                    }
-                }
-            });
-            threads.get(i).start();
-        }
-        mStorage.writeKeyValue("key", "initalValue", 0);
-        synchronized (monitor) {
-            monitor.notifyAll();
-        }
-        for (int i = 0; i < threads.size(); i++) {
-            try {
-                threads.get(i).join();
-            } catch (InterruptedException e) {
-            }
-        }
-        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
-        mStorage.clearCache();
-        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
-    }
-
-    public void testKeyValue_CacheStarvedWriter() {
-        final CountDownLatch latch = new CountDownLatch(1);
-        List<Thread> threads = new ArrayList<>();
-        for (int i = 0; i < 100; i++) {
-            final int threadId = i;
-            threads.add(new Thread() {
-                @Override
-                public void run() {
-                    try {
-                        latch.await();
-                    } catch (InterruptedException e) {
-                        return;
-                    }
-                    if (threadId == 50) {
-                        mStorage.writeKeyValue("starvedWriterKey", "value", 0);
-                    } else {
-                        mStorage.readKeyValue("starvedWriterKey", "default", 0);
-                    }
-                }
-            });
-            threads.get(i).start();
-        }
-        latch.countDown();
-        for (int i = 0; i < threads.size(); i++) {
-            try {
-                threads.get(i).join();
-            } catch (InterruptedException e) {
-            }
-        }
-        String cached = mStorage.readKeyValue("key", "default", 0);
-        mStorage.clearCache();
-        String storage = mStorage.readKeyValue("key", "default", 0);
-        assertEquals("Cached value didn't match stored value", storage, cached);
-    }
-
-    public void testRemoveUser() {
-        mStorage.writeKeyValue("key", "value", 0);
-        writePasswordBytes(PASSWORD_0, 0);
-        writePatternBytes(PATTERN_0, 0);
-
-        mStorage.writeKeyValue("key", "value", 1);
-        writePasswordBytes(PASSWORD_1, 1);
-        writePatternBytes(PATTERN_1, 1);
-
-        mStorage.removeUser(0);
-
-        assertEquals("value", mStorage.readKeyValue("key", "default", 1));
-        assertEquals("default", mStorage.readKeyValue("key", "default", 0));
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_NONE, mStorage.readCredentialHash(0).type);
-        assertPatternBytes(PATTERN_1, 1);
-    }
-
-    public void testCredential_Default() {
-        assertEquals(mStorage.readCredentialHash(0).type, LockPatternUtils.CREDENTIAL_TYPE_NONE);
-    }
-
-    public void testPassword_Write() {
-        writePasswordBytes(PASSWORD_0, 0);
-
-        assertPasswordBytes(PASSWORD_0, 0);
-        mStorage.clearCache();
-        assertPasswordBytes(PASSWORD_0, 0);
-    }
-
-    public void testPassword_WriteProfileWritesParent() {
-        writePasswordBytes(PASSWORD_0, 1);
-        writePasswordBytes(PASSWORD_1, 2);
-
-        assertPasswordBytes(PASSWORD_0, 1);
-        assertPasswordBytes(PASSWORD_1, 2);
-        mStorage.clearCache();
-        assertPasswordBytes(PASSWORD_0, 1);
-        assertPasswordBytes(PASSWORD_1, 2);
-    }
-
-    public void testLockType_WriteProfileWritesParent() {
-        writePasswordBytes(PASSWORD_0, 10);
-        writePatternBytes(PATTERN_0, 20);
-
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                mStorage.readCredentialHash(10).type);
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
-                mStorage.readCredentialHash(20).type);
-        mStorage.clearCache();
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                mStorage.readCredentialHash(10).type);
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
-                mStorage.readCredentialHash(20).type);
-    }
-
-    public void testPassword_WriteParentWritesProfile() {
-        writePasswordBytes(PASSWORD_0, 2);
-        writePasswordBytes(PASSWORD_1, 1);
-
-        assertPasswordBytes(PASSWORD_1, 1);
-        assertPasswordBytes(PASSWORD_0, 2);
-        mStorage.clearCache();
-        assertPasswordBytes(PASSWORD_1, 1);
-        assertPasswordBytes(PASSWORD_0, 2);
-    }
-
-    public void testProfileLock_ReadWriteChildProfileLock() {
-        assertFalse(mStorage.hasChildProfileLock(20));
-        mStorage.writeChildProfileLock(20, PASSWORD_0);
-        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
-        assertTrue(mStorage.hasChildProfileLock(20));
-        mStorage.clearCache();
-        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
-        assertTrue(mStorage.hasChildProfileLock(20));
-    }
-
-    public void testPattern_Write() {
-        writePatternBytes(PATTERN_0, 0);
-
-        assertPatternBytes(PATTERN_0, 0);
-        mStorage.clearCache();
-        assertPatternBytes(PATTERN_0, 0);
-    }
-
-    public void testPattern_WriteProfileWritesParent() {
-        writePatternBytes(PATTERN_0, 1);
-        writePatternBytes(PATTERN_1, 2);
-
-        assertPatternBytes(PATTERN_0, 1);
-        assertPatternBytes(PATTERN_1, 2);
-        mStorage.clearCache();
-        assertPatternBytes(PATTERN_0, 1);
-        assertPatternBytes(PATTERN_1, 2);
-    }
-
-    public void testPattern_WriteParentWritesProfile() {
-        writePatternBytes(PATTERN_1, 2);
-        writePatternBytes(PATTERN_0, 1);
-
-        assertPatternBytes(PATTERN_0, 1);
-        assertPatternBytes(PATTERN_1, 2);
-        mStorage.clearCache();
-        assertPatternBytes(PATTERN_0, 1);
-        assertPatternBytes(PATTERN_1, 2);
-    }
-
-    public void testPrefetch() {
-        mStorage.writeKeyValue("key", "toBeFetched", 0);
-        writePatternBytes(PATTERN_0, 0);
-
-        mStorage.clearCache();
-        mStorage.prefetchUser(0);
-
-        assertEquals("toBeFetched", mStorage.readKeyValue("key", "default", 0));
-        assertPatternBytes(PATTERN_0, 0);
-    }
-
-    public void testFileLocation_Owner() {
-        LockSettingsStorage storage = new LockSettingsStorage(getContext());
-
-        assertEquals("/data/system/gesture.key", storage.getLegacyLockPatternFilename(0));
-        assertEquals("/data/system/password.key", storage.getLegacyLockPasswordFilename(0));
-        assertEquals("/data/system/gatekeeper.pattern.key", storage.getLockPatternFilename(0));
-        assertEquals("/data/system/gatekeeper.password.key", storage.getLockPasswordFilename(0));
-    }
-
-    public void testFileLocation_SecondaryUser() {
-        LockSettingsStorage storage = new LockSettingsStorage(getContext());
-
-        assertEquals("/data/system/users/1/gatekeeper.pattern.key", storage.getLockPatternFilename(1));
-        assertEquals("/data/system/users/1/gatekeeper.password.key", storage.getLockPasswordFilename(1));
-    }
-
-    public void testFileLocation_ProfileToSecondary() {
-        LockSettingsStorage storage = new LockSettingsStorage(getContext());
-
-        assertEquals("/data/system/users/2/gatekeeper.pattern.key", storage.getLockPatternFilename(2));
-        assertEquals("/data/system/users/2/gatekeeper.password.key", storage.getLockPasswordFilename(2));
-    }
-
-    public void testFileLocation_ProfileToOwner() {
-        LockSettingsStorage storage = new LockSettingsStorage(getContext());
-
-        assertEquals("/data/system/users/3/gatekeeper.pattern.key", storage.getLockPatternFilename(3));
-        assertEquals("/data/system/users/3/gatekeeper.password.key", storage.getLockPasswordFilename(3));
-    }
-
-    public void testSyntheticPasswordState() {
-        final byte[] data = {1,2,3,4};
-        mStorage.writeSyntheticPasswordState(10, 1234L, "state", data);
-        assertArrayEquals(data, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
-        assertEquals(null, mStorage.readSyntheticPasswordState(0, 1234L, "state"));
-
-        mStorage.deleteSyntheticPasswordState(10, 1234L, "state");
-        assertEquals(null, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
-    }
-
-    private static void assertArrayEquals(byte[] expected, byte[] actual) {
-        if (!Arrays.equals(expected, actual)) {
-            fail("expected:<" + Arrays.toString(expected) +
-                    "> but was:<" + Arrays.toString(actual) + ">");
-        }
-    }
-
-    private void writePasswordBytes(byte[] password, int userId) {
-        mStorage.writeCredentialHash(CredentialHash.create(
-                password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
-    }
-
-    private void writePatternBytes(byte[] pattern, int userId) {
-        mStorage.writeCredentialHash(CredentialHash.create(
-                pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
-    }
-
-    private void assertPasswordBytes(byte[] password, int userId) {
-        CredentialHash cred = mStorage.readCredentialHash(userId);
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, cred.type);
-        assertArrayEquals(password, cred.hash);
-    }
-
-    private void assertPatternBytes(byte[] pattern, int userId) {
-        CredentialHash cred = mStorage.readCredentialHash(userId);
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN, cred.type);
-        assertArrayEquals(pattern, cred.hash);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/MockGateKeeperService.java b/services/tests/servicestests/src/com/android/server/MockGateKeeperService.java
deleted file mode 100644
index bc93341..0000000
--- a/services/tests/servicestests/src/com/android/server/MockGateKeeperService.java
+++ /dev/null
@@ -1,194 +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;
-
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.service.gatekeeper.GateKeeperResponse;
-import android.service.gatekeeper.IGateKeeperService;
-import android.util.ArrayMap;
-
-import junit.framework.AssertionFailedError;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Random;
-
-public class MockGateKeeperService implements IGateKeeperService {
-    static class VerifyHandle {
-        public byte[] password;
-        public long sid;
-
-        public VerifyHandle(byte[] password, long sid) {
-            this.password = password;
-            this.sid = sid;
-        }
-
-        public VerifyHandle(byte[] handle) {
-            ByteBuffer buffer = ByteBuffer.allocate(handle.length);
-            buffer.put(handle, 0, handle.length);
-            buffer.flip();
-            int version = buffer.get();
-            sid = buffer.getLong();
-            password = new byte[buffer.remaining()];
-            buffer.get(password);
-        }
-
-        public byte[] toBytes() {
-            ByteBuffer buffer = ByteBuffer.allocate(1 + Long.BYTES + password.length);
-            buffer.put((byte)0);
-            buffer.putLong(sid);
-            buffer.put(password);
-            return buffer.array();
-        }
-    }
-
-    static class AuthToken {
-        public long challenge;
-        public long sid;
-
-        public AuthToken(long challenge, long sid) {
-            this.challenge = challenge;
-            this.sid = sid;
-        }
-
-        public AuthToken(byte[] handle) {
-            ByteBuffer buffer = ByteBuffer.allocate(handle.length);
-            buffer.put(handle, 0, handle.length);
-            buffer.flip();
-            int version = buffer.get();
-            challenge = buffer.getLong();
-            sid = buffer.getLong();
-        }
-
-        public byte[] toBytes() {
-            ByteBuffer buffer = ByteBuffer.allocate(1 + Long.BYTES + Long.BYTES);
-            buffer.put((byte)0);
-            buffer.putLong(challenge);
-            buffer.putLong(sid);
-            return buffer.array();
-        }
-    }
-
-    private ArrayMap<Integer, Long> sidMap = new ArrayMap<>();
-    private ArrayMap<Integer, AuthToken> authTokenMap = new ArrayMap<>();
-
-    private ArrayMap<Integer, byte[]> handleMap = new ArrayMap<>();
-
-    @Override
-    public GateKeeperResponse enroll(int uid, byte[] currentPasswordHandle, byte[] currentPassword,
-            byte[] desiredPassword) throws android.os.RemoteException {
-
-        if (currentPasswordHandle != null) {
-            VerifyHandle handle = new VerifyHandle(currentPasswordHandle);
-            if (Arrays.equals(currentPassword, handle.password)) {
-                // Trusted enroll
-                VerifyHandle newHandle = new VerifyHandle(desiredPassword, handle.sid);
-                refreshSid(uid, handle.sid, false);
-                handleMap.put(uid, newHandle.toBytes());
-                return GateKeeperResponse.createOkResponse(newHandle.toBytes(), false);
-            } else {
-                return null;
-            }
-        } else {
-            // Untrusted enroll
-            long newSid = new Random().nextLong();
-            VerifyHandle newHandle = new VerifyHandle(desiredPassword, newSid);
-            refreshSid(uid, newSid, true);
-            handleMap.put(uid, newHandle.toBytes());
-            return GateKeeperResponse.createOkResponse(newHandle.toBytes(), false);
-        }
-    }
-
-    @Override
-    public GateKeeperResponse verify(int uid, byte[] enrolledPasswordHandle,
-            byte[] providedPassword) throws android.os.RemoteException {
-        return verifyChallenge(uid, 0, enrolledPasswordHandle, providedPassword);
-    }
-
-    @Override
-    public GateKeeperResponse verifyChallenge(int uid, long challenge,
-            byte[] enrolledPasswordHandle, byte[] providedPassword) throws RemoteException {
-
-        VerifyHandle handle = new VerifyHandle(enrolledPasswordHandle);
-        if (Arrays.equals(handle.password, providedPassword)) {
-            byte[] knownHandle = handleMap.get(uid);
-            if (knownHandle != null) {
-                if (!Arrays.equals(knownHandle, enrolledPasswordHandle)) {
-                    throw new AssertionFailedError("Got correct but obsolete handle");
-                }
-            }
-            refreshSid(uid, handle.sid, false);
-            AuthToken token = new AuthToken(challenge, handle.sid);
-            refreshAuthToken(uid, token);
-            return GateKeeperResponse.createOkResponse(token.toBytes(), false);
-        } else {
-            return GateKeeperResponse.createGenericResponse(GateKeeperResponse.RESPONSE_ERROR);
-        }
-    }
-
-    private void refreshAuthToken(int uid, AuthToken token) {
-        authTokenMap.put(uid, token);
-    }
-
-    public AuthToken getAuthToken(int uid) {
-        return authTokenMap.get(uid);
-    }
-
-    public AuthToken getAuthTokenForSid(long sid) {
-        for(AuthToken token : authTokenMap.values()) {
-            if (token.sid == sid) {
-                return token;
-            }
-        }
-        return null;
-    }
-
-    public void clearAuthToken(int uid) {
-        authTokenMap.remove(uid);
-    }
-
-    @Override
-    public IBinder asBinder() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void clearSecureUserId(int userId) throws RemoteException {
-        sidMap.remove(userId);
-    }
-
-    @Override
-    public long getSecureUserId(int userId) throws RemoteException {
-        if (sidMap.containsKey(userId)) {
-            return sidMap.get(userId);
-        } else {
-            return 0L;
-        }
-    }
-
-    private void refreshSid(int uid, long sid, boolean force) {
-        if (!sidMap.containsKey(uid) || force) {
-            sidMap.put(uid, sid);
-        } else{
-            if (sidMap.get(uid) != sid) {
-                throw new AssertionFailedError("Inconsistent SID");
-            }
-        }
-    }
-
-}
diff --git a/services/tests/servicestests/src/com/android/server/MockLockSettingsContext.java b/services/tests/servicestests/src/com/android/server/MockLockSettingsContext.java
deleted file mode 100644
index 9dede3b..0000000
--- a/services/tests/servicestests/src/com/android/server/MockLockSettingsContext.java
+++ /dev/null
@@ -1,63 +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;
-
-import android.app.NotificationManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.os.UserManager;
-import android.os.storage.StorageManager;
-
-public class MockLockSettingsContext extends ContextWrapper {
-
-    private UserManager mUserManager;
-    private NotificationManager mNotificationManager;
-    private DevicePolicyManager mDevicePolicyManager;
-    private StorageManager mStorageManager;
-
-    public MockLockSettingsContext(Context base, UserManager userManager,
-            NotificationManager notificationManager, DevicePolicyManager devicePolicyManager,
-            StorageManager storageManager) {
-        super(base);
-        mUserManager = userManager;
-        mNotificationManager = notificationManager;
-        mDevicePolicyManager = devicePolicyManager;
-        mStorageManager = storageManager;
-    }
-
-    @Override
-    public Object getSystemService(String name) {
-        if (USER_SERVICE.equals(name)) {
-            return mUserManager;
-        } else if (NOTIFICATION_SERVICE.equals(name)) {
-            return mNotificationManager;
-        } else if (DEVICE_POLICY_SERVICE.equals(name)) {
-            return mDevicePolicyManager;
-        } else if (STORAGE_SERVICE.equals(name)) {
-            return mStorageManager;
-        } else {
-            throw new RuntimeException("System service not mocked: " + name);
-        }
-    }
-
-    @Override
-    public void enforceCallingOrSelfPermission(String permission, String message) {
-        // Skip permission checks for unit tests.
-    }
-
-}
diff --git a/services/tests/servicestests/src/com/android/server/MockStorageManager.java b/services/tests/servicestests/src/com/android/server/MockStorageManager.java
deleted file mode 100644
index 3a17718..0000000
--- a/services/tests/servicestests/src/com/android/server/MockStorageManager.java
+++ /dev/null
@@ -1,508 +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;
-
-import android.content.pm.IPackageMoveObserver;
-import android.os.IBinder;
-import android.os.IProgressListener;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.os.storage.DiskInfo;
-import android.os.storage.IObbActionListener;
-import android.os.storage.IStorageEventListener;
-import android.os.storage.IStorageManager;
-import android.os.storage.IStorageShutdownObserver;
-import android.os.storage.StorageVolume;
-import android.os.storage.VolumeInfo;
-import android.os.storage.VolumeRecord;
-import android.util.ArrayMap;
-import android.util.Pair;
-
-import com.android.internal.os.AppFuseMount;
-
-import junit.framework.AssertionFailedError;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-public class MockStorageManager implements IStorageManager {
-
-    private ArrayMap<Integer, ArrayList<Pair<byte[], byte[]>>> mAuth = new ArrayMap<>();
-    private boolean mIgnoreBadUnlock;
-
-    @Override
-    public void addUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret)
-            throws RemoteException {
-        getUserAuth(userId).add(new Pair<>(token, secret));
-    }
-
-    @Override
-    public void fixateNewestUserKeyAuth(int userId) throws RemoteException {
-        ArrayList<Pair<byte[], byte[]>> auths = mAuth.get(userId);
-        Pair<byte[], byte[]> latest = auths.get(auths.size() - 1);
-        auths.clear();
-        auths.add(latest);
-    }
-
-    private ArrayList<Pair<byte[], byte[]>> getUserAuth(int userId) {
-        if (!mAuth.containsKey(userId)) {
-            ArrayList<Pair<byte[], byte[]>> auths = new ArrayList<Pair<byte[], byte[]>>();
-            auths.add(new Pair(null, null));
-            mAuth.put(userId,  auths);
-        }
-        return mAuth.get(userId);
-    }
-
-    public byte[] getUserUnlockToken(int userId) {
-        ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId);
-        if (auths.size() != 1) {
-            throw new AssertionFailedError("More than one secret exists");
-        }
-        return auths.get(0).second;
-    }
-
-    public void unlockUser(int userId, byte[] secret, IProgressListener listener)
-            throws RemoteException {
-        listener.onStarted(userId, null);
-        listener.onFinished(userId, null);
-        ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId);
-        if (secret != null) {
-            if (auths.size() > 1) {
-                throw new AssertionFailedError("More than one secret exists");
-            }
-            Pair<byte[], byte[]> auth = auths.get(0);
-            if ((!mIgnoreBadUnlock) && auth.second != null && !Arrays.equals(secret, auth.second)) {
-                throw new AssertionFailedError("Invalid secret to unlock user");
-            }
-        } else {
-            if (auths != null && auths.size() > 0) {
-                throw new AssertionFailedError("Cannot unlock encrypted user with empty token");
-            }
-        }
-    }
-
-    public void setIgnoreBadUnlock(boolean ignore) {
-        mIgnoreBadUnlock = ignore;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void registerListener(IStorageEventListener listener) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unregisterListener(IStorageEventListener listener) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isUsbMassStorageConnected() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setUsbMassStorageEnabled(boolean enable) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isUsbMassStorageEnabled() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int mountVolume(String mountPoint) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unmountVolume(String mountPoint, boolean force, boolean removeEncryption)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-
-    }
-
-    @Override
-    public int formatVolume(String mountPoint) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int[] getStorageUsers(String path) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getVolumeState(String mountPoint) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int createSecureContainer(String id, int sizeMb, String fstype, String key, int ownerUid,
-            boolean external) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int finalizeSecureContainer(String id) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int destroySecureContainer(String id, boolean force) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int mountSecureContainer(String id, String key, int ownerUid, boolean readOnly)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int unmountSecureContainer(String id, boolean force) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isSecureContainerMounted(String id) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int renameSecureContainer(String oldId, String newId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getSecureContainerPath(String id) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String[] getSecureContainerList() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void shutdown(IStorageShutdownObserver observer) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void finishMediaUpdate() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void mountObb(String rawPath, String canonicalPath, String key, IObbActionListener token,
-            int nonce) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unmountObb(String rawPath, boolean force, IObbActionListener token, int nonce)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isObbMounted(String rawPath) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getMountedObbPath(String rawPath) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isExternalStorageEmulated() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int decryptStorage(String password) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int encryptStorage(int type, String password) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int changeEncryptionPassword(int type, String password) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public StorageVolume[] getVolumeList(int uid, String packageName, int flags)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getSecureContainerFilesystemPath(String cid) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getEncryptionState() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int verifyEncryptionPassword(String password) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int fixPermissionsSecureContainer(String id, int gid, String filename)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int mkdirs(String callingPkg, String path) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getPasswordType() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getPassword() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void clearPassword() throws RemoteException {
-        throw new UnsupportedOperationException();
-
-    }
-
-    @Override
-    public void setField(String field, String contents) throws RemoteException {
-        throw new UnsupportedOperationException();
-
-    }
-
-    @Override
-    public String getField(String field) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int resizeSecureContainer(String id, int sizeMb, String key) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long lastMaintenance() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void runMaintenance() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void waitForAsecScan() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public DiskInfo[] getDisks() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public VolumeInfo[] getVolumes(int flags) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public VolumeRecord[] getVolumeRecords(int flags) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void mount(String volId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unmount(String volId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void format(String volId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void partitionPublic(String diskId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void partitionPrivate(String diskId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void partitionMixed(String diskId, int ratio) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void forgetVolume(String fsUuid) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void forgetAllVolumes() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getPrimaryStorageUuid() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long benchmark(String volId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setDebugFlags(int flags, int mask) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void createUserKey(int userId, int serialNumber, boolean ephemeral)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void destroyUserKey(int userId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void lockUserKey(int userId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isUserKeyUnlocked(int userId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void prepareUserStorage(String volumeUuid, int userId, int serialNumber, int flags)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void destroyUserStorage(String volumeUuid, int userId, int flags)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isConvertibleToFBE() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void fstrim(int flags) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public AppFuseMount mountProxyFileDescriptorBridge() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ParcelFileDescriptor openProxyFileDescriptor(int mountPointId, int fileId, int mode)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long getCacheQuotaBytes(String volumeUuid, int uid) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long getCacheSizeBytes(String volumeUuid, int uid) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long getAllocatableBytes(String path, int flags) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void allocateBytes(String path, long bytes, int flags) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void secdiscard(String path) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-}
diff --git a/services/tests/servicestests/src/com/android/server/MockSyntheticPasswordManager.java b/services/tests/servicestests/src/com/android/server/MockSyntheticPasswordManager.java
deleted file mode 100644
index 93e3fc6..0000000
--- a/services/tests/servicestests/src/com/android/server/MockSyntheticPasswordManager.java
+++ /dev/null
@@ -1,102 +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;
-
-import android.util.ArrayMap;
-
-import junit.framework.AssertionFailedError;
-
-import java.nio.ByteBuffer;
-import java.security.NoSuchAlgorithmException;
-import java.security.spec.InvalidKeySpecException;
-import java.util.Arrays;
-
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.PBEKeySpec;
-
-public class MockSyntheticPasswordManager extends SyntheticPasswordManager {
-
-    private MockGateKeeperService mGateKeeper;
-
-    public MockSyntheticPasswordManager(LockSettingsStorage storage,
-            MockGateKeeperService gatekeeper) {
-        super(storage);
-        mGateKeeper = gatekeeper;
-    }
-
-    private ArrayMap<String, byte[]> mBlobs = new ArrayMap<>();
-
-    @Override
-    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
-        if (mBlobs.containsKey(blobKeyName) && !Arrays.equals(mBlobs.get(blobKeyName), blob)) {
-            throw new AssertionFailedError("blobKeyName content is overwritten: " + blobKeyName);
-        }
-        ByteBuffer buffer = ByteBuffer.allocate(blob.length);
-        buffer.put(blob, 0, blob.length);
-        buffer.flip();
-        int len;
-        len = buffer.getInt();
-        byte[] data = new byte[len];
-        buffer.get(data);
-        len = buffer.getInt();
-        byte[] appId = new byte[len];
-        buffer.get(appId);
-        long sid = buffer.getLong();
-        if (!Arrays.equals(appId, applicationId)) {
-            throw new AssertionFailedError("Invalid application id");
-        }
-        if (sid != 0 && mGateKeeper.getAuthTokenForSid(sid) == null) {
-            throw new AssertionFailedError("No valid auth token");
-        }
-        return data;
-    }
-
-    @Override
-    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
-        ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + data.length + Integer.BYTES
-                + applicationId.length + Long.BYTES);
-        buffer.putInt(data.length);
-        buffer.put(data);
-        buffer.putInt(applicationId.length);
-        buffer.put(applicationId);
-        buffer.putLong(sid);
-        byte[] result = buffer.array();
-        mBlobs.put(blobKeyName, result);
-        return result;
-    }
-
-    @Override
-    protected void destroySPBlobKey(String keyAlias) {
-    }
-
-    @Override
-    protected long sidFromPasswordHandle(byte[] handle) {
-        return new MockGateKeeperService.VerifyHandle(handle).sid;
-    }
-
-    @Override
-    protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) {
-        try {
-            PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10, outLen * 8);
-            SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
-            return f.generateSecret(spec).getEncoded();
-        } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-}
diff --git a/services/tests/servicestests/src/com/android/server/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/SyntheticPasswordTests.java
deleted file mode 100644
index 3ec71e4..0000000
--- a/services/tests/servicestests/src/com/android/server/SyntheticPasswordTests.java
+++ /dev/null
@@ -1,349 +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;
-
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
-
-import android.os.RemoteException;
-import android.os.UserHandle;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.VerifyCredentialResponse;
-import com.android.server.SyntheticPasswordManager.AuthenticationResult;
-import com.android.server.SyntheticPasswordManager.AuthenticationToken;
-
-
-/**
- * runtest frameworks-services -c com.android.server.SyntheticPasswordTests
- */
-public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    public void testPasswordBasedSyntheticPassword() throws RemoteException {
-        final int USER_ID = 10;
-        final String PASSWORD = "user-password";
-        final String BADPASSWORD = "bad-password";
-        MockSyntheticPasswordManager manager = new MockSyntheticPasswordManager(mStorage, mGateKeeperService);
-        AuthenticationToken authToken = manager.newSyntheticPasswordAndSid(mGateKeeperService, null,
-                null, USER_ID);
-        long handle = manager.createPasswordBasedSyntheticPassword(mGateKeeperService, PASSWORD,
-                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, authToken, USER_ID);
-
-        AuthenticationResult result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle, PASSWORD, USER_ID);
-        assertEquals(result.authToken.deriveKeyStorePassword(), authToken.deriveKeyStorePassword());
-
-        result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle, BADPASSWORD, USER_ID);
-        assertNull(result.authToken);
-    }
-
-    private void disableSyntheticPassword(int userId) throws RemoteException {
-        mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
-    }
-
-    private void enableSyntheticPassword(int userId) throws RemoteException {
-        mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
-    }
-
-    private boolean hasSyntheticPassword(int userId) throws RemoteException {
-        return mService.getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId) != 0;
-    }
-
-    public void testPasswordMigration() throws RemoteException {
-        final String PASSWORD = "testPasswordMigration-password";
-
-        disableSyntheticPassword(PRIMARY_USER_ID);
-        mService.setLockCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-        enableSyntheticPassword(PRIMARY_USER_ID);
-        // Performs migration
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-
-        // SP-based verification
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-    }
-
-    private void initializeCredentialUnderSP(String password, int userId) throws RemoteException {
-        enableSyntheticPassword(userId);
-        mService.setLockCredential(password, password != null ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD : LockPatternUtils.CREDENTIAL_TYPE_NONE, null, userId);
-    }
-
-    public void testSyntheticPasswordChangeCredential() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordChangeCredential-password";
-        final String NEWPASSWORD = "testSyntheticPasswordChangeCredential-newpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, PASSWORD, PRIMARY_USER_ID);
-        mGateKeeperService.clearSecureUserId(PRIMARY_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-    }
-
-    public void testSyntheticPasswordVerifyCredential() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordVerifyCredential-password";
-        final String BADPASSWORD = "testSyntheticPasswordVerifyCredential-badpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-
-        assertEquals(VerifyCredentialResponse.RESPONSE_ERROR,
-                mService.verifyCredential(BADPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-    }
-
-    public void testSyntheticPasswordClearCredential() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
-        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        // clear password
-        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, PASSWORD, PRIMARY_USER_ID);
-        assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-
-        // set a new password
-        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertNotSame(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-    }
-
-    public void testSyntheticPasswordClearCredentialUntrusted() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
-        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        // clear password
-        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-
-        // set a new password
-        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertNotSame(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-    }
-
-    public void testSyntheticPasswordChangeCredentialUntrusted() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
-        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        // Untrusted change password
-        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        assertNotSame(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertNotSame(sid ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-
-        // Verify the password
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-    }
-
-
-    public void testManagedProfileUnifiedChallengeMigration() throws RemoteException {
-        final String UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd";
-        disableSyntheticPassword(PRIMARY_USER_ID);
-        disableSyntheticPassword(MANAGED_PROFILE_USER_ID);
-        mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
-        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
-        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-        final byte[] profileStorageKey = mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID);
-        assertTrue(primarySid != 0);
-        assertTrue(profileSid != 0);
-        assertTrue(profileSid != primarySid);
-
-        // do migration
-        enableSyntheticPassword(PRIMARY_USER_ID);
-        enableSyntheticPassword(MANAGED_PROFILE_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-
-        // verify
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(primarySid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-        assertArrayNotSame(profileStorageKey, mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(MANAGED_PROFILE_USER_ID));
-    }
-
-    public void testManagedProfileSeparateChallengeMigration() throws RemoteException {
-        final String primaryPassword = "testManagedProfileSeparateChallengeMigration-primary";
-        final String profilePassword = "testManagedProfileSeparateChallengeMigration-profile";
-        mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, MANAGED_PROFILE_USER_ID);
-        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
-        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-        final byte[] profileStorageKey = mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID);
-        assertTrue(primarySid != 0);
-        assertTrue(profileSid != 0);
-        assertTrue(profileSid != primarySid);
-
-        // do migration
-        enableSyntheticPassword(PRIMARY_USER_ID);
-        enableSyntheticPassword(MANAGED_PROFILE_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, MANAGED_PROFILE_USER_ID).getResponseCode());
-
-        // verify
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, MANAGED_PROFILE_USER_ID).getResponseCode());
-        assertEquals(primarySid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-        assertArrayNotSame(profileStorageKey, mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(MANAGED_PROFILE_USER_ID));
-    }
-
-    public void testTokenBasedResetPassword() throws RemoteException {
-        final String PASSWORD = "password";
-        final String PATTERN = "123654";
-        final String TOKEN = "some-high-entropy-secure-token";
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
-
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID).getResponseCode());
-        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-    }
-
-    public void testTokenBasedClearPassword() throws RemoteException {
-        final String PASSWORD = "password";
-        final String PATTERN = "123654";
-        final String TOKEN = "some-high-entropy-secure-token";
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.setLockCredentialWithToken(null, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
-        mService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
-
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID).getResponseCode());
-        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-    }
-
-    public void testTokenBasedResetPasswordAfterCredentialChanges() throws RemoteException {
-        final String PASSWORD = "password";
-        final String PATTERN = "123654";
-        final String NEWPASSWORD = "password";
-        final String TOKEN = "some-high-entropy-secure-token";
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.setLockCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, PASSWORD, PRIMARY_USER_ID);
-
-        mService.setLockCredentialWithToken(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
-
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-    }
-
-    public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNeedsMigration() throws RemoteException {
-        final String TOKEN = "some-high-entropy-secure-token";
-        enableSyntheticPassword(PRIMARY_USER_ID);
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-    }
-
-    public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNoMigration() throws RemoteException {
-        final String TOKEN = "some-high-entropy-secure-token";
-        initializeCredentialUnderSP(null, PRIMARY_USER_ID);
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-    }
-
-    public void testEscrowTokenActivatedLaterWithUserPasswordNeedsMigration() throws RemoteException {
-        final String TOKEN = "some-high-entropy-secure-token";
-        final String PASSWORD = "password";
-        // Set up pre-SP user password
-        disableSyntheticPassword(PRIMARY_USER_ID);
-        mService.setLockCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PRIMARY_USER_ID);
-        enableSyntheticPassword(PRIMARY_USER_ID);
-
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        // Token not activated immediately since user password exists
-        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-        // Activate token (password gets migrated to SP at the same time)
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
-                        PRIMARY_USER_ID).getResponseCode());
-        // Verify token is activated
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-    }
-
-    // b/34600579
-    //TODO: add non-migration work profile case, and unify/un-unify transition.
-    //TODO: test token after user resets password
-    //TODO: test token based reset after unified work challenge
-    //TODO: test clear password after unified work challenge
-}
-
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 f75d49c..2252c85 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
@@ -16,10 +16,15 @@
 
 package com.android.server.am;
 
+import static android.view.WindowManagerPolicy.NAV_BAR_BOTTOM;
+import static android.view.WindowManagerPolicy.NAV_BAR_LEFT;
+import static android.view.WindowManagerPolicy.NAV_BAR_RIGHT;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.when;
 
 import android.content.ComponentName;
+import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -94,4 +99,36 @@
 
         return -1;
     }
+
+    @Test
+    public void testPositionLimitedAspectRatioNavBarBottom() throws Exception {
+        verifyPositionWithLimitedAspectRatio(NAV_BAR_BOTTOM, new Rect(0, 0, 1000, 2000), 1.5f,
+                new Rect(0, 0, 1000, 1500));
+    }
+
+    @Test
+    public void testPositionLimitedAspectRatioNavBarLeft() throws Exception {
+        verifyPositionWithLimitedAspectRatio(NAV_BAR_LEFT, new Rect(0, 0, 2000, 1000), 1.5f,
+                new Rect(500, 0, 2000, 1000));
+    }
+
+    @Test
+    public void testPositionLimitedAspectRatioNavBarRight() throws Exception {
+        verifyPositionWithLimitedAspectRatio(NAV_BAR_RIGHT, new Rect(0, 0, 2000, 1000), 1.5f,
+                new Rect(0, 0, 1500, 1000));
+    }
+
+    private void verifyPositionWithLimitedAspectRatio(int navBarPosition, Rect taskBounds,
+            float aspectRatio, Rect expectedActivityBounds) {
+        final ActivityManagerService service = createActivityManagerService();
+        final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
+        final ActivityRecord record = createActivity(service, testActivityComponent, task);
+
+        // Verify with nav bar on the right.
+        when(service.mWindowManager.getNavBarPosition()).thenReturn(navBarPosition);
+        task.getConfiguration().setAppBounds(taskBounds);
+        record.info.maxAspectRatio = aspectRatio;
+        record.ensureActivityConfigurationLocked(0 /* globalChanges */, false /* preserveWindow */);
+        assertEquals(expectedActivityBounds, record.getBounds());
+    }
 }
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 bac1216..16bc011 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -120,6 +120,7 @@
                 null /*_taskDescription*/, new ActivityManager.TaskThumbnailInfo());
         final ActivityStack stack = service.mStackSupervisor.getStack(stackId,
                 true /*createStaticStackIfNeeded*/, true /*onTop*/);
+        service.mStackSupervisor.setFocusStackUnchecked("test", stack);
         stack.addTask(task, true, "creating test task");
         task.setStack(stack);
         task.setWindowContainerController(mock(TaskWindowContainerController.class));
diff --git a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
index 2f202d98..da30c11 100644
--- a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
@@ -34,6 +34,7 @@
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.AppOpsService;
 
+import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
@@ -59,7 +60,6 @@
  * Run: adb shell am instrument -e class com.android.server.am.CoreSettingsObserverTest -w \
  *     com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
  */
-@Ignore
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class CoreSettingsObserverTest {
@@ -79,11 +79,17 @@
 
     @BeforeClass
     public static void setupOnce() {
+        FakeSettingsProvider.clearSettingsProvider();
         CoreSettingsObserver.sSecureSettingToTypeMap.put(TEST_SETTING_SECURE_INT, int.class);
         CoreSettingsObserver.sGlobalSettingToTypeMap.put(TEST_SETTING_GLOBAL_FLOAT, float.class);
         CoreSettingsObserver.sSystemSettingToTypeMap.put(TEST_SETTING_SYSTEM_STRING, String.class);
     }
 
+    @AfterClass
+    public static void tearDownOnce() {
+        FakeSettingsProvider.clearSettingsProvider();
+    }
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
diff --git a/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java b/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
index f287386..54f93a8 100644
--- a/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
@@ -32,6 +32,7 @@
 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;
@@ -40,6 +41,7 @@
 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;
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java b/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
index 984a484..ea207f1 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
@@ -58,7 +58,7 @@
     }
 
     public void testTaskIdsPersistence() {
-        SparseBooleanArray taskIdsOnFile = mTaskPersister.loadPersistedTaskIdsForUser(testUserId);
+        SparseBooleanArray taskIdsOnFile = new SparseBooleanArray();
         for (int i = 0; i < 100; i++) {
             taskIdsOnFile.put(getRandomTaskIdForUser(testUserId), true);
         }
diff --git a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
new file mode 100644
index 0000000..27ef9d7
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
@@ -0,0 +1,915 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.app.backup.BackupManager;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
+import android.app.backup.IFullBackupRestoreObserver;
+import android.app.backup.ISelectBackupTransportCallback;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class TrampolineTest {
+    private static final String PACKAGE_NAME = "some.package.name";
+    private static final String TRANSPORT_NAME = "some.transport.name";
+    private static final String CURRENT_PASSWORD = "current_password";
+    private static final String NEW_PASSWORD = "new_password";
+    private static final String ENCRYPTION_PASSWORD = "encryption_password";
+    private static final String DATA_MANAGEMENT_LABEL = "data_management_label";
+    private static final String DESTINATION_STRING = "destination_string";
+    private static final String[] PACKAGE_NAMES =
+            new String[]{"some.package.name._1", "some.package.name._2"};
+    private static final String[] TRANSPORTS =
+            new String[]{"some.transport.name._1", "some.transport.name._2"};
+    private static final ComponentName TRANSPORT_COMPONENT_NAME = new ComponentName("package",
+            "class");
+    private static final ComponentName[] TRANSPORT_COMPONENTS = new ComponentName[]{
+            new ComponentName("package1", "class1"),
+            new ComponentName("package2", "class2")
+    };
+    private final int NON_USER_SYSTEM = UserHandle.USER_SYSTEM + 1;
+
+    @Mock private BackupManagerService mBackupManagerServiceMock;
+    @Mock private RefactoredBackupManagerService mRefactoredBackupManagerServiceMock;
+    @Mock private Context mContextMock;
+    @Mock private File mSuppressFileMock;
+    @Mock private File mSuppressFileParentMock;
+    @Mock private IBinder mAgentMock;
+    @Mock private ParcelFileDescriptor mParcelFileDescriptorMock;
+    @Mock private IFullBackupRestoreObserver mFullBackupRestoreObserverMock;
+    @Mock private IBackupObserver mBackupObserverMock;
+    @Mock private IBackupManagerMonitor mBackupManagerMonitorMock;
+    @Mock private PrintWriter mPrintWriterMock;
+
+    private FileDescriptor mFileDescriptorStub = new FileDescriptor();
+
+    private TrampolineTestable mTrampoline;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        TrampolineTestable.sRefactoredBackupManagerServiceMock =
+                mRefactoredBackupManagerServiceMock;
+        TrampolineTestable.sBackupManagerServiceMock = mBackupManagerServiceMock;
+        TrampolineTestable.sSuppressFile = mSuppressFileMock;
+        TrampolineTestable.sCallingUid = Process.SYSTEM_UID;
+        TrampolineTestable.sRefactoredServiceEnabled = false;
+        TrampolineTestable.sBackupDisabled = false;
+
+        when(mSuppressFileMock.getParentFile()).thenReturn(mSuppressFileParentMock);
+
+        mTrampoline = new TrampolineTestable(mContextMock);
+    }
+
+    @Test
+    public void constructor_createsSuppressFileDirectory() {
+        verify(mSuppressFileParentMock).mkdirs();
+    }
+
+    @Test
+    public void initialize_forUserSystem_successfullyInitialized() {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    // The BackupManagerService can only be initialized by USER_SYSTEM, so we check that if any
+    // other user trying to initialize it leaves it non-active.
+    @Test
+    public void initialize_forNonUserSystem_nonInitialized() {
+        mTrampoline.initialize(NON_USER_SYSTEM);
+
+        assertFalse(mTrampoline.isBackupServiceActive(NON_USER_SYSTEM));
+    }
+
+    @Test
+    public void initialize_globallyDisabled_nonInitialized() {
+        TrampolineTestable.sBackupDisabled = true;
+
+        TrampolineTestable trampoline = new TrampolineTestable(mContextMock);
+        trampoline.initialize(UserHandle.USER_SYSTEM);
+
+        assertFalse(trampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    // Verify that BackupManagerService is not initialized if suppress file exists.
+    @Test
+    public void initialize_suppressFileExists_nonInitialized() {
+        when(mSuppressFileMock.exists()).thenReturn(true);
+
+        TrampolineTestable trampoline = new TrampolineTestable(mContextMock);
+        trampoline.initialize(UserHandle.USER_SYSTEM);
+
+        assertFalse(trampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    @Test
+    public void isBackupServiceActive_calledBeforeInitialize_returnsFalse() {
+        assertFalse(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    @Test
+    public void createService_refactoredServiceEnabled() {
+        TrampolineTestable.sRefactoredServiceEnabled = true;
+
+        assertEquals(mRefactoredBackupManagerServiceMock, mTrampoline.createService());
+    }
+
+    @Test
+    public void createService_refactoredServiceDisabled() {
+        TrampolineTestable.sRefactoredServiceEnabled = false;
+
+        assertEquals(mBackupManagerServiceMock, mTrampoline.createService());
+    }
+
+    @Test
+    public void setBackupServiceActive_callerSystemUid_serviceCreated() {
+        TrampolineTestable.sCallingUid = Process.SYSTEM_UID;
+
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    @Test
+    public void setBackupServiceActive_callerRootUid_serviceCreated() {
+        TrampolineTestable.sCallingUid = Process.ROOT_UID;
+
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    @Test
+    public void setBackupServiceActive_callerNonRootNonSystem_securityExceptionThrown() {
+        TrampolineTestable.sCallingUid = Process.FIRST_APPLICATION_UID;
+
+        try {
+            mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+            fail();
+        } catch (SecurityException expected) {
+        }
+
+        assertFalse(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    @Test
+    public void setBackupServiceActive_backupDisabled_ignored() {
+        TrampolineTestable.sBackupDisabled = true;
+        TrampolineTestable trampoline = new TrampolineTestable(mContextMock);
+
+        trampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+
+        assertFalse(trampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    @Test
+    public void setBackupServiceActive_nonUserSystem_ignored() {
+        mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true);
+
+        assertFalse(mTrampoline.isBackupServiceActive(NON_USER_SYSTEM));
+    }
+
+    @Test
+    public void setBackupServiceActive_alreadyActive_ignored() {
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+        assertEquals(1, mTrampoline.getCreateServiceCallsCount());
+
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+        assertEquals(1, mTrampoline.getCreateServiceCallsCount());
+    }
+
+    @Test
+    public void setBackupServiceActive_makeActive_serviceCreatedAndSuppressFileDeleted() {
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+        verify(mSuppressFileMock).delete();
+    }
+
+    @Test
+    public void setBackupServiceActive_makeNonActive_serviceDeletedAndSuppressFileCreated()
+            throws IOException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false);
+
+        assertFalse(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+        verify(mSuppressFileMock).createNewFile();
+    }
+
+    @Test
+    public void
+    setBackupServiceActive_makeNonActive_serviceDeletedAndSuppressFileCreated_ioExceptionHandled()
+            throws IOException {
+        when(mSuppressFileMock.createNewFile()).thenThrow(new IOException());
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false);
+
+        assertFalse(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+        verify(mSuppressFileMock).createNewFile();
+    }
+
+    @Test
+    public void setBackupServiceActive_makeNonActive_alreadyNonActive_ignored() throws IOException {
+        reset(mSuppressFileMock);
+
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false);
+
+        verifyNoMoreInteractions(mSuppressFileMock);
+    }
+
+    @Test
+    public void dataChanged_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.dataChanged(PACKAGE_NAME);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void dataChanged_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.dataChanged(PACKAGE_NAME);
+        verify(mBackupManagerServiceMock).dataChanged(PACKAGE_NAME);
+    }
+
+    @Test
+    public void clearBackupData_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.clearBackupData(TRANSPORT_NAME, PACKAGE_NAME);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void clearBackupData_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.clearBackupData(TRANSPORT_NAME, PACKAGE_NAME);
+        verify(mBackupManagerServiceMock).clearBackupData(TRANSPORT_NAME, PACKAGE_NAME);
+    }
+
+    @Test
+    public void agentConnected_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.agentConnected(PACKAGE_NAME, mAgentMock);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void agentConnected_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.agentConnected(PACKAGE_NAME, mAgentMock);
+        verify(mBackupManagerServiceMock).agentConnected(PACKAGE_NAME, mAgentMock);
+    }
+
+    @Test
+    public void agentDisconnected_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.agentDisconnected(PACKAGE_NAME);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void agentDisconnected_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.agentDisconnected(PACKAGE_NAME);
+        verify(mBackupManagerServiceMock).agentDisconnected(PACKAGE_NAME);
+    }
+
+    @Test
+    public void restoreAtInstall_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.restoreAtInstall(PACKAGE_NAME, 123);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void restoreAtInstall_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.restoreAtInstall(PACKAGE_NAME, 123);
+        verify(mBackupManagerServiceMock).restoreAtInstall(PACKAGE_NAME, 123);
+    }
+
+    @Test
+    public void setBackupEnabled_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.setBackupEnabled(true);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void setBackupEnabled_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.setBackupEnabled(true);
+        verify(mBackupManagerServiceMock).setBackupEnabled(true);
+    }
+
+    @Test
+    public void setAutoRestore_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.setAutoRestore(true);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void setAutoRestore_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.setAutoRestore(true);
+        verify(mBackupManagerServiceMock).setAutoRestore(true);
+    }
+
+    @Test
+    public void setBackupProvisioned_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.setBackupProvisioned(true);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void setBackupProvisioned_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.setBackupProvisioned(true);
+        verify(mBackupManagerServiceMock).setBackupProvisioned(true);
+    }
+
+    @Test
+    public void isBackupEnabled_calledBeforeInitialize_ignored() throws RemoteException {
+        assertFalse(mTrampoline.isBackupEnabled());
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void isBackupEnabled_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.isBackupEnabled();
+        verify(mBackupManagerServiceMock).isBackupEnabled();
+    }
+
+    @Test
+    public void setBackupPassword_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.setBackupPassword(CURRENT_PASSWORD, NEW_PASSWORD);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void setBackupPassword_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.setBackupPassword(CURRENT_PASSWORD, NEW_PASSWORD);
+        verify(mBackupManagerServiceMock).setBackupPassword(CURRENT_PASSWORD, NEW_PASSWORD);
+    }
+
+    @Test
+    public void hasBackupPassword_calledBeforeInitialize_ignored() throws RemoteException {
+        assertFalse(mTrampoline.hasBackupPassword());
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void hasBackupPassword_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.hasBackupPassword();
+        verify(mBackupManagerServiceMock).hasBackupPassword();
+    }
+
+    @Test
+    public void backupNow_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.backupNow();
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void backupNow_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.backupNow();
+        verify(mBackupManagerServiceMock).backupNow();
+    }
+
+    @Test
+    public void adbBackup_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.adbBackup(mParcelFileDescriptorMock, true, true, true, true, true, true, true,
+                true,
+                PACKAGE_NAMES);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void adbBackup_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.adbBackup(mParcelFileDescriptorMock, true, true, true, true, true, true, true,
+                true,
+                PACKAGE_NAMES);
+        verify(mBackupManagerServiceMock).adbBackup(mParcelFileDescriptorMock, true, true, true,
+                true,
+                true, true, true, true, PACKAGE_NAMES);
+    }
+
+    @Test
+    public void fullTransportBackup_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.fullTransportBackup(PACKAGE_NAMES);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void fullTransportBackup_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.fullTransportBackup(PACKAGE_NAMES);
+        verify(mBackupManagerServiceMock).fullTransportBackup(PACKAGE_NAMES);
+    }
+
+    @Test
+    public void adbRestore_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.adbRestore(mParcelFileDescriptorMock);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void adbRestore_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.adbRestore(mParcelFileDescriptorMock);
+        verify(mBackupManagerServiceMock).adbRestore(mParcelFileDescriptorMock);
+    }
+
+    @Test
+    public void acknowledgeFullBackupOrRestore_calledBeforeInitialize_ignored()
+            throws RemoteException {
+        mTrampoline.acknowledgeFullBackupOrRestore(123, true, CURRENT_PASSWORD, ENCRYPTION_PASSWORD,
+                mFullBackupRestoreObserverMock);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void acknowledgeFullBackupOrRestore_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.acknowledgeFullBackupOrRestore(123, true, CURRENT_PASSWORD, ENCRYPTION_PASSWORD,
+                mFullBackupRestoreObserverMock);
+        verify(mBackupManagerServiceMock).acknowledgeAdbBackupOrRestore(123, true, CURRENT_PASSWORD,
+                ENCRYPTION_PASSWORD, mFullBackupRestoreObserverMock);
+    }
+
+    @Test
+    public void getCurrentTransport_calledBeforeInitialize_ignored() throws RemoteException {
+        assertNull(mTrampoline.getCurrentTransport());
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void getCurrentTransport_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.getCurrentTransport()).thenReturn(TRANSPORT_NAME);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+
+        assertEquals(TRANSPORT_NAME, mTrampoline.getCurrentTransport());
+        verify(mBackupManagerServiceMock).getCurrentTransport();
+    }
+
+    @Test
+    public void listAllTransports_calledBeforeInitialize_ignored() throws RemoteException {
+        assertNull(mTrampoline.listAllTransports());
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void listAllTransports_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.listAllTransports()).thenReturn(TRANSPORTS);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(TRANSPORTS, mTrampoline.listAllTransports());
+        verify(mBackupManagerServiceMock).listAllTransports();
+    }
+
+    @Test
+    public void listAllTransportComponents_calledBeforeInitialize_ignored() throws RemoteException {
+        assertNull(mTrampoline.listAllTransportComponents());
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void listAllTransportComponents_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.listAllTransportComponents()).thenReturn(
+                TRANSPORT_COMPONENTS);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(TRANSPORT_COMPONENTS, mTrampoline.listAllTransportComponents());
+        verify(mBackupManagerServiceMock).listAllTransportComponents();
+    }
+
+    @Test
+    public void getTransportWhitelist_calledBeforeInitialize_ignored() throws RemoteException {
+        assertNull(mTrampoline.getTransportWhitelist());
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void getTransportWhitelist_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.getTransportWhitelist()).thenReturn(TRANSPORTS);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(TRANSPORTS, mTrampoline.getTransportWhitelist());
+        verify(mBackupManagerServiceMock).getTransportWhitelist();
+    }
+
+    @Test
+    public void selectBackupTransport_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.selectBackupTransport(TRANSPORT_NAME);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void selectBackupTransport_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.selectBackupTransport(TRANSPORT_NAME);
+        verify(mBackupManagerServiceMock).selectBackupTransport(TRANSPORT_NAME);
+    }
+
+    @Test
+    public void selectBackupTransportAsync_calledBeforeInitialize_ignored() throws Exception {
+        LinkedBlockingQueue<Integer> q = new LinkedBlockingQueue();
+        mTrampoline.selectBackupTransportAsync(
+                TRANSPORT_COMPONENT_NAME,
+                new ISelectBackupTransportCallback() {
+                    @Override
+                    public void onSuccess(String transportName) throws RemoteException {
+
+                    }
+
+                    @Override
+                    public void onFailure(int reason) throws RemoteException {
+                        q.offer(reason);
+                    }
+
+                    @Override
+                    public IBinder asBinder() {
+                        return null;
+                    }
+                });
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+        Integer errorCode = q.poll(5, TimeUnit.SECONDS);
+        assertNotNull(errorCode);
+        assertEquals(BackupManager.ERROR_BACKUP_NOT_ALLOWED, (int) errorCode);
+    }
+
+    @Test
+    public void selectBackupTransportAsync_calledBeforeInitialize_ignored_nullListener()
+            throws Exception {
+        mTrampoline.selectBackupTransportAsync(TRANSPORT_COMPONENT_NAME, null);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+        // No crash.
+    }
+
+    @Test
+    public void selectBackupTransportAsync_calledBeforeInitialize_ignored_listenerThrowException()
+            throws Exception {
+        mTrampoline.selectBackupTransportAsync(
+                TRANSPORT_COMPONENT_NAME,
+                new ISelectBackupTransportCallback() {
+                    @Override
+                    public void onSuccess(String transportName) throws RemoteException {
+
+                    }
+
+                    @Override
+                    public void onFailure(int reason) throws RemoteException {
+                        throw new RemoteException("Crash");
+                    }
+
+                    @Override
+                    public IBinder asBinder() {
+                        return null;
+                    }
+                });
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+        // No crash.
+    }
+
+    @Test
+    public void selectBackupTransportAsync_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.selectBackupTransportAsync(TRANSPORT_COMPONENT_NAME, null);
+        verify(mBackupManagerServiceMock).selectBackupTransportAsync(TRANSPORT_COMPONENT_NAME,
+                null);
+    }
+
+    @Test
+    public void getConfigurationIntent_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.getConfigurationIntent(TRANSPORT_NAME);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void getConfigurationIntent_forwarded() throws RemoteException {
+        Intent configurationIntentStub = new Intent();
+        when(mBackupManagerServiceMock.getConfigurationIntent(TRANSPORT_NAME)).thenReturn(
+                configurationIntentStub);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(configurationIntentStub, mTrampoline.getConfigurationIntent(TRANSPORT_NAME));
+        verify(mBackupManagerServiceMock).getConfigurationIntent(TRANSPORT_NAME);
+    }
+
+    @Test
+    public void getDestinationString_calledBeforeInitialize_ignored() throws RemoteException {
+        assertNull(mTrampoline.getDestinationString(TRANSPORT_NAME));
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void getDestinationString_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.getDestinationString(TRANSPORT_NAME)).thenReturn(
+                DESTINATION_STRING);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(DESTINATION_STRING, mTrampoline.getDestinationString(TRANSPORT_NAME));
+        verify(mBackupManagerServiceMock).getDestinationString(TRANSPORT_NAME);
+    }
+
+    @Test
+    public void getDataManagementIntent_calledBeforeInitialize_ignored() throws RemoteException {
+        assertNull(mTrampoline.getDataManagementIntent(TRANSPORT_NAME));
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void getDataManagementIntent_forwarded() throws RemoteException {
+        Intent dataManagementIntent = new Intent();
+        when(mBackupManagerServiceMock.getDataManagementIntent(TRANSPORT_NAME)).thenReturn(
+                dataManagementIntent);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(dataManagementIntent, mTrampoline.getDataManagementIntent(TRANSPORT_NAME));
+        verify(mBackupManagerServiceMock).getDataManagementIntent(TRANSPORT_NAME);
+    }
+
+    @Test
+    public void getDataManagementLabel_calledBeforeInitialize_ignored() throws RemoteException {
+        assertNull(mTrampoline.getDataManagementLabel(TRANSPORT_NAME));
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void getDataManagementLabel_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.getDataManagementLabel(TRANSPORT_NAME)).thenReturn(
+                DATA_MANAGEMENT_LABEL);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(DATA_MANAGEMENT_LABEL, mTrampoline.getDataManagementLabel(TRANSPORT_NAME));
+        verify(mBackupManagerServiceMock).getDataManagementLabel(TRANSPORT_NAME);
+    }
+
+    @Test
+    public void beginRestoreSession_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.beginRestoreSession(PACKAGE_NAME, TRANSPORT_NAME);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void beginRestoreSession_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.beginRestoreSession(PACKAGE_NAME, TRANSPORT_NAME);
+        verify(mBackupManagerServiceMock).beginRestoreSession(PACKAGE_NAME, TRANSPORT_NAME);
+    }
+
+    @Test
+    public void opComplete_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.opComplete(1, 2);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void opComplete_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.opComplete(1, 2);
+        verify(mBackupManagerServiceMock).opComplete(1, 2);
+    }
+
+    @Test
+    public void getAvailableRestoreToken_calledBeforeInitialize_ignored() throws RemoteException {
+        assertEquals(0, mTrampoline.getAvailableRestoreToken(PACKAGE_NAME));
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void getAvailableRestoreToken_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.getAvailableRestoreToken(PACKAGE_NAME)).thenReturn(123L);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(123, mTrampoline.getAvailableRestoreToken(PACKAGE_NAME));
+        verify(mBackupManagerServiceMock).getAvailableRestoreToken(PACKAGE_NAME);
+    }
+
+    @Test
+    public void isAppEligibleForBackup_calledBeforeInitialize_ignored() throws RemoteException {
+        assertFalse(mTrampoline.isAppEligibleForBackup(PACKAGE_NAME));
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void isAppEligibleForBackup_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.isAppEligibleForBackup(PACKAGE_NAME)).thenReturn(true);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertTrue(mTrampoline.isAppEligibleForBackup(PACKAGE_NAME));
+        verify(mBackupManagerServiceMock).isAppEligibleForBackup(PACKAGE_NAME);
+    }
+
+    @Test
+    public void requestBackup_calledBeforeInitialize_ignored() throws RemoteException {
+        assertEquals(BackupManager.ERROR_BACKUP_NOT_ALLOWED, mTrampoline.requestBackup(
+                PACKAGE_NAMES, mBackupObserverMock, mBackupManagerMonitorMock, 123));
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void requestBackup_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.requestBackup(PACKAGE_NAMES, mBackupObserverMock,
+                mBackupManagerMonitorMock, 123)).thenReturn(456);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(456, mTrampoline.requestBackup(PACKAGE_NAMES, mBackupObserverMock,
+                mBackupManagerMonitorMock, 123));
+        verify(mBackupManagerServiceMock).requestBackup(PACKAGE_NAMES, mBackupObserverMock,
+                mBackupManagerMonitorMock, 123);
+    }
+
+    @Test
+    public void cancelBackups_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.cancelBackups();
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void cancelBackups_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.cancelBackups();
+        verify(mBackupManagerServiceMock).cancelBackups();
+    }
+
+    @Test
+    public void beginFullBackup_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.beginFullBackup(new FullBackupJob());
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void beginFullBackup_forwarded() throws RemoteException {
+        FullBackupJob fullBackupJob = new FullBackupJob();
+        when(mBackupManagerServiceMock.beginFullBackup(fullBackupJob)).thenReturn(true);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertTrue(mTrampoline.beginFullBackup(fullBackupJob));
+        verify(mBackupManagerServiceMock).beginFullBackup(fullBackupJob);
+    }
+
+    @Test
+    public void endFullBackup_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.endFullBackup();
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void endFullBackup_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.endFullBackup();
+        verify(mBackupManagerServiceMock).endFullBackup();
+    }
+
+    @Test
+    public void dump_callerDoesNotHavePermission_ignored() throws RemoteException {
+        when(mContextMock.checkCallingOrSelfPermission(
+                android.Manifest.permission.DUMP)).thenReturn(
+                PackageManager.PERMISSION_DENIED);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+
+        mTrampoline.dump(mFileDescriptorStub, mPrintWriterMock, new String[0]);
+
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void dump_calledBeforeInitialize_ignored() throws RemoteException {
+        when(mContextMock.checkCallingOrSelfPermission(
+                android.Manifest.permission.DUMP)).thenReturn(
+                PackageManager.PERMISSION_GRANTED);
+
+        mTrampoline.dump(mFileDescriptorStub, mPrintWriterMock, new String[0]);
+
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void dump_callerHasPermission_forwarded() throws RemoteException {
+        when(mContextMock.checkCallingOrSelfPermission(
+                android.Manifest.permission.DUMP)).thenReturn(
+                PackageManager.PERMISSION_GRANTED);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+
+        mTrampoline.dump(mFileDescriptorStub, mPrintWriterMock, null);
+
+        verify(mBackupManagerServiceMock).dump(mFileDescriptorStub, mPrintWriterMock, null);
+    }
+
+    private static class TrampolineTestable extends Trampoline {
+        static boolean sBackupDisabled = false;
+        static boolean sRefactoredServiceEnabled = false;
+        static File sSuppressFile = null;
+        static int sCallingUid = -1;
+        static BackupManagerService sBackupManagerServiceMock = null;
+        static RefactoredBackupManagerService sRefactoredBackupManagerServiceMock = null;
+        private int mCreateServiceCallsCount = 0;
+
+        TrampolineTestable(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected BackupManagerServiceInterface createService() {
+            mCreateServiceCallsCount++;
+            return super.createService();
+        }
+
+        @Override
+        public boolean isBackupDisabled() {
+            return sBackupDisabled;
+        }
+
+        @Override
+        public File getSuppressFile() {
+            return sSuppressFile;
+        }
+
+        @Override
+        protected int binderGetCallingUid() {
+            return sCallingUid;
+        }
+
+        @Override
+        protected boolean isRefactoredServiceEnabled() {
+            return sRefactoredServiceEnabled;
+        }
+
+        @Override
+        protected BackupManagerServiceInterface createRefactoredBackupManagerService() {
+            return sRefactoredBackupManagerServiceMock;
+        }
+
+        @Override
+        protected BackupManagerServiceInterface createBackupManagerService() {
+            return sBackupManagerServiceMock;
+        }
+
+        int getCreateServiceCallsCount() {
+            return mCreateServiceCallsCount;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/backup/restore/PerformAdbRestoreTaskTest.java b/services/tests/servicestests/src/com/android/server/backup/restore/PerformAdbRestoreTaskTest.java
new file mode 100644
index 0000000..05f4c13
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/restore/PerformAdbRestoreTaskTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.restore;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.frameworks.servicestests.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+import java.io.InputStream;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class PerformAdbRestoreTaskTest {
+    private Context mContext;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = InstrumentationRegistry.getContext();
+    }
+
+    @Test
+    public void parseBackupFileAndReturnTarStream_backupNotEncrypted_returnsNonNull()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+
+        assertThat(tarInputStream).isNotNull();
+    }
+
+    @Test
+    public void
+    parseBackupFileAndReturnTarStream_backupEncryptedAndPasswordProvided_returnsNonNull()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, "123");
+
+        assertThat(tarInputStream).isNotNull();
+    }
+
+    @Test
+    public void
+    parseBackupFileAndReturnTarStream_backupEncryptedAndPasswordNotProvided_returnsNull()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+
+        assertThat(tarInputStream).isNull();
+    }
+
+    @Test
+    public void
+    parseBackupFileAndReturnTarStream_backupEncryptedAndIncorrectPassword_returnsNull()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, "1234");
+
+        assertThat(tarInputStream).isNull();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java b/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java
new file mode 100644
index 0000000..45b107d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java
@@ -0,0 +1,1008 @@
+package com.android.server.backup.testutils;
+
+import android.app.PackageInstallObserver;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ChangedPackages;
+import android.content.pm.FeatureInfo;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageInstallObserver;
+import android.content.pm.IPackageStatsObserver;
+import android.content.pm.InstantAppInfo;
+import android.content.pm.InstrumentationInfo;
+import android.content.pm.IntentFilterVerificationInfo;
+import android.content.pm.KeySet;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionGroupInfo;
+import android.content.pm.PermissionInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.pm.SharedLibraryInfo;
+import android.content.pm.VerifierDeviceIdentity;
+import android.content.pm.VersionedPackage;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.storage.VolumeInfo;
+
+import java.util.List;
+
+/**
+ * Stub for PackageManager to use in tests.
+ */
+public class PackageManagerStub extends PackageManager {
+    public static PackageInfo sPackageInfo;
+
+    @Override
+    public PackageInfo getPackageInfo(String packageName, int flags)
+            throws NameNotFoundException {
+        if (sPackageInfo == null) {
+            throw new NameNotFoundException();
+        }
+
+        return sPackageInfo;
+    }
+
+    @Override
+    public PackageInfo getPackageInfo(VersionedPackage versionedPackage, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public String[] currentToCanonicalPackageNames(String[] names) {
+        return new String[0];
+    }
+
+    @Override
+    public String[] canonicalToCurrentPackageNames(String[] names) {
+        return new String[0];
+    }
+
+    @Override
+    public Intent getLaunchIntentForPackage(String packageName) {
+        return null;
+    }
+
+    @Override
+    public Intent getLeanbackLaunchIntentForPackage(String packageName) {
+        return null;
+    }
+
+    @Override
+    public int[] getPackageGids(String packageName) throws NameNotFoundException {
+        return new int[0];
+    }
+
+    @Override
+    public int[] getPackageGids(String packageName, int flags)
+            throws NameNotFoundException {
+        return new int[0];
+    }
+
+    @Override
+    public int getPackageUid(String packageName, int flags)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int getPackageUidAsUser(String packageName, int userId)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int getPackageUidAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public PermissionInfo getPermissionInfo(String name, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public boolean isPermissionReviewModeEnabled() {
+        return false;
+    }
+
+    @Override
+    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
+        return null;
+    }
+
+    @Override
+    public ApplicationInfo getApplicationInfo(String packageName, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ActivityInfo getActivityInfo(ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ActivityInfo getReceiverInfo(ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ServiceInfo getServiceInfo(ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ProviderInfo getProviderInfo(ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public List<PackageInfo> getInstalledPackages(int flags) {
+        return null;
+    }
+
+    @Override
+    public List<PackageInfo> getPackagesHoldingPermissions(String[] permissions, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public int checkPermission(String permName, String pkgName) {
+        return 0;
+    }
+
+    @Override
+    public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
+        return false;
+    }
+
+    @Override
+    public String getPermissionControllerPackageName() {
+        return null;
+    }
+
+    @Override
+    public boolean addPermission(PermissionInfo info) {
+        return false;
+    }
+
+    @Override
+    public boolean addPermissionAsync(PermissionInfo info) {
+        return false;
+    }
+
+    @Override
+    public void removePermission(String name) {
+
+    }
+
+    @Override
+    public void grantRuntimePermission(String packageName, String permissionName,
+            UserHandle user) {
+
+    }
+
+    @Override
+    public void revokeRuntimePermission(String packageName, String permissionName,
+            UserHandle user) {
+
+    }
+
+    @Override
+    public int getPermissionFlags(String permissionName, String packageName, UserHandle user) {
+        return 0;
+    }
+
+    @Override
+    public void updatePermissionFlags(String permissionName, String packageName, int flagMask,
+            int flagValues, UserHandle user) {
+
+    }
+
+    @Override
+    public boolean shouldShowRequestPermissionRationale(String permission) {
+        return false;
+    }
+
+    @Override
+    public int checkSignatures(String pkg1, String pkg2) {
+        return 0;
+    }
+
+    @Override
+    public int checkSignatures(int uid1, int uid2) {
+        return 0;
+    }
+
+    @Override
+    public String[] getPackagesForUid(int uid) {
+        return new String[0];
+    }
+
+    @Override
+    public String getNameForUid(int uid) {
+        return null;
+    }
+
+    @Override
+    public int getUidForSharedUser(String sharedUserName)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public List<ApplicationInfo> getInstalledApplications(int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<InstantAppInfo> getInstantApps() {
+        return null;
+    }
+
+    @Override
+    public Drawable getInstantAppIcon(String packageName) {
+        return null;
+    }
+
+    @Override
+    public boolean isInstantApp() {
+        return false;
+    }
+
+    @Override
+    public boolean isInstantApp(String packageName) {
+        return false;
+    }
+
+    @Override
+    public int getInstantAppCookieMaxBytes() {
+        return 0;
+    }
+
+    @Override
+    public int getInstantAppCookieMaxSize() {
+        return 0;
+    }
+
+    @Override
+    public byte[] getInstantAppCookie() {
+        return new byte[0];
+    }
+
+    @Override
+    public void clearInstantAppCookie() {
+
+    }
+
+    @Override
+    public void updateInstantAppCookie(byte[] cookie) {
+
+    }
+
+    @Override
+    public boolean setInstantAppCookie(byte[] cookie) {
+        return false;
+    }
+
+    @Override
+    public String[] getSystemSharedLibraryNames() {
+        return new String[0];
+    }
+
+    @Override
+    public List<SharedLibraryInfo> getSharedLibraries(int flags) {
+        return null;
+    }
+
+    @Override
+    public List<SharedLibraryInfo> getSharedLibrariesAsUser(int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public String getServicesSystemSharedLibraryPackageName() {
+        return null;
+    }
+
+    @Override
+    public String getSharedSystemSharedLibraryPackageName() {
+        return null;
+    }
+
+    @Override
+    public ChangedPackages getChangedPackages(int sequenceNumber) {
+        return null;
+    }
+
+    @Override
+    public FeatureInfo[] getSystemAvailableFeatures() {
+        return new FeatureInfo[0];
+    }
+
+    @Override
+    public boolean hasSystemFeature(String name) {
+        return false;
+    }
+
+    @Override
+    public boolean hasSystemFeature(String name, int version) {
+        return false;
+    }
+
+    @Override
+    public ResolveInfo resolveActivity(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
+            Intent[] specifics,
+            Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags,
+            int userId) {
+        return null;
+    }
+
+    @Override
+    public ResolveInfo resolveService(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentContentProvidersAsUser(Intent intent, int flags,
+            int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public ProviderInfo resolveContentProvider(String name, int flags) {
+        return null;
+    }
+
+    @Override
+    public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) {
+        return null;
+    }
+
+    @Override
+    public InstrumentationInfo getInstrumentationInfo(ComponentName className, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public List<InstrumentationInfo> queryInstrumentation(String targetPackage, int flags) {
+        return null;
+    }
+
+    @Override
+    public Drawable getDrawable(String packageName, int resid, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityIcon(ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityIcon(Intent intent) throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityBanner(ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityBanner(Intent intent) throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getDefaultActivityIcon() {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationIcon(ApplicationInfo info) {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationIcon(String packageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationBanner(ApplicationInfo info) {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationBanner(String packageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityLogo(ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityLogo(Intent intent) throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationLogo(ApplicationInfo info) {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationLogo(String packageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
+        return null;
+    }
+
+    @Override
+    public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
+            Rect badgeLocation, int badgeDensity) {
+        return null;
+    }
+
+    @Override
+    public Drawable getUserBadgeForDensity(UserHandle user, int density) {
+        return null;
+    }
+
+    @Override
+    public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
+        return null;
+    }
+
+    @Override
+    public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
+        return null;
+    }
+
+    @Override
+    public CharSequence getText(String packageName, int resid, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public XmlResourceParser getXml(String packageName, int resid, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public CharSequence getApplicationLabel(ApplicationInfo info) {
+        return null;
+    }
+
+    @Override
+    public Resources getResourcesForActivity(ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Resources getResourcesForApplication(ApplicationInfo app)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Resources getResourcesForApplication(String appPackageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
+            String installerPackageName) {
+
+    }
+
+    @Override
+    public void installPackage(Uri packageURI, PackageInstallObserver observer, int flags,
+            String installerPackageName) {
+
+    }
+
+    @Override
+    public int installExistingPackage(String packageName)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int installExistingPackage(String packageName, int installReason)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int installExistingPackageAsUser(String packageName, int userId)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public void verifyPendingInstall(int id, int verificationCode) {
+
+    }
+
+    @Override
+    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
+            long millisecondsToDelay) {
+
+    }
+
+    @Override
+    public void verifyIntentFilter(int verificationId, int verificationCode,
+            List<String> failedDomains) {
+
+    }
+
+    @Override
+    public int getIntentVerificationStatusAsUser(String packageName, int userId) {
+        return 0;
+    }
+
+    @Override
+    public boolean updateIntentVerificationStatusAsUser(String packageName, int status,
+            int userId) {
+        return false;
+    }
+
+    @Override
+    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
+        return null;
+    }
+
+    @Override
+    public List<IntentFilter> getAllIntentFilters(String packageName) {
+        return null;
+    }
+
+    @Override
+    public String getDefaultBrowserPackageNameAsUser(int userId) {
+        return null;
+    }
+
+    @Override
+    public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
+        return false;
+    }
+
+    @Override
+    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
+
+    }
+
+    @Override
+    public void setUpdateAvailable(String packageName, boolean updateAvaialble) {
+
+    }
+
+    @Override
+    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
+
+    }
+
+    @Override
+    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer,
+            int flags,
+            int userId) {
+
+    }
+
+    @Override
+    public String getInstallerPackageName(String packageName) {
+        return null;
+    }
+
+    @Override
+    public void clearApplicationUserData(String packageName, IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void deleteApplicationCacheFiles(String packageName, IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void deleteApplicationCacheFilesAsUser(String packageName, int userId,
+            IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void freeStorageAndNotify(String volumeUuid, long freeStorageSize,
+            IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
+
+    }
+
+    @Override
+    public void getPackageSizeInfoAsUser(String packageName, int userId,
+            IPackageStatsObserver observer) {
+
+    }
+
+    @Override
+    public void addPackageToPreferred(String packageName) {
+
+    }
+
+    @Override
+    public void removePackageFromPreferred(String packageName) {
+
+    }
+
+    @Override
+    public List<PackageInfo> getPreferredPackages(int flags) {
+        return null;
+    }
+
+    @Override
+    public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set,
+            ComponentName activity) {
+
+    }
+
+    @Override
+    public void replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set,
+            ComponentName activity) {
+
+    }
+
+    @Override
+    public void clearPackagePreferredActivities(String packageName) {
+
+    }
+
+    @Override
+    public int getPreferredActivities(List<IntentFilter> outFilters,
+            List<ComponentName> outActivities, String packageName) {
+        return 0;
+    }
+
+    @Override
+    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
+        return null;
+    }
+
+    @Override
+    public void setComponentEnabledSetting(ComponentName componentName, int newState,
+            int flags) {
+
+    }
+
+    @Override
+    public int getComponentEnabledSetting(ComponentName componentName) {
+        return 0;
+    }
+
+    @Override
+    public void setApplicationEnabledSetting(String packageName, int newState, int flags) {
+
+    }
+
+    @Override
+    public int getApplicationEnabledSetting(String packageName) {
+        return 0;
+    }
+
+    @Override
+    public void flushPackageRestrictionsAsUser(int userId) {
+
+    }
+
+    @Override
+    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
+            UserHandle userHandle) {
+        return false;
+    }
+
+    @Override
+    public boolean getApplicationHiddenSettingAsUser(String packageName,
+            UserHandle userHandle) {
+        return false;
+    }
+
+    @Override
+    public boolean isSafeMode() {
+        return false;
+    }
+
+    @Override
+    public void addOnPermissionsChangeListener(
+            OnPermissionsChangedListener listener) {
+
+    }
+
+    @Override
+    public void removeOnPermissionsChangeListener(
+            OnPermissionsChangedListener listener) {
+
+    }
+
+    @Override
+    public KeySet getKeySetByAlias(String packageName, String alias) {
+        return null;
+    }
+
+    @Override
+    public KeySet getSigningKeySet(String packageName) {
+        return null;
+    }
+
+    @Override
+    public boolean isSignedBy(String packageName, KeySet ks) {
+        return false;
+    }
+
+    @Override
+    public boolean isSignedByExactly(String packageName, KeySet ks) {
+        return false;
+    }
+
+    @Override
+    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
+            int userId) {
+        return new String[0];
+    }
+
+    @Override
+    public boolean isPackageSuspendedForUser(String packageName, int userId) {
+        return false;
+    }
+
+    @Override
+    public void setApplicationCategoryHint(String packageName, int categoryHint) {
+
+    }
+
+    @Override
+    public int getMoveStatus(int moveId) {
+        return 0;
+    }
+
+    @Override
+    public void registerMoveCallback(MoveCallback callback, Handler handler) {
+
+    }
+
+    @Override
+    public void unregisterMoveCallback(MoveCallback callback) {
+
+    }
+
+    @Override
+    public int movePackage(String packageName, VolumeInfo vol) {
+        return 0;
+    }
+
+    @Override
+    public VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
+        return null;
+    }
+
+    @Override
+    public List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
+        return null;
+    }
+
+    @Override
+    public int movePrimaryStorage(VolumeInfo vol) {
+        return 0;
+    }
+
+    @Override
+    public VolumeInfo getPrimaryStorageCurrentVolume() {
+        return null;
+    }
+
+    @Override
+    public List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
+        return null;
+    }
+
+    @Override
+    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
+        return null;
+    }
+
+    @Override
+    public boolean isUpgrade() {
+        return false;
+    }
+
+    @Override
+    public PackageInstaller getPackageInstaller() {
+        return null;
+    }
+
+    @Override
+    public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId,
+            int targetUserId,
+            int flags) {
+
+    }
+
+    @Override
+    public void clearCrossProfileIntentFilters(int sourceUserId) {
+
+    }
+
+    @Override
+    public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public boolean isPackageAvailable(String packageName) {
+        return false;
+    }
+
+    @Override
+    public int getInstallReason(String packageName, UserHandle user) {
+        return 0;
+    }
+
+    @Override
+    public boolean canRequestPackageInstalls() {
+        return false;
+    }
+
+    @Override
+    public ComponentName getInstantAppResolverSettingsComponent() {
+        return null;
+    }
+
+    @Override
+    public ComponentName getInstantAppInstallerComponent() {
+        return null;
+    }
+
+    @Override
+    public String getInstantAppAndroidId(String packageName, UserHandle user) {
+        return null;
+    }
+
+    @Override
+    public void registerDexModule(String dexModulePath,
+            DexModuleRegisterCallback callback) {
+
+    }
+}
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
new file mode 100644
index 0000000..650681e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
@@ -0,0 +1,460 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.Signature;
+import android.os.Process;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.server.backup.RefactoredBackupManagerService;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Random;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class AppBackupUtilsTest {
+    private static final String CUSTOM_BACKUP_AGENT_NAME = "custom.backup.agent";
+    private static final String TEST_PACKAGE_NAME = "test_package";
+
+    private final Random mRandom = new Random(1000000009);
+
+    @Test
+    public void appIsEligibleForBackup_backupNotAllowed_returnsFalse() throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags = 0;
+        applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
+        applicationInfo.packageName = TEST_PACKAGE_NAME;
+
+        boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isFalse();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_systemAppWithoutCustomBackupAgent_returnsFalse()
+            throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        applicationInfo.uid = Process.SYSTEM_UID;
+        applicationInfo.backupAgentName = null;
+        applicationInfo.packageName = TEST_PACKAGE_NAME;
+
+        boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isFalse();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_sharedStorageBackupPackage_returnsFalse() throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        applicationInfo.uid = Process.SYSTEM_UID;
+        applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
+        applicationInfo.packageName = RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+
+        boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isFalse();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_systemAppWithCustomBackupAgent_returnsTrue()
+            throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        applicationInfo.uid = Process.SYSTEM_UID;
+        applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
+        applicationInfo.packageName = TEST_PACKAGE_NAME;
+
+        boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isTrue();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_nonSystemAppWithoutCustomBackupAgent_returnsTrue()
+            throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        applicationInfo.backupAgentName = null;
+        applicationInfo.packageName = TEST_PACKAGE_NAME;
+
+        boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isTrue();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_nonSystemAppWithCustomBackupAgent_returnsTrue()
+            throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
+        applicationInfo.packageName = TEST_PACKAGE_NAME;
+
+        boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isTrue();
+    }
+
+    @Test
+    public void appIsStopped_returnsTrue() throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_STOPPED;
+
+        boolean isStopped = AppBackupUtils.appIsStopped(applicationInfo);
+
+        assertThat(isStopped).isTrue();
+    }
+
+    @Test
+    public void appIsStopped_returnsFalse() throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags = ~ApplicationInfo.FLAG_STOPPED;
+
+        boolean isStopped = AppBackupUtils.appIsStopped(applicationInfo);
+
+        assertThat(isStopped).isFalse();
+    }
+
+    @Test
+    public void appGetsFullBackup_noCustomBackupAgent_returnsTrue() throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.backupAgentName = null;
+
+        boolean result = AppBackupUtils.appGetsFullBackup(packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void appGetsFullBackup_withCustomBackupAgentAndFullBackupOnlyFlag_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.backupAgentName = "backup.agent";
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
+
+        boolean result = AppBackupUtils.appGetsFullBackup(packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void appGetsFullBackup_withCustomBackupAgentAndWithoutFullBackupOnlyFlag_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.backupAgentName = "backup.agent";
+        packageInfo.applicationInfo.flags = ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
+
+        boolean result = AppBackupUtils.appGetsFullBackup(packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void appIsKeyValueOnly_noCustomBackupAgent_returnsTrue() throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.backupAgentName = null;
+
+        boolean result = AppBackupUtils.appIsKeyValueOnly(packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void appIsKeyValueOnly_withCustomBackupAgentAndFullBackupOnlyFlag_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.backupAgentName = "backup.agent";
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
+
+        boolean result = AppBackupUtils.appIsKeyValueOnly(packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void appIsKeyValueOnly_withCustomBackupAgentAndWithoutFullBackupOnlyFlag_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.backupAgentName = "backup.agent";
+        packageInfo.applicationInfo.flags = ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
+
+        boolean result = AppBackupUtils.appIsKeyValueOnly(packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_targetIsNull_returnsFalse() throws Exception {
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], null);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_systemApplication_returnsTrue() throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_allowsUnsignedApps_bothSignaturesNull_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = null;
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(null, packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_allowsUnsignedApps_bothSignaturesEmpty_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[0];
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void
+    signaturesMatch_allowsUnsignedApps_storedSignatureNullTargetSignatureEmpty_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[0];
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(null, packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void
+    signaturesMatch_allowsUnsignedApps_storedSignatureEmptyTargetSignatureNull_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = null;
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void
+    signaturesMatch_disallowsAppsUnsignedOnOnlyOneDevice_storedSignatureIsNull_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[]{generateRandomSignature()};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(null, packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void
+    signaturesMatch_disallowsAppsUnsignedOnOnlyOneDevice_targetSignatureIsNull_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = null;
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[]{generateRandomSignature()},
+                packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_signaturesMatch_returnsTrue() throws Exception {
+        Signature signature1 = generateRandomSignature();
+        Signature signature2 = generateRandomSignature();
+        Signature signature3 = generateRandomSignature();
+        assertThat(signature1).isNotEqualTo(signature2);
+        assertThat(signature2).isNotEqualTo(signature3);
+        assertThat(signature1).isNotEqualTo(signature3);
+
+        Signature signature1Copy = new Signature(signature1.toByteArray());
+        Signature signature2Copy = new Signature(signature2.toByteArray());
+        Signature signature3Copy = new Signature(signature3.toByteArray());
+        assertThat(signature1Copy).isEqualTo(signature1);
+        assertThat(signature2Copy).isEqualTo(signature2);
+        assertThat(signature3Copy).isEqualTo(signature3);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[]{signature1, signature2, signature3};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(
+                new Signature[]{signature3Copy, signature1Copy, signature2Copy}, packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_extraSignatureInTarget_returnsTrue() throws Exception {
+        Signature signature1 = generateRandomSignature();
+        Signature signature2 = generateRandomSignature();
+        Signature signature3 = generateRandomSignature();
+        assertThat(signature1).isNotEqualTo(signature2);
+        assertThat(signature2).isNotEqualTo(signature3);
+        assertThat(signature1).isNotEqualTo(signature3);
+
+        Signature signature1Copy = new Signature(signature1.toByteArray());
+        Signature signature2Copy = new Signature(signature2.toByteArray());
+        assertThat(signature1Copy).isEqualTo(signature1);
+        assertThat(signature2Copy).isEqualTo(signature2);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[]{signature1, signature2, signature3};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(
+                new Signature[]{signature2Copy, signature1Copy}, packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_extraSignatureInStored_returnsFalse() throws Exception {
+        Signature signature1 = generateRandomSignature();
+        Signature signature2 = generateRandomSignature();
+        Signature signature3 = generateRandomSignature();
+        assertThat(signature1).isNotEqualTo(signature2);
+        assertThat(signature2).isNotEqualTo(signature3);
+        assertThat(signature1).isNotEqualTo(signature3);
+
+        Signature signature1Copy = new Signature(signature1.toByteArray());
+        Signature signature2Copy = new Signature(signature2.toByteArray());
+        assertThat(signature1Copy).isEqualTo(signature1);
+        assertThat(signature2Copy).isEqualTo(signature2);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[]{signature1Copy, signature2Copy};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(
+                new Signature[]{signature1, signature2, signature3}, packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_emptyStoredSignatures_returnsTrue() throws Exception {
+        Signature signature1 = generateRandomSignature();
+        Signature signature2 = generateRandomSignature();
+        Signature signature3 = generateRandomSignature();
+        assertThat(signature1).isNotEqualTo(signature2);
+        assertThat(signature2).isNotEqualTo(signature3);
+        assertThat(signature1).isNotEqualTo(signature3);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[]{signature1, signature2, signature3};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_emptyTargetSignatures_returnsFalse() throws Exception {
+        Signature signature1 = generateRandomSignature();
+        Signature signature2 = generateRandomSignature();
+        Signature signature3 = generateRandomSignature();
+        assertThat(signature1).isNotEqualTo(signature2);
+        assertThat(signature2).isNotEqualTo(signature3);
+        assertThat(signature1).isNotEqualTo(signature3);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[0];
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(
+                new Signature[]{signature1, signature2, signature3}, packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_oneNonMatchingSignature_returnsFalse() throws Exception {
+        Signature signature1 = generateRandomSignature();
+        Signature signature2 = generateRandomSignature();
+        Signature signature3 = generateRandomSignature();
+        Signature signature4 = generateRandomSignature();
+        assertThat(signature1).isNotEqualTo(signature2);
+        assertThat(signature2).isNotEqualTo(signature3);
+        assertThat(signature1).isNotEqualTo(signature3);
+        assertThat(signature1).isNotEqualTo(signature4);
+        assertThat(signature2).isNotEqualTo(signature4);
+        assertThat(signature3).isNotEqualTo(signature4);
+
+        Signature signature1Copy = new Signature(signature1.toByteArray());
+        Signature signature2Copy = new Signature(signature2.toByteArray());
+        assertThat(signature1Copy).isEqualTo(signature1);
+        assertThat(signature2Copy).isEqualTo(signature2);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[]{signature1, signature2, signature3};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(
+                new Signature[]{signature1Copy, signature2Copy, signature4}, packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    private Signature generateRandomSignature() {
+        byte[] signatureBytes = new byte[256];
+        mRandom.nextBytes(signatureBytes);
+        return new Signature(signatureBytes);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java
new file mode 100644
index 0000000..87c587a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_ID;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_VERSION;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+
+import android.app.backup.IBackupManagerMonitor;
+import android.content.pm.PackageInfo;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class BackupManagerMonitorUtilsTest {
+    @Mock private IBackupManagerMonitor mMonitorMock;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void monitorEvent_monitorIsNull_returnsNull() throws Exception {
+        IBackupManagerMonitor result = BackupManagerMonitorUtils.monitorEvent(null, 0, null, 0,
+                null);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void monitorEvent_monitorOnEventThrows_returnsNull() throws Exception {
+        doThrow(new RemoteException()).when(mMonitorMock).onEvent(any(Bundle.class));
+
+        IBackupManagerMonitor result = BackupManagerMonitorUtils.monitorEvent(mMonitorMock, 0, null,
+                0, null);
+
+        verify(mMonitorMock).onEvent(any(Bundle.class));
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void monitorEvent_packageAndExtrasAreNull_fillsBundleCorrectly() throws Exception {
+        IBackupManagerMonitor result = BackupManagerMonitorUtils.monitorEvent(mMonitorMock, 1, null,
+                2, null);
+
+        assertThat(result).isEqualTo(mMonitorMock);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mMonitorMock).onEvent(bundleCaptor.capture());
+        Bundle eventBundle = bundleCaptor.getValue();
+        assertThat(eventBundle.size()).isEqualTo(2);
+        assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_ID)).isEqualTo(1);
+        assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_CATEGORY)).isEqualTo(2);
+    }
+
+    @Test
+    public void monitorEvent_packageAndExtrasAreNotNull_fillsBundleCorrectly() throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = "test.package";
+        packageInfo.versionCode = 3;
+        Bundle extras = new Bundle();
+        extras.putInt("key1", 4);
+        extras.putString("key2", "value2");
+
+        IBackupManagerMonitor result = BackupManagerMonitorUtils.monitorEvent(mMonitorMock, 1,
+                packageInfo, 2, extras);
+
+        assertThat(result).isEqualTo(mMonitorMock);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mMonitorMock).onEvent(bundleCaptor.capture());
+        Bundle eventBundle = bundleCaptor.getValue();
+        assertThat(eventBundle.size()).isEqualTo(6);
+        assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_ID)).isEqualTo(1);
+        assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_CATEGORY)).isEqualTo(2);
+        assertThat(eventBundle.getString(EXTRA_LOG_EVENT_PACKAGE_NAME)).isEqualTo("test.package");
+        assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_PACKAGE_VERSION)).isEqualTo(3);
+        assertThat(eventBundle.getInt("key1")).isEqualTo(4);
+        assertThat(eventBundle.getString("key2")).isEqualTo("value2");
+    }
+
+    @Test
+    public void putMonitoringExtraString_bundleExists_fillsBundleCorrectly() throws Exception {
+        Bundle bundle = new Bundle();
+
+        Bundle result = BackupManagerMonitorUtils.putMonitoringExtra(bundle, "key", "value");
+
+        assertThat(result).isEqualTo(bundle);
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.getString("key")).isEqualTo("value");
+    }
+
+    @Test
+    public void putMonitoringExtraString_bundleDoesNotExist_fillsBundleCorrectly()
+            throws Exception {
+        Bundle result = BackupManagerMonitorUtils.putMonitoringExtra(null, "key", "value");
+
+        assertThat(result).isNotNull();
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.getString("key")).isEqualTo("value");
+    }
+
+
+    @Test
+    public void putMonitoringExtraLong_bundleExists_fillsBundleCorrectly() throws Exception {
+        Bundle bundle = new Bundle();
+
+        Bundle result = BackupManagerMonitorUtils.putMonitoringExtra(bundle, "key", 123);
+
+        assertThat(result).isEqualTo(bundle);
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.getLong("key")).isEqualTo(123);
+    }
+
+    @Test
+    public void putMonitoringExtraLong_bundleDoesNotExist_fillsBundleCorrectly() throws Exception {
+        Bundle result = BackupManagerMonitorUtils.putMonitoringExtra(null, "key", 123);
+
+        assertThat(result).isNotNull();
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.getLong("key")).isEqualTo(123);
+    }
+
+    @Test
+    public void putMonitoringExtraBoolean_bundleExists_fillsBundleCorrectly() throws Exception {
+        Bundle bundle = new Bundle();
+
+        Bundle result = BackupManagerMonitorUtils.putMonitoringExtra(bundle, "key", true);
+
+        assertThat(result).isEqualTo(bundle);
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.getBoolean("key")).isTrue();
+    }
+
+    @Test
+    public void putMonitoringExtraBoolean_bundleDoesNotExist_fillsBundleCorrectly()
+            throws Exception {
+        Bundle result = BackupManagerMonitorUtils.putMonitoringExtra(null, "key", true);
+
+        assertThat(result).isNotNull();
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.getBoolean("key")).isTrue();
+    }
+
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/BackupObserverUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/BackupObserverUtilsTest.java
new file mode 100644
index 0000000..ebe6133
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/BackupObserverUtilsTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+
+import android.app.backup.BackupProgress;
+import android.app.backup.IBackupObserver;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class BackupObserverUtilsTest {
+    private static final String PACKAGE_NAME = "some.package";
+
+    @Mock
+    private IBackupObserver mBackupObserverMock;
+    private final BackupProgress mBackupProgress = new BackupProgress(0, 0);
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void sendBackupOnUpdate_observerIsNull_doesNotThrow() throws Exception {
+        BackupObserverUtils.sendBackupOnUpdate(null, PACKAGE_NAME, mBackupProgress);
+
+        // Should not throw.
+    }
+
+    @Test
+    public void sendBackupOnUpdate_callsObserver() throws Exception {
+        BackupObserverUtils.sendBackupOnUpdate(mBackupObserverMock, PACKAGE_NAME, mBackupProgress);
+
+        verify(mBackupObserverMock).onUpdate(PACKAGE_NAME, mBackupProgress);
+    }
+
+    @Test
+    public void sendBackupOnUpdate_handlesRemoteException() throws Exception {
+        doThrow(new RemoteException()).when(mBackupObserverMock).onUpdate(PACKAGE_NAME,
+                mBackupProgress);
+
+        BackupObserverUtils.sendBackupOnUpdate(mBackupObserverMock, PACKAGE_NAME, mBackupProgress);
+
+        verify(mBackupObserverMock).onUpdate(PACKAGE_NAME, mBackupProgress);
+    }
+
+    @Test
+    public void sendBackupOnPackageResult_observerIsNull_doesNotThrow() throws Exception {
+        BackupObserverUtils.sendBackupOnPackageResult(null, PACKAGE_NAME, 1);
+
+        // Should not throw.
+    }
+
+    @Test
+    public void sendBackupOnPackageResult_callsObserver() throws Exception {
+        BackupObserverUtils.sendBackupOnPackageResult(mBackupObserverMock, PACKAGE_NAME, 1);
+
+        verify(mBackupObserverMock).onResult(PACKAGE_NAME, 1);
+    }
+
+    @Test
+    public void sendBackupOnPackageResult_handlesRemoteException() throws Exception {
+        doThrow(new RemoteException()).when(mBackupObserverMock).onResult(PACKAGE_NAME, 1);
+
+        BackupObserverUtils.sendBackupOnPackageResult(mBackupObserverMock, PACKAGE_NAME, 1);
+
+        verify(mBackupObserverMock).onResult(PACKAGE_NAME, 1);
+    }
+
+    @Test
+    public void sendBackupFinished_observerIsNull_doesNotThrow() throws Exception {
+        BackupObserverUtils.sendBackupFinished(null, 1);
+
+        // Should not throw.
+    }
+
+    @Test
+    public void sendBackupFinished_callsObserver() throws Exception {
+        BackupObserverUtils.sendBackupFinished(mBackupObserverMock, 1);
+
+        verify(mBackupObserverMock).backupFinished(1);
+    }
+
+    @Test
+    public void sendBackupFinished_handlesRemoteException() throws Exception {
+        doThrow(new RemoteException()).when(mBackupObserverMock).onResult(PACKAGE_NAME, 1);
+
+        BackupObserverUtils.sendBackupFinished(mBackupObserverMock, 1);
+
+        verify(mBackupObserverMock).backupFinished(1);
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupRestoreObserverUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupRestoreObserverUtilsTest.java
new file mode 100644
index 0000000..2f56598
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupRestoreObserverUtilsTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+
+import android.app.backup.IFullBackupRestoreObserver;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class FullBackupRestoreObserverUtilsTest {
+    private static final String PACKAGE_NAME = "some.package";
+    @Mock
+    private IFullBackupRestoreObserver mFullBackupRestoreObserverMock;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void sendStartRestore_observerIsNull_returnsNull() throws Exception {
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendStartRestore(null);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void sendStartRestore_callsObserver() throws Exception {
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendStartRestore(
+                mFullBackupRestoreObserverMock);
+
+        assertThat(result).isEqualTo(mFullBackupRestoreObserverMock);
+        verify(mFullBackupRestoreObserverMock).onStartRestore();
+    }
+
+    @Test
+    public void sendStartRestore_observerThrows_returnsNull() throws Exception {
+        doThrow(new RemoteException()).when(mFullBackupRestoreObserverMock).onStartRestore();
+
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendStartRestore(
+                mFullBackupRestoreObserverMock);
+
+        assertThat(result).isNull();
+        verify(mFullBackupRestoreObserverMock).onStartRestore();
+    }
+
+    @Test
+    public void sendOnRestorePackage_observerIsNull_returnsNull() throws Exception {
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendOnRestorePackage(
+                null, PACKAGE_NAME);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void sendOnRestorePackage_callsObserver() throws Exception {
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendOnRestorePackage(
+                mFullBackupRestoreObserverMock, PACKAGE_NAME);
+
+        assertThat(result).isEqualTo(mFullBackupRestoreObserverMock);
+        verify(mFullBackupRestoreObserverMock).onRestorePackage(PACKAGE_NAME);
+    }
+
+    @Test
+    public void sendOnRestorePackage_observerThrows_returnsNull() throws Exception {
+        doThrow(new RemoteException()).when(mFullBackupRestoreObserverMock).onRestorePackage(
+                PACKAGE_NAME);
+
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendOnRestorePackage(
+                mFullBackupRestoreObserverMock, PACKAGE_NAME);
+
+        assertThat(result).isNull();
+        verify(mFullBackupRestoreObserverMock).onRestorePackage(PACKAGE_NAME);
+    }
+
+    @Test
+    public void sendEndRestore_observerIsNull_returnsNull() throws Exception {
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendEndRestore(null);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void sendEndRestore_callsObserver() throws Exception {
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendEndRestore(
+                mFullBackupRestoreObserverMock);
+
+        assertThat(result).isEqualTo(mFullBackupRestoreObserverMock);
+        verify(mFullBackupRestoreObserverMock).onEndRestore();
+    }
+
+    @Test
+    public void sendEndRestore_observerThrows_returnsNull() throws Exception {
+        doThrow(new RemoteException()).when(mFullBackupRestoreObserverMock).onEndRestore();
+
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendEndRestore(
+                mFullBackupRestoreObserverMock);
+
+        assertThat(result).isNull();
+        verify(mFullBackupRestoreObserverMock).onEndRestore();
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupUtilsTest.java
new file mode 100644
index 0000000..4e3de64
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupUtilsTest.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.os.ParcelFileDescriptor;
+import android.platform.test.annotations.Presubmit;
+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.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Random;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class FullBackupUtilsTest {
+    @Mock private ParcelFileDescriptor mParcelFileDescriptorMock;
+    @Mock private OutputStream mOutputStreamMock;
+    private File mTemporaryFile;
+    private ByteArrayOutputStream mByteArrayOutputStream;
+    private ParcelFileDescriptor mTemporaryFileDescriptor;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mTemporaryFile = File.createTempFile("backup-data", ".txt");
+        mByteArrayOutputStream = new ByteArrayOutputStream();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mTemporaryFileDescriptor != null) {
+            mTemporaryFileDescriptor.close();
+        }
+        if (mTemporaryFile != null) {
+            mTemporaryFile.delete();
+        }
+    }
+
+    @Test
+    public void routeSocketDataToOutput_inPipeIsNull_throwsNPE() throws Exception {
+        try {
+            FullBackupUtils.routeSocketDataToOutput(null, mOutputStreamMock);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    @Test
+    public void routeSocketDataToOutput_outNull_throwsNPE() throws Exception {
+        try {
+            FullBackupUtils.routeSocketDataToOutput(mParcelFileDescriptorMock, null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    @Test
+    public void routeSocketDataToOutput_emptyInput_throwsEOFException() throws Exception {
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        try {
+            FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                    mOutputStreamMock);
+            fail();
+        } catch (EOFException expected) {
+        }
+
+        verifyZeroInteractions(mOutputStreamMock);
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_incompleteChunkSizeInput_throwsEOFException()
+            throws Exception {
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeByte(100);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        try {
+            FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                    mOutputStreamMock);
+            fail();
+        } catch (EOFException expected) {
+        }
+
+        verifyZeroInteractions(mOutputStreamMock);
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_validEmptyInput_doesNotWriteAnything() throws Exception {
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor, mOutputStreamMock);
+
+        verifyZeroInteractions(mOutputStreamMock);
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_notEnoughData_throwsEOFException() throws Exception {
+        byte[] data = createFakeDataArray(100);
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(data.length + 1);
+        outputStream.write(data);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        try {
+            FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                    mByteArrayOutputStream);
+            fail();
+        } catch (EOFException expected) {
+        }
+
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_oneSmallChunk_writesOutputCorrectly() throws Exception {
+        byte[] data = createFakeDataArray(100);
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(data.length);
+        outputStream.write(data);
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                mByteArrayOutputStream);
+
+        assertThat(mByteArrayOutputStream.toByteArray()).isEqualTo(data);
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_oneLargeChunk_writesOutputCorrectly() throws Exception {
+        byte[] data = createFakeDataArray(128000);
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(data.length);
+        outputStream.write(data);
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                mByteArrayOutputStream);
+
+        assertThat(mByteArrayOutputStream.toByteArray()).isEqualTo(data);
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_twoSmallChunks_writesOutputCorrectly() throws Exception {
+        byte[] data = createFakeDataArray(200);
+        int chunk1Length = 97;
+        int chunk2Length = data.length - chunk1Length;
+
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(chunk1Length);
+        outputStream.write(data, 0, chunk1Length);
+        outputStream.writeInt(chunk2Length);
+        outputStream.write(data, chunk1Length, chunk2Length);
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                mByteArrayOutputStream);
+
+        assertThat(mByteArrayOutputStream.toByteArray()).isEqualTo(data);
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_twoLargeChunks_writesOutputCorrectly() throws Exception {
+        byte[] data = createFakeDataArray(256000);
+        int chunk1Length = 127313;
+        int chunk2Length = data.length - chunk1Length;
+
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(chunk1Length);
+        outputStream.write(data, 0, chunk1Length);
+        outputStream.writeInt(chunk2Length);
+        outputStream.write(data, chunk1Length, chunk2Length);
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                mByteArrayOutputStream);
+
+        assertThat(mByteArrayOutputStream.toByteArray()).isEqualTo(data);
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    private static byte[] createFakeDataArray(int length) {
+        byte[] data = new byte[length];
+        new Random(3742).nextBytes(data);
+        return data;
+    }
+}
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
new file mode 100644
index 0000000..6b25d12
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
@@ -0,0 +1,533 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_ID;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_APK_NOT_INSTALLED;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_RESTORE_ANY_VERSION;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_SYSTEM_APP_NO_AGENT;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSIONS_MATCH;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
+import android.app.backup.IBackupManagerMonitor;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.Signature;
+import android.os.Bundle;
+import android.os.Process;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.frameworks.servicestests.R;
+import com.android.server.backup.FileMetadata;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.restore.PerformAdbRestoreTask;
+import com.android.server.backup.restore.RestorePolicy;
+import com.android.server.backup.testutils.PackageManagerStub;
+
+import com.google.common.hash.Hashing;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class TarBackupReaderTest {
+    private static final String TELEPHONY_PACKAGE_NAME = "com.android.providers.telephony";
+    private static final String TELEPHONY_PACKAGE_SIGNATURE_SHA256 =
+            "301aa3cb081134501c45f1422abc66c24224fd5ded5fdc8f17e697176fd866aa";
+    private static final int TELEPHONY_PACKAGE_VERSION = 25;
+    private static final String TEST_PACKAGE_NAME = "com.android.backup.testing";
+    private static final Signature FAKE_SIGNATURE_1 = new Signature("1234");
+    private static final Signature FAKE_SIGNATURE_2 = new Signature("5678");
+
+    @Mock private BytesReadListener mBytesReadListenerMock;
+    @Mock private IBackupManagerMonitor mBackupManagerMonitorMock;
+
+    private final PackageManagerStub mPackageManagerStub = new PackageManagerStub();
+    private Context mContext;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = InstrumentationRegistry.getContext();
+    }
+
+    @Test
+    public void readTarHeaders_backupEncrypted_correctlyParsesFileMetadata() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, "123");
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata fileMetadata = tarBackupReader.readTarHeaders();
+
+        assertThat(fileMetadata.packageName).isEqualTo(TELEPHONY_PACKAGE_NAME);
+        assertThat(fileMetadata.mode).isEqualTo(0600);
+        assertThat(fileMetadata.size).isEqualTo(2438);
+        assertThat(fileMetadata.domain).isEqualTo(null);
+        assertThat(fileMetadata.path).isEqualTo("_manifest");
+    }
+
+    @Test
+    public void readTarHeaders_backupNotEncrypted_correctlyParsesFileMetadata() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata fileMetadata = tarBackupReader.readTarHeaders();
+
+        assertThat(fileMetadata.packageName).isEqualTo(TELEPHONY_PACKAGE_NAME);
+        assertThat(fileMetadata.mode).isEqualTo(0600);
+        assertThat(fileMetadata.size).isEqualTo(2438);
+        assertThat(fileMetadata.domain).isEqualTo(null);
+        assertThat(fileMetadata.path).isEqualTo("_manifest");
+    }
+
+    @Test
+    public void readTarHeaders_backupNotEncrypted_correctlyReadsPaxHeader() throws Exception {
+        // Files with long names (>100 chars) will force backup to add PAX header.
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_file_with_long_name);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+
+        // Read manifest file.
+        FileMetadata fileMetadata = tarBackupReader.readTarHeaders();
+        Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(
+                fileMetadata);
+        RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
+                mPackageManagerStub, false /* allowApks */, fileMetadata, signatures);
+
+        assertThat(restorePolicy).isEqualTo(RestorePolicy.IGNORE);
+        assertThat(fileMetadata.packageName).isEqualTo(TEST_PACKAGE_NAME);
+        assertThat(fileMetadata.path).isEqualTo(
+                RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME);
+
+        tarBackupReader.skipTarPadding(fileMetadata.size);
+
+        // Read actual file (PAX header will only exist here).
+        fileMetadata = tarBackupReader.readTarHeaders();
+        signatures = tarBackupReader.readAppManifestAndReturnSignatures(
+                fileMetadata);
+        restorePolicy = tarBackupReader.chooseRestorePolicy(
+                mPackageManagerStub, false /* allowApks */, fileMetadata, signatures);
+
+        assertThat(restorePolicy).isEqualTo(RestorePolicy.IGNORE);
+        assertThat(fileMetadata.packageName).isEqualTo(TEST_PACKAGE_NAME);
+        char[] expectedFileNameChars = new char[200];
+        Arrays.fill(expectedFileNameChars, '1');
+        String expectedFileName = new String(expectedFileNameChars);
+        assertThat(fileMetadata.path).isEqualTo(expectedFileName);
+    }
+
+    @Test
+    public void readAppManifest_backupEncrypted_correctlyParsesAppManifest() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, "123");
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata fileMetadata = tarBackupReader.readTarHeaders();
+
+        Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(fileMetadata);
+
+        assertThat(fileMetadata.version).isEqualTo(TELEPHONY_PACKAGE_VERSION);
+        assertThat(fileMetadata.hasApk).isFalse();
+        assertThat(signatures).isNotNull();
+        assertThat(signatures).hasLength(1);
+
+        String signatureSha256 = Hashing.sha256().hashBytes(signatures[0].toByteArray()).toString();
+        assertThat(signatureSha256).isEqualTo(TELEPHONY_PACKAGE_SIGNATURE_SHA256);
+    }
+
+    @Test
+    public void readAppManifest_backupNotEncrypted_correctlyParsesAppManifest() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata fileMetadata = tarBackupReader.readTarHeaders();
+
+        Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(fileMetadata);
+
+        assertThat(fileMetadata.version).isEqualTo(TELEPHONY_PACKAGE_VERSION);
+        assertThat(fileMetadata.hasApk).isFalse();
+        assertThat(signatures).isNotNull();
+        assertThat(signatures).hasLength(1);
+
+        String signatureSha256 = Hashing.sha256().hashBytes(signatures[0].toByteArray()).toString();
+        assertThat(signatureSha256).isEqualTo(TELEPHONY_PACKAGE_SIGNATURE_SHA256);
+    }
+
+    @Test
+    public void chooseRestorePolicy_signaturesIsNull_returnsIgnore() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                true /* allowApks */, new FileMetadata(), null /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        verifyZeroInteractions(mBackupManagerMonitorMock);
+    }
+
+    @Test
+    public void chooseRestorePolicy_packageDoesNotExistAndAllowApksAndHasApk_returnsAcceptIfApk()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata info = new FileMetadata();
+        info.hasApk = true;
+        PackageManagerStub.sPackageInfo = null;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                true /* allowApks */, info, new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_APK_NOT_INSTALLED);
+    }
+
+    @Test
+    public void
+    chooseRestorePolicy_packageDoesNotExistAndAllowApksAndDoesNotHaveApk_returnsAcceptIfApkLogsCannotRestore()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata info = new FileMetadata();
+        info.hasApk = false;
+        PackageManagerStub.sPackageInfo = null;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                true /* allowApks */, info, new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock, times(2)).onEvent(bundleCaptor.capture());
+        List<Bundle> eventBundles = bundleCaptor.getAllValues();
+        assertThat(eventBundles).hasSize(2);
+        assertThat(eventBundles.get(0).get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_APK_NOT_INSTALLED);
+        assertThat(eventBundles.get(1).get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK);
+    }
+
+    @Test
+    public void chooseRestorePolicy_packageDoesNotExistAndDoesNotAllowApks_returnsIgnore()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        PackageManagerStub.sPackageInfo = null;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_APK_NOT_INSTALLED);
+    }
+
+    @Test
+    public void chooseRestorePolicy_doesNotAllowsBackup_returnsIgnore() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags = ~ApplicationInfo.FLAG_ALLOW_BACKUP;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE);
+    }
+
+    @Test
+    public void chooseRestorePolicy_systemAppWithNoAgent_returnsIgnore() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.uid = Process.SYSTEM_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_SYSTEM_APP_NO_AGENT);
+    }
+
+    @Test
+    public void chooseRestorePolicy_nonSystemAppSignaturesDoNotMatch_returnsIgnore()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_2};
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH);
+    }
+
+    @Test
+    public void chooseRestorePolicy_systemAppWithBackupAgentAndRestoreAnyVersion_returnsAccept()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |=
+                ApplicationInfo.FLAG_ALLOW_BACKUP | ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.SYSTEM_UID;
+        packageInfo.applicationInfo.backupAgentName = "backup.agent";
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_RESTORE_ANY_VERSION);
+    }
+
+    @Test
+    public void chooseRestorePolicy_restoreAnyVersion_returnsAccept() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |=
+                ApplicationInfo.FLAG_ALLOW_BACKUP | ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_RESTORE_ANY_VERSION);
+    }
+
+    @Test
+    public void chooseRestorePolicy_notRestoreAnyVersionButVersionMatch_returnsAccept()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+        FileMetadata info = new FileMetadata();
+        info.version = 1;
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        packageInfo.versionCode = 2;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, info, signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_VERSIONS_MATCH);
+    }
+
+    @Test
+    public void
+    chooseRestorePolicy_notRestoreAnyVersionAndVersionMismatchButAllowApksAndHasApk_returnsAcceptIfApk()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+        FileMetadata info = new FileMetadata();
+        info.version = 2;
+        info.hasApk = true;
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        packageInfo.versionCode = 1;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                true /* allowApks */, info, signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
+        verifyNoMoreInteractions(mBackupManagerMonitorMock);
+    }
+
+    @Test
+    public void
+    chooseRestorePolicy_notRestoreAnyVersionAndVersionMismatchAndDoesNotAllowApks_returnsIgnore()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+        FileMetadata info = new FileMetadata();
+        info.version = 2;
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        packageInfo.versionCode = 1;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, info, signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER);
+    }
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java b/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
index 07280bc..62b0ca8 100644
--- a/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
@@ -21,16 +21,22 @@
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.UserHandle;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.server.content.ContentService.ObserverCall;
 import com.android.server.content.ContentService.ObserverNode;
 
+/**
+ * bit FrameworksServicesTests:com.android.server.content.ObserverNodeTest
+ */
+@SmallTest
 public class ObserverNodeTest extends AndroidTestCase {
     static class TestObserver  extends ContentObserver {
         public TestObserver() {
-            super(new Handler());
+            super(new Handler(Looper.getMainLooper()));
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java b/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java
index be6861c..d093e79 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java
@@ -1,9 +1,32 @@
+/*
+ * 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.content;
 
 import android.os.Bundle;
+import android.test.suitebuilder.annotation.SmallTest;
 
 import junit.framework.TestCase;
 
+/**
+ * Tests for SyncManager.
+ *
+ * bit FrameworksServicesTests:com.android.server.content.SyncManagerTest
+ */
+@SmallTest
 public class SyncManagerTest extends TestCase {
 
     final String KEY_1 = "key_1";
@@ -61,4 +84,42 @@
         assertFalse("Extras considered equal when they are different.",
                 SyncManager.syncExtrasEquals(b1, b2, false /* don't care about system extras */));
     }
+
+    public void testFormatDurationHMS() {
+        checkFormatDurationHMS("0s", 0, 0, 0, 0);
+        checkFormatDurationHMS("1s", 0, 0, 0, 1);
+        checkFormatDurationHMS("9s", 0, 0, 0, 9);
+        checkFormatDurationHMS("10s", 0, 0, 0, 10);
+        checkFormatDurationHMS("59s", 0, 0, 0, 59);
+        checkFormatDurationHMS("1m00s", 0, 0, 1, 0);
+        checkFormatDurationHMS("1m01s", 0, 0, 1, 1);
+        checkFormatDurationHMS("1m09s", 0, 0, 1, 9);
+        checkFormatDurationHMS("1m10s", 0, 0, 1, 10);
+        checkFormatDurationHMS("1m59s", 0, 0, 1, 59);
+        checkFormatDurationHMS("1h00m00s", 0, 1, 0, 0);
+        checkFormatDurationHMS("1h00m01s", 0, 1, 0, 1);
+        checkFormatDurationHMS("1h01m01s", 0, 1, 1, 1);
+        checkFormatDurationHMS("1h09m10s", 0, 1, 9, 10);
+        checkFormatDurationHMS("1h10m59s", 0, 1, 10, 59);
+        checkFormatDurationHMS("1h59m00s", 0, 1, 59, 0);
+
+        checkFormatDurationHMS("1d00h00m00s", 1, 0, 0, 0);
+        checkFormatDurationHMS("1d00h00m00s", 1, 0, 0, 0);
+        checkFormatDurationHMS("1d01h00m00s", 1, 1, 0, 0);
+        checkFormatDurationHMS("1d09h00m00s", 1, 9, 0, 0);
+        checkFormatDurationHMS("1d10h00m00s", 1, 10, 0, 0);
+        checkFormatDurationHMS("1d23h00m00s", 1, 23, 0, 0);
+        checkFormatDurationHMS("123d01h00m00s", 123, 1, 0, 0);
+
+        final StringBuilder sb = new StringBuilder();
+        assertEquals("-1m01s", SyncManager.formatDurationHMS(sb, -61000L).toString());
+    }
+
+    private void checkFormatDurationHMS(String expected,
+            int d, int h, int m, int s) {
+        final long time = (d * 24 * 3600) + (h * 3600) + (m * 60) + s;
+
+        final StringBuilder sb = new StringBuilder();
+        assertEquals(expected, SyncManager.formatDurationHMS(sb, time * 1000).toString());
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java b/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
index e45b92a..deaa34c 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
@@ -17,24 +17,17 @@
 package com.android.server.content;
 
 import android.accounts.Account;
-import android.content.ContentResolver;
-import android.content.Context;
 import android.os.Bundle;
 import android.os.PersistableBundle;
-import android.os.SystemClock;
-import android.provider.Settings;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
 /**
- * You can run those tests with:
+ * Test for SyncOperation.
  *
- * adb shell am instrument
- * -e debug false
- * -w
- * -e class android.content.SyncOperationTest com.android.frameworks.coretests/android.test.InstrumentationTestRunner
+ * bit FrameworksServicesTests:com.android.server.content.SyncOperationTest
  */
-
+@SmallTest
 public class SyncOperationTest extends AndroidTestCase {
 
     Account mDummy;
diff --git a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
index 91c0de6..85de1f1 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
-import android.content.PeriodicSync;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.test.AndroidTestCase;
@@ -33,14 +32,18 @@
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.server.content.SyncStorageEngine.EndPoint;
-
 import com.android.internal.os.AtomicFile;
 
 import java.io.File;
 import java.io.FileOutputStream;
-import java.util.List;
 
+/**
+ * Test for SyncStorageEngine.
+ *
+ * bit FrameworksServicesTests:com.android.server.content.SyncStorageEngineTest
+ *
+ * TODO Broken.  Fix it.  b/62485315
+ */
 public class SyncStorageEngineTest extends AndroidTestCase {
 
     protected Account account1;
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java
index 3819914..175fdd8 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java
@@ -16,6 +16,7 @@
 package com.android.server.devicepolicy;
 
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
 /**
  * Test for {@link DevicePolicyConstants}.
@@ -29,6 +30,7 @@
 
  -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
  */
+@SmallTest
 public class DevicePolicyConstantsTest extends AndroidTestCase {
     private static final String TAG = "DevicePolicyConstantsTest";
 
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
index be1d07b..c5fb0bd 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
@@ -47,14 +47,14 @@
 
         mContext = getContext();
 
-        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
+        when(getServices().packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
                 .thenReturn(true);
     }
 
     public void testMigration() throws Exception {
-        final File user10dir = mMockContext.addUser(10, 0);
-        final File user11dir = mMockContext.addUser(11, UserInfo.FLAG_MANAGED_PROFILE);
-        mMockContext.addUser(12, 0);
+        final File user10dir = getServices().addUser(10, 0);
+        final File user11dir = getServices().addUser(11, UserInfo.FLAG_MANAGED_PROFILE);
+        getServices().addUser(12, 0);
 
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
         setUpPackageManagerForAdmin(admin2, UserHandle.getUid(10, 123));
@@ -62,12 +62,12 @@
 
         // Create the legacy owners & policies file.
         DpmTestUtils.writeToFile(
-                (new File(mContext.dataDir, OwnersTestable.LEGACY_FILE)).getAbsoluteFile(),
+                (new File(getServices().dataDir, OwnersTestable.LEGACY_FILE)).getAbsoluteFile(),
                 DpmTestUtils.readAsset(mRealTestContext,
                         "DevicePolicyManagerServiceMigrationTest/legacy_device_owner.xml"));
 
         DpmTestUtils.writeToFile(
-                (new File(mContext.systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
+                (new File(getServices().systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
                 DpmTestUtils.readAsset(mRealTestContext,
                         "DevicePolicyManagerServiceMigrationTest/legacy_device_policies.xml"));
 
@@ -81,12 +81,12 @@
                         "DevicePolicyManagerServiceMigrationTest/legacy_device_policies_11.xml"));
 
         // Set up UserManager
-        when(mMockContext.userManagerInternal.getBaseUserRestrictions(
+        when(getServices().userManagerInternal.getBaseUserRestrictions(
                 eq(UserHandle.USER_SYSTEM))).thenReturn(DpmTestUtils.newRestrictions(
                 UserManager.DISALLOW_ADD_USER,
                 UserManager.DISALLOW_RECORD_AUDIO));
 
-        when(mMockContext.userManagerInternal.getBaseUserRestrictions(
+        when(getServices().userManagerInternal.getBaseUserRestrictions(
                 eq(10))).thenReturn(DpmTestUtils.newRestrictions(
                 UserManager.DISALLOW_REMOVE_USER,
                 UserManager.DISALLOW_ADD_USER,
@@ -95,7 +95,7 @@
                 UserManager.DISALLOW_WALLPAPER,
                 UserManager.DISALLOW_RECORD_AUDIO));
 
-        when(mMockContext.userManagerInternal.getBaseUserRestrictions(
+        when(getServices().userManagerInternal.getBaseUserRestrictions(
                 eq(11))).thenReturn(DpmTestUtils.newRestrictions(
                 UserManager.DISALLOW_REMOVE_USER,
                 UserManager.DISALLOW_ADD_USER,
@@ -113,7 +113,7 @@
             newBaseRestrictions.put(userId, bundle);
 
             return null;
-        }).when(mContext.userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
+        }).when(getServices().userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
                 anyInt(), any(Bundle.class));
 
         // Initialize DPM/DPMS and let it migrate the persisted information.
@@ -125,7 +125,7 @@
         try {
             LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
 
-            dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
+            dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
 
             dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
             dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
@@ -200,17 +200,17 @@
 
         // Create the legacy owners & policies file.
         DpmTestUtils.writeToFile(
-                (new File(mContext.dataDir, OwnersTestable.LEGACY_FILE)).getAbsoluteFile(),
+                (new File(getServices().dataDir, OwnersTestable.LEGACY_FILE)).getAbsoluteFile(),
                 DpmTestUtils.readAsset(mRealTestContext,
                         "DevicePolicyManagerServiceMigrationTest2/legacy_device_owner.xml"));
 
         DpmTestUtils.writeToFile(
-                (new File(mContext.systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
+                (new File(getServices().systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
                 DpmTestUtils.readAsset(mRealTestContext,
                         "DevicePolicyManagerServiceMigrationTest2/legacy_device_policies.xml"));
 
         // Set up UserManager
-        when(mMockContext.userManagerInternal.getBaseUserRestrictions(
+        when(getServices().userManagerInternal.getBaseUserRestrictions(
                 eq(UserHandle.USER_SYSTEM))).thenReturn(DpmTestUtils.newRestrictions(
                 UserManager.DISALLOW_ADD_USER,
                 UserManager.DISALLOW_RECORD_AUDIO,
@@ -226,7 +226,7 @@
             newBaseRestrictions.put(userId, bundle);
 
             return null;
-        }).when(mContext.userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
+        }).when(getServices().userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
                 anyInt(), any(Bundle.class));
 
         // Initialize DPM/DPMS and let it migrate the persisted information.
@@ -238,7 +238,7 @@
         try {
             LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
 
-            dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
+            dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
 
             dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
             dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
@@ -273,18 +273,18 @@
     // Test setting default restrictions for managed profile.
     public void testMigration3_managedProfileOwner() throws Exception {
         // Create a managed profile user.
-        final File user10dir = mMockContext.addUser(10, UserInfo.FLAG_MANAGED_PROFILE);
+        final File user10dir = getServices().addUser(10, UserInfo.FLAG_MANAGED_PROFILE);
         // Profile owner package for managed profile user.
         setUpPackageManagerForAdmin(admin1, UserHandle.getUid(10, 123));
         // Set up fake UserManager to make it look like a managed profile.
-        when(mMockContext.userManager.isManagedProfile(eq(10))).thenReturn(true);
+        when(getServices().userManager.isManagedProfile(eq(10))).thenReturn(true);
         // Set up fake Settings to make it look like INSTALL_NON_MARKET_APPS was reversed.
-        when(mMockContext.settings.settingsSecureGetIntForUser(
+        when(getServices().settings.settingsSecureGetIntForUser(
                 eq(Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED),
                 eq(0), eq(10))).thenReturn(1);
         // Write policy and owners files.
         DpmTestUtils.writeToFile(
-                (new File(mContext.systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
+                (new File(getServices().systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
                 DpmTestUtils.readAsset(mRealTestContext,
                         "DevicePolicyManagerServiceMigrationTest3/system_device_policies.xml"));
         DpmTestUtils.writeToFile(
@@ -304,7 +304,7 @@
         try {
             LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
 
-            dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
+            dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
 
             dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
             dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index b870d94..5471715 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -61,11 +61,12 @@
         private final File mDeviceOwnerFile;
         private final File mUsersDataDir;
 
-        public OwnersTestable(DpmMockContext context) {
-            super(context.userManager, context.userManagerInternal, context.packageManagerInternal);
-            mLegacyFile = new File(context.dataDir, LEGACY_FILE);
-            mDeviceOwnerFile = new File(context.dataDir, DEVICE_OWNER_FILE);
-            mUsersDataDir = new File(context.dataDir, "users");
+        public OwnersTestable(MockSystemServices services) {
+            super(services.userManager, services.userManagerInternal,
+                    services.packageManagerInternal);
+            mLegacyFile = new File(services.dataDir, LEGACY_FILE);
+            mDeviceOwnerFile = new File(services.dataDir, DEVICE_OWNER_FILE);
+            mUsersDataDir = new File(services.dataDir, "users");
         }
 
         @Override
@@ -88,8 +89,8 @@
     public final DpmMockContext context;
     private final MockInjector mMockInjector;
 
-    public DevicePolicyManagerServiceTestable(DpmMockContext context, File dataDir) {
-        this(new MockInjector(context, dataDir));
+    public DevicePolicyManagerServiceTestable(MockSystemServices services, DpmMockContext context) {
+        this(new MockInjector(services, context));
     }
 
     private DevicePolicyManagerServiceTestable(MockInjector injector) {
@@ -100,15 +101,13 @@
 
 
     public void notifyChangeToContentObserver(Uri uri, int userHandle) {
-        ContentObserver co = mMockInjector.mContentObservers
-                .get(new Pair<Uri, Integer>(uri, userHandle));
+        ContentObserver co = mMockInjector.mContentObservers.get(new Pair<>(uri, userHandle));
         if (co != null) {
             co.onChange(false, uri, userHandle); // notify synchronously
         }
 
         // Notify USER_ALL observer too.
-        co = mMockInjector.mContentObservers
-                .get(new Pair<Uri, Integer>(uri, UserHandle.USER_ALL));
+        co = mMockInjector.mContentObservers.get(new Pair<>(uri, UserHandle.USER_ALL));
         if (co != null) {
             co.onChange(false, uri, userHandle); // notify synchronously
         }
@@ -118,76 +117,75 @@
     private static class MockInjector extends Injector {
 
         public final DpmMockContext context;
-
-        public final File dataDir;
+        private final MockSystemServices services;
 
         // Key is a pair of uri and userId
         private final Map<Pair<Uri, Integer>, ContentObserver> mContentObservers = new ArrayMap<>();
 
-        private MockInjector(DpmMockContext context, File dataDir) {
+        private MockInjector(MockSystemServices services, DpmMockContext context) {
             super(context);
+            this.services = services;
             this.context = context;
-            this.dataDir = dataDir;
         }
 
         @Override
         Owners newOwners() {
-            return new OwnersTestable(context);
+            return new OwnersTestable(services);
         }
 
         @Override
         UserManager getUserManager() {
-            return context.userManager;
+            return services.userManager;
         }
 
         @Override
         UserManagerInternal getUserManagerInternal() {
-            return context.userManagerInternal;
+            return services.userManagerInternal;
         }
 
         @Override
         PackageManagerInternal getPackageManagerInternal() {
-            return context.packageManagerInternal;
+            return services.packageManagerInternal;
         }
 
         @Override
         PowerManagerInternal getPowerManagerInternal() {
-            return context.powerManagerInternal;
+            return services.powerManagerInternal;
         }
 
         @Override
         NotificationManager getNotificationManager() {
-            return context.notificationManager;
+            return services.notificationManager;
         }
 
         @Override
         IIpConnectivityMetrics getIIpConnectivityMetrics() {
-            return context.iipConnectivityMetrics;
+            return services.iipConnectivityMetrics;
         }
 
         @Override
         IWindowManager getIWindowManager() {
-            return context.iwindowManager;
+            return services.iwindowManager;
         }
 
         @Override
         IActivityManager getIActivityManager() {
-            return context.iactivityManager;
+            return services.iactivityManager;
         }
 
         @Override
         IPackageManager getIPackageManager() {
-            return context.ipackageManager;
+            return services.ipackageManager;
         }
 
         @Override
         IBackupManager getIBackupManager() {
-            return context.ibackupManager;
+            return services.ibackupManager;
         }
 
         @Override
         IAudioService getIAudioService() {
-            return context.iaudioService;
+            return services.iaudioService;
         }
 
         @Override
@@ -197,32 +195,32 @@
 
         @Override
         LockPatternUtils newLockPatternUtils() {
-            return context.lockPatternUtils;
+            return services.lockPatternUtils;
         }
 
         @Override
         boolean storageManagerIsFileBasedEncryptionEnabled() {
-            return context.storageManager.isFileBasedEncryptionEnabled();
+            return services.storageManager.isFileBasedEncryptionEnabled();
         }
 
         @Override
         boolean storageManagerIsNonDefaultBlockEncrypted() {
-            return context.storageManager.isNonDefaultBlockEncrypted();
+            return services.storageManager.isNonDefaultBlockEncrypted();
         }
 
         @Override
         boolean storageManagerIsEncrypted() {
-            return context.storageManager.isEncrypted();
+            return services.storageManager.isEncrypted();
         }
 
         @Override
         boolean storageManagerIsEncryptable() {
-            return context.storageManager.isEncryptable();
+            return services.storageManager.isEncryptable();
         }
 
         @Override
         String getDevicePolicyFilePathForSystemUser() {
-            return context.systemUserDataDir.getAbsolutePath() + "/";
+            return services.systemUserDataDir.getAbsolutePath() + "/";
         }
 
         @Override
@@ -257,53 +255,53 @@
 
         @Override
         File environmentGetUserSystemDirectory(int userId) {
-            return context.environment.getUserSystemDirectory(userId);
+            return services.environment.getUserSystemDirectory(userId);
         }
 
         @Override
         void powerManagerGoToSleep(long time, int reason, int flags) {
-            context.powerManager.goToSleep(time, reason, flags);
+            services.powerManager.goToSleep(time, reason, flags);
         }
 
         @Override
         void powerManagerReboot(String reason) {
-            context.powerManager.reboot(reason);
+            services.powerManager.reboot(reason);
         }
 
         @Override
-        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force)
-                throws IOException {
-            context.recoverySystem.rebootWipeUserData(shutdown, reason, force);
+        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force,
+                boolean wipeEuicc) throws IOException {
+            services.recoverySystem.rebootWipeUserData(shutdown, reason, force, wipeEuicc);
         }
 
         @Override
         boolean systemPropertiesGetBoolean(String key, boolean def) {
-            return context.systemProperties.getBoolean(key, def);
+            return services.systemProperties.getBoolean(key, def);
         }
 
         @Override
         long systemPropertiesGetLong(String key, long def) {
-            return context.systemProperties.getLong(key, def);
+            return services.systemProperties.getLong(key, def);
         }
 
         @Override
         String systemPropertiesGet(String key, String def) {
-            return context.systemProperties.get(key, def);
+            return services.systemProperties.get(key, def);
         }
 
         @Override
         String systemPropertiesGet(String key) {
-            return context.systemProperties.get(key);
+            return services.systemProperties.get(key);
         }
 
         @Override
         void systemPropertiesSet(String key, String value) {
-            context.systemProperties.set(key, value);
+            services.systemProperties.set(key, value);
         }
 
         @Override
         boolean userManagerIsSplitSystemUser() {
-            return context.userManagerForMock.isSplitSystemUser();
+            return services.userManagerForMock.isSplitSystemUser();
         }
 
         @Override
@@ -320,87 +318,87 @@
 
         @Override
         int settingsSecureGetIntForUser(String name, int def, int userHandle) {
-            return context.settings.settingsSecureGetIntForUser(name, def, userHandle);
+            return services.settings.settingsSecureGetIntForUser(name, def, userHandle);
         }
 
         @Override
         String settingsSecureGetStringForUser(String name, int userHandle) {
-            return context.settings.settingsSecureGetStringForUser(name, userHandle);
+            return services.settings.settingsSecureGetStringForUser(name, userHandle);
         }
 
         @Override
         void settingsSecurePutIntForUser(String name, int value, int userHandle) {
-            context.settings.settingsSecurePutIntForUser(name, value, userHandle);
+            services.settings.settingsSecurePutIntForUser(name, value, userHandle);
         }
 
         @Override
         void settingsSecurePutStringForUser(String name, String value, int userHandle) {
-            context.settings.settingsSecurePutStringForUser(name, value, userHandle);
+            services.settings.settingsSecurePutStringForUser(name, value, userHandle);
         }
 
         @Override
         void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
-            context.settings.settingsGlobalPutStringForUser(name, value, userHandle);
+            services.settings.settingsGlobalPutStringForUser(name, value, userHandle);
         }
 
         @Override
         void settingsSecurePutInt(String name, int value) {
-            context.settings.settingsSecurePutInt(name, value);
+            services.settings.settingsSecurePutInt(name, value);
         }
 
         @Override
         void settingsGlobalPutInt(String name, int value) {
-            context.settings.settingsGlobalPutInt(name, value);
+            services.settings.settingsGlobalPutInt(name, value);
         }
 
         @Override
         void settingsSecurePutString(String name, String value) {
-            context.settings.settingsSecurePutString(name, value);
+            services.settings.settingsSecurePutString(name, value);
         }
 
         @Override
         void settingsGlobalPutString(String name, String value) {
-            context.settings.settingsGlobalPutString(name, value);
+            services.settings.settingsGlobalPutString(name, value);
         }
 
         @Override
         int settingsGlobalGetInt(String name, int def) {
-            return context.settings.settingsGlobalGetInt(name, def);
+            return services.settings.settingsGlobalGetInt(name, def);
         }
 
         @Override
         String settingsGlobalGetString(String name) {
-            return context.settings.settingsGlobalGetString(name);
+            return services.settings.settingsGlobalGetString(name);
         }
 
         @Override
         void securityLogSetLoggingEnabledProperty(boolean enabled) {
-            context.settings.securityLogSetLoggingEnabledProperty(enabled);
+            services.settings.securityLogSetLoggingEnabledProperty(enabled);
         }
 
         @Override
         boolean securityLogGetLoggingEnabledProperty() {
-            return context.settings.securityLogGetLoggingEnabledProperty();
+            return services.settings.securityLogGetLoggingEnabledProperty();
         }
 
         @Override
         boolean securityLogIsLoggingEnabled() {
-            return context.settings.securityLogIsLoggingEnabled();
+            return services.settings.securityLogIsLoggingEnabled();
         }
 
         @Override
         TelephonyManager getTelephonyManager() {
-            return context.telephonyManager;
+            return services.telephonyManager;
         }
 
         @Override
         boolean isBuildDebuggable() {
-            return context.buildMock.isDebuggable;
+            return services.buildMock.isDebuggable;
         }
 
         @Override
         KeyChain.KeyChainConnection keyChainBindAsUser(UserHandle user) {
-            return context.keyChainConnection;
+            return services.keyChainConnection;
         }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index c2b0ea5..fb98897 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -15,41 +15,61 @@
  */
 package com.android.server.devicepolicy;
 
+import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS;
+import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL;
+import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
 import static android.os.UserManagerInternal.CAMERA_DISABLED_GLOBALLY;
 import static android.os.UserManagerInternal.CAMERA_DISABLED_LOCALLY;
 import static android.os.UserManagerInternal.CAMERA_NOT_DISABLED;
 
+import static com.android.server.testutis.TestUtils.assertExpectException;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.nullable;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+import static org.mockito.hamcrest.MockitoHamcrest.argThat;
+
 import android.Manifest.permission;
 import android.app.Activity;
 import android.app.Notification;
-import android.app.NotificationManager;
 import android.app.admin.DeviceAdminReceiver;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManagerInternal;
+import android.app.admin.PasswordMetrics;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.ServiceConnection;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.StringParceledListSlice;
-import android.content.res.Resources;
-import android.graphics.Color;
-import android.net.IIpConnectivityMetrics;
-import android.net.Uri;
 import android.content.pm.UserInfo;
+import android.graphics.Color;
+import android.net.Uri;
 import android.net.wifi.WifiInfo;
 import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
-import android.os.IBinder;
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.UserManagerInternal;
 import android.provider.Settings;
-import android.security.IKeyChainService;
 import android.security.KeyChain;
 import android.telephony.TelephonyManager;
 import android.test.MoreAsserts;
@@ -77,30 +97,6 @@
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
-import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS;
-import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isNull;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.nullable;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-import static org.mockito.hamcrest.MockitoHamcrest.argThat;
-
 /**
  * Tests for DevicePolicyManager( and DevicePolicyManagerService).
  * You can run them via:
@@ -120,8 +116,15 @@
     private static final List<String> OWNER_SETUP_PERMISSIONS = Arrays.asList(
             permission.MANAGE_DEVICE_ADMINS, permission.MANAGE_PROFILE_AND_DEVICE_OWNERS,
             permission.MANAGE_USERS, permission.INTERACT_ACROSS_USERS_FULL);
+    public static final String NOT_DEVICE_OWNER_MSG = "does not own the device";
+    public static final String ONGOING_CALL_MSG = "ongoing call on the device";
 
+    // TODO replace all instances of this with explicit {@link #mServiceContext}.
+    @Deprecated
     private DpmMockContext mContext;
+
+    private DpmMockContext mServiceContext;
+    private DpmMockContext mAdmin1Context;
     public DevicePolicyManager dpm;
     public DevicePolicyManagerServiceTestable dpms;
 
@@ -158,11 +161,13 @@
         super.setUp();
 
         mContext = getContext();
-        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
+        mServiceContext = mContext;
+        mServiceContext.binder.callingUid = DpmMockContext.CALLER_UID;
+        when(getServices().packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
                 .thenReturn(true);
 
         // By default, pretend all users are running and unlocked.
-        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true);
+        when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(true);
 
         initializeDpms();
 
@@ -171,6 +176,11 @@
         setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_UID);
         setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID);
 
+        mAdmin1Context = new DpmMockContext(getServices(), mRealTestContext);
+        mAdmin1Context.packageName = admin1.getPackageName();
+        mAdmin1Context.applicationInfo = new ApplicationInfo();
+        mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_UID;
+
         setUpUserManager();
     }
 
@@ -183,18 +193,15 @@
     private void initializeDpms() {
         // Need clearCallingIdentity() to pass permission checks.
         final long ident = mContext.binder.clearCallingIdentity();
-        try {
-            LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
+        LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
 
-            dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
+        dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
+        dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
+        dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
 
-            dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
-            dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
+        dpm = new DevicePolicyManagerTestable(mContext, dpms);
 
-            dpm = new DevicePolicyManagerTestable(mContext, dpms);
-        } finally {
-            mContext.binder.restoreCallingIdentity(ident);
-        }
+        mContext.binder.restoreCallingIdentity(ident);
     }
 
     private void setUpUserManager() {
@@ -213,7 +220,7 @@
 
                 return null;
             }
-        }).when(mContext.userManager).setApplicationRestrictions(
+        }).when(getServices().userManager).setApplicationRestrictions(
                 anyString(), nullable(Bundle.class), any(UserHandle.class));
 
         // UM.getApplicationRestrictions() will read from appRestrictions.
@@ -225,33 +232,36 @@
 
                 return appRestrictions.get(Pair.create(pkg, user));
             }
-        }).when(mContext.userManager).getApplicationRestrictions(
+        }).when(getServices().userManager).getApplicationRestrictions(
                 anyString(), any(UserHandle.class));
 
         // Add the first secondary user.
-        mContext.addUser(DpmMockContext.CALLER_USER_HANDLE, 0);
+        getServices().addUser(DpmMockContext.CALLER_USER_HANDLE, 0);
     }
 
     private void setAsProfileOwner(ComponentName admin) {
-        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
-        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+        final long ident = mServiceContext.binder.clearCallingIdentity();
 
-        // PO needs to be an DA.
-        dpm.setActiveAdmin(admin, /* replace =*/ false);
+        mServiceContext.binder.callingUid =
+                UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID);
+        runAsCaller(mServiceContext, dpms, dpm -> {
+            // PO needs to be a DA.
+            dpm.setActiveAdmin(admin, /*replace=*/ false);
+            // Fire!
+            assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
+            // Check
+            assertEquals(admin, dpm.getProfileOwnerAsUser(DpmMockContext.CALLER_USER_HANDLE));
+        });
 
-        // Fire!
-        assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
-
-        // Check
-        assertEquals(admin, dpm.getProfileOwnerAsUser(DpmMockContext.CALLER_USER_HANDLE));
+        mServiceContext.binder.restoreCallingIdentity(ident);
     }
 
     public void testHasNoFeature() throws Exception {
-        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
+        when(getServices().packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
                 .thenReturn(false);
 
         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
-        new DevicePolicyManagerServiceTestable(mContext, dataDir);
+        new DevicePolicyManagerServiceTestable(getServices(), mContext);
 
         // If the device has no DPMS feature, it shouldn't register the local service.
         assertNull(LocalServices.getService(DevicePolicyManagerInternal.class));
@@ -264,19 +274,14 @@
         // 1. Failure cases.
 
         // Caller doesn't have MANAGE_DEVICE_ADMINS.
-        try {
-            dpm.setActiveAdmin(admin1, false);
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex= */ null,
+                () -> dpm.setActiveAdmin(admin1, false));
 
         // Caller has MANAGE_DEVICE_ADMINS, but for different user.
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
-        try {
-            dpm.setActiveAdmin(admin1, false, DpmMockContext.CALLER_USER_HANDLE + 1);
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+
+        assertExpectException(SecurityException.class, /* messageRegex= */ null,
+                () -> dpm.setActiveAdmin(admin1, false, DpmMockContext.CALLER_USER_HANDLE + 1));
     }
 
     /**
@@ -307,7 +312,7 @@
                         DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
                 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
 
-        verify(mContext.ipackageManager, times(1)).setApplicationEnabledSetting(
+        verify(getServices().ipackageManager, times(1)).setApplicationEnabledSetting(
                 eq(admin1.getPackageName()),
                 eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT),
                 eq(PackageManager.DONT_KILL_APP),
@@ -335,7 +340,7 @@
         // Next, add one more admin.
         // Before doing so, update the application info, now it's enabled.
         setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID,
-                PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+                PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
 
         dpm.setActiveAdmin(admin2, /* replace =*/ false);
 
@@ -346,7 +351,7 @@
 
         // Admin2 was already enabled, so setApplicationEnabledSetting() shouldn't have called
         // again.  (times(1) because it was previously called for admin1)
-        verify(mContext.ipackageManager, times(1)).setApplicationEnabledSetting(
+        verify(getServices().ipackageManager, times(1)).setApplicationEnabledSetting(
                 eq(admin1.getPackageName()),
                 eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT),
                 eq(PackageManager.DONT_KILL_APP),
@@ -354,11 +359,8 @@
                 anyString());
 
         // 4. Add the same admin1 again without replace, which should throw.
-        try {
-            dpm.setActiveAdmin(admin1, /* replace =*/ false);
-            fail("Didn't throw");
-        } catch (IllegalArgumentException expected) {
-        }
+        assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null,
+                () -> dpm.setActiveAdmin(admin1, /* replace =*/ false));
 
         // 5. Add the same admin1 again with replace, which should succeed.
         dpm.setActiveAdmin(admin1, /* replace =*/ true);
@@ -385,7 +387,7 @@
         final int ANOTHER_USER_ID = 100;
         final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 20456);
 
-        mMockContext.addUser(ANOTHER_USER_ID, 0); // Add one more user.
+        getServices().addUser(ANOTHER_USER_ID, 0); // Add one more user.
 
         // Set up pacakge manager for the other user.
         setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID);
@@ -420,11 +422,8 @@
         assertTrue(dpm.isAdminActive(admin1));
 
         // Add the same admin1 again without replace, which should throw.
-        try {
-            dpm.setActiveAdmin(admin1, /* replace =*/ false);
-            fail("Didn't throw");
-        } catch (IllegalArgumentException expected) {
-        }
+        assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null,
+                () -> dpm.setActiveAdmin(admin1, /* replace =*/ false));
     }
 
     /**
@@ -436,12 +435,9 @@
         // 1. Make sure the caller has proper permissions.
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
 
-        try {
-            dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false);
-            fail();
-        } catch (IllegalArgumentException expected) {
-            assertTrue(expected.getMessage().contains(permission.BIND_DEVICE_ADMIN));
-        }
+        assertExpectException(IllegalArgumentException.class,
+                /* messageRegex= */ permission.BIND_DEVICE_ADMIN,
+                () -> dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false));
         assertFalse(dpm.isAdminActive(adminNoPerm));
 
         // Change the target API level to MNC.  Now it can be set as DA.
@@ -470,11 +466,8 @@
         assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
 
         // Directly call the DPMS method with a different userid, which should fail.
-        try {
-            dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE + 1);
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE + 1));
 
         // Try to remove active admin with a different caller userid should fail too, without
         // having MANAGE_DEVICE_ADMINS.
@@ -483,11 +476,8 @@
         // Change the caller, and call into DPMS directly with a different user-id.
 
         mContext.binder.callingUid = 1234567;
-        try {
-            dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE);
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
     }
 
     /**
@@ -508,20 +498,16 @@
         assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
 
         // 1. User not unlocked.
-        when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
+        when(getServices().userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
                 .thenReturn(false);
-        try {
-            dpm.removeActiveAdmin(admin1);
-            fail("Didn't throw IllegalStateException");
-        } catch (IllegalStateException expected) {
-            MoreAsserts.assertContainsRegex(
-                    "User must be running and unlocked", expected.getMessage());
-        }
+        assertExpectException(IllegalStateException.class,
+                /* messageRegex= */ "User must be running and unlocked",
+                () -> dpm.removeActiveAdmin(admin1));
 
         assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
 
         // 2. User unlocked.
-        when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
+        when(getServices().userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
                 .thenReturn(true);
 
         dpm.removeActiveAdmin(admin1);
@@ -656,7 +642,7 @@
         // Setup device owner.
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
         mContext.packageName = admin1.getPackageName();
-        doReturn(true).when(mContext.lockPatternUtils)
+        doReturn(true).when(getServices().lockPatternUtils)
                 .isSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID);
         setupDeviceOwner();
 
@@ -687,13 +673,9 @@
         // Try to set a profile owner on the same user, which should fail.
         setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
         dpm.setActiveAdmin(admin2, /* refreshing= */ true, UserHandle.USER_SYSTEM);
-        try {
-            dpm.setProfileOwner(admin2, "owner-name", UserHandle.USER_SYSTEM);
-            fail("IllegalStateException not thrown");
-        } catch (IllegalStateException expected) {
-            assertTrue("Message was: " + expected.getMessage(),
-                    expected.getMessage().contains("already has a device owner"));
-        }
+        assertExpectException(IllegalStateException.class,
+                /* messageRegex= */ "already has a device owner",
+                () -> dpm.setProfileOwner(admin2, "owner-name", UserHandle.USER_SYSTEM));
 
         // DO admin can't be deactivated.
         dpm.removeActiveAdmin(admin1);
@@ -739,11 +721,11 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
 
         // Verify internal calls.
-        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
+        verify(getServices().iactivityManager, times(1)).updateDeviceOwner(
                 eq(admin1.getPackageName()));
 
         // TODO We should check if the caller has called clearCallerIdentity().
-        verify(mContext.ibackupManager, times(1)).setBackupServiceActive(
+        verify(getServices().ibackupManager, times(1)).setBackupServiceActive(
                 eq(UserHandle.USER_SYSTEM), eq(false));
 
         verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
@@ -850,26 +832,14 @@
             assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
         }
 
-        try {
-            dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName());
-            fail();
-        } catch (SecurityException expected) {
-        }
-        try {
-            dpm.getDeviceOwnerComponentOnAnyUser();
-            fail();
-        } catch (SecurityException expected) {
-        }
-        try {
-            dpm.getDeviceOwnerUserId();
-            fail();
-        } catch (SecurityException expected) {
-        }
-        try {
-            dpm.getDeviceOwnerNameOnAnyUser();
-            fail();
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                dpm::getDeviceOwnerComponentOnAnyUser);
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                dpm::getDeviceOwnerUserId);
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                dpm::getDeviceOwnerNameOnAnyUser);
 
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         // Still no MANAGE_USERS.
@@ -877,26 +847,14 @@
         assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
         assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
 
-        try {
-            dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName());
-            fail();
-        } catch (SecurityException expected) {
-        }
-        try {
-            dpm.getDeviceOwnerComponentOnAnyUser();
-            fail();
-        } catch (SecurityException expected) {
-        }
-        try {
-            dpm.getDeviceOwnerUserId();
-            fail();
-        } catch (SecurityException expected) {
-        }
-        try {
-            dpm.getDeviceOwnerNameOnAnyUser();
-            fail();
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                dpm::getDeviceOwnerComponentOnAnyUser);
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                dpm::getDeviceOwnerUserId);
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                dpm::getDeviceOwnerNameOnAnyUser);
 
         // Restore.
         mContext.binder.callingUid = origCallingUser;
@@ -916,13 +874,9 @@
         // Call from a process on the system user.
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
 
-        try {
-            dpm.setDeviceOwner(new ComponentName("a.b.c", ".def"));
-            fail("Didn't throw IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertTrue("Message was: " + expected.getMessage(),
-                    expected.getMessage().contains("Invalid component"));
-        }
+        assertExpectException(IllegalArgumentException.class,
+                /* messageRegex= */ "Invalid component",
+                () -> dpm.setDeviceOwner(new ComponentName("a.b.c", ".def")));
     }
 
     public void testSetDeviceOwner_failures() throws Exception {
@@ -948,48 +902,43 @@
         assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
 
         // Verify internal calls.
-        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
+        verify(getServices().iactivityManager, times(1)).updateDeviceOwner(
                 eq(admin1.getPackageName()));
 
         assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
-        when(mContext.userManager.hasUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
+        when(getServices().userManager.hasUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
                 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM))).thenReturn(true);
 
         assertTrue(dpm.isAdminActive(admin1));
         assertFalse(dpm.isRemovingAdmin(admin1, UserHandle.USER_SYSTEM));
 
         // Set up other mocks.
-        when(mContext.userManager.getUserRestrictions()).thenReturn(new Bundle());
+        when(getServices().userManager.getUserRestrictions()).thenReturn(new Bundle());
 
         // Now call clear.
-        doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(mContext.packageManager).getPackageUidAsUser(
-                eq(admin1.getPackageName()),
-                anyInt());
+        doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(getServices().packageManager).
+                getPackageUidAsUser(eq(admin1.getPackageName()), anyInt());
 
         // But first pretend the user is locked.  Then it should fail.
-        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(false);
-        try {
-            dpm.clearDeviceOwnerApp(admin1.getPackageName());
-            fail("Didn't throw IllegalStateException");
-        } catch (IllegalStateException expected) {
-            MoreAsserts.assertContainsRegex(
-                    "User must be running and unlocked", expected.getMessage());
-        }
+        when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(false);
+        assertExpectException(IllegalStateException.class,
+                /* messageRegex= */ "User must be running and unlocked",
+                () -> dpm.clearDeviceOwnerApp(admin1.getPackageName()));
 
-        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true);
-        reset(mContext.userManagerInternal);
+        when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(true);
+        reset(getServices().userManagerInternal);
         dpm.clearDeviceOwnerApp(admin1.getPackageName());
 
         // Now DO shouldn't be set.
         assertNull(dpm.getDeviceOwnerComponentOnAnyUser());
 
-        verify(mContext.userManager).setUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
+        verify(getServices().userManager).setUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
                 eq(false),
                 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
 
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 eq(null),
                 eq(true), eq(CAMERA_NOT_DISABLED));
@@ -1023,7 +972,7 @@
         assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
 
         // Verify internal calls.
-        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
+        verify(getServices().iactivityManager, times(1)).updateDeviceOwner(
                 eq(admin1.getPackageName()));
 
         assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
@@ -1032,15 +981,12 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
 
         // Now call clear.
-        doReturn(DpmMockContext.CALLER_UID).when(mContext.packageManager).getPackageUidAsUser(
+        doReturn(DpmMockContext.CALLER_UID).when(getServices().packageManager).getPackageUidAsUser(
                 eq(admin1.getPackageName()),
                 anyInt());
-        try {
-            dpm.clearDeviceOwnerApp(admin1.getPackageName());
-            fail("Didn't throw");
-        } catch (SecurityException e) {
-            assertEquals("clearDeviceOwner can only be called by the device owner", e.getMessage());
-        }
+        assertExpectException(SecurityException.class,
+                /* messageRegex =*/ "clearDeviceOwner can only be called by the device owner",
+                () -> dpm.clearDeviceOwnerApp(admin1.getPackageName()));
 
         // DO shouldn't be removed.
         assertTrue(dpm.isDeviceManaged());
@@ -1055,14 +1001,14 @@
 
         // Try setting DO on the same user, which should fail.
         setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
-        dpm.setActiveAdmin(admin2, /* refreshing= */ true, DpmMockContext.CALLER_USER_HANDLE);
-        try {
-            dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE);
-            fail("IllegalStateException not thrown");
-        } catch (IllegalStateException expected) {
-            assertTrue("Message was: " + expected.getMessage(),
-                    expected.getMessage().contains("already has a profile owner"));
-        }
+        mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+        runAsCaller(mServiceContext, dpms, dpm -> {
+            dpm.setActiveAdmin(admin2, /* refreshing= */ true, DpmMockContext.CALLER_USER_HANDLE);
+            assertExpectException(IllegalStateException.class,
+                    /* messageRegex= */ "already has a profile owner",
+                    () -> dpm.setDeviceOwner(admin2, "owner-name",
+                            DpmMockContext.CALLER_USER_HANDLE));
+        });
     }
 
     public void testClearProfileOwner() throws Exception {
@@ -1074,18 +1020,14 @@
         assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
 
         // First try when the user is locked, which should fail.
-        when(mContext.userManager.isUserUnlocked(anyInt()))
+        when(getServices().userManager.isUserUnlocked(anyInt()))
                 .thenReturn(false);
-        try {
-            dpm.clearProfileOwner(admin1);
-            fail("Didn't throw IllegalStateException");
-        } catch (IllegalStateException expected) {
-            MoreAsserts.assertContainsRegex(
-                    "User must be running and unlocked", expected.getMessage());
-        }
+        assertExpectException(IllegalStateException.class,
+                /* messageRegex= */ "User must be running and unlocked",
+                () -> dpm.clearProfileOwner(admin1));
+
         // Clear, really.
-        when(mContext.userManager.isUserUnlocked(anyInt()))
-                .thenReturn(true);
+        when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(true);
         dpm.clearProfileOwner(admin1);
 
         // Check
@@ -1109,7 +1051,7 @@
         final int ANOTHER_USER_ID = 100;
         final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 456);
 
-        mMockContext.addUser(ANOTHER_USER_ID, 0); // Add one more user.
+        getServices().addUser(ANOTHER_USER_ID, 0); // Add one more user.
 
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.MANAGE_USERS);
@@ -1118,7 +1060,7 @@
 
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
 
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
 
         // Make sure the admin packge is installed to each user.
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
@@ -1140,7 +1082,7 @@
         dpm.setActiveAdmin(admin2, /* replace =*/ false, ANOTHER_USER_ID);
 
         // Set DO on the first non-system user.
-        mContext.setUserRunning(DpmMockContext.CALLER_USER_HANDLE, true);
+        getServices().setUserRunning(DpmMockContext.CALLER_USER_HANDLE, true);
         assertTrue(dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
 
         assertEquals(admin2, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false));
@@ -1159,7 +1101,7 @@
      * finds the right component from a package name upon migration.
      */
     public void testDeviceOwnerMigration() throws Exception {
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         checkDeviceOwnerWithMultipleDeviceAdmins();
 
         // Overwrite the device owner setting and clears the clas name.
@@ -1172,7 +1114,7 @@
         assertEquals("", dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false).getClassName());
 
         // Then create a new DPMS to have it load the settings from files.
-        when(mContext.userManager.getUserRestrictions(any(UserHandle.class)))
+        when(getServices().userManager.getUserRestrictions(any(UserHandle.class)))
                 .thenReturn(new Bundle());
         initializeDpms();
 
@@ -1226,8 +1168,7 @@
      */
     private int setupPackageInPackageManager(final String packageName, final int appId)
             throws Exception {
-        return setupPackageInPackageManager(
-                packageName, DpmMockContext.CALLER_USER_HANDLE, appId,
+        return setupPackageInPackageManager(packageName, DpmMockContext.CALLER_USER_HANDLE, appId,
                 ApplicationInfo.FLAG_HAS_CODE);
     }
 
@@ -1240,31 +1181,29 @@
      * @param flags flags to set in the ApplicationInfo for this package
      * @return the UID of the package as known by the mock package manager
      */
-    private int setupPackageInPackageManager(
-            final String packageName, int userId, final int appId, int flags)
-            throws Exception {
-        // Make the PackageManager return the package instead of throwing a NameNotFoundException
+    private int setupPackageInPackageManager(final String packageName, int userId, final int appId,
+            int flags) throws Exception {
+        final int uid = UserHandle.getUid(userId, appId);
+        // Make the PackageManager return the package instead of throwing NameNotFoundException
         final PackageInfo pi = new PackageInfo();
         pi.applicationInfo = new ApplicationInfo();
         pi.applicationInfo.flags = flags;
-        doReturn(pi).when(mContext.ipackageManager).getPackageInfo(
+        doReturn(pi).when(getServices().ipackageManager).getPackageInfo(
                 eq(packageName),
                 anyInt(),
                 eq(userId));
-        doReturn(pi.applicationInfo).when(mContext.ipackageManager).getApplicationInfo(
+        doReturn(pi.applicationInfo).when(getServices().ipackageManager).getApplicationInfo(
                 eq(packageName),
                 anyInt(),
                 eq(userId));
-
         // Setup application UID with the PackageManager
-        final int uid = UserHandle.getUid(userId, appId);
-        doReturn(uid).when(mContext.packageManager).getPackageUidAsUser(
+        doReturn(uid).when(getServices().packageManager).getPackageUidAsUser(
                 eq(packageName),
                 eq(userId));
         // Associate packageName to uid
-        doReturn(packageName).when(mContext.ipackageManager).getNameForUid(eq(uid));
+        doReturn(packageName).when(getServices().ipackageManager).getNameForUid(eq(uid));
         doReturn(new String[]{packageName})
-            .when(mContext.ipackageManager).getPackagesForUid(eq(uid));
+                .when(getServices().ipackageManager).getPackagesForUid(eq(uid));
         return uid;
     }
 
@@ -1275,7 +1214,7 @@
         mContext.applicationInfo = new ApplicationInfo();
         mContext.callerPermissions.add(permission.MANAGE_USERS);
         mContext.packageName = "com.android.frameworks.servicestests";
-        mContext.addPackageContext(user, mContext);
+        getServices().addPackageContext(user, mContext);
         when(mContext.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE);
 
         StringParceledListSlice oneCert = asSlice(new String[] {"1"});
@@ -1285,20 +1224,20 @@
         doReturn(TEST_STRING).when(mContext.resources).getQuantityText(anyInt(), eq(2));
 
         // Given that we have exactly one certificate installed,
-        when(mContext.keyChainConnection.getService().getUserCaAliases()).thenReturn(oneCert);
+        when(getServices().keyChainConnection.getService().getUserCaAliases()).thenReturn(oneCert);
         // when that certificate is approved,
         dpms.approveCaCert(oneCert.getList().get(0), userId, true);
         // a notification should not be shown.
-        verify(mContext.notificationManager, timeout(1000))
+        verify(getServices().notificationManager, timeout(1000))
                 .cancelAsUser(anyString(), anyInt(), eq(user));
 
         // Given that we have four certificates installed,
-        when(mContext.keyChainConnection.getService().getUserCaAliases()).thenReturn(fourCerts);
+        when(getServices().keyChainConnection.getService().getUserCaAliases()).thenReturn(fourCerts);
         // when two of them are approved (one of them approved twice hence no action),
         dpms.approveCaCert(fourCerts.getList().get(0), userId, true);
         dpms.approveCaCert(fourCerts.getList().get(1), userId, true);
         // a notification should be shown saying that there are two certificates left to approve.
-        verify(mContext.notificationManager, timeout(1000))
+        verify(getServices().notificationManager, timeout(1000))
                 .notifyAsUser(anyString(), anyInt(), argThat(
                         new BaseMatcher<Notification>() {
                             @Override
@@ -1355,12 +1294,8 @@
         mContext.binder.callingUid = RESTRICTIONS_DELEGATE_UID;
         mContext.packageName = RESTRICTIONS_DELEGATE;
 
-        // DPMS throws a SecurityException
-        try {
-            dpm.installCaCert(null, null);
-            fail("Didn't throw SecurityException on unauthorized access");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.installCaCert(null, null));
 
         // On calling install certificate APIs from an authorized process
         mContext.binder.callingUid = CERT_DELEGATE_UID;
@@ -1382,11 +1317,8 @@
         // DPMS does not allow access to ex-delegate
         mContext.binder.callingUid = CERT_DELEGATE_UID;
         mContext.packageName = CERT_DELEGATE;
-        try {
-            dpm.installCaCert(null, null);
-            fail("Didn't throw SecurityException on unauthorized access");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.installCaCert(null, null));
 
         // But still allows access to other existing delegates
         mContext.binder.callingUid = RESTRICTIONS_DELEGATE_UID;
@@ -1403,6 +1335,8 @@
 
         final String nonExistAppRestrictionsManagerPackage = "com.google.app.restrictions.manager2";
         final String appRestrictionsManagerPackage = "com.google.app.restrictions.manager";
+        final String nonDelegateExceptionMessageRegex =
+                "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.";
         final int appRestrictionsManagerAppId = 20987;
         final int appRestrictionsManagerUid = setupPackageInPackageManager(
                 appRestrictionsManagerPackage, appRestrictionsManagerAppId);
@@ -1412,24 +1346,10 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         mContext.packageName = admin1.getPackageName();
         assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
-        Bundle rest = new Bundle();
+        final Bundle rest = new Bundle();
         rest.putString("KEY_STRING", "Foo1");
-        try {
-            dpm.setApplicationRestrictions(null, "pkg1", rest);
-            fail("Didn't throw expected SecurityException");
-        } catch (SecurityException expected) {
-            MoreAsserts.assertContainsRegex(
-                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
-                    expected.getMessage());
-        }
-        try {
-            dpm.getApplicationRestrictions(null, "pkg1");
-            fail("Didn't throw expected SecurityException");
-        } catch (SecurityException expected) {
-            MoreAsserts.assertContainsRegex(
-                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
-                    expected.getMessage());
-        }
+        assertExpectException(SecurityException.class, nonDelegateExceptionMessageRegex,
+                () -> dpm.setApplicationRestrictions(null, "pkg1", rest));
 
         // Check via the profile owner that no restrictions were set.
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
@@ -1437,14 +1357,10 @@
         assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size());
 
         // Check the API does not allow setting a non-existent package
-        try {
-            dpm.setApplicationRestrictionsManagingPackage(admin1,
-                    nonExistAppRestrictionsManagerPackage);
-            fail("Non-existent app set as app restriction manager.");
-        } catch (PackageManager.NameNotFoundException expected) {
-            MoreAsserts.assertContainsRegex(
-                    nonExistAppRestrictionsManagerPackage, expected.getMessage());
-        }
+        assertExpectException(PackageManager.NameNotFoundException.class,
+                /* messageRegex= */ nonExistAppRestrictionsManagerPackage,
+                () -> dpm.setApplicationRestrictionsManagingPackage(
+                        admin1, nonExistAppRestrictionsManagerPackage));
 
         // Let appRestrictionsManagerPackage manage app restrictions
         dpm.setApplicationRestrictionsManagingPackage(admin1, appRestrictionsManagerPackage);
@@ -1464,14 +1380,8 @@
         mContext.binder.callingUid = UserHandle.getUid(
                 UserHandle.USER_SYSTEM, appRestrictionsManagerAppId);
         assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
-        try {
-            dpm.setApplicationRestrictions(null, "pkg1", rest);
-            fail("Didn't throw expected SecurityException");
-        } catch (SecurityException expected) {
-            MoreAsserts.assertContainsRegex(
-                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
-                    expected.getMessage());
-        }
+        assertExpectException(SecurityException.class, nonDelegateExceptionMessageRegex,
+                () -> dpm.setApplicationRestrictions(null, "pkg1", rest));
 
         // The DPM is still able to manage app restrictions, even if it allowed another app to do it
         // too.
@@ -1487,14 +1397,8 @@
         mContext.binder.callingUid = appRestrictionsManagerUid;
         mContext.packageName = appRestrictionsManagerPackage;
         assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
-        try {
-            dpm.setApplicationRestrictions(null, "pkg1", null);
-            fail("Didn't throw expected SecurityException");
-        } catch (SecurityException expected) {
-            MoreAsserts.assertContainsRegex(
-                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
-                    expected.getMessage());
-        }
+        assertExpectException(SecurityException.class, nonDelegateExceptionMessageRegex,
+                () -> dpm.setApplicationRestrictions(null, "pkg1", null));
     }
 
     public void testSetUserRestriction_asDo() throws Exception {
@@ -1517,7 +1421,7 @@
                 UserHandle.USER_SYSTEM));
 
         // Check that the user restrictions that are enabled by default are set. Then unset them.
-        String[] defaultRestrictions = UserRestrictionsUtils
+        final String[] defaultRestrictions = UserRestrictionsUtils
                 .getDefaultEnabledForDeviceOwner().toArray(new String[0]);
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(defaultRestrictions),
@@ -1527,35 +1431,35 @@
                 DpmTestUtils.newRestrictions(defaultRestrictions),
                 dpm.getUserRestrictions(admin1)
         );
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(defaultRestrictions),
                 eq(true) /* isDeviceOwner */,
                 eq(CAMERA_NOT_DISABLED)
         );
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         for (String restriction : defaultRestrictions) {
             dpm.clearUserRestriction(admin1, restriction);
         }
 
         assertNoDeviceOwnerRestrictions();
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
                 eq(true), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS,
                         UserManager.DISALLOW_ADD_USER),
                 eq(true), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(
@@ -1569,11 +1473,11 @@
         );
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
                 eq(true), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
@@ -1585,71 +1489,71 @@
         );
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(),
                 eq(true), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         assertNoDeviceOwnerRestrictions();
 
         // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE are PO restrictions, but when
         // DO sets them, the scope is global.
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
                         UserManager.DISALLOW_UNMUTE_MICROPHONE),
                 eq(true), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         // More tests.
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
                 eq(true), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_FUN);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
                         UserManager.DISALLOW_ADD_USER),
                 eq(true), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         dpm.setCameraDisabled(admin1, true);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 // DISALLOW_CAMERA will be applied to both local and global.
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
                         UserManager.DISALLOW_ADD_USER),
                 eq(true), eq(CAMERA_DISABLED_GLOBALLY));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         // Set up another DA and let it disable camera.  Now DISALLOW_CAMERA will only be applied
         // locally.
         dpm.setCameraDisabled(admin1, false);
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
         dpm.setActiveAdmin(admin2, /* replace =*/ false, UserHandle.USER_SYSTEM);
         dpm.setCameraDisabled(admin2, true);
 
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 // DISALLOW_CAMERA will be applied to both local and global. <- TODO: fix this
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
                         UserManager.DISALLOW_ADD_USER),
                 eq(true), eq(CAMERA_DISABLED_LOCALLY));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
         // TODO Make sure restrictions are written to the file.
     }
 
@@ -1663,19 +1567,19 @@
         );
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES),
                 eq(false), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
                         UserManager.DISALLOW_OUTGOING_CALLS),
                 eq(false), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(
@@ -1694,11 +1598,11 @@
         );
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
                 eq(false), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(
@@ -1715,11 +1619,11 @@
         );
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(),
                 eq(false), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(),
@@ -1734,22 +1638,22 @@
         // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE can be set by PO too, even
         // though when DO sets them they'll be applied globally.
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
                         UserManager.DISALLOW_UNMUTE_MICROPHONE),
                 eq(false), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         dpm.setCameraDisabled(admin1, true);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
                         UserManager.DISALLOW_UNMUTE_MICROPHONE),
                 eq(false), eq(CAMERA_DISABLED_LOCALLY));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         // TODO Make sure restrictions are written to the file.
     }
@@ -1785,13 +1689,13 @@
                 DpmTestUtils.newRestrictions(defaultRestrictions),
                 dpm.getUserRestrictions(admin1)
         );
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(defaultRestrictions),
                 eq(true) /* isDeviceOwner */,
                 eq(CAMERA_NOT_DISABLED)
         );
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         for (String restriction : defaultRestrictions) {
             dpm.clearUserRestriction(admin1, restriction);
@@ -1800,7 +1704,7 @@
         assertNoDeviceOwnerRestrictions();
 
         // Initialize DPMS again and check that the user restriction wasn't enabled again.
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
         initializeDpms();
         assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
         assertNotNull(dpms.getDeviceOwnerAdminLocked());
@@ -1815,7 +1719,7 @@
         UserRestrictionsUtils
                 .getDefaultEnabledForDeviceOwner().add(newDefaultEnabledRestriction);
         try {
-            reset(mContext.userManagerInternal);
+            reset(getServices().userManagerInternal);
             initializeDpms();
             assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
             assertNotNull(dpms.getDeviceOwnerAdminLocked());
@@ -1828,13 +1732,13 @@
                 DpmTestUtils.newRestrictions(newDefaultEnabledRestriction),
                 dpm.getUserRestrictions(admin1)
             );
-            verify(mContext.userManagerInternal, atLeast(1)).setDevicePolicyUserRestrictions(
+            verify(getServices().userManagerInternal, atLeast(1)).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(newDefaultEnabledRestriction),
                 eq(true) /* isDeviceOwner */,
                 eq(CAMERA_NOT_DISABLED)
             );
-            reset(mContext.userManagerInternal);
+            reset(getServices().userManagerInternal);
 
             // Remove the restriction.
             dpm.clearUserRestriction(admin1, newDefaultEnabledRestriction);
@@ -1873,33 +1777,21 @@
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
 
         // Test 1. Caller doesn't have DO or DA.
-        try {
-            dpm.getWifiMacAddress(admin1);
-            fail();
-        } catch (SecurityException e) {
-            MoreAsserts.assertContainsRegex("No active admin", e.getMessage());
-        }
+        assertExpectException(SecurityException.class, /* messageRegex= */ "No active admin",
+                () -> dpm.getWifiMacAddress(admin1));
 
         // DO needs to be an DA.
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
         assertTrue(dpm.isAdminActive(admin1));
 
         // Test 2. Caller has DA, but not DO.
-        try {
-            dpm.getWifiMacAddress(admin1);
-            fail();
-        } catch (SecurityException e) {
-            MoreAsserts.assertContainsRegex("does not own the device", e.getMessage());
-        }
+        assertExpectException(SecurityException.class, /* messageRegex= */ NOT_DEVICE_OWNER_MSG,
+                () -> dpm.getWifiMacAddress(admin1));
 
         // Test 3. Caller has PO, but not DO.
         assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
-        try {
-            dpm.getWifiMacAddress(admin1);
-            fail();
-        } catch (SecurityException e) {
-            MoreAsserts.assertContainsRegex("does not own the device", e.getMessage());
-        }
+        assertExpectException(SecurityException.class, /* messageRegex= */ NOT_DEVICE_OWNER_MSG,
+                () -> dpm.getWifiMacAddress(admin1));
 
         // Remove PO.
         dpm.clearProfileOwner(admin1);
@@ -1911,13 +1803,13 @@
         assertNull(dpm.getWifiMacAddress(admin1));
 
         // 4-2.  Returns WifiInfo, but with the default MAC.
-        when(mContext.wifiManager.getConnectionInfo()).thenReturn(new WifiInfo());
+        when(getServices().wifiManager.getConnectionInfo()).thenReturn(new WifiInfo());
         assertNull(dpm.getWifiMacAddress(admin1));
 
         // 4-3. With a real MAC address.
         final WifiInfo wi = new WifiInfo();
         wi.setMacAddress("11:22:33:44:55:66");
-        when(mContext.wifiManager.getConnectionInfo()).thenReturn(wi);
+        when(getServices().wifiManager.getConnectionInfo()).thenReturn(wi);
         assertEquals("11:22:33:44:55:66", dpm.getWifiMacAddress(admin1));
     }
 
@@ -1934,21 +1826,13 @@
         // Set admin1 as DA.
         dpm.setActiveAdmin(admin1, false);
         assertTrue(dpm.isAdminActive(admin1));
-        try {
-            dpm.reboot(admin1);
-            fail("DA calls DPM.reboot(), did not throw expected SecurityException");
-        } catch (SecurityException expected) {
-            MoreAsserts.assertContainsRegex("does not own the device", expected.getMessage());
-        }
+        assertExpectException(SecurityException.class, /* messageRegex= */ NOT_DEVICE_OWNER_MSG,
+                () -> dpm.reboot(admin1));
 
         // Set admin1 as PO.
         assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
-        try {
-            dpm.reboot(admin1);
-            fail("PO calls DPM.reboot(), did not throw expected SecurityException");
-        } catch (SecurityException expected) {
-            MoreAsserts.assertContainsRegex("does not own the device", expected.getMessage());
-        }
+        assertExpectException(SecurityException.class, /* messageRegex= */ NOT_DEVICE_OWNER_MSG,
+                () -> dpm.reboot(admin1));
 
         // Remove PO and add DO.
         dpm.clearProfileOwner(admin1);
@@ -1957,27 +1841,19 @@
 
         // admin1 is DO.
         // Set current call state of device to ringing.
-        when(mContext.telephonyManager.getCallState())
+        when(getServices().telephonyManager.getCallState())
                 .thenReturn(TelephonyManager.CALL_STATE_RINGING);
-        try {
-            dpm.reboot(admin1);
-            fail("DPM.reboot() called when receiveing a call, should thrown IllegalStateException");
-        } catch (IllegalStateException expected) {
-            MoreAsserts.assertContainsRegex("ongoing call on the device", expected.getMessage());
-        }
+        assertExpectException(IllegalStateException.class, /* messageRegex= */ ONGOING_CALL_MSG,
+                () -> dpm.reboot(admin1));
 
         // Set current call state of device to dialing/active.
-        when(mContext.telephonyManager.getCallState())
+        when(getServices().telephonyManager.getCallState())
                 .thenReturn(TelephonyManager.CALL_STATE_OFFHOOK);
-        try {
-            dpm.reboot(admin1);
-            fail("DPM.reboot() called when dialing, should thrown IllegalStateException");
-        } catch (IllegalStateException expected) {
-            MoreAsserts.assertContainsRegex("ongoing call on the device", expected.getMessage());
-        }
+        assertExpectException(IllegalStateException.class, /* messageRegex= */ ONGOING_CALL_MSG,
+                () -> dpm.reboot(admin1));
 
         // Set current call state of device to idle.
-        when(mContext.telephonyManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_IDLE);
+        when(getServices().telephonyManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_IDLE);
         dpm.reboot(admin1);
     }
 
@@ -2001,31 +1877,20 @@
 
         // Only system can call the per user versions.
         {
-            try {
-                dpm.getShortSupportMessageForUser(admin1,
-                        DpmMockContext.CALLER_USER_HANDLE);
-                fail("Only system should be able to call getXXXForUser versions");
-            } catch (SecurityException expected) {
-                MoreAsserts.assertContainsRegex("message for user", expected.getMessage());
-            }
-            try {
-                dpm.getLongSupportMessageForUser(admin1,
-                        DpmMockContext.CALLER_USER_HANDLE);
-                fail("Only system should be able to call getXXXForUser versions");
-            } catch (SecurityException expected) {
-                MoreAsserts.assertContainsRegex("message for user", expected.getMessage());
-            }
+            assertExpectException(SecurityException.class, /* messageRegex= */ "message for user",
+                    () -> dpm.getShortSupportMessageForUser(admin1,
+                            DpmMockContext.CALLER_USER_HANDLE));
+            assertExpectException(SecurityException.class, /* messageRegex= */ "message for user",
+                    () -> dpm.getLongSupportMessageForUser(admin1,
+                        DpmMockContext.CALLER_USER_HANDLE));
         }
 
         // Can't set message for admin in another uid.
         {
             mContext.binder.callingUid = DpmMockContext.CALLER_UID + 1;
-            try {
-                dpm.setShortSupportMessage(admin1, "Some text");
-                fail("Admins should only be able to change their own support text.");
-            } catch (SecurityException expected) {
-                MoreAsserts.assertContainsRegex("is not owned by uid", expected.getMessage());
-            }
+            assertExpectException(SecurityException.class,
+                    /* messageRegex= */ "is not owned by uid",
+                    () -> dpm.setShortSupportMessage(admin1, "Some text"));
             mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         }
 
@@ -2086,7 +1951,7 @@
         assertNull(intent);
 
         // Existing permission that is not set by device/profile owner returns null
-        when(mContext.userManager.hasUserRestriction(
+        when(getServices().userManager.hasUserRestriction(
                 eq(UserManager.DISALLOW_ADJUST_VOLUME),
                 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
                 .thenReturn(true);
@@ -2094,7 +1959,7 @@
         assertNull(intent);
 
         // Permission that is set by device owner returns correct intent
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 eq(UserManager.DISALLOW_ADJUST_VOLUME),
                 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
@@ -2103,8 +1968,7 @@
         assertEquals(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS, intent.getAction());
         assertEquals(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID),
                 intent.getIntExtra(Intent.EXTRA_USER_ID, -1));
-        assertEquals(admin1,
-                (ComponentName) intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN));
+        assertEquals(admin1, intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN));
         assertEquals(UserManager.DISALLOW_ADJUST_VOLUME,
                 intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
 
@@ -2240,24 +2104,17 @@
 
     public void testSetUserProvisioningState_unprivileged() throws Exception {
         setupProfileOwner();
-        try {
-            dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
-                    DpmMockContext.CALLER_USER_HANDLE);
-            fail("Expected SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
+                        DpmMockContext.CALLER_USER_HANDLE));
     }
 
     public void testSetUserProvisioningState_noManagement() {
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
-        try {
-            dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
-                    DpmMockContext.CALLER_USER_HANDLE);
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException e) {
-            MoreAsserts.assertContainsRegex("change provisioning state unless a .* owner is set",
-                    e.getMessage());
-        }
+        assertExpectException(IllegalStateException.class,
+                /* messageRegex= */ "change provisioning state unless a .* owner is set",
+                () -> dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
+                        DpmMockContext.CALLER_USER_HANDLE));
         assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
     }
 
@@ -2323,15 +2180,11 @@
         setupProfileOwner();
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
 
-        try {
-            exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
-                    DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
-                    DevicePolicyManager.STATE_USER_UNMANAGED);
-            fail("Expected IllegalStateException");
-        } catch (IllegalStateException e) {
-            MoreAsserts.assertContainsRegex("Cannot move to user provisioning state",
-                    e.getMessage());
-        }
+        assertExpectException(IllegalStateException.class,
+                /* messageRegex= */ "Cannot move to user provisioning state",
+                () -> exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+                        DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
+                        DevicePolicyManager.STATE_USER_UNMANAGED));
     }
 
     public void testSetUserProvisioningState_illegalTransitionToAnotherInProgressState()
@@ -2339,15 +2192,11 @@
         setupProfileOwner();
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
 
-        try {
-            exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
-                    DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE,
-                    DevicePolicyManager.STATE_USER_SETUP_COMPLETE);
-            fail("Expected IllegalStateException");
-        } catch (IllegalStateException e) {
-            MoreAsserts.assertContainsRegex("Cannot move to user provisioning state",
-                    e.getMessage());
-        }
+        assertExpectException(IllegalStateException.class,
+                /* messageRegex= */ "Cannot move to user provisioning state",
+                () -> exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+                        DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE,
+                        DevicePolicyManager.STATE_USER_SETUP_COMPLETE));
     }
 
     private void exerciseUserProvisioningTransitions(int userId, int... states) {
@@ -2384,52 +2233,52 @@
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
         dpm.setActiveAdmin(admin2, /* replace =*/ false);
 
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin1, 0);
         verifyScreenTimeoutCall(null, false);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin1, 1);
         verifyScreenTimeoutCall(1, true);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin2, 10);
         verifyScreenTimeoutCall(null, false);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin1, 5);
         verifyScreenTimeoutCall(5, true);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin2, 4);
         verifyScreenTimeoutCall(4, true);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin1, 0);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin2, Integer.MAX_VALUE);
         verifyScreenTimeoutCall(Integer.MAX_VALUE, true);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin2, Integer.MAX_VALUE + 1);
         verifyScreenTimeoutCall(Integer.MAX_VALUE, true);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin2, 10);
         verifyScreenTimeoutCall(10, true);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         // There's no restriction; shold be set to MAX.
         dpm.setMaximumTimeToLock(admin2, 0);
@@ -2449,25 +2298,20 @@
 
         // verify that the minimum timeout cannot be modified on user builds (system property is
         // not being read)
-        mContext.buildMock.isDebuggable = false;
+        getServices().buildMock.isDebuggable = false;
 
         dpm.setRequiredStrongAuthTimeout(admin1, MAX_MINUS_ONE_MINUTE);
         assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MAX_MINUS_ONE_MINUTE);
         assertEquals(dpm.getRequiredStrongAuthTimeout(null), MAX_MINUS_ONE_MINUTE);
 
-        verify(mContext.systemProperties, never()).getLong(anyString(), anyLong());
+        verify(getServices().systemProperties, never()).getLong(anyString(), anyLong());
 
         // restore to the debuggable build state
-        mContext.buildMock.isDebuggable = true;
+        getServices().buildMock.isDebuggable = true;
 
         // Always return the default (second arg) when getting system property for long type
-        when(mContext.systemProperties.getLong(anyString(), anyLong())).thenAnswer(
-                new Answer<Long>() {
-                    @Override
-                    public Long answer(InvocationOnMock invocation) throws Throwable {
-                        return (Long) invocation.getArguments()[1];
-                    }
-                }
+        when(getServices().systemProperties.getLong(anyString(), anyLong())).thenAnswer(
+                invocation -> invocation.getArguments()[1]
         );
 
         // reset to default (0 means the admin is not participating, so default should be returned)
@@ -2515,20 +2359,17 @@
                 DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
 
         // negative value
-        try {
-            dpm.setRequiredStrongAuthTimeout(admin1, -ONE_MINUTE);
-            fail("Didn't throw IllegalArgumentException");
-        } catch (IllegalArgumentException iae) {
-        }
+        assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null,
+                () -> dpm.setRequiredStrongAuthTimeout(admin1, -ONE_MINUTE));
     }
 
     private void verifyScreenTimeoutCall(Integer expectedTimeout,
             boolean shouldStayOnWhilePluggedInBeCleared) {
         if (expectedTimeout == null) {
-            verify(mMockContext.powerManagerInternal, times(0))
+            verify(getServices().powerManagerInternal, times(0))
                     .setMaximumScreenOffTimeoutFromDeviceAdmin(anyInt());
         } else {
-            verify(mMockContext.powerManagerInternal, times(1))
+            verify(getServices().powerManagerInternal, times(1))
                     .setMaximumScreenOffTimeoutFromDeviceAdmin(eq(expectedTimeout));
         }
         // TODO Verify calls to settingsGlobalPutInt.  Tried but somehow mockito threw
@@ -2536,13 +2377,13 @@
     }
 
     private void setup_DeviceAdminFeatureOff() throws Exception {
-        when(mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN))
+        when(getServices().packageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN))
                 .thenReturn(false);
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(false);
         initializeDpms();
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(true);
         setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
 
@@ -2575,11 +2416,11 @@
     }
 
     private void setup_ManagedProfileFeatureOff() throws Exception {
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(false);
         initializeDpms();
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(true);
         setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
 
@@ -2597,7 +2438,7 @@
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false);
 
         // Test again when split user is on
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true);
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
@@ -2619,7 +2460,7 @@
                 DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED);
 
         // Test again when split user is on
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
                 DevicePolicyManager.CODE_OK);
         assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
@@ -2632,10 +2473,10 @@
     }
 
     private void setup_nonSplitUser_firstBoot_primaryUser() throws Exception {
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(true);
         setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
 
@@ -2670,10 +2511,10 @@
     }
 
     private void setup_nonSplitUser_afterDeviceSetup_primaryUser() throws Exception {
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(true);
         setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
 
@@ -2691,9 +2532,9 @@
         final int MANAGED_PROFILE_USER_ID = 18;
         final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 1308);
         addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
                 false /* we can't remove a managed profile */)).thenReturn(false);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
                 true)).thenReturn(true);
     }
 
@@ -2755,11 +2596,11 @@
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
         // The DO should be allowed to initiate provisioning if it set the restriction itself, but
         // other packages should be forbidden.
-        when(mContext.userManager.hasUserRestriction(
+        when(getServices().userManager.hasUserRestriction(
                 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
                 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
                 .thenReturn(true);
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
                 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
@@ -2781,11 +2622,11 @@
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
         // The DO should not be allowed to initiate provisioning if the restriction is set by
         // another entity.
-        when(mContext.userManager.hasUserRestriction(
+        when(getServices().userManager.hasUserRestriction(
                 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
                 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
                 .thenReturn(true);
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
                 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
@@ -2823,11 +2664,11 @@
         setup_nonSplitUser_withDo_primaryUser_ManagedProfile();
         mContext.packageName = admin1.getPackageName();
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
-        when(mContext.userManager.hasUserRestriction(
+        when(getServices().userManager.hasUserRestriction(
                 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE),
                 eq(UserHandle.SYSTEM)))
                 .thenReturn(true);
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE),
                 eq(UserHandle.SYSTEM)))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
@@ -2847,10 +2688,10 @@
     }
 
     private void setup_splitUser_firstBoot_systemUser() throws Exception {
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(false);
         setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
 
@@ -2886,10 +2727,10 @@
     }
 
     private void setup_splitUser_afterDeviceSetup_systemUser() throws Exception {
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(false);
         setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
 
@@ -2926,10 +2767,10 @@
     }
 
     private void setup_splitUser_firstBoot_primaryUser() throws Exception {
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
                 true)).thenReturn(true);
         setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
 
@@ -2963,10 +2804,10 @@
     }
 
     private void setup_splitUser_afterDeviceSetup_primaryUser() throws Exception {
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
                 true)).thenReturn(true);
         setUserSetupCompleteForUser(true, DpmMockContext.CALLER_USER_HANDLE);
 
@@ -3005,10 +2846,10 @@
     private void setup_provisionManagedProfileWithDeviceOwner_systemUser() throws Exception {
         setDeviceOwner();
 
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(false);
         setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
 
@@ -3035,10 +2876,10 @@
     private void setup_provisionManagedProfileWithDeviceOwner_primaryUser() throws Exception {
         setDeviceOwner();
 
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
                 true)).thenReturn(true);
         setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
 
@@ -3066,16 +2907,16 @@
     private void setup_provisionManagedProfileCantRemoveUser_primaryUser() throws Exception {
         setDeviceOwner();
 
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(mContext.userManager.hasUserRestriction(
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManager.hasUserRestriction(
                 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE),
                 eq(UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))))
                 .thenReturn(true);
-        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+        when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
                 false /* we can't remove a managed profile */)).thenReturn(false);
-        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+        when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
                 true)).thenReturn(true);
         setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
 
@@ -3100,32 +2941,23 @@
 
     public void testCheckProvisioningPreCondition_permission() {
         // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted
-        try {
-            dpm.checkProvisioningPreCondition(
-                    DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, "some.package");
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.checkProvisioningPreCondition(
+                        DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, "some.package"));
     }
 
     public void testForceUpdateUserSetupComplete_permission() {
         // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted
-        try {
-            dpm.forceUpdateUserSetupComplete();
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.forceUpdateUserSetupComplete());
     }
 
     public void testForceUpdateUserSetupComplete_systemUser() {
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
         // GIVEN calling from user 20
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
-        try {
-            dpm.forceUpdateUserSetupComplete();
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.forceUpdateUserSetupComplete());
     }
 
     public void testForceUpdateUserSetupComplete_userbuild() {
@@ -3143,7 +2975,7 @@
         dpms.mUserData.put(UserHandle.USER_SYSTEM, userData);
 
         // GIVEN it's user build
-        mContext.buildMock.isDebuggable = false;
+        getServices().buildMock.isDebuggable = false;
 
         assertTrue(dpms.hasUserSetupCompleted());
 
@@ -3168,7 +3000,7 @@
         dpms.mUserData.put(UserHandle.USER_SYSTEM, userData);
 
         // GIVEN it's userdebug build
-        mContext.buildMock.isDebuggable = true;
+        getServices().buildMock.isDebuggable = true;
 
         assertTrue(dpms.hasUserSetupCompleted());
 
@@ -3179,12 +3011,13 @@
     }
 
     private void clearDeviceOwner() throws Exception {
-        final long ident = mContext.binder.clearCallingIdentity();
-        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
-        doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(mContext.packageManager)
+        doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(getServices().packageManager)
                 .getPackageUidAsUser(eq(admin1.getPackageName()), anyInt());
-        dpm.clearDeviceOwnerApp(admin1.getPackageName());
-        mContext.binder.restoreCallingIdentity(ident);
+
+        mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        runAsCaller(mAdmin1Context, dpms, dpm -> {
+            dpm.clearDeviceOwnerApp(admin1.getPackageName());
+        });
     }
 
     public void testGetLastSecurityLogRetrievalTime() throws Exception {
@@ -3193,7 +3026,7 @@
 
         // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
         // feature is disabled because there are non-affiliated secondary users.
-        mContext.removeUser(DpmMockContext.CALLER_USER_HANDLE);
+        getServices().removeUser(DpmMockContext.CALLER_USER_HANDLE);
         when(mContext.resources.getBoolean(R.bool.config_supportPreRebootSecurityLogs))
                 .thenReturn(true);
 
@@ -3202,9 +3035,9 @@
 
         // Enabling logging should not change the timestamp.
         dpm.setSecurityLoggingEnabled(admin1, true);
-        verify(mContext.settings)
+        verify(getServices().settings)
                 .securityLogSetLoggingEnabledProperty(true);
-        when(mContext.settings.securityLogGetLoggingEnabledProperty())
+        when(getServices().settings.securityLogGetLoggingEnabledProperty())
                 .thenReturn(true);
         assertEquals(-1, dpm.getLastSecurityLogRetrievalTime());
 
@@ -3268,7 +3101,7 @@
 
         // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
         // feature is disabled because there are non-affiliated secondary users.
-        mContext.removeUser(DpmMockContext.CALLER_USER_HANDLE);
+        getServices().removeUser(DpmMockContext.CALLER_USER_HANDLE);
 
         // No bug reports were requested so far.
         assertEquals(-1, dpm.getLastBugReportRequestTime());
@@ -3316,8 +3149,8 @@
 
         // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
         // feature is disabled because there are non-affiliated secondary users.
-        mContext.removeUser(DpmMockContext.CALLER_USER_HANDLE);
-        when(mContext.iipConnectivityMetrics.registerNetdEventCallback(anyObject()))
+        getServices().removeUser(DpmMockContext.CALLER_USER_HANDLE);
+        when(getServices().iipConnectivityMetrics.addNetdEventCallback(anyInt(), anyObject()))
                 .thenReturn(true);
 
         // No logs were retrieved so far.
@@ -3388,7 +3221,7 @@
 
         // Add a secondary user, it should never talk with.
         final int ANOTHER_USER_ID = 36;
-        mContext.addUser(ANOTHER_USER_ID, 0);
+        getServices().addUser(ANOTHER_USER_ID, 0);
 
         // Since the managed profile is not affiliated, they should not be allowed to talk to each
         // other.
@@ -3469,7 +3302,7 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
         // Lock task packages are updated when loading user data.
-        verify(mContext.iactivityManager)
+        verify(getServices().iactivityManager)
                 .updateLockTaskPackages(eq(UserHandle.USER_SYSTEM), eq(new String[0]));
 
         // Set up a managed profile managed by different package (package name shouldn't matter)
@@ -3478,7 +3311,7 @@
         final ComponentName adminDifferentPackage =
                 new ComponentName("another.package", "whatever.class");
         addManagedProfile(adminDifferentPackage, MANAGED_PROFILE_ADMIN_UID, admin2);
-        verify(mContext.iactivityManager)
+        verify(getServices().iactivityManager)
                 .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(new String[0]));
 
         // The DO can still set lock task packages
@@ -3488,22 +3321,16 @@
         MoreAsserts.assertEquals(doPackages, dpm.getLockTaskPackages(admin1));
         assertTrue(dpm.isLockTaskPermitted("doPackage1"));
         assertFalse(dpm.isLockTaskPermitted("anotherPackage"));
-        verify(mContext.iactivityManager)
+        verify(getServices().iactivityManager)
                 .updateLockTaskPackages(eq(UserHandle.USER_SYSTEM), eq(doPackages));
 
         // Managed profile is unaffiliated - shouldn't be able to setLockTaskPackages.
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
         final String[] poPackages = {"poPackage1", "poPackage2"};
-        try {
-            dpm.setLockTaskPackages(adminDifferentPackage, poPackages);
-            fail("Didn't throw expected security exception.");
-        } catch (SecurityException expected) {
-        }
-        try {
-            dpm.getLockTaskPackages(adminDifferentPackage);
-            fail("Didn't throw expected security exception.");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.setLockTaskPackages(adminDifferentPackage, poPackages));
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.getLockTaskPackages(adminDifferentPackage));
         assertFalse(dpm.isLockTaskPermitted("doPackage1"));
 
         // Setting same affiliation ids
@@ -3519,14 +3346,14 @@
         MoreAsserts.assertEquals(poPackages, dpm.getLockTaskPackages(adminDifferentPackage));
         assertTrue(dpm.isLockTaskPermitted("poPackage1"));
         assertFalse(dpm.isLockTaskPermitted("doPackage2"));
-        verify(mContext.iactivityManager)
+        verify(getServices().iactivityManager)
                 .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(poPackages));
 
         // Unaffiliate the profile, lock task mode no longer available on the profile.
         dpm.setAffiliationIds(adminDifferentPackage, Collections.emptySet());
         assertFalse(dpm.isLockTaskPermitted("poPackage1"));
         // Lock task packages cleared when loading user data and when the user becomes unaffiliated.
-        verify(mContext.iactivityManager, times(2))
+        verify(getServices().iactivityManager, times(2))
                 .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(new String[0]));
 
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
@@ -3590,11 +3417,11 @@
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
 
         // Even if the caller is the managed profile, the current user is the user 0
-        when(mContext.iactivityManager.getCurrentUser())
+        when(getServices().iactivityManager.getCurrentUser())
                 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
 
         dpm.wipeData(0);
-        verify(mContext.userManagerInternal).removeUserEvenWhenDisallowed(
+        verify(getServices().userManagerInternal).removeUserEvenWhenDisallowed(
                 MANAGED_PROFILE_USER_ID);
     }
 
@@ -3604,48 +3431,56 @@
         addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
 
         // Even if the caller is the managed profile, the current user is the user 0
-        when(mContext.iactivityManager.getCurrentUser())
+        when(getServices().iactivityManager.getCurrentUser())
                 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
 
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
                 UserHandle.of(MANAGED_PROFILE_USER_ID)))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
-        try {
-            // The PO is not allowed to remove the profile if the user restriction was set on the
-            // profile by the system
-            dpm.wipeData(0);
-            fail("SecurityException not thrown");
-        } catch (SecurityException expected) {
-        }
+        // The PO is not allowed to remove the profile if the user restriction was set on the
+        // profile by the system
+        assertExpectException(SecurityException.class, /* messageRegex= */ null,
+                () -> dpm.wipeData(0));
     }
 
     public void testWipeDataDeviceOwner() throws Exception {
         setDeviceOwner();
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 UserManager.DISALLOW_FACTORY_RESET,
                 UserHandle.SYSTEM))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
 
         dpm.wipeData(0);
-        verify(mContext.recoverySystem).rebootWipeUserData(
-                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true));
+        verify(getServices().recoverySystem).rebootWipeUserData(
+                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true),
+                /*wipeEuicc=*/ eq(false));
+    }
+
+    public void testWipeEuiccDataEnabled() throws Exception {
+        setDeviceOwner();
+        when(getServices().userManager.getUserRestrictionSource(
+            UserManager.DISALLOW_FACTORY_RESET,
+            UserHandle.SYSTEM))
+            .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
+
+        dpm.wipeData(WIPE_EUICC);
+        verify(getServices().recoverySystem).rebootWipeUserData(
+                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true),
+                /*wipeEuicc=*/ eq(true));
     }
 
     public void testWipeDataDeviceOwnerDisallowed() throws Exception {
         setDeviceOwner();
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 UserManager.DISALLOW_FACTORY_RESET,
                 UserHandle.SYSTEM))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
-        try {
-            // The DO is not allowed to wipe the device if the user restriction was set
-            // by the system
-            dpm.wipeData(0);
-            fail("SecurityException not thrown");
-        } catch (SecurityException expected) {
-        }
+        // The DO is not allowed to wipe the device if the user restriction was set
+        // by the system
+        assertExpectException(SecurityException.class, /* messageRegex= */ null,
+                () -> dpm.wipeData(0));
     }
 
     public void testMaximumFailedPasswordAttemptsReachedManagedProfile() throws Exception {
@@ -3654,10 +3489,10 @@
         addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
 
         // Even if the caller is the managed profile, the current user is the user 0
-        when(mContext.iactivityManager.getCurrentUser())
+        when(getServices().iactivityManager.getCurrentUser())
                 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
 
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
                 UserHandle.of(MANAGED_PROFILE_USER_ID)))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
@@ -3675,9 +3510,9 @@
 
         // The profile should be wiped even if DISALLOW_REMOVE_MANAGED_PROFILE is enabled, because
         // both the user restriction and the policy were set by the PO.
-        verify(mContext.userManagerInternal).removeUserEvenWhenDisallowed(
+        verify(getServices().userManagerInternal).removeUserEvenWhenDisallowed(
                 MANAGED_PROFILE_USER_ID);
-        verifyZeroInteractions(mContext.recoverySystem);
+        verifyZeroInteractions(getServices().recoverySystem);
     }
 
     public void testMaximumFailedPasswordAttemptsReachedManagedProfileDisallowed()
@@ -3687,10 +3522,10 @@
         addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
 
         // Even if the caller is the managed profile, the current user is the user 0
-        when(mContext.iactivityManager.getCurrentUser())
+        when(getServices().iactivityManager.getCurrentUser())
                 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
 
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
                 UserHandle.of(MANAGED_PROFILE_USER_ID)))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
@@ -3708,14 +3543,14 @@
 
         // DISALLOW_REMOVE_MANAGED_PROFILE was set by the system, not the PO, so the profile is
         // not wiped.
-        verify(mContext.userManagerInternal, never())
+        verify(getServices().userManagerInternal, never())
                 .removeUserEvenWhenDisallowed(anyInt());
-        verifyZeroInteractions(mContext.recoverySystem);
+        verifyZeroInteractions(getServices().recoverySystem);
     }
 
     public void testMaximumFailedPasswordAttemptsReachedDeviceOwner() throws Exception {
         setDeviceOwner();
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 UserManager.DISALLOW_FACTORY_RESET,
                 UserHandle.SYSTEM))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
@@ -3730,13 +3565,14 @@
 
         // The device should be wiped even if DISALLOW_FACTORY_RESET is enabled, because both the
         // user restriction and the policy were set by the DO.
-        verify(mContext.recoverySystem).rebootWipeUserData(
-                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true));
+        verify(getServices().recoverySystem).rebootWipeUserData(
+                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true),
+                /*wipeEuicc=*/ eq(false));
     }
 
     public void testMaximumFailedPasswordAttemptsReachedDeviceOwnerDisallowed() throws Exception {
         setDeviceOwner();
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 UserManager.DISALLOW_FACTORY_RESET,
                 UserHandle.SYSTEM))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
@@ -3750,8 +3586,8 @@
         dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
 
         // DISALLOW_FACTORY_RESET was set by the system, not the DO, so the device is not wiped.
-        verifyZeroInteractions(mContext.recoverySystem);
-        verify(mContext.userManagerInternal, never())
+        verifyZeroInteractions(getServices().recoverySystem);
+        verify(getServices().userManagerInternal, never())
                 .removeUserEvenWhenDisallowed(anyInt());
     }
 
@@ -3760,18 +3596,18 @@
         final String app1 = "com.example.app1";
         final String app2 = "com.example.app2";
 
-        when(mContext.ipackageManager.checkPermission(eq(permission), eq(app1), anyInt()))
+        when(getServices().ipackageManager.checkPermission(eq(permission), eq(app1), anyInt()))
                 .thenReturn(PackageManager.PERMISSION_GRANTED);
-        doReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED).when(mContext.packageManager)
+        doReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED).when(getServices().packageManager)
                 .getPermissionFlags(permission, app1, UserHandle.SYSTEM);
-        when(mContext.packageManager.getPermissionFlags(permission, app1,
+        when(getServices().packageManager.getPermissionFlags(permission, app1,
                 UserHandle.of(DpmMockContext.CALLER_USER_HANDLE)))
                 .thenReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED);
-        when(mContext.ipackageManager.checkPermission(eq(permission), eq(app2), anyInt()))
+        when(getServices().ipackageManager.checkPermission(eq(permission), eq(app2), anyInt()))
                 .thenReturn(PackageManager.PERMISSION_DENIED);
-        doReturn(0).when(mContext.packageManager).getPermissionFlags(permission, app2,
+        doReturn(0).when(getServices().packageManager).getPermissionFlags(permission, app2,
                 UserHandle.SYSTEM);
-        when(mContext.packageManager.getPermissionFlags(permission, app2,
+        when(getServices().packageManager.getPermissionFlags(permission, app2,
                 UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))).thenReturn(0);
 
         // System can retrieve permission grant state.
@@ -3785,11 +3621,8 @@
         // A regular app cannot retrieve permission grant state.
         mContext.binder.callingUid = setupPackageInPackageManager(app1, 1);
         mContext.packageName = app1;
-        try {
-            dpm.getPermissionGrantState(null, app1, permission);
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex= */ null,
+                () -> dpm.getPermissionGrantState(null, app1, permission));
 
         // Profile owner can retrieve permission grant state.
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
@@ -3805,37 +3638,113 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
         // test token validation
-        try {
-            dpm.setResetPasswordToken(admin1, new byte[31]);
-            fail("should not have accepted tokens too short");
-        } catch (IllegalArgumentException expected) {
-        }
+        assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null,
+                () -> dpm.setResetPasswordToken(admin1, new byte[31]));
+
         // test adding a token
         final byte[] token = new byte[32];
         final long handle = 123456;
         final String password = "password";
-        when(mContext.lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM)))
+        when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM)))
             .thenReturn(handle);
         assertTrue(dpm.setResetPasswordToken(admin1, token));
 
         // test password activation
-        when(mContext.lockPatternUtils.isEscrowTokenActive(eq(handle), eq(UserHandle.USER_SYSTEM)))
+        when(getServices().lockPatternUtils.isEscrowTokenActive(eq(handle), eq(UserHandle.USER_SYSTEM)))
             .thenReturn(true);
         assertTrue(dpm.isResetPasswordTokenActive(admin1));
 
         // test reset password with token
-        when(mContext.lockPatternUtils.setLockCredentialWithToken(eq(password),
+        when(getServices().lockPatternUtils.setLockCredentialWithToken(eq(password),
                 eq(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), eq(handle), eq(token),
                 eq(UserHandle.USER_SYSTEM)))
                 .thenReturn(true);
         assertTrue(dpm.resetPasswordWithToken(admin1, password, token, 0));
 
         // test removing a token
-        when(mContext.lockPatternUtils.removeEscrowToken(eq(handle), eq(UserHandle.USER_SYSTEM)))
+        when(getServices().lockPatternUtils.removeEscrowToken(eq(handle), eq(UserHandle.USER_SYSTEM)))
                 .thenReturn(true);
         assertTrue(dpm.clearResetPasswordToken(admin1));
     }
 
+    public void testIsActivePasswordSufficient() throws Exception {
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        mContext.packageName = admin1.getPackageName();
+        setupDeviceOwner();
+
+        dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_COMPLEX);
+        dpm.setPasswordMinimumLength(admin1, 8);
+        dpm.setPasswordMinimumLetters(admin1, 6);
+        dpm.setPasswordMinimumLowerCase(admin1, 3);
+        dpm.setPasswordMinimumUpperCase(admin1, 1);
+        dpm.setPasswordMinimumNonLetter(admin1, 1);
+        dpm.setPasswordMinimumNumeric(admin1, 1);
+        dpm.setPasswordMinimumSymbols(admin1, 0);
+
+        PasswordMetrics passwordMetricsNoSymbols = new PasswordMetrics(
+                DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, 9,
+                8, 2,
+                6, 1,
+                0, 1);
+
+        setActivePasswordState(passwordMetricsNoSymbols);
+        assertTrue(dpm.isActivePasswordSufficient());
+
+        initializeDpms();
+        reset(mContext.spiedContext);
+        assertTrue(dpm.isActivePasswordSufficient());
+
+        // This call simulates the user entering the password for the first time after a reboot.
+        // This causes password metrics to be reloaded into memory.  Until this happens,
+        // dpm.isActivePasswordSufficient() will continue to return its last checkpointed value,
+        // even if the DPC changes password requirements so that the password no longer meets the
+        // requirements.  This is a known limitation of the current implementation of
+        // isActivePasswordSufficient() - see b/34218769.
+        setActivePasswordState(passwordMetricsNoSymbols);
+        assertTrue(dpm.isActivePasswordSufficient());
+
+        dpm.setPasswordMinimumSymbols(admin1, 1);
+        // This assertion would fail if we had not called setActivePasswordState() again after
+        // initializeDpms() - see previous comment.
+        assertFalse(dpm.isActivePasswordSufficient());
+
+        initializeDpms();
+        reset(mContext.spiedContext);
+        assertFalse(dpm.isActivePasswordSufficient());
+
+        PasswordMetrics passwordMetricsWithSymbols = new PasswordMetrics(
+                DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, 9,
+                7, 2,
+                5, 1,
+                1, 2);
+
+        setActivePasswordState(passwordMetricsWithSymbols);
+        assertTrue(dpm.isActivePasswordSufficient());
+    }
+
+    private void setActivePasswordState(PasswordMetrics passwordMetrics)
+            throws Exception {
+        final int userHandle = UserHandle.getUserId(mContext.binder.callingUid);
+        final long ident = mContext.binder.clearCallingIdentity();
+
+        dpm.setActivePasswordState(passwordMetrics, userHandle);
+        dpm.reportPasswordChanged(userHandle);
+
+        final Intent intent = new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED);
+        intent.setComponent(admin1);
+        intent.putExtra(Intent.EXTRA_USER, UserHandle.of(mContext.binder.callingUid));
+
+        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
+                MockUtils.checkIntent(intent),
+                MockUtils.checkUserHandle(userHandle));
+
+        // CertificateMonitor.updateInstalledCertificates is called on the background thread,
+        // let it finish with system uid, otherwise it will throw and crash.
+        flushTasks();
+
+        mContext.binder.restoreCallingIdentity(ident);
+    }
+
     public void testIsCurrentInputMethodSetByOwnerForDeviceOwner() throws Exception {
         final String currentIme = Settings.Secure.DEFAULT_INPUT_METHOD;
         final Uri currentImeUri = Settings.Secure.getUriFor(currentIme);
@@ -3857,12 +3766,12 @@
 
         // Device owner changes IME for first user.
         mContext.binder.callingUid = deviceOwnerUid;
-        when(mContext.settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM))
+        when(getServices().settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM))
                 .thenReturn("ime1");
         dpm.setSecureSetting(admin1, currentIme, "ime2");
-        verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime2",
+        verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime2",
                 UserHandle.USER_SYSTEM);
-        reset(mContext.settings);
+        reset(getServices().settings);
         dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM);
         mContext.binder.callingUid = firstUserSystemUid;
         assertTrue(dpm.isCurrentInputMethodSetByOwner());
@@ -3885,10 +3794,10 @@
 
         // Device owner changes IME for first user again.
         mContext.binder.callingUid = deviceOwnerUid;
-        when(mContext.settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM))
+        when(getServices().settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM))
                 .thenReturn("ime2");
         dpm.setSecureSetting(admin1, currentIme, "ime3");
-        verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime3",
+        verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime3",
                 UserHandle.USER_SYSTEM);
         dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM);
         mContext.binder.callingUid = firstUserSystemUid;
@@ -3936,12 +3845,12 @@
 
         // Profile owner changes IME for second user.
         mContext.binder.callingUid = profileOwnerUid;
-        when(mContext.settings.settingsSecureGetStringForUser(currentIme,
+        when(getServices().settings.settingsSecureGetStringForUser(currentIme,
                 DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime1");
         dpm.setSecureSetting(admin1, currentIme, "ime2");
-        verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime2",
+        verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime2",
                 DpmMockContext.CALLER_USER_HANDLE);
-        reset(mContext.settings);
+        reset(getServices().settings);
         dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE);
         mContext.binder.callingUid = firstUserSystemUid;
         assertFalse(dpm.isCurrentInputMethodSetByOwner());
@@ -3964,10 +3873,10 @@
 
         // Profile owner changes IME for second user again.
         mContext.binder.callingUid = profileOwnerUid;
-        when(mContext.settings.settingsSecureGetStringForUser(currentIme,
+        when(getServices().settings.settingsSecureGetStringForUser(currentIme,
                 DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime2");
         dpm.setSecureSetting(admin1, currentIme, "ime3");
-        verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime3",
+        verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime3",
                 DpmMockContext.CALLER_USER_HANDLE);
         dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE);
         mContext.binder.callingUid = firstUserSystemUid;
@@ -4026,7 +3935,7 @@
         // Attempt to set to empty list (which means no listener is whitelisted)
         mContext.binder.callingUid = adminUid;
         assertFalse(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.<String>emptyList()));
+                admin1, Collections.emptyList()));
         assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1));
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
@@ -4049,12 +3958,10 @@
         assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
                 admin1, Collections.singletonList(permittedListener)));
 
-        try {
-            dpms.isNotificationListenerServicePermitted(
-                permittedListener, MANAGED_PROFILE_USER_ID);
-            fail("isNotificationListenerServicePermitted should throw if not called from System");
-        } catch (SecurityException expected) {
-        }
+        // isNotificationListenerServicePermitted should throw if not called from System.
+        assertExpectException(SecurityException.class, /* messageRegex= */ null,
+                () -> dpms.isNotificationListenerServicePermitted(
+                        permittedListener, MANAGED_PROFILE_USER_ID));
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
         assertTrue(dpms.isNotificationListenerServicePermitted(
@@ -4103,7 +4010,7 @@
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
         assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
                 admin1, Collections.singletonList(permittedListener)));
-        List<String> permittedListeners =
+        final List<String> permittedListeners =
                 dpms.getPermittedCrossProfileNotificationListeners(admin1);
         assertEquals(1, permittedListeners.size());
         assertEquals(permittedListener, permittedListeners.get(0));
@@ -4120,7 +4027,7 @@
         // Setting an empty whitelist - only system listeners allowed
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
         assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.<String>emptyList()));
+                admin1, Collections.emptyList()));
         assertEquals(0, dpms.getPermittedCrossProfileNotificationListeners(admin1).size());
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
@@ -4184,7 +4091,7 @@
         // all allowed in primary profile
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
         assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.<String>emptyList()));
+                admin1, Collections.emptyList()));
         assertEquals(0, dpms.getPermittedCrossProfileNotificationListeners(admin1).size());
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
@@ -4199,39 +4106,38 @@
     }
 
     public void testGetOwnerInstalledCaCertsForDeviceOwner() throws Exception {
-        mContext.packageName = mRealTestContext.getPackageName();
+        mServiceContext.packageName = mRealTestContext.getPackageName();
+        mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+        mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setDeviceOwner();
 
-        final DpmMockContext caller = new DpmMockContext(mRealTestContext, "test-caller");
-        caller.packageName = admin1.getPackageName();
-        caller.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
-
-        verifyCanGetOwnerInstalledCaCerts(admin1, caller);
+        verifyCanGetOwnerInstalledCaCerts(admin1, mAdmin1Context);
     }
 
     public void testGetOwnerInstalledCaCertsForProfileOwner() throws Exception {
-        mContext.packageName = mRealTestContext.getPackageName();
+        mServiceContext.packageName = mRealTestContext.getPackageName();
+        mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+        mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_UID;
         setAsProfileOwner(admin1);
 
-        final DpmMockContext caller = new DpmMockContext(mRealTestContext, "test-caller");
-        caller.packageName = admin1.getPackageName();
-        caller.binder.callingUid = DpmMockContext.CALLER_UID;
-
-        verifyCanGetOwnerInstalledCaCerts(admin1, caller);
-        verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(admin1, caller);
+        verifyCanGetOwnerInstalledCaCerts(admin1, mAdmin1Context);
+        verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(admin1, mAdmin1Context);
     }
 
     public void testGetOwnerInstalledCaCertsForDelegate() throws Exception {
-        mContext.packageName = mRealTestContext.getPackageName();
+        mServiceContext.packageName = mRealTestContext.getPackageName();
+        mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+        mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_UID;
         setAsProfileOwner(admin1);
 
-        final String delegate = "com.example.delegate";
-        final int delegateUid = setupPackageInPackageManager(delegate, 20988);
-        dpm.setCertInstallerPackage(admin1, delegate);
+        final DpmMockContext caller = new DpmMockContext(getServices(), mRealTestContext);
+        caller.packageName = "com.example.delegate";
+        caller.binder.callingUid = setupPackageInPackageManager(caller.packageName,
+                DpmMockContext.CALLER_USER_HANDLE, 20988, ApplicationInfo.FLAG_HAS_CODE);
 
-        final DpmMockContext caller = new DpmMockContext(mRealTestContext, "test-caller");
-        caller.packageName = delegate;
-        caller.binder.callingUid = delegateUid;
+        // Make caller a delegated cert installer.
+        runAsCaller(mAdmin1Context, dpms,
+                dpm -> dpm.setCertInstallerPackage(admin1, caller.packageName));
 
         verifyCanGetOwnerInstalledCaCerts(null, caller);
         verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(null, caller);
@@ -4243,13 +4149,9 @@
         final byte[] caCert = TEST_CA.getBytes();
 
         // device admin (used for posting the tls notification)
-        final DpmMockContext admin1Context;
+        DpmMockContext admin1Context = mAdmin1Context;
         if (admin1.getPackageName().equals(callerContext.getPackageName())) {
             admin1Context = callerContext;
-        } else {
-            admin1Context = new DpmMockContext(mRealTestContext, "test-admin");
-            admin1Context.packageName = admin1.getPackageName();
-            admin1Context.applicationInfo = new ApplicationInfo();
         }
         when(admin1Context.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE);
 
@@ -4260,21 +4162,21 @@
         // system_server
         final DpmMockContext serviceContext = mContext;
         serviceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        serviceContext.addPackageContext(callerUser, admin1Context);
-        serviceContext.addPackageContext(callerUser, callerContext);
+        getServices().addPackageContext(callerUser, admin1Context);
+        getServices().addPackageContext(callerUser, callerContext);
 
         // Install a CA cert.
         runAsCaller(callerContext, dpms, (dpm) -> {
-            when(mContext.keyChainConnection.getService().installCaCertificate(caCert))
+            when(getServices().keyChainConnection.getService().installCaCertificate(caCert))
                         .thenReturn(alias);
             assertTrue(dpm.installCaCert(caller, caCert));
-            when(mContext.keyChainConnection.getService().getUserCaAliases())
+            when(getServices().keyChainConnection.getService().getUserCaAliases())
                     .thenReturn(asSlice(new String[] {alias}));
-
         });
 
-        serviceContext.injectBroadcast(new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
-                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()));
+        getServices().injectBroadcast(mServiceContext, new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
+                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()),
+                callerUser.getIdentifier());
         flushTasks();
 
         final List<String> ownerInstalledCaCerts = new ArrayList<>();
@@ -4282,26 +4184,26 @@
         // Device Owner / Profile Owner can find out which CA certs were installed by itself.
         runAsCaller(admin1Context, dpms, (dpm) -> {
             final List<String> installedCaCerts = dpm.getOwnerInstalledCaCerts(callerUser);
-            assertEquals(Arrays.asList(alias), installedCaCerts);
+            assertEquals(Collections.singletonList(alias), installedCaCerts);
             ownerInstalledCaCerts.addAll(installedCaCerts);
         });
 
         // Restarting the DPMS should not lose information.
         initializeDpms();
-        runAsCaller(admin1Context, dpms, (dpm) -> {
-            assertEquals(ownerInstalledCaCerts, dpm.getOwnerInstalledCaCerts(callerUser));
-        });
+        runAsCaller(admin1Context, dpms, (dpm) ->
+                assertEquals(ownerInstalledCaCerts, dpm.getOwnerInstalledCaCerts(callerUser)));
 
         // System can find out which CA certs were installed by the Device Owner / Profile Owner.
         runAsCaller(serviceContext, dpms, (dpm) -> {
             assertEquals(ownerInstalledCaCerts, dpm.getOwnerInstalledCaCerts(callerUser));
 
             // Remove the CA cert.
-            reset(mContext.keyChainConnection.getService());
+            reset(getServices().keyChainConnection.getService());
         });
 
-        serviceContext.injectBroadcast(new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
-                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()));
+        getServices().injectBroadcast(mServiceContext, new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
+                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()),
+                callerUser.getIdentifier());
         flushTasks();
 
         // Verify that the CA cert is no longer reported as installed by the Device Owner / Profile
@@ -4317,13 +4219,9 @@
         final byte[] caCert = TEST_CA.getBytes();
 
         // device admin (used for posting the tls notification)
-        final DpmMockContext admin1Context;
+        DpmMockContext admin1Context = mAdmin1Context;
         if (admin1.getPackageName().equals(callerContext.getPackageName())) {
             admin1Context = callerContext;
-        } else {
-            admin1Context = new DpmMockContext(mRealTestContext, "test-admin");
-            admin1Context.packageName = admin1.getPackageName();
-            admin1Context.applicationInfo = new ApplicationInfo();
         }
         when(admin1Context.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE);
 
@@ -4334,27 +4232,26 @@
         // system_server
         final DpmMockContext serviceContext = mContext;
         serviceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        serviceContext.addPackageContext(callerUser, admin1Context);
-        serviceContext.addPackageContext(callerUser, callerContext);
+        getServices().addPackageContext(callerUser, admin1Context);
+        getServices().addPackageContext(callerUser, callerContext);
 
         // Install a CA cert as caller
         runAsCaller(callerContext, dpms, (dpm) -> {
-            when(mContext.keyChainConnection.getService().installCaCertificate(caCert))
+            when(getServices().keyChainConnection.getService().installCaCertificate(caCert))
                     .thenReturn(alias);
             assertTrue(dpm.installCaCert(callerName, caCert));
         });
 
         // Fake the CA cert as having been installed
-        when(serviceContext.keyChainConnection.getService().getUserCaAliases())
+        when(getServices().keyChainConnection.getService().getUserCaAliases())
                 .thenReturn(asSlice(new String[] {alias}));
-        serviceContext.injectBroadcast(new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
-                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()));
+        getServices().injectBroadcast(mServiceContext, new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
+                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()),
+                callerUser.getIdentifier());
         flushTasks();
 
         // Removing the Profile Owner should clear the information on which CA certs were installed
-        runAsCaller(admin1Context, dpms, (dpm) -> {
-            dpm.clearProfileOwner(admin1);
-        });
+        runAsCaller(admin1Context, dpms, dpm -> dpm.clearProfileOwner(admin1));
 
         runAsCaller(serviceContext, dpms, (dpm) -> {
             final List<String> ownerInstalledCaCerts = dpm.getOwnerInstalledCaCerts(callerUser);
@@ -4364,7 +4261,7 @@
     }
 
     private void setUserSetupCompleteForUser(boolean isUserSetupComplete, int userhandle) {
-        when(mContext.settings.settingsSecureGetIntForUser(Settings.Secure.USER_SETUP_COMPLETE, 0,
+        when(getServices().settings.settingsSecureGetIntForUser(Settings.Secure.USER_SETUP_COMPLETE, 0,
                 userhandle)).thenReturn(isUserSetupComplete ? 1 : 0);
         dpms.notifyChangeToContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), userhandle);
@@ -4377,8 +4274,8 @@
 
     private void assertProvisioningAllowed(String action, boolean expected, String packageName,
             int uid) {
-        String previousPackageName = mContext.packageName;
-        int previousUid = mMockContext.binder.callingUid;
+        final String previousPackageName = mContext.packageName;
+        final int previousUid = mMockContext.binder.callingUid;
 
         // Call assertProvisioningAllowed with the packageName / uid passed as arguments.
         mContext.packageName = packageName;
@@ -4411,7 +4308,7 @@
     private void addManagedProfile(
             ComponentName admin, int adminUid, ComponentName copyFromAdmin) throws Exception {
         final int userId = UserHandle.getUserId(adminUid);
-        mContext.addUser(userId, UserInfo.FLAG_MANAGED_PROFILE, UserHandle.USER_SYSTEM);
+        getServices().addUser(userId, UserInfo.FLAG_MANAGED_PROFILE, UserHandle.USER_SYSTEM);
         mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
         setUpPackageManagerForFakeAdmin(admin, adminUid, copyFromAdmin);
         dpm.setActiveAdmin(admin, false, userId);
@@ -4432,6 +4329,6 @@
 
         // We can't let exceptions happen on the background thread. Throw them here if they happen
         // so they still cause the test to fail despite being suppressed.
-        mContext.rethrowBackgroundBroadcastExceptions();
+        getServices().rethrowBackgroundBroadcastExceptions();
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
index 87106ec..9702118 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -16,61 +16,28 @@
 
 package com.android.server.devicepolicy;
 
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.AlarmManager;
-import android.app.IActivityManager;
-import android.app.NotificationManager;
-import android.app.backup.IBackupManager;
+import static org.mockito.Mockito.mock;
+
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
-import android.content.pm.UserInfo;
 import android.content.res.Resources;
-import android.media.IAudioService;
-import android.net.IIpConnectivityMetrics;
-import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.PowerManager.WakeLock;
-import android.os.PowerManagerInternal;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.os.UserManagerInternal;
-import android.security.KeyChain;
-import android.telephony.TelephonyManager;
-import android.test.mock.MockContentResolver;
 import android.test.mock.MockContext;
 import android.util.ArrayMap;
-import android.util.Pair;
-import android.view.IWindowManager;
-
-import com.android.internal.widget.LockPatternUtils;
 
 import org.junit.Assert;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
 
-import java.io.File;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
-
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
 
 /**
  * Context used throughout DPMS tests.
@@ -107,9 +74,10 @@
     public static final int SYSTEM_PID = 11111;
 
     public static final String ANOTHER_PACKAGE_NAME = "com.another.package.name";
-
     public static final int ANOTHER_UID = UserHandle.getUid(UserHandle.USER_SYSTEM, 18434);
 
+    private final MockSystemServices mMockSystemServices;
+
     public static class MockBinder {
         public int callingUid = CALLER_UID;
         public int callingPid = CALLER_PID;
@@ -144,130 +112,7 @@
         }
     }
 
-    public static class EnvironmentForMock {
-        public File getUserSystemDirectory(int userId) {
-            return null;
-        }
-    }
-
-    public static class BuildMock {
-        public boolean isDebuggable = true;
-    }
-
-    public static class PowerManagerForMock {
-        public WakeLock newWakeLock(int levelAndFlags, String tag) {
-            return null;
-        }
-
-        public void goToSleep(long time, int reason, int flags) {
-        }
-
-        public void reboot(String reason) {
-        }
-    }
-
-    public static class RecoverySystemForMock {
-        public void rebootWipeUserData(
-                boolean shutdown, String reason, boolean force) throws IOException {
-        }
-    }
-
-    public static class SystemPropertiesForMock {
-        public boolean getBoolean(String key, boolean def) {
-            return false;
-        }
-
-        public long getLong(String key, long def) {
-            return 0;
-        }
-
-        public String get(String key, String def) {
-            return null;
-        }
-
-        public String get(String key) {
-            return null;
-        }
-
-        public void set(String key, String value) {
-        }
-    }
-
-    public static class UserManagerForMock {
-        public boolean isSplitSystemUser() {
-            return false;
-        }
-    }
-
-    public static class SettingsForMock {
-        public int settingsSecureGetIntForUser(String name, int def, int userHandle) {
-            return 0;
-        }
-
-        public String settingsSecureGetStringForUser(String name, int userHandle) {
-            return null;
-        }
-
-        public void settingsSecurePutIntForUser(String name, int value, int userHandle) {
-        }
-
-        public void settingsSecurePutStringForUser(String name, String value, int userHandle) {
-        }
-
-        public void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
-        }
-
-        public void settingsSecurePutInt(String name, int value) {
-        }
-
-        public void settingsGlobalPutInt(String name, int value) {
-        }
-
-        public void settingsSecurePutString(String name, String value) {
-        }
-
-        public void settingsGlobalPutString(String name, String value) {
-        }
-
-        public int settingsGlobalGetInt(String name, int value) {
-            return 0;
-        }
-
-        public String settingsGlobalGetString(String name) {
-            return "";
-        }
-
-        public void securityLogSetLoggingEnabledProperty(boolean enabled) {
-        }
-
-        public boolean securityLogGetLoggingEnabledProperty() {
-            return false;
-        }
-
-        public boolean securityLogIsLoggingEnabled() {
-            return false;
-        }
-    }
-
-    public static class StorageManagerForMock {
-        public boolean isFileBasedEncryptionEnabled() {
-            return false;
-        }
-
-        public boolean isNonDefaultBlockEncrypted() {
-            return false;
-        }
-
-        public boolean isEncrypted() {
-            return false;
-        }
-
-        public boolean isEncryptable() {
-            return false;
-        }
-    }
-
-    public final Context realTestContext;
+    private final Context realTestContext;
 
     /**
      * Use this instance to verify unimplemented methods such as {@link #sendBroadcast}.
@@ -276,39 +121,8 @@
      */
     public final Context spiedContext;
 
-    public final File dataDir;
-    public final File systemUserDataDir;
-
     public final MockBinder binder;
-    public final EnvironmentForMock environment;
     public final Resources resources;
-    public final SystemPropertiesForMock systemProperties;
-    public final UserManager userManager;
-    public final UserManagerInternal userManagerInternal;
-    public final PackageManagerInternal packageManagerInternal;
-    public final UserManagerForMock userManagerForMock;
-    public final PowerManagerForMock powerManager;
-    public final PowerManagerInternal powerManagerInternal;
-    public final RecoverySystemForMock recoverySystem;
-    public final NotificationManager notificationManager;
-    public final IIpConnectivityMetrics iipConnectivityMetrics;
-    public final IWindowManager iwindowManager;
-    public final IActivityManager iactivityManager;
-    public final IPackageManager ipackageManager;
-    public final IBackupManager ibackupManager;
-    public final IAudioService iaudioService;
-    public final LockPatternUtils lockPatternUtils;
-    public final StorageManagerForMock storageManager;
-    public final WifiManager wifiManager;
-    public final SettingsForMock settings;
-    public final MockContentResolver contentResolver;
-    public final TelephonyManager telephonyManager;
-    public final AccountManager accountManager;
-    public final AlarmManager alarmManager;
-    public final KeyChain.KeyChainConnection keyChainConnection;
-
-    /** Note this is a partial mock, not a real mock. */
-    public final PackageManager packageManager;
 
     /** TODO: Migrate everything to use {@link #permissions} to avoid confusion. */
     @Deprecated
@@ -317,246 +131,17 @@
     /** Less confusing alias for {@link #callerPermissions}. */
     public final List<String> permissions = callerPermissions;
 
-    private final ArrayList<UserInfo> mUserInfos = new ArrayList<>();
-
-    public final BuildMock buildMock = new BuildMock();
-
-    /** Optional mapping of other user contexts for {@link #createPackageContextAsUser} to return */
-    public final Map<Pair<UserHandle, String>, Context> userPackageContexts = new ArrayMap<>();
-
     public String packageName = null;
 
     public ApplicationInfo applicationInfo = null;
 
-    // We have to keep track of broadcast receivers registered for a given intent ourselves as the
-    // DPM unit tests mock out the package manager and PackageManager.queryBroadcastReceivers() does
-    // not work.
-    private class BroadcastReceiverRegistration {
-        public final BroadcastReceiver receiver;
-        public final IntentFilter filter;
-        public final Handler scheduler;
-
-        // Exceptions thrown in a background thread kill the whole test. Save them instead.
-        public final AtomicReference<Exception> backgroundException = new AtomicReference<>();
-
-        public BroadcastReceiverRegistration(BroadcastReceiver receiver, IntentFilter filter,
-                Handler scheduler) {
-            this.receiver = receiver;
-            this.filter = filter;
-            this.scheduler = scheduler;
-        }
-
-        public void sendBroadcastIfApplicable(int userId, Intent intent) {
-            final BroadcastReceiver.PendingResult result = new BroadcastReceiver.PendingResult(
-                    0 /* resultCode */, null /* resultData */, null /* resultExtras */,
-                    0 /* type */, false /* ordered */, false /* sticky */, null /* token */, userId,
-                    0 /* flags */);
-            if (filter.match(null, intent, false, "DpmMockContext") > 0) {
-                final Runnable send = () -> {
-                    receiver.setPendingResult(result);
-                    receiver.onReceive(DpmMockContext.this, intent);
-                };
-                if (scheduler != null) {
-                    scheduler.post(() -> {
-                        try {
-                            send.run();
-                        } catch (Exception e) {
-                            backgroundException.compareAndSet(null, e);
-                        }
-                    });
-                } else {
-                    send.run();
-                }
-            }
-        }
-    }
-    private List<BroadcastReceiverRegistration> mBroadcastReceivers = new ArrayList<>();
-
-    public DpmMockContext(Context realTestContext, String name) {
-        this(realTestContext, new File(realTestContext.getCacheDir(), name));
-    }
-
-    public DpmMockContext(Context context, File dataDir) {
+    public DpmMockContext(MockSystemServices mockSystemServices, Context context) {
+        mMockSystemServices = mockSystemServices;
         realTestContext = context;
 
-        this.dataDir = dataDir;
-        DpmTestUtils.clearDir(dataDir);
-
         binder = new MockBinder();
-        environment = mock(EnvironmentForMock.class);
         resources = mock(Resources.class);
-        systemProperties = mock(SystemPropertiesForMock.class);
-        userManager = mock(UserManager.class);
-        userManagerInternal = mock(UserManagerInternal.class);
-        userManagerForMock = mock(UserManagerForMock.class);
-        packageManagerInternal = mock(PackageManagerInternal.class);
-        powerManager = mock(PowerManagerForMock.class);
-        powerManagerInternal = mock(PowerManagerInternal.class);
-        recoverySystem = mock(RecoverySystemForMock.class);
-        notificationManager = mock(NotificationManager.class);
-        iipConnectivityMetrics = mock(IIpConnectivityMetrics.class);
-        iwindowManager = mock(IWindowManager.class);
-        iactivityManager = mock(IActivityManager.class);
-        ipackageManager = mock(IPackageManager.class);
-        ibackupManager = mock(IBackupManager.class);
-        iaudioService = mock(IAudioService.class);
-        lockPatternUtils = mock(LockPatternUtils.class);
-        storageManager = mock(StorageManagerForMock.class);
-        wifiManager = mock(WifiManager.class);
-        settings = mock(SettingsForMock.class);
-        telephonyManager = mock(TelephonyManager.class);
-        accountManager = mock(AccountManager.class);
-        alarmManager = mock(AlarmManager.class);
-        keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS);
-
-        // Package manager is huge, so we use a partial mock instead.
-        packageManager = spy(context.getPackageManager());
-
         spiedContext = mock(Context.class);
-
-        contentResolver = new MockContentResolver();
-
-        // Add the system user with a fake profile group already set up (this can happen in the real
-        // world if a managed profile is added and then removed).
-        systemUserDataDir =
-                addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY, UserHandle.USER_SYSTEM);
-
-        // System user is always running.
-        setUserRunning(UserHandle.USER_SYSTEM, true);
-    }
-
-    public File addUser(int userId, int flags) {
-        return addUser(userId, flags, UserInfo.NO_PROFILE_GROUP_ID);
-    }
-
-    public File addUser(int userId, int flags, int profileGroupId) {
-        // Set up (default) UserInfo for CALLER_USER_HANDLE.
-        final UserInfo uh = new UserInfo(userId, "user" + userId, flags);
-        uh.profileGroupId = profileGroupId;
-        when(userManager.getUserInfo(eq(userId))).thenReturn(uh);
-
-        mUserInfos.add(uh);
-        when(userManager.getUsers()).thenReturn(mUserInfos);
-        when(userManager.getUsers(anyBoolean())).thenReturn(mUserInfos);
-        when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true);
-        when(userManager.getUserInfo(anyInt())).thenAnswer(
-                new Answer<UserInfo>() {
-                    @Override
-                    public UserInfo answer(InvocationOnMock invocation) throws Throwable {
-                        final int userId = (int) invocation.getArguments()[0];
-                        return getUserInfo(userId);
-                    }
-                }
-        );
-        when(userManager.getProfiles(anyInt())).thenAnswer(
-                new Answer<List<UserInfo>>() {
-                    @Override
-                    public List<UserInfo> answer(InvocationOnMock invocation) throws Throwable {
-                        final int userId = (int) invocation.getArguments()[0];
-                        return getProfiles(userId);
-                    }
-                }
-        );
-        when(userManager.getProfileIdsWithDisabled(anyInt())).thenAnswer(
-                new Answer<int[]>() {
-                    @Override
-                    public int[] answer(InvocationOnMock invocation) throws Throwable {
-                        final int userId = (int) invocation.getArguments()[0];
-                        List<UserInfo> profiles = getProfiles(userId);
-                        return profiles.stream()
-                                .mapToInt(profile -> profile.id)
-                                .toArray();
-                    }
-                }
-        );
-        when(accountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
-
-        // Create a data directory.
-        final File dir = new File(dataDir, "users/" + userId);
-        DpmTestUtils.clearDir(dir);
-
-        when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir);
-        return dir;
-    }
-
-    public void removeUser(int userId) {
-        for (int i = 0; i < mUserInfos.size(); i++) {
-            if (mUserInfos.get(i).id == userId) {
-                mUserInfos.remove(i);
-                break;
-            }
-        }
-        when(userManager.getUserInfo(eq(userId))).thenReturn(null);
-
-        when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(false);
-    }
-
-    private UserInfo getUserInfo(int userId) {
-        for (UserInfo ui : mUserInfos) {
-            if (ui.id == userId) {
-                return ui;
-            }
-        }
-        return null;
-    }
-
-    private List<UserInfo> getProfiles(int userId) {
-        final ArrayList<UserInfo> ret = new ArrayList<UserInfo>();
-        UserInfo parent = null;
-        for (UserInfo ui : mUserInfos) {
-            if (ui.id == userId) {
-                parent = ui;
-                break;
-            }
-        }
-        if (parent == null) {
-            return ret;
-        }
-        for (UserInfo ui : mUserInfos) {
-            if (ui == parent
-                    || ui.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
-                    && ui.profileGroupId == parent.profileGroupId) {
-                ret.add(ui);
-            }
-        }
-        return ret;
-    }
-
-    /**
-     * Add multiple users at once.  They'll all have flag 0.
-     */
-    public void addUsers(int... userIds) {
-        for (int userId : userIds) {
-            addUser(userId, 0);
-        }
-    }
-
-    public void setUserRunning(int userId, boolean isRunning) {
-        when(userManager.isUserRunning(MockUtils.checkUserHandle(userId)))
-                .thenReturn(isRunning);
-    }
-
-    public void injectBroadcast(final Intent intent) {
-        final int userId = UserHandle.getUserId(binder.getCallingUid());
-        for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
-            receiver.sendBroadcastIfApplicable(userId, intent);
-        }
-    }
-
-    public void rethrowBackgroundBroadcastExceptions() throws Exception {
-        for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
-            final Exception e = receiver.backgroundException.getAndSet(null);
-            if (e != null) {
-                throw e;
-            }
-        }
-    }
-
-    public void addPackageContext(UserHandle user, Context context) {
-        if (context.getPackageName() == null) {
-            throw new NullPointerException("getPackageName() == null");
-        }
-        userPackageContexts.put(new Pair<>(user, context.getPackageName()), context);
     }
 
     @Override
@@ -589,15 +174,15 @@
     public Object getSystemService(String name) {
         switch (name) {
             case Context.ALARM_SERVICE:
-                return alarmManager;
+                return mMockSystemServices.alarmManager;
             case Context.USER_SERVICE:
-                return userManager;
+                return mMockSystemServices.userManager;
             case Context.POWER_SERVICE:
-                return powerManager;
+                return mMockSystemServices.powerManager;
             case Context.WIFI_SERVICE:
-                return wifiManager;
+                return mMockSystemServices.wifiManager;
             case Context.ACCOUNT_SERVICE:
-                return accountManager;
+                return mMockSystemServices.accountManager;
         }
         throw new UnsupportedOperationException();
     }
@@ -609,22 +194,25 @@
 
     @Override
     public PackageManager getPackageManager() {
-        return packageManager;
+        return mMockSystemServices.packageManager;
+    }
+
+    public UserManagerInternal getUserManagerInternal() {
+        return mMockSystemServices.userManagerInternal;
     }
 
     @Override
     public void enforceCallingOrSelfPermission(String permission, String message) {
-        if (binder.getCallingUid() == SYSTEM_UID) {
+        if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) {
             return; // Assume system has all permissions.
         }
-
         List<String> permissions = binder.callingPermissions.get(binder.getCallingUid());
         if (permissions == null) {
             // TODO: delete the following line. to do this without breaking any tests, first it's
             //       necessary to remove all tests that set it directly.
             permissions = callerPermissions;
-//            throw new UnsupportedOperationException(
-//                    "Caller UID " + binder.getCallingUid() + " doesn't exist");
+            //            throw new UnsupportedOperationException(
+            //                    "Caller UID " + binder.getCallingUid() + " doesn't exist");
         }
         if (!permissions.contains(permission)) {
             throw new SecurityException("Caller doesn't have " + permission + " : " + message);
@@ -773,44 +361,40 @@
 
     @Override
     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
-        mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, null));
+        mMockSystemServices.registerReceiver(receiver, filter, null);
         return spiedContext.registerReceiver(receiver, filter);
     }
 
     @Override
     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
             String broadcastPermission, Handler scheduler) {
-        mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler));
+        mMockSystemServices.registerReceiver(receiver, filter, scheduler);
         return spiedContext.registerReceiver(receiver, filter, broadcastPermission, scheduler);
     }
 
     @Override
     public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
             IntentFilter filter, String broadcastPermission, Handler scheduler) {
-        mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler));
+        mMockSystemServices.registerReceiver(receiver, filter, scheduler);
         return spiedContext.registerReceiverAsUser(receiver, user, filter, broadcastPermission,
                 scheduler);
     }
 
     @Override
     public void unregisterReceiver(BroadcastReceiver receiver) {
-        mBroadcastReceivers.removeIf(r -> r.receiver == receiver);
+        mMockSystemServices.unregisterReceiver(receiver);
         spiedContext.unregisterReceiver(receiver);
     }
 
     @Override
     public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
             throws PackageManager.NameNotFoundException {
-        final Pair<UserHandle, String> key = new Pair<>(user, packageName);
-        if (userPackageContexts.containsKey(key)) {
-            return userPackageContexts.get(key);
-        }
-        throw new UnsupportedOperationException("No package " + packageName + " for user " + user);
+        return mMockSystemServices.createPackageContextAsUser(packageName, flags, user);
     }
 
     @Override
     public ContentResolver getContentResolver() {
-        return contentResolver;
+        return mMockSystemServices.contentResolver;
     }
 
     @Override
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
index 5d68edd6..e0ea573 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
@@ -16,6 +16,10 @@
 
 package com.android.server.devicepolicy;
 
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -28,20 +32,14 @@
 import android.os.UserHandle;
 import android.test.AndroidTestCase;
 
-import java.io.File;
 import java.util.List;
 
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
-
 public abstract class DpmTestBase extends AndroidTestCase {
     public static final String TAG = "DpmTest";
 
     protected Context mRealTestContext;
     protected DpmMockContext mMockContext;
-
-    public File dataDir;
+    private MockSystemServices mServices;
 
     public ComponentName admin1;
     public ComponentName admin2;
@@ -55,8 +53,8 @@
 
         mRealTestContext = super.getContext();
 
-        mMockContext = new DpmMockContext(
-                mRealTestContext, new File(mRealTestContext.getCacheDir(), "test-data"));
+        mServices = new MockSystemServices(mRealTestContext, "test-data");
+        mMockContext = new DpmMockContext(mServices, mRealTestContext);
 
         admin1 = new ComponentName(mRealTestContext, DummyDeviceAdmins.Admin1.class);
         admin2 = new ComponentName(mRealTestContext, DummyDeviceAdmins.Admin2.class);
@@ -71,12 +69,16 @@
         return mMockContext;
     }
 
+    public MockSystemServices getServices() {
+        return mServices;
+    }
+
     protected interface DpmRunnable {
-        public void run(DevicePolicyManager dpm) throws Exception;
+        void run(DevicePolicyManager dpm) throws Exception;
     }
 
     /**
-     * Simulate an RPC from {@param caller} to the service context ({@link #mContext}).
+     * Simulate an RPC from {@param caller} to the service context ({@link #mMockContext}).
      *
      * The caller sees its own context. The server also sees its own separate context, with the
      * appropriate calling UID and calling permissions fields already set up.
@@ -85,12 +87,15 @@
             DpmRunnable action) {
         final DpmMockContext serviceContext = mMockContext;
 
+        // Save calling UID and PID before clearing identity so we don't run into aliasing issues.
+        final int callingUid = caller.binder.callingUid;
+        final int callingPid = caller.binder.callingPid;
+
         final long origId = serviceContext.binder.clearCallingIdentity();
         try {
-            serviceContext.binder.callingUid = caller.binder.callingUid;
-            serviceContext.binder.callingPid = caller.binder.callingPid;
-            serviceContext.binder.callingPermissions.put(caller.binder.callingUid,
-                    caller.permissions);
+            serviceContext.binder.callingUid = callingUid;
+            serviceContext.binder.callingPid = callingPid;
+            serviceContext.binder.callingPermissions.put(callingUid, caller.permissions);
             action.run(new DevicePolicyManagerTestable(caller, dpms));
         } catch (Exception e) {
             throw new AssertionError(e);
@@ -99,7 +104,7 @@
         }
     }
 
-    protected void markPackageAsInstalled(String packageName, ApplicationInfo ai, int userId)
+    private void markPackageAsInstalled(String packageName, ApplicationInfo ai, int userId)
             throws Exception {
         final PackageInfo pi = DpmTestUtils.cloneParcelable(
                 mRealTestContext.getPackageManager().getPackageInfo(
@@ -110,12 +115,12 @@
             pi.applicationInfo = ai;
         }
 
-        doReturn(pi).when(mMockContext.ipackageManager).getPackageInfo(
+        doReturn(pi).when(mServices.ipackageManager).getPackageInfo(
                 eq(packageName),
                 eq(0),
                 eq(userId));
 
-        doReturn(ai.uid).when(mMockContext.packageManager).getPackageUidAsUser(
+        doReturn(ai.uid).when(mServices.packageManager).getPackageUidAsUser(
                 eq(packageName),
                 eq(userId));
     }
@@ -151,7 +156,7 @@
      * @param copyFromAdmin package information for {@code admin} will be built based on this
      *    component's information.
      */
-    protected void setUpPackageManagerForFakeAdmin(ComponentName admin, int packageUid,
+    private void setUpPackageManagerForFakeAdmin(ComponentName admin, int packageUid,
             Integer enabledSetting, Integer appTargetSdk, ComponentName copyFromAdmin)
             throws Exception {
 
@@ -171,7 +176,7 @@
         ai.packageName = admin.getPackageName();
         ai.name = admin.getClassName();
 
-        doReturn(ai).when(mMockContext.ipackageManager).getApplicationInfo(
+        doReturn(ai).when(mServices.ipackageManager).getApplicationInfo(
                 eq(admin.getPackageName()),
                 anyInt(),
                 eq(UserHandle.getUserId(packageUid)));
@@ -198,12 +203,12 @@
 
         // Note we don't set up queryBroadcastReceivers.  We don't use it in DPMS.
 
-        doReturn(aci).when(mMockContext.ipackageManager).getReceiverInfo(
+        doReturn(aci).when(mServices.ipackageManager).getReceiverInfo(
                 eq(admin),
                 anyInt(),
                 eq(UserHandle.getUserId(packageUid)));
 
-        doReturn(new String[] {admin.getPackageName()}).when(mMockContext.ipackageManager)
+        doReturn(new String[] {admin.getPackageName()}).when(mServices.ipackageManager)
             .getPackagesForUid(eq(packageUid));
         // Set up getPackageInfo().
         markPackageAsInstalled(admin.getPackageName(), ai, UserHandle.getUserId(packageUid));
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
new file mode 100644
index 0000000..99f54ba
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -0,0 +1,462 @@
+/*
+ * 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.devicepolicy;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.AlarmManager;
+import android.app.IActivityManager;
+import android.app.NotificationManager;
+import android.app.backup.IBackupManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.content.pm.UserInfo;
+import android.media.IAudioService;
+import android.net.IIpConnectivityMetrics;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.PowerManagerInternal;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.UserManagerInternal;
+import android.provider.Settings;
+import android.security.KeyChain;
+import android.telephony.TelephonyManager;
+import android.test.mock.MockContentResolver;
+import android.util.ArrayMap;
+import android.util.Pair;
+import android.view.IWindowManager;
+
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.internal.widget.LockPatternUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * System services mocks and some other data that are shared by all contexts during the test.
+ */
+public class MockSystemServices {
+    public final File systemUserDataDir;
+    public final EnvironmentForMock environment;
+    public final SystemPropertiesForMock systemProperties;
+    public final UserManager userManager;
+    public final UserManagerInternal userManagerInternal;
+    public final PackageManagerInternal packageManagerInternal;
+    public final UserManagerForMock userManagerForMock;
+    public final PowerManagerForMock powerManager;
+    public final PowerManagerInternal powerManagerInternal;
+    public final RecoverySystemForMock recoverySystem;
+    public final NotificationManager notificationManager;
+    public final IIpConnectivityMetrics iipConnectivityMetrics;
+    public final IWindowManager iwindowManager;
+    public final IActivityManager iactivityManager;
+    public final IPackageManager ipackageManager;
+    public final IBackupManager ibackupManager;
+    public final IAudioService iaudioService;
+    public final LockPatternUtils lockPatternUtils;
+    public final StorageManagerForMock storageManager;
+    public final WifiManager wifiManager;
+    public final SettingsForMock settings;
+    public final MockContentResolver contentResolver;
+    public final TelephonyManager telephonyManager;
+    public final AccountManager accountManager;
+    public final AlarmManager alarmManager;
+    public final KeyChain.KeyChainConnection keyChainConnection;
+    /** Note this is a partial mock, not a real mock. */
+    public final PackageManager packageManager;
+    public final BuildMock buildMock = new BuildMock();
+    public final File dataDir;
+
+    public MockSystemServices(Context realContext, String name) {
+        dataDir = new File(realContext.getCacheDir(), name);
+        DpmTestUtils.clearDir(dataDir);
+
+        environment = mock(EnvironmentForMock.class);
+        systemProperties = mock(SystemPropertiesForMock.class);
+        userManager = mock(UserManager.class);
+        userManagerInternal = mock(UserManagerInternal.class);
+        userManagerForMock = mock(UserManagerForMock.class);
+        packageManagerInternal = mock(PackageManagerInternal.class);
+        powerManager = mock(PowerManagerForMock.class);
+        powerManagerInternal = mock(PowerManagerInternal.class);
+        recoverySystem = mock(RecoverySystemForMock.class);
+        notificationManager = mock(NotificationManager.class);
+        iipConnectivityMetrics = mock(IIpConnectivityMetrics.class);
+        iwindowManager = mock(IWindowManager.class);
+        iactivityManager = mock(IActivityManager.class);
+        ipackageManager = mock(IPackageManager.class);
+        ibackupManager = mock(IBackupManager.class);
+        iaudioService = mock(IAudioService.class);
+        lockPatternUtils = mock(LockPatternUtils.class);
+        storageManager = mock(StorageManagerForMock.class);
+        wifiManager = mock(WifiManager.class);
+        settings = mock(SettingsForMock.class);
+        telephonyManager = mock(TelephonyManager.class);
+        accountManager = mock(AccountManager.class);
+        alarmManager = mock(AlarmManager.class);
+        keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS);
+
+        // Package manager is huge, so we use a partial mock instead.
+        packageManager = spy(realContext.getPackageManager());
+
+        contentResolver = new MockContentResolver();
+        contentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+
+        // Add the system user with a fake profile group already set up (this can happen in the real
+        // world if a managed profile is added and then removed).
+        systemUserDataDir =
+                addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY, UserHandle.USER_SYSTEM);
+
+        // System user is always running.
+        setUserRunning(UserHandle.USER_SYSTEM, true);
+    }
+
+    /** Optional mapping of other user contexts for {@link #createPackageContextAsUser} to return */
+    private final Map<Pair<UserHandle, String>, Context> userPackageContexts = new ArrayMap<>();
+
+    private final ArrayList<UserInfo> mUserInfos = new ArrayList<>();
+
+    private final List<BroadcastReceiverRegistration> mBroadcastReceivers = new ArrayList<>();
+
+    public void registerReceiver(
+            BroadcastReceiver receiver, IntentFilter filter, Handler scheduler) {
+        mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler));
+    }
+
+    public void unregisterReceiver(BroadcastReceiver receiver) {
+        mBroadcastReceivers.removeIf(r -> r.receiver == receiver);
+    }
+
+    public File addUser(int userId, int flags) {
+        return addUser(userId, flags, UserInfo.NO_PROFILE_GROUP_ID);
+    }
+
+    public File addUser(int userId, int flags, int profileGroupId) {
+        // Set up (default) UserInfo for CALLER_USER_HANDLE.
+        final UserInfo uh = new UserInfo(userId, "user" + userId, flags);
+        uh.profileGroupId = profileGroupId;
+        when(userManager.getUserInfo(eq(userId))).thenReturn(uh);
+
+        mUserInfos.add(uh);
+        when(userManager.getUsers()).thenReturn(mUserInfos);
+        when(userManager.getUsers(anyBoolean())).thenReturn(mUserInfos);
+        when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true);
+        when(userManager.getUserInfo(anyInt())).thenAnswer(
+                invocation -> {
+                    final int userId1 = (int) invocation.getArguments()[0];
+                    return getUserInfo(userId1);
+                }
+        );
+        when(userManager.getProfiles(anyInt())).thenAnswer(
+                invocation -> {
+                    final int userId12 = (int) invocation.getArguments()[0];
+                    return getProfiles(userId12);
+                }
+        );
+        when(userManager.getProfileIdsWithDisabled(anyInt())).thenAnswer(
+                invocation -> {
+                    final int userId13 = (int) invocation.getArguments()[0];
+                    List<UserInfo> profiles = getProfiles(userId13);
+                    return profiles.stream()
+                            .mapToInt(profile -> profile.id)
+                            .toArray();
+                }
+        );
+        when(accountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
+
+        // Create a data directory.
+        final File dir = new File(dataDir, "users/" + userId);
+        DpmTestUtils.clearDir(dir);
+
+        when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir);
+        return dir;
+    }
+
+    public void removeUser(int userId) {
+        for (int i = 0; i < mUserInfos.size(); i++) {
+            if (mUserInfos.get(i).id == userId) {
+                mUserInfos.remove(i);
+                break;
+            }
+        }
+        when(userManager.getUserInfo(eq(userId))).thenReturn(null);
+
+        when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(false);
+    }
+
+    private UserInfo getUserInfo(int userId) {
+        for (final UserInfo ui : mUserInfos) {
+            if (ui.id == userId) {
+                return ui;
+            }
+        }
+        return null;
+    }
+
+    private List<UserInfo> getProfiles(int userId) {
+        final ArrayList<UserInfo> ret = new ArrayList<>();
+        UserInfo parent = null;
+        for (final UserInfo ui : mUserInfos) {
+            if (ui.id == userId) {
+                parent = ui;
+                break;
+            }
+        }
+        if (parent == null) {
+            return ret;
+        }
+        for (final UserInfo ui : mUserInfos) {
+            if (ui == parent
+                    || ui.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
+                    && ui.profileGroupId == parent.profileGroupId) {
+                ret.add(ui);
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * Add multiple users at once.  They'll all have flag 0.
+     */
+    public void addUsers(int... userIds) {
+        for (final int userId : userIds) {
+            addUser(userId, 0);
+        }
+    }
+
+    public void setUserRunning(int userId, boolean isRunning) {
+        when(userManager.isUserRunning(MockUtils.checkUserHandle(userId)))
+                .thenReturn(isRunning);
+    }
+
+    public void injectBroadcast(Context context, final Intent intent, int userId) {
+        //final int userId = UserHandle.getUserId(binder.getCallingUid());
+        for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
+            receiver.sendBroadcastIfApplicable(context, userId, intent);
+        }
+    }
+
+    public void rethrowBackgroundBroadcastExceptions() throws Exception {
+        for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
+            final Exception e = receiver.backgroundException.getAndSet(null);
+            if (e != null) {
+                throw e;
+            }
+        }
+    }
+
+    public void addPackageContext(UserHandle user, Context context) {
+        if (context.getPackageName() == null) {
+            throw new NullPointerException("getPackageName() == null");
+        }
+        userPackageContexts.put(new Pair<>(user, context.getPackageName()), context);
+    }
+
+    public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
+            throws PackageManager.NameNotFoundException {
+        final Pair<UserHandle, String> key = new Pair<>(user, packageName);
+        if (userPackageContexts.containsKey(key)) {
+            return userPackageContexts.get(key);
+        }
+        throw new UnsupportedOperationException("No package " + packageName + " for user " + user);
+    }
+
+
+    public static class EnvironmentForMock {
+        public File getUserSystemDirectory(int userId) {
+            return null;
+        }
+    }
+
+    public static class BuildMock {
+        public boolean isDebuggable = true;
+    }
+
+    public static class PowerManagerForMock {
+        public PowerManager.WakeLock newWakeLock(int levelAndFlags, String tag) {
+            return null;
+        }
+
+        public void goToSleep(long time, int reason, int flags) {
+        }
+
+        public void reboot(String reason) {
+        }
+    }
+
+    public static class RecoverySystemForMock {
+        public void rebootWipeUserData(boolean shutdown, String reason, boolean force,
+                boolean wipeEuicc) throws IOException {
+        }
+    }
+
+    public static class SystemPropertiesForMock {
+        public boolean getBoolean(String key, boolean def) {
+            return false;
+        }
+
+        public long getLong(String key, long def) {
+            return 0;
+        }
+
+        public String get(String key, String def) {
+            return null;
+        }
+
+        public String get(String key) {
+            return null;
+        }
+
+        public void set(String key, String value) {
+        }
+    }
+
+    public static class UserManagerForMock {
+        public boolean isSplitSystemUser() {
+            return false;
+        }
+    }
+
+    public static class SettingsForMock {
+        public int settingsSecureGetIntForUser(String name, int def, int userHandle) {
+            return 0;
+        }
+
+        public String settingsSecureGetStringForUser(String name, int userHandle) {
+            return null;
+        }
+
+        public void settingsSecurePutIntForUser(String name, int value, int userHandle) {
+        }
+
+        public void settingsSecurePutStringForUser(String name, String value, int userHandle) {
+        }
+
+        public void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
+        }
+
+        public void settingsSecurePutInt(String name, int value) {
+        }
+
+        public void settingsGlobalPutInt(String name, int value) {
+        }
+
+        public void settingsSecurePutString(String name, String value) {
+        }
+
+        public void settingsGlobalPutString(String name, String value) {
+        }
+
+        public int settingsGlobalGetInt(String name, int value) {
+            return 0;
+        }
+
+        public String settingsGlobalGetString(String name) {
+            return "";
+        }
+
+        public void securityLogSetLoggingEnabledProperty(boolean enabled) {
+        }
+
+        public boolean securityLogGetLoggingEnabledProperty() {
+            return false;
+        }
+
+        public boolean securityLogIsLoggingEnabled() {
+            return false;
+        }
+    }
+
+    public static class StorageManagerForMock {
+        public boolean isFileBasedEncryptionEnabled() {
+            return false;
+        }
+
+        public boolean isNonDefaultBlockEncrypted() {
+            return false;
+        }
+
+        public boolean isEncrypted() {
+            return false;
+        }
+
+        public boolean isEncryptable() {
+            return false;
+        }
+    }
+
+    // We have to keep track of broadcast receivers registered for a given intent ourselves as the
+    // DPM unit tests mock out the package manager and PackageManager.queryBroadcastReceivers() does
+    // not work.
+    private static class BroadcastReceiverRegistration {
+        public final BroadcastReceiver receiver;
+        public final IntentFilter filter;
+        public final Handler scheduler;
+
+        // Exceptions thrown in a background thread kill the whole test. Save them instead.
+        public final AtomicReference<Exception> backgroundException = new AtomicReference<>();
+
+        public BroadcastReceiverRegistration(BroadcastReceiver receiver, IntentFilter filter,
+                Handler scheduler) {
+            this.receiver = receiver;
+            this.filter = filter;
+            this.scheduler = scheduler;
+        }
+
+        public void sendBroadcastIfApplicable(Context context, int userId, Intent intent) {
+            final BroadcastReceiver.PendingResult result = new BroadcastReceiver.PendingResult(
+                    0 /* resultCode */, null /* resultData */, null /* resultExtras */,
+                    0 /* type */, false /* ordered */, false /* sticky */, null /* token */, userId,
+                    0 /* flags */);
+            if (filter.match(null, intent, false, "DpmMockContext") > 0) {
+                final Runnable send = () -> {
+                    receiver.setPendingResult(result);
+                    receiver.onReceive(context, intent);
+                };
+                if (scheduler != null) {
+                    scheduler.post(() -> {
+                        try {
+                            send.run();
+                        } catch (Exception e) {
+                            backgroundException.compareAndSet(null, e);
+                        }
+                    });
+                } else {
+                    send.run();
+                }
+            }
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
index 423c4d5..85835f7 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
@@ -20,6 +20,7 @@
 
 import android.content.ComponentName;
 import android.os.UserHandle;
+import android.test.suitebuilder.annotation.SmallTest;
 
 /**
  * Tests for the DeviceOwner object that saves & loads device and policy owner information.
@@ -32,13 +33,14 @@
 
  (mmma frameworks/base/services/tests/servicestests/ for non-ninja build)
  */
+@SmallTest
 public class OwnersTest extends DpmTestBase {
     public void testUpgrade01() throws Exception {
-        getContext().addUsers(10, 11, 20, 21);
+        getServices().addUsers(10, 11, 20, 21);
 
         // First, migrate.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
 
             DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
                     DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test01/input.xml"));
@@ -70,7 +72,7 @@
 
         // Then re-read and check.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
@@ -87,11 +89,11 @@
     }
 
     public void testUpgrade02() throws Exception {
-        getContext().addUsers(10, 11, 20, 21);
+        getServices().addUsers(10, 11, 20, 21);
 
         // First, migrate.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
 
             DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
                     DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test02/input.xml"));
@@ -125,7 +127,7 @@
 
         // Then re-read and check.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertTrue(owners.hasDeviceOwner());
@@ -145,11 +147,11 @@
     }
 
     public void testUpgrade03() throws Exception {
-        getContext().addUsers(10, 11, 20, 21);
+        getServices().addUsers(10, 11, 20, 21);
 
         // First, migrate.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
 
             DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
                     DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test03/input.xml"));
@@ -191,7 +193,7 @@
 
         // Then re-read and check.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
@@ -223,11 +225,11 @@
      * and {@link  Owners#setProfileOwnerUserRestrictionsMigrated(int)}.
      */
     public void testUpgrade04() throws Exception {
-        getContext().addUsers(10, 11, 20, 21);
+        getServices().addUsers(10, 11, 20, 21);
 
         // First, migrate.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
 
             DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
                     DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test04/input.xml"));
@@ -273,7 +275,7 @@
 
         // Then re-read and check.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertTrue(owners.hasDeviceOwner());
@@ -306,7 +308,7 @@
         }
 
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
@@ -319,7 +321,7 @@
         }
 
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
@@ -333,11 +335,11 @@
     }
 
     public void testUpgrade05() throws Exception {
-        getContext().addUsers(10, 11, 20, 21);
+        getServices().addUsers(10, 11, 20, 21);
 
         // First, migrate.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
 
             DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
                     DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test05/input.xml"));
@@ -370,7 +372,7 @@
 
         // Then re-read and check.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
@@ -389,11 +391,11 @@
     }
 
     public void testUpgrade06() throws Exception {
-        getContext().addUsers(10, 11, 20, 21);
+        getServices().addUsers(10, 11, 20, 21);
 
         // First, migrate.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
 
             DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
                     DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test06/input.xml"));
@@ -425,7 +427,7 @@
 
         // Then re-read and check.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
@@ -444,9 +446,9 @@
     }
 
     public void testRemoveExistingFiles() throws Exception {
-        getContext().addUsers(10, 11, 20, 21);
+        getServices().addUsers(10, 11, 20, 21);
 
-        final OwnersTestable owners = new OwnersTestable(getContext());
+        final OwnersTestable owners = new OwnersTestable(getServices());
 
         // First, migrate to create new-style config files.
         DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
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 c399a5d..61df22e 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -29,8 +29,11 @@
 import android.view.WindowManagerInternal;
 
 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 org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
@@ -44,35 +47,51 @@
 
 @SmallTest
 public class DisplayManagerServiceTest extends AndroidTestCase {
-    private Handler mHandler;
-    private DisplayManagerService mDisplayManager;
+    private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
+    private static final long SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS = 10;
+
+    private final DisplayManagerService.Injector mShortMockedInjector =
+            new DisplayManagerService.Injector() {
+                @Override
+                VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
+                        Context context, Handler handler, DisplayAdapter.Listener listener) {
+                    return mMockVirtualDisplayAdapter;
+                }
+
+                @Override
+                long getDefaultDisplayDelayTimeout() {
+                    return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS;
+                }
+            };
+    private final DisplayManagerService.Injector mBasicInjector =
+            new DisplayManagerService.Injector() {
+                @Override
+                VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
+                        Context context, Handler handler,
+                        DisplayAdapter.Listener displayAdapterListener) {
+                    return new VirtualDisplayAdapter(syncRoot, context, handler,
+                            displayAdapterListener,
+                            (String name, boolean secure) -> mMockDisplayToken);
+                }
+            };
+
     @Mock InputManagerInternal mMockInputManagerInternal;
     @Mock IVirtualDisplayCallback.Stub mMockAppToken;
     @Mock WindowManagerInternal mMockWindowManagerInternal;
+    @Mock LightsManager mMockLightsManager;
     @Mock VirtualDisplayAdapter mMockVirtualDisplayAdapter;
     @Mock IBinder mMockDisplayToken;
 
     @Override
     protected void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mDisplayManager = new DisplayManagerService(mContext,
-        new DisplayManagerService.Injector() {
-            @Override
-            VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
-                    Handler handler, DisplayAdapter.Listener displayAdapterListener) {
-                return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener,
-                        (String name, boolean secure) -> mMockDisplayToken);
-            }
-        });
-        mHandler = mDisplayManager.getDisplayHandler();
 
         LocalServices.removeServiceForTest(InputManagerInternal.class);
         LocalServices.addService(InputManagerInternal.class, mMockInputManagerInternal);
         LocalServices.removeServiceForTest(WindowManagerInternal.class);
         LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerInternal);
-
-        mDisplayManager.systemReady(false /* safeMode */, false /* onlyCore */);
-        mDisplayManager.windowManagerAndInputReady();
+        LocalServices.removeServiceForTest(LightsManager.class);
+        LocalServices.addService(LightsManager.class, mMockLightsManager);
         super.setUp();
     }
 
@@ -82,8 +101,14 @@
     }
 
     public void testCreateVirtualDisplay_sentToInputManager() throws Exception {
+        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 = mDisplayManager.new BinderService();
+        DisplayManagerService.BinderService bs = displayManager.new BinderService();
 
         String uniqueId = "uniqueId --- Test";
         String uniqueIdPrefix = "virtual:" + mContext.getPackageName() + ":";
@@ -98,10 +123,10 @@
                 "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */,
                 uniqueId);
 
-        mDisplayManager.performTraversalInTransactionFromWindowManagerInternal();
+        displayManager.performTraversalInTransactionFromWindowManagerInternal();
 
         // flush the handler
-        mHandler.runWithScissors(() -> {}, 0 /* now */);
+        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
 
         ArgumentCaptor<List<DisplayViewport>> virtualViewportCaptor =
                 ArgumentCaptor.forClass(List.class);
@@ -115,4 +140,97 @@
         assertEquals(uniqueIdPrefix + uniqueId, dv.uniqueId);
         assertEquals(displayId, dv.displayId);
     }
+
+    public void testCreateVirtualDisplayRotatesWithContent() throws Exception {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mBasicInjector);
+        registerDefaultDisplays(displayManager);
+
+        // This is effectively the DisplayManager service published to ServiceManager.
+        DisplayManagerService.BinderService bs = displayManager.new BinderService();
+
+        String uniqueId = "uniqueId --- Rotates With Content Test";
+        int width = 600;
+        int height = 800;
+        int dpi = 320;
+        int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
+
+        when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+        int displayId = bs.createVirtualDisplay(mMockAppToken /* callback */,
+                null /* projection */, "com.android.frameworks.servicestests",
+                "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */,
+                uniqueId);
+
+        displayManager.performTraversalInTransactionFromWindowManagerInternal();
+
+        // flush the handler
+        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
+
+        DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
+        assertNotNull(ddi);
+        assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0);
+    }
+
+    /**
+     * Tests that the virtual display is created along-side the default display.
+     */
+    public void testStartVirtualDisplayWithDefaultDisplay_Succeeds() throws Exception {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mShortMockedInjector);
+        registerDefaultDisplays(displayManager);
+        displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
+    }
+
+    /**
+     * Tests that we get a Runtime exception when we cannot initialize the default display.
+     */
+    public void testStartVirtualDisplayWithDefDisplay_NoDefaultDisplay() throws Exception {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mShortMockedInjector);
+        Handler handler = displayManager.getDisplayHandler();
+        handler.runWithScissors(() -> {}, 0 /* now */);
+
+        try {
+            displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
+        } catch (RuntimeException e) {
+            return;
+        }
+        fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the"
+                + " default display");
+    }
+
+    /**
+     * Tests that we get a Runtime exception when we cannot initialize the virtual display.
+     */
+    public void testStartVirtualDisplayWithDefDisplay_NoVirtualDisplayAdapter() throws Exception {
+        DisplayManagerService displayManager = new DisplayManagerService(mContext,
+                new DisplayManagerService.Injector() {
+                    @Override
+                    VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
+                            Context context, Handler handler, DisplayAdapter.Listener listener) {
+                        return null;  // return null for the adapter.  This should cause a failure.
+                    }
+
+                    @Override
+                    long getDefaultDisplayDelayTimeout() {
+                        return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS;
+                    }
+                });
+        try {
+            displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
+        } catch (RuntimeException e) {
+            return;
+        }
+        fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the"
+                + " virtual display adapter");
+    }
+
+    private void registerDefaultDisplays(DisplayManagerService displayManager) {
+        Handler handler = displayManager.getDisplayHandler();
+        // Would prefer to call displayManager.onStart() directly here but it performs binderService
+        // registration which triggers security exceptions when running from a test.
+        handler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
+        // flush the handler
+        handler.runWithScissors(() -> {}, 0 /* now */);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
index 33e1a16..689c8f7 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
@@ -206,7 +206,8 @@
                 invalidLateRuntimeElapsedMillis - TWO_HOURS;  // Early is (late - period).
         final JobStatus js = new JobStatus(b.build(), SOME_UID, "somePackage",
                 0 /* sourceUserId */, "someTag",
-                invalidEarlyRuntimeElapsedMillis, invalidLateRuntimeElapsedMillis);
+                invalidEarlyRuntimeElapsedMillis, invalidLateRuntimeElapsedMillis,
+                0 /* lastSuccessfulRunTime */, 0 /* lastFailedRunTime */);
 
         mTaskStoreUnderTest.add(js);
         Thread.sleep(IO_WAIT);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
new file mode 100644
index 0000000..84cca0e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
@@ -0,0 +1,166 @@
+/*
+ * 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.server.locksettings;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.IActivityManager;
+import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.pm.UserInfo;
+import android.os.FileUtils;
+import android.os.IProgressListener;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+import android.security.KeyStore;
+import android.test.AndroidTestCase;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+
+public class BaseLockSettingsServiceTests extends AndroidTestCase {
+    protected static final int PRIMARY_USER_ID = 0;
+    protected static final int MANAGED_PROFILE_USER_ID = 12;
+    protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
+    protected static final int SECONDARY_USER_ID = 20;
+
+    private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER_ID, null, null,
+            UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
+    private static final UserInfo SECONDARY_USER_INFO = new UserInfo(SECONDARY_USER_ID, null, null,
+            UserInfo.FLAG_INITIALIZED);
+
+    private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
+
+    LockSettingsService mService;
+
+    MockLockSettingsContext mContext;
+    LockSettingsStorageTestable mStorage;
+
+    LockPatternUtils mLockPatternUtils;
+    MockGateKeeperService mGateKeeperService;
+    NotificationManager mNotificationManager;
+    UserManager mUserManager;
+    MockStorageManager mStorageManager;
+    IActivityManager mActivityManager;
+    DevicePolicyManager mDevicePolicyManager;
+    KeyStore mKeyStore;
+    MockSyntheticPasswordManager mSpManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mLockPatternUtils = mock(LockPatternUtils.class);
+        mGateKeeperService = new MockGateKeeperService();
+        mNotificationManager = mock(NotificationManager.class);
+        mUserManager = mock(UserManager.class);
+        mStorageManager = new MockStorageManager();
+        mActivityManager = mock(IActivityManager.class);
+        mDevicePolicyManager = mock(DevicePolicyManager.class);
+
+        mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager,
+                mDevicePolicyManager, mock(StorageManager.class));
+        mStorage = new LockSettingsStorageTestable(mContext,
+                new File(getContext().getFilesDir(), "locksettings"));
+        File storageDir = mStorage.mStorageDir;
+        if (storageDir.exists()) {
+            FileUtils.deleteContents(storageDir);
+        } else {
+            storageDir.mkdirs();
+        }
+
+        mSpManager = new MockSyntheticPasswordManager(mStorage, mGateKeeperService, mUserManager);
+        mService = new LockSettingsServiceTestable(mContext, mLockPatternUtils,
+                mStorage, mGateKeeperService, mKeyStore, mStorageManager, mActivityManager,
+                mSpManager);
+        when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO);
+        mPrimaryUserProfiles.add(PRIMARY_USER_INFO);
+        installChildProfile(MANAGED_PROFILE_USER_ID);
+        installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
+        when(mUserManager.getUsers(anyBoolean())).thenReturn(mPrimaryUserProfiles);
+        when(mUserManager.getProfiles(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserProfiles);
+        when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO);
+
+        when(mActivityManager.unlockUser(anyInt(), any(), any(), any())).thenAnswer(
+                new Answer<Boolean>() {
+            @Override
+            public Boolean answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                mStorageManager.unlockUser((int)args[0], (byte[])args[2],
+                        (IProgressListener) args[3]);
+                return true;
+            }
+        });
+
+        when(mLockPatternUtils.getLockSettings()).thenReturn(mService);
+
+        // Adding a fake Device Owner app which will enable escrow token support in LSS.
+        when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(
+                new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
+    }
+
+    private UserInfo installChildProfile(int profileId) {
+        final UserInfo userInfo = new UserInfo(
+            profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE);
+        mPrimaryUserProfiles.add(userInfo);
+        when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
+        when(mUserManager.getProfileParent(eq(profileId))).thenReturn(PRIMARY_USER_INFO);
+        when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true);
+        when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true);
+        return userInfo;
+    }
+
+    private UserInfo installAndTurnOffChildProfile(int profileId) {
+        final UserInfo userInfo = installChildProfile(profileId);
+        userInfo.flags |= UserInfo.FLAG_QUIET_MODE;
+        when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false);
+        when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false);
+        return userInfo;
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mStorage.closeDatabase();
+        File db = getContext().getDatabasePath("locksettings.db");
+        assertTrue(!db.exists() || db.delete());
+
+        File storageDir = mStorage.mStorageDir;
+        assertTrue(FileUtils.deleteContents(storageDir));
+    }
+
+    protected static void assertArrayEquals(byte[] expected, byte[] actual) {
+        assertTrue(Arrays.equals(expected, actual));
+    }
+
+    protected static void assertArrayNotSame(byte[] expected, byte[] actual) {
+        assertFalse(Arrays.equals(expected, actual));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
new file mode 100644
index 0000000..3a4aa2d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -0,0 +1,140 @@
+/*
+ * 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.locksettings;
+
+import static org.mockito.Mockito.mock;
+
+import android.app.IActivityManager;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.storage.IStorageManager;
+import android.security.KeyStore;
+import android.security.keystore.KeyPermanentlyInvalidatedException;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import java.io.FileNotFoundException;
+
+public class LockSettingsServiceTestable extends LockSettingsService {
+
+    private static class MockInjector extends LockSettingsService.Injector {
+
+        private LockSettingsStorage mLockSettingsStorage;
+        private KeyStore mKeyStore;
+        private IActivityManager mActivityManager;
+        private LockPatternUtils mLockPatternUtils;
+        private IStorageManager mStorageManager;
+        private SyntheticPasswordManager mSpManager;
+
+        public MockInjector(Context context, LockSettingsStorage storage, KeyStore keyStore,
+                IActivityManager activityManager, LockPatternUtils lockPatternUtils,
+                IStorageManager storageManager, SyntheticPasswordManager spManager) {
+            super(context);
+            mLockSettingsStorage = storage;
+            mKeyStore = keyStore;
+            mActivityManager = activityManager;
+            mLockPatternUtils = lockPatternUtils;
+            mStorageManager = storageManager;
+            mSpManager = spManager;
+        }
+
+        @Override
+        public Handler getHandler() {
+            return mock(Handler.class);
+        }
+
+        @Override
+        public LockSettingsStorage getStorage() {
+            return mLockSettingsStorage;
+        }
+
+        @Override
+        public LockSettingsStrongAuth getStrongAuth() {
+            return mock(LockSettingsStrongAuth.class);
+        }
+
+        @Override
+        public SynchronizedStrongAuthTracker getStrongAuthTracker() {
+            return mock(SynchronizedStrongAuthTracker.class);
+        }
+
+        @Override
+        public IActivityManager getActivityManager() {
+            return mActivityManager;
+        }
+
+        @Override
+        public LockPatternUtils getLockPatternUtils() {
+            return mLockPatternUtils;
+        }
+
+        @Override
+        public KeyStore getKeyStore() {
+            return mKeyStore;
+        }
+
+        @Override
+        public IStorageManager getStorageManager() {
+            return mStorageManager;
+        }
+
+        @Override
+        public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) {
+            return mSpManager;
+        }
+
+        @Override
+        public int binderGetCallingUid() {
+            return Process.SYSTEM_UID;
+        }
+
+
+    }
+
+    protected LockSettingsServiceTestable(Context context, LockPatternUtils lockPatternUtils,
+            LockSettingsStorage storage, MockGateKeeperService gatekeeper, KeyStore keystore,
+            IStorageManager storageManager, IActivityManager mActivityManager,
+            SyntheticPasswordManager spManager) {
+        super(new MockInjector(context, storage, keystore, mActivityManager, lockPatternUtils,
+                storageManager, spManager));
+        mGateKeeperService = gatekeeper;
+    }
+
+    @Override
+    protected void tieProfileLockToParent(int userId, String password) {
+        mStorage.writeChildProfileLock(userId, password.getBytes());
+    }
+
+    @Override
+    protected String getDecryptedPasswordForTiedProfile(int userId) throws FileNotFoundException,
+            KeyPermanentlyInvalidatedException {
+        byte[] storedData = mStorage.readChildProfileLock(userId);
+        if (storedData == null) {
+            throw new FileNotFoundException("Child profile lock file not found");
+        }
+        try {
+            if (mGateKeeperService.getSecureUserId(userId) == 0) {
+                throw new KeyPermanentlyInvalidatedException();
+            }
+        } catch (RemoteException e) {
+            // shouldn't happen.
+        }
+        return new String(storedData);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
new file mode 100644
index 0000000..cb32492
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -0,0 +1,254 @@
+/*
+ * 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.server.locksettings;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+
+import android.os.RemoteException;
+import android.service.gatekeeper.GateKeeperResponse;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.VerifyCredentialResponse;
+import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
+import com.android.server.locksettings.MockGateKeeperService.VerifyHandle;
+
+/**
+ * runtest frameworks-services -c com.android.server.locksettings.LockSettingsServiceTests
+ */
+public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testCreatePasswordPrimaryUser() throws RemoteException {
+        testCreateCredential(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD,
+                PASSWORD_QUALITY_ALPHABETIC);
+    }
+
+    public void testCreatePatternPrimaryUser() throws RemoteException {
+        testCreateCredential(PRIMARY_USER_ID, "123456789", CREDENTIAL_TYPE_PATTERN,
+                PASSWORD_QUALITY_SOMETHING);
+    }
+
+    public void testChangePasswordPrimaryUser() throws RemoteException {
+        testChangeCredentials(PRIMARY_USER_ID, "78963214", CREDENTIAL_TYPE_PATTERN,
+                "asdfghjk", CREDENTIAL_TYPE_PASSWORD, PASSWORD_QUALITY_ALPHABETIC);
+    }
+
+    public void testChangePatternPrimaryUser() throws RemoteException {
+        testChangeCredentials(PRIMARY_USER_ID, "!£$%^&*(())", CREDENTIAL_TYPE_PASSWORD,
+                "1596321", CREDENTIAL_TYPE_PATTERN, PASSWORD_QUALITY_SOMETHING);
+    }
+
+    public void testChangePasswordFailPrimaryUser() throws RemoteException {
+        final long sid = 1234;
+        final String FAILED_MESSAGE = "Failed to enroll password";
+        initializeStorageWithCredential(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid);
+
+        try {
+            mService.setLockCredential("newpwd", CREDENTIAL_TYPE_PASSWORD, "badpwd",
+                    PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+            fail("Did not fail when enrolling using incorrect credential");
+        } catch (RemoteException expected) {
+            assertTrue(expected.getMessage().equals(FAILED_MESSAGE));
+        }
+        try {
+            mService.setLockCredential("newpwd", CREDENTIAL_TYPE_PASSWORD, null,
+                    PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+            fail("Did not fail when enrolling using incorrect credential");
+        } catch (RemoteException expected) {
+            assertTrue(expected.getMessage().equals(FAILED_MESSAGE));
+        }
+        assertVerifyCredentials(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid);
+    }
+
+    public void testClearPasswordPrimaryUser() throws RemoteException {
+        final String PASSWORD = "password";
+        initializeStorageWithCredential(PRIMARY_USER_ID, PASSWORD, CREDENTIAL_TYPE_PASSWORD, 1234);
+        mService.setLockCredential(null, CREDENTIAL_TYPE_NONE, PASSWORD,
+                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+        assertFalse(mService.havePassword(PRIMARY_USER_ID));
+        assertFalse(mService.havePattern(PRIMARY_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+    }
+
+    public void testManagedProfileUnifiedChallenge() throws RemoteException {
+        final String UnifiedPassword = "testManagedProfileUnifiedChallenge-pwd";
+        mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID);
+        mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
+        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
+        final long turnedOffProfileSid =
+                mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID);
+        assertTrue(primarySid != 0);
+        assertTrue(profileSid != 0);
+        assertTrue(profileSid != primarySid);
+        assertTrue(turnedOffProfileSid != 0);
+        assertTrue(turnedOffProfileSid != primarySid);
+        assertTrue(turnedOffProfileSid != profileSid);
+
+        // clear auth token and wait for verify challenge from primary user to re-generate it.
+        mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
+        mGateKeeperService.clearAuthToken(TURNED_OFF_PROFILE_USER_ID);
+        // verify credential
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
+                UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
+                .getResponseCode());
+
+        // Verify that we have a new auth token for the profile
+        assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+
+        // Verify that profile which aren't running (e.g. turn off work) don't get unlocked
+        assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
+
+        /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
+         * credential as part of verifyCredential() before the new credential is committed in
+         * StorageManager. So we relax the check in our mock StorageManager to allow that.
+         */
+        mStorageManager.setIgnoreBadUnlock(true);
+        // Change primary password and verify that profile SID remains
+        mService.setLockCredential("pwd", LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                UnifiedPassword, PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        mStorageManager.setIgnoreBadUnlock(false);
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+        assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
+
+        // Clear unified challenge
+        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, UnifiedPassword,
+                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID));
+    }
+
+    public void testManagedProfileSeparateChallenge() throws RemoteException {
+        final String primaryPassword = "testManagedProfileSeparateChallenge-primary";
+        final String profilePassword = "testManagedProfileSeparateChallenge-profile";
+        mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID);
+        /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
+         * credential as part of verifyCredential() before the new credential is committed in
+         * StorageManager. So we relax the check in our mock StorageManager to allow that.
+         */
+        mStorageManager.setIgnoreBadUnlock(true);
+        mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_COMPLEX, MANAGED_PROFILE_USER_ID);
+        mStorageManager.setIgnoreBadUnlock(false);
+
+        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
+        assertTrue(primarySid != 0);
+        assertTrue(profileSid != 0);
+        assertTrue(profileSid != primarySid);
+
+        // clear auth token and make sure verify challenge from primary user does not regenerate it.
+        mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
+        // verify primary credential
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
+                primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
+                .getResponseCode());
+        assertNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
+
+        // verify profile credential
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
+                profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
+                MANAGED_PROFILE_USER_ID).getResponseCode());
+        assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+
+        // Change primary credential and make sure we don't affect profile
+        mStorageManager.setIgnoreBadUnlock(true);
+        mService.setLockCredential("pwd", LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                primaryPassword, PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        mStorageManager.setIgnoreBadUnlock(false);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
+                profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
+                MANAGED_PROFILE_USER_ID).getResponseCode());
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+    }
+
+    private void testCreateCredential(int userId, String credential, int type, int quality)
+            throws RemoteException {
+        mService.setLockCredential(credential, type, null, quality, userId);
+        assertVerifyCredentials(userId, credential, type, -1);
+    }
+
+    private void testChangeCredentials(int userId, String newCredential, int newType,
+            String oldCredential, int oldType, int quality) throws RemoteException {
+        final long sid = 1234;
+        initializeStorageWithCredential(userId, oldCredential, oldType, sid);
+        mService.setLockCredential(newCredential, newType, oldCredential, quality, userId);
+        assertVerifyCredentials(userId, newCredential, newType, sid);
+    }
+
+    private void assertVerifyCredentials(int userId, String credential, int type, long sid)
+            throws RemoteException{
+        final long challenge = 54321;
+        VerifyCredentialResponse response = mService.verifyCredential(credential, type, challenge,
+                userId);
+
+        assertEquals(GateKeeperResponse.RESPONSE_OK, response.getResponseCode());
+        if (sid != -1) assertEquals(sid, mGateKeeperService.getSecureUserId(userId));
+        final int incorrectType;
+        if (type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
+            assertTrue(mService.havePassword(userId));
+            assertFalse(mService.havePattern(userId));
+            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+        } else if (type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN){
+            assertFalse(mService.havePassword(userId));
+            assertTrue(mService.havePattern(userId));
+            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+        } else {
+            assertFalse(mService.havePassword(userId));
+            assertFalse(mService.havePassword(userId));
+            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+        }
+        // check for bad type
+        assertEquals(GateKeeperResponse.RESPONSE_ERROR, mService.verifyCredential(credential,
+                incorrectType, challenge, userId).getResponseCode());
+        // check for bad credential
+        assertEquals(GateKeeperResponse.RESPONSE_ERROR, mService.verifyCredential("0" + credential,
+                type, challenge, userId).getResponseCode());
+    }
+
+    private void initializeStorageWithCredential(int userId, String credential, int type, long sid) {
+        byte[] oldHash = new VerifyHandle(credential.getBytes(), sid).toBytes();
+        if (type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
+            mStorage.writeCredentialHash(CredentialHash.create(oldHash,
+                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
+        } else {
+            mStorage.writeCredentialHash(CredentialHash.create(oldHash,
+                    LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
new file mode 100644
index 0000000..424c08c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
@@ -0,0 +1,142 @@
+/*
+ * 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.server.locksettings;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
+
+import static com.android.internal.widget.LockPatternUtils.stringToPattern;
+
+import static junit.framework.Assert.*;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import static java.io.FileDescriptor.*;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.Binder;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.FileDescriptor;
+
+/**
+ * Test class for {@link LockSettingsShellCommand}.
+ *
+ * runtest frameworks-services -c com.android.server.locksettings.LockSettingsShellCommandTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class LockSettingsShellCommandTest {
+
+    private LockSettingsShellCommand mCommand;
+
+    private @Mock LockPatternUtils mLockPatternUtils;
+    private int mUserId;
+    private final Binder mBinder = new Binder();
+    private final ShellCallback mShellCallback = new ShellCallback();
+    private final ResultReceiver mResultReceiver = new ResultReceiver(
+            new Handler(Looper.getMainLooper()));
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        final Context context = InstrumentationRegistry.getTargetContext();
+        mUserId = ActivityManager.getCurrentUser();
+        mCommand = new LockSettingsShellCommand(context, mLockPatternUtils);
+    }
+
+    @Test
+    public void testWrongPassword() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(false);
+        assertEquals(-1, mCommand.exec(mBinder, in, out, err,
+                new String[] { "set-pin", "--old", "1234" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils, never()).saveLockPassword(any(), any(), anyInt(), anyInt());
+    }
+
+    @Test
+    public void testChangePin() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(true);
+        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
+                new String[] { "set-pin", "--old", "1234", "4321" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils).saveLockPassword("4321", "1234", PASSWORD_QUALITY_NUMERIC,
+                mUserId);
+    }
+
+    @Test
+    public void testChangePassword() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(true);
+        assertEquals(0,  mCommand.exec(new Binder(), in, out, err,
+                new String[] { "set-password", "--old", "1234", "4321" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils).saveLockPassword("4321", "1234", PASSWORD_QUALITY_ALPHABETIC,
+                mUserId);
+    }
+
+    @Test
+    public void testChangePattern() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.checkPattern(stringToPattern("1234"), mUserId)).thenReturn(true);
+        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
+                new String[] { "set-pattern", "--old", "1234", "4321" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils).saveLockPattern(stringToPattern("4321"), "1234", mUserId);
+    }
+
+    @Test
+    public void testClear() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.checkPattern(stringToPattern("1234"), mUserId)).thenReturn(true);
+        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
+                new String[] { "clear", "--old", "1234" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils).clearLock("1234", mUserId);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
new file mode 100644
index 0000000..4bdd1c5
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
@@ -0,0 +1,66 @@
+/*
+ * 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.locksettings;
+
+import android.content.Context;
+
+import java.io.File;
+
+public class LockSettingsStorageTestable extends LockSettingsStorage {
+
+    public File mStorageDir;
+
+    public LockSettingsStorageTestable(Context context, File storageDir) {
+        super(context);
+        mStorageDir = storageDir;
+    }
+
+    @Override
+    String getLockPatternFilename(int userId) {
+        return makeDirs(mStorageDir,
+                super.getLockPatternFilename(userId)).getAbsolutePath();
+    }
+
+    @Override
+    String getLockPasswordFilename(int userId) {
+        return makeDirs(mStorageDir,
+                super.getLockPasswordFilename(userId)).getAbsolutePath();
+    }
+
+    @Override
+    String getChildProfileLockFile(int userId) {
+        return makeDirs(mStorageDir,
+                super.getChildProfileLockFile(userId)).getAbsolutePath();
+    }
+
+    @Override
+    protected File getSyntheticPasswordDirectoryForUser(int userId) {
+        return makeDirs(mStorageDir, super.getSyntheticPasswordDirectoryForUser(
+                userId).getAbsolutePath());
+    }
+
+    private File makeDirs(File baseDir, String filePath) {
+        File path = new File(filePath);
+        if (path.getParent() == null) {
+            return new File(baseDir, filePath);
+        } else {
+            File mappedDir = new File(baseDir, path.getParent());
+            mappedDir.mkdirs();
+            return new File(mappedDir, path.getName());
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
new file mode 100644
index 0000000..a0578c9
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.pm.UserInfo;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.FileUtils;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+import android.test.AndroidTestCase;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
+import com.android.server.locksettings.LockSettingsStorage.PersistentData;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * runtest frameworks-services -c com.android.server.locksettings.LockSettingsStorageTests
+ */
+public class LockSettingsStorageTests extends AndroidTestCase {
+    private static final int SOME_USER_ID = 1034;
+    private final byte[] PASSWORD_0 = "thepassword0".getBytes();
+    private final byte[] PASSWORD_1 = "password1".getBytes();
+    private final byte[] PATTERN_0 = "123654".getBytes();
+    private final byte[] PATTERN_1 = "147852369".getBytes();
+
+    public static final byte[] PAYLOAD = new byte[] {1, 2, -1, -2, 33};
+
+    LockSettingsStorage mStorage;
+    File mStorageDir;
+
+    private File mDb;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mStorageDir = new File(getContext().getFilesDir(), "locksettings");
+        mDb = getContext().getDatabasePath("locksettings.db");
+
+        assertTrue(mStorageDir.exists() || mStorageDir.mkdirs());
+        assertTrue(FileUtils.deleteContents(mStorageDir));
+        assertTrue(!mDb.exists() || mDb.delete());
+
+        final UserManager mockUserManager = mock(UserManager.class);
+        // User 2 is a profile of user 1.
+        when(mockUserManager.getProfileParent(eq(2))).thenReturn(new UserInfo(1, "name", 0));
+        // User 3 is a profile of user 0.
+        when(mockUserManager.getProfileParent(eq(3))).thenReturn(new UserInfo(0, "name", 0));
+
+        MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager,
+                mock(NotificationManager.class), mock(DevicePolicyManager.class),
+                mock(StorageManager.class));
+        mStorage = new LockSettingsStorageTestable(context,
+                new File(getContext().getFilesDir(), "locksettings"));
+        mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
+                    @Override
+                    public void initialize(SQLiteDatabase db) {
+                        mStorage.writeKeyValue(db, "initializedKey", "initialValue", 0);
+                    }
+                });
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mStorage.closeDatabase();
+    }
+
+    public void testKeyValue_InitializeWorked() {
+        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
+        mStorage.clearCache();
+        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
+    }
+
+    public void testKeyValue_WriteThenRead() {
+        mStorage.writeKeyValue("key", "value", 0);
+        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
+        mStorage.clearCache();
+        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
+    }
+
+    public void testKeyValue_DefaultValue() {
+        assertEquals("default", mStorage.readKeyValue("unititialized key", "default", 0));
+        assertEquals("default2", mStorage.readKeyValue("unititialized key", "default2", 0));
+    }
+
+    public void testKeyValue_Concurrency() {
+        final Object monitor = new Object();
+        List<Thread> threads = new ArrayList<>();
+        for (int i = 0; i < 100; i++) {
+            final int threadId = i;
+            threads.add(new Thread() {
+                @Override
+                public void run() {
+                    synchronized (monitor) {
+                        try {
+                            monitor.wait();
+                        } catch (InterruptedException e) {
+                            return;
+                        }
+                        mStorage.writeKeyValue("key", "1 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                        mStorage.writeKeyValue("key", "2 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                        mStorage.writeKeyValue("key", "3 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                        mStorage.writeKeyValue("key", "4 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                        mStorage.writeKeyValue("key", "5 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                    }
+                }
+            });
+            threads.get(i).start();
+        }
+        mStorage.writeKeyValue("key", "initalValue", 0);
+        synchronized (monitor) {
+            monitor.notifyAll();
+        }
+        for (int i = 0; i < threads.size(); i++) {
+            try {
+                threads.get(i).join();
+            } catch (InterruptedException e) {
+            }
+        }
+        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
+        mStorage.clearCache();
+        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
+    }
+
+    public void testKeyValue_CacheStarvedWriter() {
+        final CountDownLatch latch = new CountDownLatch(1);
+        List<Thread> threads = new ArrayList<>();
+        for (int i = 0; i < 100; i++) {
+            final int threadId = i;
+            threads.add(new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        latch.await();
+                    } catch (InterruptedException e) {
+                        return;
+                    }
+                    if (threadId == 50) {
+                        mStorage.writeKeyValue("starvedWriterKey", "value", 0);
+                    } else {
+                        mStorage.readKeyValue("starvedWriterKey", "default", 0);
+                    }
+                }
+            });
+            threads.get(i).start();
+        }
+        latch.countDown();
+        for (int i = 0; i < threads.size(); i++) {
+            try {
+                threads.get(i).join();
+            } catch (InterruptedException e) {
+            }
+        }
+        String cached = mStorage.readKeyValue("key", "default", 0);
+        mStorage.clearCache();
+        String storage = mStorage.readKeyValue("key", "default", 0);
+        assertEquals("Cached value didn't match stored value", storage, cached);
+    }
+
+    public void testRemoveUser() {
+        mStorage.writeKeyValue("key", "value", 0);
+        writePasswordBytes(PASSWORD_0, 0);
+        writePatternBytes(PATTERN_0, 0);
+
+        mStorage.writeKeyValue("key", "value", 1);
+        writePasswordBytes(PASSWORD_1, 1);
+        writePatternBytes(PATTERN_1, 1);
+
+        mStorage.removeUser(0);
+
+        assertEquals("value", mStorage.readKeyValue("key", "default", 1));
+        assertEquals("default", mStorage.readKeyValue("key", "default", 0));
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_NONE, mStorage.readCredentialHash(0).type);
+        assertPatternBytes(PATTERN_1, 1);
+    }
+
+    public void testCredential_Default() {
+        assertEquals(mStorage.readCredentialHash(0).type, LockPatternUtils.CREDENTIAL_TYPE_NONE);
+    }
+
+    public void testPassword_Write() {
+        writePasswordBytes(PASSWORD_0, 0);
+
+        assertPasswordBytes(PASSWORD_0, 0);
+        mStorage.clearCache();
+        assertPasswordBytes(PASSWORD_0, 0);
+    }
+
+    public void testPassword_WriteProfileWritesParent() {
+        writePasswordBytes(PASSWORD_0, 1);
+        writePasswordBytes(PASSWORD_1, 2);
+
+        assertPasswordBytes(PASSWORD_0, 1);
+        assertPasswordBytes(PASSWORD_1, 2);
+        mStorage.clearCache();
+        assertPasswordBytes(PASSWORD_0, 1);
+        assertPasswordBytes(PASSWORD_1, 2);
+    }
+
+    public void testLockType_WriteProfileWritesParent() {
+        writePasswordBytes(PASSWORD_0, 10);
+        writePatternBytes(PATTERN_0, 20);
+
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                mStorage.readCredentialHash(10).type);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                mStorage.readCredentialHash(20).type);
+        mStorage.clearCache();
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                mStorage.readCredentialHash(10).type);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                mStorage.readCredentialHash(20).type);
+    }
+
+    public void testPassword_WriteParentWritesProfile() {
+        writePasswordBytes(PASSWORD_0, 2);
+        writePasswordBytes(PASSWORD_1, 1);
+
+        assertPasswordBytes(PASSWORD_1, 1);
+        assertPasswordBytes(PASSWORD_0, 2);
+        mStorage.clearCache();
+        assertPasswordBytes(PASSWORD_1, 1);
+        assertPasswordBytes(PASSWORD_0, 2);
+    }
+
+    public void testProfileLock_ReadWriteChildProfileLock() {
+        assertFalse(mStorage.hasChildProfileLock(20));
+        mStorage.writeChildProfileLock(20, PASSWORD_0);
+        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
+        assertTrue(mStorage.hasChildProfileLock(20));
+        mStorage.clearCache();
+        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
+        assertTrue(mStorage.hasChildProfileLock(20));
+    }
+
+    public void testPattern_Write() {
+        writePatternBytes(PATTERN_0, 0);
+
+        assertPatternBytes(PATTERN_0, 0);
+        mStorage.clearCache();
+        assertPatternBytes(PATTERN_0, 0);
+    }
+
+    public void testPattern_WriteProfileWritesParent() {
+        writePatternBytes(PATTERN_0, 1);
+        writePatternBytes(PATTERN_1, 2);
+
+        assertPatternBytes(PATTERN_0, 1);
+        assertPatternBytes(PATTERN_1, 2);
+        mStorage.clearCache();
+        assertPatternBytes(PATTERN_0, 1);
+        assertPatternBytes(PATTERN_1, 2);
+    }
+
+    public void testPattern_WriteParentWritesProfile() {
+        writePatternBytes(PATTERN_1, 2);
+        writePatternBytes(PATTERN_0, 1);
+
+        assertPatternBytes(PATTERN_0, 1);
+        assertPatternBytes(PATTERN_1, 2);
+        mStorage.clearCache();
+        assertPatternBytes(PATTERN_0, 1);
+        assertPatternBytes(PATTERN_1, 2);
+    }
+
+    public void testPrefetch() {
+        mStorage.writeKeyValue("key", "toBeFetched", 0);
+        writePatternBytes(PATTERN_0, 0);
+
+        mStorage.clearCache();
+        mStorage.prefetchUser(0);
+
+        assertEquals("toBeFetched", mStorage.readKeyValue("key", "default", 0));
+        assertPatternBytes(PATTERN_0, 0);
+    }
+
+    public void testFileLocation_Owner() {
+        LockSettingsStorage storage = new LockSettingsStorage(getContext());
+
+        assertEquals("/data/system/gesture.key", storage.getLegacyLockPatternFilename(0));
+        assertEquals("/data/system/password.key", storage.getLegacyLockPasswordFilename(0));
+        assertEquals("/data/system/gatekeeper.pattern.key", storage.getLockPatternFilename(0));
+        assertEquals("/data/system/gatekeeper.password.key", storage.getLockPasswordFilename(0));
+    }
+
+    public void testFileLocation_SecondaryUser() {
+        LockSettingsStorage storage = new LockSettingsStorage(getContext());
+
+        assertEquals("/data/system/users/1/gatekeeper.pattern.key", storage.getLockPatternFilename(1));
+        assertEquals("/data/system/users/1/gatekeeper.password.key", storage.getLockPasswordFilename(1));
+    }
+
+    public void testFileLocation_ProfileToSecondary() {
+        LockSettingsStorage storage = new LockSettingsStorage(getContext());
+
+        assertEquals("/data/system/users/2/gatekeeper.pattern.key", storage.getLockPatternFilename(2));
+        assertEquals("/data/system/users/2/gatekeeper.password.key", storage.getLockPasswordFilename(2));
+    }
+
+    public void testFileLocation_ProfileToOwner() {
+        LockSettingsStorage storage = new LockSettingsStorage(getContext());
+
+        assertEquals("/data/system/users/3/gatekeeper.pattern.key", storage.getLockPatternFilename(3));
+        assertEquals("/data/system/users/3/gatekeeper.password.key", storage.getLockPasswordFilename(3));
+    }
+
+    public void testSyntheticPasswordState() {
+        final byte[] data = {1,2,3,4};
+        mStorage.writeSyntheticPasswordState(10, 1234L, "state", data);
+        assertArrayEquals(data, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
+        assertEquals(null, mStorage.readSyntheticPasswordState(0, 1234L, "state"));
+
+        mStorage.deleteSyntheticPasswordState(10, 1234L, "state");
+        assertEquals(null, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
+    }
+
+    public void testPersistentData_serializeUnserialize() {
+        byte[] serialized = PersistentData.toBytes(PersistentData.TYPE_GATEKEEPER, SOME_USER_ID,
+                DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, PAYLOAD);
+        PersistentData deserialized = PersistentData.fromBytes(serialized);
+
+        assertEquals(PersistentData.TYPE_GATEKEEPER, deserialized.type);
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, deserialized.qualityForUi);
+        assertArrayEquals(PAYLOAD, deserialized.payload);
+    }
+
+    public void testPersistentData_unserializeNull() {
+        PersistentData deserialized = PersistentData.fromBytes(null);
+        assertSame(PersistentData.NONE, deserialized);
+    }
+
+    public void testPersistentData_unserializeEmptyArray() {
+        PersistentData deserialized = PersistentData.fromBytes(new byte[0]);
+        assertSame(PersistentData.NONE, deserialized);
+    }
+
+    public void testPersistentData_unserialize_version1() {
+        // This test ensures that we can read serialized VERSION_1 PersistentData even if we change
+        // the wire format in the future.
+        byte[] serializedVersion1 = new byte[] {
+                1, /* PersistentData.VERSION_1 */
+                2, /* PersistentData.TYPE_SP */
+                0x00, 0x00, 0x04, 0x0A,  /* SOME_USER_ID */
+                0x00, 0x03, 0x00, 0x00,  /* PASSWORD_NUMERIC_COMPLEX */
+                1, 2, -1, -2, 33, /* PAYLOAD */
+        };
+        PersistentData deserialized = PersistentData.fromBytes(serializedVersion1);
+        assertEquals(PersistentData.TYPE_SP, deserialized.type);
+        assertEquals(SOME_USER_ID, deserialized.userId);
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX,
+                deserialized.qualityForUi);
+        assertArrayEquals(PAYLOAD, deserialized.payload);
+
+        // Make sure the constants we use on the wire do not change.
+        assertEquals(0, PersistentData.TYPE_NONE);
+        assertEquals(1, PersistentData.TYPE_GATEKEEPER);
+        assertEquals(2, PersistentData.TYPE_SP);
+        assertEquals(3, PersistentData.TYPE_SP_WEAVER);
+    }
+
+    public void testCredentialHash_serializeUnserialize() {
+        byte[] serialized = CredentialHash.create(
+                PAYLOAD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD).toBytes();
+        CredentialHash deserialized = CredentialHash.fromBytes(serialized);
+
+        assertEquals(CredentialHash.VERSION_GATEKEEPER, deserialized.version);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, deserialized.type);
+        assertArrayEquals(PAYLOAD, deserialized.hash);
+        assertFalse(deserialized.isBaseZeroPattern);
+    }
+
+    public void testCredentialHash_unserialize_versionGatekeeper() {
+        // This test ensures that we can read serialized VERSION_GATEKEEPER CredentialHashes
+        // even if we change the wire format in the future.
+        byte[] serialized = new byte[] {
+                1, /* VERSION_GATEKEEPER */
+                2, /* CREDENTIAL_TYPE_PASSWORD */
+                0, 0, 0, 5, /* hash length */
+                1, 2, -1, -2, 33, /* hash */
+        };
+        CredentialHash deserialized = CredentialHash.fromBytes(serialized);
+
+        assertEquals(CredentialHash.VERSION_GATEKEEPER, deserialized.version);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, deserialized.type);
+        assertArrayEquals(PAYLOAD, deserialized.hash);
+        assertFalse(deserialized.isBaseZeroPattern);
+
+        // Make sure the constants we use on the wire do not change.
+        assertEquals(-1, LockPatternUtils.CREDENTIAL_TYPE_NONE);
+        assertEquals(1, LockPatternUtils.CREDENTIAL_TYPE_PATTERN);
+        assertEquals(2, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
+    }
+
+    private static void assertArrayEquals(byte[] expected, byte[] actual) {
+        if (!Arrays.equals(expected, actual)) {
+            fail("expected:<" + Arrays.toString(expected) +
+                    "> but was:<" + Arrays.toString(actual) + ">");
+        }
+    }
+
+    private void writePasswordBytes(byte[] password, int userId) {
+        mStorage.writeCredentialHash(CredentialHash.create(
+                password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
+    }
+
+    private void writePatternBytes(byte[] pattern, int userId) {
+        mStorage.writeCredentialHash(CredentialHash.create(
+                pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
+    }
+
+    private void assertPasswordBytes(byte[] password, int userId) {
+        CredentialHash cred = mStorage.readCredentialHash(userId);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, cred.type);
+        assertArrayEquals(password, cred.hash);
+    }
+
+    private void assertPatternBytes(byte[] pattern, int userId) {
+        CredentialHash cred = mStorage.readCredentialHash(userId);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN, cred.type);
+        assertArrayEquals(pattern, cred.hash);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockGateKeeperService.java b/services/tests/servicestests/src/com/android/server/locksettings/MockGateKeeperService.java
new file mode 100644
index 0000000..b89c1d1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockGateKeeperService.java
@@ -0,0 +1,198 @@
+/*
+ * 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.locksettings;
+
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.service.gatekeeper.GateKeeperResponse;
+import android.service.gatekeeper.IGateKeeperService;
+import android.util.ArrayMap;
+
+import junit.framework.AssertionFailedError;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Random;
+
+public class MockGateKeeperService implements IGateKeeperService {
+    static class VerifyHandle {
+        public byte[] password;
+        public long sid;
+
+        public VerifyHandle(byte[] password, long sid) {
+            this.password = password;
+            this.sid = sid;
+        }
+
+        public VerifyHandle(byte[] handle) {
+            ByteBuffer buffer = ByteBuffer.allocate(handle.length);
+            buffer.put(handle, 0, handle.length);
+            buffer.flip();
+            int version = buffer.get();
+            sid = buffer.getLong();
+            password = new byte[buffer.remaining()];
+            buffer.get(password);
+        }
+
+        public byte[] toBytes() {
+            ByteBuffer buffer = ByteBuffer.allocate(1 + Long.BYTES + password.length);
+            buffer.put((byte)0);
+            buffer.putLong(sid);
+            buffer.put(password);
+            return buffer.array();
+        }
+    }
+
+    static class AuthToken {
+        public long challenge;
+        public long sid;
+
+        public AuthToken(long challenge, long sid) {
+            this.challenge = challenge;
+            this.sid = sid;
+        }
+
+        public AuthToken(byte[] handle) {
+            ByteBuffer buffer = ByteBuffer.allocate(handle.length);
+            buffer.put(handle, 0, handle.length);
+            buffer.flip();
+            int version = buffer.get();
+            challenge = buffer.getLong();
+            sid = buffer.getLong();
+        }
+
+        public byte[] toBytes() {
+            ByteBuffer buffer = ByteBuffer.allocate(1 + Long.BYTES + Long.BYTES);
+            buffer.put((byte)0);
+            buffer.putLong(challenge);
+            buffer.putLong(sid);
+            return buffer.array();
+        }
+    }
+
+    private ArrayMap<Integer, Long> sidMap = new ArrayMap<>();
+    private ArrayMap<Integer, AuthToken> authTokenMap = new ArrayMap<>();
+
+    private ArrayMap<Integer, byte[]> handleMap = new ArrayMap<>();
+
+    @Override
+    public GateKeeperResponse enroll(int uid, byte[] currentPasswordHandle, byte[] currentPassword,
+            byte[] desiredPassword) throws android.os.RemoteException {
+
+        if (currentPasswordHandle != null) {
+            VerifyHandle handle = new VerifyHandle(currentPasswordHandle);
+            if (Arrays.equals(currentPassword, handle.password)) {
+                // Trusted enroll
+                VerifyHandle newHandle = new VerifyHandle(desiredPassword, handle.sid);
+                refreshSid(uid, handle.sid, false);
+                handleMap.put(uid, newHandle.toBytes());
+                return GateKeeperResponse.createOkResponse(newHandle.toBytes(), false);
+            } else {
+                return null;
+            }
+        } else {
+            // Untrusted enroll
+            long newSid = new Random().nextLong();
+            VerifyHandle newHandle = new VerifyHandle(desiredPassword, newSid);
+            refreshSid(uid, newSid, true);
+            handleMap.put(uid, newHandle.toBytes());
+            return GateKeeperResponse.createOkResponse(newHandle.toBytes(), false);
+        }
+    }
+
+    @Override
+    public GateKeeperResponse verify(int uid, byte[] enrolledPasswordHandle,
+            byte[] providedPassword) throws android.os.RemoteException {
+        return verifyChallenge(uid, 0, enrolledPasswordHandle, providedPassword);
+    }
+
+    @Override
+    public GateKeeperResponse verifyChallenge(int uid, long challenge,
+            byte[] enrolledPasswordHandle, byte[] providedPassword) throws RemoteException {
+
+        VerifyHandle handle = new VerifyHandle(enrolledPasswordHandle);
+        if (Arrays.equals(handle.password, providedPassword)) {
+            byte[] knownHandle = handleMap.get(uid);
+            if (knownHandle != null) {
+                if (!Arrays.equals(knownHandle, enrolledPasswordHandle)) {
+                    throw new AssertionFailedError("Got correct but obsolete handle");
+                }
+            }
+            refreshSid(uid, handle.sid, false);
+            AuthToken token = new AuthToken(challenge, handle.sid);
+            refreshAuthToken(uid, token);
+            return GateKeeperResponse.createOkResponse(token.toBytes(), false);
+        } else {
+            return GateKeeperResponse.createGenericResponse(GateKeeperResponse.RESPONSE_ERROR);
+        }
+    }
+
+    private void refreshAuthToken(int uid, AuthToken token) {
+        authTokenMap.put(uid, token);
+    }
+
+    public AuthToken getAuthToken(int uid) {
+        return authTokenMap.get(uid);
+    }
+
+    public AuthToken getAuthTokenForSid(long sid) {
+        for(AuthToken token : authTokenMap.values()) {
+            if (token.sid == sid) {
+                return token;
+            }
+        }
+        return null;
+    }
+
+    public void clearAuthToken(int uid) {
+        authTokenMap.remove(uid);
+    }
+
+    @Override
+    public IBinder asBinder() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void clearSecureUserId(int userId) throws RemoteException {
+        sidMap.remove(userId);
+    }
+
+    @Override
+    public void reportDeviceSetupComplete() throws RemoteException {
+    }
+
+    @Override
+    public long getSecureUserId(int userId) throws RemoteException {
+        if (sidMap.containsKey(userId)) {
+            return sidMap.get(userId);
+        } else {
+            return 0L;
+        }
+    }
+
+    private void refreshSid(int uid, long sid, boolean force) {
+        if (!sidMap.containsKey(uid) || force) {
+            sidMap.put(uid, sid);
+        } else{
+            if (sidMap.get(uid) != sid) {
+                throw new AssertionFailedError("Inconsistent SID");
+            }
+        }
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
new file mode 100644
index 0000000..8da33a8
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
@@ -0,0 +1,63 @@
+/*
+ * 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.locksettings;
+
+import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+
+public class MockLockSettingsContext extends ContextWrapper {
+
+    private UserManager mUserManager;
+    private NotificationManager mNotificationManager;
+    private DevicePolicyManager mDevicePolicyManager;
+    private StorageManager mStorageManager;
+
+    public MockLockSettingsContext(Context base, UserManager userManager,
+            NotificationManager notificationManager, DevicePolicyManager devicePolicyManager,
+            StorageManager storageManager) {
+        super(base);
+        mUserManager = userManager;
+        mNotificationManager = notificationManager;
+        mDevicePolicyManager = devicePolicyManager;
+        mStorageManager = storageManager;
+    }
+
+    @Override
+    public Object getSystemService(String name) {
+        if (USER_SERVICE.equals(name)) {
+            return mUserManager;
+        } else if (NOTIFICATION_SERVICE.equals(name)) {
+            return mNotificationManager;
+        } else if (DEVICE_POLICY_SERVICE.equals(name)) {
+            return mDevicePolicyManager;
+        } else if (STORAGE_SERVICE.equals(name)) {
+            return mStorageManager;
+        } else {
+            throw new RuntimeException("System service not mocked: " + name);
+        }
+    }
+
+    @Override
+    public void enforceCallingOrSelfPermission(String permission, String message) {
+        // Skip permission checks for unit tests.
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockStorageManager.java b/services/tests/servicestests/src/com/android/server/locksettings/MockStorageManager.java
new file mode 100644
index 0000000..40e114b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockStorageManager.java
@@ -0,0 +1,507 @@
+/*
+ * 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.locksettings;
+
+import android.content.pm.IPackageMoveObserver;
+import android.os.IBinder;
+import android.os.IProgressListener;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.storage.DiskInfo;
+import android.os.storage.IObbActionListener;
+import android.os.storage.IStorageEventListener;
+import android.os.storage.IStorageManager;
+import android.os.storage.IStorageShutdownObserver;
+import android.os.storage.StorageVolume;
+import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
+import android.util.ArrayMap;
+import android.util.Pair;
+
+import com.android.internal.os.AppFuseMount;
+
+import junit.framework.AssertionFailedError;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class MockStorageManager implements IStorageManager {
+
+    private ArrayMap<Integer, ArrayList<Pair<byte[], byte[]>>> mAuth = new ArrayMap<>();
+    private boolean mIgnoreBadUnlock;
+
+    @Override
+    public void addUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret)
+            throws RemoteException {
+        getUserAuth(userId).add(new Pair<>(token, secret));
+    }
+
+    @Override
+    public void fixateNewestUserKeyAuth(int userId) throws RemoteException {
+        ArrayList<Pair<byte[], byte[]>> auths = mAuth.get(userId);
+        Pair<byte[], byte[]> latest = auths.get(auths.size() - 1);
+        auths.clear();
+        auths.add(latest);
+    }
+
+    private ArrayList<Pair<byte[], byte[]>> getUserAuth(int userId) {
+        if (!mAuth.containsKey(userId)) {
+            ArrayList<Pair<byte[], byte[]>> auths = new ArrayList<Pair<byte[], byte[]>>();
+            auths.add(new Pair(null, null));
+            mAuth.put(userId,  auths);
+        }
+        return mAuth.get(userId);
+    }
+
+    public byte[] getUserUnlockToken(int userId) {
+        ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId);
+        if (auths.size() != 1) {
+            throw new AssertionFailedError("More than one secret exists");
+        }
+        return auths.get(0).second;
+    }
+
+    public void unlockUser(int userId, byte[] secret, IProgressListener listener)
+            throws RemoteException {
+        listener.onStarted(userId, null);
+        listener.onFinished(userId, null);
+        ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId);
+        if (secret != null) {
+            if (auths.size() > 1) {
+                throw new AssertionFailedError("More than one secret exists");
+            }
+            Pair<byte[], byte[]> auth = auths.get(0);
+            if ((!mIgnoreBadUnlock) && auth.second != null && !Arrays.equals(secret, auth.second)) {
+                throw new AssertionFailedError("Invalid secret to unlock user");
+            }
+        } else {
+            if (auths != null && auths.size() > 0) {
+                throw new AssertionFailedError("Cannot unlock encrypted user with empty token");
+            }
+        }
+    }
+
+    public void setIgnoreBadUnlock(boolean ignore) {
+        mIgnoreBadUnlock = ignore;
+    }
+
+    @Override
+    public IBinder asBinder() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void registerListener(IStorageEventListener listener) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unregisterListener(IStorageEventListener listener) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isUsbMassStorageConnected() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setUsbMassStorageEnabled(boolean enable) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isUsbMassStorageEnabled() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int mountVolume(String mountPoint) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unmountVolume(String mountPoint, boolean force, boolean removeEncryption)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+
+    }
+
+    @Override
+    public int formatVolume(String mountPoint) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int[] getStorageUsers(String path) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getVolumeState(String mountPoint) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int createSecureContainer(String id, int sizeMb, String fstype, String key, int ownerUid,
+            boolean external) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int finalizeSecureContainer(String id) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int destroySecureContainer(String id, boolean force) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int mountSecureContainer(String id, String key, int ownerUid, boolean readOnly)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int unmountSecureContainer(String id, boolean force) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isSecureContainerMounted(String id) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int renameSecureContainer(String oldId, String newId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getSecureContainerPath(String id) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String[] getSecureContainerList() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void shutdown(IStorageShutdownObserver observer) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void finishMediaUpdate() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void mountObb(String rawPath, String canonicalPath, String key, IObbActionListener token,
+            int nonce) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unmountObb(String rawPath, boolean force, IObbActionListener token, int nonce)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isObbMounted(String rawPath) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getMountedObbPath(String rawPath) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isExternalStorageEmulated() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int decryptStorage(String password) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int encryptStorage(int type, String password) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int changeEncryptionPassword(int type, String password) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public StorageVolume[] getVolumeList(int uid, String packageName, int flags)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getSecureContainerFilesystemPath(String cid) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getEncryptionState() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int verifyEncryptionPassword(String password) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int fixPermissionsSecureContainer(String id, int gid, String filename)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int mkdirs(String callingPkg, String path) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getPasswordType() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getPassword() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void clearPassword() throws RemoteException {
+        throw new UnsupportedOperationException();
+
+    }
+
+    @Override
+    public void setField(String field, String contents) throws RemoteException {
+        throw new UnsupportedOperationException();
+
+    }
+
+    @Override
+    public String getField(String field) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int resizeSecureContainer(String id, int sizeMb, String key) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long lastMaintenance() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void runMaintenance() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void waitForAsecScan() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public DiskInfo[] getDisks() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public VolumeInfo[] getVolumes(int flags) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public VolumeRecord[] getVolumeRecords(int flags) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void mount(String volId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unmount(String volId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void format(String volId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void partitionPublic(String diskId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void partitionPrivate(String diskId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void partitionMixed(String diskId, int ratio) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void forgetVolume(String fsUuid) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void forgetAllVolumes() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getPrimaryStorageUuid() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long benchmark(String volId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setDebugFlags(int flags, int mask) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void createUserKey(int userId, int serialNumber, boolean ephemeral)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void destroyUserKey(int userId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void lockUserKey(int userId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isUserKeyUnlocked(int userId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void prepareUserStorage(String volumeUuid, int userId, int serialNumber, int flags)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void destroyUserStorage(String volumeUuid, int userId, int flags)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isConvertibleToFBE() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void fstrim(int flags) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public AppFuseMount mountProxyFileDescriptorBridge() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ParcelFileDescriptor openProxyFileDescriptor(int mountPointId, int fileId, int mode)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getCacheQuotaBytes(String volumeUuid, int uid) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getCacheSizeBytes(String volumeUuid, int uid) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getAllocatableBytes(String path, int flags, String callingPackage) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void allocateBytes(String path, long bytes, int flags, String callingPackage) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void secdiscard(String path) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java b/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
new file mode 100644
index 0000000..d7468c2
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
@@ -0,0 +1,116 @@
+/*
+ * 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.locksettings;
+
+import android.hardware.weaver.V1_0.IWeaver;
+import android.os.RemoteException;
+import android.os.UserManager;
+import android.util.ArrayMap;
+
+import junit.framework.AssertionFailedError;
+
+import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Arrays;
+
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+public class MockSyntheticPasswordManager extends SyntheticPasswordManager {
+
+    private MockGateKeeperService mGateKeeper;
+    private IWeaver mWeaverService;
+
+    public MockSyntheticPasswordManager(LockSettingsStorage storage,
+            MockGateKeeperService gatekeeper, UserManager userManager) {
+        super(storage, userManager);
+        mGateKeeper = gatekeeper;
+    }
+
+    private ArrayMap<String, byte[]> mBlobs = new ArrayMap<>();
+
+    @Override
+    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
+        if (mBlobs.containsKey(blobKeyName) && !Arrays.equals(mBlobs.get(blobKeyName), blob)) {
+            throw new AssertionFailedError("blobKeyName content is overwritten: " + blobKeyName);
+        }
+        ByteBuffer buffer = ByteBuffer.allocate(blob.length);
+        buffer.put(blob, 0, blob.length);
+        buffer.flip();
+        int len;
+        len = buffer.getInt();
+        byte[] data = new byte[len];
+        buffer.get(data);
+        len = buffer.getInt();
+        byte[] appId = new byte[len];
+        buffer.get(appId);
+        long sid = buffer.getLong();
+        if (!Arrays.equals(appId, applicationId)) {
+            throw new AssertionFailedError("Invalid application id");
+        }
+        if (sid != 0 && mGateKeeper.getAuthTokenForSid(sid) == null) {
+            throw new AssertionFailedError("No valid auth token");
+        }
+        return data;
+    }
+
+    @Override
+    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
+        ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + data.length + Integer.BYTES
+                + applicationId.length + Long.BYTES);
+        buffer.putInt(data.length);
+        buffer.put(data);
+        buffer.putInt(applicationId.length);
+        buffer.put(applicationId);
+        buffer.putLong(sid);
+        byte[] result = buffer.array();
+        mBlobs.put(blobKeyName, result);
+        return result;
+    }
+
+    @Override
+    protected void destroySPBlobKey(String keyAlias) {
+    }
+
+    @Override
+    protected long sidFromPasswordHandle(byte[] handle) {
+        return new MockGateKeeperService.VerifyHandle(handle).sid;
+    }
+
+    @Override
+    protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) {
+        try {
+            PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10, outLen * 8);
+            SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
+            return f.generateSecret(spec).getEncoded();
+        } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    @Override
+    protected IWeaver getWeaverService() throws RemoteException {
+        return mWeaverService;
+    }
+
+    public void enableWeaver() {
+        mWeaverService = new MockWeaverService();
+        initWeaverService();
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockWeaverService.java b/services/tests/servicestests/src/com/android/server/locksettings/MockWeaverService.java
new file mode 100644
index 0000000..34831cd
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockWeaverService.java
@@ -0,0 +1,108 @@
+package com.android.server.locksettings;
+
+import android.hardware.weaver.V1_0.IWeaver;
+import android.hardware.weaver.V1_0.WeaverConfig;
+import android.hardware.weaver.V1_0.WeaverReadResponse;
+import android.hardware.weaver.V1_0.WeaverStatus;
+import android.hidl.base.V1_0.DebugInfo;
+import android.os.IHwBinder;
+import android.os.IHwBinder.DeathRecipient;
+import android.os.RemoteException;
+import android.util.Pair;
+
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class MockWeaverService implements IWeaver {
+
+    private static final int MAX_SLOTS = 8;
+    private static final int KEY_LENGTH = 256 / 8;
+    private static final int VALUE_LENGTH = 256 / 8;
+
+    private Pair<ArrayList<Byte>, ArrayList<Byte>>[] slots = new Pair[MAX_SLOTS];
+    @Override
+    public void getConfig(getConfigCallback cb) throws RemoteException {
+        WeaverConfig config = new WeaverConfig();
+        config.keySize = KEY_LENGTH;
+        config.valueSize = VALUE_LENGTH;
+        config.slots = MAX_SLOTS;
+        cb.onValues(WeaverStatus.OK, config);
+    }
+
+    @Override
+    public int write(int slotId, ArrayList<Byte> key, ArrayList<Byte> value)
+            throws RemoteException {
+        if (slotId < 0 || slotId >= MAX_SLOTS) {
+            throw new RuntimeException("Invalid slot id");
+        }
+        slots[slotId] = Pair.create((ArrayList<Byte>) key.clone(), (ArrayList<Byte>) value.clone());
+        return WeaverStatus.OK;
+    }
+
+    @Override
+    public void read(int slotId, ArrayList<Byte> key, readCallback cb) throws RemoteException {
+        if (slotId < 0 || slotId >= MAX_SLOTS) {
+            throw new RuntimeException("Invalid slot id");
+        }
+
+        WeaverReadResponse response = new WeaverReadResponse();
+        if (key.equals(slots[slotId].first)) {
+            response.value.addAll(slots[slotId].second);
+            cb.onValues(WeaverStatus.OK, response);
+        } else {
+            cb.onValues(WeaverStatus.FAILED, response);
+        }
+    }
+
+    @Override
+    public IHwBinder asBinder() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ArrayList<String> interfaceChain() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String interfaceDescriptor() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setHALInstrumentation() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean linkToDeath(DeathRecipient recipient, long cookie) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void ping() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public DebugInfo getDebugInfo() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void notifySyspropsChanged() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean unlinkToDeath(DeathRecipient recipient) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ArrayList<byte[]> getHashChain() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
new file mode 100644
index 0000000..ba4ff33
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -0,0 +1,421 @@
+/*
+ * 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.locksettings;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
+import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
+
+import android.app.admin.DevicePolicyManager;
+import android.os.RemoteException;
+import android.os.UserHandle;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.VerifyCredentialResponse;
+import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;
+import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationToken;
+import com.android.server.locksettings.SyntheticPasswordManager.PasswordData;
+
+
+/**
+ * runtest frameworks-services -c com.android.server.locksettings.SyntheticPasswordTests
+ */
+public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
+
+    public static final byte[] PAYLOAD = new byte[] {1, 2, -1, -2, 55};
+    public static final byte[] PAYLOAD2 = new byte[] {2, 3, -2, -3, 44, 1};
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testPasswordBasedSyntheticPassword() throws RemoteException {
+        final int USER_ID = 10;
+        final String PASSWORD = "user-password";
+        final String BADPASSWORD = "bad-password";
+        MockSyntheticPasswordManager manager = new MockSyntheticPasswordManager(mStorage,
+                mGateKeeperService, mUserManager);
+        AuthenticationToken authToken = manager.newSyntheticPasswordAndSid(mGateKeeperService, null,
+                null, USER_ID);
+        long handle = manager.createPasswordBasedSyntheticPassword(mGateKeeperService, PASSWORD,
+                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, authToken, PASSWORD_QUALITY_ALPHABETIC,
+                USER_ID);
+
+        AuthenticationResult result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle, PASSWORD, USER_ID);
+        assertEquals(result.authToken.deriveKeyStorePassword(), authToken.deriveKeyStorePassword());
+
+        result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle, BADPASSWORD, USER_ID);
+        assertNull(result.authToken);
+    }
+
+    private void disableSyntheticPassword(int userId) throws RemoteException {
+        mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
+    }
+
+    private void enableSyntheticPassword(int userId) throws RemoteException {
+        mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
+    }
+
+    private boolean hasSyntheticPassword(int userId) throws RemoteException {
+        return mService.getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId) != 0;
+    }
+
+    public void testPasswordMigration() throws RemoteException {
+        final String PASSWORD = "testPasswordMigration-password";
+
+        disableSyntheticPassword(PRIMARY_USER_ID);
+        mService.setLockCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+        enableSyntheticPassword(PRIMARY_USER_ID);
+        // Performs migration
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+
+        // SP-based verification
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+    }
+
+    private void initializeCredentialUnderSP(String password, int userId) throws RemoteException {
+        enableSyntheticPassword(userId);
+        int quality = password != null ? PASSWORD_QUALITY_ALPHABETIC
+                : PASSWORD_QUALITY_UNSPECIFIED;
+        int type = password != null ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD
+                : LockPatternUtils.CREDENTIAL_TYPE_NONE;
+        mService.setLockCredential(password, type, null, quality, userId);
+    }
+
+    public void testSyntheticPasswordChangeCredential() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordChangeCredential-password";
+        final String NEWPASSWORD = "testSyntheticPasswordChangeCredential-newpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, PASSWORD,
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        mGateKeeperService.clearSecureUserId(PRIMARY_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+    }
+
+    public void testSyntheticPasswordVerifyCredential() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordVerifyCredential-password";
+        final String BADPASSWORD = "testSyntheticPasswordVerifyCredential-badpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+
+        assertEquals(VerifyCredentialResponse.RESPONSE_ERROR,
+                mService.verifyCredential(BADPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+    }
+
+    public void testSyntheticPasswordClearCredential() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
+        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        // clear password
+        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, PASSWORD,
+                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+        assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+
+        // set a new password
+        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertNotSame(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+    }
+
+    public void testSyntheticPasswordClearCredentialUntrusted() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
+        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        // clear password
+        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, null,
+                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+        assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+
+        // set a new password
+        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertNotSame(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+    }
+
+    public void testSyntheticPasswordChangeCredentialUntrusted() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
+        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        // Untrusted change password
+        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        assertNotSame(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertNotSame(sid ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+
+        // Verify the password
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+    }
+
+
+    public void testManagedProfileUnifiedChallengeMigration() throws RemoteException {
+        final String UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd";
+        disableSyntheticPassword(PRIMARY_USER_ID);
+        disableSyntheticPassword(MANAGED_PROFILE_USER_ID);
+        mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
+        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
+        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+        final byte[] profileStorageKey = mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID);
+        assertTrue(primarySid != 0);
+        assertTrue(profileSid != 0);
+        assertTrue(profileSid != primarySid);
+
+        // do migration
+        enableSyntheticPassword(PRIMARY_USER_ID);
+        enableSyntheticPassword(MANAGED_PROFILE_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+
+        // verify
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(primarySid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+        assertArrayNotSame(profileStorageKey, mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(MANAGED_PROFILE_USER_ID));
+    }
+
+    public void testManagedProfileSeparateChallengeMigration() throws RemoteException {
+        final String primaryPassword = "testManagedProfileSeparateChallengeMigration-primary";
+        final String profilePassword = "testManagedProfileSeparateChallengeMigration-profile";
+        mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID);
+        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
+        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+        final byte[] profileStorageKey = mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID);
+        assertTrue(primarySid != 0);
+        assertTrue(profileSid != 0);
+        assertTrue(profileSid != primarySid);
+
+        // do migration
+        enableSyntheticPassword(PRIMARY_USER_ID);
+        enableSyntheticPassword(MANAGED_PROFILE_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, MANAGED_PROFILE_USER_ID).getResponseCode());
+
+        // verify
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, MANAGED_PROFILE_USER_ID).getResponseCode());
+        assertEquals(primarySid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+        assertArrayNotSame(profileStorageKey, mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(MANAGED_PROFILE_USER_ID));
+    }
+
+    public void testTokenBasedResetPassword() throws RemoteException {
+        final String PASSWORD = "password";
+        final String PATTERN = "123654";
+        final String TOKEN = "some-high-entropy-secure-token";
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                handle, TOKEN.getBytes(), PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
+
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID).getResponseCode());
+        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+    }
+
+    public void testTokenBasedClearPassword() throws RemoteException {
+        final String PASSWORD = "password";
+        final String PATTERN = "123654";
+        final String TOKEN = "some-high-entropy-secure-token";
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.setLockCredentialWithToken(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, handle,
+                TOKEN.getBytes(), PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+        mService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                handle, TOKEN.getBytes(), PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
+
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID).getResponseCode());
+        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+    }
+
+    public void testTokenBasedResetPasswordAfterCredentialChanges() throws RemoteException {
+        final String PASSWORD = "password";
+        final String PATTERN = "123654";
+        final String NEWPASSWORD = "password";
+        final String TOKEN = "some-high-entropy-secure-token";
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.setLockCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, PASSWORD,
+                PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
+
+        mService.setLockCredentialWithToken(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                handle, TOKEN.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+    }
+
+    public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNeedsMigration() throws RemoteException {
+        final String TOKEN = "some-high-entropy-secure-token";
+        enableSyntheticPassword(PRIMARY_USER_ID);
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+    }
+
+    public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNoMigration() throws RemoteException {
+        final String TOKEN = "some-high-entropy-secure-token";
+        initializeCredentialUnderSP(null, PRIMARY_USER_ID);
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+    }
+
+    public void testEscrowTokenActivatedLaterWithUserPasswordNeedsMigration() throws RemoteException {
+        final String TOKEN = "some-high-entropy-secure-token";
+        final String PASSWORD = "password";
+        // Set up pre-SP user password
+        disableSyntheticPassword(PRIMARY_USER_ID);
+        mService.setLockCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        enableSyntheticPassword(PRIMARY_USER_ID);
+
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        // Token not activated immediately since user password exists
+        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+        // Activate token (password gets migrated to SP at the same time)
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
+                        PRIMARY_USER_ID).getResponseCode());
+        // Verify token is activated
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+    }
+
+    public void testPasswordData_serializeDeserialize() {
+        PasswordData data = new PasswordData();
+        data.scryptN = 11;
+        data.scryptR = 22;
+        data.scryptP = 33;
+        data.passwordType = CREDENTIAL_TYPE_PASSWORD;
+        data.salt = PAYLOAD;
+        data.passwordHandle = PAYLOAD2;
+
+        PasswordData deserialized = PasswordData.fromBytes(data.toBytes());
+
+        assertEquals(11, deserialized.scryptN);
+        assertEquals(22, deserialized.scryptR);
+        assertEquals(33, deserialized.scryptP);
+        assertEquals(CREDENTIAL_TYPE_PASSWORD, deserialized.passwordType);
+        assertArrayEquals(PAYLOAD, deserialized.salt);
+        assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
+    }
+
+    public void testPasswordData_deserialize() {
+        // Test that we can deserialize existing PasswordData and don't inadvertently change the
+        // wire format.
+        byte[] serialized = new byte[] {
+                0, 0, 0, 2, /* CREDENTIAL_TYPE_PASSWORD */
+                11, /* scryptN */
+                22, /* scryptR */
+                33, /* scryptP */
+                0, 0, 0, 5, /* salt.length */
+                1, 2, -1, -2, 55, /* salt */
+                0, 0, 0, 6, /* passwordHandle.length */
+                2, 3, -2, -3, 44, 1, /* passwordHandle */
+        };
+        PasswordData deserialized = PasswordData.fromBytes(serialized);
+
+        assertEquals(11, deserialized.scryptN);
+        assertEquals(22, deserialized.scryptR);
+        assertEquals(33, deserialized.scryptP);
+        assertEquals(CREDENTIAL_TYPE_PASSWORD, deserialized.passwordType);
+        assertArrayEquals(PAYLOAD, deserialized.salt);
+        assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
+    }
+
+    // b/34600579
+    //TODO: add non-migration work profile case, and unify/un-unify transition.
+    //TODO: test token after user resets password
+    //TODO: test token based reset after unified work challenge
+    //TODO: test clear password after unified work challenge
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java
new file mode 100644
index 0000000..5e56704
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java
@@ -0,0 +1,11 @@
+package com.android.server.locksettings;
+
+public class WeaverBasedSyntheticPasswordTests extends SyntheticPasswordTests {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mSpManager.enableWeaver();
+    }
+
+}
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 f1d5927..3c64582 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -1266,16 +1266,16 @@
         if (force || !ENABLE_DUMP) return;
 
         Log.v(TAG, "Dumping ShortcutService: " + message);
-        for (String line : dumpsys(null).split("\n")) {
+        for (String line : dumpsys("-u").split("\n")) {
             Log.v(TAG, line);
         }
     }
 
     protected String dumpCheckin() {
-        return dumpsys(new String[]{"--checkin"});
+        return dumpsys("--checkin");
     }
 
-    private String dumpsys(String[] args) {
+    protected String dumpsys(String... args) {
         final ArrayList<String> origPermissions = new ArrayList<>(mCallerPermissions);
         mCallerPermissions.add(android.Manifest.permission.DUMP);
         try {
@@ -2139,4 +2139,15 @@
         mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(getCallingPackage(), getCallingUserId()));
     }
+
+    protected void assertFileNotExists(String path) {
+        final File f = new File(mInjectedFilePathRoot, path);
+        assertFalse("File shouldn't exist: " + f.getAbsolutePath(), f.exists());
+    }
+
+    protected void assertFileExistsWithContent(String path) {
+        final File f = new File(mInjectedFilePathRoot, path);
+        assertTrue("File should exist: " + f.getAbsolutePath(), f.exists());
+        assertTrue("File should be larger than 0b: " + f.getAbsolutePath(), f.length() > 0);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index f4944f9..951f226 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -4732,8 +4732,23 @@
      * - Bitmaps
      */
     public void testBackupAndRestore() {
+
+        assertFileNotExists("user-0/shortcut_dump/restore-0-start.txt");
+        assertFileNotExists("user-0/shortcut_dump/restore-1-payload.xml");
+        assertFileNotExists("user-0/shortcut_dump/restore-2.txt");
+        assertFileNotExists("user-0/shortcut_dump/restore-3.txt");
+        assertFileNotExists("user-0/shortcut_dump/restore-4.txt");
+        assertFileNotExists("user-0/shortcut_dump/restore-5-finish.txt");
+
         prepareForBackupTest();
 
+        assertFileExistsWithContent("user-0/shortcut_dump/restore-0-start.txt");
+        assertFileExistsWithContent("user-0/shortcut_dump/restore-1-payload.xml");
+        assertFileExistsWithContent("user-0/shortcut_dump/restore-2.txt");
+        assertFileExistsWithContent("user-0/shortcut_dump/restore-3.txt");
+        assertFileExistsWithContent("user-0/shortcut_dump/restore-4.txt");
+        assertFileExistsWithContent("user-0/shortcut_dump/restore-5-finish.txt");
+
         checkBackupAndRestore_success();
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java
index 25f9100..da641b9 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java
@@ -15,6 +15,7 @@
  */
 package com.android.server.pm;
 
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.array;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertContains;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertSuccess;
@@ -40,7 +41,7 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
- * Unit test for "cmd shortcut"
+ * Unit test for "cmd shortcut" and "dumpsys shortcut".
  *
  * Launcher related commands are tested in
  */
@@ -336,4 +337,29 @@
                     .areAllNotPinned();
         });
     }
+
+    public void testDumpsysArgs() {
+        checkDumpsysArgs(null, true, false, false);
+        checkDumpsysArgs(array("-u"), true, true, false);
+        checkDumpsysArgs(array("--uid"), true, true, false);
+
+        checkDumpsysArgs(array("-f"), true, false, true);
+        checkDumpsysArgs(array("--files"), true, false, true);
+
+        checkDumpsysArgs(array("-a"), true, true, true);
+        checkDumpsysArgs(array("--all"), true, true, true);
+
+        checkDumpsysArgs(array("-a", "-n"), false, true, true);
+        checkDumpsysArgs(array("-a", "--no-main"), false, true, true);
+    }
+
+    private void checkDumpsysArgs(String[] args, boolean expectMain, boolean expectUid,
+            boolean expectDumpFiles) {
+        String dump = dumpsys(args);
+
+        assertEquals(expectMain, dump.contains("Icon format: PNG"));
+        assertEquals(expectUid, dump.contains("SHORTCUT MANAGER UID STATES"));
+        assertEquals(expectDumpFiles, dump.contains("SHORTCUT MANAGER FILES"));
+    }
+
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 1964cad..b656d5e 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -53,8 +53,7 @@
 
     // Packages which are used during tests.
     private static final String[] PACKAGES = new String[] {
-            "com.android.egg",
-            "com.android.retaildemo"
+            "com.android.egg"
     };
 
     private final Object mUserRemoveLock = new Object();
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
index afc0f67..4db9a30 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -23,10 +23,14 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
+import dalvik.system.DelegateLastClassLoader;
+import dalvik.system.PathClassLoader;
 import dalvik.system.VMRuntime;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -48,6 +52,10 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class DexManagerTests {
+    private static final String PATH_CLASS_LOADER_NAME = PathClassLoader.class.getName();
+    private static final String DELEGATE_LAST_CLASS_LOADER_NAME =
+            DelegateLastClassLoader.class.getName();
+
     private DexManager mDexManager;
 
     private TestData mFooUser0;
@@ -56,6 +64,9 @@
     private TestData mInvalidIsa;
     private TestData mDoesNotExist;
 
+    private TestData mBarUser0UnsupportedClassLoader;
+    private TestData mBarUser0DelegateLastClassLoader;
+
     private int mUser0;
     private int mUser1;
 
@@ -68,12 +79,17 @@
         String foo = "foo";
         String bar = "bar";
 
-        mFooUser0 = new TestData(foo, isa, mUser0);
-        mBarUser0 = new TestData(bar, isa, mUser0);
-        mBarUser1 = new TestData(bar, isa, mUser1);
+        mFooUser0 = new TestData(foo, isa, mUser0, PATH_CLASS_LOADER_NAME);
+        mBarUser0 = new TestData(bar, isa, mUser0, PATH_CLASS_LOADER_NAME);
+        mBarUser1 = new TestData(bar, isa, mUser1, PATH_CLASS_LOADER_NAME);
         mInvalidIsa = new TestData("INVALID", "INVALID_ISA", mUser0);
         mDoesNotExist = new TestData("DOES.NOT.EXIST", isa, mUser1);
 
+        mBarUser0UnsupportedClassLoader = new TestData(bar, isa, mUser0,
+                "unsupported.class_loader");
+        mBarUser0DelegateLastClassLoader = new TestData(bar, isa, mUser0,
+                DELEGATE_LAST_CLASS_LOADER_NAME);
+
         mDexManager = new DexManager(null, null, null, null);
 
         // Foo and Bar are available to user0.
@@ -90,7 +106,7 @@
         notifyDexLoad(mFooUser0, mFooUser0.getBaseAndSplitDexPaths(), mUser0);
 
         // Package is not used by others, so we should get nothing back.
-        assertNull(getPackageUseInfo(mFooUser0));
+        assertNoUseInfo(mFooUser0);
     }
 
     @Test
@@ -100,8 +116,7 @@
 
         // Bar is used by others now and should be in our records
         PackageUseInfo pui = getPackageUseInfo(mBarUser0);
-        assertNotNull(pui);
-        assertTrue(pui.isUsedByOtherApps());
+        assertIsUsedByOtherApps(mBarUser0, pui, true);
         assertTrue(pui.getDexUseInfoMap().isEmpty());
     }
 
@@ -112,8 +127,7 @@
         notifyDexLoad(mFooUser0, fooSecondaries, mUser0);
 
         PackageUseInfo pui = getPackageUseInfo(mFooUser0);
-        assertNotNull(pui);
-        assertFalse(pui.isUsedByOtherApps());
+        assertIsUsedByOtherApps(mFooUser0, pui, false);
         assertEquals(fooSecondaries.size(), pui.getDexUseInfoMap().size());
         assertSecondaryUse(mFooUser0, pui, fooSecondaries, /*isUsedByOtherApps*/false, mUser0);
     }
@@ -125,8 +139,7 @@
         notifyDexLoad(mFooUser0, barSecondaries, mUser0);
 
         PackageUseInfo pui = getPackageUseInfo(mBarUser0);
-        assertNotNull(pui);
-        assertFalse(pui.isUsedByOtherApps());
+        assertIsUsedByOtherApps(mBarUser0, pui, false);
         assertEquals(barSecondaries.size(), pui.getDexUseInfoMap().size());
         assertSecondaryUse(mFooUser0, pui, barSecondaries, /*isUsedByOtherApps*/true, mUser0);
     }
@@ -149,8 +162,7 @@
 
         // Check bar usage. Should be used by other app (for primary and barSecondaries).
         PackageUseInfo pui = getPackageUseInfo(mBarUser0);
-        assertNotNull(pui);
-        assertTrue(pui.isUsedByOtherApps());
+        assertIsUsedByOtherApps(mBarUser0, pui, true);
         assertEquals(barSecondaries.size() + barSecondariesForOwnUse.size(),
                 pui.getDexUseInfoMap().size());
 
@@ -160,8 +172,7 @@
 
         // Check foo usage. Should not be used by other app.
         pui = getPackageUseInfo(mFooUser0);
-        assertNotNull(pui);
-        assertFalse(pui.isUsedByOtherApps());
+        assertIsUsedByOtherApps(mFooUser0, pui, false);
         assertEquals(fooSecondaries.size(), pui.getDexUseInfoMap().size());
         assertSecondaryUse(mFooUser0, pui, fooSecondaries, /*isUsedByOtherApps*/false, mUser0);
     }
@@ -169,22 +180,22 @@
     @Test
     public void testPackageUseInfoNotFound() {
         // Assert we don't get back data we did not previously record.
-        assertNull(getPackageUseInfo(mFooUser0));
+        assertNoUseInfo(mFooUser0);
     }
 
     @Test
     public void testInvalidIsa() {
         // Notifying with an invalid ISA should be ignored.
         notifyDexLoad(mInvalidIsa, mInvalidIsa.getSecondaryDexPaths(), mUser0);
-        assertNull(getPackageUseInfo(mInvalidIsa));
+        assertNoUseInfo(mInvalidIsa);
     }
 
     @Test
-    public void testNotExistingPackate() {
+    public void testNotExistingPackage() {
         // Notifying about the load of a package which was previously not
         // register in DexManager#load should be ignored.
         notifyDexLoad(mDoesNotExist, mDoesNotExist.getBaseAndSplitDexPaths(), mUser0);
-        assertNull(getPackageUseInfo(mDoesNotExist));
+        assertNoUseInfo(mDoesNotExist);
     }
 
     @Test
@@ -192,7 +203,7 @@
         // Bar from User1 tries to load secondary dex files from User0 Bar.
         // Request should be ignored.
         notifyDexLoad(mBarUser1, mBarUser0.getSecondaryDexPaths(), mUser1);
-        assertNull(getPackageUseInfo(mBarUser1));
+        assertNoUseInfo(mBarUser1);
     }
 
     @Test
@@ -201,7 +212,7 @@
         // Note that the PackageManagerService already filters this out but we
         // still check that nothing goes unexpected in DexManager.
         notifyDexLoad(mBarUser0, mFooUser0.getBaseAndSplitDexPaths(), mUser1);
-        assertNull(getPackageUseInfo(mBarUser1));
+        assertNoUseInfo(mBarUser1);
     }
 
     @Test
@@ -213,7 +224,7 @@
         // Before we notify about the installation of the newPackage if mFoo
         // is trying to load something from it we should not find it.
         notifyDexLoad(mFooUser0, newSecondaries, mUser0);
-        assertNull(getPackageUseInfo(newPackage));
+        assertNoUseInfo(newPackage);
 
         // Notify about newPackage install and let mFoo load its dexes.
         mDexManager.notifyPackageInstalled(newPackage.mPackageInfo, mUser0);
@@ -221,8 +232,7 @@
 
         // We should get back the right info.
         PackageUseInfo pui = getPackageUseInfo(newPackage);
-        assertNotNull(pui);
-        assertFalse(pui.isUsedByOtherApps());
+        assertIsUsedByOtherApps(newPackage, pui, false);
         assertEquals(newSecondaries.size(), pui.getDexUseInfoMap().size());
         assertSecondaryUse(newPackage, pui, newSecondaries, /*isUsedByOtherApps*/true, mUser0);
     }
@@ -238,8 +248,7 @@
         notifyDexLoad(newPackage, newSecondaries, mUser0);
 
         PackageUseInfo pui = getPackageUseInfo(newPackage);
-        assertNotNull(pui);
-        assertFalse(pui.isUsedByOtherApps());
+        assertIsUsedByOtherApps(newPackage, pui, false);
         assertEquals(newSecondaries.size(), pui.getDexUseInfoMap().size());
         assertSecondaryUse(newPackage, pui, newSecondaries, /*isUsedByOtherApps*/false, mUser0);
     }
@@ -251,8 +260,7 @@
 
         // Bar is used by others now and should be in our records.
         PackageUseInfo pui = getPackageUseInfo(mBarUser0);
-        assertNotNull(pui);
-        assertTrue(pui.isUsedByOtherApps());
+        assertIsUsedByOtherApps(mBarUser0, pui, true);
         assertTrue(pui.getDexUseInfoMap().isEmpty());
 
         // Notify that bar is updated.
@@ -262,8 +270,7 @@
 
         // The usedByOtherApps flag should be clear now.
         pui = getPackageUseInfo(mBarUser0);
-        assertNotNull(pui);
-        assertFalse(pui.isUsedByOtherApps());
+        assertIsUsedByOtherApps(mBarUser0, pui, false);
     }
 
     @Test
@@ -275,8 +282,7 @@
 
         // We shouldn't find yet the new split as we didn't notify the package update.
         notifyDexLoad(mFooUser0, newSplits, mUser0);
-        PackageUseInfo pui = getPackageUseInfo(mBarUser0);
-        assertNull(pui);
+        assertNoUseInfo(mBarUser0);
 
         // Notify that bar is updated. splitSourceDirs will contain the updated path.
         mDexManager.notifyPackageUpdated(mBarUser0.getPackageName(),
@@ -285,9 +291,9 @@
 
         // Now, when the split is loaded we will find it and we should mark Bar as usedByOthers.
         notifyDexLoad(mFooUser0, newSplits, mUser0);
-        pui = getPackageUseInfo(mBarUser0);
+        PackageUseInfo pui = getPackageUseInfo(mBarUser0);
         assertNotNull(pui);
-        assertTrue(pui.isUsedByOtherApps());
+        assertIsUsedByOtherApps(newSplits, pui, true);
     }
 
     @Test
@@ -319,8 +325,7 @@
         // Foo should still be around since it's used by other apps but with no
         // secondary dex info.
         PackageUseInfo pui = getPackageUseInfo(mFooUser0);
-        assertNotNull(pui);
-        assertTrue(pui.isUsedByOtherApps());
+        assertIsUsedByOtherApps(mFooUser0, pui, true);
         assertTrue(pui.getDexUseInfoMap().isEmpty());
     }
 
@@ -334,8 +339,7 @@
 
         // Foo should not be around since all its secondary dex info were deleted
         // and it is not used by other apps.
-        PackageUseInfo pui = getPackageUseInfo(mFooUser0);
-        assertNull(pui);
+        assertNoUseInfo(mFooUser0);
     }
 
     @Test
@@ -347,8 +351,7 @@
         mDexManager.notifyPackageDataDestroyed(mBarUser0.getPackageName(), UserHandle.USER_ALL);
 
         // Bar should not be around since it was removed for all users.
-        PackageUseInfo pui = getPackageUseInfo(mBarUser0);
-        assertNull(pui);
+        assertNoUseInfo(mBarUser0);
     }
 
     @Test
@@ -357,7 +360,7 @@
         // Load a dex file from framework.
         notifyDexLoad(mFooUser0, Arrays.asList(frameworkDex), mUser0);
         // The dex file should not be recognized as a package.
-        assertNull(mDexManager.getPackageUseInfo(frameworkDex));
+        assertFalse(mDexManager.hasInfoOnPackage(frameworkDex));
     }
 
     @Test
@@ -367,14 +370,83 @@
         notifyDexLoad(mFooUser0, fooSecondaries, mUser0);
 
         PackageUseInfo pui = getPackageUseInfo(mFooUser0);
-        assertNotNull(pui);
-        assertFalse(pui.isUsedByOtherApps());
+        assertIsUsedByOtherApps(mFooUser0, pui, false);
         assertEquals(fooSecondaries.size(), pui.getDexUseInfoMap().size());
         assertSecondaryUse(mFooUser0, pui, fooSecondaries, /*isUsedByOtherApps*/false, mUser0);
     }
 
+    @Test
+    public void testNotifyUnsupportedClassLoader() {
+        List<String> secondaries = mBarUser0UnsupportedClassLoader.getSecondaryDexPaths();
+        notifyDexLoad(mBarUser0UnsupportedClassLoader, secondaries, mUser0);
+
+        PackageUseInfo pui = getPackageUseInfo(mBarUser0UnsupportedClassLoader);
+        assertIsUsedByOtherApps(mBarUser0UnsupportedClassLoader, pui, false);
+        assertEquals(secondaries.size(), pui.getDexUseInfoMap().size());
+        // We expect that all the contexts are unsupported.
+        String[] expectedContexts =
+                Collections.nCopies(secondaries.size(),
+                        PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT).toArray(new String[0]);
+        assertSecondaryUse(mBarUser0UnsupportedClassLoader, pui, secondaries,
+                /*isUsedByOtherApps*/false, mUser0, expectedContexts);
+    }
+
+    @Test
+    public void testNotifyVariableClassLoader() {
+        // Record bar secondaries with the default PathClassLoader.
+        List<String> secondaries = mBarUser0.getSecondaryDexPaths();
+
+        notifyDexLoad(mBarUser0, secondaries, mUser0);
+        PackageUseInfo pui = getPackageUseInfo(mBarUser0);
+        assertIsUsedByOtherApps(mBarUser0, pui, false);
+        assertEquals(secondaries.size(), pui.getDexUseInfoMap().size());
+        assertSecondaryUse(mFooUser0, pui, secondaries, /*isUsedByOtherApps*/false, mUser0);
+
+        // Record bar secondaries again with a different class loader. This will change the context.
+        notifyDexLoad(mBarUser0DelegateLastClassLoader, secondaries, mUser0);
+
+        pui = getPackageUseInfo(mBarUser0);
+        assertIsUsedByOtherApps(mBarUser0, pui, false);
+        assertEquals(secondaries.size(), pui.getDexUseInfoMap().size());
+        // We expect that all the contexts to be changed to variable now.
+        String[] expectedContexts =
+                Collections.nCopies(secondaries.size(),
+                        PackageDexUsage.VARIABLE_CLASS_LOADER_CONTEXT).toArray(new String[0]);
+        assertSecondaryUse(mFooUser0, pui, secondaries, /*isUsedByOtherApps*/false, mUser0,
+                expectedContexts);
+    }
+
+    @Test
+    public void testNotifyUnsupportedClassLoaderDoesNotChange() {
+        List<String> secondaries = mBarUser0UnsupportedClassLoader.getSecondaryDexPaths();
+        notifyDexLoad(mBarUser0UnsupportedClassLoader, secondaries, mUser0);
+
+        PackageUseInfo pui = getPackageUseInfo(mBarUser0UnsupportedClassLoader);
+        assertIsUsedByOtherApps(mBarUser0UnsupportedClassLoader, pui, false);
+        assertEquals(secondaries.size(), pui.getDexUseInfoMap().size());
+        // We expect that all the contexts are unsupported.
+        String[] expectedContexts =
+                Collections.nCopies(secondaries.size(),
+                        PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT).toArray(new String[0]);
+        assertSecondaryUse(mBarUser0UnsupportedClassLoader, pui, secondaries,
+                /*isUsedByOtherApps*/false, mUser0, expectedContexts);
+
+        // Record bar secondaries again with a different class loader. This will change the context.
+        // However, because the context was already marked as unsupported we should not chage it.
+        notifyDexLoad(mBarUser0DelegateLastClassLoader, secondaries, mUser0);
+        pui = getPackageUseInfo(mBarUser0UnsupportedClassLoader);
+        assertSecondaryUse(mBarUser0UnsupportedClassLoader, pui, secondaries,
+                /*isUsedByOtherApps*/false, mUser0, expectedContexts);
+
+    }
+
+
     private void assertSecondaryUse(TestData testData, PackageUseInfo pui,
-            List<String> secondaries, boolean isUsedByOtherApps, int ownerUserId) {
+            List<String> secondaries, boolean isUsedByOtherApps, int ownerUserId,
+            String[] expectedContexts) {
+        assertNotNull(expectedContexts);
+        assertEquals(expectedContexts.length, secondaries.size());
+        int index = 0;
         for (String dex : secondaries) {
             DexUseInfo dui = pui.getDexUseInfoMap().get(dex);
             assertNotNull(dui);
@@ -382,16 +454,50 @@
             assertEquals(ownerUserId, dui.getOwnerUserId());
             assertEquals(1, dui.getLoaderIsas().size());
             assertTrue(dui.getLoaderIsas().contains(testData.mLoaderIsa));
+            assertEquals(expectedContexts[index++], dui.getClassLoaderContext());
         }
     }
+    private void assertSecondaryUse(TestData testData, PackageUseInfo pui,
+            List<String> secondaries, boolean isUsedByOtherApps, int ownerUserId) {
+        String[] expectedContexts = DexoptUtils.processContextForDexLoad(
+                Arrays.asList(testData.mClassLoader),
+                Arrays.asList(String.join(File.pathSeparator, secondaries)));
+        assertSecondaryUse(testData, pui, secondaries, isUsedByOtherApps, ownerUserId,
+                expectedContexts);
+    }
 
+    private void assertIsUsedByOtherApps(TestData testData, PackageUseInfo pui,
+            boolean isUsedByOtherApps) {
+        assertIsUsedByOtherApps(testData.getBaseAndSplitDexPaths(), pui, isUsedByOtherApps);
+    }
+
+    private void assertIsUsedByOtherApps(List<String> codePaths, PackageUseInfo pui,
+            boolean isUsedByOtherApps) {
+        for (String codePath : codePaths) {
+            assertEquals(codePath, isUsedByOtherApps, pui.isUsedByOtherApps(codePath));
+        }
+    }
     private void notifyDexLoad(TestData testData, List<String> dexPaths, int loaderUserId) {
-        mDexManager.notifyDexLoad(testData.mPackageInfo.applicationInfo, dexPaths,
+        // By default, assume a single class loader in the chain.
+        // This makes writing tests much easier.
+        List<String> classLoaders = Arrays.asList(testData.mClassLoader);
+        List<String> classPaths = Arrays.asList(String.join(File.pathSeparator, dexPaths));
+        notifyDexLoad(testData, classLoaders, classPaths, loaderUserId);
+    }
+
+    private void notifyDexLoad(TestData testData, List<String> classLoader, List<String> classPaths,
+            int loaderUserId) {
+        mDexManager.notifyDexLoad(testData.mPackageInfo.applicationInfo, classLoader, classPaths,
                 testData.mLoaderIsa, loaderUserId);
     }
 
     private PackageUseInfo getPackageUseInfo(TestData testData) {
-        return mDexManager.getPackageUseInfo(testData.mPackageInfo.packageName);
+        assertTrue(mDexManager.hasInfoOnPackage(testData.mPackageInfo.packageName));
+        return mDexManager.getPackageUseInfoOrDefault(testData.mPackageInfo.packageName);
+    }
+
+    private void assertNoUseInfo(TestData testData) {
+        assertFalse(mDexManager.hasInfoOnPackage(testData.mPackageInfo.packageName));
     }
 
     private static PackageInfo getMockPackageInfo(String packageName, int userId) {
@@ -416,10 +522,16 @@
     private static class TestData {
         private final PackageInfo mPackageInfo;
         private final String mLoaderIsa;
+        private final String mClassLoader;
 
-        private TestData(String  packageName, String loaderIsa, int userId) {
+        private TestData(String packageName, String loaderIsa, int userId, String classLoader) {
             mPackageInfo = getMockPackageInfo(packageName, userId);
             mLoaderIsa = loaderIsa;
+            mClassLoader = classLoader;
+        }
+
+        private TestData(String packageName, String loaderIsa, int userId) {
+            this(packageName, loaderIsa, userId, PATH_CLASS_LOADER_NAME);
         }
 
         private String getPackageName() {
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java
new file mode 100644
index 0000000..c2072df
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java
@@ -0,0 +1,143 @@
+/*
+ * 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.pm.dex;
+
+
+import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.android.server.pm.PackageManagerService;
+import com.android.server.pm.PackageManagerServiceCompilerMapping;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DexoptOptionsTests {
+    private final static String mPackageName = "test.android.com";
+    private final static String mCompilerFilter =
+            PackageManagerServiceCompilerMapping.getDefaultCompilerFilter();
+    private final static String mSplitName = "split-A.apk";
+
+    @Test
+    public void testCreateDexoptOptionsEmpty() {
+        DexoptOptions opt = new DexoptOptions(mPackageName, mCompilerFilter, /*flags*/ 0);
+        assertEquals(mPackageName, opt.getPackageName());
+        assertEquals(mCompilerFilter, opt.getCompilerFilter());
+        assertEquals(null, opt.getSplitName());
+        assertFalse(opt.isBootComplete());
+        assertFalse(opt.isCheckForProfileUpdates());
+        assertFalse(opt.isDexoptOnlySecondaryDex());
+        assertFalse(opt.isDexoptOnlySharedDex());
+        assertFalse(opt.isDowngrade());
+        assertFalse(opt.isForce());
+        assertFalse(opt.isDexoptIdleBackgroundJob());
+    }
+
+    @Test
+    public void testCreateDexoptOptionsFull() {
+        int flags =
+                DexoptOptions.DEXOPT_FORCE |
+                DexoptOptions.DEXOPT_BOOT_COMPLETE |
+                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
+                DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
+                DexoptOptions.DEXOPT_ONLY_SHARED_DEX |
+                DexoptOptions.DEXOPT_DOWNGRADE  |
+                DexoptOptions.DEXOPT_AS_SHARED_LIBRARY |
+                DexoptOptions.DEXOPT_IDLE_BACKGROUND_JOB;
+
+        DexoptOptions opt = new DexoptOptions(mPackageName, mCompilerFilter, flags);
+        assertEquals(mPackageName, opt.getPackageName());
+        assertEquals(mCompilerFilter, opt.getCompilerFilter());
+        assertEquals(null, opt.getSplitName());
+        assertTrue(opt.isBootComplete());
+        assertTrue(opt.isCheckForProfileUpdates());
+        assertTrue(opt.isDexoptOnlySecondaryDex());
+        assertTrue(opt.isDexoptOnlySharedDex());
+        assertTrue(opt.isDowngrade());
+        assertTrue(opt.isForce());
+        assertTrue(opt.isDexoptAsSharedLibrary());
+        assertTrue(opt.isDexoptIdleBackgroundJob());
+    }
+
+    @Test
+    public void testCreateDexoptOptionsReason() {
+        int flags =
+                DexoptOptions.DEXOPT_FORCE |
+                DexoptOptions.DEXOPT_BOOT_COMPLETE |
+                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES;
+
+        int[] reasons = new int[] {
+                PackageManagerService.REASON_FIRST_BOOT,
+                PackageManagerService.REASON_BOOT,
+                PackageManagerService.REASON_INSTALL,
+                PackageManagerService.REASON_BACKGROUND_DEXOPT,
+                PackageManagerService.REASON_AB_OTA,
+                PackageManagerService.REASON_INACTIVE_PACKAGE_DOWNGRADE,};
+
+        for (int reason : reasons) {
+            DexoptOptions opt = new DexoptOptions(mPackageName, reason, flags);
+            assertEquals(mPackageName, opt.getPackageName());
+            assertEquals(getCompilerFilterForReason(reason), opt.getCompilerFilter());
+            assertEquals(null, opt.getSplitName());
+            assertTrue(opt.isBootComplete());
+            assertTrue(opt.isCheckForProfileUpdates());
+            assertFalse(opt.isDexoptOnlySecondaryDex());
+            assertFalse(opt.isDexoptOnlySharedDex());
+            assertFalse(opt.isDowngrade());
+            assertTrue(opt.isForce());
+            assertFalse(opt.isDexoptAsSharedLibrary());
+        }
+    }
+
+    @Test
+    public void testCreateDexoptOptionsSplit() {
+        int flags = DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE;
+
+        DexoptOptions opt = new DexoptOptions(mPackageName, mCompilerFilter, mSplitName, flags);
+        assertEquals(mPackageName, opt.getPackageName());
+        assertEquals(mCompilerFilter, opt.getCompilerFilter());
+        assertEquals(mSplitName, opt.getSplitName());
+        assertTrue(opt.isBootComplete());
+        assertFalse(opt.isCheckForProfileUpdates());
+        assertFalse(opt.isDexoptOnlySecondaryDex());
+        assertFalse(opt.isDexoptOnlySharedDex());
+        assertFalse(opt.isDowngrade());
+        assertTrue(opt.isForce());
+        assertFalse(opt.isDexoptAsSharedLibrary());
+    }
+
+    @Test
+    public void testCreateDexoptInvalid() {
+        boolean gotException = false;
+        try {
+            int invalidFlags = 999;
+            new DexoptOptions(mPackageName, mCompilerFilter, invalidFlags);
+        } catch (IllegalArgumentException ignore) {
+            gotException = true;
+        }
+
+        assertTrue(gotException);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
new file mode 100644
index 0000000..34dc1ad
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
@@ -0,0 +1,420 @@
+/*
+ * 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.pm.dex;
+
+import com.android.server.pm.PackageDexOptimizer;
+
+import static com.android.server.pm.PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.content.pm.ApplicationInfo;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.SparseArray;
+
+import dalvik.system.DelegateLastClassLoader;
+import dalvik.system.DexClassLoader;
+import dalvik.system.PathClassLoader;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DexoptUtilsTest {
+    private static final String DEX_CLASS_LOADER_NAME = DexClassLoader.class.getName();
+    private static final String PATH_CLASS_LOADER_NAME = PathClassLoader.class.getName();
+    private static final String DELEGATE_LAST_CLASS_LOADER_NAME =
+            DelegateLastClassLoader.class.getName();
+
+    private static class TestData {
+        ApplicationInfo info;
+        boolean[] pathsWithCode;
+    }
+
+    private TestData createMockApplicationInfo(String baseClassLoader, boolean addSplits,
+            boolean addSplitDependencies) {
+        ApplicationInfo ai = new ApplicationInfo();
+        String codeDir = "/data/app/mock.android.com";
+        ai.setBaseCodePath(codeDir + "/base.dex");
+        ai.privateFlags = ai.privateFlags | ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING;
+        boolean[] pathsWithCode;
+        if (!addSplits) {
+            pathsWithCode = new boolean[] {true};
+        } else {
+            pathsWithCode = new boolean[9];
+            Arrays.fill(pathsWithCode, true);
+            pathsWithCode[7] = false;  // config split
+
+            ai.setSplitCodePaths(new String[]{
+                    codeDir + "/base-1.dex",
+                    codeDir + "/base-2.dex",
+                    codeDir + "/base-3.dex",
+                    codeDir + "/base-4.dex",
+                    codeDir + "/base-5.dex",
+                    codeDir + "/base-6.dex",
+                    codeDir + "/config-split-7.dex",
+                    codeDir + "/feature-no-deps.dex"});
+
+            String[] splitClassLoaderNames = new String[]{
+                    PATH_CLASS_LOADER_NAME,
+                    PATH_CLASS_LOADER_NAME,
+                    PATH_CLASS_LOADER_NAME,
+                    PATH_CLASS_LOADER_NAME,
+                    PATH_CLASS_LOADER_NAME,
+                    null,   // A null class loader name should default to PathClassLoader.
+                    null,   // The config split gets a null class loader.
+                    null};  // The feature split with no dependency and no specified class loader.
+            if (addSplitDependencies) {
+                ai.splitDependencies = new SparseArray<>(splitClassLoaderNames.length + 1);
+                ai.splitDependencies.put(0, new int[] {-1}); // base has no dependency
+                ai.splitDependencies.put(1, new int[] {2}); // split 1 depends on 2
+                ai.splitDependencies.put(2, new int[] {4}); // split 2 depends on 4
+                ai.splitDependencies.put(3, new int[] {4}); // split 3 depends on 4
+                ai.splitDependencies.put(4, new int[] {0}); // split 4 depends on base
+                ai.splitDependencies.put(5, new int[] {0}); // split 5 depends on base
+                ai.splitDependencies.put(6, new int[] {5}); // split 6 depends on 5
+                // Do not add the config split to the dependency list.
+                // Do not add the feature split with no dependency to the dependency list.
+            }
+        }
+        TestData data = new TestData();
+        data.info = ai;
+        data.pathsWithCode = pathsWithCode;
+        return data;
+    }
+
+    @Test
+    public void testSplitChain() {
+        TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, true);
+        String[] sharedLibrary = new String[] {"a.dex", "b.dex"};
+        String[] contexts = DexoptUtils.getClassLoaderContexts(
+                data.info, sharedLibrary, data.pathsWithCode);
+
+        assertEquals(9, contexts.length);
+        assertEquals("PCL[a.dex:b.dex]", contexts[0]);
+        assertEquals("PCL[];PCL[base-2.dex];PCL[base-4.dex];PCL[a.dex:b.dex:base.dex]",
+                contexts[1]);
+        assertEquals("PCL[];PCL[base-4.dex];PCL[a.dex:b.dex:base.dex]", contexts[2]);
+        assertEquals("PCL[];PCL[base-4.dex];PCL[a.dex:b.dex:base.dex]", contexts[3]);
+        assertEquals("PCL[];PCL[a.dex:b.dex:base.dex]", contexts[4]);
+        assertEquals("PCL[];PCL[a.dex:b.dex:base.dex]", contexts[5]);
+        assertEquals("PCL[];PCL[base-5.dex];PCL[a.dex:b.dex:base.dex]", contexts[6]);
+        assertEquals(null, contexts[7]);  // config split
+        assertEquals("PCL[]", contexts[8]);  // feature split with no dependency
+    }
+
+    @Test
+    public void testSplitChainNoSplitDependencies() {
+        TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, false);
+        String[] sharedLibrary = new String[] {"a.dex", "b.dex"};
+        String[] contexts = DexoptUtils.getClassLoaderContexts(
+                data.info, sharedLibrary, data.pathsWithCode);
+
+        assertEquals(9, contexts.length);
+        assertEquals("PCL[a.dex:b.dex]", contexts[0]);
+        assertEquals("PCL[a.dex:b.dex:base.dex]", contexts[1]);
+        assertEquals("PCL[a.dex:b.dex:base.dex:base-1.dex]", contexts[2]);
+        assertEquals("PCL[a.dex:b.dex:base.dex:base-1.dex:base-2.dex]", contexts[3]);
+        assertEquals("PCL[a.dex:b.dex:base.dex:base-1.dex:base-2.dex:base-3.dex]", contexts[4]);
+        assertEquals(
+                "PCL[a.dex:b.dex:base.dex:base-1.dex:base-2.dex:base-3.dex:base-4.dex]",
+                contexts[5]);
+        assertEquals(
+                "PCL[a.dex:b.dex:base.dex:base-1.dex:base-2.dex:base-3.dex:base-4.dex:base-5.dex]",
+                contexts[6]);
+        assertEquals(null, contexts[7]);  // config split
+        assertEquals(
+                "PCL[a.dex:b.dex:base.dex:base-1.dex:base-2.dex:base-3.dex:base-4.dex:base-5.dex:base-6.dex:config-split-7.dex]",
+                contexts[8]);  // feature split with no dependency
+    }
+
+    @Test
+    public void testSplitChainNoIsolationNoSharedLibrary() {
+        TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, true);
+        data.info.privateFlags = data.info.privateFlags
+                & (~ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING);
+        String[] contexts = DexoptUtils.getClassLoaderContexts(
+                data.info, null, data.pathsWithCode);
+
+        assertEquals(9, contexts.length);
+        assertEquals("PCL[]", contexts[0]);
+        assertEquals("PCL[base.dex]", contexts[1]);
+        assertEquals("PCL[base.dex:base-1.dex]", contexts[2]);
+        assertEquals("PCL[base.dex:base-1.dex:base-2.dex]", contexts[3]);
+        assertEquals("PCL[base.dex:base-1.dex:base-2.dex:base-3.dex]", contexts[4]);
+        assertEquals("PCL[base.dex:base-1.dex:base-2.dex:base-3.dex:base-4.dex]", contexts[5]);
+        assertEquals(
+                "PCL[base.dex:base-1.dex:base-2.dex:base-3.dex:base-4.dex:base-5.dex]",
+                contexts[6]);
+        assertEquals(null, contexts[7]);  // config split
+        assertEquals(
+                "PCL[base.dex:base-1.dex:base-2.dex:base-3.dex:base-4.dex:base-5.dex:base-6.dex:config-split-7.dex]",
+                contexts[8]);  // feature split with no dependency
+    }
+
+    @Test
+    public void testSplitChainNoSharedLibraries() {
+        TestData data = createMockApplicationInfo(
+                DELEGATE_LAST_CLASS_LOADER_NAME, true, true);
+        String[] contexts = DexoptUtils.getClassLoaderContexts(
+                data.info, null, data.pathsWithCode);
+
+        assertEquals(9, contexts.length);
+        assertEquals("PCL[]", contexts[0]);
+        assertEquals("PCL[];PCL[base-2.dex];PCL[base-4.dex];PCL[base.dex]", contexts[1]);
+        assertEquals("PCL[];PCL[base-4.dex];PCL[base.dex]", contexts[2]);
+        assertEquals("PCL[];PCL[base-4.dex];PCL[base.dex]", contexts[3]);
+        assertEquals("PCL[];PCL[base.dex]", contexts[4]);
+        assertEquals("PCL[];PCL[base.dex]", contexts[5]);
+        assertEquals("PCL[];PCL[base-5.dex];PCL[base.dex]", contexts[6]);
+        assertEquals(null, contexts[7]);  // config split
+        assertEquals("PCL[]", contexts[8]);  // feature split with no dependency
+    }
+
+    @Test
+    public void testSplitChainWithNullPrimaryClassLoader() {
+        // A null classLoaderName should mean PathClassLoader.
+        TestData data = createMockApplicationInfo(null, true, true);
+        String[] sharedLibrary = new String[] {"a.dex", "b.dex"};
+        String[] contexts = DexoptUtils.getClassLoaderContexts(
+                data.info, sharedLibrary, data.pathsWithCode);
+
+        assertEquals(9, contexts.length);
+        assertEquals("PCL[a.dex:b.dex]", contexts[0]);
+        assertEquals("PCL[];PCL[base-2.dex];PCL[base-4.dex];PCL[a.dex:b.dex:base.dex]", contexts[1]);
+        assertEquals("PCL[];PCL[base-4.dex];PCL[a.dex:b.dex:base.dex]", contexts[2]);
+        assertEquals("PCL[];PCL[base-4.dex];PCL[a.dex:b.dex:base.dex]", contexts[3]);
+        assertEquals("PCL[];PCL[a.dex:b.dex:base.dex]", contexts[4]);
+        assertEquals("PCL[];PCL[a.dex:b.dex:base.dex]", contexts[5]);
+        assertEquals("PCL[];PCL[base-5.dex];PCL[a.dex:b.dex:base.dex]", contexts[6]);
+        assertEquals(null, contexts[7]);  // config split
+        assertEquals("PCL[]", contexts[8]);  // feature split with no dependency
+    }
+
+    @Test
+    public void tesNoSplits() {
+        TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, false, false);
+        String[] sharedLibrary = new String[] {"a.dex", "b.dex"};
+        String[] contexts = DexoptUtils.getClassLoaderContexts(
+                data.info, sharedLibrary, data.pathsWithCode);
+
+        assertEquals(1, contexts.length);
+        assertEquals("PCL[a.dex:b.dex]", contexts[0]);
+    }
+
+    @Test
+    public void tesNoSplitsNullClassLoaderName() {
+        TestData data = createMockApplicationInfo(null, false, false);
+        String[] sharedLibrary = new String[] {"a.dex", "b.dex"};
+        String[] contexts = DexoptUtils.getClassLoaderContexts(
+                data.info, sharedLibrary, data.pathsWithCode);
+
+        assertEquals(1, contexts.length);
+        assertEquals("PCL[a.dex:b.dex]", contexts[0]);
+    }
+
+    @Test
+    public void tesNoSplitDelegateLast() {
+        TestData data = createMockApplicationInfo(
+                DELEGATE_LAST_CLASS_LOADER_NAME, false, false);
+        String[] sharedLibrary = new String[] {"a.dex", "b.dex"};
+        String[] contexts = DexoptUtils.getClassLoaderContexts(
+                data.info, sharedLibrary, data.pathsWithCode);
+
+        assertEquals(1, contexts.length);
+        assertEquals("PCL[a.dex:b.dex]", contexts[0]);
+    }
+
+    @Test
+    public void tesNoSplitsNoSharedLibraries() {
+        TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, false, false);
+        String[] contexts = DexoptUtils.getClassLoaderContexts(
+                data.info, null, data.pathsWithCode);
+
+        assertEquals(1, contexts.length);
+        assertEquals("PCL[]", contexts[0]);
+    }
+
+    @Test
+    public void tesNoSplitDelegateLastNoSharedLibraries() {
+        TestData data = createMockApplicationInfo(
+                DELEGATE_LAST_CLASS_LOADER_NAME, false, false);
+        String[] contexts = DexoptUtils.getClassLoaderContexts(
+                data.info, null, data.pathsWithCode);
+
+        assertEquals(1, contexts.length);
+        assertEquals("PCL[]", contexts[0]);
+    }
+
+    @Test
+    public void testContextWithNoCode() {
+        TestData data = createMockApplicationInfo(null, true, false);
+        Arrays.fill(data.pathsWithCode, false);
+
+        String[] sharedLibrary = new String[] {"a.dex", "b.dex"};
+        String[] contexts = DexoptUtils.getClassLoaderContexts(
+                data.info, sharedLibrary, data.pathsWithCode);
+
+        assertEquals(9, contexts.length);
+        assertEquals(null, contexts[0]);
+        assertEquals(null, contexts[1]);
+        assertEquals(null, contexts[2]);
+        assertEquals(null, contexts[3]);
+        assertEquals(null, contexts[4]);
+        assertEquals(null, contexts[5]);
+        assertEquals(null, contexts[6]);
+        assertEquals(null, contexts[7]);
+    }
+
+    @Test
+    public void testContextBaseNoCode() {
+        TestData data = createMockApplicationInfo(null, true, true);
+        data.pathsWithCode[0] = false;
+        String[] sharedLibrary = new String[] {"a.dex", "b.dex"};
+        String[] contexts = DexoptUtils.getClassLoaderContexts(
+                data.info, sharedLibrary, data.pathsWithCode);
+
+        assertEquals(9, contexts.length);
+        assertEquals(null, contexts[0]);
+        assertEquals("PCL[];PCL[base-2.dex];PCL[base-4.dex];PCL[a.dex:b.dex:base.dex]", contexts[1]);
+        assertEquals("PCL[];PCL[base-4.dex];PCL[a.dex:b.dex:base.dex]", contexts[2]);
+        assertEquals("PCL[];PCL[base-4.dex];PCL[a.dex:b.dex:base.dex]", contexts[3]);
+        assertEquals("PCL[];PCL[a.dex:b.dex:base.dex]", contexts[4]);
+        assertEquals("PCL[];PCL[a.dex:b.dex:base.dex]", contexts[5]);
+        assertEquals("PCL[];PCL[base-5.dex];PCL[a.dex:b.dex:base.dex]", contexts[6]);
+        assertEquals(null, contexts[7]);
+    }
+
+    @Test
+    public void testProcessContextForDexLoad() {
+        List<String> classLoaders = Arrays.asList(
+                DELEGATE_LAST_CLASS_LOADER_NAME,
+                PATH_CLASS_LOADER_NAME,
+                PATH_CLASS_LOADER_NAME);
+        List<String> classPaths = Arrays.asList(
+                String.join(File.pathSeparator, "foo.dex", "bar.dex"),
+                String.join(File.pathSeparator, "parent1.dex"),
+                String.join(File.pathSeparator, "parent2.dex", "parent3.dex"));
+        String[] context = DexoptUtils.processContextForDexLoad(classLoaders, classPaths);
+        assertNotNull(context);
+        assertEquals(2, context.length);
+        assertEquals("PCL[];PCL[parent1.dex];PCL[parent2.dex:parent3.dex]", context[0]);
+        assertEquals("PCL[foo.dex];PCL[parent1.dex];PCL[parent2.dex:parent3.dex]", context[1]);
+    }
+
+    @Test
+    public void testProcessContextForDexLoadSingleElement() {
+        List<String> classLoaders = Arrays.asList(PATH_CLASS_LOADER_NAME);
+        List<String> classPaths = Arrays.asList(
+                String.join(File.pathSeparator, "foo.dex", "bar.dex", "zoo.dex"));
+        String[] context = DexoptUtils.processContextForDexLoad(classLoaders, classPaths);
+        assertNotNull(context);
+        assertEquals(3, context.length);
+        assertEquals("PCL[]", context[0]);
+        assertEquals("PCL[foo.dex]", context[1]);
+        assertEquals("PCL[foo.dex:bar.dex]", context[2]);
+    }
+
+    @Test
+    public void testProcessContextForDexLoadUnsupported() {
+        List<String> classLoaders = Arrays.asList(
+                DELEGATE_LAST_CLASS_LOADER_NAME,
+                "unsupported.class.loader");
+        List<String> classPaths = Arrays.asList(
+                String.join(File.pathSeparator, "foo.dex", "bar.dex"),
+                String.join(File.pathSeparator, "parent1.dex"));
+        String[] context = DexoptUtils.processContextForDexLoad(classLoaders, classPaths);
+        assertNull(context);
+    }
+
+    @Test
+    public void testProcessContextForDexLoadIllegalCallEmptyList() {
+        boolean gotException = false;
+        try {
+            DexoptUtils.processContextForDexLoad(Collections.emptyList(), Collections.emptyList());
+        } catch (IllegalArgumentException ignore) {
+            gotException = true;
+        }
+        assertTrue(gotException);
+    }
+
+    @Test
+    public void testProcessContextForDexLoadIllegalCallDifferentSize() {
+        boolean gotException = false;
+        try {
+            DexoptUtils.processContextForDexLoad(Collections.emptyList(), Arrays.asList("a"));
+        } catch (IllegalArgumentException ignore) {
+            gotException = true;
+        }
+        assertTrue(gotException);
+    }
+
+    @Test
+    public void testEncodeClassLoader() {
+        assertEquals(SKIP_SHARED_LIBRARY_CHECK, DexoptUtils.encodeClassLoader(
+                SKIP_SHARED_LIBRARY_CHECK, "dalvik.system.PathClassLoader"));
+        assertEquals(SKIP_SHARED_LIBRARY_CHECK, DexoptUtils.encodeClassLoader(
+                SKIP_SHARED_LIBRARY_CHECK, "dalvik.system.DexClassLoader"));
+        assertEquals(SKIP_SHARED_LIBRARY_CHECK, DexoptUtils.encodeClassLoader(
+                SKIP_SHARED_LIBRARY_CHECK, "dalvik.system.DelegateLastClassLoader"));
+        assertEquals("PCL[xyz]", DexoptUtils.encodeClassLoader("xyz",
+                "dalvik.system.PathClassLoader"));
+        assertEquals("PCL[xyz]", DexoptUtils.encodeClassLoader("xyz",
+                "dalvik.system.DexClassLoader"));
+        assertEquals("DLC[xyz]", DexoptUtils.encodeClassLoader("xyz",
+                "dalvik.system.DelegateLastClassLoader"));
+        assertEquals("PCL[xyz]", DexoptUtils.encodeClassLoader("xyz", null));
+        assertEquals("abc[xyz]", DexoptUtils.encodeClassLoader("xyz", "abc"));
+
+        try {
+            DexoptUtils.encodeClassLoader(null, "abc");
+            fail(); // Exception should be caught.
+        } catch (NullPointerException expected) {}
+    }
+
+    @Test
+    public void testEncodeClassLoaderChain() {
+        assertEquals(SKIP_SHARED_LIBRARY_CHECK, DexoptUtils.encodeClassLoaderChain(
+                SKIP_SHARED_LIBRARY_CHECK, "PCL[a]"));
+        assertEquals(SKIP_SHARED_LIBRARY_CHECK, DexoptUtils.encodeClassLoaderChain("PCL[a]",
+                SKIP_SHARED_LIBRARY_CHECK));
+        assertEquals("PCL[a];DLC[b]", DexoptUtils.encodeClassLoaderChain("PCL[a]",
+                "DLC[b]"));
+        assertEquals(SKIP_SHARED_LIBRARY_CHECK, DexoptUtils.encodeClassLoaderChain("PCL[a]",
+                SKIP_SHARED_LIBRARY_CHECK));
+
+        try {
+            DexoptUtils.encodeClassLoaderChain("a", null);
+            fail(); // exception is expected
+        } catch (NullPointerException expected) {}
+
+        try {
+            DexoptUtils.encodeClassLoaderChain(null, "b");
+            fail(); // exception is expected
+        } catch (NullPointerException expected) {}
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
index 2e99433..69a148d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
@@ -21,6 +21,7 @@
 import android.support.test.runner.AndroidJUnit4;
 import dalvik.system.VMRuntime;
 
+import java.util.Collections;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -72,25 +73,25 @@
         String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
 
         mFooBaseUser0 = new TestData(fooPackageName,
-                fooCodeDir + "base.apk", 0, isa, false, true);
+                fooCodeDir + "base.apk", 0, isa, false, true, fooPackageName);
 
         mFooSplit1User0 = new TestData(fooPackageName,
-                fooCodeDir + "split-1.apk", 0, isa, false, true);
+                fooCodeDir + "split-1.apk", 0, isa, false, true, fooPackageName);
 
         mFooSplit2UsedByOtherApps0 = new TestData(fooPackageName,
-                fooCodeDir + "split-2.apk", 0, isa, true, true);
+                fooCodeDir + "split-2.apk", 0, isa, true, true, "used.by.other.com");
 
         mFooSecondary1User0 = new TestData(fooPackageName,
-                fooDataDir + "sec-1.dex", 0, isa, false, false);
+                fooDataDir + "sec-1.dex", 0, isa, false, false, fooPackageName);
 
         mFooSecondary1User1 = new TestData(fooPackageName,
-                fooDataDir + "sec-1.dex", 1, isa, false, false);
+                fooDataDir + "sec-1.dex", 1, isa, false, false, fooPackageName);
 
         mFooSecondary2UsedByOtherApps0 = new TestData(fooPackageName,
-                fooDataDir + "sec-2.dex", 0, isa, true, false);
+                fooDataDir + "sec-2.dex", 0, isa, true, false, "used.by.other.com");
 
         mInvalidIsa = new TestData(fooPackageName,
-                fooCodeDir + "base.apk", 0, "INVALID_ISA", false, true);
+                fooCodeDir + "base.apk", 0, "INVALID_ISA", false, true, "INALID_USER");
 
         String barPackageName = "com.google.bar";
         String barCodeDir = "/data/app/com.google.bar/";
@@ -98,11 +99,11 @@
         String barDataDir1 = "/data/user/1/com.google.bar/";
 
         mBarBaseUser0 = new TestData(barPackageName,
-                barCodeDir + "base.apk", 0, isa, false, true);
+                barCodeDir + "base.apk", 0, isa, false, true, barPackageName);
         mBarSecondary1User0 = new TestData(barPackageName,
-                barDataDir + "sec-1.dex", 0, isa, false, false);
+                barDataDir + "sec-1.dex", 0, isa, false, false, barPackageName);
         mBarSecondary2User1 = new TestData(barPackageName,
-                barDataDir1 + "sec-2.dex", 1, isa, false, false);
+                barDataDir1 + "sec-2.dex", 1, isa, false, false, barPackageName);
     }
 
     @Test
@@ -249,7 +250,10 @@
         Map<String, Set<Integer>> packageToUsersMap = new HashMap<>();
         packageToUsersMap.put(mBarSecondary2User1.mPackageName,
                 new HashSet<>(Arrays.asList(mBarSecondary2User1.mOwnerUserId)));
-        mPackageDexUsage.syncData(packageToUsersMap);
+        Map<String, Set<String>> packageToCodePaths = new HashMap<>();
+        packageToCodePaths.put(mBarBaseUser0.mPackageName,
+                new HashSet<>(Arrays.asList(mBarBaseUser0.mDexFile)));
+        mPackageDexUsage.syncData(packageToUsersMap, packageToCodePaths);
 
         // Assert that only user 1 files are there.
         assertPackageDexUsage(mBarBaseUser0, mBarSecondary2User1);
@@ -319,7 +323,8 @@
             mFooSplit2UsedByOtherApps0.mOwnerUserId,
             mFooSplit2UsedByOtherApps0.mLoaderIsa,
             /*mIsUsedByOtherApps*/false,
-            mFooSplit2UsedByOtherApps0.mPrimaryOrSplit);
+            mFooSplit2UsedByOtherApps0.mPrimaryOrSplit,
+            mFooSplit2UsedByOtherApps0.mUsedBy);
         assertPackageDexUsage(noLongerUsedByOtherApps);
     }
 
@@ -332,14 +337,223 @@
         assertFalse(mPackageDexUsage.clearUsedByOtherApps(mFooSplit2UsedByOtherApps0.mPackageName));
     }
 
+    @Test
+    public void testRecordDexFileUsers() {
+        PackageDexUsage packageDexUsageRecordUsers = new PackageDexUsage();
+        Set<String> users = new HashSet<>(Arrays.asList(
+                new String[] {"another.package.1"}));
+        Set<String> usersExtra = new HashSet<>(Arrays.asList(
+                new String[] {"another.package.2", "another.package.3"}));
+
+        assertTrue(record(packageDexUsageRecordUsers, mFooSplit2UsedByOtherApps0, users));
+        assertTrue(record(packageDexUsageRecordUsers, mFooSplit2UsedByOtherApps0, usersExtra));
+
+        assertTrue(record(packageDexUsageRecordUsers, mFooSecondary1User0, users));
+        assertTrue(record(packageDexUsageRecordUsers, mFooSecondary1User0, usersExtra));
+
+        packageDexUsageRecordUsers = writeAndReadBack(packageDexUsageRecordUsers);
+        // Verify that the users were recorded.
+        Set<String> userAll = new HashSet<>(users);
+        userAll.addAll(usersExtra);
+        assertPackageDexUsage(packageDexUsageRecordUsers, userAll, mFooSplit2UsedByOtherApps0,
+                mFooSecondary1User0);
+    }
+
+    @Test
+    public void testRecordDexFileUsersNotTheOwningPackage() {
+        PackageDexUsage packageDexUsageRecordUsers = new PackageDexUsage();
+        Set<String> users = new HashSet<>(Arrays.asList(
+                new String[] {mFooSplit2UsedByOtherApps0.mPackageName}));
+        Set<String> usersExtra = new HashSet<>(Arrays.asList(
+                new String[] {"another.package.2", "another.package.3"}));
+
+        assertTrue(record(packageDexUsageRecordUsers, mFooSplit2UsedByOtherApps0, users));
+        assertTrue(record(packageDexUsageRecordUsers, mFooSplit2UsedByOtherApps0, usersExtra));
+
+        assertTrue(record(packageDexUsageRecordUsers, mFooSecondary1User0, users));
+        assertTrue(record(packageDexUsageRecordUsers, mFooSecondary1User0, usersExtra));
+
+        packageDexUsageRecordUsers = writeAndReadBack(packageDexUsageRecordUsers);
+        // Verify that only the non owning packages were recorded.
+        assertPackageDexUsage(packageDexUsageRecordUsers, usersExtra, mFooSplit2UsedByOtherApps0,
+                mFooSecondary1User0);
+    }
+
+    @Test
+    public void testRecordClassLoaderContextVariableContext() {
+        // Record a secondary dex file.
+        assertTrue(record(mFooSecondary1User0));
+        // Now update its context.
+        TestData fooSecondary1User0NewContext = mFooSecondary1User0.updateClassLoaderContext(
+                "PCL[new_context.dex]");
+        assertTrue(record(fooSecondary1User0NewContext));
+
+        // Not check that the context was switch to variable.
+        TestData expectedContext = mFooSecondary1User0.updateClassLoaderContext(
+                PackageDexUsage.VARIABLE_CLASS_LOADER_CONTEXT);
+
+        assertPackageDexUsage(null, expectedContext);
+        writeAndReadBack();
+        assertPackageDexUsage(null, expectedContext);
+    }
+
+    @Test
+    public void testRecordClassLoaderContextUnsupportedContext() {
+        // Record a secondary dex file.
+        assertTrue(record(mFooSecondary1User0));
+        // Now update its context.
+        TestData unsupportedContext = mFooSecondary1User0.updateClassLoaderContext(
+                PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT);
+        assertTrue(record(unsupportedContext));
+
+        assertPackageDexUsage(null, unsupportedContext);
+        writeAndReadBack();
+        assertPackageDexUsage(null, unsupportedContext);
+    }
+
+    @Test
+    public void testRecordClassLoaderContextTransitionFromUnknown() {
+        // Record a secondary dex file.
+        TestData unknownContext = mFooSecondary1User0.updateClassLoaderContext(
+                PackageDexUsage.UNKNOWN_CLASS_LOADER_CONTEXT);
+        assertTrue(record(unknownContext));
+
+        assertPackageDexUsage(null, unknownContext);
+        writeAndReadBack();
+        assertPackageDexUsage(null, unknownContext);
+
+        // Now update the secondary dex record with a class loader context. This simulates the
+        // version 2 to version 3 upgrade.
+
+        assertTrue(record(mFooSecondary1User0));
+
+        assertPackageDexUsage(null, mFooSecondary1User0);
+        writeAndReadBack();
+        assertPackageDexUsage(null, mFooSecondary1User0);
+    }
+
+    @Test
+    public void testDexUsageClassLoaderContext() {
+        final boolean isUsedByOtherApps = false;
+        final int userId = 0;
+        PackageDexUsage.DexUseInfo validContext = new DexUseInfo(isUsedByOtherApps, userId,
+                "valid_context", "arm");
+        assertFalse(validContext.isUnknownClassLoaderContext());
+        assertFalse(validContext.isUnsupportedClassLoaderContext());
+        assertFalse(validContext.isVariableClassLoaderContext());
+
+        PackageDexUsage.DexUseInfo unsupportedContext = new DexUseInfo(isUsedByOtherApps, userId,
+                PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT, "arm");
+        assertFalse(unsupportedContext.isUnknownClassLoaderContext());
+        assertTrue(unsupportedContext.isUnsupportedClassLoaderContext());
+        assertFalse(unsupportedContext.isVariableClassLoaderContext());
+
+        PackageDexUsage.DexUseInfo variableContext = new DexUseInfo(isUsedByOtherApps, userId,
+                PackageDexUsage.VARIABLE_CLASS_LOADER_CONTEXT, "arm");
+        assertFalse(variableContext.isUnknownClassLoaderContext());
+        assertFalse(variableContext.isUnsupportedClassLoaderContext());
+        assertTrue(variableContext.isVariableClassLoaderContext());
+
+        PackageDexUsage.DexUseInfo unknownContext = new DexUseInfo(isUsedByOtherApps, userId,
+                PackageDexUsage.UNKNOWN_CLASS_LOADER_CONTEXT, "arm");
+        assertTrue(unknownContext.isUnknownClassLoaderContext());
+        assertFalse(unknownContext.isUnsupportedClassLoaderContext());
+        assertFalse(unknownContext.isVariableClassLoaderContext());
+    }
+
+    @Test
+    public void testReadVersion1() {
+        String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
+        // Equivalent to
+        //   record(mFooSplit2UsedByOtherApps0);
+        //   record(mFooSecondary1User0);
+        //   record(mFooSecondary2UsedByOtherApps0);
+        //   record(mBarBaseUser0);
+        //   record(mBarSecondary1User0);
+        String content = "PACKAGE_MANAGER__PACKAGE_DEX_USAGE__1\n"
+                + "com.google.foo,1\n"
+                + "#/data/user/0/com.google.foo/sec-1.dex\n"
+                + "0,0," + isa + "\n"
+                + "#/data/user/0/com.google.foo/sec-2.dex\n"
+                + "0,1," + isa + "\n"
+                + "com.google.bar,0\n"
+                + "#/data/user/0/com.google.bar/sec-1.dex\n"
+                + "0,0," + isa + "\n";
+
+        PackageDexUsage packageDexUsage = new PackageDexUsage();
+        try {
+            packageDexUsage.read(new StringReader(content));
+        } catch (IOException e) {
+            fail();
+        }
+
+        // After the read we must sync the data to fill the missing information on the code paths.
+        Map<String, Set<Integer>> packageToUsersMap = new HashMap<>();
+        Map<String, Set<String>> packageToCodePaths = new HashMap<>();
+
+        // Handle foo package.
+        packageToUsersMap.put(mFooSplit2UsedByOtherApps0.mPackageName,
+            new HashSet<>(Arrays.asList(mFooSplit2UsedByOtherApps0.mOwnerUserId)));
+        packageToCodePaths.put(mFooSplit2UsedByOtherApps0.mPackageName,
+            new HashSet<>(Arrays.asList(mFooSplit2UsedByOtherApps0.mDexFile,
+                mFooSplit1User0.mDexFile, mFooBaseUser0.mDexFile)));
+        // Handle bar package.
+        packageToUsersMap.put(mBarBaseUser0.mPackageName,
+            new HashSet<>(Arrays.asList(mBarBaseUser0.mOwnerUserId)));
+        packageToCodePaths.put(mBarBaseUser0.mPackageName,
+            new HashSet<>(Arrays.asList(mBarBaseUser0.mDexFile)));
+
+        // Sync the data.
+        packageDexUsage.syncData(packageToUsersMap, packageToCodePaths);
+
+        // Update the class loaders to unknown before asserting if needed. Before version 2 we
+        // didn't have any.
+        String unknown = PackageDexUsage.UNKNOWN_CLASS_LOADER_CONTEXT;
+        TestData fooBaseUser0 = mFooBaseUser0.updateClassLoaderContext(unknown);
+        TestData fooSplit1User0 = mFooSplit1User0.updateClassLoaderContext(unknown);
+        TestData fooSplit2UsedByOtherApps0 =
+            mFooSplit2UsedByOtherApps0.updateClassLoaderContext(unknown);
+        TestData fooSecondary1User0 = mFooSecondary1User0.updateClassLoaderContext(unknown);
+        TestData fooSecondary2UsedByOtherApps0 =
+            mFooSecondary2UsedByOtherApps0.updateClassLoaderContext(unknown);
+        TestData barBaseUser0 = mBarBaseUser0.updateClassLoaderContext(unknown);
+        TestData barSecondary1User0 = mBarSecondary1User0.updateClassLoaderContext(unknown);
+
+        // Assert foo code paths. Note that we ignore the users during upgrade.
+        final Set<String> ignoredUsers = null;
+        assertPackageDexUsage(packageDexUsage, ignoredUsers,
+            fooSplit2UsedByOtherApps0, fooSecondary1User0, fooSecondary2UsedByOtherApps0);
+        // Because fooSplit2UsedByOtherApps0 is used by others, all the other code paths must
+        // share the same data.
+        assertPackageDexUsage(packageDexUsage, ignoredUsers,
+            fooSplit1User0.updateUseByOthers(true),
+            fooSecondary1User0, fooSecondary2UsedByOtherApps0);
+        assertPackageDexUsage(packageDexUsage, ignoredUsers, fooBaseUser0.updateUseByOthers(true),
+            fooSecondary1User0, fooSecondary2UsedByOtherApps0);
+
+        // Assert bar code paths. Note that we ignore the users during upgrade.
+        assertPackageDexUsage(packageDexUsage, ignoredUsers, barBaseUser0, barSecondary1User0);
+    }
+
     private void assertPackageDexUsage(TestData primary, TestData... secondaries) {
+        assertPackageDexUsage(mPackageDexUsage, null, primary, secondaries);
+    }
+
+    private void assertPackageDexUsage(PackageDexUsage packageDexUsage, Set<String> users,
+            TestData primary, TestData... secondaries) {
         String packageName = primary == null ? secondaries[0].mPackageName : primary.mPackageName;
-        boolean primaryUsedByOtherApps = primary == null ? false : primary.mUsedByOtherApps;
-        PackageUseInfo pInfo = mPackageDexUsage.getPackageUseInfo(packageName);
+        boolean primaryUsedByOtherApps = primary != null && primary.mUsedByOtherApps;
+        PackageUseInfo pInfo = packageDexUsage.getPackageUseInfo(packageName);
 
         // Check package use info
         assertNotNull(pInfo);
-        assertEquals(primaryUsedByOtherApps, pInfo.isUsedByOtherApps());
+        if (primary != null) {
+            assertEquals(primaryUsedByOtherApps, pInfo.isUsedByOtherApps(primary.mDexFile));
+            if (users != null) {
+                assertEquals(pInfo.getLoadingPackages(primary.mDexFile), users);
+            }
+        }
+
         Map<String, DexUseInfo> dexUseInfoMap = pInfo.getDexUseInfoMap();
         assertEquals(secondaries.length, dexUseInfoMap.size());
 
@@ -351,24 +565,45 @@
             assertEquals(testData.mOwnerUserId, dInfo.getOwnerUserId());
             assertEquals(1, dInfo.getLoaderIsas().size());
             assertTrue(dInfo.getLoaderIsas().contains(testData.mLoaderIsa));
+            if (users != null) {
+                 assertEquals(dInfo.getLoadingPackages(), users);
+            }
+
+            assertEquals(testData.mClassLoaderContext, dInfo.getClassLoaderContext());
         }
     }
 
     private boolean record(TestData testData) {
         return mPackageDexUsage.record(testData.mPackageName, testData.mDexFile,
-                testData.mOwnerUserId, testData.mLoaderIsa, testData.mUsedByOtherApps,
-                testData.mPrimaryOrSplit);
+               testData.mOwnerUserId, testData.mLoaderIsa, testData.mUsedByOtherApps,
+               testData.mPrimaryOrSplit, testData.mUsedBy, testData.mClassLoaderContext);
+    }
+
+    private boolean record(PackageDexUsage packageDexUsage, TestData testData, Set<String> users) {
+        boolean result = true;
+        for (String user : users) {
+            result = result && packageDexUsage.record(testData.mPackageName, testData.mDexFile,
+                    testData.mOwnerUserId, testData.mLoaderIsa, testData.mUsedByOtherApps,
+                    testData.mPrimaryOrSplit, user, testData.mClassLoaderContext);
+        }
+        return result;
     }
 
     private void writeAndReadBack() {
+        mPackageDexUsage = writeAndReadBack(mPackageDexUsage);
+    }
+
+    private PackageDexUsage writeAndReadBack(PackageDexUsage packageDexUsage) {
         try {
             StringWriter writer = new StringWriter();
-            mPackageDexUsage.write(writer);
+            packageDexUsage.write(writer);
 
-            mPackageDexUsage = new PackageDexUsage();
-            mPackageDexUsage.read(new StringReader(writer.toString()));
+            PackageDexUsage newPackageDexUsage = new PackageDexUsage();
+            newPackageDexUsage.read(new StringReader(writer.toString()));
+            return newPackageDexUsage;
         } catch (IOException e) {
             fail("Unexpected IOException: " + e.getMessage());
+            return null;
         }
     }
 
@@ -379,16 +614,35 @@
         private final String mLoaderIsa;
         private final boolean mUsedByOtherApps;
         private final boolean mPrimaryOrSplit;
+        private final String mUsedBy;
+        private final String mClassLoaderContext;
 
         private TestData(String packageName, String dexFile, int ownerUserId,
-                 String loaderIsa, boolean isUsedByOtherApps, boolean primaryOrSplit) {
+                String loaderIsa, boolean isUsedByOtherApps, boolean primaryOrSplit, String usedBy) {
+            this(packageName, dexFile, ownerUserId, loaderIsa, isUsedByOtherApps, primaryOrSplit,
+                    usedBy, "DefaultClassLoaderContextFor_" + dexFile);
+        }
+        private TestData(String packageName, String dexFile, int ownerUserId,
+                String loaderIsa, boolean isUsedByOtherApps, boolean primaryOrSplit, String usedBy,
+                String classLoaderContext) {
             mPackageName = packageName;
             mDexFile = dexFile;
             mOwnerUserId = ownerUserId;
             mLoaderIsa = loaderIsa;
             mUsedByOtherApps = isUsedByOtherApps;
             mPrimaryOrSplit = primaryOrSplit;
+            mUsedBy = usedBy;
+            mClassLoaderContext = classLoaderContext;
         }
 
+        private TestData updateClassLoaderContext(String newContext) {
+            return new TestData(mPackageName, mDexFile, mOwnerUserId, mLoaderIsa, mUsedByOtherApps,
+                    mPrimaryOrSplit, mUsedBy, newContext);
+        }
+
+        private TestData updateUseByOthers(boolean newUsedByOthers) {
+            return new TestData(mPackageName, mDexFile, mOwnerUserId, mLoaderIsa, newUsedByOthers,
+                mPrimaryOrSplit, mUsedBy, mClassLoaderContext);
+        }
     }
 }
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 d12c07a..14b1ce1 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -20,6 +20,7 @@
 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
 import android.os.PowerManager;
 import android.os.PowerSaveState;
+import android.os.SystemProperties;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.TextUtils;
@@ -44,17 +45,14 @@
     private static final float PRECISION = 0.001f;
     private static final float BRIGHTNESS_FACTOR = 0.7f;
     private static final boolean BATTERY_SAVER_ENABLED = true;
-    private static final String LAST_REBOOT_REASON = "last_reboot_reason";
+    private static final String TEST_LAST_REBOOT_PROPERTY = "test.sys.boot.reason";
 
     private @Mock BatterySaverPolicy mBatterySaverPolicy;
     private PowerManagerService mService;
     private PowerSaveState mPowerSaveState;
     private DisplayPowerRequest mDisplayPowerRequest;
-    private File mTempReason;
 
     @Rule
-    public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
     public void setUp() throws Exception {
         super.setUp();
         MockitoAnnotations.initMocks(this);
@@ -68,8 +66,6 @@
                 .thenReturn(mPowerSaveState);
         mDisplayPowerRequest = new DisplayPowerRequest();
         mService = new PowerManagerService(getContext(), mBatterySaverPolicy);
-        temporaryFolder.create();
-        mTempReason = temporaryFolder.newFile(LAST_REBOOT_REASON);
     }
 
     @SmallTest
@@ -82,14 +78,9 @@
 
     @SmallTest
     public void testGetLastShutdownReasonInternal() {
-        try {
-            FileWriter writer = new FileWriter(mTempReason);
-            writer.append("thermal-shutdown\n");
-            writer.close();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        int reason = mService.getLastShutdownReasonInternal(mTempReason);
+        SystemProperties.set(TEST_LAST_REBOOT_PROPERTY, "shutdown,thermal");
+        int reason = mService.getLastShutdownReasonInternal(TEST_LAST_REBOOT_PROPERTY);
+        SystemProperties.set(TEST_LAST_REBOOT_PROPERTY, "");
         assertThat(reason).isEqualTo(PowerManager.SHUTDOWN_REASON_THERMAL_SHUTDOWN);
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
deleted file mode 100644
index 6706969..0000000
--- a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
+++ /dev/null
@@ -1,156 +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.server.retaildemo;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.pm.IPackageInstallObserver2;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.os.FileUtils;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.test.mock.MockContentResolver;
-
-import com.android.internal.util.test.FakeSettingsProvider;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.io.File;
-import java.util.ArrayList;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class PreloadAppsInstallerTest {
-    private static final int TEST_DEMO_USER = 111;
-
-    private Context mContext;
-    private @Mock IPackageManager mIpm;
-    private MockContentResolver mContentResolver;
-    private File mPreloadsAppsDirectory;
-    private String[] mPreloadedApps =
-            new String[] {"test1.apk.preload", "test2.apk.preload", "test3.apk.preload"};
-    private ArrayList<String> mPreloadedAppPaths = new ArrayList<>();
-
-    private PreloadAppsInstaller mInstaller;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
-        mContentResolver = new MockContentResolver(mContext);
-        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
-        when(mContext.getContentResolver()).thenReturn(mContentResolver);
-        initializePreloadedApps();
-        Settings.Secure.putStringForUser(mContentResolver,
-                Settings.Secure.DEMO_USER_SETUP_COMPLETE, "0", TEST_DEMO_USER);
-
-        mInstaller = new PreloadAppsInstaller(mContext, mIpm, mPreloadsAppsDirectory);
-    }
-
-    private void initializePreloadedApps() throws Exception {
-        mPreloadsAppsDirectory = new File(InstrumentationRegistry.getContext().getFilesDir(),
-                 "test_preload_apps_dir");
-        mPreloadsAppsDirectory.mkdir();
-        for (String name : mPreloadedApps) {
-            final File f = new File(mPreloadsAppsDirectory, name);
-            f.createNewFile();
-            mPreloadedAppPaths.add(f.getPath());
-        }
-    }
-
-    @After
-    public void tearDown() {
-        if (mPreloadsAppsDirectory != null) {
-            FileUtils.deleteContentsAndDir(mPreloadsAppsDirectory);
-        }
-    }
-
-    @Test
-    public void testInstallApps() throws Exception {
-        mInstaller.installApps(TEST_DEMO_USER);
-        for (String path : mPreloadedAppPaths) {
-            ArgumentCaptor<IPackageInstallObserver2> observer =
-                    ArgumentCaptor.forClass(IPackageInstallObserver2.class);
-            verify(mIpm).installPackageAsUser(eq(path), observer.capture(), anyInt(),
-                    anyString(), eq(TEST_DEMO_USER));
-            observer.getValue().onPackageInstalled(path, PackageManager.INSTALL_SUCCEEDED,
-                    null, null);
-            // Verify that we try to install the package in system user.
-            verify(mIpm).installExistingPackageAsUser(path, UserHandle.USER_SYSTEM,
-                    0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
-        }
-        assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed",
-                "1",
-                Settings.Secure.getStringForUser(mContentResolver,
-                        Settings.Secure.DEMO_USER_SETUP_COMPLETE, TEST_DEMO_USER));
-    }
-
-    @Test
-    public void testInstallApps_noPreloads() throws Exception {
-        // Delete all files in preloaded apps directory - no preloaded apps
-        FileUtils.deleteContents(mPreloadsAppsDirectory);
-        mInstaller.installApps(TEST_DEMO_USER);
-        assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed",
-                "1",
-                Settings.Secure.getStringForUser(mContentResolver,
-                        Settings.Secure.DEMO_USER_SETUP_COMPLETE, TEST_DEMO_USER));
-    }
-
-    @Test
-    public void testInstallApps_installationFails() throws Exception {
-        mInstaller.installApps(TEST_DEMO_USER);
-        for (int i = 0; i < mPreloadedAppPaths.size(); ++i) {
-            ArgumentCaptor<IPackageInstallObserver2> observer =
-                    ArgumentCaptor.forClass(IPackageInstallObserver2.class);
-            final String path = mPreloadedAppPaths.get(i);
-            verify(mIpm).installPackageAsUser(eq(path), observer.capture(), anyInt(),
-                    anyString(), eq(TEST_DEMO_USER));
-            if (i == 0) {
-                observer.getValue().onPackageInstalled(path, PackageManager.INSTALL_FAILED_DEXOPT,
-                        null, null);
-                continue;
-            }
-            observer.getValue().onPackageInstalled(path, PackageManager.INSTALL_SUCCEEDED,
-                    null, null);
-            // Verify that we try to install the package in system user.
-            verify(mIpm).installExistingPackageAsUser(path, UserHandle.USER_SYSTEM,
-                    0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
-        }
-        assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed",
-                "1",
-                Settings.Secure.getStringForUser(mContentResolver,
-                        Settings.Secure.DEMO_USER_SETUP_COMPLETE, TEST_DEMO_USER));
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
deleted file mode 100644
index 2e13d29..0000000
--- a/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
+++ /dev/null
@@ -1,476 +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.server.retaildemo;
-
-import static com.android.server.retaildemo.RetailDemoModeService.SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.Manifest;
-import android.app.ActivityManagerInternal;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.RetailDemoModeServiceInternal;
-import android.app.job.JobInfo;
-import android.app.job.JobScheduler;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
-import android.content.res.Configuration;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.net.wifi.WifiManager;
-import android.os.FileUtils;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.CallLog;
-import android.provider.MediaStore;
-import android.provider.Settings;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.test.mock.MockContentProvider;
-import android.test.mock.MockContentResolver;
-import android.util.ArrayMap;
-
-import com.android.internal.util.test.FakeSettingsProvider;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.server.SystemService;
-import com.android.server.retaildemo.RetailDemoModeService.Injector;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.mockito.compat.ArgumentMatcher;
-
-import java.io.File;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class RetailDemoModeServiceTest {
-    private static final int TEST_DEMO_USER = 111;
-    private static final long SETUP_COMPLETE_TIMEOUT_MS = 2000; // 2 sec
-    private static final String TEST_CAMERA_PKG = "test.cameraapp";
-    private static final String TEST_PRELOADS_DIR_NAME = "test_preloads";
-
-    private Context mContext;
-    private @Mock UserManager mUm;
-    private @Mock PackageManager mPm;
-    private @Mock IPackageManager mIpm;
-    private @Mock NotificationManager mNm;
-    private @Mock ActivityManagerInternal mAmi;
-    private @Mock AudioManager mAudioManager;
-    private @Mock WifiManager mWifiManager;
-    private @Mock LockPatternUtils mLockPatternUtils;
-    private @Mock JobScheduler mJobScheduler;
-    private MockPreloadAppsInstaller mPreloadAppsInstaller;
-    private MockContentResolver mContentResolver;
-    private MockContactsProvider mContactsProvider;
-    private Configuration mConfiguration;
-    private File mTestPreloadsDir;
-    private CountDownLatch mLatch;
-
-    private RetailDemoModeService mService;
-    private TestInjector mInjector;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
-        when(mContext.getSystemServiceName(eq(JobScheduler.class))).thenReturn(
-                Context.JOB_SCHEDULER_SERVICE);
-        when(mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE)).thenReturn(mJobScheduler);
-        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUm);
-        mContentResolver = new MockContentResolver(mContext);
-        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
-        mContactsProvider = new MockContactsProvider(mContext);
-        mContentResolver.addProvider(CallLog.AUTHORITY, mContactsProvider);
-        when(mContext.getContentResolver()).thenReturn(mContentResolver);
-        mPreloadAppsInstaller = new MockPreloadAppsInstaller(mContext);
-        mConfiguration = new Configuration();
-        mTestPreloadsDir = new File(InstrumentationRegistry.getContext().getFilesDir(),
-                TEST_PRELOADS_DIR_NAME);
-
-        Settings.Global.putString(mContentResolver, Settings.Global.RETAIL_DEMO_MODE_CONSTANTS, "");
-        Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_PROVISIONED, 1);
-        Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_DEMO_MODE, 1);
-
-        // Initialize RetailDemoModeService
-        mInjector = new TestInjector();
-        mService = new RetailDemoModeService(mInjector);
-        mService.onStart();
-    }
-
-    @After
-    public void tearDown() {
-        if (mTestPreloadsDir != null) {
-            FileUtils.deleteContentsAndDir(mTestPreloadsDir);
-        }
-    }
-
-    @Test
-    public void testDemoUserSetup() throws Exception {
-        mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
-
-        mLatch = new CountDownLatch(1);
-        final UserInfo userInfo = new UserInfo();
-        userInfo.id = TEST_DEMO_USER;
-        when(mUm.createUser(anyString(), anyInt())).thenReturn(userInfo);
-
-        setCameraPackage(TEST_CAMERA_PKG);
-        mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
-        assertEquals(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED + " property not set",
-                "1", mInjector.systemPropertiesGet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED));
-
-        final ArgumentCaptor<IntentFilter> intentFilter =
-                ArgumentCaptor.forClass(IntentFilter.class);
-        verify(mContext).registerReceiver(any(BroadcastReceiver.class), intentFilter.capture());
-        assertTrue("Not registered for " + Intent.ACTION_SCREEN_OFF,
-                intentFilter.getValue().hasAction(Intent.ACTION_SCREEN_OFF));
-
-        // Wait for the setup to complete.
-        mLatch.await(SETUP_COMPLETE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        ArgumentCaptor<Integer> flags = ArgumentCaptor.forClass(Integer.class);
-        verify(mUm).createUser(anyString(), flags.capture());
-        assertTrue("FLAG_DEMO not set during user creation",
-                (flags.getValue() & UserInfo.FLAG_DEMO) != 0);
-        assertTrue("FLAG_EPHEMERAL not set during user creation",
-                (flags.getValue() & UserInfo.FLAG_EPHEMERAL) != 0);
-        // Verify if necessary restrictions are being set.
-        final UserHandle user = UserHandle.of(TEST_DEMO_USER);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, user);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true, user);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, true, user);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER, true, user);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, true, user);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, false, user);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, true, UserHandle.SYSTEM);
-        // Verify if necessary settings are updated.
-        assertEquals("SKIP_FIRST_USE_HINTS setting is not set for demo user",
-                Settings.Secure.getIntForUser(mContentResolver,
-                        Settings.Secure.SKIP_FIRST_USE_HINTS, TEST_DEMO_USER),
-                1);
-        assertEquals("PACKAGE_VERIFIER_ENABLE settings should be set to 0 for demo user",
-                Settings.Global.getInt(mContentResolver,
-                        Settings.Global.PACKAGE_VERIFIER_ENABLE),
-                0);
-        // Verify if camera is granted location permission.
-        verify(mPm).grantRuntimePermission(TEST_CAMERA_PKG,
-                Manifest.permission.ACCESS_FINE_LOCATION, user);
-        // Verify call logs are cleared.
-        assertTrue("Call logs should be deleted", mContactsProvider.isCallLogDeleted());
-    }
-
-    @Test
-    public void testSettingsObserver_disableDemoMode() throws Exception {
-        final RetailDemoModeService.SettingsObserver observer =
-                mService.new SettingsObserver(new Handler(Looper.getMainLooper()));
-        final Uri deviceDemoModeUri = Settings.Global.getUriFor(Settings.Global.DEVICE_DEMO_MODE);
-        when(mUm.hasUserRestriction(UserManager.DISALLOW_SAFE_BOOT, UserHandle.SYSTEM))
-                .thenReturn(false);
-        Settings.Global.putInt(mContentResolver, Settings.Global.PACKAGE_VERIFIER_ENABLE, 1);
-        // Settings.Global.DEVICE_DEMO_MODE has been set to 1 initially.
-        observer.onChange(false, deviceDemoModeUri);
-        final ArgumentCaptor<BroadcastReceiver> receiver =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mContext).registerReceiver(receiver.capture(), any(IntentFilter.class));
-
-        Settings.Global.putInt(mContentResolver, Settings.Global.PACKAGE_VERIFIER_ENABLE, 0);
-        new File(mTestPreloadsDir, "dir1").mkdirs();
-        new File(mTestPreloadsDir, "file1").createNewFile();
-        Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_DEMO_MODE, 0);
-        observer.onChange(false, deviceDemoModeUri);
-        verify(mContext).unregisterReceiver(receiver.getValue());
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, false, UserHandle.SYSTEM);
-        assertEquals("Package verifier enable value has not been reset", 1,
-                Settings.Global.getInt(mContentResolver, Settings.Global.PACKAGE_VERIFIER_ENABLE));
-        Thread.sleep(20); // Wait for the deletion to complete.
-        // verify that the preloaded directory is emptied.
-        assertEquals("Preloads directory is not emptied",
-                0, mTestPreloadsDir.list().length);
-        // Verify that the expiration job was scheduled
-        verify(mJobScheduler).schedule(any(JobInfo.class));
-    }
-
-    @Test
-    public void testSettingsObserver_enableDemoMode() throws Exception {
-        final RetailDemoModeService.SettingsObserver observer =
-                mService.new SettingsObserver(new Handler(Looper.getMainLooper()));
-        final Uri deviceDemoModeUri = Settings.Global.getUriFor(Settings.Global.DEVICE_DEMO_MODE);
-        // Settings.Global.DEVICE_DEMO_MODE has been set to 1 initially.
-        observer.onChange(false, deviceDemoModeUri);
-        assertEquals(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED + " property not set",
-                "1", mInjector.systemPropertiesGet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED));
-
-        final ArgumentCaptor<IntentFilter> intentFilter =
-                ArgumentCaptor.forClass(IntentFilter.class);
-        verify(mContext).registerReceiver(any(BroadcastReceiver.class), intentFilter.capture());
-        assertTrue("Not registered for " + Intent.ACTION_SCREEN_OFF,
-                intentFilter.getValue().hasAction(Intent.ACTION_SCREEN_OFF));
-    }
-
-    @Test
-    public void testSwitchToDemoUser() {
-        // To make the RetailDemoModeService update it's internal state.
-        mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
-        final RetailDemoModeService.SettingsObserver observer =
-                mService.new SettingsObserver(new Handler(Looper.getMainLooper()));
-        observer.onChange(false, Settings.Global.getUriFor(Settings.Global.DEVICE_DEMO_MODE));
-
-        final UserInfo userInfo = new UserInfo(TEST_DEMO_USER, "demo_user",
-                UserInfo.FLAG_DEMO | UserInfo.FLAG_EPHEMERAL);
-        when(mUm.getUserInfo(TEST_DEMO_USER)).thenReturn(userInfo);
-        when(mWifiManager.isWifiEnabled()).thenReturn(false);
-        final int minVolume = -111;
-        for (int stream : RetailDemoModeService.VOLUME_STREAMS_TO_MUTE) {
-            when(mAudioManager.getStreamMinVolume(stream)).thenReturn(minVolume);
-        }
-
-        mService.onSwitchUser(TEST_DEMO_USER);
-        verify(mAmi).updatePersistentConfigurationForUser(mConfiguration, TEST_DEMO_USER);
-        for (int stream : RetailDemoModeService.VOLUME_STREAMS_TO_MUTE) {
-            verify(mAudioManager).setStreamVolume(stream, minVolume, 0);
-        }
-        verify(mLockPatternUtils).setLockScreenDisabled(true, TEST_DEMO_USER);
-        verify(mWifiManager).setWifiEnabled(true);
-    }
-
-    private void setCameraPackage(String pkgName) {
-        final ResolveInfo ri = new ResolveInfo();
-        final ActivityInfo ai = new ActivityInfo();
-        ai.packageName = pkgName;
-        ri.activityInfo = ai;
-        when(mPm.resolveActivityAsUser(
-                argThat(new IntentMatcher(MediaStore.ACTION_IMAGE_CAPTURE)),
-                anyInt(),
-                eq(TEST_DEMO_USER))).thenReturn(ri);
-    }
-
-    private class IntentMatcher extends ArgumentMatcher<Intent> {
-        private final Intent mIntent;
-
-        IntentMatcher(String action) {
-            mIntent = new Intent(action);
-        }
-
-        @Override
-        public boolean matchesObject(Object argument) {
-            if (argument instanceof Intent) {
-                return ((Intent) argument).filterEquals(mIntent);
-            }
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            return "Expected: " + mIntent;
-        }
-    }
-
-    private class MockContactsProvider extends MockContentProvider {
-        private boolean mCallLogDeleted;
-
-        MockContactsProvider(Context context) {
-            super(context);
-        }
-
-        @Override
-        public int delete(Uri uri, String selection, String[] selectionArgs) {
-            if (CallLog.Calls.CONTENT_URI.equals(uri)) {
-                mCallLogDeleted = true;
-            }
-            return 0;
-        }
-
-        public boolean isCallLogDeleted() {
-            return mCallLogDeleted;
-        }
-    }
-
-    private class MockPreloadAppsInstaller extends PreloadAppsInstaller {
-        MockPreloadAppsInstaller(Context context) {
-            super(context);
-        }
-
-        @Override
-        public void installApps(int userId) {
-        }
-    }
-
-    private class TestInjector extends Injector {
-        private ArrayMap<String, String> mSystemProperties = new ArrayMap<>();
-
-        TestInjector() {
-            super(mContext);
-        }
-
-        @Override
-        Context getContext() {
-            return mContext;
-        }
-
-        @Override
-        UserManager getUserManager() {
-            return mUm;
-        }
-
-        @Override
-        WifiManager getWifiManager() {
-            return mWifiManager;
-        }
-
-        @Override
-        void switchUser(int userId) {
-            if (mLatch != null) {
-                mLatch.countDown();
-            }
-        }
-
-        @Override
-        AudioManager getAudioManager() {
-            return mAudioManager;
-        }
-
-        @Override
-        NotificationManager getNotificationManager() {
-            return mNm;
-        }
-
-        @Override
-        ActivityManagerInternal getActivityManagerInternal() {
-            return mAmi;
-        }
-
-        @Override
-        PackageManager getPackageManager() {
-            return mPm;
-        }
-
-        @Override
-        IPackageManager getIPackageManager() {
-            return mIpm;
-        }
-
-        @Override
-        ContentResolver getContentResolver() {
-            return mContentResolver;
-        }
-
-        @Override
-        PreloadAppsInstaller getPreloadAppsInstaller() {
-            return mPreloadAppsInstaller;
-        }
-
-        @Override
-        void systemPropertiesSet(String key, String value) {
-            mSystemProperties.put(key, value);
-        }
-
-        @Override
-        void turnOffAllFlashLights(String[] cameraIdsWithFlash) {
-        }
-
-        @Override
-        void initializeWakeLock() {
-        }
-
-        @Override
-        void destroyWakeLock() {
-        }
-
-        @Override
-        boolean isWakeLockHeld() {
-            return false;
-        }
-
-        @Override
-        void acquireWakeLock() {
-        }
-
-        @Override
-        void releaseWakeLock() {
-        }
-
-        @Override
-        void logSessionDuration(int duration) {
-        }
-
-        @Override
-        void logSessionCount(int count) {
-        }
-
-        @Override
-        Configuration getSystemUsersConfiguration() {
-            return mConfiguration;
-        }
-
-        @Override
-        LockPatternUtils getLockPatternUtils() {
-            return mLockPatternUtils;
-        }
-
-        @Override
-        Notification createResetNotification() {
-            return null;
-        }
-
-        @Override
-        File getDataPreloadsDirectory() {
-            return mTestPreloadsDir;
-        }
-
-        @Override
-        File getDataPreloadsFileCacheDirectory() {
-            return new File(mTestPreloadsDir, "file_cache");
-        }
-
-        @Override
-        void publishLocalService(RetailDemoModeService service,
-                RetailDemoModeServiceInternal localService) {
-        }
-
-        String systemPropertiesGet(String key) {
-            return mSystemProperties.get(key);
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/testutis/TestUtils.java b/services/tests/servicestests/src/com/android/server/testutis/TestUtils.java
index d2a4484..8828988 100644
--- a/services/tests/servicestests/src/com/android/server/testutis/TestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/testutis/TestUtils.java
@@ -23,12 +23,14 @@
     private TestUtils() {
     }
 
+    public interface ExceptionRunnable {
+        void run() throws Exception;
+    }
+
     public static void assertExpectException(Class<? extends Throwable> expectedExceptionType,
-            String expectedExceptionMessageRegex, Runnable r) {
+            String expectedExceptionMessageRegex, ExceptionRunnable r) {
         try {
             r.run();
-            Assert.fail("Expected exception type " + expectedExceptionType.getName()
-                    + " was not thrown");
         } catch (Throwable e) {
             Assert.assertTrue(
                     "Expected exception type was " + expectedExceptionType.getName()
@@ -37,6 +39,9 @@
             if (expectedExceptionMessageRegex != null) {
                 MoreAsserts.assertContainsRegex(expectedExceptionMessageRegex, e.getMessage());
             }
+            return; // Pass.
         }
+        Assert.fail("Expected exception type " + expectedExceptionType.getName()
+                + " was not thrown");
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java b/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java
index 38142d3..7d73e82 100644
--- a/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java
@@ -107,7 +107,7 @@
         mFakeIntentHelper.assertNotInitialized();
 
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+        mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
     }
 
     @Test
@@ -119,7 +119,7 @@
         mPackageTracker.start();
 
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+        mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
 
         try {
             // This call should also not be allowed and will throw an exception if tracking is
@@ -129,7 +129,7 @@
         } catch (IllegalStateException expected) {}
 
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+        mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
     }
 
     @Test
@@ -141,14 +141,14 @@
         mPackageTracker.start();
 
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+        mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
 
         // Receiving a check result when tracking is disabled should cause the storage to be
         // reset.
         mPackageTracker.recordCheckResult(null /* checkToken */, true /* success */);
 
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+        mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
 
         // Assert the storage was reset.
         checkPackageStorageStatusIsInitialOrReset();
@@ -166,13 +166,13 @@
         mPackageTracker.start();
 
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+        mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
 
         // Receiving a check result when tracking is disabled should cause the storage to be reset.
         mPackageTracker.recordCheckResult(createArbitraryCheckToken(), true /* success */);
 
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+        mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
 
         // Assert the storage was reset.
         checkPackageStorageStatusIsInitialOrReset();
@@ -195,7 +195,7 @@
         mFakeIntentHelper.assertNotInitialized();
 
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+        mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
     }
 
     @Test
@@ -215,7 +215,7 @@
         mFakeIntentHelper.assertNotInitialized();
 
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+        mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
     }
 
     @Test
@@ -235,7 +235,7 @@
         mFakeIntentHelper.assertNotInitialized();
 
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+        mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
     }
 
     @Test
@@ -255,7 +255,7 @@
         mFakeIntentHelper.assertNotInitialized();
 
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+        mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
      }
 
     @Test
@@ -289,7 +289,7 @@
         mFakeIntentHelper.assertUpdateNotTriggered();
 
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+        mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
 
         // Assert the storage was not touched.
         checkPackageStorageStatusIsInitialOrReset();
@@ -325,7 +325,7 @@
         mFakeIntentHelper.assertUpdateNotTriggered();
 
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+        mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
 
         // Assert the storage was not touched.
         checkPackageStorageStatusIsInitialOrReset();
@@ -416,7 +416,7 @@
         mPackageTracker.recordCheckResult(null /* checkToken */, success);
 
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
+        mFakeIntentHelper.assertReliabilityTriggerScheduled();
 
         // Assert the storage was reset.
         checkPackageStorageStatusIsInitialOrReset();
@@ -627,7 +627,7 @@
         mPackageTracker.recordCheckResult(token1, true /* success */);
 
         // Reliability triggering should still be enabled.
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
+        mFakeIntentHelper.assertReliabilityTriggerScheduled();
 
         // Check the expected storage state.
         checkPackageStorageStatus(PackageStatus.CHECK_STARTED, packageVersions2);
@@ -743,7 +743,7 @@
 
         // Under the covers we expect it to fail to update because the storage should recognize that
         // the token is no longer valid.
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
+        mFakeIntentHelper.assertReliabilityTriggerScheduled();
 
         // Peek inside the package tracker to make sure it is tracking failure counts properly.
         assertEquals(1, mPackageTracker.getCheckFailureCountForTests());
@@ -766,7 +766,7 @@
         checkPackageStorageStatusIsInitialOrReset();
 
         // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
+        mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
 
         // Assert the PackageTracker did trigger an update.
         checkUpdateCheckTriggered(packageVersions);
@@ -803,7 +803,7 @@
         checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions);
 
         // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
+        mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
 
         // Assert the PackageTracker did not attempt to trigger an update.
         mFakeIntentHelper.assertUpdateNotTriggered();
@@ -843,7 +843,7 @@
         checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
 
         // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
+        mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
 
         // Assert the PackageTracker did trigger an update.
         checkUpdateCheckTriggered(currentPackageVersions);
@@ -890,7 +890,7 @@
 
         for (int i = 0; i < retriesAllowed + 1; i++) {
             // Simulate a reliability trigger.
-            mFakeIntentHelper.simulateReliabilityTrigger();
+            mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
 
             // Assert the PackageTracker did trigger an update.
             checkUpdateCheckTriggered(currentPackageVersions);
@@ -912,9 +912,9 @@
 
             // Check reliability triggering is in the correct state.
             if (i <= retriesAllowed) {
-                mFakeIntentHelper.assertReliabilityTriggeringEnabled();
+                mFakeIntentHelper.assertReliabilityTriggerScheduled();
             } else {
-                mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+                mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
             }
         }
     }
@@ -950,7 +950,7 @@
         // Fail (retries - 1) times.
         for (int i = 0; i < retriesAllowed - 1; i++) {
             // Simulate a reliability trigger.
-            mFakeIntentHelper.simulateReliabilityTrigger();
+            mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
 
             // Assert the PackageTracker did trigger an update.
             checkUpdateCheckTriggered(currentPackageVersions);
@@ -971,11 +971,11 @@
                     currentPackageVersions);
 
             // Check reliability triggering is still enabled.
-            mFakeIntentHelper.assertReliabilityTriggeringEnabled();
+            mFakeIntentHelper.assertReliabilityTriggerScheduled();
         }
 
         // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
+        mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
 
         // Assert the PackageTracker did trigger an update.
         checkUpdateCheckTriggered(currentPackageVersions);
@@ -1023,7 +1023,7 @@
         checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
 
         // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
+        mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
 
         // Assert the PackageTracker did trigger an update.
         checkUpdateCheckTriggered(currentPackageVersions);
@@ -1033,18 +1033,18 @@
         mFakeClock.incrementClock(checkDelayMillis - 1);
 
         // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
+        mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
 
         // Assert the PackageTracker did not trigger an update.
         mFakeIntentHelper.assertUpdateNotTriggered();
         checkPackageStorageStatus(PackageStatus.CHECK_STARTED, currentPackageVersions);
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
+        mFakeIntentHelper.assertReliabilityTriggerScheduled();
 
         // Increment the clock slightly more. Should now consider the response overdue.
         mFakeClock.incrementClock(2);
 
         // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
+        mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
 
         // Triggering should have happened.
         checkUpdateCheckTriggered(currentPackageVersions);
@@ -1096,7 +1096,7 @@
         mFakeClock.incrementClock(checkDelayMillis + 1);
 
         // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
+        mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
 
         // Assert the PackageTracker triggered an update.
         checkUpdateCheckTriggered(newPackageVersions);
@@ -1154,18 +1154,18 @@
         mFakeClock.incrementClock(checkDelayMillis - 1);
 
         // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
+        mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
 
         // Assert the PackageTracker did not trigger an update.
         mFakeIntentHelper.assertUpdateNotTriggered();
         checkPackageStorageStatus(PackageStatus.CHECK_STARTED, newPackageVersions);
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
+        mFakeIntentHelper.assertReliabilityTriggerScheduled();
 
         // Increment the clock slightly more. Should now consider the response overdue.
         mFakeClock.incrementClock(2);
 
         // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
+        mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
 
         // Triggering should have happened.
         checkUpdateCheckTriggered(newPackageVersions);
@@ -1202,7 +1202,7 @@
 
         // If an update check was triggered reliability triggering should always be enabled to
         // ensure that it can be completed if it fails.
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
+        mFakeIntentHelper.assertReliabilityTriggerScheduled();
 
         // Check the expected storage state.
         checkPackageStorageStatus(PackageStatus.CHECK_STARTED, packageVersions);
@@ -1210,7 +1210,7 @@
 
     private void checkUpdateCheckFailed(PackageVersions packageVersions) {
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
+        mFakeIntentHelper.assertReliabilityTriggerScheduled();
 
         // Assert the storage was updated.
         checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, packageVersions);
@@ -1218,7 +1218,7 @@
 
     private void checkUpdateCheckSuccessful(PackageVersions packageVersions) {
         // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
+        mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
 
         // Assert the storage was updated.
         checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions);
@@ -1345,7 +1345,7 @@
         mFakeIntentHelper.assertInitialized(UPDATE_APP_PACKAGE_NAME, DATA_APP_PACKAGE_NAME);
 
         // Assert that reliability tracking is always enabled after initialization.
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
+        mFakeIntentHelper.assertReliabilityTriggerScheduled();
     }
 
     private void checkPackageStorageStatus(
@@ -1368,34 +1368,34 @@
      */
     private static class FakeIntentHelper implements IntentHelper {
 
-        private Listener mListener;
+        private PackageTracker mPackageTracker;
         private String mUpdateAppPackageName;
         private String mDataAppPackageName;
 
         private CheckToken mLastToken;
 
-        private boolean mReliabilityTriggeringEnabled;
+        private boolean mReliabilityTriggerScheduled;
 
         @Override
         public void initialize(String updateAppPackageName, String dataAppPackageName,
-                Listener listener) {
+                PackageTracker packageTracker) {
             assertNotNull(updateAppPackageName);
             assertNotNull(dataAppPackageName);
-            assertNotNull(listener);
-            mListener = listener;
+            assertNotNull(packageTracker);
+            mPackageTracker = packageTracker;
             mUpdateAppPackageName = updateAppPackageName;
             mDataAppPackageName = dataAppPackageName;
         }
 
         public void assertInitialized(
                 String expectedUpdateAppPackageName, String expectedDataAppPackageName) {
-            assertNotNull(mListener);
+            assertNotNull(mPackageTracker);
             assertEquals(expectedUpdateAppPackageName, mUpdateAppPackageName);
             assertEquals(expectedDataAppPackageName, mDataAppPackageName);
         }
 
         public void assertNotInitialized() {
-            assertNull(mListener);
+            assertNull(mPackageTracker);
         }
 
         @Override
@@ -1407,21 +1407,21 @@
         }
 
         @Override
-        public void enableReliabilityTriggering() {
-            mReliabilityTriggeringEnabled = true;
+        public void scheduleReliabilityTrigger(long minimumDelayMillis) {
+            mReliabilityTriggerScheduled = true;
         }
 
         @Override
-        public void disableReliabilityTriggering() {
-            mReliabilityTriggeringEnabled = false;
+        public void unscheduleReliabilityTrigger() {
+            mReliabilityTriggerScheduled = false;
         }
 
-        public void assertReliabilityTriggeringEnabled() {
-            assertTrue(mReliabilityTriggeringEnabled);
+        public void assertReliabilityTriggerScheduled() {
+            assertTrue(mReliabilityTriggerScheduled);
         }
 
-        public void assertReliabilityTriggeringDisabled() {
-            assertFalse(mReliabilityTriggeringEnabled);
+        public void assertReliabilityTriggerNotScheduled() {
+            assertFalse(mReliabilityTriggerScheduled);
         }
 
         public void assertUpdateTriggered() {
@@ -1440,11 +1440,7 @@
         }
 
         public void simulatePackageUpdatedEvent() {
-            mListener.triggerUpdateIfNeeded(true);
-        }
-
-        public void simulateReliabilityTrigger() {
-            mListener.triggerUpdateIfNeeded(false);
+            mPackageTracker.triggerUpdateIfNeeded(true /* packageChanged */);
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java
index 2887e3b..d09d0c8 100644
--- a/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java
@@ -585,7 +585,39 @@
         verifyNoPackageTrackerCallsMade();
 
         // Set up the installer.
-        configureStageUninstallExpectation(true /* success */);
+        configureStageUninstallExpectation(TimeZoneDistroInstaller.UNINSTALL_SUCCESS);
+
+        // Simulate the async execution.
+        mFakeExecutor.simulateAsyncExecutionOfLastCommand();
+
+        // Verify the expected calls were made to other components.
+        verifyStageUninstallCalled();
+        verifyPackageTrackerCalled(token, true /* success */);
+
+        // Check the callback was called.
+        callback.assertResultReceived(Callback.SUCCESS);
+    }
+
+    @Test
+    public void requestUninstall_asyncNothingInstalled() throws Exception {
+        configureCallerHasPermission();
+
+        CheckToken token = createArbitraryToken();
+        byte[] tokenBytes = token.toByteArray();
+
+        TestCallback callback = new TestCallback();
+
+        // Request the uninstall.
+        assertEquals(RulesManager.SUCCESS,
+                mRulesManagerService.requestUninstall(tokenBytes, callback));
+
+        // Assert nothing has happened yet.
+        callback.assertNoResultReceived();
+        verifyNoInstallerCallsMade();
+        verifyNoPackageTrackerCallsMade();
+
+        // Set up the installer.
+        configureStageUninstallExpectation(TimeZoneDistroInstaller.UNINSTALL_NOTHING_INSTALLED);
 
         // Simulate the async execution.
         mFakeExecutor.simulateAsyncExecutionOfLastCommand();
@@ -613,7 +645,7 @@
         callback.assertNoResultReceived();
 
         // Set up the installer.
-        configureStageUninstallExpectation(true /* success */);
+        configureStageUninstallExpectation(TimeZoneDistroInstaller.UNINSTALL_SUCCESS);
 
         // Simulate the async execution.
         mFakeExecutor.simulateAsyncExecutionOfLastCommand();
@@ -644,7 +676,7 @@
         callback.assertNoResultReceived();
 
         // Set up the installer.
-        configureStageUninstallExpectation(false /* success */);
+        configureStageUninstallExpectation(TimeZoneDistroInstaller.UNINSTALL_FAIL);
 
         // Simulate the async execution.
         mFakeExecutor.simulateAsyncExecutionOfLastCommand();
@@ -849,8 +881,8 @@
                 .thenReturn(resultCode);
     }
 
-    private void configureStageUninstallExpectation(boolean success) throws Exception {
-        doReturn(success).when(mMockTimeZoneDistroInstaller).stageUninstall();
+    private void configureStageUninstallExpectation(int resultCode) throws Exception {
+        doReturn(resultCode).when(mMockTimeZoneDistroInstaller).stageUninstall();
     }
 
     private void verifyStageInstallCalled() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java b/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
index a599427..432cfc7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
@@ -17,6 +17,7 @@
 package com.android.server.wm;
 
 import android.app.ActivityManager;
+import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.view.DisplayInfo;
@@ -27,6 +28,7 @@
 import android.support.test.runner.AndroidJUnit4;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
 /**
@@ -48,6 +50,20 @@
     }
 
     /**
+     * Ensures that appBounds causes {@link android.content.pm.ActivityInfo.CONFIG_APP_BOUNDS} diff.
+     */
+    @Test
+    public void testAppBoundsConfigurationDiff() {
+        final Configuration config = new Configuration();
+        final Configuration config2 = new Configuration();
+        config.appBounds = new Rect(0, 1, 1, 0);
+        config2.appBounds = new Rect(1, 2, 2, 1);
+
+        assertEquals(ActivityInfo.CONFIG_SCREEN_SIZE, config.diff(config2));
+        assertEquals(0, config.diffPublicOnly(config2));
+    }
+
+    /**
      * Ensures the configuration app bounds at the root level match the app dimensions.
      */
     @Test
@@ -121,7 +137,6 @@
                 mParentBounds);
     }
 
-
     private void testStackBoundsConfiguration(Integer stackId, Rect parentBounds, Rect bounds,
             Rect expectedConfigBounds) {
         final StackWindowController stackController = stackId != null ?
@@ -140,4 +155,29 @@
         assertTrue((expectedConfigBounds == null && config.appBounds == null)
                 || expectedConfigBounds.equals(config.appBounds));
     }
+
+    /**
+     * Ensures appBounds are considered in {@link Configuration#compareTo(Configuration)}.
+     */
+    @Test
+    public void testConfigurationCompareTo() throws Exception {
+        final Configuration blankConfig = new Configuration();
+
+        final Configuration config1 = new Configuration();
+        config1.appBounds = new Rect(1, 2, 3, 4);
+
+        final Configuration config2 = new Configuration(config1);
+
+        assertEquals(config1.compareTo(config2), 0);
+
+        config2.appBounds.left = 0;
+
+        // Different bounds
+        assertNotEquals(config1.compareTo(config2), 0);
+
+        // No bounds
+        assertEquals(config1.compareTo(blankConfig), -1);
+        assertEquals(blankConfig.compareTo(config1), 1);
+
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 36083bf..77a0436 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -175,7 +175,7 @@
         token.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
 
         token.setFillsParent(false);
-        // Can specify orientation if app doesn't fill parent. Allowed for SDK <= 25.
+        // Can specify orientation if app doesn't fill parent.
         assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation());
 
         token.setFillsParent(true);
@@ -185,6 +185,11 @@
         assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation());
         // Can specify orientation if the current orientation candidate is orientation behind.
         assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation(SCREEN_ORIENTATION_BEHIND));
+
+        token.sendingToBottom = false;
+        token.setIsOnTop(true);
+        // Allow for token to provide orientation hidden if on top and not being sent to bottom.
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation());
     }
 
     @Test
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 856e940..91eb55b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -31,10 +31,13 @@
 import org.junit.runner.RunWith;
 
 import android.content.res.Configuration;
+import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.DisplayMetrics;
 import android.util.SparseIntArray;
+import android.view.MotionEvent;
 
 import java.util.Arrays;
 import java.util.LinkedList;
@@ -237,6 +240,52 @@
         assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
     }
 
+    /**
+     * Tests tapping on a stack in different display results in window gaining focus.
+     */
+    @Test
+    public void testInputEventBringsCorrectDisplayInFocus() throws Exception {
+        DisplayContent dc0 = sWm.getDefaultDisplayContentLocked();
+        // Create a second display
+        final DisplayContent dc1 = createNewDisplay();
+
+        // Add stack with activity.
+        final TaskStack stack0 = createTaskStackOnDisplay(dc0);
+        final Task task0 = createTaskInStack(stack0, 0 /* userId */);
+        final WindowTestUtils.TestAppWindowToken token =
+                new WindowTestUtils.TestAppWindowToken(dc0);
+        task0.addChild(token, 0);
+        dc0.mTapDetector = new TaskTapPointerEventListener(sWm, dc0);
+        sWm.registerPointerEventListener(dc0.mTapDetector);
+        final TaskStack stack1 = createTaskStackOnDisplay(dc1);
+        final Task task1 = createTaskInStack(stack1, 0 /* userId */);
+        final WindowTestUtils.TestAppWindowToken token1 =
+                new WindowTestUtils.TestAppWindowToken(dc0);
+        task1.addChild(token1, 0);
+        dc1.mTapDetector = new TaskTapPointerEventListener(sWm, dc0);
+        sWm.registerPointerEventListener(dc1.mTapDetector);
+
+        // tap on primary display (by sending ACTION_DOWN followed by ACTION_UP)
+        DisplayMetrics dm0 = dc0.getDisplayMetrics();
+        dc0.mTapDetector.onPointerEvent(
+                createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, true));
+        dc0.mTapDetector.onPointerEvent(
+                createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, false));
+
+        // Check focus is on primary display.
+        assertEquals(sWm.mCurrentFocus, dc0.findFocusedWindow());
+
+        // Tap on secondary display
+        DisplayMetrics dm1 = dc1.getDisplayMetrics();
+        dc1.mTapDetector.onPointerEvent(
+                createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, true));
+        dc1.mTapDetector.onPointerEvent(
+                createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, false));
+
+        // Check focus is on secondary.
+        assertEquals(sWm.mCurrentFocus, dc1.findFocusedWindow());
+    }
+
     @Test
     @Ignore
     public void testFocusedWindowMultipleDisplays() throws Exception {
@@ -355,4 +404,18 @@
         }
         assertTrue(actualWindows.isEmpty());
     }
+
+    private MotionEvent createTapEvent(float x, float y, boolean isDownEvent) {
+        final long downTime = SystemClock.uptimeMillis();
+        final long eventTime = SystemClock.uptimeMillis() + 100;
+        final int metaState = 0;
+
+        return MotionEvent.obtain(
+                downTime,
+                eventTime,
+                isDownEvent ? MotionEvent.ACTION_DOWN : MotionEvent.ACTION_UP,
+                x,
+                y,
+                metaState);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
index 39c0de8..2f3c03c 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
@@ -31,7 +31,6 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.util.ArraySet;
 
-import com.android.internal.util.Predicate;
 import com.android.server.wm.TaskSnapshotPersister.RemoveObsoleteFilesQueueItem;
 
 import org.junit.Test;
@@ -176,4 +175,16 @@
                 new File(sFilesDir.getPath() + "/snapshots/2_reduced.jpg")};
         assertTrueForFiles(existsFiles, File::exists, " must exist");
     }
+
+    /**
+     * Private predicate definition.
+     *
+     * This is needed because com.android.internal.util.Predicate is deprecated
+     * and can only be used with classes fron android.test.runner. This cannot
+     * use java.util.function.Predicate because that is not present on all API
+     * versions that this test must run on.
+     */
+    private interface Predicate<T> {
+        boolean apply(T t);
+    }
 }
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 c457cb3..95adc9c 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -17,6 +17,11 @@
 package com.android.server.wm;
 
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManagerPolicy.NAV_BAR_BOTTOM;
+
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -38,6 +43,7 @@
 import android.os.RemoteException;
 import android.view.Display;
 import android.view.IWindowManager;
+import android.view.InputChannel;
 import android.view.KeyEvent;
 import android.view.WindowManager;
 import android.view.WindowManagerPolicy;
@@ -90,7 +96,14 @@
                 }).when(am).notifyKeyguardFlagsChanged(any());
             }
 
-            sWm = WindowManagerService.main(context, mock(InputManagerService.class), true, false,
+            InputManagerService ims = mock(InputManagerService.class);
+            // InputChannel is final and can't be mocked.
+            InputChannel[] input = InputChannel.openInputChannelPair(TAG_WM);
+            if (input != null && input.length > 1) {
+                doReturn(input[1]).when(ims).monitorInput(anyString());
+            }
+
+            sWm = WindowManagerService.main(context, ims, true, false,
                     false, new TestWindowManagerPolicy());
         }
         return sWm;
@@ -381,6 +394,11 @@
     }
 
     @Override
+    public boolean okToAnimate() {
+        return true;
+    }
+
+    @Override
     public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
 
     }
@@ -609,6 +627,11 @@
     }
 
     @Override
+    public int getNavBarPosition() {
+        return NAV_BAR_BOTTOM;
+    }
+
+    @Override
     public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight,
             Rect outInsets) {
 
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 8fe4116..6e253e7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -363,6 +363,50 @@
                 Math.min(pf.height(), displayInfo.logicalHeight));
     }
 
+    @Test
+    public void testLayoutLetterboxedWindow() {
+        // First verify task behavior in multi-window mode.
+        final DisplayInfo displayInfo = sWm.getDefaultDisplayContentLocked().getDisplayInfo();
+        final int logicalWidth = displayInfo.logicalWidth;
+        final int logicalHeight = displayInfo.logicalHeight;
+
+        final int taskLeft = logicalWidth / 5;
+        final int taskTop = logicalHeight / 5;
+        final int taskRight = logicalWidth / 4 * 3;
+        final int taskBottom = logicalHeight / 4 * 3;
+        final Rect taskBounds = new Rect(taskLeft, taskTop, taskRight, taskBottom);
+        TaskWithBounds task = new TaskWithBounds(taskBounds);
+        task.mInsetBounds.set(taskLeft, taskTop, taskRight, taskBottom);
+        task.mFullscreenForTest = false;
+        WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
+
+        final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
+        w.computeFrameLw(pf /* parentFrame */, pf /* displayFrame */, pf /* overscanFrame */,
+                pf /* contentFrame */, pf /* visibleFrame */, pf /* decorFrame */,
+                pf /* stableFrame */, null /* outsetFrame */);
+        // For non fullscreen tasks the containing frame is based off the
+        // task bounds not the parent frame.
+        assertRect(w.mFrame, taskLeft, taskTop, taskRight, taskBottom);
+        assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
+        assertRect(w.mContentInsets, 0, 0, 0, 0);
+
+        // Now simulate switch to fullscreen for letterboxed app.
+        final int xInset = logicalWidth / 10;
+        final int yInset = logicalWidth / 10;
+        final Rect cf = new Rect(xInset, yInset, logicalWidth - xInset, logicalHeight - yInset);
+        w.mAppToken.onOverrideConfigurationChanged(w.mAppToken.getOverrideConfiguration(), cf);
+        pf.set(0, 0, logicalWidth, logicalHeight);
+        task.mFullscreenForTest = true;
+
+        w.computeFrameLw(pf /* parentFrame */, pf /* displayFrame */, pf /* overscanFrame */,
+                cf /* contentFrame */, cf /* visibleFrame */, pf /* decorFrame */,
+                cf /* stableFrame */, null /* outsetFrame */);
+        assertEquals(cf, w.mFrame);
+        assertEquals(cf, w.getContentFrameLw());
+        assertRect(w.mContentInsets, 0, 0, 0, 0);
+    }
+
     private WindowStateWithTask createWindow(Task task, int width, int height) {
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
         attrs.width = width;
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 c809c32..67db5f4 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -218,8 +218,7 @@
         root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
         root.mTurnOnScreen = false;
 
-        root.prepareWindowToDisplayDuringRelayout(new MergedConfiguration(),
-                wasVisible /*wasVisible*/);
+        root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/);
         assertTrue(root.mTurnOnScreen);
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
index b83532c..7ff1110 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -89,6 +89,7 @@
 
     /** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */
     public static class TestAppWindowToken extends AppWindowToken {
+        boolean mOnTop = false;
 
         TestAppWindowToken(DisplayContent dc) {
             super(dc.mService, new IApplicationToken.Stub() {}, false, dc, true /* fillsParent */,
@@ -125,6 +126,15 @@
         int positionInParent() {
             return getParent().mChildren.indexOf(this);
         }
+
+        void setIsOnTop(boolean onTop) {
+            mOnTop = onTop;
+        }
+
+        @Override
+        boolean isOnTop() {
+            return mOnTop;
+        }
     }
 
     /* Used so we can gain access to some protected members of the {@link WindowToken} class */
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index 922f08d..926a606 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -339,6 +339,10 @@
         return ret;
     }
 
+    public static <T> T[] array(T... array) {
+        return array;
+    }
+
     public static <T> List<T> list(T... array) {
         return Arrays.asList(array);
     }
diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java
index 562443f..21b11b0 100644
--- a/services/usage/java/com/android/server/usage/StorageStatsService.java
+++ b/services/usage/java/com/android/server/usage/StorageStatsService.java
@@ -197,7 +197,7 @@
             // logic should be kept in sync with getAllocatableBytes().
             if (isQuotaSupported(volumeUuid, callingPackage)) {
                 final long cacheTotal = getCacheBytes(volumeUuid, callingPackage);
-                final long cacheReserved = mStorage.getStorageCacheBytes(path);
+                final long cacheReserved = mStorage.getStorageCacheBytes(path, 0);
                 final long cacheClearable = Math.max(0, cacheTotal - cacheReserved);
 
                 return path.getUsableSpace() + cacheClearable;
@@ -392,6 +392,7 @@
         res.videoBytes = stats[2];
         res.imageBytes = stats[3];
         res.appBytes = stats[4];
+        res.obbBytes = stats[5];
         return res;
     }
 
diff --git a/services/usb/Android.mk b/services/usb/Android.mk
index 57bf57d..55bfccf 100644
--- a/services/usb/Android.mk
+++ b/services/usb/Android.mk
@@ -10,6 +10,7 @@
 LOCAL_JAVA_LIBRARIES := services.core \
 android.hidl.manager-V1.0-java
 
-LOCAL_STATIC_JAVA_LIBRARIES := android.hardware.usb-V1.0-java
+LOCAL_STATIC_JAVA_LIBRARIES := android.hardware.usb-V1.0-java \
+android.hardware.usb-V1.1-java
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
index 03d8241..68c1d5f 100644
--- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
@@ -65,6 +65,9 @@
     private final HashMap<UsbDevice,UsbAudioDevice>
         mAudioDevices = new HashMap<UsbDevice,UsbAudioDevice>();
 
+    private boolean mIsInputHeadset; // as reported by UsbDescriptorParser
+    private boolean mIsOutputHeadset; // as reported by UsbDescriptorParser
+
     private final HashMap<UsbDevice,UsbMidiDevice>
         mMidiDevices = new HashMap<UsbDevice,UsbMidiDevice>();
 
@@ -184,24 +187,34 @@
         try {
             // Playback Device
             if (audioDevice.mHasPlayback) {
-                int device = (audioDevice == mAccessoryAudioDevice ?
-                        AudioSystem.DEVICE_OUT_USB_ACCESSORY :
-                        AudioSystem.DEVICE_OUT_USB_DEVICE);
+                int device;
+                if (mIsOutputHeadset) {
+                    device = AudioSystem.DEVICE_OUT_USB_HEADSET;
+                } else {
+                    device = (audioDevice == mAccessoryAudioDevice
+                        ? AudioSystem.DEVICE_OUT_USB_ACCESSORY
+                        : AudioSystem.DEVICE_OUT_USB_DEVICE);
+                }
                 if (DEBUG) {
                     Slog.i(TAG, "pre-call device:0x" + Integer.toHexString(device) +
-                            " addr:" + address + " name:" + audioDevice.mDeviceName);
+                            " addr:" + address + " name:" + audioDevice.getDeviceName());
                 }
                 mAudioService.setWiredDeviceConnectionState(
-                        device, state, address, audioDevice.mDeviceName, TAG);
+                        device, state, address, audioDevice.getDeviceName(), TAG);
             }
 
             // Capture Device
             if (audioDevice.mHasCapture) {
-               int device = (audioDevice == mAccessoryAudioDevice ?
-                        AudioSystem.DEVICE_IN_USB_ACCESSORY :
-                        AudioSystem.DEVICE_IN_USB_DEVICE);
+                int device;
+                if (mIsInputHeadset) {
+                    device = AudioSystem.DEVICE_IN_USB_HEADSET;
+                } else {
+                    device = (audioDevice == mAccessoryAudioDevice
+                        ? AudioSystem.DEVICE_IN_USB_ACCESSORY
+                        : AudioSystem.DEVICE_IN_USB_DEVICE);
+                }
                 mAudioService.setWiredDeviceConnectionState(
-                        device, state, address, audioDevice.mDeviceName, TAG);
+                        device, state, address, audioDevice.getDeviceName(), TAG);
             }
         } catch (RemoteException e) {
             Slog.e(TAG, "RemoteException in setWiredDeviceConnectionState");
@@ -329,10 +342,9 @@
         UsbAudioDevice audioDevice =
                 new UsbAudioDevice(card, device, hasPlayback, hasCapture, deviceClass);
         AlsaCardsParser.AlsaCardRecord cardRecord = mCardsParser.getCardRecordFor(card);
-        audioDevice.mDeviceName = cardRecord.mCardName;
-        audioDevice.mDeviceDescription = cardRecord.mCardDescription;
+        audioDevice.setDeviceNameAndDescription(cardRecord.mCardName, cardRecord.mCardDescription);
 
-        notifyDeviceState(audioDevice, true);
+        notifyDeviceState(audioDevice, true /*enabled*/);
 
         return audioDevice;
     }
@@ -344,12 +356,16 @@
         return selectAudioCard(mCardsParser.getDefaultCard());
     }
 
-    /* package */ void usbDeviceAdded(UsbDevice usbDevice) {
-       if (DEBUG) {
-          Slog.d(TAG, "deviceAdded(): " + usbDevice.getManufacturerName() +
-                  " nm:" + usbDevice.getProductName());
+    /* package */ void usbDeviceAdded(UsbDevice usbDevice,
+            boolean isInputHeadset, boolean isOutputHeadset) {
+        if (DEBUG) {
+            Slog.d(TAG, "deviceAdded(): " + usbDevice.getManufacturerName()
+                    + " nm:" + usbDevice.getProductName());
         }
 
+        mIsInputHeadset = isInputHeadset;
+        mIsOutputHeadset = isOutputHeadset;
+
         // Is there an audio interface in there?
         boolean isAudioDevice = false;
 
@@ -442,7 +458,7 @@
         Slog.i(TAG, "USB Audio Device Removed: " + audioDevice);
         if (audioDevice != null) {
             if (audioDevice.mHasPlayback || audioDevice.mHasCapture) {
-                notifyDeviceState(audioDevice, false);
+                notifyDeviceState(audioDevice, false /*enabled*/);
 
                 // if there any external devices left, select one of them
                 selectDefaultDevice();
@@ -461,9 +477,9 @@
         if (enabled) {
             mAccessoryAudioDevice = new UsbAudioDevice(card, device, true, false,
                     UsbAudioDevice.kAudioDeviceClass_External);
-            notifyDeviceState(mAccessoryAudioDevice, true);
+            notifyDeviceState(mAccessoryAudioDevice, true /*enabled*/);
         } else if (mAccessoryAudioDevice != null) {
-            notifyDeviceState(mAccessoryAudioDevice, false);
+            notifyDeviceState(mAccessoryAudioDevice, false /*enabled*/);
             mAccessoryAudioDevice = null;
         }
     }
@@ -508,6 +524,7 @@
     //
     // Logging
     //
+    // called by UsbService.dump
     public void dump(IndentingPrintWriter pw) {
         pw.println("USB Audio Devices:");
         for (UsbDevice device : mAudioDevices.keySet()) {
diff --git a/services/usb/java/com/android/server/usb/UsbAudioDevice.java b/services/usb/java/com/android/server/usb/UsbAudioDevice.java
index 70d1fc6..4b17dfe 100644
--- a/services/usb/java/com/android/server/usb/UsbAudioDevice.java
+++ b/services/usb/java/com/android/server/usb/UsbAudioDevice.java
@@ -36,8 +36,8 @@
     // This member is a combination of the above bit-flags
     public final int mDeviceClass;
 
-    public String mDeviceName = "";
-    public String mDeviceDescription = "";
+    private String mDeviceName = "";
+    private String mDeviceDescription = "";
 
     public UsbAudioDevice(int card, int device,
             boolean hasPlayback, boolean hasCapture, int deviceClass) {
@@ -59,8 +59,19 @@
         return sb.toString();
     }
 
-    public String toShortString() {
+    // called by logDevices
+    String toShortString() {
         return "[card:" + mCard + " device:" + mDevice + " " + mDeviceName + "]";
     }
+
+    String getDeviceName() {
+        return mDeviceName;
+    }
+
+    void setDeviceNameAndDescription(String deviceName, String deviceDescription) {
+        mDeviceName = deviceName;
+        mDeviceDescription = deviceDescription;
+    }
+
 }
 
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index ca74688..946d237 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -30,6 +30,10 @@
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbConfiguration;
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbInterface;
 import android.hardware.usb.UsbManager;
 import android.hardware.usb.UsbPort;
 import android.hardware.usb.UsbPortStatus;
@@ -61,6 +65,8 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Scanner;
@@ -125,9 +131,11 @@
     private static final int MSG_BOOT_COMPLETED = 4;
     private static final int MSG_USER_SWITCHED = 5;
     private static final int MSG_UPDATE_USER_RESTRICTIONS = 6;
-    private static final int MSG_UPDATE_HOST_STATE = 7;
+    private static final int MSG_UPDATE_PORT_STATE = 7;
     private static final int MSG_ACCESSORY_MODE_ENTER_TIMEOUT = 8;
     private static final int MSG_UPDATE_CHARGING_STATE = 9;
+    private static final int MSG_UPDATE_HOST_STATE = 10;
+    private static final int MSG_LOCALE_CHANGED = 11;
 
     private static final int AUDIO_MODE_SOURCE = 1;
 
@@ -168,6 +176,22 @@
     private final UsbSettingsManager mSettingsManager;
     private Intent mBroadcastedIntent;
     private boolean mPendingBootBroadcast;
+    private static Set<Integer> sBlackListedInterfaces;
+
+    static {
+        sBlackListedInterfaces = new HashSet<Integer>();
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_AUDIO);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_COMM);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_HID);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_PRINTER);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_MASS_STORAGE);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_HUB);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_CDC_DATA);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_CSCID);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_CONTENT_SEC);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_VIDEO);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_WIRELESS_CONTROLLER);
+    };
 
     private class AdbSettingsObserver extends ContentObserver {
         public AdbSettingsObserver() {
@@ -201,7 +225,7 @@
         }
     };
 
-    private final BroadcastReceiver mHostReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mPortReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             UsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT);
@@ -219,6 +243,26 @@
         }
     };
 
+    private final BroadcastReceiver mHostReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Iterator devices = ((UsbManager) context.getSystemService(Context.USB_SERVICE))
+                    .getDeviceList().entrySet().iterator();
+            if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
+                mHandler.sendMessage(MSG_UPDATE_HOST_STATE, devices, true);
+            } else {
+                mHandler.sendMessage(MSG_UPDATE_HOST_STATE, devices, false);
+            }
+        }
+    };
+
+    private final BroadcastReceiver mLanguageChangedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mHandler.sendEmptyMessage(MSG_LOCALE_CHANGED);
+        }
+    };
+
     public UsbDeviceManager(Context context, UsbAlsaManager alsaManager,
             UsbSettingsManager settingsManager) {
         mContext = context;
@@ -243,10 +287,18 @@
         if (secureAdbEnabled && !dataEncrypted) {
             mDebuggingManager = new UsbDebuggingManager(context);
         }
-        mContext.registerReceiver(mHostReceiver,
+        mContext.registerReceiver(mPortReceiver,
                 new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED));
         mContext.registerReceiver(mChargingReceiver,
                 new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+
+        IntentFilter filter =
+                new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED);
+        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
+        mContext.registerReceiver(mHostReceiver, filter);
+
+        mContext.registerReceiver(mLanguageChangedReceiver,
+                new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
     }
 
     private UsbProfileGroupSettingsManager getCurrentSettings() {
@@ -371,6 +423,8 @@
         private boolean mSinkPower;
         private boolean mConfigured;
         private boolean mUsbDataUnlocked;
+        private boolean mAudioAccessoryConnected;
+        private boolean mAudioAccessorySupported;
         private String mCurrentFunctions;
         private boolean mCurrentFunctionsApplied;
         private UsbAccessory mCurrentAccessory;
@@ -379,6 +433,8 @@
         private int mCurrentUser = UserHandle.USER_NULL;
         private boolean mUsbCharging;
         private String mCurrentOemFunctions;
+        private boolean mHideUsbNotification;
+        private boolean mSupportsAllCombinations;
 
         public UsbHandler(Looper looper) {
             super(looper);
@@ -481,21 +537,16 @@
         }
 
         public void updateHostState(UsbPort port, UsbPortStatus status) {
-            boolean hostConnected = status.getCurrentDataRole() == UsbPort.DATA_ROLE_HOST;
-            boolean sourcePower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE;
-            boolean sinkPower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SINK;
-
             if (DEBUG) {
                 Slog.i(TAG, "updateHostState " + port + " status=" + status);
             }
 
             SomeArgs args = SomeArgs.obtain();
-            args.argi1 = hostConnected ? 1 : 0;
-            args.argi2 = sourcePower ? 1 : 0;
-            args.argi3 = sinkPower ? 1 : 0;
+            args.arg1 = port;
+            args.arg2 = status;
 
-            removeMessages(MSG_UPDATE_HOST_STATE);
-            Message msg = obtainMessage(MSG_UPDATE_HOST_STATE, args);
+            removeMessages(MSG_UPDATE_PORT_STATE);
+            Message msg = obtainMessage(MSG_UPDATE_PORT_STATE, args);
             // debounce rapid transitions of connect/disconnect on type-c ports
             sendMessageDelayed(msg, UPDATE_DELAY);
         }
@@ -540,7 +591,7 @@
                 }
 
                 setEnabledFunctions(oldFunctions, true, mUsbDataUnlocked);
-                updateAdbNotification();
+                updateAdbNotification(false);
             }
 
             if (mDebuggingManager != null) {
@@ -560,7 +611,7 @@
 
             if (usbDataUnlocked != mUsbDataUnlocked) {
                 mUsbDataUnlocked = usbDataUnlocked;
-                updateUsbNotification();
+                updateUsbNotification(false);
                 forceRestart = true;
             }
 
@@ -642,8 +693,9 @@
                 // Set the new USB configuration.
                 setUsbConfig(oemFunctions);
 
-                if (UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_MTP)
-                        || UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_PTP)) {
+                if (mBootCompleted
+                        && (UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_MTP)
+                        || UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_PTP))) {
                     // Start up dependent services.
                     updateUsbStateBroadcastIfNeeded(true);
                 }
@@ -765,7 +817,7 @@
             }
 
             // send broadcast intent only if the USB state has changed
-            if (!isUsbStateChanged(intent)) {
+            if (!isUsbStateChanged(intent) && !configChanged) {
                 if (DEBUG) {
                     Slog.d(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras());
                 }
@@ -840,8 +892,8 @@
                     mConnected = (msg.arg1 == 1);
                     mConfigured = (msg.arg2 == 1);
 
-                    updateUsbNotification();
-                    updateAdbNotification();
+                    updateUsbNotification(false);
+                    updateAdbNotification(false);
                     if (mBootCompleted) {
                         updateUsbStateBroadcastIfNeeded(false);
                     }
@@ -850,7 +902,7 @@
                         updateCurrentAccessory();
                     }
                     if (mBootCompleted) {
-                        if (!mConnected) {
+                        if (!mConnected && !hasMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT)) {
                             // restore defaults when USB is disconnected
                             setEnabledFunctions(null, !mAdbEnabled, false);
                         }
@@ -859,14 +911,31 @@
                         mPendingBootBroadcast = true;
                     }
                     break;
-                case MSG_UPDATE_HOST_STATE:
+                case MSG_UPDATE_PORT_STATE:
                     SomeArgs args = (SomeArgs) msg.obj;
                     boolean prevHostConnected = mHostConnected;
-                    mHostConnected = (args.argi1 == 1);
-                    mSourcePower = (args.argi2 == 1);
-                    mSinkPower = (args.argi3 == 1);
+                    UsbPort port = (UsbPort) args.arg1;
+                    UsbPortStatus status = (UsbPortStatus) args.arg2;
+                    mHostConnected = status.getCurrentDataRole() == UsbPort.DATA_ROLE_HOST;
+                    mSourcePower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE;
+                    mSinkPower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SINK;
+                    mAudioAccessoryConnected =
+                            (status.getCurrentMode() == UsbPort.MODE_AUDIO_ACCESSORY);
+                    mAudioAccessorySupported = port.isModeSupported(UsbPort.MODE_AUDIO_ACCESSORY);
+                    // Ideally we want to see if PR_SWAP and DR_SWAP is supported.
+                    // But, this should be suffice, since, all four combinations are only supported
+                    // when PR_SWAP and DR_SWAP are supported.
+                    mSupportsAllCombinations = status.isRoleCombinationSupported(
+                            UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST)
+                            && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK,
+                            UsbPort.DATA_ROLE_HOST)
+                            && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE,
+                            UsbPort.DATA_ROLE_DEVICE)
+                            && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK,
+                            UsbPort.DATA_ROLE_HOST);
+
                     args.recycle();
-                    updateUsbNotification();
+                    updateUsbNotification(false);
                     if (mBootCompleted) {
                         if (mHostConnected || prevHostConnected) {
                             updateUsbStateBroadcastIfNeeded(false);
@@ -877,7 +946,39 @@
                     break;
                 case MSG_UPDATE_CHARGING_STATE:
                     mUsbCharging = (msg.arg1 == 1);
-                    updateUsbNotification();
+                    updateUsbNotification(false);
+                    break;
+                case MSG_UPDATE_HOST_STATE:
+                    Iterator devices = (Iterator) msg.obj;
+                    boolean connected = (msg.arg1 == 1);
+
+                    if (DEBUG) {
+                        Slog.i(TAG, "HOST_STATE connected:" + connected);
+                    }
+
+                    mHideUsbNotification = false;
+                    while (devices.hasNext()) {
+                        Map.Entry pair = (Map.Entry) devices.next();
+                        if (DEBUG) {
+                            Slog.i(TAG, pair.getKey() + " = " + pair.getValue());
+                        }
+                        UsbDevice device = (UsbDevice) pair.getValue();
+                        int configurationCount = device.getConfigurationCount() - 1;
+                        while (configurationCount >= 0) {
+                            UsbConfiguration config = device.getConfiguration(configurationCount);
+                            configurationCount--;
+                            int interfaceCount = config.getInterfaceCount() - 1;
+                            while (interfaceCount >= 0) {
+                                UsbInterface intrface = config.getInterface(interfaceCount);
+                                interfaceCount--;
+                                if (sBlackListedInterfaces.contains(intrface.getInterfaceClass())) {
+                                    mHideUsbNotification = true;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    updateUsbNotification(false);
                     break;
                 case MSG_ENABLE_ADB:
                     setAdbEnabled(msg.arg1 == 1);
@@ -895,10 +996,14 @@
                             mCurrentFunctions, forceRestart, mUsbDataUnlocked && !forceRestart);
                     break;
                 case MSG_SYSTEM_READY:
-                    updateUsbNotification();
-                    updateAdbNotification();
+                    updateUsbNotification(false);
+                    updateAdbNotification(false);
                     updateUsbFunctions();
                     break;
+                case MSG_LOCALE_CHANGED:
+                    updateAdbNotification(true);
+                    updateUsbNotification(true);
+                    break;
                 case MSG_BOOT_COMPLETED:
                     mBootCompleted = true;
                     if (mPendingBootBroadcast) {
@@ -949,15 +1054,31 @@
             return mCurrentAccessory;
         }
 
-        private void updateUsbNotification() {
+        private void updateUsbNotification(boolean force) {
             if (mNotificationManager == null || !mUseUsbNotification
                     || ("0".equals(SystemProperties.get("persist.charging.notify")))) {
                 return;
             }
+
+            // Dont show the notification when connected to a USB peripheral
+            // and the link does not support PR_SWAP and DR_SWAP
+            if (mHideUsbNotification && !mSupportsAllCombinations) {
+                if (mUsbNotificationId != 0) {
+                    mNotificationManager.cancelAsUser(null, mUsbNotificationId,
+                            UserHandle.ALL);
+                    mUsbNotificationId = 0;
+                    Slog.d(TAG, "Clear notification");
+                }
+                return;
+            }
+
             int id = 0;
             int titleRes = 0;
             Resources r = mContext.getResources();
-            if (mConnected) {
+            if (mAudioAccessoryConnected && !mAudioAccessorySupported) {
+                titleRes = com.android.internal.R.string.usb_unsupported_audio_accessory_title;
+                id = SystemMessage.NOTE_USB_AUDIO_ACCESSORY_NOT_SUPPORTED;
+            } else if (mConnected) {
                 if (!mUsbDataUnlocked) {
                     if (mSourcePower) {
                         titleRes = com.android.internal.R.string.usb_supplying_notification_title;
@@ -996,26 +1117,51 @@
                 titleRes = com.android.internal.R.string.usb_charging_notification_title;
                 id = SystemMessage.NOTE_USB_CHARGING;
             }
-            if (id != mUsbNotificationId) {
+            if (id != mUsbNotificationId || force) {
                 // clear notification if title needs changing
                 if (mUsbNotificationId != 0) {
                     mNotificationManager.cancelAsUser(null, mUsbNotificationId,
                             UserHandle.ALL);
+                    Slog.d(TAG, "Clear notification");
                     mUsbNotificationId = 0;
                 }
                 if (id != 0) {
-                    CharSequence message = r.getText(
-                            com.android.internal.R.string.usb_notification_message);
+                    CharSequence message;
                     CharSequence title = r.getText(titleRes);
+                    PendingIntent pi;
+                    String channel;
 
-                    Intent intent = Intent.makeRestartActivityTask(
-                            new ComponentName("com.android.settings",
-                                    "com.android.settings.deviceinfo.UsbModeChooserActivity"));
-                    PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
-                            intent, 0, null, UserHandle.CURRENT);
+                    if (titleRes
+                            != com.android.internal.R.string
+                            .usb_unsupported_audio_accessory_title) {
+                        Intent intent = Intent.makeRestartActivityTask(
+                                new ComponentName("com.android.settings",
+                                        "com.android.settings.deviceinfo.UsbModeChooserActivity"));
+                        pi = PendingIntent.getActivityAsUser(mContext, 0,
+                                intent, 0, null, UserHandle.CURRENT);
+                        channel = SystemNotificationChannels.USB;
+                        message = r.getText(
+                                com.android.internal.R.string.usb_notification_message);
+                    } else {
+                        final Intent intent = new Intent();
+                        intent.setClassName("com.android.settings",
+                                "com.android.settings.HelpTrampoline");
+                        intent.putExtra(Intent.EXTRA_TEXT,
+                                "help_url_audio_accessory_not_supported");
 
-                    Notification notification =
-                            new Notification.Builder(mContext, SystemNotificationChannels.USB)
+                        if (mContext.getPackageManager().resolveActivity(intent, 0) != null) {
+                            pi = PendingIntent.getActivity(mContext, 0, intent, 0);
+                        } else {
+                            pi = null;
+                        }
+
+                        channel = SystemNotificationChannels.ALERTS;
+                        message = r.getText(
+                                com.android.internal.R.string
+                                        .usb_unsupported_audio_accessory_message);
+                    }
+
+                    Notification.Builder builder = new Notification.Builder(mContext, channel)
                                     .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
                                     .setWhen(0)
                                     .setOngoing(true)
@@ -1027,22 +1173,37 @@
                                     .setContentTitle(title)
                                     .setContentText(message)
                                     .setContentIntent(pi)
-                                    .setVisibility(Notification.VISIBILITY_PUBLIC)
-                                    .build();
+                                    .setVisibility(Notification.VISIBILITY_PUBLIC);
+
+                    if (titleRes
+                            == com.android.internal.R.string
+                            .usb_unsupported_audio_accessory_title) {
+                        builder.setStyle(new Notification.BigTextStyle()
+                                .bigText(message));
+                    }
+                    Notification notification = builder.build();
+
                     mNotificationManager.notifyAsUser(null, id, notification,
                             UserHandle.ALL);
+                    Slog.d(TAG, "push notification:" + title);
                     mUsbNotificationId = id;
                 }
             }
         }
 
-        private void updateAdbNotification() {
+        private void updateAdbNotification(boolean force) {
             if (mNotificationManager == null) return;
             final int id = SystemMessage.NOTE_ADB_ACTIVE;
             final int titleRes = com.android.internal.R.string.adb_active_notification_title;
+
             if (mAdbEnabled && mConnected) {
                 if ("0".equals(SystemProperties.get("persist.adb.notify"))) return;
 
+                if (force && mAdbNotificationShown) {
+                    mAdbNotificationShown = false;
+                    mNotificationManager.cancelAsUser(null, id, UserHandle.ALL);
+                }
+
                 if (!mAdbNotificationShown) {
                     Resources r = mContext.getResources();
                     CharSequence title = r.getText(titleRes);
@@ -1085,10 +1246,13 @@
         private String getDefaultFunctions() {
             String func = SystemProperties.get(getPersistProp(true),
                     UsbManager.USB_FUNCTION_NONE);
-            if (UsbManager.USB_FUNCTION_NONE.equals(func)) {
-                func = UsbManager.USB_FUNCTION_MTP;
+            // if ADB is enabled, reset functions to ADB
+            // else enable MTP as usual.
+            if (UsbManager.containsFunction(func, UsbManager.USB_FUNCTION_ADB)) {
+                return UsbManager.USB_FUNCTION_ADB;
+            } else {
+                return UsbManager.USB_FUNCTION_MTP;
             }
-            return func;
         }
 
         public void dump(IndentingPrintWriter pw) {
@@ -1104,6 +1268,9 @@
             pw.println("  mSourcePower: " + mSourcePower);
             pw.println("  mSinkPower: " + mSinkPower);
             pw.println("  mUsbCharging: " + mUsbCharging);
+            pw.println("  mHideUsbNotification: " + mHideUsbNotification);
+            pw.println("  mAudioAccessoryConnected: " + mAudioAccessoryConnected);
+
             try {
                 pw.println("  Kernel state: "
                         + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim());
@@ -1211,8 +1378,7 @@
                         newFunction = UsbManager.addFunction(overrideFunctions.second,
                                 UsbManager.USB_FUNCTION_ADB);
                     } else {
-                        newFunction = UsbManager.addFunction(UsbManager.USB_FUNCTION_NONE,
-                                UsbManager.USB_FUNCTION_ADB);
+                        newFunction = overrideFunctions.second;
                     }
                     Slog.d(TAG, "OEM USB override persisting: " + newFunction + "in prop: "
                             + UsbDeviceManager.getPersistProp(false));
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index af78c05..3279fa6 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -16,7 +16,6 @@
 
 package com.android.server.usb;
 
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
@@ -32,6 +31,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.usb.descriptors.UsbDescriptorParser;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -259,7 +259,18 @@
                     getCurrentUserSettings().deviceAttachedForFixedHandler(mNewDevice,
                             usbDeviceConnectionHandler);
                 }
-                mUsbAlsaManager.usbDeviceAdded(mNewDevice);
+                // deviceName is something like: "/dev/bus/usb/001/001"
+                UsbDescriptorParser parser = new UsbDescriptorParser();
+                boolean isInputHeadset = false;
+                boolean isOutputHeadset = false;
+                if (parser.parseDevice(mNewDevice.getDeviceName())) {
+                    isInputHeadset = parser.isInputHeadset();
+                    isOutputHeadset = parser.isOutputHeadset();
+                    Slog.i(TAG, "---- isHeadset[in:" + isInputHeadset
+                            + " , out:" + isOutputHeadset + "]");
+                }
+                mUsbAlsaManager.usbDeviceAdded(mNewDevice,
+                        isInputHeadset, isOutputHeadset);
             } else {
                 Slog.e(TAG, "mNewDevice is null in endUsbDeviceAdded");
             }
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 2729795..7e2496c 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -22,11 +22,12 @@
 import android.hardware.usb.UsbPort;
 import android.hardware.usb.UsbPortStatus;
 import android.hardware.usb.V1_0.IUsb;
-import android.hardware.usb.V1_0.IUsbCallback;
 import android.hardware.usb.V1_0.PortRole;
 import android.hardware.usb.V1_0.PortRoleType;
 import android.hardware.usb.V1_0.PortStatus;
 import android.hardware.usb.V1_0.Status;
+import android.hardware.usb.V1_1.IUsbCallback;
+import android.hardware.usb.V1_1.PortStatus_1_1;
 import android.hidl.manager.V1_0.IServiceManager;
 import android.hidl.manager.V1_0.IServiceNotification;
 import android.os.Bundle;
@@ -454,6 +455,39 @@
             return;
         }
 
+
+        public void notifyPortStatusChange_1_1(ArrayList<PortStatus_1_1> currentPortStatus,
+                int retval) {
+            if (!portManager.mSystemReady) {
+                return;
+            }
+
+            if (retval != Status.SUCCESS) {
+                logAndPrint(Log.ERROR, pw, "port status enquiry failed");
+                return;
+            }
+
+            ArrayList<RawPortInfo> newPortInfo = new ArrayList<RawPortInfo>();
+
+            for (PortStatus_1_1 current : currentPortStatus) {
+                RawPortInfo temp = new RawPortInfo(current.status.portName,
+                        current.supportedModes, current.currentMode,
+                        current.status.canChangeMode, current.status.currentPowerRole,
+                        current.status.canChangePowerRole,
+                        current.status.currentDataRole, current.status.canChangeDataRole);
+                newPortInfo.add(temp);
+                logAndPrint(Log.INFO, pw, "ClientCallback: " + current.status.portName);
+            }
+
+            Message message = portManager.mHandler.obtainMessage();
+            Bundle bundle = new Bundle();
+            bundle.putParcelableArrayList(PORT_INFO, newPortInfo);
+            message.what = MSG_UPDATE_PORTS;
+            message.setData(bundle);
+            portManager.mHandler.sendMessage(message);
+            return;
+        }
+
         public void notifyRoleSwitchStatus(String portName, PortRole role, int retval) {
             if (retval == Status.SUCCESS) {
                 logAndPrint(Log.INFO, pw, portName + " role switch successful");
@@ -568,7 +602,7 @@
             IndentingPrintWriter pw) {
         // Only allow mode switch capability for dual role ports.
         // Validate that the current mode matches the supported modes we expect.
-        if (supportedModes != UsbPort.MODE_DUAL) {
+        if ((supportedModes & UsbPort.MODE_DUAL) != UsbPort.MODE_DUAL) {
             canChangeMode = false;
             if (currentMode != 0 && currentMode != supportedModes) {
                 logAndPrint(Log.WARN, pw, "Ignoring inconsistent current mode from USB "
diff --git a/services/usb/java/com/android/server/usb/descriptors/ByteStream.java b/services/usb/java/com/android/server/usb/descriptors/ByteStream.java
new file mode 100644
index 0000000..d678931
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/ByteStream.java
@@ -0,0 +1,189 @@
+/*
+ * 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.usb.descriptors;
+
+import android.annotation.NonNull;
+
+/**
+ * @hide
+ * A stream interface wrapping a byte array. Very much like a java.io.ByteArrayInputStream
+ * but with the capability to "back up" in situations where the parser discovers that a
+ * UsbDescriptor has overrun its length.
+ */
+public class ByteStream {
+    private static final String TAG = "ByteStream";
+
+    /** The byte array being wrapped */
+    @NonNull
+    private final byte[] mBytes; // this is never null.
+
+    /**
+     * The index into the byte array to be read next.
+     * This value is altered by reading data out of the stream
+     * (using either the getByte() or unpack*() methods), or alternatively
+     * by explicitly offseting the stream position with either
+     * advance() or reverse().
+     */
+    private int mIndex;
+
+    /*
+     * This member used with resetReadCount() & getReadCount() can be used to determine how many
+     * bytes a UsbDescriptor subclass ACTUALLY reads (as opposed to what its length field says).
+     * using this info, the parser can mark a descriptor as valid or invalid and correct the stream
+     * position with advance() & reverse() to keep from "getting lost" in the descriptor stream.
+     */
+    private int mReadCount;
+
+    /**
+     * Create a ByteStream object wrapping the specified byte array.
+     *
+     * @param bytes The byte array containing the raw descriptor information retrieved from
+     *              the USB device.
+     * @throws IllegalArgumentException
+     */
+    public ByteStream(@NonNull byte[] bytes) {
+        if (bytes == null) {
+            throw new IllegalArgumentException();
+        }
+        mBytes = bytes;
+    }
+
+    /**
+     * Resets the running count of bytes read so that later we can see how much more has been read.
+     */
+    public void resetReadCount() {
+        mReadCount = 0;
+    }
+
+    /**
+     * Retrieves the running count of bytes read from the stream.
+     */
+    public int getReadCount() {
+        return mReadCount;
+    }
+
+    /**
+     * @return The value of the next byte in the stream without advancing the stream.
+     * Does not affect the running count as the byte hasn't been "consumed".
+     * @throws IndexOutOfBoundsException
+     */
+    public byte peekByte() {
+        if (available() > 0) {
+            return mBytes[mIndex + 1];
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * @return the next byte from the stream and advances the stream and the read count. Note
+     * that this is a signed byte (as is the case of byte in Java). The user may need to understand
+     * from context if it should be interpreted as an unsigned value.
+     * @throws IndexOutOfBoundsException
+     */
+    public byte getByte() {
+        if (available() > 0) {
+            mReadCount++;
+            return mBytes[mIndex++];
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Reads 2 bytes in *little endian format* from the stream and composes a 16-bit integer.
+     * As we are storing the 2-byte value in a 4-byte integer, the upper 2 bytes are always
+     * 0, essentially making the returned value *unsigned*.
+     * @return The 16-bit integer (packed into the lower 2 bytes of an int) encoded by the
+     * next 2 bytes in the stream.
+     * @throws IndexOutOfBoundsException
+     */
+    public int unpackUsbWord() {
+        if (available() >= 2) {
+            int b0 = getByte();
+            int b1 = getByte();
+            return ((b1 << 8) & 0x0000FF00) | (b0 & 0x000000FF);
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Reads 3 bytes in *little endian format* from the stream and composes a 24-bit integer.
+     * As we are storing the 3-byte value in a 4-byte integer, the upper byte is always
+     * 0, essentially making the returned value *unsigned*.
+     * @return The 24-bit integer (packed into the lower 3 bytes of an int) encoded by the
+     * next 3 bytes in the stream.
+     * @throws IndexOutOfBoundsException
+     */
+    public int unpackUsbTriple() {
+        if (available() >= 3) {
+            int b0 = getByte();
+            int b1 = getByte();
+            int b2 = getByte();
+            return ((b2 << 16) & 0x00FF0000) | ((b1 << 8) & 0x0000FF00) | (b0 & 0x000000FF);
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Advances the logical position in the stream. Affects the running count also.
+     * @param numBytes The number of bytes to advance.
+     * @throws IndexOutOfBoundsException
+     * @throws IllegalArgumentException
+     */
+    public void advance(int numBytes) {
+        if (numBytes < 0) {
+            // Positive offsets only
+            throw new IllegalArgumentException();
+        }
+        // do arithmetic and comparison in long to ovoid potention integer overflow
+        long longNewIndex = (long) mIndex + (long) numBytes;
+        if (longNewIndex < (long) mBytes.length) {
+            mReadCount += numBytes;
+            mIndex += numBytes;
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Reverse the logical position in the stream. Affects the running count also.
+     * @param numBytes The (positive) number of bytes to reverse.
+     * @throws IndexOutOfBoundsException
+     * @throws IllegalArgumentException
+     */
+    public void reverse(int numBytes) {
+        if (numBytes < 0) {
+            // Positive (reverse) offsets only
+            throw new IllegalArgumentException();
+        }
+        if (mIndex >= numBytes) {
+            mReadCount -= numBytes;
+            mIndex -= numBytes;
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * @return The number of bytes available to be read in the stream.
+     */
+    public int available() {
+        return mBytes.length - mIndex;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACAudioControlEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioControlEndpoint.java
new file mode 100644
index 0000000..96fcc6a
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioControlEndpoint.java
@@ -0,0 +1,72 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Audio Control Endpoint.
+ * audio10.pdf section 4.4.2.1
+ */
+public class UsbACAudioControlEndpoint extends UsbACEndpoint {
+    private static final String TAG = "ACAudioControlEndpoint";
+
+    private byte mAddress;  // 2:1 The address of the endpoint on the USB device.
+                            // D7: Direction. 1 = IN endpoint
+                            // D6..4: Reserved, reset to zero
+                            // D3..0: The endpoint number.
+    private byte mAttribs;  // 3:1 (see ATTRIBSMASK_* below
+    private int mMaxPacketSize; // 4:2 Maximum packet size this endpoint is capable of sending
+                                // or receiving when this configuration is selected.
+    private byte mInterval; // 6:1
+
+    static final byte ADDRESSMASK_DIRECTION = (byte) 0x80;
+    static final byte ADDRESSMASK_ENDPOINT  = 0x0F;
+
+    static final byte ATTRIBSMASK_SYNC  = 0x0C;
+    static final byte ATTRIBMASK_TRANS  = 0x03;
+
+    public UsbACAudioControlEndpoint(int length, byte type, byte subclass) {
+        super(length, type, subclass);
+    }
+
+    public byte getAddress() {
+        return mAddress;
+    }
+
+    public byte getAttribs() {
+        return mAttribs;
+    }
+
+    public int getMaxPacketSize() {
+        return mMaxPacketSize;
+    }
+
+    public byte getInterval() {
+        return mInterval;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        mAddress = stream.getByte();
+        mAttribs = stream.getByte();
+        mMaxPacketSize = stream.unpackUsbWord();
+        mInterval = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACAudioStreamEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioStreamEndpoint.java
new file mode 100644
index 0000000..d387883
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioStreamEndpoint.java
@@ -0,0 +1,39 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Streaming Endpoint
+ * see audio10.pdf section 3.7.2
+ */
+public class UsbACAudioStreamEndpoint extends UsbACEndpoint {
+    private static final String TAG = "ACAudioStreamEndpoint";
+
+    //TODO data fields...
+    public UsbACAudioStreamEndpoint(int length, byte type, byte subclass) {
+        super(length, type, subclass);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        //TODO Read fields
+        stream.advance(mLength - stream.getReadCount());
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java
new file mode 100644
index 0000000..223496ab
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java
@@ -0,0 +1,71 @@
+/*
+ * 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.usb.descriptors;
+
+import android.util.Log;
+
+/**
+ * @hide
+ * An audio class-specific Endpoint
+ * see audio10.pdf section 4.4.1.2
+ */
+abstract class UsbACEndpoint extends UsbDescriptor {
+    private static final String TAG = "ACEndpoint";
+
+    protected final byte mSubclass; // from the mSubclass member of the "enclosing"
+                                    // Interface Descriptor, not the stream.
+    protected byte mSubtype;        // 2:1 HEADER descriptor subtype
+
+    UsbACEndpoint(int length, byte type, byte subclass) {
+        super(length, type);
+        mSubclass = subclass;
+    }
+
+    public byte getSubclass() {
+        return mSubclass;
+    }
+
+    public byte getSubtype() {
+        return mSubtype;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mSubtype = stream.getByte();
+
+        return mLength;
+    }
+
+    public static UsbDescriptor allocDescriptor(UsbDescriptorParser parser,
+            int length, byte type) {
+        UsbInterfaceDescriptor interfaceDesc = parser.getCurInterface();
+        byte subClass = interfaceDesc.getUsbSubclass();
+        switch (subClass) {
+            case AUDIO_AUDIOCONTROL:
+                return new UsbACAudioControlEndpoint(length, type, subClass);
+
+            case AUDIO_AUDIOSTREAMING:
+                return new UsbACAudioStreamEndpoint(length, type, subClass);
+
+            case AUDIO_MIDISTREAMING:
+                return new UsbACMidiEndpoint(length, type, subClass);
+
+            default:
+                Log.w(TAG, "Unknown Audio Class Endpoint id:0x" + Integer.toHexString(subClass));
+                return null;
+        }
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACFeatureUnit.java b/services/usb/java/com/android/server/usb/descriptors/UsbACFeatureUnit.java
new file mode 100644
index 0000000..739fe55
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACFeatureUnit.java
@@ -0,0 +1,76 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Feature Unit Interface
+ * see audio10.pdf section 3.5.5
+ */
+public class UsbACFeatureUnit extends UsbACInterface {
+    private static final String TAG = "ACFeatureUnit";
+
+    // audio10.pdf section 4.3.2.5
+    public static final int CONTROL_MASK_MUTE =    0x0001;
+    public static final int CONTROL_MASK_VOL =     0x0002;
+    public static final int CONTROL_MASK_BASS =    0x0004;
+    public static final int CONTROL_MASK_MID =     0x0008;
+    public static final int CONTROL_MASK_TREB =    0x0010;
+    public static final int CONTROL_MASK_EQ =      0x0020;
+    public static final int CONTROL_MASK_AGC =     0x0040;
+    public static final int CONTROL_MASK_DELAY =   0x0080;
+    public static final int CONTROL_MASK_BOOST =   0x0100; // BASS boost
+    public static final int CONTROL_MASK_LOUD =    0x0200; // LOUDNESS
+
+    private int mNumChannels;
+
+    private byte mUnitID;   // 3:1 Constant uniquely identifying the Unit within the audio function.
+                            // This value is used in all requests to address this Unit
+    private byte mSourceID; // 4:1 ID of the Unit or Terminal to which this Feature Unit
+                            // is connected.
+    private byte mControlSize;  // 5:1 Size in bytes of an element of the mControls array: n
+    private int[] mControls;    // 6:? bitmask (see above) of supported controls in a given
+                                // logical channel
+    private byte mUnitName;     // ?:1 Index of a string descriptor, describing this Feature Unit.
+
+    public UsbACFeatureUnit(int length, byte type, byte subtype, byte subClass) {
+        super(length, type, subtype, subClass);
+    }
+
+    public int getNumChannels() {
+        return mNumChannels;
+    }
+
+    public byte getUnitID() {
+        return mUnitID;
+    }
+
+    public byte getSourceID() {
+        return mSourceID;
+    }
+
+    public byte getControlSize() {
+        return mControlSize;
+    }
+
+    public int[] getControls() {
+        return mControls;
+    }
+
+    public byte getUnitName() {
+        return mUnitName;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACHeader.java b/services/usb/java/com/android/server/usb/descriptors/UsbACHeader.java
new file mode 100644
index 0000000..e31438c
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACHeader.java
@@ -0,0 +1,78 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Interface Header.
+ * see audio10.pdf section 4.3.2
+ */
+public class UsbACHeader extends UsbACInterface {
+    private static final String TAG = "ACHeader";
+
+    private int mADCRelease;    // 3:2 Audio Device Class Specification Release (BCD).
+    private int mTotalLength;   // 5:2 Total number of bytes returned for the class-specific
+                                // AudioControl interface descriptor. Includes the combined length
+                                // of this descriptor header and all Unit and Terminal descriptors.
+    private byte mNumInterfaces = 0; // 7:1 The number of AudioStreaming and MIDIStreaming
+                                     // interfaces in the Audio Interface Collection to which this
+                                     // AudioControl interface belongs: n
+    private byte[] mInterfaceNums = null;   // 8:n List of Audio/MIDI streaming interface
+                                            // numbers associate with this endpoint
+    private byte mControls;                 // Vers 2.0 thing
+
+    public UsbACHeader(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    public int getADCRelease() {
+        return mADCRelease;
+    }
+
+    public int getTotalLength() {
+        return mTotalLength;
+    }
+
+    public byte getNumInterfaces() {
+        return mNumInterfaces;
+    }
+
+    public byte[] getInterfaceNums() {
+        return mInterfaceNums;
+    }
+
+    public byte getControls() {
+        return mControls;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mADCRelease = stream.unpackUsbWord();
+
+        mTotalLength = stream.unpackUsbWord();
+        if (mADCRelease >= 0x200) {
+            mControls = stream.getByte();
+        } else {
+            mNumInterfaces = stream.getByte();
+            mInterfaceNums = new byte[mNumInterfaces];
+            for (int index = 0; index < mNumInterfaces; index++) {
+                mInterfaceNums[index] = stream.getByte();
+            }
+        }
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACInputTerminal.java b/services/usb/java/com/android/server/usb/descriptors/UsbACInputTerminal.java
new file mode 100644
index 0000000..653a7de
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACInputTerminal.java
@@ -0,0 +1,64 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Input Terminal interface.
+ * see audio10.pdf section 4.3.2.1
+ */
+public class UsbACInputTerminal extends UsbACTerminal {
+    private static final String TAG = "ACInputTerminal";
+
+    private byte mNrChannels;       // 7:1 1 Channel (0x01)
+                                    // Number of logical output channels in the
+                                    // Terminal’s output audio channel cluster
+    private int mChannelConfig;     // 8:2 Mono (0x0000)
+    private byte mChannelNames;     // 10:1 Unused (0x00)
+    private byte mTerminal;         // 11:1 Unused (0x00)
+
+    public UsbACInputTerminal(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    public byte getNrChannels() {
+        return mNrChannels;
+    }
+
+    public int getChannelConfig() {
+        return mChannelConfig;
+    }
+
+    public byte getChannelNames() {
+        return mChannelNames;
+    }
+
+    public byte getTerminal() {
+        return mTerminal;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        mNrChannels = stream.getByte();
+        mChannelConfig = stream.unpackUsbWord();
+        mChannelNames = stream.getByte();
+        mTerminal = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java b/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java
new file mode 100644
index 0000000..0ab7fcc
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+import android.util.Log;
+
+/**
+ * @hide
+ * An audio class-specific Interface.
+ * see audio10.pdf section 4.3.2
+ */
+public abstract class UsbACInterface extends UsbDescriptor {
+    private static final String TAG = "ACInterface";
+
+    // Audio Control Subtypes
+    public static final byte ACI_UNDEFINED = 0;
+    public static final byte ACI_HEADER = 1;
+    public static final byte ACI_INPUT_TERMINAL = 2;
+    public static final byte ACI_OUTPUT_TERMINAL = 3;
+    public static final byte ACI_MIXER_UNIT = 4;
+    public static final byte ACI_SELECTOR_UNIT = 5;
+    public static final byte ACI_FEATURE_UNIT = 6;
+    public static final byte ACI_PROCESSING_UNIT = 7;
+    public static final byte ACI_EXTENSION_UNIT = 8;
+
+    // Audio Streaming Subtypes
+    public static final byte ASI_UNDEFINED = 0;
+    public static final byte ASI_GENERAL = 1;
+    public static final byte ASI_FORMAT_TYPE = 2;
+    public static final byte ASI_FORMAT_SPECIFIC = 3;
+
+    // MIDI Streaming Subtypes
+    public static final byte MSI_UNDEFINED = 0;
+    public static final byte MSI_HEADER = 1;
+    public static final byte MSI_IN_JACK = 2;
+    public static final byte MSI_OUT_JACK = 3;
+    public static final byte MSI_ELEMENT = 4;
+
+    // Sample format IDs (encodings)
+    // FORMAT_I
+    public static final int FORMAT_I_UNDEFINED     = 0x0000;
+    public static final int FORMAT_I_PCM           = 0x0001;
+    public static final int FORMAT_I_PCM8          = 0x0002;
+    public static final int FORMAT_I_IEEE_FLOAT    = 0x0003;
+    public static final int FORMAT_I_ALAW          = 0x0004;
+    public static final int FORMAT_I_MULAW         = 0x0005;
+    // FORMAT_II
+    public static final int FORMAT_II_UNDEFINED    = 0x1000;
+    public static final int FORMAT_II_MPEG         = 0x1001;
+    public static final int FORMAT_II_AC3          = 0x1002;
+    // FORMAT_III
+    public static final int FORMAT_III_UNDEFINED              = 0x2000;
+    public static final int FORMAT_III_IEC1937AC3             = 0x2001;
+    public static final int FORMAT_III_IEC1937_MPEG1_Layer1   = 0x2002;
+    public static final int FORMAT_III_IEC1937_MPEG1_Layer2   = 0x2003;
+    public static final int FORMAT_III_IEC1937_MPEG2_EXT      = 0x2004;
+    public static final int FORMAT_III_IEC1937_MPEG2_Layer1LS = 0x2005;
+
+    protected final byte mSubtype;  // 2:1 HEADER descriptor subtype
+    protected final byte mSubclass; // from the mSubclass member of the
+                                    // "enclosing" Interface Descriptor
+
+    public UsbACInterface(int length, byte type, byte subtype, byte subclass) {
+        super(length, type);
+        mSubtype = subtype;
+        mSubclass = subclass;
+    }
+
+    public byte getSubtype() {
+        return mSubtype;
+    }
+
+    public byte getSubclass() {
+        return mSubclass;
+    }
+
+    private static UsbDescriptor allocAudioControlDescriptor(ByteStream stream,
+            int length, byte type, byte subtype, byte subClass) {
+        switch (subtype) {
+            case ACI_HEADER:
+                return new UsbACHeader(length, type, subtype, subClass);
+
+            case ACI_INPUT_TERMINAL:
+                return new UsbACInputTerminal(length, type, subtype, subClass);
+
+            case ACI_OUTPUT_TERMINAL:
+                return new UsbACOutputTerminal(length, type, subtype, subClass);
+
+            case ACI_SELECTOR_UNIT:
+                return new UsbACSelectorUnit(length, type, subtype, subClass);
+
+            case ACI_FEATURE_UNIT:
+                return new UsbACFeatureUnit(length, type, subtype, subClass);
+
+            case ACI_MIXER_UNIT:
+                return new UsbACMixerUnit(length, type, subtype, subClass);
+
+            case ACI_PROCESSING_UNIT:
+            case ACI_EXTENSION_UNIT:
+            case ACI_UNDEFINED:
+                // break; Fall through until we implement this descriptor
+            default:
+                Log.w(TAG, "Unknown Audio Class Interface subtype:0x"
+                        + Integer.toHexString(subtype));
+                return null;
+        }
+    }
+
+    private static UsbDescriptor allocAudioStreamingDescriptor(ByteStream stream,
+            int length, byte type, byte subtype, byte subClass) {
+        switch (subtype) {
+            case ASI_GENERAL:
+                return new UsbASGeneral(length, type, subtype, subClass);
+
+            case ASI_FORMAT_TYPE:
+                return UsbASFormat.allocDescriptor(stream, length, type, subtype, subClass);
+
+            case ASI_FORMAT_SPECIFIC:
+            case ASI_UNDEFINED:
+                // break; Fall through until we implement this descriptor
+            default:
+                Log.w(TAG, "Unknown Audio Streaming Interface subtype:0x"
+                        + Integer.toHexString(subtype));
+                return null;
+        }
+    }
+
+    private static UsbDescriptor allocMidiStreamingDescriptor(int length, byte type,
+            byte subtype, byte subClass) {
+        switch (subtype) {
+            case MSI_HEADER:
+                return new UsbMSMidiHeader(length, type, subtype, subClass);
+
+            case MSI_IN_JACK:
+                return new UsbMSMidiInputJack(length, type, subtype, subClass);
+
+            case MSI_OUT_JACK:
+                return new UsbMSMidiOutputJack(length, type, subtype, subClass);
+
+            case MSI_ELEMENT:
+                // break;
+                // Fall through until we implement that descriptor
+
+            case MSI_UNDEFINED:
+                // break; Fall through until we implement this descriptor
+            default:
+                Log.w(TAG, "Unknown MIDI Streaming Interface subtype:0x"
+                        + Integer.toHexString(subtype));
+                return null;
+        }
+    }
+
+    /**
+     * Allocates an audio class interface subtype based on subtype and subclass.
+     */
+    public static UsbDescriptor allocDescriptor(UsbDescriptorParser parser, ByteStream stream,
+            int length, byte type) {
+        byte subtype = stream.getByte();
+        UsbInterfaceDescriptor interfaceDesc = parser.getCurInterface();
+        byte subClass = interfaceDesc.getUsbSubclass();
+        switch (subClass) {
+            case AUDIO_AUDIOCONTROL:
+                return allocAudioControlDescriptor(stream, length, type, subtype, subClass);
+
+            case AUDIO_AUDIOSTREAMING:
+                return allocAudioStreamingDescriptor(stream, length, type, subtype, subClass);
+
+            case AUDIO_MIDISTREAMING:
+                return allocMidiStreamingDescriptor(length, type, subtype, subClass);
+
+            default:
+                Log.w(TAG, "Unknown Audio Class Interface Subclass: 0x"
+                        + Integer.toHexString(subClass));
+                return null;
+        }
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACMidiEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACMidiEndpoint.java
new file mode 100644
index 0000000..9c07242
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACMidiEndpoint.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Midi Endpoint.
+ * see midi10.pdf section 6.2.2
+ */
+public class UsbACMidiEndpoint extends UsbACEndpoint {
+    private static final String TAG = "ACMidiEndpoint";
+
+    private byte mNumJacks;
+    private byte[] mJackIds;
+
+    public UsbACMidiEndpoint(int length, byte type, byte subclass) {
+        super(length, type, subclass);
+    }
+
+    public byte getNumJacks() {
+        return mNumJacks;
+    }
+
+    public byte[] getJackIds() {
+        return mJackIds;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        mNumJacks = stream.getByte();
+        mJackIds = new byte[mNumJacks];
+        for (int jack = 0; jack < mNumJacks; jack++) {
+            mJackIds[jack] = stream.getByte();
+        }
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACMixerUnit.java b/services/usb/java/com/android/server/usb/descriptors/UsbACMixerUnit.java
new file mode 100644
index 0000000..552b5ae
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACMixerUnit.java
@@ -0,0 +1,100 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Mixer Interface.
+ * see audio10.pdf section 4.3.2.3
+ */
+public class UsbACMixerUnit extends UsbACInterface {
+    private static final String TAG = "ACMixerUnit";
+
+    private byte mUnitID;       // 3:1
+    private byte mNumInputs;    // 4:1 Number of Input Pins of this Unit.
+    private byte[] mInputIDs;   // 5...:1 ID of the Unit or Terminal to which the Input Pins
+                                // are connected.
+    private byte mNumOutputs;   // The number of output channels
+    private int mChannelConfig; // Spacial location of output channels
+    private byte mChanNameID;   // First channel name string descriptor ID
+    private byte[] mControls;   // bitmasks of which controls are present for each channel
+    private byte mNameID;       // string descriptor ID of mixer name
+
+    public UsbACMixerUnit(int length, byte type, byte subtype, byte subClass) {
+        super(length, type, subtype, subClass);
+    }
+
+    public byte getUnitID() {
+        return mUnitID;
+    }
+
+    public byte getNumInputs() {
+        return mNumInputs;
+    }
+
+    public byte[] getInputIDs() {
+        return mInputIDs;
+    }
+
+    public byte getNumOutputs() {
+        return mNumOutputs;
+    }
+
+    public int getChannelConfig() {
+        return mChannelConfig;
+    }
+
+    public byte getChanNameID() {
+        return mChanNameID;
+    }
+
+    public byte[] getControls() {
+        return mControls;
+    }
+
+    public byte getNameID() {
+        return mNameID;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mUnitID = stream.getByte();
+        mNumInputs = stream.getByte();
+        mInputIDs = new byte[mNumInputs];
+        for (int input = 0; input < mNumInputs; input++) {
+            mInputIDs[input] = stream.getByte();
+        }
+        mNumOutputs = stream.getByte();
+        mChannelConfig = stream.unpackUsbWord();
+        mChanNameID = stream.getByte();
+
+        int controlArraySize;
+        int totalChannels = mNumInputs * mNumOutputs;
+        if (totalChannels % 8 == 0) {
+            controlArraySize = totalChannels / 8;
+        } else {
+            controlArraySize = totalChannels / 8 + 1;
+        }
+        mControls = new byte[controlArraySize];
+        for (int index = 0; index < controlArraySize; index++) {
+            mControls[index] = stream.getByte();
+        }
+
+        mNameID = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACOutputTerminal.java b/services/usb/java/com/android/server/usb/descriptors/UsbACOutputTerminal.java
new file mode 100644
index 0000000..f957e3d
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACOutputTerminal.java
@@ -0,0 +1,49 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Output Terminal Interface.
+ * see audio10.pdf section 4.3.2.2
+ */
+public class UsbACOutputTerminal extends UsbACTerminal {
+    private static final String TAG = "ACOutputTerminal";
+
+    private byte mSourceID;         // 7:1 From Input Terminal. (0x01)
+    private byte mTerminal;         // 8:1 Unused.
+
+    public UsbACOutputTerminal(int length, byte type, byte subtype, byte subClass) {
+        super(length, type, subtype, subClass);
+    }
+
+    public byte getSourceID() {
+        return mSourceID;
+    }
+
+    public byte getTerminal() {
+        return mTerminal;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        mSourceID = stream.getByte();
+        mTerminal = stream.getByte();
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACSelectorUnit.java b/services/usb/java/com/android/server/usb/descriptors/UsbACSelectorUnit.java
new file mode 100644
index 0000000..b1f60bd
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACSelectorUnit.java
@@ -0,0 +1,65 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Selector Unit Interface.
+ * see audio10.pdf section 4.3.2.4
+ */
+public class UsbACSelectorUnit extends UsbACInterface {
+    private static final String TAG = "ACSelectorUnit";
+
+    private byte mUnitID;   // 3:1 Constant uniquely identifying the Unit within the audio function.
+                            // This value is used in all requests to address this Unit.
+    private byte mNumPins;  // 4:1 Number of input pins in this unit
+    private byte[] mSourceIDs;  // 5+mNumPins:1 ID of the Unit or Terminal to which the first
+                                // Input Pin of this Selector Unit is connected.
+    private byte mNameIndex;    // Index of a string descriptor, describing the Selector Unit.
+
+    public UsbACSelectorUnit(int length, byte type, byte subtype, byte subClass) {
+        super(length, type, subtype, subClass);
+    }
+
+    public byte getUnitID() {
+        return mUnitID;
+    }
+
+    public byte getNumPins() {
+        return mNumPins;
+    }
+
+    public byte[] getSourceIDs() {
+        return mSourceIDs;
+    }
+
+    public byte getNameIndex() {
+        return mNameIndex;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mUnitID = stream.getByte();
+        mNumPins = stream.getByte();
+        mSourceIDs = new byte[mNumPins];
+        for (int index = 0; index < mNumPins; index++) {
+            mSourceIDs[index] = stream.getByte();
+        }
+        mNameIndex = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java b/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java
new file mode 100644
index 0000000..ea80208
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java
@@ -0,0 +1,54 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ */
+public abstract class UsbACTerminal extends UsbACInterface {
+    // Note that these fields are the same for both the
+    // audio class-specific Output Terminal Interface.(audio10.pdf section 4.3.2.2)
+    // and audio class-specific Input Terminal interface.(audio10.pdf section 4.3.2.1)
+    // so we may as well unify the parsing here.
+    protected byte mTerminalID;       // 3:1 ID of this Output Terminal. (0x02)
+    protected int mTerminalType;      // 4:2 USB Streaming. (0x0101)
+    protected byte mAssocTerminal;    // 6:1 Unused (0x00)
+
+    public UsbACTerminal(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    public byte getTerminalID() {
+        return mTerminalID;
+    }
+
+    public int getTerminalType() {
+        return mTerminalType;
+    }
+
+    public byte getAssocTerminal() {
+        return mAssocTerminal;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mTerminalID = stream.getByte();
+        mTerminalType = stream.unpackUsbWord();
+        mAssocTerminal = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASFormat.java b/services/usb/java/com/android/server/usb/descriptors/UsbASFormat.java
new file mode 100644
index 0000000..d7c84c6
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbASFormat.java
@@ -0,0 +1,64 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Format Interface.
+ *   Subclasses: UsbACFormatI and UsbACFormatII.
+ * see audio10.pdf section 4.5.3 & & Frmts10.pdf
+ */
+public abstract class UsbASFormat extends UsbACInterface {
+    private static final String TAG = "ASFormat";
+
+    private final byte mFormatType;   // 3:1 FORMAT_TYPE_*
+
+    public static final byte FORMAT_TYPE_I = 1;
+    public static final byte FORMAT_TYPE_II = 2;
+
+    public UsbASFormat(int length, byte type, byte subtype, byte formatType, byte mSubclass) {
+        super(length, type, subtype, mSubclass);
+        mFormatType = formatType;
+    }
+
+    public byte getFormatType() {
+        return mFormatType;
+    }
+
+    /**
+     * Allocates the audio-class format subtype associated with the format type read from the
+     * stream.
+     */
+    public static UsbDescriptor allocDescriptor(ByteStream stream, int length, byte type,
+            byte subtype, byte subclass) {
+
+        byte formatType = stream.getByte();
+        //TODO
+        // There is an issue parsing format descriptors on (some) USB 2.0 pro-audio interfaces
+        // Since we don't need this info for headset detection, just skip these descriptors
+        // for now to avoid the (low) possibility of an IndexOutOfBounds exception.
+        switch (formatType) {
+//            case FORMAT_TYPE_I:
+//                return new UsbASFormatI(length, type, subtype, formatType, subclass);
+//
+//            case FORMAT_TYPE_II:
+//                return new UsbASFormatII(length, type, subtype, formatType, subclass);
+
+            default:
+                return null;
+        }
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASFormatI.java b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatI.java
new file mode 100644
index 0000000..347a6cf
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatI.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Format I interface.
+ * see Frmts10.pdf section 2.2
+ */
+public class UsbASFormatI extends UsbASFormat {
+    private static final String TAG = "ASFormatI";
+
+    private byte mNumChannels;      // 4:1
+    private byte mSubframeSize;     // 5:1 frame size in bytes
+    private byte mBitResolution;    // 6:1 sample size in bits
+    private byte mSampleFreqType;   // 7:1
+    private int[] mSampleRates;     // if mSamFreqType == 0, there will be 2 values: the
+                                    // min & max rates otherwise mSamFreqType rates.
+                                    // All 3-byte values. All rates in Hz
+
+    public UsbASFormatI(int length, byte type, byte subtype, byte formatType, byte subclass) {
+        super(length, type, subtype, formatType, subclass);
+    }
+
+    public byte getNumChannels() {
+        return mNumChannels;
+    }
+
+    public byte getSubframeSize() {
+        return mSubframeSize;
+    }
+
+    public byte getBitResolution() {
+        return mBitResolution;
+    }
+
+    public byte getSampleFreqType() {
+        return mSampleFreqType;
+    }
+
+    public int[] getSampleRates() {
+        return mSampleRates;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mNumChannels = stream.getByte();
+        mSubframeSize = stream.getByte();
+        mBitResolution = stream.getByte();
+        mSampleFreqType = stream.getByte();
+        if (mSampleFreqType == 0) {
+            mSampleRates = new int[2];
+            mSampleRates[0] = stream.unpackUsbTriple();
+            mSampleRates[1] = stream.unpackUsbTriple();
+        } else {
+            mSampleRates = new int[mSampleFreqType];
+            for (int index = 0; index < mSampleFreqType; index++) {
+                mSampleRates[index] = stream.unpackUsbTriple();
+            }
+        }
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASFormatII.java b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatII.java
new file mode 100644
index 0000000..abdc621
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatII.java
@@ -0,0 +1,72 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Format II interface.
+ * see Frmts10.pdf section 2.3
+ */
+public class UsbASFormatII extends UsbASFormat {
+    private static final String TAG = "ASFormatII";
+
+    private int mMaxBitRate; // 4:2 Indicates the maximum number of bits per second this
+                            // interface can handle. Expressed in kbits/s.
+    private int mSamplesPerFrame;   // 6:2 Indicates the number of PCM audio samples contained
+                                    // in one encoded audio frame.
+    private byte mSamFreqType;  // Indicates how the sampling frequency can be programmed:
+                                // 0: Continuous sampling frequency
+                                // 1..255: The number of discrete sampling frequencies supported
+                                // by the isochronous data endpoint of the AudioStreaming
+                                // interface (ns)
+    private int[] mSampleRates; // if mSamFreqType == 0, there will be 2 values:
+                                // the min & max rates. otherwise mSamFreqType rates.
+                                // All 3-byte values. All rates in Hz
+
+    public UsbASFormatII(int length, byte type, byte subtype, byte formatType, byte subclass) {
+        super(length, type, subtype, formatType, subclass);
+    }
+
+    public int getMaxBitRate() {
+        return mMaxBitRate;
+    }
+
+    public int getSamplesPerFrame() {
+        return mSamplesPerFrame;
+    }
+
+    public byte getSamFreqType() {
+        return mSamFreqType;
+    }
+
+    public int[] getSampleRates() {
+        return mSampleRates;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mMaxBitRate = stream.unpackUsbWord();
+        mSamplesPerFrame = stream.unpackUsbWord();
+        mSamFreqType = stream.getByte();
+        int numFreqs = mSamFreqType == 0 ? 2 : mSamFreqType;
+        mSampleRates = new int[numFreqs];
+        for (int index = 0; index < numFreqs; index++) {
+            mSampleRates[index] = stream.unpackUsbTriple();
+        }
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASGeneral.java b/services/usb/java/com/android/server/usb/descriptors/UsbASGeneral.java
new file mode 100644
index 0000000..c4f42d3
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbASGeneral.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.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific General interface.
+ * see audio10.pdf section 4.5.2
+ */
+public class UsbASGeneral extends UsbACInterface {
+    private static final String TAG = "ACGeneral";
+
+    // audio10.pdf - section 4.5.2
+    private byte mTerminalLink; // 3:1 The Terminal ID of the Terminal to which the endpoint
+                                // of this interface is connected.
+    private byte mDelay;        // 4:1 Delay introduced by the data path (see Section 3.4,
+                                // “Inter Channel Synchronization”). Expressed in number of frames.
+    private int mFormatTag;     // 5:2 The Audio Data Format that has to be used to communicate
+                                // with this interface.
+
+    public UsbASGeneral(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    public byte getTerminalLink() {
+        return mTerminalLink;
+    }
+
+    public byte getDelay() {
+        return mDelay;
+    }
+
+    public int getFormatTag() {
+        return mFormatTag;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mTerminalLink = stream.getByte();
+        mDelay = stream.getByte();
+        mFormatTag = stream.unpackUsbWord();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbBinaryParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbBinaryParser.java
new file mode 100644
index 0000000..185cee2
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbBinaryParser.java
@@ -0,0 +1,72 @@
+/*
+ * 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.usb.descriptors;
+
+import android.hardware.usb.UsbDeviceConnection;
+import android.util.Log;
+
+import com.android.server.usb.descriptors.report.UsbStrings;
+
+/**
+ * @hide
+ * A class that just walks the descriptors and does a hex dump of the contained values.
+ * Usefull as a debugging tool.
+ */
+public class UsbBinaryParser {
+    private static final String TAG = "UsbBinaryParser";
+    private static final boolean LOGGING = false;
+
+    private void dumpDescriptor(ByteStream stream, int length, byte type, StringBuilder builder) {
+
+        // Log
+        if (LOGGING) {
+            Log.i(TAG, "l:" + length + " t:" + Integer.toHexString(type) + " "
+                    + UsbStrings.getDescriptorName(type));
+            StringBuilder sb = new StringBuilder();
+            for (int index = 2; index < length; index++) {
+                sb.append("0x" + Integer.toHexString(stream.getByte() & 0xFF) + " ");
+            }
+            Log.i(TAG, sb.toString());
+        } else {
+            // Screen Dump
+            builder.append("<p>");
+            builder.append("<b> l:" + length
+                    + " t:0x" + Integer.toHexString(type) + " "
+                    + UsbStrings.getDescriptorName(type) + "</b><br>");
+            for (int index = 2; index < length; index++) {
+                builder.append("0x" + Integer.toHexString(stream.getByte() & 0xFF) + " ");
+            }
+            builder.append("</p>");
+        }
+    }
+
+    /**
+     * Walk through descriptor stream and generate an HTML text report of the contents.
+     * TODO: This should be done in the model of UsbDescriptorsParser/Reporter model.
+     */
+    public void parseDescriptors(UsbDeviceConnection connection, byte[] descriptors,
+                                 StringBuilder builder) {
+
+        builder.append("<tt>");
+        ByteStream stream = new ByteStream(descriptors);
+        while (stream.available() > 0) {
+            int length = (int) stream.getByte() & 0x000000FF;
+            byte type = stream.getByte();
+            dumpDescriptor(stream, length, type, builder);
+        }
+        builder.append("</tt>");
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java
new file mode 100644
index 0000000..8ae6d0f
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An USB Config Descriptor.
+ * see usb11.pdf section 9.6.2
+ */
+public class UsbConfigDescriptor extends UsbDescriptor {
+    private static final String TAG = "Config";
+
+    private int mTotalLength;   // 2:2 Total length in bytes of data returned
+    private byte mNumInterfaces; // 4:1 Number of Interfaces
+    private byte mConfigValue;  // 5:1 Value to use as an argument to select this configuration
+    private byte mConfigIndex;  // 6:1 Index of String Descriptor describing this configuration
+    private byte mAttribs;      // 7:1 D7 Reserved, set to 1. (USB 1.0 Bus Powered)
+                                //     D6 Self Powered
+                                //     D5 Remote Wakeup
+                                //     D4..0 Reserved, set to 0.
+    private byte mMaxPower;     // 8:1 Maximum Power Consumption in 2mA units
+
+    UsbConfigDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    public int getTotalLength() {
+        return mTotalLength;
+    }
+
+    public byte getNumInterfaces() {
+        return mNumInterfaces;
+    }
+
+    public byte getConfigValue() {
+        return mConfigValue;
+    }
+
+    public byte getConfigIndex() {
+        return mConfigIndex;
+    }
+
+    public byte getAttribs() {
+        return mAttribs;
+    }
+
+    public byte getMaxPower() {
+        return mMaxPower;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mTotalLength = stream.unpackUsbWord();
+        mNumInterfaces = stream.getByte();
+        mConfigValue = stream.getByte();
+        mConfigIndex = stream.getByte();
+        mAttribs = stream.getByte();
+        mMaxPower = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java
new file mode 100644
index 0000000..63b2d7f
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java
@@ -0,0 +1,223 @@
+/*
+ * 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.usb.descriptors;
+
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDeviceConnection;
+import android.util.Log;
+
+/*
+ * Some notes about UsbDescriptor and its subclasses.
+ *
+ * It is assumed that the user of the UsbDescriptorParser knows what they are doing
+ * so NO PROTECTION is implemented against "improper" use. Such uses are specifically:
+ * allocating a UsbDescriptor (subclass) object outside of the context of parsing/reading
+ * a rawdescriptor stream and perhaps accessing fields which have not been inialized (by
+ * parsing/reading or course).
+ */
+
+/**
+ * @hide
+ * Common superclass for all USB Descriptors.
+ */
+public abstract class UsbDescriptor {
+    private static final String TAG = "Descriptor";
+
+    protected final int mLength;    // 0:1 bLength Number Size of the Descriptor in Bytes (18 bytes)
+                                    // we store this as an int because Java bytes are SIGNED.
+    protected final byte mType;     // 1:1 bDescriptorType Constant Device Descriptor (0x01)
+
+    private byte[] mRawData;
+
+    private static final int SIZE_STRINGBUFFER = 256;
+    private static byte[] sStringBuffer = new byte[SIZE_STRINGBUFFER];
+
+    // Status
+    public static final int STATUS_UNPARSED         = 0;
+    public static final int STATUS_PARSED_OK        = 1;
+    public static final int STATUS_PARSED_UNDERRUN  = 2;
+    public static final int STATUS_PARSED_OVERRUN   = 3;
+    private int mStatus = STATUS_UNPARSED;
+
+    private static String[] sStatusStrings = {
+            "UNPARSED", "PARSED - OK", "PARSED - UNDERRUN", "PARSED - OVERRUN"};
+
+    // Descriptor Type IDs
+    public static final byte DESCRIPTORTYPE_DEVICE = 0x01;            // 1
+    public static final byte DESCRIPTORTYPE_CONFIG = 0x02;            // 2
+    public static final byte DESCRIPTORTYPE_STRING = 0x03;            // 3
+    public static final byte DESCRIPTORTYPE_INTERFACE = 0x04;         // 4
+    public static final byte DESCRIPTORTYPE_ENDPOINT = 0x05;          // 5
+    public static final byte DESCRIPTORTYPE_INTERFACEASSOC = 0x0B;    // 11
+    public static final byte DESCRIPTORTYPE_BOS = 0x0F;               // 15
+    public static final byte DESCRIPTORTYPE_CAPABILITY = 0x10;        // 16
+
+    public static final byte DESCRIPTORTYPE_HID = 0x21;                // 33
+    public static final byte DESCRIPTORTYPE_REPORT = 0x22;             // 34
+    public static final byte DESCRIPTORTYPE_PHYSICAL = 0x23;           // 35
+    public static final byte DESCRIPTORTYPE_AUDIO_INTERFACE = 0x24;    // 36
+    public static final byte DESCRIPTORTYPE_AUDIO_ENDPOINT = 0x25;     // 37
+    public static final byte DESCRIPTORTYPE_HUB = 0x29;                // 41
+    public static final byte DESCRIPTORTYPE_SUPERSPEED_HUB = 0x2A;     // 42
+    public static final byte DESCRIPTORTYPE_ENDPOINT_COMPANION = 0x30; // 48
+
+    // Class IDs
+    public static final byte CLASSID_DEVICE  =      0x00;
+    public static final byte CLASSID_AUDIO =        0x01;
+    public static final byte CLASSID_COM =          0x02;
+    public static final byte CLASSID_HID =          0x03;
+    // public static final byte CLASSID_??? =       0x04;
+    public static final byte CLASSID_PHYSICAL =     0x05;
+    public static final byte CLASSID_IMAGE =        0x06;
+    public static final byte CLASSID_PRINTER =      0x07;
+    public static final byte CLASSID_STORAGE =      0x08;
+    public static final byte CLASSID_HUB =          0x09;
+    public static final byte CLASSID_CDC_CONTROL =  0x0A;
+    public static final byte CLASSID_SMART_CARD =   0x0B;
+    //public static final byte CLASSID_??? =        0x0C;
+    public static final byte CLASSID_SECURITY =     0x0D;
+    public static final byte CLASSID_VIDEO =        0x0E;
+    public static final byte CLASSID_HEALTHCARE =   0x0F;
+    public static final byte CLASSID_AUDIOVIDEO =   0x10;
+    public static final byte CLASSID_BILLBOARD =    0x11;
+    public static final byte CLASSID_TYPECBRIDGE =  0x12;
+    public static final byte CLASSID_DIAGNOSTIC =   (byte) 0xDC;
+    public static final byte CLASSID_WIRELESS =     (byte) 0xE0;
+    public static final byte CLASSID_MISC =         (byte) 0xEF;
+    public static final byte CLASSID_APPSPECIFIC =  (byte) 0xFE;
+    public static final byte CLASSID_VENDSPECIFIC = (byte) 0xFF;
+
+    // Audio Subclass codes
+    public static final byte AUDIO_SUBCLASS_UNDEFINED   = 0x00;
+    public static final byte AUDIO_AUDIOCONTROL         = 0x01;
+    public static final byte AUDIO_AUDIOSTREAMING       = 0x02;
+    public static final byte AUDIO_MIDISTREAMING        = 0x03;
+
+    // Request IDs
+    public static final int REQUEST_GET_STATUS         = 0x00;
+    public static final int REQUEST_CLEAR_FEATURE      = 0x01;
+    public static final int REQUEST_SET_FEATURE        = 0x03;
+    public static final int REQUEST_GET_ADDRESS        = 0x05;
+    public static final int REQUEST_GET_DESCRIPTOR     = 0x06;
+    public static final int REQUEST_SET_DESCRIPTOR     = 0x07;
+    public static final int REQUEST_GET_CONFIGURATION  = 0x08;
+    public static final int REQUEST_SET_CONFIGURATION  = 0x09;
+
+    /**
+     * @throws IllegalArgumentException
+     */
+    UsbDescriptor(int length, byte type) {
+        // a descriptor has at least a length byte and type byte
+        // one could imagine an empty one otherwise
+        if (length < 2) {
+            // huh?
+            throw new IllegalArgumentException();
+        }
+
+        mLength = length;
+        mType = type;
+    }
+
+    public int getLength() {
+        return mLength;
+    }
+
+    public byte getType() {
+        return mType;
+    }
+
+    public int getStatus() {
+        return mStatus;
+    }
+
+    public void setStatus(int status) {
+        mStatus = status;
+    }
+
+    public String getStatusString() {
+        return sStatusStrings[mStatus];
+    }
+
+    public byte[] getRawData() {
+        return mRawData;
+    }
+
+    /**
+     * Called by the parser for any necessary cleanup.
+     */
+    public void postParse(ByteStream stream) {
+        // Status
+        int bytesRead = stream.getReadCount();
+        if (bytesRead < mLength) {
+            // Too cold...
+            stream.advance(mLength - bytesRead);
+            mStatus = STATUS_PARSED_UNDERRUN;
+            Log.w(TAG, "UNDERRUN t:0x" + Integer.toHexString(mType)
+                    + " r:" + bytesRead + " < l:" + mLength);
+        } else if (bytesRead > mLength) {
+            // Too hot...
+            stream.reverse(bytesRead - mLength);
+            mStatus = STATUS_PARSED_OVERRUN;
+            Log.w(TAG, "OVERRRUN t:0x" + Integer.toHexString(mType)
+                    + " r:" + bytesRead + " > l:" + mLength);
+        } else {
+            // Just right!
+            mStatus = STATUS_PARSED_OK;
+        }
+    }
+
+    /**
+     * Reads data fields from specified raw-data stream.
+     */
+    public int parseRawDescriptors(ByteStream stream) {
+        int numRead = stream.getReadCount();
+        int dataLen = mLength - numRead;
+        if (dataLen > 0) {
+            mRawData = new byte[dataLen];
+            for (int index = 0; index < dataLen; index++) {
+                mRawData[index] = stream.getByte();
+            }
+        }
+        return mLength;
+    }
+
+    /**
+     * Gets a string for the specified index from the USB Device's string descriptors.
+     */
+    public static String getUsbDescriptorString(UsbDeviceConnection connection, byte strIndex) {
+        String usbStr = "";
+        if (strIndex != 0) {
+            try {
+                int rdo = connection.controlTransfer(
+                        UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_STANDARD,
+                        REQUEST_GET_DESCRIPTOR,
+                        (DESCRIPTORTYPE_STRING << 8) | strIndex,
+                        0,
+                        sStringBuffer,
+                        0xFF,
+                        0);
+                if (rdo >= 0) {
+                    usbStr = new String(sStringBuffer, 2, rdo - 2, "UTF-16LE");
+                } else {
+                    usbStr = "?";
+                }
+            } catch (Exception e) {
+                Log.e(TAG, "Can not communicate with USB device", e);
+            }
+        }
+        return usbStr;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
new file mode 100644
index 0000000..d4a0ac4
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
@@ -0,0 +1,387 @@
+/*
+ * 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.usb.descriptors;
+
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * @hide
+ * Class for parsing a binary stream of USB Descriptors.
+ */
+public class UsbDescriptorParser {
+    private static final String TAG = "DescriptorParser";
+
+    // Descriptor Objects
+    private ArrayList<UsbDescriptor> mDescriptors = new ArrayList<UsbDescriptor>();
+
+    private UsbDeviceDescriptor mDeviceDescriptor;
+    private UsbInterfaceDescriptor mCurInterfaceDescriptor;
+
+    public UsbDescriptorParser() {}
+
+    /**
+     * The probability (as returned by getHeadsetProbability() at which we conclude
+     * the peripheral is a headset.
+     */
+    private static final float IN_HEADSET_TRIGGER = 0.75f;
+    private static final float OUT_HEADSET_TRIGGER = 0.75f;
+
+    private UsbDescriptor allocDescriptor(ByteStream stream) {
+        stream.resetReadCount();
+
+        int length = (int) stream.getByte() & 0x000000FF;
+        byte type = stream.getByte();
+
+        UsbDescriptor descriptor = null;
+        switch (type) {
+            /*
+             * Standard
+             */
+            case UsbDescriptor.DESCRIPTORTYPE_DEVICE:
+                descriptor = mDeviceDescriptor = new UsbDeviceDescriptor(length, type);
+                break;
+
+            case UsbDescriptor.DESCRIPTORTYPE_CONFIG:
+                descriptor = new UsbConfigDescriptor(length, type);
+                break;
+
+            case UsbDescriptor.DESCRIPTORTYPE_INTERFACE:
+                descriptor = mCurInterfaceDescriptor = new UsbInterfaceDescriptor(length, type);
+                break;
+
+            case UsbDescriptor.DESCRIPTORTYPE_ENDPOINT:
+                descriptor = new UsbEndpointDescriptor(length, type);
+                break;
+
+            /*
+             * HID
+             */
+            case UsbDescriptor.DESCRIPTORTYPE_HID:
+                descriptor = new UsbHIDDescriptor(length, type);
+                break;
+
+            /*
+             * Other
+             */
+            case UsbDescriptor.DESCRIPTORTYPE_INTERFACEASSOC:
+                descriptor = new UsbInterfaceAssoc(length, type);
+                break;
+
+            /*
+             * Audio Class Specific
+             */
+            case UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE:
+                descriptor = UsbACInterface.allocDescriptor(this, stream, length, type);
+                break;
+
+            case UsbDescriptor.DESCRIPTORTYPE_AUDIO_ENDPOINT:
+                descriptor = UsbACEndpoint.allocDescriptor(this, length, type);
+                break;
+
+            default:
+                break;
+        }
+
+        if (descriptor == null) {
+            // Unknown Descriptor
+            Log.i(TAG, "Unknown Descriptor len:" + length + " type:0x"
+                    + Integer.toHexString(type));
+            descriptor = new UsbUnknown(length, type);
+        }
+
+        return descriptor;
+    }
+
+    public UsbDeviceDescriptor getDeviceDescriptor() {
+        return mDeviceDescriptor;
+    }
+
+    public UsbInterfaceDescriptor getCurInterface() {
+        return mCurInterfaceDescriptor;
+    }
+
+    /**
+     * @hide
+     */
+    public void parseDescriptors(byte[] descriptors) {
+        mDescriptors.clear();
+
+        ByteStream stream = new ByteStream(descriptors);
+        while (stream.available() > 0) {
+            UsbDescriptor descriptor = null;
+            try {
+                descriptor = allocDescriptor(stream);
+            } catch (Exception ex) {
+                Log.e(TAG, "Exception allocating USB descriptor.", ex);
+            }
+
+            if (descriptor != null) {
+                // Parse
+                try {
+                    descriptor.parseRawDescriptors(stream);
+
+                    // Its OK to add the invalid descriptor as the postParse()
+                    // routine will mark it as invalid.
+                    mDescriptors.add(descriptor);
+
+                    // Clean up
+                    descriptor.postParse(stream);
+                } catch (Exception ex) {
+                    Log.e(TAG, "Exception parsing USB descriptors.", ex);
+                }
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public boolean parseDevice(String deviceAddr) {
+        byte[] rawDescriptors = getRawDescriptors(deviceAddr);
+        if (rawDescriptors != null) {
+            parseDescriptors(rawDescriptors);
+            return true;
+        }
+        return false;
+    }
+
+    private native byte[] getRawDescriptors(String deviceAddr);
+
+    public int getParsingSpec() {
+        return mDeviceDescriptor != null ? mDeviceDescriptor.getSpec() : 0;
+    }
+
+    public ArrayList<UsbDescriptor> getDescriptors() {
+        return mDescriptors;
+    }
+
+    /**
+     * @hide
+     */
+    public ArrayList<UsbDescriptor> getDescriptors(byte type) {
+        ArrayList<UsbDescriptor> list = new ArrayList<UsbDescriptor>();
+        for (UsbDescriptor descriptor : mDescriptors) {
+            if (descriptor.getType() == type) {
+                list.add(descriptor);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * @hide
+     */
+    public ArrayList<UsbDescriptor> getInterfaceDescriptorsForClass(byte usbClass) {
+        ArrayList<UsbDescriptor> list = new ArrayList<UsbDescriptor>();
+        for (UsbDescriptor descriptor : mDescriptors) {
+            // ensure that this isn't an unrecognized DESCRIPTORTYPE_INTERFACE
+            if (descriptor.getType() == UsbDescriptor.DESCRIPTORTYPE_INTERFACE) {
+                if (descriptor instanceof UsbInterfaceDescriptor) {
+                    UsbInterfaceDescriptor intrDesc = (UsbInterfaceDescriptor) descriptor;
+                    if (intrDesc.getUsbClass() == usbClass) {
+                        list.add(descriptor);
+                    }
+                } else {
+                    Log.w(TAG, "Unrecognized Interface l:" + descriptor.getLength()
+                            + " t:0x" + Integer.toHexString(descriptor.getType()));
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * @hide
+     */
+    public ArrayList<UsbDescriptor> getACInterfaceDescriptors(byte subtype, byte subclass) {
+        ArrayList<UsbDescriptor> list = new ArrayList<UsbDescriptor>();
+        for (UsbDescriptor descriptor : mDescriptors) {
+            if (descriptor.getType() == UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE) {
+                // ensure that this isn't an unrecognized DESCRIPTORTYPE_AUDIO_INTERFACE
+                if (descriptor instanceof UsbACInterface) {
+                    UsbACInterface acDescriptor = (UsbACInterface) descriptor;
+                    if (acDescriptor.getSubtype() == subtype
+                            && acDescriptor.getSubclass() == subclass) {
+                        list.add(descriptor);
+                    }
+                } else {
+                    Log.w(TAG, "Unrecognized Audio Interface l:" + descriptor.getLength()
+                            + " t:0x" + Integer.toHexString(descriptor.getType()));
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean hasHIDDescriptor() {
+        ArrayList<UsbDescriptor> descriptors =
+                getInterfaceDescriptorsForClass(UsbDescriptor.CLASSID_HID);
+        return !descriptors.isEmpty();
+    }
+
+    /**
+     * @hide
+     */
+    public boolean hasMIDIInterface() {
+        ArrayList<UsbDescriptor> descriptors =
+                getInterfaceDescriptorsForClass(UsbDescriptor.CLASSID_AUDIO);
+        for (UsbDescriptor descriptor : descriptors) {
+            // enusure that this isn't an unrecognized interface descriptor
+            if (descriptor instanceof UsbInterfaceDescriptor) {
+                UsbInterfaceDescriptor interfaceDescr = (UsbInterfaceDescriptor) descriptor;
+                if (interfaceDescr.getUsbSubclass() == UsbDescriptor.AUDIO_MIDISTREAMING) {
+                    return true;
+                }
+            } else {
+                Log.w(TAG, "Undefined Audio Class Interface l:" + descriptor.getLength()
+                        + " t:0x" + Integer.toHexString(descriptor.getType()));
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    public float getInputHeadsetProbability() {
+        if (hasMIDIInterface()) {
+            return 0.0f;
+        }
+
+        float probability = 0.0f;
+        ArrayList<UsbDescriptor> acDescriptors;
+
+        // Look for a microphone
+        boolean hasMic = false;
+        acDescriptors = getACInterfaceDescriptors(UsbACInterface.ACI_INPUT_TERMINAL,
+                UsbACInterface.AUDIO_AUDIOCONTROL);
+        for (UsbDescriptor descriptor : acDescriptors) {
+            if (descriptor instanceof UsbACInputTerminal) {
+                UsbACInputTerminal inDescr = (UsbACInputTerminal) descriptor;
+                if (inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_IN_MIC
+                        || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET
+                        || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_UNDEFINED
+                        || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_EXTERN_LINE) {
+                    hasMic = true;
+                    break;
+                }
+            } else {
+                Log.w(TAG, "Undefined Audio Input terminal l:" + descriptor.getLength()
+                        + " t:0x" + Integer.toHexString(descriptor.getType()));
+            }
+        }
+
+        // Look for a "speaker"
+        boolean hasSpeaker = false;
+        acDescriptors =
+                getACInterfaceDescriptors(UsbACInterface.ACI_OUTPUT_TERMINAL,
+                        UsbACInterface.AUDIO_AUDIOCONTROL);
+        for (UsbDescriptor descriptor : acDescriptors) {
+            if (descriptor instanceof UsbACOutputTerminal) {
+                UsbACOutputTerminal outDescr = (UsbACOutputTerminal) descriptor;
+                if (outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_OUT_SPEAKER
+                        || outDescr.getTerminalType()
+                            == UsbTerminalTypes.TERMINAL_OUT_HEADPHONES
+                        || outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET) {
+                    hasSpeaker = true;
+                    break;
+                }
+            } else {
+                Log.w(TAG, "Undefined Audio Output terminal l:" + descriptor.getLength()
+                        + " t:0x" + Integer.toHexString(descriptor.getType()));
+            }
+        }
+
+        if (hasMic && hasSpeaker) {
+            probability += 0.75f;
+        }
+
+        if (hasMic && hasHIDDescriptor()) {
+            probability += 0.25f;
+        }
+
+        return probability;
+    }
+
+    /**
+     * getInputHeadsetProbability() reports a probability of a USB Input peripheral being a
+     * headset. The probability range is between 0.0f (definitely NOT a headset) and
+     * 1.0f (definitely IS a headset). A probability of 0.75f seems sufficient
+     * to count on the peripheral being a headset.
+     */
+    public boolean isInputHeadset() {
+        return getInputHeadsetProbability() >= IN_HEADSET_TRIGGER;
+    }
+
+    /**
+     * @hide
+     */
+    public float getOutputHeadsetProbability() {
+        if (hasMIDIInterface()) {
+            return 0.0f;
+        }
+
+        float probability = 0.0f;
+        ArrayList<UsbDescriptor> acDescriptors;
+
+        // Look for a "speaker"
+        boolean hasSpeaker = false;
+        acDescriptors =
+                getACInterfaceDescriptors(UsbACInterface.ACI_OUTPUT_TERMINAL,
+                        UsbACInterface.AUDIO_AUDIOCONTROL);
+        for (UsbDescriptor descriptor : acDescriptors) {
+            if (descriptor instanceof UsbACOutputTerminal) {
+                UsbACOutputTerminal outDescr = (UsbACOutputTerminal) descriptor;
+                if (outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_OUT_SPEAKER
+                        || outDescr.getTerminalType()
+                            == UsbTerminalTypes.TERMINAL_OUT_HEADPHONES
+                        || outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET) {
+                    hasSpeaker = true;
+                    break;
+                }
+            } else {
+                Log.w(TAG, "Undefined Audio Output terminal l:" + descriptor.getLength()
+                        + " t:0x" + Integer.toHexString(descriptor.getType()));
+            }
+        }
+
+        if (hasSpeaker) {
+            probability += 0.75f;
+        }
+
+        if (hasSpeaker && hasHIDDescriptor()) {
+            probability += 0.25f;
+        }
+
+        return probability;
+    }
+
+    /**
+     * getOutputHeadsetProbability() reports a probability of a USB Output peripheral being a
+     * headset. The probability range is between 0.0f (definitely NOT a headset) and
+     * 1.0f (definitely IS a headset). A probability of 0.75f seems sufficient
+     * to count on the peripheral being a headset.
+     */
+    public boolean isOutputHeadset() {
+        return getOutputHeadsetProbability() >= OUT_HEADSET_TRIGGER;
+    }
+
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
new file mode 100644
index 0000000..90848ca
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
@@ -0,0 +1,109 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * A USB Device Descriptor.
+ * see usb11.pdf section 9.6.1
+ */
+/* public */ public class UsbDeviceDescriptor extends UsbDescriptor {
+    private static final String TAG = "Device";
+
+    private int mSpec;          // 2:2 bcdUSB 2 BCD USB Specification Number - BCD
+    private byte mDevClass;     // 4:1 class code
+    private byte mDevSubClass;  // 5:1 subclass code
+    private byte mProtocol;     // 6:1 protocol
+    private byte mPacketSize;   // 7:1 Maximum Packet Size for Zero Endpoint.
+                                // Valid Sizes are 8, 16, 32, 64
+    private int mVendorID;      // 8:2 vendor ID
+    private int mProductID;     // 10:2 product ID
+    private int mDeviceRelease; // 12:2 Device Release number - BCD
+    private byte mMfgIndex;     // 14:1 Index of Manufacturer String Descriptor
+    private byte mProductIndex; // 15:1 Index of Product String Descriptor
+    private byte mSerialNum;    // 16:1 Index of Serial Number String Descriptor
+    private byte mNumConfigs;   // 17:1 Number of Possible Configurations
+
+    UsbDeviceDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    public int getSpec() {
+        return mSpec;
+    }
+
+    public byte getDevClass() {
+        return mDevClass;
+    }
+
+    public byte getDevSubClass() {
+        return mDevSubClass;
+    }
+
+    public byte getProtocol() {
+        return mProtocol;
+    }
+
+    public byte getPacketSize() {
+        return mPacketSize;
+    }
+
+    public int getVendorID() {
+        return mVendorID;
+    }
+
+    public int getProductID() {
+        return mProductID;
+    }
+
+    public int getDeviceRelease() {
+        return mDeviceRelease;
+    }
+
+    public byte getMfgIndex() {
+        return mMfgIndex;
+    }
+
+    public byte getProductIndex() {
+        return mProductIndex;
+    }
+
+    public byte getSerialNum() {
+        return mSerialNum;
+    }
+
+    public byte getNumConfigs() {
+        return mNumConfigs;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mSpec = stream.unpackUsbWord();
+        mDevClass = stream.getByte();
+        mDevSubClass = stream.getByte();
+        mProtocol = stream.getByte();
+        mPacketSize = stream.getByte();
+        mVendorID = stream.unpackUsbWord();
+        mProductID = stream.unpackUsbWord();
+        mDeviceRelease = stream.unpackUsbWord();
+        mMfgIndex = stream.getByte();
+        mProductIndex = stream.getByte();
+        mSerialNum = stream.getByte();
+        mNumConfigs = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java
new file mode 100644
index 0000000..def6700
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java
@@ -0,0 +1,117 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * A Usb Endpoint Descriptor.
+ * see usb11.pdf section 9.6.4
+ */
+public class UsbEndpointDescriptor extends UsbDescriptor {
+    private static final String TAG = "EndPoint";
+
+    public static final byte MASK_ENDPOINT_ADDRESS     = 0b0001111;
+    public static final byte MASK_ENDPOINT_DIRECTION   = (byte) 0b10000000;
+    public static final byte DIRECTION_OUTPUT          = 0x00;
+    public static final byte DIRECTION_INPUT           = (byte) 0x80;
+
+    public static final byte MASK_ATTRIBS_TRANSTYPE = 0b00000011;
+    public static final byte TRANSTYPE_CONTROL     = 0x00;
+    public static final byte TRANSTYPE_ISO         = 0x01;
+    public static final byte TRANSTYPE_BULK        = 0x02;
+    public static final byte TRANSTYPE_INTERRUPT   = 0x03;
+
+    public static final byte MASK_ATTRIBS_SYNCTYPE  = 0b00001100;
+    public static final byte SYNCTYPE_NONE          = 0b00000000;
+    public static final byte SYNCTYPE_ASYNC         = 0b00000100;
+    public static final byte SYNCTYPE_ADAPTSYNC     = 0b00001000;
+    public static final byte SYNCTYPE_RESERVED      = 0b00001100;
+
+    public static final byte MASK_ATTRIBS_USEAGE    = 0b00110000;
+    public static final byte USEAGE_DATA            = 0b00000000;
+    public static final byte USEAGE_FEEDBACK        = 0b00010000;
+    public static final byte USEAGE_EXPLICIT        = 0b00100000;
+    public static final byte USEAGE_RESERVED        = 0b00110000;
+
+    private byte mEndpointAddress;  // 2:1 Endpoint Address
+                                    // Bits 0..3b Endpoint Number.
+                                    // Bits 4..6b Reserved. Set to Zero
+                                    // Bits 7 Direction 0 = Out, 1 = In
+                                    // (Ignored for Control Endpoints)
+    private byte mAttributes;   // 3:1 Various flags
+                                // Bits 0..1 Transfer Type:
+                                //     00 = Control, 01 = Isochronous, 10 = Bulk, 11 = Interrupt
+                                // Bits 2..7 are reserved. If Isochronous endpoint,
+                                // Bits 3..2 = Synchronisation Type (Iso Mode)
+                                //  00 = No Synchonisation
+                                //  01 = Asynchronous
+                                //  10 = Adaptive
+                                //  11 = Synchronous
+                                // Bits 5..4 = Usage Type (Iso Mode)
+                                //  00: Data Endpoint
+                                //  01:Feedback Endpoint 10
+                                //  Explicit Feedback Data Endpoint
+                                //  11: Reserved
+    private int mPacketSize;    // 4:2 Maximum Packet Size this endpoint is capable of
+                                // sending or receiving
+    private byte mInterval;     // 6:1 Interval for polling endpoint data transfers. Value in
+                                // frame counts.
+                                // Ignored for Bulk & Control Endpoints. Isochronous must equal
+                                // 1 and field may range from 1 to 255 for interrupt endpoints.
+    private byte mRefresh;
+    private byte mSyncAddress;
+
+    public UsbEndpointDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    public byte getEndpointAddress() {
+        return mEndpointAddress;
+    }
+
+    public byte getAttributes() {
+        return mAttributes;
+    }
+
+    public int getPacketSize() {
+        return mPacketSize;
+    }
+
+    public byte getInterval() {
+        return mInterval;
+    }
+
+    public byte getRefresh() {
+        return mRefresh;
+    }
+
+    public byte getSyncAddress() {
+        return mSyncAddress;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mEndpointAddress = stream.getByte();
+        mAttributes = stream.getByte();
+        mPacketSize = stream.unpackUsbWord();
+        mInterval = stream.getByte();
+        if (mLength == 9) {
+            mRefresh = stream.getByte();
+            mSyncAddress = stream.getByte();
+        }
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbHIDDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbHIDDescriptor.java
new file mode 100644
index 0000000..56c07ec
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbHIDDescriptor.java
@@ -0,0 +1,70 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * A USB HID (Human Interface Descriptor).
+ * see HID1_11.pdf - 6.2.1
+ */
+public class UsbHIDDescriptor extends UsbDescriptor {
+    private static final String TAG = "HID";
+
+    private int mRelease;           // 2:2 the HID Class Specification release.
+    private byte mCountryCode;      // 4:1 country code of the localized hardware.
+    private byte mNumDescriptors;   // number of descriptors (always at least one
+                                    // i.e. Report descriptor.)
+    private byte mDescriptorType;   // 6:1 type of class descriptor.
+                                    // See Section 7.1.2: Set_Descriptor
+                                    // Request for a table of class descriptor constants.
+    private int mDescriptorLen;     // 7:2 Numeric expression that is the total size of
+                                    // the Report descriptor.
+
+    public UsbHIDDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    public int getRelease() {
+        return mRelease;
+    }
+
+    public byte getCountryCode() {
+        return mCountryCode;
+    }
+
+    public byte getNumDescriptors() {
+        return mNumDescriptors;
+    }
+
+    public byte getDescriptorType() {
+        return mDescriptorType;
+    }
+
+    public int getDescriptorLen() {
+        return mDescriptorLen;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mRelease = stream.unpackUsbWord();
+        mCountryCode = stream.getByte();
+        mNumDescriptors = stream.getByte();
+        mDescriptorType = stream.getByte();
+        mDescriptorLen = stream.unpackUsbWord();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceAssoc.java b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceAssoc.java
new file mode 100644
index 0000000..4b18a01
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceAssoc.java
@@ -0,0 +1,73 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * A USB Interface Association Descriptor.
+ * found this one here: http://www.usb.org/developers/docs/whitepapers/iadclasscode_r10.pdf
+ * also: https://msdn.microsoft.com/en-us/library/windows/hardware/ff540054(v=vs.85).aspx
+ */
+public class UsbInterfaceAssoc extends UsbDescriptor {
+    private static final String TAG = "InterfaceAssoc";
+
+    private byte mFirstInterface;
+    private byte mInterfaceCount;
+    private byte mFunctionClass;
+    private byte mFunctionSubClass;
+    private byte mFunctionProtocol;
+    private byte mFunction;
+
+    public UsbInterfaceAssoc(int length, byte type) {
+        super(length, type);
+    }
+
+    public byte getFirstInterface() {
+        return mFirstInterface;
+    }
+
+    public byte getInterfaceCount() {
+        return mInterfaceCount;
+    }
+
+    public byte getFunctionClass() {
+        return mFunctionClass;
+    }
+
+    public byte getFunctionSubClass() {
+        return mFunctionSubClass;
+    }
+
+    public byte getFunctionProtocol() {
+        return mFunctionProtocol;
+    }
+
+    public byte getFunction() {
+        return mFunction;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mFirstInterface = stream.getByte();
+        mInterfaceCount = stream.getByte();
+        mFunctionClass = stream.getByte();
+        mFunctionSubClass = stream.getByte();
+        mFunctionProtocol = stream.getByte();
+        mFunction = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java
new file mode 100644
index 0000000..21b5e0c
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java
@@ -0,0 +1,78 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * A common super-class for all USB Interface Descritor subtypes.
+ * see usb11.pdf section 9.6.3
+ */
+public class UsbInterfaceDescriptor extends UsbDescriptor {
+    private static final String TAG = "Interface";
+
+    protected byte mInterfaceNumber;  // 2:1 Number of Interface
+    protected byte mAlternateSetting; // 3:1 Value used to select alternative setting
+    protected byte mNumEndpoints;     // 4:1 Number of Endpoints used for this interface
+    protected byte mUsbClass;         // 5:1 Class Code
+    protected byte mUsbSubclass;      // 6:1 Subclass Code
+    protected byte mProtocol;         // 7:1 Protocol Code
+    protected byte mDescrIndex;       // 8:1 Index of String Descriptor Describing this interface
+
+    UsbInterfaceDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mInterfaceNumber = stream.getByte();
+        mAlternateSetting = stream.getByte();
+        mNumEndpoints = stream.getByte();
+        mUsbClass = stream.getByte();
+        mUsbSubclass = stream.getByte();
+        mProtocol = stream.getByte();
+        mDescrIndex = stream.getByte();
+
+        return mLength;
+    }
+
+    public byte getInterfaceNumber() {
+        return mInterfaceNumber;
+    }
+
+    public byte getAlternateSetting() {
+        return mAlternateSetting;
+    }
+
+    public byte getNumEndpoints() {
+        return mNumEndpoints;
+    }
+
+    public byte getUsbClass() {
+        return mUsbClass;
+    }
+
+    public byte getUsbSubclass() {
+        return mUsbSubclass;
+    }
+
+    public byte getProtocol() {
+        return mProtocol;
+    }
+
+    public byte getDescrIndex() {
+        return mDescrIndex;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiHeader.java b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiHeader.java
new file mode 100644
index 0000000..4452b23
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiHeader.java
@@ -0,0 +1,36 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Midi Streaming Interface.
+ * see midi10.pdf section 6.1.2.1
+ */
+public class UsbMSMidiHeader extends UsbACInterface {
+    private static final String TAG = "MSMidiHeader";
+
+    public UsbMSMidiHeader(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        // TODO - read data memebers
+        stream.advance(mLength - stream.getReadCount());
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiInputJack.java b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiInputJack.java
new file mode 100644
index 0000000..2d33ba7
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiInputJack.java
@@ -0,0 +1,36 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Midi Input Jack Interface.
+ * see midi10.pdf section B.4.3
+ */
+public class UsbMSMidiInputJack extends UsbACInterface {
+    private static final String TAG = "MSMidiInputJack";
+
+    UsbMSMidiInputJack(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        // TODO - read data memebers
+        stream.advance(mLength - stream.getReadCount());
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiOutputJack.java b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiOutputJack.java
new file mode 100644
index 0000000..bd2dc11
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiOutputJack.java
@@ -0,0 +1,36 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Midi Output Jack Interface.
+ * see midi10.pdf section B.4.4
+ */
+public class UsbMSMidiOutputJack extends UsbACInterface {
+    private static final String TAG = "MSMidiOutputJack";
+
+    public UsbMSMidiOutputJack(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        // TODO - read data memebers
+        stream.advance(mLength - stream.getReadCount());
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java b/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java
new file mode 100644
index 0000000..b521462
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java
@@ -0,0 +1,93 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * A class for decoding information in Terminal Descriptors.
+ * see termt10.pdf
+ */
+public class UsbTerminalTypes {
+    private static final String TAG = "TerminalTypes";
+
+    // USB
+    public static final int TERMINAL_USB_STREAMING   = 0x0101;
+
+    // Inputs
+    public static final int TERMINAL_IN_UNDEFINED    = 0x0200;
+    public static final int TERMINAL_IN_MIC          = 0x0201;
+    public static final int TERMINAL_IN_DESKTOP_MIC  = 0x0202;
+    public static final int TERMINAL_IN_PERSONAL_MIC = 0x0203;
+    public static final int TERMINAL_IN_OMNI_MIC     = 0x0204;
+    public static final int TERMINAL_IN_MIC_ARRAY    = 0x0205;
+    public static final int TERMINAL_IN_PROC_MIC_ARRAY = 0x0206;
+
+    // Outputs
+    public static final int TERMINAL_OUT_UNDEFINED       = 0x0300;
+    public static final int TERMINAL_OUT_SPEAKER         = 0x0301;
+    public static final int TERMINAL_OUT_HEADPHONES      = 0x0302;
+    public static final int TERMINAL_OUT_HEADMOUNTED     = 0x0303;
+    public static final int TERMINAL_OUT_DESKTOPSPEAKER  = 0x0304;
+    public static final int TERMINAL_OUT_ROOMSPEAKER     = 0x0305;
+    public static final int TERMINAL_OUT_COMSPEAKER      = 0x0306;
+    public static final int TERMINAL_OUT_LFSPEAKER       = 0x0307;
+
+    // Bi-directional
+    public static final int TERMINAL_BIDIR_UNDEFINED    = 0x0400;
+    public static final int TERMINAL_BIDIR_HANDSET      = 0x0401;
+    public static final int TERMINAL_BIDIR_HEADSET      = 0x0402;
+    public static final int TERMINAL_BIDIR_SKRPHONE     = 0x0403;
+    public static final int TERMINAL_BIDIR_SKRPHONE_SUPRESS = 0x0404;
+    public static final int TERMINAL_BIDIR_SKRPHONE_CANCEL = 0x0405;
+
+    // Telephony
+    public static final int TERMINAL_TELE_UNDEFINED     = 0x0500;
+    public static final int TERMINAL_TELE_PHONELINE     = 0x0501;
+    public static final int TERMINAL_TELE_PHONE         = 0x0502;
+    public static final int TERMINAL_TELE_DOWNLINEPHONE = 0x0503;
+
+    // External
+    public static final int TERMINAL_EXTERN_UNDEFINED   = 0x0600;
+    public static final int TERMINAL_EXTERN_ANALOG      = 0x0601;
+    public static final int TERMINAL_EXTERN_DIGITAL     = 0x0602;
+    public static final int TERMINAL_EXTERN_LINE        = 0x0603;
+    public static final int TERMINAL_EXTERN_LEGACY      = 0x0604;
+    public static final int TERMINAL_EXTERN_SPIDF       = 0x0605;
+    public static final int TERMINAL_EXTERN_1394DA      = 0x0606;
+    public static final int TERMINAL_EXTERN_1394DV      = 0x0607;
+
+    public static final int TERMINAL_EMBED_UNDEFINED    = 0x0700;
+    public static final int TERMINAL_EMBED_CALNOISE     = 0x0701;
+    public static final int TERMINAL_EMBED_EQNOISE      = 0x0702;
+    public static final int TERMINAL_EMBED_CDPLAYER     = 0x0703;
+    public static final int TERMINAL_EMBED_DAT          = 0x0704;
+    public static final int TERMINAL_EMBED_DCC          = 0x0705;
+    public static final int TERMINAL_EMBED_MINIDISK     = 0x0706;
+    public static final int TERMINAL_EMBED_ANALOGTAPE   = 0x0707;
+    public static final int TERMINAL_EMBED_PHONOGRAPH   = 0x0708;
+    public static final int TERMINAL_EMBED_VCRAUDIO     = 0x0709;
+    public static final int TERMINAL_EMBED_VIDDISKAUDIO = 0x070A;
+    public static final int TERMINAL_EMBED_DVDAUDIO     = 0x070B;
+    public static final int TERMINAL_EMBED_TVAUDIO      = 0x070C;
+    public static final int TERMINAL_EMBED_SATELLITEAUDIO = 0x070D;
+    public static final int TERMINAL_EMBED_CABLEAUDIO   = 0x070E;
+    public static final int TERMINAL_EMBED_DSSAUDIO     = 0x070F;
+    public static final int TERMINAL_EMBED_RADIOAUDIO   = 0x0710;
+    public static final int TERMINAL_EMBED_RADIOTRANSMITTER = 0x0711;
+    public static final int TERMINAL_EMBED_MULTITRACK   = 0x0712;
+    public static final int TERMINAL_EMBED_SYNTHESIZER  = 0x0713;
+
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbUnknown.java b/services/usb/java/com/android/server/usb/descriptors/UsbUnknown.java
new file mode 100644
index 0000000..a6fe8bb
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbUnknown.java
@@ -0,0 +1,28 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * A holder for any unrecognized descriptor encountered in the descriptor stream.
+ */
+public class UsbUnknown extends UsbDescriptor {
+    static final String TAG = "Unknown";
+
+    public UsbUnknown(int length, byte type) {
+        super(length, type);
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/report/HTMLReporter.java b/services/usb/java/com/android/server/usb/descriptors/report/HTMLReporter.java
new file mode 100644
index 0000000..c98789d
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/report/HTMLReporter.java
@@ -0,0 +1,572 @@
+/*
+ * 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.usb.descriptors.report;
+
+import android.hardware.usb.UsbDeviceConnection;
+
+import com.android.server.usb.descriptors.UsbACAudioControlEndpoint;
+import com.android.server.usb.descriptors.UsbACAudioStreamEndpoint;
+import com.android.server.usb.descriptors.UsbACFeatureUnit;
+import com.android.server.usb.descriptors.UsbACHeader;
+import com.android.server.usb.descriptors.UsbACInputTerminal;
+import com.android.server.usb.descriptors.UsbACInterface;
+import com.android.server.usb.descriptors.UsbACMidiEndpoint;
+import com.android.server.usb.descriptors.UsbACMixerUnit;
+import com.android.server.usb.descriptors.UsbACOutputTerminal;
+import com.android.server.usb.descriptors.UsbACSelectorUnit;
+import com.android.server.usb.descriptors.UsbACTerminal;
+import com.android.server.usb.descriptors.UsbASFormat;
+import com.android.server.usb.descriptors.UsbASFormatI;
+import com.android.server.usb.descriptors.UsbASFormatII;
+import com.android.server.usb.descriptors.UsbASGeneral;
+import com.android.server.usb.descriptors.UsbConfigDescriptor;
+import com.android.server.usb.descriptors.UsbDescriptor;
+import com.android.server.usb.descriptors.UsbDeviceDescriptor;
+import com.android.server.usb.descriptors.UsbEndpointDescriptor;
+import com.android.server.usb.descriptors.UsbHIDDescriptor;
+import com.android.server.usb.descriptors.UsbInterfaceAssoc;
+import com.android.server.usb.descriptors.UsbInterfaceDescriptor;
+import com.android.server.usb.descriptors.UsbMSMidiHeader;
+import com.android.server.usb.descriptors.UsbMSMidiInputJack;
+import com.android.server.usb.descriptors.UsbMSMidiOutputJack;
+import com.android.server.usb.descriptors.UsbUnknown;
+
+/**
+ * Implements the Reporter inteface to provide HTML reporting for UsbDescriptor subclasses.
+ */
+public class HTMLReporter implements Reporter {
+    private final StringBuilder mStringBuilder;
+    private final UsbDeviceConnection mConnection;
+
+    public HTMLReporter(StringBuilder stringBuilder, UsbDeviceConnection connection) {
+        mStringBuilder = stringBuilder;
+        mConnection = connection;
+    }
+
+    /*
+     * HTML Helpers
+     */
+    private void writeHeader(int level, String text) {
+        mStringBuilder
+                .append("<h").append(level).append('>')
+                .append(text)
+                .append("</h").append(level).append('>');
+    }
+
+    private void openParagraph() {
+        mStringBuilder.append("<p>");
+    }
+
+    private void closeParagraph() {
+        mStringBuilder.append("</p>");
+    }
+
+    private void writeParagraph(String text) {
+        openParagraph();
+        mStringBuilder.append(text);
+        closeParagraph();
+    }
+
+    private void openList() {
+        mStringBuilder.append("<ul>");
+    }
+
+    private void closeList() {
+        mStringBuilder.append("</ul>");
+    }
+
+    private void openListItem() {
+        mStringBuilder.append("<li>");
+    }
+
+    private void closeListItem() {
+        mStringBuilder.append("</li>");
+    }
+
+    private void writeListItem(String text) {
+        openListItem();
+        mStringBuilder.append(text);
+        closeListItem();
+    }
+
+    /*
+     * Data Formating Helpers
+     */
+    private static String getHexString(byte value) {
+        return "0x" + Integer.toHexString(((int) value) & 0xFF).toUpperCase();
+    }
+
+    private static String getBCDString(int value) {
+        int major = value >> 8;
+        int minor = (value >> 4) & 0x0F;
+        int subminor = value & 0x0F;
+
+        return "" + major + "." + minor + subminor;
+    }
+
+    private static String getHexString(int value) {
+        int intValue = value & 0xFFFF;
+        return "0x" + Integer.toHexString(intValue).toUpperCase();
+    }
+
+    private void dumpHexArray(byte[] rawData, StringBuilder builder) {
+        if (rawData != null) {
+            // Assume the type and Length and perhaps sub-type have been displayed
+            openParagraph();
+            for (int index = 0; index < rawData.length; index++) {
+                builder.append(getHexString(rawData[index]) + " ");
+            }
+            closeParagraph();
+        }
+    }
+
+    /**
+     * Decode ACTUAL UsbDescriptor sub classes and call type-specific report methods.
+     */
+    @Override
+    public void report(UsbDescriptor descriptor) {
+        if (descriptor instanceof UsbDeviceDescriptor) {
+            tsReport((UsbDeviceDescriptor) descriptor);
+        } else if (descriptor instanceof UsbConfigDescriptor) {
+            tsReport((UsbConfigDescriptor) descriptor);
+        } else if (descriptor instanceof UsbInterfaceDescriptor) {
+            tsReport((UsbInterfaceDescriptor) descriptor);
+        } else if (descriptor instanceof UsbEndpointDescriptor) {
+            tsReport((UsbEndpointDescriptor) descriptor);
+        } else if (descriptor instanceof UsbHIDDescriptor) {
+            tsReport((UsbHIDDescriptor) descriptor);
+        } else if (descriptor instanceof UsbACAudioControlEndpoint) {
+            tsReport((UsbACAudioControlEndpoint) descriptor);
+        } else if (descriptor instanceof UsbACAudioStreamEndpoint) {
+            tsReport((UsbACAudioStreamEndpoint) descriptor);
+        } else if (descriptor instanceof UsbACHeader) {
+            tsReport((UsbACHeader) descriptor);
+        } else if (descriptor instanceof UsbACFeatureUnit) {
+            tsReport((UsbACFeatureUnit) descriptor);
+        } else if (descriptor instanceof UsbACInputTerminal) {
+            tsReport((UsbACInputTerminal) descriptor);
+        } else if (descriptor instanceof UsbACOutputTerminal) {
+            tsReport((UsbACOutputTerminal) descriptor);
+        } else if (descriptor instanceof UsbACMidiEndpoint) {
+            tsReport((UsbACMidiEndpoint) descriptor);
+        } else if (descriptor instanceof UsbACMixerUnit) {
+            tsReport((UsbACMixerUnit) descriptor);
+        } else if (descriptor instanceof UsbACSelectorUnit) {
+            tsReport((UsbACSelectorUnit) descriptor);
+        } else if (descriptor instanceof UsbASFormatI) {
+            tsReport((UsbASFormatI) descriptor);
+        } else if (descriptor instanceof UsbASFormatII) {
+            tsReport((UsbASFormatII) descriptor);
+        } else if (descriptor instanceof UsbASFormat) {
+            tsReport((UsbASFormat) descriptor);
+        } else if (descriptor instanceof UsbASGeneral) {
+            tsReport((UsbASGeneral) descriptor);
+        } else if (descriptor instanceof UsbInterfaceAssoc) {
+            tsReport((UsbInterfaceAssoc) descriptor);
+        } else if (descriptor instanceof UsbMSMidiHeader) {
+            tsReport((UsbMSMidiHeader) descriptor);
+        } else if (descriptor instanceof UsbMSMidiInputJack) {
+            tsReport((UsbMSMidiInputJack) descriptor);
+        } else if (descriptor instanceof UsbMSMidiOutputJack) {
+            tsReport((UsbMSMidiOutputJack) descriptor);
+        } else if (descriptor instanceof UsbUnknown) {
+            tsReport((UsbUnknown) descriptor);
+        } else if (descriptor instanceof UsbACInterface) {
+            tsReport((UsbACInterface) descriptor);
+        } else if (descriptor instanceof UsbDescriptor) {
+            tsReport((UsbDescriptor) descriptor);
+        }
+    }
+
+    //
+    // Type-specific report() implementations
+    //
+    private void tsReport(UsbDescriptor descriptor) {
+        int length = descriptor.getLength();
+        byte type = descriptor.getType();
+        int status = descriptor.getStatus();
+
+        String descTypeStr = UsbStrings.getDescriptorName(type);
+        writeParagraph(descTypeStr + ":" + type + " l:" + length + " s:" + status);
+    }
+
+    private void tsReport(UsbDeviceDescriptor descriptor) {
+        writeHeader(1, "Device len:" + descriptor.getLength());
+        openList();
+
+        int spec = descriptor.getSpec();
+        writeListItem("spec:" + getBCDString(spec));
+
+        byte devClass = descriptor.getDevClass();
+        String classStr = UsbStrings.getClassName(devClass);
+        byte devSubClass = descriptor.getDevSubClass();
+        String subClasStr = UsbStrings.getClassName(devSubClass);
+        writeListItem("class " + devClass + ":" + classStr + " subclass"
+                + devSubClass + ":" + subClasStr);
+        writeListItem("vendorID:" + descriptor.getVendorID()
+                + " prodID:" + descriptor.getProductID()
+                + " prodRel:" + getBCDString(descriptor.getDeviceRelease()));
+
+        byte mfgIndex = descriptor.getMfgIndex();
+        String manufacturer = UsbDescriptor.getUsbDescriptorString(mConnection, mfgIndex);
+        byte productIndex = descriptor.getProductIndex();
+        String product = UsbDescriptor.getUsbDescriptorString(mConnection, productIndex);
+
+        writeListItem("mfg " + mfgIndex + ":" + manufacturer
+                + " prod " + productIndex + ":" + product);
+        closeList();
+    }
+
+    private void tsReport(UsbConfigDescriptor descriptor) {
+        writeHeader(2, "Config #" + descriptor.getConfigValue()
+                + " len:" + descriptor.getLength());
+
+        openList();
+        writeListItem(descriptor.getNumInterfaces() + " interfaces.");
+        writeListItem("attribs:" + getHexString(descriptor.getAttribs()));
+        closeList();
+    }
+
+    private void tsReport(UsbInterfaceDescriptor descriptor) {
+        byte usbClass = descriptor.getUsbClass();
+        byte usbSubclass = descriptor.getUsbSubclass();
+        String descr = UsbStrings.getDescriptorName(descriptor.getType());
+        String className = UsbStrings.getClassName(usbClass);
+        String subclassName = "";
+        if (usbClass == UsbDescriptor.CLASSID_AUDIO) {
+            subclassName = UsbStrings.getAudioSubclassName(usbSubclass);
+        }
+
+        writeHeader(2, descr + " #" + descriptor.getInterfaceNumber()
+                        + " len:" + descriptor.getLength());
+        String descrStr =
+                UsbDescriptor.getUsbDescriptorString(mConnection, descriptor.getDescrIndex());
+        if (descrStr.length() > 0) {
+            mStringBuilder.append("<br>" + descrStr);
+        }
+        openList();
+        writeListItem("class " + getHexString(usbClass) + ":" + className
+                + " subclass " + getHexString(usbSubclass) + ":" + subclassName);
+        writeListItem(""  + descriptor.getNumEndpoints() + " endpoints");
+        closeList();
+    }
+
+    private void tsReport(UsbEndpointDescriptor descriptor) {
+        writeHeader(3, "Endpoint " + getHexString(descriptor.getType())
+                + " len:" + descriptor.getLength());
+        openList();
+
+        byte address = descriptor.getEndpointAddress();
+        writeListItem("address:"
+                + getHexString(address & UsbEndpointDescriptor.MASK_ENDPOINT_ADDRESS)
+                + ((address & UsbEndpointDescriptor.MASK_ENDPOINT_DIRECTION)
+                        == UsbEndpointDescriptor.DIRECTION_OUTPUT ? " [out]" : " [in]"));
+
+        byte attributes = descriptor.getAttributes();
+        openListItem();
+        mStringBuilder.append("attribs:" + getHexString(attributes) + " ");
+        switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_TRANSTYPE) {
+            case UsbEndpointDescriptor.TRANSTYPE_CONTROL:
+                mStringBuilder.append("Control");
+                break;
+            case UsbEndpointDescriptor.TRANSTYPE_ISO:
+                mStringBuilder.append("Iso");
+                break;
+            case UsbEndpointDescriptor.TRANSTYPE_BULK:
+                mStringBuilder.append("Bulk");
+                break;
+            case UsbEndpointDescriptor.TRANSTYPE_INTERRUPT:
+                mStringBuilder.append("Interrupt");
+                break;
+        }
+        closeListItem();
+
+        // These flags are only relevant for ISO transfer type
+        if ((attributes & UsbEndpointDescriptor.MASK_ATTRIBS_TRANSTYPE)
+                == UsbEndpointDescriptor.TRANSTYPE_ISO) {
+            openListItem();
+            mStringBuilder.append("sync:");
+            switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_SYNCTYPE) {
+                case UsbEndpointDescriptor.SYNCTYPE_NONE:
+                    mStringBuilder.append("NONE");
+                    break;
+                case UsbEndpointDescriptor.SYNCTYPE_ASYNC:
+                    mStringBuilder.append("ASYNC");
+                    break;
+                case UsbEndpointDescriptor.SYNCTYPE_ADAPTSYNC:
+                    mStringBuilder.append("ADAPTIVE ASYNC");
+                    break;
+            }
+            closeListItem();
+
+            openListItem();
+            mStringBuilder.append("useage:");
+            switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_USEAGE) {
+                case UsbEndpointDescriptor.USEAGE_DATA:
+                    mStringBuilder.append("DATA");
+                    break;
+                case UsbEndpointDescriptor.USEAGE_FEEDBACK:
+                    mStringBuilder.append("FEEDBACK");
+                    break;
+                case UsbEndpointDescriptor.USEAGE_EXPLICIT:
+                    mStringBuilder.append("EXPLICIT FEEDBACK");
+                    break;
+                case UsbEndpointDescriptor.USEAGE_RESERVED:
+                    mStringBuilder.append("RESERVED");
+                    break;
+            }
+            closeListItem();
+        }
+        writeListItem("package size:" + descriptor.getPacketSize());
+        writeListItem("interval:" + descriptor.getInterval());
+        closeList();
+    }
+
+    private void tsReport(UsbHIDDescriptor descriptor) {
+        String descr = UsbStrings.getDescriptorName(descriptor.getType());
+        writeHeader(2, descr + " len:" + descriptor.getLength());
+        openList();
+        writeListItem("spec:" + getBCDString(descriptor.getRelease()));
+        writeListItem("type:" + getBCDString(descriptor.getDescriptorType()));
+        writeListItem("descriptor.getNumDescriptors()  descriptors len:"
+                + descriptor.getDescriptorLen());
+        closeList();
+    }
+
+    private void tsReport(UsbACAudioControlEndpoint descriptor) {
+        writeHeader(3, "AC Audio Control Endpoint:" + getHexString(descriptor.getType())
+                + " length:" + descriptor.getLength());
+    }
+
+    private void tsReport(UsbACAudioStreamEndpoint descriptor) {
+        writeHeader(3, "AC Audio Streaming Endpoint:"
+                + getHexString(descriptor.getType())
+                + " length:" + descriptor.getLength());
+    }
+
+    private void tsReport(UsbACHeader descriptor) {
+        tsReport((UsbACInterface) descriptor);
+
+        openList();
+        writeListItem("spec:" + getBCDString(descriptor.getADCRelease()));
+        int numInterfaces = descriptor.getNumInterfaces();
+        writeListItem("" + numInterfaces + " interfaces");
+        if (numInterfaces > 0) {
+            openListItem();
+            mStringBuilder.append("[");
+            byte[] interfaceNums = descriptor.getInterfaceNums();
+            if (numInterfaces != 0 && interfaceNums != null) {
+                for (int index = 0; index < numInterfaces; index++) {
+                    mStringBuilder.append("" + interfaceNums[index]);
+                    if (index < numInterfaces - 1) {
+                        mStringBuilder.append(" ");
+                    }
+                }
+            }
+            mStringBuilder.append("]");
+            closeListItem();
+        }
+        writeListItem("controls:" + getHexString(descriptor.getControls()));
+        closeList();
+    }
+
+    private void tsReport(UsbACFeatureUnit descriptor) {
+        tsReport((UsbACInterface) descriptor);
+    }
+
+    private void tsReport(UsbACInterface descriptor) {
+        String subClassName =
+                descriptor.getSubclass() == UsbDescriptor.AUDIO_AUDIOCONTROL
+                        ? "AC Control"
+                        : "AC Streaming";
+        byte subtype = descriptor.getSubtype();
+        String subTypeStr = UsbStrings.getACControlInterfaceName(subtype);
+        writeHeader(4, subClassName + " - " + getHexString(subtype)
+                + ":" + subTypeStr + " len:" + descriptor.getLength());
+    }
+
+    private void tsReport(UsbACTerminal descriptor) {
+        tsReport((UsbACInterface) descriptor);
+    }
+
+    private void tsReport(UsbACInputTerminal descriptor) {
+        tsReport((UsbACTerminal) descriptor);
+
+        openList();
+        writeListItem("ID:" + getHexString(descriptor.getTerminalID()));
+        int terminalType = descriptor.getTerminalType();
+        writeListItem("Type:<b>" + getHexString(terminalType) + ":"
+                + UsbStrings.getTerminalName(terminalType) + "</b>");
+        writeListItem("AssocTerminal:" + getHexString(descriptor.getAssocTerminal()));
+        writeListItem("" + descriptor.getNrChannels() + " chans. config:"
+                + getHexString(descriptor.getChannelConfig()));
+        closeList();
+    }
+
+    private void tsReport(UsbACOutputTerminal descriptor) {
+        tsReport((UsbACTerminal) descriptor);
+
+        openList();
+        writeListItem("ID:" + getHexString(descriptor.getTerminalID()));
+        int terminalType = descriptor.getTerminalType();
+        writeListItem("Type:<b>" + getHexString(terminalType) + ":"
+                + UsbStrings.getTerminalName(terminalType) + "</b>");
+        writeListItem("AssocTerminal:" + getHexString(descriptor.getAssocTerminal()));
+        writeListItem("Source:" + getHexString(descriptor.getSourceID()));
+        closeList();
+    }
+
+    private void tsReport(UsbACMidiEndpoint descriptor) {
+        writeHeader(3, "AC Midi Endpoint:" + getHexString(descriptor.getType())
+                + " length:" + descriptor.getLength());
+        openList();
+        writeListItem("" + descriptor.getNumJacks() + " jacks.");
+        closeList();
+    }
+
+    private void tsReport(UsbACMixerUnit descriptor) {
+        tsReport((UsbACInterface) descriptor);
+        openList();
+
+        writeListItem("Unit ID:" + getHexString(descriptor.getUnitID()));
+        byte numInputs = descriptor.getNumInputs();
+        byte[] inputIDs = descriptor.getInputIDs();
+        openListItem();
+        mStringBuilder.append("Num Inputs:" + numInputs + " [");
+        for (int input = 0; input < numInputs; input++) {
+            mStringBuilder.append("" + getHexString(inputIDs[input]));
+            if (input < numInputs - 1) {
+                mStringBuilder.append(" ");
+            }
+        }
+        mStringBuilder.append("]");
+        closeListItem();
+
+        writeListItem("Num Outputs:" + descriptor.getNumOutputs());
+        writeListItem("Chan Config:" + getHexString(descriptor.getChannelConfig()));
+
+        byte[] controls = descriptor.getControls();
+        openListItem();
+        mStringBuilder.append("controls:" + controls.length + " [");
+        for (int ctrl = 0; ctrl < controls.length; ctrl++) {
+            mStringBuilder.append("" + controls[ctrl]);
+            if (ctrl < controls.length - 1) {
+                mStringBuilder.append(" ");
+            }
+        }
+        mStringBuilder.append("]");
+        closeListItem();
+        closeList();
+        // byte mChanNameID; // First channel name string descriptor ID
+        // byte mNameID;       // string descriptor ID of mixer name
+    }
+
+    private void tsReport(UsbACSelectorUnit descriptor) {
+        tsReport((UsbACInterface) descriptor);
+    }
+
+    private void tsReport(UsbASFormat descriptor) {
+        writeHeader(4, "AC Streaming Format "
+                + (descriptor.getFormatType() ==  UsbASFormat.FORMAT_TYPE_I  ? "I" : "II")
+                + " - " + getHexString(descriptor.getSubtype()) + ":"
+                + " len:" + descriptor.getLength());
+    }
+
+    private void tsReport(UsbASFormatI descriptor) {
+        tsReport((UsbASFormat) descriptor);
+        openList();
+        writeListItem("chans:" + descriptor.getNumChannels());
+        writeListItem("subframe size:" + descriptor.getSubframeSize());
+        writeListItem("bit resolution:" + descriptor.getBitResolution());
+        byte sampleFreqType = descriptor.getSampleFreqType();
+        int[] sampleRates = descriptor.getSampleRates();
+        writeListItem("sample freq type:" + sampleFreqType);
+        if (sampleFreqType == 0) {
+            openList();
+            writeListItem("min:" + sampleRates[0]);
+            writeListItem("max:" + sampleRates[1]);
+            closeList();
+        } else {
+            openList();
+            for (int index = 0; index < sampleFreqType; index++) {
+                writeListItem("" + sampleRates[index]);
+            }
+            closeList();
+        }
+        closeList();
+    }
+
+    private void tsReport(UsbASFormatII descriptor) {
+        tsReport((UsbASFormat) descriptor);
+        openList();
+        writeListItem("max bit rate:" + descriptor.getMaxBitRate());
+        writeListItem("samples per frame:" + descriptor.getMaxBitRate());
+        byte sampleFreqType = descriptor.getSamFreqType();
+        int[] sampleRates = descriptor.getSampleRates();
+        writeListItem("sample freq type:" + sampleFreqType);
+        if (sampleFreqType == 0) {
+            openList();
+            writeListItem("min:" + sampleRates[0]);
+            writeListItem("max:" + sampleRates[1]);
+            closeList();
+        } else {
+            openList();
+            for (int index = 0; index < sampleFreqType; index++) {
+                writeListItem("" + sampleRates[index]);
+            }
+            closeList();
+        }
+
+        closeList();
+    }
+
+    private void tsReport(UsbASGeneral descriptor) {
+        tsReport((UsbACInterface) descriptor);
+        openList();
+        int formatTag = descriptor.getFormatTag();
+        writeListItem("fmt:" + UsbStrings.getAudioFormatName(formatTag) + " - "
+                + getHexString(formatTag));
+        closeList();
+    }
+
+    private void tsReport(UsbInterfaceAssoc descriptor) {
+        tsReport((UsbDescriptor) descriptor);
+    }
+
+    private void tsReport(UsbMSMidiHeader descriptor) {
+        writeHeader(3, "MS Midi Header:" + getHexString(descriptor.getType())
+                + " subType:" + getHexString(descriptor.getSubclass())
+                + " length:" + descriptor.getSubclass());
+    }
+
+    private void tsReport(UsbMSMidiInputJack descriptor) {
+        writeHeader(3, "MS Midi Input Jack:" + getHexString(descriptor.getType())
+                + " subType:" + getHexString(descriptor.getSubclass())
+                + " length:" + descriptor.getSubclass());
+    }
+
+    private void tsReport(UsbMSMidiOutputJack descriptor) {
+        writeHeader(3, "MS Midi Output Jack:" + getHexString(descriptor.getType())
+                + " subType:" + getHexString(descriptor.getSubclass())
+                + " length:" + descriptor.getSubclass());
+    }
+
+    private void tsReport(UsbUnknown descriptor) {
+        writeParagraph("<i><b>Unknown Descriptor " + getHexString(descriptor.getType())
+                + " len:" + descriptor.getLength() + "</b></i>");
+        dumpHexArray(descriptor.getRawData(), mStringBuilder);
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/report/Reporter.java b/services/usb/java/com/android/server/usb/descriptors/report/Reporter.java
new file mode 100644
index 0000000..2944c10
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/report/Reporter.java
@@ -0,0 +1,40 @@
+/*
+ * 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.usb.descriptors.report;
+
+import com.android.server.usb.descriptors.UsbDescriptor;
+
+/**
+ * Declares the Reporter interface to provide HTML reporting for UsbDescriptor (sub)classes.
+ *
+ * NOTE: It is the responsibility of the implementor of this interface to correctly
+ * interpret/decode the SPECIFIC UsbDescriptor subclass (perhaps with 'instanceof') that is
+ * passed and handle that in the appropriate manner. This appears to be a
+ * not very object-oriented approach, and that is true. This approach DOES however move the
+ * complexity and 'plumbing' of reporting into the Reporter implementation and avoids needing
+ * a (trivial) type-specific call to 'report()' in each UsbDescriptor (sub)class, instead
+ * having just one in the top-level UsbDescriptor class. It also removes the need to add new
+ * type-specific 'report()' methods to be added to Reporter interface whenever a
+ * new UsbDescriptor subclass is defined. This seems like a pretty good trade-off.
+ *
+ * See HTMLReporter.java in this package for an example of type decoding.
+ */
+public interface Reporter {
+    /**
+     * Generate report for this UsbDescriptor descriptor
+     */
+    void report(UsbDescriptor descriptor);
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/report/Reporting.java b/services/usb/java/com/android/server/usb/descriptors/report/Reporting.java
new file mode 100644
index 0000000..c13111b
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/report/Reporting.java
@@ -0,0 +1,27 @@
+/*
+ * 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.usb.descriptors.report;
+
+/**
+ * Declares the interface for classes that provide reporting functionality.
+ * (This is the double-indirection aspect of the "Visitor" pattern.
+ */
+public interface Reporting {
+    /**
+     * Declares the report method that UsbDescriptor subclasses call.
+     */
+    void report(Reporter reporter);
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java b/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java
new file mode 100644
index 0000000..0461150
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java
@@ -0,0 +1,312 @@
+/*
+ * 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.usb.descriptors.report;
+
+import com.android.server.usb.descriptors.UsbACInterface;
+import com.android.server.usb.descriptors.UsbDescriptor;
+import com.android.server.usb.descriptors.UsbTerminalTypes;
+
+import java.util.HashMap;
+
+/**
+ * @hide
+ * A class to provide human-readable strings for various USB constants.
+ */
+public class UsbStrings {
+    private static final String TAG = "UsbStrings";
+
+    private static HashMap<Byte, String> sDescriptorNames;
+    private static HashMap<Byte, String> sACControlInterfaceNames;
+    private static HashMap<Byte, String> sACStreamingInterfaceNames;
+    private static HashMap<Byte, String> sClassNames;
+    private static HashMap<Byte, String> sAudioSubclassNames;
+    private static HashMap<Integer, String> sAudioEncodingNames;
+    private static HashMap<Integer, String> sTerminalNames;
+
+    private static void initDescriptorNames() {
+        sDescriptorNames = new HashMap<Byte, String>();
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_DEVICE, "Device");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_CONFIG, "Config");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_STRING, "String");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_INTERFACE, "Interface");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_ENDPOINT, "Endpoint");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_BOS, "BOS (whatever that means)");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_INTERFACEASSOC,
+                "Interface Association");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_CAPABILITY, "Capability");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_HID, "HID");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_REPORT, "Report");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_PHYSICAL, "Physical");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE,
+                "Audio Class Interface");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_AUDIO_ENDPOINT, "Audio Class Endpoint");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_HUB, "Hub");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_SUPERSPEED_HUB, "Superspeed Hub");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_ENDPOINT_COMPANION,
+                "Endpoint Companion");
+    }
+
+    private static void initACControlInterfaceNames() {
+        sACControlInterfaceNames = new HashMap<Byte, String>();
+        sACControlInterfaceNames.put(UsbACInterface.ACI_UNDEFINED, "Undefined");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_HEADER, "Header");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_INPUT_TERMINAL, "Input Terminal");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_OUTPUT_TERMINAL, "Output Terminal");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_MIXER_UNIT, "Mixer Unit");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_SELECTOR_UNIT, "Selector Unit");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_FEATURE_UNIT, "Feature Unit");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_PROCESSING_UNIT, "Processing Unit");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_EXTENSION_UNIT, "Extension Unit");
+    }
+
+    private static void initACStreamingInterfaceNames() {
+        sACStreamingInterfaceNames = new HashMap<Byte, String>();
+        sACStreamingInterfaceNames.put(UsbACInterface.ASI_UNDEFINED, "Undefined");
+        sACStreamingInterfaceNames.put(UsbACInterface.ASI_GENERAL, "General");
+        sACStreamingInterfaceNames.put(UsbACInterface.ASI_FORMAT_TYPE, "Format Type");
+        sACStreamingInterfaceNames.put(UsbACInterface.ASI_FORMAT_SPECIFIC, "Format Specific");
+    }
+
+    private static void initClassNames() {
+        sClassNames = new HashMap<Byte, String>();
+        sClassNames.put(UsbDescriptor.CLASSID_DEVICE, "Device");
+        sClassNames.put(UsbDescriptor.CLASSID_AUDIO, "Audio");
+        sClassNames.put(UsbDescriptor.CLASSID_COM, "Communications");
+        sClassNames.put(UsbDescriptor.CLASSID_HID, "HID");
+        sClassNames.put(UsbDescriptor.CLASSID_PHYSICAL, "Physical");
+        sClassNames.put(UsbDescriptor.CLASSID_IMAGE, "Image");
+        sClassNames.put(UsbDescriptor.CLASSID_PRINTER, "Printer");
+        sClassNames.put(UsbDescriptor.CLASSID_STORAGE, "Storage");
+        sClassNames.put(UsbDescriptor.CLASSID_HUB, "Hub");
+        sClassNames.put(UsbDescriptor.CLASSID_CDC_CONTROL, "CDC Control");
+        sClassNames.put(UsbDescriptor.CLASSID_SMART_CARD, "Smart Card");
+        sClassNames.put(UsbDescriptor.CLASSID_SECURITY, "Security");
+        sClassNames.put(UsbDescriptor.CLASSID_VIDEO, "Video");
+        sClassNames.put(UsbDescriptor.CLASSID_HEALTHCARE, "Healthcare");
+        sClassNames.put(UsbDescriptor.CLASSID_AUDIOVIDEO, "Audio/Video");
+        sClassNames.put(UsbDescriptor.CLASSID_BILLBOARD, "Billboard");
+        sClassNames.put(UsbDescriptor.CLASSID_TYPECBRIDGE, "Type C Bridge");
+        sClassNames.put(UsbDescriptor.CLASSID_DIAGNOSTIC, "Diagnostic");
+        sClassNames.put(UsbDescriptor.CLASSID_WIRELESS, "Wireless");
+        sClassNames.put(UsbDescriptor.CLASSID_MISC, "Misc");
+        sClassNames.put(UsbDescriptor.CLASSID_APPSPECIFIC, "Application Specific");
+        sClassNames.put(UsbDescriptor.CLASSID_VENDSPECIFIC, "Vendor Specific");
+    }
+
+    private static void initAudioSubclassNames() {
+        sAudioSubclassNames = new HashMap<Byte, String>();
+        sAudioSubclassNames.put(UsbDescriptor.AUDIO_SUBCLASS_UNDEFINED, "Undefinded");
+        sAudioSubclassNames.put(UsbDescriptor.AUDIO_AUDIOCONTROL, "Audio Control");
+        sAudioSubclassNames.put(UsbDescriptor.AUDIO_AUDIOSTREAMING, "Audio Streaming");
+        sAudioSubclassNames.put(UsbDescriptor.AUDIO_MIDISTREAMING, "MIDI Streaming");
+    }
+
+    private static void initAudioEncodingNames() {
+        sAudioEncodingNames = new HashMap<Integer, String>();
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_UNDEFINED, "Format I Undefined");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_PCM, "Format I PCM");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_PCM8, "Format I PCM8");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_IEEE_FLOAT, "Format I FLOAT");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_ALAW, "Format I ALAW");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_MULAW, "Format I MuLAW");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_II_UNDEFINED, "FORMAT_II Undefined");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_II_MPEG, "FORMAT_II MPEG");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_II_AC3, "FORMAT_II AC3");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_UNDEFINED, "FORMAT_III Undefined");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937AC3, "FORMAT_III IEC1937 AC3");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG1_Layer1,
+                "FORMAT_III MPEG1 Layer 1");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG1_Layer2,
+                "FORMAT_III MPEG1 Layer 2");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG2_EXT,
+                "FORMAT_III MPEG2 EXT");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG2_Layer1LS,
+                "FORMAT_III MPEG2 Layer1LS");
+    }
+
+    private static void initTerminalNames() {
+        sTerminalNames = new HashMap<Integer, String>();
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_USB_STREAMING, "USB Streaming");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_MIC, "Microphone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_DESKTOP_MIC, "Desktop Microphone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_PERSONAL_MIC,
+                "Personal (headset) Microphone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_OMNI_MIC, "Omni Microphone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_MIC_ARRAY, "Microphone Array");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_PROC_MIC_ARRAY,
+                "Proecessing Microphone Array");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_SPEAKER, "Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_HEADPHONES, "Headphones");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_HEADMOUNTED, "Head Mounted Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_DESKTOPSPEAKER, "Desktop Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_ROOMSPEAKER, "Room Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_COMSPEAKER, "Communications Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_LFSPEAKER, "Low Frequency Speaker");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_HANDSET, "Handset");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_HEADSET, "Headset");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_SKRPHONE, "Speaker Phone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_SKRPHONE_SUPRESS,
+                "Speaker Phone (echo supressing)");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_SKRPHONE_CANCEL,
+                "Speaker Phone (echo canceling)");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_PHONELINE, "Phone Line");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_PHONE, "Telephone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_DOWNLINEPHONE, "Down Line Phone");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_ANALOG, "Analog Connector");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_DIGITAL, "Digital Connector");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_LINE, "Line Connector");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_LEGACY, "Legacy Audio Connector");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_SPIDF, "S/PIDF Interface");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_1394DA, "1394 Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_1394DV, "1394 Audio/Video");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_CALNOISE, "Calibration Nose");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_EQNOISE, "EQ Noise");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_CDPLAYER, "CD Player");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DAT, "DAT");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DCC, "DCC");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_MINIDISK, "Mini Disk");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_ANALOGTAPE, "Analog Tap");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_PHONOGRAPH, "Phonograph");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_VCRAUDIO, "VCR Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_VIDDISKAUDIO, "Video Disk Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DVDAUDIO, "DVD Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_TVAUDIO, "TV Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_SATELLITEAUDIO, "Satellite Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_CABLEAUDIO, "Cable Tuner Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DSSAUDIO, "DSS Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_RADIOTRANSMITTER, "Radio Transmitter");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_MULTITRACK, "Multitrack Recorder");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_SYNTHESIZER, "Synthesizer");
+    }
+
+    /**
+     * Retrieves the terminal name for the specified terminal type ID.
+     */
+    public static String getTerminalName(int terminalType) {
+        String name = sTerminalNames.get(terminalType);
+        return name != null
+                ? name
+                : "Unknown Terminal Type 0x" + Integer.toHexString(terminalType);
+    }
+    /**
+     * Initializes string tables.
+     */
+    public static void allocUsbStrings() {
+        initDescriptorNames();
+        initACControlInterfaceNames();
+        initACStreamingInterfaceNames();
+        initClassNames();
+        initAudioSubclassNames();
+        initAudioEncodingNames();
+        initTerminalNames();
+    }
+
+    /**
+     * Initializes string tables.
+     */
+    public static void releaseUsbStrings() {
+        sDescriptorNames = null;
+        sACControlInterfaceNames = null;
+        sACStreamingInterfaceNames = null;
+        sClassNames = null;
+        sAudioSubclassNames = null;
+        sAudioEncodingNames = null;
+        sTerminalNames = null;
+    }
+
+    /**
+     * Retrieves the name for the specified descriptor ID.
+     */
+    public static String getDescriptorName(byte descriptorID) {
+        String name = sDescriptorNames.get(descriptorID);
+        int iDescriptorID = descriptorID & 0xFF;
+        return name != null
+            ? name
+            : "Unknown Descriptor [0x" + Integer.toHexString(iDescriptorID)
+                + ":" + iDescriptorID + "]";
+    }
+
+    /**
+     * Retrieves the audio-class control interface name for the specified audio-class subtype.
+     */
+    public static String getACControlInterfaceName(byte subtype) {
+        String name = sACControlInterfaceNames.get(subtype);
+        int iSubType = subtype & 0xFF;
+        return name != null
+                ? name
+                : "Unknown subtype [0x" + Integer.toHexString(iSubType)
+                    + ":" + iSubType + "]";
+    }
+
+    /**
+     * Retrieves the audio-class streaming interface name for the specified audio-class subtype.
+     */
+    public static String getACStreamingInterfaceName(byte subtype) {
+        String name = sACStreamingInterfaceNames.get(subtype);
+        int iSubType = subtype & 0xFF;
+        return name != null
+                ? name
+                : "Unknown Subtype [0x" + Integer.toHexString(iSubType) + ":"
+                    + iSubType + "]";
+    }
+
+    /**
+     * Retrieves the name for the specified USB class ID.
+     */
+    public static String getClassName(byte classID) {
+        String name = sClassNames.get(classID);
+        int iClassID = classID & 0xFF;
+        return name != null
+                ? name
+                : "Unknown Class ID [0x" + Integer.toHexString(iClassID) + ":"
+                    + iClassID + "]";
+    }
+
+    /**
+     * Retrieves the name for the specified USB audio subclass ID.
+     */
+    public static String getAudioSubclassName(byte subClassID) {
+        String name = sAudioSubclassNames.get(subClassID);
+        int iSubclassID = subClassID & 0xFF;
+        return name != null
+                ? name
+                : "Unknown Audio Subclass [0x" + Integer.toHexString(iSubclassID) + ":"
+                    + iSubclassID + "]";
+    }
+
+    /**
+     * Retrieves the name for the specified USB audio format ID.
+     */
+    public static String getAudioFormatName(int formatID) {
+        String name = sAudioEncodingNames.get(formatID);
+        return name != null
+                ? name
+                : "Unknown Format (encoding) ID [0x" + Integer.toHexString(formatID) + ":"
+                    + formatID + "]";
+    }
+}
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 520b0e8..f53eb15 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -300,7 +300,11 @@
 
             // Load the model if it is not loaded.
             if (!modelData.isModelLoaded()) {
-                // Load the model
+                // Before we try and load this model, we should first make sure that any other
+                // models that don't have an active recognition/dead callback are unloaded. Since
+                // there is a finite limit on the number of models that the hardware may be able to
+                // have loaded, we want to make sure there's room for our model.
+                stopAndUnloadDeadModelsLocked();
                 int[] handle = new int[] { INVALID_VALUE };
                 int status = mModule.loadSoundModel(soundModel, handle);
                 if (status != SoundTrigger.STATUS_OK) {
@@ -554,6 +558,13 @@
         }
     }
 
+    boolean isRecognitionRequested(UUID modelId) {
+        synchronized (mLock) {
+            ModelData modelData = mModelDataMap.get(modelId);
+            return modelData != null && modelData.isRequested();
+        }
+    }
+
     //---- SoundTrigger.StatusListener methods
     @Override
     public void onRecognition(RecognitionEvent event) {
@@ -901,7 +912,29 @@
         }
     }
 
+    /**
+     * Stops and unloads a sound model, and removes any reference to the model if successful.
+     *
+     * @param modelData The model data to remove.
+     * @param exception Optional exception to print in logcat. May be null.
+     */
     private void forceStopAndUnloadModelLocked(ModelData modelData, Exception exception) {
+      forceStopAndUnloadModelLocked(modelData, exception, null /* modelDataIterator */);
+    }
+
+    /**
+     * Stops and unloads a sound model, and removes any reference to the model if successful.
+     *
+     * @param modelData The model data to remove.
+     * @param exception Optional exception to print in logcat. May be null.
+     * @param modelDataIterator If this function is to be used while iterating over the
+     *        mModelDataMap, you can provide the iterator for the current model data to be used to
+     *        remove the modelData from the map. This avoids generating a
+     *        ConcurrentModificationException, since this function will try and remove the model
+     *        data from the mModelDataMap when it can successfully unload the model.
+     */
+    private void forceStopAndUnloadModelLocked(ModelData modelData, Exception exception,
+            Iterator modelDataIterator) {
         if (exception != null) {
           Slog.e(TAG, "forceStopAndUnloadModel", exception);
         }
@@ -918,7 +951,11 @@
             Slog.d(TAG, "Unloading previously loaded dangling model " + modelData.getHandle());
             if (mModule.unloadSoundModel(modelData.getHandle()) == STATUS_OK) {
                 // Remove the model data from existence.
-                mModelDataMap.remove(modelData.getModelId());
+                if (modelDataIterator != null) {
+                    modelDataIterator.remove();
+                } else {
+                    mModelDataMap.remove(modelData.getModelId());
+                }
                 Iterator it = mKeyphraseUuidMap.entrySet().iterator();
                 while (it.hasNext()) {
                     Map.Entry pair = (Map.Entry) it.next();
@@ -933,6 +970,23 @@
         }
     }
 
+    private void stopAndUnloadDeadModelsLocked() {
+        Iterator it = mModelDataMap.entrySet().iterator();
+        while (it.hasNext()) {
+            ModelData modelData = (ModelData) ((Map.Entry) it.next()).getValue();
+            if (!modelData.isModelLoaded()) {
+                continue;
+            }
+            if (modelData.getCallback() == null
+                    || (modelData.getCallback().asBinder() != null
+                        && !modelData.getCallback().asBinder().pingBinder())) {
+                // No one is listening on this model, so we might as well evict it.
+                Slog.w(TAG, "Removing model " + modelData.getHandle() + " that has no clients");
+                forceStopAndUnloadModelLocked(modelData, null /* exception */, it);
+            }
+        }
+    }
+
     private ModelData getOrCreateGenericModelDataLocked(UUID modelId) {
         ModelData modelData = mModelDataMap.get(modelId);
         if (modelData == null) {
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 9bca012..51c805d 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -16,18 +16,25 @@
 
 package com.android.server.soundtrigger;
 import static android.hardware.soundtrigger.SoundTrigger.STATUS_ERROR;
+import static android.hardware.soundtrigger.SoundTrigger.STATUS_OK;
 
+import android.app.PendingIntent;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.Manifest;
 import android.hardware.soundtrigger.IRecognitionStatusCallback;
 import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.SoundModel;
 import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
 import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
 import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
+import android.media.soundtrigger.SoundTriggerManager;
+import android.os.Bundle;
 import android.os.Parcel;
 import android.os.ParcelUuid;
+import android.os.PowerManager;
 import android.os.RemoteException;
 import android.util.Slog;
 
@@ -36,6 +43,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.TreeMap;
 import java.util.UUID;
 
 /**
@@ -52,16 +60,23 @@
     private static final boolean DEBUG = true;
 
     final Context mContext;
+    private Object mLock;
     private final SoundTriggerServiceStub mServiceStub;
     private final LocalSoundTriggerService mLocalSoundTriggerService;
     private SoundTriggerDbHelper mDbHelper;
     private SoundTriggerHelper mSoundTriggerHelper;
+    private final TreeMap<UUID, SoundModel> mLoadedModels;
+    private final TreeMap<UUID, LocalSoundTriggerRecognitionStatusCallback> mIntentCallbacks;
+    private PowerManager.WakeLock mWakelock;
 
     public SoundTriggerService(Context context) {
         super(context);
         mContext = context;
         mServiceStub = new SoundTriggerServiceStub();
         mLocalSoundTriggerService = new LocalSoundTriggerService(context);
+        mLoadedModels = new TreeMap<UUID, SoundModel>();
+        mIntentCallbacks = new TreeMap<UUID, LocalSoundTriggerRecognitionStatusCallback>();
+        mLock = new Object();
     }
 
     @Override
@@ -177,8 +192,357 @@
             mSoundTriggerHelper.unloadGenericSoundModel(soundModelId.getUuid());
             mDbHelper.deleteGenericSoundModel(soundModelId.getUuid());
         }
+
+        @Override
+        public int loadGenericSoundModel(GenericSoundModel soundModel) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (!isInitialized()) return STATUS_ERROR;
+            if (soundModel == null || soundModel.uuid == null) {
+                Slog.e(TAG, "Invalid sound model");
+                return STATUS_ERROR;
+            }
+            if (DEBUG) {
+                Slog.i(TAG, "loadGenericSoundModel(): id = " + soundModel.uuid);
+            }
+            synchronized (mLock) {
+                SoundModel oldModel = mLoadedModels.get(soundModel.uuid);
+                // If the model we're loading is actually different than what we had loaded, we
+                // should unload that other model now. We don't care about return codes since we
+                // don't know if the other model is loaded.
+                if (oldModel != null && !oldModel.equals(soundModel)) {
+                    mSoundTriggerHelper.unloadGenericSoundModel(soundModel.uuid);
+                    mIntentCallbacks.remove(soundModel.uuid);
+                }
+                mLoadedModels.put(soundModel.uuid, soundModel);
+            }
+            return STATUS_OK;
+        }
+
+        @Override
+        public int loadKeyphraseSoundModel(KeyphraseSoundModel soundModel) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (!isInitialized()) return STATUS_ERROR;
+            if (soundModel == null || soundModel.uuid == null) {
+                Slog.e(TAG, "Invalid sound model");
+                return STATUS_ERROR;
+            }
+            if (soundModel.keyphrases == null || soundModel.keyphrases.length != 1) {
+                Slog.e(TAG, "Only one keyphrase per model is currently supported.");
+                return STATUS_ERROR;
+            }
+            if (DEBUG) {
+                Slog.i(TAG, "loadKeyphraseSoundModel(): id = " + soundModel.uuid);
+            }
+            synchronized (mLock) {
+                SoundModel oldModel = mLoadedModels.get(soundModel.uuid);
+                // If the model we're loading is actually different than what we had loaded, we
+                // should unload that other model now. We don't care about return codes since we
+                // don't know if the other model is loaded.
+                if (oldModel != null && !oldModel.equals(soundModel)) {
+                    mSoundTriggerHelper.unloadKeyphraseSoundModel(soundModel.keyphrases[0].id);
+                    mIntentCallbacks.remove(soundModel.uuid);
+                }
+                mLoadedModels.put(soundModel.uuid, soundModel);
+            }
+            return STATUS_OK;
+        }
+
+        @Override
+        public int startRecognitionForIntent(ParcelUuid soundModelId, PendingIntent callbackIntent,
+                SoundTrigger.RecognitionConfig config) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (!isInitialized()) return STATUS_ERROR;
+            if (DEBUG) {
+                Slog.i(TAG, "startRecognition(): id = " + soundModelId);
+            }
+
+            synchronized (mLock) {
+                SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+                if (soundModel == null) {
+                    Slog.e(TAG, soundModelId + " is not loaded");
+                    return STATUS_ERROR;
+                }
+                LocalSoundTriggerRecognitionStatusCallback callback = mIntentCallbacks.get(
+                        soundModelId.getUuid());
+                if (callback != null) {
+                    Slog.e(TAG, soundModelId + " is already running");
+                    return STATUS_ERROR;
+                }
+                callback = new LocalSoundTriggerRecognitionStatusCallback(soundModelId.getUuid(),
+                        callbackIntent, config);
+                int ret;
+                switch (soundModel.type) {
+                    case SoundModel.TYPE_KEYPHRASE: {
+                        KeyphraseSoundModel keyphraseSoundModel = (KeyphraseSoundModel) soundModel;
+                        ret = mSoundTriggerHelper.startKeyphraseRecognition(
+                                keyphraseSoundModel.keyphrases[0].id, keyphraseSoundModel, callback,
+                                config);
+                    } break;
+                    case SoundModel.TYPE_GENERIC_SOUND:
+                        ret = mSoundTriggerHelper.startGenericRecognition(soundModel.uuid,
+                                (GenericSoundModel) soundModel, callback, config);
+                        break;
+                    default:
+                        Slog.e(TAG, "Unknown model type");
+                        return STATUS_ERROR;
+                }
+
+                if (ret != STATUS_OK) {
+                    Slog.e(TAG, "Failed to start model: " + ret);
+                    return ret;
+                }
+                mIntentCallbacks.put(soundModelId.getUuid(), callback);
+            }
+            return STATUS_OK;
+        }
+
+        @Override
+        public int stopRecognitionForIntent(ParcelUuid soundModelId) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (!isInitialized()) return STATUS_ERROR;
+            if (DEBUG) {
+                Slog.i(TAG, "stopRecognition(): id = " + soundModelId);
+            }
+
+            synchronized (mLock) {
+                SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+                if (soundModel == null) {
+                    Slog.e(TAG, soundModelId + " is not loaded");
+                    return STATUS_ERROR;
+                }
+                LocalSoundTriggerRecognitionStatusCallback callback = mIntentCallbacks.get(
+                        soundModelId.getUuid());
+                if (callback == null) {
+                    Slog.e(TAG, soundModelId + " is not running");
+                    return STATUS_ERROR;
+                }
+                int ret;
+                switch (soundModel.type) {
+                    case SoundModel.TYPE_KEYPHRASE:
+                        ret = mSoundTriggerHelper.stopKeyphraseRecognition(
+                                ((KeyphraseSoundModel)soundModel).keyphrases[0].id, callback);
+                        break;
+                    case SoundModel.TYPE_GENERIC_SOUND:
+                        ret = mSoundTriggerHelper.stopGenericRecognition(soundModel.uuid, callback);
+                        break;
+                    default:
+                        Slog.e(TAG, "Unknown model type");
+                        return STATUS_ERROR;
+                }
+
+                if (ret != STATUS_OK) {
+                    Slog.e(TAG, "Failed to stop model: " + ret);
+                    return ret;
+                }
+                mIntentCallbacks.remove(soundModelId.getUuid());
+            }
+            return STATUS_OK;
+        }
+
+        @Override
+        public int unloadSoundModel(ParcelUuid soundModelId) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (!isInitialized()) return STATUS_ERROR;
+            if (DEBUG) {
+                Slog.i(TAG, "unloadSoundModel(): id = " + soundModelId);
+            }
+
+            synchronized (mLock) {
+                SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+                if (soundModel == null) {
+                    Slog.e(TAG, soundModelId + " is not loaded");
+                    return STATUS_ERROR;
+                }
+                int ret;
+                switch (soundModel.type) {
+                    case SoundModel.TYPE_KEYPHRASE:
+                        ret = mSoundTriggerHelper.unloadKeyphraseSoundModel(
+                                ((KeyphraseSoundModel)soundModel).keyphrases[0].id);
+                        break;
+                    case SoundModel.TYPE_GENERIC_SOUND:
+                        ret = mSoundTriggerHelper.unloadGenericSoundModel(soundModel.uuid);
+                        break;
+                    default:
+                        Slog.e(TAG, "Unknown model type");
+                        return STATUS_ERROR;
+                }
+                if (ret != STATUS_OK) {
+                    Slog.e(TAG, "Failed to unload model");
+                    return ret;
+                }
+                mLoadedModels.remove(soundModelId.getUuid());
+                return STATUS_OK;
+            }
+        }
+
+        @Override
+        public boolean isRecognitionActive(ParcelUuid parcelUuid) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (!isInitialized()) return false;
+            synchronized (mLock) {
+                LocalSoundTriggerRecognitionStatusCallback callback =
+                        mIntentCallbacks.get(parcelUuid.getUuid());
+                if (callback == null) {
+                    return false;
+                }
+                return mSoundTriggerHelper.isRecognitionRequested(parcelUuid.getUuid());
+            }
+        }
     }
 
+    private final class LocalSoundTriggerRecognitionStatusCallback
+            extends IRecognitionStatusCallback.Stub {
+        private UUID mUuid;
+        private PendingIntent mCallbackIntent;
+        private RecognitionConfig mRecognitionConfig;
+
+        public LocalSoundTriggerRecognitionStatusCallback(UUID modelUuid,
+                PendingIntent callbackIntent,
+                RecognitionConfig config) {
+            mUuid = modelUuid;
+            mCallbackIntent = callbackIntent;
+            mRecognitionConfig = config;
+        }
+
+        @Override
+        public boolean pingBinder() {
+            return mCallbackIntent != null;
+        }
+
+        @Override
+        public void onKeyphraseDetected(SoundTrigger.KeyphraseRecognitionEvent event) {
+            if (mCallbackIntent == null) {
+                return;
+            }
+            grabWakeLock();
+
+            Slog.w(TAG, "Keyphrase sound trigger event: " + event);
+            Intent extras = new Intent();
+            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
+                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_EVENT);
+            extras.putExtra(SoundTriggerManager.EXTRA_RECOGNITION_EVENT, event);
+            try {
+                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
+                if (!mRecognitionConfig.allowMultipleTriggers) {
+                    removeCallback(/*releaseWakeLock=*/false);
+                }
+            } catch (PendingIntent.CanceledException e) {
+                removeCallback(/*releaseWakeLock=*/true);
+            }
+        }
+
+        @Override
+        public void onGenericSoundTriggerDetected(SoundTrigger.GenericRecognitionEvent event) {
+            if (mCallbackIntent == null) {
+                return;
+            }
+            grabWakeLock();
+
+            Slog.w(TAG, "Generic sound trigger event: " + event);
+            Intent extras = new Intent();
+            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
+                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_EVENT);
+            extras.putExtra(SoundTriggerManager.EXTRA_RECOGNITION_EVENT, event);
+            try {
+                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
+                if (!mRecognitionConfig.allowMultipleTriggers) {
+                    removeCallback(/*releaseWakeLock=*/false);
+                }
+            } catch (PendingIntent.CanceledException e) {
+                removeCallback(/*releaseWakeLock=*/true);
+            }
+        }
+
+        @Override
+        public void onError(int status) {
+            if (mCallbackIntent == null) {
+                return;
+            }
+            grabWakeLock();
+
+            Slog.i(TAG, "onError: " + status);
+            Intent extras = new Intent();
+            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
+                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_ERROR);
+            extras.putExtra(SoundTriggerManager.EXTRA_STATUS, status);
+            try {
+                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
+                // Remove the callback, but wait for the intent to finish before we let go of the
+                // wake lock
+                removeCallback(/*releaseWakeLock=*/false);
+            } catch (PendingIntent.CanceledException e) {
+                removeCallback(/*releaseWakeLock=*/true);
+            }
+        }
+
+        @Override
+        public void onRecognitionPaused() {
+            if (mCallbackIntent == null) {
+                return;
+            }
+            grabWakeLock();
+
+            Slog.i(TAG, "onRecognitionPaused");
+            Intent extras = new Intent();
+            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
+                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_PAUSED);
+            try {
+                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
+            } catch (PendingIntent.CanceledException e) {
+                removeCallback(/*releaseWakeLock=*/true);
+            }
+        }
+
+        @Override
+        public void onRecognitionResumed() {
+            if (mCallbackIntent == null) {
+                return;
+            }
+            grabWakeLock();
+
+            Slog.i(TAG, "onRecognitionResumed");
+            Intent extras = new Intent();
+            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
+                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_RESUMED);
+            try {
+                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
+            } catch (PendingIntent.CanceledException e) {
+                removeCallback(/*releaseWakeLock=*/true);
+            }
+        }
+
+        private void removeCallback(boolean releaseWakeLock) {
+            mCallbackIntent = null;
+            synchronized (mLock) {
+                mIntentCallbacks.remove(mUuid);
+                if (releaseWakeLock) {
+                    mWakelock.release();
+                }
+            }
+        }
+    }
+
+    private void grabWakeLock() {
+        synchronized (mLock) {
+            if (mWakelock == null) {
+                PowerManager pm = ((PowerManager) mContext.getSystemService(Context.POWER_SERVICE));
+                mWakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+            }
+            mWakelock.acquire();
+        }
+    }
+
+    private PendingIntent.OnFinished mCallbackCompletedHandler = new PendingIntent.OnFinished() {
+        @Override
+        public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
+                String resultData, Bundle resultExtras) {
+            // We're only ever invoked when the callback is done, so release the lock.
+            synchronized (mLock) {
+                mWakelock.release();
+            }
+        }
+    };
+
     public final class LocalSoundTriggerService extends SoundTriggerInternal {
         private final Context mContext;
         private SoundTriggerHelper mSoundTriggerHelper;
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index b4414d5..f81c89a 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -132,6 +133,86 @@
     public static final String EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS =
             "android.telecom.extra.LAST_EMERGENCY_CALLBACK_TIME_MILLIS";
 
+    /**
+     * Call event sent from a {@link Call} via {@link #sendCallEvent(String, Bundle)} to inform
+     * Telecom that the user has requested that the current {@link Call} should be handed over
+     * to another {@link ConnectionService}.
+     * <p>
+     * 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
+     */
+    public static final String EVENT_REQUEST_HANDOVER =
+            "android.telecom.event.REQUEST_HANDOVER";
+
+    /**
+     * 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
+     */
+    public static final String EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE =
+            "android.telecom.extra.HANDOVER_PHONE_ACCOUNT_HANDLE";
+
+    /**
+     * Integer extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event.  Specifies the
+     * video state of the call when it is handed over to the new {@link PhoneAccount}.
+     * <p>
+     * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
+     * {@link VideoProfile#STATE_BIDIRECTIONAL}, {@link VideoProfile#STATE_RX_ENABLED}, and
+     * {@link VideoProfile#STATE_TX_ENABLED}.
+     * @hide
+     */
+    public static final String EXTRA_HANDOVER_VIDEO_STATE =
+            "android.telecom.extra.HANDOVER_VIDEO_STATE";
+
+    /**
+     * Extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event.  Used by the
+     * {@link InCallService} initiating a handover to provide a {@link Bundle} with extra
+     * information to the handover {@link ConnectionService} specified by
+     * {@link #EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE}.
+     * <p>
+     * This {@link Bundle} is not interpreted by Telecom, but passed as-is to the
+     * {@link ConnectionService} via the request extras when
+     * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
+     * is called to initate the handover.
+     * @hide
+     */
+    public static final String EXTRA_HANDOVER_EXTRAS = "android.telecom.extra.HANDOVER_EXTRAS";
+
+    /**
+     * Call event sent from Telecom to the handover {@link ConnectionService} via
+     * {@link Connection#onCallEvent(String, Bundle)} to inform a {@link Connection} that a handover
+     * to the {@link ConnectionService} has completed successfully.
+     * <p>
+     * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
+     * @hide
+     */
+    public static final String EVENT_HANDOVER_COMPLETE =
+            "android.telecom.event.HANDOVER_COMPLETE";
+
+    /**
+     * Call event sent from Telecom to the handover destination {@link ConnectionService} via
+     * {@link Connection#onCallEvent(String, Bundle)} to inform the handover destination that the
+     * source connection has disconnected.  The {@link Bundle} parameter for the call event will be
+     * {@code null}.
+     * <p>
+     * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
+     * @hide
+     */
+    public static final String EVENT_HANDOVER_SOURCE_DISCONNECTED =
+            "android.telecom.event.HANDOVER_SOURCE_DISCONNECTED";
+
+    /**
+     * Call event sent from Telecom to the handover {@link ConnectionService} via
+     * {@link Connection#onCallEvent(String, Bundle)} to inform a {@link Connection} that a handover
+     * to the {@link ConnectionService} has failed.
+     * <p>
+     * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
+     * @hide
+     */
+    public static final String EVENT_HANDOVER_FAILED =
+            "android.telecom.event.HANDOVER_FAILED";
+
     public static class Details {
 
         /** Call can currently be put on hold or unheld. */
@@ -775,6 +856,39 @@
      */
     public static abstract class Callback {
         /**
+         * @hide
+         */
+        @IntDef({HANDOVER_FAILURE_DEST_APP_REJECTED, HANDOVER_FAILURE_DEST_NOT_SUPPORTED,
+                HANDOVER_FAILURE_DEST_INVALID_PERM, HANDOVER_FAILURE_DEST_USER_REJECTED})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface HandoverFailureErrors {}
+
+        /**
+         * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when the app
+         * to handover the call rejects handover.
+         */
+        public static final int HANDOVER_FAILURE_DEST_APP_REJECTED = 1;
+
+        /**
+         * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when there is
+         * an error associated with unsupported handover.
+         */
+        public static final int HANDOVER_FAILURE_DEST_NOT_SUPPORTED = 2;
+
+        /**
+         * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when there
+         * are some permission errors associated with APIs doing handover.
+         */
+        public static final int HANDOVER_FAILURE_DEST_INVALID_PERM = 3;
+
+        /**
+         * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when user
+         * rejects handover.
+         */
+        public static final int HANDOVER_FAILURE_DEST_USER_REJECTED = 4;
+
+
+        /**
          * Invoked when the state of this {@code Call} has changed. See {@link #getState()}.
          *
          * @param call The {@code Call} invoking this method.
@@ -909,6 +1023,21 @@
          *               {@link android.telecom.Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
          */
         public void onRttInitiationFailure(Call call, int reason) {}
+
+        /**
+         * Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount}
+         * has completed successfully.
+         * @param call The call which had initiated handover.
+         */
+        public void onHandoverComplete(Call call) {}
+
+        /**
+         * Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount}
+         * has failed.
+         * @param call The call which had initiated handover.
+         * @param failureReason Error reason for failure
+         */
+        public void onHandoverFailed(Call call, @HandoverFailureErrors int failureReason) {}
     }
 
     /**
@@ -1009,12 +1138,17 @@
          * @return A string containing text sent by the remote user, or {@code null} if the
          * conversation has been terminated or if there was an error while reading.
          */
-        public String read() throws IOException {
-            int numRead = mReceiveStream.read(mReadBuffer, 0, READ_BUFFER_SIZE);
-            if (numRead < 0) {
-                return null;
+        public String read() {
+            try {
+                int numRead = mReceiveStream.read(mReadBuffer, 0, READ_BUFFER_SIZE);
+                if (numRead < 0) {
+                    return null;
+                }
+                return new String(mReadBuffer, 0, numRead);
+            } catch (IOException e) {
+                Log.w(this, "Exception encountered when reading from InputStreamReader: %s", e);
             }
-            return new String(mReadBuffer, 0, numRead);
+            return null;
         }
 
         /**
@@ -1022,7 +1156,9 @@
          * be read.
          * @return A string containing text entered by the user, or {@code null} if the user has
          * not entered any new text yet.
+         * @hide
          */
+        @TestApi
         public String readImmediately() throws IOException {
             if (mReceiveStream.ready()) {
                 return read();
@@ -1278,6 +1414,24 @@
     }
 
     /**
+     * Initiates a handover of this {@link Call} to the {@link ConnectionService} identified
+     * by {@code toHandle}.  The videoState specified indicates the desired video state after the
+     * handover.
+     * <p>
+     * A handover request is initiated by the user from one app to indicate a desire
+     * to handover a call to another.
+     *
+     * @param toHandle {@link PhoneAccountHandle} of the {@link ConnectionService} to handover
+     *                 this call to.
+     * @param videoState Indicates the video state desired after the handover.
+     * @param extras Bundle containing extra information to be passed to the
+     *               {@link ConnectionService}
+     */
+    public void handoverTo(PhoneAccountHandle toHandle, int videoState, Bundle extras) {
+        mInCallAdapter.handoverTo(mTelecomCallId, toHandle, videoState, extras);
+    }
+
+    /**
      * Terminate the RTT session on this call. The resulting state change will be notified via
      * the {@link Callback#onRttStatusChanged(Call, boolean, RttCall)} callback.
      */
diff --git a/telecomm/java/android/telecom/CallAudioState.java b/telecomm/java/android/telecom/CallAudioState.java
index f601d8b..4b827d2 100644
--- a/telecomm/java/android/telecom/CallAudioState.java
+++ b/telecomm/java/android/telecom/CallAudioState.java
@@ -16,16 +16,35 @@
 
 package android.telecom;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothDevice;
 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.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 import java.util.Locale;
+import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  *  Encapsulates the telecom audio state, including the current audio routing, supported audio
  *  routing and mute.
  */
 public final class CallAudioState implements Parcelable {
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value={ROUTE_EARPIECE, ROUTE_BLUETOOTH, ROUTE_WIRED_HEADSET, ROUTE_SPEAKER},
+            flag=true)
+    public @interface CallAudioRoute {}
+
     /** Direct the audio stream through the device's earpiece. */
     public static final int ROUTE_EARPIECE      = 0x00000001;
 
@@ -55,6 +74,8 @@
     private final boolean isMuted;
     private final int route;
     private final int supportedRouteMask;
+    private final BluetoothDevice activeBluetoothDevice;
+    private final Collection<BluetoothDevice> supportedBluetoothDevices;
 
     /**
      * Constructor for a {@link CallAudioState} object.
@@ -73,10 +94,21 @@
      * {@link #ROUTE_WIRED_HEADSET}
      * {@link #ROUTE_SPEAKER}
      */
-    public CallAudioState(boolean muted, int route, int supportedRouteMask) {
-        this.isMuted = muted;
+    public CallAudioState(boolean muted, @CallAudioRoute int route,
+            @CallAudioRoute int supportedRouteMask) {
+        this(muted, route, supportedRouteMask, null, Collections.emptyList());
+    }
+
+    /** @hide */
+    public CallAudioState(boolean isMuted, @CallAudioRoute int route,
+            @CallAudioRoute int supportedRouteMask,
+            @Nullable BluetoothDevice activeBluetoothDevice,
+            @NonNull Collection<BluetoothDevice> supportedBluetoothDevices) {
+        this.isMuted = isMuted;
         this.route = route;
         this.supportedRouteMask = supportedRouteMask;
+        this.activeBluetoothDevice = activeBluetoothDevice;
+        this.supportedBluetoothDevices = supportedBluetoothDevices;
     }
 
     /** @hide */
@@ -84,6 +116,8 @@
         isMuted = state.isMuted();
         route = state.getRoute();
         supportedRouteMask = state.getSupportedRouteMask();
+        activeBluetoothDevice = state.activeBluetoothDevice;
+        supportedBluetoothDevices = state.getSupportedBluetoothDevices();
     }
 
     /** @hide */
@@ -92,6 +126,8 @@
         isMuted = state.isMuted();
         route = state.getRoute();
         supportedRouteMask = state.getSupportedRouteMask();
+        activeBluetoothDevice = null;
+        supportedBluetoothDevices = Collections.emptyList();
     }
 
     @Override
@@ -103,17 +139,32 @@
             return false;
         }
         CallAudioState state = (CallAudioState) obj;
-        return isMuted() == state.isMuted() && getRoute() == state.getRoute() &&
-                getSupportedRouteMask() == state.getSupportedRouteMask();
+        if (supportedBluetoothDevices.size() != state.supportedBluetoothDevices.size()) {
+            return false;
+        }
+        for (BluetoothDevice device : supportedBluetoothDevices) {
+            if (!state.supportedBluetoothDevices.contains(device)) {
+                return false;
+            }
+        }
+        return Objects.equals(activeBluetoothDevice, state.activeBluetoothDevice) && isMuted() ==
+                state.isMuted() && getRoute() == state.getRoute() && getSupportedRouteMask() ==
+                state.getSupportedRouteMask();
     }
 
     @Override
     public String toString() {
+        String bluetoothDeviceList = supportedBluetoothDevices.stream()
+                .map(BluetoothDevice::getAddress).collect(Collectors.joining(", "));
+
         return String.format(Locale.US,
-                "[AudioState isMuted: %b, route: %s, supportedRouteMask: %s]",
+                "[AudioState isMuted: %b, route: %s, supportedRouteMask: %s, " +
+                        "activeBluetoothDevice: [%s], supportedBluetoothDevices: [%s]]",
                 isMuted,
                 audioRouteToString(route),
-                audioRouteToString(supportedRouteMask));
+                audioRouteToString(supportedRouteMask),
+                activeBluetoothDevice,
+                bluetoothDeviceList);
     }
 
     /**
@@ -126,6 +177,7 @@
     /**
      * @return The current audio route being used.
      */
+    @CallAudioRoute
     public int getRoute() {
         return route;
     }
@@ -133,11 +185,27 @@
     /**
      * @return Bit mask of all routes supported by this call.
      */
+    @CallAudioRoute
     public int getSupportedRouteMask() {
         return supportedRouteMask;
     }
 
     /**
+     * @return The {@link BluetoothDevice} through which audio is being routed.
+     *         Will not be {@code null} if {@link #getRoute()} returns {@link #ROUTE_BLUETOOTH}.
+     */
+    public BluetoothDevice getActiveBluetoothDevice() {
+        return activeBluetoothDevice;
+    }
+
+    /**
+     * @return {@link List} of {@link BluetoothDevice}s that can be used for this call.
+     */
+    public Collection<BluetoothDevice> getSupportedBluetoothDevices() {
+        return supportedBluetoothDevices;
+    }
+
+    /**
      * Converts the provided audio route into a human readable string representation.
      *
      * @param route to convert into a string.
@@ -177,7 +245,13 @@
             boolean isMuted = source.readByte() == 0 ? false : true;
             int route = source.readInt();
             int supportedRouteMask = source.readInt();
-            return new CallAudioState(isMuted, route, supportedRouteMask);
+            BluetoothDevice activeBluetoothDevice = source.readParcelable(
+                    ClassLoader.getSystemClassLoader());
+            List<BluetoothDevice> supportedBluetoothDevices = new ArrayList<>();
+            source.readParcelableList(supportedBluetoothDevices,
+                    ClassLoader.getSystemClassLoader());
+            return new CallAudioState(isMuted, route,
+                    supportedRouteMask, activeBluetoothDevice, supportedBluetoothDevices);
         }
 
         @Override
@@ -202,6 +276,8 @@
         destination.writeByte((byte) (isMuted ? 1 : 0));
         destination.writeInt(route);
         destination.writeInt(supportedRouteMask);
+        destination.writeParcelable(activeBluetoothDevice, 0);
+        destination.writeParcelableList(new ArrayList<>(supportedBluetoothDevices), 0);
     }
 
     private static void listAppend(StringBuffer buffer, String str) {
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 177759e..5fcff18 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.telecom.Connection.VideoProvider;
 import android.util.ArraySet;
 
@@ -81,6 +82,7 @@
     private int mConnectionProperties;
     private String mDisconnectMessage;
     private long mConnectTimeMillis = CONNECT_TIME_NOT_SPECIFIED;
+    private long mConnectElapsedTimeMillis = CONNECT_TIME_NOT_SPECIFIED;
     private StatusHints mStatusHints;
     private Bundle mExtras;
     private Set<String> mPreviousExtraKeys;
@@ -454,10 +456,6 @@
      * @param conferenceableConnections The set of connections this connection can conference with.
      */
     public final void setConferenceableConnections(List<Connection> conferenceableConnections) {
-        if (Objects.equals(mConferenceableConnections, conferenceableConnections)) {
-            return;
-        }
-
         clearConferenceableList();
         for (Connection c : conferenceableConnections) {
             // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
@@ -586,7 +584,11 @@
     }
 
     /**
-     * Sets the connection start time of the {@code Conference}.
+     * Sets the connection start time of the {@code Conference}.  Should be specified in wall-clock
+     * time returned by {@link System#currentTimeMillis()}.
+     * <p>
+     * When setting the connection time, you should always set the connection elapsed time via
+     * {@link #setConnectionElapsedTime(long)}.
      *
      * @param connectionTimeMillis The connection time, in milliseconds.
      */
@@ -595,6 +597,20 @@
     }
 
     /**
+     * Sets the elapsed time since system boot when the {@link Conference} was connected.
+     * This is used to determine the duration of the {@link Conference}.
+     * <p>
+     * When setting the connection elapsed time, you should always set the connection time via
+     * {@link #setConnectionTime(long)}.
+     *
+     * @param connectionElapsedTime The connection time, as measured by
+     * {@link SystemClock#elapsedRealtime()}.
+     */
+    public final void setConnectionElapsedTime(long connectionElapsedTime) {
+        mConnectElapsedTimeMillis = connectionElapsedTime;
+    }
+
+    /**
      * @hide
      * @deprecated Use {@link #getConnectionTime}.
      */
@@ -616,6 +632,21 @@
     }
 
     /**
+     * Retrieves the connection start time of the {@link Conference}, if specified.  A value of
+     * {@link #CONNECT_TIME_NOT_SPECIFIED} indicates that Telecom should determine the start time
+     * of the conference.
+     *
+     * This is based on the value of {@link SystemClock#elapsedRealtime()} to ensure that it is not
+     * impacted by wall clock changes (user initiated, network initiated, time zone change, etc).
+     *
+     * @return The elapsed time at which the {@link Conference} was connected.
+     * @hide
+     */
+    public final long getConnectElapsedTime() {
+        return mConnectElapsedTimeMillis;
+    }
+
+    /**
      * 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 7d2f5c8..ffb5e93 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -20,12 +20,12 @@
 import com.android.internal.telecom.IVideoCallback;
 import com.android.internal.telecom.IVideoProvider;
 
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.app.Notification;
+import android.bluetooth.BluetoothDevice;
 import android.content.Intent;
 import android.hardware.camera2.CameraManager;
 import android.net.Uri;
@@ -37,14 +37,13 @@
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.util.ArraySet;
 import android.view.Surface;
 
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -571,6 +570,24 @@
     public static final String EVENT_CALL_REMOTELY_UNHELD =
             "android.telecom.event.CALL_REMOTELY_UNHELD";
 
+    /**
+     * Connection event used to inform an {@link InCallService} which initiated a call handover via
+     * {@link Call#EVENT_REQUEST_HANDOVER} that the handover from this {@link Connection} has
+     * successfully completed.
+     * @hide
+     */
+    public static final String EVENT_HANDOVER_COMPLETE =
+            "android.telecom.event.HANDOVER_COMPLETE";
+
+    /**
+     * Connection event used to inform an {@link InCallService} which initiated a call handover via
+     * {@link Call#EVENT_REQUEST_HANDOVER} that the handover from this {@link Connection} has failed
+     * to complete.
+     * @hide
+     */
+    public static final String EVENT_HANDOVER_FAILED =
+            "android.telecom.event.HANDOVER_FAILED";
+
     // Flag controlling whether PII is emitted into the logs
     private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
 
@@ -803,11 +820,13 @@
         public void onConnectionEvent(Connection c, String event, Bundle extras) {}
         /** @hide */
         public void onConferenceSupportedChanged(Connection c, boolean isConferenceSupported) {}
-        public void onAudioRouteChanged(Connection c, int audioRoute) {}
+        public void onAudioRouteChanged(Connection c, int audioRoute, String bluetoothAddress) {}
         public void onRttInitiationSuccess(Connection c) {}
         public void onRttInitiationFailure(Connection c, int reason) {}
         public void onRttSessionRemotelyTerminated(Connection c) {}
         public void onRemoteRttRequest(Connection c) {}
+        /** @hide */
+        public void onPhoneAccountChanged(Connection c, PhoneAccountHandle pHandle) {}
     }
 
     /**
@@ -1678,6 +1697,7 @@
     private VideoProvider mVideoProvider;
     private boolean mAudioModeIsVoip;
     private long mConnectTimeMillis = Conference.CONNECT_TIME_NOT_SPECIFIED;
+    private long mConnectElapsedTimeMillis = Conference.CONNECT_TIME_NOT_SPECIFIED;
     private StatusHints mStatusHints;
     private int mVideoState;
     private DisconnectCause mDisconnectCause;
@@ -1822,6 +1842,22 @@
     }
 
     /**
+     * Retrieves the connection start time of the {@link Connection}, if specified.  A value of
+     * {@link Conference#CONNECT_TIME_NOT_SPECIFIED} indicates that Telecom should determine the
+     * start time of the conference.
+     *
+     * Based on the value of {@link SystemClock#elapsedRealtime()}, which ensures that wall-clock
+     * changes do not impact the call duration.
+     *
+     * @return The time at which the {@link Connection} was connected.
+     *
+     * @hide
+     */
+    public final long getConnectElapsedTimeMillis() {
+        return mConnectElapsedTimeMillis;
+    }
+
+    /**
      * @return The status hints for this connection.
      */
     public final StatusHints getStatusHints() {
@@ -2232,7 +2268,8 @@
      * Sets the time at which a call became active on this Connection. This is set only
      * when a conference call becomes active on this connection.
      *
-     * @param connectionTimeMillis The connection time, in milliseconds.
+     * @param connectTimeMillis The connection time, in milliseconds.  Should be set using a value
+     *                          obtained from {@link System#currentTimeMillis()}.
      *
      * @hide
      */
@@ -2241,6 +2278,19 @@
     }
 
     /**
+     * Sets the time at which a call became active on this Connection. This is set only
+     * when a conference call becomes active on this connection.
+     *
+     * @param connectElapsedTimeMillis The connection time, in milliseconds.  Stored in the format
+     *                              {@link SystemClock#elapsedRealtime()}.
+     *
+     * @hide
+     */
+    public final void setConnectElapsedTimeMillis(long connectElapsedTimeMillis) {
+        mConnectElapsedTimeMillis = connectElapsedTimeMillis;
+    }
+
+    /**
      * Sets the label and icon status to display in the in-call UI.
      *
      * @param statusHints The status label and icon to set.
@@ -2527,7 +2577,29 @@
      */
     public final void setAudioRoute(int route) {
         for (Listener l : mListeners) {
-            l.onAudioRouteChanged(this, route);
+            l.onAudioRouteChanged(this, route, null);
+        }
+    }
+
+    /**
+     *
+     * Request audio routing to a specific bluetooth device. Calling this method may result in
+     * the device routing audio to a different bluetooth device than the one specified if the
+     * bluetooth stack is unable to route audio to the requested device.
+     * A list of available devices can be obtained via
+     * {@link CallAudioState#getSupportedBluetoothDevices()}
+     *
+     * <p>
+     * Used by self-managed {@link ConnectionService}s which wish to use bluetooth audio for a
+     * self-managed {@link Connection} (see {@link PhoneAccount#CAPABILITY_SELF_MANAGED}.)
+     * <p>
+     * See also {@link InCallService#requestBluetoothAudio(String)}
+     * @param bluetoothAddress The address of the bluetooth device to connect to, as returned by
+     *                         {@link BluetoothDevice#getAddress()}.
+     */
+    public void requestBluetoothAudio(@NonNull String bluetoothAddress) {
+        for (Listener l : mListeners) {
+            l.onAudioRouteChanged(this, CallAudioState.ROUTE_BLUETOOTH, bluetoothAddress);
         }
     }
 
@@ -3015,6 +3087,18 @@
     }
 
     /**
+     * Notifies listeners when phone account is changed. For example, when the PhoneAccount is
+     * changed due to an emergency call being redialed.
+     * @param pHandle The new PhoneAccountHandle for this connection.
+     * @hide
+     */
+    public void notifyPhoneAccountChanged(PhoneAccountHandle pHandle) {
+        for (Listener l : mListeners) {
+            l.onPhoneAccountChanged(this, pHandle);
+        }
+    }
+
+    /**
      * Sends an event associated with this {@code Connection} with associated event extras to the
      * {@link InCallService}.
      * <p>
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 6f742e9..da8ac5e 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -92,6 +92,24 @@
     @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
     public static final String SERVICE_INTERFACE = "android.telecom.ConnectionService";
 
+    /**
+     * Boolean extra used by Telecom to inform a {@link ConnectionService} that the purpose of it
+     * being asked to create a new outgoing {@link Connection} is to perform a handover of an
+     * ongoing call on the device from another {@link PhoneAccount}/{@link ConnectionService}.  Will
+     * be specified in the {@link ConnectionRequest#getExtras()} passed by Telecom when
+     * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} is called.
+     * <p>
+     * When your {@link ConnectionService} receives this extra, it should communicate the fact that
+     * this is a handover to the other device's matching {@link ConnectionService}.  That
+     * {@link ConnectionService} will continue the handover using
+     * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}, specifying
+     * {@link TelecomManager#EXTRA_IS_HANDOVER}.  Telecom will match the phone numbers of the
+     * handover call on the other device with ongoing calls for {@link ConnectionService}s which
+     * support {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}.
+     * @hide
+     */
+    public static final String EXTRA_IS_HANDOVER = TelecomManager.EXTRA_IS_HANDOVER;
+
     // Flag controlling whether PII is emitted into the logs
     private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
 
@@ -1276,10 +1294,10 @@
         }
 
         @Override
-        public void onAudioRouteChanged(Connection c, int audioRoute) {
+        public void onAudioRouteChanged(Connection c, int audioRoute, String bluetoothAddress) {
             String id = mIdByConnection.get(c);
             if (id != null) {
-                mAdapter.setAudioRoute(id, audioRoute);
+                mAdapter.setAudioRoute(id, audioRoute, bluetoothAddress);
             }
         }
 
@@ -1314,6 +1332,14 @@
                 mAdapter.onRemoteRttRequest(id);
             }
         }
+
+        @Override
+        public void onPhoneAccountChanged(Connection c, PhoneAccountHandle pHandle) {
+            String id = mIdByConnection.get(c);
+            if (id != null) {
+                mAdapter.onPhoneAccountChanged(id, pHandle);
+            }
+        }
     };
 
     /** {@inheritDoc} */
@@ -1387,6 +1413,7 @@
                         connection.isRingbackRequested(),
                         connection.getAudioModeIsVoip(),
                         connection.getConnectTimeMillis(),
+                        connection.getConnectElapsedTimeMillis(),
                         connection.getStatusHints(),
                         connection.getDisconnectCause(),
                         createIdList(connection.getConferenceables()),
@@ -1422,6 +1449,12 @@
      */
     private void notifyCreateConnectionComplete(final String callId) {
         Log.i(this, "notifyCreateConnectionComplete %s", callId);
+        if (callId == null) {
+            // This could happen if the connection fails quickly and is removed from the
+            // ConnectionService before Telecom sends the create connection complete callback.
+            Log.w(this, "notifyCreateConnectionComplete: callId is null.");
+            return;
+        }
         onCreateConnectionComplete(findConnectionForAction(callId,
                 "notifyCreateConnectionComplete"));
     }
@@ -1798,6 +1831,7 @@
                             null : conference.getVideoProvider().getInterface(),
                     conference.getVideoState(),
                     conference.getConnectTimeMillis(),
+                    conference.getConnectElapsedTime(),
                     conference.getStatusHints(),
                     conference.getExtras());
 
@@ -1863,6 +1897,7 @@
                     connection.isRingbackRequested(),
                     connection.getAudioModeIsVoip(),
                     connection.getConnectTimeMillis(),
+                    connection.getConnectElapsedTimeMillis(),
                     connection.getStatusHints(),
                     connection.getDisconnectCause(),
                     emptyList,
@@ -1998,6 +2033,43 @@
     }
 
     /**
+     * Called by Telecom on the initiating side of the handover to create an instance of a
+     * handover connection.
+     * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
+     *                               ConnectionService which needs to handover the call.
+     * @param request Details about the call which needs to be handover.
+     * @return Connection object corresponding to the handover call.
+     */
+    public Connection onCreateOutgoingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
+                                                         ConnectionRequest request) {
+        return null;
+    }
+
+    /**
+     * Called by Telecom on the receiving side of the handover to request the
+     * {@link ConnectionService} to create an instance of a handover connection.
+     * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
+     *                               ConnectionService which needs to handover the call.
+     * @param request Details about the call which needs to be handover.
+     * @return {@link Connection} object corresponding to the handover call.
+     */
+    public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
+                                                         ConnectionRequest request) {
+        return null;
+    }
+
+    /**
+     * Called by Telecom in response to a {@code TelecomManager#acceptHandover()}
+     * invocation which failed.
+     * @param request Details about the call which needs to be handover.
+     * @param error Reason for handover failure as defined in
+     *              {@link android.telecom.Call.Callback#HANDOVER_FAILURE_DEST_INVALID_PERM}
+     */
+    public void onHandoverFailed(ConnectionRequest request, int error) {
+        return;
+    }
+
+    /**
      * Create a {@code Connection} for a new unknown call. An unknown call is a call originating
      * from the ConnectionService that was neither a user-initiated outgoing call, nor an incoming
      * call created using
@@ -2148,7 +2220,7 @@
     }
 
     private Connection findConnectionForAction(String callId, String action) {
-        if (mConnectionById.containsKey(callId)) {
+        if (callId != null && mConnectionById.containsKey(callId)) {
             return mConnectionById.get(callId);
         }
         Log.w(this, "%s - Cannot find Connection %s", action, callId);
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index 63bdf74..92a9dc2 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -520,11 +520,14 @@
      * @param callId The unique ID of the call.
      * @param audioRoute The new audio route (see {@code CallAudioState#ROUTE_*}).
      */
-    void setAudioRoute(String callId, int audioRoute) {
-        Log.v(this, "setAudioRoute: %s %s", callId, CallAudioState.audioRouteToString(audioRoute));
+    void setAudioRoute(String callId, int audioRoute, String bluetoothAddress) {
+        Log.v(this, "setAudioRoute: %s %s %s", callId,
+                CallAudioState.audioRouteToString(audioRoute),
+                bluetoothAddress);
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setAudioRoute(callId, audioRoute, Log.getExternalSession());
+                adapter.setAudioRoute(callId, audioRoute,
+                        bluetoothAddress, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -609,4 +612,20 @@
             }
         }
     }
+
+    /**
+     * Notifies Telecom that a call's PhoneAccountHandle has changed.
+     *
+     * @param callId The unique ID of the call.
+     * @param pHandle The new PhoneAccountHandle associated with the call.
+     */
+    void onPhoneAccountChanged(String callId, PhoneAccountHandle pHandle) {
+        for (IConnectionServiceAdapter adapter : mAdapters) {
+            try {
+                Log.d(this, "onPhoneAccountChanged %s", callId);
+                adapter.onPhoneAccountChanged(callId, pHandle, Log.getExternalSession());
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
 }
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index 80e3c33..3fbdeb1 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -72,6 +72,7 @@
     private static final int MSG_ON_RTT_INITIATION_FAILURE = 31;
     private static final int MSG_ON_RTT_REMOTELY_TERMINATED = 32;
     private static final int MSG_ON_RTT_UPGRADE_REQUEST = 33;
+    private static final int MSG_SET_PHONE_ACCOUNT_CHANGED = 34;
 
     private final IConnectionServiceAdapter mDelegate;
 
@@ -297,8 +298,8 @@
                 case MSG_SET_AUDIO_ROUTE: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.setAudioRoute((String) args.arg1, args.argi1,
-                                (Session.Info) args.arg2);
+                        mDelegate.setAudioRoute((String) args.arg1, args.argi1, (String) args.arg2,
+                                (Session.Info) args.arg3);
                     } finally {
                         args.recycle();
                     }
@@ -318,6 +319,16 @@
                 case MSG_ON_RTT_UPGRADE_REQUEST:
                     mDelegate.onRemoteRttRequest((String) msg.obj, null /*Session.Info*/);
                     break;
+                case MSG_SET_PHONE_ACCOUNT_CHANGED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        mDelegate.onPhoneAccountChanged((String) args.arg1,
+                                (PhoneAccountHandle) args.arg2, null /*Session.Info*/);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
             }
         }
     };
@@ -537,12 +548,12 @@
 
         @Override
         public final void setAudioRoute(String connectionId, int audioRoute,
-                Session.Info sessionInfo) {
-
+                String bluetoothAddress, Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.argi1 = audioRoute;
-            args.arg2 = sessionInfo;
+            args.arg2 = bluetoothAddress;
+            args.arg3 = sessionInfo;
             mHandler.obtainMessage(MSG_SET_AUDIO_ROUTE, args).sendToTarget();
         }
 
@@ -581,6 +592,15 @@
                 throws RemoteException {
             mHandler.obtainMessage(MSG_ON_RTT_UPGRADE_REQUEST, connectionId).sendToTarget();
         }
+
+        @Override
+        public void onPhoneAccountChanged(String callId, PhoneAccountHandle pHandle,
+                Session.Info sessionInfo) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = pHandle;
+            mHandler.obtainMessage(MSG_SET_PHONE_ACCOUNT_CHANGED, args).sendToTarget();
+        }
     };
 
     public ConnectionServiceAdapterServant(IConnectionServiceAdapter delegate) {
diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java
index cd65232..2a707c9 100644
--- a/telecomm/java/android/telecom/DefaultDialerManager.java
+++ b/telecomm/java/android/telecom/DefaultDialerManager.java
@@ -170,7 +170,7 @@
 
         final Intent dialIntentWithTelScheme = new Intent(Intent.ACTION_DIAL);
         dialIntentWithTelScheme.setData(Uri.fromParts(PhoneAccount.SCHEME_TEL, "", null));
-        return filterByIntent(context, packageNames, dialIntentWithTelScheme);
+        return filterByIntent(context, packageNames, dialIntentWithTelScheme, userId);
     }
 
     public static List<String> getInstalledDialerApplications(Context context) {
@@ -204,17 +204,18 @@
      *
      * @param context A valid context
      * @param packageNames List of package names to filter.
+     * @param userId The UserId
      * @return The filtered list.
      */
     private static List<String> filterByIntent(Context context, List<String> packageNames,
-            Intent intent) {
+            Intent intent, int userId) {
         if (packageNames == null || packageNames.isEmpty()) {
             return new ArrayList<>();
         }
 
         final List<String> result = new ArrayList<>();
         final List<ResolveInfo> resolveInfoList = context.getPackageManager()
-                .queryIntentActivities(intent, 0);
+                .queryIntentActivitiesAsUser(intent, 0, userId);
         final int length = resolveInfoList.size();
         for (int i = 0; i < length; i++) {
             final ActivityInfo info = resolveInfoList.get(i).activityInfo;
diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java
index 9559a28..4bc2a9b 100644
--- a/telecomm/java/android/telecom/InCallAdapter.java
+++ b/telecomm/java/android/telecom/InCallAdapter.java
@@ -16,6 +16,7 @@
 
 package android.telecom;
 
+import android.bluetooth.BluetoothDevice;
 import android.os.Bundle;
 import android.os.RemoteException;
 
@@ -128,7 +129,22 @@
      */
     public void setAudioRoute(int route) {
         try {
-            mAdapter.setAudioRoute(route);
+            mAdapter.setAudioRoute(route, null);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Request audio routing to a specific bluetooth device. Calling this method may result in
+     * the device routing audio to a different bluetooth device than the one specified. A list of
+     * available devices can be obtained via {@link CallAudioState#getSupportedBluetoothDevices()}
+     *
+     * @param bluetoothAddress The address of the bluetooth device to connect to, as returned by
+     * {@link BluetoothDevice#getAddress()}, or {@code null} if no device is preferred.
+     */
+    public void requestBluetoothAudio(String bluetoothAddress) {
+        try {
+            mAdapter.setAudioRoute(CallAudioState.ROUTE_BLUETOOTH, bluetoothAddress);
         } catch (RemoteException e) {
         }
     }
@@ -419,4 +435,21 @@
         } catch (RemoteException ignored) {
         }
     }
+
+
+    /**
+     * Initiates a handover of this {@link Call} to the {@link ConnectionService} identified
+     * by destAcct.
+     * @param callId The callId of the Call which calls this function.
+     * @param destAcct ConnectionService to which the call should be handed over.
+     * @param videoState The video state desired after the handover.
+     * @param extras Extra information to be passed to ConnectionService
+     */
+    public void handoverTo(String callId, PhoneAccountHandle destAcct, int videoState,
+                           Bundle extras) {
+        try {
+            mAdapter.handoverTo(callId, destAcct, videoState, extras);
+        } catch (RemoteException ignored) {
+        }
+    }
 }
diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index e384d46..d558bba 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -16,9 +16,11 @@
 
 package android.telecom;
 
+import android.annotation.NonNull;
 import android.annotation.SdkConstant;
 import android.annotation.SystemApi;
 import android.app.Service;
+import android.bluetooth.BluetoothDevice;
 import android.content.Intent;
 import android.hardware.camera2.CameraManager;
 import android.net.Uri;
@@ -377,6 +379,22 @@
     }
 
     /**
+     * Request audio routing to a specific bluetooth device. Calling this method may result in
+     * the device routing audio to a different bluetooth device than the one specified if the
+     * bluetooth stack is unable to route audio to the requested device.
+     * A list of available devices can be obtained via
+     * {@link CallAudioState#getSupportedBluetoothDevices()}
+     *
+     * @param bluetoothAddress The address of the bluetooth device to connect to, as returned by
+     *                         {@link BluetoothDevice#getAddress()}.
+     */
+    public final void requestBluetoothAudio(@NonNull String bluetoothAddress) {
+        if (mPhone != null) {
+            mPhone.requestBluetoothAudio(bluetoothAddress);
+        }
+    }
+
+    /**
      * Invoked when the {@code Phone} has been created. This is a signal to the in-call experience
      * to start displaying in-call information to the user. Each instance of {@code InCallService}
      * will have only one {@code Phone}, and this method will be called exactly once in the lifetime
diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java
index 640c9e1..de205380 100644
--- a/telecomm/java/android/telecom/Log.java
+++ b/telecomm/java/android/telecom/Log.java
@@ -325,7 +325,8 @@
         return sEventManager;
     }
 
-    private static SessionManager getSessionManager() {
+    @VisibleForTesting
+    public static SessionManager getSessionManager() {
         // Checking for null again outside of synchronization because we only need to synchronize
         // during the lazy loading of the session logger. We don't need to synchronize elsewhere.
         if (sSessionManager == null) {
diff --git a/telecomm/java/android/telecom/ParcelableConference.java b/telecomm/java/android/telecom/ParcelableConference.java
index f5689d8..a6221d4 100644
--- a/telecomm/java/android/telecom/ParcelableConference.java
+++ b/telecomm/java/android/telecom/ParcelableConference.java
@@ -41,6 +41,7 @@
     private final int mVideoState;
     private StatusHints mStatusHints;
     private Bundle mExtras;
+    private long mConnectElapsedTimeMillis = Conference.CONNECT_TIME_NOT_SPECIFIED;
 
     public ParcelableConference(
             PhoneAccountHandle phoneAccount,
@@ -51,6 +52,7 @@
             IVideoProvider videoProvider,
             int videoState,
             long connectTimeMillis,
+            long connectElapsedTimeMillis,
             StatusHints statusHints,
             Bundle extras) {
         mPhoneAccount = phoneAccount;
@@ -58,12 +60,12 @@
         mConnectionCapabilities = connectionCapabilities;
         mConnectionProperties = connectionProperties;
         mConnectionIds = connectionIds;
-        mConnectTimeMillis = Conference.CONNECT_TIME_NOT_SPECIFIED;
         mVideoProvider = videoProvider;
         mVideoState = videoState;
         mConnectTimeMillis = connectTimeMillis;
         mStatusHints = statusHints;
         mExtras = extras;
+        mConnectElapsedTimeMillis = connectElapsedTimeMillis;
     }
 
     @Override
@@ -111,6 +113,11 @@
     public long getConnectTimeMillis() {
         return mConnectTimeMillis;
     }
+
+    public long getConnectElapsedTimeMillis() {
+        return mConnectElapsedTimeMillis;
+    }
+
     public IVideoProvider getVideoProvider() {
         return mVideoProvider;
     }
@@ -144,10 +151,11 @@
             StatusHints statusHints = source.readParcelable(classLoader);
             Bundle extras = source.readBundle(classLoader);
             int properties = source.readInt();
+            long connectElapsedTimeMillis = source.readLong();
 
             return new ParcelableConference(phoneAccount, state, capabilities, properties,
-                    connectionIds, videoCallProvider, videoState, connectTimeMillis, statusHints,
-                    extras);
+                    connectionIds, videoCallProvider, videoState, connectTimeMillis,
+                    connectElapsedTimeMillis, statusHints, extras);
         }
 
         @Override
@@ -176,5 +184,6 @@
         destination.writeParcelable(mStatusHints, 0);
         destination.writeBundle(mExtras);
         destination.writeInt(mConnectionProperties);
+        destination.writeLong(mConnectElapsedTimeMillis);
     }
 }
diff --git a/telecomm/java/android/telecom/ParcelableConnection.java b/telecomm/java/android/telecom/ParcelableConnection.java
index 434abf5..61d5a12 100644
--- a/telecomm/java/android/telecom/ParcelableConnection.java
+++ b/telecomm/java/android/telecom/ParcelableConnection.java
@@ -47,6 +47,7 @@
     private final boolean mRingbackRequested;
     private final boolean mIsVoipAudioMode;
     private final long mConnectTimeMillis;
+    private final long mConnectElapsedTimeMillis;
     private final StatusHints mStatusHints;
     private final DisconnectCause mDisconnectCause;
     private final List<String> mConferenceableConnectionIds;
@@ -69,6 +70,7 @@
             boolean ringbackRequested,
             boolean isVoipAudioMode,
             long connectTimeMillis,
+            long connectElapsedTimeMillis,
             StatusHints statusHints,
             DisconnectCause disconnectCause,
             List<String> conferenceableConnectionIds,
@@ -77,7 +79,8 @@
         this(phoneAccount, state, capabilities, properties, supportedAudioRoutes, address,
                 addressPresentation, callerDisplayName, callerDisplayNamePresentation,
                 videoProvider, videoState, ringbackRequested, isVoipAudioMode, connectTimeMillis,
-                statusHints, disconnectCause, conferenceableConnectionIds, extras);
+                connectElapsedTimeMillis, statusHints, disconnectCause, conferenceableConnectionIds,
+                extras);
         mParentCallId = parentCallId;
     }
 
@@ -97,6 +100,7 @@
             boolean ringbackRequested,
             boolean isVoipAudioMode,
             long connectTimeMillis,
+            long connectElapsedTimeMillis,
             StatusHints statusHints,
             DisconnectCause disconnectCause,
             List<String> conferenceableConnectionIds,
@@ -115,6 +119,7 @@
         mRingbackRequested = ringbackRequested;
         mIsVoipAudioMode = isVoipAudioMode;
         mConnectTimeMillis = connectTimeMillis;
+        mConnectElapsedTimeMillis = connectElapsedTimeMillis;
         mStatusHints = statusHints;
         mDisconnectCause = disconnectCause;
         mConferenceableConnectionIds = conferenceableConnectionIds;
@@ -190,6 +195,10 @@
         return mConnectTimeMillis;
     }
 
+    public long getConnectElapsedTimeMillis() {
+        return mConnectElapsedTimeMillis;
+    }
+
     public final StatusHints getStatusHints() {
         return mStatusHints;
     }
@@ -255,6 +264,7 @@
             int properties = source.readInt();
             int supportedAudioRoutes = source.readInt();
             String parentCallId = source.readString();
+            long connectElapsedTimeMillis = source.readLong();
 
             return new ParcelableConnection(
                     phoneAccount,
@@ -271,6 +281,7 @@
                     ringbackRequested,
                     audioModeIsVoip,
                     connectTimeMillis,
+                    connectElapsedTimeMillis,
                     statusHints,
                     disconnectCause,
                     conferenceableConnectionIds,
@@ -313,5 +324,6 @@
         destination.writeInt(mConnectionProperties);
         destination.writeInt(mSupportedAudioRoutes);
         destination.writeString(mParentCallId);
+        destination.writeLong(mConnectElapsedTimeMillis);
     }
 }
diff --git a/telecomm/java/android/telecom/Phone.java b/telecomm/java/android/telecom/Phone.java
index 066f6c2..421b1a4 100644
--- a/telecomm/java/android/telecom/Phone.java
+++ b/telecomm/java/android/telecom/Phone.java
@@ -17,7 +17,9 @@
 package android.telecom;
 
 import android.annotation.SystemApi;
+import android.bluetooth.BluetoothDevice;
 import android.os.Bundle;
+import android.os.RemoteException;
 import android.util.ArrayMap;
 
 import java.util.Collections;
@@ -295,6 +297,18 @@
     }
 
     /**
+     * Request audio routing to a specific bluetooth device. Calling this method may result in
+     * the device routing audio to a different bluetooth device than the one specified. A list of
+     * available devices can be obtained via {@link CallAudioState#getSupportedBluetoothDevices()}
+     *
+     * @param bluetoothAddress The address of the bluetooth device to connect to, as returned by
+     * {@link BluetoothDevice#getAddress()}, or {@code null} if no device is preferred.
+     */
+    public void requestBluetoothAudio(String bluetoothAddress) {
+        mInCallAdapter.requestBluetoothAudio(bluetoothAddress);
+    }
+
+    /**
      * Turns the proximity sensor on. When this request is made, the proximity sensor will
      * become active, and the touch screen and display will be turned off when the user's face
      * is detected to be in close proximity to the screen. This operation is a no-op on devices
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index 5530cb7..74b9465 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -76,6 +76,63 @@
     public static final String EXTRA_CALL_SUBJECT_CHARACTER_ENCODING =
             "android.telecom.extra.CALL_SUBJECT_CHARACTER_ENCODING";
 
+     /**
+     * Indicating flag for phone account whether to use voip audio mode for voip calls
+     * @hide
+     */
+    public static final String EXTRA_ALWAYS_USE_VOIP_AUDIO_MODE =
+            "android.telecom.extra.ALWAYS_USE_VOIP_AUDIO_MODE";
+
+    /**
+     * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
+     * indicates whether this {@link PhoneAccount} is capable of supporting a request to handover a
+     * connection (see {@code android.telecom.Call#handoverTo()}) to this {@link PhoneAccount} from
+     * a {@link PhoneAccount} specifying {@link #EXTRA_SUPPORTS_HANDOVER_FROM}.
+     * <p>
+     * A handover request is initiated by the user from the default dialer app to indicate a desire
+     * to handover a call from one {@link PhoneAccount}/{@link ConnectionService} to another.
+     */
+    public static final String EXTRA_SUPPORTS_HANDOVER_TO =
+            "android.telecom.extra.SUPPORTS_HANDOVER_TO";
+
+    /**
+     * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
+     * indicates whether this {@link PhoneAccount} supports using a fallback if video calling is
+     * not available. This extra is for device level support, {@link
+     * android.telephony.CarrierConfigManager#KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL} should also
+     * be checked to ensure it is not disabled by individual carrier.
+     *
+     * @hide
+     */
+    public static final String EXTRA_SUPPORTS_VIDEO_CALLING_FALLBACK =
+            "android.telecom.extra.SUPPORTS_VIDEO_CALLING_FALLBACK";
+
+    /**
+     * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
+     * indicates whether this {@link PhoneAccount} is capable of supporting a request to handover a
+     * connection from this {@link PhoneAccount} to another {@link PhoneAccount}.
+     * (see {@code android.telecom.Call#handoverTo()}) which specifies
+     * {@link #EXTRA_SUPPORTS_HANDOVER_TO}.
+     * <p>
+     * A handover request is initiated by the user from the default dialer app to indicate a desire
+     * to handover a call from one {@link PhoneAccount}/{@link ConnectionService} to another.
+     */
+    public static final String EXTRA_SUPPORTS_HANDOVER_FROM =
+            "android.telecom.extra.SUPPORTS_HANDOVER_FROM";
+
+
+    /**
+     * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
+     * indicates whether a Self-Managed {@link PhoneAccount} should log its calls to the call log.
+     * Self-Managed {@link PhoneAccount}s are responsible for their own notifications, so the system
+     * will not create a notification when a missed call is logged.
+     * <p>
+     * By default, Self-Managed {@link PhoneAccount}s do not log their calls to the call log.
+     * Setting this extra to {@code true} provides a means for them to log their calls.
+     */
+    public static final String EXTRA_LOG_SELF_MANAGED_CALLS =
+            "android.telecom.extra.LOG_SELF_MANAGED_CALLS";
+
     /**
      * Flag indicating that this {@code PhoneAccount} can act as a connection manager for
      * other connections. The {@link ConnectionService} associated with this {@code PhoneAccount}
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index 57fc9ce..05480dc 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -25,6 +25,7 @@
 import android.annotation.SystemApi;
 import android.hardware.camera2.CameraManager;
 import android.net.Uri;
+import android.os.BadParcelableException;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -1064,7 +1065,7 @@
      *
      * @param state The audio state of this {@code RemoteConnection}.
      * @hide
-     * @deprecated Use {@link #setCallAudioState(CallAudioState) instead.
+     * @deprecated Use {@link #setCallAudioState(CallAudioState)} instead.
      */
     @SystemApi
     @Deprecated
@@ -1464,7 +1465,11 @@
         if (mExtras == null) {
             mExtras = new Bundle();
         }
-        mExtras.putAll(extras);
+        try {
+            mExtras.putAll(extras);
+        } catch (BadParcelableException bpe) {
+            Log.w(this, "putExtras: could not unmarshal extras; exception = " + bpe);
+        }
 
         notifyExtrasChanged();
     }
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index 06cdd1a..85906ad 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -208,6 +208,11 @@
         }
 
         @Override
+        public void onPhoneAccountChanged(String callId, PhoneAccountHandle pHandle,
+                Session.Info sessionInfo) {
+        }
+
+        @Override
         public void addConferenceCall(
                 final String callId, ParcelableConference parcel, Session.Info sessionInfo) {
             RemoteConference conference = new RemoteConference(callId,
@@ -393,7 +398,8 @@
         }
 
         @Override
-        public void setAudioRoute(String callId, int audioRoute, Session.Info sessionInfo) {
+        public void setAudioRoute(String callId, int audioRoute, String bluetoothAddress,
+                Session.Info sessionInfo) {
             if (hasConnection(callId)) {
                 // TODO(3pcalls): handle this for remote connections.
                 // Likely we don't want to do anything since it doesn't make sense for self-managed
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index d0b36c9..4d2cb04 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -349,6 +349,44 @@
             "android.telecom.extra.NEW_OUTGOING_CALL_CANCEL_TIMEOUT";
 
     /**
+     * Boolean extra specified to indicate that the intention of adding a call is to handover an
+     * existing call from the user's device to a different {@link PhoneAccount}.
+     * <p>
+     * Used when calling {@link #addNewIncomingCall(PhoneAccountHandle, Bundle)}
+     * to indicate to Telecom that the purpose of adding a new incoming call is to handover an
+     * existing call from the user's device to a different {@link PhoneAccount}.  This occurs on
+     * the receiving side of a handover.
+     * <p>
+     * Used when Telecom calls
+     * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
+     * to indicate that the purpose of Telecom requesting a new outgoing connection it to request
+     * a handover to this {@link ConnectionService} from an ongoing call on the user's device.  This
+     * occurs on the initiating side of a handover.
+     * <p>
+     * The phone number of the call used by Telecom to determine which call should be handed over.
+     * @hide
+     */
+    public static final String EXTRA_IS_HANDOVER = "android.telecom.extra.IS_HANDOVER";
+
+    /**
+     * Parcelable extra used with {@link #EXTRA_IS_HANDOVER} to indicate the source
+     * {@link PhoneAccountHandle} when initiating a handover which {@link ConnectionService}
+     * the handover is from.
+     * @hide
+     */
+    public static final String EXTRA_HANDOVER_FROM_PHONE_ACCOUNT =
+            "android.telecom.extra.HANDOVER_FROM_PHONE_ACCOUNT";
+
+    /**
+     * Extra key specified in the {@link ConnectionRequest#getExtras()} when Telecom calls
+     * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
+     * to inform the {@link ConnectionService} what the initial {@link CallAudioState} of the
+     * {@link Connection} will be.
+     * @hide
+     */
+    public static final String EXTRA_CALL_AUDIO_STATE = "android.telecom.extra.CALL_AUDIO_STATE";
+
+    /**
      * A boolean extra, which when set on the {@link Intent#ACTION_CALL} intent or on the bundle
      * passed into {@link #placeCall(Uri, Bundle)}, indicates that the call should be initiated with
      * an RTT session open. See {@link android.telecom.Call.RttCall} for more information on RTT.
@@ -1307,10 +1345,7 @@
 
     /**
      * Returns whether TTY is supported on this device.
-     *
-     * @hide
      */
-    @SystemApi
     @RequiresPermission(anyOf = {
             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
             android.Manifest.permission.READ_PHONE_STATE
@@ -1714,6 +1749,41 @@
         return false;
     }
 
+    /**
+     * Called from the recipient side of a handover to indicate a desire to accept the handover
+     * of an ongoing call to another {@link ConnectionService} identified by
+     * {@link PhoneAccountHandle} destAcct. For managed {@link ConnectionService}s, the specified
+     * {@link PhoneAccountHandle} must have been registered with {@link #registerPhoneAccount} and
+     * the user must have enabled the corresponding {@link PhoneAccount}.  This can be checked using
+     * {@link #getPhoneAccount}. Self-managed {@link ConnectionService}s must have
+     * {@link android.Manifest.permission#MANAGE_OWN_CALLS} to handover a call to it.
+     * <p>
+     * Once invoked, this method will cause the system to bind to the {@link ConnectionService}
+     * associated with the {@link PhoneAccountHandle} destAcct and call
+     * (See {@link ConnectionService#onCreateIncomingHandoverConnection}).
+     * <p>
+     * For a managed {@link ConnectionService}, a {@link SecurityException} will be thrown if either
+     * the {@link PhoneAccountHandle} destAcct does not correspond to a registered
+     * {@link PhoneAccount} or the associated {@link PhoneAccount} is not currently enabled by the
+     * user.
+     * <p>
+     * For a self-managed {@link ConnectionService}, a {@link SecurityException} will be thrown if
+     * the calling app does not have {@link android.Manifest.permission#MANAGE_OWN_CALLS}.
+     *
+     * @param srcAddr The {@link android.net.Uri} of the ongoing call to handover to the caller’s
+     *                {@link ConnectionService}.
+     * @param videoState Video state after the handover.
+     * @param destAcct The {@link PhoneAccountHandle} registered to the calling package.
+     */
+    public void acceptHandover(Uri srcAddr, int videoState, PhoneAccountHandle destAcct) {
+        try {
+            if (isServiceConnected()) {
+                getTelecomService().acceptHandover(srcAddr, videoState, destAcct);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException acceptHandover: " + e);
+        }
+    }
 
     private ITelecomService getTelecomService() {
         if (mTelecomServiceOverride != null) {
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
index ac9da2e..da2015f 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
@@ -24,6 +24,7 @@
 import android.telecom.Logging.Session;
 import android.telecom.ParcelableConnection;
 import android.telecom.ParcelableConference;
+import android.telecom.PhoneAccountHandle;
 import android.telecom.StatusHints;
 
 import com.android.internal.telecom.IVideoProvider;
@@ -102,7 +103,8 @@
 
     void removeExtras(String callId, in List<String> keys, in Session.Info sessionInfo);
 
-    void setAudioRoute(String callId, int audioRoute, in Session.Info sessionInfo);
+    void setAudioRoute(String callId, int audioRoute, String bluetoothAddress,
+            in Session.Info sessionInfo);
 
     void onConnectionEvent(String callId, String event, in Bundle extras,
     in Session.Info sessionInfo);
@@ -114,4 +116,7 @@
     void onRttSessionRemotelyTerminated(String callId, in Session.Info sessionInfo);
 
     void onRemoteRttRequest(String callId, in Session.Info sessionInfo);
+
+    void onPhoneAccountChanged(String callId, in PhoneAccountHandle pHandle,
+    in Session.Info sessionInfo);
 }
diff --git a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
index 73fa29a..23ac940 100644
--- a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
@@ -39,7 +39,7 @@
 
     void mute(boolean shouldMute);
 
-    void setAudioRoute(int route);
+    void setAudioRoute(int route, String bluetoothAddress);
 
     void playDtmfTone(String callId, char digit);
 
@@ -77,4 +77,7 @@
     void stopRtt(String callId);
 
     void setRttMode(String callId, int mode);
+
+    void handoverTo(String callId, in PhoneAccountHandle destAcct, int videoState,
+            in Bundle extras);
 }
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 8ebac2c..3460754f 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -274,4 +274,9 @@
      * @see TelecomServiceImpl#waitOnHandler
      */
     void waitOnHandlers();
+
+    /**
+     * @see TelecomServiceImpl#acceptHandover
+     */
+    void acceptHandover(in Uri srcAddr, int videoState, in PhoneAccountHandle destAcct);
 }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index fe8774f..1d08111 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -199,7 +199,7 @@
     /** Display carrier settings menu if true */
     public static final String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool";
 
-    /** Does not display additional call seting for IMS phone based on GSM Phone */
+    /** Does not display additional call setting for IMS phone based on GSM Phone */
     public static final String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
 
     /** Show APN Settings for some CDMA carriers */
@@ -209,6 +209,12 @@
     public static final String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
 
     /**
+     * Determine whether user can edit voicemail number in Settings.
+     */
+    public static final String KEY_EDITABLE_VOICEMAIL_NUMBER_SETTING_BOOL =
+            "editable_voicemail_number_setting_bool";
+
+    /**
      * Since the default voicemail number is empty, if a SIM card does not have a voicemail number
      * available the user cannot use voicemail. This flag allows the user to edit the voicemail
      * number in such cases, and is false by default.
@@ -332,14 +338,29 @@
     public static final String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";
 
     /**
-     * Flag indicating whether we should downgrade/terminate VT calls and disable VT when
-     * data enabled changed (e.g. reach data limit or turn off data).
+     * When {@code true}, changes to the mobile data enabled switch will not cause the VT
+     * registration state to change.  That is, turning on or off mobile data will not cause VT to be
+     * enabled or disabled.
+     * When {@code false}, disabling mobile data will cause VT to be de-registered.
+     * <p>
+     * See also {@link #KEY_VILTE_DATA_IS_METERED_BOOL}.
      * @hide
      */
     public static final String KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS =
             "ignore_data_enabled_changed_for_video_calls";
 
     /**
+     * Flag indicating whether data used for a video call over LTE is metered or not.
+     * <p>
+     * When {@code true}, if the device hits the data limit or data is disabled during a ViLTE call,
+     * the call will be downgraded to audio-only (or paused if
+     * {@link #KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL} is {@code true}).
+     *
+     * @hide
+     */
+    public static final String KEY_VILTE_DATA_IS_METERED_BOOL = "vilte_data_is_metered_bool";
+
+    /**
      * Flag specifying whether WFC over IMS should be available for carrier: independent of
      * carrier provisioning. If false: hard disabled. If true: then depends on carrier
      * provisioning, availability etc.
@@ -798,6 +819,14 @@
     public static final String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
 
     /**
+     * Default Enhanced 4G LTE mode enabled. When this is {@code true}, Enhanced 4G LTE mode by
+     * default is on, otherwise if {@code false}, Enhanced 4G LTE mode by default is off.
+     * @hide
+     */
+    public static final String KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL =
+            "enhanced_4g_lte_on_by_default_bool";
+
+    /**
      * Determine whether IMS apn can be shown.
      */
     public static final String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
@@ -1029,6 +1058,26 @@
      */
     public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET =
             "carrier_default_actions_on_reset_string_array";
+
+    /**
+     * Defines carrier-specific actions which act upon
+     * com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE,
+     * used for customization of the default carrier app
+     * Format:
+     * {
+     *     "true : CARRIER_ACTION_IDX_1",
+     *     "false: CARRIER_ACTION_IDX_2"
+     * }
+     * Where {@code true} is a boolean indicates default network available/unavailable
+     * Where {@code CARRIER_ACTION_IDX} is an integer defined in
+     * {@link com.android.carrierdefaultapp.CarrierActionUtils CarrierActionUtils}
+     * Example:
+     * {@link com.android.carrierdefaultapp.CarrierActionUtils
+     * #CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER enable the app as the default URL handler}
+     * @hide
+     */
+    public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE =
+            "carrier_default_actions_on_default_network_available_string_array";
     /**
      * Defines a list of acceptable redirection url for default carrier app
      * @hides
@@ -1233,6 +1282,15 @@
     public static final String KEY_VIDEO_CALLS_CAN_BE_HD_AUDIO = "video_calls_can_be_hd_audio";
 
     /**
+     * Whether system apps are allowed to use fallback if carrier video call is not available.
+     * Defaults to {@code true}.
+     *
+     * @hide
+     */
+    public static final String KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL =
+            "allow_video_calling_fallback_bool";
+
+    /**
      * Defines operator-specific {@link com.android.ims.ImsReasonInfo} mappings.
      *
      * Format: "ORIGINAL_CODE|MESSAGE|NEW_CODE"
@@ -1344,6 +1402,17 @@
         "support_3gpp_call_forwarding_while_roaming_bool";
 
     /**
+     * Boolean indicating whether to display voicemail number as default call forwarding number in
+     * call forwarding settings.
+     * If true, display vm number when cf number is null.
+     * If false, display the cf number from network.
+     * By default this value is false.
+     * @hide
+     */
+    public static final String KEY_DISPLAY_VOICEMAIL_NUMBER_AS_DEFAULT_CALL_FORWARDING_NUMBER_BOOL =
+            "display_voicemail_number_as_default_call_forwarding_number";
+
+    /**
      * When {@code true}, the user will be notified when they attempt to place an international call
      * when the call is placed using wifi calling.
      * @hide
@@ -1453,6 +1522,13 @@
             "boosted_lte_earfcns_string_array";
 
     /**
+     * Determine whether to use only RSRP for the number of LTE signal bars.
+     * @hide
+     */
+    public static final String KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL =
+            "use_only_rsrp_for_lte_signal_bar_bool";
+
+    /**
      * Key identifying if voice call barring notification is required to be shown to the user.
      * @hide
      */
@@ -1500,6 +1576,78 @@
     public static final String IMSI_KEY_EXPIRATION_DAYS_TIME_INT =
             "imsi_key_expiration_days_time_int";
 
+    /**
+     * Key identifying if the CDMA Caller ID presentation and suppression MMI codes
+     * should be converted to 3GPP CLIR codes when a multimode (CDMA+UMTS+LTE) device is roaming
+     * on a 3GPP network. Specifically *67<number> will be converted to #31#<number> and
+     * *82<number> will be converted to *31#<number> before dialing a call when this key is
+     * set TRUE and device is roaming on a 3GPP network.
+     * @hide
+     */
+    public static final String KEY_CONVERT_CDMA_CALLER_ID_MMI_CODES_WHILE_ROAMING_ON_3GPP_BOOL =
+            "convert_cdma_caller_id_mmi_codes_while_roaming_on_3gpp_bool";
+    
+    /**
+     * Flag specifying whether IMS registration state menu is shown in Status Info setting,
+     * default to false.
+     * @hide
+     */
+    public static final String KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL =
+            "show_ims_registration_status_bool";
+
+    /**
+     * The flag to disable the popup dialog which warns the user of data charges.
+     * @hide
+     */
+    public static final String KEY_DISABLE_CHARGE_INDICATION_BOOL =
+            "disable_charge_indication_bool";
+
+    /**
+     * Boolean indicating whether to skip the call forwarding (CF) fail-to-disable dialog.
+     * The logic used to determine whether we succeeded in disabling is carrier specific,
+     * so the dialog may not always be accurate.
+     * {@code false} - show CF fail-to-disable dialog.
+     * {@code true}  - skip showing CF fail-to-disable dialog.
+     *
+     * @hide
+     */
+    public static final String KEY_SKIP_CF_FAIL_TO_DISABLE_DIALOG_BOOL =
+            "skip_cf_fail_to_disable_dialog_bool";
+
+    /**
+     * List of the FAC (feature access codes) to dial as a normal call.
+     * @hide
+     */
+    public static final String KEY_FEATURE_ACCESS_CODES_STRING_ARRAY =
+            "feature_access_codes_string_array";
+
+    /**
+     * Determines if the carrier wants to identify high definition calls in the call log.
+     * @hide
+     */
+    public static final String KEY_IDENTIFY_HIGH_DEFINITION_CALLS_IN_CALL_LOG_BOOL =
+            "identify_high_definition_calls_in_call_log_bool";
+
+    /**
+     * Flag specifying whether to use the {@link ServiceState} roaming status, which can be
+     * affected by other carrier configs (e.g.
+     * {@link #KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY}), when setting the SPN display.
+     * <p>
+     * If {@code true}, the SPN display uses {@link ServiceState#getRoaming}.
+     * If {@code false} the SPN display checks if the current MCC/MNC is different from the
+     * SIM card's MCC/MNC.
+     *
+     * @see KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY
+     * @see KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY
+     * @see KEY_NON_ROAMING_OPERATOR_STRING_ARRAY
+     * @see KEY_ROAMING_OPERATOR_STRING_ARRAY
+     * @see KEY_FORCE_HOME_NETWORK_BOOL
+     *
+     * @hide
+     */
+    public static final String KEY_SPN_DISPLAY_RULE_USE_ROAMING_FROM_SERVICE_STATE_BOOL =
+            "spn_display_rule_use_roaming_from_service_state_bool";
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -1517,7 +1665,8 @@
         sDefaults.putBoolean(KEY_NOTIFY_HANDOVER_VIDEO_FROM_WIFI_TO_LTE_BOOL, false);
         sDefaults.putBoolean(KEY_SUPPORT_DOWNGRADE_VT_TO_AUDIO_BOOL, true);
         sDefaults.putString(KEY_DEFAULT_VM_NUMBER_STRING, "");
-        sDefaults.putBoolean(KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS, false);
+        sDefaults.putBoolean(KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS, true);
+        sDefaults.putBoolean(KEY_VILTE_DATA_IS_METERED_BOOL, true);
         sDefaults.putBoolean(KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL, false);
         sDefaults.putBoolean(KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, false);
         sDefaults.putBoolean(KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL, false);
@@ -1558,6 +1707,7 @@
         sDefaults.putBoolean(KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL, false);
         sDefaults.putBoolean(KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL, true);
         sDefaults.putBoolean(KEY_USE_HFA_FOR_PROVISIONING_BOOL, false);
+        sDefaults.putBoolean(KEY_EDITABLE_VOICEMAIL_NUMBER_SETTING_BOOL, true);
         sDefaults.putBoolean(KEY_EDITABLE_VOICEMAIL_NUMBER_BOOL, false);
         sDefaults.putBoolean(KEY_USE_OTASP_FOR_PROVISIONING_BOOL, false);
         sDefaults.putBoolean(KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL, false);
@@ -1638,6 +1788,7 @@
         sDefaults.putBoolean(KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL, true);
         sDefaults.putBoolean(KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true);
         sDefaults.putBoolean(KEY_HIDE_ENHANCED_4G_LTE_BOOL, false);
+        sDefaults.putBoolean(KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL, true);
         sDefaults.putBoolean(KEY_HIDE_IMS_APN_BOOL, false);
         sDefaults.putBoolean(KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL, false);
         sDefaults.putBoolean(KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL, false);
@@ -1652,6 +1803,7 @@
         sDefaults.putString(KEY_CARRIER_NAME_STRING, "");
         sDefaults.putBoolean(KEY_SUPPORT_DIRECT_FDN_DIALING_BOOL, false);
         sDefaults.putBoolean(KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL, false);
+        sDefaults.putBoolean(KEY_SKIP_CF_FAIL_TO_DISABLE_DIALOG_BOOL, false);
 
         // MMS defaults
         sDefaults.putBoolean(KEY_MMS_ALIAS_ENABLED_BOOL, false);
@@ -1697,7 +1849,6 @@
         sDefaults.putStringArray(KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
                 new String[]{
                         "com.android.carrierdefaultapp/.CarrierDefaultBroadcastReceiver:" +
-                                "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED," +
                                 "com.android.internal.telephony.CARRIER_SIGNAL_RESET"
                 });
         sDefaults.putStringArray(KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY, null);
@@ -1706,12 +1857,22 @@
         // Default carrier app configurations
         sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_REDIRECTION_STRING_ARRAY,
                 new String[]{
-                        "4, 1"
+                        "9, 4, 1"
+                        //9: CARRIER_ACTION_REGISTER_NETWORK_AVAIL
                         //4: CARRIER_ACTION_DISABLE_METERED_APNS
                         //1: CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION
                 });
         sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET, new String[]{
-                "6" //6: CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS
+                "6, 8"
+                //6: CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS
+                //8: CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER
+                });
+        sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE,
+                new String[] {
+                        String.valueOf(false) + ": 7",
+                        //7: CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER
+                        String.valueOf(true) + ": 8"
+                        //8: CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER
                 });
         sDefaults.putStringArray(KEY_CARRIER_DEFAULT_REDIRECTION_URL_STRING_ARRAY, null);
 
@@ -1730,6 +1891,7 @@
         sDefaults.putBoolean(KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL, true);
         sDefaults.putBoolean(KEY_WIFI_CALLS_CAN_BE_HD_AUDIO, true);
         sDefaults.putBoolean(KEY_VIDEO_CALLS_CAN_BE_HD_AUDIO, true);
+        sDefaults.putBoolean(KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL, true);
 
         sDefaults.putStringArray(KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY, null);
         sDefaults.putBoolean(KEY_ENHANCED_4G_LTE_TITLE_VARIANT_BOOL, false);
@@ -1742,17 +1904,27 @@
         sDefaults.putInt(KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT, -1);
         sDefaults.putBoolean(KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL, true);
         sDefaults.putBoolean(KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL, true);
+        sDefaults.putBoolean(KEY_DISPLAY_VOICEMAIL_NUMBER_AS_DEFAULT_CALL_FORWARDING_NUMBER_BOOL,
+                false);
         sDefaults.putBoolean(KEY_NOTIFY_INTERNATIONAL_CALL_ON_WFC_BOOL, false);
         sDefaults.putBoolean(KEY_EDITABLE_TETHER_APN_BOOL, false);
         sDefaults.putStringArray(KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY,
                 null);
         sDefaults.putInt(KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0);
         sDefaults.putStringArray(KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY, null);
+        sDefaults.putBoolean(KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL, false);
         sDefaults.putBoolean(KEY_DISABLE_VOICE_BARRING_NOTIFICATION_BOOL, false);
-	sDefaults.putStringArray(KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, null);
-        sDefaults.putStringArray(KEY_ROAMING_OPERATOR_STRING_ARRAY, null);
         sDefaults.putInt(IMSI_KEY_EXPIRATION_DAYS_TIME_INT, IMSI_ENCRYPTION_DAYS_TIME_DISABLED);
         sDefaults.putString(IMSI_KEY_DOWNLOAD_URL_STRING, null);
+        sDefaults.putBoolean(KEY_CONVERT_CDMA_CALLER_ID_MMI_CODES_WHILE_ROAMING_ON_3GPP_BOOL,
+                false);
+        sDefaults.putStringArray(KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, null);
+        sDefaults.putStringArray(KEY_ROAMING_OPERATOR_STRING_ARRAY, null);
+        sDefaults.putBoolean(KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false);
+        sDefaults.putBoolean(KEY_DISABLE_CHARGE_INDICATION_BOOL, false);
+        sDefaults.putStringArray(KEY_FEATURE_ACCESS_CODES_STRING_ARRAY, null);
+        sDefaults.putBoolean(KEY_IDENTIFY_HIGH_DEFINITION_CALLS_IN_CALL_LOG_BOOL, false);
+        sDefaults.putBoolean(KEY_SPN_DISPLAY_RULE_USE_ROAMING_FROM_SERVICE_STATE_BOOL, false);
     }
 
     /**
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index b39b4c7..ddc938e 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -19,6 +19,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.Rlog;
+import android.text.TextUtils;
 
 import java.util.Objects;
 
@@ -50,6 +51,10 @@
      * to +90 degrees).
      */
     private final int mLatitude;
+    // long alpha Operator Name String or Enhanced Operator Name String
+    private final String mAlphaLong;
+    // short alpha Operator Name String or Enhanced Operator Name String
+    private final String mAlphaShort;
 
     /**
      * @hide
@@ -60,6 +65,8 @@
         mBasestationId = Integer.MAX_VALUE;
         mLongitude = Integer.MAX_VALUE;
         mLatitude = Integer.MAX_VALUE;
+        mAlphaLong = null;
+        mAlphaShort = null;
     }
 
     /**
@@ -75,19 +82,37 @@
      * @hide
      */
     public CellIdentityCdma (int nid, int sid, int bid, int lon, int lat) {
+        this(nid, sid, bid, lon, lat, null, null);
+    }
+
+    /**
+     * public constructor
+     * @param nid Network Id 0..65535
+     * @param sid CDMA System Id 0..32767
+     * @param bid Base Station Id 0..65535
+     * @param lon Longitude is a decimal number ranges from -2592000
+     *        to 2592000
+     * @param lat Latitude is a decimal number ranges from -1296000
+     *        to 1296000
+     * @param alphal long alpha Operator Name String or Enhanced Operator Name String
+     * @param alphas short alpha Operator Name String or Enhanced Operator Name String
+     *
+     * @hide
+     */
+    public CellIdentityCdma (int nid, int sid, int bid, int lon, int lat, String alphal,
+                             String alphas) {
         mNetworkId = nid;
         mSystemId = sid;
         mBasestationId = bid;
         mLongitude = lon;
         mLatitude = lat;
+        mAlphaLong = alphal;
+        mAlphaShort = alphas;
     }
 
     private CellIdentityCdma(CellIdentityCdma cid) {
-        mNetworkId = cid.mNetworkId;
-        mSystemId = cid.mSystemId;
-        mBasestationId = cid.mBasestationId;
-        mLongitude = cid.mLongitude;
-        mLatitude = cid.mLatitude;
+        this(cid.mNetworkId, cid.mSystemId, cid.mBasestationId, cid.mLongitude, cid.mLatitude,
+                cid.mAlphaLong, cid.mAlphaShort);
     }
 
     CellIdentityCdma copy() {
@@ -137,9 +162,26 @@
         return mLatitude;
     }
 
+    /**
+     * @return The long alpha tag associated with the current scan result (may be the operator
+     * name string or extended operator name string). May be null if unknown.
+     */
+    public CharSequence getOperatorAlphaLong() {
+        return mAlphaLong;
+    }
+
+    /**
+     * @return The short alpha tag associated with the current scan result (may be the operator
+     * name string or extended operator name string).  May be null if unknown.
+     */
+    public CharSequence getOperatorAlphaShort() {
+        return mAlphaShort;
+    }
+
     @Override
     public int hashCode() {
-        return Objects.hash(mNetworkId, mSystemId, mBasestationId, mLatitude, mLongitude);
+        return Objects.hash(mNetworkId, mSystemId, mBasestationId, mLatitude, mLongitude,
+                mAlphaLong, mAlphaShort);
     }
 
     @Override
@@ -153,11 +195,14 @@
         }
 
         CellIdentityCdma o = (CellIdentityCdma) other;
+
         return mNetworkId == o.mNetworkId &&
                 mSystemId == o.mSystemId &&
                 mBasestationId == o.mBasestationId &&
                 mLatitude == o.mLatitude &&
-                mLongitude == o.mLongitude;
+                mLongitude == o.mLongitude &&
+                TextUtils.equals(mAlphaLong, o.mAlphaLong) &&
+                TextUtils.equals(mAlphaShort, o.mAlphaShort);
     }
 
     @Override
@@ -168,6 +213,8 @@
         sb.append(" mBasestationId="); sb.append(mBasestationId);
         sb.append(" mLongitude="); sb.append(mLongitude);
         sb.append(" mLatitude="); sb.append(mLatitude);
+        sb.append(" mAlphaLong="); sb.append(mAlphaLong);
+        sb.append(" mAlphaShort="); sb.append(mAlphaShort);
         sb.append("}");
 
         return sb.toString();
@@ -188,15 +235,15 @@
         dest.writeInt(mBasestationId);
         dest.writeInt(mLongitude);
         dest.writeInt(mLatitude);
+        dest.writeString(mAlphaLong);
+        dest.writeString(mAlphaShort);
     }
 
     /** Construct from Parcel, type has already been processed */
     private CellIdentityCdma(Parcel in) {
-        mNetworkId = in.readInt();
-        mSystemId = in.readInt();
-        mBasestationId = in.readInt();
-        mLongitude = in.readInt();
-        mLatitude = in.readInt();
+        this(in.readInt(), in.readInt(), in.readInt(), in.readInt(), in.readInt(),
+                in.readString(), in.readString());
+
         if (DBG) log("CellIdentityCdma(Parcel): " + toString());
     }
 
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index ec008e2..c9684062 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -19,6 +19,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.Rlog;
+import android.text.TextUtils;
 
 import java.util.Objects;
 
@@ -30,10 +31,6 @@
     private static final String LOG_TAG = "CellIdentityGsm";
     private static final boolean DBG = false;
 
-    // 3-digit Mobile Country Code, 0..999
-    private final int mMcc;
-    // 2 or 3-digit Mobile Network Code, 0..999
-    private final int mMnc;
     // 16-bit Location Area Code, 0..65535
     private final int mLac;
     // 16-bit GSM Cell Identity described in TS 27.007, 0..65535
@@ -42,17 +39,27 @@
     private final int mArfcn;
     // 6-bit Base Station Identity Code
     private final int mBsic;
+    // 3-digit Mobile Country Code in string format
+    private final String mMccStr;
+    // 2 or 3-digit Mobile Network Code in string format
+    private final String mMncStr;
+    // long alpha Operator Name String or Enhanced Operator Name String
+    private final String mAlphaLong;
+    // short alpha Operator Name String or Enhanced Operator Name String
+    private final String mAlphaShort;
 
     /**
      * @hide
      */
     public CellIdentityGsm() {
-        mMcc = Integer.MAX_VALUE;
-        mMnc = Integer.MAX_VALUE;
         mLac = Integer.MAX_VALUE;
         mCid = Integer.MAX_VALUE;
         mArfcn = Integer.MAX_VALUE;
         mBsic = Integer.MAX_VALUE;
+        mMccStr = null;
+        mMncStr = null;
+        mAlphaLong = null;
+        mAlphaShort = null;
     }
     /**
      * public constructor
@@ -64,7 +71,8 @@
      * @hide
      */
     public CellIdentityGsm (int mcc, int mnc, int lac, int cid) {
-        this(mcc, mnc, lac, cid, Integer.MAX_VALUE, Integer.MAX_VALUE);
+        this(lac, cid, Integer.MAX_VALUE, Integer.MAX_VALUE,
+                String.valueOf(mcc), String.valueOf(mnc), null, null);
     }
 
     /**
@@ -79,39 +87,85 @@
      * @hide
      */
     public CellIdentityGsm (int mcc, int mnc, int lac, int cid, int arfcn, int bsic) {
-        mMcc = mcc;
-        mMnc = mnc;
+        this(lac, cid, arfcn, bsic, String.valueOf(mcc), String.valueOf(mnc), null, null);
+    }
+
+    /**
+     * public constructor
+     * @param lac 16-bit Location Area Code, 0..65535
+     * @param cid 16-bit GSM Cell Identity or 28-bit UMTS Cell Identity
+     * @param arfcn 16-bit GSM Absolute RF Channel Number
+     * @param bsic 6-bit Base Station Identity Code
+     * @param mccStr 3-digit Mobile Country Code in string format
+     * @param mncStr 2 or 3-digit Mobile Network Code in string format
+     * @param alphal long alpha Operator Name String or Enhanced Operator Name String
+     * @param alphas short alpha Operator Name String or Enhanced Operator Name String
+     *
+     * @hide
+     */
+    public CellIdentityGsm (int lac, int cid, int arfcn, int bsic, String mccStr,
+                            String mncStr, String alphal, String alphas) {
         mLac = lac;
         mCid = cid;
         mArfcn = arfcn;
-        mBsic = bsic;
+        // In RIL BSIC is a UINT8, so 0xFF is the 'INVALID' designator
+        // for inbound parcels
+        mBsic = (bsic == 0xFF) ? Integer.MAX_VALUE : bsic;
+
+        // Only allow INT_MAX if unknown string mcc/mnc
+        if (mccStr == null || mccStr.matches("^[0-9]{3}$")) {
+            mMccStr = mccStr;
+        } else if (mccStr.isEmpty() || mccStr.equals(String.valueOf(Integer.MAX_VALUE))) {
+            // If the mccStr is empty or unknown, set it as null.
+            mMccStr = null;
+        } else {
+            // TODO: b/69384059 Should throw IllegalArgumentException for the invalid MCC format
+            // after the bug got fixed.
+            mMccStr = null;
+            log("invalid MCC format: " + mccStr);
+        }
+
+        if (mncStr == null || mncStr.matches("^[0-9]{2,3}$")) {
+            mMncStr = mncStr;
+        } else if (mncStr.isEmpty() || mncStr.equals(String.valueOf(Integer.MAX_VALUE))) {
+            // If the mncStr is empty or unknown, set it as null.
+            mMncStr = null;
+        } else {
+            // TODO: b/69384059 Should throw IllegalArgumentException for the invalid MNC format
+            // after the bug got fixed.
+            mMncStr = null;
+            log("invalid MNC format: " + mncStr);
+        }
+
+        mAlphaLong = alphal;
+        mAlphaShort = alphas;
     }
 
     private CellIdentityGsm(CellIdentityGsm cid) {
-        mMcc = cid.mMcc;
-        mMnc = cid.mMnc;
-        mLac = cid.mLac;
-        mCid = cid.mCid;
-        mArfcn = cid.mArfcn;
-        mBsic = cid.mBsic;
+        this(cid.mLac, cid.mCid, cid.mArfcn, cid.mBsic, cid.mMccStr,
+                cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort);
     }
 
     CellIdentityGsm copy() {
-       return new CellIdentityGsm(this);
+        return new CellIdentityGsm(this);
     }
 
     /**
      * @return 3-digit Mobile Country Code, 0..999, Integer.MAX_VALUE if unknown
+     * @deprecated Use {@link #getMccStr} instead.
      */
+    @Deprecated
     public int getMcc() {
-        return mMcc;
+        return (mMccStr != null) ? Integer.valueOf(mMccStr) : Integer.MAX_VALUE;
     }
 
     /**
      * @return 2 or 3-digit Mobile Network Code, 0..999, Integer.MAX_VALUE if unknown
+     * @deprecated Use {@link #getMncStr} instead.
      */
+    @Deprecated
     public int getMnc() {
-        return mMnc;
+        return (mMncStr != null) ? Integer.valueOf(mMncStr) : Integer.MAX_VALUE;
     }
 
     /**
@@ -144,6 +198,43 @@
         return mBsic;
     }
 
+    /**
+     * @return a 5 or 6 character string (MCC+MNC), null if any field is unknown
+     */
+    public String getMobileNetworkOperator() {
+        return (mMncStr == null || mMncStr == null) ? null : mMccStr + mMncStr;
+    }
+
+    /**
+     * @return Mobile Country Code in string format, null if unknown
+     */
+    public String getMccStr() {
+        return mMccStr;
+    }
+
+    /**
+     * @return Mobile Network Code in string format, null if unknown
+     */
+    public String getMncStr() {
+        return mMncStr;
+    }
+
+    /**
+     * @return The long alpha tag associated with the current scan result (may be the operator
+     * name string or extended operator name string). May be null if unknown.
+     */
+    public CharSequence getOperatorAlphaLong() {
+        return mAlphaLong;
+    }
+
+    /**
+     * @return The short alpha tag associated with the current scan result (may be the operator
+     * name string or extended operator name string).  May be null if unknown.
+     */
+    public CharSequence getOperatorAlphaShort() {
+        return mAlphaShort;
+    }
+
 
     /**
      * @return Integer.MAX_VALUE, undefined for GSM
@@ -155,7 +246,7 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mMcc, mMnc, mLac, mCid);
+        return Objects.hash(mMccStr, mMncStr, mLac, mCid, mAlphaLong, mAlphaShort);
     }
 
     @Override
@@ -169,23 +260,27 @@
         }
 
         CellIdentityGsm o = (CellIdentityGsm) other;
-        return mMcc == o.mMcc &&
-                mMnc == o.mMnc &&
-                mLac == o.mLac &&
+        return mLac == o.mLac &&
                 mCid == o.mCid &&
                 mArfcn == o.mArfcn &&
-                mBsic == o.mBsic;
+                mBsic == o.mBsic &&
+                TextUtils.equals(mMccStr, o.mMccStr) &&
+                TextUtils.equals(mMncStr, o.mMncStr) &&
+                TextUtils.equals(mAlphaLong, o.mAlphaLong) &&
+                TextUtils.equals(mAlphaShort, o.mAlphaShort);
     }
 
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder("CellIdentityGsm:{");
-        sb.append(" mMcc=").append(mMcc);
-        sb.append(" mMnc=").append(mMnc);
         sb.append(" mLac=").append(mLac);
         sb.append(" mCid=").append(mCid);
         sb.append(" mArfcn=").append(mArfcn);
         sb.append(" mBsic=").append("0x").append(Integer.toHexString(mBsic));
+        sb.append(" mMcc=").append(mMccStr);
+        sb.append(" mMnc=").append(mMncStr);
+        sb.append(" mAlphaLong=").append(mAlphaLong);
+        sb.append(" mAlphaShort=").append(mAlphaShort);
         sb.append("}");
 
         return sb.toString();
@@ -201,26 +296,20 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         if (DBG) log("writeToParcel(Parcel, int): " + toString());
-        dest.writeInt(mMcc);
-        dest.writeInt(mMnc);
         dest.writeInt(mLac);
         dest.writeInt(mCid);
         dest.writeInt(mArfcn);
         dest.writeInt(mBsic);
+        dest.writeString(mMccStr);
+        dest.writeString(mMncStr);
+        dest.writeString(mAlphaLong);
+        dest.writeString(mAlphaShort);
     }
 
     /** Construct from Parcel, type has already been processed */
     private CellIdentityGsm(Parcel in) {
-        mMcc = in.readInt();
-        mMnc = in.readInt();
-        mLac = in.readInt();
-        mCid = in.readInt();
-        mArfcn = in.readInt();
-        int bsic = in.readInt();
-        // In RIL BSIC is a UINT8, so 0xFF is the 'INVALID' designator
-        // for inbound parcels
-        if (bsic == 0xFF) bsic = Integer.MAX_VALUE;
-        mBsic = bsic;
+        this(in.readInt(), in.readInt(), in.readInt(), in.readInt(), in.readString(),
+                in.readString(), in.readString(), in.readString());
 
         if (DBG) log("CellIdentityGsm(Parcel): " + toString());
     }
@@ -229,16 +318,16 @@
     @SuppressWarnings("hiding")
     public static final Creator<CellIdentityGsm> CREATOR =
             new Creator<CellIdentityGsm>() {
-        @Override
-        public CellIdentityGsm createFromParcel(Parcel in) {
-            return new CellIdentityGsm(in);
-        }
+                @Override
+                public CellIdentityGsm createFromParcel(Parcel in) {
+                    return new CellIdentityGsm(in);
+                }
 
-        @Override
-        public CellIdentityGsm[] newArray(int size) {
-            return new CellIdentityGsm[size];
-        }
-    };
+                @Override
+                public CellIdentityGsm[] newArray(int size) {
+                    return new CellIdentityGsm[size];
+                }
+            };
 
     /**
      * log
@@ -246,4 +335,4 @@
     private static void log(String s) {
         Rlog.w(LOG_TAG, s);
     }
-}
+}
\ No newline at end of file
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index ce74383..825dcc3 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -19,6 +19,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.Rlog;
+import android.text.TextUtils;
 
 import java.util.Objects;
 
@@ -30,10 +31,6 @@
     private static final String LOG_TAG = "CellIdentityLte";
     private static final boolean DBG = false;
 
-    // 3-digit Mobile Country Code, 0..999
-    private final int mMcc;
-    // 2 or 3-digit Mobile Network Code, 0..999
-    private final int mMnc;
     // 28-bit cell identity
     private final int mCi;
     // physical cell id 0..503
@@ -42,17 +39,27 @@
     private final int mTac;
     // 18-bit Absolute RF Channel Number
     private final int mEarfcn;
+    // 3-digit Mobile Country Code in string format
+    private final String mMccStr;
+    // 2 or 3-digit Mobile Network Code in string format
+    private final String mMncStr;
+    // long alpha Operator Name String or Enhanced Operator Name String
+    private final String mAlphaLong;
+    // short alpha Operator Name String or Enhanced Operator Name String
+    private final String mAlphaShort;
 
     /**
      * @hide
      */
     public CellIdentityLte() {
-        mMcc = Integer.MAX_VALUE;
-        mMnc = Integer.MAX_VALUE;
         mCi = Integer.MAX_VALUE;
         mPci = Integer.MAX_VALUE;
         mTac = Integer.MAX_VALUE;
         mEarfcn = Integer.MAX_VALUE;
+        mMccStr = null;
+        mMncStr = null;
+        mAlphaLong = null;
+        mAlphaShort = null;
     }
 
     /**
@@ -66,7 +73,7 @@
      * @hide
      */
     public CellIdentityLte (int mcc, int mnc, int ci, int pci, int tac) {
-        this(mcc, mnc, ci, pci, tac, Integer.MAX_VALUE);
+        this(ci, pci, tac, Integer.MAX_VALUE, String.valueOf(mcc), String.valueOf(mnc), null, null);
     }
 
     /**
@@ -81,21 +88,61 @@
      * @hide
      */
     public CellIdentityLte (int mcc, int mnc, int ci, int pci, int tac, int earfcn) {
-        mMcc = mcc;
-        mMnc = mnc;
+        this(ci, pci, tac, earfcn, String.valueOf(mcc), String.valueOf(mnc), null, null);
+    }
+
+    /**
+     *
+     * @param ci 28-bit Cell Identity
+     * @param pci Physical Cell Id 0..503
+     * @param tac 16-bit Tracking Area Code
+     * @param earfcn 18-bit LTE Absolute RF Channel Number
+     * @param mccStr 3-digit Mobile Country Code in string format
+     * @param mncStr 2 or 3-digit Mobile Network Code in string format
+     * @param alphal long alpha Operator Name String or Enhanced Operator Name String
+     * @param alphas short alpha Operator Name String or Enhanced Operator Name String
+     *
+     * @hide
+     */
+    public CellIdentityLte (int ci, int pci, int tac, int earfcn, String mccStr,
+                            String mncStr, String alphal, String alphas) {
         mCi = ci;
         mPci = pci;
         mTac = tac;
         mEarfcn = earfcn;
+
+        // Only allow INT_MAX if unknown string mcc/mnc
+        if (mccStr == null || mccStr.matches("^[0-9]{3}$")) {
+            mMccStr = mccStr;
+        } else if (mccStr.isEmpty() || mccStr.equals(String.valueOf(Integer.MAX_VALUE))) {
+            // If the mccStr is empty or unknown, set it as null.
+            mMccStr = null;
+        } else {
+            // TODO: b/69384059 Should throw IllegalArgumentException for the invalid MCC format
+            // after the bug got fixed.
+            mMccStr = null;
+            log("invalid MCC format: " + mccStr);
+        }
+
+        if (mncStr == null || mncStr.matches("^[0-9]{2,3}$")) {
+            mMncStr = mncStr;
+        } else if (mncStr.isEmpty() || mncStr.equals(String.valueOf(Integer.MAX_VALUE))) {
+            // If the mncStr is empty or unknown, set it as null.
+            mMncStr = null;
+        } else {
+            // TODO: b/69384059 Should throw IllegalArgumentException for the invalid MNC format
+            // after the bug got fixed.
+            mMncStr = null;
+            log("invalid MNC format: " + mncStr);
+        }
+
+        mAlphaLong = alphal;
+        mAlphaShort = alphas;
     }
 
     private CellIdentityLte(CellIdentityLte cid) {
-        mMcc = cid.mMcc;
-        mMnc = cid.mMnc;
-        mCi = cid.mCi;
-        mPci = cid.mPci;
-        mTac = cid.mTac;
-        mEarfcn = cid.mEarfcn;
+        this(cid.mCi, cid.mPci, cid.mTac, cid.mEarfcn, cid.mMccStr,
+                cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort);
     }
 
     CellIdentityLte copy() {
@@ -104,16 +151,20 @@
 
     /**
      * @return 3-digit Mobile Country Code, 0..999, Integer.MAX_VALUE if unknown
+     * @deprecated Use {@link #getMccStr} instead.
      */
+    @Deprecated
     public int getMcc() {
-        return mMcc;
+        return (mMccStr != null) ? Integer.valueOf(mMccStr) : Integer.MAX_VALUE;
     }
 
     /**
      * @return 2 or 3-digit Mobile Network Code, 0..999, Integer.MAX_VALUE if unknown
+     * @deprecated Use {@link #getMncStr} instead.
      */
+    @Deprecated
     public int getMnc() {
-        return mMnc;
+        return (mMncStr != null) ? Integer.valueOf(mMncStr) : Integer.MAX_VALUE;
     }
 
     /**
@@ -144,9 +195,46 @@
         return mEarfcn;
     }
 
+    /**
+     * @return Mobile Country Code in string format, null if unknown
+     */
+    public String getMccStr() {
+        return mMccStr;
+    }
+
+    /**
+     * @return Mobile Network Code in string format, null if unknown
+     */
+    public String getMncStr() {
+        return mMncStr;
+    }
+
+    /**
+     * @return a 5 or 6 character string (MCC+MNC), null if any field is unknown
+     */
+    public String getMobileNetworkOperator() {
+        return (mMncStr == null || mMncStr == null) ? null : mMccStr + mMncStr;
+    }
+
+    /**
+     * @return The long alpha tag associated with the current scan result (may be the operator
+     * name string or extended operator name string). May be null if unknown.
+     */
+    public CharSequence getOperatorAlphaLong() {
+        return mAlphaLong;
+    }
+
+    /**
+     * @return The short alpha tag associated with the current scan result (may be the operator
+     * name string or extended operator name string).  May be null if unknown.
+     */
+    public CharSequence getOperatorAlphaShort() {
+        return mAlphaShort;
+    }
+
     @Override
     public int hashCode() {
-        return Objects.hash(mMcc, mMnc, mCi, mPci, mTac);
+        return Objects.hash(mMccStr, mMncStr, mCi, mPci, mTac, mAlphaLong, mAlphaShort);
     }
 
     @Override
@@ -160,23 +248,27 @@
         }
 
         CellIdentityLte o = (CellIdentityLte) other;
-        return mMcc == o.mMcc &&
-                mMnc == o.mMnc &&
-                mCi == o.mCi &&
+        return mCi == o.mCi &&
                 mPci == o.mPci &&
                 mTac == o.mTac &&
-                mEarfcn == o.mEarfcn;
+                mEarfcn == o.mEarfcn &&
+                TextUtils.equals(mMccStr, o.mMccStr) &&
+                TextUtils.equals(mMncStr, o.mMncStr) &&
+                TextUtils.equals(mAlphaLong, o.mAlphaLong) &&
+                TextUtils.equals(mAlphaShort, o.mAlphaShort);
     }
 
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder("CellIdentityLte:{");
-        sb.append(" mMcc="); sb.append(mMcc);
-        sb.append(" mMnc="); sb.append(mMnc);
         sb.append(" mCi="); sb.append(mCi);
         sb.append(" mPci="); sb.append(mPci);
         sb.append(" mTac="); sb.append(mTac);
         sb.append(" mEarfcn="); sb.append(mEarfcn);
+        sb.append(" mMcc="); sb.append(mMccStr);
+        sb.append(" mMnc="); sb.append(mMncStr);
+        sb.append(" mAlphaLong="); sb.append(mAlphaLong);
+        sb.append(" mAlphaShort="); sb.append(mAlphaShort);
         sb.append("}");
 
         return sb.toString();
@@ -192,22 +284,21 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         if (DBG) log("writeToParcel(Parcel, int): " + toString());
-        dest.writeInt(mMcc);
-        dest.writeInt(mMnc);
         dest.writeInt(mCi);
         dest.writeInt(mPci);
         dest.writeInt(mTac);
         dest.writeInt(mEarfcn);
+        dest.writeString(mMccStr);
+        dest.writeString(mMncStr);
+        dest.writeString(mAlphaLong);
+        dest.writeString(mAlphaShort);
     }
 
     /** Construct from Parcel, type has already been processed */
     private CellIdentityLte(Parcel in) {
-        mMcc = in.readInt();
-        mMnc = in.readInt();
-        mCi = in.readInt();
-        mPci = in.readInt();
-        mTac = in.readInt();
-        mEarfcn = in.readInt();
+        this(in.readInt(), in.readInt(), in.readInt(), in.readInt(), in.readString(),
+                in.readString(), in.readString(), in.readString());
+
         if (DBG) log("CellIdentityLte(Parcel): " + toString());
     }
 
@@ -215,16 +306,16 @@
     @SuppressWarnings("hiding")
     public static final Creator<CellIdentityLte> CREATOR =
             new Creator<CellIdentityLte>() {
-        @Override
-        public CellIdentityLte createFromParcel(Parcel in) {
-            return new CellIdentityLte(in);
-        }
+                @Override
+                public CellIdentityLte createFromParcel(Parcel in) {
+                    return new CellIdentityLte(in);
+                }
 
-        @Override
-        public CellIdentityLte[] newArray(int size) {
-            return new CellIdentityLte[size];
-        }
-    };
+                @Override
+                public CellIdentityLte[] newArray(int size) {
+                    return new CellIdentityLte[size];
+                }
+            };
 
     /**
      * log
@@ -232,4 +323,4 @@
     private static void log(String s) {
         Rlog.w(LOG_TAG, s);
     }
-}
+}
\ No newline at end of file
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index 0d13efd..e74b570 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -19,6 +19,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.Rlog;
+import android.text.TextUtils;
 
 import java.util.Objects;
 
@@ -30,10 +31,6 @@
     private static final String LOG_TAG = "CellIdentityWcdma";
     private static final boolean DBG = false;
 
-    // 3-digit Mobile Country Code, 0..999
-    private final int mMcc;
-    // 2 or 3-digit Mobile Network Code, 0..999
-    private final int mMnc;
     // 16-bit Location Area Code, 0..65535
     private final int mLac;
     // 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455
@@ -42,17 +39,27 @@
     private final int mPsc;
     // 16-bit UMTS Absolute RF Channel Number
     private final int mUarfcn;
+    // 3-digit Mobile Country Code in string format
+    private final String mMccStr;
+    // 2 or 3-digit Mobile Network Code in string format
+    private final String mMncStr;
+    // long alpha Operator Name String or Enhanced Operator Name String
+    private final String mAlphaLong;
+    // short alpha Operator Name String or Enhanced Operator Name String
+    private final String mAlphaShort;
 
     /**
      * @hide
      */
     public CellIdentityWcdma() {
-        mMcc = Integer.MAX_VALUE;
-        mMnc = Integer.MAX_VALUE;
         mLac = Integer.MAX_VALUE;
         mCid = Integer.MAX_VALUE;
         mPsc = Integer.MAX_VALUE;
         mUarfcn = Integer.MAX_VALUE;
+        mMccStr = null;
+        mMncStr = null;
+        mAlphaLong = null;
+        mAlphaShort = null;
     }
     /**
      * public constructor
@@ -65,7 +72,8 @@
      * @hide
      */
     public CellIdentityWcdma (int mcc, int mnc, int lac, int cid, int psc) {
-        this(mcc, mnc, lac, cid, psc, Integer.MAX_VALUE);
+        this(lac, cid, psc, Integer.MAX_VALUE, String.valueOf(mcc), String.valueOf(mnc),
+                null, null);
     }
 
     /**
@@ -80,39 +88,83 @@
      * @hide
      */
     public CellIdentityWcdma (int mcc, int mnc, int lac, int cid, int psc, int uarfcn) {
-        mMcc = mcc;
-        mMnc = mnc;
+        this(lac, cid, psc, uarfcn, String.valueOf(mcc), String.valueOf(mnc), null, null);
+    }
+
+    /**
+     * public constructor
+     * @param lac 16-bit Location Area Code, 0..65535
+     * @param cid 28-bit UMTS Cell Identity
+     * @param psc 9-bit UMTS Primary Scrambling Code
+     * @param uarfcn 16-bit UMTS Absolute RF Channel Number
+     * @param mccStr 3-digit Mobile Country Code in string format
+     * @param mncStr 2 or 3-digit Mobile Network Code in string format
+     * @param alphal long alpha Operator Name String or Enhanced Operator Name String
+     * @param alphas short alpha Operator Name String or Enhanced Operator Name String
+     *
+     * @hide
+     */
+    public CellIdentityWcdma (int lac, int cid, int psc, int uarfcn,
+                              String mccStr, String mncStr, String alphal, String alphas) {
         mLac = lac;
         mCid = cid;
         mPsc = psc;
         mUarfcn = uarfcn;
+
+        // Only allow INT_MAX if unknown string mcc/mnc
+        if (mccStr == null || mccStr.matches("^[0-9]{3}$")) {
+            mMccStr = mccStr;
+        } else if (mccStr.isEmpty() || mccStr.equals(String.valueOf(Integer.MAX_VALUE))) {
+            // If the mccStr is empty or unknown, set it as null.
+            mMccStr = null;
+        } else {
+            // TODO: b/69384059 Should throw IllegalArgumentException for the invalid MCC format
+            // after the bug got fixed.
+            mMccStr = null;
+            log("invalid MCC format: " + mccStr);
+        }
+
+        if (mncStr == null || mncStr.matches("^[0-9]{2,3}$")) {
+            mMncStr = mncStr;
+        } else if (mncStr.isEmpty() || mncStr.equals(String.valueOf(Integer.MAX_VALUE))) {
+            // If the mncStr is empty or unknown, set it as null.
+            mMncStr = null;
+        } else {
+            // TODO: b/69384059 Should throw IllegalArgumentException for the invalid MNC format
+            // after the bug got fixed.
+            mMncStr = null;
+            log("invalid MNC format: " + mncStr);
+        }
+
+        mAlphaLong = alphal;
+        mAlphaShort = alphas;
     }
 
     private CellIdentityWcdma(CellIdentityWcdma cid) {
-        mMcc = cid.mMcc;
-        mMnc = cid.mMnc;
-        mLac = cid.mLac;
-        mCid = cid.mCid;
-        mPsc = cid.mPsc;
-        mUarfcn = cid.mUarfcn;
+        this(cid.mLac, cid.mCid, cid.mPsc, cid.mUarfcn, cid.mMccStr,
+                cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort);
     }
 
     CellIdentityWcdma copy() {
-       return new CellIdentityWcdma(this);
+        return new CellIdentityWcdma(this);
     }
 
     /**
      * @return 3-digit Mobile Country Code, 0..999, Integer.MAX_VALUE if unknown
+     * @deprecated Use {@link #getMccStr} instead.
      */
+    @Deprecated
     public int getMcc() {
-        return mMcc;
+        return (mMccStr != null) ? Integer.valueOf(mMccStr) : Integer.MAX_VALUE;
     }
 
     /**
      * @return 2 or 3-digit Mobile Network Code, 0..999, Integer.MAX_VALUE if unknown
+     * @deprecated Use {@link #getMncStr} instead.
      */
+    @Deprecated
     public int getMnc() {
-        return mMnc;
+        return (mMncStr != null) ? Integer.valueOf(mMncStr) : Integer.MAX_VALUE;
     }
 
     /**
@@ -138,9 +190,46 @@
         return mPsc;
     }
 
+    /**
+     * @return Mobile Country Code in string version, null if unknown
+     */
+    public String getMccStr() {
+        return mMccStr;
+    }
+
+    /**
+     * @return Mobile Network Code in string version, null if unknown
+     */
+    public String getMncStr() {
+        return mMncStr;
+    }
+
+    /**
+     * @return a 5 or 6 character string (MCC+MNC), null if any field is unknown
+     */
+    public String getMobileNetworkOperator() {
+        return (mMncStr == null || mMncStr == null) ? null : mMccStr + mMncStr;
+    }
+
+    /**
+     * @return The long alpha tag associated with the current scan result (may be the operator
+     * name string or extended operator name string). May be null if unknown.
+     */
+    public CharSequence getOperatorAlphaLong() {
+        return mAlphaLong;
+    }
+
+    /**
+     * @return The short alpha tag associated with the current scan result (may be the operator
+     * name string or extended operator name string).  May be null if unknown.
+     */
+    public CharSequence getOperatorAlphaShort() {
+        return mAlphaShort;
+    }
+
     @Override
     public int hashCode() {
-        return Objects.hash(mMcc, mMnc, mLac, mCid, mPsc);
+        return Objects.hash(mMccStr, mMncStr, mLac, mCid, mPsc, mAlphaLong, mAlphaShort);
     }
 
     /**
@@ -161,23 +250,27 @@
         }
 
         CellIdentityWcdma o = (CellIdentityWcdma) other;
-        return mMcc == o.mMcc &&
-                mMnc == o.mMnc &&
-                mLac == o.mLac &&
+        return mLac == o.mLac &&
                 mCid == o.mCid &&
                 mPsc == o.mPsc &&
-                mUarfcn == o.mUarfcn;
+                mUarfcn == o.mUarfcn &&
+                TextUtils.equals(mMccStr, o.mMccStr) &&
+                TextUtils.equals(mMncStr, o.mMncStr) &&
+                TextUtils.equals(mAlphaLong, o.mAlphaLong) &&
+                TextUtils.equals(mAlphaShort, o.mAlphaShort);
     }
 
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder("CellIdentityWcdma:{");
-        sb.append(" mMcc=").append(mMcc);
-        sb.append(" mMnc=").append(mMnc);
         sb.append(" mLac=").append(mLac);
         sb.append(" mCid=").append(mCid);
         sb.append(" mPsc=").append(mPsc);
         sb.append(" mUarfcn=").append(mUarfcn);
+        sb.append(" mMcc=").append(mMccStr);
+        sb.append(" mMnc=").append(mMncStr);
+        sb.append(" mAlphaLong=").append(mAlphaLong);
+        sb.append(" mAlphaShort=").append(mAlphaShort);
         sb.append("}");
 
         return sb.toString();
@@ -193,22 +286,21 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         if (DBG) log("writeToParcel(Parcel, int): " + toString());
-        dest.writeInt(mMcc);
-        dest.writeInt(mMnc);
         dest.writeInt(mLac);
         dest.writeInt(mCid);
         dest.writeInt(mPsc);
         dest.writeInt(mUarfcn);
+        dest.writeString(mMccStr);
+        dest.writeString(mMncStr);
+        dest.writeString(mAlphaLong);
+        dest.writeString(mAlphaShort);
     }
 
     /** Construct from Parcel, type has already been processed */
     private CellIdentityWcdma(Parcel in) {
-        mMcc = in.readInt();
-        mMnc = in.readInt();
-        mLac = in.readInt();
-        mCid = in.readInt();
-        mPsc = in.readInt();
-        mUarfcn = in.readInt();
+        this(in.readInt(), in.readInt(), in.readInt(), in.readInt(), in.readString(),
+                in.readString(), in.readString(), in.readString());
+
         if (DBG) log("CellIdentityWcdma(Parcel): " + toString());
     }
 
@@ -216,16 +308,16 @@
     @SuppressWarnings("hiding")
     public static final Creator<CellIdentityWcdma> CREATOR =
             new Creator<CellIdentityWcdma>() {
-        @Override
-        public CellIdentityWcdma createFromParcel(Parcel in) {
-            return new CellIdentityWcdma(in);
-        }
+                @Override
+                public CellIdentityWcdma createFromParcel(Parcel in) {
+                    return new CellIdentityWcdma(in);
+                }
 
-        @Override
-        public CellIdentityWcdma[] newArray(int size) {
-            return new CellIdentityWcdma[size];
-        }
-    };
+                @Override
+                public CellIdentityWcdma[] newArray(int size) {
+                    return new CellIdentityWcdma[size];
+                }
+            };
 
     /**
      * log
@@ -233,4 +325,4 @@
     private static void log(String s) {
         Rlog.w(LOG_TAG, s);
     }
-}
+}
\ No newline at end of file
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index 9513517..c3a2ceb 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -227,13 +227,6 @@
     public static final int DATA_LIMIT_REACHED = 55;
 
     /**
-     * The emergency call was terminated because it was dialed on the wrong SIM slot.
-     * The call needs to be redialed the other slot.
-     * {@hide}
-     */
-    public static final int DIALED_ON_WRONG_SLOT = 56;
-
-    /**
      * The call being placed was detected as a call forwarding number and was being dialed while
      * roaming on a carrier that does not allow this.
      */
@@ -258,6 +251,35 @@
      */
     public static final int IMS_ACCESS_BLOCKED = 60;
 
+    /**
+     * The call has ended (mid-call) because the device's battery is too low.
+     */
+    public static final int LOW_BATTERY = 61;
+
+    /**
+     * A call was not dialed because the device's battery is too low.
+     */
+    public static final int DIAL_LOW_BATTERY = 62;
+
+    /**
+     * Emergency call failed with a temporary fail cause and can be redialed on this slot.
+     * {@hide}
+     */
+    public static final int EMERGENCY_TEMP_FAILURE = 63;
+
+    /**
+     * Emergency call failed with a permanent fail cause and should not be redialed on this
+     * slot. 
+     * {@hide}
+     */
+    public static final int EMERGENCY_PERM_FAILURE = 64;
+
+    /**
+     * This cause is used to report a normal event only when no other cause in the normal class
+     * applies.
+     * {@hide}
+     */
+    public static final int NORMAL_UNSPECIFIED = 65;
     //*********************************************************************************************
     // When adding a disconnect type:
     // 1) Update toString() with the newly added disconnect type.
@@ -382,8 +404,6 @@
             return "DATA_DISABLED";
         case DATA_LIMIT_REACHED:
             return "DATA_LIMIT_REACHED";
-        case DIALED_ON_WRONG_SLOT:
-            return "DIALED_ON_WRONG_SLOT";
         case DIALED_CALL_FORWARDING_WHILE_ROAMING:
             return "DIALED_CALL_FORWARDING_WHILE_ROAMING";
         case IMEI_NOT_ACCEPTED:
@@ -392,6 +412,16 @@
             return "WIFI_LOST";
         case IMS_ACCESS_BLOCKED:
             return "IMS_ACCESS_BLOCKED";
+        case LOW_BATTERY:
+            return "LOW_BATTERY";
+        case DIAL_LOW_BATTERY:
+            return "DIAL_LOW_BATTERY";
+        case EMERGENCY_TEMP_FAILURE:
+            return "EMERGENCY_TEMP_FAILURE";
+        case EMERGENCY_PERM_FAILURE:
+            return "EMERGENCY_PERM_FAILURE";
+        case NORMAL_UNSPECIFIED:
+            return "NORMAL_UNSPECIFIED";
         default:
             return "INVALID: " + cause;
         }
diff --git a/telephony/java/android/telephony/MbmsDownloadManager.java b/telephony/java/android/telephony/MbmsDownloadManager.java
deleted file mode 100644
index 1e8cf18..0000000
--- a/telephony/java/android/telephony/MbmsDownloadManager.java
+++ /dev/null
@@ -1,586 +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.telephony;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SdkConstant;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.net.Uri;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.telephony.mbms.DownloadProgressListener;
-import android.telephony.mbms.FileInfo;
-import android.telephony.mbms.DownloadRequest;
-import android.telephony.mbms.MbmsDownloadManagerCallback;
-import android.telephony.mbms.MbmsDownloadReceiver;
-import android.telephony.mbms.MbmsException;
-import android.telephony.mbms.MbmsTempFileProvider;
-import android.telephony.mbms.MbmsUtils;
-import android.telephony.mbms.vendor.IMbmsDownloadService;
-import android.util.Log;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
-/** @hide */
-public class MbmsDownloadManager {
-    private static final String LOG_TAG = MbmsDownloadManager.class.getSimpleName();
-
-    /** @hide */
-    // TODO: systemapi
-    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
-    public static final String MBMS_DOWNLOAD_SERVICE_ACTION =
-            "android.telephony.action.EmbmsDownload";
-
-    /**
-     * Integer extra indicating the result code of the download. One of
-     * {@link #RESULT_SUCCESSFUL}, {@link #RESULT_EXPIRED}, or {@link #RESULT_CANCELLED}.
-     */
-    public static final String EXTRA_RESULT = "android.telephony.mbms.extra.RESULT";
-
-    /**
-     * Extra containing the {@link android.telephony.mbms.FileInfo} for which the download result
-     * is for. Must not be null.
-     */
-    public static final String EXTRA_FILE_INFO = "android.telephony.mbms.extra.FILE_INFO";
-
-    /**
-     * Extra containing a single {@link Uri} indicating the location of the successfully
-     * downloaded file. Set on the intent provided via
-     * {@link android.telephony.mbms.DownloadRequest.Builder#setAppIntent(Intent)}.
-     * Will always be set to a non-null value if {@link #EXTRA_RESULT} is set to
-     * {@link #RESULT_SUCCESSFUL}.
-     */
-    public static final String EXTRA_COMPLETED_FILE_URI =
-            "android.telephony.mbms.extra.COMPLETED_FILE_URI";
-
-    public static final int RESULT_SUCCESSFUL = 1;
-    public static final int RESULT_CANCELLED = 2;
-    public static final int RESULT_EXPIRED = 3;
-    public static final int RESULT_IO_ERROR = 4;
-    // TODO - more results!
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({STATUS_UNKNOWN, STATUS_ACTIVELY_DOWNLOADING, STATUS_PENDING_DOWNLOAD,
-            STATUS_PENDING_REPAIR, STATUS_PENDING_DOWNLOAD_WINDOW})
-    public @interface DownloadStatus {}
-
-    public static final int STATUS_UNKNOWN = 0;
-    public static final int STATUS_ACTIVELY_DOWNLOADING = 1;
-    public static final int STATUS_PENDING_DOWNLOAD = 2;
-    public static final int STATUS_PENDING_REPAIR = 3;
-    public static final int STATUS_PENDING_DOWNLOAD_WINDOW = 4;
-
-    private static AtomicBoolean sIsInitialized = new AtomicBoolean(false);
-
-    private final Context mContext;
-    private int mSubscriptionId = INVALID_SUBSCRIPTION_ID;
-    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
-        @Override
-        public void binderDied() {
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, "Received death notification");
-        }
-    };
-
-    private AtomicReference<IMbmsDownloadService> mService = new AtomicReference<>(null);
-    private final MbmsDownloadManagerCallback mCallback;
-
-    private MbmsDownloadManager(Context context, MbmsDownloadManagerCallback callback, int subId) {
-        mContext = context;
-        mCallback = callback;
-        mSubscriptionId = subId;
-    }
-
-    /**
-     * Create a new MbmsDownloadManager using the system default data subscription ID.
-     * See {@link #create(Context, MbmsDownloadManagerCallback, int)}
-     *
-     * @hide
-     */
-    public static MbmsDownloadManager create(Context context,
-            MbmsDownloadManagerCallback listener)
-            throws MbmsException {
-        return create(context, listener, SubscriptionManager.getDefaultSubscriptionId());
-    }
-
-    /**
-     * Create a new MbmsDownloadManager using the given subscription ID.
-     *
-     * Note that this call will bind a remote service and that may take a bit. The instance of
-     * {@link MbmsDownloadManager} that is returned will not be ready for use until
-     * {@link MbmsDownloadManagerCallback#middlewareReady()} is called on the provided callback.
-     * If you attempt to use the manager before it is ready, a {@link MbmsException} will be thrown.
-     *
-     * This also may throw an {@link IllegalArgumentException} or an {@link IllegalStateException}.
-     *
-     * You may only have one instance of {@link MbmsDownloadManager} per UID. If you call this
-     * method while there is an active instance of {@link MbmsDownloadManager} in your process
-     * (in other words, one that has not had {@link #dispose()} called on it), this method will
-     * throw an {@link MbmsException}. If you call this method in a different process
-     * running under the same UID, an error will be indicated via
-     * {@link MbmsDownloadManagerCallback#error(int, String)}.
-     *
-     * Note that initialization may fail asynchronously. If you wish to try again after you
-     * receive such an asynchronous error, you must call dispose() on the instance of
-     * {@link MbmsDownloadManager} that you received before calling this method again.
-     *
-     * @param context The instance of {@link Context} to use
-     * @param listener A callback to get asynchronous error messages and file service updates.
-     * @param subscriptionId The data subscription ID to use
-     * @hide
-     */
-    public static MbmsDownloadManager create(Context context,
-            MbmsDownloadManagerCallback listener, int subscriptionId)
-            throws MbmsException {
-        if (!sIsInitialized.compareAndSet(false, true)) {
-            throw new MbmsException(MbmsException.InitializationErrors.ERROR_DUPLICATE_INITIALIZE);
-        }
-        MbmsDownloadManager mdm = new MbmsDownloadManager(context, listener, subscriptionId);
-        try {
-            mdm.bindAndInitialize();
-        } catch (MbmsException e) {
-            sIsInitialized.set(false);
-            throw e;
-        }
-        return mdm;
-    }
-
-    private void bindAndInitialize() throws MbmsException {
-        MbmsUtils.startBinding(mContext, MBMS_DOWNLOAD_SERVICE_ACTION,
-                new ServiceConnection() {
-                    @Override
-                    public void onServiceConnected(ComponentName name, IBinder service) {
-                        IMbmsDownloadService downloadService =
-                                IMbmsDownloadService.Stub.asInterface(service);
-                        int result;
-                        try {
-                            result = downloadService.initialize(mSubscriptionId, mCallback);
-                        } catch (RemoteException e) {
-                            Log.e(LOG_TAG, "Service died before initialization");
-                            sIsInitialized.set(false);
-                            return;
-                        } catch (RuntimeException e) {
-                            Log.e(LOG_TAG, "Runtime exception during initialization");
-                            sendErrorToApp(
-                                    MbmsException.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
-                                    e.toString());
-                            sIsInitialized.set(false);
-                            return;
-                        }
-                        if (result != MbmsException.SUCCESS) {
-                            sendErrorToApp(result, "Error returned during initialization");
-                            sIsInitialized.set(false);
-                            return;
-                        }
-                        try {
-                            downloadService.asBinder().linkToDeath(mDeathRecipient, 0);
-                        } catch (RemoteException e) {
-                            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST,
-                                    "Middleware lost during initialization");
-                            sIsInitialized.set(false);
-                            return;
-                        }
-                        mService.set(downloadService);
-                    }
-
-                    @Override
-                    public void onServiceDisconnected(ComponentName name) {
-                        sIsInitialized.set(false);
-                        mService.set(null);
-                    }
-                });
-    }
-
-    /**
-     * An inspection API to retrieve the list of available
-     * {@link android.telephony.mbms.FileServiceInfo}s currently being advertised.
-     * The results are returned asynchronously via a call to
-     * {@link MbmsDownloadManagerCallback#fileServicesUpdated(List)}
-     *
-     * The serviceClasses argument lets the app filter on types of programming and is opaque data
-     * negotiated beforehand between the app and the carrier.
-     *
-     * This may throw an {@link MbmsException} containing one of the following errors:
-     * {@link MbmsException#ERROR_MIDDLEWARE_NOT_BOUND}
-     * {@link MbmsException#ERROR_MIDDLEWARE_LOST}
-     *
-     * Asynchronous error codes via the {@link MbmsDownloadManagerCallback#error(int, String)}
-     * callback can include any of the errors except:
-     * {@link MbmsException.StreamingErrors#ERROR_UNABLE_TO_START_SERVICE}
-     *
-     * @param classList A list of service classes which the app wishes to receive
-     *                  {@link MbmsDownloadManagerCallback#fileServicesUpdated(List)} callbacks
-     *                  about. Subsequent calls to this method will replace this list of service
-     *                  classes (i.e. the middleware will no longer send updates for services
-     *                  matching classes only in the old list).
-     */
-    public void getFileServices(List<String> classList) throws MbmsException {
-        IMbmsDownloadService downloadService = mService.get();
-        if (downloadService == null) {
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND);
-        }
-        try {
-            int returnCode = downloadService.getFileServices(mSubscriptionId, classList);
-            if (returnCode != MbmsException.SUCCESS) {
-                throw new MbmsException(returnCode);
-            }
-        } catch (RemoteException e) {
-            Log.w(LOG_TAG, "Remote process died");
-            mService.set(null);
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_LOST);
-        }
-    }
-
-    /**
-     * Sets the temp file root for downloads.
-     * All temp files created for the middleware to write to will be contained in the specified
-     * directory. Applications that wish to specify a location only need to call this method once
-     * as long their data is persisted in storage -- the argument will be stored both in a
-     * local instance of {@link android.content.SharedPreferences} and by the middleware.
-     *
-     * If this method is not called at least once before calling
-     * {@link #download(DownloadRequest, DownloadProgressListener)}, the framework
-     * will default to a directory formed by the concatenation of the app's files directory and
-     * {@link android.telephony.mbms.MbmsTempFileProvider#DEFAULT_TOP_LEVEL_TEMP_DIRECTORY}.
-     *
-     * Before calling this method, the app must cancel all of its pending
-     * {@link DownloadRequest}s via {@link #cancelDownload(DownloadRequest)}. If this is not done,
-     * an {@link MbmsException} will be thrown with code
-     * {@link MbmsException.DownloadErrors#ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT} unless the
-     * provided directory is the same as what has been previously configured.
-     *
-     * The {@link File} supplied as a root temp file directory must already exist. If not, an
-     * {@link IllegalArgumentException} will be thrown.
-     * @param tempFileRootDirectory A directory to place temp files in.
-     */
-    public void setTempFileRootDirectory(@NonNull File tempFileRootDirectory)
-            throws MbmsException {
-        IMbmsDownloadService downloadService = mService.get();
-        if (downloadService == null) {
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND);
-        }
-        if (!tempFileRootDirectory.exists()) {
-            throw new IllegalArgumentException("Provided directory does not exist");
-        }
-        if (!tempFileRootDirectory.isDirectory()) {
-            throw new IllegalArgumentException("Provided File is not a directory");
-        }
-        String filePath;
-        try {
-            filePath = tempFileRootDirectory.getCanonicalPath();
-        } catch (IOException e) {
-            throw new IllegalArgumentException("Unable to canonicalize the provided path: " + e);
-        }
-
-        try {
-            int result = downloadService.setTempFileRootDirectory(mSubscriptionId, filePath);
-            if (result != MbmsException.SUCCESS) {
-                throw new MbmsException(result);
-            }
-        } catch (RemoteException e) {
-            mService.set(null);
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_LOST);
-        }
-
-        SharedPreferences prefs = mContext.getSharedPreferences(
-                MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_FILE_NAME, 0);
-        prefs.edit().putString(MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_NAME, filePath).apply();
-    }
-
-    /**
-     * Retrieves the currently configured temp file root directory. Returns the file that was
-     * configured via {@link #setTempFileRootDirectory(File)} or the default directory
-     * {@link #download(DownloadRequest, DownloadProgressListener)} was called without ever setting
-     * the temp file root. If neither method has been called since the last time the app's shared
-     * preferences were reset, returns null.
-     *
-     * @return A {@link File} pointing to the configured temp file directory, or null if not yet
-     *         configured.
-     */
-    public @Nullable File getTempFileRootDirectory() {
-        SharedPreferences prefs = mContext.getSharedPreferences(
-                MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_FILE_NAME, 0);
-        String path = prefs.getString(MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_NAME, null);
-        if (path != null) {
-            return new File(path);
-        }
-        return null;
-    }
-
-    /**
-     * Requests a download of a file that is available via multicast.
-     *
-     * downloadListener is an optional callback object which can be used to get progress reports
-     *     of a currently occuring download.  Note this can only run while the calling app
-     *     is running, so future downloads will simply result in resultIntents being sent
-     *     for completed or errored-out downloads.  A NULL indicates no callbacks are needed.
-     *
-     * May throw an {@link IllegalArgumentException}
-     *
-     * If {@link #setTempFileRootDirectory(File)} has not called after the app has been installed,
-     * this method will create a directory at the default location defined at
-     * {@link MbmsTempFileProvider#DEFAULT_TOP_LEVEL_TEMP_DIRECTORY} and store that as the temp
-     * file root directory.
-     *
-     * Asynchronous errors through the listener include any of the errors
-     *
-     * @param request The request that specifies what should be downloaded
-     * @param progressListener Optional listener that will be provided progress updates
-     *                         if the app is running.
-     */
-    public void download(DownloadRequest request, DownloadProgressListener progressListener)
-            throws MbmsException {
-        IMbmsDownloadService downloadService = mService.get();
-        if (downloadService == null) {
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND);
-        }
-
-        // Check to see whether the app's set a temp root dir yet, and set it if not.
-        SharedPreferences prefs = mContext.getSharedPreferences(
-                MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_FILE_NAME, 0);
-        if (prefs.getString(MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_NAME, null) == null) {
-            File tempRootDirectory = new File(mContext.getFilesDir(),
-                    MbmsTempFileProvider.DEFAULT_TOP_LEVEL_TEMP_DIRECTORY);
-            tempRootDirectory.mkdirs();
-            setTempFileRootDirectory(tempRootDirectory);
-        }
-
-        checkValidDownloadDestination(request);
-        writeDownloadRequestToken(request);
-        try {
-            downloadService.download(request, progressListener);
-        } catch (RemoteException e) {
-            mService.set(null);
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_LOST);
-        }
-    }
-
-    /**
-     * Returns a list of pending {@link DownloadRequest}s that originated from this application.
-     * A pending request is one that was issued via
-     * {@link #download(DownloadRequest, DownloadProgressListener)} but not cancelled through
-     * {@link #cancelDownload(DownloadRequest)}.
-     * @return A list, possibly empty, of {@link DownloadRequest}s
-     */
-    public @NonNull List<DownloadRequest> listPendingDownloads() throws MbmsException {
-        IMbmsDownloadService downloadService = mService.get();
-        if (downloadService == null) {
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND);
-        }
-
-        try {
-            return downloadService.listPendingDownloads(mSubscriptionId);
-        } catch (RemoteException e) {
-            mService.set(null);
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_LOST);
-        }
-    }
-
-    /**
-     * Attempts to cancel the specified {@link DownloadRequest}.
-     *
-     * If the middleware is not aware of the specified download request, an MbmsException will be
-     * thrown with error code {@link MbmsException.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST}.
-     *
-     * If this method returns without throwing an exception, you may assume that cancellation
-     * was successful.
-     * @param downloadRequest The download request that you wish to cancel.
-     */
-    public void cancelDownload(DownloadRequest downloadRequest) throws MbmsException {
-        IMbmsDownloadService downloadService = mService.get();
-        if (downloadService == null) {
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND);
-        }
-
-        try {
-            int result = downloadService.cancelDownload(downloadRequest);
-            if (result != MbmsException.SUCCESS) {
-                throw new MbmsException(result);
-            }
-        } catch (RemoteException e) {
-            mService.set(null);
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_LOST);
-        }
-        deleteDownloadRequestToken(downloadRequest);
-    }
-
-    /**
-     * Gets information about the status of a file pending download.
-     *
-     * If the middleware has not yet been properly initialized or if it has no records of the
-     * file indicated by {@code fileInfo} being associated with {@code downloadRequest},
-     * {@link #STATUS_UNKNOWN} will be returned.
-     *
-     * @param downloadRequest The download request to query.
-     * @param fileInfo The particular file within the request to get information on.
-     * @return The status of the download.
-     */
-    @DownloadStatus
-    public int getDownloadStatus(DownloadRequest downloadRequest, FileInfo fileInfo)
-            throws MbmsException {
-        IMbmsDownloadService downloadService = mService.get();
-        if (downloadService == null) {
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND);
-        }
-
-        try {
-            return downloadService.getDownloadStatus(downloadRequest, fileInfo);
-        } catch (RemoteException e) {
-            mService.set(null);
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_LOST);
-        }
-    }
-
-    /**
-     * Resets the middleware's knowledge of previously-downloaded files in this download request.
-     *
-     * Normally, the middleware keeps track of the hashes of downloaded files and won't re-download
-     * files whose server-reported hash matches one of the already-downloaded files. This means
-     * that if the file is accidentally deleted by the user or by the app, the middleware will
-     * not try to download it again.
-     * This method will reset the middleware's cache of hashes for the provided
-     * {@link DownloadRequest}, so that previously downloaded content will be downloaded again
-     * when available.
-     * This will not interrupt in-progress downloads.
-     *
-     * If the middleware is not aware of the specified download request, an MbmsException will be
-     * thrown with error code {@link MbmsException.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST}.
-     *
-     * May throw a {@link MbmsException} with error code
-     * @param downloadRequest The request to re-download files for.
-     */
-    public void resetDownloadKnowledge(DownloadRequest downloadRequest) throws MbmsException {
-        IMbmsDownloadService downloadService = mService.get();
-        if (downloadService == null) {
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND);
-        }
-
-        try {
-            int result = downloadService.resetDownloadKnowledge(downloadRequest);
-            if (result != MbmsException.SUCCESS) {
-                throw new MbmsException(result);
-            }
-        } catch (RemoteException e) {
-            mService.set(null);
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_LOST);
-        }
-    }
-
-    public void dispose() {
-        try {
-            IMbmsDownloadService downloadService = mService.get();
-            if (downloadService == null) {
-                Log.i(LOG_TAG, "Service already dead");
-                return;
-            }
-            downloadService.dispose(mSubscriptionId);
-        } catch (RemoteException e) {
-            // Ignore
-            Log.i(LOG_TAG, "Remote exception while disposing of service");
-        } finally {
-            mService.set(null);
-            sIsInitialized.set(false);
-        }
-    }
-
-    private void writeDownloadRequestToken(DownloadRequest request) {
-        File token = getDownloadRequestTokenPath(request);
-        if (!token.getParentFile().exists()) {
-            token.getParentFile().mkdirs();
-        }
-        if (token.exists()) {
-            Log.w(LOG_TAG, "Download token " + token.getName() + " already exists");
-            return;
-        }
-        try {
-            if (!token.createNewFile()) {
-                throw new RuntimeException("Failed to create download token for request "
-                        + request);
-            }
-        } catch (IOException e) {
-            throw new RuntimeException("Failed to create download token for request " + request
-                    + " due to IOException " + e);
-        }
-    }
-
-    private void deleteDownloadRequestToken(DownloadRequest request) {
-        File token = getDownloadRequestTokenPath(request);
-        if (!token.isFile()) {
-            Log.w(LOG_TAG, "Attempting to delete non-existent download token at " + token);
-            return;
-        }
-        if (!token.delete()) {
-            Log.w(LOG_TAG, "Couldn't delete download token at " + token);
-        }
-    }
-
-    private File getDownloadRequestTokenPath(DownloadRequest request) {
-        File tempFileLocation = MbmsUtils.getEmbmsTempFileDirForService(mContext,
-                request.getFileServiceId());
-        String downloadTokenFileName = request.getHash()
-                + MbmsDownloadReceiver.DOWNLOAD_TOKEN_SUFFIX;
-        return new File(tempFileLocation, downloadTokenFileName);
-    }
-
-    /**
-     * Verifies the following:
-     * If a request is multi-part,
-     *     1. Destination Uri must exist and be a directory
-     *     2. Directory specified must contain no files.
-     * Otherwise
-     *     1. The file specified by the destination Uri must not exist.
-     */
-    private void checkValidDownloadDestination(DownloadRequest request) {
-        File toFile = new File(request.getDestinationUri().getSchemeSpecificPart());
-        if (request.isMultipartDownload()) {
-            if (!toFile.isDirectory()) {
-                throw new IllegalArgumentException("Multipart download must specify valid " +
-                        "destination directory.");
-            }
-            if (toFile.listFiles().length > 0) {
-                throw new IllegalArgumentException("Destination directory must be clear of all " +
-                        "files.");
-            }
-        } else {
-            if (toFile.exists()) {
-                throw new IllegalArgumentException("Destination file must not exist.");
-            }
-        }
-    }
-
-    private void sendErrorToApp(int errorCode, String message) {
-        try {
-            mCallback.error(errorCode, message);
-        } catch (RemoteException e) {
-            // Ignore, should not happen locally.
-        }
-    }
-}
diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java
new file mode 100644
index 0000000..f392570
--- /dev/null
+++ b/telephony/java/android/telephony/MbmsDownloadSession.java
@@ -0,0 +1,813 @@
+/*
+ * 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.telephony;
+
+import android.annotation.IntDef;
+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.Intent;
+import android.content.ServiceConnection;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.telephony.mbms.DownloadStateCallback;
+import android.telephony.mbms.FileInfo;
+import android.telephony.mbms.DownloadRequest;
+import android.telephony.mbms.InternalDownloadSessionCallback;
+import android.telephony.mbms.InternalDownloadStateCallback;
+import android.telephony.mbms.MbmsDownloadSessionCallback;
+import android.telephony.mbms.MbmsDownloadReceiver;
+import android.telephony.mbms.MbmsErrors;
+import android.telephony.mbms.MbmsTempFileProvider;
+import android.telephony.mbms.MbmsUtils;
+import android.telephony.mbms.vendor.IMbmsDownloadService;
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+/**
+ * This class provides functionality for file download over MBMS.
+ */
+public class MbmsDownloadSession implements AutoCloseable {
+    private static final String LOG_TAG = MbmsDownloadSession.class.getSimpleName();
+
+    /**
+     * Service action which must be handled by the middleware implementing the MBMS file download
+     * interface.
+     * @hide
+     */
+    @SystemApi
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String MBMS_DOWNLOAD_SERVICE_ACTION =
+            "android.telephony.action.EmbmsDownload";
+
+    /**
+     * Metadata key that specifies the component name of the service to bind to for file-download.
+     * @hide
+     */
+    @TestApi
+    public static final String MBMS_DOWNLOAD_SERVICE_OVERRIDE_METADATA =
+            "mbms-download-service-override";
+
+    /**
+     * Integer extra that Android will attach to the intent supplied via
+     * {@link android.telephony.mbms.DownloadRequest.Builder#setAppIntent(Intent)}
+     * Indicates the result code of the download. One of
+     * {@link #RESULT_SUCCESSFUL}, {@link #RESULT_EXPIRED}, {@link #RESULT_CANCELLED},
+     * {@link #RESULT_IO_ERROR}, {@link #RESULT_DOWNLOAD_FAILURE}, {@link #RESULT_OUT_OF_STORAGE},
+     * {@link #RESULT_SERVICE_ID_NOT_DEFINED}, or {@link #RESULT_FILE_ROOT_UNREACHABLE}.
+     *
+     * This extra may also be used by the middleware when it is sending intents to the app.
+     */
+    public static final String EXTRA_MBMS_DOWNLOAD_RESULT =
+            "android.telephony.extra.MBMS_DOWNLOAD_RESULT";
+
+    /**
+     * {@link FileInfo} extra that Android will attach to the intent supplied via
+     * {@link android.telephony.mbms.DownloadRequest.Builder#setAppIntent(Intent)}
+     * Indicates the file for which the download result is for. Never null.
+     *
+     * This extra may also be used by the middleware when it is sending intents to the app.
+     */
+    public static final String EXTRA_MBMS_FILE_INFO = "android.telephony.extra.MBMS_FILE_INFO";
+
+    /**
+     * {@link Uri} extra that Android will attach to the intent supplied via
+     * {@link android.telephony.mbms.DownloadRequest.Builder#setAppIntent(Intent)}
+     * Indicates the location of the successfully downloaded file within the temp file root set
+     * via {@link #setTempFileRootDirectory(File)}.
+     * While you may use this file in-place, it is highly encouraged that you move
+     * this file to a different location after receiving the download completion intent, as this
+     * file resides within the temp file directory.
+     *
+     * Will always be set to a non-null value if
+     * {@link #EXTRA_MBMS_DOWNLOAD_RESULT} is set to {@link #RESULT_SUCCESSFUL}.
+     */
+    public static final String EXTRA_MBMS_COMPLETED_FILE_URI =
+            "android.telephony.extra.MBMS_COMPLETED_FILE_URI";
+
+    /**
+     * Extra containing the {@link DownloadRequest} for which the download result or file
+     * descriptor request is for. Must not be null.
+     */
+    public static final String EXTRA_MBMS_DOWNLOAD_REQUEST =
+            "android.telephony.extra.MBMS_DOWNLOAD_REQUEST";
+
+    /**
+     * The default directory name for all MBMS temp files. If you call
+     * {@link #download(DownloadRequest)} without first calling
+     * {@link #setTempFileRootDirectory(File)}, this directory will be created for you under the
+     * path returned by {@link Context#getFilesDir()}.
+     */
+    public static final String DEFAULT_TOP_LEVEL_TEMP_DIRECTORY = "androidMbmsTempFileRoot";
+
+    /**
+     * Indicates that the download was successful.
+     */
+    public static final int RESULT_SUCCESSFUL = 1;
+
+    /**
+     * Indicates that the download was cancelled via {@link #cancelDownload(DownloadRequest)}.
+     */
+    public static final int RESULT_CANCELLED = 2;
+
+    /**
+     * Indicates that the download will not be completed due to the expiration of its download
+     * window on the carrier's network.
+     */
+    public static final int RESULT_EXPIRED = 3;
+
+    /**
+     * Indicates that the download will not be completed due to an I/O error incurred while
+     * writing to temp files.
+     *
+     * This is likely a transient error and another {@link DownloadRequest} should be sent to try
+     * the download again.
+     */
+    public static final int RESULT_IO_ERROR = 4;
+
+    /**
+     * Indicates that the Service ID specified in the {@link DownloadRequest} is incorrect due to
+     * the Id being incorrect, stale, expired, or similar.
+     */
+    public static final int RESULT_SERVICE_ID_NOT_DEFINED = 5;
+
+    /**
+     * Indicates that there was an error while processing downloaded files, such as a file repair or
+     * file decoding error and is not due to a file I/O error.
+     *
+     * This is likely a transient error and another {@link DownloadRequest} should be sent to try
+     * the download again.
+     */
+    public static final int RESULT_DOWNLOAD_FAILURE = 6;
+
+    /**
+     * Indicates that the file system is full and the {@link DownloadRequest} can not complete.
+     * Either space must be made on the current file system or the temp file root location must be
+     * changed to a location that is not full to download the temp files.
+     */
+    public static final int RESULT_OUT_OF_STORAGE = 7;
+
+    /**
+     * Indicates that the file root that was set is currently unreachable. This can happen if the
+     * temp files are set to be stored on external storage and the SD card was removed, for example.
+     * The temp file root should be changed before sending another DownloadRequest.
+     */
+    public static final int RESULT_FILE_ROOT_UNREACHABLE = 8;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({STATUS_UNKNOWN, STATUS_ACTIVELY_DOWNLOADING, STATUS_PENDING_DOWNLOAD,
+            STATUS_PENDING_REPAIR, STATUS_PENDING_DOWNLOAD_WINDOW})
+    public @interface DownloadStatus {}
+
+    /**
+     * Indicates that the middleware has no information on the file.
+     */
+    public static final int STATUS_UNKNOWN = 0;
+
+    /**
+     * Indicates that the file is actively downloading.
+     */
+    public static final int STATUS_ACTIVELY_DOWNLOADING = 1;
+
+    /**
+     * TODO: I don't know...
+     */
+    public static final int STATUS_PENDING_DOWNLOAD = 2;
+
+    /**
+     * Indicates that the file is being repaired after the download being interrupted.
+     */
+    public static final int STATUS_PENDING_REPAIR = 3;
+
+    /**
+     * Indicates that the file is waiting to download because its download window has not yet
+     * started.
+     */
+    public static final int STATUS_PENDING_DOWNLOAD_WINDOW = 4;
+
+    private static AtomicBoolean sIsInitialized = new AtomicBoolean(false);
+
+    private final Context mContext;
+    private int mSubscriptionId = INVALID_SUBSCRIPTION_ID;
+    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
+        @Override
+        public void binderDied() {
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, "Received death notification");
+        }
+    };
+
+    private AtomicReference<IMbmsDownloadService> mService = new AtomicReference<>(null);
+    private final InternalDownloadSessionCallback mInternalCallback;
+    private final Map<DownloadStateCallback, InternalDownloadStateCallback>
+            mInternalDownloadCallbacks = new HashMap<>();
+
+    private MbmsDownloadSession(Context context, MbmsDownloadSessionCallback callback,
+            int subscriptionId, Handler handler) {
+        mContext = context;
+        mSubscriptionId = subscriptionId;
+        if (handler == null) {
+            handler = new Handler(Looper.getMainLooper());
+        }
+        mInternalCallback = new InternalDownloadSessionCallback(callback, handler);
+    }
+
+    /**
+     * Create a new {@link MbmsDownloadSession} using the system default data subscription ID.
+     * See {@link #create(Context, MbmsDownloadSessionCallback, int, Handler)}
+     */
+    public static MbmsDownloadSession create(@NonNull Context context,
+            @NonNull MbmsDownloadSessionCallback callback, @NonNull Handler handler) {
+        return create(context, callback, SubscriptionManager.getDefaultSubscriptionId(), handler);
+    }
+
+    /**
+     * Create a new MbmsDownloadManager using the given subscription ID.
+     *
+     * Note that this call will bind a remote service and that may take a bit. The instance of
+     * {@link MbmsDownloadSession} that is returned will not be ready for use until
+     * {@link MbmsDownloadSessionCallback#onMiddlewareReady()} is called on the provided callback.
+     * If you attempt to use the instance before it is ready, an {@link IllegalStateException}
+     * will be thrown or an error will be delivered through
+     * {@link MbmsDownloadSessionCallback#onError(int, String)}.
+     *
+     * This also may throw an {@link IllegalArgumentException}.
+     *
+     * You may only have one instance of {@link MbmsDownloadSession} per UID. If you call this
+     * method while there is an active instance of {@link MbmsDownloadSession} 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 MbmsDownloadSessionCallback#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 MbmsDownloadSession} that you received before calling this method again.
+     *
+     * @param context The instance of {@link Context} to use
+     * @param callback A callback to get asynchronous error messages and file service updates.
+     * @param subscriptionId The data subscription ID to use
+     * @param handler The {@link Handler} on which callbacks should be enqueued.
+     * @return A new instance of {@link MbmsDownloadSession}, or null if an error occurred during
+     * setup.
+     */
+    public static @Nullable MbmsDownloadSession create(@NonNull Context context,
+            final @NonNull MbmsDownloadSessionCallback callback,
+            int subscriptionId, @NonNull Handler handler) {
+        if (!sIsInitialized.compareAndSet(false, true)) {
+            throw new IllegalStateException("Cannot have two active instances");
+        }
+        MbmsDownloadSession session =
+                new MbmsDownloadSession(context, callback, subscriptionId, handler);
+        final int result = session.bindAndInitialize();
+        if (result != MbmsErrors.SUCCESS) {
+            sIsInitialized.set(false);
+            handler.post(new Runnable() {
+                @Override
+                public void run() {
+                    callback.onError(result, null);
+                }
+            });
+            return null;
+        }
+        return session;
+    }
+
+    private int bindAndInitialize() {
+        return MbmsUtils.startBinding(mContext, MBMS_DOWNLOAD_SERVICE_ACTION,
+                new ServiceConnection() {
+                    @Override
+                    public void onServiceConnected(ComponentName name, IBinder service) {
+                        IMbmsDownloadService downloadService =
+                                IMbmsDownloadService.Stub.asInterface(service);
+                        int result;
+                        try {
+                            result = downloadService.initialize(mSubscriptionId, mInternalCallback);
+                        } catch (RemoteException e) {
+                            Log.e(LOG_TAG, "Service died before initialization");
+                            sIsInitialized.set(false);
+                            return;
+                        } catch (RuntimeException e) {
+                            Log.e(LOG_TAG, "Runtime exception during initialization");
+                            sendErrorToApp(
+                                    MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+                                    e.toString());
+                            sIsInitialized.set(false);
+                            return;
+                        }
+                        if (result != MbmsErrors.SUCCESS) {
+                            sendErrorToApp(result, "Error returned during initialization");
+                            sIsInitialized.set(false);
+                            return;
+                        }
+                        try {
+                            downloadService.asBinder().linkToDeath(mDeathRecipient, 0);
+                        } catch (RemoteException e) {
+                            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST,
+                                    "Middleware lost during initialization");
+                            sIsInitialized.set(false);
+                            return;
+                        }
+                        mService.set(downloadService);
+                    }
+
+                    @Override
+                    public void onServiceDisconnected(ComponentName name) {
+                        sIsInitialized.set(false);
+                        mService.set(null);
+                    }
+                });
+    }
+
+    /**
+     * An inspection API to retrieve the list of available
+     * {@link android.telephony.mbms.FileServiceInfo}s currently being advertised.
+     * The results are returned asynchronously via a call to
+     * {@link MbmsDownloadSessionCallback#onFileServicesUpdated(List)}
+     *
+     * Asynchronous error codes via the {@link MbmsDownloadSessionCallback#onError(int, String)}
+     * callback may include any of the errors that are not specific to the streaming use-case.
+     *
+     * May throw an {@link IllegalStateException} or {@link IllegalArgumentException}.
+     *
+     * @param classList A list of service classes which the app wishes to receive
+     *                  {@link MbmsDownloadSessionCallback#onFileServicesUpdated(List)} callbacks
+     *                  about. Subsequent calls to this method will replace this list of service
+     *                  classes (i.e. the middleware will no longer send updates for services
+     *                  matching classes only in the old list).
+     *                  Values in this list should be negotiated with the wireless carrier prior
+     *                  to using this API.
+     */
+    public void requestUpdateFileServices(@NonNull List<String> classList) {
+        IMbmsDownloadService downloadService = mService.get();
+        if (downloadService == null) {
+            throw new IllegalStateException("Middleware not yet bound");
+        }
+        try {
+            int returnCode = downloadService.requestUpdateFileServices(mSubscriptionId, classList);
+            if (returnCode != MbmsErrors.SUCCESS) {
+                sendErrorToApp(returnCode, null);
+            }
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Remote process died");
+            mService.set(null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+        }
+    }
+
+    /**
+     * Sets the temp file root for downloads.
+     * All temp files created for the middleware to write to will be contained in the specified
+     * directory. Applications that wish to specify a location only need to call this method once
+     * as long their data is persisted in storage -- the argument will be stored both in a
+     * local instance of {@link android.content.SharedPreferences} and by the middleware.
+     *
+     * If this method is not called at least once before calling
+     * {@link #download(DownloadRequest)}, the framework
+     * will default to a directory formed by the concatenation of the app's files directory and
+     * {@link MbmsDownloadSession#DEFAULT_TOP_LEVEL_TEMP_DIRECTORY}.
+     *
+     * Before calling this method, the app must cancel all of its pending
+     * {@link DownloadRequest}s via {@link #cancelDownload(DownloadRequest)}. If this is not done,
+     * you will receive an asynchronous error with code
+     * {@link MbmsErrors.DownloadErrors#ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT} unless the
+     * provided directory is the same as what has been previously configured.
+     *
+     * The {@link File} supplied as a root temp file directory must already exist. If not, an
+     * {@link IllegalArgumentException} will be thrown. In addition, as an additional sanity
+     * check, an {@link IllegalArgumentException} will be thrown if you attempt to set the temp
+     * file root directory to one of your data roots (the value of {@link Context#getDataDir()},
+     * {@link Context#getFilesDir()}, or {@link Context#getCacheDir()}).
+     * @param tempFileRootDirectory A directory to place temp files in.
+     */
+    public void setTempFileRootDirectory(@NonNull File tempFileRootDirectory) {
+        IMbmsDownloadService downloadService = mService.get();
+        if (downloadService == null) {
+            throw new IllegalStateException("Middleware not yet bound");
+        }
+        try {
+            validateTempFileRootSanity(tempFileRootDirectory);
+        } catch (IOException e) {
+            throw new IllegalStateException("Got IOException checking directory sanity");
+        }
+        String filePath;
+        try {
+            filePath = tempFileRootDirectory.getCanonicalPath();
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Unable to canonicalize the provided path: " + e);
+        }
+
+        try {
+            int result = downloadService.setTempFileRootDirectory(mSubscriptionId, filePath);
+            if (result != MbmsErrors.SUCCESS) {
+                sendErrorToApp(result, null);
+            }
+        } catch (RemoteException e) {
+            mService.set(null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+            return;
+        }
+
+        SharedPreferences prefs = mContext.getSharedPreferences(
+                MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_FILE_NAME, 0);
+        prefs.edit().putString(MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_NAME, filePath).apply();
+    }
+
+    private void validateTempFileRootSanity(File tempFileRootDirectory) throws IOException {
+        if (!tempFileRootDirectory.exists()) {
+            throw new IllegalArgumentException("Provided directory does not exist");
+        }
+        if (!tempFileRootDirectory.isDirectory()) {
+            throw new IllegalArgumentException("Provided File is not a directory");
+        }
+        String canonicalTempFilePath = tempFileRootDirectory.getCanonicalPath();
+        if (mContext.getDataDir().getCanonicalPath().equals(canonicalTempFilePath)) {
+            throw new IllegalArgumentException("Temp file root cannot be your data dir");
+        }
+        if (mContext.getCacheDir().getCanonicalPath().equals(canonicalTempFilePath)) {
+            throw new IllegalArgumentException("Temp file root cannot be your cache dir");
+        }
+        if (mContext.getFilesDir().getCanonicalPath().equals(canonicalTempFilePath)) {
+            throw new IllegalArgumentException("Temp file root cannot be your files dir");
+        }
+    }
+    /**
+     * Retrieves the currently configured temp file root directory. Returns the file that was
+     * configured via {@link #setTempFileRootDirectory(File)} or the default directory
+     * {@link #download(DownloadRequest)} was called without ever
+     * setting the temp file root. If neither method has been called since the last time the app's
+     * shared preferences were reset, returns {@code null}.
+     *
+     * @return A {@link File} pointing to the configured temp file directory, or null if not yet
+     *         configured.
+     */
+    public @Nullable File getTempFileRootDirectory() {
+        SharedPreferences prefs = mContext.getSharedPreferences(
+                MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_FILE_NAME, 0);
+        String path = prefs.getString(MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_NAME, null);
+        if (path != null) {
+            return new File(path);
+        }
+        return null;
+    }
+
+    /**
+     * Requests the download of a file or set of files that the carrier has indicated to be
+     * available.
+     *
+     * May throw an {@link IllegalArgumentException}
+     *
+     * If {@link #setTempFileRootDirectory(File)} has not called after the app has been installed,
+     * this method will create a directory at the default location defined at
+     * {@link MbmsDownloadSession#DEFAULT_TOP_LEVEL_TEMP_DIRECTORY} and store that as the temp
+     * file root directory.
+     *
+     * Asynchronous errors through the callback may include any error not specific to the
+     * streaming use-case.
+     * @param request The request that specifies what should be downloaded.
+     */
+    public void download(@NonNull DownloadRequest request) {
+        IMbmsDownloadService downloadService = mService.get();
+        if (downloadService == null) {
+            throw new IllegalStateException("Middleware not yet bound");
+        }
+
+        // Check to see whether the app's set a temp root dir yet, and set it if not.
+        SharedPreferences prefs = mContext.getSharedPreferences(
+                MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_FILE_NAME, 0);
+        if (prefs.getString(MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_NAME, null) == null) {
+            File tempRootDirectory = new File(mContext.getFilesDir(),
+                    DEFAULT_TOP_LEVEL_TEMP_DIRECTORY);
+            tempRootDirectory.mkdirs();
+            setTempFileRootDirectory(tempRootDirectory);
+        }
+
+        writeDownloadRequestToken(request);
+        try {
+            downloadService.download(request);
+        } catch (RemoteException e) {
+            mService.set(null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+        }
+    }
+
+    /**
+     * Returns a list of pending {@link DownloadRequest}s that originated from this application.
+     * A pending request is one that was issued via
+     * {@link #download(DownloadRequest)} but not cancelled through
+     * {@link #cancelDownload(DownloadRequest)}.
+     * @return A list, possibly empty, of {@link DownloadRequest}s
+     */
+    public @NonNull List<DownloadRequest> listPendingDownloads() {
+        IMbmsDownloadService downloadService = mService.get();
+        if (downloadService == null) {
+            throw new IllegalStateException("Middleware not yet bound");
+        }
+
+        try {
+            return downloadService.listPendingDownloads(mSubscriptionId);
+        } catch (RemoteException e) {
+            mService.set(null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+            return Collections.emptyList();
+        }
+    }
+
+    /**
+     * Registers a callback for a {@link DownloadRequest} previously requested via
+     * {@link #download(DownloadRequest)}. This callback will only be called as long as both this
+     * app and the middleware are both running -- if either one stops, no further calls on the
+     * provided {@link DownloadStateCallback} will be enqueued.
+     *
+     * If the middleware is not aware of the specified download request,
+     * this method will throw an {@link IllegalArgumentException}.
+     *
+     * @param request The {@link DownloadRequest} that you want updates on.
+     * @param callback The callback that should be called when the middleware has information to
+     *                 share on the download.
+     * @param handler The {@link Handler} on which calls to {@code callback} should be enqueued on.
+     */
+    public void registerStateCallback(@NonNull DownloadRequest request,
+            @NonNull DownloadStateCallback callback, @NonNull Handler handler) {
+        IMbmsDownloadService downloadService = mService.get();
+        if (downloadService == null) {
+            throw new IllegalStateException("Middleware not yet bound");
+        }
+
+        InternalDownloadStateCallback internalCallback =
+                new InternalDownloadStateCallback(callback, handler);
+
+        try {
+            int result = downloadService.registerStateCallback(request, internalCallback,
+                    callback.getCallbackFilterFlags());
+            if (result != MbmsErrors.SUCCESS) {
+                if (result == MbmsErrors.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST) {
+                    throw new IllegalArgumentException("Unknown download request.");
+                }
+                sendErrorToApp(result, null);
+                return;
+            }
+        } catch (RemoteException e) {
+            mService.set(null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+            return;
+        }
+        mInternalDownloadCallbacks.put(callback, internalCallback);
+    }
+
+    /**
+     * Un-register a callback previously registered via
+     * {@link #registerStateCallback(DownloadRequest, DownloadStateCallback, Handler)}. After
+     * this method is called, no further callbacks will be enqueued on the {@link Handler}
+     * provided upon registration, even if this method throws an exception.
+     *
+     * If the middleware is not aware of the specified download request,
+     * this method will throw an {@link IllegalArgumentException}.
+     *
+     * @param request The {@link DownloadRequest} provided during registration
+     * @param callback The callback provided during registration.
+     */
+    public void unregisterStateCallback(@NonNull DownloadRequest request,
+            @NonNull DownloadStateCallback callback) {
+        try {
+            IMbmsDownloadService downloadService = mService.get();
+            if (downloadService == null) {
+                throw new IllegalStateException("Middleware not yet bound");
+            }
+
+            InternalDownloadStateCallback internalCallback =
+                    mInternalDownloadCallbacks.get(callback);
+
+            try {
+                int result = downloadService.unregisterStateCallback(request, internalCallback);
+                if (result != MbmsErrors.SUCCESS) {
+                    if (result == MbmsErrors.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST) {
+                        throw new IllegalArgumentException("Unknown download request.");
+                    }
+                    sendErrorToApp(result, null);
+                }
+            } catch (RemoteException e) {
+                mService.set(null);
+                sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+            }
+        } finally {
+            InternalDownloadStateCallback internalCallback =
+                    mInternalDownloadCallbacks.remove(callback);
+            if (internalCallback != null) {
+                internalCallback.stop();
+            }
+        }
+    }
+
+    /**
+     * Attempts to cancel the specified {@link DownloadRequest}.
+     *
+     * If the middleware is not aware of the specified download request,
+     * this method will throw an {@link IllegalArgumentException}.
+     *
+     * @param downloadRequest The download request that you wish to cancel.
+     */
+    public void cancelDownload(@NonNull DownloadRequest downloadRequest) {
+        IMbmsDownloadService downloadService = mService.get();
+        if (downloadService == null) {
+            throw new IllegalStateException("Middleware not yet bound");
+        }
+
+        try {
+            int result = downloadService.cancelDownload(downloadRequest);
+            if (result != MbmsErrors.SUCCESS) {
+                if (result == MbmsErrors.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST) {
+                    throw new IllegalArgumentException("Unknown download request.");
+                }
+                sendErrorToApp(result, null);
+                return;
+            }
+        } catch (RemoteException e) {
+            mService.set(null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+            return;
+        }
+        deleteDownloadRequestToken(downloadRequest);
+    }
+
+    /**
+     * Gets information about the status of a file pending download.
+     *
+     * If there was a problem communicating with the middleware or if it has no records of the
+     * file indicated by {@code fileInfo} being associated with {@code downloadRequest},
+     * {@link #STATUS_UNKNOWN} will be returned.
+     *
+     * @param downloadRequest The download request to query.
+     * @param fileInfo The particular file within the request to get information on.
+     * @return The status of the download.
+     */
+    @DownloadStatus
+    public int getDownloadStatus(DownloadRequest downloadRequest, FileInfo fileInfo) {
+        IMbmsDownloadService downloadService = mService.get();
+        if (downloadService == null) {
+            throw new IllegalStateException("Middleware not yet bound");
+        }
+
+        try {
+            return downloadService.getDownloadStatus(downloadRequest, fileInfo);
+        } catch (RemoteException e) {
+            mService.set(null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+            return STATUS_UNKNOWN;
+        }
+    }
+
+    /**
+     * Resets the middleware's knowledge of previously-downloaded files in this download request.
+     *
+     * Normally, the middleware keeps track of the hashes of downloaded files and won't re-download
+     * files whose server-reported hash matches one of the already-downloaded files. This means
+     * that if the file is accidentally deleted by the user or by the app, the middleware will
+     * not try to download it again.
+     * This method will reset the middleware's cache of hashes for the provided
+     * {@link DownloadRequest}, so that previously downloaded content will be downloaded again
+     * when available.
+     * This will not interrupt in-progress downloads.
+     *
+     * This is distinct from cancelling and re-issuing the download request -- if you cancel and
+     * re-issue, the middleware will not clear its cache of download state information.
+     *
+     * If the middleware is not aware of the specified download request, an
+     * {@link IllegalArgumentException} will be thrown.
+     *
+     * @param downloadRequest The request to re-download files for.
+     */
+    public void resetDownloadKnowledge(DownloadRequest downloadRequest) {
+        IMbmsDownloadService downloadService = mService.get();
+        if (downloadService == null) {
+            throw new IllegalStateException("Middleware not yet bound");
+        }
+
+        try {
+            int result = downloadService.resetDownloadKnowledge(downloadRequest);
+            if (result != MbmsErrors.SUCCESS) {
+                if (result == MbmsErrors.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST) {
+                    throw new IllegalArgumentException("Unknown download request.");
+                }
+                sendErrorToApp(result, null);
+            }
+        } catch (RemoteException e) {
+            mService.set(null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+        }
+    }
+
+    /**
+     * Terminates this instance.
+     *
+     * After this method returns,
+     * no further callbacks originating from the middleware will be enqueued on the provided
+     * instance of {@link MbmsDownloadSessionCallback}, but callbacks that have already been
+     * enqueued will still be delivered.
+     *
+     * It is safe to call {@link #create(Context, MbmsDownloadSessionCallback, int, Handler)} to
+     * obtain another instance of {@link MbmsDownloadSession} immediately after this method
+     * returns.
+     *
+     * May throw an {@link IllegalStateException}
+     */
+    @Override
+    public void close() {
+        try {
+            IMbmsDownloadService downloadService = mService.get();
+            if (downloadService == null) {
+                Log.i(LOG_TAG, "Service already dead");
+                return;
+            }
+            downloadService.dispose(mSubscriptionId);
+        } catch (RemoteException e) {
+            // Ignore
+            Log.i(LOG_TAG, "Remote exception while disposing of service");
+        } finally {
+            mService.set(null);
+            sIsInitialized.set(false);
+            mInternalCallback.stop();
+        }
+    }
+
+    private void writeDownloadRequestToken(DownloadRequest request) {
+        File token = getDownloadRequestTokenPath(request);
+        if (!token.getParentFile().exists()) {
+            token.getParentFile().mkdirs();
+        }
+        if (token.exists()) {
+            Log.w(LOG_TAG, "Download token " + token.getName() + " already exists");
+            return;
+        }
+        try {
+            if (!token.createNewFile()) {
+                throw new RuntimeException("Failed to create download token for request "
+                        + request);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to create download token for request " + request
+                    + " due to IOException " + e);
+        }
+    }
+
+    private void deleteDownloadRequestToken(DownloadRequest request) {
+        File token = getDownloadRequestTokenPath(request);
+        if (!token.isFile()) {
+            Log.w(LOG_TAG, "Attempting to delete non-existent download token at " + token);
+            return;
+        }
+        if (!token.delete()) {
+            Log.w(LOG_TAG, "Couldn't delete download token at " + token);
+        }
+    }
+
+    private File getDownloadRequestTokenPath(DownloadRequest request) {
+        File tempFileLocation = MbmsUtils.getEmbmsTempFileDirForService(mContext,
+                request.getFileServiceId());
+        String downloadTokenFileName = request.getHash()
+                + MbmsDownloadReceiver.DOWNLOAD_TOKEN_SUFFIX;
+        return new File(tempFileLocation, downloadTokenFileName);
+    }
+
+    private void sendErrorToApp(int errorCode, String message) {
+        try {
+            mInternalCallback.onError(errorCode, message);
+        } catch (RemoteException e) {
+            // Ignore, should not happen locally.
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/MbmsStreamingManager.java b/telephony/java/android/telephony/MbmsStreamingManager.java
deleted file mode 100644
index b6b253e..0000000
--- a/telephony/java/android/telephony/MbmsStreamingManager.java
+++ /dev/null
@@ -1,323 +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.telephony;
-
-import android.annotation.SdkConstant;
-import android.annotation.SystemApi;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.ServiceConnection;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.telephony.mbms.InternalStreamingManagerCallback;
-import android.telephony.mbms.InternalStreamingServiceCallback;
-import android.telephony.mbms.MbmsException;
-import android.telephony.mbms.MbmsStreamingManagerCallback;
-import android.telephony.mbms.MbmsUtils;
-import android.telephony.mbms.StreamingService;
-import android.telephony.mbms.StreamingServiceCallback;
-import android.telephony.mbms.StreamingServiceInfo;
-import android.telephony.mbms.vendor.IMbmsStreamingService;
-import android.util.Log;
-
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
-/**
- * This class provides functionality for streaming media over MBMS.
- */
-public class MbmsStreamingManager {
-    private static final String LOG_TAG = "MbmsStreamingManager";
-
-    /**
-     * Service action which must be handled by the middleware implementing the MBMS streaming
-     * interface.
-     * @hide
-     */
-    @SystemApi
-    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
-    public static final String MBMS_STREAMING_SERVICE_ACTION =
-            "android.telephony.action.EmbmsStreaming";
-
-    private static AtomicBoolean sIsInitialized = new AtomicBoolean(false);
-
-    private AtomicReference<IMbmsStreamingService> mService = new AtomicReference<>(null);
-    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
-        @Override
-        public void binderDied() {
-            sIsInitialized.set(false);
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, "Received death notification");
-        }
-    };
-
-    private InternalStreamingManagerCallback mInternalCallback;
-
-    private final Context mContext;
-    private int mSubscriptionId = INVALID_SUBSCRIPTION_ID;
-
-    /** @hide */
-    private MbmsStreamingManager(Context context, MbmsStreamingManagerCallback callback,
-                    int subscriptionId, Handler handler) {
-        mContext = context;
-        mSubscriptionId = subscriptionId;
-        if (handler == null) {
-            handler = new Handler(Looper.getMainLooper());
-        }
-        mInternalCallback = new InternalStreamingManagerCallback(callback, handler);
-    }
-
-    /**
-     * Create a new MbmsStreamingManager using the given subscription ID.
-     *
-     * Note that this call will bind a remote service. You may not call this method on your app's
-     * main thread. This may throw an {@link MbmsException}, indicating errors that may happen
-     * during the initialization or binding process.
-     *
-     *
-     * You may only have one instance of {@link MbmsStreamingManager} per UID. If you call this
-     * method while there is an active instance of {@link MbmsStreamingManager} in your process
-     * (in other words, one that has not had {@link #dispose()} called on it), this method will
-     * throw an {@link MbmsException}. If you call this method in a different process
-     * running under the same UID, an error will be indicated via
-     * {@link MbmsStreamingManagerCallback#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 dispose() on the instance of
-     * {@link MbmsStreamingManager} that you received before calling this method again.
-     *
-     * @param context The {@link Context} to use.
-     * @param callback A callback object on which you wish to receive results of asynchronous
-     *                 operations.
-     * @param subscriptionId The subscription ID to use.
-     * @param handler The handler you wish to receive callbacks on. If null, callbacks will be
-     *                processed on the main looper (in other words, the looper returned from
-     *                {@link Looper#getMainLooper()}).
-     */
-    public static MbmsStreamingManager create(Context context,
-            MbmsStreamingManagerCallback callback, int subscriptionId, Handler handler)
-            throws MbmsException {
-        if (!sIsInitialized.compareAndSet(false, true)) {
-            throw new MbmsException(MbmsException.InitializationErrors.ERROR_DUPLICATE_INITIALIZE);
-        }
-        MbmsStreamingManager manager = new MbmsStreamingManager(context, callback,
-                subscriptionId, handler);
-        try {
-            manager.bindAndInitialize();
-        } catch (MbmsException e) {
-            sIsInitialized.set(false);
-            throw e;
-        }
-        return manager;
-    }
-
-    /**
-     * Create a new MbmsStreamingManager using the system default data subscription ID.
-     * See {@link #create(Context, MbmsStreamingManagerCallback, int, Handler)}.
-     */
-    public static MbmsStreamingManager create(Context context,
-            MbmsStreamingManagerCallback callback, Handler handler)
-            throws MbmsException {
-        return create(context, callback, SubscriptionManager.getDefaultSubscriptionId(), handler);
-    }
-
-    /**
-     * Create a new MbmsStreamingManager using the system default data subscription ID and
-     * default {@link Handler}.
-     * See {@link #create(Context, MbmsStreamingManagerCallback, int, Handler)}.
-     */
-    public static MbmsStreamingManager create(Context context,
-            MbmsStreamingManagerCallback callback)
-            throws MbmsException {
-        return create(context, callback, SubscriptionManager.getDefaultSubscriptionId(), null);
-    }
-
-    /**
-     * Terminates this instance, ending calls to the registered listener.  Also terminates
-     * any streaming services spawned from this instance.
-     *
-     * May throw an {@link IllegalStateException}
-     */
-    public void dispose() {
-        try {
-            IMbmsStreamingService streamingService = mService.get();
-            if (streamingService == null) {
-                // Ignore and return, assume already disposed.
-                return;
-            }
-            streamingService.dispose(mSubscriptionId);
-        } catch (RemoteException e) {
-            // Ignore for now
-        } finally {
-            mService.set(null);
-            sIsInitialized.set(false);
-        }
-    }
-
-    /**
-     * An inspection API to retrieve the list of streaming media currently be advertised.
-     * The results are returned asynchronously through the previously registered callback.
-     * serviceClasses lets the app filter on types of programming and is opaque data between
-     * the app and the carrier.
-     *
-     * Multiple calls replace the list of serviceClasses of interest.
-     *
-     * This may throw an {@link MbmsException} containing any error in
-     * {@link android.telephony.mbms.MbmsException.GeneralErrors},
-     * {@link MbmsException#ERROR_MIDDLEWARE_NOT_BOUND}, or
-     * {@link MbmsException#ERROR_MIDDLEWARE_LOST}.
-     *
-     * May also throw an unchecked {@link IllegalArgumentException} or an
-     * {@link IllegalStateException}
-     *
-     * @param classList A list of streaming service classes that the app would like updates on.
-     */
-    public void getStreamingServices(List<String> classList) throws MbmsException {
-        IMbmsStreamingService streamingService = mService.get();
-        if (streamingService == null) {
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND);
-        }
-        try {
-            int returnCode = streamingService.getStreamingServices(mSubscriptionId, classList);
-            if (returnCode != MbmsException.SUCCESS) {
-                throw new MbmsException(returnCode);
-            }
-        } catch (RemoteException e) {
-            Log.w(LOG_TAG, "Remote process died");
-            mService.set(null);
-            sIsInitialized.set(false);
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_LOST);
-        }
-    }
-
-    /**
-     * Starts streaming a requested service, reporting status to the indicated callback.
-     * Returns an object used to control that stream. The stream may not be ready for consumption
-     * immediately upon return from this method -- wait until the streaming state has been
-     * reported via
-     * {@link android.telephony.mbms.StreamingServiceCallback#onStreamStateUpdated(int, int)}
-     *
-     * May throw an
-     * {@link MbmsException} containing any of the error codes in
-     * {@link android.telephony.mbms.MbmsException.GeneralErrors},
-     * {@link MbmsException#ERROR_MIDDLEWARE_NOT_BOUND}, or
-     * {@link MbmsException#ERROR_MIDDLEWARE_LOST}.
-     *
-     * May also throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
-     *
-     * Asynchronous errors through the callback include any of the errors in
-     * {@link android.telephony.mbms.MbmsException.GeneralErrors} or
-     * {@link android.telephony.mbms.MbmsException.StreamingErrors}.
-     *
-     * @param serviceInfo The information about the service to stream.
-     * @param callback A callback that'll be called when something about the stream changes.
-     * @param handler A handler that calls to {@code callback} should be called on. If null,
-     *                defaults to the handler provided via
-     *                {@link #create(Context, MbmsStreamingManagerCallback, int, Handler)}.
-     * @return An instance of {@link StreamingService} through which the stream can be controlled.
-     */
-    public StreamingService startStreaming(StreamingServiceInfo serviceInfo,
-            StreamingServiceCallback callback, Handler handler) throws MbmsException {
-        IMbmsStreamingService streamingService = mService.get();
-        if (streamingService == null) {
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND);
-        }
-
-        InternalStreamingServiceCallback serviceCallback = new InternalStreamingServiceCallback(
-                callback, handler == null ? mInternalCallback.getHandler() : handler);
-
-        StreamingService serviceForApp = new StreamingService(
-                mSubscriptionId, streamingService, serviceInfo, serviceCallback);
-
-        try {
-            int returnCode = streamingService.startStreaming(
-                    mSubscriptionId, serviceInfo.getServiceId(), serviceCallback);
-            if (returnCode != MbmsException.SUCCESS) {
-                throw new MbmsException(returnCode);
-            }
-        } catch (RemoteException e) {
-            Log.w(LOG_TAG, "Remote process died");
-            mService.set(null);
-            sIsInitialized.set(false);
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_LOST);
-        }
-
-        return serviceForApp;
-    }
-
-    private void bindAndInitialize() throws MbmsException {
-        MbmsUtils.startBinding(mContext, MBMS_STREAMING_SERVICE_ACTION,
-                new ServiceConnection() {
-                    @Override
-                    public void onServiceConnected(ComponentName name, IBinder service) {
-                        IMbmsStreamingService streamingService =
-                                IMbmsStreamingService.Stub.asInterface(service);
-                        int result;
-                        try {
-                            result = streamingService.initialize(mInternalCallback,
-                                    mSubscriptionId);
-                        } catch (RemoteException e) {
-                            Log.e(LOG_TAG, "Service died before initialization");
-                            sendErrorToApp(
-                                    MbmsException.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
-                                    e.toString());
-                            sIsInitialized.set(false);
-                            return;
-                        } catch (RuntimeException e) {
-                            Log.e(LOG_TAG, "Runtime exception during initialization");
-                            sendErrorToApp(
-                                    MbmsException.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
-                                    e.toString());
-                            sIsInitialized.set(false);
-                            return;
-                        }
-                        if (result != MbmsException.SUCCESS) {
-                            sendErrorToApp(result, "Error returned during initialization");
-                            sIsInitialized.set(false);
-                            return;
-                        }
-                        try {
-                            streamingService.asBinder().linkToDeath(mDeathRecipient, 0);
-                        } catch (RemoteException e) {
-                            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST,
-                                    "Middleware lost during initialization");
-                            sIsInitialized.set(false);
-                            return;
-                        }
-                        mService.set(streamingService);
-                    }
-
-                    @Override
-                    public void onServiceDisconnected(ComponentName name) {
-                        sIsInitialized.set(false);
-                        mService.set(null);
-                    }
-                });
-    }
-
-    private void sendErrorToApp(int errorCode, String message) {
-        try {
-            mInternalCallback.error(errorCode, message);
-        } catch (RemoteException e) {
-            // Ignore, should not happen locally.
-        }
-    }
-}
diff --git a/telephony/java/android/telephony/MbmsStreamingSession.java b/telephony/java/android/telephony/MbmsStreamingSession.java
new file mode 100644
index 0000000..fb2ff7b
--- /dev/null
+++ b/telephony/java/android/telephony/MbmsStreamingSession.java
@@ -0,0 +1,339 @@
+/*
+ * 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.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.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.telephony.mbms.InternalStreamingSessionCallback;
+import android.telephony.mbms.InternalStreamingServiceCallback;
+import android.telephony.mbms.MbmsErrors;
+import android.telephony.mbms.MbmsStreamingSessionCallback;
+import android.telephony.mbms.MbmsUtils;
+import android.telephony.mbms.StreamingService;
+import android.telephony.mbms.StreamingServiceCallback;
+import android.telephony.mbms.StreamingServiceInfo;
+import android.telephony.mbms.vendor.IMbmsStreamingService;
+import android.util.ArraySet;
+import android.util.Log;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+/**
+ * This class provides functionality for streaming media over MBMS.
+ */
+public class MbmsStreamingSession implements AutoCloseable {
+    private static final String LOG_TAG = "MbmsStreamingSession";
+
+    /**
+     * Service action which must be handled by the middleware implementing the MBMS streaming
+     * interface.
+     * @hide
+     */
+    @SystemApi
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String MBMS_STREAMING_SERVICE_ACTION =
+            "android.telephony.action.EmbmsStreaming";
+
+    /**
+     * Metadata key that specifies the component name of the service to bind to for file-download.
+     * @hide
+     */
+    @TestApi
+    public static final String MBMS_STREAMING_SERVICE_OVERRIDE_METADATA =
+            "mbms-streaming-service-override";
+
+    private static AtomicBoolean sIsInitialized = new AtomicBoolean(false);
+
+    private AtomicReference<IMbmsStreamingService> mService = new AtomicReference<>(null);
+    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
+        @Override
+        public void binderDied() {
+            sIsInitialized.set(false);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, "Received death notification");
+        }
+    };
+
+    private InternalStreamingSessionCallback mInternalCallback;
+    private Set<StreamingService> mKnownActiveStreamingServices = new ArraySet<>();
+
+    private final Context mContext;
+    private int mSubscriptionId = INVALID_SUBSCRIPTION_ID;
+
+    /** @hide */
+    private MbmsStreamingSession(Context context, MbmsStreamingSessionCallback callback,
+                    int subscriptionId, Handler handler) {
+        mContext = context;
+        mSubscriptionId = subscriptionId;
+        if (handler == null) {
+            handler = new Handler(Looper.getMainLooper());
+        }
+        mInternalCallback = new InternalStreamingSessionCallback(callback, handler);
+    }
+
+    /**
+     * Create a new {@link MbmsStreamingSession} using the given subscription ID.
+     *
+     * Note that this call will bind a remote service. You may not call this method on your app's
+     * main thread.
+     *
+     * You may only have one instance of {@link MbmsStreamingSession} per UID. If you call this
+     * method while there is an active instance of {@link MbmsStreamingSession} 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 MbmsStreamingSessionCallback#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 MbmsStreamingSession} that you received before calling this method again.
+     *
+     * @param context The {@link Context} to use.
+     * @param callback A callback object on which you wish to receive results of asynchronous
+     *                 operations.
+     * @param subscriptionId The subscription ID to use.
+     * @param handler The handler you wish to receive callbacks on.
+     * @return An instance of {@link MbmsStreamingSession}, or null if an error occurred.
+     */
+    public static @Nullable MbmsStreamingSession create(@NonNull Context context,
+            final @NonNull MbmsStreamingSessionCallback callback, int subscriptionId,
+            @NonNull Handler handler) {
+        if (!sIsInitialized.compareAndSet(false, true)) {
+            throw new IllegalStateException("Cannot create two instances of MbmsStreamingSession");
+        }
+        MbmsStreamingSession session = new MbmsStreamingSession(context, callback,
+                subscriptionId, handler);
+
+        final int result = session.bindAndInitialize();
+        if (result != MbmsErrors.SUCCESS) {
+            sIsInitialized.set(false);
+            handler.post(new Runnable() {
+                @Override
+                public void run() {
+                    callback.onError(result, null);
+                }
+            });
+            return null;
+        }
+        return session;
+    }
+
+    /**
+     * Create a new {@link MbmsStreamingSession} using the system default data subscription ID.
+     * See {@link #create(Context, MbmsStreamingSessionCallback, int, Handler)}.
+     */
+    public static MbmsStreamingSession create(@NonNull Context context,
+            @NonNull MbmsStreamingSessionCallback callback, @NonNull Handler handler) {
+        return create(context, callback, SubscriptionManager.getDefaultSubscriptionId(), handler);
+    }
+
+    /**
+     * Terminates this instance. Also terminates
+     * any streaming services spawned from this instance as if
+     * {@link StreamingService#stopStreaming()} 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 MbmsStreamingSessionCallback}, but callbacks that have already been
+     * enqueued will still be delivered.
+     *
+     * It is safe to call {@link #create(Context, MbmsStreamingSessionCallback, int, Handler)} to
+     * obtain another instance of {@link MbmsStreamingSession} immediately after this method
+     * returns.
+     *
+     * May throw an {@link IllegalStateException}
+     */
+    public void close() {
+        try {
+            IMbmsStreamingService streamingService = mService.get();
+            if (streamingService == null) {
+                // Ignore and return, assume already disposed.
+                return;
+            }
+            streamingService.dispose(mSubscriptionId);
+            for (StreamingService s : mKnownActiveStreamingServices) {
+                s.getCallback().stop();
+            }
+            mKnownActiveStreamingServices.clear();
+        } catch (RemoteException e) {
+            // Ignore for now
+        } finally {
+            mService.set(null);
+            sIsInitialized.set(false);
+            mInternalCallback.stop();
+        }
+    }
+
+    /**
+     * An inspection API to retrieve the list of streaming media currently be advertised.
+     * The results are returned asynchronously via
+     * {@link MbmsStreamingSessionCallback#onStreamingServicesUpdated(List)} on the callback
+     * provided upon creation.
+     *
+     * Multiple calls replace the list of service classes of interest.
+     *
+     * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}.
+     *
+     * @param serviceClassList A list of streaming service classes that the app would like updates
+     *                         on. The exact names of these classes should be negotiated with the
+     *                         wireless carrier separately.
+     */
+    public void requestUpdateStreamingServices(List<String> serviceClassList) {
+        IMbmsStreamingService streamingService = mService.get();
+        if (streamingService == null) {
+            throw new IllegalStateException("Middleware not yet bound");
+        }
+        try {
+            int returnCode = streamingService.requestUpdateStreamingServices(
+                    mSubscriptionId, serviceClassList);
+            if (returnCode != MbmsErrors.SUCCESS) {
+                sendErrorToApp(returnCode, null);
+            }
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Remote process died");
+            mService.set(null);
+            sIsInitialized.set(false);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+        }
+    }
+
+    /**
+     * Starts streaming a requested service, reporting status to the indicated callback.
+     * Returns an object used to control that stream. The stream may not be ready for consumption
+     * immediately upon return from this method -- wait until the streaming state has been
+     * reported via
+     * {@link android.telephony.mbms.StreamingServiceCallback#onStreamStateUpdated(int, int)}
+     *
+     * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
+     *
+     * Asynchronous errors through the callback include any of the errors in
+     * {@link MbmsErrors.GeneralErrors} or
+     * {@link MbmsErrors.StreamingErrors}.
+     *
+     * @param serviceInfo The information about the service to stream.
+     * @param callback A callback that'll be called when something about the stream changes.
+     * @param handler A handler that calls to {@code callback} should be called on.
+     * @return An instance of {@link StreamingService} through which the stream can be controlled.
+     *         May be {@code null} if an error occurred.
+     */
+    public @Nullable StreamingService startStreaming(StreamingServiceInfo serviceInfo,
+            StreamingServiceCallback callback, @NonNull Handler handler) {
+        IMbmsStreamingService streamingService = mService.get();
+        if (streamingService == null) {
+            throw new IllegalStateException("Middleware not yet bound");
+        }
+
+        InternalStreamingServiceCallback serviceCallback = new InternalStreamingServiceCallback(
+                callback, handler);
+
+        StreamingService serviceForApp = new StreamingService(
+                mSubscriptionId, streamingService, this, serviceInfo, serviceCallback);
+        mKnownActiveStreamingServices.add(serviceForApp);
+
+        try {
+            int returnCode = streamingService.startStreaming(
+                    mSubscriptionId, serviceInfo.getServiceId(), serviceCallback);
+            if (returnCode != MbmsErrors.SUCCESS) {
+                sendErrorToApp(returnCode, null);
+                return null;
+            }
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Remote process died");
+            mService.set(null);
+            sIsInitialized.set(false);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+            return null;
+        }
+
+        return serviceForApp;
+    }
+
+    /** @hide */
+    public void onStreamingServiceStopped(StreamingService service) {
+        mKnownActiveStreamingServices.remove(service);
+    }
+
+    private int bindAndInitialize() {
+        return MbmsUtils.startBinding(mContext, MBMS_STREAMING_SERVICE_ACTION,
+                new ServiceConnection() {
+                    @Override
+                    public void onServiceConnected(ComponentName name, IBinder service) {
+                        IMbmsStreamingService streamingService =
+                                IMbmsStreamingService.Stub.asInterface(service);
+                        int result;
+                        try {
+                            result = streamingService.initialize(mInternalCallback,
+                                    mSubscriptionId);
+                        } catch (RemoteException e) {
+                            Log.e(LOG_TAG, "Service died before initialization");
+                            sendErrorToApp(
+                                    MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+                                    e.toString());
+                            sIsInitialized.set(false);
+                            return;
+                        } catch (RuntimeException e) {
+                            Log.e(LOG_TAG, "Runtime exception during initialization");
+                            sendErrorToApp(
+                                    MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+                                    e.toString());
+                            sIsInitialized.set(false);
+                            return;
+                        }
+                        if (result != MbmsErrors.SUCCESS) {
+                            sendErrorToApp(result, "Error returned during initialization");
+                            sIsInitialized.set(false);
+                            return;
+                        }
+                        try {
+                            streamingService.asBinder().linkToDeath(mDeathRecipient, 0);
+                        } catch (RemoteException e) {
+                            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST,
+                                    "Middleware lost during initialization");
+                            sIsInitialized.set(false);
+                            return;
+                        }
+                        mService.set(streamingService);
+                    }
+
+                    @Override
+                    public void onServiceDisconnected(ComponentName name) {
+                        sIsInitialized.set(false);
+                        mService.set(null);
+                    }
+                });
+    }
+
+    private void sendErrorToApp(int errorCode, String message) {
+        try {
+            mInternalCallback.onError(errorCode, message);
+        } catch (RemoteException e) {
+            // Ignore, should not happen locally.
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/NetworkScanRequest.java b/telephony/java/android/telephony/NetworkScanRequest.java
index d2aef20..9674c93 100644
--- a/telephony/java/android/telephony/NetworkScanRequest.java
+++ b/telephony/java/android/telephony/NetworkScanRequest.java
@@ -19,6 +19,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 
 /**
@@ -38,6 +39,20 @@
     public static final int MAX_BANDS = 8;
     /** @hide */
     public static final int MAX_CHANNELS = 32;
+    /** @hide */
+    public static final int MAX_MCC_MNC_LIST_SIZE = 20;
+    /** @hide */
+    public static final int MIN_SEARCH_PERIODICITY_SEC = 5;
+    /** @hide */
+    public static final int MAX_SEARCH_PERIODICITY_SEC = 300;
+    /** @hide */
+    public static final int MIN_SEARCH_MAX_SEC = 60;
+    /** @hide */
+    public static final int MAX_SEARCH_MAX_SEC = 3600;
+    /** @hide */
+    public static final int MIN_INCREMENTAL_PERIODICITY_SEC = 1;
+    /** @hide */
+    public static final int MAX_INCREMENTAL_PERIODICITY_SEC = 10;
 
     /** Performs the scan only once */
     public static final int SCAN_TYPE_ONE_SHOT = 0;
@@ -46,24 +61,84 @@
      *
      * The modem will start new scans periodically, and the interval between two scans is usually
      * multiple minutes.
-     * */
+     */
     public static final int SCAN_TYPE_PERIODIC = 1;
 
     /** Defines the type of the scan. */
     public int scanType;
 
+    /**
+     * Search periodicity (in seconds).
+     * Expected range for the input is [5s - 300s]
+     * This value must be less than or equal to maxSearchTime
+     */
+    public int searchPeriodicity;
+
+    /**
+     * Maximum duration of the periodic search (in seconds).
+     * Expected range for the input is [60s - 3600s]
+     * If the search lasts this long, it will be terminated.
+     */
+    public int maxSearchTime;
+
+    /**
+     * Indicates whether the modem should report incremental
+     * results of the network scan to the client.
+     * FALSE – Incremental results are not reported.
+     * TRUE (default) – Incremental results are reported
+     */
+    public boolean incrementalResults;
+
+    /**
+     * Indicates the periodicity with which the modem should
+     * report incremental results to the client (in seconds).
+     * Expected range for the input is [1s - 10s]
+     * This value must be less than or equal to maxSearchTime
+     */
+    public int incrementalResultsPeriodicity;
+
     /** Describes the radio access technologies with bands or channels that need to be scanned. */
     public RadioAccessSpecifier[] specifiers;
 
     /**
+     * Describes the List of PLMN ids (MCC-MNC)
+     * If any PLMN of this list is found, search should end at that point and
+     * results with all PLMN found till that point should be sent as response.
+     * If list not sent, search to be completed till end and all PLMNs found to be reported.
+     * Max size of array is MAX_MCC_MNC_LIST_SIZE
+     */
+    public ArrayList<String> mccMncs;
+
+    /**
      * Creates a new NetworkScanRequest with scanType and network specifiers
      *
      * @param scanType The type of the scan
      * @param specifiers the radio network with bands / channels to be scanned
+     * @param searchPeriodicity Search periodicity (in seconds)
+     * @param maxSearchTime Maximum duration of the periodic search (in seconds)
+     * @param incrementalResults Indicates whether the modem should report incremental
+     *                           results of the network scan to the client
+     * @param incrementalResultsPeriodicity Indicates the periodicity with which the modem should
+     *                                      report incremental results to the client (in seconds)
+     * @param mccMncs Describes the List of PLMN ids (MCC-MNC)
      */
-    public NetworkScanRequest(int scanType, RadioAccessSpecifier[] specifiers) {
+    public NetworkScanRequest(int scanType, RadioAccessSpecifier[] specifiers,
+                    int searchPeriodicity,
+                    int maxSearchTime,
+                    boolean incrementalResults,
+                    int incrementalResultsPeriodicity,
+                    ArrayList<String> mccMncs) {
         this.scanType = scanType;
         this.specifiers = specifiers;
+        this.searchPeriodicity = searchPeriodicity;
+        this.maxSearchTime = maxSearchTime;
+        this.incrementalResults = incrementalResults;
+        this.incrementalResultsPeriodicity = incrementalResultsPeriodicity;
+        if (mccMncs != null) {
+            this.mccMncs = mccMncs;
+        } else {
+            this.mccMncs = new ArrayList<>();
+        }
     }
 
     @Override
@@ -75,6 +150,11 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(scanType);
         dest.writeParcelableArray(specifiers, flags);
+        dest.writeInt(searchPeriodicity);
+        dest.writeInt(maxSearchTime);
+        dest.writeBoolean(incrementalResults);
+        dest.writeInt(incrementalResultsPeriodicity);
+        dest.writeStringList(mccMncs);
     }
 
     private NetworkScanRequest(Parcel in) {
@@ -82,6 +162,12 @@
         specifiers = (RadioAccessSpecifier[]) in.readParcelableArray(
                 Object.class.getClassLoader(),
                 RadioAccessSpecifier.class);
+        searchPeriodicity = in.readInt();
+        maxSearchTime = in.readInt();
+        incrementalResults = in.readBoolean();
+        incrementalResultsPeriodicity = in.readInt();
+        mccMncs = new ArrayList<>();
+        in.readStringList(mccMncs);
     }
 
     @Override
@@ -99,13 +185,24 @@
         }
 
         return (scanType == nsr.scanType
-                && Arrays.equals(specifiers, nsr.specifiers));
+                && Arrays.equals(specifiers, nsr.specifiers)
+                && searchPeriodicity == nsr.searchPeriodicity
+                && maxSearchTime == nsr.maxSearchTime
+                && incrementalResults == nsr.incrementalResults
+                && incrementalResultsPeriodicity == nsr.incrementalResultsPeriodicity
+                && (((mccMncs != null)
+                && mccMncs.equals(nsr.mccMncs))));
     }
 
     @Override
     public int hashCode () {
         return ((scanType * 31)
-                + (Arrays.hashCode(specifiers)) * 37);
+                + (Arrays.hashCode(specifiers)) * 37
+                + (searchPeriodicity * 41)
+                + (maxSearchTime * 43)
+                + ((incrementalResults == true? 1 : 0) * 47)
+                + (incrementalResultsPeriodicity * 53)
+                + (mccMncs.hashCode() * 59));
     }
 
     public static final Creator<NetworkScanRequest> CREATOR =
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 8705446..1b942de 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -77,9 +77,28 @@
     public static final int TOA_International = 0x91;
     public static final int TOA_Unknown = 0x81;
 
+    /*
+     * The BCD extended type used to determine the extended char for the digit which is greater than
+     * 9.
+     *
+     * see TS 51.011 section 10.5.1 EF_ADN(Abbreviated dialling numbers)
+     */
+    public static final int BCD_EXTENDED_TYPE_EF_ADN = 1;
+
+    /*
+     * The BCD extended type used to determine the extended char for the digit which is greater than
+     * 9.
+     *
+     * see TS 24.008 section 10.5.4.7 Called party BCD number
+     */
+    public static final int BCD_EXTENDED_TYPE_CALLED_PARTY = 2;
+
     static final String LOG_TAG = "PhoneNumberUtils";
     private static final boolean DBG = false;
 
+    private static final String BCD_EF_ADN_EXTENDED = "*#,N;";
+    private static final String BCD_CALLED_PARTY_EXTENDED = "*#abc";
+
     /*
      * global-phone-number = ["+"] 1*( DIGIT / written-sep )
      * written-sep         = ("-"/".")
@@ -799,11 +818,33 @@
      *
      * @return partial string on invalid decode
      *
-     * FIXME(mkf) support alphanumeric address type
-     *  currently implemented in SMSMessage.getAddress()
+     * @deprecated use {@link #calledPartyBCDToString(byte[], int, int, int)} instead. Calling this
+     * method is equivalent to calling {@link #calledPartyBCDToString(byte[], int, int)} with
+     * {@link #BCD_EXTENDED_TYPE_EF_ADN} as the extended type.
      */
-    public static String
-    calledPartyBCDToString (byte[] bytes, int offset, int length) {
+    @Deprecated
+    public static String calledPartyBCDToString(byte[] bytes, int offset, int length) {
+        return calledPartyBCDToString(bytes, offset, length, BCD_EXTENDED_TYPE_EF_ADN);
+    }
+
+    /**
+     *  3GPP TS 24.008 10.5.4.7
+     *  Called Party BCD Number
+     *
+     *  See Also TS 51.011 10.5.1 "dialing number/ssc string"
+     *  and TS 11.11 "10.3.1 EF adn (Abbreviated dialing numbers)"
+     *
+     * @param bytes the data buffer
+     * @param offset should point to the TOA (aka. TON/NPI) octet after the length byte
+     * @param length is the number of bytes including TOA byte
+     *                and must be at least 2
+     * @param bcdExtType used to determine the extended bcd coding
+     * @see #BCD_EXTENDED_TYPE_EF_ADN
+     * @see #BCD_EXTENDED_TYPE_CALLED_PARTY
+     *
+     */
+    public static String calledPartyBCDToString(
+            byte[] bytes, int offset, int length, int bcdExtType) {
         boolean prependPlus = false;
         StringBuilder ret = new StringBuilder(1 + length * 2);
 
@@ -817,7 +858,7 @@
         }
 
         internalCalledPartyBCDFragmentToString(
-                ret, bytes, offset + 1, length - 1);
+                ret, bytes, offset + 1, length - 1, bcdExtType);
 
         if (prependPlus && ret.length() == 0) {
             // If the only thing there is a prepended plus, return ""
@@ -902,14 +943,13 @@
         return ret.toString();
     }
 
-    private static void
-    internalCalledPartyBCDFragmentToString(
-        StringBuilder sb, byte [] bytes, int offset, int length) {
+    private static void internalCalledPartyBCDFragmentToString(
+            StringBuilder sb, byte [] bytes, int offset, int length, int bcdExtType) {
         for (int i = offset ; i < length + offset ; i++) {
             byte b;
             char c;
 
-            c = bcdToChar((byte)(bytes[i] & 0xf));
+            c = bcdToChar((byte)(bytes[i] & 0xf), bcdExtType);
 
             if (c == 0) {
                 return;
@@ -930,7 +970,7 @@
                 break;
             }
 
-            c = bcdToChar(b);
+            c = bcdToChar(b, bcdExtType);
             if (c == 0) {
                 return;
             }
@@ -943,49 +983,65 @@
     /**
      * Like calledPartyBCDToString, but field does not start with a
      * TOA byte. For example: SIM ADN extension fields
+     *
+     * @deprecated use {@link #calledPartyBCDFragmentToString(byte[], int, int, int)} instead.
+     * Calling this method is equivalent to calling
+     * {@link #calledPartyBCDFragmentToString(byte[], int, int, int)} with
+     * {@link #BCD_EXTENDED_TYPE_EF_ADN} as the extended type.
      */
+    @Deprecated
+    public static String calledPartyBCDFragmentToString(byte[] bytes, int offset, int length) {
+        return calledPartyBCDFragmentToString(bytes, offset, length, BCD_EXTENDED_TYPE_EF_ADN);
+    }
 
-    public static String
-    calledPartyBCDFragmentToString(byte [] bytes, int offset, int length) {
+    /**
+     * Like calledPartyBCDToString, but field does not start with a
+     * TOA byte. For example: SIM ADN extension fields
+     */
+    public static String calledPartyBCDFragmentToString(
+            byte[] bytes, int offset, int length, int bcdExtType) {
         StringBuilder ret = new StringBuilder(length * 2);
-
-        internalCalledPartyBCDFragmentToString(ret, bytes, offset, length);
-
+        internalCalledPartyBCDFragmentToString(ret, bytes, offset, length, bcdExtType);
         return ret.toString();
     }
 
-    /** returns 0 on invalid value */
-    private static char
-    bcdToChar(byte b) {
+    /**
+     * Returns the correspond character for given {@code b} based on {@code bcdExtType}, or 0 on
+     * invalid code.
+     */
+    private static char bcdToChar(byte b, int bcdExtType) {
         if (b < 0xa) {
-            return (char)('0' + b);
-        } else switch (b) {
-            case 0xa: return '*';
-            case 0xb: return '#';
-            case 0xc: return PAUSE;
-            case 0xd: return WILD;
-
-            default: return 0;
+            return (char) ('0' + b);
         }
+
+        String extended = null;
+        if (BCD_EXTENDED_TYPE_EF_ADN == bcdExtType) {
+            extended = BCD_EF_ADN_EXTENDED;
+        } else if (BCD_EXTENDED_TYPE_CALLED_PARTY == bcdExtType) {
+            extended = BCD_CALLED_PARTY_EXTENDED;
+        }
+        if (extended == null || b - 0xa >= extended.length()) {
+            return 0;
+        }
+
+        return extended.charAt(b - 0xa);
     }
 
-    private static int
-    charToBCD(char c) {
-        if (c >= '0' && c <= '9') {
+    private static int charToBCD(char c, int bcdExtType) {
+        if ('0' <= c && c <= '9') {
             return c - '0';
-        } else if (c == '*') {
-            return 0xa;
-        } else if (c == '#') {
-            return 0xb;
-        } else if (c == PAUSE) {
-            return 0xc;
-        } else if (c == WILD) {
-            return 0xd;
-        } else if (c == WAIT) {
-            return 0xe;
-        } else {
-            throw new RuntimeException ("invalid char for BCD " + c);
         }
+
+        String extended = null;
+        if (BCD_EXTENDED_TYPE_EF_ADN == bcdExtType) {
+            extended = BCD_EF_ADN_EXTENDED;
+        } else if (BCD_EXTENDED_TYPE_CALLED_PARTY == bcdExtType) {
+            extended = BCD_CALLED_PARTY_EXTENDED;
+        }
+        if (extended == null || extended.indexOf(c) == -1) {
+            throw new RuntimeException("invalid char for BCD " + c);
+        }
+        return 0xa + extended.indexOf(c);
     }
 
     /**
@@ -1034,40 +1090,60 @@
      *
      * Returns null if network portion is empty.
      */
-    public static byte[]
-    networkPortionToCalledPartyBCD(String s) {
+    public static byte[] networkPortionToCalledPartyBCD(String s) {
         String networkPortion = extractNetworkPortion(s);
-        return numberToCalledPartyBCDHelper(networkPortion, false);
+        return numberToCalledPartyBCDHelper(
+                networkPortion, false, BCD_EXTENDED_TYPE_EF_ADN);
     }
 
     /**
      * Same as {@link #networkPortionToCalledPartyBCD}, but includes a
      * one-byte length prefix.
      */
-    public static byte[]
-    networkPortionToCalledPartyBCDWithLength(String s) {
+    public static byte[] networkPortionToCalledPartyBCDWithLength(String s) {
         String networkPortion = extractNetworkPortion(s);
-        return numberToCalledPartyBCDHelper(networkPortion, true);
+        return numberToCalledPartyBCDHelper(
+                networkPortion, true, BCD_EXTENDED_TYPE_EF_ADN);
     }
 
     /**
      * Convert a dialing number to BCD byte array
      *
-     * @param number dialing number string
-     *        if the dialing number starts with '+', set to international TOA
+     * @param number dialing number string. If the dialing number starts with '+', set to
+     * international TOA
+     *
+     * @return BCD byte array
+     *
+     * @deprecated use {@link #numberToCalledPartyBCD(String, int)} instead. Calling this method
+     * is equivalent to calling {@link #numberToCalledPartyBCD(String, int)} with
+     * {@link #BCD_EXTENDED_TYPE_EF_ADN} as the extended type.
+     */
+    @Deprecated
+    public static byte[] numberToCalledPartyBCD(String number) {
+        return numberToCalledPartyBCD(number, BCD_EXTENDED_TYPE_EF_ADN);
+    }
+
+    /**
+     * Convert a dialing number to BCD byte array
+     *
+     * @param number dialing number string. If the dialing number starts with '+', set to
+     * international TOA
+     * @param bcdExtType used to determine the extended bcd coding
+     * @see #BCD_EXTENDED_TYPE_EF_ADN
+     * @see #BCD_EXTENDED_TYPE_CALLED_PARTY
+     *
      * @return BCD byte array
      */
-    public static byte[]
-    numberToCalledPartyBCD(String number) {
-        return numberToCalledPartyBCDHelper(number, false);
+    public static byte[] numberToCalledPartyBCD(String number, int bcdExtType) {
+        return numberToCalledPartyBCDHelper(number, false, bcdExtType);
     }
 
     /**
      * If includeLength is true, prepend a one-byte length value to
      * the return array.
      */
-    private static byte[]
-    numberToCalledPartyBCDHelper(String number, boolean includeLength) {
+    private static byte[] numberToCalledPartyBCDHelper(
+            String number, boolean includeLength, int bcdExtType) {
         int numberLenReal = number.length();
         int numberLenEffective = numberLenReal;
         boolean hasPlus = number.indexOf('+') != -1;
@@ -1087,7 +1163,8 @@
             char c = number.charAt(i);
             if (c == '+') continue;
             int shift = ((digitCount & 0x01) == 1) ? 4 : 0;
-            result[extraBytes + (digitCount >> 1)] |= (byte)((charToBCD(c) & 0x0F) << shift);
+            result[extraBytes + (digitCount >> 1)] |=
+                    (byte)((charToBCD(c, bcdExtType) & 0x0F) << shift);
             digitCount++;
         }
 
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index afff6d5..9ccfa94 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -204,16 +204,6 @@
     public static final int LISTEN_VOLTE_STATE                              = 0x00004000;
 
     /**
-     * Listen for OEM hook raw event
-     *
-     * @see #onOemHookRawEvent
-     * @hide
-     * @deprecated OEM needs a vendor-extension hal and their apps should use that instead
-     */
-    @Deprecated
-    public static final int LISTEN_OEM_HOOK_RAW_EVENT                       = 0x00008000;
-
-    /**
      * Listen for carrier network changes indicated by a carrier app.
      *
      * @see #onCarrierNetworkRequest
@@ -359,9 +349,6 @@
                     case LISTEN_DATA_ACTIVATION_STATE:
                         PhoneStateListener.this.onDataActivationStateChanged((int)msg.obj);
                         break;
-                    case LISTEN_OEM_HOOK_RAW_EVENT:
-                        PhoneStateListener.this.onOemHookRawEvent((byte[])msg.obj);
-                        break;
                     case LISTEN_CARRIER_NETWORK_CHANGE:
                         PhoneStateListener.this.onCarrierNetworkChange((boolean)msg.obj);
                         break;
@@ -556,16 +543,6 @@
     }
 
     /**
-     * Callback invoked when OEM hook raw event is received. Requires
-     * the READ_PRIVILEGED_PHONE_STATE permission.
-     * @param rawData is the byte array of the OEM hook raw data.
-     * @hide
-     */
-    public void onOemHookRawEvent(byte[] rawData) {
-        // 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
@@ -677,10 +654,6 @@
             send(LISTEN_DATA_ACTIVATION_STATE, 0, 0, activationState);
         }
 
-        public void onOemHookRawEvent(byte[] rawData) {
-            send(LISTEN_OEM_HOOK_RAW_EVENT, 0, 0, rawData);
-        }
-
         public void onCarrierNetworkChange(boolean active) {
             send(LISTEN_CARRIER_NETWORK_CHANGE, 0, 0, active);
         }
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index e448fb2..116e711 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1197,15 +1197,6 @@
         }
     }
 
-    /**
-     * @Deprecated to be removed Q3 2013 use {@link #getVoiceNetworkType}
-     * @hide
-     */
-    public int getNetworkType() {
-        Rlog.e(LOG_TAG, "ServiceState.getNetworkType() DEPRECATED will be removed *******");
-        return rilRadioTechnologyToNetworkType(mRilVoiceRadioTechnology);
-    }
-
     /** @hide */
     public int getDataNetworkType() {
         return rilRadioTechnologyToNetworkType(mRilDataRadioTechnology);
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 9e02399..de02de7 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -19,7 +19,6 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.telephony.Rlog;
 import android.util.Log;
 import android.content.res.Resources;
 
@@ -69,6 +68,7 @@
     private int mTdScdmaRscp;
 
     private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult
+    private boolean mUseOnlyRsrpForLteLevel; // Use only RSRP for the number of LTE signal bar.
 
     /**
      * Create a new SignalStrength from a intent notifier Bundle
@@ -109,6 +109,7 @@
         mLteRsrpBoost = 0;
         mTdScdmaRscp = INVALID;
         isGsm = true;
+        mUseOnlyRsrpForLteLevel = false;
     }
 
     /**
@@ -135,6 +136,7 @@
         mLteRsrpBoost = 0;
         mTdScdmaRscp = INVALID;
         isGsm = gsmFlag;
+        mUseOnlyRsrpForLteLevel = false;
     }
 
     /**
@@ -146,10 +148,10 @@
             int cdmaDbm, int cdmaEcio,
             int evdoDbm, int evdoEcio, int evdoSnr,
             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
-            int lteRsrpBoost, int tdScdmaRscp, boolean gsmFlag) {
+            int lteRsrpBoost, int tdScdmaRscp, boolean gsmFlag, boolean lteLevelBaseOnRsrp) {
         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
                 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
-                lteRsrq, lteRssnr, lteCqi, lteRsrpBoost, gsmFlag);
+                lteRsrq, lteRssnr, lteCqi, lteRsrpBoost, gsmFlag, lteLevelBaseOnRsrp);
         mTdScdmaRscp = tdScdmaRscp;
     }
 
@@ -165,7 +167,7 @@
             int tdScdmaRscp, boolean gsmFlag) {
         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
                 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
-                lteRsrq, lteRssnr, lteCqi, 0, gsmFlag);
+                lteRsrq, lteRssnr, lteCqi, 0, gsmFlag, false);
         mTdScdmaRscp = tdScdmaRscp;
     }
 
@@ -181,7 +183,7 @@
             boolean gsmFlag) {
         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
                 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
-                lteRsrq, lteRssnr, lteCqi, 0, gsmFlag);
+                lteRsrq, lteRssnr, lteCqi, 0, gsmFlag, false);
     }
 
     /**
@@ -195,7 +197,7 @@
             boolean gsmFlag) {
         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
                 evdoDbm, evdoEcio, evdoSnr, 99, INVALID,
-                INVALID, INVALID, INVALID, 0, gsmFlag);
+                INVALID, INVALID, INVALID, 0, gsmFlag, false);
     }
 
     /**
@@ -229,7 +231,7 @@
             boolean gsm) {
         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
                 evdoDbm, evdoEcio, evdoSnr, 99, INVALID,
-                INVALID, INVALID, INVALID, 0, gsm);
+                INVALID, INVALID, INVALID, 0, gsm, false);
     }
 
     /**
@@ -249,6 +251,7 @@
      * @param lteCqi
      * @param lteRsrpBoost
      * @param gsm
+     * @param useOnlyRsrpForLteLevel
      *
      * @hide
      */
@@ -256,7 +259,7 @@
             int cdmaDbm, int cdmaEcio,
             int evdoDbm, int evdoEcio, int evdoSnr,
             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
-            int lteRsrpBoost, boolean gsm) {
+            int lteRsrpBoost, boolean gsm, boolean useOnlyRsrpForLteLevel) {
         mGsmSignalStrength = gsmSignalStrength;
         mGsmBitErrorRate = gsmBitErrorRate;
         mCdmaDbm = cdmaDbm;
@@ -272,6 +275,7 @@
         mLteRsrpBoost = lteRsrpBoost;
         mTdScdmaRscp = INVALID;
         isGsm = gsm;
+        mUseOnlyRsrpForLteLevel = useOnlyRsrpForLteLevel;
         if (DBG) log("initialize: " + toString());
     }
 
@@ -294,6 +298,7 @@
         mLteRsrpBoost = s.mLteRsrpBoost;
         mTdScdmaRscp = s.mTdScdmaRscp;
         isGsm = s.isGsm;
+        mUseOnlyRsrpForLteLevel = s.mUseOnlyRsrpForLteLevel;
     }
 
     /**
@@ -319,6 +324,7 @@
         mLteRsrpBoost = in.readInt();
         mTdScdmaRscp = in.readInt();
         isGsm = (in.readInt() != 0);
+        mUseOnlyRsrpForLteLevel = (in.readInt() != 0);
     }
 
     /**
@@ -367,6 +373,7 @@
         out.writeInt(mLteRsrpBoost);
         out.writeInt(mTdScdmaRscp);
         out.writeInt(isGsm ? 1 : 0);
+        out.writeInt(mUseOnlyRsrpForLteLevel ? 1 : 0);
     }
 
     /**
@@ -429,6 +436,15 @@
     }
 
     /**
+     * Fix {@link #isGsm} based on the signal strength data.
+     *
+     * @hide
+     */
+    public void fixType() {
+        isGsm = getCdmaRelatedSignalStrength() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+    }
+
+    /**
      * @param true - Gsm, Lte phones
      *        false - Cdma phones
      *
@@ -441,6 +457,17 @@
     }
 
     /**
+     * @param useOnlyRsrpForLteLevel true if it uses only RSRP for the number of LTE signal bar,
+     * otherwise false.
+     *
+     * Used by phone to use only RSRP or not for the number of LTE signal bar.
+     * @hide
+     */
+    public void setUseOnlyRsrpForLteLevel(boolean useOnlyRsrpForLteLevel) {
+        mUseOnlyRsrpForLteLevel = useOnlyRsrpForLteLevel;
+    }
+
+    /**
      * @param lteRsrpBoost - signal strength offset
      *
      * Used by phone to set the lte signal strength offset which will be
@@ -541,30 +568,7 @@
      *     while 4 represents a very strong signal strength.
      */
     public int getLevel() {
-        int level = 0;
-
-        if (isGsm) {
-            level = getLteLevel();
-            if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-                level = getTdScdmaLevel();
-                if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-                    level = getGsmLevel();
-                }
-            }
-        } else {
-            int cdmaLevel = getCdmaLevel();
-            int evdoLevel = getEvdoLevel();
-            if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-                /* We don't know evdo, use cdma */
-                level = cdmaLevel;
-            } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-                /* We don't know cdma, use evdo */
-                level = evdoLevel;
-            } else {
-                /* We know both, use the lowest level */
-                level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
-            }
-        }
+        int level = isGsm ? getGsmRelatedSignalStrength() : getCdmaRelatedSignalStrength();
         if (DBG) log("getLevel=" + level);
         return level;
     }
@@ -850,6 +854,13 @@
             }
         }
 
+        if (useOnlyRsrpForLteLevel()) {
+            log("getLTELevel - rsrp = " + rsrpIconLevel);
+            if (rsrpIconLevel != -1) {
+                return rsrpIconLevel;
+            }
+        }
+
         /*
          * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
          * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
@@ -930,6 +941,15 @@
     }
 
     /**
+     * @return true if it uses only RSRP for the number of LTE signal bar, otherwise false.
+     *
+     * @hide
+     */
+    public boolean useOnlyRsrpForLteLevel() {
+        return this.mUseOnlyRsrpForLteLevel;
+    }
+
+    /**
      * @return get TD_SCDMA dbm
      *
      * @hide
@@ -989,7 +1009,8 @@
                 + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum)
                 + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum)
                 + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum)
-                + (mLteRsrpBoost * primeNum) + (mTdScdmaRscp * primeNum) + (isGsm ? 1 : 0));
+                + (mLteRsrpBoost * primeNum) + (mTdScdmaRscp * primeNum) + (isGsm ? 1 : 0)
+                + (mUseOnlyRsrpForLteLevel ? 1 : 0));
     }
 
     /**
@@ -1023,7 +1044,8 @@
                 && mLteCqi == s.mLteCqi
                 && mLteRsrpBoost == s.mLteRsrpBoost
                 && mTdScdmaRscp == s.mTdScdmaRscp
-                && isGsm == s.isGsm);
+                && isGsm == s.isGsm
+                && mUseOnlyRsrpForLteLevel == s.mUseOnlyRsrpForLteLevel);
     }
 
     /**
@@ -1046,7 +1068,39 @@
                 + " " + mLteCqi
                 + " " + mLteRsrpBoost
                 + " " + mTdScdmaRscp
-                + " " + (isGsm ? "gsm|lte" : "cdma"));
+                + " " + (isGsm ? "gsm|lte" : "cdma")
+                + " " + (mUseOnlyRsrpForLteLevel ? "use_only_rsrp_for_lte_level" :
+                         "use_rsrp_and_rssnr_for_lte_level"));
+    }
+
+    /** Returns the signal strength related to GSM. */
+    private int getGsmRelatedSignalStrength() {
+        int level = getLteLevel();
+        if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+            level = getTdScdmaLevel();
+            if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+                level = getGsmLevel();
+            }
+        }
+        return level;
+    }
+
+    /** Returns the signal strength related to CDMA. */
+    private int getCdmaRelatedSignalStrength() {
+        int level;
+        int cdmaLevel = getCdmaLevel();
+        int evdoLevel = getEvdoLevel();
+        if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+            /* We don't know evdo, use cdma */
+            level = cdmaLevel;
+        } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+            /* We don't know cdma, use evdo */
+            level = evdoLevel;
+        } else {
+            /* We know both, use the lowest level */
+            level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
+        }
+        return level;
     }
 
     /**
@@ -1071,6 +1125,7 @@
         mLteRsrpBoost = m.getInt("lteRsrpBoost");
         mTdScdmaRscp = m.getInt("TdScdma");
         isGsm = m.getBoolean("isGsm");
+        mUseOnlyRsrpForLteLevel = m.getBoolean("useOnlyRsrpForLteLevel");
     }
 
     /**
@@ -1095,6 +1150,7 @@
         m.putInt("lteRsrpBoost", mLteRsrpBoost);
         m.putInt("TdScdma", mTdScdmaRscp);
         m.putBoolean("isGsm", isGsm);
+        m.putBoolean("useOnlyRsrpForLteLevel", mUseOnlyRsrpForLteLevel);
     }
 
     /**
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 1eac263..31ee315 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -387,6 +387,112 @@
     }
 
     /**
+     * Send a text based SMS with messaging options.
+     *
+     * @param destinationAddress the address to send the message to
+     * @param scAddress is the service center address or null to use
+     *  the current default SMSC
+     * @param text the body of the message to send
+     * @param sentIntent if not NULL this <code>PendingIntent</code> is
+     *  broadcast when the message is successfully sent, or failed.
+     *  The result code will be <code>Activity.RESULT_OK</code> for success,
+     *  or one of these errors:<br>
+     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
+     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
+     *  <code>RESULT_ERROR_NULL_PDU</code><br>
+     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
+     *  the extra "errorCode" containing a radio technology specific value,
+     *  generally only useful for troubleshooting.<br>
+     *  The per-application based SMS control checks sentIntent. If sentIntent
+     *  is NULL the caller will be checked against all unknown applications,
+     *  which cause smaller number of SMS to be sent in checking period.
+     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
+     *  broadcast when the message is delivered to the recipient.  The
+     *  raw pdu of the status report is in the extended data ("pdu").
+     * @param priority Priority level of the message
+     *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
+     *  ---------------------------------
+     *  PRIORITY      | Level of Priority
+     *  ---------------------------------
+     *      '00'      |     Normal
+     *      '01'      |     Interactive
+     *      '10'      |     Urgent
+     *      '11'      |     Emergency
+     *  ----------------------------------
+     *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
+     * @param expectMore is a boolean to indicate the sending messages through same link or not.
+     * @param validityPeriod Validity Period of the message in mins.
+     *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
+     *  Validity Period(Minimum) -> 5 mins
+     *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
+     *  Any Other values included Negative considered as Invalid Validity Period of the message.
+     *
+     * @throws IllegalArgumentException if destinationAddress or text are empty
+     * {@hide}
+     */
+    public void sendTextMessage(
+            String destinationAddress, String scAddress, String text,
+            PendingIntent sentIntent, PendingIntent deliveryIntent,
+            int priority, boolean expectMore, int validityPeriod) {
+        sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
+                true /* persistMessage*/, priority, expectMore, validityPeriod);
+    }
+
+    private void sendTextMessageInternal(
+            String destinationAddress, String scAddress, String text,
+            PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage,
+            int priority, boolean expectMore, int validityPeriod) {
+        if (TextUtils.isEmpty(destinationAddress)) {
+            throw new IllegalArgumentException("Invalid destinationAddress");
+        }
+
+        if (TextUtils.isEmpty(text)) {
+            throw new IllegalArgumentException("Invalid message body");
+        }
+
+        if (priority < 0x00 || priority > 0x03) {
+            throw new IllegalArgumentException("Invalid priority");
+        }
+
+        if (validityPeriod < 0x05 || validityPeriod > 0x09b0a0) {
+            throw new IllegalArgumentException("Invalid validity period");
+        }
+
+        try {
+             ISms iccISms = getISmsServiceOrThrow();
+            if (iccISms != null) {
+                iccISms.sendTextForSubscriberWithOptions(getSubscriptionId(),
+                        ActivityThread.currentPackageName(), destinationAddress, scAddress, text,
+                        sentIntent, deliveryIntent, persistMessage,  priority, expectMore,
+                        validityPeriod);
+            }
+        } catch (RemoteException ex) {
+            // ignore it
+        }
+    }
+
+    /**
+     * Send a text based SMS without writing it into the SMS Provider.
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or the calling app has carrier
+     * privileges.
+     * </p>
+     *
+     * @see #sendTextMessage(String, String, String, PendingIntent,
+     * PendingIntent, int, boolean, int)
+     * @hide
+     */
+    public void sendTextMessageWithoutPersisting(
+            String destinationAddress, String scAddress, String text,
+            PendingIntent sentIntent, PendingIntent deliveryIntent, int priority,
+            boolean expectMore, int validityPeriod) {
+        sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
+                false /* persistMessage */, priority, expectMore, validityPeriod);
+    }
+
+    /**
+     *
      * Inject an SMS PDU into the android application framework.
      *
      * <p>Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier
@@ -541,6 +647,140 @@
     }
 
     /**
+     * Send a multi-part text based SMS with messaging options. The callee should have already
+     * divided the message into correctly sized parts by calling
+     * <code>divideMessage</code>.
+     *
+     * <p class="note"><strong>Note:</strong> Using this method requires that your app has the
+     * {@link android.Manifest.permission#SEND_SMS} permission.</p>
+     *
+     * <p class="note"><strong>Note:</strong> Beginning with Android 4.4 (API level 19), if
+     * <em>and only if</em> an app is not selected as the default SMS app, the system automatically
+     * writes messages sent using this method to the SMS Provider (the default SMS app is always
+     * responsible for writing its sent messages to the SMS Provider). For information about
+     * how to behave as the default SMS app, see {@link android.provider.Telephony}.</p>
+     *
+     * @param destinationAddress the address to send the message to
+     * @param scAddress is the service center address or null to use
+     *   the current default SMSC
+     * @param parts an <code>ArrayList</code> of strings that, in order,
+     *   comprise the original message
+     * @param sentIntents if not null, an <code>ArrayList</code> of
+     *   <code>PendingIntent</code>s (one for each message part) that is
+     *   broadcast when the corresponding message part has been sent.
+     *   The result code will be <code>Activity.RESULT_OK</code> for success,
+     *   or one of these errors:<br>
+     *   <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
+     *   <code>RESULT_ERROR_RADIO_OFF</code><br>
+     *   <code>RESULT_ERROR_NULL_PDU</code><br>
+     *   For <code>RESULT_ERROR_GENERIC_FAILURE</code> each sentIntent may include
+     *   the extra "errorCode" containing a radio technology specific value,
+     *   generally only useful for troubleshooting.<br>
+     *   The per-application based SMS control checks sentIntent. If sentIntent
+     *   is NULL the caller will be checked against all unknown applications,
+     *   which cause smaller number of SMS to be sent in checking period.
+     * @param deliveryIntents if not null, an <code>ArrayList</code> of
+     *   <code>PendingIntent</code>s (one for each message part) that is
+     *   broadcast when the corresponding message part has been delivered
+     *   to the recipient.  The raw pdu of the status report is in the
+     *   extended data ("pdu").
+     * @param priority Priority level of the message
+     *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
+     *  ---------------------------------
+     *  PRIORITY      | Level of Priority
+     *  ---------------------------------
+     *      '00'      |     Normal
+     *      '01'      |     Interactive
+     *      '10'      |     Urgent
+     *      '11'      |     Emergency
+     *  ----------------------------------
+     *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
+     * @param expectMore is a boolean to indicate the sending messages through same link or not.
+     * @param validityPeriod Validity Period of the message in mins.
+     *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
+     *  Validity Period(Minimum) -> 5 mins
+     *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
+     *  Any Other values included Negative considered as Invalid Validity Period of the message.
+     *
+     * @throws IllegalArgumentException if destinationAddress or data are empty
+     * {@hide}
+     */
+    public void sendMultipartTextMessage(
+            String destinationAddress, String scAddress, ArrayList<String> parts,
+            ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents,
+            int priority, boolean expectMore, int validityPeriod) {
+        sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
+                deliveryIntents, true /* persistMessage*/);
+    }
+
+    private void sendMultipartTextMessageInternal(
+            String destinationAddress, String scAddress, List<String> parts,
+            List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
+            boolean persistMessage, int priority, boolean expectMore, int validityPeriod) {
+        if (TextUtils.isEmpty(destinationAddress)) {
+            throw new IllegalArgumentException("Invalid destinationAddress");
+        }
+        if (parts == null || parts.size() < 1) {
+            throw new IllegalArgumentException("Invalid message body");
+        }
+
+        if (priority < 0x00 || priority > 0x03) {
+            throw new IllegalArgumentException("Invalid priority");
+        }
+
+        if (validityPeriod < 0x05 || validityPeriod > 0x09b0a0) {
+            throw new IllegalArgumentException("Invalid validity period");
+        }
+
+        if (parts.size() > 1) {
+            try {
+                 ISms iccISms = getISmsServiceOrThrow();
+                if (iccISms != null) {
+                    iccISms.sendMultipartTextForSubscriberWithOptions(getSubscriptionId(),
+                            ActivityThread.currentPackageName(), destinationAddress, scAddress,
+                            parts, sentIntents, deliveryIntents, persistMessage, priority,
+                            expectMore, validityPeriod);
+                }
+            } catch (RemoteException ex) {
+                // ignore it
+            }
+        } else {
+            PendingIntent sentIntent = null;
+            PendingIntent deliveryIntent = null;
+            if (sentIntents != null && sentIntents.size() > 0) {
+                sentIntent = sentIntents.get(0);
+            }
+            if (deliveryIntents != null && deliveryIntents.size() > 0) {
+                deliveryIntent = deliveryIntents.get(0);
+            }
+            sendTextMessageInternal(destinationAddress, scAddress, parts.get(0),
+                    sentIntent, deliveryIntent, persistMessage, priority, expectMore,
+                    validityPeriod);
+        }
+    }
+
+    /**
+     * Send a multi-part text based SMS without writing it into the SMS Provider.
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or the calling app has carrier
+     * privileges.
+     * </p>
+     *
+     * @see #sendMultipartTextMessage(String, String, ArrayList, ArrayList,
+     * ArrayList, int, boolean, int)
+     * @hide
+     **/
+    public void sendMultipartTextMessageWithoutPersisting(
+            String destinationAddress, String scAddress, List<String> parts,
+            List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
+            int priority, boolean expectMore, int validityPeriod) {
+        sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
+                deliveryIntents, false /* persistMessage*/, priority, expectMore,
+                validityPeriod);
+    }
+
+   /**
      * Send a data based SMS to a specific application port.
      *
      * <p class="note"><strong>Note:</strong> Using this method requires that your app has the
@@ -1003,7 +1243,7 @@
      *   <code>getAllMessagesFromIcc</code>
      * @return <code>ArrayList</code> of <code>SmsMessage</code> objects.
      */
-    private static ArrayList<SmsMessage> createMessageListFromRawRecords(List<SmsRawData> records) {
+    private ArrayList<SmsMessage> createMessageListFromRawRecords(List<SmsRawData> records) {
         ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>();
         if (records != null) {
             int count = records.size();
@@ -1011,7 +1251,8 @@
                 SmsRawData data = records.get(i);
                 // List contains all records, including "free" records (null)
                 if (data != null) {
-                    SmsMessage sms = SmsMessage.createFromEfRecord(i+1, data.getBytes());
+                    SmsMessage sms = SmsMessage.createFromEfRecord(i+1, data.getBytes(),
+                            getSubscriptionId());
                     if (sms != null) {
                         messages.add(sms);
                     }
@@ -1131,10 +1372,14 @@
     static public final int RESULT_ERROR_NULL_PDU           = 3;
     /** Failed because service is currently unavailable */
     static public final int RESULT_ERROR_NO_SERVICE         = 4;
-    /** Failed because we reached the sending queue limit.  {@hide} */
+    /** Failed because we reached the sending queue limit. */
     static public final int RESULT_ERROR_LIMIT_EXCEEDED     = 5;
     /** Failed because FDN is enabled. {@hide} */
     static public final int RESULT_ERROR_FDN_CHECK_FAILURE  = 6;
+    /** Failed because user denied the sending of this short code. */
+    static public final int RESULT_ERROR_SHORT_CODE_NOT_ALLOWED = 7;
+    /** Failed because the user has denied this app ever send premium short codes. */
+    static public final int RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED = 8;
 
     static private final String PHONE_PACKAGE_NAME = "com.android.phone";
 
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index dcdda86..ec84050 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -267,6 +267,31 @@
     }
 
     /**
+     * Create an SmsMessage from an SMS EF record.
+     *
+     * @param index Index of SMS record. This should be index in ArrayList
+     *              returned by SmsManager.getAllMessagesFromSim + 1.
+     * @param data Record data.
+     * @param subId Subscription Id of the SMS
+     * @return An SmsMessage representing the record.
+     *
+     * @hide
+     */
+    public static SmsMessage createFromEfRecord(int index, byte[] data, int subId) {
+        SmsMessageBase wrappedMessage;
+
+        if (isCdmaVoice(subId)) {
+            wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromEfRecord(
+                    index, data);
+        } else {
+            wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromEfRecord(
+                    index, data);
+        }
+
+        return wrappedMessage != null ? new SmsMessage(wrappedMessage) : null;
+    }
+
+    /**
      * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the
      * length in bytes (not hex chars) less the SMSC header
      *
@@ -818,6 +843,7 @@
          int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(subId);
          return (PHONE_TYPE_CDMA == activePhone);
    }
+
     /**
      * Decide if the carrier supports long SMS.
      * {@hide}
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index cf2d27e..4e1c15f 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -16,7 +16,10 @@
 
 package android.telephony;
 
+import android.annotation.Nullable;
 import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -30,6 +33,8 @@
 import android.os.Parcelable;
 import android.util.DisplayMetrics;
 
+import java.util.Arrays;
+
 /**
  * A Parcelable class for Subscription Information.
  */
@@ -110,11 +115,34 @@
     private String mCountryIso;
 
     /**
+     * Whether the subscription is an embedded one.
+     */
+    private boolean mIsEmbedded;
+
+    /**
+     * The access rules for this subscription, if it is embedded and defines any.
+     */
+    @Nullable
+    private UiccAccessRule[] mAccessRules;
+
+    /**
      * @hide
      */
     public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
             CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
             Bitmap icon, int mcc, int mnc, String countryIso) {
+        this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number,
+                roaming, icon, mcc, mnc, countryIso, false /* isEmbedded */,
+                null /* accessRules */);
+    }
+
+    /**
+     * @hide
+     */
+    public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
+            CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
+            Bitmap icon, int mcc, int mnc, String countryIso, boolean isEmbedded,
+            @Nullable UiccAccessRule[] accessRules) {
         this.mId = id;
         this.mIccId = iccId;
         this.mSimSlotIndex = simSlotIndex;
@@ -128,6 +156,8 @@
         this.mMcc = mcc;
         this.mMnc = mnc;
         this.mCountryIso = countryIso;
+        this.mIsEmbedded = isEmbedded;
+        this.mAccessRules = accessRules;
     }
 
     /**
@@ -284,6 +314,79 @@
         return this.mCountryIso;
     }
 
+    /**
+     * @return whether the subscription is an embedded one.
+     * @hide
+     *
+     * TODO(b/35851809): Make this public.
+     */
+    public boolean isEmbedded() {
+        return this.mIsEmbedded;
+    }
+
+    /**
+     * Checks whether the app with the given context is authorized to manage this subscription
+     * according to its metadata. Only supported for embedded subscriptions (if {@link #isEmbedded}
+     * returns true).
+     *
+     * @param context Context of the application to check.
+     * @return whether the app is authorized to manage this subscription per its metadata.
+     * @throws UnsupportedOperationException if this subscription is not embedded.
+     * @hide
+     *
+     * TODO(b/35851809): Make this public.
+     */
+    public boolean canManageSubscription(Context context) {
+        return canManageSubscription(context, context.getPackageName());
+    }
+
+    /**
+     * Checks whether the given app is authorized to manage this subscription according to its
+     * metadata. Only supported for embedded subscriptions (if {@link #isEmbedded} returns true).
+     *
+     * @param context Any context.
+     * @param packageName Package name of the app to check.
+     * @return whether the app is authorized to manage this subscription per its metadata.
+     * @throws UnsupportedOperationException if this subscription is not embedded.
+     * @hide
+     */
+    public boolean canManageSubscription(Context context, String packageName) {
+        if (!isEmbedded()) {
+            throw new UnsupportedOperationException("Not an embedded subscription");
+        }
+        if (mAccessRules == null) {
+            return false;
+        }
+        PackageManager packageManager = context.getPackageManager();
+        PackageInfo packageInfo;
+        try {
+            packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new IllegalArgumentException("Unknown package: " + packageName, e);
+        }
+        for (UiccAccessRule rule : mAccessRules) {
+            if (rule.getCarrierPrivilegeStatus(packageInfo)
+                    == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @return the {@link UiccAccessRule}s dictating who is authorized to manage this subscription.
+     * @throws UnsupportedOperationException if this subscription is not embedded.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public @Nullable UiccAccessRule[] getAccessRules() {
+        if (!isEmbedded()) {
+            throw new UnsupportedOperationException("Not an embedded subscription");
+        }
+        return mAccessRules;
+    }
+
     public static final Parcelable.Creator<SubscriptionInfo> CREATOR = new Parcelable.Creator<SubscriptionInfo>() {
         @Override
         public SubscriptionInfo createFromParcel(Parcel source) {
@@ -300,9 +403,12 @@
             int mnc = source.readInt();
             String countryIso = source.readString();
             Bitmap iconBitmap = Bitmap.CREATOR.createFromParcel(source);
+            boolean isEmbedded = source.readBoolean();
+            UiccAccessRule[] accessRules = source.createTypedArray(UiccAccessRule.CREATOR);
 
             return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName,
-                    nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso);
+                    nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso,
+                    isEmbedded, accessRules);
         }
 
         @Override
@@ -326,6 +432,8 @@
         dest.writeInt(mMnc);
         dest.writeString(mCountryIso);
         mIconBitmap.writeToParcel(dest, flags);
+        dest.writeBoolean(mIsEmbedded);
+        dest.writeTypedArray(mAccessRules, flags);
     }
 
     @Override
@@ -355,6 +463,7 @@
                 + " displayName=" + mDisplayName + " carrierName=" + mCarrierName
                 + " nameSource=" + mNameSource + " iconTint=" + mIconTint
                 + " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc
-                + " mnc " + mMnc + "}";
+                + " mnc " + mMnc + " isEmbedded " + mIsEmbedded
+                + " accessRules " + Arrays.toString(mAccessRules) + "}";
     }
 }
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 709877d..d2fd097 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -25,17 +25,18 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.net.Uri;
-import android.telephony.Rlog;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Message;
-import android.os.ServiceManager;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.util.DisplayMetrics;
 
-import com.android.internal.telephony.ISub;
 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
+import com.android.internal.telephony.ISub;
 import com.android.internal.telephony.ITelephonyRegistry;
 import com.android.internal.telephony.PhoneConstants;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -43,7 +44,8 @@
  * SubscriptionManager is the application interface to SubscriptionController
  * and provides information about the current Telephony Subscriptions.
  * <p>
- * All SDK public methods require android.Manifest.permission.READ_PHONE_STATE.
+ * All SDK public methods require android.Manifest.permission.READ_PHONE_STATE unless otherwise
+ * specified.
  */
 @SystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)
 public class SubscriptionManager {
@@ -259,6 +261,32 @@
     public static final String SIM_PROVISIONING_STATUS = "sim_provisioning_status";
 
     /**
+     * TelephonyProvider column name for whether a subscription is embedded (that is, present on an
+     * eSIM).
+     * <p>Type: INTEGER (int), 1 for embedded or 0 for non-embedded.
+     * @hide
+     */
+    public static final String IS_EMBEDDED = "is_embedded";
+
+    /**
+     * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from
+     * {@link UiccAccessRule#encodeRules}. Only present if {@link #IS_EMBEDDED} is 1.
+     * <p>TYPE: BLOB
+     * @hide
+     */
+    public static final String ACCESS_RULES = "access_rules";
+
+    /**
+     * TelephonyProvider column name identifying whether an embedded subscription is on a removable
+     * card. Such subscriptions are marked inaccessible as soon as the current card is removed.
+     * Otherwise, they will remain accessible unless explicitly deleted. Only present if
+     * {@link #IS_EMBEDDED} is 1.
+     * <p>TYPE: INTEGER (int), 1 for removable or 0 for non-removable.
+     * @hide
+     */
+    public static final String IS_REMOVABLE = "is_removable";
+
+    /**
      *  TelephonyProvider column name for extreme threat in CB settings
      * @hide
      */
@@ -381,7 +409,15 @@
      * for #onSubscriptionsChanged to be invoked.
      */
     public static class OnSubscriptionsChangedListener {
-        private final Handler mHandler  = new Handler() {
+        private class OnSubscriptionsChangedListenerHandler extends Handler {
+            OnSubscriptionsChangedListenerHandler() {
+                super();
+            }
+
+            OnSubscriptionsChangedListenerHandler(Looper looper) {
+                super(looper);
+            }
+
             @Override
             public void handleMessage(Message msg) {
                 if (DBG) {
@@ -389,7 +425,22 @@
                 }
                 OnSubscriptionsChangedListener.this.onSubscriptionsChanged();
             }
-        };
+        }
+
+        private final Handler mHandler;
+
+        public OnSubscriptionsChangedListener() {
+            mHandler = new OnSubscriptionsChangedListenerHandler();
+        }
+
+        /**
+         * Allow a listener to be created with a custom looper
+         * @param looper the looper that the underlining handler should run on
+         * @hide
+         */
+        public OnSubscriptionsChangedListener(Looper looper) {
+            mHandler = new OnSubscriptionsChangedListenerHandler(looper);
+        }
 
         /**
          * Callback invoked when there is any change to any SubscriptionInfo. Typically
@@ -632,6 +683,112 @@
     }
 
     /**
+     * Gets the SubscriptionInfo(s) of all available subscriptions, if any.
+     *
+     * <p>Available subscriptions include active ones (those with a non-negative
+     * {@link SubscriptionInfo#getSimSlotIndex()}) as well as inactive but installed embedded
+     * subscriptions.
+     *
+     * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
+     * {@link SubscriptionInfo#getSubscriptionId}.
+     *
+     * @return Sorted list of the current {@link SubscriptionInfo} records available on the
+     * device.
+     * <ul>
+     * <li>
+     * If null is returned the current state is unknown but if a
+     * {@link OnSubscriptionsChangedListener} has been registered
+     * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
+     * <li>
+     * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
+     * <li>
+     * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
+     * then by {@link SubscriptionInfo#getSubscriptionId}.
+     * </ul>
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public List<SubscriptionInfo> getAvailableSubscriptionInfoList() {
+        List<SubscriptionInfo> result = null;
+
+        try {
+            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+            if (iSub != null) {
+                result = iSub.getAvailableSubscriptionInfoList(mContext.getOpPackageName());
+            }
+        } catch (RemoteException ex) {
+            // ignore it
+        }
+        return result;
+    }
+
+    /**
+     * Gets the SubscriptionInfo(s) of all embedded subscriptions accessible to the calling app, if
+     * any.
+     *
+     * <p>Only those subscriptions for which the calling app has carrier privileges per the
+     * subscription metadata, if any, will be included in the returned list.
+     *
+     * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
+     * {@link SubscriptionInfo#getSubscriptionId}.
+     *
+     * @return Sorted list of the current embedded {@link SubscriptionInfo} records available on the
+     * device which are accessible to the caller.
+     * <ul>
+     * <li>
+     * If null is returned the current state is unknown but if a
+     * {@link OnSubscriptionsChangedListener} has been registered
+     * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
+     * <li>
+     * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
+     * <li>
+     * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
+     * then by {@link SubscriptionInfo#getSubscriptionId}.
+     * </ul>
+     * @hide
+     *
+     * TODO(b/35851809): Make this public.
+     */
+    public List<SubscriptionInfo> getAccessibleSubscriptionInfoList() {
+        List<SubscriptionInfo> result = null;
+
+        try {
+            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+            if (iSub != null) {
+                result = iSub.getAccessibleSubscriptionInfoList(mContext.getOpPackageName());
+            }
+        } catch (RemoteException ex) {
+            // ignore it
+        }
+        return result;
+    }
+
+    /**
+     * Request a refresh of the platform cache of profile information.
+     *
+     * <p>Should be called by the EuiccService implementation whenever this information changes due
+     * to an operation done outside the scope of a request initiated by the platform to the
+     * EuiccService. There is no need to refresh for downloads, deletes, or other operations that
+     * were made through the EuiccService.
+     *
+     * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public void requestEmbeddedSubscriptionInfoListRefresh() {
+        try {
+            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+            if (iSub != null) {
+                iSub.requestEmbeddedSubscriptionInfoListRefresh();
+            }
+        } catch (RemoteException ex) {
+            // ignore it
+        }
+    }
+
+    /**
      * @return the count of all subscriptions in the database, this includes
      * all subscriptions that have been seen.
      * @hide
diff --git a/telephony/java/android/telephony/Telephony.java b/telephony/java/android/telephony/Telephony.java
index 3282f5f..66ff6e4 100644
--- a/telephony/java/android/telephony/Telephony.java
+++ b/telephony/java/android/telephony/Telephony.java
@@ -2765,6 +2765,13 @@
         public static final String USER_VISIBLE = "user_visible";
 
         /**
+         * Is the user allowed to edit this APN?
+         * <p>Type: INTEGER (boolean) </p>
+         * @hide
+         */
+        public static final String USER_EDITABLE = "user_editable";
+
+        /**
          * Following are possible values for the EDITED field
          * @hide
          */
@@ -2798,6 +2805,26 @@
          *  @hide
          */
         public static final int CARRIER_DELETED_BUT_PRESENT_IN_XML = 6;
+
+        /**
+         * The owner of the APN.
+         * <p>Type: INTEGER</p>
+         * @hide
+         */
+        public static final String OWNED_BY = "owned_by";
+
+        /**
+         * Possible value for the OWNED_BY field.
+         * APN is owned by DPC.
+         * @hide
+         */
+        public static final int OWNED_BY_DPC = 0;
+        /**
+         * Possible value for the OWNED_BY field.
+         * APN is owned by other sources.
+         * @hide
+         */
+        public static final int OWNED_BY_OTHERS = 1;
     }
 
     /**
@@ -3243,4 +3270,69 @@
          */
         public static final String IS_USING_CARRIER_AGGREGATION = "is_using_carrier_aggregation";
     }
+
+    /**
+     * Contains carrier identification information.
+     * @hide
+     */
+    public static final class CarrierIdentification implements BaseColumns {
+        /**
+         * Numeric operator ID (as String). {@code MCC + MNC}
+         * <P>Type: TEXT </P>
+         */
+        public static final String MCCMNC = "mccmnc";
+
+        /**
+         * Group id level 1 (as String).
+         * <P>Type: TEXT </P>
+         */
+        public static final String GID1 = "gid1";
+
+        /**
+         * Group id level 2 (as String).
+         * <P>Type: TEXT </P>
+         */
+        public static final String GID2 = "gid2";
+
+        /**
+         * Public Land Mobile Network name.
+         * <P>Type: TEXT </P>
+         */
+        public static final String PLMN = "plmn";
+
+        /**
+         * Prefix xpattern of IMSI (International Mobile Subscriber Identity).
+         * <P>Type: TEXT </P>
+         */
+        public static final String IMSI_PREFIX_XPATTERN = "imsi_prefix_xpattern";
+
+        /**
+         * Service Provider Name.
+         * <P>Type: TEXT </P>
+         */
+        public static final String SPN = "spn";
+
+        /**
+         * Prefer APN name.
+         * <P>Type: TEXT </P>
+         */
+        public static final String APN = "apn";
+
+        /**
+         * User facing carrier name.
+         * <P>Type: TEXT </P>
+         */
+        public static final String NAME = "carrier_name";
+
+        /**
+         * A unique carrier id
+         * <P>Type: INTEGER </P>
+         */
+        public static final String CID = "carrier_id";
+
+        /**
+         * The {@code content://} URI for this table.
+         */
+        public static final Uri CONTENT_URI = Uri.parse("content://carrier_identification");
+    }
 }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 4520ea7..6b26dbb 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -52,8 +52,9 @@
 import android.telephony.ims.feature.ImsFeature;
 import android.util.Log;
 
-import com.android.ims.internal.IImsServiceController;
-import com.android.ims.internal.IImsServiceFeatureListener;
+import com.android.ims.internal.IImsMMTelFeature;
+import com.android.ims.internal.IImsRcsFeature;
+import com.android.ims.internal.IImsServiceFeatureCallback;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telecom.ITelecomService;
 import com.android.internal.telephony.CellNetworkScanResult;
@@ -106,8 +107,6 @@
     public static final String MODEM_ACTIVITY_RESULT_KEY =
             BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY;
 
-    private static ITelephonyRegistry sRegistry;
-
     /**
      * The allowed states of Wi-Fi calling.
      *
@@ -178,11 +177,6 @@
             mContext = context;
         }
         mSubscriptionManager = SubscriptionManager.from(mContext);
-
-        if (sRegistry == null) {
-            sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
-                    "telephony.registry"));
-        }
     }
 
     /** @hide */
@@ -873,6 +867,20 @@
     public static final String EVENT_NOTIFY_INTERNATIONAL_CALL_ON_WFC =
             "android.telephony.event.EVENT_NOTIFY_INTERNATIONAL_CALL_ON_WFC";
 
+    /**
+     * {@link android.telecom.Connection} event used to indicate that an outgoing call has been
+     * forwarded to another number.
+     * <p>
+     * Sent in response to an IMS supplementary service notification indicating the call has been
+     * forwarded.
+     * <p>
+     * Sent via {@link android.telecom.Connection#sendConnectionEvent(String, Bundle)}.
+     * The {@link Bundle} parameter is expected to be null when this connection event is used.
+     * @hide
+     */
+    public static final String EVENT_CALL_FORWARDED =
+            "android.telephony.event.EVENT_CALL_FORWARDED";
+
     /* Visual voicemail protocols */
 
     /**
@@ -1632,8 +1640,7 @@
      * @hide
      */
     public String getNetworkCountryIso(int subId) {
-        int phoneId = SubscriptionManager.getPhoneId(subId);
-        return getNetworkCountryIsoForPhone(phoneId);
+        return getNetworkCountryIsoForPhone(getPhoneId(subId));
     }
 
     /**
@@ -1648,9 +1655,20 @@
      */
     /** {@hide} */
     public String getNetworkCountryIsoForPhone(int phoneId) {
-        return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony == null)
+                return "";
+            return telephony.getNetworkCountryIsoForPhone(phoneId);
+        } catch (RemoteException ex) {
+                return "";
+        }
     }
 
+    /*
+     * When adding a network type to the list below, make sure to add the correct icon to
+     * MobileSignalController.mapIconSets().
+     */
     /** Network type is unknown */
     public static final int NETWORK_TYPE_UNKNOWN = 0;
     /** Current network is GPRS */
@@ -2120,13 +2138,16 @@
      * @hide
      */
     public String getSimOperatorNumeric() {
-        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+        int subId = mSubId;
         if (!SubscriptionManager.isUsableSubIdValue(subId)) {
-            subId = SubscriptionManager.getDefaultSmsSubscriptionId();
+            subId = SubscriptionManager.getDefaultDataSubscriptionId();
             if (!SubscriptionManager.isUsableSubIdValue(subId)) {
-                subId = SubscriptionManager.getDefaultVoiceSubscriptionId();
+                subId = SubscriptionManager.getDefaultSmsSubscriptionId();
                 if (!SubscriptionManager.isUsableSubIdValue(subId)) {
-                    subId = SubscriptionManager.getDefaultSubscriptionId();
+                    subId = SubscriptionManager.getDefaultVoiceSubscriptionId();
+                    if (!SubscriptionManager.isUsableSubIdValue(subId)) {
+                        subId = SubscriptionManager.getDefaultSubscriptionId();
+                    }
                 }
             }
         }
@@ -3439,6 +3460,10 @@
         return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE));
     }
 
+    private ITelephonyRegistry getTelephonyRegistry() {
+        return ITelephonyRegistry.Stub.asInterface(ServiceManager.getService("telephony.registry"));
+    }
+
     //
     //
     // PhoneStateListener
@@ -3478,12 +3503,16 @@
             if (listener.mSubId == null) {
                 listener.mSubId = mSubId;
             }
-            sRegistry.listenForSubscriber(listener.mSubId, getOpPackageName(),
-                    listener.callback, events, notifyNow);
+
+            ITelephonyRegistry registry = getTelephonyRegistry();
+            if (registry != null) {
+                registry.listenForSubscriber(listener.mSubId, getOpPackageName(),
+                        listener.callback, events, notifyNow);
+            } else {
+                Rlog.w(TAG, "telephony registry not ready.");
+            }
         } catch (RemoteException ex) {
             // system process dead
-        } catch (NullPointerException ex) {
-            // system process dead
         }
     }
 
@@ -3758,7 +3787,7 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
-                return telephony.iccOpenLogicalChannel(subId, AID, p2);
+                return telephony.iccOpenLogicalChannel(subId, getOpPackageName(), AID, p2);
         } catch (RemoteException ex) {
         } catch (NullPointerException ex) {
         }
@@ -4560,27 +4589,78 @@
     public @interface Feature {}
 
     /**
-     * Returns the {@link IImsServiceController} that corresponds to the given slot Id and IMS
-     * feature or {@link null} if the service is not available. If an ImsServiceController is
-     * available, the {@link IImsServiceFeatureListener} callback is registered as a listener for
-     * feature updates.
-     * @param slotIndex The SIM slot that we are requesting the {@link IImsServiceController} for.
-     * @param feature The IMS Feature we are requesting, corresponding to {@link ImsFeature}.
+     * Returns the {@link IImsMMTelFeature} that corresponds to the given slot Id and MMTel
+     * feature or {@link null} if the service is not available. If an MMTelFeature is available, the
+     * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
+     * @param slotIndex The SIM slot that we are requesting the {@link IImsMMTelFeature} for.
      * @param callback Listener that will send updates to ImsManager when there are updates to
      * ImsServiceController.
-     * @return {@link IImsServiceController} interface for the feature specified or {@link null} if
+     * @return {@link IImsMMTelFeature} interface for the feature specified or {@code null} if
      * it is unavailable.
      * @hide
      */
-    public IImsServiceController getImsServiceControllerAndListen(int slotIndex, @Feature int feature,
-            IImsServiceFeatureListener callback) {
+    public @Nullable IImsMMTelFeature getImsMMTelFeatureAndListen(int slotIndex,
+            IImsServiceFeatureCallback callback) {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.getImsServiceControllerAndListen(slotIndex, feature, callback);
+                return telephony.getMMTelFeatureAndListen(slotIndex, callback);
             }
         } catch (RemoteException e) {
-            Rlog.e(TAG, "getImsServiceControllerAndListen, RemoteException: " + e.getMessage());
+            Rlog.e(TAG, "getImsMMTelFeatureAndListen, RemoteException: "
+                    + e.getMessage());
+        }
+        return null;
+    }
+
+    /**
+     * Returns the {@link IImsMMTelFeature} that corresponds to the given slot Id and MMTel
+     * feature for emergency calling or {@link null} if the service is not available. If an
+     * MMTelFeature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
+     * listener for feature updates.
+     * @param slotIndex The SIM slot that we are requesting the {@link IImsMMTelFeature} for.
+     * @param callback Listener that will send updates to ImsManager when there are updates to
+     * ImsServiceController.
+     * @return {@link IImsMMTelFeature} interface for the feature specified or {@code null} if
+     * it is unavailable.
+     * @hide
+     */
+    public @Nullable IImsMMTelFeature getImsEmergencyMMTelFeatureAndListen(int slotIndex,
+            IImsServiceFeatureCallback callback) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.getEmergencyMMTelFeatureAndListen(slotIndex, callback);
+            }
+        } catch (RemoteException e) {
+            Rlog.e(TAG, "getImsEmergencyMMTelFeatureAndListen, RemoteException: "
+                    + e.getMessage());
+        }
+        return null;
+    }
+
+    /**
+     * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id and RCS
+     * feature for emergency calling or {@link null} if the service is not available. If an
+     * RcsFeature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
+     * listener for feature updates.
+     * @param slotIndex The SIM slot that we are requesting the {@link IImsRcsFeature} for.
+     * @param callback Listener that will send updates to ImsManager when there are updates to
+     * ImsServiceController.
+     * @return {@link IImsRcsFeature} interface for the feature specified or {@code null} if
+     * it is unavailable.
+     * @hide
+     */
+    public @Nullable IImsRcsFeature getImsRcsFeatureAndListen(int slotIndex,
+            IImsServiceFeatureCallback callback) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.getRcsFeatureAndListen(slotIndex, callback);
+            }
+        } catch (RemoteException e) {
+            Rlog.e(TAG, "getImsRcsFeatureAndListen, RemoteException: "
+                    + e.getMessage());
         }
         return null;
     }
@@ -5090,7 +5170,12 @@
         }
     }
 
-    /** @hide */
+    /**
+     * @deprecated Use  {@link android.telecom.TelecomManager#placeCall(Uri address,
+     * Bundle extras)} instead.
+     * @hide
+     */
+    @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.CALL_PHONE)
     public void call(String callingPackage, String number) {
@@ -5103,7 +5188,11 @@
         }
     }
 
-    /** @hide */
+    /**
+     * @deprecated Use {@link android.telecom.TelecomManager#endCall()} instead.
+     * @hide
+     */
+    @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.CALL_PHONE)
     public boolean endCall() {
@@ -5117,7 +5206,11 @@
         return false;
     }
 
-    /** @hide */
+    /**
+     * @deprecated Use {@link android.telecom.TelecomManager#acceptRingingCall} instead
+     * @hide
+     */
+    @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public void answerRingingCall() {
@@ -5130,7 +5223,11 @@
         }
     }
 
-    /** @hide */
+    /**
+     * @deprecated Use {@link android.telecom.TelecomManager#silenceRinger} instead
+     * @hide
+     */
+    @Deprecated
     @SystemApi
     @SuppressLint("Doclava125")
     public void silenceRinger() {
@@ -5593,29 +5690,6 @@
         return retVal;
     }
 
-    /**
-     * Returns the result and response from RIL for oem request
-     *
-     * @param oemReq the data is sent to ril.
-     * @param oemResp the respose data from RIL.
-     * @return negative value request was not handled or get error
-     *         0 request was handled succesfully, but no response data
-     *         positive value success, data length of response
-     * @hide
-     * @deprecated OEM needs a vendor-extension hal and their apps should use that instead
-     */
-    @Deprecated
-    public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
-        try {
-            ITelephony telephony = getITelephony();
-            if (telephony != null)
-                return telephony.invokeOemRilRequestRaw(oemReq, oemResp);
-        } catch (RemoteException ex) {
-        } catch (NullPointerException ex) {
-        }
-        return -1;
-    }
-
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@@ -5685,10 +5759,13 @@
     }
 
     /**
+     * @deprecated Use {link@ android.telecom.TelecomManager#isTtySupported} instead
      * Whether the phone supports TTY mode.
      *
      * @return {@code true} if the device supports TTY mode, and {@code false} otherwise.
+     *
      */
+    @Deprecated
     public boolean isTtyModeSupported() {
         try {
             ITelephony telephony = getITelephony();
@@ -5780,6 +5857,25 @@
    }
 
     /**
+     * Returns the IMS Registration Status for a particular Subscription ID
+     *
+     * @param subId Subscription ID
+     * @return true if IMS status is registered, false if the IMS status is not registered or a
+     * RemoteException occurred.
+     *
+     * @hide
+     */
+    public boolean isImsRegistered(int subId) {
+       try {
+           return getITelephony().isImsRegisteredForSubscriber(subId);
+       } catch (RemoteException ex) {
+           return false;
+       } catch (NullPointerException ex) {
+           return false;
+       }
+    }
+
+    /**
      * Returns the Status of Volte
      * @hide
      */
@@ -6650,6 +6746,25 @@
     }
 
     /**
+     * Action set from carrier signalling broadcast receivers to start/stop reporting default
+     * network available events
+     * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
+     * @param subId the subscription ID that this action applies to.
+     * @param report control start/stop reporting network status.
+     * @hide
+     */
+    public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                service.carrierActionReportDefaultNetworkStatus(subId, report);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelephony#carrierActionReportDefaultNetworkStatus", e);
+        }
+    }
+
+    /**
      * Get aggregated video call data usage since boot.
      * Permissions android.Manifest.permission.READ_NETWORK_USAGE_HISTORY is required.
      *
@@ -6744,7 +6859,6 @@
      * Get the most recent SignalStrength information reported by the modem. Due
      * to power saving this information may not always be current.
      * @return the most recent cached signal strength info from the modem
-     * @hide
      */
     @Nullable
     public SignalStrength getSignalStrength() {
@@ -6759,4 +6873,3 @@
         return null;
     }
 }
-
diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java
index 92a21b6..7bcdcdc 100644
--- a/telephony/java/android/telephony/TelephonyScanManager.java
+++ b/telephony/java/android/telephony/TelephonyScanManager.java
@@ -73,8 +73,8 @@
         /**
          * Informs the user that there is some error about the scan.
          *
-         * This callback will be called whenever there is any error about the scan, but the scan
-         * won't stop unless the onComplete() callback is called.
+         * This callback will be called whenever there is any error about the scan, and the scan
+         * will be terminated. onComplete() will NOT be called.
          */
         public void onError(int error) {}
     }
diff --git a/telephony/java/android/telephony/UiccAccessRule.aidl b/telephony/java/android/telephony/UiccAccessRule.aidl
new file mode 100644
index 0000000..f923c45
--- /dev/null
+++ b/telephony/java/android/telephony/UiccAccessRule.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.telephony;
+
+parcelable UiccAccessRule;
diff --git a/telephony/java/android/telephony/UiccAccessRule.java b/telephony/java/android/telephony/UiccAccessRule.java
new file mode 100644
index 0000000..e42a758
--- /dev/null
+++ b/telephony/java/android/telephony/UiccAccessRule.java
@@ -0,0 +1,230 @@
+/*
+ * 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.telephony;
+
+import android.annotation.Nullable;
+import android.content.pm.PackageInfo;
+import android.content.pm.Signature;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import com.android.internal.telephony.uicc.IccUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+
+/**
+ * Describes a single UICC access rule according to the GlobalPlatform Secure Element Access Control
+ * specification.
+ *
+ * @hide
+ *
+ * TODO(b/35851809): Make this a SystemApi.
+ */
+public final class UiccAccessRule implements Parcelable {
+    private static final String TAG = "UiccAccessRule";
+
+    private static final int ENCODING_VERSION = 1;
+
+    public static final Creator<UiccAccessRule> CREATOR = new Creator<UiccAccessRule>() {
+        @Override
+        public UiccAccessRule createFromParcel(Parcel in) {
+            return new UiccAccessRule(in);
+        }
+
+        @Override
+        public UiccAccessRule[] newArray(int size) {
+            return new UiccAccessRule[size];
+        }
+    };
+
+    /**
+     * Encode these access rules as a byte array which can be parsed with {@link #decodeRules}.
+     * @hide
+     */
+    @Nullable
+    public static byte[] encodeRules(@Nullable UiccAccessRule[] accessRules) {
+        if (accessRules == null) {
+            return null;
+        }
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            DataOutputStream output = new DataOutputStream(baos);
+            output.writeInt(ENCODING_VERSION);
+            output.writeInt(accessRules.length);
+            for (UiccAccessRule accessRule : accessRules) {
+                output.writeInt(accessRule.mCertificateHash.length);
+                output.write(accessRule.mCertificateHash);
+                if (accessRule.mPackageName != null) {
+                    output.writeBoolean(true);
+                    output.writeUTF(accessRule.mPackageName);
+                } else {
+                    output.writeBoolean(false);
+                }
+                output.writeLong(accessRule.mAccessType);
+            }
+            output.close();
+            return baos.toByteArray();
+        } catch (IOException e) {
+            throw new IllegalStateException(
+                    "ByteArrayOutputStream should never lead to an IOException", e);
+        }
+    }
+
+    /**
+     * Decodes a byte array generated with {@link #encodeRules}.
+     * @hide
+     */
+    @Nullable
+    public static UiccAccessRule[] decodeRules(@Nullable byte[] encodedRules) {
+        if (encodedRules == null) {
+            return null;
+        }
+        ByteArrayInputStream bais = new ByteArrayInputStream(encodedRules);
+        try (DataInputStream input = new DataInputStream(bais)) {
+            input.readInt(); // version; currently ignored
+            int count = input.readInt();
+            UiccAccessRule[] accessRules = new UiccAccessRule[count];
+            for (int i = 0; i < count; i++) {
+                int certificateHashLength = input.readInt();
+                byte[] certificateHash = new byte[certificateHashLength];
+                input.readFully(certificateHash);
+                String packageName = input.readBoolean() ? input.readUTF() : null;
+                long accessType = input.readLong();
+                accessRules[i] = new UiccAccessRule(certificateHash, packageName, accessType);
+            }
+            input.close();
+            return accessRules;
+        } catch (IOException e) {
+            throw new IllegalStateException(
+                    "ByteArrayInputStream should never lead to an IOException", e);
+        }
+    }
+
+    private final byte[] mCertificateHash;
+    private final @Nullable String mPackageName;
+    // This bit is not currently used, but reserved for future use.
+    private final long mAccessType;
+
+    public UiccAccessRule(byte[] certificateHash, @Nullable String packageName, long accessType) {
+        this.mCertificateHash = certificateHash;
+        this.mPackageName = packageName;
+        this.mAccessType = accessType;
+    }
+
+    UiccAccessRule(Parcel in) {
+        mCertificateHash = in.createByteArray();
+        mPackageName = in.readString();
+        mAccessType = in.readLong();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeByteArray(mCertificateHash);
+        dest.writeString(mPackageName);
+        dest.writeLong(mAccessType);
+    }
+
+    /**
+     * Return the package name this rule applies to.
+     *
+     * @return the package name, or null if this rule applies to any package signed with the given
+     *     certificate.
+     */
+    public @Nullable String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * Returns the carrier privilege status associated with the given package.
+     *
+     * @param packageInfo package info fetched from
+     *     {@link android.content.pm.PackageManager#getPackageInfo}.
+     *     {@link android.content.pm.PackageManager#GET_SIGNATURES} must have been passed in.
+     * @return either {@link TelephonyManager#CARRIER_PRIVILEGE_STATUS_HAS_ACCESS} or
+     *     {@link TelephonyManager#CARRIER_PRIVILEGE_STATUS_NO_ACCESS}.
+     */
+    public int getCarrierPrivilegeStatus(PackageInfo packageInfo) {
+        if (packageInfo.signatures == null || packageInfo.signatures.length == 0) {
+            throw new IllegalArgumentException(
+                    "Must use GET_SIGNATURES when looking up package info");
+        }
+
+        for (Signature sig : packageInfo.signatures) {
+            int accessStatus = getCarrierPrivilegeStatus(sig, packageInfo.packageName);
+            if (accessStatus != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) {
+                return accessStatus;
+            }
+        }
+
+        return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
+    }
+
+    /**
+     * Returns the carrier privilege status for the given certificate and package name.
+     *
+     * @param signature The signature of the certificate.
+     * @param packageName name of the package.
+     * @return either {@link TelephonyManager#CARRIER_PRIVILEGE_STATUS_HAS_ACCESS} or
+     *     {@link TelephonyManager#CARRIER_PRIVILEGE_STATUS_NO_ACCESS}.
+     */
+    public int getCarrierPrivilegeStatus(Signature signature, String packageName) {
+        // SHA-1 is for backward compatible support only, strongly discouraged for new use.
+        byte[] certHash = getCertHash(signature, "SHA-1");
+        byte[] certHash256 = getCertHash(signature, "SHA-256");
+        if (matches(certHash, packageName) || matches(certHash256, packageName)) {
+            return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
+        }
+
+        return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
+    }
+
+    private boolean matches(byte[] certHash, String packageName) {
+        return certHash != null && Arrays.equals(this.mCertificateHash, certHash) &&
+                (TextUtils.isEmpty(this.mPackageName) || this.mPackageName.equals(packageName));
+    }
+
+    @Override
+    public String toString() {
+        return "cert: " + IccUtils.bytesToHexString(mCertificateHash) + " pkg: " +
+                mPackageName + " access: " + mAccessType;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Converts a Signature into a Certificate hash usable for comparison.
+     */
+    private static byte[] getCertHash(Signature signature, String algo) {
+        try {
+            MessageDigest md = MessageDigest.getInstance(algo);
+            return md.digest(signature.toByteArray());
+        } catch (NoSuchAlgorithmException ex) {
+            Rlog.e(TAG, "NoSuchAlgorithmException: " + ex);
+        }
+        return null;
+    }
+}
diff --git a/telephony/java/android/telephony/euicc/DownloadableSubscription.aidl b/telephony/java/android/telephony/euicc/DownloadableSubscription.aidl
new file mode 100644
index 0000000..26679c9
--- /dev/null
+++ b/telephony/java/android/telephony/euicc/DownloadableSubscription.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.telephony.euicc;
+
+parcelable DownloadableSubscription;
diff --git a/telephony/java/android/telephony/euicc/DownloadableSubscription.java b/telephony/java/android/telephony/euicc/DownloadableSubscription.java
new file mode 100644
index 0000000..b5484e34
--- /dev/null
+++ b/telephony/java/android/telephony/euicc/DownloadableSubscription.java
@@ -0,0 +1,145 @@
+/*
+ * 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.telephony.euicc;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.UiccAccessRule;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Information about a subscription which is available for download.
+ *
+ * TODO(b/35851809): Make this public.
+ * @hide
+ */
+public final class DownloadableSubscription implements Parcelable {
+
+    public static final Creator<DownloadableSubscription> CREATOR =
+            new Creator<DownloadableSubscription>() {
+                @Override
+                public DownloadableSubscription createFromParcel(Parcel in) {
+                    return new DownloadableSubscription(in);
+                }
+
+                @Override
+                public DownloadableSubscription[] newArray(int size) {
+                    return new DownloadableSubscription[size];
+                }
+            };
+
+    /**
+     * Activation code. May be null for subscriptions which are not based on activation codes, e.g.
+     * to download a default subscription assigned to this device.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    @Nullable
+    public final String encodedActivationCode;
+
+    // see getCarrierName and setCarrierName
+    @Nullable
+    private String carrierName;
+    // see getAccessRules and setAccessRules
+    private UiccAccessRule[] accessRules;
+
+    /** @hide */
+    private DownloadableSubscription(String encodedActivationCode) {
+        this.encodedActivationCode = encodedActivationCode;
+    }
+
+    private DownloadableSubscription(Parcel in) {
+        encodedActivationCode = in.readString();
+        carrierName = in.readString();
+        accessRules = in.createTypedArray(UiccAccessRule.CREATOR);
+    }
+
+    /**
+     * Create a DownloadableSubscription for the given activation code.
+     *
+     * @param encodedActivationCode the activation code to use. Must not be null.
+     * @return the {@link DownloadableSubscription} which may be passed to
+     *     {@link EuiccManager#downloadSubscription}.
+     */
+    public static DownloadableSubscription forActivationCode(String encodedActivationCode) {
+        Preconditions.checkNotNull(encodedActivationCode, "Activation code may not be null");
+        return new DownloadableSubscription(encodedActivationCode);
+    }
+
+    /**
+     * Set the user-visible carrier name.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public void setCarrierName(String carrierName) {
+        this.carrierName = carrierName;
+    }
+
+    /**
+     * Returns the user-visible carrier name.
+     *
+     * <p>Only present for downloadable subscriptions that were queried from a server (as opposed to
+     * those created with {@link #forActivationCode}). May be populated with
+     * {@link EuiccManager#getDownloadableSubscriptionMetadata}.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    @Nullable
+    public String getCarrierName() {
+        return carrierName;
+    }
+
+    /**
+     * Returns the {@link UiccAccessRule}s dictating access to this subscription.
+     *
+     * <p>Only present for downloadable subscriptions that were queried from a server (as opposed to
+     * those created with {@link #forActivationCode}). May be populated with
+     * {@link EuiccManager#getDownloadableSubscriptionMetadata}.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public UiccAccessRule[] getAccessRules() {
+        return accessRules;
+    }
+
+    /**
+     * Set the {@link UiccAccessRule}s dictating access to this subscription.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public void setAccessRules(UiccAccessRule[] accessRules) {
+        this.accessRules = accessRules;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(encodedActivationCode);
+        dest.writeString(carrierName);
+        dest.writeTypedArray(accessRules, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/telephony/java/android/telephony/euicc/EuiccInfo.aidl b/telephony/java/android/telephony/euicc/EuiccInfo.aidl
new file mode 100644
index 0000000..3cfba75
--- /dev/null
+++ b/telephony/java/android/telephony/euicc/EuiccInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.telephony.euicc;
+
+parcelable EuiccInfo;
diff --git a/telephony/java/android/telephony/euicc/EuiccInfo.java b/telephony/java/android/telephony/euicc/EuiccInfo.java
new file mode 100644
index 0000000..5bfff08
--- /dev/null
+++ b/telephony/java/android/telephony/euicc/EuiccInfo.java
@@ -0,0 +1,72 @@
+/*
+ * 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.telephony.euicc;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information about an eUICC chip/device.
+ *
+ * @see EuiccManager#getEuiccInfo
+ * @hide
+ *
+ * TODO(b/35851809): Make this public.
+ */
+// WARNING: Do not add any privacy-sensitive fields to this class (such as an eUICC identifier)!
+// This API is accessible to all applications. Privacy-sensitive fields should be returned in their
+// own APIs guarded with appropriate permission checks.
+public final class EuiccInfo implements Parcelable {
+
+    public static final Creator<EuiccInfo> CREATOR =
+            new Creator<EuiccInfo>() {
+                @Override
+                public EuiccInfo createFromParcel(Parcel in) {
+                    return new EuiccInfo(in);
+                }
+
+                @Override
+                public EuiccInfo[] newArray(int size) {
+                    return new EuiccInfo[size];
+                }
+            };
+
+    /**
+     * Version of the operating system running on the eUICC. This field is hardware-specific and is
+     * not guaranteed to match any particular format.
+     */
+    @Nullable
+    public final String osVersion;
+
+    public EuiccInfo(@Nullable String osVersion) {
+        this.osVersion = osVersion;
+    }
+
+    private EuiccInfo(Parcel in) {
+        osVersion = in.readString();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(osVersion);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
new file mode 100644
index 0000000..8304d84
--- /dev/null
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -0,0 +1,515 @@
+/*
+ * 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.telephony.euicc;
+
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+import com.android.internal.telephony.euicc.IEuiccController;
+
+/**
+ * EuiccManager is the application interface to eUICCs, or eSIMs/embedded SIMs.
+ *
+ * <p>You do not instantiate this class directly; instead, you retrieve an instance through
+ * {@link Context#getSystemService(String)} and {@link Context#EUICC_SERVICE}.
+ *
+ * <p>See {@link #isEnabled} before attempting to use these APIs.
+ *
+ * TODO(b/35851809): Make this public.
+ * @hide
+ */
+public class EuiccManager {
+
+    /**
+     * Intent action to launch the embedded SIM (eUICC) management settings screen.
+     *
+     * <p>This screen shows a list of embedded profiles and offers the user the ability to switch
+     * between them, download new profiles, and delete unused profiles.
+     *
+     * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
+     * {@link #isEnabled} is false.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS =
+            "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
+
+    /**
+     * Intent action to provision an embedded subscription.
+     *
+     * <p>May be called during device provisioning to launch a screen to perform embedded SIM
+     * provisioning, e.g. if no physical SIM is present and the user elects to configure their
+     * embedded SIM.
+     *
+     * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
+     * {@link #isEnabled} is false or if the device is already provisioned.
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION =
+            "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
+
+    /**
+     * Intent action to handle a resolvable error.
+     * @hide
+     */
+    public static final String ACTION_RESOLVE_ERROR =
+            "android.telephony.euicc.action.RESOLVE_ERROR";
+
+    /**
+     * Result code for an operation indicating that the operation succeeded.
+     */
+    public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0;
+
+    /**
+     * Result code for an operation indicating that the user must take some action before the
+     * operation can continue.
+     *
+     * @see #startResolutionActivity
+     */
+    public static final int EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR = 1;
+
+    /**
+     * Result code for an operation indicating that an unresolvable error occurred.
+     *
+     * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} will be populated with a detailed error
+     * code for logging/debugging purposes only.
+     */
+    public static final int EMBEDDED_SUBSCRIPTION_RESULT_ERROR = 2;
+
+    /**
+     * Key for an extra set on {@link PendingIntent} result callbacks providing a detailed result
+     * code.
+     *
+     * <p>This code is an implementation detail of the embedded subscription manager and is only
+     * intended for logging or debugging purposes.
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE";
+
+    /**
+     * Key for an extra set on {@link #getDownloadableSubscriptionMetadata} PendingIntent result
+     * callbacks providing the downloadable subscription metadata.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
+
+    /**
+     * Key for an extra set on {@link #getDefaultDownloadableSubscriptionList} PendingIntent result
+     * callbacks providing the list of available downloadable subscriptions.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS";
+
+    /**
+     * Key for an extra set on {@link PendingIntent} result callbacks providing the resolution
+     * pending intent for {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}s.
+     * @hide
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT";
+
+    /**
+     * Key for an extra set on the {@link #EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT} intent
+     * containing the EuiccService action to launch for resolution.
+     * @hide
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION";
+
+    /**
+     * Key for an extra set on the {@link #EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT} intent
+     * providing the callback to execute after resolution is completed.
+     * @hide
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT";
+
+    /**
+     * Optional meta-data attribute for a carrier app providing an icon to use to represent the
+     * carrier. If not provided, the app's launcher icon will be used as a fallback.
+     */
+    public static final String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon";
+
+    private final Context mContext;
+    private final IEuiccController mController;
+
+    /** @hide */
+    public EuiccManager(Context context) {
+        mContext = context;
+        mController = IEuiccController.Stub.asInterface(ServiceManager.getService("econtroller"));
+    }
+
+    /**
+     * Whether embedded subscriptions are currently enabled.
+     *
+     * <p>Even on devices with the {@link PackageManager#FEATURE_TELEPHONY_EUICC} feature, embedded
+     * subscriptions may be turned off, e.g. because of a carrier restriction from an inserted
+     * physical SIM. Therefore, this runtime check should be used before accessing embedded
+     * subscription APIs.
+     *
+     * @return true if embedded subscriptions are currently enabled.
+     */
+    public boolean isEnabled() {
+        // In the future, this may reach out to IEuiccController (if non-null) to check any dynamic
+        // restrictions.
+        return mController != null;
+    }
+
+    /**
+     * Returns the EID identifying the eUICC hardware.
+     *
+     * <p>Requires that the calling app has carrier privileges on the active subscription on the
+     * eUICC.
+     *
+     * @return the EID. May be null if {@link #isEnabled()} is false or the eUICC is not ready.
+     */
+    @Nullable
+    public String getEid() {
+        if (!isEnabled()) {
+            return null;
+        }
+        try {
+            return mController.getEid();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Attempt to download the given {@link DownloadableSubscription}.
+     *
+     * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
+     * or the calling app must be authorized to manage both the currently-active subscription and
+     * the subscription to be downloaded according to the subscription metadata. Without the former,
+     * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
+     * intent to prompt the user to accept the download.
+     *
+     * @param subscription the subscription to download.
+     * @param switchAfterDownload if true, the profile will be activated upon successful download.
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     */
+    public void downloadSubscription(DownloadableSubscription subscription,
+            boolean switchAfterDownload, PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.downloadSubscription(subscription, switchAfterDownload,
+                    mContext.getOpPackageName(), callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Start an activity to resolve a user-resolvable error.
+     *
+     * <p>If an operation returns {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}, this
+     * method may be called to prompt the user to resolve the issue.
+     *
+     * <p>This method may only be called once for a particular error.
+     *
+     * @param activity the calling activity (which should be in the foreground).
+     * @param requestCode an application-specific request code which will be provided to
+     *     {@link Activity#onActivityResult} upon completion. Note that the operation may still be
+     *     in progress when the resolution activity completes; it is not fully finished until the
+     *     callback intent is triggered.
+     * @param resultIntent the Intent provided to the initial callback intent which failed with
+     *     {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}.
+     * @param callbackIntent a PendingIntent to launch when the operation completes. This is
+     *     trigered upon completion of the original operation that required user resolution.
+     * @throws android.content.IntentSender.SendIntentException if called more than once.
+     */
+    public void startResolutionActivity(Activity activity, int requestCode, Intent resultIntent,
+            PendingIntent callbackIntent) throws IntentSender.SendIntentException {
+        PendingIntent resolutionIntent =
+                resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT);
+        if (resolutionIntent == null) {
+            throw new IllegalArgumentException("Invalid result intent");
+        }
+        Intent fillInIntent = new Intent();
+        fillInIntent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT,
+                callbackIntent);
+        activity.startIntentSenderForResult(resolutionIntent.getIntentSender(), requestCode,
+                fillInIntent, 0 /* flagsMask */, 0 /* flagsValues */, 0 /* extraFlags */);
+    }
+
+    /**
+     * Continue an operation after the user resolves an error.
+     *
+     * <p>To be called by the LUI upon completion of a resolvable error flow.
+     *
+     * @param resolutionIntent The original intent used to start the LUI.
+     * @param resolutionExtras Resolution-specific extras depending on the result of the resolution.
+     *     For example, this may indicate whether the user has consented or may include the input
+     *     they provided.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public void continueOperation(Intent resolutionIntent, Bundle resolutionExtras) {
+        if (!isEnabled()) {
+            PendingIntent callbackIntent =
+                    resolutionIntent.getParcelableExtra(
+                            EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT);
+            if (callbackIntent != null) {
+                sendUnavailableError(callbackIntent);
+            }
+            return;
+        }
+        try {
+            mController.continueOperation(resolutionIntent, resolutionExtras);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Fills in the metadata for a DownloadableSubscription.
+     *
+     * <p>May be used in cases that a DownloadableSubscription was constructed to download a
+     * profile, but the metadata for the profile is unknown (e.g. we only know the activation code).
+     * The callback will be triggered with an Intent with
+     * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION} set to the
+     * downloadable subscription metadata upon success.
+     *
+     * <p>Requires that the calling app has the
+     * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
+     * internal system use only.
+     *
+     * @param subscription the subscription which needs metadata filled in
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public void getDownloadableSubscriptionMetadata(
+            DownloadableSubscription subscription, PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.getDownloadableSubscriptionMetadata(
+                    subscription, mContext.getOpPackageName(), callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Gets metadata for subscription which are available for download on this device.
+     *
+     * <p>Subscriptions returned here may be passed to {@link #downloadSubscription}. They may have
+     * been pre-assigned to this particular device, for example. The callback will be triggered with
+     * an Intent with {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS} set to the
+     * list of available subscriptions upon success.
+     *
+     * <p>Requires that the calling app has the
+     * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
+     * internal system use only.
+     *
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public void getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.getDefaultDownloadableSubscriptionList(
+                    mContext.getOpPackageName(), callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns information about the eUICC chip/device.
+     *
+     * @return the {@link EuiccInfo}. May be null if {@link #isEnabled()} is false or the eUICC is
+     *     not ready.
+     */
+    @Nullable
+    public EuiccInfo getEuiccInfo() {
+        if (!isEnabled()) {
+            return null;
+        }
+        try {
+            return mController.getEuiccInfo();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Deletes the given subscription.
+     *
+     * <p>If this subscription is currently active, the device will first switch away from it onto
+     * an "empty" subscription.
+     *
+     * <p>Requires that the calling app has carrier privileges according to the metadata of the
+     * profile to be deleted, or the
+     * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
+     *
+     * @param subscriptionId the ID of the subscription to delete.
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     */
+    public void deleteSubscription(int subscriptionId, PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.deleteSubscription(
+                    subscriptionId, mContext.getOpPackageName(), callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Switch to (enable) the given subscription.
+     *
+     * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
+     * or the calling app must be authorized to manage both the currently-active subscription and
+     * the subscription to be enabled according to the subscription metadata. Without the former,
+     * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
+     * intent to prompt the user to accept the download.
+     *
+     * @param subscriptionId the ID of the subscription to enable. May be
+     *     {@link android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID} to deactivate the
+     *     current profile without activating another profile to replace it.
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     */
+    public void switchToSubscription(int subscriptionId, PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.switchToSubscription(
+                    subscriptionId, mContext.getOpPackageName(), callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Update the nickname for the given subscription.
+     *
+     * <p>Requires that the calling app has the
+     * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
+     * internal system use only.
+     *
+     * @param subscriptionId the ID of the subscription to update.
+     * @param nickname the new nickname to apply.
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     * @hide
+     */
+    public void updateSubscriptionNickname(
+            int subscriptionId, String nickname, PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.updateSubscriptionNickname(subscriptionId, nickname, callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Erase all subscriptions and reset the eUICC.
+     *
+     * <p>Requires that the calling app has the
+     * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
+     * internal system use only.
+     *
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     * @hide
+     */
+    public void eraseSubscriptions(PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.eraseSubscriptions(callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Ensure that subscriptions will be retained on the next factory reset.
+     *
+     * <p>By default, all subscriptions on the eUICC are erased the first time a device boots (ever
+     * and after factory resets). This ensures that the data is wiped after a factory reset is
+     * performed via fastboot or recovery mode, as these modes do not support the necessary radio
+     * communication needed to wipe the eSIM.
+     *
+     * <p>However, this method may be called right before a factory reset issued via settings when
+     * the user elects to retain subscriptions. Doing so will mark them for retention so that they
+     * are not cleared after the ensuing reset.
+     *
+     * <p>Requires that the calling app has the {@link android.Manifest.permission#MASTER_CLEAR}
+     * permission. This is for internal system use only.
+     *
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     * @hide
+     */
+    public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.retainSubscriptionsForFactoryReset(callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    private static void sendUnavailableError(PendingIntent callbackIntent) {
+        try {
+            callbackIntent.send(EMBEDDED_SUBSCRIPTION_RESULT_ERROR);
+        } catch (PendingIntent.CanceledException e) {
+            // Caller canceled the callback; do nothing.
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java
index 9d91cc3..8230eaf 100644
--- a/telephony/java/android/telephony/ims/ImsService.java
+++ b/telephony/java/android/telephony/ims/ImsService.java
@@ -16,13 +16,11 @@
 
 package android.telephony.ims;
 
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
-import android.app.PendingIntent;
 import android.app.Service;
 import android.content.Intent;
-import android.content.pm.PackageManager;
 import android.os.IBinder;
-import android.os.Message;
 import android.os.RemoteException;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ims.feature.ImsFeature;
@@ -31,22 +29,13 @@
 import android.util.Log;
 import android.util.SparseArray;
 
-import com.android.ims.ImsCallProfile;
-import com.android.ims.internal.IImsCallSession;
-import com.android.ims.internal.IImsCallSessionListener;
-import com.android.ims.internal.IImsConfig;
-import com.android.ims.internal.IImsEcbm;
 import com.android.ims.internal.IImsFeatureStatusCallback;
-import com.android.ims.internal.IImsMultiEndpoint;
-import com.android.ims.internal.IImsRegistrationListener;
+import com.android.ims.internal.IImsMMTelFeature;
+import com.android.ims.internal.IImsRcsFeature;
 import com.android.ims.internal.IImsServiceController;
-import com.android.ims.internal.IImsServiceFeatureListener;
-import com.android.ims.internal.IImsUt;
 import com.android.internal.annotations.VisibleForTesting;
 
 import static android.Manifest.permission.MODIFY_PHONE_STATE;
-import static android.Manifest.permission.READ_PHONE_STATE;
-import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
 
 /**
  * Main ImsService implementation, which binds via the Telephony ImsResolver. Services that extend
@@ -92,247 +81,38 @@
      */
     public static final String SERVICE_INTERFACE = "android.telephony.ims.ImsService";
 
-    // A map of slot Id -> Set of features corresponding to that slot.
-    private final SparseArray<SparseArray<ImsFeature>> mFeatures = new SparseArray<>();
+    // A map of slot Id -> map of features (indexed by ImsFeature feature id) corresponding to that
+    // slot.
+    // We keep track of this to facilitate cleanup of the IImsFeatureStatusCallback and
+    // call ImsFeature#onFeatureRemoved.
+    private final SparseArray<SparseArray<ImsFeature>> mFeaturesBySlot = new SparseArray<>();
 
     /**
      * @hide
      */
-    // Implements all supported features as a flat interface.
     protected final IBinder mImsServiceController = new IImsServiceController.Stub() {
 
         @Override
-        public void createImsFeature(int slotId, int feature, IImsFeatureStatusCallback c)
+        public IImsMMTelFeature createEmergencyMMTelFeature(int slotId,
+                IImsFeatureStatusCallback c) {
+            return createEmergencyMMTelFeatureInternal(slotId, c);
+        }
+
+        @Override
+        public IImsMMTelFeature createMMTelFeature(int slotId, IImsFeatureStatusCallback c) {
+            return createMMTelFeatureInternal(slotId, c);
+        }
+
+        @Override
+        public IImsRcsFeature createRcsFeature(int slotId, IImsFeatureStatusCallback c) {
+            return createRcsFeatureInternal(slotId, c);
+        }
+
+        @Override
+        public void removeImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c)
                 throws RemoteException {
-            synchronized (mFeatures) {
-                enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "createImsFeature");
-                onCreateImsFeatureInternal(slotId, feature, c);
-            }
+            ImsService.this.removeImsFeature(slotId, featureType, c);
         }
-
-        @Override
-        public void removeImsFeature(int slotId, int feature,  IImsFeatureStatusCallback c)
-                throws RemoteException {
-            synchronized (mFeatures) {
-                enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "removeImsFeature");
-                onRemoveImsFeatureInternal(slotId, feature, c);
-            }
-        }
-
-        @Override
-        public int startSession(int slotId, int featureType, PendingIntent incomingCallIntent,
-                IImsRegistrationListener listener) throws RemoteException {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "startSession");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    return feature.startSession(incomingCallIntent, listener);
-                }
-            }
-            return 0;
-        }
-
-        @Override
-        public void endSession(int slotId, int featureType, int sessionId) throws RemoteException {
-            synchronized (mFeatures) {
-                enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "endSession");
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    feature.endSession(sessionId);
-                }
-            }
-        }
-
-        @Override
-        public boolean isConnected(int slotId, int featureType, int callSessionType, int callType)
-                throws RemoteException {
-            enforceReadPhoneStatePermission("isConnected");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    return feature.isConnected(callSessionType, callType);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean isOpened(int slotId, int featureType) throws RemoteException {
-            enforceReadPhoneStatePermission("isOpened");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    return feature.isOpened();
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public int getFeatureStatus(int slotId, int featureType) throws RemoteException {
-            enforceReadPhoneStatePermission("getFeatureStatus");
-            int status = ImsFeature.STATE_NOT_AVAILABLE;
-            synchronized (mFeatures) {
-                SparseArray<ImsFeature> featureMap = mFeatures.get(slotId);
-                if (featureMap != null) {
-                    ImsFeature feature = getImsFeatureFromType(featureMap, featureType);
-                    if (feature != null) {
-                        status = feature.getFeatureState();
-                    }
-                }
-            }
-            return status;
-        }
-
-        @Override
-        public void addRegistrationListener(int slotId, int featureType,
-                IImsRegistrationListener listener) throws RemoteException {
-            enforceReadPhoneStatePermission("addRegistrationListener");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    feature.addRegistrationListener(listener);
-                }
-            }
-        }
-
-        @Override
-        public void removeRegistrationListener(int slotId, int featureType,
-                IImsRegistrationListener listener) throws RemoteException {
-            enforceReadPhoneStatePermission("removeRegistrationListener");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    feature.removeRegistrationListener(listener);
-                }
-            }
-        }
-
-        @Override
-        public ImsCallProfile createCallProfile(int slotId, int featureType, int sessionId,
-                int callSessionType, int callType) throws RemoteException {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "createCallProfile");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    return feature.createCallProfile(sessionId, callSessionType,  callType);
-                }
-            }
-            return null;
-        }
-
-        @Override
-        public IImsCallSession createCallSession(int slotId, int featureType, int sessionId,
-                ImsCallProfile profile, IImsCallSessionListener listener) throws RemoteException {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "createCallSession");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    return feature.createCallSession(sessionId, profile, listener);
-                }
-            }
-            return null;
-        }
-
-        @Override
-        public IImsCallSession getPendingCallSession(int slotId, int featureType, int sessionId,
-                String callId) throws RemoteException {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "getPendingCallSession");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    return feature.getPendingCallSession(sessionId, callId);
-                }
-            }
-            return null;
-        }
-
-        @Override
-        public IImsUt getUtInterface(int slotId, int featureType)
-                throws RemoteException {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "getUtInterface");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    return feature.getUtInterface();
-                }
-            }
-            return null;
-        }
-
-        @Override
-        public IImsConfig getConfigInterface(int slotId, int featureType)
-                throws RemoteException {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "getConfigInterface");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    return feature.getConfigInterface();
-                }
-            }
-            return null;
-        }
-
-        @Override
-        public void turnOnIms(int slotId, int featureType) throws RemoteException {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "turnOnIms");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    feature.turnOnIms();
-                }
-            }
-        }
-
-        @Override
-        public void turnOffIms(int slotId, int featureType) throws RemoteException {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "turnOffIms");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    feature.turnOffIms();
-                }
-            }
-        }
-
-        @Override
-        public IImsEcbm getEcbmInterface(int slotId, int featureType)
-                throws RemoteException {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "getEcbmInterface");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    return feature.getEcbmInterface();
-                }
-            }
-            return null;
-        }
-
-        @Override
-        public void setUiTTYMode(int slotId, int featureType, int uiTtyMode, Message onComplete)
-                throws RemoteException {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "setUiTTYMode");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    feature.setUiTTYMode(uiTtyMode, onComplete);
-                }
-            }
-        }
-
-        @Override
-        public IImsMultiEndpoint getMultiEndpointInterface(int slotId, int featureType)
-                throws RemoteException {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "getMultiEndpointInterface");
-            synchronized (mFeatures) {
-                MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
-                if (feature != null) {
-                    return feature.getMultiEndpointInterface();
-                }
-            }
-            return null;
-        }
-
     };
 
     /**
@@ -341,127 +121,93 @@
     @Override
     public IBinder onBind(Intent intent) {
         if(SERVICE_INTERFACE.equals(intent.getAction())) {
+            Log.i(LOG_TAG, "ImsService Bound.");
             return mImsServiceController;
         }
         return null;
     }
 
     /**
-     * Called from the ImsResolver to create the requested ImsFeature, as defined by the slot and
-     * featureType
-     * @param slotId An integer representing which SIM slot the ImsFeature is assigned to.
-     * @param featureType An integer representing the type of ImsFeature being created. This is
-     * defined in {@link ImsFeature}.
+     * @hide
      */
-    // Be sure to lock on mFeatures before accessing this method
-    private void onCreateImsFeatureInternal(int slotId, int featureType,
+    @VisibleForTesting
+    public SparseArray<ImsFeature> getFeatures(int slotId) {
+        return mFeaturesBySlot.get(slotId);
+    }
+
+    private IImsMMTelFeature createEmergencyMMTelFeatureInternal(int slotId,
             IImsFeatureStatusCallback c) {
-        SparseArray<ImsFeature> featureMap = mFeatures.get(slotId);
-        if (featureMap == null) {
-            featureMap = new SparseArray<>();
-            mFeatures.put(slotId, featureMap);
-        }
-        ImsFeature f = makeImsFeature(slotId, featureType);
+        MMTelFeature f = onCreateEmergencyMMTelImsFeature(slotId);
         if (f != null) {
-            f.setContext(this);
-            f.setSlotId(slotId);
-            f.addImsFeatureStatusCallback(c);
-            featureMap.put(featureType, f);
-        }
-
-    }
-    /**
-     * Called from the ImsResolver to remove an existing ImsFeature, as defined by the slot and
-     * featureType.
-     * @param slotId An integer representing which SIM slot the ImsFeature is assigned to.
-     * @param featureType An integer representing the type of ImsFeature being removed. This is
-     * defined in {@link ImsFeature}.
-     */
-    // Be sure to lock on mFeatures before accessing this method
-    private void onRemoveImsFeatureInternal(int slotId, int featureType,
-            IImsFeatureStatusCallback c) {
-        SparseArray<ImsFeature> featureMap = mFeatures.get(slotId);
-        if (featureMap == null) {
-            return;
-        }
-
-        ImsFeature featureToRemove = getImsFeatureFromType(featureMap, featureType);
-        if (featureToRemove != null) {
-            featureMap.remove(featureType);
-            featureToRemove.notifyFeatureRemoved(slotId);
-            // Remove reference to Binder
-            featureToRemove.removeImsFeatureStatusCallback(c);
-        }
-    }
-
-    // Be sure to lock on mFeatures before accessing this method
-    private MMTelFeature resolveMMTelFeature(int slotId, int featureType) {
-        SparseArray<ImsFeature> features = getImsFeatureMap(slotId);
-        MMTelFeature feature = null;
-        if (features != null) {
-            feature = resolveImsFeature(features, featureType, MMTelFeature.class);
-        }
-        return feature;
-    }
-
-    // Be sure to lock on mFeatures before accessing this method
-    private <T extends ImsFeature> T resolveImsFeature(SparseArray<ImsFeature> set, int featureType,
-            Class<T> className) {
-        ImsFeature feature = getImsFeatureFromType(set, featureType);
-        if (feature == null) {
+            setupFeature(f, slotId, ImsFeature.EMERGENCY_MMTEL, c);
+            return f.getBinder();
+        } else {
             return null;
         }
-        try {
-            return className.cast(feature);
-        } catch (ClassCastException e)
-        {
-            Log.e(LOG_TAG, "Can not cast ImsFeature! Exception: " + e.getMessage());
+    }
+
+    private IImsMMTelFeature createMMTelFeatureInternal(int slotId,
+            IImsFeatureStatusCallback c) {
+        MMTelFeature f = onCreateMMTelImsFeature(slotId);
+        if (f != null) {
+            setupFeature(f, slotId, ImsFeature.MMTEL, c);
+            return f.getBinder();
+        } else {
+            return null;
         }
-        return null;
     }
 
-    /**
-     * @hide
-     */
-    @VisibleForTesting
-    // Be sure to lock on mFeatures before accessing this method
-    public SparseArray<ImsFeature> getImsFeatureMap(int slotId) {
-        return mFeatures.get(slotId);
-    }
-
-    /**
-     * @hide
-     */
-    @VisibleForTesting
-    // Be sure to lock on mFeatures before accessing this method
-    public ImsFeature getImsFeatureFromType(SparseArray<ImsFeature> set, int featureType) {
-        return set.get(featureType);
-    }
-
-    private ImsFeature makeImsFeature(int slotId, int feature) {
-        switch (feature) {
-            case ImsFeature.EMERGENCY_MMTEL: {
-                return onCreateEmergencyMMTelImsFeature(slotId);
-            }
-            case ImsFeature.MMTEL: {
-                return onCreateMMTelImsFeature(slotId);
-            }
-            case ImsFeature.RCS: {
-                return onCreateRcsFeature(slotId);
-            }
+    private IImsRcsFeature createRcsFeatureInternal(int slotId,
+            IImsFeatureStatusCallback c) {
+        RcsFeature f = onCreateRcsFeature(slotId);
+        if (f != null) {
+            setupFeature(f, slotId, ImsFeature.RCS, c);
+            return f.getBinder();
+        } else {
+            return null;
         }
-        // Tried to create feature that is not defined.
-        return null;
     }
 
-    /**
-     * Check for both READ_PHONE_STATE and READ_PRIVILEGED_PHONE_STATE. READ_PHONE_STATE is a
-     * public permission and READ_PRIVILEGED_PHONE_STATE is only granted to system apps.
-     */
-    private void enforceReadPhoneStatePermission(String fn) {
-        if (checkCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE)
-                != PackageManager.PERMISSION_GRANTED) {
-            enforceCallingOrSelfPermission(READ_PHONE_STATE, fn);
+    private void setupFeature(ImsFeature f, int slotId, int featureType,
+            IImsFeatureStatusCallback c) {
+        f.setContext(this);
+        f.setSlotId(slotId);
+        f.addImsFeatureStatusCallback(c);
+        addImsFeature(slotId, featureType, f);
+    }
+
+    private void addImsFeature(int slotId, int featureType, ImsFeature f) {
+        synchronized (mFeaturesBySlot) {
+            // Get SparseArray for Features, by querying slot Id
+            SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId);
+            if (features == null) {
+                // Populate new SparseArray of features if it doesn't exist for this slot yet.
+                features = new SparseArray<>();
+                mFeaturesBySlot.put(slotId, features);
+            }
+            features.put(featureType, f);
+        }
+    }
+
+    private void removeImsFeature(int slotId, int featureType,
+            IImsFeatureStatusCallback c) {
+        synchronized (mFeaturesBySlot) {
+            // get ImsFeature associated with the slot/feature
+            SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId);
+            if (features == null) {
+                Log.w(LOG_TAG, "Can not remove ImsFeature. No ImsFeatures exist on slot "
+                        + slotId);
+                return;
+            }
+            ImsFeature f = features.get(featureType);
+            if (f == null) {
+                Log.w(LOG_TAG, "Can not remove ImsFeature. No feature with type "
+                        + featureType + " exists on slot " + slotId);
+                return;
+            }
+            f.removeImsFeatureStatusCallback(c);
+            f.onFeatureRemoved();
+            features.remove(featureType);
         }
     }
 
@@ -470,7 +216,7 @@
      * functionality. Must be able to handle emergency calls at any time as well.
      * @hide
      */
-    public MMTelFeature onCreateEmergencyMMTelImsFeature(int slotId) {
+    public @Nullable MMTelFeature onCreateEmergencyMMTelImsFeature(int slotId) {
         return null;
     }
 
@@ -479,7 +225,7 @@
      * functionality.
      * @hide
      */
-    public MMTelFeature onCreateMMTelImsFeature(int slotId) {
+    public @Nullable MMTelFeature onCreateMMTelImsFeature(int slotId) {
         return null;
     }
 
@@ -487,7 +233,7 @@
      * @return An implementation of RcsFeature that will be used by the system for RCS.
      * @hide
      */
-    public RcsFeature onCreateRcsFeature(int slotId) {
+    public @Nullable RcsFeature onCreateRcsFeature(int slotId) {
         return null;
     }
 }
diff --git a/telephony/java/android/telephony/ims/ImsServiceProxy.java b/telephony/java/android/telephony/ims/ImsServiceProxy.java
deleted file mode 100644
index 038e295..0000000
--- a/telephony/java/android/telephony/ims/ImsServiceProxy.java
+++ /dev/null
@@ -1,335 +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.telephony.ims;
-
-import android.app.PendingIntent;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.telephony.ims.feature.IRcsFeature;
-import android.telephony.ims.feature.ImsFeature;
-import android.util.Log;
-
-import com.android.ims.ImsCallProfile;
-import com.android.ims.internal.IImsCallSession;
-import com.android.ims.internal.IImsCallSessionListener;
-import com.android.ims.internal.IImsConfig;
-import com.android.ims.internal.IImsEcbm;
-import com.android.ims.internal.IImsMultiEndpoint;
-import com.android.ims.internal.IImsRegistrationListener;
-import com.android.ims.internal.IImsServiceController;
-import com.android.ims.internal.IImsServiceFeatureListener;
-import com.android.ims.internal.IImsUt;
-
-/**
- * A container of the IImsServiceController binder, which implements all of the ImsFeatures that
- * the platform currently supports: MMTel and RCS.
- * @hide
- */
-
-public class ImsServiceProxy extends ImsServiceProxyCompat implements IRcsFeature {
-
-    protected String LOG_TAG = "ImsServiceProxy";
-    private final int mSupportedFeature;
-
-    // Start by assuming the proxy is available for usage.
-    private boolean mIsAvailable = true;
-    // ImsFeature Status from the ImsService. Cached.
-    private Integer mFeatureStatusCached = null;
-    private ImsServiceProxy.INotifyStatusChanged mStatusCallback;
-    private final Object mLock = new Object();
-
-    public interface INotifyStatusChanged {
-        void notifyStatusChanged();
-    }
-
-    private final IImsServiceFeatureListener mListenerBinder =
-            new IImsServiceFeatureListener.Stub() {
-
-        @Override
-        public void imsFeatureCreated(int slotId, int feature) throws RemoteException {
-            // The feature has been re-enabled. This may happen when the service crashes.
-            synchronized (mLock) {
-                if (!mIsAvailable && mSlotId == slotId && feature == mSupportedFeature) {
-                    Log.i(LOG_TAG, "Feature enabled on slotId: " + slotId + " for feature: " +
-                            feature);
-                    mIsAvailable = true;
-                }
-            }
-        }
-
-        @Override
-        public void imsFeatureRemoved(int slotId, int feature) throws RemoteException {
-            synchronized (mLock) {
-                if (mIsAvailable && mSlotId == slotId && feature == mSupportedFeature) {
-                    Log.i(LOG_TAG, "Feature disabled on slotId: " + slotId + " for feature: " +
-                            feature);
-                    mIsAvailable = false;
-                }
-            }
-        }
-
-        @Override
-        public void imsStatusChanged(int slotId, int feature, int status) throws RemoteException {
-            synchronized (mLock) {
-                Log.i(LOG_TAG, "imsStatusChanged: slot: " + slotId + " feature: " + feature +
-                        " status: " + status);
-                if (mSlotId == slotId && feature == mSupportedFeature) {
-                    mFeatureStatusCached = status;
-                    if (mStatusCallback != null) {
-                        mStatusCallback.notifyStatusChanged();
-                    }
-                }
-            }
-        }
-    };
-
-    public ImsServiceProxy(int slotId, IBinder binder, int featureType) {
-        super(slotId, binder);
-        mSupportedFeature = featureType;
-    }
-
-    public ImsServiceProxy(int slotId, int featureType) {
-        super(slotId, null /*IBinder*/);
-        mSupportedFeature = featureType;
-    }
-
-    public IImsServiceFeatureListener getListener() {
-        return mListenerBinder;
-    }
-
-    public void setBinder(IBinder binder) {
-        mBinder = binder;
-    }
-
-    @Override
-    public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener)
-            throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).startSession(mSlotId, mSupportedFeature,
-                    incomingCallIntent, listener);
-        }
-    }
-
-    @Override
-    public void endSession(int sessionId) throws RemoteException {
-        synchronized (mLock) {
-            // Only check to make sure the binder connection still exists. This method should
-            // still be able to be called when the state is STATE_NOT_AVAILABLE.
-            checkBinderConnection();
-            getServiceInterface(mBinder).endSession(mSlotId, mSupportedFeature, sessionId);
-        }
-    }
-
-    @Override
-    public boolean isConnected(int callServiceType, int callType)
-            throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).isConnected(mSlotId, mSupportedFeature,
-                    callServiceType, callType);
-        }
-    }
-
-    @Override
-    public boolean isOpened() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).isOpened(mSlotId, mSupportedFeature);
-        }
-    }
-
-    @Override
-    public void addRegistrationListener(IImsRegistrationListener listener)
-    throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).addRegistrationListener(mSlotId, mSupportedFeature,
-                    listener);
-        }
-    }
-
-    @Override
-    public void removeRegistrationListener(IImsRegistrationListener listener)
-            throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).removeRegistrationListener(mSlotId, mSupportedFeature,
-                    listener);
-        }
-    }
-
-    @Override
-    public ImsCallProfile createCallProfile(int sessionId, int callServiceType, int callType)
-            throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).createCallProfile(mSlotId, mSupportedFeature,
-                    sessionId, callServiceType, callType);
-        }
-    }
-
-    @Override
-    public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile,
-            IImsCallSessionListener listener) throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).createCallSession(mSlotId, mSupportedFeature,
-                    sessionId, profile, listener);
-        }
-    }
-
-    @Override
-    public IImsCallSession getPendingCallSession(int sessionId, String callId)
-            throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).getPendingCallSession(mSlotId, mSupportedFeature,
-                    sessionId, callId);
-        }
-    }
-
-    @Override
-    public IImsUt getUtInterface() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).getUtInterface(mSlotId, mSupportedFeature);
-        }
-    }
-
-    @Override
-    public IImsConfig getConfigInterface() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).getConfigInterface(mSlotId, mSupportedFeature);
-        }
-    }
-
-    @Override
-    public void turnOnIms() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).turnOnIms(mSlotId, mSupportedFeature);
-        }
-    }
-
-    @Override
-    public void turnOffIms() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).turnOffIms(mSlotId, mSupportedFeature);
-        }
-    }
-
-    @Override
-    public IImsEcbm getEcbmInterface() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).getEcbmInterface(mSlotId, mSupportedFeature);
-        }
-    }
-
-    @Override
-    public void setUiTTYMode(int uiTtyMode, Message onComplete)
-            throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).setUiTTYMode(mSlotId, mSupportedFeature, uiTtyMode,
-                    onComplete);
-        }
-    }
-
-    @Override
-    public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).getMultiEndpointInterface(mSlotId,
-                    mSupportedFeature);
-        }
-    }
-
-    @Override
-    public int getFeatureStatus() {
-        synchronized (mLock) {
-            if (isBinderAlive() && mFeatureStatusCached != null) {
-                Log.i(LOG_TAG, "getFeatureStatus - returning cached: " + mFeatureStatusCached);
-                return mFeatureStatusCached;
-            }
-        }
-        // Don't synchronize on Binder call.
-        Integer status = retrieveFeatureStatus();
-        synchronized (mLock) {
-            if (status == null) {
-                return ImsFeature.STATE_NOT_AVAILABLE;
-            }
-            // Cache only non-null value for feature status.
-            mFeatureStatusCached = status;
-        }
-        Log.i(LOG_TAG, "getFeatureStatus - returning " + status);
-        return status;
-    }
-
-    /**
-     * Internal method used to retrieve the feature status from the corresponding ImsService.
-     */
-    private Integer retrieveFeatureStatus() {
-        if (mBinder != null) {
-            try {
-                return getServiceInterface(mBinder).getFeatureStatus(mSlotId, mSupportedFeature);
-            } catch (RemoteException e) {
-                // Status check failed, don't update cache
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @param c Callback that will fire when the feature status has changed.
-     */
-    public void setStatusCallback(INotifyStatusChanged c) {
-        mStatusCallback = c;
-    }
-
-    /**
-     * @return Returns true if the ImsService is ready to take commands, false otherwise. If this
-     * method returns false, it doesn't mean that the Binder connection is not available (use
-     * {@link #isBinderReady()} to check that), but that the ImsService is not accepting commands
-     * at this time.
-     *
-     * For example, for DSDS devices, only one slot can be {@link ImsFeature#STATE_READY} to take
-     * commands at a time, so the other slot must stay at {@link ImsFeature#STATE_NOT_AVAILABLE}.
-     */
-    public boolean isBinderReady() {
-        return isBinderAlive() && getFeatureStatus() == ImsFeature.STATE_READY;
-    }
-
-    @Override
-    public boolean isBinderAlive() {
-        return mIsAvailable && mBinder != null && mBinder.isBinderAlive();
-    }
-
-    protected void checkServiceIsReady() throws RemoteException {
-        if (!isBinderReady()) {
-            throw new RemoteException("ImsServiceProxy is not ready to accept commands.");
-        }
-    }
-
-    private IImsServiceController getServiceInterface(IBinder b) {
-        return IImsServiceController.Stub.asInterface(b);
-    }
-}
diff --git a/telephony/java/android/telephony/ims/ImsServiceProxyCompat.java b/telephony/java/android/telephony/ims/ImsServiceProxyCompat.java
deleted file mode 100644
index bbd5f02..0000000
--- a/telephony/java/android/telephony/ims/ImsServiceProxyCompat.java
+++ /dev/null
@@ -1,183 +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.telephony.ims;
-
-import android.app.PendingIntent;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.telephony.ims.feature.IMMTelFeature;
-import android.telephony.ims.feature.ImsFeature;
-
-import com.android.ims.ImsCallProfile;
-import com.android.ims.internal.IImsCallSession;
-import com.android.ims.internal.IImsCallSessionListener;
-import com.android.ims.internal.IImsConfig;
-import com.android.ims.internal.IImsEcbm;
-import com.android.ims.internal.IImsMultiEndpoint;
-import com.android.ims.internal.IImsRegistrationListener;
-import com.android.ims.internal.IImsService;
-import com.android.ims.internal.IImsUt;
-
-/**
- * Compatibility class that implements the new ImsService IMMTelFeature interface, but
- * uses the old IImsService interface to support older devices that implement the deprecated
- * opt/net/ims interface.
- * @hide
- */
-
-public class ImsServiceProxyCompat implements IMMTelFeature {
-
-    private static final int SERVICE_ID = ImsFeature.MMTEL;
-
-    protected final int mSlotId;
-    protected IBinder mBinder;
-
-    public ImsServiceProxyCompat(int slotId, IBinder binder) {
-        mSlotId = slotId;
-        mBinder = binder;
-    }
-
-    @Override
-    public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener)
-            throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).open(mSlotId, ImsFeature.MMTEL, incomingCallIntent,
-                listener);
-    }
-
-    @Override
-    public void endSession(int sessionId) throws RemoteException {
-        checkBinderConnection();
-        getServiceInterface(mBinder).close(sessionId);
-    }
-
-    @Override
-    public boolean isConnected(int callServiceType, int callType)
-            throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).isConnected(SERVICE_ID,  callServiceType, callType);
-    }
-
-    @Override
-    public boolean isOpened() throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).isOpened(SERVICE_ID);
-    }
-
-    @Override
-    public void addRegistrationListener(IImsRegistrationListener listener)
-            throws RemoteException {
-        checkBinderConnection();
-        getServiceInterface(mBinder).addRegistrationListener(mSlotId, ImsFeature.MMTEL, listener);
-    }
-
-    @Override
-    public void removeRegistrationListener(IImsRegistrationListener listener)
-            throws RemoteException {
-        // Not Implemented in old ImsService. If the registration listener becomes invalid, the
-        // ImsService will remove.
-    }
-
-    @Override
-    public ImsCallProfile createCallProfile(int sessionId, int callServiceType, int callType)
-            throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).createCallProfile(sessionId, callServiceType, callType);
-    }
-
-    @Override
-    public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile,
-            IImsCallSessionListener listener) throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).createCallSession(sessionId, profile, listener);
-    }
-
-    @Override
-    public IImsCallSession getPendingCallSession(int sessionId, String callId)
-            throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).getPendingCallSession(sessionId, callId);
-    }
-
-    @Override
-    public IImsUt getUtInterface() throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).getUtInterface(SERVICE_ID);
-    }
-
-    @Override
-    public IImsConfig getConfigInterface() throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).getConfigInterface(mSlotId);
-    }
-
-    @Override
-    public void turnOnIms() throws RemoteException {
-        checkBinderConnection();
-        getServiceInterface(mBinder).turnOnIms(mSlotId);
-    }
-
-    @Override
-    public void turnOffIms() throws RemoteException {
-        checkBinderConnection();
-        getServiceInterface(mBinder).turnOffIms(mSlotId);
-    }
-
-    @Override
-    public IImsEcbm getEcbmInterface() throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).getEcbmInterface(SERVICE_ID);
-    }
-
-    @Override
-    public void setUiTTYMode(int uiTtyMode, Message onComplete)
-            throws RemoteException {
-        checkBinderConnection();
-        getServiceInterface(mBinder).setUiTTYMode(SERVICE_ID, uiTtyMode, onComplete);
-    }
-
-    @Override
-    public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).getMultiEndpointInterface(SERVICE_ID);
-    }
-
-    /**
-     * Base implementation, always returns READY for compatibility with old ImsService.
-     */
-    public int getFeatureStatus() {
-        return ImsFeature.STATE_READY;
-    }
-
-    /**
-     * @return false if the binder connection is no longer alive.
-     */
-    public boolean isBinderAlive() {
-        return mBinder != null && mBinder.isBinderAlive();
-    }
-
-    private IImsService getServiceInterface(IBinder b) {
-        return IImsService.Stub.asInterface(b);
-    }
-
-    protected void checkBinderConnection() throws RemoteException {
-        if (!isBinderAlive()) {
-            throw new RemoteException("ImsServiceProxy is not available for that feature.");
-        }
-    }
-}
diff --git a/telephony/java/android/telephony/ims/feature/IMMTelFeature.java b/telephony/java/android/telephony/ims/feature/IMMTelFeature.java
deleted file mode 100644
index d65e27e..0000000
--- a/telephony/java/android/telephony/ims/feature/IMMTelFeature.java
+++ /dev/null
@@ -1,187 +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.telephony.ims.feature;
-
-import android.app.PendingIntent;
-import android.os.Message;
-import android.os.RemoteException;
-
-import com.android.ims.ImsCallProfile;
-import com.android.ims.internal.IImsCallSession;
-import com.android.ims.internal.IImsCallSessionListener;
-import com.android.ims.internal.IImsConfig;
-import com.android.ims.internal.IImsEcbm;
-import com.android.ims.internal.IImsMultiEndpoint;
-import com.android.ims.internal.IImsRegistrationListener;
-import com.android.ims.internal.IImsUt;
-
-/**
- * MMTel interface for an ImsService. When updating this interface, ensure that base implementations
- * of your changes are also present in MMTelFeature for compatibility with older versions of the
- * MMTel feature.
- * @hide
- */
-
-public interface IMMTelFeature {
-
-    /**
-     * Notifies the MMTel feature that you would like to start a session. This should always be
-     * done before making/receiving IMS calls. The IMS service will register the device to the
-     * operator's network with the credentials (from ISIM) periodically in order to receive calls
-     * from the operator's network. When the IMS service receives a new call, it will send out an
-     * intent with the provided action string. The intent contains a call ID extra
-     * {@link IImsCallSession#getCallId} and it can be used to take a call.
-     *
-     * @param incomingCallIntent When an incoming call is received, the IMS service will call
-     * {@link PendingIntent#send} to send back the intent to the caller with
-     * {@link #INCOMING_CALL_RESULT_CODE} as the result code and the intent to fill in the call ID;
-     * It cannot be null.
-     * @param listener To listen to IMS registration events; It cannot be null
-     * @return an integer (greater than 0) representing the session id associated with the session
-     * that has been started.
-     */
-    int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener)
-            throws RemoteException;
-
-    /**
-     * End a previously started session using the associated sessionId.
-     * @param sessionId an integer (greater than 0) representing the ongoing session. See
-     * {@link #startSession}.
-     */
-    void endSession(int sessionId) throws RemoteException;
-
-    /**
-     * Checks if the IMS service has successfully registered to the IMS network with the specified
-     * service & call type.
-     *
-     * @param callServiceType a service type that is specified in {@link ImsCallProfile}
-     *        {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
-     *        {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
-     * @param callType a call type that is specified in {@link ImsCallProfile}
-     *        {@link ImsCallProfile#CALL_TYPE_VOICE_N_VIDEO}
-     *        {@link ImsCallProfile#CALL_TYPE_VOICE}
-     *        {@link ImsCallProfile#CALL_TYPE_VT}
-     *        {@link ImsCallProfile#CALL_TYPE_VS}
-     * @return true if the specified service id is connected to the IMS network; false otherwise
-     * @throws RemoteException
-     */
-    boolean isConnected(int callServiceType, int callType) throws RemoteException;
-
-    /**
-     * Checks if the specified IMS service is opened.
-     *
-     * @return true if the specified service id is opened; false otherwise
-     */
-    boolean isOpened() throws RemoteException;
-
-    /**
-     * Add a new registration listener for the client associated with the session Id.
-     * @param listener An implementation of IImsRegistrationListener.
-     */
-    void addRegistrationListener(IImsRegistrationListener listener)
-            throws RemoteException;
-
-    /**
-     * Remove a previously registered listener using {@link #addRegistrationListener} for the client
-     * associated with the session Id.
-     * @param listener A previously registered IImsRegistrationListener
-     */
-    void removeRegistrationListener(IImsRegistrationListener listener)
-            throws RemoteException;
-
-    /**
-     * Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state.
-     *
-     * @param sessionId a session id which is obtained from {@link #startSession}
-     * @param callServiceType a service type that is specified in {@link ImsCallProfile}
-     *        {@link ImsCallProfile#SERVICE_TYPE_NONE}
-     *        {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
-     *        {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
-     * @param callType a call type that is specified in {@link ImsCallProfile}
-     *        {@link ImsCallProfile#CALL_TYPE_VOICE}
-     *        {@link ImsCallProfile#CALL_TYPE_VT}
-     *        {@link ImsCallProfile#CALL_TYPE_VT_TX}
-     *        {@link ImsCallProfile#CALL_TYPE_VT_RX}
-     *        {@link ImsCallProfile#CALL_TYPE_VT_NODIR}
-     *        {@link ImsCallProfile#CALL_TYPE_VS}
-     *        {@link ImsCallProfile#CALL_TYPE_VS_TX}
-     *        {@link ImsCallProfile#CALL_TYPE_VS_RX}
-     * @return a {@link ImsCallProfile} object
-     */
-    ImsCallProfile createCallProfile(int sessionId, int callServiceType, int callType)
-            throws RemoteException;
-
-    /**
-     * Creates a {@link ImsCallSession} with the specified call profile.
-     * Use other methods, if applicable, instead of interacting with
-     * {@link ImsCallSession} directly.
-     *
-     * @param sessionId a session id which is obtained from {@link #startSession}
-     * @param profile a call profile to make the call
-     * @param listener An implementation of IImsCallSessionListener.
-     */
-    IImsCallSession createCallSession(int sessionId, ImsCallProfile profile,
-            IImsCallSessionListener listener) throws RemoteException;
-
-    /**
-     * Retrieves the call session associated with a pending call.
-     *
-     * @param sessionId a session id which is obtained from {@link #startSession}
-     * @param callId a call id to make the call
-     */
-    IImsCallSession getPendingCallSession(int sessionId, String callId) throws RemoteException;
-
-    /**
-     * @return The Ut interface for the supplementary service configuration.
-     */
-    IImsUt getUtInterface() throws RemoteException;
-
-    /**
-     * @return The config interface for IMS Configuration
-     */
-    IImsConfig getConfigInterface() throws RemoteException;
-
-    /**
-     * Signal the MMTelFeature to turn on IMS when it has been turned off using {@link #turnOffIms}
-     * @param sessionId a session id which is obtained from {@link #startSession}
-     */
-    void turnOnIms() throws RemoteException;
-
-    /**
-     * Signal the MMTelFeature to turn off IMS when it has been turned on using {@link #turnOnIms}
-     * @param sessionId a session id which is obtained from {@link #startSession}
-     */
-    void turnOffIms() throws RemoteException;
-
-    /**
-     * @return The Emergency call-back mode interface for emergency VoLTE calls that support it.
-     */
-    IImsEcbm getEcbmInterface() throws RemoteException;
-
-    /**
-     * Sets the current UI TTY mode for the MMTelFeature.
-     * @param uiTtyMode An integer containing the new UI TTY Mode.
-     * @param onComplete A {@link Message} to be used when the mode has been set.
-     * @throws RemoteException
-     */
-    void setUiTTYMode(int uiTtyMode, Message onComplete) throws RemoteException;
-
-    /**
-     * @return MultiEndpoint interface for DEP notifications
-     */
-    IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException;
-}
diff --git a/telephony/java/android/telephony/ims/feature/IRcsFeature.java b/telephony/java/android/telephony/ims/feature/IRcsFeature.java
deleted file mode 100644
index e28e1b3..0000000
--- a/telephony/java/android/telephony/ims/feature/IRcsFeature.java
+++ /dev/null
@@ -1,26 +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.telephony.ims.feature;
-
-/**
- * Feature interface that provides access to RCS APIs. Currently empty until RCS support is added
- * in the framework.
- * @hide
- */
-
-public interface IRcsFeature {
-}
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index 9d880b7..062858d 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.content.Context;
 import android.content.Intent;
+import android.os.IInterface;
 import android.os.RemoteException;
 import android.telephony.SubscriptionManager;
 import android.util.Log;
@@ -91,17 +92,12 @@
     public static final int STATE_INITIALIZING = 1;
     public static final int STATE_READY = 2;
 
-    private List<INotifyFeatureRemoved> mRemovedListeners = new ArrayList<>();
     private final Set<IImsFeatureStatusCallback> mStatusCallbacks = Collections.newSetFromMap(
             new WeakHashMap<IImsFeatureStatusCallback, Boolean>());
     private @ImsState int mState = STATE_NOT_AVAILABLE;
     private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
     private Context mContext;
 
-    public interface INotifyFeatureRemoved {
-        void onFeatureRemoved(int slotId);
-    }
-
     public void setContext(Context context) {
         mContext = context;
     }
@@ -110,26 +106,6 @@
         mSlotId = slotId;
     }
 
-    public void addFeatureRemovedListener(INotifyFeatureRemoved listener) {
-        synchronized (mRemovedListeners) {
-            mRemovedListeners.add(listener);
-        }
-    }
-
-    public void removeFeatureRemovedListener(INotifyFeatureRemoved listener) {
-        synchronized (mRemovedListeners) {
-            mRemovedListeners.remove(listener);
-        }
-    }
-
-    // Not final for testing.
-    public void notifyFeatureRemoved(int slotId) {
-        synchronized (mRemovedListeners) {
-            mRemovedListeners.forEach(l -> l.onFeatureRemoved(slotId));
-            onFeatureRemoved();
-        }
-    }
-
     public int getFeatureState() {
         return mState;
     }
@@ -215,4 +191,9 @@
      * Called when the feature is being removed and must be cleaned up.
      */
     public abstract void onFeatureRemoved();
+
+    /**
+     * @return Binder instance
+     */
+    public abstract IInterface getBinder();
 }
diff --git a/telephony/java/android/telephony/ims/feature/MMTelFeature.java b/telephony/java/android/telephony/ims/feature/MMTelFeature.java
index a71f0bf..e790d14 100644
--- a/telephony/java/android/telephony/ims/feature/MMTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MMTelFeature.java
@@ -18,104 +18,337 @@
 
 import android.app.PendingIntent;
 import android.os.Message;
+import android.os.RemoteException;
 
 import com.android.ims.ImsCallProfile;
 import com.android.ims.internal.IImsCallSession;
 import com.android.ims.internal.IImsCallSessionListener;
 import com.android.ims.internal.IImsConfig;
 import com.android.ims.internal.IImsEcbm;
+import com.android.ims.internal.IImsMMTelFeature;
 import com.android.ims.internal.IImsMultiEndpoint;
 import com.android.ims.internal.IImsRegistrationListener;
 import com.android.ims.internal.IImsUt;
-
-import java.util.ArrayList;
-import java.util.List;
+import com.android.ims.internal.ImsCallSession;
 
 /**
- * Base implementation, which implements all methods in IMMTelFeature. Any class wishing to use
- * MMTelFeature should extend this class and implement all methods that the service supports.
+ * Base implementation for MMTel.
+ * Any class wishing to use MMTelFeature should extend this class and implement all methods that the
+ * service supports.
  *
  * @hide
  */
 
-public class MMTelFeature extends ImsFeature implements IMMTelFeature {
+public class MMTelFeature extends ImsFeature {
 
+    // Lock for feature synchronization
+    private final Object mLock = new Object();
+
+    private final IImsMMTelFeature mImsMMTelBinder = new IImsMMTelFeature.Stub() {
+
+        @Override
+        public int startSession(PendingIntent incomingCallIntent,
+                IImsRegistrationListener listener) throws RemoteException {
+            synchronized (mLock) {
+                return MMTelFeature.this.startSession(incomingCallIntent, listener);
+            }
+        }
+
+        @Override
+        public void endSession(int sessionId) throws RemoteException {
+            synchronized (mLock) {
+                MMTelFeature.this.endSession(sessionId);
+            }
+        }
+
+        @Override
+        public boolean isConnected(int callSessionType, int callType)
+                throws RemoteException {
+            synchronized (mLock) {
+                return MMTelFeature.this.isConnected(callSessionType, callType);
+            }
+        }
+
+        @Override
+        public boolean isOpened() throws RemoteException {
+            synchronized (mLock) {
+                return MMTelFeature.this.isOpened();
+            }
+        }
+
+        @Override
+        public int getFeatureStatus() throws RemoteException {
+            synchronized (mLock) {
+                return MMTelFeature.this.getFeatureState();
+            }
+        }
+
+        @Override
+        public void addRegistrationListener(IImsRegistrationListener listener)
+                throws RemoteException {
+            synchronized (mLock) {
+                MMTelFeature.this.addRegistrationListener(listener);
+            }
+        }
+
+        @Override
+        public void removeRegistrationListener(IImsRegistrationListener listener)
+                throws RemoteException {
+            synchronized (mLock) {
+                MMTelFeature.this.removeRegistrationListener(listener);
+            }
+        }
+
+        @Override
+        public ImsCallProfile createCallProfile(int sessionId, int callSessionType, int callType)
+                throws RemoteException {
+            synchronized (mLock) {
+                return MMTelFeature.this.createCallProfile(sessionId, callSessionType,  callType);
+            }
+        }
+
+        @Override
+        public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile,
+                IImsCallSessionListener listener) throws RemoteException {
+            synchronized (mLock) {
+                return MMTelFeature.this.createCallSession(sessionId, profile, listener);
+            }
+        }
+
+        @Override
+        public IImsCallSession getPendingCallSession(int sessionId, String callId)
+                throws RemoteException {
+            synchronized (mLock) {
+                return MMTelFeature.this.getPendingCallSession(sessionId, callId);
+            }
+        }
+
+        @Override
+        public IImsUt getUtInterface() throws RemoteException {
+            synchronized (mLock) {
+                return MMTelFeature.this.getUtInterface();
+            }
+        }
+
+        @Override
+        public IImsConfig getConfigInterface() throws RemoteException {
+            synchronized (mLock) {
+                return MMTelFeature.this.getConfigInterface();
+            }
+        }
+
+        @Override
+        public void turnOnIms() throws RemoteException {
+            synchronized (mLock) {
+                MMTelFeature.this.turnOnIms();
+            }
+        }
+
+        @Override
+        public void turnOffIms() throws RemoteException {
+            synchronized (mLock) {
+                MMTelFeature.this.turnOffIms();
+            }
+        }
+
+        @Override
+        public IImsEcbm getEcbmInterface() throws RemoteException {
+            synchronized (mLock) {
+                return MMTelFeature.this.getEcbmInterface();
+            }
+        }
+
+        @Override
+        public void setUiTTYMode(int uiTtyMode, Message onComplete) throws RemoteException {
+            synchronized (mLock) {
+                MMTelFeature.this.setUiTTYMode(uiTtyMode, onComplete);
+            }
+        }
+
+        @Override
+        public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
+            synchronized (mLock) {
+                return MMTelFeature.this.getMultiEndpointInterface();
+            }
+        }
+    };
+
+    /**
+     * @hide
+     */
     @Override
+    public final IImsMMTelFeature getBinder() {
+        return mImsMMTelBinder;
+    }
+
+    /**
+     * Notifies the MMTel feature that you would like to start a session. This should always be
+     * done before making/receiving IMS calls. The IMS service will register the device to the
+     * operator's network with the credentials (from ISIM) periodically in order to receive calls
+     * from the operator's network. When the IMS service receives a new call, it will send out an
+     * intent with the provided action string. The intent contains a call ID extra
+     * {@link IImsCallSession#getCallId} and it can be used to take a call.
+     *
+     * @param incomingCallIntent When an incoming call is received, the IMS service will call
+     * {@link PendingIntent#send} to send back the intent to the caller with
+     * ImsManager#INCOMING_CALL_RESULT_CODE as the result code and the intent to fill in the call
+     * ID; It cannot be null.
+     * @param listener To listen to IMS registration events; It cannot be null
+     * @return an integer (greater than 0) representing the session id associated with the session
+     * that has been started.
+     */
     public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener) {
         return 0;
     }
 
-    @Override
+    /**
+     * End a previously started session using the associated sessionId.
+     * @param sessionId an integer (greater than 0) representing the ongoing session. See
+     * {@link #startSession}.
+     */
     public void endSession(int sessionId) {
     }
 
-    @Override
+    /**
+     * Checks if the IMS service has successfully registered to the IMS network with the specified
+     * service & call type.
+     *
+     * @param callSessionType a service type that is specified in {@link ImsCallProfile}
+     *        {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
+     *        {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
+     * @param callType a call type that is specified in {@link ImsCallProfile}
+     *        {@link ImsCallProfile#CALL_TYPE_VOICE_N_VIDEO}
+     *        {@link ImsCallProfile#CALL_TYPE_VOICE}
+     *        {@link ImsCallProfile#CALL_TYPE_VT}
+     *        {@link ImsCallProfile#CALL_TYPE_VS}
+     * @return true if the specified service id is connected to the IMS network; false otherwise
+     */
     public boolean isConnected(int callSessionType, int callType) {
         return false;
     }
 
-    @Override
+    /**
+     * Checks if the specified IMS service is opened.
+     *
+     * @return true if the specified service id is opened; false otherwise
+     */
     public boolean isOpened() {
         return false;
     }
 
-    @Override
+    /**
+     * Add a new registration listener for the client associated with the session Id.
+     * @param listener An implementation of IImsRegistrationListener.
+     */
     public void addRegistrationListener(IImsRegistrationListener listener) {
     }
 
-    @Override
+    /**
+     * Remove a previously registered listener using {@link #addRegistrationListener} for the client
+     * associated with the session Id.
+     * @param listener A previously registered IImsRegistrationListener
+     */
     public void removeRegistrationListener(IImsRegistrationListener listener) {
     }
 
-    @Override
+    /**
+     * Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state.
+     *
+     * @param sessionId a session id which is obtained from {@link #startSession}
+     * @param callSessionType a service type that is specified in {@link ImsCallProfile}
+     *        {@link ImsCallProfile#SERVICE_TYPE_NONE}
+     *        {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
+     *        {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
+     * @param callType a call type that is specified in {@link ImsCallProfile}
+     *        {@link ImsCallProfile#CALL_TYPE_VOICE}
+     *        {@link ImsCallProfile#CALL_TYPE_VT}
+     *        {@link ImsCallProfile#CALL_TYPE_VT_TX}
+     *        {@link ImsCallProfile#CALL_TYPE_VT_RX}
+     *        {@link ImsCallProfile#CALL_TYPE_VT_NODIR}
+     *        {@link ImsCallProfile#CALL_TYPE_VS}
+     *        {@link ImsCallProfile#CALL_TYPE_VS_TX}
+     *        {@link ImsCallProfile#CALL_TYPE_VS_RX}
+     * @return a {@link ImsCallProfile} object
+     */
     public ImsCallProfile createCallProfile(int sessionId, int callSessionType, int callType) {
         return null;
     }
 
-    @Override
+    /**
+     * Creates an {@link ImsCallSession} with the specified call profile.
+     * Use other methods, if applicable, instead of interacting with
+     * {@link ImsCallSession} directly.
+     *
+     * @param sessionId a session id which is obtained from {@link #startSession}
+     * @param profile a call profile to make the call
+     * @param listener An implementation of IImsCallSessionListener.
+     */
     public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile,
             IImsCallSessionListener listener) {
         return null;
     }
 
-    @Override
+    /**
+     * Retrieves the call session associated with a pending call.
+     *
+     * @param sessionId a session id which is obtained from {@link #startSession}
+     * @param callId a call id to make the call
+     */
     public IImsCallSession getPendingCallSession(int sessionId, String callId) {
         return null;
     }
 
-    @Override
+    /**
+     * @return The Ut interface for the supplementary service configuration.
+     */
     public IImsUt getUtInterface() {
         return null;
     }
 
-    @Override
+    /**
+     * @return The config interface for IMS Configuration
+     */
     public IImsConfig getConfigInterface() {
         return null;
     }
 
-    @Override
+    /**
+     * Signal the MMTelFeature to turn on IMS when it has been turned off using {@link #turnOffIms}
+     */
     public void turnOnIms() {
     }
 
-    @Override
+    /**
+     * Signal the MMTelFeature to turn off IMS when it has been turned on using {@link #turnOnIms}
+     */
     public void turnOffIms() {
     }
 
-    @Override
+    /**
+     * @return The Emergency call-back mode interface for emergency VoLTE calls that support it.
+     */
     public IImsEcbm getEcbmInterface() {
         return null;
     }
 
-    @Override
+    /**
+     * Sets the current UI TTY mode for the MMTelFeature.
+     * @param uiTtyMode An integer containing the new UI TTY Mode.
+     * @param onComplete A {@link Message} to be used when the mode has been set.
+     */
     public void setUiTTYMode(int uiTtyMode, Message onComplete) {
     }
 
-    @Override
+    /**
+     * @return MultiEndpoint interface for DEP notifications
+     */
     public IImsMultiEndpoint getMultiEndpointInterface() {
         return null;
     }
 
-    @Override
+    /**
+     * {@inheritDoc}
+     */
     public void onFeatureRemoved() {
 
     }
diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java
index 9cddc1b..a82e608 100644
--- a/telephony/java/android/telephony/ims/feature/RcsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java
@@ -16,13 +16,20 @@
 
 package android.telephony.ims.feature;
 
+import com.android.ims.internal.IImsRcsFeature;
+
 /**
  * Base implementation of the RcsFeature APIs. Any ImsService wishing to support RCS should extend
- * this class and provide implementations of the IRcsFeature methods that they support.
+ * this class and provide implementations of the RcsFeature methods that they support.
  * @hide
  */
 
-public class RcsFeature extends ImsFeature implements IRcsFeature {
+public class RcsFeature extends ImsFeature {
+
+    private final IImsRcsFeature mImsRcsBinder = new IImsRcsFeature.Stub() {
+        // Empty Default Implementation.
+    };
+
 
     public RcsFeature() {
         super();
@@ -32,4 +39,9 @@
     public void onFeatureRemoved() {
 
     }
+
+    @Override
+    public final IImsRcsFeature getBinder() {
+        return mImsRcsBinder;
+    }
 }
diff --git a/telephony/java/android/telephony/mbms/DownloadProgressListener.java b/telephony/java/android/telephony/mbms/DownloadProgressListener.java
deleted file mode 100644
index d91e9ad..0000000
--- a/telephony/java/android/telephony/mbms/DownloadProgressListener.java
+++ /dev/null
@@ -1,48 +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.telephony.mbms;
-
-import android.os.RemoteException;
-
-/**
- * A optional listener class used by download clients to track progress.
- * @hide
- */
-public class DownloadProgressListener extends IDownloadProgressListener.Stub {
-    /**
-     * Gives process callbacks for a given DownloadRequest.
-     * This is optionally specified when requesting a download and
-     * only lives while the app is running - it's unlikely to be useful for
-     * downloads far in the future.
-     *
-     * @param request a {@link DownloadRequest}, indicating which download is being referenced.
-     * @param fileInfo a {@link FileInfo} specifying the file to report progress on.  Note that
-     *   the request may result in many files being downloaded and the client
-     *   may not have been able to get a list of them in advance.
-     * @param currentDownloadSize is the current amount downloaded.
-     * @param fullDownloadSize is the total number of bytes that make up the downloaded content.
-     *   This may be different from the decoded final size, but is useful in gauging download
-     *   progress.
-     * @param currentDecodedSize is the number of bytes that have been decoded.
-     * @param fullDecodedSize is the total number of bytes that make up the final decoded content.
-     */
-    @Override
-    public void progress(DownloadRequest request, FileInfo fileInfo,
-            int currentDownloadSize, int fullDownloadSize,
-            int currentDecodedSize, int fullDecodedSize) throws RemoteException {
-    }
-}
diff --git a/telephony/java/android/telephony/mbms/DownloadRequest.java b/telephony/java/android/telephony/mbms/DownloadRequest.java
index eae9011..f0d60b6 100644
--- a/telephony/java/android/telephony/mbms/DownloadRequest.java
+++ b/telephony/java/android/telephony/mbms/DownloadRequest.java
@@ -16,6 +16,8 @@
 
 package android.telephony.mbms;
 
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Parcel;
@@ -25,7 +27,6 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.File;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
@@ -37,34 +38,27 @@
 import java.util.Objects;
 
 /**
- * A Parcelable class describing a pending Cell-Broadcast download request
- * @hide
+ * Describes a request to download files over cell-broadcast. Instances of this class should be
+ * created by the app when requesting a download, and instances of this class will be passed back
+ * to the app when the middleware updates the status of the download.
  */
-public class DownloadRequest implements Parcelable {
+public final class DownloadRequest implements Parcelable {
     // Version code used to keep token calculation consistent.
     private static final int CURRENT_VERSION = 1;
     private static final String LOG_TAG = "MbmsDownloadRequest";
 
-    /**
-     * Maximum permissible length for the app's download-completion intent, when serialized via
-     * {@link Intent#toUri(int)}.
-     */
+    /** @hide */
     public static final int MAX_APP_INTENT_SIZE = 50000;
 
-    /**
-     * Maximum permissible length for the app's destination path, when serialized via
-     * {@link Uri#toString()}.
-     */
+    /** @hide */
     public static final int MAX_DESTINATION_URI_SIZE = 50000;
 
     /** @hide */
     private static class OpaqueDataContainer implements Serializable {
-        private final String destinationUri;
         private final String appIntent;
         private final int version;
 
-        public OpaqueDataContainer(String destinationUri, String appIntent, int version) {
-            this.destinationUri = destinationUri;
+        public OpaqueDataContainer(String appIntent, int version) {
             this.appIntent = appIntent;
             this.version = version;
         }
@@ -73,11 +67,23 @@
     public static class Builder {
         private String fileServiceId;
         private Uri source;
-        private Uri dest;
         private int subscriptionId;
         private String appIntent;
         private int version = CURRENT_VERSION;
 
+
+        /**
+         * Builds a new DownloadRequest.
+         * @param sourceUri the source URI for the DownloadRequest to be built. This URI should
+         *     never be null.
+         */
+        public Builder(@NonNull Uri sourceUri) {
+            if (sourceUri == null) {
+                throw new IllegalArgumentException("Source URI must be non-null.");
+            }
+            source = sourceUri;
+        }
+
         /**
          * Sets the service from which the download request to be built will download from.
          * @param serviceInfo
@@ -91,43 +97,16 @@
         /**
          * Set the service ID for the download request. For use by the middleware only.
          * @hide
-         * TODO: systemapi
          */
+        @SystemApi
         public Builder setServiceId(String serviceId) {
             fileServiceId = serviceId;
             return this;
         }
 
         /**
-         * Sets the source URI for the download request to be built.
-         * @param source
-         * @return
-         */
-        public Builder setSource(Uri source) {
-            this.source = source;
-            return this;
-        }
-
-        /**
-         * Sets the destination URI for the download request to be built. The middleware should
-         * not set this directly.
-         * @param dest A URI obtained from {@link Uri#fromFile(File)}, denoting the requested
-         *             final destination of the download.
-         * @return
-         */
-        public Builder setDest(Uri dest) {
-            if (dest.toString().length() > MAX_DESTINATION_URI_SIZE) {
-                throw new IllegalArgumentException("Destination uri must not exceed length " +
-                        MAX_DESTINATION_URI_SIZE);
-            }
-            this.dest = dest;
-            return this;
-        }
-
-        /**
          * Set the subscription ID on which the file(s) should be downloaded.
          * @param subscriptionId
-         * @return
          */
         public Builder setSubscriptionId(int subscriptionId) {
             this.subscriptionId = subscriptionId;
@@ -141,7 +120,6 @@
          *
          * The middleware should not use this method.
          * @param intent
-         * @return
          */
         public Builder setAppIntent(Intent intent) {
             this.appIntent = intent.toUri(0);
@@ -158,17 +136,15 @@
          * manager code, but is irrelevant to the middleware.
          * @param data A byte array, the contents of which should have been originally obtained
          *             from {@link DownloadRequest#getOpaqueData()}.
-         * @return
-         * TODO: systemapi
          * @hide
          */
+        @SystemApi
         public Builder setOpaqueData(byte[] data) {
             try {
                 ObjectInputStream stream = new ObjectInputStream(new ByteArrayInputStream(data));
                 OpaqueDataContainer dataContainer = (OpaqueDataContainer) stream.readObject();
                 version = dataContainer.version;
                 appIntent = dataContainer.appIntent;
-                dest = Uri.parse(dataContainer.destinationUri);
             } catch (IOException e) {
                 // Really should never happen
                 Log.e(LOG_TAG, "Got IOException trying to parse opaque data");
@@ -181,24 +157,21 @@
         }
 
         public DownloadRequest build() {
-            return new DownloadRequest(fileServiceId, source, dest,
-                    subscriptionId, appIntent, version);
+            return new DownloadRequest(fileServiceId, source, subscriptionId, appIntent, version);
         }
     }
 
     private final String fileServiceId;
     private final Uri sourceUri;
-    private final Uri destinationUri;
     private final int subscriptionId;
     private final String serializedResultIntentForApp;
     private final int version;
 
     private DownloadRequest(String fileServiceId,
-            Uri source, Uri dest,
-            int sub, String appIntent, int version) {
+            Uri source, int sub,
+            String appIntent, int version) {
         this.fileServiceId = fileServiceId;
         sourceUri = source;
-        destinationUri = dest;
         subscriptionId = sub;
         serializedResultIntentForApp = appIntent;
         this.version = version;
@@ -211,7 +184,6 @@
     private DownloadRequest(DownloadRequest dr) {
         fileServiceId = dr.fileServiceId;
         sourceUri = dr.sourceUri;
-        destinationUri = dr.destinationUri;
         subscriptionId = dr.subscriptionId;
         serializedResultIntentForApp = dr.serializedResultIntentForApp;
         version = dr.version;
@@ -220,7 +192,6 @@
     private DownloadRequest(Parcel in) {
         fileServiceId = in.readString();
         sourceUri = in.readParcelable(getClass().getClassLoader());
-        destinationUri = in.readParcelable(getClass().getClassLoader());
         subscriptionId = in.readInt();
         serializedResultIntentForApp = in.readString();
         version = in.readInt();
@@ -233,7 +204,6 @@
     public void writeToParcel(Parcel out, int flags) {
         out.writeString(fileServiceId);
         out.writeParcelable(sourceUri, flags);
-        out.writeParcelable(destinationUri, flags);
         out.writeInt(subscriptionId);
         out.writeString(serializedResultIntentForApp);
         out.writeInt(version);
@@ -254,14 +224,6 @@
     }
 
     /**
-     * For use by the client app only.
-     * @return The URI of the final destination of the download.
-     */
-    public Uri getDestinationUri() {
-        return destinationUri;
-    }
-
-    /**
      * @return The subscription ID on which to perform MBMS operations.
      */
     public int getSubscriptionId() {
@@ -287,14 +249,14 @@
      * {@link Builder#setOpaqueData(byte[])}.
      * @return A byte array of opaque data to persist.
      * @hide
-     * TODO: systemapi
      */
+    @SystemApi
     public byte[] getOpaqueData() {
         try {
             ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
             ObjectOutputStream stream = new ObjectOutputStream(byteArrayOutputStream);
             OpaqueDataContainer container = new OpaqueDataContainer(
-                    destinationUri.toString(), serializedResultIntentForApp, version);
+                    serializedResultIntentForApp, version);
             stream.writeObject(container);
             stream.flush();
             return byteArrayOutputStream.toByteArray();
@@ -321,6 +283,22 @@
     };
 
     /**
+     * Maximum permissible length for the app's destination path, when serialized via
+     * {@link Uri#toString()}.
+     */
+    public static int getMaxAppIntentSize() {
+        return MAX_APP_INTENT_SIZE;
+    }
+
+    /**
+     * Maximum permissible length for the app's download-completion intent, when serialized via
+     * {@link Intent#toUri(int)}.
+     */
+    public static int getMaxDestinationUriSize() {
+        return MAX_DESTINATION_URI_SIZE;
+    }
+
+    /**
      * @hide
      */
     public boolean isMultipartDownload() {
@@ -342,10 +320,11 @@
             throw new RuntimeException("Could not get sha256 hash object");
         }
         if (version >= 1) {
-            // Hash the source URI, destination URI, and the app intent
+            // Hash the source URI and the app intent
             digest.update(sourceUri.toString().getBytes(StandardCharsets.UTF_8));
-            digest.update(destinationUri.toString().getBytes(StandardCharsets.UTF_8));
-            digest.update(serializedResultIntentForApp.getBytes(StandardCharsets.UTF_8));
+            if (serializedResultIntentForApp != null) {
+                digest.update(serializedResultIntentForApp.getBytes(StandardCharsets.UTF_8));
+            }
         }
         // Add updates for future versions here
         return Base64.encodeToString(digest.digest(), Base64.URL_SAFE | Base64.NO_WRAP);
@@ -365,13 +344,12 @@
                 version == request.version &&
                 Objects.equals(fileServiceId, request.fileServiceId) &&
                 Objects.equals(sourceUri, request.sourceUri) &&
-                Objects.equals(destinationUri, request.destinationUri) &&
                 Objects.equals(serializedResultIntentForApp, request.serializedResultIntentForApp);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(fileServiceId, sourceUri, destinationUri,
+        return Objects.hash(fileServiceId, sourceUri,
                 subscriptionId, serializedResultIntentForApp, version);
     }
 }
diff --git a/telephony/java/android/telephony/mbms/DownloadStateCallback.java b/telephony/java/android/telephony/mbms/DownloadStateCallback.java
new file mode 100644
index 0000000..9f60cc3
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/DownloadStateCallback.java
@@ -0,0 +1,131 @@
+/*
+ * 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.telephony.mbms;
+
+import android.annotation.IntDef;
+import android.telephony.MbmsDownloadSession;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A optional listener class used by download clients to track progress. Apps should extend this
+ * class and pass an instance into
+ * {@link MbmsDownloadSession#download(DownloadRequest)}
+ *
+ * This is optionally specified when requesting a download and will only be called while the app
+ * is running.
+ */
+public class DownloadStateCallback {
+
+    /**
+     * Bitmask flags used for filtering out callback methods. Used when constructing the
+     * DownloadStateCallback as an optional parameter.
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true, value = {ALL_UPDATES, PROGRESS_UPDATES, STATE_UPDATES})
+    public @interface FilterFlag {}
+
+    /**
+     * Receive all callbacks.
+     * Default value.
+     */
+    public static final int ALL_UPDATES = 0x00;
+    /**
+     * Receive callbacks for {@link #onProgressUpdated}.
+     */
+    public static final int PROGRESS_UPDATES = 0x01;
+    /**
+     * Receive callbacks for {@link #onStateUpdated}.
+     */
+    public static final int STATE_UPDATES = 0x02;
+
+    private final int mCallbackFilterFlags;
+
+    /**
+     * Creates a DownloadStateCallback that will receive all callbacks.
+     */
+    public DownloadStateCallback() {
+        mCallbackFilterFlags = ALL_UPDATES;
+    }
+
+    /**
+     * Creates a DownloadStateCallback that will only receive callbacks for the methods specified
+     * via the filterFlags parameter.
+     * @param filterFlags A bitmask of filter flags that will specify which callback this instance
+     *     is interested in.
+     */
+    public DownloadStateCallback(int filterFlags) {
+        mCallbackFilterFlags = filterFlags;
+    }
+
+    /**
+     * Return the currently set filter flags.
+     * @return An integer containing the bitmask of flags that this instance is interested in.
+     * @hide
+     */
+    public int getCallbackFilterFlags() {
+        return mCallbackFilterFlags;
+    }
+
+    /**
+     * Returns true if a filter flag is set for a particular callback method. If the flag is set,
+     * the callback will be delivered to the listening process.
+     * @param flag A filter flag specifying whether or not a callback method is registered to
+     *     receive callbacks.
+     * @return true if registered to receive callbacks in the listening process, false if not.
+     */
+    public final boolean isFilterFlagSet(@FilterFlag int flag) {
+        if (mCallbackFilterFlags == ALL_UPDATES) {
+            return true;
+        }
+        return (mCallbackFilterFlags & flag) > 0;
+    }
+
+    /**
+     * Called when the middleware wants to report progress for a file in a {@link DownloadRequest}.
+     *
+     * @param request a {@link DownloadRequest}, indicating which download is being referenced.
+     * @param fileInfo a {@link FileInfo} specifying the file to report progress on.  Note that
+     *   the request may result in many files being downloaded and the client
+     *   may not have been able to get a list of them in advance.
+     * @param currentDownloadSize is the current amount downloaded.
+     * @param fullDownloadSize is the total number of bytes that make up the downloaded content.
+     *   This may be different from the decoded final size, but is useful in gauging download
+     *   progress.
+     * @param currentDecodedSize is the number of bytes that have been decoded.
+     * @param fullDecodedSize is the total number of bytes that make up the final decoded content.
+     */
+    public void onProgressUpdated(DownloadRequest request, FileInfo fileInfo,
+            int currentDownloadSize, int fullDownloadSize,
+            int currentDecodedSize, int fullDecodedSize) {
+    }
+
+    /**
+     * Gives download state callbacks for a file in a {@link DownloadRequest}.
+     *
+     * @param request a {@link DownloadRequest}, indicating which download is being referenced.
+     * @param fileInfo a {@link FileInfo} specifying the file to report progress on.  Note that
+     *   the request may result in many files being downloaded and the client
+     *   may not have been able to get a list of them in advance.
+     * @param state The current state of the download.
+     */
+    public void onStateUpdated(DownloadRequest request, FileInfo fileInfo,
+            @MbmsDownloadSession.DownloadStatus int state) {
+    }
+}
diff --git a/telephony/java/android/telephony/mbms/FileInfo.java b/telephony/java/android/telephony/mbms/FileInfo.java
index f97131d..e064adb 100644
--- a/telephony/java/android/telephony/mbms/FileInfo.java
+++ b/telephony/java/android/telephony/mbms/FileInfo.java
@@ -16,26 +16,21 @@
 
 package android.telephony.mbms;
 
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
 
-/**
- * A Parcelable class Cell-Broadcast downloadable file information.
- * @hide
- */
-public class FileInfo implements Parcelable {
+import java.util.Objects;
 
-    /**
-     * The URI into the carriers infrastructure which points to this file.
-     * This is used internally but is also one of the few pieces of data about the content that is
-     * exposed and may be needed for disambiguation by the application.
-     */
+/**
+ * Describes a single file that is available over MBMS.
+ */
+public final class FileInfo implements Parcelable {
+
     private final Uri uri;
 
-    /**
-     * The mime type of the content.
-     */
     private final String mimeType;
 
     public static final Parcelable.Creator<FileInfo> CREATOR =
@@ -53,8 +48,9 @@
 
     /**
      * @hide
-     * TODO: systemapi
      */
+    @SystemApi
+    @TestApi
     public FileInfo(Uri uri, String mimeType) {
         this.uri = uri;
         this.mimeType = mimeType;
@@ -76,11 +72,37 @@
         return 0;
     }
 
+    /**
+     * @return The URI in the carrier's infrastructure which points to this file. Apps should
+     * negotiate the contents of this URI separately with the carrier.
+     */
     public Uri getUri() {
         return uri;
     }
 
+    /**
+     * @return The MIME type of the file.
+     */
     public String getMimeType() {
         return mimeType;
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        FileInfo fileInfo = (FileInfo) o;
+        return Objects.equals(uri, fileInfo.uri) &&
+                Objects.equals(mimeType, fileInfo.mimeType);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(uri, mimeType);
+    }
 }
diff --git a/telephony/java/android/telephony/mbms/FileServiceInfo.java b/telephony/java/android/telephony/mbms/FileServiceInfo.java
index 8afe4d3..b30a3af 100644
--- a/telephony/java/android/telephony/mbms/FileServiceInfo.java
+++ b/telephony/java/android/telephony/mbms/FileServiceInfo.java
@@ -16,6 +16,8 @@
 
 package android.telephony.mbms;
 
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -26,13 +28,15 @@
 import java.util.Map;
 
 /**
- * A Parcelable class Cell-Broadcast downloadable file information.
- * @hide
+ * Describes a file service available from the carrier from which files can be downloaded via
+ * cell-broadcast.
  */
-public class FileServiceInfo extends ServiceInfo implements Parcelable {
+public final class FileServiceInfo extends ServiceInfo implements Parcelable {
     private final List<FileInfo> files;
 
-    /** @hide TODO: systemapi */
+    /** @hide */
+    @SystemApi
+    @TestApi
     public FileServiceInfo(Map<Locale, String> newNames, String newClassName,
             List<Locale> newLocales, String newServiceId, Date start, Date end,
             List<FileInfo> newFiles) {
@@ -56,7 +60,7 @@
     FileServiceInfo(Parcel in) {
         super(in);
         files = new ArrayList<FileInfo>();
-        in.readList(files, null);
+        in.readList(files, FileInfo.class.getClassLoader());
     }
 
     @Override
@@ -70,8 +74,12 @@
         return 0;
     }
 
+    /**
+     * @return A list of files available from this service. Note that this list may not be
+     * exhaustive -- the middleware may not have information on all files that are available.
+     * Consult the carrier for an authoritative and exhaustive list.
+     */
     public List<FileInfo> getFiles() {
         return files;
     }
-
 }
diff --git a/telephony/java/android/telephony/mbms/IDownloadProgressListener.aidl b/telephony/java/android/telephony/mbms/IDownloadProgressListener.aidl
deleted file mode 100755
index bb9dc6c..0000000
--- a/telephony/java/android/telephony/mbms/IDownloadProgressListener.aidl
+++ /dev/null
@@ -1,34 +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.
-*/
-
-package android.telephony.mbms;
-
-import android.telephony.mbms.DownloadRequest;
-import android.telephony.mbms.FileInfo;
-
-/**
- * The optional interface used by download clients to track progress.
- * @hide
- */
-interface IDownloadProgressListener
-{
-    /**
-     * Gives progress callbacks for a given DownloadRequest.  Includes a FileInfo
-     * as the list of files may not have been known at request-time.
-     */
-    void progress(in DownloadRequest request, in FileInfo fileInfo, int currentDownloadSize,
-            int fullDownloadSize, int currentDecodedSize, int fullDecodedSize);
-}
diff --git a/telephony/java/android/telephony/mbms/IDownloadStateCallback.aidl b/telephony/java/android/telephony/mbms/IDownloadStateCallback.aidl
new file mode 100755
index 0000000..cebc70d
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/IDownloadStateCallback.aidl
@@ -0,0 +1,37 @@
+/*
+** 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;
+
+import android.telephony.mbms.DownloadRequest;
+import android.telephony.mbms.FileInfo;
+
+/**
+ * The optional interface used by download clients to track progress.
+ * @hide
+ */
+interface IDownloadStateCallback
+{
+    /**
+     * Gives progress callbacks for a given DownloadRequest.  Includes a FileInfo
+     * as the list of files may not have been known at request-time.
+     */
+    void onProgressUpdated(in DownloadRequest request, in FileInfo fileInfo,
+            int currentDownloadSize, int fullDownloadSize,
+            int currentDecodedSize, int fullDecodedSize);
+
+    void onStateUpdated(in DownloadRequest request, in FileInfo fileInfo, int state);
+}
diff --git a/telephony/java/android/telephony/mbms/IMbmsDownloadManagerCallback.aidl b/telephony/java/android/telephony/mbms/IMbmsDownloadManagerCallback.aidl
deleted file mode 100755
index ac2f202..0000000
--- a/telephony/java/android/telephony/mbms/IMbmsDownloadManagerCallback.aidl
+++ /dev/null
@@ -1,34 +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.
-*/
-
-package android.telephony.mbms;
-
-import android.telephony.mbms.FileServiceInfo;
-
-import java.util.List;
-
-/**
- * The interface the clients top-level file download listener will satisfy.
- * @hide
- */
-oneway interface IMbmsDownloadManagerCallback
-{
-    void error(int errorCode, String message);
-
-    void fileServicesUpdated(in List<FileServiceInfo> services);
-
-    void middlewareReady();
-}
diff --git a/telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl b/telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl
new file mode 100755
index 0000000..0d813a7
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl
@@ -0,0 +1,34 @@
+/*
+** 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;
+
+import android.telephony.mbms.FileServiceInfo;
+
+import java.util.List;
+
+/**
+ * The interface the clients top-level file download listener will satisfy.
+ * @hide
+ */
+oneway interface IMbmsDownloadSessionCallback
+{
+    void onError(int errorCode, String message);
+
+    void onFileServicesUpdated(in List<FileServiceInfo> services);
+
+    void onMiddlewareReady();
+}
diff --git a/telephony/java/android/telephony/mbms/IMbmsStreamingManagerCallback.aidl b/telephony/java/android/telephony/mbms/IMbmsStreamingManagerCallback.aidl
deleted file mode 100755
index 007aee7..0000000
--- a/telephony/java/android/telephony/mbms/IMbmsStreamingManagerCallback.aidl
+++ /dev/null
@@ -1,34 +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.
-*/
-
-package android.telephony.mbms;
-
-import android.telephony.mbms.StreamingServiceInfo;
-
-import java.util.List;
-
-/**
- * The interface the clients top-level streaming listener will satisfy.
- * @hide
- */
-oneway interface IMbmsStreamingManagerCallback
-{
-    void error(int errorCode, String message);
-
-    void streamingServicesUpdated(in List<StreamingServiceInfo> services);
-
-    void middlewareReady();
-}
diff --git a/telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl b/telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl
new file mode 100755
index 0000000..0bf0ebc
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl
@@ -0,0 +1,34 @@
+/*
+** 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;
+
+import android.telephony.mbms.StreamingServiceInfo;
+
+import java.util.List;
+
+/**
+ * The interface the clients top-level streaming listener will satisfy.
+ * @hide
+ */
+oneway interface IMbmsStreamingSessionCallback
+{
+    void onError(int errorCode, String message);
+
+    void onStreamingServicesUpdated(in List<StreamingServiceInfo> services);
+
+    void onMiddlewareReady();
+}
diff --git a/telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl b/telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl
index 0952fbe..164cefb 100755
--- a/telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl
+++ b/telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl
@@ -20,9 +20,9 @@
  * @hide
  */
 oneway interface IStreamingServiceCallback {
-    void error(int errorCode, String message);
-    void streamStateUpdated(int state, int reason);
-    void mediaDescriptionUpdated();
-    void broadcastSignalStrengthUpdated(int signalStrength);
-    void streamMethodUpdated(int methodType);
+    void onError(int errorCode, String message);
+    void onStreamStateUpdated(int state, int reason);
+    void onMediaDescriptionUpdated();
+    void onBroadcastSignalStrengthUpdated(int signalStrength);
+    void onStreamMethodUpdated(int methodType);
 }
diff --git a/telephony/java/android/telephony/mbms/InternalDownloadSessionCallback.java b/telephony/java/android/telephony/mbms/InternalDownloadSessionCallback.java
new file mode 100644
index 0000000..a7a5958
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/InternalDownloadSessionCallback.java
@@ -0,0 +1,86 @@
+/*
+ * 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.telephony.mbms;
+
+import android.os.Handler;
+import android.os.RemoteException;
+
+import java.util.List;
+
+/** @hide */
+public class InternalDownloadSessionCallback extends IMbmsDownloadSessionCallback.Stub {
+
+    private final Handler mHandler;
+    private final MbmsDownloadSessionCallback mAppCallback;
+    private volatile boolean mIsStopped = false;
+
+    public InternalDownloadSessionCallback(MbmsDownloadSessionCallback appCallback,
+            Handler handler) {
+        mAppCallback = appCallback;
+        mHandler = handler;
+    }
+
+    @Override
+    public void onError(final int errorCode, final String message) throws RemoteException {
+        if (mIsStopped) {
+            return;
+        }
+
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mAppCallback.onError(errorCode, message);
+            }
+        });
+    }
+
+    @Override
+    public void onFileServicesUpdated(final List<FileServiceInfo> services) throws RemoteException {
+        if (mIsStopped) {
+            return;
+        }
+
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mAppCallback.onFileServicesUpdated(services);
+            }
+        });
+    }
+
+    @Override
+    public void onMiddlewareReady() throws RemoteException {
+        if (mIsStopped) {
+            return;
+        }
+
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mAppCallback.onMiddlewareReady();
+            }
+        });
+    }
+
+    public Handler getHandler() {
+        return mHandler;
+    }
+
+    public void stop() {
+        mIsStopped = true;
+    }
+}
diff --git a/telephony/java/android/telephony/mbms/InternalDownloadStateCallback.java b/telephony/java/android/telephony/mbms/InternalDownloadStateCallback.java
new file mode 100644
index 0000000..8702952
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/InternalDownloadStateCallback.java
@@ -0,0 +1,70 @@
+/*
+ * 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.telephony.mbms;
+
+import android.os.Handler;
+import android.os.RemoteException;
+
+/**
+ * @hide
+ */
+public class InternalDownloadStateCallback extends IDownloadStateCallback.Stub {
+    private final Handler mHandler;
+    private final DownloadStateCallback mAppCallback;
+    private volatile boolean mIsStopped = false;
+
+    public InternalDownloadStateCallback(DownloadStateCallback appCallback, Handler handler) {
+        mAppCallback = appCallback;
+        mHandler = handler;
+    }
+
+    @Override
+    public void onProgressUpdated(final DownloadRequest request, final FileInfo fileInfo,
+            final int currentDownloadSize, final int fullDownloadSize, final int currentDecodedSize,
+            final int fullDecodedSize) throws RemoteException {
+        if (mIsStopped) {
+            return;
+        }
+
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mAppCallback.onProgressUpdated(request, fileInfo, currentDownloadSize,
+                        fullDownloadSize, currentDecodedSize, fullDecodedSize);
+            }
+        });
+    }
+
+    @Override
+    public void onStateUpdated(final DownloadRequest request, final FileInfo fileInfo,
+            final int state) throws RemoteException {
+        if (mIsStopped) {
+            return;
+        }
+
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mAppCallback.onStateUpdated(request, fileInfo, state);
+            }
+        });
+    }
+
+    public void stop() {
+        mIsStopped = true;
+    }
+}
diff --git a/telephony/java/android/telephony/mbms/InternalStreamingManagerCallback.java b/telephony/java/android/telephony/mbms/InternalStreamingManagerCallback.java
deleted file mode 100644
index b52df8c..0000000
--- a/telephony/java/android/telephony/mbms/InternalStreamingManagerCallback.java
+++ /dev/null
@@ -1,72 +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.telephony.mbms;
-
-import android.os.Handler;
-import android.os.RemoteException;
-import android.telephony.mbms.IMbmsStreamingManagerCallback;
-import android.telephony.mbms.MbmsStreamingManagerCallback;
-import android.telephony.mbms.StreamingServiceInfo;
-
-import java.util.List;
-
-/** @hide */
-public class InternalStreamingManagerCallback extends IMbmsStreamingManagerCallback.Stub {
-    private final Handler mHandler;
-    private final MbmsStreamingManagerCallback mAppCallback;
-
-    public InternalStreamingManagerCallback(MbmsStreamingManagerCallback appCallback,
-            Handler handler) {
-        mAppCallback = appCallback;
-        mHandler = handler;
-    }
-
-    @Override
-    public void error(int errorCode, String message) throws RemoteException {
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                mAppCallback.onError(errorCode, message);
-            }
-        });
-    }
-
-    @Override
-    public void streamingServicesUpdated(List<StreamingServiceInfo> services)
-            throws RemoteException {
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                mAppCallback.onStreamingServicesUpdated(services);
-            }
-        });
-    }
-
-    @Override
-    public void middlewareReady() throws RemoteException {
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                mAppCallback.onMiddlewareReady();
-            }
-        });
-    }
-
-    public Handler getHandler() {
-        return mHandler;
-    }
-}
diff --git a/telephony/java/android/telephony/mbms/InternalStreamingServiceCallback.java b/telephony/java/android/telephony/mbms/InternalStreamingServiceCallback.java
index bb337b2..eb6579ce 100644
--- a/telephony/java/android/telephony/mbms/InternalStreamingServiceCallback.java
+++ b/telephony/java/android/telephony/mbms/InternalStreamingServiceCallback.java
@@ -23,6 +23,7 @@
 public class InternalStreamingServiceCallback extends IStreamingServiceCallback.Stub {
     private final StreamingServiceCallback mAppCallback;
     private final Handler mHandler;
+    private volatile boolean mIsStopped = false;
 
     public InternalStreamingServiceCallback(StreamingServiceCallback appCallback, Handler handler) {
         mAppCallback = appCallback;
@@ -30,7 +31,11 @@
     }
 
     @Override
-    public void error(int errorCode, String message) throws RemoteException {
+    public void onError(final int errorCode, final String message) throws RemoteException {
+        if (mIsStopped) {
+            return;
+        }
+
         mHandler.post(new Runnable() {
             @Override
             public void run() {
@@ -40,7 +45,11 @@
     }
 
     @Override
-    public void streamStateUpdated(int state, int reason) throws RemoteException {
+    public void onStreamStateUpdated(final int state, final int reason) throws RemoteException {
+        if (mIsStopped) {
+            return;
+        }
+
         mHandler.post(new Runnable() {
             @Override
             public void run() {
@@ -50,7 +59,11 @@
     }
 
     @Override
-    public void mediaDescriptionUpdated() throws RemoteException {
+    public void onMediaDescriptionUpdated() throws RemoteException {
+        if (mIsStopped) {
+            return;
+        }
+
         mHandler.post(new Runnable() {
             @Override
             public void run() {
@@ -60,7 +73,11 @@
     }
 
     @Override
-    public void broadcastSignalStrengthUpdated(int signalStrength) throws RemoteException {
+    public void onBroadcastSignalStrengthUpdated(final int signalStrength) throws RemoteException {
+        if (mIsStopped) {
+            return;
+        }
+
         mHandler.post(new Runnable() {
             @Override
             public void run() {
@@ -70,7 +87,11 @@
     }
 
     @Override
-    public void streamMethodUpdated(int methodType) throws RemoteException {
+    public void onStreamMethodUpdated(final int methodType) throws RemoteException {
+        if (mIsStopped) {
+            return;
+        }
+
         mHandler.post(new Runnable() {
             @Override
             public void run() {
@@ -78,4 +99,8 @@
             }
         });
     }
+
+    public void stop() {
+        mIsStopped = true;
+    }
 }
diff --git a/telephony/java/android/telephony/mbms/InternalStreamingSessionCallback.java b/telephony/java/android/telephony/mbms/InternalStreamingSessionCallback.java
new file mode 100644
index 0000000..d782d12
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/InternalStreamingSessionCallback.java
@@ -0,0 +1,86 @@
+/*
+ * 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.telephony.mbms;
+
+import android.os.Handler;
+import android.os.RemoteException;
+
+import java.util.List;
+
+/** @hide */
+public class InternalStreamingSessionCallback extends IMbmsStreamingSessionCallback.Stub {
+    private final Handler mHandler;
+    private final MbmsStreamingSessionCallback mAppCallback;
+    private volatile boolean mIsStopped = false;
+
+    public InternalStreamingSessionCallback(MbmsStreamingSessionCallback appCallback,
+            Handler handler) {
+        mAppCallback = appCallback;
+        mHandler = handler;
+    }
+
+    @Override
+    public void onError(final int errorCode, final String message) throws RemoteException {
+        if (mIsStopped) {
+            return;
+        }
+
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mAppCallback.onError(errorCode, message);
+            }
+        });
+    }
+
+    @Override
+    public void onStreamingServicesUpdated(final List<StreamingServiceInfo> services)
+            throws RemoteException {
+        if (mIsStopped) {
+            return;
+        }
+
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mAppCallback.onStreamingServicesUpdated(services);
+            }
+        });
+    }
+
+    @Override
+    public void onMiddlewareReady() throws RemoteException {
+        if (mIsStopped) {
+            return;
+        }
+
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mAppCallback.onMiddlewareReady();
+            }
+        });
+    }
+
+    public Handler getHandler() {
+        return mHandler;
+    }
+
+    public void stop() {
+        mIsStopped = true;
+    }
+}
diff --git a/telephony/java/android/telephony/mbms/MbmsDownloadManagerCallback.java b/telephony/java/android/telephony/mbms/MbmsDownloadManagerCallback.java
deleted file mode 100644
index 17291d0..0000000
--- a/telephony/java/android/telephony/mbms/MbmsDownloadManagerCallback.java
+++ /dev/null
@@ -1,64 +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.telephony.mbms;
-
-import android.os.RemoteException;
-import android.telephony.MbmsDownloadManager;
-
-import java.util.List;
-
-/**
- * A Parcelable class with Cell-Broadcast service information.
- * @hide
- */
-public class MbmsDownloadManagerCallback extends IMbmsDownloadManagerCallback.Stub {
-
-    @Override
-    public void error(int errorCode, String message) throws RemoteException {
-        // default implementation empty
-    }
-
-    /**
-     * Called to indicate published File Services have changed.
-     *
-     * This will only be called after the application has requested
-     * a list of file services and specified a service class list
-     * of interest AND the results of a subsequent getFileServices
-     * call with the same service class list would return different
-     * results.
-     *
-     * @param services a List of FileServiceInfos
-     *
-     */
-    @Override
-    public void fileServicesUpdated(List<FileServiceInfo> services) throws RemoteException {
-        // default implementation empty
-    }
-
-    /**
-     * 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 android.telephony.MbmsDownloadManager} will result in an {@link MbmsException}
-     * being thrown with error code {@link MbmsException#ERROR_MIDDLEWARE_NOT_BOUND}
-     * or {@link MbmsException.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}
-     */
-    @Override
-    public void middlewareReady() throws RemoteException {
-        // default implementation empty
-    }
-}
diff --git a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
index ba7d120..9ef188c 100644
--- a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
+++ b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
@@ -16,6 +16,7 @@
 
 package android.telephony.mbms;
 
+import android.annotation.SystemApi;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -24,8 +25,8 @@
 import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Bundle;
-import android.telephony.MbmsDownloadManager;
-import android.telephony.mbms.vendor.VendorIntents;
+import android.telephony.MbmsDownloadSession;
+import android.telephony.mbms.vendor.VendorUtils;
 import android.util.Log;
 
 import java.io.File;
@@ -35,52 +36,74 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
 import java.util.UUID;
 
 /**
- * @hide
+ * The {@link BroadcastReceiver} responsible for handling intents sent from the middleware. Apps
+ * that wish to download using MBMS APIs should declare this class in their AndroidManifest.xml as
+ * follows:
+<pre>{@code
+<receiver
+    android:name="android.telephony.mbms.MbmsDownloadReceiver"
+    android:permission="android.permission.SEND_EMBMS_INTENTS"
+    android:enabled="true"
+    android:exported="true">
+</receiver>}</pre>
  */
 public class MbmsDownloadReceiver extends BroadcastReceiver {
+    /** @hide */
     public static final String DOWNLOAD_TOKEN_SUFFIX = ".download_token";
+    /** @hide */
     public static final String MBMS_FILE_PROVIDER_META_DATA_KEY = "mbms-file-provider-authority";
 
     /**
-     * TODO: @SystemApi all these result codes
      * Indicates that the requested operation completed without error.
+     * @hide
      */
+    @SystemApi
     public static final int RESULT_OK = 0;
 
     /**
      * Indicates that the intent sent had an invalid action. This will be the result if
      * {@link Intent#getAction()} returns anything other than
-     * {@link VendorIntents#ACTION_DOWNLOAD_RESULT_INTERNAL},
-     * {@link VendorIntents#ACTION_FILE_DESCRIPTOR_REQUEST}, or
-     * {@link VendorIntents#ACTION_CLEANUP}.
+     * {@link VendorUtils#ACTION_DOWNLOAD_RESULT_INTERNAL},
+     * {@link VendorUtils#ACTION_FILE_DESCRIPTOR_REQUEST}, or
+     * {@link VendorUtils#ACTION_CLEANUP}.
      * This is a fatal result code and no result extras should be expected.
+     * @hide
      */
+    @SystemApi
     public static final int RESULT_INVALID_ACTION = 1;
 
     /**
      * Indicates that the intent was missing some required extras.
      * This is a fatal result code and no result extras should be expected.
+     * @hide
      */
+    @SystemApi
     public static final int RESULT_MALFORMED_INTENT = 2;
 
     /**
-     * Indicates that the supplied value for {@link VendorIntents#EXTRA_TEMP_FILE_ROOT}
+     * Indicates that the supplied value for {@link VendorUtils#EXTRA_TEMP_FILE_ROOT}
      * does not match what the app has stored.
      * This is a fatal result code and no result extras should be expected.
+     * @hide
      */
+    @SystemApi
     public static final int RESULT_BAD_TEMP_FILE_ROOT = 3;
 
     /**
      * Indicates that the manager was unable to move the completed download to its final location.
      * This is a fatal result code and no result extras should be expected.
+     * @hide
      */
+    @SystemApi
     public static final int RESULT_DOWNLOAD_FINALIZATION_ERROR = 4;
 
     /**
@@ -88,35 +111,48 @@
      * descriptors.
      * This is a non-fatal result code -- some file descriptors may still be generated, but there
      * is no guarantee that they will be the same number as requested.
+     * @hide
      */
+    @SystemApi
     public static final int RESULT_TEMP_FILE_GENERATION_ERROR = 5;
 
+    /**
+     * Indicates that the manager was unable to notify the app of the completed download.
+     * This is a fatal result code and no result extras should be expected.
+     * @hide
+     */
+    @SystemApi
+    public static final int RESULT_APP_NOTIFICATION_ERROR = 6;
+
+
     private static final String LOG_TAG = "MbmsDownloadReceiver";
     private static final String TEMP_FILE_SUFFIX = ".embms.temp";
-    private static final int MAX_TEMP_FILE_RETRIES = 5;
+    private static final String TEMP_FILE_STAGING_LOCATION = "staged_completed_files";
 
+    private static final int MAX_TEMP_FILE_RETRIES = 5;
 
     private String mFileProviderAuthorityCache = null;
     private String mMiddlewarePackageNameCache = null;
 
+    /** @hide */
     @Override
     public void onReceive(Context context, Intent intent) {
         if (!verifyIntentContents(context, intent)) {
             setResultCode(RESULT_MALFORMED_INTENT);
             return;
         }
-        if (!Objects.equals(intent.getStringExtra(VendorIntents.EXTRA_TEMP_FILE_ROOT),
+        if (!Objects.equals(intent.getStringExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT),
                 MbmsTempFileProvider.getEmbmsTempFileDir(context).getPath())) {
             setResultCode(RESULT_BAD_TEMP_FILE_ROOT);
             return;
         }
 
-        if (VendorIntents.ACTION_DOWNLOAD_RESULT_INTERNAL.equals(intent.getAction())) {
+        if (VendorUtils.ACTION_DOWNLOAD_RESULT_INTERNAL.equals(intent.getAction())) {
             moveDownloadedFile(context, intent);
             cleanupPostMove(context, intent);
-        } else if (VendorIntents.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) {
+        } else if (VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) {
             generateTempFiles(context, intent);
-        } else if (VendorIntents.ACTION_CLEANUP.equals(intent.getAction())) {
+        } else if (VendorUtils.ACTION_CLEANUP.equals(intent.getAction())) {
             cleanupTempFiles(context, intent);
         } else {
             setResultCode(RESULT_INVALID_ACTION);
@@ -124,30 +160,37 @@
     }
 
     private boolean verifyIntentContents(Context context, Intent intent) {
-        if (VendorIntents.ACTION_DOWNLOAD_RESULT_INTERNAL.equals(intent.getAction())) {
-            if (!intent.hasExtra(MbmsDownloadManager.EXTRA_RESULT)) {
+        if (VendorUtils.ACTION_DOWNLOAD_RESULT_INTERNAL.equals(intent.getAction())) {
+            if (!intent.hasExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT)) {
                 Log.w(LOG_TAG, "Download result did not include a result code. Ignoring.");
                 return false;
             }
-            if (!intent.hasExtra(VendorIntents.EXTRA_REQUEST)) {
+            if (!intent.hasExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST)) {
                 Log.w(LOG_TAG, "Download result did not include the associated request. Ignoring.");
                 return false;
             }
-            if (!intent.hasExtra(VendorIntents.EXTRA_TEMP_FILE_ROOT)) {
+            // We do not need to verify below extras if the result is not success.
+            if (MbmsDownloadSession.RESULT_SUCCESSFUL !=
+                    intent.getIntExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT,
+                    MbmsDownloadSession.RESULT_CANCELLED)) {
+                return true;
+            }
+            if (!intent.hasExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT)) {
                 Log.w(LOG_TAG, "Download result did not include the temp file root. Ignoring.");
                 return false;
             }
-            if (!intent.hasExtra(MbmsDownloadManager.EXTRA_FILE_INFO)) {
+            if (!intent.hasExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO)) {
                 Log.w(LOG_TAG, "Download result did not include the associated file info. " +
                         "Ignoring.");
                 return false;
             }
-            if (!intent.hasExtra(VendorIntents.EXTRA_FINAL_URI)) {
+            if (!intent.hasExtra(VendorUtils.EXTRA_FINAL_URI)) {
                 Log.w(LOG_TAG, "Download result did not include the path to the final " +
                         "temp file. Ignoring.");
                 return false;
             }
-            DownloadRequest request = intent.getParcelableExtra(VendorIntents.EXTRA_REQUEST);
+            DownloadRequest request = intent.getParcelableExtra(
+                    MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST);
             String expectedTokenFileName = request.getHash() + DOWNLOAD_TOKEN_SUFFIX;
             File expectedTokenFile = new File(
                     MbmsUtils.getEmbmsTempFileDirForService(context, request.getFileServiceId()),
@@ -157,27 +200,27 @@
                         "Expected " + expectedTokenFile);
                 return false;
             }
-        } else if (VendorIntents.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) {
-            if (!intent.hasExtra(VendorIntents.EXTRA_SERVICE_INFO)) {
-                Log.w(LOG_TAG, "Temp file request did not include the associated service info." +
+        } else if (VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) {
+            if (!intent.hasExtra(VendorUtils.EXTRA_SERVICE_ID)) {
+                Log.w(LOG_TAG, "Temp file request did not include the associated service id." +
                         " Ignoring.");
                 return false;
             }
-            if (!intent.hasExtra(VendorIntents.EXTRA_TEMP_FILE_ROOT)) {
+            if (!intent.hasExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT)) {
                 Log.w(LOG_TAG, "Download result did not include the temp file root. Ignoring.");
                 return false;
             }
-        } else if (VendorIntents.ACTION_CLEANUP.equals(intent.getAction())) {
-            if (!intent.hasExtra(VendorIntents.EXTRA_SERVICE_INFO)) {
-                Log.w(LOG_TAG, "Cleanup request did not include the associated service info." +
+        } else if (VendorUtils.ACTION_CLEANUP.equals(intent.getAction())) {
+            if (!intent.hasExtra(VendorUtils.EXTRA_SERVICE_ID)) {
+                Log.w(LOG_TAG, "Cleanup request did not include the associated service id." +
                         " Ignoring.");
                 return false;
             }
-            if (!intent.hasExtra(VendorIntents.EXTRA_TEMP_FILE_ROOT)) {
+            if (!intent.hasExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT)) {
                 Log.w(LOG_TAG, "Cleanup request did not include the temp file root. Ignoring.");
                 return false;
             }
-            if (!intent.hasExtra(VendorIntents.EXTRA_TEMP_FILES_IN_USE)) {
+            if (!intent.hasExtra(VendorUtils.EXTRA_TEMP_FILES_IN_USE)) {
                 Log.w(LOG_TAG, "Cleanup request did not include the list of temp files in use. " +
                         "Ignoring.");
                 return false;
@@ -187,21 +230,28 @@
     }
 
     private void moveDownloadedFile(Context context, Intent intent) {
-        DownloadRequest request = intent.getParcelableExtra(VendorIntents.EXTRA_REQUEST);
+        DownloadRequest request = intent.getParcelableExtra(
+                MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST);
         Intent intentForApp = request.getIntentForApp();
-
-        int result = intent.getIntExtra(MbmsDownloadManager.EXTRA_RESULT,
-                MbmsDownloadManager.RESULT_CANCELLED);
-        intentForApp.putExtra(MbmsDownloadManager.EXTRA_RESULT, result);
-
-        if (result != MbmsDownloadManager.RESULT_SUCCESSFUL) {
-            Log.i(LOG_TAG, "Download request indicated a failed download. Aborting.");
-            context.sendBroadcast(intentForApp);
+        if (intentForApp == null) {
+            Log.i(LOG_TAG, "Malformed app notification intent");
+            setResultCode(RESULT_APP_NOTIFICATION_ERROR);
             return;
         }
 
-        Uri destinationUri = request.getDestinationUri();
-        Uri finalTempFile = intent.getParcelableExtra(VendorIntents.EXTRA_FINAL_URI);
+        int result = intent.getIntExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT,
+                MbmsDownloadSession.RESULT_CANCELLED);
+        intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT, result);
+        intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, request);
+
+        if (result != MbmsDownloadSession.RESULT_SUCCESSFUL) {
+            Log.i(LOG_TAG, "Download request indicated a failed download. Aborting.");
+            context.sendBroadcast(intentForApp);
+            setResultCode(RESULT_OK);
+            return;
+        }
+
+        Uri finalTempFile = intent.getParcelableExtra(VendorUtils.EXTRA_FINAL_URI);
         if (!verifyTempFilePath(context, request.getFileServiceId(), finalTempFile)) {
             Log.w(LOG_TAG, "Download result specified an invalid temp file " + finalTempFile);
             setResultCode(RESULT_DOWNLOAD_FINALIZATION_ERROR);
@@ -209,30 +259,36 @@
         }
 
         FileInfo completedFileInfo =
-                (FileInfo) intent.getParcelableExtra(MbmsDownloadManager.EXTRA_FILE_INFO);
-        String relativePath = calculateDestinationFileRelativePath(request, completedFileInfo);
+                (FileInfo) intent.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO);
+        Path stagingDirectory = FileSystems.getDefault().getPath(
+                MbmsTempFileProvider.getEmbmsTempFileDir(context).getPath(),
+                TEMP_FILE_STAGING_LOCATION);
 
-        Uri finalFileLocation = moveTempFile(finalTempFile, destinationUri, relativePath);
-        if (finalFileLocation == null) {
+        Uri stagedFileLocation;
+        try {
+            stagedFileLocation = stageTempFile(finalTempFile, stagingDirectory);
+        } catch (IOException e) {
             Log.w(LOG_TAG, "Failed to move temp file to final destination");
             setResultCode(RESULT_DOWNLOAD_FINALIZATION_ERROR);
             return;
         }
-        intentForApp.putExtra(MbmsDownloadManager.EXTRA_COMPLETED_FILE_URI, finalFileLocation);
-        intentForApp.putExtra(MbmsDownloadManager.EXTRA_FILE_INFO, completedFileInfo);
+        intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_COMPLETED_FILE_URI,
+                stagedFileLocation);
+        intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO, completedFileInfo);
 
         context.sendBroadcast(intentForApp);
         setResultCode(RESULT_OK);
     }
 
     private void cleanupPostMove(Context context, Intent intent) {
-        DownloadRequest request = intent.getParcelableExtra(VendorIntents.EXTRA_REQUEST);
+        DownloadRequest request = intent.getParcelableExtra(
+                MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST);
         if (request == null) {
             Log.w(LOG_TAG, "Intent does not include a DownloadRequest. Ignoring.");
             return;
         }
 
-        List<Uri> tempFiles = intent.getParcelableExtra(VendorIntents.EXTRA_TEMP_LIST);
+        List<Uri> tempFiles = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_LIST);
         if (tempFiles == null) {
             return;
         }
@@ -246,16 +302,15 @@
     }
 
     private void generateTempFiles(Context context, Intent intent) {
-        FileServiceInfo serviceInfo =
-                intent.getParcelableExtra(VendorIntents.EXTRA_SERVICE_INFO);
-        if (serviceInfo == null) {
-            Log.w(LOG_TAG, "Temp file request did not include the associated service info. " +
+        String serviceId = intent.getStringExtra(VendorUtils.EXTRA_SERVICE_ID);
+        if (serviceId == null) {
+            Log.w(LOG_TAG, "Temp file request did not include the associated service id. " +
                     "Ignoring.");
             setResultCode(RESULT_MALFORMED_INTENT);
             return;
         }
-        int fdCount = intent.getIntExtra(VendorIntents.EXTRA_FD_COUNT, 0);
-        List<Uri> pausedList = intent.getParcelableExtra(VendorIntents.EXTRA_PAUSED_LIST);
+        int fdCount = intent.getIntExtra(VendorUtils.EXTRA_FD_COUNT, 0);
+        List<Uri> pausedList = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_PAUSED_LIST);
 
         if (fdCount == 0 && (pausedList == null || pausedList.size() == 0)) {
             Log.i(LOG_TAG, "No temp files actually requested. Ending.");
@@ -265,22 +320,20 @@
         }
 
         ArrayList<UriPathPair> freshTempFiles =
-                generateFreshTempFiles(context, serviceInfo, fdCount);
+                generateFreshTempFiles(context, serviceId, fdCount);
         ArrayList<UriPathPair> pausedFiles =
-                generateUrisForPausedFiles(context, serviceInfo, pausedList);
+                generateUrisForPausedFiles(context, serviceId, pausedList);
 
         Bundle result = new Bundle();
-        result.putParcelableArrayList(VendorIntents.EXTRA_FREE_URI_LIST, freshTempFiles);
-        result.putParcelableArrayList(VendorIntents.EXTRA_PAUSED_URI_LIST, pausedFiles);
+        result.putParcelableArrayList(VendorUtils.EXTRA_FREE_URI_LIST, freshTempFiles);
+        result.putParcelableArrayList(VendorUtils.EXTRA_PAUSED_URI_LIST, pausedFiles);
         setResultCode(RESULT_OK);
         setResultExtras(result);
     }
 
-    private ArrayList<UriPathPair> generateFreshTempFiles(Context context,
-            FileServiceInfo serviceInfo,
+    private ArrayList<UriPathPair> generateFreshTempFiles(Context context, String serviceId,
             int freshFdCount) {
-        File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context,
-                serviceInfo.getServiceId());
+        File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context, serviceId);
         if (!tempFileDir.exists()) {
             tempFileDir.mkdirs();
         }
@@ -324,14 +377,14 @@
     }
 
     private ArrayList<UriPathPair> generateUrisForPausedFiles(Context context,
-            FileServiceInfo serviceInfo, List<Uri> pausedFiles) {
+            String serviceId, List<Uri> pausedFiles) {
         if (pausedFiles == null) {
             return new ArrayList<>(0);
         }
         ArrayList<UriPathPair> result = new ArrayList<>(pausedFiles.size());
 
         for (Uri fileUri : pausedFiles) {
-            if (!verifyTempFilePath(context, serviceInfo.getServiceId(), fileUri)) {
+            if (!verifyTempFilePath(context, serviceId, fileUri)) {
                 Log.w(LOG_TAG, "Supplied file " + fileUri + " is not a valid temp file to resume");
                 setResultCode(RESULT_TEMP_FILE_GENERATION_ERROR);
                 continue;
@@ -353,12 +406,10 @@
     }
 
     private void cleanupTempFiles(Context context, Intent intent) {
-        FileServiceInfo serviceInfo =
-                intent.getParcelableExtra(VendorIntents.EXTRA_SERVICE_INFO);
-        File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context,
-                serviceInfo.getServiceId());
+        String serviceId = intent.getStringExtra(VendorUtils.EXTRA_SERVICE_ID);
+        File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context, serviceId);
         final List<Uri> filesInUse =
-                intent.getParcelableArrayListExtra(VendorIntents.EXTRA_TEMP_FILES_IN_USE);
+                intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_FILES_IN_USE);
         File[] filesToDelete = tempFileDir.listFiles(new FileFilter() {
             @Override
             public boolean accept(File file) {
@@ -385,63 +436,22 @@
         }
     }
 
-    private static String calculateDestinationFileRelativePath(DownloadRequest request,
-            FileInfo info) {
-        List<String> filePathComponents = info.getUri().getPathSegments();
-        List<String> requestPathComponents = request.getSourceUri().getPathSegments();
-        Iterator<String> filePathIter = filePathComponents.iterator();
-        Iterator<String> requestPathIter = requestPathComponents.iterator();
-
-        StringBuilder pathBuilder = new StringBuilder();
-        // Iterate through the segments of the carrier's URI to the file, along with the segments
-        // of the source URI specified in the download request. The relative path is calculated
-        // as the tail of the file's URI that does not match the path segments in the source URI.
-        while (filePathIter.hasNext()) {
-            String currFilePathComponent = filePathIter.next();
-            if (requestPathIter.hasNext()) {
-                String requestFilePathComponent = requestPathIter.next();
-                if (requestFilePathComponent.equals(currFilePathComponent)) {
-                    continue;
-                }
-            }
-            pathBuilder.append(currFilePathComponent);
-            pathBuilder.append('/');
-        }
-        // remove the trailing slash
-        if (pathBuilder.length() > 0) {
-            pathBuilder.deleteCharAt(pathBuilder.length() - 1);
-        }
-        return pathBuilder.toString();
-    }
-
     /*
-     * Moves a tempfile located at fromPath to a new location at toPath. If
-     * toPath is a directory, the destination file will be located at  relativePath
-     * underneath toPath.
+     * Moves a tempfile located at fromPath to a new location in the staging directory.
      */
-    private static Uri moveTempFile(Uri fromPath, Uri toPath, String relativePath) {
+    private static Uri stageTempFile(Uri fromPath, Path stagingDirectory) throws IOException {
         if (!ContentResolver.SCHEME_FILE.equals(fromPath.getScheme())) {
             Log.w(LOG_TAG, "Moving source uri " + fromPath+ " does not have a file scheme");
             return null;
         }
-        if (!ContentResolver.SCHEME_FILE.equals(toPath.getScheme())) {
-            Log.w(LOG_TAG, "Moving destination uri " + toPath + " does not have a file scheme");
-            return null;
-        }
 
-        File fromFile = new File(fromPath.getSchemeSpecificPart());
-        File toFile = new File(toPath.getSchemeSpecificPart());
-        if (toFile.isDirectory()) {
-            toFile = new File(toFile, relativePath);
+        Path fromFile = FileSystems.getDefault().getPath(fromPath.getPath());
+        if (!Files.isDirectory(stagingDirectory)) {
+            Files.createDirectory(stagingDirectory);
         }
-        toFile.getParentFile().mkdirs();
+        Path result = Files.move(fromFile, stagingDirectory.resolve(fromFile.getFileName()));
 
-        if (fromFile.renameTo(toFile)) {
-            return Uri.fromFile(toFile);
-        } else if (manualMove(fromFile, toFile)) {
-            return Uri.fromFile(toFile);
-        }
-        return null;
+        return Uri.fromFile(result.toFile());
     }
 
     private static boolean verifyTempFilePath(Context context, String serviceId,
@@ -483,9 +493,14 @@
         } catch (PackageManager.NameNotFoundException e) {
             throw new RuntimeException("Package manager couldn't find " + context.getPackageName());
         }
+        if (appInfo.metaData == null) {
+            throw new RuntimeException("App must declare the file provider authority as metadata " +
+                    "in the manifest.");
+        }
         String authority = appInfo.metaData.getString(MBMS_FILE_PROVIDER_META_DATA_KEY);
         if (authority == null) {
-            throw new RuntimeException("Must declare the file provider authority as meta data");
+            throw new RuntimeException("App must declare the file provider authority as metadata " +
+                    "in the manifest.");
         }
         return authority;
     }
@@ -493,7 +508,7 @@
     private String getMiddlewarePackageCached(Context context) {
         if (mMiddlewarePackageNameCache == null) {
             mMiddlewarePackageNameCache = MbmsUtils.getMiddlewareServiceInfo(context,
-                    MbmsDownloadManager.MBMS_DOWNLOAD_SERVICE_ACTION).packageName;
+                    MbmsDownloadSession.MBMS_DOWNLOAD_SERVICE_ACTION).packageName;
         }
         return mMiddlewarePackageNameCache;
     }
diff --git a/telephony/java/android/telephony/mbms/MbmsDownloadSessionCallback.java b/telephony/java/android/telephony/mbms/MbmsDownloadSessionCallback.java
new file mode 100644
index 0000000..77dea6f
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/MbmsDownloadSessionCallback.java
@@ -0,0 +1,66 @@
+/*
+ * 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.telephony.mbms;
+
+import android.telephony.MbmsDownloadSession;
+
+import java.util.List;
+
+/**
+ * A callback class that apps should use to receive information on file downloads over
+ * cell-broadcast.
+ */
+public class MbmsDownloadSessionCallback {
+
+    /**
+     * Indicates that the middleware has encountered an asynchronous error.
+     * @param errorCode Any error code listed in {@link MbmsErrors}
+     * @param message A message, intended for debugging purposes, describing the error in further
+     *                detail.
+     */
+    public void onError(int errorCode, String message) {
+        // default implementation empty
+    }
+
+    /**
+     * Called to indicate published File Services have changed.
+     *
+     * This will only be called after the application has requested a list of file services and
+     * specified a service class list of interest via
+     * {@link MbmsDownloadSession#requestUpdateFileServices(List)}. If there are subsequent calls to
+     * {@link MbmsDownloadSession#requestUpdateFileServices(List)},
+     * this method may not be called again if
+     * the list of service classes would remain the same.
+     *
+     * @param services The most recently updated list of available file services.
+     */
+    public void onFileServicesUpdated(List<FileServiceInfo> services) {
+        // default implementation empty
+    }
+
+    /**
+     * 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 MbmsDownloadSession} will result in an {@link IllegalStateException}
+     * being thrown or {@link #onError(int, String)} being called with error code
+     * {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}
+     */
+    public void onMiddlewareReady() {
+        // default implementation empty
+    }
+}
diff --git a/telephony/java/android/telephony/mbms/MbmsErrors.java b/telephony/java/android/telephony/mbms/MbmsErrors.java
new file mode 100644
index 0000000..af0af24
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/MbmsErrors.java
@@ -0,0 +1,134 @@
+/*
+ * 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.telephony.mbms;
+
+import android.telephony.MbmsStreamingSession;
+
+public class MbmsErrors {
+    /** Indicates that the operation was successful. */
+    public static final int SUCCESS = 0;
+
+    // Following errors are generated in the manager and should not be returned from the
+    // middleware
+    /**
+     * Indicates that either no MBMS middleware app is installed on the device or multiple
+     * middleware apps are installed on the device.
+     */
+    public static final int ERROR_NO_UNIQUE_MIDDLEWARE = 1;
+
+    /**
+     * Indicates that the app attempted to perform an operation on an instance of
+     * {@link android.telephony.MbmsDownloadSession} or
+     * {@link MbmsStreamingSession} without being bound to the middleware.
+     */
+    public static final int ERROR_MIDDLEWARE_NOT_BOUND = 2;
+
+    /** Indicates that the middleware has died and the requested operation was not completed.*/
+    public static final int ERROR_MIDDLEWARE_LOST = 3;
+
+    /**
+     * Indicates errors that may be generated during initialization by the
+     * middleware. They are applicable to both streaming and file-download use-cases.
+     */
+    public static class InitializationErrors {
+        private InitializationErrors() {}
+        /**
+         * Indicates that the app tried to create more than one instance each of
+         * {@link MbmsStreamingSession} or {@link android.telephony.MbmsDownloadSession}.
+         */
+        public static final int ERROR_DUPLICATE_INITIALIZE = 101;
+        /** Indicates that the app is not authorized to access media via MBMS.*/
+        public static final int ERROR_APP_PERMISSIONS_NOT_GRANTED = 102;
+        /** Indicates that the middleware was unable to initialize for this app. */
+        public static final int ERROR_UNABLE_TO_INITIALIZE = 103;
+    }
+
+    /**
+     * Indicates the errors that may occur at any point and are applicable to both
+     * streaming and file-download.
+     */
+    public static class GeneralErrors {
+        private GeneralErrors() {}
+        /**
+         * Indicates that the app attempted to perform an operation before receiving notification
+         * that the middleware is ready via {@link MbmsStreamingSessionCallback#onMiddlewareReady()}
+         * or {@link MbmsDownloadSessionCallback#onMiddlewareReady()}.
+         */
+        public static final int ERROR_MIDDLEWARE_NOT_YET_READY = 201;
+        /**
+         * Indicates that the middleware ran out of memory and was unable to complete the requested
+         * operation.
+         */
+        public static final int ERROR_OUT_OF_MEMORY = 202;
+        /**
+         * Indicates that the requested operation failed due to the middleware being unavailable due
+         * to a transient condition. The app may retry the operation at a later time.
+         */
+        public static final int ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE = 203;
+        /**
+         * Indicates that the requested operation was not performed due to being in emergency
+         * callback mode.
+         */
+        public static final int ERROR_IN_E911 = 204;
+        /** Indicates that MBMS is not available due to the device being in roaming. */
+        public static final int ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE = 205;
+        /** Indicates that MBMS is not available due to a SIM read error. */
+        public static final int ERROR_UNABLE_TO_READ_SIM = 206;
+        /**
+         * Indicates that MBMS is not available due to the inserted SIM being from an unsupported
+         * carrier.
+         */
+        public static final int ERROR_CARRIER_CHANGE_NOT_ALLOWED = 207;
+    }
+
+    /**
+     * Indicates the errors that are applicable only to the streaming use-case
+     */
+    public static class StreamingErrors {
+        private StreamingErrors() {}
+        /** Indicates that the middleware cannot start a stream due to too many ongoing streams */
+        public static final int ERROR_CONCURRENT_SERVICE_LIMIT_REACHED = 301;
+
+        /** Indicates that the middleware was unable to start the streaming service */
+        public static final int ERROR_UNABLE_TO_START_SERVICE = 302;
+
+        /**
+         * Indicates that the app called
+         * {@link MbmsStreamingSession#startStreaming(
+         * StreamingServiceInfo, StreamingServiceCallback, android.os.Handler)}
+         * more than once for the same {@link StreamingServiceInfo}.
+         */
+        public static final int ERROR_DUPLICATE_START_STREAM = 303;
+    }
+
+    /**
+     * Indicates the errors that are applicable only to the file-download use-case
+     */
+    public static class DownloadErrors {
+        private DownloadErrors() { }
+        /**
+         * Indicates that the app is not allowed to change the temp file root at this time due to
+         * outstanding download requests.
+         */
+        public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 401;
+
+        /** Indicates that the middleware has no record of the supplied {@link DownloadRequest}. */
+        public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402;
+    }
+
+    private MbmsErrors() {}
+}
diff --git a/telephony/java/android/telephony/mbms/MbmsException.java b/telephony/java/android/telephony/mbms/MbmsException.java
deleted file mode 100644
index 6de5a18..0000000
--- a/telephony/java/android/telephony/mbms/MbmsException.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.telephony.mbms;
-
-public class MbmsException extends Exception {
-    /** Indicates that the operation was successful. */
-    public static final int SUCCESS = 0;
-
-    // Following errors are generated in the manager and should not be returned from the
-    // middleware
-    /**
-     * Indicates that either no MBMS middleware app is installed on the device or multiple
-     * middleware apps are installed on the device.
-     */
-    public static final int ERROR_NO_UNIQUE_MIDDLEWARE = 1;
-
-    /**
-     * Indicates that the app attempted to perform an operation on an instance of
-     * TODO: link android.telephony.MbmsDownloadManager or
-     * {@link android.telephony.MbmsStreamingManager} without being bound to the middleware.
-     */
-    public static final int ERROR_MIDDLEWARE_NOT_BOUND = 2;
-
-    /** Indicates that the middleware has died and the requested operation was not completed.*/
-    public static final int ERROR_MIDDLEWARE_LOST = 3;
-
-    /**
-     * Indicates errors that may be generated during initialization by the
-     * middleware. They are applicable to both streaming and file-download use-cases.
-     */
-    public static class InitializationErrors {
-        private InitializationErrors() {}
-        /**
-         * Indicates that the app tried to create more than one instance each of
-         * {@link android.telephony.MbmsStreamingManager} or
-         * TODO: link android.telephony.MbmsDownloadManager
-         */
-        public static final int ERROR_DUPLICATE_INITIALIZE = 101;
-        /** Indicates that the app is not authorized to access media via MBMS.*/
-        public static final int ERROR_APP_PERMISSIONS_NOT_GRANTED = 102;
-        /** Indicates that the middleware was unable to initialize for this app. */
-        public static final int ERROR_UNABLE_TO_INITIALIZE = 103;
-    }
-
-    /**
-     * Indicates the errors that may occur at any point and are applicable to both
-     * streaming and file-download.
-     */
-    public static class GeneralErrors {
-        private GeneralErrors() {}
-        /**
-         * Indicates that the app attempted to perform an operation before receiving notification
-         * that the middleware is ready via {@link MbmsStreamingManagerCallback#onMiddlewareReady()}
-         * or TODO: link MbmsDownloadManagerCallback#middlewareReady
-         */
-        public static final int ERROR_MIDDLEWARE_NOT_YET_READY = 201;
-        /**
-         * Indicates that the middleware ran out of memory and was unable to complete the requested
-         * operation.
-         */
-        public static final int ERROR_OUT_OF_MEMORY = 202;
-        /**
-         * Indicates that the requested operation failed due to the middleware being unavailable due
-         * to a transient condition. The app may retry the operation at a later time.
-         */
-        public static final int ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE = 203;
-        /**
-         * Indicates that the requested operation was not performed due to being in emergency
-         * callback mode.
-         */
-        public static final int ERROR_IN_E911 = 204;
-        /** Indicates that MBMS is not available due to the device being in roaming. */
-        public static final int ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE = 205;
-        /** Indicates that MBMS is not available due to a SIM read error. */
-        public static final int ERROR_UNABLE_TO_READ_SIM = 206;
-        /**
-         * Indicates that MBMS is not available due to the inserted SIM being from an unsupported
-         * carrier.
-         */
-        public static final int ERROR_CARRIER_CHANGE_NOT_ALLOWED = 207;
-    }
-
-    /**
-     * Indicates the errors that are applicable only to the streaming use-case
-     */
-    public static class StreamingErrors {
-        private StreamingErrors() {}
-        /** Indicates that the middleware cannot start a stream due to too many ongoing streams */
-        public static final int ERROR_CONCURRENT_SERVICE_LIMIT_REACHED = 301;
-
-        /** Indicates that the middleware was unable to start the streaming service */
-        public static final int ERROR_UNABLE_TO_START_SERVICE = 302;
-
-        /**
-         * Indicates that the app called
-         * {@link android.telephony.MbmsStreamingManager#startStreaming(
-         * StreamingServiceInfo, StreamingServiceCallback, android.os.Handler)}
-         * more than once for the same {@link StreamingServiceInfo}.
-         */
-        public static final int ERROR_DUPLICATE_START_STREAM = 303;
-    }
-
-    /**
-     * Indicates the errors that are applicable only to the file-download use-case
-     * TODO: unhide
-     * @hide
-     */
-    public static class DownloadErrors {
-        /**
-         * Indicates that the app is not allowed to change the temp file root at this time due to
-         * outstanding download requests.
-         */
-        public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 401;
-
-        /** Indicates that the middleware has no record of the supplied {@link DownloadRequest}. */
-        public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402;
-    }
-
-    private final int mErrorCode;
-
-    /** @hide */
-    public MbmsException(int errorCode) {
-        super();
-        mErrorCode = errorCode;
-    }
-
-    public int getErrorCode() {
-        return mErrorCode;
-    }
-}
diff --git a/telephony/java/android/telephony/mbms/MbmsStreamingManagerCallback.java b/telephony/java/android/telephony/mbms/MbmsStreamingManagerCallback.java
deleted file mode 100644
index b31ffa7..0000000
--- a/telephony/java/android/telephony/mbms/MbmsStreamingManagerCallback.java
+++ /dev/null
@@ -1,68 +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.telephony.mbms;
-
-import android.content.Context;
-import android.os.RemoteException;
-import android.telephony.MbmsStreamingManager;
-
-import java.util.List;
-
-/**
- * A callback class that is used to receive information from the middleware on MBMS streaming
- * services. An instance of this object should be passed into
- * {@link android.telephony.MbmsStreamingManager#create(Context, MbmsStreamingManagerCallback)}.
- */
-public class MbmsStreamingManagerCallback {
-    /**
-     * Called by the middleware when it has detected an error condition. The possible error codes
-     * are listed in {@link MbmsException}.
-     * @param errorCode The error code.
-     * @param message A human-readable message generated by the middleware for debugging purposes.
-     */
-    public void onError(int errorCode, String message) {
-        // default implementation empty
-    }
-
-    /**
-     * Called to indicate published Streaming Services have changed.
-     *
-     * This will only be called after the application has requested
-     * a list of streaming services and specified a service class list
-     * of interest AND the results of a subsequent getStreamServices
-     * call with the same service class list would return different
-     * results.
-     *
-     * @param services a List of StreamingServiceInfos
-     *
-     */
-    public void onStreamingServicesUpdated(List<StreamingServiceInfo> services) {
-        // default implementation empty
-    }
-
-    /**
-     * 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 android.telephony.MbmsStreamingManager} will result in an {@link MbmsException}
-     * being thrown with error code {@link MbmsException#ERROR_MIDDLEWARE_NOT_BOUND}
-     * or {@link MbmsException.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}
-     */
-    public void onMiddlewareReady() {
-        // default implementation empty
-    }
-}
diff --git a/telephony/java/android/telephony/mbms/MbmsStreamingSessionCallback.java b/telephony/java/android/telephony/mbms/MbmsStreamingSessionCallback.java
new file mode 100644
index 0000000..5c130a0
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/MbmsStreamingSessionCallback.java
@@ -0,0 +1,68 @@
+/*
+ * 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.telephony.mbms;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.Handler;
+import android.telephony.MbmsStreamingSession;
+
+import java.util.List;
+
+/**
+ * A callback class that is used to receive information from the middleware on MBMS streaming
+ * services. An instance of this object should be passed into
+ * {@link MbmsStreamingSession#create(Context, MbmsStreamingSessionCallback, int, Handler)}.
+ */
+public class MbmsStreamingSessionCallback {
+    /**
+     * 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(int errorCode, @Nullable String message) {
+        // default implementation empty
+    }
+
+    /**
+     * Called to indicate published Streaming Services have changed.
+     *
+     * This will only be called after the application has requested
+     * a list of streaming services and specified a service class list
+     * of interest AND the results of a subsequent getStreamServices
+     * call with the same service class list would return different
+     * results.
+     *
+     * @param services The list of available services.
+     */
+    public void onStreamingServicesUpdated(List<StreamingServiceInfo> services) {
+        // default implementation empty
+    }
+
+    /**
+     * 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 MbmsStreamingSession} 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() {
+        // default implementation empty
+    }
+}
diff --git a/telephony/java/android/telephony/mbms/MbmsTempFileProvider.java b/telephony/java/android/telephony/mbms/MbmsTempFileProvider.java
index c4d033b..689becd 100644
--- a/telephony/java/android/telephony/mbms/MbmsTempFileProvider.java
+++ b/telephony/java/android/telephony/mbms/MbmsTempFileProvider.java
@@ -23,12 +23,11 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
 import android.database.Cursor;
 import android.net.Uri;
-import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
+import android.telephony.MbmsDownloadSession;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -39,7 +38,6 @@
  * @hide
  */
 public class MbmsTempFileProvider extends ContentProvider {
-    public static final String DEFAULT_TOP_LEVEL_TEMP_DIRECTORY = "androidMbmsTempFileRoot";
     public static final String TEMP_FILE_ROOT_PREF_FILE_NAME = "MbmsTempFileRootPrefs";
     public static final String TEMP_FILE_ROOT_PREF_NAME = "mbms_temp_file_root";
 
@@ -182,8 +180,8 @@
             if (storedTempFileRoot != null) {
                 return new File(storedTempFileRoot).getCanonicalFile();
             } else {
-                return new File(context.getFilesDir(), DEFAULT_TOP_LEVEL_TEMP_DIRECTORY)
-                        .getCanonicalFile();
+                return new File(context.getFilesDir(),
+                        MbmsDownloadSession.DEFAULT_TOP_LEVEL_TEMP_DIRECTORY).getCanonicalFile();
             }
         } catch (IOException e) {
             throw new RuntimeException("Unable to canonicalize temp file root path " + e);
diff --git a/telephony/java/android/telephony/mbms/MbmsUtils.java b/telephony/java/android/telephony/mbms/MbmsUtils.java
index 4b913f82..b4ad1d7 100644
--- a/telephony/java/android/telephony/mbms/MbmsUtils.java
+++ b/telephony/java/android/telephony/mbms/MbmsUtils.java
@@ -22,6 +22,8 @@
 import android.content.ServiceConnection;
 import android.content.pm.*;
 import android.content.pm.ServiceInfo;
+import android.telephony.MbmsDownloadSession;
+import android.telephony.MbmsStreamingSession;
 import android.util.Log;
 
 import java.io.File;
@@ -48,39 +50,80 @@
         return new ComponentName(ci.packageName, ci.name);
     }
 
+    private static ComponentName getOverrideServiceName(Context context, String serviceAction) {
+        String metaDataKey = null;
+        switch (serviceAction) {
+            case MbmsDownloadSession.MBMS_DOWNLOAD_SERVICE_ACTION:
+                metaDataKey = MbmsDownloadSession.MBMS_DOWNLOAD_SERVICE_OVERRIDE_METADATA;
+                break;
+            case MbmsStreamingSession.MBMS_STREAMING_SERVICE_ACTION:
+                metaDataKey = MbmsStreamingSession.MBMS_STREAMING_SERVICE_OVERRIDE_METADATA;
+                break;
+        }
+        if (metaDataKey == null) {
+            return null;
+        }
+
+        ApplicationInfo appInfo;
+        try {
+            appInfo = context.getPackageManager()
+                    .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
+        } catch (PackageManager.NameNotFoundException e) {
+            return null;
+        }
+        if (appInfo.metaData == null) {
+            return null;
+        }
+        String serviceComponent = appInfo.metaData.getString(metaDataKey);
+        if (serviceComponent == null) {
+            return null;
+        }
+        return ComponentName.unflattenFromString(serviceComponent);
+    }
+
     public static ServiceInfo getMiddlewareServiceInfo(Context context, String serviceAction) {
         // Query for the proper service
         PackageManager packageManager = context.getPackageManager();
         Intent queryIntent = new Intent();
         queryIntent.setAction(serviceAction);
-        List<ResolveInfo> downloadServices = packageManager.queryIntentServices(queryIntent,
-                PackageManager.MATCH_SYSTEM_ONLY);
 
-        if (downloadServices == null || downloadServices.size() == 0) {
-            Log.w(LOG_TAG, "No download services found, cannot get service info");
+        ComponentName overrideService = getOverrideServiceName(context, serviceAction);
+        List<ResolveInfo> services;
+        if (overrideService == null) {
+            services = packageManager.queryIntentServices(queryIntent,
+                    PackageManager.MATCH_SYSTEM_ONLY);
+        } else {
+            queryIntent.setComponent(overrideService);
+            services = packageManager.queryIntentServices(queryIntent,
+                    PackageManager.MATCH_ALL);
+        }
+
+        if (services == null || services.size() == 0) {
+            Log.w(LOG_TAG, "No MBMS services found, cannot get service info");
             return null;
         }
 
-        if (downloadServices.size() > 1) {
-            Log.w(LOG_TAG, "More than one download service found, cannot get unique service");
+        if (services.size() > 1) {
+            Log.w(LOG_TAG, "More than one MBMS service found, cannot get unique service");
             return null;
         }
-        return downloadServices.get(0).serviceInfo;
+        return services.get(0).serviceInfo;
     }
 
-    public static void startBinding(Context context, String serviceAction,
-            ServiceConnection serviceConnection) throws MbmsException {
+    public static int startBinding(Context context, String serviceAction,
+            ServiceConnection serviceConnection) {
         Intent bindIntent = new Intent();
         ServiceInfo mbmsServiceInfo =
                 MbmsUtils.getMiddlewareServiceInfo(context, serviceAction);
 
         if (mbmsServiceInfo == null) {
-            throw new MbmsException(MbmsException.ERROR_NO_UNIQUE_MIDDLEWARE);
+            return MbmsErrors.ERROR_NO_UNIQUE_MIDDLEWARE;
         }
 
         bindIntent.setComponent(MbmsUtils.toComponentName(mbmsServiceInfo));
 
         context.bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
+        return MbmsErrors.SUCCESS;
     }
 
     /**
diff --git a/telephony/java/android/telephony/mbms/ServiceInfo.java b/telephony/java/android/telephony/mbms/ServiceInfo.java
index c01604b..8529f52 100644
--- a/telephony/java/android/telephony/mbms/ServiceInfo.java
+++ b/telephony/java/android/telephony/mbms/ServiceInfo.java
@@ -16,22 +16,26 @@
 
 package android.telephony.mbms;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.Set;
 
 /**
  * Describes a cell-broadcast service. This class should not be instantiated directly -- use
- * {@link StreamingServiceInfo} or FileServiceInfo TODO: add link once that's unhidden
+ * {@link StreamingServiceInfo} or {@link FileServiceInfo}
  */
 public class ServiceInfo {
     // arbitrary limit on the number of locale -> name pairs we support
@@ -58,6 +62,7 @@
         if (newLocales.size() > MAP_LIMIT) {
             throw new RuntimeException("bad locales length " + newLocales.size());
         }
+
         names = new HashMap(newNames.size());
         names.putAll(newNames);
         className = newClassName;
@@ -114,16 +119,36 @@
     }
 
     /**
-     * User displayable names listed by language. Do not modify the map returned from this method.
+     * Get the user-displayable name for this cell-broadcast service corresponding to the
+     * provided {@link Locale}.
+     * @param locale The {@link Locale} in which you want the name of the service. This must be a
+     *               value from the set returned by {@link #getNamedContentLocales()} -- an
+     *               {@link java.util.NoSuchElementException} may be thrown otherwise.
+     * @return The {@link CharSequence} providing the name of the service in the given
+     *         {@link Locale}
      */
-    public Map<Locale, String> getNames() {
-        return names;
+    public @NonNull CharSequence getNameForLocale(@NonNull Locale locale) {
+        if (!names.containsKey(locale)) {
+            throw new NoSuchElementException("Locale not supported");
+        }
+        return names.get(locale);
+    }
+
+    /**
+     * Return an unmodifiable set of the current {@link Locale}s that have a user-displayable name
+     * associated with them. The user-displayable name associated with any {@link Locale} in this
+     * set can be retrieved with {@link #getNameForLocale(Locale)}.
+     * @return An unmodifiable set of {@link Locale} objects corresponding to a user-displayable
+     * content name in that locale.
+     */
+    public @NonNull Set<Locale> getNamedContentLocales() {
+        return Collections.unmodifiableSet(names.keySet());
     }
 
     /**
      * The class name for this service - used to categorize and filter
      */
-    public String getClassName() {
+    public String getServiceClassName() {
         return className;
     }
 
diff --git a/telephony/java/android/telephony/mbms/StreamingService.java b/telephony/java/android/telephony/mbms/StreamingService.java
index 1d66bac..ec9134a 100644
--- a/telephony/java/android/telephony/mbms/StreamingService.java
+++ b/telephony/java/android/telephony/mbms/StreamingService.java
@@ -17,8 +17,10 @@
 package android.telephony.mbms;
 
 import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.net.Uri;
 import android.os.RemoteException;
+import android.telephony.MbmsStreamingSession;
 import android.telephony.mbms.vendor.IMbmsStreamingService;
 import android.util.Log;
 
@@ -27,7 +29,7 @@
 
 /**
  * Class used to represent a single MBMS stream. After a stream has been started with
- * {@link android.telephony.MbmsStreamingManager#startStreaming(StreamingServiceInfo,
+ * {@link MbmsStreamingSession#startStreaming(StreamingServiceInfo,
  * StreamingServiceCallback, android.os.Handler)},
  * this class is used to hold information about the stream and control it.
  */
@@ -63,7 +65,7 @@
 
     /**
      * State changed due to a call to {@link #stopStreaming()} or
-     * {@link android.telephony.MbmsStreamingManager#startStreaming(StreamingServiceInfo,
+     * {@link MbmsStreamingSession#startStreaming(StreamingServiceInfo,
      * StreamingServiceCallback, android.os.Handler)}
      */
     public static final int REASON_BY_USER_REQUEST = 1;
@@ -101,6 +103,7 @@
     public final static int UNICAST_METHOD   = 2;
 
     private final int mSubscriptionId;
+    private final MbmsStreamingSession mParentSession;
     private final StreamingServiceInfo mServiceInfo;
     private final InternalStreamingServiceCallback mCallback;
 
@@ -111,25 +114,25 @@
      */
     public StreamingService(int subscriptionId,
             IMbmsStreamingService service,
+            MbmsStreamingSession session,
             StreamingServiceInfo streamingServiceInfo,
             InternalStreamingServiceCallback callback) {
         mSubscriptionId = subscriptionId;
+        mParentSession = session;
         mService = service;
         mServiceInfo = streamingServiceInfo;
         mCallback = callback;
     }
 
     /**
-     * Retreive the Uri used to play this stream.
+     * Retrieve the Uri used to play this stream.
      *
-     * This may throw a {@link MbmsException} with the error code
-     * {@link MbmsException#ERROR_MIDDLEWARE_LOST}
+     * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}.
      *
-     * May also throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
-     *
-     * @return The {@link Uri} to pass to the streaming client.
+     * @return The {@link Uri} to pass to the streaming client, or {@code null} if an error
+     *         occurred.
      */
-    public Uri getPlaybackUri() throws MbmsException {
+    public @Nullable Uri getPlaybackUri() {
         if (mService == null) {
             throw new IllegalStateException("No streaming service attached");
         }
@@ -139,25 +142,26 @@
         } catch (RemoteException e) {
             Log.w(LOG_TAG, "Remote process died");
             mService = null;
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_LOST);
+            mParentSession.onStreamingServiceStopped(this);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+            return null;
         }
     }
 
     /**
-     * Retreive the info for this StreamingService.
+     * Retrieve the {@link StreamingServiceInfo} corresponding to this stream.
      */
     public StreamingServiceInfo getInfo() {
         return mServiceInfo;
     }
 
     /**
-     * Stop streaming this service.
-     * This may throw a {@link MbmsException} with the error code
-     * {@link MbmsException#ERROR_MIDDLEWARE_LOST}
+     * Stop streaming this service. Further operations on this object will fail with an
+     * {@link IllegalStateException}.
      *
-     * May also throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
+     * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
      */
-    public void stopStreaming() throws MbmsException {
+    public void stopStreaming() {
         if (mService == null) {
             throw new IllegalStateException("No streaming service attached");
         }
@@ -167,32 +171,22 @@
         } catch (RemoteException e) {
             Log.w(LOG_TAG, "Remote process died");
             mService = null;
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_LOST);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+        } finally {
+            mParentSession.onStreamingServiceStopped(this);
         }
     }
 
-    /**
-     * Disposes of this stream. Further operations on this object will fail with an
-     * {@link IllegalStateException}.
-     *
-     * This may throw a {@link MbmsException} with the error code
-     * {@link MbmsException#ERROR_MIDDLEWARE_LOST}
-     * May also throw an {@link IllegalStateException}
-     */
-    public void dispose() throws MbmsException {
-        if (mService == null) {
-            throw new IllegalStateException("No streaming service attached");
-        }
+    /** @hide */
+    public InternalStreamingServiceCallback getCallback() {
+        return mCallback;
+    }
 
+    private void sendErrorToApp(int errorCode, String message) {
         try {
-            mService.disposeStream(mSubscriptionId, mServiceInfo.getServiceId());
+            mCallback.onError(errorCode, message);
         } catch (RemoteException e) {
-            Log.w(LOG_TAG, "Remote process died");
-            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_LOST);
-        } catch (IllegalArgumentException e) {
-            throw new IllegalStateException("StreamingService state inconsistent with middleware");
-        } finally {
-            mService = null;
+            // Ignore, should not happen locally.
         }
     }
 }
diff --git a/telephony/java/android/telephony/mbms/StreamingServiceCallback.java b/telephony/java/android/telephony/mbms/StreamingServiceCallback.java
index b72c715..0903824 100644
--- a/telephony/java/android/telephony/mbms/StreamingServiceCallback.java
+++ b/telephony/java/android/telephony/mbms/StreamingServiceCallback.java
@@ -16,6 +16,8 @@
 
 package android.telephony.mbms;
 
+import android.annotation.Nullable;
+
 /**
  * A callback class for use when the application is actively streaming content. The middleware
  * will provide updates on the status of the stream via this callback.
@@ -33,11 +35,11 @@
 
     /**
      * Called by the middleware when it has detected an error condition in this stream. The
-     * possible error codes are listed in {@link MbmsException}.
+     * 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(int errorCode, String message) {
+    public void onError(int errorCode, @Nullable String message) {
         // default implementation empty
     }
 
diff --git a/telephony/java/android/telephony/mbms/StreamingServiceInfo.java b/telephony/java/android/telephony/mbms/StreamingServiceInfo.java
index c704f34..ef2a14a 100644
--- a/telephony/java/android/telephony/mbms/StreamingServiceInfo.java
+++ b/telephony/java/android/telephony/mbms/StreamingServiceInfo.java
@@ -17,6 +17,7 @@
 package android.telephony.mbms;
 
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -41,6 +42,7 @@
      * @hide
      */
     @SystemApi
+    @TestApi
     public StreamingServiceInfo(Map<Locale, String> names, String className,
             List<Locale> locales, String serviceId, Date start, Date end) {
         super(names, className, locales, serviceId, start, end);
diff --git a/telephony/java/android/telephony/mbms/UriPathPair.java b/telephony/java/android/telephony/mbms/UriPathPair.java
index 7acc270..dd20a69 100644
--- a/telephony/java/android/telephony/mbms/UriPathPair.java
+++ b/telephony/java/android/telephony/mbms/UriPathPair.java
@@ -16,13 +16,22 @@
 
 package android.telephony.mbms;
 
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.content.ContentResolver;
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.telephony.mbms.vendor.VendorUtils;
 
-/** @hide */
-public class UriPathPair implements Parcelable {
+/**
+ * Wrapper for a pair of {@link Uri}s that describe a temp file used by the middleware to
+ * download files via cell-broadcast.
+ * @hide
+ */
+@SystemApi
+@TestApi
+public final class UriPathPair implements Parcelable {
     private final Uri mFilePathUri;
     private final Uri mContentUri;
 
@@ -40,7 +49,7 @@
     }
 
     /** @hide */
-    protected UriPathPair(Parcel in) {
+    private UriPathPair(Parcel in) {
         mFilePathUri = in.readParcelable(Uri.class.getClassLoader());
         mContentUri = in.readParcelable(Uri.class.getClassLoader());
     }
@@ -57,12 +66,23 @@
         }
     };
 
-    /** future systemapi */
+    /**
+     * Returns the file-path {@link Uri}. This has scheme {@code file} and points to the actual
+     * location on disk where the temp file resides. Use this when sending {@link Uri}s back to the
+     * app in the intents in {@link VendorUtils}.
+     * @return A {@code file} {@link Uri}.
+     */
     public Uri getFilePathUri() {
         return mFilePathUri;
     }
 
-    /** future systemapi */
+    /**
+     * Returns the content {@link Uri} that may be used with
+     * {@link ContentResolver#openFileDescriptor(Uri, String)} to obtain a
+     * {@link android.os.ParcelFileDescriptor} to a temp file to write to. This {@link Uri} will
+     * expire if the middleware process dies.
+     * @return A {@code content} {@link Uri}
+     */
     public Uri getContentUri() {
         return mContentUri;
     }
diff --git a/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl b/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl
index dfcc5f7..cb93542 100755
--- a/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl
+++ b/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl
@@ -20,21 +20,27 @@
 import android.net.Uri;
 import android.telephony.mbms.DownloadRequest;
 import android.telephony.mbms.FileInfo;
-import android.telephony.mbms.IMbmsDownloadManagerCallback;
-import android.telephony.mbms.IDownloadProgressListener;
+import android.telephony.mbms.IMbmsDownloadSessionCallback;
+import android.telephony.mbms.IDownloadStateCallback;
 
 /**
  * @hide
  */
 interface IMbmsDownloadService
 {
-    int initialize(int subId, IMbmsDownloadManagerCallback listener);
+    int initialize(int subId, IMbmsDownloadSessionCallback listener);
 
-    int getFileServices(int subId, in List<String> serviceClasses);
+    int requestUpdateFileServices(int subId, in List<String> serviceClasses);
 
     int setTempFileRootDirectory(int subId, String rootDirectoryPath);
 
-    int download(in DownloadRequest downloadRequest, IDownloadProgressListener listener);
+    int download(in DownloadRequest downloadRequest);
+
+    int registerStateCallback(in DownloadRequest downloadRequest, IDownloadStateCallback listener,
+        int flags);
+
+    int unregisterStateCallback(in DownloadRequest downloadRequest,
+        IDownloadStateCallback listener);
 
     List<DownloadRequest> listPendingDownloads(int subscriptionId);
 
diff --git a/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl b/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl
index 4dd4292..c90ffc7 100755
--- a/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl
+++ b/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl
@@ -17,7 +17,7 @@
 package android.telephony.mbms.vendor;
 
 import android.net.Uri;
-import android.telephony.mbms.IMbmsStreamingManagerCallback;
+import android.telephony.mbms.IMbmsStreamingSessionCallback;
 import android.telephony.mbms.IStreamingServiceCallback;
 import android.telephony.mbms.StreamingServiceInfo;
 
@@ -26,18 +26,16 @@
  */
 interface IMbmsStreamingService
 {
-    int initialize(IMbmsStreamingManagerCallback listener, int subId);
+    int initialize(IMbmsStreamingSessionCallback callback, int subId);
 
-    int getStreamingServices(int subId, in List<String> serviceClasses);
+    int requestUpdateStreamingServices(int subId, in List<String> serviceClasses);
 
     int startStreaming(int subId, String serviceId,
-            IStreamingServiceCallback listener);
+            IStreamingServiceCallback callback);
 
     Uri getPlaybackUri(int subId, String serviceId);
 
     void stopStreaming(int subId, String serviceId);
 
-    void disposeStream(int subId, String serviceId);
-
     void dispose(int subId);
 }
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
index 71713d0..4fee3df 100644
--- a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
@@ -17,40 +17,93 @@
 package android.telephony.mbms.vendor;
 
 import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
 import android.os.RemoteException;
-import android.telephony.mbms.DownloadProgressListener;
+import android.telephony.MbmsDownloadSession;
 import android.telephony.mbms.DownloadRequest;
+import android.telephony.mbms.DownloadStateCallback;
 import android.telephony.mbms.FileInfo;
 import android.telephony.mbms.FileServiceInfo;
-import android.telephony.mbms.IDownloadProgressListener;
-import android.telephony.mbms.IMbmsDownloadManagerCallback;
-import android.telephony.mbms.MbmsDownloadManagerCallback;
-import android.telephony.mbms.MbmsException;
+import android.telephony.mbms.IDownloadStateCallback;
+import android.telephony.mbms.IMbmsDownloadSessionCallback;
+import android.telephony.mbms.MbmsDownloadSessionCallback;
+import android.telephony.mbms.MbmsErrors;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
- * Base class for MbmsDownloadService. The middleware should extend this base class rather than
- * the aidl stub for compatibility
+ * Base class for MbmsDownloadService. The middleware should return an instance of this object from
+ * its {@link android.app.Service#onBind(Intent)} method.
  * @hide
- * TODO: future systemapi
  */
+@SystemApi
+@TestApi
 public class MbmsDownloadServiceBase extends IMbmsDownloadService.Stub {
+    private final Map<IBinder, DownloadStateCallback> mDownloadCallbackBinderMap = new HashMap<>();
+    private final Map<IBinder, DeathRecipient> mDownloadCallbackDeathRecipients = new HashMap<>();
+
+
+    // Filters the DownloadStateCallbacks by its configuration from the app.
+    private abstract static class FilteredDownloadStateCallback extends DownloadStateCallback {
+
+        private final IDownloadStateCallback mCallback;
+        public FilteredDownloadStateCallback(IDownloadStateCallback callback, int callbackFlags) {
+            super(callbackFlags);
+            mCallback = callback;
+        }
+
+        @Override
+        public void onProgressUpdated(DownloadRequest request, FileInfo fileInfo,
+                int currentDownloadSize, int fullDownloadSize, int currentDecodedSize,
+                int fullDecodedSize) {
+            if (!isFilterFlagSet(PROGRESS_UPDATES)) {
+                return;
+            }
+            try {
+                mCallback.onProgressUpdated(request, fileInfo, currentDownloadSize,
+                        fullDownloadSize, currentDecodedSize, fullDecodedSize);
+            } catch (RemoteException e) {
+                onRemoteException(e);
+            }
+        }
+
+        @Override
+        public void onStateUpdated(DownloadRequest request, FileInfo fileInfo,
+                @MbmsDownloadSession.DownloadStatus int state) {
+            if (!isFilterFlagSet(STATE_UPDATES)) {
+                return;
+            }
+            try {
+                mCallback.onStateUpdated(request, fileInfo, state);
+            } catch (RemoteException e) {
+                onRemoteException(e);
+            }
+        }
+
+        protected abstract void onRemoteException(RemoteException e);
+    }
+
     /**
      * Initialize the download service for this app and subId, registering the listener.
      *
      * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}, which
      * will be intercepted and passed to the app as
-     * {@link android.telephony.mbms.MbmsException.InitializationErrors#ERROR_UNABLE_TO_INITIALIZE}
+     * {@link MbmsErrors.InitializationErrors#ERROR_UNABLE_TO_INITIALIZE}
      *
-     * May return any value from {@link android.telephony.mbms.MbmsException.InitializationErrors}
-     * or {@link MbmsException#SUCCESS}. Non-successful error codes will be passed to the app via
-     * {@link IMbmsDownloadManagerCallback#error(int, String)}.
+     * May return any value from {@link MbmsErrors.InitializationErrors}
+     * or {@link MbmsErrors#SUCCESS}. Non-successful error codes will be passed to the app via
+     * {@link IMbmsDownloadSessionCallback#onError(int, String)}.
      *
      * @param callback The callback to use to communicate with the app.
      * @param subscriptionId The subscription ID to use.
      */
-    public int initialize(int subscriptionId, MbmsDownloadManagerCallback callback)
+    public int initialize(int subscriptionId, MbmsDownloadSessionCallback callback)
             throws RemoteException {
         return 0;
     }
@@ -60,30 +113,59 @@
      * @hide
      */
     @Override
-    public final int initialize(int subscriptionId,
-            final IMbmsDownloadManagerCallback callback) throws RemoteException {
-        return initialize(subscriptionId, new MbmsDownloadManagerCallback() {
+    public final int initialize(final int subscriptionId,
+            final IMbmsDownloadSessionCallback callback) throws RemoteException {
+        if (callback == null) {
+            throw new NullPointerException("Callback must not be null");
+        }
+
+        final int uid = Binder.getCallingUid();
+
+        int result = initialize(subscriptionId, new MbmsDownloadSessionCallback() {
             @Override
-            public void error(int errorCode, String message) throws RemoteException {
-                callback.error(errorCode, message);
+            public void onError(int errorCode, String message) {
+                try {
+                    callback.onError(errorCode, message);
+                } catch (RemoteException e) {
+                    onAppCallbackDied(uid, subscriptionId);
+                }
             }
 
             @Override
-            public void fileServicesUpdated(List<FileServiceInfo> services) throws RemoteException {
-                callback.fileServicesUpdated(services);
+            public void onFileServicesUpdated(List<FileServiceInfo> services) {
+                try {
+                    callback.onFileServicesUpdated(services);
+                } catch (RemoteException e) {
+                    onAppCallbackDied(uid, subscriptionId);
+                }
             }
 
             @Override
-            public void middlewareReady() throws RemoteException {
-                callback.middlewareReady();
+            public void onMiddlewareReady() {
+                try {
+                    callback.onMiddlewareReady();
+                } 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;
     }
 
     /**
      * Registers serviceClasses of interest with the appName/subId key.
      * Starts async fetching data on streaming services of matching classes to be reported
-     * later via {@link IMbmsDownloadManagerCallback#fileServicesUpdated(List)}
+     * later via {@link IMbmsDownloadSessionCallback#onFileServicesUpdated(List)}
      *
      * Note that subsequent calls with the same uid and subId will replace
      * the service class list.
@@ -94,11 +176,11 @@
      * @param serviceClasses The service classes that the app wishes to get info on. The strings
      *                       may contain arbitrary data as negotiated between the app and the
      *                       carrier.
-     * @return One of {@link MbmsException#SUCCESS} or
-     *         {@link MbmsException.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY},
+     * @return One of {@link MbmsErrors#SUCCESS} or
+     *         {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY},
      */
     @Override
-    public int getFileServices(int subscriptionId, List<String> serviceClasses)
+    public int requestUpdateFileServices(int subscriptionId, List<String> serviceClasses)
             throws RemoteException {
         return 0;
     }
@@ -110,13 +192,13 @@
      *
      * If the calling app (as identified by the calling UID) currently has any pending download
      * requests that have not been canceled, the middleware must return
-     * {@link MbmsException.DownloadErrors#ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT} here.
+     * {@link MbmsErrors.DownloadErrors#ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT} here.
      *
      * @param subscriptionId The subscription id the download is operating under.
      * @param rootDirectoryPath The path to the app's temp file root directory.
-     * @return {@link MbmsException#SUCCESS},
-     *         {@link MbmsException.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY} or
-     *         {@link MbmsException.DownloadErrors#ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT}
+     * @return {@link MbmsErrors#SUCCESS},
+     *         {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY} or
+     *         {@link MbmsErrors.DownloadErrors#ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT}
      */
     @Override
     public int setTempFileRootDirectory(int subscriptionId,
@@ -132,12 +214,32 @@
      * this is not the case, an {@link IllegalStateException} may be thrown.
      *
      * @param downloadRequest An object describing the set of files to be downloaded.
-     * @param listener A listener through which the middleware can provide progress updates to
-     *                 the app while both are still running.
-     * @return Any error from {@link android.telephony.mbms.MbmsException.GeneralErrors}
-     *         or {@link MbmsException#SUCCESS}
+     * @return Any error from {@link MbmsErrors.GeneralErrors}
+     *         or {@link MbmsErrors#SUCCESS}
      */
-    public int download(DownloadRequest downloadRequest, DownloadProgressListener listener) {
+    @Override
+    public int download(DownloadRequest downloadRequest) throws RemoteException {
+        return 0;
+    }
+
+    /**
+     * Registers a download state callbacks for the provided {@link DownloadRequest}.
+     *
+     * This method is called by the app when it wants to request updates on the progress or
+     * status of the download.
+     *
+     * If the middleware is not aware of a download having been requested with the provided
+     *
+     * {@link DownloadRequest} in the past,
+     * {@link MbmsErrors.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST}
+     * must be returned.
+     *
+     * @param downloadRequest The {@link DownloadRequest} that was used to initiate the download
+     *                        for which progress updates are being requested.
+     * @param callback The callback object to use.
+     */
+    public int registerStateCallback(DownloadRequest downloadRequest,
+            DownloadStateCallback callback) throws RemoteException {
         return 0;
     }
 
@@ -146,24 +248,99 @@
      * @hide
      */
     @Override
-    public final int download(DownloadRequest downloadRequest, IDownloadProgressListener listener)
-            throws RemoteException {
-        return download(downloadRequest, new DownloadProgressListener() {
+    public final int registerStateCallback(final DownloadRequest downloadRequest,
+            final IDownloadStateCallback callback, int flags) throws RemoteException {
+        final int uid = Binder.getCallingUid();
+        if (downloadRequest == null) {
+            throw new NullPointerException("Download request must not be null");
+        }
+        if (callback == null) {
+            throw new NullPointerException("Callback must not be null");
+        }
+
+        DownloadStateCallback exposedCallback = new FilteredDownloadStateCallback(callback, flags) {
             @Override
-            public void progress(DownloadRequest request, FileInfo fileInfo, int
-                    currentDownloadSize, int fullDownloadSize, int currentDecodedSize, int
-                    fullDecodedSize) throws RemoteException {
-                listener.progress(request, fileInfo, currentDownloadSize, fullDownloadSize,
-                        currentDecodedSize, fullDecodedSize);
+            protected void onRemoteException(RemoteException e) {
+                onAppCallbackDied(uid, downloadRequest.getSubscriptionId());
             }
-        });
+        };
+
+        int result = registerStateCallback(downloadRequest, exposedCallback);
+
+        if (result == MbmsErrors.SUCCESS) {
+            DeathRecipient deathRecipient = new DeathRecipient() {
+                @Override
+                public void binderDied() {
+                    onAppCallbackDied(uid, downloadRequest.getSubscriptionId());
+                    mDownloadCallbackBinderMap.remove(callback.asBinder());
+                    mDownloadCallbackDeathRecipients.remove(callback.asBinder());
+                }
+            };
+            mDownloadCallbackDeathRecipients.put(callback.asBinder(), deathRecipient);
+            callback.asBinder().linkToDeath(deathRecipient, 0);
+            mDownloadCallbackBinderMap.put(callback.asBinder(), exposedCallback);
+        }
+
+        return result;
     }
 
+    /**
+     * Un-registers a download state callbacks for the provided {@link DownloadRequest}.
+     *
+     * This method is called by the app when it no longer wants to request updates on the
+     * download.
+     *
+     * If the middleware is not aware of a download having been requested with the provided
+     * {@link DownloadRequest} in the past,
+     * {@link MbmsErrors.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST}
+     * must be returned.
+     *
+     * @param downloadRequest The {@link DownloadRequest} that was used to register the callback
+     * @param callback The callback object that
+     *                 {@link #registerStateCallback(DownloadRequest, DownloadStateCallback)}
+     *                 was called with.
+     */
+    public int unregisterStateCallback(DownloadRequest downloadRequest,
+            DownloadStateCallback callback) throws RemoteException {
+        return 0;
+    }
+
+    /**
+     * Actual AIDL implementation -- hides the callback AIDL from the API.
+     * @hide
+     */
+    @Override
+    public final int unregisterStateCallback(
+            final DownloadRequest downloadRequest, final IDownloadStateCallback callback)
+            throws RemoteException {
+        if (downloadRequest == null) {
+            throw new NullPointerException("Download request must not be null");
+        }
+        if (callback == null) {
+            throw new NullPointerException("Callback must not be null");
+        }
+
+        DeathRecipient deathRecipient =
+                mDownloadCallbackDeathRecipients.remove(callback.asBinder());
+        if (deathRecipient == null) {
+            throw new IllegalArgumentException("Unknown callback");
+        }
+
+        callback.asBinder().unlinkToDeath(deathRecipient, 0);
+
+        DownloadStateCallback exposedCallback =
+                mDownloadCallbackBinderMap.remove(callback.asBinder());
+        if (exposedCallback == null) {
+            throw new IllegalArgumentException("Unknown callback");
+        }
+
+        return unregisterStateCallback(downloadRequest, exposedCallback);
+    }
 
     /**
      * Returns a list of pending {@link DownloadRequest}s that originated from the calling
      * application, identified by its uid. A pending request is one that was issued via
-     * {@link #download(DownloadRequest, IDownloadProgressListener)} but not cancelled through
+     * {@link #download(DownloadRequest)} but not cancelled through
      * {@link #cancelDownload(DownloadRequest)}.
      * The middleware must return a non-null result synchronously or throw an exception
      * inheriting from {@link RuntimeException}.
@@ -179,13 +356,13 @@
      * Issues a request to cancel the specified download request.
      *
      * If the middleware is unable to cancel the request for whatever reason, it should return
-     * synchronously with an error. If this method returns {@link MbmsException#SUCCESS}, the app
+     * synchronously with an error. If this method returns {@link MbmsErrors#SUCCESS}, the app
      * will no longer be expecting any more file-completed intents from the middleware for this
      * {@link DownloadRequest}.
      * @param downloadRequest The request to cancel
-     * @return {@link MbmsException#SUCCESS},
-     *         {@link MbmsException.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST},
-     *         {@link MbmsException.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}
+     * @return {@link MbmsErrors#SUCCESS},
+     *         {@link MbmsErrors.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST},
+     *         {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}
      */
     @Override
     public int cancelDownload(DownloadRequest downloadRequest) throws RemoteException {
@@ -197,7 +374,7 @@
      *
      * If the middleware has not yet been properly initialized or if it has no records of the
      * file indicated by {@code fileInfo} being associated with {@code downloadRequest},
-     * {@link android.telephony.MbmsDownloadManager#STATUS_UNKNOWN} must be returned.
+     * {@link MbmsDownloadSession#STATUS_UNKNOWN} must be returned.
      *
      * @param downloadRequest The download request to query.
      * @param fileInfo The particular file within the request to get information on.
@@ -217,7 +394,7 @@
      * In addition, current in-progress downloads must not be interrupted.
      *
      * If the middleware is not aware of the specified download request, return
-     * {@link MbmsException.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST}.
+     * {@link MbmsErrors.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST}.
      *
      * @param downloadRequest The request to re-download files for.
      */
@@ -231,7 +408,7 @@
      * 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(int, IMbmsDownloadManagerCallback)} should no longer be used
+     * {@link #initialize(int, IMbmsDownloadSessionCallback)} should no longer be used
      * after this method has been called by the app.
      *
      * Any download requests issued by the app should remain in effect until the app calls
@@ -244,4 +421,12 @@
     @Override
     public void dispose(int subscriptionId) throws RemoteException {
     }
+
+    /**
+     * 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) {
+    }
 }
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
index 843e048..db177c0 100644
--- a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
@@ -18,13 +18,15 @@
 
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.content.Intent;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.RemoteException;
-import android.telephony.mbms.IMbmsStreamingManagerCallback;
+import android.telephony.mbms.IMbmsStreamingSessionCallback;
 import android.telephony.mbms.IStreamingServiceCallback;
-import android.telephony.mbms.MbmsException;
-import android.telephony.mbms.MbmsStreamingManagerCallback;
+import android.telephony.mbms.MbmsErrors;
+import android.telephony.mbms.MbmsStreamingSessionCallback;
 import android.telephony.mbms.StreamingService;
 import android.telephony.mbms.StreamingServiceCallback;
 import android.telephony.mbms.StreamingServiceInfo;
@@ -32,25 +34,28 @@
 import java.util.List;
 
 /**
+ * Base class for MBMS streaming services. The middleware should return an instance of this
+ * object from its {@link android.app.Service#onBind(Intent)} method.
  * @hide
  */
 @SystemApi
+@TestApi
 public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub {
     /**
      * Initialize streaming service for this app and subId, registering the listener.
      *
      * May throw an {@link IllegalArgumentException} or a {@link SecurityException}, which
      * will be intercepted and passed to the app as
-     * {@link android.telephony.mbms.MbmsException.InitializationErrors#ERROR_UNABLE_TO_INITIALIZE}
+     * {@link MbmsErrors.InitializationErrors#ERROR_UNABLE_TO_INITIALIZE}
      *
-     * May return any value from {@link android.telephony.mbms.MbmsException.InitializationErrors}
-     * or {@link MbmsException#SUCCESS}. Non-successful error codes will be passed to the app via
-     * {@link IMbmsStreamingManagerCallback#error(int, String)}.
+     * May return any value from {@link MbmsErrors.InitializationErrors}
+     * or {@link MbmsErrors#SUCCESS}. Non-successful error codes will be passed to the app via
+     * {@link IMbmsStreamingSessionCallback#onError(int, String)}.
      *
      * @param callback The callback to use to communicate with the app.
      * @param subscriptionId The subscription ID to use.
      */
-    public int initialize(MbmsStreamingManagerCallback callback, int subscriptionId)
+    public int initialize(MbmsStreamingSessionCallback callback, int subscriptionId)
             throws RemoteException {
         return 0;
     }
@@ -60,30 +65,28 @@
      * @hide
      */
     @Override
-    public final int initialize(final IMbmsStreamingManagerCallback callback,
+    public final int initialize(final IMbmsStreamingSessionCallback callback,
             final int subscriptionId) throws RemoteException {
-        final int uid = Binder.getCallingUid();
-        callback.asBinder().linkToDeath(new DeathRecipient() {
-            @Override
-            public void binderDied() {
-                onAppCallbackDied(uid, subscriptionId);
-            }
-        }, 0);
+        if (callback == null) {
+            throw new NullPointerException("Callback must not be null");
+        }
 
-        return initialize(new MbmsStreamingManagerCallback() {
+        final int uid = Binder.getCallingUid();
+
+        int result = initialize(new MbmsStreamingSessionCallback() {
             @Override
-            public void onError(int errorCode, String message) {
+            public void onError(final int errorCode, final String message) {
                 try {
-                    callback.error(errorCode, message);
+                    callback.onError(errorCode, message);
                 } catch (RemoteException e) {
                     onAppCallbackDied(uid, subscriptionId);
                 }
             }
 
             @Override
-            public void onStreamingServicesUpdated(List<StreamingServiceInfo> services) {
+            public void onStreamingServicesUpdated(final List<StreamingServiceInfo> services) {
                 try {
-                    callback.streamingServicesUpdated(services);
+                    callback.onStreamingServicesUpdated(services);
                 } catch (RemoteException e) {
                     onAppCallbackDied(uid, subscriptionId);
                 }
@@ -92,19 +95,30 @@
             @Override
             public void onMiddlewareReady() {
                 try {
-                    callback.middlewareReady();
+                    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;
     }
 
 
     /**
      * Registers serviceClasses of interest with the appName/subId key.
      * Starts async fetching data on streaming services of matching classes to be reported
-     * later via {@link IMbmsStreamingManagerCallback#streamingServicesUpdated(List)}
+     * later via {@link IMbmsStreamingSessionCallback#onStreamingServicesUpdated(List)}
      *
      * Note that subsequent calls with the same uid and subId will replace
      * the service class list.
@@ -115,11 +129,11 @@
      * @param serviceClasses The service classes that the app wishes to get info on. The strings
      *                       may contain arbitrary data as negotiated between the app and the
      *                       carrier.
-     * @return {@link MbmsException#SUCCESS} or any of the errors in
-     * {@link android.telephony.mbms.MbmsException.GeneralErrors}
+     * @return {@link MbmsErrors#SUCCESS} or any of the errors in
+     * {@link MbmsErrors.GeneralErrors}
      */
     @Override
-    public int getStreamingServices(int subscriptionId,
+    public int requestUpdateStreamingServices(int subscriptionId,
             List<String> serviceClasses) throws RemoteException {
         return 0;
     }
@@ -127,14 +141,14 @@
     /**
      * Starts streaming on a particular service. This method may perform asynchronous work. When
      * the middleware is ready to send bits to the frontend, it should inform the app via
-     * {@link IStreamingServiceCallback#streamStateUpdated(int, int)}.
+     * {@link IStreamingServiceCallback#onStreamStateUpdated(int, int)}.
      *
      * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
      *
      * @param subscriptionId The subscription id to use.
      * @param serviceId The ID of the streaming service that the app has requested.
      * @param callback The callback object on which the app wishes to receive updates.
-     * @return Any error in {@link android.telephony.mbms.MbmsException.GeneralErrors}
+     * @return Any error in {@link MbmsErrors.GeneralErrors}
      */
     public int startStreaming(int subscriptionId, String serviceId,
             StreamingServiceCallback callback) throws RemoteException {
@@ -147,31 +161,29 @@
      * @hide
      */
     @Override
-    public int startStreaming(int subscriptionId, String serviceId,
-            IStreamingServiceCallback callback) throws RemoteException {
-        final int uid = Binder.getCallingUid();
-        callback.asBinder().linkToDeath(new DeathRecipient() {
-            @Override
-            public void binderDied() {
-                onAppCallbackDied(uid, subscriptionId);
-            }
-        }, 0);
+    public int startStreaming(final int subscriptionId, String serviceId,
+            final IStreamingServiceCallback callback) throws RemoteException {
+        if (callback == null) {
+            throw new NullPointerException("Callback must not be null");
+        }
 
-        return startStreaming(subscriptionId, serviceId, new StreamingServiceCallback() {
+        final int uid = Binder.getCallingUid();
+
+        int result = startStreaming(subscriptionId, serviceId, new StreamingServiceCallback() {
             @Override
-            public void onError(int errorCode, String message) {
+            public void onError(final int errorCode, final String message) {
                 try {
-                    callback.error(errorCode, message);
+                    callback.onError(errorCode, message);
                 } catch (RemoteException e) {
                     onAppCallbackDied(uid, subscriptionId);
                 }
             }
 
             @Override
-            public void onStreamStateUpdated(@StreamingService.StreamingState int state,
-                    @StreamingService.StreamingStateChangeReason int reason) {
+            public void onStreamStateUpdated(@StreamingService.StreamingState final int state,
+                    @StreamingService.StreamingStateChangeReason final int reason) {
                 try {
-                    callback.streamStateUpdated(state, reason);
+                    callback.onStreamStateUpdated(state, reason);
                 } catch (RemoteException e) {
                     onAppCallbackDied(uid, subscriptionId);
                 }
@@ -180,30 +192,41 @@
             @Override
             public void onMediaDescriptionUpdated() {
                 try {
-                    callback.mediaDescriptionUpdated();
+                    callback.onMediaDescriptionUpdated();
                 } catch (RemoteException e) {
                     onAppCallbackDied(uid, subscriptionId);
                 }
             }
 
             @Override
-            public void onBroadcastSignalStrengthUpdated(int signalStrength) {
+            public void onBroadcastSignalStrengthUpdated(final int signalStrength) {
                 try {
-                    callback.broadcastSignalStrengthUpdated(signalStrength);
+                    callback.onBroadcastSignalStrengthUpdated(signalStrength);
                 } catch (RemoteException e) {
                     onAppCallbackDied(uid, subscriptionId);
                 }
             }
 
             @Override
-            public void onStreamMethodUpdated(int methodType) {
+            public void onStreamMethodUpdated(final int methodType) {
                 try {
-                    callback.streamMethodUpdated(methodType);
+                    callback.onStreamMethodUpdated(methodType);
                 } 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;
     }
 
     /**
@@ -225,7 +248,11 @@
     /**
      * Stop streaming the stream identified by {@code serviceId}. Notification of the resulting
      * stream state change should be reported to the app via
-     * {@link IStreamingServiceCallback#streamStateUpdated(int, int)}.
+     * {@link IStreamingServiceCallback#onStreamStateUpdated(int, int)}.
+     *
+     * In addition, the callback provided via
+     * {@link #startStreaming(int, String, IStreamingServiceCallback)} should no longer be
+     * used after this method has called by the app.
      *
      * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
      *
@@ -238,27 +265,10 @@
     }
 
     /**
-     * Dispose of the stream identified by {@code serviceId} for the app identified by the
-     * {@code appName} and {@code subscriptionId} arguments along with the caller's uid.
-     * No notification back to the app is required for this operation, and the callback provided via
-     * {@link #startStreaming(int, String, IStreamingServiceCallback)} should no longer be
-     * used after this method has called by the app.
-     *
-     * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
-     *
-     * @param subscriptionId The subscription id to use.
-     * @param serviceId The ID of the streaming service that the app wishes to dispose of.
-     */
-    @Override
-    public void disposeStream(int subscriptionId, String serviceId)
-            throws RemoteException {
-    }
-
-    /**
      * 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(IMbmsStreamingManagerCallback, int)} should no longer be used
+     * {@link #initialize(IMbmsStreamingSessionCallback, int)} should no longer be used
      * after this method has been called by the app.
      *
      * May throw an {@link IllegalStateException}
diff --git a/telephony/java/android/telephony/mbms/vendor/VendorIntents.java b/telephony/java/android/telephony/mbms/vendor/VendorIntents.java
deleted file mode 100644
index 367c995..0000000
--- a/telephony/java/android/telephony/mbms/vendor/VendorIntents.java
+++ /dev/null
@@ -1,166 +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.telephony.mbms.vendor;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ResolveInfo;
-import android.net.Uri;
-import android.telephony.mbms.DownloadRequest;
-import android.telephony.mbms.MbmsDownloadReceiver;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * @hide
- * TODO: future systemapi
- */
-public class VendorIntents {
-
-    /**
-     * The MBMS middleware should send this when a download of single file has completed or
-     * failed. Mandatory extras are
-     * {@link android.telephony.MbmsDownloadManager#EXTRA_RESULT}
-     * {@link android.telephony.MbmsDownloadManager#EXTRA_FILE_INFO}
-     * {@link #EXTRA_REQUEST}
-     * {@link #EXTRA_TEMP_LIST}
-     * {@link #EXTRA_FINAL_URI}
-     */
-    public static final String ACTION_DOWNLOAD_RESULT_INTERNAL =
-            "android.telephony.mbms.action.DOWNLOAD_RESULT_INTERNAL";
-
-    /**
-     * The MBMS middleware should send this when it wishes to request {@code content://} URIs to
-     * serve as temp files for downloads or when it wishes to resume paused downloads. Mandatory
-     * extras are
-     * {@link #EXTRA_REQUEST}
-     *
-     * Optional extras are
-     * {@link #EXTRA_FD_COUNT} (0 if not present)
-     * {@link #EXTRA_PAUSED_LIST} (empty if not present)
-     */
-    public static final String ACTION_FILE_DESCRIPTOR_REQUEST =
-            "android.telephony.mbms.action.FILE_DESCRIPTOR_REQUEST";
-
-    /**
-     * The MBMS middleware should send this when it wishes to clean up temp  files in the app's
-     * filesystem. Mandatory extras are:
-     * {@link #EXTRA_TEMP_FILES_IN_USE}
-     */
-    public static final String ACTION_CLEANUP =
-            "android.telephony.mbms.action.CLEANUP";
-
-    /**
-     * Extra containing a {@link List} of {@link Uri}s that were used as temp files for this
-     * completed file. These {@link Uri}s should have scheme {@code file://}, and the temp
-     * files will be deleted upon receipt of the intent.
-     * May be null.
-     */
-    public static final String EXTRA_TEMP_LIST = "android.telephony.mbms.extra.TEMP_LIST";
-
-    /**
-     * Extra containing an integer indicating the number of temp files requested.
-     */
-    public static final String EXTRA_FD_COUNT = "android.telephony.mbms.extra.FD_COUNT";
-
-    /**
-     * Extra containing a list of {@link Uri}s that the middleware is requesting access to via
-     * {@link #ACTION_FILE_DESCRIPTOR_REQUEST} in order to resume downloading. These {@link Uri}s
-     * should have scheme {@code file://}.
-     */
-    public static final String EXTRA_PAUSED_LIST = "android.telephony.mbms.extra.PAUSED_LIST";
-
-    /**
-     * Extra containing a list of {@link android.telephony.mbms.UriPathPair}s, used in the
-     * response to {@link #ACTION_FILE_DESCRIPTOR_REQUEST}. These are temp files that are meant
-     * to be used for new file downloads.
-     */
-    public static final String EXTRA_FREE_URI_LIST = "android.telephony.mbms.extra.FREE_URI_LIST";
-
-    /**
-     * Extra containing a list of {@link android.telephony.mbms.UriPathPair}s, used in the
-     * response to {@link #ACTION_FILE_DESCRIPTOR_REQUEST}. These
-     * {@link android.telephony.mbms.UriPathPair}s contain {@code content://} URIs that provide
-     * access to previously paused downloads.
-     */
-    public static final String EXTRA_PAUSED_URI_LIST =
-            "android.telephony.mbms.extra.PAUSED_URI_LIST";
-
-    /**
-     * Extra containing a string that points to the middleware's knowledge of where the temp file
-     * root for the app is. The path should be a canonical path as returned by
-     * {@link File#getCanonicalPath()}
-     */
-    public static final String EXTRA_TEMP_FILE_ROOT =
-            "android.telephony.mbms.extra.TEMP_FILE_ROOT";
-
-    /**
-     * Extra containing a list of {@link Uri}s indicating temp files which the middleware is
-     * still using.
-     */
-    public static final String EXTRA_TEMP_FILES_IN_USE =
-            "android.telephony.mbms.extra.TEMP_FILES_IN_USE";
-
-    /**
-     * Extra containing the {@link DownloadRequest} for which the download result or file
-     * descriptor request is for. Must not be null.
-     */
-    public static final String EXTRA_REQUEST = "android.telephony.mbms.extra.REQUEST";
-
-    /**
-     * Extra containing a single {@link Uri} indicating the path to the temp file in which the
-     * decoded downloaded file resides. Must not be null.
-     */
-    public static final String EXTRA_FINAL_URI = "android.telephony.mbms.extra.FINAL_URI";
-
-    /**
-     * Extra containing an instance of {@link android.telephony.mbms.ServiceInfo}, used by
-     * file-descriptor requests and cleanup requests to specify which service they want to
-     * request temp files or clean up temp files for, respectively.
-     */
-    public static final String EXTRA_SERVICE_INFO =
-            "android.telephony.mbms.extra.SERVICE_INFO";
-
-    /**
-     * Retrieves the {@link ComponentName} for the {@link android.content.BroadcastReceiver} that
-     * the various intents from the middleware should be targeted towards.
-     * @param uid The uid of the frontend app.
-     * @return The component name of the receiver that the middleware should send its intents to,
-     * or null if the app didn't declare it in the manifest.
-     */
-    public static ComponentName getAppReceiverFromUid(Context context, int uid) {
-        String[] packageNames = context.getPackageManager().getPackagesForUid(uid);
-        if (packageNames == null) {
-            return null;
-        }
-
-        for (String packageName : packageNames) {
-            ComponentName candidate = new ComponentName(packageName,
-                    MbmsDownloadReceiver.class.getCanonicalName());
-            Intent queryIntent = new Intent();
-            queryIntent.setComponent(candidate);
-            List<ResolveInfo> receivers =
-                    context.getPackageManager().queryBroadcastReceivers(queryIntent, 0);
-            if (receivers != null && receivers.size() > 0) {
-                return candidate;
-            }
-        }
-        return null;
-    }
-}
diff --git a/telephony/java/android/telephony/mbms/vendor/VendorUtils.java b/telephony/java/android/telephony/mbms/vendor/VendorUtils.java
new file mode 100644
index 0000000..f1cac8c
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/vendor/VendorUtils.java
@@ -0,0 +1,159 @@
+/*
+ * 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.telephony.mbms.vendor;
+
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.telephony.MbmsDownloadSession;
+import android.telephony.mbms.MbmsDownloadReceiver;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Contains constants and utility methods for MBMS Download middleware apps to communicate with
+ * frontend apps.
+ * @hide
+ */
+@SystemApi
+@TestApi
+public class VendorUtils {
+
+    /**
+     * The MBMS middleware should send this when a download of single file has completed or
+     * failed. The only mandatory extra is
+     * {@link MbmsDownloadSession#EXTRA_MBMS_DOWNLOAD_RESULT}
+     * and the following are required when the download has completed:
+     * {@link MbmsDownloadSession#EXTRA_MBMS_FILE_INFO}
+     * {@link MbmsDownloadSession#EXTRA_MBMS_DOWNLOAD_REQUEST}
+     * {@link #EXTRA_TEMP_LIST}
+     * {@link #EXTRA_FINAL_URI}
+     */
+    public static final String ACTION_DOWNLOAD_RESULT_INTERNAL =
+            "android.telephony.mbms.action.DOWNLOAD_RESULT_INTERNAL";
+
+    /**
+     * The MBMS middleware should send this when it wishes to request {@code content://} URIs to
+     * serve as temp files for downloads or when it wishes to resume paused downloads. Mandatory
+     * extras are
+     * {@link #EXTRA_SERVICE_ID}
+     *
+     * Optional extras are
+     * {@link #EXTRA_FD_COUNT} (0 if not present)
+     * {@link #EXTRA_PAUSED_LIST} (empty if not present)
+     */
+    public static final String ACTION_FILE_DESCRIPTOR_REQUEST =
+            "android.telephony.mbms.action.FILE_DESCRIPTOR_REQUEST";
+
+    /**
+     * The MBMS middleware should send this when it wishes to clean up temp  files in the app's
+     * filesystem. Mandatory extras are:
+     * {@link #EXTRA_TEMP_FILES_IN_USE}
+     */
+    public static final String ACTION_CLEANUP =
+            "android.telephony.mbms.action.CLEANUP";
+
+    /**
+     * Extra containing a {@link List} of {@link Uri}s that were used as temp files for this
+     * completed file. These {@link Uri}s should have scheme {@code file://}, and the temp
+     * files will be deleted upon receipt of the intent.
+     * May be null.
+     */
+    public static final String EXTRA_TEMP_LIST = "android.telephony.mbms.extra.TEMP_LIST";
+
+    /**
+     * Extra containing an integer indicating the number of temp files requested.
+     */
+    public static final String EXTRA_FD_COUNT = "android.telephony.mbms.extra.FD_COUNT";
+
+    /**
+     * Extra containing a list of {@link Uri}s that the middleware is requesting access to via
+     * {@link #ACTION_FILE_DESCRIPTOR_REQUEST} in order to resume downloading. These {@link Uri}s
+     * should have scheme {@code file://}.
+     */
+    public static final String EXTRA_PAUSED_LIST = "android.telephony.mbms.extra.PAUSED_LIST";
+
+    /**
+     * Extra containing a list of {@link android.telephony.mbms.UriPathPair}s, used in the
+     * response to {@link #ACTION_FILE_DESCRIPTOR_REQUEST}. These are temp files that are meant
+     * to be used for new file downloads.
+     */
+    public static final String EXTRA_FREE_URI_LIST = "android.telephony.mbms.extra.FREE_URI_LIST";
+
+    /**
+     * Extra containing a list of {@link android.telephony.mbms.UriPathPair}s, used in the
+     * response to {@link #ACTION_FILE_DESCRIPTOR_REQUEST}. These
+     * {@link android.telephony.mbms.UriPathPair}s contain {@code content://} URIs that provide
+     * access to previously paused downloads.
+     */
+    public static final String EXTRA_PAUSED_URI_LIST =
+            "android.telephony.mbms.extra.PAUSED_URI_LIST";
+
+    /**
+     * Extra containing a string that points to the middleware's knowledge of where the temp file
+     * root for the app is. The path should be a canonical path as returned by
+     * {@link File#getCanonicalPath()}
+     */
+    public static final String EXTRA_TEMP_FILE_ROOT =
+            "android.telephony.mbms.extra.TEMP_FILE_ROOT";
+
+    /**
+     * Extra containing a list of {@link Uri}s indicating temp files which the middleware is
+     * still using.
+     */
+    public static final String EXTRA_TEMP_FILES_IN_USE =
+            "android.telephony.mbms.extra.TEMP_FILES_IN_USE";
+
+    /**
+     * Extra containing a single {@link Uri} indicating the path to the temp file in which the
+     * decoded downloaded file resides. Must not be null.
+     */
+    public static final String EXTRA_FINAL_URI = "android.telephony.mbms.extra.FINAL_URI";
+
+    /**
+     * Extra containing a String representing a service ID, used by
+     * file-descriptor requests and cleanup requests to specify which service they want to
+     * request temp files or clean up temp files for, respectively.
+     */
+    public static final String EXTRA_SERVICE_ID =
+            "android.telephony.mbms.extra.SERVICE_ID";
+
+    /**
+     * Retrieves the {@link ComponentName} for the {@link android.content.BroadcastReceiver} that
+     * the various intents from the middleware should be targeted towards.
+     * @param packageName The package name of the app.
+     * @return The component name of the receiver that the middleware should send its intents to,
+     * or null if the app didn't declare it in the manifest.
+     */
+    public static ComponentName getAppReceiverFromPackageName(Context context, String packageName) {
+        ComponentName candidate = new ComponentName(packageName,
+                MbmsDownloadReceiver.class.getCanonicalName());
+        Intent queryIntent = new Intent();
+        queryIntent.setComponent(candidate);
+        List<ResolveInfo> receivers =
+                context.getPackageManager().queryBroadcastReceivers(queryIntent, 0);
+        if (receivers != null && receivers.size() > 0) {
+            return candidate;
+        }
+        return null;
+    }
+}
diff --git a/telephony/java/com/android/ims/ImsCallProfile.java b/telephony/java/com/android/ims/ImsCallProfile.java
index 36abfc9..489c208 100644
--- a/telephony/java/com/android/ims/ImsCallProfile.java
+++ b/telephony/java/com/android/ims/ImsCallProfile.java
@@ -19,7 +19,9 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.telecom.VideoProfile;
+import android.util.Log;
 
 import com.android.internal.telephony.PhoneConstants;
 
@@ -216,6 +218,29 @@
     public int mServiceType;
     public int mCallType;
     public int mRestrictCause = CALL_RESTRICT_CAUSE_NONE;
+
+    /**
+     * Extras associated with this {@link ImsCallProfile}.
+     * <p>
+     * Valid data types include:
+     * <ul>
+     *     <li>{@link Integer} (and int)</li>
+     *     <li>{@link Long} (and long)</li>
+     *     <li>{@link Double} (and double)</li>
+     *     <li>{@link String}</li>
+     *     <li>{@code int[]}</li>
+     *     <li>{@code long[]}</li>
+     *     <li>{@code double[]}</li>
+     *     <li>{@code String[]}</li>
+     *     <li>{@link PersistableBundle}</li>
+     *     <li>{@link Boolean} (and boolean)</li>
+     *     <li>{@code boolean[]}</li>
+     *     <li>Other {@link Parcelable} classes in the {@code android.*} namespace.</li>
+     * </ul>
+     * <p>
+     * Invalid types will be removed when the {@link ImsCallProfile} is parceled for transmit across
+     * a {@link android.os.Binder}.
+     */
     public Bundle mCallExtras;
     public ImsStreamMediaProfile mMediaProfile;
 
@@ -315,16 +340,17 @@
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
+        Bundle filteredExtras = maybeCleanseExtras(mCallExtras);
         out.writeInt(mServiceType);
         out.writeInt(mCallType);
-        out.writeParcelable(mCallExtras, 0);
+        out.writeBundle(filteredExtras);
         out.writeParcelable(mMediaProfile, 0);
     }
 
     private void readFromParcel(Parcel in) {
         mServiceType = in.readInt();
         mCallType = in.readInt();
-        mCallExtras = in.readParcelable(null);
+        mCallExtras = in.readBundle();
         mMediaProfile = in.readParcelable(null);
     }
 
@@ -465,6 +491,31 @@
     }
 
     /**
+     * Cleanses a {@link Bundle} to ensure that it contains only data of type:
+     * 1. Primitive data types (e.g. int, bool, and other values determined by
+     * {@link android.os.PersistableBundle#isValidType(Object)}).
+     * 2. Other Bundles.
+     * 3. {@link Parcelable} objects in the {@code android.*} namespace.
+     * @param extras the source {@link Bundle}
+     * @return where all elements are valid types the source {@link Bundle} is returned unmodified,
+     *      otherwise a copy of the {@link Bundle} with the invalid elements is returned.
+     */
+    private Bundle maybeCleanseExtras(Bundle extras) {
+        if (extras == null) {
+            return null;
+        }
+
+        int startSize = extras.size();
+        Bundle filtered = extras.filterValues();
+        int endSize = filtered.size();
+        if (startSize != endSize) {
+            Log.i(TAG, "maybeCleanseExtras: " + (startSize - endSize) + " extra values were "
+                    + "removed - only primitive types and system parcelables are permitted.");
+        }
+        return filtered;
+    }
+
+    /**
      * Determines if a video state is set in a video state bit-mask.
      *
      * @param videoState The video state bit mask.
diff --git a/telephony/java/com/android/ims/ImsConferenceState.java b/telephony/java/com/android/ims/ImsConferenceState.java
index c57ef98..0afde88 100644
--- a/telephony/java/com/android/ims/ImsConferenceState.java
+++ b/telephony/java/com/android/ims/ImsConferenceState.java
@@ -79,6 +79,8 @@
     public static final String STATUS_DISCONNECTED = "disconnected";
     public static final String STATUS_MUTED_VIA_FOCUS = "muted-via-focus";
     public static final String STATUS_CONNECT_FAIL = "connect-fail";
+    public static final String STATUS_SEND_ONLY = "sendonly";
+    public static final String STATUS_SEND_RECV = "sendrecv";
 
     /**
      * conference-info : SIP status code (integer)
@@ -156,15 +158,53 @@
         } else if (status.equals(STATUS_ALERTING) ||
                 status.equals(STATUS_DIALING_OUT)) {
             return Connection.STATE_DIALING;
-        } else if (status.equals(STATUS_ON_HOLD)) {
+        } else if (status.equals(STATUS_ON_HOLD) ||
+                status.equals(STATUS_SEND_ONLY)) {
             return Connection.STATE_HOLDING;
         } else if (status.equals(STATUS_CONNECTED) ||
                 status.equals(STATUS_MUTED_VIA_FOCUS) ||
-                status.equals(STATUS_DISCONNECTING)) {
+                status.equals(STATUS_DISCONNECTING) ||
+                status.equals(STATUS_SEND_RECV)) {
             return Connection.STATE_ACTIVE;
         } else if (status.equals(STATUS_DISCONNECTED)) {
             return Connection.STATE_DISCONNECTED;
         }
         return Call.STATE_ACTIVE;
     }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("[");
+        sb.append(ImsConferenceState.class.getSimpleName());
+        sb.append(" ");
+        if (mParticipants.size() > 0) {
+            Set<Entry<String, Bundle>> entries = mParticipants.entrySet();
+
+            if (entries != null) {
+                Iterator<Entry<String, Bundle>> iterator = entries.iterator();
+                sb.append("<");
+                while (iterator.hasNext()) {
+                    Entry<String, Bundle> entry = iterator.next();
+                    sb.append(entry.getKey());
+                    sb.append(": ");
+                    Bundle participantData = entry.getValue();
+
+                    for (String key : participantData.keySet()) {
+                        sb.append(key);
+                        sb.append("=");
+                        if (ENDPOINT.equals(key) || USER.equals(key)) {
+                            sb.append(android.telecom.Log.pii(participantData.get(key)));
+                        } else {
+                            sb.append(participantData.get(key));
+                        }
+                        sb.append(", ");
+                    }
+                }
+                sb.append(">");
+            }
+        }
+        sb.append("]");
+        return sb.toString();
+    }
 }
diff --git a/telephony/java/com/android/ims/ImsConfig.java b/telephony/java/com/android/ims/ImsConfig.java
index e7b22bd..cf4c47b 100644
--- a/telephony/java/com/android/ims/ImsConfig.java
+++ b/telephony/java/com/android/ims/ImsConfig.java
@@ -524,6 +524,7 @@
     * Defines IMS feature value.
     */
     public static class FeatureValueConstants {
+        public static final int ERROR = -1;
         public static final int OFF = 0;
         public static final int ON = 1;
     }
diff --git a/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl b/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl
new file mode 100644
index 0000000..52b3853
--- /dev/null
+++ b/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl
@@ -0,0 +1,56 @@
+/*
+ * 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.ims.internal;
+
+import android.app.PendingIntent;
+
+import com.android.ims.ImsCallProfile;
+import com.android.ims.internal.IImsCallSession;
+import com.android.ims.internal.IImsCallSessionListener;
+import com.android.ims.internal.IImsConfig;
+import com.android.ims.internal.IImsEcbm;
+import com.android.ims.internal.IImsMultiEndpoint;
+import com.android.ims.internal.IImsRegistrationListener;
+import com.android.ims.internal.IImsUt;
+
+import android.os.Message;
+
+/**
+ * See MMTelFeature for more information.
+ * {@hide}
+ */
+interface IImsMMTelFeature {
+    int startSession(in PendingIntent incomingCallIntent,
+            in IImsRegistrationListener listener);
+    void endSession(int sessionId);
+    boolean isConnected(int callSessionType, int callType);
+    boolean isOpened();
+    int getFeatureStatus();
+    void addRegistrationListener(in IImsRegistrationListener listener);
+    void removeRegistrationListener(in IImsRegistrationListener listener);
+    ImsCallProfile createCallProfile(int sessionId, int callSessionType, int callType);
+    IImsCallSession createCallSession(int sessionId, in ImsCallProfile profile,
+            IImsCallSessionListener listener);
+    IImsCallSession getPendingCallSession(int sessionId, String callId);
+    IImsUt getUtInterface();
+    IImsConfig getConfigInterface();
+    void turnOnIms();
+    void turnOffIms();
+    IImsEcbm getEcbmInterface();
+    void setUiTTYMode(int uiTtyMode, in Message onComplete);
+    IImsMultiEndpoint getMultiEndpointInterface();
+}
diff --git a/telephony/java/com/android/ims/internal/IImsRcsFeature.aidl b/telephony/java/com/android/ims/internal/IImsRcsFeature.aidl
new file mode 100644
index 0000000..b1cb23b
--- /dev/null
+++ b/telephony/java/com/android/ims/internal/IImsRcsFeature.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ims.internal;
+
+/**
+ * See RcsFeature for more information.
+ * {@hide}
+ */
+interface IImsRcsFeature {
+    //Empty Default Implementation
+}
\ No newline at end of file
diff --git a/telephony/java/com/android/ims/internal/IImsServiceController.aidl b/telephony/java/com/android/ims/internal/IImsServiceController.aidl
index bb06d7e..857089f 100644
--- a/telephony/java/com/android/ims/internal/IImsServiceController.aidl
+++ b/telephony/java/com/android/ims/internal/IImsServiceController.aidl
@@ -16,49 +16,17 @@
 
 package com.android.ims.internal;
 
-import android.app.PendingIntent;
-
-import com.android.ims.ImsCallProfile;
-import com.android.ims.internal.IImsCallSession;
-import com.android.ims.internal.IImsCallSessionListener;
-import com.android.ims.internal.IImsConfig;
-import com.android.ims.internal.IImsEcbm;
 import com.android.ims.internal.IImsFeatureStatusCallback;
-import com.android.ims.internal.IImsMultiEndpoint;
-import com.android.ims.internal.IImsRegistrationListener;
-import com.android.ims.internal.IImsUt;
-
-import android.os.Message;
+import com.android.ims.internal.IImsMMTelFeature;
+import com.android.ims.internal.IImsRcsFeature;
 
 /**
- * See ImsService and IMMTelFeature for more information.
+ * See ImsService and MMTelFeature for more information.
  * {@hide}
  */
 interface IImsServiceController {
-    // ImsService Control
-    void createImsFeature(int slotId, int feature, IImsFeatureStatusCallback c);
-    void removeImsFeature(int slotId, int feature, IImsFeatureStatusCallback c);
-    // MMTel Feature
-    int startSession(int slotId, int featureType, in PendingIntent incomingCallIntent,
-            in IImsRegistrationListener listener);
-    void endSession(int slotId, int featureType, int sessionId);
-    boolean isConnected(int slotId, int featureType, int callSessionType, int callType);
-    boolean isOpened(int slotId, int featureType);
-    int getFeatureStatus(int slotId, int featureType);
-    void addRegistrationListener(int slotId, int featureType, in IImsRegistrationListener listener);
-    void removeRegistrationListener(int slotId, int featureType,
-            in IImsRegistrationListener listener);
-    ImsCallProfile createCallProfile(int slotId, int featureType, int sessionId,
-            int callSessionType, int callType);
-    IImsCallSession createCallSession(int slotId, int featureType, int sessionId,
-            in ImsCallProfile profile, IImsCallSessionListener listener);
-    IImsCallSession getPendingCallSession(int slotId, int featureType, int sessionId,
-            String callId);
-    IImsUt getUtInterface(int slotId, int featureType);
-    IImsConfig getConfigInterface(int slotId, int featureType);
-    void turnOnIms(int slotId, int featureType);
-    void turnOffIms(int slotId, int featureType);
-    IImsEcbm getEcbmInterface(int slotId, int featureType);
-    void setUiTTYMode(int slotId, int featureType, int uiTtyMode, in Message onComplete);
-    IImsMultiEndpoint getMultiEndpointInterface(int slotId, int featureType);
+    IImsMMTelFeature createEmergencyMMTelFeature(int slotId, in IImsFeatureStatusCallback c);
+    IImsMMTelFeature createMMTelFeature(int slotId, in IImsFeatureStatusCallback c);
+    IImsRcsFeature createRcsFeature(int slotId, in IImsFeatureStatusCallback c);
+    void removeImsFeature(int slotId, int featureType, in IImsFeatureStatusCallback c);
 }
diff --git a/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl b/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl
new file mode 100644
index 0000000..9a9cf53
--- /dev/null
+++ b/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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.ims.internal;
+
+/**
+ *  Interface from ImsResolver to ImsServiceProxy in ImsManager.
+ * Callback to ImsManager when a feature changes in the ImsServiceController.
+ * {@hide}
+ */
+oneway interface IImsServiceFeatureCallback {
+    void imsFeatureCreated(int slotId, int feature);
+    void imsFeatureRemoved(int slotId, int feature);
+    void imsStatusChanged(int slotId, int feature, int status);
+}
\ No newline at end of file
diff --git a/telephony/java/com/android/ims/internal/IImsServiceFeatureListener.aidl b/telephony/java/com/android/ims/internal/IImsServiceFeatureListener.aidl
deleted file mode 100644
index df10700..0000000
--- a/telephony/java/com/android/ims/internal/IImsServiceFeatureListener.aidl
+++ /dev/null
@@ -1,28 +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.ims.internal;
-
-/**
- *  Interface from ImsResolver to ImsServiceProxy in ImsManager.
- * Callback to ImsManager when a feature changes in the ImsServiceController.
- * {@hide}
- */
-oneway interface IImsServiceFeatureListener {
-    void imsFeatureCreated(int slotId, int feature);
-    void imsFeatureRemoved(int slotId, int feature);
-    void imsStatusChanged(int slotId, int feature, int status);
-}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/ExponentialBackoff.java b/telephony/java/com/android/internal/telephony/ExponentialBackoff.java
new file mode 100644
index 0000000..80958c0
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/ExponentialBackoff.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.annotation.NonNull;
+import android.os.Handler;
+import android.os.Looper;
+
+/** The implementation of exponential backoff with jitter applied. */
+public class ExponentialBackoff {
+    private int mRetryCounter;
+    private long mStartDelayMs;
+    private long mMaximumDelayMs;
+    private long mCurrentDelayMs;
+    private int mMultiplier;
+    private Runnable mRunnable;
+    private Handler mHandler;
+
+    public ExponentialBackoff(
+            long initialDelayMs,
+            long maximumDelayMs,
+            int multiplier,
+            @NonNull Looper looper,
+            @NonNull Runnable runnable) {
+        this(initialDelayMs, maximumDelayMs, multiplier, new Handler(looper), runnable);
+    }
+
+    public ExponentialBackoff(
+            long initialDelayMs,
+            long maximumDelayMs,
+            int multiplier,
+            @NonNull Handler handler,
+            @NonNull Runnable runnable) {
+        mRetryCounter = 0;
+        mStartDelayMs = initialDelayMs;
+        mMaximumDelayMs = maximumDelayMs;
+        mMultiplier = multiplier;
+        mHandler = handler;
+        mRunnable = runnable;
+    }
+
+    /** Starts the backoff, the runnable will be executed after {@link #mStartDelayMs}. */
+    public void start() {
+        mRetryCounter = 0;
+        mCurrentDelayMs = mStartDelayMs;
+        mHandler.removeCallbacks(mRunnable);
+        mHandler.postDelayed(mRunnable, mCurrentDelayMs);
+    }
+
+    /** Stops the backoff, all pending messages will be removed from the message queue. */
+    public void stop() {
+        mRetryCounter = 0;
+        mHandler.removeCallbacks(mRunnable);
+    }
+
+    /** Should call when the retry action has failed and we want to retry after a longer delay. */
+    public void notifyFailed() {
+        mRetryCounter++;
+        long temp = Math.min(
+                mMaximumDelayMs, (long) (mStartDelayMs * Math.pow(mMultiplier, mRetryCounter)));
+        mCurrentDelayMs = (long) (((1 + Math.random()) / 2) * temp);
+        mHandler.removeCallbacks(mRunnable);
+        mHandler.postDelayed(mRunnable, mCurrentDelayMs);
+    }
+
+    /** Returns the delay for the most recently posted message. */
+    public long getCurrentDelay() {
+        return mCurrentDelayMs;
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index e9c5461..ac16139 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -45,7 +45,6 @@
     void onVoLteServiceStateChanged(in VoLteServiceState lteState);
     void onVoiceActivationStateChanged(int activationState);
     void onDataActivationStateChanged(int activationState);
-    void onOemHookRawEvent(in byte[] rawData);
     void onCarrierNetworkChange(in boolean active);
 }
 
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index fe37531..a4eb424 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -187,6 +187,57 @@
             in PendingIntent deliveryIntent, in boolean persistMessage);
 
     /**
+     * Send an SMS with options using Subscription Id.
+     *
+     * @param subId the subId on which the SMS has to be sent.
+     * @param destAddr the address to send the message to
+     * @param scAddr the SMSC to send the message through, or NULL for the
+     *  default SMSC
+     * @param text the body of the message to send
+     * @param sentIntent if not NULL this <code>PendingIntent</code> is
+     *  broadcast when the message is sucessfully sent, or failed.
+     *  The result code will be <code>Activity.RESULT_OK<code> for success,
+     *  or one of these errors:<br>
+     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
+     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
+     *  <code>RESULT_ERROR_NULL_PDU</code><br>
+     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
+     *  the extra "errorCode" containing a radio technology specific value,
+     *  generally only useful for troubleshooting.<br>
+     *  The per-application based SMS control checks sentIntent. If sentIntent
+     *  is NULL the caller will be checked against all unknown applications,
+     *  which cause smaller number of SMS to be sent in checking period.
+     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
+     *  broadcast when the message is delivered to the recipient.  The
+     *  raw pdu of the status report is in the extended data ("pdu").
+     * @param persistMessageForNonDefaultSmsApp whether the sent message should
+     *   be automatically persisted in the SMS db. It only affects messages sent
+     *   by a non-default SMS app. Currently only the carrier app can set this
+     *   parameter to false to skip auto message persistence.
+     * @param priority Priority level of the message
+     *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
+     *  ---------------------------------
+     *  PRIORITY      | Level of Priority
+     *  ---------------------------------
+     *      '00'      |     Normal
+     *      '01'      |     Interactive
+     *      '10'      |     Urgent
+     *      '11'      |     Emergency
+     *  ----------------------------------
+     *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
+     * @param expectMore is a boolean to indicate the sending message is multi segmented or not.
+     * @param validityPeriod Validity Period of the message in mins.
+     *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
+     *  Validity Period(Minimum) -> 5 mins
+     *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
+     *  Any Other values included Negative considered as Invalid Validity Period of the message.
+     */
+    void sendTextForSubscriberWithOptions(in int subId, String callingPkg, in String destAddr,
+            in String scAddr, in String text, in PendingIntent sentIntent,
+            in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp,
+            in int priority, in boolean expectMore, in int validityPeriod);
+
+    /**
      * Inject an SMS PDU into the android platform.
      *
      * @param subId the subId on which the SMS has to be injected.
@@ -234,6 +285,56 @@
             in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp);
 
     /**
+     * Send a multi-part text based SMS with options using Subscription Id.
+     *
+     * @param subId the subId on which the SMS has to be sent.
+     * @param destinationAddress the address to send the message to
+     * @param scAddress is the service center address or null to use
+     *   the current default SMSC
+     * @param parts an <code>ArrayList</code> of strings that, in order,
+     *   comprise the original message
+     * @param sentIntents if not null, an <code>ArrayList</code> of
+     *   <code>PendingIntent</code>s (one for each message part) that is
+     *   broadcast when the corresponding message part has been sent.
+     *   The result code will be <code>Activity.RESULT_OK<code> for success,
+     *   or one of these errors:
+     *   <code>RESULT_ERROR_GENERIC_FAILURE</code>
+     *   <code>RESULT_ERROR_RADIO_OFF</code>
+     *   <code>RESULT_ERROR_NULL_PDU</code>.
+     * @param deliveryIntents if not null, an <code>ArrayList</code> of
+     *   <code>PendingIntent</code>s (one for each message part) that is
+     *   broadcast when the corresponding message part has been delivered
+     *   to the recipient.  The raw pdu of the status report is in the
+     *   extended data ("pdu").
+     * @param persistMessageForNonDefaultSmsApp whether the sent message should
+     *   be automatically persisted in the SMS db. It only affects messages sent
+     *   by a non-default SMS app. Currently only the carrier app can set this
+     *   parameter to false to skip auto message persistence.
+     * @param priority Priority level of the message
+     *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
+     *  ---------------------------------
+     *  PRIORITY      | Level of Priority
+     *  ---------------------------------
+     *      '00'      |     Normal
+     *      '01'      |     Interactive
+     *      '10'      |     Urgent
+     *      '11'      |     Emergency
+     *  ----------------------------------
+     *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
+     * @param expectMore is a boolean to indicate the sending message is multi segmented or not.
+     * @param validityPeriod Validity Period of the message in mins.
+     *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
+     *  Validity Period(Minimum) -> 5 mins
+     *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
+     *  Any Other values included Negative considered as Invalid Validity Period of the message.
+     */
+    void sendMultipartTextForSubscriberWithOptions(in int subId, String callingPkg,
+            in String destinationAddress, in String scAddress, in List<String> parts,
+            in List<PendingIntent> sentIntents, in List<PendingIntent> deliveryIntents,
+            in boolean persistMessageForNonDefaultSmsApp, in int priority, in boolean expectMore,
+            in int validityPeriod);
+
+    /**
      * Enable reception of cell broadcast (SMS-CB) messages with the given
      * message identifier and RAN type. The RAN type specify this message ID
      * belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 71f2c6b..644ad49 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -94,6 +94,21 @@
     int getActiveSubInfoCountMax();
 
     /**
+     * @see android.telephony.SubscriptionManager#getAvailableSubscriptionInfoList
+     */
+    List<SubscriptionInfo> getAvailableSubscriptionInfoList(String callingPackage);
+
+    /**
+     * @see android.telephony.SubscriptionManager#getAccessibleSubscriptionInfoList
+     */
+    List<SubscriptionInfo> getAccessibleSubscriptionInfoList(String callingPackage);
+
+    /**
+     * @see android.telephony.SubscriptionManager#requestEmbeddedSubscriptionInfoListRefresh
+     */
+    oneway void requestEmbeddedSubscriptionInfoListRefresh();
+
+    /**
      * Add a new SubscriptionInfo to subinfo database if needed
      * @param iccId the IccId of the SIM card
      * @param slotIndex the slot which the SIM is inserted
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index ab7c5e7..fd6091a 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -38,8 +38,9 @@
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyHistogram;
 import android.telephony.VisualVoicemailSmsFilterSettings;
-import com.android.ims.internal.IImsServiceController;
-import com.android.ims.internal.IImsServiceFeatureListener;
+import com.android.ims.internal.IImsMMTelFeature;
+import com.android.ims.internal.IImsRcsFeature;
+import com.android.ims.internal.IImsServiceFeatureCallback;
 import com.android.internal.telephony.CellNetworkScanResult;
 import com.android.internal.telephony.OperatorInfo;
 
@@ -377,6 +378,13 @@
     Bundle getCellLocation(String callingPkg);
 
     /**
+     * Returns the ISO country code equivalent of the current registered
+     * operator's MCC (Mobile Country Code).
+     * @see android.telephony.TelephonyManager#getNetworkCountryIso
+     */
+    String getNetworkCountryIsoForPhone(int phoneId);
+
+    /**
      * Returns the neighboring cell information of the device.
      */
     List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg);
@@ -623,11 +631,13 @@
      * Input parameters equivalent to TS 27.007 AT+CCHO command.
      *
      * @param subId The subscription to use.
+     * @param callingPackage the name of the package making the call.
      * @param AID Application id. See ETSI 102.221 and 101.220.
      * @param p2 P2 parameter (described in ISO 7816-4).
      * @return an IccOpenLogicalChannelResponse object.
      */
-    IccOpenLogicalChannelResponse iccOpenLogicalChannel(int subId, String AID, int p2);
+    IccOpenLogicalChannelResponse iccOpenLogicalChannel(
+            int subId, String callingPackage, String AID, int p2);
 
     /**
      * Closes a previously opened logical channel to the ICC card.
@@ -775,12 +785,27 @@
     int getTetherApnRequired();
 
     /**
-     *  Get ImsServiceController binder from ImsResolver that corresponds to the subId and feature
-     *  requested as well as registering the ImsServiceController for callbacks using the
-     *  IImsServiceFeatureListener interface.
+     *  Get IImsMMTelFeature binder from ImsResolver that corresponds to the subId and MMTel feature
+     *  as well as registering the MMTelFeature for callbacks using the IImsServiceFeatureCallback
+     *  interface.
      */
-    IImsServiceController getImsServiceControllerAndListen(int slotIndex, int feature,
-                IImsServiceFeatureListener callback);
+    IImsMMTelFeature getMMTelFeatureAndListen(int slotId, in IImsServiceFeatureCallback callback);
+
+    /**
+     *  Get IImsMMTelFeature binder from ImsResolver that corresponds to the subId and MMTel feature
+     *  as well as registering the MMTelFeature for callbacks using the IImsServiceFeatureCallback
+     *  interface.
+     *  Used for emergency calling only.
+     */
+    IImsMMTelFeature getEmergencyMMTelFeatureAndListen(int slotId,
+            in IImsServiceFeatureCallback callback);
+
+    /**
+     *  Get IImsRcsFeature binder from ImsResolver that corresponds to the subId and RCS feature
+     *  as well as registering the RcsFeature for callbacks using the IImsServiceFeatureCallback
+     *  interface.
+     */
+    IImsRcsFeature getRcsFeatureAndListen(int slotId, in IImsServiceFeatureCallback callback);
 
     /**
      * Set the network selection mode to automatic.
@@ -991,17 +1016,6 @@
             in List<String> cdmaNonRoamingList);
 
     /**
-     * Returns the result and response from RIL for oem request
-     *
-     * @param oemReq the data is sent to ril.
-     * @param oemResp the respose data from RIL.
-     * @return negative value request was not handled or get error
-     *         0 request was handled succesfully, but no response data
-     *         positive value success, data length of response
-     */
-    int invokeOemRilRequestRaw(in byte[] oemReq, out byte[] oemResp);
-
-    /**
      * Check if any mobile Radios need to be shutdown.
      *
      * @return true is any mobile radio needs to be shutdown
@@ -1080,6 +1094,15 @@
     boolean isImsRegistered();
 
     /**
+     * Get IMS Registration Status on a particular subid.
+     *
+     * @param subId user preferred subId.
+     *
+     * @return {@code true} if the IMS status is registered.
+     */
+    boolean isImsRegisteredForSubscriber(int subId);
+
+    /**
      * Returns the Status of Wi-Fi Calling
      */
     boolean isWifiCallingAvailable();
@@ -1294,6 +1317,16 @@
     void carrierActionSetRadioEnabled(int subId, boolean enabled);
 
     /**
+     * Action set from carrier signalling broadcast receivers to start/stop reporting default
+     * network conditions.
+     * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
+     * @param subId the subscription ID that this action applies to.
+     * @param report control start/stop reporting default network events.
+     * @hide
+     */
+    void carrierActionReportDefaultNetworkStatus(int subId, boolean report);
+
+    /**
      * Get aggregated video call data usage since boot.
      * Permissions android.Manifest.permission.READ_NETWORK_USAGE_HISTORY is required.
      *
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 2c2206c..75d8f3f 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -67,7 +67,6 @@
     void notifyVoLteServiceStateChanged(in VoLteServiceState lteState);
     void notifySimActivationStateChangedForPhoneId(in int phoneId, in int subId,
             int activationState, int activationType);
-    void notifyOemHookRawEventForSubscriber(in int subId, in byte[] rawData);
     void notifySubscriptionInfoChanged();
     void notifyCarrierNetworkChange(in boolean active);
 }
diff --git a/telephony/java/com/android/internal/telephony/NetworkScanResult.java b/telephony/java/com/android/internal/telephony/NetworkScanResult.java
index 8b09848..95f39d7 100644
--- a/telephony/java/com/android/internal/telephony/NetworkScanResult.java
+++ b/telephony/java/com/android/internal/telephony/NetworkScanResult.java
@@ -19,7 +19,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.CellInfo;
-import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -76,17 +75,15 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(scanStatus);
         dest.writeInt(scanError);
-        CellInfo[] ci = networkInfos.toArray(new CellInfo[networkInfos.size()]);
-        dest.writeParcelableArray(ci, flags);
+        dest.writeParcelableList(networkInfos, flags);
     }
 
     private NetworkScanResult(Parcel in) {
         scanStatus = in.readInt();
         scanError = in.readInt();
-        CellInfo[] ci = (CellInfo[]) in.readParcelableArray(
-                Object.class.getClassLoader(),
-                CellInfo.class);
-        networkInfos = Arrays.asList(ci);
+        List<CellInfo> ni = new ArrayList<>();
+        in.readParcelableList(ni, Object.class.getClassLoader());
+        networkInfos = ni;
     }
 
     @Override
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index 0343890..f29d993c 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -447,6 +447,20 @@
             "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE";
 
     /**
+     * <p>Broadcast Action: when system default network available/unavailable with
+     * carrier-disabled mobile data. Intended for carrier apps to set/reset carrier actions when
+     * other network becomes system default network, Wi-Fi for example.
+     * The intent will have the following extra values:</p>
+     * <ul>
+     *   <li>defaultNetworkAvailable</li><dd>A boolean indicates default network available.</dd>
+     *   <li>subId</li><dd>Sub Id which associated the default data.</dd>
+     * </ul>
+     * <p class="note">This is a protected intent that can only be sent by the system. </p>
+     */
+    public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE =
+            "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE";
+
+    /**
      * <p>Broadcast Action: when framework reset all carrier actions on sim load or absent.
      * intended for carrier apps clean up (clear UI e.g.) and only sent to the specified carrier app
      * The intent will have the following extra values:</p>
@@ -465,7 +479,7 @@
     public static final String EXTRA_APN_PROTO_KEY = "apnProto";
     public static final String EXTRA_PCO_ID_KEY = "pcoId";
     public static final String EXTRA_PCO_VALUE_KEY = "pcoValue";
-
+    public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE_KEY = "defaultNetworkAvailable";
 
    /**
      * Broadcast action to trigger CI OMA-DM Session.
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 629173d..14c5f4b 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -99,6 +99,15 @@
     private static final int RETURN_NO_ACK  = 0;
     private static final int RETURN_ACK     = 1;
 
+    /**
+     * Supported priority modes for CDMA SMS messages
+     * (See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1)
+     */
+    private static final int PRIORITY_NORMAL        = 0x0;
+    private static final int PRIORITY_INTERACTIVE   = 0x1;
+    private static final int PRIORITY_URGENT        = 0x2;
+    private static final int PRIORITY_EMERGENCY     = 0x3;
+
     private SmsEnvelope mEnvelope;
     private BearerData mBearerData;
 
@@ -161,7 +170,7 @@
 
             // Second byte is the MSG_LEN, length of the message
             // See 3GPP2 C.S0023 3.4.27
-            int size = data[1];
+            int size = data[1] & 0xFF;
 
             // Note: Data may include trailing FF's.  That's OK; message
             // should still parse correctly.
@@ -211,6 +220,26 @@
      */
     public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, String message,
             boolean statusReportRequested, SmsHeader smsHeader) {
+        return getSubmitPdu(scAddr, destAddr, message, statusReportRequested, smsHeader, -1);
+    }
+
+    /**
+     * Get an SMS-SUBMIT PDU for a destination address and a message
+     *
+     * @param scAddr                Service Centre address.  Null means use default.
+     * @param destAddr              Address of the recipient.
+     * @param message               String representation of the message payload.
+     * @param statusReportRequested Indicates whether a report is requested for this message.
+     * @param smsHeader             Array containing the data for the User Data Header, preceded
+     *                              by the Element Identifiers.
+     * @param priority              Priority level of the message
+     * @return a <code>SubmitPdu</code> containing the encoded SC
+     *         address, if applicable, and the encoded message.
+     *         Returns null on encode error.
+     * @hide
+     */
+    public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, String message,
+            boolean statusReportRequested, SmsHeader smsHeader, int priority) {
 
         /**
          * TODO(cleanup): Do we really want silent failure like this?
@@ -224,7 +253,7 @@
         UserData uData = new UserData();
         uData.payloadStr = message;
         uData.userDataHeader = smsHeader;
-        return privateGetSubmitPdu(destAddr, statusReportRequested, uData);
+        return privateGetSubmitPdu(destAddr, statusReportRequested, uData, priority);
     }
 
     /**
@@ -282,6 +311,22 @@
     }
 
     /**
+     * Get an SMS-SUBMIT PDU for a data message to a destination address &amp; port
+     *
+     * @param destAddr the address of the destination for the message
+     * @param userData the data for the message
+     * @param statusReportRequested Indicates whether a report is requested for this message.
+     * @param priority Priority level of the message
+     * @return a <code>SubmitPdu</code> containing the encoded SC
+     *         address, if applicable, and the encoded message.
+     *         Returns null on encode error.
+     */
+    public static SubmitPdu getSubmitPdu(String destAddr, UserData userData,
+            boolean statusReportRequested, int priority) {
+        return privateGetSubmitPdu(destAddr, statusReportRequested, userData, priority);
+    }
+
+    /**
      * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
      */
     @Override
@@ -764,6 +809,15 @@
      */
     private static SubmitPdu privateGetSubmitPdu(String destAddrStr, boolean statusReportRequested,
             UserData userData) {
+        return privateGetSubmitPdu(destAddrStr, statusReportRequested, userData, -1);
+    }
+
+    /**
+     * Creates BearerData and Envelope from parameters for a Submit SMS.
+     * @return byte stream for SubmitPdu.
+     */
+    private static SubmitPdu privateGetSubmitPdu(String destAddrStr, boolean statusReportRequested,
+            UserData userData, int priority) {
 
         /**
          * TODO(cleanup): give this function a more meaningful name.
@@ -792,6 +846,10 @@
         bearerData.userAckReq = false;
         bearerData.readAckReq = false;
         bearerData.reportReq = false;
+        if (priority >= PRIORITY_NORMAL && priority <= PRIORITY_EMERGENCY) {
+            bearerData.priorityIndicatorSet = true;
+            bearerData.priority = priority;
+        }
 
         bearerData.userData = userData;
 
diff --git a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
new file mode 100644
index 0000000..b3fc90d
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.euicc;
+
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.Bundle;
+import android.telephony.euicc.DownloadableSubscription;
+import android.telephony.euicc.EuiccInfo;
+
+/** @hide */
+interface IEuiccController {
+    oneway void continueOperation(in Intent resolutionIntent, in Bundle resolutionExtras);
+    oneway void getDownloadableSubscriptionMetadata(in DownloadableSubscription subscription,
+        String callingPackage, in PendingIntent callbackIntent);
+    oneway void getDefaultDownloadableSubscriptionList(
+        String callingPackage, in PendingIntent callbackIntent);
+    String getEid();
+    oneway void downloadSubscription(in DownloadableSubscription subscription,
+        boolean switchAfterDownload, String callingPackage, in PendingIntent callbackIntent);
+    EuiccInfo getEuiccInfo();
+    oneway void deleteSubscription(int subscriptionId, String callingPackage,
+        in PendingIntent callbackIntent);
+    oneway void switchToSubscription(int subscriptionId, String callingPackage,
+        in PendingIntent callbackIntent);
+    oneway void updateSubscriptionNickname(int subscriptionId, String nickname,
+        in PendingIntent callbackIntent);
+    oneway void eraseSubscriptions(in PendingIntent callbackIntent);
+    oneway void retainSubscriptionsForFactoryReset(in PendingIntent callbackIntent);
+}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java
index 2fbf7ed..bd8c83e 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony.gsm;
 
 import android.telephony.PhoneNumberUtils;
+
 import java.text.ParseException;
 import com.android.internal.telephony.GsmAlphabet;
 import com.android.internal.telephony.SmsAddress;
@@ -71,8 +72,11 @@
                 // Make sure the final unused BCD digit is 0xf
                 origBytes[length - 1] |= 0xf0;
             }
-            address = PhoneNumberUtils.calledPartyBCDToString(origBytes,
-                    OFFSET_TOA, length - OFFSET_TOA);
+            address = PhoneNumberUtils.calledPartyBCDToString(
+                    origBytes,
+                    OFFSET_TOA,
+                    length - OFFSET_TOA,
+                    PhoneNumberUtils.BCD_EXTENDED_TYPE_CALLED_PARTY);
 
             // And restore origBytes
             origBytes[length - 1] = lastByte;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
index f28d126..0fabc2f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
@@ -30,10 +30,6 @@
     /** Private constructor for utility class. */
     private SmsCbConstants() { }
 
-    /** Channel 50 required by Brazil. ID 0~999 is allocated by GSMA */
-    public static final int MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_50
-            = 0x0032;
-
     /** Start of PWS Message Identifier range (includes ETWS and CMAS). */
     public static final int MESSAGE_ID_PWS_FIRST_IDENTIFIER
             = 0x1100; // 4352
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index d4098d9..4f5bfa9 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -89,6 +89,18 @@
 
     private int mVoiceMailCount = 0;
 
+    private static final int VALIDITY_PERIOD_FORMAT_NONE = 0x00;
+    private static final int VALIDITY_PERIOD_FORMAT_ENHANCED = 0x01;
+    private static final int VALIDITY_PERIOD_FORMAT_RELATIVE = 0x02;
+    private static final int VALIDITY_PERIOD_FORMAT_ABSOLUTE = 0x03;
+
+    //Validity Period min - 5 mins
+    private static final int VALIDITY_PERIOD_MIN = 5;
+    //Validity Period max - 63 weeks
+    private static final int VALIDITY_PERIOD_MAX = 635040;
+
+    private static final int INVALID_VALIDITY_PERIOD = -1;
+
     public static class SubmitPdu extends SubmitPduBase {
     }
 
@@ -202,6 +214,45 @@
     }
 
     /**
+     * Get Encoded Relative Validty Period Value from Validity period in mins.
+     *
+     * @param validityPeriod Validity period in mins.
+     *
+     * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
+     * ||relValidityPeriod (TP-VP)  ||                 ||  validityPeriod   ||
+     *
+     *      0 to 143                            --->       (TP-VP + 1) x 5 minutes
+     *
+     *      144 to 167                         --->        12 hours + ((TP-VP -143) x 30 minutes)
+     *
+     *      168 to 196                         --->        (TP-VP - 166) x 1 day
+     *
+     *      197 to 255                         --->        (TP-VP - 192) x 1 week
+     *
+     * @return relValidityPeriod Encoded Relative Validity Period Value.
+     * @hide
+     */
+    public static int getRelativeValidityPeriod(int validityPeriod) {
+        int relValidityPeriod = INVALID_VALIDITY_PERIOD;
+
+        if (validityPeriod < VALIDITY_PERIOD_MIN  || validityPeriod > VALIDITY_PERIOD_MAX) {
+            Rlog.e(LOG_TAG,"Invalid Validity Period" + validityPeriod);
+            return relValidityPeriod;
+        }
+
+        if (validityPeriod <= 720) {
+            relValidityPeriod = (validityPeriod  / 5) - 1;
+        } else if (validityPeriod <= 1440) {
+            relValidityPeriod = ((validityPeriod - 720) / 30) + 143;
+        } else if (validityPeriod <= 43200) {
+            relValidityPeriod = (validityPeriod  / 1440) + 166;
+        } else if (validityPeriod <= 635040) {
+            relValidityPeriod = (validityPeriod  / 10080) + 192;
+        }
+        return relValidityPeriod;
+    }
+
+    /**
      * Get an SMS-SUBMIT PDU for a destination address and a message
      *
      * @param scAddress Service Centre address.  Null means use default.
@@ -236,6 +287,29 @@
             String destinationAddress, String message,
             boolean statusReportRequested, byte[] header, int encoding,
             int languageTable, int languageShiftTable) {
+        return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested,
+            header, encoding, languageTable, languageShiftTable, -1);
+    }
+
+    /**
+     * Get an SMS-SUBMIT PDU for a destination address and a message using the
+     * specified encoding.
+     *
+     * @param scAddress Service Centre address.  Null means use default.
+     * @param encoding Encoding defined by constants in
+     *        com.android.internal.telephony.SmsConstants.ENCODING_*
+     * @param languageTable
+     * @param languageShiftTable
+     * @param validityPeriod Validity Period of the message in Minutes.
+     * @return a <code>SubmitPdu</code> containing the encoded SC
+     *         address, if applicable, and the encoded message.
+     *         Returns null on encode error.
+     * @hide
+     */
+    public static SubmitPdu getSubmitPdu(String scAddress,
+            String destinationAddress, String message,
+            boolean statusReportRequested, byte[] header, int encoding,
+            int languageTable, int languageShiftTable, int validityPeriod) {
 
         // Perform null parameter checks.
         if (message == null || destinationAddress == null) {
@@ -272,8 +346,19 @@
         }
 
         SubmitPdu ret = new SubmitPdu();
-        // MTI = SMS-SUBMIT, UDHI = header != null
-        byte mtiByte = (byte)(0x01 | (header != null ? 0x40 : 0x00));
+
+        int validityPeriodFormat = VALIDITY_PERIOD_FORMAT_NONE;
+        int relativeValidityPeriod = INVALID_VALIDITY_PERIOD;
+
+        // TP-Validity-Period-Format (TP-VPF) in 3GPP TS 23.040 V6.8.1 section 9.2.3.3
+        //bit 4:3 = 10 - TP-VP field present - relative format
+        if((relativeValidityPeriod = getRelativeValidityPeriod(validityPeriod)) >= 0) {
+            validityPeriodFormat = VALIDITY_PERIOD_FORMAT_RELATIVE;
+        }
+
+        byte mtiByte = (byte)(0x01 | (validityPeriodFormat << 0x03) |
+                (header != null ? 0x40 : 0x00));
+
         ByteArrayOutputStream bo = getSubmitPduHead(
                 scAddress, destinationAddress, mtiByte,
                 statusReportRequested, ret);
@@ -338,7 +423,11 @@
             bo.write(0x08);
         }
 
-        // (no TP-Validity-Period)
+        if (validityPeriodFormat == VALIDITY_PERIOD_FORMAT_RELATIVE) {
+            // ( TP-Validity-Period - relative format)
+            bo.write(relativeValidityPeriod);
+        }
+
         bo.write(userData, 0, userData.length);
         ret.encodedMessage = bo.toByteArray();
         return ret;
@@ -388,6 +477,24 @@
     }
 
     /**
+     * Get an SMS-SUBMIT PDU for a destination address and a message
+     *
+     * @param scAddress Service Centre address.  Null means use default.
+     * @param destinationAddress the address of the destination for the message
+     * @param statusReportRequested staus report of the message Requested
+     * @param validityPeriod Validity Period of the message in Minutes.
+     * @return a <code>SubmitPdu</code> containing the encoded SC
+     *         address, if applicable, and the encoded message.
+     *         Returns null on encode error.
+     */
+    public static SubmitPdu getSubmitPdu(String scAddress,
+            String destinationAddress, String message,
+            boolean statusReportRequested, int validityPeriod) {
+        return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested,
+                null, ENCODING_UNKNOWN, 0, 0, validityPeriod);
+    }
+
+    /**
      * Get an SMS-SUBMIT PDU for a data message to a destination address &amp; port
      *
      * @param scAddress Service Centre address. null == use default
@@ -535,8 +642,8 @@
             } else {
                 // SC address
                 try {
-                    ret = PhoneNumberUtils
-                            .calledPartyBCDToString(mPdu, mCur, len);
+                    ret = PhoneNumberUtils.calledPartyBCDToString(
+                            mPdu, mCur, len, PhoneNumberUtils.BCD_EXTENDED_TYPE_CALLED_PARTY);
                 } catch (RuntimeException tr) {
                     Rlog.d(LOG_TAG, "invalid SC address: ", tr);
                     ret = null;
diff --git a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java
index 62d570c..99a82ad 100644
--- a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java
+++ b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java
@@ -567,4 +567,12 @@
         } while (valueIndex < endIndex);
         return result;
     }
+
+    public static String getDecimalSubstring(String iccId) {
+        int position;
+        for (position = 0; position < iccId.length(); position ++) {
+            if (!Character.isDigit(iccId.charAt(position))) break;
+        }
+        return iccId.substring( 0, position );
+    }
 }
diff --git a/test-runner/Android.mk b/test-runner/Android.mk
index 0752661..a642fdf 100644
--- a/test-runner/Android.mk
+++ b/test-runner/Android.mk
@@ -70,11 +70,10 @@
 
 LOCAL_SOURCE_FILES_ALL_GENERATED := true
 
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
 # Make sure to run droiddoc first to generate the stub source files.
-$(full_classes_compiled_jar) : $(android_test_mock_gen_stamp)
-$(full_classes_jack) : $(android_test_mock_gen_stamp)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(android_test_mock_gen_stamp)
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
 
 # Archive a copy of the classes.jar in SDK build.
 $(call dist-for-goals,sdk win_sdk,$(full_classes_jar):android.test.mock.jar)
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index 24e7bff..5e5ba46 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -149,6 +149,12 @@
         throw new UnsupportedOperationException();
     }
 
+    /** @hide */
+    @Override
+    public void reloadSharedPreferences() {
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public boolean moveSharedPreferencesFrom(Context sourceContext, String name) {
         throw new UnsupportedOperationException();
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index bcde519..3cb1f39 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -17,6 +17,7 @@
 package android.test.mock;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.PackageInstallObserver;
 import android.content.ComponentName;
 import android.content.Intent;
@@ -1168,4 +1169,13 @@
     public String getInstantAppAndroidId(String packageName, UserHandle user) {
         throw new UnsupportedOperationException();
     }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void registerDexModule(String dexModulePath,
+            @Nullable DexModuleRegisterCallback callback) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/tests/Internal/Android.mk b/tests/Internal/Android.mk
new file mode 100644
index 0000000..fc001e9
--- /dev/null
+++ b/tests/Internal/Android.mk
@@ -0,0 +1,23 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_USE_AAPT2 := true
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_PROTOC_OPTIMIZE_TYPE := nano
+
+# Include some source files directly to be able to access package members
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_STATIC_JAVA_LIBRARIES := junit \
+    legacy-android-test \
+    android-support-test \
+    mockito-target-minus-junit4
+
+LOCAL_CERTIFICATE := platform
+
+LOCAL_PACKAGE_NAME := InternalTests
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
+include $(BUILD_PACKAGE)
diff --git a/tests/Internal/AndroidManifest.xml b/tests/Internal/AndroidManifest.xml
new file mode 100644
index 0000000..a2c95fb
--- /dev/null
+++ b/tests/Internal/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?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
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.internal.tests">
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.internal.tests"
+                     android:label="Internal Tests" />
+</manifest>
diff --git a/tests/Internal/AndroidTest.xml b/tests/Internal/AndroidTest.xml
new file mode 100644
index 0000000..6531c93
--- /dev/null
+++ b/tests/Internal/AndroidTest.xml
@@ -0,0 +1,29 @@
+<?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
+  -->
+<configuration description="Runs tests for internal classes/utilities.">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="InternalTests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="framework-base-presubmit" />
+    <option name="test-tag" value="InternalTests" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.internal.tests" />
+        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/Internal/src/android/app/WallpaperColorsTest.java b/tests/Internal/src/android/app/WallpaperColorsTest.java
new file mode 100644
index 0000000..fb529b9
--- /dev/null
+++ b/tests/Internal/src/android/app/WallpaperColorsTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.app;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class WallpaperColorsTest {
+
+    @Test
+    public void supportsDarkTextOverrideTest() {
+        final Color color = Color.valueOf(Color.WHITE);
+        // Default should not support dark text!
+        WallpaperColors colors = new WallpaperColors(color, null, null, 0);
+        Assert.assertTrue("Default behavior is not to support dark text",
+                (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) == 0);
+
+        // Override it
+        colors = new WallpaperColors(color, null, null, WallpaperColors.HINT_SUPPORTS_DARK_TEXT);
+        Assert.assertFalse("Forcing dark text support doesn't work",
+                (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) == 0);
+    }
+
+    /**
+     * Sanity check to guarantee that white supports dark text and black doesn't
+     */
+    @Test
+    public void colorHintsTest() {
+        Bitmap image = Bitmap.createBitmap(30, 30, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(image);
+
+        canvas.drawColor(Color.WHITE);
+        int hints = WallpaperColors.fromBitmap(image).getColorHints();
+        boolean supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
+        boolean supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
+        Assert.assertTrue("White surface should support dark text", supportsDarkText);
+        Assert.assertFalse("White surface shouldn't support dark theme", supportsDarkTheme);
+
+        canvas.drawColor(Color.BLACK);
+        hints = WallpaperColors.fromBitmap(image).getColorHints();
+        supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
+        supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
+        Assert.assertFalse("Black surface shouldn't support dark text", supportsDarkText);
+        Assert.assertTrue("Black surface should support dark theme", supportsDarkTheme);
+
+        Paint paint = new Paint();
+        paint.setStyle(Paint.Style.FILL);
+        paint.setColor(Color.BLACK);
+        canvas.drawColor(Color.WHITE);
+        canvas.drawRect(0, 0, 8, 8, paint);
+        supportsDarkText = (WallpaperColors.fromBitmap(image)
+                .getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
+        Assert.assertFalse("Light surface shouldn't support dark text "
+                + "when it contains dark pixels", supportsDarkText);
+    }
+
+    /**
+     * WallpaperColors should not recycle bitmaps that it didn't create.
+     */
+    @Test
+    public void wallpaperRecycleBitmapTest() {
+        Bitmap image = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888);
+        WallpaperColors.fromBitmap(image);
+        Canvas canvas = new Canvas();
+        // This would crash:
+        canvas.drawBitmap(image, 0, 0, new Paint());
+    }
+}
diff --git a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
new file mode 100644
index 0000000..cb6a83d
--- /dev/null
+++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.internal.colorextraction;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Color;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.colorextraction.types.ExtractionType;
+import com.android.internal.colorextraction.types.Tonal;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests color extraction generation.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ColorExtractorTest {
+
+    Context mContext;
+
+    @Before
+    public void setup() {
+        mContext = InstrumentationRegistry.getContext();
+    }
+
+    @Test
+    public void ColorExtractor_extractWhenInitialized() {
+        ExtractionType type = mock(Tonal.class);
+        new ColorExtractor(mContext, type);
+        // 1 for lock and 1 for system
+        verify(type, times(2))
+                .extractInto(any(), any(), any(), any());
+    }
+
+    @Test
+    public void getColors_usesExtractedColors() {
+        GradientColors colorsExpectedNormal = new GradientColors();
+        colorsExpectedNormal.setMainColor(Color.RED);
+        colorsExpectedNormal.setSecondaryColor(Color.GRAY);
+
+        GradientColors colorsExpectedDark = new GradientColors();
+        colorsExpectedNormal.setMainColor(Color.BLACK);
+        colorsExpectedNormal.setSecondaryColor(Color.BLUE);
+
+        GradientColors colorsExpectedExtraDark = new GradientColors();
+        colorsExpectedNormal.setMainColor(Color.MAGENTA);
+        colorsExpectedNormal.setSecondaryColor(Color.GREEN);
+
+        ExtractionType type =
+                (inWallpaperColors, outGradientColorsNormal, outGradientColorsDark,
+                        outGradientColorsExtraDark) -> {
+                    outGradientColorsNormal.set(colorsExpectedNormal);
+                    outGradientColorsDark.set(colorsExpectedDark);
+                    outGradientColorsExtraDark.set(colorsExpectedExtraDark);
+                };
+        ColorExtractor extractor = new ColorExtractor(mContext, type);
+
+        GradientColors colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM,
+                ColorExtractor.TYPE_NORMAL);
+        assertEquals("Extracted colors not being used!", colors, colorsExpectedNormal);
+        colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM, ColorExtractor.TYPE_DARK);
+        assertEquals("Extracted colors not being used!", colors, colorsExpectedDark);
+        colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM, ColorExtractor.TYPE_EXTRA_DARK);
+        assertEquals("Extracted colors not being used!", colors, colorsExpectedExtraDark);
+    }
+
+    @Test
+    public void addOnColorsChangedListener_invokesListener() {
+        ColorExtractor.OnColorsChangedListener mockedListeners =
+                mock(ColorExtractor.OnColorsChangedListener.class);
+        ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext));
+        extractor.addOnColorsChangedListener(mockedListeners);
+
+        extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null),
+                WallpaperManager.FLAG_LOCK);
+        verify(mockedListeners, times(1)).onColorsChanged(any(),
+                eq(WallpaperManager.FLAG_LOCK));
+
+        extractor.removeOnColorsChangedListener(mockedListeners);
+        extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null),
+                WallpaperManager.FLAG_LOCK);
+        verifyNoMoreInteractions(mockedListeners);
+    }
+}
diff --git a/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
new file mode 100644
index 0000000..6dc9ba7
--- /dev/null
+++ b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.internal.colorextraction.types;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.app.WallpaperColors;
+import android.graphics.Color;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Range;
+
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.graphics.ColorUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+/**
+ * Tests tonal palette generation.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TonalTest {
+
+    @Test
+    public void extractInto_usesFallback() {
+        GradientColors normal = new GradientColors();
+        Tonal tonal = new Tonal(InstrumentationRegistry.getContext());
+        tonal.extractInto(null, normal, new GradientColors(),
+                new GradientColors());
+        assertFalse("Should use fallback color if WallpaperColors is null.",
+                normal.getMainColor() == Tonal.MAIN_COLOR_LIGHT);
+    }
+
+    @Test
+    public void extractInto_usesFallbackWhenTooLightOrDark() {
+        GradientColors normal = new GradientColors();
+        Tonal tonal = new Tonal(InstrumentationRegistry.getContext());
+        tonal.extractInto(new WallpaperColors(Color.valueOf(0xff000000), null, null, 0),
+                normal, new GradientColors(), new GradientColors());
+        assertTrue("Should use fallback color if WallpaperColors is too dark.",
+                normal.getMainColor() == Tonal.MAIN_COLOR_DARK);
+
+        tonal.extractInto(new WallpaperColors(Color.valueOf(0xffffffff), null, null,
+                        WallpaperColors.HINT_SUPPORTS_DARK_TEXT),
+                normal, new GradientColors(), new GradientColors());
+        assertTrue("Should use fallback color if WallpaperColors is too light.",
+                normal.getMainColor() == Tonal.MAIN_COLOR_LIGHT);
+    }
+
+    @Test
+    public void colorRange_containsColor() {
+        Tonal.ColorRange colorRange = new Tonal.ColorRange(new Range<>(0f, 50f),
+                new Range<>(0f, 1f), new Range<>(0f, 1f));
+        float[] hsl = new float[] {25, 0, 0};
+        assertTrue("Range " + colorRange + " doesn't contain " + Arrays.toString(hsl),
+                colorRange.containsColor(hsl[0], hsl[1], hsl[2]));
+    }
+
+    @Test
+    public void colorRange_doesntContainColor() {
+        Tonal.ColorRange colorRange = new Tonal.ColorRange(new Range<>(0f, 50f),
+                new Range<>(0f, 0.5f), new Range<>(0f, 0.5f));
+        float[] hsl = new float[] {100, 0, 0};
+        assertFalse("Range " + colorRange + " shouldn't contain " + Arrays.toString(hsl),
+                colorRange.containsColor(hsl[0], hsl[1], hsl[2]));
+        hsl = new float[] {0, 0.6f, 0};
+        assertFalse("Range " + colorRange + " shouldn't contain " + Arrays.toString(hsl),
+                colorRange.containsColor(hsl[0], hsl[1], hsl[2]));
+        hsl = new float[] {0, 0, 0.6f};
+        assertFalse("Range " + colorRange + " shouldn't contain " + Arrays.toString(hsl),
+                colorRange.containsColor(hsl[0], hsl[1], hsl[2]));
+    }
+
+    @Test
+    public void configParser_dataSanity() {
+        Tonal.ConfigParser config = new Tonal.ConfigParser(InstrumentationRegistry.getContext());
+        // 1 to avoid regression where only first item would be parsed.
+        assertTrue("Tonal palettes are empty", config.getTonalPalettes().size() > 1);
+        assertTrue("Blacklisted colors are empty", config.getBlacklistedColors().size() > 1);
+    }
+
+    @Test
+    public void tonal_excludeBlacklistedColor() {
+        // Make sure that palette generation will fail.
+        Tonal tonal = new Tonal(InstrumentationRegistry.getContext());
+
+        // Creating a WallpaperColors object that contains *only* blacklisted colors.
+        float[] hsl = tonal.getBlacklistedColors().get(0).getCenter();
+        WallpaperColors colors = new WallpaperColors(Color.valueOf(ColorUtils.HSLToColor(hsl)),
+                null, null, 0);
+
+        // Make sure that palette generation will fail
+        GradientColors normal = new GradientColors();
+        tonal.extractInto(colors, normal, new GradientColors(),
+                new GradientColors());
+        assertTrue("Cannot generate a tonal palette from blacklisted colors.",
+                normal.getMainColor() == Tonal.MAIN_COLOR_DARK);
+    }
+}
diff --git a/tests/Internal/src/com/android/internal/graphics/ColorUtilsTest.java b/tests/Internal/src/com/android/internal/graphics/ColorUtilsTest.java
new file mode 100644
index 0000000..73df9a0
--- /dev/null
+++ b/tests/Internal/src/com/android/internal/graphics/ColorUtilsTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.internal.graphics;
+
+import android.graphics.Color;
+import android.support.test.filters.SmallTest;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+@SmallTest
+public class ColorUtilsTest {
+
+    @Test
+    public void calculateMinimumBackgroundAlpha_satisfiestContrast() {
+
+        int alpha = ColorUtils.calculateMinimumBackgroundAlpha(Color.WHITE, Color.BLACK, 4.5f);
+        assertTrue("Alpha doesn't need to be 255 to satisfy contrast", alpha < 255);
+
+        int worstCase = ColorUtils.blendARGB(Color.WHITE, Color.BLACK, alpha/255f);
+        worstCase = ColorUtils.setAlphaComponent(worstCase, 255);
+        double contrast = ColorUtils.calculateContrast(Color.WHITE, worstCase);
+        assertTrue("Blended color should satisfy contrast", contrast >= 4.5);
+
+    }
+}
diff --git a/tests/Internal/src/com/android/internal/ml/clustering/KMeansTest.java b/tests/Internal/src/com/android/internal/ml/clustering/KMeansTest.java
new file mode 100644
index 0000000..a64f8a6
--- /dev/null
+++ b/tests/Internal/src/com/android/internal/ml/clustering/KMeansTest.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.ml.clustering;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.annotation.SuppressLint;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class KMeansTest {
+
+    // Error tolerance (epsilon)
+    private static final double EPS = 0.01;
+
+    private KMeans mKMeans;
+
+    @Before
+    public void setUp() {
+        // Setup with a random seed to have predictable results
+        mKMeans = new KMeans(new Random(0), 30, 0);
+    }
+
+    @Test
+    public void getCheckDataSanityTest() {
+        try {
+            mKMeans.checkDataSetSanity(new float[][] {
+                    {0, 1, 2},
+                    {1, 2, 3}
+            });
+        } catch (IllegalArgumentException e) {
+            Assert.fail("Valid data didn't pass sanity check");
+        }
+
+        try {
+            mKMeans.checkDataSetSanity(new float[][] {
+                    null,
+                    {1, 2, 3}
+            });
+            Assert.fail("Data has null items and passed");
+        } catch (IllegalArgumentException e) {}
+
+        try {
+            mKMeans.checkDataSetSanity(new float[][] {
+                    {0, 1, 2, 4},
+                    {1, 2, 3}
+            });
+            Assert.fail("Data has invalid shape and passed");
+        } catch (IllegalArgumentException e) {}
+
+        try {
+            mKMeans.checkDataSetSanity(null);
+            Assert.fail("Null data should throw exception");
+        } catch (IllegalArgumentException e) {}
+    }
+
+    @Test
+    public void sqDistanceTest() {
+        float a[] = {4, 10};
+        float b[] = {5, 2};
+        float sqDist = (float) (Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2));
+
+        assertEquals("Squared distance not valid", mKMeans.sqDistance(a, b), sqDist, EPS);
+    }
+
+    @Test
+    public void nearestMeanTest() {
+        KMeans.Mean meanA = new KMeans.Mean(0, 1);
+        KMeans.Mean meanB = new KMeans.Mean(1, 1);
+        List<KMeans.Mean> means = Arrays.asList(meanA, meanB);
+
+        KMeans.Mean nearest = mKMeans.nearestMean(new float[] {1, 1}, means);
+
+        assertEquals("Unexpected nearest mean for point {1, 1}", nearest, meanB);
+    }
+
+    @SuppressLint("DefaultLocale")
+    @Test
+    public void scoreTest() {
+        List<KMeans.Mean> closeMeans = Arrays.asList(new KMeans.Mean(0, 0.1f, 0.1f),
+                new KMeans.Mean(0, 0.1f, 0.15f),
+                new KMeans.Mean(0.1f, 0.2f, 0.1f));
+        List<KMeans.Mean> farMeans = Arrays.asList(new KMeans.Mean(0, 0, 0),
+                new KMeans.Mean(0, 0.5f, 0.5f),
+                new KMeans.Mean(1, 0.9f, 0.9f));
+
+        double closeScore = KMeans.score(closeMeans);
+        double farScore = KMeans.score(farMeans);
+        assertTrue(String.format("Score of well distributed means should be greater than "
+                + "close means but got: %f, %f", farScore, closeScore), farScore > closeScore);
+    }
+
+    @Test
+    public void predictTest() {
+        float[] expectedCentroid1 = {1, 1, 1};
+        float[] expectedCentroid2 = {0, 0, 0};
+        float[][] X = new float[][] {
+                {1, 1, 1},
+                {1, 1, 1},
+                {1, 1, 1},
+                {0, 0, 0},
+                {0, 0, 0},
+                {0, 0, 0},
+        };
+
+        final int numClusters = 2;
+
+        // Here we assume that we won't get stuck into a local optima.
+        // It's fine because we're seeding a random, we won't ever have
+        // unstable results but in real life we need multiple initialization
+        // and score comparison
+        List<KMeans.Mean> means = mKMeans.predict(numClusters, X);
+
+        assertEquals("Expected number of clusters is invalid", numClusters, means.size());
+
+        boolean exists1 = false, exists2 = false;
+        for (KMeans.Mean mean : means) {
+            if (Arrays.equals(mean.getCentroid(), expectedCentroid1)) {
+                exists1 = true;
+            } else if (Arrays.equals(mean.getCentroid(), expectedCentroid2)) {
+                exists2 = true;
+            } else {
+                throw new AssertionError("Unexpected mean: " + mean);
+            }
+        }
+        assertTrue("Expected means were not predicted, got: " + means,
+                exists1 && exists2);
+    }
+}
diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
index b550cfa..00bf33a 100644
--- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
+++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
@@ -689,8 +689,20 @@
         AudioFormat format =  event.getCaptureAudioFormat();
         result = result + "AudioFormat: " + ((format == null) ? "null" : format.toString());
         byte[] triggerAudio = event.getTriggerAudio();
-        result = result + "TriggerAudio: " + (triggerAudio == null ? "null" : triggerAudio.length);
-        result = result + "CaptureSession: " + event.getCaptureSession();
+        result = result + ", TriggerAudio: " + (triggerAudio == null ? "null" : triggerAudio.length);
+        byte[] data = event.getData();
+        result = result + ", Data: " + (data == null ? "null" : data.length);
+        if (data != null) {
+          try {
+            String decodedData = new String(data, "UTF-8");
+            if (decodedData.chars().allMatch(c -> (c >= 32 && c < 128) || c == 0)) {
+                result = result + ", Decoded Data: '" + decodedData + "'";
+            }
+          } catch (Exception e) {
+            Log.e(TAG, "Failed to decode data");
+          }
+        }
+        result = result + ", CaptureSession: " + event.getCaptureSession();
         result += " )";
         return result;
     }
diff --git a/tests/StatusBar/AndroidManifest.xml b/tests/StatusBar/AndroidManifest.xml
index 81442bf..6a082e9 100644
--- a/tests/StatusBar/AndroidManifest.xml
+++ b/tests/StatusBar/AndroidManifest.xml
@@ -6,6 +6,7 @@
     <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
     <uses-permission android:name="android.permission.VIBRATE" />
     <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
+    <uses-permission android:name="android.permission.MANAGE_NOTIFICATIONS" />
 
     <application>
         <activity android:name="StatusBarTest" android:label="_StatusBar">
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 5dd42dd..8210403 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -62,16 +62,16 @@
     boolean mProgressDone = true;
 
     final int[] kNumberedIconResIDs = {
-        R.drawable.notification0,
-        R.drawable.notification1,
-        R.drawable.notification2,
-        R.drawable.notification3,
-        R.drawable.notification4,
-        R.drawable.notification5,
-        R.drawable.notification6,
-        R.drawable.notification7,
-        R.drawable.notification8,
-        R.drawable.notification9
+            R.drawable.notification0,
+            R.drawable.notification1,
+            R.drawable.notification2,
+            R.drawable.notification3,
+            R.drawable.notification4,
+            R.drawable.notification5,
+            R.drawable.notification6,
+            R.drawable.notification7,
+            R.drawable.notification8,
+            R.drawable.notification9
     };
     final int kUnnumberedIconResID = R.drawable.notificationx;
 
@@ -129,6 +129,42 @@
                     mNM.notify(7001, n);
                 }
             },
+            new Test("with zen") {
+                public void run()
+                {
+                    mNM.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALARMS);
+                    Notification n = new Notification.Builder(NotificationTestList.this,
+                            "default")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setContentTitle("Default priority")
+                            .build();
+                    mNM.notify("default", 7004, n);
+                    try {
+                        Thread.sleep(8000);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    mNM.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL);
+                }
+            },
+            new Test("repeated") {
+                public void run()
+                {
+                    for (int i = 0; i < 50; i++) {
+                        Notification n = new Notification.Builder(NotificationTestList.this,
+                                "default")
+                                .setSmallIcon(R.drawable.icon2)
+                                .setContentTitle("Default priority")
+                                .build();
+                        mNM.notify("default", 7004, n);
+                        try {
+                            Thread.sleep(100);
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            },
             new Test("Post a group") {
                 public void run()
                 {
@@ -402,85 +438,85 @@
                     mNM.notify("cancel_madness", 7014, n);
                 }
             },
-        new Test("Off") {
-            public void run() {
-                PowerManager pm = (PowerManager) NotificationTestList.this.getSystemService(
-                        Context.POWER_SERVICE);
-                PowerManager.WakeLock wl = 
+            new Test("Off") {
+                public void run() {
+                    PowerManager pm = (PowerManager) NotificationTestList.this.getSystemService(
+                            Context.POWER_SERVICE);
+                    PowerManager.WakeLock wl =
                             pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "sound");
-                wl.acquire();
+                    wl.acquire();
 
-                pm.goToSleep(SystemClock.uptimeMillis());
+                    pm.goToSleep(SystemClock.uptimeMillis());
 
-                Notification n = new Notification.Builder(NotificationTestList.this, "default")
-                        .setSmallIcon(R.drawable.stat_sys_phone)
-                        .setContentTitle(name)
-                        .build();
-                Log.d(TAG, "n.sound=" + n.sound);
+                    Notification n = new Notification.Builder(NotificationTestList.this, "default")
+                            .setSmallIcon(R.drawable.stat_sys_phone)
+                            .setContentTitle(name)
+                            .build();
+                    Log.d(TAG, "n.sound=" + n.sound);
 
-                mNM.notify(1, n);
+                    mNM.notify(1, n);
 
-                Log.d(TAG, "releasing wake lock");
-                wl.release();
-                Log.d(TAG, "released wake lock");
-            }
-        },
+                    Log.d(TAG, "releasing wake lock");
+                    wl.release();
+                    Log.d(TAG, "released wake lock");
+                }
+            },
 
-        new Test("Cancel #1") {
-            public void run()
-            {
-                mNM.cancel(1);
-            }
-        },
+            new Test("Cancel #1") {
+                public void run()
+                {
+                    mNM.cancel(1);
+                }
+            },
 
-        new Test("Custom Button") {
-            public void run() {
-                RemoteViews view = new RemoteViews(getPackageName(), R.layout.button_notification);
-                view.setOnClickPendingIntent(R.id.button, makeIntent2());
-                Notification n = new Notification.Builder(NotificationTestList.this, "default")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle(name)
-                        .setOngoing(true)
-                        .setCustomContentView(view)
-                        .build();
+            new Test("Custom Button") {
+                public void run() {
+                    RemoteViews view = new RemoteViews(getPackageName(), R.layout.button_notification);
+                    view.setOnClickPendingIntent(R.id.button, makeIntent2());
+                    Notification n = new Notification.Builder(NotificationTestList.this, "default")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle(name)
+                            .setOngoing(true)
+                            .setCustomContentView(view)
+                            .build();
 
-                mNM.notify(1, n);
-            }
-        },
+                    mNM.notify(1, n);
+                }
+            },
 
-        new Test("Action Button") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "default")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle(name)
-                        .setOngoing(true)
-                        .addAction(new Notification.Action.Builder(
-                                Icon.createWithResource(NotificationTestList.this,
-                                        R.drawable.ic_statusbar_chat),
-                                "Button", makeIntent2())
-                                .build())
-                        .build();
+            new Test("Action Button") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "default")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle(name)
+                            .setOngoing(true)
+                            .addAction(new Notification.Action.Builder(
+                                    Icon.createWithResource(NotificationTestList.this,
+                                            R.drawable.ic_statusbar_chat),
+                                    "Button", makeIntent2())
+                                    .build())
+                            .build();
 
-                mNM.notify(1, n);
-            }
-        },
+                    mNM.notify(1, n);
+                }
+            },
 
-        new Test("with intent") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "default")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle("Persistent #1")
-                        .setContentText("This is a notification!!!")
-                        .setContentIntent(makeIntent2())
-                        .setOngoing(true)
-                        .build();
+            new Test("with intent") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "default")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle("Persistent #1")
+                            .setContentText("This is a notification!!!")
+                            .setContentIntent(makeIntent2())
+                            .setOngoing(true)
+                            .build();
 
-                mNM.notify(1, n);
-            }
-        },
+                    mNM.notify(1, n);
+                }
+            },
 
             new Test("Is blocked?") {
                 public void run() {
@@ -498,484 +534,484 @@
                 }
             },
 
-        new Test("Whens") {
-            public void run()
-            {
-                Notification.Builder n = new Notification.Builder(
-                        NotificationTestList.this, "default")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setContentTitle(name)
-                        .setOngoing(true);
+            new Test("Whens") {
+                public void run()
+                {
+                    Notification.Builder n = new Notification.Builder(
+                            NotificationTestList.this, "default")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setContentTitle(name)
+                            .setOngoing(true);
 
-                mNM.notify(1, n.setContentTitle("(453) 123-2328")
-                .setWhen(System.currentTimeMillis()-(1000*60*60*24))
-                .build());
+                    mNM.notify(1, n.setContentTitle("(453) 123-2328")
+                            .setWhen(System.currentTimeMillis()-(1000*60*60*24))
+                            .build());
 
-                mNM.notify(1, n.setContentTitle("Mark Willem, Me (2)")
-                .setWhen(System.currentTimeMillis())
-                .build());
+                    mNM.notify(1, n.setContentTitle("Mark Willem, Me (2)")
+                            .setWhen(System.currentTimeMillis())
+                            .build());
 
-                mNM.notify(1, n.setContentTitle("Sophia Winterlanden")
-                        .setWhen(System.currentTimeMillis() + (1000 * 60 * 60 * 24))
-                        .build());
-            }
-        },
-
-        new Test("Bad Icon #1 (when=create)") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.layout.chrono_notification /* not an icon */)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle("Persistent #1")
-                        .setContentText("This is the same notification!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Bad Icon #1 (when=now)") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.layout.chrono_notification /* not an icon */)
-                        .setWhen(System.currentTimeMillis())
-                        .setContentTitle("Persistent #1")
-                        .setContentText("This is the same notification!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Null Icon #1 (when=now)") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(0)
-                        .setWhen(System.currentTimeMillis())
-                        .setContentTitle("Persistent #1")
-                        .setContentText("This is the same notification!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Bad resource #1 (when=create)") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.drawable.icon2)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle("Persistent #1")
-                        .setContentText("This is the same notification!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                n.contentView.setInt(1 /*bogus*/, "bogus method", 666);
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Bad resource #1 (when=now)") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.drawable.icon2)
-                        .setWhen(System.currentTimeMillis())
-                        .setContentTitle("Persistent #1")
-                        .setContentText("This is the same notification!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                n.contentView.setInt(1 /*bogus*/, "bogus method", 666);
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Times") {
-            public void run()
-            {
-                long now = System.currentTimeMillis();
-
-                timeNotification(7, "24 hours from now", now+(1000*60*60*24));
-                timeNotification(6, "12:01:00 from now", now+(1000*60*60*12)+(60*1000));
-                timeNotification(5, "12 hours from now", now+(1000*60*60*12));
-                timeNotification(4, "now", now);
-                timeNotification(3, "11:59:00 ago", now-((1000*60*60*12)-(60*1000)));
-                timeNotification(2, "12 hours ago", now-(1000*60*60*12));
-                timeNotification(1, "24 hours ago", now-(1000*60*60*24));
-            }
-        },
-        new StateStress("Stress - Ongoing / Latest", 100, 100, new Runnable[] {
-                new Runnable() {
-                    public void run() {
-                        Log.d(TAG, "Stress - Ongoing/Latest 0");
-                        Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                                .setSmallIcon(R.drawable.icon3)
-                                .setWhen(System.currentTimeMillis())
-                                .setContentTitle("Stress - Ongoing")
-                                .setContentText("Notify me!!!")
-                                .setOngoing(true)
-                                .build();
-                        mNM.notify(1, n);
-                    }
-                },
-                new Runnable() {
-                    public void run() {
-                        Log.d(TAG, "Stress - Ongoing/Latest 1");
-                        Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                                .setSmallIcon(R.drawable.icon4)
-                                .setWhen(System.currentTimeMillis())
-                                .setContentTitle("Stress - Latest")
-                                .setContentText("Notify me!!!")
-                                .build();
-                        mNM.notify(1, n);
-                    }
+                    mNM.notify(1, n.setContentTitle("Sophia Winterlanden")
+                            .setWhen(System.currentTimeMillis() + (1000 * 60 * 60 * 24))
+                            .build());
                 }
-            }),
+            },
 
-        new Test("Long") {
-            public void run()
-            {
-                NotificationChannel channel = new NotificationChannel("v. noisy",
-                        "channel for sound and a custom vibration", IMPORTANCE_DEFAULT);
-                channel.enableVibration(true);
-                channel.setVibrationPattern(new long[] {
-                        300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400,
-                        300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400,
-                        300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400 });
-                mNM.createNotificationChannel(channel);
+            new Test("Bad Icon #1 (when=create)") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.layout.chrono_notification /* not an icon */)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle("Persistent #1")
+                            .setContentText("This is the same notification!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-                Notification n = new Notification.Builder(NotificationTestList.this, "v. noisy")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setContentTitle(name)
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
+            new Test("Bad Icon #1 (when=now)") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.layout.chrono_notification /* not an icon */)
+                            .setWhen(System.currentTimeMillis())
+                            .setContentTitle("Persistent #1")
+                            .setContentText("This is the same notification!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-        new Test("Progress #1") {
-            public void run() {
-                final boolean PROGRESS_UPDATES_WHEN = true;
-                if (!mProgressDone) return;
-                mProgressDone = false;
-                Thread t = new Thread() {
-                    public void run() {
-                        int x = 0;
-                        final Notification.Builder n = new Notification.Builder(
-                                NotificationTestList.this, "low")
-                                .setSmallIcon(R.drawable.icon1)
-                                .setContentTitle(name)
-                                .setOngoing(true);
+            new Test("Null Icon #1 (when=now)") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(0)
+                            .setWhen(System.currentTimeMillis())
+                            .setContentTitle("Persistent #1")
+                            .setContentText("This is the same notification!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-                        while (!mProgressDone) {
-                            n.setWhen(PROGRESS_UPDATES_WHEN
-                                    ? System.currentTimeMillis()
-                                    : mActivityCreateTime);
-                            n.setProgress(100, x, false);
-                            n.setContentText("Progress: " + x + "%");
+            new Test("Bad resource #1 (when=create)") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle("Persistent #1")
+                            .setContentText("This is the same notification!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    n.contentView.setInt(1 /*bogus*/, "bogus method", 666);
+                    mNM.notify(1, n);
+                }
+            },
 
-                            mNM.notify(500, n.build());
-                            x = (x + 7) % 100;
+            new Test("Bad resource #1 (when=now)") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setWhen(System.currentTimeMillis())
+                            .setContentTitle("Persistent #1")
+                            .setContentText("This is the same notification!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    n.contentView.setInt(1 /*bogus*/, "bogus method", 666);
+                    mNM.notify(1, n);
+                }
+            },
 
-                            try {
-                                Thread.sleep(1000);
-                            } catch (InterruptedException e) {
-                                break;
-                            }
+            new Test("Times") {
+                public void run()
+                {
+                    long now = System.currentTimeMillis();
+
+                    timeNotification(7, "24 hours from now", now+(1000*60*60*24));
+                    timeNotification(6, "12:01:00 from now", now+(1000*60*60*12)+(60*1000));
+                    timeNotification(5, "12 hours from now", now+(1000*60*60*12));
+                    timeNotification(4, "now", now);
+                    timeNotification(3, "11:59:00 ago", now-((1000*60*60*12)-(60*1000)));
+                    timeNotification(2, "12 hours ago", now-(1000*60*60*12));
+                    timeNotification(1, "24 hours ago", now-(1000*60*60*24));
+                }
+            },
+            new StateStress("Stress - Ongoing / Latest", 100, 100, new Runnable[] {
+                    new Runnable() {
+                        public void run() {
+                            Log.d(TAG, "Stress - Ongoing/Latest 0");
+                            Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                                    .setSmallIcon(R.drawable.icon3)
+                                    .setWhen(System.currentTimeMillis())
+                                    .setContentTitle("Stress - Ongoing")
+                                    .setContentText("Notify me!!!")
+                                    .setOngoing(true)
+                                    .build();
+                            mNM.notify(1, n);
+                        }
+                    },
+                    new Runnable() {
+                        public void run() {
+                            Log.d(TAG, "Stress - Ongoing/Latest 1");
+                            Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                                    .setSmallIcon(R.drawable.icon4)
+                                    .setWhen(System.currentTimeMillis())
+                                    .setContentTitle("Stress - Latest")
+                                    .setContentText("Notify me!!!")
+                                    .build();
+                            mNM.notify(1, n);
                         }
                     }
-                };
-                t.start();
-            }
-        },
+            }),
 
-        new Test("Stop Progress") {
-            public void run() {
-                mProgressDone = true;
-                mNM.cancel(500);
-            }
-        },
+            new Test("Long") {
+                public void run()
+                {
+                    NotificationChannel channel = new NotificationChannel("v. noisy",
+                            "channel for sound and a custom vibration", IMPORTANCE_DEFAULT);
+                    channel.enableVibration(true);
+                    channel.setVibrationPattern(new long[] {
+                            300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400,
+                            300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400,
+                            300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400 });
+                    mNM.createNotificationChannel(channel);
 
-        new Test("Blue Lights") {
-            public void run()
-            {
-                NotificationChannel channel = new NotificationChannel("blue",
-                        "blue", IMPORTANCE_DEFAULT);
-                channel.enableLights(true);
-                channel.setLightColor(0xff0000ff);
-                mNM.createNotificationChannel(channel);
+                    Notification n = new Notification.Builder(NotificationTestList.this, "v. noisy")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setContentTitle(name)
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-                Notification n = new Notification.Builder(NotificationTestList.this, "blue")
-                        .setSmallIcon(R.drawable.icon2)
-                        .setContentTitle(name)
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
+            new Test("Progress #1") {
+                public void run() {
+                    final boolean PROGRESS_UPDATES_WHEN = true;
+                    if (!mProgressDone) return;
+                    mProgressDone = false;
+                    Thread t = new Thread() {
+                        public void run() {
+                            int x = 0;
+                            final Notification.Builder n = new Notification.Builder(
+                                    NotificationTestList.this, "low")
+                                    .setSmallIcon(R.drawable.icon1)
+                                    .setContentTitle(name)
+                                    .setOngoing(true);
 
-        new Test("Red Lights") {
-            public void run()
-            {
-                NotificationChannel channel = new NotificationChannel("red",
-                        "red", IMPORTANCE_DEFAULT);
-                channel.enableLights(true);
-                channel.setLightColor(0xffff0000);
-                mNM.createNotificationChannel(channel);
+                            while (!mProgressDone) {
+                                n.setWhen(PROGRESS_UPDATES_WHEN
+                                        ? System.currentTimeMillis()
+                                        : mActivityCreateTime);
+                                n.setProgress(100, x, false);
+                                n.setContentText("Progress: " + x + "%");
 
-                Notification n = new Notification.Builder(NotificationTestList.this, "red")
-                        .setSmallIcon(R.drawable.icon2)
-                        .setContentTitle(name)
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
+                                mNM.notify(500, n.build());
+                                x = (x + 7) % 100;
 
-        new Test("Lights off") {
-            public void run()
-            {
-                Notification n = new Notification.Builder(NotificationTestList.this, "default")
-                        .setSmallIcon(R.drawable.icon2)
-                        .setContentTitle(name)
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Alert once") {
-            public void run()
-            {
-                Notification n = new Notification.Builder(NotificationTestList.this, "high")
-                        .setSmallIcon(R.drawable.icon2)
-                        .setContentTitle(name)
-                        .setOnlyAlertOnce(true)
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Resource Sound") {
-            public void run()
-            {
-                NotificationChannel channel = new NotificationChannel("res_sound",
-                        "resource sound", IMPORTANCE_DEFAULT);
-                channel.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
-                        getPackageName() + "/raw/ringer"), Notification.AUDIO_ATTRIBUTES_DEFAULT);
-                mNM.createNotificationChannel(channel);
-
-                Notification n = new Notification.Builder(NotificationTestList.this, "res_sound")
-                        .setSmallIcon(R.drawable.stat_sys_phone)
-                        .setContentTitle(name)
-                        .build();
-                Log.d(TAG, "n.sound=" + n.sound);
-
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Sound and Cancel") {
-            public void run()
-            {
-                NotificationChannel channel = new NotificationChannel("res_sound",
-                        "resource sound", IMPORTANCE_DEFAULT);
-                channel.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
-                        getPackageName() + "/raw/ringer"), Notification.AUDIO_ATTRIBUTES_DEFAULT);
-                mNM.createNotificationChannel(channel);
-
-                Notification n = new Notification.Builder(NotificationTestList.this, "res_sound")
-                        .setSmallIcon(R.drawable.stat_sys_phone)
-                        .setContentTitle(name)
-                        .build();
-
-                mNM.notify(1, n);
-                SystemClock.sleep(600);
-                mNM.cancel(1);
-            }
-        },
-
-        new Test("Vibrate and cancel") {
-            public void run()
-            {
-                NotificationChannel channel = new NotificationChannel("vibrate",
-                        "vibrate", IMPORTANCE_DEFAULT);
-                channel.enableVibration(true);
-                channel.setVibrationPattern(new long[] {0, 700, 500, 1000, 0, 700, 500, 1000,
-                        0, 700, 500, 1000, 0, 700, 500, 1000, 0, 700, 500, 1000, 0, 700, 500, 1000,
-                        0, 700, 500, 1000, 0, 700, 500, 1000});
-                mNM.createNotificationChannel(channel);
-
-                Notification n = new Notification.Builder(NotificationTestList.this, "vibrate")
-                        .setSmallIcon(R.drawable.stat_sys_phone)
-                        .setContentTitle(name)
-                        .build();
-
-                mNM.notify(1, n);
-                SystemClock.sleep(500);
-                mNM.cancel(1);
-            }
-        },
-
-        new Test("Vibrate pattern") {
-            public void run()
-            {
-                mVibrator.vibrate(new long[] { 250, 1000, 500, 2000 }, -1);
-            }
-        },
-
-        new Test("Vibrate pattern repeating") {
-            public void run()
-            {
-                mVibrator.vibrate(new long[] { 250, 1000, 500 }, 1);
-            }
-        },
-
-        new Test("Vibrate 3s") {
-            public void run()
-            {
-                mVibrator.vibrate(3000);
-            }
-        },
-
-        new Test("Vibrate 100s") {
-            public void run()
-            {
-                mVibrator.vibrate(100000);
-            }
-        },
-
-        new Test("Vibrate off") {
-            public void run()
-            {
-                mVibrator.cancel();
-            }
-        },
-
-        new Test("Cancel #1") {
-            public void run() {
-                mNM.cancel(1);
-            }
-        },
-
-        new Test("Cancel #1 in 3 sec") {
-            public void run() {
-                mHandler.postDelayed(new Runnable() {
-                            public void run() {
-                                Log.d(TAG, "Cancelling now...");
-                                mNM.cancel(1);
+                                try {
+                                    Thread.sleep(1000);
+                                } catch (InterruptedException e) {
+                                    break;
+                                }
                             }
-                        }, 3000);
-            }
-        },
+                        }
+                    };
+                    t.start();
+                }
+            },
 
-        new Test("Cancel #2") {
-            public void run() {
-                mNM.cancel(2);
-            }
-        },
+            new Test("Stop Progress") {
+                public void run() {
+                    mProgressDone = true;
+                    mNM.cancel(500);
+                }
+            },
 
-        new Test("Persistent #1") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this)
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle(name)
-                        .setContentText("This is a notification!!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
+            new Test("Blue Lights") {
+                public void run()
+                {
+                    NotificationChannel channel = new NotificationChannel("blue",
+                            "blue", IMPORTANCE_DEFAULT);
+                    channel.enableLights(true);
+                    channel.setLightColor(0xff0000ff);
+                    mNM.createNotificationChannel(channel);
 
-        new Test("Persistent #1 in 3 sec") {
-            public void run() {
-                mHandler.postDelayed(new Runnable() {
-                            public void run() {
-                                String message = "            "
-                                        + "tick tock tick tock\n\nSometimes notifications can "
-                                        + "be really long and wrap to more than one line.\n"
-                                        + "Sometimes."
-                                        + "Ohandwhathappensifwehaveonereallylongstringarewesure"
-                                        + "thatwesegmentitcorrectly?\n";
-                                Notification n = new Notification.Builder(
-                                        NotificationTestList.this, "low")
-                                        .setSmallIcon(R.drawable.icon1)
-                                        .setContentTitle(name)
-                                        .setContentText("This is still a notification!!!")
-                                        .setContentIntent(makeIntent())
-                                        .setStyle(new Notification.BigTextStyle().bigText(message))
-                                        .build();
-                                mNM.notify(1, n);
-                            }
-                        }, 3000);
-            }
-        },
+                    Notification n = new Notification.Builder(NotificationTestList.this, "blue")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setContentTitle(name)
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-        new Test("Persistent #2") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle(name)
-                        .setContentText("This is a notification!!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                mNM.notify(2, n);
-            }
-        },
+            new Test("Red Lights") {
+                public void run()
+                {
+                    NotificationChannel channel = new NotificationChannel("red",
+                            "red", IMPORTANCE_DEFAULT);
+                    channel.enableLights(true);
+                    channel.setLightColor(0xffff0000);
+                    mNM.createNotificationChannel(channel);
 
-        new Test("Persistent #3") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle(name)
-                        .setContentText("This is a notification!!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                mNM.notify(3, n);
-            }
-        },
+                    Notification n = new Notification.Builder(NotificationTestList.this, "red")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setContentTitle(name)
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-        new Test("Persistent #2 Vibrate") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle(name)
-                        .setContentText("This is a notification!!!")
-                        .setContentIntent(makeIntent())
-                        .setDefaults(Notification.DEFAULT_VIBRATE)
-                        .build();
-                mNM.notify(2, n);
-            }
-        },
+            new Test("Lights off") {
+                public void run()
+                {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "default")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setContentTitle(name)
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-        new Test("Persistent #1 - different icon") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.drawable.icon2)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle(name)
-                        .setContentText("This is a notification!!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
+            new Test("Alert once") {
+                public void run()
+                {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "high")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setContentTitle(name)
+                            .setOnlyAlertOnce(true)
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-        new Test("Chronometer Start") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(System.currentTimeMillis())
-                        .setContentTitle(name)
-                        .setContentIntent(makeIntent())
-                        .setOngoing(true)
-                        .setUsesChronometer(true)
-                        .build();
-                mNM.notify(2, n);
-            }
-        },
+            new Test("Resource Sound") {
+                public void run()
+                {
+                    NotificationChannel channel = new NotificationChannel("res_sound",
+                            "resource sound", IMPORTANCE_DEFAULT);
+                    channel.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
+                            getPackageName() + "/raw/ringer"), Notification.AUDIO_ATTRIBUTES_DEFAULT);
+                    mNM.createNotificationChannel(channel);
 
-        new Test("Chronometer Stop") {
-            public void run() {
-                mHandler.postDelayed(new Runnable() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "res_sound")
+                            .setSmallIcon(R.drawable.stat_sys_phone)
+                            .setContentTitle(name)
+                            .build();
+                    Log.d(TAG, "n.sound=" + n.sound);
+
+                    mNM.notify(1, n);
+                }
+            },
+
+            new Test("Sound and Cancel") {
+                public void run()
+                {
+                    NotificationChannel channel = new NotificationChannel("res_sound",
+                            "resource sound", IMPORTANCE_DEFAULT);
+                    channel.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
+                            getPackageName() + "/raw/ringer"), Notification.AUDIO_ATTRIBUTES_DEFAULT);
+                    mNM.createNotificationChannel(channel);
+
+                    Notification n = new Notification.Builder(NotificationTestList.this, "res_sound")
+                            .setSmallIcon(R.drawable.stat_sys_phone)
+                            .setContentTitle(name)
+                            .build();
+
+                    mNM.notify(1, n);
+                    SystemClock.sleep(600);
+                    mNM.cancel(1);
+                }
+            },
+
+            new Test("Vibrate and cancel") {
+                public void run()
+                {
+                    NotificationChannel channel = new NotificationChannel("vibrate",
+                            "vibrate", IMPORTANCE_DEFAULT);
+                    channel.enableVibration(true);
+                    channel.setVibrationPattern(new long[] {0, 700, 500, 1000, 0, 700, 500, 1000,
+                            0, 700, 500, 1000, 0, 700, 500, 1000, 0, 700, 500, 1000, 0, 700, 500, 1000,
+                            0, 700, 500, 1000, 0, 700, 500, 1000});
+                    mNM.createNotificationChannel(channel);
+
+                    Notification n = new Notification.Builder(NotificationTestList.this, "vibrate")
+                            .setSmallIcon(R.drawable.stat_sys_phone)
+                            .setContentTitle(name)
+                            .build();
+
+                    mNM.notify(1, n);
+                    SystemClock.sleep(500);
+                    mNM.cancel(1);
+                }
+            },
+
+            new Test("Vibrate pattern") {
+                public void run()
+                {
+                    mVibrator.vibrate(new long[] { 250, 1000, 500, 2000 }, -1);
+                }
+            },
+
+            new Test("Vibrate pattern repeating") {
+                public void run()
+                {
+                    mVibrator.vibrate(new long[] { 250, 1000, 500 }, 1);
+                }
+            },
+
+            new Test("Vibrate 3s") {
+                public void run()
+                {
+                    mVibrator.vibrate(3000);
+                }
+            },
+
+            new Test("Vibrate 100s") {
+                public void run()
+                {
+                    mVibrator.vibrate(100000);
+                }
+            },
+
+            new Test("Vibrate off") {
+                public void run()
+                {
+                    mVibrator.cancel();
+                }
+            },
+
+            new Test("Cancel #1") {
+                public void run() {
+                    mNM.cancel(1);
+                }
+            },
+
+            new Test("Cancel #1 in 3 sec") {
+                public void run() {
+                    mHandler.postDelayed(new Runnable() {
+                        public void run() {
+                            Log.d(TAG, "Cancelling now...");
+                            mNM.cancel(1);
+                        }
+                    }, 3000);
+                }
+            },
+
+            new Test("Cancel #2") {
+                public void run() {
+                    mNM.cancel(2);
+                }
+            },
+
+            new Test("Persistent #1") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this)
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle(name)
+                            .setContentText("This is a notification!!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
+
+            new Test("Persistent #1 in 3 sec") {
+                public void run() {
+                    mHandler.postDelayed(new Runnable() {
+                        public void run() {
+                            String message = "            "
+                                    + "tick tock tick tock\n\nSometimes notifications can "
+                                    + "be really long and wrap to more than one line.\n"
+                                    + "Sometimes."
+                                    + "Ohandwhathappensifwehaveonereallylongstringarewesure"
+                                    + "thatwesegmentitcorrectly?\n";
+                            Notification n = new Notification.Builder(
+                                    NotificationTestList.this, "low")
+                                    .setSmallIcon(R.drawable.icon1)
+                                    .setContentTitle(name)
+                                    .setContentText("This is still a notification!!!")
+                                    .setContentIntent(makeIntent())
+                                    .setStyle(new Notification.BigTextStyle().bigText(message))
+                                    .build();
+                            mNM.notify(1, n);
+                        }
+                    }, 3000);
+                }
+            },
+
+            new Test("Persistent #2") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle(name)
+                            .setContentText("This is a notification!!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    mNM.notify(2, n);
+                }
+            },
+
+            new Test("Persistent #3") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle(name)
+                            .setContentText("This is a notification!!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    mNM.notify(3, n);
+                }
+            },
+
+            new Test("Persistent #2 Vibrate") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle(name)
+                            .setContentText("This is a notification!!!")
+                            .setContentIntent(makeIntent())
+                            .setDefaults(Notification.DEFAULT_VIBRATE)
+                            .build();
+                    mNM.notify(2, n);
+                }
+            },
+
+            new Test("Persistent #1 - different icon") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle(name)
+                            .setContentText("This is a notification!!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
+
+            new Test("Chronometer Start") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(System.currentTimeMillis())
+                            .setContentTitle(name)
+                            .setContentIntent(makeIntent())
+                            .setOngoing(true)
+                            .setUsesChronometer(true)
+                            .build();
+                    mNM.notify(2, n);
+                }
+            },
+
+            new Test("Chronometer Stop") {
+                public void run() {
+                    mHandler.postDelayed(new Runnable() {
                         public void run() {
                             Log.d(TAG, "Chronometer Stop");
                             Notification n = new Notification.Builder(
@@ -988,121 +1024,121 @@
                             mNM.notify(2, n);
                         }
                     }, 3000);
-            }
-        },
-
-        new Test("Sequential Persistent") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 1));
-                mNM.notify(2, notificationWithNumbers(name, 2));
-            }
-        },
-
-        new Test("Replace Persistent") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 1));
-                mNM.notify(1, notificationWithNumbers(name, 1));
-            }
-        },
-
-        new Test("Run and Cancel (n=1)") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 1));
-                mNM.cancel(1);
-            }
-        },
-
-        new Test("Run an Cancel (n=2)") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 1));
-                mNM.notify(2, notificationWithNumbers(name, 2));
-                mNM.cancel(2);
-            }
-        },
-
-        // Repeatedly notify and cancel -- triggers bug #670627
-        new Test("Bug 670627") {
-            public void run() {
-                for (int i = 0; i < 10; i++) {
-                  Log.d(TAG, "Add two notifications");
-                  mNM.notify(1, notificationWithNumbers(name, 1));
-                  mNM.notify(2, notificationWithNumbers(name, 2));
-                  Log.d(TAG, "Cancel two notifications");
-                  mNM.cancel(1);
-                  mNM.cancel(2);
                 }
-            }
-        },
+            },
 
-        new Test("Ten Notifications") {
-            public void run() {
-                for (int i = 0; i < 10; i++) {
-                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                            .setSmallIcon(kNumberedIconResIDs[i])
-                            .setContentTitle("Persistent #" + i)
-                            .setContentText("Notify me!!!" + i)
-                            .setOngoing(i < 2)
-                            .setNumber(i)
-                            .build();
-                    mNM.notify((i+1)*10, n);
+            new Test("Sequential Persistent") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 1));
+                    mNM.notify(2, notificationWithNumbers(name, 2));
                 }
-            }
-        },
-        
-        new Test("Cancel eight notifications") {
-            public void run() {
-                for (int i = 1; i < 9; i++) {
-                    mNM.cancel((i+1)*10);
+            },
+
+            new Test("Replace Persistent") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 1));
+                    mNM.notify(1, notificationWithNumbers(name, 1));
                 }
-            }
-        },
-        
-        new Test("Cancel the other two notifications") {
-            public void run() {
-                mNM.cancel(10);
-                mNM.cancel(100);
-            }
-        },
-        
-        new Test("Persistent with numbers 1") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 1));
-            }
-        },
+            },
 
-        new Test("Persistent with numbers 22") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 22));
-            }
-        },
+            new Test("Run and Cancel (n=1)") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 1));
+                    mNM.cancel(1);
+                }
+            },
 
-        new Test("Persistent with numbers 333") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 333));
-            }
-        },
+            new Test("Run an Cancel (n=2)") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 1));
+                    mNM.notify(2, notificationWithNumbers(name, 2));
+                    mNM.cancel(2);
+                }
+            },
 
-        new Test("Persistent with numbers 4444") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 4444));
-            }
-        },
+            // Repeatedly notify and cancel -- triggers bug #670627
+            new Test("Bug 670627") {
+                public void run() {
+                    for (int i = 0; i < 10; i++) {
+                        Log.d(TAG, "Add two notifications");
+                        mNM.notify(1, notificationWithNumbers(name, 1));
+                        mNM.notify(2, notificationWithNumbers(name, 2));
+                        Log.d(TAG, "Cancel two notifications");
+                        mNM.cancel(1);
+                        mNM.cancel(2);
+                    }
+                }
+            },
 
-        new Test("Crash") {
-            public void run()
-            {
-                PowerManager.WakeLock wl =
-                        ((PowerManager) NotificationTestList.this.getSystemService(Context.POWER_SERVICE))
-                                .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "crasher");
-                wl.acquire();
-                mHandler.postDelayed(new Runnable() {
-                            public void run() {
-                                throw new RuntimeException("Die!");
-                            }
-                        }, 10000);
+            new Test("Ten Notifications") {
+                public void run() {
+                    for (int i = 0; i < 10; i++) {
+                        Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                                .setSmallIcon(kNumberedIconResIDs[i])
+                                .setContentTitle("Persistent #" + i)
+                                .setContentText("Notify me!!!" + i)
+                                .setOngoing(i < 2)
+                                .setNumber(i)
+                                .build();
+                        mNM.notify((i+1)*10, n);
+                    }
+                }
+            },
 
-            }
-        },
+            new Test("Cancel eight notifications") {
+                public void run() {
+                    for (int i = 1; i < 9; i++) {
+                        mNM.cancel((i+1)*10);
+                    }
+                }
+            },
+
+            new Test("Cancel the other two notifications") {
+                public void run() {
+                    mNM.cancel(10);
+                    mNM.cancel(100);
+                }
+            },
+
+            new Test("Persistent with numbers 1") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 1));
+                }
+            },
+
+            new Test("Persistent with numbers 22") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 22));
+                }
+            },
+
+            new Test("Persistent with numbers 333") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 333));
+                }
+            },
+
+            new Test("Persistent with numbers 4444") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 4444));
+                }
+            },
+
+            new Test("Crash") {
+                public void run()
+                {
+                    PowerManager.WakeLock wl =
+                            ((PowerManager) NotificationTestList.this.getSystemService(Context.POWER_SERVICE))
+                                    .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "crasher");
+                    wl.acquire();
+                    mHandler.postDelayed(new Runnable() {
+                        public void run() {
+                            throw new RuntimeException("Die!");
+                        }
+                    }, 10000);
+
+                }
+            },
 
     };
 
@@ -1176,4 +1212,3 @@
         return Bitmap.createBitmap(bd.getBitmap());
     }
 }
-
diff --git a/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/src/com/android/hardware/usb/externalmanagementtest/UsbDeviceStateController.java b/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/src/com/android/hardware/usb/externalmanagementtest/UsbDeviceStateController.java
index 1cb394e..42f7955 100644
--- a/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/src/com/android/hardware/usb/externalmanagementtest/UsbDeviceStateController.java
+++ b/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/src/com/android/hardware/usb/externalmanagementtest/UsbDeviceStateController.java
@@ -89,7 +89,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             release();
         } finally {
             super.finalize();
diff --git a/tests/net/Android.mk b/tests/net/Android.mk
index 3af0adc..677585c 100644
--- a/tests/net/Android.mk
+++ b/tests/net/Android.mk
@@ -42,6 +42,7 @@
     libui \
     libunwind \
     libutils \
+    libvndksupport \
     libcrypto \
     libhidl-gen-utils \
     libhidlbase \
@@ -52,6 +53,7 @@
     libtinyxml2 \
     libvintf \
     libhwbinder \
+    libunwindstack \
     android.hidl.token@1.0
 
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
diff --git a/tests/net/AndroidTest.xml b/tests/net/AndroidTest.xml
index 6c0a6d0..f8ecc6b 100644
--- a/tests/net/AndroidTest.xml
+++ b/tests/net/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="FrameworksNetTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.tests.net" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/tests/net/java/android/net/IpSecConfigTest.java b/tests/net/java/android/net/IpSecConfigTest.java
new file mode 100644
index 0000000..1b4bef5
--- /dev/null
+++ b/tests/net/java/android/net/IpSecConfigTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Unit tests for {@link IpSecConfig}. */
+@SmallTest
+@RunWith(JUnit4.class)
+public class IpSecConfigTest {
+
+    @Test
+    public void testDefaults() throws Exception {
+        IpSecConfig c = new IpSecConfig();
+        assertEquals(IpSecTransform.MODE_TRANSPORT, c.getMode());
+        assertEquals("", c.getLocalAddress());
+        assertEquals("", c.getRemoteAddress());
+        assertNull(c.getNetwork());
+        assertEquals(IpSecTransform.ENCAP_NONE, c.getEncapType());
+        assertEquals(IpSecManager.INVALID_RESOURCE_ID, c.getEncapSocketResourceId());
+        assertEquals(0, c.getEncapRemotePort());
+        assertEquals(0, c.getNattKeepaliveInterval());
+        for (int direction :
+                new int[] {IpSecTransform.DIRECTION_OUT, IpSecTransform.DIRECTION_IN}) {
+            assertNull(c.getEncryption(direction));
+            assertNull(c.getAuthentication(direction));
+            assertEquals(IpSecManager.INVALID_RESOURCE_ID, c.getSpiResourceId(direction));
+        }
+    }
+
+    @Test
+    public void testParcelUnparcel() throws Exception {
+        assertParcelingIsLossless(new IpSecConfig());
+
+        IpSecConfig c = new IpSecConfig();
+        c.setMode(IpSecTransform.MODE_TUNNEL);
+        c.setLocalAddress("0.0.0.0");
+        c.setRemoteAddress("1.2.3.4");
+        c.setEncapType(android.system.OsConstants.UDP_ENCAP_ESPINUDP);
+        c.setEncapSocketResourceId(7);
+        c.setEncapRemotePort(22);
+        c.setNattKeepaliveInterval(42);
+        c.setEncryption(
+                IpSecTransform.DIRECTION_OUT,
+                new IpSecAlgorithm(
+                        IpSecAlgorithm.CRYPT_AES_CBC,
+                        new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}));
+        c.setAuthentication(
+                IpSecTransform.DIRECTION_OUT,
+                new IpSecAlgorithm(
+                        IpSecAlgorithm.AUTH_HMAC_SHA1,
+                        new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0}));
+        c.setSpiResourceId(IpSecTransform.DIRECTION_OUT, 1984);
+        c.setEncryption(
+                IpSecTransform.DIRECTION_IN,
+                new IpSecAlgorithm(
+                        IpSecAlgorithm.CRYPT_AES_CBC,
+                        new byte[] {2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}));
+        c.setAuthentication(
+                IpSecTransform.DIRECTION_IN,
+                new IpSecAlgorithm(
+                        IpSecAlgorithm.AUTH_HMAC_SHA1,
+                        new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 1}));
+        c.setSpiResourceId(IpSecTransform.DIRECTION_IN, 99);
+        assertParcelingIsLossless(c);
+    }
+
+    private void assertParcelingIsLossless(IpSecConfig ci) throws Exception {
+        Parcel p = Parcel.obtain();
+        ci.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        IpSecConfig co = IpSecConfig.CREATOR.createFromParcel(p);
+        assertTrue(IpSecConfig.equals(co, ci));
+    }
+}
diff --git a/tests/net/java/android/net/IpSecManagerTest.java b/tests/net/java/android/net/IpSecManagerTest.java
index 9f31d27..ccb0f3b 100644
--- a/tests/net/java/android/net/IpSecManagerTest.java
+++ b/tests/net/java/android/net/IpSecManagerTest.java
@@ -31,19 +31,21 @@
 import static org.mockito.Mockito.when;
 
 import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.system.Os;
-import android.test.AndroidTestCase;
+
 import com.android.server.IpSecService;
+
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
 
 /** Unit tests for {@link IpSecManager}. */
 @SmallTest
-@RunWith(JUnit4.class)
+@RunWith(AndroidJUnit4.class)
 public class IpSecManagerTest {
 
     private static final int TEST_UDP_ENCAP_PORT = 34567;
diff --git a/tests/net/java/android/net/LinkPropertiesTest.java b/tests/net/java/android/net/LinkPropertiesTest.java
new file mode 100644
index 0000000..52da79a
--- /dev/null
+++ b/tests/net/java/android/net/LinkPropertiesTest.java
@@ -0,0 +1,781 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.net.IpPrefix;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.LinkProperties.CompareResult;
+import android.net.LinkProperties.ProvisioningChange;
+import android.net.RouteInfo;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.system.OsConstants;
+import android.util.ArraySet;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class LinkPropertiesTest {
+    private static InetAddress ADDRV4 = NetworkUtils.numericToInetAddress("75.208.6.1");
+    private static InetAddress ADDRV6 = NetworkUtils.numericToInetAddress(
+            "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
+    private static InetAddress DNS1 = NetworkUtils.numericToInetAddress("75.208.7.1");
+    private static InetAddress DNS2 = NetworkUtils.numericToInetAddress("69.78.7.1");
+    private static InetAddress DNS6 = NetworkUtils.numericToInetAddress("2001:4860:4860::8888");
+    private static InetAddress GATEWAY1 = NetworkUtils.numericToInetAddress("75.208.8.1");
+    private static InetAddress GATEWAY2 = NetworkUtils.numericToInetAddress("69.78.8.1");
+    private static InetAddress GATEWAY61 = NetworkUtils.numericToInetAddress("fe80::6:0000:613");
+    private static InetAddress GATEWAY62 = NetworkUtils.numericToInetAddress("fe80::6:2222");
+    private static String NAME = "qmi0";
+    private static int MTU = 1500;
+
+    private static LinkAddress LINKADDRV4 = new LinkAddress(ADDRV4, 32);
+    private static LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128);
+    private static LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64");
+
+    // TODO: replace all calls to NetworkUtils.numericToInetAddress with calls to this method.
+    private InetAddress Address(String addrString) {
+        return NetworkUtils.numericToInetAddress(addrString);
+    }
+
+    public void assertLinkPropertiesEqual(LinkProperties source, LinkProperties target) {
+        // Check implementation of equals(), element by element.
+        assertTrue(source.isIdenticalInterfaceName(target));
+        assertTrue(target.isIdenticalInterfaceName(source));
+
+        assertTrue(source.isIdenticalAddresses(target));
+        assertTrue(target.isIdenticalAddresses(source));
+
+        assertTrue(source.isIdenticalDnses(target));
+        assertTrue(target.isIdenticalDnses(source));
+
+        assertTrue(source.isIdenticalRoutes(target));
+        assertTrue(target.isIdenticalRoutes(source));
+
+        assertTrue(source.isIdenticalHttpProxy(target));
+        assertTrue(target.isIdenticalHttpProxy(source));
+
+        assertTrue(source.isIdenticalStackedLinks(target));
+        assertTrue(target.isIdenticalStackedLinks(source));
+
+        assertTrue(source.isIdenticalMtu(target));
+        assertTrue(target.isIdenticalMtu(source));
+
+        // Check result of equals().
+        assertTrue(source.equals(target));
+        assertTrue(target.equals(source));
+
+        // Check hashCode.
+        assertEquals(source.hashCode(), target.hashCode());
+    }
+
+    @Test
+    public void testEqualsNull() {
+        LinkProperties source = new LinkProperties();
+        LinkProperties target = new LinkProperties();
+
+        assertFalse(source == target);
+        assertLinkPropertiesEqual(source, target);
+    }
+
+    @Test
+    public void testEqualsSameOrder() throws Exception {
+        LinkProperties source = new LinkProperties();
+        source.setInterfaceName(NAME);
+        // set 2 link addresses
+        source.addLinkAddress(LINKADDRV4);
+        source.addLinkAddress(LINKADDRV6);
+        // set 2 dnses
+        source.addDnsServer(DNS1);
+        source.addDnsServer(DNS2);
+        // set 2 gateways
+        source.addRoute(new RouteInfo(GATEWAY1));
+        source.addRoute(new RouteInfo(GATEWAY2));
+        source.setMtu(MTU);
+
+        LinkProperties target = new LinkProperties();
+
+        // All fields are same
+        target.setInterfaceName(NAME);
+        target.addLinkAddress(LINKADDRV4);
+        target.addLinkAddress(LINKADDRV6);
+        target.addDnsServer(DNS1);
+        target.addDnsServer(DNS2);
+        target.addRoute(new RouteInfo(GATEWAY1));
+        target.addRoute(new RouteInfo(GATEWAY2));
+        target.setMtu(MTU);
+
+        assertLinkPropertiesEqual(source, target);
+
+        target.clear();
+        // change Interface Name
+        target.setInterfaceName("qmi1");
+        target.addLinkAddress(LINKADDRV4);
+        target.addLinkAddress(LINKADDRV6);
+        target.addDnsServer(DNS1);
+        target.addDnsServer(DNS2);
+        target.addRoute(new RouteInfo(GATEWAY1));
+        target.addRoute(new RouteInfo(GATEWAY2));
+        target.setMtu(MTU);
+        assertFalse(source.equals(target));
+
+        target.clear();
+        target.setInterfaceName(NAME);
+        // change link addresses
+        target.addLinkAddress(new LinkAddress(
+                NetworkUtils.numericToInetAddress("75.208.6.2"), 32));
+        target.addLinkAddress(LINKADDRV6);
+        target.addDnsServer(DNS1);
+        target.addDnsServer(DNS2);
+        target.addRoute(new RouteInfo(GATEWAY1));
+        target.addRoute(new RouteInfo(GATEWAY2));
+        target.setMtu(MTU);
+        assertFalse(source.equals(target));
+
+        target.clear();
+        target.setInterfaceName(NAME);
+        target.addLinkAddress(LINKADDRV4);
+        target.addLinkAddress(LINKADDRV6);
+        // change dnses
+        target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2"));
+        target.addDnsServer(DNS2);
+        target.addRoute(new RouteInfo(GATEWAY1));
+        target.addRoute(new RouteInfo(GATEWAY2));
+        target.setMtu(MTU);
+        assertFalse(source.equals(target));
+
+        target.clear();
+        target.setInterfaceName(NAME);
+        target.addLinkAddress(LINKADDRV4);
+        target.addLinkAddress(LINKADDRV6);
+        target.addDnsServer(DNS1);
+        target.addDnsServer(DNS2);
+        // change gateway
+        target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2")));
+        target.addRoute(new RouteInfo(GATEWAY2));
+        target.setMtu(MTU);
+        assertFalse(source.equals(target));
+
+        target.clear();
+        target.setInterfaceName(NAME);
+        target.addLinkAddress(LINKADDRV4);
+        target.addLinkAddress(LINKADDRV6);
+        target.addDnsServer(DNS1);
+        target.addDnsServer(DNS2);
+        target.addRoute(new RouteInfo(GATEWAY1));
+        target.addRoute(new RouteInfo(GATEWAY2));
+        // change mtu
+        target.setMtu(1440);
+        assertFalse(source.equals(target));
+    }
+
+    @Test
+    public void testEqualsDifferentOrder() throws Exception {
+        LinkProperties source = new LinkProperties();
+        source.setInterfaceName(NAME);
+        // set 2 link addresses
+        source.addLinkAddress(LINKADDRV4);
+        source.addLinkAddress(LINKADDRV6);
+        // set 2 dnses
+        source.addDnsServer(DNS1);
+        source.addDnsServer(DNS2);
+        // set 2 gateways
+        source.addRoute(new RouteInfo(GATEWAY1));
+        source.addRoute(new RouteInfo(GATEWAY2));
+        source.setMtu(MTU);
+
+        LinkProperties target = new LinkProperties();
+        // Exchange order
+        target.setInterfaceName(NAME);
+        target.addLinkAddress(LINKADDRV6);
+        target.addLinkAddress(LINKADDRV4);
+        target.addDnsServer(DNS2);
+        target.addDnsServer(DNS1);
+        target.addRoute(new RouteInfo(GATEWAY2));
+        target.addRoute(new RouteInfo(GATEWAY1));
+        target.setMtu(MTU);
+
+        assertLinkPropertiesEqual(source, target);
+    }
+
+    @Test
+    public void testEqualsDuplicated() throws Exception {
+        LinkProperties source = new LinkProperties();
+        // set 3 link addresses, eg, [A, A, B]
+        source.addLinkAddress(LINKADDRV4);
+        source.addLinkAddress(LINKADDRV4);
+        source.addLinkAddress(LINKADDRV6);
+
+        LinkProperties target = new LinkProperties();
+        // set 3 link addresses, eg, [A, B, B]
+        target.addLinkAddress(LINKADDRV4);
+        target.addLinkAddress(LINKADDRV6);
+        target.addLinkAddress(LINKADDRV6);
+
+        assertLinkPropertiesEqual(source, target);
+    }
+
+    private void assertAllRoutesHaveInterface(String iface, LinkProperties lp) {
+        for (RouteInfo r : lp.getRoutes()) {
+            assertEquals(iface, r.getInterface());
+        }
+    }
+
+    @Test
+    public void testRouteInterfaces() {
+        LinkAddress prefix = new LinkAddress(
+            NetworkUtils.numericToInetAddress("2001:db8::"), 32);
+        InetAddress address = ADDRV6;
+
+        // Add a route with no interface to a LinkProperties with no interface. No errors.
+        LinkProperties lp = new LinkProperties();
+        RouteInfo r = new RouteInfo(prefix, address, null);
+        assertTrue(lp.addRoute(r));
+        assertEquals(1, lp.getRoutes().size());
+        assertAllRoutesHaveInterface(null, lp);
+
+        // Adding the same route twice has no effect.
+        assertFalse(lp.addRoute(r));
+        assertEquals(1, lp.getRoutes().size());
+
+        // Add a route with an interface. Expect an exception.
+        r = new RouteInfo(prefix, address, "wlan0");
+        try {
+          lp.addRoute(r);
+          fail("Adding wlan0 route to LP with no interface, expect exception");
+        } catch (IllegalArgumentException expected) {}
+
+        // Change the interface name. All the routes should change their interface name too.
+        lp.setInterfaceName("rmnet0");
+        assertAllRoutesHaveInterface("rmnet0", lp);
+
+        // Now add a route with the wrong interface. This causes an exception too.
+        try {
+          lp.addRoute(r);
+          fail("Adding wlan0 route to rmnet0 LP, expect exception");
+        } catch (IllegalArgumentException expected) {}
+
+        // If the interface name matches, the route is added.
+        r = new RouteInfo(prefix, null, "wlan0");
+        lp.setInterfaceName("wlan0");
+        lp.addRoute(r);
+        assertEquals(2, lp.getRoutes().size());
+        assertAllRoutesHaveInterface("wlan0", lp);
+
+        // Routes with null interfaces are converted to wlan0.
+        r = RouteInfo.makeHostRoute(ADDRV6, null);
+        lp.addRoute(r);
+        assertEquals(3, lp.getRoutes().size());
+        assertAllRoutesHaveInterface("wlan0", lp);
+
+        // Check comparisons work.
+        LinkProperties lp2 = new LinkProperties(lp);
+        assertAllRoutesHaveInterface("wlan0", lp);
+        assertEquals(0, lp.compareAllRoutes(lp2).added.size());
+        assertEquals(0, lp.compareAllRoutes(lp2).removed.size());
+
+        lp2.setInterfaceName("p2p0");
+        assertAllRoutesHaveInterface("p2p0", lp2);
+        assertEquals(3, lp.compareAllRoutes(lp2).added.size());
+        assertEquals(3, lp.compareAllRoutes(lp2).removed.size());
+    }
+
+    @Test
+    public void testStackedInterfaces() {
+        LinkProperties rmnet0 = new LinkProperties();
+        rmnet0.setInterfaceName("rmnet0");
+        rmnet0.addLinkAddress(LINKADDRV6);
+
+        LinkProperties clat4 = new LinkProperties();
+        clat4.setInterfaceName("clat4");
+        clat4.addLinkAddress(LINKADDRV4);
+
+        assertEquals(0, rmnet0.getStackedLinks().size());
+        assertEquals(1, rmnet0.getAddresses().size());
+        assertEquals(1, rmnet0.getLinkAddresses().size());
+        assertEquals(1, rmnet0.getAllAddresses().size());
+        assertEquals(1, rmnet0.getAllLinkAddresses().size());
+
+        rmnet0.addStackedLink(clat4);
+        assertEquals(1, rmnet0.getStackedLinks().size());
+        assertEquals(1, rmnet0.getAddresses().size());
+        assertEquals(1, rmnet0.getLinkAddresses().size());
+        assertEquals(2, rmnet0.getAllAddresses().size());
+        assertEquals(2, rmnet0.getAllLinkAddresses().size());
+
+        rmnet0.addStackedLink(clat4);
+        assertEquals(1, rmnet0.getStackedLinks().size());
+        assertEquals(1, rmnet0.getAddresses().size());
+        assertEquals(1, rmnet0.getLinkAddresses().size());
+        assertEquals(2, rmnet0.getAllAddresses().size());
+        assertEquals(2, rmnet0.getAllLinkAddresses().size());
+
+        assertEquals(0, clat4.getStackedLinks().size());
+
+        // Modify an item in the returned collection to see what happens.
+        for (LinkProperties link : rmnet0.getStackedLinks()) {
+            if (link.getInterfaceName().equals("clat4")) {
+               link.setInterfaceName("newname");
+            }
+        }
+        for (LinkProperties link : rmnet0.getStackedLinks()) {
+            assertFalse("newname".equals(link.getInterfaceName()));
+        }
+
+        assertTrue(rmnet0.removeStackedLink("clat4"));
+        assertEquals(0, rmnet0.getStackedLinks().size());
+        assertEquals(1, rmnet0.getAddresses().size());
+        assertEquals(1, rmnet0.getLinkAddresses().size());
+        assertEquals(1, rmnet0.getAllAddresses().size());
+        assertEquals(1, rmnet0.getAllLinkAddresses().size());
+
+        assertFalse(rmnet0.removeStackedLink("clat4"));
+    }
+
+    private LinkAddress getFirstLinkAddress(LinkProperties lp) {
+        return lp.getLinkAddresses().iterator().next();
+    }
+
+    @Test
+    public void testAddressMethods() {
+        LinkProperties lp = new LinkProperties();
+
+        // No addresses.
+        assertFalse(lp.hasIPv4Address());
+        assertFalse(lp.hasGlobalIPv6Address());
+
+        // Addresses on stacked links don't count.
+        LinkProperties stacked = new LinkProperties();
+        stacked.setInterfaceName("stacked");
+        lp.addStackedLink(stacked);
+        stacked.addLinkAddress(LINKADDRV4);
+        stacked.addLinkAddress(LINKADDRV6);
+        assertTrue(stacked.hasIPv4Address());
+        assertTrue(stacked.hasGlobalIPv6Address());
+        assertFalse(lp.hasIPv4Address());
+        assertFalse(lp.hasGlobalIPv6Address());
+        lp.removeStackedLink("stacked");
+        assertFalse(lp.hasIPv4Address());
+        assertFalse(lp.hasGlobalIPv6Address());
+
+        // Addresses on the base link.
+        // Check the return values of hasIPvXAddress and ensure the add/remove methods return true
+        // iff something changes.
+        assertEquals(0, lp.getLinkAddresses().size());
+        assertTrue(lp.addLinkAddress(LINKADDRV6));
+        assertEquals(1, lp.getLinkAddresses().size());
+        assertFalse(lp.hasIPv4Address());
+        assertTrue(lp.hasGlobalIPv6Address());
+
+        assertTrue(lp.removeLinkAddress(LINKADDRV6));
+        assertEquals(0, lp.getLinkAddresses().size());
+
+        assertTrue(lp.addLinkAddress(LINKADDRV6LINKLOCAL));
+        assertEquals(1, lp.getLinkAddresses().size());
+        assertFalse(lp.hasGlobalIPv6Address());
+
+        assertTrue(lp.addLinkAddress(LINKADDRV4));
+        assertEquals(2, lp.getLinkAddresses().size());
+        assertTrue(lp.hasIPv4Address());
+        assertFalse(lp.hasGlobalIPv6Address());
+
+        assertTrue(lp.addLinkAddress(LINKADDRV6));
+        assertEquals(3, lp.getLinkAddresses().size());
+        assertTrue(lp.hasIPv4Address());
+        assertTrue(lp.hasGlobalIPv6Address());
+
+        assertTrue(lp.removeLinkAddress(LINKADDRV6LINKLOCAL));
+        assertEquals(2, lp.getLinkAddresses().size());
+        assertTrue(lp.hasIPv4Address());
+        assertTrue(lp.hasGlobalIPv6Address());
+
+        // Adding an address twice has no effect.
+        // Removing an address that's not present has no effect.
+        assertFalse(lp.addLinkAddress(LINKADDRV4));
+        assertEquals(2, lp.getLinkAddresses().size());
+        assertTrue(lp.hasIPv4Address());
+        assertTrue(lp.removeLinkAddress(LINKADDRV4));
+        assertEquals(1, lp.getLinkAddresses().size());
+        assertFalse(lp.hasIPv4Address());
+        assertFalse(lp.removeLinkAddress(LINKADDRV4));
+        assertEquals(1, lp.getLinkAddresses().size());
+
+        // Adding an address that's already present but with different properties causes the
+        // existing address to be updated and returns true.
+        // Start with only LINKADDRV6.
+        assertEquals(1, lp.getLinkAddresses().size());
+        assertEquals(LINKADDRV6, getFirstLinkAddress(lp));
+
+        // Create a LinkAddress object for the same address, but with different flags.
+        LinkAddress deprecated = new LinkAddress(ADDRV6, 128,
+                OsConstants.IFA_F_DEPRECATED, OsConstants.RT_SCOPE_UNIVERSE);
+        assertTrue(deprecated.isSameAddressAs(LINKADDRV6));
+        assertFalse(deprecated.equals(LINKADDRV6));
+
+        // Check that adding it updates the existing address instead of adding a new one.
+        assertTrue(lp.addLinkAddress(deprecated));
+        assertEquals(1, lp.getLinkAddresses().size());
+        assertEquals(deprecated, getFirstLinkAddress(lp));
+        assertFalse(LINKADDRV6.equals(getFirstLinkAddress(lp)));
+
+        // Removing LINKADDRV6 removes deprecated, because removing addresses ignores properties.
+        assertTrue(lp.removeLinkAddress(LINKADDRV6));
+        assertEquals(0, lp.getLinkAddresses().size());
+    }
+
+    @Test
+    public void testSetLinkAddresses() {
+        LinkProperties lp = new LinkProperties();
+        lp.addLinkAddress(LINKADDRV4);
+        lp.addLinkAddress(LINKADDRV6);
+
+        LinkProperties lp2 = new LinkProperties();
+        lp2.addLinkAddress(LINKADDRV6);
+
+        assertFalse(lp.equals(lp2));
+
+        lp2.setLinkAddresses(lp.getLinkAddresses());
+        assertTrue(lp.equals(lp));
+    }
+
+    @Test
+    public void testIsProvisioned() {
+        LinkProperties lp4 = new LinkProperties();
+        assertFalse("v4only:empty", lp4.isProvisioned());
+        lp4.addLinkAddress(LINKADDRV4);
+        assertFalse("v4only:addr-only", lp4.isProvisioned());
+        lp4.addDnsServer(DNS1);
+        assertFalse("v4only:addr+dns", lp4.isProvisioned());
+        lp4.addRoute(new RouteInfo(GATEWAY1));
+        assertTrue("v4only:addr+dns+route", lp4.isProvisioned());
+        assertTrue("v4only:addr+dns+route", lp4.isIPv4Provisioned());
+        assertFalse("v4only:addr+dns+route", lp4.isIPv6Provisioned());
+
+        LinkProperties lp6 = new LinkProperties();
+        assertFalse("v6only:empty", lp6.isProvisioned());
+        lp6.addLinkAddress(LINKADDRV6LINKLOCAL);
+        assertFalse("v6only:fe80-only", lp6.isProvisioned());
+        lp6.addDnsServer(DNS6);
+        assertFalse("v6only:fe80+dns", lp6.isProvisioned());
+        lp6.addRoute(new RouteInfo(GATEWAY61));
+        assertFalse("v6only:fe80+dns+route", lp6.isProvisioned());
+        lp6.addLinkAddress(LINKADDRV6);
+        assertTrue("v6only:fe80+global+dns+route", lp6.isIPv6Provisioned());
+        assertTrue("v6only:fe80+global+dns+route", lp6.isProvisioned());
+        lp6.removeLinkAddress(LINKADDRV6LINKLOCAL);
+        assertFalse("v6only:global+dns+route", lp6.isIPv4Provisioned());
+        assertTrue("v6only:global+dns+route", lp6.isIPv6Provisioned());
+        assertTrue("v6only:global+dns+route", lp6.isProvisioned());
+
+        LinkProperties lp46 = new LinkProperties();
+        lp46.addLinkAddress(LINKADDRV4);
+        lp46.addLinkAddress(LINKADDRV6);
+        lp46.addDnsServer(DNS1);
+        lp46.addDnsServer(DNS6);
+        assertFalse("dualstack:missing-routes", lp46.isProvisioned());
+        lp46.addRoute(new RouteInfo(GATEWAY1));
+        assertTrue("dualstack:v4-provisioned", lp46.isIPv4Provisioned());
+        assertFalse("dualstack:v4-provisioned", lp46.isIPv6Provisioned());
+        assertTrue("dualstack:v4-provisioned", lp46.isProvisioned());
+        lp46.addRoute(new RouteInfo(GATEWAY61));
+        assertTrue("dualstack:both-provisioned", lp46.isIPv4Provisioned());
+        assertTrue("dualstack:both-provisioned", lp46.isIPv6Provisioned());
+        assertTrue("dualstack:both-provisioned", lp46.isProvisioned());
+
+        // A link with an IPv6 address and default route, but IPv4 DNS server.
+        LinkProperties mixed = new LinkProperties();
+        mixed.addLinkAddress(LINKADDRV6);
+        mixed.addDnsServer(DNS1);
+        mixed.addRoute(new RouteInfo(GATEWAY61));
+        assertFalse("mixed:addr6+route6+dns4", mixed.isIPv4Provisioned());
+        assertFalse("mixed:addr6+route6+dns4", mixed.isIPv6Provisioned());
+        assertFalse("mixed:addr6+route6+dns4", mixed.isProvisioned());
+    }
+
+    @Test
+    public void testCompareProvisioning() {
+        LinkProperties v4lp = new LinkProperties();
+        v4lp.addLinkAddress(LINKADDRV4);
+        v4lp.addRoute(new RouteInfo(GATEWAY1));
+        v4lp.addDnsServer(DNS1);
+        assertTrue(v4lp.isProvisioned());
+
+        LinkProperties v4r = new LinkProperties(v4lp);
+        v4r.removeDnsServer(DNS1);
+        assertFalse(v4r.isProvisioned());
+
+        assertEquals(ProvisioningChange.STILL_NOT_PROVISIONED,
+                LinkProperties.compareProvisioning(v4r, v4r));
+        assertEquals(ProvisioningChange.LOST_PROVISIONING,
+                LinkProperties.compareProvisioning(v4lp, v4r));
+        assertEquals(ProvisioningChange.GAINED_PROVISIONING,
+                LinkProperties.compareProvisioning(v4r, v4lp));
+        assertEquals(ProvisioningChange.STILL_PROVISIONED,
+                LinkProperties.compareProvisioning(v4lp, v4lp));
+
+        // Check that losing IPv4 provisioning on a dualstack network is
+        // seen as a total loss of provisioning.
+        LinkProperties v6lp = new LinkProperties();
+        v6lp.addLinkAddress(LINKADDRV6);
+        v6lp.addRoute(new RouteInfo(GATEWAY61));
+        v6lp.addDnsServer(DNS6);
+        assertFalse(v6lp.isIPv4Provisioned());
+        assertTrue(v6lp.isIPv6Provisioned());
+        assertTrue(v6lp.isProvisioned());
+
+        LinkProperties v46lp = new LinkProperties(v6lp);
+        v46lp.addLinkAddress(LINKADDRV4);
+        v46lp.addRoute(new RouteInfo(GATEWAY1));
+        v46lp.addDnsServer(DNS1);
+        assertTrue(v46lp.isIPv4Provisioned());
+        assertTrue(v46lp.isIPv6Provisioned());
+        assertTrue(v46lp.isProvisioned());
+
+        assertEquals(ProvisioningChange.STILL_PROVISIONED,
+                LinkProperties.compareProvisioning(v4lp, v46lp));
+        assertEquals(ProvisioningChange.STILL_PROVISIONED,
+                LinkProperties.compareProvisioning(v6lp, v46lp));
+        assertEquals(ProvisioningChange.LOST_PROVISIONING,
+                LinkProperties.compareProvisioning(v46lp, v6lp));
+        assertEquals(ProvisioningChange.LOST_PROVISIONING,
+                LinkProperties.compareProvisioning(v46lp, v4lp));
+
+        // Check that losing and gaining a secondary router does not change
+        // the provisioning status.
+        LinkProperties v6lp2 = new LinkProperties(v6lp);
+        v6lp2.addRoute(new RouteInfo(GATEWAY62));
+        assertTrue(v6lp2.isProvisioned());
+
+        assertEquals(ProvisioningChange.STILL_PROVISIONED,
+                LinkProperties.compareProvisioning(v6lp2, v6lp));
+        assertEquals(ProvisioningChange.STILL_PROVISIONED,
+                LinkProperties.compareProvisioning(v6lp, v6lp2));
+    }
+
+    @Test
+    public void testIsReachable() {
+        final LinkProperties v4lp = new LinkProperties();
+        assertFalse(v4lp.isReachable(DNS1));
+        assertFalse(v4lp.isReachable(DNS2));
+
+        // Add an on-link route, making the on-link DNS server reachable,
+        // but there is still no IPv4 address.
+        assertTrue(v4lp.addRoute(new RouteInfo(
+                new IpPrefix(NetworkUtils.numericToInetAddress("75.208.0.0"), 16))));
+        assertFalse(v4lp.isReachable(DNS1));
+        assertFalse(v4lp.isReachable(DNS2));
+
+        // Adding an IPv4 address (right now, any IPv4 address) means we use
+        // the routes to compute likely reachability.
+        assertTrue(v4lp.addLinkAddress(new LinkAddress(ADDRV4, 16)));
+        assertTrue(v4lp.isReachable(DNS1));
+        assertFalse(v4lp.isReachable(DNS2));
+
+        // Adding a default route makes the off-link DNS server reachable.
+        assertTrue(v4lp.addRoute(new RouteInfo(GATEWAY1)));
+        assertTrue(v4lp.isReachable(DNS1));
+        assertTrue(v4lp.isReachable(DNS2));
+
+        final LinkProperties v6lp = new LinkProperties();
+        final InetAddress kLinkLocalDns = NetworkUtils.numericToInetAddress("fe80::6:1");
+        final InetAddress kLinkLocalDnsWithScope = NetworkUtils.numericToInetAddress("fe80::6:2%43");
+        final InetAddress kOnLinkDns = NetworkUtils.numericToInetAddress("2001:db8:85a3::53");
+        assertFalse(v6lp.isReachable(kLinkLocalDns));
+        assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope));
+        assertFalse(v6lp.isReachable(kOnLinkDns));
+        assertFalse(v6lp.isReachable(DNS6));
+
+        // Add a link-local route, making the link-local DNS servers reachable. Because
+        // we assume the presence of an IPv6 link-local address, link-local DNS servers
+        // are considered reachable, but only those with a non-zero scope identifier.
+        assertTrue(v6lp.addRoute(new RouteInfo(
+                new IpPrefix(NetworkUtils.numericToInetAddress("fe80::"), 64))));
+        assertFalse(v6lp.isReachable(kLinkLocalDns));
+        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+        assertFalse(v6lp.isReachable(kOnLinkDns));
+        assertFalse(v6lp.isReachable(DNS6));
+
+        // Add a link-local address--nothing changes.
+        assertTrue(v6lp.addLinkAddress(LINKADDRV6LINKLOCAL));
+        assertFalse(v6lp.isReachable(kLinkLocalDns));
+        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+        assertFalse(v6lp.isReachable(kOnLinkDns));
+        assertFalse(v6lp.isReachable(DNS6));
+
+        // Add a global route on link, but no global address yet. DNS servers reachable
+        // via a route that doesn't require a gateway: give them the benefit of the
+        // doubt and hope the link-local source address suffices for communication.
+        assertTrue(v6lp.addRoute(new RouteInfo(
+                new IpPrefix(NetworkUtils.numericToInetAddress("2001:db8:85a3::"), 64))));
+        assertFalse(v6lp.isReachable(kLinkLocalDns));
+        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+        assertTrue(v6lp.isReachable(kOnLinkDns));
+        assertFalse(v6lp.isReachable(DNS6));
+
+        // Add a global address; the on-link global address DNS server is (still)
+        // presumed reachable.
+        assertTrue(v6lp.addLinkAddress(new LinkAddress(ADDRV6, 64)));
+        assertFalse(v6lp.isReachable(kLinkLocalDns));
+        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+        assertTrue(v6lp.isReachable(kOnLinkDns));
+        assertFalse(v6lp.isReachable(DNS6));
+
+        // Adding a default route makes the off-link DNS server reachable.
+        assertTrue(v6lp.addRoute(new RouteInfo(GATEWAY62)));
+        assertFalse(v6lp.isReachable(kLinkLocalDns));
+        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+        assertTrue(v6lp.isReachable(kOnLinkDns));
+        assertTrue(v6lp.isReachable(DNS6));
+
+        // Check isReachable on stacked links. This requires that the source IP address be assigned
+        // on the interface returned by the route lookup.
+        LinkProperties stacked = new LinkProperties();
+
+        // Can't add a stacked link without an interface name.
+        stacked.setInterfaceName("v4-test0");
+        v6lp.addStackedLink(stacked);
+
+        InetAddress stackedAddress = Address("192.0.0.4");
+        LinkAddress stackedLinkAddress = new LinkAddress(stackedAddress, 32);
+        assertFalse(v6lp.isReachable(stackedAddress));
+        stacked.addLinkAddress(stackedLinkAddress);
+        assertFalse(v6lp.isReachable(stackedAddress));
+        stacked.addRoute(new RouteInfo(stackedLinkAddress));
+        assertTrue(stacked.isReachable(stackedAddress));
+        assertTrue(v6lp.isReachable(stackedAddress));
+
+        assertFalse(v6lp.isReachable(DNS1));
+        stacked.addRoute(new RouteInfo((IpPrefix) null, stackedAddress));
+        assertTrue(v6lp.isReachable(DNS1));
+    }
+
+    @Test
+    public void testLinkPropertiesEnsureDirectlyConnectedRoutes() {
+        // IPv4 case: no route added initially
+        LinkProperties rmnet0 = new LinkProperties();
+        rmnet0.setInterfaceName("rmnet0");
+        rmnet0.addLinkAddress(new LinkAddress("10.0.0.2/8"));
+        RouteInfo directRoute0 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
+                rmnet0.getInterfaceName());
+
+        // Since no routes is added explicitly, getAllRoutes() should return empty.
+        assertTrue(rmnet0.getAllRoutes().isEmpty());
+        rmnet0.ensureDirectlyConnectedRoutes();
+        // ensureDirectlyConnectedRoutes() should have added the missing local route.
+        assertEqualRoutes(Collections.singletonList(directRoute0), rmnet0.getAllRoutes());
+
+        // IPv4 case: both direct and default routes added initially
+        LinkProperties rmnet1 = new LinkProperties();
+        rmnet1.setInterfaceName("rmnet1");
+        rmnet1.addLinkAddress(new LinkAddress("10.0.0.3/8"));
+        RouteInfo defaultRoute1 = new RouteInfo((IpPrefix) null,
+                NetworkUtils.numericToInetAddress("10.0.0.1"), rmnet1.getInterfaceName());
+        RouteInfo directRoute1 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
+                rmnet1.getInterfaceName());
+        rmnet1.addRoute(defaultRoute1);
+        rmnet1.addRoute(directRoute1);
+
+        // Check added routes
+        assertEqualRoutes(Arrays.asList(defaultRoute1, directRoute1), rmnet1.getAllRoutes());
+        // ensureDirectlyConnectedRoutes() shouldn't change the routes since direct connected
+        // route is already part of the configuration.
+        rmnet1.ensureDirectlyConnectedRoutes();
+        assertEqualRoutes(Arrays.asList(defaultRoute1, directRoute1), rmnet1.getAllRoutes());
+
+        // IPv6 case: only default routes added initially
+        LinkProperties rmnet2 = new LinkProperties();
+        rmnet2.setInterfaceName("rmnet2");
+        rmnet2.addLinkAddress(new LinkAddress("fe80::cafe/64"));
+        rmnet2.addLinkAddress(new LinkAddress("2001:db8::2/64"));
+        RouteInfo defaultRoute2 = new RouteInfo((IpPrefix) null,
+                NetworkUtils.numericToInetAddress("2001:db8::1"), rmnet2.getInterfaceName());
+        RouteInfo directRoute2 = new RouteInfo(new IpPrefix("2001:db8::/64"), null,
+                rmnet2.getInterfaceName());
+        RouteInfo linkLocalRoute2 = new RouteInfo(new IpPrefix("fe80::/64"), null,
+                rmnet2.getInterfaceName());
+        rmnet2.addRoute(defaultRoute2);
+
+        assertEqualRoutes(Arrays.asList(defaultRoute2), rmnet2.getAllRoutes());
+        rmnet2.ensureDirectlyConnectedRoutes();
+        assertEqualRoutes(Arrays.asList(defaultRoute2, directRoute2, linkLocalRoute2),
+                rmnet2.getAllRoutes());
+
+        // Corner case: no interface name
+        LinkProperties rmnet3 = new LinkProperties();
+        rmnet3.addLinkAddress(new LinkAddress("192.168.0.2/24"));
+        RouteInfo directRoute3 = new RouteInfo(new IpPrefix("192.168.0.0/24"), null,
+                rmnet3.getInterfaceName());
+
+        assertTrue(rmnet3.getAllRoutes().isEmpty());
+        rmnet3.ensureDirectlyConnectedRoutes();
+        assertEqualRoutes(Collections.singletonList(directRoute3), rmnet3.getAllRoutes());
+
+    }
+
+    @Test
+    public void testCompareResult() {
+        // Either adding or removing items
+        compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(1),
+                Arrays.asList(2, 3, 4), new ArrayList<>());
+        compareResult(Arrays.asList(1, 2), Arrays.asList(3, 2, 1, 4),
+                new ArrayList<>(), Arrays.asList(3, 4));
+
+
+        // adding and removing items at the same time
+        compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(2, 3, 4, 5),
+                Arrays.asList(1), Arrays.asList(5));
+        compareResult(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6),
+                Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6));
+
+        // null cases
+        compareResult(Arrays.asList(1, 2, 3), null, Arrays.asList(1, 2, 3), new ArrayList<>());
+        compareResult(null, Arrays.asList(3, 2, 1), new ArrayList<>(), Arrays.asList(1, 2, 3));
+        compareResult(null, null, new ArrayList<>(), new ArrayList<>());
+    }
+
+    private void assertEqualRoutes(Collection<RouteInfo> expected, Collection<RouteInfo> actual) {
+        Set<RouteInfo> expectedSet = new ArraySet<>(expected);
+        Set<RouteInfo> actualSet = new ArraySet<>(actual);
+        // Duplicated entries in actual routes are considered failures
+        assertEquals(actual.size(), actualSet.size());
+
+        assertEquals(expectedSet, actualSet);
+    }
+
+    private <T> void compareResult(List<T> oldItems, List<T> newItems, List<T> expectRemoved,
+            List<T> expectAdded) {
+        CompareResult<T> result = new CompareResult<>(oldItems, newItems);
+        assertEquals(new ArraySet<>(expectAdded), new ArraySet<>(result.added));
+        assertEquals(new ArraySet<>(expectRemoved), (new ArraySet<>(result.removed)));
+    }
+}
diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java
new file mode 100644
index 0000000..fcbb9da
--- /dev/null
+++ b/tests/net/java/android/net/MacAddressTest.java
@@ -0,0 +1,208 @@
+/*
+ * 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.net;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import android.net.MacAddress.MacAddressType;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import java.util.Arrays;
+import java.util.Random;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class MacAddressTest {
+
+    static class AddrTypeTestCase {
+        byte[] addr;
+        MacAddressType expected;
+
+        static AddrTypeTestCase of(MacAddressType expected, int... addr) {
+            AddrTypeTestCase t = new AddrTypeTestCase();
+            t.expected = expected;
+            t.addr = toByteArray(addr);
+            return t;
+        }
+    }
+
+    @Test
+    public void testMacAddrTypes() {
+        AddrTypeTestCase[] testcases = {
+            AddrTypeTestCase.of(null),
+            AddrTypeTestCase.of(null, 0),
+            AddrTypeTestCase.of(null, 1, 2, 3, 4, 5),
+            AddrTypeTestCase.of(null, 1, 2, 3, 4, 5, 6, 7),
+            AddrTypeTestCase.of(MacAddressType.UNICAST, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0),
+            AddrTypeTestCase.of(MacAddressType.BROADCAST, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff),
+            AddrTypeTestCase.of(MacAddressType.MULTICAST, 1, 2, 3, 4, 5, 6),
+            AddrTypeTestCase.of(MacAddressType.MULTICAST, 11, 22, 33, 44, 55, 66),
+            AddrTypeTestCase.of(MacAddressType.MULTICAST, 33, 33, 0xaa, 0xbb, 0xcc, 0xdd)
+        };
+
+        for (AddrTypeTestCase t : testcases) {
+            MacAddressType got = MacAddress.macAddressType(t.addr);
+            String msg = String.format("expected type of %s to be %s, but got %s",
+                    Arrays.toString(t.addr), t.expected, got);
+            assertEquals(msg, t.expected, got);
+
+            if (got != null) {
+                assertEquals(got, new MacAddress(t.addr).addressType());
+            }
+        }
+    }
+
+    @Test
+    public void testIsMulticastAddress() {
+        MacAddress[] multicastAddresses = {
+            MacAddress.BROADCAST_ADDRESS,
+            new MacAddress("07:00:d3:56:8a:c4"),
+            new MacAddress("33:33:aa:bb:cc:dd"),
+        };
+        MacAddress[] unicastAddresses = {
+            MacAddress.ALL_ZEROS_ADDRESS,
+            new MacAddress("00:01:44:55:66:77"),
+            new MacAddress("08:00:22:33:44:55"),
+            new MacAddress("06:00:00:00:00:00"),
+        };
+
+        for (MacAddress mac : multicastAddresses) {
+            String msg = mac.toString() + " expected to be a multicast address";
+            assertTrue(msg, mac.isMulticastAddress());
+        }
+        for (MacAddress mac : unicastAddresses) {
+            String msg = mac.toString() + " expected not to be a multicast address";
+            assertFalse(msg, mac.isMulticastAddress());
+        }
+    }
+
+    @Test
+    public void testIsLocallyAssignedAddress() {
+        MacAddress[] localAddresses = {
+            new MacAddress("06:00:00:00:00:00"),
+            new MacAddress("07:00:d3:56:8a:c4"),
+            new MacAddress("33:33:aa:bb:cc:dd"),
+        };
+        MacAddress[] universalAddresses = {
+            new MacAddress("00:01:44:55:66:77"),
+            new MacAddress("08:00:22:33:44:55"),
+        };
+
+        for (MacAddress mac : localAddresses) {
+            String msg = mac.toString() + " expected to be a locally assigned address";
+            assertTrue(msg, mac.isLocallyAssigned());
+        }
+        for (MacAddress mac : universalAddresses) {
+            String msg = mac.toString() + " expected not to be globally unique address";
+            assertFalse(msg, mac.isLocallyAssigned());
+        }
+    }
+
+    @Test
+    public void testMacAddressConversions() {
+        final int iterations = 10000;
+        for (int i = 0; i < iterations; i++) {
+            MacAddress mac = MacAddress.getRandomAddress();
+
+            String stringRepr = mac.toString();
+            byte[] bytesRepr = mac.toByteArray();
+
+            assertEquals(mac, new MacAddress(stringRepr));
+            assertEquals(mac, new MacAddress(bytesRepr));
+        }
+    }
+
+    @Test
+    public void testMacAddressRandomGeneration() {
+        final int iterations = 1000;
+        final String expectedAndroidOui = "da:a1:19";
+        for (int i = 0; i < iterations; i++) {
+            MacAddress mac = MacAddress.getRandomAddress();
+            String stringRepr = mac.toString();
+
+            assertTrue(stringRepr + " expected to be a locally assigned address",
+                    mac.isLocallyAssigned());
+            assertTrue(stringRepr + " expected to begin with " + expectedAndroidOui,
+                    stringRepr.startsWith(expectedAndroidOui));
+        }
+
+        final Random r = new Random();
+        final String anotherOui = "24:5f:78";
+        final String expectedLocalOui = "26:5f:78";
+        final MacAddress base = new MacAddress(anotherOui + ":0:0:0");
+        for (int i = 0; i < iterations; i++) {
+            MacAddress mac = MacAddress.getRandomAddress(base, r);
+            String stringRepr = mac.toString();
+
+            assertTrue(stringRepr + " expected to be a locally assigned address",
+                    mac.isLocallyAssigned());
+            assertTrue(stringRepr + " expected to begin with " + expectedLocalOui,
+                    stringRepr.startsWith(expectedLocalOui));
+        }
+    }
+
+    @Test
+    public void testConstructorInputValidation() {
+        String[] invalidStringAddresses = {
+            null,
+            "",
+            "abcd",
+            "1:2:3:4:5",
+            "1:2:3:4:5:6:7",
+            "10000:2:3:4:5:6",
+        };
+
+        for (String s : invalidStringAddresses) {
+            try {
+                MacAddress mac = new MacAddress(s);
+                fail("new MacAddress(" + s + ") should have failed, but returned " + mac);
+            } catch (IllegalArgumentException excepted) {
+            }
+        }
+
+        byte[][] invalidBytesAddresses = {
+            null,
+            {},
+            {1,2,3,4,5},
+            {1,2,3,4,5,6,7},
+        };
+
+        for (byte[] b : invalidBytesAddresses) {
+            try {
+                MacAddress mac = new MacAddress(b);
+                fail("new MacAddress(" + Arrays.toString(b)
+                        + ") should have failed, but returned " + mac);
+            } catch (IllegalArgumentException excepted) {
+            }
+        }
+    }
+
+    static byte[] toByteArray(int... in) {
+        byte[] out = new byte[in.length];
+        for (int i = 0; i < in.length; i++) {
+            out[i] = (byte) in[i];
+        }
+        return out;
+    }
+}
diff --git a/tests/net/java/android/net/NetworkCapabilitiesTest.java b/tests/net/java/android/net/NetworkCapabilitiesTest.java
index 7346f9f9..cd2d098 100644
--- a/tests/net/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/java/android/net/NetworkCapabilitiesTest.java
@@ -16,6 +16,7 @@
 
 package android.net;
 
+import static android.net.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
@@ -26,13 +27,12 @@
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.NetworkCapabilities.UNRESTRICTED_CAPABILITIES;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
-
-import android.net.NetworkCapabilities;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -159,4 +159,25 @@
         assertNotEquals("", nc1.describeImmutableDifferences(nc2));
         assertEquals("", nc1.describeImmutableDifferences(nc1));
     }
+
+    @Test
+    public void testLinkBandwidthUtils() {
+        assertEquals(LINK_BANDWIDTH_UNSPECIFIED, NetworkCapabilities
+                .minBandwidth(LINK_BANDWIDTH_UNSPECIFIED, LINK_BANDWIDTH_UNSPECIFIED));
+        assertEquals(10, NetworkCapabilities
+                .minBandwidth(LINK_BANDWIDTH_UNSPECIFIED, 10));
+        assertEquals(10, NetworkCapabilities
+                .minBandwidth(10, LINK_BANDWIDTH_UNSPECIFIED));
+        assertEquals(10, NetworkCapabilities
+                .minBandwidth(10, 20));
+
+        assertEquals(LINK_BANDWIDTH_UNSPECIFIED, NetworkCapabilities
+                .maxBandwidth(LINK_BANDWIDTH_UNSPECIFIED, LINK_BANDWIDTH_UNSPECIFIED));
+        assertEquals(10, NetworkCapabilities
+                .maxBandwidth(LINK_BANDWIDTH_UNSPECIFIED, 10));
+        assertEquals(10, NetworkCapabilities
+                .maxBandwidth(10, LINK_BANDWIDTH_UNSPECIFIED));
+        assertEquals(20, NetworkCapabilities
+                .maxBandwidth(10, 20));
+    }
 }
diff --git a/tests/net/java/android/net/NetworkStatsTest.java b/tests/net/java/android/net/NetworkStatsTest.java
index eb85eb4..25289ba 100644
--- a/tests/net/java/android/net/NetworkStatsTest.java
+++ b/tests/net/java/android/net/NetworkStatsTest.java
@@ -30,23 +30,30 @@
 import static android.net.NetworkStats.IFACE_ALL;
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 
 import com.google.android.collect.Sets;
 
-import junit.framework.TestCase;
-
 import java.util.HashSet;
 
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
 @SmallTest
-public class NetworkStatsTest extends TestCase {
+public class NetworkStatsTest {
 
     private static final String TEST_IFACE = "test0";
     private static final String TEST_IFACE2 = "test2";
     private static final int TEST_UID = 1001;
     private static final long TEST_START = 1194220800000L;
 
+    @Test
     public void testFindIndex() throws Exception {
         final NetworkStats stats = new NetworkStats(TEST_START, 5)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
@@ -74,6 +81,7 @@
                 ROAMING_NO));
     }
 
+    @Test
     public void testFindIndexHinted() {
         final NetworkStats stats = new NetworkStats(TEST_START, 3)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
@@ -116,6 +124,7 @@
         }
     }
 
+    @Test
     public void testAddEntryGrow() throws Exception {
         final NetworkStats stats = new NetworkStats(TEST_START, 4);
 
@@ -168,6 +177,7 @@
                 ROAMING_YES, 7L, 70L, 5L, 50L, 11);
     }
 
+    @Test
     public void testCombineExisting() throws Exception {
         final NetworkStats stats = new NetworkStats(TEST_START, 10);
 
@@ -190,6 +200,7 @@
                 256L, 2L, 256L, 2L, 6);
     }
 
+    @Test
     public void testSubtractIdenticalData() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
@@ -208,6 +219,7 @@
                 0L, 0L, 0L, 0);
     }
 
+    @Test
     public void testSubtractIdenticalRows() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
@@ -226,6 +238,7 @@
                 1L, 4L, 1L, 8);
     }
 
+    @Test
     public void testSubtractNewRows() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
@@ -247,6 +260,7 @@
                 1024L, 8L, 1024L, 8L, 20);
     }
 
+    @Test
     public void testSubtractMissingRows() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
                 .addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0)
@@ -264,6 +278,7 @@
         assertEquals(4L, result.getTotalBytes());
     }
 
+    @Test
     public void testTotalBytes() throws Exception {
         final NetworkStats iface = new NetworkStats(TEST_START, 2)
                 .addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L)
@@ -304,6 +319,7 @@
         assertEquals(96L, uidRoaming.getTotalBytes());
     }
 
+    @Test
     public void testGroupedByIfaceEmpty() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 3);
         final NetworkStats grouped = uidStats.groupedByIface();
@@ -312,6 +328,7 @@
         assertEquals(0, grouped.size());
     }
 
+    @Test
     public void testGroupedByIfaceAll() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
                 .addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L, 0L,
@@ -329,6 +346,7 @@
                 384L, 24L, 0L, 6L, 0L);
     }
 
+    @Test
     public void testGroupedByIface() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 7)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L,
@@ -357,6 +375,7 @@
                 1024L, 64L, 0L, 0L, 0L);
     }
 
+    @Test
     public void testAddAllValues() {
         final NetworkStats first = new NetworkStats(TEST_START, 5)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
@@ -387,6 +406,7 @@
                 32L, 0L, 0L, 0L, 0L);
     }
 
+    @Test
     public void testGetTotal() {
         final NetworkStats stats = new NetworkStats(TEST_START, 7)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L,
@@ -415,6 +435,7 @@
         assertValues(stats.getTotal(null, ifaces), 1024L, 64L, 0L, 0L, 0L);
     }
 
+    @Test
     public void testWithoutUid() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 3)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
@@ -433,6 +454,7 @@
                 8L, 0L, 0L, 0L);
     }
 
+    @Test
     public void testClone() throws Exception {
         final NetworkStats original = new NetworkStats(TEST_START, 5)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
@@ -449,6 +471,7 @@
         assertEquals(128L + 512L, clone.getTotalBytes());
     }
 
+    @Test
     public void testAddWhenEmpty() throws Exception {
         final NetworkStats red = new NetworkStats(TEST_START, -1);
         final NetworkStats blue = new NetworkStats(TEST_START, 5)
@@ -459,6 +482,7 @@
         red.combineAllValues(blue);
     }
 
+    @Test
     public void testMigrateTun() throws Exception {
         final int tunUid = 10030;
         final String tunIface = "tun0";
@@ -556,6 +580,7 @@
     // interface by the vpn app before it's sent out of the underlying interface. The VPN app should
     // not be charged for the echoed data but it should still be charged for any extra data it sends
     // via the underlying interface.
+    @Test
     public void testMigrateTun_VpnAsLoopback() {
         final int tunUid = 10030;
         final String tunIface = "tun0";
diff --git a/tests/net/java/android/net/NetworkTest.java b/tests/net/java/android/net/NetworkTest.java
new file mode 100644
index 0000000..bacf986
--- /dev/null
+++ b/tests/net/java/android/net/NetworkTest.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.net.LocalServerSocket;
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
+import android.net.Network;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.Inet6Address;
+import java.net.SocketException;
+import java.util.Objects;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NetworkTest {
+    final Network mNetwork = new Network(99);
+
+    @Test
+    public void testBindSocketOfInvalidFdThrows() throws Exception {
+
+        final FileDescriptor fd = new FileDescriptor();
+        assertFalse(fd.valid());
+
+        try {
+            mNetwork.bindSocket(fd);
+            fail("SocketException not thrown");
+        } catch (SocketException expected) {}
+    }
+
+    @Test
+    public void testBindSocketOfNonSocketFdThrows() throws Exception {
+        final File devNull = new File("/dev/null");
+        assertTrue(devNull.canRead());
+
+        final FileInputStream fis = new FileInputStream(devNull);
+        assertTrue(null != fis.getFD());
+        assertTrue(fis.getFD().valid());
+
+        try {
+            mNetwork.bindSocket(fis.getFD());
+            fail("SocketException not thrown");
+        } catch (SocketException expected) {}
+    }
+
+    @Test
+    public void testBindSocketOfConnectedDatagramSocketThrows() throws Exception {
+        final DatagramSocket mDgramSocket = new DatagramSocket(0, (InetAddress) Inet6Address.ANY);
+        mDgramSocket.connect((InetAddress) Inet6Address.LOOPBACK, 53);
+        assertTrue(mDgramSocket.isConnected());
+
+        try {
+            mNetwork.bindSocket(mDgramSocket);
+            fail("SocketException not thrown");
+        } catch (SocketException expected) {}
+    }
+
+    @Test
+    public void testBindSocketOfLocalSocketThrows() throws Exception {
+        final LocalSocket mLocalClient = new LocalSocket();
+        mLocalClient.bind(new LocalSocketAddress("testClient"));
+        assertTrue(mLocalClient.getFileDescriptor().valid());
+
+        try {
+            mNetwork.bindSocket(mLocalClient.getFileDescriptor());
+            fail("SocketException not thrown");
+        } catch (SocketException expected) {}
+
+        final LocalServerSocket mLocalServer = new LocalServerSocket("testServer");
+        mLocalClient.connect(mLocalServer.getLocalSocketAddress());
+        assertTrue(mLocalClient.isConnected());
+
+        try {
+            mNetwork.bindSocket(mLocalClient.getFileDescriptor());
+            fail("SocketException not thrown");
+        } catch (SocketException expected) {}
+    }
+
+    @Test
+    public void testZeroIsObviousForDebugging() {
+        Network zero = new Network(0);
+        assertEquals(0, zero.hashCode());
+        assertEquals(0, zero.getNetworkHandle());
+        assertEquals("0", zero.toString());
+    }
+
+    @Test
+    public void testGetNetworkHandle() {
+        Network one = new Network(1);
+        Network two = new Network(2);
+        Network three = new Network(3);
+
+        // None of the hashcodes are zero.
+        assertNotEqual(0, one.hashCode());
+        assertNotEqual(0, two.hashCode());
+        assertNotEqual(0, three.hashCode());
+
+        // All the hashcodes are distinct.
+        assertNotEqual(one.hashCode(), two.hashCode());
+        assertNotEqual(one.hashCode(), three.hashCode());
+        assertNotEqual(two.hashCode(), three.hashCode());
+
+        // None of the handles are zero.
+        assertNotEqual(0, one.getNetworkHandle());
+        assertNotEqual(0, two.getNetworkHandle());
+        assertNotEqual(0, three.getNetworkHandle());
+
+        // All the handles are distinct.
+        assertNotEqual(one.getNetworkHandle(), two.getNetworkHandle());
+        assertNotEqual(one.getNetworkHandle(), three.getNetworkHandle());
+        assertNotEqual(two.getNetworkHandle(), three.getNetworkHandle());
+
+        // The handles are not equal to the hashcodes.
+        assertNotEqual(one.hashCode(), one.getNetworkHandle());
+        assertNotEqual(two.hashCode(), two.getNetworkHandle());
+        assertNotEqual(three.hashCode(), three.getNetworkHandle());
+
+        // Adjust as necessary to test an implementation's specific constants.
+        // When running with runtest, "adb logcat -s TestRunner" can be useful.
+        assertEquals(4311403230L, one.getNetworkHandle());
+        assertEquals(8606370526L, two.getNetworkHandle());
+        assertEquals(12901337822L, three.getNetworkHandle());
+    }
+
+    private static <T> void assertNotEqual(T t1, T t2) {
+        assertFalse(Objects.equals(t1, t2));
+    }
+}
diff --git a/tests/net/java/android/net/StaticIpConfigurationTest.java b/tests/net/java/android/net/StaticIpConfigurationTest.java
new file mode 100644
index 0000000..5bb5734
--- /dev/null
+++ b/tests/net/java/android/net/StaticIpConfigurationTest.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import java.net.InetAddress;
+import java.util.HashSet;
+import java.util.Objects;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class StaticIpConfigurationTest {
+
+    private static final String ADDRSTR = "192.0.2.2/25";
+    private static final LinkAddress ADDR = new LinkAddress(ADDRSTR);
+    private static final InetAddress GATEWAY = IpAddress("192.0.2.1");
+    private static final InetAddress OFFLINKGATEWAY = IpAddress("192.0.2.129");
+    private static final InetAddress DNS1 = IpAddress("8.8.8.8");
+    private static final InetAddress DNS2 = IpAddress("8.8.4.4");
+    private static final InetAddress DNS3 = IpAddress("4.2.2.2");
+    private static final String IFACE = "eth0";
+
+    private static InetAddress IpAddress(String addr) {
+        return InetAddress.parseNumericAddress(addr);
+    }
+
+    private void checkEmpty(StaticIpConfiguration s) {
+        assertNull(s.ipAddress);
+        assertNull(s.gateway);
+        assertNull(s.domains);
+        assertEquals(0, s.dnsServers.size());
+    }
+
+    private static <T> void assertNotEquals(T t1, T t2) {
+        assertFalse(Objects.equals(t1, t2));
+    }
+
+    private StaticIpConfiguration makeTestObject() {
+        StaticIpConfiguration s = new StaticIpConfiguration();
+        s.ipAddress = ADDR;
+        s.gateway = GATEWAY;
+        s.dnsServers.add(DNS1);
+        s.dnsServers.add(DNS2);
+        s.dnsServers.add(DNS3);
+        s.domains = "google.com";
+        return s;
+    }
+
+    @Test
+    public void testConstructor() {
+        StaticIpConfiguration s = new StaticIpConfiguration();
+        checkEmpty(s);
+    }
+
+    @Test
+    public void testCopyAndClear() {
+        StaticIpConfiguration empty = new StaticIpConfiguration((StaticIpConfiguration) null);
+        checkEmpty(empty);
+
+        StaticIpConfiguration s1 = makeTestObject();
+        StaticIpConfiguration s2 = new StaticIpConfiguration(s1);
+        assertEquals(s1, s2);
+        s2.clear();
+        assertEquals(empty, s2);
+    }
+
+    @Test
+    public void testHashCodeAndEquals() {
+        HashSet<Integer> hashCodes = new HashSet();
+        hashCodes.add(0);
+
+        StaticIpConfiguration s = new StaticIpConfiguration();
+        // Check that this hash code is nonzero and different from all the ones seen so far.
+        assertTrue(hashCodes.add(s.hashCode()));
+
+        s.ipAddress = ADDR;
+        assertTrue(hashCodes.add(s.hashCode()));
+
+        s.gateway = GATEWAY;
+        assertTrue(hashCodes.add(s.hashCode()));
+
+        s.dnsServers.add(DNS1);
+        assertTrue(hashCodes.add(s.hashCode()));
+
+        s.dnsServers.add(DNS2);
+        assertTrue(hashCodes.add(s.hashCode()));
+
+        s.dnsServers.add(DNS3);
+        assertTrue(hashCodes.add(s.hashCode()));
+
+        s.domains = "example.com";
+        assertTrue(hashCodes.add(s.hashCode()));
+
+        assertFalse(s.equals(null));
+        assertEquals(s, s);
+
+        StaticIpConfiguration s2 = new StaticIpConfiguration(s);
+        assertEquals(s, s2);
+
+        s.ipAddress = new LinkAddress(DNS1, 32);
+        assertNotEquals(s, s2);
+
+        s2 = new StaticIpConfiguration(s);
+        s.domains = "foo";
+        assertNotEquals(s, s2);
+
+        s2 = new StaticIpConfiguration(s);
+        s.gateway = DNS2;
+        assertNotEquals(s, s2);
+
+        s2 = new StaticIpConfiguration(s);
+        s.dnsServers.add(DNS3);
+        assertNotEquals(s, s2);
+    }
+
+    @Test
+    public void testToLinkProperties() {
+        LinkProperties expected = new LinkProperties();
+        expected.setInterfaceName(IFACE);
+
+        StaticIpConfiguration s = new StaticIpConfiguration();
+        assertEquals(expected, s.toLinkProperties(IFACE));
+
+        final RouteInfo connectedRoute = new RouteInfo(new IpPrefix(ADDRSTR), null, IFACE);
+        s.ipAddress = ADDR;
+        expected.addLinkAddress(ADDR);
+        expected.addRoute(connectedRoute);
+        assertEquals(expected, s.toLinkProperties(IFACE));
+
+        s.gateway = GATEWAY;
+        RouteInfo defaultRoute = new RouteInfo(new IpPrefix("0.0.0.0/0"), GATEWAY, IFACE);
+        expected.addRoute(defaultRoute);
+        assertEquals(expected, s.toLinkProperties(IFACE));
+
+        s.gateway = OFFLINKGATEWAY;
+        expected.removeRoute(defaultRoute);
+        defaultRoute = new RouteInfo(new IpPrefix("0.0.0.0/0"), OFFLINKGATEWAY, IFACE);
+        expected.addRoute(defaultRoute);
+
+        RouteInfo gatewayRoute = new RouteInfo(new IpPrefix("192.0.2.129/32"), null, IFACE);
+        expected.addRoute(gatewayRoute);
+        assertEquals(expected, s.toLinkProperties(IFACE));
+
+        s.dnsServers.add(DNS1);
+        expected.addDnsServer(DNS1);
+        assertEquals(expected, s.toLinkProperties(IFACE));
+
+        s.dnsServers.add(DNS2);
+        s.dnsServers.add(DNS3);
+        expected.addDnsServer(DNS2);
+        expected.addDnsServer(DNS3);
+        assertEquals(expected, s.toLinkProperties(IFACE));
+
+        s.domains = "google.com";
+        expected.setDomains("google.com");
+        assertEquals(expected, s.toLinkProperties(IFACE));
+
+        s.gateway = null;
+        expected.removeRoute(defaultRoute);
+        expected.removeRoute(gatewayRoute);
+        assertEquals(expected, s.toLinkProperties(IFACE));
+
+        // Without knowing the IP address, we don't have a directly-connected route, so we can't
+        // tell if the gateway is off-link or not and we don't add a host route. This isn't a real
+        // configuration, but we should at least not crash.
+        s.gateway = OFFLINKGATEWAY;
+        s.ipAddress = null;
+        expected.removeLinkAddress(ADDR);
+        expected.removeRoute(connectedRoute);
+        expected.addRoute(defaultRoute);
+        assertEquals(expected, s.toLinkProperties(IFACE));
+    }
+
+    private StaticIpConfiguration passThroughParcel(StaticIpConfiguration s) {
+        Parcel p = Parcel.obtain();
+        StaticIpConfiguration s2 = null;
+        try {
+            s.writeToParcel(p, 0);
+            p.setDataPosition(0);
+            s2 = StaticIpConfiguration.CREATOR.createFromParcel(p);
+        } finally {
+            p.recycle();
+        }
+        assertNotNull(s2);
+        return s2;
+    }
+
+    @Test
+    public void testParceling() {
+        StaticIpConfiguration s = makeTestObject();
+        StaticIpConfiguration s2 = passThroughParcel(s);
+        assertEquals(s, s2);
+    }
+}
diff --git a/tests/net/java/android/net/UidRangeTest.java b/tests/net/java/android/net/UidRangeTest.java
index 0a56e1b..1d1013e 100644
--- a/tests/net/java/android/net/UidRangeTest.java
+++ b/tests/net/java/android/net/UidRangeTest.java
@@ -16,14 +16,20 @@
 
 package android.net;
 
-import android.os.Parcel;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.TestCase;
-
 import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 
-public class UidRangeTest extends TestCase {
+import android.os.Parcel;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class UidRangeTest {
 
     static {
         System.loadLibrary("frameworksnettestsjni");
@@ -33,7 +39,7 @@
     private static native int getStart(byte[] inParcel);
     private static native int getStop(byte[] inParcel);
 
-    @SmallTest
+    @Test
     public void testNativeParcelUnparcel() {
         UidRange original = new UidRange(1234, Integer.MAX_VALUE);
 
@@ -45,7 +51,7 @@
         assertArrayEquals(inParcel, outParcel);
     }
 
-    @SmallTest
+    @Test
     public void testIndividualNativeFields() {
         UidRange original = new UidRange(0x11115678, 0x22224321);
         byte[] originalBytes = marshall(original);
@@ -54,14 +60,14 @@
         assertEquals(original.stop, getStop(originalBytes));
     }
 
-    @SmallTest
+    @Test
     public void testSingleItemUidRangeAllowed() {
         new UidRange(123, 123);
         new UidRange(0, 0);
         new UidRange(Integer.MAX_VALUE, Integer.MAX_VALUE);
     }
 
-    @SmallTest
+    @Test
     public void testNegativeUidsDisallowed() {
         try {
             new UidRange(-2, 100);
@@ -76,7 +82,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testStopLessThanStartDisallowed() {
         final int x = 4195000;
         try {
diff --git a/tests/net/java/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java
index bfbb8cc..725ddb9 100644
--- a/tests/net/java/android/net/apf/ApfTest.java
+++ b/tests/net/java/android/net/apf/ApfTest.java
@@ -16,12 +16,20 @@
 
 package android.net.apf;
 
+import static android.system.OsConstants.*;
+import static com.android.internal.util.BitUtils.bytesToBEInt;
+import static com.android.internal.util.BitUtils.put;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.verify;
+
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.NetworkUtils;
-import android.net.apf.ApfCapabilities;
-import android.net.apf.ApfFilter;
-import android.net.apf.ApfGenerator;
+import android.net.apf.ApfFilter.ApfConfiguration;
 import android.net.apf.ApfGenerator.IllegalInstructionException;
 import android.net.apf.ApfGenerator.Register;
 import android.net.ip.IpManager;
@@ -30,23 +38,22 @@
 import android.os.ConditionVariable;
 import android.os.Parcelable;
 import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 import android.system.ErrnoException;
 import android.system.Os;
-import android.test.AndroidTestCase;
 import android.text.format.DateUtils;
-import android.test.suitebuilder.annotation.SmallTest;
-import static android.system.OsConstants.*;
 
 import com.android.frameworks.tests.net.R;
 import com.android.internal.util.HexDump;
-import static com.android.internal.util.BitUtils.bytesToBEInt;
-import static com.android.internal.util.BitUtils.put;
 
+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 static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.verify;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -69,14 +76,15 @@
  * Build, install and run with:
  *  runtest frameworks-net -c android.net.apf.ApfTest
  */
-public class ApfTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ApfTest {
     private static final int TIMEOUT_MS = 500;
 
     @Mock IpConnectivityLog mLog;
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
         MockitoAnnotations.initMocks(this);
         // Load up native shared library containing APF interpreter exposed via JNI.
         System.loadLibrary("frameworksnettestsjni");
@@ -89,12 +97,24 @@
     // least the minimum packet size.
     private final static int MIN_PKT_SIZE = 15;
 
+    private static final ApfCapabilities MOCK_APF_CAPABILITIES =
+      new ApfCapabilities(2, 1700, ARPHRD_ETHER);
+
     private final static boolean DROP_MULTICAST = true;
     private final static boolean ALLOW_MULTICAST = false;
 
     private final static boolean DROP_802_3_FRAMES = true;
     private final static boolean ALLOW_802_3_FRAMES = false;
 
+    private static ApfConfiguration getDefaultConfig() {
+        ApfFilter.ApfConfiguration config = new ApfConfiguration();
+        config.apfCapabilities = MOCK_APF_CAPABILITIES;
+        config.multicastFilter = ALLOW_MULTICAST;
+        config.ieee802_3Filter = ALLOW_802_3_FRAMES;
+        config.ethTypeBlackList = new int[0];
+        return config;
+    }
+
     private static String label(int code) {
         switch (code) {
             case PASS: return "PASS";
@@ -161,7 +181,7 @@
      * generating bytecode for that program and running it through the
      * interpreter to verify it functions correctly.
      */
-    @SmallTest
+    @Test
     public void testApfInstructions() throws IllegalInstructionException {
         // Empty program should pass because having the program counter reach the
         // location immediately after the program indicates the packet should be
@@ -569,7 +589,7 @@
      * Generate some BPF programs, translate them to APF, then run APF and BPF programs
      * over packet traces and verify both programs filter out the same packets.
      */
-    @SmallTest
+    @Test
     public void testApfAgainstBpf() throws Exception {
         String[] tcpdump_filters = new String[]{ "udp", "tcp", "icmp", "icmp6", "udp port 53",
                 "arp", "dst 239.255.255.250", "arp or tcp or udp port 53", "net 192.168.1.0/24",
@@ -609,14 +629,13 @@
 
     private static class TestApfFilter extends ApfFilter {
         public final static byte[] MOCK_MAC_ADDR = {1,2,3,4,5,6};
-        private FileDescriptor mWriteSocket;
 
+        private FileDescriptor mWriteSocket;
         private final long mFixedTimeMs = SystemClock.elapsedRealtime();
 
-        public TestApfFilter(IpManager.Callback ipManagerCallback, boolean multicastFilter,
-                boolean ieee802_3Filter, IpConnectivityLog log) throws Exception {
-            super(new ApfCapabilities(2, 1700, ARPHRD_ETHER), NetworkInterface.getByName("lo"),
-                    ipManagerCallback, multicastFilter, ieee802_3Filter, log);
+        public TestApfFilter(ApfConfiguration config, IpManager.Callback ipManagerCallback,
+                IpConnectivityLog log) throws Exception {
+            super(config, NetworkInterface.getByName("lo"), ipManagerCallback, log);
         }
 
         // Pretend an RA packet has been received and show it to ApfFilter.
@@ -738,15 +757,16 @@
     private static final byte[] ANOTHER_IPV4_ADDR        = {10, 0, 0, 2};
     private static final byte[] IPV4_ANY_HOST_ADDR       = {0, 0, 0, 0};
 
-    @SmallTest
+    @Test
     public void testApfFilterIPv4() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
         LinkProperties lp = new LinkProperties();
         lp.addLinkAddress(link);
 
-        ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST,
-                ALLOW_802_3_FRAMES, mLog);
+        ApfConfiguration config = getDefaultConfig();
+        config.multicastFilter = DROP_MULTICAST;
+        TestApfFilter apfFilter = new TestApfFilter(config, ipManagerCallback, mLog);
         apfFilter.setLinkProperties(lp);
 
         byte[] program = ipManagerCallback.getApfProgram();
@@ -794,11 +814,11 @@
         apfFilter.shutdown();
     }
 
-    @SmallTest
+    @Test
     public void testApfFilterIPv6() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
-        ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST,
-                ALLOW_802_3_FRAMES, mLog);
+        ApfConfiguration config = getDefaultConfig();
+        TestApfFilter apfFilter = new TestApfFilter(config, ipManagerCallback, mLog);
         byte[] program = ipManagerCallback.getApfProgram();
 
         // Verify empty IPv6 packet is passed
@@ -827,7 +847,7 @@
         apfFilter.shutdown();
     }
 
-    @SmallTest
+    @Test
     public void testApfFilterMulticast() throws Exception {
         final byte[] unicastIpv4Addr   = {(byte)192,0,2,63};
         final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255};
@@ -839,8 +859,9 @@
         LinkProperties lp = new LinkProperties();
         lp.addLinkAddress(link);
 
-        ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST,
-                DROP_802_3_FRAMES, mLog);
+        ApfConfiguration config = getDefaultConfig();
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        TestApfFilter apfFilter = new TestApfFilter(config, ipManagerCallback, mLog);
         apfFilter.setLinkProperties(lp);
 
         byte[] program = ipManagerCallback.getApfProgram();
@@ -902,8 +923,9 @@
         // Verify it can be initialized to on
         ipManagerCallback.resetApfProgramWait();
         apfFilter.shutdown();
-        apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST,
-                DROP_802_3_FRAMES, mLog);
+        config.multicastFilter = DROP_MULTICAST;
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        apfFilter = new TestApfFilter(config, ipManagerCallback, mLog);
         apfFilter.setLinkProperties(lp);
         program = ipManagerCallback.getApfProgram();
         assertDrop(program, mcastv4packet.array());
@@ -918,15 +940,15 @@
         apfFilter.shutdown();
     }
 
-    @SmallTest
+    @Test
     public void testApfFilter802_3() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
         LinkProperties lp = new LinkProperties();
         lp.addLinkAddress(link);
 
-        ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST,
-                ALLOW_802_3_FRAMES, mLog);
+        ApfConfiguration config = getDefaultConfig();
+        TestApfFilter apfFilter = new TestApfFilter(config, ipManagerCallback, mLog);
         apfFilter.setLinkProperties(lp);
 
         byte[] program = ipManagerCallback.getApfProgram();
@@ -947,8 +969,8 @@
         // Now turn on the filter
         ipManagerCallback.resetApfProgramWait();
         apfFilter.shutdown();
-        apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST,
-                DROP_802_3_FRAMES, mLog);
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        apfFilter = new TestApfFilter(config, ipManagerCallback, mLog);
         apfFilter.setLinkProperties(lp);
         program = ipManagerCallback.getApfProgram();
 
@@ -968,6 +990,70 @@
         apfFilter.shutdown();
     }
 
+    @Test
+    public void testApfFilterEthTypeBL() throws Exception {
+        MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
+        LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
+        LinkProperties lp = new LinkProperties();
+        lp.addLinkAddress(link);
+        final int[] emptyBlackList = {};
+        final int[] ipv4BlackList = {ETH_P_IP};
+        final int[] ipv4Ipv6BlackList = {ETH_P_IP, ETH_P_IPV6};
+
+        ApfConfiguration config = getDefaultConfig();
+        TestApfFilter apfFilter = new TestApfFilter(config, ipManagerCallback, mLog);
+        apfFilter.setLinkProperties(lp);
+
+        byte[] program = ipManagerCallback.getApfProgram();
+
+        // Verify empty packet of 100 zero bytes is passed
+        // Note that eth-type = 0 makes it an IEEE802.3 frame
+        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
+        assertPass(program, packet.array());
+
+        // Verify empty packet with IPv4 is passed
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
+        assertPass(program, packet.array());
+
+        // Verify empty IPv6 packet is passed
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
+        assertPass(program, packet.array());
+
+        // Now add IPv4 to the black list
+        ipManagerCallback.resetApfProgramWait();
+        apfFilter.shutdown();
+        config.ethTypeBlackList = ipv4BlackList;
+        apfFilter = new TestApfFilter(config, ipManagerCallback, mLog);
+        apfFilter.setLinkProperties(lp);
+        program = ipManagerCallback.getApfProgram();
+
+        // Verify that IPv4 frame will be dropped
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
+        assertDrop(program, packet.array());
+
+        // Verify that IPv6 frame will pass
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
+        assertPass(program, packet.array());
+
+        // Now let us have both IPv4 and IPv6 in the black list
+        ipManagerCallback.resetApfProgramWait();
+        apfFilter.shutdown();
+        config.ethTypeBlackList = ipv4Ipv6BlackList;
+        apfFilter = new TestApfFilter(config, ipManagerCallback, mLog);
+        apfFilter.setLinkProperties(lp);
+        program = ipManagerCallback.getApfProgram();
+
+        // Verify that IPv4 frame will be dropped
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
+        assertDrop(program, packet.array());
+
+        // Verify that IPv6 frame will be dropped
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
+        assertDrop(program, packet.array());
+
+        apfFilter.shutdown();
+    }
+
     private byte[] getProgram(MockIpManagerCallback cb, ApfFilter filter, LinkProperties lp) {
         cb.resetApfProgramWait();
         filter.setLinkProperties(lp);
@@ -989,11 +1075,13 @@
         assertDrop(program, garpReply());
     }
 
-    @SmallTest
+    @Test
     public void testApfFilterArp() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
-        ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST,
-                DROP_802_3_FRAMES, mLog);
+        ApfConfiguration config = getDefaultConfig();
+        config.multicastFilter = DROP_MULTICAST;
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        TestApfFilter apfFilter = new TestApfFilter(config, ipManagerCallback, mLog);
 
         // Verify initially ARP request filter is off, and GARP filter is on.
         verifyArpFilter(ipManagerCallback.getApfProgram(), PASS);
@@ -1066,7 +1154,7 @@
 
     // Test that when ApfFilter is shown the given packet, it generates a program to filter it
     // for the given lifetime.
-    private void testRaLifetime(TestApfFilter apfFilter, MockIpManagerCallback ipManagerCallback,
+    private void verifyRaLifetime(TestApfFilter apfFilter, MockIpManagerCallback ipManagerCallback,
             ByteBuffer packet, int lifetime) throws IOException, ErrnoException {
         // Verify new program generated if ApfFilter witnesses RA
         ipManagerCallback.resetApfProgramWait();
@@ -1111,11 +1199,13 @@
         ipManagerCallback.assertNoProgramUpdate();
     }
 
-    @SmallTest
+    @Test
     public void testApfFilterRa() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
-        TestApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST,
-                DROP_802_3_FRAMES, mLog);
+        ApfConfiguration config = getDefaultConfig();
+        config.multicastFilter = DROP_MULTICAST;
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        TestApfFilter apfFilter = new TestApfFilter(config, ipManagerCallback, mLog);
         byte[] program = ipManagerCallback.getApfProgram();
 
         final int ROUTER_LIFETIME = 1000;
@@ -1141,7 +1231,7 @@
         basePacket.put(IPV6_ALL_NODES_ADDRESS);
         assertPass(program, basePacket.array());
 
-        testRaLifetime(apfFilter, ipManagerCallback, basePacket, ROUTER_LIFETIME);
+        verifyRaLifetime(apfFilter, ipManagerCallback, basePacket, ROUTER_LIFETIME);
         verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, -1));
 
         ByteBuffer newFlowLabelPacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]);
@@ -1176,7 +1266,8 @@
         prefixOptionPacket.putInt(
                 ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET,
                 PREFIX_VALID_LIFETIME);
-        testRaLifetime(apfFilter, ipManagerCallback, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME);
+        verifyRaLifetime(
+                apfFilter, ipManagerCallback, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME);
         verifyRaEvent(new RaEvent(
                 ROUTER_LIFETIME, PREFIX_VALID_LIFETIME, PREFIX_PREFERRED_LIFETIME, -1, -1, -1));
 
@@ -1188,7 +1279,7 @@
         rdnssOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
         rdnssOptionPacket.putInt(
                 ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, RDNSS_LIFETIME);
-        testRaLifetime(apfFilter, ipManagerCallback, rdnssOptionPacket, RDNSS_LIFETIME);
+        verifyRaLifetime(apfFilter, ipManagerCallback, rdnssOptionPacket, RDNSS_LIFETIME);
         verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, RDNSS_LIFETIME, -1));
 
         ByteBuffer routeInfoOptionPacket = ByteBuffer.wrap(
@@ -1199,7 +1290,7 @@
         routeInfoOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
         routeInfoOptionPacket.putInt(
                 ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, ROUTE_LIFETIME);
-        testRaLifetime(apfFilter, ipManagerCallback, routeInfoOptionPacket, ROUTE_LIFETIME);
+        verifyRaLifetime(apfFilter, ipManagerCallback, routeInfoOptionPacket, ROUTE_LIFETIME);
         verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, ROUTE_LIFETIME, -1, -1));
 
         ByteBuffer dnsslOptionPacket = ByteBuffer.wrap(
@@ -1210,7 +1301,7 @@
         dnsslOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
         dnsslOptionPacket.putInt(
                 ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, DNSSL_LIFETIME);
-        testRaLifetime(apfFilter, ipManagerCallback, dnsslOptionPacket, ROUTER_LIFETIME);
+        verifyRaLifetime(apfFilter, ipManagerCallback, dnsslOptionPacket, ROUTER_LIFETIME);
         verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, DNSSL_LIFETIME));
 
         // Verify that current program filters all five RAs:
@@ -1230,12 +1321,12 @@
      * copy that resource into the app's data directory and return the path to it.
      */
     private String stageFile(int rawId) throws Exception {
-        File file = new File(getContext().getFilesDir(), "staged_file");
+        File file = new File(InstrumentationRegistry.getContext().getFilesDir(), "staged_file");
         new File(file.getParent()).mkdirs();
         InputStream in = null;
         OutputStream out = null;
         try {
-            in = getContext().getResources().openRawResource(rawId);
+            in = InstrumentationRegistry.getContext().getResources().openRawResource(rawId);
             out = new FileOutputStream(file);
             Streams.copy(in, out);
         } finally {
@@ -1252,13 +1343,15 @@
         buffer.position(original);
     }
 
-    @SmallTest
+    @Test
     public void testRaParsing() throws Exception {
         final int maxRandomPacketSize = 512;
         final Random r = new Random();
         MockIpManagerCallback cb = new MockIpManagerCallback();
-        TestApfFilter apfFilter = new TestApfFilter(cb, DROP_MULTICAST,
-                DROP_802_3_FRAMES, mLog);
+        ApfConfiguration config = getDefaultConfig();
+        config.multicastFilter = DROP_MULTICAST;
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        TestApfFilter apfFilter = new TestApfFilter(config, cb, mLog);
         for (int i = 0; i < 1000; i++) {
             byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
             r.nextBytes(packet);
@@ -1271,13 +1364,15 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testRaProcessing() throws Exception {
         final int maxRandomPacketSize = 512;
         final Random r = new Random();
         MockIpManagerCallback cb = new MockIpManagerCallback();
-        TestApfFilter apfFilter = new TestApfFilter(cb, DROP_MULTICAST,
-                DROP_802_3_FRAMES, mLog);
+        ApfConfiguration config = getDefaultConfig();
+        config.multicastFilter = DROP_MULTICAST;
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        TestApfFilter apfFilter = new TestApfFilter(config, cb, mLog);
         for (int i = 0; i < 1000; i++) {
             byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
             r.nextBytes(packet);
@@ -1310,7 +1405,7 @@
     private native static boolean compareBpfApf(String filter, String pcap_filename,
             byte[] apf_program);
 
-    @SmallTest
+    @Test
     public void testBroadcastAddress() throws Exception {
         assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 0));
         assertEqualsIp("0.0.0.0", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 32));
diff --git a/tests/net/java/android/net/dhcp/DhcpPacketTest.java b/tests/net/java/android/net/dhcp/DhcpPacketTest.java
index d79c312..050183c 100644
--- a/tests/net/java/android/net/dhcp/DhcpPacketTest.java
+++ b/tests/net/java/android/net/dhcp/DhcpPacketTest.java
@@ -16,23 +16,36 @@
 
 package android.net.dhcp;
 
+import static android.net.dhcp.DhcpPacket.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import android.net.DhcpResults;
 import android.net.LinkAddress;
 import android.net.NetworkUtils;
 import android.net.metrics.DhcpErrorEvent;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 import android.system.OsConstants;
-import android.test.suitebuilder.annotation.SmallTest;
+
 import com.android.internal.util.HexDump;
+
 import java.net.Inet4Address;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Random;
-import junit.framework.TestCase;
 
-import static android.net.dhcp.DhcpPacket.*;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
-public class DhcpPacketTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DhcpPacketTest {
 
     private static Inet4Address SERVER_ADDR = v4Address("192.0.2.1");
     private static Inet4Address CLIENT_ADDR = v4Address("192.0.2.234");
@@ -46,6 +59,7 @@
         return (Inet4Address) NetworkUtils.numericToInetAddress(addrString);
     }
 
+    @Before
     public void setUp() {
         DhcpPacket.testOverrideVendorId = "android-dhcp-???";
         DhcpPacket.testOverrideHostname = "android-01234567890abcde";
@@ -131,7 +145,7 @@
         assertEquals(expectedVendorInfo, offerPacket.mVendorInfo);
     }
 
-    @SmallTest
+    @Test
     public void testDomainName() throws Exception {
         byte[] nullByte = new byte[] { 0x00 };
         byte[] twoNullBytes = new byte[] { 0x00, 0x00 };
@@ -186,7 +200,7 @@
         assertEquals(leaseTimeMillis, offerPacket.getLeaseTimeMillis());
     }
 
-    @SmallTest
+    @Test
     public void testLeaseTime() throws Exception {
         byte[] noLease = null;
         byte[] tooShortLease = new byte[] { 0x00, 0x00 };
@@ -234,7 +248,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testIpAddress() throws Exception {
         byte[] slash11Netmask = new byte[] { (byte) 0xff, (byte) 0xe0, 0x00, 0x00 };
         byte[] slash24Netmask = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00 };
@@ -278,11 +292,11 @@
         assertEquals(mtu, dhcpResults.mtu);
     }
 
-    @SmallTest
+    @Test
     public void testOffer1() throws Exception {
-        // TODO: Turn all of these into golden files. This will probably require modifying
-        // Android.mk appropriately, making this into an AndroidTestCase, and adding code to read
-        // the golden files from the test APK's assets via mContext.getAssets().
+        // TODO: Turn all of these into golden files. This will probably require using
+        // android.support.test.InstrumentationRegistry for obtaining a Context object
+        // to read such golden files, along with an appropriate Android.mk.
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // IP header.
             "451001480000000080118849c0a89003c0a89ff7" +
@@ -311,7 +325,7 @@
                 null, "192.168.144.3", null, 7200, false, 0, dhcpResults);
     }
 
-    @SmallTest
+    @Test
     public void testOffer2() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // IP header.
@@ -343,7 +357,7 @@
         assertTrue(dhcpResults.hasMeteredHint());
     }
 
-    @SmallTest
+    @Test
     public void testBadIpPacket() throws Exception {
         final byte[] packet = HexDump.hexStringToByteArray(
             // IP header.
@@ -358,7 +372,7 @@
         fail("Dhcp packet parsing should have failed");
     }
 
-    @SmallTest
+    @Test
     public void testBadDhcpPacket() throws Exception {
         final byte[] packet = HexDump.hexStringToByteArray(
             // IP header.
@@ -377,7 +391,7 @@
         fail("Dhcp packet parsing should have failed");
     }
 
-    @SmallTest
+    @Test
     public void testBadTruncatedOffer() throws Exception {
         final byte[] packet = HexDump.hexStringToByteArray(
             // IP header.
@@ -406,7 +420,7 @@
         fail("Dhcp packet parsing should have failed");
     }
 
-    @SmallTest
+    @Test
     public void testBadOfferWithoutACookie() throws Exception {
         final byte[] packet = HexDump.hexStringToByteArray(
             // IP header.
@@ -437,7 +451,7 @@
         fail("Dhcp packet parsing should have failed");
     }
 
-    @SmallTest
+    @Test
     public void testOfferWithBadCookie() throws Exception {
         final byte[] packet = HexDump.hexStringToByteArray(
             // IP header.
@@ -473,7 +487,7 @@
         assertEquals(Integer.toHexString(expected), Integer.toHexString(got));
     }
 
-    @SmallTest
+    @Test
     public void testTruncatedOfferPackets() throws Exception {
         final byte[] packet = HexDump.hexStringToByteArray(
             // IP header.
@@ -507,7 +521,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testRandomPackets() throws Exception {
         final int maxRandomPacketSize = 512;
         final Random r = new Random();
@@ -547,7 +561,7 @@
                 null, "192.168.144.3", null, 7200, false, expectedMtu, dhcpResults);
     }
 
-    @SmallTest
+    @Test
     public void testMtu() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // IP header.
@@ -583,7 +597,7 @@
         checkMtu(packet, 0, mtuBytes(-1));
     }
 
-    @SmallTest
+    @Test
     public void testBadHwaddrLength() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // IP header.
@@ -652,7 +666,7 @@
         assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
     }
 
-    @SmallTest
+    @Test
     public void testPadAndOverloadedOptionsOffer() throws Exception {
         // A packet observed in the real world that is interesting for two reasons:
         //
@@ -691,7 +705,7 @@
                 null, "1.1.1.1", null, 43200, false, 0, dhcpResults);
     }
 
-    @SmallTest
+    @Test
     public void testBug2111() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // IP header.
@@ -721,7 +735,7 @@
                 "domain123.co.uk", "192.0.2.254", null, 49094, false, 0, dhcpResults);
     }
 
-    @SmallTest
+    @Test
     public void testBug2136() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // Ethernet header.
@@ -754,7 +768,7 @@
                 "lancs.ac.uk", "10.32.255.128", null, 7200, false, 0, dhcpResults);
     }
 
-    @SmallTest
+    @Test
     public void testUdpServerAnySourcePort() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // Ethernet header.
@@ -789,7 +803,7 @@
                 "wvm.edu", "10.1.105.252", null, 86400, false, 0, dhcpResults);
     }
 
-    @SmallTest
+    @Test
     public void testUdpInvalidDstPort() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // Ethernet header.
@@ -821,7 +835,7 @@
         } catch (ParseException expected) {}
     }
 
-    @SmallTest
+    @Test
     public void testMultipleRouters() throws Exception {
         final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
             // Ethernet header.
@@ -854,7 +868,7 @@
                 null, "192.171.189.2", null, 28800, false, 0, dhcpResults);
     }
 
-    @SmallTest
+    @Test
     public void testDiscoverPacket() throws Exception {
         short secs = 7;
         int transactionId = 0xdeadbeef;
diff --git a/tests/net/java/android/net/ip/IpManagerTest.java b/tests/net/java/android/net/ip/IpManagerTest.java
index 541f91ad..22d88fb 100644
--- a/tests/net/java/android/net/ip/IpManagerTest.java
+++ b/tests/net/java/android/net/ip/IpManagerTest.java
@@ -180,7 +180,8 @@
         // Add N - 1 addresses
         for (int i = 0; i < lastAddr; i++) {
             mObserver.addressUpdated(iface, new LinkAddress(addresses[i]));
-            verify(mCb, timeout(100).times(1)).onLinkPropertiesChange(any());
+            verify(mCb, timeout(100)).onLinkPropertiesChange(any());
+            reset(mCb);
         }
 
         // Add Nth address
diff --git a/tests/net/java/android/net/netlink/ConntrackMessageTest.java b/tests/net/java/android/net/netlink/ConntrackMessageTest.java
new file mode 100644
index 0000000..3aab942
--- /dev/null
+++ b/tests/net/java/android/net/netlink/ConntrackMessageTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assume.assumeTrue;
+
+import android.system.OsConstants;
+import libcore.util.HexEncoding;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ConntrackMessageTest {
+    private static final boolean USING_LE = (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN);
+
+    // Example 1: TCP (192.168.43.209, 44333) -> (23.211.13.26, 443)
+    public static final String CT_V4UPDATE_TCP_HEX =
+            // struct nlmsghdr
+            "50000000" +      // length = 80
+            "0001" +          // type = (1 << 8) | 0
+            "0501" +          // flags
+            "01000000" +      // seqno = 1
+            "00000000" +      // pid = 0
+            // struct nfgenmsg
+            "02" +            // nfgen_family  = AF_INET
+            "00" +            // version = NFNETLINK_V0
+            "0000" +          // res_id
+            // struct nlattr
+            "3400" +          // nla_len = 52
+            "0180" +          // nla_type = nested CTA_TUPLE_ORIG
+                // struct nlattr
+                "1400" +      // nla_len = 20
+                "0180" +      // nla_type = nested CTA_TUPLE_IP
+                    "0800 0100 C0A82BD1" +  // nla_type=CTA_IP_V4_SRC, ip=192.168.43.209
+                    "0800 0200 17D30D1A" +  // nla_type=CTA_IP_V4_DST, ip=23.211.13.26
+                // struct nlattr
+                "1C00" +      // nla_len = 28
+                "0280" +      // nla_type = nested CTA_TUPLE_PROTO
+                    "0500 0100 06 000000" +  // nla_type=CTA_PROTO_NUM, proto=6
+                    "0600 0200 AD2D 0000" +  // nla_type=CTA_PROTO_SRC_PORT, port=44333 (big endian)
+                    "0600 0300 01BB 0000" +  // nla_type=CTA_PROTO_DST_PORT, port=443 (big endian)
+            // struct nlattr
+            "0800" +          // nla_len = 8
+            "0700" +          // nla_type = CTA_TIMEOUT
+            "00069780";       // nla_value = 432000 (big endian)
+    public static final byte[] CT_V4UPDATE_TCP_BYTES =
+            HexEncoding.decode(CT_V4UPDATE_TCP_HEX.replaceAll(" ", "").toCharArray(), false);
+
+    // Example 2: UDP (100.96.167.146, 37069) -> (216.58.197.10, 443)
+    public static final String CT_V4UPDATE_UDP_HEX =
+            // struct nlmsghdr
+            "50000000" +      // length = 80
+            "0001" +          // type = (1 << 8) | 0
+            "0501" +          // flags
+            "01000000" +      // seqno = 1
+            "00000000" +      // pid = 0
+            // struct nfgenmsg
+            "02" +            // nfgen_family  = AF_INET
+            "00" +            // version = NFNETLINK_V0
+            "0000" +          // res_id
+            // struct nlattr
+            "3400" +          // nla_len = 52
+            "0180" +          // nla_type = nested CTA_TUPLE_ORIG
+                // struct nlattr
+                "1400" +      // nla_len = 20
+                "0180" +      // nla_type = nested CTA_TUPLE_IP
+                    "0800 0100 6460A792" +  // nla_type=CTA_IP_V4_SRC, ip=100.96.167.146
+                    "0800 0200 D83AC50A" +  // nla_type=CTA_IP_V4_DST, ip=216.58.197.10
+                // struct nlattr
+                "1C00" +      // nla_len = 28
+                "0280" +      // nla_type = nested CTA_TUPLE_PROTO
+                    "0500 0100 11 000000" +  // nla_type=CTA_PROTO_NUM, proto=17
+                    "0600 0200 90CD 0000" +  // nla_type=CTA_PROTO_SRC_PORT, port=37069 (big endian)
+                    "0600 0300 01BB 0000" +  // nla_type=CTA_PROTO_DST_PORT, port=443 (big endian)
+            // struct nlattr
+            "0800" +          // nla_len = 8
+            "0700" +          // nla_type = CTA_TIMEOUT
+            "000000B4";       // nla_value = 180 (big endian)
+    public static final byte[] CT_V4UPDATE_UDP_BYTES =
+            HexEncoding.decode(CT_V4UPDATE_UDP_HEX.replaceAll(" ", "").toCharArray(), false);
+
+    @Test
+    public void testConntrackIPv4TcpTimeoutUpdate() throws Exception {
+        assumeTrue(USING_LE);
+
+        final byte[] tcp = ConntrackMessage.newIPv4TimeoutUpdateRequest(
+                OsConstants.IPPROTO_TCP,
+                (Inet4Address) InetAddress.getByName("192.168.43.209"), 44333,
+                (Inet4Address) InetAddress.getByName("23.211.13.26"), 443,
+                432000);
+        assertArrayEquals(CT_V4UPDATE_TCP_BYTES, tcp);
+    }
+
+    @Test
+    public void testConntrackIPv4UdpTimeoutUpdate() throws Exception {
+        assumeTrue(USING_LE);
+
+        final byte[] udp = ConntrackMessage.newIPv4TimeoutUpdateRequest(
+                OsConstants.IPPROTO_UDP,
+                (Inet4Address) InetAddress.getByName("100.96.167.146"), 37069,
+                (Inet4Address) InetAddress.getByName("216.58.197.10"), 443,
+                180);
+        assertArrayEquals(CT_V4UPDATE_UDP_BYTES, udp);
+    }
+}
diff --git a/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java b/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
index 5deba27..6647760 100644
--- a/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
+++ b/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
@@ -19,20 +19,30 @@
 import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
 import static android.net.netlink.StructNlMsgHdr.NLM_F_ACK;
 import static android.net.netlink.StructNlMsgHdr.NLM_F_REPLACE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import android.net.netlink.NetlinkConstants;
 import android.net.netlink.NetlinkErrorMessage;
 import android.net.netlink.NetlinkMessage;
 import android.net.netlink.StructNlMsgErr;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 import android.util.Log;
+
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
-import junit.framework.TestCase;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
 import libcore.util.HexEncoding;
 
 
-public class NetlinkErrorMessageTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NetlinkErrorMessageTest {
     private final String TAG = "NetlinkErrorMessageTest";
 
     // Hexadecimal representation of packet capture.
@@ -54,7 +64,7 @@
     public static final byte[] NLM_ERROR_OK =
             HexEncoding.decode(NLM_ERROR_OK_HEX.toCharArray(), false);
 
-    @SmallTest
+    @Test
     public void testParseNlmErrorOk() {
         final ByteBuffer byteBuffer = ByteBuffer.wrap(NLM_ERROR_OK);
         byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
diff --git a/tests/net/java/android/net/netlink/NetlinkSocketTest.java b/tests/net/java/android/net/netlink/NetlinkSocketTest.java
index 78b3b70..bd36bac8 100644
--- a/tests/net/java/android/net/netlink/NetlinkSocketTest.java
+++ b/tests/net/java/android/net/netlink/NetlinkSocketTest.java
@@ -16,25 +16,35 @@
 
 package android.net.netlink;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
 import android.net.netlink.NetlinkSocket;
 import android.net.netlink.RtNetlinkNeighborMessage;
 import android.net.netlink.StructNdMsg;
 import android.net.netlink.StructNlMsgHdr;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 import android.system.ErrnoException;
 import android.system.NetlinkSocketAddress;
 import android.system.OsConstants;
 import android.util.Log;
+
 import java.io.InterruptedIOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
-import junit.framework.TestCase;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
 
-public class NetlinkSocketTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NetlinkSocketTest {
     private final String TAG = "NetlinkSocketTest";
 
-    @SmallTest
+    @Test
     public void testBasicWorkingGetNeighborsQuery() throws Exception {
         NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
         assertNotNull(s);
@@ -93,7 +103,7 @@
         s.close();
     }
 
-    @SmallTest
+    @Test
     public void testRepeatedCloseCallsAreQuiet() throws Exception {
         // Create a working NetlinkSocket.
         NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
diff --git a/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java b/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
index 029758e..c9fd74f 100644
--- a/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
+++ b/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
@@ -16,15 +16,19 @@
 
 package android.net.netlink;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
 import android.net.netlink.NetlinkConstants;
 import android.net.netlink.NetlinkMessage;
 import android.net.netlink.RtNetlinkNeighborMessage;
 import android.net.netlink.StructNdMsg;
 import android.net.netlink.StructNlMsgHdr;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 import android.system.OsConstants;
 import android.util.Log;
-import libcore.util.HexEncoding;
 
 import java.net.Inet4Address;
 import java.net.InetAddress;
@@ -32,10 +36,15 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.Arrays;
-import junit.framework.TestCase;
 
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
-public class RtNetlinkNeighborMessageTest extends TestCase {
+import libcore.util.HexEncoding;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class RtNetlinkNeighborMessageTest {
     private final String TAG = "RtNetlinkNeighborMessageTest";
 
     // Hexadecimal representation of packet capture.
@@ -136,7 +145,7 @@
     public static final byte[] RTM_GETNEIGH_RESPONSE =
             HexEncoding.decode(RTM_GETNEIGH_RESPONSE_HEX.replaceAll(" ", "").toCharArray(), false);
 
-    @SmallTest
+    @Test
     public void testParseRtmDelNeigh() {
         final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_DELNEIGH);
         byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
@@ -163,7 +172,7 @@
         assertEquals(InetAddress.parseNumericAddress("192.168.159.254"), destination);
     }
 
-    @SmallTest
+    @Test
     public void testParseRtmNewNeigh() {
         final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_NEWNEIGH);
         byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
@@ -190,7 +199,7 @@
         assertEquals(InetAddress.parseNumericAddress("fe80::86c9:b2ff:fe6a:ed4b"), destination);
     }
 
-    @SmallTest
+    @Test
     public void testParseRtmGetNeighResponse() {
         final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_GETNEIGH_RESPONSE);
         byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
@@ -215,7 +224,7 @@
         assertEquals(14, messageCount);
     }
 
-    @SmallTest
+    @Test
     public void testCreateRtmNewNeighMessage() {
         final int seqNo = 2635;
         final int ifIndex = 14;
diff --git a/tests/net/java/android/net/nsd/NsdManagerTest.java b/tests/net/java/android/net/nsd/NsdManagerTest.java
index f77608f..0a5a6aa 100644
--- a/tests/net/java/android/net/nsd/NsdManagerTest.java
+++ b/tests/net/java/android/net/nsd/NsdManagerTest.java
@@ -28,6 +28,7 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+import static com.android.internal.util.TestUtils.waitForIdleHandler;
 
 import android.os.HandlerThread;
 import android.os.Handler;
@@ -38,6 +39,7 @@
 import android.os.Message;
 import android.os.Messenger;
 import com.android.internal.util.AsyncChannel;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -56,7 +58,9 @@
     @Mock INsdManager mService;
     MockServiceHandler mServiceHandler;
 
-    long mTimeoutMs = 100; // non-final so that tests can adjust the value.
+    NsdManager mManager;
+
+    long mTimeoutMs = 200; // non-final so that tests can adjust the value.
 
     @Before
     public void setUp() throws Exception {
@@ -64,11 +68,23 @@
 
         mServiceHandler = spy(MockServiceHandler.create(mContext));
         when(mService.getMessenger()).thenReturn(new Messenger(mServiceHandler));
+
+        mManager = makeManager();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mServiceHandler.waitForIdle(mTimeoutMs);
+        mServiceHandler.chan.disconnect();
+        mServiceHandler.stop();
+        if (mManager != null) {
+            mManager.disconnect();
+        }
     }
 
     @Test
     public void testResolveService() {
-        NsdManager manager = makeManager();
+        NsdManager manager = mManager;
 
         NsdServiceInfo request = new NsdServiceInfo("a_name", "a_type");
         NsdServiceInfo reply = new NsdServiceInfo("resolved_name", "resolved_type");
@@ -88,7 +104,7 @@
 
     @Test
     public void testParallelResolveService() {
-        NsdManager manager = makeManager();
+        NsdManager manager = mManager;
 
         NsdServiceInfo request = new NsdServiceInfo("a_name", "a_type");
         NsdServiceInfo reply = new NsdServiceInfo("resolved_name", "resolved_type");
@@ -111,7 +127,7 @@
 
     @Test
     public void testRegisterService() {
-        NsdManager manager = makeManager();
+        NsdManager manager = mManager;
 
         NsdServiceInfo request1 = new NsdServiceInfo("a_name", "a_type");
         NsdServiceInfo request2 = new NsdServiceInfo("another_name", "another_type");
@@ -170,7 +186,7 @@
 
     @Test
     public void testDiscoverService() {
-        NsdManager manager = makeManager();
+        NsdManager manager = mManager;
 
         NsdServiceInfo reply1 = new NsdServiceInfo("a_name", "a_type");
         NsdServiceInfo reply2 = new NsdServiceInfo("another_name", "a_type");
@@ -248,7 +264,7 @@
 
     @Test
     public void testInvalidCalls() {
-        NsdManager manager = new NsdManager(mContext, mService);
+        NsdManager manager = mManager;
 
         NsdManager.RegistrationListener listener1 = mock(NsdManager.RegistrationListener.class);
         NsdManager.DiscoveryListener listener2 = mock(NsdManager.DiscoveryListener.class);
@@ -318,9 +334,10 @@
     }
 
     int verifyRequest(int expectedMessageType) {
+        mServiceHandler.waitForIdle(mTimeoutMs);
         verify(mServiceHandler, timeout(mTimeoutMs)).handleMessage(any());
         reset(mServiceHandler);
-        Message received = mServiceHandler.lastMessage;
+        Message received = mServiceHandler.getLastMessage();
         assertEquals(NsdManager.nameOf(expectedMessageType), NsdManager.nameOf(received.what));
         return received.arg2;
     }
@@ -331,27 +348,43 @@
 
     // Implements the server side of AsyncChannel connection protocol
     public static class MockServiceHandler extends Handler {
-        public Context mContext;
+        public final Context context;
         public AsyncChannel chan;
-        public volatile Message lastMessage;
+        public Message lastMessage;
 
-        MockServiceHandler(Looper looper, Context context) {
-            super(looper);
-            mContext = context;
+        MockServiceHandler(Looper l, Context c) {
+            super(l);
+            context = c;
+        }
+
+        synchronized Message getLastMessage() {
+            return lastMessage;
+        }
+
+        synchronized void setLastMessage(Message msg) {
+            lastMessage = obtainMessage();
+            lastMessage.copyFrom(msg);
+        }
+
+        void waitForIdle(long timeoutMs) {
+            waitForIdleHandler(this, timeoutMs);
         }
 
         @Override
         public void handleMessage(Message msg) {
-            lastMessage = obtainMessage();
-            lastMessage.copyFrom(msg);
+            setLastMessage(msg);
             if (msg.what == AsyncChannel.CMD_CHANNEL_FULL_CONNECTION) {
                 chan = new AsyncChannel();
-                chan.connect(mContext, this, msg.replyTo);
+                chan.connect(context, this, msg.replyTo);
                 chan.sendMessage(AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED);
             }
         }
 
-        public static MockServiceHandler create(Context context) {
+        void stop() {
+            getLooper().quitSafely();
+        }
+
+        static MockServiceHandler create(Context context) {
             HandlerThread t = new HandlerThread("mock-service-handler");
             t.start();
             return new MockServiceHandler(t.getLooper(), context);
diff --git a/tests/net/java/android/net/util/BlockingSocketReaderTest.java b/tests/net/java/android/net/util/BlockingSocketReaderTest.java
index e03350f..29dfa4c 100644
--- a/tests/net/java/android/net/util/BlockingSocketReaderTest.java
+++ b/tests/net/java/android/net/util/BlockingSocketReaderTest.java
@@ -16,17 +16,25 @@
 
 package android.net.util;
 
+import static android.net.util.BlockingSocketReader.DEFAULT_RECV_BUF_SIZE;
 import static android.system.OsConstants.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.StructTimeval;
 
-import libcore.io.IoBridge;
-
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.UncheckedIOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.Inet6Address;
@@ -37,15 +45,21 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-import junit.framework.TestCase;
+import org.junit.runner.RunWith;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 
+import libcore.io.IoBridge;
 
 /**
  * Tests for BlockingSocketReader.
  *
  * @hide
  */
-public class BlockingSocketReaderTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class BlockingSocketReaderTest {
     static final InetAddress LOOPBACK6 = Inet6Address.getLoopbackAddress();
     static final StructTimeval TIMEO = StructTimeval.fromMillis(500);
 
@@ -53,61 +67,83 @@
     protected FileDescriptor mLocalSocket;
     protected InetSocketAddress mLocalSockName;
     protected byte[] mLastRecvBuf;
-    protected boolean mExited;
+    protected boolean mStopped;
+    protected HandlerThread mHandlerThread;
     protected BlockingSocketReader mReceiver;
 
-    @Override
+    class UdpLoopbackReader extends BlockingSocketReader {
+        public UdpLoopbackReader(Handler h) {
+            super(h);
+        }
+
+        @Override
+        protected FileDescriptor createFd() {
+            FileDescriptor s = null;
+            try {
+                s = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+                Os.bind(s, LOOPBACK6, 0);
+                mLocalSockName = (InetSocketAddress) Os.getsockname(s);
+                Os.setsockoptTimeval(s, SOL_SOCKET, SO_SNDTIMEO, TIMEO);
+            } catch (ErrnoException|SocketException e) {
+                closeFd(s);
+                fail();
+                return null;
+            }
+
+            mLocalSocket = s;
+            return s;
+        }
+
+        @Override
+        protected void handlePacket(byte[] recvbuf, int length) {
+            mLastRecvBuf = Arrays.copyOf(recvbuf, length);
+            mLatch.countDown();
+        }
+
+        @Override
+        protected void onStart() {
+            mStopped = false;
+            mLatch.countDown();
+        }
+
+        @Override
+        protected void onStop() {
+            mStopped = true;
+            mLatch.countDown();
+        }
+    };
+
+    @Before
     public void setUp() {
         resetLatch();
         mLocalSocket = null;
         mLocalSockName = null;
         mLastRecvBuf = null;
-        mExited = false;
+        mStopped = false;
 
-        mReceiver = new BlockingSocketReader() {
-            @Override
-            protected FileDescriptor createSocket() {
-                FileDescriptor s = null;
-                try {
-                    s = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
-                    Os.bind(s, LOOPBACK6, 0);
-                    mLocalSockName = (InetSocketAddress) Os.getsockname(s);
-                    Os.setsockoptTimeval(s, SOL_SOCKET, SO_SNDTIMEO, TIMEO);
-                } catch (ErrnoException|SocketException e) {
-                    closeSocket(s);
-                    fail();
-                    return null;
-                }
-
-                mLocalSocket = s;
-                return s;
-            }
-
-            @Override
-            protected void handlePacket(byte[] recvbuf, int length) {
-                mLastRecvBuf = Arrays.copyOf(recvbuf, length);
-                mLatch.countDown();
-            }
-
-            @Override
-            protected void onExit() {
-                mExited = true;
-                mLatch.countDown();
-            }
-        };
+        mHandlerThread = new HandlerThread(BlockingSocketReaderTest.class.getSimpleName());
+        mHandlerThread.start();
     }
 
-    @Override
-    public void tearDown() {
-        if (mReceiver != null) mReceiver.stop();
+    @After
+    public void tearDown() throws Exception {
+        if (mReceiver != null) {
+            mHandlerThread.getThreadHandler().post(() -> { mReceiver.stop(); });
+            waitForActivity();
+        }
         mReceiver = null;
+        mHandlerThread.quit();
+        mHandlerThread = null;
     }
 
     void resetLatch() { mLatch = new CountDownLatch(1); }
 
     void waitForActivity() throws Exception {
-        assertTrue(mLatch.await(500, TimeUnit.MILLISECONDS));
-        resetLatch();
+        try {
+            mLatch.await(1000, TimeUnit.MILLISECONDS);
+        } finally {
+            resetLatch();
+        }
     }
 
     void sendPacket(byte[] contents) throws Exception {
@@ -117,32 +153,57 @@
         sender.close();
     }
 
+    @Test
     public void testBasicWorking() throws Exception {
-        assertTrue(mReceiver.start());
+        final Handler h = mHandlerThread.getThreadHandler();
+        mReceiver = new UdpLoopbackReader(h);
+
+        h.post(() -> { mReceiver.start(); });
+        waitForActivity();
         assertTrue(mLocalSockName != null);
         assertEquals(LOOPBACK6, mLocalSockName.getAddress());
         assertTrue(0 < mLocalSockName.getPort());
         assertTrue(mLocalSocket != null);
-        assertFalse(mExited);
+        assertFalse(mStopped);
 
         final byte[] one = "one 1".getBytes("UTF-8");
         sendPacket(one);
         waitForActivity();
         assertEquals(1, mReceiver.numPacketsReceived());
         assertTrue(Arrays.equals(one, mLastRecvBuf));
-        assertFalse(mExited);
+        assertFalse(mStopped);
 
         final byte[] two = "two 2".getBytes("UTF-8");
         sendPacket(two);
         waitForActivity();
         assertEquals(2, mReceiver.numPacketsReceived());
         assertTrue(Arrays.equals(two, mLastRecvBuf));
-        assertFalse(mExited);
+        assertFalse(mStopped);
 
         mReceiver.stop();
         waitForActivity();
         assertEquals(2, mReceiver.numPacketsReceived());
         assertTrue(Arrays.equals(two, mLastRecvBuf));
-        assertTrue(mExited);
+        assertTrue(mStopped);
+        mReceiver = null;
+    }
+
+    class NullBlockingSocketReader extends BlockingSocketReader {
+        public NullBlockingSocketReader(Handler h, int recvbufsize) {
+            super(h, recvbufsize);
+        }
+
+        @Override
+        public FileDescriptor createFd() { return null; }
+    }
+
+    @Test
+    public void testMinimalRecvBufSize() throws Exception {
+        final Handler h = mHandlerThread.getThreadHandler();
+
+        for (int i : new int[]{-1, 0, 1, DEFAULT_RECV_BUF_SIZE-1}) {
+            final BlockingSocketReader b = new NullBlockingSocketReader(h, i);
+            assertEquals(DEFAULT_RECV_BUF_SIZE, b.recvBufSize());
+        }
     }
 }
diff --git a/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java b/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java
index dd679bc..38d3d74 100644
--- a/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java
+++ b/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java
@@ -17,18 +17,25 @@
 package android.net.util;
 
 import static android.net.util.NetworkConstants.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
 import libcore.util.HexEncoding;
 
-import junit.framework.TestCase;
-
-
 /**
  * Tests for ConnectivityPacketSummary.
  *
  * @hide
  */
-public class ConnectivityPacketSummaryTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ConnectivityPacketSummaryTest {
     private static final byte[] MYHWADDR = {
         asByte(0x80), asByte(0x7a), asByte(0xbf), asByte(0x6f), asByte(0x48), asByte(0xf3)
     };
@@ -39,6 +46,7 @@
         return ConnectivityPacketSummary.summarize(MYHWADDR, bytes);
     }
 
+    @Test
     public void testParseICMPv6DADProbe() {
         final String packet =
                 // Ethernet
@@ -60,6 +68,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testParseICMPv6RS() {
         final String packet =
                 // Ethernet
@@ -81,6 +90,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testParseICMPv6RA() {
         final String packet =
                 // Ethernet
@@ -113,6 +123,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testParseICMPv6NS() {
         final String packet =
                 // Ethernet
@@ -135,6 +146,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testInvalidICMPv6NDLength() {
         final String packet =
                 // Ethernet
@@ -159,6 +171,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testParseICMPv6NA() {
         final String packet =
                 // Ethernet
@@ -179,6 +192,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testParseARPRequest() {
         final String packet =
                 // Ethernet
@@ -197,6 +211,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testParseARPReply() {
         final String packet =
                 // Ethernet
@@ -217,6 +232,7 @@
         assertEquals(expected, getSummary(packet));
     }
 
+    @Test
     public void testParseDHCPv4Discover() {
         final String packet =
                 // Ethernet
@@ -262,6 +278,7 @@
         assertTrue(getSummary(packet).startsWith(expectedPrefix));
     }
 
+    @Test
     public void testParseDHCPv4Offer() {
         final String packet =
                 // Ethernet
@@ -307,6 +324,7 @@
         assertTrue(getSummary(packet).startsWith(expectedPrefix));
     }
 
+    @Test
     public void testParseDHCPv4Request() {
         final String packet =
                 // Ethernet
@@ -354,6 +372,7 @@
         assertTrue(getSummary(packet).startsWith(expectedPrefix));
     }
 
+    @Test
     public void testParseDHCPv4Ack() {
         final String packet =
                 // Ethernet
diff --git a/tests/net/java/android/net/util/IpUtilsTest.java b/tests/net/java/android/net/util/IpUtilsTest.java
index c2d1608..8903bf9 100644
--- a/tests/net/java/android/net/util/IpUtilsTest.java
+++ b/tests/net/java/android/net/util/IpUtilsTest.java
@@ -16,15 +16,19 @@
 
 package android.net.util;
 
-import android.net.util.IpUtils;
-import android.test.suitebuilder.annotation.SmallTest;
+import static org.junit.Assert.assertEquals;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 
 import java.nio.ByteBuffer;
 
-import junit.framework.TestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
-
-public class IpUtilsTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IpUtilsTest {
 
     private static final int IPV4_HEADER_LENGTH = 20;
     private static final int IPV6_HEADER_LENGTH = 40;
@@ -67,7 +71,7 @@
     //           "hello")
     // print JavaPacketDefinition(str(packet))
 
-    @SmallTest
+    @Test
     public void testIpv6TcpChecksum() throws Exception {
         // packet = (scapy.IPv6(src="2001:db8::1", dst="2001:db8::2", tc=0x80) /
         //           scapy.TCP(sport=12345, dport=7,
@@ -115,7 +119,7 @@
         assertEquals(0, IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen));
     }
 
-    @SmallTest
+    @Test
     public void testIpv4UdpChecksum() {
         // packet = (scapy.IP(src="192.0.2.1", dst="192.0.2.2", tos=0x40) /
         //           scapy.UDP(sport=32012, dport=4500) /
diff --git a/tests/net/java/android/net/util/VersionedBroadcastListenerTest.java b/tests/net/java/android/net/util/VersionedBroadcastListenerTest.java
new file mode 100644
index 0000000..39f59f1
--- /dev/null
+++ b/tests/net/java/android/net/util/VersionedBroadcastListenerTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.reset;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.UserHandle;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.test.BroadcastInterceptingContext;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class VersionedBroadcastListenerTest {
+    private static final String TAG = VersionedBroadcastListenerTest.class.getSimpleName();
+    private static final String ACTION_TEST = "action.test.happy.broadcasts";
+
+    @Mock private Context mContext;
+    private BroadcastInterceptingContext mServiceContext;
+    private Handler mHandler;
+    private VersionedBroadcastListener mListener;
+    private int mCallbackCount;
+
+    private void doCallback() { mCallbackCount++; }
+
+    private class MockContext extends BroadcastInterceptingContext {
+        MockContext(Context base) {
+            super(base);
+        }
+    }
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+    }
+
+    @Before public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        reset(mContext);
+        mServiceContext = new MockContext(mContext);
+        mHandler = new Handler(Looper.myLooper());
+        mCallbackCount = 0;
+        final IntentFilter filter = new IntentFilter();
+        filter.addAction(ACTION_TEST);
+        mListener = new VersionedBroadcastListener(
+                TAG, mServiceContext, mHandler, filter, (Intent intent) -> doCallback());
+    }
+
+    @After public void tearDown() throws Exception {
+        if (mListener != null) {
+            mListener.stopListening();
+            mListener = null;
+        }
+    }
+
+    private void sendBroadcast() {
+        final Intent intent = new Intent(ACTION_TEST);
+        mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+    }
+
+    @Test
+    public void testBasicListening() {
+        assertEquals(0, mCallbackCount);
+        mListener.startListening();
+        for (int i = 0; i < 5; i++) {
+            sendBroadcast();
+            assertEquals(i+1, mCallbackCount);
+        }
+        mListener.stopListening();
+    }
+
+    @Test
+    public void testBroadcastsBeforeStartAreIgnored() {
+        assertEquals(0, mCallbackCount);
+        for (int i = 0; i < 5; i++) {
+            sendBroadcast();
+            assertEquals(0, mCallbackCount);
+        }
+
+        mListener.startListening();
+        sendBroadcast();
+        assertEquals(1, mCallbackCount);
+    }
+
+    @Test
+    public void testBroadcastsAfterStopAreIgnored() {
+        mListener.startListening();
+        sendBroadcast();
+        assertEquals(1, mCallbackCount);
+        mListener.stopListening();
+
+        for (int i = 0; i < 5; i++) {
+            sendBroadcast();
+            assertEquals(1, mCallbackCount);
+        }
+    }
+}
diff --git a/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java b/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java
index a423c2a..fb2bd79 100644
--- a/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java
+++ b/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java
@@ -24,12 +24,15 @@
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 
 import android.content.res.Resources;
 import android.net.NetworkStats;
 import android.net.TrafficStats;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
+import android.support.test.runner.AndroidJUnit4;
 
 import com.android.frameworks.tests.net.R;
 
@@ -42,19 +45,23 @@
 import libcore.io.IoUtils;
 import libcore.io.Streams;
 
+import org.junit.runner.RunWith;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
 /**
  * Tests for {@link NetworkStatsFactory}.
  */
+@RunWith(AndroidJUnit4.class)
 @SmallTest
-public class NetworkStatsFactoryTest extends AndroidTestCase {
+public class NetworkStatsFactoryTest {
     private File mTestProc;
     private NetworkStatsFactory mFactory;
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-
-        mTestProc = new File(getContext().getFilesDir(), "proc");
+        mTestProc = new File(InstrumentationRegistry.getContext().getFilesDir(), "proc");
         if (mTestProc.exists()) {
             IoUtils.deleteContents(mTestProc);
         }
@@ -62,17 +69,16 @@
         mFactory = new NetworkStatsFactory(mTestProc);
     }
 
-    @Override
+    @After
     public void tearDown() throws Exception {
         mFactory = null;
 
         if (mTestProc.exists()) {
             IoUtils.deleteContents(mTestProc);
         }
-
-        super.tearDown();
     }
 
+    @Test
     public void testNetworkStatsDetail() throws Exception {
         final NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_typical);
 
@@ -84,6 +90,7 @@
         assertStatsEntry(stats, "rmnet2", 10001, SET_DEFAULT, 0x0, 1125899906842624L, 984L);
     }
 
+    @Test
     public void testKernelTags() throws Exception {
         assertEquals(0, kernelToTag("0x0000000000000000"));
         assertEquals(0x32, kernelToTag("0x0000003200000000"));
@@ -98,6 +105,7 @@
         assertEquals(TrafficStats.TAG_SYSTEM_DOWNLOAD, kernelToTag("0xffffff0100000000"));
     }
 
+    @Test
     public void testNetworkStatsWithSet() throws Exception {
         final NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_typical);
         assertEquals(70, stats.size());
@@ -106,6 +114,7 @@
         assertStatsEntry(stats, "rmnet1", 10021, SET_FOREGROUND, 0x30100000, 742L, 3L, 1265L, 3L);
     }
 
+    @Test
     public void testNetworkStatsSingle() throws Exception {
         stageFile(R.raw.xt_qtaguid_iface_typical, file("net/xt_qtaguid/iface_stat_all"));
 
@@ -116,6 +125,7 @@
         assertStatsEntry(stats, "test2", UID_ALL, SET_ALL, TAG_NONE, 1L, 2L, 3L, 4L);
     }
 
+    @Test
     public void testNetworkStatsXt() throws Exception {
         stageFile(R.raw.xt_qtaguid_iface_fmt_typical, file("net/xt_qtaguid/iface_stat_fmt"));
 
@@ -127,6 +137,7 @@
         assertStatsEntry(stats, "rmnet2", UID_ALL, SET_ALL, TAG_NONE, 4968L, 35L, 3081L, 39L);
     }
 
+    @Test
     public void testDoubleClatAccounting() throws Exception {
         NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0");
 
@@ -161,6 +172,7 @@
         NetworkStatsFactory.noteStackedIface("v4-wlan0", null);
     }
 
+    @Test
     public void testDoubleClatAccounting100MBDownload() throws Exception {
         // Downloading 100mb from an ipv4 only destination in a foreground activity
 
@@ -197,7 +209,7 @@
         InputStream in = null;
         OutputStream out = null;
         try {
-            in = getContext().getResources().openRawResource(rawId);
+            in = InstrumentationRegistry.getContext().getResources().openRawResource(rawId);
             out = new FileOutputStream(file);
             Streams.copy(in, out);
         } finally {
@@ -251,5 +263,4 @@
         assertEquals("unexpected txBytes", txBytes, entry.txBytes);
         assertEquals("unexpected txPackets", txPackets, entry.txPackets);
     }
-
 }
diff --git a/tests/net/java/com/android/internal/util/BitUtilsTest.java b/tests/net/java/com/android/internal/util/BitUtilsTest.java
index 0ad8a21..f4dc12a 100644
--- a/tests/net/java/com/android/internal/util/BitUtilsTest.java
+++ b/tests/net/java/com/android/internal/util/BitUtilsTest.java
@@ -56,6 +56,25 @@
     }
 
     @Test
+    public void testUnsignedShortComposition() {
+        byte b0 = 0;
+        byte b1 = 1;
+        byte b2 = 2;
+        byte b10 = 10;
+        byte b16 = 16;
+        byte b128 = -128;
+        byte b224 = -32;
+        byte b255 = -1;
+        assertEquals(0x0000, uint16(b0, b0));
+        assertEquals(0xffff, uint16(b255, b255));
+        assertEquals(0x0a01, uint16(b10, b1));
+        assertEquals(0x8002, uint16(b128, b2));
+        assertEquals(0x01ff, uint16(b1, b255));
+        assertEquals(0x80ff, uint16(b128, b255));
+        assertEquals(0xe010, uint16(b224, b16));
+    }
+
+    @Test
     public void testUnsignedIntWideningConversions() {
         assertEquals(0, uint32(0));
         assertEquals(1, uint32(1));
diff --git a/tests/net/java/com/android/internal/util/RingBufferTest.java b/tests/net/java/com/android/internal/util/RingBufferTest.java
new file mode 100644
index 0000000..7a2344317
--- /dev/null
+++ b/tests/net/java/com/android/internal/util/RingBufferTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import java.util.Arrays;
+import java.util.Objects;
+
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RingBufferTest {
+
+    @Test
+    public void testEmptyRingBuffer() {
+        RingBuffer<String> buffer = new RingBuffer<>(String.class, 100);
+
+        assertArraysEqual(new String[0], buffer.toArray());
+    }
+
+    @Test
+    public void testIncorrectConstructorArguments() {
+        try {
+            RingBuffer<String> buffer = new RingBuffer<>(String.class, -10);
+            fail("Should not be able to create a negative capacity RingBuffer");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            RingBuffer<String> buffer = new RingBuffer<>(String.class, 0);
+            fail("Should not be able to create a 0 capacity RingBuffer");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
+    public void testRingBufferWithNoWrapping() {
+        RingBuffer<String> buffer = new RingBuffer<>(String.class, 100);
+
+        buffer.append("a");
+        buffer.append("b");
+        buffer.append("c");
+        buffer.append("d");
+        buffer.append("e");
+
+        String[] expected = {"a", "b", "c", "d", "e"};
+        assertArraysEqual(expected, buffer.toArray());
+    }
+
+    @Test
+    public void testRingBufferWithCapacity1() {
+        RingBuffer<String> buffer = new RingBuffer<>(String.class, 1);
+
+        buffer.append("a");
+        assertArraysEqual(new String[]{"a"}, buffer.toArray());
+
+        buffer.append("b");
+        assertArraysEqual(new String[]{"b"}, buffer.toArray());
+
+        buffer.append("c");
+        assertArraysEqual(new String[]{"c"}, buffer.toArray());
+
+        buffer.append("d");
+        assertArraysEqual(new String[]{"d"}, buffer.toArray());
+
+        buffer.append("e");
+        assertArraysEqual(new String[]{"e"}, buffer.toArray());
+    }
+
+    @Test
+    public void testRingBufferWithWrapping() {
+        int capacity = 100;
+        RingBuffer<String> buffer = new RingBuffer<>(String.class, capacity);
+
+        buffer.append("a");
+        buffer.append("b");
+        buffer.append("c");
+        buffer.append("d");
+        buffer.append("e");
+
+        String[] expected1 = {"a", "b", "c", "d", "e"};
+        assertArraysEqual(expected1, buffer.toArray());
+
+        String[] expected2 = new String[capacity];
+        int firstIndex = 0;
+        int lastIndex = capacity - 1;
+
+        expected2[firstIndex] = "e";
+        for (int i = 1; i < capacity; i++) {
+            buffer.append("x");
+            expected2[i] = "x";
+        }
+        assertArraysEqual(expected2, buffer.toArray());
+
+        buffer.append("x");
+        expected2[firstIndex] = "x";
+        assertArraysEqual(expected2, buffer.toArray());
+
+        for (int i = 0; i < 10; i++) {
+            for (String s : expected2) {
+                buffer.append(s);
+            }
+        }
+        assertArraysEqual(expected2, buffer.toArray());
+
+        buffer.append("a");
+        expected2[lastIndex] = "a";
+        assertArraysEqual(expected2, buffer.toArray());
+    }
+
+    static <T> void assertArraysEqual(T[] expected, T[] got) {
+        if (expected.length != got.length) {
+            fail(Arrays.toString(expected) + " and " + Arrays.toString(got)
+                    + " did not have the same length");
+        }
+
+        for (int i = 0; i < expected.length; i++) {
+            if (!Objects.equals(expected[i], got[i])) {
+                fail(Arrays.toString(expected) + " and " + Arrays.toString(got)
+                        + " were not equal");
+            }
+        }
+    }
+}
diff --git a/tests/net/java/com/android/internal/util/TestUtils.java b/tests/net/java/com/android/internal/util/TestUtils.java
index c9fa340..6db01d3 100644
--- a/tests/net/java/com/android/internal/util/TestUtils.java
+++ b/tests/net/java/com/android/internal/util/TestUtils.java
@@ -30,8 +30,7 @@
      * Block until the given Handler thread becomes idle, or until timeoutMs has passed.
      */
     public static void waitForIdleHandler(HandlerThread handlerThread, long timeoutMs) {
-        // TODO: convert to getThreadHandler once it is available on aosp
-        waitForIdleLooper(handlerThread.getLooper(), timeoutMs);
+        waitForIdleHandler(handlerThread.getThreadHandler(), timeoutMs);
     }
 
     /**
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index f6481cf..113cd37 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -19,18 +19,48 @@
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.TYPE_ETHERNET;
 import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA;
+import static android.net.ConnectivityManager.TYPE_MOBILE_MMS;
 import static android.net.ConnectivityManager.TYPE_NONE;
 import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.ConnectivityManager.getNetworkTypeName;
-import static android.net.NetworkCapabilities.*;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_IA;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
 
 import static com.android.internal.util.TestUtils.waitForIdleHandler;
 
-import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.eq;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.NotificationManager;
@@ -38,7 +68,6 @@
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Resources;
@@ -57,13 +86,13 @@
 import android.net.Network;
 import android.net.NetworkAgent;
 import android.net.NetworkCapabilities;
-import android.net.NetworkConfig;
 import android.net.NetworkFactory;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkMisc;
 import android.net.NetworkRequest;
 import android.net.NetworkSpecifier;
+import android.net.NetworkUtils;
 import android.net.RouteInfo;
 import android.net.StringNetworkSpecifier;
 import android.net.metrics.IpConnectivityLog;
@@ -71,37 +100,38 @@
 import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.HandlerThread;
-import android.os.IBinder;
 import android.os.INetworkManagementService;
 import android.os.Looper;
 import android.os.Message;
-import android.os.MessageQueue;
-import android.os.Messenger;
-import android.os.MessageQueue.IdleHandler;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.Process;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.test.AndroidTestCase;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.test.mock.MockContentResolver;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.Log;
-import android.util.LogPrinter;
 
 import com.android.internal.util.WakeupMessage;
 import com.android.internal.util.test.BroadcastInterceptingContext;
 import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.server.connectivity.DefaultNetworkMetrics;
+import com.android.server.connectivity.IpConnectivityMetrics;
 import com.android.server.connectivity.MockableSystemProperties;
 import com.android.server.connectivity.NetworkAgentInfo;
 import com.android.server.connectivity.NetworkMonitor;
-import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
 import com.android.server.net.NetworkPinner;
 import com.android.server.net.NetworkPolicyManagerInternal;
 
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.Spy;
@@ -109,21 +139,26 @@
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.BooleanSupplier;
 import java.util.function.Predicate;
 
+
 /**
  * Tests for {@link ConnectivityService}.
  *
  * Build, install and run with:
  *  runtest frameworks-net -c com.android.server.ConnectivityServiceTest
  */
-public class ConnectivityServiceTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ConnectivityServiceTest {
     private static final String TAG = "ConnectivityServiceTest";
 
     private static final int TIMEOUT_MS = 500;
@@ -135,6 +170,11 @@
     private MockNetworkAgent mWiFiNetworkAgent;
     private MockNetworkAgent mCellNetworkAgent;
     private MockNetworkAgent mEthernetNetworkAgent;
+    private Context mContext;
+
+    @Mock IpConnectivityMetrics.Logger mMetricsService;
+    @Mock DefaultNetworkMetrics mDefaultNetworkMetrics;
+    @Mock INetworkStatsService mStatsService;
 
     // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods
     // do not go through ConnectivityService but talk to netd directly, so they don't automatically
@@ -236,7 +276,7 @@
         waitForIdle(TIMEOUT_MS);
     }
 
-    @SmallTest
+    @Test
     public void testWaitForIdle() {
         final int attempts = 50;  // Causes the test to take about 200ms on bullhead-eng.
 
@@ -304,6 +344,10 @@
         private String mRedirectUrl;
 
         MockNetworkAgent(int transport) {
+            this(transport, new LinkProperties());
+        }
+
+        MockNetworkAgent(int transport, LinkProperties linkProperties) {
             final int type = transportToLegacyType(transport);
             final String typeName = ConnectivityManager.getNetworkTypeName(type);
             mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
@@ -329,7 +373,7 @@
             mHandlerThread.start();
             mNetworkAgent = new NetworkAgent(mHandlerThread.getLooper(), mServiceContext,
                     "Mock-" + typeName, mNetworkInfo, mNetworkCapabilities,
-                    new LinkProperties(), mScore, new NetworkMisc()) {
+                    linkProperties, mScore, new NetworkMisc()) {
                 @Override
                 public void unwanted() { mDisconnected.open(); }
 
@@ -674,7 +718,8 @@
         public WrappedNetworkMonitor(Context context, Handler handler,
                 NetworkAgentInfo networkAgentInfo, NetworkRequest defaultRequest,
                 IpConnectivityLog log) {
-            super(context, handler, networkAgentInfo, defaultRequest, log);
+            super(context, handler, networkAgentInfo, defaultRequest, log,
+                    NetworkMonitor.NetworkMonitorSettings.DEFAULT);
         }
 
         @Override
@@ -732,7 +777,8 @@
 
                 // Don't overlap test NetIDs with real NetIDs as binding sockets to real networks
                 // can have odd side-effects, like network validations succeeding.
-                final Network[] networks = ConnectivityManager.from(getContext()).getAllNetworks();
+                Context context = InstrumentationRegistry.getContext();
+                final Network[] networks = ConnectivityManager.from(context).getAllNetworks();
                 boolean overlaps = false;
                 for (Network network : networks) {
                     if (netId == network.netId) {
@@ -772,6 +818,18 @@
             return new FakeWakeupMessage(context, handler, cmdName, cmd, 0, 0, obj);
         }
 
+        @Override
+        public boolean hasService(String name) {
+            // Currenty, the only relevant service that ConnectivityService checks for is
+            // ETHERNET_SERVICE.
+            return Context.ETHERNET_SERVICE.equals(name);
+        }
+
+        @Override
+        protected IpConnectivityMetrics.Logger metricsLogger() {
+            return mMetricsService;
+        }
+
         public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() {
             return mLastCreatedNetworkMonitor;
         }
@@ -796,9 +854,12 @@
         fail("ConditionVariable was blocked for more than " + TIMEOUT_MS + "ms");
     }
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
+        mContext = InstrumentationRegistry.getContext();
+
+        MockitoAnnotations.initMocks(this);
+        when(mMetricsService.defaultNetworkMetrics()).thenReturn(mDefaultNetworkMetrics);
 
         // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
         // http://b/25897652 .
@@ -806,18 +867,18 @@
             Looper.prepare();
         }
 
-        mServiceContext = new MockContext(getContext());
+        mServiceContext = new MockContext(InstrumentationRegistry.getContext());
         LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
         LocalServices.addService(
                 NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class));
         mService = new WrappedConnectivityService(mServiceContext,
                 mock(INetworkManagementService.class),
-                mock(INetworkStatsService.class),
+                mStatsService,
                 mock(INetworkPolicyManager.class),
                 mock(IpConnectivityLog.class));
 
         mService.systemReady();
-        mCm = new WrappedConnectivityManager(getContext(), mService);
+        mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService);
         mCm.bindProcessToNetwork(null);
 
         // Ensure that the default setting for Captive Portals is used for most tests
@@ -825,6 +886,7 @@
         setMobileDataAlwaysOn(false);
     }
 
+    @After
     public void tearDown() throws Exception {
         setMobileDataAlwaysOn(false);
         if (mCellNetworkAgent != null) {
@@ -839,7 +901,6 @@
             mEthernetNetworkAgent.disconnect();
             mEthernetNetworkAgent = null;
         }
-        super.tearDown();
     }
 
     private static int transportToLegacyType(int transport) {
@@ -913,15 +974,23 @@
         return cv;
     }
 
+    @Test
     public void testNetworkTypes() {
         // Ensure that our mocks for the networkAttributes config variable work as expected. If they
         // don't, then tests that depend on CONNECTIVITY_ACTION broadcasts for these network types
         // will fail. Failing here is much easier to debug.
         assertTrue(mCm.isNetworkSupported(TYPE_WIFI));
         assertTrue(mCm.isNetworkSupported(TYPE_MOBILE));
+        assertTrue(mCm.isNetworkSupported(TYPE_MOBILE_MMS));
+        assertFalse(mCm.isNetworkSupported(TYPE_MOBILE_FOTA));
+
+        // Check that TYPE_ETHERNET is supported. Unlike the asserts above, which only validate our
+        // mocks, this assert exercises the ConnectivityService code path that ensures that
+        // TYPE_ETHERNET is supported if the ethernet service is running.
+        assertTrue(mCm.isNetworkSupported(TYPE_ETHERNET));
     }
 
-    @SmallTest
+    @Test
     public void testLingering() throws Exception {
         verifyNoNetwork();
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -962,7 +1031,7 @@
         verifyNoNetwork();
     }
 
-    @SmallTest
+    @Test
     public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception {
         // Test bringing up unvalidated WiFi
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -997,7 +1066,7 @@
         verifyNoNetwork();
     }
 
-    @SmallTest
+    @Test
     public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception {
         // Test bringing up unvalidated cellular.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1023,7 +1092,7 @@
         verifyNoNetwork();
     }
 
-    @SmallTest
+    @Test
     public void testUnlingeringDoesNotValidate() throws Exception {
         // Test bringing up unvalidated WiFi.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -1051,7 +1120,7 @@
                 NET_CAPABILITY_VALIDATED));
     }
 
-    @SmallTest
+    @Test
     public void testCellularOutscoresWeakWifi() throws Exception {
         // Test bringing up validated cellular.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1077,7 +1146,7 @@
         verifyActiveNetwork(TRANSPORT_WIFI);
     }
 
-    @SmallTest
+    @Test
     public void testReapingNetwork() throws Exception {
         // Test bringing up WiFi without NET_CAPABILITY_INTERNET.
         // Expect it to be torn down immediately because it satisfies no requests.
@@ -1110,7 +1179,7 @@
         waitFor(cv);
     }
 
-    @SmallTest
+    @Test
     public void testCellularFallback() throws Exception {
         // Test bringing up validated cellular.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1148,7 +1217,7 @@
         verifyActiveNetwork(TRANSPORT_WIFI);
     }
 
-    @SmallTest
+    @Test
     public void testWiFiFallback() throws Exception {
         // Test bringing up unvalidated WiFi.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -1362,7 +1431,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testStateChangeNetworkCallbacks() throws Exception {
         final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
         final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
@@ -1452,7 +1521,7 @@
         assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
     }
 
-    @SmallTest
+    @Test
     public void testMultipleLingering() {
         NetworkRequest request = new NetworkRequest.Builder()
                 .clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED)
@@ -1680,7 +1749,7 @@
         mCm.unregisterNetworkCallback(trackDefaultCallback);
     }
 
-    @SmallTest
+    @Test
     public void testExplicitlySelected() {
         NetworkRequest request = new NetworkRequest.Builder()
                 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET)
@@ -1847,7 +1916,7 @@
         handlerThread.quit();
     }
 
-    @SmallTest
+    @Test
     public void testNetworkFactoryRequests() throws Exception {
         tryNetworkFactoryRequests(NET_CAPABILITY_MMS);
         tryNetworkFactoryRequests(NET_CAPABILITY_SUPL);
@@ -1867,7 +1936,7 @@
         // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed.
     }
 
-    @SmallTest
+    @Test
     public void testNoMutableNetworkRequests() throws Exception {
         PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0);
         NetworkRequest request1 = new NetworkRequest.Builder()
@@ -1884,7 +1953,7 @@
         assertException(() -> { mCm.requestNetwork(request2, pendingIntent); }, expected);
     }
 
-    @SmallTest
+    @Test
     public void testMMSonWiFi() throws Exception {
         // Test bringing up cellular without MMS NetworkRequest gets reaped
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1923,7 +1992,7 @@
         verifyActiveNetwork(TRANSPORT_WIFI);
     }
 
-    @SmallTest
+    @Test
     public void testMMSonCell() throws Exception {
         // Test bringing up cellular without MMS
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1952,7 +2021,7 @@
         verifyActiveNetwork(TRANSPORT_CELLULAR);
     }
 
-    @SmallTest
+    @Test
     public void testCaptivePortal() {
         final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
         final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
@@ -2003,7 +2072,7 @@
         validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
     }
 
-    @SmallTest
+    @Test
     public void testCaptivePortalApp() {
         final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
         final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
@@ -2049,7 +2118,7 @@
         mCm.unregisterNetworkCallback(captivePortalCallback);
     }
 
-    @SmallTest
+    @Test
     public void testAvoidOrIgnoreCaptivePortals() {
         final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
         final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
@@ -2094,7 +2163,7 @@
         return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI);
     }
 
-    @SmallTest
+    @Test
     public void testNetworkSpecifier() {
         NetworkRequest rEmpty1 = newWifiRequestBuilder().build();
         NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build();
@@ -2155,7 +2224,7 @@
         assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cFoo, cBar);
     }
 
-    @SmallTest
+    @Test
     public void testInvalidNetworkSpecifier() {
         try {
             NetworkRequest.Builder builder = new NetworkRequest.Builder();
@@ -2216,7 +2285,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testNetworkSpecifierUidSpoofSecurityException() {
         class UidAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable {
             @Override
@@ -2250,7 +2319,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testRegisterDefaultNetworkCallback() throws Exception {
         final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
         mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
@@ -2299,7 +2368,7 @@
         defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
     }
 
-    @SmallTest
+    @Test
     public void testAdditionalStateCallbacks() throws Exception {
         // File a network request for mobile.
         final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
@@ -2360,7 +2429,7 @@
         return nc.hasCapability(NET_CAPABILITY_FOREGROUND);
     }
 
-    @SmallTest
+    @Test
     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.
@@ -2529,7 +2598,7 @@
         return false;
     }
 
-    @SmallTest
+    @Test
     public void testMobileDataAlwaysOn() throws Exception {
         final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
         final NetworkRequest cellRequest = new NetworkRequest.Builder()
@@ -2594,7 +2663,7 @@
         handlerThread.quit();
     }
 
-    @SmallTest
+    @Test
     public void testAvoidBadWifiSetting() throws Exception {
         final ContentResolver cr = mServiceContext.getContentResolver();
         final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker();
@@ -2632,7 +2701,7 @@
         assertTrue(tracker.shouldNotifyWifiUnvalidated());
     }
 
-    @SmallTest
+    @Test
     public void testAvoidBadWifi() throws Exception {
         final ContentResolver cr = mServiceContext.getContentResolver();
         final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker();
@@ -2759,7 +2828,7 @@
         mCm.unregisterNetworkCallback(defaultCallback);
     }
 
-    @SmallTest
+    @Test
     public void testMeteredMultipathPreferenceSetting() throws Exception {
         final ContentResolver cr = mServiceContext.getContentResolver();
         final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker();
@@ -2783,7 +2852,7 @@
      * Validate that a satisfied network request does not trigger onUnavailable() once the
      * time-out period expires.
      */
-    @SmallTest
+    @Test
     public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() {
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI).build();
@@ -2803,7 +2872,7 @@
      * Validate that a satisfied network request followed by a disconnected (lost) network does
      * not trigger onUnavailable() once the time-out period expires.
      */
-    @SmallTest
+    @Test
     public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() {
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI).build();
@@ -2827,7 +2896,7 @@
      * callback is called when time-out expires. Then validate that if network request is
      * (somehow) satisfied - the callback isn't called later.
      */
-    @SmallTest
+    @Test
     public void testTimedoutNetworkRequest() {
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI).build();
@@ -2848,7 +2917,7 @@
      * Validate that when a network request is unregistered (cancelled), no posterior event can
      * trigger the callback.
      */
-    @SmallTest
+    @Test
     public void testNoCallbackAfterUnregisteredNetworkRequest() {
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI).build();
@@ -2956,7 +3025,7 @@
         return mWiFiNetworkAgent.getNetwork();
     }
 
-    @SmallTest
+    @Test
     public void testPacketKeepalives() throws Exception {
         InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
         InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35");
@@ -3080,7 +3149,7 @@
         callback3.expectStopped();
     }
 
-    @SmallTest
+    @Test
     public void testGetCaptivePortalServerUrl() throws Exception {
         String url = mCm.getCaptivePortalServerUrl();
         assertEquals("http://connectivitycheck.gstatic.com/generate_204", url);
@@ -3125,7 +3194,7 @@
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
     }
 
-    @SmallTest
+    @Test
     public void testNetworkPinner() {
         NetworkRequest wifiRequest = new NetworkRequest.Builder()
                 .addTransportType(TRANSPORT_WIFI)
@@ -3185,69 +3254,69 @@
         assertPinnedToWifiWithCellDefault();
     }
 
-    @SmallTest
-    public void testNetworkRequestMaximum() {
+    @Test
+    public void testNetworkCallbackMaximum() {
         final int MAX_REQUESTS = 100;
-        // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added.
+        final int CALLBACKS = 90;
+        final int INTENTS = 10;
+        assertEquals(MAX_REQUESTS, CALLBACKS + INTENTS);
+
         NetworkRequest networkRequest = new NetworkRequest.Builder().build();
-        ArrayList<NetworkCallback> networkCallbacks = new ArrayList<NetworkCallback>();
-        try {
-            for (int i = 0; i < MAX_REQUESTS; i++) {
-                NetworkCallback networkCallback = new NetworkCallback();
-                mCm.requestNetwork(networkRequest, networkCallback);
-                networkCallbacks.add(networkCallback);
-            }
-            fail("Registering " + MAX_REQUESTS + " NetworkRequests did not throw exception");
-        } catch (TooManyRequestsException expected) {}
-        for (NetworkCallback networkCallback : networkCallbacks) {
-            mCm.unregisterNetworkCallback(networkCallback);
-        }
-        networkCallbacks.clear();
+        ArrayList<Object> registered = new ArrayList<>();
 
-        try {
-            for (int i = 0; i < MAX_REQUESTS; i++) {
-                NetworkCallback networkCallback = new NetworkCallback();
-                mCm.registerNetworkCallback(networkRequest, networkCallback);
-                networkCallbacks.add(networkCallback);
-            }
-            fail("Registering " + MAX_REQUESTS + " NetworkCallbacks did not throw exception");
-        } catch (TooManyRequestsException expected) {}
-        for (NetworkCallback networkCallback : networkCallbacks) {
-            mCm.unregisterNetworkCallback(networkCallback);
+        int j = 0;
+        while (j++ < CALLBACKS / 2) {
+            NetworkCallback cb = new NetworkCallback();
+            mCm.requestNetwork(networkRequest, cb);
+            registered.add(cb);
         }
-        networkCallbacks.clear();
+        while (j++ < CALLBACKS) {
+            NetworkCallback cb = new NetworkCallback();
+            mCm.registerNetworkCallback(networkRequest, cb);
+            registered.add(cb);
+        }
+        j = 0;
+        while (j++ < INTENTS / 2) {
+            PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, new Intent("a" + j), 0);
+            mCm.requestNetwork(networkRequest, pi);
+            registered.add(pi);
+        }
+        while (j++ < INTENTS) {
+            PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, new Intent("b" + j), 0);
+            mCm.registerNetworkCallback(networkRequest, pi);
+            registered.add(pi);
+        }
 
-        ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>();
+        // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added.
         try {
-            for (int i = 0; i < MAX_REQUESTS + 1; i++) {
-                PendingIntent pendingIntent =
-                        PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0);
-                mCm.requestNetwork(networkRequest, pendingIntent);
-                pendingIntents.add(pendingIntent);
-            }
-            fail("Registering " + MAX_REQUESTS +
-                    " PendingIntent NetworkRequests did not throw exception");
+            mCm.requestNetwork(networkRequest, new NetworkCallback());
+            fail("Registering " + MAX_REQUESTS + " network requests did not throw exception");
         } catch (TooManyRequestsException expected) {}
-        for (PendingIntent pendingIntent : pendingIntents) {
-            mCm.unregisterNetworkCallback(pendingIntent);
-        }
-        pendingIntents.clear();
+        try {
+            mCm.registerNetworkCallback(networkRequest, new NetworkCallback());
+            fail("Registering " + MAX_REQUESTS + " network callbacks did not throw exception");
+        } catch (TooManyRequestsException expected) {}
+        try {
+            mCm.requestNetwork(networkRequest,
+                PendingIntent.getBroadcast(mContext, 0, new Intent("c"), 0));
+            fail("Registering " + MAX_REQUESTS + " PendingIntent requests did not throw exception");
+        } catch (TooManyRequestsException expected) {}
+        try {
+            mCm.registerNetworkCallback(networkRequest,
+                PendingIntent.getBroadcast(mContext, 0, new Intent("d"), 0));
+            fail("Registering " + MAX_REQUESTS
+                    + " PendingIntent callbacks did not throw exception");
+        } catch (TooManyRequestsException expected) {}
 
-        try {
-            for (int i = 0; i < MAX_REQUESTS + 1; i++) {
-                PendingIntent pendingIntent =
-                        PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0);
-                mCm.registerNetworkCallback(networkRequest, pendingIntent);
-                pendingIntents.add(pendingIntent);
+        for (Object o : registered) {
+            if (o instanceof NetworkCallback) {
+                mCm.unregisterNetworkCallback((NetworkCallback)o);
             }
-            fail("Registering " + MAX_REQUESTS +
-                    " PendingIntent NetworkCallbacks did not throw exception");
-        } catch (TooManyRequestsException expected) {}
-        for (PendingIntent pendingIntent : pendingIntents) {
-            mCm.unregisterNetworkCallback(pendingIntent);
+            if (o instanceof PendingIntent) {
+                mCm.unregisterNetworkCallback((PendingIntent)o);
+            }
         }
-        pendingIntents.clear();
-        waitForIdle(5000);
+        waitForIdle();
 
         // Test that the limit is not hit when MAX_REQUESTS requests are added and removed.
         for (int i = 0; i < MAX_REQUESTS; i++) {
@@ -3256,28 +3325,31 @@
             mCm.unregisterNetworkCallback(networkCallback);
         }
         waitForIdle();
+
         for (int i = 0; i < MAX_REQUESTS; i++) {
             NetworkCallback networkCallback = new NetworkCallback();
             mCm.registerNetworkCallback(networkRequest, networkCallback);
             mCm.unregisterNetworkCallback(networkCallback);
         }
         waitForIdle();
+
         for (int i = 0; i < MAX_REQUESTS; i++) {
             PendingIntent pendingIntent =
-                    PendingIntent.getBroadcast(mContext, 0, new Intent("b" + i), 0);
+                    PendingIntent.getBroadcast(mContext, 0, new Intent("e" + i), 0);
             mCm.requestNetwork(networkRequest, pendingIntent);
             mCm.unregisterNetworkCallback(pendingIntent);
         }
         waitForIdle();
+
         for (int i = 0; i < MAX_REQUESTS; i++) {
             PendingIntent pendingIntent =
-                    PendingIntent.getBroadcast(mContext, 0, new Intent("c" + i), 0);
+                    PendingIntent.getBroadcast(mContext, 0, new Intent("f" + i), 0);
             mCm.registerNetworkCallback(networkRequest, pendingIntent);
             mCm.unregisterNetworkCallback(pendingIntent);
         }
     }
 
-    @SmallTest
+    @Test
     public void testNetworkInfoOfTypeNone() {
         ConditionVariable broadcastCV = waitForConnectivityBroadcasts(1);
 
@@ -3317,7 +3389,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testDeprecatedAndUnsupportedOperations() throws Exception {
         final int TYPE_NONE = ConnectivityManager.TYPE_NONE;
         assertNull(mCm.getNetworkInfo(TYPE_NONE));
@@ -3338,6 +3410,102 @@
         assertException(() -> { mCm.requestRouteToHostAddress(TYPE_NONE, null); }, unsupported);
     }
 
+    @Test
+    public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() {
+        final NetworkRequest networkRequest = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_WIFI).build();
+        final TestNetworkCallback networkCallback = new TestNetworkCallback();
+        mCm.registerNetworkCallback(networkRequest, networkCallback);
+
+        LinkProperties lp = new LinkProperties();
+        lp.setInterfaceName("wlan0");
+        LinkAddress myIpv4Address = new LinkAddress("192.168.12.3/24");
+        RouteInfo myIpv4DefaultRoute = new RouteInfo((IpPrefix) null,
+                NetworkUtils.numericToInetAddress("192.168.12.1"), lp.getInterfaceName());
+        lp.addLinkAddress(myIpv4Address);
+        lp.addRoute(myIpv4DefaultRoute);
+
+        // Verify direct routes are added when network agent is first registered in
+        // ConnectivityService.
+        MockNetworkAgent networkAgent = new MockNetworkAgent(TRANSPORT_WIFI, lp);
+        networkAgent.connect(true);
+        networkCallback.expectCallback(CallbackState.AVAILABLE, networkAgent);
+        networkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, networkAgent);
+        CallbackInfo cbi = networkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
+                networkAgent);
+        networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, networkAgent);
+        networkCallback.assertNoCallback();
+        checkDirectlyConnectedRoutes(cbi.arg, Arrays.asList(myIpv4Address),
+                Arrays.asList(myIpv4DefaultRoute));
+        checkDirectlyConnectedRoutes(mCm.getLinkProperties(networkAgent.getNetwork()),
+                Arrays.asList(myIpv4Address), Arrays.asList(myIpv4DefaultRoute));
+
+        // Verify direct routes are added during subsequent link properties updates.
+        LinkProperties newLp = new LinkProperties(lp);
+        LinkAddress myIpv6Address1 = new LinkAddress("fe80::cafe/64");
+        LinkAddress myIpv6Address2 = new LinkAddress("2001:db8::2/64");
+        newLp.addLinkAddress(myIpv6Address1);
+        newLp.addLinkAddress(myIpv6Address2);
+        networkAgent.sendLinkProperties(newLp);
+        cbi = networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, networkAgent);
+        networkCallback.assertNoCallback();
+        checkDirectlyConnectedRoutes(cbi.arg,
+                Arrays.asList(myIpv4Address, myIpv6Address1, myIpv6Address2),
+                Arrays.asList(myIpv4DefaultRoute));
+        mCm.unregisterNetworkCallback(networkCallback);
+    }
+
+    @Test
+    public void testStatsIfacesChanged() throws Exception {
+        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+
+        // Simple connection should have updated ifaces
+        mCellNetworkAgent.connect(false);
+        waitForIdle();
+        verify(mStatsService, atLeastOnce()).forceUpdateIfaces();
+        reset(mStatsService);
+
+        // Metered change should update ifaces
+        mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+        waitForIdle();
+        verify(mStatsService, atLeastOnce()).forceUpdateIfaces();
+        reset(mStatsService);
+
+        mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+        waitForIdle();
+        verify(mStatsService, atLeastOnce()).forceUpdateIfaces();
+        reset(mStatsService);
+
+        // Captive portal change shouldn't update ifaces
+        mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
+        waitForIdle();
+        verify(mStatsService, never()).forceUpdateIfaces();
+        reset(mStatsService);
+
+        // Roaming change should update ifaces
+        mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
+        waitForIdle();
+        verify(mStatsService, atLeastOnce()).forceUpdateIfaces();
+        reset(mStatsService);
+    }
+
+    private void checkDirectlyConnectedRoutes(Object callbackObj,
+            Collection<LinkAddress> linkAddresses, Collection<RouteInfo> otherRoutes) {
+        assertTrue(callbackObj instanceof LinkProperties);
+        LinkProperties lp = (LinkProperties) callbackObj;
+
+        Set<RouteInfo> expectedRoutes = new ArraySet<>();
+        expectedRoutes.addAll(otherRoutes);
+        for (LinkAddress address : linkAddresses) {
+            RouteInfo localRoute = new RouteInfo(address, null, lp.getInterfaceName());
+            // Duplicates in linkAddresses are considered failures
+            assertTrue(expectedRoutes.add(localRoute));
+        }
+        List<RouteInfo> observedRoutes = lp.getRoutes();
+        assertEquals(expectedRoutes.size(), observedRoutes.size());
+        assertTrue(observedRoutes.containsAll(expectedRoutes));
+    }
+
     private static <T> void assertEmpty(T[] ts) {
         int length = ts.length;
         assertEquals("expected empty array, but length was " + length, 0, length);
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
new file mode 100644
index 0000000..5c031eb
--- /dev/null
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -0,0 +1,422 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.INetd;
+import android.net.IpSecAlgorithm;
+import android.net.IpSecConfig;
+import android.net.IpSecManager;
+import android.net.IpSecSpiResponse;
+import android.net.IpSecTransform;
+import android.net.IpSecTransformResponse;
+import android.net.NetworkUtils;
+import android.os.Binder;
+import android.os.ParcelFileDescriptor;
+import android.support.test.filters.SmallTest;
+
+import java.net.Socket;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/** Unit tests for {@link IpSecService}. */
+@SmallTest
+@RunWith(Parameterized.class)
+public class IpSecServiceParameterizedTest {
+
+    private static final int TEST_SPI_OUT = 0xD1201D;
+    private static final int TEST_SPI_IN = TEST_SPI_OUT + 1;
+
+    private final String mRemoteAddr;
+
+    @Parameterized.Parameters
+    public static Collection ipSecConfigs() {
+        return Arrays.asList(new Object[][] {{"8.8.4.4"}, {"2601::10"}});
+    }
+
+    private static final byte[] AEAD_KEY = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+        0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+        0x73, 0x61, 0x6C, 0x74
+    };
+    private static final byte[] CRYPT_KEY = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+        0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
+    };
+    private static final byte[] AUTH_KEY = {
+        0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
+        0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F
+    };
+
+    Context mMockContext;
+    INetd mMockNetd;
+    IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
+    IpSecService mIpSecService;
+
+    private static final IpSecAlgorithm AUTH_ALGO =
+            new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4);
+    private static final IpSecAlgorithm CRYPT_ALGO =
+            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[] DIRECTIONS =
+            new int[] {IpSecTransform.DIRECTION_IN, IpSecTransform.DIRECTION_OUT};
+
+    public IpSecServiceParameterizedTest(String remoteAddr) {
+        mRemoteAddr = remoteAddr;
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mMockContext = mock(Context.class);
+        mMockNetd = mock(INetd.class);
+        mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
+        mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
+
+        // Injecting mock netd
+        when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
+    }
+
+    @Test
+    public void testIpSecServiceReserveSpi() throws Exception {
+        when(mMockNetd.ipSecAllocateSpi(
+                        anyInt(),
+                        eq(IpSecTransform.DIRECTION_OUT),
+                        anyString(),
+                        eq(mRemoteAddr),
+                        eq(TEST_SPI_OUT)))
+                .thenReturn(TEST_SPI_OUT);
+
+        IpSecSpiResponse spiResp =
+                mIpSecService.reserveSecurityParameterIndex(
+                        IpSecTransform.DIRECTION_OUT, mRemoteAddr, TEST_SPI_OUT, new Binder());
+        assertEquals(IpSecManager.Status.OK, spiResp.status);
+        assertEquals(TEST_SPI_OUT, spiResp.spi);
+    }
+
+    @Test
+    public void testReleaseSecurityParameterIndex() throws Exception {
+        when(mMockNetd.ipSecAllocateSpi(
+                        anyInt(),
+                        eq(IpSecTransform.DIRECTION_OUT),
+                        anyString(),
+                        eq(mRemoteAddr),
+                        eq(TEST_SPI_OUT)))
+                .thenReturn(TEST_SPI_OUT);
+
+        IpSecSpiResponse spiResp =
+                mIpSecService.reserveSecurityParameterIndex(
+                        IpSecTransform.DIRECTION_OUT, mRemoteAddr, TEST_SPI_OUT, new Binder());
+
+        mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId);
+
+        verify(mMockNetd)
+                .ipSecDeleteSecurityAssociation(
+                        eq(spiResp.resourceId),
+                        anyInt(),
+                        anyString(),
+                        anyString(),
+                        eq(TEST_SPI_OUT));
+    }
+
+    private int getNewSpiResourceId(int direction, String remoteAddress, int returnSpi)
+            throws Exception {
+        when(mMockNetd.ipSecAllocateSpi(anyInt(), anyInt(), anyString(), anyString(), anyInt()))
+                .thenReturn(returnSpi);
+
+        IpSecSpiResponse spi =
+                mIpSecService.reserveSecurityParameterIndex(
+                        direction,
+                        NetworkUtils.numericToInetAddress(remoteAddress).getHostAddress(),
+                        IpSecManager.INVALID_SECURITY_PARAMETER_INDEX,
+                        new Binder());
+        return spi.resourceId;
+    }
+
+    private void addDefaultSpisAndRemoteAddrToIpSecConfig(IpSecConfig config) throws Exception {
+        config.setSpiResourceId(
+                IpSecTransform.DIRECTION_OUT,
+                getNewSpiResourceId(IpSecTransform.DIRECTION_OUT, mRemoteAddr, TEST_SPI_OUT));
+        config.setSpiResourceId(
+                IpSecTransform.DIRECTION_IN,
+                getNewSpiResourceId(IpSecTransform.DIRECTION_IN, mRemoteAddr, TEST_SPI_IN));
+        config.setRemoteAddress(mRemoteAddr);
+    }
+
+    private void addAuthAndCryptToIpSecConfig(IpSecConfig config) throws Exception {
+        for (int direction : DIRECTIONS) {
+            config.setEncryption(direction, CRYPT_ALGO);
+            config.setAuthentication(direction, AUTH_ALGO);
+        }
+    }
+
+    @Test
+    public void testCreateTransportModeTransform() throws Exception {
+        IpSecConfig ipSecConfig = new IpSecConfig();
+        addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
+        addAuthAndCryptToIpSecConfig(ipSecConfig);
+
+        IpSecTransformResponse createTransformResp =
+                mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
+        assertEquals(IpSecManager.Status.OK, createTransformResp.status);
+
+        verify(mMockNetd)
+                .ipSecAddSecurityAssociation(
+                        eq(createTransformResp.resourceId),
+                        anyInt(),
+                        eq(IpSecTransform.DIRECTION_OUT),
+                        anyString(),
+                        anyString(),
+                        anyLong(),
+                        eq(TEST_SPI_OUT),
+                        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());
+        verify(mMockNetd)
+                .ipSecAddSecurityAssociation(
+                        eq(createTransformResp.resourceId),
+                        anyInt(),
+                        eq(IpSecTransform.DIRECTION_IN),
+                        anyString(),
+                        anyString(),
+                        anyLong(),
+                        eq(TEST_SPI_IN),
+                        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());
+    }
+
+    @Test
+    public void testCreateTransportModeTransformAead() throws Exception {
+        IpSecConfig ipSecConfig = new IpSecConfig();
+        addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
+
+        ipSecConfig.setAuthenticatedEncryption(IpSecTransform.DIRECTION_OUT, AEAD_ALGO);
+        ipSecConfig.setAuthenticatedEncryption(IpSecTransform.DIRECTION_IN, AEAD_ALGO);
+
+        IpSecTransformResponse createTransformResp =
+                mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
+        assertEquals(IpSecManager.Status.OK, createTransformResp.status);
+
+        verify(mMockNetd)
+                .ipSecAddSecurityAssociation(
+                        eq(createTransformResp.resourceId),
+                        anyInt(),
+                        eq(IpSecTransform.DIRECTION_OUT),
+                        anyString(),
+                        anyString(),
+                        anyLong(),
+                        eq(TEST_SPI_OUT),
+                        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());
+        verify(mMockNetd)
+                .ipSecAddSecurityAssociation(
+                        eq(createTransformResp.resourceId),
+                        anyInt(),
+                        eq(IpSecTransform.DIRECTION_IN),
+                        anyString(),
+                        anyString(),
+                        anyLong(),
+                        eq(TEST_SPI_IN),
+                        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());
+    }
+
+    @Test
+    public void testCreateInvalidConfigAeadWithAuth() throws Exception {
+        IpSecConfig ipSecConfig = new IpSecConfig();
+        addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
+
+        for (int direction : DIRECTIONS) {
+            ipSecConfig.setAuthentication(direction, AUTH_ALGO);
+            ipSecConfig.setAuthenticatedEncryption(direction, AEAD_ALGO);
+        }
+
+        try {
+            mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
+            fail(
+                    "IpSecService should have thrown an error on authentication being"
+                            + " enabled with authenticated encryption");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
+    public void testCreateInvalidConfigAeadWithCrypt() throws Exception {
+        IpSecConfig ipSecConfig = new IpSecConfig();
+        addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
+
+        for (int direction : DIRECTIONS) {
+            ipSecConfig.setEncryption(direction, CRYPT_ALGO);
+            ipSecConfig.setAuthenticatedEncryption(direction, AEAD_ALGO);
+        }
+
+        try {
+            mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
+            fail(
+                    "IpSecService should have thrown an error on encryption being"
+                            + " enabled with authenticated encryption");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
+    public void testCreateInvalidConfigAeadWithAuthAndCrypt() throws Exception {
+        IpSecConfig ipSecConfig = new IpSecConfig();
+        addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
+
+        for (int direction : DIRECTIONS) {
+            ipSecConfig.setAuthentication(direction, AUTH_ALGO);
+            ipSecConfig.setEncryption(direction, CRYPT_ALGO);
+            ipSecConfig.setAuthenticatedEncryption(direction, AEAD_ALGO);
+        }
+
+        try {
+            mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
+            fail(
+                    "IpSecService should have thrown an error on authentication and encryption being"
+                            + " enabled with authenticated encryption");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
+    public void testDeleteTransportModeTransform() throws Exception {
+        IpSecConfig ipSecConfig = new IpSecConfig();
+        addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
+        addAuthAndCryptToIpSecConfig(ipSecConfig);
+
+        IpSecTransformResponse createTransformResp =
+                mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
+        mIpSecService.deleteTransportModeTransform(createTransformResp.resourceId);
+
+        verify(mMockNetd)
+                .ipSecDeleteSecurityAssociation(
+                        eq(createTransformResp.resourceId),
+                        eq(IpSecTransform.DIRECTION_OUT),
+                        anyString(),
+                        anyString(),
+                        eq(TEST_SPI_OUT));
+        verify(mMockNetd)
+                .ipSecDeleteSecurityAssociation(
+                        eq(createTransformResp.resourceId),
+                        eq(IpSecTransform.DIRECTION_IN),
+                        anyString(),
+                        anyString(),
+                        eq(TEST_SPI_IN));
+    }
+
+    @Test
+    public void testApplyTransportModeTransform() throws Exception {
+        IpSecConfig ipSecConfig = new IpSecConfig();
+        addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
+        addAuthAndCryptToIpSecConfig(ipSecConfig);
+
+        IpSecTransformResponse createTransformResp =
+                mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
+        ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
+
+        int resourceId = createTransformResp.resourceId;
+        mIpSecService.applyTransportModeTransform(pfd, resourceId);
+
+        verify(mMockNetd)
+                .ipSecApplyTransportModeTransform(
+                        eq(pfd.getFileDescriptor()),
+                        eq(resourceId),
+                        eq(IpSecTransform.DIRECTION_OUT),
+                        anyString(),
+                        anyString(),
+                        eq(TEST_SPI_OUT));
+        verify(mMockNetd)
+                .ipSecApplyTransportModeTransform(
+                        eq(pfd.getFileDescriptor()),
+                        eq(resourceId),
+                        eq(IpSecTransform.DIRECTION_IN),
+                        anyString(),
+                        anyString(),
+                        eq(TEST_SPI_IN));
+    }
+
+    @Test
+    public void testRemoveTransportModeTransform() throws Exception {
+        ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
+        mIpSecService.removeTransportModeTransform(pfd, 1);
+
+        verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd.getFileDescriptor());
+    }
+}
diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java
index 23fee28..8e579aa 100644
--- a/tests/net/java/com/android/server/IpSecServiceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceTest.java
@@ -21,11 +21,11 @@
 import static android.system.OsConstants.IPPROTO_UDP;
 import static android.system.OsConstants.SOCK_DGRAM;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyObject;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
@@ -34,41 +34,39 @@
 
 import android.content.Context;
 import android.net.INetd;
-import android.net.IpSecAlgorithm;
-import android.net.IpSecConfig;
 import android.net.IpSecManager;
 import android.net.IpSecSpiResponse;
 import android.net.IpSecTransform;
-import android.net.IpSecTransformResponse;
 import android.net.IpSecUdpEncapResponse;
 import android.os.Binder;
 import android.os.ParcelFileDescriptor;
 import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.system.ErrnoException;
 import android.system.Os;
+
 import java.io.FileDescriptor;
 import java.net.InetAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
 
 /** Unit tests for {@link IpSecService}. */
 @SmallTest
-@RunWith(JUnit4.class)
+@RunWith(AndroidJUnit4.class)
 public class IpSecServiceTest {
 
     private static final int DROID_SPI = 0xD1201D;
-    private static final int DROID_SPI2 = DROID_SPI + 1;
+    private static final int MAX_NUM_ENCAP_SOCKETS = 100;
+    private static final int MAX_NUM_SPIS = 100;
     private static final int TEST_UDP_ENCAP_INVALID_PORT = 100;
     private static final int TEST_UDP_ENCAP_PORT_OUT_RANGE = 100000;
-    private static final int TEST_UDP_ENCAP_PORT = 34567;
-
-    private static final String IPV4_LOOPBACK = "127.0.0.1";
-    private static final String IPV4_ADDR = "192.168.0.2";
 
     private static final InetAddress INADDR_ANY;
 
@@ -80,21 +78,6 @@
         }
     }
 
-    private static final int[] DIRECTIONS =
-            new int[] {IpSecTransform.DIRECTION_OUT, IpSecTransform.DIRECTION_IN};
-    private static final byte[] CRYPT_KEY = {
-        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-        0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
-    };
-    private static final byte[] AUTH_KEY = {
-        0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
-        0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F
-    };
-
     Context mMockContext;
     INetd mMockNetd;
     IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
@@ -118,44 +101,6 @@
     }
 
     @Test
-    public void testIpSecServiceReserveSpi() throws Exception {
-        when(mMockNetd.ipSecAllocateSpi(
-                        anyInt(),
-                        eq(IpSecTransform.DIRECTION_OUT),
-                        anyString(),
-                        eq(IPV4_LOOPBACK),
-                        eq(DROID_SPI)))
-                .thenReturn(DROID_SPI);
-
-        IpSecSpiResponse spiResp =
-                mIpSecService.reserveSecurityParameterIndex(
-                        IpSecTransform.DIRECTION_OUT, IPV4_LOOPBACK, DROID_SPI, new Binder());
-        assertEquals(IpSecManager.Status.OK, spiResp.status);
-        assertEquals(DROID_SPI, spiResp.spi);
-    }
-
-    @Test
-    public void testReleaseSecurityParameterIndex() throws Exception {
-        when(mMockNetd.ipSecAllocateSpi(
-                        anyInt(),
-                        eq(IpSecTransform.DIRECTION_OUT),
-                        anyString(),
-                        eq(IPV4_LOOPBACK),
-                        eq(DROID_SPI)))
-                .thenReturn(DROID_SPI);
-
-        IpSecSpiResponse spiResp =
-                mIpSecService.reserveSecurityParameterIndex(
-                        IpSecTransform.DIRECTION_OUT, IPV4_LOOPBACK, DROID_SPI, new Binder());
-
-        mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId);
-
-        verify(mMockNetd)
-                .ipSecDeleteSecurityAssociation(
-                        eq(spiResp.resourceId), anyInt(), anyString(), anyString(), eq(DROID_SPI));
-    }
-
-    @Test
     public void testReleaseInvalidSecurityParameterIndex() throws Exception {
         try {
             mIpSecService.releaseSecurityParameterIndex(1);
@@ -238,6 +183,7 @@
                 mIpSecService.openUdpEncapsulationSocket(0, new Binder());
         assertNotNull(udpEncapResp);
         assertEquals(IpSecManager.Status.OK, udpEncapResp.status);
+        assertNotEquals(0, udpEncapResp.port);
         mIpSecService.closeUdpEncapsulationSocket(udpEncapResp.resourceId);
         udpEncapResp.fileDescriptor.close();
     }
@@ -285,108 +231,6 @@
         }
     }
 
-    IpSecConfig buildIpSecConfig() throws Exception {
-        IpSecManager ipSecManager = new IpSecManager(mIpSecService);
-
-        // Mocking the netd to allocate SPI
-        when(mMockNetd.ipSecAllocateSpi(anyInt(), anyInt(), anyString(), anyString(), anyInt()))
-                .thenReturn(DROID_SPI)
-                .thenReturn(DROID_SPI2);
-
-        IpSecAlgorithm encryptAlgo = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
-        IpSecAlgorithm authAlgo =
-                new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 8);
-
-        InetAddress localAddr = InetAddress.getByAddress(new byte[] {127, 0, 0, 1});
-
-        /** Allocate and add SPI records in the IpSecService through IpSecManager interface. */
-        IpSecManager.SecurityParameterIndex outSpi =
-                ipSecManager.reserveSecurityParameterIndex(IpSecTransform.DIRECTION_OUT, localAddr);
-        IpSecManager.SecurityParameterIndex inSpi =
-                ipSecManager.reserveSecurityParameterIndex(IpSecTransform.DIRECTION_IN, localAddr);
-
-        IpSecConfig ipSecConfig =
-                new IpSecTransform.Builder(mMockContext)
-                        .setSpi(IpSecTransform.DIRECTION_OUT, outSpi)
-                        .setSpi(IpSecTransform.DIRECTION_IN, inSpi)
-                        .setEncryption(IpSecTransform.DIRECTION_OUT, encryptAlgo)
-                        .setAuthentication(IpSecTransform.DIRECTION_OUT, authAlgo)
-                        .setEncryption(IpSecTransform.DIRECTION_IN, encryptAlgo)
-                        .setAuthentication(IpSecTransform.DIRECTION_IN, authAlgo)
-                        .getIpSecConfig();
-        return ipSecConfig;
-    }
-
-    @Test
-    public void testCreateTransportModeTransform() throws Exception {
-        IpSecConfig ipSecConfig = buildIpSecConfig();
-
-        IpSecTransformResponse createTransformResp =
-                mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
-        assertEquals(IpSecManager.Status.OK, createTransformResp.status);
-
-        verify(mMockNetd)
-                .ipSecAddSecurityAssociation(
-                        eq(createTransformResp.resourceId),
-                        anyInt(),
-                        eq(IpSecTransform.DIRECTION_OUT),
-                        anyString(),
-                        anyString(),
-                        anyLong(),
-                        eq(DROID_SPI),
-                        eq(IpSecAlgorithm.AUTH_HMAC_SHA256),
-                        eq(AUTH_KEY),
-                        anyInt(),
-                        eq(IpSecAlgorithm.CRYPT_AES_CBC),
-                        eq(CRYPT_KEY),
-                        anyInt(),
-                        anyInt(),
-                        anyInt(),
-                        anyInt());
-        verify(mMockNetd)
-                .ipSecAddSecurityAssociation(
-                        eq(createTransformResp.resourceId),
-                        anyInt(),
-                        eq(IpSecTransform.DIRECTION_IN),
-                        anyString(),
-                        anyString(),
-                        anyLong(),
-                        eq(DROID_SPI2),
-                        eq(IpSecAlgorithm.AUTH_HMAC_SHA256),
-                        eq(AUTH_KEY),
-                        anyInt(),
-                        eq(IpSecAlgorithm.CRYPT_AES_CBC),
-                        eq(CRYPT_KEY),
-                        anyInt(),
-                        anyInt(),
-                        anyInt(),
-                        anyInt());
-    }
-
-    @Test
-    public void testDeleteTransportModeTransform() throws Exception {
-        IpSecConfig ipSecConfig = buildIpSecConfig();
-
-        IpSecTransformResponse createTransformResp =
-                mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
-        mIpSecService.deleteTransportModeTransform(createTransformResp.resourceId);
-
-        verify(mMockNetd)
-                .ipSecDeleteSecurityAssociation(
-                        eq(createTransformResp.resourceId),
-                        eq(IpSecTransform.DIRECTION_OUT),
-                        anyString(),
-                        anyString(),
-                        eq(DROID_SPI));
-        verify(mMockNetd)
-                .ipSecDeleteSecurityAssociation(
-                        eq(createTransformResp.resourceId),
-                        eq(IpSecTransform.DIRECTION_IN),
-                        anyString(),
-                        anyString(),
-                        eq(DROID_SPI2));
-    }
-
     @Test
     public void testDeleteInvalidTransportModeTransform() throws Exception {
         try {
@@ -397,39 +241,142 @@
     }
 
     @Test
-    public void testApplyTransportModeTransform() throws Exception {
-        IpSecConfig ipSecConfig = buildIpSecConfig();
-
-        IpSecTransformResponse createTransformResp =
-                mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
-        ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
-
-        int resourceId = createTransformResp.resourceId;
-        mIpSecService.applyTransportModeTransform(pfd, resourceId);
-
-        verify(mMockNetd)
-                .ipSecApplyTransportModeTransform(
-                        eq(pfd.getFileDescriptor()),
-                        eq(resourceId),
-                        eq(IpSecTransform.DIRECTION_OUT),
-                        anyString(),
-                        anyString(),
-                        eq(DROID_SPI));
-        verify(mMockNetd)
-                .ipSecApplyTransportModeTransform(
-                        eq(pfd.getFileDescriptor()),
-                        eq(resourceId),
-                        eq(IpSecTransform.DIRECTION_IN),
-                        anyString(),
-                        anyString(),
-                        eq(DROID_SPI2));
-    }
-
-    @Test
     public void testRemoveTransportModeTransform() throws Exception {
         ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
         mIpSecService.removeTransportModeTransform(pfd, 1);
 
         verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd.getFileDescriptor());
     }
+
+    @Test
+    public void testValidateIpAddresses() throws Exception {
+        String[] invalidAddresses =
+                new String[] {"www.google.com", "::", "2001::/64", "0.0.0.0", ""};
+        for (String address : invalidAddresses) {
+            try {
+                IpSecSpiResponse spiResp =
+                        mIpSecService.reserveSecurityParameterIndex(
+                                IpSecTransform.DIRECTION_OUT, address, DROID_SPI, new Binder());
+                fail("Invalid address was passed through IpSecService validation: " + address);
+            } catch (IllegalArgumentException e) {
+            } catch (Exception e) {
+                fail(
+                        "Invalid InetAddress was not caught in validation: "
+                                + address
+                                + ", Exception: "
+                                + e);
+            }
+        }
+    }
+
+    /**
+     * This function checks if the number of encap UDP socket that one UID can reserve
+     * has a reasonable limit.
+     */
+    @Test
+    public void testSocketResourceTrackerLimitation() throws Exception {
+        List<IpSecUdpEncapResponse> openUdpEncapSockets = new ArrayList<IpSecUdpEncapResponse>();
+        // Reserve sockets until it fails.
+        for (int i = 0; i < MAX_NUM_ENCAP_SOCKETS; i++) {
+            IpSecUdpEncapResponse newUdpEncapSocket =
+                    mIpSecService.openUdpEncapsulationSocket(0, new Binder());
+            assertNotNull(newUdpEncapSocket);
+            if (IpSecManager.Status.OK != newUdpEncapSocket.status) {
+                break;
+            }
+            openUdpEncapSockets.add(newUdpEncapSocket);
+        }
+        // Assert that the total sockets quota has a reasonable limit.
+        assertTrue(
+                openUdpEncapSockets.size() > 0
+                        && openUdpEncapSockets.size() < MAX_NUM_ENCAP_SOCKETS);
+
+        // Try to reserve one more UDP encapsulation socket, and should fail.
+        IpSecUdpEncapResponse extraUdpEncapSocket =
+                mIpSecService.openUdpEncapsulationSocket(0, new Binder());
+        assertNotNull(extraUdpEncapSocket);
+        assertEquals(IpSecManager.Status.RESOURCE_UNAVAILABLE, extraUdpEncapSocket.status);
+
+        // Close one of the open UDP encapsulation scokets.
+        mIpSecService.closeUdpEncapsulationSocket(openUdpEncapSockets.get(0).resourceId);
+        openUdpEncapSockets.get(0).fileDescriptor.close();
+        openUdpEncapSockets.remove(0);
+
+        // Try to reserve one more UDP encapsulation socket, and should be successful.
+        extraUdpEncapSocket = mIpSecService.openUdpEncapsulationSocket(0, new Binder());
+        assertNotNull(extraUdpEncapSocket);
+        assertEquals(IpSecManager.Status.OK, extraUdpEncapSocket.status);
+        openUdpEncapSockets.add(extraUdpEncapSocket);
+
+        // Close open UDP sockets.
+        for (IpSecUdpEncapResponse openSocket : openUdpEncapSockets) {
+            mIpSecService.closeUdpEncapsulationSocket(openSocket.resourceId);
+            openSocket.fileDescriptor.close();
+        }
+    }
+
+    /**
+     * This function checks if the number of SPI that one UID can reserve
+     * has a reasonable limit.
+     * This test does not test for both address families or duplicate SPIs because resource
+     * tracking code does not depend on them.
+     */
+    @Test
+    public void testSpiResourceTrackerLimitation() throws Exception {
+        List<IpSecSpiResponse> reservedSpis = new ArrayList<IpSecSpiResponse>();
+        // Return the same SPI for all SPI allocation since IpSecService only
+        // tracks the resource ID.
+        when(mMockNetd.ipSecAllocateSpi(
+                        anyInt(),
+                        eq(IpSecTransform.DIRECTION_OUT),
+                        anyString(),
+                        eq(InetAddress.getLoopbackAddress().getHostAddress()),
+                        anyInt()))
+                .thenReturn(DROID_SPI);
+        // Reserve spis until it fails.
+        for (int i = 0; i < MAX_NUM_SPIS; i++) {
+            IpSecSpiResponse newSpi =
+                    mIpSecService.reserveSecurityParameterIndex(
+                            0x1,
+                            InetAddress.getLoopbackAddress().getHostAddress(),
+                            DROID_SPI + i,
+                            new Binder());
+            assertNotNull(newSpi);
+            if (IpSecManager.Status.OK != newSpi.status) {
+                break;
+            }
+            reservedSpis.add(newSpi);
+        }
+        // Assert that the SPI quota has a reasonable limit.
+        assertTrue(reservedSpis.size() > 0 && reservedSpis.size() < MAX_NUM_SPIS);
+
+        // Try to reserve one more SPI, and should fail.
+        IpSecSpiResponse extraSpi =
+                mIpSecService.reserveSecurityParameterIndex(
+                        0x1,
+                        InetAddress.getLoopbackAddress().getHostAddress(),
+                        DROID_SPI + MAX_NUM_SPIS,
+                        new Binder());
+        assertNotNull(extraSpi);
+        assertEquals(IpSecManager.Status.RESOURCE_UNAVAILABLE, extraSpi.status);
+
+        // Release one reserved spi.
+        mIpSecService.releaseSecurityParameterIndex(reservedSpis.get(0).resourceId);
+        reservedSpis.remove(0);
+
+        // Should successfully reserve one more spi.
+        extraSpi =
+                mIpSecService.reserveSecurityParameterIndex(
+                        0x1,
+                        InetAddress.getLoopbackAddress().getHostAddress(),
+                        DROID_SPI + MAX_NUM_SPIS,
+                        new Binder());
+        assertNotNull(extraSpi);
+        assertEquals(IpSecManager.Status.OK, extraSpi.status);
+
+        // Release reserved SPIs.
+        for (IpSecSpiResponse spiResp : reservedSpis) {
+            mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId);
+        }
+    }
 }
diff --git a/tests/net/java/com/android/server/NsdServiceTest.java b/tests/net/java/com/android/server/NsdServiceTest.java
index 68cb251..b88c784 100644
--- a/tests/net/java/com/android/server/NsdServiceTest.java
+++ b/tests/net/java/com/android/server/NsdServiceTest.java
@@ -77,7 +77,10 @@
 
     @After
     public void tearDown() throws Exception {
-        mThread.quit();
+        if (mThread != null) {
+            mThread.quit();
+            mThread = null;
+        }
     }
 
     @Test
@@ -95,6 +98,9 @@
         client2.disconnect();
 
         verify(mDaemon, timeout(mTimeoutMs).times(1)).stop();
+
+        client1.disconnect();
+        client2.disconnect();
     }
 
     @Test
@@ -131,6 +137,8 @@
 
         // checks that request are cleaned
         verifyDaemonCommands("stop-register 2", "stop-discover 3", "stop-resolve 4");
+
+        client.disconnect();
     }
 
     NsdService makeService() {
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
index d11565a..0656c5f 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.connectivity;
 
+import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
+import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
 import static com.android.server.connectivity.MetricsTestUtil.aBool;
 import static com.android.server.connectivity.MetricsTestUtil.aByteArray;
 import static com.android.server.connectivity.MetricsTestUtil.aLong;
@@ -31,29 +33,41 @@
 import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.ETHERNET;
 import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.MULTIPLE;
 import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.WIFI;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 
 import android.net.ConnectivityMetricsEvent;
 import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.ApfStats;
+import android.net.metrics.ConnectStats;
 import android.net.metrics.DefaultNetworkEvent;
 import android.net.metrics.DhcpClientEvent;
 import android.net.metrics.DhcpErrorEvent;
 import android.net.metrics.DnsEvent;
+import android.net.metrics.DnsEvent;
 import android.net.metrics.IpManagerEvent;
 import android.net.metrics.IpReachabilityEvent;
 import android.net.metrics.NetworkEvent;
 import android.net.metrics.RaEvent;
 import android.net.metrics.ValidationProbeEvent;
+import android.net.metrics.WakeupStats;
+import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
+
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
+
 import java.util.Arrays;
 import java.util.List;
-import junit.framework.TestCase;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
 // TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
-public class IpConnectivityEventBuilderTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IpConnectivityEventBuilderTest {
 
-    @SmallTest
+    @Test
     public void testLinkLayerInferrence() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(IpReachabilityEvent.class),
@@ -182,43 +196,43 @@
         verifySerialization(want, ev);
     }
 
-    @SmallTest
+    @Test
     public void testDefaultNetworkEventSerialization() {
-        ConnectivityMetricsEvent ev = describeIpEvent(
-                aType(DefaultNetworkEvent.class),
-                anInt(102),
-                anIntArray(1, 2, 3),
-                anInt(101),
-                aBool(true),
-                aBool(false));
+        DefaultNetworkEvent ev = new DefaultNetworkEvent(1001);
+        ev.netId = 102;
+        ev.transports = 2;
+        ev.previousTransports = 4;
+        ev.ipv4 = true;
+        ev.initialScore = 20;
+        ev.finalScore = 60;
+        ev.durationMs = 54;
+        ev.validatedMs = 27;
 
         String want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
-                "  link_layer: 0",
-                "  network_id: 0",
-                "  time_ms: 1",
-                "  transports: 0",
+                "  link_layer: 4",
+                "  network_id: 102",
+                "  time_ms: 0",
+                "  transports: 2",
                 "  default_network_event <",
-                "    network_id <",
-                "      network_id: 102",
-                "    >",
-                "    previous_network_id <",
-                "      network_id: 101",
-                "    >",
-                "    previous_network_ip_support: 1",
-                "    transport_types: 1",
-                "    transport_types: 2",
-                "    transport_types: 3",
+                "    default_network_duration_ms: 54",
+                "    final_score: 60",
+                "    initial_score: 20",
+                "    ip_support: 1",
+                "    no_default_network_duration_ms: 0",
+                "    previous_default_network_link_layer: 1",
+                "    previous_network_ip_support: 0",
+                "    validation_duration_ms: 27",
                 "  >",
                 ">",
                 "version: 2\n");
 
-        verifySerialization(want, ev);
+        verifySerialization(want, IpConnectivityEventBuilder.toProto(ev));
     }
 
-    @SmallTest
+    @Test
     public void testDhcpClientEventSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(DhcpClientEvent.class),
@@ -244,7 +258,7 @@
         verifySerialization(want, ev);
     }
 
-    @SmallTest
+    @Test
     public void testDhcpErrorEventSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(DhcpErrorEvent.class),
@@ -269,7 +283,7 @@
         verifySerialization(want, ev);
     }
 
-    @SmallTest
+    @Test
     public void testIpManagerEventSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(IpManagerEvent.class),
@@ -295,7 +309,7 @@
         verifySerialization(want, ev);
     }
 
-    @SmallTest
+    @Test
     public void testIpReachabilityEventSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(IpReachabilityEvent.class),
@@ -319,11 +333,10 @@
         verifySerialization(want, ev);
     }
 
-    @SmallTest
+    @Test
     public void testNetworkEventSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(NetworkEvent.class),
-                anInt(100),
                 anInt(5),
                 aLong(20410));
 
@@ -338,9 +351,6 @@
                 "  network_event <",
                 "    event_type: 5",
                 "    latency_ms: 20410",
-                "    network_id <",
-                "      network_id: 100",
-                "    >",
                 "  >",
                 ">",
                 "version: 2\n");
@@ -348,7 +358,7 @@
         verifySerialization(want, ev);
     }
 
-    @SmallTest
+    @Test
     public void testValidationProbeEventSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(ValidationProbeEvent.class),
@@ -375,7 +385,7 @@
         verifySerialization(want, ev);
     }
 
-    @SmallTest
+    @Test
     public void testApfProgramEventSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(ApfProgramEvent.class),
@@ -409,7 +419,7 @@
         verifySerialization(want, ev);
     }
 
-    @SmallTest
+    @Test
     public void testApfStatsSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(ApfStats.class),
@@ -442,6 +452,8 @@
                 "    program_updates_all: 7",
                 "    program_updates_allowing_multicast: 3",
                 "    received_ras: 10",
+                "    total_packet_dropped: 0",
+                "    total_packet_processed: 0",
                 "    zero_lifetime_ras: 1",
                 "  >",
                 ">",
@@ -450,7 +462,7 @@
         verifySerialization(want, ev);
     }
 
-    @SmallTest
+    @Test
     public void testRaEventSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(RaEvent.class),
@@ -483,11 +495,71 @@
         verifySerialization(want, ev);
     }
 
+    @Test
+    public void testWakeupStatsSerialization() {
+        WakeupStats stats = new WakeupStats("wlan0");
+        stats.totalWakeups = 14;
+        stats.applicationWakeups = 5;
+        stats.nonApplicationWakeups = 1;
+        stats.rootWakeups = 2;
+        stats.systemWakeups = 3;
+        stats.noUidWakeups = 3;
+        stats.l2UnicastCount = 5;
+        stats.l2MulticastCount = 1;
+        stats.l2BroadcastCount = 2;
+        stats.ethertypes.put(0x800, 3);
+        stats.ethertypes.put(0x86dd, 3);
+        stats.ipNextHeaders.put(6, 5);
+
+
+        IpConnectivityEvent got = IpConnectivityEventBuilder.toProto(stats);
+        String want = String.join("\n",
+                "dropped_events: 0",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 4",
+                "  network_id: 0",
+                "  time_ms: 0",
+                "  transports: 0",
+                "  wakeup_stats <",
+                "    application_wakeups: 5",
+                "    duration_sec: 0",
+                "    ethertype_counts <",
+                "      key: 2048",
+                "      value: 3",
+                "    >",
+                "    ethertype_counts <",
+                "      key: 34525",
+                "      value: 3",
+                "    >",
+                "    ip_next_header_counts <",
+                "      key: 6",
+                "      value: 5",
+                "    >",
+                "    l2_broadcast_count: 2",
+                "    l2_multicast_count: 1",
+                "    l2_unicast_count: 5",
+                "    no_uid_wakeups: 3",
+                "    non_application_wakeups: 1",
+                "    root_wakeups: 2",
+                "    system_wakeups: 3",
+                "    total_wakeups: 14",
+                "  >",
+                ">",
+                "version: 2\n");
+
+        verifySerialization(want, got);
+    }
+
     static void verifySerialization(String want, ConnectivityMetricsEvent... input) {
+        List<IpConnectivityEvent> protoInput =
+                IpConnectivityEventBuilder.toProto(Arrays.asList(input));
+        verifySerialization(want, protoInput.toArray(new IpConnectivityEvent[0]));
+    }
+
+    static void verifySerialization(String want, IpConnectivityEvent... input) {
         try {
-            List<IpConnectivityEvent> proto =
-                    IpConnectivityEventBuilder.toProto(Arrays.asList(input));
-            byte[] got = IpConnectivityEventBuilder.serialize(0, proto);
+            byte[] got = IpConnectivityEventBuilder.serialize(0, Arrays.asList(input));
             IpConnectivityLog log = IpConnectivityLog.parseFrom(got);
             assertEquals(want, log.toString());
         } catch (Exception e) {
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index e01469b..10d6deb 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -18,6 +18,7 @@
 
 import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
 import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -30,6 +31,10 @@
 import android.net.ConnectivityManager;
 import android.net.ConnectivityMetricsEvent;
 import android.net.IIpConnectivityMetrics;
+import android.net.IpPrefix;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.RouteInfo;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.metrics.ApfProgramEvent;
@@ -41,18 +46,22 @@
 import android.net.metrics.IpReachabilityEvent;
 import android.net.metrics.RaEvent;
 import android.net.metrics.ValidationProbeEvent;
-import android.system.OsConstants;
 import android.os.Parcelable;
 import android.support.test.runner.AndroidJUnit4;
+import android.system.OsConstants;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Base64;
+
+import com.android.internal.util.BitUtils;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass;
+
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
+
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
@@ -69,6 +78,9 @@
     private static final String EXAMPLE_IPV4 = "192.0.2.1";
     private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1";
 
+    private static final byte[] MAC_ADDR =
+            {(byte)0x84, (byte)0xc9, (byte)0xb2, (byte)0x6a, (byte)0xed, (byte)0x4b};
+
     @Mock Context mCtx;
     @Mock IIpConnectivityMetrics mMockService;
     @Mock ConnectivityManager mCm;
@@ -162,6 +174,124 @@
     }
 
     @Test
+    public void testDefaultNetworkEvents() throws Exception {
+        final long cell = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_CELLULAR});
+        final long wifi = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_WIFI});
+
+        NetworkAgentInfo[][] defaultNetworks = {
+            // nothing -> cell
+            {null, makeNai(100, 10, false, true, cell)},
+            // cell -> wifi
+            {makeNai(100, 50, true, true, cell), makeNai(101, 20, true, false, wifi)},
+            // wifi -> nothing
+            {makeNai(101, 60, true, false, wifi), null},
+            // nothing -> cell
+            {null, makeNai(102, 10, true, true, cell)},
+            // cell -> wifi
+            {makeNai(102, 50, true, true, cell), makeNai(103, 20, true, false, wifi)},
+        };
+
+        long timeMs = mService.mDefaultNetworkMetrics.creationTimeMs;
+        long durationMs = 1001;
+        for (NetworkAgentInfo[] pair : defaultNetworks) {
+            timeMs += durationMs;
+            durationMs += durationMs;
+            mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs, pair[1], pair[0]);
+        }
+
+        String want = String.join("\n",
+                "dropped_events: 0",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 5",
+                "  network_id: 0",
+                "  time_ms: 0",
+                "  transports: 0",
+                "  default_network_event <",
+                "    default_network_duration_ms: 1001",
+                "    final_score: 0",
+                "    initial_score: 0",
+                "    ip_support: 0",
+                "    no_default_network_duration_ms: 0",
+                "    previous_default_network_link_layer: 0",
+                "    previous_network_ip_support: 0",
+                "    validation_duration_ms: 0",
+                "  >",
+                ">",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 2",
+                "  network_id: 100",
+                "  time_ms: 0",
+                "  transports: 1",
+                "  default_network_event <",
+                "    default_network_duration_ms: 2002",
+                "    final_score: 50",
+                "    initial_score: 10",
+                "    ip_support: 3",
+                "    no_default_network_duration_ms: 0",
+                "    previous_default_network_link_layer: 0",
+                "    previous_network_ip_support: 0",
+                "    validation_duration_ms: 2002",
+                "  >",
+                ">",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 4",
+                "  network_id: 101",
+                "  time_ms: 0",
+                "  transports: 2",
+                "  default_network_event <",
+                "    default_network_duration_ms: 4004",
+                "    final_score: 60",
+                "    initial_score: 20",
+                "    ip_support: 1",
+                "    no_default_network_duration_ms: 0",
+                "    previous_default_network_link_layer: 2",
+                "    previous_network_ip_support: 0",
+                "    validation_duration_ms: 4004",
+                "  >",
+                ">",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 5",
+                "  network_id: 0",
+                "  time_ms: 0",
+                "  transports: 0",
+                "  default_network_event <",
+                "    default_network_duration_ms: 8008",
+                "    final_score: 0",
+                "    initial_score: 0",
+                "    ip_support: 0",
+                "    no_default_network_duration_ms: 0",
+                "    previous_default_network_link_layer: 4",
+                "    previous_network_ip_support: 0",
+                "    validation_duration_ms: 0",
+                "  >",
+                ">",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 2",
+                "  network_id: 102",
+                "  time_ms: 0",
+                "  transports: 1",
+                "  default_network_event <",
+                "    default_network_duration_ms: 16016",
+                "    final_score: 50",
+                "    initial_score: 10",
+                "    ip_support: 3",
+                "    no_default_network_duration_ms: 0",
+                "    previous_default_network_link_layer: 4",
+                "    previous_network_ip_support: 0",
+                "    validation_duration_ms: 16016",
+                "  >",
+                ">",
+                "version: 2\n");
+
+        verifySerialization(want, getdump("flush"));
+    }
+
+    @Test
     public void testEndToEndLogging() throws Exception {
         // TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
         IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
@@ -194,7 +324,6 @@
         Parcelable[] events = {
             new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED),
             new DhcpClientEvent("SomeState", 192),
-            new DefaultNetworkEvent(102, new int[]{1,2,3}, 101, true, false),
             new IpManagerEvent(IpManagerEvent.PROVISIONING_OK, 5678),
             validationEv,
             apfStats,
@@ -224,6 +353,31 @@
         dnsEvent(101, EVENT_GETADDRINFO, 0, 56);
         dnsEvent(101, EVENT_GETHOSTBYNAME, 0, 34);
 
+        // iface, uid
+        final byte[] mac = {0x48, 0x7c, 0x2b, 0x6a, 0x3e, 0x4b};
+        final String srcIp = "192.168.2.1";
+        final String dstIp = "192.168.2.23";
+        final int sport = 2356;
+        final int dport = 13489;
+        final long now = 1001L;
+        final int v4 = 0x800;
+        final int tcp = 6;
+        final int udp = 17;
+        wakeupEvent("wlan0", 1000, v4, tcp, mac, srcIp, dstIp, sport, dport, 1001L);
+        wakeupEvent("wlan0", 10123, v4, tcp, mac, srcIp, dstIp, sport, dport, 1001L);
+        wakeupEvent("wlan0", 1000, v4, udp, mac, srcIp, dstIp, sport, dport, 1001L);
+        wakeupEvent("wlan0", 10008, v4, udp, mac, srcIp, dstIp, sport, dport, 1001L);
+        wakeupEvent("wlan0", -1, v4, udp, mac, srcIp, dstIp, sport, dport, 1001L);
+        wakeupEvent("wlan0", 10008, v4, tcp, mac, srcIp, dstIp, sport, dport, 1001L);
+
+        long timeMs = mService.mDefaultNetworkMetrics.creationTimeMs;
+        final long cell = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_CELLULAR});
+        final long wifi = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_WIFI});
+        NetworkAgentInfo cellNai = makeNai(100, 50, false, true, cell);
+        NetworkAgentInfo wifiNai = makeNai(101, 60, true, false, wifi);
+        mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs + 200, cellNai, null);
+        mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs + 300, wifiNai, cellNai);
+
         String want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
@@ -255,25 +409,6 @@
                 "  network_id: 0",
                 "  time_ms: 300",
                 "  transports: 0",
-                "  default_network_event <",
-                "    network_id <",
-                "      network_id: 102",
-                "    >",
-                "    previous_network_id <",
-                "      network_id: 101",
-                "    >",
-                "    previous_network_ip_support: 1",
-                "    transport_types: 1",
-                "    transport_types: 2",
-                "    transport_types: 3",
-                "  >",
-                ">",
-                "events <",
-                "  if_name: \"\"",
-                "  link_layer: 4",
-                "  network_id: 0",
-                "  time_ms: 400",
-                "  transports: 0",
                 "  ip_provisioning_event <",
                 "    event_type: 1",
                 "    if_name: \"\"",
@@ -284,7 +419,7 @@
                 "  if_name: \"\"",
                 "  link_layer: 4",
                 "  network_id: 0",
-                "  time_ms: 500",
+                "  time_ms: 400",
                 "  transports: 0",
                 "  validation_probe_event <",
                 "    latency_ms: 40730",
@@ -296,7 +431,7 @@
                 "  if_name: \"\"",
                 "  link_layer: 4",
                 "  network_id: 0",
-                "  time_ms: 600",
+                "  time_ms: 500",
                 "  transports: 0",
                 "  apf_statistics <",
                 "    dropped_ras: 2",
@@ -308,6 +443,8 @@
                 "    program_updates_all: 7",
                 "    program_updates_allowing_multicast: 3",
                 "    received_ras: 10",
+                "    total_packet_dropped: 0",
+                "    total_packet_processed: 0",
                 "    zero_lifetime_ras: 1",
                 "  >",
                 ">",
@@ -315,7 +452,7 @@
                 "  if_name: \"\"",
                 "  link_layer: 4",
                 "  network_id: 0",
-                "  time_ms: 700",
+                "  time_ms: 600",
                 "  transports: 0",
                 "  ra_event <",
                 "    dnssl_lifetime: -1",
@@ -328,6 +465,40 @@
                 ">",
                 "events <",
                 "  if_name: \"\"",
+                "  link_layer: 5",
+                "  network_id: 0",
+                "  time_ms: 0",
+                "  transports: 0",
+                "  default_network_event <",
+                "    default_network_duration_ms: 200",
+                "    final_score: 0",
+                "    initial_score: 0",
+                "    ip_support: 0",
+                "    no_default_network_duration_ms: 0",
+                "    previous_default_network_link_layer: 0",
+                "    previous_network_ip_support: 0",
+                "    validation_duration_ms: 0",
+                "  >",
+                ">",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 2",
+                "  network_id: 100",
+                "  time_ms: 0",
+                "  transports: 1",
+                "  default_network_event <",
+                "    default_network_duration_ms: 100",
+                "    final_score: 50",
+                "    initial_score: 50",
+                "    ip_support: 2",
+                "    no_default_network_duration_ms: 0",
+                "    previous_default_network_link_layer: 0",
+                "    previous_network_ip_support: 0",
+                "    validation_duration_ms: 100",
+                "  >",
+                ">",
+                "events <",
+                "  if_name: \"\"",
                 "  link_layer: 4",
                 "  network_id: 100",
                 "  time_ms: 0",
@@ -367,6 +538,10 @@
                 "    event_types: 1",
                 "    event_types: 1",
                 "    event_types: 2",
+                "    getaddrinfo_error_count: 0",
+                "    getaddrinfo_query_count: 0",
+                "    gethostbyname_error_count: 0",
+                "    gethostbyname_query_count: 0",
                 "    latencies_ms: 3456",
                 "    latencies_ms: 45",
                 "    latencies_ms: 638",
@@ -384,12 +559,47 @@
                 "  dns_lookup_batch <",
                 "    event_types: 1",
                 "    event_types: 2",
+                "    getaddrinfo_error_count: 0",
+                "    getaddrinfo_query_count: 0",
+                "    gethostbyname_error_count: 0",
+                "    gethostbyname_query_count: 0",
                 "    latencies_ms: 56",
                 "    latencies_ms: 34",
                 "    return_codes: 0",
                 "    return_codes: 0",
                 "  >",
                 ">",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 4",
+                "  network_id: 0",
+                "  time_ms: 0",
+                "  transports: 0",
+                "  wakeup_stats <",
+                "    application_wakeups: 3",
+                "    duration_sec: 0",
+                "    ethertype_counts <",
+                "      key: 2048",
+                "      value: 6",
+                "    >",
+                "    ip_next_header_counts <",
+                "      key: 6",
+                "      value: 3",
+                "    >",
+                "    ip_next_header_counts <",
+                "      key: 17",
+                "      value: 3",
+                "    >",
+                "    l2_broadcast_count: 0",
+                "    l2_multicast_count: 0",
+                "    l2_unicast_count: 6",
+                "    no_uid_wakeups: 1",
+                "    non_application_wakeups: 0",
+                "    root_wakeups: 0",
+                "    system_wakeups: 2",
+                "    total_wakeups: 6",
+                "  >",
+                ">",
                 "version: 2\n");
 
         verifySerialization(want, getdump("flush"));
@@ -410,6 +620,32 @@
         mNetdListener.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
     }
 
+    void wakeupEvent(String iface, int uid, int ether, int ip, byte[] mac, String srcIp,
+            String dstIp, int sport, int dport, long now) throws Exception {
+        String prefix = NetdEventListenerService.WAKEUP_EVENT_IFACE_PREFIX + iface;
+        mNetdListener.onWakeupEvent(prefix, uid, ether, ip, mac, srcIp, dstIp, sport, dport, now);
+    }
+
+    NetworkAgentInfo makeNai(int netId, int score, boolean ipv4, boolean ipv6, long transports) {
+        NetworkAgentInfo nai = mock(NetworkAgentInfo.class);
+        when(nai.network()).thenReturn(new Network(netId));
+        when(nai.getCurrentScore()).thenReturn(score);
+        nai.linkProperties = new LinkProperties();
+        nai.networkCapabilities = new NetworkCapabilities();
+        for (int t : BitUtils.unpackBits(transports)) {
+            nai.networkCapabilities.addTransportType(t);
+        }
+        if (ipv4) {
+            nai.linkProperties.addLinkAddress(new LinkAddress("192.0.2.12/24"));
+            nai.linkProperties.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0")));
+        }
+        if (ipv6) {
+            nai.linkProperties.addLinkAddress(new LinkAddress("2001:db8:dead:beef:f00::a0/64"));
+            nai.linkProperties.addRoute(new RouteInfo(new IpPrefix("::/0")));
+        }
+        return nai;
+    }
+
     List<ConnectivityMetricsEvent> verifyEvents(int n, int timeoutMs) throws Exception {
         ArgumentCaptor<ConnectivityMetricsEvent> captor =
                 ArgumentCaptor.forClass(ConnectivityMetricsEvent.class);
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 77956be..354cf2f 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -16,24 +16,8 @@
 
 package com.android.server.connectivity;
 
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkMisc;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.format.DateUtils;
-import com.android.internal.R;
-import com.android.server.ConnectivityService;
-import com.android.server.connectivity.NetworkNotificationManager;
-import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
-import junit.framework.TestCase;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.anyInt;
@@ -44,7 +28,32 @@
 import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.reset;
 
-public class LingerMonitorTest extends TestCase {
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkInfo;
+import android.net.NetworkMisc;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
+import android.text.format.DateUtils;
+
+import com.android.internal.R;
+import com.android.server.ConnectivityService;
+import com.android.server.connectivity.NetworkNotificationManager;
+import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
+
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class LingerMonitorTest {
     static final String CELLULAR = "CELLULAR";
     static final String WIFI     = "WIFI";
 
@@ -62,6 +71,7 @@
     @Mock NetworkNotificationManager mNotifier;
     @Mock Resources mResources;
 
+    @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mCtx.getResources()).thenReturn(mResources);
@@ -71,7 +81,7 @@
         mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, HIGH_RATE_LIMIT);
     }
 
-    @SmallTest
+    @Test
     public void testTransitions() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         NetworkAgentInfo nai1 = wifiNai(100);
@@ -81,7 +91,7 @@
         assertFalse(mMonitor.isNotificationEnabled(nai2, nai1));
     }
 
-    @SmallTest
+    @Test
     public void testNotificationOnLinger() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -92,7 +102,7 @@
         verifyNotification(from, to);
     }
 
-    @SmallTest
+    @Test
     public void testToastOnLinger() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
@@ -103,7 +113,7 @@
         verifyToast(from, to);
     }
 
-    @SmallTest
+    @Test
     public void testNotificationClearedAfterDisconnect() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -117,7 +127,7 @@
         verify(mNotifier, times(1)).clearNotification(100);
     }
 
-    @SmallTest
+    @Test
     public void testNotificationClearedAfterSwitchingBack() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -131,7 +141,7 @@
         verify(mNotifier, times(1)).clearNotification(100);
     }
 
-    @SmallTest
+    @Test
     public void testUniqueToast() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
@@ -149,7 +159,7 @@
         verifyNoNotifications();
     }
 
-    @SmallTest
+    @Test
     public void testMultipleNotifications() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -168,7 +178,7 @@
         verifyNotification(wifi2, cell);
     }
 
-    @SmallTest
+    @Test
     public void testRateLimiting() throws InterruptedException {
         mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, LOW_RATE_LIMIT);
 
@@ -194,7 +204,7 @@
         verifyNoNotifications();
     }
 
-    @SmallTest
+    @Test
     public void testDailyLimiting() throws InterruptedException {
         mMonitor = new TestableLingerMonitor(mCtx, mNotifier, LOW_DAILY_LIMIT, HIGH_RATE_LIMIT);
 
@@ -221,7 +231,7 @@
         verifyNoNotifications();
     }
 
-    @SmallTest
+    @Test
     public void testUniqueNotification() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -238,7 +248,7 @@
         verifyNotification(from, to);
     }
 
-    @SmallTest
+    @Test
     public void testIgnoreNeverValidatedNetworks() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
         setNotificationSwitch(transition(WIFI, CELLULAR));
@@ -250,7 +260,7 @@
         verifyNoNotifications();
     }
 
-    @SmallTest
+    @Test
     public void testIgnoreCurrentlyValidatedNetworks() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
         setNotificationSwitch(transition(WIFI, CELLULAR));
@@ -262,7 +272,7 @@
         verifyNoNotifications();
     }
 
-    @SmallTest
+    @Test
     public void testNoNotificationType() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
         setNotificationSwitch();
@@ -273,7 +283,7 @@
         verifyNoNotifications();
     }
 
-    @SmallTest
+    @Test
     public void testNoTransitionToNotify() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NONE);
         setNotificationSwitch(transition(WIFI, CELLULAR));
@@ -284,7 +294,7 @@
         verifyNoNotifications();
     }
 
-    @SmallTest
+    @Test
     public void testDifferentTransitionToNotify() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
         setNotificationSwitch(transition(CELLULAR, WIFI));
diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
new file mode 100644
index 0000000..dfe31bd
--- /dev/null
+++ b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.net.ConnectivityManager;
+import android.net.InterfaceConfiguration;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.NetworkInfo;
+import android.os.Handler;
+import android.os.INetworkManagementService;
+import android.os.test.TestLooper;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.server.ConnectivityService;
+
+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;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class Nat464XlatTest {
+
+    static final String BASE_IFACE = "test0";
+    static final String STACKED_IFACE = "v4-test0";
+    static final LinkAddress ADDR = new LinkAddress("192.0.2.5/29");
+
+    @Mock ConnectivityService mConnectivity;
+    @Mock INetworkManagementService mNms;
+    @Mock InterfaceConfiguration mConfig;
+    @Mock NetworkAgentInfo mNai;
+
+    TestLooper mLooper;
+    Handler mHandler;
+
+    Nat464Xlat makeNat464Xlat() {
+        return new Nat464Xlat(mNms, mNai);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mLooper = new TestLooper();
+        mHandler = new Handler(mLooper.getLooper());
+
+        MockitoAnnotations.initMocks(this);
+
+        mNai.linkProperties = new LinkProperties();
+        mNai.linkProperties.setInterfaceName(BASE_IFACE);
+        mNai.networkInfo = new NetworkInfo(null);
+        mNai.networkInfo.setType(ConnectivityManager.TYPE_WIFI);
+        when(mNai.connService()).thenReturn(mConnectivity);
+        when(mNai.handler()).thenReturn(mHandler);
+
+        when(mNms.getInterfaceConfig(eq(STACKED_IFACE))).thenReturn(mConfig);
+        when(mConfig.getLinkAddress()).thenReturn(ADDR);
+    }
+
+    @Test
+    public void testRequiresClat() throws Exception {
+        final int[] supportedTypes = {
+            ConnectivityManager.TYPE_MOBILE,
+            ConnectivityManager.TYPE_WIFI,
+            ConnectivityManager.TYPE_ETHERNET,
+        };
+
+        // NetworkInfo doesn't allow setting the State directly, but rather
+        // requires setting DetailedState in order set State as a side-effect.
+        final NetworkInfo.DetailedState[] supportedDetailedStates = {
+            NetworkInfo.DetailedState.CONNECTED,
+            NetworkInfo.DetailedState.SUSPENDED,
+        };
+
+        for (int type : supportedTypes) {
+            mNai.networkInfo.setType(type);
+            for (NetworkInfo.DetailedState state : supportedDetailedStates) {
+                mNai.networkInfo.setDetailedState(state, "reason", "extraInfo");
+                assertTrue(
+                        String.format("requiresClat expected for type=%d state=%s", type, state),
+                        Nat464Xlat.requiresClat(mNai));
+            }
+        }
+    }
+
+    @Test
+    public void testNormalStartAndStop() throws Exception {
+        Nat464Xlat nat = makeNat464Xlat();
+        ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class);
+
+        // ConnectivityService starts clat.
+        nat.start();
+
+        verify(mNms).registerObserver(eq(nat));
+        verify(mNms).startClatd(eq(BASE_IFACE));
+
+        // Stacked interface up notification arrives.
+        nat.interfaceLinkStateChanged(STACKED_IFACE, true);
+        mLooper.dispatchNext();
+
+        verify(mNms).getInterfaceConfig(eq(STACKED_IFACE));
+        verify(mConnectivity).handleUpdateLinkProperties(eq(mNai), c.capture());
+        assertFalse(c.getValue().getStackedLinks().isEmpty());
+        assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
+        assertRunning(nat);
+
+        // ConnectivityService stops clat (Network disconnects, IPv4 addr appears, ...).
+        nat.stop();
+
+        verify(mNms).stopClatd(eq(BASE_IFACE));
+
+        // Stacked interface removed notification arrives.
+        nat.interfaceRemoved(STACKED_IFACE);
+        mLooper.dispatchNext();
+
+        verify(mNms).unregisterObserver(eq(nat));
+        verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture());
+        assertTrue(c.getValue().getStackedLinks().isEmpty());
+        assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
+        assertIdle(nat);
+
+        verifyNoMoreInteractions(mNms, mConnectivity);
+    }
+
+    @Test
+    public void testClatdCrashWhileRunning() throws Exception {
+        Nat464Xlat nat = makeNat464Xlat();
+        ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class);
+
+        // ConnectivityService starts clat.
+        nat.start();
+
+        verify(mNms).registerObserver(eq(nat));
+        verify(mNms).startClatd(eq(BASE_IFACE));
+
+        // Stacked interface up notification arrives.
+        nat.interfaceLinkStateChanged(STACKED_IFACE, true);
+        mLooper.dispatchNext();
+
+        verify(mNms).getInterfaceConfig(eq(STACKED_IFACE));
+        verify(mConnectivity, times(1)).handleUpdateLinkProperties(eq(mNai), c.capture());
+        assertFalse(c.getValue().getStackedLinks().isEmpty());
+        assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
+        assertRunning(nat);
+
+        // Stacked interface removed notification arrives (clatd crashed, ...).
+        nat.interfaceRemoved(STACKED_IFACE);
+        mLooper.dispatchNext();
+
+        verify(mNms).unregisterObserver(eq(nat));
+        verify(mNms).stopClatd(eq(BASE_IFACE));
+        verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture());
+        assertTrue(c.getValue().getStackedLinks().isEmpty());
+        assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
+        assertIdle(nat);
+
+        // ConnectivityService stops clat: no-op.
+        nat.stop();
+
+        verifyNoMoreInteractions(mNms, mConnectivity);
+    }
+
+    @Test
+    public void testStopBeforeClatdStarts() throws Exception {
+        Nat464Xlat nat = makeNat464Xlat();
+
+        // ConnectivityService starts clat.
+        nat.start();
+
+        verify(mNms).registerObserver(eq(nat));
+        verify(mNms).startClatd(eq(BASE_IFACE));
+
+        // ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...)
+        nat.stop();
+
+        verify(mNms).unregisterObserver(eq(nat));
+        verify(mNms).stopClatd(eq(BASE_IFACE));
+        assertIdle(nat);
+
+        // In-flight interface up notification arrives: no-op
+        nat.interfaceLinkStateChanged(STACKED_IFACE, true);
+        mLooper.dispatchNext();
+
+
+        // Interface removed notification arrives after stopClatd() takes effect: no-op.
+        nat.interfaceRemoved(STACKED_IFACE);
+        mLooper.dispatchNext();
+
+        assertIdle(nat);
+
+        verifyNoMoreInteractions(mNms, mConnectivity);
+    }
+
+    @Test
+    public void testStopAndClatdNeverStarts() throws Exception {
+        Nat464Xlat nat = makeNat464Xlat();
+
+        // ConnectivityService starts clat.
+        nat.start();
+
+        verify(mNms).registerObserver(eq(nat));
+        verify(mNms).startClatd(eq(BASE_IFACE));
+
+        // ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...)
+        nat.stop();
+
+        verify(mNms).unregisterObserver(eq(nat));
+        verify(mNms).stopClatd(eq(BASE_IFACE));
+        assertIdle(nat);
+
+        verifyNoMoreInteractions(mNms, mConnectivity);
+    }
+
+    static void assertIdle(Nat464Xlat nat) {
+        assertTrue("Nat464Xlat was not IDLE", !nat.isStarted());
+    }
+
+    static void assertRunning(Nat464Xlat nat) {
+        assertTrue("Nat464Xlat was not RUNNING", nat.isRunning());
+    }
+}
diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
index f98ab3d..67805c9 100644
--- a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
@@ -19,6 +19,7 @@
 import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
 import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.mock;
@@ -37,9 +38,11 @@
 import android.system.OsConstants;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Base64;
+
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.DNSLookupBatch;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog;
+
 import java.io.FileOutputStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -47,6 +50,7 @@
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -57,7 +61,10 @@
     private static final String EXAMPLE_IPV4 = "192.0.2.1";
     private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1";
 
-    NetdEventListenerService mNetdEventListenerService;
+    private static final byte[] MAC_ADDR =
+            {(byte)0x84, (byte)0xc9, (byte)0xb2, (byte)0x6a, (byte)0xed, (byte)0x4b};
+
+    NetdEventListenerService mService;
     ConnectivityManager mCm;
 
     @Before
@@ -71,7 +78,192 @@
         when(mCm.getNetworkCapabilities(new Network(100))).thenReturn(ncWifi);
         when(mCm.getNetworkCapabilities(new Network(101))).thenReturn(ncCell);
 
-        mNetdEventListenerService = new NetdEventListenerService(mCm);
+        mService = new NetdEventListenerService(mCm);
+    }
+
+    @Test
+    public void testWakeupEventLogging() throws Exception {
+        final int BUFFER_LENGTH = NetdEventListenerService.WAKEUP_EVENT_BUFFER_LENGTH;
+        final long now = System.currentTimeMillis();
+        final String iface = "wlan0";
+        final byte[] mac = MAC_ADDR;
+        final String srcIp = "192.168.2.1";
+        final String dstIp = "192.168.2.23";
+        final String srcIp6 = "2001:db8:4:fd00:a585:13d1:6a23:4fb4";
+        final String dstIp6 = "2001:db8:4006:807::200a";
+        final int sport = 2356;
+        final int dport = 13489;
+
+        final int v4 = 0x800;
+        final int v6 = 0x86dd;
+        final int tcp = 6;
+        final int udp = 17;
+        final int icmp6 = 58;
+
+        // Baseline without any event
+        String[] baseline = listNetdEvent();
+
+        int[] uids = {10001, 10002, 10004, 1000, 10052, 10023, 10002, 10123, 10004};
+        wakeupEvent(iface, uids[0], v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent(iface, uids[1], v6, udp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent(iface, uids[2], v6, udp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent(iface, uids[3], v4, icmp6, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent(iface, uids[4], v6, tcp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent(iface, uids[5], v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent(iface, uids[6], v6, udp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent(iface, uids[7], v6, tcp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent(iface, uids[8], v6, udp, mac, srcIp6, dstIp6, sport, dport, now);
+
+        String[] events2 = remove(listNetdEvent(), baseline);
+        int expectedLength2 = uids.length + 1; // +1 for the WakeupStats line
+        assertEquals(expectedLength2, events2.length);
+        assertContains(events2[0], "WakeupStats");
+        assertContains(events2[0], "wlan0");
+        assertContains(events2[0], "0x800");
+        assertContains(events2[0], "0x86dd");
+        for (int i = 0; i < uids.length; i++) {
+            String got = events2[i+1];
+            assertContains(got, "WakeupEvent");
+            assertContains(got, "wlan0");
+            assertContains(got, "uid: " + uids[i]);
+        }
+
+        int uid = 20000;
+        for (int i = 0; i < BUFFER_LENGTH * 2; i++) {
+            long ts = now + 10;
+            wakeupEvent(iface, uid, 0x800, 6, mac, srcIp, dstIp, 23, 24, ts);
+        }
+
+        String[] events3 = remove(listNetdEvent(), baseline);
+        int expectedLength3 = BUFFER_LENGTH + 1; // +1 for the WakeupStats line
+        assertEquals(expectedLength3, events3.length);
+        assertContains(events2[0], "WakeupStats");
+        assertContains(events2[0], "wlan0");
+        for (int i = 1; i < expectedLength3; i++) {
+            String got = events3[i];
+            assertContains(got, "WakeupEvent");
+            assertContains(got, "wlan0");
+            assertContains(got, "uid: " + uid);
+        }
+
+        uid = 45678;
+        wakeupEvent(iface, uid, 0x800, 6, mac, srcIp, dstIp, 23, 24, now);
+
+        String[] events4 = remove(listNetdEvent(), baseline);
+        String lastEvent = events4[events4.length - 1];
+        assertContains(lastEvent, "WakeupEvent");
+        assertContains(lastEvent, "wlan0");
+        assertContains(lastEvent, "uid: " + uid);
+    }
+
+    @Test
+    public void testWakeupStatsLogging() throws Exception {
+        final byte[] mac = MAC_ADDR;
+        final String srcIp = "192.168.2.1";
+        final String dstIp = "192.168.2.23";
+        final String srcIp6 = "2401:fa00:4:fd00:a585:13d1:6a23:4fb4";
+        final String dstIp6 = "2404:6800:4006:807::200a";
+        final int sport = 2356;
+        final int dport = 13489;
+        final long now = 1001L;
+
+        final int v4 = 0x800;
+        final int v6 = 0x86dd;
+        final int tcp = 6;
+        final int udp = 17;
+        final int icmp6 = 58;
+
+        wakeupEvent("wlan0", 1000, v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("rmnet0", 10123, v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("wlan0", 1000, v4, udp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("rmnet0", 10008, v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("wlan0", -1, v6, icmp6, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent("wlan0", 10008, v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("rmnet0", 1000, v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("wlan0", 10004, v4, udp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("wlan0", 1000, v6, tcp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent("wlan0", 0, v6, udp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent("wlan0", -1, v6, icmp6, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent("rmnet0", 10052, v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("wlan0", 0, v6, udp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent("rmnet0", 1000, v6, tcp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent("wlan0", 1010, v4, udp, mac, srcIp, dstIp, sport, dport, now);
+
+        String got = flushStatistics();
+        String want = String.join("\n",
+                "dropped_events: 0",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 2",
+                "  network_id: 0",
+                "  time_ms: 0",
+                "  transports: 0",
+                "  wakeup_stats <",
+                "    application_wakeups: 3",
+                "    duration_sec: 0",
+                "    ethertype_counts <",
+                "      key: 2048",
+                "      value: 4",
+                "    >",
+                "    ethertype_counts <",
+                "      key: 34525",
+                "      value: 1",
+                "    >",
+                "    ip_next_header_counts <",
+                "      key: 6",
+                "      value: 5",
+                "    >",
+                "    l2_broadcast_count: 0",
+                "    l2_multicast_count: 0",
+                "    l2_unicast_count: 5",
+                "    no_uid_wakeups: 0",
+                "    non_application_wakeups: 0",
+                "    root_wakeups: 0",
+                "    system_wakeups: 2",
+                "    total_wakeups: 5",
+                "  >",
+                ">",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 4",
+                "  network_id: 0",
+                "  time_ms: 0",
+                "  transports: 0",
+                "  wakeup_stats <",
+                "    application_wakeups: 2",
+                "    duration_sec: 0",
+                "    ethertype_counts <",
+                "      key: 2048",
+                "      value: 5",
+                "    >",
+                "    ethertype_counts <",
+                "      key: 34525",
+                "      value: 5",
+                "    >",
+                "    ip_next_header_counts <",
+                "      key: 6",
+                "      value: 3",
+                "    >",
+                "    ip_next_header_counts <",
+                "      key: 17",
+                "      value: 5",
+                "    >",
+                "    ip_next_header_counts <",
+                "      key: 58",
+                "      value: 2",
+                "    >",
+                "    l2_broadcast_count: 0",
+                "    l2_multicast_count: 0",
+                "    l2_unicast_count: 10",
+                "    no_uid_wakeups: 2",
+                "    non_application_wakeups: 1",
+                "    root_wakeups: 2",
+                "    system_wakeups: 3",
+                "    total_wakeups: 10",
+                "  >",
+                ">",
+                "version: 2\n");
+        assertEquals(want, got);
     }
 
     @Test
@@ -111,6 +303,10 @@
                 "    event_types: 1",
                 "    event_types: 2",
                 "    event_types: 2",
+                "    getaddrinfo_error_count: 0",
+                "    getaddrinfo_query_count: 0",
+                "    gethostbyname_error_count: 0",
+                "    gethostbyname_query_count: 0",
                 "    latencies_ms: 3456",
                 "    latencies_ms: 267",
                 "    latencies_ms: 1230",
@@ -142,6 +338,10 @@
                 "    event_types: 2",
                 "    event_types: 1",
                 "    event_types: 1",
+                "    getaddrinfo_error_count: 0",
+                "    getaddrinfo_query_count: 0",
+                "    gethostbyname_error_count: 0",
+                "    gethostbyname_query_count: 0",
                 "    latencies_ms: 56",
                 "    latencies_ms: 78",
                 "    latencies_ms: 14",
@@ -278,7 +478,7 @@
     Thread connectEventAction(int netId, int error, int latencyMs, String ipAddr) {
         return new Thread(() -> {
             try {
-                mNetdEventListenerService.onConnectEvent(netId, error, latencyMs, ipAddr, 80, 1);
+                mService.onConnectEvent(netId, error, latencyMs, ipAddr, 80, 1);
             } catch (Exception e) {
                 fail(e.toString());
             }
@@ -286,7 +486,13 @@
     }
 
     void dnsEvent(int netId, int type, int result, int latency) throws Exception {
-        mNetdEventListenerService.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
+        mService.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
+    }
+
+    void wakeupEvent(String iface, int uid, int ether, int ip, byte[] mac, String srcIp,
+            String dstIp, int sport, int dport, long now) throws Exception {
+        String prefix = NetdEventListenerService.WAKEUP_EVENT_IFACE_PREFIX + iface;
+        mService.onWakeupEvent(prefix, uid, ether, ip, mac, srcIp, dstIp, sport, dport, now);
     }
 
     void asyncDump(long durationMs) throws Exception {
@@ -294,7 +500,7 @@
         final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null"));
         new Thread(() -> {
             while (System.currentTimeMillis() < stop) {
-                mNetdEventListenerService.dump(pw);
+                mService.list(pw);
             }
         }).start();
     }
@@ -303,7 +509,7 @@
     String flushStatistics() throws Exception {
         IpConnectivityMetrics metricsService =
                 new IpConnectivityMetrics(mock(Context.class), (ctx) -> 2000);
-        metricsService.mNetdListener = mNetdEventListenerService;
+        metricsService.mNetdListener = mService;
 
         StringWriter buffer = new StringWriter();
         PrintWriter writer = new PrintWriter(buffer);
@@ -321,4 +527,27 @@
         }
         return log.toString();
     }
+
+    String[] listNetdEvent() throws Exception {
+        StringWriter buffer = new StringWriter();
+        PrintWriter writer = new PrintWriter(buffer);
+        mService.list(writer);
+        return buffer.toString().split("\\n");
+    }
+
+    static void assertContains(String got, String want) {
+        assertTrue(got + " did not contain \"" + want + "\"", got.contains(want));
+    }
+
+    static <T> T[] remove(T[] array, T[] filtered) {
+        List<T> c = Arrays.asList(filtered);
+        int next = 0;
+        for (int i = 0; i < array.length; i++) {
+            if (c.contains(array[i])) {
+                continue;
+            }
+            array[next++] = array[i];
+        }
+        return Arrays.copyOf(array, next);
+    }
 }
diff --git a/tests/net/java/com/android/server/connectivity/NetworkMonitorTest.java b/tests/net/java/com/android/server/connectivity/NetworkMonitorTest.java
new file mode 100644
index 0000000..27a897d
--- /dev/null
+++ b/tests/net/java/com/android/server/connectivity/NetworkMonitorTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.Network;
+import android.net.NetworkRequest;
+import android.net.metrics.IpConnectivityLog;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.TelephonyManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NetworkMonitorTest {
+
+    static final int TEST_ID = 60; // should be less than min netid 100
+
+    @Mock Context mContext;
+    @Mock Handler mHandler;
+    @Mock IpConnectivityLog mLogger;
+    @Mock NetworkAgentInfo mAgent;
+    @Mock NetworkMonitor.NetworkMonitorSettings mSettings;
+    @Mock NetworkRequest mRequest;
+    @Mock TelephonyManager mTelephony;
+    @Mock WifiManager mWifi;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        when(mAgent.network()).thenReturn(new Network(TEST_ID));
+        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephony);
+        when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifi);
+    }
+
+    NetworkMonitor makeMonitor() {
+        return new NetworkMonitor(mContext, mHandler, mAgent, mRequest, mLogger, mSettings);
+    }
+
+    @Test
+    public void testCreatingNetworkMonitor() {
+        NetworkMonitor monitor = makeMonitor();
+    }
+}
+
diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index 911347c..125fe725 100644
--- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -34,20 +34,29 @@
 import android.content.res.Resources;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
 import android.telephony.TelephonyManager;
-import android.test.suitebuilder.annotation.SmallTest;
+
 import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import junit.framework.TestCase;
+
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
-public class NetworkNotificationManagerTest extends TestCase {
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NetworkNotificationManagerTest {
 
     static final NetworkCapabilities CELL_CAPABILITIES = new NetworkCapabilities();
     static final NetworkCapabilities WIFI_CAPABILITIES = new NetworkCapabilities();
@@ -71,6 +80,7 @@
 
     NetworkNotificationManager mManager;
 
+    @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mCaptor = ArgumentCaptor.forClass(Notification.class);
@@ -87,7 +97,7 @@
         mManager = new NetworkNotificationManager(mCtx, mTelephonyManager, mNotificationManager);
     }
 
-    @SmallTest
+    @Test
     public void testNotificationsShownAndCleared() {
         final int NETWORK_ID_BASE = 100;
         List<NotificationType> types = Arrays.asList(NotificationType.values());
@@ -117,7 +127,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testNoInternetNotificationsNotShownForCellular() {
         mManager.showNotification(100, NO_INTERNET, mCellNai, mWifiNai, null, false);
         mManager.showNotification(101, LOST_INTERNET, mCellNai, mWifiNai, null, false);
@@ -131,7 +141,7 @@
         verify(mNotificationManager, times(1)).notifyAsUser(eq(tag), eq(eventId), any(), any());
     }
 
-    @SmallTest
+    @Test
     public void testNotificationsNotShownIfNoInternetCapability() {
         mWifiNai.networkCapabilities = new NetworkCapabilities();
         mWifiNai.networkCapabilities .addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
@@ -142,7 +152,7 @@
         verify(mNotificationManager, never()).notifyAsUser(any(), anyInt(), any(), any());
     }
 
-    @SmallTest
+    @Test
     public void testDuplicatedNotificationsNoInternetThenSignIn() {
         final int id = 101;
         final String tag = NetworkNotificationManager.tagFor(id);
@@ -164,7 +174,7 @@
         verify(mNotificationManager, times(1)).cancelAsUser(eq(tag), eq(SIGN_IN.eventId), any());
     }
 
-    @SmallTest
+    @Test
     public void testDuplicatedNotificationsSignInThenNoInternet() {
         final int id = 101;
         final String tag = NetworkNotificationManager.tagFor(id);
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index 212f477..a115146 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -40,7 +40,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.mock;
 
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -60,14 +59,12 @@
 import android.net.util.SharedLog;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.INetworkManagementService;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.test.TestLooper;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.provider.Settings;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -279,6 +276,31 @@
         mIntents.remove(bcast);
     }
 
+    public void failingLocalOnlyHotspotLegacyApBroadcast(
+            boolean emulateInterfaceStatusChanged) throws Exception {
+        when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
+
+        // Emulate externally-visible WifiManager effects, causing the
+        // per-interface state machine to start up, and telling us that
+        // hotspot mode is to be started.
+        if (emulateInterfaceStatusChanged) {
+            mTethering.interfaceStatusChanged(mTestIfname, true);
+        }
+        sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
+        mLooper.dispatchAll();
+
+        // If, and only if, Tethering received an interface status changed
+        // then it creates a TetherInterfaceStateMachine and sends out a
+        // broadcast indicating that the interface is "available".
+        if (emulateInterfaceStatusChanged) {
+            verify(mConnectivityManager, atLeastOnce()).isTetheringSupported();
+            verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
+        }
+        verifyNoMoreInteractions(mConnectivityManager);
+        verifyNoMoreInteractions(mNMService);
+        verifyNoMoreInteractions(mWifiManager);
+    }
+
     @Test
     public void testUsbConfiguredBroadcastStartsTethering() throws Exception {
         when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
@@ -305,31 +327,6 @@
         verify(mNMService, times(1)).listInterfaces();
     }
 
-    public void failingLocalOnlyHotspotLegacyApBroadcast(
-            boolean emulateInterfaceStatusChanged) throws Exception {
-        when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
-
-        // Emulate externally-visible WifiManager effects, causing the
-        // per-interface state machine to start up, and telling us that
-        // hotspot mode is to be started.
-        if (emulateInterfaceStatusChanged) {
-            mTethering.interfaceStatusChanged(mTestIfname, true);
-        }
-        sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
-        mLooper.dispatchAll();
-
-        // If, and only if, Tethering received an interface status changed
-        // then it creates a TetherInterfaceStateMachine and sends out a
-        // broadcast indicating that the interface is "available".
-        if (emulateInterfaceStatusChanged) {
-            verify(mConnectivityManager, atLeastOnce()).isTetheringSupported();
-            verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
-        }
-        verifyNoMoreInteractions(mConnectivityManager);
-        verifyNoMoreInteractions(mNMService);
-        verifyNoMoreInteractions(mWifiManager);
-    }
-
     @Test
     public void failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged() throws Exception {
         failingLocalOnlyHotspotLegacyApBroadcast(true);
@@ -410,7 +407,7 @@
         when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
 
         // Emulate pressing the WiFi tethering button.
-        mTethering.startTethering(ConnectivityManager.TETHERING_WIFI, null, false);
+        mTethering.startTethering(TETHERING_WIFI, null, false);
         mLooper.dispatchAll();
         verify(mWifiManager, times(1)).startSoftAp(null);
         verifyNoMoreInteractions(mWifiManager);
@@ -561,90 +558,6 @@
         verifyNoMoreInteractions(mNMService);
     }
 
-    private void userRestrictionsListenerBehaviour(
-        boolean currentDisallow, boolean nextDisallow, String[] activeTetheringIfacesList,
-        int expectedInteractionsWithShowNotification) throws  Exception {
-        final int userId = 0;
-        final Bundle currRestrictions = new Bundle();
-        final Bundle newRestrictions = new Bundle();
-        Tethering tethering = mock(Tethering.class);
-        Tethering.TetheringUserRestrictionListener turl =
-                new Tethering.TetheringUserRestrictionListener(tethering);
-
-        currRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, currentDisallow);
-        newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
-        when(tethering.getTetheredIfaces()).thenReturn(activeTetheringIfacesList);
-
-        turl.onUserRestrictionsChanged(userId, newRestrictions, currRestrictions);
-
-        verify(tethering, times(expectedInteractionsWithShowNotification))
-                .showTetheredNotification(anyInt(), eq(false));
-
-        verify(tethering, times(expectedInteractionsWithShowNotification)).untetherAll();
-    }
-
-    @Test
-    public void testDisallowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
-        final String[] emptyActiveIfacesList = new String[]{};
-        final boolean currDisallow = false;
-        final boolean nextDisallow = true;
-        final int expectedInteractionsWithShowNotification = 0;
-
-        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, emptyActiveIfacesList,
-                expectedInteractionsWithShowNotification);
-    }
-
-    @Test
-    public void testDisallowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
-        final String[] nonEmptyActiveIfacesList = new String[]{mTestIfname};
-        final boolean currDisallow = false;
-        final boolean nextDisallow = true;
-        final int expectedInteractionsWithShowNotification = 1;
-
-        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
-                expectedInteractionsWithShowNotification);
-    }
-
-    @Test
-    public void testAllowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
-        final String[] nonEmptyActiveIfacesList = new String[]{};
-        final boolean currDisallow = true;
-        final boolean nextDisallow = false;
-        final int expectedInteractionsWithShowNotification = 0;
-
-        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
-                expectedInteractionsWithShowNotification);
-    }
-
-    @Test
-    public void testAllowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
-        final String[] nonEmptyActiveIfacesList = new String[]{mTestIfname};
-        final boolean currDisallow = true;
-        final boolean nextDisallow = false;
-        final int expectedInteractionsWithShowNotification = 0;
-
-        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
-                expectedInteractionsWithShowNotification);
-    }
-
-    @Test
-    public void testDisallowTetheringUnchanged() throws Exception {
-        final String[] nonEmptyActiveIfacesList = new String[]{mTestIfname};
-        final int expectedInteractionsWithShowNotification = 0;
-        boolean currDisallow = true;
-        boolean nextDisallow = true;
-
-        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
-                expectedInteractionsWithShowNotification);
-
-        currDisallow = false;
-        nextDisallow = false;
-
-        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
-                expectedInteractionsWithShowNotification);
-    }
-
-
     // TODO: Test that a request for hotspot mode doesn't interfere with an
     // already operating tethering mode interface.
 }
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index 506d9e5..c29363c 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -20,49 +20,86 @@
 import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
 import static android.content.pm.UserInfo.FLAG_PRIMARY;
 import static android.content.pm.UserInfo.FLAG_RESTRICTED;
-import static org.mockito.AdditionalMatchers.*;
-import static org.mockito.Mockito.*;
+import static android.net.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_VPN;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.AdditionalMatchers.aryEq;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.annotation.UserIdInt;
 import android.app.AppOpsManager;
 import android.app.NotificationManager;
 import android.content.Context;
-import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
 import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.net.NetworkInfo.DetailedState;
 import android.net.UidRange;
-import android.os.Build;
+import android.net.VpnService;
+import android.os.Build.VERSION_CODES;
+import android.os.Bundle;
 import android.os.INetworkManagementService;
 import android.os.Looper;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
+import com.android.internal.R;
 import com.android.internal.net.VpnConfig;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
-
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.mockito.Answers;
-import org.mockito.ArgumentCaptor;
 import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+
 /**
  * Tests for {@link Vpn}.
  *
  * Build, install and run with:
- *  runtest --path src/com/android/server/connectivity/VpnTest.java
+ *  runtest frameworks-net -c com.android.server.connectivity.VpnTest
  */
-public class VpnTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class VpnTest {
     private static final String TAG = "VpnTest";
 
     // Mock users
@@ -100,8 +137,9 @@
     @Mock private AppOpsManager mAppOps;
     @Mock private NotificationManager mNotificationManager;
     @Mock private Vpn.SystemServices mSystemServices;
+    @Mock private ConnectivityManager mConnectivityManager;
 
-    @Override
+    @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
 
@@ -113,16 +151,21 @@
         when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))).thenReturn(mAppOps);
         when(mContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
                 .thenReturn(mNotificationManager);
+        when(mContext.getSystemService(eq(Context.CONNECTIVITY_SERVICE)))
+                .thenReturn(mConnectivityManager);
+        when(mContext.getString(R.string.config_customVpnAlwaysOnDisconnectedDialogComponent))
+                .thenReturn(Resources.getSystem().getString(
+                        R.string.config_customVpnAlwaysOnDisconnectedDialogComponent));
 
         // Used by {@link Notification.Builder}
         ApplicationInfo applicationInfo = new ApplicationInfo();
-        applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+        applicationInfo.targetSdkVersion = VERSION_CODES.CUR_DEVELOPMENT;
         when(mContext.getApplicationInfo()).thenReturn(applicationInfo);
 
         doNothing().when(mNetService).registerObserver(any());
     }
 
-    @SmallTest
+    @Test
     public void testRestrictedProfilesAreAddedToVpn() {
         setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB);
 
@@ -136,7 +179,7 @@
         })), ranges);
     }
 
-    @SmallTest
+    @Test
     public void testManagedProfilesAreNotAddedToVpn() {
         setMockedUsers(primaryUser, managedProfileA);
 
@@ -149,7 +192,7 @@
         })), ranges);
     }
 
-    @SmallTest
+    @Test
     public void testAddUserToVpnOnlyAddsOneUser() {
         setMockedUsers(primaryUser, restrictedProfileA, managedProfileA);
 
@@ -162,7 +205,7 @@
         })), ranges);
     }
 
-    @SmallTest
+    @Test
     public void testUidWhiteAndBlacklist() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
         final UidRange user = UidRange.createForUser(primaryUser.id);
@@ -187,7 +230,7 @@
         })), disallow);
     }
 
-    @SmallTest
+    @Test
     public void testLockdownChangingPackage() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
         final UidRange user = UidRange.createForUser(primaryUser.id);
@@ -222,7 +265,7 @@
         assertUnblocked(vpn, user.start + PKG_UIDS[3]);
     }
 
-    @SmallTest
+    @Test
     public void testLockdownAddingAProfile() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
         setMockedUsers(primaryUser);
@@ -262,7 +305,7 @@
         }));
     }
 
-    @SmallTest
+    @Test
     public void testLockdownRuleRepeatability() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
 
@@ -285,7 +328,7 @@
         verify(mNetService, times(2)).setAllowOnlyVpnForUids(anyBoolean(), any(UidRange[].class));
     }
 
-    @SmallTest
+    @Test
     public void testLockdownRuleReversibility() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
 
@@ -314,7 +357,41 @@
         order.verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(entireUser));
     }
 
-    @SmallTest
+    @Test
+    public void testIsAlwaysOnPackageSupported() throws Exception {
+        final Vpn vpn = createVpn(primaryUser.id);
+
+        ApplicationInfo appInfo = new ApplicationInfo();
+        when(mPackageManager.getApplicationInfoAsUser(eq(PKGS[0]), anyInt(), eq(primaryUser.id)))
+                .thenReturn(appInfo);
+
+        ServiceInfo svcInfo = new ServiceInfo();
+        ResolveInfo resInfo = new ResolveInfo();
+        resInfo.serviceInfo = svcInfo;
+        when(mPackageManager.queryIntentServicesAsUser(any(), eq(PackageManager.GET_META_DATA),
+                eq(primaryUser.id)))
+                .thenReturn(Collections.singletonList(resInfo));
+
+        // null package name should return false
+        assertFalse(vpn.isAlwaysOnPackageSupported(null));
+
+        // Pre-N apps are not supported
+        appInfo.targetSdkVersion = VERSION_CODES.M;
+        assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0]));
+
+        // N+ apps are supported by default
+        appInfo.targetSdkVersion = VERSION_CODES.N;
+        assertTrue(vpn.isAlwaysOnPackageSupported(PKGS[0]));
+
+        // Apps that opt out explicitly are not supported
+        appInfo.targetSdkVersion = VERSION_CODES.CUR_DEVELOPMENT;
+        Bundle metaData = new Bundle();
+        metaData.putBoolean(VpnService.SERVICE_META_DATA_SUPPORTS_ALWAYS_ON, false);
+        svcInfo.metaData = metaData;
+        assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0]));
+    }
+
+    @Test
     public void testNotificationShownForAlwaysOnApp() {
         final UserHandle userHandle = UserHandle.of(primaryUser.id);
         final Vpn vpn = createVpn(primaryUser.id);
@@ -346,6 +423,66 @@
         order.verify(mNotificationManager).cancelAsUser(anyString(), anyInt(), eq(userHandle));
     }
 
+    @Test
+    public void testCapabilities() {
+        final Vpn vpn = createVpn(primaryUser.id);
+        setMockedUsers(primaryUser);
+
+        final Network mobile = new Network(1);
+        final Network wifi = new Network(2);
+
+        final Map<Network, NetworkCapabilities> networks = new HashMap<>();
+        networks.put(mobile, new NetworkCapabilities()
+                .addTransportType(TRANSPORT_CELLULAR)
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .addCapability(NET_CAPABILITY_NOT_METERED)
+                .setLinkDownstreamBandwidthKbps(10));
+        networks.put(wifi, new NetworkCapabilities()
+                .addTransportType(TRANSPORT_WIFI)
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .addCapability(NET_CAPABILITY_NOT_ROAMING)
+                .setLinkUpstreamBandwidthKbps(20));
+        setMockedNetworks(networks);
+
+        final NetworkCapabilities caps = new NetworkCapabilities();
+
+        Vpn.updateCapabilities(mConnectivityManager, new Network[] { }, caps);
+        assertTrue(caps.hasTransport(TRANSPORT_VPN));
+        assertFalse(caps.hasTransport(TRANSPORT_CELLULAR));
+        assertFalse(caps.hasTransport(TRANSPORT_WIFI));
+        assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkDownstreamBandwidthKbps());
+        assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkUpstreamBandwidthKbps());
+        assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
+        assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
+
+        Vpn.updateCapabilities(mConnectivityManager, new Network[] { mobile }, caps);
+        assertTrue(caps.hasTransport(TRANSPORT_VPN));
+        assertTrue(caps.hasTransport(TRANSPORT_CELLULAR));
+        assertFalse(caps.hasTransport(TRANSPORT_WIFI));
+        assertEquals(10, caps.getLinkDownstreamBandwidthKbps());
+        assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkUpstreamBandwidthKbps());
+        assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
+        assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
+
+        Vpn.updateCapabilities(mConnectivityManager, new Network[] { wifi }, caps);
+        assertTrue(caps.hasTransport(TRANSPORT_VPN));
+        assertFalse(caps.hasTransport(TRANSPORT_CELLULAR));
+        assertTrue(caps.hasTransport(TRANSPORT_WIFI));
+        assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkDownstreamBandwidthKbps());
+        assertEquals(20, caps.getLinkUpstreamBandwidthKbps());
+        assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
+        assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
+
+        Vpn.updateCapabilities(mConnectivityManager, new Network[] { mobile, wifi }, caps);
+        assertTrue(caps.hasTransport(TRANSPORT_VPN));
+        assertTrue(caps.hasTransport(TRANSPORT_CELLULAR));
+        assertTrue(caps.hasTransport(TRANSPORT_WIFI));
+        assertEquals(10, caps.getLinkDownstreamBandwidthKbps());
+        assertEquals(20, caps.getLinkUpstreamBandwidthKbps());
+        assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
+        assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
+    }
+
     /**
      * Mock some methods of vpn object.
      */
@@ -412,4 +549,11 @@
         } catch (Exception e) {
         }
     }
+
+    private void setMockedNetworks(final Map<Network, NetworkCapabilities> networks) {
+        doAnswer(invocation -> {
+            final Network network = (Network) invocation.getArguments()[0];
+            return networks.get(network);
+        }).when(mConnectivityManager).getNetworkCapabilities(any());
+    }
 }
diff --git a/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java b/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java
index 679c369..b98f63b 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java
@@ -32,12 +32,13 @@
 import static org.mockito.Matchers.anyObject;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -108,13 +109,11 @@
         mContentResolver = new MockContentResolver(mContext);
         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
-        // TODO: call this when available.
-        // FakeSettingsProvider.clearSettingsProvider();
+        FakeSettingsProvider.clearSettingsProvider();
     }
 
     @After public void tearDown() throws Exception {
-        // TODO: call this when available.
-        // FakeSettingsProvider.clearSettingsProvider();
+        FakeSettingsProvider.clearSettingsProvider();
     }
 
     private void setupFunctioningHardwareInterface() {
@@ -144,8 +143,7 @@
         return offload;
     }
 
-    // TODO: Restore when FakeSettingsProvider.clearSettingsProvider() is available.
-    // @Test
+    @Test
     public void testNoSettingsValueDefaultDisabledDoesNotStart() throws Exception {
         setupFunctioningHardwareInterface();
         when(mHardware.getDefaultTetherOffloadDisabled()).thenReturn(1);
@@ -165,8 +163,7 @@
         inOrder.verifyNoMoreInteractions();
     }
 
-    // TODO: Restore when FakeSettingsProvider.clearSettingsProvider() is available.
-    // @Test
+    @Test
     public void testNoSettingsValueDefaultEnabledDoesStart() throws Exception {
         setupFunctioningHardwareInterface();
         when(mHardware.getDefaultTetherOffloadDisabled()).thenReturn(0);
@@ -440,6 +437,9 @@
         ethernetStats.txBytes = 100000;
         when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(ethernetStats);
         offload.setUpstreamLinkProperties(null);
+        // Expect that we first clear the HAL's upstream parameters.
+        inOrder.verify(mHardware, times(1)).setUpstreamParameters(
+                eq(""), eq("0.0.0.0"), eq("0.0.0.0"), eq(null));
         // Expect that we fetch stats from the previous upstream.
         inOrder.verify(mHardware, times(1)).getForwardedStats(eq(ethernetIface));
 
@@ -448,9 +448,7 @@
         NetworkStats perUidStats = provider.getTetherStats(STATS_PER_UID);
         waitForIdle();
         // There is no current upstream, so no stats are fetched.
-        inOrder.verify(mHardware, never()).getForwardedStats(eq(ethernetIface));
-        inOrder.verify(mHardware, times(1)).setUpstreamParameters(
-                eq(null), eq(null), eq(null), eq(null));
+        inOrder.verify(mHardware, never()).getForwardedStats(any());
         inOrder.verifyNoMoreInteractions();
 
         assertEquals(2, stats.size());
@@ -625,9 +623,116 @@
         inOrder.verifyNoMoreInteractions();
     }
 
+    @Test
+    public void testControlCallbackOnStoppedUnsupportedFetchesAllStats() throws Exception {
+        setupFunctioningHardwareInterface();
+        enableOffload();
+
+        final OffloadController offload = makeOffloadController();
+        offload.start();
+
+        // Pretend to set a few different upstreams (only the interface name
+        // matters for this test; we're ignoring IP and route information).
+        final LinkProperties upstreamLp = new LinkProperties();
+        for (String ifname : new String[]{RMNET0, WLAN0, RMNET0}) {
+            upstreamLp.setInterfaceName(ifname);
+            offload.setUpstreamLinkProperties(upstreamLp);
+        }
+
+        // Clear invocation history, especially the getForwardedStats() calls
+        // that happen with setUpstreamParameters().
+        clearInvocations(mHardware);
+
+        OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
+        callback.onStoppedUnsupported();
+
+        // Verify forwarded stats behaviour.
+        verify(mHardware, times(1)).getForwardedStats(eq(RMNET0));
+        verify(mHardware, times(1)).getForwardedStats(eq(WLAN0));
+        verifyNoMoreInteractions(mHardware);
+        verify(mNMService, times(1)).tetherLimitReached(mTetherStatsProviderCaptor.getValue());
+        verifyNoMoreInteractions(mNMService);
+    }
+
+    @Test
+    public void testControlCallbackOnSupportAvailableFetchesAllStatsAndPushesAllParameters()
+            throws Exception {
+        setupFunctioningHardwareInterface();
+        enableOffload();
+
+        final OffloadController offload = makeOffloadController();
+        offload.start();
+
+        // Pretend to set a few different upstreams (only the interface name
+        // matters for this test; we're ignoring IP and route information).
+        final LinkProperties upstreamLp = new LinkProperties();
+        for (String ifname : new String[]{RMNET0, WLAN0, RMNET0}) {
+            upstreamLp.setInterfaceName(ifname);
+            offload.setUpstreamLinkProperties(upstreamLp);
+        }
+
+        // Pretend that some local prefixes and downstreams have been added
+        // (and removed, for good measure).
+        final Set<IpPrefix> minimumLocalPrefixes = new HashSet<>();
+        for (String s : new String[]{
+                "127.0.0.0/8", "192.0.2.0/24", "fe80::/64", "2001:db8::/64"}) {
+            minimumLocalPrefixes.add(new IpPrefix(s));
+        }
+        offload.setLocalPrefixes(minimumLocalPrefixes);
+
+        final LinkProperties usbLinkProperties = new LinkProperties();
+        usbLinkProperties.setInterfaceName(RNDIS0);
+        usbLinkProperties.addLinkAddress(new LinkAddress("192.168.42.1/24"));
+        usbLinkProperties.addRoute(new RouteInfo(new IpPrefix(USB_PREFIX)));
+        offload.notifyDownstreamLinkProperties(usbLinkProperties);
+
+        final LinkProperties wifiLinkProperties = new LinkProperties();
+        wifiLinkProperties.setInterfaceName(WLAN0);
+        wifiLinkProperties.addLinkAddress(new LinkAddress("192.168.43.1/24"));
+        wifiLinkProperties.addRoute(new RouteInfo(new IpPrefix(WIFI_PREFIX)));
+        wifiLinkProperties.addRoute(new RouteInfo(new IpPrefix(IPV6_LINKLOCAL)));
+        // Use a benchmark prefix (RFC 5180 + erratum), since the documentation
+        // prefix is included in the excluded prefix list.
+        wifiLinkProperties.addLinkAddress(new LinkAddress("2001:2::1/64"));
+        wifiLinkProperties.addLinkAddress(new LinkAddress("2001:2::2/64"));
+        wifiLinkProperties.addRoute(new RouteInfo(new IpPrefix("2001:2::/64")));
+        offload.notifyDownstreamLinkProperties(wifiLinkProperties);
+
+        offload.removeDownstreamInterface(RNDIS0);
+
+        // Clear invocation history, especially the getForwardedStats() calls
+        // that happen with setUpstreamParameters().
+        clearInvocations(mHardware);
+
+        OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
+        callback.onSupportAvailable();
+
+        // Verify forwarded stats behaviour.
+        verify(mHardware, times(1)).getForwardedStats(eq(RMNET0));
+        verify(mHardware, times(1)).getForwardedStats(eq(WLAN0));
+        verify(mNMService, times(1)).tetherLimitReached(mTetherStatsProviderCaptor.getValue());
+        verifyNoMoreInteractions(mNMService);
+
+        // TODO: verify local prefixes and downstreams are also pushed to the HAL.
+        verify(mHardware, times(1)).setLocalPrefixes(mStringArrayCaptor.capture());
+        ArrayList<String> localPrefixes = mStringArrayCaptor.getValue();
+        assertEquals(4, localPrefixes.size());
+        assertArrayListContains(localPrefixes,
+                // TODO: The logic to find and exclude downstream IP prefixes
+                // is currently in Tethering's OffloadWrapper but must be moved
+                // into OffloadController proper. After this, also check for:
+                //     "192.168.43.1/32", "2001:2::1/128", "2001:2::2/128"
+                "127.0.0.0/8", "192.0.2.0/24", "fe80::/64", "2001:db8::/64");
+        verify(mHardware, times(1)).addDownstreamPrefix(WLAN0, "192.168.43.0/24");
+        verify(mHardware, times(1)).addDownstreamPrefix(WLAN0, "2001:2::/64");
+        verify(mHardware, times(1)).setUpstreamParameters(eq(RMNET0), any(), any(), any());
+        verify(mHardware, times(1)).setDataLimit(eq(RMNET0), anyLong());
+        verifyNoMoreInteractions(mHardware);
+    }
+
     private static void assertArrayListContains(ArrayList<String> list, String... elems) {
         for (String element : elems) {
-            assertTrue(list.contains(element));
+            assertTrue(element + " not in list", list.contains(element));
         }
     }
 }
diff --git a/tests/net/java/com/android/server/connectivity/tethering/SimChangeListenerTest.java b/tests/net/java/com/android/server/connectivity/tethering/SimChangeListenerTest.java
index b5d333b..f58ea7e 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/SimChangeListenerTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/SimChangeListenerTest.java
@@ -48,8 +48,6 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class SimChangeListenerTest {
-    private static final int EVENT_UNM_UPDATE = 1;
-
     @Mock private Context mContext;
     private BroadcastInterceptingContext mServiceContext;
     private Handler mHandler;
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index fa99795..375b418 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -1169,9 +1169,8 @@
         final LinkProperties prop = new LinkProperties();
         prop.setInterfaceName(TEST_IFACE);
         final NetworkCapabilities capabilities = new NetworkCapabilities();
-        if (!isMetered) {
-            capabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
-        }
+        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !isMetered);
+        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
         return new NetworkState(info, prop, capabilities, null, null, TEST_SSID);
     }
 
@@ -1187,6 +1186,8 @@
         final LinkProperties prop = new LinkProperties();
         prop.setInterfaceName(TEST_IFACE);
         final NetworkCapabilities capabilities = new NetworkCapabilities();
+        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
+        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
         return new NetworkState(info, prop, capabilities, null, subscriberId, null);
     }
 
@@ -1196,6 +1197,8 @@
         final LinkProperties prop = new LinkProperties();
         prop.setInterfaceName(iface);
         final NetworkCapabilities capabilities = new NetworkCapabilities();
+        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
+        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
         return new NetworkState(info, prop, capabilities, null, null, null);
     }
 
diff --git a/tests/radio/Android.mk b/tests/radio/Android.mk
new file mode 100644
index 0000000..dc55d0b
--- /dev/null
+++ b/tests/radio/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := RadioTests
+
+LOCAL_MODULE_TAGS := tests
+# TODO(b/13282254): uncomment when b/13282254 is fixed
+# LOCAL_SDK_VERSION := current
+
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util android-support-test testng
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_DEX_PREOPT := false
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
diff --git a/tests/radio/AndroidManifest.xml b/tests/radio/AndroidManifest.xml
new file mode 100644
index 0000000..150edbf
--- /dev/null
+++ b/tests/radio/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.hardware.radio.tests">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.hardware.radio.tests"
+        android:label="Tests for broadcast radio API" >
+    </instrumentation>
+</manifest>
diff --git a/tests/radio/src/android/hardware/radio/tests/RadioTest.java b/tests/radio/src/android/hardware/radio/tests/RadioTest.java
new file mode 100644
index 0000000..47e104c
--- /dev/null
+++ b/tests/radio/src/android/hardware/radio/tests/RadioTest.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.radio.tests;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.radio.RadioManager;
+import android.hardware.radio.RadioTuner;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.testng.Assert.assertThrows;
+
+/**
+ * A test for broadcast radio API.
+ */
+@RunWith(AndroidJUnit4.class)
+public class RadioTest {
+    private static final String TAG = "RadioTest";
+
+    public final Context mContext = InstrumentationRegistry.getContext();
+
+    private final int kConfigCallbackTimeoutMs = 10000;
+    private final int kCancelTimeoutMs = 1000;
+    private final int kTuneCallbackTimeoutMs = 30000;
+
+    private RadioManager mRadioManager;
+    private RadioTuner mRadioTuner;
+    private RadioManager.ModuleProperties mModule;
+    private final List<RadioManager.ModuleProperties> mModules = new ArrayList<>();
+    @Mock private RadioTuner.Callback mCallback;
+
+    RadioManager.AmBandDescriptor mAmBandDescriptor;
+    RadioManager.FmBandDescriptor mFmBandDescriptor;
+
+    RadioManager.BandConfig mAmBandConfig;
+    RadioManager.BandConfig mFmBandConfig;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+        // check if radio is supported and skip the test if it's not
+        PackageManager packageManager = mContext.getPackageManager();
+        boolean isRadioSupported = packageManager.hasSystemFeature(PackageManager.FEATURE_RADIO);
+        assumeTrue(isRadioSupported);
+
+        mRadioManager = (RadioManager)mContext.getSystemService(Context.RADIO_SERVICE);
+        assertNotNull(mRadioManager);
+
+        int status = mRadioManager.listModules(mModules);
+        assertEquals(RadioManager.STATUS_OK, status);
+        assertFalse(mModules.isEmpty());
+    }
+
+    @After
+    public void tearDown() {
+        mRadioManager = null;
+        mModules.clear();
+        if (mRadioTuner != null) {
+            mRadioTuner.close();
+            mRadioTuner = null;
+        }
+        verifyNoMoreInteractions(mCallback);
+    }
+
+    private void openTuner() {
+        openTuner(true);
+    }
+
+    private void resetCallback() {
+        verifyNoMoreInteractions(mCallback);
+        Mockito.reset(mCallback);
+    }
+
+    private void openTuner(boolean withAudio) {
+        assertNull(mRadioTuner);
+
+        // find FM band and build its config
+        mModule = mModules.get(0);
+        for (RadioManager.BandDescriptor band : mModule.getBands()) {
+            if (band.getType() == RadioManager.BAND_AM) {
+                mAmBandDescriptor = (RadioManager.AmBandDescriptor)band;
+            }
+            if (band.getType() == RadioManager.BAND_FM) {
+                mFmBandDescriptor = (RadioManager.FmBandDescriptor)band;
+            }
+        }
+        assertNotNull(mAmBandDescriptor);
+        assertNotNull(mFmBandDescriptor);
+        mAmBandConfig = new RadioManager.AmBandConfig.Builder(mAmBandDescriptor).build();
+        mFmBandConfig = new RadioManager.FmBandConfig.Builder(mFmBandDescriptor).build();
+
+        mRadioTuner = mRadioManager.openTuner(mModule.getId(),
+                mFmBandConfig, withAudio, mCallback, null);
+        assertNotNull(mRadioTuner);
+        verify(mCallback, timeout(kConfigCallbackTimeoutMs)).onConfigurationChanged(any());
+        resetCallback();
+    }
+
+    private void checkAntenna() {
+        boolean isConnected = mRadioTuner.isAntennaConnected();
+        assertTrue(isConnected);
+    }
+
+    @Test
+    public void testOpenTuner() {
+        openTuner();
+    }
+
+    @Test
+    public void testReopenTuner() throws Throwable {
+        openTuner();
+        mRadioTuner.close();
+        mRadioTuner = null;
+        Thread.sleep(100);  // TODO(b/36122635): force reopen
+        openTuner();
+    }
+
+    @Test
+    public void testDoubleClose() {
+        openTuner();
+        mRadioTuner.close();
+        mRadioTuner.close();
+    }
+
+    @Test
+    public void testUseAfterClose() {
+        openTuner();
+        mRadioTuner.close();
+        int ret = mRadioTuner.cancel();
+        assertEquals(RadioManager.STATUS_INVALID_OPERATION, ret);
+    }
+
+    @Test
+    public void testSetAndGetConfiguration() {
+        openTuner();
+
+        // set
+        int ret = mRadioTuner.setConfiguration(mAmBandConfig);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        verify(mCallback, timeout(kConfigCallbackTimeoutMs)).onConfigurationChanged(any());
+
+        // get
+        RadioManager.BandConfig[] config = new RadioManager.BandConfig[1];
+        ret = mRadioTuner.getConfiguration(config);
+        assertEquals(RadioManager.STATUS_OK, ret);
+
+        assertEquals(mAmBandConfig, config[0]);
+    }
+
+    @Test
+    public void testSetBadConfiguration() throws Throwable {
+        openTuner();
+
+        // set bad config
+        Constructor<RadioManager.AmBandConfig> configConstr =
+                RadioManager.AmBandConfig.class.getDeclaredConstructor(
+                        int.class, int.class, int.class, int.class, int.class, boolean.class);
+        configConstr.setAccessible(true);
+        RadioManager.AmBandConfig badConfig = configConstr.newInstance(
+                0 /*region*/, RadioManager.BAND_AM /*type*/,
+                10000 /*lowerLimit*/, 1 /*upperLimit*/, 100 /*spacing*/, false /*stereo*/);
+        int ret = mRadioTuner.setConfiguration(badConfig);
+        assertEquals(RadioManager.STATUS_BAD_VALUE, ret);
+        verify(mCallback, never()).onConfigurationChanged(any());
+
+        // set null config
+        ret = mRadioTuner.setConfiguration(null);
+        assertEquals(RadioManager.STATUS_BAD_VALUE, ret);
+        verify(mCallback, never()).onConfigurationChanged(any());
+
+        // setting good config should recover
+        ret = mRadioTuner.setConfiguration(mAmBandConfig);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        verify(mCallback, timeout(kConfigCallbackTimeoutMs)).onConfigurationChanged(any());
+    }
+
+    @Test
+    public void testMute() {
+        openTuner();
+
+        boolean isMuted = mRadioTuner.getMute();
+        assertFalse(isMuted);
+
+        int ret = mRadioTuner.setMute(true);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        isMuted = mRadioTuner.getMute();
+        assertTrue(isMuted);
+
+        ret = mRadioTuner.setMute(false);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        isMuted = mRadioTuner.getMute();
+        assertFalse(isMuted);
+    }
+
+    @Test
+    public void testMuteNoAudio() {
+        openTuner(false);
+
+        int ret = mRadioTuner.setMute(false);
+        assertEquals(RadioManager.STATUS_ERROR, ret);
+
+        boolean isMuted = mRadioTuner.getMute();
+        assertTrue(isMuted);
+    }
+
+    @Test
+    public void testStep() {
+        openTuner();
+        checkAntenna();
+
+        int ret = mRadioTuner.step(RadioTuner.DIRECTION_DOWN, true);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        verify(mCallback, timeout(kTuneCallbackTimeoutMs)).onProgramInfoChanged(any());
+
+        resetCallback();
+
+        ret = mRadioTuner.step(RadioTuner.DIRECTION_UP, false);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        verify(mCallback, timeout(kTuneCallbackTimeoutMs)).onProgramInfoChanged(any());
+    }
+
+    @Test
+    public void testTuneAndGetPI() {
+        openTuner();
+        checkAntenna();
+
+        int channel = mFmBandConfig.getLowerLimit() + mFmBandConfig.getSpacing();
+
+        // test tune
+        int ret = mRadioTuner.tune(channel, 0);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        ArgumentCaptor<RadioManager.ProgramInfo> infoc =
+                ArgumentCaptor.forClass(RadioManager.ProgramInfo.class);
+        verify(mCallback, timeout(kTuneCallbackTimeoutMs))
+                .onProgramInfoChanged(infoc.capture());
+        assertEquals(channel, infoc.getValue().getChannel());
+
+        // test getProgramInformation
+        RadioManager.ProgramInfo[] info = new RadioManager.ProgramInfo[1];
+        ret = mRadioTuner.getProgramInformation(info);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        assertNotNull(info[0]);
+        assertEquals(channel, info[0].getChannel());
+    }
+
+    @Test
+    public void testDummyCancel() {
+        openTuner();
+
+        int ret = mRadioTuner.cancel();
+        assertEquals(RadioManager.STATUS_OK, ret);
+    }
+
+    @Test
+    public void testLateCancel() {
+        openTuner();
+        checkAntenna();
+
+        int ret = mRadioTuner.step(RadioTuner.DIRECTION_DOWN, false);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        verify(mCallback, timeout(kTuneCallbackTimeoutMs)).onProgramInfoChanged(any());
+
+        int cancelRet = mRadioTuner.cancel();
+        assertEquals(RadioManager.STATUS_OK, cancelRet);
+    }
+
+    @Test
+    public void testScanAndCancel() {
+        openTuner();
+        checkAntenna();
+
+        /* There is a possible race condition between scan and cancel commands - the scan may finish
+         * before cancel command is issued. Thus we accept both outcomes in this test.
+         */
+        int scanRet = mRadioTuner.scan(RadioTuner.DIRECTION_DOWN, true);
+        int cancelRet = mRadioTuner.cancel();
+
+        assertEquals(RadioManager.STATUS_OK, scanRet);
+        assertEquals(RadioManager.STATUS_OK, cancelRet);
+
+        verify(mCallback, after(kCancelTimeoutMs).atMost(1)).onError(RadioTuner.ERROR_CANCELLED);
+        verify(mCallback, atMost(1)).onProgramInfoChanged(any());
+    }
+
+    @Test
+    public void testStartBackgroundScan() {
+        openTuner();
+        checkAntenna();
+
+        boolean ret = mRadioTuner.startBackgroundScan();
+        boolean isSupported = mModule.isBackgroundScanningSupported();
+        assertEquals(isSupported, ret);
+    }
+
+    @Test
+    public void testGetProgramList() {
+        openTuner();
+        checkAntenna();
+
+        try {
+            List<RadioManager.ProgramInfo> list = mRadioTuner.getProgramList(null);
+            assertNotNull(list);
+        } catch (IllegalStateException e) {
+            // the list may or may not be ready at this point
+            Log.i(TAG, "Background list is not ready");
+        }
+    }
+
+    @Test
+    public void testForcedAnalog() {
+        openTuner();
+
+        boolean isSupported = true;
+        boolean isForced;
+        try {
+            isForced = mRadioTuner.isAnalogForced();
+            assertFalse(isForced);
+        } catch (IllegalStateException ex) {
+            Log.i(TAG, "Forced analog switch is not supported by this tuner");
+            isSupported = false;
+        }
+
+        if (isSupported) {
+            mRadioTuner.setAnalogForced(true);
+            isForced = mRadioTuner.isAnalogForced();
+            assertTrue(isForced);
+
+            mRadioTuner.setAnalogForced(false);
+            isForced = mRadioTuner.isAnalogForced();
+            assertFalse(isForced);
+        } else {
+            assertThrows(IllegalStateException.class, () -> mRadioTuner.setAnalogForced(true));
+        }
+    }
+}
diff --git a/tests/testables/Android.mk b/tests/testables/Android.mk
index 759bc35..0e36981 100644
--- a/tests/testables/Android.mk
+++ b/tests/testables/Android.mk
@@ -31,3 +31,5 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/testables/src/android/testing/AndroidTestingRunner.java b/tests/testables/src/android/testing/AndroidTestingRunner.java
index a425f70..cf5d4cf 100644
--- a/tests/testables/src/android/testing/AndroidTestingRunner.java
+++ b/tests/testables/src/android/testing/AndroidTestingRunner.java
@@ -35,6 +35,8 @@
 
 /**
  * A runner with support for extra annotations provided by the Testables library.
+ * @see UiThreadTest
+ * @see TestableLooper.RunWithLooper
  */
 public class AndroidTestingRunner extends BlockJUnit4ClassRunner {
 
diff --git a/tests/testables/src/android/testing/BaseFragmentTest.java b/tests/testables/src/android/testing/BaseFragmentTest.java
index f1e4d21..5fa065a 100644
--- a/tests/testables/src/android/testing/BaseFragmentTest.java
+++ b/tests/testables/src/android/testing/BaseFragmentTest.java
@@ -84,6 +84,10 @@
         });
     }
 
+    /**
+     * Allows tests to sub-class TestableContext if they want to provide any extended functionality
+     * or provide a {@link LeakCheck} to the TestableContext upon instantiation.
+     */
     protected TestableContext getContext() {
         return new TestableContext(InstrumentationRegistry.getContext());
     }
diff --git a/tests/testables/src/android/testing/LeakCheck.java b/tests/testables/src/android/testing/LeakCheck.java
index 8daaa8f..949215b 100644
--- a/tests/testables/src/android/testing/LeakCheck.java
+++ b/tests/testables/src/android/testing/LeakCheck.java
@@ -14,6 +14,7 @@
 
 package android.testing;
 
+import android.content.Context;
 import android.util.ArrayMap;
 import android.util.Log;
 
@@ -28,6 +29,35 @@
 import java.util.List;
 import java.util.Map;
 
+/**
+ * Utility for dealing with the facts of Lifecycle. Creates trackers to check that for every
+ * call to registerX, addX, bindX, a corresponding call to unregisterX, removeX, and unbindX
+ * is performed. This should be applied to a test as a {@link org.junit.rules.TestRule}
+ * and will only check for leaks on successful tests.
+ * <p>
+ * Example that will catch an allocation and fail:
+ * <pre class="prettyprint">
+ * public class LeakCheckTest {
+ *    &#064;Rule public LeakCheck mLeakChecker = new LeakCheck();
+ *
+ *    &#064;Test
+ *    public void testLeak() {
+ *        Context context = new ContextWrapper(...) {
+ *            public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ *                mLeakChecker.getTracker("receivers").addAllocation(new Throwable());
+ *            }
+ *            public void unregisterReceiver(BroadcastReceiver receiver) {
+ *                mLeakChecker.getTracker("receivers").clearAllocations();
+ *            }
+ *        };
+ *        context.registerReceiver(...);
+ *    }
+ *  }
+ * </pre>
+ *
+ * Note: {@link TestableContext} supports leak tracking when using
+ * {@link TestableContext#TestableContext(Context, LeakCheck)}.
+ */
 public class LeakCheck extends TestWatcher {
 
     private final Map<String, Tracker> mTrackers = new HashMap<>();
@@ -40,6 +70,13 @@
         verify();
     }
 
+    /**
+     * Acquire a {@link Tracker}. Gets a tracker for the specified tag, creating one if necessary.
+     * There should be one tracker for each pair of add/remove callbacks (e.g. one tracker for
+     * registerReceiver/unregisterReceiver).
+     *
+     * @param tag Unique tag to use for this set of allocation tracking.
+     */
     public Tracker getTracker(String tag) {
         Tracker t = mTrackers.get(tag);
         if (t == null) {
@@ -49,10 +86,13 @@
         return t;
     }
 
-    public void verify() {
+    private void verify() {
         mTrackers.values().forEach(Tracker::verify);
     }
 
+    /**
+     * Holds allocations associated with a specific callback (such as a BroadcastReceiver).
+     */
     public static class LeakInfo {
         private static final String TAG = "LeakInfo";
         private List<Throwable> mThrowables = new ArrayList<>();
@@ -60,11 +100,20 @@
         LeakInfo() {
         }
 
+        /**
+         * Should be called once for each callback/listener added. addAllocation may be
+         * called several times, but it only takes one clearAllocations call to remove all
+         * of them.
+         */
         public void addAllocation(Throwable t) {
             // TODO: Drop off the first element in the stack trace here to have a cleaner stack.
             mThrowables.add(t);
         }
 
+        /**
+         * Should be called when the callback/listener has been removed. One call to
+         * clearAllocations will counteract any number of calls to addAllocation.
+         */
         public void clearAllocations() {
             mThrowables.clear();
         }
@@ -82,9 +131,16 @@
         }
     }
 
+    /**
+     * Tracks allocations related to a specific tag or method(s).
+     * @see #getTracker(String)
+     */
     public static class Tracker {
         private Map<Object, LeakInfo> mObjects = new ArrayMap<>();
 
+        private Tracker() {
+        }
+
         public LeakInfo getLeakInfo(Object object) {
             LeakInfo leakInfo = mObjects.get(object);
             if (leakInfo == null) {
diff --git a/tests/testables/src/android/testing/TestableContentResolver.java b/tests/testables/src/android/testing/TestableContentResolver.java
index bfafbe0..0850916 100644
--- a/tests/testables/src/android/testing/TestableContentResolver.java
+++ b/tests/testables/src/android/testing/TestableContentResolver.java
@@ -27,7 +27,11 @@
 import java.util.Map;
 
 /**
- * Alternative to a MockContentResolver that falls back to real providers.
+ * A version of ContentResolver that allows easy mocking of providers.
+ * By default it acts as a normal ContentResolver and returns all the
+ * same providers.
+ * @see #addProvider(String, ContentProvider)
+ * @see #setFallbackToExisting(boolean)
  */
 public class TestableContentResolver extends ContentResolver {
 
diff --git a/tests/testables/src/android/testing/TestableContext.java b/tests/testables/src/android/testing/TestableContext.java
index 630a287..498d517 100644
--- a/tests/testables/src/android/testing/TestableContext.java
+++ b/tests/testables/src/android/testing/TestableContext.java
@@ -43,6 +43,7 @@
  * <ul>
  * <li>System services can be mocked out with {@link #addMockSystemService}</li>
  * <li>Service binding can be mocked out with {@link #addMockService}</li>
+ * <li>Resources can be mocked out using {@link #getOrCreateTestableResources()}</li>
  * <li>Settings support {@link TestableSettingsProvider}</li>
  * <li>Has support for {@link LeakCheck} for services and receivers</li>
  * </ul>
@@ -50,10 +51,8 @@
  * <p>TestableContext should be defined as a rule on your test so it can clean up after itself.
  * Like the following:</p>
  * <pre class="prettyprint">
- * {@literal
- * @Rule
+ * &#064;Rule
  * private final TestableContext mContext = new TestableContext(InstrumentationRegister.getContext());
- * }
  * </pre>
  */
 public class TestableContext extends ContextWrapper implements TestRule {
@@ -69,6 +68,7 @@
     private LeakCheck.Tracker mReceiver;
     private LeakCheck.Tracker mService;
     private LeakCheck.Tracker mComponent;
+    private TestableResources mTestableResources;
 
     public TestableContext(Context base) {
         this(base, null);
@@ -98,25 +98,59 @@
         return super.getPackageManager();
     }
 
-    @Override
-    public Resources getResources() {
-        return super.getResources();
+    /**
+     * Makes sure the resources being returned by this TestableContext are a version of
+     * TestableResources.
+     * @see #getResources()
+     */
+    public void ensureTestableResources() {
+        if (mTestableResources == null) {
+            mTestableResources = new TestableResources(super.getResources());
+        }
     }
 
+    /**
+     * Get (and create if necessary) {@link TestableResources} for this TestableContext.
+     */
+    public TestableResources getOrCreateTestableResources() {
+        ensureTestableResources();
+        return mTestableResources;
+    }
+
+    /**
+     * Returns a Resources instance for the test.
+     *
+     * By default this returns the same resources object that would come from the
+     * {@link ContextWrapper}, but if {@link #ensureTestableResources()} or
+     * {@link #getOrCreateTestableResources()} has been called, it will return resources gotten from
+     * {@link TestableResources}.
+     */
+    @Override
+    public Resources getResources() {
+        return mTestableResources != null ? mTestableResources.getResources()
+                : super.getResources();
+    }
+
+    /**
+     * @see #getSystemService(String)
+     */
     public <T> void addMockSystemService(Class<T> service, T mock) {
         addMockSystemService(getSystemServiceName(service), mock);
     }
 
+    /**
+     * @see #getSystemService(String)
+     */
     public void addMockSystemService(String name, Object service) {
         if (mMockSystemServices == null) mMockSystemServices = new ArrayMap<>();
         mMockSystemServices.put(name, service);
     }
 
-    public void addMockService(ComponentName component, IBinder service) {
-        if (mMockServices == null) mMockServices = new ArrayMap<>();
-        mMockServices.put(component, service);
-    }
-
+    /**
+     * If a matching mock service has been added through {@link #addMockSystemService} then
+     * that will be returned, otherwise the real service will be acquired from the base
+     * context.
+     */
     @Override
     public Object getSystemService(String name) {
         if (mMockSystemServices != null && mMockSystemServices.containsKey(name)) {
@@ -137,6 +171,10 @@
         return mTestableContentResolver;
     }
 
+    /**
+     * Will always return itself for a TestableContext to ensure the testable effects extend
+     * to the application context.
+     */
     @Override
     public Context getApplicationContext() {
         // Return this so its always a TestableContext.
@@ -170,6 +208,24 @@
         super.unregisterReceiver(receiver);
     }
 
+    /**
+     * Adds a mock service to be connected to by a bindService call.
+     * <p>
+     *     Normally a TestableContext will pass through all bind requests to the base context
+     *     but when addMockService has been called for a ComponentName being bound, then
+     *     TestableContext will immediately trigger a {@link ServiceConnection#onServiceConnected}
+     *     with the specified service, and will call {@link ServiceConnection#onServiceDisconnected}
+     *     when the service is unbound.
+     * </p>
+     */
+    public void addMockService(ComponentName component, IBinder service) {
+        if (mMockServices == null) mMockServices = new ArrayMap<>();
+        mMockServices.put(component, service);
+    }
+
+    /**
+     * @see #addMockService(ComponentName, IBinder)
+     */
     @Override
     public boolean bindService(Intent service, ServiceConnection conn, int flags) {
         if (mService != null) mService.getLeakInfo(conn).addAllocation(new Throwable());
@@ -177,6 +233,9 @@
         return super.bindService(service, conn, flags);
     }
 
+    /**
+     * @see #addMockService(ComponentName, IBinder)
+     */
     @Override
     public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
             Handler handler, UserHandle user) {
@@ -185,6 +244,9 @@
         return super.bindServiceAsUser(service, conn, flags, handler, user);
     }
 
+    /**
+     * @see #addMockService(ComponentName, IBinder)
+     */
     @Override
     public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
             UserHandle user) {
@@ -203,6 +265,9 @@
         return false;
     }
 
+    /**
+     * @see #addMockService(ComponentName, IBinder)
+     */
     @Override
     public void unbindService(ServiceConnection conn) {
         if (mService != null) mService.getLeakInfo(conn).clearAllocations();
@@ -214,6 +279,13 @@
         super.unbindService(conn);
     }
 
+    /**
+     * Check if the TestableContext has a mock binding for a specified component. Will return
+     * true between {@link ServiceConnection#onServiceConnected} and
+     * {@link ServiceConnection#onServiceDisconnected} callbacks for a mock service.
+     *
+     * @see #addMockService(ComponentName, IBinder)
+     */
     public boolean isBound(ComponentName component) {
         return mActiveServices != null && mActiveServices.containsValue(component);
     }
diff --git a/tests/testables/src/android/testing/TestableInstrumentation.java b/tests/testables/src/android/testing/TestableInstrumentation.java
new file mode 100644
index 0000000..93fed85
--- /dev/null
+++ b/tests/testables/src/android/testing/TestableInstrumentation.java
@@ -0,0 +1,181 @@
+/*
+ * 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.testing;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.TestLooperManager;
+import android.support.test.runner.AndroidJUnitRunner;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * Wrapper around instrumentation that spins up a TestLooperManager around
+ * the main looper whenever a test is not using it to attempt to stop crashes
+ * from stopping other tests from running.
+ */
+public class TestableInstrumentation extends AndroidJUnitRunner {
+
+    private static final String TAG = "TestableInstrumentation";
+
+    private static final int MAX_CRASHES = 5;
+    private static MainLooperManager sManager;
+
+    @Override
+    public void onCreate(Bundle arguments) {
+        sManager = new MainLooperManager();
+        Log.setWtfHandler((tag, what, system) -> {
+            if (system) {
+                Log.e(TAG, "WTF!!", what);
+            } else {
+                // These normally kill the app, but we don't want that in a test, instead we want
+                // it to throw.
+                throw new RuntimeException(what);
+            }
+        });
+        super.onCreate(arguments);
+    }
+
+    @Override
+    public void finish(int resultCode, Bundle results) {
+        sManager.destroy();
+        super.finish(resultCode, results);
+    }
+
+    public static void acquireMain() {
+        if (sManager != null) {
+            sManager.acquireMain();
+        }
+    }
+
+    public static void releaseMain() {
+        if (sManager != null) {
+            sManager.releaseMain();
+        }
+    }
+
+    public class MainLooperManager implements Runnable {
+
+        private final ArrayList<Throwable> mExceptions = new ArrayList<>();
+        private Message mStopMessage;
+        private final Handler mMainHandler;
+        private TestLooperManager mManager;
+
+        public MainLooperManager() {
+            mMainHandler = new Handler(Looper.getMainLooper());
+            startManaging();
+        }
+
+        @Override
+        public void run() {
+            try {
+                synchronized (this) {
+                    // Let the thing starting us know we are up and ready to run.
+                    notify();
+                }
+                while (true) {
+                    Message m = mManager.next();
+                    if (m == mStopMessage) {
+                        mManager.recycle(m);
+                        return;
+                    }
+                    try {
+                        mManager.execute(m);
+                    } catch (Throwable t) {
+                        if (!checkStack(t) || (mExceptions.size() == MAX_CRASHES)) {
+                            throw t;
+                        }
+                        mExceptions.add(t);
+                        Log.d(TAG, "Ignoring exception to run more tests", t);
+                    }
+                    mManager.recycle(m);
+                }
+            } finally {
+                mManager.release();
+                synchronized (this) {
+                    // Let the caller know we are done managing the main thread.
+                    notify();
+                }
+            }
+        }
+
+        private boolean checkStack(Throwable t) {
+            StackTraceElement topStack = t.getStackTrace()[0];
+            String className = topStack.getClassName();
+            if (className.equals(TestLooperManager.class.getName())) {
+                topStack = t.getCause().getStackTrace()[0];
+                className = topStack.getClassName();
+            }
+            // Only interested in blocking exceptions from the app itself, not from android
+            // framework.
+            return !className.startsWith("android.")
+                    && !className.startsWith("com.android.internal");
+        }
+
+        public void destroy() {
+            mStopMessage.sendToTarget();
+            if (mExceptions.size() != 0) {
+                throw new RuntimeException("Exception caught during tests", mExceptions.get(0));
+            }
+        }
+
+        public void acquireMain() {
+            synchronized (this) {
+                mStopMessage.sendToTarget();
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+
+        public void releaseMain() {
+            startManaging();
+        }
+
+        private void startManaging() {
+            mStopMessage = mMainHandler.obtainMessage();
+            synchronized (this) {
+                mManager = acquireLooperManager(Looper.getMainLooper());
+                // This bit needs to happen on a background thread or it will hang if called
+                // from the same thread we are looking to block.
+                new Thread(() -> {
+                    // Post a message to the main handler that will manage executing all future
+                    // messages.
+                    mMainHandler.post(this);
+                    while (!mManager.hasMessages(mMainHandler, null, this));
+                    // Lastly run the message that executes this so it can manage the main thread.
+                    Message next = mManager.next();
+                    // Run through messages until we reach ours.
+                    while (next.getCallback() != this) {
+                        mManager.execute(next);
+                        mManager.recycle(next);
+                        next = mManager.next();
+                    }
+                    mManager.execute(next);
+                }).start();
+                if (Looper.myLooper() != Looper.getMainLooper()) {
+                    try {
+                        wait();
+                    } catch (InterruptedException e) {
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/tests/testables/src/android/testing/TestableLooper.java b/tests/testables/src/android/testing/TestableLooper.java
index 9eddc51..f1a7092 100644
--- a/tests/testables/src/android/testing/TestableLooper.java
+++ b/tests/testables/src/android/testing/TestableLooper.java
@@ -29,20 +29,18 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
-import java.lang.reflect.Field;
 import java.util.Map;
 
 /**
- * Creates a looper on the current thread with control over if/when messages are
- * executed. Warning: This class works through some reflection and may break/need
- * to be updated from time to time.
+ * This is a wrapper around {@link TestLooperManager} to make it easier to manage
+ * and provide an easy annotation for use with tests.
+ *
+ * @see TestableLooperTest TestableLooperTest for examples.
  */
 public class TestableLooper {
 
     private Looper mLooper;
     private MessageQueue mQueue;
-    private boolean mMain;
-    private Object mOriginalMain;
     private MessageHandler mMessageHandler;
 
     private Handler mHandler;
@@ -50,7 +48,7 @@
     private TestLooperManager mQueueWrapper;
 
     public TestableLooper(Looper l) throws Exception {
-        this(InstrumentationRegistry.getInstrumentation().acquireLooperManager(l), l);
+        this(acquireLooperManager(l), l);
     }
 
     private TestableLooper(TestLooperManager wrapper, Looper l) throws Exception {
@@ -72,35 +70,23 @@
         mHandler = new Handler(mLooper);
     }
 
-    public void setAsMainLooper() throws NoSuchFieldException, IllegalAccessException {
-        mMain = true;
-        setAsMainInt();
-    }
-
-    private void setAsMainInt() throws NoSuchFieldException, IllegalAccessException {
-        Field field = mLooper.getClass().getDeclaredField("sMainLooper");
-        field.setAccessible(true);
-        if (mOriginalMain == null) {
-            mOriginalMain = field.get(null);
-        }
-        field.set(null, mLooper);
-    }
-
     /**
-     * Must be called if setAsMainLooper is called to restore the main looper when the
-     * test is complete, otherwise the main looper will not be available for any subsequent
-     * tests.
+     * Must be called to release the looper when the test is complete, otherwise
+     * the looper will not be available for any subsequent tests. This is
+     * automatically handled for tests using {@link RunWithLooper}.
      */
     public void destroy() throws NoSuchFieldException, IllegalAccessException {
         mQueueWrapper.release();
-        if (mMain && mOriginalMain != null) {
-            Field field = mLooper.getClass().getDeclaredField("sMainLooper");
-            field.setAccessible(true);
-            field.set(null, mOriginalMain);
-            mOriginalMain = null;
+        if (mLooper == Looper.getMainLooper()) {
+            TestableInstrumentation.releaseMain();
         }
     }
 
+    /**
+     * Sets a callback for all messages processed on this TestableLooper.
+     *
+     * @see {@link MessageHandler}
+     */
     public void setMessageHandler(MessageHandler handler) {
         mMessageHandler = handler;
     }
@@ -119,6 +105,9 @@
         return num;
     }
 
+    /**
+     * Process messages in the queue until no more are found.
+     */
     public void processAllMessages() {
         while (processQueuedMessages() != 0) ;
     }
@@ -183,6 +172,11 @@
         void run() throws Exception;
     }
 
+    /**
+     * Annotation that tells the {@link AndroidTestingRunner} to create a TestableLooper and
+     * run this test/class on that thread. The {@link TestableLooper} can be acquired using
+     * {@link #get(Object)}.
+     */
     @Retention(RetentionPolicy.RUNTIME)
     @Target({ElementType.METHOD, ElementType.TYPE})
     public @interface RunWithLooper {
@@ -204,13 +198,24 @@
         }
     }
 
+    private static TestLooperManager acquireLooperManager(Looper l) {
+        if (l == Looper.getMainLooper()) {
+            TestableInstrumentation.acquireMain();
+        }
+        return InstrumentationRegistry.getInstrumentation().acquireLooperManager(l);
+    }
+
     private static final Map<Object, TestableLooper> sLoopers = new ArrayMap<>();
 
+    /**
+     * For use with {@link RunWithLooper}, used to get the TestableLooper that was
+     * automatically created for this test.
+     */
     public static TestableLooper get(Object test) {
         return sLoopers.get(test);
     }
 
-    public static class LooperFrameworkMethod extends FrameworkMethod {
+    static class LooperFrameworkMethod extends FrameworkMethod {
         private HandlerThread mHandlerThread;
 
         private final TestableLooper mTestableLooper;
@@ -251,8 +256,7 @@
             }
             boolean set = mTestableLooper.mQueueWrapper == null;
             if (set) {
-                mTestableLooper.mQueueWrapper = InstrumentationRegistry.getInstrumentation()
-                        .acquireLooperManager(mLooper);
+                mTestableLooper.mQueueWrapper = acquireLooperManager(mLooper);
             }
             try {
                 Object[] ret = new Object[1];
@@ -287,6 +291,9 @@
                 if (set) {
                     mTestableLooper.mQueueWrapper.release();
                     mTestableLooper.mQueueWrapper = null;
+                    if (mLooper == Looper.getMainLooper()) {
+                        TestableInstrumentation.releaseMain();
+                    }
                 }
             }
         }
@@ -319,6 +326,11 @@
         }
     }
 
+    /**
+     * Callback to control the execution of messages on the looper, when set with
+     * {@link #setMessageHandler(MessageHandler)} then {@link #onMessageHandled(Message)}
+     * will get called back for every message processed on the {@link TestableLooper}.
+     */
     public interface MessageHandler {
         /**
          * Return true to have the message executed and delivered to target.
diff --git a/tests/testables/src/android/testing/TestableResources.java b/tests/testables/src/android/testing/TestableResources.java
new file mode 100644
index 0000000..a2fa95d
--- /dev/null
+++ b/tests/testables/src/android/testing/TestableResources.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package android.testing;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.withSettings;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+import android.util.SparseArray;
+
+import org.mockito.invocation.InvocationOnMock;
+
+/**
+ * Provides a version of Resources that defaults to all existing resources, but can have ids
+ * changed to return specific values.
+ * <p>
+ * TestableResources are lazily initialized, be sure to call
+ * {@link TestableContext#ensureTestableResources} before your tested code has an opportunity
+ * to cache {@link Context#getResources}.
+ * </p>
+ */
+public class TestableResources {
+
+    private static final String TAG = "TestableResources";
+    private final Resources mResources;
+    private final SparseArray<Object> mOverrides = new SparseArray<>();
+
+    TestableResources(Resources realResources) {
+        mResources = mock(Resources.class, withSettings()
+                .spiedInstance(realResources)
+                .defaultAnswer(this::answer));
+    }
+
+    /**
+     * Gets the implementation of Resources that will return overridden values when called.
+     */
+    public Resources getResources() {
+        return mResources;
+    }
+
+    /**
+     * Sets the return value for the specified resource id.
+     * <p>
+     * Since resource ids are unique there is a single addOverride that will override the value
+     * whenever it is gotten regardless of which method is used (i.e. getColor or getDrawable).
+     * </p>
+     * @param id The resource id to be overridden
+     * @param value The value of the resource, null to cause a {@link Resources.NotFoundException}
+     *              when gotten.
+     */
+    public void addOverride(int id, Object value) {
+        mOverrides.put(id, value);
+    }
+
+    /**
+     * Removes the override for the specified id.
+     * <p>
+     * This should be called over addOverride(id, null), because specifying a null value will
+     * cause a {@link Resources.NotFoundException} whereas removing the override will actually
+     * switch back to returning the default/real value of the resource.
+     * </p>
+     * @param id
+     */
+    public void removeOverride(int id) {
+        mOverrides.remove(id);
+    }
+
+    private Object answer(InvocationOnMock invocationOnMock) throws Throwable {
+        try {
+            int id = invocationOnMock.getArgument(0);
+            int index = mOverrides.indexOfKey(id);
+            if (index >= 0) {
+                Object value = mOverrides.valueAt(index);
+                if (value == null) throw new Resources.NotFoundException();
+                return value;
+            }
+        } catch (Resources.NotFoundException e) {
+            // Let through NotFoundException.
+            throw e;
+        } catch (Throwable t) {
+            // Generic catching for the many things that can go wrong, fall back to
+            // the real implementation.
+            Log.i(TAG, "Falling back to default resources call " + t);
+        }
+        return invocationOnMock.callRealMethod();
+    }
+}
diff --git a/tests/testables/src/android/testing/UiThreadTest.java b/tests/testables/src/android/testing/UiThreadTest.java
index e40e1d7..32a5824 100644
--- a/tests/testables/src/android/testing/UiThreadTest.java
+++ b/tests/testables/src/android/testing/UiThreadTest.java
@@ -20,8 +20,8 @@
 import java.lang.annotation.Target;
 
 /**
- * When applied to a class, all tests, befores, and afters will behave as if
- * they have @UiThreadTest applied to them.
+ * When applied to a class, all {@link org.junit.Test}s, {@link org.junit.After}s, and
+ * {@link org.junit.Before} will behave as if they have @UiThreadTest applied to them.
  */
 @Target({ElementType.METHOD, ElementType.TYPE})
 @Retention(RetentionPolicy.RUNTIME)
diff --git a/tests/testables/src/android/testing/ViewUtils.java b/tests/testables/src/android/testing/ViewUtils.java
index fca44ae..1c6016e 100644
--- a/tests/testables/src/android/testing/ViewUtils.java
+++ b/tests/testables/src/android/testing/ViewUtils.java
@@ -21,8 +21,16 @@
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
 
+/**
+ * Utilities to make testing views easier.
+ */
 public class ViewUtils {
 
+    /**
+     * Causes the view (and its children) to have {@link View#onAttachedToWindow()} called.
+     *
+     * This is currently done by adding the view to a window.
+     */
     public static void attachView(View view) {
         // Make sure hardware acceleration isn't turned on.
         view.getContext().getApplicationInfo().flags &=
@@ -34,6 +42,11 @@
         view.getContext().getSystemService(WindowManager.class).addView(view, lp);
     }
 
+    /**
+     * Causes the view (and its children) to have {@link View#onDetachedFromWindow()} called.
+     *
+     * This is currently done by removing the view from a window.
+     */
     public static void detachView(View view) {
         view.getContext().getSystemService(WindowManager.class).removeViewImmediate(view);
     }
diff --git a/tests/testables/tests/Android.mk b/tests/testables/tests/Android.mk
index a123d80..16fe535 100644
--- a/tests/testables/tests/Android.mk
+++ b/tests/testables/tests/Android.mk
@@ -18,7 +18,7 @@
 LOCAL_USE_AAPT2 := true
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_PACKAGE_NAME := TestablesTest
+LOCAL_PACKAGE_NAME := TestablesTests
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
     $(call all-Iaidl-files-under, src)
diff --git a/tests/testables/tests/res/values/strings.xml b/tests/testables/tests/res/values/strings.xml
new file mode 100644
index 0000000..1ad0ade
--- /dev/null
+++ b/tests/testables/tests/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="test_string">This is a test string</string>
+</resources>
diff --git a/tests/testables/tests/src/android/testing/TestableLooperTest.java b/tests/testables/tests/src/android/testing/TestableLooperTest.java
index 12f1d0a..13e72ba 100644
--- a/tests/testables/tests/src/android/testing/TestableLooperTest.java
+++ b/tests/testables/tests/src/android/testing/TestableLooperTest.java
@@ -31,9 +31,11 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.TestableLooper.MessageHandler;
 import android.testing.TestableLooper.RunWithLooper;
 
+@SmallTest
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 public class TestableLooperTest {
diff --git a/tests/testables/tests/src/android/testing/TestableResourcesTest.java b/tests/testables/tests/src/android/testing/TestableResourcesTest.java
new file mode 100644
index 0000000..dc7cf95
--- /dev/null
+++ b/tests/testables/tests/src/android/testing/TestableResourcesTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.testing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import android.content.res.Resources;
+import android.support.test.InstrumentationRegistry;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.testables.R;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class TestableResourcesTest {
+
+    @Rule
+    public TestableContext mContext = new TestableContext(InstrumentationRegistry.getContext());
+
+    @Test
+    public void testLazyInit() {
+        Resources before = mContext.getResources();
+        mContext.ensureTestableResources();
+        Resources after = mContext.getResources();
+        assertNotEquals(before, after);
+    }
+
+    @Test
+    public void testAddingResource() {
+        final int nonExistentId = 3; // Ids don't go this low.
+
+        try {
+            mContext.getColor(nonExistentId);
+            fail("Should throw NotFoundException");
+        } catch (Resources.NotFoundException e) {
+        }
+        mContext.getOrCreateTestableResources().addOverride(nonExistentId, 0xffffff);
+
+        assertEquals(0xffffff, mContext.getColor(nonExistentId));
+    }
+
+    @Test
+    public void testClearingResource() {
+        final int nonExistentId = 3; // Ids don't go this low.
+
+        mContext.getOrCreateTestableResources().addOverride(nonExistentId, 0xffffff);
+        assertEquals(0xffffff, mContext.getColor(nonExistentId));
+        mContext.getOrCreateTestableResources().removeOverride(nonExistentId);
+        try {
+            mContext.getColor(nonExistentId);
+            fail("Should throw NotFoundException");
+        } catch (Resources.NotFoundException e) {
+        }
+    }
+
+    @Test
+    public void testOverrideExisting() {
+        int existentId = R.string.test_string;
+
+        assertNotNull(mContext.getString(existentId));
+        mContext.getOrCreateTestableResources().addOverride(existentId, "Other strings");
+
+        assertEquals("Other strings", mContext.getString(existentId));
+    }
+
+    @Test(expected = Resources.NotFoundException.class)
+    public void testNonExistentException() {
+        int existentId = R.string.test_string;
+
+        assertNotNull(mContext.getString(existentId));
+        mContext.getOrCreateTestableResources().addOverride(existentId, null);
+
+        assertNull(mContext.getString(existentId));
+    }
+}
diff --git a/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java b/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java
index 0e2cc57..ac61deb 100644
--- a/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java
+++ b/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java
@@ -20,6 +20,7 @@
 import android.provider.Settings.Secure;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -27,6 +28,7 @@
 
 import static org.junit.Assert.*;
 
+@SmallTest
 @RunWith(AndroidJUnit4.class)
 public class TestableSettingsProviderTest {
 
diff --git a/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java b/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
index 8ca849b..e482708 100644
--- a/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
+++ b/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
@@ -54,7 +54,8 @@
  * Note that this class cannot be used in the same process as real settings. This is because it
  * works by passing an alternate ContentResolver to Settings operations. Unfortunately, the Settings
  * class only fetches the content provider from the passed-in ContentResolver the first time it's
- * used, and after that stores it in a per-process static.
+ * used, and after that stores it in a per-process static. If this needs to be used in this case,
+ * then call {@link #clearSettingsProvider()} before and after using this.
  *
  * TODO: evaluate implementing settings change notifications. This would require:
  *
@@ -90,6 +91,15 @@
         }
     }
 
+    /**
+     * This needs to be called before and after using the FakeSettingsProvider class.
+     */
+    public static void clearSettingsProvider() {
+        Settings.Secure.clearProviderForTest();
+        Settings.Global.clearProviderForTest();
+        Settings.System.clearProviderForTest();
+    }
+
     public Bundle call(String method, String arg, Bundle extras) {
         // Methods are "GET_system", "GET_global", "PUT_secure", etc.
         String[] commands = method.split("_", 2);
diff --git a/tools/aapt/Android.bp b/tools/aapt/Android.bp
new file mode 100644
index 0000000..e26c9c3
--- /dev/null
+++ b/tools/aapt/Android.bp
@@ -0,0 +1,115 @@
+//
+// 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.
+//
+
+// ==========================================================
+// Setup some common variables for the different build
+// targets here.
+// ==========================================================
+
+cc_defaults {
+    name: "aapt_defaults",
+
+    static_libs: [
+        "libandroidfw",
+        "libpng",
+        "libutils",
+        "liblog",
+        "libcutils",
+        "libexpat",
+        "libziparchive",
+        "libbase",
+        "libz",
+    ],
+    group_static_libs: true,
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+    target: {
+        windows: {
+            enabled: true,
+        },
+    },
+
+    // This tool is prebuilt if we're doing an app-only build.
+    product_variables: {
+        pdk: {
+            enabled: false,
+        },
+        unbundled_build: {
+            enabled: false,
+        },
+    },
+}
+
+// ==========================================================
+// Build the host static library: libaapt
+// ==========================================================
+cc_library_host_static {
+    name: "libaapt",
+    defaults: ["aapt_defaults"],
+    target: {
+        darwin: {
+            cflags: ["-D_DARWIN_UNLIMITED_STREAMS"],
+        },
+    },
+    cflags: [
+        "-Wno-format-y2k",
+        "-DSTATIC_ANDROIDFW_FOR_TOOLS",
+    ],
+
+    srcs: [
+        "AaptAssets.cpp",
+        "AaptConfig.cpp",
+        "AaptUtil.cpp",
+        "AaptXml.cpp",
+        "ApkBuilder.cpp",
+        "Command.cpp",
+        "CrunchCache.cpp",
+        "FileFinder.cpp",
+        "Images.cpp",
+        "Package.cpp",
+        "pseudolocalize.cpp",
+        "Resource.cpp",
+        "ResourceFilter.cpp",
+        "ResourceIdCache.cpp",
+        "ResourceTable.cpp",
+        "SourcePos.cpp",
+        "StringPool.cpp",
+        "WorkQueue.cpp",
+        "XMLNode.cpp",
+        "ZipEntry.cpp",
+        "ZipFile.cpp",
+    ],
+}
+
+// ==========================================================
+// Build the host tests: libaapt_tests
+// ==========================================================
+cc_test_host {
+    name: "libaapt_tests",
+    defaults: ["aapt_defaults"],
+    srcs: [
+        "tests/AaptConfig_test.cpp",
+        "tests/AaptGroupEntry_test.cpp",
+        "tests/Pseudolocales_test.cpp",
+        "tests/ResourceFilter_test.cpp",
+        "tests/ResourceTable_test.cpp",
+    ],
+    static_libs: ["libaapt"],
+}
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index 04f46d9..7bcf631d 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -14,7 +14,6 @@
 # limitations under the License.
 #
 
-# This tool is prebuilt if we're doing an app-only build.
 ifeq ($(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)),)
 
 # ==========================================================
@@ -23,37 +22,6 @@
 # ==========================================================
 LOCAL_PATH:= $(call my-dir)
 
-aaptMain := Main.cpp
-aaptSources := \
-    AaptAssets.cpp \
-    AaptConfig.cpp \
-    AaptUtil.cpp \
-    AaptXml.cpp \
-    ApkBuilder.cpp \
-    Command.cpp \
-    CrunchCache.cpp \
-    FileFinder.cpp \
-    Images.cpp \
-    Package.cpp \
-    pseudolocalize.cpp \
-    Resource.cpp \
-    ResourceFilter.cpp \
-    ResourceIdCache.cpp \
-    ResourceTable.cpp \
-    SourcePos.cpp \
-    StringPool.cpp \
-    WorkQueue.cpp \
-    XMLNode.cpp \
-    ZipEntry.cpp \
-    ZipFile.cpp
-
-aaptTests := \
-    tests/AaptConfig_test.cpp \
-    tests/AaptGroupEntry_test.cpp \
-    tests/Pseudolocales_test.cpp \
-    tests/ResourceFilter_test.cpp \
-    tests/ResourceTable_test.cpp
-
 aaptHostStaticLibs := \
     libandroidfw \
     libpng \
@@ -62,35 +30,10 @@
     libcutils \
     libexpat \
     libziparchive \
-    libbase
+    libbase \
+    libz
 
-aaptCFlags := -DAAPT_VERSION=\"$(BUILD_NUMBER_FROM_FILE)\"
-aaptCFlags += -Wall -Werror
-
-aaptHostLdLibs_linux := -lrt -ldl -lpthread
-
-# Statically link libz for MinGW (Win SDK under Linux),
-# and dynamically link for all others.
-aaptHostStaticLibs_windows := libz
-aaptHostLdLibs_linux += -lz
-aaptHostLdLibs_darwin := -lz
-
-
-# ==========================================================
-# Build the host static library: libaapt
-# ==========================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libaapt
-LOCAL_MODULE_HOST_OS := darwin linux windows
-LOCAL_CFLAGS := -Wno-format-y2k -DSTATIC_ANDROIDFW_FOR_TOOLS $(aaptCFlags)
-LOCAL_CPPFLAGS := $(aaptCppFlags)
-LOCAL_CFLAGS_darwin := -D_DARWIN_UNLIMITED_STREAMS
-LOCAL_SRC_FILES := $(aaptSources)
-LOCAL_STATIC_LIBRARIES := $(aaptHostStaticLibs)
-LOCAL_STATIC_LIBRARIES_windows := $(aaptHostStaticLibs_windows)
-
-include $(BUILD_HOST_STATIC_LIBRARY)
+aaptCFlags := -Wall -Werror
 
 # ==========================================================
 # Build the host executable: aapt
@@ -99,33 +42,10 @@
 
 LOCAL_MODULE := aapt
 LOCAL_MODULE_HOST_OS := darwin linux windows
-LOCAL_CFLAGS := $(aaptCFlags)
-LOCAL_CPPFLAGS := $(aaptCppFlags)
-LOCAL_LDLIBS_darwin := $(aaptHostLdLibs_darwin)
-LOCAL_LDLIBS_linux := $(aaptHostLdLibs_linux)
-LOCAL_SRC_FILES := $(aaptMain)
+LOCAL_CFLAGS := -DAAPT_VERSION=\"$(BUILD_NUMBER_FROM_FILE)\" $(aaptCFlags)
+LOCAL_SRC_FILES := Main.cpp
 LOCAL_STATIC_LIBRARIES := libaapt $(aaptHostStaticLibs)
-LOCAL_STATIC_LIBRARIES_windows := $(aaptHostStaticLibs_windows)
 
 include $(BUILD_HOST_EXECUTABLE)
 
-
-# ==========================================================
-# Build the host tests: libaapt_tests
-# ==========================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libaapt_tests
-LOCAL_CFLAGS := $(aaptCFlags)
-LOCAL_CPPFLAGS := $(aaptCppFlags)
-LOCAL_LDLIBS_darwin := $(aaptHostLdLibs_darwin)
-LOCAL_LDLIBS_linux := $(aaptHostLdLibs_linux)
-LOCAL_SRC_FILES := $(aaptTests)
-LOCAL_C_INCLUDES := $(LOCAL_PATH)
-LOCAL_STATIC_LIBRARIES := libaapt $(aaptHostStaticLibs)
-LOCAL_STATIC_LIBRARIES_windows := $(aaptHostStaticLibs_windows)
-
-include $(BUILD_HOST_NATIVE_TEST)
-
-
 endif # No TARGET_BUILD_APPS or TARGET_BUILD_PDK
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index ba73180..5e85802 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -29,24 +29,6 @@
 
 using namespace android;
 
-#ifndef AAPT_VERSION
-    #define AAPT_VERSION ""
-#endif
-
-/*
- * Show version info.  All the cool kids do it.
- */
-int doVersion(Bundle* bundle)
-{
-    if (bundle->getFileSpecCount() != 0) {
-        printf("(ignoring extra arguments)\n");
-    }
-    printf("Android Asset Packaging Tool, v0.2-" AAPT_VERSION "\n");
-
-    return 0;
-}
-
-
 /*
  * Open the file read only.  The call fails if the file doesn't exist.
  *
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index 5f586a1..627a231 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -1246,7 +1246,7 @@
         if (kIsDebug) {
             printf("Adding 9-patch info...\n");
         }
-        strcpy((char*)unknowns[p_index].name, "npTc");
+        memcpy((char*)unknowns[p_index].name, "npTc", 5);
         unknowns[p_index].data = (png_byte*)imageInfo.serialize9patch();
         unknowns[p_index].size = imageInfo.info9Patch.serializedSize();
         // TODO: remove the check below when everything works
@@ -1254,7 +1254,7 @@
 
         // automatically generated 9 patch outline data
         int chunk_size = sizeof(png_uint_32) * 6;
-        strcpy((char*)unknowns[o_index].name, "npOl");
+        memcpy((char*)unknowns[o_index].name, "npOl", 5);
         unknowns[o_index].data = (png_byte*) calloc(chunk_size, 1);
         png_byte outputData[chunk_size];
         memcpy(&outputData, &imageInfo.outlineInsetsLeft, 4 * sizeof(png_uint_32));
@@ -1266,7 +1266,7 @@
         // optional optical inset / layout bounds data
         if (imageInfo.haveLayoutBounds) {
             int chunk_size = sizeof(png_uint_32) * 4;
-            strcpy((char*)unknowns[b_index].name, "npLb");
+            memcpy((char*)unknowns[b_index].name, "npLb", 5);
             unknowns[b_index].data = (png_byte*) calloc(chunk_size, 1);
             memcpy(unknowns[b_index].data, &imageInfo.layoutBoundsLeft, chunk_size);
             unknowns[b_index].size = chunk_size;
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 417b7ae..d714687 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -20,6 +20,23 @@
 
 static const char* gProgName = "aapt";
 
+#ifndef AAPT_VERSION
+    #define AAPT_VERSION ""
+#endif
+
+/*
+ * Show version info.  All the cool kids do it.
+ */
+int doVersion(Bundle* bundle)
+{
+    if (bundle->getFileSpecCount() != 0) {
+        printf("(ignoring extra arguments)\n");
+    }
+    printf("Android Asset Packaging Tool, v0.2-" AAPT_VERSION "\n");
+
+    return 0;
+}
+
 /*
  * When running under Cygwin on Windows, this will convert slash-based
  * paths into back-slash-based ones. Otherwise the ApptAssets file comparisons
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index eff8283..046de46 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -24,7 +24,7 @@
 ]
 
 cc_defaults {
-    name: "aapt_defaults",
+    name: "aapt2_defaults",
     cflags: [
         "-Wall",
         "-Werror",
@@ -39,14 +39,9 @@
         windows: {
             enabled: true,
             cflags: ["-Wno-maybe-uninitialized"],
-            static_libs: ["libz"],
         },
         darwin: {
             cflags: ["-D_DARWIN_UNLIMITED_STREAMS"],
-            host_ldlibs: ["-lz"],
-        },
-        linux: {
-            host_ldlibs: ["-lz"],
         },
     },
     static_libs: [
@@ -59,6 +54,7 @@
         "libpng",
         "libbase",
         "libprotobuf-cpp-lite",
+        "libz",
     ],
     group_static_libs: true,
 }
@@ -84,6 +80,7 @@
         "compile/PseudolocaleGenerator.cpp",
         "compile/Pseudolocalizer.cpp",
         "compile/XmlIdCollector.cpp",
+        "configuration/ConfigurationParser.cpp",
         "filter/ConfigFilter.cpp",
         "flatten/Archive.cpp",
         "flatten/TableFlattener.cpp",
@@ -141,7 +138,7 @@
     proto: {
         export_proto_headers: true,
     },
-    defaults: ["aapt_defaults"],
+    defaults: ["aapt2_defaults"],
 }
 
 // ==========================================================
@@ -151,7 +148,7 @@
     name: "libaapt2_jni",
     srcs: toolSources + ["jni/aapt2_jni.cpp"],
     static_libs: ["libaapt2"],
-    defaults: ["aapt_defaults"],
+    defaults: ["aapt2_defaults"],
 }
 
 // ==========================================================
@@ -159,9 +156,15 @@
 // ==========================================================
 cc_test_host {
     name: "aapt2_tests",
-    srcs: ["test/Common.cpp", "**/*_test.cpp"],
-    static_libs: ["libaapt2", "libgmock"],
-    defaults: ["aapt_defaults"],
+    srcs: [
+        "test/Common.cpp",
+        "**/*_test.cpp",
+    ],
+    static_libs: [
+        "libaapt2",
+        "libgmock",
+    ],
+    defaults: ["aapt2_defaults"],
 }
 
 // ==========================================================
@@ -171,5 +174,5 @@
     name: "aapt2",
     srcs: ["Main.cpp"] + toolSources,
     static_libs: ["libaapt2"],
-    defaults: ["aapt_defaults"],
+    defaults: ["aapt2_defaults"],
 }
diff --git a/tools/aapt2/ConfigDescription.cpp b/tools/aapt2/ConfigDescription.cpp
index 46098cb..7ff0c72 100644
--- a/tools/aapt2/ConfigDescription.cpp
+++ b/tools/aapt2/ConfigDescription.cpp
@@ -877,7 +877,16 @@
 }
 
 bool ConfigDescription::Dominates(const ConfigDescription& o) const {
-  if (*this == DefaultConfig() || *this == o) {
+  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) &&
diff --git a/tools/aapt2/DominatorTree_test.cpp b/tools/aapt2/DominatorTree_test.cpp
index e89c6be..efc523f 100644
--- a/tools/aapt2/DominatorTree_test.cpp
+++ b/tools/aapt2/DominatorTree_test.cpp
@@ -69,14 +69,12 @@
 TEST(DominatorTreeTest, DefaultDominatesEverything) {
   const ConfigDescription default_config = {};
   const ConfigDescription land_config = test::ParseConfigOrDie("land");
-  const ConfigDescription sw600dp_land_config =
-      test::ParseConfigOrDie("sw600dp-land-v13");
+  const ConfigDescription sw600dp_land_config = test::ParseConfigOrDie("sw600dp-land-v13");
 
   std::vector<std::unique_ptr<ResourceConfigValue>> configs;
   configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
   configs.push_back(util::make_unique<ResourceConfigValue>(land_config, ""));
-  configs.push_back(
-      util::make_unique<ResourceConfigValue>(sw600dp_land_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_land_config, ""));
 
   DominatorTree tree(configs);
   PrettyPrinter printer;
@@ -91,16 +89,13 @@
 TEST(DominatorTreeTest, ProductsAreDominatedSeparately) {
   const ConfigDescription default_config = {};
   const ConfigDescription land_config = test::ParseConfigOrDie("land");
-  const ConfigDescription sw600dp_land_config =
-      test::ParseConfigOrDie("sw600dp-land-v13");
+  const ConfigDescription sw600dp_land_config = test::ParseConfigOrDie("sw600dp-land-v13");
 
   std::vector<std::unique_ptr<ResourceConfigValue>> configs;
   configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
   configs.push_back(util::make_unique<ResourceConfigValue>(land_config, ""));
-  configs.push_back(
-      util::make_unique<ResourceConfigValue>(default_config, "phablet"));
-  configs.push_back(
-      util::make_unique<ResourceConfigValue>(sw600dp_land_config, "phablet"));
+  configs.push_back(util::make_unique<ResourceConfigValue>(default_config, "phablet"));
+  configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_land_config, "phablet"));
 
   DominatorTree tree(configs);
   PrettyPrinter printer;
@@ -118,16 +113,11 @@
   const ConfigDescription en_config = test::ParseConfigOrDie("en");
   const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
   const ConfigDescription ldrtl_config = test::ParseConfigOrDie("ldrtl-v4");
-  const ConfigDescription ldrtl_xhdpi_config =
-      test::ParseConfigOrDie("ldrtl-xhdpi-v4");
-  const ConfigDescription sw300dp_config =
-      test::ParseConfigOrDie("sw300dp-v13");
-  const ConfigDescription sw540dp_config =
-      test::ParseConfigOrDie("sw540dp-v14");
-  const ConfigDescription sw600dp_config =
-      test::ParseConfigOrDie("sw600dp-v14");
-  const ConfigDescription sw720dp_config =
-      test::ParseConfigOrDie("sw720dp-v13");
+  const ConfigDescription ldrtl_xhdpi_config = test::ParseConfigOrDie("ldrtl-xhdpi-v4");
+  const ConfigDescription sw300dp_config = test::ParseConfigOrDie("sw300dp-v13");
+  const ConfigDescription sw540dp_config = test::ParseConfigOrDie("sw540dp-v14");
+  const ConfigDescription sw600dp_config = test::ParseConfigOrDie("sw600dp-v14");
+  const ConfigDescription sw720dp_config = test::ParseConfigOrDie("sw720dp-v13");
   const ConfigDescription v20_config = test::ParseConfigOrDie("v20");
 
   std::vector<std::unique_ptr<ResourceConfigValue>> configs;
@@ -135,8 +125,7 @@
   configs.push_back(util::make_unique<ResourceConfigValue>(en_config, ""));
   configs.push_back(util::make_unique<ResourceConfigValue>(en_v21_config, ""));
   configs.push_back(util::make_unique<ResourceConfigValue>(ldrtl_config, ""));
-  configs.push_back(
-      util::make_unique<ResourceConfigValue>(ldrtl_xhdpi_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(ldrtl_xhdpi_config, ""));
   configs.push_back(util::make_unique<ResourceConfigValue>(sw300dp_config, ""));
   configs.push_back(util::make_unique<ResourceConfigValue>(sw540dp_config, ""));
   configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_config, ""));
@@ -148,15 +137,37 @@
 
   std::string expected =
       "<default>\n"
-      "  en\n"
-      "    en-v21\n"
       "  ldrtl-v4\n"
       "    ldrtl-xhdpi-v4\n"
       "  sw300dp-v13\n"
       "    sw540dp-v14\n"
       "      sw600dp-v14\n"
       "    sw720dp-v13\n"
-      "  v20\n";
+      "  v20\n"
+      "en\n"
+      "  en-v21\n";
+  EXPECT_EQ(expected, printer.ToString(&tree));
+}
+
+TEST(DominatorTreeTest, LocalesAreNeverDominated) {
+  const ConfigDescription fr_config = test::ParseConfigOrDie("fr");
+  const ConfigDescription fr_rCA_config = test::ParseConfigOrDie("fr-rCA");
+  const ConfigDescription fr_rFR_config = test::ParseConfigOrDie("fr-rFR");
+
+  std::vector<std::unique_ptr<ResourceConfigValue>> configs;
+  configs.push_back(util::make_unique<ResourceConfigValue>(ConfigDescription::DefaultConfig(), ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(fr_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(fr_rCA_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(fr_rFR_config, ""));
+
+  DominatorTree tree(configs);
+  PrettyPrinter printer;
+
+  std::string expected =
+      "<default>\n"
+      "fr\n"
+      "fr-rCA\n"
+      "fr-rFR\n";
   EXPECT_EQ(expected, printer.ToString(&tree));
 }
 
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 5352ca8..c6382b1 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -843,4 +843,9 @@
   EXPECT_THAT(*str->value, Eq(""));
 }
 
+TEST_F(ResourceParserTest, ParsePlatformIndependentNewline) {
+  std::string input = R"(<string name="foo">%1$s %n %2$s</string>)";
+  ASSERT_TRUE(TestParse(input));
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index e09a3979..b64cd8c 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -145,7 +145,7 @@
   const std::string& root_dir = options.res_dir.value();
   std::unique_ptr<DIR, decltype(closedir)*> d(opendir(root_dir.data()), closedir);
   if (!d) {
-    context->GetDiagnostics()->Error(DiagMessage()
+    context->GetDiagnostics()->Error(DiagMessage(root_dir) << "failed to open directory: "
                                      << android::base::SystemErrorCodeToString(errno));
     return false;
   }
@@ -164,7 +164,7 @@
 
     std::unique_ptr<DIR, decltype(closedir)*> subdir(opendir(prefix_path.data()), closedir);
     if (!subdir) {
-      context->GetDiagnostics()->Error(DiagMessage()
+      context->GetDiagnostics()->Error(DiagMessage(prefix_path) << "failed to open directory: "
                                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
@@ -180,7 +180,7 @@
       std::string err_str;
       Maybe<ResourcePathData> path_data = ExtractResourcePathData(full_path, &err_str);
       if (!path_data) {
-        context->GetDiagnostics()->Error(DiagMessage() << err_str);
+        context->GetDiagnostics()->Error(DiagMessage(full_path) << err_str);
         return false;
       }
 
@@ -198,6 +198,7 @@
     std::ifstream fin(path_data.source.path, std::ifstream::binary);
     if (!fin) {
       context->GetDiagnostics()->Error(DiagMessage(path_data.source)
+                                       << "failed to open file: "
                                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
@@ -395,6 +396,7 @@
     std::ifstream fin(path_data.source.path, std::ifstream::binary);
     if (!fin) {
       context->GetDiagnostics()->Error(DiagMessage(path_data.source)
+                                       << "failed to open file: "
                                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
@@ -481,6 +483,7 @@
     if (!android::base::ReadFileToString(path_data.source.path, &content,
                                          true /*follow_symlinks*/)) {
       context->GetDiagnostics()->Error(DiagMessage(path_data.source)
+                                       << "failed to open file: "
                                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
diff --git a/tools/aapt2/cmd/Dump.cpp b/tools/aapt2/cmd/Dump.cpp
index 57c4574..aa94723 100644
--- a/tools/aapt2/cmd/Dump.cpp
+++ b/tools/aapt2/cmd/Dump.cpp
@@ -31,21 +31,22 @@
 
 namespace aapt {
 
-void DumpCompiledFile(const pb::CompiledFile& pb_file, const void* data, size_t len,
+bool DumpCompiledFile(const pb::CompiledFile& pb_file, const void* data, size_t len,
                       const Source& source, IAaptContext* context) {
   std::unique_ptr<ResourceFile> file =
       DeserializeCompiledFileFromPb(pb_file, source, context->GetDiagnostics());
   if (!file) {
     context->GetDiagnostics()->Warn(DiagMessage() << "failed to read compiled file");
-    return;
+    return false;
   }
 
   std::cout << "Resource: " << file->name << "\n"
             << "Config:   " << file->config << "\n"
             << "Source:   " << file->source << "\n";
+  return true;
 }
 
-void TryDumpFile(IAaptContext* context, const std::string& file_path) {
+bool TryDumpFile(IAaptContext* context, const std::string& file_path) {
   std::unique_ptr<ResourceTable> table;
 
   std::string err;
@@ -57,18 +58,18 @@
       if (!data) {
         context->GetDiagnostics()->Error(DiagMessage(file_path)
                                          << "failed to open resources.arsc.flat");
-        return;
+        return false;
       }
 
       pb::ResourceTable pb_table;
       if (!pb_table.ParseFromArray(data->data(), data->size())) {
         context->GetDiagnostics()->Error(DiagMessage(file_path) << "invalid resources.arsc.flat");
-        return;
+        return false;
       }
 
       table = DeserializeTableFromPb(pb_table, Source(file_path), context->GetDiagnostics());
       if (!table) {
-        return;
+        return false;
       }
     }
 
@@ -79,14 +80,14 @@
         if (!data) {
           context->GetDiagnostics()->Error(DiagMessage(file_path)
                                            << "failed to open resources.arsc");
-          return;
+          return false;
         }
 
         table = util::make_unique<ResourceTable>();
         BinaryResourceParser parser(context, table.get(), Source(file_path), data->data(),
                                     data->size());
         if (!parser.Parse()) {
-          return;
+          return false;
         }
       }
     }
@@ -96,7 +97,7 @@
     Maybe<android::FileMap> file = file::MmapPath(file_path, &err);
     if (!file) {
       context->GetDiagnostics()->Error(DiagMessage(file_path) << err);
-      return;
+      return false;
     }
 
     android::FileMap* file_map = &file.value();
@@ -113,24 +114,26 @@
 
       uint32_t num_files = 0;
       if (!input.ReadLittleEndian32(&num_files)) {
-        return;
+        return false;
       }
 
       for (uint32_t i = 0; i < num_files; i++) {
         pb::CompiledFile compiled_file;
         if (!input.ReadCompiledFile(&compiled_file)) {
           context->GetDiagnostics()->Warn(DiagMessage() << "failed to read compiled file");
-          return;
+          return false;
         }
 
         uint64_t offset, len;
         if (!input.ReadDataMetaData(&offset, &len)) {
           context->GetDiagnostics()->Warn(DiagMessage() << "failed to read meta data");
-          return;
+          return false;
         }
 
         const void* data = static_cast<const uint8_t*>(file_map->getDataPtr()) + offset;
-        DumpCompiledFile(compiled_file, data, len, Source(file_path), context);
+        if (!DumpCompiledFile(compiled_file, data, len, Source(file_path), context)) {
+          return false;
+        }
       }
     }
   }
@@ -140,6 +143,8 @@
     options.show_sources = true;
     Debug::PrintTable(table.get(), options);
   }
+
+  return true;
 }
 
 class DumpContext : public IAaptContext {
@@ -203,8 +208,11 @@
   context.SetVerbose(verbose);
 
   for (const std::string& arg : flags.GetArgs()) {
-    TryDumpFile(&context, arg);
+    if (!TryDumpFile(&context, arg)) {
+      return 1;
+    }
   }
+
   return 0;
 }
 
diff --git a/tools/aapt2/compile/Png.cpp b/tools/aapt2/compile/Png.cpp
index 6d6147d..33122dc 100644
--- a/tools/aapt2/compile/Png.cpp
+++ b/tools/aapt2/compile/Png.cpp
@@ -538,7 +538,7 @@
     if (kDebug) {
       diag->Note(DiagMessage() << "adding 9-patch info..");
     }
-    strcpy((char*)unknowns[pIndex].name, "npTc");
+    memcpy((char*)unknowns[pIndex].name, "npTc", 5);
     unknowns[pIndex].data = (png_byte*)info->serialize9Patch();
     unknowns[pIndex].size = info->info9Patch.serializedSize();
     // TODO: remove the check below when everything works
@@ -546,7 +546,7 @@
 
     // automatically generated 9 patch outline data
     int chunkSize = sizeof(png_uint_32) * 6;
-    strcpy((char*)unknowns[oIndex].name, "npOl");
+    memcpy((char*)unknowns[oIndex].name, "npOl", 5);
     unknowns[oIndex].data = (png_byte*)calloc(chunkSize, 1);
     png_byte outputData[chunkSize];
     memcpy(&outputData, &info->outlineInsetsLeft, 4 * sizeof(png_uint_32));
@@ -558,7 +558,7 @@
     // optional optical inset / layout bounds data
     if (info->haveLayoutBounds) {
       int chunkSize = sizeof(png_uint_32) * 4;
-      strcpy((char*)unknowns[bIndex].name, "npLb");
+      memcpy((char*)unknowns[bIndex].name, "npLb", 5);
       unknowns[bIndex].data = (png_byte*)calloc(chunkSize, 1);
       memcpy(unknowns[bIndex].data, &info->layoutBoundsLeft, chunkSize);
       unknowns[bIndex].size = chunkSize;
diff --git a/tools/aapt2/compile/PngChunkFilter.cpp b/tools/aapt2/compile/PngChunkFilter.cpp
index 7073c13..5af91fd 100644
--- a/tools/aapt2/compile/PngChunkFilter.cpp
+++ b/tools/aapt2/compile/PngChunkFilter.cpp
@@ -75,7 +75,7 @@
     window_start_ = 0;
     window_end_ = kPngSignatureSize;
   } else {
-    error_msg_ = "PNG does not start with PNG signature";
+    error_msg_ = "file does not start with PNG signature";
   }
 }
 
diff --git a/tools/aapt2/compile/PngCrunch.cpp b/tools/aapt2/compile/PngCrunch.cpp
index 42443d8..0346a19 100644
--- a/tools/aapt2/compile/PngCrunch.cpp
+++ b/tools/aapt2/compile/PngCrunch.cpp
@@ -142,19 +142,24 @@
 }
 
 std::unique_ptr<Image> ReadPng(IAaptContext* context, const Source& source, io::InputStream* in) {
+  // Create a diagnostics that has the source information encoded.
+  SourcePathDiagnostics source_diag(source, context->GetDiagnostics());
+
   // Read the first 8 bytes of the file looking for the PNG signature.
   // Bail early if it does not match.
   const png_byte* signature;
   size_t buffer_size;
   if (!in->Next((const void**)&signature, &buffer_size)) {
-    context->GetDiagnostics()->Error(DiagMessage()
-                                     << android::base::SystemErrorCodeToString(errno));
+    if (in->HadError()) {
+      source_diag.Error(DiagMessage() << "failed to read PNG signature: " << in->GetError());
+    } else {
+      source_diag.Error(DiagMessage() << "not enough data for PNG signature");
+    }
     return {};
   }
 
   if (buffer_size < kPngSignatureSize || png_sig_cmp(signature, 0, kPngSignatureSize) != 0) {
-    context->GetDiagnostics()->Error(DiagMessage()
-                                     << "file signature does not match PNG signature");
+    source_diag.Error(DiagMessage() << "file signature does not match PNG signature");
     return {};
   }
 
@@ -166,21 +171,18 @@
   // version of libpng.
   png_structp read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
   if (read_ptr == nullptr) {
-    context->GetDiagnostics()->Error(DiagMessage() << "failed to create libpng read png_struct");
+    source_diag.Error(DiagMessage() << "failed to create libpng read png_struct");
     return {};
   }
 
   // Create and initialize the memory for image header and data.
   png_infop info_ptr = png_create_info_struct(read_ptr);
   if (info_ptr == nullptr) {
-    context->GetDiagnostics()->Error(DiagMessage() << "failed to create libpng read png_info");
+    source_diag.Error(DiagMessage() << "failed to create libpng read png_info");
     png_destroy_read_struct(&read_ptr, nullptr, nullptr);
     return {};
   }
 
-  // Create a diagnostics that has the source information encoded.
-  SourcePathDiagnostics source_diag(source, context->GetDiagnostics());
-
   // Automatically release PNG resources at end of scope.
   PngReadStructDeleter png_read_deleter(read_ptr, info_ptr);
 
diff --git a/tools/aapt2/configuration/ConfigurationParser.cpp b/tools/aapt2/configuration/ConfigurationParser.cpp
new file mode 100644
index 0000000..89618d3
--- /dev/null
+++ b/tools/aapt2/configuration/ConfigurationParser.cpp
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "configuration/ConfigurationParser.h"
+
+#include <algorithm>
+#include <functional>
+#include <memory>
+#include <utility>
+
+#include <android-base/logging.h>
+
+#include "ConfigDescription.h"
+#include "Diagnostics.h"
+#include "util/Util.h"
+#include "xml/XmlActionExecutor.h"
+#include "xml/XmlDom.h"
+#include "xml/XmlUtil.h"
+
+namespace aapt {
+
+namespace {
+
+using ::aapt::configuration::Abi;
+using ::aapt::configuration::AndroidManifest;
+using ::aapt::configuration::AndroidSdk;
+using ::aapt::configuration::Artifact;
+using ::aapt::configuration::Configuration;
+using ::aapt::configuration::GlTexture;
+using ::aapt::configuration::Group;
+using ::aapt::configuration::Locale;
+using ::aapt::util::TrimWhitespace;
+using ::aapt::xml::Element;
+using ::aapt::xml::FindRootElement;
+using ::aapt::xml::NodeCast;
+using ::aapt::xml::XmlActionExecutor;
+using ::aapt::xml::XmlActionExecutorPolicy;
+using ::aapt::xml::XmlNodeAction;
+
+const std::unordered_map<std::string, Abi> kAbiMap = {
+    {"armeabi", Abi::kArmeV6},
+    {"armeabi-v7a", Abi::kArmV7a},
+    {"arm64-v8a", Abi::kArm64V8a},
+    {"x86", Abi::kX86},
+    {"x86_64", Abi::kX86_64},
+    {"mips", Abi::kMips},
+    {"mips64", Abi::kMips64},
+    {"universal", Abi::kUniversal},
+};
+
+constexpr const char* kAaptXmlNs = "http://schemas.android.com/tools/aapt";
+
+/** A default noop diagnostics context. */
+class NoopDiagnostics : public IDiagnostics {
+ public:
+  void Log(Level level, DiagMessageActual& actualMsg) override {}
+};
+NoopDiagnostics noop_;
+
+std::string GetLabel(const Element* element, IDiagnostics* diag) {
+  std::string label;
+  for (const auto& attr : element->attributes) {
+    if (attr.name == "label") {
+      label = attr.value;
+      break;
+    }
+  }
+
+  if (label.empty()) {
+    diag->Error(DiagMessage() << "No label found for element " << element->name);
+  }
+  return label;
+}
+
+/** XML node visitor that removes all of the namespace URIs from the node and all children. */
+class NamespaceVisitor : public xml::Visitor {
+ public:
+  void Visit(xml::Element* node) override {
+    node->namespace_uri.clear();
+    VisitChildren(node);
+  }
+};
+
+}  // namespace
+
+ConfigurationParser::ConfigurationParser(std::string contents)
+    : contents_(std::move(contents)),
+      diag_(&noop_) {
+}
+
+Maybe<Configuration> ConfigurationParser::Parse() {
+  std::istringstream in(contents_);
+
+  auto doc = xml::Inflate(&in, diag_, Source("config.xml"));
+  if (!doc) {
+    return {};
+  }
+
+  // Strip any namespaces from the XML as the XmlActionExecutor ignores anything with a namespace.
+  auto* root = FindRootElement(doc.get());
+  if (root == nullptr) {
+    diag_->Error(DiagMessage() << "Could not find the root element in the XML document");
+    return {};
+  }
+
+  std::string& xml_ns = root->namespace_uri;
+  if (!xml_ns.empty()) {
+    if (xml_ns != kAaptXmlNs) {
+      diag_->Error(DiagMessage() << "Unknown namespace found on root element: " << xml_ns);
+      return {};
+    }
+
+    xml_ns.clear();
+    NamespaceVisitor visitor;
+    root->Accept(&visitor);
+  }
+
+  XmlActionExecutor executor;
+  XmlNodeAction& root_action = executor["post-process"];
+  XmlNodeAction& artifacts_action = root_action["artifacts"];
+  XmlNodeAction& groups_action = root_action["groups"];
+
+  Configuration config;
+
+  // Helper to bind a static method to an action handler in the DOM executor.
+  auto bind_handler = [&config](std::function<bool(Configuration*, Element*, IDiagnostics*)> h)
+      -> XmlNodeAction::ActionFuncWithDiag {
+    return std::bind(h, &config, std::placeholders::_1, std::placeholders::_2);
+  };
+
+  // Parse the artifact elements.
+  artifacts_action["artifact"].Action(bind_handler(artifact_handler_));
+  artifacts_action["artifact-format"].Action(bind_handler(artifact_format_handler_));
+
+  // Parse the different configuration groups.
+  groups_action["abi-group"].Action(bind_handler(abi_group_handler_));
+  groups_action["screen-density-group"].Action(bind_handler(screen_density_group_handler_));
+  groups_action["locale-group"].Action(bind_handler(locale_group_handler_));
+  groups_action["android-sdk-group"].Action(bind_handler(android_sdk_group_handler_));
+  groups_action["gl-texture-group"].Action(bind_handler(gl_texture_group_handler_));
+  groups_action["device-feature-group"].Action(bind_handler(device_feature_group_handler_));
+
+  if (!executor.Execute(XmlActionExecutorPolicy::kNone, diag_, doc.get())) {
+    diag_->Error(DiagMessage() << "Could not process XML document");
+    return {};
+  }
+
+  return {config};
+}
+
+ConfigurationParser::ActionHandler ConfigurationParser::artifact_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      Artifact artifact{};
+      for (const auto& attr : root_element->attributes) {
+        if (attr.name == "name") {
+          artifact.name = attr.value;
+        } else if (attr.name == "abi-group") {
+          artifact.abi_group = {attr.value};
+        } else if (attr.name == "screen-density-group") {
+          artifact.screen_density_group = {attr.value};
+        } else if (attr.name == "locale-group") {
+          artifact.locale_group = {attr.value};
+        } else if (attr.name == "android-sdk-group") {
+          artifact.android_sdk_group = {attr.value};
+        } else if (attr.name == "gl-texture-group") {
+          artifact.gl_texture_group = {attr.value};
+        } else if (attr.name == "device-feature-group") {
+          artifact.device_feature_group = {attr.value};
+        } else {
+          diag->Note(
+              DiagMessage() << "Unknown artifact attribute: " << attr.name << " = " << attr.value);
+        }
+      }
+      config->artifacts[artifact.name] = artifact;
+      return true;
+    };
+
+ConfigurationParser::ActionHandler ConfigurationParser::artifact_format_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      for (auto& node : root_element->children) {
+        xml::Text* t;
+        if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+          config->artifact_format = TrimWhitespace(t->text).to_string();
+          break;
+        }
+      }
+      return true;
+    };
+
+ConfigurationParser::ActionHandler ConfigurationParser::abi_group_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      std::string label = GetLabel(root_element, diag);
+      if (label.empty()) {
+        return false;
+      }
+
+      auto& group = config->abi_groups[label];
+      bool valid = true;
+
+      for (auto* child : root_element->GetChildElements()) {
+        if (child->name != "abi") {
+          diag->Error(
+              DiagMessage() << "Unexpected element in ABI group: " << child->name);
+          valid = false;
+        } else {
+          for (auto& node : child->children) {
+            xml::Text* t;
+            if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+              group.push_back(kAbiMap.at(TrimWhitespace(t->text).to_string()));
+              break;
+            }
+          }
+        }
+      }
+
+      return valid;
+    };
+
+ConfigurationParser::ActionHandler ConfigurationParser::screen_density_group_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      std::string label = GetLabel(root_element, diag);
+      if (label.empty()) {
+        return false;
+      }
+
+      auto& group = config->screen_density_groups[label];
+      bool valid = true;
+
+      for (auto* child : root_element->GetChildElements()) {
+        if (child->name != "screen-density") {
+          diag->Error(
+              DiagMessage() << "Unexpected root_element in screen density group: "
+                            << child->name);
+          valid = false;
+        } else {
+          for (auto& node : child->children) {
+            xml::Text* t;
+            if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+              ConfigDescription config_descriptor;
+              const android::StringPiece& text = TrimWhitespace(t->text);
+              if (ConfigDescription::Parse(text, &config_descriptor)) {
+                // Copy the density with the minimum SDK version stripped out.
+                group.push_back(config_descriptor.CopyWithoutSdkVersion());
+              } else {
+                diag->Error(
+                    DiagMessage() << "Could not parse config descriptor for screen-density: "
+                                  << text);
+                valid = false;
+              }
+              break;
+            }
+          }
+        }
+      }
+
+      return valid;
+    };
+
+ConfigurationParser::ActionHandler ConfigurationParser::locale_group_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      std::string label = GetLabel(root_element, diag);
+      if (label.empty()) {
+        return false;
+      }
+
+      auto& group = config->locale_groups[label];
+      bool valid = true;
+
+      for (auto* child : root_element->GetChildElements()) {
+        if (child->name != "locale") {
+          diag->Error(
+              DiagMessage() << "Unexpected root_element in screen density group: "
+                            << child->name);
+          valid = false;
+        } else {
+          Locale entry;
+          for (const auto& attr : child->attributes) {
+            if (attr.name == "lang") {
+              entry.lang = {attr.value};
+            } else if (attr.name == "region") {
+              entry.region = {attr.value};
+            } else {
+              diag->Warn(DiagMessage() << "Unknown attribute: " << attr.name
+                                       << " = " << attr.value);
+            }
+          }
+          group.push_back(entry);
+        }
+      }
+
+      return valid;
+    };
+
+ConfigurationParser::ActionHandler ConfigurationParser::android_sdk_group_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      std::string label = GetLabel(root_element, diag);
+      if (label.empty()) {
+        return false;
+      }
+
+      auto& group = config->android_sdk_groups[label];
+      bool valid = true;
+
+      for (auto* child : root_element->GetChildElements()) {
+        if (child->name != "android-sdk") {
+          diag->Error(
+              DiagMessage() << "Unexpected root_element in ABI group: " << child->name);
+          valid = false;
+        } else {
+          AndroidSdk entry;
+          for (const auto& attr : child->attributes) {
+            if (attr.name == "minSdkVersion") {
+              entry.min_sdk_version = {attr.value};
+            } else if (attr.name == "targetSdkVersion") {
+              entry.target_sdk_version = {attr.value};
+            } else if (attr.name == "maxSdkVersion") {
+              entry.max_sdk_version = {attr.value};
+            } else {
+              diag->Warn(DiagMessage() << "Unknown attribute: " << attr.name
+                                       << " = " << attr.value);
+            }
+          }
+
+          // TODO: Fill in the manifest details when they are finalised.
+          for (auto node : child->GetChildElements()) {
+            if (node->name == "manifest") {
+              if (entry.manifest) {
+                diag->Warn(DiagMessage() << "Found multiple manifest tags. Ignoring duplicates.");
+                continue;
+              }
+              entry.manifest = {AndroidManifest()};
+            }
+          }
+
+          group.push_back(entry);
+        }
+      }
+
+      return valid;
+    };
+
+ConfigurationParser::ActionHandler ConfigurationParser::gl_texture_group_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      std::string label = GetLabel(root_element, diag);
+      if (label.empty()) {
+        return false;
+      }
+
+      auto& group = config->gl_texture_groups[label];
+      bool valid = true;
+
+      GlTexture result;
+      for (auto* child : root_element->GetChildElements()) {
+        if (child->name != "gl-texture") {
+          diag->Error(
+              DiagMessage() << "Unexpected element in GL texture group: "
+                            << child->name);
+          valid = false;
+        } else {
+          for (const auto& attr : child->attributes) {
+            if (attr.name == "name") {
+              result.name = attr.value;
+              break;
+            }
+          }
+
+          for (auto* element : child->GetChildElements()) {
+            if (element->name != "texture-path") {
+              diag->Error(
+                  DiagMessage() << "Unexpected element in gl-texture element: "
+                                << child->name);
+              valid = false;
+              continue;
+            }
+            for (auto& node : element->children) {
+              xml::Text* t;
+              if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+                result.texture_paths.push_back(TrimWhitespace(t->text).to_string());
+              }
+            }
+          }
+        }
+        group.push_back(result);
+      }
+
+      return valid;
+    };
+
+ConfigurationParser::ActionHandler ConfigurationParser::device_feature_group_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      std::string label = GetLabel(root_element, diag);
+      if (label.empty()) {
+        return false;
+      }
+
+      auto& group = config->device_feature_groups[label];
+      bool valid = true;
+
+      for (auto* child : root_element->GetChildElements()) {
+        if (child->name != "supports-feature") {
+          diag->Error(
+              DiagMessage() << "Unexpected root_element in device feature group: "
+                            << child->name);
+          valid = false;
+        } else {
+          for (auto& node : child->children) {
+            xml::Text* t;
+            if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+              group.push_back(TrimWhitespace(t->text).to_string());
+              break;
+            }
+          }
+        }
+      }
+
+      return valid;
+    };
+
+}  // namespace aapt
diff --git a/tools/aapt2/configuration/ConfigurationParser.h b/tools/aapt2/configuration/ConfigurationParser.h
new file mode 100644
index 0000000..0fb2f71
--- /dev/null
+++ b/tools/aapt2/configuration/ConfigurationParser.h
@@ -0,0 +1,216 @@
+/*
+ * 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.
+ */
+
+#ifndef AAPT2_CONFIGURATION_H
+#define AAPT2_CONFIGURATION_H
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+#include <ConfigDescription.h>
+
+#include "util/Maybe.h"
+
+namespace aapt {
+
+namespace configuration {
+
+/** A mapping of group labels to group of configuration items. */
+template<class T>
+using Group = std::unordered_map<std::string, std::vector<T>>;
+
+/** Output artifact configuration options. */
+struct Artifact {
+  /** Name to use for output of processing foo.apk -> foo.<name>.apk. */
+  std::string name;
+  /** If present, uses the ABI group with this name. */
+  Maybe<std::string> abi_group;
+  /** If present, uses the screen density group with this name. */
+  Maybe<std::string> screen_density_group;
+  /** If present, uses the locale group with this name. */
+  Maybe<std::string> locale_group;
+  /** If present, uses the Android SDK group with this name. */
+  Maybe<std::string> android_sdk_group;
+  /** If present, uses the device feature group with this name. */
+  Maybe<std::string> device_feature_group;
+  /** If present, uses the OpenGL texture group with this name. */
+  Maybe<std::string> gl_texture_group;
+};
+
+/** Enumeration of currently supported ABIs. */
+enum class Abi {
+  kArmeV6,
+  kArmV7a,
+  kArm64V8a,
+  kX86,
+  kX86_64,
+  kMips,
+  kMips64,
+  kUniversal
+};
+
+/**
+ * Represents an individual locale. When a locale is included, it must be
+ * declared from least specific to most specific, as a region does not make
+ * sense without a language. If neither the language or region are specified it
+ * acts as a special case for catch all. This can allow all locales to be kept,
+ * or compressed.
+ */
+struct Locale {
+  /** The ISO<?> standard locale language code. */
+  Maybe<std::string> lang;
+  /** The ISO<?> standard locale region code. */
+  Maybe<std::string> region;
+
+  inline friend bool operator==(const Locale& lhs, const Locale& rhs) {
+    return lhs.lang == rhs.lang && lhs.region == rhs.region;
+  }
+};
+
+// TODO: Encapsulate manifest modifications from the configuration file.
+struct AndroidManifest {
+  inline friend bool operator==(const AndroidManifest& lhs, const AndroidManifest& rhs) {
+    return true;  // nothing to compare yet.
+  }
+};
+
+struct AndroidSdk {
+  Maybe<std::string> min_sdk_version;
+  Maybe<std::string> target_sdk_version;
+  Maybe<std::string> max_sdk_version;
+  Maybe<AndroidManifest> manifest;
+
+  inline friend bool operator==(const AndroidSdk& lhs, const AndroidSdk& rhs) {
+    return lhs.min_sdk_version == rhs.min_sdk_version &&
+        lhs.target_sdk_version == rhs.target_sdk_version &&
+        lhs.max_sdk_version == rhs.max_sdk_version &&
+        lhs.manifest == rhs.manifest;
+  }
+};
+
+// TODO: Make device features more than just an arbitrary string?
+using DeviceFeature = std::string;
+
+/** Represents a mapping of texture paths to a GL texture format. */
+struct GlTexture {
+  std::string name;
+  std::vector<std::string> texture_paths;
+
+  inline friend bool operator==(const GlTexture& lhs, const GlTexture& rhs) {
+    return lhs.name == rhs.name && lhs.texture_paths == rhs.texture_paths;
+  }
+};
+
+/**
+ * AAPT2 XML configuration binary representation.
+ */
+struct Configuration {
+  std::unordered_map<std::string, Artifact> artifacts;
+  Maybe<std::string> artifact_format;
+
+  Group<Abi> abi_groups;
+  Group<ConfigDescription> screen_density_groups;
+  Group<Locale> locale_groups;
+  Group<AndroidSdk> android_sdk_groups;
+  Group<DeviceFeature> device_feature_groups;
+  Group<GlTexture> gl_texture_groups;
+};
+
+}  // namespace configuration
+
+// Forward declaration of classes used in the API.
+struct IDiagnostics;
+namespace xml {
+class Element;
+}
+
+/**
+ * XML configuration file parser for the split and optimize commands.
+ */
+class ConfigurationParser {
+ public:
+  /** Returns a ConfigurationParser for the configuration in the provided file contents. */
+  static ConfigurationParser ForContents(const std::string& contents) {
+    ConfigurationParser parser{contents};
+    return parser;
+  }
+
+  /** Returns a ConfigurationParser for the file located at the provided path. */
+  static ConfigurationParser ForPath(const std::string& path) {
+    // TODO: Read XML file into memory.
+    return ForContents(path);
+  }
+
+  /** Sets the diagnostics context to use when parsing. */
+  ConfigurationParser& WithDiagnostics(IDiagnostics* diagnostics) {
+    diag_ = diagnostics;
+    return *this;
+  }
+
+  /**
+   * Parses the configuration file and returns the results. If the configuration could not be parsed
+   * the result is empty and any errors will be displayed with the provided diagnostics context.
+   */
+  Maybe<configuration::Configuration> Parse();
+
+ protected:
+  /**
+   * Instantiates a new ConfigurationParser with the provided configuration file and a no-op
+   * diagnostics context. The default diagnostics context can be overridden with a call to
+   * WithDiagnostics(IDiagnostics *).
+   */
+  explicit ConfigurationParser(std::string contents);
+
+  /** Returns the current diagnostics context to any subclasses. */
+  IDiagnostics* diagnostics() {
+    return diag_;
+  }
+
+  /**
+   * An ActionHandler for processing XML elements in the XmlActionExecutor. Returns true if the
+   * element was successfully processed, otherwise returns false.
+   */
+  using ActionHandler = std::function<bool(configuration::Configuration* config,
+                                           xml::Element* element,
+                                           IDiagnostics* diag)>;
+
+  /** Handler for <artifact> tags. */
+  static ActionHandler artifact_handler_;
+  /** Handler for <artifact-format> tags. */
+  static ActionHandler artifact_format_handler_;
+  /** Handler for <abi-group> tags. */
+  static ActionHandler abi_group_handler_;
+  /** Handler for <screen-density-group> tags. */
+  static ActionHandler screen_density_group_handler_;
+  /** Handler for <locale-group> tags. */
+  static ActionHandler locale_group_handler_;
+  /** Handler for <android-sdk-group> tags. */
+  static ActionHandler android_sdk_group_handler_;
+  /** Handler for <gl-texture-group> tags. */
+  static ActionHandler gl_texture_group_handler_;
+  /** Handler for <device-feature-group> tags. */
+  static ActionHandler device_feature_group_handler_;
+
+ private:
+  /** The contents of the configuration file to parse. */
+  const std::string contents_;
+  /** The diagnostics context to send messages to. */
+  IDiagnostics* diag_;
+};
+
+}  // namespace aapt
+
+#endif //AAPT2_CONFIGURATION_H
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
new file mode 100644
index 0000000..72a97b2
--- /dev/null
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "configuration/ConfigurationParser.h"
+
+#include <string>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "androidfw/ResourceTypes.h"
+
+#include "test/Test.h"
+#include "xml/XmlDom.h"
+
+namespace aapt {
+namespace {
+
+using android::ResTable_config;
+using configuration::Abi;
+using configuration::AndroidSdk;
+using configuration::Configuration;
+using configuration::DeviceFeature;
+using configuration::GlTexture;
+using configuration::Locale;
+using configuration::AndroidManifest;
+using testing::ElementsAre;
+using xml::Element;
+using xml::NodeCast;
+
+constexpr const char* kValidConfig = R"(<?xml version="1.0" encoding="utf-8" ?>
+<post-process xmlns="http://schemas.android.com/tools/aapt">
+  <groups>
+    <abi-group label="arm">
+      <abi>armeabi-v7a</abi>
+      <abi>arm64-v8a</abi>
+    </abi-group>
+    <abi-group label="other">
+      <abi>x86</abi>
+      <abi>mips</abi>
+    </abi-group>
+    <screen-density-group label="large">
+      <screen-density>xhdpi</screen-density>
+      <screen-density>xxhdpi</screen-density>
+      <screen-density>xxxhdpi</screen-density>
+    </screen-density-group>
+    <screen-density-group label="alldpi">
+      <screen-density>ldpi</screen-density>
+      <screen-density>mdpi</screen-density>
+      <screen-density>hdpi</screen-density>
+      <screen-density>xhdpi</screen-density>
+      <screen-density>xxhdpi</screen-density>
+      <screen-density>xxxhdpi</screen-density>
+    </screen-density-group>
+    <locale-group label="europe">
+      <locale lang="en"/>
+      <locale lang="es"/>
+      <locale lang="fr"/>
+      <locale lang="de"/>
+    </locale-group>
+    <locale-group label="north-america">
+      <locale lang="en"/>
+      <locale lang="es" region="MX"/>
+      <locale lang="fr" region="CA"/>
+    </locale-group>
+    <locale-group label="all">
+      <locale/>
+    </locale-group>
+    <android-sdk-group label="19">
+      <android-sdk
+          minSdkVersion="19"
+          targetSdkVersion="24"
+          maxSdkVersion="25">
+        <manifest>
+          <!--- manifest additions here XSLT? TODO -->
+        </manifest>
+      </android-sdk>
+    </android-sdk-group>
+    <gl-texture-group label="dxt1">
+      <gl-texture name="GL_EXT_texture_compression_dxt1">
+        <texture-path>assets/dxt1/*</texture-path>
+      </gl-texture>
+    </gl-texture-group>
+    <device-feature-group label="low-latency">
+      <supports-feature>android.hardware.audio.low_latency</supports-feature>
+    </device-feature-group>
+  </groups>
+  <artifacts>
+    <artifact-format>
+      ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
+    </artifact-format>
+    <artifact
+        name="art1"
+        abi-group="arm"
+        screen-density-group="large"
+        locale-group="europe"
+        android-sdk-group="19"
+        gl-texture-group="dxt1"
+        device-feature-group="low-latency"/>
+    <artifact
+        name="art2"
+        abi-group="other"
+        screen-density-group="alldpi"
+        locale-group="north-america"
+        android-sdk-group="19"
+        gl-texture-group="dxt1"
+        device-feature-group="low-latency"/>
+  </artifacts>
+</post-process>
+)";
+
+class ConfigurationParserTest : public ConfigurationParser, public ::testing::Test {
+ public:
+  ConfigurationParserTest() : ConfigurationParser("") {}
+
+ protected:
+  StdErrDiagnostics diag_;
+};
+
+TEST_F(ConfigurationParserTest, ValidateFile) {
+  auto parser = ConfigurationParser::ForContents(kValidConfig).WithDiagnostics(&diag_);
+  auto result = parser.Parse();
+  ASSERT_TRUE(result);
+  Configuration& value = result.value();
+  EXPECT_EQ(2ul, value.artifacts.size());
+  ASSERT_TRUE(value.artifact_format);
+  EXPECT_EQ(
+      "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
+      value.artifact_format.value()
+  );
+
+  EXPECT_EQ(2ul, value.abi_groups.size());
+  EXPECT_EQ(2ul, value.abi_groups["arm"].size());
+  EXPECT_EQ(2ul, value.abi_groups["other"].size());
+
+  EXPECT_EQ(2ul, value.screen_density_groups.size());
+  EXPECT_EQ(3ul, value.screen_density_groups["large"].size());
+  EXPECT_EQ(6ul, value.screen_density_groups["alldpi"].size());
+
+  EXPECT_EQ(3ul, value.locale_groups.size());
+  EXPECT_EQ(4ul, value.locale_groups["europe"].size());
+  EXPECT_EQ(3ul, value.locale_groups["north-america"].size());
+  EXPECT_EQ(1ul, value.locale_groups["all"].size());
+
+  EXPECT_EQ(1ul, value.android_sdk_groups.size());
+  EXPECT_EQ(1ul, value.android_sdk_groups["19"].size());
+
+  EXPECT_EQ(1ul, value.gl_texture_groups.size());
+  EXPECT_EQ(1ul, value.gl_texture_groups["dxt1"].size());
+
+  EXPECT_EQ(1ul, value.device_feature_groups.size());
+  EXPECT_EQ(1ul, value.device_feature_groups["low-latency"].size());
+}
+
+TEST_F(ConfigurationParserTest, InvalidNamespace) {
+  constexpr const char* invalid_ns = R"(<?xml version="1.0" encoding="utf-8" ?>
+  <post-process xmlns="http://schemas.android.com/tools/another-unknown-tool" />)";
+
+  auto result = ConfigurationParser::ForContents(invalid_ns).Parse();
+  ASSERT_FALSE(result);
+}
+
+TEST_F(ConfigurationParserTest, ArtifactAction) {
+  static constexpr const char* xml = R"xml(
+    <artifact
+        abi-group="arm"
+        screen-density-group="large"
+        locale-group="europe"
+        android-sdk-group="19"
+        gl-texture-group="dxt1"
+        device-feature-group="low-latency"/>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok = artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+
+  EXPECT_EQ(1ul, config.artifacts.size());
+
+  auto& artifact = config.artifacts.begin()->second;
+  EXPECT_EQ("", artifact.name); // TODO: make this fail.
+  EXPECT_EQ("arm", artifact.abi_group.value());
+  EXPECT_EQ("large", artifact.screen_density_group.value());
+  EXPECT_EQ("europe", artifact.locale_group.value());
+  EXPECT_EQ("19", artifact.android_sdk_group.value());
+  EXPECT_EQ("dxt1", artifact.gl_texture_group.value());
+  EXPECT_EQ("low-latency", artifact.device_feature_group.value());
+}
+
+TEST_F(ConfigurationParserTest, ArtifactFormatAction) {
+  static constexpr const char* xml = R"xml(
+    <artifact-format>
+      ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
+    </artifact-format>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok = artifact_format_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+  ASSERT_TRUE(config.artifact_format);
+  EXPECT_EQ(
+      "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
+      static_cast<std::string>(config.artifact_format.value())
+  );
+}
+
+TEST_F(ConfigurationParserTest, AbiGroupAction) {
+  static constexpr const char* xml = R"xml(
+    <abi-group label="arm">
+      <!-- First comment. -->
+      <abi>
+        armeabi-v7a
+      </abi>
+      <!-- Another comment. -->
+      <abi>arm64-v8a</abi>
+    </abi-group>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok = abi_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+
+  EXPECT_EQ(1ul, config.abi_groups.size());
+  ASSERT_EQ(1u, config.abi_groups.count("arm"));
+
+  auto& out = config.abi_groups["arm"];
+  ASSERT_THAT(out, ElementsAre(Abi::kArmV7a, Abi::kArm64V8a));
+}
+
+TEST_F(ConfigurationParserTest, ScreenDensityGroupAction) {
+  static constexpr const char* xml = R"xml(
+    <screen-density-group label="large">
+      <screen-density>xhdpi</screen-density>
+      <screen-density>
+        xxhdpi
+      </screen-density>
+      <screen-density>xxxhdpi</screen-density>
+    </screen-density-group>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok =
+      screen_density_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+
+  EXPECT_EQ(1ul, config.screen_density_groups.size());
+  ASSERT_EQ(1u, config.screen_density_groups.count("large"));
+
+  ConfigDescription xhdpi;
+  xhdpi.density = ResTable_config::DENSITY_XHIGH;
+  ConfigDescription xxhdpi;
+  xxhdpi.density = ResTable_config::DENSITY_XXHIGH;
+  ConfigDescription xxxhdpi;
+  xxxhdpi.density = ResTable_config::DENSITY_XXXHIGH;
+
+  auto& out = config.screen_density_groups["large"];
+  ASSERT_THAT(out, ElementsAre(xhdpi, xxhdpi, xxxhdpi));
+}
+
+TEST_F(ConfigurationParserTest, LocaleGroupAction) {
+  static constexpr const char* xml = R"xml(
+    <locale-group label="europe">
+      <locale lang="en"/>
+      <locale lang="es"/>
+      <locale lang="fr"/>
+      <locale lang="de"/>
+    </locale-group>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok = locale_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+
+  ASSERT_EQ(1ul, config.locale_groups.size());
+  ASSERT_EQ(1u, config.locale_groups.count("europe"));
+
+  auto& out = config.locale_groups["europe"];
+
+  Locale en;
+  en.lang = std::string("en");
+  Locale es;
+  es.lang = std::string("es");
+  Locale fr;
+  fr.lang = std::string("fr");
+  Locale de;
+  de.lang = std::string("de");
+
+  ASSERT_THAT(out, ElementsAre(en, es, fr, de));
+}
+
+TEST_F(ConfigurationParserTest, AndroidSdkGroupAction) {
+  static constexpr const char* xml = R"xml(
+    <android-sdk-group label="19">
+      <android-sdk
+          minSdkVersion="19"
+          targetSdkVersion="24"
+          maxSdkVersion="25">
+        <manifest>
+          <!--- manifest additions here XSLT? TODO -->
+        </manifest>
+      </android-sdk>
+    </android-sdk-group>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+
+  ASSERT_EQ(1ul, config.android_sdk_groups.size());
+  ASSERT_EQ(1u, config.android_sdk_groups.count("19"));
+
+  auto& out = config.android_sdk_groups["19"];
+
+  AndroidSdk sdk;
+  sdk.min_sdk_version = std::string("19");
+  sdk.target_sdk_version = std::string("24");
+  sdk.max_sdk_version = std::string("25");
+  sdk.manifest = AndroidManifest();
+
+  ASSERT_EQ(1ul, out.size());
+  ASSERT_EQ(sdk, out[0]);
+}
+
+TEST_F(ConfigurationParserTest, GlTextureGroupAction) {
+  static constexpr const char* xml = R"xml(
+    <gl-texture-group label="dxt1">
+      <gl-texture name="GL_EXT_texture_compression_dxt1">
+        <texture-path>assets/dxt1/main/*</texture-path>
+        <texture-path>
+          assets/dxt1/test/*
+        </texture-path>
+      </gl-texture>
+    </gl-texture-group>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok = gl_texture_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+
+  EXPECT_EQ(1ul, config.gl_texture_groups.size());
+  ASSERT_EQ(1u, config.gl_texture_groups.count("dxt1"));
+
+  auto& out = config.gl_texture_groups["dxt1"];
+
+  GlTexture texture{
+      std::string("GL_EXT_texture_compression_dxt1"),
+      {"assets/dxt1/main/*", "assets/dxt1/test/*"}
+  };
+
+  ASSERT_EQ(1ul, out.size());
+  ASSERT_EQ(texture, out[0]);
+}
+
+TEST_F(ConfigurationParserTest, DeviceFeatureGroupAction) {
+  static constexpr const char* xml = R"xml(
+    <device-feature-group label="low-latency">
+      <supports-feature>android.hardware.audio.low_latency</supports-feature>
+      <supports-feature>
+        android.hardware.audio.pro
+      </supports-feature>
+    </device-feature-group>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok
+      = device_feature_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+
+  EXPECT_EQ(1ul, config.device_feature_groups.size());
+  ASSERT_EQ(1u, config.device_feature_groups.count("low-latency"));
+
+  auto& out = config.device_feature_groups["low-latency"];
+
+  DeviceFeature low_latency = "android.hardware.audio.low_latency";
+  DeviceFeature pro = "android.hardware.audio.pro";
+  ASSERT_THAT(out, ElementsAre(low_latency, pro));
+}
+
+}  // namespace
+}  // namespace aapt
diff --git a/tools/aapt2/configuration/aapt2.xsd b/tools/aapt2/configuration/aapt2.xsd
new file mode 100644
index 0000000..47bf99e
--- /dev/null
+++ b/tools/aapt2/configuration/aapt2.xsd
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<xsd:schema
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    elementFormDefault="qualified"
+    xmlns="http://schemas.android.com/tools/aapt2"
+    targetNamespace="http://schemas.android.com/tools/aapt2">
+
+  <xsd:element name="post-process">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element name="groups" type="groups"/>
+        <xsd:element name="artifacts" type="artifacts"/>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+
+  <xsd:complexType name="groups">
+    <xsd:sequence>
+      <xsd:element name="abi-group" type="abi-group" maxOccurs="unbounded"/>
+      <xsd:element name="screen-density-group" type="screen-density-group" maxOccurs="unbounded"/>
+      <xsd:element name="locale-group" type="locale-group" maxOccurs="unbounded"/>
+      <xsd:element name="android-sdk-group" type="android-sdk-group" maxOccurs="unbounded"/>
+      <xsd:element
+          name="gl-texture-group"
+          type="gl-texture-group"
+          maxOccurs="unbounded"/>
+      <xsd:element name="device-feature-group" type="device-feature-group" maxOccurs="unbounded"/>
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="artifacts">
+    <xsd:sequence>
+      <xsd:element name="artifact-format" type="xsd:string"/>
+      <xsd:element name="artifact" type="artifact" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="generate-all" type="xsd:boolean"/>
+  </xsd:complexType>
+
+  <!-- Groups output artifacts together by dimension labels. -->
+  <xsd:complexType name="artifact">
+    <xsd:attribute name="name" type="xsd:string"/>
+    <xsd:attribute name="abi-group" type="xsd:string"/>
+    <xsd:attribute name="android-sdk-group" type="xsd:string"/>
+    <xsd:attribute name="device-feature-group" type="xsd:string"/>
+    <xsd:attribute name="gl-texture-group" type="xsd:string"/>
+    <xsd:attribute name="screen-density-group" type="xsd:string"/>
+    <xsd:attribute name="locale-group" type="xsd:string"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="gl-texture-group">
+    <xsd:sequence>
+      <xsd:element name="gl-texture" type="gl-texture" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="label" type="xsd:string" use="optional"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="gl-texture">
+    <xsd:sequence>
+      <xsd:element name="texture-path" type="xsd:string" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="device-feature-group">
+    <xsd:sequence>
+      <xsd:element name="supports-feature" type="xsd:string" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="label" type="xsd:string" use="optional"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="abi-group">
+    <xsd:sequence>
+      <xsd:element name="abi" type="abi-name" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="label" type="xsd:string" use="optional"/>
+  </xsd:complexType>
+
+  <xsd:simpleType name="abi-name">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="armeabi"/>
+      <xsd:enumeration value="armeabi-v7a"/>
+      <xsd:enumeration value="arm64-v8a"/>
+      <xsd:enumeration value="x86"/>
+      <xsd:enumeration value="x86_64"/>
+      <xsd:enumeration value="mips"/>
+      <xsd:enumeration value="mips64"/>
+      <xsd:enumeration value="fat"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+
+  <xsd:complexType name="screen-density-group">
+    <xsd:sequence>
+      <xsd:element name="screen-density" type="screen-density" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="label" type="xsd:string" use="optional"/>
+  </xsd:complexType>
+
+  <xsd:simpleType name="screen-density">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="alldpi"/>
+      <xsd:enumeration value="ldpi"/>
+      <xsd:enumeration value="mdpi"/>
+      <xsd:enumeration value="hdpi"/>
+      <xsd:enumeration value="xhdpi"/>
+      <xsd:enumeration value="xxhdpi"/>
+      <xsd:enumeration value="xxxhdpi"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+
+  <xsd:complexType name="android-sdk-group">
+    <xsd:sequence>
+      <xsd:element name="android-sdk" type="android-sdk" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="label" type="xsd:string" use="optional"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="android-sdk">
+    <!-- TODO(safarmer): Add permissions to add/remove. -->
+    <!-- TODO(safarmer): Add option for uncompressed native libs. -->
+    <xsd:sequence>
+      <xsd:element name="manifest" type="manifest"/>
+    </xsd:sequence>
+    <xsd:attribute name="minSdkVersion" type="xsd:integer"/>
+    <xsd:attribute name="targetSdkVersion" type="xsd:integer"/>
+    <xsd:attribute name="maxSdkVersion" type="xsd:integer"/>
+  </xsd:complexType>
+
+  <!-- TODO(safarmer): Figure out the best way to handle manifest updates. -->
+  <xsd:simpleType name="manifest">
+    <xsd:restriction base="xsd:string"/>
+  </xsd:simpleType>
+
+  <xsd:complexType name="locale-group">
+    <xsd:sequence>
+      <xsd:element name="locale" type="locale" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="label" type="xsd:string" use="optional"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="locale">
+    <xsd:attribute name="lang" type="xsd:string"/>
+    <xsd:attribute name="region" type="xsd:string"/>
+    <xsd:attribute name="compressed" type="xsd:boolean"/>
+  </xsd:complexType>
+
+</xsd:schema>
diff --git a/tools/aapt2/configuration/example/config.xml b/tools/aapt2/configuration/example/config.xml
new file mode 100644
index 0000000..a8360f8
--- /dev/null
+++ b/tools/aapt2/configuration/example/config.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<post-process xmlns="http://schemas.android.com/tools/aapt2">
+  <groups>
+    <abi-group label="arm">
+      <abi>armeabi-v7a</abi>
+      <abi>arm64-v8a</abi>
+    </abi-group>
+
+    <abi-group label="other">
+      <abi>x86</abi>
+      <abi>mips</abi>
+    </abi-group>
+
+    <screen-density-group label="large">
+      <screen-density>xhdpi</screen-density>
+      <screen-density>xxhdpi</screen-density>
+      <screen-density>xxxhdpi</screen-density>
+    </screen-density-group>
+
+    <screen-density-group label="alldpi">
+      <screen-density>ldpi</screen-density>
+      <screen-density>mdpi</screen-density>
+      <screen-density>hdpi</screen-density>
+      <screen-density>xhdpi</screen-density>
+      <screen-density>xxhdpi</screen-density>
+      <screen-density>xxxhdpi</screen-density>
+    </screen-density-group>
+
+    <locale-group label="europe">
+      <locale lang="en"/>
+      <locale lang="es"/>
+      <locale lang="fr"/>
+      <locale lang="de" compressed="true"/>
+    </locale-group>
+
+    <locale-group label="north-america">
+      <locale lang="en"/>
+      <locale lang="es" region="MX"/>
+      <locale lang="fr" region="CA" compressed="true"/>
+    </locale-group>
+
+    <locale-group label="all">
+      <locale compressed="true"/>
+    </locale-group>
+
+    <android-sdk-group label="19">
+      <android-sdk
+          minSdkVersion="19"
+          targetSdkVersion="24"
+          maxSdkVersion="25">
+        <manifest>
+          <!--- manifest additions here XSLT? TODO -->
+        </manifest>
+      </android-sdk>
+    </android-sdk-group>
+
+    <gl-texture-group label="dxt1">
+      <gl-texture name="GL_EXT_texture_compression_dxt1">
+        <texture-path>assets/dxt1/*</texture-path>
+      </gl-texture>
+    </gl-texture-group>
+
+    <device-feature-group label="low-latency">
+      <supports-feature>android.hardware.audio.low_latency</supports-feature>
+    </device-feature-group>
+  </groups>
+
+  <artifacts>
+    <artifact-format>
+      ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
+    </artifact-format>
+
+    <artifact
+        abi-group="arm"
+        screen-density-group="large"
+        locale-group="europe"
+        android-sdk-group="19"
+        gl-texture-group="dxt1"
+        device-feature-group="low-latency"/>
+
+    <artifact
+        abi-group="other"
+        screen-density-group="alldpi"
+        locale-group="north-america"
+        android-sdk-group="19"
+        gl-texture-group="dxt1"
+        device-feature-group="low-latency"/>
+
+  </artifacts>
+</post-process>
diff --git a/tools/aapt2/flatten/XmlFlattener.cpp b/tools/aapt2/flatten/XmlFlattener.cpp
index 0711749..bfebedef 100644
--- a/tools/aapt2/flatten/XmlFlattener.cpp
+++ b/tools/aapt2/flatten/XmlFlattener.cpp
@@ -257,9 +257,11 @@
 
       // Process plain strings to make sure they get properly escaped.
       StringPiece raw_value = xml_attr->value;
-      util::StringBuilder str_builder;
+
+      util::StringBuilder str_builder(true /*preserve_spaces*/);
+      str_builder.Append(xml_attr->value);
+
       if (!options_.keep_raw_values) {
-        str_builder.Append(xml_attr->value);
         raw_value = str_builder.ToString();
       }
 
diff --git a/tools/aapt2/flatten/XmlFlattener_test.cpp b/tools/aapt2/flatten/XmlFlattener_test.cpp
index f1e903f..a57e317 100644
--- a/tools/aapt2/flatten/XmlFlattener_test.cpp
+++ b/tools/aapt2/flatten/XmlFlattener_test.cpp
@@ -23,7 +23,13 @@
 #include "util/BigBuffer.h"
 #include "util/Util.h"
 
-using android::StringPiece16;
+using ::aapt::test::StrEq;
+using ::android::StringPiece16;
+using ::testing::Eq;
+using ::testing::Ge;
+using ::testing::IsNull;
+using ::testing::Ne;
+using ::testing::NotNull;
 
 namespace aapt {
 
@@ -72,163 +78,138 @@
 };
 
 TEST_F(XmlFlattenerTest, FlattenXmlWithNoCompiledAttributes) {
-  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
-            <View xmlns:test="http://com.test"
-                  attr="hey">
-              <Layout test:hello="hi" />
-              <Layout>Some text\\</Layout>
-            </View>)EOF");
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(
+      <View xmlns:test="http://com.test" attr="hey">
+          <Layout test:hello="hi" />
+          <Layout>Some text\\</Layout>
+      </View>)");
 
   android::ResXMLTree tree;
   ASSERT_TRUE(Flatten(doc.get(), &tree));
-
-  ASSERT_EQ(android::ResXMLTree::START_NAMESPACE, tree.next());
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_NAMESPACE));
 
   size_t len;
-  const char16_t* namespace_prefix = tree.getNamespacePrefix(&len);
-  EXPECT_EQ(StringPiece16(u"test"), StringPiece16(namespace_prefix, len));
+  EXPECT_THAT(tree.getNamespacePrefix(&len), StrEq(u"test"));
+  EXPECT_THAT(tree.getNamespaceUri(&len), StrEq(u"http://com.test"));
 
-  const char16_t* namespace_uri = tree.getNamespaceUri(&len);
-  ASSERT_EQ(StringPiece16(u"http://com.test"), StringPiece16(namespace_uri, len));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementNamespace(&len), IsNull());
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"View"));
 
-  ASSERT_EQ(android::ResXMLTree::START_TAG, tree.next());
+  ASSERT_THAT(tree.getAttributeCount(), Eq(1u));
+  EXPECT_THAT(tree.getAttributeNamespace(0, &len), IsNull());
+  EXPECT_THAT(tree.getAttributeName(0, &len), StrEq(u"attr"));
 
-  ASSERT_EQ(nullptr, tree.getElementNamespace(&len));
-  const char16_t* tag_name = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(u"View"), StringPiece16(tag_name, len));
+  const StringPiece16 kAttr(u"attr");
+  EXPECT_THAT(tree.indexOfAttribute(nullptr, 0, kAttr.data(), kAttr.size()), Eq(0));
 
-  ASSERT_EQ(1u, tree.getAttributeCount());
-  ASSERT_EQ(nullptr, tree.getAttributeNamespace(0, &len));
-  const char16_t* attr_name = tree.getAttributeName(0, &len);
-  EXPECT_EQ(StringPiece16(u"attr"), StringPiece16(attr_name, len));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementNamespace(&len), IsNull());
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"Layout"));
 
-  EXPECT_EQ(0, tree.indexOfAttribute(nullptr, 0, u"attr", StringPiece16(u"attr").size()));
+  ASSERT_THAT(tree.getAttributeCount(), Eq(1u));
+  EXPECT_THAT(tree.getAttributeNamespace(0, &len), StrEq(u"http://com.test"));
+  EXPECT_THAT(tree.getAttributeName(0, &len), StrEq(u"hello"));
 
-  ASSERT_EQ(android::ResXMLTree::START_TAG, tree.next());
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
 
-  ASSERT_EQ(nullptr, tree.getElementNamespace(&len));
-  tag_name = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(u"Layout"), StringPiece16(tag_name, len));
+  EXPECT_THAT(tree.getElementNamespace(&len), IsNull());
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"Layout"));
+  ASSERT_THAT(tree.getAttributeCount(), Eq(0u));
 
-  ASSERT_EQ(1u, tree.getAttributeCount());
-  const char16_t* attr_namespace = tree.getAttributeNamespace(0, &len);
-  EXPECT_EQ(StringPiece16(u"http://com.test"), StringPiece16(attr_namespace, len));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u"Some text\\"));
 
-  attr_name = tree.getAttributeName(0, &len);
-  EXPECT_EQ(StringPiece16(u"hello"), StringPiece16(attr_name, len));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+  EXPECT_THAT(tree.getElementNamespace(&len), IsNull());
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"Layout"));
 
-  ASSERT_EQ(android::ResXMLTree::END_TAG, tree.next());
-  ASSERT_EQ(android::ResXMLTree::START_TAG, tree.next());
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+  EXPECT_THAT(tree.getElementNamespace(&len), IsNull());
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"View"));
 
-  ASSERT_EQ(nullptr, tree.getElementNamespace(&len));
-  tag_name = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(u"Layout"), StringPiece16(tag_name, len));
-  ASSERT_EQ(0u, tree.getAttributeCount());
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_NAMESPACE));
+  EXPECT_THAT(tree.getNamespacePrefix(&len), StrEq(u"test"));
+  EXPECT_THAT(tree.getNamespaceUri(&len), StrEq(u"http://com.test"));
 
-  ASSERT_EQ(android::ResXMLTree::TEXT, tree.next());
-  const char16_t* text = tree.getText(&len);
-  EXPECT_EQ(StringPiece16(u"Some text\\"), StringPiece16(text, len));
-
-  ASSERT_EQ(android::ResXMLTree::END_TAG, tree.next());
-  ASSERT_EQ(nullptr, tree.getElementNamespace(&len));
-  tag_name = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(u"Layout"), StringPiece16(tag_name, len));
-
-  ASSERT_EQ(android::ResXMLTree::END_TAG, tree.next());
-  ASSERT_EQ(nullptr, tree.getElementNamespace(&len));
-  tag_name = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(u"View"), StringPiece16(tag_name, len));
-
-  ASSERT_EQ(android::ResXMLTree::END_NAMESPACE, tree.next());
-  namespace_prefix = tree.getNamespacePrefix(&len);
-  EXPECT_EQ(StringPiece16(u"test"), StringPiece16(namespace_prefix, len));
-
-  namespace_uri = tree.getNamespaceUri(&len);
-  ASSERT_EQ(StringPiece16(u"http://com.test"), StringPiece16(namespace_uri, len));
-
-  ASSERT_EQ(android::ResXMLTree::END_DOCUMENT, tree.next());
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_DOCUMENT));
 }
 
 TEST_F(XmlFlattenerTest, FlattenCompiledXmlAndStripOnlyTools) {
-  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
-            <View xmlns:tools="http://schemas.android.com/tools"
-                xmlns:foo="http://schemas.android.com/foo"
-                foo:bar="Foo"
-                tools:ignore="MissingTranslation"/>)EOF");
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(
+      <View xmlns:tools="http://schemas.android.com/tools"
+          xmlns:foo="http://schemas.android.com/foo"
+          foo:bar="Foo"
+          tools:ignore="MissingTranslation"/>)");
 
   android::ResXMLTree tree;
   ASSERT_TRUE(Flatten(doc.get(), &tree));
-
-  ASSERT_EQ(tree.next(), android::ResXMLTree::START_NAMESPACE);
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_NAMESPACE));
 
   size_t len;
-  const char16_t* namespace_prefix = tree.getNamespacePrefix(&len);
-  EXPECT_EQ(StringPiece16(namespace_prefix, len), u"foo");
+  EXPECT_THAT(tree.getNamespacePrefix(&len), StrEq(u"foo"));
+  EXPECT_THAT(tree.getNamespaceUri(&len), StrEq(u"http://schemas.android.com/foo"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
 
-  const char16_t* namespace_uri = tree.getNamespaceUri(&len);
-  ASSERT_EQ(StringPiece16(namespace_uri, len),
-            u"http://schemas.android.com/foo");
-
-  ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG);
-
-  EXPECT_EQ(tree.indexOfAttribute("http://schemas.android.com/tools", "ignore"),
-            android::NAME_NOT_FOUND);
-  EXPECT_GE(tree.indexOfAttribute("http://schemas.android.com/foo", "bar"), 0);
+  EXPECT_THAT(tree.indexOfAttribute("http://schemas.android.com/tools", "ignore"),
+              Eq(android::NAME_NOT_FOUND));
+  EXPECT_THAT(tree.indexOfAttribute("http://schemas.android.com/foo", "bar"), Ge(0));
 }
 
 TEST_F(XmlFlattenerTest, AssignSpecialAttributeIndices) {
-  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
-            <View xmlns:android="http://schemas.android.com/apk/res/android"
-                  android:id="@id/id"
-                  class="str"
-                  style="@id/id"/>)EOF");
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(
+      <View xmlns:android="http://schemas.android.com/apk/res/android"
+          android:id="@id/id"
+          class="str"
+          style="@id/id"/>)");
 
   android::ResXMLTree tree;
   ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   while (tree.next() != android::ResXMLTree::START_TAG) {
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
   }
 
-  EXPECT_EQ(tree.indexOfClass(), 0);
-  EXPECT_EQ(tree.indexOfStyle(), 1);
+  EXPECT_THAT(tree.indexOfClass(), Eq(0));
+  EXPECT_THAT(tree.indexOfStyle(), Eq(1));
 }
 
 // The device ResXMLParser in libandroidfw differentiates between empty namespace and null
 // namespace.
 TEST_F(XmlFlattenerTest, NoNamespaceIsNotTheSameAsEmptyNamespace) {
-  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom("<View package=\"android\"/>");
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<View package="android"/>)");
 
   android::ResXMLTree tree;
   ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   while (tree.next() != android::ResXMLTree::START_TAG) {
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
   }
 
   const StringPiece16 kPackage = u"package";
-  EXPECT_GE(tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size()), 0);
+  EXPECT_THAT(tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size()), Ge(0));
 }
 
 TEST_F(XmlFlattenerTest, EmptyStringValueInAttributeIsNotNull) {
-  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom("<View package=\"\"/>");
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<View package=""/>)");
 
   android::ResXMLTree tree;
   ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   while (tree.next() != android::ResXMLTree::START_TAG) {
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
   }
 
   const StringPiece16 kPackage = u"package";
   ssize_t idx = tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size());
-  ASSERT_GE(idx, 0);
+  ASSERT_THAT(idx, Ge(0));
 
   size_t len;
-  EXPECT_NE(nullptr, tree.getAttributeStringValue(idx, &len));
+  EXPECT_THAT(tree.getAttributeStringValue(idx, &len), NotNull());
 }
 
 TEST_F(XmlFlattenerTest, FlattenNonStandardPackageId) {
@@ -236,11 +217,11 @@
   context_->SetPackageId(0x80);
   context_->SetNameManglerPolicy({"com.app.test.feature"});
 
-  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDomForPackageName(context_.get(), R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDomForPackageName(context_.get(), R"(
       <View xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:app="http://schemas.android.com/apk/res-auto"
             android:id="@id/foo"
-            app:foo="@id/foo" />)EOF");
+            app:foo="@id/foo" />)");
 
   XmlReferenceLinker linker;
   ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
@@ -253,59 +234,57 @@
   ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   while (tree.next() != android::ResXMLTree::START_TAG) {
-    ASSERT_NE(android::ResXMLTree::BAD_DOCUMENT, tree.getEventType());
-    ASSERT_NE(android::ResXMLTree::END_DOCUMENT, tree.getEventType());
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
   }
 
   ssize_t idx;
 
   idx = tree.indexOfAttribute(xml::kSchemaAndroid, "id");
-  ASSERT_GE(idx, 0);
-  EXPECT_EQ(idx, tree.indexOfID());
-  EXPECT_EQ(ResourceId(0x010100d0), ResourceId(tree.getAttributeNameResID(idx)));
+  ASSERT_THAT(idx, Ge(0));
+  EXPECT_THAT(tree.indexOfID(), Eq(idx));
+  EXPECT_THAT(tree.getAttributeNameResID(idx), Eq(0x010100d0u));
 
   idx = tree.indexOfAttribute(xml::kSchemaAuto, "foo");
-  ASSERT_GE(idx, 0);
-  EXPECT_EQ(ResourceId(0x80010000), ResourceId(tree.getAttributeNameResID(idx)));
-  EXPECT_EQ(android::Res_value::TYPE_REFERENCE, tree.getAttributeDataType(idx));
-  EXPECT_EQ(ResourceId(0x80020000), tree.getAttributeData(idx));
+  ASSERT_THAT(idx, Ge(0));
+  EXPECT_THAT(tree.getAttributeNameResID(idx), Eq(0x80010000u));
+  EXPECT_THAT(tree.getAttributeDataType(idx), Eq(android::Res_value::TYPE_REFERENCE));
+  EXPECT_THAT(tree.getAttributeData(idx), Eq(int32_t(0x80020000)));
 }
 
 TEST_F(XmlFlattenerTest, ProcessEscapedStrings) {
   std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(
-      R"EOF(<element value="\?hello" pattern="\\d{5}">\\d{5}</element>)EOF");
+      R"(<element value="\?hello" pattern="\\d{5}" other="&quot;">\\d{5}</element>)");
 
   android::ResXMLTree tree;
   ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   while (tree.next() != android::ResXMLTree::START_TAG) {
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
   }
 
   const StringPiece16 kValue = u"value";
   const StringPiece16 kPattern = u"pattern";
+  const StringPiece16 kOther = u"other";
 
   size_t len;
   ssize_t idx;
-  const char16_t* str16;
 
   idx = tree.indexOfAttribute(nullptr, 0, kValue.data(), kValue.size());
-  ASSERT_GE(idx, 0);
-  str16 = tree.getAttributeStringValue(idx, &len);
-  ASSERT_NE(nullptr, str16);
-  EXPECT_EQ(StringPiece16(u"?hello"), StringPiece16(str16, len));
+  ASSERT_THAT(idx, Ge(0));
+  EXPECT_THAT(tree.getAttributeStringValue(idx, &len), StrEq(u"?hello"));
 
   idx = tree.indexOfAttribute(nullptr, 0, kPattern.data(), kPattern.size());
-  ASSERT_GE(idx, 0);
-  str16 = tree.getAttributeStringValue(idx, &len);
-  ASSERT_NE(nullptr, str16);
-  EXPECT_EQ(StringPiece16(u"\\d{5}"), StringPiece16(str16, len));
+  ASSERT_THAT(idx, Ge(0));
+  EXPECT_THAT(tree.getAttributeStringValue(idx, &len), StrEq(u"\\d{5}"));
 
-  ASSERT_EQ(android::ResXMLTree::TEXT, tree.next());
-  str16 = tree.getText(&len);
-  ASSERT_NE(nullptr, str16);
-  EXPECT_EQ(StringPiece16(u"\\d{5}"), StringPiece16(str16, len));
+  idx = tree.indexOfAttribute(nullptr, 0, kOther.data(), kOther.size());
+  ASSERT_THAT(idx, Ge(0));
+  EXPECT_THAT(tree.getAttributeStringValue(idx, &len), StrEq(u"\""));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u"\\d{5}"));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/integration-tests/AppOne/AndroidManifest.xml b/tools/aapt2/integration-tests/AppOne/AndroidManifest.xml
index 1a4067f..a5f202d 100644
--- a/tools/aapt2/integration-tests/AppOne/AndroidManifest.xml
+++ b/tools/aapt2/integration-tests/AppOne/AndroidManifest.xml
@@ -19,4 +19,11 @@
     <uses-sdk android:minSdkVersion="21" />
 
     <uses-permission-sdk-23 android:name="android.permission.TEST" android:maxSdkVersion="22" />
+
+    <application>
+        <activity android:name=".MyActivity">
+            <layout android:defaultHeight="500dp"
+                android:defaultWidth="600dp" />
+        </activity>
+    </application>
 </manifest>
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 53c66a6..012bb5e 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -293,6 +293,7 @@
   manifest_action["instrumentation"]["meta-data"] = meta_data_action;
 
   manifest_action["original-package"];
+  manifest_action["overlay"];
   manifest_action["protected-broadcast"];
   manifest_action["uses-permission"];
   manifest_action["uses-permission-sdk-23"];
@@ -326,7 +327,10 @@
   uses_static_library_action.Action(RequiredAndroidAttribute("certDigest"));
 
   application_action["meta-data"] = meta_data_action;
+
   application_action["activity"] = component_action;
+  application_action["activity"]["layout"];
+
   application_action["activity-alias"] = component_action;
   application_action["service"] = component_action;
   application_action["receiver"] = component_action;
diff --git a/tools/aapt2/optimize/ResourceDeduper_test.cpp b/tools/aapt2/optimize/ResourceDeduper_test.cpp
index 4d00fa6..d9f384c0 100644
--- a/tools/aapt2/optimize/ResourceDeduper_test.cpp
+++ b/tools/aapt2/optimize/ResourceDeduper_test.cpp
@@ -19,69 +19,88 @@
 #include "ResourceTable.h"
 #include "test/Test.h"
 
+using ::aapt::test::HasValue;
+using ::testing::Not;
+
 namespace aapt {
 
 TEST(ResourceDeduperTest, SameValuesAreDeduped) {
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   const ConfigDescription default_config = {};
+  const ConfigDescription ldrtl_config = test::ParseConfigOrDie("ldrtl");
+  const ConfigDescription ldrtl_v21_config = test::ParseConfigOrDie("ldrtl-v21");
   const ConfigDescription en_config = test::ParseConfigOrDie("en");
   const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
-  // Chosen because this configuration is compatible with en.
+  // Chosen because this configuration is compatible with ldrtl/en.
   const ConfigDescription land_config = test::ParseConfigOrDie("land");
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .AddString("android:string/dedupe", ResourceId{}, default_config,
-                     "dedupe")
-          .AddString("android:string/dedupe", ResourceId{}, en_config, "dedupe")
-          .AddString("android:string/dedupe", ResourceId{}, land_config,
-                     "dedupe")
-          .AddString("android:string/dedupe2", ResourceId{}, default_config,
-                     "dedupe")
-          .AddString("android:string/dedupe2", ResourceId{}, en_config,
-                     "dedupe")
-          .AddString("android:string/dedupe2", ResourceId{}, en_v21_config,
-                     "keep")
-          .AddString("android:string/dedupe2", ResourceId{}, land_config,
-                     "dedupe")
+          .AddString("android:string/dedupe", ResourceId{}, default_config, "dedupe")
+          .AddString("android:string/dedupe", ResourceId{}, ldrtl_config, "dedupe")
+          .AddString("android:string/dedupe", ResourceId{}, land_config, "dedupe")
+
+          .AddString("android:string/dedupe2", ResourceId{}, default_config, "dedupe")
+          .AddString("android:string/dedupe2", ResourceId{}, ldrtl_config, "dedupe")
+          .AddString("android:string/dedupe2", ResourceId{}, ldrtl_v21_config, "keep")
+          .AddString("android:string/dedupe2", ResourceId{}, land_config, "dedupe")
+
+          .AddString("android:string/dedupe3", ResourceId{}, default_config, "dedupe")
+          .AddString("android:string/dedupe3", ResourceId{}, en_config, "dedupe")
+          .AddString("android:string/dedupe3", ResourceId{}, en_v21_config, "dedupe")
           .Build();
 
   ASSERT_TRUE(ResourceDeduper().Consume(context.get(), table.get()));
-  EXPECT_EQ(nullptr, test::GetValueForConfig<String>(
-                         table.get(), "android:string/dedupe", en_config));
-  EXPECT_EQ(nullptr, test::GetValueForConfig<String>(
-                         table.get(), "android:string/dedupe", land_config));
-  EXPECT_EQ(nullptr, test::GetValueForConfig<String>(
-                         table.get(), "android:string/dedupe2", en_config));
-  EXPECT_NE(nullptr, test::GetValueForConfig<String>(
-                         table.get(), "android:string/dedupe2", en_v21_config));
+  EXPECT_THAT(table, Not(HasValue("android:string/dedupe", ldrtl_config)));
+  EXPECT_THAT(table, Not(HasValue("android:string/dedupe", land_config)));
+
+  EXPECT_THAT(table, HasValue("android:string/dedupe2", ldrtl_v21_config));
+  EXPECT_THAT(table, Not(HasValue("android:string/dedupe2", ldrtl_config)));
+
+  EXPECT_THAT(table, HasValue("android:string/dedupe3", default_config));
+  EXPECT_THAT(table, HasValue("android:string/dedupe3", en_config));
+  EXPECT_THAT(table, Not(HasValue("android:string/dedupe3", en_v21_config)));
 }
 
 TEST(ResourceDeduperTest, DifferentValuesAreKept) {
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   const ConfigDescription default_config = {};
-  const ConfigDescription en_config = test::ParseConfigOrDie("en");
-  const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
-  // Chosen because this configuration is compatible with en.
+  const ConfigDescription ldrtl_config = test::ParseConfigOrDie("ldrtl");
+  const ConfigDescription ldrtl_v21_config = test::ParseConfigOrDie("ldrtl-v21");
+  // Chosen because this configuration is compatible with ldrtl.
   const ConfigDescription land_config = test::ParseConfigOrDie("land");
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .AddString("android:string/keep", ResourceId{}, default_config,
-                     "keep")
-          .AddString("android:string/keep", ResourceId{}, en_config, "keep")
-          .AddString("android:string/keep", ResourceId{}, en_v21_config,
-                     "keep2")
+          .AddString("android:string/keep", ResourceId{}, default_config, "keep")
+          .AddString("android:string/keep", ResourceId{}, ldrtl_config, "keep")
+          .AddString("android:string/keep", ResourceId{}, ldrtl_v21_config, "keep2")
           .AddString("android:string/keep", ResourceId{}, land_config, "keep2")
           .Build();
 
   ASSERT_TRUE(ResourceDeduper().Consume(context.get(), table.get()));
-  EXPECT_NE(nullptr, test::GetValueForConfig<String>(
-                         table.get(), "android:string/keep", en_config));
-  EXPECT_NE(nullptr, test::GetValueForConfig<String>(
-                         table.get(), "android:string/keep", en_v21_config));
-  EXPECT_NE(nullptr, test::GetValueForConfig<String>(
-                         table.get(), "android:string/keep", land_config));
+  EXPECT_THAT(table, HasValue("android:string/keep", ldrtl_config));
+  EXPECT_THAT(table, HasValue("android:string/keep", ldrtl_v21_config));
+  EXPECT_THAT(table, HasValue("android:string/keep", land_config));
+}
+
+TEST(ResourceDeduperTest, LocalesValuesAreKept) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  const ConfigDescription default_config = {};
+  const ConfigDescription fr_config = test::ParseConfigOrDie("fr");
+  const ConfigDescription fr_rCA_config = test::ParseConfigOrDie("fr-rCA");
+
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .AddString("android:string/keep", ResourceId{}, default_config, "keep")
+          .AddString("android:string/keep", ResourceId{}, fr_config, "keep")
+          .AddString("android:string/keep", ResourceId{}, fr_rCA_config, "keep")
+          .Build();
+
+  ASSERT_TRUE(ResourceDeduper().Consume(context.get(), table.get()));
+  EXPECT_THAT(table, HasValue("android:string/keep", default_config));
+  EXPECT_THAT(table, HasValue("android:string/keep", fr_config));
+  EXPECT_THAT(table, HasValue("android:string/keep", fr_rCA_config));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h
index 0585148..8efd56a 100644
--- a/tools/aapt2/test/Common.h
+++ b/tools/aapt2/test/Common.h
@@ -145,11 +145,34 @@
 
 namespace test {
 
+MATCHER_P(StrEq, a,
+          std::string(negation ? "isn't" : "is") + " equal to " +
+              ::testing::PrintToString(android::StringPiece16(a))) {
+  return android::StringPiece16(arg) == a;
+}
+
 MATCHER_P(ValueEq, a,
           std::string(negation ? "isn't" : "is") + " equal to " + ::testing::PrintToString(a)) {
   return arg.Equals(&a);
 }
 
+MATCHER_P(StrValueEq, a,
+          std::string(negation ? "isn't" : "is") + " equal to " + ::testing::PrintToString(a)) {
+  return *(arg.value) == a;
+}
+
+MATCHER_P(HasValue, name,
+          std::string(negation ? "does not have" : "has") + " value " +
+              ::testing::PrintToString(name)) {
+  return GetValueForConfig<Value>(&(*arg), name, {}) != nullptr;
+}
+
+MATCHER_P2(HasValue, name, config,
+           std::string(negation ? "does not have" : "has") + " value " +
+               ::testing::PrintToString(name) + " for config " + ::testing::PrintToString(config)) {
+  return GetValueForConfig<Value>(&(*arg), name, config) != nullptr;
+}
+
 }  // namespace test
 }  // namespace aapt
 
diff --git a/tools/aapt2/util/Maybe.h b/tools/aapt2/util/Maybe.h
index b43f8e8..9a82418 100644
--- a/tools/aapt2/util/Maybe.h
+++ b/tools/aapt2/util/Maybe.h
@@ -281,16 +281,12 @@
   return Maybe<T>();
 }
 
-/**
- * Define the == operator between Maybe<T> and Maybe<U> only if the operator T
- * == U is defined.
- * That way the compiler will show an error at the callsite when comparing two
- * Maybe<> objects
- * whose inner types can't be compared.
- */
+// Define the == operator between Maybe<T> and Maybe<U> only if the operator T == U is defined.
+// That way the compiler will show an error at the callsite when comparing two Maybe<> objects
+// whose inner types can't be compared.
 template <typename T, typename U>
-typename std::enable_if<has_eq_op<T, U>::value, bool>::type operator==(
-    const Maybe<T>& a, const Maybe<U>& b) {
+typename std::enable_if<has_eq_op<T, U>::value, bool>::type operator==(const Maybe<T>& a,
+                                                                       const Maybe<U>& b) {
   if (a && b) {
     return a.value() == b.value();
   } else if (!a && !b) {
@@ -299,18 +295,22 @@
   return false;
 }
 
-/**
- * Same as operator== but negated.
- */
 template <typename T, typename U>
-typename std::enable_if<has_eq_op<T, U>::value, bool>::type operator!=(
-    const Maybe<T>& a, const Maybe<U>& b) {
+typename std::enable_if<has_eq_op<T, U>::value, bool>::type operator==(const Maybe<T>& a,
+                                                                       const U& b) {
+  return a ? a.value() == b : false;
+}
+
+// Same as operator== but negated.
+template <typename T, typename U>
+typename std::enable_if<has_eq_op<T, U>::value, bool>::type operator!=(const Maybe<T>& a,
+                                                                       const Maybe<U>& b) {
   return !(a == b);
 }
 
 template <typename T, typename U>
-typename std::enable_if<has_lt_op<T, U>::value, bool>::type operator<(
-    const Maybe<T>& a, const Maybe<U>& b) {
+typename std::enable_if<has_lt_op<T, U>::value, bool>::type operator<(const Maybe<T>& a,
+                                                                      const Maybe<U>& b) {
   if (a && b) {
     return a.value() < b.value();
   } else if (!a && !b) {
diff --git a/tools/aapt2/util/Util.cpp b/tools/aapt2/util/Util.cpp
index cf223225..8a8be85 100644
--- a/tools/aapt2/util/Util.cpp
+++ b/tools/aapt2/util/Util.cpp
@@ -203,7 +203,7 @@
     if (*c == '%' && c + 1 < end) {
       c++;
 
-      if (*c == '%') {
+      if (*c == '%' || *c == 'n') {
         c++;
         continue;
       }
@@ -312,6 +312,9 @@
   return result_utf8;
 }
 
+StringBuilder::StringBuilder(bool preserve_spaces) : preserve_spaces_(preserve_spaces) {
+}
+
 StringBuilder& StringBuilder::Append(const StringPiece& str) {
   if (!error_.empty()) {
     return *this;
@@ -368,14 +371,12 @@
       }
       last_char_was_escape_ = false;
       start = current + 1;
-    } else if (*current == '"') {
+    } else if (!preserve_spaces_ && *current == '"') {
       if (!quote_ && trailing_space_) {
-        // We found an opening quote, and we have
-        // trailing space, so we should append that
+        // We found an opening quote, and we have trailing space, so we should append that
         // space now.
         if (trailing_space_) {
-          // We had trailing whitespace, so
-          // replace with a single space.
+          // We had trailing whitespace, so replace with a single space.
           if (!str_.empty()) {
             str_ += ' ';
           }
@@ -385,7 +386,7 @@
       quote_ = !quote_;
       str_.append(start, current - start);
       start = current + 1;
-    } else if (*current == '\'' && !quote_) {
+    } else if (!preserve_spaces_ && *current == '\'' && !quote_) {
       // This should be escaped.
       error_ = "unescaped apostrophe";
       return *this;
@@ -402,7 +403,7 @@
       str_.append(start, current - start);
       start = current + 1;
       last_char_was_escape_ = true;
-    } else if (!quote_) {
+    } else if (!preserve_spaces_ && !quote_) {
       // This is not quoted text, so look for whitespace.
       if (isspace(*current)) {
         // We found whitespace, see if we have seen some
diff --git a/tools/aapt2/util/Util.h b/tools/aapt2/util/Util.h
index 386f74b..b9ada77 100644
--- a/tools/aapt2/util/Util.h
+++ b/tools/aapt2/util/Util.h
@@ -166,6 +166,8 @@
 
 class StringBuilder {
  public:
+  explicit StringBuilder(bool preserve_spaces = false);
+
   StringBuilder& Append(const android::StringPiece& str);
   const std::string& ToString() const;
   const std::string& Error() const;
@@ -179,6 +181,7 @@
   explicit operator bool() const;
 
  private:
+  bool preserve_spaces_;
   std::string str_;
   size_t utf16_len_ = 0;
   bool quote_ = false;
diff --git a/tools/aapt2/util/Util_test.cpp b/tools/aapt2/util/Util_test.cpp
index e49aee5..5cced3e 100644
--- a/tools/aapt2/util/Util_test.cpp
+++ b/tools/aapt2/util/Util_test.cpp
@@ -20,16 +20,17 @@
 
 #include "test/Test.h"
 
-using android::StringPiece;
+using ::android::StringPiece;
+using ::testing::Eq;
+using ::testing::Ne;
+using ::testing::SizeIs;
 
 namespace aapt {
 
 TEST(UtilTest, TrimOnlyWhitespace) {
-  const std::string full = "\n        ";
-
-  StringPiece trimmed = util::TrimWhitespace(full);
+  const StringPiece trimmed = util::TrimWhitespace("\n        ");
   EXPECT_TRUE(trimmed.empty());
-  EXPECT_EQ(0u, trimmed.size());
+  EXPECT_THAT(trimmed, SizeIs(0u));
 }
 
 TEST(UtilTest, StringEndsWith) {
@@ -41,85 +42,74 @@
 }
 
 TEST(UtilTest, StringBuilderSplitEscapeSequence) {
-  EXPECT_EQ(StringPiece("this is a new\nline."), util::StringBuilder()
-                                                     .Append("this is a new\\")
-                                                     .Append("nline.")
-                                                     .ToString());
+  EXPECT_THAT(util::StringBuilder().Append("this is a new\\").Append("nline.").ToString(),
+              Eq("this is a new\nline."));
 }
 
 TEST(UtilTest, StringBuilderWhitespaceRemoval) {
-  EXPECT_EQ(StringPiece("hey guys this is so cool"),
-            util::StringBuilder()
-                .Append("    hey guys ")
-                .Append(" this is so cool ")
-                .ToString());
-
-  EXPECT_EQ(StringPiece(" wow,  so many \t spaces. what?"),
-            util::StringBuilder()
-                .Append(" \" wow,  so many \t ")
-                .Append("spaces. \"what? ")
-                .ToString());
-
-  EXPECT_EQ(StringPiece("where is the pie?"), util::StringBuilder()
-                                                  .Append("  where \t ")
-                                                  .Append(" \nis the "
-                                                          " pie?")
-                                                  .ToString());
+  EXPECT_THAT(util::StringBuilder().Append("    hey guys ").Append(" this is so cool ").ToString(),
+              Eq("hey guys this is so cool"));
+  EXPECT_THAT(
+      util::StringBuilder().Append(" \" wow,  so many \t ").Append("spaces. \"what? ").ToString(),
+      Eq(" wow,  so many \t spaces. what?"));
+  EXPECT_THAT(util::StringBuilder().Append("  where \t ").Append(" \nis the pie?").ToString(),
+              Eq("where is the pie?"));
 }
 
 TEST(UtilTest, StringBuilderEscaping) {
-  EXPECT_EQ(StringPiece("hey guys\n this \t is so\\ cool"),
-            util::StringBuilder()
-                .Append("    hey guys\\n ")
-                .Append(" this \\t is so\\\\ cool ")
-                .ToString());
-
-  EXPECT_EQ(StringPiece("@?#\\\'"),
-            util::StringBuilder().Append("\\@\\?\\#\\\\\\'").ToString());
+  EXPECT_THAT(util::StringBuilder()
+                  .Append("    hey guys\\n ")
+                  .Append(" this \\t is so\\\\ cool ")
+                  .ToString(),
+              Eq("hey guys\n this \t is so\\ cool"));
+  EXPECT_THAT(util::StringBuilder().Append("\\@\\?\\#\\\\\\'").ToString(), Eq("@?#\\\'"));
 }
 
 TEST(UtilTest, StringBuilderMisplacedQuote) {
-  util::StringBuilder builder{};
+  util::StringBuilder builder;
   EXPECT_FALSE(builder.Append("they're coming!"));
 }
 
 TEST(UtilTest, StringBuilderUnicodeCodes) {
-  EXPECT_EQ(std::string("\u00AF\u0AF0 woah"),
-            util::StringBuilder().Append("\\u00AF\\u0AF0 woah").ToString());
-
+  EXPECT_THAT(util::StringBuilder().Append("\\u00AF\\u0AF0 woah").ToString(),
+              Eq("\u00AF\u0AF0 woah"));
   EXPECT_FALSE(util::StringBuilder().Append("\\u00 yo"));
 }
 
+TEST(UtilTest, StringBuilderPreserveSpaces) {
+  EXPECT_THAT(util::StringBuilder(true /*preserve_spaces*/).Append("\"").ToString(), Eq("\""));
+}
+
 TEST(UtilTest, TokenizeInput) {
   auto tokenizer = util::Tokenize(StringPiece("this| is|the|end"), '|');
   auto iter = tokenizer.begin();
-  ASSERT_EQ(*iter, StringPiece("this"));
+  ASSERT_THAT(*iter, Eq("this"));
   ++iter;
-  ASSERT_EQ(*iter, StringPiece(" is"));
+  ASSERT_THAT(*iter, Eq(" is"));
   ++iter;
-  ASSERT_EQ(*iter, StringPiece("the"));
+  ASSERT_THAT(*iter, Eq("the"));
   ++iter;
-  ASSERT_EQ(*iter, StringPiece("end"));
+  ASSERT_THAT(*iter, Eq("end"));
   ++iter;
-  ASSERT_EQ(tokenizer.end(), iter);
+  ASSERT_THAT(iter, Eq(tokenizer.end()));
 }
 
 TEST(UtilTest, TokenizeEmptyString) {
   auto tokenizer = util::Tokenize(StringPiece(""), '|');
   auto iter = tokenizer.begin();
-  ASSERT_NE(tokenizer.end(), iter);
-  ASSERT_EQ(StringPiece(), *iter);
+  ASSERT_THAT(iter, Ne(tokenizer.end()));
+  ASSERT_THAT(*iter, Eq(StringPiece()));
   ++iter;
-  ASSERT_EQ(tokenizer.end(), iter);
+  ASSERT_THAT(iter, Eq(tokenizer.end()));
 }
 
 TEST(UtilTest, TokenizeAtEnd) {
   auto tokenizer = util::Tokenize(StringPiece("one."), '.');
   auto iter = tokenizer.begin();
-  ASSERT_EQ(*iter, StringPiece("one"));
+  ASSERT_THAT(*iter, Eq("one"));
   ++iter;
-  ASSERT_NE(iter, tokenizer.end());
-  ASSERT_EQ(*iter, StringPiece());
+  ASSERT_THAT(iter, Ne(tokenizer.end()));
+  ASSERT_THAT(*iter, Eq(StringPiece()));
 }
 
 TEST(UtilTest, IsJavaClassName) {
diff --git a/tools/aapt2/xml/XmlDom_test.cpp b/tools/aapt2/xml/XmlDom_test.cpp
index fb18ea3..031801e 100644
--- a/tools/aapt2/xml/XmlDom_test.cpp
+++ b/tools/aapt2/xml/XmlDom_test.cpp
@@ -28,17 +28,16 @@
 
 TEST(XmlDomTest, Inflate) {
   std::stringstream in(kXmlPreamble);
-  in << R"EOF(
-        <Layout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content">
-            <TextView android:id="@+id/id"
-                      android:layout_width="wrap_content"
-                      android:layout_height="wrap_content" />
-        </Layout>
-    )EOF";
+  in << R"(
+      <Layout xmlns:android="http://schemas.android.com/apk/res/android"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content">
+        <TextView android:id="@+id/id"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+      </Layout>)";
 
-  const Source source = {"test.xml"};
+  const Source source("test.xml");
   StdErrDiagnostics diag;
   std::unique_ptr<xml::XmlResource> doc = xml::Inflate(&in, &diag, source);
   ASSERT_NE(doc, nullptr);
@@ -51,8 +50,8 @@
 
 // Escaping is handled after parsing of the values for resource-specific values.
 TEST(XmlDomTest, ForwardEscapes) {
-  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
-      <element value="\?hello" pattern="\\d{5}">\\d{5}</element>)EOF");
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(
+      <element value="\?hello" pattern="\\d{5}">\\d{5}</element>)");
 
   xml::Element* el = xml::FindRootElement(doc->root.get());
   ASSERT_NE(nullptr, el);
@@ -65,10 +64,20 @@
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ("\\?hello", attr->value);
 
-  ASSERT_EQ(1u, el->children.size());
   xml::Text* text = xml::NodeCast<xml::Text>(el->children[0].get());
   ASSERT_NE(nullptr, text);
   EXPECT_EQ("\\\\d{5}", text->text);
 }
 
+TEST(XmlDomTest, XmlEscapeSequencesAreParsed) {
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element value="&quot;" />)");
+
+  xml::Element* el = xml::FindRootElement(doc.get());
+  ASSERT_NE(nullptr, el);
+
+  xml::Attribute* attr = el->FindAttribute({}, "value");
+  ASSERT_NE(nullptr, attr);
+  EXPECT_EQ("\"", attr->value);
+}
+
 }  // namespace aapt
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py
index 53501f9..77c1c24 100644
--- a/tools/apilint/apilint.py
+++ b/tools/apilint/apilint.py
@@ -429,7 +429,8 @@
         if len(creator) == 0 or len(write) == 0 or len(describe) == 0:
             error(clazz, None, "FW3", "Parcelable requires CREATOR, writeToParcel, and describeContents; missing one")
 
-        if " final class " not in clazz.raw:
+        if ((" final class " not in clazz.raw) and
+            (" final deprecated class " not in clazz.raw)):
             error(clazz, None, "FW8", "Parcelable classes must be final")
 
 
diff --git a/tools/bit/Android.bp b/tools/bit/Android.bp
new file mode 100644
index 0000000..a806271
--- /dev/null
+++ b/tools/bit/Android.bp
@@ -0,0 +1,45 @@
+//
+// 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.
+//
+
+// ==========================================================
+// Build the host executable: bit
+// ==========================================================
+cc_binary_host {
+    name: "bit",
+
+    srcs: [
+        "aapt.cpp",
+        "adb.cpp",
+        "command.cpp",
+        "main.cpp",
+        "make.cpp",
+        "print.cpp",
+        "util.cpp",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+    static_libs: [
+        "libexpat",
+        "libinstrumentation",
+        "libjsoncpp",
+    ],
+
+    shared_libs: ["libprotobuf-cpp-full"],
+}
diff --git a/tools/bit/Android.mk b/tools/bit/Android.mk
deleted file mode 100644
index 57f46d4..0000000
--- a/tools/bit/Android.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH:= $(call my-dir)
-
-# ==========================================================
-# Build the host executable: protoc-gen-javastream
-# ==========================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := bit
-
-LOCAL_MODULE_HOST_OS := linux darwin
-
-LOCAL_SRC_FILES := \
-    aapt.cpp \
-    adb.cpp \
-    command.cpp \
-    main.cpp \
-    make.cpp \
-    print.cpp \
-    util.cpp
-
-LOCAL_STATIC_LIBRARIES := \
-    libexpat \
-    libinstrumentation \
-    libjsoncpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libprotobuf-cpp-full
-
-include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/bit/adb.cpp b/tools/bit/adb.cpp
index 0c8424d..93fda54 100644
--- a/tools/bit/adb.cpp
+++ b/tools/bit/adb.cpp
@@ -293,7 +293,9 @@
     print_command(cmd);
 
     int fds[2];
-    pipe(fds);
+    if (0 != pipe(fds)) {
+        return errno;
+    }
 
     pid_t pid = fork();
 
diff --git a/tools/bit/adb.h b/tools/bit/adb.h
index dca80c8..f0774db9 100644
--- a/tools/bit/adb.h
+++ b/tools/bit/adb.h
@@ -17,7 +17,7 @@
 #ifndef ADB_H
 #define ADB_H
 
-#include "instrumentation_data.pb.h"
+#include "proto/instrumentation_data.pb.h"
 
 #include <string>
 
diff --git a/tools/bit/command.cpp b/tools/bit/command.cpp
index 9a8449b..f95ea11 100644
--- a/tools/bit/command.cpp
+++ b/tools/bit/command.cpp
@@ -105,7 +105,9 @@
     }
 
     int fds[2];
-    pipe(fds);
+    if (0 != pipe(fds)) {
+        return string();
+    }
 
     pid_t pid = fork();
 
@@ -187,7 +189,7 @@
 int
 exec_with_path_search(const char* prog, char const* const* argv, char const* const* envp)
 {
-    if (prog[0] == '/') {
+    if (strchr(prog, '/') != NULL) {
         return execve(prog, (char*const*)argv, (char*const*)envp);
     } else {
         char* pathEnv = strdup(getenv("PATH"));
diff --git a/tools/bit/main.cpp b/tools/bit/main.cpp
index d056ba5..e81898f 100644
--- a/tools/bit/main.cpp
+++ b/tools/bit/main.cpp
@@ -561,6 +561,15 @@
     }
 }
 
+static void
+chdir_or_exit(const char *path) {
+    // TODO: print_command("cd", path);
+    if (0 != chdir(path)) {
+        print_error("Error: Could not chdir: %s", path);
+        exit(1);
+    }
+}
+
 /**
  * Run the build, install, and test actions.
  */
@@ -579,12 +588,12 @@
     const string buildProduct = get_required_env("TARGET_PRODUCT", false);
     const string buildVariant = get_required_env("TARGET_BUILD_VARIANT", false);
     const string buildType = get_required_env("TARGET_BUILD_TYPE", false);
-    const string buildDevice = get_build_var(buildTop, "TARGET_DEVICE", false);
-    const string buildId = get_build_var(buildTop, "BUILD_ID", false);
-    const string buildOut = get_out_dir();
 
-    // TODO: print_command("cd", buildTop.c_str());
-    chdir(buildTop.c_str());
+    chdir_or_exit(buildTop.c_str());
+
+    const string buildDevice = get_build_var("TARGET_DEVICE", false);
+    const string buildId = get_build_var("BUILD_ID", false);
+    const string buildOut = get_out_dir();
 
     // Get the modules for the targets
     map<string,Module> modules;
@@ -952,7 +961,7 @@
     const string buildProduct = get_required_env("TARGET_PRODUCT", false);
     const string buildOut = get_out_dir();
 
-    chdir(buildTop.c_str());
+    chdir_or_exit(buildTop.c_str());
 
     string buildDevice = sniff_device_name(buildOut, buildProduct);
 
diff --git a/tools/bit/make.cpp b/tools/bit/make.cpp
index a800241..ef3ccc5 100644
--- a/tools/bit/make.cpp
+++ b/tools/bit/make.cpp
@@ -36,31 +36,16 @@
 
 map<string,string> g_buildVars;
 
-static unsigned int
-get_thread_count()
-{
-    unsigned int threads = std::thread::hardware_concurrency();
-    // Guess if the value cannot be computed
-    return threads == 0 ? 4 : static_cast<unsigned int>(threads * 1.3f);
-}
-
 string
-get_build_var(const string& buildTop, const string& name, bool quiet)
+get_build_var(const string& name, bool quiet)
 {
     int err;
 
     map<string,string>::iterator it = g_buildVars.find(name);
     if (it == g_buildVars.end()) {
-        Command cmd("make");
-        cmd.AddArg("--no-print-directory");
-        cmd.AddArg(string("-j") + std::to_string(get_thread_count()));
-        cmd.AddArg("-C");
-        cmd.AddArg(buildTop);
-        cmd.AddArg("-f");
-        cmd.AddArg("build/core/config.mk");
-        cmd.AddArg(string("dumpvar-") + name);
-        cmd.AddEnv("CALLED_FROM_SETUP", "true");
-        cmd.AddEnv("BUILD_SYSTEM", "build/core");
+        Command cmd("build/soong/soong_ui.bash");
+        cmd.AddArg("--dumpvar-mode");
+        cmd.AddArg(name);
 
         string output = trim(get_command_output(cmd, &err, quiet));
         if (err == 0) {
@@ -208,10 +193,8 @@
 int
 build_goals(const vector<string>& goals)
 {
-    Command cmd("make");
-    cmd.AddArg(string("-j") + std::to_string(get_thread_count()));
-    cmd.AddArg("-f");
-    cmd.AddArg("build/core/main.mk");
+    Command cmd("build/soong/soong_ui.bash");
+    cmd.AddArg("--make-mode");
     for (size_t i=0; i<goals.size(); i++) {
         cmd.AddArg(goals[i]);
     }
diff --git a/tools/bit/make.h b/tools/bit/make.h
index bb83c6e..1c9504d 100644
--- a/tools/bit/make.h
+++ b/tools/bit/make.h
@@ -31,7 +31,7 @@
     vector<string> installed;
 };
 
-string get_build_var(const string& buildTop, const string& name, bool quiet);
+string get_build_var(const string& name, bool quiet);
 
 /**
  * Poke around in the out directory and try to find a device name that matches
diff --git a/tools/bit/util.cpp b/tools/bit/util.cpp
index fc93bcb..9223931 100644
--- a/tools/bit/util.cpp
+++ b/tools/bit/util.cpp
@@ -101,7 +101,6 @@
 void
 get_directory_contents(const string& name, map<string,FileInfo>* results)
 {
-    int err;
     DIR* dir = opendir(name.c_str());
     if (dir == NULL) {
         return;
@@ -241,7 +240,9 @@
     fseek(file, 0, SEEK_SET);
 
     char* buf = (char*)malloc(size);
-    fread(buf, 1, size, file);
+    if ((size_t) size != fread(buf, 1, size, file)) {
+        return string();
+    }
 
     string result(buf, size);
 
diff --git a/tools/fonts/add_additional_fonts.py b/tools/fonts/add_additional_fonts.py
new file mode 100644
index 0000000..bf4af2b
--- /dev/null
+++ b/tools/fonts/add_additional_fonts.py
@@ -0,0 +1,44 @@
+#!/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/fonts/fontchain_lint.py b/tools/fonts/fontchain_lint.py
deleted file mode 100755
index c0475ee..0000000
--- a/tools/fonts/fontchain_lint.py
+++ /dev/null
@@ -1,664 +0,0 @@
-#!/usr/bin/env python
-
-import collections
-import copy
-import glob
-import itertools
-from os import path
-import sys
-from xml.etree import ElementTree
-
-from fontTools import ttLib
-
-EMOJI_VS = 0xFE0F
-
-LANG_TO_SCRIPT = {
-    'as': 'Beng',
-    'bg': 'Cyrl',
-    'bn': 'Beng',
-    'cu': 'Cyrl',
-    'cy': 'Latn',
-    'da': 'Latn',
-    'de': 'Latn',
-    'en': 'Latn',
-    'es': 'Latn',
-    'et': 'Latn',
-    'eu': 'Latn',
-    'fr': 'Latn',
-    'ga': 'Latn',
-    'gu': 'Gujr',
-    'hi': 'Deva',
-    'hr': 'Latn',
-    'hu': 'Latn',
-    'hy': 'Armn',
-    'ja': 'Jpan',
-    'kn': 'Knda',
-    'ko': 'Kore',
-    'ml': 'Mlym',
-    'mn': 'Cyrl',
-    'mr': 'Deva',
-    'nb': 'Latn',
-    'nn': 'Latn',
-    'or': 'Orya',
-    'pa': 'Guru',
-    'pt': 'Latn',
-    'sl': 'Latn',
-    'ta': 'Taml',
-    'te': 'Telu',
-    'tk': 'Latn',
-}
-
-def lang_to_script(lang_code):
-    lang = lang_code.lower()
-    while lang not in LANG_TO_SCRIPT:
-        hyphen_idx = lang.rfind('-')
-        assert hyphen_idx != -1, (
-            'We do not know what script the "%s" language is written in.'
-            % lang_code)
-        assumed_script = lang[hyphen_idx+1:]
-        if len(assumed_script) == 4 and assumed_script.isalpha():
-            # This is actually the script
-            return assumed_script.title()
-        lang = lang[:hyphen_idx]
-    return LANG_TO_SCRIPT[lang]
-
-
-def printable(inp):
-    if type(inp) is set:  # set of character sequences
-        return '{' + ', '.join([printable(seq) for seq in inp]) + '}'
-    if type(inp) is tuple:  # character sequence
-        return '<' + (', '.join([printable(ch) for ch in inp])) + '>'
-    else:  # single character
-        return 'U+%04X' % inp
-
-
-def open_font(font):
-    font_file, index = font
-    font_path = path.join(_fonts_dir, font_file)
-    if index is not None:
-        return ttLib.TTFont(font_path, fontNumber=index)
-    else:
-        return ttLib.TTFont(font_path)
-
-
-def get_best_cmap(font):
-    ttfont = open_font(font)
-    all_unicode_cmap = None
-    bmp_cmap = None
-    for cmap in ttfont['cmap'].tables:
-        specifier = (cmap.format, cmap.platformID, cmap.platEncID)
-        if specifier == (4, 3, 1):
-            assert bmp_cmap is None, 'More than one BMP cmap in %s' % (font, )
-            bmp_cmap = cmap
-        elif specifier == (12, 3, 10):
-            assert all_unicode_cmap is None, (
-                'More than one UCS-4 cmap in %s' % (font, ))
-            all_unicode_cmap = cmap
-
-    return all_unicode_cmap.cmap if all_unicode_cmap else bmp_cmap.cmap
-
-
-def get_variation_sequences_cmap(font):
-    ttfont = open_font(font)
-    vs_cmap = None
-    for cmap in ttfont['cmap'].tables:
-        specifier = (cmap.format, cmap.platformID, cmap.platEncID)
-        if specifier == (14, 0, 5):
-            assert vs_cmap is None, 'More than one VS cmap in %s' % (font, )
-            vs_cmap = cmap
-    return vs_cmap
-
-
-def get_emoji_map(font):
-    # Add normal characters
-    emoji_map = copy.copy(get_best_cmap(font))
-    reverse_cmap = {glyph: code for code, glyph in emoji_map.items()}
-
-    # Add variation sequences
-    vs_dict = get_variation_sequences_cmap(font).uvsDict
-    for vs in vs_dict:
-        for base, glyph in vs_dict[vs]:
-            if glyph is None:
-                emoji_map[(base, vs)] = emoji_map[base]
-            else:
-                emoji_map[(base, vs)] = glyph
-
-    # Add GSUB rules
-    ttfont = open_font(font)
-    for lookup in ttfont['GSUB'].table.LookupList.Lookup:
-        if lookup.LookupType != 4:
-            # Other lookups are used in the emoji font for fallback.
-            # We ignore them for now.
-            continue
-        for subtable in lookup.SubTable:
-            ligatures = subtable.ligatures
-            for first_glyph in ligatures:
-                for ligature in ligatures[first_glyph]:
-                    sequence = [first_glyph] + ligature.Component
-                    sequence = [reverse_cmap[glyph] for glyph in sequence]
-                    sequence = tuple(sequence)
-                    # Make sure no starting subsequence of 'sequence' has been
-                    # seen before.
-                    for sub_len in range(2, len(sequence)+1):
-                        subsequence = sequence[:sub_len]
-                        assert subsequence not in emoji_map
-                    emoji_map[sequence] = ligature.LigGlyph
-
-    return emoji_map
-
-
-def assert_font_supports_any_of_chars(font, chars):
-    best_cmap = get_best_cmap(font)
-    for char in chars:
-        if char in best_cmap:
-            return
-    sys.exit('None of characters in %s were found in %s' % (chars, font))
-
-
-def assert_font_supports_all_of_chars(font, chars):
-    best_cmap = get_best_cmap(font)
-    for char in chars:
-        assert char in best_cmap, (
-            'U+%04X was not found in %s' % (char, font))
-
-
-def assert_font_supports_none_of_chars(font, chars):
-    best_cmap = get_best_cmap(font)
-    for char in chars:
-        assert char not in best_cmap, (
-            'U+%04X was found in %s' % (char, font))
-
-
-def assert_font_supports_all_sequences(font, sequences):
-    vs_dict = get_variation_sequences_cmap(font).uvsDict
-    for base, vs in sorted(sequences):
-        assert vs in vs_dict and (base, None) in vs_dict[vs], (
-            '<U+%04X, U+%04X> was not found in %s' % (base, vs, font))
-
-
-def check_hyphens(hyphens_dir):
-    # Find all the scripts that need automatic hyphenation
-    scripts = set()
-    for hyb_file in glob.iglob(path.join(hyphens_dir, '*.hyb')):
-        hyb_file = path.basename(hyb_file)
-        assert hyb_file.startswith('hyph-'), (
-            'Unknown hyphenation file %s' % hyb_file)
-        lang_code = hyb_file[hyb_file.index('-')+1:hyb_file.index('.')]
-        scripts.add(lang_to_script(lang_code))
-
-    HYPHENS = {0x002D, 0x2010}
-    for script in scripts:
-        fonts = _script_to_font_map[script]
-        assert fonts, 'No fonts found for the "%s" script' % script
-        for font in fonts:
-            assert_font_supports_any_of_chars(font, HYPHENS)
-
-
-class FontRecord(object):
-    def __init__(self, name, scripts, variant, weight, style, font):
-        self.name = name
-        self.scripts = scripts
-        self.variant = variant
-        self.weight = weight
-        self.style = style
-        self.font = font
-
-
-def parse_fonts_xml(fonts_xml_path):
-    global _script_to_font_map, _fallback_chain
-    _script_to_font_map = collections.defaultdict(set)
-    _fallback_chain = []
-    tree = ElementTree.parse(fonts_xml_path)
-    families = tree.findall('family')
-    # Minikin supports up to 254 but users can place their own font at the first
-    # place. Thus, 253 is the maximum allowed number of font families in the
-    # default collection.
-    assert len(families) < 254, (
-        'System font collection can contains up to 253 font families.')
-    for family in families:
-        name = family.get('name')
-        variant = family.get('variant')
-        langs = family.get('lang')
-        if name:
-            assert variant is None, (
-                'No variant expected for LGC font %s.' % name)
-            assert langs is None, (
-                'No language expected for LGC fonts %s.' % name)
-        else:
-            assert variant in {None, 'elegant', 'compact'}, (
-                'Unexpected value for variant: %s' % variant)
-
-        if langs:
-            langs = langs.split()
-            scripts = {lang_to_script(lang) for lang in langs}
-        else:
-            scripts = set()
-
-        for child in family:
-            assert child.tag == 'font', (
-                'Unknown tag <%s>' % child.tag)
-            font_file = child.text.rstrip()
-            weight = int(child.get('weight'))
-            assert weight % 100 == 0, (
-                'Font weight "%d" is not a multiple of 100.' % weight)
-
-            style = child.get('style')
-            assert style in {'normal', 'italic'}, (
-                'Unknown style "%s"' % style)
-
-            index = child.get('index')
-            if index:
-                index = int(index)
-
-            _fallback_chain.append(FontRecord(
-                name,
-                frozenset(scripts),
-                variant,
-                weight,
-                style,
-                (font_file, index)))
-
-            if name: # non-empty names are used for default LGC fonts
-                map_scripts = {'Latn', 'Grek', 'Cyrl'}
-            else:
-                map_scripts = scripts
-            for script in map_scripts:
-                _script_to_font_map[script].add((font_file, index))
-
-
-def check_emoji_coverage(all_emoji, equivalent_emoji):
-    emoji_font = get_emoji_font()
-    check_emoji_font_coverage(emoji_font, all_emoji, equivalent_emoji)
-
-
-def get_emoji_font():
-    emoji_fonts = [
-        record.font for record in _fallback_chain
-        if 'Zsye' in record.scripts]
-    assert len(emoji_fonts) == 1, 'There are %d emoji fonts.' % len(emoji_fonts)
-    return emoji_fonts[0]
-
-
-def check_emoji_font_coverage(emoji_font, all_emoji, equivalent_emoji):
-    coverage = get_emoji_map(emoji_font)
-    for sequence in all_emoji:
-        assert sequence in coverage, (
-            '%s is not supported in the emoji font.' % printable(sequence))
-
-    for sequence in coverage:
-        if sequence in {0x0000, 0x000D, 0x0020}:
-            # The font needs to support a few extra characters, which is OK
-            continue
-        assert sequence in all_emoji, (
-            'Emoji font should not support %s.' % printable(sequence))
-
-    for first, second in sorted(equivalent_emoji.items()):
-        assert coverage[first] == coverage[second], (
-            '%s and %s should map to the same glyph.' % (
-                printable(first),
-                printable(second)))
-
-    for glyph in set(coverage.values()):
-        maps_to_glyph = [seq for seq in coverage if coverage[seq] == glyph]
-        if len(maps_to_glyph) > 1:
-            # There are more than one sequences mapping to the same glyph. We
-            # need to make sure they were expected to be equivalent.
-            equivalent_seqs = set()
-            for seq in maps_to_glyph:
-                equivalent_seq = seq
-                while equivalent_seq in equivalent_emoji:
-                    equivalent_seq = equivalent_emoji[equivalent_seq]
-                equivalent_seqs.add(equivalent_seq)
-            assert len(equivalent_seqs) == 1, (
-                'The sequences %s should not result in the same glyph %s' % (
-                    printable(equivalent_seqs),
-                    glyph))
-
-
-def check_emoji_defaults(default_emoji):
-    missing_text_chars = _emoji_properties['Emoji'] - default_emoji
-    emoji_font_seen = False
-    for record in _fallback_chain:
-        if 'Zsye' in record.scripts:
-            emoji_font_seen = True
-            # No need to check the emoji font
-            continue
-        # For later fonts, we only check them if they have a script
-        # defined, since the defined script may get them to a higher
-        # score even if they appear after the emoji font. However,
-        # we should skip checking the text symbols font, since
-        # symbol fonts should be able to override the emoji display
-        # style when 'Zsym' is explicitly specified by the user.
-        if emoji_font_seen and (not record.scripts or 'Zsym' in record.scripts):
-            continue
-
-        # Check default emoji-style characters
-        assert_font_supports_none_of_chars(record.font, sorted(default_emoji))
-
-        # Mark default text-style characters appearing in fonts above the emoji
-        # font as seen
-        if not emoji_font_seen:
-            missing_text_chars -= set(get_best_cmap(record.font))
-
-    # Noto does not have monochrome glyphs for Unicode 7.0 wingdings and
-    # webdings yet.
-    missing_text_chars -= _chars_by_age['7.0']
-    assert missing_text_chars == set(), (
-        'Text style version of some emoji characters are missing: ' +
-            repr(missing_text_chars))
-
-
-# Setting reverse to true returns a dictionary that maps the values to sets of
-# characters, useful for some binary properties. Otherwise, we get a
-# dictionary that maps characters to the property values, assuming there's only
-# one property in the file.
-def parse_unicode_datafile(file_path, reverse=False):
-    if reverse:
-        output_dict = collections.defaultdict(set)
-    else:
-        output_dict = {}
-    with open(file_path) as datafile:
-        for line in datafile:
-            if '#' in line:
-                line = line[:line.index('#')]
-            line = line.strip()
-            if not line:
-                continue
-
-            chars, prop = line.split(';')[:2]
-            chars = chars.strip()
-            prop = prop.strip()
-
-            if ' ' in chars:  # character sequence
-                sequence = [int(ch, 16) for ch in chars.split(' ')]
-                additions = [tuple(sequence)]
-            elif '..' in chars:  # character range
-                char_start, char_end = chars.split('..')
-                char_start = int(char_start, 16)
-                char_end = int(char_end, 16)
-                additions = xrange(char_start, char_end+1)
-            else:  # singe character
-                additions = [int(chars, 16)]
-            if reverse:
-                output_dict[prop].update(additions)
-            else:
-                for addition in additions:
-                    assert addition not in output_dict
-                    output_dict[addition] = prop
-    return output_dict
-
-
-def parse_emoji_variants(file_path):
-    emoji_set = set()
-    text_set = set()
-    with open(file_path) as datafile:
-        for line in datafile:
-            if '#' in line:
-                line = line[:line.index('#')]
-            line = line.strip()
-            if not line:
-                continue
-            sequence, description, _ = line.split(';')
-            sequence = sequence.strip().split(' ')
-            base = int(sequence[0], 16)
-            vs = int(sequence[1], 16)
-            description = description.strip()
-            if description == 'text style':
-                text_set.add((base, vs))
-            elif description == 'emoji style':
-                emoji_set.add((base, vs))
-    return text_set, emoji_set
-
-
-def parse_ucd(ucd_path):
-    global _emoji_properties, _chars_by_age
-    global _text_variation_sequences, _emoji_variation_sequences
-    global _emoji_sequences, _emoji_zwj_sequences
-    _emoji_properties = parse_unicode_datafile(
-        path.join(ucd_path, 'emoji-data.txt'), reverse=True)
-    emoji_properties_additions = parse_unicode_datafile(
-        path.join(ucd_path, 'additions', 'emoji-data.txt'), reverse=True)
-    for prop in emoji_properties_additions.keys():
-        _emoji_properties[prop].update(emoji_properties_additions[prop])
-
-    _chars_by_age = parse_unicode_datafile(
-        path.join(ucd_path, 'DerivedAge.txt'), reverse=True)
-    sequences = parse_emoji_variants(
-        path.join(ucd_path, 'emoji-variation-sequences.txt'))
-    _text_variation_sequences, _emoji_variation_sequences = sequences
-    _emoji_sequences = parse_unicode_datafile(
-        path.join(ucd_path, 'emoji-sequences.txt'))
-    _emoji_sequences.update(parse_unicode_datafile(
-        path.join(ucd_path, 'additions', 'emoji-sequences.txt')))
-    _emoji_zwj_sequences = parse_unicode_datafile(
-        path.join(ucd_path, 'emoji-zwj-sequences.txt'))
-    _emoji_zwj_sequences.update(parse_unicode_datafile(
-        path.join(ucd_path, 'additions', 'emoji-zwj-sequences.txt')))
-
-
-def flag_sequence(territory_code):
-    return tuple(0x1F1E6 + ord(ch) - ord('A') for ch in territory_code)
-
-
-UNSUPPORTED_FLAGS = frozenset({
-    flag_sequence('BL'), flag_sequence('BQ'), flag_sequence('DG'),
-    flag_sequence('EA'), flag_sequence('EH'), flag_sequence('FK'),
-    flag_sequence('GF'), flag_sequence('GP'), flag_sequence('GS'),
-    flag_sequence('MF'), flag_sequence('MQ'), flag_sequence('NC'),
-    flag_sequence('PM'), flag_sequence('RE'), flag_sequence('TF'),
-    flag_sequence('WF'), flag_sequence('XK'), flag_sequence('YT'),
-})
-
-EQUIVALENT_FLAGS = {
-    flag_sequence('BV'): flag_sequence('NO'),
-    flag_sequence('CP'): flag_sequence('FR'),
-    flag_sequence('HM'): flag_sequence('AU'),
-    flag_sequence('SJ'): flag_sequence('NO'),
-    flag_sequence('UM'): flag_sequence('US'),
-}
-
-COMBINING_KEYCAP = 0x20E3
-
-LEGACY_ANDROID_EMOJI = {
-    0xFE4E5: flag_sequence('JP'),
-    0xFE4E6: flag_sequence('US'),
-    0xFE4E7: flag_sequence('FR'),
-    0xFE4E8: flag_sequence('DE'),
-    0xFE4E9: flag_sequence('IT'),
-    0xFE4EA: flag_sequence('GB'),
-    0xFE4EB: flag_sequence('ES'),
-    0xFE4EC: flag_sequence('RU'),
-    0xFE4ED: flag_sequence('CN'),
-    0xFE4EE: flag_sequence('KR'),
-    0xFE82C: (ord('#'), COMBINING_KEYCAP),
-    0xFE82E: (ord('1'), COMBINING_KEYCAP),
-    0xFE82F: (ord('2'), COMBINING_KEYCAP),
-    0xFE830: (ord('3'), COMBINING_KEYCAP),
-    0xFE831: (ord('4'), COMBINING_KEYCAP),
-    0xFE832: (ord('5'), COMBINING_KEYCAP),
-    0xFE833: (ord('6'), COMBINING_KEYCAP),
-    0xFE834: (ord('7'), COMBINING_KEYCAP),
-    0xFE835: (ord('8'), COMBINING_KEYCAP),
-    0xFE836: (ord('9'), COMBINING_KEYCAP),
-    0xFE837: (ord('0'), COMBINING_KEYCAP),
-}
-
-ZWJ_IDENTICALS = {
-    # KISS
-    (0x1F469, 0x200D, 0x2764, 0x200D, 0x1F48B, 0x200D, 0x1F468): 0x1F48F,
-    # COUPLE WITH HEART
-    (0x1F469, 0x200D, 0x2764, 0x200D, 0x1F468): 0x1F491,
-    # FAMILY
-    (0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F466): 0x1F46A,
-}
-
-ZWJ = 0x200D
-FEMALE_SIGN = 0x2640
-MALE_SIGN = 0x2642
-
-GENDER_DEFAULTS = [
-    (0x26F9, MALE_SIGN), # PERSON WITH BALL
-    (0x1F3C3, MALE_SIGN), # RUNNER
-    (0x1F3C4, MALE_SIGN), # SURFER
-    (0x1F3CA, MALE_SIGN), # SWIMMER
-    (0x1F3CB, MALE_SIGN), # WEIGHT LIFTER
-    (0x1F3CC, MALE_SIGN), # GOLFER
-    (0x1F46E, MALE_SIGN), # POLICE OFFICER
-    (0x1F46F, FEMALE_SIGN), # WOMAN WITH BUNNY EARS
-    (0x1F471, MALE_SIGN), # PERSON WITH BLOND HAIR
-    (0x1F473, MALE_SIGN), # MAN WITH TURBAN
-    (0x1F477, MALE_SIGN), # CONSTRUCTION WORKER
-    (0x1F481, FEMALE_SIGN), # INFORMATION DESK PERSON
-    (0x1F482, MALE_SIGN), # GUARDSMAN
-    (0x1F486, FEMALE_SIGN), # FACE MASSAGE
-    (0x1F487, FEMALE_SIGN), # HAIRCUT
-    (0x1F575, MALE_SIGN), # SLEUTH OR SPY
-    (0x1F645, FEMALE_SIGN), # FACE WITH NO GOOD GESTURE
-    (0x1F646, FEMALE_SIGN), # FACE WITH OK GESTURE
-    (0x1F647, MALE_SIGN), # PERSON BOWING DEEPLY
-    (0x1F64B, FEMALE_SIGN), # HAPPY PERSON RAISING ONE HAND
-    (0x1F64D, FEMALE_SIGN), # PERSON FROWNING
-    (0x1F64E, FEMALE_SIGN), # PERSON WITH POUTING FACE
-    (0x1F6A3, MALE_SIGN), # ROWBOAT
-    (0x1F6B4, MALE_SIGN), # BICYCLIST
-    (0x1F6B5, MALE_SIGN), # MOUNTAIN BICYCLIST
-    (0x1F6B6, MALE_SIGN), # PEDESTRIAN
-    (0x1F926, FEMALE_SIGN), # FACE PALM
-    (0x1F937, FEMALE_SIGN), # SHRUG
-    (0x1F938, MALE_SIGN), # PERSON DOING CARTWHEEL
-    (0x1F939, MALE_SIGN), # JUGGLING
-    (0x1F93C, MALE_SIGN), # WRESTLERS
-    (0x1F93D, MALE_SIGN), # WATER POLO
-    (0x1F93E, MALE_SIGN), # HANDBALL
-    (0x1F9D6, FEMALE_SIGN), # PERSON IN STEAMY ROOM
-    (0x1F9D7, FEMALE_SIGN), # PERSON CLIMBING
-    (0x1F9D8, FEMALE_SIGN), # PERSON IN LOTUS POSITION
-    (0x1F9D9, FEMALE_SIGN), # MAGE
-    (0x1F9DA, FEMALE_SIGN), # FAIRY
-    (0x1F9DB, FEMALE_SIGN), # VAMPIRE
-    (0x1F9DC, FEMALE_SIGN), # MERPERSON
-    (0x1F9DD, FEMALE_SIGN), # ELF
-    (0x1F9DE, FEMALE_SIGN), # GENIE
-    (0x1F9DF, FEMALE_SIGN), # ZOMBIE
-]
-
-def is_fitzpatrick_modifier(cp):
-    return 0x1F3FB <= cp <= 0x1F3FF
-
-
-def reverse_emoji(seq):
-    rev = list(reversed(seq))
-    # if there are fitzpatrick modifiers in the sequence, keep them after
-    # the emoji they modify
-    for i in xrange(1, len(rev)):
-        if is_fitzpatrick_modifier(rev[i-1]):
-            rev[i], rev[i-1] = rev[i-1], rev[i]
-    return tuple(rev)
-
-
-def compute_expected_emoji():
-    equivalent_emoji = {}
-    sequence_pieces = set()
-    all_sequences = set()
-    all_sequences.update(_emoji_variation_sequences)
-
-    # add zwj sequences not in the current emoji-zwj-sequences.txt
-    adjusted_emoji_zwj_sequences = dict(_emoji_zwj_sequences)
-    adjusted_emoji_zwj_sequences.update(_emoji_zwj_sequences)
-
-    # Add empty flag tag sequence that is supported as fallback
-    _emoji_sequences[(0x1F3F4, 0xE007F)] = 'Emoji_Tag_Sequence'
-
-    for sequence in _emoji_sequences.keys():
-        sequence = tuple(ch for ch in sequence if ch != EMOJI_VS)
-        all_sequences.add(sequence)
-        sequence_pieces.update(sequence)
-        if _emoji_sequences.get(sequence, None) == 'Emoji_Tag_Sequence':
-            # Add reverse of all emoji ZWJ sequences, which are added to the fonts
-            # as a workaround to get the sequences work in RTL text.
-            # TODO: test if these are actually needed by Minikin/HarfBuzz.
-            reversed_seq = reverse_emoji(sequence)
-            all_sequences.add(reversed_seq)
-            equivalent_emoji[reversed_seq] = sequence
-
-    for sequence in adjusted_emoji_zwj_sequences.keys():
-        sequence = tuple(ch for ch in sequence if ch != EMOJI_VS)
-        all_sequences.add(sequence)
-        sequence_pieces.update(sequence)
-        # Add reverse of all emoji ZWJ sequences, which are added to the fonts
-        # as a workaround to get the sequences work in RTL text.
-        reversed_seq = reverse_emoji(sequence)
-        all_sequences.add(reversed_seq)
-        equivalent_emoji[reversed_seq] = sequence
-
-    # Remove unsupported flags
-    all_sequences.difference_update(UNSUPPORTED_FLAGS)
-
-    # Add all tag characters used in flags
-    sequence_pieces.update(range(0xE0030, 0xE0039 + 1))
-    sequence_pieces.update(range(0xE0061, 0xE007A + 1))
-
-    all_emoji = (
-        _emoji_properties['Emoji'] |
-        all_sequences |
-        sequence_pieces |
-        set(LEGACY_ANDROID_EMOJI.keys()))
-    default_emoji = (
-        _emoji_properties['Emoji_Presentation'] |
-        all_sequences |
-        set(LEGACY_ANDROID_EMOJI.keys()))
-
-    equivalent_emoji.update(EQUIVALENT_FLAGS)
-    equivalent_emoji.update(LEGACY_ANDROID_EMOJI)
-    equivalent_emoji.update(ZWJ_IDENTICALS)
-
-    for ch, gender in GENDER_DEFAULTS:
-        equivalent_emoji[(ch, ZWJ, gender)] = ch
-        for skin_tone in range(0x1F3FB, 0x1F3FF+1):
-            skin_toned = (ch, skin_tone, ZWJ, gender)
-            if skin_toned in all_emoji:
-                equivalent_emoji[skin_toned] = (ch, skin_tone)
-
-    for seq in _emoji_variation_sequences:
-        equivalent_emoji[seq] = seq[0]
-
-    return all_emoji, default_emoji, equivalent_emoji
-
-
-def check_vertical_metrics():
-    for record in _fallback_chain:
-        if record.name in ['sans-serif', 'sans-serif-condensed']:
-            font = open_font(record.font)
-            assert font['head'].yMax == 2163 and font['head'].yMin == -555, (
-                'yMax and yMin of %s do not match expected values.' % (record.font,))
-
-        if record.name in ['sans-serif', 'sans-serif-condensed', 'serif', 'monospace']:
-            font = open_font(record.font)
-            assert font['hhea'].ascent == 1900 and font['hhea'].descent == -500, (
-                'ascent and descent of %s do not match expected values.' % (record.font,))
-
-
-def main():
-    global _fonts_dir
-    target_out = sys.argv[1]
-    _fonts_dir = path.join(target_out, 'fonts')
-
-    fonts_xml_path = path.join(target_out, 'etc', 'fonts.xml')
-    parse_fonts_xml(fonts_xml_path)
-
-    check_vertical_metrics()
-
-    hyphens_dir = path.join(target_out, 'usr', 'hyphen-data')
-    check_hyphens(hyphens_dir)
-
-    check_emoji = sys.argv[2]
-    if check_emoji == 'true':
-        ucd_path = sys.argv[3]
-        parse_ucd(ucd_path)
-        all_emoji, default_emoji, equivalent_emoji = compute_expected_emoji()
-        check_emoji_coverage(all_emoji, equivalent_emoji)
-        check_emoji_defaults(default_emoji)
-
-
-if __name__ == '__main__':
-    main()
diff --git a/tools/fonts/fontchain_linter.py b/tools/fonts/fontchain_linter.py
new file mode 100755
index 0000000..c6ad4c2a
--- /dev/null
+++ b/tools/fonts/fontchain_linter.py
@@ -0,0 +1,679 @@
+#!/usr/bin/env python
+
+import collections
+import copy
+import glob
+from os import path
+import sys
+from xml.etree import ElementTree
+
+from fontTools import ttLib
+
+EMOJI_VS = 0xFE0F
+
+LANG_TO_SCRIPT = {
+    'as': 'Beng',
+    'bg': 'Cyrl',
+    'bn': 'Beng',
+    'cu': 'Cyrl',
+    'cy': 'Latn',
+    'da': 'Latn',
+    'de': 'Latn',
+    'en': 'Latn',
+    'es': 'Latn',
+    'et': 'Latn',
+    'eu': 'Latn',
+    'fr': 'Latn',
+    'ga': 'Latn',
+    'gu': 'Gujr',
+    'hi': 'Deva',
+    'hr': 'Latn',
+    'hu': 'Latn',
+    'hy': 'Armn',
+    'ja': 'Jpan',
+    'kn': 'Knda',
+    'ko': 'Kore',
+    'ml': 'Mlym',
+    'mn': 'Cyrl',
+    'mr': 'Deva',
+    'nb': 'Latn',
+    'nn': 'Latn',
+    'or': 'Orya',
+    'pa': 'Guru',
+    'pt': 'Latn',
+    'sl': 'Latn',
+    'ta': 'Taml',
+    'te': 'Telu',
+    'tk': 'Latn',
+}
+
+def lang_to_script(lang_code):
+    lang = lang_code.lower()
+    while lang not in LANG_TO_SCRIPT:
+        hyphen_idx = lang.rfind('-')
+        assert hyphen_idx != -1, (
+            'We do not know what script the "%s" language is written in.'
+            % lang_code)
+        assumed_script = lang[hyphen_idx+1:]
+        if len(assumed_script) == 4 and assumed_script.isalpha():
+            # This is actually the script
+            return assumed_script.title()
+        lang = lang[:hyphen_idx]
+    return LANG_TO_SCRIPT[lang]
+
+
+def printable(inp):
+    if type(inp) is set:  # set of character sequences
+        return '{' + ', '.join([printable(seq) for seq in inp]) + '}'
+    if type(inp) is tuple:  # character sequence
+        return '<' + (', '.join([printable(ch) for ch in inp])) + '>'
+    else:  # single character
+        return 'U+%04X' % inp
+
+
+def open_font(font):
+    font_file, index = font
+    font_path = path.join(_fonts_dir, font_file)
+    if index is not None:
+        return ttLib.TTFont(font_path, fontNumber=index)
+    else:
+        return ttLib.TTFont(font_path)
+
+
+def get_best_cmap(font):
+    ttfont = open_font(font)
+    all_unicode_cmap = None
+    bmp_cmap = None
+    for cmap in ttfont['cmap'].tables:
+        specifier = (cmap.format, cmap.platformID, cmap.platEncID)
+        if specifier == (4, 3, 1):
+            assert bmp_cmap is None, 'More than one BMP cmap in %s' % (font, )
+            bmp_cmap = cmap
+        elif specifier == (12, 3, 10):
+            assert all_unicode_cmap is None, (
+                'More than one UCS-4 cmap in %s' % (font, ))
+            all_unicode_cmap = cmap
+
+    return all_unicode_cmap.cmap if all_unicode_cmap else bmp_cmap.cmap
+
+
+def get_variation_sequences_cmap(font):
+    ttfont = open_font(font)
+    vs_cmap = None
+    for cmap in ttfont['cmap'].tables:
+        specifier = (cmap.format, cmap.platformID, cmap.platEncID)
+        if specifier == (14, 0, 5):
+            assert vs_cmap is None, 'More than one VS cmap in %s' % (font, )
+            vs_cmap = cmap
+    return vs_cmap
+
+
+def get_emoji_map(font):
+    # Add normal characters
+    emoji_map = copy.copy(get_best_cmap(font))
+    reverse_cmap = {glyph: code for code, glyph in emoji_map.items()}
+
+    # Add variation sequences
+    vs_dict = get_variation_sequences_cmap(font).uvsDict
+    for vs in vs_dict:
+        for base, glyph in vs_dict[vs]:
+            if glyph is None:
+                emoji_map[(base, vs)] = emoji_map[base]
+            else:
+                emoji_map[(base, vs)] = glyph
+
+    # Add GSUB rules
+    ttfont = open_font(font)
+    for lookup in ttfont['GSUB'].table.LookupList.Lookup:
+        if lookup.LookupType != 4:
+            # Other lookups are used in the emoji font for fallback.
+            # We ignore them for now.
+            continue
+        for subtable in lookup.SubTable:
+            ligatures = subtable.ligatures
+            for first_glyph in ligatures:
+                for ligature in ligatures[first_glyph]:
+                    sequence = [first_glyph] + ligature.Component
+                    sequence = [reverse_cmap[glyph] for glyph in sequence]
+                    sequence = tuple(sequence)
+                    # Make sure no starting subsequence of 'sequence' has been
+                    # seen before.
+                    for sub_len in range(2, len(sequence)+1):
+                        subsequence = sequence[:sub_len]
+                        assert subsequence not in emoji_map
+                    emoji_map[sequence] = ligature.LigGlyph
+
+    return emoji_map
+
+
+def assert_font_supports_any_of_chars(font, chars):
+    best_cmap = get_best_cmap(font)
+    for char in chars:
+        if char in best_cmap:
+            return
+    sys.exit('None of characters in %s were found in %s' % (chars, font))
+
+
+def assert_font_supports_all_of_chars(font, chars):
+    best_cmap = get_best_cmap(font)
+    for char in chars:
+        assert char in best_cmap, (
+            'U+%04X was not found in %s' % (char, font))
+
+
+def assert_font_supports_none_of_chars(font, chars):
+    best_cmap = get_best_cmap(font)
+    for char in chars:
+        assert char not in best_cmap, (
+            'U+%04X was found in %s' % (char, font))
+
+
+def assert_font_supports_all_sequences(font, sequences):
+    vs_dict = get_variation_sequences_cmap(font).uvsDict
+    for base, vs in sorted(sequences):
+        assert vs in vs_dict and (base, None) in vs_dict[vs], (
+            '<U+%04X, U+%04X> was not found in %s' % (base, vs, font))
+
+
+def check_hyphens(hyphens_dir):
+    # Find all the scripts that need automatic hyphenation
+    scripts = set()
+    for hyb_file in glob.iglob(path.join(hyphens_dir, '*.hyb')):
+        hyb_file = path.basename(hyb_file)
+        assert hyb_file.startswith('hyph-'), (
+            'Unknown hyphenation file %s' % hyb_file)
+        lang_code = hyb_file[hyb_file.index('-')+1:hyb_file.index('.')]
+        scripts.add(lang_to_script(lang_code))
+
+    HYPHENS = {0x002D, 0x2010}
+    for script in scripts:
+        fonts = _script_to_font_map[script]
+        assert fonts, 'No fonts found for the "%s" script' % script
+        for font in fonts:
+            assert_font_supports_any_of_chars(font, HYPHENS)
+
+
+class FontRecord(object):
+    def __init__(self, name, scripts, variant, weight, style, font):
+        self.name = name
+        self.scripts = scripts
+        self.variant = variant
+        self.weight = weight
+        self.style = style
+        self.font = font
+
+
+def parse_fonts_xml(fonts_xml_path):
+    global _script_to_font_map, _fallback_chain
+    _script_to_font_map = collections.defaultdict(set)
+    _fallback_chain = []
+    tree = ElementTree.parse(fonts_xml_path)
+    families = tree.findall('family')
+    # Minikin supports up to 254 but users can place their own font at the first
+    # place. Thus, 253 is the maximum allowed number of font families in the
+    # default collection.
+    assert len(families) < 254, (
+        'System font collection can contains up to 253 font families.')
+    for family in families:
+        name = family.get('name')
+        variant = family.get('variant')
+        langs = family.get('lang')
+        if name:
+            assert variant is None, (
+                'No variant expected for LGC font %s.' % name)
+            assert langs is None, (
+                'No language expected for LGC fonts %s.' % name)
+        else:
+            assert variant in {None, 'elegant', 'compact'}, (
+                'Unexpected value for variant: %s' % variant)
+
+        if langs:
+            langs = langs.split()
+            scripts = {lang_to_script(lang) for lang in langs}
+        else:
+            scripts = set()
+
+        for child in family:
+            assert child.tag == 'font', (
+                'Unknown tag <%s>' % child.tag)
+            font_file = child.text.rstrip()
+            weight = int(child.get('weight'))
+            assert weight % 100 == 0, (
+                'Font weight "%d" is not a multiple of 100.' % weight)
+
+            style = child.get('style')
+            assert style in {'normal', 'italic'}, (
+                'Unknown style "%s"' % style)
+
+            index = child.get('index')
+            if index:
+                index = int(index)
+
+            _fallback_chain.append(FontRecord(
+                name,
+                frozenset(scripts),
+                variant,
+                weight,
+                style,
+                (font_file, index)))
+
+            if name: # non-empty names are used for default LGC fonts
+                map_scripts = {'Latn', 'Grek', 'Cyrl'}
+            else:
+                map_scripts = scripts
+            for script in map_scripts:
+                _script_to_font_map[script].add((font_file, index))
+
+
+def check_emoji_coverage(all_emoji, equivalent_emoji):
+    emoji_font = get_emoji_font()
+    check_emoji_font_coverage(emoji_font, all_emoji, equivalent_emoji)
+
+
+def get_emoji_font():
+    emoji_fonts = [
+        record.font for record in _fallback_chain
+        if 'Zsye' in record.scripts]
+    assert len(emoji_fonts) == 1, 'There are %d emoji fonts.' % len(emoji_fonts)
+    return emoji_fonts[0]
+
+
+def check_emoji_font_coverage(emoji_font, all_emoji, equivalent_emoji):
+    coverage = get_emoji_map(emoji_font)
+    for sequence in all_emoji:
+        assert sequence in coverage, (
+            '%s is not supported in the emoji font.' % printable(sequence))
+
+    for sequence in coverage:
+        if sequence in {0x0000, 0x000D, 0x0020}:
+            # The font needs to support a few extra characters, which is OK
+            continue
+        assert sequence in all_emoji, (
+            'Emoji font should not support %s.' % printable(sequence))
+
+    for first, second in sorted(equivalent_emoji.items()):
+        assert coverage[first] == coverage[second], (
+            '%s and %s should map to the same glyph.' % (
+                printable(first),
+                printable(second)))
+
+    for glyph in set(coverage.values()):
+        maps_to_glyph = [seq for seq in coverage if coverage[seq] == glyph]
+        if len(maps_to_glyph) > 1:
+            # There are more than one sequences mapping to the same glyph. We
+            # need to make sure they were expected to be equivalent.
+            equivalent_seqs = set()
+            for seq in maps_to_glyph:
+                equivalent_seq = seq
+                while equivalent_seq in equivalent_emoji:
+                    equivalent_seq = equivalent_emoji[equivalent_seq]
+                equivalent_seqs.add(equivalent_seq)
+            assert len(equivalent_seqs) == 1, (
+                'The sequences %s should not result in the same glyph %s' % (
+                    printable(equivalent_seqs),
+                    glyph))
+
+
+def check_emoji_defaults(default_emoji):
+    missing_text_chars = _emoji_properties['Emoji'] - default_emoji
+    emoji_font_seen = False
+    for record in _fallback_chain:
+        if 'Zsye' in record.scripts:
+            emoji_font_seen = True
+            # No need to check the emoji font
+            continue
+        # For later fonts, we only check them if they have a script
+        # defined, since the defined script may get them to a higher
+        # score even if they appear after the emoji font. However,
+        # we should skip checking the text symbols font, since
+        # symbol fonts should be able to override the emoji display
+        # style when 'Zsym' is explicitly specified by the user.
+        if emoji_font_seen and (not record.scripts or 'Zsym' in record.scripts):
+            continue
+
+        # Check default emoji-style characters
+        assert_font_supports_none_of_chars(record.font, sorted(default_emoji))
+
+        # Mark default text-style characters appearing in fonts above the emoji
+        # font as seen
+        if not emoji_font_seen:
+            missing_text_chars -= set(get_best_cmap(record.font))
+
+    # Noto does not have monochrome glyphs for Unicode 7.0 wingdings and
+    # webdings yet.
+    missing_text_chars -= _chars_by_age['7.0']
+    assert missing_text_chars == set(), (
+        'Text style version of some emoji characters are missing: ' +
+            repr(missing_text_chars))
+
+
+# Setting reverse to true returns a dictionary that maps the values to sets of
+# characters, useful for some binary properties. Otherwise, we get a
+# dictionary that maps characters to the property values, assuming there's only
+# one property in the file.
+def parse_unicode_datafile(file_path, reverse=False):
+    if reverse:
+        output_dict = collections.defaultdict(set)
+    else:
+        output_dict = {}
+    with open(file_path) as datafile:
+        for line in datafile:
+            if '#' in line:
+                line = line[:line.index('#')]
+            line = line.strip()
+            if not line:
+                continue
+
+            chars, prop = line.split(';')[:2]
+            chars = chars.strip()
+            prop = prop.strip()
+
+            if ' ' in chars:  # character sequence
+                sequence = [int(ch, 16) for ch in chars.split(' ')]
+                additions = [tuple(sequence)]
+            elif '..' in chars:  # character range
+                char_start, char_end = chars.split('..')
+                char_start = int(char_start, 16)
+                char_end = int(char_end, 16)
+                additions = xrange(char_start, char_end+1)
+            else:  # singe character
+                additions = [int(chars, 16)]
+            if reverse:
+                output_dict[prop].update(additions)
+            else:
+                for addition in additions:
+                    assert addition not in output_dict
+                    output_dict[addition] = prop
+    return output_dict
+
+
+def parse_emoji_variants(file_path):
+    emoji_set = set()
+    text_set = set()
+    with open(file_path) as datafile:
+        for line in datafile:
+            if '#' in line:
+                line = line[:line.index('#')]
+            line = line.strip()
+            if not line:
+                continue
+            sequence, description, _ = line.split(';')
+            sequence = sequence.strip().split(' ')
+            base = int(sequence[0], 16)
+            vs = int(sequence[1], 16)
+            description = description.strip()
+            if description == 'text style':
+                text_set.add((base, vs))
+            elif description == 'emoji style':
+                emoji_set.add((base, vs))
+    return text_set, emoji_set
+
+
+def parse_ucd(ucd_path):
+    global _emoji_properties, _chars_by_age
+    global _text_variation_sequences, _emoji_variation_sequences
+    global _emoji_sequences, _emoji_zwj_sequences
+    _emoji_properties = parse_unicode_datafile(
+        path.join(ucd_path, 'emoji-data.txt'), reverse=True)
+    emoji_properties_additions = parse_unicode_datafile(
+        path.join(ucd_path, 'additions', 'emoji-data.txt'), reverse=True)
+    for prop in emoji_properties_additions.keys():
+        _emoji_properties[prop].update(emoji_properties_additions[prop])
+
+    _chars_by_age = parse_unicode_datafile(
+        path.join(ucd_path, 'DerivedAge.txt'), reverse=True)
+    sequences = parse_emoji_variants(
+        path.join(ucd_path, 'emoji-variation-sequences.txt'))
+    _text_variation_sequences, _emoji_variation_sequences = sequences
+    _emoji_sequences = parse_unicode_datafile(
+        path.join(ucd_path, 'emoji-sequences.txt'))
+    _emoji_sequences.update(parse_unicode_datafile(
+        path.join(ucd_path, 'additions', 'emoji-sequences.txt')))
+    _emoji_zwj_sequences = parse_unicode_datafile(
+        path.join(ucd_path, 'emoji-zwj-sequences.txt'))
+    _emoji_zwj_sequences.update(parse_unicode_datafile(
+        path.join(ucd_path, 'additions', 'emoji-zwj-sequences.txt')))
+
+
+def flag_sequence(territory_code):
+    return tuple(0x1F1E6 + ord(ch) - ord('A') for ch in territory_code)
+
+
+UNSUPPORTED_FLAGS = frozenset({
+    flag_sequence('BL'), flag_sequence('BQ'), flag_sequence('DG'),
+    flag_sequence('EA'), flag_sequence('EH'), flag_sequence('FK'),
+    flag_sequence('GF'), flag_sequence('GP'), flag_sequence('GS'),
+    flag_sequence('MF'), flag_sequence('MQ'), flag_sequence('NC'),
+    flag_sequence('PM'), flag_sequence('RE'), flag_sequence('TF'),
+    flag_sequence('WF'), flag_sequence('XK'), flag_sequence('YT'),
+})
+
+EQUIVALENT_FLAGS = {
+    flag_sequence('BV'): flag_sequence('NO'),
+    flag_sequence('CP'): flag_sequence('FR'),
+    flag_sequence('HM'): flag_sequence('AU'),
+    flag_sequence('SJ'): flag_sequence('NO'),
+    flag_sequence('UM'): flag_sequence('US'),
+}
+
+COMBINING_KEYCAP = 0x20E3
+
+LEGACY_ANDROID_EMOJI = {
+    0xFE4E5: flag_sequence('JP'),
+    0xFE4E6: flag_sequence('US'),
+    0xFE4E7: flag_sequence('FR'),
+    0xFE4E8: flag_sequence('DE'),
+    0xFE4E9: flag_sequence('IT'),
+    0xFE4EA: flag_sequence('GB'),
+    0xFE4EB: flag_sequence('ES'),
+    0xFE4EC: flag_sequence('RU'),
+    0xFE4ED: flag_sequence('CN'),
+    0xFE4EE: flag_sequence('KR'),
+    0xFE82C: (ord('#'), COMBINING_KEYCAP),
+    0xFE82E: (ord('1'), COMBINING_KEYCAP),
+    0xFE82F: (ord('2'), COMBINING_KEYCAP),
+    0xFE830: (ord('3'), COMBINING_KEYCAP),
+    0xFE831: (ord('4'), COMBINING_KEYCAP),
+    0xFE832: (ord('5'), COMBINING_KEYCAP),
+    0xFE833: (ord('6'), COMBINING_KEYCAP),
+    0xFE834: (ord('7'), COMBINING_KEYCAP),
+    0xFE835: (ord('8'), COMBINING_KEYCAP),
+    0xFE836: (ord('9'), COMBINING_KEYCAP),
+    0xFE837: (ord('0'), COMBINING_KEYCAP),
+}
+
+ZWJ_IDENTICALS = {
+    # KISS
+    (0x1F469, 0x200D, 0x2764, 0x200D, 0x1F48B, 0x200D, 0x1F468): 0x1F48F,
+    # COUPLE WITH HEART
+    (0x1F469, 0x200D, 0x2764, 0x200D, 0x1F468): 0x1F491,
+    # FAMILY
+    (0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F466): 0x1F46A,
+}
+
+ZWJ = 0x200D
+FEMALE_SIGN = 0x2640
+MALE_SIGN = 0x2642
+
+GENDER_DEFAULTS = [
+    (0x26F9, MALE_SIGN), # PERSON WITH BALL
+    (0x1F3C3, MALE_SIGN), # RUNNER
+    (0x1F3C4, MALE_SIGN), # SURFER
+    (0x1F3CA, MALE_SIGN), # SWIMMER
+    (0x1F3CB, MALE_SIGN), # WEIGHT LIFTER
+    (0x1F3CC, MALE_SIGN), # GOLFER
+    (0x1F46E, MALE_SIGN), # POLICE OFFICER
+    (0x1F46F, FEMALE_SIGN), # WOMAN WITH BUNNY EARS
+    (0x1F471, MALE_SIGN), # PERSON WITH BLOND HAIR
+    (0x1F473, MALE_SIGN), # MAN WITH TURBAN
+    (0x1F477, MALE_SIGN), # CONSTRUCTION WORKER
+    (0x1F481, FEMALE_SIGN), # INFORMATION DESK PERSON
+    (0x1F482, MALE_SIGN), # GUARDSMAN
+    (0x1F486, FEMALE_SIGN), # FACE MASSAGE
+    (0x1F487, FEMALE_SIGN), # HAIRCUT
+    (0x1F575, MALE_SIGN), # SLEUTH OR SPY
+    (0x1F645, FEMALE_SIGN), # FACE WITH NO GOOD GESTURE
+    (0x1F646, FEMALE_SIGN), # FACE WITH OK GESTURE
+    (0x1F647, MALE_SIGN), # PERSON BOWING DEEPLY
+    (0x1F64B, FEMALE_SIGN), # HAPPY PERSON RAISING ONE HAND
+    (0x1F64D, FEMALE_SIGN), # PERSON FROWNING
+    (0x1F64E, FEMALE_SIGN), # PERSON WITH POUTING FACE
+    (0x1F6A3, MALE_SIGN), # ROWBOAT
+    (0x1F6B4, MALE_SIGN), # BICYCLIST
+    (0x1F6B5, MALE_SIGN), # MOUNTAIN BICYCLIST
+    (0x1F6B6, MALE_SIGN), # PEDESTRIAN
+    (0x1F926, FEMALE_SIGN), # FACE PALM
+    (0x1F937, FEMALE_SIGN), # SHRUG
+    (0x1F938, MALE_SIGN), # PERSON DOING CARTWHEEL
+    (0x1F939, MALE_SIGN), # JUGGLING
+    (0x1F93C, MALE_SIGN), # WRESTLERS
+    (0x1F93D, MALE_SIGN), # WATER POLO
+    (0x1F93E, MALE_SIGN), # HANDBALL
+    (0x1F9D6, FEMALE_SIGN), # PERSON IN STEAMY ROOM
+    (0x1F9D7, FEMALE_SIGN), # PERSON CLIMBING
+    (0x1F9D8, FEMALE_SIGN), # PERSON IN LOTUS POSITION
+    (0x1F9D9, FEMALE_SIGN), # MAGE
+    (0x1F9DA, FEMALE_SIGN), # FAIRY
+    (0x1F9DB, FEMALE_SIGN), # VAMPIRE
+    (0x1F9DC, FEMALE_SIGN), # MERPERSON
+    (0x1F9DD, FEMALE_SIGN), # ELF
+    (0x1F9DE, FEMALE_SIGN), # GENIE
+    (0x1F9DF, FEMALE_SIGN), # ZOMBIE
+]
+
+def is_fitzpatrick_modifier(cp):
+    return 0x1F3FB <= cp <= 0x1F3FF
+
+
+def reverse_emoji(seq):
+    rev = list(reversed(seq))
+    # if there are fitzpatrick modifiers in the sequence, keep them after
+    # the emoji they modify
+    for i in xrange(1, len(rev)):
+        if is_fitzpatrick_modifier(rev[i-1]):
+            rev[i], rev[i-1] = rev[i-1], rev[i]
+    return tuple(rev)
+
+
+def compute_expected_emoji():
+    equivalent_emoji = {}
+    sequence_pieces = set()
+    all_sequences = set()
+    all_sequences.update(_emoji_variation_sequences)
+
+    # add zwj sequences not in the current emoji-zwj-sequences.txt
+    adjusted_emoji_zwj_sequences = dict(_emoji_zwj_sequences)
+    adjusted_emoji_zwj_sequences.update(_emoji_zwj_sequences)
+
+    # Add empty flag tag sequence that is supported as fallback
+    _emoji_sequences[(0x1F3F4, 0xE007F)] = 'Emoji_Tag_Sequence'
+
+    for sequence in _emoji_sequences.keys():
+        sequence = tuple(ch for ch in sequence if ch != EMOJI_VS)
+        all_sequences.add(sequence)
+        sequence_pieces.update(sequence)
+        if _emoji_sequences.get(sequence, None) == 'Emoji_Tag_Sequence':
+            # Add reverse of all emoji ZWJ sequences, which are added to the
+            # fonts as a workaround to get the sequences work in RTL text.
+            # TODO: test if these are actually needed by Minikin/HarfBuzz.
+            reversed_seq = reverse_emoji(sequence)
+            all_sequences.add(reversed_seq)
+            equivalent_emoji[reversed_seq] = sequence
+
+    for sequence in adjusted_emoji_zwj_sequences.keys():
+        sequence = tuple(ch for ch in sequence if ch != EMOJI_VS)
+        all_sequences.add(sequence)
+        sequence_pieces.update(sequence)
+        # Add reverse of all emoji ZWJ sequences, which are added to the fonts
+        # as a workaround to get the sequences work in RTL text.
+        reversed_seq = reverse_emoji(sequence)
+        all_sequences.add(reversed_seq)
+        equivalent_emoji[reversed_seq] = sequence
+
+    # Remove unsupported flags
+    all_sequences.difference_update(UNSUPPORTED_FLAGS)
+
+    # Add all tag characters used in flags
+    sequence_pieces.update(range(0xE0030, 0xE0039 + 1))
+    sequence_pieces.update(range(0xE0061, 0xE007A + 1))
+
+    all_emoji = (
+        _emoji_properties['Emoji'] |
+        all_sequences |
+        sequence_pieces |
+        set(LEGACY_ANDROID_EMOJI.keys()))
+    default_emoji = (
+        _emoji_properties['Emoji_Presentation'] |
+        all_sequences |
+        set(LEGACY_ANDROID_EMOJI.keys()))
+
+    equivalent_emoji.update(EQUIVALENT_FLAGS)
+    equivalent_emoji.update(LEGACY_ANDROID_EMOJI)
+    equivalent_emoji.update(ZWJ_IDENTICALS)
+
+    for ch, gender in GENDER_DEFAULTS:
+        equivalent_emoji[(ch, ZWJ, gender)] = ch
+        for skin_tone in range(0x1F3FB, 0x1F3FF+1):
+            skin_toned = (ch, skin_tone, ZWJ, gender)
+            if skin_toned in all_emoji:
+                equivalent_emoji[skin_toned] = (ch, skin_tone)
+
+    for seq in _emoji_variation_sequences:
+        equivalent_emoji[seq] = seq[0]
+
+    return all_emoji, default_emoji, equivalent_emoji
+
+
+def check_vertical_metrics():
+    for record in _fallback_chain:
+        if record.name in ['sans-serif', 'sans-serif-condensed']:
+            font = open_font(record.font)
+            assert font['head'].yMax == 2163 and font['head'].yMin == -555, (
+                'yMax and yMin of %s do not match expected values.' % (
+                record.font,))
+
+        if record.name in ['sans-serif', 'sans-serif-condensed',
+                           'serif', 'monospace']:
+            font = open_font(record.font)
+            assert (font['hhea'].ascent == 1900 and
+                    font['hhea'].descent == -500), (
+                        'ascent and descent of %s do not match expected '
+                        'values.' % (record.font,))
+
+
+def check_cjk_punctuation():
+    cjk_scripts = {'Hans', 'Hant', 'Jpan', 'Kore'}
+    cjk_punctuation = range(0x3000, 0x301F + 1)
+    for record in _fallback_chain:
+        if record.scripts.intersection(cjk_scripts):
+            # CJK font seen. Stop checking the rest of the fonts.
+            break
+        assert_font_supports_none_of_chars(record.font, cjk_punctuation)
+
+
+def main():
+    global _fonts_dir
+    target_out = sys.argv[1]
+    _fonts_dir = path.join(target_out, 'fonts')
+
+    fonts_xml_path = path.join(target_out, 'etc', 'fonts.xml')
+    parse_fonts_xml(fonts_xml_path)
+
+    check_vertical_metrics()
+
+    hyphens_dir = path.join(target_out, 'usr', 'hyphen-data')
+    check_hyphens(hyphens_dir)
+
+    check_cjk_punctuation()
+
+    check_emoji = sys.argv[2]
+    if check_emoji == 'true':
+        ucd_path = sys.argv[3]
+        parse_ucd(ucd_path)
+        all_emoji, default_emoji, equivalent_emoji = compute_expected_emoji()
+        check_emoji_coverage(all_emoji, equivalent_emoji)
+        check_emoji_defaults(default_emoji)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/tools/incident_report/Android.bp b/tools/incident_report/Android.bp
new file mode 100644
index 0000000..f2d0d0f
--- /dev/null
+++ b/tools/incident_report/Android.bp
@@ -0,0 +1,35 @@
+//
+// 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.
+//
+
+// ==========================================================
+// Build the host executable: incident_report
+// ==========================================================
+cc_binary_host {
+    name: "incident_report",
+
+    srcs: [
+        "generic_message.cpp",
+        "main.cpp",
+        "printer.cpp",
+    ],
+
+    shared_libs: [
+        "libplatformprotos",
+        "libprotobuf-cpp-full",
+    ],
+
+    cflags: ["-Wall", "-Werror"],
+}
diff --git a/tools/incident_report/Android.mk b/tools/incident_report/Android.mk
deleted file mode 100644
index e57a959..0000000
--- a/tools/incident_report/Android.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH:= $(call my-dir)
-
-# ==========================================================
-# Build the host executable: protoc-gen-javastream
-# ==========================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := incident_report
-
-LOCAL_C_INCLUDES := \
-    external/protobuf/src
-
-LOCAL_SRC_FILES := \
-    generic_message.cpp \
-    main.cpp \
-    printer.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libplatformprotos \
-    libprotobuf-cpp-full
-
-# b/34740546, work around clang-tidy segmentation fault.
-LOCAL_TIDY_CHECKS := -modernize*
-
-LOCAL_C_FLAGS := \
-    -Wno-unused-parameter
-include $(BUILD_HOST_EXECUTABLE)
-
-
diff --git a/tools/incident_report/main.cpp b/tools/incident_report/main.cpp
index 884b8e4..1d8809f6 100644
--- a/tools/incident_report/main.cpp
+++ b/tools/incident_report/main.cpp
@@ -355,6 +355,7 @@
             args[argpos++] = NULL;
             execvp(args[0], (char*const*)args);
             fprintf(stderr, "execvp failed: %s\n", strerror(errno));
+            free(args);
             return 1;
         } else {
             // parent
@@ -400,6 +401,7 @@
         }
     }
 
+    free(buffer);
     return 0;
 }
 
diff --git a/tools/incident_report/printer.cpp b/tools/incident_report/printer.cpp
index bd660dd2..bff1025 100644
--- a/tools/incident_report/printer.cpp
+++ b/tools/incident_report/printer.cpp
@@ -70,7 +70,6 @@
 
     len = vsnprintf(mBuf, mBufSize, format, args);
     va_end(args);
-    bool truncated = (len >= mBufSize) && (reallocate(len) < len);
 
     va_start(args, format);
     len = vsnprintf(mBuf, mBufSize, format, args);
diff --git a/tools/incident_section_gen/Android.bp b/tools/incident_section_gen/Android.bp
new file mode 100644
index 0000000..f07445a
--- /dev/null
+++ b/tools/incident_section_gen/Android.bp
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+// ==========================================================
+// Build the host executable: incident-section-gen
+// ==========================================================
+cc_binary_host {
+    name: "incident-section-gen",
+    cflags: [
+        "-g",
+        "-O0",
+        "-Wall",
+        "-Werror",
+    ],
+    srcs: ["main.cpp"],
+    shared_libs: [
+        "libplatformprotos",
+        "libprotobuf-cpp-full",
+    ],
+}
diff --git a/tools/incident_section_gen/Android.mk b/tools/incident_section_gen/Android.mk
deleted file mode 100644
index 0549026..0000000
--- a/tools/incident_section_gen/Android.mk
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH:= $(call my-dir)
-
-# ==========================================================
-# Build the host executable: protoc-gen-javastream
-# ==========================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := incident-section-gen
-# b/34740546, work around clang-tidy segmentation fault.
-LOCAL_TIDY_CHECKS := -modernize*
-LOCAL_CFLAGS += -g -O0
-LOCAL_C_INCLUDES := \
-    external/protobuf/src
-LOCAL_SRC_FILES := \
-    main.cpp
-LOCAL_LDFLAGS := -ldl
-LOCAL_SHARED_LIBRARIES := \
-    libplatformprotos \
-    libprotobuf-cpp-full
-
-include $(BUILD_HOST_EXECUTABLE)
-
diff --git a/tools/layoutlib/.gitignore b/tools/layoutlib/.gitignore
deleted file mode 100644
index 819103d..0000000
--- a/tools/layoutlib/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-bin
-/.idea/workspace.xml
-/out
-/bridge/out
diff --git a/tools/layoutlib/.idea/.name b/tools/layoutlib/.idea/.name
deleted file mode 100644
index 10eb5c1..0000000
--- a/tools/layoutlib/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-layoutlib
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/artifacts/studio_android_widgets_jar.xml b/tools/layoutlib/.idea/artifacts/studio_android_widgets_jar.xml
deleted file mode 100644
index 0450be3..0000000
--- a/tools/layoutlib/.idea/artifacts/studio_android_widgets_jar.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<component name="ArtifactManager">
-  <artifact type="jar" name="studio-android-widgets:jar">
-    <output-path>$PROJECT_DIR$/out/artifacts/studio_android_widgets_jar</output-path>
-    <root id="archive" name="studio-android-widgets.jar">
-      <element id="module-output" name="studio-android-widgets" />
-    </root>
-  </artifact>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/artifacts/studio_android_widgets_src_jar.xml b/tools/layoutlib/.idea/artifacts/studio_android_widgets_src_jar.xml
deleted file mode 100644
index a844ca3..0000000
--- a/tools/layoutlib/.idea/artifacts/studio_android_widgets_src_jar.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<component name="ArtifactManager">
-  <artifact type="jar" name="studio-android-widgets-src:jar">
-    <output-path>$PROJECT_DIR$/out/artifacts/studio_android_widgets_src_jar</output-path>
-    <root id="archive" name="studio-android-widgets-src.jar">
-      <element id="dir-copy" path="$PROJECT_DIR$/studio-custom-widgets/src" />
-    </root>
-  </artifact>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/codeStyleSettings.xml b/tools/layoutlib/.idea/codeStyleSettings.xml
deleted file mode 100644
index ac90d1e..0000000
--- a/tools/layoutlib/.idea/codeStyleSettings.xml
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectCodeStyleSettingsManager">
-    <option name="PER_PROJECT_SETTINGS">
-      <value>
-        <option name="FIELD_NAME_PREFIX" value="m" />
-        <option name="STATIC_FIELD_NAME_PREFIX" value="s" />
-        <option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
-        <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
-        <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
-        <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
-          <value />
-        </option>
-        <option name="IMPORT_LAYOUT_TABLE">
-          <value>
-            <package name="com.android" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="org" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="android" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="java" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="" withSubpackages="true" static="true" />
-          </value>
-        </option>
-        <option name="RIGHT_MARGIN" value="100" />
-        <option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
-        <option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
-        <option name="JD_ADD_BLANK_AFTER_PARM_COMMENTS" value="true" />
-        <option name="JD_ADD_BLANK_AFTER_RETURN" value="true" />
-        <option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true" />
-        <option name="WRAP_COMMENTS" value="true" />
-        <JavaCodeStyleSettings>
-          <option name="CLASS_NAMES_IN_JAVADOC" value="3" />
-        </JavaCodeStyleSettings>
-        <XML>
-          <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
-        </XML>
-        <codeStyleSettings language="JAVA">
-          <option name="KEEP_LINE_BREAKS" value="false" />
-          <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
-          <option name="CALL_PARAMETERS_WRAP" value="1" />
-          <option name="METHOD_PARAMETERS_WRAP" value="1" />
-          <option name="THROWS_LIST_WRAP" value="1" />
-          <option name="EXTENDS_KEYWORD_WRAP" value="1" />
-          <option name="THROWS_KEYWORD_WRAP" value="1" />
-          <option name="BINARY_OPERATION_WRAP" value="1" />
-          <option name="TERNARY_OPERATION_WRAP" value="1" />
-          <option name="ARRAY_INITIALIZER_WRAP" value="1" />
-          <option name="ASSIGNMENT_WRAP" value="1" />
-          <option name="ASSERT_STATEMENT_WRAP" value="1" />
-          <option name="IF_BRACE_FORCE" value="3" />
-          <option name="DOWHILE_BRACE_FORCE" value="3" />
-          <option name="WHILE_BRACE_FORCE" value="3" />
-          <option name="FOR_BRACE_FORCE" value="3" />
-          <option name="WRAP_LONG_LINES" value="true" />
-          <arrangement>
-            <groups>
-              <group>
-                <type>GETTERS_AND_SETTERS</type>
-                <order>KEEP</order>
-              </group>
-              <group>
-                <type>OVERRIDDEN_METHODS</type>
-                <order>KEEP</order>
-              </group>
-            </groups>
-          </arrangement>
-        </codeStyleSettings>
-        <codeStyleSettings language="XML">
-          <indentOptions>
-            <option name="CONTINUATION_INDENT_SIZE" value="4" />
-          </indentOptions>
-        </codeStyleSettings>
-      </value>
-    </option>
-    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/compiler.xml b/tools/layoutlib/.idea/compiler.xml
deleted file mode 100644
index 35961a2..0000000
--- a/tools/layoutlib/.idea/compiler.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="CompilerConfiguration">
-    <option name="DEFAULT_COMPILER" value="Javac" />
-    <excludeFromCompile>
-      <directory url="file://$PROJECT_DIR$/create/tests/mock_data" includeSubdirectories="true" />
-    </excludeFromCompile>
-    <resourceExtensions />
-    <wildcardResourcePatterns>
-      <entry name="!?*.java" />
-      <entry name="!?*.form" />
-      <entry name="!?*.class" />
-      <entry name="!?*.groovy" />
-      <entry name="!?*.scala" />
-      <entry name="!?*.flex" />
-      <entry name="!?*.kt" />
-      <entry name="!?*.clj" />
-    </wildcardResourcePatterns>
-    <annotationProcessing>
-      <profile default="true" name="Default" enabled="false">
-        <processorPath useClasspath="true" />
-      </profile>
-    </annotationProcessing>
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/copyright/Android.xml b/tools/layoutlib/.idea/copyright/Android.xml
deleted file mode 100644
index d81d75d..0000000
--- a/tools/layoutlib/.idea/copyright/Android.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<component name="CopyrightManager">
-  <copyright>
-    <option name="notice" value="Copyright (C) &amp;#36;today.year The Android Open Source Project&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;     http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
-    <option name="keyword" value="Copyright" />
-    <option name="allowReplaceKeyword" value="" />
-    <option name="myName" value="Android" />
-    <option name="myLocal" value="true" />
-  </copyright>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/copyright/profiles_settings.xml b/tools/layoutlib/.idea/copyright/profiles_settings.xml
deleted file mode 100644
index 20145de..0000000
--- a/tools/layoutlib/.idea/copyright/profiles_settings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<component name="CopyrightManager">
-  <settings default="Android" />
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/encodings.xml b/tools/layoutlib/.idea/encodings.xml
deleted file mode 100644
index f758959..0000000
--- a/tools/layoutlib/.idea/encodings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false">
-    <file url="PROJECT" charset="UTF-8" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/inspectionProfiles/Project_Default.xml b/tools/layoutlib/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index 74fa549..0000000
--- a/tools/layoutlib/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<component name="InspectionProjectProfileManager">
-  <profile version="1.0" is_locked="false">
-    <option name="myName" value="Project Default" />
-    <option name="myLocal" value="false" />
-    <inspection_tool class="DefaultFileTemplate" enabled="false" level="WARNING" enabled_by_default="false">
-      <option name="CHECK_FILE_HEADER" value="true" />
-      <option name="CHECK_TRY_CATCH_SECTION" value="true" />
-      <option name="CHECK_METHOD_BODY" value="true" />
-    </inspection_tool>
-    <inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
-      <option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
-      <option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
-    </inspection_tool>
-    <inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true">
-      <option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="false" />
-      <option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="false" />
-      <option name="SUGGEST_PRIVATE_FOR_INNERS" value="true" />
-    </inspection_tool>
-  </profile>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/inspectionProfiles/profiles_settings.xml b/tools/layoutlib/.idea/inspectionProfiles/profiles_settings.xml
deleted file mode 100644
index 3b31283..0000000
--- a/tools/layoutlib/.idea/inspectionProfiles/profiles_settings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<component name="InspectionProjectProfileManager">
-  <settings>
-    <option name="PROJECT_PROFILE" value="Project Default" />
-    <option name="USE_PROJECT_PROFILE" value="true" />
-    <version value="1.0" />
-  </settings>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/framework_jar.xml b/tools/layoutlib/.idea/libraries/framework_jar.xml
deleted file mode 100644
index 6695a36..0000000
--- a/tools/layoutlib/.idea/libraries/framework_jar.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<component name="libraryTable">
-  <library name="framework.jar">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="file://$PROJECT_DIR$/../../core/java" />
-      <root url="file://$PROJECT_DIR$/../../graphics/java" />
-      <root url="file://$PROJECT_DIR$/../../../../libcore/luni/src/main/java" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/junit.xml b/tools/layoutlib/.idea/libraries/junit.xml
deleted file mode 100644
index ba46ebf..0000000
--- a/tools/layoutlib/.idea/libraries/junit.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
-  <library name="junit">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../out/host/common/obj/JAVA_LIBRARIES/junit-host_intermediates/javalib.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="file://$PROJECT_DIR$/../../../../external/junit/src" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml b/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml
deleted file mode 100644
index a873600..0000000
--- a/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
-  <library name="layoutlib_api-prebuilt">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-sources.jar!/" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/mockito.xml b/tools/layoutlib/.idea/libraries/mockito.xml
deleted file mode 100644
index 032963e..0000000
--- a/tools/layoutlib/.idea/libraries/mockito.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<component name="libraryTable">
-  <library name="mockito">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../out/host/common/obj/JAVA_LIBRARIES/mockito-host_intermediates/javalib.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES />
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/objenesis.xml b/tools/layoutlib/.idea/libraries/objenesis.xml
deleted file mode 100644
index 1484de5..0000000
--- a/tools/layoutlib/.idea/libraries/objenesis.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<component name="libraryTable">
-  <library name="objenesis">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../out/host/common/obj/JAVA_LIBRARIES/objenesis-host_intermediates/javalib.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES />
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/misc.xml b/tools/layoutlib/.idea/misc.xml
deleted file mode 100644
index 44b47f2..0000000
--- a/tools/layoutlib/.idea/misc.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="EntryPointsManager">
-    <entry_points version="2.0" />
-    <list size="1">
-      <item index="0" class="java.lang.String" itemvalue="com.android.tools.layoutlib.annotations.LayoutlibDelegate" />
-    </list>
-  </component>
-  <component name="FrameworkDetectionExcludesConfiguration">
-    <type id="android" />
-  </component>
-  <component name="NullableNotNullManager">
-    <option name="myDefaultNullable" value="android.annotation.Nullable" />
-    <option name="myDefaultNotNull" value="android.annotation.NonNull" />
-    <option name="myNullables">
-      <value>
-        <list size="6">
-          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
-          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
-          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
-          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
-          <item index="4" class="java.lang.String" itemvalue="com.android.annotations.Nullable" />
-          <item index="5" class="java.lang.String" itemvalue="android.annotation.Nullable" />
-        </list>
-      </value>
-    </option>
-    <option name="myNotNulls">
-      <value>
-        <list size="6">
-          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
-          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
-          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
-          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
-          <item index="4" class="java.lang.String" itemvalue="com.android.annotations.NonNull" />
-          <item index="5" class="java.lang.String" itemvalue="android.annotation.NonNull" />
-        </list>
-      </value>
-    </option>
-  </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
-    <output url="file://$PROJECT_DIR$/out" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/modules.xml b/tools/layoutlib/.idea/modules.xml
deleted file mode 100644
index 6ffc1cc..0000000
--- a/tools/layoutlib/.idea/modules.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectModuleManager">
-    <modules>
-      <module fileurl="file://$PROJECT_DIR$/bridge/bridge.iml" filepath="$PROJECT_DIR$/bridge/bridge.iml" />
-      <module fileurl="file://$PROJECT_DIR$/create/create.iml" filepath="$PROJECT_DIR$/create/create.iml" />
-      <module fileurl="file://$PROJECT_DIR$/legacy/legacy.iml" filepath="$PROJECT_DIR$/legacy/legacy.iml" />
-      <module fileurl="file://$PROJECT_DIR$/studio-custom-widgets/studio-android-widgets.iml" filepath="$PROJECT_DIR$/studio-custom-widgets/studio-android-widgets.iml" />
-    </modules>
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/runConfigurations/All_in_bridge.xml b/tools/layoutlib/.idea/runConfigurations/All_in_bridge.xml
deleted file mode 100644
index 0b22717..0000000
--- a/tools/layoutlib/.idea/runConfigurations/All_in_bridge.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="All in bridge" type="JUnit" factoryName="JUnit" singleton="true">
-    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
-    <module name="bridge" />
-    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-    <option name="ALTERNATIVE_JRE_PATH" value="" />
-    <option name="PACKAGE_NAME" value="" />
-    <option name="MAIN_CLASS_NAME" value="" />
-    <option name="METHOD_NAME" value="" />
-    <option name="TEST_OBJECT" value="package" />
-    <option name="VM_PARAMETERS" value="-ea" />
-    <option name="PARAMETERS" value="" />
-    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
-    <option name="ENV_VARIABLES" />
-    <option name="PASS_PARENT_ENVS" value="true" />
-    <option name="TEST_SEARCH_SCOPE">
-      <value defaultName="singleModule" />
-    </option>
-    <envs />
-    <patterns />
-    <RunnerSettings RunnerId="Run" />
-    <ConfigurationWrapper RunnerId="Run" />
-    <method />
-  </configuration>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/runConfigurations/All_in_create.xml b/tools/layoutlib/.idea/runConfigurations/All_in_create.xml
deleted file mode 100644
index b9cd419d..0000000
--- a/tools/layoutlib/.idea/runConfigurations/All_in_create.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="All in create" type="JUnit" factoryName="JUnit" singleton="false" nameIsGenerated="true">
-    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
-    <module name="create" />
-    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-    <option name="ALTERNATIVE_JRE_PATH" value="" />
-    <option name="PACKAGE_NAME" value="" />
-    <option name="MAIN_CLASS_NAME" value="" />
-    <option name="METHOD_NAME" value="" />
-    <option name="TEST_OBJECT" value="package" />
-    <option name="VM_PARAMETERS" value="-ea" />
-    <option name="PARAMETERS" value="" />
-    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
-    <option name="ENV_VARIABLES" />
-    <option name="PASS_PARENT_ENVS" value="true" />
-    <option name="TEST_SEARCH_SCOPE">
-      <value defaultName="singleModule" />
-    </option>
-    <envs />
-    <patterns />
-    <RunnerSettings RunnerId="Debug">
-      <option name="DEBUG_PORT" value="" />
-      <option name="TRANSPORT" value="0" />
-      <option name="LOCAL" value="true" />
-    </RunnerSettings>
-    <RunnerSettings RunnerId="Run" />
-    <ConfigurationWrapper RunnerId="Debug" />
-    <ConfigurationWrapper RunnerId="Run" />
-    <method />
-  </configuration>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/runConfigurations/Bridge_quick.xml b/tools/layoutlib/.idea/runConfigurations/Bridge_quick.xml
deleted file mode 100644
index b402849..0000000
--- a/tools/layoutlib/.idea/runConfigurations/Bridge_quick.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="Bridge quick" type="JUnit" factoryName="JUnit">
-    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
-    <module name="bridge" />
-    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-    <option name="ALTERNATIVE_JRE_PATH" value="" />
-    <option name="PACKAGE_NAME" />
-    <option name="MAIN_CLASS_NAME" value="" />
-    <option name="METHOD_NAME" value="" />
-    <option name="TEST_OBJECT" value="pattern" />
-    <option name="VM_PARAMETERS" value="-ea" />
-    <option name="PARAMETERS" value="" />
-    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
-    <option name="ENV_VARIABLES" />
-    <option name="PASS_PARENT_ENVS" value="true" />
-    <option name="TEST_SEARCH_SCOPE">
-      <value defaultName="singleModule" />
-    </option>
-    <envs />
-    <patterns>
-      <pattern testClass="com.android.layoutlib.bridge.TestDelegates" />
-      <pattern testClass="android.graphics.Matrix_DelegateTest" />
-      <pattern testClass="com.android.layoutlib.bridge.android.BridgeXmlBlockParserTest" />
-    </patterns>
-    <RunnerSettings RunnerId="Run" />
-    <ConfigurationWrapper RunnerId="Run" />
-    <method />
-  </configuration>
-</component>
diff --git a/tools/layoutlib/.idea/runConfigurations/Create.xml b/tools/layoutlib/.idea/runConfigurations/Create.xml
deleted file mode 100644
index 536a23f..0000000
--- a/tools/layoutlib/.idea/runConfigurations/Create.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="Create" type="Application" factoryName="Application" singleton="true">
-    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
-    <option name="MAIN_CLASS_NAME" value="com.android.tools.layoutlib.create.Main" />
-    <option name="VM_PARAMETERS" value="-ea" />
-    <option name="PROGRAM_PARAMETERS" value="out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar out/host/common/obj/JAVA_LIBRARIES/icu4j-icudata-host-jarjar_intermediates/classes-jarjar.jar out/host/common/obj/JAVA_LIBRARIES/icu4j-icutzdata-host-jarjar_intermediates/classes-jarjar.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/javalib.jar" />
-    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/../../../../" />
-    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-    <option name="ALTERNATIVE_JRE_PATH" value="" />
-    <option name="ENABLE_SWING_INSPECTOR" value="false" />
-    <option name="ENV_VARIABLES" />
-    <option name="PASS_PARENT_ENVS" value="true" />
-    <module name="create" />
-    <envs />
-    <RunnerSettings RunnerId="Debug">
-      <option name="DEBUG_PORT" value="" />
-      <option name="TRANSPORT" value="0" />
-      <option name="LOCAL" value="true" />
-    </RunnerSettings>
-    <RunnerSettings RunnerId="Run" />
-    <ConfigurationWrapper RunnerId="Debug" />
-    <ConfigurationWrapper RunnerId="Run" />
-    <method />
-  </configuration>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/scopes/scope_settings.xml b/tools/layoutlib/.idea/scopes/scope_settings.xml
deleted file mode 100644
index 922003b..0000000
--- a/tools/layoutlib/.idea/scopes/scope_settings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<component name="DependencyValidationManager">
-  <state>
-    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
-  </state>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/uiDesigner.xml b/tools/layoutlib/.idea/uiDesigner.xml
deleted file mode 100644
index 3b00020..0000000
--- a/tools/layoutlib/.idea/uiDesigner.xml
+++ /dev/null
@@ -1,125 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="Palette2">
-    <group name="Swing">
-      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
-      </item>
-      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
-      </item>
-      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
-      </item>
-      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
-        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
-      </item>
-      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
-        <initial-values>
-          <property name="text" value="Button" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
-        <initial-values>
-          <property name="text" value="RadioButton" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
-        <initial-values>
-          <property name="text" value="CheckBox" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
-        <initial-values>
-          <property name="text" value="Label" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
-          <preferred-size width="150" height="-1" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
-          <preferred-size width="150" height="-1" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
-          <preferred-size width="150" height="-1" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
-      </item>
-      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
-          <preferred-size width="200" height="200" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
-          <preferred-size width="200" height="200" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
-      </item>
-      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
-      </item>
-      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
-      </item>
-      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
-      </item>
-      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
-          <preferred-size width="-1" height="20" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
-      </item>
-      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
-      </item>
-    </group>
-  </component>
-</project>
-
diff --git a/tools/layoutlib/.idea/vcs.xml b/tools/layoutlib/.idea/vcs.xml
deleted file mode 100644
index 9ab281a..0000000
--- a/tools/layoutlib/.idea/vcs.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="VcsDirectoryMappings">
-    <mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
-  </component>
-</project>
-
diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk
deleted file mode 100644
index 29c933a..0000000
--- a/tools/layoutlib/Android.mk
+++ /dev/null
@@ -1,82 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(my-dir)
-include $(CLEAR_VARS)
-
-#
-# Define rules to build temp_layoutlib.jar, which contains a subset of
-# the classes in framework.jar.  The layoutlib_create tool is used to
-# transform the framework jar into the temp_layoutlib jar.
-#
-
-# We need to process the framework classes.jar file, but we can't
-# depend directly on it (private vars won't be inherited correctly).
-# So, we depend on framework's BUILT file.
-built_framework_dep := $(call java-lib-deps,framework)
-built_framework_classes := $(call java-lib-files,framework)
-
-built_oj_dep := $(call java-lib-deps,core-oj)
-built_oj_classes := $(call java-lib-files,core-oj)
-
-built_core_dep := $(call java-lib-deps,core-libart)
-built_core_classes := $(call java-lib-files,core-libart)
-
-built_ext_dep := $(call java-lib-deps,ext)
-built_ext_classes := $(call java-lib-files,ext)
-
-built_icudata_dep := $(call java-lib-deps,icu4j-icudata-host-jarjar,HOST)
-built_icutzdata_dep := $(call java-lib-deps,icu4j-icutzdata-host-jarjar,HOST)
-
-built_layoutlib_create_jar := $(call java-lib-files,layoutlib_create,HOST)
-
-# This is mostly a copy of config/host_java_library.mk
-LOCAL_MODULE := temp_layoutlib
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
-LOCAL_IS_HOST_MODULE := true
-LOCAL_BUILT_MODULE_STEM := classes.jar
-
-#######################################
-include $(BUILD_SYSTEM)/base_rules.mk
-#######################################
-
-$(LOCAL_BUILT_MODULE): $(built_oj_dep) \
-                       $(built_core_dep) \
-                       $(built_framework_dep) \
-                       $(built_ext_dep) \
-		       $(built_icudata_dep) \
-		       $(built_icutzdata_dep) \
-                       $(built_layoutlib_create_jar)
-	$(hide) echo "host layoutlib_create: $@"
-	$(hide) mkdir -p $(dir $@)
-	$(hide) rm -f $@
-	$(hide) ls -l $(built_framework_classes)
-	$(hide) java -ea -jar $(built_layoutlib_create_jar) \
-	             $@ \
-	             $(built_oj_classes) \
-	             $(built_core_classes) \
-	             $(built_framework_classes) \
-	             $(built_ext_classes) \
-		     $(built_icudata_dep) \
-		     $(built_icutzdata_dep) \
-	             $(built_ext_data)
-	$(hide) ls -l $(built_framework_classes)
-
-
-#
-# Include the subdir makefiles.
-#
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/layoutlib/README b/tools/layoutlib/README
deleted file mode 100644
index 0fea9bd..0000000
--- a/tools/layoutlib/README
+++ /dev/null
@@ -1,4 +0,0 @@
-Layoutlib is a custom version of the android View framework designed to run inside Eclipse.
-The goal of the library is to provide layout rendering in Eclipse that are very very close to their rendering on devices.
-
-None of the com.android.* or android.* classes in layoutlib run on devices.
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
deleted file mode 100644
index 9c4160c..0000000
--- a/tools/layoutlib/bridge/.classpath
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry excluding="org/kxml2/io/" kind="src" path="src"/>
-	<classpathentry kind="src" path="tests/src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar" sourcepath="/ANDROID_SRC/tools/base/layoutlib-api/src/main"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/tools-common/tools-common-prebuilt.jar"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/icu4j/icu4j.jar"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/sdk-common/sdk-common.jar"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/guavalib_intermediates/javalib.jar"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/layoutlib/bridge/.project b/tools/layoutlib/bridge/.project
deleted file mode 100644
index e36e71b..0000000
--- a/tools/layoutlib/bridge/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>layoutlib_bridge</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/layoutlib/bridge/.settings/README.txt b/tools/layoutlib/bridge/.settings/README.txt
deleted file mode 100644
index 9120b20..0000000
--- a/tools/layoutlib/bridge/.settings/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Copy this in eclipse project as a .settings folder at the root.
-This ensure proper compilation compliance and warning/error levels.
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/.settings/org.eclipse.jdt.core.prefs b/tools/layoutlib/bridge/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 5381a0e..0000000
--- a/tools/layoutlib/bridge/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,93 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.nonnull=com.android.annotations.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=com.android.annotations.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled
-org.eclipse.jdt.core.compiler.annotation.nullable=com.android.annotations.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=error
-org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk
deleted file mode 100644
index 3dd8002..0000000
--- a/tools/layoutlib/bridge/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
-LOCAL_JAVA_LIBRARIES := \
-	layoutlib_api-prebuilt \
-	tools-common-prebuilt
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-	temp_layoutlib \
-	ninepatch-prebuilt
-
-LOCAL_MODULE := layoutlib
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/tools/layoutlib/bridge/bridge.iml b/tools/layoutlib/bridge/bridge.iml
deleted file mode 100644
index 85ec3eb..0000000
--- a/tools/layoutlib/bridge/bridge.iml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/res" type="java-test-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/src" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/src/main/myapplication.widgets" isTestSource="true" />
-      <excludeFolder url="file://$MODULE_DIR$/.settings" />
-      <excludeFolder url="file://$MODULE_DIR$/bin" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/.gradle" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/.idea" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/generated" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/assets" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/dependency-cache" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/incremental" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/libs" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/manifests" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/res" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/rs" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/symbols" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/gradle" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
-    <orderEntry type="module-library">
-      <library name="ninepatch-prebuilt">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="file://$ANDROID_SRC$/tools/base/ninepatch/src/main/java" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="module-library">
-      <library name="tools-common-prebuilt">
-        <ANNOTATIONS>
-          <root url="file://$MODULE_DIR$/.." />
-        </ANNOTATIONS>
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt-sources.jar!/" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="library" name="framework.jar" level="project" />
-    <orderEntry type="module-library" scope="TEST">
-      <library name="kxml2-2.3.0">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="file://$MODULE_DIR$/../../../../../libcore/xml/src/main/java" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="module-library" scope="TEST">
-      <library name="guava">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0-sources.jar!/" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="module-library" scope="TEST">
-      <library name="sdk-common">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/sdk-common/sdk-common.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/sdk-common/sdk-common-sources.jar!/" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="library" scope="TEST" name="junit" level="project" />
-    <orderEntry type="library" scope="TEST" name="mockito" level="project" />
-    <orderEntry type="library" scope="TEST" name="objenesis" level="project" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/resources/bars/README b/tools/layoutlib/bridge/resources/bars/README
deleted file mode 100644
index c84ef80..0000000
--- a/tools/layoutlib/bridge/resources/bars/README
+++ /dev/null
@@ -1,8 +0,0 @@
-The directory contains the resources for StatusBar and Navigation Bar.
-
-The resources are not arranged as per the standard resources configuration.
-They are stored per API. However, to prevent duplication of resources, each API
-resource directory is used as a backup for all earlier API levels.
-
-For example, for the back icon for ICS, we search first in v18, where we don't
-find it, and then in v19.
diff --git a/tools/layoutlib/bridge/resources/bars/navigation_bar.xml b/tools/layoutlib/bridge/resources/bars/navigation_bar.xml
deleted file mode 100644
index 55bd1d2..0000000
--- a/tools/layoutlib/bridge/resources/bars/navigation_bar.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-	<View
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:layout_weight="1"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:layout_weight="1"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:visibility="invisible"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/navigation_bar600dp.xml b/tools/layoutlib/bridge/resources/bars/navigation_bar600dp.xml
deleted file mode 100644
index e208a0d..0000000
--- a/tools/layoutlib/bridge/resources/bars/navigation_bar600dp.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-	<View
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:layout_weight="1"
-		  	android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:layout_weight="1"
-			android:visibility="invisible"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/status_bar.xml b/tools/layoutlib/bridge/resources/bars/status_bar.xml
deleted file mode 100644
index 04571e1..0000000
--- a/tools/layoutlib/bridge/resources/bars/status_bar.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"/>
-    <!-- The exact size of the wifi icon is specified in order to scale it properly.
-    Without scaling, it appeared huge. This is currently, 70% of the actual size. -->
-    <ImageView
-            android:layout_height="22.4dp"
-            android:layout_width="20.65dp"
-            android:layout_marginTop="1dp"/>
-    <ImageView
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_marginLeft="3dp"
-            android:layout_marginRight="5dp"
-            android:layout_marginTop="4dp"/>
-    <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="4dp"
-            android:layout_marginRight="5dp"
-            android:gravity="center_vertical"
-            android:textSize="16dp"
-            android:fontFamily="sans-serif-medium"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/title_bar.xml b/tools/layoutlib/bridge/resources/bars/title_bar.xml
deleted file mode 100644
index 76d78d9..0000000
--- a/tools/layoutlib/bridge/resources/bars/title_bar.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-	<TextView
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_battery_100.png
deleted file mode 100644
index c920ec4..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 6248cfd..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_battery_100.png
deleted file mode 100644
index 943332e..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 441de0c..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_battery_100.png
deleted file mode 100644
index 36c61e1..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 459a1a2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_back.png
deleted file mode 100644
index 84e6bc8..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_home.png
deleted file mode 100644
index 38e4f45..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_recent.png
deleted file mode 100644
index bf9f300..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 6248cfd..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/hdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_back.png
deleted file mode 100644
index 782ebfe..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_recent.png
deleted file mode 100644
index 677b471..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_back.png
deleted file mode 100644
index a1b8062..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index fcdbefe..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_back.png
deleted file mode 100644
index 633d864..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 4665e2a..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_back.png
deleted file mode 100644
index a00bc5b..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_home.png
deleted file mode 100644
index dc3183b..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_recent.png
deleted file mode 100644
index b07f611..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 441de0c..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/mdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_back.png
deleted file mode 100644
index bd60cd6..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_home.png
deleted file mode 100644
index c5bc5c9..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index f621d9c..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 459a1a2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_back.png
deleted file mode 100644
index 79cfcee..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_home.png
deleted file mode 100644
index 64f6a22..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 6e0b071..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 494b005..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_back.png
deleted file mode 100644
index d2760bb..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_home.png
deleted file mode 100644
index df43e21b..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_recent.png
deleted file mode 100644
index 6fab1d6..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_100.png
deleted file mode 100644
index f17189a..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-hdpi/ic_sysbar_back.png
deleted file mode 100644
index 2fcfdde..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-mdpi/ic_sysbar_back.png
deleted file mode 100644
index 48708a5..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xhdpi/ic_sysbar_back.png
deleted file mode 100644
index 3d73184..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xxhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xxhdpi/ic_sysbar_back.png
deleted file mode 100644
index 786935d..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_back.png
deleted file mode 100644
index 1d8c3af..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_home.png
deleted file mode 100644
index 66de0ec..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_recent.png
deleted file mode 100644
index 30c65f5..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_100.png
deleted file mode 100644
index 2a9757d..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_back.png
deleted file mode 100644
index a356285..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_home.png
deleted file mode 100644
index ba2d0b2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 94a74b1..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_100.png
deleted file mode 100644
index 555bcd9..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml
deleted file mode 100644
index 0498b6c..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
-</vector>
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_back.png
deleted file mode 100644
index 29da099..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_home.png
deleted file mode 100644
index 59b32f2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index ba66d27..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/stat_sys_battery_100.png
deleted file mode 100644
index 6474aad..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_battery_100.png
deleted file mode 100644
index 754cdf6..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index b5326d2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/ldpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v9/ldpi/stat_sys_battery_100.png
deleted file mode 100644
index 7023ea7b..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/ldpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_battery_100.png
deleted file mode 100644
index 17a955d..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 19165ab..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-b.png b/tools/layoutlib/bridge/resources/icons/shadow-b.png
deleted file mode 100644
index 68f4f4b..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-b.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-bl.png b/tools/layoutlib/bridge/resources/icons/shadow-bl.png
deleted file mode 100644
index ee7dbe8..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-bl.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-br.png b/tools/layoutlib/bridge/resources/icons/shadow-br.png
deleted file mode 100644
index c45ad77..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-br.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-l.png b/tools/layoutlib/bridge/resources/icons/shadow-l.png
deleted file mode 100644
index 77d0bd0..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-l.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-r.png b/tools/layoutlib/bridge/resources/icons/shadow-r.png
deleted file mode 100644
index 4af7a33..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-r.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-tl.png b/tools/layoutlib/bridge/resources/icons/shadow-tl.png
deleted file mode 100644
index 424fb36..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-tl.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-tr.png b/tools/layoutlib/bridge/resources/icons/shadow-tr.png
deleted file mode 100644
index 1fd0c772..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-tr.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-b.png b/tools/layoutlib/bridge/resources/icons/shadow2-b.png
deleted file mode 100644
index 963973e..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-b.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-bl.png b/tools/layoutlib/bridge/resources/icons/shadow2-bl.png
deleted file mode 100644
index 7612487..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-bl.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-br.png b/tools/layoutlib/bridge/resources/icons/shadow2-br.png
deleted file mode 100644
index 8e20252..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-br.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-l.png b/tools/layoutlib/bridge/resources/icons/shadow2-l.png
deleted file mode 100644
index 2db18a0..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-l.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-r.png b/tools/layoutlib/bridge/resources/icons/shadow2-r.png
deleted file mode 100644
index 8e026f1..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-r.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-tl.png b/tools/layoutlib/bridge/resources/icons/shadow2-tl.png
deleted file mode 100644
index a8045ed..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-tl.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-tr.png b/tools/layoutlib/bridge/resources/icons/shadow2-tr.png
deleted file mode 100644
index 590373c..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-tr.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/src/android/animation/AnimationThread.java b/tools/layoutlib/bridge/src/android/animation/AnimationThread.java
deleted file mode 100644
index ce2aec79..0000000
--- a/tools/layoutlib/bridge/src/android/animation/AnimationThread.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.animation;
-
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-
-import android.os.Handler;
-import android.os.Handler_Delegate;
-import android.os.Message;
-
-import java.util.PriorityQueue;
-import java.util.Queue;
-
-/**
- * Abstract animation thread.
- * <p/>
- * This does not actually start an animation, instead it fakes a looper that will play whatever
- * animation is sending messages to its own {@link Handler}.
- * <p/>
- * Classes should implement {@link #preAnimation()} and {@link #postAnimation()}.
- * <p/>
- * If {@link #preAnimation()} does not start an animation somehow then the thread doesn't do
- * anything.
- *
- */
-public abstract class AnimationThread extends Thread {
-
-    private static class MessageBundle implements Comparable<MessageBundle> {
-        final Handler mTarget;
-        final Message mMessage;
-        final long mUptimeMillis;
-
-        MessageBundle(Handler target, Message message, long uptimeMillis) {
-            mTarget = target;
-            mMessage = message;
-            mUptimeMillis = uptimeMillis;
-        }
-
-        @Override
-        public int compareTo(MessageBundle bundle) {
-            if (mUptimeMillis < bundle.mUptimeMillis) {
-                return -1;
-            }
-            return 1;
-        }
-    }
-
-    private final RenderSessionImpl mSession;
-
-    private Queue<MessageBundle> mQueue = new PriorityQueue<MessageBundle>();
-    private final IAnimationListener mListener;
-
-    public AnimationThread(RenderSessionImpl scene, String threadName,
-            IAnimationListener listener) {
-        super(threadName);
-        mSession = scene;
-        mListener = listener;
-    }
-
-    public abstract Result preAnimation();
-    public abstract void postAnimation();
-
-    @Override
-    public void run() {
-        Bridge.prepareThread();
-        try {
-            /* FIXME: The ANIMATION_FRAME message no longer exists.  Instead, the
-             * animation timing loop is completely based on a Choreographer objects
-             * that schedules animation and drawing frames.  The animation handler is
-             * no longer even a handler; it is just a Runnable enqueued on the Choreographer.
-            Handler_Delegate.setCallback(new IHandlerCallback() {
-                @Override
-                public void sendMessageAtTime(Handler handler, Message msg, long uptimeMillis) {
-                    if (msg.what == ValueAnimator.ANIMATION_START ||
-                            msg.what == ValueAnimator.ANIMATION_FRAME) {
-                        mQueue.add(new MessageBundle(handler, msg, uptimeMillis));
-                    } else {
-                        // just ignore.
-                    }
-                }
-            });
-            */
-
-            // call out to the pre-animation work, which should start an animation or more.
-            Result result = preAnimation();
-            if (result.isSuccess() == false) {
-                mListener.done(result);
-            }
-
-            // loop the animation
-            RenderSession session = mSession.getSession();
-            do {
-                // check early.
-                if (mListener.isCanceled()) {
-                    break;
-                }
-
-                // get the next message.
-                MessageBundle bundle = mQueue.poll();
-                if (bundle == null) {
-                    break;
-                }
-
-                // sleep enough for this bundle to be on time
-                long currentTime = System.currentTimeMillis();
-                if (currentTime < bundle.mUptimeMillis) {
-                    try {
-                        sleep(bundle.mUptimeMillis - currentTime);
-                    } catch (InterruptedException e) {
-                        // FIXME log/do something/sleep again?
-                        e.printStackTrace();
-                    }
-                }
-
-                // check after sleeping.
-                if (mListener.isCanceled()) {
-                    break;
-                }
-
-                // ready to do the work, acquire the scene.
-                result = mSession.acquire(250);
-                if (result.isSuccess() == false) {
-                    mListener.done(result);
-                    return;
-                }
-
-                // process the bundle. If the animation is not finished, this will enqueue
-                // the next message, so mQueue will have another one.
-                try {
-                    // check after acquiring in case it took a while.
-                    if (mListener.isCanceled()) {
-                        break;
-                    }
-
-                    bundle.mTarget.handleMessage(bundle.mMessage);
-                    if (mSession.render(false /*freshRender*/).isSuccess()) {
-                        mListener.onNewFrame(session);
-                    }
-                } finally {
-                    mSession.release();
-                }
-            } while (mListener.isCanceled() == false && mQueue.size() > 0);
-
-            mListener.done(Status.SUCCESS.createResult());
-
-        } catch (Throwable throwable) {
-            // can't use Bridge.getLog() as the exception might be thrown outside
-            // of an acquire/release block.
-            mListener.done(Status.ERROR_UNKNOWN.createResult("Error playing animation", throwable));
-
-        } finally {
-            postAnimation();
-            Handler_Delegate.setCallback(null);
-            Bridge.cleanupThread();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
deleted file mode 100644
index 28a489a..0000000
--- a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.animation;
-
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Delegate implementing the native methods of android.animation.PropertyValuesHolder
- *
- * Through the layoutlib_create tool, the original native methods of PropertyValuesHolder have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- * The main goal of this class' methods are to provide a native way to access setters and getters
- * on some object. We override these methods to use reflection since the original reflection
- * implementation of the PropertyValuesHolder won't be able to access protected methods.
- *
- */
-/*package*/
-@SuppressWarnings("unused")
-class PropertyValuesHolder_Delegate {
-    // This code is copied from android.animation.PropertyValuesHolder and must be kept in sync
-    // We try several different types when searching for appropriate setter/getter functions.
-    // The caller may have supplied values in a type that does not match the setter/getter
-    // functions (such as the integers 0 and 1 to represent floating point values for alpha).
-    // Also, the use of generics in constructors means that we end up with the Object versions
-    // of primitive types (Float vs. float). But most likely, the setter/getter functions
-    // will take primitive types instead.
-    // So we supply an ordered array of other types to try before giving up.
-    private static Class[] FLOAT_VARIANTS = {float.class, Float.class, double.class, int.class,
-            Double.class, Integer.class};
-    private static Class[] INTEGER_VARIANTS = {int.class, Integer.class, float.class, double.class,
-            Float.class, Double.class};
-
-    private static final Object sMethodIndexLock = new Object();
-    private static final Map<Long, Method> ID_TO_METHOD = new HashMap<Long, Method>();
-    private static final Map<String, Long> METHOD_NAME_TO_ID = new HashMap<String, Long>();
-    private static long sNextId = 1;
-
-    private static long registerMethod(Class<?> targetClass, String methodName, Class[] types,
-            int nArgs) {
-        // Encode the number of arguments in the method name
-        String methodIndexName = String.format("%1$s.%2$s#%3$d", targetClass.getSimpleName(),
-                methodName, nArgs);
-        synchronized (sMethodIndexLock) {
-            Long methodId = METHOD_NAME_TO_ID.get(methodIndexName);
-
-            if (methodId != null) {
-                // The method was already registered
-                return methodId;
-            }
-
-            Class[] args = new Class[nArgs];
-            Method method = null;
-            for (Class typeVariant : types) {
-                for (int i = 0; i < nArgs; i++) {
-                    args[i] = typeVariant;
-                }
-                try {
-                    method = targetClass.getDeclaredMethod(methodName, args);
-                } catch (NoSuchMethodException ignore) {
-                }
-            }
-
-            if (method != null) {
-                methodId = sNextId++;
-                ID_TO_METHOD.put(methodId, method);
-                METHOD_NAME_TO_ID.put(methodIndexName, methodId);
-
-                return methodId;
-            }
-        }
-
-        // Method not found
-        return 0;
-    }
-
-    private static void callMethod(Object target, long methodID, Object... args) {
-        Method method = ID_TO_METHOD.get(methodID);
-        assert method != null;
-
-        try {
-            method.setAccessible(true);
-            method.invoke(target, args);
-        } catch (IllegalAccessException e) {
-            Bridge.getLog().error(null, "Unable to update property during animation", e, null);
-        } catch (InvocationTargetException e) {
-            Bridge.getLog().error(null, "Unable to update property during animation", e, null);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetIntMethod(Class<?> targetClass, String methodName) {
-        return nGetMultipleIntMethod(targetClass, methodName, 1);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetFloatMethod(Class<?> targetClass, String methodName) {
-        return nGetMultipleFloatMethod(targetClass, methodName, 1);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetMultipleIntMethod(Class<?> targetClass, String methodName,
-            int numParams) {
-        return registerMethod(targetClass, methodName, INTEGER_VARIANTS, numParams);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetMultipleFloatMethod(Class<?> targetClass, String methodName,
-            int numParams) {
-        return registerMethod(targetClass, methodName, FLOAT_VARIANTS, numParams);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallIntMethod(Object target, long methodID, int arg) {
-        callMethod(target, methodID, arg);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallFloatMethod(Object target, long methodID, float arg) {
-        callMethod(target, methodID, arg);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallTwoIntMethod(Object target, long methodID, int arg1,
-            int arg2) {
-        callMethod(target, methodID, arg1, arg2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallFourIntMethod(Object target, long methodID, int arg1,
-            int arg2, int arg3, int arg4) {
-        callMethod(target, methodID, arg1, arg2, arg3, arg4);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallMultipleIntMethod(Object target, long methodID,
-            int[] args) {
-        assert args != null;
-
-        // Box parameters
-        Object[] params = new Object[args.length];
-        for (int i = 0; i < args.length; i++) {
-            params[i] = args;
-        }
-        callMethod(target, methodID, params);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallTwoFloatMethod(Object target, long methodID, float arg1,
-            float arg2) {
-        callMethod(target, methodID, arg1, arg2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallFourFloatMethod(Object target, long methodID, float arg1,
-            float arg2, float arg3, float arg4) {
-        callMethod(target, methodID, arg1, arg2, arg3, arg4);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallMultipleFloatMethod(Object target, long methodID,
-            float[] args) {
-        assert args != null;
-
-        // Box parameters
-        Object[] params = new Object[args.length];
-        for (int i = 0; i < args.length; i++) {
-            params[i] = args;
-        }
-        callMethod(target, methodID, params);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java b/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
deleted file mode 100644
index f7654ce..0000000
--- a/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app;
-
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-import android.os.Bundle;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Fragment}
- *
- * Through the layoutlib_create tool, the original  methods of Fragment have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * The methods being re-implemented are the ones responsible for instantiating Fragment objects.
- * Because the classes of these objects are found in the project, these methods need access to
- * {@link LayoutlibCallback} object. They are however static methods, so the callback is set
- * before the inflation through {@link #setLayoutlibCallback(LayoutlibCallback)}.
- */
-public class Fragment_Delegate {
-
-    private static LayoutlibCallback sLayoutlibCallback;
-
-    /**
-     * Sets the current {@link LayoutlibCallback} to be used to instantiate classes coming
-     * from the project being rendered.
-     */
-    public static void setLayoutlibCallback(LayoutlibCallback layoutlibCallback) {
-        sLayoutlibCallback = layoutlibCallback;
-    }
-
-    /**
-     * Like {@link #instantiate(Context, String, Bundle)} but with a null
-     * argument Bundle.
-     */
-    @LayoutlibDelegate
-    /*package*/ static Fragment instantiate(Context context, String fname) {
-        return instantiate(context, fname, null);
-    }
-
-    /**
-     * Create a new instance of a Fragment with the given class name.  This is
-     * the same as calling its empty constructor.
-     *
-     * @param context The calling context being used to instantiate the fragment.
-     * This is currently just used to get its ClassLoader.
-     * @param fname The class name of the fragment to instantiate.
-     * @param args Bundle of arguments to supply to the fragment, which it
-     * can retrieve with {@link Fragment#getArguments()}.  May be null.
-     * @return Returns a new fragment instance.
-     * @throws Fragment.InstantiationException If there is a failure in instantiating
-     * the given fragment class.  This is a runtime exception; it is not
-     * normally expected to happen.
-     */
-    @LayoutlibDelegate
-    /*package*/ static Fragment instantiate(Context context, String fname, Bundle args) {
-        try {
-            if (sLayoutlibCallback != null) {
-                Fragment f = (Fragment) sLayoutlibCallback.loadView(fname,
-                        new Class[0], new Object[0]);
-
-                if (args != null) {
-                    args.setClassLoader(f.getClass().getClassLoader());
-                    f.mArguments = args;
-                }
-                return f;
-            }
-
-            return null;
-        } catch (ClassNotFoundException e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        } catch (java.lang.InstantiationException e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        } catch (IllegalAccessException e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        } catch (Exception e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/app/SystemServiceRegistry_Accessor.java b/tools/layoutlib/bridge/src/android/app/SystemServiceRegistry_Accessor.java
deleted file mode 100644
index 591aee0..0000000
--- a/tools/layoutlib/bridge/src/android/app/SystemServiceRegistry_Accessor.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app;
-
-/**
- * Class to allow accessing {@link SystemServiceRegistry#getSystemServiceName}
- */
-public class SystemServiceRegistry_Accessor {
-    /**
-     * Gets the name of the system-level service that is represented by the specified class.
-     */
-    public static String getSystemServiceName(Class<?> serviceClass) {
-        return SystemServiceRegistry.getSystemServiceName(serviceClass);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java
deleted file mode 100644
index b4d5288..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.util.SparseArray;
-
-/**
- * Delegate used to provide implementation of a select few native methods of {@link AssetManager}
- * <p/>
- * Through the layoutlib_create tool, the original native methods of AssetManager have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class AssetManager_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static long newTheme(AssetManager manager) {
-        return Resources_Theme_Delegate.getDelegateManager()
-                .addNewDelegate(new Resources_Theme_Delegate());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void deleteTheme(AssetManager manager, long theme) {
-        Resources_Theme_Delegate.getDelegateManager().removeJavaReferenceFor(theme);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static SparseArray<String> getAssignedPackageIdentifiers(AssetManager manager) {
-        return new SparseArray<>();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeAssetManager.java b/tools/layoutlib/bridge/src/android/content/res/BridgeAssetManager.java
deleted file mode 100644
index 2691e56..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeAssetManager.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import com.android.ide.common.rendering.api.AssetRepository;
-import com.android.layoutlib.bridge.Bridge;
-
-public class BridgeAssetManager extends AssetManager {
-
-    private AssetRepository mAssetRepository;
-
-    /**
-     * This initializes the static field {@link AssetManager#sSystem} which is used
-     * by methods who get a global asset manager using {@link AssetManager#getSystem()}.
-     * <p/>
-     * They will end up using our bridge asset manager.
-     * <p/>
-     * {@link Bridge} calls this method after setting up a new bridge.
-     */
-    public static AssetManager initSystem() {
-        if (!(AssetManager.sSystem instanceof BridgeAssetManager)) {
-            // Note that AssetManager() creates a system AssetManager and we override it
-            // with our BridgeAssetManager.
-            AssetManager.sSystem = new BridgeAssetManager();
-            AssetManager.sSystem.makeStringBlocks(null);
-        }
-        return AssetManager.sSystem;
-    }
-
-    /**
-     * Clears the static {@link AssetManager#sSystem} to make sure we don't leave objects
-     * around that would prevent us from unloading the library.
-     */
-    public static void clearSystem() {
-        AssetManager.sSystem = null;
-    }
-
-    public void setAssetRepository(AssetRepository assetRepository) {
-        mAssetRepository = assetRepository;
-    }
-
-    public AssetRepository getAssetRepository() {
-        return mAssetRepository;
-    }
-
-    public BridgeAssetManager() {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
deleted file mode 100644
index cda8e6a..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ /dev/null
@@ -1,991 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import com.android.ide.common.rendering.api.ArrayResourceValue;
-import com.android.ide.common.rendering.api.AttrResourceValue;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.ResourceType;
-
-import android.annotation.Nullable;
-import android.content.res.Resources.NotFoundException;
-import android.content.res.Resources.Theme;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.LayoutInflater_Delegate;
-import android.view.ViewGroup.LayoutParams;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Map;
-
-import static android.util.TypedValue.TYPE_ATTRIBUTE;
-import static android.util.TypedValue.TYPE_DIMENSION;
-import static android.util.TypedValue.TYPE_FLOAT;
-import static android.util.TypedValue.TYPE_INT_BOOLEAN;
-import static android.util.TypedValue.TYPE_INT_COLOR_ARGB4;
-import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8;
-import static android.util.TypedValue.TYPE_INT_COLOR_RGB4;
-import static android.util.TypedValue.TYPE_INT_COLOR_RGB8;
-import static android.util.TypedValue.TYPE_INT_DEC;
-import static android.util.TypedValue.TYPE_INT_HEX;
-import static android.util.TypedValue.TYPE_NULL;
-import static android.util.TypedValue.TYPE_REFERENCE;
-import static android.util.TypedValue.TYPE_STRING;
-import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
-import static com.android.SdkConstants.PREFIX_THEME_REF;
-import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_EMPTY;
-import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_NULL;
-import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_UNDEFINED;
-
-/**
- * Custom implementation of TypedArray to handle non compiled resources.
- */
-public final class BridgeTypedArray extends TypedArray {
-
-    private final Resources mBridgeResources;
-    private final BridgeContext mContext;
-    private final boolean mPlatformFile;
-
-    private final ResourceValue[] mResourceData;
-    private final String[] mNames;
-    private final boolean[] mIsFramework;
-
-    // Contains ids that are @empty. We still store null in mResourceData for that index, since we
-    // want to save on the check against empty, each time a resource value is requested.
-    @Nullable
-    private int[] mEmptyIds;
-
-    public BridgeTypedArray(Resources resources, BridgeContext context, int len,
-            boolean platformFile) {
-        super(resources);
-        mBridgeResources = resources;
-        mContext = context;
-        mPlatformFile = platformFile;
-        mResourceData = new ResourceValue[len];
-        mNames = new String[len];
-        mIsFramework = new boolean[len];
-    }
-
-    /**
-     * A bridge-specific method that sets a value in the type array
-     * @param index the index of the value in the TypedArray
-     * @param name the name of the attribute
-     * @param isFramework whether the attribute is in the android namespace.
-     * @param value the value of the attribute
-     */
-    public void bridgeSetValue(int index, String name, boolean isFramework, ResourceValue value) {
-        mResourceData[index] = value;
-        mNames[index] = name;
-        mIsFramework[index] = isFramework;
-    }
-
-    /**
-     * Seals the array after all calls to
-     * {@link #bridgeSetValue(int, String, boolean, ResourceValue)} have been done.
-     * <p/>This allows to compute the list of non default values, permitting
-     * {@link #getIndexCount()} to return the proper value.
-     */
-    public void sealArray() {
-        // fills TypedArray.mIndices which is used to implement getIndexCount/getIndexAt
-        // first count the array size
-        int count = 0;
-        ArrayList<Integer> emptyIds = null;
-        for (int i = 0; i < mResourceData.length; i++) {
-            ResourceValue data = mResourceData[i];
-            if (data != null) {
-                String dataValue = data.getValue();
-                if (REFERENCE_NULL.equals(dataValue) || REFERENCE_UNDEFINED.equals(dataValue)) {
-                    mResourceData[i] = null;
-                } else if (REFERENCE_EMPTY.equals(dataValue)) {
-                    mResourceData[i] = null;
-                    if (emptyIds == null) {
-                        emptyIds = new ArrayList<Integer>(4);
-                    }
-                    emptyIds.add(i);
-                } else {
-                    count++;
-                }
-            }
-        }
-
-        if (emptyIds != null) {
-            mEmptyIds = new int[emptyIds.size()];
-            for (int i = 0; i < emptyIds.size(); i++) {
-                mEmptyIds[i] = emptyIds.get(i);
-            }
-        }
-
-        // allocate the table with an extra to store the size
-        mIndices = new int[count+1];
-        mIndices[0] = count;
-
-        // fill the array with the indices.
-        int index = 1;
-        for (int i = 0 ; i < mResourceData.length ; i++) {
-            if (mResourceData[i] != null) {
-                mIndices[index++] = i;
-            }
-        }
-    }
-
-    /**
-     * Set the theme to be used for inflating drawables.
-     */
-    public void setTheme(Theme theme) {
-        mTheme = theme;
-    }
-
-    /**
-     * Return the number of values in this array.
-     */
-    @Override
-    public int length() {
-        return mResourceData.length;
-    }
-
-    /**
-     * Return the Resources object this array was loaded from.
-     */
-    @Override
-    public Resources getResources() {
-        return mBridgeResources;
-    }
-
-    /**
-     * Retrieve the styled string value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return CharSequence holding string data.  May be styled.  Returns
-     *         null if the attribute is not defined.
-     */
-    @Override
-    public CharSequence getText(int index) {
-        // FIXME: handle styled strings!
-        return getString(index);
-    }
-
-    /**
-     * Retrieve the string value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return String holding string data.  Any styling information is
-     * removed.  Returns null if the attribute is not defined.
-     */
-    @Override
-    public String getString(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-        // As unfortunate as it is, it's possible to use enums with all attribute formats,
-        // not just integers/enums. So, we need to search the enums always. In case
-        // enums are used, the returned value is an integer.
-        Integer v = resolveEnumAttribute(index);
-        return v == null ? mResourceData[index].getValue() : String.valueOf((int) v);
-    }
-
-    /**
-     * Retrieve the boolean value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined.
-     *
-     * @return Attribute boolean value, or defValue if not defined.
-     */
-    @Override
-    public boolean getBoolean(int index, boolean defValue) {
-        String s = getString(index);
-        return s == null ? defValue : XmlUtils.convertValueToBoolean(s, defValue);
-
-    }
-
-    /**
-     * Retrieve the integer value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined.
-     *
-     * @return Attribute int value, or defValue if not defined.
-     */
-    @Override
-    public int getInt(int index, int defValue) {
-        String s = getString(index);
-        try {
-            return convertValueToInt(s, defValue);
-        } catch (NumberFormatException e) {
-            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                    String.format("\"%1$s\" in attribute \"%2$s\" is not a valid integer",
-                            s, mNames[index]),
-                    null);
-        }
-        return defValue;
-    }
-
-    /**
-     * Retrieve the float value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Attribute float value, or defValue if not defined..
-     */
-    @Override
-    public float getFloat(int index, float defValue) {
-        String s = getString(index);
-        try {
-            if (s != null) {
-                    return Float.parseFloat(s);
-            }
-        } catch (NumberFormatException e) {
-            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                    String.format("\"%1$s\" in attribute \"%2$s\" cannot be converted to float.",
-                            s, mNames[index]),
-                    null);
-        }
-        return defValue;
-    }
-
-    /**
-     * Retrieve the color value for the attribute at <var>index</var>.  If
-     * the attribute references a color resource holding a complex
-     * {@link android.content.res.ColorStateList}, then the default color from
-     * the set is returned.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute color value, or defValue if not defined.
-     */
-    @Override
-    public int getColor(int index, int defValue) {
-        if (index < 0 || index >= mResourceData.length) {
-            return defValue;
-        }
-
-        if (mResourceData[index] == null) {
-            return defValue;
-        }
-
-        ColorStateList colorStateList = ResourceHelper.getColorStateList(
-                mResourceData[index], mContext);
-        if (colorStateList != null) {
-            return colorStateList.getDefaultColor();
-        }
-
-        return defValue;
-    }
-
-    @Override
-    public ColorStateList getColorStateList(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-
-        return ResourceHelper.getColorStateList(mResourceData[index], mContext);
-    }
-
-    @Override
-    public ComplexColor getComplexColor(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-
-        return ResourceHelper.getComplexColor(mResourceData[index], mContext);
-    }
-
-    /**
-     * Retrieve the integer value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute integer value, or defValue if not defined.
-     */
-    @Override
-    public int getInteger(int index, int defValue) {
-        return getInt(index, defValue);
-    }
-
-    /**
-     * Retrieve a dimensional unit attribute at <var>index</var>.  Unit
-     * conversions are based on the current {@link DisplayMetrics}
-     * associated with the resources this {@link TypedArray} object
-     * came from.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric, or defValue if not defined.
-     *
-     * @see #getDimensionPixelOffset
-     * @see #getDimensionPixelSize
-     */
-    @Override
-    public float getDimension(int index, float defValue) {
-        String s = getString(index);
-        if (s == null) {
-            return defValue;
-        }
-        // Check if the value is a magic constant that doesn't require a unit.
-        try {
-            int i = Integer.parseInt(s);
-            if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) {
-                return i;
-            }
-        } catch (NumberFormatException ignored) {
-            // pass
-        }
-
-        if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) {
-            return mValue.getDimension(mBridgeResources.getDisplayMetrics());
-        }
-
-        return defValue;
-    }
-
-    /**
-     * Retrieve a dimensional unit attribute at <var>index</var> for use
-     * as an offset in raw pixels.  This is the same as
-     * {@link #getDimension}, except the returned value is converted to
-     * integer pixels for you.  An offset conversion involves simply
-     * truncating the base value to an integer.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric and truncated to integer pixels, or defValue if not defined.
-     *
-     * @see #getDimension
-     * @see #getDimensionPixelSize
-     */
-    @Override
-    public int getDimensionPixelOffset(int index, int defValue) {
-        return (int) getDimension(index, defValue);
-    }
-
-    /**
-     * Retrieve a dimensional unit attribute at <var>index</var> for use
-     * as a size in raw pixels.  This is the same as
-     * {@link #getDimension}, except the returned value is converted to
-     * integer pixels for use as a size.  A size conversion involves
-     * rounding the base value, and ensuring that a non-zero base value
-     * is at least one pixel in size.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric and truncated to integer pixels, or defValue if not defined.
-     *
-     * @see #getDimension
-     * @see #getDimensionPixelOffset
-     */
-    @Override
-    public int getDimensionPixelSize(int index, int defValue) {
-        try {
-            return getDimension(index, null);
-        } catch (RuntimeException e) {
-            String s = getString(index);
-
-            if (s != null) {
-                // looks like we were unable to resolve the dimension value
-                Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                        String.format("\"%1$s\" in attribute \"%2$s\" is not a valid format.",
-                                s, mNames[index]), null);
-            }
-
-            return defValue;
-        }
-    }
-
-    /**
-     * Special version of {@link #getDimensionPixelSize} for retrieving
-     * {@link android.view.ViewGroup}'s layout_width and layout_height
-     * attributes.  This is only here for performance reasons; applications
-     * should use {@link #getDimensionPixelSize}.
-     *
-     * @param index Index of the attribute to retrieve.
-     * @param name Textual name of attribute for error reporting.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric and truncated to integer pixels.
-     */
-    @Override
-    public int getLayoutDimension(int index, String name) {
-        try {
-            // this will throw an exception if not found.
-            return getDimension(index, name);
-        } catch (RuntimeException e) {
-
-            if (LayoutInflater_Delegate.sIsInInclude) {
-                throw new RuntimeException("Layout Dimension '" + name + "' not found.");
-            }
-
-            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                    "You must supply a " + name + " attribute.", null);
-
-            return 0;
-        }
-    }
-
-    @Override
-    public int getLayoutDimension(int index, int defValue) {
-        return getDimensionPixelSize(index, defValue);
-    }
-
-    /** @param name attribute name, used for error reporting. */
-    private int getDimension(int index, @Nullable String name) {
-        String s = getString(index);
-        if (s == null) {
-            if (name != null) {
-                throw new RuntimeException("Attribute '" + name + "' not found");
-            }
-            throw new RuntimeException();
-        }
-        // Check if the value is a magic constant that doesn't require a unit.
-        try {
-            int i = Integer.parseInt(s);
-            if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) {
-                return i;
-            }
-        } catch (NumberFormatException ignored) {
-            // pass
-        }
-        if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) {
-            float f = mValue.getDimension(mBridgeResources.getDisplayMetrics());
-
-            final int res = (int)(f+0.5f);
-            if (res != 0) return res;
-            if (f == 0) return 0;
-            if (f > 0) return 1;
-        }
-
-        throw new RuntimeException();
-    }
-
-    /**
-     * Retrieve a fractional unit attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param base The base value of this fraction.  In other words, a
-     *             standard fraction is multiplied by this value.
-     * @param pbase The parent base value of this fraction.  In other
-     *             words, a parent fraction (nn%p) is multiplied by this
-     *             value.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute fractional value multiplied by the appropriate
-     * base value, or defValue if not defined.
-     */
-    @Override
-    public float getFraction(int index, int base, int pbase, float defValue) {
-        String value = getString(index);
-        if (value == null) {
-            return defValue;
-        }
-
-        if (ResourceHelper.parseFloatAttribute(mNames[index], value, mValue, false)) {
-            return mValue.getFraction(base, pbase);
-        }
-
-        // looks like we were unable to resolve the fraction value
-        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                String.format(
-                        "\"%1$s\" in attribute \"%2$s\" cannot be converted to a fraction.",
-                        value, mNames[index]), null);
-
-        return defValue;
-    }
-
-    /**
-     * Retrieve the resource identifier for the attribute at
-     * <var>index</var>.  Note that attribute resource as resolved when
-     * the overall {@link TypedArray} object is retrieved.  As a
-     * result, this function will return the resource identifier of the
-     * final resource value that was found, <em>not</em> necessarily the
-     * original resource that was specified by the attribute.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute resource identifier, or defValue if not defined.
-     */
-    @Override
-    public int getResourceId(int index, int defValue) {
-        if (index < 0 || index >= mResourceData.length) {
-            return defValue;
-        }
-
-        // get the Resource for this index
-        ResourceValue resValue = mResourceData[index];
-
-        // no data, return the default value.
-        if (resValue == null) {
-            return defValue;
-        }
-
-        // check if this is a style resource
-        if (resValue instanceof StyleResourceValue) {
-            // get the id that will represent this style.
-            return mContext.getDynamicIdByStyle((StyleResourceValue)resValue);
-        }
-
-        // if the attribute was a reference to a resource, and not a declaration of an id (@+id),
-        // then the xml attribute value was "resolved" which leads us to a ResourceValue with a
-        // valid getType() and getName() returning a resource name.
-        // (and getValue() returning null!). We need to handle this!
-        if (resValue.getResourceType() != null) {
-            // if this is a framework id
-            if (mPlatformFile || resValue.isFramework()) {
-                // look for idName in the android R classes
-                return mContext.getFrameworkResourceValue(
-                        resValue.getResourceType(), resValue.getName(), defValue);
-            }
-
-            // look for idName in the project R class.
-            return mContext.getProjectResourceValue(
-                    resValue.getResourceType(), resValue.getName(), defValue);
-        }
-
-        // else, try to get the value, and resolve it somehow.
-        String value = resValue.getValue();
-        if (value == null) {
-            return defValue;
-        }
-        value = value.trim();
-
-        // if the value is just an integer, return it.
-        try {
-            int i = Integer.parseInt(value);
-            if (Integer.toString(i).equals(value)) {
-                return i;
-            }
-        } catch (NumberFormatException e) {
-            // pass
-        }
-
-        if (value.startsWith("#")) {
-            // this looks like a color, do not try to parse it
-            return defValue;
-        }
-
-        // Handle the @id/<name>, @+id/<name> and @android:id/<name>
-        // We need to return the exact value that was compiled (from the various R classes),
-        // as these values can be reused internally with calls to findViewById().
-        // There's a trick with platform layouts that not use "android:" but their IDs are in
-        // fact in the android.R and com.android.internal.R classes.
-        // The field mPlatformFile will indicate that all IDs are to be looked up in the android R
-        // classes exclusively.
-
-        // if this is a reference to an id, find it.
-        if (value.startsWith("@id/") || value.startsWith("@+") ||
-                value.startsWith("@android:id/")) {
-
-            int pos = value.indexOf('/');
-            String idName = value.substring(pos + 1);
-            boolean create = value.startsWith("@+");
-            boolean isFrameworkId =
-                    mPlatformFile || value.startsWith("@android") || value.startsWith("@+android");
-
-            // Look for the idName in project or android R class depending on isPlatform.
-            if (create) {
-                Integer idValue;
-                if (isFrameworkId) {
-                    idValue = Bridge.getResourceId(ResourceType.ID, idName);
-                } else {
-                    idValue = mContext.getLayoutlibCallback().getResourceId(ResourceType.ID, idName);
-                }
-                return idValue == null ? defValue : idValue;
-            }
-            // This calls the same method as in if(create), but doesn't create a dynamic id, if
-            // one is not found.
-            if (isFrameworkId) {
-                return mContext.getFrameworkResourceValue(ResourceType.ID, idName, defValue);
-            } else {
-                return mContext.getProjectResourceValue(ResourceType.ID, idName, defValue);
-            }
-        }
-        else if (value.startsWith("@aapt:_aapt")) {
-            return mContext.getLayoutlibCallback().getResourceId(ResourceType.AAPT, value);
-        }
-
-        // not a direct id valid reference. First check if it's an enum (this is a corner case
-        // for attributes that have a reference|enum type), then fallback to resolve
-        // as an ID without prefix.
-        Integer enumValue = resolveEnumAttribute(index);
-        if (enumValue != null) {
-            return enumValue;
-        }
-
-        // Ok, not an enum, resolve as an ID
-        Integer idValue;
-
-        if (resValue.isFramework()) {
-            idValue = Bridge.getResourceId(resValue.getResourceType(),
-                    resValue.getName());
-        } else {
-            idValue = mContext.getLayoutlibCallback().getResourceId(
-                    resValue.getResourceType(), resValue.getName());
-        }
-
-        if (idValue != null) {
-            return idValue;
-        }
-
-        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE,
-                String.format(
-                    "Unable to resolve id \"%1$s\" for attribute \"%2$s\"", value, mNames[index]),
-                    resValue);
-
-        return defValue;
-    }
-
-    @Override
-    public int getThemeAttributeId(int index, int defValue) {
-        // TODO: Get the right Theme Attribute ID to enable caching of the drawables.
-        return defValue;
-    }
-
-    /**
-     * Retrieve the Drawable for the attribute at <var>index</var>.  This
-     * gets the resource ID of the selected attribute, and uses
-     * {@link Resources#getDrawable Resources.getDrawable} of the owning
-     * Resources object to retrieve its Drawable.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Drawable for the attribute, or null if not defined.
-     */
-    @Override
-    public Drawable getDrawable(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-
-        ResourceValue value = mResourceData[index];
-        return ResourceHelper.getDrawable(value, mContext, mTheme);
-    }
-
-
-    /**
-     * Retrieve the Typeface for the attribute at <var>index</var>.
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Typeface for the attribute, or null if not defined.
-     */
-    @Override
-    public Typeface getFont(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-
-        ResourceValue value = mResourceData[index];
-        return ResourceHelper.getFont(value, mContext, mTheme);
-    }
-
-    /**
-     * Retrieve the CharSequence[] for the attribute at <var>index</var>.
-     * This gets the resource ID of the selected attribute, and uses
-     * {@link Resources#getTextArray Resources.getTextArray} of the owning
-     * Resources object to retrieve its String[].
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return CharSequence[] for the attribute, or null if not defined.
-     */
-    @Override
-    public CharSequence[] getTextArray(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-        ResourceValue resVal = mResourceData[index];
-        if (resVal instanceof ArrayResourceValue) {
-            ArrayResourceValue array = (ArrayResourceValue) resVal;
-            int count = array.getElementCount();
-            return count >= 0 ? Resources_Delegate.fillValues(mBridgeResources, array, new CharSequence[count]) :
-                    null;
-        }
-        int id = getResourceId(index, 0);
-        String resIdMessage = id > 0 ? " (resource id 0x" + Integer.toHexString(id) + ')' : "";
-        assert false :
-                String.format("%1$s in %2$s%3$s is not a valid array resource.", resVal.getValue(),
-                        mNames[index], resIdMessage);
-
-        return new CharSequence[0];
-    }
-
-    @Override
-    public int[] extractThemeAttrs() {
-        // The drawables are always inflated with a Theme and we don't care about caching. So,
-        // just return.
-        return null;
-    }
-
-    @Override
-    public int getChangingConfigurations() {
-        // We don't care about caching. Any change in configuration is a fresh render. So,
-        // just return.
-        return 0;
-    }
-
-    /**
-     * Retrieve the raw TypedValue for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param outValue TypedValue object in which to place the attribute's
-     *                 data.
-     *
-     * @return Returns true if the value was retrieved, else false.
-     */
-    @Override
-    public boolean getValue(int index, TypedValue outValue) {
-        String s = getString(index);
-        return s != null && ResourceHelper.parseFloatAttribute(mNames[index], s, outValue, false);
-    }
-
-    @Override
-    @SuppressWarnings("ResultOfMethodCallIgnored")
-    public int getType(int index) {
-        String value = getString(index);
-        if (value == null) {
-            return TYPE_NULL;
-        }
-        if (value.startsWith(PREFIX_RESOURCE_REF)) {
-            return TYPE_REFERENCE;
-        }
-        if (value.startsWith(PREFIX_THEME_REF)) {
-            return TYPE_ATTRIBUTE;
-        }
-        try {
-            // Don't care about the value. Only called to check if an exception is thrown.
-            convertValueToInt(value, 0);
-            if (value.startsWith("0x") || value.startsWith("0X")) {
-                return TYPE_INT_HEX;
-            }
-            // is it a color?
-            if (value.startsWith("#")) {
-                int length = value.length() - 1;
-                if (length == 3) {  // rgb
-                    return TYPE_INT_COLOR_RGB4;
-                }
-                if (length == 4) {  // argb
-                    return TYPE_INT_COLOR_ARGB4;
-                }
-                if (length == 6) {  // rrggbb
-                    return TYPE_INT_COLOR_RGB8;
-                }
-                if (length == 8) {  // aarrggbb
-                    return TYPE_INT_COLOR_ARGB8;
-                }
-            }
-            if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) {
-                return TYPE_INT_BOOLEAN;
-            }
-            return TYPE_INT_DEC;
-        } catch (NumberFormatException ignored) {
-            try {
-                Float.parseFloat(value);
-                return TYPE_FLOAT;
-            } catch (NumberFormatException ignore) {
-            }
-            // Might be a dimension.
-            if (ResourceHelper.parseFloatAttribute(null, value, new TypedValue(), false)) {
-                return TYPE_DIMENSION;
-            }
-        }
-        // TODO: handle fractions.
-        return TYPE_STRING;
-    }
-
-    /**
-     * Determines whether there is an attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return True if the attribute has a value, false otherwise.
-     */
-    @Override
-    public boolean hasValue(int index) {
-        return index >= 0 && index < mResourceData.length && mResourceData[index] != null;
-    }
-
-    @Override
-    public boolean hasValueOrEmpty(int index) {
-        return hasValue(index) || index >= 0 && index < mResourceData.length &&
-                mEmptyIds != null && Arrays.binarySearch(mEmptyIds, index) >= 0;
-    }
-
-    /**
-     * Retrieve the raw TypedValue for the attribute at <var>index</var>
-     * and return a temporary object holding its data.  This object is only
-     * valid until the next call on to {@link TypedArray}.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Returns a TypedValue object if the attribute is defined,
-     *         containing its data; otherwise returns null.  (You will not
-     *         receive a TypedValue whose type is TYPE_NULL.)
-     */
-    @Override
-    public TypedValue peekValue(int index) {
-        if (index < 0 || index >= mResourceData.length) {
-            return null;
-        }
-
-        if (getValue(index, mValue)) {
-            return mValue;
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a message about the parser state suitable for printing error messages.
-     */
-    @Override
-    public String getPositionDescription() {
-        return "<internal -- stub if needed>";
-    }
-
-    /**
-     * Give back a previously retrieved TypedArray, for later re-use.
-     */
-    @Override
-    public void recycle() {
-        // pass
-    }
-
-    @Override
-    public String toString() {
-        return Arrays.toString(mResourceData);
-    }
-
-    /**
-     * Searches for the string in the attributes (flag or enums) and returns the integer.
-     * If found, it will return an integer matching the value.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Attribute int value, or null if not defined.
-     */
-    private Integer resolveEnumAttribute(int index) {
-        // Get the map of attribute-constant -> IntegerValue
-        Map<String, Integer> map = null;
-        if (mIsFramework[index]) {
-            map = Bridge.getEnumValues(mNames[index]);
-        } else {
-            // get the styleable matching the resolved name
-            RenderResources res = mContext.getRenderResources();
-            ResourceValue attr = res.getProjectResource(ResourceType.ATTR, mNames[index]);
-            if (attr instanceof AttrResourceValue) {
-                map = ((AttrResourceValue) attr).getAttributeValues();
-            }
-        }
-
-        if (map != null) {
-            // accumulator to store the value of the 1+ constants.
-            int result = 0;
-            boolean found = false;
-
-            // split the value in case this is a mix of several flags.
-            String[] keywords = mResourceData[index].getValue().split("\\|");
-            for (String keyword : keywords) {
-                Integer i = map.get(keyword.trim());
-                if (i != null) {
-                    result |= i;
-                    found = true;
-                }
-                // TODO: We should act smartly and log a warning for incorrect keywords. However,
-                // this method is currently called even if the resourceValue is not an enum.
-            }
-            if (found) {
-                return result;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Copied from {@link XmlUtils#convertValueToInt(CharSequence, int)}, but adapted to account
-     * for aapt, and the fact that host Java VM's Integer.parseInt("XXXXXXXX", 16) cannot handle
-     * "XXXXXXXX" > 80000000.
-     */
-    private static int convertValueToInt(@Nullable String charSeq, int defValue) {
-        if (null == charSeq || charSeq.isEmpty())
-            return defValue;
-
-        int sign = 1;
-        int index = 0;
-        int len = charSeq.length();
-        int base = 10;
-
-        if ('-' == charSeq.charAt(0)) {
-            sign = -1;
-            index++;
-        }
-
-        if ('0' == charSeq.charAt(index)) {
-            //  Quick check for a zero by itself
-            if (index == (len - 1))
-                return 0;
-
-            char c = charSeq.charAt(index + 1);
-
-            if ('x' == c || 'X' == c) {
-                index += 2;
-                base = 16;
-            } else {
-                index++;
-                // Leave the base as 10. aapt removes the preceding zero, and thus when framework
-                // sees the value, it only gets the decimal value.
-            }
-        } else if ('#' == charSeq.charAt(index)) {
-            return ResourceHelper.getColor(charSeq) * sign;
-        } else if ("true".equals(charSeq) || "TRUE".equals(charSeq)) {
-            return -1;
-        } else if ("false".equals(charSeq) || "FALSE".equals(charSeq)) {
-            return 0;
-        }
-
-        // Use Long, since we want to handle hex ints > 80000000.
-        return ((int)Long.parseLong(charSeq.substring(index), base)) * sign;
-    }
-
-    static TypedArray obtain(Resources res, int len) {
-        return new BridgeTypedArray(res, null, len, true);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/ComplexColor_Accessor.java b/tools/layoutlib/bridge/src/android/content/res/ComplexColor_Accessor.java
deleted file mode 100644
index 09c0260..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/ComplexColor_Accessor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.res.Resources.Theme;
-import android.util.AttributeSet;
-
-import java.io.IOException;
-
-/**
- * Class that provides access to the {@link GradientColor#createFromXmlInner(Resources,
- * XmlPullParser, AttributeSet, Theme)} and {@link ColorStateList#createFromXmlInner(Resources,
- * XmlPullParser, AttributeSet, Theme)} methods
- */
-public class ComplexColor_Accessor {
-    public static GradientColor createGradientColorFromXmlInner(@NonNull Resources r,
-            @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme)
-            throws IOException, XmlPullParserException {
-        return GradientColor.createFromXmlInner(r, parser, attrs, theme);
-    }
-
-    public static ColorStateList createColorStateListFromXmlInner(@NonNull Resources r,
-            @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme)
-            throws IOException, XmlPullParserException {
-        return ColorStateList.createFromXmlInner(r, parser, attrs, theme);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
deleted file mode 100644
index c20ee12..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
+++ /dev/null
@@ -1,1025 +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.content.res;
-
-import com.android.SdkConstants;
-import com.android.ide.common.rendering.api.ArrayResourceValue;
-import com.android.ide.common.rendering.api.DensityBasedResourceValue;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.PluralsResourceValue;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.layoutlib.bridge.util.NinePatchInputStream;
-import com.android.ninepatch.NinePatch;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.util.Pair;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.res.Resources.NotFoundException;
-import android.content.res.Resources.Theme;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.icu.text.PluralRules;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.LruCache;
-import android.util.TypedValue;
-import android.view.DisplayAdjustments;
-import android.view.ViewGroup.LayoutParams;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.util.Iterator;
-
-@SuppressWarnings("deprecation")
-public class Resources_Delegate {
-
-    private static boolean[] mPlatformResourceFlag = new boolean[1];
-    // TODO: This cache is cleared every time a render session is disposed. Look into making this
-    // more long lived.
-    private static LruCache<String, Drawable.ConstantState> sDrawableCache = new LruCache<>(50);
-
-    public static Resources initSystem(BridgeContext context,
-            AssetManager assets,
-            DisplayMetrics metrics,
-            Configuration config,
-            LayoutlibCallback layoutlibCallback) {
-        Resources resources = new Resources(Resources_Delegate.class.getClassLoader());
-        resources.setImpl(new ResourcesImpl(assets, metrics, config, new DisplayAdjustments()));
-        resources.mContext = context;
-        resources.mLayoutlibCallback = layoutlibCallback;
-        return Resources.mSystem = resources;
-    }
-
-    /**
-     * Disposes the static {@link Resources#mSystem} to make sure we don't leave objects around that
-     * would prevent us from unloading the library.
-     */
-    public static void disposeSystem() {
-        sDrawableCache.evictAll();
-        Resources.mSystem.mContext = null;
-        Resources.mSystem.mLayoutlibCallback = null;
-        Resources.mSystem = null;
-    }
-
-    public static BridgeTypedArray newTypeArray(Resources resources, int numEntries,
-            boolean platformFile) {
-        return new BridgeTypedArray(resources, resources.mContext, numEntries, platformFile);
-    }
-
-    private static Pair<ResourceType, String> getResourceInfo(Resources resources, int id,
-            boolean[] platformResFlag_out) {
-        // first get the String related to this id in the framework
-        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
-
-        // Set the layoutlib callback and context for resources
-        if (resources != Resources.mSystem && resources.mLayoutlibCallback == null) {
-            resources.mLayoutlibCallback = Resources.mSystem.mLayoutlibCallback;
-            resources.mContext = Resources.mSystem.mContext;
-        }
-
-        if (resourceInfo != null) {
-            platformResFlag_out[0] = true;
-            return resourceInfo;
-        }
-
-        // didn't find a match in the framework? look in the project.
-        if (resources.mLayoutlibCallback != null) {
-            resourceInfo = resources.mLayoutlibCallback.resolveResourceId(id);
-
-            if (resourceInfo != null) {
-                platformResFlag_out[0] = false;
-                return resourceInfo;
-            }
-        }
-        return null;
-    }
-
-    private static Pair<String, ResourceValue> getResourceValue(Resources resources, int id,
-            boolean[] platformResFlag_out) {
-        Pair<ResourceType, String> resourceInfo =
-                getResourceInfo(resources, id, platformResFlag_out);
-
-        if (resourceInfo != null) {
-            String attributeName = resourceInfo.getSecond();
-            RenderResources renderResources = resources.mContext.getRenderResources();
-            ResourceValue value = platformResFlag_out[0] ?
-                    renderResources.getFrameworkResource(resourceInfo.getFirst(), attributeName) :
-                    renderResources.getProjectResource(resourceInfo.getFirst(), attributeName);
-
-            if (value == null) {
-                // Unable to resolve the attribute, just leave the unresolved value
-                value = new ResourceValue(resourceInfo.getFirst(), attributeName, attributeName,
-                        platformResFlag_out[0]);
-            }
-            return Pair.of(attributeName, value);
-        }
-
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static Drawable getDrawable(Resources resources, int id) {
-        return getDrawable(resources, id, null);
-    }
-
-    @LayoutlibDelegate
-    static Drawable getDrawable(Resources resources, int id, Theme theme) {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-        if (value != null) {
-            String key = value.getSecond().getValue();
-
-            Drawable.ConstantState constantState = key != null ? sDrawableCache.get(key) : null;
-            Drawable drawable;
-            if (constantState != null) {
-                drawable = constantState.newDrawable(resources, theme);
-            } else {
-                drawable =
-                        ResourceHelper.getDrawable(value.getSecond(), resources.mContext, theme);
-
-                if (key != null) {
-                    sDrawableCache.put(key, drawable.getConstantState());
-                }
-            }
-
-            return drawable;
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static int getColor(Resources resources, int id) {
-        return getColor(resources, id, null);
-    }
-
-    @LayoutlibDelegate
-    static int getColor(Resources resources, int id, Theme theme) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resourceValue = value.getSecond();
-            try {
-                return ResourceHelper.getColor(resourceValue.getValue());
-            } catch (NumberFormatException e) {
-                // Check if the value passed is a file. If it is, mostly likely, user is referencing
-                // a color state list from a place where they should reference only a pure color.
-                String message;
-                if (new File(resourceValue.getValue()).isFile()) {
-                    String resource = (resourceValue.isFramework() ? "@android:" : "@") + "color/"
-                            + resourceValue.getName();
-                    message = "Hexadecimal color expected, found Color State List for " + resource;
-                } else {
-                    message = e.getMessage();
-                }
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, message, e, null);
-                return 0;
-            }
-        }
-
-        // Suppress possible NPE. getColorStateList will never return null, it will instead
-        // throw an exception, but intelliJ can't figure that out
-        //noinspection ConstantConditions
-        return getColorStateList(resources, id, theme).getDefaultColor();
-    }
-
-    @LayoutlibDelegate
-    static ColorStateList getColorStateList(Resources resources, int id) throws NotFoundException {
-        return getColorStateList(resources, id, null);
-    }
-
-    @LayoutlibDelegate
-    static ColorStateList getColorStateList(Resources resources, int id, Theme theme)
-            throws NotFoundException {
-        Pair<String, ResourceValue> resValue =
-                getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (resValue != null) {
-            ColorStateList stateList = ResourceHelper.getColorStateList(resValue.getSecond(),
-                    resources.mContext);
-            if (stateList != null) {
-                return stateList.obtainForTheme(theme);
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static CharSequence getText(Resources resources, int id, CharSequence def) {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    return v;
-                }
-            }
-        }
-
-        return def;
-    }
-
-    @LayoutlibDelegate
-    static CharSequence getText(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    return v;
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static CharSequence[] getTextArray(Resources resources, int id) throws NotFoundException {
-        ResourceValue resValue = getArrayResourceValue(resources, id);
-        if (resValue == null) {
-            // Error already logged by getArrayResourceValue.
-            return new CharSequence[0];
-        } else if (!(resValue instanceof ArrayResourceValue)) {
-            return new CharSequence[]{
-                    resolveReference(resources, resValue.getValue(), resValue.isFramework())};
-        }
-        ArrayResourceValue arv = ((ArrayResourceValue) resValue);
-        return fillValues(resources, arv, new CharSequence[arv.getElementCount()]);
-    }
-
-    @LayoutlibDelegate
-    static String[] getStringArray(Resources resources, int id) throws NotFoundException {
-        ResourceValue resValue = getArrayResourceValue(resources, id);
-        if (resValue == null) {
-            // Error already logged by getArrayResourceValue.
-            return new String[0];
-        } else if (!(resValue instanceof ArrayResourceValue)) {
-            return new String[]{
-                    resolveReference(resources, resValue.getValue(), resValue.isFramework())};
-        }
-        ArrayResourceValue arv = ((ArrayResourceValue) resValue);
-        return fillValues(resources, arv, new String[arv.getElementCount()]);
-    }
-
-    /**
-     * Resolve each element in resValue and copy them to {@code values}. The values copied are
-     * always Strings. The ideal signature for the method should be &lt;T super String&gt;, but java
-     * generics don't support it.
-     */
-    static <T extends CharSequence> T[] fillValues(Resources resources, ArrayResourceValue resValue,
-            T[] values) {
-        int i = 0;
-        for (Iterator<String> iterator = resValue.iterator(); iterator.hasNext(); i++) {
-            @SuppressWarnings("unchecked")
-            T s = (T) resolveReference(resources, iterator.next(), resValue.isFramework());
-            values[i] = s;
-        }
-        return values;
-    }
-
-    @LayoutlibDelegate
-    static int[] getIntArray(Resources resources, int id) throws NotFoundException {
-        ResourceValue rv = getArrayResourceValue(resources, id);
-        if (rv == null) {
-            // Error already logged by getArrayResourceValue.
-            return new int[0];
-        } else if (!(rv instanceof ArrayResourceValue)) {
-            // This is an older IDE that can only give us the first element of the array.
-            String firstValue = resolveReference(resources, rv.getValue(), rv.isFramework());
-            try {
-                return new int[]{getInt(firstValue)};
-            } catch (NumberFormatException e) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
-                        "Integer resource array contains non-integer value: " +
-                                firstValue, null);
-                return new int[1];
-            }
-        }
-        ArrayResourceValue resValue = ((ArrayResourceValue) rv);
-        int[] values = new int[resValue.getElementCount()];
-        int i = 0;
-        for (Iterator<String> iterator = resValue.iterator(); iterator.hasNext(); i++) {
-            String element = resolveReference(resources, iterator.next(), resValue.isFramework());
-            try {
-                values[i] = getInt(element);
-            } catch (NumberFormatException e) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
-                        "Integer resource array contains non-integer value: " + element, null);
-            }
-        }
-        return values;
-    }
-
-    /**
-     * Try to find the ArrayResourceValue for the given id.
-     * <p/>
-     * If the ResourceValue found is not of type {@link ResourceType#ARRAY}, the method logs an
-     * error and return null. However, if the ResourceValue found has type {@code
-     * ResourceType.ARRAY}, but the value is not an instance of {@link ArrayResourceValue}, the
-     * method returns the ResourceValue. This happens on older versions of the IDE, which did not
-     * parse the array resources properly.
-     * <p/>
-     *
-     * @throws NotFoundException if no resource if found
-     */
-    @Nullable
-    private static ResourceValue getArrayResourceValue(Resources resources, int id)
-            throws NotFoundException {
-        Pair<String, ResourceValue> v = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (v != null) {
-            ResourceValue resValue = v.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                final ResourceType type = resValue.getResourceType();
-                if (type != ResourceType.ARRAY) {
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
-                            String.format(
-                                    "Resource with id 0x%1$X is not an array resource, but %2$s",
-                                    id, type == null ? "null" : type.getDisplayName()),
-                            null);
-                    return null;
-                }
-                if (!(resValue instanceof ArrayResourceValue)) {
-                    Bridge.getLog().warning(LayoutLog.TAG_UNSUPPORTED,
-                            "Obtaining resource arrays via getTextArray, getStringArray or getIntArray is not fully supported in this version of the IDE.",
-                            null);
-                }
-                return resValue;
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @NonNull
-    private static String resolveReference(Resources resources, @NonNull String ref,
-            boolean forceFrameworkOnly) {
-        if (ref.startsWith(SdkConstants.PREFIX_RESOURCE_REF) || ref.startsWith
-                (SdkConstants.PREFIX_THEME_REF)) {
-            ResourceValue rv =
-                    resources.mContext.getRenderResources().findResValue(ref, forceFrameworkOnly);
-            rv = resources.mContext.getRenderResources().resolveResValue(rv);
-            if (rv != null) {
-                return rv.getValue();
-            }
-        }
-        // Not a reference.
-        return ref;
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser getLayout(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> v = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (v != null) {
-            ResourceValue value = v.getSecond();
-            XmlPullParser parser = null;
-
-            try {
-                // check if the current parser can provide us with a custom parser.
-                if (!mPlatformResourceFlag[0]) {
-                    parser = resources.mLayoutlibCallback.getParser(value);
-                }
-
-                // create a new one manually if needed.
-                if (parser == null) {
-                    File xml = new File(value.getValue());
-                    if (xml.isFile()) {
-                        // we need to create a pull parser around the layout XML file, and then
-                        // give that to our XmlBlockParser
-                        parser = ParserFactory.create(xml, true);
-                    }
-                }
-
-                if (parser != null) {
-                    return new BridgeXmlBlockParser(parser, resources.mContext,
-                            mPlatformResourceFlag[0]);
-                }
-            } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to configure parser for " + value.getValue(), e, null /*data*/);
-                // we'll return null below.
-            } catch (FileNotFoundException e) {
-                // this shouldn't happen since we check above.
-            }
-
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser getAnimation(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> v = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (v != null) {
-            ResourceValue value = v.getSecond();
-            XmlPullParser parser;
-
-            try {
-                File xml = new File(value.getValue());
-                if (xml.isFile()) {
-                    // we need to create a pull parser around the layout XML file, and then
-                    // give that to our XmlBlockParser
-                    parser = ParserFactory.create(xml);
-
-                    return new BridgeXmlBlockParser(parser, resources.mContext,
-                            mPlatformResourceFlag[0]);
-                }
-            } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to configure parser for " + value.getValue(), e, null /*data*/);
-                // we'll return null below.
-            } catch (FileNotFoundException e) {
-                // this shouldn't happen since we check above.
-            }
-
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static TypedArray obtainAttributes(Resources resources, AttributeSet set, int[] attrs) {
-        return resources.mContext.obtainStyledAttributes(set, attrs);
-    }
-
-    @LayoutlibDelegate
-    static TypedArray obtainAttributes(Resources resources, Resources.Theme theme, AttributeSet
-            set, int[] attrs) {
-        return Resources.obtainAttributes_Original(resources, theme, set, attrs);
-    }
-
-    @LayoutlibDelegate
-    static TypedArray obtainTypedArray(Resources resources, int id) throws NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    @LayoutlibDelegate
-    static float getDimension(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    if (v.equals(BridgeConstants.MATCH_PARENT) ||
-                            v.equals(BridgeConstants.FILL_PARENT)) {
-                        return LayoutParams.MATCH_PARENT;
-                    } else if (v.equals(BridgeConstants.WRAP_CONTENT)) {
-                        return LayoutParams.WRAP_CONTENT;
-                    }
-                    TypedValue tmpValue = new TypedValue();
-                    if (ResourceHelper.parseFloatAttribute(
-                            value.getFirst(), v, tmpValue, true /*requireUnit*/) &&
-                            tmpValue.type == TypedValue.TYPE_DIMENSION) {
-                        return tmpValue.getDimension(resources.getDisplayMetrics());
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    static int getDimensionPixelOffset(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    TypedValue tmpValue = new TypedValue();
-                    if (ResourceHelper.parseFloatAttribute(
-                            value.getFirst(), v, tmpValue, true /*requireUnit*/) &&
-                            tmpValue.type == TypedValue.TYPE_DIMENSION) {
-                        return TypedValue.complexToDimensionPixelOffset(tmpValue.data,
-                                resources.getDisplayMetrics());
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    static int getDimensionPixelSize(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    TypedValue tmpValue = new TypedValue();
-                    if (ResourceHelper.parseFloatAttribute(
-                            value.getFirst(), v, tmpValue, true /*requireUnit*/) &&
-                            tmpValue.type == TypedValue.TYPE_DIMENSION) {
-                        return TypedValue.complexToDimensionPixelSize(tmpValue.data,
-                                resources.getDisplayMetrics());
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    static int getInteger(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    try {
-                        return getInt(v);
-                    } catch (NumberFormatException e) {
-                        // return exception below
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    static boolean getBoolean(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    return Boolean.parseBoolean(v);
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return false;
-    }
-
-    @LayoutlibDelegate
-    static String getResourceEntryName(Resources resources, int resid) throws NotFoundException {
-        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, new boolean[1]);
-        if (resourceInfo != null) {
-            return resourceInfo.getSecond();
-        }
-        throwException(resid, null);
-        return null;
-
-    }
-
-    @LayoutlibDelegate
-    static String getResourceName(Resources resources, int resid) throws NotFoundException {
-        boolean[] platformOut = new boolean[1];
-        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, platformOut);
-        String packageName;
-        if (resourceInfo != null) {
-            if (platformOut[0]) {
-                packageName = SdkConstants.ANDROID_NS_NAME;
-            } else {
-                packageName = resources.mContext.getPackageName();
-                packageName = packageName == null ? SdkConstants.APP_PREFIX : packageName;
-            }
-            return packageName + ':' + resourceInfo.getFirst().getName() + '/' +
-                    resourceInfo.getSecond();
-        }
-        throwException(resid, null);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getResourcePackageName(Resources resources, int resid) throws NotFoundException {
-        boolean[] platformOut = new boolean[1];
-        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, platformOut);
-        if (resourceInfo != null) {
-            if (platformOut[0]) {
-                return SdkConstants.ANDROID_NS_NAME;
-            }
-            String packageName = resources.mContext.getPackageName();
-            return packageName == null ? SdkConstants.APP_PREFIX : packageName;
-        }
-        throwException(resid, null);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getResourceTypeName(Resources resources, int resid) throws NotFoundException {
-        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, new boolean[1]);
-        if (resourceInfo != null) {
-            return resourceInfo.getFirst().getName();
-        }
-        throwException(resid, null);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getString(Resources resources, int id, Object... formatArgs)
-            throws NotFoundException {
-        String s = getString(resources, id);
-        if (s != null) {
-            return String.format(s, formatArgs);
-
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getString(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null && value.getSecond().getValue() != null) {
-            return value.getSecond().getValue();
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getQuantityString(Resources resources, int id, int quantity) throws
-            NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            if (value.getSecond() instanceof PluralsResourceValue) {
-                PluralsResourceValue pluralsResourceValue = (PluralsResourceValue) value.getSecond();
-                PluralRules pluralRules = PluralRules.forLocale(resources.getConfiguration().getLocales()
-                        .get(0));
-                String strValue = pluralsResourceValue.getValue(pluralRules.select(quantity));
-                if (strValue == null) {
-                    strValue = pluralsResourceValue.getValue(PluralRules.KEYWORD_OTHER);
-                }
-
-                return strValue;
-            }
-            else {
-                return value.getSecond().getValue();
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getQuantityString(Resources resources, int id, int quantity, Object... formatArgs)
-            throws NotFoundException {
-        String raw = getQuantityString(resources, id, quantity);
-        return String.format(resources.getConfiguration().getLocales().get(0), raw, formatArgs);
-    }
-
-    @LayoutlibDelegate
-    static CharSequence getQuantityText(Resources resources, int id, int quantity) throws
-            NotFoundException {
-        return getQuantityString(resources, id, quantity);
-    }
-
-    @LayoutlibDelegate
-    static Typeface getFont(Resources resources, int id) throws
-            NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-        if (value != null) {
-            return ResourceHelper.getFont(value.getSecond(), resources.mContext, null);
-        }
-
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static Typeface getFont(Resources resources, TypedValue outValue, int id) throws
-            NotFoundException {
-        Resources_Delegate.getValue(resources, id, outValue, true);
-        if (outValue.string != null) {
-            return ResourceHelper.getFont(outValue.string.toString(), resources.mContext, null,
-                    mPlatformResourceFlag[0]);
-        }
-
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static void getValue(Resources resources, int id, TypedValue outValue, boolean resolveRefs)
-            throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resVal = value.getSecond();
-            String v = resVal.getValue();
-
-            if (v != null) {
-                if (ResourceHelper.parseFloatAttribute(value.getFirst(), v, outValue,
-                        false /*requireUnit*/)) {
-                    return;
-                }
-                if (resVal instanceof DensityBasedResourceValue) {
-                    outValue.density =
-                            ((DensityBasedResourceValue) resVal).getResourceDensity().getDpiValue();
-                }
-
-                // else it's a string
-                outValue.type = TypedValue.TYPE_STRING;
-                outValue.string = v;
-                return;
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-    }
-
-    @LayoutlibDelegate
-    static void getValue(Resources resources, String name, TypedValue outValue, boolean resolveRefs)
-            throws NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser getXml(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            String v = value.getSecond().getValue();
-
-            if (v != null) {
-                // check this is a file
-                File f = new File(v);
-                if (f.isFile()) {
-                    try {
-                        XmlPullParser parser = ParserFactory.create(f);
-
-                        return new BridgeXmlBlockParser(parser, resources.mContext,
-                                mPlatformResourceFlag[0]);
-                    } catch (XmlPullParserException e) {
-                        NotFoundException newE = new NotFoundException();
-                        newE.initCause(e);
-                        throw newE;
-                    } catch (FileNotFoundException e) {
-                        NotFoundException newE = new NotFoundException();
-                        newE.initCause(e);
-                        throw newE;
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser loadXmlResourceParser(Resources resources, int id,
-            String type) throws NotFoundException {
-        return resources.loadXmlResourceParser_Original(id, type);
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser loadXmlResourceParser(Resources resources, String file, int id,
-            int assetCookie, String type) throws NotFoundException {
-        // even though we know the XML file to load directly, we still need to resolve the
-        // id so that we can know if it's a platform or project resource.
-        // (mPlatformResouceFlag will get the result and will be used later).
-        getResourceValue(resources, id, mPlatformResourceFlag);
-
-        File f = new File(file);
-        try {
-            XmlPullParser parser = ParserFactory.create(f);
-
-            return new BridgeXmlBlockParser(parser, resources.mContext, mPlatformResourceFlag[0]);
-        } catch (XmlPullParserException e) {
-            NotFoundException newE = new NotFoundException();
-            newE.initCause(e);
-            throw newE;
-        } catch (FileNotFoundException e) {
-            NotFoundException newE = new NotFoundException();
-            newE.initCause(e);
-            throw newE;
-        }
-    }
-
-    @LayoutlibDelegate
-    static InputStream openRawResource(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            String path = value.getSecond().getValue();
-
-            if (path != null) {
-                // check this is a file
-                File f = new File(path);
-                if (f.isFile()) {
-                    try {
-                        // if it's a nine-patch return a custom input stream so that
-                        // other methods (mainly bitmap factory) can detect it's a 9-patch
-                        // and actually load it as a 9-patch instead of a normal bitmap
-                        if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
-                            return new NinePatchInputStream(f);
-                        }
-                        return new FileInputStream(f);
-                    } catch (FileNotFoundException e) {
-                        NotFoundException newE = new NotFoundException();
-                        newE.initCause(e);
-                        throw newE;
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static InputStream openRawResource(Resources resources, int id, TypedValue value) throws
-            NotFoundException {
-        getValue(resources, id, value, true);
-
-        String path = value.string.toString();
-
-        File f = new File(path);
-        if (f.isFile()) {
-            try {
-                // if it's a nine-patch return a custom input stream so that
-                // other methods (mainly bitmap factory) can detect it's a 9-patch
-                // and actually load it as a 9-patch instead of a normal bitmap
-                if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
-                    return new NinePatchInputStream(f);
-                }
-                return new FileInputStream(f);
-            } catch (FileNotFoundException e) {
-                NotFoundException exception = new NotFoundException();
-                exception.initCause(e);
-                throw exception;
-            }
-        }
-
-        throw new NotFoundException();
-    }
-
-    @LayoutlibDelegate
-    static AssetFileDescriptor openRawResourceFd(Resources resources, int id) throws
-            NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Builds and throws a {@link Resources.NotFoundException} based on a resource id and a resource
-     * type.
-     *
-     * @param id the id of the resource
-     *
-     * @throws NotFoundException
-     */
-    private static void throwException(Resources resources, int id) throws NotFoundException {
-        throwException(id, getResourceInfo(resources, id, new boolean[1]));
-    }
-
-    private static void throwException(int id, @Nullable Pair<ResourceType, String> resourceInfo) {
-        String message;
-        if (resourceInfo != null) {
-            message = String.format(
-                    "Could not find %1$s resource matching value 0x%2$X (resolved name: %3$s) in current configuration.",
-                    resourceInfo.getFirst(), id, resourceInfo.getSecond());
-        } else {
-            message = String.format("Could not resolve resource value: 0x%1$X.", id);
-        }
-
-        throw new NotFoundException(message);
-    }
-
-    private static int getInt(String v) throws NumberFormatException {
-        int radix = 10;
-        if (v.startsWith("0x")) {
-            v = v.substring(2);
-            radix = 16;
-        } else if (v.startsWith("0")) {
-            radix = 8;
-        }
-        return Integer.parseInt(v, radix);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
deleted file mode 100644
index f1e8fc21..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
+++ /dev/null
@@ -1,152 +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.
- */
-
-package android.content.res;
-
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import android.content.res.Resources.NotFoundException;
-import android.content.res.Resources.Theme;
-import android.content.res.Resources.ThemeKey;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Resources.Theme}
- *
- * Through the layoutlib_create tool, the original  methods of Theme have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class Resources_Theme_Delegate {
-
-    // ---- delegate manager ----
-
-    private static final DelegateManager<Resources_Theme_Delegate> sManager =
-            new DelegateManager<Resources_Theme_Delegate>(Resources_Theme_Delegate.class);
-
-    public static DelegateManager<Resources_Theme_Delegate> getDelegateManager() {
-        return sManager;
-    }
-
-    // ---- delegate methods. ----
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtainStyledAttributes(
-            Resources thisResources, Theme thisTheme,
-            int[] attrs) {
-        boolean changed = setupResources(thisTheme);
-        BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(attrs);
-        ta.setTheme(thisTheme);
-        restoreResources(changed);
-        return ta;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtainStyledAttributes(
-            Resources thisResources, Theme thisTheme,
-            int resid, int[] attrs)
-            throws NotFoundException {
-        boolean changed = setupResources(thisTheme);
-        BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(resid,
-                attrs);
-        ta.setTheme(thisTheme);
-        restoreResources(changed);
-        return ta;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtainStyledAttributes(
-            Resources thisResources, Theme thisTheme,
-            AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) {
-        boolean changed = setupResources(thisTheme);
-        BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(set,
-                attrs, defStyleAttr, defStyleRes);
-        ta.setTheme(thisTheme);
-        restoreResources(changed);
-        return ta;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean resolveAttribute(
-            Resources thisResources, Theme thisTheme,
-            int resid, TypedValue outValue,
-            boolean resolveRefs) {
-        boolean changed = setupResources(thisTheme);
-        boolean found =  RenderSessionImpl.getCurrentContext().resolveThemeAttribute(resid,
-                outValue, resolveRefs);
-        restoreResources(changed);
-        return found;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray resolveAttributes(Resources thisResources, Theme thisTheme,
-            int[] values, int[] attrs) {
-        // FIXME
-        return null;
-    }
-
-    // ---- private helper methods ----
-
-    private static boolean setupResources(Theme thisTheme) {
-        // Key is a space-separated list of theme ids applied that have been merged into the
-        // BridgeContext's theme to make thisTheme.
-        final ThemeKey key = thisTheme.getKey();
-        final int[] resId = key.mResId;
-        final boolean[] force = key.mForce;
-
-        boolean changed = false;
-        for (int i = 0, N = key.mCount; i < N; i++) {
-            StyleResourceValue style = resolveStyle(resId[i]);
-            if (style != null) {
-                RenderSessionImpl.getCurrentContext().getRenderResources().applyStyle(
-                        style, force[i]);
-                changed = true;
-            }
-
-        }
-        return changed;
-    }
-
-    private static void restoreResources(boolean changed) {
-        if (changed) {
-            RenderSessionImpl.getCurrentContext().getRenderResources().clearStyles();
-        }
-    }
-
-    @Nullable
-    private static StyleResourceValue resolveStyle(int nativeResid) {
-        if (nativeResid == 0) {
-            return null;
-        }
-        BridgeContext context = RenderSessionImpl.getCurrentContext();
-        ResourceReference theme = context.resolveId(nativeResid);
-        if (theme.isFramework()) {
-            return (StyleResourceValue) context.getRenderResources()
-                    .getFrameworkResource(ResourceType.STYLE, theme.getName());
-        } else {
-            return (StyleResourceValue) context.getRenderResources()
-                    .getProjectResource(ResourceType.STYLE, theme.getName());
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java
deleted file mode 100644
index faa8852..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java
+++ /dev/null
@@ -1,35 +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.
- */
-
-package android.content.res;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.util.TypedValue;
-
-public class TypedArray_Delegate {
-
-    @LayoutlibDelegate
-    public static boolean getValueAt(TypedArray theTypedArray, int index, TypedValue outValue) {
-        // pass
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtain(Resources res, int len) {
-        return BridgeTypedArray.obtain(res, len);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BaseCanvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BaseCanvas_Delegate.java
deleted file mode 100644
index cc71053..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BaseCanvas_Delegate.java
+++ /dev/null
@@ -1,762 +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.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.GcSnapshot;
-import com.android.layoutlib.bridge.impl.PorterDuffUtility;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import android.text.TextUtils;
-
-import java.awt.*;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Arc2D;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBuffer;
-
-public class BaseCanvas_Delegate {
-    // ---- delegate manager ----
-    protected static DelegateManager<BaseCanvas_Delegate> sManager =
-            new DelegateManager<>(BaseCanvas_Delegate.class);
-
-    // ---- delegate helper data ----
-    private final static boolean[] sBoolOut = new boolean[1];
-
-
-    // ---- delegate data ----
-    protected Bitmap_Delegate mBitmap;
-    protected GcSnapshot mSnapshot;
-
-    // ---- Public Helper methods ----
-
-    protected BaseCanvas_Delegate(Bitmap_Delegate bitmap) {
-        mSnapshot = GcSnapshot.createDefaultSnapshot(mBitmap = bitmap);
-    }
-
-    protected BaseCanvas_Delegate() {
-        mSnapshot = GcSnapshot.createDefaultSnapshot(null /*image*/);
-    }
-
-    /**
-     * Disposes of the {@link Graphics2D} stack.
-     */
-    protected void dispose() {
-        mSnapshot.dispose();
-    }
-
-    /**
-     * Returns the current {@link Graphics2D} used to draw.
-     */
-    public GcSnapshot getSnapshot() {
-        return mSnapshot;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top,
-            long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity) {
-        // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        BufferedImage image = bitmapDelegate.getImage();
-        float right = left + image.getWidth();
-        float bottom = top + image.getHeight();
-
-        drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
-                0, 0, image.getWidth(), image.getHeight(),
-                (int)left, (int)top, (int)right, (int)bottom);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static 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) {
-        // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero, (int) srcLeft, (int) srcTop,
-                (int) srcRight, (int) srcBottom, (int) dstLeft, (int) dstTop, (int) dstRight,
-                (int) dstBottom);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawBitmap(long nativeCanvas, int[] colors, int offset, int stride,
-            final float x, final float y, int width, int height, boolean hasAlpha,
-            long nativePaintOrZero) {
-        // create a temp BufferedImage containing the content.
-        final BufferedImage image = new BufferedImage(width, height,
-                hasAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB);
-        image.setRGB(0, 0, width, height, colors, offset, stride);
-
-        draw(nativeCanvas, nativePaintOrZero, true /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paint) -> {
-                    if (paint != null && paint.isFilterBitmap()) {
-                        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-                    }
-
-                    graphics.drawImage(image, (int) x, (int) y, null);
-                });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawColor(long nativeCanvas, final int color, final int mode) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        final int w = canvasDelegate.mBitmap.getImage().getWidth();
-        final int h = canvasDelegate.mBitmap.getImage().getHeight();
-        draw(nativeCanvas, (graphics, paint) -> {
-            // reset its transform just in case
-            graphics.setTransform(new AffineTransform());
-
-            // set the color
-            graphics.setColor(new java.awt.Color(color, true /*alpha*/));
-
-            Composite composite = PorterDuffUtility.getComposite(
-                    PorterDuffUtility.getPorterDuffMode(mode), 0xFF);
-            if (composite != null) {
-                graphics.setComposite(composite);
-            }
-
-            graphics.fillRect(0, 0, w, h);
-        });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawPaint(long nativeCanvas, long paint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawPaint is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawPoint(long nativeCanvas, float x, float y,
-            long nativePaint) {
-        // TODO: need to support the attribute (e.g. stroke width) of paint
-        draw(nativeCanvas, nativePaint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> graphics.fillRect((int)x, (int)y, 1, 1));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawPoints(long nativeCanvas, float[] pts, int offset, int count,
-            long nativePaint) {
-        if (offset < 0 || count < 0 || offset + count > pts.length) {
-            throw new IllegalArgumentException("Invalid argument set");
-        }
-        // ignore the last point if the count is odd (It means it is not paired).
-        count = (count >> 1) << 1;
-        for (int i = offset; i < offset + count; i += 2) {
-            nDrawPoint(nativeCanvas, pts[i], pts[i + 1], nativePaint);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawLine(long nativeCanvas,
-            final float startX, final float startY, final float stopX, final float stopY,
-            long paint) {
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> graphics.drawLine((int)startX, (int)startY, (int)stopX, (int)stopY));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawLines(long nativeCanvas,
-            final float[] pts, final int offset, final int count,
-            long nativePaint) {
-        draw(nativeCanvas, nativePaint, false /*compositeOnly*/,
-                false /*forceSrcMode*/, (graphics, paintDelegate) -> {
-                    for (int i = 0; i < count; i += 4) {
-                        graphics.drawLine((int) pts[i + offset], (int) pts[i + offset + 1],
-                                (int) pts[i + offset + 2], (int) pts[i + offset + 3]);
-                    }
-                });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawRect(long nativeCanvas,
-            final float left, final float top, final float right, final float bottom, long paint) {
-
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> {
-                    int style = paintDelegate.getStyle();
-
-                    // draw
-                    if (style == Paint.Style.FILL.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.fillRect((int)left, (int)top,
-                                (int)(right-left), (int)(bottom-top));
-                    }
-
-                    if (style == Paint.Style.STROKE.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.drawRect((int)left, (int)top,
-                                (int)(right-left), (int)(bottom-top));
-                    }
-                });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawOval(long nativeCanvas, final float left,
-            final float top, final float right, final float bottom, long paint) {
-        if (right > left && bottom > top) {
-            draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                    (graphics, paintDelegate) -> {
-                        int style = paintDelegate.getStyle();
-
-                        // draw
-                        if (style == Paint.Style.FILL.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.fillOval((int)left, (int)top,
-                                    (int)(right - left), (int)(bottom - top));
-                        }
-
-                        if (style == Paint.Style.STROKE.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.drawOval((int)left, (int)top,
-                                    (int)(right - left), (int)(bottom - top));
-                        }
-                    });
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawCircle(long nativeCanvas,
-            float cx, float cy, float radius, long paint) {
-        nDrawOval(nativeCanvas,
-                cx - radius, cy - radius, cx + radius, cy + radius,
-                paint);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawArc(long nativeCanvas,
-            final float left, final float top, final float right, final float bottom,
-            final float startAngle, final float sweep,
-            final boolean useCenter, long paint) {
-        if (right > left && bottom > top) {
-            draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                    (graphics, paintDelegate) -> {
-                        int style = paintDelegate.getStyle();
-
-                        Arc2D.Float arc = new Arc2D.Float(
-                                left, top, right - left, bottom - top,
-                                -startAngle, -sweep,
-                                useCenter ? Arc2D.PIE : Arc2D.OPEN);
-
-                        // draw
-                        if (style == Paint.Style.FILL.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.fill(arc);
-                        }
-
-                        if (style == Paint.Style.STROKE.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.draw(arc);
-                        }
-                    });
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawRoundRect(long nativeCanvas,
-            final float left, final float top, final float right, final float bottom,
-            final float rx, final float ry, long paint) {
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> {
-                    int style = paintDelegate.getStyle();
-
-                    // draw
-                    if (style == Paint.Style.FILL.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.fillRoundRect(
-                                (int)left, (int)top,
-                                (int)(right - left), (int)(bottom - top),
-                                2 * (int)rx, 2 * (int)ry);
-                    }
-
-                    if (style == Paint.Style.STROKE.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.drawRoundRect(
-                                (int)left, (int)top,
-                                (int)(right - left), (int)(bottom - top),
-                                2 * (int)rx, 2 * (int)ry);
-                    }
-                });
-    }
-
-    @LayoutlibDelegate
-    public static void nDrawPath(long nativeCanvas, long path, long paint) {
-        final Path_Delegate pathDelegate = Path_Delegate.getDelegate(path);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> {
-                    Shape shape = pathDelegate.getJavaShape();
-                    Rectangle2D bounds = shape.getBounds2D();
-                    if (bounds.isEmpty()) {
-                        // Apple JRE 1.6 doesn't like drawing empty shapes.
-                        // http://b.android.com/178278
-
-                        if (pathDelegate.isEmpty()) {
-                            // This means that the path doesn't have any lines or curves so
-                            // nothing to draw.
-                            return;
-                        }
-
-                        // The stroke width is not consider for the size of the bounds so,
-                        // for example, a horizontal line, would be considered as an empty
-                        // rectangle.
-                        // If the strokeWidth is not 0, we use it to consider the size of the
-                        // path as well.
-                        float strokeWidth = paintDelegate.getStrokeWidth();
-                        if (strokeWidth <= 0.0f) {
-                            return;
-                        }
-                        bounds.setRect(bounds.getX(), bounds.getY(),
-                                Math.max(strokeWidth, bounds.getWidth()),
-                                Math.max(strokeWidth, bounds.getHeight()));
-                    }
-
-                    int style = paintDelegate.getStyle();
-
-                    if (style == Paint.Style.FILL.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.fill(shape);
-                    }
-
-                    if (style == Paint.Style.STROKE.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.draw(shape);
-                    }
-                });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawRegion(long nativeCanvas, long nativeRegion,
-            long nativePaint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Some canvas paths may not be drawn", null, null);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawNinePatch(long nativeCanvas, long nativeBitmap, long ninePatch,
-            final float dstLeft, final float dstTop, final float dstRight, final float dstBottom,
-            long nativePaintOrZero, final int screenDensity, final int bitmapDensity) {
-
-        // get the delegate from the native int.
-        final Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nativeBitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        byte[] c = NinePatch_Delegate.getChunk(ninePatch);
-        if (c == null) {
-            // not a 9-patch?
-            BufferedImage image = bitmapDelegate.getImage();
-            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero, 0, 0, image.getWidth(),
-                    image.getHeight(), (int) dstLeft, (int) dstTop, (int) dstRight,
-                    (int) dstBottom);
-            return;
-        }
-
-        final NinePatchChunk chunkObject = NinePatch_Delegate.getChunk(c);
-        assert chunkObject != null;
-        if (chunkObject == null) {
-            return;
-        }
-
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // this one can be null
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nativePaintOrZero);
-
-        canvasDelegate.getSnapshot().draw(new GcSnapshot.Drawable() {
-            @Override
-            public void draw(Graphics2D graphics, Paint_Delegate paint) {
-                chunkObject.draw(bitmapDelegate.getImage(), graphics, (int) dstLeft, (int) dstTop,
-                        (int) (dstRight - dstLeft), (int) (dstBottom - dstTop), screenDensity,
-                        bitmapDensity);
-            }
-        }, paintDelegate, true, false);
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawBitmapMatrix(long nCanvas, Bitmap bitmap,
-            long nMatrix, long nPaint) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the delegate from the native int, which can be null
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
-
-        // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        final BufferedImage image = getImageToDraw(bitmapDelegate, paintDelegate, sBoolOut);
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        final AffineTransform mtx = matrixDelegate.getAffineTransform();
-
-        canvasDelegate.getSnapshot().draw((graphics, paint) -> {
-            if (paint != null && paint.isFilterBitmap()) {
-                graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-            }
-
-            //FIXME add support for canvas, screen and bitmap densities.
-            graphics.drawImage(image, mtx, null);
-        }, paintDelegate, true /*compositeOnly*/, false /*forceSrcMode*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawBitmapMesh(long nCanvas, Bitmap bitmap,
-            int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors,
-            int colorOffset, long nPaint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawBitmapMesh is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawVertices(long nCanvas, int mode, int n,
-            float[] verts, int vertOffset,
-            float[] texs, int texOffset,
-            int[] colors, int colorOffset,
-            short[] indices, int indexOffset,
-            int indexCount, long nPaint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawVertices is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawText(long nativeCanvas, char[] text, int index, int count,
-            float startX, float startY, int flags, long paint, long typeface) {
-        drawText(nativeCanvas, text, index, count, startX, startY, (flags & 1) != 0,
-                paint, typeface);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawText(long nativeCanvas, String text,
-            int start, int end, float x, float y, final int flags, long paint,
-            long typeface) {
-        int count = end - start;
-        char[] buffer = TemporaryBuffer.obtain(count);
-        TextUtils.getChars(text, start, end, buffer, 0);
-
-        nDrawText(nativeCanvas, buffer, 0, count, x, y, flags, paint, typeface);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawTextRun(long nativeCanvas, String text,
-            int start, int end, int contextStart, int contextEnd,
-            float x, float y, boolean isRtl, long paint, long typeface) {
-        int count = end - start;
-        char[] buffer = TemporaryBuffer.obtain(count);
-        TextUtils.getChars(text, start, end, buffer, 0);
-
-        drawText(nativeCanvas, buffer, 0, count, x, y, isRtl, paint, typeface);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawTextRun(long nativeCanvas, char[] text,
-            int start, int count, int contextStart, int contextCount,
-            float x, float y, boolean isRtl, long paint, long typeface) {
-        drawText(nativeCanvas, text, start, count, x, y, isRtl, paint, typeface);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawTextOnPath(long nativeCanvas,
-            char[] text, int index,
-            int count, long path,
-            float hOffset,
-            float vOffset, int bidiFlags,
-            long paint, long typeface) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawTextOnPath is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawTextOnPath(long nativeCanvas,
-            String text, long path,
-            float hOffset,
-            float vOffset,
-            int bidiFlags, long paint,
-            long typeface) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawTextOnPath is not supported.", null, null /*data*/);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * Executes a {@link GcSnapshot.Drawable} with a given canvas and paint.
-     * <p>Note that the drawable may actually be executed several times if there are
-     * layers involved (see {@link #saveLayer(RectF, Paint_Delegate, int)}.
-     */
-    private static void draw(long nCanvas, long nPaint, boolean compositeOnly, boolean forceSrcMode,
-            GcSnapshot.Drawable drawable) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the paint which can be null if nPaint is 0;
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
-
-        canvasDelegate.getSnapshot().draw(drawable, paintDelegate, compositeOnly, forceSrcMode);
-    }
-
-    /**
-     * Executes a {@link GcSnapshot.Drawable} with a given canvas. No paint object will be provided
-     * to {@link GcSnapshot.Drawable#draw(Graphics2D, Paint_Delegate)}.
-     * <p>Note that the drawable may actually be executed several times if there are
-     * layers involved (see {@link #saveLayer(RectF, Paint_Delegate, int)}.
-     */
-    private static void draw(long nCanvas, GcSnapshot.Drawable drawable) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.mSnapshot.draw(drawable);
-    }
-
-    private static void drawText(long nativeCanvas, final char[] text, final int index,
-            final int count, final float startX, final float startY, final boolean isRtl,
-            long paint, final long typeface) {
-
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> {
-                    // WARNING: the logic in this method is similar to Paint_Delegate.measureText.
-                    // Any change to this method should be reflected in Paint.measureText
-
-                    // assert that the typeface passed is actually the one stored in paint.
-                    assert (typeface == paintDelegate.mNativeTypeface);
-
-                    // Paint.TextAlign indicates how the text is positioned relative to X.
-                    // LEFT is the default and there's nothing to do.
-                    float x = startX;
-                    int limit = index + count;
-                    if (paintDelegate.getTextAlign() != Paint.Align.LEFT.nativeInt) {
-                        RectF bounds =
-                                paintDelegate.measureText(text, index, count, null, 0, isRtl);
-                        float m = bounds.right - bounds.left;
-                        if (paintDelegate.getTextAlign() == Paint.Align.CENTER.nativeInt) {
-                            x -= m / 2;
-                        } else if (paintDelegate.getTextAlign() == Paint.Align.RIGHT.nativeInt) {
-                            x -= m;
-                        }
-                    }
-
-                    new BidiRenderer(graphics, paintDelegate, text).setRenderLocation(x,
-                            startY).renderText(index, limit, isRtl, null, 0, true);
-                });
-    }
-
-    private static void drawBitmap(long nativeCanvas, Bitmap_Delegate bitmap,
-            long nativePaintOrZero, final int sleft, final int stop, final int sright,
-            final int sbottom, final int dleft, final int dtop, final int dright,
-            final int dbottom) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the paint, which could be null if the int is 0
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nativePaintOrZero);
-
-        final BufferedImage image = getImageToDraw(bitmap, paintDelegate, sBoolOut);
-
-        draw(nativeCanvas, nativePaintOrZero, true /*compositeOnly*/, sBoolOut[0],
-                (graphics, paint) -> {
-                    if (paint != null && paint.isFilterBitmap()) {
-                        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-                    }
-
-                    //FIXME add support for canvas, screen and bitmap densities.
-                    graphics.drawImage(image, dleft, dtop, dright, dbottom, sleft, stop, sright,
-                            sbottom, null);
-                });
-    }
-
-    /**
-     * Returns a BufferedImage ready for drawing, based on the bitmap and paint delegate.
-     * The image returns, through a 1-size boolean array, whether the drawing code should
-     * use a SRC composite no matter what the paint says.
-     *
-     * @param bitmap the bitmap
-     * @param paint the paint that will be used to draw
-     * @param forceSrcMode whether the composite will have to be SRC
-     * @return the image to draw
-     */
-    private static BufferedImage getImageToDraw(Bitmap_Delegate bitmap, Paint_Delegate paint,
-            boolean[] forceSrcMode) {
-        BufferedImage image = bitmap.getImage();
-        forceSrcMode[0] = false;
-
-        // if the bitmap config is alpha_8, then we erase all color value from it
-        // before drawing it or apply the texture from the shader if present.
-        if (bitmap.getConfig() == Bitmap.Config.ALPHA_8) {
-            Shader_Delegate shader = paint.getShader();
-            java.awt.Paint javaPaint = null;
-            if (shader instanceof BitmapShader_Delegate) {
-                javaPaint = shader.getJavaPaint();
-            }
-
-            fixAlpha8Bitmap(image, javaPaint);
-        } else if (!bitmap.hasAlpha()) {
-            // hasAlpha is merely a rendering hint. There can in fact be alpha values
-            // in the bitmap but it should be ignored at drawing time.
-            // There is two ways to do this:
-            // - override the composite to be SRC. This can only be used if the composite
-            //   was going to be SRC or SRC_OVER in the first place
-            // - Create a different bitmap to draw in which all the alpha channel values is set
-            //   to 0xFF.
-            if (paint != null) {
-                PorterDuff.Mode mode = PorterDuff.intToMode(paint.getPorterDuffMode());
-
-                forceSrcMode[0] = mode == PorterDuff.Mode.SRC_OVER || mode == PorterDuff.Mode.SRC;
-            }
-
-            // if we can't force SRC mode, then create a temp bitmap of TYPE_RGB
-            if (!forceSrcMode[0]) {
-                image = Bitmap_Delegate.createCopy(image, BufferedImage.TYPE_INT_RGB, 0xFF);
-            }
-        }
-
-        return image;
-    }
-
-    /**
-     * This method will apply the correct color to the passed "only alpha" image. Colors on the
-     * passed image will be destroyed.
-     * If the passed javaPaint is null, the color will be set to 0. If a paint is passed, it will
-     * be used to obtain the color that will be applied.
-     * <p/>
-     * This will destroy the passed image color channel.
-     */
-    private static void fixAlpha8Bitmap(final BufferedImage image,
-            @Nullable java.awt.Paint javaPaint) {
-        int w = image.getWidth();
-        int h = image.getHeight();
-
-        DataBuffer texture = null;
-        if (javaPaint != null) {
-            PaintContext context = javaPaint.createContext(ColorModel.getRGBdefault(), null, null,
-                    new AffineTransform(), null);
-            texture = context.getRaster(0, 0, w, h).getDataBuffer();
-        }
-
-        int[] argb = new int[w * h];
-        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
-
-        final int length = argb.length;
-        for (int i = 0; i < length; i++) {
-            argb[i] &= 0xFF000000;
-            if (texture != null) {
-                argb[i] |= texture.getElem(i) & 0x00FFFFFF;
-            }
-        }
-
-        image.setRGB(0, 0, w, h, argb, 0, w);
-    }
-
-    protected int save(int saveFlags) {
-        // get the current save count
-        int count = mSnapshot.size();
-
-        mSnapshot = mSnapshot.save(saveFlags);
-
-        // return the old save count
-        return count;
-    }
-
-    protected int saveLayerAlpha(RectF rect, int alpha, int saveFlags) {
-        Paint_Delegate paint = new Paint_Delegate();
-        paint.setAlpha(alpha);
-        return saveLayer(rect, paint, saveFlags);
-    }
-
-    protected int saveLayer(RectF rect, Paint_Delegate paint, int saveFlags) {
-        // get the current save count
-        int count = mSnapshot.size();
-
-        mSnapshot = mSnapshot.saveLayer(rect, paint, saveFlags);
-
-        // return the old save count
-        return count;
-    }
-
-    /**
-     * Restores the {@link GcSnapshot} to <var>saveCount</var>
-     * @param saveCount the saveCount
-     */
-    protected void restoreTo(int saveCount) {
-        mSnapshot = mSnapshot.restoreTo(saveCount);
-    }
-
-    /**
-     * Restores the top {@link GcSnapshot}
-     */
-    protected void restore() {
-        mSnapshot = mSnapshot.restore();
-    }
-
-    protected boolean clipRect(float left, float top, float right, float bottom, int regionOp) {
-        return mSnapshot.clipRect(left, top, right, bottom, regionOp);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java b/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
deleted file mode 100644
index c6827a3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
+++ /dev/null
@@ -1,325 +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 android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-
-import android.graphics.Paint_Delegate.FontInfo;
-import android.icu.lang.UScript;
-import android.icu.lang.UScriptRun;
-import android.icu.text.Bidi;
-import android.icu.text.BidiRun;
-
-import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.Toolkit;
-import java.awt.font.FontRenderContext;
-import java.awt.font.GlyphVector;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Render the text by breaking it into various scripts and using the right font for each script.
- * Can be used to measure the text without actually drawing it.
- */
-@SuppressWarnings("deprecation")
-public class BidiRenderer {
-    private static String JAVA_VENDOR = System.getProperty("java.vendor");
-
-    private static class ScriptRun {
-        int start;
-        int limit;
-        boolean isRtl;
-        int scriptCode;
-        Font font;
-
-        public ScriptRun(int start, int limit, boolean isRtl) {
-            this.start = start;
-            this.limit = limit;
-            this.isRtl = isRtl;
-            this.scriptCode = UScript.INVALID_CODE;
-        }
-    }
-
-    private final Graphics2D mGraphics;
-    private final Paint_Delegate mPaint;
-    private char[] mText;
-    // This List can contain nulls. A null font implies that the we weren't able to load the font
-    // properly. So, if we encounter a situation where we try to use that font, log a warning.
-    private List<Font> mFonts;
-    // Bounds of the text drawn so far.
-    private RectF mBounds;
-    private float mBaseline;
-
-    /**
-     * @param graphics May be null.
-     * @param paint The Paint to use to get the fonts. Should not be null.
-     * @param text Unidirectional text. Should not be null.
-     */
-    public BidiRenderer(Graphics2D graphics, Paint_Delegate paint, char[] text) {
-        assert (paint != null);
-        mGraphics = graphics;
-        mPaint = paint;
-        mText = text;
-        mFonts = new ArrayList<Font>(paint.getFonts().size());
-        for (FontInfo fontInfo : paint.getFonts()) {
-            if (fontInfo == null) {
-                mFonts.add(null);
-                continue;
-            }
-            mFonts.add(fontInfo.mFont);
-        }
-        mBounds = new RectF();
-    }
-
-    /**
-     *
-     * @param x The x-coordinate of the left edge of where the text should be drawn on the given
-     *            graphics.
-     * @param y The y-coordinate at which to draw the text on the given mGraphics.
-     *
-     */
-    public BidiRenderer setRenderLocation(float x, float y) {
-        mBounds = new RectF(x, y, x, y);
-        mBaseline = y;
-        return this;
-    }
-
-    /**
-     * Perform Bidi Analysis on the text and then render it.
-     * <p/>
-     * To skip the analysis and render unidirectional text, see {@link
-     * #renderText(int, int, boolean, float[], int, boolean)}
-     */
-    public RectF renderText(int start, int limit, int bidiFlags, float[] advances,
-            int advancesIndex, boolean draw) {
-        Bidi bidi = new Bidi(mText, start, null, 0, limit - start, getIcuFlags(bidiFlags));
-        for (int i = 0; i < bidi.countRuns(); i++) {
-            BidiRun visualRun = bidi.getVisualRun(i);
-            boolean isRtl = visualRun.getDirection() == Bidi.RTL;
-            renderText(visualRun.getStart(), visualRun.getLimit(), isRtl, advances,
-                    advancesIndex, draw);
-        }
-        return mBounds;
-    }
-
-    /**
-     * Render unidirectional text.
-     * <p/>
-     * This method can also be used to measure the width of the text without actually drawing it.
-     * <p/>
-     * @param start index of the first character
-     * @param limit index of the first character that should not be rendered.
-     * @param isRtl is the text right-to-left
-     * @param advances If not null, then advances for each character to be rendered are returned
-     *            here.
-     * @param advancesIndex index into advances from where the advances need to be filled.
-     * @param draw If true and {@code graphics} is not null, draw the rendered text on the graphics
-     *            at the given co-ordinates
-     * @return A rectangle specifying the bounds of the text drawn.
-     */
-    public RectF renderText(int start, int limit, boolean isRtl, float[] advances,
-            int advancesIndex, boolean draw) {
-        // We break the text into scripts and then select font based on it and then render each of
-        // the script runs.
-        for (ScriptRun run : getScriptRuns(mText, start, limit, isRtl, mFonts)) {
-            int flag = Font.LAYOUT_NO_LIMIT_CONTEXT | Font.LAYOUT_NO_START_CONTEXT;
-            flag |= isRtl ? Font.LAYOUT_RIGHT_TO_LEFT : Font.LAYOUT_LEFT_TO_RIGHT;
-            renderScript(run.start, run.limit, run.font, flag, advances, advancesIndex, draw);
-            advancesIndex += run.limit - run.start;
-        }
-        return mBounds;
-    }
-
-    /**
-     * Render a script run to the right of the bounds passed. Use the preferred font to render as
-     * much as possible. This also implements a fallback mechanism to render characters that cannot
-     * be drawn using the preferred font.
-     */
-    private void renderScript(int start, int limit, Font preferredFont, int flag,
-            float[] advances, int advancesIndex, boolean draw) {
-        if (mFonts.size() == 0 || preferredFont == null) {
-            return;
-        }
-
-        while (start < limit) {
-            boolean foundFont = false;
-            int canDisplayUpTo = preferredFont.canDisplayUpTo(mText, start, limit);
-            if (canDisplayUpTo == -1) {
-                // We can draw all characters in the text.
-                render(start, limit, preferredFont, flag, advances, advancesIndex, draw);
-                return;
-            }
-            if (canDisplayUpTo > start) {
-                // We can draw something.
-                render(start, canDisplayUpTo, preferredFont, flag, advances, advancesIndex, draw);
-                advancesIndex += canDisplayUpTo - start;
-                start = canDisplayUpTo;
-            }
-
-            // The current character cannot be drawn with the preferred font. Cycle through all the
-            // fonts to check which one can draw it.
-            int charCount = Character.isHighSurrogate(mText[start]) ? 2 : 1;
-            for (Font font : mFonts) {
-                if (font == null) {
-                    logFontWarning();
-                    continue;
-                }
-                canDisplayUpTo = font.canDisplayUpTo(mText, start, start + charCount);
-                if (canDisplayUpTo == -1) {
-                    render(start, start+charCount, font, flag, advances, advancesIndex, draw);
-                    start += charCount;
-                    advancesIndex += charCount;
-                    foundFont = true;
-                    break;
-                }
-            }
-            if (!foundFont) {
-                // No font can display this char. Use the preferred font. The char will most
-                // probably appear as a box or a blank space. We could, probably, use some
-                // heuristics and break the character into the base character and diacritics and
-                // then draw it, but it's probably not worth the effort.
-                render(start, start + charCount, preferredFont, flag, advances, advancesIndex,
-                        draw);
-                start += charCount;
-                advancesIndex += charCount;
-            }
-        }
-    }
-
-    private static void logFontWarning() {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
-                "Some fonts could not be loaded. The rendering may not be perfect. " +
-                        "Try running the IDE with JRE 7.", null, null);
-    }
-
-    /**
-     * Renders the text to the right of the bounds with the given font.
-     * @param font The font to render the text with.
-     */
-    private void render(int start, int limit, Font font, int flag, float[] advances,
-            int advancesIndex, boolean draw) {
-
-        FontRenderContext frc;
-        if (mGraphics != null) {
-            frc = mGraphics.getFontRenderContext();
-        } else {
-            frc = Toolkit.getDefaultToolkit().getFontMetrics(font).getFontRenderContext();
-
-            // Metrics obtained this way don't have anti-aliasing set. So,
-            // we create a new FontRenderContext with anti-aliasing set.
-            AffineTransform transform = font.getTransform();
-            if (mPaint.isAntiAliased() &&
-                    // Workaround for http://b.android.com/211659
-                    (transform.getScaleX() <= 9.9 ||
-                    !"JetBrains s.r.o".equals(JAVA_VENDOR))) {
-                frc = new FontRenderContext(transform, true, frc.usesFractionalMetrics());
-            }
-        }
-        GlyphVector gv = font.layoutGlyphVector(frc, mText, start, limit, flag);
-        int ng = gv.getNumGlyphs();
-        int[] ci = gv.getGlyphCharIndices(0, ng, null);
-        if (advances != null) {
-            for (int i = 0; i < ng; i++) {
-                int adv_idx = advancesIndex + ci[i];
-                advances[adv_idx] += gv.getGlyphMetrics(i).getAdvanceX();
-            }
-        }
-        if (draw && mGraphics != null) {
-            mGraphics.drawGlyphVector(gv, mBounds.right, mBaseline);
-        }
-
-        // Update the bounds.
-        Rectangle2D awtBounds = gv.getLogicalBounds();
-        RectF bounds = awtRectToAndroidRect(awtBounds, mBounds.right, mBaseline);
-        // If the width of the bounds is zero, no text had been drawn earlier. Hence, use the
-        // coordinates from the bounds as an offset.
-        if (Math.abs(mBounds.right - mBounds.left) == 0) {
-            mBounds = bounds;
-        } else {
-            mBounds.union(bounds);
-        }
-    }
-
-    // --- Static helper methods ---
-
-    private static RectF awtRectToAndroidRect(Rectangle2D awtRec, float offsetX, float offsetY) {
-        float left = (float) awtRec.getX();
-        float top = (float) awtRec.getY();
-        float right = (float) (left + awtRec.getWidth());
-        float bottom = (float) (top + awtRec.getHeight());
-        RectF androidRect = new RectF(left, top, right, bottom);
-        androidRect.offset(offsetX, offsetY);
-        return androidRect;
-    }
-
-    /* package */  static List<ScriptRun> getScriptRuns(char[] text, int start, int limit,
-            boolean isRtl, List<Font> fonts) {
-        LinkedList<ScriptRun> scriptRuns = new LinkedList<ScriptRun>();
-
-        int count = limit - start;
-        UScriptRun uScriptRun = new UScriptRun(text, start, count);
-        while (uScriptRun.next()) {
-            int scriptStart = uScriptRun.getScriptStart();
-            int scriptLimit = uScriptRun.getScriptLimit();
-            ScriptRun run = new ScriptRun(scriptStart, scriptLimit, isRtl);
-            run.scriptCode = uScriptRun.getScriptCode();
-            setScriptFont(text, run, fonts);
-            scriptRuns.add(run);
-        }
-
-        return scriptRuns;
-    }
-
-    // TODO: Replace this method with one which returns the font based on the scriptCode.
-    private static void setScriptFont(char[] text, ScriptRun run,
-            List<Font> fonts) {
-        for (Font font : fonts) {
-            if (font == null) {
-                logFontWarning();
-                continue;
-            }
-            if (font.canDisplayUpTo(text, run.start, run.limit) == -1) {
-                run.font = font;
-                return;
-            }
-        }
-        run.font = fonts.get(0);
-    }
-
-    private static int getIcuFlags(int bidiFlag) {
-        switch (bidiFlag) {
-            case Paint.BIDI_LTR:
-            case Paint.BIDI_FORCE_LTR:
-                return Bidi.DIRECTION_LEFT_TO_RIGHT;
-            case Paint.BIDI_RTL:
-            case Paint.BIDI_FORCE_RTL:
-                return Bidi.DIRECTION_RIGHT_TO_LEFT;
-            case Paint.BIDI_DEFAULT_LTR:
-                return Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;
-            case Paint.BIDI_DEFAULT_RTL:
-                return Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT;
-            default:
-                assert false;
-                return Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
deleted file mode 100644
index 8bd2a7a..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
+++ /dev/null
@@ -1,156 +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.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.resources.Density;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import com.android.layoutlib.bridge.util.NinePatchInputStream;
-import android.graphics.BitmapFactory.Options;
-import android.graphics.Bitmap_Delegate.BitmapCreateFlags;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.EnumSet;
-import java.util.Set;
-
-/**
- * Delegate implementing the native methods of android.graphics.BitmapFactory
- *
- * Through the layoutlib_create tool, the original native methods of BitmapFactory have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-/*package*/ class BitmapFactory_Delegate {
-
-    // ------ Native Delegates ------
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage,
-            @Nullable Rect padding, @Nullable Options opts) {
-        Bitmap bm = null;
-
-        Density density = Density.MEDIUM;
-        Set<BitmapCreateFlags> bitmapCreateFlags = EnumSet.of(BitmapCreateFlags.MUTABLE);
-        if (opts != null) {
-            density = Density.getEnum(opts.inDensity);
-            if (opts.inPremultiplied) {
-                bitmapCreateFlags.add(BitmapCreateFlags.PREMULTIPLIED);
-            }
-            opts.inScaled = false;
-        }
-
-        try {
-            if (is instanceof NinePatchInputStream) {
-                NinePatchInputStream npis = (NinePatchInputStream) is;
-                npis.disableFakeMarkSupport();
-
-                // load the bitmap as a nine patch
-                com.android.ninepatch.NinePatch ninePatch = com.android.ninepatch.NinePatch.load(
-                        npis, true /*is9Patch*/, false /*convert*/);
-
-                // get the bitmap and chunk objects.
-                bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), bitmapCreateFlags,
-                        density);
-                NinePatchChunk chunk = ninePatch.getChunk();
-
-                // put the chunk in the bitmap
-                bm.setNinePatchChunk(NinePatch_Delegate.serialize(chunk));
-
-                if (padding != null) {
-                    // read the padding
-                    int[] paddingArray = chunk.getPadding();
-                    padding.left = paddingArray[0];
-                    padding.top = paddingArray[1];
-                    padding.right = paddingArray[2];
-                    padding.bottom = paddingArray[3];
-                }
-            } else {
-                // load the bitmap directly.
-                bm = Bitmap_Delegate.createBitmap(is, bitmapCreateFlags, density);
-            }
-        } catch (IOException e) {
-            Bridge.getLog().error(null, "Failed to load image", e, null);
-        }
-
-        return bm;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
-            Rect padding, Options opts) {
-        opts.inBitmap = null;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeAsset(long asset, Rect padding, Options opts) {
-        opts.inBitmap = null;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeByteArray(byte[] data, int offset,
-            int length, Options opts) {
-        opts.inBitmap = null;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeIsSeekable(FileDescriptor fd) {
-        return true;
-    }
-
-    /**
-     * Set the newly decoded bitmap's density based on the Options.
-     *
-     * Copied from {@link BitmapFactory#setDensityFromOptions(Bitmap, Options)}.
-     */
-    @LayoutlibDelegate
-    /*package*/ static void setDensityFromOptions(Bitmap outputBitmap, Options opts) {
-        if (outputBitmap == null || opts == null) return;
-
-        final int density = opts.inDensity;
-        if (density != 0) {
-            outputBitmap.setDensity(density);
-            final int targetDensity = opts.inTargetDensity;
-            if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {
-                return;
-            }
-
-            // --- Change from original implementation begins ---
-            // LayoutLib doesn't scale the nine patch when decoding it. Hence, don't change the
-            // density of the source bitmap in case of ninepatch.
-
-            if (opts.inScaled) {
-            // --- Change from original implementation ends. ---
-                outputBitmap.setDensity(targetDensity);
-            }
-        } else if (opts.inBitmap != null) {
-            // bitmap was reused, ensure density is reset
-            outputBitmap.setDensity(Bitmap.getDefaultDensity());
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
deleted file mode 100644
index 4914a48..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-import java.awt.PaintContext;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.Raster;
-
-/**
- * Delegate implementing the native methods of android.graphics.BitmapShader
- *
- * Through the layoutlib_create tool, the original native methods of BitmapShader have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original BitmapShader class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class BitmapShader_Delegate extends Shader_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        // no message since isSupported returns true;
-        return null;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long nativeMatrix, Bitmap androidBitmap,
-            int shaderTileModeX, int shaderTileModeY) {
-        Bitmap_Delegate bitmap = Bitmap_Delegate.getDelegate(androidBitmap);
-        if (bitmap == null) {
-            return 0;
-        }
-
-        BitmapShader_Delegate newDelegate = new BitmapShader_Delegate(nativeMatrix,
-                bitmap.getImage(),
-                Shader_Delegate.getTileMode(shaderTileModeX),
-                Shader_Delegate.getTileMode(shaderTileModeY));
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private BitmapShader_Delegate(long matrix, BufferedImage image,
-            TileMode tileModeX, TileMode tileModeY) {
-        super(matrix);
-        mJavaPaint = new BitmapShaderPaint(image, tileModeX, tileModeY);
-    }
-
-    private class BitmapShaderPaint implements java.awt.Paint {
-        private final BufferedImage mImage;
-        private final TileMode mTileModeX;
-        private final TileMode mTileModeY;
-
-        BitmapShaderPaint(BufferedImage image,
-                TileMode tileModeX, TileMode tileModeY) {
-            mImage = image;
-            mTileModeX = tileModeX;
-            mTileModeY = tileModeY;
-        }
-
-        @Override
-        public PaintContext createContext(ColorModel colorModel, Rectangle deviceBounds,
-                Rectangle2D userBounds, AffineTransform xform, RenderingHints hints) {
-            AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in BitmapShader", e, null /*data*/);
-                canvasMatrix = new AffineTransform();
-            }
-
-            AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in BitmapShader", e, null /*data*/);
-                localMatrix = new AffineTransform();
-            }
-
-            if (!colorModel.isCompatibleRaster(mImage.getRaster())) {
-                // Fallback to the default ARGB color model
-                colorModel = ColorModel.getRGBdefault();
-            }
-
-            return new BitmapShaderContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class BitmapShaderContext implements PaintContext {
-
-            private final AffineTransform mCanvasMatrix;
-            private final AffineTransform mLocalMatrix;
-            private final ColorModel mColorModel;
-
-            public BitmapShaderContext(
-                    AffineTransform canvasMatrix,
-                    AffineTransform localMatrix,
-                    ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel;
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public Raster getRaster(int x, int y, int w, int h) {
-                BufferedImage image = new BufferedImage(
-                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
-                    mColorModel.isAlphaPremultiplied(), null);
-
-                int[] data = new int[w*h];
-
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix.
-                        pt1[0] = pt2[0];
-                        pt1[1] = pt2[1];
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        data[index++] = getColor(pt2[0], pt2[1]);
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-        }
-
-        /**
-         * Returns a color for an arbitrary point.
-         */
-        private int getColor(float fx, float fy) {
-            int x = getCoordinate(Math.round(fx), mImage.getWidth(), mTileModeX);
-            int y = getCoordinate(Math.round(fy), mImage.getHeight(), mTileModeY);
-
-            return mImage.getRGB(x, y);
-        }
-
-        private int getCoordinate(int i, int size, TileMode mode) {
-            if (i < 0) {
-                switch (mode) {
-                    case CLAMP:
-                        i = 0;
-                        break;
-                    case REPEAT:
-                        i = size - 1 - (-i % size);
-                        break;
-                    case MIRROR:
-                        // this is the same as the positive side, just make the value positive
-                        // first.
-                        i = -i;
-                        int count = i / size;
-                        i = i % size;
-
-                        if ((count % 2) == 1) {
-                            i = size - 1 - i;
-                        }
-                        break;
-                }
-            } else if (i >= size) {
-                switch (mode) {
-                    case CLAMP:
-                        i = size - 1;
-                        break;
-                    case REPEAT:
-                        i = i % size;
-                        break;
-                    case MIRROR:
-                        int count = i / size;
-                        i = i % size;
-
-                        if ((count % 2) == 1) {
-                            i = size - 1 - i;
-                        }
-                        break;
-                }
-            }
-
-            return i;
-        }
-
-
-        @Override
-        public int getTransparency() {
-            return java.awt.Paint.TRANSLUCENT;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
deleted file mode 100644
index 43c95f4..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.resources.Density;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import android.graphics.Bitmap.Config;
-import android.os.Parcel;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.Buffer;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.Set;
-
-import javax.imageio.ImageIO;
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.Bitmap
- *
- * Through the layoutlib_create tool, the original native methods of Bitmap have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Bitmap class.
- *
- * @see DelegateManager
- *
- */
-public final class Bitmap_Delegate {
-
-
-    public enum BitmapCreateFlags {
-        NONE, PREMULTIPLIED, MUTABLE
-    }
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Bitmap_Delegate> sManager =
-            new DelegateManager<>(Bitmap_Delegate.class);
-    private static long sFinalizer = -1;
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-    private final Config mConfig;
-    private final BufferedImage mImage;
-    private boolean mHasAlpha = true;
-    private boolean mHasMipMap = false;      // TODO: check the default.
-    private boolean mIsPremultiplied = true;
-    private int mGenerationId = 0;
-
-
-    // ---- Public Helper methods ----
-
-    /**
-     * Returns the native delegate associated to a given an int referencing a {@link Bitmap} object.
-     */
-    public static Bitmap_Delegate getDelegate(long native_bitmap) {
-        return sManager.getDelegate(native_bitmap);
-    }
-
-    @Nullable
-    public static Bitmap_Delegate getDelegate(@Nullable Bitmap bitmap) {
-        return bitmap == null ? null : getDelegate(bitmap.getNativeInstance());
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given file content.
-     *
-     * @param input the file from which to read the bitmap content
-     * @param isMutable whether the bitmap is mutable
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(File input, boolean isMutable, Density density)
-            throws IOException {
-        return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given file content.
-     *
-     * @param input the file from which to read the bitmap content
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isPremultiplied()
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    private static Bitmap createBitmap(File input, Set<BitmapCreateFlags> createFlags,
-            Density density) throws IOException {
-        // create a delegate with the content of the file.
-        BufferedImage image = ImageIO.read(input);
-        if (image == null && input.exists()) {
-            // There was a problem decoding the image, or the decoder isn't registered. Webp maybe.
-            // Replace with a broken image icon.
-            BridgeContext currentContext = RenderAction.getCurrentContext();
-            if (currentContext != null) {
-                RenderResources resources = currentContext.getRenderResources();
-                ResourceValue broken = resources.getFrameworkResource(ResourceType.DRAWABLE,
-                        "ic_menu_report_image");
-                File brokenFile = new File(broken.getValue());
-                if (brokenFile.exists()) {
-                    image = ImageIO.read(brokenFile);
-                }
-            }
-        }
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
-
-        return createBitmap(delegate, createFlags, density.getDpiValue());
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given stream content.
-     *
-     * @param input the stream from which to read the bitmap content
-     * @param isMutable whether the bitmap is mutable
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density)
-            throws IOException {
-        return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given stream content.
-     *
-     * @param input the stream from which to read the bitmap content
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isPremultiplied()
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(InputStream input, Set<BitmapCreateFlags> createFlags,
-            Density density) throws IOException {
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
-
-        return createBitmap(delegate, createFlags, density.getDpiValue());
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
-     *
-     * @param image the bitmap content
-     * @param isMutable whether the bitmap is mutable
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(BufferedImage image, boolean isMutable, Density density) {
-        return createBitmap(image, getPremultipliedBitmapCreateFlags(isMutable), density);
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
-     *
-     * @param image the bitmap content
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isPremultiplied()
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(BufferedImage image, Set<BitmapCreateFlags> createFlags,
-            Density density) {
-        // create a delegate with the given image.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
-
-        return createBitmap(delegate, createFlags, density.getDpiValue());
-    }
-
-    private static int getBufferedImageType() {
-        return BufferedImage.TYPE_INT_ARGB;
-    }
-
-    /**
-     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
-     */
-    public BufferedImage getImage() {
-        return mImage;
-    }
-
-    /**
-     * Returns the Android bitmap config. Note that this not the config of the underlying
-     * Java2D bitmap.
-     */
-    public Config getConfig() {
-        return mConfig;
-    }
-
-    /**
-     * Returns the hasAlpha rendering hint
-     * @return true if the bitmap alpha should be used at render time
-     */
-    public boolean hasAlpha() {
-        return mHasAlpha && mConfig != Config.RGB_565;
-    }
-
-    /**
-     * Update the generationId.
-     *
-     * @see Bitmap#getGenerationId()
-     */
-    public void change() {
-        mGenerationId++;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
-            int height, int nativeConfig, boolean isMutable) {
-        int imageType = getBufferedImageType();
-
-        // create the image
-        BufferedImage image = new BufferedImage(width, height, imageType);
-
-        if (colors != null) {
-            image.setRGB(0, 0, width, height, colors, offset, stride);
-        }
-
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
-
-        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
-                            Bitmap.getDefaultDensity());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCopy(long srcBitmap, int nativeConfig, boolean isMutable) {
-        Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(srcBitmap);
-        if (srcBmpDelegate == null) {
-            return null;
-        }
-
-        BufferedImage srcImage = srcBmpDelegate.getImage();
-
-        int width = srcImage.getWidth();
-        int height = srcImage.getHeight();
-
-        int imageType = getBufferedImageType();
-
-        // create the image
-        BufferedImage image = new BufferedImage(width, height, imageType);
-
-        // copy the source image into the image.
-        int[] argb = new int[width * height];
-        srcImage.getRGB(0, 0, width, height, argb, 0, width);
-        image.setRGB(0, 0, width, height, argb, 0, width);
-
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
-
-        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
-                Bitmap.getDefaultDensity());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCopyAshmem(long nativeSrcBitmap) {
-        // Unused method; no implementation provided.
-        assert false;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCopyAshmemConfig(long nativeSrcBitmap, int nativeConfig) {
-        // Unused method; no implementation provided.
-        assert false;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeGetNativeFinalizer() {
-        synchronized (Bitmap_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(sManager::removeJavaReferenceFor);
-            }
-            return sFinalizer;
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeRecycle(long nativeBitmap) {
-        // In our case reycle() is a no-op. We will let the finalizer to dispose the bitmap.
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeReconfigure(long nativeBitmap, int width, int height,
-            int config, boolean isPremultiplied) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.reconfigure() is not supported", null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeCompress(long nativeBitmap, int format, int quality,
-            OutputStream stream, byte[] tempStorage) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.compress() is not supported", null /*data*/);
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeErase(long nativeBitmap, int color) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        BufferedImage image = delegate.mImage;
-
-        Graphics2D g = image.createGraphics();
-        try {
-            g.setColor(new java.awt.Color(color, true));
-
-            g.fillRect(0, 0, image.getWidth(), image.getHeight());
-        } finally {
-            g.dispose();
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeRowBytes(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mImage.getWidth();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeConfig(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mConfig.nativeInt;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeHasAlpha(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        return delegate == null || delegate.mHasAlpha;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeHasMipMap(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        return delegate == null || delegate.mHasMipMap;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGetPixel(long nativeBitmap, int x, int y) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mImage.getRGB(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeGetPixels(long nativeBitmap, int[] pixels, int offset,
-            int stride, int x, int y, int width, int height) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.getImage().getRGB(x, y, width, height, pixels, offset, stride);
-    }
-
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetPixel(long nativeBitmap, int x, int y, int color) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.getImage().setRGB(x, y, color);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetPixels(long nativeBitmap, int[] colors, int offset,
-            int stride, int x, int y, int width, int height) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.getImage().setRGB(x, y, width, height, colors, offset, stride);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeCopyPixelsToBuffer(long nativeBitmap, Buffer dst) {
-        // FIXME implement native delegate
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.copyPixelsToBuffer is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeCopyPixelsFromBuffer(long nb, Buffer src) {
-        // FIXME implement native delegate
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.copyPixelsFromBuffer is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGenerationId(long nativeBitmap) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mGenerationId;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) {
-        // This is only called by Bitmap.CREATOR (Parcelable.Creator<Bitmap>), which is only
-        // used during aidl call so really this should not be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Bitmaps cannot be created from parcels.",
-                null /*data*/);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeWriteToParcel(long nativeBitmap, boolean isMutable,
-            int density, Parcel p) {
-        // This is only called when sending a bitmap through aidl, so really this should not
-        // be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Bitmaps cannot be written to parcels.",
-                null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeExtractAlpha(long nativeBitmap, long nativePaint,
-            int[] offsetXY) {
-        Bitmap_Delegate bitmap = sManager.getDelegate(nativeBitmap);
-        if (bitmap == null) {
-            return null;
-        }
-
-        // get the paint which can be null if nativePaint is 0.
-        Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
-
-        if (paint != null && paint.getMaskFilter() != null) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
-                    "MaskFilter not supported in Bitmap.extractAlpha",
-                    null, null /*data*/);
-        }
-
-        int alpha = paint != null ? paint.getAlpha() : 0xFF;
-        BufferedImage image = createCopy(bitmap.getImage(), BufferedImage.TYPE_INT_ARGB, alpha);
-
-        // create the delegate. The actual Bitmap config is only an alpha channel
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ALPHA_8);
-
-        // the density doesn't matter, it's set by the Java method.
-        return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.MUTABLE),
-                Density.DEFAULT_DENSITY /*density*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeIsPremultiplied(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        return delegate != null && delegate.mIsPremultiplied;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetPremultiplied(long nativeBitmap, boolean isPremul) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mIsPremultiplied = isPremul;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetHasAlpha(long nativeBitmap, boolean hasAlpha,
-            boolean isPremul) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mHasAlpha = hasAlpha;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mHasMipMap = hasMipMap;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeSameAs(long nb0, long nb1) {
-        Bitmap_Delegate delegate1 = sManager.getDelegate(nb0);
-        if (delegate1 == null) {
-            return false;
-        }
-
-        Bitmap_Delegate delegate2 = sManager.getDelegate(nb1);
-        if (delegate2 == null) {
-            return false;
-        }
-
-        BufferedImage image1 = delegate1.getImage();
-        BufferedImage image2 = delegate2.getImage();
-        if (delegate1.mConfig != delegate2.mConfig ||
-                image1.getWidth() != image2.getWidth() ||
-                image1.getHeight() != image2.getHeight()) {
-            return false;
-        }
-
-        // get the internal data
-        int w = image1.getWidth();
-        int h = image2.getHeight();
-        int[] argb1 = new int[w*h];
-        int[] argb2 = new int[w*h];
-
-        image1.getRGB(0, 0, w, h, argb1, 0, w);
-        image2.getRGB(0, 0, w, h, argb2, 0, w);
-
-        // compares
-        if (delegate1.mConfig == Config.ALPHA_8) {
-            // in this case we have to manually compare the alpha channel as the rest is garbage.
-            final int length = w*h;
-            for (int i = 0 ; i < length ; i++) {
-                if ((argb1[i] & 0xFF000000) != (argb2[i] & 0xFF000000)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        return Arrays.equals(argb1, argb2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGetAllocationByteCount(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-        return nativeRowBytes(nativeBitmap) * delegate.mImage.getHeight();
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativePrepareToDraw(long nativeBitmap) {
-        // do nothing as Bitmap_Delegate does not have caches
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCopyPreserveInternalConfig(long nativeBitmap) {
-        Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(nativeBitmap);
-        if (srcBmpDelegate == null) {
-            return null;
-        }
-
-        BufferedImage srcImage = srcBmpDelegate.getImage();
-
-        // create the image
-        BufferedImage image = new BufferedImage(srcImage.getColorModel(), srcImage.copyData(null),
-                srcImage.isAlphaPremultiplied(), null);
-
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, srcBmpDelegate.getConfig());
-
-        return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.NONE),
-                Bitmap.getDefaultDensity());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCreateHardwareBitmap(GraphicBuffer buffer) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.nativeCreateHardwareBitmap() is not supported", null /*data*/);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.nativeCreateGraphicBufferHandle() is not supported", null /*data*/);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeIsSRGB(long nativeBitmap) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Color spaces are not supported", null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeGetColorSpace(long nativePtr, float[] xyz, float[] params) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Color spaces are not supported", null /*data*/);
-        return false;
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private Bitmap_Delegate(BufferedImage image, Config config) {
-        mImage = image;
-        mConfig = config;
-    }
-
-    private static Bitmap createBitmap(Bitmap_Delegate delegate,
-            Set<BitmapCreateFlags> createFlags, int density) {
-        // get its native_int
-        long nativeInt = sManager.addNewDelegate(delegate);
-
-        int width = delegate.mImage.getWidth();
-        int height = delegate.mImage.getHeight();
-        boolean isMutable = createFlags.contains(BitmapCreateFlags.MUTABLE);
-        boolean isPremultiplied = createFlags.contains(BitmapCreateFlags.PREMULTIPLIED);
-
-        // and create/return a new Bitmap with it
-        return new Bitmap(nativeInt, width, height, density, isMutable,
-                          isPremultiplied, null /*ninePatchChunk*/, null /* layoutBounds */);
-    }
-
-    private static Set<BitmapCreateFlags> getPremultipliedBitmapCreateFlags(boolean isMutable) {
-        Set<BitmapCreateFlags> createFlags = EnumSet.of(BitmapCreateFlags.PREMULTIPLIED);
-        if (isMutable) {
-            createFlags.add(BitmapCreateFlags.MUTABLE);
-        }
-        return createFlags;
-    }
-
-    /**
-     * Creates and returns a copy of a given BufferedImage.
-     * <p/>
-     * if alpha is different than 255, then it is applied to the alpha channel of each pixel.
-     *
-     * @param image the image to copy
-     * @param imageType the type of the new image
-     * @param alpha an optional alpha modifier
-     * @return a new BufferedImage
-     */
-    /*package*/ static BufferedImage createCopy(BufferedImage image, int imageType, int alpha) {
-        int w = image.getWidth();
-        int h = image.getHeight();
-
-        BufferedImage result = new BufferedImage(w, h, imageType);
-
-        int[] argb = new int[w * h];
-        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
-
-        if (alpha != 255) {
-            final int length = argb.length;
-            for (int i = 0 ; i < length; i++) {
-                int a = (argb[i] >>> 24 * alpha) / 255;
-                argb[i] = (a << 24) | (argb[i] & 0x00FFFFFF);
-            }
-        }
-
-        result.setRGB(0, 0, w, h, argb, 0, w);
-
-        return result;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java b/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java
deleted file mode 100644
index 5cc964a..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import java.awt.Composite;
-import java.awt.CompositeContext;
-import java.awt.RenderingHints;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-
-/*
- * (non-Javadoc)
- * The class is adapted from a demo tool for Blending Modes written by
- * Romain Guy (romainguy@android.com). The tool is available at
- * http://www.curious-creature.org/2006/09/20/new-blendings-modes-for-java2d/
- *
- * This class has been adapted for applying color filters. When applying color filters, the src
- * image should not extend beyond the dest image, but in our implementation of the filters, it does.
- * To compensate for the effect, we recompute the alpha value of the src image before applying
- * the color filter as it should have been applied.
- */
-public final class BlendComposite implements Composite {
-    public enum BlendingMode {
-        MULTIPLY(),
-        SCREEN(),
-        DARKEN(),
-        LIGHTEN(),
-        OVERLAY(),
-        ADD();
-
-        private final BlendComposite mComposite;
-
-        BlendingMode() {
-            mComposite = new BlendComposite(this);
-        }
-
-        BlendComposite getBlendComposite() {
-            return mComposite;
-        }
-    }
-
-    private float alpha;
-    private BlendingMode mode;
-
-    private BlendComposite(BlendingMode mode) {
-        this(mode, 1.0f);
-    }
-
-    private BlendComposite(BlendingMode mode, float alpha) {
-        this.mode = mode;
-        setAlpha(alpha);
-    }
-
-    public static BlendComposite getInstance(BlendingMode mode) {
-        return mode.getBlendComposite();
-    }
-
-    public static BlendComposite getInstance(BlendingMode mode, float alpha) {
-        if (alpha > 0.9999f) {
-            return getInstance(mode);
-        }
-        return new BlendComposite(mode, alpha);
-    }
-
-    public float getAlpha() {
-        return alpha;
-    }
-
-    public BlendingMode getMode() {
-        return mode;
-    }
-
-    private void setAlpha(float alpha) {
-        if (alpha < 0.0f || alpha > 1.0f) {
-            assert false : "alpha must be comprised between 0.0f and 1.0f";
-            alpha = Math.min(alpha, 1.0f);
-            alpha = Math.max(alpha, 0.0f);
-        }
-
-        this.alpha = alpha;
-    }
-
-    @Override
-    public int hashCode() {
-        return Float.floatToIntBits(alpha) * 31 + mode.ordinal();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof BlendComposite)) {
-            return false;
-        }
-
-        BlendComposite bc = (BlendComposite) obj;
-
-        return mode == bc.mode && alpha == bc.alpha;
-    }
-
-    public CompositeContext createContext(ColorModel srcColorModel,
-                                          ColorModel dstColorModel,
-                                          RenderingHints hints) {
-        return new BlendingContext(this);
-    }
-
-    private static final class BlendingContext implements CompositeContext {
-        private final Blender blender;
-        private final BlendComposite composite;
-
-        private BlendingContext(BlendComposite composite) {
-            this.composite = composite;
-            this.blender = Blender.getBlenderFor(composite);
-        }
-
-        public void dispose() {
-        }
-
-        public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
-            if (src.getSampleModel().getDataType() != DataBuffer.TYPE_INT ||
-                dstIn.getSampleModel().getDataType() != DataBuffer.TYPE_INT ||
-                dstOut.getSampleModel().getDataType() != DataBuffer.TYPE_INT) {
-                throw new IllegalStateException(
-                        "Source and destination must store pixels as INT.");
-            }
-
-            int width = Math.min(src.getWidth(), dstIn.getWidth());
-            int height = Math.min(src.getHeight(), dstIn.getHeight());
-
-            float alpha = composite.getAlpha();
-
-            int[] srcPixel = new int[4];
-            int[] dstPixel = new int[4];
-            int[] result = new int[4];
-            int[] srcPixels = new int[width];
-            int[] dstPixels = new int[width];
-
-            for (int y = 0; y < height; y++) {
-                dstIn.getDataElements(0, y, width, 1, dstPixels);
-                if (alpha != 0) {
-                    src.getDataElements(0, y, width, 1, srcPixels);
-                    for (int x = 0; x < width; x++) {
-                        // pixels are stored as INT_ARGB
-                        // our arrays are [R, G, B, A]
-                        int pixel = srcPixels[x];
-                        srcPixel[0] = (pixel >> 16) & 0xFF;
-                        srcPixel[1] = (pixel >>  8) & 0xFF;
-                        srcPixel[2] = (pixel      ) & 0xFF;
-                        srcPixel[3] = (pixel >> 24) & 0xFF;
-
-                        pixel = dstPixels[x];
-                        dstPixel[0] = (pixel >> 16) & 0xFF;
-                        dstPixel[1] = (pixel >>  8) & 0xFF;
-                        dstPixel[2] = (pixel      ) & 0xFF;
-                        dstPixel[3] = (pixel >> 24) & 0xFF;
-
-                        // ---- Modified from original ----
-                        // recompute src pixel for transparency.
-                        srcPixel[3] *= dstPixel[3] / 0xFF;
-                        // ---- Modification ends ----
-
-                        result = blender.blend(srcPixel, dstPixel, result);
-
-                        // mixes the result with the opacity
-                        if (alpha == 1) {
-                            dstPixels[x] = (result[3] & 0xFF) << 24 |
-                                           (result[0] & 0xFF) << 16 |
-                                           (result[1] & 0xFF) <<  8 |
-                                           result[2] & 0xFF;
-                        } else {
-                            dstPixels[x] =
-                                    ((int) (dstPixel[3] + (result[3] - dstPixel[3]) * alpha) & 0xFF) << 24 |
-                                    ((int) (dstPixel[0] + (result[0] - dstPixel[0]) * alpha) & 0xFF) << 16 |
-                                    ((int) (dstPixel[1] + (result[1] - dstPixel[1]) * alpha) & 0xFF) <<  8 |
-                                    (int) (dstPixel[2] + (result[2] - dstPixel[2]) * alpha) & 0xFF;
-                        }
-
-                    }
-            }
-                dstOut.setDataElements(0, y, width, 1, dstPixels);
-            }
-        }
-    }
-
-    private static abstract class Blender {
-        public abstract int[] blend(int[] src, int[] dst, int[] result);
-
-        public static Blender getBlenderFor(BlendComposite composite) {
-            switch (composite.getMode()) {
-                case ADD:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 4; i++) {
-                                result[i] = Math.min(255, src[i] + dst[i]);
-                            }
-                            return result;
-                        }
-                    };
-                case DARKEN:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 3; i++) {
-                                result[i] = Math.min(src[i], dst[i]);
-                            }
-                            result[3] = Math.min(255, src[3] + dst[3]);
-                            return result;
-                        }
-                    };
-                case LIGHTEN:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 3; i++) {
-                                result[i] = Math.max(src[i], dst[i]);
-                            }
-                            result[3] = Math.min(255, src[3] + dst[3]);
-                            return result;
-                        }
-                    };
-                case MULTIPLY:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 3; i++) {
-                                result[i] = (src[i] * dst[i]) >> 8;
-                            }
-                            result[3] = Math.min(255, src[3] + dst[3] - (src[3] * dst[3]) / 255);
-                            return result;
-                        }
-                    };
-                case OVERLAY:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 3; i++) {
-                                result[i] = dst[i] < 128 ? dst[i] * src[i] >> 7 :
-                                    255 - ((255 - dst[i]) * (255 - src[i]) >> 7);
-                            }
-                            result[3] = Math.min(255, src[3] + dst[3]);
-                            return result;
-                        }
-                    };
-                case SCREEN:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            result[0] = 255 - ((255 - src[0]) * (255 - dst[0]) >> 8);
-                            result[1] = 255 - ((255 - src[1]) * (255 - dst[1]) >> 8);
-                            result[2] = 255 - ((255 - src[2]) * (255 - dst[2]) >> 8);
-                            result[3] = Math.min(255, src[3] + dst[3]);
-                            return result;
-                        }
-                    };
-                default:
-                    assert false : "Blender not implement for " + composite.getMode().name();
-
-                    // Ignore the blend
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            result[0] = dst[0];
-                            result[1] = dst[1];
-                            result[2] = dst[2];
-                            result[3] = dst[3];
-                            return result;
-                        }
-                    };
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java
deleted file mode 100644
index d2569c7..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.BlurMaskFilter
- *
- * Through the layoutlib_create tool, the original native methods of BlurMaskFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original BlurMaskFilter class.
- *
- * Because this extends {@link MaskFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link MaskFilter_Delegate}.
- *
- * @see MaskFilter_Delegate
- *
- */
-public class BlurMaskFilter_Delegate extends MaskFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Blur Mask Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeConstructor(float radius, int style) {
-        BlurMaskFilter_Delegate newDelegate = new BlurMaskFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
deleted file mode 100644
index 47216ee..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.GcSnapshot;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import android.graphics.Bitmap.Config;
-
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.geom.AffineTransform;
-
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-
-/**
- * Delegate implementing the native methods of android.graphics.Canvas
- *
- * Through the layoutlib_create tool, the original native methods of Canvas have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Canvas class.
- *
- * @see DelegateManager
- *
- */
-public final class Canvas_Delegate extends BaseCanvas_Delegate {
-
-    // ---- delegate manager ----
-    private static long sFinalizer = -1;
-
-    private DrawFilter_Delegate mDrawFilter = null;
-
-    // ---- Public Helper methods ----
-
-    /**
-     * Returns the native delegate associated to a given {@link Canvas} object.
-     */
-    public static Canvas_Delegate getDelegate(Canvas canvas) {
-        return (Canvas_Delegate) sManager.getDelegate(canvas.getNativeCanvasWrapper());
-    }
-
-    /**
-     * Returns the native delegate associated to a given an int referencing a {@link Canvas} object.
-     */
-    public static Canvas_Delegate getDelegate(long native_canvas) {
-        return (Canvas_Delegate) sManager.getDelegate(native_canvas);
-    }
-
-    /**
-     * Returns the current {@link Graphics2D} used to draw.
-     */
-    public GcSnapshot getSnapshot() {
-        return mSnapshot;
-    }
-
-    /**
-     * Returns the {@link DrawFilter} delegate or null if none have been set.
-     *
-     * @return the delegate or null.
-     */
-    public DrawFilter_Delegate getDrawFilter() {
-        return mDrawFilter;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nFreeCaches() {
-        // nothing to be done here.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFreeTextLayoutCaches() {
-        // nothing to be done here yet.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nInitRaster(@Nullable Bitmap bitmap) {
-        long nativeBitmapOrZero = 0;
-        if (bitmap != null) {
-            nativeBitmapOrZero = bitmap.getNativeInstance();
-        }
-        if (nativeBitmapOrZero > 0) {
-            // get the Bitmap from the int
-            Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nativeBitmapOrZero);
-
-            // create a new Canvas_Delegate with the given bitmap and return its new native int.
-            Canvas_Delegate newDelegate = new Canvas_Delegate(bitmapDelegate);
-
-            return sManager.addNewDelegate(newDelegate);
-        }
-
-        // create a new Canvas_Delegate and return its new native int.
-        Canvas_Delegate newDelegate = new Canvas_Delegate();
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    public static void nSetBitmap(long canvas, Bitmap bitmap) {
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas);
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (canvasDelegate == null || bitmapDelegate==null) {
-            return;
-        }
-        canvasDelegate.mBitmap = bitmapDelegate;
-        canvasDelegate.mSnapshot = GcSnapshot.createDefaultSnapshot(bitmapDelegate);
-    }
-
-    @LayoutlibDelegate
-    public static boolean nIsOpaque(long nativeCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        return canvasDelegate.mBitmap.getConfig() == Config.RGB_565;
-    }
-
-    @LayoutlibDelegate
-    public static void nSetHighContrastText(long nativeCanvas, boolean highContrastText){}
-
-    @LayoutlibDelegate
-    public static int nGetWidth(long nativeCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.mBitmap.getImage().getWidth();
-    }
-
-    @LayoutlibDelegate
-    public static int nGetHeight(long nativeCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.mBitmap.getImage().getHeight();
-    }
-
-    @LayoutlibDelegate
-    public static int nSave(long nativeCanvas, int saveFlags) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.save(saveFlags);
-    }
-
-    @LayoutlibDelegate
-    public static int nSaveLayer(long nativeCanvas, float l,
-                                               float t, float r, float b,
-                                               long paint, int layerFlags) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(paint);
-        if (paintDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.saveLayer(new RectF(l, t, r, b),
-                paintDelegate, layerFlags);
-    }
-
-    @LayoutlibDelegate
-    public static int nSaveLayerAlpha(long nativeCanvas, float l,
-                                                    float t, float r, float b,
-                                                    int alpha, int layerFlags) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.saveLayerAlpha(new RectF(l, t, r, b), alpha, layerFlags);
-    }
-
-    @LayoutlibDelegate
-    public static boolean nRestore(long nativeCanvas) {
-        // FIXME: implement throwOnUnderflow.
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        canvasDelegate.restore();
-        return true;
-    }
-
-    @LayoutlibDelegate
-    public static void nRestoreToCount(long nativeCanvas, int saveCount) {
-        // FIXME: implement throwOnUnderflow.
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.restoreTo(saveCount);
-    }
-
-    @LayoutlibDelegate
-    public static int nGetSaveCount(long nativeCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.getSnapshot().size();
-    }
-
-    @LayoutlibDelegate
-   public static void nTranslate(long nativeCanvas, float dx, float dy) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.getSnapshot().translate(dx, dy);
-    }
-
-    @LayoutlibDelegate
-       public static void nScale(long nativeCanvas, float sx, float sy) {
-            // get the delegate from the native int.
-            Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-            if (canvasDelegate == null) {
-                return;
-            }
-
-            canvasDelegate.getSnapshot().scale(sx, sy);
-        }
-
-    @LayoutlibDelegate
-    public static void nRotate(long nativeCanvas, float degrees) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.getSnapshot().rotate(Math.toRadians(degrees));
-    }
-
-    @LayoutlibDelegate
-   public static void nSkew(long nativeCanvas, float kx, float ky) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the current top graphics2D object.
-        GcSnapshot g = canvasDelegate.getSnapshot();
-
-        // get its current matrix
-        AffineTransform currentTx = g.getTransform();
-        // get the AffineTransform for the given skew.
-        float[] mtx = Matrix_Delegate.getSkew(kx, ky);
-        AffineTransform matrixTx = Matrix_Delegate.getAffineTransform(mtx);
-
-        // combine them so that the given matrix is applied after.
-        currentTx.preConcatenate(matrixTx);
-
-        // give it to the graphics2D as a new matrix replacing all previous transform
-        g.setTransform(currentTx);
-    }
-
-    @LayoutlibDelegate
-    public static void nConcat(long nCanvas, long nMatrix) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        // get the current top graphics2D object.
-        GcSnapshot snapshot = canvasDelegate.getSnapshot();
-
-        // get its current matrix
-        AffineTransform currentTx = snapshot.getTransform();
-        // get the AffineTransform of the given matrix
-        AffineTransform matrixTx = matrixDelegate.getAffineTransform();
-
-        // combine them so that the given matrix is applied after.
-        currentTx.concatenate(matrixTx);
-
-        // give it to the graphics2D as a new matrix replacing all previous transform
-        snapshot.setTransform(currentTx);
-    }
-
-    @LayoutlibDelegate
-    public static void nSetMatrix(long nCanvas, long nMatrix) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        // get the current top graphics2D object.
-        GcSnapshot snapshot = canvasDelegate.getSnapshot();
-
-        // get the AffineTransform of the given matrix
-        AffineTransform matrixTx = matrixDelegate.getAffineTransform();
-
-        // give it to the graphics2D as a new matrix replacing all previous transform
-        snapshot.setTransform(matrixTx);
-
-        if (matrixDelegate.hasPerspective()) {
-            assert false;
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
-                    "android.graphics.Canvas#setMatrix(android.graphics.Matrix) only " +
-                    "supports affine transformations.", null, null /*data*/);
-        }
-    }
-
-    @LayoutlibDelegate
-    public static boolean nClipRect(long nCanvas,
-                                                  float left, float top,
-                                                  float right, float bottom,
-                                                  int regionOp) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        return canvasDelegate.clipRect(left, top, right, bottom, regionOp);
-    }
-
-    @LayoutlibDelegate
-    public static boolean nClipPath(long nativeCanvas,
-                                                  long nativePath,
-                                                  int regionOp) {
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return true;
-        }
-
-        Path_Delegate pathDelegate = Path_Delegate.getDelegate(nativePath);
-        if (pathDelegate == null) {
-            return true;
-        }
-
-        return canvasDelegate.mSnapshot.clip(pathDelegate.getJavaShape(), regionOp);
-    }
-
-    @LayoutlibDelegate
-    public static void nSetDrawFilter(long nativeCanvas, long nativeFilter) {
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.mDrawFilter = DrawFilter_Delegate.getDelegate(nativeFilter);
-
-        if (canvasDelegate.mDrawFilter != null && !canvasDelegate.mDrawFilter.isSupported()) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_DRAWFILTER,
-                    canvasDelegate.mDrawFilter.getSupportMessage(), null, null /*data*/);
-        }
-    }
-
-    @LayoutlibDelegate
-    public static boolean nGetClipBounds(long nativeCanvas,
-                                                       Rect bounds) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        Rectangle rect = canvasDelegate.getSnapshot().getClip().getBounds();
-        if (rect != null && !rect.isEmpty()) {
-            bounds.left = rect.x;
-            bounds.top = rect.y;
-            bounds.right = rect.x + rect.width;
-            bounds.bottom = rect.y + rect.height;
-            return true;
-        }
-
-        return false;
-    }
-
-    @LayoutlibDelegate
-    public static void nGetMatrix(long canvas, long matrix) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        AffineTransform transform = canvasDelegate.getSnapshot().getTransform();
-        matrixDelegate.set(Matrix_Delegate.makeValues(transform));
-    }
-
-    @LayoutlibDelegate
-    public static boolean nQuickReject(long nativeCanvas, long path) {
-        // FIXME properly implement quickReject
-        return false;
-    }
-
-    @LayoutlibDelegate
-    public static boolean nQuickReject(long nativeCanvas,
-                                                     float left, float top,
-                                                     float right, float bottom) {
-        // FIXME properly implement quickReject
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetNativeFinalizer() {
-        synchronized (Canvas_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(nativePtr -> {
-                    Canvas_Delegate delegate = Canvas_Delegate.getDelegate(nativePtr);
-                    if (delegate != null) {
-                        delegate.dispose();
-                    }
-                    sManager.removeJavaReferenceFor(nativePtr);
-                });
-            }
-        }
-        return sFinalizer;
-    }
-
-    private Canvas_Delegate(Bitmap_Delegate bitmap) {
-        super(bitmap);
-    }
-
-    private Canvas_Delegate() {
-        super();
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
deleted file mode 100644
index cb013b6..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Graphics2D;
-
-/**
- * Delegate implementing the native methods of android.graphics.ColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of ColorFilter have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ColorFilter class.
- *
- * This also serve as a base class for all ColorFilter delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class ColorFilter_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<ColorFilter_Delegate> sManager =
-            new DelegateManager<ColorFilter_Delegate>(ColorFilter_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static ColorFilter_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public abstract String getSupportMessage();
-
-    public boolean isSupported() {
-        return false;
-    }
-
-    public void applyFilter(Graphics2D g, int width, int height) {
-        // This should never be called directly. If supported, the sub class should override this.
-        assert false;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nSafeUnref(long native_instance) {
-        sManager.removeJavaReferenceFor(native_instance);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
deleted file mode 100644
index 6739484..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.ColorMatrixColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of ColorMatrixColorFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ColorMatrixColorFilter class.
- *
- * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link ColorFilter_Delegate}.
- *
- * @see ColorFilter_Delegate
- *
- */
-public class ColorMatrixColorFilter_Delegate extends ColorFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public String getSupportMessage() {
-        return "ColorMatrix Color Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeColorMatrixFilter(float[] array) {
-        ColorMatrixColorFilter_Delegate newDelegate = new ColorMatrixColorFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java
deleted file mode 100644
index bc3df7d..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.ComposePathEffect
- *
- * Through the layoutlib_create tool, the original native methods of ComposePathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ComposePathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class ComposePathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Compose Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long outerpe, long innerpe) {
-        ComposePathEffect_Delegate newDelegate = new ComposePathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
deleted file mode 100644
index ab37968..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Paint;
-
-/**
- * Delegate implementing the native methods of android.graphics.ComposeShader
- *
- * Through the layoutlib_create tool, the original native methods of ComposeShader have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ComposeShader class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class ComposeShader_Delegate extends Shader_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Paint getJavaPaint() {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Compose Shaders are not supported in Layout Preview mode.";
-    }
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long nativeMatrix, long native_shaderA,
-            long native_shaderB, int native_mode) {
-        // FIXME not supported yet.
-        ComposeShader_Delegate newDelegate = new ComposeShader_Delegate(nativeMatrix);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-
-    // ---- Private delegate/helper methods ----
-
-    private ComposeShader_Delegate(long nativeMatrix) {
-        super(nativeMatrix);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java
deleted file mode 100644
index 73745c3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.CornerPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of CornerPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original CornerPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class CornerPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Corner Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(float radius) {
-        CornerPathEffect_Delegate newDelegate = new CornerPathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
deleted file mode 100644
index 881afde..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.BasicStroke;
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.DashPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of DashPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original DashPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
- * {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public final class DashPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    private final float[] mIntervals;
-    private final float mPhase;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        return new BasicStroke(
-                paint.getStrokeWidth(),
-                paint.getJavaCap(),
-                paint.getJavaJoin(),
-                paint.getJavaStrokeMiter(),
-                mIntervals,
-                mPhase);
-    }
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        // no message since isSupported returns true;
-        return null;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(float intervals[], float phase) {
-        DashPathEffect_Delegate newDelegate = new DashPathEffect_Delegate(intervals, phase);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private DashPathEffect_Delegate(float intervals[], float phase) {
-        mIntervals = new float[intervals.length];
-        System.arraycopy(intervals, 0, mIntervals, 0, intervals.length);
-        mPhase = phase;
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java
deleted file mode 100644
index 46109f3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.DiscretePathEffect
- *
- * Through the layoutlib_create tool, the original native methods of DiscretePathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original DiscretePathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class DiscretePathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Discrete Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(float length, float deviation) {
-        DiscretePathEffect_Delegate newDelegate = new DiscretePathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java
deleted file mode 100644
index 2e10740..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.DrawFilter
- *
- * Through the layoutlib_create tool, the original native methods of DrawFilter have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original DrawFilter class.
- *
- * This also serve as a base class for all DrawFilter delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class DrawFilter_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<DrawFilter_Delegate> sManager =
-            new DelegateManager<DrawFilter_Delegate>(DrawFilter_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static DrawFilter_Delegate getDelegate(long nativeDrawFilter) {
-        return sManager.getDelegate(nativeDrawFilter);
-    }
-
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(long nativeDrawFilter) {
-        sManager.removeJavaReferenceFor(nativeDrawFilter);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java
deleted file mode 100644
index e5040cc..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.EmbossMaskFilter
- *
- * Through the layoutlib_create tool, the original native methods of EmbossMaskFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original EmbossMaskFilter class.
- *
- * Because this extends {@link MaskFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link MaskFilter_Delegate}.
- *
- * @see MaskFilter_Delegate
- *
- */
-public class EmbossMaskFilter_Delegate extends MaskFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Emboss Mask Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeConstructor(float[] direction, float ambient,
-            float specular, float blurRadius) {
-        EmbossMaskFilter_Delegate newDelegate = new EmbossMaskFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
deleted file mode 100644
index 78b6f71..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.AssetRepository;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.res.AssetManager;
-import android.content.res.BridgeAssetManager;
-import android.graphics.fonts.FontVariationAxis;
-import android.text.FontConfig;
-
-import java.awt.Font;
-import java.awt.FontFormatException;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.Set;
-
-import static android.graphics.Typeface.RESOLVE_BY_FONT_TABLE;
-import static android.graphics.Typeface_Delegate.SYSTEM_FONTS;
-
-/**
- * Delegate implementing the native methods of android.graphics.FontFamily
- *
- * Through the layoutlib_create tool, the original native methods of FontFamily have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original FontFamily class.
- *
- * @see DelegateManager
- */
-public class FontFamily_Delegate {
-
-    public static final int DEFAULT_FONT_WEIGHT = 400;
-    public static final int BOLD_FONT_WEIGHT_DELTA = 300;
-    public static final int BOLD_FONT_WEIGHT = 700;
-
-    private static final String FONT_SUFFIX_ITALIC = "Italic.ttf";
-    private static final String FN_ALL_FONTS_LIST = "fontsInSdk.txt";
-    private static final String EXTENSION_OTF = ".otf";
-
-    private static final int CACHE_SIZE = 10;
-    // The cache has a drawback that if the font file changed after the font object was created,
-    // we will not update it.
-    private static final Map<String, FontInfo> sCache =
-            new LinkedHashMap<String, FontInfo>(CACHE_SIZE) {
-        @Override
-        protected boolean removeEldestEntry(Map.Entry<String, FontInfo> eldest) {
-            return size() > CACHE_SIZE;
-        }
-
-        @Override
-        public FontInfo put(String key, FontInfo value) {
-            // renew this entry.
-            FontInfo removed = remove(key);
-            super.put(key, value);
-            return removed;
-        }
-    };
-
-    /**
-     * A class associating {@link Font} with its metadata.
-     */
-    private static final class FontInfo {
-        @Nullable
-        Font mFont;
-        int mWeight;
-        boolean mIsItalic;
-    }
-
-    // ---- delegate manager ----
-    private static final DelegateManager<FontFamily_Delegate> sManager =
-            new DelegateManager<FontFamily_Delegate>(FontFamily_Delegate.class);
-
-    // ---- delegate helper data ----
-    private static String sFontLocation;
-    private static final List<FontFamily_Delegate> sPostInitDelegate = new
-            ArrayList<FontFamily_Delegate>();
-    private static Set<String> SDK_FONTS;
-
-
-    // ---- delegate data ----
-    private List<FontInfo> mFonts = new ArrayList<FontInfo>();
-
-    /**
-     * The variant of the Font Family - compact or elegant.
-     * <p/>
-     * 0 is unspecified, 1 is compact and 2 is elegant. This needs to be kept in sync with values in
-     * android.graphics.FontFamily
-     *
-     * @see Paint#setElegantTextHeight(boolean)
-     */
-    private FontVariant mVariant;
-    // List of runnables to process fonts after sFontLoader is initialized.
-    private List<Runnable> mPostInitRunnables = new ArrayList<Runnable>();
-    /** @see #isValid() */
-    private boolean mValid = false;
-
-
-    // ---- Public helper class ----
-
-    public enum FontVariant {
-        // The order needs to be kept in sync with android.graphics.FontFamily.
-        NONE, COMPACT, ELEGANT
-    }
-
-    // ---- Public Helper methods ----
-
-    public static FontFamily_Delegate getDelegate(long nativeFontFamily) {
-        return sManager.getDelegate(nativeFontFamily);
-    }
-
-    public static synchronized void setFontLocation(String fontLocation) {
-        sFontLocation = fontLocation;
-        // init list of bundled fonts.
-        File allFonts = new File(fontLocation, FN_ALL_FONTS_LIST);
-        // Current number of fonts is 103. Use the next round number to leave scope for more fonts
-        // in the future.
-        Set<String> allFontsList = new HashSet<String>(128);
-        Scanner scanner = null;
-        try {
-            scanner = new Scanner(allFonts);
-            while (scanner.hasNext()) {
-                String name = scanner.next();
-                // Skip font configuration files.
-                if (!name.endsWith(".xml")) {
-                    allFontsList.add(name);
-                }
-            }
-        } catch (FileNotFoundException e) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Unable to load the list of fonts. Try re-installing the SDK Platform from the SDK Manager.",
-                    e, null);
-        } finally {
-            if (scanner != null) {
-                scanner.close();
-            }
-        }
-        SDK_FONTS = Collections.unmodifiableSet(allFontsList);
-        for (FontFamily_Delegate fontFamily : sPostInitDelegate) {
-            fontFamily.init();
-        }
-        sPostInitDelegate.clear();
-    }
-
-    @Nullable
-    public Font getFont(int desiredWeight, boolean isItalic) {
-        FontInfo desiredStyle = new FontInfo();
-        desiredStyle.mWeight = desiredWeight;
-        desiredStyle.mIsItalic = isItalic;
-        FontInfo bestFont = null;
-        int bestMatch = Integer.MAX_VALUE;
-        //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
-        for (int i = 0, n = mFonts.size(); i < n; i++) {
-            FontInfo font = mFonts.get(i);
-            int match = computeMatch(font, desiredStyle);
-            if (match < bestMatch) {
-                bestMatch = match;
-                bestFont = font;
-            }
-        }
-        if (bestFont == null) {
-            return null;
-        }
-        if (bestMatch == 0) {
-            return bestFont.mFont;
-        }
-        // Derive the font as required and add it to the list of Fonts.
-        deriveFont(bestFont, desiredStyle);
-        addFont(desiredStyle);
-        return desiredStyle.mFont;
-    }
-
-    public FontVariant getVariant() {
-        return mVariant;
-    }
-
-    /**
-     * Returns if the FontFamily should contain any fonts. If this returns true and
-     * {@link #getFont(int, boolean)} returns an empty list, it means that an error occurred while
-     * loading the fonts. However, some fonts are deliberately skipped, for example they are not
-     * bundled with the SDK. In such a case, this method returns false.
-     */
-    public boolean isValid() {
-        return mValid;
-    }
-
-    private static Font loadFont(String path) {
-        if (path.startsWith(SYSTEM_FONTS) ) {
-            String relativePath = path.substring(SYSTEM_FONTS.length());
-            File f = new File(sFontLocation, relativePath);
-
-            try {
-                return Font.createFont(Font.TRUETYPE_FONT, f);
-            } catch (Exception e) {
-                if (path.endsWith(EXTENSION_OTF) && e instanceof FontFormatException) {
-                    // If we aren't able to load an Open Type font, don't log a warning just yet.
-                    // We wait for a case where font is being used. Only then we try to log the
-                    // warning.
-                    return null;
-                }
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
-                        String.format("Unable to load font %1$s", relativePath),
-                        e, null);
-            }
-        } else {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                    "Only platform fonts located in " + SYSTEM_FONTS + "can be loaded.",
-                    null, null);
-        }
-
-        return null;
-    }
-
-    @Nullable
-    /*package*/ static String getFontLocation() {
-        return sFontLocation;
-    }
-
-    // ---- delegate methods ----
-    @LayoutlibDelegate
-    /*package*/ static boolean addFont(FontFamily thisFontFamily, String path, int ttcIndex,
-            FontVariationAxis[] axes, int weight, int italic) {
-        if (thisFontFamily.mBuilderPtr == 0) {
-            assert false : "Unable to call addFont after freezing.";
-            return false;
-        }
-        final FontFamily_Delegate delegate = getDelegate(thisFontFamily.mBuilderPtr);
-        return delegate != null && delegate.addFont(path, ttcIndex, weight, italic);
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nInitBuilder(String lang, int variant) {
-        // TODO: support lang. This is required for japanese locale.
-        FontFamily_Delegate delegate = new FontFamily_Delegate();
-        // variant can be 0, 1 or 2.
-        assert variant < 3;
-        delegate.mVariant = FontVariant.values()[variant];
-        if (sFontLocation != null) {
-            delegate.init();
-        } else {
-            sPostInitDelegate.add(delegate);
-        }
-        return sManager.addNewDelegate(delegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateFamily(long builderPtr) {
-        return builderPtr;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nUnrefFamily(long nativePtr) {
-        // Removing the java reference for the object doesn't mean that it's freed for garbage
-        // collection. Typeface_Delegate may still hold a reference for it.
-        sManager.removeJavaReferenceFor(nativePtr);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex,
-            int weight, int isItalic) {
-        assert false : "The only client of this method has been overridden.";
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nAddFontWeightStyle(long builderPtr, ByteBuffer font,
-            int ttcIndex, int weight, int isItalic) {
-        assert false : "The only client of this method has been overridden.";
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddAxisValue(long builderPtr, int tag, float value) {
-        assert false : "The only client of this method has been overridden.";
-    }
-
-    static boolean addFont(long builderPtr, final String path, final int weight,
-            final boolean isItalic) {
-        final FontFamily_Delegate delegate = getDelegate(builderPtr);
-        int italic = isItalic ? 1 : 0;
-        if (delegate != null) {
-            if (sFontLocation == null) {
-                delegate.mPostInitRunnables.add(() -> delegate.addFont(path, weight, italic));
-                return true;
-            }
-            return delegate.addFont(path, weight, italic);
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nAddFontFromAssetManager(long builderPtr, AssetManager mgr, String path,
-            int cookie, boolean isAsset, int ttcIndex, int weight, int isItalic) {
-        FontFamily_Delegate ffd = sManager.getDelegate(builderPtr);
-        if (ffd == null) {
-            return false;
-        }
-        ffd.mValid = true;
-        if (mgr == null) {
-            return false;
-        }
-        if (mgr instanceof BridgeAssetManager) {
-            InputStream fontStream = null;
-            try {
-                AssetRepository assetRepository = ((BridgeAssetManager) mgr).getAssetRepository();
-                if (assetRepository == null) {
-                    Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Asset not found: " + path,
-                            null);
-                    return false;
-                }
-                if (!assetRepository.isSupported()) {
-                    // Don't log any warnings on unsupported IDEs.
-                    return false;
-                }
-                // Check cache
-                FontInfo fontInfo = sCache.get(path);
-                if (fontInfo != null) {
-                    // renew the font's lease.
-                    sCache.put(path, fontInfo);
-                    ffd.addFont(fontInfo);
-                    return true;
-                }
-                fontStream = isAsset ?
-                        assetRepository.openAsset(path, AssetManager.ACCESS_STREAMING) :
-                        assetRepository.openNonAsset(cookie, path, AssetManager.ACCESS_STREAMING);
-                if (fontStream == null) {
-                    Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Asset not found: " + path,
-                            path);
-                    return false;
-                }
-                Font font = Font.createFont(Font.TRUETYPE_FONT, fontStream);
-                fontInfo = new FontInfo();
-                fontInfo.mFont = font;
-                if (weight == RESOLVE_BY_FONT_TABLE) {
-                    fontInfo.mWeight = font.isBold() ? BOLD_FONT_WEIGHT : DEFAULT_FONT_WEIGHT;
-                } else {
-                    fontInfo.mWeight = weight;
-                }
-                fontInfo.mIsItalic = isItalic == RESOLVE_BY_FONT_TABLE ? font.isItalic() :
-                        isItalic == 1;
-                ffd.addFont(fontInfo);
-                return true;
-            } catch (IOException e) {
-                Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Unable to load font " + path, e,
-                        path);
-            } catch (FontFormatException e) {
-                if (path.endsWith(EXTENSION_OTF)) {
-                    // otf fonts are not supported on the user's config (JRE version + OS)
-                    Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                            "OpenType fonts are not supported yet: " + path, null, path);
-                } else {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                            "Unable to load font " + path, e, path);
-                }
-            } finally {
-                if (fontStream != null) {
-                    try {
-                        fontStream.close();
-                    } catch (IOException ignored) {
-                    }
-                }
-            }
-            return false;
-        }
-        // This should never happen. AssetManager is a final class (from user's perspective), and
-        // we've replaced every creation of AssetManager with our implementation. We create an
-        // exception and log it, but continue with rest of the rendering, without loading this font.
-        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                "You have found a bug in the rendering library. Please file a bug at b.android.com.",
-                new RuntimeException("Asset Manager is not an instance of BridgeAssetManager"),
-                null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAbort(long builderPtr) {
-        sManager.removeJavaReferenceFor(builderPtr);
-    }
-
-    // ---- private helper methods ----
-
-    private void init() {
-        for (Runnable postInitRunnable : mPostInitRunnables) {
-            postInitRunnable.run();
-        }
-        mPostInitRunnables = null;
-    }
-
-    private boolean addFont(final String path, int ttcIndex, int weight, int italic) {
-        // FIXME: support ttc fonts. Hack JRE??
-        if (sFontLocation == null) {
-            mPostInitRunnables.add(() -> addFont(path, weight, italic));
-            return true;
-        }
-        return addFont(path, weight, italic);
-    }
-
-     private boolean addFont(@NonNull String path) {
-         return addFont(path, DEFAULT_FONT_WEIGHT, path.endsWith(FONT_SUFFIX_ITALIC) ? 1 : RESOLVE_BY_FONT_TABLE);
-     }
-
-    private boolean addFont(@NonNull String path, int weight, int italic) {
-        if (path.startsWith(SYSTEM_FONTS) &&
-                !SDK_FONTS.contains(path.substring(SYSTEM_FONTS.length()))) {
-            return mValid = false;
-        }
-        // Set valid to true, even if the font fails to load.
-        mValid = true;
-        Font font = loadFont(path);
-        if (font == null) {
-            return false;
-        }
-        FontInfo fontInfo = new FontInfo();
-        fontInfo.mFont = font;
-        fontInfo.mWeight = weight;
-        fontInfo.mIsItalic = italic == RESOLVE_BY_FONT_TABLE ? font.isItalic() : italic == 1;
-        addFont(fontInfo);
-        return true;
-    }
-
-    private boolean addFont(@NonNull FontInfo fontInfo) {
-        int weight = fontInfo.mWeight;
-        boolean isItalic = fontInfo.mIsItalic;
-        // The list is usually just two fonts big. So iterating over all isn't as bad as it looks.
-        // It's biggest for roboto where the size is 12.
-        //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
-        for (int i = 0, n = mFonts.size(); i < n; i++) {
-            FontInfo font = mFonts.get(i);
-            if (font.mWeight == weight && font.mIsItalic == isItalic) {
-                return false;
-            }
-        }
-        mFonts.add(fontInfo);
-        return true;
-    }
-
-    /**
-     * Compute matching metric between two styles - 0 is an exact match.
-     */
-    private static int computeMatch(@NonNull FontInfo font1, @NonNull FontInfo font2) {
-        int score = Math.abs(font1.mWeight - font2.mWeight);
-        if (font1.mIsItalic != font2.mIsItalic) {
-            score += 200;
-        }
-        return score;
-    }
-
-    /**
-     * Try to derive a font from {@code srcFont} for the style in {@code outFont}.
-     * <p/>
-     * {@code outFont} is updated to reflect the style of the derived font.
-     * @param srcFont the source font
-     * @param outFont contains the desired font style. Updated to contain the derived font and
-     *                its style
-     * @return outFont
-     */
-    @NonNull
-    private FontInfo deriveFont(@NonNull FontInfo srcFont, @NonNull FontInfo outFont) {
-        int desiredWeight = outFont.mWeight;
-        int srcWeight = srcFont.mWeight;
-        assert srcFont.mFont != null;
-        Font derivedFont = srcFont.mFont;
-        // Embolden the font if required.
-        if (desiredWeight >= BOLD_FONT_WEIGHT && desiredWeight - srcWeight > BOLD_FONT_WEIGHT_DELTA / 2) {
-            derivedFont = derivedFont.deriveFont(Font.BOLD);
-            srcWeight += BOLD_FONT_WEIGHT_DELTA;
-        }
-        // Italicize the font if required.
-        if (outFont.mIsItalic && !srcFont.mIsItalic) {
-            derivedFont = derivedFont.deriveFont(Font.ITALIC);
-        } else if (outFont.mIsItalic != srcFont.mIsItalic) {
-            // The desired font is plain, but the src font is italics. We can't convert it back. So
-            // we update the value to reflect the true style of the font we're deriving.
-            outFont.mIsItalic = srcFont.mIsItalic;
-        }
-        outFont.mFont = derivedFont;
-        outFont.mWeight = srcWeight;
-        // No need to update mIsItalics, as it's already been handled above.
-        return outFont;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
deleted file mode 100644
index 64410e4..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import android.graphics.Shader.TileMode;
-
-/**
- * Base class for true Gradient shader delegate.
- */
-public abstract class Gradient_Delegate extends Shader_Delegate {
-
-    protected final int[] mColors;
-    protected final float[] mPositions;
-
-    @Override
-    public boolean isSupported() {
-        // all gradient shaders are supported.
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        // all gradient shaders are supported, no need for a gradient support
-        return null;
-    }
-
-    /**
-     * Creates the base shader and do some basic test on the parameters.
-     *
-     * @param nativeMatrix reference to the shader's native transformation matrix
-     * @param colors The colors to be distributed along the gradient line
-     * @param positions May be null. The relative positions [0..1] of each
-     *            corresponding color in the colors array. If this is null, the
-     *            the colors are distributed evenly along the gradient line.
-     */
-    protected Gradient_Delegate(long nativeMatrix, int colors[], float positions[]) {
-        super(nativeMatrix);
-        assert colors.length >= 2 : "needs >= 2 number of colors";
-
-        if (positions == null) {
-            float spacing = 1.f / (colors.length - 1);
-            positions = new float[colors.length];
-            positions[0] = 0.f;
-            positions[colors.length - 1] = 1.f;
-            for (int i = 1; i < colors.length - 1; i++) {
-                positions[i] = spacing * i;
-            }
-        } else {
-            assert colors.length == positions.length :
-                    "color and position " + "arrays must be of equal length";
-        }
-
-        mColors = colors;
-        mPositions = positions;
-    }
-
-    /**
-     * Base class for (Java) Gradient Paints. This handles computing the gradient colors based
-     * on the color and position lists, as well as the {@link TileMode}
-     *
-     */
-    protected abstract static class GradientPaint implements java.awt.Paint {
-        private final static int GRADIENT_SIZE = 100;
-
-        private final int[] mColors;
-        private final float[] mPositions;
-        private final TileMode mTileMode;
-        private int[] mGradient;
-
-        protected GradientPaint(int[] colors, float[] positions, TileMode tileMode) {
-            mColors = colors;
-            mPositions = positions;
-            mTileMode = tileMode;
-        }
-
-        @Override
-        public int getTransparency() {
-            return java.awt.Paint.TRANSLUCENT;
-        }
-
-        /**
-         * Pre-computes the colors for the gradient. This must be called once before any call
-         * to {@link #getGradientColor(float)}
-         */
-        protected void precomputeGradientColors() {
-            if (mGradient == null) {
-                // actually create an array with an extra size, so that we can really go
-                // from 0 to SIZE (100%), or currentPos in the loop below will never equal 1.0
-                mGradient = new int[GRADIENT_SIZE+1];
-
-                int prevPos = 0;
-                int nextPos = 1;
-                for (int i  = 0 ; i <= GRADIENT_SIZE ; i++) {
-                    // compute current position
-                    float currentPos = (float)i/GRADIENT_SIZE;
-                    while (currentPos > mPositions[nextPos]) {
-                        prevPos = nextPos++;
-                    }
-
-                    float percent = (currentPos - mPositions[prevPos]) /
-                            (mPositions[nextPos] - mPositions[prevPos]);
-
-                    mGradient[i] = computeColor(mColors[prevPos], mColors[nextPos], percent);
-                }
-            }
-        }
-
-        /**
-         * Returns the color based on the position in the gradient.
-         * <var>pos</var> can be anything, even &lt; 0 or &gt; > 1, as the gradient
-         * will use {@link TileMode} value to convert it into a [0,1] value.
-         */
-        protected int getGradientColor(float pos) {
-            if (pos < 0.f) {
-                if (mTileMode != null) {
-                    switch (mTileMode) {
-                        case CLAMP:
-                            pos = 0.f;
-                            break;
-                        case REPEAT:
-                            // remove the integer part to stay in the [0,1] range.
-                            // we also need to invert the value from [-1,0] to [0, 1]
-                            pos = pos - (float)Math.floor(pos);
-                            break;
-                        case MIRROR:
-                            // this is the same as the positive side, just make the value positive
-                            // first.
-                            pos = Math.abs(pos);
-
-                            // get the integer and the decimal part
-                            int intPart = (int)Math.floor(pos);
-                            pos = pos - intPart;
-                            // 0 -> 1 : normal order
-                            // 1 -> 2: mirrored
-                            // etc..
-                            // this means if the intpart is odd we invert
-                            if ((intPart % 2) == 1) {
-                                pos = 1.f - pos;
-                            }
-                            break;
-                    }
-                } else {
-                    pos = 0.0f;
-                }
-            } else if (pos > 1f) {
-                if (mTileMode != null) {
-                    switch (mTileMode) {
-                        case CLAMP:
-                            pos = 1.f;
-                            break;
-                        case REPEAT:
-                            // remove the integer part to stay in the [0,1] range
-                            pos = pos - (float)Math.floor(pos);
-                            break;
-                        case MIRROR:
-                            // get the integer and the decimal part
-                            int intPart = (int)Math.floor(pos);
-                            pos = pos - intPart;
-                            // 0 -> 1 : normal order
-                            // 1 -> 2: mirrored
-                            // etc..
-                            // this means if the intpart is odd we invert
-                            if ((intPart % 2) == 1) {
-                                pos = 1.f - pos;
-                            }
-                            break;
-                    }
-                } else {
-                    pos = 1.0f;
-                }
-            }
-
-            int index = (int)((pos * GRADIENT_SIZE) + .5);
-
-            return mGradient[index];
-        }
-
-        /**
-         * Returns the color between c1, and c2, based on the percent of the distance
-         * between c1 and c2.
-         */
-        private int computeColor(int c1, int c2, float percent) {
-            int a = computeChannel((c1 >> 24) & 0xFF, (c2 >> 24) & 0xFF, percent);
-            int r = computeChannel((c1 >> 16) & 0xFF, (c2 >> 16) & 0xFF, percent);
-            int g = computeChannel((c1 >>  8) & 0xFF, (c2 >>  8) & 0xFF, percent);
-            int b = computeChannel((c1      ) & 0xFF, (c2      ) & 0xFF, percent);
-            return a << 24 | r << 16 | g << 8 | b;
-        }
-
-        /**
-         * Returns the channel value between 2 values based on the percent of the distance between
-         * the 2 values..
-         */
-        private int computeChannel(int c1, int c2, float percent) {
-            return c1 + (int)((percent * (c2-c1)) + .5);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
deleted file mode 100644
index 0dd9703..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.LightingColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of LightingColorFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original LightingColorFilter class.
- *
- * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link ColorFilter_Delegate}.
- *
- * @see ColorFilter_Delegate
- *
- */
-public class LightingColorFilter_Delegate extends ColorFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public String getSupportMessage() {
-        return "Lighting Color Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long native_CreateLightingFilter(int mul, int add) {
-        LightingColorFilter_Delegate newDelegate = new LightingColorFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
deleted file mode 100644
index cd4393a..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-import java.awt.image.ColorModel;
-
-/**
- * Delegate implementing the native methods of android.graphics.LinearGradient
- *
- * Through the layoutlib_create tool, the original native methods of LinearGradient have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original LinearGradient class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public final class LinearGradient_Delegate extends Gradient_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate1(LinearGradient thisGradient, long matrix,
-            float x0, float y0, float x1, float y1,
-            int colors[], float positions[], int tileMode) {
-        LinearGradient_Delegate newDelegate = new LinearGradient_Delegate(matrix, x0, y0,
-                x1, y1, colors, positions, Shader_Delegate.getTileMode(tileMode));
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate2(LinearGradient thisGradient, long matrix,
-            float x0, float y0, float x1, float y1,
-            int color0, int color1, int tileMode) {
-        return nativeCreate1(thisGradient, matrix, x0, y0, x1, y1, new int[] { color0, color1},
-                null /*positions*/, tileMode);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * Create a shader that draws a linear gradient along a line.
-     *
-     * @param nativeMatrix reference to the shader's native transformation matrix
-     * @param x0 The x-coordinate for the start of the gradient line
-     * @param y0 The y-coordinate for the start of the gradient line
-     * @param x1 The x-coordinate for the end of the gradient line
-     * @param y1 The y-coordinate for the end of the gradient line
-     * @param colors The colors to be distributed along the gradient line
-     * @param positions May be null. The relative positions [0..1] of each
-     *            corresponding color in the colors array. If this is null, the
-     *            the colors are distributed evenly along the gradient line.
-     * @param tile The Shader tiling mode
-     */
-    private LinearGradient_Delegate(long nativeMatrix, float x0, float y0, float x1,
-            float y1, int colors[], float positions[], TileMode tile) {
-        super(nativeMatrix, colors, positions);
-        mJavaPaint = new LinearGradientPaint(x0, y0, x1, y1, mColors, mPositions, tile);
-    }
-
-    // ---- Custom Java Paint ----
-    /**
-     * Linear Gradient (Java) Paint able to handle more than 2 points, as
-     * {@link java.awt.GradientPaint} only supports 2 points and does not support Android's tile
-     * modes.
-     */
-    private class LinearGradientPaint extends GradientPaint {
-
-        private final float mX0;
-        private final float mY0;
-        private final float mDx;
-        private final float mDy;
-        private final float mDSize2;
-
-        public LinearGradientPaint(float x0, float y0, float x1, float y1, int colors[],
-                float positions[], TileMode tile) {
-            super(colors, positions, tile);
-            mX0 = x0;
-            mY0 = y0;
-            mDx = x1 - x0;
-            mDy = y1 - y0;
-            mDSize2 = mDx * mDx + mDy * mDy;
-        }
-
-        @Override
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel      colorModel,
-                java.awt.Rectangle             deviceBounds,
-                java.awt.geom.Rectangle2D      userBounds,
-                java.awt.geom.AffineTransform  xform,
-                java.awt.RenderingHints        hints) {
-            precomputeGradientColors();
-
-            java.awt.geom.AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in LinearGradient", e, null /*data*/);
-                canvasMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in LinearGradient", e, null /*data*/);
-                localMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            return new LinearGradientPaintContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class LinearGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.geom.AffineTransform mCanvasMatrix;
-            private final java.awt.geom.AffineTransform mLocalMatrix;
-            private final java.awt.image.ColorModel mColorModel;
-
-            private LinearGradientPaintContext(
-                    java.awt.geom.AffineTransform canvasMatrix,
-                    java.awt.geom.AffineTransform localMatrix,
-                    java.awt.image.ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel.hasAlpha() ? colorModel : ColorModel.getRGBdefault();
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
-                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
-                    mColorModel.isAlphaPremultiplied(), null);
-
-                int[] data = new int[w*h];
-
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix.
-                        pt1[0] = pt2[0];
-                        pt1[1] = pt2[1];
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        data[index++] = getColor(pt2[0], pt2[1]);
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-        }
-
-        /**
-         * Returns a color for an arbitrary point.
-         */
-        private int getColor(float x, float y) {
-            float pos;
-            if (mDx == 0) {
-                pos = (y - mY0) / mDy;
-            } else if (mDy == 0) {
-                pos = (x - mX0) / mDx;
-            } else {
-                // find the x position on the gradient vector.
-                float _x = (mDx*mDy*(y-mY0) + mDy*mDy*mX0 + mDx*mDx*x) / mDSize2;
-                // from it get the position relative to the vector
-                pos = (_x - mX0) / mDx;
-            }
-
-            return getGradientColor(pos);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java
deleted file mode 100644
index e726c59..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.MaskFilter
- *
- * Through the layoutlib_create tool, the original native methods of MaskFilter have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original MaskFilter class.
- *
- * This also serve as a base class for all MaskFilter delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class MaskFilter_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<MaskFilter_Delegate> sManager =
-            new DelegateManager<MaskFilter_Delegate>(MaskFilter_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static MaskFilter_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(long native_filter) {
-        sManager.removeJavaReferenceFor(native_filter);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
deleted file mode 100644
index 354f919..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
+++ /dev/null
@@ -1,1077 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Matrix.ScaleToFit;
-
-import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
-
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.Matrix
- *
- * Through the layoutlib_create tool, the original native methods of Matrix have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Matrix class.
- *
- * @see DelegateManager
- *
- */
-public final class Matrix_Delegate {
-
-    private final static int MATRIX_SIZE = 9;
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Matrix_Delegate> sManager =
-            new DelegateManager<Matrix_Delegate>(Matrix_Delegate.class);
-    private static long sFinalizer = -1;
-
-    // ---- delegate data ----
-    private float mValues[] = new float[MATRIX_SIZE];
-
-    // ---- Public Helper methods ----
-
-    public static Matrix_Delegate getDelegate(long native_instance) {
-        return sManager.getDelegate(native_instance);
-    }
-
-    /**
-     * Returns an {@link AffineTransform} matching the given Matrix.
-     */
-    public static AffineTransform getAffineTransform(Matrix m) {
-        Matrix_Delegate delegate = sManager.getDelegate(m.native_instance);
-        if (delegate == null) {
-            return null;
-        }
-
-        return delegate.getAffineTransform();
-    }
-
-    public static boolean hasPerspective(Matrix m) {
-        Matrix_Delegate delegate = sManager.getDelegate(m.native_instance);
-        if (delegate == null) {
-            return false;
-        }
-
-        return delegate.hasPerspective();
-    }
-
-    /**
-     * Sets the content of the matrix with the content of another matrix.
-     */
-    public void set(Matrix_Delegate matrix) {
-        System.arraycopy(matrix.mValues, 0, mValues, 0, MATRIX_SIZE);
-    }
-
-    /**
-     * Sets the content of the matrix with the content of another matrix represented as an array
-     * of values.
-     */
-    public void set(float[] values) {
-        System.arraycopy(values, 0, mValues, 0, MATRIX_SIZE);
-    }
-
-    /**
-     * Resets the matrix to be the identity matrix.
-     */
-    public void reset() {
-        reset(mValues);
-    }
-
-    /**
-     * Returns whether or not the matrix is identity.
-     */
-    public boolean isIdentity() {
-        for (int i = 0, k = 0; i < 3; i++) {
-            for (int j = 0; j < 3; j++, k++) {
-                if (mValues[k] != ((i==j) ? 1 : 0)) {
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    public static float[] makeValues(AffineTransform matrix) {
-        float[] values = new float[MATRIX_SIZE];
-        values[0] = (float) matrix.getScaleX();
-        values[1] = (float) matrix.getShearX();
-        values[2] = (float) matrix.getTranslateX();
-        values[3] = (float) matrix.getShearY();
-        values[4] = (float) matrix.getScaleY();
-        values[5] = (float) matrix.getTranslateY();
-        values[6] = 0.f;
-        values[7] = 0.f;
-        values[8] = 1.f;
-
-        return values;
-    }
-
-    public static Matrix_Delegate make(AffineTransform matrix) {
-        return new Matrix_Delegate(makeValues(matrix));
-    }
-
-    public boolean mapRect(RectF dst, RectF src) {
-        // array with 4 corners
-        float[] corners = new float[] {
-                src.left, src.top,
-                src.right, src.top,
-                src.right, src.bottom,
-                src.left, src.bottom,
-        };
-
-        // apply the transform to them.
-        mapPoints(corners);
-
-        // now put the result in the rect. We take the min/max of Xs and min/max of Ys
-        dst.left = Math.min(Math.min(corners[0], corners[2]), Math.min(corners[4], corners[6]));
-        dst.right = Math.max(Math.max(corners[0], corners[2]), Math.max(corners[4], corners[6]));
-
-        dst.top = Math.min(Math.min(corners[1], corners[3]), Math.min(corners[5], corners[7]));
-        dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7]));
-
-
-        return (computeTypeMask() & kRectStaysRect_Mask) != 0;
-    }
-
-
-    /**
-     * Returns an {@link AffineTransform} matching the matrix.
-     */
-    public AffineTransform getAffineTransform() {
-        return getAffineTransform(mValues);
-    }
-
-    public boolean hasPerspective() {
-        return (mValues[6] != 0 || mValues[7] != 0 || mValues[8] != 1);
-    }
-
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreate(long native_src_or_zero) {
-        // create the delegate
-        Matrix_Delegate newDelegate = new Matrix_Delegate();
-
-        // copy from values if needed.
-        if (native_src_or_zero > 0) {
-            Matrix_Delegate oldDelegate = sManager.getDelegate(native_src_or_zero);
-            if (oldDelegate != null) {
-                System.arraycopy(
-                        oldDelegate.mValues, 0,
-                        newDelegate.mValues, 0,
-                        MATRIX_SIZE);
-            }
-        }
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsIdentity(long native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        return d.isIdentity();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsAffine(long native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return true;
-        }
-
-        return (d.computeTypeMask() & kPerspective_Mask) == 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nRectStaysRect(long native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return true;
-        }
-
-        return (d.computeTypeMask() & kRectStaysRect_Mask) != 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReset(long native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        reset(d.mValues);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSet(long native_object, long other) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        Matrix_Delegate src = sManager.getDelegate(other);
-        if (src == null) {
-            return;
-        }
-
-        System.arraycopy(src.mValues, 0, d.mValues, 0, MATRIX_SIZE);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTranslate(long native_object, float dx, float dy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        setTranslate(d.mValues, dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetScale(long native_object, float sx, float sy,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues = getScale(sx, sy, px, py);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetScale(long native_object, float sx, float sy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues[0] = sx;
-        d.mValues[1] = 0;
-        d.mValues[2] = 0;
-        d.mValues[3] = 0;
-        d.mValues[4] = sy;
-        d.mValues[5] = 0;
-        d.mValues[6] = 0;
-        d.mValues[7] = 0;
-        d.mValues[8] = 1;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetRotate(long native_object, float degrees, float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues = getRotate(degrees, px, py);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetRotate(long native_object, float degrees) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        setRotate(d.mValues, degrees);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSinCos(long native_object, float sinValue, float cosValue,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        setTranslate(d.mValues, -px, -py);
-
-        // scale
-        d.postTransform(getRotate(sinValue, cosValue));
-        // translate back the pivot
-        d.postTransform(getTranslate(px, py));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSinCos(long native_object, float sinValue, float cosValue) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        setRotate(d.mValues, sinValue, cosValue);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSkew(long native_object, float kx, float ky,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues = getSkew(kx, ky, px, py);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSkew(long native_object, float kx, float ky) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues[0] = 1;
-        d.mValues[1] = kx;
-        d.mValues[2] = -0;
-        d.mValues[3] = ky;
-        d.mValues[4] = 1;
-        d.mValues[5] = 0;
-        d.mValues[6] = 0;
-        d.mValues[7] = 0;
-        d.mValues[8] = 1;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetConcat(long native_object, long a, long b) {
-        if (a == native_object) {
-            nPreConcat(native_object, b);
-            return;
-        } else if (b == native_object) {
-            nPostConcat(native_object, a);
-            return;
-        }
-
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        Matrix_Delegate a_mtx = sManager.getDelegate(a);
-        Matrix_Delegate b_mtx = sManager.getDelegate(b);
-        if (d != null && a_mtx != null && b_mtx != null) {
-            multiply(d.mValues, a_mtx.mValues, b_mtx.mValues);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreTranslate(long native_object, float dx, float dy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getTranslate(dx, dy));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreScale(long native_object, float sx, float sy,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getScale(sx, sy, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreScale(long native_object, float sx, float sy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getScale(sx, sy));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreRotate(long native_object, float degrees,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getRotate(degrees, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreRotate(long native_object, float degrees) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-
-            double rad = Math.toRadians(degrees);
-            float sin = (float) Math.sin(rad);
-            float cos = (float) Math.cos(rad);
-
-            d.preTransform(getRotate(sin, cos));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreSkew(long native_object, float kx, float ky,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getSkew(kx, ky, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreSkew(long native_object, float kx, float ky) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getSkew(kx, ky));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreConcat(long native_object, long other_matrix) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        Matrix_Delegate other = sManager.getDelegate(other_matrix);
-        if (d != null && other != null) {
-            d.preTransform(other.mValues);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostTranslate(long native_object, float dx, float dy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getTranslate(dx, dy));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostScale(long native_object, float sx, float sy,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getScale(sx, sy, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostScale(long native_object, float sx, float sy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getScale(sx, sy));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostRotate(long native_object, float degrees,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getRotate(degrees, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostRotate(long native_object, float degrees) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getRotate(degrees));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostSkew(long native_object, float kx, float ky,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getSkew(kx, ky, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostSkew(long native_object, float kx, float ky) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getSkew(kx, ky));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostConcat(long native_object, long other_matrix) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        Matrix_Delegate other = sManager.getDelegate(other_matrix);
-        if (d != null && other != null) {
-            d.postTransform(other.mValues);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetRectToRect(long native_object, RectF src,
-            RectF dst, int stf) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        if (src.isEmpty()) {
-            reset(d.mValues);
-            return false;
-        }
-
-        if (dst.isEmpty()) {
-            d.mValues[0] = d.mValues[1] = d.mValues[2] = d.mValues[3] = d.mValues[4] = d.mValues[5]
-               = d.mValues[6] = d.mValues[7] = 0;
-            d.mValues[8] = 1;
-        } else {
-            float    tx, sx = dst.width() / src.width();
-            float    ty, sy = dst.height() / src.height();
-            boolean  xLarger = false;
-
-            if (stf != ScaleToFit.FILL.nativeInt) {
-                if (sx > sy) {
-                    xLarger = true;
-                    sx = sy;
-                } else {
-                    sy = sx;
-                }
-            }
-
-            tx = dst.left - src.left * sx;
-            ty = dst.top - src.top * sy;
-            if (stf == ScaleToFit.CENTER.nativeInt || stf == ScaleToFit.END.nativeInt) {
-                float diff;
-
-                if (xLarger) {
-                    diff = dst.width() - src.width() * sy;
-                } else {
-                    diff = dst.height() - src.height() * sy;
-                }
-
-                if (stf == ScaleToFit.CENTER.nativeInt) {
-                    diff = diff / 2;
-                }
-
-                if (xLarger) {
-                    tx += diff;
-                } else {
-                    ty += diff;
-                }
-            }
-
-            d.mValues[0] = sx;
-            d.mValues[4] = sy;
-            d.mValues[2] = tx;
-            d.mValues[5] = ty;
-            d.mValues[1]  = d.mValues[3] = d.mValues[6] = d.mValues[7] = 0;
-
-        }
-        // shared cleanup
-        d.mValues[8] = 1;
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetPolyToPoly(long native_object, float[] src, int srcIndex,
-            float[] dst, int dstIndex, int pointCount) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Matrix.setPolyToPoly is not supported.",
-                null, null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nInvert(long native_object, long inverse) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        Matrix_Delegate inv_mtx = sManager.getDelegate(inverse);
-        if (inv_mtx == null) {
-            return false;
-        }
-
-        try {
-            AffineTransform affineTransform = d.getAffineTransform();
-            AffineTransform inverseTransform = affineTransform.createInverse();
-            inv_mtx.mValues[0] = (float)inverseTransform.getScaleX();
-            inv_mtx.mValues[1] = (float)inverseTransform.getShearX();
-            inv_mtx.mValues[2] = (float)inverseTransform.getTranslateX();
-            inv_mtx.mValues[3] = (float)inverseTransform.getScaleX();
-            inv_mtx.mValues[4] = (float)inverseTransform.getShearY();
-            inv_mtx.mValues[5] = (float)inverseTransform.getTranslateY();
-
-            return true;
-        } catch (NoninvertibleTransformException e) {
-            return false;
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nMapPoints(long native_object, float[] dst, int dstIndex,
-            float[] src, int srcIndex, int ptCount, boolean isPts) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        if (isPts) {
-            d.mapPoints(dst, dstIndex, src, srcIndex, ptCount);
-        } else {
-            d.mapVectors(dst, dstIndex, src, srcIndex, ptCount);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nMapRect(long native_object, RectF dst, RectF src) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        return d.mapRect(dst, src);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nMapRadius(long native_object, float radius) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return 0.f;
-        }
-
-        float[] src = new float[] { radius, 0.f, 0.f, radius };
-        d.mapVectors(src, 0, src, 0, 2);
-
-        float l1 = (float) Math.hypot(src[0], src[1]);
-        float l2 = (float) Math.hypot(src[2], src[3]);
-        return (float) Math.sqrt(l1 * l2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetValues(long native_object, float[] values) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        System.arraycopy(d.mValues, 0, values, 0, MATRIX_SIZE);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetValues(long native_object, float[] values) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        System.arraycopy(values, 0, d.mValues, 0, MATRIX_SIZE);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nEquals(long native_a, long native_b) {
-        Matrix_Delegate a = sManager.getDelegate(native_a);
-        if (a == null) {
-            return false;
-        }
-
-        Matrix_Delegate b = sManager.getDelegate(native_b);
-        if (b == null) {
-            return false;
-        }
-
-        for (int i = 0 ; i < MATRIX_SIZE ; i++) {
-            if (a.mValues[i] != b.mValues[i]) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetNativeFinalizer() {
-        synchronized (Matrix_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(sManager::removeJavaReferenceFor);
-            }
-        }
-        return sFinalizer;
-    }
-
-    // ---- Private helper methods ----
-
-    /*package*/ static AffineTransform getAffineTransform(float[] matrix) {
-        // the AffineTransform constructor takes the value in a different order
-        // for a matrix [ 0 1 2 ]
-        //              [ 3 4 5 ]
-        // the order is 0, 3, 1, 4, 2, 5...
-        return new AffineTransform(
-                matrix[0], matrix[3], matrix[1],
-                matrix[4], matrix[2], matrix[5]);
-    }
-
-    /**
-     * Reset a matrix to the identity
-     */
-    private static void reset(float[] mtx) {
-        for (int i = 0, k = 0; i < 3; i++) {
-            for (int j = 0; j < 3; j++, k++) {
-                mtx[k] = ((i==j) ? 1 : 0);
-            }
-        }
-    }
-
-    @SuppressWarnings("unused")
-    private final static int kIdentity_Mask      = 0;
-    private final static int kTranslate_Mask     = 0x01;  //!< set if the matrix has translation
-    private final static int kScale_Mask         = 0x02;  //!< set if the matrix has X or Y scale
-    private final static int kAffine_Mask        = 0x04;  //!< set if the matrix skews or rotates
-    private final static int kPerspective_Mask   = 0x08;  //!< set if the matrix is in perspective
-    private final static int kRectStaysRect_Mask = 0x10;
-    @SuppressWarnings("unused")
-    private final static int kUnknown_Mask       = 0x80;
-
-    @SuppressWarnings("unused")
-    private final static int kAllMasks           = kTranslate_Mask |
-                                                   kScale_Mask |
-                                                   kAffine_Mask |
-                                                   kPerspective_Mask |
-                                                   kRectStaysRect_Mask;
-
-    // these guys align with the masks, so we can compute a mask from a variable 0/1
-    @SuppressWarnings("unused")
-    private final static int kTranslate_Shift = 0;
-    @SuppressWarnings("unused")
-    private final static int kScale_Shift = 1;
-    @SuppressWarnings("unused")
-    private final static int kAffine_Shift = 2;
-    @SuppressWarnings("unused")
-    private final static int kPerspective_Shift = 3;
-    private final static int kRectStaysRect_Shift = 4;
-
-    private int computeTypeMask() {
-        int mask = 0;
-
-        if (mValues[6] != 0. || mValues[7] != 0. || mValues[8] != 1.) {
-            mask |= kPerspective_Mask;
-        }
-
-        if (mValues[2] != 0. || mValues[5] != 0.) {
-            mask |= kTranslate_Mask;
-        }
-
-        float m00 = mValues[0];
-        float m01 = mValues[1];
-        float m10 = mValues[3];
-        float m11 = mValues[4];
-
-        if (m01 != 0. || m10 != 0.) {
-            mask |= kAffine_Mask;
-        }
-
-        if (m00 != 1. || m11 != 1.) {
-            mask |= kScale_Mask;
-        }
-
-        if ((mask & kPerspective_Mask) == 0) {
-            // map non-zero to 1
-            int im00 = m00 != 0 ? 1 : 0;
-            int im01 = m01 != 0 ? 1 : 0;
-            int im10 = m10 != 0 ? 1 : 0;
-            int im11 = m11 != 0 ? 1 : 0;
-
-            // record if the (p)rimary and (s)econdary diagonals are all 0 or
-            // all non-zero (answer is 0 or 1)
-            int dp0 = (im00 | im11) ^ 1;  // true if both are 0
-            int dp1 = im00 & im11;        // true if both are 1
-            int ds0 = (im01 | im10) ^ 1;  // true if both are 0
-            int ds1 = im01 & im10;        // true if both are 1
-
-            // return 1 if primary is 1 and secondary is 0 or
-            // primary is 0 and secondary is 1
-            mask |= ((dp0 & ds1) | (dp1 & ds0)) << kRectStaysRect_Shift;
-        }
-
-        return mask;
-    }
-
-    private Matrix_Delegate() {
-        reset();
-    }
-
-    private Matrix_Delegate(float[] values) {
-        System.arraycopy(values, 0, mValues, 0, MATRIX_SIZE);
-    }
-
-    /**
-     * Adds the given transformation to the current Matrix
-     * <p/>This in effect does this = this*matrix
-     * @param matrix
-     */
-    private void postTransform(float[] matrix) {
-        float[] tmp = new float[9];
-        multiply(tmp, mValues, matrix);
-        mValues = tmp;
-    }
-
-    /**
-     * Adds the given transformation to the current Matrix
-     * <p/>This in effect does this = matrix*this
-     * @param matrix
-     */
-    private void preTransform(float[] matrix) {
-        float[] tmp = new float[9];
-        multiply(tmp, matrix, mValues);
-        mValues = tmp;
-    }
-
-    /**
-     * Apply this matrix to the array of 2D points specified by src, and write
-      * the transformed points into the array of points specified by dst. The
-      * two arrays represent their "points" as pairs of floats [x, y].
-      *
-      * @param dst   The array of dst points (x,y pairs)
-      * @param dstIndex The index of the first [x,y] pair of dst floats
-      * @param src   The array of src points (x,y pairs)
-      * @param srcIndex The index of the first [x,y] pair of src floats
-      * @param pointCount The number of points (x,y pairs) to transform
-      */
-
-     private void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex,
-                           int pointCount) {
-         final int count = pointCount * 2;
-
-         float[] tmpDest = dst;
-         boolean inPlace = dst == src;
-         if (inPlace) {
-             tmpDest = new float[dstIndex + count];
-         }
-
-         for (int i = 0 ; i < count ; i += 2) {
-             // just in case we are doing in place, we better put this in temp vars
-             float x = mValues[0] * src[i + srcIndex] +
-                       mValues[1] * src[i + srcIndex + 1] +
-                       mValues[2];
-             float y = mValues[3] * src[i + srcIndex] +
-                       mValues[4] * src[i + srcIndex + 1] +
-                       mValues[5];
-
-             tmpDest[i + dstIndex]     = x;
-             tmpDest[i + dstIndex + 1] = y;
-         }
-
-         if (inPlace) {
-             System.arraycopy(tmpDest, dstIndex, dst, dstIndex, count);
-         }
-     }
-
-     /**
-      * Apply this matrix to the array of 2D points, and write the transformed
-      * points back into the array
-      *
-      * @param pts The array [x0, y0, x1, y1, ...] of points to transform.
-      */
-
-     private void mapPoints(float[] pts) {
-         mapPoints(pts, 0, pts, 0, pts.length >> 1);
-     }
-
-     private void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int ptCount) {
-         if (hasPerspective()) {
-             // transform the (0,0) point
-             float[] origin = new float[] { 0.f, 0.f};
-             mapPoints(origin);
-
-             // translate the vector data as points
-             mapPoints(dst, dstIndex, src, srcIndex, ptCount);
-
-             // then substract the transformed origin.
-             final int count = ptCount * 2;
-             for (int i = 0 ; i < count ; i += 2) {
-                 dst[dstIndex + i] = dst[dstIndex + i] - origin[0];
-                 dst[dstIndex + i + 1] = dst[dstIndex + i + 1] - origin[1];
-             }
-         } else {
-             // make a copy of the matrix
-             Matrix_Delegate copy = new Matrix_Delegate(mValues);
-
-             // remove the translation
-             setTranslate(copy.mValues, 0, 0);
-
-             // map the content as points.
-             copy.mapPoints(dst, dstIndex, src, srcIndex, ptCount);
-         }
-     }
-
-    /**
-     * multiply two matrices and store them in a 3rd.
-     * <p/>This in effect does dest = a*b
-     * dest cannot be the same as a or b.
-     */
-     /*package*/ static void multiply(float dest[], float[] a, float[] b) {
-        // first row
-        dest[0] = b[0] * a[0] + b[1] * a[3] + b[2] * a[6];
-        dest[1] = b[0] * a[1] + b[1] * a[4] + b[2] * a[7];
-        dest[2] = b[0] * a[2] + b[1] * a[5] + b[2] * a[8];
-
-        // 2nd row
-        dest[3] = b[3] * a[0] + b[4] * a[3] + b[5] * a[6];
-        dest[4] = b[3] * a[1] + b[4] * a[4] + b[5] * a[7];
-        dest[5] = b[3] * a[2] + b[4] * a[5] + b[5] * a[8];
-
-        // 3rd row
-        dest[6] = b[6] * a[0] + b[7] * a[3] + b[8] * a[6];
-        dest[7] = b[6] * a[1] + b[7] * a[4] + b[8] * a[7];
-        dest[8] = b[6] * a[2] + b[7] * a[5] + b[8] * a[8];
-    }
-
-    /**
-     * Returns a matrix that represents a given translate
-     * @param dx
-     * @param dy
-     * @return
-     */
-    /*package*/ static float[] getTranslate(float dx, float dy) {
-        return setTranslate(new float[9], dx, dy);
-    }
-
-    /*package*/ static float[] setTranslate(float[] dest, float dx, float dy) {
-        dest[0] = 1;
-        dest[1] = 0;
-        dest[2] = dx;
-        dest[3] = 0;
-        dest[4] = 1;
-        dest[5] = dy;
-        dest[6] = 0;
-        dest[7] = 0;
-        dest[8] = 1;
-        return dest;
-    }
-
-    /*package*/ static float[] getScale(float sx, float sy) {
-        return new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 };
-    }
-
-    /**
-     * Returns a matrix that represents the given scale info.
-     * @param sx
-     * @param sy
-     * @param px
-     * @param py
-     */
-    /*package*/ static float[] getScale(float sx, float sy, float px, float py) {
-        float[] tmp = new float[9];
-        float[] tmp2 = new float[9];
-
-        // TODO: do it in one pass
-
-        // translate tmp so that the pivot is in 0,0
-        setTranslate(tmp, -px, -py);
-
-        // scale into tmp2
-        multiply(tmp2, tmp, getScale(sx, sy));
-
-        // translate back the pivot back into tmp
-        multiply(tmp, tmp2, getTranslate(px, py));
-
-        return tmp;
-    }
-
-
-    /*package*/ static float[] getRotate(float degrees) {
-        double rad = Math.toRadians(degrees);
-        float sin = (float)Math.sin(rad);
-        float cos = (float)Math.cos(rad);
-
-        return getRotate(sin, cos);
-    }
-
-    /*package*/ static float[] getRotate(float sin, float cos) {
-        return setRotate(new float[9], sin, cos);
-    }
-
-    /*package*/ static float[] setRotate(float[] dest, float degrees) {
-        double rad = Math.toRadians(degrees);
-        float sin = (float)Math.sin(rad);
-        float cos = (float)Math.cos(rad);
-
-        return setRotate(dest, sin, cos);
-    }
-
-    /*package*/ static float[] setRotate(float[] dest, float sin, float cos) {
-        dest[0] = cos;
-        dest[1] = -sin;
-        dest[2] = 0;
-        dest[3] = sin;
-        dest[4] = cos;
-        dest[5] = 0;
-        dest[6] = 0;
-        dest[7] = 0;
-        dest[8] = 1;
-        return dest;
-    }
-
-    /*package*/ static float[] getRotate(float degrees, float px, float py) {
-        float[] tmp = new float[9];
-        float[] tmp2 = new float[9];
-
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        setTranslate(tmp, -px, -py);
-
-        // rotate into tmp2
-        double rad = Math.toRadians(degrees);
-        float cos = (float)Math.cos(rad);
-        float sin = (float)Math.sin(rad);
-        multiply(tmp2, tmp, getRotate(sin, cos));
-
-        // translate back the pivot back into tmp
-        multiply(tmp, tmp2, getTranslate(px, py));
-
-        return tmp;
-    }
-
-    /*package*/ static float[] getSkew(float kx, float ky) {
-        return new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 };
-    }
-
-    /*package*/ static float[] getSkew(float kx, float ky, float px, float py) {
-        float[] tmp = new float[9];
-        float[] tmp2 = new float[9];
-
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        setTranslate(tmp, -px, -py);
-
-        // skew into tmp2
-        multiply(tmp2, tmp, new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 });
-        // translate back the pivot back into tmp
-        multiply(tmp, tmp2, getTranslate(px, py));
-
-        return tmp;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
deleted file mode 100644
index 1f0eb3b..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.GcSnapshot;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.drawable.NinePatchDrawable;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.lang.ref.SoftReference;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Delegate implementing the native methods of android.graphics.NinePatch
- *
- * Through the layoutlib_create tool, the original native methods of NinePatch have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-public final class NinePatch_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<NinePatch_Delegate> sManager =
-            new DelegateManager<NinePatch_Delegate>(NinePatch_Delegate.class);
-
-    // ---- delegate helper data ----
-    /**
-     * Cache map for {@link NinePatchChunk}.
-     * When the chunks are created they are serialized into a byte[], and both are put
-     * in the cache, using a {@link SoftReference} for the chunk. The default Java classes
-     * for {@link NinePatch} and {@link NinePatchDrawable} only reference to the byte[] data, and
-     * provide this for drawing.
-     * Using the cache map allows us to not have to deserialize the byte[] back into a
-     * {@link NinePatchChunk} every time a rendering is done.
-     */
-    private final static Map<byte[], SoftReference<NinePatchChunk>> sChunkCache =
-        new HashMap<byte[], SoftReference<NinePatchChunk>>();
-
-    // ---- delegate data ----
-    private byte[] chunk;
-
-
-    // ---- Public Helper methods ----
-
-    /**
-     * Serializes the given chunk.
-     *
-     * @return the serialized data for the chunk.
-     */
-    public static byte[] serialize(NinePatchChunk chunk) {
-        // serialize the chunk to get a byte[]
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream oos = null;
-        try {
-            oos = new ObjectOutputStream(baos);
-            oos.writeObject(chunk);
-        } catch (IOException e) {
-            Bridge.getLog().error(null, "Failed to serialize NinePatchChunk.", e, null /*data*/);
-            return null;
-        } finally {
-            if (oos != null) {
-                try {
-                    oos.close();
-                } catch (IOException ignored) {
-                }
-            }
-        }
-
-        // get the array and add it to the cache
-        byte[] array = baos.toByteArray();
-        sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk));
-        return array;
-    }
-
-    /**
-     * Returns a {@link NinePatchChunk} object for the given serialized representation.
-     *
-     * If the chunk is present in the cache then the object from the cache is returned, otherwise
-     * the array is deserialized into a {@link NinePatchChunk} object.
-     *
-     * @param array the serialized representation of the chunk.
-     * @return the NinePatchChunk or null if deserialization failed.
-     */
-    public static NinePatchChunk getChunk(byte[] array) {
-        SoftReference<NinePatchChunk> chunkRef = sChunkCache.get(array);
-        NinePatchChunk chunk = chunkRef.get();
-        if (chunk == null) {
-            ByteArrayInputStream bais = new ByteArrayInputStream(array);
-            ObjectInputStream ois = null;
-            try {
-                ois = new ObjectInputStream(bais);
-                chunk = (NinePatchChunk) ois.readObject();
-
-                // put back the chunk in the cache
-                if (chunk != null) {
-                    sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk));
-                }
-            } catch (IOException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to deserialize NinePatchChunk content.", e, null /*data*/);
-                return null;
-            } catch (ClassNotFoundException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to deserialize NinePatchChunk class.", e, null /*data*/);
-                return null;
-            } finally {
-                if (ois != null) {
-                    try {
-                        ois.close();
-                    } catch (IOException ignored) {
-                    }
-                }
-            }
-        }
-
-        return chunk;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isNinePatchChunk(byte[] chunk) {
-        NinePatchChunk chunkObject = getChunk(chunk);
-        return chunkObject != null;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long validateNinePatchChunk(byte[] chunk) {
-        // the default JNI implementation only checks that the byte[] has the same
-        // size as the C struct it represent. Since we cannot do the same check (serialization
-        // will return different size depending on content), we do nothing.
-        NinePatch_Delegate newDelegate = new NinePatch_Delegate();
-        newDelegate.chunk = chunk;
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeFinalize(long chunk) {
-        sManager.removeJavaReferenceFor(chunk);
-    }
-
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeGetTransparentRegion(Bitmap bitmap, long chunk, Rect location) {
-        return 0;
-    }
-
-    static byte[] getChunk(long nativeNinePatch) {
-        NinePatch_Delegate delegate = sManager.getDelegate(nativeNinePatch);
-        if (delegate != null) {
-            return delegate.chunk;
-        }
-        return null;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java
deleted file mode 100644
index fa20746..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.PaintFlagsDrawFilter
- *
- * Through the layoutlib_create tool, the original native methods of PaintFlagsDrawFilter have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PaintFlagsDrawFilter class.
- *
- * Because this extends {@link DrawFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the DrawFilter classes will be added to the manager owned by
- * {@link DrawFilter_Delegate}.
- *
- * @see DrawFilter_Delegate
- *
- */
-public class PaintFlagsDrawFilter_Delegate extends DrawFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Paint Flags Draw Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeConstructor(int clearBits, int setBits) {
-        PaintFlagsDrawFilter_Delegate newDelegate = new PaintFlagsDrawFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
deleted file mode 100644
index 1bb56e3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ /dev/null
@@ -1,1329 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.graphics.FontFamily_Delegate.FontVariant;
-import android.graphics.Paint.FontMetrics;
-import android.graphics.Paint.FontMetricsInt;
-import android.text.TextUtils;
-
-import java.awt.BasicStroke;
-import java.awt.Font;
-import java.awt.Shape;
-import java.awt.Stroke;
-import java.awt.Toolkit;
-import java.awt.geom.AffineTransform;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.Paint
- *
- * Through the layoutlib_create tool, the original native methods of Paint have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Paint class.
- *
- * @see DelegateManager
- *
- */
-public class Paint_Delegate {
-
-    /**
-     * Class associating a {@link Font} and its {@link java.awt.FontMetrics}.
-     */
-    /*package*/ static final class FontInfo {
-        Font mFont;
-        java.awt.FontMetrics mMetrics;
-    }
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Paint_Delegate> sManager =
-            new DelegateManager<Paint_Delegate>(Paint_Delegate.class);
-    private static long sFinalizer = -1;
-
-    // ---- delegate helper data ----
-
-    // This list can contain null elements.
-    private List<FontInfo> mFonts;
-
-    // ---- delegate data ----
-    private int mFlags;
-    private int mColor;
-    private int mStyle;
-    private int mCap;
-    private int mJoin;
-    private int mTextAlign;
-    private Typeface_Delegate mTypeface;
-    private float mStrokeWidth;
-    private float mStrokeMiter;
-    private float mTextSize;
-    private float mTextScaleX;
-    private float mTextSkewX;
-    private int mHintingMode = Paint.HINTING_ON;
-    private int mHyphenEdit;
-    private float mLetterSpacing;  // not used in actual text rendering.
-    private float mWordSpacing;  // not used in actual text rendering.
-    // Variant of the font. A paint's variant can only be compact or elegant.
-    private FontVariant mFontVariant = FontVariant.COMPACT;
-
-    private int mPorterDuffMode = Xfermode.DEFAULT;
-    private ColorFilter_Delegate mColorFilter;
-    private Shader_Delegate mShader;
-    private PathEffect_Delegate mPathEffect;
-    private MaskFilter_Delegate mMaskFilter;
-
-    private Locale mLocale = Locale.getDefault();
-
-    // Used only to assert invariants.
-    public long mNativeTypeface;
-
-    // ---- Public Helper methods ----
-
-    @Nullable
-    public static Paint_Delegate getDelegate(long native_paint) {
-        return sManager.getDelegate(native_paint);
-    }
-
-    /**
-     * Returns the list of {@link Font} objects.
-     */
-    public List<FontInfo> getFonts() {
-        return mFonts;
-    }
-
-    public boolean isAntiAliased() {
-        return (mFlags & Paint.ANTI_ALIAS_FLAG) != 0;
-    }
-
-    public boolean isFilterBitmap() {
-        return (mFlags & Paint.FILTER_BITMAP_FLAG) != 0;
-    }
-
-    public int getStyle() {
-        return mStyle;
-    }
-
-    public int getColor() {
-        return mColor;
-    }
-
-    public int getAlpha() {
-        return mColor >>> 24;
-    }
-
-    public void setAlpha(int alpha) {
-        mColor = (alpha << 24) | (mColor & 0x00FFFFFF);
-    }
-
-    public int getTextAlign() {
-        return mTextAlign;
-    }
-
-    public float getStrokeWidth() {
-        return mStrokeWidth;
-    }
-
-    /**
-     * returns the value of stroke miter needed by the java api.
-     */
-    public float getJavaStrokeMiter() {
-        return mStrokeMiter;
-    }
-
-    public int getJavaCap() {
-        switch (Paint.sCapArray[mCap]) {
-            case BUTT:
-                return BasicStroke.CAP_BUTT;
-            case ROUND:
-                return BasicStroke.CAP_ROUND;
-            default:
-            case SQUARE:
-                return BasicStroke.CAP_SQUARE;
-        }
-    }
-
-    public int getJavaJoin() {
-        switch (Paint.sJoinArray[mJoin]) {
-            default:
-            case MITER:
-                return BasicStroke.JOIN_MITER;
-            case ROUND:
-                return BasicStroke.JOIN_ROUND;
-            case BEVEL:
-                return BasicStroke.JOIN_BEVEL;
-        }
-    }
-
-    public Stroke getJavaStroke() {
-        if (mPathEffect != null) {
-            if (mPathEffect.isSupported()) {
-                Stroke stroke = mPathEffect.getStroke(this);
-                assert stroke != null;
-                if (stroke != null) {
-                    return stroke;
-                }
-            } else {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT,
-                        mPathEffect.getSupportMessage(),
-                        null, null /*data*/);
-            }
-        }
-
-        // if no custom stroke as been set, set the default one.
-        return new BasicStroke(
-                    getStrokeWidth(),
-                    getJavaCap(),
-                    getJavaJoin(),
-                    getJavaStrokeMiter());
-    }
-
-    /**
-     * Returns the {@link PorterDuff.Mode} as an int
-     */
-    public int getPorterDuffMode() {
-        return mPorterDuffMode;
-    }
-
-    /**
-     * Returns the {@link ColorFilter} delegate or null if none have been set
-     *
-     * @return the delegate or null.
-     */
-    public ColorFilter_Delegate getColorFilter() {
-        return mColorFilter;
-    }
-
-    public void setColorFilter(long colorFilterPtr) {
-        mColorFilter = ColorFilter_Delegate.getDelegate(colorFilterPtr);
-    }
-
-    public void setShader(long shaderPtr) {
-        mShader = Shader_Delegate.getDelegate(shaderPtr);
-    }
-
-    /**
-     * Returns the {@link Shader} delegate or null if none have been set
-     *
-     * @return the delegate or null.
-     */
-    public Shader_Delegate getShader() {
-        return mShader;
-    }
-
-    /**
-     * Returns the {@link MaskFilter} delegate or null if none have been set
-     *
-     * @return the delegate or null.
-     */
-    public MaskFilter_Delegate getMaskFilter() {
-        return mMaskFilter;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetFlags(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mFlags;
-    }
-
-
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetFlags(long nativePaint, int flags) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mFlags = flags;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetFilterBitmap(long nativePaint, boolean filter) {
-        setFlag(nativePaint, Paint.FILTER_BITMAP_FLAG, filter);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetHinting(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return Paint.HINTING_ON;
-        }
-
-        return delegate.mHintingMode;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetHinting(long nativePaint, int mode) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mHintingMode = mode;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetAntiAlias(long nativePaint, boolean aa) {
-        setFlag(nativePaint, Paint.ANTI_ALIAS_FLAG, aa);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSubpixelText(long nativePaint,
-            boolean subpixelText) {
-        setFlag(nativePaint, Paint.SUBPIXEL_TEXT_FLAG, subpixelText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetUnderlineText(long nativePaint,
-            boolean underlineText) {
-        setFlag(nativePaint, Paint.UNDERLINE_TEXT_FLAG, underlineText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrikeThruText(long nativePaint,
-            boolean strikeThruText) {
-        setFlag(nativePaint, Paint.STRIKE_THRU_TEXT_FLAG, strikeThruText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetFakeBoldText(long nativePaint,
-            boolean fakeBoldText) {
-        setFlag(nativePaint, Paint.FAKE_BOLD_TEXT_FLAG, fakeBoldText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetDither(long nativePaint, boolean dither) {
-        setFlag(nativePaint, Paint.DITHER_FLAG, dither);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetLinearText(long nativePaint, boolean linearText) {
-        setFlag(nativePaint, Paint.LINEAR_TEXT_FLAG, linearText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetColor(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mColor;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetColor(long nativePaint, int color) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mColor = color;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetAlpha(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.getAlpha();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetAlpha(long nativePaint, int a) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.setAlpha(a);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetStrokeWidth(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mStrokeWidth;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrokeWidth(long nativePaint, float width) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mStrokeWidth = width;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetStrokeMiter(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mStrokeMiter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrokeMiter(long nativePaint, float miter) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mStrokeMiter = miter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetShadowLayer(long paint, float radius, float dx, float dy,
-            int color) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.setShadowLayer is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nHasShadowLayer(long paint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.hasShadowLayer is not supported.", null, null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsElegantTextHeight(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetElegantTextHeight(long nativePaint,
-            boolean elegant) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextSize(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mTextSize;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextSize(long nativePaint, float textSize) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        if (delegate.mTextSize != textSize) {
-            delegate.mTextSize = textSize;
-            delegate.updateFontObject();
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextScaleX(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mTextScaleX;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextScaleX(long nativePaint, float scaleX) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        if (delegate.mTextScaleX != scaleX) {
-            delegate.mTextScaleX = scaleX;
-            delegate.updateFontObject();
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextSkewX(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mTextSkewX;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextSkewX(long nativePaint, float skewX) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        if (delegate.mTextSkewX != skewX) {
-            delegate.mTextSkewX = skewX;
-            delegate.updateFontObject();
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nAscent(long nativePaint, long nativeTypeface) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        if (delegate.mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
-            // Android expects negative ascent so we invert the value from Java.
-            return - javaMetrics.getAscent();
-        }
-
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nDescent(long nativePaint, long nativeTypeface) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        if (delegate.mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
-            return javaMetrics.getDescent();
-        }
-
-        return 0;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetFontMetrics(long nativePaint, long nativeTypeface,
-            FontMetrics metrics) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.getFontMetrics(metrics);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetFontMetricsInt(long nativePaint,
-            long nativeTypeface, FontMetricsInt fmi) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        if (delegate.mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
-            if (fmi != null) {
-                // Android expects negative ascent so we invert the value from Java.
-                fmi.top = - javaMetrics.getMaxAscent();
-                fmi.ascent = - javaMetrics.getAscent();
-                fmi.descent = javaMetrics.getDescent();
-                fmi.bottom = javaMetrics.getMaxDescent();
-                fmi.leading = javaMetrics.getLeading();
-            }
-
-            return javaMetrics.getHeight();
-        }
-
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nBreakText(long nativePaint, long nativeTypeface, char[] text,
-            int index, int count, float maxWidth, int bidiFlags, float[] measuredWidth) {
-
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        int inc = count > 0 ? 1 : -1;
-
-        int measureIndex = 0;
-        for (int i = index; i != index + count; i += inc, measureIndex++) {
-            int start, end;
-            if (i < index) {
-                start = i;
-                end = index;
-            } else {
-                start = index;
-                end = i;
-            }
-
-            // measure from start to end
-            RectF bounds = delegate.measureText(text, start, end - start + 1, null, 0, bidiFlags);
-            float res = bounds.right - bounds.left;
-
-            if (measuredWidth != null) {
-                measuredWidth[measureIndex] = res;
-            }
-
-            if (res > maxWidth) {
-                // we should not return this char index, but since it's 0-based
-                // and we need to return a count, we simply return measureIndex;
-                return measureIndex;
-            }
-
-        }
-
-        return measureIndex;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nBreakText(long nativePaint, long nativeTypeface, String text,
-            boolean measureForwards,
-            float maxWidth, int bidiFlags, float[] measuredWidth) {
-        return nBreakText(nativePaint, nativeTypeface, text.toCharArray(), 0, text.length(),
-                maxWidth, bidiFlags, measuredWidth);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nInit() {
-        Paint_Delegate newDelegate = new Paint_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nInitWithPaint(long paint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(paint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        Paint_Delegate newDelegate = new Paint_Delegate(delegate);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReset(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.reset();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSet(long native_dst, long native_src) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate_dst = sManager.getDelegate(native_dst);
-        if (delegate_dst == null) {
-            return;
-        }
-
-        // get the delegate from the native int.
-        Paint_Delegate delegate_src = sManager.getDelegate(native_src);
-        if (delegate_src == null) {
-            return;
-        }
-
-        delegate_dst.set(delegate_src);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetStyle(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mStyle;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStyle(long native_object, int style) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mStyle = style;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetStrokeCap(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mCap;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrokeCap(long native_object, int cap) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mCap = cap;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetStrokeJoin(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mJoin;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrokeJoin(long native_object, int join) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mJoin = join;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nGetFillPath(long native_object, long src, long dst) {
-        Paint_Delegate paint = sManager.getDelegate(native_object);
-        if (paint == null) {
-            return false;
-        }
-
-        Path_Delegate srcPath = Path_Delegate.getDelegate(src);
-        if (srcPath == null) {
-            return true;
-        }
-
-        Path_Delegate dstPath = Path_Delegate.getDelegate(dst);
-        if (dstPath == null) {
-            return true;
-        }
-
-        Stroke stroke = paint.getJavaStroke();
-        Shape strokeShape = stroke.createStrokedShape(srcPath.getJavaShape());
-
-        dstPath.setJavaShape(strokeShape);
-
-        // FIXME figure out the return value?
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetShader(long native_object, long shader) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return shader;
-        }
-
-        delegate.mShader = Shader_Delegate.getDelegate(shader);
-
-        return shader;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetColorFilter(long native_object, long filter) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return filter;
-        }
-
-        delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);
-
-        // Log warning if it's not supported.
-        if (delegate.mColorFilter != null && !delegate.mColorFilter.isSupported()) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
-                    delegate.mColorFilter.getSupportMessage(), null, null /*data*/);
-        }
-
-        return filter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetXfermode(long native_object, int xfermode) {
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-        delegate.mPorterDuffMode = xfermode;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetPathEffect(long native_object, long effect) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return effect;
-        }
-
-        delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect);
-
-        return effect;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetMaskFilter(long native_object, long maskfilter) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return maskfilter;
-        }
-
-        delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter);
-
-        // since none of those are supported, display a fidelity warning right away
-        if (delegate.mMaskFilter != null && !delegate.mMaskFilter.isSupported()) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
-                    delegate.mMaskFilter.getSupportMessage(), null, null /*data*/);
-        }
-
-        return maskfilter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetTypeface(long native_object, long typeface) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        Typeface_Delegate typefaceDelegate = Typeface_Delegate.getDelegate(typeface);
-        if (delegate.mTypeface != typefaceDelegate || delegate.mNativeTypeface != typeface) {
-            delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
-            delegate.mNativeTypeface = typeface;
-            delegate.updateFontObject();
-        }
-        return typeface;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetTextAlign(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mTextAlign;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextAlign(long native_object, int align) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mTextAlign = align;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nSetTextLocales(long native_object, String locale) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        delegate.setTextLocale(locale);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextLocalesByMinikinLangListId(long paintPtr,
-            int mMinikinLangListId) {
-        // FIXME
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextAdvances(long native_object, long native_typeface,
-            char[] text, int index, int count, int contextIndex, int contextCount,
-            int bidiFlags, float[] advances, int advancesIndex) {
-
-        if (advances != null)
-            for (int i = advancesIndex; i< advancesIndex+count; i++)
-                advances[i]=0;
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0.f;
-        }
-
-        // native_typeface is passed here since Framework's old implementation did not have the
-        // typeface object associated with the Paint. Since, we follow the new framework way,
-        // we store the typeface with the paint and use it directly.
-        assert (native_typeface == delegate.mNativeTypeface);
-
-        RectF bounds = delegate.measureText(text, index, count, advances, advancesIndex, bidiFlags);
-        return bounds.right - bounds.left;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextAdvances(long native_object, long native_typeface,
-            String text, int start, int end, int contextStart, int contextEnd,
-            int bidiFlags, float[] advances, int advancesIndex) {
-        // FIXME: support contextStart and contextEnd
-        int count = end - start;
-        char[] buffer = TemporaryBuffer.obtain(count);
-        TextUtils.getChars(text, start, end, buffer, 0);
-
-        return nGetTextAdvances(native_object, native_typeface, buffer, 0, count,
-                contextStart, contextEnd - contextStart, bidiFlags, advances, advancesIndex);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, long typefacePtr,
-            char[] text, int contextStart, int contextLength, int flags, int offset,
-            int cursorOpt) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextRunCursor is not supported.", null, null /*data*/);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, long typefacePtr,
-            String text, int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextRunCursor is not supported.", null, null /*data*/);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetTextPath(long native_object, long native_typeface,
-            int bidiFlags, char[] text, int index, int count, float x, float y, long path) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextPath is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetTextPath(long native_object, long native_typeface,
-            int bidiFlags, String text, int start, int end, float x, float y, long path) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextPath is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetStringBounds(long nativePaint, long native_typeface,
-            String text, int start, int end, int bidiFlags, Rect bounds) {
-        nGetCharArrayBounds(nativePaint, native_typeface, text.toCharArray(), start,
-                end - start, bidiFlags, bounds);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetCharArrayBounds(long nativePaint, long native_typeface,
-            char[] text, int index, int count, int bidiFlags, Rect bounds) {
-
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        // assert that the typeface passed is actually the one that we had stored.
-        assert (native_typeface == delegate.mNativeTypeface);
-
-        delegate.measureText(text, index, count, null, 0, bidiFlags).roundOut(bounds);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetNativeFinalizer() {
-        synchronized (Paint_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(
-                        sManager::removeJavaReferenceFor);
-            }
-        }
-        return sFinalizer;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetLetterSpacing(long nativePaint) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-        return delegate.mLetterSpacing;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetLetterSpacing(long nativePaint, float letterSpacing) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
-                "Paint.setLetterSpacing() not supported.", null, null);
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-        delegate.mLetterSpacing = letterSpacing;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetWordSpacing(long nativePaint) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-        return delegate.mWordSpacing;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetWordSpacing(long nativePaint, float wordSpacing) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-        delegate.mWordSpacing = wordSpacing;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetFontFeatureSettings(long nativePaint, String settings) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
-                "Paint.setFontFeatureSettings() not supported.", null, null);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetHyphenEdit(long nativePaint) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-        return delegate.mHyphenEdit;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetHyphenEdit(long nativePaint, int hyphen) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-        delegate.mHyphenEdit = hyphen;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nHasGlyph(long nativePaint, long nativeTypeface, int bidiFlags,
-            String string) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return false;
-        }
-        if (string.length() == 0) {
-            return false;
-        }
-        if (string.length() > 1) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
-                    "Paint.hasGlyph() is not supported for ligatures.", null, null);
-            return false;
-        }
-        assert nativeTypeface == delegate.mNativeTypeface;
-        Typeface_Delegate typeface_delegate = Typeface_Delegate.getDelegate(nativeTypeface);
-
-        char c = string.charAt(0);
-        for (Font font : typeface_delegate.getFonts(delegate.mFontVariant)) {
-            if (font.canDisplay(c)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetRunAdvance(long nativePaint, long nativeTypeface,
-            @NonNull char[] text, int start, int end, int contextStart, int contextEnd,
-            boolean isRtl, int offset) {
-        int count = end - start;
-        float[] advances = new float[count];
-        int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
-        nGetTextAdvances(nativePaint, nativeTypeface, text, start, count,
-                contextStart, contextEnd - contextStart, bidiFlags, advances, 0);
-        int startOffset = offset - start;  // offset from start.
-        float sum = 0;
-        for (int i = 0; i < startOffset; i++) {
-            sum += advances[i];
-        }
-        return sum;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetOffsetForAdvance(long nativePaint, long nativeTypeface,
-            char[] text, int start, int end, int contextStart, int contextEnd, boolean isRtl,
-            float advance) {
-        int count = end - start;
-        float[] advances = new float[count];
-        int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
-        nGetTextAdvances(nativePaint, nativeTypeface, text, start, count,
-                contextStart, contextEnd - contextStart, bidiFlags, advances, 0);
-        float sum = 0;
-        int i;
-        for (i = 0; i < count && sum < advance; i++) {
-            sum += advances[i];
-        }
-        float distanceToI = sum - advance;
-        float distanceToIMinus1 = advance - (sum - advances[i]);
-        return distanceToI > distanceToIMinus1 ? i : i - 1;
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /*package*/ Paint_Delegate() {
-        reset();
-    }
-
-    private Paint_Delegate(Paint_Delegate paint) {
-        set(paint);
-    }
-
-    private void set(Paint_Delegate paint) {
-        mFlags = paint.mFlags;
-        mColor = paint.mColor;
-        mStyle = paint.mStyle;
-        mCap = paint.mCap;
-        mJoin = paint.mJoin;
-        mTextAlign = paint.mTextAlign;
-
-        boolean needsFontUpdate = false;
-        if (mTypeface != paint.mTypeface || mNativeTypeface != paint.mNativeTypeface) {
-            mTypeface = paint.mTypeface;
-            mNativeTypeface = paint.mNativeTypeface;
-            needsFontUpdate = true;
-        }
-
-        if (mTextSize != paint.mTextSize) {
-            mTextSize = paint.mTextSize;
-            needsFontUpdate = true;
-        }
-
-        if (mTextScaleX != paint.mTextScaleX) {
-            mTextScaleX = paint.mTextScaleX;
-            needsFontUpdate = true;
-        }
-
-        if (mTextSkewX != paint.mTextSkewX) {
-            mTextSkewX = paint.mTextSkewX;
-            needsFontUpdate = true;
-        }
-
-        mStrokeWidth = paint.mStrokeWidth;
-        mStrokeMiter = paint.mStrokeMiter;
-        mPorterDuffMode = paint.mPorterDuffMode;
-        mColorFilter = paint.mColorFilter;
-        mShader = paint.mShader;
-        mPathEffect = paint.mPathEffect;
-        mMaskFilter = paint.mMaskFilter;
-        mHintingMode = paint.mHintingMode;
-
-        if (needsFontUpdate) {
-            updateFontObject();
-        }
-    }
-
-    private void reset() {
-        mFlags = Paint.HIDDEN_DEFAULT_PAINT_FLAGS;
-        mColor = 0xFF000000;
-        mStyle = Paint.Style.FILL.nativeInt;
-        mCap = Paint.Cap.BUTT.nativeInt;
-        mJoin = Paint.Join.MITER.nativeInt;
-        mTextAlign = 0;
-        mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
-        mNativeTypeface = 0;
-        mStrokeWidth = 1.f;
-        mStrokeMiter = 4.f;
-        mTextSize = 20.f;
-        mTextScaleX = 1.f;
-        mTextSkewX = 0.f;
-        mPorterDuffMode = Xfermode.DEFAULT;
-        mColorFilter = null;
-        mShader = null;
-        mPathEffect = null;
-        mMaskFilter = null;
-        updateFontObject();
-        mHintingMode = Paint.HINTING_ON;
-    }
-
-    /**
-     * Update the {@link Font} object from the typeface, text size and scaling
-     */
-    @SuppressWarnings("deprecation")
-    private void updateFontObject() {
-        if (mTypeface != null) {
-            // Get the fonts from the TypeFace object.
-            List<Font> fonts = mTypeface.getFonts(mFontVariant);
-
-            if (fonts.isEmpty()) {
-                mFonts = Collections.emptyList();
-                return;
-            }
-
-            // create new font objects as well as FontMetrics, based on the current text size
-            // and skew info.
-            int nFonts = fonts.size();
-            ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(nFonts);
-            //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
-            for (int i = 0; i < nFonts; i++) {
-                Font font = fonts.get(i);
-                if (font == null) {
-                    // If the font is null, add null to infoList. When rendering the text, if this
-                    // null is reached, a warning will be logged.
-                    infoList.add(null);
-                    continue;
-                }
-                FontInfo info = new FontInfo();
-                info.mFont = font.deriveFont(mTextSize);
-                if (mTextScaleX != 1.0 || mTextSkewX != 0) {
-                    // TODO: support skew
-                    info.mFont = info.mFont.deriveFont(new AffineTransform(
-                            mTextScaleX, mTextSkewX, 0, 1, 0, 0));
-                }
-                // The metrics here don't have anti-aliasing set.
-                info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
-
-                infoList.add(info);
-            }
-
-            mFonts = Collections.unmodifiableList(infoList);
-        }
-    }
-
-    /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
-            int advancesIndex, int bidiFlags) {
-        return new BidiRenderer(null, this, text)
-                .renderText(index, index + count, bidiFlags, advances, advancesIndex, false);
-    }
-
-    /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
-            int advancesIndex, boolean isRtl) {
-        return new BidiRenderer(null, this, text)
-                .renderText(index, index + count, isRtl, advances, advancesIndex, false);
-    }
-
-    private float getFontMetrics(FontMetrics metrics) {
-        if (mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
-            if (metrics != null) {
-                // Android expects negative ascent so we invert the value from Java.
-                metrics.top = - javaMetrics.getMaxAscent();
-                metrics.ascent = - javaMetrics.getAscent();
-                metrics.descent = javaMetrics.getDescent();
-                metrics.bottom = javaMetrics.getMaxDescent();
-                metrics.leading = javaMetrics.getLeading();
-            }
-
-            return javaMetrics.getHeight();
-        }
-
-        return 0;
-    }
-
-    private void setTextLocale(String locale) {
-        mLocale = new Locale(locale);
-    }
-
-    private static void setFlag(long nativePaint, int flagMask, boolean flagValue) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        if (flagValue) {
-            delegate.mFlags |= flagMask;
-        } else {
-            delegate.mFlags &= ~flagMask;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java
deleted file mode 100644
index fd9ba62e..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.PathDashPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of PathDashPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PathDashPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class PathDashPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Path Dash Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long native_path, float advance, float phase,
-            int native_style) {
-        PathDashPathEffect_Delegate newDelegate = new PathDashPathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
deleted file mode 100644
index 000481e..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.PathEffect
- *
- * Through the layoutlib_create tool, the original native methods of PathEffect have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PathEffect class.
- *
- * This also serve as a base class for all PathEffect delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class PathEffect_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<PathEffect_Delegate> sManager =
-            new DelegateManager<PathEffect_Delegate>(PathEffect_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static PathEffect_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public abstract Stroke getStroke(Paint_Delegate paint);
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(long native_patheffect) {
-        sManager.removeJavaReferenceFor(native_patheffect);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathMeasure_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathMeasure_Delegate.java
deleted file mode 100644
index 7f707c9..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PathMeasure_Delegate.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.util.CachedPathIteratorFactory;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import com.android.layoutlib.bridge.util.CachedPathIteratorFactory.CachedPathIterator;
-
-import java.awt.geom.PathIterator;
-
-/**
- * Delegate implementing the native methods of {@link android.graphics.PathMeasure}
- * <p/>
- * Through the layoutlib_create tool, the original native methods of PathMeasure have been
- * replaced by
- * calls to methods of the same name in this delegate class.
- * <p/>
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between it
- * and the original PathMeasure class.
- *
- * @see DelegateManager
- */
-public final class PathMeasure_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<PathMeasure_Delegate> sManager =
-            new DelegateManager<PathMeasure_Delegate>(PathMeasure_Delegate.class);
-
-    // ---- delegate data ----
-    private CachedPathIteratorFactory mOriginalPathIterator;
-
-    private long mNativePath;
-
-
-    private PathMeasure_Delegate(long native_path, boolean forceClosed) {
-        mNativePath = native_path;
-        if (native_path != 0) {
-            if (forceClosed) {
-                // Copy the path and call close
-                native_path = Path_Delegate.nInit(native_path);
-                Path_Delegate.nClose(native_path);
-            }
-
-            Path_Delegate pathDelegate = Path_Delegate.getDelegate(native_path);
-            mOriginalPathIterator = new CachedPathIteratorFactory(pathDelegate.getJavaShape()
-                    .getPathIterator(null));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long native_create(long native_path, boolean forceClosed) {
-        return sManager.addNewDelegate(new PathMeasure_Delegate(native_path, forceClosed));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_destroy(long native_instance) {
-        sManager.removeJavaReferenceFor(native_instance);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_getPosTan(long native_instance, float distance, float pos[],
-            float tan[]) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "PathMeasure.getPostTan is not supported.", null, null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_getMatrix(long native_instance, float distance, long
-            native_matrix, int flags) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "PathMeasure.getMatrix is not supported.", null, null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_nextContour(long native_instance) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "PathMeasure.nextContour is not supported.", null, null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setPath(long native_instance, long native_path, boolean
-            forceClosed) {
-        PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
-        assert pathMeasure != null;
-
-        if (native_path != 0) {
-            if (forceClosed) {
-                // Copy the path and call close
-                native_path = Path_Delegate.nInit(native_path);
-                Path_Delegate.nClose(native_path);
-            }
-
-            Path_Delegate pathDelegate = Path_Delegate.getDelegate(native_path);
-            pathMeasure.mOriginalPathIterator = new CachedPathIteratorFactory(pathDelegate.getJavaShape()
-                    .getPathIterator(null));
-        }
-
-        pathMeasure.mNativePath = native_path;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float native_getLength(long native_instance) {
-        PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
-        assert pathMeasure != null;
-
-        if (pathMeasure.mOriginalPathIterator == null) {
-            return 0;
-        }
-
-        return pathMeasure.mOriginalPathIterator.iterator().getTotalLength();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_isClosed(long native_instance) {
-        PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
-        assert pathMeasure != null;
-
-        Path_Delegate path = Path_Delegate.getDelegate(pathMeasure.mNativePath);
-        if (path == null) {
-            return false;
-        }
-
-        int type = 0;
-        float segment[] = new float[6];
-        for (PathIterator pi = path.getJavaShape().getPathIterator(null); !pi.isDone(); pi.next()) {
-            type = pi.currentSegment(segment);
-        }
-
-        // A path is a closed path if the last element is SEG_CLOSE
-        return type == PathIterator.SEG_CLOSE;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_getSegment(long native_instance, float startD, float stopD,
-            long native_dst_path, boolean startWithMoveTo) {
-        if (startD < 0) {
-            startD = 0;
-        }
-
-        if (startD >= stopD) {
-            return false;
-        }
-
-        PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
-        assert pathMeasure != null;
-
-        CachedPathIterator iterator = pathMeasure.mOriginalPathIterator.iterator();
-        float accLength = startD;
-        boolean isZeroLength = true; // Whether the output has zero length or not
-        float[] points = new float[6];
-
-        iterator.jumpToSegment(accLength);
-        while (!iterator.isDone() && (stopD - accLength > 0.1f)) {
-            int type = iterator.currentSegment(points, stopD - accLength);
-
-            if (accLength - iterator.getCurrentSegmentLength() <= stopD) {
-                if (startWithMoveTo) {
-                    startWithMoveTo = false;
-
-                    // If this segment is a MOVETO, then we just use that one. If not, then we issue
-                    // a first moveto
-                    if (type != PathIterator.SEG_MOVETO) {
-                        float[] lastPoint = new float[2];
-                        iterator.getCurrentSegmentEnd(lastPoint);
-                        Path_Delegate.nMoveTo(native_dst_path, lastPoint[0], lastPoint[1]);
-                    }
-                }
-
-                isZeroLength = isZeroLength && iterator.getCurrentSegmentLength() > 0;
-                switch (type) {
-                    case PathIterator.SEG_MOVETO:
-                        Path_Delegate.nMoveTo(native_dst_path, points[0], points[1]);
-                        break;
-                    case PathIterator.SEG_LINETO:
-                        Path_Delegate.nLineTo(native_dst_path, points[0], points[1]);
-                        break;
-                    case PathIterator.SEG_CLOSE:
-                        Path_Delegate.nClose(native_dst_path);
-                        break;
-                    case PathIterator.SEG_CUBICTO:
-                        Path_Delegate.nCubicTo(native_dst_path, points[0], points[1],
-                                points[2], points[3],
-                                points[4], points[5]);
-                        break;
-                    case PathIterator.SEG_QUADTO:
-                        Path_Delegate.nQuadTo(native_dst_path, points[0], points[1],
-                                points[2],
-                                points[3]);
-                        break;
-                    default:
-                        assert false;
-                }
-            }
-
-            accLength += iterator.getCurrentSegmentLength();
-            iterator.next();
-        }
-
-        return !isZeroLength;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
deleted file mode 100644
index 50b9165..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ /dev/null
@@ -1,896 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.graphics.Path.Direction;
-import android.graphics.Path.FillType;
-
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Arc2D;
-import java.awt.geom.Area;
-import java.awt.geom.Ellipse2D;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.Path2D;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.RoundRectangle2D;
-import java.util.ArrayList;
-
-/**
- * Delegate implementing the native methods of android.graphics.Path
- *
- * Through the layoutlib_create tool, the original native methods of Path have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Path class.
- *
- * @see DelegateManager
- *
- */
-public final class Path_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Path_Delegate> sManager =
-            new DelegateManager<Path_Delegate>(Path_Delegate.class);
-
-    private static final float EPSILON = 1e-4f;
-
-    // ---- delegate data ----
-    private FillType mFillType = FillType.WINDING;
-    private Path2D mPath = new Path2D.Double();
-
-    private float mLastX = 0;
-    private float mLastY = 0;
-
-    // true if the path contains does not contain a curve or line.
-    private boolean mCachedIsEmpty = true;
-
-    // ---- Public Helper methods ----
-
-    public static Path_Delegate getDelegate(long nPath) {
-        return sManager.getDelegate(nPath);
-    }
-
-    public Path2D getJavaShape() {
-        return mPath;
-    }
-
-    public void setJavaShape(Shape shape) {
-        reset();
-        mPath.append(shape, false /*connect*/);
-    }
-
-    public void reset() {
-        mPath.reset();
-        mLastX = 0;
-        mLastY = 0;
-    }
-
-    public void setPathIterator(PathIterator iterator) {
-        reset();
-        mPath.append(iterator, false /*connect*/);
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nInit() {
-        // create the delegate
-        Path_Delegate newDelegate = new Path_Delegate();
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nInit(long nPath) {
-        // create the delegate
-        Path_Delegate newDelegate = new Path_Delegate();
-
-        // get the delegate to copy, which could be null if nPath is 0
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate != null) {
-            newDelegate.set(pathDelegate);
-        }
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReset(long nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.reset();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRewind(long nPath) {
-        // call out to reset since there's nothing to optimize in
-        // terms of data structs.
-        nReset(nPath);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSet(long native_dst, long nSrc) {
-        Path_Delegate pathDstDelegate = sManager.getDelegate(native_dst);
-        if (pathDstDelegate == null) {
-            return;
-        }
-
-        Path_Delegate pathSrcDelegate = sManager.getDelegate(nSrc);
-        if (pathSrcDelegate == null) {
-            return;
-        }
-
-        pathDstDelegate.set(pathSrcDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsConvex(long nPath) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Path.isConvex is not supported.", null, null);
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetFillType(long nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return 0;
-        }
-
-        return pathDelegate.mFillType.nativeInt;
-    }
-
-    @LayoutlibDelegate
-    public static void nSetFillType(long nPath, int ft) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.setFillType(Path.sFillTypeArray[ft]);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsEmpty(long nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        return pathDelegate == null || pathDelegate.isEmpty();
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsRect(long nPath, RectF rect) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return false;
-        }
-
-        // create an Area that can test if the path is a rect
-        Area area = new Area(pathDelegate.mPath);
-        if (area.isRectangular()) {
-            if (rect != null) {
-                pathDelegate.fillBounds(rect);
-            }
-
-            return true;
-        }
-
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nComputeBounds(long nPath, RectF bounds) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.fillBounds(bounds);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nIncReserve(long nPath, int extraPtCount) {
-        // since we use a java2D path, there's no way to pre-allocate new points,
-        // so we do nothing.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nMoveTo(long nPath, float x, float y) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.moveTo(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRMoveTo(long nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rMoveTo(dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nLineTo(long nPath, float x, float y) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.lineTo(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRLineTo(long nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rLineTo(dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nQuadTo(long nPath, float x1, float y1, float x2, float y2) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.quadTo(x1, y1, x2, y2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRQuadTo(long nPath, float dx1, float dy1, float dx2, float dy2) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rQuadTo(dx1, dy1, dx2, dy2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCubicTo(long nPath, float x1, float y1,
-            float x2, float y2, float x3, float y3) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.cubicTo(x1, y1, x2, y2, x3, y3);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRCubicTo(long nPath, float x1, float y1,
-            float x2, float y2, float x3, float y3) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rCubicTo(x1, y1, x2, y2, x3, y3);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nArcTo(long nPath, float left, float top, float right,
-            float bottom,
-                    float startAngle, float sweepAngle, boolean forceMoveTo) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.arcTo(left, top, right, bottom, startAngle, sweepAngle, forceMoveTo);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nClose(long nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.close();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddRect(long nPath,
-            float left, float top, float right, float bottom, int dir) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.addRect(left, top, right, bottom, dir);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddOval(long nPath, float left, float top, float right,
-            float bottom, int dir) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.mPath.append(new Ellipse2D.Float(
-                left, top, right - left, bottom - top), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddCircle(long nPath, float x, float y, float radius, int dir) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        // because x/y is the center of the circle, need to offset this by the radius
-        pathDelegate.mPath.append(new Ellipse2D.Float(
-                x - radius, y - radius, radius * 2, radius * 2), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddArc(long nPath, float left, float top, float right,
-            float bottom, float startAngle, float sweepAngle) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        // because x/y is the center of the circle, need to offset this by the radius
-        pathDelegate.mPath.append(new Arc2D.Float(
-                left, top, right - left, bottom - top,
-                -startAngle, -sweepAngle, Arc2D.OPEN), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddRoundRect(long nPath, float left, float top, float right,
-            float bottom, float rx, float ry, int dir) {
-
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.mPath.append(new RoundRectangle2D.Float(
-                left, top, right - left, bottom - top, rx * 2, ry * 2), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddRoundRect(long nPath, float left, float top, float right,
-            float bottom, float[] radii, int dir) {
-
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        float[] cornerDimensions = new float[radii.length];
-        for (int i = 0; i < radii.length; i++) {
-            cornerDimensions[i] = 2 * radii[i];
-        }
-        pathDelegate.mPath.append(new RoundRectangle(left, top, right - left, bottom - top,
-                cornerDimensions), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddPath(long nPath, long src, float dx, float dy) {
-        addPath(nPath, src, AffineTransform.getTranslateInstance(dx, dy));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddPath(long nPath, long src) {
-        addPath(nPath, src, null /*transform*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddPath(long nPath, long src, long matrix) {
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        addPath(nPath, src, matrixDelegate.getAffineTransform());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nOffset(long nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.offset(dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetLastPoint(long nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.mLastX = dx;
-        pathDelegate.mLastY = dy;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nTransform(long nPath, long matrix,
-                                                long dst_path) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        // this can be null if dst_path is 0
-        Path_Delegate dstDelegate = sManager.getDelegate(dst_path);
-
-        pathDelegate.transform(matrixDelegate, dstDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nTransform(long nPath, long matrix) {
-        nTransform(nPath, matrix, 0);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nOp(long nPath1, long nPath2, int op, long result) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.op() not supported", null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFinalize(long nPath) {
-        sManager.removeJavaReferenceFor(nPath);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float[] nApproximate(long nPath, float error) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return null;
-        }
-        // Get a FlatteningIterator
-        PathIterator iterator = pathDelegate.getJavaShape().getPathIterator(null, error);
-
-        float segment[] = new float[6];
-        float totalLength = 0;
-        ArrayList<Point2D.Float> points = new ArrayList<Point2D.Float>();
-        Point2D.Float previousPoint = null;
-        while (!iterator.isDone()) {
-            int type = iterator.currentSegment(segment);
-            Point2D.Float currentPoint = new Point2D.Float(segment[0], segment[1]);
-            // MoveTo shouldn't affect the length
-            if (previousPoint != null && type != PathIterator.SEG_MOVETO) {
-                totalLength += currentPoint.distance(previousPoint);
-            }
-            previousPoint = currentPoint;
-            points.add(currentPoint);
-            iterator.next();
-        }
-
-        int nPoints = points.size();
-        float[] result = new float[nPoints * 3];
-        previousPoint = null;
-        for (int i = 0; i < nPoints; i++) {
-            Point2D.Float point = points.get(i);
-            float distance = previousPoint != null ? (float) previousPoint.distance(point) : .0f;
-            result[i * 3] = distance / totalLength;
-            result[i * 3 + 1] = point.x;
-            result[i * 3 + 2] = point.y;
-
-            totalLength += distance;
-            previousPoint = point;
-        }
-
-        return result;
-    }
-
-    // ---- Private helper methods ----
-
-    private void set(Path_Delegate delegate) {
-        mPath.reset();
-        setFillType(delegate.mFillType);
-        mPath.append(delegate.mPath, false /*connect*/);
-    }
-
-    private void setFillType(FillType fillType) {
-        mFillType = fillType;
-        mPath.setWindingRule(getWindingRule(fillType));
-    }
-
-    /**
-     * Returns the Java2D winding rules matching a given Android {@link FillType}.
-     * @param type the android fill type
-     * @return the matching java2d winding rule.
-     */
-    private static int getWindingRule(FillType type) {
-        switch (type) {
-            case WINDING:
-            case INVERSE_WINDING:
-                return GeneralPath.WIND_NON_ZERO;
-            case EVEN_ODD:
-            case INVERSE_EVEN_ODD:
-                return GeneralPath.WIND_EVEN_ODD;
-
-            default:
-                assert false;
-                return GeneralPath.WIND_NON_ZERO;
-        }
-    }
-
-    @NonNull
-    private static Direction getDirection(int direction) {
-        for (Direction d : Direction.values()) {
-            if (direction == d.nativeInt) {
-                return d;
-            }
-        }
-
-        assert false;
-        return null;
-    }
-
-    public static void addPath(long destPath, long srcPath, AffineTransform transform) {
-        Path_Delegate destPathDelegate = sManager.getDelegate(destPath);
-        if (destPathDelegate == null) {
-            return;
-        }
-
-        Path_Delegate srcPathDelegate = sManager.getDelegate(srcPath);
-        if (srcPathDelegate == null) {
-            return;
-        }
-
-        if (transform != null) {
-            destPathDelegate.mPath.append(
-                    srcPathDelegate.mPath.getPathIterator(transform), false);
-        } else {
-            destPathDelegate.mPath.append(srcPathDelegate.mPath, false);
-        }
-    }
-
-
-    /**
-     * Returns whether the path already contains any points.
-     * Note that this is different to
-     * {@link #isEmpty} because if all elements are {@link PathIterator#SEG_MOVETO},
-     * {@link #isEmpty} will return true while hasPoints will return false.
-     */
-    public boolean hasPoints() {
-        return !mPath.getPathIterator(null).isDone();
-    }
-
-    /**
-     * Returns whether the path is empty (contains no lines or curves).
-     * @see Path#isEmpty
-     */
-    public boolean isEmpty() {
-        if (!mCachedIsEmpty) {
-            return false;
-        }
-
-        float[] coords = new float[6];
-        mCachedIsEmpty = Boolean.TRUE;
-        for (PathIterator it = mPath.getPathIterator(null); !it.isDone(); it.next()) {
-            int type = it.currentSegment(coords);
-            if (type != PathIterator.SEG_MOVETO) {
-                // Once we know that the path is not empty, we do not need to check again unless
-                // Path#reset is called.
-                mCachedIsEmpty = false;
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Fills the given {@link RectF} with the path bounds.
-     * @param bounds the RectF to be filled.
-     */
-    public void fillBounds(RectF bounds) {
-        Rectangle2D rect = mPath.getBounds2D();
-        bounds.left = (float)rect.getMinX();
-        bounds.right = (float)rect.getMaxX();
-        bounds.top = (float)rect.getMinY();
-        bounds.bottom = (float)rect.getMaxY();
-    }
-
-    /**
-     * Set the beginning of the next contour to the point (x,y).
-     *
-     * @param x The x-coordinate of the start of a new contour
-     * @param y The y-coordinate of the start of a new contour
-     */
-    public void moveTo(float x, float y) {
-        mPath.moveTo(mLastX = x, mLastY = y);
-    }
-
-    /**
-     * Set the beginning of the next contour relative to the last point on the
-     * previous contour. If there is no previous contour, this is treated the
-     * same as moveTo().
-     *
-     * @param dx The amount to add to the x-coordinate of the end of the
-     *           previous contour, to specify the start of a new contour
-     * @param dy The amount to add to the y-coordinate of the end of the
-     *           previous contour, to specify the start of a new contour
-     */
-    public void rMoveTo(float dx, float dy) {
-        dx += mLastX;
-        dy += mLastY;
-        mPath.moveTo(mLastX = dx, mLastY = dy);
-    }
-
-    /**
-     * Add a line from the last point to the specified point (x,y).
-     * If no moveTo() call has been made for this contour, the first point is
-     * automatically set to (0,0).
-     *
-     * @param x The x-coordinate of the end of a line
-     * @param y The y-coordinate of the end of a line
-     */
-    public void lineTo(float x, float y) {
-        if (!hasPoints()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        mPath.lineTo(mLastX = x, mLastY = y);
-    }
-
-    /**
-     * Same as lineTo, but the coordinates are considered relative to the last
-     * point on this contour. If there is no previous point, then a moveTo(0,0)
-     * is inserted automatically.
-     *
-     * @param dx The amount to add to the x-coordinate of the previous point on
-     *           this contour, to specify a line
-     * @param dy The amount to add to the y-coordinate of the previous point on
-     *           this contour, to specify a line
-     */
-    public void rLineTo(float dx, float dy) {
-        if (!hasPoints()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-
-        if (Math.abs(dx) < EPSILON && Math.abs(dy) < EPSILON) {
-            // The delta is so small that this shouldn't generate a line
-            return;
-        }
-
-        dx += mLastX;
-        dy += mLastY;
-        mPath.lineTo(mLastX = dx, mLastY = dy);
-    }
-
-    /**
-     * Add a quadratic bezier from the last point, approaching control point
-     * (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
-     * this contour, the first point is automatically set to (0,0).
-     *
-     * @param x1 The x-coordinate of the control point on a quadratic curve
-     * @param y1 The y-coordinate of the control point on a quadratic curve
-     * @param x2 The x-coordinate of the end point on a quadratic curve
-     * @param y2 The y-coordinate of the end point on a quadratic curve
-     */
-    public void quadTo(float x1, float y1, float x2, float y2) {
-        mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2);
-    }
-
-    /**
-     * Same as quadTo, but the coordinates are considered relative to the last
-     * point on this contour. If there is no previous point, then a moveTo(0,0)
-     * is inserted automatically.
-     *
-     * @param dx1 The amount to add to the x-coordinate of the last point on
-     *            this contour, for the control point of a quadratic curve
-     * @param dy1 The amount to add to the y-coordinate of the last point on
-     *            this contour, for the control point of a quadratic curve
-     * @param dx2 The amount to add to the x-coordinate of the last point on
-     *            this contour, for the end point of a quadratic curve
-     * @param dy2 The amount to add to the y-coordinate of the last point on
-     *            this contour, for the end point of a quadratic curve
-     */
-    public void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
-        if (!hasPoints()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx1 += mLastX;
-        dy1 += mLastY;
-        dx2 += mLastX;
-        dy2 += mLastY;
-        mPath.quadTo(dx1, dy1, mLastX = dx2, mLastY = dy2);
-    }
-
-    /**
-     * Add a cubic bezier from the last point, approaching control points
-     * (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
-     * made for this contour, the first point is automatically set to (0,0).
-     *
-     * @param x1 The x-coordinate of the 1st control point on a cubic curve
-     * @param y1 The y-coordinate of the 1st control point on a cubic curve
-     * @param x2 The x-coordinate of the 2nd control point on a cubic curve
-     * @param y2 The y-coordinate of the 2nd control point on a cubic curve
-     * @param x3 The x-coordinate of the end point on a cubic curve
-     * @param y3 The y-coordinate of the end point on a cubic curve
-     */
-    public void cubicTo(float x1, float y1, float x2, float y2,
-                        float x3, float y3) {
-        if (!hasPoints()) {
-            mPath.moveTo(0, 0);
-        }
-        mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
-    }
-
-    /**
-     * Same as cubicTo, but the coordinates are considered relative to the
-     * current point on this contour. If there is no previous point, then a
-     * moveTo(0,0) is inserted automatically.
-     */
-    public void rCubicTo(float dx1, float dy1, float dx2, float dy2,
-                         float dx3, float dy3) {
-        if (!hasPoints()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx1 += mLastX;
-        dy1 += mLastY;
-        dx2 += mLastX;
-        dy2 += mLastY;
-        dx3 += mLastX;
-        dy3 += mLastY;
-        mPath.curveTo(dx1, dy1, dx2, dy2, mLastX = dx3, mLastY = dy3);
-    }
-
-    /**
-     * Append the specified arc to the path as a new contour. If the start of
-     * the path is different from the path's current last point, then an
-     * automatic lineTo() is added to connect the current contour to the
-     * start of the arc. However, if the path is empty, then we call moveTo()
-     * with the first point of the arc. The sweep angle is tread mod 360.
-     *
-     * @param left        The left of oval defining shape and size of the arc
-     * @param top         The top of oval defining shape and size of the arc
-     * @param right       The right of oval defining shape and size of the arc
-     * @param bottom      The bottom of oval defining shape and size of the arc
-     * @param startAngle  Starting angle (in degrees) where the arc begins
-     * @param sweepAngle  Sweep angle (in degrees) measured clockwise, treated
-     *                    mod 360.
-     * @param forceMoveTo If true, always begin a new contour with the arc
-     */
-    public void arcTo(float left, float top, float right, float bottom, float startAngle,
-            float sweepAngle,
-            boolean forceMoveTo) {
-        Arc2D arc = new Arc2D.Float(left, top, right - left, bottom - top, -startAngle,
-                -sweepAngle, Arc2D.OPEN);
-        mPath.append(arc, true /*connect*/);
-
-        resetLastPointFromPath();
-    }
-
-    /**
-     * Close the current contour. If the current point is not equal to the
-     * first point of the contour, a line segment is automatically added.
-     */
-    public void close() {
-        mPath.closePath();
-    }
-
-    private void resetLastPointFromPath() {
-        Point2D last = mPath.getCurrentPoint();
-        mLastX = (float) last.getX();
-        mLastY = (float) last.getY();
-    }
-
-    /**
-     * Add a closed rectangle contour to the path
-     *
-     * @param left   The left side of a rectangle to add to the path
-     * @param top    The top of a rectangle to add to the path
-     * @param right  The right side of a rectangle to add to the path
-     * @param bottom The bottom of a rectangle to add to the path
-     * @param dir    The direction to wind the rectangle's contour
-     */
-    public void addRect(float left, float top, float right, float bottom,
-                        int dir) {
-        moveTo(left, top);
-
-        Direction direction = getDirection(dir);
-
-        switch (direction) {
-            case CW:
-                lineTo(right, top);
-                lineTo(right, bottom);
-                lineTo(left, bottom);
-                break;
-            case CCW:
-                lineTo(left, bottom);
-                lineTo(right, bottom);
-                lineTo(right, top);
-                break;
-        }
-
-        close();
-
-        resetLastPointFromPath();
-    }
-
-    /**
-     * Offset the path by (dx,dy), returning true on success
-     *
-     * @param dx  The amount in the X direction to offset the entire path
-     * @param dy  The amount in the Y direction to offset the entire path
-     */
-    public void offset(float dx, float dy) {
-        GeneralPath newPath = new GeneralPath();
-
-        PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
-
-        newPath.append(iterator, false /*connect*/);
-        mPath = newPath;
-    }
-
-    /**
-     * Transform the points in this path by matrix, and write the answer
-     * into dst. If dst is null, then the the original path is modified.
-     *
-     * @param matrix The matrix to apply to the path
-     * @param dst    The transformed path is written here. If dst is null,
-     *               then the the original path is modified
-     */
-    public void transform(Matrix_Delegate matrix, Path_Delegate dst) {
-        if (matrix.hasPerspective()) {
-            assert false;
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
-                    "android.graphics.Path#transform() only " +
-                    "supports affine transformations.", null, null /*data*/);
-        }
-
-        GeneralPath newPath = new GeneralPath();
-
-        PathIterator iterator = mPath.getPathIterator(matrix.getAffineTransform());
-
-        newPath.append(iterator, false /*connect*/);
-
-        if (dst != null) {
-            dst.mPath = newPath;
-        } else {
-            mPath = newPath;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
deleted file mode 100644
index ff3f19f..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.PorterDuff.Mode;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-
-import static com.android.layoutlib.bridge.impl.PorterDuffUtility.getComposite;
-import static com.android.layoutlib.bridge.impl.PorterDuffUtility.getPorterDuffMode;
-
-/**
- * Delegate implementing the native methods of android.graphics.PorterDuffColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of PorterDuffColorFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PorterDuffColorFilter class.
- *
- * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link ColorFilter_Delegate}.
- *
- * @see ColorFilter_Delegate
- *
- */
-public class PorterDuffColorFilter_Delegate extends ColorFilter_Delegate {
-
-    // ---- delegate data ----
-
-    private final java.awt.Color mSrcColor;
-    private final Mode mMode;
-
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "PorterDuff Color Filter is not supported for mode: " + mMode.name() + ".";
-    }
-
-    @Override
-    public void applyFilter(Graphics2D g, int width, int height) {
-        g.setComposite(getComposite(mMode, 0xFF));
-        g.setColor(mSrcColor);
-        g.fillRect(0, 0, width, height);
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long native_CreatePorterDuffFilter(int srcColor, int porterDuffMode) {
-        PorterDuffColorFilter_Delegate newDelegate =
-                new PorterDuffColorFilter_Delegate(srcColor, porterDuffMode);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-
-    // ---- Private delegate/helper methods ----
-
-    private PorterDuffColorFilter_Delegate(int srcColor, int mode) {
-        mSrcColor = new java.awt.Color(srcColor, true /* hasAlpha */);
-        mMode = getCompatibleMode(getPorterDuffMode(mode));
-    }
-
-    // For filtering the colors, the src image should contain the "color" only for pixel values
-    // which are not transparent in the target image. But, we are using a simple rectangular image
-    // completely filled with color. Hence some Composite rules do not apply as intended. However,
-    // in such cases, they can usually be mapped to some other mode, which produces an approximately
-    // equivalent result.
-    private Mode getCompatibleMode(Mode mode) {
-        Mode m = mode;
-        // Modes that are directly supported:
-        // CLEAR, DST, SRC_IN, DST_IN, DST_OUT, SRC_ATOP, DARKEN, LIGHTEN, MULTIPLY, SCREEN,
-        // ADD, OVERLAY
-        switch (mode) {
-        // Modes that can be mapped to one of the supported modes.
-        case SRC:
-            m = Mode.SRC_IN;
-            break;
-        case SRC_OVER:
-            m = Mode.SRC_ATOP;
-            break;
-        case DST_OVER:
-            m = Mode.DST;
-            break;
-        case SRC_OUT:
-            m = Mode.CLEAR;
-            break;
-        case DST_ATOP:
-            m = Mode.DST_IN;
-            break;
-        case XOR:
-            m = Mode.DST_OUT;
-            break;
-        }
-        return m;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
deleted file mode 100644
index b5ba468..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-import java.awt.image.ColorModel;
-
-/**
- * Delegate implementing the native methods of android.graphics.RadialGradient
- *
- * Through the layoutlib_create tool, the original native methods of RadialGradient have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original RadialGradient class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class RadialGradient_Delegate extends Gradient_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate1(long matrix, float x, float y, float radius,
-            int colors[], float positions[], int tileMode) {
-        RadialGradient_Delegate newDelegate = new RadialGradient_Delegate(matrix, x, y, radius,
-                colors, positions, Shader_Delegate.getTileMode(tileMode));
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate2(long matrix, float x, float y, float radius,
-            int color0, int color1, int tileMode) {
-        return nativeCreate1(matrix, x, y, radius, new int[] { color0, color1 },
-                null /*positions*/, tileMode);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * Create a shader that draws a radial gradient given the center and radius.
-     *
-     * @param nativeMatrix reference to the shader's native transformation matrix
-     * @param x The x-coordinate of the center of the radius
-     * @param y The y-coordinate of the center of the radius
-     * @param radius Must be positive. The radius of the circle for this
-     *            gradient
-     * @param colors The colors to be distributed between the center and edge of
-     *            the circle
-     * @param positions May be NULL. The relative position of each corresponding
-     *            color in the colors array. If this is NULL, the the colors are
-     *            distributed evenly between the center and edge of the circle.
-     * @param tile The Shader tiling mode
-     */
-    private RadialGradient_Delegate(long nativeMatrix, float x, float y, float radius,
-            int colors[], float positions[], TileMode tile) {
-        super(nativeMatrix, colors, positions);
-        mJavaPaint = new RadialGradientPaint(x, y, radius, mColors, mPositions, tile);
-    }
-
-    private class RadialGradientPaint extends GradientPaint {
-
-        private final float mX;
-        private final float mY;
-        private final float mRadius;
-
-        public RadialGradientPaint(float x, float y, float radius,
-                int[] colors, float[] positions, TileMode mode) {
-            super(colors, positions, mode);
-            mX = x;
-            mY = y;
-            mRadius = radius;
-        }
-
-        @Override
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel     colorModel,
-                java.awt.Rectangle            deviceBounds,
-                java.awt.geom.Rectangle2D     userBounds,
-                java.awt.geom.AffineTransform xform,
-                java.awt.RenderingHints       hints) {
-            precomputeGradientColors();
-
-            java.awt.geom.AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in RadialGradient", e, null /*data*/);
-                canvasMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in RadialGradient", e, null /*data*/);
-                localMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            return new RadialGradientPaintContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class RadialGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.geom.AffineTransform mCanvasMatrix;
-            private final java.awt.geom.AffineTransform mLocalMatrix;
-            private final java.awt.image.ColorModel mColorModel;
-
-            public RadialGradientPaintContext(
-                    java.awt.geom.AffineTransform canvasMatrix,
-                    java.awt.geom.AffineTransform localMatrix,
-                    java.awt.image.ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel.hasAlpha() ? colorModel : ColorModel.getRGBdefault();
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
-                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
-                    mColorModel.isAlphaPremultiplied(), null);
-
-                int[] data = new int[w*h];
-
-                // compute distance from each point to the center, and figure out the distance from
-                // it.
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix
-                        pt1[0] = pt2[0] - mX;
-                        pt1[1] = pt2[1] - mY;
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        float _x = pt2[0];
-                        float _y = pt2[1];
-                        float distance = (float) Math.hypot(_x, _y);
-
-                        data[index++] = getGradientColor(distance / mRadius);
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-
-        }
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
deleted file mode 100644
index edb7025..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.os.Parcel;
-
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Area;
-import java.awt.geom.Rectangle2D;
-
-/**
- * Delegate implementing the native methods of android.graphics.Region
- *
- * Through the layoutlib_create tool, the original native methods of Region have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Region class.
- *
- * This also serve as a base class for all Region delegate classes.
- *
- * @see DelegateManager
- *
- */
-public class Region_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<Region_Delegate> sManager =
-            new DelegateManager<Region_Delegate>(Region_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-    private Area mArea = new Area();
-
-    // ---- Public Helper methods ----
-
-    public static Region_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public Area getJavaArea() {
-        return mArea;
-    }
-
-    /**
-     * Combines two {@link Shape} into another one (actually an {@link Area}), according
-     * to the given {@link Region.Op}.
-     *
-     * If the Op is not one that combines two shapes, then this return null
-     *
-     * @param shape1 the firt shape to combine which can be null if there's no original clip.
-     * @param shape2 the 2nd shape to combine
-     * @param regionOp the operande for the combine
-     * @return a new area or null.
-     */
-    public static Area combineShapes(Shape shape1, Shape shape2, int regionOp) {
-        if (regionOp == Region.Op.DIFFERENCE.nativeInt) {
-            // if shape1 is null (empty), then the result is null.
-            if (shape1 == null) {
-                return null;
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.subtract(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.INTERSECT.nativeInt) {
-            // if shape1 is null, then the result is simply shape2.
-            if (shape1 == null) {
-                return new Area(shape2);
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.intersect(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.UNION.nativeInt) {
-            // if shape1 is null, then the result is simply shape2.
-            if (shape1 == null) {
-                return new Area(shape2);
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.add(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.XOR.nativeInt) {
-            // if shape1 is null, then the result is simply shape2
-            if (shape1 == null) {
-                return new Area(shape2);
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.exclusiveOr(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.REVERSE_DIFFERENCE.nativeInt) {
-            // result is always a new area.
-            Area result = new Area(shape2);
-
-            if (shape1 != null) {
-                result.subtract(shape1 instanceof Area ? (Area) shape1 : new Area(shape1));
-            }
-
-            return result;
-        }
-
-        return null;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isEmpty(Region thisRegion) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return true;
-        }
-
-        return regionDelegate.mArea.isEmpty();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isRect(Region thisRegion) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return true;
-        }
-
-        return regionDelegate.mArea.isRectangular();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isComplex(Region thisRegion) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return true;
-        }
-
-        return regionDelegate.mArea.isSingular() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean contains(Region thisRegion, int x, int y) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.contains(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean quickContains(Region thisRegion,
-            int left, int top, int right, int bottom) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.isRectangular() &&
-                regionDelegate.mArea.contains(left, top, right - left, bottom - top);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean quickReject(Region thisRegion,
-            int left, int top, int right, int bottom) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.isEmpty() ||
-                regionDelegate.mArea.intersects(left, top, right - left, bottom - top) == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean quickReject(Region thisRegion, Region rgn) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        Region_Delegate targetRegionDelegate = sManager.getDelegate(rgn.mNativeRegion);
-        if (targetRegionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.isEmpty() ||
-                regionDelegate.mArea.getBounds().intersects(
-                        targetRegionDelegate.mArea.getBounds()) == false;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void translate(Region thisRegion, int dx, int dy, Region dst) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return;
-        }
-
-        Region_Delegate targetRegionDelegate = sManager.getDelegate(dst.mNativeRegion);
-        if (targetRegionDelegate == null) {
-            return;
-        }
-
-        if (regionDelegate.mArea.isEmpty()) {
-            targetRegionDelegate.mArea = new Area();
-        } else {
-            targetRegionDelegate.mArea = new Area(regionDelegate.mArea);
-            AffineTransform mtx = new AffineTransform();
-            mtx.translate(dx, dy);
-            targetRegionDelegate.mArea.transform(mtx);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void scale(Region thisRegion, float scale, Region dst) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return;
-        }
-
-        Region_Delegate targetRegionDelegate = sManager.getDelegate(dst.mNativeRegion);
-        if (targetRegionDelegate == null) {
-            return;
-        }
-
-        if (regionDelegate.mArea.isEmpty()) {
-            targetRegionDelegate.mArea = new Area();
-        } else {
-            targetRegionDelegate.mArea = new Area(regionDelegate.mArea);
-            AffineTransform mtx = new AffineTransform();
-            mtx.scale(scale, scale);
-            targetRegionDelegate.mArea.transform(mtx);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeConstructor() {
-        Region_Delegate newDelegate = new Region_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(long native_region) {
-        sManager.removeJavaReferenceFor(native_region);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetRegion(long native_dst, long native_src) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return;
-        }
-
-        Region_Delegate srcRegion = sManager.getDelegate(native_src);
-        if (srcRegion == null) {
-            return;
-        }
-
-        dstRegion.mArea.reset();
-        dstRegion.mArea.add(srcRegion.mArea);
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeSetRect(long native_dst,
-            int left, int top, int right, int bottom) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return true;
-        }
-
-        dstRegion.mArea = new Area(new Rectangle2D.Float(left, top, right - left, bottom - top));
-        return dstRegion.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeSetPath(long native_dst, long native_path, long native_clip) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return true;
-        }
-
-        Path_Delegate path = Path_Delegate.getDelegate(native_path);
-        if (path == null) {
-            return true;
-        }
-
-        dstRegion.mArea = new Area(path.getJavaShape());
-
-        Region_Delegate clip = sManager.getDelegate(native_clip);
-        if (clip != null) {
-            dstRegion.mArea.subtract(clip.getJavaArea());
-        }
-
-        return dstRegion.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeGetBounds(long native_region, Rect rect) {
-        Region_Delegate region = sManager.getDelegate(native_region);
-        if (region == null) {
-            return true;
-        }
-
-        Rectangle bounds = region.mArea.getBounds();
-        if (bounds.isEmpty()) {
-            rect.left = rect.top = rect.right = rect.bottom = 0;
-            return false;
-        }
-
-        rect.left = bounds.x;
-        rect.top = bounds.y;
-        rect.right = bounds.x + bounds.width;
-        rect.bottom = bounds.y + bounds.height;
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeGetBoundaryPath(long native_region, long native_path) {
-        Region_Delegate region = sManager.getDelegate(native_region);
-        if (region == null) {
-            return false;
-        }
-
-        Path_Delegate path = Path_Delegate.getDelegate(native_path);
-        if (path == null) {
-            return false;
-        }
-
-        if (region.mArea.isEmpty()) {
-            path.reset();
-            return false;
-        }
-
-        path.setPathIterator(region.mArea.getPathIterator(new AffineTransform()));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeOp(long native_dst,
-            int left, int top, int right, int bottom, int op) {
-        Region_Delegate region = sManager.getDelegate(native_dst);
-        if (region == null) {
-            return false;
-        }
-
-        region.mArea = combineShapes(region.mArea,
-                new Rectangle2D.Float(left, top, right - left, bottom - top), op);
-
-        assert region.mArea != null;
-        if (region.mArea != null) {
-            region.mArea = new Area();
-        }
-
-        return region.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeOp(long native_dst, Rect rect, long native_region, int op) {
-        Region_Delegate region = sManager.getDelegate(native_dst);
-        if (region == null) {
-            return false;
-        }
-
-        region.mArea = combineShapes(region.mArea,
-                new Rectangle2D.Float(rect.left, rect.top, rect.width(), rect.height()), op);
-
-        assert region.mArea != null;
-        if (region.mArea != null) {
-            region.mArea = new Area();
-        }
-
-        return region.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeOp(long native_dst,
-            long native_region1, long native_region2, int op) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return true;
-        }
-
-        Region_Delegate region1 = sManager.getDelegate(native_region1);
-        if (region1 == null) {
-            return false;
-        }
-
-        Region_Delegate region2 = sManager.getDelegate(native_region2);
-        if (region2 == null) {
-            return false;
-        }
-
-        dstRegion.mArea = combineShapes(region1.mArea, region2.mArea, op);
-
-        assert dstRegion.mArea != null;
-        if (dstRegion.mArea != null) {
-            dstRegion.mArea = new Area();
-        }
-
-        return dstRegion.mArea.getBounds().isEmpty() == false;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreateFromParcel(Parcel p) {
-        // This is only called by Region.CREATOR (Parcelable.Creator<Region>), which is only
-        // used during aidl call so really this should not be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Regions cannot be created from parcels.",
-                null /*data*/);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeWriteToParcel(long native_region,
-                                                      Parcel p) {
-        // This is only called when sending a region through aidl, so really this should not
-        // be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Regions cannot be written to parcels.",
-                null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeEquals(long native_r1, long native_r2) {
-        Region_Delegate region1 = sManager.getDelegate(native_r1);
-        if (region1 == null) {
-            return false;
-        }
-
-        Region_Delegate region2 = sManager.getDelegate(native_r2);
-        if (region2 == null) {
-            return false;
-        }
-
-        return region1.mArea.equals(region2.mArea);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String nativeToString(long native_region) {
-        Region_Delegate region = sManager.getDelegate(native_region);
-        if (region == null) {
-            return "not found";
-        }
-
-        return region.mArea.toString();
-    }
-
-    // ---- Private delegate/helper methods ----
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java b/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java
deleted file mode 100644
index 736f03e..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java
+++ /dev/null
@@ -1,368 +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.graphics;
-
-import java.awt.geom.AffineTransform;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.RectangularShape;
-import java.awt.geom.RoundRectangle2D;
-import java.util.EnumSet;
-import java.util.NoSuchElementException;
-
-/**
- * Defines a rectangle with rounded corners, where the sizes of the corners
- * are potentially different.
- */
-public class RoundRectangle extends RectangularShape {
-    public double x;
-    public double y;
-    public double width;
-    public double height;
-    public double ulWidth;
-    public double ulHeight;
-    public double urWidth;
-    public double urHeight;
-    public double lrWidth;
-    public double lrHeight;
-    public double llWidth;
-    public double llHeight;
-
-    private enum Zone {
-        CLOSE_OUTSIDE,
-        CLOSE_INSIDE,
-        MIDDLE,
-        FAR_INSIDE,
-        FAR_OUTSIDE
-    }
-
-    private final EnumSet<Zone> close = EnumSet.of(Zone.CLOSE_OUTSIDE, Zone.CLOSE_INSIDE);
-    private final EnumSet<Zone> far = EnumSet.of(Zone.FAR_OUTSIDE, Zone.FAR_INSIDE);
-
-    /**
-     * @param cornerDimensions array of 8 floating-point number corresponding to the width and
-     * the height of each corner in the following order: upper-left, upper-right, lower-right,
-     * lower-left. It assumes for the size the same convention as {@link RoundRectangle2D}, that
-     * is that the width and height of a corner correspond to the total width and height of the
-     * ellipse that corner is a quarter of.
-     */
-    public RoundRectangle(float x, float y, float width, float height, float[] cornerDimensions) {
-        assert cornerDimensions.length == 8 : "The array of corner dimensions must have eight " +
-                    "elements";
-
-        this.x = x;
-        this.y = y;
-        this.width = width;
-        this.height = height;
-
-        float[] dimensions = cornerDimensions.clone();
-        // If a value is negative, the corresponding corner is squared
-        for (int i = 0; i < dimensions.length; i += 2) {
-            if (dimensions[i] < 0 || dimensions[i + 1] < 0) {
-                dimensions[i] = 0;
-                dimensions[i + 1] = 0;
-            }
-        }
-
-        double topCornerWidth = (dimensions[0] + dimensions[2]) / 2d;
-        double bottomCornerWidth = (dimensions[4] + dimensions[6]) / 2d;
-        double leftCornerHeight = (dimensions[1] + dimensions[7]) / 2d;
-        double rightCornerHeight = (dimensions[3] + dimensions[5]) / 2d;
-
-        // Rescale the corner dimensions if they are bigger than the rectangle
-        double scale = Math.min(1.0, width / topCornerWidth);
-        scale = Math.min(scale, width / bottomCornerWidth);
-        scale = Math.min(scale, height / leftCornerHeight);
-        scale = Math.min(scale, height / rightCornerHeight);
-
-        this.ulWidth = dimensions[0] * scale;
-        this.ulHeight = dimensions[1] * scale;
-        this.urWidth = dimensions[2] * scale;
-        this.urHeight = dimensions[3] * scale;
-        this.lrWidth = dimensions[4] * scale;
-        this.lrHeight = dimensions[5] * scale;
-        this.llWidth = dimensions[6] * scale;
-        this.llHeight = dimensions[7] * scale;
-    }
-
-    @Override
-    public double getX() {
-        return x;
-    }
-
-    @Override
-    public double getY() {
-        return y;
-    }
-
-    @Override
-    public double getWidth() {
-        return width;
-    }
-
-    @Override
-    public double getHeight() {
-        return height;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return (width <= 0d) || (height <= 0d);
-    }
-
-    @Override
-    public void setFrame(double x, double y, double w, double h) {
-        this.x = x;
-        this.y = y;
-        this.width = w;
-        this.height = h;
-    }
-
-    @Override
-    public Rectangle2D getBounds2D() {
-        return new Rectangle2D.Double(x, y, width, height);
-    }
-
-    @Override
-    public boolean contains(double x, double y) {
-        if (isEmpty()) {
-            return false;
-        }
-
-        double x0 = getX();
-        double y0 = getY();
-        double x1 = x0 + getWidth();
-        double y1 = y0 + getHeight();
-        // Check for trivial rejection - point is outside bounding rectangle
-        if (x < x0 || y < y0 || x >= x1 || y >= y1) {
-            return false;
-        }
-
-        double insideTopX0 = x0 + ulWidth / 2d;
-        double insideLeftY0 = y0 + ulHeight / 2d;
-        if (x < insideTopX0 && y < insideLeftY0) {
-            // In the upper-left corner
-            return isInsideCorner(x - insideTopX0, y - insideLeftY0, ulWidth / 2d, ulHeight / 2d);
-        }
-
-        double insideTopX1 = x1 - urWidth / 2d;
-        double insideRightY0 = y0 + urHeight / 2d;
-        if (x > insideTopX1 && y < insideRightY0) {
-            // In the upper-right corner
-            return isInsideCorner(x - insideTopX1, y - insideRightY0, urWidth / 2d, urHeight / 2d);
-        }
-
-        double insideBottomX1 = x1 - lrWidth / 2d;
-        double insideRightY1 = y1 - lrHeight / 2d;
-        if (x > insideBottomX1 && y > insideRightY1) {
-            // In the lower-right corner
-            return isInsideCorner(x - insideBottomX1, y - insideRightY1, lrWidth / 2d,
-                    lrHeight / 2d);
-        }
-
-        double insideBottomX0 = x0 + llWidth / 2d;
-        double insideLeftY1 = y1 - llHeight / 2d;
-        if (x < insideBottomX0 && y > insideLeftY1) {
-            // In the lower-left corner
-            return isInsideCorner(x - insideBottomX0, y - insideLeftY1, llWidth / 2d,
-                    llHeight / 2d);
-        }
-
-        // In the central part of the rectangle
-        return true;
-    }
-
-    private boolean isInsideCorner(double x, double y, double width, double height) {
-        double squareDist = height * height * x * x + width * width * y * y;
-        return squareDist <= width * width * height * height;
-    }
-
-    private Zone classify(double coord, double side1, double arcSize1, double side2,
-            double arcSize2) {
-        if (coord < side1) {
-            return Zone.CLOSE_OUTSIDE;
-        } else if (coord < side1 + arcSize1) {
-            return Zone.CLOSE_INSIDE;
-        } else if (coord < side2 - arcSize2) {
-            return Zone.MIDDLE;
-        } else if (coord < side2) {
-            return Zone.FAR_INSIDE;
-        } else {
-            return Zone.FAR_OUTSIDE;
-        }
-    }
-
-    public boolean intersects(double x, double y, double w, double h) {
-        if (isEmpty() || w <= 0 || h <= 0) {
-            return false;
-        }
-        double x0 = getX();
-        double y0 = getY();
-        double x1 = x0 + getWidth();
-        double y1 = y0 + getHeight();
-        // Check for trivial rejection - bounding rectangles do not intersect
-        if (x + w <= x0 || x >= x1 || y + h <= y0 || y >= y1) {
-            return false;
-        }
-
-        double maxLeftCornerWidth = Math.max(ulWidth, llWidth) / 2d;
-        double maxRightCornerWidth = Math.max(urWidth, lrWidth) / 2d;
-        double maxUpperCornerHeight = Math.max(ulHeight, urHeight) / 2d;
-        double maxLowerCornerHeight = Math.max(llHeight, lrHeight) / 2d;
-        Zone x0class = classify(x, x0, maxLeftCornerWidth, x1, maxRightCornerWidth);
-        Zone x1class = classify(x + w, x0, maxLeftCornerWidth, x1, maxRightCornerWidth);
-        Zone y0class = classify(y, y0, maxUpperCornerHeight, y1, maxLowerCornerHeight);
-        Zone y1class = classify(y + h, y0, maxUpperCornerHeight, y1, maxLowerCornerHeight);
-
-        // Trivially accept if any point is inside inner rectangle
-        if (x0class == Zone.MIDDLE || x1class == Zone.MIDDLE || y0class == Zone.MIDDLE || y1class == Zone.MIDDLE) {
-            return true;
-        }
-        // Trivially accept if either edge spans inner rectangle
-        if ((close.contains(x0class) && far.contains(x1class)) || (close.contains(y0class) &&
-                far.contains(y1class))) {
-            return true;
-        }
-
-        // Since neither edge spans the center, then one of the corners
-        // must be in one of the rounded edges.  We detect this case if
-        // a [xy]0class is 3 or a [xy]1class is 1.  One of those two cases
-        // must be true for each direction.
-        // We now find a "nearest point" to test for being inside a rounded
-        // corner.
-        if (x1class == Zone.CLOSE_INSIDE && y1class == Zone.CLOSE_INSIDE) {
-            // Potentially in upper-left corner
-            x = x + w - x0 - ulWidth / 2d;
-            y = y + h - y0 - ulHeight / 2d;
-            return x > 0 || y > 0 || isInsideCorner(x, y, ulWidth / 2d, ulHeight / 2d);
-        }
-        if (x1class == Zone.CLOSE_INSIDE) {
-            // Potentially in lower-left corner
-            x = x + w - x0 - llWidth / 2d;
-            y = y - y1 + llHeight / 2d;
-            return x > 0 || y < 0 || isInsideCorner(x, y, llWidth / 2d, llHeight / 2d);
-        }
-        if (y1class == Zone.CLOSE_INSIDE) {
-            //Potentially in the upper-right corner
-            x = x - x1 + urWidth / 2d;
-            y = y + h - y0 - urHeight / 2d;
-            return x < 0 || y > 0 || isInsideCorner(x, y, urWidth / 2d, urHeight / 2d);
-        }
-        // Potentially in the lower-right corner
-        x = x - x1 + lrWidth / 2d;
-        y = y - y1 + lrHeight / 2d;
-        return x < 0 || y < 0 || isInsideCorner(x, y, lrWidth / 2d, lrHeight / 2d);
-    }
-
-    @Override
-    public boolean contains(double x, double y, double w, double h) {
-        if (isEmpty() || w <= 0 || h <= 0) {
-            return false;
-        }
-        return (contains(x, y) &&
-                contains(x + w, y) &&
-                contains(x, y + h) &&
-                contains(x + w, y + h));
-    }
-
-    @Override
-    public PathIterator getPathIterator(final AffineTransform at) {
-        return new PathIterator() {
-            int index;
-
-            // ArcIterator.btan(Math.PI/2)
-            public static final double CtrlVal = 0.5522847498307933;
-            private final double ncv = 1.0 - CtrlVal;
-
-            // Coordinates of control points for Bezier curves approximating the straight lines
-            // and corners of the rounded rectangle.
-            private final double[][] ctrlpts = {
-                    {0.0, 0.0, 0.0, ulHeight},
-                    {0.0, 0.0, 1.0, -llHeight},
-                    {0.0, 0.0, 1.0, -llHeight * ncv, 0.0, ncv * llWidth, 1.0, 0.0, 0.0, llWidth,
-                            1.0, 0.0},
-                    {1.0, -lrWidth, 1.0, 0.0},
-                    {1.0, -lrWidth * ncv, 1.0, 0.0, 1.0, 0.0, 1.0, -lrHeight * ncv, 1.0, 0.0, 1.0,
-                            -lrHeight},
-                    {1.0, 0.0, 0.0, urHeight},
-                    {1.0, 0.0, 0.0, ncv * urHeight, 1.0, -urWidth * ncv, 0.0, 0.0, 1.0, -urWidth,
-                            0.0, 0.0},
-                    {0.0, ulWidth, 0.0, 0.0},
-                    {0.0, ncv * ulWidth, 0.0, 0.0, 0.0, 0.0, 0.0, ncv * ulHeight, 0.0, 0.0, 0.0,
-                            ulHeight},
-                    {}
-            };
-            private final int[] types = {
-                    SEG_MOVETO,
-                    SEG_LINETO, SEG_CUBICTO,
-                    SEG_LINETO, SEG_CUBICTO,
-                    SEG_LINETO, SEG_CUBICTO,
-                    SEG_LINETO, SEG_CUBICTO,
-                    SEG_CLOSE,
-            };
-
-            @Override
-            public int getWindingRule() {
-                return WIND_NON_ZERO;
-            }
-
-            @Override
-            public boolean isDone() {
-                return index >= ctrlpts.length;
-            }
-
-            @Override
-            public void next() {
-                index++;
-            }
-
-            @Override
-            public int currentSegment(float[] coords) {
-                if (isDone()) {
-                    throw new NoSuchElementException("roundrect iterator out of bounds");
-                }
-                int nc = 0;
-                double ctrls[] = ctrlpts[index];
-                for (int i = 0; i < ctrls.length; i += 4) {
-                    coords[nc++] = (float) (x + ctrls[i] * width + ctrls[i + 1] / 2d);
-                    coords[nc++] = (float) (y + ctrls[i + 2] * height + ctrls[i + 3] / 2d);
-                }
-                if (at != null) {
-                    at.transform(coords, 0, coords, 0, nc / 2);
-                }
-                return types[index];
-            }
-
-            @Override
-            public int currentSegment(double[] coords) {
-                if (isDone()) {
-                    throw new NoSuchElementException("roundrect iterator out of bounds");
-                }
-                int nc = 0;
-                double ctrls[] = ctrlpts[index];
-                for (int i = 0; i < ctrls.length; i += 4) {
-                    coords[nc++] = x + ctrls[i] * width + ctrls[i + 1] / 2d;
-                    coords[nc++] = y + ctrls[i + 2] * height + ctrls[i + 3] / 2d;
-                }
-                if (at != null) {
-                    at.transform(coords, 0, coords, 0, nc / 2);
-                }
-                return types[index];
-            }
-        };
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
deleted file mode 100644
index 5b75089..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-/**
- * Delegate implementing the native methods of android.graphics.Shader
- *
- * Through the layoutlib_create tool, the original native methods of Shader have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Shader class.
- *
- * This also serve as a base class for all Shader delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class Shader_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<Shader_Delegate> sManager =
-            new DelegateManager<Shader_Delegate>(Shader_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-    private Matrix_Delegate mLocalMatrix = null;
-
-    // ---- Public Helper methods ----
-
-    public static Shader_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    /**
-     * Returns the {@link TileMode} matching the given int.
-     * @param tileMode the tile mode int value
-     * @return the TileMode enum.
-     */
-    public static TileMode getTileMode(int tileMode) {
-        for (TileMode tm : TileMode.values()) {
-            if (tm.nativeInt == tileMode) {
-                return tm;
-            }
-        }
-
-        assert false;
-        return TileMode.CLAMP;
-    }
-
-    public abstract java.awt.Paint getJavaPaint();
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSafeUnref(long nativeInstance) {
-        sManager.removeJavaReferenceFor(nativeInstance);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    protected Shader_Delegate(long nativeMatrix) {
-        mLocalMatrix = Matrix_Delegate.getDelegate(nativeMatrix);
-    }
-
-    protected java.awt.geom.AffineTransform getLocalMatrix() {
-        if (mLocalMatrix != null) {
-            return mLocalMatrix.getAffineTransform();
-        }
-
-        return new java.awt.geom.AffineTransform();
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java
deleted file mode 100644
index 6d2e9b4..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.SumPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of SumPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original SumPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class SumPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Sum Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long first, long second) {
-        SumPathEffect_Delegate newDelegate = new SumPathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
deleted file mode 100644
index 30152bc..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.SweepGradient
- *
- * Through the layoutlib_create tool, the original native methods of SweepGradient have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original SweepGradient class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class SweepGradient_Delegate extends Gradient_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate1(long matrix, float x, float y, int colors[], float
-            positions[]) {
-        SweepGradient_Delegate newDelegate = new SweepGradient_Delegate(matrix, x, y, colors,
-                positions);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate2(long matrix, float x, float y, int color0, int color1) {
-        return nativeCreate1(matrix, x, y, new int[] { color0, color1 },
-                null /*positions*/);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * A subclass of Shader that draws a sweep gradient around a center point.
-     *
-     * @param nativeMatrix reference to the shader's native transformation matrix
-     * @param cx       The x-coordinate of the center
-     * @param cy       The y-coordinate of the center
-     * @param colors   The colors to be distributed between around the center.
-     *                 There must be at least 2 colors in the array.
-     * @param positions May be NULL. The relative position of
-     *                 each corresponding color in the colors array, beginning
-     *                 with 0 and ending with 1.0. If the values are not
-     *                 monotonic, the drawing may produce unexpected results.
-     *                 If positions is NULL, then the colors are automatically
-     *                 spaced evenly.
-     */
-    private SweepGradient_Delegate(long nativeMatrix, float cx, float cy,
-            int colors[], float positions[]) {
-        super(nativeMatrix, colors, positions);
-        mJavaPaint = new SweepGradientPaint(cx, cy, mColors, mPositions);
-    }
-
-    private class SweepGradientPaint extends GradientPaint {
-
-        private final float mCx;
-        private final float mCy;
-
-        public SweepGradientPaint(float cx, float cy, int[] colors,
-                float[] positions) {
-            super(colors, positions, null /*tileMode*/);
-            mCx = cx;
-            mCy = cy;
-        }
-
-        @Override
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel     colorModel,
-                java.awt.Rectangle            deviceBounds,
-                java.awt.geom.Rectangle2D     userBounds,
-                java.awt.geom.AffineTransform xform,
-                java.awt.RenderingHints       hints) {
-            precomputeGradientColors();
-
-            java.awt.geom.AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in SweepGradient", e, null /*data*/);
-                canvasMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in SweepGradient", e, null /*data*/);
-                localMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            return new SweepGradientPaintContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class SweepGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.geom.AffineTransform mCanvasMatrix;
-            private final java.awt.geom.AffineTransform mLocalMatrix;
-            private final java.awt.image.ColorModel mColorModel;
-
-            public SweepGradientPaintContext(
-                    java.awt.geom.AffineTransform canvasMatrix,
-                    java.awt.geom.AffineTransform localMatrix,
-                    java.awt.image.ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel;
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
-                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
-                    mColorModel.isAlphaPremultiplied(), null);
-
-                int[] data = new int[w*h];
-
-                // compute angle from each point to the center, and figure out the distance from
-                // it.
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix
-                        pt1[0] = pt2[0] - mCx;
-                        pt1[1] = pt2[1] - mCy;
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        float dx = pt2[0];
-                        float dy = pt2[1];
-
-                        float angle;
-                        if (dx == 0) {
-                            angle = (float) (dy < 0 ? 3 * Math.PI / 2 : Math.PI / 2);
-                        } else if (dy == 0) {
-                            angle = (float) (dx < 0 ? Math.PI : 0);
-                        } else {
-                            angle = (float) Math.atan(dy / dx);
-                            if (dx > 0) {
-                                if (dy < 0) {
-                                    angle += Math.PI * 2;
-                                }
-                            } else {
-                                angle += Math.PI;
-                            }
-                        }
-
-                        // convert to 0-1. value and get color
-                        data[index++] = getGradientColor((float) (angle / (2 * Math.PI)));
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Accessor.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Accessor.java
deleted file mode 100644
index ce669cb..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Accessor.java
+++ /dev/null
@@ -1,28 +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.graphics;
-
-import android.annotation.NonNull;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class Typeface_Accessor {
-    public static boolean isSystemFont(@NonNull String fontName) {
-        return Typeface.sSystemFontMap.containsKey(fontName);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
deleted file mode 100644
index c7818a3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.graphics.FontFamily_Delegate.FontVariant;
-import android.graphics.fonts.FontVariationAxis;
-import android.text.FontConfig;
-
-import java.awt.Font;
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import static android.graphics.FontFamily_Delegate.getFontLocation;
-
-/**
- * Delegate implementing the native methods of android.graphics.Typeface
- *
- * Through the layoutlib_create tool, the original native methods of Typeface have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Typeface class.
- *
- * @see DelegateManager
- *
- */
-public final class Typeface_Delegate {
-
-    public static final String SYSTEM_FONTS = "/system/fonts/";
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Typeface_Delegate> sManager =
-            new DelegateManager<Typeface_Delegate>(Typeface_Delegate.class);
-
-
-    // ---- delegate data ----
-
-    @NonNull
-    private final FontFamily_Delegate[] mFontFamilies;  // the reference to FontFamily_Delegate.
-    /** @see Font#getStyle() */
-    private final int mStyle;
-    private final int mWeight;
-
-    private static long sDefaultTypeface;
-
-
-    // ---- Public Helper methods ----
-
-    public static Typeface_Delegate getDelegate(long nativeTypeface) {
-        return sManager.getDelegate(nativeTypeface);
-    }
-
-    /**
-     * Return a list of fonts that match the style and variant. The list is ordered according to
-     * preference of fonts.
-     *
-     * The list may contain null when the font failed to load. If null is reached when trying to
-     * render with this list of fonts, then a warning should be logged letting the user know that
-     * some font failed to load.
-     *
-     * @param variant The variant preferred. Can only be {@link FontVariant#COMPACT} or
-     *                {@link FontVariant#ELEGANT}
-     */
-    @NonNull
-    public List<Font> getFonts(FontVariant variant) {
-        assert variant != FontVariant.NONE;
-
-        // Calculate the required weight based on style and weight of this typeface.
-        int weight = mWeight + ((mStyle & Font.BOLD) == 0 ? 0 : FontFamily_Delegate.BOLD_FONT_WEIGHT_DELTA);
-        if (weight > 900) {
-            weight = 900;
-        }
-        final boolean isItalic = (mStyle & Font.ITALIC) != 0;
-        List<Font> fonts = new ArrayList<Font>(mFontFamilies.length);
-        for (int i = 0; i < mFontFamilies.length; i++) {
-            FontFamily_Delegate ffd = mFontFamilies[i];
-            if (ffd != null && ffd.isValid()) {
-                Font font = ffd.getFont(weight, isItalic);
-                if (font != null) {
-                    FontVariant ffdVariant = ffd.getVariant();
-                    if (ffdVariant == FontVariant.NONE) {
-                        fonts.add(font);
-                        continue;
-                    }
-                    // We cannot open each font and get locales supported, etc to match the fonts.
-                    // As a workaround, we hardcode certain assumptions like Elegant and Compact
-                    // always appear in pairs.
-                    assert i < mFontFamilies.length - 1;
-                    FontFamily_Delegate ffd2 = mFontFamilies[++i];
-                    assert ffd2 != null;
-                    FontVariant ffd2Variant = ffd2.getVariant();
-                    Font font2 = ffd2.getFont(weight, isItalic);
-                    assert ffd2Variant != FontVariant.NONE && ffd2Variant != ffdVariant
-                            && font2 != null;
-                    // Add the font with the matching variant to the list.
-                    if (variant == ffd.getVariant()) {
-                        fonts.add(font);
-                    } else {
-                        fonts.add(font2);
-                    }
-                } else {
-                    // The FontFamily is valid but doesn't contain any matching font. This means
-                    // that the font failed to load. We add null to the list of fonts. Don't throw
-                    // the warning just yet. If this is a non-english font, we don't want to warn
-                    // users who are trying to render only english text.
-                    fonts.add(null);
-                }
-            }
-        }
-        return fonts;
-    }
-
-    /**
-     * Clear the default typefaces when disposing bridge.
-     */
-    public static void resetDefaults() {
-        // Sometimes this is called before the Bridge is initialized. In that case, we don't want to
-        // initialize Typeface because the SDK fonts location hasn't been set.
-        if (FontFamily_Delegate.getFontLocation() != null) {
-            Typeface.sDefaults = null;
-        }
-    }
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized long nativeCreateFromTypeface(long native_instance, int style) {
-        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
-        if (delegate == null) {
-            delegate = sManager.getDelegate(sDefaultTypeface);
-        }
-        if (delegate == null) {
-            return 0;
-        }
-
-        return sManager.addNewDelegate(new Typeface_Delegate(delegate.mFontFamilies, style,
-                delegate.mWeight));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized long nativeCreateFromTypefaceWithVariation(long native_instance,
-            List<FontVariationAxis> axes) {
-        long newInstance = nativeCreateFromTypeface(native_instance, 0);
-
-        if (newInstance != 0) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                    "nativeCreateFromTypefaceWithVariation is not supported", null, null);
-        }
-        return newInstance;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized int[] nativeGetSupportedAxes(long native_instance) {
-        // nativeCreateFromTypefaceWithVariation is not supported so we do not keep the axes
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreateWeightAlias(long native_instance, int weight) {
-        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
-        if (delegate == null) {
-            delegate = sManager.getDelegate(sDefaultTypeface);
-        }
-        if (delegate == null) {
-            return 0;
-        }
-        Typeface_Delegate weightAlias =
-                new Typeface_Delegate(delegate.mFontFamilies, delegate.mStyle, weight);
-        return sManager.addNewDelegate(weightAlias);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized long nativeCreateFromArray(long[] familyArray) {
-        FontFamily_Delegate[] fontFamilies = new FontFamily_Delegate[familyArray.length];
-        for (int i = 0; i < familyArray.length; i++) {
-            fontFamilies[i] = FontFamily_Delegate.getDelegate(familyArray[i]);
-        }
-        Typeface_Delegate delegate = new Typeface_Delegate(fontFamilies, Typeface.NORMAL);
-        return sManager.addNewDelegate(delegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeUnref(long native_instance) {
-        sManager.removeJavaReferenceFor(native_instance);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGetStyle(long native_instance) {
-        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mStyle;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetDefault(long native_instance) {
-        sDefaultTypeface = native_instance;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static File getSystemFontConfigLocation() {
-        return new File(getFontLocation());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static FontFamily makeFamilyFromParsed(FontConfig.Family family,
-            Map<String, ByteBuffer> bufferForPath) {
-        FontFamily fontFamily = new FontFamily(family.getLanguage(), family.getVariant());
-        for (FontConfig.Font font : family.getFonts()) {
-            String fullPathName = "/system/fonts/" + font.getFontName();
-            FontFamily_Delegate.addFont(fontFamily.mBuilderPtr, fullPathName,
-                    font.getWeight(), font.isItalic());
-        }
-        fontFamily.freeze();
-        return fontFamily;
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private Typeface_Delegate(@NonNull FontFamily_Delegate[] fontFamilies, int style) {
-        this(fontFamilies, style, FontFamily_Delegate.DEFAULT_FONT_WEIGHT);
-    }
-
-    public Typeface_Delegate(@NonNull FontFamily_Delegate[] fontFamilies, int style, int weight) {
-        mFontFamilies = fontFamilies;
-        mStyle = style;
-        mWeight = weight;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java
deleted file mode 100644
index ad2c564..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java
+++ /dev/null
@@ -1,298 +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.graphics.drawable;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.internal.view.animation.NativeInterpolatorFactoryHelper_Delegate;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.graphics.drawable.AnimatedVectorDrawable.VectorDrawableAnimatorRT;
-import android.graphics.drawable.VectorDrawable_Delegate.VFullPath_Delegate;
-import android.graphics.drawable.VectorDrawable_Delegate.VGroup_Delegate;
-import android.graphics.drawable.VectorDrawable_Delegate.VNativeObject;
-import android.graphics.drawable.VectorDrawable_Delegate.VPathRenderer_Delegate;
-
-import java.util.ArrayList;
-import java.util.function.Consumer;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link
- * AnimatedVectorDrawable}
- * <p>
- * Through the layoutlib_create tool, the original  methods of AnimatedVectorDrawable have been
- * replaced by calls to methods of the same name in this delegate class.
- */
-@SuppressWarnings("unused")
-public class AnimatedVectorDrawable_Delegate {
-    private static DelegateManager<AnimatorSetHolder> sAnimatorSets = new
-            DelegateManager<>(AnimatorSetHolder.class);
-    private static DelegateManager<PropertySetter> sHolders = new
-            DelegateManager<>(PropertySetter.class);
-
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateAnimatorSet() {
-        return sAnimatorSets.addNewDelegate(new AnimatorSetHolder());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetVectorDrawableTarget(long animatorPtr, long vectorDrawablePtr) {
-        // TODO: implement
-    }
-    @LayoutlibDelegate
-    /*package*/ static void nAddAnimator(long setPtr, long propertyValuesHolder,
-            long nativeInterpolator, long startDelay, long duration, int repeatCount,
-            int repeatMode) {
-        PropertySetter holder = sHolders.getDelegate(propertyValuesHolder);
-        if (holder == null || holder.getValues() == null) {
-            return;
-        }
-
-        ObjectAnimator animator = new ObjectAnimator();
-        animator.setValues(holder.getValues());
-        animator.setInterpolator(
-                NativeInterpolatorFactoryHelper_Delegate.getDelegate(nativeInterpolator));
-        animator.setStartDelay(startDelay);
-        animator.setDuration(duration);
-        animator.setRepeatCount(repeatCount);
-        animator.setRepeatMode(repeatMode);
-        animator.setTarget(holder);
-        animator.setPropertyName(holder.getValues().getPropertyName());
-
-        AnimatorSetHolder set = sAnimatorSets.getDelegate(setPtr);
-        assert set != null;
-        set.addAnimator(animator);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateGroupPropertyHolder(long nativePtr, int propertyId,
-            float startValue, float endValue) {
-        VGroup_Delegate group = VNativeObject.getDelegate(nativePtr);
-        Consumer<Float> setter = group.getPropertySetter(propertyId);
-
-        return sHolders.addNewDelegate(FloatPropertySetter.of(setter, startValue,
-                endValue));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathDataPropertyHolder(long nativePtr, long startValuePtr,
-            long endValuePtr) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, "AnimatedVectorDrawable path " +
-                "animations are not supported.", null, null);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathColorPropertyHolder(long nativePtr, int propertyId,
-            int startValue, int endValue) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(nativePtr);
-        Consumer<Integer> setter = path.getIntPropertySetter(propertyId);
-
-        return sHolders.addNewDelegate(IntPropertySetter.of(setter, startValue,
-                endValue));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathPropertyHolder(long nativePtr, int propertyId,
-            float startValue, float endValue) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(nativePtr);
-        Consumer<Float> setter = path.getFloatPropertySetter(propertyId);
-
-        return sHolders.addNewDelegate(FloatPropertySetter.of(setter, startValue,
-                endValue));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateRootAlphaPropertyHolder(long nativePtr, float startValue,
-            float endValue) {
-        VPathRenderer_Delegate renderer = VNativeObject.getDelegate(nativePtr);
-
-        return sHolders.addNewDelegate(FloatPropertySetter.of(renderer::setRootAlpha,
-                startValue,
-                endValue));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetPropertyHolderData(long nativePtr, float[] data, int length) {
-        PropertySetter setter = sHolders.getDelegate(nativePtr);
-        assert setter != null;
-
-        setter.setValues(data);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetPropertyHolderData(long nativePtr, int[] data, int length) {
-        PropertySetter setter = sHolders.getDelegate(nativePtr);
-        assert setter != null;
-
-        setter.setValues(data);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nStart(long animatorSetPtr, VectorDrawableAnimatorRT set, int id) {
-        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
-        assert animatorSet != null;
-
-        animatorSet.start();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReverse(long animatorSetPtr, VectorDrawableAnimatorRT set, int id) {
-        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
-        assert animatorSet != null;
-
-        animatorSet.reverse();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nEnd(long animatorSetPtr) {
-        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
-        assert animatorSet != null;
-
-        animatorSet.end();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReset(long animatorSetPtr) {
-        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
-        assert animatorSet != null;
-
-        animatorSet.end();
-        animatorSet.start();
-    }
-
-    private static class AnimatorSetHolder {
-        private ArrayList<Animator> mAnimators = new ArrayList<>();
-        private AnimatorSet mAnimatorSet = null;
-
-        private void addAnimator(@NonNull Animator animator) {
-            mAnimators.add(animator);
-        }
-
-        private void ensureAnimatorSet() {
-            if (mAnimatorSet == null) {
-                mAnimatorSet = new AnimatorSet();
-                mAnimatorSet.playTogether(mAnimators);
-            }
-        }
-
-        private void start() {
-            ensureAnimatorSet();
-
-            mAnimatorSet.start();
-        }
-
-        private void end() {
-            mAnimatorSet.end();
-        }
-
-        private void reset() {
-            end();
-            start();
-        }
-
-        private void reverse() {
-            mAnimatorSet.reverse();
-        }
-    }
-
-    /**
-     * Class that allows setting a value and holds the range of values for the given property.
-     *
-     * @param <T> the type of the property
-     */
-    private static class PropertySetter<T> {
-        final Consumer<T> mValueSetter;
-        private PropertyValuesHolder mValues;
-
-        private PropertySetter(@NonNull Consumer<T> valueSetter) {
-            mValueSetter = valueSetter;
-        }
-
-        /**
-         * Method to set an {@link Integer} value for this property. The default implementation of
-         * this method doesn't do anything. This method is accessed via reflection by the
-         * PropertyValuesHolder.
-         */
-        public void setIntValue(Integer value) {
-        }
-
-        /**
-         * Method to set an {@link Integer} value for this property. The default implementation of
-         * this method doesn't do anything. This method is accessed via reflection by the
-         * PropertyValuesHolder.
-         */
-        public void setFloatValue(Float value) {
-        }
-
-        void setValues(float... values) {
-            mValues = PropertyValuesHolder.ofFloat("floatValue", values);
-        }
-
-        @Nullable
-        PropertyValuesHolder getValues() {
-            return mValues;
-        }
-
-        void setValues(int... values) {
-            mValues = PropertyValuesHolder.ofInt("intValue", values);
-        }
-    }
-
-    private static class IntPropertySetter extends PropertySetter<Integer> {
-        private IntPropertySetter(Consumer<Integer> valueSetter) {
-            super(valueSetter);
-        }
-
-        private static PropertySetter of(Consumer<Integer> valueSetter, int... values) {
-            PropertySetter setter = new IntPropertySetter(valueSetter);
-            setter.setValues(values);
-
-            return setter;
-        }
-
-        public void setIntValue(Integer value) {
-            mValueSetter.accept(value);
-        }
-    }
-
-    private static class FloatPropertySetter extends PropertySetter<Float> {
-        private FloatPropertySetter(Consumer<Float> valueSetter) {
-            super(valueSetter);
-        }
-
-        private static PropertySetter of(Consumer<Float> valueSetter, float... values) {
-            PropertySetter setter = new FloatPropertySetter(valueSetter);
-            setter.setValues(values);
-
-            return setter;
-        }
-
-        public void setFloatValue(Float value) {
-            mValueSetter.accept(value);
-        }
-
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java
deleted file mode 100644
index fc848d9..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics.drawable;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Canvas;
-import android.graphics.drawable.AnimatedVectorDrawable.VectorDrawableAnimatorRT;
-
-public class AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate {
-    @LayoutlibDelegate
-    /*package*/ static boolean useLastSeenTarget(VectorDrawableAnimatorRT thisDrawableAnimator) {
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void onDraw(VectorDrawableAnimatorRT thisDrawableAnimator, Canvas canvas) {
-        // Do not attempt to record as we are not using a DisplayListCanvas
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/GradientDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/GradientDrawable_Delegate.java
deleted file mode 100644
index a3ad2aac..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/GradientDrawable_Delegate.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics.drawable;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Path;
-import android.graphics.drawable.GradientDrawable.GradientState;
-
-import java.lang.reflect.Field;
-
-/**
- * Delegate implementing the native methods of {@link GradientDrawable}
- *
- * Through the layoutlib_create tool, the original native methods of GradientDrawable have been
- * replaced by calls to methods of the same name in this delegate class.
- */
-public class GradientDrawable_Delegate {
-
-    /**
-     * The ring can be built either by drawing full circles, or by drawing arcs in case the
-     * circle isn't complete. LayoutLib cannot handle drawing full circles (requires path
-     * subtraction). So, if we need to draw full circles, we switch to drawing 99% circle.
-     */
-    @LayoutlibDelegate
-    /*package*/ static Path buildRing(GradientDrawable thisDrawable, GradientState st) {
-        boolean useLevel = st.mUseLevelForShape;
-        int level = thisDrawable.getLevel();
-        // 10000 is the max level. See android.graphics.drawable.Drawable#getLevel()
-        float sweep = useLevel ? (360.0f * level / 10000.0f) : 360f;
-        Field mLevel = null;
-        if (sweep >= 360 || sweep <= -360) {
-            st.mUseLevelForShape = true;
-            // Use reflection to set the value of the field to prevent setting the drawable to
-            // dirty again.
-            try {
-                mLevel = Drawable.class.getDeclaredField("mLevel");
-                mLevel.setAccessible(true);
-                mLevel.setInt(thisDrawable, 9999);  // set to one less than max.
-            } catch (NoSuchFieldException e) {
-                // The field has been removed in a recent framework change. Fall back to old
-                // buggy behaviour.
-            } catch (IllegalAccessException e) {
-                // We've already set the field to be accessible.
-                assert false;
-            }
-        }
-        Path path = thisDrawable.buildRing_Original(st);
-        st.mUseLevelForShape = useLevel;
-        if (mLevel != null) {
-            try {
-                mLevel.setInt(thisDrawable, level);
-            } catch (IllegalAccessException e) {
-                assert false;
-            }
-        }
-        return path;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
deleted file mode 100644
index 616784c..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
+++ /dev/null
@@ -1,1262 +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.graphics.drawable;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.content.res.Resources;
-import android.content.res.Resources.Theme;
-import android.content.res.TypedArray;
-import android.graphics.BaseCanvas_Delegate;
-import android.graphics.Canvas_Delegate;
-import android.graphics.Color;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Paint.Cap;
-import android.graphics.Paint.Join;
-import android.graphics.Paint_Delegate;
-import android.graphics.Path;
-import android.graphics.PathMeasure;
-import android.graphics.Path_Delegate;
-import android.graphics.Rect;
-import android.graphics.Region.Op;
-import android.util.ArrayMap;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.MathUtils;
-import android.util.PathParser_Delegate;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-import java.util.ArrayList;
-import java.util.function.Consumer;
-
-import static android.graphics.Canvas.CLIP_SAVE_FLAG;
-import static android.graphics.Canvas.MATRIX_SAVE_FLAG;
-import static android.graphics.Paint.Cap.BUTT;
-import static android.graphics.Paint.Cap.ROUND;
-import static android.graphics.Paint.Cap.SQUARE;
-import static android.graphics.Paint.Join.BEVEL;
-import static android.graphics.Paint.Join.MITER;
-import static android.graphics.Paint.Style;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link VectorDrawable}
- * <p>
- * Through the layoutlib_create tool, the original  methods of VectorDrawable have been replaced by
- * calls to methods of the same name in this delegate class.
- */
-@SuppressWarnings("unused")
-public class VectorDrawable_Delegate {
-    private static final String LOGTAG = VectorDrawable_Delegate.class.getSimpleName();
-    private static final boolean DBG_VECTOR_DRAWABLE = false;
-
-    private static final DelegateManager<VNativeObject> sPathManager =
-            new DelegateManager<>(VNativeObject.class);
-
-    private static long addNativeObject(VNativeObject object) {
-        long ptr = sPathManager.addNewDelegate(object);
-        object.setNativePtr(ptr);
-
-        return ptr;
-    }
-
-    /**
-     * Obtains styled attributes from the theme, if available, or unstyled resources if the theme is
-     * null.
-     */
-    private static TypedArray obtainAttributes(
-            Resources res, Theme theme, AttributeSet set, int[] attrs) {
-        if (theme == null) {
-            return res.obtainAttributes(set, attrs);
-        }
-        return theme.obtainStyledAttributes(set, attrs, 0, 0);
-    }
-
-    private static int applyAlpha(int color, float alpha) {
-        int alphaBytes = Color.alpha(color);
-        color &= 0x00FFFFFF;
-        color |= ((int) (alphaBytes * alpha)) << 24;
-        return color;
-    }
-
-    @LayoutlibDelegate
-    static long nCreateTree(long rootGroupPtr) {
-        return addNativeObject(new VPathRenderer_Delegate(rootGroupPtr));
-    }
-
-    @LayoutlibDelegate
-    static long nCreateTreeFromCopy(long rendererToCopyPtr, long rootGroupPtr) {
-        VPathRenderer_Delegate rendererToCopy = VNativeObject.getDelegate(rendererToCopyPtr);
-        return addNativeObject(new VPathRenderer_Delegate(rendererToCopy,
-                rootGroupPtr));
-    }
-
-    @LayoutlibDelegate
-    static void nSetRendererViewportSize(long rendererPtr, float viewportWidth,
-            float viewportHeight) {
-        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
-        nativePathRenderer.mViewportWidth = viewportWidth;
-        nativePathRenderer.mViewportHeight = viewportHeight;
-    }
-
-    @LayoutlibDelegate
-    static boolean nSetRootAlpha(long rendererPtr, float alpha) {
-        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
-        nativePathRenderer.setRootAlpha(alpha);
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    static float nGetRootAlpha(long rendererPtr) {
-        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
-
-        return nativePathRenderer.getRootAlpha();
-    }
-
-    @LayoutlibDelegate
-    static void nSetAllowCaching(long rendererPtr, boolean allowCaching) {
-        // ignored
-    }
-
-    @LayoutlibDelegate
-    static int nDraw(long rendererPtr, long canvasWrapperPtr,
-            long colorFilterPtr, Rect bounds, boolean needsMirroring, boolean canReuseCache) {
-        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
-
-        Canvas_Delegate.nSave(canvasWrapperPtr, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
-        Canvas_Delegate.nTranslate(canvasWrapperPtr, bounds.left, bounds.top);
-
-        if (needsMirroring) {
-            Canvas_Delegate.nTranslate(canvasWrapperPtr, bounds.width(), 0);
-            Canvas_Delegate.nScale(canvasWrapperPtr, -1.0f, 1.0f);
-        }
-
-        // At this point, canvas has been translated to the right position.
-        // And we use this bound for the destination rect for the drawBitmap, so
-        // we offset to (0, 0);
-        bounds.offsetTo(0, 0);
-        nativePathRenderer.draw(canvasWrapperPtr, colorFilterPtr, bounds.width(), bounds.height());
-
-        Canvas_Delegate.nRestore(canvasWrapperPtr);
-
-        return bounds.width() * bounds.height();
-    }
-
-    @LayoutlibDelegate
-    static long nCreateFullPath() {
-        return addNativeObject(new VFullPath_Delegate());
-    }
-
-    @LayoutlibDelegate
-    static long nCreateFullPath(long nativeFullPathPtr) {
-        VFullPath_Delegate original = VNativeObject.getDelegate(nativeFullPathPtr);
-        return addNativeObject(new VFullPath_Delegate(original));
-    }
-
-    @LayoutlibDelegate
-    static boolean nGetFullPathProperties(long pathPtr, byte[] propertiesData,
-            int length) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-
-        ByteBuffer properties = ByteBuffer.wrap(propertiesData);
-        properties.order(ByteOrder.nativeOrder());
-
-        properties.putFloat(VFullPath_Delegate.STROKE_WIDTH_INDEX * 4, path.getStrokeWidth());
-        properties.putInt(VFullPath_Delegate.STROKE_COLOR_INDEX * 4, path.getStrokeColor());
-        properties.putFloat(VFullPath_Delegate.STROKE_ALPHA_INDEX * 4, path.getStrokeAlpha());
-        properties.putInt(VFullPath_Delegate.FILL_COLOR_INDEX * 4, path.getFillColor());
-        properties.putFloat(VFullPath_Delegate.FILL_ALPHA_INDEX * 4, path.getStrokeAlpha());
-        properties.putFloat(VFullPath_Delegate.TRIM_PATH_START_INDEX * 4, path.getTrimPathStart());
-        properties.putFloat(VFullPath_Delegate.TRIM_PATH_END_INDEX * 4, path.getTrimPathEnd());
-        properties.putFloat(VFullPath_Delegate.TRIM_PATH_OFFSET_INDEX * 4,
-                path.getTrimPathOffset());
-        properties.putInt(VFullPath_Delegate.STROKE_LINE_CAP_INDEX * 4, path.getStrokeLineCap());
-        properties.putInt(VFullPath_Delegate.STROKE_LINE_JOIN_INDEX * 4, path.getStrokeLineJoin());
-        properties.putFloat(VFullPath_Delegate.STROKE_MITER_LIMIT_INDEX * 4,
-                path.getStrokeMiterlimit());
-        properties.putInt(VFullPath_Delegate.FILL_TYPE_INDEX * 4, path.getFillType());
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    static void nUpdateFullPathProperties(long pathPtr, float strokeWidth,
-            int strokeColor, float strokeAlpha, int fillColor, float fillAlpha, float trimPathStart,
-            float trimPathEnd, float trimPathOffset, float strokeMiterLimit, int strokeLineCap,
-            int strokeLineJoin, int fillType) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-
-        path.setStrokeWidth(strokeWidth);
-        path.setStrokeColor(strokeColor);
-        path.setStrokeAlpha(strokeAlpha);
-        path.setFillColor(fillColor);
-        path.setFillAlpha(fillAlpha);
-        path.setTrimPathStart(trimPathStart);
-        path.setTrimPathEnd(trimPathEnd);
-        path.setTrimPathOffset(trimPathOffset);
-        path.setStrokeMiterlimit(strokeMiterLimit);
-        path.setStrokeLineCap(strokeLineCap);
-        path.setStrokeLineJoin(strokeLineJoin);
-        path.setFillType(fillType);
-    }
-
-    @LayoutlibDelegate
-    static void nUpdateFullPathFillGradient(long pathPtr, long fillGradientPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-
-        path.setFillGradient(fillGradientPtr);
-    }
-
-    @LayoutlibDelegate
-    static void nUpdateFullPathStrokeGradient(long pathPtr, long strokeGradientPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-
-        path.setStrokeGradient(strokeGradientPtr);
-    }
-
-    @LayoutlibDelegate
-    static long nCreateClipPath() {
-        return addNativeObject(new VClipPath_Delegate());
-    }
-
-    @LayoutlibDelegate
-    static long nCreateClipPath(long clipPathPtr) {
-        VClipPath_Delegate original = VNativeObject.getDelegate(clipPathPtr);
-        return addNativeObject(new VClipPath_Delegate(original));
-    }
-
-    @LayoutlibDelegate
-    static long nCreateGroup() {
-        return addNativeObject(new VGroup_Delegate());
-    }
-
-    @LayoutlibDelegate
-    static long nCreateGroup(long groupPtr) {
-        VGroup_Delegate original = VNativeObject.getDelegate(groupPtr);
-        return addNativeObject(new VGroup_Delegate(original, new ArrayMap<>()));
-    }
-
-    @LayoutlibDelegate
-    static void nSetName(long nodePtr, String name) {
-        VNativeObject group = VNativeObject.getDelegate(nodePtr);
-        group.setName(name);
-    }
-
-    @LayoutlibDelegate
-    static boolean nGetGroupProperties(long groupPtr, float[] propertiesData,
-            int length) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-
-        FloatBuffer properties = FloatBuffer.wrap(propertiesData);
-
-        properties.put(VGroup_Delegate.ROTATE_INDEX, group.getRotation());
-        properties.put(VGroup_Delegate.PIVOT_X_INDEX, group.getPivotX());
-        properties.put(VGroup_Delegate.PIVOT_Y_INDEX, group.getPivotY());
-        properties.put(VGroup_Delegate.SCALE_X_INDEX, group.getScaleX());
-        properties.put(VGroup_Delegate.SCALE_Y_INDEX, group.getScaleY());
-        properties.put(VGroup_Delegate.TRANSLATE_X_INDEX, group.getTranslateX());
-        properties.put(VGroup_Delegate.TRANSLATE_Y_INDEX, group.getTranslateY());
-
-        return true;
-    }
-    @LayoutlibDelegate
-    static void nUpdateGroupProperties(long groupPtr, float rotate, float pivotX,
-            float pivotY, float scaleX, float scaleY, float translateX, float translateY) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-
-        group.setRotation(rotate);
-        group.setPivotX(pivotX);
-        group.setPivotY(pivotY);
-        group.setScaleX(scaleX);
-        group.setScaleY(scaleY);
-        group.setTranslateX(translateX);
-        group.setTranslateY(translateY);
-    }
-
-    @LayoutlibDelegate
-    static void nAddChild(long groupPtr, long nodePtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.mChildren.add(VNativeObject.getDelegate(nodePtr));
-    }
-
-    @LayoutlibDelegate
-    static void nSetPathString(long pathPtr, String pathString, int length) {
-        VPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setPathData(PathParser_Delegate.createNodesFromPathData(pathString));
-    }
-
-    /**
-     * The setters and getters below for paths and groups are here temporarily, and will be removed
-     * once the animation in AVD is replaced with RenderNodeAnimator, in which case the animation
-     * will modify these properties in native. By then no JNI hopping would be necessary for VD
-     * during animation, and these setters and getters will be obsolete.
-     */
-    // Setters and getters during animation.
-    @LayoutlibDelegate
-    static float nGetRotation(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getRotation();
-    }
-
-    @LayoutlibDelegate
-    static void nSetRotation(long groupPtr, float rotation) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setRotation(rotation);
-    }
-
-    @LayoutlibDelegate
-    static float nGetPivotX(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getPivotX();
-    }
-
-    @LayoutlibDelegate
-    static void nSetPivotX(long groupPtr, float pivotX) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setPivotX(pivotX);
-    }
-
-    @LayoutlibDelegate
-    static float nGetPivotY(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getPivotY();
-    }
-
-    @LayoutlibDelegate
-    static void nSetPivotY(long groupPtr, float pivotY) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setPivotY(pivotY);
-    }
-
-    @LayoutlibDelegate
-    static float nGetScaleX(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getScaleX();
-    }
-
-    @LayoutlibDelegate
-    static void nSetScaleX(long groupPtr, float scaleX) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setScaleX(scaleX);
-    }
-
-    @LayoutlibDelegate
-    static float nGetScaleY(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getScaleY();
-    }
-
-    @LayoutlibDelegate
-    static void nSetScaleY(long groupPtr, float scaleY) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setScaleY(scaleY);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTranslateX(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getTranslateX();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTranslateX(long groupPtr, float translateX) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setTranslateX(translateX);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTranslateY(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getTranslateY();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTranslateY(long groupPtr, float translateY) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setTranslateY(translateY);
-    }
-
-    @LayoutlibDelegate
-    static void nSetPathData(long pathPtr, long pathDataPtr) {
-        VPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setPathData(PathParser_Delegate.getDelegate(pathDataPtr).getPathDataNodes());
-    }
-
-    @LayoutlibDelegate
-    static float nGetStrokeWidth(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getStrokeWidth();
-    }
-
-    @LayoutlibDelegate
-    static void nSetStrokeWidth(long pathPtr, float width) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setStrokeWidth(width);
-    }
-
-    @LayoutlibDelegate
-    static int nGetStrokeColor(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getStrokeColor();
-    }
-
-    @LayoutlibDelegate
-    static void nSetStrokeColor(long pathPtr, int strokeColor) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setStrokeColor(strokeColor);
-    }
-
-    @LayoutlibDelegate
-    static float nGetStrokeAlpha(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getStrokeAlpha();
-    }
-
-    @LayoutlibDelegate
-    static void nSetStrokeAlpha(long pathPtr, float alpha) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setStrokeAlpha(alpha);
-    }
-
-    @LayoutlibDelegate
-    static int nGetFillColor(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getFillColor();
-    }
-
-    @LayoutlibDelegate
-    static void nSetFillColor(long pathPtr, int fillColor) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setFillColor(fillColor);
-    }
-
-    @LayoutlibDelegate
-    static float nGetFillAlpha(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getFillAlpha();
-    }
-
-    @LayoutlibDelegate
-    static void nSetFillAlpha(long pathPtr, float fillAlpha) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setFillAlpha(fillAlpha);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTrimPathStart(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getTrimPathStart();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTrimPathStart(long pathPtr, float trimPathStart) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setTrimPathStart(trimPathStart);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTrimPathEnd(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getTrimPathEnd();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTrimPathEnd(long pathPtr, float trimPathEnd) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setTrimPathEnd(trimPathEnd);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTrimPathOffset(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getTrimPathOffset();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTrimPathOffset(long pathPtr, float trimPathOffset) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setTrimPathOffset(trimPathOffset);
-    }
-
-    /**
-     * Base class for all the internal Delegates that does two functions:
-     * <ol>
-     *     <li>Serves as base class to store all the delegates in one {@link DelegateManager}
-     *     <li>Provides setName for all the classes. {@link VPathRenderer_Delegate} does actually
-     *     not need it
-     * </ol>
-     */
-    abstract static class VNativeObject {
-        long mNativePtr = 0;
-
-        @NonNull
-        static <T> T getDelegate(long nativePtr) {
-            //noinspection unchecked
-            T vNativeObject = (T) sPathManager.getDelegate(nativePtr);
-
-            assert vNativeObject != null;
-            return vNativeObject;
-        }
-
-        abstract void setName(String name);
-
-        void setNativePtr(long nativePtr) {
-            mNativePtr = nativePtr;
-        }
-
-        /**
-         * Method to explicitly dispose native objects
-         */
-        void dispose() {
-        }
-    }
-
-    private static class VClipPath_Delegate extends VPath_Delegate {
-        private VClipPath_Delegate() {
-            // Empty constructor.
-        }
-
-        private VClipPath_Delegate(VClipPath_Delegate copy) {
-            super(copy);
-        }
-
-        @Override
-        public boolean isClipPath() {
-            return true;
-        }
-    }
-
-    static class VFullPath_Delegate extends VPath_Delegate {
-        // These constants need to be kept in sync with their values in VectorDrawable.VFullPath
-        private static final int STROKE_WIDTH_INDEX = 0;
-        private static final int STROKE_COLOR_INDEX = 1;
-        private static final int STROKE_ALPHA_INDEX = 2;
-        private static final int FILL_COLOR_INDEX = 3;
-        private static final int FILL_ALPHA_INDEX = 4;
-        private static final int TRIM_PATH_START_INDEX = 5;
-        private static final int TRIM_PATH_END_INDEX = 6;
-        private static final int TRIM_PATH_OFFSET_INDEX = 7;
-        private static final int STROKE_LINE_CAP_INDEX = 8;
-        private static final int STROKE_LINE_JOIN_INDEX = 9;
-        private static final int STROKE_MITER_LIMIT_INDEX = 10;
-        private static final int FILL_TYPE_INDEX = 11;
-
-        private static final int LINECAP_BUTT = 0;
-        private static final int LINECAP_ROUND = 1;
-        private static final int LINECAP_SQUARE = 2;
-
-        private static final int LINEJOIN_MITER = 0;
-        private static final int LINEJOIN_ROUND = 1;
-        private static final int LINEJOIN_BEVEL = 2;
-
-        @NonNull
-        public Consumer<Float> getFloatPropertySetter(int propertyIdx) {
-            switch (propertyIdx) {
-                case STROKE_WIDTH_INDEX:
-                    return this::setStrokeWidth;
-                case STROKE_ALPHA_INDEX:
-                    return this::setStrokeAlpha;
-                case FILL_ALPHA_INDEX:
-                    return this::setFillAlpha;
-                case TRIM_PATH_START_INDEX:
-                    return this::setTrimPathStart;
-                case TRIM_PATH_END_INDEX:
-                    return this::setTrimPathEnd;
-                case TRIM_PATH_OFFSET_INDEX:
-                    return this::setTrimPathOffset;
-            }
-
-            assert false : ("Invalid VFullPath_Delegate property index " + propertyIdx);
-            return t -> {};
-        }
-
-        @NonNull
-        public Consumer<Integer> getIntPropertySetter(int propertyIdx) {
-            switch (propertyIdx) {
-                case STROKE_COLOR_INDEX:
-                    return this::setStrokeColor;
-                case FILL_COLOR_INDEX:
-                    return this::setFillColor;
-            }
-
-            assert false : ("Invalid VFullPath_Delegate property index " + propertyIdx);
-            return t -> {};
-        }
-
-        /////////////////////////////////////////////////////
-        // Variables below need to be copied (deep copy if applicable) for mutation.
-
-        int mStrokeColor = Color.TRANSPARENT;
-        float mStrokeWidth = 0;
-
-        int mFillColor = Color.TRANSPARENT;
-        long mStrokeGradient = 0;
-        long mFillGradient = 0;
-        float mStrokeAlpha = 1.0f;
-        float mFillAlpha = 1.0f;
-        float mTrimPathStart = 0;
-        float mTrimPathEnd = 1;
-        float mTrimPathOffset = 0;
-
-        Cap mStrokeLineCap = BUTT;
-        Join mStrokeLineJoin = MITER;
-        float mStrokeMiterlimit = 4;
-
-        int mFillType = 0; // WINDING(0) is the default value. See Path.FillType
-
-        private VFullPath_Delegate() {
-            // Empty constructor.
-        }
-
-        private VFullPath_Delegate(VFullPath_Delegate copy) {
-            super(copy);
-
-            mStrokeColor = copy.mStrokeColor;
-            mStrokeWidth = copy.mStrokeWidth;
-            mStrokeAlpha = copy.mStrokeAlpha;
-            mFillColor = copy.mFillColor;
-            mFillAlpha = copy.mFillAlpha;
-            mTrimPathStart = copy.mTrimPathStart;
-            mTrimPathEnd = copy.mTrimPathEnd;
-            mTrimPathOffset = copy.mTrimPathOffset;
-
-            mStrokeLineCap = copy.mStrokeLineCap;
-            mStrokeLineJoin = copy.mStrokeLineJoin;
-            mStrokeMiterlimit = copy.mStrokeMiterlimit;
-
-            mStrokeGradient = copy.mStrokeGradient;
-            mFillGradient = copy.mFillGradient;
-            mFillType = copy.mFillType;
-        }
-
-        private int getStrokeLineCap() {
-            switch (mStrokeLineCap) {
-                case BUTT:
-                    return LINECAP_BUTT;
-                case ROUND:
-                    return LINECAP_ROUND;
-                case SQUARE:
-                    return LINECAP_SQUARE;
-                default:
-                    assert false;
-            }
-
-            return -1;
-        }
-
-        private void setStrokeLineCap(int cap) {
-            switch (cap) {
-                case LINECAP_BUTT:
-                    mStrokeLineCap = BUTT;
-                    break;
-                case LINECAP_ROUND:
-                    mStrokeLineCap = ROUND;
-                    break;
-                case LINECAP_SQUARE:
-                    mStrokeLineCap = SQUARE;
-                    break;
-                default:
-                    assert false;
-            }
-        }
-
-        private int getStrokeLineJoin() {
-            switch (mStrokeLineJoin) {
-                case MITER:
-                    return LINEJOIN_MITER;
-                case ROUND:
-                    return LINEJOIN_ROUND;
-                case BEVEL:
-                    return LINEJOIN_BEVEL;
-                default:
-                    assert false;
-            }
-
-            return -1;
-        }
-
-        private void setStrokeLineJoin(int join) {
-            switch (join) {
-                case LINEJOIN_BEVEL:
-                    mStrokeLineJoin = BEVEL;
-                    break;
-                case LINEJOIN_MITER:
-                    mStrokeLineJoin = MITER;
-                    break;
-                case LINEJOIN_ROUND:
-                    mStrokeLineJoin = Join.ROUND;
-                    break;
-                default:
-                    assert false;
-            }
-        }
-
-        private int getStrokeColor() {
-            return mStrokeColor;
-        }
-
-        private void setStrokeColor(int strokeColor) {
-            mStrokeColor = strokeColor;
-        }
-
-        private float getStrokeWidth() {
-            return mStrokeWidth;
-        }
-
-        private void setStrokeWidth(float strokeWidth) {
-            mStrokeWidth = strokeWidth;
-        }
-
-        private float getStrokeAlpha() {
-            return mStrokeAlpha;
-        }
-
-        private void setStrokeAlpha(float strokeAlpha) {
-            mStrokeAlpha = strokeAlpha;
-        }
-
-        private int getFillColor() {
-            return mFillColor;
-        }
-
-        private void setFillColor(int fillColor) {
-            mFillColor = fillColor;
-        }
-
-        private float getFillAlpha() {
-            return mFillAlpha;
-        }
-
-        private void setFillAlpha(float fillAlpha) {
-            mFillAlpha = fillAlpha;
-        }
-
-        private float getTrimPathStart() {
-            return mTrimPathStart;
-        }
-
-        private void setTrimPathStart(float trimPathStart) {
-            mTrimPathStart = trimPathStart;
-        }
-
-        private float getTrimPathEnd() {
-            return mTrimPathEnd;
-        }
-
-        private void setTrimPathEnd(float trimPathEnd) {
-            mTrimPathEnd = trimPathEnd;
-        }
-
-        private float getTrimPathOffset() {
-            return mTrimPathOffset;
-        }
-
-        private void setTrimPathOffset(float trimPathOffset) {
-            mTrimPathOffset = trimPathOffset;
-        }
-
-        private void setStrokeMiterlimit(float limit) {
-            mStrokeMiterlimit = limit;
-        }
-
-        private float getStrokeMiterlimit() {
-            return mStrokeMiterlimit;
-        }
-
-        private void setStrokeGradient(long gradientPtr) {
-            mStrokeGradient = gradientPtr;
-        }
-
-        private void setFillGradient(long gradientPtr) {
-            mFillGradient = gradientPtr;
-        }
-
-        private void setFillType(int fillType) {
-            mFillType = fillType;
-        }
-
-        private int getFillType() {
-            return mFillType;
-        }
-    }
-
-    static class VGroup_Delegate extends VNativeObject {
-        // This constants need to be kept in sync with their definitions in VectorDrawable.Group
-        private static final int ROTATE_INDEX = 0;
-        private static final int PIVOT_X_INDEX = 1;
-        private static final int PIVOT_Y_INDEX = 2;
-        private static final int SCALE_X_INDEX = 3;
-        private static final int SCALE_Y_INDEX = 4;
-        private static final int TRANSLATE_X_INDEX = 5;
-        private static final int TRANSLATE_Y_INDEX = 6;
-
-        public Consumer<Float> getPropertySetter(int propertyIdx) {
-            switch (propertyIdx) {
-                case ROTATE_INDEX:
-                    return this::setRotation;
-                case PIVOT_X_INDEX:
-                    return this::setPivotX;
-                case PIVOT_Y_INDEX:
-                    return this::setPivotY;
-                case SCALE_X_INDEX:
-                    return this::setScaleX;
-                case SCALE_Y_INDEX:
-                    return this::setScaleY;
-                case TRANSLATE_X_INDEX:
-                    return this::setTranslateX;
-                case TRANSLATE_Y_INDEX:
-                    return this::setTranslateY;
-            }
-
-            assert false : ("Invalid VGroup_Delegate property index " + propertyIdx);
-            return t -> {};
-        }
-
-        /////////////////////////////////////////////////////
-        // Variables below need to be copied (deep copy if applicable) for mutation.
-        final ArrayList<Object> mChildren = new ArrayList<>();
-        // mStackedMatrix is only used temporarily when drawing, it combines all
-        // the parents' local matrices with the current one.
-        private final Matrix mStackedMatrix = new Matrix();
-        // mLocalMatrix is updated based on the update of transformation information,
-        // either parsed from the XML or by animation.
-        private final Matrix mLocalMatrix = new Matrix();
-        private float mRotate = 0;
-        private float mPivotX = 0;
-        private float mPivotY = 0;
-        private float mScaleX = 1;
-        private float mScaleY = 1;
-        private float mTranslateX = 0;
-        private float mTranslateY = 0;
-        private int mChangingConfigurations;
-        private String mGroupName = null;
-
-        private VGroup_Delegate(VGroup_Delegate copy, ArrayMap<String, Object> targetsMap) {
-            mRotate = copy.mRotate;
-            mPivotX = copy.mPivotX;
-            mPivotY = copy.mPivotY;
-            mScaleX = copy.mScaleX;
-            mScaleY = copy.mScaleY;
-            mTranslateX = copy.mTranslateX;
-            mTranslateY = copy.mTranslateY;
-            mGroupName = copy.mGroupName;
-            mChangingConfigurations = copy.mChangingConfigurations;
-            if (mGroupName != null) {
-                targetsMap.put(mGroupName, this);
-            }
-
-            mLocalMatrix.set(copy.mLocalMatrix);
-        }
-
-        private VGroup_Delegate() {
-        }
-
-        private void updateLocalMatrix() {
-            // The order we apply is the same as the
-            // RenderNode.cpp::applyViewPropertyTransforms().
-            mLocalMatrix.reset();
-            mLocalMatrix.postTranslate(-mPivotX, -mPivotY);
-            mLocalMatrix.postScale(mScaleX, mScaleY);
-            mLocalMatrix.postRotate(mRotate, 0, 0);
-            mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY);
-        }
-
-        /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
-        private float getRotation() {
-            return mRotate;
-        }
-
-        private void setRotation(float rotation) {
-            if (rotation != mRotate) {
-                mRotate = rotation;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getPivotX() {
-            return mPivotX;
-        }
-
-        private void setPivotX(float pivotX) {
-            if (pivotX != mPivotX) {
-                mPivotX = pivotX;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getPivotY() {
-            return mPivotY;
-        }
-
-        private void setPivotY(float pivotY) {
-            if (pivotY != mPivotY) {
-                mPivotY = pivotY;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getScaleX() {
-            return mScaleX;
-        }
-
-        private void setScaleX(float scaleX) {
-            if (scaleX != mScaleX) {
-                mScaleX = scaleX;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getScaleY() {
-            return mScaleY;
-        }
-
-        private void setScaleY(float scaleY) {
-            if (scaleY != mScaleY) {
-                mScaleY = scaleY;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getTranslateX() {
-            return mTranslateX;
-        }
-
-        private void setTranslateX(float translateX) {
-            if (translateX != mTranslateX) {
-                mTranslateX = translateX;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getTranslateY() {
-            return mTranslateY;
-        }
-
-        private void setTranslateY(float translateY) {
-            if (translateY != mTranslateY) {
-                mTranslateY = translateY;
-                updateLocalMatrix();
-            }
-        }
-
-        @Override
-        public void setName(String name) {
-            mGroupName = name;
-        }
-
-        @Override
-        protected void dispose() {
-            mChildren.stream().filter(child -> child instanceof VNativeObject).forEach(child
-                    -> {
-                VNativeObject nativeObject = (VNativeObject) child;
-                if (nativeObject.mNativePtr != 0) {
-                    sPathManager.removeJavaReferenceFor(nativeObject.mNativePtr);
-                    nativeObject.mNativePtr = 0;
-                }
-                nativeObject.dispose();
-            });
-            mChildren.clear();
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            super.finalize();
-        }
-    }
-
-    public static class VPath_Delegate extends VNativeObject {
-        protected PathParser_Delegate.PathDataNode[] mNodes = null;
-        String mPathName;
-        int mChangingConfigurations;
-
-        public VPath_Delegate() {
-            // Empty constructor.
-        }
-
-        public VPath_Delegate(VPath_Delegate copy) {
-            mPathName = copy.mPathName;
-            mChangingConfigurations = copy.mChangingConfigurations;
-            mNodes = copy.mNodes != null ? PathParser_Delegate.deepCopyNodes(copy.mNodes) : null;
-        }
-
-        public void toPath(Path path) {
-            path.reset();
-            if (mNodes != null) {
-                PathParser_Delegate.PathDataNode.nodesToPath(mNodes,
-                        Path_Delegate.getDelegate(path.mNativePath));
-            }
-        }
-
-        @Override
-        public void setName(String name) {
-            mPathName = name;
-        }
-
-        public boolean isClipPath() {
-            return false;
-        }
-
-        private void setPathData(PathParser_Delegate.PathDataNode[] nodes) {
-            if (!PathParser_Delegate.canMorph(mNodes, nodes)) {
-                // This should not happen in the middle of animation.
-                mNodes = PathParser_Delegate.deepCopyNodes(nodes);
-            } else {
-                PathParser_Delegate.updateNodes(mNodes, nodes);
-            }
-        }
-
-        @Override
-        void dispose() {
-            mNodes = null;
-        }
-    }
-
-    static class VPathRenderer_Delegate extends VNativeObject {
-        /* Right now the internal data structure is organized as a tree.
-         * Each node can be a group node, or a path.
-         * A group node can have groups or paths as children, but a path node has
-         * no children.
-         * One example can be:
-         *                 Root Group
-         *                /    |     \
-         *           Group    Path    Group
-         *          /     \             |
-         *         Path   Path         Path
-         *
-         */
-        // Variables that only used temporarily inside the draw() call, so there
-        // is no need for deep copying.
-        private final Path mPath;
-        private final Path mRenderPath;
-        private final Matrix mFinalPathMatrix = new Matrix();
-        private final long mRootGroupPtr;
-        private float mViewportWidth = 0;
-        private float mViewportHeight = 0;
-        private float mRootAlpha = 1.0f;
-        private Paint mStrokePaint;
-        private Paint mFillPaint;
-        private PathMeasure mPathMeasure;
-
-        private VPathRenderer_Delegate(long rootGroupPtr) {
-            mRootGroupPtr = rootGroupPtr;
-            mPath = new Path();
-            mRenderPath = new Path();
-        }
-
-        private VPathRenderer_Delegate(VPathRenderer_Delegate rendererToCopy,
-                long rootGroupPtr) {
-            this(rootGroupPtr);
-            mViewportWidth = rendererToCopy.mViewportWidth;
-            mViewportHeight = rendererToCopy.mViewportHeight;
-            mRootAlpha = rendererToCopy.mRootAlpha;
-        }
-
-        private float getRootAlpha() {
-            return mRootAlpha;
-        }
-
-        void setRootAlpha(float alpha) {
-            mRootAlpha = alpha;
-        }
-
-        private void drawGroupTree(VGroup_Delegate currentGroup, Matrix currentMatrix,
-                long canvasPtr, int w, int h, long filterPtr) {
-            // Calculate current group's matrix by preConcat the parent's and
-            // and the current one on the top of the stack.
-            // Basically the Mfinal = Mviewport * M0 * M1 * M2;
-            // Mi the local matrix at level i of the group tree.
-            currentGroup.mStackedMatrix.set(currentMatrix);
-            currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix);
-
-            // Save the current clip information, which is local to this group.
-            Canvas_Delegate.nSave(canvasPtr, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
-            // Draw the group tree in the same order as the XML file.
-            for (int i = 0; i < currentGroup.mChildren.size(); i++) {
-                Object child = currentGroup.mChildren.get(i);
-                if (child instanceof VGroup_Delegate) {
-                    VGroup_Delegate childGroup = (VGroup_Delegate) child;
-                    drawGroupTree(childGroup, currentGroup.mStackedMatrix,
-                            canvasPtr, w, h, filterPtr);
-                } else if (child instanceof VPath_Delegate) {
-                    VPath_Delegate childPath = (VPath_Delegate) child;
-                    drawPath(currentGroup, childPath, canvasPtr, w, h, filterPtr);
-                }
-            }
-            Canvas_Delegate.nRestore(canvasPtr);
-        }
-
-        public void draw(long canvasPtr, long filterPtr, int w, int h) {
-            // Traverse the tree in pre-order to draw.
-            drawGroupTree(VNativeObject.getDelegate(mRootGroupPtr), Matrix.IDENTITY_MATRIX, canvasPtr, w, h, filterPtr);
-        }
-
-        private void drawPath(VGroup_Delegate VGroup, VPath_Delegate VPath, long canvasPtr,
-                int w,
-                int h,
-                long filterPtr) {
-            final float scaleX = w / mViewportWidth;
-            final float scaleY = h / mViewportHeight;
-            final float minScale = Math.min(scaleX, scaleY);
-            final Matrix groupStackedMatrix = VGroup.mStackedMatrix;
-
-            mFinalPathMatrix.set(groupStackedMatrix);
-            mFinalPathMatrix.postScale(scaleX, scaleY);
-
-            final float matrixScale = getMatrixScale(groupStackedMatrix);
-            if (matrixScale == 0) {
-                // When either x or y is scaled to 0, we don't need to draw anything.
-                return;
-            }
-            VPath.toPath(mPath);
-            final Path path = mPath;
-
-            mRenderPath.reset();
-
-            if (VPath.isClipPath()) {
-                mRenderPath.addPath(path, mFinalPathMatrix);
-                Canvas_Delegate.nClipPath(canvasPtr, mRenderPath.mNativePath, Op
-                        .INTERSECT.nativeInt);
-            } else {
-                VFullPath_Delegate fullPath = (VFullPath_Delegate) VPath;
-                if (fullPath.mTrimPathStart != 0.0f || fullPath.mTrimPathEnd != 1.0f) {
-                    float start = (fullPath.mTrimPathStart + fullPath.mTrimPathOffset) % 1.0f;
-                    float end = (fullPath.mTrimPathEnd + fullPath.mTrimPathOffset) % 1.0f;
-
-                    if (mPathMeasure == null) {
-                        mPathMeasure = new PathMeasure();
-                    }
-                    mPathMeasure.setPath(mPath, false);
-
-                    float len = mPathMeasure.getLength();
-                    start = start * len;
-                    end = end * len;
-                    path.reset();
-                    if (start > end) {
-                        mPathMeasure.getSegment(start, len, path, true);
-                        mPathMeasure.getSegment(0f, end, path, true);
-                    } else {
-                        mPathMeasure.getSegment(start, end, path, true);
-                    }
-                    path.rLineTo(0, 0); // fix bug in measure
-                }
-                mRenderPath.addPath(path, mFinalPathMatrix);
-
-                if (fullPath.mFillColor != Color.TRANSPARENT) {
-                    if (mFillPaint == null) {
-                        mFillPaint = new Paint();
-                        mFillPaint.setStyle(Style.FILL);
-                        mFillPaint.setAntiAlias(true);
-                    }
-
-                    final Paint fillPaint = mFillPaint;
-                    fillPaint.setColor(applyAlpha(applyAlpha(fullPath.mFillColor, fullPath
-                      .mFillAlpha), getRootAlpha()));
-                    Paint_Delegate fillPaintDelegate = Paint_Delegate.getDelegate(fillPaint
-                            .getNativeInstance());
-                    // mFillPaint can not be null at this point so we will have a delegate
-                    assert fillPaintDelegate != null;
-                    fillPaintDelegate.setColorFilter(filterPtr);
-                    fillPaintDelegate.setShader(fullPath.mFillGradient);
-                    Path_Delegate.nSetFillType(mRenderPath.mNativePath, fullPath.mFillType);
-                    BaseCanvas_Delegate.nDrawPath(canvasPtr, mRenderPath.mNativePath, fillPaint
-                            .getNativeInstance());
-                }
-
-                if (fullPath.mStrokeColor != Color.TRANSPARENT) {
-                    if (mStrokePaint == null) {
-                        mStrokePaint = new Paint();
-                        mStrokePaint.setStyle(Style.STROKE);
-                        mStrokePaint.setAntiAlias(true);
-                    }
-
-                    final Paint strokePaint = mStrokePaint;
-                    if (fullPath.mStrokeLineJoin != null) {
-                        strokePaint.setStrokeJoin(fullPath.mStrokeLineJoin);
-                    }
-
-                    if (fullPath.mStrokeLineCap != null) {
-                        strokePaint.setStrokeCap(fullPath.mStrokeLineCap);
-                    }
-
-                    strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit);
-                    strokePaint.setColor(applyAlpha(applyAlpha(fullPath.mStrokeColor, fullPath
-                      .mStrokeAlpha), getRootAlpha()));
-                    Paint_Delegate strokePaintDelegate = Paint_Delegate.getDelegate(strokePaint
-                            .getNativeInstance());
-                    // mStrokePaint can not be null at this point so we will have a delegate
-                    assert strokePaintDelegate != null;
-                    strokePaintDelegate.setColorFilter(filterPtr);
-                    final float finalStrokeScale = minScale * matrixScale;
-                    strokePaint.setStrokeWidth(fullPath.mStrokeWidth * finalStrokeScale);
-                    strokePaintDelegate.setShader(fullPath.mStrokeGradient);
-                    BaseCanvas_Delegate.nDrawPath(canvasPtr, mRenderPath.mNativePath, strokePaint
-                            .getNativeInstance());
-                }
-            }
-        }
-
-        private float getMatrixScale(Matrix groupStackedMatrix) {
-            // Given unit vectors A = (0, 1) and B = (1, 0).
-            // After matrix mapping, we got A' and B'. Let theta = the angel b/t A' and B'.
-            // Therefore, the final scale we want is min(|A'| * sin(theta), |B'| * sin(theta)),
-            // which is (|A'| * |B'| * sin(theta)) / max (|A'|, |B'|);
-            // If  max (|A'|, |B'|) = 0, that means either x or y has a scale of 0.
-            //
-            // For non-skew case, which is most of the cases, matrix scale is computing exactly the
-            // scale on x and y axis, and take the minimal of these two.
-            // For skew case, an unit square will mapped to a parallelogram. And this function will
-            // return the minimal height of the 2 bases.
-            float[] unitVectors = new float[]{0, 1, 1, 0};
-            groupStackedMatrix.mapVectors(unitVectors);
-            float scaleX = MathUtils.mag(unitVectors[0], unitVectors[1]);
-            float scaleY = MathUtils.mag(unitVectors[2], unitVectors[3]);
-            float crossProduct = MathUtils.cross(unitVectors[0], unitVectors[1],
-                    unitVectors[2], unitVectors[3]);
-            float maxScale = MathUtils.max(scaleX, scaleY);
-
-            float matrixScale = 0;
-            if (maxScale > 0) {
-                matrixScale = MathUtils.abs(crossProduct) / maxScale;
-            }
-            if (DBG_VECTOR_DRAWABLE) {
-                Log.d(LOGTAG, "Scale x " + scaleX + " y " + scaleY + " final " + matrixScale);
-            }
-            return matrixScale;
-        }
-
-        @Override
-        public void setName(String name) {
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            // The mRootGroupPtr is not explicitly freed by anything in the VectorDrawable so we
-            // need to free it here.
-            VNativeObject nativeObject = sPathManager.getDelegate(mRootGroupPtr);
-            sPathManager.removeJavaReferenceFor(mRootGroupPtr);
-            assert nativeObject != null;
-            nativeObject.dispose();
-
-            super.finalize();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java b/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java
deleted file mode 100644
index afbe97c0..0000000
--- a/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java
+++ /dev/null
@@ -1,80 +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.
- */
-
-package android.os;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Delegate overriding selected methods of android.os.HandlerThread
- *
- * Through the layoutlib_create tool, selected methods of Handler have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- *
- */
-public class HandlerThread_Delegate {
-
-    private static Map<BridgeContext, List<HandlerThread>> sThreads =
-            new HashMap<BridgeContext, List<HandlerThread>>();
-
-    public static void cleanUp(BridgeContext context) {
-        List<HandlerThread> list = sThreads.get(context);
-        if (list != null) {
-            for (HandlerThread thread : list) {
-                thread.quit();
-            }
-
-            list.clear();
-            sThreads.remove(context);
-        }
-    }
-
-    // -------- Delegate methods
-
-    @LayoutlibDelegate
-    /*package*/ static void run(HandlerThread theThread) {
-        // record the thread so that it can be quit() on clean up.
-        BridgeContext context = RenderAction.getCurrentContext();
-        List<HandlerThread> list = sThreads.get(context);
-        if (list == null) {
-            list = new ArrayList<HandlerThread>();
-            sThreads.put(context, list);
-        }
-
-        list.add(theThread);
-
-        // ---- START DEFAULT IMPLEMENTATION.
-
-        theThread.mTid = Process.myTid();
-        Looper.prepare();
-        synchronized (theThread) {
-            theThread.mLooper = Looper.myLooper();
-            theThread.notifyAll();
-        }
-        Process.setThreadPriority(theThread.mPriority);
-        theThread.onLooperPrepared();
-        Looper.loop();
-        theThread.mTid = -1;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java b/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java
deleted file mode 100644
index 2152c8a..0000000
--- a/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-
-/**
- * Delegate overriding selected methods of android.os.Handler
- *
- * Through the layoutlib_create tool, selected methods of Handler have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- *
- */
-public class Handler_Delegate {
-
-    // -------- Delegate methods
-
-    @LayoutlibDelegate
-    /*package*/ static boolean sendMessageAtTime(Handler handler, Message msg, long uptimeMillis) {
-        // get the callback
-        IHandlerCallback callback = sCallbacks.get();
-        if (callback != null) {
-            callback.sendMessageAtTime(handler, msg, uptimeMillis);
-        }
-        return true;
-    }
-
-    // -------- Delegate implementation
-
-    public interface IHandlerCallback {
-        void sendMessageAtTime(Handler handler, Message msg, long uptimeMillis);
-    }
-
-    private final static ThreadLocal<IHandlerCallback> sCallbacks =
-        new ThreadLocal<IHandlerCallback>();
-
-    public static void setCallback(IHandlerCallback callback) {
-        sCallbacks.set(callback);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/os/Looper_Accessor.java b/tools/layoutlib/bridge/src/android/os/Looper_Accessor.java
deleted file mode 100644
index 09f3e47..0000000
--- a/tools/layoutlib/bridge/src/android/os/Looper_Accessor.java
+++ /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.
- */
-package android.os;
-
-import java.lang.reflect.Field;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class Looper_Accessor {
-
-    public static void cleanupThread() {
-        // clean up the looper
-        Looper.sThreadLocal.remove();
-        try {
-            Field sMainLooper = Looper.class.getDeclaredField("sMainLooper");
-            sMainLooper.setAccessible(true);
-            sMainLooper.set(null, null);
-        } catch (SecurityException e) {
-            catchReflectionException();
-        } catch (IllegalArgumentException e) {
-            catchReflectionException();
-        } catch (NoSuchFieldException e) {
-            catchReflectionException();
-        } catch (IllegalAccessException e) {
-            catchReflectionException();
-        }
-
-    }
-
-    private static void catchReflectionException() {
-        assert(false);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/ServiceManager.java b/tools/layoutlib/bridge/src/android/os/ServiceManager.java
deleted file mode 100644
index 34c7845..0000000
--- a/tools/layoutlib/bridge/src/android/os/ServiceManager.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 android.os;
-
-import java.util.Map;
-
-public final class ServiceManager {
-
-    /**
-     * Returns a reference to a service with the given name.
-     *
-     * @param name the name of the service to get
-     * @return a reference to the service, or <code>null</code> if the service doesn't exist
-     */
-    public static IBinder getService(String name) {
-        return null;
-    }
-
-    /**
-     * Is not supposed to return null, but that is fine for layoutlib.
-     */
-    public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
-        throw new ServiceNotFoundException(name);
-    }
-
-    /**
-     * Place a new @a service called @a name into the service
-     * manager.
-     *
-     * @param name the name of the new service
-     * @param service the service object
-     */
-    public static void addService(String name, IBinder service) {
-        // pass
-    }
-
-    /**
-     * Retrieve an existing service called @a name from the
-     * service manager.  Non-blocking.
-     */
-    public static IBinder checkService(String name) {
-        return null;
-    }
-
-    /**
-     * Return a list of all currently running services.
-     * @return an array of all currently running services, or <code>null</code> in
-     * case of an exception
-     */
-    public static String[] listServices() {
-        // actual implementation returns null sometimes, so it's ok
-        // to return null instead of an empty list.
-        return null;
-    }
-
-    /**
-     * This is only intended to be called when the process is first being brought
-     * up and bound by the activity manager. There is only one thread in the process
-     * at that time, so no locking is done.
-     *
-     * @param cache the cache of service references
-     * @hide
-     */
-    public static void initServiceCache(Map<String, IBinder> cache) {
-        // pass
-    }
-
-    /**
-     * Exception thrown when no service published for given name. This might be
-     * thrown early during boot before certain services have published
-     * themselves.
-     *
-     * @hide
-     */
-    public static class ServiceNotFoundException extends Exception {
-        // identical to the original implementation
-        public ServiceNotFoundException(String name) {
-            super("No service published for: " + name);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java b/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
deleted file mode 100644
index 9677aaf..0000000
--- a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.java.System_Delegate;
-
-/**
- * Delegate implementing the native methods of android.os.SystemClock
- *
- * Through the layoutlib_create tool, the original native methods of SystemClock have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-public class SystemClock_Delegate {
-    /**
-     * Returns milliseconds since boot, not counting time spent in deep sleep.
-     * <b>Note:</b> This value may get reset occasionally (before it would
-     * otherwise wrap around).
-     *
-     * @return milliseconds of non-sleep uptime since boot.
-     */
-    @LayoutlibDelegate
-    /*package*/ static long uptimeMillis() {
-        return System_Delegate.currentTimeMillis() - System_Delegate.bootTimeMillis();
-    }
-
-    /**
-     * Returns milliseconds since boot, including time spent in sleep.
-     *
-     * @return elapsed milliseconds since boot.
-     */
-    @LayoutlibDelegate
-    /*package*/ static long elapsedRealtime() {
-        return System_Delegate.currentTimeMillis() - System_Delegate.bootTimeMillis();
-    }
-
-    /**
-     * Returns nanoseconds since boot, including time spent in sleep.
-     *
-     * @return elapsed nanoseconds since boot.
-     */
-    @LayoutlibDelegate
-    /*package*/ static long elapsedRealtimeNanos() {
-        return System_Delegate.nanoTime() - System_Delegate.bootTime();
-    }
-
-    /**
-     * Returns milliseconds running in the current thread.
-     *
-     * @return elapsed milliseconds in the thread
-     */
-    @LayoutlibDelegate
-    /*package*/ static long currentThreadTimeMillis() {
-        return System_Delegate.currentTimeMillis();
-    }
-
-    /**
-     * Returns microseconds running in the current thread.
-     *
-     * @return elapsed microseconds in the thread
-     *
-     * @hide
-     */
-    @LayoutlibDelegate
-    /*package*/ static long currentThreadTimeMicro() {
-        return System_Delegate.currentTimeMillis() * 1000;
-    }
-
-    /**
-     * Returns current wall time in  microseconds.
-     *
-     * @return elapsed microseconds in wall time
-     *
-     * @hide
-     */
-    @LayoutlibDelegate
-    /*package*/ static long currentTimeMicro() {
-        return elapsedRealtime() * 1000;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java b/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java
deleted file mode 100644
index d299add..0000000
--- a/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.util.Map;
-
-/**
- * Delegate implementing the native methods of android.os.SystemProperties
- *
- * Through the layoutlib_create tool, the original native methods of SystemProperties have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- */
-public class SystemProperties_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static String native_get(String key) {
-        return native_get(key, "");
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String native_get(String key, String def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        String value = properties.get(key);
-        if (value != null) {
-            return value;
-        }
-
-        return def;
-    }
-    @LayoutlibDelegate
-    /*package*/ static int native_get_int(String key, int def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        String value = properties.get(key);
-        if (value != null) {
-            return Integer.decode(value);
-        }
-
-        return def;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long native_get_long(String key, long def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        String value = properties.get(key);
-        if (value != null) {
-            return Long.decode(value);
-        }
-
-        return def;
-    }
-
-    /**
-     * Values 'n', 'no', '0', 'false' or 'off' are considered false.
-     * Values 'y', 'yes', '1', 'true' or 'on' are considered true.
-     */
-    @LayoutlibDelegate
-    /*package*/ static boolean native_get_boolean(String key, boolean def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        String value = properties.get(key);
-
-        if ("n".equals(value) || "no".equals(value) || "0".equals(value) || "false".equals(value)
-                || "off".equals(value)) {
-            return false;
-        }
-        //noinspection SimplifiableIfStatement
-        if ("y".equals(value) || "yes".equals(value) || "1".equals(value) || "true".equals(value)
-                || "on".equals(value)) {
-            return true;
-        }
-
-        return def;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_set(String key, String def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        properties.put(key, def);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_add_change_callback() {
-        // pass.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_report_sysprop_change() {
-        // pass.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/preference/BridgePreferenceInflater.java b/tools/layoutlib/bridge/src/android/preference/BridgePreferenceInflater.java
deleted file mode 100644
index aa393a9..0000000
--- a/tools/layoutlib/bridge/src/android/preference/BridgePreferenceInflater.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.preference;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.InflateException;
-
-public class BridgePreferenceInflater extends PreferenceInflater {
-
-    public BridgePreferenceInflater(Context context, PreferenceManager preferenceManager) {
-        super(context, preferenceManager);
-    }
-
-    @Override
-    protected Preference onCreateItem(String name, AttributeSet attrs)
-            throws ClassNotFoundException {
-        Object viewKey = null;
-        BridgeContext bc = null;
-
-        Context context = getContext();
-        if (context instanceof BridgeContext) {
-            bc = (BridgeContext) context;
-        }
-        if (attrs instanceof BridgeXmlBlockParser) {
-            viewKey = ((BridgeXmlBlockParser) attrs).getViewCookie();
-        }
-
-        Preference preference = null;
-        try {
-            preference = super.onCreateItem(name, attrs);
-        } catch (ClassNotFoundException | InflateException exception) {
-            // name is probably not a valid preference type
-            if ("SwitchPreferenceCompat".equals(name)) {
-                preference = super.onCreateItem("SwitchPreference", attrs);
-            }
-        }
-
-        if (viewKey != null && bc != null) {
-            bc.addCookie(preference, viewKey);
-        }
-        return preference;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/preference/Preference_Delegate.java b/tools/layoutlib/bridge/src/android/preference/Preference_Delegate.java
deleted file mode 100644
index 2e44a77..0000000
--- a/tools/layoutlib/bridge/src/android/preference/Preference_Delegate.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.preference;
-
-import com.android.internal.R;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ListView;
-
-/**
- * Delegate that provides implementation for native methods in {@link Preference}
- * <p/>
- * Through the layoutlib_create tool, selected methods of Preference have been replaced by calls to
- * methods of the same name in this delegate class.
- */
-public class Preference_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static View getView(Preference pref, View convertView, ViewGroup parent) {
-        Context context = pref.getContext();
-        BridgeContext bc = context instanceof BridgeContext ? ((BridgeContext) context) : null;
-        convertView = pref.getView_Original(convertView, parent);
-        if (bc != null) {
-            Object cookie = bc.getCookie(pref);
-            if (cookie != null) {
-                bc.addViewKey(convertView, cookie);
-            }
-        }
-        return convertView;
-    }
-
-    /**
-     * Inflates the parser and returns the ListView containing the Preferences.
-     */
-    public static View inflatePreference(Context context, XmlPullParser parser, ViewGroup root) {
-        PreferenceManager pm = new PreferenceManager(context);
-        PreferenceInflater inflater = new BridgePreferenceInflater(context, pm);
-        PreferenceScreen ps = (PreferenceScreen) inflater.inflate(parser, null, true);
-        pm.setPreferences(ps);
-        ListView preferenceView = createContainerView(context, root);
-        ps.bind(preferenceView);
-        return preferenceView;
-    }
-
-    private static ListView createContainerView(Context context, ViewGroup root) {
-        TypedArray a = context.obtainStyledAttributes(null, R.styleable.PreferenceFragment,
-                R.attr.preferenceFragmentStyle, 0);
-        int mLayoutResId = a.getResourceId(R.styleable.PreferenceFragment_layout,
-                        R.layout.preference_list_fragment);
-        a.recycle();
-
-        LayoutInflater inflater =
-                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        inflater.inflate(mLayoutResId, root, true);
-
-        return (ListView) root.findViewById(android.R.id.list);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java b/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java
deleted file mode 100644
index 38171dc..0000000
--- a/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java
+++ /dev/null
@@ -1,63 +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.
- */
-
-package android.text;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.icu.text.Bidi;
-
-/**
- * Delegate used to provide new implementation for the native methods of {@link AndroidBidi}
- *
- * Through the layoutlib_create tool, the original  methods of AndroidBidi have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class AndroidBidi_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static int runBidi(int dir, char[] chars, byte[] charInfo, int count,
-            boolean haveInfo) {
-
-        switch (dir) {
-        case 0: // Layout.DIR_REQUEST_LTR
-            dir = Bidi.LTR;
-            break;
-        case 1: // Layout.DIR_REQUEST_RTL
-            dir = Bidi.RTL;
-            break;
-        case -1: // Layout.DIR_REQUEST_DEFAULT_RTL
-            dir = Bidi.LEVEL_DEFAULT_RTL;
-            break;
-        case -2: // Layout.DIR_REQUEST_DEFAULT_LTR
-            dir = Bidi.LEVEL_DEFAULT_LTR;
-            break;
-        default:
-            // Invalid code. Log error, assume LEVEL_DEFAULT_LTR and continue.
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Invalid direction flag", null);
-            dir = Bidi.LEVEL_DEFAULT_LTR;
-        }
-        Bidi bidi = new Bidi(chars, 0, null, 0, count, dir);
-        if (charInfo != null) {
-            for (int i = 0; i < count; ++i)
-            charInfo[i] = bidi.getLevelAt(i);
-        }
-        return bidi.getParaLevel();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java b/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
deleted file mode 100644
index 50289e9..0000000
--- a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import android.annotation.NonNull;
-import android.text.Primitive.PrimitiveType;
-import android.text.StaticLayout.LineBreaks;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static android.text.Primitive.PrimitiveType.PENALTY_INFINITY;
-
-// Based on the native implementation of GreedyLineBreaker in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public class GreedyLineBreaker extends LineBreaker {
-
-    public GreedyLineBreaker(@NonNull List<Primitive> primitives, @NonNull LineWidth lineWidth,
-            @NonNull TabStops tabStops) {
-        super(primitives, lineWidth, tabStops);
-    }
-
-    @Override
-    public void computeBreaks(@NonNull LineBreaks lineBreaks) {
-        BreakInfo breakInfo = new BreakInfo();
-        int lineNum = 0;
-        float width = 0, printedWidth = 0;
-        boolean breakFound = false, goodBreakFound = false;
-        int breakIndex = 0, goodBreakIndex = 0;
-        float breakWidth = 0, goodBreakWidth = 0;
-        int firstTabIndex = Integer.MAX_VALUE;
-
-        float maxWidth = mLineWidth.getLineWidth(lineNum);
-
-        int numPrimitives = mPrimitives.size();
-        // greedily fit as many characters as possible on each line
-        // loop over all primitives, and choose the best break point
-        // (if possible, a break point without splitting a word)
-        // after going over the maximum length
-        for (int i = 0; i < numPrimitives; i++) {
-            Primitive p = mPrimitives.get(i);
-
-            // update the current line width
-            if (p.type == PrimitiveType.BOX || p.type == PrimitiveType.GLUE) {
-                width += p.width;
-                if (p.type == PrimitiveType.BOX) {
-                    printedWidth = width;
-                }
-            } else if (p.type == PrimitiveType.VARIABLE) {
-                width = mTabStops.width(width);
-                // keep track of first tab character in the region we are examining
-                // so we can determine whether or not a line contains a tab
-                firstTabIndex = Math.min(firstTabIndex, i);
-            }
-
-            // find the best break point for the characters examined so far
-            if (printedWidth > maxWidth) {
-                //noinspection StatementWithEmptyBody
-                if (breakFound || goodBreakFound) {
-                    if (goodBreakFound) {
-                        // a true line break opportunity existed in the characters examined so far,
-                        // so there is no need to split a word
-                        i = goodBreakIndex; // no +1 because of i++
-                        lineNum++;
-                        maxWidth = mLineWidth.getLineWidth(lineNum);
-                        breakInfo.mBreaksList.add(mPrimitives.get(goodBreakIndex).location);
-                        breakInfo.mWidthsList.add(goodBreakWidth);
-                        breakInfo.mFlagsList.add(firstTabIndex < goodBreakIndex);
-                        firstTabIndex = Integer.MAX_VALUE;
-                    } else {
-                        // must split a word because there is no other option
-                        i = breakIndex; // no +1 because of i++
-                        lineNum++;
-                        maxWidth = mLineWidth.getLineWidth(lineNum);
-                        breakInfo.mBreaksList.add(mPrimitives.get(breakIndex).location);
-                        breakInfo.mWidthsList.add(breakWidth);
-                        breakInfo.mFlagsList.add(firstTabIndex < breakIndex);
-                        firstTabIndex = Integer.MAX_VALUE;
-                    }
-                    printedWidth = width = 0;
-                    goodBreakFound = breakFound = false;
-                    goodBreakWidth = breakWidth = 0;
-                    continue;
-                } else {
-                    // no choice, keep going... must make progress by putting at least one
-                    // character on a line, even if part of that character is cut off --
-                    // there is no other option
-                }
-            }
-
-            // update possible break points
-            if (p.type == PrimitiveType.PENALTY &&
-                    p.penalty < PENALTY_INFINITY) {
-                // this does not handle penalties with width
-
-                // handle forced line break
-                if (p.penalty == -PENALTY_INFINITY) {
-                    lineNum++;
-                    maxWidth = mLineWidth.getLineWidth(lineNum);
-                    breakInfo.mBreaksList.add(p.location);
-                    breakInfo.mWidthsList.add(printedWidth);
-                    breakInfo.mFlagsList.add(firstTabIndex < i);
-                    firstTabIndex = Integer.MAX_VALUE;
-                    printedWidth = width = 0;
-                    goodBreakFound = breakFound = false;
-                    goodBreakWidth = breakWidth = 0;
-                    continue;
-                }
-                if (i > breakIndex && (printedWidth <= maxWidth || !breakFound)) {
-                    breakFound = true;
-                    breakIndex = i;
-                    breakWidth = printedWidth;
-                }
-                if (i > goodBreakIndex && printedWidth <= maxWidth) {
-                    goodBreakFound = true;
-                    goodBreakIndex = i;
-                    goodBreakWidth = printedWidth;
-                }
-            } else if (p.type == PrimitiveType.WORD_BREAK) {
-                // only do this if necessary -- we don't want to break words
-                // when possible, but sometimes it is unavoidable
-                if (i > breakIndex && (printedWidth <= maxWidth || !breakFound)) {
-                    breakFound = true;
-                    breakIndex = i;
-                    breakWidth = printedWidth;
-                }
-            }
-        }
-
-        if (breakFound || goodBreakFound) {
-            // output last break if there are more characters to output
-            if (goodBreakFound) {
-                breakInfo.mBreaksList.add(mPrimitives.get(goodBreakIndex).location);
-                breakInfo.mWidthsList.add(goodBreakWidth);
-                breakInfo.mFlagsList.add(firstTabIndex < goodBreakIndex);
-            } else {
-                breakInfo.mBreaksList.add(mPrimitives.get(breakIndex).location);
-                breakInfo.mWidthsList.add(breakWidth);
-                breakInfo.mFlagsList.add(firstTabIndex < breakIndex);
-            }
-        }
-        breakInfo.copyTo(lineBreaks);
-    }
-
-    private static class BreakInfo {
-        List<Integer> mBreaksList = new ArrayList<Integer>();
-        List<Float> mWidthsList = new ArrayList<Float>();
-        List<Boolean> mFlagsList = new ArrayList<Boolean>();
-
-        public void copyTo(LineBreaks lineBreaks) {
-            if (lineBreaks.breaks.length != mBreaksList.size()) {
-                lineBreaks.breaks = new int[mBreaksList.size()];
-                lineBreaks.widths = new float[mWidthsList.size()];
-                lineBreaks.flags = new int[mFlagsList.size()];
-            }
-
-            int i = 0;
-            for (int b : mBreaksList) {
-                lineBreaks.breaks[i] = b;
-                i++;
-            }
-            i = 0;
-            for (float b : mWidthsList) {
-                lineBreaks.widths[i] = b;
-                i++;
-            }
-            i = 0;
-            for (boolean b : mFlagsList) {
-                lineBreaks.flags[i] = b ? TAB_MASK : 0;
-                i++;
-            }
-
-            mBreaksList = null;
-            mWidthsList = null;
-            mFlagsList = null;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java b/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java
deleted file mode 100644
index 499e58a..0000000
--- a/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-
-/**
- * Delegate that overrides implementation for certain methods in {@link android.text.Hyphenator}
- * <p/>
- * Through the layoutlib_create tool, selected methods of Hyphenator have been replaced
- * by calls to methods of the same name in this delegate class.
- */
-public class Hyphenator_Delegate {
-
-    private static final DelegateManager<Hyphenator_Delegate> sDelegateManager = new
-            DelegateManager<Hyphenator_Delegate>(Hyphenator_Delegate.class);
-
-    @LayoutlibDelegate
-    /*package*/ static File getSystemHyphenatorLocation() {
-        // FIXME
-        return null;
-    }
-
-    /*package*/ @SuppressWarnings("UnusedParameters")  // TODO implement this.
-    static long loadHyphenator(ByteBuffer buffer, int offset, int minPrefix, int minSuffix) {
-        return sDelegateManager.addNewDelegate(new Hyphenator_Delegate());
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/LineBreaker.java b/tools/layoutlib/bridge/src/android/text/LineBreaker.java
deleted file mode 100644
index 06e9c84..0000000
--- a/tools/layoutlib/bridge/src/android/text/LineBreaker.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import android.annotation.NonNull;
-import android.text.StaticLayout.LineBreaks;
-
-import java.util.Collections;
-import java.util.List;
-
-// Based on the native implementation of LineBreaker in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public abstract class LineBreaker {
-
-    protected static final int TAB_MASK   = 0x20000000;  // keep in sync with StaticLayout
-
-    protected final @NonNull List<Primitive> mPrimitives;
-    protected final @NonNull LineWidth mLineWidth;
-    protected final @NonNull TabStops mTabStops;
-
-    public LineBreaker(@NonNull List<Primitive> primitives, @NonNull LineWidth lineWidth,
-            @NonNull TabStops tabStops) {
-        mPrimitives = Collections.unmodifiableList(primitives);
-        mLineWidth = lineWidth;
-        mTabStops = tabStops;
-    }
-
-    public abstract void computeBreaks(@NonNull LineBreaks breakInfo);
-}
diff --git a/tools/layoutlib/bridge/src/android/text/LineWidth.java b/tools/layoutlib/bridge/src/android/text/LineWidth.java
deleted file mode 100644
index 2ea886d..0000000
--- a/tools/layoutlib/bridge/src/android/text/LineWidth.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-// Based on the native implementation of LineWidth in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public class LineWidth {
-    private final float mFirstWidth;
-    private final int mFirstWidthLineCount;
-    private float mRestWidth;
-
-    public LineWidth(float firstWidth, int firstWidthLineCount, float restWidth) {
-        mFirstWidth = firstWidth;
-        mFirstWidthLineCount = firstWidthLineCount;
-        mRestWidth = restWidth;
-    }
-
-    public float getLineWidth(int line) {
-        return (line < mFirstWidthLineCount) ? mFirstWidth : mRestWidth;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java b/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java
deleted file mode 100644
index ed8e33a..0000000
--- a/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import android.annotation.NonNull;
-import android.text.Primitive.PrimitiveType;
-import android.text.StaticLayout.LineBreaks;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.ListIterator;
-
-import static android.text.Primitive.PrimitiveType.PENALTY_INFINITY;
-
-
-// Based on the native implementation of OptimizingLineBreaker in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-/**
- * A more complex version of line breaking where we try to prevent the right edge from being too
- * jagged.
- */
-public class OptimizingLineBreaker extends LineBreaker {
-
-    public OptimizingLineBreaker(@NonNull List<Primitive> primitives, @NonNull LineWidth lineWidth,
-            @NonNull TabStops tabStops) {
-        super(primitives, lineWidth, tabStops);
-    }
-
-    @Override
-    public void computeBreaks(@NonNull LineBreaks breakInfo) {
-        int numBreaks = mPrimitives.size();
-        assert numBreaks > 0;
-        if (numBreaks == 1) {
-            // This can be true only if it's an empty paragraph.
-            Primitive p = mPrimitives.get(0);
-            assert p.type == PrimitiveType.PENALTY;
-            breakInfo.breaks = new int[]{0};
-            breakInfo.widths = new float[]{p.width};
-            breakInfo.flags = new int[]{0};
-            return;
-        }
-        Node[] opt = new Node[numBreaks];
-        opt[0] = new Node(-1, 0, 0, 0, false);
-        opt[numBreaks - 1] = new Node(-1, 0, 0, 0, false);
-
-        ArrayList<Integer> active = new ArrayList<Integer>();
-        active.add(0);
-        int lastBreak = 0;
-        for (int i = 0; i < numBreaks; i++) {
-            Primitive p = mPrimitives.get(i);
-            if (p.type == PrimitiveType.PENALTY) {
-                boolean finalBreak = (i + 1 == numBreaks);
-                Node bestBreak = null;
-
-                for (ListIterator<Integer> it = active.listIterator(); it.hasNext();
-                        /* incrementing done in loop */) {
-                    int pos = it.next();
-                    int lines = opt[pos].mPrevCount;
-                    float maxWidth = mLineWidth.getLineWidth(lines);
-                    // we have to compute metrics every time --
-                    // we can't really pre-compute this stuff and just deal with breaks
-                    // because of the way tab characters work, this makes it computationally
-                    // harder, but this way, we can still optimize while treating tab characters
-                    // correctly
-                    LineMetrics lineMetrics = computeMetrics(pos, i);
-                    if (lineMetrics.mPrintedWidth <= maxWidth) {
-                        float demerits = computeDemerits(maxWidth, lineMetrics.mPrintedWidth,
-                                finalBreak, p.penalty) + opt[pos].mDemerits;
-                        if (bestBreak == null || demerits < bestBreak.mDemerits) {
-                            if (bestBreak == null) {
-                                bestBreak = new Node(pos, opt[pos].mPrevCount + 1, demerits,
-                                        lineMetrics.mPrintedWidth, lineMetrics.mHasTabs);
-                            } else {
-                                bestBreak.mPrev = pos;
-                                bestBreak.mPrevCount = opt[pos].mPrevCount + 1;
-                                bestBreak.mDemerits = demerits;
-                                bestBreak.mWidth = lineMetrics.mPrintedWidth;
-                                bestBreak.mHasTabs = lineMetrics.mHasTabs;
-                            }
-                        }
-                    } else {
-                        it.remove();
-                    }
-                }
-                if (p.penalty == -PENALTY_INFINITY) {
-                    active.clear();
-                }
-                if (bestBreak != null) {
-                    opt[i] = bestBreak;
-                    active.add(i);
-                    lastBreak = i;
-                }
-                if (active.isEmpty()) {
-                    // we can't give up!
-                    LineMetrics lineMetrics = new LineMetrics();
-                    int lines = opt[lastBreak].mPrevCount;
-                    float maxWidth = mLineWidth.getLineWidth(lines);
-                    int breakIndex = desperateBreak(lastBreak, numBreaks, maxWidth, lineMetrics);
-                    opt[breakIndex] = new Node(lastBreak, lines + 1, 0 /*doesn't matter*/,
-                            lineMetrics.mWidth, lineMetrics.mHasTabs);
-                    active.add(breakIndex);
-                    lastBreak = breakIndex;
-                    i = breakIndex; // incremented by i++
-                }
-            }
-        }
-
-        int idx = numBreaks - 1;
-        int count = opt[idx].mPrevCount;
-        resize(breakInfo, count);
-        while (opt[idx].mPrev != -1) {
-            count--;
-            assert count >=0;
-
-            breakInfo.breaks[count] = mPrimitives.get(idx).location;
-            breakInfo.widths[count] = opt[idx].mWidth;
-            breakInfo.flags [count] = opt[idx].mHasTabs ? TAB_MASK : 0;
-            idx = opt[idx].mPrev;
-        }
-    }
-
-    private static void resize(LineBreaks lineBreaks, int size) {
-        if (lineBreaks.breaks.length == size) {
-            return;
-        }
-        int[] breaks = new int[size];
-        float[] widths = new float[size];
-        int[] flags = new int[size];
-
-        int toCopy = Math.min(size, lineBreaks.breaks.length);
-        System.arraycopy(lineBreaks.breaks, 0, breaks, 0, toCopy);
-        System.arraycopy(lineBreaks.widths, 0, widths, 0, toCopy);
-        System.arraycopy(lineBreaks.flags, 0, flags, 0, toCopy);
-
-        lineBreaks.breaks = breaks;
-        lineBreaks.widths = widths;
-        lineBreaks.flags = flags;
-    }
-
-    @NonNull
-    private LineMetrics computeMetrics(int start, int end) {
-        boolean f = false;
-        float w = 0, pw = 0;
-        for (int i = start; i < end; i++) {
-            Primitive p = mPrimitives.get(i);
-            if (p.type == PrimitiveType.BOX || p.type == PrimitiveType.GLUE) {
-                w += p.width;
-                if (p.type == PrimitiveType.BOX) {
-                    pw = w;
-                }
-            } else if (p.type == PrimitiveType.VARIABLE) {
-                w = mTabStops.width(w);
-                f = true;
-            }
-        }
-        return new LineMetrics(w, pw, f);
-    }
-
-    private static float computeDemerits(float maxWidth, float width, boolean finalBreak,
-            float penalty) {
-        float deviation = finalBreak ? 0 : maxWidth - width;
-        return (deviation * deviation) + penalty;
-    }
-
-    /**
-     * @return the last break position or -1 if failed.
-     */
-    @SuppressWarnings("ConstantConditions")  // method too complex to be analyzed.
-    private int desperateBreak(int start, int limit, float maxWidth,
-            @NonNull LineMetrics lineMetrics) {
-        float w = 0, pw = 0;
-        boolean breakFound = false;
-        int breakIndex = 0, firstTabIndex = Integer.MAX_VALUE;
-        for (int i = start; i < limit; i++) {
-            Primitive p = mPrimitives.get(i);
-
-            if (p.type == PrimitiveType.BOX || p.type == PrimitiveType.GLUE) {
-                w += p.width;
-                if (p.type == PrimitiveType.BOX) {
-                    pw = w;
-                }
-            } else if (p.type == PrimitiveType.VARIABLE) {
-                w = mTabStops.width(w);
-                firstTabIndex = Math.min(firstTabIndex, i);
-            }
-
-            if (pw > maxWidth && breakFound) {
-                break;
-            }
-
-            // must make progress
-            if (i > start &&
-                    (p.type == PrimitiveType.PENALTY || p.type == PrimitiveType.WORD_BREAK)) {
-                breakFound = true;
-                breakIndex = i;
-            }
-        }
-
-        if (breakFound) {
-            lineMetrics.mWidth = w;
-            lineMetrics.mPrintedWidth = pw;
-            lineMetrics.mHasTabs = (start <= firstTabIndex && firstTabIndex < breakIndex);
-            return breakIndex;
-        } else {
-            return -1;
-        }
-    }
-
-    private static class LineMetrics {
-        /** Actual width of the line. */
-        float mWidth;
-        /** Width of the line minus trailing whitespace. */
-        float mPrintedWidth;
-        boolean mHasTabs;
-
-        public LineMetrics() {
-        }
-
-        public LineMetrics(float width, float printedWidth, boolean hasTabs) {
-            mWidth = width;
-            mPrintedWidth = printedWidth;
-            mHasTabs = hasTabs;
-        }
-    }
-
-    /**
-     * A struct to store the info about a break.
-     */
-    @SuppressWarnings("SpellCheckingInspection")  // For the word struct.
-    private static class Node {
-        // -1 for the first node.
-        int mPrev;
-        // number of breaks so far.
-        int mPrevCount;
-        float mDemerits;
-        float mWidth;
-        boolean mHasTabs;
-
-        public Node(int prev, int prevCount, float demerits, float width, boolean hasTabs) {
-            mPrev = prev;
-            mPrevCount = prevCount;
-            mDemerits = demerits;
-            mWidth = width;
-            mHasTabs = hasTabs;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/Primitive.java b/tools/layoutlib/bridge/src/android/text/Primitive.java
deleted file mode 100644
index 37ed072..0000000
--- a/tools/layoutlib/bridge/src/android/text/Primitive.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import android.annotation.NonNull;
-
-// Based on the native implementation of Primitive in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public class Primitive {
-    public final @NonNull PrimitiveType type;
-    public final int location;
-    // The following fields don't make sense for all types.
-    // Box and Glue have width only.
-    // Penalty has both width and penalty.
-    // Word_break has penalty only.
-    public final float width;
-    public final float penalty;
-
-    /**
-     * Use {@code PrimitiveType#getNewPrimitive()}
-     */
-    private Primitive(@NonNull PrimitiveType type, int location, float width, float penalty) {
-        this.type = type;
-        this.location = location;
-        this.width = width;
-        this.penalty = penalty;
-    }
-
-    public static enum PrimitiveType {
-        /**
-         * Something with a constant width that is to be typeset - like a character.
-         */
-        BOX,
-        /**
-         * Blank space with fixed width.
-         */
-        GLUE,
-        /**
-         * Aesthetic cost indicating how desirable breaking at this point will be. A penalty of
-         * {@link #PENALTY_INFINITY} means a forced non-break, whereas a penalty of negative
-         * {@code #PENALTY_INFINITY} means a forced break.
-         * <p/>
-         * Currently, it only stores penalty with values 0 or -infinity.
-         */
-        PENALTY,
-        /**
-         * For tabs - variable width space.
-         */
-        VARIABLE,
-        /**
-         * Possible breakpoints within a word. Think of this as a high cost {@link #PENALTY}.
-         */
-        WORD_BREAK;
-
-        public Primitive getNewPrimitive(int location) {
-            assert this == VARIABLE;
-            return new Primitive(this, location, 0f, 0f);
-        }
-
-        public Primitive getNewPrimitive(int location, float value) {
-            assert this == BOX || this == GLUE || this == WORD_BREAK;
-            if (this == BOX || this == GLUE) {
-                return new Primitive(this, location, value, 0f);
-            } else {
-                return new Primitive(this, location, 0f, value);
-            }
-        }
-
-        public Primitive getNewPrimitive(int location, float width, float penalty) {
-            assert this == PENALTY;
-            return new Primitive(this, location, width, penalty);
-        }
-
-        // forced non-break, negative infinity is forced break.
-        public static final float PENALTY_INFINITY = 1e7f;
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
deleted file mode 100644
index cc03143..0000000
--- a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
+++ /dev/null
@@ -1,238 +0,0 @@
-package android.text;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.graphics.BidiRenderer;
-import android.graphics.Paint;
-import android.graphics.Paint_Delegate;
-import android.graphics.RectF;
-import android.icu.text.BreakIterator;
-import android.icu.util.ULocale;
-import android.text.Primitive.PrimitiveType;
-import android.text.StaticLayout.LineBreaks;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.swing.text.Segment;
-
-/**
- * Delegate that provides implementation for native methods in {@link android.text.StaticLayout}
- * <p/>
- * Through the layoutlib_create tool, selected methods of StaticLayout have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class StaticLayout_Delegate {
-
-    private static final char CHAR_SPACE     = 0x20;
-    private static final char CHAR_TAB       = 0x09;
-    private static final char CHAR_NEWLINE   = 0x0A;
-    private static final char CHAR_ZWSP      = 0x200B;  // Zero width space.
-
-    // ---- Builder delegate manager ----
-    private static final DelegateManager<Builder> sBuilderManager =
-        new DelegateManager<Builder>(Builder.class);
-
-    @LayoutlibDelegate
-    /*package*/ static long nNewBuilder() {
-        return sBuilderManager.addNewDelegate(new Builder());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFreeBuilder(long nativeBuilder) {
-        sBuilderManager.removeJavaReferenceFor(nativeBuilder);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFinishBuilder(long nativeBuilder) {
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nLoadHyphenator(ByteBuffer buf, int offset, int minPrefix,
-            int minSuffix) {
-        return Hyphenator_Delegate.loadHyphenator(buf, offset, minPrefix, minSuffix);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetLocale(long nativeBuilder, String locale, long nativeHyphenator) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder != null) {
-            builder.mLocale = locale;
-            builder.mNativeHyphenator = nativeHyphenator;
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetIndents(long nativeBuilder, int[] indents) {
-        // TODO.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetupParagraph(long nativeBuilder, char[] text, int length,
-            float firstWidth, int firstWidthLineCount, float restWidth,
-            int[] variableTabStops, int defaultTabStop, int breakStrategy,
-            int hyphenationFrequency, boolean isJustified) {
-        // TODO: implement justified alignment
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder == null) {
-            return;
-        }
-
-        builder.mText = text;
-        builder.mWidths = new float[length];
-        builder.mLineWidth = new LineWidth(firstWidth, firstWidthLineCount, restWidth);
-        builder.mTabStopCalculator = new TabStops(variableTabStops, defaultTabStop);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nAddStyleRun(long nativeBuilder, long nativePaint, long nativeTypeface,
-            int start, int end, boolean isRtl) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-
-        int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
-        return builder == null ? 0 :
-                measureText(nativePaint, builder.mText, start, end - start, builder.mWidths,
-                        bidiFlags);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddMeasuredRun(long nativeBuilder, int start, int end, float[] widths) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder != null) {
-            System.arraycopy(widths, start, builder.mWidths, start, end - start);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddReplacementRun(long nativeBuilder, int start, int end, float width) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder == null) {
-            return;
-        }
-        builder.mWidths[start] = width;
-        Arrays.fill(builder.mWidths, start + 1, end, 0.0f);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetWidths(long nativeBuilder, float[] floatsArray) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder != null) {
-            System.arraycopy(builder.mWidths, 0, floatsArray, 0, builder.mWidths.length);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nComputeLineBreaks(long nativeBuilder,
-            LineBreaks recycle, int[] recycleBreaks, float[] recycleWidths,
-            int[] recycleFlags, int recycleLength) {
-
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder == null) {
-            return 0;
-        }
-
-        // compute all possible breakpoints.
-        int length = builder.mWidths.length;
-        BreakIterator it = BreakIterator.getLineInstance(new ULocale(builder.mLocale));
-        it.setText(new Segment(builder.mText, 0, length));
-
-        // average word length in english is 5. So, initialize the possible breaks with a guess.
-        List<Integer> breaks = new ArrayList<Integer>((int) Math.ceil(length / 5d));
-        int loc;
-        it.first();
-        while ((loc = it.next()) != BreakIterator.DONE) {
-            breaks.add(loc);
-        }
-
-        List<Primitive> primitives =
-                computePrimitives(builder.mText, builder.mWidths, length, breaks);
-        switch (builder.mBreakStrategy) {
-            case Layout.BREAK_STRATEGY_SIMPLE:
-                builder.mLineBreaker = new GreedyLineBreaker(primitives, builder.mLineWidth,
-                        builder.mTabStopCalculator);
-                break;
-            case Layout.BREAK_STRATEGY_HIGH_QUALITY:
-                // TODO
-//                break;
-            case Layout.BREAK_STRATEGY_BALANCED:
-                builder.mLineBreaker = new OptimizingLineBreaker(primitives, builder.mLineWidth,
-                        builder.mTabStopCalculator);
-                break;
-            default:
-                assert false : "Unknown break strategy: " + builder.mBreakStrategy;
-                builder.mLineBreaker = new GreedyLineBreaker(primitives, builder.mLineWidth,
-                        builder.mTabStopCalculator);
-        }
-        builder.mLineBreaker.computeBreaks(recycle);
-        return recycle.breaks.length;
-    }
-
-    /**
-     * Compute metadata each character - things which help in deciding if it's possible to break
-     * at a point or not.
-     */
-    @NonNull
-    private static List<Primitive> computePrimitives(@NonNull char[] text, @NonNull float[] widths,
-            int length, @NonNull List<Integer> breaks) {
-        // Initialize the list with a guess of the number of primitives:
-        // 2 Primitives per non-whitespace char and approx 5 chars per word (i.e. 83% chars)
-        List<Primitive> primitives = new ArrayList<Primitive>(((int) Math.ceil(length * 1.833)));
-        int breaksSize = breaks.size();
-        int breakIndex = 0;
-        for (int i = 0; i < length; i++) {
-            char c = text[i];
-            if (c == CHAR_SPACE || c == CHAR_ZWSP) {
-                primitives.add(PrimitiveType.GLUE.getNewPrimitive(i, widths[i]));
-            } else if (c == CHAR_TAB) {
-                primitives.add(PrimitiveType.VARIABLE.getNewPrimitive(i));
-            } else if (c != CHAR_NEWLINE) {
-                while (breakIndex < breaksSize && breaks.get(breakIndex) < i) {
-                    breakIndex++;
-                }
-                Primitive p;
-                if (widths[i] != 0) {
-                    if (breakIndex < breaksSize && breaks.get(breakIndex) == i) {
-                        p = PrimitiveType.PENALTY.getNewPrimitive(i, 0, 0);
-                    } else {
-                        p = PrimitiveType.WORD_BREAK.getNewPrimitive(i, 0);
-                    }
-                    primitives.add(p);
-                }
-
-                primitives.add(PrimitiveType.BOX.getNewPrimitive(i, widths[i]));
-            }
-        }
-        // final break at end of everything
-        primitives.add(
-                PrimitiveType.PENALTY.getNewPrimitive(length, 0, -PrimitiveType.PENALTY_INFINITY));
-        return primitives;
-    }
-
-    private static float measureText(long nativePaint, char []text, int index, int count,
-            float[] widths, int bidiFlags) {
-        Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
-        RectF bounds = new BidiRenderer(null, paint, text)
-            .renderText(index, index + count, bidiFlags, widths, 0, false);
-        return bounds.right - bounds.left;
-    }
-
-    // TODO: Rename to LineBreakerRef and move everything other than LineBreaker to LineBreaker.
-    /**
-     * Java representation of the native Builder class.
-     */
-    private static class Builder {
-        String mLocale;
-        char[] mText;
-        float[] mWidths;
-        LineBreaker mLineBreaker;
-        long mNativeHyphenator;
-        int mBreakStrategy;
-        LineWidth mLineWidth;
-        TabStops mTabStopCalculator;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/TabStops.java b/tools/layoutlib/bridge/src/android/text/TabStops.java
deleted file mode 100644
index 6c2f1e1..0000000
--- a/tools/layoutlib/bridge/src/android/text/TabStops.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import android.annotation.Nullable;
-
-// Based on the native implementation of TabStops in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public class TabStops {
-    @Nullable
-    private int[] mStops;
-    private final int mTabWidth;
-
-    public TabStops(@Nullable int[] stops, int defaultTabWidth) {
-        mTabWidth = defaultTabWidth;
-        mStops = stops;
-    }
-
-    public float width(float widthSoFar) {
-        if (mStops != null) {
-            for (int i : mStops) {
-                if (i > widthSoFar) {
-                    return i;
-                }
-            }
-        }
-        // find the next tabStop after widthSoFar.
-        return (int) ((widthSoFar + mTabWidth) / mTabWidth) * mTabWidth;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/format/DateFormat_Delegate.java b/tools/layoutlib/bridge/src/android/text/format/DateFormat_Delegate.java
deleted file mode 100644
index 1e4f213..0000000
--- a/tools/layoutlib/bridge/src/android/text/format/DateFormat_Delegate.java
+++ /dev/null
@@ -1,42 +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 android.text.format;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-
-
-/**
- * Delegate used to provide new implementation for the native methods of {@link DateFormat}
- *
- * Through the layoutlib_create tool, the original  methods of DateFormat have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class DateFormat_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static boolean is24HourFormat(Context context) {
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean is24HourFormat(Context context, int userHandle) {
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java b/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
deleted file mode 100644
index 9fd1e15..0000000
--- a/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import com.android.ide.common.rendering.api.AttrResourceValue;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.ResourceType;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import android.annotation.NonNull;
-
-import java.util.Map;
-import java.util.function.Function;
-
-/**
- * A correct implementation of the {@link AttributeSet} interface on top of a XmlPullParser
- */
-public class BridgeXmlPullAttributes extends XmlPullAttributes {
-
-    private final BridgeContext mContext;
-    private final boolean mPlatformFile;
-    private final Function<String, Map<String, Integer>> mFrameworkEnumValueSupplier;
-    private final Function<String, Map<String, Integer>> mProjectEnumValueSupplier;
-
-    // VisibleForTesting
-    BridgeXmlPullAttributes(@NonNull XmlPullParser parser, @NonNull BridgeContext context,
-            boolean platformFile,
-            @NonNull Function<String, Map<String, Integer>> frameworkEnumValueSupplier,
-            @NonNull Function<String, Map<String, Integer>> projectEnumValueSupplier) {
-        super(parser);
-        mContext = context;
-        mPlatformFile = platformFile;
-        mFrameworkEnumValueSupplier = frameworkEnumValueSupplier;
-        mProjectEnumValueSupplier = projectEnumValueSupplier;
-    }
-
-    public BridgeXmlPullAttributes(@NonNull XmlPullParser parser, @NonNull BridgeContext context,
-            boolean platformFile) {
-        this(parser, context, platformFile, Bridge::getEnumValues, attrName -> {
-            // get the styleable matching the resolved name
-            RenderResources res = context.getRenderResources();
-            ResourceValue attr = res.getProjectResource(ResourceType.ATTR, attrName);
-            return attr instanceof AttrResourceValue ?
-                    ((AttrResourceValue) attr).getAttributeValues() : null;
-        });
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see android.util.XmlPullAttributes#getAttributeNameResource(int)
-     *
-     * This methods must return com.android.internal.R.attr.<name> matching
-     * the name of the attribute.
-     * It returns 0 if it doesn't find anything.
-     */
-    @Override
-    public int getAttributeNameResource(int index) {
-        // get the attribute name.
-        String name = getAttributeName(index);
-
-        // get the attribute namespace
-        String ns = mParser.getAttributeNamespace(index);
-
-        if (BridgeConstants.NS_RESOURCES.equals(ns)) {
-            return Bridge.getResourceId(ResourceType.ATTR, name);
-
-        }
-
-        // this is not an attribute in the android namespace, we query the customviewloader, if
-        // the namespaces match.
-        if (mContext.getLayoutlibCallback().getNamespace().equals(ns)) {
-            Integer v = mContext.getLayoutlibCallback().getResourceId(ResourceType.ATTR, name);
-            if (v != null) {
-                return v;
-            }
-        }
-
-        return 0;
-    }
-
-    @Override
-    public int getAttributeListValue(String namespace, String attribute,
-            String[] options, int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToList(value, options, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(String namespace, String attribute,
-            boolean defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToBoolean(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-
-        return resolveResourceValue(value, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(String namespace, String attribute, int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value == null) {
-            return defaultValue;
-        }
-
-        ResourceValue r = getResourceValue(value);
-
-        if (r != null) {
-            value = r.getValue();
-        }
-
-        if (value.charAt(0) == '#') {
-            return ResourceHelper.getColor(value);
-        }
-
-        try {
-            return XmlUtils.convertValueToInt(value, defaultValue);
-        } catch (NumberFormatException e) {
-            // This is probably an enum
-            Map<String, Integer> enumValues = BridgeConstants.NS_RESOURCES.equals(namespace) ?
-                    mFrameworkEnumValueSupplier.apply(attribute) :
-                    mProjectEnumValueSupplier.apply(attribute);
-
-            Integer enumValue = enumValues != null ? enumValues.get(value) : null;
-            if (enumValue != null) {
-                return enumValue;
-            }
-
-            // We weren't able to find the enum int value
-            throw e;
-        }
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(String namespace, String attribute,
-            int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToUnsignedInt(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public float getAttributeFloatValue(String namespace, String attribute,
-            float defaultValue) {
-        String s = getAttributeValue(namespace, attribute);
-        if (s != null) {
-            ResourceValue r = getResourceValue(s);
-
-            if (r != null) {
-                s = r.getValue();
-            }
-
-            return Float.parseFloat(s);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public int getAttributeListValue(int index,
-            String[] options, int defaultValue) {
-        return XmlUtils.convertValueToList(
-            getAttributeValue(index), options, defaultValue);
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
-        String value = getAttributeValue(index);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToBoolean(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public int getAttributeResourceValue(int index, int defaultValue) {
-        String value = getAttributeValue(index);
-
-        return resolveResourceValue(value, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(int index, int defaultValue) {
-        return getAttributeIntValue(mParser.getAttributeNamespace(index),
-                getAttributeName(index)
-                , defaultValue);
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
-        String value = getAttributeValue(index);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToUnsignedInt(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public float getAttributeFloatValue(int index, float defaultValue) {
-        String s = getAttributeValue(index);
-        if (s != null) {
-            ResourceValue r = getResourceValue(s);
-
-            if (r != null) {
-                s = r.getValue();
-            }
-
-            return Float.parseFloat(s);
-        }
-
-        return defaultValue;
-    }
-
-    // -- private helper methods
-
-    /**
-     * Returns a resolved {@link ResourceValue} from a given value.
-     */
-    private ResourceValue getResourceValue(String value) {
-        // now look for this particular value
-        RenderResources resources = mContext.getRenderResources();
-        return resources.resolveResValue(resources.findResValue(value, mPlatformFile));
-    }
-
-    /**
-     * Resolves and return a value to its associated integer.
-     */
-    private int resolveResourceValue(String value, int defaultValue) {
-        ResourceValue resource = getResourceValue(value);
-        if (resource != null) {
-            Integer id = null;
-            if (mPlatformFile || resource.isFramework()) {
-                id = Bridge.getResourceId(resource.getResourceType(), resource.getName());
-            } else {
-                id = mContext.getLayoutlibCallback().getResourceId(
-                        resource.getResourceType(), resource.getName());
-            }
-
-            if (id != null) {
-                return id;
-            }
-        }
-
-        return defaultValue;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/Log_Delegate.java b/tools/layoutlib/bridge/src/android/util/Log_Delegate.java
deleted file mode 100644
index 7f432ab..0000000
--- a/tools/layoutlib/bridge/src/android/util/Log_Delegate.java
+++ /dev/null
@@ -1,51 +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.
- */
-
-package android.util;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-class Log_Delegate {
-    // to replicate prefix visible when using 'adb logcat'
-    private static char priorityChar(int priority) {
-        switch (priority) {
-            case Log.VERBOSE:
-                return 'V';
-            case Log.DEBUG:
-                return 'D';
-            case Log.INFO:
-                return 'I';
-            case Log.WARN:
-                return 'W';
-            case Log.ERROR:
-                return 'E';
-            case Log.ASSERT:
-                return 'A';
-            default:
-                return '?';
-        }
-    }
-
-    @LayoutlibDelegate
-    static int println_native(int bufID, int priority, String tag, String msgs) {
-        String prefix = priorityChar(priority) + "/" + tag + ": ";
-        for (String msg: msgs.split("\n")) {
-            System.out.println(prefix + msg);
-        }
-        return 0;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/util/LruCache.java b/tools/layoutlib/bridge/src/android/util/LruCache.java
deleted file mode 100644
index 5208606..0000000
--- a/tools/layoutlib/bridge/src/android/util/LruCache.java
+++ /dev/null
@@ -1,391 +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.
- */
-
-package android.util;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * BEGIN LAYOUTLIB CHANGE
- * This is a custom version that doesn't use the non standard LinkedHashMap#eldest.
- * END LAYOUTLIB CHANGE
- *
- * A cache that holds strong references to a limited number of values. Each time
- * a value is accessed, it is moved to the head of a queue. When a value is
- * added to a full cache, the value at the end of that queue is evicted and may
- * become eligible for garbage collection.
- *
- * <p>If your cached values hold resources that need to be explicitly released,
- * override {@link #entryRemoved}.
- *
- * <p>If a cache miss should be computed on demand for the corresponding keys,
- * override {@link #create}. This simplifies the calling code, allowing it to
- * assume a value will always be returned, even when there's a cache miss.
- *
- * <p>By default, the cache size is measured in the number of entries. Override
- * {@link #sizeOf} to size the cache in different units. For example, this cache
- * is limited to 4MiB of bitmaps:
- * <pre>   {@code
- *   int cacheSize = 4 * 1024 * 1024; // 4MiB
- *   LruCache<String, Bitmap> bitmapCache = new LruCache<String, Bitmap>(cacheSize) {
- *       protected int sizeOf(String key, Bitmap value) {
- *           return value.getByteCount();
- *       }
- *   }}</pre>
- *
- * <p>This class is thread-safe. Perform multiple cache operations atomically by
- * synchronizing on the cache: <pre>   {@code
- *   synchronized (cache) {
- *     if (cache.get(key) == null) {
- *         cache.put(key, value);
- *     }
- *   }}</pre>
- *
- * <p>This class does not allow null to be used as a key or value. A return
- * value of null from {@link #get}, {@link #put} or {@link #remove} is
- * unambiguous: the key was not in the cache.
- *
- * <p>This class appeared in Android 3.1 (Honeycomb MR1); it's available as part
- * of <a href="http://developer.android.com/sdk/compatibility-library.html">Android's
- * Support Package</a> for earlier releases.
- */
-public class LruCache<K, V> {
-    private final LinkedHashMap<K, V> map;
-
-    /** Size of this cache in units. Not necessarily the number of elements. */
-    private int size;
-    private int maxSize;
-
-    private int putCount;
-    private int createCount;
-    private int evictionCount;
-    private int hitCount;
-    private int missCount;
-
-    /**
-     * @param maxSize for caches that do not override {@link #sizeOf}, this is
-     *     the maximum number of entries in the cache. For all other caches,
-     *     this is the maximum sum of the sizes of the entries in this cache.
-     */
-    public LruCache(int maxSize) {
-        if (maxSize <= 0) {
-            throw new IllegalArgumentException("maxSize <= 0");
-        }
-        this.maxSize = maxSize;
-        this.map = new LinkedHashMap<K, V>(0, 0.75f, true);
-    }
-
-    /**
-     * Sets the size of the cache.
-     * @param maxSize The new maximum size.
-     *
-     * @hide
-     */
-    public void resize(int maxSize) {
-        if (maxSize <= 0) {
-            throw new IllegalArgumentException("maxSize <= 0");
-        }
-
-        synchronized (this) {
-            this.maxSize = maxSize;
-        }
-        trimToSize(maxSize);
-    }
-
-    /**
-     * Returns the value for {@code key} if it exists in the cache or can be
-     * created by {@code #create}. If a value was returned, it is moved to the
-     * head of the queue. This returns null if a value is not cached and cannot
-     * be created.
-     */
-    public final V get(K key) {
-        if (key == null) {
-            throw new NullPointerException("key == null");
-        }
-
-        V mapValue;
-        synchronized (this) {
-            mapValue = map.get(key);
-            if (mapValue != null) {
-                hitCount++;
-                return mapValue;
-            }
-            missCount++;
-        }
-
-        /*
-         * Attempt to create a value. This may take a long time, and the map
-         * may be different when create() returns. If a conflicting value was
-         * added to the map while create() was working, we leave that value in
-         * the map and release the created value.
-         */
-
-        V createdValue = create(key);
-        if (createdValue == null) {
-            return null;
-        }
-
-        synchronized (this) {
-            createCount++;
-            mapValue = map.put(key, createdValue);
-
-            if (mapValue != null) {
-                // There was a conflict so undo that last put
-                map.put(key, mapValue);
-            } else {
-                size += safeSizeOf(key, createdValue);
-            }
-        }
-
-        if (mapValue != null) {
-            entryRemoved(false, key, createdValue, mapValue);
-            return mapValue;
-        } else {
-            trimToSize(maxSize);
-            return createdValue;
-        }
-    }
-
-    /**
-     * Caches {@code value} for {@code key}. The value is moved to the head of
-     * the queue.
-     *
-     * @return the previous value mapped by {@code key}.
-     */
-    public final V put(K key, V value) {
-        if (key == null || value == null) {
-            throw new NullPointerException("key == null || value == null");
-        }
-
-        V previous;
-        synchronized (this) {
-            putCount++;
-            size += safeSizeOf(key, value);
-            previous = map.put(key, value);
-            if (previous != null) {
-                size -= safeSizeOf(key, previous);
-            }
-        }
-
-        if (previous != null) {
-            entryRemoved(false, key, previous, value);
-        }
-
-        trimToSize(maxSize);
-        return previous;
-    }
-
-    /**
-     * @param maxSize the maximum size of the cache before returning. May be -1
-     *     to evict even 0-sized elements.
-     */
-    private void trimToSize(int maxSize) {
-        while (true) {
-            K key;
-            V value;
-            synchronized (this) {
-                if (size < 0 || (map.isEmpty() && size != 0)) {
-                    throw new IllegalStateException(getClass().getName()
-                            + ".sizeOf() is reporting inconsistent results!");
-                }
-
-                if (size <= maxSize) {
-                    break;
-                }
-
-                // BEGIN LAYOUTLIB CHANGE
-                // get the last item in the linked list.
-                // This is not efficient, the goal here is to minimize the changes
-                // compared to the platform version.
-                Map.Entry<K, V> toEvict = null;
-                for (Map.Entry<K, V> entry : map.entrySet()) {
-                    toEvict = entry;
-                }
-                // END LAYOUTLIB CHANGE
-
-                if (toEvict == null) {
-                    break;
-                }
-
-                key = toEvict.getKey();
-                value = toEvict.getValue();
-                map.remove(key);
-                size -= safeSizeOf(key, value);
-                evictionCount++;
-            }
-
-            entryRemoved(true, key, value, null);
-        }
-    }
-
-    /**
-     * Removes the entry for {@code key} if it exists.
-     *
-     * @return the previous value mapped by {@code key}.
-     */
-    public final V remove(K key) {
-        if (key == null) {
-            throw new NullPointerException("key == null");
-        }
-
-        V previous;
-        synchronized (this) {
-            previous = map.remove(key);
-            if (previous != null) {
-                size -= safeSizeOf(key, previous);
-            }
-        }
-
-        if (previous != null) {
-            entryRemoved(false, key, previous, null);
-        }
-
-        return previous;
-    }
-
-    /**
-     * Called for entries that have been evicted or removed. This method is
-     * invoked when a value is evicted to make space, removed by a call to
-     * {@link #remove}, or replaced by a call to {@link #put}. The default
-     * implementation does nothing.
-     *
-     * <p>The method is called without synchronization: other threads may
-     * access the cache while this method is executing.
-     *
-     * @param evicted true if the entry is being removed to make space, false
-     *     if the removal was caused by a {@link #put} or {@link #remove}.
-     * @param newValue the new value for {@code key}, if it exists. If non-null,
-     *     this removal was caused by a {@link #put}. Otherwise it was caused by
-     *     an eviction or a {@link #remove}.
-     */
-    protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {}
-
-    /**
-     * Called after a cache miss to compute a value for the corresponding key.
-     * Returns the computed value or null if no value can be computed. The
-     * default implementation returns null.
-     *
-     * <p>The method is called without synchronization: other threads may
-     * access the cache while this method is executing.
-     *
-     * <p>If a value for {@code key} exists in the cache when this method
-     * returns, the created value will be released with {@link #entryRemoved}
-     * and discarded. This can occur when multiple threads request the same key
-     * at the same time (causing multiple values to be created), or when one
-     * thread calls {@link #put} while another is creating a value for the same
-     * key.
-     */
-    protected V create(K key) {
-        return null;
-    }
-
-    private int safeSizeOf(K key, V value) {
-        int result = sizeOf(key, value);
-        if (result < 0) {
-            throw new IllegalStateException("Negative size: " + key + "=" + value);
-        }
-        return result;
-    }
-
-    /**
-     * Returns the size of the entry for {@code key} and {@code value} in
-     * user-defined units.  The default implementation returns 1 so that size
-     * is the number of entries and max size is the maximum number of entries.
-     *
-     * <p>An entry's size must not change while it is in the cache.
-     */
-    protected int sizeOf(K key, V value) {
-        return 1;
-    }
-
-    /**
-     * Clear the cache, calling {@link #entryRemoved} on each removed entry.
-     */
-    public final void evictAll() {
-        trimToSize(-1); // -1 will evict 0-sized elements
-    }
-
-    /**
-     * For caches that do not override {@link #sizeOf}, this returns the number
-     * of entries in the cache. For all other caches, this returns the sum of
-     * the sizes of the entries in this cache.
-     */
-    public synchronized final int size() {
-        return size;
-    }
-
-    /**
-     * For caches that do not override {@link #sizeOf}, this returns the maximum
-     * number of entries in the cache. For all other caches, this returns the
-     * maximum sum of the sizes of the entries in this cache.
-     */
-    public synchronized final int maxSize() {
-        return maxSize;
-    }
-
-    /**
-     * Returns the number of times {@link #get} returned a value that was
-     * already present in the cache.
-     */
-    public synchronized final int hitCount() {
-        return hitCount;
-    }
-
-    /**
-     * Returns the number of times {@link #get} returned null or required a new
-     * value to be created.
-     */
-    public synchronized final int missCount() {
-        return missCount;
-    }
-
-    /**
-     * Returns the number of times {@link #create(Object)} returned a value.
-     */
-    public synchronized final int createCount() {
-        return createCount;
-    }
-
-    /**
-     * Returns the number of times {@link #put} was called.
-     */
-    public synchronized final int putCount() {
-        return putCount;
-    }
-
-    /**
-     * Returns the number of values that have been evicted.
-     */
-    public synchronized final int evictionCount() {
-        return evictionCount;
-    }
-
-    /**
-     * Returns a copy of the current contents of the cache, ordered from least
-     * recently accessed to most recently accessed.
-     */
-    public synchronized final Map<K, V> snapshot() {
-        return new LinkedHashMap<K, V>(map);
-    }
-
-    @Override public synchronized final String toString() {
-        int accesses = hitCount + missCount;
-        int hitPercent = accesses != 0 ? (100 * hitCount / accesses) : 0;
-        return String.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]",
-                maxSize, hitCount, missCount, hitPercent);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java b/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java
deleted file mode 100644
index 7b69388..0000000
--- a/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java
+++ /dev/null
@@ -1,844 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.graphics.Path_Delegate;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Delegate that provides implementation for native methods in {@link android.util.PathParser}
- * <p/>
- * Through the layoutlib_create tool, selected methods of PathParser have been replaced by calls to
- * methods of the same name in this delegate class.
- *
- * Most of the code has been taken from the implementation in
- * {@code tools/base/sdk-common/src/main/java/com/android/ide/common/vectordrawable/PathParser.java}
- * revision be6fe89a3b686db5a75e7e692a148699973957f3
- */
-public class PathParser_Delegate {
-
-    private static final Logger LOGGER = Logger.getLogger("PathParser");
-
-    // ---- Builder delegate manager ----
-    private static final DelegateManager<PathParser_Delegate> sManager =
-            new DelegateManager<PathParser_Delegate>(PathParser_Delegate.class);
-
-    // ---- delegate data ----
-    @NonNull
-    private PathDataNode[] mPathDataNodes;
-
-    public static PathParser_Delegate getDelegate(long nativePtr) {
-        return sManager.getDelegate(nativePtr);
-    }
-
-    private PathParser_Delegate(@NonNull PathDataNode[] nodes) {
-        mPathDataNodes = nodes;
-    }
-
-    public PathDataNode[] getPathDataNodes() {
-        return mPathDataNodes;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nParseStringForPath(long pathPtr, @NonNull String pathString, int
-            stringLength) {
-        Path_Delegate path_delegate = Path_Delegate.getDelegate(pathPtr);
-        if (path_delegate == null) {
-            return;
-        }
-        assert pathString.length() == stringLength;
-        PathDataNode.nodesToPath(createNodesFromPathData(pathString), path_delegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCreatePathFromPathData(long outPathPtr, long pathData) {
-        Path_Delegate path_delegate = Path_Delegate.getDelegate(outPathPtr);
-        PathParser_Delegate source = sManager.getDelegate(outPathPtr);
-        if (source == null || path_delegate == null) {
-            return;
-        }
-        PathDataNode.nodesToPath(source.mPathDataNodes, path_delegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateEmptyPathData() {
-        PathParser_Delegate newDelegate = new PathParser_Delegate(new PathDataNode[0]);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathData(long nativePtr) {
-        PathParser_Delegate source = sManager.getDelegate(nativePtr);
-        if (source == null) {
-            return 0;
-        }
-        PathParser_Delegate dest = new PathParser_Delegate(deepCopyNodes(source.mPathDataNodes));
-        return sManager.addNewDelegate(dest);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathDataFromString(@NonNull String pathString,
-            int stringLength) {
-        assert pathString.length() == stringLength : "Inconsistent path string length.";
-        PathDataNode[] nodes = createNodesFromPathData(pathString);
-        PathParser_Delegate delegate = new PathParser_Delegate(nodes);
-        return sManager.addNewDelegate(delegate);
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nInterpolatePathData(long outDataPtr, long fromDataPtr,
-            long toDataPtr, float fraction) {
-        PathParser_Delegate out = sManager.getDelegate(outDataPtr);
-        PathParser_Delegate from = sManager.getDelegate(fromDataPtr);
-        PathParser_Delegate to = sManager.getDelegate(toDataPtr);
-        if (out == null || from == null || to == null) {
-            return false;
-        }
-        int length = from.mPathDataNodes.length;
-        if (length != to.mPathDataNodes.length) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Cannot interpolate path data with different lengths (from " + length + " to " +
-                            to.mPathDataNodes.length + ").", null);
-            return false;
-        }
-        if (out.mPathDataNodes.length != length) {
-            out.mPathDataNodes = new PathDataNode[length];
-        }
-        for (int i = 0; i < length; i++) {
-            if (out.mPathDataNodes[i] == null) {
-                out.mPathDataNodes[i] = new PathDataNode(from.mPathDataNodes[i]);
-            }
-            out.mPathDataNodes[i].interpolatePathDataNode(from.mPathDataNodes[i],
-                        to.mPathDataNodes[i], fraction);
-        }
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFinalize(long nativePtr) {
-        sManager.removeJavaReferenceFor(nativePtr);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nCanMorph(long fromDataPtr, long toDataPtr) {
-        PathParser_Delegate fromPath = PathParser_Delegate.getDelegate(fromDataPtr);
-        PathParser_Delegate toPath = PathParser_Delegate.getDelegate(toDataPtr);
-        if (fromPath == null || toPath == null || fromPath.getPathDataNodes() == null || toPath
-                .getPathDataNodes() == null) {
-            return true;
-        }
-        return PathParser_Delegate.canMorph(fromPath.getPathDataNodes(), toPath.getPathDataNodes());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetPathData(long outDataPtr, long fromDataPtr) {
-        PathParser_Delegate out = sManager.getDelegate(outDataPtr);
-        PathParser_Delegate from = sManager.getDelegate(fromDataPtr);
-        if (from == null || out == null) {
-            return;
-        }
-        out.mPathDataNodes = deepCopyNodes(from.mPathDataNodes);
-    }
-
-    /**
-     * @param pathData The string representing a path, the same as "d" string in svg file.
-     *
-     * @return an array of the PathDataNode.
-     */
-    @NonNull
-    public static PathDataNode[] createNodesFromPathData(@NonNull String pathData) {
-        int start = 0;
-        int end = 1;
-
-        ArrayList<PathDataNode> list = new ArrayList<PathDataNode>();
-        while (end < pathData.length()) {
-            end = nextStart(pathData, end);
-            String s = pathData.substring(start, end).trim();
-            if (s.length() > 0) {
-                float[] val = getFloats(s);
-                addNode(list, s.charAt(0), val);
-            }
-
-            start = end;
-            end++;
-        }
-        if ((end - start) == 1 && start < pathData.length()) {
-            addNode(list, pathData.charAt(start), new float[0]);
-        }
-        return list.toArray(new PathDataNode[list.size()]);
-    }
-
-    /**
-     * @param source The array of PathDataNode to be duplicated.
-     *
-     * @return a deep copy of the <code>source</code>.
-     */
-    @NonNull
-    public static PathDataNode[] deepCopyNodes(@NonNull PathDataNode[] source) {
-        PathDataNode[] copy = new PathDataNode[source.length];
-        for (int i = 0; i < source.length; i++) {
-            copy[i] = new PathDataNode(source[i]);
-        }
-        return copy;
-    }
-
-    /**
-     * @param nodesFrom The source path represented in an array of PathDataNode
-     * @param nodesTo The target path represented in an array of PathDataNode
-     * @return whether the <code>nodesFrom</code> can morph into <code>nodesTo</code>
-     */
-    public static boolean canMorph(PathDataNode[] nodesFrom, PathDataNode[] nodesTo) {
-        if (nodesFrom == null || nodesTo == null) {
-            return false;
-        }
-
-        if (nodesFrom.length != nodesTo.length) {
-            return false;
-        }
-
-        for (int i = 0; i < nodesFrom.length; i ++) {
-            if (nodesFrom[i].mType != nodesTo[i].mType
-                    || nodesFrom[i].mParams.length != nodesTo[i].mParams.length) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Update the target's data to match the source.
-     * Before calling this, make sure canMorph(target, source) is true.
-     *
-     * @param target The target path represented in an array of PathDataNode
-     * @param source The source path represented in an array of PathDataNode
-     */
-    public static void updateNodes(PathDataNode[] target, PathDataNode[] source) {
-        for (int i = 0; i < source.length; i ++) {
-            target[i].mType = source[i].mType;
-            for (int j = 0; j < source[i].mParams.length; j ++) {
-                target[i].mParams[j] = source[i].mParams[j];
-            }
-        }
-    }
-
-    private static int nextStart(@NonNull String s, int end) {
-        char c;
-
-        while (end < s.length()) {
-            c = s.charAt(end);
-            // Note that 'e' or 'E' are not valid path commands, but could be
-            // used for floating point numbers' scientific notation.
-            // Therefore, when searching for next command, we should ignore 'e'
-            // and 'E'.
-            if ((((c - 'A') * (c - 'Z') <= 0) || ((c - 'a') * (c - 'z') <= 0))
-                    && c != 'e' && c != 'E') {
-                return end;
-            }
-            end++;
-        }
-        return end;
-    }
-
-    /**
-     * Calculate the position of the next comma or space or negative sign
-     *
-     * @param s the string to search
-     * @param start the position to start searching
-     * @param result the result of the extraction, including the position of the the starting
-     * position of next number, whether it is ending with a '-'.
-     */
-    private static void extract(@NonNull String s, int start, @NonNull ExtractFloatResult result) {
-        // Now looking for ' ', ',', '.' or '-' from the start.
-        int currentIndex = start;
-        boolean foundSeparator = false;
-        result.mEndWithNegOrDot = false;
-        boolean secondDot = false;
-        boolean isExponential = false;
-        for (; currentIndex < s.length(); currentIndex++) {
-            boolean isPrevExponential = isExponential;
-            isExponential = false;
-            char currentChar = s.charAt(currentIndex);
-            switch (currentChar) {
-                case ' ':
-                case ',':
-                    foundSeparator = true;
-                    break;
-                case '-':
-                    // The negative sign following a 'e' or 'E' is not a separator.
-                    if (currentIndex != start && !isPrevExponential) {
-                        foundSeparator = true;
-                        result.mEndWithNegOrDot = true;
-                    }
-                    break;
-                case '.':
-                    if (!secondDot) {
-                        secondDot = true;
-                    } else {
-                        // This is the second dot, and it is considered as a separator.
-                        foundSeparator = true;
-                        result.mEndWithNegOrDot = true;
-                    }
-                    break;
-                case 'e':
-                case 'E':
-                    isExponential = true;
-                    break;
-            }
-            if (foundSeparator) {
-                break;
-            }
-        }
-        // When there is nothing found, then we put the end position to the end
-        // of the string.
-        result.mEndPosition = currentIndex;
-    }
-
-    /**
-     * Parse the floats in the string. This is an optimized version of
-     * parseFloat(s.split(",|\\s"));
-     *
-     * @param s the string containing a command and list of floats
-     *
-     * @return array of floats
-     */
-    @NonNull
-    private static float[] getFloats(@NonNull String s) {
-        if (s.charAt(0) == 'z' || s.charAt(0) == 'Z') {
-            return new float[0];
-        }
-        try {
-            float[] results = new float[s.length()];
-            int count = 0;
-            int startPosition = 1;
-            int endPosition;
-
-            ExtractFloatResult result = new ExtractFloatResult();
-            int totalLength = s.length();
-
-            // The startPosition should always be the first character of the
-            // current number, and endPosition is the character after the current
-            // number.
-            while (startPosition < totalLength) {
-                extract(s, startPosition, result);
-                endPosition = result.mEndPosition;
-
-                if (startPosition < endPosition) {
-                    results[count++] = Float.parseFloat(
-                            s.substring(startPosition, endPosition));
-                }
-
-                if (result.mEndWithNegOrDot) {
-                    // Keep the '-' or '.' sign with next number.
-                    startPosition = endPosition;
-                } else {
-                    startPosition = endPosition + 1;
-                }
-            }
-            return Arrays.copyOf(results, count);
-        } catch (NumberFormatException e) {
-            assert false : "error in parsing \"" + s + "\"" + e;
-            return new float[0];
-        }
-    }
-
-
-    private static void addNode(@NonNull ArrayList<PathDataNode> list, char cmd,
-            @NonNull float[] val) {
-        list.add(new PathDataNode(cmd, val));
-    }
-
-    private static class ExtractFloatResult {
-        // We need to return the position of the next separator and whether the
-        // next float starts with a '-' or a '.'.
-        private int mEndPosition;
-        private boolean mEndWithNegOrDot;
-    }
-
-    /**
-     * Each PathDataNode represents one command in the "d" attribute of the svg file. An array of
-     * PathDataNode can represent the whole "d" attribute.
-     */
-    public static class PathDataNode {
-        private char mType;
-        @NonNull
-        private float[] mParams;
-
-        private PathDataNode(char type, @NonNull float[] params) {
-            mType = type;
-            mParams = params;
-        }
-
-        public char getType() {
-            return mType;
-        }
-
-        @NonNull
-        public float[] getParams() {
-            return mParams;
-        }
-
-        private PathDataNode(@NonNull PathDataNode n) {
-            mType = n.mType;
-            mParams = Arrays.copyOf(n.mParams, n.mParams.length);
-        }
-
-        /**
-         * Convert an array of PathDataNode to Path. Reset the passed path as needed before
-         * calling this method.
-         *
-         * @param node The source array of PathDataNode.
-         * @param path The target Path object.
-         */
-        public static void nodesToPath(@NonNull PathDataNode[] node, @NonNull Path_Delegate path) {
-            float[] current = new float[6];
-            char previousCommand = 'm';
-            //noinspection ForLoopReplaceableByForEach
-            for (int i = 0; i < node.length; i++) {
-                addCommand(path, current, previousCommand, node[i].mType, node[i].mParams);
-                previousCommand = node[i].mType;
-            }
-        }
-
-        /**
-         * The current PathDataNode will be interpolated between the <code>nodeFrom</code> and
-         * <code>nodeTo</code> according to the <code>fraction</code>.
-         *
-         * @param nodeFrom The start value as a PathDataNode.
-         * @param nodeTo The end value as a PathDataNode
-         * @param fraction The fraction to interpolate.
-         */
-        private void interpolatePathDataNode(@NonNull PathDataNode nodeFrom,
-                @NonNull PathDataNode nodeTo, float fraction) {
-            for (int i = 0; i < nodeFrom.mParams.length; i++) {
-                mParams[i] = nodeFrom.mParams[i] * (1 - fraction)
-                        + nodeTo.mParams[i] * fraction;
-            }
-        }
-
-        @SuppressWarnings("PointlessArithmeticExpression")
-        private static void addCommand(@NonNull Path_Delegate path, float[] current,
-                char previousCmd, char cmd, @NonNull float[] val) {
-
-            int incr = 2;
-            float currentX = current[0];
-            float currentY = current[1];
-            float ctrlPointX = current[2];
-            float ctrlPointY = current[3];
-            float currentSegmentStartX = current[4];
-            float currentSegmentStartY = current[5];
-            float reflectiveCtrlPointX;
-            float reflectiveCtrlPointY;
-
-            switch (cmd) {
-                case 'z':
-                case 'Z':
-                    path.close();
-                    // Path is closed here, but we need to move the pen to the
-                    // closed position. So we cache the segment's starting position,
-                    // and restore it here.
-                    currentX = currentSegmentStartX;
-                    currentY = currentSegmentStartY;
-                    ctrlPointX = currentSegmentStartX;
-                    ctrlPointY = currentSegmentStartY;
-                    path.moveTo(currentX, currentY);
-                    break;
-                case 'm':
-                case 'M':
-                case 'l':
-                case 'L':
-                case 't':
-                case 'T':
-                    incr = 2;
-                    break;
-                case 'h':
-                case 'H':
-                case 'v':
-                case 'V':
-                    incr = 1;
-                    break;
-                case 'c':
-                case 'C':
-                    incr = 6;
-                    break;
-                case 's':
-                case 'S':
-                case 'q':
-                case 'Q':
-                    incr = 4;
-                    break;
-                case 'a':
-                case 'A':
-                    incr = 7;
-                    break;
-            }
-
-            for (int k = 0; k < val.length; k += incr) {
-                switch (cmd) {
-                    case 'm': // moveto - Start a new sub-path (relative)
-                        currentX += val[k + 0];
-                        currentY += val[k + 1];
-
-                        if (k > 0) {
-                            // According to the spec, if a moveto is followed by multiple
-                            // pairs of coordinates, the subsequent pairs are treated as
-                            // implicit lineto commands.
-                            path.rLineTo(val[k + 0], val[k + 1]);
-                        } else {
-                            path.rMoveTo(val[k + 0], val[k + 1]);
-                            currentSegmentStartX = currentX;
-                            currentSegmentStartY = currentY;
-                        }
-                        break;
-                    case 'M': // moveto - Start a new sub-path
-                        currentX = val[k + 0];
-                        currentY = val[k + 1];
-
-                        if (k > 0) {
-                            // According to the spec, if a moveto is followed by multiple
-                            // pairs of coordinates, the subsequent pairs are treated as
-                            // implicit lineto commands.
-                            path.lineTo(val[k + 0], val[k + 1]);
-                        } else {
-                            path.moveTo(val[k + 0], val[k + 1]);
-                            currentSegmentStartX = currentX;
-                            currentSegmentStartY = currentY;
-                        }
-                        break;
-                    case 'l': // lineto - Draw a line from the current point (relative)
-                        path.rLineTo(val[k + 0], val[k + 1]);
-                        currentX += val[k + 0];
-                        currentY += val[k + 1];
-                        break;
-                    case 'L': // lineto - Draw a line from the current point
-                        path.lineTo(val[k + 0], val[k + 1]);
-                        currentX = val[k + 0];
-                        currentY = val[k + 1];
-                        break;
-                    case 'h': // horizontal lineto - Draws a horizontal line (relative)
-                        path.rLineTo(val[k + 0], 0);
-                        currentX += val[k + 0];
-                        break;
-                    case 'H': // horizontal lineto - Draws a horizontal line
-                        path.lineTo(val[k + 0], currentY);
-                        currentX = val[k + 0];
-                        break;
-                    case 'v': // vertical lineto - Draws a vertical line from the current point (r)
-                        path.rLineTo(0, val[k + 0]);
-                        currentY += val[k + 0];
-                        break;
-                    case 'V': // vertical lineto - Draws a vertical line from the current point
-                        path.lineTo(currentX, val[k + 0]);
-                        currentY = val[k + 0];
-                        break;
-                    case 'c': // curveto - Draws a cubic Bézier curve (relative)
-                        path.rCubicTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3],
-                                val[k + 4], val[k + 5]);
-
-                        ctrlPointX = currentX + val[k + 2];
-                        ctrlPointY = currentY + val[k + 3];
-                        currentX += val[k + 4];
-                        currentY += val[k + 5];
-
-                        break;
-                    case 'C': // curveto - Draws a cubic Bézier curve
-                        path.cubicTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3],
-                                val[k + 4], val[k + 5]);
-                        currentX = val[k + 4];
-                        currentY = val[k + 5];
-                        ctrlPointX = val[k + 2];
-                        ctrlPointY = val[k + 3];
-                        break;
-                    case 's': // smooth curveto - Draws a cubic Bézier curve (reflective cp)
-                        reflectiveCtrlPointX = 0;
-                        reflectiveCtrlPointY = 0;
-                        if (previousCmd == 'c' || previousCmd == 's'
-                                || previousCmd == 'C' || previousCmd == 'S') {
-                            reflectiveCtrlPointX = currentX - ctrlPointX;
-                            reflectiveCtrlPointY = currentY - ctrlPointY;
-                        }
-                        path.rCubicTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
-                                val[k + 0], val[k + 1],
-                                val[k + 2], val[k + 3]);
-
-                        ctrlPointX = currentX + val[k + 0];
-                        ctrlPointY = currentY + val[k + 1];
-                        currentX += val[k + 2];
-                        currentY += val[k + 3];
-                        break;
-                    case 'S': // shorthand/smooth curveto Draws a cubic Bézier curve(reflective cp)
-                        reflectiveCtrlPointX = currentX;
-                        reflectiveCtrlPointY = currentY;
-                        if (previousCmd == 'c' || previousCmd == 's'
-                                || previousCmd == 'C' || previousCmd == 'S') {
-                            reflectiveCtrlPointX = 2 * currentX - ctrlPointX;
-                            reflectiveCtrlPointY = 2 * currentY - ctrlPointY;
-                        }
-                        path.cubicTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
-                                val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
-                        ctrlPointX = val[k + 0];
-                        ctrlPointY = val[k + 1];
-                        currentX = val[k + 2];
-                        currentY = val[k + 3];
-                        break;
-                    case 'q': // Draws a quadratic Bézier (relative)
-                        path.rQuadTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
-                        ctrlPointX = currentX + val[k + 0];
-                        ctrlPointY = currentY + val[k + 1];
-                        currentX += val[k + 2];
-                        currentY += val[k + 3];
-                        break;
-                    case 'Q': // Draws a quadratic Bézier
-                        path.quadTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
-                        ctrlPointX = val[k + 0];
-                        ctrlPointY = val[k + 1];
-                        currentX = val[k + 2];
-                        currentY = val[k + 3];
-                        break;
-                    case 't': // Draws a quadratic Bézier curve(reflective control point)(relative)
-                        reflectiveCtrlPointX = 0;
-                        reflectiveCtrlPointY = 0;
-                        if (previousCmd == 'q' || previousCmd == 't'
-                                || previousCmd == 'Q' || previousCmd == 'T') {
-                            reflectiveCtrlPointX = currentX - ctrlPointX;
-                            reflectiveCtrlPointY = currentY - ctrlPointY;
-                        }
-                        path.rQuadTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
-                                val[k + 0], val[k + 1]);
-                        ctrlPointX = currentX + reflectiveCtrlPointX;
-                        ctrlPointY = currentY + reflectiveCtrlPointY;
-                        currentX += val[k + 0];
-                        currentY += val[k + 1];
-                        break;
-                    case 'T': // Draws a quadratic Bézier curve (reflective control point)
-                        reflectiveCtrlPointX = currentX;
-                        reflectiveCtrlPointY = currentY;
-                        if (previousCmd == 'q' || previousCmd == 't'
-                                || previousCmd == 'Q' || previousCmd == 'T') {
-                            reflectiveCtrlPointX = 2 * currentX - ctrlPointX;
-                            reflectiveCtrlPointY = 2 * currentY - ctrlPointY;
-                        }
-                        path.quadTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
-                                val[k + 0], val[k + 1]);
-                        ctrlPointX = reflectiveCtrlPointX;
-                        ctrlPointY = reflectiveCtrlPointY;
-                        currentX = val[k + 0];
-                        currentY = val[k + 1];
-                        break;
-                    case 'a': // Draws an elliptical arc
-                        // (rx ry x-axis-rotation large-arc-flag sweep-flag x y)
-                        drawArc(path,
-                                currentX,
-                                currentY,
-                                val[k + 5] + currentX,
-                                val[k + 6] + currentY,
-                                val[k + 0],
-                                val[k + 1],
-                                val[k + 2],
-                                val[k + 3] != 0,
-                                val[k + 4] != 0);
-                        currentX += val[k + 5];
-                        currentY += val[k + 6];
-                        ctrlPointX = currentX;
-                        ctrlPointY = currentY;
-                        break;
-                    case 'A': // Draws an elliptical arc
-                        drawArc(path,
-                                currentX,
-                                currentY,
-                                val[k + 5],
-                                val[k + 6],
-                                val[k + 0],
-                                val[k + 1],
-                                val[k + 2],
-                                val[k + 3] != 0,
-                                val[k + 4] != 0);
-                        currentX = val[k + 5];
-                        currentY = val[k + 6];
-                        ctrlPointX = currentX;
-                        ctrlPointY = currentY;
-                        break;
-                }
-                previousCmd = cmd;
-            }
-            current[0] = currentX;
-            current[1] = currentY;
-            current[2] = ctrlPointX;
-            current[3] = ctrlPointY;
-            current[4] = currentSegmentStartX;
-            current[5] = currentSegmentStartY;
-        }
-
-        private static void drawArc(@NonNull Path_Delegate p, float x0, float y0, float x1,
-                float y1, float a, float b, float theta, boolean isMoreThanHalf,
-                boolean isPositiveArc) {
-
-            LOGGER.log(Level.FINE, "(" + x0 + "," + y0 + ")-(" + x1 + "," + y1
-                    + ") {" + a + " " + b + "}");
-        /* Convert rotation angle from degrees to radians */
-            double thetaD = theta * Math.PI / 180.0f;
-        /* Pre-compute rotation matrix entries */
-            double cosTheta = Math.cos(thetaD);
-            double sinTheta = Math.sin(thetaD);
-        /* Transform (x0, y0) and (x1, y1) into unit space */
-        /* using (inverse) rotation, followed by (inverse) scale */
-            double x0p = (x0 * cosTheta + y0 * sinTheta) / a;
-            double y0p = (-x0 * sinTheta + y0 * cosTheta) / b;
-            double x1p = (x1 * cosTheta + y1 * sinTheta) / a;
-            double y1p = (-x1 * sinTheta + y1 * cosTheta) / b;
-            LOGGER.log(Level.FINE, "unit space (" + x0p + "," + y0p + ")-(" + x1p
-                    + "," + y1p + ")");
-        /* Compute differences and averages */
-            double dx = x0p - x1p;
-            double dy = y0p - y1p;
-            double xm = (x0p + x1p) / 2;
-            double ym = (y0p + y1p) / 2;
-        /* Solve for intersecting unit circles */
-            double dsq = dx * dx + dy * dy;
-            if (dsq == 0.0) {
-                LOGGER.log(Level.FINE, " Points are coincident");
-                return; /* Points are coincident */
-            }
-            double disc = 1.0 / dsq - 1.0 / 4.0;
-            if (disc < 0.0) {
-                LOGGER.log(Level.FINE, "Points are too far apart " + dsq);
-                float adjust = (float) (Math.sqrt(dsq) / 1.99999);
-                drawArc(p, x0, y0, x1, y1, a * adjust, b * adjust, theta,
-                        isMoreThanHalf, isPositiveArc);
-                return; /* Points are too far apart */
-            }
-            double s = Math.sqrt(disc);
-            double sdx = s * dx;
-            double sdy = s * dy;
-            double cx;
-            double cy;
-            if (isMoreThanHalf == isPositiveArc) {
-                cx = xm - sdy;
-                cy = ym + sdx;
-            } else {
-                cx = xm + sdy;
-                cy = ym - sdx;
-            }
-
-            double eta0 = Math.atan2((y0p - cy), (x0p - cx));
-            LOGGER.log(Level.FINE, "eta0 = Math.atan2( " + (y0p - cy) + " , "
-                    + (x0p - cx) + ") = " + Math.toDegrees(eta0));
-
-            double eta1 = Math.atan2((y1p - cy), (x1p - cx));
-            LOGGER.log(Level.FINE, "eta1 = Math.atan2( " + (y1p - cy) + " , "
-                    + (x1p - cx) + ") = " + Math.toDegrees(eta1));
-            double sweep = (eta1 - eta0);
-            if (isPositiveArc != (sweep >= 0)) {
-                if (sweep > 0) {
-                    sweep -= 2 * Math.PI;
-                } else {
-                    sweep += 2 * Math.PI;
-                }
-            }
-
-            cx *= a;
-            cy *= b;
-            double tcx = cx;
-            cx = cx * cosTheta - cy * sinTheta;
-            cy = tcx * sinTheta + cy * cosTheta;
-            LOGGER.log(
-                    Level.FINE,
-                    "cx, cy, a, b, x0, y0, thetaD, eta0, sweep = " + cx + " , "
-                            + cy + " , " + a + " , " + b + " , " + x0 + " , " + y0
-                            + " , " + Math.toDegrees(thetaD) + " , "
-                            + Math.toDegrees(eta0) + " , " + Math.toDegrees(sweep));
-
-            arcToBezier(p, cx, cy, a, b, x0, y0, thetaD, eta0, sweep);
-        }
-
-        /**
-         * Converts an arc to cubic Bezier segments and records them in p.
-         *
-         * @param p The target for the cubic Bezier segments
-         * @param cx The x coordinate center of the ellipse
-         * @param cy The y coordinate center of the ellipse
-         * @param a The radius of the ellipse in the horizontal direction
-         * @param b The radius of the ellipse in the vertical direction
-         * @param e1x E(eta1) x coordinate of the starting point of the arc
-         * @param e1y E(eta2) y coordinate of the starting point of the arc
-         * @param theta The angle that the ellipse bounding rectangle makes with the horizontal
-         * plane
-         * @param start The start angle of the arc on the ellipse
-         * @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
-         */
-        private static void arcToBezier(@NonNull Path_Delegate p, double cx, double cy, double a,
-                double b, double e1x, double e1y, double theta, double start,
-                double sweep) {
-            // Taken from equations at:
-            // http://spaceroots.org/documents/ellipse/node8.html
-            // and http://www.spaceroots.org/documents/ellipse/node22.html
-            // Maximum of 45 degrees per cubic Bezier segment
-            int numSegments = (int) Math.ceil(Math.abs(sweep * 4 / Math.PI));
-
-
-            double eta1 = start;
-            double cosTheta = Math.cos(theta);
-            double sinTheta = Math.sin(theta);
-            double cosEta1 = Math.cos(eta1);
-            double sinEta1 = Math.sin(eta1);
-            double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
-            double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1);
-
-            double anglePerSegment = sweep / numSegments;
-            for (int i = 0; i < numSegments; i++) {
-                double eta2 = eta1 + anglePerSegment;
-                double sinEta2 = Math.sin(eta2);
-                double cosEta2 = Math.cos(eta2);
-                double e2x = cx + (a * cosTheta * cosEta2)
-                        - (b * sinTheta * sinEta2);
-                double e2y = cy + (a * sinTheta * cosEta2)
-                        + (b * cosTheta * sinEta2);
-                double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2;
-                double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2;
-                double tanDiff2 = Math.tan((eta2 - eta1) / 2);
-                double alpha = Math.sin(eta2 - eta1)
-                        * (Math.sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3;
-                double q1x = e1x + alpha * ep1x;
-                double q1y = e1y + alpha * ep1y;
-                double q2x = e2x - alpha * ep2x;
-                double q2y = e2y - alpha * ep2y;
-
-                p.cubicTo((float) q1x,
-                        (float) q1y,
-                        (float) q2x,
-                        (float) q2y,
-                        (float) e2x,
-                        (float) e2y);
-                eta1 = eta2;
-                e1x = e2x;
-                e1y = e2y;
-                ep1x = ep2x;
-                ep1y = ep2y;
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/Xml_Delegate.java b/tools/layoutlib/bridge/src/android/util/Xml_Delegate.java
deleted file mode 100644
index 213e848..0000000
--- a/tools/layoutlib/bridge/src/android/util/Xml_Delegate.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-/**
- * Delegate overriding some methods of android.util.Xml
- *
- * Through the layoutlib_create tool, the original methods of Xml have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- */
-public class Xml_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static XmlPullParser newPullParser() {
-        try {
-            return ParserFactory.instantiateParser(null);
-        } catch (XmlPullParserException e) {
-            throw new AssertionError();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java b/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
deleted file mode 100644
index 4445a22..0000000
--- a/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
+++ /dev/null
@@ -1,58 +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.
- */
-
-package android.view;
-
-import com.android.layoutlib.bridge.android.BridgeWindow;
-import com.android.layoutlib.bridge.android.BridgeWindowSession;
-
-import android.content.Context;
-import android.os.Handler;
-import android.view.View.AttachInfo;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class AttachInfo_Accessor {
-
-    public static void setAttachInfo(View view) {
-        Context context = view.getContext();
-        WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
-        Display display = wm.getDefaultDisplay();
-        ViewRootImpl root = new ViewRootImpl(context, display);
-        AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(),
-                display, root, new Handler(), null, context);
-        info.mHasWindowFocus = true;
-        info.mWindowVisibility = View.VISIBLE;
-        info.mInTouchMode = false; // this is so that we can display selections.
-        info.mHardwareAccelerated = false;
-        view.dispatchAttachedToWindow(info, 0);
-    }
-
-    public static void dispatchOnPreDraw(View view) {
-        view.mAttachInfo.mTreeObserver.dispatchOnPreDraw();
-    }
-
-    public static void detachFromWindow(View view) {
-        if (view != null) {
-            view.dispatchDetachedFromWindow();
-        }
-    }
-
-    public static ViewRootImpl getRootView(View view) {
-        return view.mAttachInfo != null ? view.mAttachInfo.mViewRootImpl : null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
deleted file mode 100644
index b6e6ec0..0000000
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.MergeCookie;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.MockView;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.android.support.DrawerLayoutUtil;
-import com.android.layoutlib.bridge.android.support.RecyclerViewUtil;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.util.ReflectionUtils;
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Animatable;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-import android.widget.NumberPicker;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import static com.android.SdkConstants.AUTO_COMPLETE_TEXT_VIEW;
-import static com.android.SdkConstants.BUTTON;
-import static com.android.SdkConstants.CHECKED_TEXT_VIEW;
-import static com.android.SdkConstants.CHECK_BOX;
-import static com.android.SdkConstants.EDIT_TEXT;
-import static com.android.SdkConstants.IMAGE_BUTTON;
-import static com.android.SdkConstants.IMAGE_VIEW;
-import static com.android.SdkConstants.MULTI_AUTO_COMPLETE_TEXT_VIEW;
-import static com.android.SdkConstants.RADIO_BUTTON;
-import static com.android.SdkConstants.SEEK_BAR;
-import static com.android.SdkConstants.SPINNER;
-import static com.android.SdkConstants.TEXT_VIEW;
-import static com.android.layoutlib.bridge.android.BridgeContext.getBaseContext;
-
-/**
- * Custom implementation of {@link LayoutInflater} to handle custom views.
- */
-public final class BridgeInflater extends LayoutInflater {
-
-    private final LayoutlibCallback mLayoutlibCallback;
-    /**
-     * If true, the inflater will try to replace the framework widgets with the AppCompat versions.
-     * Ideally, this should be based on the activity being an AppCompat activity but since that is
-     * not trivial to check from layoutlib, we currently base the decision on the current theme
-     * being an AppCompat theme.
-     */
-    private boolean mLoadAppCompatViews;
-    /**
-     * This set contains the framework views that have an AppCompat version but failed to load.
-     * This might happen because not all widgets are contained in all versions of the support
-     * library.
-     * This will help us to avoid trying to load the AppCompat version multiple times if it
-     * doesn't exist.
-     */
-    private Set<String> mFailedAppCompatViews = new HashSet<>();
-    private boolean mIsInMerge = false;
-    private ResourceReference mResourceReference;
-    private Map<View, String> mOpenDrawerLayouts;
-
-    // Keep in sync with the same value in LayoutInflater.
-    private static final int[] ATTRS_THEME = new int[] {com.android.internal.R.attr.theme };
-
-    private static final String APPCOMPAT_WIDGET_PREFIX = "android.support.v7.widget.AppCompat";
-    /** List of platform widgets that have an AppCompat version */
-    private static final Set<String> APPCOMPAT_VIEWS = Collections.unmodifiableSet(
-            new HashSet<>(
-                    Arrays.asList(TEXT_VIEW, IMAGE_VIEW, BUTTON, EDIT_TEXT, SPINNER,
-                            IMAGE_BUTTON, CHECK_BOX, RADIO_BUTTON, CHECKED_TEXT_VIEW,
-                            AUTO_COMPLETE_TEXT_VIEW, MULTI_AUTO_COMPLETE_TEXT_VIEW, "RatingBar",
-                            SEEK_BAR)));
-
-    /**
-     * List of class prefixes which are tried first by default.
-     * <p/>
-     * This should match the list in com.android.internal.policy.impl.PhoneLayoutInflater.
-     */
-    private static final String[] sClassPrefixList = {
-        "android.widget.",
-        "android.webkit.",
-        "android.app."
-    };
-
-    public static String[] getClassPrefixList() {
-        return sClassPrefixList;
-    }
-
-    private BridgeInflater(LayoutInflater original, Context newContext) {
-        super(original, newContext);
-        newContext = getBaseContext(newContext);
-        if (newContext instanceof BridgeContext) {
-            mLayoutlibCallback = ((BridgeContext) newContext).getLayoutlibCallback();
-            mLoadAppCompatViews = ((BridgeContext) newContext).isAppCompatTheme();
-        } else {
-            mLayoutlibCallback = null;
-            mLoadAppCompatViews = false;
-        }
-    }
-
-    /**
-     * Instantiate a new BridgeInflater with an {@link LayoutlibCallback} object.
-     *
-     * @param context The Android application context.
-     * @param layoutlibCallback the {@link LayoutlibCallback} object.
-     */
-    public BridgeInflater(BridgeContext context, LayoutlibCallback layoutlibCallback) {
-        super(context);
-        mLayoutlibCallback = layoutlibCallback;
-        mConstructorArgs[0] = context;
-        mLoadAppCompatViews = context.isAppCompatTheme();
-    }
-
-    @Override
-    public View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException {
-        View view = null;
-
-        try {
-            if (mLoadAppCompatViews
-                    && APPCOMPAT_VIEWS.contains(name)
-                    && !mFailedAppCompatViews.contains(name)) {
-                // We are using an AppCompat theme so try to load the appcompat views
-                view = loadCustomView(APPCOMPAT_WIDGET_PREFIX + name, attrs, true);
-
-                if (view == null) {
-                    mFailedAppCompatViews.add(name); // Do not try this one anymore
-                }
-            }
-
-            if (view == null) {
-                // First try to find a class using the default Android prefixes
-                for (String prefix : sClassPrefixList) {
-                    try {
-                        view = createView(name, prefix, attrs);
-                        if (view != null) {
-                            break;
-                        }
-                    } catch (ClassNotFoundException e) {
-                        // Ignore. We'll try again using the base class below.
-                    }
-                }
-
-                // Next try using the parent loader. This will most likely only work for
-                // fully-qualified class names.
-                try {
-                    if (view == null) {
-                        view = super.onCreateView(name, attrs);
-                    }
-                } catch (ClassNotFoundException e) {
-                    // Ignore. We'll try again using the custom view loader below.
-                }
-            }
-
-            // Finally try again using the custom view loader
-            if (view == null) {
-                view = loadCustomView(name, attrs);
-            }
-        } catch (InflateException e) {
-            // Don't catch the InflateException below as that results in hiding the real cause.
-            throw e;
-        } catch (Exception e) {
-            // Wrap the real exception in a ClassNotFoundException, so that the calling method
-            // can deal with it.
-            throw new ClassNotFoundException("onCreateView", e);
-        }
-
-        setupViewInContext(view, attrs);
-
-        return view;
-    }
-
-    @Override
-    public View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,
-            boolean ignoreThemeAttr) {
-        View view = null;
-        if (name.equals("view")) {
-            // This is usually done by the superclass but this allows us catching the error and
-            // reporting something useful.
-            name = attrs.getAttributeValue(null, "class");
-
-            if (name == null) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to inflate view tag without " +
-                  "class attribute", null);
-                // We weren't able to resolve the view so we just pass a mock View to be able to
-                // continue rendering.
-                view = new MockView(context, attrs);
-                ((MockView) view).setText("view");
-            }
-        }
-
-        try {
-            if (view == null) {
-                view = super.createViewFromTag(parent, name, context, attrs, ignoreThemeAttr);
-            }
-        } catch (InflateException e) {
-            // Creation of ContextThemeWrapper code is same as in the super method.
-            // Apply a theme wrapper, if allowed and one is specified.
-            if (!ignoreThemeAttr) {
-                final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME);
-                final int themeResId = ta.getResourceId(0, 0);
-                if (themeResId != 0) {
-                    context = new ContextThemeWrapper(context, themeResId);
-                }
-                ta.recycle();
-            }
-            if (!(e.getCause() instanceof ClassNotFoundException)) {
-                // There is some unknown inflation exception in inflating a View that was found.
-                view = new MockView(context, attrs);
-                ((MockView) view).setText(name);
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN, e.getMessage(), e, null);
-            } else {
-                final Object lastContext = mConstructorArgs[0];
-                mConstructorArgs[0] = context;
-                // try to load the class from using the custom view loader
-                try {
-                    view = loadCustomView(name, attrs);
-                } catch (Exception e2) {
-                    // Wrap the real exception in an InflateException so that the calling
-                    // method can deal with it.
-                    InflateException exception = new InflateException();
-                    if (!e2.getClass().equals(ClassNotFoundException.class)) {
-                        exception.initCause(e2);
-                    } else {
-                        exception.initCause(e);
-                    }
-                    throw exception;
-                } finally {
-                    mConstructorArgs[0] = lastContext;
-                }
-            }
-        }
-
-        setupViewInContext(view, attrs);
-
-        return view;
-    }
-
-    @Override
-    public View inflate(int resource, ViewGroup root) {
-        Context context = getContext();
-        context = getBaseContext(context);
-        if (context instanceof BridgeContext) {
-            BridgeContext bridgeContext = (BridgeContext)context;
-
-            ResourceValue value = null;
-
-            @SuppressWarnings("deprecation")
-            Pair<ResourceType, String> layoutInfo = Bridge.resolveResourceId(resource);
-            if (layoutInfo != null) {
-                value = bridgeContext.getRenderResources().getFrameworkResource(
-                        ResourceType.LAYOUT, layoutInfo.getSecond());
-            } else {
-                layoutInfo = mLayoutlibCallback.resolveResourceId(resource);
-
-                if (layoutInfo != null) {
-                    value = bridgeContext.getRenderResources().getProjectResource(
-                            ResourceType.LAYOUT, layoutInfo.getSecond());
-                }
-            }
-
-            if (value != null) {
-                File f = new File(value.getValue());
-                if (f.isFile()) {
-                    try {
-                        XmlPullParser parser = ParserFactory.create(f, true);
-
-                        BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
-                                parser, bridgeContext, value.isFramework());
-
-                        return inflate(bridgeParser, root);
-                    } catch (Exception e) {
-                        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                                "Failed to parse file " + f.getAbsolutePath(), e, null);
-
-                        return null;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Instantiates the given view name and returns the instance. If the view doesn't exist, a
-     * MockView or null might be returned.
-     * @param name the custom view name
-     * @param attrs the {@link AttributeSet} to be passed to the view constructor
-     * @param silent if true, errors while loading the view won't be reported and, if the view
-     * doesn't exist, null will be returned.
-     */
-    private View loadCustomView(String name, AttributeSet attrs, boolean silent) throws Exception {
-        if (mLayoutlibCallback != null) {
-            // first get the classname in case it's not the node name
-            if (name.equals("view")) {
-                name = attrs.getAttributeValue(null, "class");
-                if (name == null) {
-                    return null;
-                }
-            }
-
-            mConstructorArgs[1] = attrs;
-
-            Object customView = silent ?
-                    mLayoutlibCallback.loadClass(name, mConstructorSignature, mConstructorArgs)
-                    : mLayoutlibCallback.loadView(name, mConstructorSignature, mConstructorArgs);
-
-            if (customView instanceof View) {
-                return (View)customView;
-            }
-        }
-
-        return null;
-    }
-
-    private View loadCustomView(String name, AttributeSet attrs) throws Exception {
-        return loadCustomView(name, attrs, false);
-    }
-
-    private void setupViewInContext(View view, AttributeSet attrs) {
-        Context context = getContext();
-        context = getBaseContext(context);
-        if (context instanceof BridgeContext) {
-            BridgeContext bc = (BridgeContext) context;
-            // get the view key
-            Object viewKey = getViewKeyFromParser(attrs, bc, mResourceReference, mIsInMerge);
-            if (viewKey != null) {
-                bc.addViewKey(view, viewKey);
-            }
-            String scrollPosX = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES, "scrollX");
-            if (scrollPosX != null && scrollPosX.endsWith("px")) {
-                int value = Integer.parseInt(scrollPosX.substring(0, scrollPosX.length() - 2));
-                bc.setScrollXPos(view, value);
-            }
-            String scrollPosY = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES, "scrollY");
-            if (scrollPosY != null && scrollPosY.endsWith("px")) {
-                int value = Integer.parseInt(scrollPosY.substring(0, scrollPosY.length() - 2));
-                bc.setScrollYPos(view, value);
-            }
-            if (ReflectionUtils.isInstanceOf(view, RecyclerViewUtil.CN_RECYCLER_VIEW)) {
-                Integer resourceId = null;
-                String attrVal = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI,
-                        BridgeConstants.ATTR_LIST_ITEM);
-                if (attrVal != null && !attrVal.isEmpty()) {
-                    ResourceValue resValue = bc.getRenderResources().findResValue(attrVal, false);
-                    if (resValue.isFramework()) {
-                        resourceId = Bridge.getResourceId(resValue.getResourceType(),
-                                resValue.getName());
-                    } else {
-                        resourceId = mLayoutlibCallback.getResourceId(resValue.getResourceType(),
-                                resValue.getName());
-                    }
-                }
-                if (resourceId == null) {
-                    resourceId = 0;
-                }
-                RecyclerViewUtil.setAdapter(view, bc, mLayoutlibCallback, resourceId);
-            } else if (ReflectionUtils.isInstanceOf(view, DrawerLayoutUtil.CN_DRAWER_LAYOUT)) {
-                String attrVal = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI,
-                        BridgeConstants.ATTR_OPEN_DRAWER);
-                if (attrVal != null) {
-                    getDrawerLayoutMap().put(view, attrVal);
-                }
-            }
-            else if (view instanceof NumberPicker) {
-                NumberPicker numberPicker = (NumberPicker) view;
-                String minValue = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI, "minValue");
-                if (minValue != null) {
-                    numberPicker.setMinValue(Integer.parseInt(minValue));
-                }
-                String maxValue = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI, "maxValue");
-                if (maxValue != null) {
-                    numberPicker.setMaxValue(Integer.parseInt(maxValue));
-                }
-            }
-            else if (view instanceof ImageView) {
-                ImageView img = (ImageView) view;
-                Drawable drawable = img.getDrawable();
-                if (drawable instanceof Animatable) {
-                    if (!((Animatable) drawable).isRunning()) {
-                        ((Animatable) drawable).start();
-                    }
-                }
-            }
-
-        }
-    }
-
-    public void setIsInMerge(boolean isInMerge) {
-        mIsInMerge = isInMerge;
-    }
-
-    public void setResourceReference(ResourceReference reference) {
-        mResourceReference = reference;
-    }
-
-    @Override
-    public LayoutInflater cloneInContext(Context newContext) {
-        return new BridgeInflater(this, newContext);
-    }
-
-    /*package*/ static Object getViewKeyFromParser(AttributeSet attrs, BridgeContext bc,
-            ResourceReference resourceReference, boolean isInMerge) {
-
-        if (!(attrs instanceof BridgeXmlBlockParser)) {
-            return null;
-        }
-        BridgeXmlBlockParser parser = ((BridgeXmlBlockParser) attrs);
-
-        // get the view key
-        Object viewKey = parser.getViewCookie();
-
-        if (viewKey == null) {
-            int currentDepth = parser.getDepth();
-
-            // test whether we are in an included file or in a adapter binding view.
-            BridgeXmlBlockParser previousParser = bc.getPreviousParser();
-            if (previousParser != null) {
-                // looks like we are inside an embedded layout.
-                // only apply the cookie of the calling node (<include>) if we are at the
-                // top level of the embedded layout. If there is a merge tag, then
-                // skip it and look for the 2nd level
-                int testDepth = isInMerge ? 2 : 1;
-                if (currentDepth == testDepth) {
-                    viewKey = previousParser.getViewCookie();
-                    // if we are in a merge, wrap the cookie in a MergeCookie.
-                    if (viewKey != null && isInMerge) {
-                        viewKey = new MergeCookie(viewKey);
-                    }
-                }
-            } else if (resourceReference != null && currentDepth == 1) {
-                // else if there's a resource reference, this means we are in an adapter
-                // binding case. Set the resource ref as the view cookie only for the top
-                // level view.
-                viewKey = resourceReference;
-            }
-        }
-
-        return viewKey;
-    }
-
-    public void postInflateProcess(View view) {
-        if (mOpenDrawerLayouts != null) {
-            String gravity = mOpenDrawerLayouts.get(view);
-            if (gravity != null) {
-                DrawerLayoutUtil.openDrawer(view, gravity);
-            }
-            mOpenDrawerLayouts.remove(view);
-        }
-    }
-
-    @NonNull
-    private Map<View, String> getDrawerLayoutMap() {
-        if (mOpenDrawerLayouts == null) {
-            mOpenDrawerLayouts = new HashMap<View, String>(4);
-        }
-        return mOpenDrawerLayouts;
-    }
-
-    public void onDoneInflation() {
-        if (mOpenDrawerLayouts != null) {
-            mOpenDrawerLayouts.clear();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java b/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java
deleted file mode 100644
index 494ffa1..0000000
--- a/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.view;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.java.System_Delegate;
-
-import java.lang.reflect.Field;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Choreographer}
- *
- * Through the layoutlib_create tool, the original  methods of Choreographer have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-public class Choreographer_Delegate {
-    static final AtomicReference<Choreographer> mInstance = new AtomicReference<Choreographer>();
-
-    @LayoutlibDelegate
-    public static Choreographer getInstance() {
-        if (mInstance.get() == null) {
-            mInstance.compareAndSet(null, Choreographer.getInstance_Original());
-        }
-
-        return mInstance.get();
-    }
-
-    @LayoutlibDelegate
-    public static float getRefreshRate() {
-        return 60.f;
-    }
-
-    @LayoutlibDelegate
-    static void scheduleVsyncLocked(Choreographer thisChoreographer) {
-        // do nothing
-    }
-
-    public static void doFrame(long frameTimeNanos) {
-        Choreographer thisChoreographer = Choreographer.getInstance();
-
-        thisChoreographer.mLastFrameTimeNanos = frameTimeNanos - thisChoreographer
-                .getFrameIntervalNanos();
-        thisChoreographer.mFrameInfo.markInputHandlingStart();
-        thisChoreographer.doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
-
-        thisChoreographer.mFrameInfo.markAnimationsStart();
-        thisChoreographer.doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
-
-        thisChoreographer.mFrameInfo.markPerformTraversalsStart();
-        thisChoreographer.doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
-
-        thisChoreographer.doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
-    }
-
-    public static void dispose() {
-        try {
-            Field threadInstanceField = Choreographer.class.getDeclaredField("sThreadInstance");
-            threadInstanceField.setAccessible(true);
-            @SuppressWarnings("unchecked") ThreadLocal<Choreographer> threadInstance =
-                    (ThreadLocal<Choreographer>) threadInstanceField.get(null);
-            threadInstance.remove();
-        } catch (ReflectiveOperationException e) {
-            assert false;
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Unable to clear Choreographer memory.", e, null);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
deleted file mode 100644
index 53dc821..0000000
--- a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
+++ /dev/null
@@ -1,36 +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.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Display}
- *
- * Through the layoutlib_create tool, the original  methods of Display have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class Display_Delegate {
-
-    @LayoutlibDelegate
-    static void updateDisplayInfoLocked(Display theDisplay) {
-        // do nothing
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/HandlerActionQueue_Delegate.java b/tools/layoutlib/bridge/src/android/view/HandlerActionQueue_Delegate.java
deleted file mode 100644
index e580ed0..0000000
--- a/tools/layoutlib/bridge/src/android/view/HandlerActionQueue_Delegate.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of
- * {@link HandlerActionQueue}
- *
- * Through the layoutlib_create tool, the original  methods of ViewRootImpl.RunQueue have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-public class HandlerActionQueue_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static void postDelayed(HandlerActionQueue thisQueue, Runnable action, long
-            delayMillis) {
-        // The actual HandlerActionQueue is never run and therefore never cleared. This method
-        // avoids runnables to be added to the RunQueue so they do not leak resources.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
deleted file mode 100644
index deb0e09..0000000
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ /dev/null
@@ -1,529 +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.
- */
-
-package android.view;
-
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.GraphicBuffer;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.IRemoteCallback;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.DisplayMetrics;
-
-import com.android.internal.app.IAssistScreenshotReceiver;
-import com.android.internal.os.IResultReceiver;
-import com.android.internal.policy.IKeyguardDismissCallback;
-import com.android.internal.policy.IShortcutService;
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
-
-/**
- * Basic implementation of {@link IWindowManager} so that {@link Display} (and
- * {@link Display_Delegate}) can return a valid instance.
- */
-public class IWindowManagerImpl implements IWindowManager {
-
-    private final Configuration mConfig;
-    private final DisplayMetrics mMetrics;
-    private final int mRotation;
-    private final boolean mHasNavigationBar;
-
-    public IWindowManagerImpl(Configuration config, DisplayMetrics metrics, int rotation,
-            boolean hasNavigationBar) {
-        mConfig = config;
-        mMetrics = metrics;
-        mRotation = rotation;
-        mHasNavigationBar = hasNavigationBar;
-    }
-
-    // custom API.
-
-    public DisplayMetrics getMetrics() {
-        return mMetrics;
-    }
-
-    // ---- implementation of IWindowManager that we care about ----
-
-    @Override
-    public int getDefaultDisplayRotation() throws RemoteException {
-        return mRotation;
-    }
-
-    @Override
-    public boolean hasNavigationBar() {
-        return mHasNavigationBar;
-    }
-
-    // ---- unused implementation of IWindowManager ----
-
-    @Override
-    public void addWindowToken(IBinder arg0, int arg1, int arg2) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void clearForcedDisplaySize(int displayId) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void clearForcedDisplayDensityForUser(int displayId, int userId) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setOverscan(int displayId, int left, int top, int right, int bottom)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void closeSystemDialogs(String arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void startFreezingScreen(int exitAnim, int enterAnim) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void stopFreezingScreen() {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void disableKeyguard(IBinder arg0, String arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void executeAppTransition() throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void exitKeyguardSecurely(IOnKeyguardExitResult arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void freezeRotation(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public float getAnimationScale(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public float[] getAnimationScales() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getPendingAppTransition() throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public boolean inKeyguardRestrictedInputMode() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean inputMethodClientHasFocus(IInputMethodClient arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isKeyguardLocked() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isKeyguardSecure() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isViewServerRunning() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public IWindowSession openSession(IWindowSessionCallback argn1, IInputMethodClient arg0,
-            IInputContext arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void overridePendingAppTransition(String arg0, int arg1, int arg2,
-            IRemoteCallback startedCallback) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
-            int startHeight) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionClipReveal(int startX, int startY,
-            int startWidth, int startHeight) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionThumb(GraphicBuffer srcThumb, int startX, int startY,
-            IRemoteCallback startedCallback, boolean scaleUp) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionAspectScaledThumb(GraphicBuffer srcThumb, int startX,
-            int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
-            boolean scaleUp) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionInPlace(String packageName, int anim) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionMultiThumbFuture(
-            IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback startedCallback,
-            boolean scaleUp) throws RemoteException {
-
-    }
-
-    @Override
-    public void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
-            IRemoteCallback callback0, IRemoteCallback callback1, boolean scaleUp) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void prepareAppTransition(int arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void reenableKeyguard(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void removeWindowToken(IBinder arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean requestAssistScreenshot(IAssistScreenshotReceiver receiver)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void setAnimationScale(int arg0, float arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setAnimationScales(float[] arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public float getCurrentAnimatorScale() throws RemoteException {
-        return 0;
-    }
-
-    @Override
-    public void setEventDispatching(boolean arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setFocusedApp(IBinder arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void getInitialDisplaySize(int displayId, Point size) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void getBaseDisplaySize(int displayId, Point size) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setForcedDisplaySize(int displayId, int arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public int getInitialDisplayDensity(int displayId) {
-        return -1;
-    }
-
-    @Override
-    public int getBaseDisplayDensity(int displayId) {
-        return -1;
-    }
-
-    @Override
-    public void setForcedDisplayDensityForUser(int displayId, int density, int userId)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setForcedDisplayScalingMode(int displayId, int mode) {
-    }
-
-    @Override
-    public void setInTouchMode(boolean arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public int[] setNewDisplayOverrideConfiguration(Configuration arg0, int displayId)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void setScreenCaptureDisabled(int userId, boolean disabled) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void updateRotation(boolean arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setStrictModeVisualIndicatorPreference(String arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void showStrictModeViolation(boolean arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean startViewServer(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void statusBarVisibilityChanged(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setRecentsVisibility(boolean visible) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setPipVisibility(boolean visible) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean stopViewServer() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void thawRotation() throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public Configuration updateOrientationFromAppTokens(Configuration arg0, IBinder arg1, int arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int watchRotation(IRotationWatcher arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void removeRotationWatcher(IRotationWatcher arg0) throws RemoteException {
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getPreferredOptionsPanelGravity() throws RemoteException {
-        return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
-    }
-
-    @Override
-    public void dismissKeyguard(IKeyguardDismissCallback callback) throws RemoteException {
-    }
-
-    @Override
-    public void setSwitchingUser(boolean switching) throws RemoteException {
-    }
-
-    @Override
-    public void lockNow(Bundle options) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean isSafeModeEnabled() {
-        return false;
-    }
-
-    @Override
-    public boolean isRotationFrozen() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void enableScreenIfNeeded() throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean clearWindowContentFrameStats(IBinder token) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public WindowContentFrameStats getWindowContentFrameStats(IBinder token)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getDockedStackSide() throws RemoteException {
-        return 0;
-    }
-
-    @Override
-    public void setDockedStackResizing(boolean resizing) throws RemoteException {
-    }
-
-    @Override
-    public void endProlongedAnimations() {
-    }
-
-    @Override
-    public void registerDockedStackListener(IDockedStackListener listener) throws RemoteException {
-    }
-
-    @Override
-    public void registerPinnedStackListener(int displayId, IPinnedStackListener listener) throws RemoteException {
-    }
-
-    @Override
-    public void setResizeDimLayer(boolean visible, int targetStackId, float alpha)
-            throws RemoteException {
-    }
-
-    @Override
-    public void setDockedStackDividerTouchRegion(Rect touchableRegion) throws RemoteException {
-    }
-
-    @Override
-    public void requestAppKeyboardShortcuts(
-            IResultReceiver receiver, int deviceId) throws RemoteException {
-    }
-
-    @Override
-    public void getStableInsets(int displayId, Rect outInsets) throws RemoteException {
-    }
-
-    @Override
-    public void registerShortcutKey(long shortcutCode, IShortcutService service)
-        throws RemoteException {}
-
-    @Override
-    public void createInputConsumer(String name, InputChannel inputChannel)
-            throws RemoteException {}
-
-    @Override
-    public boolean destroyInputConsumer(String name) throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public Bitmap screenshotWallpaper() throws RemoteException {
-        return null;
-    }
-
-    @Override
-    public void enableSurfaceTrace(ParcelFileDescriptor fd) throws RemoteException {
-    }
-
-    @Override
-    public void disableSurfaceTrace() throws RemoteException {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
deleted file mode 100644
index cec6bb3..0000000
--- a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
+++ /dev/null
@@ -1,236 +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.
- */
-
-package android.view;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.util.Xml;
-
-import java.io.IOException;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link LayoutInflater}
- *
- * Through the layoutlib_create tool, the original  methods of LayoutInflater have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class LayoutInflater_Delegate {
-    private static final String TAG_MERGE = "merge";
-
-    private static final String ATTR_LAYOUT = "layout";
-
-    private static final int[] ATTRS_THEME = new int[] {
-            com.android.internal.R.attr.theme };
-
-    public static boolean sIsInInclude = false;
-
-    /**
-     * Recursive method used to descend down the xml hierarchy and instantiate
-     * views, instantiate their children, and then call onFinishInflate().
-     *
-     * This implementation just records the merge status before calling the default implementation.
-     */
-    @LayoutlibDelegate
-    /* package */ static void rInflate(LayoutInflater thisInflater, XmlPullParser parser,
-            View parent, Context context, AttributeSet attrs, boolean finishInflate)
-            throws XmlPullParserException, IOException {
-
-        if (finishInflate == false) {
-            // this is a merge rInflate!
-            if (thisInflater instanceof BridgeInflater) {
-                ((BridgeInflater) thisInflater).setIsInMerge(true);
-            }
-        }
-
-        // ---- START DEFAULT IMPLEMENTATION.
-
-        thisInflater.rInflate_Original(parser, parent, context, attrs, finishInflate);
-
-        // ---- END DEFAULT IMPLEMENTATION.
-
-        if (finishInflate == false) {
-            // this is a merge rInflate!
-            if (thisInflater instanceof BridgeInflater) {
-                ((BridgeInflater) thisInflater).setIsInMerge(false);
-            }
-        }
-    }
-
-    @LayoutlibDelegate
-    public static void parseInclude(LayoutInflater thisInflater, XmlPullParser parser,
-            Context context, View parent, AttributeSet attrs)
-            throws XmlPullParserException, IOException {
-        int type;
-
-        if (parent instanceof ViewGroup) {
-            // Apply a theme wrapper, if requested. This is sort of a weird
-            // edge case, since developers think the <include> overwrites
-            // values in the AttributeSet of the included View. So, if the
-            // included View has a theme attribute, we'll need to ignore it.
-            final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME);
-            final int themeResId = ta.getResourceId(0, 0);
-            final boolean hasThemeOverride = themeResId != 0;
-            if (hasThemeOverride) {
-                context = new ContextThemeWrapper(context, themeResId);
-            }
-            ta.recycle();
-
-            // If the layout is pointing to a theme attribute, we have to
-            // massage the value to get a resource identifier out of it.
-            int layout = attrs.getAttributeResourceValue(null, ATTR_LAYOUT, 0);
-            if (layout == 0) {
-                final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
-                if (value == null || value.length() <= 0) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a layout in the"
-                            + " include tag: <include layout=\"@layout/layoutID\" />", null);
-                    LayoutInflater.consumeChildElements(parser);
-                    return;
-                }
-
-                // Attempt to resolve the "?attr/name" string to an identifier.
-                layout = context.getResources().getIdentifier(value.substring(1), null, null);
-            }
-
-            // The layout might be referencing a theme attribute.
-            // ---- START CHANGES
-            if (layout != 0) {
-                final TypedValue tempValue = new TypedValue();
-                if (context.getTheme().resolveAttribute(layout, tempValue, true)) {
-                    layout = tempValue.resourceId;
-                }
-            }
-            // ---- END CHANGES
-
-            if (layout == 0) {
-                final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
-                if (value == null) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a layout in the"
-                            + " include tag: <include layout=\"@layout/layoutID\" />", null);
-                } else {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a valid layout "
-                            + "reference. The layout ID " + value + " is not valid.", null);
-                }
-            } else {
-                final XmlResourceParser childParser =
-                    thisInflater.getContext().getResources().getLayout(layout);
-
-                try {
-                    final AttributeSet childAttrs = Xml.asAttributeSet(childParser);
-
-                    while ((type = childParser.next()) != XmlPullParser.START_TAG &&
-                            type != XmlPullParser.END_DOCUMENT) {
-                        // Empty.
-                    }
-
-                    if (type != XmlPullParser.START_TAG) {
-                        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                                childParser.getPositionDescription() + ": No start tag found!",
-                                null);
-                        LayoutInflater.consumeChildElements(parser);
-                        return;
-                    }
-
-                    final String childName = childParser.getName();
-
-                    if (TAG_MERGE.equals(childName)) {
-                        // Inflate all children.
-                        thisInflater.rInflate(childParser, parent, context, childAttrs, false);
-                    } else {
-                        final View view = thisInflater.createViewFromTag(parent, childName,
-                                context, childAttrs, hasThemeOverride);
-                        final ViewGroup group = (ViewGroup) parent;
-
-                        final TypedArray a = context.obtainStyledAttributes(
-                                attrs, com.android.internal.R.styleable.Include);
-                        final int id = a.getResourceId(
-                                com.android.internal.R.styleable.Include_id, View.NO_ID);
-                        final int visibility = a.getInt(
-                                com.android.internal.R.styleable.Include_visibility, -1);
-                        a.recycle();
-
-                        // We try to load the layout params set in the <include /> tag. If
-                        // they don't exist, we will rely on the layout params set in the
-                        // included XML file.
-                        // During a layoutparams generation, a runtime exception is thrown
-                        // if either layout_width or layout_height is missing. We catch
-                        // this exception and set localParams accordingly: true means we
-                        // successfully loaded layout params from the <include /> tag,
-                        // false means we need to rely on the included layout params.
-                        ViewGroup.LayoutParams params = null;
-                        try {
-                            // ---- START CHANGES
-                            sIsInInclude = true;
-                            // ---- END CHANGES
-
-                            params = group.generateLayoutParams(attrs);
-                        } catch (RuntimeException ignored) {
-                            // Ignore, just fail over to child attrs.
-                        } finally {
-                            // ---- START CHANGES
-                            sIsInInclude = false;
-                            // ---- END CHANGES
-                        }
-                        if (params == null) {
-                            params = group.generateLayoutParams(childAttrs);
-                        }
-                        view.setLayoutParams(params);
-
-                        // Inflate all children.
-                        thisInflater.rInflateChildren(childParser, view, childAttrs, true);
-
-                        if (id != View.NO_ID) {
-                            view.setId(id);
-                        }
-
-                        switch (visibility) {
-                            case 0:
-                                view.setVisibility(View.VISIBLE);
-                                break;
-                            case 1:
-                                view.setVisibility(View.INVISIBLE);
-                                break;
-                            case 2:
-                                view.setVisibility(View.GONE);
-                                break;
-                        }
-
-                        group.addView(view);
-                    }
-                } finally {
-                    childParser.close();
-                }
-            }
-        } else {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "<include /> can only be used inside of a ViewGroup",
-                    null);
-        }
-
-        LayoutInflater.consumeChildElements(parser);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
deleted file mode 100644
index 08a97d6..0000000
--- a/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.content.Context;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.internal.view.menu.BridgeMenuItemImpl;
-import com.android.internal.view.menu.MenuView;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.util.AttributeSet;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link MenuInflater}
- * <p/>
- * Through the layoutlib_create tool, the original  methods of MenuInflater have been
- * replaced by calls to methods of the same name in this delegate class.
- * <p/>
- * The main purpose of the class is to get the view key from the menu xml parser and add it to
- * the menu item. The view key is used by the IDE to match the individual view elements to the
- * corresponding xml tag in the menu/layout file.
- * <p/>
- * For Menus, the views may be reused and the {@link MenuItem} is a better object to hold the
- * view key than the {@link MenuView.ItemView}. At the time of computation of the rest of {@link
- * ViewInfo}, we check the corresponding view key in the menu item for the view and add it
- */
-public class MenuInflater_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static void registerMenu(MenuInflater thisInflater, MenuItem menuItem,
-            AttributeSet attrs) {
-        if (menuItem instanceof BridgeMenuItemImpl) {
-            Context context = thisInflater.getContext();
-            context = BridgeContext.getBaseContext(context);
-            if (context instanceof BridgeContext) {
-                Object viewKey = BridgeInflater.getViewKeyFromParser(
-                        attrs, ((BridgeContext) context), null, false);
-                ((BridgeMenuItemImpl) menuItem).setViewCookie(viewKey);
-                return;
-            }
-        }
-        // This means that Bridge did not take over the instantiation of some object properly.
-        // This is most likely a bug in the LayoutLib code.
-        Bridge.getLog().warning(LayoutLog.TAG_BROKEN,
-                "Action Bar Menu rendering may be incorrect.", null);
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void registerMenu(MenuInflater thisInflater, SubMenu subMenu,
-            AttributeSet parser) {
-        registerMenu(thisInflater, subMenu.getItem(), parser);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/PointerIcon_Delegate.java b/tools/layoutlib/bridge/src/android/view/PointerIcon_Delegate.java
deleted file mode 100644
index 4a5ea9b..0000000
--- a/tools/layoutlib/bridge/src/android/view/PointerIcon_Delegate.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-import android.content.res.Resources;
-
-public class PointerIcon_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static void loadResource(PointerIcon icon, Context context, Resources resources,
-            int resourceId) {
-        // HACK: This bypasses the problem of having an enum resolved as a resourceId.
-        // PointerIcon would not be displayed by layoutlib anyway, so we always return the null
-        // icon.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
deleted file mode 100644
index 8ae212c..0000000
--- a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2015, 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;
-
-import android.annotation.NonNull;
-import android.graphics.Canvas;
-import android.graphics.Outline;
-import android.graphics.Rect;
-import com.android.layoutlib.bridge.shadowutil.SpotShadow;
-import com.android.layoutlib.bridge.shadowutil.ShadowBuffer;
-
-public class RectShadowPainter {
-
-    private static final float SHADOW_STRENGTH = 0.1f;
-    private static final int LIGHT_POINTS = 8;
-
-    private static final int QUADRANT_DIVIDED_COUNT = 8;
-
-    private static final int RAY_TRACING_RAYS = 180;
-    private static final int RAY_TRACING_LAYERS = 10;
-
-    public static void paintShadow(@NonNull Outline viewOutline, float elevation,
-            @NonNull Canvas canvas) {
-        Rect outline = new Rect();
-        if (!viewOutline.getRect(outline)) {
-            assert false : "Outline is not a rect shadow";
-            return;
-        }
-
-        Rect originCanvasRect = canvas.getClipBounds();
-        int saved = modifyCanvas(canvas);
-        if (saved == -1) {
-            return;
-        }
-        try {
-            float radius = viewOutline.getRadius();
-            if (radius <= 0) {
-                // We can not paint a shadow with radius 0
-                return;
-            }
-
-            // view's absolute position in this canvas.
-            int viewLeft = -originCanvasRect.left + outline.left;
-            int viewTop = -originCanvasRect.top + outline.top;
-            int viewRight = viewLeft + outline.width();
-            int viewBottom = viewTop + outline.height();
-
-            float[][] rectangleCoordinators = generateRectangleCoordinates(viewLeft, viewTop,
-                    viewRight, viewBottom, radius, elevation);
-
-            // TODO: get these values from resources.
-            float lightPosX = canvas.getWidth() / 2;
-            float lightPosY = 0;
-            float lightHeight = 1800;
-            float lightSize = 200;
-
-            paintGeometricShadow(rectangleCoordinators, lightPosX, lightPosY, lightHeight,
-                    lightSize, canvas);
-        } finally {
-            canvas.restoreToCount(saved);
-        }
-    }
-
-    private static int modifyCanvas(@NonNull Canvas canvas) {
-        Rect rect = canvas.getClipBounds();
-        canvas.translate(rect.left, rect.top);
-        return canvas.save();
-    }
-
-    @NonNull
-    private static float[][] generateRectangleCoordinates(float left, float top, float right,
-            float bottom, float radius, float elevation) {
-        left = left + radius;
-        top = top + radius;
-        right = right - radius;
-        bottom = bottom - radius;
-
-        final double RADIANS_STEP = 2 * Math.PI / 4 / QUADRANT_DIVIDED_COUNT;
-
-        float[][] ret = new float[QUADRANT_DIVIDED_COUNT * 4][3];
-
-        int points = 0;
-        // left-bottom points
-        for (int i = 0; i < QUADRANT_DIVIDED_COUNT; i++) {
-            ret[points][0] = (float) (left - radius + radius * Math.cos(RADIANS_STEP * i));
-            ret[points][1] = (float) (bottom + radius - radius * Math.cos(RADIANS_STEP * i));
-            ret[points][2] = elevation;
-            points++;
-        }
-        // left-top points
-        for (int i = 0; i < QUADRANT_DIVIDED_COUNT; i++) {
-            ret[points][0] = (float) (left + radius - radius * Math.cos(RADIANS_STEP * i));
-            ret[points][1] = (float) (top + radius - radius * Math.cos(RADIANS_STEP * i));
-            ret[points][2] = elevation;
-            points++;
-        }
-        // right-top points
-        for (int i = 0; i < QUADRANT_DIVIDED_COUNT; i++) {
-            ret[points][0] = (float) (right + radius - radius * Math.cos(RADIANS_STEP * i));
-            ret[points][1] = (float) (top + radius + radius * Math.cos(RADIANS_STEP * i));
-            ret[points][2] = elevation;
-            points++;
-        }
-        // right-bottom point
-        for (int i = 0; i < QUADRANT_DIVIDED_COUNT; i++) {
-            ret[points][0] = (float) (right - radius + radius * Math.cos(RADIANS_STEP * i));
-            ret[points][1] = (float) (bottom - radius + radius * Math.cos(RADIANS_STEP * i));
-            ret[points][2] = elevation;
-            points++;
-        }
-
-        return ret;
-    }
-
-    private static void paintGeometricShadow(@NonNull float[][] coordinates, float lightPosX,
-            float lightPosY, float lightHeight, float lightSize, Canvas canvas) {
-        if (canvas == null || canvas.getWidth() == 0 || canvas.getHeight() == 0) {
-            return;
-        }
-
-        // The polygon of shadow (same as the original item)
-        float[] shadowPoly = new float[coordinates.length * 3];
-        for (int i = 0; i < coordinates.length; i++) {
-            shadowPoly[i * 3 + 0] = coordinates[i][0];
-            shadowPoly[i * 3 + 1] = coordinates[i][1];
-            shadowPoly[i * 3 + 2] = coordinates[i][2];
-        }
-
-        // TODO: calculate the ambient shadow and mix with Spot shadow.
-
-        // Calculate the shadow of SpotLight
-        float[] light = SpotShadow.calculateLight(lightSize, LIGHT_POINTS, lightPosX,
-                lightPosY, lightHeight);
-
-        int stripSize = 3 * SpotShadow.getStripSize(RAY_TRACING_RAYS, RAY_TRACING_LAYERS);
-        if (stripSize < 9) {
-            return;
-        }
-        float[] strip = new float[stripSize];
-        SpotShadow.calcShadow(light, LIGHT_POINTS, shadowPoly, coordinates.length, RAY_TRACING_RAYS,
-                RAY_TRACING_LAYERS, 1f, strip);
-
-        ShadowBuffer buff = new ShadowBuffer(canvas.getWidth(), canvas.getHeight());
-        buff.generateTriangles(strip, SHADOW_STRENGTH);
-        buff.draw(canvas);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java b/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
deleted file mode 100644
index 152878b..0000000
--- a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Matrix;
-
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-/**
- * Delegate implementing the native methods of {@link RenderNode}
- * <p/>
- * Through the layoutlib_create tool, some native methods of RenderNode have been replaced by calls
- * to methods of the same name in this delegate class.
- *
- * @see DelegateManager
- */
-public class RenderNode_Delegate {
-
-
-    // ---- delegate manager ----
-    private static final DelegateManager<RenderNode_Delegate> sManager =
-            new DelegateManager<RenderNode_Delegate>(RenderNode_Delegate.class);
-    private static long sFinalizer = -1;
-
-    private float mLift;
-    private float mTranslationX;
-    private float mTranslationY;
-    private float mTranslationZ;
-    private float mRotation;
-    private float mScaleX = 1;
-    private float mScaleY = 1;
-    private float mPivotX;
-    private float mPivotY;
-    private boolean mPivotExplicitlySet;
-    private int mLeft;
-    private int mRight;
-    private int mTop;
-    private int mBottom;
-    @SuppressWarnings("UnusedDeclaration")
-    private String mName;
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreate(String name) {
-        RenderNode_Delegate renderNodeDelegate = new RenderNode_Delegate();
-        renderNodeDelegate.mName = name;
-        return sManager.addNewDelegate(renderNodeDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetNativeFinalizer() {
-        synchronized (RenderNode_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(sManager::removeJavaReferenceFor);
-            }
-        }
-        return sFinalizer;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetElevation(long renderNode, float lift) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mLift != lift) {
-            delegate.mLift = lift;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetElevation(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mLift;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetTranslationX(long renderNode, float translationX) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mTranslationX != translationX) {
-            delegate.mTranslationX = translationX;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTranslationX(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mTranslationX;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetTranslationY(long renderNode, float translationY) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mTranslationY != translationY) {
-            delegate.mTranslationY = translationY;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTranslationY(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mTranslationY;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetTranslationZ(long renderNode, float translationZ) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mTranslationZ != translationZ) {
-            delegate.mTranslationZ = translationZ;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTranslationZ(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mTranslationZ;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetRotation(long renderNode, float rotation) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mRotation != rotation) {
-            delegate.mRotation = rotation;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetRotation(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mRotation;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void getMatrix(RenderNode renderNode, Matrix outMatrix) {
-        outMatrix.reset();
-        if (renderNode != null) {
-            float rotation = renderNode.getRotation();
-            float translationX = renderNode.getTranslationX();
-            float translationY = renderNode.getTranslationY();
-            float pivotX = renderNode.getPivotX();
-            float pivotY = renderNode.getPivotY();
-            float scaleX = renderNode.getScaleX();
-            float scaleY = renderNode.getScaleY();
-
-            outMatrix.setTranslate(translationX, translationY);
-            outMatrix.preRotate(rotation, pivotX, pivotY);
-            outMatrix.preScale(scaleX, scaleY, pivotX, pivotY);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetLeft(long renderNode, int left) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mLeft != left) {
-            delegate.mLeft = left;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetTop(long renderNode, int top) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mTop != top) {
-            delegate.mTop = top;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetRight(long renderNode, int right) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mRight != right) {
-            delegate.mRight = right;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetBottom(long renderNode, int bottom) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mBottom != bottom) {
-            delegate.mBottom = bottom;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetLeftTopRightBottom(long renderNode, int left, int top, int right,
-            int bottom) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && (delegate.mLeft != left || delegate.mTop != top || delegate
-                .mRight != right || delegate.mBottom != bottom)) {
-            delegate.mLeft = left;
-            delegate.mTop = top;
-            delegate.mRight = right;
-            delegate.mBottom = bottom;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsPivotExplicitlySet(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        return delegate != null && delegate.mPivotExplicitlySet;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetPivotX(long renderNode, float pivotX) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            delegate.mPivotX = pivotX;
-            delegate.mPivotExplicitlySet = true;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetPivotX(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            if (delegate.mPivotExplicitlySet) {
-                return delegate.mPivotX;
-            } else {
-                return (delegate.mRight - delegate.mLeft) / 2.0f;
-            }
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetPivotY(long renderNode, float pivotY) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            delegate.mPivotY = pivotY;
-            delegate.mPivotExplicitlySet = true;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetPivotY(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            if (delegate.mPivotExplicitlySet) {
-                return delegate.mPivotY;
-            } else {
-                return (delegate.mBottom - delegate.mTop) / 2.0f;
-            }
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetScaleX(long renderNode, float scaleX) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mScaleX != scaleX) {
-            delegate.mScaleX = scaleX;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetScaleX(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mScaleX;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetScaleY(long renderNode, float scaleY) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mScaleY != scaleY) {
-            delegate.mScaleY = scaleY;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetScaleY(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mScaleY;
-        }
-        return 0f;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/ShadowPainter.java b/tools/layoutlib/bridge/src/android/view/ShadowPainter.java
deleted file mode 100644
index f09fffd..0000000
--- a/tools/layoutlib/bridge/src/android/view/ShadowPainter.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.annotation.NonNull;
-
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.image.BufferedImage;
-import java.awt.image.DataBufferInt;
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.imageio.ImageIO;
-
-public class ShadowPainter {
-
-    /**
-     * Adds a drop shadow to a semi-transparent image (of an arbitrary shape) and returns it as a
-     * new image. This method attempts to mimic the same visual characteristics as the rectangular
-     * shadow painting methods in this class, {@link #createRectangularDropShadow(java.awt.image.BufferedImage)}
-     * and {@link #createSmallRectangularDropShadow(java.awt.image.BufferedImage)}.
-     * <p/>
-     * If shadowSize is less or equals to 1, no shadow will be painted and the source image will be
-     * returned instead.
-     *
-     * @param source the source image
-     * @param shadowSize the size of the shadow, normally {@link #SHADOW_SIZE or {@link
-     * #SMALL_SHADOW_SIZE}}
-     *
-     * @return an image with the shadow painted in or the source image if shadowSize <= 1
-     */
-    @NonNull
-    public static BufferedImage createDropShadow(BufferedImage source, int shadowSize) {
-        shadowSize /= 2; // make shadow size have the same meaning as in the other shadow paint methods in this class
-
-        return createDropShadow(source, shadowSize, 0.7f, 0);
-    }
-
-    /**
-     * Creates a drop shadow of a given image and returns a new image which shows the input image on
-     * top of its drop shadow.
-     * <p/>
-     * <b>NOTE: If the shape is rectangular and opaque, consider using {@link
-     * #drawRectangleShadow(Graphics2D, int, int, int, int)} instead.</b>
-     *
-     * @param source the source image to be shadowed
-     * @param shadowSize the size of the shadow in pixels
-     * @param shadowOpacity the opacity of the shadow, with 0=transparent and 1=opaque
-     * @param shadowRgb the RGB int to use for the shadow color
-     *
-     * @return a new image with the source image on top of its shadow when shadowSize > 0 or the
-     * source image otherwise
-     */
-    @SuppressWarnings({"SuspiciousNameCombination", "UnnecessaryLocalVariable"})  // Imported code
-    public static BufferedImage createDropShadow(BufferedImage source, int shadowSize,
-            float shadowOpacity, int shadowRgb) {
-        if (shadowSize <= 0) {
-            return source;
-        }
-
-        // This code is based on
-        //      http://www.jroller.com/gfx/entry/non_rectangular_shadow
-
-        BufferedImage image;
-        int width = source.getWidth();
-        int height = source.getHeight();
-        image = new BufferedImage(width + SHADOW_SIZE, height + SHADOW_SIZE,
-                BufferedImage.TYPE_INT_ARGB);
-
-        Graphics2D g2 = image.createGraphics();
-        g2.drawImage(image, shadowSize, shadowSize, null);
-
-        int dstWidth = image.getWidth();
-        int dstHeight = image.getHeight();
-
-        int left = (shadowSize - 1) >> 1;
-        int right = shadowSize - left;
-        int xStart = left;
-        int xStop = dstWidth - right;
-        int yStart = left;
-        int yStop = dstHeight - right;
-
-        shadowRgb &= 0x00FFFFFF;
-
-        int[] aHistory = new int[shadowSize];
-        int historyIdx;
-
-        int aSum;
-
-        int[] dataBuffer = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
-        int lastPixelOffset = right * dstWidth;
-        float sumDivider = shadowOpacity / shadowSize;
-
-        // horizontal pass
-        for (int y = 0, bufferOffset = 0; y < dstHeight; y++, bufferOffset = y * dstWidth) {
-            aSum = 0;
-            historyIdx = 0;
-            for (int x = 0; x < shadowSize; x++, bufferOffset++) {
-                int a = dataBuffer[bufferOffset] >>> 24;
-                aHistory[x] = a;
-                aSum += a;
-            }
-
-            bufferOffset -= right;
-
-            for (int x = xStart; x < xStop; x++, bufferOffset++) {
-                int a = (int) (aSum * sumDivider);
-                dataBuffer[bufferOffset] = a << 24 | shadowRgb;
-
-                // subtract the oldest pixel from the sum
-                aSum -= aHistory[historyIdx];
-
-                // get the latest pixel
-                a = dataBuffer[bufferOffset + right] >>> 24;
-                aHistory[historyIdx] = a;
-                aSum += a;
-
-                if (++historyIdx >= shadowSize) {
-                    historyIdx -= shadowSize;
-                }
-            }
-        }
-        // vertical pass
-        for (int x = 0, bufferOffset = 0; x < dstWidth; x++, bufferOffset = x) {
-            aSum = 0;
-            historyIdx = 0;
-            for (int y = 0; y < shadowSize; y++, bufferOffset += dstWidth) {
-                int a = dataBuffer[bufferOffset] >>> 24;
-                aHistory[y] = a;
-                aSum += a;
-            }
-
-            bufferOffset -= lastPixelOffset;
-
-            for (int y = yStart; y < yStop; y++, bufferOffset += dstWidth) {
-                int a = (int) (aSum * sumDivider);
-                dataBuffer[bufferOffset] = a << 24 | shadowRgb;
-
-                // subtract the oldest pixel from the sum
-                aSum -= aHistory[historyIdx];
-
-                // get the latest pixel
-                a = dataBuffer[bufferOffset + lastPixelOffset] >>> 24;
-                aHistory[historyIdx] = a;
-                aSum += a;
-
-                if (++historyIdx >= shadowSize) {
-                    historyIdx -= shadowSize;
-                }
-            }
-        }
-
-        g2.drawImage(source, null, 0, 0);
-        g2.dispose();
-
-        return image;
-    }
-
-    /**
-     * Draws a rectangular drop shadow (of size {@link #SHADOW_SIZE} by {@link #SHADOW_SIZE} around
-     * the given source and returns a new image with both combined
-     *
-     * @param source the source image
-     *
-     * @return the source image with a drop shadow on the bottom and right
-     */
-    @SuppressWarnings("UnusedDeclaration")
-    public static BufferedImage createRectangularDropShadow(BufferedImage source) {
-        int type = source.getType();
-        if (type == BufferedImage.TYPE_CUSTOM) {
-            type = BufferedImage.TYPE_INT_ARGB;
-        }
-
-        int width = source.getWidth();
-        int height = source.getHeight();
-        BufferedImage image;
-        image = new BufferedImage(width + SHADOW_SIZE, height + SHADOW_SIZE, type);
-        Graphics2D g = image.createGraphics();
-        g.drawImage(source, 0, 0, null);
-        drawRectangleShadow(image, 0, 0, width, height);
-        g.dispose();
-
-        return image;
-    }
-
-    /**
-     * Draws a small rectangular drop shadow (of size {@link #SMALL_SHADOW_SIZE} by {@link
-     * #SMALL_SHADOW_SIZE} around the given source and returns a new image with both combined
-     *
-     * @param source the source image
-     *
-     * @return the source image with a drop shadow on the bottom and right
-     */
-    @SuppressWarnings("UnusedDeclaration")
-    public static BufferedImage createSmallRectangularDropShadow(BufferedImage source) {
-        int type = source.getType();
-        if (type == BufferedImage.TYPE_CUSTOM) {
-            type = BufferedImage.TYPE_INT_ARGB;
-        }
-
-        int width = source.getWidth();
-        int height = source.getHeight();
-
-        BufferedImage image;
-        image = new BufferedImage(width + SMALL_SHADOW_SIZE, height + SMALL_SHADOW_SIZE, type);
-
-        Graphics2D g = image.createGraphics();
-        g.drawImage(source, 0, 0, null);
-        drawSmallRectangleShadow(image, 0, 0, width, height);
-        g.dispose();
-
-        return image;
-    }
-
-    /**
-     * Draws a drop shadow for the given rectangle into the given context. It will not draw anything
-     * if the rectangle is smaller than a minimum determined by the assets used to draw the shadow
-     * graphics. The size of the shadow is {@link #SHADOW_SIZE}.
-     *
-     * @param image the image to draw the shadow into
-     * @param x the left coordinate of the left hand side of the rectangle
-     * @param y the top coordinate of the top of the rectangle
-     * @param width the width of the rectangle
-     * @param height the height of the rectangle
-     */
-    public static void drawRectangleShadow(BufferedImage image,
-            int x, int y, int width, int height) {
-        Graphics2D gc = image.createGraphics();
-        try {
-            drawRectangleShadow(gc, x, y, width, height);
-        } finally {
-            gc.dispose();
-        }
-    }
-
-    /**
-     * Draws a small drop shadow for the given rectangle into the given context. It will not draw
-     * anything if the rectangle is smaller than a minimum determined by the assets used to draw the
-     * shadow graphics. The size of the shadow is {@link #SMALL_SHADOW_SIZE}.
-     *
-     * @param image the image to draw the shadow into
-     * @param x the left coordinate of the left hand side of the rectangle
-     * @param y the top coordinate of the top of the rectangle
-     * @param width the width of the rectangle
-     * @param height the height of the rectangle
-     */
-    public static void drawSmallRectangleShadow(BufferedImage image,
-            int x, int y, int width, int height) {
-        Graphics2D gc = image.createGraphics();
-        try {
-            drawSmallRectangleShadow(gc, x, y, width, height);
-        } finally {
-            gc.dispose();
-        }
-    }
-
-    /**
-     * The width and height of the drop shadow painted by
-     * {@link #drawRectangleShadow(Graphics2D, int, int, int, int)}
-     */
-    public static final int SHADOW_SIZE = 20; // DO NOT EDIT. This corresponds to bitmap graphics
-
-    /**
-     * The width and height of the drop shadow painted by
-     * {@link #drawSmallRectangleShadow(Graphics2D, int, int, int, int)}
-     */
-    public static final int SMALL_SHADOW_SIZE = 10; // DO NOT EDIT. Corresponds to bitmap graphics
-
-    /**
-     * Draws a drop shadow for the given rectangle into the given context. It will not draw anything
-     * if the rectangle is smaller than a minimum determined by the assets used to draw the shadow
-     * graphics.
-     *
-     * @param gc the graphics context to draw into
-     * @param x the left coordinate of the left hand side of the rectangle
-     * @param y the top coordinate of the top of the rectangle
-     * @param width the width of the rectangle
-     * @param height the height of the rectangle
-     */
-    public static void drawRectangleShadow(Graphics2D gc, int x, int y, int width, int height) {
-        assert ShadowBottomLeft != null;
-        assert ShadowBottomRight.getWidth(null) == SHADOW_SIZE;
-        assert ShadowBottomRight.getHeight(null) == SHADOW_SIZE;
-
-        int blWidth = ShadowBottomLeft.getWidth(null);
-        int trHeight = ShadowTopRight.getHeight(null);
-        if (width < blWidth) {
-            return;
-        }
-        if (height < trHeight) {
-            return;
-        }
-
-        gc.drawImage(ShadowBottomLeft, x - ShadowBottomLeft.getWidth(null), y + height, null);
-        gc.drawImage(ShadowBottomRight, x + width, y + height, null);
-        gc.drawImage(ShadowTopRight, x + width, y, null);
-        gc.drawImage(ShadowTopLeft, x - ShadowTopLeft.getWidth(null), y, null);
-        gc.drawImage(ShadowBottom,
-                x, y + height, x + width, y + height + ShadowBottom.getHeight(null),
-                0, 0, ShadowBottom.getWidth(null), ShadowBottom.getHeight(null), null);
-        gc.drawImage(ShadowRight,
-                x + width, y + ShadowTopRight.getHeight(null), x + width + ShadowRight.getWidth(null), y + height,
-                0, 0, ShadowRight.getWidth(null), ShadowRight.getHeight(null), null);
-        gc.drawImage(ShadowLeft,
-                x - ShadowLeft.getWidth(null), y + ShadowTopLeft.getHeight(null), x, y + height,
-                0, 0, ShadowLeft.getWidth(null), ShadowLeft.getHeight(null), null);
-    }
-
-    /**
-     * Draws a small drop shadow for the given rectangle into the given context. It will not draw
-     * anything if the rectangle is smaller than a minimum determined by the assets used to draw the
-     * shadow graphics.
-     * <p/>
-     *
-     * @param gc the graphics context to draw into
-     * @param x the left coordinate of the left hand side of the rectangle
-     * @param y the top coordinate of the top of the rectangle
-     * @param width the width of the rectangle
-     * @param height the height of the rectangle
-     */
-    public static void drawSmallRectangleShadow(Graphics2D gc, int x, int y, int width,
-            int height) {
-        assert Shadow2BottomLeft != null;
-        assert Shadow2TopRight != null;
-        assert Shadow2BottomRight.getWidth(null) == SMALL_SHADOW_SIZE;
-        assert Shadow2BottomRight.getHeight(null) == SMALL_SHADOW_SIZE;
-
-        int blWidth = Shadow2BottomLeft.getWidth(null);
-        int trHeight = Shadow2TopRight.getHeight(null);
-        if (width < blWidth) {
-            return;
-        }
-        if (height < trHeight) {
-            return;
-        }
-
-        gc.drawImage(Shadow2BottomLeft, x - Shadow2BottomLeft.getWidth(null), y + height, null);
-        gc.drawImage(Shadow2BottomRight, x + width, y + height, null);
-        gc.drawImage(Shadow2TopRight, x + width, y, null);
-        gc.drawImage(Shadow2TopLeft, x - Shadow2TopLeft.getWidth(null), y, null);
-        gc.drawImage(Shadow2Bottom,
-                x, y + height, x + width, y + height + Shadow2Bottom.getHeight(null),
-                0, 0, Shadow2Bottom.getWidth(null), Shadow2Bottom.getHeight(null), null);
-        gc.drawImage(Shadow2Right,
-                x + width, y + Shadow2TopRight.getHeight(null), x + width + Shadow2Right.getWidth(null), y + height,
-                0, 0, Shadow2Right.getWidth(null), Shadow2Right.getHeight(null), null);
-        gc.drawImage(Shadow2Left,
-                x - Shadow2Left.getWidth(null), y + Shadow2TopLeft.getHeight(null), x, y + height,
-                0, 0, Shadow2Left.getWidth(null), Shadow2Left.getHeight(null), null);
-    }
-
-    private static Image loadIcon(String name) {
-        InputStream inputStream = ShadowPainter.class.getResourceAsStream(name);
-        if (inputStream == null) {
-            throw new RuntimeException("Unable to load image for shadow: " + name);
-        }
-        try {
-            return ImageIO.read(inputStream);
-        } catch (IOException e) {
-            throw new RuntimeException("Unable to load image for shadow:" + name, e);
-        } finally {
-            try {
-                inputStream.close();
-            } catch (IOException e) {
-                // ignore.
-            }
-        }
-    }
-
-    // Shadow graphics. This was generated by creating a drop shadow in
-    // Gimp, using the parameters x offset=10, y offset=10, blur radius=10,
-    // (for the small drop shadows x offset=10, y offset=10, blur radius=10)
-    // color=black, and opacity=51. These values attempt to make a shadow
-    // that is legible both for dark and light themes, on top of the
-    // canvas background (rgb(150,150,150). Darker shadows would tend to
-    // blend into the foreground for a dark holo screen, and lighter shadows
-    // would be hard to spot on the canvas background. If you make adjustments,
-    // make sure to check the shadow with both dark and light themes.
-    //
-    // After making the graphics, I cut out the top right, bottom left
-    // and bottom right corners as 20x20 images, and these are reproduced by
-    // painting them in the corresponding places in the target graphics context.
-    // I then grabbed a single horizontal gradient line from the middle of the
-    // right edge,and a single vertical gradient line from the bottom. These
-    // are then painted scaled/stretched in the target to fill the gaps between
-    // the three corner images.
-    //
-    // Filenames: bl=bottom left, b=bottom, br=bottom right, r=right, tr=top right
-
-    // Normal Drop Shadow
-    private static final Image ShadowBottom = loadIcon("/icons/shadow-b.png");
-    private static final Image ShadowBottomLeft = loadIcon("/icons/shadow-bl.png");
-    private static final Image ShadowBottomRight = loadIcon("/icons/shadow-br.png");
-    private static final Image ShadowRight = loadIcon("/icons/shadow-r.png");
-    private static final Image ShadowTopRight = loadIcon("/icons/shadow-tr.png");
-    private static final Image ShadowTopLeft = loadIcon("/icons/shadow-tl.png");
-    private static final Image ShadowLeft = loadIcon("/icons/shadow-l.png");
-
-    // Small Drop Shadow
-    private static final Image Shadow2Bottom = loadIcon("/icons/shadow2-b.png");
-    private static final Image Shadow2BottomLeft = loadIcon("/icons/shadow2-bl.png");
-    private static final Image Shadow2BottomRight = loadIcon("/icons/shadow2-br.png");
-    private static final Image Shadow2Right = loadIcon("/icons/shadow2-r.png");
-    private static final Image Shadow2TopRight = loadIcon("/icons/shadow2-tr.png");
-    private static final Image Shadow2TopLeft = loadIcon("/icons/shadow2-tl.png");
-    private static final Image Shadow2Left = loadIcon("/icons/shadow2-l.png");
-}
diff --git a/tools/layoutlib/bridge/src/android/view/SurfaceView.java b/tools/layoutlib/bridge/src/android/view/SurfaceView.java
deleted file mode 100644
index ebb2af4..0000000
--- a/tools/layoutlib/bridge/src/android/view/SurfaceView.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.layoutlib.bridge.MockView;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.util.AttributeSet;
-
-/**
- * Mock version of the SurfaceView.
- * Only non override public methods from the real SurfaceView have been added in there.
- * Methods that take an unknown class as parameter or as return object, have been removed for now.
- *
- * TODO: generate automatically.
- *
- */
-public class SurfaceView extends MockView {
-
-    public SurfaceView(Context context) {
-        this(context, null);
-    }
-
-    public SurfaceView(Context context, AttributeSet attrs) {
-        this(context, attrs , 0);
-    }
-
-    public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    public boolean gatherTransparentRegion(Region region) {
-      return false;
-    }
-
-    public void setZOrderMediaOverlay(boolean isMediaOverlay) {
-    }
-
-    public void setZOrderOnTop(boolean onTop) {
-    }
-
-    public void setSecure(boolean isSecure) {
-    }
-
-    public SurfaceHolder getHolder() {
-        return mSurfaceHolder;
-    }
-
-    private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
-
-        @Override
-        public boolean isCreating() {
-            return false;
-        }
-
-        @Override
-        public void addCallback(Callback callback) {
-        }
-
-        @Override
-        public void removeCallback(Callback callback) {
-        }
-
-        @Override
-        public void setFixedSize(int width, int height) {
-        }
-
-        @Override
-        public void setSizeFromLayout() {
-        }
-
-        @Override
-        public void setFormat(int format) {
-        }
-
-        @Override
-        public void setType(int type) {
-        }
-
-        @Override
-        public void setKeepScreenOn(boolean screenOn) {
-        }
-
-        @Override
-        public Canvas lockCanvas() {
-            return null;
-        }
-
-        @Override
-        public Canvas lockCanvas(Rect dirty) {
-            return null;
-        }
-
-        @Override
-        public void unlockCanvasAndPost(Canvas canvas) {
-        }
-
-        @Override
-        public Surface getSurface() {
-            return null;
-        }
-
-        @Override
-        public Rect getSurfaceFrame() {
-            return null;
-        }
-    };
-}
-
diff --git a/tools/layoutlib/bridge/src/android/view/ViewConfiguration_Accessor.java b/tools/layoutlib/bridge/src/android/view/ViewConfiguration_Accessor.java
deleted file mode 100644
index c3533e0..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewConfiguration_Accessor.java
+++ /dev/null
@@ -1,29 +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.
- */
-
-package android.view;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class ViewConfiguration_Accessor {
-
-    public static void clearConfigurations() {
-        // clear the stored ViewConfiguration since the map is per density and not per context.
-        ViewConfiguration.sConfigurations.clear();
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
deleted file mode 100644
index 4b760a7..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.resources.Density;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.graphics.Outline;
-import android.graphics.Path_Delegate;
-import android.graphics.Rect;
-import android.graphics.Region.Op;
-import android.view.animation.Transformation;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link ViewGroup}
- * <p/>
- * Through the layoutlib_create tool, the original  methods of ViewGroup have been replaced by calls
- * to methods of the same name in this delegate class.
- */
-public class ViewGroup_Delegate {
-
-    /**
-     * Overrides the original drawChild call in ViewGroup to draw the shadow.
-     */
-    @LayoutlibDelegate
-    /*package*/ static boolean drawChild(ViewGroup thisVG, Canvas canvas, View child,
-            long drawingTime) {
-        if (child.getZ() > thisVG.getZ()) {
-            // The background's bounds are set lazily. Make sure they are set correctly so that
-            // the outline obtained is correct.
-            child.setBackgroundBounds();
-            ViewOutlineProvider outlineProvider = child.getOutlineProvider();
-            if (outlineProvider != null) {
-                Outline outline = child.mAttachInfo.mTmpOutline;
-                outlineProvider.getOutline(child, outline);
-                if (outline.mPath != null || (outline.mRect != null && !outline.mRect.isEmpty())) {
-                    int restoreTo = transformCanvas(thisVG, canvas, child);
-                    drawShadow(thisVG, canvas, child, outline);
-                    canvas.restoreToCount(restoreTo);
-                }
-            }
-        }
-        return thisVG.drawChild_Original(canvas, child, drawingTime);
-    }
-
-    private static void drawShadow(ViewGroup parent, Canvas canvas, View child,
-            Outline outline) {
-        float elevation = getElevation(child, parent);
-        if(outline.mMode == Outline.MODE_ROUND_RECT && outline.mRect != null) {
-            RectShadowPainter.paintShadow(outline, elevation, canvas);
-            return;
-        }
-        BufferedImage shadow = null;
-        if (outline.mPath != null) {
-            shadow = getPathShadow(outline, canvas, elevation);
-        }
-        if (shadow == null) {
-            return;
-        }
-        Bitmap bitmap = Bitmap_Delegate.createBitmap(shadow, false,
-                Density.getEnum(canvas.getDensity()));
-        Rect clipBounds = canvas.getClipBounds();
-        Rect newBounds = new Rect(clipBounds);
-        newBounds.inset((int)-elevation, (int)-elevation);
-        canvas.clipRect(newBounds, Op.REPLACE);
-        canvas.drawBitmap(bitmap, 0, 0, null);
-        canvas.clipRect(clipBounds, Op.REPLACE);
-    }
-
-    private static float getElevation(View child, ViewGroup parent) {
-        return child.getZ() - parent.getZ();
-    }
-
-    private static BufferedImage getPathShadow(Outline outline, Canvas canvas, float elevation) {
-        Rect clipBounds = canvas.getClipBounds();
-        if (clipBounds.isEmpty()) {
-          return null;
-        }
-        BufferedImage image = new BufferedImage(clipBounds.width(), clipBounds.height(),
-                BufferedImage.TYPE_INT_ARGB);
-        Graphics2D graphics = image.createGraphics();
-        graphics.draw(Path_Delegate.getDelegate(outline.mPath.mNativePath).getJavaShape());
-        graphics.dispose();
-        return ShadowPainter.createDropShadow(image, (int) elevation);
-    }
-
-    // Copied from android.view.View#draw(Canvas, ViewGroup, long) and removed code paths
-    // which were never taken. Ideally, we should hook up the shadow code in the same method so
-    // that we don't have to transform the canvas twice.
-    private static int transformCanvas(ViewGroup thisVG, Canvas canvas, View child) {
-        final int restoreTo = canvas.save();
-        final boolean childHasIdentityMatrix = child.hasIdentityMatrix();
-        int flags = thisVG.mGroupFlags;
-        Transformation transformToApply = null;
-        boolean concatMatrix = false;
-        if ((flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
-            final Transformation t = thisVG.getChildTransformation();
-            final boolean hasTransform = thisVG.getChildStaticTransformation(child, t);
-            if (hasTransform) {
-                final int transformType = t.getTransformationType();
-                transformToApply = transformType != Transformation.TYPE_IDENTITY ? t : null;
-                concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0;
-            }
-        }
-        concatMatrix |= childHasIdentityMatrix;
-
-        child.computeScroll();
-        int sx = child.mScrollX;
-        int sy = child.mScrollY;
-
-        canvas.translate(child.mLeft - sx, child.mTop - sy);
-        float alpha = child.getAlpha() * child.getTransitionAlpha();
-
-        if (transformToApply != null || alpha < 1 || !childHasIdentityMatrix) {
-            if (transformToApply != null || !childHasIdentityMatrix) {
-                int transX = -sx;
-                int transY = -sy;
-
-                if (transformToApply != null) {
-                    if (concatMatrix) {
-                        // Undo the scroll translation, apply the transformation matrix,
-                        // then redo the scroll translate to get the correct result.
-                        canvas.translate(-transX, -transY);
-                        canvas.concat(transformToApply.getMatrix());
-                        canvas.translate(transX, transY);
-                    }
-                    if (!childHasIdentityMatrix) {
-                        canvas.translate(-transX, -transY);
-                        canvas.concat(child.getMatrix());
-                        canvas.translate(transX, transY);
-                    }
-                }
-
-            }
-        }
-        return restoreTo;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Accessor.java b/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Accessor.java
deleted file mode 100644
index 0e15b97..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Accessor.java
+++ /dev/null
@@ -1,26 +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;
-
-/**
- * Accessor to allow layoutlib to call {@link ViewRootImpl#dispatchApplyInsets} directly.
- */
-public class ViewRootImpl_Accessor {
-    public static void dispatchApplyInsets(ViewRootImpl viewRoot, View host) {
-        viewRoot.dispatchApplyInsets(host);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java
deleted file mode 100644
index 14b84ef..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link ViewRootImpl}
- *
- * Through the layoutlib_create tool, the original  methods of ViewRootImpl have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class ViewRootImpl_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isInTouchMode() {
-        return false; // this allows displaying selection.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/View_Delegate.java b/tools/layoutlib/bridge/src/android/view/View_Delegate.java
deleted file mode 100644
index 408ec54..0000000
--- a/tools/layoutlib/bridge/src/android/view/View_Delegate.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-import android.os.IBinder;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link View}
- *
- * Through the layoutlib_create tool, the original  methods of View have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class View_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isInEditMode(View thisView) {
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static IBinder getWindowToken(View thisView) {
-        Context baseContext = BridgeContext.getBaseContext(thisView.getContext());
-        if (baseContext instanceof BridgeContext) {
-            return ((BridgeContext) baseContext).getBinder();
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/WindowCallback.java b/tools/layoutlib/bridge/src/android/view/WindowCallback.java
deleted file mode 100644
index 1ea8a9f..0000000
--- a/tools/layoutlib/bridge/src/android/view/WindowCallback.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.annotation.Nullable;
-import android.view.ActionMode.Callback;
-import android.view.WindowManager.LayoutParams;
-import android.view.accessibility.AccessibilityEvent;
-
-import java.util.List;
-
-/**
- * An empty implementation of {@link Window.Callback} that always returns null/false.
- */
-public class WindowCallback implements Window.Callback {
-    @Override
-    public boolean dispatchKeyEvent(KeyEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchKeyShortcutEvent(KeyEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchTrackballEvent(MotionEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchGenericMotionEvent(MotionEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        return false;
-    }
-
-    @Override
-    public View onCreatePanelView(int featureId) {
-        return null;
-    }
-
-    @Override
-    public boolean onCreatePanelMenu(int featureId, Menu menu) {
-        return false;
-    }
-
-    @Override
-    public boolean onPreparePanel(int featureId, View view, Menu menu) {
-        return false;
-    }
-
-    @Override
-    public boolean onMenuOpened(int featureId, Menu menu) {
-        return false;
-    }
-
-    @Override
-    public boolean onMenuItemSelected(int featureId, MenuItem item) {
-        return false;
-    }
-
-    @Override
-    public void onWindowAttributesChanged(LayoutParams attrs) {
-
-    }
-
-    @Override
-    public void onContentChanged() {
-
-    }
-
-    @Override
-    public void onWindowFocusChanged(boolean hasFocus) {
-
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-
-    }
-
-    @Override
-    public void onPanelClosed(int featureId, Menu menu) {
-
-    }
-
-    @Override
-    public boolean onSearchRequested(SearchEvent searchEvent) {
-        return onSearchRequested();
-    }
-
-    @Override
-    public boolean onSearchRequested() {
-        return false;
-    }
-
-    @Override
-    public ActionMode onWindowStartingActionMode(Callback callback) {
-        return null;
-    }
-
-    @Override
-    public ActionMode onWindowStartingActionMode(Callback callback, int type) {
-        return null;
-    }
-
-    @Override
-    public void onActionModeStarted(ActionMode mode) {
-
-    }
-
-    @Override
-    public void onActionModeFinished(ActionMode mode) {
-
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java b/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java
deleted file mode 100644
index 2606e55..0000000
--- a/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of
- * {@link WindowManagerGlobal}
- *
- * Through the layoutlib_create tool, the original  methods of WindowManagerGlobal have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-public class WindowManagerGlobal_Delegate {
-
-    private static IWindowManager sService;
-
-    @LayoutlibDelegate
-    public static IWindowManager getWindowManagerService() {
-        return sService;
-    }
-
-    // ---- internal implementation stuff ----
-
-    public static void setWindowManagerService(IWindowManager service) {
-        sService = service;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java b/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java
deleted file mode 100644
index 672ff6d..0000000
--- a/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java
+++ /dev/null
@@ -1,278 +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 android.view.accessibility;
-
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.pm.ServiceInfo;
-import android.view.IWindow;
-import android.view.View;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * System level service that serves as an event dispatch for {@link AccessibilityEvent}s.
- * Such events are generated when something notable happens in the user interface,
- * for example an {@link android.app.Activity} starts, the focus or selection of a
- * {@link android.view.View} changes etc. Parties interested in handling accessibility
- * events implement and register an accessibility service which extends
- * {@code android.accessibilityservice.AccessibilityService}.
- *
- * @see AccessibilityEvent
- * @see android.content.Context#getSystemService
- */
-@SuppressWarnings("UnusedDeclaration")
-public final class AccessibilityManager {
-
-    private static AccessibilityManager sInstance = new AccessibilityManager(null, null, 0);
-
-
-    /**
-     * Listener for the accessibility state.
-     */
-    public interface AccessibilityStateChangeListener {
-
-        /**
-         * Called back on change in the accessibility state.
-         *
-         * @param enabled Whether accessibility is enabled.
-         */
-        public void onAccessibilityStateChanged(boolean enabled);
-    }
-
-    /**
-     * Listener for the system touch exploration state. To listen for changes to
-     * the touch exploration state on the device, implement this interface and
-     * register it with the system by calling
-     * {@link #addTouchExplorationStateChangeListener}.
-     */
-    public interface TouchExplorationStateChangeListener {
-
-        /**
-         * Called when the touch exploration enabled state changes.
-         *
-         * @param enabled Whether touch exploration is enabled.
-         */
-        public void onTouchExplorationStateChanged(boolean enabled);
-    }
-
-    /**
-     * Listener for the system high text contrast state. To listen for changes to
-     * the high text contrast state on the device, implement this interface and
-     * register it with the system by calling
-     * {@link #addHighTextContrastStateChangeListener}.
-     */
-    public interface HighTextContrastChangeListener {
-
-        /**
-         * Called when the high text contrast enabled state changes.
-         *
-         * @param enabled Whether high text contrast is enabled.
-         */
-        public void onHighTextContrastStateChanged(boolean enabled);
-    }
-
-    private final IAccessibilityManagerClient.Stub mClient =
-            new IAccessibilityManagerClient.Stub() {
-                public void setState(int state) {
-                }
-
-                public void notifyServicesStateChanged() {
-                }
-
-                public void setRelevantEventTypes(int eventTypes) {
-                }
-            };
-
-    /**
-     * Get an AccessibilityManager instance (create one if necessary).
-     *
-     */
-    public static AccessibilityManager getInstance(Context context) {
-        return sInstance;
-    }
-
-    /**
-     * Create an instance.
-     *
-     * @param context A {@link Context}.
-     */
-    public AccessibilityManager(Context context, IAccessibilityManager service, int userId) {
-    }
-
-    public IAccessibilityManagerClient getClient() {
-        return mClient;
-    }
-
-    /**
-     * Returns if the {@link AccessibilityManager} is enabled.
-     *
-     * @return True if this {@link AccessibilityManager} is enabled, false otherwise.
-     */
-    public boolean isEnabled() {
-        return false;
-    }
-
-    /**
-     * Returns if the touch exploration in the system is enabled.
-     *
-     * @return True if touch exploration is enabled, false otherwise.
-     */
-    public boolean isTouchExplorationEnabled() {
-        return true;
-    }
-
-    /**
-     * Returns if the high text contrast in the system is enabled.
-     * <p>
-     * <strong>Note:</strong> You need to query this only if you application is
-     * doing its own rendering and does not rely on the platform rendering pipeline.
-     * </p>
-     *
-     */
-    public boolean isHighTextContrastEnabled() {
-        return false;
-    }
-
-    /**
-     * Sends an {@link AccessibilityEvent}.
-     */
-    public void sendAccessibilityEvent(AccessibilityEvent event) {
-    }
-
-    /**
-     * Requests interruption of the accessibility feedback from all accessibility services.
-     */
-    public void interrupt() {
-    }
-
-    /**
-     * Returns the {@link ServiceInfo}s of the installed accessibility services.
-     *
-     * @return An unmodifiable list with {@link ServiceInfo}s.
-     */
-    @Deprecated
-    public List<ServiceInfo> getAccessibilityServiceList() {
-        return Collections.emptyList();
-    }
-
-    public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList() {
-        return Collections.emptyList();
-    }
-
-    /**
-     * Returns the {@link AccessibilityServiceInfo}s of the enabled accessibility services
-     * for a given feedback type.
-     *
-     * @param feedbackTypeFlags The feedback type flags.
-     * @return An unmodifiable list with {@link AccessibilityServiceInfo}s.
-     *
-     * @see AccessibilityServiceInfo#FEEDBACK_AUDIBLE
-     * @see AccessibilityServiceInfo#FEEDBACK_GENERIC
-     * @see AccessibilityServiceInfo#FEEDBACK_HAPTIC
-     * @see AccessibilityServiceInfo#FEEDBACK_SPOKEN
-     * @see AccessibilityServiceInfo#FEEDBACK_VISUAL
-     */
-    public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(
-            int feedbackTypeFlags) {
-        return Collections.emptyList();
-    }
-
-    /**
-     * Registers an {@link AccessibilityStateChangeListener} for changes in
-     * the global accessibility state of the system.
-     *
-     * @param listener The listener.
-     * @return True if successfully registered.
-     */
-    public boolean addAccessibilityStateChangeListener(
-            AccessibilityStateChangeListener listener) {
-        return true;
-    }
-
-    public boolean removeAccessibilityStateChangeListener(
-            AccessibilityStateChangeListener listener) {
-        return true;
-    }
-
-    /**
-     * Registers a {@link TouchExplorationStateChangeListener} for changes in
-     * the global touch exploration state of the system.
-     *
-     * @param listener The listener.
-     * @return True if successfully registered.
-     */
-    public boolean addTouchExplorationStateChangeListener(
-            @NonNull TouchExplorationStateChangeListener listener) {
-        return true;
-    }
-
-    /**
-     * Unregisters a {@link TouchExplorationStateChangeListener}.
-     *
-     * @param listener The listener.
-     * @return True if successfully unregistered.
-     */
-    public boolean removeTouchExplorationStateChangeListener(
-            @NonNull TouchExplorationStateChangeListener listener) {
-        return true;
-    }
-
-    /**
-     * Registers a {@link HighTextContrastChangeListener} for changes in
-     * the global high text contrast state of the system.
-     *
-     * @param listener The listener.
-     * @return True if successfully registered.
-     *
-     */
-    public boolean addHighTextContrastStateChangeListener(
-            @NonNull HighTextContrastChangeListener listener) {
-        return true;
-    }
-
-    /**
-     * Unregisters a {@link HighTextContrastChangeListener}.
-     *
-     * @param listener The listener.
-     * @return True if successfully unregistered.
-     *
-     */
-    public boolean removeHighTextContrastStateChangeListener(
-            @NonNull HighTextContrastChangeListener listener) {
-        return true;
-    }
-
-    /**
-     * Sets the current state and notifies listeners, if necessary.
-     *
-     * @param stateFlags The state flags.
-     */
-    private void setStateLocked(int stateFlags) {
-    }
-
-    public int addAccessibilityInteractionConnection(IWindow windowToken,
-            IAccessibilityInteractionConnection connection) {
-        return View.NO_ID;
-    }
-
-    public void removeAccessibilityInteractionConnection(IWindow windowToken) {
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java b/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java
deleted file mode 100644
index dc4f9c8..0000000
--- a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java
+++ /dev/null
@@ -1,27 +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.
- */
-
-package android.view.inputmethod;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class InputMethodManager_Accessor {
-
-    public static void resetInstance() {
-        InputMethodManager.sInstance = null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java b/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java
deleted file mode 100644
index 7c98847..0000000
--- a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java
+++ /dev/null
@@ -1,49 +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.
- */
-
-package android.view.inputmethod;
-
-import com.android.layoutlib.bridge.android.BridgeIInputMethodManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-import android.os.Looper;
-
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link InputMethodManager}
- *
- * Through the layoutlib_create tool, the original  methods of InputMethodManager have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class InputMethodManager_Delegate {
-
-    // ---- Overridden methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static InputMethodManager getInstance() {
-        synchronized (InputMethodManager.class) {
-            InputMethodManager imm = InputMethodManager.peekInstance();
-            if (imm == null) {
-                imm = new InputMethodManager(
-                        new BridgeIInputMethodManager(), Looper.getMainLooper());
-                InputMethodManager.sInstance = imm;
-            }
-            return imm;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/textservice/TextServicesManager.java b/tools/layoutlib/bridge/src/android/view/textservice/TextServicesManager.java
deleted file mode 100644
index 8e1f218..0000000
--- a/tools/layoutlib/bridge/src/android/view/textservice/TextServicesManager.java
+++ /dev/null
@@ -1,72 +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.textservice;
-
-import android.os.Bundle;
-import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;
-
-import java.util.Locale;
-
-/**
- * A stub class of TextServicesManager for Layout-Lib.
- */
-public final class TextServicesManager {
-    private static final TextServicesManager sInstance = new TextServicesManager();
-    private static final SpellCheckerInfo[] EMPTY_SPELL_CHECKER_INFO = new SpellCheckerInfo[0];
-
-    /**
-     * Retrieve the global TextServicesManager instance, creating it if it doesn't already exist.
-     * @hide
-     */
-    public static TextServicesManager getInstance() {
-        return sInstance;
-    }
-
-    public SpellCheckerSession newSpellCheckerSession(Bundle bundle, Locale locale,
-            SpellCheckerSessionListener listener, boolean referToSpellCheckerLanguageSettings) {
-        return null;
-    }
-
-    /**
-     * @hide
-     */
-    public SpellCheckerInfo[] getEnabledSpellCheckers() {
-        return EMPTY_SPELL_CHECKER_INFO;
-    }
-
-    /**
-     * @hide
-     */
-    public SpellCheckerInfo getCurrentSpellChecker() {
-        return null;
-    }
-
-    /**
-     * @hide
-     */
-    public SpellCheckerSubtype getCurrentSpellCheckerSubtype(
-            boolean allowImplicitlySelectedSubtype) {
-        return null;
-    }
-
-    /**
-     * @hide
-     */
-    public boolean isSpellCheckerEnabled() {
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/webkit/WebView.java b/tools/layoutlib/bridge/src/android/webkit/WebView.java
deleted file mode 100644
index 202f204..0000000
--- a/tools/layoutlib/bridge/src/android/webkit/WebView.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.webkit;
-
-import com.android.layoutlib.bridge.MockView;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Picture;
-import android.os.Bundle;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * Mock version of the WebView.
- * Only non override public methods from the real WebView have been added in there.
- * Methods that take an unknown class as parameter or as return object, have been removed for now.
- * 
- * TODO: generate automatically.
- *
- */
-public class WebView extends MockView {
-
-    /**
-     * Construct a new WebView with a Context object.
-     * @param context A Context object used to access application assets.
-     */
-    public WebView(Context context) {
-        this(context, null);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     */
-    public WebView(Context context, AttributeSet attrs) {
-        this(context, attrs, com.android.internal.R.attr.webViewStyle);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters and a default style.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     * @param defStyle The default style resource ID.
-     */
-    public WebView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-    
-    // START FAKE PUBLIC METHODS
-    
-    public void setHorizontalScrollbarOverlay(boolean overlay) {
-    }
-
-    public void setVerticalScrollbarOverlay(boolean overlay) {
-    }
-
-    public boolean overlayHorizontalScrollbar() {
-        return false;
-    }
-
-    public boolean overlayVerticalScrollbar() {
-        return false;
-    }
-
-    public void savePassword(String host, String username, String password) {
-    }
-
-    public void setHttpAuthUsernamePassword(String host, String realm,
-            String username, String password) {
-    }
-
-    public String[] getHttpAuthUsernamePassword(String host, String realm) {
-        return null;
-    }
-
-    public void destroy() {
-    }
-
-    public static void enablePlatformNotifications() {
-    }
-
-    public static void disablePlatformNotifications() {
-    }
-
-    public void loadUrl(String url) {
-    }
-
-    public void loadData(String data, String mimeType, String encoding) {
-    }
-
-    public void loadDataWithBaseURL(String baseUrl, String data,
-            String mimeType, String encoding, String failUrl) {
-    }
-
-    public void stopLoading() {
-    }
-
-    public void reload() {
-    }
-
-    public boolean canGoBack() {
-        return false;
-    }
-
-    public void goBack() {
-    }
-
-    public boolean canGoForward() {
-        return false;
-    }
-
-    public void goForward() {
-    }
-
-    public boolean canGoBackOrForward(int steps) {
-        return false;
-    }
-
-    public void goBackOrForward(int steps) {
-    }
-
-    public boolean pageUp(boolean top) {
-        return false;
-    }
-    
-    public boolean pageDown(boolean bottom) {
-        return false;
-    }
-
-    public void clearView() {
-    }
-    
-    public Picture capturePicture() {
-        return null;
-    }
-
-    public float getScale() {
-        return 0;
-    }
-
-    public void setInitialScale(int scaleInPercent) {
-    }
-
-    public void invokeZoomPicker() {
-    }
-
-    public void requestFocusNodeHref(Message hrefMsg) {
-    }
-
-    public void requestImageRef(Message msg) {
-    }
-
-    public String getUrl() {
-        return null;
-    }
-
-    public String getTitle() {
-        return null;
-    }
-
-    public Bitmap getFavicon() {
-        return null;
-    }
-
-    public int getProgress() {
-        return 0;
-    }
-    
-    public int getContentHeight() {
-        return 0;
-    }
-
-    public void pauseTimers() {
-    }
-
-    public void resumeTimers() {
-    }
-
-    public void clearCache() {
-    }
-
-    public void clearFormData() {
-    }
-
-    public void clearHistory() {
-    }
-
-    public void clearSslPreferences() {
-    }
-
-    public static String findAddress(String addr) {
-        return null;
-    }
-
-    public void documentHasImages(Message response) {
-    }
-
-    public void setWebViewClient(WebViewClient client) {
-    }
-
-    public void setDownloadListener(DownloadListener listener) {
-    }
-
-    public void setWebChromeClient(WebChromeClient client) {
-    }
-
-    public void addJavascriptInterface(Object obj, String interfaceName) {
-    }
-
-    public View getZoomControls() {
-        return null;
-    }
-
-    public boolean zoomIn() {
-        return false;
-    }
-
-    public boolean zoomOut() {
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java b/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java
deleted file mode 100644
index fdd1779..0000000
--- a/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.widget;
-
-import android.content.Context;
-
-/**
- * To access non public members of classes in {@link Toolbar}
- */
-public class Toolbar_Accessor {
-    public static ActionMenuPresenter getActionMenuPresenter(Toolbar toolbar) {
-        return toolbar.getOuterActionMenuPresenter();
-    }
-
-    public static Context getPopupContext(Toolbar toolbar) {
-        return toolbar.getPopupContext();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/util/VirtualRefBasePtr_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/util/VirtualRefBasePtr_Delegate.java
deleted file mode 100644
index 01fe45d..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/util/VirtualRefBasePtr_Delegate.java
+++ /dev/null
@@ -1,53 +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.internal.util;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.util.LongSparseLongArray;
-
-/**
- * Delegate used to provide new implementation the native methods of {@link VirtualRefBasePtr}
- *
- * Through the layoutlib_create tool, the original native  methods of VirtualRefBasePtr have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-@SuppressWarnings("unused")
-public class VirtualRefBasePtr_Delegate {
-    private static final DelegateManager<Object> sManager = new DelegateManager<>(Object.class);
-    private static final LongSparseLongArray sRefCount = new LongSparseLongArray();
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized void nIncStrong(long ptr) {
-        long counter = sRefCount.get(ptr);
-        sRefCount.put(ptr, ++counter);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized void nDecStrong(long ptr) {
-        long counter = sRefCount.get(ptr);
-
-        if (counter > 1) {
-            sRefCount.put(ptr, --counter);
-        } else {
-            sRefCount.delete(ptr);
-            sManager.removeJavaReferenceFor(ptr);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java
deleted file mode 100644
index bf998b8..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java
+++ /dev/null
@@ -1,74 +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.
- */
-
-package com.android.internal.util;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link XmlUtils}
- *
- * Through the layoutlib_create tool, the original  methods of XmlUtils have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class XmlUtils_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static final int convertValueToInt(CharSequence charSeq, int defaultValue) {
-        if (null == charSeq)
-            return defaultValue;
-
-        String nm = charSeq.toString();
-
-        // This code is copied from the original implementation. The issue is that
-        // The Dalvik libraries are able to handle Integer.parse("XXXXXXXX", 16) where XXXXXXX
-        // is > 80000000 but the Java VM cannot.
-
-        int sign = 1;
-        int index = 0;
-        int len = nm.length();
-        int base = 10;
-
-        if ('-' == nm.charAt(0)) {
-            sign = -1;
-            index++;
-        }
-
-        if ('0' == nm.charAt(index)) {
-            //  Quick check for a zero by itself
-            if (index == (len - 1))
-                return 0;
-
-            char c = nm.charAt(index + 1);
-
-            if ('x' == c || 'X' == c) {
-                index += 2;
-                base = 16;
-            } else {
-                index++;
-                base = 8;
-            }
-        }
-        else if ('#' == nm.charAt(index)) {
-            index++;
-            base = 16;
-        }
-
-        return ((int)Long.parseLong(nm.substring(index), base)) * sign;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java
deleted file mode 100644
index da1ab27..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java
+++ /dev/null
@@ -1,140 +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.internal.view.animation;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Path;
-import android.util.MathUtils;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.AnticipateInterpolator;
-import android.view.animation.AnticipateOvershootInterpolator;
-import android.view.animation.BaseInterpolator;
-import android.view.animation.BounceInterpolator;
-import android.view.animation.CycleInterpolator;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-import android.view.animation.OvershootInterpolator;
-import android.view.animation.PathInterpolator;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link
- * NativeInterpolatorFactoryHelper}
- * <p>
- * Through the layoutlib_create tool, the original  methods of NativeInterpolatorFactoryHelper have
- * been replaced by calls to methods of the same name in this delegate class.
- */
-@SuppressWarnings("unused")
-public class NativeInterpolatorFactoryHelper_Delegate {
-    private static final DelegateManager<Interpolator> sManager = new DelegateManager<>
-            (Interpolator.class);
-
-    public static Interpolator getDelegate(long nativePtr) {
-        return sManager.getDelegate(nativePtr);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createAccelerateDecelerateInterpolator() {
-        return sManager.addNewDelegate(new AccelerateDecelerateInterpolator());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createAccelerateInterpolator(float factor) {
-        return sManager.addNewDelegate(new AccelerateInterpolator(factor));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createAnticipateInterpolator(float tension) {
-        return sManager.addNewDelegate(new AnticipateInterpolator(tension));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createAnticipateOvershootInterpolator(float tension) {
-        return sManager.addNewDelegate(new AnticipateOvershootInterpolator(tension));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createBounceInterpolator() {
-        return sManager.addNewDelegate(new BounceInterpolator());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createCycleInterpolator(float cycles) {
-        return sManager.addNewDelegate(new CycleInterpolator(cycles));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createDecelerateInterpolator(float factor) {
-        return sManager.addNewDelegate(new DecelerateInterpolator(factor));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createLinearInterpolator() {
-        return sManager.addNewDelegate(new LinearInterpolator());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createOvershootInterpolator(float tension) {
-        return sManager.addNewDelegate(new OvershootInterpolator(tension));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createPathInterpolator(float[] x, float[] y) {
-        Path path = new Path();
-        path.moveTo(x[0], y[0]);
-        for (int i = 1; i < x.length; i++) {
-            path.lineTo(x[i], y[i]);
-        }
-        return sManager.addNewDelegate(new PathInterpolator(path));
-    }
-
-    private static class LutInterpolator extends BaseInterpolator {
-        private final float[] mValues;
-        private final int mSize;
-
-        private LutInterpolator(float[] values) {
-            mValues = values;
-            mSize = mValues.length;
-        }
-
-        @Override
-        public float getInterpolation(float input) {
-            float lutpos = input * (mSize - 1);
-            if (lutpos >= (mSize - 1)) {
-                return mValues[mSize - 1];
-            }
-
-            int ipart = (int) lutpos;
-            float weight = lutpos - ipart;
-
-            int i1 = ipart;
-            int i2 = Math.min(i1 + 1, mSize - 1);
-
-            assert i1 >= 0 && i2 >= 0 : "Negatives in the interpolation";
-
-            return MathUtils.lerp(mValues[i1], mValues[i2], weight);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createLutInterpolator(float[] values) {
-        return sManager.addNewDelegate(new LutInterpolator(values));
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java b/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java
deleted file mode 100644
index bb95c4e..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java
+++ /dev/null
@@ -1,65 +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.internal.view.menu;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-
-import android.content.Context;
-import android.view.View;
-
-/**
- * An extension of the {@link MenuItemImpl} to store the view cookie also.
- */
-public class BridgeMenuItemImpl extends MenuItemImpl {
-
-    /**
-     * An object returned by the IDE that helps mapping each View to the corresponding XML tag in
-     * the layout. For Menus, we store this cookie here and attach it to the corresponding view
-     * at the time of rendering.
-     */
-    private Object viewCookie;
-    private BridgeContext mContext;
-
-    /**
-     * Instantiates this menu item.
-     */
-    BridgeMenuItemImpl(MenuBuilder menu, int group, int id, int categoryOrder, int ordering,
-            CharSequence title, int showAsAction) {
-        super(menu, group, id, categoryOrder, ordering, title, showAsAction);
-        Context context = menu.getContext();
-        context = BridgeContext.getBaseContext(context);
-        if (context instanceof BridgeContext) {
-            mContext = ((BridgeContext) context);
-        }
-    }
-
-    public Object getViewCookie() {
-        return viewCookie;
-    }
-
-    public void setViewCookie(Object viewCookie) {
-        // If the menu item has an associated action provider view,
-        // directly set the cookie in the view to cookie map stored in BridgeContext.
-        View actionView = getActionView();
-        if (actionView != null && mContext != null) {
-            mContext.addViewKey(actionView, viewCookie);
-            // We don't need to add the view cookie to the this item now. But there's no harm in
-            // storing it, in case we need it in the future.
-        }
-        this.viewCookie = viewCookie;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilder_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilder_Delegate.java
deleted file mode 100644
index 505fb81..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilder_Delegate.java
+++ /dev/null
@@ -1,38 +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.internal.view.menu;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link MenuBuilder}
- * <p/>
- * Through the layoutlib_create tool, the original  methods of {@code MenuBuilder} have been
- * replaced by calls to methods of the same name in this delegate class.
- */
-public class MenuBuilder_Delegate {
-    /**
-     * The method overrides the instantiation of the {@link MenuItemImpl} with an instance of
-     * {@link BridgeMenuItemImpl} so that view cookies may be stored.
-     */
-    @LayoutlibDelegate
-    /*package*/ static MenuItemImpl createNewMenuItem(MenuBuilder thisMenu, int group, int id,
-            int categoryOrder, int ordering, CharSequence title, int defaultShowAsAction) {
-        return new BridgeMenuItemImpl(thisMenu, group, id, categoryOrder, ordering, title,
-                defaultShowAsAction);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/widget/ActionBarAccessor.java b/tools/layoutlib/bridge/src/com/android/internal/widget/ActionBarAccessor.java
deleted file mode 100644
index 40b6220..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/widget/ActionBarAccessor.java
+++ /dev/null
@@ -1,32 +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.internal.widget;
-
-import android.widget.ActionMenuPresenter;
-
-/**
- * To access non public members of AbsActionBarView
- */
-public class ActionBarAccessor {
-
-    /**
-     * Returns the {@link ActionMenuPresenter} associated with the {@link AbsActionBarView}
-     */
-    public static ActionMenuPresenter getActionMenuPresenter(AbsActionBarView view) {
-        return view.mActionMenuPresenter;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
deleted file mode 100644
index 2e14974..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ /dev/null
@@ -1,737 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.ide.common.rendering.api.Capability;
-import com.android.ide.common.rendering.api.DrawableParams;
-import com.android.ide.common.rendering.api.Features;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.impl.RenderDrawable;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-import com.android.layoutlib.bridge.util.DynamicIdMap;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.create.MethodAdapter;
-import com.android.tools.layoutlib.create.OverrideMethod;
-import com.android.util.Pair;
-
-import android.annotation.NonNull;
-import android.content.res.BridgeAssetManager;
-import android.graphics.Bitmap;
-import android.graphics.FontFamily_Delegate;
-import android.graphics.Typeface;
-import android.graphics.Typeface_Delegate;
-import android.icu.util.ULocale;
-import android.os.Looper;
-import android.os.Looper_Accessor;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-
-import java.io.File;
-import java.lang.ref.SoftReference;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.locks.ReentrantLock;
-
-import libcore.io.MemoryMappedFile_Delegate;
-
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-
-/**
- * Main entry point of the LayoutLib Bridge.
- * <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call
- * {@link #createSession(SessionParams)}
- */
-public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
-
-    private static final String ICU_LOCALE_DIRECTION_RTL = "right-to-left";
-
-    public static class StaticMethodNotImplementedException extends RuntimeException {
-        private static final long serialVersionUID = 1L;
-
-        public StaticMethodNotImplementedException(String msg) {
-            super(msg);
-        }
-    }
-
-    /**
-     * Lock to ensure only one rendering/inflating happens at a time.
-     * This is due to some singleton in the Android framework.
-     */
-    private final static ReentrantLock sLock = new ReentrantLock();
-
-    /**
-     * Maps from id to resource type/name. This is for com.android.internal.R
-     */
-    private final static Map<Integer, Pair<ResourceType, String>> sRMap =
-        new HashMap<Integer, Pair<ResourceType, String>>();
-
-    /**
-     * Same as sRMap except for int[] instead of int resources. This is for android.R only.
-     */
-    private final static Map<IntArray, String> sRArrayMap = new HashMap<IntArray, String>(384);
-    /**
-     * Reverse map compared to sRMap, resource type -> (resource name -> id).
-     * This is for com.android.internal.R.
-     */
-    private final static Map<ResourceType, Map<String, Integer>> sRevRMap =
-        new EnumMap<ResourceType, Map<String,Integer>>(ResourceType.class);
-
-    // framework resources are defined as 0x01XX#### where XX is the resource type (layout,
-    // drawable, etc...). Using FF as the type allows for 255 resource types before we get a
-    // collision which should be fine.
-    private final static int DYNAMIC_ID_SEED_START = 0x01ff0000;
-    private final static DynamicIdMap sDynamicIds = new DynamicIdMap(DYNAMIC_ID_SEED_START);
-
-    private final static Map<Object, Map<String, SoftReference<Bitmap>>> sProjectBitmapCache =
-        new HashMap<Object, Map<String, SoftReference<Bitmap>>>();
-    private final static Map<Object, Map<String, SoftReference<NinePatchChunk>>> sProject9PatchCache =
-        new HashMap<Object, Map<String, SoftReference<NinePatchChunk>>>();
-
-    private final static Map<String, SoftReference<Bitmap>> sFrameworkBitmapCache =
-        new HashMap<String, SoftReference<Bitmap>>();
-    private final static Map<String, SoftReference<NinePatchChunk>> sFramework9PatchCache =
-        new HashMap<String, SoftReference<NinePatchChunk>>();
-
-    private static Map<String, Map<String, Integer>> sEnumValueMap;
-    private static Map<String, String> sPlatformProperties;
-
-    /**
-     * int[] wrapper to use as keys in maps.
-     */
-    private final static class IntArray {
-        private int[] mArray;
-
-        private IntArray() {
-            // do nothing
-        }
-
-        private IntArray(int[] a) {
-            mArray = a;
-        }
-
-        private void set(int[] a) {
-            mArray = a;
-        }
-
-        @Override
-        public int hashCode() {
-            return Arrays.hashCode(mArray);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) return true;
-            if (obj == null) return false;
-            if (getClass() != obj.getClass()) return false;
-
-            IntArray other = (IntArray) obj;
-            return Arrays.equals(mArray, other.mArray);
-        }
-    }
-
-    /** Instance of IntArrayWrapper to be reused in {@link #resolveResourceId(int[])}. */
-    private final static IntArray sIntArrayWrapper = new IntArray();
-
-    /**
-     * A default log than prints to stdout/stderr.
-     */
-    private final static LayoutLog sDefaultLog = new LayoutLog() {
-        @Override
-        public void error(String tag, String message, Object data) {
-            System.err.println(message);
-        }
-
-        @Override
-        public void error(String tag, String message, Throwable throwable, Object data) {
-            System.err.println(message);
-        }
-
-        @Override
-        public void warning(String tag, String message, Object data) {
-            System.out.println(message);
-        }
-    };
-
-    /**
-     * Current log.
-     */
-    private static LayoutLog sCurrentLog = sDefaultLog;
-
-    private static final int LAST_SUPPORTED_FEATURE = Features.THEME_PREVIEW_NAVIGATION_BAR;
-
-    @Override
-    public int getApiLevel() {
-        return com.android.ide.common.rendering.api.Bridge.API_CURRENT;
-    }
-
-    @Override
-    @Deprecated
-    public EnumSet<Capability> getCapabilities() {
-        // The Capability class is deprecated and frozen. All Capabilities enumerated there are
-        // supported by this version of LayoutLibrary. So, it's safe to use EnumSet.allOf()
-        return EnumSet.allOf(Capability.class);
-    }
-
-    @Override
-    public boolean supports(int feature) {
-        return feature <= LAST_SUPPORTED_FEATURE;
-    }
-
-    @Override
-    public boolean init(Map<String,String> platformProperties,
-            File fontLocation,
-            Map<String, Map<String, Integer>> enumValueMap,
-            LayoutLog log) {
-        sPlatformProperties = platformProperties;
-        sEnumValueMap = enumValueMap;
-
-        BridgeAssetManager.initSystem();
-
-        // When DEBUG_LAYOUT is set and is not 0 or false, setup a default listener
-        // on static (native) methods which prints the signature on the console and
-        // throws an exception.
-        // This is useful when testing the rendering in ADT to identify static native
-        // methods that are ignored -- layoutlib_create makes them returns 0/false/null
-        // which is generally OK yet might be a problem, so this is how you'd find out.
-        //
-        // Currently layoutlib_create only overrides static native method.
-        // Static non-natives are not overridden and thus do not get here.
-        final String debug = System.getenv("DEBUG_LAYOUT");
-        if (debug != null && !debug.equals("0") && !debug.equals("false")) {
-
-            OverrideMethod.setDefaultListener(new MethodAdapter() {
-                @Override
-                public void onInvokeV(String signature, boolean isNative, Object caller) {
-                    sDefaultLog.error(null, "Missing Stub: " + signature +
-                            (isNative ? " (native)" : ""), null /*data*/);
-
-                    if (debug.equalsIgnoreCase("throw")) {
-                        // Throwing this exception doesn't seem that useful. It breaks
-                        // the layout editor yet doesn't display anything meaningful to the
-                        // user. Having the error in the console is just as useful. We'll
-                        // throw it only if the environment variable is "throw" or "THROW".
-                        throw new StaticMethodNotImplementedException(signature);
-                    }
-                }
-            });
-        }
-
-        // load the fonts.
-        FontFamily_Delegate.setFontLocation(fontLocation.getAbsolutePath());
-        MemoryMappedFile_Delegate.setDataDir(fontLocation.getAbsoluteFile().getParentFile());
-
-        // now parse com.android.internal.R (and only this one as android.R is a subset of
-        // the internal version), and put the content in the maps.
-        try {
-            Class<?> r = com.android.internal.R.class;
-            // Parse the styleable class first, since it may contribute to attr values.
-            parseStyleable();
-
-            for (Class<?> inner : r.getDeclaredClasses()) {
-                if (inner == com.android.internal.R.styleable.class) {
-                    // Already handled the styleable case. Not skipping attr, as there may be attrs
-                    // that are not referenced from styleables.
-                    continue;
-                }
-                String resTypeName = inner.getSimpleName();
-                ResourceType resType = ResourceType.getEnum(resTypeName);
-                if (resType != null) {
-                    Map<String, Integer> fullMap = null;
-                    switch (resType) {
-                        case ATTR:
-                            fullMap = sRevRMap.get(ResourceType.ATTR);
-                            break;
-                        case STRING:
-                        case STYLE:
-                            // Slightly less than thousand entries in each.
-                            fullMap = new HashMap<String, Integer>(1280);
-                            // no break.
-                        default:
-                            if (fullMap == null) {
-                                fullMap = new HashMap<String, Integer>();
-                            }
-                            sRevRMap.put(resType, fullMap);
-                    }
-
-                    for (Field f : inner.getDeclaredFields()) {
-                        // only process static final fields. Since the final attribute may have
-                        // been altered by layoutlib_create, we only check static
-                        if (!isValidRField(f)) {
-                            continue;
-                        }
-                        Class<?> type = f.getType();
-                        if (type.isArray()) {
-                            // if the object is an int[] we put it in sRArrayMap using an IntArray
-                            // wrapper that properly implements equals and hashcode for the array
-                            // objects, as required by the map contract.
-                            sRArrayMap.put(new IntArray((int[]) f.get(null)), f.getName());
-                        } else {
-                            Integer value = (Integer) f.get(null);
-                            sRMap.put(value, Pair.of(resType, f.getName()));
-                            fullMap.put(f.getName(), value);
-                        }
-                    }
-                }
-            }
-        } catch (Exception throwable) {
-            if (log != null) {
-                log.error(LayoutLog.TAG_BROKEN,
-                        "Failed to load com.android.internal.R from the layout library jar",
-                        throwable, null);
-            }
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Tests if the field is pubic, static and one of int or int[].
-     */
-    private static boolean isValidRField(Field field) {
-        int modifiers = field.getModifiers();
-        boolean isAcceptable = Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers);
-        Class<?> type = field.getType();
-        return isAcceptable && type == int.class ||
-                (type.isArray() && type.getComponentType() == int.class);
-
-    }
-
-    private static void parseStyleable() throws Exception {
-        // R.attr doesn't contain all the needed values. There are too many resources in the
-        // framework for all to be in the R class. Only the ones specified manually in
-        // res/values/symbols.xml are put in R class. Since, we need to create a map of all attr
-        // values, we try and find them from the styleables.
-
-        // There were 1500 elements in this map at M timeframe.
-        Map<String, Integer> revRAttrMap = new HashMap<String, Integer>(2048);
-        sRevRMap.put(ResourceType.ATTR, revRAttrMap);
-        // There were 2000 elements in this map at M timeframe.
-        Map<String, Integer> revRStyleableMap = new HashMap<String, Integer>(3072);
-        sRevRMap.put(ResourceType.STYLEABLE, revRStyleableMap);
-        Class<?> c = com.android.internal.R.styleable.class;
-        Field[] fields = c.getDeclaredFields();
-        // Sort the fields to bring all arrays to the beginning, so that indices into the array are
-        // able to refer back to the arrays (i.e. no forward references).
-        Arrays.sort(fields, new Comparator<Field>() {
-            @Override
-            public int compare(Field o1, Field o2) {
-                if (o1 == o2) {
-                    return 0;
-                }
-                Class<?> t1 = o1.getType();
-                Class<?> t2 = o2.getType();
-                if (t1.isArray() && !t2.isArray()) {
-                    return -1;
-                } else if (t2.isArray() && !t1.isArray()) {
-                    return 1;
-                }
-                return o1.getName().compareTo(o2.getName());
-            }
-        });
-        Map<String, int[]> styleables = new HashMap<String, int[]>();
-        for (Field field : fields) {
-            if (!isValidRField(field)) {
-                // Only consider public static fields that are int or int[].
-                // Don't check the final flag as it may have been modified by layoutlib_create.
-                continue;
-            }
-            String name = field.getName();
-            if (field.getType().isArray()) {
-                int[] styleableValue = (int[]) field.get(null);
-                sRArrayMap.put(new IntArray(styleableValue), name);
-                styleables.put(name, styleableValue);
-                continue;
-            }
-            // Not an array.
-            String arrayName = name;
-            int[] arrayValue = null;
-            int index;
-            while ((index = arrayName.lastIndexOf('_')) >= 0) {
-                // Find the name of the corresponding styleable.
-                // Search in reverse order so that attrs like LinearLayout_Layout_layout_gravity
-                // are mapped to LinearLayout_Layout and not to LinearLayout.
-                arrayName = arrayName.substring(0, index);
-                arrayValue = styleables.get(arrayName);
-                if (arrayValue != null) {
-                    break;
-                }
-            }
-            index = (Integer) field.get(null);
-            if (arrayValue != null) {
-                String attrName = name.substring(arrayName.length() + 1);
-                int attrValue = arrayValue[index];
-                sRMap.put(attrValue, Pair.of(ResourceType.ATTR, attrName));
-                revRAttrMap.put(attrName, attrValue);
-            }
-            sRMap.put(index, Pair.of(ResourceType.STYLEABLE, name));
-            revRStyleableMap.put(name, index);
-        }
-    }
-
-    @Override
-    public boolean dispose() {
-        BridgeAssetManager.clearSystem();
-
-        // dispose of the default typeface.
-        Typeface_Delegate.resetDefaults();
-        Typeface.sDynamicTypefaceCache.evictAll();
-
-        return true;
-    }
-
-    /**
-     * Starts a layout session by inflating and rendering it. The method returns a
-     * {@link RenderSession} on which further actions can be taken.
-     * <p/>
-     * If {@link SessionParams} includes the {@link RenderParamsFlags#FLAG_DO_NOT_RENDER_ON_CREATE},
-     * this method will only inflate the layout but will NOT render it.
-     * @param params the {@link SessionParams} object with all the information necessary to create
-     *           the scene.
-     * @return a new {@link RenderSession} object that contains the result of the layout.
-     * @since 5
-     */
-    @Override
-    public RenderSession createSession(SessionParams params) {
-        try {
-            Result lastResult = SUCCESS.createResult();
-            RenderSessionImpl scene = new RenderSessionImpl(params);
-            try {
-                prepareThread();
-                lastResult = scene.init(params.getTimeout());
-                if (lastResult.isSuccess()) {
-                    lastResult = scene.inflate();
-
-                    boolean doNotRenderOnCreate = Boolean.TRUE.equals(
-                            params.getFlag(RenderParamsFlags.FLAG_DO_NOT_RENDER_ON_CREATE));
-                    if (lastResult.isSuccess() && !doNotRenderOnCreate) {
-                        lastResult = scene.render(true /*freshRender*/);
-                    }
-                }
-            } finally {
-                scene.release();
-                cleanupThread();
-            }
-
-            return new BridgeRenderSession(scene, lastResult);
-        } catch (Throwable t) {
-            // get the real cause of the exception.
-            Throwable t2 = t;
-            while (t2.getCause() != null) {
-                t2 = t.getCause();
-            }
-            return new BridgeRenderSession(null,
-                    ERROR_UNKNOWN.createResult(t2.getMessage(), t));
-        }
-    }
-
-    @Override
-    public Result renderDrawable(DrawableParams params) {
-        try {
-            Result lastResult = SUCCESS.createResult();
-            RenderDrawable action = new RenderDrawable(params);
-            try {
-                prepareThread();
-                lastResult = action.init(params.getTimeout());
-                if (lastResult.isSuccess()) {
-                    lastResult = action.render();
-                }
-            } finally {
-                action.release();
-                cleanupThread();
-            }
-
-            return lastResult;
-        } catch (Throwable t) {
-            // get the real cause of the exception.
-            Throwable t2 = t;
-            while (t2.getCause() != null) {
-                t2 = t.getCause();
-            }
-            return ERROR_UNKNOWN.createResult(t2.getMessage(), t);
-        }
-    }
-
-    @Override
-    public void clearCaches(Object projectKey) {
-        if (projectKey != null) {
-            sProjectBitmapCache.remove(projectKey);
-            sProject9PatchCache.remove(projectKey);
-        }
-    }
-
-    @Override
-    public Result getViewParent(Object viewObject) {
-        if (viewObject instanceof View) {
-            return Status.SUCCESS.createResult(((View)viewObject).getParent());
-        }
-
-        throw new IllegalArgumentException("viewObject is not a View");
-    }
-
-    @Override
-    public Result getViewIndex(Object viewObject) {
-        if (viewObject instanceof View) {
-            View view = (View) viewObject;
-            ViewParent parentView = view.getParent();
-
-            if (parentView instanceof ViewGroup) {
-                Status.SUCCESS.createResult(((ViewGroup) parentView).indexOfChild(view));
-            }
-
-            return Status.SUCCESS.createResult();
-        }
-
-        throw new IllegalArgumentException("viewObject is not a View");
-    }
-
-    @Override
-    public boolean isRtl(String locale) {
-        return isLocaleRtl(locale);
-    }
-
-    public static boolean isLocaleRtl(String locale) {
-        if (locale == null) {
-            locale = "";
-        }
-        ULocale uLocale = new ULocale(locale);
-        return uLocale.getCharacterOrientation().equals(ICU_LOCALE_DIRECTION_RTL);
-    }
-
-    /**
-     * Returns the lock for the bridge
-     */
-    public static ReentrantLock getLock() {
-        return sLock;
-    }
-
-    /**
-     * Prepares the current thread for rendering.
-     *
-     * Note that while this can be called several time, the first call to {@link #cleanupThread()}
-     * will do the clean-up, and make the thread unable to do further scene actions.
-     */
-    public synchronized static void prepareThread() {
-        // we need to make sure the Looper has been initialized for this thread.
-        // this is required for View that creates Handler objects.
-        if (Looper.myLooper() == null) {
-            Looper.prepareMainLooper();
-        }
-    }
-
-    /**
-     * Cleans up thread-specific data. After this, the thread cannot be used for scene actions.
-     * <p>
-     * Note that it doesn't matter how many times {@link #prepareThread()} was called, a single
-     * call to this will prevent the thread from doing further scene actions
-     */
-    public synchronized static void cleanupThread() {
-        // clean up the looper
-        Looper_Accessor.cleanupThread();
-    }
-
-    public static LayoutLog getLog() {
-        return sCurrentLog;
-    }
-
-    public static void setLog(LayoutLog log) {
-        // check only the thread currently owning the lock can do this.
-        if (!sLock.isHeldByCurrentThread()) {
-            throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
-        }
-
-        if (log != null) {
-            sCurrentLog = log;
-        } else {
-            sCurrentLog = sDefaultLog;
-        }
-    }
-
-    /**
-     * Returns details of a framework resource from its integer value.
-     * @param value the integer value
-     * @return a Pair containing the resource type and name, or null if the id
-     *     does not match any resource.
-     */
-    public static Pair<ResourceType, String> resolveResourceId(int value) {
-        Pair<ResourceType, String> pair = sRMap.get(value);
-        if (pair == null) {
-            pair = sDynamicIds.resolveId(value);
-            if (pair == null) {
-                //System.out.println(String.format("Missing id: %1$08X (%1$d)", value));
-            }
-        }
-        return pair;
-    }
-
-    /**
-     * Returns the name of a framework resource whose value is an int array.
-     */
-    public static String resolveResourceId(int[] array) {
-        sIntArrayWrapper.set(array);
-        return sRArrayMap.get(sIntArrayWrapper);
-    }
-
-    /**
-     * Returns the integer id of a framework resource, from a given resource type and resource name.
-     * <p/>
-     * If no resource is found, it creates a dynamic id for the resource.
-     *
-     * @param type the type of the resource
-     * @param name the name of the resource.
-     *
-     * @return an {@link Integer} containing the resource id.
-     */
-    @NonNull
-    public static Integer getResourceId(ResourceType type, String name) {
-        Map<String, Integer> map = sRevRMap.get(type);
-        Integer value = null;
-        if (map != null) {
-            value = map.get(name);
-        }
-
-        return value == null ? sDynamicIds.getId(type, name) : value;
-
-    }
-
-    /**
-     * Returns the list of possible enums for a given attribute name.
-     */
-    public static Map<String, Integer> getEnumValues(String attributeName) {
-        if (sEnumValueMap != null) {
-            return sEnumValueMap.get(attributeName);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the platform build properties.
-     */
-    public static Map<String, String> getPlatformProperties() {
-        return sPlatformProperties;
-    }
-
-    /**
-     * Returns the bitmap for a specific path, from a specific project cache, or from the
-     * framework cache.
-     * @param value the path of the bitmap
-     * @param projectKey the key of the project, or null to query the framework cache.
-     * @return the cached Bitmap or null if not found.
-     */
-    public static Bitmap getCachedBitmap(String value, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
-            if (map != null) {
-                SoftReference<Bitmap> ref = map.get(value);
-                if (ref != null) {
-                    return ref.get();
-                }
-            }
-        } else {
-            SoftReference<Bitmap> ref = sFrameworkBitmapCache.get(value);
-            if (ref != null) {
-                return ref.get();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Sets a bitmap in a project cache or in the framework cache.
-     * @param value the path of the bitmap
-     * @param bmp the Bitmap object
-     * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
-     */
-    public static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
-
-            if (map == null) {
-                map = new HashMap<String, SoftReference<Bitmap>>();
-                sProjectBitmapCache.put(projectKey, map);
-            }
-
-            map.put(value, new SoftReference<Bitmap>(bmp));
-        } else {
-            sFrameworkBitmapCache.put(value, new SoftReference<Bitmap>(bmp));
-        }
-    }
-
-    /**
-     * Returns the 9 patch chunk for a specific path, from a specific project cache, or from the
-     * framework cache.
-     * @param value the path of the 9 patch
-     * @param projectKey the key of the project, or null to query the framework cache.
-     * @return the cached 9 patch or null if not found.
-     */
-    public static NinePatchChunk getCached9Patch(String value, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);
-
-            if (map != null) {
-                SoftReference<NinePatchChunk> ref = map.get(value);
-                if (ref != null) {
-                    return ref.get();
-                }
-            }
-        } else {
-            SoftReference<NinePatchChunk> ref = sFramework9PatchCache.get(value);
-            if (ref != null) {
-                return ref.get();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Sets a 9 patch chunk in a project cache or in the framework cache.
-     * @param value the path of the 9 patch
-     * @param ninePatch the 9 patch object
-     * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
-     */
-    public static void setCached9Patch(String value, NinePatchChunk ninePatch, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);
-
-            if (map == null) {
-                map = new HashMap<String, SoftReference<NinePatchChunk>>();
-                sProject9PatchCache.put(projectKey, map);
-            }
-
-            map.put(value, new SoftReference<NinePatchChunk>(ninePatch));
-        } else {
-            sFramework9PatchCache.put(value, new SoftReference<NinePatchChunk>(ninePatch));
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
deleted file mode 100644
index 6228766..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-/**
- * Constant definition class.<br>
- * <br>
- * Most constants have a prefix defining the content.
- * <ul>
- * <li><code>WS_</code> Workspace path constant. Those are absolute paths,
- * from the project root.</li>
- * <li><code>OS_</code> OS path constant. These paths are different depending on the platform.</li>
- * <li><code>FN_</code> File name constant.</li>
- * <li><code>FD_</code> Folder name constant.</li>
- * <li><code>EXT_</code> File extension constant. This does NOT include a dot.</li>
- * <li><code>DOT_</code> File extension constant. This start with a dot.</li>
- * <li><code>RE_</code> Regexp constant.</li>
- * <li><code>NS_</code> Namespace constant.</li>
- * <li><code>CLASS_</code> Fully qualified class name.</li>
- * </ul>
- *
- */
-public class BridgeConstants {
-
-    /** Namespace for the resource XML */
-    public final static String NS_RESOURCES = "http://schemas.android.com/apk/res/android";
-
-    /** App auto namespace */
-    public final static String NS_APP_RES_AUTO = "http://schemas.android.com/apk/res-auto";
-    public final static String NS_TOOLS_URI = "http://schemas.android.com/tools";
-
-    public final static String R = "com.android.internal.R";
-
-
-    public final static String MATCH_PARENT = "match_parent";
-    public final static String FILL_PARENT = "fill_parent";
-    public final static String WRAP_CONTENT = "wrap_content";
-
-    // Should be kept in sync with LayoutMetadata.KEY_LV_ITEM in tools/adt/idea
-    /** Attribute in the tools namespace used to specify layout manager for RecyclerView. */
-    @SuppressWarnings("SpellCheckingInspection")
-    public static final String ATTR_LIST_ITEM = "listitem";
-    public static final String ATTR_OPEN_DRAWER = "openDrawer";
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
deleted file mode 100644
index fdf6d63..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.RenderParams;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-import com.android.tools.layoutlib.java.System_Delegate;
-import com.android.util.PropertiesMap;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.awt.image.BufferedImage;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * An implementation of {@link RenderSession}.
- *
- * This is a pretty basic class that does almost nothing. All of the work is done in
- * {@link RenderSessionImpl}.
- *
- */
-public class BridgeRenderSession extends RenderSession {
-
-    @Nullable
-    private final RenderSessionImpl mSession;
-    @NonNull
-    private Result mLastResult;
-
-    @Override
-    public Result getResult() {
-        return mLastResult;
-    }
-
-    @Override
-    public BufferedImage getImage() {
-        return mSession != null ? mSession.getImage() :
-                new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
-    }
-
-    @Override
-    public boolean isAlphaChannelImage() {
-        return mSession != null && mSession.isAlphaChannelImage();
-    }
-
-    @Override
-    public List<ViewInfo> getRootViews() {
-        return mSession != null ? mSession.getViewInfos() : Collections.emptyList();
-    }
-
-    @Override
-    public List<ViewInfo> getSystemRootViews() {
-        return mSession != null ? mSession.getSystemViewInfos() : Collections.emptyList();
-    }
-
-    @Override
-    public Map<Object, PropertiesMap> getDefaultProperties() {
-        return mSession != null ? mSession.getDefaultProperties() : Collections.emptyMap();
-    }
-
-    @Override
-    public Result measure(long timeout) {
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(timeout);
-                if (mLastResult.isSuccess()) {
-                    mSession.invalidateRenderingSize();
-                    mLastResult = mSession.measure();
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result render(long timeout, boolean forceMeasure) {
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(timeout);
-                if (mLastResult.isSuccess()) {
-                    if (forceMeasure) {
-                        mSession.invalidateRenderingSize();
-                    }
-                    mLastResult = mSession.render(false /*freshRender*/);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result animate(Object targetObject, String animationName,
-            boolean isFrameworkAnimation, IAnimationListener listener) {
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-                if (mLastResult.isSuccess()) {
-                    mLastResult = mSession.animate(targetObject, animationName, isFrameworkAnimation,
-                            listener);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result insertChild(Object parentView, ILayoutPullParser childXml, int index,
-            IAnimationListener listener) {
-        if (!(parentView instanceof ViewGroup)) {
-            throw new IllegalArgumentException("parentView is not a ViewGroup");
-        }
-
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-                if (mLastResult.isSuccess()) {
-                    mLastResult =
-                            mSession.insertChild((ViewGroup) parentView, childXml, index, listener);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-
-    @Override
-    public Result moveChild(Object parentView, Object childView, int index,
-            Map<String, String> layoutParams, IAnimationListener listener) {
-        if (!(parentView instanceof ViewGroup)) {
-            throw new IllegalArgumentException("parentView is not a ViewGroup");
-        }
-        if (!(childView instanceof View)) {
-            throw new IllegalArgumentException("childView is not a View");
-        }
-
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-                if (mLastResult.isSuccess()) {
-                    mLastResult = mSession.moveChild((ViewGroup) parentView, (View) childView, index,
-                            layoutParams, listener);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result removeChild(Object childView, IAnimationListener listener) {
-        if (!(childView instanceof View)) {
-            throw new IllegalArgumentException("childView is not a View");
-        }
-
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-                if (mLastResult.isSuccess()) {
-                    mLastResult = mSession.removeChild((View) childView, listener);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public void setSystemTimeNanos(long nanos) {
-        System_Delegate.setNanosTime(nanos);
-    }
-
-    @Override
-    public void setSystemBootTimeNanos(long nanos) {
-        System_Delegate.setBootTimeNanos(nanos);
-    }
-
-    @Override
-    public void setElapsedFrameTimeNanos(long nanos) {
-        if (mSession != null) {
-            mSession.setElapsedFrameTimeNanos(nanos);
-        }
-    }
-
-    @Override
-    public void dispose() {
-        if (mSession != null) {
-            mSession.dispose();
-        }
-    }
-
-    /*package*/ BridgeRenderSession(@Nullable RenderSessionImpl scene, @NonNull Result lastResult) {
-        mSession = scene;
-        if (scene != null) {
-            mSession.setScene(this);
-        }
-        mLastResult = lastResult;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
deleted file mode 100644
index e10f20d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-
-/**
- * Base class for mocked views.
- * <p/>
- * FrameLayout with a single TextView. Doesn't allow adding any other views to itself.
- */
-public class MockView extends FrameLayout {
-
-    private final TextView mView;
-
-    public MockView(Context context) {
-        this(context, null);
-    }
-
-    public MockView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public MockView(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public MockView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        mView = new TextView(context, attrs);
-        mView.setTextColor(0xFF000000);
-        setGravity(Gravity.CENTER);
-        setText(getClass().getSimpleName());
-        addView(mView);
-        setBackgroundColor(0xFF7F7F7F);
-    }
-
-    // Only allow adding one TextView.
-    @Override
-    public void addView(View child) {
-        if (child == mView) {
-            super.addView(child);
-        }
-    }
-
-    @Override
-    public void addView(View child, int index) {
-        if (child == mView) {
-            super.addView(child, index);
-        }
-    }
-
-    @Override
-    public void addView(View child, int width, int height) {
-        if (child == mView) {
-            super.addView(child, width, height);
-        }
-    }
-
-    @Override
-    public void addView(View child, ViewGroup.LayoutParams params) {
-        if (child == mView) {
-            super.addView(child, params);
-        }
-    }
-
-    @Override
-    public void addView(View child, int index, ViewGroup.LayoutParams params) {
-        if (child == mView) {
-            super.addView(child, index, params);
-        }
-    }
-
-    // The following methods are called by the IDE via reflection, and should be considered part
-    // of the API.
-    // Historically, MockView used to be a textView and had these methods. Now, we simply delegate
-    // them to the contained textView.
-
-    public void setText(CharSequence text) {
-        mView.setText(text);
-    }
-
-    @SuppressWarnings("WeakerAccess") // This method is used from Studio
-    public void setGravity(int gravity) {
-        mView.setGravity(gravity);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
deleted file mode 100644
index faaf105..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
+++ /dev/null
@@ -1,72 +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.layoutlib.bridge.android;
-
-import com.android.layoutlib.bridge.impl.RenderAction;
-
-import android.icu.util.ULocale;
-
-import java.util.Locale;
-
-/**
- * This class provides an alternate implementation for {@code java.util.Locale#toLanguageTag}
- * which is only available after Java 6.
- *
- * The create tool re-writes references to the above mentioned method to this one. Hence it's
- * imperative that this class is not deleted unless the create tool is modified.
- */
-@SuppressWarnings("UnusedDeclaration")
-public class AndroidLocale {
-
-    public static String toLanguageTag(Locale locale)  {
-        return ULocale.forLocale(locale).toLanguageTag();
-    }
-
-    public static String adjustLanguageCode(String languageCode) {
-        String adjusted = languageCode.toLowerCase(Locale.US);
-        // Map new language codes to the obsolete language
-        // codes so the correct resource bundles will be used.
-        if (languageCode.equals("he")) {
-            adjusted = "iw";
-        } else if (languageCode.equals("id")) {
-            adjusted = "in";
-        } else if (languageCode.equals("yi")) {
-            adjusted = "ji";
-        }
-
-        return adjusted;
-    }
-
-    public static Locale forLanguageTag(String tag) {
-        return ULocale.forLanguageTag(tag).toLocale();
-    }
-
-    public static String getScript(Locale locale) {
-        return ULocale.forLocale(locale).getScript();
-    }
-
-    public static Locale getDefault() {
-        BridgeContext context = RenderAction.getCurrentContext();
-        if (context != null) {
-            Locale locale = context.getConfiguration().locale;
-            if (locale != null) {
-                return locale;
-            }
-        }
-        return Locale.getDefault();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
deleted file mode 100644
index c827f17..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderResult;
-import android.content.ContentValues;
-import android.content.IContentProvider;
-import android.content.OperationApplicationException;
-import android.content.res.AssetFileDescriptor;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.ICancellationSignal;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-
-/**
- * Mock implementation of {@link IContentProvider}.
- *
- * TODO: never return null when the method is not supposed to. Return fake data instead.
- */
-public final class BridgeContentProvider implements IContentProvider {
-    @Override
-    public ContentProviderResult[] applyBatch(String callingPackage,
-            ArrayList<ContentProviderOperation> arg0)
-            throws RemoteException, OperationApplicationException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int bulkInsert(String callingPackage, Uri arg0, ContentValues[] arg1)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public Bundle call(String callingPackage, String arg0, String arg1, Bundle arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int delete(String callingPackage, Uri arg0, String arg1, String[] arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public String getType(Uri arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Uri insert(String callingPackage, Uri arg0, ContentValues arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public AssetFileDescriptor openAssetFile(
-            String callingPackage, Uri arg0, String arg1, ICancellationSignal signal)
-            throws RemoteException, FileNotFoundException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ParcelFileDescriptor openFile(
-            String callingPackage, Uri arg0, String arg1, ICancellationSignal signal, IBinder token)
-            throws RemoteException, FileNotFoundException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Cursor query(String callingPackage, Uri arg0, String[] arg1,
-            Bundle arg3, ICancellationSignal arg4) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int update(String callingPackage, Uri arg0, ContentValues arg1, String arg2,
-            String[] arg3) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String[] getStreamTypes(Uri arg0, String arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public AssetFileDescriptor openTypedAssetFile(String callingPackage, Uri arg0, String arg1,
-            Bundle arg2, ICancellationSignal signal) throws RemoteException, FileNotFoundException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ICancellationSignal createCancellationSignal() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-
-    @Override
-    public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException {
-        return null;
-    }
-
-    @Override
-    public Uri uncanonicalize(String callingPkg, Uri uri) throws RemoteException {
-        return null;
-    }
-
-    @Override
-    public boolean refresh(String callingPkg, Uri url, Bundle args,
-                    ICancellationSignal cancellationSignal) throws RemoteException {
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
deleted file mode 100644
index 8d259d7..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
+++ /dev/null
@@ -1,120 +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.layoutlib.bridge.android;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.IContentProvider;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Bundle;
-
-/**
- * A mock content resolver for the LayoutLib Bridge.
- * <p/>
- * It won't serve any actual data but it's good enough for all
- * the widgets which expect to have a content resolver available via
- * {@link BridgeContext#getContentResolver()}.
- */
-public class BridgeContentResolver extends ContentResolver {
-
-    private BridgeContentProvider mProvider = null;
-
-    public BridgeContentResolver(Context context) {
-        super(context);
-    }
-
-    @Override
-    public IContentProvider acquireProvider(Context c, String name) {
-        if (mProvider == null) {
-            mProvider = new BridgeContentProvider();
-        }
-
-        return mProvider;
-    }
-
-    @Override
-    public IContentProvider acquireExistingProvider(Context c, String name) {
-        if (mProvider == null) {
-            mProvider = new BridgeContentProvider();
-        }
-
-        return mProvider;
-    }
-
-    @Override
-    public boolean releaseProvider(IContentProvider icp) {
-        // ignore
-        return false;
-    }
-
-    @Override
-    protected IContentProvider acquireUnstableProvider(Context c, String name) {
-        return acquireProvider(c, name);
-    }
-
-    @Override
-    public boolean releaseUnstableProvider(IContentProvider icp) {
-        return releaseProvider(icp);
-    }
-
-    /** @hide */
-    @Override
-    public void unstableProviderDied(IContentProvider icp) {
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void registerContentObserver(Uri uri, boolean notifyForDescendents,
-            ContentObserver observer) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void unregisterContentObserver(ContentObserver observer) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void startSync(Uri uri, Bundle extras) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void cancelSync(Uri uri) {
-        // pass
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
deleted file mode 100644
index 1fc5d72..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ /dev/null
@@ -1,2064 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.SdkConstants;
-import com.android.ide.common.rendering.api.AssetRepository;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.view.WindowManagerImpl;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.impl.Stack;
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-import com.android.util.PropertiesMap;
-import com.android.util.PropertiesMap.Property;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Notification;
-import android.app.SystemServiceRegistry_Accessor;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.AssetManager;
-import android.content.res.BridgeAssetManager;
-import android.content.res.BridgeTypedArray;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.Resources.Theme;
-import android.content.res.Resources_Delegate;
-import android.database.DatabaseErrorHandler;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.drawable.Drawable;
-import android.hardware.display.DisplayManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Looper;
-import android.os.Parcel;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.os.ShellCallback;
-import android.os.UserHandle;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.BridgeInflater;
-import android.view.Display;
-import android.view.DisplayAdjustments;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityManager;
-import android.view.textservice.TextServicesManager;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-
-import static android.os._Original_Build.VERSION_CODES.JELLY_BEAN_MR1;
-import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE;
-
-/**
- * Custom implementation of Context/Activity to handle non compiled resources.
- */
-@SuppressWarnings("deprecation")  // For use of Pair.
-public class BridgeContext extends Context {
-    private static final String PREFIX_THEME_APPCOMPAT = "Theme.AppCompat";
-
-    private static final Map<String, ResourceValue> FRAMEWORK_PATCHED_VALUES = new HashMap<>(2);
-    private static final Map<String, ResourceValue> FRAMEWORK_REPLACE_VALUES = new HashMap<>(3);
-
-    static {
-        FRAMEWORK_PATCHED_VALUES.put("animateFirstView", new ResourceValue(
-                ResourceType.BOOL, "animateFirstView", "false", false));
-        FRAMEWORK_PATCHED_VALUES.put("animateLayoutChanges",
-                new ResourceValue(ResourceType.BOOL, "animateLayoutChanges", "false", false));
-
-
-        FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionItemLayout",
-                new ResourceValue(ResourceType.LAYOUT, "textEditSuggestionItemLayout",
-                        "text_edit_suggestion_item", true));
-        FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionContainerLayout",
-                new ResourceValue(ResourceType.LAYOUT, "textEditSuggestionContainerLayout",
-                        "text_edit_suggestion_container", true));
-        FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionHighlightStyle",
-                new ResourceValue(ResourceType.STYLE, "textEditSuggestionHighlightStyle",
-                        "TextAppearance.Holo.SuggestionHighlight", true));
-
-    }
-
-    /** The map adds cookies to each view so that IDE can link xml tags to views. */
-    private final HashMap<View, Object> mViewKeyMap = new HashMap<>();
-    /**
-     * In some cases, when inflating an xml, some objects are created. Then later, the objects are
-     * converted to views. This map stores the mapping from objects to cookies which can then be
-     * used to populate the mViewKeyMap.
-     */
-    private final HashMap<Object, Object> mViewKeyHelpMap = new HashMap<>();
-    private final BridgeAssetManager mAssets;
-    private Resources mSystemResources;
-    private final Object mProjectKey;
-    private final DisplayMetrics mMetrics;
-    private final RenderResources mRenderResources;
-    private final Configuration mConfig;
-    private final ApplicationInfo mApplicationInfo;
-    private final LayoutlibCallback mLayoutlibCallback;
-    private final WindowManager mWindowManager;
-    private final DisplayManager mDisplayManager;
-    private final HashMap<View, Integer> mScrollYPos = new HashMap<>();
-    private final HashMap<View, Integer> mScrollXPos = new HashMap<>();
-
-    private Resources.Theme mTheme;
-
-    private final Map<Object, PropertiesMap> mDefaultPropMaps = new IdentityHashMap<>();
-
-    // maps for dynamically generated id representing style objects (StyleResourceValue)
-    @Nullable
-    private Map<Integer, StyleResourceValue> mDynamicIdToStyleMap;
-    private Map<StyleResourceValue, Integer> mStyleToDynamicIdMap;
-    private int mDynamicIdGenerator = 0x02030000; // Base id for R.style in custom namespace
-
-    // cache for TypedArray generated from StyleResourceValue object
-    private TypedArrayCache mTypedArrayCache;
-    private BridgeInflater mBridgeInflater;
-
-    private BridgeContentResolver mContentResolver;
-
-    private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<>();
-    private SharedPreferences mSharedPreferences;
-    private ClassLoader mClassLoader;
-    private IBinder mBinder;
-    private PackageManager mPackageManager;
-    private Boolean mIsThemeAppCompat;
-
-    /**
-     * Some applications that target both pre API 17 and post API 17, set the newer attrs to
-     * reference the older ones. For example, android:paddingStart will resolve to
-     * android:paddingLeft. This way the apps need to only define paddingLeft at any other place.
-     * This a map from value to attribute name. Warning for missing references shouldn't be logged
-     * if value and attr name pair is the same as an entry in this map.
-     */
-    private static Map<String, String> RTL_ATTRS = new HashMap<>(10);
-
-    static {
-        RTL_ATTRS.put("?android:attr/paddingLeft", "paddingStart");
-        RTL_ATTRS.put("?android:attr/paddingRight", "paddingEnd");
-        RTL_ATTRS.put("?android:attr/layout_marginLeft", "layout_marginStart");
-        RTL_ATTRS.put("?android:attr/layout_marginRight", "layout_marginEnd");
-        RTL_ATTRS.put("?android:attr/layout_toLeftOf", "layout_toStartOf");
-        RTL_ATTRS.put("?android:attr/layout_toRightOf", "layout_toEndOf");
-        RTL_ATTRS.put("?android:attr/layout_alignParentLeft", "layout_alignParentStart");
-        RTL_ATTRS.put("?android:attr/layout_alignParentRight", "layout_alignParentEnd");
-        RTL_ATTRS.put("?android:attr/drawableLeft", "drawableStart");
-        RTL_ATTRS.put("?android:attr/drawableRight", "drawableEnd");
-    }
-
-    /**
-     * @param projectKey An Object identifying the project. This is used for the cache mechanism.
-     * @param metrics the {@link DisplayMetrics}.
-     * @param renderResources the configured resources (both framework and projects) for this
-     * render.
-     * @param config the Configuration object for this render.
-     * @param targetSdkVersion the targetSdkVersion of the application.
-     */
-    public BridgeContext(Object projectKey, DisplayMetrics metrics,
-            RenderResources renderResources,
-            AssetRepository assets,
-            LayoutlibCallback layoutlibCallback,
-            Configuration config,
-            int targetSdkVersion,
-            boolean hasRtlSupport) {
-        mProjectKey = projectKey;
-        mMetrics = metrics;
-        mLayoutlibCallback = layoutlibCallback;
-
-        mRenderResources = renderResources;
-        mConfig = config;
-        AssetManager systemAssetManager = AssetManager.getSystem();
-        if (systemAssetManager instanceof BridgeAssetManager) {
-            mAssets = (BridgeAssetManager) systemAssetManager;
-        } else {
-            throw new AssertionError("Creating BridgeContext without initializing Bridge");
-        }
-        mAssets.setAssetRepository(assets);
-
-        mApplicationInfo = new ApplicationInfo();
-        mApplicationInfo.targetSdkVersion = targetSdkVersion;
-        if (hasRtlSupport) {
-            mApplicationInfo.flags = mApplicationInfo.flags | ApplicationInfo.FLAG_SUPPORTS_RTL;
-        }
-
-        mWindowManager = new WindowManagerImpl(mMetrics);
-        mDisplayManager = new DisplayManager(this);
-    }
-
-    /**
-     * Initializes the {@link Resources} singleton to be linked to this {@link Context}, its
-     * {@link DisplayMetrics}, {@link Configuration}, and {@link LayoutlibCallback}.
-     *
-     * @see #disposeResources()
-     */
-    public void initResources() {
-        AssetManager assetManager = AssetManager.getSystem();
-
-        mSystemResources = Resources_Delegate.initSystem(
-                this,
-                assetManager,
-                mMetrics,
-                mConfig,
-                mLayoutlibCallback);
-        mTheme = mSystemResources.newTheme();
-    }
-
-    /**
-     * Disposes the {@link Resources} singleton.
-     */
-    public void disposeResources() {
-        Resources_Delegate.disposeSystem();
-    }
-
-    public void setBridgeInflater(BridgeInflater inflater) {
-        mBridgeInflater = inflater;
-    }
-
-    public void addViewKey(View view, Object viewKey) {
-        mViewKeyMap.put(view, viewKey);
-    }
-
-    public Object getViewKey(View view) {
-        return mViewKeyMap.get(view);
-    }
-
-    public void addCookie(Object o, Object cookie) {
-        mViewKeyHelpMap.put(o, cookie);
-    }
-
-    public Object getCookie(Object o) {
-        return mViewKeyHelpMap.get(o);
-    }
-
-    public Object getProjectKey() {
-        return mProjectKey;
-    }
-
-    public DisplayMetrics getMetrics() {
-        return mMetrics;
-    }
-
-    public LayoutlibCallback getLayoutlibCallback() {
-        return mLayoutlibCallback;
-    }
-
-    public RenderResources getRenderResources() {
-        return mRenderResources;
-    }
-
-    public Map<Object, PropertiesMap> getDefaultProperties() {
-        return mDefaultPropMaps;
-    }
-
-    public Configuration getConfiguration() {
-        return mConfig;
-    }
-
-    /**
-     * Adds a parser to the stack.
-     * @param parser the parser to add.
-     */
-    public void pushParser(BridgeXmlBlockParser parser) {
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("PUSH " + parser.getParser().toString());
-        }
-        mParserStack.push(parser);
-    }
-
-    /**
-     * Removes the parser at the top of the stack
-     */
-    public void popParser() {
-        BridgeXmlBlockParser parser = mParserStack.pop();
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("POPD " + parser.getParser().toString());
-        }
-    }
-
-    /**
-     * Returns the current parser at the top the of the stack.
-     * @return a parser or null.
-     */
-    private BridgeXmlBlockParser getCurrentParser() {
-        return mParserStack.peek();
-    }
-
-    /**
-     * Returns the previous parser.
-     * @return a parser or null if there isn't any previous parser
-     */
-    public BridgeXmlBlockParser getPreviousParser() {
-        if (mParserStack.size() < 2) {
-            return null;
-        }
-        return mParserStack.get(mParserStack.size() - 2);
-    }
-
-    public boolean resolveThemeAttribute(int resId, TypedValue outValue, boolean resolveRefs) {
-        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resId);
-        boolean isFrameworkRes = true;
-        if (resourceInfo == null) {
-            resourceInfo = mLayoutlibCallback.resolveResourceId(resId);
-            isFrameworkRes = false;
-        }
-
-        if (resourceInfo == null) {
-            return false;
-        }
-
-        ResourceValue value = mRenderResources.findItemInTheme(resourceInfo.getSecond(),
-                isFrameworkRes);
-        if (resolveRefs) {
-            value = mRenderResources.resolveResValue(value);
-        }
-
-        if (value == null) {
-            // unable to find the attribute.
-            return false;
-        }
-
-        // check if this is a style resource
-        if (value instanceof StyleResourceValue) {
-            // get the id that will represent this style.
-            outValue.resourceId = getDynamicIdByStyle((StyleResourceValue) value);
-            return true;
-        }
-
-        String stringValue = value.getValue();
-        if (!stringValue.isEmpty()) {
-            if (stringValue.charAt(0) == '#') {
-                outValue.type = TypedValue.TYPE_INT_COLOR_ARGB8;
-                outValue.data = Color.parseColor(value.getValue());
-            }
-            else if (stringValue.charAt(0) == '@') {
-                outValue.type = TypedValue.TYPE_REFERENCE;
-            }
-
-        }
-
-        int a;
-        // if this is a framework value.
-        if (value.isFramework()) {
-            // look for idName in the android R classes.
-            // use 0 a default res value as it's not a valid id value.
-            a = getFrameworkResourceValue(value.getResourceType(), value.getName(), 0 /*defValue*/);
-        } else {
-            // look for idName in the project R class.
-            // use 0 a default res value as it's not a valid id value.
-            a = getProjectResourceValue(value.getResourceType(), value.getName(), 0 /*defValue*/);
-        }
-
-        if (a != 0) {
-            outValue.resourceId = a;
-            return true;
-        }
-
-        // If the value is not a valid reference, fallback to pass the value as a string.
-        outValue.string = stringValue;
-        return true;
-    }
-
-
-    public ResourceReference resolveId(int id) {
-        // first get the String related to this id in the framework
-        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
-
-        if (resourceInfo != null) {
-            return new ResourceReference(resourceInfo.getSecond(), true);
-        }
-
-        // didn't find a match in the framework? look in the project.
-        if (mLayoutlibCallback != null) {
-            resourceInfo = mLayoutlibCallback.resolveResourceId(id);
-
-            if (resourceInfo != null) {
-                return new ResourceReference(resourceInfo.getSecond(), false);
-            }
-        }
-
-        // The base value for R.style is 0x01030000 and the custom style is 0x02030000.
-        // So, if the second byte is 03, it's probably a style.
-        if ((id >> 16 & 0xFF) == 0x03) {
-            return getStyleByDynamicId(id);
-        }
-        return null;
-    }
-
-    public Pair<View, Boolean> inflateView(ResourceReference resource, ViewGroup parent,
-            @SuppressWarnings("SameParameterValue") boolean attachToRoot,
-            boolean skipCallbackParser) {
-        boolean isPlatformLayout = resource.isFramework();
-
-        if (!isPlatformLayout && !skipCallbackParser) {
-            // check if the project callback can provide us with a custom parser.
-            ILayoutPullParser parser = getParser(resource);
-
-            if (parser != null) {
-                BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(parser,
-                        this, resource.isFramework());
-                try {
-                    pushParser(blockParser);
-                    return Pair.of(
-                            mBridgeInflater.inflate(blockParser, parent, attachToRoot),
-                            Boolean.TRUE);
-                } finally {
-                    popParser();
-                }
-            }
-        }
-
-        ResourceValue resValue;
-        if (resource instanceof ResourceValue) {
-            resValue = (ResourceValue) resource;
-        } else {
-            if (isPlatformLayout) {
-                resValue = mRenderResources.getFrameworkResource(ResourceType.LAYOUT,
-                        resource.getName());
-            } else {
-                resValue = mRenderResources.getProjectResource(ResourceType.LAYOUT,
-                        resource.getName());
-            }
-        }
-
-        if (resValue != null) {
-
-            File xml = new File(resValue.getValue());
-            if (xml.isFile()) {
-                // we need to create a pull parser around the layout XML file, and then
-                // give that to our XmlBlockParser
-                try {
-                    XmlPullParser parser = ParserFactory.create(xml, true);
-
-                    // set the resource ref to have correct view cookies
-                    mBridgeInflater.setResourceReference(resource);
-
-                    BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(parser,
-                            this, resource.isFramework());
-                    try {
-                        pushParser(blockParser);
-                        return Pair.of(
-                                mBridgeInflater.inflate(blockParser, parent, attachToRoot),
-                                Boolean.FALSE);
-                    } finally {
-                        popParser();
-                    }
-                } catch (XmlPullParserException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                            "Failed to configure parser for " + xml, e, null /*data*/);
-                    // we'll return null below.
-                } catch (FileNotFoundException e) {
-                    // this shouldn't happen since we check above.
-                } finally {
-                    mBridgeInflater.setResourceReference(null);
-                }
-            } else {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        String.format("File %s is missing!", xml), null);
-            }
-        } else {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    String.format("Layout %s%s does not exist.", isPlatformLayout ? "android:" : "",
-                            resource.getName()), null);
-        }
-
-        return Pair.of(null, Boolean.FALSE);
-    }
-
-    /**
-     * Returns whether the current selected theme is based on AppCompat
-     */
-    public boolean isAppCompatTheme() {
-        // If a cached value exists, return it.
-        if (mIsThemeAppCompat != null) {
-            return mIsThemeAppCompat;
-        }
-        // Ideally, we should check if the corresponding activity extends
-        // android.support.v7.app.ActionBarActivity, and not care about the theme name at all.
-        StyleResourceValue defaultTheme = mRenderResources.getDefaultTheme();
-        // We can't simply check for parent using resources.themeIsParentOf() since the
-        // inheritance structure isn't really what one would expect. The first common parent
-        // between Theme.AppCompat.Light and Theme.AppCompat is Theme.Material (for v21).
-        boolean isThemeAppCompat = false;
-        for (int i = 0; i < 50; i++) {
-            if (defaultTheme == null) {
-                break;
-            }
-            // for loop ensures that we don't run into cyclic theme inheritance.
-            if (defaultTheme.getName().startsWith(PREFIX_THEME_APPCOMPAT)) {
-                isThemeAppCompat = true;
-                break;
-            }
-            defaultTheme = mRenderResources.getParent(defaultTheme);
-        }
-        mIsThemeAppCompat = isThemeAppCompat;
-        return isThemeAppCompat;
-    }
-
-    @SuppressWarnings("deprecation")
-    private ILayoutPullParser getParser(ResourceReference resource) {
-        ILayoutPullParser parser;
-        if (resource instanceof ResourceValue) {
-            parser = mLayoutlibCallback.getParser((ResourceValue) resource);
-        } else {
-            parser = mLayoutlibCallback.getParser(resource.getName());
-        }
-        return parser;
-    }
-
-    // ------------ Context methods
-
-    @Override
-    public Resources getResources() {
-        return mSystemResources;
-    }
-
-    @Override
-    public Theme getTheme() {
-        return mTheme;
-    }
-
-    @Override
-    public ClassLoader getClassLoader() {
-        // The documentation for this method states that it should return a class loader one can
-        // use to retrieve classes in this package. However, when called by LayoutInflater, we do
-        // not want the class loader to return app's custom views.
-        // This is so that the IDE can instantiate the custom views and also generate proper error
-        // messages in case of failure. This also enables the IDE to fallback to MockView in case
-        // there's an exception thrown when trying to inflate the custom view.
-        // To work around this issue, LayoutInflater is modified via LayoutLib Create tool to
-        // replace invocations of this method to a new method: getFrameworkClassLoader(). Also,
-        // the method is injected into Context. The implementation of getFrameworkClassLoader() is:
-        // "return getClass().getClassLoader();". This means that when LayoutInflater asks for
-        // the context ClassLoader, it gets only LayoutLib's ClassLoader which doesn't have
-        // access to the apps's custom views.
-        // This method can now return the right ClassLoader, which CustomViews can use to do the
-        // right thing.
-        if (mClassLoader == null) {
-            mClassLoader = new ClassLoader(getClass().getClassLoader()) {
-                @Override
-                protected Class<?> findClass(String name) throws ClassNotFoundException {
-                    for (String prefix : BridgeInflater.getClassPrefixList()) {
-                        if (name.startsWith(prefix)) {
-                            // These are framework classes and should not be loaded from the app.
-                            throw new ClassNotFoundException(name + " not found");
-                        }
-                    }
-                    return BridgeContext.this.mLayoutlibCallback.findClass(name);
-                }
-            };
-        }
-        return mClassLoader;
-    }
-
-    @Override
-    public Object getSystemService(String service) {
-        if (LAYOUT_INFLATER_SERVICE.equals(service)) {
-            return mBridgeInflater;
-        }
-
-        if (TEXT_SERVICES_MANAGER_SERVICE.equals(service)) {
-            // we need to return a valid service to avoid NPE
-            return TextServicesManager.getInstance();
-        }
-
-        if (WINDOW_SERVICE.equals(service)) {
-            return mWindowManager;
-        }
-
-        // needed by SearchView
-        if (INPUT_METHOD_SERVICE.equals(service)) {
-            return null;
-        }
-
-        if (POWER_SERVICE.equals(service)) {
-            return new PowerManager(this, new BridgePowerManager(), new Handler());
-        }
-
-        if (DISPLAY_SERVICE.equals(service)) {
-            return mDisplayManager;
-        }
-
-        if (ACCESSIBILITY_SERVICE.equals(service)) {
-            return AccessibilityManager.getInstance(this);
-        }
-
-        if (AUTOFILL_MANAGER_SERVICE.equals(service)) {
-            return null;
-        }
-
-        if (AUDIO_SERVICE.equals(service)) {
-            return null;
-        }
-
-        assert false : "Unsupported Service: " + service;
-        return null;
-    }
-
-    @Override
-    public String getSystemServiceName(Class<?> serviceClass) {
-        return SystemServiceRegistry_Accessor.getSystemServiceName(serviceClass);
-    }
-
-    @Override
-    public final BridgeTypedArray obtainStyledAttributes(int[] attrs) {
-        return obtainStyledAttributes(0, attrs);
-    }
-
-    @Override
-    public final BridgeTypedArray obtainStyledAttributes(int resId, int[] attrs)
-            throws Resources.NotFoundException {
-        StyleResourceValue style = null;
-        // get the StyleResourceValue based on the resId;
-        if (resId != 0) {
-            style = getStyleByDynamicId(resId);
-
-            if (style == null) {
-                // In some cases, style may not be a dynamic id, so we do a full search.
-                ResourceReference ref = resolveId(resId);
-                if (ref != null) {
-                    style = mRenderResources.getStyle(ref.getName(), ref.isFramework());
-                }
-            }
-
-            if (style == null) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
-                        "Failed to find style with " + resId, null);
-                return null;
-            }
-        }
-
-        if (mTypedArrayCache == null) {
-            mTypedArrayCache = new TypedArrayCache();
-        }
-
-        List<StyleResourceValue> currentThemes = mRenderResources.getAllThemes();
-
-        Pair<BridgeTypedArray, PropertiesMap> typeArrayAndPropertiesPair =
-                mTypedArrayCache.get(attrs, currentThemes, resId);
-
-        if (typeArrayAndPropertiesPair == null) {
-            typeArrayAndPropertiesPair = createStyleBasedTypedArray(style, attrs);
-            mTypedArrayCache.put(attrs, currentThemes, resId, typeArrayAndPropertiesPair);
-        }
-        // Add value to defaultPropsMap if needed
-        if (typeArrayAndPropertiesPair.getSecond() != null) {
-            BridgeXmlBlockParser parser = getCurrentParser();
-            Object key = parser != null ? parser.getViewCookie() : null;
-            if (key != null) {
-                PropertiesMap defaultPropMap = mDefaultPropMaps.get(key);
-                if (defaultPropMap == null) {
-                    defaultPropMap = typeArrayAndPropertiesPair.getSecond();
-                    mDefaultPropMaps.put(key, defaultPropMap);
-                } else {
-                    defaultPropMap.putAll(typeArrayAndPropertiesPair.getSecond());
-                }
-            }
-        }
-        return typeArrayAndPropertiesPair.getFirst();
-    }
-
-    @Override
-    public final BridgeTypedArray obtainStyledAttributes(AttributeSet set, int[] attrs) {
-        return obtainStyledAttributes(set, attrs, 0, 0);
-    }
-
-    @Override
-    public BridgeTypedArray obtainStyledAttributes(AttributeSet set, int[] attrs,
-            int defStyleAttr, int defStyleRes) {
-
-        PropertiesMap defaultPropMap = null;
-        boolean isPlatformFile = true;
-
-        // Hint: for XmlPullParser, attach source //DEVICE_SRC/dalvik/libcore/xml/src/java
-        if (set instanceof BridgeXmlBlockParser) {
-            BridgeXmlBlockParser parser;
-            parser = (BridgeXmlBlockParser)set;
-
-            isPlatformFile = parser.isPlatformFile();
-
-            Object key = parser.getViewCookie();
-            if (key != null) {
-                defaultPropMap = mDefaultPropMaps.computeIfAbsent(key, k -> new PropertiesMap());
-            }
-
-        } else if (set instanceof BridgeLayoutParamsMapAttributes) {
-            // this is only for temp layout params generated dynamically, so this is never
-            // platform content.
-            isPlatformFile = false;
-        } else if (set != null) { // null parser is ok
-            // really this should not be happening since its instantiated in Bridge
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Parser is not a BridgeXmlBlockParser!", null);
-            return null;
-        }
-
-        List<Pair<String, Boolean>> attributeList = searchAttrs(attrs);
-
-        BridgeTypedArray ta =
-                Resources_Delegate.newTypeArray(mSystemResources, attrs.length, isPlatformFile);
-
-        // look for a custom style.
-        String customStyle = null;
-        if (set != null) {
-            customStyle = set.getAttributeValue(null, "style");
-        }
-
-        StyleResourceValue customStyleValues = null;
-        if (customStyle != null) {
-            ResourceValue item = mRenderResources.findResValue(customStyle,
-                    isPlatformFile /*forceFrameworkOnly*/);
-
-            // resolve it in case it links to something else
-            item = mRenderResources.resolveResValue(item);
-
-            if (item instanceof StyleResourceValue) {
-                customStyleValues = (StyleResourceValue)item;
-            }
-        }
-
-        // resolve the defStyleAttr value into a IStyleResourceValue
-        StyleResourceValue defStyleValues = null;
-
-        if (defStyleAttr != 0) {
-            // get the name from the int.
-            Pair<String, Boolean> defStyleAttribute = searchAttr(defStyleAttr);
-
-            if (defStyleAttribute == null) {
-                // This should be rare. Happens trying to map R.style.foo to @style/foo fails.
-                // This will happen if the user explicitly used a non existing int value for
-                // defStyleAttr or there's something wrong with the project structure/build.
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
-                        "Failed to find the style corresponding to the id " + defStyleAttr, null);
-            } else {
-                String defStyleName = defStyleAttribute.getFirst();
-
-                // look for the style in the current theme, and its parent:
-                ResourceValue item = mRenderResources.findItemInTheme(defStyleName,
-                        defStyleAttribute.getSecond());
-
-                if (item != null) {
-                    // item is a reference to a style entry. Search for it.
-                    item = mRenderResources.findResValue(item.getValue(), item.isFramework());
-                    item = mRenderResources.resolveResValue(item);
-                    if (item instanceof StyleResourceValue) {
-                        defStyleValues = (StyleResourceValue) item;
-                    }
-                    if (defaultPropMap != null) {
-                        if (defStyleAttribute.getSecond()) {
-                            defStyleName = "android:" + defStyleName;
-                        }
-                        defaultPropMap.put("style", new Property(defStyleName, item.getValue()));
-                    }
-                } else {
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR,
-                            String.format(
-                                    "Failed to find style '%s' in current theme",
-                                    defStyleAttribute.getFirst()),
-                            null);
-                }
-            }
-        } else if (defStyleRes != 0) {
-            StyleResourceValue item = getStyleByDynamicId(defStyleRes);
-            if (item != null) {
-                defStyleValues = item;
-            } else {
-                boolean isFrameworkRes = true;
-                Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
-                if (value == null) {
-                    value = mLayoutlibCallback.resolveResourceId(defStyleRes);
-                    isFrameworkRes = false;
-                }
-
-                if (value != null) {
-                    if ((value.getFirst() == ResourceType.STYLE)) {
-                        // look for the style in all resources:
-                        item = mRenderResources.getStyle(value.getSecond(), isFrameworkRes);
-                        if (item != null) {
-                            if (defaultPropMap != null) {
-                                String name = item.getName();
-                                defaultPropMap.put("style", new Property(name, name));
-                            }
-
-                            defStyleValues = item;
-                        } else {
-                            Bridge.getLog().error(null,
-                                    String.format(
-                                            "Style with id 0x%x (resolved to '%s') does not exist.",
-                                            defStyleRes, value.getSecond()),
-                                    null);
-                        }
-                    } else {
-                        Bridge.getLog().error(null,
-                                String.format(
-                                        "Resource id 0x%x is not of type STYLE (instead %s)",
-                                        defStyleRes, value.getFirst().toString()),
-                                null);
-                    }
-                } else {
-                    Bridge.getLog().error(null,
-                            String.format(
-                                    "Failed to find style with id 0x%x in current theme",
-                                    defStyleRes),
-                            null);
-                }
-            }
-        }
-
-        String appNamespace = mLayoutlibCallback.getNamespace();
-
-        if (attributeList != null) {
-            for (int index = 0 ; index < attributeList.size() ; index++) {
-                Pair<String, Boolean> attribute = attributeList.get(index);
-
-                if (attribute == null) {
-                    continue;
-                }
-
-                String attrName = attribute.getFirst();
-                boolean frameworkAttr = attribute.getSecond();
-                String value = null;
-                if (set != null) {
-                    value = set.getAttributeValue(
-                            frameworkAttr ? BridgeConstants.NS_RESOURCES : appNamespace,
-                                    attrName);
-
-                    // if this is an app attribute, and the first get fails, try with the
-                    // new res-auto namespace as well
-                    if (!frameworkAttr && value == null) {
-                        value = set.getAttributeValue(BridgeConstants.NS_APP_RES_AUTO, attrName);
-                    }
-                }
-
-                // Calculate the default value from the Theme in two cases:
-                //   - If defaultPropMap is not null, get the default value to add it to the list
-                //   of default values of properties.
-                //   - If value is null, it means that the attribute is not directly set as an
-                //   attribute in the XML so try to get the default value.
-                ResourceValue defaultValue = null;
-                if (defaultPropMap != null || value == null) {
-                    // look for the value in the custom style first (and its parent if needed)
-                    if (customStyleValues != null) {
-                        defaultValue = mRenderResources.findItemInStyle(customStyleValues, attrName,
-                                frameworkAttr);
-                    }
-
-                    // then look for the value in the default Style (and its parent if needed)
-                    if (defaultValue == null && defStyleValues != null) {
-                        defaultValue = mRenderResources.findItemInStyle(defStyleValues, attrName,
-                                frameworkAttr);
-                    }
-
-                    // if the item is not present in the defStyle, we look in the main theme (and
-                    // its parent themes)
-                    if (defaultValue == null) {
-                        defaultValue = mRenderResources.findItemInTheme(attrName, frameworkAttr);
-                    }
-
-                    // if we found a value, we make sure this doesn't reference another value.
-                    // So we resolve it.
-                    if (defaultValue != null) {
-                        String preResolve = defaultValue.getValue();
-                        defaultValue = mRenderResources.resolveResValue(defaultValue);
-
-                        if (defaultPropMap != null) {
-                            defaultPropMap.put(
-                                    frameworkAttr ? SdkConstants.PREFIX_ANDROID + attrName :
-                                            attrName, new Property(preResolve, defaultValue.getValue()));
-                        }
-                    }
-                }
-                // Done calculating the defaultValue
-
-                // if there's no direct value for this attribute in the XML, we look for default
-                // values in the widget defStyle, and then in the theme.
-                if (value == null) {
-                    if (frameworkAttr) {
-                        // For some framework values, layoutlib patches the actual value in the
-                        // theme when it helps to improve the final preview. In most cases
-                        // we just disable animations.
-                        ResourceValue patchedValue = FRAMEWORK_PATCHED_VALUES.get(attrName);
-                        if (patchedValue != null) {
-                            defaultValue = patchedValue;
-                        }
-                    }
-
-                    // if we found a value, we make sure this doesn't reference another value.
-                    // So we resolve it.
-                    if (defaultValue != null) {
-                        // If the value is a reference to another theme attribute that doesn't
-                        // exist, we should log a warning and omit it.
-                        String val = defaultValue.getValue();
-                        if (val != null && val.startsWith(SdkConstants.PREFIX_THEME_REF)) {
-                            // Because we always use the latest framework code, some resources might
-                            // fail to resolve when using old themes (they haven't been backported).
-                            // Since this is an artifact caused by us using always the latest
-                            // code, we check for some of those values and replace them here.
-                            defaultValue = FRAMEWORK_REPLACE_VALUES.get(attrName);
-
-                            if (defaultValue == null &&
-                                    (getApplicationInfo().targetSdkVersion < JELLY_BEAN_MR1 ||
-                                    !attrName.equals(RTL_ATTRS.get(val)))) {
-                                // Only log a warning if the referenced value isn't one of the RTL
-                                // attributes, or the app targets old API.
-                                Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR,
-                                        String.format("Failed to find '%s' in current theme.", val),
-                                        val);
-                            }
-                        }
-                    }
-
-                    ta.bridgeSetValue(index, attrName, frameworkAttr, defaultValue);
-                } else {
-                    // there is a value in the XML, but we need to resolve it in case it's
-                    // referencing another resource or a theme value.
-                    ta.bridgeSetValue(index, attrName, frameworkAttr,
-                            mRenderResources.resolveValue(null, attrName, value, isPlatformFile));
-                }
-            }
-        }
-
-        ta.sealArray();
-
-        return ta;
-    }
-
-    @Override
-    public Looper getMainLooper() {
-        return Looper.myLooper();
-    }
-
-
-    @Override
-    public String getPackageName() {
-        if (mApplicationInfo.packageName == null) {
-            mApplicationInfo.packageName = mLayoutlibCallback.getFlag(FLAG_KEY_APPLICATION_PACKAGE);
-        }
-        return mApplicationInfo.packageName;
-    }
-
-    @Override
-    public PackageManager getPackageManager() {
-        if (mPackageManager == null) {
-            mPackageManager = new BridgePackageManager();
-        }
-        return mPackageManager;
-    }
-
-    // ------------- private new methods
-
-    /**
-     * Creates a {@link BridgeTypedArray} by filling the values defined by the int[] with the
-     * values found in the given style. If no style is specified, the default theme, along with the
-     * styles applied to it are used.
-     *
-     * @see #obtainStyledAttributes(int, int[])
-     */
-    private Pair<BridgeTypedArray, PropertiesMap> createStyleBasedTypedArray(
-            @Nullable StyleResourceValue style, int[] attrs) throws Resources.NotFoundException {
-        List<Pair<String, Boolean>> attributes = searchAttrs(attrs);
-
-        BridgeTypedArray ta =
-                Resources_Delegate.newTypeArray(mSystemResources, attrs.length, false);
-
-        PropertiesMap defaultPropMap = new PropertiesMap();
-        // for each attribute, get its name so that we can search it in the style
-        for (int i = 0; i < attrs.length; i++) {
-            Pair<String, Boolean> attribute = attributes.get(i);
-
-            if (attribute != null) {
-                // look for the value in the given style
-                ResourceValue resValue;
-                String attrName = attribute.getFirst();
-                boolean frameworkAttr = attribute.getSecond();
-                if (style != null) {
-                    resValue = mRenderResources.findItemInStyle(style, attrName, frameworkAttr);
-                } else {
-                    resValue = mRenderResources.findItemInTheme(attrName, frameworkAttr);
-                }
-
-                if (resValue != null) {
-                    // Add it to defaultPropMap before resolving
-                    String preResolve = resValue.getValue();
-                    // resolve it to make sure there are no references left.
-                    resValue = mRenderResources.resolveResValue(resValue);
-                    ta.bridgeSetValue(i, attrName, frameworkAttr, resValue);
-                    defaultPropMap.put(
-                            frameworkAttr ? SdkConstants.ANDROID_PREFIX + attrName : attrName,
-                            new Property(preResolve, resValue.getValue()));
-                }
-            }
-        }
-
-        ta.sealArray();
-
-        return Pair.of(ta, defaultPropMap);
-    }
-
-    /**
-     * The input int[] attrs is a list of attributes. The returns a list of information about
-     * each attributes. The information is (name, isFramework)
-     * <p/>
-     *
-     * @param attrs An attribute array reference given to obtainStyledAttributes.
-     * @return List of attribute information.
-     */
-    private List<Pair<String, Boolean>> searchAttrs(int[] attrs) {
-        List<Pair<String, Boolean>> results = new ArrayList<>(attrs.length);
-
-        // for each attribute, get its name so that we can search it in the style
-        for (int attr : attrs) {
-            Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attr);
-            boolean isFramework = false;
-            if (resolvedResource != null) {
-                isFramework = true;
-            } else {
-                resolvedResource = mLayoutlibCallback.resolveResourceId(attr);
-            }
-
-            if (resolvedResource != null) {
-                results.add(Pair.of(resolvedResource.getSecond(), isFramework));
-            } else {
-                results.add(null);
-            }
-        }
-
-        return results;
-    }
-
-    /**
-     * Searches for the attribute referenced by its internal id.
-     *
-     * @param attr An attribute reference given to obtainStyledAttributes such as defStyle.
-     * @return A (name, isFramework) pair describing the attribute if found. Returns null
-     *         if nothing is found.
-     */
-    private Pair<String, Boolean> searchAttr(int attr) {
-        Pair<ResourceType, String> info = Bridge.resolveResourceId(attr);
-        if (info != null) {
-            return Pair.of(info.getSecond(), Boolean.TRUE);
-        }
-
-        info = mLayoutlibCallback.resolveResourceId(attr);
-        if (info != null) {
-            return Pair.of(info.getSecond(), Boolean.FALSE);
-        }
-
-        return null;
-    }
-
-    public int getDynamicIdByStyle(StyleResourceValue resValue) {
-        if (mDynamicIdToStyleMap == null) {
-            // create the maps.
-            mDynamicIdToStyleMap = new HashMap<>();
-            mStyleToDynamicIdMap = new HashMap<>();
-        }
-
-        // look for an existing id
-        Integer id = mStyleToDynamicIdMap.get(resValue);
-
-        if (id == null) {
-            // generate a new id
-            id = ++mDynamicIdGenerator;
-
-            // and add it to the maps.
-            mDynamicIdToStyleMap.put(id, resValue);
-            mStyleToDynamicIdMap.put(resValue, id);
-        }
-
-        return id;
-    }
-
-    private StyleResourceValue getStyleByDynamicId(int i) {
-        if (mDynamicIdToStyleMap != null) {
-            return mDynamicIdToStyleMap.get(i);
-        }
-
-        return null;
-    }
-
-    public int getFrameworkResourceValue(ResourceType resType, String resName, int defValue) {
-        if (getRenderResources().getFrameworkResource(resType, resName) != null) {
-            // Bridge.getResourceId creates a new resource id if an existing one isn't found. So,
-            // we check for the existence of the resource before calling it.
-            return Bridge.getResourceId(resType, resName);
-        }
-
-        return defValue;
-    }
-
-    public int getProjectResourceValue(ResourceType resType, String resName, int defValue) {
-        // getResourceId creates a new resource id if an existing resource id isn't found. So, we
-        // check for the existence of the resource before calling it.
-        if (getRenderResources().getProjectResource(resType, resName) != null) {
-            if (mLayoutlibCallback != null) {
-                Integer value = mLayoutlibCallback.getResourceId(resType, resName);
-                if (value != null) {
-                    return value;
-                }
-            }
-        }
-
-        return defValue;
-    }
-
-    public static Context getBaseContext(Context context) {
-        while (context instanceof ContextWrapper) {
-            context = ((ContextWrapper) context).getBaseContext();
-        }
-        return context;
-    }
-
-    public IBinder getBinder() {
-        if (mBinder == null) {
-            // create a dummy binder. We only need it be not null.
-            mBinder = new IBinder() {
-                @Override
-                public String getInterfaceDescriptor() throws RemoteException {
-                    return null;
-                }
-
-                @Override
-                public boolean pingBinder() {
-                    return false;
-                }
-
-                @Override
-                public boolean isBinderAlive() {
-                    return false;
-                }
-
-                @Override
-                public IInterface queryLocalInterface(String descriptor) {
-                    return null;
-                }
-
-                @Override
-                public void dump(FileDescriptor fd, String[] args) throws RemoteException {
-
-                }
-
-                @Override
-                public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
-
-                }
-
-                @Override
-                public boolean transact(int code, Parcel data, Parcel reply, int flags)
-                        throws RemoteException {
-                    return false;
-                }
-
-                @Override
-                public void linkToDeath(DeathRecipient recipient, int flags)
-                        throws RemoteException {
-
-                }
-
-                @Override
-                public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
-                    return false;
-                }
-
-                @Override
-                public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
-                  String[] args, ShellCallback shellCallback, ResultReceiver resultReceiver) {
-                }
-            };
-        }
-        return mBinder;
-    }
-
-    //------------ NOT OVERRIDEN --------------------
-
-    @Override
-    public boolean bindService(Intent arg0, ServiceConnection arg1, int arg2) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public int checkCallingOrSelfPermission(String arg0) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkCallingOrSelfUriPermission(Uri arg0, int arg1) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkCallingPermission(String arg0) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkCallingUriPermission(Uri arg0, int arg1) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkPermission(String arg0, int arg1, int arg2) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkSelfPermission(String arg0) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkPermission(String arg0, int arg1, int arg2, IBinder arg3) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3, IBinder arg4) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3,
-            int arg4, int arg5) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public void clearWallpaper() {
-        // pass
-
-    }
-
-    @Override
-    public Context createPackageContext(String arg0, int arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createPackageContextAsUser(String arg0, int arg1, UserHandle user) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createConfigurationContext(Configuration overrideConfiguration) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createDisplayContext(Display display) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createContextForSplit(String splitName) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String[] databaseList() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createApplicationContext(ApplicationInfo application, int flags)
-            throws PackageManager.NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public boolean moveDatabaseFrom(Context sourceContext, String name) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public boolean deleteDatabase(String arg0) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public boolean deleteFile(String arg0) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public void enforceCallingOrSelfPermission(String arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceCallingOrSelfUriPermission(Uri arg0, int arg1,
-            String arg2) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceCallingPermission(String arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceCallingUriPermission(Uri arg0, int arg1, String arg2) {
-        // pass
-
-    }
-
-    @Override
-    public void enforcePermission(String arg0, int arg1, int arg2, String arg3) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceUriPermission(Uri arg0, int arg1, int arg2, int arg3,
-            String arg4) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceUriPermission(Uri arg0, String arg1, String arg2,
-            int arg3, int arg4, int arg5, String arg6) {
-        // pass
-
-    }
-
-    @Override
-    public String[] fileList() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public BridgeAssetManager getAssets() {
-        return mAssets;
-    }
-
-    @Override
-    public File getCacheDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getCodeCacheDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getExternalCacheDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getPreloadsFileCache() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public ContentResolver getContentResolver() {
-        if (mContentResolver == null) {
-            mContentResolver = new BridgeContentResolver(this);
-        }
-        return mContentResolver;
-    }
-
-    @Override
-    public File getDatabasePath(String arg0) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getDir(String arg0, int arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getFileStreamPath(String arg0) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getSharedPreferencesPath(String name) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getDataDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getFilesDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getNoBackupFilesDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getExternalFilesDir(String type) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String getPackageCodePath() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String getBasePackageName() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String getOpPackageName() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public ApplicationInfo getApplicationInfo() {
-        return mApplicationInfo;
-    }
-
-    @Override
-    public String getPackageResourcePath() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public SharedPreferences getSharedPreferences(String arg0, int arg1) {
-        if (mSharedPreferences == null) {
-            mSharedPreferences = new BridgeSharedPreferences();
-        }
-        return mSharedPreferences;
-    }
-
-    @Override
-    public SharedPreferences getSharedPreferences(File arg0, int arg1) {
-        if (mSharedPreferences == null) {
-            mSharedPreferences = new BridgeSharedPreferences();
-        }
-        return mSharedPreferences;
-    }
-
-    @Override
-    public boolean moveSharedPreferencesFrom(Context sourceContext, String name) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public boolean deleteSharedPreferences(String name) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public Drawable getWallpaper() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public int getWallpaperDesiredMinimumWidth() {
-        return -1;
-    }
-
-    @Override
-    public int getWallpaperDesiredMinimumHeight() {
-        return -1;
-    }
-
-    @Override
-    public void grantUriPermission(String arg0, Uri arg1, int arg2) {
-        // pass
-
-    }
-
-    @Override
-    public FileInputStream openFileInput(String arg0) throws FileNotFoundException {
-        // pass
-        return null;
-    }
-
-    @Override
-    public FileOutputStream openFileOutput(String arg0, int arg1) throws FileNotFoundException {
-        // pass
-        return null;
-    }
-
-    @Override
-    public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, CursorFactory arg2) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1,
-            CursorFactory arg2, DatabaseErrorHandler arg3) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Drawable peekWallpaper() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1, int arg2) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1,
-            String arg2, Handler arg3) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1,
-            String arg2, Handler arg3, int arg4) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiverAsUser(BroadcastReceiver arg0, UserHandle arg0p5,
-            IntentFilter arg1, String arg2, Handler arg3) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void removeStickyBroadcast(Intent arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void revokeUriPermission(Uri arg0, int arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void revokeUriPermission(String arg0, Uri arg1, int arg2) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent arg0, String arg1, Bundle arg2) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
-        // pass
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent arg0, String arg1,
-            BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
-            Bundle arg6) {
-        // pass
-
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent arg0, String arg1,
-            Bundle arg7, BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
-            Bundle arg6) {
-        // pass
-
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
-            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
-            String initialData, Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendBroadcastAsUser(Intent intent, UserHandle user) {
-        // pass
-    }
-
-    @Override
-    public void sendBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission) {
-        // pass
-    }
-
-    @Override
-    public void sendBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, Bundle options) {
-        // pass
-    }
-
-    public void sendBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, int appOp) {
-        // pass
-    }
-
-    @Override
-    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
-            int initialCode, String initialData, Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
-            Handler scheduler,
-            int initialCode, String initialData, Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
-            Handler scheduler,
-            int initialCode, String initialData, Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyBroadcast(Intent arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void sendStickyOrderedBroadcast(Intent intent,
-            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
-           Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyOrderedBroadcastAsUser(Intent intent,
-            UserHandle user, BroadcastReceiver resultReceiver,
-            Handler scheduler, int initialCode, String initialData,
-            Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
-        // pass
-    }
-
-    @Override
-    public void setTheme(int arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void setWallpaper(Bitmap arg0) throws IOException {
-        // pass
-
-    }
-
-    @Override
-    public void setWallpaper(InputStream arg0) throws IOException {
-        // pass
-
-    }
-
-    @Override
-    public void startActivity(Intent arg0) {
-        // pass
-    }
-
-    @Override
-    public void startActivity(Intent arg0, Bundle arg1) {
-        // pass
-    }
-
-    @Override
-    public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
-            throws IntentSender.SendIntentException {
-        // pass
-    }
-
-    @Override
-    public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
-            Bundle options) throws IntentSender.SendIntentException {
-        // pass
-    }
-
-    @Override
-    public boolean startInstrumentation(ComponentName arg0, String arg1,
-            Bundle arg2) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public ComponentName startService(Intent arg0) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public ComponentName startForegroundService(Intent service) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public boolean stopService(Intent arg0) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public ComponentName startServiceAsUser(Intent arg0, UserHandle arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public boolean stopServiceAsUser(Intent arg0, UserHandle arg1) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public void unbindService(ServiceConnection arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void unregisterReceiver(BroadcastReceiver arg0) {
-        // pass
-
-    }
-
-    @Override
-    public Context getApplicationContext() {
-        return this;
-    }
-
-    @Override
-    public void startActivities(Intent[] arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void startActivities(Intent[] arg0, Bundle arg1) {
-        // pass
-
-    }
-
-    @Override
-    public boolean isRestricted() {
-        return false;
-    }
-
-    @Override
-    public File getObbDir() {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "OBB not supported", null);
-        return null;
-    }
-
-    @Override
-    public DisplayAdjustments getDisplayAdjustments(int displayId) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Display getDisplay() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void updateDisplay(int displayId) {
-        // pass
-    }
-
-    @Override
-    public int getUserId() {
-        return 0; // not used
-    }
-
-    @Override
-    public File[] getExternalFilesDirs(String type) {
-        // pass
-        return new File[0];
-    }
-
-    @Override
-    public File[] getObbDirs() {
-        // pass
-        return new File[0];
-    }
-
-    @Override
-    public File[] getExternalCacheDirs() {
-        // pass
-        return new File[0];
-    }
-
-    @Override
-    public File[] getExternalMediaDirs() {
-        // pass
-        return new File[0];
-    }
-
-    public void setScrollYPos(@NonNull View view, int scrollPos) {
-        mScrollYPos.put(view, scrollPos);
-    }
-
-    public int getScrollYPos(@NonNull View view) {
-        Integer pos = mScrollYPos.get(view);
-        return pos != null ? pos : 0;
-    }
-
-    public void setScrollXPos(@NonNull View view, int scrollPos) {
-        mScrollXPos.put(view, scrollPos);
-    }
-
-    public int getScrollXPos(@NonNull View view) {
-        Integer pos = mScrollXPos.get(view);
-        return pos != null ? pos : 0;
-    }
-
-    @Override
-    public Context createDeviceProtectedStorageContext() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createCredentialProtectedStorageContext() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public boolean isDeviceProtectedStorage() {
-        return false;
-    }
-
-    @Override
-    public boolean isCredentialProtectedStorage() {
-        return false;
-    }
-
-    @Override
-    public boolean canLoadUnsafeResources() {
-        return false;
-    }
-
-    /**
-     * The cached value depends on
-     * <ol>
-     * <li>{@code int[]}: the attributes for which TypedArray is created </li>
-     * <li>{@code List<StyleResourceValue>}: the themes set on the context at the time of
-     * creation of the TypedArray</li>
-     * <li>{@code Integer}: the default style used at the time of creation</li>
-     * </ol>
-     *
-     * The class is created by using nested maps resolving one dependency at a time.
-     * <p/>
-     * The final value of the nested maps is a pair of the typed array and a map of properties
-     * that should be added to {@link #mDefaultPropMaps}, if needed.
-     */
-    private static class TypedArrayCache {
-
-        private Map<int[],
-                Map<List<StyleResourceValue>,
-                        Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>>> mCache;
-
-        private TypedArrayCache() {
-            mCache = new IdentityHashMap<>();
-        }
-
-        public Pair<BridgeTypedArray, PropertiesMap> get(int[] attrs,
-                List<StyleResourceValue> themes, int resId) {
-            Map<List<StyleResourceValue>, Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>>
-                    cacheFromThemes = mCache.get(attrs);
-            if (cacheFromThemes != null) {
-                Map<Integer, Pair<BridgeTypedArray, PropertiesMap>> cacheFromResId =
-                        cacheFromThemes.get(themes);
-                if (cacheFromResId != null) {
-                    return cacheFromResId.get(resId);
-                }
-            }
-            return null;
-        }
-
-        public void put(int[] attrs, List<StyleResourceValue> themes, int resId,
-                Pair<BridgeTypedArray, PropertiesMap> value) {
-            Map<List<StyleResourceValue>, Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>>
-                    cacheFromThemes = mCache.computeIfAbsent(attrs, k -> new HashMap<>());
-            Map<Integer, Pair<BridgeTypedArray, PropertiesMap>> cacheFromResId =
-                    cacheFromThemes.computeIfAbsent(themes, k -> new HashMap<>());
-            cacheFromResId.put(resId, value);
-        }
-
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
deleted file mode 100644
index 4805ed1..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
+++ /dev/null
@@ -1,258 +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.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.internal.inputmethod.IInputContentUriToken;
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
-import com.android.internal.view.IInputMethodManager;
-import com.android.internal.view.InputBindResult;
-
-import android.net.Uri;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.text.style.SuggestionSpan;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodSubtype;
-
-import java.util.List;
-
-/**
- * Basic implementation of IInputMethodManager that does nothing.
- *
- */
-public class BridgeIInputMethodManager implements IInputMethodManager {
-
-    @Override
-    public void addClient(IInputMethodClient arg0, IInputContext arg1, int arg2, int arg3)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void finishInput(IInputMethodClient arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public InputMethodSubtype getCurrentInputMethodSubtype() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<InputMethodInfo> getEnabledInputMethodList() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String arg0,
-            boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<InputMethodInfo> getInputMethodList() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public InputMethodSubtype getLastInputMethodSubtype() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List getShortcutInputMethodsAndSubtypes() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void hideMySoftInput(IBinder arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean hideSoftInput(IInputMethodClient arg0, int arg1, ResultReceiver arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean notifySuggestionPicked(SuggestionSpan arg0, String arg1, int arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void registerSuggestionSpansForNotification(SuggestionSpan[] arg0)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void removeClient(IInputMethodClient arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setAdditionalInputMethodSubtypes(String arg0, InputMethodSubtype[] arg1)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean setCurrentInputMethodSubtype(InputMethodSubtype arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void setImeWindowStatus(IBinder arg0, IBinder arg1, int arg2, int arg3)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setInputMethod(IBinder arg0, String arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setInputMethodAndSubtype(IBinder arg0, String arg1, InputMethodSubtype arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean setInputMethodEnabled(String arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void showInputMethodAndSubtypeEnablerFromClient(IInputMethodClient arg0, String arg1)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void showInputMethodPickerFromClient(IInputMethodClient arg0,
-            int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void showMySoftInput(IBinder arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean showSoftInput(IInputMethodClient arg0, int arg1, ResultReceiver arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean switchToLastInputMethod(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean switchToNextInputMethod(IBinder arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean shouldOfferSwitchingToNextInputMethod(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-     public int getInputMethodWindowVisibleHeight() throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void notifyUserAction(int sequenceNumber) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void updateStatusIcon(IBinder arg0, String arg1, int arg2) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void clearLastInputMethodWindowForTransition(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public InputBindResult startInputOrWindowGainedFocus(
-            /* @InputMethodClient.StartInputReason */ int startInputReason,
-            IInputMethodClient client, IBinder windowToken, int controlFlags,
-            /* @android.view.WindowManager.LayoutParams.SoftInputModeFlags */ int softInputMode,
-            int windowFlags, EditorInfo attribute, IInputContext inputContext,
-            /* @InputConnectionInspector.MissingMethodFlags */ int missingMethodFlags)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public IInputContentUriToken createInputContentUriToken(IBinder token, Uri contentUri,
-            String packageName) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void reportFullscreenMode(IBinder token, boolean fullscreen) {
-        // TODO Auto-generated method stub
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java
deleted file mode 100644
index f5912e7..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.layoutlib.bridge.BridgeConstants;
-
-import android.util.AttributeSet;
-
-import java.util.Map;
-
-/**
- * An implementation of the {@link AttributeSet} interface on top of a map of attribute in the form
- * of (name, value).
- *
- * This is meant to be called only from {@link BridgeContext#obtainStyledAttributes(AttributeSet, int[], int, int)}
- * in the case of LayoutParams and therefore isn't a full implementation.
- */
-public class BridgeLayoutParamsMapAttributes implements AttributeSet {
-
-    private final Map<String, String> mAttributes;
-
-    public BridgeLayoutParamsMapAttributes(Map<String, String> attributes) {
-        mAttributes = attributes;
-    }
-
-    @Override
-    public String getAttributeValue(String namespace, String name) {
-        if (BridgeConstants.NS_RESOURCES.equals(namespace)) {
-            return mAttributes.get(name);
-        }
-
-        return null;
-    }
-
-    // ---- the following methods are not called from
-    // BridgeContext#obtainStyledAttributes(AttributeSet, int[], int, int)
-    // Should they ever be called, we'll just implement them on a need basis.
-
-    @Override
-    public int getAttributeCount() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getAttributeName(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getAttributeValue(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getPositionDescription() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeNameResource(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeListValue(String namespace, String attribute,
-            String[] options, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(String namespace, String attribute,
-            boolean defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeResourceValue(String namespace, String attribute,
-            int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeIntValue(String namespace, String attribute,
-            int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(String namespace, String attribute,
-            int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public float getAttributeFloatValue(String namespace, String attribute,
-            float defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeListValue(int index,
-            String[] options, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeResourceValue(int index, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeIntValue(int index, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public float getAttributeFloatValue(int index, float defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getIdAttribute() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getClassAttribute() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getIdAttributeResourceValue(int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getStyleAttribute() {
-        throw new UnsupportedOperationException();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
deleted file mode 100644
index 1b5a54d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
+++ /dev/null
@@ -1,958 +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.layoutlib.bridge.android;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.PackageInstallObserver;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.ChangedPackages;
-import android.content.pm.InstantAppInfo;
-import android.content.pm.FeatureInfo;
-import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageDeleteObserver;
-import android.content.pm.IPackageInstallObserver;
-import android.content.pm.IPackageStatsObserver;
-import android.content.pm.InstrumentationInfo;
-import android.content.pm.IntentFilterVerificationInfo;
-import android.content.pm.KeySet;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageItemInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PermissionGroupInfo;
-import android.content.pm.PermissionInfo;
-import android.content.pm.ProviderInfo;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.content.pm.SharedLibraryInfo;
-import android.content.pm.VerifierDeviceIdentity;
-import android.content.pm.VersionedPackage;
-import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
-import android.graphics.Rect;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.os.storage.VolumeInfo;
-import java.util.List;
-
-/**
- * An implementation of {@link PackageManager} that does nothing.
- */
-@SuppressWarnings("deprecation")
-public class BridgePackageManager extends PackageManager {
-    @Override
-    public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public PackageInfo getPackageInfo(VersionedPackage versionedPackage,
-            @PackageInfoFlags int flags) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<SharedLibraryInfo> getSharedLibraries(@InstallFlags int flags) {
-        return null;
-    }
-
-    @Override
-    public List<SharedLibraryInfo> getSharedLibrariesAsUser(@InstallFlags int flags,
-            int userId) {
-        return null;
-    }
-
-    @Override
-    public String[] currentToCanonicalPackageNames(String[] names) {
-        return new String[0];
-    }
-
-    @Override
-    public String[] canonicalToCurrentPackageNames(String[] names) {
-        return new String[0];
-    }
-
-    @Override
-    public Intent getLaunchIntentForPackage(String packageName) {
-        return null;
-    }
-
-    @Override
-    public Intent getLeanbackLaunchIntentForPackage(String packageName) {
-        return null;
-    }
-
-    @Override
-    public int[] getPackageGids(String packageName) throws NameNotFoundException {
-        return new int[0];
-    }
-
-    @Override
-    public int[] getPackageGids(String packageName, int flags) throws NameNotFoundException {
-        return new int[0];
-    }
-
-    @Override
-    public int getPackageUid(String packageName, int flags) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public int getPackageUidAsUser(String packageName, int userHandle) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public int getPackageUidAsUser(String packageName, int flags, int userHandle) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public PermissionInfo getPermissionInfo(String name, int flags) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public boolean isPermissionReviewModeEnabled() {
-        return false;
-    }
-
-    @Override
-    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
-        return null;
-    }
-
-    @Override
-    public ApplicationInfo getApplicationInfo(String packageName, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ActivityInfo getActivityInfo(ComponentName component, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ActivityInfo getReceiverInfo(ComponentName component, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ServiceInfo getServiceInfo(ComponentName component, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ProviderInfo getProviderInfo(ComponentName component, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<PackageInfo> getInstalledPackages(int flags) {
-        return null;
-    }
-
-    @Override
-    public List<PackageInfo> getPackagesHoldingPermissions(String[] permissions, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public int checkPermission(String permName, String pkgName) {
-        return 0;
-    }
-
-    @Override
-    public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
-        return false;
-    }
-
-    @Override
-    public String getPermissionControllerPackageName() {
-        return null;
-    }
-
-    @Override
-    public boolean addPermission(PermissionInfo info) {
-        return false;
-    }
-
-    @Override
-    public boolean addPermissionAsync(PermissionInfo info) {
-        return false;
-    }
-
-    @Override
-    public void removePermission(String name) {
-    }
-
-    @Override
-    public void grantRuntimePermission(String packageName, String permissionName, UserHandle user) {
-    }
-
-    @Override
-    public void revokeRuntimePermission(String packageName, String permissionName,
-            UserHandle user) {
-    }
-
-    @Override
-    public int getPermissionFlags(String permissionName, String packageName, UserHandle user) {
-        return 0;
-    }
-
-    @Override
-    public void updatePermissionFlags(String permissionName, String packageName, int flagMask,
-            int flagValues, UserHandle user) {
-    }
-
-    @Override
-    public boolean shouldShowRequestPermissionRationale(String permission) {
-        return false;
-    }
-
-    @Override
-    public int checkSignatures(String pkg1, String pkg2) {
-        return 0;
-    }
-
-    @Override
-    public int checkSignatures(int uid1, int uid2) {
-        return 0;
-    }
-
-    @Override
-    public String[] getPackagesForUid(int uid) {
-        return new String[0];
-    }
-
-    @Override
-    public String getNameForUid(int uid) {
-        return null;
-    }
-
-    @Override
-    public int getUidForSharedUser(String sharedUserName) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public List<ApplicationInfo> getInstalledApplications(int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<InstantAppInfo> getInstantApps() {
-        return null;
-    }
-
-    @Override
-    public Drawable getInstantAppIcon(String packageName) {
-        assert false : "Unsupported operation";
-        return new ColorDrawable();
-    }
-
-    @Override
-    public byte[] getInstantAppCookie() {
-        return new byte[0];
-    }
-
-    @Override
-    public boolean isInstantApp() {
-        return false;
-    }
-
-    @Override
-    public boolean isInstantApp(String packageName) {
-        return false;
-    }
-
-    @Override
-    public int getInstantAppCookieMaxBytes() {
-        return 0;
-    }
-
-    @Override
-    public int getInstantAppCookieMaxSize() {
-        return 0;
-    }
-
-    @Override
-    public void clearInstantAppCookie() {;
-
-    }
-
-    @Override
-    public void updateInstantAppCookie(@Nullable byte[] cookie) {
-
-    }
-
-    @Override
-    public boolean setInstantAppCookie(@NonNull byte[] cookie) {
-        return false;
-    }
-
-    @Override
-    public String[] getSystemSharedLibraryNames() {
-        return new String[0];
-    }
-
-    @Override
-    public String getServicesSystemSharedLibraryPackageName() {
-        return null;
-    }
-
-    @Override
-    public @NonNull String getSharedSystemSharedLibraryPackageName() {
-        return null;
-    }
-
-    @Override
-    public FeatureInfo[] getSystemAvailableFeatures() {
-        return new FeatureInfo[0];
-    }
-
-    @Override
-    public boolean hasSystemFeature(String name) {
-        return false;
-    }
-
-    @Override
-    public boolean hasSystemFeature(String name, int version) {
-        return false;
-    }
-
-    @Override
-    public ResolveInfo resolveActivity(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics,
-            Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public ResolveInfo resolveService(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentContentProvidersAsUser(Intent intent, int flags,
-            int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public ProviderInfo resolveContentProvider(String name, int flags) {
-        return null;
-    }
-
-    @Override
-    public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) {
-        return null;
-    }
-
-    @Override
-    public InstrumentationInfo getInstrumentationInfo(ComponentName className, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<InstrumentationInfo> queryInstrumentation(String targetPackage, int flags) {
-        return null;
-    }
-
-    @Override
-    public Drawable getDrawable(String packageName, int resid, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityIcon(ComponentName activityName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityIcon(Intent intent) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityBanner(ComponentName activityName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityBanner(Intent intent) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getDefaultActivityIcon() {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationIcon(ApplicationInfo info) {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationIcon(String packageName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationBanner(ApplicationInfo info) {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationBanner(String packageName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityLogo(ComponentName activityName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityLogo(Intent intent) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationLogo(ApplicationInfo info) {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationLogo(String packageName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
-        return null;
-    }
-
-    @Override
-    public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
-            Rect badgeLocation, int badgeDensity) {
-        return null;
-    }
-
-    @Override
-    public Drawable getUserBadgeForDensity(UserHandle user, int density) {
-        return null;
-    }
-
-    @Override
-    public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
-        return null;
-    }
-
-    @Override
-    public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
-        return null;
-    }
-
-    @Override
-    public CharSequence getText(String packageName, int resid, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public XmlResourceParser getXml(String packageName, int resid, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public CharSequence getApplicationLabel(ApplicationInfo info) {
-        return null;
-    }
-
-    @Override
-    public Resources getResourcesForActivity(ComponentName activityName)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Resources getResourcesForApplication(ApplicationInfo app) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Resources getResourcesForApplication(String appPackageName)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
-            String installerPackageName) {
-    }
-
-    @Override
-    public void installPackage(Uri packageURI, PackageInstallObserver observer, int flags,
-            String installerPackageName) {
-    }
-
-    @Override
-    public int installExistingPackage(String packageName) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public int installExistingPackage(String packageName, int installReason)
-            throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public int installExistingPackageAsUser(String packageName, int userId)
-            throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public void verifyPendingInstall(int id, int verificationCode) {
-    }
-
-    @Override
-    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
-            long millisecondsToDelay) {
-    }
-
-    @Override
-    public void verifyIntentFilter(int verificationId, int verificationCode,
-            List<String> outFailedDomains) {
-    }
-
-    @Override
-    public int getIntentVerificationStatusAsUser(String packageName, int userId) {
-        return 0;
-    }
-
-    @Override
-    public boolean updateIntentVerificationStatusAsUser(String packageName, int status, int userId) {
-        return false;
-    }
-
-    @Override
-    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
-        return null;
-    }
-
-    @Override
-    public List<IntentFilter> getAllIntentFilters(String packageName) {
-        return null;
-    }
-
-    @Override
-    public String getDefaultBrowserPackageNameAsUser(int userId) {
-        return null;
-    }
-
-    @Override
-    public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
-        return false;
-    }
-
-    @Override
-    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
-    }
-
-    @Override
-    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
-    }
-
-    @Override
-    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
-    }
-
-    @Override
-    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags,
-            int userId) {
-    }
-
-    @Override
-    public String getInstallerPackageName(String packageName) {
-        return null;
-    }
-
-    @Override
-    public void clearApplicationUserData(String packageName, IPackageDataObserver observer) {
-    }
-
-    @Override
-    public void deleteApplicationCacheFiles(String packageName, IPackageDataObserver observer) {
-    }
-
-    @Override
-    public void deleteApplicationCacheFilesAsUser(String packageName, int userId,
-            IPackageDataObserver observer) {
-    }
-
-    @Override
-    public void freeStorageAndNotify(String volumeUuid, long freeStorageSize,
-            IPackageDataObserver observer) {
-    }
-
-    @Override
-    public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
-    }
-
-    @Override
-    public void getPackageSizeInfoAsUser(String packageName, int userHandle,
-            IPackageStatsObserver observer) {
-    }
-
-    @Override
-    public void addPackageToPreferred(String packageName) {
-    }
-
-    @Override
-    public void removePackageFromPreferred(String packageName) {
-    }
-
-    @Override
-    public List<PackageInfo> getPreferredPackages(int flags) {
-        return null;
-    }
-
-    @Override
-    public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set,
-            ComponentName activity) {
-    }
-
-    @Override
-    public void replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set,
-            ComponentName activity) {
-    }
-
-    @Override
-    public void clearPackagePreferredActivities(String packageName) {
-    }
-
-    @Override
-    public int getPreferredActivities(List<IntentFilter> outFilters,
-            List<ComponentName> outActivities, String packageName) {
-        return 0;
-    }
-
-    @Override
-    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
-        return null;
-    }
-
-    @Override
-    public void setComponentEnabledSetting(ComponentName componentName, int newState, int flags) {
-    }
-
-    @Override
-    public int getComponentEnabledSetting(ComponentName componentName) {
-        return 0;
-    }
-
-    @Override
-    public void setApplicationEnabledSetting(String packageName, int newState, int flags) {
-    }
-
-    @Override
-    public int getApplicationEnabledSetting(String packageName) {
-        return 0;
-    }
-
-    @Override
-    public void flushPackageRestrictionsAsUser(int userId) {
-    }
-
-    @Override
-    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
-            UserHandle userHandle) {
-        return false;
-    }
-
-    @Override
-    public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle userHandle) {
-        return false;
-    }
-
-    @Override
-    public boolean isSafeMode() {
-        return false;
-    }
-
-    @Override
-    public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
-    }
-
-    @Override
-    public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
-    }
-
-    @Override
-    public KeySet getKeySetByAlias(String packageName, String alias) {
-        return null;
-    }
-
-    @Override
-    public KeySet getSigningKeySet(String packageName) {
-        return null;
-    }
-
-    @Override
-    public boolean isSignedBy(String packageName, KeySet ks) {
-        return false;
-    }
-
-    @Override
-    public boolean isSignedByExactly(String packageName, KeySet ks) {
-        return false;
-    }
-
-    @Override
-    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
-            int userId) {
-        return new String[]{};
-    }
-
-    @Override
-    public boolean isPackageSuspendedForUser(String packageName, int userId) {
-        return false;
-    }
-
-    @Override
-    public void setApplicationCategoryHint(String packageName, int categoryHint) {
-    }
-
-    @Override
-    public int getMoveStatus(int moveId) {
-        return 0;
-    }
-
-    @Override
-    public void registerMoveCallback(MoveCallback callback, Handler handler) {
-    }
-
-    @Override
-    public void unregisterMoveCallback(MoveCallback callback) {
-    }
-
-    @Override
-    public int movePackage(String packageName, VolumeInfo vol) {
-        return 0;
-    }
-
-    @Override
-    public VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
-        return null;
-    }
-
-    @Override
-    public List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
-        return null;
-    }
-
-    @Override
-    public int movePrimaryStorage(VolumeInfo vol) {
-        return 0;
-    }
-
-    @Override
-    public VolumeInfo getPrimaryStorageCurrentVolume() {
-        return null;
-    }
-
-    @Override
-    public List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
-        return null;
-    }
-
-    @Override
-    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
-        return null;
-    }
-
-    @Override
-    public ChangedPackages getChangedPackages(int sequenceNumber) {
-        return null;
-    }
-
-    @Override
-    public boolean isUpgrade() {
-        return false;
-    }
-
-    @Override
-    public PackageInstaller getPackageInstaller() {
-        return null;
-    }
-
-    @Override
-    public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
-            int flags) {
-    }
-
-    @Override
-    public void clearCrossProfileIntentFilters(int sourceUserId) {
-    }
-
-    @Override
-    public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public boolean isPackageAvailable(String packageName) {
-        return false;
-    }
-
-    @Override
-    public int getInstallReason(String packageName, UserHandle user) {
-        return INSTALL_REASON_UNKNOWN;
-    }
-
-    @Override
-    public boolean canRequestPackageInstalls() {
-        return false;
-    }
-
-    @Override
-    public ComponentName getInstantAppResolverSettingsComponent() {
-        return null;
-    }
-
-    @Override
-    public ComponentName getInstantAppInstallerComponent() {
-        return null;
-    }
-
-    @Override
-    public String getInstantAppAndroidId(String packageName, UserHandle user) {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
deleted file mode 100644
index ed428ec9..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.os.IBinder;
-import android.os.IPowerManager;
-import android.os.PowerManager;
-import android.os.PowerSaveState;
-import android.os.RemoteException;
-import android.os.WorkSource;
-
-/**
- * Fake implementation of IPowerManager.
- *
- */
-public class BridgePowerManager implements IPowerManager {
-
-    @Override
-    public boolean isInteractive() throws RemoteException {
-        return true;
-    }
-
-    @Override
-    public boolean isPowerSaveMode() throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public boolean setPowerSaveMode(boolean mode) throws RemoteException {
-        return false;
-    }
-
-    public PowerSaveState getPowerSaveState(int serviceType) {
-        return null;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3, String arg4)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void acquireWakeLockWithUid(IBinder arg0, int arg1, String arg2, String arg2_5, int arg3)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void powerHint(int hintId, int data) {
-        // pass for now.
-    }
-
-    @Override
-    public void crash(String arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void goToSleep(long arg0, int arg1, int arg2) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void nap(long arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void reboot(boolean confirm, String reason, boolean wait) {
-        // pass for now.
-    }
-
-    @Override
-    public void rebootSafeMode(boolean confirm, boolean wait) {
-        // pass for now.
-    }
-
-    @Override
-    public void shutdown(boolean confirm, String reason, boolean wait) {
-        // pass for now.
-    }
-
-    @Override
-    public void releaseWakeLock(IBinder arg0, int arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void updateWakeLockUids(IBinder arg0, int[] arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setAttentionLight(boolean arg0, int arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setTemporaryScreenBrightnessSettingOverride(int arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setStayOnSetting(int arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void updateWakeLockWorkSource(IBinder arg0, WorkSource arg1, String arg2) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public boolean isWakeLockLevelSupported(int level) throws RemoteException {
-        // pass for now.
-        return true;
-    }
-
-    @Override
-    public void userActivity(long time, int event, int flags) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void wakeUp(long time, String reason, String opPackageName) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void boostScreenBrightness(long time) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public boolean isDeviceIdleMode() throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public boolean isLightDeviceIdleMode() throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public boolean isScreenBrightnessBoosted() throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public int getLastShutdownReason() {
-        return PowerManager.SHUTDOWN_REASON_UNKNOWN;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeSharedPreferences.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeSharedPreferences.java
deleted file mode 100644
index 132ff2f..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeSharedPreferences.java
+++ /dev/null
@@ -1,138 +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.layoutlib.bridge.android;
-
-import android.content.SharedPreferences;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * An empty shared preferences implementation which doesn't store anything. It always returns
- * null, 0 or false.
- */
-public class BridgeSharedPreferences implements SharedPreferences {
-    private Editor mEditor;
-
-    @Override
-    public Map<String, ?> getAll() {
-        return null;
-    }
-
-    @Override
-    public String getString(String key, String defValue) {
-        return null;
-    }
-
-    @Override
-    public Set<String> getStringSet(String key, Set<String> defValues) {
-        return null;
-    }
-
-    @Override
-    public int getInt(String key, int defValue) {
-        return 0;
-    }
-
-    @Override
-    public long getLong(String key, long defValue) {
-        return 0;
-    }
-
-    @Override
-    public float getFloat(String key, float defValue) {
-        return 0;
-    }
-
-    @Override
-    public boolean getBoolean(String key, boolean defValue) {
-        return false;
-    }
-
-    @Override
-    public boolean contains(String key) {
-        return false;
-    }
-
-    @Override
-    public Editor edit() {
-        if (mEditor != null) {
-            return mEditor;
-        }
-        mEditor = new Editor() {
-            @Override
-            public Editor putString(String key, String value) {
-                return null;
-            }
-
-            @Override
-            public Editor putStringSet(String key, Set<String> values) {
-                return null;
-            }
-
-            @Override
-            public Editor putInt(String key, int value) {
-                return null;
-            }
-
-            @Override
-            public Editor putLong(String key, long value) {
-                return null;
-            }
-
-            @Override
-            public Editor putFloat(String key, float value) {
-                return null;
-            }
-
-            @Override
-            public Editor putBoolean(String key, boolean value) {
-                return null;
-            }
-
-            @Override
-            public Editor remove(String key) {
-                return null;
-            }
-
-            @Override
-            public Editor clear() {
-                return null;
-            }
-
-            @Override
-            public boolean commit() {
-                return false;
-            }
-
-            @Override
-            public void apply() {
-            }
-        };
-        return mEditor;
-    }
-
-    @Override
-    public void registerOnSharedPreferenceChangeListener(
-            OnSharedPreferenceChangeListener listener) {
-    }
-
-    @Override
-    public void unregisterOnSharedPreferenceChangeListener(
-            OnSharedPreferenceChangeListener listener) {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
deleted file mode 100644
index ffbe7c4..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.internal.os.IResultReceiver;
-
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.MergedConfiguration;
-import android.view.DragEvent;
-import android.view.IWindow;
-
-/**
- * Implementation of {@link IWindow} to pass to the AttachInfo.
- */
-public final class BridgeWindow implements IWindow {
-
-    @Override
-    public void dispatchAppVisibility(boolean arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchGetNewSurface() throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void resized(Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5, Rect rect6,
-            boolean b, MergedConfiguration mergedConfig, Rect rect7, boolean b2, boolean b3, int i0)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void moved(int arg0, int arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
-            boolean sync) {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchWallpaperCommand(String action, int x, int y,
-            int z, Bundle extras, boolean sync) {
-        // pass for now.
-    }
-
-    @Override
-    public void closeSystemDialogs(String reason) {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchDragEvent(DragEvent event) {
-        // pass for now.
-    }
-
-    @Override
-    public void updatePointerIcon(float x, float y) {
-        // pass for now
-    }
-
-    @Override
-    public void dispatchSystemUiVisibilityChanged(int seq, int globalUi,
-            int localValue, int localChanges) {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchWindowShown() {
-    }
-
-    @Override
-    public void requestAppKeyboardShortcuts(
-            IResultReceiver receiver, int deviceId) throws RemoteException {
-    }
-
-    @Override
-    public void dispatchPointerCaptureChanged(boolean hasCapture) {
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // pass for now.
-        return null;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
deleted file mode 100644
index 2c88394..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.content.ClipData;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.MergedConfiguration;
-import android.view.IWindow;
-import android.view.IWindowId;
-import android.view.IWindowSession;
-import android.view.InputChannel;
-import android.view.Surface;
-import android.view.SurfaceView;
-import android.view.WindowManager.LayoutParams;
-
-/**
- * Implementation of {@link IWindowSession} so that mSession is not null in
- * the {@link SurfaceView}.
- */
-public final class BridgeWindowSession implements IWindowSession {
-
-    @Override
-    public int add(IWindow arg0, int seq, LayoutParams arg1, int arg2, Rect arg3, Rect arg4,
-            InputChannel outInputchannel)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public int addToDisplay(IWindow arg0, int seq, LayoutParams arg1, int arg2, int displayId,
-                            Rect arg3, Rect arg4, Rect arg5, InputChannel outInputchannel)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public int addWithoutInputChannel(IWindow arg0, int seq, LayoutParams arg1, int arg2,
-                                      Rect arg3, Rect arg4)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public int addToDisplayWithoutInputChannel(IWindow arg0, int seq, LayoutParams arg1, int arg2,
-                                               int displayId, Rect arg3, Rect arg4)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public void finishDrawing(IWindow arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public boolean getInTouchMode() throws RemoteException {
-        // pass for now.
-        return false;
-    }
-
-    @Override
-    public boolean performHapticFeedback(IWindow window, int effectId, boolean always) {
-        // pass for now.
-        return false;
-    }
-
-    @Override
-    public int relayout(IWindow iWindow, int i, LayoutParams layoutParams, int i2,
-            int i3, int i4, int i5, Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5,
-            Rect rect6, Rect rect7, MergedConfiguration mergedConfig, Surface surface)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public boolean outOfMemory(IWindow window) throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
-        // pass for now.
-    }
-
-    @Override
-    public void remove(IWindow arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setInTouchMode(boolean arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setTransparentRegion(IWindow arg0, Region arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setInsets(IWindow window, int touchable, Rect contentInsets,
-            Rect visibleInsets, Region touchableRegion) {
-        // pass for now.
-    }
-
-    @Override
-    public IBinder prepareDrag(IWindow window, int flags,
-            int thumbnailWidth, int thumbnailHeight, Surface outSurface)
-            throws RemoteException {
-        // pass for now
-        return null;
-    }
-
-    @Override
-    public boolean performDrag(IWindow window, IBinder dragToken,
-            int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
-            ClipData data)
-            throws RemoteException {
-        // pass for now
-        return false;
-    }
-
-    @Override
-    public boolean startMovingTask(IWindow window, float startX, float startY)
-            throws RemoteException {
-        // pass for now
-        return false;
-    }
-
-    @Override
-    public void reportDropResult(IWindow window, boolean consumed) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void cancelDragAndDrop(IBinder dragToken) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void dragRecipientEntered(IWindow window) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void dragRecipientExited(IWindow window) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void setWallpaperPosition(IBinder window, float x, float y,
-        float xStep, float yStep) {
-        // pass for now.
-    }
-
-    @Override
-    public void wallpaperOffsetsComplete(IBinder window) {
-        // pass for now.
-    }
-
-    @Override
-    public void setWallpaperDisplayOffset(IBinder windowToken, int x, int y) {
-        // pass for now.
-    }
-
-    @Override
-    public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
-            int z, Bundle extras, boolean sync) {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void wallpaperCommandComplete(IBinder window, Bundle result) {
-        // pass for now.
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void onRectangleOnScreenRequested(IBinder window, Rect rectangle) {
-        // pass for now.
-    }
-
-    @Override
-    public IWindowId getWindowId(IBinder window) throws RemoteException {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void pokeDrawLock(IBinder window) {
-        // pass for now.
-    }
-
-    @Override
-    public void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly) {
-        // pass for now.
-    }
-
-    @Override
-    public void updatePointerIcon(IWindow window) {
-        // pass for now.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
deleted file mode 100644
index ac8712e..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.res.XmlResourceParser;
-import android.util.AttributeSet;
-import android.util.BridgeXmlPullAttributes;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-
-/**
- * {@link BridgeXmlBlockParser} reimplements most of android.xml.XmlBlock.Parser.
- * It delegates to both an instance of {@link XmlPullParser} and an instance of
- * XmlPullAttributes (for the {@link AttributeSet} part).
- */
-public class BridgeXmlBlockParser implements XmlResourceParser {
-
-    private final XmlPullParser mParser;
-    private final BridgeXmlPullAttributes mAttrib;
-    private final BridgeContext mContext;
-    private final boolean mPlatformFile;
-
-    private boolean mStarted = false;
-    private int mEventType = START_DOCUMENT;
-
-    private boolean mPopped = true; // default to true in case it's not pushed.
-
-    /**
-     * Builds a {@link BridgeXmlBlockParser}.
-     * @param parser The XmlPullParser to get the content from.
-     * @param context the Context.
-     * @param platformFile Indicates whether the the file is a platform file or not.
-     */
-    public BridgeXmlBlockParser(XmlPullParser parser, BridgeContext context, boolean platformFile) {
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("CRTE " + parser.toString());
-        }
-
-        mParser = parser;
-        mContext = context;
-        mPlatformFile = platformFile;
-        mAttrib = new BridgeXmlPullAttributes(parser, context, mPlatformFile);
-
-        if (mContext != null) {
-            mContext.pushParser(this);
-            mPopped = false;
-        }
-    }
-
-    public XmlPullParser getParser() {
-        return mParser;
-    }
-
-    public boolean isPlatformFile() {
-        return mPlatformFile;
-    }
-
-    public Object getViewCookie() {
-        if (mParser instanceof ILayoutPullParser) {
-            return ((ILayoutPullParser)mParser).getViewCookie();
-        }
-
-        return null;
-    }
-
-    public void ensurePopped() {
-        if (mContext != null && mPopped == false) {
-            mContext.popParser();
-            mPopped = true;
-        }
-    }
-
-    // ------- XmlResourceParser implementation
-
-    @Override
-    public void setFeature(String name, boolean state)
-            throws XmlPullParserException {
-        if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) {
-            return;
-        }
-        if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name) && state) {
-            return;
-        }
-        throw new XmlPullParserException("Unsupported feature: " + name);
-    }
-
-    @Override
-    public boolean getFeature(String name) {
-        if (FEATURE_PROCESS_NAMESPACES.equals(name)) {
-            return true;
-        }
-        if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void setProperty(String name, Object value) throws XmlPullParserException {
-        throw new XmlPullParserException("setProperty() not supported");
-    }
-
-    @Override
-    public Object getProperty(String name) {
-        return null;
-    }
-
-    @Override
-    public void setInput(Reader in) throws XmlPullParserException {
-        mParser.setInput(in);
-    }
-
-    @Override
-    public void setInput(InputStream inputStream, String inputEncoding)
-            throws XmlPullParserException {
-        mParser.setInput(inputStream, inputEncoding);
-    }
-
-    @Override
-    public void defineEntityReplacementText(String entityName,
-            String replacementText) throws XmlPullParserException {
-        throw new XmlPullParserException(
-                "defineEntityReplacementText() not supported");
-    }
-
-    @Override
-    public String getNamespacePrefix(int pos) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespacePrefix() not supported");
-    }
-
-    @Override
-    public String getInputEncoding() {
-        return null;
-    }
-
-    @Override
-    public String getNamespace(String prefix) {
-        throw new RuntimeException("getNamespace() not supported");
-    }
-
-    @Override
-    public int getNamespaceCount(int depth) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespaceCount() not supported");
-    }
-
-    @Override
-    public String getPositionDescription() {
-        return "Binary XML file line #" + getLineNumber();
-    }
-
-    @Override
-    public String getNamespaceUri(int pos) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespaceUri() not supported");
-    }
-
-    @Override
-    public int getColumnNumber() {
-        return -1;
-    }
-
-    @Override
-    public int getDepth() {
-        return mParser.getDepth();
-    }
-
-    @Override
-    public String getText() {
-        return mParser.getText();
-    }
-
-    @Override
-    public int getLineNumber() {
-        return mParser.getLineNumber();
-    }
-
-    @Override
-    public int getEventType() {
-        return mEventType;
-    }
-
-    @Override
-    public boolean isWhitespace() throws XmlPullParserException {
-        // Original comment: whitespace was stripped by aapt.
-        return mParser.isWhitespace();
-    }
-
-    @Override
-    public String getPrefix() {
-        throw new RuntimeException("getPrefix not supported");
-    }
-
-    @Override
-    public char[] getTextCharacters(int[] holderForStartAndLength) {
-        String txt = getText();
-        char[] chars = null;
-        if (txt != null) {
-            holderForStartAndLength[0] = 0;
-            holderForStartAndLength[1] = txt.length();
-            chars = new char[txt.length()];
-            txt.getChars(0, txt.length(), chars, 0);
-        }
-        return chars;
-    }
-
-    @Override
-    public String getNamespace() {
-        return mParser.getNamespace();
-    }
-
-    @Override
-    public String getName() {
-        return mParser.getName();
-    }
-
-    @Override
-    public String getAttributeNamespace(int index) {
-        return mParser.getAttributeNamespace(index);
-    }
-
-    @Override
-    public String getAttributeName(int index) {
-        return mParser.getAttributeName(index);
-    }
-
-    @Override
-    public String getAttributePrefix(int index) {
-        throw new RuntimeException("getAttributePrefix not supported");
-    }
-
-    @Override
-    public boolean isEmptyElementTag() {
-        // XXX Need to detect this.
-        return false;
-    }
-
-    @Override
-    public int getAttributeCount() {
-        return mParser.getAttributeCount();
-    }
-
-    @Override
-    public String getAttributeValue(int index) {
-        return mParser.getAttributeValue(index);
-    }
-
-    @Override
-    public String getAttributeType(int index) {
-        return "CDATA";
-    }
-
-    @Override
-    public boolean isAttributeDefault(int index) {
-        return false;
-    }
-
-    @Override
-    public int nextToken() throws XmlPullParserException, IOException {
-        return next();
-    }
-
-    @Override
-    public String getAttributeValue(String namespace, String name) {
-        return mParser.getAttributeValue(namespace, name);
-    }
-
-    @Override
-    public int next() throws XmlPullParserException, IOException {
-        if (!mStarted) {
-            mStarted = true;
-
-            if (ParserFactory.LOG_PARSER) {
-                System.out.println("STRT " + mParser.toString());
-            }
-
-            return START_DOCUMENT;
-        }
-
-        int ev = mParser.next();
-
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("NEXT " + mParser.toString() + " " +
-                    eventTypeToString(mEventType) + " -> " + eventTypeToString(ev));
-        }
-
-        if (ev == END_TAG && mParser.getDepth() == 1) {
-            // done with parser remove it from the context stack.
-            ensurePopped();
-
-            if (ParserFactory.LOG_PARSER) {
-                System.out.println("");
-            }
-        }
-
-        mEventType = ev;
-        return ev;
-    }
-
-    public static String eventTypeToString(int eventType) {
-        switch (eventType) {
-            case START_DOCUMENT:
-                return "START_DOC";
-            case END_DOCUMENT:
-                return "END_DOC";
-            case START_TAG:
-                return "START_TAG";
-            case END_TAG:
-                return "END_TAG";
-            case TEXT:
-                return "TEXT";
-            case CDSECT:
-                return "CDSECT";
-            case ENTITY_REF:
-                return "ENTITY_REF";
-            case IGNORABLE_WHITESPACE:
-                return "IGNORABLE_WHITESPACE";
-            case PROCESSING_INSTRUCTION:
-                return "PROCESSING_INSTRUCTION";
-            case COMMENT:
-                return "COMMENT";
-            case DOCDECL:
-                return "DOCDECL";
-        }
-
-        return "????";
-    }
-
-    @Override
-    public void require(int type, String namespace, String name)
-            throws XmlPullParserException {
-        if (type != getEventType()
-                || (namespace != null && !namespace.equals(getNamespace()))
-                || (name != null && !name.equals(getName())))
-            throw new XmlPullParserException("expected " + TYPES[type]
-                    + getPositionDescription());
-    }
-
-    @Override
-    public String nextText() throws XmlPullParserException, IOException {
-        if (getEventType() != START_TAG) {
-            throw new XmlPullParserException(getPositionDescription()
-                    + ": parser must be on START_TAG to read next text", this,
-                    null);
-        }
-        int eventType = next();
-        if (eventType == TEXT) {
-            String result = getText();
-            eventType = next();
-            if (eventType != END_TAG) {
-                throw new XmlPullParserException(
-                        getPositionDescription()
-                                + ": event TEXT it must be immediately followed by END_TAG",
-                        this, null);
-            }
-            return result;
-        } else if (eventType == END_TAG) {
-            return "";
-        } else {
-            throw new XmlPullParserException(getPositionDescription()
-                    + ": parser must be on START_TAG or TEXT to read text",
-                    this, null);
-        }
-    }
-
-    @Override
-    public int nextTag() throws XmlPullParserException, IOException {
-        int eventType = next();
-        if (eventType == TEXT && isWhitespace()) { // skip whitespace
-            eventType = next();
-        }
-        if (eventType != START_TAG && eventType != END_TAG) {
-            throw new XmlPullParserException(getPositionDescription()
-                    + ": expected start or end tag", this, null);
-        }
-        return eventType;
-    }
-
-    // AttributeSet implementation
-
-
-    @Override
-    public void close() {
-        // pass
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
-        return mAttrib.getAttributeBooleanValue(index, defaultValue);
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(String namespace, String attribute,
-            boolean defaultValue) {
-        return mAttrib.getAttributeBooleanValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public float getAttributeFloatValue(int index, float defaultValue) {
-        return mAttrib.getAttributeFloatValue(index, defaultValue);
-    }
-
-    @Override
-    public float getAttributeFloatValue(String namespace, String attribute, float defaultValue) {
-        return mAttrib.getAttributeFloatValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(int index, int defaultValue) {
-        return mAttrib.getAttributeIntValue(index, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(String namespace, String attribute, int defaultValue) {
-        return mAttrib.getAttributeIntValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public int getAttributeListValue(int index, String[] options, int defaultValue) {
-        return mAttrib.getAttributeListValue(index, options, defaultValue);
-    }
-
-    @Override
-    public int getAttributeListValue(String namespace, String attribute,
-            String[] options, int defaultValue) {
-        return mAttrib.getAttributeListValue(namespace, attribute, options, defaultValue);
-    }
-
-    @Override
-    public int getAttributeNameResource(int index) {
-        return mAttrib.getAttributeNameResource(index);
-    }
-
-    @Override
-    public int getAttributeResourceValue(int index, int defaultValue) {
-        return mAttrib.getAttributeResourceValue(index, defaultValue);
-    }
-
-    @Override
-    public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
-        return mAttrib.getAttributeResourceValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
-        return mAttrib.getAttributeUnsignedIntValue(index, defaultValue);
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue) {
-        return mAttrib.getAttributeUnsignedIntValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public String getClassAttribute() {
-        return mAttrib.getClassAttribute();
-    }
-
-    @Override
-    public String getIdAttribute() {
-        return mAttrib.getIdAttribute();
-    }
-
-    @Override
-    public int getIdAttributeResourceValue(int defaultValue) {
-        return mAttrib.getIdAttributeResourceValue(defaultValue);
-    }
-
-    @Override
-    public int getStyleAttribute() {
-        return mAttrib.getStyleAttribute();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java
deleted file mode 100644
index 051de90..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java
+++ /dev/null
@@ -1,65 +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.layoutlib.bridge.android;
-
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderParams;
-import com.android.ide.common.rendering.api.SessionParams.Key;
-
-/**
- * This contains all known keys for the {@link RenderParams#getFlag(Key)}.
- * <p/>
- * The IDE has its own copy of this class which may be newer or older than this one.
- * <p/>
- * Constants should never be modified or removed from this class.
- */
-public final class RenderParamsFlags {
-
-    public static final Key<String> FLAG_KEY_ROOT_TAG =
-            new Key<String>("rootTag", String.class);
-    public static final Key<Boolean> FLAG_KEY_DISABLE_BITMAP_CACHING =
-            new Key<Boolean>("disableBitmapCaching", Boolean.class);
-    public static final Key<Boolean> FLAG_KEY_RENDER_ALL_DRAWABLE_STATES =
-            new Key<Boolean>("renderAllDrawableStates", Boolean.class);
-    /**
-     * To tell LayoutLib that the IDE supports RecyclerView.
-     * <p/>
-     * Default is false.
-     */
-    public static final Key<Boolean> FLAG_KEY_RECYCLER_VIEW_SUPPORT =
-            new Key<Boolean>("recyclerViewSupport", Boolean.class);
-    /**
-     * The application package name. Used via {@link LayoutlibCallback#getFlag(Key)}
-     */
-    public static final Key<String> FLAG_KEY_APPLICATION_PACKAGE =
-            new Key<String>("applicationPackage", String.class);
-    /**
-     * To tell LayoutLib that IDE supports providing XML Parser for a file (useful for getting in
-     * memory contents of the file). Used via {@link LayoutlibCallback#getFlag(Key)}
-     */
-    public static final Key<Boolean> FLAG_KEY_XML_FILE_PARSER_SUPPORT =
-            new Key<Boolean>("xmlFileParser", Boolean.class);
-    /**
-     * To tell LayoutLib to not render when creating a new session. This allows controlling when the first
-     * layout rendering will happen.
-     */
-    public static final Key<Boolean> FLAG_DO_NOT_RENDER_ON_CREATE =
-            new Key<Boolean>("doNotRenderOnCreate", Boolean.class);
-
-    // Disallow instances.
-    private RenderParamsFlags() {}
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/graphics/NopCanvas.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/graphics/NopCanvas.java
deleted file mode 100644
index 131aa17..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/graphics/NopCanvas.java
+++ /dev/null
@@ -1,307 +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.layoutlib.bridge.android.graphics;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.NinePatch;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.Picture;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.Rect;
-import android.graphics.RectF;
-
-/**
- * Canvas implementation that does not do any rendering
- */
-public class NopCanvas extends Canvas {
-    private boolean mIsInitialized = false;
-
-    public NopCanvas() {
-        super();
-        mIsInitialized = true;
-    }
-
-    @Override
-    public boolean isHardwareAccelerated() {
-        // We return true the first time so there are no allocations for the software renderer in
-        // the constructor
-        return !mIsInitialized;
-    }
-
-    @Override
-    public int save() {
-        return 0;
-    }
-
-    @Override
-    public int save(int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayer(RectF bounds, Paint paint) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayer(float left, float top, float right, float bottom, Paint paint,
-            int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayer(float left, float top, float right, float bottom, Paint paint) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayerAlpha(RectF bounds, int alpha) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
-            int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha) {
-        return 0;
-    }
-
-    @Override
-    public void restore() {
-    }
-
-    @Override
-    public int getSaveCount() {
-        return 0;
-    }
-
-    @Override
-    public void restoreToCount(int saveCount) {
-    }
-
-    @Override
-    public void drawRGB(int r, int g, int b) {
-    }
-
-    @Override
-    public void drawARGB(int a, int r, int g, int b) {
-    }
-
-    @Override
-    public void drawColor(int color) {
-    }
-
-    @Override
-    public void drawColor(int color, Mode mode) {
-    }
-
-    @Override
-    public void drawPaint(Paint paint) {
-    }
-
-    @Override
-    public void drawPoints(float[] pts, int offset, int count, Paint paint) {
-    }
-
-    @Override
-    public void drawPoints(float[] pts, Paint paint) {
-    }
-
-    @Override
-    public void drawPoint(float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
-    }
-
-    @Override
-    public void drawLines(float[] pts, int offset, int count, Paint paint) {
-    }
-
-    @Override
-    public void drawLines(float[] pts, Paint paint) {
-    }
-
-    @Override
-    public void drawRect(RectF rect, Paint paint) {
-    }
-
-    @Override
-    public void drawRect(Rect r, Paint paint) {
-    }
-
-    @Override
-    public void drawRect(float left, float top, float right, float bottom, Paint paint) {
-    }
-
-    @Override
-    public void drawOval(RectF oval, Paint paint) {
-    }
-
-    @Override
-    public void drawOval(float left, float top, float right, float bottom, Paint paint) {
-    }
-
-    @Override
-    public void drawCircle(float cx, float cy, float radius, Paint paint) {
-    }
-
-    @Override
-    public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
-            Paint paint) {
-    }
-
-    @Override
-    public void drawArc(float left, float top, float right, float bottom, float startAngle,
-            float sweepAngle, boolean useCenter, Paint paint) {
-    }
-
-    @Override
-    public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
-    }
-
-    @Override
-    public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
-            Paint paint) {
-    }
-
-    @Override
-    public void drawPath(Path path, Paint paint) {
-    }
-
-    @Override
-    protected void throwIfCannotDraw(Bitmap bitmap) {
-    }
-
-    @Override
-    public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
-    }
-
-    @Override
-    public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(int[] colors, int offset, int stride, float x, float y, int width,
-            int height, boolean hasAlpha, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(int[] colors, int offset, int stride, int x, int y, int width,
-            int height, boolean hasAlpha, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
-            int vertOffset, int[] colors, int colorOffset, Paint paint) {
-    }
-
-    @Override
-    public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset,
-            float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices,
-            int indexOffset, int indexCount, Paint paint) {
-    }
-
-    @Override
-    public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawText(String text, float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawText(String text, int start, int end, float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount,
-            float x, float y, boolean isRtl, Paint paint) {
-    }
-
-    @Override
-    public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd,
-            float x, float y, boolean isRtl, Paint paint) {
-    }
-
-    @Override
-    public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) {
-    }
-
-    @Override
-    public void drawPosText(String text, float[] pos, Paint paint) {
-    }
-
-    @Override
-    public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset,
-            float vOffset, Paint paint) {
-    }
-
-    @Override
-    public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) {
-    }
-
-    @Override
-    public void drawPicture(Picture picture) {
-    }
-
-    @Override
-    public void drawPicture(Picture picture, RectF dst) {
-    }
-
-    @Override
-    public void drawPicture(Picture picture, Rect dst) {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java
deleted file mode 100644
index aa873a6..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java
+++ /dev/null
@@ -1,60 +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.layoutlib.bridge.android.support;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.view.View;
-
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
-
-/**
- * Utility class for working with the design support lib.
- */
-public class DesignLibUtil {
-
-    private static final String PKG_PREFIX = "android.support.design.widget.";
-    public static final String CN_COORDINATOR_LAYOUT = PKG_PREFIX + "CoordinatorLayout";
-    public static final String CN_APPBAR_LAYOUT = PKG_PREFIX + "AppBarLayout";
-    public static final String CN_COLLAPSING_TOOLBAR_LAYOUT =
-            PKG_PREFIX + "CollapsingToolbarLayout";
-    public static final String CN_TOOLBAR = "android.support.v7.widget.Toolbar";
-    public static final int SCROLL_AXIS_VERTICAL = 1 << 1;
-
-    /**
-     * Tries to set the title of a view. This is used to set the title in a
-     * CollapsingToolbarLayout.
-     * <p/>
-     * Any exceptions thrown during the process are logged in {@link Bridge#getLog()}
-     */
-    public static void setTitle(@NonNull View view, @Nullable String title) {
-        if (title == null) {
-            return;
-        }
-        try {
-            invoke(getMethod(view.getClass(), "setTitle", CharSequence.class), view, title);
-        } catch (ReflectionException e) {
-            Bridge.getLog().warning(LayoutLog.TAG_INFO,
-                    "Error occurred while trying to set title.", e);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java
deleted file mode 100644
index 40d3811..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java
+++ /dev/null
@@ -1,63 +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.layoutlib.bridge.android.support;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
-
-import android.annotation.Nullable;
-import android.view.View;
-
-import static android.view.Gravity.END;
-import static android.view.Gravity.LEFT;
-import static android.view.Gravity.RIGHT;
-import static android.view.Gravity.START;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getCause;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
-
-public class DrawerLayoutUtil {
-
-    public static final String CN_DRAWER_LAYOUT = "android.support.v4.widget.DrawerLayout";
-
-    public static void openDrawer(View drawerLayout, @Nullable String drawerGravity) {
-        int gravity = -1;
-        if ("left".equals(drawerGravity)) {
-            gravity = LEFT;
-        } else if ("right".equals(drawerGravity)) {
-            gravity = RIGHT;
-        } else if ("start".equals(drawerGravity)) {
-            gravity = START;
-        } else if ("end".equals(drawerGravity)) {
-            gravity = END;
-        }
-        if (gravity > 0) {
-            openDrawer(drawerLayout, gravity);
-        }
-    }
-
-    private static void openDrawer(View drawerLayout, int gravity) {
-        try {
-            invoke(getMethod(drawerLayout.getClass(), "openDrawer", int.class), drawerLayout,
-                    gravity);
-        } catch (ReflectionException e) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to open navigation drawer",
-                    getCause(e), null);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
deleted file mode 100644
index ab27819..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
+++ /dev/null
@@ -1,130 +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.layoutlib.bridge.android.support;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.util.ReflectionUtils;
-import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.view.View;
-
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getCause;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
-
-/**
- * Utility class for working with android.support.v7.widget.RecyclerView
- */
-public class RecyclerViewUtil {
-
-    private static final String RV_PKG_PREFIX = "android.support.v7.widget.";
-    public static final String CN_RECYCLER_VIEW = RV_PKG_PREFIX + "RecyclerView";
-    private static final String CN_LAYOUT_MANAGER = CN_RECYCLER_VIEW + "$LayoutManager";
-    private static final String CN_ADAPTER = CN_RECYCLER_VIEW + "$Adapter";
-
-    // LinearLayoutManager related constants.
-    private static final String CN_LINEAR_LAYOUT_MANAGER = RV_PKG_PREFIX + "LinearLayoutManager";
-    private static final Class<?>[] LLM_CONSTRUCTOR_SIGNATURE = new Class<?>[]{Context.class};
-
-    /**
-     * Tries to create an Adapter ({@code android.support.v7.widget.RecyclerView.Adapter} and a
-     * LayoutManager {@code RecyclerView.LayoutManager} and assign these to the {@code RecyclerView}
-     * that is passed.
-     * <p/>
-     * Any exceptions thrown during the process are logged in {@link Bridge#getLog()}
-     */
-    public static void setAdapter(@NonNull View recyclerView, @NonNull BridgeContext context,
-            @NonNull LayoutlibCallback layoutlibCallback, int adapterLayout) {
-        try {
-            setLayoutManager(recyclerView, context, layoutlibCallback);
-            Object adapter = createAdapter(layoutlibCallback);
-            if (adapter != null) {
-                setProperty(recyclerView, CN_ADAPTER, adapter, "setAdapter");
-                setProperty(adapter, int.class, adapterLayout, "setLayoutId");
-            }
-        } catch (ReflectionException e) {
-            Throwable cause = getCause(e);
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Error occurred while trying to setup RecyclerView.", cause, null);
-        }
-    }
-
-    private static void setLayoutManager(@NonNull View recyclerView, @NonNull BridgeContext context,
-            @NonNull LayoutlibCallback callback) throws ReflectionException {
-        if (getLayoutManager(recyclerView) == null) {
-            // Only set the layout manager if not already set by the recycler view.
-            Object layoutManager = createLayoutManager(context, callback);
-            if (layoutManager != null) {
-                setProperty(recyclerView, CN_LAYOUT_MANAGER, layoutManager, "setLayoutManager");
-            }
-        }
-    }
-
-    /** Creates a LinearLayoutManager using the provided context. */
-    @Nullable
-    private static Object createLayoutManager(@NonNull Context context,
-            @NonNull LayoutlibCallback callback)
-            throws ReflectionException {
-        try {
-            return callback.loadView(CN_LINEAR_LAYOUT_MANAGER, LLM_CONSTRUCTOR_SIGNATURE,
-                    new Object[]{context});
-        } catch (Exception e) {
-            throw new ReflectionException(e);
-        }
-    }
-
-    @Nullable
-    private static Object getLayoutManager(View recyclerView) throws ReflectionException {
-        return invoke(getMethod(recyclerView.getClass(), "getLayoutManager"), recyclerView);
-    }
-
-    @Nullable
-    private static Object createAdapter(@NonNull LayoutlibCallback layoutlibCallback)
-            throws ReflectionException {
-        Boolean ideSupport =
-                layoutlibCallback.getFlag(RenderParamsFlags.FLAG_KEY_RECYCLER_VIEW_SUPPORT);
-        if (ideSupport != Boolean.TRUE) {
-            return null;
-        }
-        try {
-            return layoutlibCallback.loadClass(CN_ADAPTER, new Class[0], new Object[0]);
-        } catch (Exception e) {
-            throw new ReflectionException(e);
-        }
-    }
-
-    private static void setProperty(@NonNull Object object, @NonNull String propertyClassName,
-      @NonNull Object propertyValue, @NonNull String propertySetter)
-            throws ReflectionException {
-        Class<?> propertyClass = ReflectionUtils.getClassInstance(propertyValue, propertyClassName);
-        setProperty(object, propertyClass, propertyValue, propertySetter);
-    }
-
-    private static void setProperty(@NonNull Object object, @NonNull Class<?> propertyClass,
-            @Nullable Object propertyValue, @NonNull String propertySetter)
-            throws ReflectionException {
-        invoke(getMethod(object.getClass(), propertySetter, propertyClass), object, propertyValue);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java
deleted file mode 100644
index 6ad9efc..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java
+++ /dev/null
@@ -1,282 +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.layoutlib.bridge.android.support;
-
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.view.ContextThemeWrapper;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.LinearLayout.LayoutParams;
-import android.widget.ScrollView;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getAccessibleMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getClassInstance;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
-
-/**
- * Class with utility methods to instantiate Preferences provided by the support library.
- * This class uses reflection to access the support preference objects so it heavily depends on
- * the API being stable.
- */
-public class SupportPreferencesUtil {
-    private static final String PREFERENCE_PKG = "android.support.v7.preference";
-    private static final String PREFERENCE_MANAGER = PREFERENCE_PKG + ".PreferenceManager";
-    private static final String PREFERENCE_GROUP = PREFERENCE_PKG + ".PreferenceGroup";
-    private static final String PREFERENCE_GROUP_ADAPTER =
-      PREFERENCE_PKG + ".PreferenceGroupAdapter";
-    private static final String PREFERENCE_INFLATER = PREFERENCE_PKG + ".PreferenceInflater";
-
-    private SupportPreferencesUtil() {
-    }
-
-    @NonNull
-    private static Object instantiateClass(@NonNull LayoutlibCallback callback,
-            @NonNull String className, @Nullable Class[] constructorSignature,
-            @Nullable Object[] constructorArgs) throws ReflectionException {
-        try {
-            Object instance = callback.loadClass(className, constructorSignature, constructorArgs);
-            if (instance == null) {
-                throw new ClassNotFoundException(className + " class not found");
-            }
-            return instance;
-        } catch (ClassNotFoundException e) {
-            throw new ReflectionException(e);
-        }
-    }
-
-    @NonNull
-    private static Object createPreferenceGroupAdapter(@NonNull LayoutlibCallback callback,
-            @NonNull Object preferenceScreen) throws ReflectionException {
-        Class<?> preferenceGroupClass = getClassInstance(preferenceScreen, PREFERENCE_GROUP);
-
-        return instantiateClass(callback, PREFERENCE_GROUP_ADAPTER,
-                new Class[]{preferenceGroupClass}, new Object[]{preferenceScreen});
-    }
-
-    @NonNull
-    private static Object createInflatedPreference(@NonNull LayoutlibCallback callback,
-      @NonNull Context context, @NonNull XmlPullParser parser, @NonNull Object preferenceScreen,
-      @NonNull Object preferenceManager) throws ReflectionException {
-        Class<?> preferenceGroupClass = getClassInstance(preferenceScreen, PREFERENCE_GROUP);
-        Object preferenceInflater = instantiateClass(callback, PREFERENCE_INFLATER,
-          new Class[]{Context.class, preferenceManager.getClass()},
-          new Object[]{context, preferenceManager});
-        Object inflatedPreference =
-                invoke(getAccessibleMethod(preferenceInflater.getClass(), "inflate",
-                        XmlPullParser.class, preferenceGroupClass), preferenceInflater, parser,
-                        null);
-
-        if (inflatedPreference == null) {
-            throw new ReflectionException("inflate method returned null");
-        }
-
-        return inflatedPreference;
-    }
-
-    /**
-     * Returns a themed wrapper context of {@link BridgeContext} with the theme specified in
-     * ?attr/preferenceTheme applied to it.
-     */
-    @Nullable
-    private static Context getThemedContext(@NonNull BridgeContext bridgeContext) {
-        RenderResources resources = bridgeContext.getRenderResources();
-        ResourceValue preferenceTheme = resources.findItemInTheme("preferenceTheme", false);
-
-        if (preferenceTheme != null) {
-            // resolve it, if needed.
-            preferenceTheme = resources.resolveResValue(preferenceTheme);
-        }
-        if (preferenceTheme instanceof StyleResourceValue) {
-            int styleId = bridgeContext.getDynamicIdByStyle(((StyleResourceValue) preferenceTheme));
-            if (styleId != 0) {
-                return new ContextThemeWrapper(bridgeContext, styleId);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a {@link LinearLayout} containing all the UI widgets representing the preferences
-     * passed in the group adapter.
-     */
-    @Nullable
-    private static LinearLayout setUpPreferencesListView(@NonNull BridgeContext bridgeContext,
-            @NonNull Context themedContext, @NonNull ArrayList<Object> viewCookie,
-            @NonNull Object preferenceGroupAdapter) throws ReflectionException {
-        // Setup the LinearLayout that will contain the preferences
-        LinearLayout listView = new LinearLayout(themedContext);
-        listView.setOrientation(LinearLayout.VERTICAL);
-        listView.setLayoutParams(
-                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
-
-        if (!viewCookie.isEmpty()) {
-            bridgeContext.addViewKey(listView, viewCookie.get(0));
-        }
-
-        // Get all the preferences and add them to the LinearLayout
-        Integer preferencesCount =
-                (Integer) invoke(getMethod(preferenceGroupAdapter.getClass(), "getItemCount"),
-                        preferenceGroupAdapter);
-        if (preferencesCount == null) {
-            return listView;
-        }
-
-        Method getItemId = getMethod(preferenceGroupAdapter.getClass(), "getItemId", int.class);
-        Method getItemViewType =
-                getMethod(preferenceGroupAdapter.getClass(), "getItemViewType", int.class);
-        Method onCreateViewHolder =
-                getMethod(preferenceGroupAdapter.getClass(), "onCreateViewHolder", ViewGroup.class,
-                        int.class);
-        for (int i = 0; i < preferencesCount; i++) {
-            Long id = (Long) invoke(getItemId, preferenceGroupAdapter, i);
-            if (id == null) {
-                continue;
-            }
-
-            // Get the type of the preference layout and bind it to a newly created view holder
-            Integer type = (Integer) invoke(getItemViewType, preferenceGroupAdapter, i);
-            Object viewHolder =
-                    invoke(onCreateViewHolder, preferenceGroupAdapter, listView, type);
-            if (viewHolder == null) {
-                continue;
-            }
-            invoke(getMethod(preferenceGroupAdapter.getClass(), "onBindViewHolder",
-                    viewHolder.getClass(), int.class), preferenceGroupAdapter, viewHolder, i);
-
-            try {
-                // Get the view from the view holder and add it to our layout
-                View itemView =
-                        (View) viewHolder.getClass().getField("itemView").get(viewHolder);
-
-                int arrayPosition = id.intValue() - 1; // IDs are 1 based
-                if (arrayPosition >= 0 && arrayPosition < viewCookie.size()) {
-                    bridgeContext.addViewKey(itemView, viewCookie.get(arrayPosition));
-                }
-                listView.addView(itemView);
-            } catch (IllegalAccessException | NoSuchFieldException ignored) {
-            }
-        }
-
-        return listView;
-    }
-
-    /**
-     * Inflates a preferences layout using the support library. If the support library is not
-     * available, this method will return null without advancing the parsers.
-     */
-    @Nullable
-    public static View inflatePreference(@NonNull BridgeContext bridgeContext,
-            @NonNull XmlPullParser parser, @Nullable ViewGroup root) {
-        try {
-            LayoutlibCallback callback = bridgeContext.getLayoutlibCallback();
-
-            Context context = getThemedContext(bridgeContext);
-            if (context == null) {
-                // Probably we couldn't find the "preferenceTheme" in the theme
-                return null;
-            }
-
-            // Create PreferenceManager
-            Object preferenceManager =
-                    instantiateClass(callback, PREFERENCE_MANAGER, new Class[]{Context.class},
-                            new Object[]{context});
-
-            // From this moment on, we can assume that we found the support library and that
-            // nothing should fail
-
-            // Create PreferenceScreen
-            Object preferenceScreen =
-                    invoke(getMethod(preferenceManager.getClass(), "createPreferenceScreen",
-                            Context.class), preferenceManager, context);
-            if (preferenceScreen == null) {
-                return null;
-            }
-
-            // Setup a parser that stores the list of cookies in the same order as the preferences
-            // are inflated. That way we can later reconstruct the list using the preference id
-            // since they are sequential and start in 1.
-            ArrayList<Object> viewCookie = new ArrayList<>();
-            if (parser instanceof BridgeXmlBlockParser) {
-                // Setup a parser that stores the XmlTag
-                parser = new BridgeXmlBlockParser(parser, null, false) {
-                    @Override
-                    public Object getViewCookie() {
-                        return ((BridgeXmlBlockParser) getParser()).getViewCookie();
-                    }
-
-                    @Override
-                    public int next() throws XmlPullParserException, IOException {
-                        int ev = super.next();
-                        if (ev == XmlPullParser.START_TAG) {
-                            viewCookie.add(this.getViewCookie());
-                        }
-
-                        return ev;
-                    }
-                };
-            }
-
-            // Create the PreferenceInflater
-            Object inflatedPreference =
-              createInflatedPreference(callback, context, parser, preferenceScreen,
-                preferenceManager);
-
-            // Setup the RecyclerView (set adapter and layout manager)
-            Object preferenceGroupAdapter =
-                    createPreferenceGroupAdapter(callback, inflatedPreference);
-
-            // Instead of just setting the group adapter as adapter for a RecyclerView, we manually
-            // get all the items and add them to a LinearLayout. This allows us to set the view
-            // cookies so the preferences are correctly linked to their XML.
-            LinearLayout listView = setUpPreferencesListView(bridgeContext, context, viewCookie,
-                    preferenceGroupAdapter);
-
-            ScrollView scrollView = new ScrollView(context);
-            scrollView.setLayoutParams(
-              new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
-            scrollView.addView(listView);
-
-            if (root != null) {
-                root.addView(scrollView);
-            }
-
-            return scrollView;
-        } catch (ReflectionException e) {
-            return null;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
deleted file mode 100644
index d7d16cf..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.layoutlib.bridge.android.view;
-
-import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.Display.Mode;
-import android.view.DisplayAdjustments;
-import android.view.DisplayInfo;
-import android.view.View;
-import android.view.WindowManager;
-
-public class WindowManagerImpl implements WindowManager {
-
-    private final DisplayMetrics mMetrics;
-    private final Display mDisplay;
-
-    public WindowManagerImpl(DisplayMetrics metrics) {
-        mMetrics = metrics;
-
-        DisplayInfo info = new DisplayInfo();
-        info.logicalHeight = mMetrics.heightPixels;
-        info.logicalWidth = mMetrics.widthPixels;
-        info.supportedModes = new Mode[] {
-                new Mode(0, mMetrics.widthPixels, mMetrics.heightPixels, 60f)
-        };
-        mDisplay = new Display(null, Display.DEFAULT_DISPLAY, info,
-                DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
-    }
-
-    @Override
-    public Display getDefaultDisplay() {
-        return mDisplay;
-    }
-
-
-    @Override
-    public void addView(View arg0, android.view.ViewGroup.LayoutParams arg1) {
-        // pass
-    }
-
-    @Override
-    public void removeView(View arg0) {
-        // pass
-    }
-
-    @Override
-    public void updateViewLayout(View arg0, android.view.ViewGroup.LayoutParams arg1) {
-        // pass
-    }
-
-
-    @Override
-    public void removeViewImmediate(View arg0) {
-        // pass
-    }
-
-    @Override
-    public void requestAppKeyboardShortcuts(
-            KeyboardShortcutsReceiver receiver, int deviceId) {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
deleted file mode 100644
index cdcf0ea..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
+++ /dev/null
@@ -1,207 +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.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.ResourceType;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.view.ContextThemeWrapper;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-
-/**
- * Assumes that the AppCompat library is present in the project's classpath and creates an
- * actionbar around it.
- */
-public class AppCompatActionBar extends BridgeActionBar {
-
-    private Object mWindowDecorActionBar;
-    private static final String WINDOW_ACTION_BAR_CLASS = "android.support.v7.internal.app.WindowDecorActionBar";
-    // This is used on v23.1.1 and later.
-    private static final String WINDOW_ACTION_BAR_CLASS_NEW = "android.support.v7.app.WindowDecorActionBar";
-    private Class<?> mWindowActionBarClass;
-
-    /**
-     * Inflate the action bar and attach it to {@code parentView}
-     */
-    public AppCompatActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) {
-        super(context, params);
-        int contentRootId = context.getProjectResourceValue(ResourceType.ID,
-                "action_bar_activity_content", 0);
-        View contentView = getDecorContent().findViewById(contentRootId);
-        if (contentView != null) {
-            assert contentView instanceof FrameLayout;
-            setContentRoot((FrameLayout) contentView);
-        } else {
-            // Something went wrong. Create a new FrameLayout in the enclosing layout.
-            FrameLayout contentRoot = new FrameLayout(context);
-            setMatchParent(contentRoot);
-            if (mEnclosingLayout != null) {
-                mEnclosingLayout.addView(contentRoot);
-            }
-            setContentRoot(contentRoot);
-        }
-        try {
-            Class[] constructorParams = {View.class};
-            Object[] constructorArgs = {getDecorContent()};
-            LayoutlibCallback callback = params.getLayoutlibCallback();
-
-            // Check if the old action bar class is present.
-            String actionBarClass = WINDOW_ACTION_BAR_CLASS;
-            try {
-                callback.findClass(actionBarClass);
-            } catch (ClassNotFoundException expected) {
-                // Failed to find the old class, use the newer one.
-                actionBarClass = WINDOW_ACTION_BAR_CLASS_NEW;
-            }
-
-            mWindowDecorActionBar = callback.loadView(actionBarClass,
-                    constructorParams, constructorArgs);
-            mWindowActionBarClass = mWindowDecorActionBar == null ? null :
-                    mWindowDecorActionBar.getClass();
-            setupActionBar();
-        } catch (Exception e) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN,
-                    "Failed to load AppCompat ActionBar with unknown error.", e);
-        }
-    }
-
-    @Override
-    protected ResourceValue getLayoutResource(BridgeContext context) {
-        // We always assume that the app has requested the action bar.
-        return context.getRenderResources().getProjectResource(ResourceType.LAYOUT,
-                "abc_screen_toolbar");
-    }
-
-    @Override
-    protected LayoutInflater getInflater(BridgeContext context) {
-        // Other than the resource resolution part, the code has been taken from the support
-        // library. see code from line 269 onwards in
-        // https://android.googlesource.com/platform/frameworks/support/+/android-5.1.0_r1/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateBase.java
-        Context themedContext = context;
-        RenderResources resources = context.getRenderResources();
-        ResourceValue actionBarTheme = resources.findItemInTheme("actionBarTheme", false);
-        if (actionBarTheme != null) {
-            // resolve it, if needed.
-            actionBarTheme = resources.resolveResValue(actionBarTheme);
-        }
-        if (actionBarTheme instanceof StyleResourceValue) {
-            int styleId = context.getDynamicIdByStyle(((StyleResourceValue) actionBarTheme));
-            if (styleId != 0) {
-                themedContext = new ContextThemeWrapper(context, styleId);
-            }
-        }
-        return LayoutInflater.from(themedContext);
-    }
-
-    @Override
-    protected void setTitle(CharSequence title) {
-        if (title != null && mWindowDecorActionBar != null) {
-            Method setTitle = getMethod(mWindowActionBarClass, "setTitle", CharSequence.class);
-            invoke(setTitle, mWindowDecorActionBar, title);
-        }
-    }
-
-    @Override
-    protected void setSubtitle(CharSequence subtitle) {
-        if (subtitle != null && mWindowDecorActionBar != null) {
-            Method setSubtitle = getMethod(mWindowActionBarClass, "setSubtitle", CharSequence.class);
-            invoke(setSubtitle, mWindowDecorActionBar, subtitle);
-        }
-    }
-
-    @Override
-    protected void setIcon(String icon) {
-        // Do this only if the action bar doesn't already have an icon.
-        if (icon != null && !icon.isEmpty() && mWindowDecorActionBar != null) {
-            if (invoke(getMethod(mWindowActionBarClass, "hasIcon"), mWindowDecorActionBar)
-                    == Boolean.TRUE) {
-                Drawable iconDrawable = getDrawable(icon, false);
-                if (iconDrawable != null) {
-                    Method setIcon = getMethod(mWindowActionBarClass, "setIcon", Drawable.class);
-                    invoke(setIcon, mWindowDecorActionBar, iconDrawable);
-                }
-            }
-        }
-    }
-
-    @Override
-    protected void setHomeAsUp(boolean homeAsUp) {
-        if (mWindowDecorActionBar != null) {
-            Method setHomeAsUp = getMethod(mWindowActionBarClass,
-                    "setDefaultDisplayHomeAsUpEnabled", boolean.class);
-            invoke(setHomeAsUp, mWindowDecorActionBar, homeAsUp);
-        }
-    }
-
-    @Override
-    public void createMenuPopup() {
-        // it's hard to add menus to appcompat's actionbar, since it'll use a lot of reflection.
-        // so we skip it for now.
-    }
-
-    @Nullable
-    private static Method getMethod(Class<?> owner, String name, Class<?>... parameterTypes) {
-        try {
-            return owner == null ? null : owner.getMethod(name, parameterTypes);
-        } catch (NoSuchMethodException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    @Nullable
-    private static Object invoke(Method method, Object owner, Object... args) {
-        try {
-            return method == null ? null : method.invoke(owner, args);
-        } catch (InvocationTargetException e) {
-            e.printStackTrace();
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    // TODO: this is duplicated from FrameworkActionBarWrapper$WindowActionBarWrapper
-    @Nullable
-    private Drawable getDrawable(@NonNull String name, boolean isFramework) {
-        RenderResources res = mBridgeContext.getRenderResources();
-        ResourceValue value = res.findResValue(name, isFramework);
-        value = res.resolveResValue(value);
-        if (value != null) {
-            return ResourceHelper.getDrawable(value, mBridgeContext);
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
deleted file mode 100644
index a439e7d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
+++ /dev/null
@@ -1,177 +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.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.MockView;
-import com.android.layoutlib.bridge.android.BridgeContext;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.FrameLayout;
-import android.widget.RelativeLayout;
-
-/**
- * An abstraction over two implementations of the ActionBar - framework and appcompat.
- */
-public abstract class BridgeActionBar {
-    // Store a reference to the context so that we don't have to cast it repeatedly.
-    @NonNull protected final BridgeContext mBridgeContext;
-    @NonNull protected final SessionParams mParams;
-    // A Layout that contains the inflated action bar. The menu popup is added to this layout.
-    @Nullable protected final ViewGroup mEnclosingLayout;
-
-    private final View mDecorContent;
-    private final ActionBarCallback mCallback;
-
-    @SuppressWarnings("NullableProblems")  // Should be initialized by subclasses.
-    @NonNull private FrameLayout mContentRoot;
-
-    public BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) {
-        mBridgeContext = context;
-        mParams = params;
-        mCallback = params.getLayoutlibCallback().getActionBarCallback();
-        ResourceValue layoutName = getLayoutResource(context);
-
-        int layoutId = 0;
-        if (layoutName == null) {
-            assert false : "Unable to find the layout for Action Bar.";
-        }
-        else {
-            if (layoutName.isFramework()) {
-                layoutId = context.getFrameworkResourceValue(layoutName.getResourceType(),
-                        layoutName.getName(), 0);
-            } else {
-                layoutId = context.getProjectResourceValue(layoutName.getResourceType(),
-                        layoutName.getName(), 0);
-
-            }
-        }
-        if (layoutId == 0) {
-            assert false : String.format("Unable to resolve attribute \"%1$s\" of type \"%2$s\"",
-                    layoutName.getName(), layoutName.getResourceType());
-            mDecorContent = new MockView(context);
-            mEnclosingLayout = null;
-        }
-        else {
-            if (mCallback.isOverflowPopupNeeded()) {
-                // Create a RelativeLayout around the action bar, to which the overflow popup may be
-                // added.
-                mEnclosingLayout = new RelativeLayout(mBridgeContext);
-                setMatchParent(mEnclosingLayout);
-            } else {
-                mEnclosingLayout = null;
-            }
-
-            // Inflate action bar layout.
-            mDecorContent = getInflater(context).inflate(layoutId, mEnclosingLayout,
-                    mEnclosingLayout != null);
-        }
-    }
-
-    /**
-     * Returns the Layout Resource that should be used to inflate the action bar. This layout
-     * should cover the complete screen, and have a FrameLayout included, where the content will
-     * be inflated.
-     */
-    protected abstract ResourceValue getLayoutResource(BridgeContext context);
-
-    protected LayoutInflater getInflater(BridgeContext context) {
-        return LayoutInflater.from(context);
-    }
-
-    protected void setContentRoot(@NonNull FrameLayout contentRoot) {
-        mContentRoot = contentRoot;
-    }
-
-    @NonNull
-    public FrameLayout getContentRoot() {
-        return mContentRoot;
-    }
-
-    /**
-     * Returns the view inflated. This should contain both the ActionBar and the app content in it.
-     */
-    protected View getDecorContent() {
-        return mDecorContent;
-    }
-
-    /** Setup things like the title, subtitle, icon etc. */
-    protected void setupActionBar() {
-        setTitle();
-        setSutTitle();
-        setIcon();
-        setHomeAsUp(mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP);
-    }
-
-    protected abstract void setTitle(CharSequence title);
-    protected abstract void setSubtitle(CharSequence subtitle);
-    protected abstract void setIcon(String icon);
-    protected abstract void setHomeAsUp(boolean homeAsUp);
-
-    private void setTitle() {
-        RenderResources res = mBridgeContext.getRenderResources();
-
-        String title = mParams.getAppLabel();
-        ResourceValue titleValue = res.findResValue(title, false);
-        if (titleValue != null && titleValue.getValue() != null) {
-            setTitle(titleValue.getValue());
-        } else {
-            setTitle(title);
-        }
-    }
-
-    private void setSutTitle() {
-        String subTitle = mCallback.getSubTitle();
-        if (subTitle != null) {
-            setSubtitle(subTitle);
-        }
-    }
-
-    private void setIcon() {
-        String appIcon = mParams.getAppIcon();
-        if (appIcon != null) {
-            setIcon(appIcon);
-        }
-    }
-
-    public abstract void createMenuPopup();
-
-    /**
-     * The root view that represents the action bar and possibly the content included in it.
-     */
-    public View getRootView() {
-        return mEnclosingLayout == null ? mDecorContent : mEnclosingLayout;
-    }
-
-    public ActionBarCallback getCallBack() {
-        return mCallback;
-    }
-
-    protected static void setMatchParent(View view) {
-        view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
-                LayoutParams.MATCH_PARENT));
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
deleted file mode 100644
index 7f8d992..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
+++ /dev/null
@@ -1,137 +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.layoutlib.bridge.bars;
-
-import android.os._Original_Build.VERSION_CODES;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import static android.os._Original_Build.VERSION_CODES.*;
-
-/**
- * Various helper methods to simulate older versions of platform.
- */
-public class Config {
-
-    // each of these resource dirs must end in '/'
-    private static final String GINGERBREAD_DIR      = "/bars/v9/";
-    private static final String JELLYBEAN_DIR        = "/bars/v18/";
-    private static final String KITKAT_DIR           = "/bars/v19/";
-    private static final String DEFAULT_RESOURCE_DIR = "/bars/v21/";
-
-    private static final List<String> sDefaultResourceDir =
-            Collections.singletonList(DEFAULT_RESOURCE_DIR);
-
-    private static final int WHITE = 0xFFFFFFFF;
-    private static final int BLACK = 0xFF000000;
-
-    public static boolean showOnScreenNavBar(int platformVersion) {
-        return isGreaterOrEqual(platformVersion, ICE_CREAM_SANDWICH);
-    }
-
-    public static int getStatusBarColor(int platformVersion) {
-        // return white for froyo and earlier; black otherwise.
-        return isGreaterOrEqual(platformVersion, GINGERBREAD) ? BLACK : WHITE;
-    }
-
-    public static List<String> getResourceDirs(int platformVersion) {
-        // Special case the most used scenario.
-        if (platformVersion == 0) {
-            return sDefaultResourceDir;
-        }
-        List<String> list = new ArrayList<String>(4);
-        // Gingerbread - uses custom battery and wifi icons.
-        if (platformVersion <= GINGERBREAD) {
-            list.add(GINGERBREAD_DIR);
-        }
-        // ICS - JellyBean uses custom battery, wifi.
-        if (platformVersion <= JELLY_BEAN_MR2) {
-            list.add(JELLYBEAN_DIR);
-        }
-        // KitKat - uses custom wifi and nav icons.
-        if (platformVersion <= KITKAT) {
-            list.add(KITKAT_DIR);
-        }
-        list.add(DEFAULT_RESOURCE_DIR);
-
-        return Collections.unmodifiableList(list);
-    }
-
-    public static String getTime(int platformVersion) {
-        if (isGreaterOrEqual(platformVersion, N)) {
-            return "7:00";
-        }
-        if (platformVersion < GINGERBREAD) {
-            return "2:20";
-        }
-        if (platformVersion < ICE_CREAM_SANDWICH) {
-            return "2:30";
-        }
-        if (platformVersion < JELLY_BEAN) {
-            return "4:00";
-        }
-        if (platformVersion < KITKAT) {
-            return "4:30";
-        }
-        if (platformVersion < LOLLIPOP) {
-            return "4:40";
-        }
-        if (platformVersion < LOLLIPOP_MR1) {
-            return "5:00";
-        }
-        if (platformVersion < M) {
-            return "5:10";
-        }
-        if (platformVersion < N) {
-            return "6:00";
-        }
-        // Should never happen.
-        return "4:04";
-    }
-
-    public static int getTimeColor(int platformVersion) {
-        if (isGreaterOrEqual(platformVersion, KITKAT) ||
-                platformVersion > FROYO && platformVersion < HONEYCOMB) {
-            // Gingerbread and KitKat onwards.
-            return WHITE;
-        }
-        // Black for froyo.
-        if (platformVersion < GINGERBREAD) {
-            return BLACK;
-        } else if (platformVersion < KITKAT) {
-            // Honeycomb to JB-mr2: Holo blue light.
-            return 0xff33b5e5;
-        }
-        // Should never happen.
-        return WHITE;
-    }
-
-    public static String getWifiIconType(int platformVersion) {
-        return isGreaterOrEqual(platformVersion, LOLLIPOP) ? "xml" : "png";
-    }
-
-    /**
-     * Compare simulated platform version and code from {@link VERSION_CODES} to check if
-     * the simulated platform is greater than or equal to the version code.
-     */
-    public static boolean isGreaterOrEqual(int platformVersion, int code) {
-        // simulated platform version = 0 means that we use the latest.
-        return platformVersion == 0 || platformVersion >= code;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
deleted file mode 100644
index 2984fc0..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ /dev/null
@@ -1,290 +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.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.Density;
-import com.android.resources.LayoutDirection;
-import com.android.resources.ResourceType;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.content.res.ColorStateList;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import static android.os._Original_Build.VERSION_CODES.LOLLIPOP;
-
-/**
- * Base "bar" class for the window decor around the the edited layout.
- * This is basically an horizontal layout that loads a given layout on creation (it is read
- * through {@link Class#getResourceAsStream(String)}).
- *
- * The given layout should be a merge layout so that all the children belong to this class directly.
- *
- * It also provides a few utility methods to configure the content of the layout.
- */
-abstract class CustomBar extends LinearLayout {
-
-
-    private final int mSimulatedPlatformVersion;
-
-    protected abstract TextView getStyleableTextView();
-
-    protected CustomBar(BridgeContext context, int orientation, String layoutPath,
-            String name, int simulatedPlatformVersion) {
-        super(context);
-        mSimulatedPlatformVersion = simulatedPlatformVersion;
-        setOrientation(orientation);
-        if (orientation == LinearLayout.HORIZONTAL) {
-            setGravity(Gravity.CENTER_VERTICAL);
-        } else {
-            setGravity(Gravity.CENTER_HORIZONTAL);
-        }
-
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-
-        XmlPullParser parser;
-        try {
-            parser = ParserFactory.create(getClass().getResourceAsStream(layoutPath), name);
-
-            BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(parser, context, false);
-
-            try {
-                inflater.inflate(bridgeParser, this, true);
-            } finally {
-                bridgeParser.ensurePopped();
-            }
-        } catch (XmlPullParserException e) {
-            // Should not happen as the resource is bundled with the jar, and  ParserFactory should
-            // have been initialized.
-            assert false;
-        }
-    }
-
-    protected void loadIcon(int index, String iconName, Density density) {
-        loadIcon(index, iconName, density, false);
-    }
-
-    protected void loadIcon(int index, String iconName, Density density, boolean isRtl) {
-        View child = getChildAt(index);
-        if (child instanceof ImageView) {
-            ImageView imageView = (ImageView) child;
-
-            LayoutDirection dir = isRtl ? LayoutDirection.RTL : null;
-            IconLoader iconLoader = new IconLoader(iconName, density, mSimulatedPlatformVersion,
-                    dir);
-            InputStream stream = iconLoader.getIcon();
-
-            if (stream != null) {
-                density = iconLoader.getDensity();
-                String path = iconLoader.getPath();
-                // look for a cached bitmap
-                Bitmap bitmap = Bridge.getCachedBitmap(path, Boolean.TRUE /*isFramework*/);
-                if (bitmap == null) {
-                    try {
-                        bitmap = Bitmap_Delegate.createBitmap(stream, false /*isMutable*/, density);
-                        Bridge.setCachedBitmap(path, bitmap, Boolean.TRUE /*isFramework*/);
-                    } catch (IOException e) {
-                        return;
-                    }
-                }
-
-                if (bitmap != null) {
-                    BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(),
-                            bitmap);
-                    imageView.setImageDrawable(drawable);
-                }
-            }
-        }
-    }
-
-    protected TextView setText(int index, String string, boolean reference) {
-        View child = getChildAt(index);
-        if (child instanceof TextView) {
-            TextView textView = (TextView) child;
-            setText(textView, string, reference);
-            return textView;
-        }
-
-        return null;
-    }
-
-    private void setText(TextView textView, String string, boolean reference) {
-        if (reference) {
-            ResourceValue value = getResourceValue(string);
-            if (value != null) {
-                string = value.getValue();
-            }
-        }
-        textView.setText(string);
-    }
-
-    protected void setStyle(String themeEntryName) {
-
-        BridgeContext bridgeContext = getContext();
-        RenderResources res = bridgeContext.getRenderResources();
-
-        ResourceValue value = res.findItemInTheme(themeEntryName, true /*isFrameworkAttr*/);
-        value = res.resolveResValue(value);
-
-        if (!(value instanceof StyleResourceValue)) {
-            return;
-        }
-
-        StyleResourceValue style = (StyleResourceValue) value;
-
-        // get the background
-        ResourceValue backgroundValue = res.findItemInStyle(style, "background",
-                true /*isFrameworkAttr*/);
-        backgroundValue = res.resolveResValue(backgroundValue);
-        if (backgroundValue != null) {
-            Drawable d = ResourceHelper.getDrawable(backgroundValue, bridgeContext);
-            if (d != null) {
-                setBackground(d);
-            }
-        }
-
-        TextView textView = getStyleableTextView();
-        if (textView != null) {
-            // get the text style
-            ResourceValue textStyleValue = res.findItemInStyle(style, "titleTextStyle",
-                    true /*isFrameworkAttr*/);
-            textStyleValue = res.resolveResValue(textStyleValue);
-            if (textStyleValue instanceof StyleResourceValue) {
-                StyleResourceValue textStyle = (StyleResourceValue) textStyleValue;
-
-                ResourceValue textSize = res.findItemInStyle(textStyle, "textSize",
-                        true /*isFrameworkAttr*/);
-                textSize = res.resolveResValue(textSize);
-
-                if (textSize != null) {
-                    TypedValue out = new TypedValue();
-                    if (ResourceHelper.parseFloatAttribute("textSize", textSize.getValue(), out,
-                            true /*requireUnit*/)) {
-                        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
-                                out.getDimension(bridgeContext.getResources().getDisplayMetrics()));
-                    }
-                }
-
-
-                ResourceValue textColor = res.findItemInStyle(textStyle, "textColor",
-                        true);
-                textColor = res.resolveResValue(textColor);
-                if (textColor != null) {
-                    ColorStateList stateList = ResourceHelper.getColorStateList(
-                            textColor, bridgeContext);
-                    if (stateList != null) {
-                        textView.setTextColor(stateList);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public BridgeContext getContext() {
-        return (BridgeContext) mContext;
-    }
-
-    /**
-     * Find the background color for this bar from the theme attributes. Only relevant to StatusBar
-     * and NavigationBar.
-     * <p/>
-     * Returns 0 if not found.
-     *
-     * @param colorAttrName the attribute name for the background color
-     * @param translucentAttrName the attribute name for the translucency property of the bar.
-     *
-     * @throws NumberFormatException if color resolved to an invalid string.
-     */
-    protected int getBarColor(@NonNull String colorAttrName, @NonNull String translucentAttrName) {
-        if (!Config.isGreaterOrEqual(mSimulatedPlatformVersion, LOLLIPOP)) {
-            return 0;
-        }
-        RenderResources renderResources = getContext().getRenderResources();
-        // First check if the bar is translucent.
-        boolean translucent = ResourceHelper.getBooleanThemeValue(renderResources,
-                translucentAttrName, true, false);
-        if (translucent) {
-            // Keep in sync with R.color.system_bar_background_semi_transparent from system ui.
-            return 0x66000000;  // 40% black.
-        }
-        boolean transparent = ResourceHelper.getBooleanThemeValue(renderResources,
-                "windowDrawsSystemBarBackgrounds", true, false);
-        if (transparent) {
-            return getColor(renderResources, colorAttrName);
-        }
-        return 0;
-    }
-
-    private static int getColor(RenderResources renderResources, String attr) {
-        // From ?attr/foo to @color/bar. This is most likely an ItemResourceValue.
-        ResourceValue resource = renderResources.findItemInTheme(attr, true);
-        // Form @color/bar to the #AARRGGBB
-        resource = renderResources.resolveResValue(resource);
-        if (resource != null) {
-            ResourceType type = resource.getResourceType();
-            if (type == null || type == ResourceType.COLOR) {
-                // if no type is specified, the value may have been specified directly in the style
-                // file, rather than referencing a color resource value.
-                try {
-                    return ResourceHelper.getColor(resource.getValue());
-                } catch (NumberFormatException e) {
-                    // Conversion failed.
-                    Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                            "Theme attribute @android:" + attr +
-                                    " does not reference a color, instead is '" +
-                                    resource.getValue() + "'.", resource);
-                }
-            }
-        }
-        return 0;
-    }
-
-    private ResourceValue getResourceValue(String reference) {
-        RenderResources res = getContext().getRenderResources();
-
-        // find the resource
-        ResourceValue value = res.findResValue(reference, false);
-
-        // resolve it if needed
-        return res.resolveResValue(value);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
deleted file mode 100644
index fd49c77..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
+++ /dev/null
@@ -1,258 +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.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.internal.R;
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.view.menu.MenuItemImpl;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.InflateException;
-import android.view.View;
-import android.view.View.MeasureSpec;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.ActionMenuPresenter;
-import android.widget.FrameLayout;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-import android.widget.RelativeLayout;
-
-import java.util.ArrayList;
-
-/**
- * Creates the ActionBar as done by the framework.
- */
-public class FrameworkActionBar extends BridgeActionBar {
-
-    private static final String LAYOUT_ATTR_NAME = "windowActionBarFullscreenDecorLayout";
-
-    // The Action Bar
-    @NonNull private FrameworkActionBarWrapper mActionBar;
-
-    // A fake parent for measuring views.
-    @Nullable private ViewGroup mMeasureParent;
-
-    /**
-     * Inflate the action bar and attach it to {@code parentView}
-     */
-    public FrameworkActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) {
-        super(context, params);
-
-        View decorContent = getDecorContent();
-
-        mActionBar = FrameworkActionBarWrapper.getActionBarWrapper(context, getCallBack(),
-                decorContent);
-
-        FrameLayout contentRoot = (FrameLayout) decorContent.findViewById(android.R.id.content);
-
-        // If something went wrong and we were not able to initialize the content root,
-        // just add a frame layout inside this and return.
-        if (contentRoot == null) {
-            contentRoot = new FrameLayout(context);
-            setMatchParent(contentRoot);
-            if (mEnclosingLayout != null) {
-                mEnclosingLayout.addView(contentRoot);
-            }
-            setContentRoot(contentRoot);
-        } else {
-            setContentRoot(contentRoot);
-            setupActionBar();
-            mActionBar.inflateMenus();
-        }
-    }
-
-    @Override
-    protected ResourceValue getLayoutResource(BridgeContext context) {
-        ResourceValue layoutName =
-                context.getRenderResources().findItemInTheme(LAYOUT_ATTR_NAME, true);
-        if (layoutName != null) {
-            // We may need to resolve the reference obtained.
-            layoutName = context.getRenderResources().findResValue(layoutName.getValue(),
-                    layoutName.isFramework());
-        }
-        if (layoutName == null) {
-             throw new InflateException("Unable to find action bar layout (" + LAYOUT_ATTR_NAME
-                    + ") in the current theme.");
-        }
-        return layoutName;
-    }
-
-    @Override
-    protected void setupActionBar() {
-        super.setupActionBar();
-        mActionBar.setupActionBar();
-    }
-
-    @Override
-    protected void setHomeAsUp(boolean homeAsUp) {
-        mActionBar.setHomeAsUp(homeAsUp);
-    }
-
-    @Override
-    protected void setTitle(CharSequence title) {
-        mActionBar.setTitle(title);
-    }
-
-    @Override
-    protected void setSubtitle(CharSequence subtitle) {
-        mActionBar.setSubTitle(subtitle);
-    }
-
-    @Override
-    protected void setIcon(String icon) {
-        mActionBar.setIcon(icon);
-    }
-
-    /**
-     * Creates a Popup and adds it to the content frame. It also adds another {@link FrameLayout} to
-     * the content frame which shall serve as the new content root.
-     */
-    @Override
-    public void createMenuPopup() {
-        if (!isOverflowPopupNeeded()) {
-            return;
-        }
-
-        DisplayMetrics metrics = mBridgeContext.getMetrics();
-        MenuBuilder menu = mActionBar.getMenuBuilder();
-        OverflowMenuAdapter adapter = new OverflowMenuAdapter(menu, mActionBar.getPopupContext());
-
-        ListView listView = new ListView(mActionBar.getPopupContext(), null,
-                R.attr.dropDownListViewStyle);
-        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
-                measureContentWidth(adapter), LayoutParams.WRAP_CONTENT);
-        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_END);
-        if (mActionBar.isSplit()) {
-            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
-            layoutParams.bottomMargin = getActionBarHeight() + mActionBar.getMenuPopupMargin();
-        } else {
-            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
-            layoutParams.topMargin = getActionBarHeight() + mActionBar.getMenuPopupMargin();
-        }
-        layoutParams.setMarginEnd(getPixelValue("5dp", metrics));
-        listView.setLayoutParams(layoutParams);
-        listView.setAdapter(adapter);
-        final TypedArray a = mActionBar.getPopupContext().obtainStyledAttributes(null,
-                R.styleable.PopupWindow, R.attr.popupMenuStyle, 0);
-        listView.setBackground(a.getDrawable(R.styleable.PopupWindow_popupBackground));
-        listView.setDivider(a.getDrawable(R.attr.actionBarDivider));
-        a.recycle();
-        listView.setElevation(mActionBar.getMenuPopupElevation());
-        assert mEnclosingLayout != null : "Unable to find view to attach ActionMenuPopup.";
-        mEnclosingLayout.addView(listView);
-    }
-
-    private boolean isOverflowPopupNeeded() {
-        boolean needed = mActionBar.isOverflowPopupNeeded();
-        if (!needed) {
-            return false;
-        }
-        // Copied from android.widget.ActionMenuPresenter.updateMenuView()
-        ArrayList<MenuItemImpl> menus = mActionBar.getMenuBuilder().getNonActionItems();
-        ActionMenuPresenter presenter = mActionBar.getActionMenuPresenter();
-        if (presenter == null) {
-            assert false : "Failed to create a Presenter for Action Bar Menus.";
-            return false;
-        }
-        if (presenter.isOverflowReserved() &&
-                menus != null) {
-            final int count = menus.size();
-            if (count == 1) {
-                needed = !menus.get(0).isActionViewExpanded();
-            } else {
-                needed = count > 0;
-            }
-        }
-        return needed;
-    }
-
-    // Copied from com.android.internal.view.menu.MenuPopHelper.measureContentWidth()
-    private int measureContentWidth(@NonNull ListAdapter adapter) {
-        // Menus don't tend to be long, so this is more sane than it looks.
-        int maxWidth = 0;
-        View itemView = null;
-        int itemType = 0;
-
-        Context context = mActionBar.getPopupContext();
-        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        final int count = adapter.getCount();
-        for (int i = 0; i < count; i++) {
-            final int positionType = adapter.getItemViewType(i);
-            if (positionType != itemType) {
-                itemType = positionType;
-                itemView = null;
-            }
-
-            if (mMeasureParent == null) {
-                mMeasureParent = new FrameLayout(context);
-            }
-
-            itemView = adapter.getView(i, itemView, mMeasureParent);
-            itemView.measure(widthMeasureSpec, heightMeasureSpec);
-
-            final int itemWidth = itemView.getMeasuredWidth();
-            int popupMaxWidth = Math.max(mBridgeContext.getMetrics().widthPixels / 2,
-                    context.getResources().getDimensionPixelSize(R.dimen.config_prefDialogWidth));
-            if (itemWidth >= popupMaxWidth) {
-                return popupMaxWidth;
-            } else if (itemWidth > maxWidth) {
-                maxWidth = itemWidth;
-            }
-        }
-
-        return maxWidth;
-    }
-
-    static int getPixelValue(@NonNull String value, @NonNull DisplayMetrics metrics) {
-        TypedValue typedValue = ResourceHelper.getValue(null, value, false /*requireUnit*/);
-        return (int) typedValue.getDimension(metrics);
-    }
-
-    // TODO: This is duplicated from RenderSessionImpl.
-    private int getActionBarHeight() {
-        RenderResources resources = mBridgeContext.getRenderResources();
-        DisplayMetrics metrics = mBridgeContext.getMetrics();
-        ResourceValue value = resources.findItemInTheme("actionBarSize", true);
-
-        // resolve it
-        value = resources.resolveResValue(value);
-
-        if (value != null) {
-            // get the numerical value, if available
-            TypedValue typedValue = ResourceHelper.getValue("actionBarSize", value.getValue(),
-                    true);
-            if (typedValue != null) {
-                // compute the pixel value based on the display metrics
-                return (int) typedValue.getDimension(metrics);
-
-            }
-        }
-        return 0;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
deleted file mode 100644
index 2cdc647..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
+++ /dev/null
@@ -1,379 +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.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.internal.R;
-import com.android.internal.app.ToolbarActionBar;
-import com.android.internal.app.WindowDecorActionBar;
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.widget.ActionBarAccessor;
-import com.android.internal.widget.ActionBarView;
-import com.android.internal.widget.DecorToolbar;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.ActionBar;
-import android.app.ActionBar.Tab;
-import android.app.ActionBar.TabListener;
-import android.app.FragmentTransaction;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.view.MenuInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowCallback;
-import android.widget.ActionMenuPresenter;
-import android.widget.ActionMenuView;
-import android.widget.Toolbar;
-import android.widget.Toolbar_Accessor;
-
-import static com.android.SdkConstants.ANDROID_NS_NAME_PREFIX;
-import static com.android.resources.ResourceType.MENU;
-
-/**
- * A common API to access {@link ToolbarActionBar} and {@link WindowDecorActionBar}.
- */
-public abstract class FrameworkActionBarWrapper {
-
-    @NonNull protected ActionBar mActionBar;
-    @NonNull protected ActionBarCallback mCallback;
-    @NonNull protected BridgeContext mContext;
-
-    /**
-     * Returns a wrapper around different implementations of the Action Bar to provide a common API.
-     *
-     * @param decorContent the top level view returned by inflating
-     *                     ?attr/windowActionBarFullscreenDecorLayout
-     */
-    @NonNull
-    public static FrameworkActionBarWrapper getActionBarWrapper(@NonNull BridgeContext context,
-            @NonNull ActionBarCallback callback, @NonNull View decorContent) {
-        View view = decorContent.findViewById(R.id.action_bar);
-        if (view instanceof Toolbar) {
-            return new ToolbarWrapper(context, callback, (Toolbar) view);
-        } else if (view instanceof ActionBarView) {
-            return new WindowActionBarWrapper(context, callback, decorContent,
-                    (ActionBarView) view);
-        } else {
-            throw new IllegalStateException("Can't make an action bar out of " +
-                    view.getClass().getSimpleName());
-        }
-    }
-
-    FrameworkActionBarWrapper(@NonNull BridgeContext context, @NonNull ActionBarCallback callback,
-            @NonNull ActionBar actionBar) {
-        mActionBar = actionBar;
-        mCallback = callback;
-        mContext = context;
-    }
-
-    /** A call to setup any custom properties. */
-    protected void setupActionBar() {
-        // Nothing to do here.
-    }
-
-    public void setTitle(CharSequence title) {
-        mActionBar.setTitle(title);
-    }
-
-    public void setSubTitle(CharSequence subTitle) {
-        if (subTitle != null) {
-            mActionBar.setSubtitle(subTitle);
-        }
-    }
-
-    public void setHomeAsUp(boolean homeAsUp) {
-        mActionBar.setDisplayHomeAsUpEnabled(homeAsUp);
-    }
-
-    public void setIcon(String icon) {
-        // Nothing to do.
-    }
-
-    protected boolean isSplit() {
-        return getDecorToolbar().isSplit();
-    }
-
-    protected boolean isOverflowPopupNeeded() {
-        return mCallback.isOverflowPopupNeeded();
-    }
-
-    /**
-     * Gets the menus to add to the action bar from the callback, resolves them, inflates them and
-     * adds them to the action bar.
-     */
-    protected void inflateMenus() {
-        MenuInflater inflater = new MenuInflater(getActionMenuContext());
-        MenuBuilder menuBuilder = getMenuBuilder();
-        for (String name : mCallback.getMenuIdNames()) {
-            int id;
-            if (name.startsWith(ANDROID_NS_NAME_PREFIX)) {
-                // Framework menu.
-                name = name.substring(ANDROID_NS_NAME_PREFIX.length());
-                id = mContext.getFrameworkResourceValue(MENU, name, -1);
-            } else {
-                // Project menu.
-                id = mContext.getProjectResourceValue(MENU, name, -1);
-            }
-            if (id > -1) {
-                inflater.inflate(id, menuBuilder);
-            }
-        }
-    }
-
-    /**
-     * The context used for the ActionBar and the menus in the ActionBarView.
-     */
-    @NonNull
-    protected Context getActionMenuContext() {
-        return mActionBar.getThemedContext();
-    }
-
-    /**
-     * The context used to inflate the popup menu.
-     */
-    @NonNull
-    abstract Context getPopupContext();
-
-    /**
-     * The Menu in which to inflate the user's menus.
-     */
-    @NonNull
-    abstract MenuBuilder getMenuBuilder();
-
-    @Nullable
-    abstract ActionMenuPresenter getActionMenuPresenter();
-
-    /**
-     * Framework's wrapper over two ActionBar implementations.
-     */
-    @NonNull
-    abstract DecorToolbar getDecorToolbar();
-
-    abstract int getMenuPopupElevation();
-
-    /**
-     * Margin between the menu popup and the action bar.
-     */
-    abstract int getMenuPopupMargin();
-
-    // ---- The implementations ----
-
-    /**
-     * Material theme uses {@link Toolbar} as the action bar. This wrapper provides access to
-     * Toolbar using a common API.
-     */
-    private static class ToolbarWrapper extends FrameworkActionBarWrapper {
-
-        @NonNull
-        private final Toolbar mToolbar;  // This is the view.
-
-        ToolbarWrapper(@NonNull BridgeContext context, @NonNull ActionBarCallback callback,
-                @NonNull Toolbar toolbar) {
-            super(context, callback, new ToolbarActionBar(toolbar, "", new WindowCallback()));
-            mToolbar = toolbar;
-        }
-
-        @Override
-        protected void inflateMenus() {
-            super.inflateMenus();
-            // Inflating the menus isn't enough. ActionMenuPresenter needs to be initialized too.
-            MenuBuilder menu = getMenuBuilder();
-            DecorToolbar decorToolbar = getDecorToolbar();
-            // Setting a menu different from the above initializes the presenter.
-            decorToolbar.setMenu(new MenuBuilder(getActionMenuContext()), null);
-            // ActionMenuView needs to be recreated to be able to set the menu back.
-            ActionMenuPresenter presenter = getActionMenuPresenter();
-            if (presenter != null) {
-                presenter.setMenuView(new ActionMenuView(getPopupContext()));
-            }
-            decorToolbar.setMenu(menu, null);
-        }
-
-        @NonNull
-        @Override
-        Context getPopupContext() {
-            return Toolbar_Accessor.getPopupContext(mToolbar);
-        }
-
-        @NonNull
-        @Override
-        MenuBuilder getMenuBuilder() {
-            return (MenuBuilder) mToolbar.getMenu();
-        }
-
-        @Nullable
-        @Override
-        ActionMenuPresenter getActionMenuPresenter() {
-            return Toolbar_Accessor.getActionMenuPresenter(mToolbar);
-        }
-
-        @NonNull
-        @Override
-        DecorToolbar getDecorToolbar() {
-            return mToolbar.getWrapper();
-        }
-
-        @Override
-        int getMenuPopupElevation() {
-            return 10;
-        }
-
-        @Override
-        int getMenuPopupMargin() {
-            return 0;
-        }
-    }
-
-    /**
-     * Holo theme uses {@link WindowDecorActionBar} as the action bar. This wrapper provides
-     * access to it using a common API.
-     */
-    private static class WindowActionBarWrapper extends FrameworkActionBarWrapper {
-
-        @NonNull private final WindowDecorActionBar mActionBar;
-        @NonNull private final ActionBarView mActionBarView;
-        @NonNull private final View mDecorContentRoot;
-        private MenuBuilder mMenuBuilder;
-
-        public WindowActionBarWrapper(@NonNull BridgeContext context,
-                @NonNull ActionBarCallback callback, @NonNull View decorContentRoot,
-                @NonNull ActionBarView actionBarView) {
-            super(context, callback, new WindowDecorActionBar(decorContentRoot));
-            mActionBarView = actionBarView;
-            mActionBar = (WindowDecorActionBar) super.mActionBar;
-            mDecorContentRoot = decorContentRoot;
-        }
-
-        @Override
-        protected void setupActionBar() {
-
-            // Set the navigation mode.
-            int navMode = mCallback.getNavigationMode();
-            mActionBar.setNavigationMode(navMode);
-            //noinspection deprecation
-            if (navMode == ActionBar.NAVIGATION_MODE_TABS) {
-                setupTabs(3);
-            }
-
-            // Set action bar to be split, if needed.
-            ViewGroup splitView = (ViewGroup) mDecorContentRoot.findViewById(R.id.split_action_bar);
-            if (splitView != null) {
-                mActionBarView.setSplitView(splitView);
-                Resources res = mContext.getResources();
-                boolean split = res.getBoolean(R.bool.split_action_bar_is_narrow)
-                        && mCallback.getSplitActionBarWhenNarrow();
-                mActionBarView.setSplitToolbar(split);
-            }
-        }
-
-        @Override
-        public void setIcon(String icon) {
-            // Set the icon only if the action bar doesn't specify an icon.
-            if (!mActionBar.hasIcon() && icon != null) {
-                Drawable iconDrawable = getDrawable(icon, false);
-                if (iconDrawable != null) {
-                    mActionBar.setIcon(iconDrawable);
-                }
-            }
-        }
-
-        @Override
-        protected void inflateMenus() {
-            super.inflateMenus();
-            // The super implementation doesn't set the menu on the view. Set it here.
-            mActionBarView.setMenu(getMenuBuilder(), null);
-        }
-
-        @NonNull
-        @Override
-        Context getPopupContext() {
-            return getActionMenuContext();
-        }
-
-        @NonNull
-        @Override
-        MenuBuilder getMenuBuilder() {
-            if (mMenuBuilder == null) {
-                mMenuBuilder = new MenuBuilder(getActionMenuContext());
-            }
-            return mMenuBuilder;
-        }
-
-        @Nullable
-        @Override
-        ActionMenuPresenter getActionMenuPresenter() {
-            return ActionBarAccessor.getActionMenuPresenter(mActionBarView);
-        }
-
-        @NonNull
-        @Override
-        ActionBarView getDecorToolbar() {
-            return mActionBarView;
-        }
-
-        @Override
-        int getMenuPopupElevation() {
-            return 0;
-        }
-
-        @Override
-        int getMenuPopupMargin() {
-            return -FrameworkActionBar.getPixelValue("10dp", mContext.getMetrics());
-        }
-
-        // TODO: Use an adapter, like List View to set up tabs.
-        @SuppressWarnings("deprecation")  // For Tab
-        private void setupTabs(int num) {
-            for (int i = 1; i <= num; i++) {
-                Tab tab = mActionBar.newTab().setText("Tab" + i).setTabListener(new TabListener() {
-                    @Override
-                    public void onTabUnselected(Tab t, FragmentTransaction ft) {
-                        // pass
-                    }
-                    @Override
-                    public void onTabSelected(Tab t, FragmentTransaction ft) {
-                        // pass
-                    }
-                    @Override
-                    public void onTabReselected(Tab t, FragmentTransaction ft) {
-                        // pass
-                    }
-                });
-                mActionBar.addTab(tab);
-            }
-        }
-
-        @Nullable
-        private Drawable getDrawable(@NonNull String name, boolean isFramework) {
-            RenderResources res = mContext.getRenderResources();
-            ResourceValue value = res.findResValue(name, isFramework);
-            value = res.resolveResValue(value);
-            if (value != null) {
-                return ResourceHelper.getDrawable(value, mContext);
-            }
-            return null;
-        }
-
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/IconLoader.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/IconLoader.java
deleted file mode 100644
index 9ab2e82..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/IconLoader.java
+++ /dev/null
@@ -1,125 +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.layoutlib.bridge.bars;
-
-import com.android.resources.Density;
-import com.android.resources.LayoutDirection;
-
-import java.io.InputStream;
-
-public class IconLoader {
-
-    private final String mIconName;
-    private final Density mDesiredDensity;
-    private final int mPlatformVersion;
-    private final LayoutDirection mDirection;
-
-    private Density mCurrentDensity;
-    private StringBuilder mCurrentPath;
-
-    IconLoader(String iconName, Density density, int platformVersion, LayoutDirection direction) {
-        mIconName = iconName;
-        mDesiredDensity = density;
-        mPlatformVersion = platformVersion;
-        mDirection = direction;
-        // An upper bound on the length of the path for the icon: /bars/v21/ldrtl-xxxhdpi/
-        final int iconPathLength = 24;
-        mCurrentPath = new StringBuilder(iconPathLength + iconName.length());
-    }
-
-    public InputStream getIcon() {
-        for (String resourceDir : Config.getResourceDirs(mPlatformVersion)) {
-            mCurrentDensity = null;
-            InputStream stream = getIcon(resourceDir);
-            if (stream != null) {
-                return stream;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Should only be called after {@link #getIcon()}. Returns the density of the icon, if found by
-     * {@code getIcon()}. If no icon was found, then the return value has no meaning.
-     */
-    public Density getDensity() {
-        return mCurrentDensity;
-    }
-
-    /**
-     * Should only be called after {@link #getIcon()}. Returns the path to the icon, if found by
-     * {@code getIcon()}. If no icon was found, then the return value has no meaning.
-     */
-    public String getPath() {
-        return mCurrentPath.toString();
-    }
-
-    /**
-     * Search for icon in the resource directory. This iterates over all densities.
-     * If a match is found, mCurrentDensity will be set to the icon's density.
-     */
-    private InputStream getIcon(String resourceDir) {
-        // First check for the desired density.
-        InputStream stream = getIcon(resourceDir, mDesiredDensity);
-        if (stream != null) {
-            mCurrentDensity = mDesiredDensity;
-            return stream;
-        }
-        // Didn't find in the desired density. Search in all.
-        for (Density density : Density.values()) {
-            if (density == mDesiredDensity) {
-                // Skip the desired density since it's already been checked.
-                continue;
-            }
-            stream = getIcon(resourceDir, density);
-            if (stream != null) {
-                mCurrentDensity = density;
-                return stream;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the icon for given density present in the given resource directory, taking layout
-     * direction into consideration.
-     */
-    private InputStream getIcon(String resourceDir, Density density) {
-        mCurrentPath.setLength(0);
-        // Currently we don't have any LTR only resources and hence the check is skipped. If they
-        // are ever added, change to:
-        // if (mDirection == LayoutDirection.RTL || mDirection == LayoutDirection.LTR) {
-        if (mDirection == LayoutDirection.RTL) {
-            mCurrentPath.append(resourceDir)
-                    .append(mDirection.getResourceValue())
-                    .append('-')
-                    .append(density.getResourceValue())
-                    .append('/')
-                    .append(mIconName);
-            InputStream stream = getClass().getResourceAsStream(mCurrentPath.toString());
-            if (stream != null) {
-                return stream;
-            }
-            mCurrentPath.setLength(0);
-        }
-        mCurrentPath.append(resourceDir)
-                .append(density.getResourceValue())
-                .append('/')
-                .append(mIconName);
-        return getClass().getResourceAsStream(mCurrentPath.toString());
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
deleted file mode 100644
index dfbc69b..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
+++ /dev/null
@@ -1,138 +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.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.resources.Density;
-
-import android.util.DisplayMetrics;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-public class NavigationBar extends CustomBar {
-
-    /** Navigation bar background color attribute name. */
-    private static final String ATTR_COLOR = "navigationBarColor";
-    /** Attribute for translucency property. */
-    public static final String ATTR_TRANSLUCENT = "windowTranslucentNavigation";
-    // These correspond to @dimen/navigation_side_padding in the system ui code.
-    private static final int PADDING_WIDTH_DEFAULT = 36;
-    private static final int PADDING_WIDTH_SW360 = 40;
-    private static final int PADDING_WIDTH_SW400 = 50;
-    // These corresponds to @dimen/navigation_key_width in the system ui code.
-    private static final int WIDTH_DEFAULT = 36;
-    private static final int WIDTH_SW360 = 40;
-    private static final int WIDTH_SW600 = 48;
-    protected static final String LAYOUT_XML = "/bars/navigation_bar.xml";
-    private static final String LAYOUT_600DP_XML = "/bars/navigation_bar600dp.xml";
-
-    public NavigationBar(BridgeContext context, Density density, int orientation, boolean isRtl,
-      boolean rtlEnabled, int simulatedPlatformVersion) {
-        this(context, density, orientation, isRtl, rtlEnabled, simulatedPlatformVersion,
-          getShortestWidth(context)>= 600 ? LAYOUT_600DP_XML : LAYOUT_XML);
-    }
-
-    protected NavigationBar(BridgeContext context, Density density, int orientation, boolean isRtl,
-      boolean rtlEnabled, int simulatedPlatformVersion, String layoutPath) {
-        super(context, orientation, layoutPath, "navigation_bar.xml", simulatedPlatformVersion);
-
-        int color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT);
-        setBackgroundColor(color == 0 ? 0xFF000000 : color);
-
-        // Cannot access the inside items through id because no R.id values have been
-        // created for them.
-        // We do know the order though.
-        // 0 is a spacer.
-        int back = 1;
-        int recent = 5;
-        if (orientation == LinearLayout.VERTICAL || (isRtl && !rtlEnabled)) {
-            // If RTL is enabled, then layoutlib mirrors the layout for us.
-            back = 5;
-            recent = 1;
-        }
-
-        //noinspection SpellCheckingInspection
-        loadIcon(back, "ic_sysbar_back.png", density, isRtl);
-        //noinspection SpellCheckingInspection
-        loadIcon(3, "ic_sysbar_home.png", density, isRtl);
-        //noinspection SpellCheckingInspection
-        loadIcon(recent, "ic_sysbar_recent.png", density, isRtl);
-        setupNavBar(context, orientation);
-    }
-
-    private void setupNavBar(BridgeContext context, int orientation) {
-        float sw = getShortestWidth(context);
-        View leftPadding = getChildAt(0);
-        View rightPadding = getChildAt(6);
-        setSize(context, leftPadding, orientation, getSidePadding(sw));
-        setSize(context, rightPadding, orientation, getSidePadding(sw));
-        int navButtonWidth = getWidth(sw);
-        for (int i = 1; i < 6; i += 2) {
-            View navButton = getChildAt(i);
-            setSize(context, navButton, orientation, navButtonWidth);
-        }
-        if (sw >= 600) {
-            setSize(context, getChildAt(2), orientation, 128);
-            setSize(context, getChildAt(4), orientation, 128);
-        }
-    }
-
-    private static void setSize(BridgeContext context, View view, int orientation, int size) {
-        size *= context.getMetrics().density;
-        LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
-        if (orientation == HORIZONTAL) {
-            layoutParams.width = size;
-        } else {
-            layoutParams.height = size;
-        }
-        view.setLayoutParams(layoutParams);
-    }
-
-    protected int getSidePadding(float sw) {
-        if (sw >= 400) {
-            return PADDING_WIDTH_SW400;
-        }
-        if (sw >= 360) {
-            return PADDING_WIDTH_SW360;
-        }
-        return PADDING_WIDTH_DEFAULT;
-    }
-
-    private static int getWidth(float sw) {
-        if (sw >= 600) {
-            return WIDTH_SW600;
-        }
-        if (sw >= 360) {
-            return WIDTH_SW360;
-        }
-        return WIDTH_DEFAULT;
-    }
-
-    private static float getShortestWidth(BridgeContext context) {
-        DisplayMetrics metrics = context.getMetrics();
-        float sw = metrics.widthPixels < metrics.heightPixels ?
-                metrics.widthPixels : metrics.heightPixels;
-        sw /= metrics.density;
-        return sw;
-    }
-
-    @Override
-    protected TextView getStyleableTextView() {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/OverflowMenuAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/OverflowMenuAdapter.java
deleted file mode 100644
index 778305d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/OverflowMenuAdapter.java
+++ /dev/null
@@ -1,99 +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.layoutlib.bridge.bars;
-
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.view.menu.MenuItemImpl;
-import com.android.internal.view.menu.MenuView;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-
-import java.util.ArrayList;
-
-/**
- * Provides an adapter for Overflow menu popup. This is very similar to
- * {@code MenuPopupHelper.MenuAdapter}
- */
-public class OverflowMenuAdapter extends BaseAdapter {
-
-    private final MenuBuilder mMenu;
-    private int mExpandedIndex = -1;
-    private final Context context;
-
-    public OverflowMenuAdapter(MenuBuilder menu, Context context) {
-        mMenu = menu;
-        findExpandedIndex();
-        this.context = context;
-    }
-
-    @Override
-    public int getCount() {
-        ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
-        if (mExpandedIndex < 0) {
-            return items.size();
-        }
-        return items.size() - 1;
-    }
-
-    @Override
-    public MenuItemImpl getItem(int position) {
-        ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
-        if (mExpandedIndex >= 0 && position >= mExpandedIndex) {
-            position++;
-        }
-        return items.get(position);
-    }
-
-    @Override
-    public long getItemId(int position) {
-        // Since a menu item's ID is optional, we'll use the position as an
-        // ID for the item in the AdapterView
-        return position;
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        if (convertView == null) {
-            LayoutInflater mInflater = LayoutInflater.from(context);
-            convertView = mInflater.inflate(com.android.internal.R.layout.popup_menu_item_layout,
-                    parent, false);
-        }
-
-        MenuView.ItemView itemView = (MenuView.ItemView) convertView;
-        itemView.initialize(getItem(position), 0);
-        return convertView;
-    }
-
-    private void findExpandedIndex() {
-        final MenuItemImpl expandedItem = mMenu.getExpandedItem();
-        if (expandedItem != null) {
-            final ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
-            final int count = items.size();
-            for (int i = 0; i < count; i++) {
-                final MenuItemImpl item = items.get(i);
-                if (item == expandedItem) {
-                    mExpandedIndex = i;
-                    return;
-                }
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
deleted file mode 100644
index 2dc7c65..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
+++ /dev/null
@@ -1,123 +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.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.resources.Density;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-public class StatusBar extends CustomBar {
-
-    private final int mSimulatedPlatformVersion;
-    /** Status bar background color attribute name. */
-    private static final String ATTR_COLOR = "statusBarColor";
-    /** Attribute for translucency property. */
-    public static final String ATTR_TRANSLUCENT = "windowTranslucentStatus";
-
-    /**
-     * Constructor to be used when creating the {@link StatusBar} as a regular control. This
-     * is currently used by the theme editor.
-     */
-    @SuppressWarnings("UnusedParameters")
-    public StatusBar(Context context, AttributeSet attrs) {
-        this((BridgeContext) context,
-                Density.getEnum(((BridgeContext) context).getMetrics().densityDpi),
-                ((BridgeContext) context).getConfiguration().getLayoutDirection() ==
-                        View.LAYOUT_DIRECTION_RTL,
-                (context.getApplicationInfo().flags & ApplicationInfo.FLAG_SUPPORTS_RTL) != 0,
-                context.getApplicationInfo().targetSdkVersion);
-    }
-
-    @SuppressWarnings("UnusedParameters")
-    public StatusBar(BridgeContext context, Density density, boolean isRtl, boolean rtlEnabled,
-            int simulatedPlatformVersion) {
-        // FIXME: if direction is RTL but it's not enabled in application manifest, mirror this bar.
-        super(context, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml",
-                simulatedPlatformVersion);
-        mSimulatedPlatformVersion = simulatedPlatformVersion;
-
-        // FIXME: use FILL_H?
-        setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT);
-
-        int color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT);
-        setBackgroundColor(color == 0 ? Config.getStatusBarColor(simulatedPlatformVersion) : color);
-
-        // Cannot access the inside items through id because no R.id values have been
-        // created for them.
-        // We do know the order though.
-        // 0 is the spacer
-        loadIcon(1, "stat_sys_wifi_signal_4_fully."
-                        + Config.getWifiIconType(simulatedPlatformVersion), density);
-        loadIcon(2, "stat_sys_battery_100.png", density);
-        setText(3, Config.getTime(simulatedPlatformVersion), false)
-                .setTextColor(Config.getTimeColor(simulatedPlatformVersion));
-    }
-
-    @Override
-    protected void loadIcon(int index, String iconName, Density density) {
-        if (!iconName.endsWith(".xml")) {
-            super.loadIcon(index, iconName, density);
-            return;
-        }
-        View child = getChildAt(index);
-        if (child instanceof ImageView) {
-            ImageView imageView = (ImageView) child;
-            // The xml is stored only in xhdpi.
-            IconLoader iconLoader = new IconLoader(iconName, Density.XHIGH,
-                    mSimulatedPlatformVersion, null);
-            InputStream stream = iconLoader.getIcon();
-
-            if (stream != null) {
-                try {
-                    BridgeXmlBlockParser parser = new BridgeXmlBlockParser(
-                            ParserFactory.create(stream, null), (BridgeContext) mContext, true);
-                    imageView.setImageDrawable(
-                            Drawable.createFromXml(mContext.getResources(), parser));
-                } catch (XmlPullParserException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e,
-                            null);
-                } catch (IOException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e,
-                            null);
-                }
-            }
-        }
-    }
-
-    @Override
-    protected TextView getStyleableTextView() {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java
deleted file mode 100644
index 0435280..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java
+++ /dev/null
@@ -1,58 +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.layoutlib.bridge.bars;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.resources.Density;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.LinearLayout;
-
-/**
- * Navigation Bar for the Theme Editor preview.
- *
- * For small bars, it is identical to {@link NavigationBar}.
- * But wide bars from {@link NavigationBar} are too wide for the Theme Editor preview.
- * To solve that problem, {@link ThemePreviewNavigationBar} use the layout for small bars,
- * and have no padding on the sides. That way, they have a similar look as the true ones,
- * and they fit in the Theme Editor preview.
- */
-public class ThemePreviewNavigationBar extends NavigationBar {
-    private static final int PADDING_WIDTH_SW600 = 0;
-
-    @SuppressWarnings("unused")
-    public ThemePreviewNavigationBar(Context context, AttributeSet attrs) {
-        super((BridgeContext) context,
-                Density.getEnum(((BridgeContext) context).getMetrics().densityDpi),
-                LinearLayout.HORIZONTAL, // In this mode, it doesn't need to be render vertically
-                ((BridgeContext) context).getConfiguration().getLayoutDirection() ==
-                        View.LAYOUT_DIRECTION_RTL,
-                (context.getApplicationInfo().flags & ApplicationInfo.FLAG_SUPPORTS_RTL) != 0,
-                0, LAYOUT_XML);
-    }
-
-    @Override
-    protected int getSidePadding(float sw) {
-        if (sw >= 600) {
-            return PADDING_WIDTH_SW600;
-        }
-        return super.getSidePadding(sw);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
deleted file mode 100644
index 4fe1001..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
+++ /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.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-public class TitleBar extends CustomBar {
-
-    private TextView mTextView;
-
-    public TitleBar(BridgeContext context, String label, int simulatedPlatformVersion) {
-        super(context, LinearLayout.HORIZONTAL, "/bars/title_bar.xml", "title_bar.xml",
-                simulatedPlatformVersion);
-
-        // Cannot access the inside items through id because no R.id values have been
-        // created for them.
-        // We do know the order though.
-        mTextView = setText(0, label, true);
-
-        setStyle("windowTitleBackgroundStyle");
-    }
-
-    @Override
-    protected TextView getStyleableTextView() {
-        return mTextView;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
deleted file mode 100644
index 11da445..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.layoutlib.bridge.util.Debug;
-import com.android.layoutlib.bridge.util.SparseWeakArray;
-
-import android.annotation.Nullable;
-import android.util.SparseArray;
-
-import java.io.PrintStream;
-import java.lang.ref.WeakReference;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Manages native delegates.
- *
- * This is used in conjunction with layoublib_create: certain Android java classes are mere
- * wrappers around a heavily native based implementation, and we need a way to run these classes
- * in our Android Studio rendering framework without bringing all the native code from the Android
- * platform.
- *
- * Thus we instruct layoutlib_create to modify the bytecode of these classes to replace their
- * native methods by "delegate calls".
- *
- * For example, a native method android.graphics.Matrix.init(...) will actually become
- * a call to android.graphics.Matrix_Delegate.init(...).
- *
- * The Android java classes that use native code uses an int (Java side) to reference native
- * objects. This int is generally directly the pointer to the C structure counterpart.
- * Typically a creation method will return such an int, and then this int will be passed later
- * to a Java method to identify the C object to manipulate.
- *
- * Since we cannot use the Java object reference as the int directly, DelegateManager manages the
- * int -> Delegate class link.
- *
- * Native methods usually always have the int as parameters. The first thing the delegate method
- * will do is call {@link #getDelegate(long)} to get the Java object matching the int.
- *
- * Typical native init methods are returning a new int back to the Java class, so
- * {@link #addNewDelegate(Object)} does the same.
- *
- * The JNI references are counted, so we do the same through a {@link WeakReference}. Because
- * the Java object needs to count as a reference (even though it only holds an int), we use the
- * following mechanism:
- *
- * - {@link #addNewDelegate(Object)} and {@link #removeJavaReferenceFor(long)} adds and removes
- *   the delegate to/from a set. This set holds the reference and prevents the GC from reclaiming
- *   the delegate.
- *
- * - {@link #addNewDelegate(Object)} also adds the delegate to a {@link SparseArray} that holds a
- *   {@link WeakReference} to the delegate. This allows the delegate to be deleted automatically
- *   when nothing references it. This means that any class that holds a delegate (except for the
- *   Java main class) must not use the int but the Delegate class instead. The integers must
- *   only be used in the API between the main Java class and the Delegate.
- *
- * @param <T> the delegate class to manage
- */
-public final class DelegateManager<T> {
-    @SuppressWarnings("FieldCanBeLocal")
-    private final Class<T> mClass;
-    private static final SparseWeakArray<Object> sDelegates = new SparseWeakArray<>();
-    /** Set used to store delegates when their main object holds a reference to them.
-     * This is to ensure that the WeakReference in the SparseWeakArray doesn't get GC'ed
-     * @see #addNewDelegate(Object)
-     * @see #removeJavaReferenceFor(long)
-     */
-    private static final Set<Object> sJavaReferences = new HashSet<>();
-    private static final AtomicLong sDelegateCounter = new AtomicLong(1);
-
-    public DelegateManager(Class<T> theClass) {
-        mClass = theClass;
-    }
-
-    /**
-     * Returns the delegate from the given native int.
-     * <p>
-     * If the int is zero, then this will always return null.
-     * <p>
-     * If the int is non zero and the delegate is not found, this will throw an assert.
-     *
-     * @param native_object the native int.
-     * @return the delegate or null if not found.
-     */
-    @Nullable
-    public T getDelegate(long native_object) {
-        if (native_object > 0) {
-            Object delegate;
-            synchronized (DelegateManager.class) {
-                delegate = sDelegates.get(native_object);
-            }
-
-            if (Debug.DEBUG) {
-                if (delegate == null) {
-                    System.err.println("Unknown " + mClass.getSimpleName() + " with int " +
-                            native_object);
-                }
-            }
-
-            assert delegate != null;
-            //noinspection unchecked
-            return (T)delegate;
-        }
-        return null;
-    }
-
-    /**
-     * Adds a delegate to the manager and returns the native int used to identify it.
-     * @param newDelegate the delegate to add
-     * @return a unique native int to identify the delegate
-     */
-    public long addNewDelegate(T newDelegate) {
-        long native_object = sDelegateCounter.getAndIncrement();
-        synchronized (DelegateManager.class) {
-            sDelegates.put(native_object, newDelegate);
-            // Only for development: assert !sJavaReferences.contains(newDelegate);
-            sJavaReferences.add(newDelegate);
-        }
-
-        if (Debug.DEBUG) {
-            System.out.println(
-                    "New " + mClass.getSimpleName() + " " +
-                            "with int " +
-                            native_object);
-        }
-
-        return native_object;
-    }
-
-    /**
-     * Removes the main reference on the given delegate.
-     * @param native_object the native integer representing the delegate.
-     */
-    public void removeJavaReferenceFor(long native_object) {
-        synchronized (DelegateManager.class) {
-            T delegate = getDelegate(native_object);
-
-            if (Debug.DEBUG) {
-                System.out.println("Removing main Java ref on " + mClass.getSimpleName() +
-                        " with int " + native_object);
-            }
-
-            sJavaReferences.remove(delegate);
-        }
-    }
-
-    public synchronized static void dump(PrintStream out) {
-        for (Object reference : sJavaReferences) {
-            int idx = sDelegates.indexOfValue(reference);
-            out.printf("[%d] %s\n", sDelegates.keyAt(idx), reference.getClass().getSimpleName());
-        }
-        out.printf("\nTotal number of objects: %d\n", sJavaReferences.size());
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
deleted file mode 100644
index 7526e09..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
+++ /dev/null
@@ -1,885 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter_Delegate;
-import android.graphics.Paint;
-import android.graphics.Paint_Delegate;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.graphics.Region_Delegate;
-import android.graphics.Shader_Delegate;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Area;
-import java.awt.geom.NoninvertibleTransformException;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-
-/**
- * Class representing a graphics context snapshot, as well as a context stack as a linked list.
- * <p>
- * This is based on top of {@link Graphics2D} but can operate independently if none are available
- * yet when setting transforms and clip information.
- * <p>
- * This allows for drawing through {@link #draw(Drawable, Paint_Delegate, boolean, boolean)} and
- * {@link #draw(Drawable)}
- *
- * Handling of layers (created with {@link Canvas#saveLayer(RectF, Paint, int)}) is handled through
- * a list of Graphics2D for each layers. The class actually maintains a list of {@link Layer}
- * for each layer. Doing a save() will duplicate this list so that each graphics2D object
- * ({@link Layer#getGraphics()}) is configured only for the new snapshot.
- */
-public class GcSnapshot {
-
-    private final GcSnapshot mPrevious;
-    private final int mFlags;
-
-    /** list of layers. The first item in the list is always the  */
-    private final ArrayList<Layer> mLayers = new ArrayList<Layer>();
-
-    /** temp transform in case transformation are set before a Graphics2D exists */
-    private AffineTransform mTransform = null;
-    /** temp clip in case clipping is set before a Graphics2D exists */
-    private Area mClip = null;
-
-    // local layer data
-    /** a local layer created with {@link Canvas#saveLayer(RectF, Paint, int)}.
-     * If this is null, this does not mean there's no layer, just that the snapshot is not the
-     * one that created the layer.
-     * @see #getLayerSnapshot()
-     */
-    private final Layer mLocalLayer;
-    private final Paint_Delegate mLocalLayerPaint;
-    private final Rect mLayerBounds;
-
-    public interface Drawable {
-        void draw(Graphics2D graphics, Paint_Delegate paint);
-    }
-
-    /**
-     * Class containing information about a layer.
-     *
-     * This contains graphics, bitmap and layer information.
-     */
-    private static class Layer {
-        private final Graphics2D mGraphics;
-        private final Bitmap_Delegate mBitmap;
-        private final BufferedImage mImage;
-        /** the flags that were used to configure the layer. This is never changed, and passed
-         * as is when {@link #makeCopy()} is called */
-        private final int mFlags;
-        /** the original content of the layer when the next object was created. This is not
-         * passed in {@link #makeCopy()} and instead is recreated when a new layer is added
-         * (depending on its flags) */
-        private BufferedImage mOriginalCopy;
-
-        /**
-         * Creates a layer with a graphics and a bitmap. This is only used to create
-         * the base layer.
-         *
-         * @param graphics the graphics
-         * @param bitmap the bitmap
-         */
-        Layer(Graphics2D graphics, Bitmap_Delegate bitmap) {
-            mGraphics = graphics;
-            mBitmap = bitmap;
-            mImage = mBitmap.getImage();
-            mFlags = 0;
-        }
-
-        /**
-         * Creates a layer with a graphics and an image. If the image belongs to a
-         * {@link Bitmap_Delegate} (case of the base layer), then
-         * {@link Layer#Layer(Graphics2D, Bitmap_Delegate)} should be used.
-         *
-         * @param graphics the graphics the new graphics for this layer
-         * @param image the image the image from which the graphics came
-         * @param flags the flags that were used to save this layer
-         */
-        Layer(Graphics2D graphics, BufferedImage image, int flags) {
-            mGraphics = graphics;
-            mBitmap = null;
-            mImage = image;
-            mFlags = flags;
-        }
-
-        /** The Graphics2D, guaranteed to be non null */
-        Graphics2D getGraphics() {
-            return mGraphics;
-        }
-
-        /** The BufferedImage, guaranteed to be non null */
-        BufferedImage getImage() {
-            return mImage;
-        }
-
-        /** Returns the layer save flags. This is only valid for additional layers.
-         * For the base layer this will always return 0;
-         * For a given layer, all further copies of this {@link Layer} object in new snapshots
-         * will always return the same value.
-         */
-        int getFlags() {
-            return mFlags;
-        }
-
-        Layer makeCopy() {
-            if (mBitmap != null) {
-                return new Layer((Graphics2D) mGraphics.create(), mBitmap);
-            }
-
-            return new Layer((Graphics2D) mGraphics.create(), mImage, mFlags);
-        }
-
-        /** sets an optional copy of the original content to be used during restore */
-        void setOriginalCopy(BufferedImage image) {
-            mOriginalCopy = image;
-        }
-
-        BufferedImage getOriginalCopy() {
-            return mOriginalCopy;
-        }
-
-        void change() {
-            if (mBitmap != null) {
-                mBitmap.change();
-            }
-        }
-
-        /**
-         * Sets the clip for the graphics2D object associated with the layer.
-         * This should be used over the normal Graphics2D setClip method.
-         *
-         * @param clipShape the shape to use a the clip shape.
-         */
-        void setClip(Shape clipShape) {
-            // because setClip is only guaranteed to work with rectangle shape,
-            // first reset the clip to max and then intersect the current (empty)
-            // clip with the shap.
-            mGraphics.setClip(null);
-            mGraphics.clip(clipShape);
-        }
-
-        /**
-         * Clips the layer with the given shape. This performs an intersect between the current
-         * clip shape and the given shape.
-         * @param shape the new clip shape.
-         */
-        public void clip(Shape shape) {
-            mGraphics.clip(shape);
-        }
-    }
-
-    /**
-     * Creates the root snapshot associating it with a given bitmap.
-     * <p>
-     * If <var>bitmap</var> is null, then {@link GcSnapshot#setBitmap(Bitmap_Delegate)} must be
-     * called before the snapshot can be used to draw. Transform and clip operations are permitted
-     * before.
-     *
-     * @param bitmap the image to associate to the snapshot or null.
-     * @return the root snapshot
-     */
-    public static GcSnapshot createDefaultSnapshot(Bitmap_Delegate bitmap) {
-        GcSnapshot snapshot = new GcSnapshot();
-        if (bitmap != null) {
-            snapshot.setBitmap(bitmap);
-        }
-
-        return snapshot;
-    }
-
-    /**
-     * Saves the current state according to the given flags and returns the new current snapshot.
-     * <p/>
-     * This is the equivalent of {@link Canvas#save(int)}
-     *
-     * @param flags the save flags.
-     * @return the new snapshot
-     *
-     * @see Canvas#save(int)
-     */
-    public GcSnapshot save(int flags) {
-        return new GcSnapshot(this, null /*layerbounds*/, null /*paint*/, flags);
-    }
-
-    /**
-     * Saves the current state and creates a new layer, and returns the new current snapshot.
-     * <p/>
-     * This is the equivalent of {@link Canvas#saveLayer(RectF, Paint, int)}
-     *
-     * @param layerBounds the layer bounds
-     * @param paint the Paint information used to blit the layer back into the layers underneath
-     *          upon restore
-     * @param flags the save flags.
-     * @return the new snapshot
-     *
-     * @see Canvas#saveLayer(RectF, Paint, int)
-     */
-    public GcSnapshot saveLayer(RectF layerBounds, Paint_Delegate paint, int flags) {
-        return new GcSnapshot(this, layerBounds, paint, flags);
-    }
-
-    /**
-     * Creates the root snapshot.
-     * {@link #setGraphics2D(Graphics2D)} will have to be called on it when possible.
-     */
-    private GcSnapshot() {
-        mPrevious = null;
-        mFlags = 0;
-        mLocalLayer = null;
-        mLocalLayerPaint = null;
-        mLayerBounds = null;
-    }
-
-    /**
-     * Creates a new {@link GcSnapshot} on top of another one, with a layer data to be restored
-     * into the main graphics when {@link #restore()} is called.
-     *
-     * @param previous the previous snapshot head.
-     * @param layerBounds the region of the layer. Optional, if null, this is a normal save()
-     * @param paint the Paint information used to blit the layer back into the layers underneath
-     *          upon restore
-     * @param flags the flags regarding what should be saved.
-     */
-    private GcSnapshot(GcSnapshot previous, RectF layerBounds, Paint_Delegate paint, int flags) {
-        assert previous != null;
-        mPrevious = previous;
-        mFlags = flags;
-
-        // make a copy of the current layers before adding the new one.
-        // This keeps the same BufferedImage reference but creates new Graphics2D for this
-        // snapshot.
-        // It does not copy whatever original copy the layers have, as they will be done
-        // only if the new layer doesn't clip drawing to itself.
-        for (Layer layer : mPrevious.mLayers) {
-            mLayers.add(layer.makeCopy());
-        }
-
-        if (layerBounds != null) {
-            // get the current transform
-            AffineTransform matrix = mLayers.get(0).getGraphics().getTransform();
-
-            // transform the layerBounds with the current transform and stores it into a int rect
-            RectF rect2 = new RectF();
-            mapRect(matrix, rect2, layerBounds);
-            mLayerBounds = new Rect();
-            rect2.round(mLayerBounds);
-
-            // get the base layer (always at index 0)
-            Layer baseLayer = mLayers.get(0);
-
-            // create the image for the layer
-            BufferedImage layerImage = new BufferedImage(
-                    baseLayer.getImage().getWidth(),
-                    baseLayer.getImage().getHeight(),
-                    (mFlags & Canvas.HAS_ALPHA_LAYER_SAVE_FLAG) != 0 ?
-                            BufferedImage.TYPE_INT_ARGB :
-                                BufferedImage.TYPE_INT_RGB);
-
-            // create a graphics for it so that drawing can be done.
-            Graphics2D layerGraphics = layerImage.createGraphics();
-
-            // because this layer inherits the current context for transform and clip,
-            // set them to one from the base layer.
-            AffineTransform currentMtx = baseLayer.getGraphics().getTransform();
-            layerGraphics.setTransform(currentMtx);
-
-            // create a new layer for this new layer and add it to the list at the end.
-            mLayers.add(mLocalLayer = new Layer(layerGraphics, layerImage, flags));
-
-            // set the clip on it.
-            Shape currentClip = baseLayer.getGraphics().getClip();
-            mLocalLayer.setClip(currentClip);
-
-            // if the drawing is not clipped to the local layer only, we save the current content
-            // of all other layers. We are only interested in the part that will actually
-            // be drawn, so we create as small bitmaps as we can.
-            // This is so that we can erase the drawing that goes in the layers below that will
-            // be coming from the layer itself.
-            if ((mFlags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0) {
-                int w = mLayerBounds.width();
-                int h = mLayerBounds.height();
-                for (int i = 0 ; i < mLayers.size() - 1 ; i++) {
-                    Layer layer = mLayers.get(i);
-                    BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
-                    Graphics2D graphics = image.createGraphics();
-                    graphics.drawImage(layer.getImage(),
-                            0, 0, w, h,
-                            mLayerBounds.left, mLayerBounds.top,
-                                    mLayerBounds.right, mLayerBounds.bottom,
-                            null);
-                    graphics.dispose();
-                    layer.setOriginalCopy(image);
-                }
-            }
-        } else {
-            mLocalLayer = null;
-            mLayerBounds = null;
-        }
-
-        mLocalLayerPaint  = paint;
-    }
-
-    public void dispose() {
-        for (Layer layer : mLayers) {
-            layer.getGraphics().dispose();
-        }
-
-        if (mPrevious != null) {
-            mPrevious.dispose();
-        }
-    }
-
-    /**
-     * Restores the top {@link GcSnapshot}, and returns the next one.
-     */
-    public GcSnapshot restore() {
-        return doRestore();
-    }
-
-    /**
-     * Restores the {@link GcSnapshot} to <var>saveCount</var>.
-     * @param saveCount the saveCount or -1 to only restore 1.
-     *
-     * @return the new head of the Gc snapshot stack.
-     */
-    public GcSnapshot restoreTo(int saveCount) {
-        return doRestoreTo(size(), saveCount);
-    }
-
-    public int size() {
-        if (mPrevious != null) {
-            return mPrevious.size() + 1;
-        }
-
-        return 1;
-    }
-
-    /**
-     * Link the snapshot to a Bitmap_Delegate.
-     * <p/>
-     * This is only for the case where the snapshot was created with a null image when calling
-     * {@link #createDefaultSnapshot(Bitmap_Delegate)}, and is therefore not yet linked to
-     * a previous snapshot.
-     * <p/>
-     * If any transform or clip information was set before, they are put into the Graphics object.
-     * @param bitmap the bitmap to link to.
-     */
-    public void setBitmap(Bitmap_Delegate bitmap) {
-        // create a new Layer for the bitmap. This will be the base layer.
-        Graphics2D graphics2D = bitmap.getImage().createGraphics();
-        Layer baseLayer = new Layer(graphics2D, bitmap);
-
-        // Set the current transform and clip which can either come from mTransform/mClip if they
-        // were set when there was no bitmap/layers or from the current base layers if there is
-        // one already.
-
-        graphics2D.setTransform(getTransform());
-        // reset mTransform in case there was one.
-        mTransform = null;
-
-        baseLayer.setClip(getClip());
-        // reset mClip in case there was one.
-        mClip = null;
-
-        // replace whatever current layers we have with this.
-        mLayers.clear();
-        mLayers.add(baseLayer);
-
-    }
-
-    public void translate(float dx, float dy) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().translate(dx, dy);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.translate(dx, dy);
-        }
-    }
-
-    public void rotate(double radians) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().rotate(radians);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.rotate(radians);
-        }
-    }
-
-    public void scale(float sx, float sy) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().scale(sx, sy);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.scale(sx, sy);
-        }
-    }
-
-    public AffineTransform getTransform() {
-        if (mLayers.size() > 0) {
-            // all graphics2D in the list have the same transform
-            return mLayers.get(0).getGraphics().getTransform();
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            return mTransform;
-        }
-    }
-
-    public void setTransform(AffineTransform transform) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().setTransform(transform);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.setTransform(transform);
-        }
-    }
-
-    public boolean clip(Shape shape, int regionOp) {
-        // Simple case of intersect with existing layers.
-        // Because Graphics2D#setClip works a bit peculiarly, we optimize
-        // the case of clipping by intersection, as it's supported natively.
-        if (regionOp == Region.Op.INTERSECT.nativeInt && mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.clip(shape);
-            }
-
-            Shape currentClip = getClip();
-            return currentClip != null && currentClip.getBounds().isEmpty() == false;
-        }
-
-        Area area = null;
-
-        if (regionOp == Region.Op.REPLACE.nativeInt) {
-            area = new Area(shape);
-        } else {
-            area = Region_Delegate.combineShapes(getClip(), shape, regionOp);
-        }
-
-        assert area != null;
-
-        if (mLayers.size() > 0) {
-            if (area != null) {
-                for (Layer layer : mLayers) {
-                    layer.setClip(area);
-                }
-            }
-
-            Shape currentClip = getClip();
-            return currentClip != null && currentClip.getBounds().isEmpty() == false;
-        } else {
-            if (area != null) {
-                mClip = area;
-            } else {
-                mClip = new Area();
-            }
-
-            return mClip.getBounds().isEmpty() == false;
-        }
-    }
-
-    public boolean clipRect(float left, float top, float right, float bottom, int regionOp) {
-        return clip(new Rectangle2D.Float(left, top, right - left, bottom - top), regionOp);
-    }
-
-    /**
-     * Returns the current clip, or null if none have been setup.
-     */
-    public Shape getClip() {
-        if (mLayers.size() > 0) {
-            // they all have the same clip
-            return mLayers.get(0).getGraphics().getClip();
-        } else {
-            return mClip;
-        }
-    }
-
-    private GcSnapshot doRestoreTo(int size, int saveCount) {
-        if (size <= saveCount) {
-            return this;
-        }
-
-        // restore the current one first.
-        GcSnapshot previous = doRestore();
-
-        if (size == saveCount + 1) { // this was the only one that needed restore.
-            return previous;
-        } else {
-            return previous.doRestoreTo(size - 1, saveCount);
-        }
-    }
-
-    /**
-     * Executes the Drawable's draw method, with a null paint delegate.
-     * <p/>
-     * Note that the method can be called several times if there are more than one active layer.
-     */
-    public void draw(Drawable drawable) {
-        draw(drawable, null, false /*compositeOnly*/, false /*forceSrcMode*/);
-    }
-
-    /**
-     * Executes the Drawable's draw method.
-     * <p/>
-     * Note that the method can be called several times if there are more than one active layer.
-     * @param compositeOnly whether the paint is used for composite only. This is typically
-     *          the case for bitmaps.
-     * @param forceSrcMode if true, this overrides the composite to be SRC
-     */
-    public void draw(Drawable drawable, Paint_Delegate paint, boolean compositeOnly,
-            boolean forceSrcMode) {
-        int forceMode = forceSrcMode ? AlphaComposite.SRC : 0;
-        // the current snapshot may not have a mLocalLayer (ie it was created on save() instead
-        // of saveLayer(), but that doesn't mean there's no layer.
-        // mLayers however saves all the information we need (flags).
-        if (mLayers.size() == 1) {
-            // no layer, only base layer. easy case.
-            drawInLayer(mLayers.get(0), drawable, paint, compositeOnly, forceMode);
-        } else {
-            // draw in all the layers until the layer save flags tells us to stop (ie drawing
-            // in that layer is limited to the layer itself.
-            int flags;
-            int i = mLayers.size() - 1;
-
-            do {
-                Layer layer = mLayers.get(i);
-
-                drawInLayer(layer, drawable, paint, compositeOnly, forceMode);
-
-                // then go to previous layer, only if there are any left, and its flags
-                // doesn't restrict drawing to the layer itself.
-                i--;
-                flags = layer.getFlags();
-            } while (i >= 0 && (flags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0);
-        }
-    }
-
-    private void drawInLayer(Layer layer, Drawable drawable, Paint_Delegate paint,
-            boolean compositeOnly, int forceMode) {
-        Graphics2D originalGraphics = layer.getGraphics();
-        if (paint == null) {
-            drawOnGraphics((Graphics2D) originalGraphics.create(), drawable,
-                    null /*paint*/, layer);
-        } else {
-            ColorFilter_Delegate filter = paint.getColorFilter();
-            if (filter == null || !filter.isSupported()) {
-                // get a Graphics2D object configured with the drawing parameters.
-                Graphics2D configuredGraphics = createCustomGraphics(originalGraphics, paint,
-                        compositeOnly, forceMode);
-                drawOnGraphics(configuredGraphics, drawable, paint, layer);
-                return;
-            }
-
-            int x = 0;
-            int y = 0;
-            int width;
-            int height;
-            Rectangle clipBounds = originalGraphics.getClip() != null ? originalGraphics
-                    .getClipBounds() : null;
-            if (clipBounds != null) {
-                if (clipBounds.width == 0 || clipBounds.height == 0) {
-                    // Clip is 0 so no need to paint anything.
-                    return;
-                }
-                // If we have clipBounds available, use them as they will always be
-                // smaller than the full layer size.
-                x = clipBounds.x;
-                y = clipBounds.y;
-                width = clipBounds.width;
-                height = clipBounds.height;
-            } else {
-                width = layer.getImage().getWidth();
-                height = layer.getImage().getHeight();
-            }
-
-            // Create a temporary image to which the color filter will be applied.
-            BufferedImage image = new BufferedImage(width, height,
-                    BufferedImage.TYPE_INT_ARGB);
-            Graphics2D imageBaseGraphics = (Graphics2D) image.getGraphics();
-            // Configure the Graphics2D object with drawing parameters and shader.
-            Graphics2D imageGraphics = createCustomGraphics(
-                    imageBaseGraphics, paint, compositeOnly,
-                    AlphaComposite.SRC_OVER);
-            // get a Graphics2D object configured with the drawing parameters, but no shader.
-            Graphics2D configuredGraphics = createCustomGraphics(originalGraphics, paint,
-                    true /*compositeOnly*/, forceMode);
-            try {
-                // The main draw operation.
-                // We translate the operation to take into account that the rendering does not
-                // know about the clipping area.
-                imageGraphics.translate(-x, -y);
-                drawable.draw(imageGraphics, paint);
-
-                // Apply the color filter.
-                // Restore the original coordinates system and apply the filter only to the
-                // clipped area.
-                imageGraphics.translate(x, y);
-                filter.applyFilter(imageGraphics, width, height);
-
-                // Draw the tinted image on the main layer using as start point the clipping
-                // upper left coordinates.
-                configuredGraphics.drawImage(image, x, y, null);
-                layer.change();
-            } finally {
-                // dispose Graphics2D objects
-                imageGraphics.dispose();
-                imageBaseGraphics.dispose();
-                configuredGraphics.dispose();
-            }
-        }
-    }
-
-    private void drawOnGraphics(Graphics2D g, Drawable drawable, Paint_Delegate paint,
-            Layer layer) {
-        try {
-            drawable.draw(g, paint);
-            layer.change();
-        } finally {
-            g.dispose();
-        }
-    }
-
-    private GcSnapshot doRestore() {
-        if (mPrevious != null) {
-            if (mLocalLayer != null) {
-                // prepare to blit the layers in which we have draw, in the layer beneath
-                // them, starting with the top one (which is the current local layer).
-                int i = mLayers.size() - 1;
-                int flags;
-                do {
-                    Layer dstLayer = mLayers.get(i - 1);
-
-                    restoreLayer(dstLayer);
-
-                    flags = dstLayer.getFlags();
-                    i--;
-                } while (i > 0 && (flags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0);
-            }
-
-            // if this snapshot does not save everything, then set the previous snapshot
-            // to this snapshot content
-
-            // didn't save the matrix? set the current matrix on the previous snapshot
-            if ((mFlags & Canvas.MATRIX_SAVE_FLAG) == 0) {
-                AffineTransform mtx = getTransform();
-                for (Layer layer : mPrevious.mLayers) {
-                    layer.getGraphics().setTransform(mtx);
-                }
-            }
-
-            // didn't save the clip? set the current clip on the previous snapshot
-            if ((mFlags & Canvas.CLIP_SAVE_FLAG) == 0) {
-                Shape clip = getClip();
-                for (Layer layer : mPrevious.mLayers) {
-                    layer.setClip(clip);
-                }
-            }
-        }
-
-        for (Layer layer : mLayers) {
-            layer.getGraphics().dispose();
-        }
-
-        return mPrevious;
-    }
-
-    private void restoreLayer(Layer dstLayer) {
-
-        Graphics2D baseGfx = dstLayer.getImage().createGraphics();
-
-        // if the layer contains an original copy this means the flags
-        // didn't restrict drawing to the local layer and we need to make sure the
-        // layer bounds in the layer beneath didn't receive any drawing.
-        // so we use the originalCopy to erase the new drawings in there.
-        BufferedImage originalCopy = dstLayer.getOriginalCopy();
-        if (originalCopy != null) {
-            Graphics2D g = (Graphics2D) baseGfx.create();
-            g.setComposite(AlphaComposite.Src);
-
-            g.drawImage(originalCopy,
-                    mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
-                    0, 0, mLayerBounds.width(), mLayerBounds.height(),
-                    null);
-            g.dispose();
-        }
-
-        // now draw put the content of the local layer onto the layer,
-        // using the paint information
-        Graphics2D g = createCustomGraphics(baseGfx, mLocalLayerPaint,
-                true /*alphaOnly*/, 0 /*forceMode*/);
-
-        g.drawImage(mLocalLayer.getImage(),
-                mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
-                mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
-                null);
-        g.dispose();
-
-        baseGfx.dispose();
-    }
-
-    /**
-     * Creates a new {@link Graphics2D} based on the {@link Paint} parameters.
-     * <p/>The object must be disposed ({@link Graphics2D#dispose()}) after being used.
-     */
-    private Graphics2D createCustomGraphics(Graphics2D original, Paint_Delegate paint,
-            boolean compositeOnly, int forceMode) {
-        // make new one graphics
-        Graphics2D g = (Graphics2D) original.create();
-
-        // configure it
-
-        if (paint.isAntiAliased()) {
-            g.setRenderingHint(
-                    RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-            g.setRenderingHint(
-                    RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
-        }
-
-        // set the shader first, as it'll replace the color if it can be used it.
-        boolean customShader = false;
-        if (!compositeOnly) {
-            customShader = setShader(g, paint);
-            // set the stroke
-            g.setStroke(paint.getJavaStroke());
-        }
-        // set the composite.
-        setComposite(g, paint, compositeOnly || customShader, forceMode);
-
-        return g;
-    }
-
-    private boolean setShader(Graphics2D g, Paint_Delegate paint) {
-        Shader_Delegate shaderDelegate = paint.getShader();
-        if (shaderDelegate != null) {
-            if (shaderDelegate.isSupported()) {
-                java.awt.Paint shaderPaint = shaderDelegate.getJavaPaint();
-                assert shaderPaint != null;
-                if (shaderPaint != null) {
-                    g.setPaint(shaderPaint);
-                    return true;
-                }
-            } else {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_SHADER,
-                        shaderDelegate.getSupportMessage(),
-                        null /*throwable*/, null /*data*/);
-            }
-        }
-
-        // if no shader, use the paint color
-        g.setColor(new Color(paint.getColor(), true /*hasAlpha*/));
-
-        return false;
-    }
-
-    private void setComposite(Graphics2D g, Paint_Delegate paint, boolean usePaintAlpha,
-            int forceMode) {
-        // the alpha for the composite. Always opaque if the normal paint color is used since
-        // it contains the alpha
-        int alpha = usePaintAlpha ? paint.getAlpha() : 0xFF;
-        if (forceMode != 0) {
-            g.setComposite(AlphaComposite.getInstance(forceMode, (float) alpha / 255.f));
-            return;
-        }
-        Mode mode = PorterDuff.intToMode(paint.getPorterDuffMode());
-        Composite composite = PorterDuffUtility.getComposite(mode, alpha);
-        g.setComposite(composite);
-    }
-
-    private void mapRect(AffineTransform matrix, RectF dst, RectF src) {
-        // array with 4 corners
-        float[] corners = new float[] {
-                src.left, src.top,
-                src.right, src.top,
-                src.right, src.bottom,
-                src.left, src.bottom,
-        };
-
-        // apply the transform to them.
-        matrix.transform(corners, 0, corners, 0, 4);
-
-        // now put the result in the rect. We take the min/max of Xs and min/max of Ys
-        dst.left = Math.min(Math.min(corners[0], corners[2]), Math.min(corners[4], corners[6]));
-        dst.right = Math.max(Math.max(corners[0], corners[2]), Math.max(corners[4], corners[6]));
-
-        dst.top = Math.min(Math.min(corners[1], corners[3]), Math.min(corners[5], corners[7]));
-        dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7]));
-    }
-
-    /**
-     * Returns the clip of the oldest snapshot of the stack, appropriately translated to be
-     * expressed in the coordinate system of the latest snapshot.
-     */
-    public Rectangle getOriginalClip() {
-        GcSnapshot originalSnapshot = this;
-        while (originalSnapshot.mPrevious != null) {
-            originalSnapshot = originalSnapshot.mPrevious;
-        }
-        if (originalSnapshot.mLayers.isEmpty()) {
-            return null;
-        }
-        Graphics2D graphics2D = originalSnapshot.mLayers.get(0).getGraphics();
-        Rectangle bounds = graphics2D.getClipBounds();
-        if (bounds == null) {
-            return null;
-        }
-        try {
-            AffineTransform originalTransform =
-                    ((Graphics2D) graphics2D.create()).getTransform().createInverse();
-            AffineTransform latestTransform = getTransform().createInverse();
-            bounds.x += latestTransform.getTranslateX() - originalTransform.getTranslateX();
-            bounds.y += latestTransform.getTranslateY() - originalTransform.getTranslateY();
-        } catch (NoninvertibleTransformException e) {
-            Bridge.getLog().warning(null, "Non invertible transformation", null);
-        }
-        return bounds;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
deleted file mode 100644
index 287334c..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
+++ /dev/null
@@ -1,467 +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.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.bars.AppCompatActionBar;
-import com.android.layoutlib.bridge.bars.BridgeActionBar;
-import com.android.layoutlib.bridge.bars.Config;
-import com.android.layoutlib.bridge.bars.FrameworkActionBar;
-import com.android.layoutlib.bridge.bars.NavigationBar;
-import com.android.layoutlib.bridge.bars.StatusBar;
-import com.android.layoutlib.bridge.bars.TitleBar;
-import com.android.resources.Density;
-import com.android.resources.ResourceType;
-import com.android.resources.ScreenOrientation;
-
-import android.annotation.NonNull;
-import android.graphics.drawable.Drawable;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.AttachInfo_Accessor;
-import android.view.View;
-import android.view.ViewRootImpl;
-import android.view.ViewRootImpl_Accessor;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.widget.LinearLayout.VERTICAL;
-import static com.android.layoutlib.bridge.impl.ResourceHelper.getBooleanThemeValue;
-
-/**
- * The Layout used to create the system decor.
- *
- * The layout inflated will contain a content frame where the user's layout can be inflated.
- * <pre>
- *  +-------------------------------------------------+---+
- *  | Status bar                                      | N |
- *  +-------------------------------------------------+ a |
- *  | Title/Action bar (optional)                     | v |
- *  +-------------------------------------------------+   |
- *  | Content, vertical extending                     | b |
- *  |                                                 | a |
- *  |                                                 | r |
- *  +-------------------------------------------------+---+
- * </pre>
- * or
- * <pre>
- *  +-------------------------------------+
- *  | Status bar                          |
- *  +-------------------------------------+
- *  | Title/Action bar (optional)         |
- *  +-------------------------------------+
- *  | Content, vertical extending         |
- *  |                                     |
- *  |                                     |
- *  +-------------------------------------+
- *  | Nav bar                             |
- *  +-------------------------------------+
- * </pre>
- *
- */
-class Layout extends RelativeLayout {
-
-    // Theme attributes used for configuring appearance of the system decor.
-    private static final String ATTR_WINDOW_FLOATING = "windowIsFloating";
-    private static final String ATTR_WINDOW_BACKGROUND = "windowBackground";
-    private static final String ATTR_WINDOW_FULL_SCREEN = "windowFullscreen";
-    private static final String ATTR_NAV_BAR_HEIGHT = "navigation_bar_height";
-    private static final String ATTR_NAV_BAR_WIDTH = "navigation_bar_width";
-    private static final String ATTR_STATUS_BAR_HEIGHT = "status_bar_height";
-    private static final String ATTR_WINDOW_ACTION_BAR = "windowActionBar";
-    private static final String ATTR_ACTION_BAR_SIZE = "actionBarSize";
-    private static final String ATTR_WINDOW_NO_TITLE = "windowNoTitle";
-    private static final String ATTR_WINDOW_TITLE_SIZE = "windowTitleSize";
-    private static final String ATTR_WINDOW_TRANSLUCENT_STATUS = StatusBar.ATTR_TRANSLUCENT;
-    private static final String ATTR_WINDOW_TRANSLUCENT_NAV = NavigationBar.ATTR_TRANSLUCENT;
-
-    // Default sizes
-    private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
-    private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
-    private static final int DEFAULT_NAV_BAR_SIZE = 48;
-
-    // Ids assigned to components created. This is so that we can refer to other components in
-    // layout params.
-    private static final String ID_NAV_BAR = "navBar";
-    private static final String ID_STATUS_BAR = "statusBar";
-    private static final String ID_TITLE_BAR = "titleBar";
-    // Prefix used with the above ids in order to make them unique in framework namespace.
-    private static final String ID_PREFIX = "android_layoutlib_";
-
-    /**
-     * Temporarily store the builder so that it doesn't have to be passed to all methods used
-     * during inflation.
-     */
-    private Builder mBuilder;
-
-    /**
-     * This holds user's layout.
-     */
-    private FrameLayout mContentRoot;
-
-    public Layout(@NonNull Builder builder) {
-        super(builder.mContext);
-        mBuilder = builder;
-        if (builder.mWindowBackground != null) {
-            Drawable d = ResourceHelper.getDrawable(builder.mWindowBackground, builder.mContext);
-            setBackground(d);
-        }
-
-        int simulatedPlatformVersion = getParams().getSimulatedPlatformVersion();
-        HardwareConfig hwConfig = getParams().getHardwareConfig();
-        Density density = hwConfig.getDensity();
-        boolean isRtl = Bridge.isLocaleRtl(getParams().getLocale());
-        setLayoutDirection(isRtl? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR);
-
-        NavigationBar navBar = null;
-        if (mBuilder.hasNavBar()) {
-            navBar = createNavBar(getContext(), density, isRtl, getParams().isRtlSupported(),
-                    simulatedPlatformVersion);
-        }
-
-        StatusBar statusBar = null;
-        if (builder.mStatusBarSize > 0) {
-            statusBar = createStatusBar(getContext(), density, isRtl, getParams().isRtlSupported(),
-                    simulatedPlatformVersion);
-        }
-
-        View actionBar = null;
-        TitleBar titleBar = null;
-        if (builder.mActionBarSize > 0) {
-            BridgeActionBar bar = createActionBar(getContext(), getParams());
-            mContentRoot = bar.getContentRoot();
-            actionBar = bar.getRootView();
-        } else if (mBuilder.mTitleBarSize > 0) {
-            titleBar = createTitleBar(getContext(), getParams().getAppLabel(),
-                    simulatedPlatformVersion);
-        }
-
-        addViews(titleBar, mContentRoot == null ? (mContentRoot = createContentFrame()) : actionBar,
-                statusBar, navBar);
-        // Done with the builder. Don't hold a reference to it.
-        mBuilder = null;
-     }
-
-    @NonNull
-    private FrameLayout createContentFrame() {
-        FrameLayout contentRoot = new FrameLayout(getContext());
-        LayoutParams params = createLayoutParams(MATCH_PARENT, MATCH_PARENT);
-        int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE;
-        if (mBuilder.hasSolidNavBar()) {
-            params.addRule(rule, getId(ID_NAV_BAR));
-        }
-        int below = -1;
-        if (mBuilder.mActionBarSize <= 0 && mBuilder.mTitleBarSize > 0) {
-            below = getId(ID_TITLE_BAR);
-        } else if (mBuilder.hasSolidStatusBar()) {
-            below = getId(ID_STATUS_BAR);
-        }
-        if (below != -1) {
-            params.addRule(BELOW, below);
-        }
-        contentRoot.setLayoutParams(params);
-        return contentRoot;
-    }
-
-    @NonNull
-    private LayoutParams createLayoutParams(int width, int height) {
-        DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
-        if (width > 0) {
-            width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, width, metrics);
-        }
-        if (height > 0) {
-            height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, height, metrics);
-        }
-        return new LayoutParams(width, height);
-    }
-
-    @NonNull
-    public FrameLayout getContentRoot() {
-        return mContentRoot;
-    }
-
-    @NonNull
-    private SessionParams getParams() {
-        return mBuilder.mParams;
-    }
-
-    @NonNull
-    @Override
-    public BridgeContext getContext(){
-        return (BridgeContext) super.getContext();
-    }
-
-    /**
-     * @param isRtl    whether the current locale is an RTL locale.
-     * @param isRtlSupported    whether the applications supports RTL (i.e. has supportsRtl=true
-     * in the manifest and targetSdkVersion >= 17.
-     */
-    @NonNull
-    private StatusBar createStatusBar(BridgeContext context, Density density, boolean isRtl,
-            boolean isRtlSupported, int simulatedPlatformVersion) {
-        StatusBar statusBar =
-                new StatusBar(context, density, isRtl, isRtlSupported, simulatedPlatformVersion);
-        LayoutParams params = createLayoutParams(MATCH_PARENT, mBuilder.mStatusBarSize);
-        if (mBuilder.isNavBarVertical()) {
-            params.addRule(START_OF, getId(ID_NAV_BAR));
-        }
-        statusBar.setLayoutParams(params);
-        statusBar.setId(getId(ID_STATUS_BAR));
-        return statusBar;
-    }
-
-    private BridgeActionBar createActionBar(@NonNull BridgeContext context,
-            @NonNull SessionParams params) {
-        boolean isMenu = "menu".equals(params.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG));
-
-        BridgeActionBar actionBar;
-        if (context.isAppCompatTheme() && !isMenu) {
-            actionBar = new AppCompatActionBar(context, params);
-        } else {
-            actionBar = new FrameworkActionBar(context, params);
-        }
-        LayoutParams layoutParams = createLayoutParams(MATCH_PARENT, MATCH_PARENT);
-        int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE;
-        if (mBuilder.hasSolidNavBar()) {
-            layoutParams.addRule(rule, getId(ID_NAV_BAR));
-        }
-        if (mBuilder.hasSolidStatusBar()) {
-            layoutParams.addRule(BELOW, getId(ID_STATUS_BAR));
-        }
-        actionBar.getRootView().setLayoutParams(layoutParams);
-        actionBar.createMenuPopup();
-        return actionBar;
-    }
-
-    @NonNull
-    private TitleBar createTitleBar(BridgeContext context, String title,
-            int simulatedPlatformVersion) {
-        TitleBar titleBar = new TitleBar(context, title, simulatedPlatformVersion);
-        LayoutParams params = createLayoutParams(MATCH_PARENT, mBuilder.mTitleBarSize);
-        if (mBuilder.hasSolidStatusBar()) {
-            params.addRule(BELOW, getId(ID_STATUS_BAR));
-        }
-        if (mBuilder.isNavBarVertical() && mBuilder.hasSolidNavBar()) {
-            params.addRule(START_OF, getId(ID_NAV_BAR));
-        }
-        titleBar.setLayoutParams(params);
-        titleBar.setId(getId(ID_TITLE_BAR));
-        return titleBar;
-    }
-
-    /**
-     * @param isRtl    whether the current locale is an RTL locale.
-     * @param isRtlSupported    whether the applications supports RTL (i.e. has supportsRtl=true
-     * in the manifest and targetSdkVersion >= 17.
-     */
-    @NonNull
-    private NavigationBar createNavBar(BridgeContext context, Density density, boolean isRtl,
-            boolean isRtlSupported, int simulatedPlatformVersion) {
-        int orientation = mBuilder.mNavBarOrientation;
-        int size = mBuilder.mNavBarSize;
-        NavigationBar navBar = new NavigationBar(context, density, orientation, isRtl,
-                isRtlSupported, simulatedPlatformVersion);
-        boolean isVertical = mBuilder.isNavBarVertical();
-        int w = isVertical ? size : MATCH_PARENT;
-        int h = isVertical ? MATCH_PARENT : size;
-        LayoutParams params = createLayoutParams(w, h);
-        params.addRule(isVertical ? ALIGN_PARENT_END : ALIGN_PARENT_BOTTOM);
-        navBar.setLayoutParams(params);
-        navBar.setId(getId(ID_NAV_BAR));
-        return navBar;
-    }
-
-    private void addViews(@NonNull View... views) {
-        for (View view : views) {
-            if (view != null) {
-                addView(view);
-            }
-        }
-    }
-
-    private int getId(String name) {
-        return Bridge.getResourceId(ResourceType.ID, ID_PREFIX + name);
-    }
-
-    @SuppressWarnings("deprecation")
-    @Override
-    public void requestFitSystemWindows() {
-        // The framework call would usually bubble up to ViewRootImpl but, in layoutlib, Layout will
-        // act as view root for most purposes. That way, we can also save going through the Handler
-        // to dispatch the new applied insets.
-        ViewRootImpl root = AttachInfo_Accessor.getRootView(this);
-        if (root != null) {
-            ViewRootImpl_Accessor.dispatchApplyInsets(root, this);
-        }
-    }
-
-    /**
-     * A helper class to help initialize the Layout.
-     */
-    static class Builder {
-        @NonNull
-        private final SessionParams mParams;
-        @NonNull
-        private final BridgeContext mContext;
-        private final RenderResources mResources;
-        
-        private final boolean mWindowIsFloating;
-        private ResourceValue mWindowBackground;
-        private int mStatusBarSize;
-        private int mNavBarSize;
-        private int mNavBarOrientation;
-        private int mActionBarSize;
-        private int mTitleBarSize;
-        private boolean mTranslucentStatus;
-        private boolean mTranslucentNav;
-
-        public Builder(@NonNull SessionParams params, @NonNull BridgeContext context) {
-            mParams = params;
-            mContext = context;
-            mResources = mParams.getResources();
-            mWindowIsFloating = getBooleanThemeValue(mResources, ATTR_WINDOW_FLOATING, true, true);
-            
-            findBackground();
-
-            if (!mParams.isForceNoDecor()) {
-                findStatusBar();
-                findActionBar();
-                findNavBar();
-            }
-        }
-
-        private void findBackground() {
-            if (!mParams.isBgColorOverridden()) {
-                mWindowBackground = mResources.findItemInTheme(ATTR_WINDOW_BACKGROUND, true);
-                mWindowBackground = mResources.resolveResValue(mWindowBackground);
-            }
-        }
-
-        private void findStatusBar() {
-            boolean windowFullScreen =
-                    getBooleanThemeValue(mResources, ATTR_WINDOW_FULL_SCREEN, true, false);
-            if (!windowFullScreen && !mWindowIsFloating) {
-                mStatusBarSize =
-                        getDimension(ATTR_STATUS_BAR_HEIGHT, true, DEFAULT_STATUS_BAR_HEIGHT);
-                mTranslucentStatus = getBooleanThemeValue(mResources,
-                        ATTR_WINDOW_TRANSLUCENT_STATUS, true, false);
-            }
-        }
-
-        private void  findActionBar() {
-            if (mWindowIsFloating) {
-                return;
-            }
-            // Check if an actionbar is needed
-            boolean isMenu = "menu".equals(mParams.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG));
-            boolean windowActionBar = isMenu ||
-                    getBooleanThemeValue(mResources, ATTR_WINDOW_ACTION_BAR,
-                            !mContext.isAppCompatTheme(), true);
-            if (windowActionBar) {
-                mActionBarSize = getDimension(ATTR_ACTION_BAR_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT);
-            } else {
-                // Maybe the gingerbread era title bar is needed
-                boolean windowNoTitle =
-                        getBooleanThemeValue(mResources, ATTR_WINDOW_NO_TITLE, true, false);
-                if (!windowNoTitle) {
-                    mTitleBarSize =
-                            getDimension(ATTR_WINDOW_TITLE_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT);
-                }
-            }
-        }
-
-        private void findNavBar() {
-            if (hasSoftwareButtons() && !mWindowIsFloating) {
-
-                // get orientation
-                HardwareConfig hwConfig = mParams.getHardwareConfig();
-                boolean barOnBottom = true;
-
-                if (hwConfig.getOrientation() == ScreenOrientation.LANDSCAPE) {
-                    int shortSize = hwConfig.getScreenHeight();
-                    int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT /
-                            hwConfig.getDensity().getDpiValue();
-
-                    // 0-599dp: "phone" UI with bar on the side
-                    // 600+dp: "tablet" UI with bar on the bottom
-                    barOnBottom = shortSizeDp >= 600;
-                }
-
-                mNavBarOrientation = barOnBottom ? LinearLayout.HORIZONTAL : VERTICAL;
-                mNavBarSize = getDimension(barOnBottom ? ATTR_NAV_BAR_HEIGHT : ATTR_NAV_BAR_WIDTH,
-                        true, DEFAULT_NAV_BAR_SIZE);
-                mTranslucentNav = getBooleanThemeValue(mResources,
-                        ATTR_WINDOW_TRANSLUCENT_NAV, true, false);
-            }
-        }
-
-        @SuppressWarnings("SameParameterValue")
-        private int getDimension(String attr, boolean isFramework, int defaultValue) {
-            ResourceValue value = mResources.findItemInTheme(attr, isFramework);
-            value = mResources.resolveResValue(value);
-            if (value != null) {
-                TypedValue typedValue = ResourceHelper.getValue(attr, value.getValue(), true);
-                if (typedValue != null) {
-                    return (int) typedValue.getDimension(mContext.getMetrics());
-                }
-            }
-            return defaultValue;
-        }
-
-        private boolean hasSoftwareButtons() {
-            return mParams.getHardwareConfig().hasSoftwareButtons();
-        }
-
-        /**
-         * Return true if the nav bar is present and not translucent
-         */
-        private boolean hasSolidNavBar() {
-            return hasNavBar() && !mTranslucentNav;
-        }
-
-        /**
-         * Return true if the status bar is present and not translucent
-         */
-        private boolean hasSolidStatusBar() {
-            return hasStatusBar() && !mTranslucentStatus;
-        }
-
-        private boolean hasNavBar() {
-            return Config.showOnScreenNavBar(mParams.getSimulatedPlatformVersion()) &&
-                    hasSoftwareButtons() && mNavBarSize > 0;
-        }
-
-        private boolean hasStatusBar() {
-            return mStatusBarSize > 0;
-        }
-
-        /**
-         * Return true if the nav bar is present and is vertical.
-         */
-        private boolean isNavBarVertical() {
-            return hasNavBar() && mNavBarOrientation == VERTICAL;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutParserWrapper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutParserWrapper.java
deleted file mode 100644
index 71e7fd2..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutParserWrapper.java
+++ /dev/null
@@ -1,377 +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.layoutlib.bridge.impl;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.Nullable;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A wrapper around XmlPullParser that can peek forward to inspect if the file is a data-binding
- * layout and some parts need to be stripped.
- */
-public class LayoutParserWrapper implements XmlPullParser {
-
-    // Data binding constants.
-    private static final String TAG_LAYOUT = "layout";
-    private static final String TAG_DATA = "data";
-    private static final String DEFAULT = "default=";
-
-    private final XmlPullParser mDelegate;
-
-    // Storage for peeked values.
-    private boolean mPeeked;
-    private int mEventType;
-    private int mDepth;
-    private int mNext;
-    private List<Attribute> mAttributes;
-    private String mText;
-    private String mName;
-
-    // Used to end the document before the actual parser ends.
-    private int mFinalDepth = -1;
-    private boolean mEndNow;
-
-    public LayoutParserWrapper(XmlPullParser delegate) {
-        mDelegate = delegate;
-    }
-
-    public LayoutParserWrapper peekTillLayoutStart() throws IOException, XmlPullParserException {
-        final int STATE_LAYOUT_NOT_STARTED = 0;  // <layout> tag not encountered yet.
-        final int STATE_ROOT_NOT_STARTED = 1;    // the main view root not found yet.
-        final int STATE_INSIDE_DATA = 2;         // START_TAG for <data> found, but not END_TAG.
-
-        int state = STATE_LAYOUT_NOT_STARTED;
-        int dataDepth = -1;    // depth of the <data> tag. Should be two.
-        while (true) {
-            int peekNext = peekNext();
-            switch (peekNext) {
-                case START_TAG:
-                    if (state == STATE_LAYOUT_NOT_STARTED) {
-                        if (mName.equals(TAG_LAYOUT)) {
-                            state = STATE_ROOT_NOT_STARTED;
-                        } else {
-                            return this; // no layout tag in the file.
-                        }
-                    } else if (state == STATE_ROOT_NOT_STARTED) {
-                        if (mName.equals(TAG_DATA)) {
-                            state = STATE_INSIDE_DATA;
-                            dataDepth = mDepth;
-                        } else {
-                            mFinalDepth = mDepth;
-                            return this;
-                        }
-                    }
-                    break;
-                case END_TAG:
-                    if (state == STATE_INSIDE_DATA) {
-                        if (mDepth <= dataDepth) {
-                            state = STATE_ROOT_NOT_STARTED;
-                        }
-                    }
-                    break;
-                case END_DOCUMENT:
-                    // No layout start found.
-                    return this;
-            }
-            // consume the peeked tag.
-            next();
-        }
-    }
-
-    private int peekNext() throws IOException, XmlPullParserException {
-        if (mPeeked) {
-            return mNext;
-        }
-        mEventType = mDelegate.getEventType();
-        mNext = mDelegate.next();
-        if (mEventType == START_TAG) {
-            int count = mDelegate.getAttributeCount();
-            mAttributes = count > 0 ? new ArrayList<Attribute>(count) :
-                    Collections.<Attribute>emptyList();
-            for (int i = 0; i < count; i++) {
-                mAttributes.add(new Attribute(mDelegate.getAttributeNamespace(i),
-                        mDelegate.getAttributeName(i), mDelegate.getAttributeValue(i)));
-            }
-        }
-        mDepth = mDelegate.getDepth();
-        mText = mDelegate.getText();
-        mName = mDelegate.getName();
-        mPeeked = true;
-        return mNext;
-    }
-
-    private void reset() {
-        mAttributes = null;
-        mText = null;
-        mName = null;
-        mPeeked = false;
-    }
-
-    @Override
-    public int next() throws XmlPullParserException, IOException {
-        int returnValue;
-        int depth;
-        if (mPeeked) {
-            returnValue = mNext;
-            depth = mDepth;
-            reset();
-        } else if (mEndNow) {
-            return END_DOCUMENT;
-        } else {
-            returnValue = mDelegate.next();
-            depth = getDepth();
-        }
-        if (returnValue == END_TAG && depth <= mFinalDepth) {
-            mEndNow = true;
-        }
-        return returnValue;
-    }
-
-    @Override
-    public int getEventType() throws XmlPullParserException {
-        return mPeeked ? mEventType : mDelegate.getEventType();
-    }
-
-    @Override
-    public int getDepth() {
-        return mPeeked ? mDepth : mDelegate.getDepth();
-    }
-
-    @Override
-    public String getName() {
-        return mPeeked ? mName : mDelegate.getName();
-    }
-
-    @Override
-    public String getText() {
-        return mPeeked ? mText : mDelegate.getText();
-    }
-
-    @Override
-    public String getAttributeValue(@Nullable String namespace, String name) {
-        String returnValue = null;
-        if (mPeeked) {
-            if (mAttributes == null) {
-                if (mEventType != START_TAG) {
-                    throw new IndexOutOfBoundsException("getAttributeValue() called when not at START_TAG.");
-                } else {
-                    return null;
-                }
-            } else {
-                for (Attribute attribute : mAttributes) {
-                    //noinspection StringEquality for nullness check.
-                    if (attribute.name.equals(name) && (attribute.namespace == namespace ||
-                            attribute.namespace != null && attribute.namespace.equals(namespace))) {
-                        returnValue = attribute.value;
-                        break;
-                    }
-                }
-            }
-        } else {
-            returnValue = mDelegate.getAttributeValue(namespace, name);
-        }
-        // Check if the value is bound via data-binding, if yes get the default value.
-        if (returnValue != null && mFinalDepth >= 0 && returnValue.startsWith("@{")) {
-            // TODO: Improve the detection of default keyword.
-            int i = returnValue.lastIndexOf(DEFAULT);
-            return i > 0 ? returnValue.substring(i + DEFAULT.length(), returnValue.length() - 1)
-                    : null;
-        }
-        return returnValue;
-    }
-
-    private static class Attribute {
-        @Nullable
-        public final String namespace;
-        public final String name;
-        public final String value;
-
-        public Attribute(@Nullable String namespace, String name, String value) {
-            this.namespace = namespace;
-            this.name = name;
-            this.value = value;
-        }
-    }
-
-    // Not affected by peeking.
-
-    @Override
-    public void setFeature(String s, boolean b) throws XmlPullParserException {
-        mDelegate.setFeature(s, b);
-    }
-
-    @Override
-    public void setProperty(String s, Object o) throws XmlPullParserException {
-        mDelegate.setProperty(s, o);
-    }
-
-    @Override
-    public void setInput(InputStream inputStream, String s) throws XmlPullParserException {
-        mDelegate.setInput(inputStream, s);
-    }
-
-    @Override
-    public void setInput(Reader reader) throws XmlPullParserException {
-        mDelegate.setInput(reader);
-    }
-
-    @Override
-    public String getInputEncoding() {
-        return mDelegate.getInputEncoding();
-    }
-
-    @Override
-    public String getNamespace(String s) {
-        return mDelegate.getNamespace(s);
-    }
-
-    @Override
-    public String getPositionDescription() {
-        return mDelegate.getPositionDescription();
-    }
-
-    @Override
-    public int getLineNumber() {
-        return mDelegate.getLineNumber();
-    }
-
-    @Override
-    public String getNamespace() {
-        return mDelegate.getNamespace();
-    }
-
-    @Override
-    public int getColumnNumber() {
-        return mDelegate.getColumnNumber();
-    }
-
-    // -- We don't care much about the methods that follow.
-
-    @Override
-    public void require(int i, String s, String s1) throws XmlPullParserException, IOException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public boolean getFeature(String s) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public void defineEntityReplacementText(String s, String s1) throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public Object getProperty(String s) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public int nextToken() throws XmlPullParserException, IOException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public int getNamespaceCount(int i) throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getNamespacePrefix(int i) throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getNamespaceUri(int i) throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public boolean isWhitespace() throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public char[] getTextCharacters(int[] ints) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getPrefix() {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public boolean isEmptyElementTag() throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public int getAttributeCount() {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributeNamespace(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributeName(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributePrefix(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributeType(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public boolean isAttributeDefault(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributeValue(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String nextText() throws XmlPullParserException, IOException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public int nextTag() throws XmlPullParserException, IOException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
deleted file mode 100644
index 1ae9cb6..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
+++ /dev/null
@@ -1,152 +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.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A factory for {@link XmlPullParser}.
- *
- */
-public class ParserFactory {
-
-    public final static boolean LOG_PARSER = false;
-
-    // Used to get a new XmlPullParser from the client.
-    @Nullable
-    private static com.android.ide.common.rendering.api.ParserFactory sParserFactory;
-
-    public static void setParserFactory(
-            @Nullable com.android.ide.common.rendering.api.ParserFactory parserFactory) {
-        sParserFactory = parserFactory;
-    }
-
-    @NonNull
-    public static XmlPullParser create(@NonNull File f)
-            throws XmlPullParserException, FileNotFoundException {
-        return create(f, false);
-    }
-
-    public static XmlPullParser create(@NonNull File f, boolean isLayout)
-      throws XmlPullParserException, FileNotFoundException {
-        InputStream stream = new FileInputStream(f);
-        return create(stream, f.getName(), f.length(), isLayout);
-    }
-    @NonNull
-    public static XmlPullParser create(@NonNull InputStream stream, @Nullable String name)
-        throws XmlPullParserException {
-        return create(stream, name, -1, false);
-    }
-
-    @NonNull
-    private static XmlPullParser create(@NonNull InputStream stream, @Nullable String name,
-            long size, boolean isLayout) throws XmlPullParserException {
-        XmlPullParser parser = instantiateParser(name);
-
-        stream = readAndClose(stream, name, size);
-
-        parser.setInput(stream, null);
-        if (isLayout) {
-            try {
-                return new LayoutParserWrapper(parser).peekTillLayoutStart();
-            } catch (IOException e) {
-                throw new XmlPullParserException(null, parser, e);
-            }
-        }
-        return parser;
-    }
-
-    @NonNull
-    public static XmlPullParser instantiateParser(@Nullable String name)
-            throws XmlPullParserException {
-        if (sParserFactory == null) {
-            throw new XmlPullParserException("ParserFactory not initialized.");
-        }
-        XmlPullParser parser = sParserFactory.createParser(name);
-        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-        return parser;
-    }
-
-    @NonNull
-    private static InputStream readAndClose(@NonNull InputStream stream, @Nullable String name,
-            long size) throws XmlPullParserException {
-        // just a sanity check. It's doubtful we'll have such big files!
-        if (size > Integer.MAX_VALUE) {
-            throw new XmlPullParserException("File " + name + " is too big to be parsed");
-        }
-        int intSize = (int) size;
-
-        // create a buffered reader to facilitate reading.
-        BufferedInputStream bufferedStream = new BufferedInputStream(stream);
-        try {
-            int avail;
-            if (intSize != -1) {
-                avail = intSize;
-            } else {
-                // get the size to read.
-                avail = bufferedStream.available();
-            }
-
-            // create the initial buffer and read it.
-            byte[] buffer = new byte[avail];
-            int read = stream.read(buffer);
-
-            // this is the easy case.
-            if (read == intSize) {
-                return new ByteArrayInputStream(buffer);
-            }
-
-            // check if there is more to read (read() does not necessarily read all that
-            // available() returned!)
-            while ((avail = bufferedStream.available()) > 0) {
-                if (read + avail > buffer.length) {
-                    // just allocate what is needed. We're mostly reading small files
-                    // so it shouldn't be too problematic.
-                    byte[] moreBuffer = new byte[read + avail];
-                    System.arraycopy(buffer, 0, moreBuffer, 0, read);
-                    buffer = moreBuffer;
-                }
-
-                read += stream.read(buffer, read, avail);
-            }
-
-            // return a new stream encapsulating this buffer.
-            return new ByteArrayInputStream(buffer);
-
-        } catch (IOException e) {
-            throw new XmlPullParserException("Failed to read " + name, null, e);
-        } finally {
-            try {
-                bufferedStream.close();
-            } catch (IOException ignored) {
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java
deleted file mode 100644
index 7b70180..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-
-import android.animation.AnimationThread;
-import android.animation.Animator;
-
-public class PlayAnimationThread extends AnimationThread {
-
-    private final Animator mAnimator;
-
-    public PlayAnimationThread(Animator animator, RenderSessionImpl scene, String animName,
-            IAnimationListener listener) {
-        super(scene, animName, listener);
-        mAnimator = animator;
-    }
-
-    @Override
-    public Result preAnimation() {
-        // start the animation. This will send a message to the handler right away, so
-        // the queue is filled when this method returns.
-        mAnimator.start();
-
-        return Status.SUCCESS.createResult();
-    }
-
-    @Override
-    public void postAnimation() {
-        // nothing to be done.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java
deleted file mode 100644
index 70e2eb1..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java
+++ /dev/null
@@ -1,107 +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.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-
-import android.graphics.BlendComposite;
-import android.graphics.BlendComposite.BlendingMode;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter_Delegate;
-
-import java.awt.AlphaComposite;
-import java.awt.Composite;
-
-/**
- * Provides various utility methods for {@link PorterDuffColorFilter_Delegate}.
- */
-public final class PorterDuffUtility {
-
-    private static final int MODES_COUNT = Mode.values().length;
-
-    // Make the class non-instantiable.
-    private PorterDuffUtility() {
-    }
-
-    /**
-     * Convert the porterDuffMode from the framework to its corresponding enum. This defaults to
-     * {@link Mode#SRC_OVER} for invalid modes.
-     */
-    public static Mode getPorterDuffMode(int porterDuffMode) {
-        if (porterDuffMode >= 0 && porterDuffMode < MODES_COUNT) {
-            return PorterDuff.intToMode(porterDuffMode);
-        }
-        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                String.format("Unknown PorterDuff.Mode: %1$d", porterDuffMode), null);
-        assert false;
-        return Mode.SRC_OVER;
-    }
-
-    /**
-     * A utility method to get the {@link Composite} that represents the filter for the given
-     * PorterDuff mode and the alpha. Defaults to {@link Mode#SRC_OVER} for invalid modes.
-     */
-    public static Composite getComposite(Mode mode, int alpha255) {
-        float alpha1 = alpha255 != 0xFF ? alpha255 / 255.f : 1.f;
-        switch (mode) {
-            case CLEAR:
-                return AlphaComposite.getInstance(AlphaComposite.CLEAR, alpha1);
-            case SRC:
-                return AlphaComposite.getInstance(AlphaComposite.SRC, alpha1);
-            case DST:
-                return AlphaComposite.getInstance(AlphaComposite.DST, alpha1);
-            case SRC_OVER:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha1);
-            case DST_OVER:
-                return AlphaComposite.getInstance(AlphaComposite.DST_OVER, alpha1);
-            case SRC_IN:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha1);
-            case DST_IN:
-                return AlphaComposite.getInstance(AlphaComposite.DST_IN, alpha1);
-            case SRC_OUT:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_OUT, alpha1);
-            case DST_OUT:
-                return AlphaComposite.getInstance(AlphaComposite.DST_OUT, alpha1);
-            case SRC_ATOP:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha1);
-            case DST_ATOP:
-                return AlphaComposite.getInstance(AlphaComposite.DST_ATOP, alpha1);
-            case XOR:
-                return AlphaComposite.getInstance(AlphaComposite.XOR, alpha1);
-            case DARKEN:
-                return BlendComposite.getInstance(BlendingMode.DARKEN, alpha1);
-            case LIGHTEN:
-                return BlendComposite.getInstance(BlendingMode.LIGHTEN, alpha1);
-            case MULTIPLY:
-                return BlendComposite.getInstance(BlendingMode.MULTIPLY, alpha1);
-            case SCREEN:
-                return BlendComposite.getInstance(BlendingMode.SCREEN, alpha1);
-            case ADD:
-                return BlendComposite.getInstance(BlendingMode.ADD, alpha1);
-            case OVERLAY:
-                return BlendComposite.getInstance(BlendingMode.OVERLAY, alpha1);
-            default:
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
-                        String.format("Unsupported PorterDuff Mode: %1$s", mode.name()),
-                        null, null /*data*/);
-
-                return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha1);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
deleted file mode 100644
index 0c53753..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderParams;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider;
-import com.android.ide.common.rendering.api.Result;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.resources.Density;
-import com.android.resources.ResourceType;
-import com.android.resources.ScreenOrientation;
-import com.android.resources.ScreenRound;
-import com.android.resources.ScreenSize;
-
-import android.content.res.Configuration;
-import android.os.HandlerThread_Delegate;
-import android.util.DisplayMetrics;
-import android.view.ViewConfiguration_Accessor;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodManager_Accessor;
-
-import java.util.Locale;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.ReentrantLock;
-
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-
-/**
- * Base class for rendering action.
- *
- * It provides life-cycle methods to init and stop the rendering.
- * The most important methods are:
- * {@link #init(long)} and {@link #acquire(long)} to start a rendering and {@link #release()}
- * after the rendering.
- *
- *
- * @param <T> the {@link RenderParams} implementation
- *
- */
-public abstract class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider {
-
-    /**
-     * The current context being rendered. This is set through {@link #acquire(long)} and
-     * {@link #init(long)}, and unset in {@link #release()}.
-     */
-    private static BridgeContext sCurrentContext = null;
-
-    private final T mParams;
-
-    private BridgeContext mContext;
-
-    /**
-     * Creates a renderAction.
-     * <p>
-     * This <b>must</b> be followed by a call to {@link RenderAction#init(long)}, which act as a
-     * call to {@link RenderAction#acquire(long)}
-     *
-     * @param params the RenderParams. This must be a copy that the action can keep
-     *
-     */
-    protected RenderAction(T params) {
-        mParams = params;
-    }
-
-    /**
-     * Initializes and acquires the scene, creating various Android objects such as context,
-     * inflater, and parser.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     *
-     * @return whether the scene was prepared
-     *
-     * @see #acquire(long)
-     * @see #release()
-     */
-    public Result init(long timeout) {
-        // acquire the lock. if the result is null, lock was just acquired, otherwise, return
-        // the result.
-        Result result = acquireLock(timeout);
-        if (result != null) {
-            return result;
-        }
-
-        HardwareConfig hardwareConfig = mParams.getHardwareConfig();
-
-        // setup the display Metrics.
-        DisplayMetrics metrics = new DisplayMetrics();
-        metrics.densityDpi = metrics.noncompatDensityDpi =
-                hardwareConfig.getDensity().getDpiValue();
-
-        metrics.density = metrics.noncompatDensity =
-                metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;
-
-        metrics.scaledDensity = metrics.noncompatScaledDensity = metrics.density;
-
-        metrics.widthPixels = metrics.noncompatWidthPixels = hardwareConfig.getScreenWidth();
-        metrics.heightPixels = metrics.noncompatHeightPixels = hardwareConfig.getScreenHeight();
-        metrics.xdpi = metrics.noncompatXdpi = hardwareConfig.getXdpi();
-        metrics.ydpi = metrics.noncompatYdpi = hardwareConfig.getYdpi();
-
-        RenderResources resources = mParams.getResources();
-
-        // build the context
-        mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources,
-                mParams.getAssets(), mParams.getLayoutlibCallback(), getConfiguration(mParams),
-                mParams.getTargetSdkVersion(), mParams.isRtlSupported());
-
-        setUp();
-
-        return SUCCESS.createResult();
-    }
-
-    /**
-     * Prepares the scene for action.
-     * <p>
-     * This call is blocking if another rendering/inflating is currently happening, and will return
-     * whether the preparation worked.
-     *
-     * The preparation can fail if another rendering took too long and the timeout was elapsed.
-     *
-     * More than one call to this from the same thread will have no effect and will return
-     * {@link Result.Status#SUCCESS}.
-     *
-     * After scene actions have taken place, only one call to {@link #release()} must be
-     * done.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     *
-     * @return whether the scene was prepared
-     *
-     * @see #release()
-     *
-     * @throws IllegalStateException if {@link #init(long)} was never called.
-     */
-    public Result acquire(long timeout) {
-        if (mContext == null) {
-            throw new IllegalStateException("After scene creation, #init() must be called");
-        }
-
-        // acquire the lock. if the result is null, lock was just acquired, otherwise, return
-        // the result.
-        Result result = acquireLock(timeout);
-        if (result != null) {
-            return result;
-        }
-
-        setUp();
-
-        return SUCCESS.createResult();
-    }
-
-    /**
-     * Acquire the lock so that the scene can be acted upon.
-     * <p>
-     * This returns null if the lock was just acquired, otherwise it returns
-     * {@link Result.Status#SUCCESS} if the lock already belonged to that thread, or another
-     * instance (see {@link Result#getStatus()}) if an error occurred.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     * @return null if the lock was just acquire or another result depending on the state.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene.
-     */
-    private Result acquireLock(long timeout) {
-        ReentrantLock lock = Bridge.getLock();
-        if (!lock.isHeldByCurrentThread()) {
-            try {
-                boolean acquired = lock.tryLock(timeout, TimeUnit.MILLISECONDS);
-
-                if (!acquired) {
-                    return ERROR_TIMEOUT.createResult();
-                }
-            } catch (InterruptedException e) {
-                return ERROR_LOCK_INTERRUPTED.createResult();
-            }
-        } else {
-            // This thread holds the lock already. Checks that this wasn't for a different context.
-            // If this is called by init, mContext will be null and so should sCurrentContext
-            // anyway
-            if (mContext != sCurrentContext) {
-                throw new IllegalStateException("Acquiring different scenes from same thread without releases");
-            }
-            return SUCCESS.createResult();
-        }
-
-        return null;
-    }
-
-    /**
-     * Cleans up the scene after an action.
-     */
-    public void release() {
-        ReentrantLock lock = Bridge.getLock();
-
-        // with the use of finally blocks, it is possible to find ourself calling this
-        // without a successful call to prepareScene. This test makes sure that unlock() will
-        // not throw IllegalMonitorStateException.
-        if (lock.isHeldByCurrentThread()) {
-            tearDown();
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Sets up the session for rendering.
-     * <p/>
-     * The counterpart is {@link #tearDown()}.
-     */
-    private void setUp() {
-        // setup the ParserFactory
-        ParserFactory.setParserFactory(mParams.getLayoutlibCallback().getParserFactory());
-
-        // make sure the Resources object references the context (and other objects) for this
-        // scene
-        mContext.initResources();
-        sCurrentContext = mContext;
-
-        // create an InputMethodManager
-        InputMethodManager.getInstance();
-
-        LayoutLog currentLog = mParams.getLog();
-        Bridge.setLog(currentLog);
-        mContext.getRenderResources().setFrameworkResourceIdProvider(this);
-        mContext.getRenderResources().setLogger(currentLog);
-    }
-
-    /**
-     * Tear down the session after rendering.
-     * <p/>
-     * The counterpart is {@link #setUp()}.
-     */
-    private void tearDown() {
-        // The context may be null, if there was an error during init().
-        if (mContext != null) {
-            // Make sure to remove static references, otherwise we could not unload the lib
-            mContext.disposeResources();
-        }
-
-        if (sCurrentContext != null) {
-            // quit HandlerThread created during this session.
-            HandlerThread_Delegate.cleanUp(sCurrentContext);
-        }
-
-        // clear the stored ViewConfiguration since the map is per density and not per context.
-        ViewConfiguration_Accessor.clearConfigurations();
-
-        // remove the InputMethodManager
-        InputMethodManager_Accessor.resetInstance();
-
-        sCurrentContext = null;
-
-        Bridge.setLog(null);
-        if (mContext != null) {
-            mContext.getRenderResources().setFrameworkResourceIdProvider(null);
-            mContext.getRenderResources().setLogger(null);
-        }
-        ParserFactory.setParserFactory(null);
-    }
-
-    public static BridgeContext getCurrentContext() {
-        return sCurrentContext;
-    }
-
-    protected T getParams() {
-        return mParams;
-    }
-
-    protected BridgeContext getContext() {
-        return mContext;
-    }
-
-    /**
-     * Returns the log associated with the session.
-     * @return the log or null if there are none.
-     */
-    public LayoutLog getLog() {
-        if (mParams != null) {
-            return mParams.getLog();
-        }
-
-        return null;
-    }
-
-    /**
-     * Checks that the lock is owned by the current thread and that the current context is the one
-     * from this scene.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     */
-    protected void checkLock() {
-        ReentrantLock lock = Bridge.getLock();
-        if (!lock.isHeldByCurrentThread()) {
-            throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
-        }
-        if (sCurrentContext != mContext) {
-            throw new IllegalStateException("Thread acquired a scene but is rendering a different one");
-        }
-    }
-
-    // VisibleForTesting
-    public static Configuration getConfiguration(RenderParams params) {
-        Configuration config = new Configuration();
-
-        HardwareConfig hardwareConfig = params.getHardwareConfig();
-
-        ScreenSize screenSize = hardwareConfig.getScreenSize();
-        if (screenSize != null) {
-            switch (screenSize) {
-                case SMALL:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_SMALL;
-                    break;
-                case NORMAL:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_NORMAL;
-                    break;
-                case LARGE:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_LARGE;
-                    break;
-                case XLARGE:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_XLARGE;
-                    break;
-            }
-        }
-
-        Density density = hardwareConfig.getDensity();
-        if (density == null) {
-            density = Density.MEDIUM;
-        }
-
-        config.screenWidthDp = hardwareConfig.getScreenWidth() / density.getDpiValue();
-        config.screenHeightDp = hardwareConfig.getScreenHeight() / density.getDpiValue();
-        if (config.screenHeightDp < config.screenWidthDp) {
-            //noinspection SuspiciousNameCombination
-            config.smallestScreenWidthDp = config.screenHeightDp;
-        } else {
-            config.smallestScreenWidthDp = config.screenWidthDp;
-        }
-        config.densityDpi = density.getDpiValue();
-
-        // never run in compat mode:
-        config.compatScreenWidthDp = config.screenWidthDp;
-        config.compatScreenHeightDp = config.screenHeightDp;
-
-        ScreenOrientation orientation = hardwareConfig.getOrientation();
-        if (orientation != null) {
-            switch (orientation) {
-            case PORTRAIT:
-                config.orientation = Configuration.ORIENTATION_PORTRAIT;
-                break;
-            case LANDSCAPE:
-                config.orientation = Configuration.ORIENTATION_LANDSCAPE;
-                break;
-            case SQUARE:
-                //noinspection deprecation
-                config.orientation = Configuration.ORIENTATION_SQUARE;
-                break;
-            }
-        } else {
-            config.orientation = Configuration.ORIENTATION_UNDEFINED;
-        }
-
-        ScreenRound roundness = hardwareConfig.getScreenRoundness();
-        if (roundness != null) {
-            switch (roundness) {
-                case ROUND:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_ROUND_YES;
-                    break;
-                case NOTROUND:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_ROUND_NO;
-            }
-        } else {
-            config.screenLayout |= Configuration.SCREENLAYOUT_ROUND_UNDEFINED;
-        }
-        String locale = params.getLocale();
-        if (locale != null && !locale.isEmpty()) config.locale = new Locale(locale);
-
-        // TODO: fill in more config info.
-
-        return config;
-    }
-
-
-    // --- FrameworkResourceIdProvider methods
-
-    @Override
-    public Integer getId(ResourceType resType, String resName) {
-        return Bridge.getResourceId(resType, resName);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
deleted file mode 100644
index d797eeca..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
+++ /dev/null
@@ -1,179 +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.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.DrawableParams;
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.resources.ResourceType;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.StateListDrawable;
-import android.view.AttachInfo_Accessor;
-import android.view.View.MeasureSpec;
-import android.widget.FrameLayout;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Action to render a given Drawable provided through {@link DrawableParams#getDrawable()}.
- *
- * The class only provides a simple {@link #render()} method, but the full life-cycle of the
- * action must be respected.
- *
- * @see RenderAction
- *
- */
-public class RenderDrawable extends RenderAction<DrawableParams> {
-
-    public RenderDrawable(DrawableParams params) {
-        super(new DrawableParams(params));
-    }
-
-    public Result render() {
-        checkLock();
-        // get the drawable resource value
-        DrawableParams params = getParams();
-        HardwareConfig hardwareConfig = params.getHardwareConfig();
-        ResourceValue drawableResource = params.getDrawable();
-
-        // resolve it
-        BridgeContext context = getContext();
-        drawableResource = context.getRenderResources().resolveResValue(drawableResource);
-
-        if (drawableResource == null) {
-            return Status.ERROR_NOT_A_DRAWABLE.createResult();
-        }
-
-        ResourceType resourceType = drawableResource.getResourceType();
-        if (resourceType != ResourceType.DRAWABLE && resourceType != ResourceType.MIPMAP) {
-            return Status.ERROR_NOT_A_DRAWABLE.createResult();
-        }
-
-        Drawable d = ResourceHelper.getDrawable(drawableResource, context);
-
-        final Boolean allStates =
-                params.getFlag(RenderParamsFlags.FLAG_KEY_RENDER_ALL_DRAWABLE_STATES);
-        if (allStates == Boolean.TRUE) {
-            final List<BufferedImage> result;
-
-            if (d instanceof StateListDrawable) {
-                result = new ArrayList<BufferedImage>();
-                final StateListDrawable stateList = (StateListDrawable) d;
-                for (int i = 0; i < stateList.getStateCount(); i++) {
-                    final Drawable stateDrawable = stateList.getStateDrawable(i);
-                    result.add(renderImage(hardwareConfig, stateDrawable, context));
-                }
-            } else {
-                result = Collections.singletonList(renderImage(hardwareConfig, d, context));
-            }
-
-            return Status.SUCCESS.createResult(result);
-        } else {
-            BufferedImage image = renderImage(hardwareConfig, d, context);
-            return Status.SUCCESS.createResult(image);
-        }
-    }
-
-    private BufferedImage renderImage(HardwareConfig hardwareConfig, Drawable d,
-            BridgeContext context) {
-        // create a simple FrameLayout
-        FrameLayout content = new FrameLayout(context);
-
-        // get the actual Drawable object to draw
-        content.setBackground(d);
-
-        // set the AttachInfo on the root view.
-        AttachInfo_Accessor.setAttachInfo(content);
-
-
-        // measure
-        int w = d.getIntrinsicWidth();
-        int h = d.getIntrinsicHeight();
-
-        final int screenWidth = hardwareConfig.getScreenWidth();
-        final int screenHeight = hardwareConfig.getScreenHeight();
-
-        if (w == -1 || h == -1) {
-            // Use screen size when either intrinsic width or height isn't available
-            w = screenWidth;
-            h = screenHeight;
-        } else if (w > screenWidth || h > screenHeight) {
-            // If image wouldn't fit to the screen, resize it to avoid cropping.
-
-            // We need to find scale such that scale * w <= screenWidth, scale * h <= screenHeight
-            double scale = Math.min((double) screenWidth / w, (double) screenHeight / h);
-
-            // scale * w / scale * h = w / h, so, proportions are preserved.
-            w = (int) Math.floor(scale * w);
-            h = (int) Math.floor(scale * h);
-        }
-
-        int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
-        int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
-        content.measure(w_spec, h_spec);
-
-        // now do the layout.
-        content.layout(0, 0, w, h);
-
-        // preDraw setup
-        AttachInfo_Accessor.dispatchOnPreDraw(content);
-
-        // draw into a new image
-        BufferedImage image = getImage(w, h);
-
-        // create an Android bitmap around the BufferedImage
-        Bitmap bitmap = Bitmap_Delegate.createBitmap(image,
-                true /*isMutable*/, hardwareConfig.getDensity());
-
-        // create a Canvas around the Android bitmap
-        Canvas canvas = new Canvas(bitmap);
-        canvas.setDensity(hardwareConfig.getDensity().getDpiValue());
-
-        // and draw
-        content.draw(canvas);
-        return image;
-    }
-
-    protected BufferedImage getImage(int w, int h) {
-        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
-        Graphics2D gc = image.createGraphics();
-        gc.setComposite(AlphaComposite.Src);
-
-        gc.setColor(new Color(0x00000000, true));
-        gc.fillRect(0, 0, w, h);
-
-        // done
-        gc.dispose();
-
-        return image;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
deleted file mode 100644
index d21955e..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ /dev/null
@@ -1,1557 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.ide.common.rendering.api.ViewType;
-import com.android.internal.view.menu.ActionMenuItemView;
-import com.android.internal.view.menu.BridgeMenuItemImpl;
-import com.android.internal.view.menu.IconMenuItemView;
-import com.android.internal.view.menu.ListMenuItemView;
-import com.android.internal.view.menu.MenuItemImpl;
-import com.android.internal.view.menu.MenuView;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.android.graphics.NopCanvas;
-import com.android.layoutlib.bridge.android.support.DesignLibUtil;
-import com.android.layoutlib.bridge.android.support.SupportPreferencesUtil;
-import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
-import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.java.System_Delegate;
-import com.android.util.Pair;
-import com.android.util.PropertiesMap;
-
-import android.animation.AnimationThread;
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.LayoutTransition;
-import android.animation.LayoutTransition.TransitionListener;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Fragment_Delegate;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.os.Looper;
-import android.preference.Preference_Delegate;
-import android.view.AttachInfo_Accessor;
-import android.view.BridgeInflater;
-import android.view.Choreographer_Delegate;
-import android.view.IWindowManager;
-import android.view.IWindowManagerImpl;
-import android.view.Surface;
-import android.view.View;
-import android.view.View.MeasureSpec;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.view.ViewGroup.MarginLayoutParams;
-import android.view.ViewParent;
-import android.view.WindowManagerGlobal_Delegate;
-import android.widget.AbsListView;
-import android.widget.AbsSpinner;
-import android.widget.ActionMenuView;
-import android.widget.AdapterView;
-import android.widget.ExpandableListView;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.QuickContactBadge;
-import android.widget.TabHost;
-import android.widget.TabHost.TabSpec;
-import android.widget.TabWidget;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.isInstanceOf;
-
-/**
- * Class implementing the render session.
- * <p/>
- * A session is a stateful representation of a layout file. It is initialized with data coming
- * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then
- * be done on the layout.
- */
-public class RenderSessionImpl extends RenderAction<SessionParams> {
-
-    private static final Canvas NOP_CANVAS = new NopCanvas();
-
-    // scene state
-    private RenderSession mScene;
-    private BridgeXmlBlockParser mBlockParser;
-    private BridgeInflater mInflater;
-    private ViewGroup mViewRoot;
-    private FrameLayout mContentRoot;
-    private Canvas mCanvas;
-    private int mMeasuredScreenWidth = -1;
-    private int mMeasuredScreenHeight = -1;
-    private boolean mIsAlphaChannelImage;
-    /** If >= 0, a frame will be executed */
-    private long mElapsedFrameTimeNanos = -1;
-    /** True if one frame has been already executed to start the animations */
-    private boolean mFirstFrameExecuted = false;
-
-    // information being returned through the API
-    private BufferedImage mImage;
-    private List<ViewInfo> mViewInfoList;
-    private List<ViewInfo> mSystemViewInfoList;
-    private Layout.Builder mLayoutBuilder;
-    private boolean mNewRenderSize;
-
-    private static final class PostInflateException extends Exception {
-        private static final long serialVersionUID = 1L;
-
-        private PostInflateException(String message) {
-            super(message);
-        }
-    }
-
-    /**
-     * Creates a layout scene with all the information coming from the layout bridge API.
-     * <p>
-     * This <b>must</b> be followed by a call to {@link RenderSessionImpl#init(long)},
-     * which act as a
-     * call to {@link RenderSessionImpl#acquire(long)}
-     *
-     * @see Bridge#createSession(SessionParams)
-     */
-    public RenderSessionImpl(SessionParams params) {
-        super(new SessionParams(params));
-    }
-
-    /**
-     * Initializes and acquires the scene, creating various Android objects such as context,
-     * inflater, and parser.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     *
-     * @return whether the scene was prepared
-     *
-     * @see #acquire(long)
-     * @see #release()
-     */
-    @Override
-    public Result init(long timeout) {
-        Result result = super.init(timeout);
-        if (!result.isSuccess()) {
-            return result;
-        }
-
-        SessionParams params = getParams();
-        BridgeContext context = getContext();
-
-        // use default of true in case it's not found to use alpha by default
-        mIsAlphaChannelImage = ResourceHelper.getBooleanThemeValue(params.getResources(),
-                "windowIsFloating", true, true);
-
-        mLayoutBuilder = new Layout.Builder(params, context);
-
-        // FIXME: find those out, and possibly add them to the render params
-        boolean hasNavigationBar = true;
-        //noinspection ConstantConditions
-        IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(),
-                context.getMetrics(), Surface.ROTATION_0, hasNavigationBar);
-        WindowManagerGlobal_Delegate.setWindowManagerService(iwm);
-
-        // build the inflater and parser.
-        mInflater = new BridgeInflater(context, params.getLayoutlibCallback());
-        context.setBridgeInflater(mInflater);
-
-        mBlockParser = new BridgeXmlBlockParser(params.getLayoutDescription(), context, false);
-
-        return SUCCESS.createResult();
-    }
-
-    /**
-     * Measures the the current layout if needed (see {@link #invalidateRenderingSize}).
-     */
-    private void measureLayout(@NonNull SessionParams params) {
-        // only do the screen measure when needed.
-        if (mMeasuredScreenWidth != -1) {
-            return;
-        }
-
-        RenderingMode renderingMode = params.getRenderingMode();
-        HardwareConfig hardwareConfig = params.getHardwareConfig();
-
-        mNewRenderSize = true;
-        mMeasuredScreenWidth = hardwareConfig.getScreenWidth();
-        mMeasuredScreenHeight = hardwareConfig.getScreenHeight();
-
-        if (renderingMode != RenderingMode.NORMAL) {
-            int widthMeasureSpecMode = renderingMode.isHorizExpand() ?
-                    MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
-                    : MeasureSpec.EXACTLY;
-            int heightMeasureSpecMode = renderingMode.isVertExpand() ?
-                    MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
-                    : MeasureSpec.EXACTLY;
-
-            // We used to compare the measured size of the content to the screen size but
-            // this does not work anymore due to the 2 following issues:
-            // - If the content is in a decor (system bar, title/action bar), the root view
-            //   will not resize even with the UNSPECIFIED because of the embedded layout.
-            // - If there is no decor, but a dialog frame, then the dialog padding prevents
-            //   comparing the size of the content to the screen frame (as it would not
-            //   take into account the dialog padding).
-
-            // The solution is to first get the content size in a normal rendering, inside
-            // the decor or the dialog padding.
-            // Then measure only the content with UNSPECIFIED to see the size difference
-            // and apply this to the screen size.
-
-            View measuredView = mContentRoot.getChildAt(0);
-
-            // first measure the full layout, with EXACTLY to get the size of the
-            // content as it is inside the decor/dialog
-            @SuppressWarnings("deprecation")
-            Pair<Integer, Integer> exactMeasure = measureView(
-                    mViewRoot, measuredView,
-                    mMeasuredScreenWidth, MeasureSpec.EXACTLY,
-                    mMeasuredScreenHeight, MeasureSpec.EXACTLY);
-
-            // now measure the content only using UNSPECIFIED (where applicable, based on
-            // the rendering mode). This will give us the size the content needs.
-            @SuppressWarnings("deprecation")
-            Pair<Integer, Integer> result = measureView(
-                    mContentRoot, mContentRoot.getChildAt(0),
-                    mMeasuredScreenWidth, widthMeasureSpecMode,
-                    mMeasuredScreenHeight, heightMeasureSpecMode);
-
-            // If measuredView is not null, exactMeasure nor result will be null.
-            assert exactMeasure != null;
-            assert result != null;
-
-            // now look at the difference and add what is needed.
-            if (renderingMode.isHorizExpand()) {
-                int measuredWidth = exactMeasure.getFirst();
-                int neededWidth = result.getFirst();
-                if (neededWidth > measuredWidth) {
-                    mMeasuredScreenWidth += neededWidth - measuredWidth;
-                }
-                if (mMeasuredScreenWidth < measuredWidth) {
-                    // If the screen width is less than the exact measured width,
-                    // expand to match.
-                    mMeasuredScreenWidth = measuredWidth;
-                }
-            }
-
-            if (renderingMode.isVertExpand()) {
-                int measuredHeight = exactMeasure.getSecond();
-                int neededHeight = result.getSecond();
-                if (neededHeight > measuredHeight) {
-                    mMeasuredScreenHeight += neededHeight - measuredHeight;
-                }
-                if (mMeasuredScreenHeight < measuredHeight) {
-                    // If the screen height is less than the exact measured height,
-                    // expand to match.
-                    mMeasuredScreenHeight = measuredHeight;
-                }
-            }
-        }
-    }
-
-    /**
-     * Inflates the layout.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #init(long)} was not called.
-     */
-    public Result inflate() {
-        checkLock();
-
-        try {
-            mViewRoot = new Layout(mLayoutBuilder);
-            mLayoutBuilder = null;  // Done with the builder.
-            mContentRoot = ((Layout) mViewRoot).getContentRoot();
-            SessionParams params = getParams();
-            BridgeContext context = getContext();
-
-            if (Bridge.isLocaleRtl(params.getLocale())) {
-                if (!params.isRtlSupported()) {
-                    Bridge.getLog().warning(LayoutLog.TAG_RTL_NOT_ENABLED,
-                            "You are using a right-to-left " +
-                                    "(RTL) locale but RTL is not enabled", null);
-                } else if (params.getSimulatedPlatformVersion() < 17) {
-                    // This will render ok because we are using the latest layoutlib but at least
-                    // warn the user that this might fail in a real device.
-                    Bridge.getLog().warning(LayoutLog.TAG_RTL_NOT_SUPPORTED, "You are using a " +
-                            "right-to-left " +
-                            "(RTL) locale but RTL is not supported for API level < 17", null);
-                }
-            }
-
-            // Sets the project callback (custom view loader) to the fragment delegate so that
-            // it can instantiate the custom Fragment.
-            Fragment_Delegate.setLayoutlibCallback(params.getLayoutlibCallback());
-
-            String rootTag = params.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG);
-            boolean isPreference = "PreferenceScreen".equals(rootTag);
-            View view;
-            if (isPreference) {
-                // First try to use the support library inflater. If something fails, fallback
-                // to the system preference inflater.
-                view = SupportPreferencesUtil.inflatePreference(getContext(), mBlockParser,
-                        mContentRoot);
-                if (view == null) {
-                    view = Preference_Delegate.inflatePreference(getContext(), mBlockParser,
-                            mContentRoot);
-                }
-            } else {
-                view = mInflater.inflate(mBlockParser, mContentRoot);
-            }
-
-            // done with the parser, pop it.
-            context.popParser();
-
-            Fragment_Delegate.setLayoutlibCallback(null);
-
-            // set the AttachInfo on the root view.
-            AttachInfo_Accessor.setAttachInfo(mViewRoot);
-
-            // post-inflate process. For now this supports TabHost/TabWidget
-            postInflateProcess(view, params.getLayoutlibCallback(), isPreference ? view : null);
-            mInflater.onDoneInflation();
-
-            setActiveToolbar(view, context, params);
-
-            measureLayout(params);
-            measureView(mViewRoot, null /*measuredView*/,
-                    mMeasuredScreenWidth, MeasureSpec.EXACTLY,
-                    mMeasuredScreenHeight, MeasureSpec.EXACTLY);
-            mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
-            mSystemViewInfoList =
-                    visitAllChildren(mViewRoot, 0, 0, params.getExtendedViewInfoMode(),
-                    false);
-
-            return SUCCESS.createResult();
-        } catch (PostInflateException e) {
-            return ERROR_INFLATION.createResult(e.getMessage(), e);
-        } catch (Throwable e) {
-            // get the real cause of the exception.
-            Throwable t = e;
-            while (t.getCause() != null) {
-                t = t.getCause();
-            }
-
-            return ERROR_INFLATION.createResult(t.getMessage(), t);
-        }
-    }
-
-    /**
-     * Sets the time for which the next frame will be selected. The time is the elapsed time from
-     * the current system nanos time. You
-     */
-    public void setElapsedFrameTimeNanos(long nanos) {
-        mElapsedFrameTimeNanos = nanos;
-    }
-
-    /**
-     * Runs a layout pass for the given view root
-     */
-    private static void doLayout(@NonNull BridgeContext context, @NonNull ViewGroup viewRoot,
-            int width, int height) {
-        // measure again with the size we need
-        // This must always be done before the call to layout
-        measureView(viewRoot, null /*measuredView*/,
-                width, MeasureSpec.EXACTLY,
-                height, MeasureSpec.EXACTLY);
-
-        // now do the layout.
-        viewRoot.layout(0, 0, width, height);
-        handleScrolling(context, viewRoot);
-    }
-
-    /**
-     * Renders the given view hierarchy to the passed canvas and returns the result of the render
-     * operation.
-     * @param canvas an optional canvas to render the views to. If null, only the measure and
-     * layout steps will be executed.
-     */
-    private static Result renderAndBuildResult(@NonNull ViewGroup viewRoot, @Nullable Canvas canvas) {
-        if (canvas == null) {
-            return SUCCESS.createResult();
-        }
-
-        AttachInfo_Accessor.dispatchOnPreDraw(viewRoot);
-        viewRoot.draw(canvas);
-
-        return SUCCESS.createResult();
-    }
-
-    /**
-     * Renders the scene.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @param freshRender whether the render is a new one and should erase the existing bitmap (in
-     *      the case where bitmaps are reused). This is typically needed when not playing
-     *      animations.)
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see SessionParams#getRenderingMode()
-     * @see RenderSession#render(long)
-     */
-    public Result render(boolean freshRender) {
-        return renderAndBuildResult(freshRender, false);
-    }
-
-    /**
-     * Measures the layout
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see SessionParams#getRenderingMode()
-     * @see RenderSession#render(long)
-     */
-    public Result measure() {
-        return renderAndBuildResult(false, true);
-    }
-
-    /**
-     * Renders the scene.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @param freshRender whether the render is a new one and should erase the existing bitmap (in
-     *      the case where bitmaps are reused). This is typically needed when not playing
-     *      animations.)
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see SessionParams#getRenderingMode()
-     * @see RenderSession#render(long)
-     */
-    private Result renderAndBuildResult(boolean freshRender, boolean onlyMeasure) {
-        checkLock();
-
-        SessionParams params = getParams();
-
-        try {
-            if (mViewRoot == null) {
-                return ERROR_NOT_INFLATED.createResult();
-            }
-
-            measureLayout(params);
-
-            HardwareConfig hardwareConfig = params.getHardwareConfig();
-            Result renderResult = SUCCESS.createResult();
-            if (onlyMeasure) {
-                // delete the canvas and image to reset them on the next full rendering
-                mImage = null;
-                mCanvas = null;
-                doLayout(getContext(), mViewRoot, mMeasuredScreenWidth, mMeasuredScreenHeight);
-            } else {
-                // draw the views
-                // create the BufferedImage into which the layout will be rendered.
-                boolean newImage = false;
-
-                // When disableBitmapCaching is true, we do not reuse mImage and
-                // we create a new one in every render.
-                // This is useful when mImage is just a wrapper of Graphics2D so
-                // it doesn't get cached.
-                boolean disableBitmapCaching = Boolean.TRUE.equals(params.getFlag(
-                    RenderParamsFlags.FLAG_KEY_DISABLE_BITMAP_CACHING));
-                if (mNewRenderSize || mCanvas == null || disableBitmapCaching) {
-                    mNewRenderSize = false;
-                    if (params.getImageFactory() != null) {
-                        mImage = params.getImageFactory().getImage(
-                                mMeasuredScreenWidth,
-                                mMeasuredScreenHeight);
-                    } else {
-                        mImage = new BufferedImage(
-                                mMeasuredScreenWidth,
-                                mMeasuredScreenHeight,
-                                BufferedImage.TYPE_INT_ARGB);
-                        newImage = true;
-                    }
-
-                    if (params.isBgColorOverridden()) {
-                        // since we override the content, it's the same as if it was a new image.
-                        newImage = true;
-                        Graphics2D gc = mImage.createGraphics();
-                        gc.setColor(new Color(params.getOverrideBgColor(), true));
-                        gc.setComposite(AlphaComposite.Src);
-                        gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
-                        gc.dispose();
-                    }
-
-                    // create an Android bitmap around the BufferedImage
-                    Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
-                            true /*isMutable*/, hardwareConfig.getDensity());
-
-                    if (mCanvas == null) {
-                        // create a Canvas around the Android bitmap
-                        mCanvas = new Canvas(bitmap);
-                    } else {
-                        mCanvas.setBitmap(bitmap);
-                    }
-                    mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue());
-                }
-
-                if (freshRender && !newImage) {
-                    Graphics2D gc = mImage.createGraphics();
-                    gc.setComposite(AlphaComposite.Src);
-
-                    gc.setColor(new Color(0x00000000, true));
-                    gc.fillRect(0, 0,
-                            mMeasuredScreenWidth, mMeasuredScreenHeight);
-
-                    // done
-                    gc.dispose();
-                }
-
-                doLayout(getContext(), mViewRoot, mMeasuredScreenWidth, mMeasuredScreenHeight);
-                if (mElapsedFrameTimeNanos >= 0) {
-                    long initialTime = System_Delegate.nanoTime();
-                    if (!mFirstFrameExecuted) {
-                        // We need to run an initial draw call to initialize the animations
-                        renderAndBuildResult(mViewRoot, NOP_CANVAS);
-
-                        // The first frame will initialize the animations
-                        Choreographer_Delegate.doFrame(initialTime);
-                        mFirstFrameExecuted = true;
-                    }
-                    // Second frame will move the animations
-                    Choreographer_Delegate.doFrame(initialTime + mElapsedFrameTimeNanos);
-                }
-                renderResult = renderAndBuildResult(mViewRoot, mCanvas);
-            }
-
-            mSystemViewInfoList =
-                    visitAllChildren(mViewRoot, 0, 0, params.getExtendedViewInfoMode(),
-                    false);
-
-            // success!
-            return renderResult;
-        } catch (Throwable e) {
-            // get the real cause of the exception.
-            Throwable t = e;
-            while (t.getCause() != null) {
-                t = t.getCause();
-            }
-
-            return ERROR_UNKNOWN.createResult(t.getMessage(), t);
-        }
-    }
-
-    /**
-     * Executes {@link View#measure(int, int)} on a given view with the given parameters (used
-     * to create measure specs with {@link MeasureSpec#makeMeasureSpec(int, int)}.
-     *
-     * if <var>measuredView</var> is non null, the method returns a {@link Pair} of (width, height)
-     * for the view (using {@link View#getMeasuredWidth()} and {@link View#getMeasuredHeight()}).
-     *
-     * @param viewToMeasure the view on which to execute measure().
-     * @param measuredView if non null, the view to query for its measured width/height.
-     * @param width the width to use in the MeasureSpec.
-     * @param widthMode the MeasureSpec mode to use for the width.
-     * @param height the height to use in the MeasureSpec.
-     * @param heightMode the MeasureSpec mode to use for the height.
-     * @return the measured width/height if measuredView is non-null, null otherwise.
-     */
-    @SuppressWarnings("deprecation")  // For the use of Pair
-    private static Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView,
-            int width, int widthMode, int height, int heightMode) {
-        int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode);
-        int h_spec = MeasureSpec.makeMeasureSpec(height, heightMode);
-        viewToMeasure.measure(w_spec, h_spec);
-
-        if (measuredView != null) {
-            return Pair.of(measuredView.getMeasuredWidth(), measuredView.getMeasuredHeight());
-        }
-
-        return null;
-    }
-
-    /**
-     * Animate an object
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#animate(Object, String, boolean, IAnimationListener)
-     */
-    public Result animate(Object targetObject, String animationName,
-            boolean isFrameworkAnimation, IAnimationListener listener) {
-        checkLock();
-
-        BridgeContext context = getContext();
-
-        // find the animation file.
-        ResourceValue animationResource;
-        int animationId = 0;
-        if (isFrameworkAnimation) {
-            animationResource = context.getRenderResources().getFrameworkResource(
-                    ResourceType.ANIMATOR, animationName);
-            if (animationResource != null) {
-                animationId = Bridge.getResourceId(ResourceType.ANIMATOR, animationName);
-            }
-        } else {
-            animationResource = context.getRenderResources().getProjectResource(
-                    ResourceType.ANIMATOR, animationName);
-            if (animationResource != null) {
-                animationId = context.getLayoutlibCallback().getResourceId(
-                        ResourceType.ANIMATOR, animationName);
-            }
-        }
-
-        if (animationResource != null) {
-            try {
-                Animator anim = AnimatorInflater.loadAnimator(context, animationId);
-                if (anim != null) {
-                    anim.setTarget(targetObject);
-
-                    new PlayAnimationThread(anim, this, animationName, listener).start();
-
-                    return SUCCESS.createResult();
-                }
-            } catch (Exception e) {
-                // get the real cause of the exception.
-                Throwable t = e;
-                while (t.getCause() != null) {
-                    t = t.getCause();
-                }
-
-                return ERROR_UNKNOWN.createResult(t.getMessage(), t);
-            }
-        }
-
-        return ERROR_ANIM_NOT_FOUND.createResult();
-    }
-
-    /**
-     * Insert a new child into an existing parent.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#insertChild(Object, ILayoutPullParser, int, IAnimationListener)
-     */
-    public Result insertChild(final ViewGroup parentView, ILayoutPullParser childXml,
-            final int index, IAnimationListener listener) {
-        checkLock();
-
-        BridgeContext context = getContext();
-
-        // create a block parser for the XML
-        BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
-                childXml, context, false /* platformResourceFlag */);
-
-        // inflate the child without adding it to the root since we want to control where it'll
-        // get added. We do pass the parentView however to ensure that the layoutParams will
-        // be created correctly.
-        final View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/);
-        blockParser.ensurePopped();
-
-        invalidateRenderingSize();
-
-        if (listener != null) {
-            new AnimationThread(this, "insertChild", listener) {
-
-                @Override
-                public Result preAnimation() {
-                    parentView.setLayoutTransition(new LayoutTransition());
-                    return addView(parentView, child, index);
-                }
-
-                @Override
-                public void postAnimation() {
-                    parentView.setLayoutTransition(null);
-                }
-            }.start();
-
-            // always return success since the real status will come through the listener.
-            return SUCCESS.createResult(child);
-        }
-
-        // add it to the parentView in the correct location
-        Result result = addView(parentView, child, index);
-        if (!result.isSuccess()) {
-            return result;
-        }
-
-        result = render(false /*freshRender*/);
-        if (result.isSuccess()) {
-            result = result.getCopyWithData(child);
-        }
-
-        return result;
-    }
-
-    /**
-     * Adds a given view to a given parent at a given index.
-     *
-     * @param parent the parent to receive the view
-     * @param view the view to add to the parent
-     * @param index the index where to do the add.
-     *
-     * @return a Result with {@link Status#SUCCESS} or
-     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
-     *     adding views.
-     */
-    private Result addView(ViewGroup parent, View view, int index) {
-        try {
-            parent.addView(view, index);
-            return SUCCESS.createResult();
-        } catch (UnsupportedOperationException e) {
-            // looks like this is a view class that doesn't support children manipulation!
-            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
-        }
-    }
-
-    /**
-     * Moves a view to a new parent at a given location
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#moveChild(Object, Object, int, Map, IAnimationListener)
-     */
-    public Result moveChild(final ViewGroup newParentView, final View childView, final int index,
-            Map<String, String> layoutParamsMap, final IAnimationListener listener) {
-        checkLock();
-
-        invalidateRenderingSize();
-
-        LayoutParams layoutParams = null;
-        if (layoutParamsMap != null) {
-            // need to create a new LayoutParams object for the new parent.
-            layoutParams = newParentView.generateLayoutParams(
-                    new BridgeLayoutParamsMapAttributes(layoutParamsMap));
-        }
-
-        // get the current parent of the view that needs to be moved.
-        final ViewGroup previousParent = (ViewGroup) childView.getParent();
-
-        if (listener != null) {
-            final LayoutParams params = layoutParams;
-
-            // there is no support for animating views across layouts, so in case the new and old
-            // parent views are different we fake the animation through a no animation thread.
-            if (previousParent != newParentView) {
-                new Thread("not animated moveChild") {
-                    @Override
-                    public void run() {
-                        Result result = moveView(previousParent, newParentView, childView, index,
-                                params);
-                        if (!result.isSuccess()) {
-                            listener.done(result);
-                        }
-
-                        // ready to do the work, acquire the scene.
-                        result = acquire(250);
-                        if (!result.isSuccess()) {
-                            listener.done(result);
-                            return;
-                        }
-
-                        try {
-                            result = render(false /*freshRender*/);
-                            if (result.isSuccess()) {
-                                listener.onNewFrame(RenderSessionImpl.this.getSession());
-                            }
-                        } finally {
-                            release();
-                        }
-
-                        listener.done(result);
-                    }
-                }.start();
-            } else {
-                new AnimationThread(this, "moveChild", listener) {
-
-                    @Override
-                    public Result preAnimation() {
-                        // set up the transition for the parent.
-                        LayoutTransition transition = new LayoutTransition();
-                        previousParent.setLayoutTransition(transition);
-
-                        // tweak the animation durations and start delays (to match the duration of
-                        // animation playing just before).
-                        // Note: Cannot user Animation.setDuration() directly. Have to set it
-                        // on the LayoutTransition.
-                        transition.setDuration(LayoutTransition.DISAPPEARING, 100);
-                        // CHANGE_DISAPPEARING plays after DISAPPEARING
-                        transition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 100);
-
-                        transition.setDuration(LayoutTransition.CHANGE_DISAPPEARING, 100);
-
-                        transition.setDuration(LayoutTransition.CHANGE_APPEARING, 100);
-                        // CHANGE_APPEARING plays after CHANGE_APPEARING
-                        transition.setStartDelay(LayoutTransition.APPEARING, 100);
-
-                        transition.setDuration(LayoutTransition.APPEARING, 100);
-
-                        return moveView(previousParent, newParentView, childView, index, params);
-                    }
-
-                    @Override
-                    public void postAnimation() {
-                        previousParent.setLayoutTransition(null);
-                        newParentView.setLayoutTransition(null);
-                    }
-                }.start();
-            }
-
-            // always return success since the real status will come through the listener.
-            return SUCCESS.createResult(layoutParams);
-        }
-
-        Result result = moveView(previousParent, newParentView, childView, index, layoutParams);
-        if (!result.isSuccess()) {
-            return result;
-        }
-
-        result = render(false /*freshRender*/);
-        if (layoutParams != null && result.isSuccess()) {
-            result = result.getCopyWithData(layoutParams);
-        }
-
-        return result;
-    }
-
-    /**
-     * Moves a View from its current parent to a new given parent at a new given location, with
-     * an optional new {@link LayoutParams} instance
-     *
-     * @param previousParent the previous parent, still owning the child at the time of the call.
-     * @param newParent the new parent
-     * @param movedView the view to move
-     * @param index the new location in the new parent
-     * @param params an option (can be null) {@link LayoutParams} instance.
-     *
-     * @return a Result with {@link Status#SUCCESS} or
-     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
-     *     adding views.
-     */
-    private Result moveView(ViewGroup previousParent, final ViewGroup newParent,
-            final View movedView, final int index, final LayoutParams params) {
-        try {
-            // check if there is a transition on the previousParent.
-            LayoutTransition previousTransition = previousParent.getLayoutTransition();
-            if (previousTransition != null) {
-                // in this case there is an animation. This means we have to wait for the child's
-                // parent reference to be null'ed out so that we can add it to the new parent.
-                // It is technically removed right before the DISAPPEARING animation is done (if
-                // the animation of this type is not null, otherwise it's after which is impossible
-                // to handle).
-                // Because there is no move animation, if the new parent is the same as the old
-                // parent, we need to wait until the CHANGE_DISAPPEARING animation is done before
-                // adding the child or the child will appear in its new location before the
-                // other children have made room for it.
-
-                // add a listener to the transition to be notified of the actual removal.
-                previousTransition.addTransitionListener(new TransitionListener() {
-                    private int mChangeDisappearingCount = 0;
-
-                    @Override
-                    public void startTransition(LayoutTransition transition, ViewGroup container,
-                            View view, int transitionType) {
-                        if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) {
-                            mChangeDisappearingCount++;
-                        }
-                    }
-
-                    @Override
-                    public void endTransition(LayoutTransition transition, ViewGroup container,
-                            View view, int transitionType) {
-                        if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) {
-                            mChangeDisappearingCount--;
-                        }
-
-                        if (transitionType == LayoutTransition.CHANGE_DISAPPEARING &&
-                                mChangeDisappearingCount == 0) {
-                            // add it to the parentView in the correct location
-                            if (params != null) {
-                                newParent.addView(movedView, index, params);
-                            } else {
-                                newParent.addView(movedView, index);
-                            }
-                        }
-                    }
-                });
-
-                // remove the view from the current parent.
-                previousParent.removeView(movedView);
-
-                // and return since adding the view to the new parent is done in the listener.
-                return SUCCESS.createResult();
-            } else {
-                // standard code with no animation. pretty simple.
-                previousParent.removeView(movedView);
-
-                // add it to the parentView in the correct location
-                if (params != null) {
-                    newParent.addView(movedView, index, params);
-                } else {
-                    newParent.addView(movedView, index);
-                }
-
-                return SUCCESS.createResult();
-            }
-        } catch (UnsupportedOperationException e) {
-            // looks like this is a view class that doesn't support children manipulation!
-            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
-        }
-    }
-
-    /**
-     * Removes a child from its current parent.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#removeChild(Object, IAnimationListener)
-     */
-    public Result removeChild(final View childView, IAnimationListener listener) {
-        checkLock();
-
-        invalidateRenderingSize();
-
-        final ViewGroup parent = (ViewGroup) childView.getParent();
-
-        if (listener != null) {
-            new AnimationThread(this, "moveChild", listener) {
-
-                @Override
-                public Result preAnimation() {
-                    parent.setLayoutTransition(new LayoutTransition());
-                    return removeView(parent, childView);
-                }
-
-                @Override
-                public void postAnimation() {
-                    parent.setLayoutTransition(null);
-                }
-            }.start();
-
-            // always return success since the real status will come through the listener.
-            return SUCCESS.createResult();
-        }
-
-        Result result = removeView(parent, childView);
-        if (!result.isSuccess()) {
-            return result;
-        }
-
-        return render(false /*freshRender*/);
-    }
-
-    /**
-     * Removes a given view from its current parent.
-     *
-     * @param view the view to remove from its parent
-     *
-     * @return a Result with {@link Status#SUCCESS} or
-     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
-     *     adding views.
-     */
-    private Result removeView(ViewGroup parent, View view) {
-        try {
-            parent.removeView(view);
-            return SUCCESS.createResult();
-        } catch (UnsupportedOperationException e) {
-            // looks like this is a view class that doesn't support children manipulation!
-            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
-        }
-    }
-
-    /**
-     * Post process on a view hierarchy that was just inflated.
-     * <p/>
-     * At the moment this only supports TabHost: If {@link TabHost} is detected, look for the
-     * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
-     * based on the content of the {@link FrameLayout}.
-     * @param view the root view to process.
-     * @param layoutlibCallback callback to the project.
-     * @param skip the view and it's children are not processed.
-     */
-    @SuppressWarnings("deprecation")  // For the use of Pair
-    private void postInflateProcess(View view, LayoutlibCallback layoutlibCallback, View skip)
-            throws PostInflateException {
-        if (view == skip) {
-            return;
-        }
-        if (view instanceof TabHost) {
-            setupTabHost((TabHost) view, layoutlibCallback);
-        } else if (view instanceof QuickContactBadge) {
-            QuickContactBadge badge = (QuickContactBadge) view;
-            badge.setImageToDefault();
-        } else if (view instanceof AdapterView<?>) {
-            // get the view ID.
-            int id = view.getId();
-
-            BridgeContext context = getContext();
-
-            // get a ResourceReference from the integer ID.
-            ResourceReference listRef = context.resolveId(id);
-
-            if (listRef != null) {
-                SessionParams params = getParams();
-                AdapterBinding binding = params.getAdapterBindings().get(listRef);
-
-                // if there was no adapter binding, trying to get it from the call back.
-                if (binding == null) {
-                    binding = layoutlibCallback.getAdapterBinding(
-                            listRef, context.getViewKey(view), view);
-                }
-
-                if (binding != null) {
-
-                    if (view instanceof AbsListView) {
-                        if ((binding.getFooterCount() > 0 || binding.getHeaderCount() > 0) &&
-                                view instanceof ListView) {
-                            ListView list = (ListView) view;
-
-                            boolean skipCallbackParser = false;
-
-                            int count = binding.getHeaderCount();
-                            for (int i = 0; i < count; i++) {
-                                Pair<View, Boolean> pair = context.inflateView(
-                                        binding.getHeaderAt(i),
-                                        list, false, skipCallbackParser);
-                                if (pair.getFirst() != null) {
-                                    list.addHeaderView(pair.getFirst());
-                                }
-
-                                skipCallbackParser |= pair.getSecond();
-                            }
-
-                            count = binding.getFooterCount();
-                            for (int i = 0; i < count; i++) {
-                                Pair<View, Boolean> pair = context.inflateView(
-                                        binding.getFooterAt(i),
-                                        list, false, skipCallbackParser);
-                                if (pair.getFirst() != null) {
-                                    list.addFooterView(pair.getFirst());
-                                }
-
-                                skipCallbackParser |= pair.getSecond();
-                            }
-                        }
-
-                        if (view instanceof ExpandableListView) {
-                            ((ExpandableListView) view).setAdapter(
-                                    new FakeExpandableAdapter(listRef, binding, layoutlibCallback));
-                        } else {
-                            ((AbsListView) view).setAdapter(
-                                    new FakeAdapter(listRef, binding, layoutlibCallback));
-                        }
-                    } else if (view instanceof AbsSpinner) {
-                        ((AbsSpinner) view).setAdapter(
-                                new FakeAdapter(listRef, binding, layoutlibCallback));
-                    }
-                }
-            }
-        } else if (view instanceof ViewGroup) {
-            mInflater.postInflateProcess(view);
-            ViewGroup group = (ViewGroup) view;
-            final int count = group.getChildCount();
-            for (int c = 0; c < count; c++) {
-                View child = group.getChildAt(c);
-                postInflateProcess(child, layoutlibCallback, skip);
-            }
-        }
-    }
-
-    /**
-     * If the root layout is a CoordinatorLayout with an AppBar:
-     * Set the title of the AppBar to the title of the activity context.
-     */
-    private void setActiveToolbar(View view, BridgeContext context, SessionParams params) {
-        View coordinatorLayout = findChildView(view, DesignLibUtil.CN_COORDINATOR_LAYOUT);
-        if (coordinatorLayout == null) {
-            return;
-        }
-        View appBar = findChildView(coordinatorLayout, DesignLibUtil.CN_APPBAR_LAYOUT);
-        if (appBar == null) {
-            return;
-        }
-        ViewGroup collapsingToolbar =
-                (ViewGroup) findChildView(appBar, DesignLibUtil.CN_COLLAPSING_TOOLBAR_LAYOUT);
-        if (collapsingToolbar == null) {
-            return;
-        }
-        if (!hasToolbar(collapsingToolbar)) {
-            return;
-        }
-        RenderResources res = context.getRenderResources();
-        String title = params.getAppLabel();
-        ResourceValue titleValue = res.findResValue(title, false);
-        if (titleValue != null && titleValue.getValue() != null) {
-            title = titleValue.getValue();
-        }
-        DesignLibUtil.setTitle(collapsingToolbar, title);
-    }
-
-    private View findChildView(View view, String className) {
-        if (!(view instanceof ViewGroup)) {
-            return null;
-        }
-        ViewGroup group = (ViewGroup) view;
-        for (int i = 0; i < group.getChildCount(); i++) {
-            if (isInstanceOf(group.getChildAt(i), className)) {
-                return group.getChildAt(i);
-            }
-        }
-        return null;
-    }
-
-    private boolean hasToolbar(View collapsingToolbar) {
-        if (!(collapsingToolbar instanceof ViewGroup)) {
-            return false;
-        }
-        ViewGroup group = (ViewGroup) collapsingToolbar;
-        for (int i = 0; i < group.getChildCount(); i++) {
-            if (isInstanceOf(group.getChildAt(i), DesignLibUtil.CN_TOOLBAR)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Set the scroll position on all the components with the "scrollX" and "scrollY" attribute. If
-     * the component supports nested scrolling attempt that first, then use the unconsumed scroll
-     * part to scroll the content in the component.
-     */
-    private static void handleScrolling(BridgeContext context, View view) {
-        int scrollPosX = context.getScrollXPos(view);
-        int scrollPosY = context.getScrollYPos(view);
-        if (scrollPosX != 0 || scrollPosY != 0) {
-            if (view.isNestedScrollingEnabled()) {
-                int[] consumed = new int[2];
-                int axis = scrollPosX != 0 ? View.SCROLL_AXIS_HORIZONTAL : 0;
-                axis |= scrollPosY != 0 ? View.SCROLL_AXIS_VERTICAL : 0;
-                if (view.startNestedScroll(axis)) {
-                    view.dispatchNestedPreScroll(scrollPosX, scrollPosY, consumed, null);
-                    view.dispatchNestedScroll(consumed[0], consumed[1], scrollPosX, scrollPosY,
-                            null);
-                    view.stopNestedScroll();
-                    scrollPosX -= consumed[0];
-                    scrollPosY -= consumed[1];
-                }
-            }
-            if (scrollPosX != 0 || scrollPosY != 0) {
-                view.scrollTo(scrollPosX, scrollPosY);
-            }
-        }
-
-        if (!(view instanceof ViewGroup)) {
-            return;
-        }
-        ViewGroup group = (ViewGroup) view;
-        for (int i = 0; i < group.getChildCount(); i++) {
-            View child = group.getChildAt(i);
-            handleScrolling(context, child);
-        }
-    }
-
-    /**
-     * Sets up a {@link TabHost} object.
-     * @param tabHost the TabHost to setup.
-     * @param layoutlibCallback The project callback object to access the project R class.
-     * @throws PostInflateException if TabHost is missing the required ids for TabHost
-     */
-    private void setupTabHost(TabHost tabHost, LayoutlibCallback layoutlibCallback)
-            throws PostInflateException {
-        // look for the TabWidget, and the FrameLayout. They have their own specific names
-        View v = tabHost.findViewById(android.R.id.tabs);
-
-        if (v == null) {
-            throw new PostInflateException(
-                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n");
-        }
-
-        if (!(v instanceof TabWidget)) {
-            throw new PostInflateException(String.format(
-                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n" +
-                    "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName()));
-        }
-
-        v = tabHost.findViewById(android.R.id.tabcontent);
-
-        if (v == null) {
-            // TODO: see if we can fake tabs even without the FrameLayout (same below when the frameLayout is empty)
-            //noinspection SpellCheckingInspection
-            throw new PostInflateException(
-                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".");
-        }
-
-        if (!(v instanceof FrameLayout)) {
-            //noinspection SpellCheckingInspection
-            throw new PostInflateException(String.format(
-                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" +
-                    "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName()));
-        }
-
-        FrameLayout content = (FrameLayout)v;
-
-        // now process the content of the frameLayout and dynamically create tabs for it.
-        final int count = content.getChildCount();
-
-        // this must be called before addTab() so that the TabHost searches its TabWidget
-        // and FrameLayout.
-        tabHost.setup();
-
-        if (count == 0) {
-            // Create a dummy child to get a single tab
-            TabSpec spec = tabHost.newTabSpec("tag")
-                    .setIndicator("Tab Label", tabHost.getResources()
-                            .getDrawable(android.R.drawable.ic_menu_info_details, null))
-                    .setContent(tag -> new LinearLayout(getContext()));
-            tabHost.addTab(spec);
-        } else {
-            // for each child of the frameLayout, add a new TabSpec
-            for (int i = 0 ; i < count ; i++) {
-                View child = content.getChildAt(i);
-                String tabSpec = String.format("tab_spec%d", i+1);
-                @SuppressWarnings("ConstantConditions")  // child cannot be null.
-                int id = child.getId();
-                @SuppressWarnings("deprecation")
-                Pair<ResourceType, String> resource = layoutlibCallback.resolveResourceId(id);
-                String name;
-                if (resource != null) {
-                    name = resource.getSecond();
-                } else {
-                    name = String.format("Tab %d", i+1); // default name if id is unresolved.
-                }
-                tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id));
-            }
-        }
-    }
-
-    /**
-     * Visits a {@link View} and its children and generate a {@link ViewInfo} containing the
-     * bounds of all the views.
-     *
-     * @param view the root View
-     * @param hOffset horizontal offset for the view bounds.
-     * @param vOffset vertical offset for the view bounds.
-     * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object.
-     * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the
-     *                       content frame.
-     *
-     * @return {@code ViewInfo} containing the bounds of the view and it children otherwise.
-     */
-    private ViewInfo visit(View view, int hOffset, int vOffset, boolean setExtendedInfo,
-            boolean isContentFrame) {
-        ViewInfo result = createViewInfo(view, hOffset, vOffset, setExtendedInfo, isContentFrame);
-
-        if (view instanceof ViewGroup) {
-            ViewGroup group = ((ViewGroup) view);
-            result.setChildren(visitAllChildren(group, isContentFrame ? 0 : hOffset,
-                    isContentFrame ? 0 : vOffset,
-                    setExtendedInfo, isContentFrame));
-        }
-        return result;
-    }
-
-    /**
-     * Visits all the children of a given ViewGroup and generates a list of {@link ViewInfo}
-     * containing the bounds of all the views. It also initializes the {@link #mViewInfoList} with
-     * the children of the {@code mContentRoot}.
-     *
-     * @param viewGroup the root View
-     * @param hOffset horizontal offset from the top for the content view frame.
-     * @param vOffset vertical offset from the top for the content view frame.
-     * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object.
-     * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the
-     *                       content frame. {@code false} if the {@code ViewInfo} to be created is
-     *                       part of the system decor.
-     */
-    private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int hOffset, int vOffset,
-            boolean setExtendedInfo, boolean isContentFrame) {
-        if (viewGroup == null) {
-            return null;
-        }
-
-        if (!isContentFrame) {
-            vOffset += viewGroup.getTop();
-            hOffset += viewGroup.getLeft();
-        }
-
-        int childCount = viewGroup.getChildCount();
-        if (viewGroup == mContentRoot) {
-            List<ViewInfo> childrenWithoutOffset = new ArrayList<>(childCount);
-            List<ViewInfo> childrenWithOffset = new ArrayList<>(childCount);
-            for (int i = 0; i < childCount; i++) {
-                ViewInfo[] childViewInfo =
-                        visitContentRoot(viewGroup.getChildAt(i), hOffset, vOffset,
-                        setExtendedInfo);
-                childrenWithoutOffset.add(childViewInfo[0]);
-                childrenWithOffset.add(childViewInfo[1]);
-            }
-            mViewInfoList = childrenWithOffset;
-            return childrenWithoutOffset;
-        } else {
-            List<ViewInfo> children = new ArrayList<>(childCount);
-            for (int i = 0; i < childCount; i++) {
-                children.add(visit(viewGroup.getChildAt(i), hOffset, vOffset, setExtendedInfo,
-                        isContentFrame));
-            }
-            return children;
-        }
-    }
-
-    /**
-     * Visits the children of {@link #mContentRoot} and generates {@link ViewInfo} containing the
-     * bounds of all the views. It returns two {@code ViewInfo} objects with the same children,
-     * one with the {@code offset} and other without the {@code offset}. The offset is needed to
-     * get the right bounds if the {@code ViewInfo} hierarchy is accessed from
-     * {@code mViewInfoList}. When the hierarchy is accessed via {@code mSystemViewInfoList}, the
-     * offset is not needed.
-     *
-     * @return an array of length two, with ViewInfo at index 0 is without offset and ViewInfo at
-     *         index 1 is with the offset.
-     */
-    @NonNull
-    private ViewInfo[] visitContentRoot(View view, int hOffset, int vOffset,
-            boolean setExtendedInfo) {
-        ViewInfo[] result = new ViewInfo[2];
-        if (view == null) {
-            return result;
-        }
-
-        result[0] = createViewInfo(view, 0, 0, setExtendedInfo, true);
-        result[1] = createViewInfo(view, hOffset, vOffset, setExtendedInfo, true);
-        if (view instanceof ViewGroup) {
-            List<ViewInfo> children =
-                    visitAllChildren((ViewGroup) view, 0, 0, setExtendedInfo, true);
-            result[0].setChildren(children);
-            result[1].setChildren(children);
-        }
-        return result;
-    }
-
-    /**
-     * Creates a {@link ViewInfo} for the view. The {@code ViewInfo} corresponding to the children
-     * of the {@code view} are not created. Consequently, the children of {@code ViewInfo} is not
-     * set.
-     * @param hOffset horizontal offset for the view bounds. Used only if view is part of the
-     * content frame.
-     * @param vOffset vertial an offset for the view bounds. Used only if view is part of the
-     * content frame.
-     */
-    private ViewInfo createViewInfo(View view, int hOffset, int vOffset, boolean setExtendedInfo,
-            boolean isContentFrame) {
-        if (view == null) {
-            return null;
-        }
-
-        ViewParent parent = view.getParent();
-        ViewInfo result;
-        if (isContentFrame) {
-            // Account for parent scroll values when calculating the bounding box
-            int scrollX = parent != null ? ((View)parent).getScrollX() : 0;
-            int scrollY = parent != null ? ((View)parent).getScrollY() : 0;
-
-            // The view is part of the layout added by the user. Hence,
-            // the ViewCookie may be obtained only through the Context.
-            result = new ViewInfo(view.getClass().getName(),
-                    getContext().getViewKey(view), -scrollX + view.getLeft() + hOffset,
-                    -scrollY + view.getTop() + vOffset, -scrollX + view.getRight() + hOffset,
-                    -scrollY + view.getBottom() + vOffset,
-                    view, view.getLayoutParams());
-        } else {
-            // We are part of the system decor.
-            SystemViewInfo r = new SystemViewInfo(view.getClass().getName(),
-                    getViewKey(view),
-                    view.getLeft(), view.getTop(), view.getRight(),
-                    view.getBottom(), view, view.getLayoutParams());
-            result = r;
-            // We currently mark three kinds of views:
-            // 1. Menus in the Action Bar
-            // 2. Menus in the Overflow popup.
-            // 3. The overflow popup button.
-            if (view instanceof ListMenuItemView) {
-                // Mark 2.
-                // All menus in the popup are of type ListMenuItemView.
-                r.setViewType(ViewType.ACTION_BAR_OVERFLOW_MENU);
-            } else {
-                // Mark 3.
-                ViewGroup.LayoutParams lp = view.getLayoutParams();
-                if (lp instanceof ActionMenuView.LayoutParams &&
-                        ((ActionMenuView.LayoutParams) lp).isOverflowButton) {
-                    r.setViewType(ViewType.ACTION_BAR_OVERFLOW);
-                } else {
-                    // Mark 1.
-                    // A view is a menu in the Action Bar is it is not the overflow button and of
-                    // its parent is of type ActionMenuView. We can also check if the view is
-                    // instanceof ActionMenuItemView but that will fail for menus using
-                    // actionProviderClass.
-                    while (parent != mViewRoot && parent instanceof ViewGroup) {
-                        if (parent instanceof ActionMenuView) {
-                            r.setViewType(ViewType.ACTION_BAR_MENU);
-                            break;
-                        }
-                        parent = parent.getParent();
-                    }
-                }
-            }
-        }
-
-        if (setExtendedInfo) {
-            MarginLayoutParams marginParams = null;
-            LayoutParams params = view.getLayoutParams();
-            if (params instanceof MarginLayoutParams) {
-                marginParams = (MarginLayoutParams) params;
-            }
-            result.setExtendedInfo(view.getBaseline(),
-                    marginParams != null ? marginParams.leftMargin : 0,
-                    marginParams != null ? marginParams.topMargin : 0,
-                    marginParams != null ? marginParams.rightMargin : 0,
-                    marginParams != null ? marginParams.bottomMargin : 0);
-        }
-
-        return result;
-    }
-
-    /* (non-Javadoc)
-     * The cookie for menu items are stored in menu item and not in the map from View stored in
-     * BridgeContext.
-     */
-    @Nullable
-    private Object getViewKey(View view) {
-        BridgeContext context = getContext();
-        if (!(view instanceof MenuView.ItemView)) {
-            return context.getViewKey(view);
-        }
-        MenuItemImpl menuItem;
-        if (view instanceof ActionMenuItemView) {
-            menuItem = ((ActionMenuItemView) view).getItemData();
-        } else if (view instanceof ListMenuItemView) {
-            menuItem = ((ListMenuItemView) view).getItemData();
-        } else if (view instanceof IconMenuItemView) {
-            menuItem = ((IconMenuItemView) view).getItemData();
-        } else {
-            menuItem = null;
-        }
-        if (menuItem instanceof BridgeMenuItemImpl) {
-            return ((BridgeMenuItemImpl) menuItem).getViewCookie();
-        }
-
-        return null;
-    }
-
-    public void invalidateRenderingSize() {
-        mMeasuredScreenWidth = mMeasuredScreenHeight = -1;
-    }
-
-    public BufferedImage getImage() {
-        return mImage;
-    }
-
-    public boolean isAlphaChannelImage() {
-        return mIsAlphaChannelImage;
-    }
-
-    public List<ViewInfo> getViewInfos() {
-        return mViewInfoList;
-    }
-
-    public List<ViewInfo> getSystemViewInfos() {
-        return mSystemViewInfoList;
-    }
-
-    public Map<Object, PropertiesMap> getDefaultProperties() {
-        return getContext().getDefaultProperties();
-    }
-
-    public void setScene(RenderSession session) {
-        mScene = session;
-    }
-
-    public RenderSession getSession() {
-        return mScene;
-    }
-
-    public void dispose() {
-        boolean createdLooper = false;
-        if (Looper.myLooper() == null) {
-            // Detaching the root view from the window will try to stop any running animations.
-            // The stop method checks that it can run in the looper so, if there is no current
-            // looper, we create a temporary one to complete the shutdown.
-            Bridge.prepareThread();
-            createdLooper = true;
-        }
-        AttachInfo_Accessor.detachFromWindow(mViewRoot);
-        if (mCanvas != null) {
-            mCanvas.release();
-            mCanvas = null;
-        }
-        if (mViewInfoList != null) {
-            mViewInfoList.clear();
-        }
-        if (mSystemViewInfoList != null) {
-            mSystemViewInfoList.clear();
-        }
-        mImage = null;
-        mViewRoot = null;
-        mContentRoot = null;
-
-        if (createdLooper) {
-            Bridge.cleanupThread();
-            Choreographer_Delegate.dispose();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
deleted file mode 100644
index 75f9ec5..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.SdkConstants;
-import com.android.ide.common.rendering.api.DensityBasedResourceValue;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.ninepatch.NinePatch;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.resources.Density;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.res.ColorStateList;
-import android.content.res.ComplexColor;
-import android.content.res.ComplexColor_Accessor;
-import android.content.res.FontResourcesParser;
-import android.content.res.GradientColor;
-import android.content.res.Resources.Theme;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Color;
-import android.graphics.NinePatch_Delegate;
-import android.graphics.Rect;
-import android.graphics.Typeface;
-import android.graphics.Typeface_Accessor;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.NinePatchDrawable;
-import android.text.FontConfig;
-import android.util.TypedValue;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Helper class to provide various conversion method used in handling android resources.
- */
-public final class ResourceHelper {
-
-    private final static Pattern sFloatPattern = Pattern.compile("(-?[0-9]+(?:\\.[0-9]+)?)(.*)");
-    private final static float[] sFloatOut = new float[1];
-
-    private final static TypedValue mValue = new TypedValue();
-
-    /**
-     * Returns the color value represented by the given string value
-     * @param value the color value
-     * @return the color as an int
-     * @throws NumberFormatException if the conversion failed.
-     */
-    public static int getColor(String value) {
-        if (value != null) {
-            value = value.trim();
-            if (!value.startsWith("#")) {
-                if (value.startsWith(SdkConstants.PREFIX_THEME_REF)) {
-                    throw new NumberFormatException(String.format(
-                            "Attribute '%s' not found. Are you using the right theme?", value));
-                }
-                throw new NumberFormatException(
-                        String.format("Color value '%s' must start with #", value));
-            }
-
-            value = value.substring(1);
-
-            // make sure it's not longer than 32bit
-            if (value.length() > 8) {
-                throw new NumberFormatException(String.format(
-                        "Color value '%s' is too long. Format is either" +
-                        "#AARRGGBB, #RRGGBB, #RGB, or #ARGB",
-                        value));
-            }
-
-            if (value.length() == 3) { // RGB format
-                char[] color = new char[8];
-                color[0] = color[1] = 'F';
-                color[2] = color[3] = value.charAt(0);
-                color[4] = color[5] = value.charAt(1);
-                color[6] = color[7] = value.charAt(2);
-                value = new String(color);
-            } else if (value.length() == 4) { // ARGB format
-                char[] color = new char[8];
-                color[0] = color[1] = value.charAt(0);
-                color[2] = color[3] = value.charAt(1);
-                color[4] = color[5] = value.charAt(2);
-                color[6] = color[7] = value.charAt(3);
-                value = new String(color);
-            } else if (value.length() == 6) {
-                value = "FF" + value;
-            }
-
-            // this is a RRGGBB or AARRGGBB value
-
-            // Integer.parseInt will fail to parse strings like "ff191919", so we use
-            // a Long, but cast the result back into an int, since we know that we're only
-            // dealing with 32 bit values.
-            return (int)Long.parseLong(value, 16);
-        }
-
-        throw new NumberFormatException();
-    }
-
-    /**
-     * Returns a {@link ComplexColor} from the given {@link ResourceValue}
-     *
-     * @param resValue the value containing a color value or a file path to a complex color
-     * definition
-     * @param context the current context
-     * @param theme the theme to use when resolving the complex color
-     * @param allowGradients when false, only {@link ColorStateList} will be returned. If a {@link
-     * GradientColor} is found, null will be returned.
-     */
-    @Nullable
-    private static ComplexColor getInternalComplexColor(@NonNull ResourceValue resValue,
-            @NonNull BridgeContext context, @Nullable Theme theme, boolean allowGradients) {
-        String value = resValue.getValue();
-        if (value == null || RenderResources.REFERENCE_NULL.equals(value)) {
-            return null;
-        }
-
-        XmlPullParser parser = null;
-        // first check if the value is a file (xml most likely)
-        Boolean psiParserSupport = context.getLayoutlibCallback().getFlag(
-                RenderParamsFlags.FLAG_KEY_XML_FILE_PARSER_SUPPORT);
-        if (psiParserSupport != null && psiParserSupport) {
-            parser = context.getLayoutlibCallback().getXmlFileParser(value);
-        }
-        if (parser == null) {
-            File f = new File(value);
-            if (f.isFile()) {
-                // let the framework inflate the color from the XML file, by
-                // providing an XmlPullParser
-                try {
-                    parser = ParserFactory.create(f);
-                } catch (XmlPullParserException | FileNotFoundException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                            "Failed to parse file " + value, e, null /*data*/);
-                }
-            }
-        }
-
-        if (parser != null) {
-            try {
-                BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
-                        parser, context, resValue.isFramework());
-                try {
-                    // Advance the parser to the first element so we can detect if it's a
-                    // color list or a gradient color
-                    int type;
-                    //noinspection StatementWithEmptyBody
-                    while ((type = blockParser.next()) != XmlPullParser.START_TAG
-                            && type != XmlPullParser.END_DOCUMENT) {
-                        // Seek parser to start tag.
-                    }
-
-                    if (type != XmlPullParser.START_TAG) {
-                        assert false : "No start tag found";
-                        return null;
-                    }
-
-                    final String name = blockParser.getName();
-                    if (allowGradients && "gradient".equals(name)) {
-                        return ComplexColor_Accessor.createGradientColorFromXmlInner(
-                                context.getResources(),
-                                blockParser, blockParser,
-                                theme);
-                    } else if ("selector".equals(name)) {
-                        return ComplexColor_Accessor.createColorStateListFromXmlInner(
-                                context.getResources(),
-                                blockParser, blockParser,
-                                theme);
-                    }
-                } finally {
-                    blockParser.ensurePopped();
-                }
-            } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to configure parser for " + value, e, null /*data*/);
-                // we'll return null below.
-            } catch (Exception e) {
-                // this is an error and not warning since the file existence is
-                // checked before attempting to parse it.
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                        "Failed to parse file " + value, e, null /*data*/);
-
-                return null;
-            }
-        } else {
-            // try to load the color state list from an int
-            try {
-                int color = getColor(value);
-                return ColorStateList.valueOf(color);
-            } catch (NumberFormatException e) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
-                        "Failed to convert " + value + " into a ColorStateList", e,
-                        null /*data*/);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a {@link ColorStateList} from the given {@link ResourceValue}
-     *
-     * @param resValue the value containing a color value or a file path to a complex color
-     * definition
-     * @param context the current context
-     */
-    @Nullable
-    public static ColorStateList getColorStateList(@NonNull ResourceValue resValue,
-            @NonNull BridgeContext context) {
-        return (ColorStateList) getInternalComplexColor(resValue, context, context.getTheme(),
-                false);
-    }
-
-    /**
-     * Returns a {@link ComplexColor} from the given {@link ResourceValue}
-     *
-     * @param resValue the value containing a color value or a file path to a complex color
-     * definition
-     * @param context the current context
-     */
-    @Nullable
-    public static ComplexColor getComplexColor(@NonNull ResourceValue resValue,
-            @NonNull BridgeContext context) {
-        return getInternalComplexColor(resValue, context, context.getTheme(), true);
-    }
-
-    /**
-     * Returns a drawable from the given value.
-     * @param value The value that contains a path to a 9 patch, a bitmap or a xml based drawable,
-     * or an hexadecimal color
-     * @param context the current context
-     */
-    public static Drawable getDrawable(ResourceValue value, BridgeContext context) {
-        return getDrawable(value, context, null);
-    }
-
-    /**
-     * Returns a drawable from the given value.
-     * @param value The value that contains a path to a 9 patch, a bitmap or a xml based drawable,
-     * or an hexadecimal color
-     * @param context the current context
-     * @param theme the theme to be used to inflate the drawable.
-     */
-    public static Drawable getDrawable(ResourceValue value, BridgeContext context, Theme theme) {
-        if (value == null) {
-            return null;
-        }
-        String stringValue = value.getValue();
-        if (RenderResources.REFERENCE_NULL.equals(stringValue)) {
-            return null;
-        }
-
-        String lowerCaseValue = stringValue.toLowerCase();
-
-        Density density = Density.MEDIUM;
-        if (value instanceof DensityBasedResourceValue) {
-            density = ((DensityBasedResourceValue) value).getResourceDensity();
-        }
-
-        if (lowerCaseValue.endsWith(NinePatch.EXTENSION_9PATCH)) {
-            File file = new File(stringValue);
-            if (file.isFile()) {
-                try {
-                    return getNinePatchDrawable(new FileInputStream(file), density,
-                            value.isFramework(), stringValue, context);
-                } catch (IOException e) {
-                    // failed to read the file, we'll return null below.
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                            "Failed lot load " + file.getAbsolutePath(), e, null /*data*/);
-                }
-            }
-
-            return null;
-        } else if (lowerCaseValue.endsWith(".xml") || stringValue.startsWith("@aapt:_aapt/")) {
-            // create a block parser for the file
-            try {
-                XmlPullParser parser = context.getLayoutlibCallback().getParser(value);
-                if (parser == null) {
-                    File drawableFile = new File(stringValue);
-                    if (drawableFile.isFile()) {
-                        parser = ParserFactory.create(drawableFile);
-                    }
-                }
-
-                BridgeXmlBlockParser blockParser =
-                        new BridgeXmlBlockParser(parser, context, value.isFramework());
-                try {
-                    return Drawable.createFromXml(context.getResources(), blockParser, theme);
-                } finally {
-                    blockParser.ensurePopped();
-                }
-            } catch (Exception e) {
-                // this is an error and not warning since the file existence is checked before
-                // attempting to parse it.
-                Bridge.getLog().error(null, "Failed to parse file " + stringValue, e,
-                        null /*data*/);
-            }
-
-            return null;
-        } else {
-            File bmpFile = new File(stringValue);
-            if (bmpFile.isFile()) {
-                try {
-                    Bitmap bitmap = Bridge.getCachedBitmap(stringValue,
-                            value.isFramework() ? null : context.getProjectKey());
-
-                    if (bitmap == null) {
-                        bitmap =
-                                Bitmap_Delegate.createBitmap(bmpFile, false /*isMutable*/, density);
-                        Bridge.setCachedBitmap(stringValue, bitmap,
-                                value.isFramework() ? null : context.getProjectKey());
-                    }
-
-                    return new BitmapDrawable(context.getResources(), bitmap);
-                } catch (IOException e) {
-                    // we'll return null below
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                            "Failed lot load " + bmpFile.getAbsolutePath(), e, null /*data*/);
-                }
-            } else {
-                // attempt to get a color from the value
-                try {
-                    int color = getColor(stringValue);
-                    return new ColorDrawable(color);
-                } catch (NumberFormatException e) {
-                    // we'll return null below.
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
-                            "Failed to convert " + stringValue + " into a drawable", e,
-                            null /*data*/);
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a {@link Typeface} given a font name. The font name, can be a system font family
-     * (like sans-serif) or a full path if the font is to be loaded from resources.
-     */
-    public static Typeface getFont(String fontName, BridgeContext context, Theme theme, boolean
-            isFramework) {
-        if (fontName == null) {
-            return null;
-        }
-
-        if (Typeface_Accessor.isSystemFont(fontName)) {
-            // Shortcut for the case where we are asking for a system font name. Those are not
-            // loaded using external resources.
-            return null;
-        }
-
-        // Check if this is an asset that we've already loaded dynamically
-        Typeface typeface = Typeface.findFromCache(context.getAssets(), fontName);
-        if (typeface != null) {
-            return typeface;
-        }
-
-        String lowerCaseValue = fontName.toLowerCase();
-        if (lowerCaseValue.endsWith(".xml")) {
-            // create a block parser for the file
-            Boolean psiParserSupport = context.getLayoutlibCallback().getFlag(
-                    RenderParamsFlags.FLAG_KEY_XML_FILE_PARSER_SUPPORT);
-            XmlPullParser parser = null;
-            if (psiParserSupport != null && psiParserSupport) {
-                parser = context.getLayoutlibCallback().getXmlFileParser(fontName);
-            }
-            else {
-                File f = new File(fontName);
-                if (f.isFile()) {
-                    try {
-                        parser = ParserFactory.create(f);
-                    } catch (XmlPullParserException | FileNotFoundException e) {
-                        // this is an error and not warning since the file existence is checked before
-                        // attempting to parse it.
-                        Bridge.getLog().error(null, "Failed to parse file " + fontName,
-                                e, null /*data*/);
-                    }
-                }
-            }
-
-            if (parser != null) {
-                BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
-                        parser, context, isFramework);
-                try {
-                    FontResourcesParser.FamilyResourceEntry entry =
-                            FontResourcesParser.parse(blockParser, context.getResources());
-                    typeface = Typeface.createFromResources(entry, context.getAssets(),
-                            fontName);
-                } catch (XmlPullParserException | IOException e) {
-                    Bridge.getLog().error(null, "Failed to parse file " + fontName,
-                            e, null /*data*/);
-                } finally {
-                    blockParser.ensurePopped();
-                }
-            } else {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        String.format("File %s does not exist (or is not a file)", fontName),
-                        null /*data*/);
-            }
-        } else {
-            typeface = Typeface.createFromResources(context.getAssets(), fontName, 0);
-        }
-
-        return typeface;
-    }
-
-    /**
-     * Returns a {@link Typeface} given a font name. The font name, can be a system font family
-     * (like sans-serif) or a full path if the font is to be loaded from resources.
-     */
-    public static Typeface getFont(ResourceValue value, BridgeContext context, Theme theme) {
-        if (value == null) {
-            return null;
-        }
-
-        return getFont(value.getValue(), context, theme, value.isFramework());
-    }
-
-    private static Drawable getNinePatchDrawable(InputStream inputStream, Density density,
-            boolean isFramework, String cacheKey, BridgeContext context) throws IOException {
-        // see if we still have both the chunk and the bitmap in the caches
-        NinePatchChunk chunk = Bridge.getCached9Patch(cacheKey,
-                isFramework ? null : context.getProjectKey());
-        Bitmap bitmap = Bridge.getCachedBitmap(cacheKey,
-                isFramework ? null : context.getProjectKey());
-
-        // if either chunk or bitmap is null, then we reload the 9-patch file.
-        if (chunk == null || bitmap == null) {
-            try {
-                NinePatch ninePatch = NinePatch.load(inputStream, true /*is9Patch*/,
-                        false /* convert */);
-                if (ninePatch != null) {
-                    if (chunk == null) {
-                        chunk = ninePatch.getChunk();
-
-                        Bridge.setCached9Patch(cacheKey, chunk,
-                                isFramework ? null : context.getProjectKey());
-                    }
-
-                    if (bitmap == null) {
-                        bitmap = Bitmap_Delegate.createBitmap(ninePatch.getImage(),
-                                false /*isMutable*/,
-                                density);
-
-                        Bridge.setCachedBitmap(cacheKey, bitmap,
-                                isFramework ? null : context.getProjectKey());
-                    }
-                }
-            } catch (MalformedURLException e) {
-                // URL is wrong, we'll return null below
-            }
-        }
-
-        if (chunk != null && bitmap != null) {
-            int[] padding = chunk.getPadding();
-            Rect paddingRect = new Rect(padding[0], padding[1], padding[2], padding[3]);
-
-            return new NinePatchDrawable(context.getResources(), bitmap,
-                    NinePatch_Delegate.serialize(chunk),
-                    paddingRect, null);
-        }
-
-        return null;
-    }
-
-    /**
-     * Looks for an attribute in the current theme.
-     *
-     * @param resources the render resources
-     * @param name the name of the attribute
-     * @param defaultValue the default value.
-     * @param isFrameworkAttr if the attribute is in android namespace
-     * @return the value of the attribute or the default one if not found.
-     */
-    public static boolean getBooleanThemeValue(@NonNull RenderResources resources, String name,
-            boolean isFrameworkAttr, boolean defaultValue) {
-        ResourceValue value = resources.findItemInTheme(name, isFrameworkAttr);
-        value = resources.resolveResValue(value);
-        if (value == null) {
-            return defaultValue;
-        }
-        return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue);
-    }
-
-    // ------- TypedValue stuff
-    // This is taken from //device/libs/utils/ResourceTypes.cpp
-
-    private static final class UnitEntry {
-        String name;
-        int type;
-        int unit;
-        float scale;
-
-        UnitEntry(String name, int type, int unit, float scale) {
-            this.name = name;
-            this.type = type;
-            this.unit = unit;
-            this.scale = scale;
-        }
-    }
-
-    private final static UnitEntry[] sUnitNames = new UnitEntry[] {
-        new UnitEntry("px", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PX, 1.0f),
-        new UnitEntry("dip", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_DIP, 1.0f),
-        new UnitEntry("dp", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_DIP, 1.0f),
-        new UnitEntry("sp", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_SP, 1.0f),
-        new UnitEntry("pt", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PT, 1.0f),
-        new UnitEntry("in", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_IN, 1.0f),
-        new UnitEntry("mm", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_MM, 1.0f),
-        new UnitEntry("%", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION, 1.0f/100),
-        new UnitEntry("%p", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100),
-    };
-
-    /**
-     * Returns the raw value from the given attribute float-type value string.
-     * This object is only valid until the next call on to {@link ResourceHelper}.
-     */
-    public static TypedValue getValue(String attribute, String value, boolean requireUnit) {
-        if (parseFloatAttribute(attribute, value, mValue, requireUnit)) {
-            return mValue;
-        }
-
-        return null;
-    }
-
-    /**
-     * Parse a float attribute and return the parsed value into a given TypedValue.
-     * @param attribute the name of the attribute. Can be null if <var>requireUnit</var> is false.
-     * @param value the string value of the attribute
-     * @param outValue the TypedValue to receive the parsed value
-     * @param requireUnit whether the value is expected to contain a unit.
-     * @return true if success.
-     */
-    public static boolean parseFloatAttribute(String attribute, @NonNull String value,
-            TypedValue outValue, boolean requireUnit) {
-        assert !requireUnit || attribute != null;
-
-        // remove the space before and after
-        value = value.trim();
-        int len = value.length();
-
-        if (len <= 0) {
-            return false;
-        }
-
-        // check that there's no non ascii characters.
-        char[] buf = value.toCharArray();
-        for (int i = 0 ; i < len ; i++) {
-            if (buf[i] > 255) {
-                return false;
-            }
-        }
-
-        // check the first character
-        if ((buf[0] < '0' || buf[0] > '9') && buf[0] != '.' && buf[0] != '-' && buf[0] != '+') {
-            return false;
-        }
-
-        // now look for the string that is after the float...
-        Matcher m = sFloatPattern.matcher(value);
-        if (m.matches()) {
-            String f_str = m.group(1);
-            String end = m.group(2);
-
-            float f;
-            try {
-                f = Float.parseFloat(f_str);
-            } catch (NumberFormatException e) {
-                // this shouldn't happen with the regexp above.
-                return false;
-            }
-
-            if (end.length() > 0 && end.charAt(0) != ' ') {
-                // Might be a unit...
-                if (parseUnit(end, outValue, sFloatOut)) {
-                    computeTypedValue(outValue, f, sFloatOut[0]);
-                    return true;
-                }
-                return false;
-            }
-
-            // make sure it's only spaces at the end.
-            end = end.trim();
-
-            if (end.length() == 0) {
-                if (outValue != null) {
-                    if (!requireUnit) {
-                        outValue.type = TypedValue.TYPE_FLOAT;
-                        outValue.data = Float.floatToIntBits(f);
-                    } else {
-                        // no unit when required? Use dp and out an error.
-                        applyUnit(sUnitNames[1], outValue, sFloatOut);
-                        computeTypedValue(outValue, f, sFloatOut[0]);
-
-                        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
-                                String.format(
-                                        "Dimension \"%1$s\" in attribute \"%2$s\" is missing unit!",
-                                        value, attribute),
-                                null);
-                    }
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private static void computeTypedValue(TypedValue outValue, float value, float scale) {
-        value *= scale;
-        boolean neg = value < 0;
-        if (neg) {
-            value = -value;
-        }
-        long bits = (long)(value*(1<<23)+.5f);
-        int radix;
-        int shift;
-        if ((bits&0x7fffff) == 0) {
-            // Always use 23p0 if there is no fraction, just to make
-            // things easier to read.
-            radix = TypedValue.COMPLEX_RADIX_23p0;
-            shift = 23;
-        } else if ((bits&0xffffffffff800000L) == 0) {
-            // Magnitude is zero -- can fit in 0 bits of precision.
-            radix = TypedValue.COMPLEX_RADIX_0p23;
-            shift = 0;
-        } else if ((bits&0xffffffff80000000L) == 0) {
-            // Magnitude can fit in 8 bits of precision.
-            radix = TypedValue.COMPLEX_RADIX_8p15;
-            shift = 8;
-        } else if ((bits&0xffffff8000000000L) == 0) {
-            // Magnitude can fit in 16 bits of precision.
-            radix = TypedValue.COMPLEX_RADIX_16p7;
-            shift = 16;
-        } else {
-            // Magnitude needs entire range, so no fractional part.
-            radix = TypedValue.COMPLEX_RADIX_23p0;
-            shift = 23;
-        }
-        int mantissa = (int)(
-            (bits>>shift) & TypedValue.COMPLEX_MANTISSA_MASK);
-        if (neg) {
-            mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK;
-        }
-        outValue.data |=
-            (radix<<TypedValue.COMPLEX_RADIX_SHIFT)
-            | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT);
-    }
-
-    private static boolean parseUnit(String str, TypedValue outValue, float[] outScale) {
-        str = str.trim();
-
-        for (UnitEntry unit : sUnitNames) {
-            if (unit.name.equals(str)) {
-                applyUnit(unit, outValue, outScale);
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static void applyUnit(UnitEntry unit, TypedValue outValue, float[] outScale) {
-        outValue.type = unit.type;
-        // COMPLEX_UNIT_SHIFT is 0 and hence intelliJ complains about it. Suppress the warning.
-        //noinspection PointlessBitwiseExpression
-        outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT;
-        outScale[0] = unit.scale;
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java
deleted file mode 100644
index 9bd0015..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import java.util.ArrayList;
-
-/**
- * Custom Stack implementation on top of an {@link ArrayList} instead of
- * using {@link java.util.Stack} which is on top of a vector.
- *
- * @param <T>
- */
-public class Stack<T> extends ArrayList<T> {
-
-    private static final long serialVersionUID = 1L;
-
-    public Stack() {
-        super();
-    }
-
-    public Stack(int size) {
-        super(size);
-    }
-
-    /**
-     * Pushes the given object to the stack
-     * @param object the object to push
-     */
-    public void push(T object) {
-        add(object);
-    }
-
-    /**
-     * Remove the object at the top of the stack and returns it.
-     * @return the removed object or null if the stack was empty.
-     */
-    public T pop() {
-        if (size() > 0) {
-            return remove(size() - 1);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the object at the top of the stack.
-     * @return the object at the top or null if the stack is empty.
-     */
-    public T peek() {
-        if (size() > 0) {
-            return get(size() - 1);
-        }
-
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java
deleted file mode 100644
index 9fea167..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java
+++ /dev/null
@@ -1,51 +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.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.ide.common.rendering.api.ViewType;
-
-/**
- * ViewInfo for views added by the platform.
- */
-public class SystemViewInfo extends ViewInfo {
-
-    private ViewType mViewType;
-
-    public SystemViewInfo(String name, Object cookie, int left, int top,
-            int right, int bottom) {
-        super(name, cookie, left, top, right, bottom);
-    }
-
-    public SystemViewInfo(String name, Object cookie, int left, int top,
-            int right, int bottom, Object viewObject, Object layoutParamsObject) {
-        super(name, cookie, left, top, right, bottom, viewObject,
-                layoutParamsObject);
-    }
-
-    @Override
-    public ViewType getViewType() {
-        if (mViewType != null) {
-            return mViewType;
-        }
-        return ViewType.SYSTEM_UNKNOWN;
-    }
-
-    public void setViewType(ViewType type) {
-        mViewType = type;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
deleted file mode 100644
index c0ca1d5..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
+++ /dev/null
@@ -1,148 +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.layoutlib.bridge.impl.binding;
-
-import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.IProjectCallback.ViewAttribute;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.util.Pair;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.Checkable;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-/**
- * A Helper class to do fake data binding in {@link AdapterView} objects.
- */
-public class AdapterHelper {
-
-    @SuppressWarnings("deprecation")
-    static Pair<View, Boolean> getView(AdapterItem item, AdapterItem parentItem, ViewGroup parent,
-            LayoutlibCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) {
-        // we don't care about recycling here because we never scroll.
-        DataBindingItem dataBindingItem = item.getDataBindingItem();
-
-        BridgeContext context = RenderAction.getCurrentContext();
-
-        Pair<View, Boolean> pair = context.inflateView(dataBindingItem.getViewReference(),
-                parent, false /*attachToRoot*/, skipCallbackParser);
-
-        View view = pair.getFirst();
-        skipCallbackParser |= pair.getSecond();
-
-        if (view != null) {
-            fillView(context, view, item, parentItem, callback, adapterRef);
-        } else {
-            // create a text view to display an error.
-            TextView tv = new TextView(context);
-            tv.setText("Unable to find layout: " + dataBindingItem.getViewReference().getName());
-            view = tv;
-        }
-
-        return Pair.of(view, skipCallbackParser);
-    }
-
-    private static void fillView(BridgeContext context, View view, AdapterItem item,
-            AdapterItem parentItem, LayoutlibCallback callback, ResourceReference adapterRef) {
-        if (view instanceof ViewGroup) {
-            ViewGroup group = (ViewGroup) view;
-            final int count = group.getChildCount();
-            for (int i = 0 ; i < count ; i++) {
-                fillView(context, group.getChildAt(i), item, parentItem, callback, adapterRef);
-            }
-        } else {
-            int id = view.getId();
-            if (id != 0) {
-                ResourceReference resolvedRef = context.resolveId(id);
-                if (resolvedRef != null) {
-                    int fullPosition = item.getFullPosition();
-                    int positionPerType = item.getPositionPerType();
-                    int fullParentPosition = parentItem != null ? parentItem.getFullPosition() : 0;
-                    int parentPositionPerType = parentItem != null ?
-                            parentItem.getPositionPerType() : 0;
-
-                    if (view instanceof TextView) {
-                        TextView tv = (TextView) view;
-                        Object value = callback.getAdapterItemValue(
-                                adapterRef, context.getViewKey(view),
-                                item.getDataBindingItem().getViewReference(),
-                                fullPosition, positionPerType,
-                                fullParentPosition, parentPositionPerType,
-                                resolvedRef, ViewAttribute.TEXT, tv.getText().toString());
-                        if (value != null) {
-                            if (value.getClass() != ViewAttribute.TEXT.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
-                                        "Wrong Adapter Item value class for TEXT. Expected String, got %s",
-                                        value.getClass().getName()), null);
-                            } else {
-                                tv.setText((String) value);
-                            }
-                        }
-                    }
-
-                    if (view instanceof Checkable) {
-                        Checkable cb = (Checkable) view;
-
-                        Object value = callback.getAdapterItemValue(
-                                adapterRef, context.getViewKey(view),
-                                item.getDataBindingItem().getViewReference(),
-                                fullPosition, positionPerType,
-                                fullParentPosition, parentPositionPerType,
-                                resolvedRef, ViewAttribute.IS_CHECKED, cb.isChecked());
-                        if (value != null) {
-                            if (value.getClass() != ViewAttribute.IS_CHECKED.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
-                                        "Wrong Adapter Item value class for IS_CHECKED. Expected Boolean, got %s",
-                                        value.getClass().getName()), null);
-                            } else {
-                                cb.setChecked((Boolean) value);
-                            }
-                        }
-                    }
-
-                    if (view instanceof ImageView) {
-                        ImageView iv = (ImageView) view;
-
-                        Object value = callback.getAdapterItemValue(
-                                adapterRef, context.getViewKey(view),
-                                item.getDataBindingItem().getViewReference(),
-                                fullPosition, positionPerType,
-                                fullParentPosition, parentPositionPerType,
-                                resolvedRef, ViewAttribute.SRC, iv.getDrawable());
-                        if (value != null) {
-                            if (value.getClass() != ViewAttribute.SRC.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
-                                        "Wrong Adapter Item value class for SRC. Expected Boolean, got %s",
-                                        value.getClass().getName()), null);
-                            } else {
-                                // FIXME
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java
deleted file mode 100644
index 8e28dba..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java
+++ /dev/null
@@ -1,74 +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.layoutlib.bridge.impl.binding;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import com.android.ide.common.rendering.api.DataBindingItem;
-
-/**
- * This is the items provided by the adapter. They are dynamically generated.
- */
-final class AdapterItem {
-    private final DataBindingItem mItem;
-    private final int mType;
-    private final int mFullPosition;
-    private final int mPositionPerType;
-    private List<AdapterItem> mChildren;
-
-    protected AdapterItem(DataBindingItem item, int type, int fullPosition,
-            int positionPerType) {
-        mItem = item;
-        mType = type;
-        mFullPosition = fullPosition;
-        mPositionPerType = positionPerType;
-    }
-
-    void addChild(AdapterItem child) {
-        if (mChildren == null) {
-            mChildren = new ArrayList<AdapterItem>();
-        }
-
-        mChildren.add(child);
-    }
-
-    List<AdapterItem> getChildren() {
-        if (mChildren != null) {
-            return mChildren;
-        }
-
-        return Collections.emptyList();
-    }
-
-    int getType() {
-        return mType;
-    }
-
-    int getFullPosition() {
-        return mFullPosition;
-    }
-
-    int getPositionPerType() {
-        return mPositionPerType;
-    }
-
-    DataBindingItem getDataBindingItem() {
-        return mItem;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
deleted file mode 100644
index 142eac1..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
+++ /dev/null
@@ -1,132 +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.
- */
-
-package com.android.layoutlib.bridge.impl.binding;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.util.Pair;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.ListAdapter;
-import android.widget.SpinnerAdapter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Fake adapter to do fake data binding in {@link AdapterView} objects for {@link ListAdapter}
- * and {@link SpinnerAdapter}.
- *
- */
-public class FakeAdapter extends BaseAdapter {
-
-    // don't use a set because the order is important.
-    private final List<ResourceReference> mTypes = new ArrayList<ResourceReference>();
-    private final LayoutlibCallback mCallback;
-    private final ResourceReference mAdapterRef;
-    private final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
-    private boolean mSkipCallbackParser = false;
-
-    public FakeAdapter(ResourceReference adapterRef, AdapterBinding binding,
-            LayoutlibCallback callback) {
-        mAdapterRef = adapterRef;
-        mCallback = callback;
-
-        final int repeatCount = binding.getRepeatCount();
-        final int itemCount = binding.getItemCount();
-
-        // Need an array to count for each type.
-        // This is likely too big, but is the max it can be.
-        int[] typeCount = new int[itemCount];
-
-        // We put several repeating sets.
-        for (int r = 0 ; r < repeatCount ; r++) {
-            // loop on the type of list items, and add however many for each type.
-            for (DataBindingItem dataBindingItem : binding) {
-                ResourceReference viewRef = dataBindingItem.getViewReference();
-                int typeIndex = mTypes.indexOf(viewRef);
-                if (typeIndex == -1) {
-                    typeIndex = mTypes.size();
-                    mTypes.add(viewRef);
-                }
-
-                int count = dataBindingItem.getCount();
-
-                int index = typeCount[typeIndex];
-                typeCount[typeIndex] += count;
-
-                for (int k = 0 ; k < count ; k++) {
-                    mItems.add(new AdapterItem(dataBindingItem, typeIndex, mItems.size(), index++));
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean isEnabled(int position) {
-        return true;
-    }
-
-    @Override
-    public int getCount() {
-        return mItems.size();
-    }
-
-    @Override
-    public Object getItem(int position) {
-        return mItems.get(position);
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return position;
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        return mItems.get(position).getType();
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        // we don't care about recycling here because we never scroll.
-        AdapterItem item = mItems.get(position);
-        @SuppressWarnings("deprecation")
-        Pair<View, Boolean> pair = AdapterHelper.getView(item, null, parent, mCallback,
-                mAdapterRef, mSkipCallbackParser);
-        mSkipCallbackParser = pair.getSecond();
-        return pair.getFirst();
-    }
-
-    @Override
-    public int getViewTypeCount() {
-        return mTypes.size();
-    }
-
-    // ---- SpinnerAdapter
-
-    @Override
-    public View getDropDownView(int position, View convertView, ViewGroup parent) {
-        // pass
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
deleted file mode 100644
index 344b17e..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
+++ /dev/null
@@ -1,236 +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.
- */
-
-package com.android.layoutlib.bridge.impl.binding;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.util.Pair;
-
-import android.database.DataSetObserver;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ExpandableListAdapter;
-import android.widget.HeterogeneousExpandableList;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@SuppressWarnings("deprecation")
-public class FakeExpandableAdapter implements ExpandableListAdapter, HeterogeneousExpandableList {
-
-    private final LayoutlibCallback mCallback;
-    private final ResourceReference mAdapterRef;
-    private boolean mSkipCallbackParser = false;
-
-    protected final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
-
-    // don't use a set because the order is important.
-    private final List<ResourceReference> mGroupTypes = new ArrayList<ResourceReference>();
-    private final List<ResourceReference> mChildrenTypes = new ArrayList<ResourceReference>();
-
-    public FakeExpandableAdapter(ResourceReference adapterRef, AdapterBinding binding,
-            LayoutlibCallback callback) {
-        mAdapterRef = adapterRef;
-        mCallback = callback;
-
-        createItems(binding, binding.getItemCount(), binding.getRepeatCount(), mGroupTypes, 1);
-    }
-
-    private void createItems(Iterable<DataBindingItem> iterable, final int itemCount,
-            final int repeatCount, List<ResourceReference> types, int depth) {
-        // Need an array to count for each type.
-        // This is likely too big, but is the max it can be.
-        int[] typeCount = new int[itemCount];
-
-        // we put several repeating sets.
-        for (int r = 0 ; r < repeatCount ; r++) {
-            // loop on the type of list items, and add however many for each type.
-            for (DataBindingItem dataBindingItem : iterable) {
-                ResourceReference viewRef = dataBindingItem.getViewReference();
-                int typeIndex = types.indexOf(viewRef);
-                if (typeIndex == -1) {
-                    typeIndex = types.size();
-                    types.add(viewRef);
-                }
-
-                List<DataBindingItem> children = dataBindingItem.getChildren();
-                int count = dataBindingItem.getCount();
-
-                // if there are children, we use the count as a repeat count for the children.
-                if (children.size() > 0) {
-                    count = 1;
-                }
-
-                int index = typeCount[typeIndex];
-                typeCount[typeIndex] += count;
-
-                for (int k = 0 ; k < count ; k++) {
-                    AdapterItem item = new AdapterItem(dataBindingItem, typeIndex, mItems.size(),
-                            index++);
-                    mItems.add(item);
-
-                    if (children.size() > 0) {
-                        createItems(dataBindingItem, depth + 1);
-                    }
-                }
-            }
-        }
-    }
-
-    private void createItems(DataBindingItem item, int depth) {
-        if (depth == 2) {
-            createItems(item, item.getChildren().size(), item.getCount(), mChildrenTypes, depth);
-        }
-    }
-
-    private AdapterItem getChildItem(int groupPosition, int childPosition) {
-        AdapterItem item = mItems.get(groupPosition);
-
-        List<AdapterItem> children = item.getChildren();
-        return children.get(childPosition);
-    }
-
-    // ---- ExpandableListAdapter
-
-    @Override
-    public int getGroupCount() {
-        return mItems.size();
-    }
-
-    @Override
-    public int getChildrenCount(int groupPosition) {
-        AdapterItem item = mItems.get(groupPosition);
-        return item.getChildren().size();
-    }
-
-    @Override
-    public Object getGroup(int groupPosition) {
-        return mItems.get(groupPosition);
-    }
-
-    @Override
-    public Object getChild(int groupPosition, int childPosition) {
-        return getChildItem(groupPosition, childPosition);
-    }
-
-    @Override
-    public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
-            ViewGroup parent) {
-        // we don't care about recycling here because we never scroll.
-        AdapterItem item = mItems.get(groupPosition);
-        Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentItem*/, parent,
-                mCallback, mAdapterRef, mSkipCallbackParser);
-        mSkipCallbackParser = pair.getSecond();
-        return pair.getFirst();
-    }
-
-    @Override
-    public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
-            View convertView, ViewGroup parent) {
-        // we don't care about recycling here because we never scroll.
-        AdapterItem parentItem = mItems.get(groupPosition);
-        AdapterItem item = getChildItem(groupPosition, childPosition);
-        Pair<View, Boolean> pair = AdapterHelper.getView(item, parentItem, parent, mCallback,
-                mAdapterRef, mSkipCallbackParser);
-        mSkipCallbackParser = pair.getSecond();
-        return pair.getFirst();
-    }
-
-    @Override
-    public long getGroupId(int groupPosition) {
-        return groupPosition;
-    }
-
-    @Override
-    public long getChildId(int groupPosition, int childPosition) {
-        return childPosition;
-    }
-
-    @Override
-    public long getCombinedGroupId(long groupId) {
-        return groupId << 16 | 0x0000FFFF;
-    }
-
-    @Override
-    public long getCombinedChildId(long groupId, long childId) {
-        return groupId << 16 | childId;
-    }
-
-    @Override
-    public boolean isChildSelectable(int groupPosition, int childPosition) {
-        return true;
-    }
-
-    @Override
-    public void onGroupCollapsed(int groupPosition) {
-        // pass
-    }
-
-    @Override
-    public void onGroupExpanded(int groupPosition) {
-        // pass
-    }
-
-    @Override
-    public void registerDataSetObserver(DataSetObserver observer) {
-        // pass
-    }
-
-    @Override
-    public void unregisterDataSetObserver(DataSetObserver observer) {
-        // pass
-    }
-
-    @Override
-    public boolean hasStableIds() {
-        return true;
-    }
-
-    @Override
-    public boolean areAllItemsEnabled() {
-        return true;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return mItems.isEmpty();
-    }
-
-    // ---- HeterogeneousExpandableList
-
-    @Override
-    public int getChildType(int groupPosition, int childPosition) {
-        return getChildItem(groupPosition, childPosition).getType();
-    }
-
-    @Override
-    public int getChildTypeCount() {
-        return mChildrenTypes.size();
-    }
-
-    @Override
-    public int getGroupType(int groupPosition) {
-        return mItems.get(groupPosition).getType();
-    }
-
-    @Override
-    public int getGroupTypeCount() {
-        return mGroupTypes.size();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/libcore/io/BridgeBufferIterator.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/libcore/io/BridgeBufferIterator.java
deleted file mode 100644
index 96cba78..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/libcore/io/BridgeBufferIterator.java
+++ /dev/null
@@ -1,81 +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.layoutlib.bridge.libcore.io;
-
-import java.nio.ByteBuffer;
-
-import libcore.io.BufferIterator;
-
-/**
- * Provides an implementation of {@link BufferIterator} over a {@link ByteBuffer}.
- */
-public class BridgeBufferIterator extends BufferIterator {
-
-    private final long mSize;
-    private final ByteBuffer mByteBuffer;
-
-    public BridgeBufferIterator(long size, ByteBuffer buffer) {
-        mSize = size;
-        mByteBuffer = buffer;
-    }
-
-    @Override
-    public void seek(int offset) {
-        assert offset <= mSize;
-        mByteBuffer.position(offset);
-    }
-
-    @Override
-    public int pos() {
-        return mByteBuffer.position();
-    }
-
-    @Override
-    public void skip(int byteCount) {
-        int newPosition = mByteBuffer.position() + byteCount;
-        assert newPosition <= mSize;
-        mByteBuffer.position(newPosition);
-    }
-
-    @Override
-    public void readByteArray(byte[] dst, int dstOffset, int byteCount) {
-        assert dst.length >= dstOffset + byteCount;
-        mByteBuffer.get(dst, dstOffset, byteCount);
-    }
-
-    @Override
-    public byte readByte() {
-        return mByteBuffer.get();
-    }
-
-    @Override
-    public int readInt() {
-        return mByteBuffer.getInt();
-    }
-
-    @Override
-    public void readIntArray(int[] dst, int dstOffset, int intCount) {
-        while (--intCount >= 0) {
-            dst[dstOffset++] = mByteBuffer.getInt();
-        }
-    }
-
-    @Override
-    public short readShort() {
-        return mByteBuffer.getShort();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/ShadowBuffer.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/ShadowBuffer.java
deleted file mode 100644
index ae33e1d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/ShadowBuffer.java
+++ /dev/null
@@ -1,181 +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.layoutlib.bridge.shadowutil;
-
-import android.annotation.NonNull;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Canvas;
-
-public class ShadowBuffer {
-
-    private int mWidth;
-    private int mHeight;
-    private Bitmap mBitmap;
-    private int[] mData;
-
-    public ShadowBuffer(int width, int height) {
-        mWidth = width;
-        mHeight = height;
-        mBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
-        mData = new int[mBitmap.getWidth() * mBitmap.getHeight()];
-        mBitmap.getPixels(mData, 0, mBitmap.getWidth(), 0, 0, mBitmap.getWidth(),
-                mBitmap.getHeight());
-    }
-
-    public void generateTriangles(@NonNull float[] strip, float scale) {
-        for (int i = 0; i < strip.length - 8; i += 3) {
-            float fx3 = strip[i];
-            float fy3 = strip[i + 1];
-            float fz3 = scale * strip[i + 2];
-
-            float fx2 = strip[i + 3];
-            float fy2 = strip[i + 4];
-            float fz2 = scale * strip[i + 5];
-
-            float fx1 = strip[i + 6];
-            float fy1 = strip[i + 7];
-            float fz1 = scale * strip[i + 8];
-
-            if (fx1 * (fy2 - fy3) + fx2 * (fy3 - fy1) + fx3 * (fy1 - fy2) == 0) {
-                continue;
-            }
-
-            triangleZBuffMin(mData, mWidth, mHeight, fx3, fy3, fz3, fx2, fy2, fz2, fx1, fy1, fz1);
-            triangleZBuffMin(mData, mWidth, mHeight, fx1, fy1, fz1, fx2, fy2, fz2, fx3, fy3, fz3);
-        }
-        mBitmap.setPixels(mData, 0, mBitmap.getWidth(), 0, 0, mBitmap.getWidth(),
-                mBitmap.getHeight());
-    }
-
-    private void triangleZBuffMin(@NonNull int[] buff, int w, int h, float fx3, float fy3,
-            float fz3, float fx2, float fy2, float fz2, float fx1, float fy1, float fz1) {
-        if (((fx1 - fx2) * (fy3 - fy2) - (fy1 - fy2) * (fx3 - fx2)) < 0) {
-            float tmpX = fx1;
-            float tmpY = fy1;
-            float tmpZ = fz1;
-            fx1 = fx2;
-            fy1 = fy2;
-            fz1 = fz2;
-            fx2 = tmpX;
-            fy2 = tmpY;
-            fz2 = tmpZ;
-        }
-        double d = (fx1 * (fy3 - fy2) - fx2 * fy3 + fx3 * fy2 + (fx2 - fx3) * fy1);
-
-        if (d == 0) {
-            return;
-        }
-        float dx = (float) (-(fy1 * (fz3 - fz2) - fy2 * fz3 + fy3 * fz2 + (fy2 - fy3) * fz1) / d);
-        float dy = (float) ((fx1 * (fz3 - fz2) - fx2 * fz3 + fx3 * fz2 + (fx2 - fx3) * fz1) / d);
-        float zOff = (float) ((fx1 * (fy3 * fz2 - fy2 * fz3) + fy1 * (fx2 * fz3 - fx3 * fz2) +
-                (fx3 * fy2 - fx2 * fy3) * fz1) / d);
-
-        int Y1 = (int) (16.0f * fy1 + .5f);
-        int Y2 = (int) (16.0f * fy2 + .5f);
-        int Y3 = (int) (16.0f * fy3 + .5f);
-
-        int X1 = (int) (16.0f * fx1 + .5f);
-        int X2 = (int) (16.0f * fx2 + .5f);
-        int X3 = (int) (16.0f * fx3 + .5f);
-
-        int DX12 = X1 - X2;
-        int DX23 = X2 - X3;
-        int DX31 = X3 - X1;
-
-        int DY12 = Y1 - Y2;
-        int DY23 = Y2 - Y3;
-        int DY31 = Y3 - Y1;
-
-        int FDX12 = DX12 << 4;
-        int FDX23 = DX23 << 4;
-        int FDX31 = DX31 << 4;
-
-        int FDY12 = DY12 << 4;
-        int FDY23 = DY23 << 4;
-        int FDY31 = DY31 << 4;
-
-        int minX = (min(X1, X2, X3) + 0xF) >> 4;
-        int maxX = (max(X1, X2, X3) + 0xF) >> 4;
-        int minY = (min(Y1, Y2, Y3) + 0xF) >> 4;
-        int maxY = (max(Y1, Y2, Y3) + 0xF) >> 4;
-
-        if (minY < 0) {
-            minY = 0;
-        }
-        if (minX < 0) {
-            minX = 0;
-        }
-        if (maxX > w) {
-            maxX = w;
-        }
-        if (maxY > h) {
-            maxY = h;
-        }
-        int off = minY * w;
-
-        int C1 = DY12 * X1 - DX12 * Y1;
-        int C2 = DY23 * X2 - DX23 * Y2;
-        int C3 = DY31 * X3 - DX31 * Y3;
-
-        if (DY12 < 0 || (DY12 == 0 && DX12 > 0)) {
-            C1++;
-        }
-        if (DY23 < 0 || (DY23 == 0 && DX23 > 0)) {
-            C2++;
-        }
-        if (DY31 < 0 || (DY31 == 0 && DX31 > 0)) {
-            C3++;
-        }
-        int CY1 = C1 + DX12 * (minY << 4) - DY12 * (minX << 4);
-        int CY2 = C2 + DX23 * (minY << 4) - DY23 * (minX << 4);
-        int CY3 = C3 + DX31 * (minY << 4) - DY31 * (minX << 4);
-
-        for (int y = minY; y < maxY; y++) {
-            int CX1 = CY1;
-            int CX2 = CY2;
-            int CX3 = CY3;
-            float p = zOff + dy * y;
-            for (int x = minX; x < maxX; x++) {
-                if (CX1 > 0 && CX2 > 0 && CX3 > 0) {
-                    int point = x + off;
-                    float zVal = p + dx * x;
-                    buff[point] |= ((int) (zVal * 255)) << 24;
-                }
-                CX1 -= FDY12;
-                CX2 -= FDY23;
-                CX3 -= FDY31;
-            }
-            CY1 += FDX12;
-            CY2 += FDX23;
-            CY3 += FDX31;
-            off += w;
-        }
-    }
-
-    private int min(int x1, int x2, int x3) {
-        return (x1 > x2) ? ((x2 > x3) ? x3 : x2) : ((x1 > x3) ? x3 : x1);
-    }
-
-    private int max(int x1, int x2, int x3) {
-        return (x1 < x2) ? ((x2 < x3) ? x3 : x2) : ((x1 < x3) ? x3 : x1);
-    }
-
-    public void draw(@NonNull Canvas c) {
-        c.drawBitmap(mBitmap, 0, 0, null);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/SpotShadow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/SpotShadow.java
deleted file mode 100644
index 33375ff..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/SpotShadow.java
+++ /dev/null
@@ -1,630 +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.layoutlib.bridge.shadowutil;
-
-import android.annotation.NonNull;
-
-public class SpotShadow {
-
-    private static float rayIntersectPoly(@NonNull float[] poly, int polyLength, float px, float py,
-            float dx, float dy) {
-        int p1 = polyLength - 1;
-        for (int p2 = 0; p2 < polyLength; p2++) {
-            float p1x = poly[p1 * 2 + 0];
-            float p1y = poly[p1 * 2 + 1];
-            float p2x = poly[p2 * 2 + 0];
-            float p2y = poly[p2 * 2 + 1];
-            float div = (dx * (p1y - p2y) + dy * p2x - dy * p1x);
-            if (div != 0) {
-                float t = (dx * (p1y - py) + dy * px - dy * p1x) / (div);
-                if (t >= 0 && t <= 1) {
-                    float t2 = (p1x * (py - p2y) + p2x * (p1y - py) + px * (p2y - p1y)) / div;
-                    if (t2 > 0) {
-                        return t2;
-                    }
-                }
-            }
-            p1 = p2;
-        }
-        return Float.NaN;
-    }
-
-    private static void centroid2d(@NonNull float[] poly, int len, @NonNull float[] ret) {
-        float sumX = 0;
-        float sumY = 0;
-        int p1 = len - 1;
-        float area = 0;
-        for (int p2 = 0; p2 < len; p2++) {
-            float x1 = poly[p1 * 2 + 0];
-            float y1 = poly[p1 * 2 + 1];
-            float x2 = poly[p2 * 2 + 0];
-            float y2 = poly[p2 * 2 + 1];
-            float a = (x1 * y2 - x2 * y1);
-            sumX += (x1 + x2) * a;
-            sumY += (y1 + y2) * a;
-            area += a;
-            p1 = p2;
-        }
-
-        float centroidX = sumX / (3 * area);
-        float centroidY = sumY / (3 * area);
-        ret[0] = centroidX;
-        ret[1] = centroidY;
-    }
-
-    /**
-     * calculates the Centroid of a 3d polygon
-     * @param poly The flatten 3d vertices coordinates of polygon, the format is like
-     * [x0, y0, z0, x1, y1, z1, x2, ...]
-     * @param len The number of polygon vertices. So the length of poly should be len * 3.
-     * @param ret The array used to sotre the result. The length should be 3.
-     */
-    private static void centroid3d(@NonNull float[] poly, int len, @NonNull float[] ret) {
-        int n = len - 1;
-        double area = 0;
-        double cx = 0, cy = 0, cz = 0;
-        for (int i = 1; i < n; i++) {
-            int k = i + 1;
-            float a0 = poly[i * 3 + 0] - poly[0 * 3 + 0];
-            float a1 = poly[i * 3 + 1] - poly[0 * 3 + 1];
-            float a2 = poly[i * 3 + 2] - poly[0 * 3 + 2];
-            float b0 = poly[k * 3 + 0] - poly[0 * 3 + 0];
-            float b1 = poly[k * 3 + 1] - poly[0 * 3 + 1];
-            float b2 = poly[k * 3 + 2] - poly[0 * 3 + 2];
-            float c0 = a1 * b2 - b1 * a2;
-            float c1 = a2 * b0 - b2 * a0;
-            float c2 = a0 * b1 - b0 * a1;
-            double areaOfTriangle = Math.sqrt(c0 * c0 + c1 * c1 + c2 * c2);
-            area += areaOfTriangle;
-            cx += areaOfTriangle * (poly[i * 3 + 0] + poly[k * 3 + 0] + poly[0 * 3 + 0]);
-            cy += areaOfTriangle * (poly[i * 3 + 1] + poly[k * 3 + 1] + poly[0 * 3 + 1]);
-            cz += areaOfTriangle * (poly[i * 3 + 2] + poly[k * 3 + 2] + poly[0 * 3 + 2]);
-        }
-        ret[0] = (float) (cx / (3 * area));
-        ret[1] = (float) (cy / (3 * area));
-        ret[2] = (float) (cz / (3 * area));
-    }
-
-    /**
-     * Extracts the convex hull of a polygon.
-     * @param points The vertices coordinates of polygon
-     * @param pointsLength The number of polygon vertices. So the length of poly should be len * 3.
-     * @param retPoly retPoly is at most the size of the input polygon
-     * @return The number of points in the retPolygon
-     */
-    private static int hull(@NonNull float[] points, int pointsLength, @NonNull float[] retPoly) {
-        quicksortX(points, 0, pointsLength - 1);
-        int n = pointsLength;
-        float[] lUpper = new float[n * 2];
-        lUpper[0] = points[0];
-        lUpper[1] = points[1];
-        lUpper[2] = points[2];
-        lUpper[3] = points[3];
-
-        int lUpperSize = 2;
-
-        for (int i = 2; i < n; i++) {
-            lUpper[lUpperSize * 2 + 0] = points[i * 2 + 0];
-            lUpper[lUpperSize * 2 + 1] = points[i * 2 + 1];
-            lUpperSize++;
-
-            while (lUpperSize > 2 &&
-                    !rightTurn(lUpper[(lUpperSize - 3) * 2], lUpper[(lUpperSize - 3) * 2 + 1],
-                            lUpper[(lUpperSize - 2) * 2], lUpper[(lUpperSize - 2) * 2 + 1],
-                            lUpper[(lUpperSize - 1) * 2], lUpper[(lUpperSize - 1) * 2 + 1])) {
-                // Remove the middle point of the three last
-                lUpper[(lUpperSize - 2) * 2 + 0] = lUpper[(lUpperSize - 1) * 2 + 0];
-                lUpper[(lUpperSize - 2) * 2 + 1] = lUpper[(lUpperSize - 1) * 2 + 1];
-                lUpperSize--;
-            }
-        }
-
-        float[] lLower = new float[n * 2];
-        lLower[0] = points[(n - 1) * 2 + 0];
-        lLower[1] = points[(n - 1) * 2 + 1];
-        lLower[2] = points[(n - 2) * 2 + 0];
-        lLower[3] = points[(n - 2) * 2 + 1];
-
-        int lLowerSize = 2;
-
-        for (int i = n - 3; i >= 0; i--) {
-            lLower[lLowerSize * 2 + 0] = points[i * 2 + 0];
-            lLower[lLowerSize * 2 + 1] = points[i * 2 + 1];
-            lLowerSize++;
-
-            while (lLowerSize > 2 &&
-                    !rightTurn(lLower[(lLowerSize - 3) * 2], lLower[(lLowerSize - 3) * 2 + 1],
-                            lLower[(lLowerSize - 2) * 2], lLower[(lLowerSize - 2) * 2 + 1],
-                            lLower[(lLowerSize - 1) * 2], lLower[(lLowerSize - 1) * 2 + 1])) {
-                // Remove the middle point of the three last
-                lLower[(lLowerSize - 2) * 2 + 0] = lLower[(lLowerSize - 1) * 2 + 0];
-                lLower[(lLowerSize - 2) * 2 + 1] = lLower[(lLowerSize - 1) * 2 + 1];
-                lLowerSize--;
-            }
-        }
-
-        int count = 0;
-        for (int i = 0; i < lUpperSize; i++) {
-            retPoly[count * 2 + 0] = lUpper[i * 2 + 0];
-            retPoly[count * 2 + 1] = lUpper[i * 2 + 1];
-            count++;
-        }
-        for (int i = 1; i < lLowerSize - 1; i++) {
-            retPoly[count * 2 + 0] = lLower[i * 2 + 0];
-            retPoly[count * 2 + 1] = lLower[i * 2 + 1];
-            count++;
-        }
-        return count;
-    }
-
-    private static boolean rightTurn(float ax, float ay, float bx, float by, float cx, float cy) {
-        return (bx - ax) * (cy - ay) - (by - ay) * (cx - ax) > 0.00001;
-    }
-
-    /**
-     * calculates the intersection of poly1 with poly2 and put in poly2
-     * @param poly1 The flatten 2d coordinates of polygon
-     * @param poly1length The vertices number of poly1
-     * @param poly2 The flatten 2d coordinates of polygon
-     * @param poly2length The vertices number of poly2
-     * @return number of vertices in poly2
-     */
-    private static int intersection(@NonNull float[] poly1, int poly1length, @NonNull float[] poly2,
-            int poly2length) {
-        makeClockwise(poly1, poly1length);
-        makeClockwise(poly2, poly2length);
-        float[] poly = new float[(poly1length * poly2length + 2) * 2];
-        int count = 0;
-        int pCount = 0;
-        for (int i = 0; i < poly1length; i++) {
-            if (pointInsidePolygon(poly1[i * 2 + 0], poly1[i * 2 + 1], poly2, poly2length)) {
-                poly[count * 2 + 0] = poly1[i * 2 + 0];
-                poly[count * 2 + 1] = poly1[i * 2 + 1];
-                count++;
-                pCount++;
-            }
-        }
-        int fromP1 = pCount;
-        for (int i = 0; i < poly2length; i++) {
-            if (pointInsidePolygon(poly2[i * 2 + 0], poly2[i * 2 + 1], poly1, poly1length)) {
-                poly[count * 2 + 0] = poly2[i * 2 + 0];
-                poly[count * 2 + 1] = poly2[i * 2 + 1];
-                count++;
-            }
-        }
-        int fromP2 = count - fromP1;
-        if (fromP1 == poly1length) { // use p1
-            for (int i = 0; i < poly1length; i++) {
-                poly2[i * 2 + 0] = poly1[i * 2 + 0];
-                poly2[i * 2 + 1] = poly1[i * 2 + 1];
-            }
-            return poly1length;
-        }
-        if (fromP2 == poly2length) { // use p2
-            return poly2length;
-        }
-        float[] intersection = new float[2];
-        for (int i = 0; i < poly2length; i++) {
-            for (int j = 0; j < poly1length; j++) {
-                int i1_by_2 = i * 2;
-                int i2_by_2 = ((i + 1) % poly2length) * 2;
-                int j1_by_2 = j * 2;
-                int j2_by_2 = ((j + 1) % poly1length) * 2;
-                boolean found =
-                        lineIntersection(poly2[i1_by_2 + 0], poly2[i1_by_2 + 1], poly2[i2_by_2 + 0],
-                                poly2[i2_by_2 + 1], poly1[j1_by_2 + 0], poly1[j1_by_2 + 1],
-                                poly1[j2_by_2 + 0], poly1[j2_by_2 + 1], intersection);
-                if (found) {
-                    poly[count * 2 + 0] = intersection[0];
-                    poly[count * 2 + 1] = intersection[1];
-                    count++;
-                } else {
-                    float dx = poly2[i * 2 + 0] - poly1[j * 2 + 0];
-                    float dy = poly2[i * 2 + 1] - poly1[j * 2 + 1];
-
-                    if (dx * dx + dy * dy < 0.01) {
-                        poly[count * 2 + 0] = poly2[i * 2 + 0];
-                        poly[count * 2 + 1] = poly2[i * 2 + 1];
-                        count++;
-                    }
-                }
-            }
-        }
-        if (count == 0) {
-            return 0;
-        }
-        float avgX = 0;
-        float avgY = 0;
-        for (int i = 0; i < count; i++) {
-            avgX += poly[i * 2 + 0];
-            avgY += poly[i * 2 + 1];
-        }
-        avgX /= count;
-        avgY /= count;
-
-        float[] ctr = new float[]{avgX, avgY};
-        sort(poly, count, ctr);
-        int size = count;
-
-        poly2[0] = poly[0];
-        poly2[1] = poly[1];
-
-        count = 1;
-        for (int i = 1; i < size; i++) {
-            float dx = poly[i * 2 + 0] - poly[(i - 1) * 2 + 0];
-            float dy = poly[i * 2 + 1] - poly[(i - 1) * 2 + 1];
-            if (dx * dx + dy * dy >= 0.01) {
-                poly2[count * 2 + 0] = poly[i * 2 + 0];
-                poly2[count * 2 + 1] = poly[i * 2 + 1];
-                count++;
-            }
-        }
-        return count;
-    }
-
-    public static void sort(@NonNull float[] poly, int polyLength, @NonNull float[] ctr) {
-        quicksortCircle(poly, 0, polyLength - 1, ctr);
-    }
-
-    public static float angle(float x1, float y1, @NonNull float[] ctr) {
-        return -(float) Math.atan2(x1 - ctr[0], y1 - ctr[1]);
-    }
-
-    private static void swapPair(@NonNull float[] points, int i, int j) {
-        float x = points[i * 2 + 0];
-        float y = points[i * 2 + 1];
-        points[i * 2 + 0] = points[j * 2 + 0];
-        points[i * 2 + 1] = points[j * 2 + 1];
-        points[j * 2 + 0] = x;
-        points[j * 2 + 1] = y;
-    }
-
-    private static void quicksortCircle(@NonNull float[] points, int low, int high,
-            @NonNull float[] ctr) {
-        int i = low, j = high;
-        int p = low + (high - low) / 2;
-        float pivot = angle(points[p * 2], points[p * 2 + 1], ctr);
-        while (i <= j) {
-            while (angle(points[i * 2 + 0], points[i * 2 + 1], ctr) < pivot) {
-                i++;
-            }
-            while (angle(points[j * 2 + 0], points[j * 2 + 1], ctr) > pivot) {
-                j--;
-            }
-            if (i <= j) {
-                swapPair(points, i, j);
-                i++;
-                j--;
-            }
-        }
-        if (low < j) {
-            quicksortCircle(points, low, j, ctr);
-        }
-        if (i < high) {
-            quicksortCircle(points, i, high, ctr);
-        }
-    }
-
-    /**
-     * This function do Quick Sort by comparing X axis only.<br>
-     * Note that the input values of points are paired coordinates, e.g. {@code [x0, y0, x1, y1, x2,
-     * y2, ...]).}
-     * @param points The input point pairs. Every {@code (2 * i, 2 * i + 1)} points are pairs.
-     * @param low lowest index used to do quick sort sort
-     * @param high highest index used to do quick sort
-     */
-    private static void quicksortX(@NonNull float[] points, int low, int high) {
-        int i = low, j = high;
-        int p = low + (high - low) / 2;
-        float pivot = points[p * 2];
-        while (i <= j) {
-            while (points[i * 2 + 0] < pivot) {
-                i++;
-            }
-            while (points[j * 2 + 0] > pivot) {
-                j--;
-            }
-
-            if (i <= j) {
-                swapPair(points, i, j);
-                i++;
-                j--;
-            }
-        }
-        if (low < j) {
-            quicksortX(points, low, j);
-        }
-        if (i < high) {
-            quicksortX(points, i, high);
-        }
-    }
-
-    private static boolean pointInsidePolygon(float x, float y, @NonNull float[] poly, int len) {
-        boolean c = false;
-        float testX = x;
-        float testY = y;
-        for (int i = 0, j = len - 1; i < len; j = i++) {
-            if (((poly[i * 2 + 1] > testY) != (poly[j * 2 + 1] > testY)) && (testX <
-                    (poly[j * 2 + 0] - poly[i * 2 + 0]) * (testY - poly[i * 2 + 1]) /
-                            (poly[j * 2 + 1] - poly[i * 2 + 1]) + poly[i * 2 + 0])) {
-                c = !c;
-            }
-        }
-        return c;
-    }
-
-    private static void makeClockwise(@NonNull float[] polygon, int len) {
-        if (polygon == null || len == 0) {
-            return;
-        }
-        if (!isClockwise(polygon, len)) {
-            reverse(polygon, len);
-        }
-    }
-
-    private static boolean isClockwise(@NonNull float[] polygon, int len) {
-        float sum = 0;
-        float p1x = polygon[(len - 1) * 2 + 0];
-        float p1y = polygon[(len - 1) * 2 + 1];
-        for (int i = 0; i < len; i++) {
-            float p2x = polygon[i * 2 + 0];
-            float p2y = polygon[i * 2 + 1];
-            sum += p1x * p2y - p2x * p1y;
-            p1x = p2x;
-            p1y = p2y;
-        }
-        return sum < 0;
-    }
-
-    private static void reverse(@NonNull float[] polygon, int len) {
-        int n = len / 2;
-        for (int i = 0; i < n; i++) {
-            float tmp0 = polygon[i * 2 + 0];
-            float tmp1 = polygon[i * 2 + 1];
-            int k = len - 1 - i;
-            polygon[i * 2 + 0] = polygon[k * 2 + 0];
-            polygon[i * 2 + 1] = polygon[k * 2 + 1];
-            polygon[k * 2 + 0] = tmp0;
-            polygon[k * 2 + 1] = tmp1;
-        }
-    }
-
-    /**
-     * Intersects two lines in parametric form.
-     */
-    private static final boolean lineIntersection(float x1, float y1, float x2, float y2, float x3,
-            float y3, float x4, float y4, @NonNull float[] ret) {
-        float d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
-        if (d == 0.000f) {
-            return false;
-        }
-
-        float dx = (x1 * y2 - y1 * x2);
-        float dy = (x3 * y4 - y3 * x4);
-        float x = (dx * (x3 - x4) - (x1 - x2) * dy) / d;
-        float y = (dx * (y3 - y4) - (y1 - y2) * dy) / d;
-
-        if (((x - x1) * (x - x2) > 0.0000001) || ((x - x3) * (x - x4) > 0.0000001) ||
-                ((y - y1) * (y - y2) > 0.0000001) || ((y - y3) * (y - y4) > 0.0000001)) {
-            return false;
-        }
-        ret[0] = x;
-        ret[1] = y;
-        return true;
-    }
-
-    @NonNull
-    public static float[] calculateLight(float size, int points, float x, float y, float height) {
-        float[] ret = new float[points * 3];
-        for (int i = 0; i < points; i++) {
-            double angle = 2 * i * Math.PI / points;
-            ret[i * 3 + 0] = (float) Math.cos(angle) * size + x;
-            ret[i * 3 + 1] = (float) Math.sin(angle) * size + y;
-            ret[i * 3 + 2] = (height);
-        }
-        return ret;
-    }
-
-    /**
-     layers indicates the number of circular strips to generate.
-     Strength is how dark a shadow to generate.
-
-    /**
-     * This calculates a collection of triangles that represent the shadow cast by a polygonal
-     * light source (lightPoly) hitting a convex polygon (poly).
-     * @param lightPoly The flatten 3d coordinates of light
-     * @param lightPolyLength The vertices number of light polygon.
-     * @param poly The flatten 3d coordinates of item
-     * @param polyLength The vertices number of light polygon.
-     * @param rays defines the number of points around the perimeter of the shadow to generate
-     * @param layers The number of shadow's fading.
-     * @param strength The factor of the black color of shadow.
-     * @param retStrips Used to store the calculated shadow strength
-     * @return true if the params is able to calculate a shadow, else false.
-     */
-    public static boolean calcShadow(@NonNull float[] lightPoly, int lightPolyLength,
-            @NonNull float[] poly, int polyLength, int rays, int layers, float strength,
-            @NonNull float[] retStrips) {
-        float[] shadowRegion = new float[lightPolyLength * polyLength * 2];
-        float[] outline = new float[polyLength * 2];
-        float[] umbra = new float[polyLength * lightPolyLength * 2];
-        int umbraLength = 0;
-
-        int k = 0;
-        for (int j = 0; j < lightPolyLength; j++) {
-            int m = 0;
-            for (int i = 0; i < polyLength; i++) {
-                float t = lightPoly[j * 3 + 2] - poly[i * 3 + 2];
-                if (t == 0) {
-                    return false;
-                }
-                t = lightPoly[j * 3 + 2] / t;
-                float x = lightPoly[j * 3 + 0] - t * (lightPoly[j * 3 + 0] - poly[i * 3 + 0]);
-                float y = lightPoly[j * 3 + 1] - t * (lightPoly[j * 3 + 1] - poly[i * 3 + 1]);
-
-                shadowRegion[k * 2 + 0] = x;
-                shadowRegion[k * 2 + 1] = y;
-                outline[m * 2 + 0] = x;
-                outline[m * 2 + 1] = y;
-
-                k++;
-                m++;
-            }
-            if (umbraLength == 0) {
-                System.arraycopy(outline, 0, umbra, 0, polyLength);
-                umbraLength = polyLength;
-            } else {
-                umbraLength = intersection(outline, polyLength, umbra, umbraLength);
-                if (umbraLength == 0) {
-                    break;
-                }
-            }
-        }
-        int shadowRegionLength = k;
-
-        float[] penumbra = new float[k * 2];
-        int penumbraLength = hull(shadowRegion, shadowRegionLength, penumbra);
-        if (umbraLength < 3) {// no real umbra make a fake one
-            float[] p = new float[3];
-            centroid3d(lightPoly, lightPolyLength, p);
-            float[] centShadow = new float[polyLength * 2];
-            for (int i = 0; i < polyLength; i++) {
-                float t = p[2] - poly[i * 3 + 2];
-                if (t == 0) {
-                    return false;
-                }
-                t = p[2] / t;
-                float x = p[0] - t * (p[0] - poly[i * 3 + 0]);
-                float y = p[1] - t * (p[1] - poly[i * 3 + 1]);
-
-                centShadow[i * 2 + 0] = x;
-                centShadow[i * 2 + 1] = y;
-            }
-            float[] c = new float[2];
-            centroid2d(centShadow, polyLength, c);
-            for (int i = 0; i < polyLength; i++) {
-                centShadow[i * 2 + 0] = (c[0] * 9 + centShadow[i * 2 + 0]) / 10;
-                centShadow[i * 2 + 1] = (c[1] * 9 + centShadow[i * 2 + 1]) / 10;
-            }
-            umbra = centShadow; // fake umbra
-            umbraLength = polyLength; // same size as the original polygon
-        }
-
-        triangulateConcentricPolygon(penumbra, penumbraLength, umbra, umbraLength, rays, layers,
-                strength, retStrips);
-        return true;
-    }
-
-    /**
-     * triangulate concentric circles.
-     * This takes the inner and outer polygons of the umbra and penumbra and triangulates it.
-     * @param penumbra The 2d flatten vertices of penumbra polygons.
-     * @param penumbraLength The number of vertices in penumbra.
-     * @param umbra The 2d flatten vertices of umbra polygons.
-     * @param umbraLength The number of vertices in umbra.
-     * @param rays defines the number of points around the perimeter of the shadow to generate
-     * @param layers The number of shadow's fading.
-     * @param strength The factor of the black color of shadow.
-     * @param retStrips Used to store the calculated shadow strength.
-     */
-    private static void triangulateConcentricPolygon(@NonNull float[] penumbra, int penumbraLength,
-            @NonNull float[] umbra, int umbraLength, int rays, int layers, float strength,
-            @NonNull float[] retStrips) {
-        int rings = layers + 1;
-        double step = Math.PI * 2 / rays;
-        float[] retXY = new float[2];
-        centroid2d(umbra, umbraLength, retXY);
-        float cx = retXY[0];
-        float cy = retXY[1];
-
-        float[] t1 = new float[rays];
-        float[] t2 = new float[rays];
-
-        for (int i = 0; i < rays; i++) {
-            float dx = (float) Math.cos(Math.PI / 4 + step * i);
-            float dy = (float) Math.sin(Math.PI / 4 + step * i);
-            t2[i] = rayIntersectPoly(umbra, umbraLength, cx, cy, dx, dy);
-            t1[i] = rayIntersectPoly(penumbra, penumbraLength, cx, cy, dx, dy);
-        }
-
-        int p = 0;
-        // Calculate the vertex
-        for (int r = 0; r < layers; r++) {
-            int startP = p;
-            for (int i = 0; i < rays; i++) {
-                float dx = (float) Math.cos(Math.PI / 4 + step * i);
-                float dy = (float) Math.sin(Math.PI / 4 + step * i);
-
-                for (int j = r; j < (r + 2); j++) {
-                    float jf = j / (float) (rings - 1);
-                    float t = t1[i] + jf * (t2[i] - t1[i]);
-                    float op = (jf + 1 - 1 / (1 + (t - t1[i]) * (t - t1[i]))) / 2;
-                    retStrips[p * 3 + 0] = dx * t + cx;
-                    retStrips[p * 3 + 1] = dy * t + cy;
-                    retStrips[p * 3 + 2] = jf * op * strength;
-                    p++;
-
-                }
-            }
-            retStrips[p * 3 + 0] = retStrips[startP * 3 + 0];
-            retStrips[p * 3 + 1] = retStrips[startP * 3 + 1];
-            retStrips[p * 3 + 2] = retStrips[startP * 3 + 2];
-            p++;
-            startP++;
-            retStrips[p * 3 + 0] = retStrips[startP * 3 + 0];
-            retStrips[p * 3 + 1] = retStrips[startP * 3 + 1];
-            retStrips[p * 3 + 2] = retStrips[startP * 3 + 2];
-            p++;
-        }
-        int oldP = p - 1;
-        retStrips[p * 3 + 0] = retStrips[oldP * 3 + 0];
-        retStrips[p * 3 + 1] = retStrips[oldP * 3 + 1];
-        retStrips[p * 3 + 2] = retStrips[oldP * 3 + 2];
-        p++;
-
-        // Skip the first point here, then make it same as last point later.
-        oldP = p;
-        p++;
-        for (int k = 0; k < rays; k++) {
-            int i = k / 2;
-            if ((k & 1) == 1) { // traverse the inside in a zig zag pattern
-                // for strips
-                i = rays - i - 1;
-            }
-            float dx = (float) Math.cos(Math.PI / 4 + step * i);
-            float dy = (float) Math.sin(Math.PI / 4 + step * i);
-
-            float jf = 1;
-
-            float t = t1[i] + jf * (t2[i] - t1[i]);
-            float op = (jf + 1 - 1 / (1 + (t - t1[i]) * (t - t1[i]))) / 2;
-
-            retStrips[p * 3 + 0] = dx * t + cx;
-            retStrips[p * 3 + 1] = dy * t + cy;
-            retStrips[p * 3 + 2] = jf * op * strength;
-            p++;
-        }
-        p = oldP;
-        retStrips[p * 3 + 0] = retStrips[oldP * 3 + 0];
-        retStrips[p * 3 + 1] = retStrips[oldP * 3 + 1];
-        retStrips[p * 3 + 2] = retStrips[oldP * 3 + 2];
-    }
-
-    public static int getStripSize(int rays, int layers) {
-        return (2 + rays + ((layers) * 2 * (rays + 1)));
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/CachedPathIteratorFactory.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/CachedPathIteratorFactory.java
deleted file mode 100644
index 0a9b9ec..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/CachedPathIteratorFactory.java
+++ /dev/null
@@ -1,485 +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.layoutlib.bridge.util;
-
-import android.annotation.NonNull;
-
-import java.awt.geom.CubicCurve2D;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-import java.awt.geom.QuadCurve2D;
-import java.util.ArrayList;
-
-import com.google.android.collect.Lists;
-
-/**
- * Class that returns iterators for a given path. These iterators are lightweight and can be reused
- * multiple times to iterate over the path.
- */
-public class CachedPathIteratorFactory {
-    /*
-     * A few conventions used in the code:
-     * Coordinates or coords arrays store segment coordinates. They use the same format as
-     * PathIterator#currentSegment coordinates array.
-     * float arrays store always points where the first element is X and the second is Y.
-     */
-
-    // This governs how accurate the approximation of the Path is.
-    private static final float PRECISION = 0.002f;
-
-    private final int mWindingRule;
-    private final int[] mTypes;
-    private final float[][] mCoordinates;
-    private final float[] mSegmentsLength;
-    private final float mTotalLength;
-
-    public CachedPathIteratorFactory(@NonNull PathIterator iterator) {
-        mWindingRule = iterator.getWindingRule();
-
-        ArrayList<Integer> typesArray = Lists.newArrayList();
-        ArrayList<float[]> pointsArray = Lists.newArrayList();
-        float[] points = new float[6];
-        while (!iterator.isDone()) {
-            int type = iterator.currentSegment(points);
-            int nPoints = getNumberOfPoints(type) * 2; // 2 coordinates per point
-
-            typesArray.add(type);
-            float[] itemPoints = new float[nPoints];
-            System.arraycopy(points, 0, itemPoints, 0, nPoints);
-            pointsArray.add(itemPoints);
-            iterator.next();
-        }
-
-        mTypes = new int[typesArray.size()];
-        mCoordinates = new float[mTypes.length][];
-        for (int i = 0; i < typesArray.size(); i++) {
-            mTypes[i] = typesArray.get(i);
-            mCoordinates[i] = pointsArray.get(i);
-        }
-
-        // Do measurement
-        mSegmentsLength = new float[mTypes.length];
-
-        // Curves that we can reuse to estimate segments length
-        CubicCurve2D.Float cubicCurve = new CubicCurve2D.Float();
-        QuadCurve2D.Float quadCurve = new QuadCurve2D.Float();
-        float lastX = 0;
-        float lastY = 0;
-        float totalLength = 0;
-        for (int i = 0; i < mTypes.length; i++) {
-            switch (mTypes[i]) {
-                case PathIterator.SEG_CUBICTO:
-                    cubicCurve.setCurve(lastX, lastY,
-                            mCoordinates[i][0], mCoordinates[i][1], mCoordinates[i][2],
-                            mCoordinates[i][3], lastX = mCoordinates[i][4],
-                            lastY = mCoordinates[i][5]);
-                    mSegmentsLength[i] =
-                            getFlatPathLength(cubicCurve.getPathIterator(null, PRECISION));
-                    break;
-                case PathIterator.SEG_QUADTO:
-                    quadCurve.setCurve(lastX, lastY, mCoordinates[i][0], mCoordinates[i][1],
-                            lastX = mCoordinates[i][2], lastY = mCoordinates[i][3]);
-                    mSegmentsLength[i] =
-                            getFlatPathLength(quadCurve.getPathIterator(null, PRECISION));
-                    break;
-                case PathIterator.SEG_CLOSE:
-                    mSegmentsLength[i] = (float) Point2D.distance(lastX, lastY,
-                            lastX = mCoordinates[0][0],
-                            lastY = mCoordinates[0][1]);
-                    mCoordinates[i] = new float[2];
-                    // We convert a SEG_CLOSE segment to a SEG_LINETO so we do not have to worry
-                    // about this special case in the rest of the code.
-                    mTypes[i] = PathIterator.SEG_LINETO;
-                    mCoordinates[i][0] = mCoordinates[0][0];
-                    mCoordinates[i][1] = mCoordinates[0][1];
-                    break;
-                case PathIterator.SEG_MOVETO:
-                    mSegmentsLength[i] = 0;
-                    lastX = mCoordinates[i][0];
-                    lastY = mCoordinates[i][1];
-                    break;
-                case PathIterator.SEG_LINETO:
-                    mSegmentsLength[i] = (float) Point2D.distance(lastX, lastY, mCoordinates[i][0],
-                            mCoordinates[i][1]);
-                    lastX = mCoordinates[i][0];
-                    lastY = mCoordinates[i][1];
-                default:
-            }
-            totalLength += mSegmentsLength[i];
-        }
-
-        mTotalLength = totalLength;
-    }
-
-    private static void quadCurveSegment(float[] coords, float t0, float t1) {
-        // Calculate X and Y at 0.5 (We'll use this to reconstruct the control point later)
-        float mt = t0 + (t1 - t0) / 2;
-        float mu = 1 - mt;
-        float mx = mu * mu * coords[0] + 2 * mu * mt * coords[2] + mt * mt * coords[4];
-        float my = mu * mu * coords[1] + 2 * mu * mt * coords[3] + mt * mt * coords[5];
-
-        float u0 = 1 - t0;
-        float u1 = 1 - t1;
-
-        // coords at t0
-        coords[0] = coords[0] * u0 * u0 + coords[2] * 2 * t0 * u0 + coords[4] * t0 * t0;
-        coords[1] = coords[1] * u0 * u0 + coords[3] * 2 * t0 * u0 + coords[5] * t0 * t0;
-
-        // coords at t1
-        coords[4] = coords[0] * u1 * u1 + coords[2] * 2 * t1 * u1 + coords[4] * t1 * t1;
-        coords[5] = coords[1] * u1 * u1 + coords[3] * 2 * t1 * u1 + coords[5] * t1 * t1;
-
-        // estimated control point at t'=0.5
-        coords[2] = 2 * mx - coords[0] / 2 - coords[4] / 2;
-        coords[3] = 2 * my - coords[1] / 2 - coords[5] / 2;
-    }
-
-    private static void cubicCurveSegment(float[] coords, float t0, float t1) {
-        // http://stackoverflow.com/questions/11703283/cubic-bezier-curve-segment
-        float u0 = 1 - t0;
-        float u1 = 1 - t1;
-
-        // Calculate the points at t0 and t1 for the quadratic curves formed by (P0, P1, P2) and
-        // (P1, P2, P3)
-        float qxa = coords[0] * u0 * u0 + coords[2] * 2 * t0 * u0 + coords[4] * t0 * t0;
-        float qxb = coords[0] * u1 * u1 + coords[2] * 2 * t1 * u1 + coords[4] * t1 * t1;
-        float qxc = coords[2] * u0 * u0 + coords[4] * 2 * t0 * u0 + coords[6] * t0 * t0;
-        float qxd = coords[2] * u1 * u1 + coords[4] * 2 * t1 * u1 + coords[6] * t1 * t1;
-
-        float qya = coords[1] * u0 * u0 + coords[3] * 2 * t0 * u0 + coords[5] * t0 * t0;
-        float qyb = coords[1] * u1 * u1 + coords[3] * 2 * t1 * u1 + coords[5] * t1 * t1;
-        float qyc = coords[3] * u0 * u0 + coords[5] * 2 * t0 * u0 + coords[7] * t0 * t0;
-        float qyd = coords[3] * u1 * u1 + coords[5] * 2 * t1 * u1 + coords[7] * t1 * t1;
-
-        // Linear interpolation
-        coords[0] = qxa * u0 + qxc * t0;
-        coords[1] = qya * u0 + qyc * t0;
-
-        coords[2] = qxa * u1 + qxc * t1;
-        coords[3] = qya * u1 + qyc * t1;
-
-        coords[4] = qxb * u0 + qxd * t0;
-        coords[5] = qyb * u0 + qyd * t0;
-
-        coords[6] = qxb * u1 + qxd * t1;
-        coords[7] = qyb * u1 + qyd * t1;
-    }
-
-    /**
-     * Returns the end point of a given segment
-     *
-     * @param type the segment type
-     * @param coords the segment coordinates array
-     * @param point the return array where the point will be stored
-     */
-    private static void getShapeEndPoint(int type, @NonNull float[] coords, @NonNull float[]
-            point) {
-        // start index of the end point for the segment type
-        int pointIndex = (getNumberOfPoints(type) - 1) * 2;
-        point[0] = coords[pointIndex];
-        point[1] = coords[pointIndex + 1];
-    }
-
-    /**
-     * Returns the number of points stored in a coordinates array for the given segment type.
-     */
-    private static int getNumberOfPoints(int segmentType) {
-        switch (segmentType) {
-            case PathIterator.SEG_QUADTO:
-                return 2;
-            case PathIterator.SEG_CUBICTO:
-                return 3;
-            case PathIterator.SEG_CLOSE:
-                return 0;
-            default:
-                return 1;
-        }
-    }
-
-    /**
-     * Returns the estimated length of a flat path. If the passed path is not flat (i.e. contains a
-     * segment that is not {@link PathIterator#SEG_CLOSE}, {@link PathIterator#SEG_MOVETO} or {@link
-     * PathIterator#SEG_LINETO} this method will fail.
-     */
-    private static float getFlatPathLength(@NonNull PathIterator iterator) {
-        float segment[] = new float[6];
-        float totalLength = 0;
-        float[] previousPoint = new float[2];
-        boolean isFirstPoint = true;
-
-        while (!iterator.isDone()) {
-            int type = iterator.currentSegment(segment);
-            assert type == PathIterator.SEG_LINETO || type == PathIterator.SEG_CLOSE || type ==
-                    PathIterator.SEG_MOVETO;
-
-            // MoveTo shouldn't affect the length
-            if (!isFirstPoint && type != PathIterator.SEG_MOVETO) {
-                totalLength += Point2D.distance(previousPoint[0], previousPoint[1], segment[0],
-                        segment[1]);
-            } else {
-                isFirstPoint = false;
-            }
-            previousPoint[0] = segment[0];
-            previousPoint[1] = segment[1];
-            iterator.next();
-        }
-
-        return totalLength;
-    }
-
-    /**
-     * Returns the estimated position along a path of the given length.
-     */
-    private void getPointAtLength(int type, @NonNull float[] coords, float lastX, float
-            lastY, float t, @NonNull float[] point) {
-        if (type == PathIterator.SEG_LINETO) {
-            point[0] = lastX + (coords[0] - lastX) * t;
-            point[1] = lastY + (coords[1] - lastY) * t;
-            // Return here, since we do not need a shape to estimate
-            return;
-        }
-
-        float[] curve = new float[8];
-        int lastPointIndex = (getNumberOfPoints(type) - 1) * 2;
-
-        System.arraycopy(coords, 0, curve, 2, coords.length);
-        curve[0] = lastX;
-        curve[1] = lastY;
-        if (type == PathIterator.SEG_CUBICTO) {
-            cubicCurveSegment(curve, 0f, t);
-        } else {
-            quadCurveSegment(curve, 0f, t);
-        }
-
-        point[0] = curve[2 + lastPointIndex];
-        point[1] = curve[2 + lastPointIndex + 1];
-    }
-
-    public CachedPathIterator iterator() {
-        return new CachedPathIterator();
-    }
-
-    /**
-     * Class that allows us to iterate over a path multiple times
-     */
-    public class CachedPathIterator implements PathIterator {
-        private int mNextIndex;
-
-        /**
-         * Current segment type.
-         *
-         * @see PathIterator
-         */
-        private int mCurrentType;
-
-        /**
-         * Stores the coordinates array of the current segment. The number of points stored depends
-         * on the segment type.
-         *
-         * @see PathIterator
-         */
-        private float[] mCurrentCoords = new float[6];
-        private float mCurrentSegmentLength;
-
-        /**
-         * Current segment length offset. When asking for the length of the current segment, the
-         * length will be reduced by this amount. This is useful when we are only using portions of
-         * the segment.
-         *
-         * @see #jumpToSegment(float)
-         */
-        private float mOffsetLength;
-
-        /** Point where the current segment started */
-        private float[] mLastPoint = new float[2];
-        private boolean isIteratorDone;
-
-        private CachedPathIterator() {
-            next();
-        }
-
-        public float getCurrentSegmentLength() {
-            return mCurrentSegmentLength;
-        }
-
-        @Override
-        public int getWindingRule() {
-            return mWindingRule;
-        }
-
-        @Override
-        public boolean isDone() {
-            return isIteratorDone;
-        }
-
-        @Override
-        public void next() {
-            if (mNextIndex >= mTypes.length) {
-                isIteratorDone = true;
-                return;
-            }
-
-            if (mNextIndex >= 1) {
-                // We've already called next() once so there is a previous segment in this path.
-                // We want to get the coordinates where the path ends.
-                getShapeEndPoint(mCurrentType, mCurrentCoords, mLastPoint);
-            } else {
-                // This is the first segment, no previous point so initialize to 0, 0
-                mLastPoint[0] = mLastPoint[1] = 0f;
-            }
-            mCurrentType = mTypes[mNextIndex];
-            mCurrentSegmentLength = mSegmentsLength[mNextIndex] - mOffsetLength;
-
-            if (mOffsetLength > 0f && (mCurrentType == SEG_CUBICTO || mCurrentType == SEG_QUADTO)) {
-                // We need to skip part of the start of the current segment (because
-                // mOffsetLength > 0)
-                float[] points = new float[8];
-
-                if (mNextIndex < 1) {
-                    points[0] = points[1] = 0f;
-                } else {
-                    getShapeEndPoint(mTypes[mNextIndex - 1], mCoordinates[mNextIndex - 1], points);
-                }
-
-                System.arraycopy(mCoordinates[mNextIndex], 0, points, 2,
-                        mCoordinates[mNextIndex].length);
-                float t0 = (mSegmentsLength[mNextIndex] - mCurrentSegmentLength) /
-                        mSegmentsLength[mNextIndex];
-                if (mCurrentType == SEG_CUBICTO) {
-                    cubicCurveSegment(points, t0, 1f);
-                } else {
-                    quadCurveSegment(points, t0, 1f);
-                }
-                System.arraycopy(points, 2, mCurrentCoords, 0, mCoordinates[mNextIndex].length);
-            } else {
-                System.arraycopy(mCoordinates[mNextIndex], 0, mCurrentCoords, 0,
-                        mCoordinates[mNextIndex].length);
-            }
-
-            mOffsetLength = 0f;
-            mNextIndex++;
-        }
-
-        @Override
-        public int currentSegment(float[] coords) {
-            System.arraycopy(mCurrentCoords, 0, coords, 0, getNumberOfPoints(mCurrentType) * 2);
-            return mCurrentType;
-        }
-
-        @Override
-        public int currentSegment(double[] coords) {
-            throw new UnsupportedOperationException();
-        }
-
-        /**
-         * Returns the point where the current segment ends
-         */
-        public void getCurrentSegmentEnd(float[] point) {
-            point[0] = mLastPoint[0];
-            point[1] = mLastPoint[1];
-        }
-
-        /**
-         * Restarts the iterator and jumps all the segments of this path up to the length value.
-         */
-        public void jumpToSegment(float length) {
-            isIteratorDone = false;
-            if (length <= 0f) {
-                mNextIndex = 0;
-                return;
-            }
-
-            float accLength = 0;
-            float lastPoint[] = new float[2];
-            for (mNextIndex = 0; mNextIndex < mTypes.length; mNextIndex++) {
-                float segmentLength = mSegmentsLength[mNextIndex];
-                if (accLength + segmentLength >= length && mTypes[mNextIndex] != SEG_MOVETO) {
-                    float[] estimatedPoint = new float[2];
-                    getPointAtLength(mTypes[mNextIndex],
-                            mCoordinates[mNextIndex], lastPoint[0], lastPoint[1],
-                            (length - accLength) / segmentLength,
-                            estimatedPoint);
-
-                    // This segment makes us go further than length so we go back one step,
-                    // set a moveto and offset the length of the next segment by the length
-                    // of this segment that we've already used.
-                    mCurrentType = PathIterator.SEG_MOVETO;
-                    mCurrentCoords[0] = estimatedPoint[0];
-                    mCurrentCoords[1] = estimatedPoint[1];
-                    mCurrentSegmentLength = 0;
-
-                    // We need to offset next path length to account for the segment we've just
-                    // skipped.
-                    mOffsetLength = length - accLength;
-                    return;
-                }
-                accLength += segmentLength;
-                getShapeEndPoint(mTypes[mNextIndex], mCoordinates[mNextIndex], lastPoint);
-            }
-        }
-
-        /**
-         * Returns the current segment up to certain length. If the current segment is shorter than
-         * length, then the whole segment is returned. The segment coordinates are copied into the
-         * coords array.
-         *
-         * @return the segment type
-         */
-        public int currentSegment(@NonNull float[] coords, float length) {
-            int type = currentSegment(coords);
-            // If the length is greater than the current segment length, no need to find
-            // the cut point. Same if this is a SEG_MOVETO.
-            if (mCurrentSegmentLength <= length || type == SEG_MOVETO) {
-                return type;
-            }
-
-            float t = length / getCurrentSegmentLength();
-
-            // We find at which offset the end point is located within the coords array and set
-            // a new end point to cut the segment short
-            switch (type) {
-                case SEG_CUBICTO:
-                case SEG_QUADTO:
-                    float[] curve = new float[8];
-                    curve[0] = mLastPoint[0];
-                    curve[1] = mLastPoint[1];
-                    System.arraycopy(coords, 0, curve, 2, coords.length);
-                    if (type == SEG_CUBICTO) {
-                        cubicCurveSegment(curve, 0f, t);
-                    } else {
-                        quadCurveSegment(curve, 0f, t);
-                    }
-                    System.arraycopy(curve, 2, coords, 0, coords.length);
-                    break;
-                default:
-                    float[] point = new float[2];
-                    getPointAtLength(type, coords, mLastPoint[0], mLastPoint[1], t, point);
-                    coords[0] = point[0];
-                    coords[1] = point[1];
-            }
-
-            return type;
-        }
-
-        /**
-         * Returns the total length of the path
-         */
-        public float getTotalLength() {
-            return mTotalLength;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java
deleted file mode 100644
index 82eab85..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-package com.android.layoutlib.bridge.util;
-
-public class Debug {
-
-    public final static boolean DEBUG = false;
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
deleted file mode 100644
index 161bf41..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.util;
-
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-
-import android.annotation.NonNull;
-import android.util.SparseArray;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class DynamicIdMap {
-
-    private final Map<Pair<ResourceType, String>, Integer> mDynamicIds = new HashMap<>();
-    private final SparseArray<Pair<ResourceType, String>> mRevDynamicIds = new SparseArray<>();
-    private int mDynamicSeed;
-
-    public DynamicIdMap(int seed) {
-        mDynamicSeed = seed;
-    }
-
-    public void reset(int seed) {
-        mDynamicIds.clear();
-        mRevDynamicIds.clear();
-        mDynamicSeed = seed;
-    }
-
-    /**
-     * Returns a dynamic integer for the given resource type/name, creating it if it doesn't
-     * already exist.
-     *
-     * @param type the type of the resource
-     * @param name the name of the resource
-     * @return an integer.
-     */
-    @NonNull
-    public Integer getId(ResourceType type, String name) {
-        return getId(Pair.of(type, name));
-    }
-
-    /**
-     * Returns a dynamic integer for the given resource type/name, creating it if it doesn't
-     * already exist.
-     *
-     * @param resource the type/name of the resource
-     * @return an integer.
-     */
-    @NonNull
-    public Integer getId(Pair<ResourceType, String> resource) {
-        Integer value = mDynamicIds.get(resource);
-        if (value == null) {
-            value = ++mDynamicSeed;
-            mDynamicIds.put(resource, value);
-            mRevDynamicIds.put(value, resource);
-        }
-
-        return value;
-    }
-
-    public Pair<ResourceType, String> resolveId(int id) {
-        return mRevDynamicIds.get(id);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/NinePatchInputStream.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/NinePatchInputStream.java
deleted file mode 100644
index f149b6c..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/NinePatchInputStream.java
+++ /dev/null
@@ -1,47 +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.layoutlib.bridge.util;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-
-/**
- * Simpler wrapper around FileInputStream. This is used when the input stream represent
- * not a normal bitmap but a nine patch.
- * This is useful when the InputStream is created in a method but used in another that needs
- * to know whether this is 9-patch or not, such as BitmapFactory.
- */
-public class NinePatchInputStream extends FileInputStream {
-    private boolean mFakeMarkSupport = true;
-    public NinePatchInputStream(File file) throws FileNotFoundException {
-        super(file);
-    }
-
-    @Override
-    public boolean markSupported() {
-        // this is needed so that BitmapFactory doesn't wrap this in a BufferedInputStream.
-        return mFakeMarkSupport || super.markSupported();
-
-    }
-
-    public void disableFakeMarkSupport() {
-        // disable fake mark support so that in case codec actually try to use them
-        // we don't lie to them.
-        mFakeMarkSupport = false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/ReflectionUtils.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/ReflectionUtils.java
deleted file mode 100644
index b89718f..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/ReflectionUtils.java
+++ /dev/null
@@ -1,123 +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.layoutlib.bridge.util;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * Utility to convert checked Reflection exceptions to unchecked exceptions.
- */
-public class ReflectionUtils {
-
-    @NonNull
-    public static Method getMethod(@NonNull Class<?> clazz, @NonNull String name,
-            @Nullable Class<?>... params) throws ReflectionException {
-        try {
-            return clazz.getMethod(name, params);
-        } catch (NoSuchMethodException e) {
-            throw new ReflectionException(e);
-        }
-    }
-
-    @NonNull
-    public static Method getAccessibleMethod(@NonNull Class<?> clazz, @NonNull String name,
-      @Nullable Class<?>... params) throws ReflectionException {
-        Method method = getMethod(clazz, name, params);
-        method.setAccessible(true);
-
-        return method;
-    }
-
-    @Nullable
-    public static Object invoke(@NonNull Method method, @Nullable Object object,
-            @Nullable Object... args) throws ReflectionException {
-        Exception ex;
-        try {
-            return method.invoke(object, args);
-        } catch (IllegalAccessException | InvocationTargetException e) {
-            ex = e;
-        }
-        throw new ReflectionException(ex);
-    }
-
-    /**
-     * Check if the object is an instance of a class named {@code className}. This doesn't work
-     * for interfaces.
-     */
-    public static boolean isInstanceOf(Object object, String className) {
-        Class superClass = object.getClass();
-        while (superClass != null) {
-            String name = superClass.getName();
-            if (name.equals(className)) {
-                return true;
-            }
-            superClass = superClass.getSuperclass();
-        }
-        return false;
-    }
-
-    @NonNull
-    public static Throwable getCause(@NonNull Throwable throwable) {
-        Throwable cause = throwable.getCause();
-        return cause == null ? throwable : cause;
-    }
-
-    /**
-     * Looks through the class hierarchy of {@code object} at runtime and returns the class matching
-     * the name {@code className}.
-     * <p>
-     * This is used when we cannot use Class.forName() since the class we want was loaded from a
-     * different ClassLoader.
-     */
-    @NonNull
-    public static Class<?> getClassInstance(@NonNull Object object, @NonNull String className) {
-        Class<?> superClass = object.getClass();
-        while (superClass != null) {
-            if (className.equals(superClass.getName())) {
-                return superClass;
-            }
-            superClass = superClass.getSuperclass();
-        }
-        throw new RuntimeException("invalid object/classname combination.");
-    }
-
-    /**
-     * Wraps all reflection related exceptions. Created since ReflectiveOperationException was
-     * introduced in 1.7 and we are still on 1.6
-     */
-    public static class ReflectionException extends Exception {
-        public ReflectionException() {
-            super();
-        }
-
-        public ReflectionException(String message) {
-            super(message);
-        }
-
-        public ReflectionException(String message, Throwable cause) {
-            super(message, cause);
-        }
-
-        public ReflectionException(Throwable cause) {
-            super(cause);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
deleted file mode 100644
index a2a8aa9..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
+++ /dev/null
@@ -1,329 +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.
- */
-
-package com.android.layoutlib.bridge.util;
-
-
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.GrowingArrayUtils;
-
-import android.util.SparseArray;
-
-import java.lang.ref.WeakReference;
-
-/**
- * This is a custom {@link SparseArray} that uses {@link WeakReference} around the objects added
- * to it. When the array is compacted, not only deleted indices but also empty references
- * are removed, making the array efficient at removing references that were reclaimed.
- *
- * The code is taken from {@link SparseArray} directly and adapted to use weak references.
- *
- * Because our usage means that we never actually call {@link #remove(long)} or
- * {@link #delete(long)}, we must manually check if there are reclaimed references to
- * trigger an internal compact step (which is normally only triggered when an item is manually
- * removed).
- *
- * SparseArrays map integral values to Objects.  Unlike a normal array of Objects,
- * there can be gaps in the indices.  It is intended to be more efficient
- * than using a HashMap to map Integers (or Longs) to Objects.
- */
-@SuppressWarnings("unchecked")
-public class SparseWeakArray<E> {
-
-    private static final Object DELETED_REF = new Object();
-    private static final WeakReference<?> DELETED = new WeakReference(DELETED_REF);
-    private boolean mGarbage = false;
-
-    /**
-     * Creates a new SparseArray containing no mappings.
-     */
-    public SparseWeakArray() {
-        this(10);
-    }
-
-    /**
-     * Creates a new SparseArray containing no mappings that will not
-     * require any additional memory allocation to store the specified
-     * number of mappings.
-     */
-    public SparseWeakArray(int initialCapacity) {
-        mKeys = ArrayUtils.newUnpaddedLongArray(initialCapacity);
-        mValues = new WeakReference[mKeys.length];
-        mSize = 0;
-    }
-
-    /**
-     * Gets the Object mapped from the specified key, or <code>null</code>
-     * if no such mapping has been made.
-     */
-    public E get(long key) {
-        return get(key, null);
-    }
-
-    /**
-     * Gets the Object mapped from the specified key, or the specified Object
-     * if no such mapping has been made.
-     */
-    public E get(long key, E valueIfKeyNotFound) {
-        int i = binarySearch(mKeys, 0, mSize, key);
-
-        if (i < 0 || mValues[i] == DELETED || mValues[i].get() == null) {
-            return valueIfKeyNotFound;
-        } else {
-            return (E) mValues[i].get();
-        }
-    }
-
-    /**
-     * Removes the mapping from the specified key, if there was any.
-     */
-    public void delete(long key) {
-        int i = binarySearch(mKeys, 0, mSize, key);
-
-        if (i >= 0) {
-            if (mValues[i] != DELETED) {
-                mValues[i] = DELETED;
-                mGarbage = true;
-            }
-        }
-    }
-
-    /**
-     * Alias for {@link #delete(long)}.
-     */
-    public void remove(long key) {
-        delete(key);
-    }
-
-    /**
-     * Removes the mapping at the specified index.
-     */
-    public void removeAt(int index) {
-        if (mValues[index] != DELETED) {
-            mValues[index] = DELETED;
-            mGarbage = true;
-        }
-    }
-
-    private void gc() {
-        int n = mSize;
-        int o = 0;
-        long[] keys = mKeys;
-        WeakReference<?>[] values = mValues;
-
-        for (int i = 0; i < n; i++) {
-            WeakReference<?> val = values[i];
-
-            // Don't keep any non DELETED values, but only the one that still have a valid
-            // reference.
-            if (val != DELETED && val.get() != null) {
-                if (i != o) {
-                    keys[o] = keys[i];
-                    values[o] = val;
-                }
-
-                o++;
-            }
-        }
-
-        mGarbage = false;
-        mSize = o;
-    }
-
-    /**
-     * Adds a mapping from the specified key to the specified value,
-     * replacing the previous mapping from the specified key if there
-     * was one.
-     */
-    public void put(long key, E value) {
-        int i = binarySearch(mKeys, 0, mSize, key);
-
-        if (i >= 0) {
-            mValues[i] = new WeakReference(value);
-        } else {
-            i = ~i;
-
-            if (i < mSize && (mValues[i] == DELETED || mValues[i].get() == null)) {
-                mKeys[i] = key;
-                mValues[i] = new WeakReference(value);
-                return;
-            }
-
-            if (mSize >= mKeys.length && (mGarbage || hasReclaimedRefs())) {
-                gc();
-
-                // Search again because indices may have changed.
-                i = ~binarySearch(mKeys, 0, mSize, key);
-            }
-
-            mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
-            mValues = GrowingArrayUtils.insert(mValues, mSize, i, new WeakReference(value));
-            mSize++;
-        }
-    }
-
-    /**
-     * Returns the number of key-value mappings that this SparseArray
-     * currently stores.
-     */
-    public int size() {
-        if (mGarbage) {
-            gc();
-        }
-
-        return mSize;
-    }
-
-    /**
-     * Given an index in the range <code>0...size()-1</code>, returns
-     * the key from the <code>index</code>th key-value mapping that this
-     * SparseArray stores.
-     */
-    public long keyAt(int index) {
-        if (mGarbage) {
-            gc();
-        }
-
-        return mKeys[index];
-    }
-
-    /**
-     * Given an index in the range <code>0...size()-1</code>, returns
-     * the value from the <code>index</code>th key-value mapping that this
-     * SparseArray stores.
-     */
-    public E valueAt(int index) {
-        if (mGarbage) {
-            gc();
-        }
-
-        return (E) mValues[index].get();
-    }
-
-    /**
-     * Given an index in the range <code>0...size()-1</code>, sets a new
-     * value for the <code>index</code>th key-value mapping that this
-     * SparseArray stores.
-     */
-    public void setValueAt(int index, E value) {
-        if (mGarbage) {
-            gc();
-        }
-
-        mValues[index] = new WeakReference(value);
-    }
-
-    /**
-     * Returns the index for which {@link #keyAt} would return the
-     * specified key, or a negative number if the specified
-     * key is not mapped.
-     */
-    public int indexOfKey(long key) {
-        if (mGarbage) {
-            gc();
-        }
-
-        return binarySearch(mKeys, 0, mSize, key);
-    }
-
-    /**
-     * Returns an index for which {@link #valueAt} would return the
-     * specified key, 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(E value) {
-        if (mGarbage) {
-            gc();
-        }
-
-        for (int i = 0; i < mSize; i++)
-            if (mValues[i].get() == value)
-                return i;
-
-        return -1;
-    }
-
-    /**
-     * Removes all key-value mappings from this SparseArray.
-     */
-    public void clear() {
-        int n = mSize;
-        WeakReference<?>[] values = mValues;
-
-        for (int i = 0; i < n; i++) {
-            values[i] = null;
-        }
-
-        mSize = 0;
-        mGarbage = false;
-    }
-
-    /**
-     * Puts a key/value pair into the array, optimizing for the case where
-     * the key is greater than all existing keys in the array.
-     */
-    public void append(long key, E value) {
-        if (mSize != 0 && key <= mKeys[mSize - 1]) {
-            put(key, value);
-            return;
-        }
-
-        if (mSize >= mKeys.length && (mGarbage || hasReclaimedRefs())) {
-            gc();
-        }
-
-        mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
-        mValues = GrowingArrayUtils.append(mValues, mSize, new WeakReference(value));
-        mSize++;
-    }
-
-    private boolean hasReclaimedRefs() {
-        for (int i = 0 ; i < mSize ; i++) {
-            if (mValues[i].get() == null) { // DELETED.get() never returns null.
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static int binarySearch(long[] a, int start, int len, long key) {
-        int high = start + len, low = start - 1, guess;
-
-        while (high - low > 1) {
-            guess = (high + low) / 2;
-
-            if (a[guess] < key)
-                low = guess;
-            else
-                high = guess;
-        }
-
-        if (high == start + len)
-            return ~(start + len);
-        else if (a[high] == key)
-            return high;
-        else
-            return ~high;
-    }
-
-    private long[] mKeys;
-    private WeakReference<?>[] mValues;
-    private int mSize;
-}
diff --git a/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java b/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java
deleted file mode 100644
index 6d013bb..0000000
--- a/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.maps;
-
-import com.android.layoutlib.bridge.MockView;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * Mock version of the MapView.
- * Only non override public methods from the real MapView have been added in there.
- * Methods that take an unknown class as parameter or as return object, have been removed for now.
- * 
- * TODO: generate automatically.
- *
- */
-public class MapView extends MockView {
-
-    /**
-     * Construct a new WebView with a Context object.
-     * @param context A Context object used to access application assets.
-     */
-    public MapView(Context context) {
-        this(context, null);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     */
-    public MapView(Context context, AttributeSet attrs) {
-        this(context, attrs, com.android.internal.R.attr.mapViewStyle);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters and a default style.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     * @param defStyle The default style resource ID.
-     */
-    public MapView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-    
-    // START FAKE PUBLIC METHODS
-    
-    public void displayZoomControls(boolean takeFocus) {
-    }
-
-    public boolean canCoverCenter() {
-        return false;
-    }
-
-    public void preLoad() {
-    }
-
-    public int getZoomLevel() {
-        return 0;
-    }
-
-    public void setSatellite(boolean on) {
-    }
-
-    public boolean isSatellite() {
-        return false;
-    }
-
-    public void setTraffic(boolean on) {
-    }
-
-    public boolean isTraffic() {
-        return false;
-    }
-
-    public void setStreetView(boolean on) {
-    }
-
-    public boolean isStreetView() {
-        return false;
-    }
-
-    public int getLatitudeSpan() {
-        return 0;
-    }
-
-    public int getLongitudeSpan() {
-        return 0;
-    }
-
-    public int getMaxZoomLevel() {
-        return 0;
-    }
-
-    public void onSaveInstanceState(Bundle state) {
-    }
-
-    public void onRestoreInstanceState(Bundle state) {
-    }
-
-    public View getZoomControls() {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/dalvik/system/VMRuntime_Delegate.java b/tools/layoutlib/bridge/src/dalvik/system/VMRuntime_Delegate.java
deleted file mode 100644
index 36efc3a..0000000
--- a/tools/layoutlib/bridge/src/dalvik/system/VMRuntime_Delegate.java
+++ /dev/null
@@ -1,78 +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 dalvik.system;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide implementation of a select few native methods of {@link VMRuntime}
- * <p/>
- * Through the layoutlib_create tool, the original native methods of VMRuntime have been replaced
- * by calls to methods of the same name in this delegate class.
- */
-public class VMRuntime_Delegate {
-
-    // Copied from libcore/libdvm/src/main/java/dalvik/system/VMRuntime
-    @LayoutlibDelegate
-    /*package*/ static Object newUnpaddedArray(VMRuntime runtime, Class<?> componentType,
-            int minLength) {
-        // Dalvik has 32bit pointers, the array header is 16bytes plus 4bytes for dlmalloc,
-        // allocations are 8byte aligned so having 4bytes of array data avoids padding.
-        if (!componentType.isPrimitive()) {
-            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
-            return java.lang.reflect.Array.newInstance(componentType, size);
-        } else if (componentType == char.class) {
-            int bytes = 20 + (2 * minLength);
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes / 2;
-            return new char[size];
-        } else if (componentType == int.class) {
-            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
-            return new int[size];
-        } else if (componentType == byte.class) {
-            int bytes = 20 + minLength;
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes;
-            return new byte[size];
-        } else if (componentType == boolean.class) {
-            int bytes = 20 + minLength;
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes;
-            return new boolean[size];
-        } else if (componentType == short.class) {
-            int bytes = 20 + (2 * minLength);
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes / 2;
-            return new short[size];
-        } else if (componentType == float.class) {
-            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
-            return new float[size];
-        } else if (componentType == long.class) {
-            return new long[minLength];
-        } else if (componentType == double.class) {
-            return new double[minLength];
-        } else {
-            assert componentType == void.class;
-            throw new IllegalArgumentException("Can't allocate an array of void");
-        }
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
deleted file mode 100644
index 9c58010..0000000
--- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
+++ /dev/null
@@ -1,263 +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.
- */
-
-package libcore.icu;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.icu.text.DateTimePatternGenerator;
-import android.icu.util.Currency;
-import android.icu.util.ULocale;
-import android.icu.util.VersionInfo;
-
-import java.util.Locale;
-
-/**
- * Delegate implementing the native methods of libcore.icu.ICU
- *
- * Through the layoutlib_create tool, the original native methods of ICU have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class ICU_Delegate {
-
-    // --- Java delegates
-
-    @LayoutlibDelegate
-    /*package*/ static String toLowerCase(String s, String localeName) {
-        return s.toLowerCase();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String toUpperCase(String s, String localeName) {
-        return s.toUpperCase();
-    }
-
-    // --- Native methods accessing ICU's database.
-
-    @LayoutlibDelegate
-    /*package*/ static String getBestDateTimePatternNative(String skeleton, String localeName) {
-        return DateTimePatternGenerator.getInstance(new ULocale(localeName))
-                .getBestPattern(skeleton);
-    }
-
-    @LayoutlibDelegate
-    @SuppressWarnings("deprecation")
-    /*package*/ static String getCldrVersion() {
-        return VersionInfo.ICU_DATA_VERSION.toString();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getIcuVersion() {
-        return VersionInfo.ICU_VERSION.toString();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getUnicodeVersion() {
-        return VersionInfo.UNICODE_7_0.toString();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableBreakIteratorLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableCalendarLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableCollatorLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableDateFormatLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableNumberFormatLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableCurrencyCodes() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getCurrencyCode(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getCurrencyDisplayName(String locale, String currencyCode) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int getCurrencyFractionDigits(String currencyCode) {
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int getCurrencyNumericCode(String currencyCode) {
-        return Currency.getInstance(currencyCode).getNumericCode();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getCurrencySymbol(String locale, String currencyCode) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayCountryNative(String countryCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayLanguageNative(String languageCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayVariantNative(String variantCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayScriptNative(String variantCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getISO3Country(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getISO3Language(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String addLikelySubtags(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getScript(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getISOLanguagesNative() {
-        return Locale.getISOLanguages();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getISOCountriesNative() {
-        return Locale.getISOCountries();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean initLocaleDataNative(String locale, LocaleData result) {
-
-        // Used by Calendar.
-        result.firstDayOfWeek = 1;
-        result.minimalDaysInFirstWeek = 1;
-
-        // Used by DateFormatSymbols.
-        result.amPm = new String[] { "AM", "PM" };
-        result.eras = new String[] { "BC", "AD" };
-
-        result.longMonthNames = new String[] { "January", "February", "March", "April", "May",
-                "June", "July", "August", "September", "October", "November", "December" };
-        result.shortMonthNames = new String[] { "Jan", "Feb", "Mar", "Apr", "May",
-                "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-        result.longStandAloneMonthNames = result.longMonthNames;
-        result.shortStandAloneMonthNames = result.shortMonthNames;
-
-        // The platform code expects this to begin at index 1, rather than 0. It maps it directly to
-        // the constants from java.util.Calendar.<weekday>
-        result.longWeekdayNames = new String[] {
-                "", "Sunday", "Monday" ,"Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
-        result.shortWeekdayNames = new String[] {
-                "", "Sun", "Mon" ,"Tue", "Wed", "Thu", "Fri", "Sat" };
-        result.tinyWeekdayNames = new String[] {
-                "", "S", "M", "T", "W", "T", "F", "S" };
-
-        result.longStandAloneWeekdayNames = result.longWeekdayNames;
-        result.shortStandAloneWeekdayNames = result.shortWeekdayNames;
-        result.tinyStandAloneWeekdayNames = result.tinyWeekdayNames;
-
-        result.fullTimeFormat = "";
-        result.longTimeFormat = "";
-        result.mediumTimeFormat = "";
-        result.shortTimeFormat = "";
-
-        result.fullDateFormat = "";
-        result.longDateFormat = "";
-        result.mediumDateFormat = "";
-        result.shortDateFormat = "";
-
-        // Used by DecimalFormatSymbols.
-        result.zeroDigit = '0';
-        result.decimalSeparator = '.';
-        result.groupingSeparator = ',';
-        result.patternSeparator = ' ';
-        result.percent = "%";
-        result.perMill = '\u2030';
-        result.monetarySeparator = ' ';
-        result.minusSign = "-";
-        result.exponentSeparator = "e";
-        result.infinity = "\u221E";
-        result.NaN = "NaN";
-        // Also used by Currency.
-        result.currencySymbol = "$";
-        result.internationalCurrencySymbol = "USD";
-
-        // Used by DecimalFormat and NumberFormat.
-        result.numberPattern = "%f";
-        result.integerPattern = "%d";
-        result.currencyPattern = "%s";
-        result.percentPattern = "%f";
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setDefaultLocale(String locale) {
-        ICU.setDefaultLocale(locale);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDefaultLocale() {
-        return ICU.getDefaultLocale();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getTZDataVersion() {
-        return ICU.getTZDataVersion();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/libcore/io/MemoryMappedFile_Delegate.java b/tools/layoutlib/bridge/src/libcore/io/MemoryMappedFile_Delegate.java
deleted file mode 100644
index 723d5c4..0000000
--- a/tools/layoutlib/bridge/src/libcore/io/MemoryMappedFile_Delegate.java
+++ /dev/null
@@ -1,118 +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 libcore.io;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.libcore.io.BridgeBufferIterator;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.system.ErrnoException;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteOrder;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel.MapMode;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Delegate used to provide alternate implementation of select methods of {@link MemoryMappedFile}.
- */
-public class MemoryMappedFile_Delegate {
-
-    private static final DelegateManager<MemoryMappedFile_Delegate> sManager = new
-            DelegateManager<MemoryMappedFile_Delegate>(MemoryMappedFile_Delegate.class);
-
-    private static final Map<MemoryMappedFile, Long> sMemoryMappedFileMap =
-            new HashMap<MemoryMappedFile, Long>();
-
-    private final MappedByteBuffer mMappedByteBuffer;
-    private final long mSize;
-
-    /** Path on the target device where the data file is available. */
-    private static final String TARGET_PATH = System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo";
-    /** Path on the host (inside the SDK) where the data files are available. */
-    private static File sRootPath;
-
-    @LayoutlibDelegate
-    static MemoryMappedFile mmapRO(String path) throws ErrnoException {
-        if (!path.startsWith(TARGET_PATH)) {
-            throw new ErrnoException("Custom timezone data files are not supported.", 1);
-        }
-        if (sRootPath == null) {
-            throw new ErrnoException("Bridge has not been initialized properly.", 1);
-        }
-        path = path.substring(TARGET_PATH.length());
-        try {
-            File f = new File(sRootPath, path);
-            if (!f.exists()) {
-                throw new ErrnoException("File not found: " + f.getPath(), 1);
-            }
-            RandomAccessFile file = new RandomAccessFile(f, "r");
-            try {
-                long size = file.length();
-                MemoryMappedFile_Delegate newDelegate = new MemoryMappedFile_Delegate(file);
-                long filePointer = file.getFilePointer();
-                MemoryMappedFile mmFile = new MemoryMappedFile(filePointer, size);
-                long delegateIndex = sManager.addNewDelegate(newDelegate);
-                sMemoryMappedFileMap.put(mmFile, delegateIndex);
-                return mmFile;
-            } finally {
-                file.close();
-            }
-        } catch (IOException e) {
-            throw new ErrnoException("mmapRO", 1, e);
-        }
-    }
-
-    @LayoutlibDelegate
-    static void close(MemoryMappedFile thisFile) throws ErrnoException {
-        Long index = sMemoryMappedFileMap.get(thisFile);
-        if (index != null) {
-            sMemoryMappedFileMap.remove(thisFile);
-            sManager.removeJavaReferenceFor(index);
-        }
-    }
-
-    @LayoutlibDelegate
-    static BufferIterator bigEndianIterator(MemoryMappedFile file) {
-        MemoryMappedFile_Delegate delegate = getDelegate(file);
-        return new BridgeBufferIterator(delegate.mSize, delegate.mMappedByteBuffer.duplicate());
-    }
-
-    // TODO: implement littleEndianIterator()
-
-    public MemoryMappedFile_Delegate(RandomAccessFile file) throws IOException {
-        mSize = file.length();
-        // It's weird that map() takes size as long, but returns MappedByteBuffer which uses an int
-        // to store the marker to the position.
-        mMappedByteBuffer = file.getChannel().map(MapMode.READ_ONLY, 0, mSize);
-        assert mMappedByteBuffer.order() == ByteOrder.BIG_ENDIAN;
-    }
-
-    public static void setDataDir(File path) {
-        sRootPath = path;
-    }
-
-    private static MemoryMappedFile_Delegate getDelegate(MemoryMappedFile file) {
-        Long index = sMemoryMappedFileMap.get(file);
-        return index == null ? null : sManager.getDelegate(index);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/libcore/util/NativeAllocationRegistry_Delegate.java b/tools/layoutlib/bridge/src/libcore/util/NativeAllocationRegistry_Delegate.java
deleted file mode 100644
index 04fabc2..0000000
--- a/tools/layoutlib/bridge/src/libcore/util/NativeAllocationRegistry_Delegate.java
+++ /dev/null
@@ -1,70 +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 libcore.util;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of {@link NativeAllocationRegistry}
- *
- * Through the layoutlib_create tool, the original native methods of NativeAllocationRegistry have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original NativeAllocationRegistry class.
- *
- * @see DelegateManager
- */
-public class NativeAllocationRegistry_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<NativeAllocationRegistry_Delegate> sManager =
-            new DelegateManager<>(NativeAllocationRegistry_Delegate.class);
-
-    private final FreeFunction mFinalizer;
-
-    private NativeAllocationRegistry_Delegate(FreeFunction finalizer) {
-        mFinalizer = finalizer;
-    }
-
-    /**
-     * The result of this method should be cached by the class and reused.
-     */
-    public static long createFinalizer(FreeFunction finalizer) {
-        return sManager.addNewDelegate(new NativeAllocationRegistry_Delegate(finalizer));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void applyFreeFunction(long freeFunction, long nativePtr) {
-        // This method MIGHT run in the context of the finalizer thread. If the delegate method
-        // crashes, it could bring down the VM. That's why we catch all the exceptions and ignore
-        // them.
-        try {
-            NativeAllocationRegistry_Delegate delegate = sManager.getDelegate(freeFunction);
-            if (delegate != null) {
-                delegate.mFinalizer.free(nativePtr);
-            }
-        } catch (Throwable ignore) {
-        }
-    }
-
-    public interface FreeFunction {
-        void free(long nativePtr);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/.classpath b/tools/layoutlib/bridge/tests/.classpath
deleted file mode 100644
index 2b32e09..0000000
--- a/tools/layoutlib/bridge/tests/.classpath
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="res"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_bridge"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/layoutlib/bridge/tests/.project b/tools/layoutlib/bridge/tests/.project
deleted file mode 100644
index 2325eed..0000000
--- a/tools/layoutlib/bridge/tests/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>layoutlib_bridge-tests</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/layoutlib/bridge/tests/Android.mk b/tools/layoutlib/bridge/tests/Android.mk
deleted file mode 100644
index 1b65eee..0000000
--- a/tools/layoutlib/bridge/tests/Android.mk
+++ /dev/null
@@ -1,43 +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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# Only compile source java files in this lib.
-LOCAL_SRC_FILES := \
-	$(call all-java-files-under, src) \
-	$(call all-java-files-under, res/testApp/MyApplication/src/main/myapplication.widgets)
-LOCAL_JAVA_RESOURCE_DIRS := res
-
-LOCAL_MODULE := layoutlib-tests
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_JAVA_LIBRARIES := layoutlib \
-			kxml2-2.3.0 \
-			layoutlib_api-prebuilt \
-			tools-common-prebuilt \
-			sdk-common \
-			junit-host \
-			guavalib \
-			mockito-host
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Copy the jar to DIST_DIR for sdk builds
-$(call dist-for-goals, sdk win_sdk, $(LOCAL_INSTALLED_MODULE))
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/layoutlib/bridge/tests/res/com/android/layoutlib/testdata/layout1.xml b/tools/layoutlib/bridge/tests/res/com/android/layoutlib/testdata/layout1.xml
deleted file mode 100644
index b8fc947..0000000
--- a/tools/layoutlib/bridge/tests/res/com/android/layoutlib/testdata/layout1.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-	android:orientation="vertical"
->
-	<Button
-		android:id="@+id/bouton"
-	    android:layout_width="wrap_content"
-	    android:layout_height="wrap_content"
-	    android:layout_weight="1"
-	    android:text="My Button Text"
-	    >
-	    </Button>
-	<View
-		android:id="@+id/surface"
-	    android:layout_width="match_parent"
-	    android:layout_height="match_parent"
-	    android:layout_weight="2"
-	    />
-	<TextView
-	    android:id="@+id/status"
-	    android:paddingLeft="2dip"
-	    android:layout_weight="0"
-	    android:background="@drawable/black"
-	    android:layout_width="match_parent"
-	    android:layout_height="wrap_content"
-	    android:lines="1"
-	    android:gravity="center_vertical|center_horizontal"
-	    android:text="My TextView Text"
-	    />
-</LinearLayout>
diff --git a/tools/layoutlib/bridge/tests/res/empty.xml b/tools/layoutlib/bridge/tests/res/empty.xml
deleted file mode 100644
index e69de29..0000000
--- a/tools/layoutlib/bridge/tests/res/empty.xml
+++ /dev/null
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/.gitignore b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/.gitignore
deleted file mode 100644
index a2ce0dc..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/.gitignore
+++ /dev/null
@@ -1,14 +0,0 @@
-.gradle
-local.properties
-.idea
-.DS_Store
-*.iml
-# We need the built .class files to load custom views and R class.
-# The only way to negate an exclusion is by including every single parent
-# and excluding all children of those parents.
-
-/build/*
-!/build/intermediates/
-
-/build/intermediates/*
-!/build/intermediates/classes/
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle
deleted file mode 100644
index 4781660..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle
+++ /dev/null
@@ -1,48 +0,0 @@
-buildscript {
-    repositories {
-        jcenter()
-    }
-    dependencies {
-        classpath 'com.android.tools.build:gradle:1.2.3'
-
-        // NOTE: Do not place your application dependencies here; they belong
-        // in the individual module build.gradle files
-    }
-}
-
-allprojects {
-    repositories {
-        jcenter()
-    }
-}
-
-apply plugin: 'com.android.application'
-
-android {
-    compileSdkVersion 25
-    buildToolsVersion '25.0.0'
-    defaultConfig {
-        applicationId 'com.android.layoutlib.test.myapplication'
-        minSdkVersion 21
-        targetSdkVersion 25
-        versionCode 1
-        versionName '1.0'
-    }
-    buildTypes {
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
-        }
-    }
-    lintOptions {
-        abortOnError false
-    }
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_6
-        targetCompatibility JavaVersion.VERSION_1_6
-    }
-}
-
-dependencies {
-    compile fileTree(dir: 'libs', include: ['*.jar'])
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/androidTest/debug/com/android/layoutlib/test/myapplication/test/BuildConfig.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/androidTest/debug/com/android/layoutlib/test/myapplication/test/BuildConfig.class
deleted file mode 100644
index 1ca7e01..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/androidTest/debug/com/android/layoutlib/test/myapplication/test/BuildConfig.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/ArraysCheckWidget.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/ArraysCheckWidget.class
deleted file mode 100644
index f73528a..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/ArraysCheckWidget.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/BuildConfig.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/BuildConfig.class
deleted file mode 100644
index ceb56bf..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/BuildConfig.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class
deleted file mode 100644
index 5bb04fc..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$array.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$array.class
deleted file mode 100644
index b87f193..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$array.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$attr.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$attr.class
deleted file mode 100644
index e2968d40..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$attr.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$color.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$color.class
deleted file mode 100644
index ff699d1..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$color.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class
deleted file mode 100644
index a3931b8..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class
deleted file mode 100644
index e293677..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class
deleted file mode 100644
index d6268bf..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$integer.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$integer.class
deleted file mode 100644
index 08b98fb..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$integer.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class
deleted file mode 100644
index f9be1ca..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class
deleted file mode 100644
index 6874b49e..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class
deleted file mode 100644
index a4205a8..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class
deleted file mode 100644
index 4fb3b61..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class
deleted file mode 100644
index dba67fd..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
deleted file mode 100644
index affc31e..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon.png
deleted file mode 100644
index 7014ddb..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
deleted file mode 100644
index f15d669..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png
deleted file mode 100644
index 88fa9dd..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector.png
deleted file mode 100644
index e33f92d..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector_1.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector_1.png
deleted file mode 100644
index 915868c..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector_1.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png
deleted file mode 100644
index ee72a6f..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png
deleted file mode 100644
index 781d617..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png
deleted file mode 100644
index 5b64d33..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/font_test.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/font_test.png
deleted file mode 100644
index 736b287..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/font_test.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners.png
deleted file mode 100644
index a8567b3..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent.png
deleted file mode 100644
index 5ae95ea3..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent_land.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent_land.png
deleted file mode 100644
index b2b6a97..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent_land.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/scrolled.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/scrolled.png
deleted file mode 100644
index cf1a769..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/scrolled.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png
deleted file mode 100644
index 67355b8..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity-old-theme.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity-old-theme.png
deleted file mode 100644
index e0abcf4..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity-old-theme.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity.png
deleted file mode 100644
index 3d0fbd6..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity_noactionbar.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity_noactionbar.png
deleted file mode 100644
index 86b00415..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity_noactionbar.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png
deleted file mode 100644
index 7bbae09..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_91383.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_91383.png
deleted file mode 100644
index e9dca692..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_91383.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle.properties b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle.properties
deleted file mode 100644
index 5d08ba7..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-# Project-wide Gradle settings.
-
-# IDE (e.g. Android Studio) users:
-# Settings specified in this file will override any Gradle settings
-# configured through the IDE.
-
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
-# Default value: -Xmx10248m -XX:MaxPermSize=256m
-# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
-
-# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.jar b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index 8c0fb64..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.jar
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.properties b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 3b51ffe..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-#Tue Mar 17 15:13:06 PDT 2015
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew
deleted file mode 100755
index 91a7e26..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/env bash
-
-##############################################################################
-##
-##  Gradle start up script for UN*X
-##
-##############################################################################
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn ( ) {
-    echo "$*"
-}
-
-die ( ) {
-    echo
-    echo "$*"
-    echo
-    exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-case "`uname`" in
-  CYGWIN* )
-    cygwin=true
-    ;;
-  Darwin* )
-    darwin=true
-    ;;
-  MINGW* )
-    msys=true
-    ;;
-esac
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
-    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
-    ls=`ls -ld "$PRG"`
-    link=`expr "$ls" : '.*-> \(.*\)$'`
-    if expr "$link" : '/.*' > /dev/null; then
-        PRG="$link"
-    else
-        PRG=`dirname "$PRG"`"/$link"
-    fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
-    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
-        # IBM's JDK on AIX uses strange locations for the executables
-        JAVACMD="$JAVA_HOME/jre/sh/java"
-    else
-        JAVACMD="$JAVA_HOME/bin/java"
-    fi
-    if [ ! -x "$JAVACMD" ] ; then
-        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-    fi
-else
-    JAVACMD="java"
-    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
-    MAX_FD_LIMIT=`ulimit -H -n`
-    if [ $? -eq 0 ] ; then
-        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
-            MAX_FD="$MAX_FD_LIMIT"
-        fi
-        ulimit -n $MAX_FD
-        if [ $? -ne 0 ] ; then
-            warn "Could not set maximum file descriptor limit: $MAX_FD"
-        fi
-    else
-        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
-    fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
-    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
-    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
-    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
-    # We build the pattern for arguments to be converted via cygpath
-    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
-    SEP=""
-    for dir in $ROOTDIRSRAW ; do
-        ROOTDIRS="$ROOTDIRS$SEP$dir"
-        SEP="|"
-    done
-    OURCYGPATTERN="(^($ROOTDIRS))"
-    # Add a user-defined pattern to the cygpath arguments
-    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
-        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
-    fi
-    # Now convert the arguments - kludge to limit ourselves to /bin/sh
-    i=0
-    for arg in "$@" ; do
-        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
-        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
-
-        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
-            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
-        else
-            eval `echo args$i`="\"$arg\""
-        fi
-        i=$((i+1))
-    done
-    case $i in
-        (0) set -- ;;
-        (1) set -- "$args0" ;;
-        (2) set -- "$args0" "$args1" ;;
-        (3) set -- "$args0" "$args1" "$args2" ;;
-        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
-        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
-        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
-        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
-        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
-        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
-    esac
-fi
-
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
-    JVM_OPTS=("$@")
-}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
-
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew.bat b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew.bat
deleted file mode 100644
index aec9973..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew.bat
+++ /dev/null
@@ -1,90 +0,0 @@
-@if "%DEBUG%" == "" @echo off

-@rem ##########################################################################

-@rem

-@rem  Gradle startup script for Windows

-@rem

-@rem ##########################################################################

-

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

-if "%OS%"=="Windows_NT" setlocal

-

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

-set DEFAULT_JVM_OPTS=

-

-set DIRNAME=%~dp0

-if "%DIRNAME%" == "" set DIRNAME=.

-set APP_BASE_NAME=%~n0

-set APP_HOME=%DIRNAME%

-

-@rem Find java.exe

-if defined JAVA_HOME goto findJavaFromJavaHome

-

-set JAVA_EXE=java.exe

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

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

-

-echo.

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

-echo.

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

-echo location of your Java installation.

-

-goto fail

-

-:findJavaFromJavaHome

-set JAVA_HOME=%JAVA_HOME:"=%

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

-

-if exist "%JAVA_EXE%" goto init

-

-echo.

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

-echo.

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

-echo location of your Java installation.

-

-goto fail

-

-:init

-@rem Get command-line arguments, handling Windowz variants

-

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

-if "%@eval[2+2]" == "4" goto 4NT_args

-

-:win9xME_args

-@rem Slurp the command line arguments.

-set CMD_LINE_ARGS=

-set _SKIP=2

-

-:win9xME_args_slurp

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

-

-set CMD_LINE_ARGS=%*

-goto execute

-

-:4NT_args

-@rem Get arguments from the 4NT Shell from JP Software

-set CMD_LINE_ARGS=%$

-

-:execute

-@rem Setup the command line

-

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

-

-@rem Execute Gradle

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

-

-:end

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

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

-

-:fail

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

-rem the _cmd.exe /c_ return code!

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

-exit /b 1

-

-:mainEnd

-if "%OS%"=="Windows_NT" endlocal

-

-:omega

diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/proguard-rules.pro b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/proguard-rules.pro
deleted file mode 100644
index b0fcd2d..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/proguard-rules.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in /usr/local/google/home/deepanshu/ssd/sdk_out/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the proguardFiles
-# directive in build.gradle.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/AndroidManifest.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/AndroidManifest.xml
deleted file mode 100644
index 2067474..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.layoutlib.test.myapplication" >
-<!-- If changing package here, update LayoutLibCallBack in tests. -->
-    <application
-        android:allowBackup="true"
-        android:icon="@drawable/ic_launcher"
-        android:label="@string/app_name"
-        android:theme="@style/AppTheme" >
-        <activity
-            android:name="com.android.layoutlib.test.myapplication.MyActivity"
-            android:label="@string/app_name" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-
-</manifest>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/ArraysCheckWidget.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/ArraysCheckWidget.java
deleted file mode 100644
index e7f22bf..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/ArraysCheckWidget.java
+++ /dev/null
@@ -1,57 +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.layoutlib.test.myapplication;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.AttributeSet;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-/**
- * A widget to test obtaining arrays from resources.
- */
-public class ArraysCheckWidget extends LinearLayout {
-    public ArraysCheckWidget(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public ArraysCheckWidget(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public ArraysCheckWidget(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        Resources resources = context.getResources();
-        for (CharSequence chars : resources.getTextArray(R.array.array)) {
-            addTextView(context, chars);
-        }
-        for (int i : resources.getIntArray(R.array.int_array)) {
-            addTextView(context, String.valueOf(i));
-        }
-        for (String string : resources.getStringArray(R.array.string_array)) {
-            addTextView(context, string);
-        }
-    }
-
-    private void addTextView(Context context, CharSequence string) {
-        TextView textView = new TextView(context);
-        textView.setText(string);
-        textView.setTextSize(30);
-        addView(textView);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/MyActivity.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/MyActivity.java
deleted file mode 100644
index 59de457..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/MyActivity.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.android.layoutlib.test.myapplication;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
-
-public class MyActivity extends Activity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity);
-    }
-
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        // Inflate the menu; this adds items to the action bar if it is present.
-        getMenuInflater().inflate(R.menu.my, menu);
-        return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        // Handle action bar item clicks here. The action bar will
-        // automatically handle clicks on the Home/Up button, so long
-        // as you specify a parent activity in AndroidManifest.xml.
-        int id = item.getItemId();
-        if (id == R.id.action_settings) {
-            return true;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java
deleted file mode 100644
index 3b819e5..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java
+++ /dev/null
@@ -1,47 +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.layoutlib.test.myapplication.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.CalendarView;
-
-public class CustomCalendar extends CalendarView {
-    public CustomCalendar(Context context) {
-        super(context);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init();
-    }
-
-    private void init() {
-        setDate(871732800000L, false, true);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java
deleted file mode 100644
index f3877f1..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java
+++ /dev/null
@@ -1,47 +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.layoutlib.test.myapplication.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.DatePicker;
-
-public class CustomDate extends DatePicker {
-    public CustomDate(Context context) {
-        super(context);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init();
-    }
-
-    private void init() {
-        init(2015, 0, 20, null);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/InsetsWidget.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/InsetsWidget.java
deleted file mode 100644
index 36e5c26..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/InsetsWidget.java
+++ /dev/null
@@ -1,43 +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.layoutlib.test.myapplication.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.WindowInsets;
-import android.widget.TextView;
-
-public class InsetsWidget extends TextView {
-    public static boolean sApplyInsetsCalled = false;
-
-    public InsetsWidget(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        requestApplyInsets();
-    }
-
-    @Override
-    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        sApplyInsetsCalled = true;
-        return super.onApplyWindowInsets(insets);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java
deleted file mode 100644
index 58ad46d..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * This package contains custom widgets used to set a specific time for the DayTimePicker during
- * testing.
- * The classes here are both used from the Android project and from the Bridge test project.
- */
-package com.android.layoutlib.test.myapplication.widgets;
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/color/gradient.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/color/gradient.xml
deleted file mode 100644
index fc0afa6..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/color/gradient.xml
+++ /dev/null
@@ -1,24 +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.
-  -->
-
-
-<gradient xmlns:android="http://schemas.android.com/apk/res/android"
-          android:startX="10"
-          android:startY="10"
-          android:endX="50"
-          android:endY="50"
-          android:startColor="#ffff0000"
-          android:endColor="#ff00ff00" />
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/adaptive.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/adaptive.xml
deleted file mode 100644
index 8f862c8..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/adaptive.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background android:drawable="@android:color/red" />
-    <foreground android:drawable="@drawable/headset" />
-</adaptive-icon>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/android.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/android.xml
deleted file mode 100644
index 42e3beb..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/android.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2016 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:viewportWidth="1102"
-        android:viewportHeight="642"
-        android:width="1102px"
-        android:height="642px">
-
-    <group
-        android:translateX="-126.347"
-        android:translateY="6.7928655e-4">
-
-
-        <path
-            android:fillColor="#94c147"
-            android:pathData="
-            m 552.777,147.57
-            c -14.147,0 -25.622,11.652 -25.622,26.02
-            v 101.68
-            c 0,14.372 11.475,26.019 25.622,26.019 14.147,0 25.61,-11.646 25.61,-26.019
-            V 173.59
-            c 0.001,-14.368 -11.462,-26.02 -25.61,-26.02
-            z
-
-            m -309.011,0
-            c -14.155,0 -25.618,11.652 -25.618,26.02
-            v 101.68
-            c 0,14.372 11.462,26.019 25.618,26.019 14.153,0 25.623,-11.646 25.623,-26.019
-            V 173.59
-            c -0.008,-14.368 -11.475,-26.02 -25.623,-26.02
-            z" />
-
-
-        <path
-        android:fillColor="#94c147"
-        android:pathData="m 284.799,148.364 v 185.768 c 0,11.035 8.948,19.98 19.983,19.98 h 22.815 v 56.567 c 0,14.37 11.47,26.016 25.623,26.016 14.148,0 25.623,-11.646 25.623,-26.016 v -56.567 h 39.878 v 56.567 c 0,14.37 11.463,26.016 25.61,26.016 14.147,0 25.622,-11.646 25.622,-26.016 v -56.567 h 22.828 c 11.022,0 19.971,-8.953 19.971,-19.98 V 148.364 H 284.799 l 0,0 z" />
-
-        <group
-        android:name="head"
-        android:pivotX="400"
-        android:pivotY="131.105">
-
-        <path
-        android:fillColor="#94c147"
-        android:pathData="m 452.302,52.105 21.057,-30.572 c 1.245,-1.819 0.939,-4.199 -0.695,-5.329 -1.637,-1.123 -3.968,-0.568 -5.225,1.251 l -21.875,31.75 c -14.404,-5.682 -30.418,-8.844 -47.293,-8.844 -16.87,0 -32.893,3.162 -47.297,8.844 l -21.875,-31.75 c -1.257,-1.819 -3.589,-2.375 -5.225,-1.251 -1.636,1.124 -1.946,3.509 -0.696,5.329 l 21.057,30.572 c -33.464,15.57 -56.951,45.166 -59.941,79.706 H 512.25 C 509.259,97.271 485.772,67.676 452.302,52.105 z M 350.187,100.28 c -6.965,0 -12.617,-5.646 -12.617,-12.616 0,-6.958 5.647,-12.61 12.617,-12.61 6.97,0 12.603,5.652 12.603,12.61 0,6.965 -5.64,12.616 -12.603,12.616 z m 97.744,0 c -6.97,0 -12.609,-5.646 -12.609,-12.616 0,-6.958 5.64,-12.61 12.609,-12.61 6.971,0 12.61,5.652 12.61,12.61 0,6.965 -5.64,12.616 -12.61,12.616 z" />
-        </group>
-
-    </group>
-
-</vector>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/headset.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/headset.xml
deleted file mode 100644
index 897c411..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/headset.xml
+++ /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.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="150dp"
-        android:height="150dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="m12,1c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-2c0,-3.87 3.13,-7 7,-7s7,3.13 7,7v2h-4v8h4v1h-7v2h6c1.66,0 3,-1.34 3,-3V10c0,-4.97 -4.03,-9 -9,-9z"/>
-</vector>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/ic_launcher.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/ic_launcher.xml
deleted file mode 100644
index 67481d4..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/ic_launcher.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <solid android:color="#ff0000" />
-    <size
-        android:width="20dp"
-        android:height="20dp" />
-</shape>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml
deleted file mode 100644
index 0998b25..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:height="76dp"
-        android:width="76dp"
-        android:viewportHeight="48"
-        android:viewportWidth="48"
-        android:alpha="0.6">
-
-    <group
-        android:name="root"
-        android:translateX="24.0"
-        android:translateY="24.0">
-        <!--
-            This is the same as the material indeterminate progressbar which involves drawing
-            several cubic segments
-        -->
-        <path
-            android:pathData="M0, 0 m 0, -19 a 19,19 0 1,1 0,38 a 19,19 0 1,1 0,-38"
-            android:strokeColor="#00FF00"
-            android:strokeLineCap="square"
-            android:strokeLineJoin="miter"
-            android:strokeWidth="1"
-            android:trimPathEnd="0.8"
-            android:trimPathStart="0.3" />
-        <!-- Same figure with reversed end and start -->
-        <path
-            android:pathData="M0, 0 m 0, -12 a 19,19 0 1,1 0,38 a 19,19 0 1,1 0,-38"
-            android:strokeColor="#FFFF00"
-            android:strokeLineCap="square"
-            android:strokeLineJoin="miter"
-            android:strokeWidth="1"
-            android:trimPathEnd="0.3"
-            android:trimPathStart="0.8" />
-
-        <!--
-            Draw a few partial quadratic segments
-        -->
-        <path
-            android:strokeWidth="2"
-            android:strokeColor="#FFFF00"
-            android:pathData="M2,2 Q 5 30 15 0"
-            android:trimPathStart="0.1"
-            android:trimPathEnd="0.9"
-        />
-
-        <!--
-            Draw a line
-        -->
-        <path
-            android:strokeWidth="3"
-            android:strokeColor="#00FFFF"
-            android:pathData="M-10,-10 L 10, 10"
-            android:trimPathStart="0.2"
-            android:trimPathEnd="0.8"
-        />
-
-        <!--
-            Draw a line with gradient stroke color
-        -->
-        <path
-            android:strokeWidth="1"
-            android:strokeColor="#FF00FF"
-            android:fillColor="@color/gradient"
-            android:pathData="M-20,-20 l0, 10 l10, 0 l0, -10 l-10,0 "
-        />
-
-        <!--
-            Draw squares with different fill types
-        -->
-        <path
-            android:fillType="evenOdd"
-            android:strokeWidth="1"
-            android:strokeColor="#AABBCC"
-            android:fillColor="#AAEFCC"
-            android:pathData="M-20,-40 l0, 10 l10, 0 l0, -10 l-10,0 m5,0 l0, 10 l10, 0 l0, -10 l-10,0"
-        />
-
-        <path
-            android:fillType="nonZero"
-            android:strokeWidth="1"
-            android:strokeColor="#AABBCC"
-            android:fillColor="#40AAEFCC"
-            android:pathData="M0,-40 l0, 10 l10, 0 l0, -10 l-10,0 m5,0 l0, 10 l10, 0 l0, -10 l-10,0"
-        />
-    </group>
-
-</vector>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfamily.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfamily.xml
deleted file mode 100644
index b1e9206..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfamily.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<font-family xmlns:android="http://schemas.android.com/apk/res/android">
-    <font android:fontStyle="normal" android:fontWeight="400" android:font="@font/testfont" />
-    <font android:fontStyle="italic" android:fontWeight="400" android:font="@font/testfont2" />
-</font-family>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/activity.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/activity.xml
deleted file mode 100644
index 97d19837..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/activity.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:paddingLeft="@dimen/activity_horizontal_margin"
-    android:paddingRight="@dimen/activity_horizontal_margin"
-    android:paddingTop="@dimen/activity_vertical_margin"
-    android:paddingBottom="@dimen/activity_vertical_margin"
-    tools:context=".MyActivity">
-
-    <TextView
-        android:text="@string/hello_world"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@+id/text1"/>
-
-    <include layout="@layout/layout"
-        android:layout_below="@+id/text1"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content" />
-</RelativeLayout>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/adaptive_icon.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/adaptive_icon.xml
deleted file mode 100644
index ca9fa55..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/adaptive_icon.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="horizontal"
-              android:layout_width="fill_parent"
-              android:layout_height="fill_parent">
-    <ImageView
-             android:layout_height="wrap_content"
-             android:layout_width="wrap_content"
-             android:src="@drawable/adaptive" />
-
-</LinearLayout>
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml
deleted file mode 100644
index 456b5f6..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml
+++ /dev/null
@@ -1,403 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:ignore="HardcodedText,LabelFor,TextFields,ContentDescription,RtlHardcoded">
-
-    <FrameLayout
-        android:id="@id/frameLayout"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentEnd="true"
-        android:layout_alignParentTop="true"
-        android:layout_marginEnd="311dp">
-
-        <TextView
-            android:id="@id/textView"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="left|top"
-            android:text="New Text" />
-    </FrameLayout>
-
-    <TextView
-        android:id="@id/textView2"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_below="@id/frameLayout"
-        android:text="Large Text"
-        android:textAppearance="?android:attr/textAppearanceLarge"
-        android:pointerIcon="hand" />
-
-    <TextView
-        android:id="@id/textView3"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:layout_toEndOf="@id/textView2"
-        android:text="Medium Text"
-        android:textAppearance="?android:attr/textAppearanceMedium" />
-
-    <TextView
-        android:id="@id/textView4"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignTop="@id/textView2"
-        android:layout_toEndOf="@id/textView2"
-        android:text="Small Text"
-        android:textAppearance="?android:attr/textAppearanceSmall" />
-
-    <Button
-        android:id="@id/button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/textView3"
-        android:layout_toEndOf="@id/textView4"
-        android:text="New Button" />
-
-    <Button
-        android:id="@id/button2"
-        style="?android:attr/buttonStyleSmall"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:layout_toEndOf="@id/button"
-        android:text="New Button" />
-
-    <CheckBox
-        android:id="@id/checkBox"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignEnd="@id/button"
-        android:layout_below="@id/button"
-        android:text="New CheckBox" />
-
-    <Switch
-        android:id="@id/switch1"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_below="@id/textView2"
-        android:text="New Switch" />
-
-    <ImageButton
-        android:id="@id/imageButton"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/button"
-        android:layout_toEndOf="@id/switch1" />
-
-    <ImageView
-        android:id="@id/imageView"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:src="@drawable/ic_launcher"
-        android:layout_below="@id/button"
-        android:layout_toEndOf="@id/imageButton" />
-
-    <GridLayout
-        android:id="@id/gridLayout"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_below="@id/imageButton"
-        android:columnCount="2"
-        android:rowCount="2">
-
-        <ProgressBar
-            android:id="@id/progressBar"
-            style="?android:attr/progressBarStyleLarge"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_column="0"
-            android:layout_row="0" />
-
-        <ProgressBar
-            android:id="@id/progressBar2"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_column="1"
-            android:layout_row="0" />
-
-        <ProgressBar
-            android:id="@id/progressBar3"
-            style="?android:attr/progressBarStyleSmall"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_column="0"
-            android:layout_row="1" />
-
-        <ProgressBar
-            android:id="@id/progressBar4"
-            style="?android:attr/progressBarStyleHorizontal"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_column="1"
-            android:layout_row="1" />
-    </GridLayout>
-
-    <SeekBar
-        android:id="@id/seekBar"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignTop="@id/gridLayout"
-        android:layout_toEndOf="@id/gridLayout" />
-
-    <RatingBar
-        android:id="@id/ratingBar"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/switch2"
-        android:layout_toEndOf="@id/gridLayout" />
-
-    <Switch
-        android:id="@id/switch2"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/seekBar"
-        android:layout_toEndOf="@id/switch1"
-        android:checked="true" />
-
-    <EditText
-        android:id="@id/editText"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignBottom="@id/ratingBar"
-        android:layout_alignParentStart="true"
-        android:text="plain text" />
-
-    <EditText
-        android:id="@id/editText2"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_below="@id/ratingBar"
-        android:ems="3"
-        android:inputType="textPersonName"
-        android:text="Name" />
-
-    <EditText
-        android:id="@id/editText3"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerVertical="true"
-        android:layout_toEndOf="@id/editText2"
-        android:ems="2"
-        android:inputType="textPassword"
-        android:text="password" />
-
-    <EditText
-        android:id="@id/editText4"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignTop="@id/editText3"
-        android:layout_toEndOf="@id/editText3"
-        android:ems="3"
-        android:inputType="numberPassword"
-        android:text="numeric password" />
-
-    <ToggleButton
-        android:id="@+id/toggleButton"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignTop="@id/editText4"
-        android:layout_toEndOf="@id/editText4"
-        android:text="New ToggleButton" />
-
-    <EditText
-        android:id="@id/editText5"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/editText3"
-        android:layout_toStartOf="@id/editText6"
-        android:ems="7"
-        android:inputType="textEmailAddress"
-        android:text="email@domain.com" />
-
-    <EditText
-        android:id="@id/editText6"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentEnd="true"
-        android:layout_below="@id/editText4"
-        android:ems="7"
-        android:inputType="phone"
-        android:text="+11235554344" />
-
-    <EditText
-        android:id="@id/editText7"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/editText"
-        android:layout_toEndOf="@id/editText4"
-        android:ems="10"
-        android:inputType="textPostalAddress"
-        android:text="1600 Amphitheatre" />
-
-    <EditText
-        android:id="@id/editText9"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/editText5"
-        android:layout_alignParentStart="true"
-        android:ems="3"
-        android:inputType="time"
-        android:text="12:12" />
-
-    <RadioGroup
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/editText5"
-        android:layout_toEndOf="@id/editText9"
-        android:orientation="horizontal">
-
-        <RadioButton
-            android:id="@id/radioButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="New RadioButton" />
-
-        <RadioButton
-            android:id="@id/radioButton2"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="New RadioButton"
-            android:checked="true" />
-
-    </RadioGroup>
-
-    <CheckedTextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="CheckedTextView"
-        android:id="@id/checkedTextView"
-        android:layout_below="@id/button2"
-        android:layout_alignParentEnd="true"
-        android:layout_alignStart="@id/button2" />
-
-    <DialerFilter
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/checkBox"
-        android:layout_toStartOf="@id/quickContactBadge"
-        android:id="@id/dialerFilter"
-        android:layout_above="@id/ratingBar"
-        android:layout_toEndOf="@id/seekBar">
-
-        <EditText
-            android:id="@android:id/hint"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="Hint" />
-
-        <EditText
-            android:id="@android:id/primary"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@android:id/hint"
-            android:text="Primary" />
-    </DialerFilter>
-
-    <QuickContactBadge
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/quickContactBadge"
-        android:layout_below="@id/checkedTextView"
-        android:layout_alignParentEnd="true" />
-
-    <android.inputmethodservice.ExtractEditText
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="ExtractEditText"
-        android:id="@id/extractEditText"
-        android:layout_below="@id/editText9"
-        android:layout_alignParentEnd="true"
-        android:layout_alignStart="@id/checkedTextView" />
-
-    <ZoomControls
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/zoomControls"
-        android:layout_below="@id/editText9"
-        android:layout_alignParentStart="true" />
-
-    <TextureView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/textureView"
-        android:layout_below="@id/zoomControls"
-        android:layout_alignParentStart="true"
-        android:layout_alignBottom="@id/extractEditText"
-        android:layout_toStartOf="@id/editText3" />
-
-    <ListView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/listView"
-        android:layout_below="@id/textureView"
-        android:layout_alignParentStart="true"
-        android:layout_alignEnd="@id/textureView" />
-
-    <GridView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/gridView"
-        android:layout_below="@id/extractEditText"
-        android:layout_alignParentEnd="true"
-        android:layout_alignStart="@id/extractEditText" />
-
-    <ScrollView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/scrollView"
-        android:layout_below="@id/zoomControls"
-        android:layout_toRightOf="@id/listView"
-        android:layout_toLeftOf="@id/extractEditText">
-
-    <TabHost
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:id="@id/tabHost">
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:orientation="vertical">
-
-            <TabWidget
-                android:id="@android:id/tabs"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"/>
-
-            <FrameLayout
-                android:id="@android:id/tabcontent"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent">
-
-                <LinearLayout
-                    android:id="@id/linearLayout"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:orientation="vertical"/>
-
-                <LinearLayout
-                    android:id="@id/linearLayout2"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:orientation="vertical"/>
-
-            </FrameLayout>
-        </LinearLayout>
-    </TabHost>
-</ScrollView>
-
-    <SearchView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/searchView"
-        android:layout_alignBottom="@id/zoomControls"
-        android:layout_toEndOf="@id/seekBar" />
-
-</RelativeLayout>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml
deleted file mode 100644
index e9aa9e1..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<com.android.layoutlib.test.myapplication.ArraysCheckWidget
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical" android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-</com.android.layoutlib.test.myapplication.ArraysCheckWidget>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_horz_layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_horz_layout.xml
deleted file mode 100644
index 2c66b7f..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_horz_layout.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="horizontal"
-              android:background="#AAAAAA"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content">
-
-    <include layout="@layout/expand_layout"
-             android:layout_height="wrap_content"
-             android:layout_width="wrap_content" />
-
-</LinearLayout>
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_layout.xml
deleted file mode 100644
index a255da7..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_layout.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <TextView
-        android:background="#FF0000"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-    <TextView
-        android:background="#00FF00"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-    <TextView
-        android:background="#0000FF"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-    <TextView
-        android:background="#FF00FF"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-    <TextView
-        android:background="#00FFFF"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-</merge>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_vert_layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_vert_layout.xml
deleted file mode 100644
index 5319654..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_vert_layout.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="vertical"
-              android:background="#AAAAAA"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content">
-
-    <include layout="@layout/expand_layout"
-             android:layout_height="wrap_content"
-             android:layout_width="wrap_content" />
-
-</LinearLayout>
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/fonts_test.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/fonts_test.xml
deleted file mode 100644
index c63b211..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/fonts_test.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical" android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="CONDENSED"
-        android:textSize="50sp"
-        android:fontFamily="sans-serif-condensed"
-        />
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="CONDENSED ITALIC"
-        android:textSize="30sp"
-        android:fontFamily="sans-serif-condensed"
-        android:textStyle="italic"
-        />
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="MONOSPACE"
-        android:textSize="50sp"
-        android:fontFamily="monospace"/>
-
-    <Space
-        android:layout_width="wrap_content"
-        android:layout_height="30dp" />
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Custom"
-        android:textSize="20sp"
-        android:fontFamily="@font/testfont"/>
-
-    <Space
-        android:layout_width="wrap_content"
-        android:layout_height="30dp" />
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Custom family"
-        android:textSize="20sp"
-        android:fontFamily="@font/testfamily"/>
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Custom family"
-        android:textSize="20sp"
-        android:fontFamily="@font/testfamily"
-        android:textStyle="italic"/>
-
-</LinearLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/four_corners.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/four_corners.xml
deleted file mode 100644
index c42284a..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/four_corners.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:layout_centerHorizontal="true"
-        android:textSize="40sp"
-        android:text="Bottom Text" />
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:layout_centerHorizontal="true"
-        android:textSize="40sp"
-        android:text="Top text" />
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_centerVertical="true"
-        android:textSize="40sp"
-        android:text="Start text" />
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentEnd="true"
-        android:layout_centerVertical="true"
-        android:textSize="40sp"
-        android:text="End text" />
-</RelativeLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/indeterminate_progressbar.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/indeterminate_progressbar.xml
deleted file mode 100644
index 70d7396..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/indeterminate_progressbar.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="horizontal"
-              android:layout_width="fill_parent"
-              android:layout_height="fill_parent">
-
-    <ProgressBar
-             android:layout_height="fill_parent"
-             android:layout_width="fill_parent" />
-
-</LinearLayout>
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/insets.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/insets.xml
deleted file mode 100644
index ff06d79..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/insets.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="horizontal"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content">
-
-    <com.android.layoutlib.test.myapplication.widgets.InsetsWidget
-        android:text="Hello world"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@+id/text1"/>
-</LinearLayout>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml
deleted file mode 100644
index ff14ce0..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:columnCount="2"
-    android:layout_height="match_parent">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Some text"/>
-    <Switch
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:checked="true"
-        android:layout_gravity="center"
-        />
-    <com.android.layoutlib.test.myapplication.widgets.CustomDate
-        android:layout_width="100dp"
-        android:layout_height="wrap_content"/>
-    <com.android.layoutlib.test.myapplication.widgets.CustomCalendar
-        android:layout_width="200dp"
-        android:layout_gravity="center_horizontal"
-        android:layout_height="200dp"/>
-</GridLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml
deleted file mode 100644
index a07498c..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:orientation="vertical"
-              android:scrollX="30px"
-              android:scrollY="90px">
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="60dp"
-        android:background="#FF0000" />
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="30dp"
-        android:background="#00FF00" />
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="60dp"
-        android:background="#0000FF" />
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="30dp"
-        android:background="#FF00FF" />
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="60dp"
-        android:background="#00FFFF" />
-
-    <LinearLayout
-        android:layout_width="200dp"
-        android:layout_height="400dp"
-        android:orientation="vertical"
-        android:scrollX="-90px"
-        android:scrollY="450px">
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="60dp"
-            android:background="#FF0000" />
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="30dp"
-            android:background="#00FF00" />
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="60dp"
-            android:background="#0000FF" />
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="30dp"
-            android:background="#FF00FF" />
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="60dp"
-            android:background="#00FFFF" />
-    </LinearLayout>
-
-
-</LinearLayout>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/shadows_test.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/shadows_test.xml
deleted file mode 100644
index b1d6a60..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/shadows_test.xml
+++ /dev/null
@@ -1,97 +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.
-  -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:orientation="vertical"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent" >
-
-    <RelativeLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_weight="1">
-
-        <Button
-            android:layout_marginLeft="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentLeft="true"
-            android:layout_centerVertical="true"
-            android:elevation="48dp"
-            android:stateListAnimator="@null"/>
-
-        <Button
-            android:layout_marginRight="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentRight="true"
-            android:layout_centerVertical="true"
-            android:elevation="48dp"
-            android:stateListAnimator="@null"/>
-
-    </RelativeLayout>
-
-    <RelativeLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_weight="1">
-
-        <Button
-            android:layout_marginLeft="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentLeft="true"
-            android:layout_centerVertical="true"
-            android:elevation="0dp"
-            android:stateListAnimator="@null"/>
-
-        <Button
-            android:layout_marginRight="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentRight="true"
-            android:layout_centerVertical="true"
-            android:elevation="108dp"
-            android:stateListAnimator="@null"/>
-
-    </RelativeLayout>
-
-    <RelativeLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_weight="1">
-
-        <Button
-            android:layout_marginLeft="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentLeft="true"
-            android:layout_centerVertical="true"
-            android:elevation="12dp"
-            android:stateListAnimator="@null"/>
-
-        <Button
-            android:layout_marginRight="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentRight="true"
-            android:layout_centerVertical="true"
-            android:elevation="108dp"
-            android:stateListAnimator="@null"/>
-
-    </RelativeLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/simple_activity.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/simple_activity.xml
deleted file mode 100644
index 14b93f3..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/simple_activity.xml
+++ /dev/null
@@ -1,32 +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.
-  -->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:paddingLeft="@dimen/activity_horizontal_margin"
-                android:paddingRight="@dimen/activity_horizontal_margin"
-                android:paddingTop="@dimen/activity_vertical_margin"
-                android:paddingBottom="@dimen/activity_vertical_margin">
-
-    <TextView
-        android:text="@string/hello_world"
-        android:layout_width="wrap_content"
-        android:layout_height="200dp"
-        android:background="#FF0000"
-        android:id="@+id/text1"/>
-
-</RelativeLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable.xml
deleted file mode 100644
index 2ce4f4c..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="horizontal"
-              android:layout_width="fill_parent"
-              android:layout_height="fill_parent">
-    <ImageView
-             android:layout_height="fill_parent"
-             android:layout_width="fill_parent"
-             android:src="@drawable/multi_path" />
-
-</LinearLayout>
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable_android.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable_android.xml
deleted file mode 100644
index 3b01ea0..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable_android.xml
+++ /dev/null
@@ -1,34 +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.
-  -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="vertical"
-              android:layout_width="fill_parent"
-              android:layout_height="fill_parent">
-    <ImageView
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:src="@drawable/android"/>
-    <ImageView
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:src="@drawable/headset"/>
-
-</LinearLayout>
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/menu/my.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/menu/my.xml
deleted file mode 100644
index bea58cc..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/menu/my.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    tools:context=".MyActivity" >
-    <item android:id="@+id/action_settings"
-        android:title="@string/action_settings"
-        android:orderInCategory="100"
-        android:showAsAction="never" />
-</menu>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/arrays.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/arrays.xml
deleted file mode 100644
index 5f58d39..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/arrays.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <array name="array">
-        <item>first</item>
-        <item>second</item>
-    </array>
-    <integer-array name="int_array">
-        <item>1</item>
-        <item>0xaB</item>  <!-- hex entry (decimal 171) -->
-        <item>010</item>   <!-- octal entry -->
-        <item>@integer/ten</item>  <!-- value reference -->
-        <item>?attr/myattr</item>  <!-- theme attr reference -->
-    </integer-array>
-    <string-array name="string_array">
-        <item>mystring</item>
-        <item>@string/hello_world</item>   <!-- string ref in appNs -->
-        <!-- theme ref in android NS. value = @string/candidates_style = <u>candidates</u> -->
-        <item>?android:attr/candidatesTextStyleSpans</item>
-        <item>@android:string/unknownName</item>  <!-- value = Unknown -->
-        <item>?EC</item>
-    </string-array>
-
-    <!-- resources that the above array can refer to -->
-    <integer name="ten">10</integer>
-    <integer name="twelve">12</integer>
-</resources>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/attrs.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/attrs.xml
deleted file mode 100644
index 894e18c..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/attrs.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <attr name="myattr" format="integer" />
-</resources>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/ids.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/ids.xml
deleted file mode 100644
index 1dc2fa0..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/ids.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <item type="id" name="button" />
-    <item type="id" name="button2" />
-    <item type="id" name="checkBox" />
-    <item type="id" name="checkedTextView" />
-    <item type="id" name="dialerFilter" />
-    <item type="id" name="editText" />
-    <item type="id" name="editText2" />
-    <item type="id" name="editText3" />
-    <item type="id" name="editText4" />
-    <item type="id" name="editText5" />
-    <item type="id" name="editText6" />
-    <item type="id" name="editText7" />
-    <item type="id" name="editText8" />
-    <item type="id" name="editText9" />
-    <item type="id" name="extractEditText" />
-    <item type="id" name="frameLayout" />
-    <item type="id" name="gridLayout" />
-    <item type="id" name="gridView" />
-    <item type="id" name="imageButton" />
-    <item type="id" name="imageView" />
-    <item type="id" name="linearLayout" />
-    <item type="id" name="linearLayout2" />
-    <item type="id" name="listView" />
-    <item type="id" name="progressBar" />
-    <item type="id" name="progressBar2" />
-    <item type="id" name="progressBar3" />
-    <item type="id" name="progressBar4" />
-    <item type="id" name="quickContactBadge" />
-    <item type="id" name="radioButton" />
-    <item type="id" name="radioButton2" />
-    <item type="id" name="ratingBar" />
-    <item type="id" name="scrollView" />
-    <item type="id" name="searchView" />
-    <item type="id" name="seekBar" />
-    <item type="id" name="spinner" />
-    <item type="id" name="switch1" />
-    <item type="id" name="switch2" />
-    <item type="id" name="tabHost" />
-    <item type="id" name="textView" />
-    <item type="id" name="textView2" />
-    <item type="id" name="textView3" />
-    <item type="id" name="textView4" />
-    <item type="id" name="textureView" />
-    <item type="id" name="zoomControls" />
-</resources>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/strings.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/strings.xml
deleted file mode 100644
index 2b7083b..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-    <string name="app_name">My Application</string>
-    <string name="hello_world">Hello world!</string>
-    <string name="action_settings">Settings</string>
-
-</resources>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml
deleted file mode 100644
index debe33b..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<resources>
-
-    <!-- Base application theme. -->
-    <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
-        <item name="myattr">@integer/ten</item>
-    </style>
-
-</resources>
diff --git a/tools/layoutlib/bridge/tests/src/android/app/SystemServiceRegistry_AccessorTest.java b/tools/layoutlib/bridge/tests/src/android/app/SystemServiceRegistry_AccessorTest.java
deleted file mode 100644
index 4f1c16c..0000000
--- a/tools/layoutlib/bridge/tests/src/android/app/SystemServiceRegistry_AccessorTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app;
-
-import org.junit.Test;
-
-import android.content.Context;
-import android.hardware.input.InputManager;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityManager;
-
-import static org.junit.Assert.*;
-
-public class SystemServiceRegistry_AccessorTest {
-    @Test
-    public void testRegistry() {
-        // Just check a few services to make sure we don't break the accessor
-        assertEquals(Context.ACCESSIBILITY_SERVICE,
-                SystemServiceRegistry_Accessor.getSystemServiceName(AccessibilityManager.class));
-        assertEquals(Context.INPUT_SERVICE,
-                SystemServiceRegistry_Accessor.getSystemServiceName(InputManager.class));
-        assertEquals(Context.WINDOW_SERVICE,
-                SystemServiceRegistry_Accessor.getSystemServiceName(WindowManager.class));
-    }
-}
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java b/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java
deleted file mode 100644
index d20fb14..0000000
--- a/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import junit.framework.TestCase;
-
-/**
- *
- */
-public class Matrix_DelegateTest extends TestCase {
-
-    public void testIdentity() {
-        Matrix m1 = new Matrix();
-
-        assertTrue(m1.isIdentity());
-
-        m1.setValues(new float[] { 1,0,0, 0,1,0, 0,0,1 });
-        assertTrue(m1.isIdentity());
-    }
-
-    public void testCopyConstructor() {
-        Matrix m1 = new Matrix();
-        Matrix m2 = new Matrix(m1);
-
-        float[] v1 = new float[9];
-        float[] v2 = new float[9];
-        m1.getValues(v1);
-        m2.getValues(v2);
-
-        for (int i = 0 ; i < 9; i++) {
-            assertEquals(v1[i], v2[i]);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/android/util/BridgeXmlPullAttributesTest.java b/tools/layoutlib/bridge/tests/src/android/util/BridgeXmlPullAttributesTest.java
deleted file mode 100644
index 2fcec8e..0000000
--- a/tools/layoutlib/bridge/tests/src/android/util/BridgeXmlPullAttributesTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.BridgeContext;
-
-import org.junit.Test;
-import org.xmlpull.v1.XmlPullParser;
-
-import com.google.common.collect.ImmutableMap;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class BridgeXmlPullAttributesTest {
-    @Test
-    public void testGetAttributeIntValueForEnums() {
-        RenderResources renderResources = new RenderResources();
-
-        XmlPullParser parser = mock(XmlPullParser.class);
-        when(parser.getAttributeValue(BridgeConstants.NS_RESOURCES, "layout_width"))
-                .thenReturn("match_parent");
-        when(parser.getAttributeName(0)).thenReturn("layout_width");
-        when(parser.getAttributeNamespace(0)).thenReturn(BridgeConstants.NS_RESOURCES);
-        // Return every value twice since there is one test using name and other using index
-        when(parser.getAttributeValue("http://custom", "my_custom_attr"))
-                .thenReturn("a", "a", "b", "b", "invalid", "invalid");
-        when(parser.getAttributeName(1)).thenReturn("my_custom_attr");
-        when(parser.getAttributeNamespace(1)).thenReturn("http://custom");
-
-        BridgeContext context = mock(BridgeContext.class);
-        when(context.getRenderResources()).thenReturn(renderResources);
-
-        BridgeXmlPullAttributes attributes = new BridgeXmlPullAttributes(
-                parser,
-                context,
-                false,
-                attrName -> {
-                    if ("layout_width".equals(attrName)) {
-                        return ImmutableMap.of(
-                                "match_parent", 123);
-                    }
-                    return ImmutableMap.of();
-                },
-                attrName -> {
-                    if ("my_custom_attr".equals(attrName)) {
-                        return ImmutableMap.of(
-                                "a", 1,
-                                "b", 2
-                        );
-                    }
-                    return ImmutableMap.of();
-                });
-
-        // Test a framework defined enum attribute
-        assertEquals(123, attributes.getAttributeIntValue(BridgeConstants.NS_RESOURCES,
-                "layout_width", 500));
-        assertEquals(123, attributes.getAttributeIntValue(0, 500));
-        // Test non existing attribute (it should return the default value)
-        assertEquals(500, attributes.getAttributeIntValue(BridgeConstants.NS_RESOURCES,
-                "layout_height", 500));
-        assertEquals(500, attributes.getAttributeIntValue(2, 500));
-
-        // Test project defined enum attribute
-        assertEquals(1, attributes.getAttributeIntValue("http://custom",
-                "my_custom_attr", 500));
-        assertEquals(1, attributes.getAttributeIntValue(1, 500));
-        assertEquals(2, attributes.getAttributeIntValue("http://custom",
-                "my_custom_attr", 500));
-        assertEquals(2, attributes.getAttributeIntValue(1, 500));
-        // Test an invalid enum
-        boolean exception = false;
-        try {
-            attributes.getAttributeIntValue("http://custom", "my_custom_attr", 500);
-        } catch(NumberFormatException e) {
-            exception = true;
-        }
-        assertTrue(exception);
-        exception = false;
-        try {
-            attributes.getAttributeIntValue(1, 500);
-        } catch(NumberFormatException e) {
-            exception = true;
-        }
-        assertTrue(exception);
-
-        // Test non existing project attribute
-        assertEquals(500, attributes.getAttributeIntValue("http://custom",
-                "my_other_attr", 500));
-    }
-
-}
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java
deleted file mode 100644
index 63b9b43..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java
+++ /dev/null
@@ -1,37 +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.layoutlib.bridge;
-
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-public class BridgeRenderSessionTest {
-    @Test
-    public void testNullSession() {
-        BridgeRenderSession renderSession = new BridgeRenderSession(null, Status.ERROR_UNKNOWN
-                .createResult("Test result"));
-
-        assertNotNull(renderSession.getImage());
-        assertNotNull(renderSession.getRootViews());
-        assertNotNull(renderSession.getSystemRootViews());
-        assertNotNull(renderSession.getDefaultProperties());
-    }
-}
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
deleted file mode 100644
index d8937f4..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.create.CreateInfo;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-/**
- * Tests that native delegate classes implement all the required methods.
- *
- * This looks at {@link CreateInfo#DELEGATE_CLASS_NATIVES} to get the list of classes that
- * have their native methods reimplemented through a delegate.
- *
- * Since the reimplemented methods are not native anymore, we look for the annotation
- * {@link LayoutlibDelegate}, and look for a matching method in the delegate (named the same
- * as the modified class with _Delegate added as a suffix).
- * If the original native method is not static, then we make sure the delegate method also
- * include the original class as first parameter (to access "this").
- *
- */
-public class TestDelegates extends TestCase {
-
-    private List<String> mErrors = new ArrayList<String>();
-
-    public void testNativeDelegates() {
-
-        final String[] classes = CreateInfo.DELEGATE_CLASS_NATIVES;
-        mErrors.clear();
-        for (String clazz : classes) {
-            loadAndCompareClasses(clazz, clazz + "_Delegate");
-        }
-        assertTrue(getErrors(), mErrors.isEmpty());
-    }
-
-    public void testMethodDelegates() {
-        final String[] methods = CreateInfo.DELEGATE_METHODS;
-        mErrors.clear();
-        for (String methodName : methods) {
-            // extract the class name
-            String className = methodName.substring(0, methodName.indexOf('#'));
-            String targetClassName = className.replace('$', '_') + "_Delegate";
-
-            loadAndCompareClasses(className, targetClassName);
-        }
-        assertTrue(getErrors(), mErrors.isEmpty());
-    }
-
-    private void loadAndCompareClasses(String originalClassName, String delegateClassName) {
-        // load the classes
-        try {
-            ClassLoader classLoader = TestDelegates.class.getClassLoader();
-            Class<?> originalClass = classLoader.loadClass(originalClassName);
-            Class<?> delegateClass = classLoader.loadClass(delegateClassName);
-
-            compare(originalClass, delegateClass);
-        } catch (ClassNotFoundException e) {
-            mErrors.add("Failed to load class: " + e.getMessage());
-        } catch (SecurityException e) {
-            mErrors.add("Failed to load class: " + e.getMessage());
-        }
-    }
-
-    private void compare(Class<?> originalClass, Class<?> delegateClass) throws SecurityException {
-        List<Method> checkedDelegateMethods = new ArrayList<Method>();
-
-        // loop on the methods of the original class, and for the ones that are annotated
-        // with @LayoutlibDelegate, look for a matching method in the delegate class.
-        // The annotation is automatically added by layoutlib_create when it replace a method
-        // by a call to a delegate
-        Method[] originalMethods = originalClass.getDeclaredMethods();
-        for (Method originalMethod : originalMethods) {
-            // look for methods that are delegated: they have the LayoutlibDelegate annotation
-            if (originalMethod.getAnnotation(LayoutlibDelegate.class) == null) {
-                continue;
-            }
-
-            // get the signature.
-            Class<?>[] parameters = originalMethod.getParameterTypes();
-
-            // if the method is not static, then the class is added as the first parameter
-            // (for "this")
-            if ((originalMethod.getModifiers() & Modifier.STATIC) == 0) {
-
-                Class<?>[] newParameters = new Class<?>[parameters.length + 1];
-                newParameters[0] = originalClass;
-                System.arraycopy(parameters, 0, newParameters, 1, parameters.length);
-                parameters = newParameters;
-            }
-
-            // if the original class is an inner class that's not static, then
-            // we add this on the enclosing class at the beginning
-            if (originalClass.getEnclosingClass() != null &&
-                    (originalClass.getModifiers() & Modifier.STATIC) == 0) {
-                Class<?>[] newParameters = new Class<?>[parameters.length + 1];
-                newParameters[0] = originalClass.getEnclosingClass();
-                System.arraycopy(parameters, 0, newParameters, 1, parameters.length);
-                parameters = newParameters;
-            }
-
-            try {
-                // try to load the method with the given parameter types.
-                Method delegateMethod = delegateClass.getDeclaredMethod(originalMethod.getName(),
-                        parameters);
-
-                // check the return type of the methods match.
-                if (delegateMethod.getReturnType() != originalMethod.getReturnType()) {
-                    mErrors.add(
-                            String.format("Delegate method %1$s.%2$s does not match the " +
-                                    "corresponding framework method which returns %3$s",
-                            delegateClass.getName(),
-                            getMethodName(delegateMethod),
-                            originalMethod.getReturnType().getName()));
-                }
-
-                // check that the method has the annotation
-                if (delegateMethod.getAnnotation(LayoutlibDelegate.class) == null) {
-                    mErrors.add(
-                            String.format("Delegate method %1$s for class %2$s does not have the " +
-                                            "@LayoutlibDelegate annotation",
-                                    delegateMethod.getName(),
-                                    originalClass.getName()));
-                }
-
-                // check that the method is static
-                if ((delegateMethod.getModifiers() & Modifier.STATIC) != Modifier.STATIC) {
-                    mErrors.add(
-                            String.format(
-                                    "Delegate method %1$s for class %2$s is not static",
-                                    delegateMethod.getName(),
-                                    originalClass.getName())
-                    );
-                }
-
-                // add the method as checked.
-                checkedDelegateMethods.add(delegateMethod);
-            } catch (NoSuchMethodException e) {
-                String name = getMethodName(originalMethod, parameters);
-                mErrors.add(String.format("Missing %1$s.%2$s", delegateClass.getName(), name));
-            }
-        }
-
-        // look for dead (delegate) code.
-        // This looks for all methods in the delegate class, and if they have the
-        // @LayoutlibDelegate annotation, make sure they have been previously found as a
-        // match for a method in the original class.
-        // If not, this means the method is a delegate for a method that either doesn't exist
-        // anymore or is not delegated anymore.
-        Method[] delegateMethods = delegateClass.getDeclaredMethods();
-        for (Method delegateMethod : delegateMethods) {
-            // look for methods that are delegates: they have the LayoutlibDelegate annotation
-            if (delegateMethod.getAnnotation(LayoutlibDelegate.class) == null) {
-                continue;
-            }
-
-            if (!checkedDelegateMethods.contains(delegateMethod)) {
-                mErrors.add(String.format(
-                        "Delegate method %1$s.%2$s is not used anymore and must be removed",
-                        delegateClass.getName(),
-                        getMethodName(delegateMethod)));
-            }
-        }
-
-    }
-
-    private String getMethodName(Method method) {
-        return getMethodName(method, method.getParameterTypes());
-    }
-
-    private String getMethodName(Method method, Class<?>[] parameters) {
-        // compute a full class name that's long but not too long.
-        StringBuilder sb = new StringBuilder(method.getName() + "(");
-        for (int j = 0; j < parameters.length; j++) {
-            Class<?> theClass = parameters[j];
-            int dimensions = 0;
-            while (theClass.isArray()) {
-                dimensions++;
-                theClass = theClass.getComponentType();
-            }
-            sb.append(theClass.getName());
-            for (int i = 0; i < dimensions; i++) {
-                sb.append("[]");
-            }
-            if (j < (parameters.length - 1)) {
-                sb.append(",");
-            }
-        }
-        sb.append(")");
-
-        return sb.toString();
-    }
-
-    private String getErrors() {
-        StringBuilder s = new StringBuilder();
-        for (String error : mErrors) {
-            s.append(error).append('\n');
-        }
-        return s.toString();
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
deleted file mode 100644
index 77c997b..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.layoutlib.bridge.impl.ParserFactory;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.kxml2.io.KXmlParser;
-import org.w3c.dom.Node;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-
-import static org.junit.Assert.assertEquals;
-
-public class BridgeXmlBlockParserTest {
-
-    @BeforeClass
-    public static void setUp() {
-        ParserFactory.setParserFactory(new ParserFactoryImpl());
-    }
-
-    @Test
-    public void testXmlBlockParser() throws Exception {
-
-        XmlPullParser parser = ParserFactory.create(
-                getClass().getResourceAsStream("/com/android/layoutlib/testdata/layout1.xml"),
-                        "layout1.xml");
-
-        parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */);
-
-        assertEquals(XmlPullParser.START_DOCUMENT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("LinearLayout", parser.getName());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("Button", parser.getName());
-        assertEquals(XmlPullParser.TEXT, parser.next());
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("View", parser.getName());
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("TextView", parser.getName());
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-        assertEquals(XmlPullParser.END_DOCUMENT, parser.next());
-    }
-
-    //------------
-
-    /**
-     * Quick 'n' dirty debug helper that dumps an XML structure to stdout.
-     */
-    @SuppressWarnings("unused")
-    private void dump(Node node, String prefix) {
-        Node n;
-
-        String[] types = {
-                "unknown",
-                "ELEMENT_NODE",
-                "ATTRIBUTE_NODE",
-                "TEXT_NODE",
-                "CDATA_SECTION_NODE",
-                "ENTITY_REFERENCE_NODE",
-                "ENTITY_NODE",
-                "PROCESSING_INSTRUCTION_NODE",
-                "COMMENT_NODE",
-                "DOCUMENT_NODE",
-                "DOCUMENT_TYPE_NODE",
-                "DOCUMENT_FRAGMENT_NODE",
-                "NOTATION_NODE"
-        };
-
-        String s = String.format("%s<%s> %s %s",
-                prefix,
-                types[node.getNodeType()],
-                node.getNodeName(),
-                node.getNodeValue() == null ? "" : node.getNodeValue().trim());
-
-        System.out.println(s);
-
-        n = node.getFirstChild();
-        if (n != null) {
-            dump(n, prefix + "- ");
-        }
-
-        n = node.getNextSibling();
-        if (n != null) {
-            dump(n, prefix);
-        }
-    }
-
-    @AfterClass
-    public static void tearDown() {
-        ParserFactory.setParserFactory(null);
-    }
-
-    private static class ParserFactoryImpl
-            extends com.android.ide.common.rendering.api.ParserFactory {
-
-        @NonNull
-        @Override
-        public XmlPullParser createParser(String displayName) throws XmlPullParserException {
-            return new KXmlParser();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/impl/LayoutParserWrapperTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/impl/LayoutParserWrapperTest.java
deleted file mode 100644
index 2c33862..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/impl/LayoutParserWrapperTest.java
+++ /dev/null
@@ -1,183 +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.layoutlib.bridge.impl;
-
-import org.junit.Test;
-import org.kxml2.io.KXmlParser;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.StringReader;
-
-import static com.android.SdkConstants.NS_RESOURCES;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotSame;
-import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
-import static org.xmlpull.v1.XmlPullParser.END_TAG;
-import static org.xmlpull.v1.XmlPullParser.START_TAG;
-
-
-public class LayoutParserWrapperTest {
-    @Test
-    @SuppressWarnings("StatementWithEmptyBody")  // some for loops need to be empty statements.
-    public void testDataBindingLayout() throws Exception {
-        LayoutParserWrapper parser = getParserFromString(sDataBindingLayout);
-        parser.peekTillLayoutStart();
-        assertEquals("Expected START_TAG", START_TAG, parser.next());
-        assertEquals("RelativeLayout", parser.getName());
-        for (int next = parser.next(); next != START_TAG && next != END_DOCUMENT;
-             next = parser.next());
-        assertEquals("Expected START_TAG", START_TAG, parser.getEventType());
-        assertEquals("TextView", parser.getName());
-        assertEquals("layout_width incorrect for first text view.", "wrap_content",
-                parser.getAttributeValue(NS_RESOURCES, "layout_width"));
-        // Ensure that data-binding part is stripped.
-        assertEquals("Bound attribute android:text incorrect", "World",
-                parser.getAttributeValue(NS_RESOURCES, "text"));
-        assertEquals("resource attribute 'id' for first text view incorrect.", "@+id/first",
-                parser.getAttributeValue(NS_RESOURCES, "id"));
-        for (int next = parser.next();
-             (next != END_TAG || !"RelativeLayout".equals(parser.getName())) && next != END_DOCUMENT;
-             next = parser.next());
-        assertNotSame("Unexpected end of document", END_DOCUMENT, parser.getEventType());
-        assertEquals("Document didn't end when expected.", END_DOCUMENT, parser.next());
-    }
-
-    @Test
-    @SuppressWarnings("StatementWithEmptyBody")
-    public void testNonDataBindingLayout() throws Exception {
-        LayoutParserWrapper parser = getParserFromString(sNonDataBindingLayout);
-        parser.peekTillLayoutStart();
-        assertEquals("Expected START_TAG", START_TAG, parser.next());
-        assertEquals("RelativeLayout", parser.getName());
-        for (int next = parser.next(); next != START_TAG && next != END_DOCUMENT;
-             next = parser.next());
-        assertEquals("Expected START_TAG", START_TAG, parser.getEventType());
-        assertEquals("TextView", parser.getName());
-        assertEquals("layout_width incorrect for first text view.", "wrap_content",
-                parser.getAttributeValue(NS_RESOURCES, "layout_width"));
-        // Ensure that value isn't modified.
-        assertEquals("Bound attribute android:text incorrect", "@{user.firstName,default=World}",
-                parser.getAttributeValue(NS_RESOURCES, "text"));
-        assertEquals("resource attribute 'id' for first text view incorrect.", "@+id/first",
-                parser.getAttributeValue(NS_RESOURCES, "id"));
-        for (int next = parser.next();
-             (next != END_TAG || !"RelativeLayout".equals(parser.getName())) && next != END_DOCUMENT;
-             next = parser.next());
-        assertNotSame("Unexpected end of document", END_DOCUMENT, parser.getEventType());
-        assertEquals("Document didn't end when expected.", END_DOCUMENT, parser.next());
-    }
-
-    private static LayoutParserWrapper getParserFromString(String layoutContent) throws
-            XmlPullParserException {
-        XmlPullParser parser = new KXmlParser();
-        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-        parser.setInput(new StringReader(layoutContent));
-        return new LayoutParserWrapper(parser);
-    }
-
-    private static final String sDataBindingLayout =
-            //language=XML
-            "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
-                    "<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
-                    "        xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" +
-                    "        xmlns:tools=\"http://schemas.android.com/tools\"\n" +
-                    "        tools:context=\".MainActivity\"\n" +
-                    "        tools:showIn=\"@layout/activity_main\">\n" +
-                    "\n" +
-                    "    <data>\n" +
-                    "\n" +
-                    "        <variable\n" +
-                    "            name=\"user\"\n" +
-                    "            type=\"com.example.User\" />\n" +
-                    "        <variable\n" +
-                    "            name=\"activity\"\n" +
-                    "            type=\"com.example.MainActivity\" />\n" +
-                    "    </data>\n" +
-                    "\n" +
-                    "    <RelativeLayout\n" +
-                    "        android:layout_width=\"match_parent\"\n" +
-                    "        android:layout_height=\"match_parent\"\n" +
-                    "        android:paddingBottom=\"@dimen/activity_vertical_margin\"\n" +
-                    "        android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n" +
-                    "        android:paddingRight=\"@dimen/activity_horizontal_margin\"\n" +
-                    "        android:paddingTop=\"@dimen/activity_vertical_margin\"\n" +
-                    "        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n" +
-                    "    >\n" +
-                    "\n" +
-                    "        <TextView\n" +
-                    "            android:id=\"@+id/first\"\n" +
-                    "            android:layout_width=\"wrap_content\"\n" +
-                    "            android:layout_alignParentStart=\"true\"\n" +
-                    "            android:layout_alignParentLeft=\"true\"\n" +
-                    "            android:layout_height=\"wrap_content\"\n" +
-                    "            android:text=\"@{user.firstName,default=World}\" />\n" +
-                    "\n" +
-                    "        <TextView\n" +
-                    "            android:id=\"@+id/last\"\n" +
-                    "            android:layout_width=\"wrap_content\"\n" +
-                    "            android:layout_height=\"wrap_content\"\n" +
-                    "            android:layout_toEndOf=\"@id/first\"\n" +
-                    "            android:layout_toRightOf=\"@id/first\"\n" +
-                    "            android:text=\"@{user.lastName,default=Hello}\" />\n" +
-                    "\n" +
-                    "        <Button\n" +
-                    "            android:layout_width=\"wrap_content\"\n" +
-                    "            android:layout_height=\"wrap_content\"\n" +
-                    "            android:layout_below=\"@id/last\"\n" +
-                    "            android:text=\"Submit\"\n" +
-                    "            android:onClick=\"@{activity.onClick}\"/>\n" +
-                    "    </RelativeLayout>\n" +
-                    "</layout>";
-
-    private static final String sNonDataBindingLayout =
-            //language=XML
-            "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
-                    "    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" +
-                    "    android:layout_width=\"match_parent\"\n" +
-                    "    android:layout_height=\"match_parent\"\n" +
-                    "    android:paddingBottom=\"@dimen/activity_vertical_margin\"\n" +
-                    "    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n" +
-                    "    android:paddingRight=\"@dimen/activity_horizontal_margin\"\n" +
-                    "    android:paddingTop=\"@dimen/activity_vertical_margin\"\n" +
-                    "    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n" +
-                    ">\n" +
-                    "\n" +
-                    "    <TextView\n" +
-                    "        android:id=\"@+id/first\"\n" +
-                    "        android:layout_width=\"wrap_content\"\n" +
-                    "        android:layout_alignParentStart=\"true\"\n" +
-                    "        android:layout_alignParentLeft=\"true\"\n" +
-                    "        android:layout_height=\"wrap_content\"\n" +
-                    "        android:text=\"@{user.firstName,default=World}\" />\n" +
-                    "\n" +
-                    "    <TextView\n" +
-                    "        android:id=\"@+id/last\"\n" +
-                    "        android:layout_width=\"wrap_content\"\n" +
-                    "        android:layout_height=\"wrap_content\"\n" +
-                    "        android:layout_toEndOf=\"@id/first\"\n" +
-                    "        android:layout_toRightOf=\"@id/first\"\n" +
-                    "        android:text=\"@{user.lastName,default=Hello}\" />\n" +
-                    "\n" +
-                    "    <Button\n" +
-                    "        android:layout_width=\"wrap_content\"\n" +
-                    "        android:layout_height=\"wrap_content\"\n" +
-                    "        android:layout_below=\"@id/last\"\n" +
-                    "        android:text=\"Submit\"\n" +
-                    "        android:onClick=\"@{activity.onClick}\"/>\n" +
-                    "</RelativeLayout>";
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
deleted file mode 100644
index eb264d65..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ /dev/null
@@ -1,42 +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.layoutlib.bridge.intensive;
-
-import com.android.layoutlib.bridge.BridgeRenderSessionTest;
-import com.android.layoutlib.bridge.TestDelegates;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParserTest;
-import com.android.layoutlib.bridge.impl.LayoutParserWrapperTest;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-import org.junit.runners.Suite.SuiteClasses;
-
-import android.graphics.Matrix_DelegateTest;
-import android.util.BridgeXmlPullAttributesTest;
-
-/**
- * Suite used by the layoutlib build system
- */
-@RunWith(Suite.class)
-@SuiteClasses({
-        RenderTests.class, LayoutParserWrapperTest.class,
-        BridgeXmlBlockParserTest.class, BridgeXmlPullAttributesTest.class,
-        Matrix_DelegateTest.class, TestDelegates.class, PerformanceTests.class,
-        BridgeRenderSessionTest.class
-})
-public class Main {
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/PerformanceTests.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/PerformanceTests.java
deleted file mode 100644
index c90c26a..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/PerformanceTests.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive;
-
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.util.perf.PerformanceRunner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import android.annotation.NonNull;
-
-/**
- * Set of render tests
- */
-@RunWith(PerformanceRunner.class)
-public class PerformanceTests extends RenderTestBase {
-
-    @Before
-    public void setUp() {
-        ignoreAllLogging();
-    }
-
-
-    private void render(@NonNull String layoutFileName) throws ClassNotFoundException {
-        SessionParams params = createSessionParams(layoutFileName, ConfigGenerator.NEXUS_5);
-        render(params, 250);
-    }
-
-    @Test
-    public void testActivity() throws ClassNotFoundException {
-        render("activity.xml");
-    }
-
-    @Test
-    public void testAllWidgets() throws ClassNotFoundException {
-        render("allwidgets.xml");
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderResult.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderResult.java
deleted file mode 100644
index 087478f..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderResult.java
+++ /dev/null
@@ -1,72 +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.layoutlib.bridge.intensive;
-
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.ViewInfo;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-class RenderResult {
-    private final List<ViewInfo> mRootViews;
-    private final List<ViewInfo> mSystemViews;
-    private final Result mRenderResult;
-    private BufferedImage mImage;
-
-    private RenderResult(@Nullable Result result, @Nullable List<ViewInfo> systemViewInfoList,
-            @Nullable List<ViewInfo> rootViewInfoList, @Nullable BufferedImage image) {
-        mSystemViews = systemViewInfoList == null ? Collections.emptyList() : systemViewInfoList;
-        mRootViews = rootViewInfoList == null ? Collections.emptyList() : rootViewInfoList;
-        mRenderResult = result;
-        mImage = image;
-    }
-
-    @NonNull
-    static RenderResult getFromSession(@NonNull RenderSession session) {
-        return new RenderResult(session.getResult(),
-                new ArrayList<>(session.getSystemRootViews()),
-                new ArrayList<>(session.getRootViews()),
-                session.getImage());
-    }
-
-    @Nullable
-    Result getResult() {
-        return mRenderResult;
-    }
-
-    @NonNull
-    public List<ViewInfo> getRootViews() {
-        return mRootViews;
-    }
-
-    @NonNull
-    public List<ViewInfo> getSystemViews() {
-        return mSystemViews;
-    }
-
-    @Nullable
-    public BufferedImage getImage() {
-        return mImage;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
deleted file mode 100644
index 8739b7f..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
+++ /dev/null
@@ -1,545 +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.layoutlib.bridge.intensive;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
-import com.android.ide.common.resources.FrameworkResources;
-import com.android.ide.common.resources.ResourceItem;
-import com.android.ide.common.resources.ResourceRepository;
-import com.android.ide.common.resources.ResourceResolver;
-import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.android.io.FolderWrapper;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
-import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
-import com.android.layoutlib.bridge.intensive.util.ImageUtils;
-import com.android.layoutlib.bridge.intensive.util.ModuleClassLoader;
-import com.android.layoutlib.bridge.intensive.util.TestAssetRepository;
-import com.android.layoutlib.bridge.intensive.util.TestUtils;
-import com.android.tools.layoutlib.java.System_Delegate;
-import com.android.utils.ILogger;
-
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.concurrent.TimeUnit;
-
-import com.google.android.collect.Lists;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-/**
- * Base class for render tests. The render tests load all the framework resources and a project
- * checked in this test's resources. The main dependencies
- * are:
- * 1. Fonts directory.
- * 2. Framework Resources.
- * 3. App resources.
- * 4. build.prop file
- * <p>
- * These are configured by two variables set in the system properties.
- * <p>
- * 1. platform.dir: This is the directory for the current platform in the built SDK
- * (.../sdk/platforms/android-<version>).
- * <p>
- * The fonts are platform.dir/data/fonts.
- * The Framework resources are platform.dir/data/res.
- * build.prop is at platform.dir/build.prop.
- * <p>
- * 2. test_res.dir: This is the directory for the resources of the test. If not specified, this
- * falls back to getClass().getProtectionDomain().getCodeSource().getLocation()
- * <p>
- * The app resources are at: test_res.dir/testApp/MyApplication/app/src/main/res
- */
-public class RenderTestBase {
-
-    private static final String PLATFORM_DIR_PROPERTY = "platform.dir";
-    private static final String RESOURCE_DIR_PROPERTY = "test_res.dir";
-
-    private static final String PLATFORM_DIR;
-    private static final String TEST_RES_DIR;
-    /** Location of the app to test inside {@link #TEST_RES_DIR} */
-    private static final String APP_TEST_DIR = "testApp/MyApplication";
-    /** Location of the app's res dir inside {@link #TEST_RES_DIR} */
-    private static final String APP_TEST_RES = APP_TEST_DIR + "/src/main/res";
-    private static final String APP_CLASSES_LOCATION =
-            APP_TEST_DIR + "/build/intermediates/classes/debug/";
-    protected static Bridge sBridge;
-    /** List of log messages generated by a render call. It can be used to find specific errors */
-    protected static ArrayList<String> sRenderMessages = Lists.newArrayList();
-    private static LayoutLog sLayoutLibLog;
-    private static FrameworkResources sFrameworkRepo;
-    private static ResourceRepository sProjectResources;
-    private static ILogger sLogger;
-
-    static {
-        // Test that System Properties are properly set.
-        PLATFORM_DIR = getPlatformDir();
-        if (PLATFORM_DIR == null) {
-            fail(String.format("System Property %1$s not properly set. The value is %2$s",
-                    PLATFORM_DIR_PROPERTY, System.getProperty(PLATFORM_DIR_PROPERTY)));
-        }
-
-        TEST_RES_DIR = getTestResDir();
-        if (TEST_RES_DIR == null) {
-            fail(String.format("System property %1$s.dir not properly set. The value is %2$s",
-                    RESOURCE_DIR_PROPERTY, System.getProperty(RESOURCE_DIR_PROPERTY)));
-        }
-    }
-
-    @Rule
-    public TestWatcher sRenderMessageWatcher = new TestWatcher() {
-        @Override
-        protected void succeeded(Description description) {
-            // We only check error messages if the rest of the test case was successful.
-            if (!sRenderMessages.isEmpty()) {
-                fail(description.getMethodName() + " render error message: " +
-                        sRenderMessages.get(0));
-            }
-        }
-    };
-    // Default class loader with access to the app classes
-    protected ClassLoader mDefaultClassLoader =
-            new ModuleClassLoader(APP_CLASSES_LOCATION, getClass().getClassLoader());
-
-    private static String getPlatformDir() {
-        String platformDir = System.getProperty(PLATFORM_DIR_PROPERTY);
-        if (platformDir != null && !platformDir.isEmpty() && new File(platformDir).isDirectory()) {
-            return platformDir;
-        }
-        // System Property not set. Try to find the directory in the build directory.
-        String androidHostOut = System.getenv("ANDROID_HOST_OUT");
-        if (androidHostOut != null) {
-            platformDir = getPlatformDirFromHostOut(new File(androidHostOut));
-            if (platformDir != null) {
-                return platformDir;
-            }
-        }
-        String workingDirString = System.getProperty("user.dir");
-        File workingDir = new File(workingDirString);
-        // Test if workingDir is android checkout root.
-        platformDir = getPlatformDirFromRoot(workingDir);
-        if (platformDir != null) {
-            return platformDir;
-        }
-
-        // Test if workingDir is platform/frameworks/base/tools/layoutlib/bridge.
-        File currentDir = workingDir;
-        if (currentDir.getName().equalsIgnoreCase("bridge")) {
-            currentDir = currentDir.getParentFile();
-        }
-        // Test if currentDir is  platform/frameworks/base/tools/layoutlib. That is, root should be
-        // workingDir/../../../../  (4 levels up)
-        for (int i = 0; i < 4; i++) {
-            if (currentDir != null) {
-                currentDir = currentDir.getParentFile();
-            }
-        }
-        return currentDir == null ? null : getPlatformDirFromRoot(currentDir);
-    }
-
-    private static String getPlatformDirFromRoot(File root) {
-        if (!root.isDirectory()) {
-            return null;
-        }
-        File out = new File(root, "out");
-        if (!out.isDirectory()) {
-            return null;
-        }
-        File host = new File(out, "host");
-        if (!host.isDirectory()) {
-            return null;
-        }
-        File[] hosts = host.listFiles(path -> path.isDirectory() &&
-                (path.getName().startsWith("linux-") || path.getName().startsWith("darwin-")));
-        assert hosts != null;
-        for (File hostOut : hosts) {
-            String platformDir = getPlatformDirFromHostOut(hostOut);
-            if (platformDir != null) {
-                return platformDir;
-            }
-        }
-        return null;
-    }
-
-    private static String getPlatformDirFromHostOut(File out) {
-        if (!out.isDirectory()) {
-            return null;
-        }
-        File sdkDir = new File(out, "sdk");
-        if (!sdkDir.isDirectory()) {
-            return null;
-        }
-        File[] sdkDirs = sdkDir.listFiles(path -> {
-            // We need to search for $TARGET_PRODUCT (usually, sdk_phone_armv7)
-            return path.isDirectory() && path.getName().startsWith("sdk");
-        });
-        assert sdkDirs != null;
-        for (File dir : sdkDirs) {
-            String platformDir = getPlatformDirFromHostOutSdkSdk(dir);
-            if (platformDir != null) {
-                return platformDir;
-            }
-        }
-        return null;
-    }
-
-    private static String getPlatformDirFromHostOutSdkSdk(File sdkDir) {
-        File[] possibleSdks = sdkDir.listFiles(
-                path -> path.isDirectory() && path.getName().contains("android-sdk"));
-        assert possibleSdks != null;
-        for (File possibleSdk : possibleSdks) {
-            File platformsDir = new File(possibleSdk, "platforms");
-            File[] platforms = platformsDir.listFiles(
-                    path -> path.isDirectory() && path.getName().startsWith("android-"));
-            if (platforms == null || platforms.length == 0) {
-                continue;
-            }
-            Arrays.sort(platforms, (o1, o2) -> {
-                final int MAX_VALUE = 1000;
-                String suffix1 = o1.getName().substring("android-".length());
-                String suffix2 = o2.getName().substring("android-".length());
-                int suff1, suff2;
-                try {
-                    suff1 = Integer.parseInt(suffix1);
-                } catch (NumberFormatException e) {
-                    suff1 = MAX_VALUE;
-                }
-                try {
-                    suff2 = Integer.parseInt(suffix2);
-                } catch (NumberFormatException e) {
-                    suff2 = MAX_VALUE;
-                }
-                if (suff1 != MAX_VALUE || suff2 != MAX_VALUE) {
-                    return suff2 - suff1;
-                }
-                return suffix2.compareTo(suffix1);
-            });
-            return platforms[0].getAbsolutePath();
-        }
-        return null;
-    }
-
-    private static String getTestResDir() {
-        String resourceDir = System.getProperty(RESOURCE_DIR_PROPERTY);
-        if (resourceDir != null && !resourceDir.isEmpty() && new File(resourceDir).isDirectory()) {
-            return resourceDir;
-        }
-        // TEST_RES_DIR not explicitly set. Fallback to the class's source location.
-        try {
-            URL location = RenderTestBase.class.getProtectionDomain().getCodeSource().getLocation();
-            return new File(location.getPath()).exists() ? location.getPath() : null;
-        } catch (NullPointerException e) {
-            // Prevent a lot of null checks by just catching the exception.
-            return null;
-        }
-    }
-
-    /**
-     * Initialize the bridge and the resource maps.
-     */
-    @BeforeClass
-    public static void beforeClass() {
-        File data_dir = new File(PLATFORM_DIR, "data");
-        File res = new File(data_dir, "res");
-        sFrameworkRepo = new FrameworkResources(new FolderWrapper(res));
-        sFrameworkRepo.loadResources();
-        sFrameworkRepo.loadPublicResources(getLogger());
-
-        sProjectResources =
-                new ResourceRepository(new FolderWrapper(TEST_RES_DIR + "/" + APP_TEST_RES),
-                        false) {
-                    @NonNull
-                    @Override
-                    protected ResourceItem createResourceItem(@NonNull String name) {
-                        return new ResourceItem(name);
-                    }
-                };
-        sProjectResources.loadResources();
-
-        File fontLocation = new File(data_dir, "fonts");
-        File buildProp = new File(PLATFORM_DIR, "build.prop");
-        File attrs = new File(res, "values" + File.separator + "attrs.xml");
-        sBridge = new Bridge();
-        sBridge.init(ConfigGenerator.loadProperties(buildProp), fontLocation,
-                ConfigGenerator.getEnumMap(attrs), getLayoutLog());
-        Bridge.getLock().lock();
-        try {
-            Bridge.setLog(getLayoutLog());
-        } finally {
-            Bridge.getLock().unlock();
-        }
-    }
-
-    @AfterClass
-    public static void tearDown() {
-        sLayoutLibLog = null;
-        sFrameworkRepo = null;
-        sProjectResources = null;
-        sLogger = null;
-        sBridge = null;
-
-        TestUtils.gc();
-
-        System.out.println("Objects still linked from the DelegateManager:");
-        DelegateManager.dump(System.out);
-    }
-
-    @NonNull
-    protected static RenderResult render(SessionParams params, long frameTimeNanos) {
-        // TODO: Set up action bar handler properly to test menu rendering.
-        // Create session params.
-        System_Delegate.setBootTimeNanos(TimeUnit.MILLISECONDS.toNanos(871732800000L));
-        System_Delegate.setNanosTime(TimeUnit.MILLISECONDS.toNanos(871732800000L));
-        RenderSession session = sBridge.createSession(params);
-
-        try {
-            if (frameTimeNanos != -1) {
-                session.setElapsedFrameTimeNanos(frameTimeNanos);
-            }
-
-            if (!session.getResult().isSuccess()) {
-                getLogger().error(session.getResult().getException(),
-                        session.getResult().getErrorMessage());
-            }
-            else {
-                // Render the session with a timeout of 50s.
-                Result renderResult = session.render(50000);
-                if (!renderResult.isSuccess()) {
-                    getLogger().error(session.getResult().getException(),
-                            session.getResult().getErrorMessage());
-                }
-            }
-
-            return RenderResult.getFromSession(session);
-        } finally {
-            session.dispose();
-        }
-    }
-
-    /**
-     * Create a new rendering session and test that rendering the given layout doesn't throw any
-     * exceptions and matches the provided image.
-     * <p>
-     * If frameTimeNanos is >= 0 a frame will be executed during the rendering. The time indicates
-     * how far in the future is.
-     */
-    @Nullable
-    protected static RenderResult renderAndVerify(SessionParams params, String goldenFileName,
-            long frameTimeNanos) throws ClassNotFoundException {
-        RenderResult result = RenderTestBase.render(params, frameTimeNanos);
-        try {
-            String goldenImagePath = APP_TEST_DIR + "/golden/" + goldenFileName;
-            assertNotNull(result.getImage());
-            ImageUtils.requireSimilar(goldenImagePath, result.getImage());
-        } catch (IOException e) {
-            getLogger().error(e, e.getMessage());
-        }
-
-        return result;
-    }
-
-    /**
-     * Create a new rendering session and test that rendering the given layout doesn't throw any
-     * exceptions and matches the provided image.
-     */
-    @Nullable
-    protected static RenderResult renderAndVerify(SessionParams params, String goldenFileName)
-            throws ClassNotFoundException {
-        return RenderTestBase.renderAndVerify(params, goldenFileName, -1);
-    }
-
-    private static LayoutLog getLayoutLog() {
-        if (sLayoutLibLog == null) {
-            sLayoutLibLog = new LayoutLog() {
-                @Override
-                public void warning(String tag, String message, Object data) {
-                    System.out.println("Warning " + tag + ": " + message);
-                    failWithMsg(message);
-                }
-
-                @Override
-                public void fidelityWarning(@Nullable String tag, String message,
-                        Throwable throwable, Object data) {
-
-                    System.out.println("FidelityWarning " + tag + ": " + message);
-                    if (throwable != null) {
-                        throwable.printStackTrace();
-                    }
-                    failWithMsg(message == null ? "" : message);
-                }
-
-                @Override
-                public void error(String tag, String message, Object data) {
-                    System.out.println("Error " + tag + ": " + message);
-                    failWithMsg(message);
-                }
-
-                @Override
-                public void error(String tag, String message, Throwable throwable, Object data) {
-                    System.out.println("Error " + tag + ": " + message);
-                    if (throwable != null) {
-                        throwable.printStackTrace();
-                    }
-                    failWithMsg(message);
-                }
-            };
-        }
-        return sLayoutLibLog;
-    }
-
-    protected static void ignoreAllLogging() {
-        sLayoutLibLog = new LayoutLog();
-        sLogger = new ILogger() {
-            @Override
-            public void error(Throwable t, String msgFormat, Object... args) {
-            }
-
-            @Override
-            public void warning(String msgFormat, Object... args) {
-            }
-
-            @Override
-            public void info(String msgFormat, Object... args) {
-            }
-
-            @Override
-            public void verbose(String msgFormat, Object... args) {
-            }
-        };
-    }
-
-    protected static ILogger getLogger() {
-        if (sLogger == null) {
-            sLogger = new ILogger() {
-                @Override
-                public void error(Throwable t, @Nullable String msgFormat, Object... args) {
-                    if (t != null) {
-                        t.printStackTrace();
-                    }
-                    failWithMsg(msgFormat == null ? "" : msgFormat, args);
-                }
-
-                @Override
-                public void warning(@NonNull String msgFormat, Object... args) {
-                    failWithMsg(msgFormat, args);
-                }
-
-                @Override
-                public void info(@NonNull String msgFormat, Object... args) {
-                    // pass.
-                }
-
-                @Override
-                public void verbose(@NonNull String msgFormat, Object... args) {
-                    // pass.
-                }
-            };
-        }
-        return sLogger;
-    }
-
-    private static void failWithMsg(@NonNull String msgFormat, Object... args) {
-        sRenderMessages.add(args == null ? msgFormat : String.format(msgFormat, args));
-    }
-
-    @Before
-    public void beforeTestCase() {
-        sRenderMessages.clear();
-    }
-
-    @NonNull
-    protected LayoutPullParser createLayoutPullParser(String layoutPath) {
-        return new LayoutPullParser(APP_TEST_RES + "/layout/" + layoutPath);
-    }
-
-    /**
-     * Create a new rendering session and test that rendering the given layout on nexus 5
-     * doesn't throw any exceptions and matches the provided image.
-     */
-    @Nullable
-    protected RenderResult renderAndVerify(String layoutFileName, String goldenFileName)
-            throws ClassNotFoundException {
-        return renderAndVerify(layoutFileName, goldenFileName, ConfigGenerator.NEXUS_5);
-    }
-
-    /**
-     * Create a new rendering session and test that rendering the given layout on given device
-     * doesn't throw any exceptions and matches the provided image.
-     */
-    @Nullable
-    protected RenderResult renderAndVerify(String layoutFileName, String goldenFileName,
-            ConfigGenerator deviceConfig) throws ClassNotFoundException {
-        SessionParams params = createSessionParams(layoutFileName, deviceConfig);
-        return renderAndVerify(params, goldenFileName);
-    }
-
-    protected SessionParams createSessionParams(String layoutFileName, ConfigGenerator deviceConfig)
-            throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createLayoutPullParser(layoutFileName);
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        // TODO: Set up action bar handler properly to test menu rendering.
-        // Create session params.
-        return getSessionParams(parser, deviceConfig, layoutLibCallback, "AppTheme", true,
-                RenderingMode.NORMAL, 22);
-    }
-
-    /**
-     * Uses Theme.Material and Target sdk version as 22.
-     */
-    protected SessionParams getSessionParams(LayoutPullParser layoutParser,
-            ConfigGenerator configGenerator, LayoutLibTestCallback layoutLibCallback,
-            String themeName, boolean isProjectTheme, RenderingMode renderingMode,
-            @SuppressWarnings("SameParameterValue") int targetSdk) {
-        FolderConfiguration config = configGenerator.getFolderConfig();
-        ResourceResolver resourceResolver =
-                ResourceResolver.create(sProjectResources.getConfiguredResources(config),
-                        sFrameworkRepo.getConfiguredResources(config), themeName, isProjectTheme);
-
-        SessionParams sessionParams =
-                new SessionParams(layoutParser, renderingMode, null /*used for caching*/,
-                        configGenerator.getHardwareConfig(), resourceResolver, layoutLibCallback, 0,
-                        targetSdk, getLayoutLog());
-        sessionParams.setFlag(RenderParamsFlags.FLAG_DO_NOT_RENDER_ON_CREATE, true);
-        sessionParams.setAssetRepository(new TestAssetRepository());
-        return sessionParams;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
deleted file mode 100644
index 7b565b1..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
+++ /dev/null
@@ -1,449 +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.layoutlib.bridge.intensive;
-
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
-import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
-import com.android.resources.Density;
-import com.android.resources.Navigation;
-import com.android.resources.ResourceType;
-
-import org.junit.Test;
-
-import android.content.res.AssetManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-
-import java.lang.reflect.Field;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Set of render tests
- */
-public class RenderTests extends RenderTestBase {
-
-    @Test
-    public void testActivity() throws ClassNotFoundException {
-        renderAndVerify("activity.xml", "activity.png");
-    }
-
-    @Test
-    public void testActivityOnOldTheme() throws ClassNotFoundException {
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        LayoutPullParser parser = createLayoutPullParser("simple_activity.xml");
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.NoTitleBar", false,
-                RenderingMode.NORMAL, 22);
-
-        renderAndVerify(params, "simple_activity-old-theme.png");
-    }
-
-    @Test
-    public void testTranslucentBars() throws ClassNotFoundException {
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        LayoutPullParser parser = createLayoutPullParser("four_corners.xml");
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar.TranslucentDecor", false,
-                RenderingMode.NORMAL, 22);
-        renderAndVerify(params, "four_corners_translucent.png");
-
-        parser = createLayoutPullParser("four_corners.xml");
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5_LAND,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar.TranslucentDecor", false,
-                RenderingMode.NORMAL, 22);
-        renderAndVerify(params, "four_corners_translucent_land.png");
-
-        parser = createLayoutPullParser("four_corners.xml");
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar", false,
-                RenderingMode.NORMAL, 22);
-        renderAndVerify(params, "four_corners.png");
-    }
-
-    @Test
-    public void testAllWidgets() throws ClassNotFoundException {
-        renderAndVerify("allwidgets.xml", "allwidgets.png");
-
-        // We expect fidelity warnings for Path.isConvex. Fail for anything else.
-        sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
-    }
-
-    @Test
-    public void testArrayCheck() throws ClassNotFoundException {
-        renderAndVerify("array_check.xml", "array_check.png");
-    }
-
-    @Test
-    public void testAllWidgetsTablet() throws ClassNotFoundException {
-        renderAndVerify("allwidgets.xml", "allwidgets_tab.png", ConfigGenerator.NEXUS_7_2012);
-
-        // We expect fidelity warnings for Path.isConvex. Fail for anything else.
-        sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
-    }
-
-    @Test
-    public void testActivityActionBar() throws ClassNotFoundException {
-        LayoutPullParser parser = createLayoutPullParser("simple_activity.xml");
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "simple_activity_noactionbar.png");
-
-        parser = createLayoutPullParser("simple_activity.xml");
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "simple_activity.png");
-
-        // This also tests that a theme with "NoActionBar" DOES HAVE an action bar when we are
-        // displaying menus.
-        parser = createLayoutPullParser("simple_activity.xml");
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar", false,
-                RenderingMode.V_SCROLL, 22);
-        params.setFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG, "menu");
-        renderAndVerify(params, "simple_activity.png");
-    }
-
-    @Test
-    public void testOnApplyInsetsCall()
-            throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
-        // We get the widget via reflection to avoid IntelliJ complaining about the class being
-        // located in the wrong package. (From the Bridge tests point of view, it is)
-        Class insetsWidgetClass = Class.forName("com.android.layoutlib.test.myapplication.widgets" +
-                ".InsetsWidget");
-        Field field = insetsWidgetClass.getDeclaredField("sApplyInsetsCalled");
-        assertFalse((Boolean)field.get(null));
-
-        LayoutPullParser parser = createLayoutPullParser("insets.xml");
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar", false,
-                RenderingMode.NORMAL, 22);
-
-        render(params, -1);
-
-        assertTrue((Boolean)field.get(null));
-        field.set(null, false);
-    }
-
-    /** Test expand_layout.xml */
-    @Test
-    public void testExpand() throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createLayoutPullParser("expand_vert_layout.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        ConfigGenerator customConfigGenerator = new ConfigGenerator()
-                .setScreenWidth(300)
-                .setScreenHeight(20)
-                .setDensity(Density.XHIGH)
-                .setNavigation(Navigation.NONAV);
-
-        SessionParams params = getSessionParams(parser, customConfigGenerator,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "expand_vert_layout.png");
-
-        customConfigGenerator = new ConfigGenerator()
-                .setScreenWidth(20)
-                .setScreenHeight(300)
-                .setDensity(Density.XHIGH)
-                .setNavigation(Navigation.NONAV);
-        parser = createLayoutPullParser("expand_horz_layout.xml");
-        params = getSessionParams(parser, customConfigGenerator,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar.Fullscreen", false,
-                RenderingMode.H_SCROLL, 22);
-
-        renderAndVerify(params, "expand_horz_layout.png");
-    }
-
-    /** Test indeterminate_progressbar.xml */
-    @Test
-    public void testVectorAnimation() throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createLayoutPullParser("indeterminate_progressbar.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "animated_vector.png", TimeUnit.SECONDS.toNanos(2));
-
-        parser = createLayoutPullParser("indeterminate_progressbar.xml");
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-        renderAndVerify(params, "animated_vector_1.png", TimeUnit.SECONDS.toNanos(3));
-    }
-
-    /**
-     * Test a vector drawable that uses trimStart and trimEnd. It also tests all the primitives
-     * for vector drawables (lines, moves and cubic and quadratic curves).
-     */
-    @Test
-    public void testVectorDrawable() throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createLayoutPullParser("vector_drawable.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "vector_drawable.png", TimeUnit.SECONDS.toNanos(2));
-    }
-
-    /**
-     * Regression test for http://b.android.com/91383 and http://b.android.com/203797
-     */
-    @Test
-    public void testVectorDrawable91383() throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createLayoutPullParser("vector_drawable_android.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "vector_drawable_91383.png", TimeUnit.SECONDS.toNanos(2));
-    }
-
-    /** Test activity.xml */
-    @Test
-    public void testScrollingAndMeasure() throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createLayoutPullParser("scrolled.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-        params.setForceNoDecor();
-        params.setExtendedViewInfoMode(true);
-
-        // Do an only-measure pass
-        RenderSession session = sBridge.createSession(params);
-        session.measure();
-        RenderResult result = RenderResult.getFromSession(session);
-        assertNotNull(result);
-        assertNotNull(result.getResult());
-        assertTrue(result.getResult().isSuccess());
-
-        ViewInfo rootLayout = result.getRootViews().get(0);
-        // Check the first box in the main LinearLayout
-        assertEquals(-90, rootLayout.getChildren().get(0).getTop());
-        assertEquals(-30, rootLayout.getChildren().get(0).getLeft());
-        assertEquals(90, rootLayout.getChildren().get(0).getBottom());
-        assertEquals(150, rootLayout.getChildren().get(0).getRight());
-
-        // Check the first box within the nested LinearLayout
-        assertEquals(-450, rootLayout.getChildren().get(5).getChildren().get(0).getTop());
-        assertEquals(90, rootLayout.getChildren().get(5).getChildren().get(0).getLeft());
-        assertEquals(-270, rootLayout.getChildren().get(5).getChildren().get(0).getBottom());
-        assertEquals(690, rootLayout.getChildren().get(5).getChildren().get(0).getRight());
-
-        // Do a full render pass
-        parser = createLayoutPullParser("scrolled.xml");
-
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-        params.setForceNoDecor();
-        params.setExtendedViewInfoMode(true);
-
-        result = renderAndVerify(params, "scrolled.png");
-        assertNotNull(result);
-        assertNotNull(result.getResult());
-        assertTrue(result.getResult().isSuccess());
-    }
-
-    @Test
-    public void testGetResourceNameVariants() throws Exception {
-        // Setup
-        // Create the layout pull parser for our resources (empty.xml can not be part of the test
-        // app as it won't compile).
-        LayoutPullParser parser = new LayoutPullParser("/empty.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_4,
-                layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22);
-        AssetManager assetManager = AssetManager.getSystem();
-        DisplayMetrics metrics = new DisplayMetrics();
-        Configuration configuration = RenderAction.getConfiguration(params);
-        //noinspection deprecation
-        Resources resources = new Resources(assetManager, metrics, configuration);
-        resources.mLayoutlibCallback = params.getLayoutlibCallback();
-        resources.mContext =
-                new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
-                        params.getAssets(), params.getLayoutlibCallback(), configuration,
-                        params.getTargetSdkVersion(), params.isRtlSupported());
-        // Test
-        assertEquals("android:style/ButtonBar",
-                resources.getResourceName(android.R.style.ButtonBar));
-        assertEquals("android", resources.getResourcePackageName(android.R.style.ButtonBar));
-        assertEquals("ButtonBar", resources.getResourceEntryName(android.R.style.ButtonBar));
-        assertEquals("style", resources.getResourceTypeName(android.R.style.ButtonBar));
-        int id = resources.mLayoutlibCallback.getResourceId(ResourceType.STRING, "app_name");
-        assertEquals("com.android.layoutlib.test.myapplication:string/app_name",
-                resources.getResourceName(id));
-        assertEquals("com.android.layoutlib.test.myapplication",
-                resources.getResourcePackageName(id));
-        assertEquals("string", resources.getResourceTypeName(id));
-        assertEquals("app_name", resources.getResourceEntryName(id));
-    }
-
-    @Test
-    public void testStringEscaping() throws Exception {
-        // Setup
-        // Create the layout pull parser for our resources (empty.xml can not be part of the test
-        // app as it won't compile).
-        LayoutPullParser parser = new LayoutPullParser("/empty.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(RenderTestBase.getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_4,
-                layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22);
-        AssetManager assetManager = AssetManager.getSystem();
-        DisplayMetrics metrics = new DisplayMetrics();
-        Configuration configuration = RenderAction.getConfiguration(params);
-        //noinspection deprecation
-        Resources resources = new Resources(assetManager, metrics, configuration);
-        resources.mLayoutlibCallback = params.getLayoutlibCallback();
-        resources.mContext =
-                new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
-                        params.getAssets(), params.getLayoutlibCallback(), configuration,
-                        params.getTargetSdkVersion(), params.isRtlSupported());
-
-        int id = resources.mLayoutlibCallback.getResourceId(ResourceType.ARRAY, "string_array");
-        String[] strings = resources.getStringArray(id);
-        assertArrayEquals(
-                new String[]{"mystring", "Hello world!", "candidates", "Unknown", "?EC"},
-                strings);
-        assertTrue(sRenderMessages.isEmpty());
-    }
-
-    //@Test
-    // Temporarily disabled (b/37725933)
-    public void testFonts() throws ClassNotFoundException {
-        // TODO: styles seem to be broken in TextView
-        renderAndVerify("fonts_test.xml", "font_test.png");
-    }
-
-    @Test
-    public void testAdaptiveIcon() throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createLayoutPullParser("adaptive_icon.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "adaptive_icon.png");
-    }
-
-    @Test
-    public void testColorTypedValue() throws Exception {
-        // Setup
-        // Create the layout pull parser for our resources (empty.xml can not be part of the test
-        // app as it won't compile).
-        LayoutPullParser parser = new LayoutPullParser("/empty.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(RenderTestBase.getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_4,
-                layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22);
-        AssetManager assetManager = AssetManager.getSystem();
-        DisplayMetrics metrics = new DisplayMetrics();
-        Configuration configuration = RenderAction.getConfiguration(params);
-        //noinspection deprecation
-        Resources resources = new Resources(assetManager, metrics, configuration);
-        resources.mLayoutlibCallback = params.getLayoutlibCallback();
-        resources.mContext =
-                new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
-                        params.getAssets(), params.getLayoutlibCallback(), configuration,
-                        params.getTargetSdkVersion(), params.isRtlSupported());
-
-        TypedValue outValue = new TypedValue();
-        resources.mContext.resolveThemeAttribute(android.R.attr.colorPrimary, outValue, true);
-        assertEquals(TypedValue.TYPE_INT_COLOR_ARGB8, outValue.type);
-        assertNotEquals(0, outValue.data);
-        assertTrue(sRenderMessages.isEmpty());
-    }
-
-    @Test
-    public void testRectangleShadow() throws Exception {
-        renderAndVerify("shadows_test.xml", "shadows_test.png");
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
deleted file mode 100644
index 34fc726..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
+++ /dev/null
@@ -1,322 +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.layoutlib.bridge.intensive.setup;
-
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.resources.configuration.CountryCodeQualifier;
-import com.android.ide.common.resources.configuration.DensityQualifier;
-import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.android.ide.common.resources.configuration.KeyboardStateQualifier;
-import com.android.ide.common.resources.configuration.LayoutDirectionQualifier;
-import com.android.ide.common.resources.configuration.LocaleQualifier;
-import com.android.ide.common.resources.configuration.NavigationMethodQualifier;
-import com.android.ide.common.resources.configuration.NetworkCodeQualifier;
-import com.android.ide.common.resources.configuration.NightModeQualifier;
-import com.android.ide.common.resources.configuration.ScreenDimensionQualifier;
-import com.android.ide.common.resources.configuration.ScreenOrientationQualifier;
-import com.android.ide.common.resources.configuration.ScreenRatioQualifier;
-import com.android.ide.common.resources.configuration.ScreenSizeQualifier;
-import com.android.ide.common.resources.configuration.TextInputMethodQualifier;
-import com.android.ide.common.resources.configuration.TouchScreenQualifier;
-import com.android.ide.common.resources.configuration.UiModeQualifier;
-import com.android.ide.common.resources.configuration.VersionQualifier;
-import com.android.resources.Density;
-import com.android.resources.Keyboard;
-import com.android.resources.KeyboardState;
-import com.android.resources.Navigation;
-import com.android.resources.NightMode;
-import com.android.resources.ScreenOrientation;
-import com.android.resources.ScreenRatio;
-import com.android.resources.ScreenSize;
-import com.android.resources.TouchScreen;
-import com.android.resources.UiMode;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.Map;
-import java.util.Properties;
-
-import com.google.android.collect.Maps;
-
-/**
- * Provides {@link FolderConfiguration} and {@link HardwareConfig} for various devices. Also
- * provides utility methods to parse build.prop and attrs.xml to generate the appropriate maps.
- */
-@SuppressWarnings("UnusedDeclaration") // For the pre-configured nexus generators.
-public class ConfigGenerator {
-
-    public static final ConfigGenerator NEXUS_4 = new ConfigGenerator();
-
-    public static final ConfigGenerator NEXUS_5 = new ConfigGenerator()
-                                                        .setScreenHeight(1920)
-                                                        .setScreenWidth(1080)
-                                                        .setXdpi(445)
-                                                        .setYdpi(445)
-                                                        .setOrientation(ScreenOrientation.PORTRAIT)
-                                                        .setDensity(Density.XXHIGH)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.NORMAL)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    public static final ConfigGenerator NEXUS_7 = new ConfigGenerator()
-                                                        .setScreenHeight(1920)
-                                                        .setScreenWidth(1200)
-                                                        .setXdpi(323)
-                                                        .setYdpi(323)
-                                                        .setOrientation(ScreenOrientation.PORTRAIT)
-                                                        .setDensity(Density.XHIGH)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.LARGE)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    public static final ConfigGenerator NEXUS_10 = new ConfigGenerator()
-                                                        .setScreenHeight(1600)
-                                                        .setScreenWidth(2560)
-                                                        .setXdpi(300)
-                                                        .setYdpi(300)
-                                                        .setOrientation(ScreenOrientation.LANDSCAPE)
-                                                        .setDensity(Density.XHIGH)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.XLARGE)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    public static final ConfigGenerator NEXUS_5_LAND = new ConfigGenerator()
-                                                        .setScreenHeight(1080)
-                                                        .setScreenWidth(1920)
-                                                        .setXdpi(445)
-                                                        .setYdpi(445)
-                                                        .setOrientation(ScreenOrientation.LANDSCAPE)
-                                                        .setDensity(Density.XXHIGH)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.NORMAL)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    public static final ConfigGenerator NEXUS_7_2012 = new ConfigGenerator()
-                                                        .setScreenHeight(1280)
-                                                        .setScreenWidth(800)
-                                                        .setXdpi(195)
-                                                        .setYdpi(200)
-                                                        .setOrientation(ScreenOrientation.PORTRAIT)
-                                                        .setDensity(Density.TV)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.LARGE)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    private static final String TAG_ATTR = "attr";
-    private static final String TAG_ENUM = "enum";
-    private static final String TAG_FLAG = "flag";
-    private static final String ATTR_NAME = "name";
-    private static final String ATTR_VALUE = "value";
-
-    // Device Configuration. Defaults are for a Nexus 4 device.
-    private int mScreenHeight = 1280;
-    private int mScreenWidth = 768;
-    private int mXdpi = 320;
-    private int mYdpi = 320;
-    private ScreenOrientation mOrientation = ScreenOrientation.PORTRAIT;
-    private Density mDensity = Density.XHIGH;
-    private ScreenRatio mRatio = ScreenRatio.NOTLONG;
-    private ScreenSize mSize = ScreenSize.NORMAL;
-    private Keyboard mKeyboard = Keyboard.NOKEY;
-    private TouchScreen mTouchScreen = TouchScreen.FINGER;
-    private KeyboardState mKeyboardState = KeyboardState.SOFT;
-    private boolean mSoftButtons = true;
-    private Navigation mNavigation = Navigation.NONAV;
-
-    public FolderConfiguration getFolderConfig() {
-        FolderConfiguration config = new FolderConfiguration();
-        config.createDefault();
-        config.setDensityQualifier(new DensityQualifier(mDensity));
-        config.setNavigationMethodQualifier(new NavigationMethodQualifier(mNavigation));
-        if (mScreenWidth > mScreenHeight) {
-            config.setScreenDimensionQualifier(new ScreenDimensionQualifier(mScreenWidth,
-                    mScreenHeight));
-        } else {
-            config.setScreenDimensionQualifier(new ScreenDimensionQualifier(mScreenHeight,
-                    mScreenWidth));
-        }
-        config.setScreenRatioQualifier(new ScreenRatioQualifier(mRatio));
-        config.setScreenSizeQualifier(new ScreenSizeQualifier(mSize));
-        config.setTextInputMethodQualifier(new TextInputMethodQualifier(mKeyboard));
-        config.setTouchTypeQualifier(new TouchScreenQualifier(mTouchScreen));
-        config.setKeyboardStateQualifier(new KeyboardStateQualifier(mKeyboardState));
-        config.setScreenOrientationQualifier(new ScreenOrientationQualifier(mOrientation));
-
-        config.updateScreenWidthAndHeight();
-
-        // some default qualifiers.
-        config.setUiModeQualifier(new UiModeQualifier(UiMode.NORMAL));
-        config.setNightModeQualifier(new NightModeQualifier(NightMode.NOTNIGHT));
-        config.setCountryCodeQualifier(new CountryCodeQualifier());
-        config.setLayoutDirectionQualifier(new LayoutDirectionQualifier());
-        config.setNetworkCodeQualifier(new NetworkCodeQualifier());
-        config.setLocaleQualifier(new LocaleQualifier());
-        config.setVersionQualifier(new VersionQualifier());
-        return config;
-    }
-
-    public HardwareConfig getHardwareConfig() {
-        return new HardwareConfig(mScreenWidth, mScreenHeight, mDensity, mXdpi, mYdpi, mSize,
-                mOrientation, null, mSoftButtons);
-    }
-
-    public static Map<String, String> loadProperties(File path) {
-        Properties p = new Properties();
-        Map<String, String> map = Maps.newHashMap();
-        try {
-            p.load(new FileInputStream(path));
-            for (String key : p.stringPropertyNames()) {
-                map.put(key, p.getProperty(key));
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return map;
-    }
-
-    public static Map<String, Map<String, Integer>> getEnumMap(File path) {
-        Map<String, Map<String, Integer>> map = Maps.newHashMap();
-        try {
-            XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser();
-            xmlPullParser.setInput(new FileInputStream(path), null);
-            int eventType = xmlPullParser.getEventType();
-            String attr = null;
-            while (eventType != XmlPullParser.END_DOCUMENT) {
-                if (eventType == XmlPullParser.START_TAG) {
-                    if (TAG_ATTR.equals(xmlPullParser.getName())) {
-                        attr = xmlPullParser.getAttributeValue(null, ATTR_NAME);
-                    } else if (TAG_ENUM.equals(xmlPullParser.getName())
-                            || TAG_FLAG.equals(xmlPullParser.getName())) {
-                        String name = xmlPullParser.getAttributeValue(null, ATTR_NAME);
-                        String value = xmlPullParser.getAttributeValue(null, ATTR_VALUE);
-                        // Integer.decode cannot handle "ffffffff", see JDK issue 6624867
-                        int i = (int) (long) Long.decode(value);
-                        assert attr != null;
-                        Map<String, Integer> attributeMap = map.get(attr);
-                        if (attributeMap == null) {
-                            attributeMap = Maps.newHashMap();
-                            map.put(attr, attributeMap);
-                        }
-                        attributeMap.put(name, i);
-                    }
-                } else if (eventType == XmlPullParser.END_TAG) {
-                    if (TAG_ATTR.equals(xmlPullParser.getName())) {
-                        attr = null;
-                    }
-                }
-                eventType = xmlPullParser.next();
-            }
-        } catch (XmlPullParserException e) {
-            e.printStackTrace();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return map;
-    }
-
-    // Methods to set the configuration values.
-
-    public ConfigGenerator setScreenHeight(int height) {
-        mScreenHeight = height;
-        return this;
-    }
-
-    public ConfigGenerator setScreenWidth(int width) {
-        mScreenWidth = width;
-        return this;
-    }
-
-    public ConfigGenerator setXdpi(int xdpi) {
-        mXdpi = xdpi;
-        return this;
-    }
-
-    public ConfigGenerator setYdpi(int ydpi) {
-        mYdpi = ydpi;
-        return this;
-    }
-
-    public ConfigGenerator setOrientation(ScreenOrientation orientation) {
-        mOrientation = orientation;
-        return this;
-    }
-
-    public ConfigGenerator setDensity(Density density) {
-        mDensity = density;
-        return this;
-    }
-
-    public ConfigGenerator setRatio(ScreenRatio ratio) {
-        mRatio = ratio;
-        return this;
-    }
-
-    public ConfigGenerator setSize(ScreenSize size) {
-        mSize = size;
-        return this;
-    }
-
-    public ConfigGenerator setKeyboard(Keyboard keyboard) {
-        mKeyboard = keyboard;
-        return this;
-    }
-
-    public ConfigGenerator setTouchScreen(TouchScreen touchScreen) {
-        mTouchScreen = touchScreen;
-        return this;
-    }
-
-    public ConfigGenerator setKeyboardState(KeyboardState state) {
-        mKeyboardState = state;
-        return this;
-    }
-
-    public ConfigGenerator setSoftButtons(boolean softButtons) {
-        mSoftButtons = softButtons;
-        return this;
-    }
-
-    public ConfigGenerator setNavigation(Navigation navigation) {
-        mNavigation = navigation;
-        return this;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
deleted file mode 100644
index 8ebfc65..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
+++ /dev/null
@@ -1,197 +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.layoutlib.bridge.intensive.setup;
-
-import com.android.SdkConstants;
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.ParserFactory;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams.Key;
-import com.android.ide.common.resources.IntArrayWrapper;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-import com.android.utils.ILogger;
-
-import org.kxml2.io.KXmlParser;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.io.File;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Map;
-
-import com.google.android.collect.Maps;
-
-import static org.junit.Assert.fail;
-
-@SuppressWarnings("deprecation") // For Pair
-public class LayoutLibTestCallback extends LayoutlibCallback {
-
-    private static final String PROJECT_CLASSES_LOCATION = "/testApp/MyApplication/build/intermediates/classes/debug/";
-    private static final String PACKAGE_NAME = "com.android.layoutlib.test.myapplication";
-
-    private final Map<Integer, Pair<ResourceType, String>> mProjectResources = Maps.newHashMap();
-    private final Map<IntArrayWrapper, String> mStyleableValueToNameMap = Maps.newHashMap();
-    private final Map<ResourceType, Map<String, Integer>> mResources = Maps.newHashMap();
-    private final ILogger mLog;
-    private final ActionBarCallback mActionBarCallback = new ActionBarCallback();
-    private final ClassLoader mModuleClassLoader;
-
-    public LayoutLibTestCallback(ILogger logger, ClassLoader classLoader) {
-        mLog = logger;
-        mModuleClassLoader = classLoader;
-    }
-
-    public void initResources() throws ClassNotFoundException {
-        Class<?> rClass = mModuleClassLoader.loadClass(PACKAGE_NAME + ".R");
-        Class<?>[] nestedClasses = rClass.getDeclaredClasses();
-        for (Class<?> resClass : nestedClasses) {
-            final ResourceType resType = ResourceType.getEnum(resClass.getSimpleName());
-
-            if (resType != null) {
-                final Map<String, Integer> resName2Id = Maps.newHashMap();
-                mResources.put(resType, resName2Id);
-
-                for (Field field : resClass.getDeclaredFields()) {
-                    final int modifiers = field.getModifiers();
-                    if (Modifier.isStatic(modifiers)) { // May not be final in library projects
-                        final Class<?> type = field.getType();
-                        try {
-                            if (type.isArray() && type.getComponentType() == int.class) {
-                                mStyleableValueToNameMap.put(
-                                        new IntArrayWrapper((int[]) field.get(null)),
-                                        field.getName());
-                            } else if (type == int.class) {
-                                final Integer value = (Integer) field.get(null);
-                                mProjectResources.put(value, Pair.of(resType, field.getName()));
-                                resName2Id.put(field.getName(), value);
-                            } else {
-                                mLog.error(null, "Unknown field type in R class: %1$s", type);
-                            }
-                        } catch (IllegalAccessException ignored) {
-                            mLog.error(ignored, "Malformed R class: %1$s", PACKAGE_NAME + ".R");
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-
-    @Override
-    public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs)
-            throws Exception {
-        Class<?> viewClass = mModuleClassLoader.loadClass(name);
-        Constructor<?> viewConstructor = viewClass.getConstructor(constructorSignature);
-        viewConstructor.setAccessible(true);
-        return viewConstructor.newInstance(constructorArgs);
-    }
-
-    @Override
-    public String getNamespace() {
-        return String.format(SdkConstants.NS_CUSTOM_RESOURCES_S,
-                PACKAGE_NAME);
-    }
-
-    @Override
-    public Pair<ResourceType, String> resolveResourceId(int id) {
-        return mProjectResources.get(id);
-    }
-
-    @Override
-    public String resolveResourceId(int[] id) {
-        return mStyleableValueToNameMap.get(new IntArrayWrapper(id));
-    }
-
-    @Override
-    public Integer getResourceId(ResourceType type, String name) {
-        Map<String, Integer> resName2Id = mResources.get(type);
-        if (resName2Id == null) {
-            return null;
-        }
-        return resName2Id.get(name);
-    }
-
-    @Override
-    public ILayoutPullParser getParser(String layoutName) {
-        fail("This method shouldn't be called by this version of LayoutLib.");
-        return null;
-    }
-
-    @Override
-    public ILayoutPullParser getParser(ResourceValue layoutResource) {
-        return new LayoutPullParser(new File(layoutResource.getValue()));
-    }
-
-    @Override
-    public Object getAdapterItemValue(ResourceReference adapterView, Object adapterCookie,
-            ResourceReference itemRef, int fullPosition, int positionPerType,
-            int fullParentPosition, int parentPositionPerType, ResourceReference viewRef,
-            ViewAttribute viewAttribute, Object defaultValue) {
-        return null;
-    }
-
-    @Override
-    public AdapterBinding getAdapterBinding(ResourceReference adapterViewRef, Object adapterCookie,
-            Object viewObject) {
-        return null;
-    }
-
-    @Override
-    public ActionBarCallback getActionBarCallback() {
-        return mActionBarCallback;
-    }
-
-    @Override
-    public boolean supports(int ideFeature) {
-        return false;
-    }
-
-    @NonNull
-    @Override
-    public ParserFactory getParserFactory() {
-        return new ParserFactory() {
-            @NonNull
-            @Override
-            public XmlPullParser createParser(@Nullable String debugName)
-                    throws XmlPullParserException {
-                return new KXmlParser();
-            }
-        };
-    }
-
-    @Override
-    public <T> T getFlag(Key<T> key) {
-        if (key.equals(RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE)) {
-            return (T) PACKAGE_NAME;
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java
deleted file mode 100644
index bc8083f..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java
+++ /dev/null
@@ -1,111 +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.layoutlib.bridge.intensive.setup;
-
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-
-import org.kxml2.io.KXmlParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOError;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import static com.android.SdkConstants.ATTR_IGNORE;
-import static com.android.SdkConstants.EXPANDABLE_LIST_VIEW;
-import static com.android.SdkConstants.GRID_VIEW;
-import static com.android.SdkConstants.LIST_VIEW;
-import static com.android.SdkConstants.SPINNER;
-import static com.android.SdkConstants.TOOLS_URI;
-
-public class LayoutPullParser extends KXmlParser implements ILayoutPullParser{
-
-    /**
-     * @param layoutPath Must start with '/' and be relative to test resources.
-     */
-    public LayoutPullParser(String layoutPath) {
-        if (layoutPath.startsWith("/")) {
-            layoutPath = layoutPath.substring(1);
-        }
-        try {
-            init(getClass().getClassLoader().getResourceAsStream(layoutPath));
-        } catch (XmlPullParserException e) {
-            throw new IOError(e);
-        }
-    }
-
-    /**
-     * @param layoutFile Path of the layout xml file on disk.
-     */
-    public LayoutPullParser(File layoutFile) {
-        try {
-            init(new FileInputStream(layoutFile));
-        } catch (XmlPullParserException | FileNotFoundException e) {
-            throw new IOError(e);
-        }
-    }
-
-    private void init(InputStream stream) throws XmlPullParserException {
-        setFeature(FEATURE_PROCESS_NAMESPACES, true);
-        setInput(stream, null);
-    }
-
-    @Override
-    public Object getViewCookie() {
-        // TODO: Implement this properly.
-        String name = super.getName();
-        if (name == null) {
-            return null;
-        }
-
-        // Store tools attributes if this looks like a layout we'll need adapter view
-        // bindings for in the LayoutlibCallback.
-        if (LIST_VIEW.equals(name) || EXPANDABLE_LIST_VIEW.equals(name) || GRID_VIEW.equals(name) || SPINNER.equals(name)) {
-            Map<String, String> map = null;
-            int count = getAttributeCount();
-            for (int i = 0; i < count; i++) {
-                String namespace = getAttributeNamespace(i);
-                if (namespace != null && namespace.equals(TOOLS_URI)) {
-                    String attribute = getAttributeName(i);
-                    if (attribute.equals(ATTR_IGNORE)) {
-                        continue;
-                    }
-                    if (map == null) {
-                        map = new HashMap<String, String>(4);
-                    }
-                    map.put(attribute, getAttributeValue(i));
-                }
-            }
-
-            return map;
-        }
-
-        return null;
-    }
-
-    @Override
-    @Deprecated
-    public ILayoutPullParser getParser(String layoutName) {
-        // Studio returns null.
-        return null;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java
deleted file mode 100644
index cdf5633..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java
+++ /dev/null
@@ -1,341 +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.layoutlib.bridge.intensive.util;
-
-import android.annotation.NonNull;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.imageio.ImageIO;
-
-import static java.awt.RenderingHints.*;
-import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
-import static java.io.File.separatorChar;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-
-// Adapted by taking the relevant pieces of code from the following classes:
-//
-// com.android.tools.idea.rendering.ImageUtils,
-// com.android.tools.idea.tests.gui.framework.fixture.layout.ImageFixture and
-// com.android.tools.idea.rendering.RenderTestBase
-/**
- * Utilities related to image processing.
- */
-public class ImageUtils {
-    /**
-     * Normally, this test will fail when there is a missing thumbnail. However, when
-     * you create creating a new test, it's useful to be able to turn this off such that
-     * you can generate all the missing thumbnails in one go, rather than having to run
-     * the test repeatedly to get to each new render assertion generating its thumbnail.
-     */
-    private static final boolean FAIL_ON_MISSING_THUMBNAIL = true;
-
-    private static final int THUMBNAIL_SIZE = 1000;
-
-    private static final double MAX_PERCENT_DIFFERENCE = 0.3;
-
-    public static void requireSimilar(@NonNull String relativePath, @NonNull BufferedImage image)
-            throws IOException {
-        int maxDimension = Math.max(image.getWidth(), image.getHeight());
-        double scale = THUMBNAIL_SIZE / (double)maxDimension;
-        BufferedImage thumbnail = scale(image, scale, scale);
-
-        InputStream is = ImageUtils.class.getClassLoader().getResourceAsStream(relativePath);
-        if (is == null) {
-            String message = "Unable to load golden thumbnail: " + relativePath + "\n";
-            message = saveImageAndAppendMessage(thumbnail, message, relativePath);
-            if (FAIL_ON_MISSING_THUMBNAIL) {
-                fail(message);
-            } else {
-                System.out.println(message);
-            }
-        }
-        else {
-            try {
-                BufferedImage goldenImage = ImageIO.read(is);
-                assertImageSimilar(relativePath, goldenImage, thumbnail, MAX_PERCENT_DIFFERENCE);
-            } finally {
-                is.close();
-            }
-        }
-    }
-
-    public static void assertImageSimilar(String relativePath, BufferedImage goldenImage,
-            BufferedImage image, double maxPercentDifferent) throws IOException {
-        assertEquals("Only TYPE_INT_ARGB image types are supported",  TYPE_INT_ARGB, image.getType());
-
-        if (goldenImage.getType() != TYPE_INT_ARGB) {
-            BufferedImage temp = new BufferedImage(goldenImage.getWidth(), goldenImage.getHeight(),
-                    TYPE_INT_ARGB);
-            temp.getGraphics().drawImage(goldenImage, 0, 0, null);
-            goldenImage = temp;
-        }
-        assertEquals(TYPE_INT_ARGB, goldenImage.getType());
-
-        int imageWidth = Math.min(goldenImage.getWidth(), image.getWidth());
-        int imageHeight = Math.min(goldenImage.getHeight(), image.getHeight());
-
-        // Blur the images to account for the scenarios where there are pixel
-        // differences
-        // in where a sharp edge occurs
-        // goldenImage = blur(goldenImage, 6);
-        // image = blur(image, 6);
-
-        int width = 3 * imageWidth;
-        @SuppressWarnings("UnnecessaryLocalVariable")
-        int height = imageHeight; // makes code more readable
-        BufferedImage deltaImage = new BufferedImage(width, height, TYPE_INT_ARGB);
-        Graphics g = deltaImage.getGraphics();
-
-        // Compute delta map
-        long delta = 0;
-        for (int y = 0; y < imageHeight; y++) {
-            for (int x = 0; x < imageWidth; x++) {
-                int goldenRgb = goldenImage.getRGB(x, y);
-                int rgb = image.getRGB(x, y);
-                if (goldenRgb == rgb) {
-                    deltaImage.setRGB(imageWidth + x, y, 0x00808080);
-                    continue;
-                }
-
-                // If the pixels have no opacity, don't delta colors at all
-                if (((goldenRgb & 0xFF000000) == 0) && (rgb & 0xFF000000) == 0) {
-                    deltaImage.setRGB(imageWidth + x, y, 0x00808080);
-                    continue;
-                }
-
-                int deltaR = ((rgb & 0xFF0000) >>> 16) - ((goldenRgb & 0xFF0000) >>> 16);
-                int newR = 128 + deltaR & 0xFF;
-                int deltaG = ((rgb & 0x00FF00) >>> 8) - ((goldenRgb & 0x00FF00) >>> 8);
-                int newG = 128 + deltaG & 0xFF;
-                int deltaB = (rgb & 0x0000FF) - (goldenRgb & 0x0000FF);
-                int newB = 128 + deltaB & 0xFF;
-
-                int avgAlpha = ((((goldenRgb & 0xFF000000) >>> 24)
-                        + ((rgb & 0xFF000000) >>> 24)) / 2) << 24;
-
-                int newRGB = avgAlpha | newR << 16 | newG << 8 | newB;
-                deltaImage.setRGB(imageWidth + x, y, newRGB);
-
-                delta += Math.abs(deltaR);
-                delta += Math.abs(deltaG);
-                delta += Math.abs(deltaB);
-            }
-        }
-
-        // 3 different colors, 256 color levels
-        long total = imageHeight * imageWidth * 3L * 256L;
-        float percentDifference = (float) (delta * 100 / (double) total);
-
-        String error = null;
-        String imageName = getName(relativePath);
-        if (percentDifference > maxPercentDifferent) {
-            error = String.format("Images differ (by %.1f%%)", percentDifference);
-        } else if (Math.abs(goldenImage.getWidth() - image.getWidth()) >= 2) {
-            error = "Widths differ too much for " + imageName + ": " +
-                    goldenImage.getWidth() + "x" + goldenImage.getHeight() +
-                    "vs" + image.getWidth() + "x" + image.getHeight();
-        } else if (Math.abs(goldenImage.getHeight() - image.getHeight()) >= 2) {
-            error = "Heights differ too much for " + imageName + ": " +
-                    goldenImage.getWidth() + "x" + goldenImage.getHeight() +
-                    "vs" + image.getWidth() + "x" + image.getHeight();
-        }
-
-        assertEquals(TYPE_INT_ARGB, image.getType());
-        if (error != null) {
-            // Expected on the left
-            // Golden on the right
-            g.drawImage(goldenImage, 0, 0, null);
-            g.drawImage(image, 2 * imageWidth, 0, null);
-
-            // Labels
-            if (imageWidth > 80) {
-                g.setColor(Color.RED);
-                g.drawString("Expected", 10, 20);
-                g.drawString("Actual", 2 * imageWidth + 10, 20);
-            }
-
-            File output = new File(getFailureDir(), "delta-" + imageName);
-            if (output.exists()) {
-                boolean deleted = output.delete();
-                assertTrue(deleted);
-            }
-            ImageIO.write(deltaImage, "PNG", output);
-            error += " - see details in " + output.getPath() + "\n";
-            error = saveImageAndAppendMessage(image, error, relativePath);
-            System.out.println(error);
-            fail(error);
-        }
-
-        g.dispose();
-    }
-
-    /**
-     * Resize the given image
-     *
-     * @param source the image to be scaled
-     * @param xScale x scale
-     * @param yScale y scale
-     * @return the scaled image
-     */
-    @NonNull
-    public static BufferedImage scale(@NonNull BufferedImage source, double xScale, double yScale) {
-
-        int sourceWidth = source.getWidth();
-        int sourceHeight = source.getHeight();
-        int destWidth = Math.max(1, (int) (xScale * sourceWidth));
-        int destHeight = Math.max(1, (int) (yScale * sourceHeight));
-        int imageType = source.getType();
-        if (imageType == BufferedImage.TYPE_CUSTOM) {
-            imageType = BufferedImage.TYPE_INT_ARGB;
-        }
-        if (xScale > 0.5 && yScale > 0.5) {
-            BufferedImage scaled =
-                    new BufferedImage(destWidth, destHeight, imageType);
-            Graphics2D g2 = scaled.createGraphics();
-            g2.setComposite(AlphaComposite.Src);
-            g2.setColor(new Color(0, true));
-            g2.fillRect(0, 0, destWidth, destHeight);
-            if (xScale == 1 && yScale == 1) {
-                g2.drawImage(source, 0, 0, null);
-            } else {
-                setRenderingHints(g2);
-                g2.drawImage(source, 0, 0, destWidth, destHeight, 0, 0, sourceWidth, sourceHeight,
-                        null);
-            }
-            g2.dispose();
-            return scaled;
-        } else {
-            // When creating a thumbnail, using the above code doesn't work very well;
-            // you get some visible artifacts, especially for text. Instead use the
-            // technique of repeatedly scaling the image into half; this will cause
-            // proper averaging of neighboring pixels, and will typically (for the kinds
-            // of screen sizes used by this utility method in the layout editor) take
-            // about 3-4 iterations to get the result since we are logarithmically reducing
-            // the size. Besides, each successive pass in operating on much fewer pixels
-            // (a reduction of 4 in each pass).
-            //
-            // However, we may not be resizing to a size that can be reached exactly by
-            // successively diving in half. Therefore, once we're within a factor of 2 of
-            // the final size, we can do a resize to the exact target size.
-            // However, we can get even better results if we perform this final resize
-            // up front. Let's say we're going from width 1000 to a destination width of 85.
-            // The first approach would cause a resize from 1000 to 500 to 250 to 125, and
-            // then a resize from 125 to 85. That last resize can distort/blur a lot.
-            // Instead, we can start with the destination width, 85, and double it
-            // successfully until we're close to the initial size: 85, then 170,
-            // then 340, and finally 680. (The next one, 1360, is larger than 1000).
-            // So, now we *start* the thumbnail operation by resizing from width 1000 to
-            // width 680, which will preserve a lot of visual details such as text.
-            // Then we can successively resize the image in half, 680 to 340 to 170 to 85.
-            // We end up with the expected final size, but we've been doing an exact
-            // divide-in-half resizing operation at the end so there is less distortion.
-
-            int iterations = 0; // Number of halving operations to perform after the initial resize
-            int nearestWidth = destWidth; // Width closest to source width that = 2^x, x is integer
-            int nearestHeight = destHeight;
-            while (nearestWidth < sourceWidth / 2) {
-                nearestWidth *= 2;
-                nearestHeight *= 2;
-                iterations++;
-            }
-
-            BufferedImage scaled = new BufferedImage(nearestWidth, nearestHeight, imageType);
-
-            Graphics2D g2 = scaled.createGraphics();
-            setRenderingHints(g2);
-            g2.drawImage(source, 0, 0, nearestWidth, nearestHeight, 0, 0, sourceWidth, sourceHeight,
-                    null);
-            g2.dispose();
-
-            sourceWidth = nearestWidth;
-            sourceHeight = nearestHeight;
-            source = scaled;
-
-            for (int iteration = iterations - 1; iteration >= 0; iteration--) {
-                int halfWidth = sourceWidth / 2;
-                int halfHeight = sourceHeight / 2;
-                scaled = new BufferedImage(halfWidth, halfHeight, imageType);
-                g2 = scaled.createGraphics();
-                setRenderingHints(g2);
-                g2.drawImage(source, 0, 0, halfWidth, halfHeight, 0, 0, sourceWidth, sourceHeight,
-                        null);
-                g2.dispose();
-
-                sourceWidth = halfWidth;
-                sourceHeight = halfHeight;
-                source = scaled;
-                iterations--;
-            }
-            return scaled;
-        }
-    }
-
-    private static void setRenderingHints(@NonNull Graphics2D g2) {
-        g2.setRenderingHint(KEY_INTERPOLATION,VALUE_INTERPOLATION_BILINEAR);
-        g2.setRenderingHint(KEY_RENDERING, VALUE_RENDER_QUALITY);
-        g2.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
-    }
-
-    /**
-     * Directory where to write the thumbnails and deltas.
-     */
-    @NonNull
-    private static File getFailureDir() {
-        String workingDirString = System.getProperty("user.dir");
-        File failureDir = new File(workingDirString, "out/failures");
-
-        //noinspection ResultOfMethodCallIgnored
-        failureDir.mkdirs();
-        return failureDir; //$NON-NLS-1$
-    }
-
-    /**
-     * Saves the generated thumbnail image and appends the info message to an initial message
-     */
-    @NonNull
-    private static String saveImageAndAppendMessage(@NonNull BufferedImage image,
-            @NonNull String initialMessage, @NonNull String relativePath) throws IOException {
-        File output = new File(getFailureDir(), getName(relativePath));
-        if (output.exists()) {
-            boolean deleted = output.delete();
-            assertTrue(deleted);
-        }
-        ImageIO.write(image, "PNG", output);
-        initialMessage += "Thumbnail for current rendering stored at " + output.getPath();
-//        initialMessage += "\nRun the following command to accept the changes:\n";
-//        initialMessage += String.format("mv %1$s %2$s", output.getPath(),
-//                ImageUtils.class.getResource(relativePath).getPath());
-        // The above has been commented out, since the destination path returned is in out dir
-        // and it makes the tests pass without the code being actually checked in.
-        return initialMessage;
-    }
-
-    private static String getName(@NonNull String relativePath) {
-        return relativePath.substring(relativePath.lastIndexOf(separatorChar) + 1);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java
deleted file mode 100644
index da360f3..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java
+++ /dev/null
@@ -1,62 +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.layoutlib.bridge.intensive.util;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import libcore.io.Streams;
-
-/**
- * Module class loader that loads classes from the test project.
- */
-public class ModuleClassLoader extends ClassLoader {
-    private final Map<String, Class<?>> mClasses = new HashMap<>();
-    private String myModuleRoot;
-
-    /**
-     * @param moduleRoot The path to the module root
-     * @param parent The parent class loader
-     */
-    public ModuleClassLoader(String moduleRoot, ClassLoader parent) {
-        super(parent);
-        myModuleRoot = moduleRoot + (moduleRoot.endsWith("/") ? "" : "/");
-    }
-
-    @Override
-    protected Class<?> findClass(String name) throws ClassNotFoundException {
-        try {
-            return super.findClass(name);
-        } catch (ClassNotFoundException ignored) {
-        }
-
-        Class<?> clazz = mClasses.get(name);
-        if (clazz == null) {
-            String path = name.replace('.', '/').concat(".class");
-            try {
-                byte[] b = Streams.readFully(getResourceAsStream(myModuleRoot + path));
-                clazz = defineClass(name, b, 0, b.length);
-                mClasses.put(name, clazz);
-            } catch (IOException ignore) {
-                throw new ClassNotFoundException(name + " not found");
-            }
-        }
-
-        return clazz;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java
deleted file mode 100644
index 0856ac9..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java
+++ /dev/null
@@ -1,54 +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.layoutlib.bridge.intensive.util;
-
-import com.android.ide.common.rendering.api.AssetRepository;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * {@link AssetRepository} used for render tests.
- */
-public class TestAssetRepository extends AssetRepository {
-    private static InputStream open(String path) throws FileNotFoundException {
-        File asset = new File(path);
-        if (asset.isFile()) {
-            return new FileInputStream(asset);
-        }
-
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public InputStream openAsset(String path, int mode) throws IOException {
-        return open(path);
-    }
-
-    @Override
-    public InputStream openNonAsset(int cookie, String path, int mode) throws IOException {
-        return open(path);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java
deleted file mode 100644
index 1df8e79..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive.util;
-
-import java.lang.ref.WeakReference;
-
-public class TestUtils {
-    public static void gc() {
-        // See RuntimeUtil#gc in jlibs (http://jlibs.in/)
-        Object obj = new Object();
-        WeakReference ref = new WeakReference<>(obj);
-        //noinspection UnusedAssignment
-        obj = null;
-        while (ref.get() != null) {
-            System.gc();
-            System.runFinalization();
-        }
-
-        System.gc();
-        System.runFinalization();
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java
deleted file mode 100644
index ee98b4b..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java
+++ /dev/null
@@ -1,97 +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.layoutlib.bridge.intensive.util.perf;
-
-import android.annotation.NonNull;
-import android.util.LongArray;
-
-import java.util.Arrays;
-import java.util.function.LongConsumer;
-
-/**
- * Class that collect a series of longs and produces the median, min and max values.
- */
-public class LongStatsCollector implements LongConsumer {
-    private final LongArray mAllValues;
-    private long mMin = Long.MAX_VALUE;
-    private long mMax = Long.MIN_VALUE;
-    public LongStatsCollector(int estimatedRuns) {
-        mAllValues = new LongArray(estimatedRuns);
-    }
-
-    public int size() {
-        return mAllValues.size();
-    }
-
-    @NonNull
-    public Stats getStats() {
-        if (mAllValues.size() == 0) {
-            throw new IndexOutOfBoundsException("No data");
-        }
-
-        double median;
-        int size = mAllValues.size();
-        long[] buffer = new long[size];
-        for (int i = 0; i < size; i++) {
-            buffer[i] = mAllValues.get(i);
-        }
-
-        Arrays.sort(buffer);
-
-        int midPoint = size / 2;
-        median = (size % 2 == 0) ? (buffer[midPoint - 1] + buffer[midPoint]) / 2 : buffer[midPoint];
-
-        return new Stats(mAllValues.size(), mMin, mMax, median);
-    }
-
-    @Override
-    public void accept(long value) {
-        mMin = Math.min(mMin, value);
-        mMax = Math.max(mMax, value);
-        mAllValues.add(value);
-    }
-
-    public static class Stats {
-        private final int mSamples;
-        private final long mMin;
-        private final long mMax;
-        private final double mMedian;
-
-        private Stats(int samples, long min, long max, double median) {
-            mSamples = samples;
-            mMin = min;
-            mMax = max;
-            mMedian = median;
-        }
-
-        public int getSampleCount() {
-            return mSamples;
-        }
-
-        public long getMin() {
-            return mMin;
-        }
-
-        public long getMax() {
-            return mMax;
-        }
-
-        public double getMedian() {
-            return mMedian;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java
deleted file mode 100644
index 7225a10..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java
+++ /dev/null
@@ -1,80 +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.layoutlib.bridge.intensive.util.perf;
-
-import org.junit.runner.Runner;
-import org.junit.runner.notification.RunNotifier;
-import org.junit.runners.BlockJUnit4ClassRunner;
-import org.junit.runners.model.FrameworkMethod;
-import org.junit.runners.model.InitializationError;
-import org.junit.runners.model.Statement;
-
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * JUnit {@link Runner} that times the test execution and produces some stats.
- */
-public class PerformanceRunner extends BlockJUnit4ClassRunner {
-    private static final int DEFAULT_WARMUP_ITERATIONS = 50;
-    private static final int DEFAULT_RUNS = 100;
-
-    private final int mWarmUpIterations;
-    private final int mRuns;
-
-    public PerformanceRunner(Class<?> testClass) throws InitializationError {
-        super(testClass);
-
-        Configuration classConfig = testClass.getAnnotation(Configuration.class);
-        mWarmUpIterations = classConfig != null && classConfig.warmUpIterations() != -1 ?
-                classConfig.warmUpIterations() :
-                DEFAULT_WARMUP_ITERATIONS;
-        mRuns = classConfig != null && classConfig.runs() != -1 ?
-                classConfig.runs() :
-                DEFAULT_RUNS;
-    }
-
-    @Override
-    protected Statement methodInvoker(FrameworkMethod method, Object test) {
-        int warmUpIterations;
-        int runs;
-
-        Configuration methodConfig = method.getAnnotation(Configuration.class);
-        warmUpIterations = methodConfig != null && methodConfig.warmUpIterations() != -1 ?
-                methodConfig.warmUpIterations() :
-                mWarmUpIterations;
-        runs = methodConfig != null && methodConfig.runs() != -1 ?
-                methodConfig.runs() :
-                mRuns;
-        return new TimedStatement(super.methodInvoker(method, test), warmUpIterations, runs,
-                (result) -> System.out.println(result.toString()));
-    }
-
-    @Override
-    public void run(RunNotifier notifier) {
-        super.run(notifier);
-    }
-
-    @Retention(RetentionPolicy.RUNTIME)
-    @Inherited
-    public @interface Configuration {
-        int warmUpIterations() default -1;
-
-        int runs() default -1;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java
deleted file mode 100644
index 77a2b0e..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java
+++ /dev/null
@@ -1,178 +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.layoutlib.bridge.intensive.util.perf;
-
-import com.android.layoutlib.bridge.intensive.util.TestUtils;
-
-import org.junit.runners.model.Statement;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Random;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Consumer;
-
-import com.google.common.hash.HashCode;
-import com.google.common.hash.HashFunction;
-import com.google.common.hash.Hashing;
-
-/**
- * JUnit {@link Statement} used to measure some statistics about the test method.
- */
-public class TimedStatement extends Statement {
-    private static final int CALIBRATION_WARMUP_ITERATIONS = 50;
-    private static final int CALIBRATION_RUNS = 100;
-
-    private static boolean sIsCalibrated;
-    private static double sCalibrated;
-
-    private final Statement mStatement;
-    private final int mWarmUpIterations;
-    private final int mRuns;
-    private final Runtime mRuntime = Runtime.getRuntime();
-    private final Consumer<TimedStatementResult> mCallback;
-
-    TimedStatement(Statement statement, int warmUpIterations, int runs,
-            Consumer<TimedStatementResult> finishedCallback) {
-        mStatement = statement;
-        mWarmUpIterations = warmUpIterations;
-        mRuns = runs;
-        mCallback = finishedCallback;
-    }
-
-    /**
-     * The calibrate method tries to do some work that involves IO, memory allocations and some
-     * operations on the randomly generated data to calibrate the speed of the machine with
-     * something that resembles the execution of a test case.
-     */
-    private static void calibrateMethod() throws IOException {
-        File tmpFile = File.createTempFile("test", "file");
-        Random rnd = new Random();
-        HashFunction hashFunction = Hashing.sha512();
-        for (int i = 0; i < 5 + rnd.nextInt(5); i++) {
-            FileOutputStream stream = new FileOutputStream(tmpFile);
-            int bytes = 30000 + rnd.nextInt(60000);
-            byte[] buffer = new byte[bytes];
-
-            rnd.nextBytes(buffer);
-            byte acc = 0;
-            for (int j = 0; j < bytes; j++) {
-                acc += buffer[i];
-            }
-            buffer[0] = acc;
-            stream.write(buffer);
-            System.gc();
-            stream.close();
-            FileInputStream input = new FileInputStream(tmpFile);
-            byte[] readBuffer = new byte[bytes];
-            //noinspection ResultOfMethodCallIgnored
-            input.read(readBuffer);
-            buffer = readBuffer;
-            HashCode code1 = hashFunction.hashBytes(buffer);
-            Arrays.sort(buffer);
-            HashCode code2 = hashFunction.hashBytes(buffer);
-            input.close();
-
-            FileOutputStream hashStream = new FileOutputStream(tmpFile);
-            hashStream.write(code1.asBytes());
-            hashStream.write(code2.asBytes());
-            hashStream.close();
-        }
-    }
-
-    /**
-     * Runs the calibration process and sets the calibration measure in {@link #sCalibrated}
-     */
-    private static void doCalibration() throws IOException {
-        System.out.println("Calibrating ...");
-        TestUtils.gc();
-        for (int i = 0; i < CALIBRATION_WARMUP_ITERATIONS; i++) {
-            calibrateMethod();
-        }
-
-        LongStatsCollector stats = new LongStatsCollector(CALIBRATION_RUNS);
-        for (int i = 0; i < CALIBRATION_RUNS; i++) {
-            TestUtils.gc();
-            long start = System.currentTimeMillis();
-            calibrateMethod();
-            stats.accept(System.currentTimeMillis() - start);
-        }
-
-        sCalibrated = stats.getStats().getMedian();
-        sIsCalibrated = true;
-        System.out.printf("  DONE %fms\n", sCalibrated);
-    }
-
-    private long getUsedMemory() {
-        return mRuntime.totalMemory() - mRuntime.freeMemory();
-    }
-
-
-    @Override
-    public void evaluate() throws Throwable {
-        if (!sIsCalibrated) {
-            doCalibration();
-        }
-
-        for (int i = 0; i < mWarmUpIterations; i++) {
-            mStatement.evaluate();
-        }
-
-        LongStatsCollector timeStats = new LongStatsCollector(mRuns);
-        LongStatsCollector memoryUseStats = new LongStatsCollector(mRuns);
-        AtomicBoolean collectSamples = new AtomicBoolean(false);
-
-        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
-        TestUtils.gc();
-        executorService.scheduleAtFixedRate(() -> {
-            if (!collectSamples.get()) {
-                return;
-            }
-            memoryUseStats.accept(getUsedMemory());
-        }, 0, 200, TimeUnit.MILLISECONDS);
-
-        try {
-            for (int i = 0; i < mRuns; i++) {
-                TestUtils.gc();
-                collectSamples.set(true);
-                long startTimeMs = System.currentTimeMillis();
-                mStatement.evaluate();
-                long stopTimeMs = System.currentTimeMillis();
-                collectSamples.set(true);
-                timeStats.accept(stopTimeMs - startTimeMs);
-
-            }
-        } finally {
-            executorService.shutdownNow();
-        }
-
-        TimedStatementResult result = new TimedStatementResult(
-                mWarmUpIterations,
-                mRuns,
-                sCalibrated,
-                timeStats.getStats(),
-                memoryUseStats.getStats());
-        mCallback.accept(result);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java
deleted file mode 100644
index 59f90d2..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java
+++ /dev/null
@@ -1,64 +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.layoutlib.bridge.intensive.util.perf;
-
-import com.android.layoutlib.bridge.intensive.util.perf.LongStatsCollector.Stats;
-
-import java.text.DecimalFormat;
-
-/**
- * Result value of a {@link TimedStatement}
- */
-public class TimedStatementResult {
-    private static final DecimalFormat UNITS_FORMAT = new DecimalFormat("#.##");
-
-    private final int mWarmUpIterations;
-    private final int mRuns;
-    private final double mCalibrationTimeMs;
-    private final Stats mTimeStats;
-    private final Stats mMemoryStats;
-
-    TimedStatementResult(int warmUpIterations, int runs,
-            double calibrationTimeMs,
-            Stats timeStats,
-            Stats memoryStats) {
-        mWarmUpIterations = warmUpIterations;
-        mRuns = runs;
-        mCalibrationTimeMs = calibrationTimeMs;
-        mTimeStats = timeStats;
-        mMemoryStats = memoryStats;
-    }
-
-    @Override
-    public String toString() {
-        return String.format(
-                "Warm up %d. Runs %d\n" + "Time:             %s ms (min: %s, max %s)\n" +
-                        "Calibration Time: %f ms\n" +
-                        "Calibrated Time:  %s units (min: %s, max %s)\n" +
-                        "Sampled %d times\n" +
-                        "   Memory used:  %d bytes (max %d)\n\n",
-                mWarmUpIterations, mRuns,
-                mTimeStats.getMedian(), mTimeStats.getMin(), mTimeStats.getMax(),
-                mCalibrationTimeMs,
-                UNITS_FORMAT.format((mTimeStats.getMedian() / mCalibrationTimeMs) * 100000),
-                UNITS_FORMAT.format((mTimeStats.getMin() / mCalibrationTimeMs) * 100000),
-                UNITS_FORMAT.format((mTimeStats.getMax() / mCalibrationTimeMs) * 100000),
-                mMemoryStats.getSampleCount(),
-                (long)mMemoryStats.getMedian() - mMemoryStats.getMin(),
-                mMemoryStats.getMax() - mMemoryStats.getMin());
-    }
-}
diff --git a/tools/layoutlib/bridge/update_nav_icons.sh b/tools/layoutlib/bridge/update_nav_icons.sh
deleted file mode 100755
index 7030d19..0000000
--- a/tools/layoutlib/bridge/update_nav_icons.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/sh
-
-# copies the navigation bar icons from system ui code to layoutlib.
-# to run, simply execute the script. (if not using bash, cd to the dir
-# containing this script and then run by ./update_nav_icons.sh)
-
-# Try to get the location of this script.
-if [ -n $BASH ]; then
-  # see http://stackoverflow.com/a/246128/1546000
-  MY_LOCATION=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
-  cd $MY_LOCATION
-else
-  # Let's assume script was run from the same dir.
-  MY_LOCATION=$(pwd)
-fi
-
-# Check mac or linux to get sed argument to enable extended regex.
-case $(uname -s) in
-  Darwin)
-    EXT_REGEX="-E"
-    ;;
-  *)
-    EXT_REGEX="-r"
-    ;;
-esac
-
-
-FB="frameworks/base"
-# frameworks/base relative to current location
-FB=$(echo $MY_LOCATION | sed $EXT_REGEX -e "s,.*$FB[^/]*/,," -e "s,[^/]+,..,g")
-CURRENT_API=21  # update only if icons change from this api version.
-DENSITIES="ldpi mdpi hdpi xhdpi xxhdpi"
-ICONS="ic_sysbar_back.png ic_sysbar_home.png ic_sysbar_recent.png"
-BARS="./resources/bars/"
-
-for icon in $ICONS
-do
-  for density in $DENSITIES
-  do
-    destination="$BARS/v$CURRENT_API/$density/"
-    mkdir -p "$destination"  # create if not present.
-    cp -v "$FB/packages/SystemUI/res/drawable-$density/$icon" "$destination"
-  done
-
-  for density in $DENSITIES
-  do
-    destination="$BARS/v$CURRENT_API/ldrtl-$density/"
-    mkdir -p "$destination"
-    cp -v "$FB/packages/SystemUI/res/drawable-ldrtl-$density/$icon" "$destination"
-    done
-done
diff --git a/tools/layoutlib/create/.classpath b/tools/layoutlib/create/.classpath
deleted file mode 100644
index 25c3b3e..0000000
--- a/tools/layoutlib/create/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry excluding="mock_data/" kind="src" path="tests"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/asm/asm-4.0.jar" sourcepath="/ANDROID_PLAT_SRC/prebuilts/misc/common/asm/src.zip"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/layoutlib/create/.project b/tools/layoutlib/create/.project
deleted file mode 100644
index e100d17..0000000
--- a/tools/layoutlib/create/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>layoutlib_create</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/layoutlib/create/.settings/README.txt b/tools/layoutlib/create/.settings/README.txt
deleted file mode 100644
index 9120b20..0000000
--- a/tools/layoutlib/create/.settings/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Copy this in eclipse project as a .settings folder at the root.
-This ensure proper compilation compliance and warning/error levels.
\ No newline at end of file
diff --git a/tools/layoutlib/create/.settings/org.eclipse.jdt.core.prefs b/tools/layoutlib/create/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 5381a0e..0000000
--- a/tools/layoutlib/create/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,93 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.nonnull=com.android.annotations.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=com.android.annotations.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled
-org.eclipse.jdt.core.compiler.annotation.nullable=com.android.annotations.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=error
-org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/tools/layoutlib/create/Android.mk b/tools/layoutlib/create/Android.mk
deleted file mode 100644
index 7611cde..0000000
--- a/tools/layoutlib/create/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-LOCAL_JAR_MANIFEST := manifest.txt
-LOCAL_STATIC_JAVA_LIBRARIES := \
-	asm-5.2
-
-LOCAL_MODULE := layoutlib_create
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/tools/layoutlib/create/README.txt b/tools/layoutlib/create/README.txt
deleted file mode 100644
index 727b194..0000000
--- a/tools/layoutlib/create/README.txt
+++ /dev/null
@@ -1,268 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-
-
-- Description -
----------------
-
-Layoutlib_create generates a JAR library used by the Eclipse graphical layout editor to perform
-layout.
-
-
-- Usage -
----------
-
- ./layoutlib_create destination.jar path/to/android1.jar path/to/android2.jar
-
-
-- Design Overview -
--------------------
-
-Layoutlib_create uses a few jars from the framework containing the Java code used by Android as
-generated by the Android build, right before the classes are converted to a DEX format.
-
-These jars can't be used directly in Eclipse as:
-- they contains references to native code (which we want to avoid in Eclipse),
-- some classes need to be overridden, for example all the drawing code that is replaced by Java 2D
-  calls in Eclipse.
-- some of the classes that need to be changed are final and/or we need access to their private
-  internal state.
-
-Consequently this tool:
-- parses the input JAR,
-- modifies some of the classes directly using some bytecode manipulation,
-- filters some packages and removes those we don't want in the output JAR,
-- injects some new classes,
-- generates a modified JAR file that is suitable for the Android plugin for Eclipse to perform
-  rendering.
-
-The ASM library is used to do the bytecode modification using its visitor pattern API.
-
-The layoutlib_create is *NOT* generic. There is no configuration file. Instead all the configuration
-is done in the main() method and the CreateInfo structure is expected to change with the Android
-platform as new classes are added, changed or removed. Some configuration that may be platform
-dependent is also present elsewhere in code.
-
-The resulting JAR is used by layoutlib_bridge (a.k.a. "the bridge"), also part of the platform, that
-provides all the necessary missing implementation for rendering graphics in Eclipse.
-
-
-
-- Implementation Notes -
-------------------------
-
-The tool works in two phases:
-- first analyze the input jar (AsmAnalyzer class)
-- then generate the output jar (AsmGenerator class),
-
-
-- Analyzer
-----------
-
-The goal of the analyzer is to create a graph of all the classes from the input JAR with their
-dependencies and then only keep the ones we want.
-
-To do that, the analyzer is created with a list of base classes to keep -- everything that derives
-from these is kept. Currently the one such class is android.view.View: since we want to render
-layouts, anything that is sort of a view needs to be kept.
-
-The analyzer is also given a list of class names to keep in the output. This is done using
-shell-like glob patterns that filter on the fully-qualified class names, for example "android.*.R**"
-("*" does not matches dots whilst "**" does, and "." and "$" are interpreted as-is). In practice we
-almost but not quite request the inclusion of full packages.
-
-The analyzer is also given a list of classes to exclude. A fake implementation of these classes is
-injected by the Generator.
-
-With this information, the analyzer parses the input zip to find all the classes. All classes
-deriving from the requested bases classes are kept. All classes whose name match the glob pattern
-are kept. The analysis then finds all the dependencies of the classes that are to be kept using an
-ASM visitor on the class, the field types, the method types and annotations types. Classes that
-belong to the current JRE are excluded.
-
-The output of the analyzer is a set of ASM ClassReader instances which are then fed to the
-generator.
-
-
-- Generator
------------
-
-The generator is constructed from a CreateInfo struct that acts as a config file and lists:
-- the classes to inject in the output JAR -- these classes are directly implemented in
-  layoutlib_create and will be used to interface with the renderer in Eclipse.
-- specific methods to override (see method stubs details below).
-- specific methods for which to delegate calls.
-- specific methods to remove based on their return type.
-- specific classes to rename.
-- specific classes to refactor.
-
-Each of these are specific strategies we use to be able to modify the Android code to fit within the
-Eclipse renderer. These strategies are explained below.
-
-The core method of the generator is transform(): it takes an input ASM ClassReader and modifies it
-to produce a byte array suitable for the final JAR file.
-
-The first step of the transformation is to implement the method delegates.
-
-The TransformClassAdapter is then used to process the potentially renamed class.  All protected or
-private classes are market as public. All classes are made non-final. Interfaces are left as-is.
-
-If a method has a return type that must be erased, the whole method is skipped.  Methods are also
-changed from protected/private to public. The code of the methods is then kept as-is, except for
-native methods which are replaced by a stub. Methods that are to be overridden are also replaced by
-a stub.
-
-Finally fields are also visited and changed from protected/private to public.
-
-The next step of the transformation is changing the name of the class in case we requested the class
-to be renamed. This uses the RenameClassAdapter to also rename all inner classes and references in
-methods and types. Note that other classes are not transformed and keep referencing the original
-name.
-
-The class is then fed to RefactorClassAdapter which is like RenameClassAdapter but updates the
-references in all classes. This is used to update the references of classes in the java package that
-were added in the Dalvik VM but are not a part of the Desktop VM. The existing classes are
-modified to update all references to these non-desktop classes. An alternate implementation of
-these (com.android.tools.layoutlib.java.*) is injected.
-
-RenameClassAdapter and RefactorClassAdapter both inherit from AbstractClassAdapter which changes the
-class version (version of the JDK used to compile the class) to 50 (corresponding to Java 6), if the
-class was originally compiled with Java 7 (version 51). This is because we don't currently generate
-the StackMapTable correctly and Java 7 VM enforces that classes with version greater than 51 have
-valid StackMapTable. As a side benefit of this, we can continue to support Java 6 because Java 7 on
-Mac has horrible font rendering support.
-
-ReplaceMethodCallsAdapter replaces calls to certain methods. This is different from the
-DelegateMethodAdapter since it doesn't preserve the original copy of the method and more importantly
-changes the calls to a method in each class instead of changing the implementation of the method.
-This is useful for methods in the Java namespace where we cannot add delegates. The configuration
-for this is not done through the CreateInfo class, but done in the ReplaceMethodAdapter.
-
-The ClassAdapters are chained together to achieve the desired output. (Look at section 2.2.7
-Transformation chains in the asm user guide, link in the References.) The order of execution of
-these is:
-ClassReader -> [DelegateClassAdapter] -> TransformClassAdapter -> [RenameClassAdapter] ->
-RefactorClassAdapter -> [ReplaceMethodCallsAdapter] -> ClassWriter
-
-- Method stubs
---------------
-
-As indicated above, all native and overridden methods are replaced by a stub.  We don't have the
-code to replace with in layoutlib_create. Instead the StubMethodAdapter replaces the code of the
-method by a call to OverrideMethod.invokeX(). When using the final JAR, the bridge can register
-listeners from these overridden method calls based on the method signatures.
-
-The listeners are currently pretty basic: we only pass the signature of the method being called, its
-caller object and a flag indicating whether the method was native. We do not currently provide the
-parameters. The listener can however specify the return value of the overridden method.
-
-This strategy is now obsolete and replaced by the method delegates.
-
-
-- Strategies
-------------
-
-We currently have 6 strategies to deal with overriding the rendering code and make it run in
-Eclipse. Most of these strategies are implemented hand-in-hand by the bridge (which runs in Eclipse)
-and the generator.
-
-
-1- Class Injection
-
-This is the easiest: we currently inject the following classes:
-- OverrideMethod and its associated MethodListener and MethodAdapter are used to intercept calls to
-  some specific methods that are stubbed out and change their return value.
-- CreateInfo class, which configured the generator. Not used yet, but could in theory help us track
-  what the generator changed.
-- AutoCloseable and Objects are part of Java 7. To enable us to still run on Java 6, new classes are
-  injected. The implementation for these classes has been taken from Android's libcore
-  (platform/libcore/luni/src/main/java/java/...).
-- Charsets, IntegralToString and UnsafeByteSequence are not part of the Desktop VM. They are
-  added to the Dalvik VM for performance reasons. An implementation that is very close to the
-  original (which is at platform/libcore/luni/src/main/java/...) is injected. Since these classees
-  were in part of the java package, where we can't inject classes, all references to these have been
-  updated (See strategy 4- Refactoring Classes).
-
-
-2- Overriding methods
-
-As explained earlier, the creator doesn't have any replacement code for methods to override. Instead
-it removes the original code and replaces it by a call to a specific OveriddeMethod.invokeX(). The
-bridge then registers a listener on the method signature and can provide an implementation.
-
-This strategy is now obsolete and replaced by the method delegates (See strategy 6- Method
-Delegates).
-
-
-3- Renaming classes
-
-This simply changes the name of a class in its definition, as well as all its references in internal
-inner classes and methods. Calls from other classes are not modified -- they keep referencing the
-original class name. This allows the bridge to literally replace an implementation.
-
-An example will make this easier: android.graphics.Paint is the main drawing class that we need to
-replace. To do so, the generator renames Paint to _original_Paint. Later the bridge provides its own
-replacement version of Paint which will be used by the rest of the Android stack. The replacement
-version of Paint can still use (either by inheritance or delegation) all the original non-native
-code of _original_Paint if it so desires.
-
-Some of the Android classes are basically wrappers over native objects and since we don't have the
-native code in Eclipse, we need to provide a full alternate implementation. Sub-classing doesn't
-work as some native methods are static and we don't control object creation.
-
-This won't rename/replace the inner static methods of a given class.
-
-
-4- Refactoring classes
-
-This is very similar to the Renaming classes except that it also updates the reference in all
-classes. This is done for classes which are added to the Dalvik VM for performance reasons but are
-not present in the Desktop VM. An implementation for these classes is also injected.
-
-
-5- Method erasure based on return type
-
-This is mostly an implementation detail of the bridge: in the Paint class mentioned above, some
-inner static classes are used to pass around attributes (e.g. FontMetrics, or the Style enum) and
-all the original implementation is native.
-
-In this case we have a strategy that tells the generator that anything returning, for example, the
-inner class Paint$Style in the Paint class should be discarded and the bridge will provide its own
-implementation.
-
-
-6- Method Delegates
-
-This strategy is used to override method implementations. Given a method SomeClass.MethodName(), 1
-or 2 methods are generated:
-a- A copy of the original method named SomeClass.MethodName_Original(). The content is the original
-method as-is from the reader. This step is omitted if the method is native, since it has no Java
-implementation.
-b- A brand new implementation of SomeClass.MethodName() which calls to a non-existing static method
-named SomeClass_Delegate.MethodName(). The implementation of this 'delegate' method is done in
-layoutlib_bridge.
-
-The delegate method is a static method. If the original method is non-static, the delegate method
-receives the original 'this' as its first argument. If the original method is an inner non-static
-method, it also receives the inner 'this' as the second argument.
-
-
-
-- References -
---------------
-
-
-The JVM Specification 2nd edition:
-  http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html
-
-Understanding bytecode:
-  http://www.ibm.com/developerworks/ibm/library/it-haggar_bytecode/
-
-Bytecode opcode list:
-  http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
-
-ASM user guide:
-  http://download.forge.objectweb.org/asm/asm4-guide.pdf
-
-
---
-end
diff --git a/tools/layoutlib/create/create.iml b/tools/layoutlib/create/create.iml
deleted file mode 100644
index ac97502..0000000
--- a/tools/layoutlib/create/create.iml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/data" type="java-test-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/mock_data" type="java-test-resource" />
-      <excludeFolder url="file://$MODULE_DIR$/.settings" />
-    </content>
-    <orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="module-library">
-      <library name="asm-5.2">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/asm/asm-5.2.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/asm/src.zip!/" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="library" scope="TEST" name="junit" level="project" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/tools/layoutlib/create/manifest.txt b/tools/layoutlib/create/manifest.txt
deleted file mode 100644
index 238e7f9..0000000
--- a/tools/layoutlib/create/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.tools.layoutlib.create.Main
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java
deleted file mode 100644
index 9a48ea6..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes a method that has been converted to a delegate by layoutlib_create.
- */
-@Retention(RetentionPolicy.RUNTIME)
-public @interface LayoutlibDelegate {
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java
deleted file mode 100644
index 0689c92..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes a parameter or field can be null.
- * <p/>
- * When decorating a method call parameter, this denotes the parameter can
- * legitimately be null and the method will gracefully deal with it. Typically used
- * on optional parameters.
- * <p/>
- * When decorating a method, this denotes the method might legitimately return null.
- * <p/>
- * This is a marker annotation and it has no specific attributes.
- */
-@Retention(RetentionPolicy.SOURCE)
-public @interface Nullable {
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java
deleted file mode 100644
index e4e016b..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes that the class, method or field has its visibility relaxed so
- * that unit tests can access it.
- * <p/>
- * The <code>visibility</code> argument can be used to specific what the original
- * visibility should have been if it had not been made public or package-private for testing.
- * The default is to consider the element private.
- */
-@Retention(RetentionPolicy.SOURCE)
-public @interface VisibleForTesting {
-    /**
-     * Intended visibility if the element had not been made public or package-private for
-     * testing.
-     */
-    enum Visibility {
-        /** The element should be considered protected. */
-        PROTECTED,
-        /** The element should be considered package-private. */
-        PACKAGE,
-        /** The element should be considered private. */
-        PRIVATE
-    }
-
-    /**
-     * Intended visibility if the element had not been made public or package-private for testing.
-     * If not specified, one should assume the element originally intended to be private.
-     */
-    Visibility visibility() default Visibility.PRIVATE;
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java
deleted file mode 100644
index 01c940a..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java
+++ /dev/null
@@ -1,418 +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.tools.layoutlib.create;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.signature.SignatureReader;
-import org.objectweb.asm.signature.SignatureVisitor;
-import org.objectweb.asm.signature.SignatureWriter;
-
-/**
- * Provides the common code for RenameClassAdapter and RefactorClassAdapter. It
- * goes through the complete class and finds references to other classes. It
- * then calls {@link #renameInternalType(String)} to convert the className to
- * the new value, if need be.
- */
-public abstract class AbstractClassAdapter extends ClassVisitor {
-
-    /**
-     * Returns the new FQCN for the class, if the reference to this class needs
-     * to be updated. Else, it returns the same string.
-     * @param name Old FQCN
-     * @return New FQCN if it needs to be renamed, else the old FQCN
-     */
-    abstract String renameInternalType(String name);
-
-    public AbstractClassAdapter(ClassVisitor cv) {
-        super(Main.ASM_VERSION, cv);
-    }
-
-    /**
-     * Renames a type descriptor, e.g. "Lcom.package.MyClass;"
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     */
-    String renameTypeDesc(String desc) {
-        if (desc == null) {
-            return null;
-        }
-
-        return renameType(Type.getType(desc));
-    }
-
-    /**
-     * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
-     * object element, e.g. "[Lcom.package.MyClass;"
-     * If the type doesn't need to be renamed, returns the internal name of the input type.
-     */
-    String renameType(Type type) {
-        if (type == null) {
-            return null;
-        }
-
-        if (type.getSort() == Type.OBJECT) {
-            String in = type.getInternalName();
-            return "L" + renameInternalType(in) + ";";
-        } else if (type.getSort() == Type.ARRAY) {
-            StringBuilder sb = new StringBuilder();
-            for (int n = type.getDimensions(); n > 0; n--) {
-                sb.append('[');
-            }
-            sb.append(renameType(type.getElementType()));
-            return sb.toString();
-        }
-        return type.getDescriptor();
-    }
-
-    /**
-     * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
-     * object element, e.g. "[Lcom.package.MyClass;".
-     * This is like renameType() except that it returns a Type object.
-     * If the type doesn't need to be renamed, returns the input type object.
-     */
-    Type renameTypeAsType(Type type) {
-        if (type == null) {
-            return null;
-        }
-
-        if (type.getSort() == Type.OBJECT) {
-            String in = type.getInternalName();
-            String newIn = renameInternalType(in);
-            if (!newIn.equals(in)) {
-                return Type.getType("L" + newIn + ";");
-            }
-        } else if (type.getSort() == Type.ARRAY) {
-            StringBuilder sb = new StringBuilder();
-            for (int n = type.getDimensions(); n > 0; n--) {
-                sb.append('[');
-            }
-            sb.append(renameType(type.getElementType()));
-            return Type.getType(sb.toString());
-        }
-        return type;
-    }
-
-    /**
-     * Renames a method descriptor, i.e. applies renameType to all arguments and to the
-     * return value.
-     */
-    String renameMethodDesc(String desc) {
-        if (desc == null) {
-            return null;
-        }
-
-        Type[] args = Type.getArgumentTypes(desc);
-
-        StringBuilder sb = new StringBuilder("(");
-        for (Type arg : args) {
-            String name = renameType(arg);
-            sb.append(name);
-        }
-        sb.append(')');
-
-        Type ret = Type.getReturnType(desc);
-        String name = renameType(ret);
-        sb.append(name);
-
-        return sb.toString();
-    }
-
-
-    /**
-     * Renames the ClassSignature handled by ClassVisitor.visit
-     * or the MethodTypeSignature handled by ClassVisitor.visitMethod.
-     */
-    String renameTypeSignature(String sig) {
-        if (sig == null) {
-            return null;
-        }
-        SignatureReader reader = new SignatureReader(sig);
-        SignatureWriter writer = new SignatureWriter();
-        reader.accept(new RenameSignatureAdapter(writer));
-        sig = writer.toString();
-        return sig;
-    }
-
-
-    /**
-     * Renames the FieldTypeSignature handled by ClassVisitor.visitField
-     * or MethodVisitor.visitLocalVariable.
-     */
-    String renameFieldSignature(String sig) {
-        return renameTypeSignature(sig);
-    }
-
-
-    //----------------------------------
-    // Methods from the ClassAdapter
-
-    @Override
-    public void visit(int version, int access, String name, String signature,
-            String superName, String[] interfaces) {
-        name = renameInternalType(name);
-        superName = renameInternalType(superName);
-        signature = renameTypeSignature(signature);
-        if (interfaces != null) {
-            for (int i = 0; i < interfaces.length; ++i) {
-                interfaces[i] = renameInternalType(interfaces[i]);
-            }
-        }
-
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-
-    @Override
-    public void visitInnerClass(String name, String outerName, String innerName, int access) {
-        name = renameInternalType(name);
-        outerName = renameInternalType(outerName);
-        super.visitInnerClass(name, outerName, innerName, access);
-    }
-
-    @Override
-    public void visitOuterClass(String owner, String name, String desc) {
-        super.visitOuterClass(renameInternalType(owner), name, renameTypeDesc(desc));
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-        desc = renameMethodDesc(desc);
-        signature = renameTypeSignature(signature);
-        MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
-        return new RenameMethodAdapter(mw);
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        desc = renameTypeDesc(desc);
-        return super.visitAnnotation(desc, visible);
-    }
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc,
-            String signature, Object value) {
-        desc = renameTypeDesc(desc);
-        return super.visitField(access, name, desc, signature, value);
-    }
-
-
-    //----------------------------------
-
-    /**
-     * A method visitor that renames all references from an old class name to a new class name.
-     */
-    public class RenameMethodAdapter extends MethodVisitor {
-
-        /**
-         * Creates a method visitor that renames all references from a given old name to a given new
-         * name. The method visitor will also rename all inner classes.
-         * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass).
-         */
-        public RenameMethodAdapter(MethodVisitor mv) {
-            super(Main.ASM_VERSION, mv);
-        }
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            desc = renameTypeDesc(desc);
-
-            return super.visitAnnotation(desc, visible);
-        }
-
-        @Override
-        public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
-            desc = renameTypeDesc(desc);
-
-            return super.visitParameterAnnotation(parameter, desc, visible);
-        }
-
-        @Override
-        public void visitTypeInsn(int opcode, String type) {
-            // The type sometimes turns out to be a type descriptor. We try to detect it and fix.
-            if (type.indexOf(';') > 0) {
-                type = renameTypeDesc(type);
-            } else {
-                type = renameInternalType(type);
-            }
-            super.visitTypeInsn(opcode, type);
-        }
-
-        @Override
-        public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-            owner = renameInternalType(owner);
-            desc = renameTypeDesc(desc);
-
-            super.visitFieldInsn(opcode, owner, name, desc);
-        }
-
-        @Override
-        public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                boolean itf) {
-            // The owner sometimes turns out to be a type descriptor. We try to detect it and fix.
-            if (owner.indexOf(';') > 0) {
-                owner = renameTypeDesc(owner);
-            } else {
-                owner = renameInternalType(owner);
-            }
-            desc = renameMethodDesc(desc);
-
-            super.visitMethodInsn(opcode, owner, name, desc, itf);
-        }
-
-        @Override
-        public void visitLdcInsn(Object cst) {
-            // If cst is a Type, this means the code is trying to pull the .class constant
-            // for this class, so it needs to be renamed too.
-            if (cst instanceof Type) {
-                cst = renameTypeAsType((Type) cst);
-            }
-            super.visitLdcInsn(cst);
-        }
-
-        @Override
-        public void visitMultiANewArrayInsn(String desc, int dims) {
-            desc = renameTypeDesc(desc);
-
-            super.visitMultiANewArrayInsn(desc, dims);
-        }
-
-        @Override
-        public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-            type = renameInternalType(type);
-
-            super.visitTryCatchBlock(start, end, handler, type);
-        }
-
-        @Override
-        public void visitLocalVariable(String name, String desc, String signature,
-                Label start, Label end, int index) {
-            desc = renameTypeDesc(desc);
-            signature = renameFieldSignature(signature);
-
-            super.visitLocalVariable(name, desc, signature, start, end, index);
-        }
-
-    }
-
-    //----------------------------------
-
-    public class RenameSignatureAdapter extends SignatureVisitor {
-
-        private final SignatureVisitor mSv;
-
-        public RenameSignatureAdapter(SignatureVisitor sv) {
-            super(Main.ASM_VERSION);
-            mSv = sv;
-        }
-
-        @Override
-        public void visitClassType(String name) {
-            name = renameInternalType(name);
-            mSv.visitClassType(name);
-        }
-
-        @Override
-        public void visitInnerClassType(String name) {
-            name = renameInternalType(name);
-            mSv.visitInnerClassType(name);
-        }
-
-        @Override
-        public SignatureVisitor visitArrayType() {
-            SignatureVisitor sv = mSv.visitArrayType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitBaseType(char descriptor) {
-            mSv.visitBaseType(descriptor);
-        }
-
-        @Override
-        public SignatureVisitor visitClassBound() {
-            SignatureVisitor sv = mSv.visitClassBound();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitEnd() {
-            mSv.visitEnd();
-        }
-
-        @Override
-        public SignatureVisitor visitExceptionType() {
-            SignatureVisitor sv = mSv.visitExceptionType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitFormalTypeParameter(String name) {
-            mSv.visitFormalTypeParameter(name);
-        }
-
-        @Override
-        public SignatureVisitor visitInterface() {
-            SignatureVisitor sv = mSv.visitInterface();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitInterfaceBound() {
-            SignatureVisitor sv = mSv.visitInterfaceBound();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitParameterType() {
-            SignatureVisitor sv = mSv.visitParameterType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitReturnType() {
-            SignatureVisitor sv = mSv.visitReturnType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitSuperclass() {
-            SignatureVisitor sv = mSv.visitSuperclass();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitTypeArgument() {
-            mSv.visitTypeArgument();
-        }
-
-        @Override
-        public SignatureVisitor visitTypeArgument(char wildcard) {
-            SignatureVisitor sv = mSv.visitTypeArgument(wildcard);
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitTypeVariable(String name) {
-            mSv.visitTypeVariable(name);
-        }
-
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
deleted file mode 100644
index 11d4c81..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
+++ /dev/null
@@ -1,914 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.signature.SignatureReader;
-import org.objectweb.asm.signature.SignatureVisitor;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.regex.Pattern;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * Analyzes the input JAR using the ASM java bytecode manipulation library
- * to list the desired classes and their dependencies.
- */
-public class AsmAnalyzer {
-
-    // Note: a bunch of stuff has package-level access for unit tests. Consider it private.
-
-    /** Output logger. */
-    private final Log mLog;
-    /** The input source JAR to parse. */
-    private final List<String> mOsSourceJar;
-    /** The generator to fill with the class list and dependency list. */
-    private final AsmGenerator mGen;
-    /** Keep all classes that derive from these one (these included). */
-    private final String[] mDeriveFrom;
-    /** Glob patterns of classes to keep, e.g. "com.foo.*" */
-    private final String[] mIncludeGlobs;
-    /** The set of classes to exclude.*/
-    private final Set<String> mExcludedClasses;
-    /** Glob patterns of files to keep as is. */
-    private final String[] mIncludeFileGlobs;
-    /** Internal names of classes that contain method calls that need to be rewritten. */
-    private final Set<String> mReplaceMethodCallClasses = new HashSet<>();
-
-    /**
-     * Creates a new analyzer.
-     *
-     * @param log The log output.
-     * @param osJarPath The input source JARs to parse.
-     * @param gen The generator to fill with the class list and dependency list.
-     * @param deriveFrom Keep all classes that derive from these one (these included).
-     * @param includeGlobs Glob patterns of classes to keep, e.g. "com.foo.*"
-     *        ("*" does not matches dots whilst "**" does, "." and "$" are interpreted as-is)
-     * @param includeFileGlobs Glob patterns of files which are kept as is. This is only for files
-     *        not ending in .class.
-     */
-    public AsmAnalyzer(Log log, List<String> osJarPath, AsmGenerator gen,
-            String[] deriveFrom, String[] includeGlobs, Set<String> excludeClasses,
-            String[] includeFileGlobs) {
-        mLog = log;
-        mGen = gen;
-        mOsSourceJar = osJarPath != null ? osJarPath : new ArrayList<String>();
-        mDeriveFrom = deriveFrom != null ? deriveFrom : new String[0];
-        mIncludeGlobs = includeGlobs != null ? includeGlobs : new String[0];
-        mExcludedClasses = excludeClasses;
-        mIncludeFileGlobs = includeFileGlobs != null ? includeFileGlobs : new String[0];
-    }
-
-    /**
-     * Starts the analysis using parameters from the constructor.
-     * Fills the generator with classes & dependencies found.
-     */
-    public void analyze() throws IOException, LogAbortException {
-
-        TreeMap<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        parseZip(mOsSourceJar, zipClasses, filesFound);
-        mLog.info("Found %d classes in input JAR%s.", zipClasses.size(),
-                mOsSourceJar.size() > 1 ? "s" : "");
-
-        Map<String, ClassReader> found = findIncludes(zipClasses);
-        Map<String, ClassReader> deps = findDeps(zipClasses, found);
-
-        if (mGen != null) {
-            mGen.setKeep(found);
-            mGen.setDeps(deps);
-            mGen.setCopyFiles(filesFound);
-            mGen.setRewriteMethodCallClasses(mReplaceMethodCallClasses);
-        }
-    }
-
-    /**
-     * Parses a JAR file and adds all the classes found to <code>classes</code>
-     * and all other files to <code>filesFound</code>.
-     *
-     * @param classes The map of class name => ASM ClassReader. Class names are
-     *                in the form "android.view.View".
-     * @param filesFound The map of file name => InputStream. The file name is
-     *                  in the form "android/data/dataFile".
-     */
-    void parseZip(List<String> jarPathList, Map<String, ClassReader> classes,
-            Map<String, InputStream> filesFound) throws IOException {
-        if (classes == null || filesFound == null) {
-            return;
-        }
-
-        Pattern[] includeFilePatterns = new Pattern[mIncludeFileGlobs.length];
-        for (int i = 0; i < mIncludeFileGlobs.length; ++i) {
-            includeFilePatterns[i] = getPatternFromGlob(mIncludeFileGlobs[i]);
-        }
-
-        for (String jarPath : jarPathList) {
-            ZipFile zip = new ZipFile(jarPath);
-            Enumeration<? extends ZipEntry> entries = zip.entries();
-            ZipEntry entry;
-            while (entries.hasMoreElements()) {
-                entry = entries.nextElement();
-                if (entry.getName().endsWith(".class")) {
-                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
-                    String className = classReaderToClassName(cr);
-                    classes.put(className, cr);
-                } else {
-                    for (Pattern includeFilePattern : includeFilePatterns) {
-                        if (includeFilePattern.matcher(entry.getName()).matches()) {
-                            filesFound.put(entry.getName(), zip.getInputStream(entry));
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name for a ClassReader.
-     * E.g. it returns something like android.view.View.
-     */
-    static String classReaderToClassName(ClassReader classReader) {
-        if (classReader == null) {
-            return null;
-        } else {
-            return classReader.getClassName().replace('/', '.');
-        }
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name from a path-like FQCN.
-     * E.g. it returns android.view.View from android/view/View.
-     */
-    static String internalToBinaryClassName(String className) {
-        if (className == null) {
-            return null;
-        } else {
-            return className.replace('/', '.');
-        }
-    }
-
-    /**
-     * Process the "includes" arrays.
-     * <p/>
-     * This updates the in_out_found map.
-     */
-    Map<String, ClassReader> findIncludes(Map<String, ClassReader> zipClasses)
-            throws LogAbortException {
-        TreeMap<String, ClassReader> found = new TreeMap<>();
-
-        mLog.debug("Find classes to include.");
-
-        for (String s : mIncludeGlobs) {
-            findGlobs(s, zipClasses, found);
-        }
-        for (String s : mDeriveFrom) {
-            findClassesDerivingFrom(s, zipClasses, found);
-        }
-
-        return found;
-    }
-
-
-    /**
-     * Uses ASM to find the class reader for the given FQCN class name.
-     * If found, insert it in the in_out_found map.
-     * Returns the class reader object.
-     */
-    ClassReader findClass(String className, Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutFound) throws LogAbortException {
-        ClassReader classReader = zipClasses.get(className);
-        if (classReader == null) {
-            throw new LogAbortException("Class %s not found by ASM in %s",
-                    className, mOsSourceJar);
-        }
-
-        inOutFound.put(className, classReader);
-        return classReader;
-    }
-
-    /**
-     * Insert in the inOutFound map all classes found in zipClasses that match the
-     * given glob pattern.
-     * <p/>
-     * The glob pattern is not a regexp. It only accepts the "*" keyword to mean
-     * "anything but a period". The "." and "$" characters match themselves.
-     * The "**" keyword means everything including ".".
-     * <p/>
-     * Examples:
-     * <ul>
-     * <li>com.foo.* matches all classes in the package com.foo but NOT sub-packages.
-     * <li>com.foo*.*$Event matches all internal Event classes in a com.foo*.* class.
-     * </ul>
-     */
-    void findGlobs(String globPattern, Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutFound) throws LogAbortException {
-
-        Pattern regexp = getPatternFromGlob(globPattern);
-
-        for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
-            String class_name = entry.getKey();
-            if (regexp.matcher(class_name).matches() &&
-                    !mExcludedClasses.contains(getOuterClassName(class_name))) {
-                findClass(class_name, zipClasses, inOutFound);
-            }
-        }
-    }
-
-    Pattern getPatternFromGlob(String globPattern) {
-     // transforms the glob pattern in a regexp:
-        // - escape "." with "\."
-        // - replace "*" by "[^.]*"
-        // - escape "$" with "\$"
-        // - add end-of-line match $
-        globPattern = globPattern.replaceAll("\\$", "\\\\\\$");
-        globPattern = globPattern.replaceAll("\\.", "\\\\.");
-        // prevent ** from being altered by the next rule, then process the * rule and finally
-        // the real ** rule (which is now @)
-        globPattern = globPattern.replaceAll("\\*\\*", "@");
-        globPattern = globPattern.replaceAll("\\*", "[^.]*");
-        globPattern = globPattern.replaceAll("@", ".*");
-        globPattern += "$";
-
-        return Pattern.compile(globPattern);
-    }
-
-    /**
-     * Checks all the classes defined in the JarClassName instance and uses BCEL to
-     * determine if they are derived from the given FQCN super class name.
-     * Inserts the super class and all the class objects found in the map.
-     */
-    void findClassesDerivingFrom(String super_name, Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutFound) throws LogAbortException {
-        if (mExcludedClasses.contains(getOuterClassName(super_name))) {
-            return;
-        }
-        findClass(super_name, zipClasses, inOutFound);
-
-        for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
-            String className = entry.getKey();
-            if (super_name.equals(className)) {
-                continue;
-            }
-            ClassReader classReader = entry.getValue();
-            ClassReader parent_cr = classReader;
-            while (parent_cr != null) {
-                String parent_name = internalToBinaryClassName(parent_cr.getSuperName());
-                if (parent_name == null) {
-                    // not found
-                    break;
-                } else if (super_name.equals(parent_name)) {
-                    inOutFound.put(className, classReader);
-                    break;
-                }
-                parent_cr = zipClasses.get(parent_name);
-            }
-        }
-    }
-
-    /**
-     * Instantiates a new DependencyVisitor. Useful for unit tests.
-     */
-    DependencyVisitor getVisitor(Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inKeep,
-            Map<String, ClassReader> outKeep,
-            Map<String, ClassReader> inDeps,
-            Map<String, ClassReader> outDeps) {
-        return new DependencyVisitor(zipClasses, inKeep, outKeep, inDeps, outDeps);
-    }
-
-    /**
-     * Finds all dependencies for all classes in keepClasses which are also
-     * listed in zipClasses. Returns a map of all the dependencies found.
-     */
-    Map<String, ClassReader> findDeps(Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutKeepClasses) {
-
-        TreeMap<String, ClassReader> deps = new TreeMap<>();
-        TreeMap<String, ClassReader> new_deps = new TreeMap<>();
-        TreeMap<String, ClassReader> new_keep = new TreeMap<>();
-        TreeMap<String, ClassReader> temp = new TreeMap<>();
-
-        DependencyVisitor visitor = getVisitor(zipClasses,
-                inOutKeepClasses, new_keep,
-                deps, new_deps);
-
-        for (ClassReader cr : inOutKeepClasses.values()) {
-            visitor.setClassName(cr.getClassName());
-            cr.accept(visitor, 0 /* flags */);
-        }
-
-        while (new_deps.size() > 0 || new_keep.size() > 0) {
-            deps.putAll(new_deps);
-            inOutKeepClasses.putAll(new_keep);
-
-            temp.clear();
-            temp.putAll(new_deps);
-            temp.putAll(new_keep);
-            new_deps.clear();
-            new_keep.clear();
-            mLog.debug("Found %1$d to keep, %2$d dependencies.",
-                    inOutKeepClasses.size(), deps.size());
-
-            for (ClassReader cr : temp.values()) {
-                visitor.setClassName(cr.getClassName());
-                cr.accept(visitor, 0 /* flags */);
-            }
-        }
-
-        mLog.info("Found %1$d classes to keep, %2$d class dependencies.",
-                inOutKeepClasses.size(), deps.size());
-
-        return deps;
-    }
-
-    private String getOuterClassName(String className) {
-        int pos = className.indexOf('$');
-        if (pos > 0) {
-            return className.substring(0, pos);
-        }
-        return className;
-    }
-
-    // ----------------------------------
-
-    /**
-     * Visitor to collect all the type dependencies from a class.
-     */
-    public class DependencyVisitor extends ClassVisitor {
-
-        /** All classes found in the source JAR. */
-        private final Map<String, ClassReader> mZipClasses;
-        /** Classes from which dependencies are to be found. */
-        private final Map<String, ClassReader> mInKeep;
-        /** Dependencies already known. */
-        private final Map<String, ClassReader> mInDeps;
-        /** New dependencies found by this visitor. */
-        private final Map<String, ClassReader> mOutDeps;
-        /** New classes to keep as-is found by this visitor. */
-        private final Map<String, ClassReader> mOutKeep;
-
-        private String mClassName;
-
-        /**
-         * Creates a new visitor that will find all the dependencies for the visited class.
-         * Types which are already in the zipClasses, keepClasses or inDeps are not marked.
-         * New dependencies are marked in outDeps.
-         *
-         * @param zipClasses All classes found in the source JAR.
-         * @param inKeep Classes from which dependencies are to be found.
-         * @param inDeps Dependencies already known.
-         * @param outDeps New dependencies found by this visitor.
-         */
-        public DependencyVisitor(Map<String, ClassReader> zipClasses,
-                Map<String, ClassReader> inKeep,
-                Map<String, ClassReader> outKeep,
-                Map<String,ClassReader> inDeps,
-                Map<String,ClassReader> outDeps) {
-            super(Main.ASM_VERSION);
-            mZipClasses = zipClasses;
-            mInKeep = inKeep;
-            mOutKeep = outKeep;
-            mInDeps = inDeps;
-            mOutDeps = outDeps;
-        }
-
-        private void setClassName(String className) {
-            mClassName = className;
-        }
-
-        /**
-         * Considers the given class name as a dependency.
-         * If it does, add to the mOutDeps map.
-         */
-        public void considerName(String className) {
-            if (className == null) {
-                return;
-            }
-
-            className = internalToBinaryClassName(className);
-
-            // exclude classes that have already been found or are marked to be excluded
-            if (mInKeep.containsKey(className) ||
-                    mOutKeep.containsKey(className) ||
-                    mInDeps.containsKey(className) ||
-                    mOutDeps.containsKey(className) ||
-                    mExcludedClasses.contains(getOuterClassName(className))) {
-                return;
-            }
-
-            // exclude classes that are not part of the JAR file being examined
-            ClassReader cr = mZipClasses.get(className);
-            if (cr == null) {
-                return;
-            }
-
-            try {
-                // exclude classes that are part of the default JRE (the one executing this program)
-                if (className.startsWith("java.") ||
-                        getClass().getClassLoader().loadClass(className) != null) {
-                    return;
-                }
-            } catch (ClassNotFoundException e) {
-                // ignore
-            }
-
-            // accept this class:
-            // - android classes are added to dependencies
-            // - non-android classes are added to the list of classes to keep as-is (they don't need
-            //   to be stubbed).
-            if (className.contains("android")) {  // TODO make configurable
-                mOutDeps.put(className, cr);
-            } else {
-                mOutKeep.put(className, cr);
-            }
-        }
-
-        /**
-         * Considers this array of names using considerName().
-         */
-        public void considerNames(String[] classNames) {
-            if (classNames != null) {
-                for (String className : classNames) {
-                    considerName(className);
-                }
-            }
-        }
-
-        /**
-         * Considers this signature or type signature by invoking the {@link SignatureVisitor}
-         * on it.
-         */
-        public void considerSignature(String signature) {
-            if (signature != null) {
-                SignatureReader sr = new SignatureReader(signature);
-                // SignatureReader.accept will call accessType so we don't really have
-                // to differentiate where the signature comes from.
-                sr.accept(new MySignatureVisitor());
-            }
-        }
-
-        /**
-         * Considers this {@link Type}. For arrays, the element type is considered.
-         * If the type is an object, it's internal name is considered.
-         */
-        public void considerType(Type t) {
-            if (t != null) {
-                if (t.getSort() == Type.ARRAY) {
-                    t = t.getElementType();
-                }
-                if (t.getSort() == Type.OBJECT) {
-                    considerName(t.getInternalName());
-                }
-            }
-        }
-
-        /**
-         * Considers a descriptor string. The descriptor is converted to a {@link Type}
-         * and then considerType() is invoked.
-         */
-        public void considerDesc(String desc) {
-            if (desc != null) {
-                try {
-                    Type t = Type.getType(desc);
-                    considerType(t);
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    // ignore, not a valid type.
-                }
-            }
-        }
-
-        // ---------------------------------------------------
-        // --- ClassVisitor, FieldVisitor
-        // ---------------------------------------------------
-
-        // Visits a class header
-        @Override
-        public void visit(int version, int access, String name,
-                String signature, String superName, String[] interfaces) {
-            // signature is the signature of this class. May be null if the class is not a generic
-            // one, and does not extend or implement generic classes or interfaces.
-
-            if (signature != null) {
-                considerSignature(signature);
-            }
-
-            // superName is the internal of name of the super class (see getInternalName).
-            // For interfaces, the super class is Object. May be null but only for the Object class.
-            considerName(superName);
-
-            // interfaces is the internal names of the class's interfaces (see getInternalName).
-            // May be null.
-            considerNames(interfaces);
-        }
-
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            // desc is the class descriptor of the annotation class.
-            considerDesc(desc);
-            return new MyAnnotationVisitor();
-        }
-
-        @Override
-        public void visitAttribute(Attribute attr) {
-            // pass
-        }
-
-        // Visits the end of a class
-        @Override
-        public void visitEnd() {
-            // pass
-        }
-
-        private class MyFieldVisitor extends FieldVisitor {
-
-            public MyFieldVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitAttribute(Attribute attr) {
-                // pass
-            }
-
-            // Visits the end of a class
-            @Override
-            public void visitEnd() {
-                // pass
-            }
-        }
-
-        @Override
-        public FieldVisitor visitField(int access, String name, String desc,
-                String signature, Object value) {
-            // desc is the field's descriptor (see Type).
-            considerDesc(desc);
-
-            // signature is the field's signature. May be null if the field's type does not use
-            // generic types.
-            considerSignature(signature);
-
-            return new MyFieldVisitor();
-        }
-
-        @Override
-        public void visitInnerClass(String name, String outerName, String innerName, int access) {
-            // name is the internal name of an inner class (see getInternalName).
-            considerName(name);
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc,
-                String signature, String[] exceptions) {
-            // desc is the method's descriptor (see Type).
-            considerDesc(desc);
-            // signature is the method's signature. May be null if the method parameters, return
-            // type and exceptions do not use generic types.
-            considerSignature(signature);
-
-            return new MyMethodVisitor(mClassName);
-        }
-
-        @Override
-        public void visitOuterClass(String owner, String name, String desc) {
-            // pass
-        }
-
-        @Override
-        public void visitSource(String source, String debug) {
-            // pass
-        }
-
-
-        // ---------------------------------------------------
-        // --- MethodVisitor
-        // ---------------------------------------------------
-
-        private class MyMethodVisitor extends MethodVisitor {
-
-            private String mOwnerClass;
-
-            public MyMethodVisitor(String ownerClass) {
-                super(Main.ASM_VERSION);
-                mOwnerClass = ownerClass;
-            }
-
-
-            @Override
-            public AnnotationVisitor visitAnnotationDefault() {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitCode() {
-                // pass
-            }
-
-            // field instruction
-            @Override
-            public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-                // owner is the class that declares the field.
-                considerName(owner);
-                // desc is the field's descriptor (see Type).
-                considerDesc(desc);
-            }
-
-            @Override
-            public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
-                // pass
-            }
-
-            @Override
-            public void visitIincInsn(int var, int increment) {
-                // pass -- an IINC instruction
-            }
-
-            @Override
-            public void visitInsn(int opcode) {
-                // pass -- a zero operand instruction
-            }
-
-            @Override
-            public void visitIntInsn(int opcode, int operand) {
-                // pass -- a single int operand instruction
-            }
-
-            @Override
-            public void visitJumpInsn(int opcode, Label label) {
-                // pass -- a jump instruction
-            }
-
-            @Override
-            public void visitLabel(Label label) {
-                // pass -- a label target
-            }
-
-            // instruction to load a constant from the stack
-            @Override
-            public void visitLdcInsn(Object cst) {
-                if (cst instanceof Type) {
-                    considerType((Type) cst);
-                }
-            }
-
-            @Override
-            public void visitLineNumber(int line, Label start) {
-                // pass
-            }
-
-            @Override
-            public void visitLocalVariable(String name, String desc,
-                    String signature, Label start, Label end, int index) {
-                // desc is the type descriptor of this local variable.
-                considerDesc(desc);
-                // signature is the type signature of this local variable. May be null if the local
-                // variable type does not use generic types.
-                considerSignature(signature);
-            }
-
-            @Override
-            public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-                // pass -- a lookup switch instruction
-            }
-
-            @Override
-            public void visitMaxs(int maxStack, int maxLocals) {
-                // pass
-            }
-
-            // instruction that invokes a method
-            @Override
-            public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                    boolean itf) {
-
-                // owner is the internal name of the method's owner class
-                considerName(owner);
-                // desc is the method's descriptor (see Type).
-                considerDesc(desc);
-
-
-                // Check if method needs to replaced by a call to a different method.
-                if (ReplaceMethodCallsAdapter.isReplacementNeeded(owner, name, desc, mOwnerClass)) {
-                    mReplaceMethodCallClasses.add(mOwnerClass);
-                }
-            }
-
-            // instruction multianewarray, whatever that is
-            @Override
-            public void visitMultiANewArrayInsn(String desc, int dims) {
-
-                // desc an array type descriptor.
-                considerDesc(desc);
-            }
-
-            @Override
-            public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-                    boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
-                // pass -- table switch instruction
-
-            }
-
-            @Override
-            public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-                // type is the internal name of the type of exceptions handled by the handler,
-                // or null to catch any exceptions (for "finally" blocks).
-                considerName(type);
-            }
-
-            // type instruction
-            @Override
-            public void visitTypeInsn(int opcode, String type) {
-                // type is the operand of the instruction to be visited. This operand must be the
-                // internal name of an object or array class.
-                considerName(type);
-            }
-
-            @Override
-            public void visitVarInsn(int opcode, int var) {
-                // pass -- local variable instruction
-            }
-        }
-
-        private class MySignatureVisitor extends SignatureVisitor {
-
-            public MySignatureVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            // ---------------------------------------------------
-            // --- SignatureVisitor
-            // ---------------------------------------------------
-
-            private String mCurrentSignatureClass = null;
-
-            // Starts the visit of a signature corresponding to a class or interface type
-            @Override
-            public void visitClassType(String name) {
-                mCurrentSignatureClass = name;
-                considerName(name);
-            }
-
-            // Visits an inner class
-            @Override
-            public void visitInnerClassType(String name) {
-                if (mCurrentSignatureClass != null) {
-                    mCurrentSignatureClass += "$" + name;
-                    considerName(mCurrentSignatureClass);
-                }
-            }
-
-            @Override
-            public SignatureVisitor visitArrayType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitBaseType(char descriptor) {
-                // pass -- a primitive type, ignored
-            }
-
-            @Override
-            public SignatureVisitor visitClassBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitExceptionType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitFormalTypeParameter(String name) {
-                // pass
-            }
-
-            @Override
-            public SignatureVisitor visitInterface() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitInterfaceBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitParameterType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitReturnType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitSuperclass() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitTypeArgument(char wildcard) {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitTypeVariable(String name) {
-                // pass
-            }
-
-            @Override
-            public void visitTypeArgument() {
-                // pass
-            }
-        }
-
-
-        // ---------------------------------------------------
-        // --- AnnotationVisitor
-        // ---------------------------------------------------
-
-        private class MyAnnotationVisitor extends AnnotationVisitor {
-
-            public MyAnnotationVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            // Visits a primitive value of an annotation
-            @Override
-            public void visit(String name, Object value) {
-                // value is the actual value, whose type must be Byte, Boolean, Character, Short,
-                // Integer, Long, Float, Double, String or Type
-                if (value instanceof Type) {
-                    considerType((Type) value);
-                }
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String name, String desc) {
-                // desc is the class descriptor of the nested annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public AnnotationVisitor visitArray(String name) {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitEnum(String name, String desc, String value) {
-                // desc is the class descriptor of the enumeration class.
-                considerDesc(desc);
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
deleted file mode 100644
index d59b419..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.jar.JarEntry;
-import java.util.jar.JarOutputStream;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * Class that generates a new JAR from a list of classes, some of which are to be kept as-is
- * and some of which are to be stubbed partially or totally.
- */
-public class AsmGenerator {
-
-    /** Output logger. */
-    private final Log mLog;
-    /** The path of the destination JAR to create. */
-    private final String mOsDestJar;
-    /** List of classes to inject in the final JAR from _this_ archive. */
-    private final Class<?>[] mInjectClasses;
-    /** All classes to output as-is, except if they have native methods. */
-    private Map<String, ClassReader> mKeep;
-    /** All dependencies that must be completely stubbed. */
-    private Map<String, ClassReader> mDeps;
-    /** All files that are to be copied as-is. */
-    private Map<String, InputStream> mCopyFiles;
-    /** All classes where certain method calls need to be rewritten. */
-    private Set<String> mReplaceMethodCallsClasses;
-    /** Counter of number of classes renamed during transform. */
-    private int mRenameCount;
-    /** FQCN Names of the classes to rename: map old-FQCN => new-FQCN */
-    private final HashMap<String, String> mRenameClasses;
-    /** FQCN Names of "old" classes that were NOT renamed. This starts with the full list of
-     *  old-FQCN to rename and they get erased as they get renamed. At the end, classes still
-     *  left here are not in the code base anymore and thus were not renamed. */
-    private HashSet<String> mClassesNotRenamed;
-    /** A map { FQCN => set { list of return types to delete from the FQCN } }. */
-    private HashMap<String, Set<String>> mDeleteReturns;
-    /** A map { FQCN => set { method names } } of methods to rewrite as delegates.
-     *  The special name {@link DelegateClassAdapter#ALL_NATIVES} can be used as in internal set. */
-    private final HashMap<String, Set<String>> mDelegateMethods;
-    /** FQCN Names of classes to refactor. All reference to old-FQCN will be updated to new-FQCN.
-     * map old-FQCN => new-FQCN */
-    private final HashMap<String, String> mRefactorClasses;
-    /** Methods to inject. FQCN of class in which method should be injected => runnable that does
-     * the injection. */
-    private final Map<String, ICreateInfo.InjectMethodRunnable> mInjectedMethodsMap;
-    /** A map { FQCN => set { field names } } which should be promoted to public visibility */
-    private final Map<String, Set<String>> mPromotedFields;
-    /** A list of classes to be promoted to public visibility */
-    private final Set<String> mPromotedClasses;
-
-    /**
-     * Creates a new generator that can generate the output JAR with the stubbed classes.
-     *
-     * @param log Output logger.
-     * @param osDestJar The path of the destination JAR to create.
-     * @param createInfo Creation parameters. Must not be null.
-     */
-    public AsmGenerator(Log log, String osDestJar, ICreateInfo createInfo) {
-        mLog = log;
-        mOsDestJar = osDestJar;
-        ArrayList<Class<?>> injectedClasses =
-                new ArrayList<>(Arrays.asList(createInfo.getInjectedClasses()));
-        // Search for and add anonymous inner classes also.
-        ListIterator<Class<?>> iter = injectedClasses.listIterator();
-        while (iter.hasNext()) {
-            Class<?> clazz = iter.next();
-            try {
-                int i = 1;
-                while(i < 100) {
-                    iter.add(Class.forName(clazz.getName() + "$" + i));
-                    i++;
-                }
-            } catch (ClassNotFoundException ignored) {
-                // Expected.
-            }
-        }
-        mInjectClasses = injectedClasses.toArray(new Class<?>[0]);
-
-        // Create the map/set of methods to change to delegates
-        mDelegateMethods = new HashMap<>();
-        addToMap(createInfo.getDelegateMethods(), mDelegateMethods);
-
-        for (String className : createInfo.getDelegateClassNatives()) {
-            className = binaryToInternalClassName(className);
-            Set<String> methods = mDelegateMethods.get(className);
-            if (methods == null) {
-                methods = new HashSet<>();
-                mDelegateMethods.put(className, methods);
-            }
-            methods.add(DelegateClassAdapter.ALL_NATIVES);
-        }
-
-        // Create the map of classes to rename.
-        mRenameClasses = new HashMap<>();
-        mClassesNotRenamed = new HashSet<>();
-        String[] renameClasses = Stream.concat(
-                Arrays.stream(createInfo.getRenamedClasses()),
-                Arrays.stream(createInfo.getRefactoredClasses()))
-                .toArray(String[]::new);
-        int n = renameClasses.length;
-        for (int i = 0; i < n; i += 2) {
-            assert i + 1 < n;
-            // The ASM class names uses "/" separators, whereas regular FQCN use "."
-            String oldFqcn = binaryToInternalClassName(renameClasses[i]);
-            String newFqcn = binaryToInternalClassName(renameClasses[i + 1]);
-            mRenameClasses.put(oldFqcn, newFqcn);
-            mClassesNotRenamed.add(oldFqcn);
-        }
-
-        // Create a map of classes to be refactored.
-        mRefactorClasses = new HashMap<>();
-        String[] refactorClasses = Stream.concat(
-                Arrays.stream(createInfo.getJavaPkgClasses()),
-                Arrays.stream(createInfo.getRefactoredClasses()))
-                .toArray(String[]::new);
-        n = refactorClasses.length;
-        for (int i = 0; i < n; i += 2) {
-            assert i + 1 < n;
-            String oldFqcn = binaryToInternalClassName(refactorClasses[i]);
-            String newFqcn = binaryToInternalClassName(refactorClasses[i + 1]);
-            mRefactorClasses.put(oldFqcn, newFqcn);
-        }
-
-        // create the map of renamed class -> return type of method to delete.
-        mDeleteReturns = new HashMap<>();
-        String[] deleteReturns = createInfo.getDeleteReturns();
-        Set<String> returnTypes = null;
-        String renamedClass = null;
-        for (String className : deleteReturns) {
-            // if we reach the end of a section, add it to the main map
-            if (className == null) {
-                if (returnTypes != null) {
-                    mDeleteReturns.put(renamedClass, returnTypes);
-                }
-
-                renamedClass = null;
-                continue;
-            }
-
-            // if the renamed class is null, this is the beginning of a section
-            if (renamedClass == null) {
-                renamedClass = binaryToInternalClassName(className);
-                continue;
-            }
-
-            // just a standard return type, we add it to the list.
-            if (returnTypes == null) {
-                returnTypes = new HashSet<>();
-            }
-            returnTypes.add(binaryToInternalClassName(className));
-        }
-
-        mPromotedFields = new HashMap<>();
-        addToMap(createInfo.getPromotedFields(), mPromotedFields);
-
-        mInjectedMethodsMap = createInfo.getInjectedMethodsMap();
-
-        mPromotedClasses =
-                Arrays.stream(createInfo.getPromotedClasses()).collect(Collectors.toSet());
-    }
-
-    /**
-     * For each value in the array, split the value on '#' and add the parts to the map as key
-     * and value.
-     */
-    private void addToMap(String[] entries, Map<String, Set<String>> map) {
-        for (String entry : entries) {
-            int pos = entry.indexOf('#');
-            if (pos <= 0 || pos >= entry.length() - 1) {
-                return;
-            }
-            String className = binaryToInternalClassName(entry.substring(0, pos));
-            String methodOrFieldName = entry.substring(pos + 1);
-            Set<String> set = map.get(className);
-            if (set == null) {
-                set = new HashSet<>();
-                map.put(className, set);
-            }
-            set.add(methodOrFieldName);
-        }
-    }
-
-    /**
-     * Returns the list of classes that have not been renamed yet.
-     * <p/>
-     * The names are "internal class names" rather than FQCN, i.e. they use "/" instead "."
-     * as package separators.
-     */
-    public Set<String> getClassesNotRenamed() {
-        return mClassesNotRenamed;
-    }
-
-    /**
-     * Utility that returns the internal ASM class name from a fully qualified binary class
-     * name. E.g. it returns android/view/View from android.view.View.
-     */
-    String binaryToInternalClassName(String className) {
-        if (className == null) {
-            return null;
-        } else {
-            return className.replace('.', '/');
-        }
-    }
-
-    /** Sets the map of classes to output as-is, except if they have native methods */
-    public void setKeep(Map<String, ClassReader> keep) {
-        mKeep = keep;
-    }
-
-    /** Sets the map of dependencies that must be completely stubbed */
-    public void setDeps(Map<String, ClassReader> deps) {
-        mDeps = deps;
-    }
-
-    /** Sets the map of files to output as-is. */
-    public void setCopyFiles(Map<String, InputStream> copyFiles) {
-        mCopyFiles = copyFiles;
-    }
-
-    public void setRewriteMethodCallClasses(Set<String> rewriteMethodCallClasses) {
-        mReplaceMethodCallsClasses = rewriteMethodCallClasses;
-    }
-
-    /** Generates the final JAR */
-    public void generate() throws IOException {
-        TreeMap<String, byte[]> all = new TreeMap<>();
-
-        for (Class<?> clazz : mInjectClasses) {
-            String name = classToEntryPath(clazz);
-            InputStream is = ClassLoader.getSystemResourceAsStream(name);
-            ClassReader cr = new ClassReader(is);
-            byte[] b = transform(cr, true);
-            name = classNameToEntryPath(transformName(cr.getClassName()));
-            all.put(name, b);
-        }
-
-        for (Entry<String, ClassReader> entry : mDeps.entrySet()) {
-            ClassReader cr = entry.getValue();
-            byte[] b = transform(cr, true);
-            String name = classNameToEntryPath(transformName(cr.getClassName()));
-            all.put(name, b);
-        }
-
-        for (Entry<String, ClassReader> entry : mKeep.entrySet()) {
-            ClassReader cr = entry.getValue();
-            byte[] b = transform(cr, true);
-            String name = classNameToEntryPath(transformName(cr.getClassName()));
-            all.put(name, b);
-        }
-
-        for (Entry<String, InputStream> entry : mCopyFiles.entrySet()) {
-            try {
-                byte[] b = inputStreamToByteArray(entry.getValue());
-                all.put(entry.getKey(), b);
-            } catch (IOException e) {
-                // Ignore.
-            }
-
-        }
-        mLog.info("# deps classes: %d", mDeps.size());
-        mLog.info("# keep classes: %d", mKeep.size());
-        mLog.info("# renamed     : %d", mRenameCount);
-
-        createJar(new FileOutputStream(mOsDestJar), all);
-        mLog.info("Created JAR file %s", mOsDestJar);
-    }
-
-    /**
-     * Writes the JAR file.
-     *
-     * @param outStream The file output stream were to write the JAR.
-     * @param all The map of all classes to output.
-     * @throws IOException if an I/O error has occurred
-     */
-    void createJar(FileOutputStream outStream, Map<String,byte[]> all) throws IOException {
-        JarOutputStream jar = new JarOutputStream(outStream);
-        for (Entry<String, byte[]> entry : all.entrySet()) {
-            String name = entry.getKey();
-            JarEntry jar_entry = new JarEntry(name);
-            jar.putNextEntry(jar_entry);
-            jar.write(entry.getValue());
-            jar.closeEntry();
-        }
-        jar.flush();
-        jar.close();
-    }
-
-    /**
-     * Utility method that converts a fully qualified java name into a JAR entry path
-     * e.g. for the input "android.view.View" it returns "android/view/View.class"
-     */
-    String classNameToEntryPath(String className) {
-        return className.replace('.', '/').concat(".class");
-    }
-
-    /**
-     * Utility method to get the JAR entry path from a Class name.
-     * e.g. it returns something like "com/foo/OuterClass$InnerClass1$InnerClass2.class"
-     */
-    private String classToEntryPath(Class<?> clazz) {
-        return classNameToEntryPath(clazz.getName());
-    }
-
-    /**
-     * Transforms a class.
-     * <p/>
-     * There are 3 kind of transformations:
-     *
-     * 1- For "mock" dependencies classes, we want to remove all code from methods and replace
-     * by a stub. Native methods must be implemented with this stub too. Abstract methods are
-     * left intact. Modified classes must be overridable (non-private, non-final).
-     * Native methods must be made non-final, non-private.
-     *
-     * 2- For "keep" classes, we want to rewrite all native methods as indicated above.
-     * If a class has native methods, it must also be made non-private, non-final.
-     *
-     * Note that unfortunately static methods cannot be changed to non-static (since static and
-     * non-static are invoked differently.)
-     */
-    byte[] transform(ClassReader cr, boolean stubNativesOnly) {
-
-        boolean hasNativeMethods = hasNativeMethods(cr);
-
-        // Get the class name, as an internal name (e.g. com/android/SomeClass$InnerClass)
-        String className = cr.getClassName();
-
-        String newName = transformName(className);
-        // transformName returns its input argument if there's no need to rename the class
-        if (!newName.equals(className)) {
-            mRenameCount++;
-            // This class is being renamed, so remove it from the list of classes not renamed.
-            mClassesNotRenamed.remove(className);
-        }
-
-        mLog.debug("Transform %s%s%s%s", className,
-                newName.equals(className) ? "" : " (renamed to " + newName + ")",
-                hasNativeMethods ? " -- has natives" : "",
-                stubNativesOnly ? " -- stub natives only" : "");
-
-        // Rewrite the new class from scratch, without reusing the constant pool from the
-        // original class reader.
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
-
-        ClassVisitor cv = cw;
-
-        // FIXME Generify
-        if ("android/content/res/Resources".equals(className)) {
-            cv = new FieldInjectorAdapter(cv);
-        }
-        if (mReplaceMethodCallsClasses.contains(className)) {
-            cv = new ReplaceMethodCallsAdapter(cv, className);
-        }
-
-        cv = new RefactorClassAdapter(cv, mRefactorClasses);
-        if (!newName.equals(className)) {
-            cv = new RenameClassAdapter(cv, className, newName);
-        }
-
-        String binaryNewName = newName.replace('/', '.');
-        if (mInjectedMethodsMap.keySet().contains(binaryNewName)) {
-            cv = new InjectMethodsAdapter(cv, mInjectedMethodsMap.get(binaryNewName));
-        }
-        cv = new TransformClassAdapter(mLog, Collections.emptySet(), mDeleteReturns.get(className),
-                newName, cv, stubNativesOnly);
-
-        Set<String> delegateMethods = mDelegateMethods.get(className);
-        if (delegateMethods != null && !delegateMethods.isEmpty()) {
-            // If delegateMethods only contains one entry ALL_NATIVES and the class is
-            // known to have no native methods, just skip this step.
-            if (hasNativeMethods ||
-                    !(delegateMethods.size() == 1 &&
-                            delegateMethods.contains(DelegateClassAdapter.ALL_NATIVES))) {
-                cv = new DelegateClassAdapter(mLog, cv, className, delegateMethods);
-            }
-        }
-
-        Set<String> promoteFields = mPromotedFields.get(className);
-        if (promoteFields != null && !promoteFields.isEmpty()) {
-            cv = new PromoteFieldClassAdapter(cv, promoteFields);
-        }
-        if (!mPromotedClasses.isEmpty()) {
-            cv = new PromoteClassClassAdapter(cv, mPromotedClasses);
-        }
-        cr.accept(cv, 0);
-
-        return cw.toByteArray();
-    }
-
-    /**
-     * Should this class be renamed, this returns the new name. Otherwise it returns the
-     * original name.
-     *
-     * @param className The internal ASM name of the class that may have to be renamed
-     * @return A new transformed name or the original input argument.
-     */
-    String transformName(String className) {
-        String newName = mRenameClasses.get(className);
-        if (newName != null) {
-            return newName;
-        }
-        int pos = className.indexOf('$');
-        if (pos > 0) {
-            // Is this an inner class of a renamed class?
-            String base = className.substring(0, pos);
-            newName = mRenameClasses.get(base);
-            if (newName != null) {
-                return newName + className.substring(pos);
-            }
-        }
-
-        return className;
-    }
-
-    /**
-     * Returns true if a class has any native methods.
-     */
-    boolean hasNativeMethods(ClassReader cr) {
-        ClassHasNativeVisitor cv = new ClassHasNativeVisitor();
-        cr.accept(cv, 0);
-        return cv.hasNativeMethods();
-    }
-
-    private byte[] inputStreamToByteArray(InputStream is) throws IOException {
-        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        byte[] data = new byte[8192];  // 8KB
-        int n;
-        while ((n = is.read(data, 0, data.length)) != -1) {
-            buffer.write(data, 0, n);
-        }
-        return buffer.toByteArray();
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
deleted file mode 100644
index 4748a7c..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.VisibleForTesting;
-import com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Indicates if a class contains any native methods.
- */
-public class ClassHasNativeVisitor extends ClassVisitor {
-    public ClassHasNativeVisitor() {
-        super(Main.ASM_VERSION);
-    }
-
-    private boolean mHasNativeMethods = false;
-
-    public boolean hasNativeMethods() {
-        return mHasNativeMethods;
-    }
-
-    @VisibleForTesting(visibility=Visibility.PRIVATE)
-    protected void setHasNativeMethods(boolean hasNativeMethods, String methodName) {
-        mHasNativeMethods = hasNativeMethods;
-    }
-
-    @Override
-    public void visit(int version, int access, String name, String signature,
-            String superName, String[] interfaces) {
-        // pass
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void visitAttribute(Attribute attr) {
-        // pass
-    }
-
-    @Override
-    public void visitEnd() {
-        // pass
-    }
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc,
-            String signature, Object value) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void visitInnerClass(String name, String outerName,
-            String innerName, int access) {
-        // pass
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-        if ((access & Opcodes.ACC_NATIVE) != 0) {
-            setHasNativeMethods(true, name);
-        }
-        return null;
-    }
-
-    @Override
-    public void visitOuterClass(String owner, String name, String desc) {
-        // pass
-    }
-
-    @Override
-    public void visitSource(String source, String debug) {
-        // pass
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
deleted file mode 100644
index cb0bc6d..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.java.AutoCloseable;
-import com.android.tools.layoutlib.java.Charsets;
-import com.android.tools.layoutlib.java.IntegralToString;
-import com.android.tools.layoutlib.java.LinkedHashMap_Delegate;
-import com.android.tools.layoutlib.java.Objects;
-import com.android.tools.layoutlib.java.System_Delegate;
-import com.android.tools.layoutlib.java.UnsafeByteSequence;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Describes the work to be done by {@link AsmGenerator}.
- */
-public final class CreateInfo implements ICreateInfo {
-
-    @Override
-    public Class<?>[] getInjectedClasses() {
-        return INJECTED_CLASSES;
-    }
-
-    @Override
-    public String[] getDelegateMethods() {
-        return DELEGATE_METHODS;
-    }
-
-    @Override
-    public String[] getDelegateClassNatives() {
-        return DELEGATE_CLASS_NATIVES;
-    }
-
-    @Override
-    public String[] getRenamedClasses() {
-        return RENAMED_CLASSES;
-    }
-
-    @Override
-    public String[] getDeleteReturns() {
-        return DELETE_RETURNS;
-    }
-
-    @Override
-    public String[] getJavaPkgClasses() {
-      return JAVA_PKG_CLASSES;
-    }
-
-    @Override
-    public String[] getRefactoredClasses() {
-        return REFACTOR_CLASSES;
-    }
-
-    @Override
-    public Set<String> getExcludedClasses() {
-        String[] refactoredClasses = getJavaPkgClasses();
-        int count = refactoredClasses.length / 2 + EXCLUDED_CLASSES.length;
-        Set<String> excludedClasses = new HashSet<>(count);
-        for (int i = 0; i < refactoredClasses.length; i+=2) {
-            excludedClasses.add(refactoredClasses[i]);
-        }
-        excludedClasses.addAll(Arrays.asList(EXCLUDED_CLASSES));
-        return excludedClasses;
-    }
-
-    @Override
-    public String[] getPromotedFields() {
-        return PROMOTED_FIELDS;
-    }
-
-    @Override
-    public String[] getPromotedClasses() {
-        return PROMOTED_CLASSES;
-    }
-
-    @Override
-    public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
-        return INJECTED_METHODS;
-    }
-
-    //-----
-
-    /**
-     * The list of class from layoutlib_create to inject in layoutlib.
-     */
-    private final static Class<?>[] INJECTED_CLASSES = new Class<?>[] {
-            OverrideMethod.class,
-            MethodListener.class,
-            MethodAdapter.class,
-            ICreateInfo.class,
-            CreateInfo.class,
-            LayoutlibDelegate.class,
-            InjectMethodRunnable.class,
-            InjectMethodRunnables.class,
-            /* Java package classes */
-            IntegralToString.class,
-            UnsafeByteSequence.class,
-            System_Delegate.class,
-            LinkedHashMap_Delegate.class,
-        };
-
-    /**
-     * The list of methods to rewrite as delegates.
-     */
-    public final static String[] DELEGATE_METHODS = new String[] {
-        "android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;",
-        "android.content.res.Resources#getAnimation",
-        "android.content.res.Resources#getBoolean",
-        "android.content.res.Resources#getColor",
-        "android.content.res.Resources#getColorStateList",
-        "android.content.res.Resources#getDimension",
-        "android.content.res.Resources#getDimensionPixelOffset",
-        "android.content.res.Resources#getDimensionPixelSize",
-        "android.content.res.Resources#getDrawable",
-        "android.content.res.Resources#getFont",
-        "android.content.res.Resources#getIntArray",
-        "android.content.res.Resources#getInteger",
-        "android.content.res.Resources#getLayout",
-        "android.content.res.Resources#getQuantityString",
-        "android.content.res.Resources#getQuantityText",
-        "android.content.res.Resources#getResourceEntryName",
-        "android.content.res.Resources#getResourceName",
-        "android.content.res.Resources#getResourcePackageName",
-        "android.content.res.Resources#getResourceTypeName",
-        "android.content.res.Resources#getString",
-        "android.content.res.Resources#getStringArray",
-        "android.content.res.Resources#getText",
-        "android.content.res.Resources#getTextArray",
-        "android.content.res.Resources#getValue",
-        "android.content.res.Resources#getXml",
-        "android.content.res.Resources#loadXmlResourceParser",
-        "android.content.res.Resources#obtainAttributes",
-        "android.content.res.Resources#obtainTypedArray",
-        "android.content.res.Resources#openRawResource",
-        "android.content.res.Resources#openRawResourceFd",
-        "android.content.res.Resources$Theme#obtainStyledAttributes",
-        "android.content.res.Resources$Theme#resolveAttribute",
-        "android.content.res.Resources$Theme#resolveAttributes",
-        "android.content.res.AssetManager#newTheme",
-        "android.content.res.AssetManager#deleteTheme",
-        "android.content.res.AssetManager#getAssignedPackageIdentifiers",
-        "android.content.res.TypedArray#getValueAt",
-        "android.content.res.TypedArray#obtain",
-        "android.graphics.BitmapFactory#finishDecode",
-        "android.graphics.BitmapFactory#setDensityFromOptions",
-        "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#useLastSeenTarget",
-        "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#onDraw",
-        "android.graphics.drawable.GradientDrawable#buildRing",
-        "android.graphics.FontFamily#addFont",
-        "android.graphics.Typeface#getSystemFontConfigLocation",
-        "android.graphics.Typeface#makeFamilyFromParsed",
-        "android.os.Handler#sendMessageAtTime",
-        "android.os.HandlerThread#run",
-        "android.preference.Preference#getView",
-        "android.text.format.DateFormat#is24HourFormat",
-        "android.text.Hyphenator#getSystemHyphenatorLocation",
-        "android.util.Xml#newPullParser",
-        "android.view.Choreographer#getInstance",
-        "android.view.Choreographer#getRefreshRate",
-        "android.view.Choreographer#scheduleVsyncLocked",
-        "android.view.Display#updateDisplayInfoLocked",
-        "android.view.Display#getWindowManager",
-        "android.view.HandlerActionQueue#postDelayed",
-        "android.view.LayoutInflater#rInflate",
-        "android.view.LayoutInflater#parseInclude",
-        "android.view.View#getWindowToken",
-        "android.view.View#isInEditMode",
-        "android.view.ViewRootImpl#isInTouchMode",
-        "android.view.WindowManagerGlobal#getWindowManagerService",
-        "android.view.inputmethod.InputMethodManager#getInstance",
-        "android.view.MenuInflater#registerMenu",
-        "android.view.RenderNode#getMatrix",
-        "android.view.RenderNode#nCreate",
-        "android.view.RenderNode#nGetNativeFinalizer",
-        "android.view.RenderNode#nSetElevation",
-        "android.view.RenderNode#nGetElevation",
-        "android.view.RenderNode#nSetTranslationX",
-        "android.view.RenderNode#nGetTranslationX",
-        "android.view.RenderNode#nSetTranslationY",
-        "android.view.RenderNode#nGetTranslationY",
-        "android.view.RenderNode#nSetTranslationZ",
-        "android.view.RenderNode#nGetTranslationZ",
-        "android.view.RenderNode#nSetRotation",
-        "android.view.RenderNode#nGetRotation",
-        "android.view.RenderNode#nSetLeft",
-        "android.view.RenderNode#nSetTop",
-        "android.view.RenderNode#nSetRight",
-        "android.view.RenderNode#nSetBottom",
-        "android.view.RenderNode#nSetLeftTopRightBottom",
-        "android.view.RenderNode#nSetPivotX",
-        "android.view.RenderNode#nGetPivotX",
-        "android.view.RenderNode#nSetPivotY",
-        "android.view.RenderNode#nGetPivotY",
-        "android.view.RenderNode#nSetScaleX",
-        "android.view.RenderNode#nGetScaleX",
-        "android.view.RenderNode#nSetScaleY",
-        "android.view.RenderNode#nGetScaleY",
-        "android.view.RenderNode#nIsPivotExplicitlySet",
-        "android.view.PointerIcon#loadResource",
-        "android.view.ViewGroup#drawChild",
-        "com.android.internal.view.menu.MenuBuilder#createNewMenuItem",
-        "com.android.internal.util.XmlUtils#convertValueToInt",
-        "dalvik.system.VMRuntime#newUnpaddedArray",
-        "libcore.io.MemoryMappedFile#mmapRO",
-        "libcore.io.MemoryMappedFile#close",
-        "libcore.io.MemoryMappedFile#bigEndianIterator",
-        "libcore.util.NativeAllocationRegistry#applyFreeFunction",
-    };
-
-    /**
-     * The list of classes on which to delegate all native methods.
-     */
-    public final static String[] DELEGATE_CLASS_NATIVES = new String[] {
-        "android.animation.PropertyValuesHolder",
-        "android.graphics.BaseCanvas",
-        "android.graphics.Bitmap",
-        "android.graphics.BitmapFactory",
-        "android.graphics.BitmapShader",
-        "android.graphics.BlurMaskFilter",
-        "android.graphics.Canvas",
-        "android.graphics.ColorFilter",
-        "android.graphics.ColorMatrixColorFilter",
-        "android.graphics.ComposePathEffect",
-        "android.graphics.ComposeShader",
-        "android.graphics.CornerPathEffect",
-        "android.graphics.DashPathEffect",
-        "android.graphics.DiscretePathEffect",
-        "android.graphics.DrawFilter",
-        "android.graphics.EmbossMaskFilter",
-        "android.graphics.FontFamily",
-        "android.graphics.LightingColorFilter",
-        "android.graphics.LinearGradient",
-        "android.graphics.MaskFilter",
-        "android.graphics.Matrix",
-        "android.graphics.NinePatch",
-        "android.graphics.Paint",
-        "android.graphics.PaintFlagsDrawFilter",
-        "android.graphics.Path",
-        "android.graphics.PathDashPathEffect",
-        "android.graphics.PathEffect",
-        "android.graphics.PathMeasure",
-        "android.graphics.PorterDuffColorFilter",
-        "android.graphics.RadialGradient",
-        "android.graphics.Region",
-        "android.graphics.Shader",
-        "android.graphics.SumPathEffect",
-        "android.graphics.SweepGradient",
-        "android.graphics.Typeface",
-        "android.graphics.drawable.AnimatedVectorDrawable",
-        "android.graphics.drawable.VectorDrawable",
-        "android.os.SystemClock",
-        "android.os.SystemProperties",
-        "android.text.AndroidBidi",
-        "android.text.StaticLayout",
-        "android.util.PathParser",
-        "android.view.Display",
-        "com.android.internal.util.VirtualRefBasePtr",
-        "com.android.internal.view.animation.NativeInterpolatorFactoryHelper",
-        "libcore.icu.ICU",
-    };
-
-    /**
-     *  The list of classes to rename, must be an even list: the binary FQCN
-     *  of class to replace followed by the new FQCN.
-     */
-    private final static String[] RENAMED_CLASSES =
-        new String[] {
-            "android.os.ServiceManager",                       "android.os._Original_ServiceManager",
-            "android.view.textservice.TextServicesManager",    "android.view.textservice._Original_TextServicesManager",
-            "android.util.LruCache",                           "android.util._Original_LruCache",
-            "android.view.SurfaceView",                        "android.view._Original_SurfaceView",
-            "android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager",
-            "android.webkit.WebView",                          "android.webkit._Original_WebView",
-        };
-
-    /**
-     * The list of class references to update, must be an even list: the binary
-     * FQCN of class to replace followed by the new FQCN. The classes to
-     * replace are to be excluded from the output.
-     */
-    private final static String[] JAVA_PKG_CLASSES =
-        new String[] {
-            "java.nio.charset.Charsets",                       "java.nio.charset.StandardCharsets",
-            "java.lang.IntegralToString",                      "com.android.tools.layoutlib.java.IntegralToString",
-            "java.lang.UnsafeByteSequence",                    "com.android.tools.layoutlib.java.UnsafeByteSequence",
-            // Use android.icu.text versions of DateFormat and SimpleDateFormat since the
-            // original ones do not match the Android implementation
-            "java.text.DateFormat",                            "android.icu.text.DateFormat",
-            "java.text.SimpleDateFormat",                      "android.icu.text.SimpleDateFormat",
-        };
-
-    /**
-     * List of classes to refactor. This is similar to combining {@link #getRenamedClasses()} and
-     * {@link #getJavaPkgClasses()}.
-     * Classes included here will be renamed and then all their references in any other classes
-     * will be also modified.
-     * FQCN of class to refactor followed by its new FQCN.
-     */
-    private final static String[] REFACTOR_CLASSES =
-            new String[] {
-                    "android.os.Build",                                "android.os._Original_Build",
-            };
-
-    private final static String[] EXCLUDED_CLASSES =
-        new String[] {
-            "android.preference.PreferenceActivity",
-            "org.kxml2.io.KXmlParser",
-        };
-
-    /**
-     * List of fields for which we will update the visibility to be public. This is sometimes
-     * needed when access from the delegate classes is needed.
-     */
-    private final static String[] PROMOTED_FIELDS = new String[] {
-        "android.graphics.drawable.VectorDrawable#mVectorState",
-        "android.view.Choreographer#mLastFrameTimeNanos",
-        "android.graphics.FontFamily#mBuilderPtr",
-        "android.graphics.Typeface#sDynamicTypefaceCache"
-    };
-
-    /**
-     * List of classes to be promoted to public visibility. Prefer using PROMOTED_FIELDS to this
-     * if possible.
-     */
-    private final static String[] PROMOTED_CLASSES = new String[] {
-    };
-
-    /**
-     * List of classes for which the methods returning them should be deleted.
-     * The array contains a list of null terminated section starting with the name of the class
-     * to rename in which the methods are deleted, followed by a list of return types identifying
-     * the methods to delete.
-     */
-    private final static String[] DELETE_RETURNS =
-        new String[] {
-            null };                         // separator, for next class/methods list.
-
-    private final static Map<String, InjectMethodRunnable> INJECTED_METHODS =
-            new HashMap<String, InjectMethodRunnable>(1) {{
-                put("android.content.Context",
-                        InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER);
-            }};
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
deleted file mode 100644
index cbb3a8a..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-import java.util.Set;
-
-/**
- * A {@link DelegateClassAdapter} can transform some methods from a class into
- * delegates that defer the call to an associated delegate class.
- * <p/>
- * This is used to override specific methods and or all native methods in classes.
- */
-public class DelegateClassAdapter extends ClassVisitor {
-
-    /** Suffix added to original methods. */
-    private static final String ORIGINAL_SUFFIX = "_Original";
-    private static final String CONSTRUCTOR = "<init>";
-    private static final String CLASS_INIT = "<clinit>";
-
-    public static final String ALL_NATIVES = "<<all_natives>>";
-
-    private final String mClassName;
-    private final Set<String> mDelegateMethods;
-    private final Log mLog;
-    private boolean mIsStaticInnerClass;
-
-    /**
-     * Creates a new {@link DelegateClassAdapter} that can transform some methods
-     * from a class into delegates that defer the call to an associated delegate class.
-     * <p/>
-     * This is used to override specific methods and or all native methods in classes.
-     *
-     * @param log The logger object. Must not be null.
-     * @param cv the class visitor to which this adapter must delegate calls.
-     * @param className The internal class name of the class to visit,
-     *          e.g. <code>com/android/SomeClass$InnerClass</code>.
-     * @param delegateMethods The set of method names to modify and/or the
-     *          special constant {@link #ALL_NATIVES} to convert all native methods.
-     */
-    public DelegateClassAdapter(Log log,
-            ClassVisitor cv,
-            String className,
-            Set<String> delegateMethods) {
-        super(Main.ASM_VERSION, cv);
-        mLog = log;
-        mClassName = className;
-        mDelegateMethods = delegateMethods;
-        // If this is an inner class, by default, we assume it's static. If it's not we will detect
-        // by looking at the fields (see visitField)
-        mIsStaticInnerClass = className.contains("$");
-    }
-
-    //----------------------------------
-    // Methods from the ClassAdapter
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc, String signature,
-            Object value) {
-        if (mIsStaticInnerClass && "this$0".equals(name)) {
-            // Having a "this$0" field, proves that this class is not a static inner class.
-            mIsStaticInnerClass = false;
-        }
-
-        return super.visitField(access, name, desc, signature, value);
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-
-        boolean isStaticMethod = (access & Opcodes.ACC_STATIC) != 0;
-        boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
-
-        boolean useDelegate = (isNative && mDelegateMethods.contains(ALL_NATIVES)) ||
-                              mDelegateMethods.contains(name);
-
-        if (!useDelegate) {
-            // Not creating a delegate for this method, pass it as-is from the reader to the writer.
-            return super.visitMethod(access, name, desc, signature, exceptions);
-        }
-
-        if (CONSTRUCTOR.equals(name) || CLASS_INIT.equals(name)) {
-            // We don't currently support generating delegates for constructors.
-            throw new UnsupportedOperationException(
-                String.format(
-                    "Delegate doesn't support overriding constructor %1$s:%2$s(%3$s)",  //$NON-NLS-1$
-                    mClassName, name, desc));
-        }
-
-        if (isNative) {
-            // Remove native flag
-            access = access & ~Opcodes.ACC_NATIVE;
-            MethodVisitor mwDelegate = super.visitMethod(access, name, desc, signature, exceptions);
-
-            DelegateMethodAdapter a = new DelegateMethodAdapter(
-                    mLog, null, mwDelegate, mClassName, name, desc, isStaticMethod,
-                    mIsStaticInnerClass);
-
-            // A native has no code to visit, so we need to generate it directly.
-            a.generateDelegateCode();
-
-            return mwDelegate;
-        }
-
-        // Given a non-native SomeClass.MethodName(), we want to generate 2 methods:
-        // - A copy of the original method named SomeClass.MethodName_Original().
-        //   The content is the original method as-is from the reader.
-        // - A brand new implementation of SomeClass.MethodName() which calls to a
-        //   non-existing method named SomeClass_Delegate.MethodName().
-        //   The implementation of this 'delegate' method is done in layoutlib_bridge.
-
-        int accessDelegate = access;
-        access = access & ~Opcodes.ACC_PRIVATE;  // If private, make it package protected.
-
-        MethodVisitor mwOriginal = super.visitMethod(access, name + ORIGINAL_SUFFIX,
-                                                     desc, signature, exceptions);
-        MethodVisitor mwDelegate = super.visitMethod(accessDelegate, name,
-                                                     desc, signature, exceptions);
-
-        return new DelegateMethodAdapter(
-                mLog, mwOriginal, mwDelegate, mClassName, name, desc, isStaticMethod,
-                mIsStaticInnerClass);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java
deleted file mode 100644
index da8babc..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.util.ArrayList;
-
-/**
- * This method adapter generates delegate methods.
- * <p/>
- * Given a method {@code SomeClass.MethodName()}, this generates 1 or 2 methods:
- * <ul>
- * <li> A copy of the original method named {@code SomeClass.MethodName_Original()}.
- *   The content is the original method as-is from the reader.
- *   This step is omitted if the method is native, since it has no Java implementation.
- * <li> A brand new implementation of {@code SomeClass.MethodName()} which calls to a
- *   non-existing method named {@code SomeClass_Delegate.MethodName()}.
- *   The implementation of this 'delegate' method is done in layoutlib_brigde.
- * </ul>
- * A method visitor is generally constructed to generate a single method; however
- * here we might want to generate one or two depending on the context. To achieve
- * that, the visitor here generates the 'original' method and acts as a no-op if
- * no such method exists (e.g. when the original is a native method).
- * The delegate method is generated after the {@code visitEnd} of the original method
- * or by having the class adapter <em>directly</em> call {@link #generateDelegateCode()}
- * for native methods.
- * <p/>
- * When generating the 'delegate', the implementation generates a call to a class
- * class named <code>&lt;className&gt;_Delegate</code> with static methods matching
- * the methods to be overridden here. The methods have the same return type.
- * The argument type list is the same except the "this" reference is passed first
- * for non-static methods.
- * <p/>
- * A new annotation is added to these 'delegate' methods so that we can easily find them
- * for automated testing.
- * <p/>
- * This class isn't intended to be generic or reusable.
- * It is called by {@link DelegateClassAdapter}, which takes care of properly initializing
- * the two method writers for the original and the delegate class, as needed, with their
- * expected names.
- * <p/>
- * The class adapter also takes care of calling {@link #generateDelegateCode()} directly for
- * a native and use the visitor pattern for non-natives.
- * Note that native methods have, by definition, no code so there's nothing a visitor
- * can visit.
- * <p/>
- * Instances of this class are not re-usable.
- * The class adapter creates a new instance for each method.
- */
-class DelegateMethodAdapter extends MethodVisitor {
-
-    /** Suffix added to delegate classes. */
-    public static final String DELEGATE_SUFFIX = "_Delegate";
-
-    /** The parent method writer to copy of the original method.
-     *  Null when dealing with a native original method. */
-    private MethodVisitor mOrgWriter;
-    /** The parent method writer to generate the delegating method. Never null. */
-    private MethodVisitor mDelWriter;
-    /** The original method descriptor (return type + argument types.) */
-    private String mDesc;
-    /** True if the original method is static. */
-    private final boolean mIsStatic;
-    /** True if the method is contained in a static inner class */
-    private final boolean mIsStaticInnerClass;
-    /** The internal class name (e.g. <code>com/android/SomeClass$InnerClass</code>.) */
-    private final String mClassName;
-    /** The method name. */
-    private final String mMethodName;
-    /** Logger object. */
-    private final Log mLog;
-
-    /** Array used to capture the first line number information from the original method
-     *  and duplicate it in the delegate. */
-    private Object[] mDelegateLineNumber;
-
-    /**
-     * Creates a new {@link DelegateMethodAdapter} that will transform this method
-     * into a delegate call.
-     * <p/>
-     * See {@link DelegateMethodAdapter} for more details.
-     *
-     * @param log The logger object. Must not be null.
-     * @param mvOriginal The parent method writer to copy of the original method.
-     *          Must be {@code null} when dealing with a native original method.
-     * @param mvDelegate The parent method writer to generate the delegating method.
-     *          Must never be null.
-     * @param className The internal class name of the class to visit,
-     *          e.g. <code>com/android/SomeClass$InnerClass</code>.
-     * @param methodName The simple name of the method.
-     * @param desc A method descriptor (c.f. {@link Type#getReturnType(String)} +
-     *          {@link Type#getArgumentTypes(String)})
-     * @param isStatic True if the method is declared static.
-     */
-    public DelegateMethodAdapter(Log log,
-            MethodVisitor mvOriginal,
-            MethodVisitor mvDelegate,
-            String className,
-            String methodName,
-            String desc,
-            boolean isStatic,
-            boolean isStaticClass) {
-        super(Main.ASM_VERSION);
-        mLog = log;
-        mOrgWriter = mvOriginal;
-        mDelWriter = mvDelegate;
-        mClassName = className;
-        mMethodName = methodName;
-        mDesc = desc;
-        mIsStatic = isStatic;
-        mIsStaticInnerClass = isStaticClass;
-    }
-
-    /**
-     * Generates the new code for the method.
-     * <p/>
-     * For native methods, this must be invoked directly by {@link DelegateClassAdapter}
-     * (since they have no code to visit).
-     * <p/>
-     * Otherwise for non-native methods the {@link DelegateClassAdapter} simply needs to
-     * return this instance of {@link DelegateMethodAdapter} and let the normal visitor pattern
-     * invoke it as part of the {@link ClassReader#accept(ClassVisitor, int)} workflow and then
-     * this method will be invoked from {@link MethodVisitor#visitEnd()}.
-     */
-    public void generateDelegateCode() {
-        /*
-         * The goal is to generate a call to a static delegate method.
-         * If this method is non-static, the first parameter will be 'this'.
-         * All the parameters must be passed and then the eventual return type returned.
-         *
-         * Example, let's say we have a method such as
-         *   public void myMethod(int a, Object b, ArrayList<String> c) { ... }
-         *
-         * We'll want to create a body that calls a delegate method like this:
-         *   TheClass_Delegate.myMethod(this, a, b, c);
-         *
-         * If the method is non-static and the class name is an inner class (e.g. has $ in its
-         * last segment), we want to push the 'this' of the outer class first:
-         *   OuterClass_InnerClass_Delegate.myMethod(
-         *     OuterClass.this,
-         *     OuterClass$InnerClass.this,
-         *     a, b, c);
-         *
-         * Only one level of inner class is supported right now, for simplicity and because
-         * we don't need more.
-         *
-         * The generated class name is the current class name with "_Delegate" appended to it.
-         * One thing to realize is that we don't care about generics -- since generic types
-         * are erased at build time, they have no influence on the method name being called.
-         */
-
-        // Add our annotation
-        AnnotationVisitor aw = mDelWriter.visitAnnotation(
-                Type.getObjectType(Type.getInternalName(LayoutlibDelegate.class)).toString(),
-                true); // visible at runtime
-        if (aw != null) {
-            aw.visitEnd();
-        }
-
-        mDelWriter.visitCode();
-
-        if (mDelegateLineNumber != null) {
-            Object[] p = mDelegateLineNumber;
-            mDelWriter.visitLineNumber((Integer) p[0], (Label) p[1]);
-        }
-
-        ArrayList<Type> paramTypes = new ArrayList<>();
-        String delegateClassName = mClassName + DELEGATE_SUFFIX;
-        boolean pushedArg0 = false;
-        int maxStack = 0;
-
-        // Check if the last segment of the class name has inner an class.
-        // Right now we only support one level of inner classes.
-        Type outerType = null;
-        int slash = mClassName.lastIndexOf('/');
-        int dol = mClassName.lastIndexOf('$');
-        if (dol != -1 && dol > slash && dol == mClassName.indexOf('$')) {
-            String outerClass = mClassName.substring(0, dol);
-            outerType = Type.getObjectType(outerClass);
-
-            // Change a delegate class name to "com/foo/Outer_Inner_Delegate"
-            delegateClassName = delegateClassName.replace('$', '_');
-        }
-
-        // For an instance method (e.g. non-static), push the 'this' preceded
-        // by the 'this' of any outer class, if any.
-        if (!mIsStatic) {
-
-            if (outerType != null && !mIsStaticInnerClass) {
-                // The first-level inner class has a package-protected member called 'this$0'
-                // that points to the outer class.
-
-                // Push this.getField("this$0") on the call stack.
-                mDelWriter.visitVarInsn(Opcodes.ALOAD, 0); // var 0 = this
-                mDelWriter.visitFieldInsn(Opcodes.GETFIELD,
-                        mClassName,                 // class where the field is defined
-                        "this$0",                   // field name
-                        outerType.getDescriptor()); // type of the field
-                maxStack++;
-                paramTypes.add(outerType);
-
-            }
-
-            // Push "this" for the instance method, which is always ALOAD 0
-            mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
-            maxStack++;
-            pushedArg0 = true;
-            paramTypes.add(Type.getObjectType(mClassName));
-        }
-
-        // Push all other arguments. Start at arg 1 if we already pushed 'this' above.
-        Type[] argTypes = Type.getArgumentTypes(mDesc);
-        int maxLocals = pushedArg0 ? 1 : 0;
-        for (Type t : argTypes) {
-            int size = t.getSize();
-            mDelWriter.visitVarInsn(t.getOpcode(Opcodes.ILOAD), maxLocals);
-            maxLocals += size;
-            maxStack += size;
-            paramTypes.add(t);
-        }
-
-        // Construct the descriptor of the delegate based on the parameters
-        // we pushed on the call stack. The return type remains unchanged.
-        String desc = Type.getMethodDescriptor(
-                Type.getReturnType(mDesc),
-                paramTypes.toArray(new Type[paramTypes.size()]));
-
-        // Invoke the static delegate
-        mDelWriter.visitMethodInsn(Opcodes.INVOKESTATIC,
-                delegateClassName,
-                mMethodName,
-                desc,
-                false);
-
-        Type returnType = Type.getReturnType(mDesc);
-        mDelWriter.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
-
-        mDelWriter.visitMaxs(maxStack, maxLocals);
-        mDelWriter.visitEnd();
-
-        // For debugging now. Maybe we should collect these and store them in
-        // a text file for helping create the delegates. We could also compare
-        // the text file to a golden and break the build on unsupported changes
-        // or regressions. Even better we could fancy-print something that looks
-        // like the expected Java method declaration.
-        mLog.debug("Delegate: %1$s # %2$s %3$s", delegateClassName, mMethodName, desc);
-    }
-
-    /* Pass down to visitor writer. In this implementation, either do nothing. */
-    @Override
-    public void visitCode() {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitCode();
-        }
-    }
-
-    /*
-     * visitMaxs is called just before visitEnd if there was any code to rewrite.
-     */
-    @Override
-    public void visitMaxs(int maxStack, int maxLocals) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitMaxs(maxStack, maxLocals);
-        }
-    }
-
-    /** End of visiting. Generate the delegating code. */
-    @Override
-    public void visitEnd() {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitEnd();
-        }
-        generateDelegateCode();
-    }
-
-    /* Writes all annotation from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        if (mOrgWriter != null) {
-            return mOrgWriter.visitAnnotation(desc, visible);
-        } else {
-            return null;
-        }
-    }
-
-    /* Writes all annotation default values from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotationDefault() {
-        if (mOrgWriter != null) {
-            return mOrgWriter.visitAnnotationDefault();
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-            boolean visible) {
-        if (mOrgWriter != null) {
-            return mOrgWriter.visitParameterAnnotation(parameter, desc, visible);
-        } else {
-            return null;
-        }
-    }
-
-    /* Writes all attributes from the original method. */
-    @Override
-    public void visitAttribute(Attribute attr) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitAttribute(attr);
-        }
-    }
-
-    /*
-     * Only writes the first line number present in the original code so that source
-     * viewers can direct to the correct method, even if the content doesn't match.
-     */
-    @Override
-    public void visitLineNumber(int line, Label start) {
-        // Capture the first line values for the new delegate method
-        if (mDelegateLineNumber == null) {
-            mDelegateLineNumber = new Object[] { line, start };
-        }
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLineNumber(line, start);
-        }
-    }
-
-    @Override
-    public void visitInsn(int opcode) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitInsn(opcode);
-        }
-    }
-
-    @Override
-    public void visitLabel(Label label) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLabel(label);
-        }
-    }
-
-    @Override
-    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitTryCatchBlock(start, end, handler, type);
-        }
-    }
-
-    @Override
-    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitMethodInsn(opcode, owner, name, desc, itf);
-        }
-    }
-
-    @Override
-    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitFieldInsn(opcode, owner, name, desc);
-        }
-    }
-
-    @Override
-    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitFrame(type, nLocal, local, nStack, stack);
-        }
-    }
-
-    @Override
-    public void visitIincInsn(int var, int increment) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitIincInsn(var, increment);
-        }
-    }
-
-    @Override
-    public void visitIntInsn(int opcode, int operand) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitIntInsn(opcode, operand);
-        }
-    }
-
-    @Override
-    public void visitJumpInsn(int opcode, Label label) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitJumpInsn(opcode, label);
-        }
-    }
-
-    @Override
-    public void visitLdcInsn(Object cst) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLdcInsn(cst);
-        }
-    }
-
-    @Override
-    public void visitLocalVariable(String name, String desc, String signature,
-            Label start, Label end, int index) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLocalVariable(name, desc, signature, start, end, index);
-        }
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLookupSwitchInsn(dflt, keys, labels);
-        }
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(String desc, int dims) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitMultiANewArrayInsn(desc, dims);
-        }
-    }
-
-    @Override
-    public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitTableSwitchInsn(min, max, dflt, labels);
-        }
-    }
-
-    @Override
-    public void visitTypeInsn(int opcode, String type) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitTypeInsn(opcode, type);
-        }
-    }
-
-    @Override
-    public void visitVarInsn(int opcode, int var) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitVarInsn(opcode, var);
-        }
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
deleted file mode 100644
index aa68ea0..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.VisibleForTesting;
-import com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.signature.SignatureReader;
-import org.objectweb.asm.signature.SignatureVisitor;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * Analyzes the input JAR using the ASM java bytecode manipulation library
- * to list the classes and their dependencies. A "dependency" is a class
- * used by another class.
- */
-public class DependencyFinder {
-
-    // Note: a bunch of stuff has package-level access for unit tests. Consider it private.
-
-    /** Output logger. */
-    private final Log mLog;
-
-    /**
-     * Creates a new analyzer.
-     *
-     * @param log The log output.
-     */
-    public DependencyFinder(Log log) {
-        mLog = log;
-    }
-
-    /**
-     * Starts the analysis using parameters from the constructor.
-     *
-     * @param osJarPath The input source JARs to parse.
-     * @return A pair: [0]: map { class FQCN => set of FQCN class dependencies }.
-     *                 [1]: map { missing class FQCN => set of FQCN class that uses it. }
-     */
-    public List<Map<String, Set<String>>> findDeps(List<String> osJarPath) throws IOException {
-
-        Map<String, ClassReader> zipClasses = parseZip(osJarPath);
-        mLog.info("Found %d classes in input JAR%s.",
-                zipClasses.size(),
-                osJarPath.size() > 1 ? "s" : "");
-
-        Map<String, Set<String>> deps = findClassesDeps(zipClasses);
-
-        Map<String, Set<String>> missing = findMissingClasses(deps, zipClasses.keySet());
-
-        List<Map<String, Set<String>>> result = new ArrayList<>(2);
-        result.add(deps);
-        result.add(missing);
-        return result;
-    }
-
-    /**
-     * Prints dependencies to the current logger, found stuff and missing stuff.
-     */
-    public void printAllDeps(List<Map<String, Set<String>>> result) {
-        assert result.size() == 2;
-        Map<String, Set<String>> deps = result.get(0);
-        Map<String, Set<String>> missing = result.get(1);
-
-        // Print all dependences found in the format:
-        // +Found: <FQCN from zip>
-        //     uses: FQCN
-
-        mLog.info("++++++ %d Entries found in source JARs", deps.size());
-        mLog.info("");
-
-        for (Entry<String, Set<String>> entry : deps.entrySet()) {
-            mLog.info(    "+Found  : %s", entry.getKey());
-            for (String dep : entry.getValue()) {
-                mLog.info("    uses: %s", dep);
-            }
-
-            mLog.info("");
-        }
-
-
-        // Now print all missing dependences in the format:
-        // -Missing <FQCN>:
-        //     used by: <FQCN>
-
-        mLog.info("");
-        mLog.info("------ %d Entries missing from source JARs", missing.size());
-        mLog.info("");
-
-        for (Entry<String, Set<String>> entry : missing.entrySet()) {
-            mLog.info(    "-Missing  : %s", entry.getKey());
-            for (String dep : entry.getValue()) {
-                mLog.info("   used by: %s", dep);
-            }
-
-            mLog.info("");
-        }
-    }
-
-    /**
-     * Prints only a summary of the missing dependencies to the current logger.
-     */
-    public void printMissingDeps(List<Map<String, Set<String>>> result) {
-        assert result.size() == 2;
-        @SuppressWarnings("unused") Map<String, Set<String>> deps = result.get(0);
-        Map<String, Set<String>> missing = result.get(1);
-
-        for (String fqcn : missing.keySet()) {
-            mLog.info("%s", fqcn);
-        }
-    }
-
-    // ----------------
-
-    /**
-     * Parses a JAR file and returns a list of all classes founds using a map
-     * class name => ASM ClassReader. Class names are in the form "android.view.View".
-     */
-    Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException {
-        TreeMap<String, ClassReader> classes = new TreeMap<>();
-
-        for (String jarPath : jarPathList) {
-            ZipFile zip = new ZipFile(jarPath);
-            Enumeration<? extends ZipEntry> entries = zip.entries();
-            ZipEntry entry;
-            while (entries.hasMoreElements()) {
-                entry = entries.nextElement();
-                if (entry.getName().endsWith(".class")) {
-                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
-                    String className = classReaderToClassName(cr);
-                    classes.put(className, cr);
-                }
-            }
-        }
-
-        return classes;
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name for a ClassReader.
-     * E.g. it returns something like android.view.View.
-     */
-    static String classReaderToClassName(ClassReader classReader) {
-        if (classReader == null) {
-            return null;
-        } else {
-            return classReader.getClassName().replace('/', '.');
-        }
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name from a path-like FQCN.
-     * E.g. it returns android.view.View from android/view/View.
-     */
-    static String internalToBinaryClassName(String className) {
-        if (className == null) {
-            return null;
-        } else {
-            return className.replace('/', '.');
-        }
-    }
-
-    /**
-     * Finds all dependencies for all classes in keepClasses which are also
-     * listed in zipClasses. Returns a map of all the dependencies found.
-     */
-    Map<String, Set<String>> findClassesDeps(Map<String, ClassReader> zipClasses) {
-
-        // The dependencies that we'll collect.
-        // It's a map Class name => uses class names.
-        Map<String, Set<String>> dependencyMap = new TreeMap<>();
-
-        DependencyVisitor visitor = getVisitor();
-
-        int count = 0;
-        try {
-            for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
-                String name = entry.getKey();
-
-                TreeSet<String> set = new TreeSet<>();
-                dependencyMap.put(name, set);
-                visitor.setDependencySet(set);
-
-                ClassReader cr = entry.getValue();
-                cr.accept(visitor, 0 /* flags */);
-
-                visitor.setDependencySet(null);
-
-                mLog.debugNoln("Visited %d classes\r", ++count);
-            }
-        } finally {
-            mLog.debugNoln("\n");
-        }
-
-        return dependencyMap;
-    }
-
-    /**
-     * Computes which classes FQCN were found as dependencies that are NOT listed
-     * in the original JAR classes.
-     *
-     * @param deps The map { FQCN => dependencies[] } returned by {@link #findClassesDeps(Map)}.
-     * @param zipClasses The set of all classes FQCN found in the JAR files.
-     * @return A map { FQCN not found in the zipClasses => classes using it }
-     */
-    private Map<String, Set<String>> findMissingClasses(
-            Map<String, Set<String>> deps,
-            Set<String> zipClasses) {
-        Map<String, Set<String>> missing = new TreeMap<>();
-
-        for (Entry<String, Set<String>> entry : deps.entrySet()) {
-            String name = entry.getKey();
-
-            for (String dep : entry.getValue()) {
-                if (!zipClasses.contains(dep)) {
-                    // This dependency doesn't exist in the zip classes.
-                    Set<String> set = missing.get(dep);
-                    if (set == null) {
-                        set = new TreeSet<>();
-                        missing.put(dep, set);
-                    }
-                    set.add(name);
-                }
-            }
-
-        }
-
-        return missing;
-    }
-
-
-    // ----------------------------------
-
-    /**
-     * Instantiates a new DependencyVisitor. Useful for unit tests.
-     */
-    @VisibleForTesting(visibility=Visibility.PRIVATE)
-    DependencyVisitor getVisitor() {
-        return new DependencyVisitor();
-    }
-
-    /**
-     * Visitor to collect all the type dependencies from a class.
-     */
-    public class DependencyVisitor extends ClassVisitor {
-
-        private Set<String> mCurrentDepSet;
-
-        /**
-         * Creates a new visitor that will find all the dependencies for the visited class.
-         */
-        public DependencyVisitor() {
-            super(Main.ASM_VERSION);
-        }
-
-        /**
-         * Sets the {@link Set} where to record direct dependencies for this class.
-         * This will change before each {@link ClassReader#accept(ClassVisitor, int)} call.
-         */
-        public void setDependencySet(Set<String> set) {
-            mCurrentDepSet = set;
-        }
-
-        /**
-         * Considers the given class name as a dependency.
-         */
-        public void considerName(String className) {
-            if (className == null) {
-                return;
-            }
-
-            className = internalToBinaryClassName(className);
-
-            try {
-                // exclude classes that are part of the default JRE (the one executing this program)
-                // or in java package (we won't be able to load them anyway).
-                if (className.startsWith("java.") ||
-                        getClass().getClassLoader().loadClass(className) != null) {
-                    return;
-                }
-            } catch (ClassNotFoundException e) {
-                // ignore
-            }
-
-            // Add it to the dependency set for the currently visited class, as needed.
-            assert mCurrentDepSet != null;
-            mCurrentDepSet.add(className);
-        }
-
-        /**
-         * Considers this array of names using considerName().
-         */
-        public void considerNames(String[] classNames) {
-            if (classNames != null) {
-                for (String className : classNames) {
-                    considerName(className);
-                }
-            }
-        }
-
-        /**
-         * Considers this signature or type signature by invoking the {@link SignatureVisitor}
-         * on it.
-         */
-        public void considerSignature(String signature) {
-            if (signature != null) {
-                SignatureReader sr = new SignatureReader(signature);
-                // SignatureReader.accept will call accessType so we don't really have
-                // to differentiate where the signature comes from.
-                sr.accept(new MySignatureVisitor());
-            }
-        }
-
-        /**
-         * Considers this {@link Type}. For arrays, the element type is considered.
-         * If the type is an object, it's internal name is considered.
-         */
-        public void considerType(Type t) {
-            if (t != null) {
-                if (t.getSort() == Type.ARRAY) {
-                    t = t.getElementType();
-                }
-                if (t.getSort() == Type.OBJECT) {
-                    considerName(t.getInternalName());
-                }
-            }
-        }
-
-        /**
-         * Considers a descriptor string. The descriptor is converted to a {@link Type}
-         * and then considerType() is invoked.
-         */
-        public boolean considerDesc(String desc) {
-            if (desc != null) {
-                try {
-                    if (desc.length() > 0 && desc.charAt(0) == '(') {
-                        // This is a method descriptor with arguments and a return type.
-                        Type t = Type.getReturnType(desc);
-                        considerType(t);
-
-                        for (Type arg : Type.getArgumentTypes(desc)) {
-                            considerType(arg);
-                        }
-
-                    } else {
-                        Type t = Type.getType(desc);
-                        considerType(t);
-                    }
-                    return true;
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    // ignore, not a valid type.
-                }
-            }
-            return false;
-        }
-
-
-        // ---------------------------------------------------
-        // --- ClassVisitor, FieldVisitor
-        // ---------------------------------------------------
-
-        // Visits a class header
-        @Override
-        public void visit(int version, int access, String name,
-                String signature, String superName, String[] interfaces) {
-            // signature is the signature of this class. May be null if the class is not a generic
-            // one, and does not extend or implement generic classes or interfaces.
-
-            if (signature != null) {
-                considerSignature(signature);
-            }
-
-            // superName is the internal of name of the super class (see getInternalName).
-            // For interfaces, the super class is Object. May be null but only for the Object class.
-            considerName(superName);
-
-            // interfaces is the internal names of the class's interfaces (see getInternalName).
-            // May be null.
-            considerNames(interfaces);
-        }
-
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            // desc is the class descriptor of the annotation class.
-            considerDesc(desc);
-            return new MyAnnotationVisitor();
-        }
-
-        @Override
-        public void visitAttribute(Attribute attr) {
-            // pass
-        }
-
-        // Visits the end of a class
-        @Override
-        public void visitEnd() {
-            // pass
-        }
-
-        private class MyFieldVisitor extends FieldVisitor {
-
-            public MyFieldVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitAttribute(Attribute attr) {
-                // pass
-            }
-
-            // Visits the end of a class
-            @Override
-            public void visitEnd() {
-                // pass
-            }
-        }
-
-        @Override
-        public FieldVisitor visitField(int access, String name, String desc,
-                String signature, Object value) {
-            // desc is the field's descriptor (see Type).
-            considerDesc(desc);
-
-            // signature is the field's signature. May be null if the field's type does not use
-            // generic types.
-            considerSignature(signature);
-
-            return new MyFieldVisitor();
-        }
-
-        @Override
-        public void visitInnerClass(String name, String outerName, String innerName, int access) {
-            // name is the internal name of an inner class (see getInternalName).
-            // Note: outerName/innerName seems to be null when we're reading the
-            // _Original_ClassName classes generated by layoutlib_create.
-            if (outerName != null) {
-                considerName(name);
-            }
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc,
-                String signature, String[] exceptions) {
-            // desc is the method's descriptor (see Type).
-            considerDesc(desc);
-            // signature is the method's signature. May be null if the method parameters, return
-            // type and exceptions do not use generic types.
-            considerSignature(signature);
-
-            return new MyMethodVisitor();
-        }
-
-        @Override
-        public void visitOuterClass(String owner, String name, String desc) {
-            // pass
-        }
-
-        @Override
-        public void visitSource(String source, String debug) {
-            // pass
-        }
-
-
-        // ---------------------------------------------------
-        // --- MethodVisitor
-        // ---------------------------------------------------
-
-        private class MyMethodVisitor extends MethodVisitor {
-
-            public MyMethodVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-
-            @Override
-            public AnnotationVisitor visitAnnotationDefault() {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitCode() {
-                // pass
-            }
-
-            // field instruction
-            @Override
-            public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-                // owner is the class that declares the field.
-                considerName(owner);
-                // desc is the field's descriptor (see Type).
-                considerDesc(desc);
-            }
-
-            @Override
-            public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
-                // pass
-            }
-
-            @Override
-            public void visitIincInsn(int var, int increment) {
-                // pass -- an IINC instruction
-            }
-
-            @Override
-            public void visitInsn(int opcode) {
-                // pass -- a zero operand instruction
-            }
-
-            @Override
-            public void visitIntInsn(int opcode, int operand) {
-                // pass -- a single int operand instruction
-            }
-
-            @Override
-            public void visitJumpInsn(int opcode, Label label) {
-                // pass -- a jump instruction
-            }
-
-            @Override
-            public void visitLabel(Label label) {
-                // pass -- a label target
-            }
-
-            // instruction to load a constant from the stack
-            @Override
-            public void visitLdcInsn(Object cst) {
-                if (cst instanceof Type) {
-                    considerType((Type) cst);
-                }
-            }
-
-            @Override
-            public void visitLineNumber(int line, Label start) {
-                // pass
-            }
-
-            @Override
-            public void visitLocalVariable(String name, String desc,
-                    String signature, Label start, Label end, int index) {
-                // desc is the type descriptor of this local variable.
-                considerDesc(desc);
-                // signature is the type signature of this local variable. May be null if the local
-                // variable type does not use generic types.
-                considerSignature(signature);
-            }
-
-            @Override
-            public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-                // pass -- a lookup switch instruction
-            }
-
-            @Override
-            public void visitMaxs(int maxStack, int maxLocals) {
-                // pass
-            }
-
-            // instruction that invokes a method
-            @Override
-            public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                    boolean itf) {
-
-                // owner is the internal name of the method's owner class
-                if (!considerDesc(owner) && owner.indexOf('/') != -1) {
-                    considerName(owner);
-                }
-                // desc is the method's descriptor (see Type).
-                considerDesc(desc);
-            }
-
-            // instruction multianewarray, whatever that is
-            @Override
-            public void visitMultiANewArrayInsn(String desc, int dims) {
-
-                // desc an array type descriptor.
-                considerDesc(desc);
-            }
-
-            @Override
-            public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-                    boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
-                // pass -- table switch instruction
-
-            }
-
-            @Override
-            public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-                // type is the internal name of the type of exceptions handled by the handler,
-                // or null to catch any exceptions (for "finally" blocks).
-                considerName(type);
-            }
-
-            // type instruction
-            @Override
-            public void visitTypeInsn(int opcode, String type) {
-                // type is the operand of the instruction to be visited. This operand must be the
-                // internal name of an object or array class.
-                considerName(type);
-            }
-
-            @Override
-            public void visitVarInsn(int opcode, int var) {
-                // pass -- local variable instruction
-            }
-        }
-
-        private class MySignatureVisitor extends SignatureVisitor {
-
-            public MySignatureVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            // ---------------------------------------------------
-            // --- SignatureVisitor
-            // ---------------------------------------------------
-
-            private String mCurrentSignatureClass = null;
-
-            // Starts the visit of a signature corresponding to a class or interface type
-            @Override
-            public void visitClassType(String name) {
-                mCurrentSignatureClass = name;
-                considerName(name);
-            }
-
-            // Visits an inner class
-            @Override
-            public void visitInnerClassType(String name) {
-                if (mCurrentSignatureClass != null) {
-                    mCurrentSignatureClass += "$" + name;
-                    considerName(mCurrentSignatureClass);
-                }
-            }
-
-            @Override
-            public SignatureVisitor visitArrayType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitBaseType(char descriptor) {
-                // pass -- a primitive type, ignored
-            }
-
-            @Override
-            public SignatureVisitor visitClassBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitExceptionType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitFormalTypeParameter(String name) {
-                // pass
-            }
-
-            @Override
-            public SignatureVisitor visitInterface() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitInterfaceBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitParameterType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitReturnType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitSuperclass() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitTypeArgument(char wildcard) {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitTypeVariable(String name) {
-                // pass
-            }
-
-            @Override
-            public void visitTypeArgument() {
-                // pass
-            }
-        }
-
-
-        // ---------------------------------------------------
-        // --- AnnotationVisitor
-        // ---------------------------------------------------
-
-        private class MyAnnotationVisitor extends AnnotationVisitor {
-
-            public MyAnnotationVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            // Visits a primitive value of an annotation
-            @Override
-            public void visit(String name, Object value) {
-                // value is the actual value, whose type must be Byte, Boolean, Character, Short,
-                // Integer, Long, Float, Double, String or Type
-                if (value instanceof Type) {
-                    considerType((Type) value);
-                }
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String name, String desc) {
-                // desc is the class descriptor of the nested annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public AnnotationVisitor visitArray(String name) {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitEnum(String name, String desc, String value) {
-                // desc is the class descriptor of the enumeration class.
-                considerDesc(desc);
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/FieldInjectorAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/FieldInjectorAdapter.java
deleted file mode 100644
index 4608a84..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/FieldInjectorAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Injects fields in a class.
- * <p>
- * TODO: Generify
- */
-public class FieldInjectorAdapter extends ClassVisitor {
-    public FieldInjectorAdapter(ClassVisitor cv) {
-        super(Opcodes.ASM4, cv);
-    }
-
-    @Override
-    public void visitEnd() {
-        super.visitField(Opcodes.ACC_PUBLIC, "mLayoutlibCallback",
-                "Lcom/android/ide/common/rendering/api/LayoutlibCallback;", null, null);
-        super.visitField(Opcodes.ACC_PUBLIC, "mContext",
-                "Lcom/android/layoutlib/bridge/android/BridgeContext;", null, null);
-        super.visitEnd();
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
deleted file mode 100644
index eca1c07..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Interface describing the work to be done by {@link AsmGenerator}.
- */
-public interface ICreateInfo {
-
-    /**
-     * Returns the list of class from layoutlib_create to inject in layoutlib.
-     * The list can be empty but must not be null.
-     */
-    Class<?>[] getInjectedClasses();
-
-    /**
-     * Returns the list of methods to rewrite as delegates.
-     * The list can be empty but must not be null.
-     */
-    String[] getDelegateMethods();
-
-    /**
-     * Returns the list of classes on which to delegate all native methods.
-     * The list can be empty but must not be null.
-     */
-    String[] getDelegateClassNatives();
-
-    /**
-     * Returns the list of classes to rename, must be an even list: the binary FQCN
-     * of class to replace followed by the new FQCN.
-     * The list can be empty but must not be null.
-     */
-    String[] getRenamedClasses();
-
-    /**
-     * List of classes to refactor. This is similar to combining {@link #getRenamedClasses()} and
-     * {@link #getJavaPkgClasses()}.
-     * Classes included here will be renamed and then all their references in any other classes
-     * will be also modified.
-     * FQCN of class to refactor followed by its new FQCN.
-     */
-    String[] getRefactoredClasses();
-
-    /**
-     * Returns the list of classes for which the methods returning them should be deleted.
-     * The array contains a list of null terminated section starting with the name of the class
-     * to rename in which the methods are deleted, followed by a list of return types identifying
-     * the methods to delete.
-     * The list can be empty but must not be null.
-     */
-    String[] getDeleteReturns();
-
-    /**
-     * Returns the list of classes to refactor, must be an even list: the
-     * binary FQCN of class to replace followed by the new FQCN. All references
-     * to the old class should be updated to the new class.
-     * The list can be empty but must not be null.
-     */
-    String[] getJavaPkgClasses();
-
-    Set<String> getExcludedClasses();
-
-    /**
-     * Returns a list of fields which should be promoted to public visibility. The array values
-     * are in the form of the binary FQCN of the class containing the field and the field name
-     * separated by a '#'.
-     */
-    String[] getPromotedFields();
-
-    /**
-     * Returns a list of classes to be promoted to public visibility.
-     */
-    String[] getPromotedClasses();
-
-    /**
-     * Returns a map from binary FQCN className to {@link InjectMethodRunnable} which will be
-     * called to inject methods into a class.
-     * Can be empty but must not be null.
-     */
-    Map<String, InjectMethodRunnable> getInjectedMethodsMap();
-
-    abstract class InjectMethodRunnable {
-        /**
-         * @param cv Must be {@link ClassVisitor}. However, the param type is object so that when
-         * loading the class, ClassVisitor is not loaded. This is because when injecting
-         * CreateInfo in LayoutLib (see {@link #getInjectedClasses()}, we don't want to inject
-         * asm classes also, but still keep CreateInfo loadable.
-         */
-        public abstract void generateMethods(Object cv);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java
deleted file mode 100644
index 1941ab4..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java
+++ /dev/null
@@ -1,54 +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.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.create.ICreateInfo.InjectMethodRunnable;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-
-import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
-import static org.objectweb.asm.Opcodes.ALOAD;
-import static org.objectweb.asm.Opcodes.ARETURN;
-import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
-
-public class InjectMethodRunnables {
-    public static final ICreateInfo.InjectMethodRunnable CONTEXT_GET_FRAMEWORK_CLASS_LOADER
-            = new InjectMethodRunnable() {
-        @Override
-        public void generateMethods(Object classVisitor) {
-            assert classVisitor instanceof ClassVisitor;
-            ClassVisitor cv = (ClassVisitor) classVisitor;
-            // generated by compiling the class:
-            // class foo { public ClassLoader getFrameworkClassLoader() { return getClass().getClassLoader(); } }
-            // and then running ASMifier on it:
-            // java -classpath asm-debug-all-5.0.2.jar:. org.objectweb.asm.util.ASMifier foo
-            MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "getFrameworkClassLoader",
-                    "()Ljava/lang/ClassLoader;", null, null);
-            mv.visitCode();
-            mv.visitVarInsn(ALOAD, 0);
-            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass",
-                    "()Ljava/lang/Class;", false);
-            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getClassLoader",
-                    "()Ljava/lang/ClassLoader;", false);
-            mv.visitInsn(ARETURN);
-            mv.visitMaxs(1, 1);
-            mv.visitEnd();
-            // generated code ends.
-        }
-    };
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodsAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodsAdapter.java
deleted file mode 100644
index c834808..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodsAdapter.java
+++ /dev/null
@@ -1,40 +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.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.create.ICreateInfo.InjectMethodRunnable;
-
-import org.objectweb.asm.ClassVisitor;
-
-/**
- * Injects methods into some classes.
- */
-public class InjectMethodsAdapter extends ClassVisitor {
-
-    private final ICreateInfo.InjectMethodRunnable mRunnable;
-
-    public InjectMethodsAdapter(ClassVisitor cv, InjectMethodRunnable runnable) {
-        super(Main.ASM_VERSION, cv);
-        mRunnable = runnable;
-    }
-
-    @Override
-    public void visitEnd() {
-        mRunnable.generateMethods(this);
-        super.visitEnd();
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
deleted file mode 100644
index c3ba591..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-public class Log {
-
-    private boolean mVerbose = false;
-
-    public void setVerbose(boolean verbose) {
-        mVerbose = verbose;
-    }
-
-    public void debug(String format, Object... args) {
-        if (mVerbose) {
-            info(format, args);
-        }
-    }
-
-    /** Similar to debug() but doesn't do a \n automatically. */
-    public void debugNoln(String format, Object... args) {
-        if (mVerbose) {
-            String s = String.format(format, args);
-            System.out.print(s);
-        }
-    }
-
-    public void info(String format, Object... args) {
-        String s = String.format(format, args);
-        outPrintln(s);
-    }
-
-    public void error(String format, Object... args) {
-        String s = String.format(format, args);
-        errPrintln(s);
-    }
-
-    public void exception(Throwable t, String format, Object... args) {
-        StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter(sw);
-        t.printStackTrace(pw);
-        pw.flush();
-        error(format + "\n" + sw.toString(), args);
-    }
-
-    /** for unit testing */
-    protected void errPrintln(String msg) {
-        System.err.println(msg);
-    }
-
-    /** for unit testing */
-    protected void outPrintln(String msg) {
-        System.out.println(msg);
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java
deleted file mode 100644
index dc4b4a7..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-public class LogAbortException extends Exception {
-
-    private final String mFormat;
-    private final Object[] mArgs;
-
-    public LogAbortException(String format, Object... args) {
-        mFormat = format;
-        mArgs = args;
-    }
-    
-    public void error(Log log) {
-        log.error(mFormat, mArgs);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
deleted file mode 100644
index 4b6cf43..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.Opcodes;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-
-/**
- * Entry point for the layoutlib_create tool.
- * <p/>
- * The tool does not currently rely on any external configuration file.
- * Instead the configuration is mostly done via the {@link CreateInfo} class.
- * <p/>
- * For a complete description of the tool and its implementation, please refer to
- * the "README.txt" file at the root of this project.
- * <p/>
- * For a quick test, invoke this as follows:
- * <pre>
- * $ make layoutlib
- * </pre>
- * which does:
- * <pre>
- * $ make layoutlib_create &lt;bunch of framework jars&gt;
- * $ java -jar out/host/linux-x86/framework/layoutlib_create.jar \
- *        out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar \
- *        out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar \
- *        out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
- * </pre>
- */
-public class Main {
-
-    public static class Options {
-        public boolean listAllDeps = false;
-        public boolean listOnlyMissingDeps = false;
-    }
-
-    public static final int ASM_VERSION = Opcodes.ASM5;
-
-    public static final Options sOptions = new Options();
-
-    public static void main(String[] args) {
-
-        Log log = new Log();
-
-        ArrayList<String> osJarPath = new ArrayList<>();
-        String[] osDestJar = { null };
-
-        if (!processArgs(log, args, osJarPath, osDestJar)) {
-            log.error("Usage: layoutlib_create [-v] output.jar input.jar ...");
-            log.error("Usage: layoutlib_create [-v] [--list-deps|--missing-deps] input.jar ...");
-            System.exit(1);
-        }
-
-        if (sOptions.listAllDeps || sOptions.listOnlyMissingDeps) {
-            System.exit(listDeps(osJarPath, log));
-
-        } else {
-            System.exit(createLayoutLib(osDestJar[0], osJarPath, log));
-        }
-
-
-        System.exit(1);
-    }
-
-    private static int createLayoutLib(String osDestJar, ArrayList<String> osJarPath, Log log) {
-        log.info("Output: %1$s", osDestJar);
-        for (String path : osJarPath) {
-            log.info("Input :      %1$s", path);
-        }
-
-        try {
-            CreateInfo info = new CreateInfo();
-            Set<String> excludeClasses = info.getExcludedClasses();
-            AsmGenerator agen = new AsmGenerator(log, osDestJar, info);
-
-            AsmAnalyzer aa = new AsmAnalyzer(log, osJarPath, agen,
-                    new String[] {                          // derived from
-                        "android.view.View",
-                        "android.app.Fragment"
-                    },
-                    new String[] {                          // include classes
-                        "android.*", // for android.R
-                        "android.util.*",
-                        "com.android.internal.util.*",
-                        "android.view.*",
-                        "android.widget.*",
-                        "com.android.internal.widget.*",
-                        "android.text.**",
-                        "android.graphics.*",
-                        "android.graphics.drawable.**",
-                        "android.content.*",
-                        "android.content.res.*",
-                        "android.preference.*",
-                        "org.apache.harmony.xml.*",
-                        "com.android.internal.R**",
-                        "android.pim.*", // for datepicker
-                        "android.os.*",  // for android.os.Handler
-                        "android.database.ContentObserver", // for Digital clock
-                        "com.android.i18n.phonenumbers.*",  // for TextView with autolink attribute
-                        "android.app.DatePickerDialog",     // b.android.com/28318
-                        "android.app.TimePickerDialog",     // b.android.com/61515
-                        "com.android.internal.view.menu.ActionMenu",
-                        "android.icu.**",                   // needed by LayoutLib
-                        "android.annotation.NonNull",       // annotations
-                        "android.annotation.Nullable",      // annotations
-                        "com.android.internal.transition.EpicenterTranslateClipReveal",
-                        "com.android.internal.graphics.drawable.AnimationScaleListDrawable",
-                    },
-                    excludeClasses,
-                    new String[] {
-                        "com/android/i18n/phonenumbers/data/*",
-                        "android/icu/impl/data/**"
-                    });
-            aa.analyze();
-            agen.generate();
-
-            // Throw an error if any class failed to get renamed by the generator
-            //
-            // IMPORTANT: if you're building the platform and you get this error message,
-            // it means the renameClasses[] array in AsmGenerator needs to be updated: some
-            // class should have been renamed but it was not found in the input JAR files.
-            Set<String> notRenamed = agen.getClassesNotRenamed();
-            if (notRenamed.size() > 0) {
-                // (80-column guide below for error formatting)
-                // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
-                log.error(
-                  "ERROR when running layoutlib_create: the following classes are referenced\n" +
-                  "by tools/layoutlib/create but were not actually found in the input JAR files.\n" +
-                  "This may be due to some platform classes having been renamed.");
-                for (String fqcn : notRenamed) {
-                    log.error("- Class not found: %s", fqcn.replace('/', '.'));
-                }
-                for (String path : osJarPath) {
-                    log.info("- Input JAR : %1$s", path);
-                }
-                return 1;
-            }
-
-            return 0;
-        } catch (IOException e) {
-            log.exception(e, "Failed to load jar");
-        } catch (LogAbortException e) {
-            e.error(log);
-        }
-
-        return 1;
-    }
-
-    private static int listDeps(ArrayList<String> osJarPath, Log log) {
-        DependencyFinder df = new DependencyFinder(log);
-        try {
-            List<Map<String, Set<String>>> result = df.findDeps(osJarPath);
-            if (sOptions.listAllDeps) {
-                df.printAllDeps(result);
-            } else if (sOptions.listOnlyMissingDeps) {
-                df.printMissingDeps(result);
-            }
-        } catch (IOException e) {
-            log.exception(e, "Failed to load jar");
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns true if args where properly parsed.
-     * Returns false if program should exit with command-line usage.
-     * <p/>
-     * Note: the String[0] is an output parameter wrapped in an array, since there is no
-     * "out" parameter support.
-     */
-    private static boolean processArgs(Log log, String[] args,
-            ArrayList<String> osJarPath, String[] osDestJar) {
-        boolean needs_dest = true;
-        for (String s : args) {
-            if (s.equals("-v")) {
-                log.setVerbose(true);
-            } else if (s.equals("--list-deps")) {
-                sOptions.listAllDeps = true;
-                needs_dest = false;
-            } else if (s.equals("--missing-deps")) {
-                sOptions.listOnlyMissingDeps = true;
-                needs_dest = false;
-            } else if (!s.startsWith("-")) {
-                if (needs_dest && osDestJar[0] == null) {
-                    osDestJar[0] = s;
-                } else {
-                    osJarPath.add(s);
-                }
-            } else {
-                log.error("Unknown argument: %s", s);
-                return false;
-            }
-        }
-
-        if (osJarPath.isEmpty()) {
-            log.error("Missing parameter: path to input jar");
-            return false;
-        }
-        if (needs_dest && osDestJar[0] == null) {
-            log.error("Missing parameter: path to output jar");
-            return false;
-        }
-
-        return true;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java
deleted file mode 100644
index 7d1e4cf..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-
-/**
- * An adapter to make it easier to use {@link MethodListener}.
- * <p/>
- * The adapter calls the void {@link #onInvokeV(String, boolean, Object)} listener
- * for all types (I, L, F, D and A), returning 0 or null as appropriate.
- */
-public class MethodAdapter implements MethodListener {
-    /**
-     * A stub method is being invoked.
-     * <p/>
-     * Known limitation: caller arguments are not available.
-     *
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
-     * @param isNative True if the method was a native method.
-     * @param caller The calling object. Null for static methods, "this" for instance methods.
-     */
-    @Override
-    public void onInvokeV(String signature, boolean isNative, Object caller) {
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an integer or similar.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an integer, or a boolean, or a short or a byte.
-     */
-    @Override
-    public int onInvokeI(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a long.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a long.
-     */
-    @Override
-    public long onInvokeL(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a float.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a float.
-     */
-    @Override
-    public float onInvokeF(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a double.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a double.
-     */
-    @Override
-    public double onInvokeD(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an object.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an object.
-     */
-    @Override
-    public Object onInvokeA(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return null;
-    }
-}
-
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java
deleted file mode 100644
index faba4d7..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-
-/**
- * Interface to allow a method invocation to be listened upon.
- * <p/>
- * This is used by {@link OverrideMethod} to register a listener for methods that
- * have been stubbed by the {@link AsmGenerator}. At runtime the stub will call either a
- * default global listener or a specific listener based on the method signature.
- */
-public interface MethodListener {
-    /**
-     * A stub method is being invoked.
-     * <p/>
-     * Known limitation: caller arguments are not available.
-     *  
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
-     * @param isNative True if the method was a native method.
-     * @param caller The calling object. Null for static methods, "this" for instance methods.
-     */
-    void onInvokeV(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an integer or similar.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an integer, or a boolean, or a short or a byte.
-     */
-    int onInvokeI(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a long.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a long.
-     */
-    long onInvokeL(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a float.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a float.
-     */
-    float onInvokeF(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a double.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a double.
-     */
-    double onInvokeD(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an object.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an object.
-     */
-    Object onInvokeA(String signature, boolean isNative, Object caller);
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
deleted file mode 100644
index 7ccafc3..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import java.util.HashMap;
-
-/**
- * Allows stub methods from LayoutLib to be overriden at runtime.
- * <p/>
- * Implementation note: all types required by this class(inner/outer classes & interfaces)
- * must be referenced by the injectClass argument to {@link AsmGenerator} in Main.java;
- * Otherwise they won't be accessible in layoutlib.jar at runtime.
- */
-public final class OverrideMethod {
-
-    /** Map of method overridden. */
-    private static HashMap<String, MethodListener> sMethods = new HashMap<>();
-    /** Default listener for all method not listed in sMethods. Nothing if null. */
-    private static MethodListener sDefaultListener = null;
-    
-    /**
-     * Sets the default listener for all methods not specifically handled.
-     * Null means to do nothing.
-     */
-    @SuppressWarnings("UnusedDeclaration") // Used by Bridge by reflection for debug purposes.
-    public static void setDefaultListener(MethodListener listener) {
-        sDefaultListener = listener;
-    }
-
-    /**
-     * Defines or reset a listener for the given method signature.
-     * 
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V"
-     * @param listener The new listener. Removes it if null.
-     */
-    public static void setMethodListener(String signature, MethodListener listener) {
-        if (listener == null) {
-            sMethods.remove(signature);
-        } else {
-            sMethods.put(signature, listener);
-        }
-    }
-    
-    /**
-     * Invokes the specific listener for the given signature or the default one if defined.
-     * <p/>
-     * This version invokes the method listener for the void return type. 
-     * <p/>
-     * Note: this is not intended to be used by the LayoutLib Bridge. It is intended to be called
-     * by the stubbed methods generated by the LayoutLib_create tool.
-     * 
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
-     * @param isNative True if the method was a native method.
-     * @param caller The calling object. Null for static methods, "this" for instance methods.
-     */
-    public static void invokeV(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            i.onInvokeV(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            sDefaultListener.onInvokeV(signature, isNative, caller);
-        }
-    }
-    
-    /**
-     * Invokes the specific listener for the int return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static int invokeI(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeI(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeI(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the long return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static long invokeL(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeL(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeL(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the float return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static float invokeF(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeF(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeF(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the double return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static double invokeD(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeD(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeD(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the object return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static Object invokeA(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeA(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeA(signature, isNative, caller);
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteClassClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteClassClassAdapter.java
deleted file mode 100644
index 99e3089..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteClassClassAdapter.java
+++ /dev/null
@@ -1,64 +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.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
-import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
-import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
-
-/**
- * Promotes given classes to public visibility.
- */
-public class PromoteClassClassAdapter extends ClassVisitor {
-
-    private final Set<String> mClassNames;
-    private static final int CLEAR_PRIVATE_MASK = ~(ACC_PRIVATE | ACC_PROTECTED);
-
-    public PromoteClassClassAdapter(ClassVisitor cv, Set<String> classNames) {
-        super(Main.ASM_VERSION, cv);
-        mClassNames =
-                classNames.stream().map(name -> name.replace(".", "/")).collect(Collectors.toSet());
-    }
-
-    @Override
-    public void visit(int version, int access, String name, String signature, String superName,
-            String[] interfaces) {
-        if (mClassNames.contains(name)) {
-            if ((access & ACC_PUBLIC) == 0) {
-                access = (access & CLEAR_PRIVATE_MASK) | ACC_PUBLIC;
-            }
-        }
-
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-
-    @Override
-    public void visitInnerClass(String name, String outerName, String innerName, int access) {
-        if (mClassNames.contains(name)) {
-            if ((access & ACC_PUBLIC) == 0) {
-                access = (access & CLEAR_PRIVATE_MASK) | ACC_PUBLIC;
-            }
-        }
-
-        super.visitInnerClass(name, outerName, innerName, access);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteFieldClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteFieldClassAdapter.java
deleted file mode 100644
index ba77860..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteFieldClassAdapter.java
+++ /dev/null
@@ -1,51 +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.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-
-import java.util.Set;
-
-import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
-import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
-import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
-
-/**
- * Promotes given fields to public visibility.
- */
-public class PromoteFieldClassAdapter extends ClassVisitor {
-
-    private final Set<String> mFieldNames;
-    private static final int CLEAR_PRIVATE_MASK = ~(ACC_PRIVATE | ACC_PROTECTED);
-
-    public PromoteFieldClassAdapter(ClassVisitor cv, Set<String> fieldNames) {
-        super(Main.ASM_VERSION, cv);
-        mFieldNames = fieldNames;
-    }
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc, String signature,
-            Object value) {
-        if (mFieldNames.contains(name)) {
-            if ((access & ACC_PUBLIC) == 0) {
-                access = (access & CLEAR_PRIVATE_MASK) | ACC_PUBLIC;
-            }
-        }
-        return super.visitField(access, name, desc, signature, value);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java
deleted file mode 100644
index 024e32f..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java
+++ /dev/null
@@ -1,104 +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.tools.layoutlib.create;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-
-public class RefactorClassAdapter extends AbstractClassAdapter {
-
-    private final HashMap<String, String> mRefactorClasses;
-
-    RefactorClassAdapter(ClassVisitor cv, HashMap<String, String> refactorClasses) {
-        super(cv);
-        mRefactorClasses = refactorClasses;
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc, String signature,
-            String[] exceptions) {
-        MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
-
-        return new RefactorStackMapAdapter(mw);
-    }
-
-    @Override
-    protected String renameInternalType(String oldClassName) {
-        if (oldClassName != null) {
-            String newName = mRefactorClasses.get(oldClassName);
-            if (newName != null) {
-                return newName;
-            }
-            int pos = oldClassName.indexOf('$');
-            if (pos > 0) {
-                newName = mRefactorClasses.get(oldClassName.substring(0, pos));
-                if (newName != null) {
-                    return newName + oldClassName.substring(pos);
-                }
-            }
-        }
-        return oldClassName;
-    }
-
-    /**
-     * A method visitor that renames all references from an old class name to a new class name in
-     * the stackmap of the method.
-     */
-    private class RefactorStackMapAdapter extends MethodVisitor {
-
-        private RefactorStackMapAdapter(MethodVisitor mv) {
-            super(Main.ASM_VERSION, mv);
-        }
-
-
-        private Object[] renameFrame(Object[] elements) {
-            if (elements == null) {
-                return null;
-            }
-
-            // The input array cannot be modified. We only copy the source array on write
-            boolean copied = false;
-            for (int i = 0; i < elements.length; i++) {
-                if (!(elements[i] instanceof String)) {
-                    continue;
-                }
-
-                if (!copied) {
-                    elements = Arrays.copyOf(elements, elements.length);
-                    copied = true;
-                }
-
-                String type = (String)elements[i];
-                if (type.indexOf(';') > 0) {
-                    elements[i] = renameTypeDesc(type);
-                } else {
-                    elements[i] = renameInternalType(type);
-                }
-            }
-
-            return elements;
-        }
-
-        @Override
-        public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
-            super.visitFrame(type, nLocal, renameFrame(local), nStack, renameFrame(stack));
-        }
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
deleted file mode 100644
index 40bd126..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-
-/**
- * This class visitor renames a class from a given old name to a given new name.
- * The class visitor will also rename all inner classes and references in the methods.
- * <p/>
- *
- * For inner classes, this handles only the case where the outer class name changes.
- * The inner class name should remain the same.
- */
-public class RenameClassAdapter extends AbstractClassAdapter {
-
-
-    private final String mOldName;
-    private final String mNewName;
-    private String mOldBase;
-    private String mNewBase;
-
-    /**
-     * Creates a class visitor that renames a class from a given old name to a given new name.
-     * The class visitor will also rename all inner classes and references in the methods.
-     * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass).
-     */
-    public RenameClassAdapter(ClassVisitor cv, String oldName, String newName) {
-        super(cv);
-        mOldBase = mOldName = oldName;
-        mNewBase = mNewName = newName;
-
-        int pos = mOldName.indexOf('$');
-        if (pos > 0) {
-            mOldBase = mOldName.substring(0, pos);
-        }
-        pos = mNewName.indexOf('$');
-        if (pos > 0) {
-            mNewBase = mNewName.substring(0, pos);
-        }
-
-        assert (mOldBase == null && mNewBase == null) || (mOldBase != null && mNewBase != null);
-    }
-
-    /**
-     * Renames an internal type name, e.g. "com.package.MyClass".
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     * <p/>
-     * The internal type of some of the MethodVisitor turns out to be a type
-       descriptor sometimes so descriptors are renamed too.
-     */
-    @Override
-    protected String renameInternalType(String type) {
-        if (type == null) {
-            return null;
-        }
-
-        if (type.equals(mOldName)) {
-            return mNewName;
-        }
-
-        if (!mOldBase.equals(mOldName) && type.equals(mOldBase)) {
-            return mNewBase;
-        }
-
-        int pos = type.indexOf('$');
-        if (pos == mOldBase.length() && type.startsWith(mOldBase)) {
-            return mNewBase + type.substring(pos);
-        }
-        return type;
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java
deleted file mode 100644
index bf94415..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java
+++ /dev/null
@@ -1,292 +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.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.java.LinkedHashMap_Delegate;
-import com.android.tools.layoutlib.java.System_Delegate;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Replaces calls to certain methods that do not exist in the Desktop VM. Useful for methods in the
- * "java" package.
- */
-public class ReplaceMethodCallsAdapter extends ClassVisitor {
-
-    /**
-     * Descriptors for specialized versions {@link System#arraycopy} that are not present on the
-     * Desktop VM.
-     */
-    private static Set<String> ARRAYCOPY_DESCRIPTORS = new HashSet<>(Arrays.asList(
-            "([CI[CII)V", "([BI[BII)V", "([SI[SII)V", "([II[III)V",
-            "([JI[JII)V", "([FI[FII)V", "([DI[DII)V", "([ZI[ZII)V"));
-
-    private static final List<MethodReplacer> METHOD_REPLACERS = new ArrayList<>(5);
-
-    private static final String ANDROID_LOCALE_CLASS =
-            "com/android/layoutlib/bridge/android/AndroidLocale";
-
-    private static final String JAVA_LOCALE_CLASS = Type.getInternalName(java.util.Locale.class);
-    private static final Type STRING = Type.getType(String.class);
-
-    private static final String JAVA_LANG_SYSTEM = Type.getInternalName(System.class);
-
-    // Static initialization block to initialize METHOD_REPLACERS.
-    static {
-        // Case 1: java.lang.System.arraycopy()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LANG_SYSTEM.equals(owner) && "arraycopy".equals(name) &&
-                        ARRAYCOPY_DESCRIPTORS.contains(desc);
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.desc = "(Ljava/lang/Object;ILjava/lang/Object;II)V";
-            }
-        });
-
-        // Case 2: java.util.Locale.toLanguageTag() and java.util.Locale.getScript()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-
-            private final String LOCALE_TO_STRING =
-                    Type.getMethodDescriptor(STRING, Type.getType(Locale.class));
-
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LOCALE_CLASS.equals(owner) && "()Ljava/lang/String;".equals(desc) &&
-                        ("toLanguageTag".equals(name) || "getScript".equals(name));
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.opcode = Opcodes.INVOKESTATIC;
-                mi.owner = ANDROID_LOCALE_CLASS;
-                mi.desc = LOCALE_TO_STRING;
-            }
-        });
-
-        // Case 3: java.util.Locale.adjustLanguageCode() or java.util.Locale.forLanguageTag() or
-        // java.util.Locale.getDefault()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-
-            private final String STRING_TO_STRING = Type.getMethodDescriptor(STRING, STRING);
-            private final String STRING_TO_LOCALE = Type.getMethodDescriptor(
-                    Type.getType(Locale.class), STRING);
-            private final String VOID_TO_LOCALE =
-                    Type.getMethodDescriptor(Type.getType(Locale.class));
-
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LOCALE_CLASS.equals(owner) &&
-                        ("adjustLanguageCode".equals(name) && desc.equals(STRING_TO_STRING) ||
-                        "forLanguageTag".equals(name) && desc.equals(STRING_TO_LOCALE) ||
-                        "getDefault".equals(name) && desc.equals(VOID_TO_LOCALE));
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.owner = ANDROID_LOCALE_CLASS;
-            }
-        });
-
-        // Case 4: java.lang.System.log?()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LANG_SYSTEM.equals(owner) && name.length() == 4
-                        && name.startsWith("log");
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                assert mi.desc.equals("(Ljava/lang/String;Ljava/lang/Throwable;)V")
-                        || mi.desc.equals("(Ljava/lang/String;)V");
-                mi.name = "log";
-                mi.owner = Type.getInternalName(System_Delegate.class);
-            }
-        });
-
-        // Case 5: java.lang.System time calls
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LANG_SYSTEM.equals(owner) && name.equals("nanoTime");
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.name = "nanoTime";
-                mi.owner = Type.getInternalName(System_Delegate.class);
-            }
-        });
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LANG_SYSTEM.equals(owner) && name.equals("currentTimeMillis");
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.name = "currentTimeMillis";
-                mi.owner = Type.getInternalName(System_Delegate.class);
-            }
-        });
-
-        // Case 6: java.util.LinkedHashMap.eldest()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-
-            private final String VOID_TO_MAP_ENTRY =
-                    Type.getMethodDescriptor(Type.getType(Map.Entry.class));
-            private final String LINKED_HASH_MAP = Type.getInternalName(LinkedHashMap.class);
-
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return LINKED_HASH_MAP.equals(owner) &&
-                        "eldest".equals(name) &&
-                        VOID_TO_MAP_ENTRY.equals(desc);
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.opcode = Opcodes.INVOKESTATIC;
-                mi.owner = Type.getInternalName(LinkedHashMap_Delegate.class);
-                mi.desc = Type.getMethodDescriptor(
-                        Type.getType(Map.Entry.class), Type.getType(LinkedHashMap.class));
-            }
-        });
-
-        // Case 7: android.content.Context.getClassLoader() in LayoutInflater
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            // When LayoutInflater asks for a class loader, we must return the class loader that
-            // cannot return app's custom views/classes. This is so that in case of any failure
-            // or exception when instantiating the views, the IDE can replace it with a mock view
-            // and have proper error handling. However, if a custom view asks for the class
-            // loader, we must return a class loader that can find app's custom views as well.
-            // Thus, we rewrite the call to get class loader in LayoutInflater to
-            // getFrameworkClassLoader and inject a new method in Context. This leaves the normal
-            // method: Context.getClassLoader() free to be used by the apps.
-            private final String VOID_TO_CLASS_LOADER =
-                    Type.getMethodDescriptor(Type.getType(ClassLoader.class));
-
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return owner.equals("android/content/Context") &&
-                        sourceClass.equals("android/view/LayoutInflater") &&
-                        name.equals("getClassLoader") &&
-                        desc.equals(VOID_TO_CLASS_LOADER);
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.name = "getFrameworkClassLoader";
-            }
-        });
-    }
-
-    /**
-     * If a method some.package.Class.Method(args) is called from some.other.Class,
-     * @param owner some/package/Class
-     * @param name Method
-     * @param desc (args)returnType
-     * @param sourceClass some/other/Class
-     * @return if the method invocation needs to be replaced by some other class.
-     */
-    public static boolean isReplacementNeeded(String owner, String name, String desc,
-            String sourceClass) {
-        for (MethodReplacer replacer : METHOD_REPLACERS) {
-            if (replacer.isNeeded(owner, name, desc, sourceClass)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private final String mOriginalClassName;
-
-    public ReplaceMethodCallsAdapter(ClassVisitor cv, String originalClassName) {
-        super(Main.ASM_VERSION, cv);
-        mOriginalClassName = originalClassName;
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc, String signature,
-            String[] exceptions) {
-        return new MyMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions));
-    }
-
-    private class MyMethodVisitor extends MethodVisitor {
-
-        public MyMethodVisitor(MethodVisitor mv) {
-            super(Main.ASM_VERSION, mv);
-        }
-
-        @Override
-        public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                boolean itf) {
-            for (MethodReplacer replacer : METHOD_REPLACERS) {
-                if (replacer.isNeeded(owner, name, desc, mOriginalClassName)) {
-                    MethodInformation mi = new MethodInformation(opcode, owner, name, desc);
-                    replacer.replace(mi);
-                    opcode = mi.opcode;
-                    owner = mi.owner;
-                    name = mi.name;
-                    desc = mi.desc;
-                    break;
-                }
-            }
-            super.visitMethodInsn(opcode, owner, name, desc, itf);
-        }
-    }
-
-    private static class MethodInformation {
-        public int opcode;
-        public String owner;
-        public String name;
-        public String desc;
-
-        public MethodInformation(int opcode, String owner, String name, String desc) {
-            this.opcode = opcode;
-            this.owner = owner;
-            this.name = name;
-            this.desc = desc;
-        }
-    }
-
-    private interface MethodReplacer {
-        boolean isNeeded(String owner, String name, String desc, String sourceClass);
-
-        /**
-         * Updates the MethodInformation with the new values of the method attributes -
-         * opcode, owner, name and desc.
-         */
-        void replace(MethodInformation mi);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
deleted file mode 100644
index 4ba7237..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-/**
- * This method adapter rewrites a method by discarding the original code and generating
- * a stub depending on the return type. Original annotations are passed along unchanged.
- */
-class StubMethodAdapter extends MethodVisitor {
-
-    private static final String CONSTRUCTOR = "<init>";
-    private static final String CLASS_INIT = "<clinit>";
-
-    /** The parent method writer */
-    private MethodVisitor mParentVisitor;
-    /** The method return type. Can be null. */
-    private Type mReturnType;
-    /** Message to be printed by stub methods. */
-    private String mInvokeSignature;
-    /** Flag to output the first line number. */
-    private boolean mOutputFirstLineNumber = true;
-    /** Flag that is true when implementing a constructor, to accept all original
-     *  code calling the original super constructor. */
-    private boolean mIsInitMethod = false;
-
-    private boolean mMessageGenerated;
-    private final boolean mIsStatic;
-    private final boolean mIsNative;
-
-    public StubMethodAdapter(MethodVisitor mv, String methodName, Type returnType,
-            String invokeSignature, boolean isStatic, boolean isNative) {
-        super(Main.ASM_VERSION);
-        mParentVisitor = mv;
-        mReturnType = returnType;
-        mInvokeSignature = invokeSignature;
-        mIsStatic = isStatic;
-        mIsNative = isNative;
-
-        if (CONSTRUCTOR.equals(methodName) || CLASS_INIT.equals(methodName)) {
-            mIsInitMethod = true;
-        }
-    }
-
-    private void generateInvoke() {
-        /* Generates the code:
-         *  OverrideMethod.invoke("signature", mIsNative ? true : false, null or this);
-         */
-        mParentVisitor.visitLdcInsn(mInvokeSignature);
-        // push true or false
-        mParentVisitor.visitInsn(mIsNative ? Opcodes.ICONST_1 : Opcodes.ICONST_0);
-        // push null or this
-        if (mIsStatic) {
-            mParentVisitor.visitInsn(Opcodes.ACONST_NULL);
-        } else {
-            mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0);
-        }
-
-        int sort = mReturnType != null ? mReturnType.getSort() : Type.VOID;
-        switch(sort) {
-        case Type.VOID:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeV",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)V",
-                    false);
-            mParentVisitor.visitInsn(Opcodes.RETURN);
-            break;
-        case Type.BOOLEAN:
-        case Type.CHAR:
-        case Type.BYTE:
-        case Type.SHORT:
-        case Type.INT:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeI",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)I",
-                    false);
-            switch(sort) {
-            case Type.BOOLEAN:
-                Label l1 = new Label();
-                mParentVisitor.visitJumpInsn(Opcodes.IFEQ, l1);
-                mParentVisitor.visitInsn(Opcodes.ICONST_1);
-                mParentVisitor.visitInsn(Opcodes.IRETURN);
-                mParentVisitor.visitLabel(l1);
-                mParentVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
-                mParentVisitor.visitInsn(Opcodes.ICONST_0);
-                break;
-            case Type.CHAR:
-                mParentVisitor.visitInsn(Opcodes.I2C);
-                break;
-            case Type.BYTE:
-                mParentVisitor.visitInsn(Opcodes.I2B);
-                break;
-            case Type.SHORT:
-                mParentVisitor.visitInsn(Opcodes.I2S);
-                break;
-            }
-            mParentVisitor.visitInsn(Opcodes.IRETURN);
-            break;
-        case Type.LONG:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeL",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)J",
-                    false);
-            mParentVisitor.visitInsn(Opcodes.LRETURN);
-            break;
-        case Type.FLOAT:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeF",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)F",
-                    false);
-            mParentVisitor.visitInsn(Opcodes.FRETURN);
-            break;
-        case Type.DOUBLE:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeD",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)D",
-                    false);
-            mParentVisitor.visitInsn(Opcodes.DRETURN);
-            break;
-        case Type.ARRAY:
-        case Type.OBJECT:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeA",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)Ljava/lang/Object;",
-                    false);
-            mParentVisitor.visitTypeInsn(Opcodes.CHECKCAST, mReturnType.getInternalName());
-            mParentVisitor.visitInsn(Opcodes.ARETURN);
-            break;
-        }
-
-    }
-
-    private void generatePop() {
-        /* Pops the stack, depending on the return type.
-         */
-        switch(mReturnType != null ? mReturnType.getSort() : Type.VOID) {
-        case Type.VOID:
-            break;
-        case Type.BOOLEAN:
-        case Type.CHAR:
-        case Type.BYTE:
-        case Type.SHORT:
-        case Type.INT:
-        case Type.FLOAT:
-        case Type.ARRAY:
-        case Type.OBJECT:
-            mParentVisitor.visitInsn(Opcodes.POP);
-            break;
-        case Type.LONG:
-        case Type.DOUBLE:
-            mParentVisitor.visitInsn(Opcodes.POP2);
-            break;
-        }
-    }
-
-    /* Pass down to visitor writer. In this implementation, either do nothing. */
-    @Override
-    public void visitCode() {
-        mParentVisitor.visitCode();
-    }
-
-    /*
-     * visitMaxs is called just before visitEnd if there was any code to rewrite.
-     * For non-constructor, generate the messaging code and the return statement
-     * if it hasn't been done before.
-     */
-    @Override
-    public void visitMaxs(int maxStack, int maxLocals) {
-        if (!mIsInitMethod && !mMessageGenerated) {
-            generateInvoke();
-            mMessageGenerated = true;
-        }
-        mParentVisitor.visitMaxs(maxStack, maxLocals);
-    }
-
-    /**
-     * End of visiting.
-     * For non-constructor, generate the messaging code and the return statement
-     * if it hasn't been done before.
-     */
-    @Override
-    public void visitEnd() {
-        if (!mIsInitMethod && !mMessageGenerated) {
-            generateInvoke();
-            mMessageGenerated = true;
-            mParentVisitor.visitMaxs(1, 1);
-        }
-        mParentVisitor.visitEnd();
-    }
-
-    /* Writes all annotation from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        return mParentVisitor.visitAnnotation(desc, visible);
-    }
-
-    /* Writes all annotation default values from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotationDefault() {
-        return mParentVisitor.visitAnnotationDefault();
-    }
-
-    @Override
-    public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-            boolean visible) {
-        return mParentVisitor.visitParameterAnnotation(parameter, desc, visible);
-    }
-
-    /* Writes all attributes from the original method. */
-    @Override
-    public void visitAttribute(Attribute attr) {
-        mParentVisitor.visitAttribute(attr);
-    }
-
-    /*
-     * Only writes the first line number present in the original code so that source
-     * viewers can direct to the correct method, even if the content doesn't match.
-     */
-    @Override
-    public void visitLineNumber(int line, Label start) {
-        if (mIsInitMethod || mOutputFirstLineNumber) {
-            mParentVisitor.visitLineNumber(line, start);
-            mOutputFirstLineNumber = false;
-        }
-    }
-
-    /**
-     * For non-constructor, rewrite existing "return" instructions to write the message.
-     */
-    @Override
-    public void visitInsn(int opcode) {
-        if (mIsInitMethod) {
-            switch (opcode) {
-            case Opcodes.RETURN:
-            case Opcodes.ARETURN:
-            case Opcodes.DRETURN:
-            case Opcodes.FRETURN:
-            case Opcodes.IRETURN:
-            case Opcodes.LRETURN:
-                // Pop the last word from the stack since invoke will generate its own return.
-                generatePop();
-                generateInvoke();
-                mMessageGenerated = true;
-                //$FALL-THROUGH$
-            default:
-                mParentVisitor.visitInsn(opcode);
-            }
-        }
-    }
-
-    @Override
-    public void visitLabel(Label label) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLabel(label);
-        }
-    }
-
-    @Override
-    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitTryCatchBlock(start, end, handler, type);
-        }
-    }
-
-    @Override
-    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitMethodInsn(opcode, owner, name, desc, itf);
-        }
-    }
-
-    @Override
-    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitFieldInsn(opcode, owner, name, desc);
-        }
-    }
-
-    @Override
-    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitFrame(type, nLocal, local, nStack, stack);
-        }
-    }
-
-    @Override
-    public void visitIincInsn(int var, int increment) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitIincInsn(var, increment);
-        }
-    }
-
-    @Override
-    public void visitIntInsn(int opcode, int operand) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitIntInsn(opcode, operand);
-        }
-    }
-
-    @Override
-    public void visitJumpInsn(int opcode, Label label) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitJumpInsn(opcode, label);
-        }
-    }
-
-    @Override
-    public void visitLdcInsn(Object cst) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLdcInsn(cst);
-        }
-    }
-
-    @Override
-    public void visitLocalVariable(String name, String desc, String signature,
-            Label start, Label end, int index) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLocalVariable(name, desc, signature, start, end, index);
-        }
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLookupSwitchInsn(dflt, keys, labels);
-        }
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(String desc, int dims) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitMultiANewArrayInsn(desc, dims);
-        }
-    }
-
-    @Override
-    public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitTableSwitchInsn(min, max, dflt, labels);
-        }
-    }
-
-    @Override
-    public void visitTypeInsn(int opcode, String type) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitTypeInsn(opcode, type);
-        }
-    }
-
-    @Override
-    public void visitVarInsn(int opcode, int var) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitVarInsn(opcode, var);
-        }
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
deleted file mode 100644
index a28ae69..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.util.Set;
-
-/**
- * Class adapter that can stub some or all of the methods of the class.
- */
-class TransformClassAdapter extends ClassVisitor {
-
-    /** True if all methods should be stubbed, false if only native ones must be stubbed. */
-    private final boolean mStubAll;
-    /** True if the class is an interface. */
-    private boolean mIsInterface;
-    private final String mClassName;
-    private final Log mLog;
-    private final Set<String> mStubMethods;
-    private Set<String> mDeleteReturns;
-
-    /**
-     * Creates a new class adapter that will stub some or all methods.
-     * @param stubMethods  list of method signatures to always stub out
-     * @param deleteReturns list of types that trigger the deletion of methods returning them.
-     * @param className The name of the class being modified
-     * @param cv The parent class writer visitor
-     * @param stubNativesOnly True if only native methods should be stubbed. False if all
-     *                        methods should be stubbed.
-     */
-    public TransformClassAdapter(Log logger, Set<String> stubMethods,
-            Set<String> deleteReturns, String className, ClassVisitor cv,
-            boolean stubNativesOnly) {
-        super(Main.ASM_VERSION, cv);
-        mLog = logger;
-        mStubMethods = stubMethods;
-        mClassName = className;
-        mStubAll = !stubNativesOnly;
-        mIsInterface = false;
-        mDeleteReturns = deleteReturns;
-    }
-
-    /* Visits the class header. */
-    @Override
-    public void visit(int version, int access, String name,
-            String signature, String superName, String[] interfaces) {
-
-        // This class might be being renamed.
-        name = mClassName;
-
-        // remove final
-        access = access & ~Opcodes.ACC_FINAL;
-        // note: leave abstract classes as such
-        // don't try to implement stub for interfaces
-
-        mIsInterface = ((access & Opcodes.ACC_INTERFACE) != 0);
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-
-    /* Visits the header of an inner class. */
-    @Override
-    public void visitInnerClass(String name, String outerName, String innerName, int access) {
-        // remove final
-        access = access & ~Opcodes.ACC_FINAL;
-        // note: leave abstract classes as such
-        // don't try to implement stub for interfaces
-
-        super.visitInnerClass(name, outerName, innerName, access);
-    }
-
-    /* Visits a method. */
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-
-        if (mDeleteReturns != null) {
-            Type t = Type.getReturnType(desc);
-            if (t.getSort() == Type.OBJECT) {
-                String returnType = t.getInternalName();
-                if (returnType != null) {
-                    if (mDeleteReturns.contains(returnType)) {
-                        return null;
-                    }
-                }
-            }
-        }
-
-        String methodSignature = mClassName.replace('/', '.') + "#" + name;
-
-        // remove final
-        access = access & ~Opcodes.ACC_FINAL;
-
-        // stub this method if they are all to be stubbed or if it is a native method
-        // and don't try to stub interfaces nor abstract non-native methods.
-        if (!mIsInterface &&
-            ((access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) != Opcodes.ACC_ABSTRACT) &&
-            (mStubAll ||
-             (access & Opcodes.ACC_NATIVE) != 0) ||
-             mStubMethods.contains(methodSignature)) {
-
-            boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
-            boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
-
-            // remove abstract, final and native
-            access = access & ~(Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL | Opcodes.ACC_NATIVE);
-
-            String invokeSignature = methodSignature + desc;
-            mLog.debug("  Stub: %s (%s)", invokeSignature, isNative ? "native" : "");
-
-            MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
-            return new StubMethodAdapter(mw, name, returnType(desc), invokeSignature,
-                    isStatic, isNative);
-
-        } else {
-            mLog.debug("  Keep: %s %s", name, desc);
-            return super.visitMethod(access, name, desc, signature, exceptions);
-        }
-    }
-
-    /**
-     * Extracts the return {@link Type} of this descriptor.
-     */
-    Type returnType(String desc) {
-        if (desc != null) {
-            try {
-                return Type.getReturnType(desc);
-            } catch (ArrayIndexOutOfBoundsException e) {
-                // ignore, not a valid type.
-            }
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java
deleted file mode 100644
index 7d6c4ec..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java
+++ /dev/null
@@ -1,32 +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.tools.layoutlib.java;
-
-/**
- * Defines the same interface as the java.lang.AutoCloseable which was added in
- * Java 7. This hack makes it possible to run the Android code which uses Java 7
- * features (API 18 and beyond) to run on Java 6.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/lang/AutoCloseable.java
- */
-public interface AutoCloseable {
-    /**
-     * Closes the object and release any system resources it holds.
-     */
-    void close() throws Exception;
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java
deleted file mode 100644
index f73b06b..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java
+++ /dev/null
@@ -1,133 +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.tools.layoutlib.java;
-
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-
-/**
- * Defines the same class as the java.nio.charset.Charsets which was added in
- * Dalvik VM. This hack, provides a replacement for that class which can't be
- * loaded in the standard JVM since it's in the java package and standard JVM
- * doesn't have it. An implementation of the native methods in the original
- * class has been added.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/nio/charset/Charsets
- */
-public final class Charsets {
-    /**
-     * A cheap and type-safe constant for the ISO-8859-1 Charset.
-     */
-    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
-
-    /**
-     * A cheap and type-safe constant for the US-ASCII Charset.
-     */
-    public static final Charset US_ASCII = Charset.forName("US-ASCII");
-
-    /**
-     * A cheap and type-safe constant for the UTF-8 Charset.
-     */
-    public static final Charset UTF_8 = Charset.forName("UTF-8");
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in US-ASCII. Unrepresentable characters are replaced by (byte) '?'.
-     */
-    public static byte[] toAsciiBytes(char[] chars, int offset, int length) {
-        CharBuffer cb = CharBuffer.allocate(length);
-        cb.put(chars, offset, length);
-        return US_ASCII.encode(cb).array();
-    }
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in ISO-8859-1. Unrepresentable characters are replaced by (byte) '?'.
-     */
-    public static byte[] toIsoLatin1Bytes(char[] chars, int offset, int length) {
-        CharBuffer cb = CharBuffer.allocate(length);
-        cb.put(chars, offset, length);
-        return ISO_8859_1.encode(cb).array();
-    }
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in UTF-8. All characters are representable in UTF-8.
-     */
-    public static byte[] toUtf8Bytes(char[] chars, int offset, int length) {
-        CharBuffer cb = CharBuffer.allocate(length);
-        cb.put(chars, offset, length);
-        return UTF_8.encode(cb).array();
-    }
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in UTF-16BE. All characters are representable in UTF-16BE.
-     */
-    public static byte[] toBigEndianUtf16Bytes(char[] chars, int offset, int length) {
-        byte[] result = new byte[length * 2];
-        int end = offset + length;
-        int resultIndex = 0;
-        for (int i = offset; i < end; ++i) {
-            char ch = chars[i];
-            result[resultIndex++] = (byte) (ch >> 8);
-            result[resultIndex++] = (byte) ch;
-        }
-        return result;
-    }
-
-    /**
-     * Decodes the given US-ASCII bytes into the given char[]. Equivalent to but faster than:
-     *
-     * for (int i = 0; i < count; ++i) {
-     *     char ch = (char) (data[start++] & 0xff);
-     *     value[i] = (ch <= 0x7f) ? ch : REPLACEMENT_CHAR;
-     * }
-     */
-    public static void asciiBytesToChars(byte[] bytes, int offset, int length, char[] chars) {
-        if (bytes == null || chars == null) {
-            return;
-        }
-        final char REPLACEMENT_CHAR = (char)0xffd;
-        int start = offset;
-        for (int i = 0; i < length; ++i) {
-            char ch = (char) (bytes[start++] & 0xff);
-            chars[i] = (ch <= 0x7f) ? ch : REPLACEMENT_CHAR;
-        }
-    }
-
-    /**
-     * Decodes the given ISO-8859-1 bytes into the given char[]. Equivalent to but faster than:
-     *
-     * for (int i = 0; i < count; ++i) {
-     *     value[i] = (char) (data[start++] & 0xff);
-     * }
-     */
-    public static void isoLatin1BytesToChars(byte[] bytes, int offset, int length, char[] chars) {
-        if (bytes == null || chars == null) {
-            return;
-        }
-        int start = offset;
-        for (int i = 0; i < length; ++i) {
-            chars[i] = (char) (bytes[start++] & 0xff);
-        }
-    }
-
-    private Charsets() {
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java
deleted file mode 100644
index e6dd00a..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java
+++ /dev/null
@@ -1,537 +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.tools.layoutlib.java;
-
-/**
- * Defines the same class as the java.lang.IntegralToString which was added in
- * Dalvik VM. This hack, provides a replacement for that class which can't be
- * loaded in the standard JVM since it's in the java package and standard JVM
- * doesn't have it. Since it's no longer in java.lang, access to package
- * private methods and classes has been replaced by the closes matching public
- * implementation.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/lang/IntegralToString.java
- */
-public final class IntegralToString {
-    /**
-     * When appending to an AbstractStringBuilder, this thread-local char[] lets us avoid
-     * allocation of a temporary array. (We can't write straight into the AbstractStringBuilder
-     * because it's almost as expensive to work out the exact length of the result as it is to
-     * do the formatting. We could try being conservative and "delete"-ing the unused space
-     * afterwards, but then we'd need to duplicate convertInt and convertLong rather than share
-     * the code.)
-     */
-    private static final ThreadLocal<char[]> BUFFER = new ThreadLocal<char[]>() {
-        @Override protected char[] initialValue() {
-            return new char[20]; // Maximum length of a base-10 long.
-        }
-    };
-
-    /**
-     * These tables are used to special-case toString computation for
-     * small values.  This serves three purposes: it reduces memory usage;
-     * it increases performance for small values; and it decreases the
-     * number of comparisons required to do the length computation.
-     * Elements of this table are lazily initialized on first use.
-     * No locking is necessary, i.e., we use the non-volatile, racy
-     * single-check idiom.
-     */
-    private static final String[] SMALL_NONNEGATIVE_VALUES = new String[100];
-    private static final String[] SMALL_NEGATIVE_VALUES = new String[100];
-
-    /** TENS[i] contains the tens digit of the number i, 0 <= i <= 99. */
-    private static final char[] TENS = {
-        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
-        '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
-        '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
-        '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
-        '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
-        '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
-        '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
-        '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
-        '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
-        '9', '9', '9', '9', '9', '9', '9', '9', '9', '9'
-    };
-
-    /** Ones [i] contains the tens digit of the number i, 0 <= i <= 99. */
-    private static final char[] ONES = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-    };
-
-    /**
-     * Table for MOD / DIV 10 computation described in Section 10-21
-     * of Hank Warren's "Hacker's Delight" online addendum.
-     * http://www.hackersdelight.org/divcMore.pdf
-     */
-    private static final char[] MOD_10_TABLE = {
-        0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 0
-    };
-
-    /**
-     * The digits for every supported radix.
-     */
-    private static final char[] DIGITS = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
-        'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
-        'u', 'v', 'w', 'x', 'y', 'z'
-    };
-
-    private static final char[] UPPER_CASE_DIGITS = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
-        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
-        'U', 'V', 'W', 'X', 'Y', 'Z'
-    };
-
-    private IntegralToString() {
-    }
-
-    /**
-     * Equivalent to Integer.toString(i, radix).
-     */
-    public static String intToString(int i, int radix) {
-        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
-            radix = 10;
-        }
-        if (radix == 10) {
-            return intToString(i);
-        }
-
-        /*
-         * If i is positive, negate it. This is the opposite of what one might
-         * expect. It is necessary because the range of the negative values is
-         * strictly larger than that of the positive values: there is no
-         * positive value corresponding to Integer.MIN_VALUE.
-         */
-        boolean negative = false;
-        if (i < 0) {
-            negative = true;
-        } else {
-            i = -i;
-        }
-
-        int bufLen = radix < 8 ? 33 : 12;  // Max chars in result (conservative)
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            int q = i / radix;
-            buf[--cursor] = DIGITS[radix * q - i];
-            i = q;
-        } while (i != 0);
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    /**
-     * Equivalent to Integer.toString(i).
-     */
-    public static String intToString(int i) {
-        return convertInt(null, i);
-    }
-
-    /**
-     * Equivalent to sb.append(Integer.toString(i)).
-     */
-    public static void appendInt(StringBuilder sb, int i) {
-        convertInt(sb, i);
-    }
-
-    /**
-     * Returns the string representation of i and leaves sb alone if sb is null.
-     * Returns null and appends the string representation of i to sb if sb is non-null.
-     */
-    private static String convertInt(StringBuilder sb, int i) {
-        boolean negative = false;
-        String quickResult = null;
-        if (i < 0) {
-            negative = true;
-            i = -i;
-            if (i < 100) {
-                if (i < 0) {
-                    // If -n is still negative, n is Integer.MIN_VALUE
-                    quickResult = "-2147483648";
-                } else {
-                    quickResult = SMALL_NEGATIVE_VALUES[i];
-                    if (quickResult == null) {
-                        SMALL_NEGATIVE_VALUES[i] = quickResult =
-                                i < 10 ? stringOf('-', ONES[i]) : stringOf('-', TENS[i], ONES[i]);
-                    }
-                }
-            }
-        } else {
-            if (i < 100) {
-                quickResult = SMALL_NONNEGATIVE_VALUES[i];
-                if (quickResult == null) {
-                    SMALL_NONNEGATIVE_VALUES[i] = quickResult =
-                            i < 10 ? stringOf(ONES[i]) : stringOf(TENS[i], ONES[i]);
-                }
-            }
-        }
-        if (quickResult != null) {
-            if (sb != null) {
-                sb.append(quickResult);
-                return null;
-            }
-            return quickResult;
-        }
-
-        int bufLen = 11; // Max number of chars in result
-        char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen];
-        int cursor = bufLen;
-
-        // Calculate digits two-at-a-time till remaining digits fit in 16 bits
-        while (i >= (1 << 16)) {
-            // Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8
-            int q = (int) ((0x51EB851FL * i) >>> 37);
-            int r = i - 100*q;
-            buf[--cursor] = ONES[r];
-            buf[--cursor] = TENS[r];
-            i = q;
-        }
-
-        // Calculate remaining digits one-at-a-time for performance
-        while (i != 0) {
-            // Compute q = n/10 and r = n % 10 as per "Hacker's Delight" 10-8
-            int q = (0xCCCD * i) >>> 19;
-            int r = i - 10*q;
-            buf[--cursor] = DIGITS[r];
-            i = q;
-        }
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-
-        if (sb != null) {
-            sb.append(buf, cursor, bufLen - cursor);
-            return null;
-        } else {
-            return new String(buf, cursor, bufLen - cursor);
-        }
-    }
-
-    /**
-     * Equivalent to Long.toString(v, radix).
-     */
-    public static String longToString(long v, int radix) {
-        int i = (int) v;
-        if (i == v) {
-            return intToString(i, radix);
-        }
-
-        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
-            radix = 10;
-        }
-        if (radix == 10) {
-            return longToString(v);
-        }
-
-        /*
-         * If v is positive, negate it. This is the opposite of what one might
-         * expect. It is necessary because the range of the negative values is
-         * strictly larger than that of the positive values: there is no
-         * positive value corresponding to Integer.MIN_VALUE.
-         */
-        boolean negative = false;
-        if (v < 0) {
-            negative = true;
-        } else {
-            v = -v;
-        }
-
-        int bufLen = radix < 8 ? 65 : 23;  // Max chars in result (conservative)
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            long q = v / radix;
-            buf[--cursor] = DIGITS[(int) (radix * q - v)];
-            v = q;
-        } while (v != 0);
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    /**
-     * Equivalent to Long.toString(l).
-     */
-    public static String longToString(long l) {
-        return convertLong(null, l);
-    }
-
-    /**
-     * Equivalent to sb.append(Long.toString(l)).
-     */
-    public static void appendLong(StringBuilder sb, long l) {
-        convertLong(sb, l);
-    }
-
-    /**
-     * Returns the string representation of n and leaves sb alone if sb is null.
-     * Returns null and appends the string representation of n to sb if sb is non-null.
-     */
-    private static String convertLong(StringBuilder sb, long n) {
-        int i = (int) n;
-        if (i == n) {
-            return convertInt(sb, i);
-        }
-
-        boolean negative = (n < 0);
-        if (negative) {
-            n = -n;
-            if (n < 0) {
-                // If -n is still negative, n is Long.MIN_VALUE
-                String quickResult = "-9223372036854775808";
-                if (sb != null) {
-                    sb.append(quickResult);
-                    return null;
-                }
-                return quickResult;
-            }
-        }
-
-        int bufLen = 20; // Maximum number of chars in result
-        char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen];
-
-        int low = (int) (n % 1000000000); // Extract low-order 9 digits
-        int cursor = intIntoCharArray(buf, bufLen, low);
-
-        // Zero-pad Low order part to 9 digits
-        while (cursor != (bufLen - 9)) {
-            buf[--cursor] = '0';
-        }
-
-        /*
-         * The remaining digits are (n - low) / 1,000,000,000.  This
-         * "exact division" is done as per the online addendum to Hank Warren's
-         * "Hacker's Delight" 10-20, http://www.hackersdelight.org/divcMore.pdf
-         */
-        n = ((n - low) >>> 9) * 0x8E47CE423A2E9C6DL;
-
-        /*
-         * If the remaining digits fit in an int, emit them using a
-         * single call to intIntoCharArray. Otherwise, strip off the
-         * low-order digit, put it in buf, and then call intIntoCharArray
-         * on the remaining digits (which now fit in an int).
-         */
-        if ((n & (-1L << 32)) == 0) {
-            cursor = intIntoCharArray(buf, cursor, (int) n);
-        } else {
-            /*
-             * Set midDigit to n % 10
-             */
-            int lo32 = (int) n;
-            int hi32 = (int) (n >>> 32);
-
-            // midDigit = ((unsigned) low32) % 10, per "Hacker's Delight" 10-21
-            int midDigit = MOD_10_TABLE[(0x19999999 * lo32 + (lo32 >>> 1) + (lo32 >>> 3)) >>> 28];
-
-            // Adjust midDigit for hi32. (assert hi32 == 1 || hi32 == 2)
-            midDigit -= hi32 << 2;  // 1L << 32 == -4 MOD 10
-            if (midDigit < 0) {
-                midDigit += 10;
-            }
-            buf[--cursor] = DIGITS[midDigit];
-
-            // Exact division as per Warren 10-20
-            int rest = ((int) ((n - midDigit) >>> 1)) * 0xCCCCCCCD;
-            cursor = intIntoCharArray(buf, cursor, rest);
-        }
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-        if (sb != null) {
-            sb.append(buf, cursor, bufLen - cursor);
-            return null;
-        } else {
-            return new String(buf, cursor, bufLen - cursor);
-        }
-    }
-
-    /**
-     * Inserts the unsigned decimal integer represented by n into the specified
-     * character array starting at position cursor.  Returns the index after
-     * the last character inserted (i.e., the value to pass in as cursor the
-     * next time this method is called). Note that n is interpreted as a large
-     * positive integer (not a negative integer) if its sign bit is set.
-     */
-    private static int intIntoCharArray(char[] buf, int cursor, int n) {
-        // Calculate digits two-at-a-time till remaining digits fit in 16 bits
-        while ((n & 0xffff0000) != 0) {
-            /*
-             * Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8.
-             * This computation is slightly different from the corresponding
-             * computation in intToString: the shifts before and after
-             * multiply can't be combined, as that would yield the wrong result
-             * if n's sign bit were set.
-             */
-            int q = (int) ((0x51EB851FL * (n >>> 2)) >>> 35);
-            int r = n - 100*q;
-            buf[--cursor] = ONES[r];
-            buf[--cursor] = TENS[r];
-            n = q;
-        }
-
-        // Calculate remaining digits one-at-a-time for performance
-        while (n != 0) {
-            // Compute q = n / 10 and r = n % 10 as per "Hacker's Delight" 10-8
-            int q = (0xCCCD * n) >>> 19;
-            int r = n - 10*q;
-            buf[--cursor] = DIGITS[r];
-            n = q;
-        }
-        return cursor;
-    }
-
-    public static String intToBinaryString(int i) {
-        int bufLen = 32;  // Max number of binary digits in an int
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[i & 1];
-        }  while ((i >>>= 1) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String longToBinaryString(long v) {
-        int i = (int) v;
-        if (v >= 0 && i == v) {
-            return intToBinaryString(i);
-        }
-
-        int bufLen = 64;  // Max number of binary digits in a long
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[((int) v) & 1];
-        }  while ((v >>>= 1) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static StringBuilder appendByteAsHex(StringBuilder sb, byte b, boolean upperCase) {
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        sb.append(digits[(b >> 4) & 0xf]);
-        sb.append(digits[b & 0xf]);
-        return sb;
-    }
-
-    public static String byteToHexString(byte b, boolean upperCase) {
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        char[] buf = new char[2]; // We always want two digits.
-        buf[0] = digits[(b >> 4) & 0xf];
-        buf[1] = digits[b & 0xf];
-        return new String(buf, 0, 2);
-    }
-
-    public static String bytesToHexString(byte[] bytes, boolean upperCase) {
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        char[] buf = new char[bytes.length * 2];
-        int c = 0;
-        for (byte b : bytes) {
-            buf[c++] = digits[(b >> 4) & 0xf];
-            buf[c++] = digits[b & 0xf];
-        }
-        return new String(buf);
-    }
-
-    public static String intToHexString(int i, boolean upperCase, int minWidth) {
-        int bufLen = 8;  // Max number of hex digits in an int
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        do {
-            buf[--cursor] = digits[i & 0xf];
-        } while ((i >>>= 4) != 0 || (bufLen - cursor < minWidth));
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String longToHexString(long v) {
-        int i = (int) v;
-        if (v >= 0 && i == v) {
-            return intToHexString(i, false, 0);
-        }
-
-        int bufLen = 16;  // Max number of hex digits in a long
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[((int) v) & 0xF];
-        } while ((v >>>= 4) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String intToOctalString(int i) {
-        int bufLen = 11;  // Max number of octal digits in an int
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[i & 7];
-        } while ((i >>>= 3) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String longToOctalString(long v) {
-        int i = (int) v;
-        if (v >= 0 && i == v) {
-            return intToOctalString(i);
-        }
-        int bufLen = 22;  // Max number of octal digits in a long
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[((int) v) & 7];
-        } while ((v >>>= 3) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    private static String stringOf(char... args) {
-        return new String(args, 0, args.length);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/LinkedHashMap_Delegate.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/LinkedHashMap_Delegate.java
deleted file mode 100644
index 59cc75f..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/LinkedHashMap_Delegate.java
+++ /dev/null
@@ -1,36 +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.tools.layoutlib.java;
-
-import com.android.tools.layoutlib.create.ReplaceMethodCallsAdapter;
-
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Provides alternate implementation to java.util.LinkedHashMap#eldest(), which is present as a
- * non-public method in the Android VM, but not present on the host VM. This is injected in the
- * layoutlib using {@link ReplaceMethodCallsAdapter}.
- */
-public class LinkedHashMap_Delegate {
-    public static <K,V> Map.Entry<K,V> eldest(LinkedHashMap<K,V> map) {
-        Iterator<Entry<K, V>> iterator = map.entrySet().iterator();
-        return iterator.hasNext() ? iterator.next() : null;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Objects.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Objects.java
deleted file mode 100644
index eb1ef72..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Objects.java
+++ /dev/null
@@ -1,132 +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.tools.layoutlib.java;
-
-import java.util.Arrays;
-import java.util.Comparator;
-
-/**
- * Defines the same class as the java.util.Objects which is added in Java 7.
- * This hack makes it possible to run the Android code which uses Java 7 features
- * (API 18 and beyond) to run on Java 6.
- * <p/>
- * Extracted from API level 19, file:
- * platform/libcore/luni/src/main/java/java/util/Objects.java
- */
-public final class Objects {
-  private Objects() {}
-
-  /**
-   * Returns 0 if {@code a == b}, or {@code c.compare(a, b)} otherwise.
-   * That is, this makes {@code c} null-safe.
-   */
-  public static <T> int compare(T a, T b, Comparator<? super T> c) {
-    if (a == b) {
-      return 0;
-    }
-    return c.compare(a, b);
-  }
-
-  /**
-   * Returns true if both arguments are null,
-   * the result of {@link Arrays#equals} if both arguments are primitive arrays,
-   * the result of {@link Arrays#deepEquals} if both arguments are arrays of reference types,
-   * and the result of {@link #equals} otherwise.
-   */
-  public static boolean deepEquals(Object a, Object b) {
-    if (a == null || b == null) {
-      return a == b;
-    } else if (a instanceof Object[] && b instanceof Object[]) {
-      return Arrays.deepEquals((Object[]) a, (Object[]) b);
-    } else if (a instanceof boolean[] && b instanceof boolean[]) {
-      return Arrays.equals((boolean[]) a, (boolean[]) b);
-    } else if (a instanceof byte[] && b instanceof byte[]) {
-      return Arrays.equals((byte[]) a, (byte[]) b);
-    } else if (a instanceof char[] && b instanceof char[]) {
-      return Arrays.equals((char[]) a, (char[]) b);
-    } else if (a instanceof double[] && b instanceof double[]) {
-      return Arrays.equals((double[]) a, (double[]) b);
-    } else if (a instanceof float[] && b instanceof float[]) {
-      return Arrays.equals((float[]) a, (float[]) b);
-    } else if (a instanceof int[] && b instanceof int[]) {
-      return Arrays.equals((int[]) a, (int[]) b);
-    } else if (a instanceof long[] && b instanceof long[]) {
-      return Arrays.equals((long[]) a, (long[]) b);
-    } else if (a instanceof short[] && b instanceof short[]) {
-      return Arrays.equals((short[]) a, (short[]) b);
-    }
-    return a.equals(b);
-  }
-
-  /**
-   * Null-safe equivalent of {@code a.equals(b)}.
-   */
-  public static boolean equals(Object a, Object b) {
-    return (a == null) ? (b == null) : a.equals(b);
-  }
-
-  /**
-   * Convenience wrapper for {@link Arrays#hashCode}, adding varargs.
-   * This can be used to compute a hash code for an object's fields as follows:
-   * {@code Objects.hash(a, b, c)}.
-   */
-  public static int hash(Object... values) {
-    return Arrays.hashCode(values);
-  }
-
-  /**
-   * Returns 0 for null or {@code o.hashCode()}.
-   */
-  public static int hashCode(Object o) {
-    return (o == null) ? 0 : o.hashCode();
-  }
-
-  /**
-   * Returns {@code o} if non-null, or throws {@code NullPointerException}.
-   */
-  public static <T> T requireNonNull(T o) {
-    if (o == null) {
-      throw new NullPointerException();
-    }
-    return o;
-  }
-
-  /**
-   * Returns {@code o} if non-null, or throws {@code NullPointerException}
-   * with the given detail message.
-   */
-  public static <T> T requireNonNull(T o, String message) {
-    if (o == null) {
-      throw new NullPointerException(message);
-    }
-    return o;
-  }
-
-  /**
-   * Returns "null" for null or {@code o.toString()}.
-   */
-  public static String toString(Object o) {
-    return (o == null) ? "null" : o.toString();
-  }
-
-  /**
-   * Returns {@code nullString} for null or {@code o.toString()}.
-   */
-  public static String toString(Object o, String nullString) {
-    return (o == null) ? nullString : o.toString();
-  }
-}
\ No newline at end of file
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/System_Delegate.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/System_Delegate.java
deleted file mode 100644
index be93744..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/System_Delegate.java
+++ /dev/null
@@ -1,68 +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.tools.layoutlib.java;
-
-import com.android.tools.layoutlib.create.ReplaceMethodCallsAdapter;
-
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Provides dummy implementation of methods that don't exist on the host VM.
- * This also providers a time control that allows to set a specific system time.
- *
- * @see ReplaceMethodCallsAdapter
- */
-@SuppressWarnings("unused")
-public class System_Delegate {
-    // Current system time
-    private static AtomicLong mNanosTime = new AtomicLong(System.nanoTime());
-    // Time that the system booted up in nanos
-    private static AtomicLong mBootNanosTime = new AtomicLong(System.nanoTime());
-
-    public static void log(String message) {
-        // ignore.
-    }
-
-    public static void log(String message, Throwable th) {
-        // ignore.
-    }
-
-    public static void setNanosTime(long nanos) {
-        mNanosTime.set(nanos);
-    }
-
-    public static void setBootTimeNanos(long nanos) {
-        mBootNanosTime.set(nanos);
-    }
-
-    public static long nanoTime() {
-        return mNanosTime.get();
-    }
-
-    public static long currentTimeMillis() {
-        return TimeUnit.NANOSECONDS.toMillis(mNanosTime.get());
-    }
-
-    public static long bootTime() {
-        return mBootNanosTime.get();
-    }
-
-    public static long bootTimeMillis() {
-        return TimeUnit.NANOSECONDS.toMillis(mBootNanosTime.get());
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java
deleted file mode 100644
index 0e09080..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java
+++ /dev/null
@@ -1,81 +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.tools.layoutlib.java;
-
-import java.nio.charset.Charset;
-
-/**
- * Defines the same class as the java.lang.UnsafeByteSequence which was added in
- * Dalvik VM. This hack, provides a replacement for that class which can't be
- * loaded in the standard JVM since it's in the java package and standard JVM
- * doesn't have it.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/lang/UnsafeByteSequence.java
- */
-public class UnsafeByteSequence {
-    private byte[] bytes;
-    private int count;
-
-    public UnsafeByteSequence(int initialCapacity) {
-        this.bytes = new byte[initialCapacity];
-    }
-
-    public int size() {
-        return count;
-    }
-
-    /**
-     * Moves the write pointer back to the beginning of the sequence,
-     * but without resizing or reallocating the buffer.
-     */
-    public void rewind() {
-        count = 0;
-    }
-
-    public void write(byte[] buffer, int offset, int length) {
-        if (count + length >= bytes.length) {
-            byte[] newBytes = new byte[(count + length) * 2];
-            System.arraycopy(bytes, 0, newBytes, 0, count);
-            bytes = newBytes;
-        }
-        System.arraycopy(buffer, offset, bytes, count, length);
-        count += length;
-    }
-
-    public void write(int b) {
-        if (count == bytes.length) {
-            byte[] newBytes = new byte[count * 2];
-            System.arraycopy(bytes, 0, newBytes, 0, count);
-            bytes = newBytes;
-        }
-        bytes[count++] = (byte) b;
-    }
-
-    public byte[] toByteArray() {
-        if (count == bytes.length) {
-            return bytes;
-        }
-        byte[] result = new byte[count];
-        System.arraycopy(bytes, 0, result, 0, count);
-        return result;
-    }
-
-    public String toString(Charset cs) {
-        return new String(bytes, 0, count, cs);
-    }
-}
diff --git a/tools/layoutlib/create/tests/Android.mk b/tools/layoutlib/create/tests/Android.mk
deleted file mode 100644
index 488d7d6..0000000
--- a/tools/layoutlib/create/tests/Android.mk
+++ /dev/null
@@ -1,35 +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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-# Only compile source java files in this lib.
-LOCAL_SRC_FILES := $(call all-java-files-under, com)
-
-LOCAL_JAVA_RESOURCE_DIRS := data mock_data
-
-LOCAL_MODULE := layoutlib-create-tests
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_JAVA_LIBRARIES := layoutlib_create junit-host
-LOCAL_STATIC_JAVA_LIBRARIES := asm-5.2
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Copy the jar to DIST_DIR for sdk builds
-$(call dist-for-goals, sdk win_sdk, $(LOCAL_INSTALLED_MODULE))
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
deleted file mode 100644
index f86917a..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.create.AsmAnalyzer.DependencyVisitor;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * Unit tests for some methods of {@link AsmAnalyzer}.
- */
-public class AsmAnalyzerTest {
-
-    private MockLog mLog;
-    private ArrayList<String> mOsJarPath;
-    private AsmAnalyzer mAa;
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-        URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar");
-
-        mOsJarPath = new ArrayList<>();
-        //noinspection ConstantConditions
-        mOsJarPath.add(url.getFile());
-
-        Set<String> excludeClasses = Collections.singleton("java.lang.JavaClass");
-
-        String[] includeFiles = new String[]{"mock_android/data/data*"};
-        mAa = new AsmAnalyzer(mLog, mOsJarPath, null /* gen */, null /* deriveFrom */,
-                null /* includeGlobs */, excludeClasses, includeFiles);
-    }
-
-    @Test
-    public void testParseZip() throws IOException {
-
-        Map<String, ClassReader> map = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, map, filesFound);
-
-        assertArrayEquals(new String[] {
-                "java.lang.JavaClass",
-                "mock_android.dummy.InnerTest",
-                "mock_android.dummy.InnerTest$DerivingClass",
-                "mock_android.dummy.InnerTest$MyGenerics1",
-                "mock_android.dummy.InnerTest$MyIntEnum",
-                "mock_android.dummy.InnerTest$MyStaticInnerClass",
-                "mock_android.dummy.InnerTest$NotStaticInner1",
-                "mock_android.dummy.InnerTest$NotStaticInner2",
-                "mock_android.util.EmptyArray",
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams",
-                "mock_android.widget.LinearLayout",
-                "mock_android.widget.LinearLayout$LayoutParams",
-                "mock_android.widget.TableLayout",
-                "mock_android.widget.TableLayout$LayoutParams"
-            },
-            map.keySet().toArray());
-        assertArrayEquals(new String[] {"mock_android/data/dataFile"},
-            filesFound.keySet().toArray());
-    }
-
-    @Test
-    public void testFindClass() throws IOException, LogAbortException {
-
-        Map<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, zipClasses, filesFound);
-        TreeMap<String, ClassReader> found = new TreeMap<>();
-
-        ClassReader cr = mAa.findClass("mock_android.view.ViewGroup$LayoutParams",
-                zipClasses, found);
-
-        assertNotNull(cr);
-        assertEquals("mock_android/view/ViewGroup$LayoutParams", cr.getClassName());
-        assertArrayEquals(new String[] { "mock_android.view.ViewGroup$LayoutParams" },
-                found.keySet().toArray());
-        assertArrayEquals(new ClassReader[] { cr }, found.values().toArray());
-    }
-
-    @Test
-    public void testFindGlobs() throws IOException, LogAbortException {
-
-        Map<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, zipClasses, filesFound);
-        TreeMap<String, ClassReader> found = new TreeMap<>();
-
-        // this matches classes, a package match returns nothing
-        found.clear();
-        mAa.findGlobs("mock_android.view", zipClasses, found);
-
-        assertArrayEquals(new String[] { },
-            found.keySet().toArray());
-
-        // a complex glob search. * is a search pattern that matches names, not dots
-        mAa.findGlobs("mock_android.*.*Group$*Layout*", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams"
-            },
-            found.keySet().toArray());
-
-        // a complex glob search. ** is a search pattern that matches names including dots
-        mAa.findGlobs("mock_android.**Group*", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.ViewGroup",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams"
-            },
-            found.keySet().toArray());
-
-        // matches a single class
-        found.clear();
-        mAa.findGlobs("mock_android.view.View", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View"
-            },
-            found.keySet().toArray());
-
-        // matches everyting inside the given package but not sub-packages
-        found.clear();
-        mAa.findGlobs("mock_android.view.*", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams"
-            },
-            found.keySet().toArray());
-
-        for (String key : found.keySet()) {
-            ClassReader value = found.get(key);
-            assertNotNull("No value for " + key, value);
-            assertEquals(key, AsmAnalyzer.classReaderToClassName(value));
-        }
-    }
-
-    @Test
-    public void testFindClassesDerivingFrom() throws LogAbortException, IOException {
-
-        Map<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, zipClasses, filesFound);
-        TreeMap<String, ClassReader> found = new TreeMap<>();
-
-        mAa.findClassesDerivingFrom("mock_android.view.View", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup",
-                "mock_android.widget.LinearLayout",
-                "mock_android.widget.TableLayout",
-            },
-            found.keySet().toArray());
-
-        for (String key : found.keySet()) {
-            ClassReader value = found.get(key);
-            assertNotNull("No value for " + key, value);
-            assertEquals(key, AsmAnalyzer.classReaderToClassName(value));
-        }
-    }
-
-    @Test
-    public void testDependencyVisitor() throws IOException, LogAbortException {
-
-        Map<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, zipClasses, filesFound);
-        TreeMap<String, ClassReader> keep = new TreeMap<>();
-        TreeMap<String, ClassReader> new_keep = new TreeMap<>();
-        TreeMap<String, ClassReader> in_deps = new TreeMap<>();
-        TreeMap<String, ClassReader> out_deps = new TreeMap<>();
-
-        ClassReader cr = mAa.findClass("mock_android.widget.LinearLayout", zipClasses, keep);
-        DependencyVisitor visitor = mAa.getVisitor(zipClasses, keep, new_keep, in_deps, out_deps);
-
-        // get first level dependencies
-        cr.accept(visitor, 0 /* flags */);
-
-        assertArrayEquals(new String[] {
-                "mock_android.util.EmptyArray",
-                "mock_android.view.ViewGroup",
-                "mock_android.widget.LinearLayout$LayoutParams",
-            },
-            out_deps.keySet().toArray());
-
-        in_deps.putAll(out_deps);
-        out_deps.clear();
-
-        // get second level dependencies
-        for (ClassReader cr2 : in_deps.values()) {
-            cr2.accept(visitor, 0 /* flags */);
-        }
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams",
-            },
-            out_deps.keySet().toArray());
-
-        in_deps.putAll(out_deps);
-        out_deps.clear();
-
-        // get third level dependencies (there are none)
-        for (ClassReader cr2 : in_deps.values()) {
-            cr2.accept(visitor, 0 /* flags */);
-        }
-        keep.putAll(new_keep);
-
-        assertArrayEquals(new String[] { }, out_deps.keySet().toArray());
-        assertArrayEquals(new String[] {
-                "mock_android.widget.LinearLayout",
-        }, keep.keySet().toArray());
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
deleted file mode 100644
index e718fb9..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package com.android.tools.layoutlib.create;
-
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Unit tests for some methods of {@link AsmGenerator}.
- */
-public class AsmGeneratorTest {
-    private MockLog mLog;
-    private ArrayList<String> mOsJarPath;
-    private String mOsDestJar;
-    private File mTempFile;
-
-    // ASM internal name for the the class in java package that should be refactored.
-    private static final String JAVA_CLASS_NAME = "java/lang/JavaClass";
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-        URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar");
-
-        mOsJarPath = new ArrayList<>();
-        //noinspection ConstantConditions
-        mOsJarPath.add(url.getFile());
-
-        mTempFile = File.createTempFile("mock", ".jar");
-        mOsDestJar = mTempFile.getAbsolutePath();
-        mTempFile.deleteOnExit();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        if (mTempFile != null) {
-            //noinspection ResultOfMethodCallIgnored
-            mTempFile.delete();
-            mTempFile = null;
-        }
-    }
-
-    @Test
-    public void testClassRenaming() throws IOException, LogAbortException {
-
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public String[] getRenamedClasses() {
-                // classes to rename (so that we can replace them)
-                return new String[] {
-                        "mock_android.view.View", "mock_android.view._Original_View",
-                        "not.an.actual.ClassName", "anoter.fake.NewClassName",
-                };
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                    "**"
-                },
-                Collections.emptySet() /* excluded classes */,
-                new String[]{} /* include files */);
-        aa.analyze();
-        agen.generate();
-
-        Set<String> notRenamed = agen.getClassesNotRenamed();
-        assertArrayEquals(new String[] { "not/an/actual/ClassName" }, notRenamed.toArray());
-
-    }
-
-    @Test
-    public void testJavaClassRefactoring() throws IOException, LogAbortException {
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public Class<?>[] getInjectedClasses() {
-                // classes to inject in the final JAR
-                return new Class<?>[] {
-                        com.android.tools.layoutlib.create.dataclass.JavaClass.class
-                };
-            }
-
-            @Override
-            public String[] getJavaPkgClasses() {
-             // classes to refactor (so that we can replace them)
-                return new String[] {
-                        "java.lang.JavaClass", "com.android.tools.layoutlib.create.dataclass.JavaClass",
-                };
-            }
-
-            @Override
-            public Set<String> getExcludedClasses() {
-                return Collections.singleton("java.lang.JavaClass");
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                    "**"
-                },
-                Collections.emptySet(),
-                new String[] {        /* include files */
-                    "mock_android/data/data*"
-                });
-        aa.analyze();
-        agen.generate();
-        Map<String, ClassReader> output = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-        parseZip(mOsDestJar, output, filesFound);
-        RecordingClassVisitor cv = new RecordingClassVisitor();
-        for (ClassReader cr: output.values()) {
-            cr.accept(cv, 0);
-        }
-        assertTrue(cv.mVisitedClasses.contains(
-                "com/android/tools/layoutlib/create/dataclass/JavaClass"));
-        assertFalse(cv.mVisitedClasses.contains(
-                JAVA_CLASS_NAME));
-        assertArrayEquals(new String[] {"mock_android/data/dataFile"},
-                filesFound.keySet().toArray());
-    }
-
-    @Test
-    public void testClassRefactoring() throws IOException, LogAbortException {
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public Class<?>[] getInjectedClasses() {
-                // classes to inject in the final JAR
-                return new Class<?>[] {
-                        com.android.tools.layoutlib.create.dataclass.JavaClass.class
-                };
-            }
-
-            @Override
-            public String[] getRefactoredClasses() {
-                // classes to refactor (so that we can replace them)
-                return new String[] {
-                        "mock_android.view.View", "mock_android.view._Original_View",
-                };
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                        "**"
-                },
-                Collections.emptySet(),
-                new String[] {});
-        aa.analyze();
-        agen.generate();
-        Map<String, ClassReader> output = new TreeMap<>();
-        parseZip(mOsDestJar, output, new TreeMap<>());
-        RecordingClassVisitor cv = new RecordingClassVisitor();
-        for (ClassReader cr: output.values()) {
-            cr.accept(cv, 0);
-        }
-        assertTrue(cv.mVisitedClasses.contains(
-                "mock_android/view/_Original_View"));
-        assertFalse(cv.mVisitedClasses.contains(
-                "mock_android/view/View"));
-    }
-
-    @Test
-    public void testClassExclusion() throws IOException, LogAbortException {
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public Set<String> getExcludedClasses() {
-                Set<String> set = new HashSet<>(2);
-                set.add("mock_android.dummy.InnerTest");
-                set.add("java.lang.JavaClass");
-                return set;
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-        Set<String> excludedClasses = ci.getExcludedClasses();
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                        "**"
-                },
-                excludedClasses,
-                new String[] {        /* include files */
-                        "mock_android/data/data*"
-                });
-        aa.analyze();
-        agen.generate();
-        Map<String, ClassReader> output = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-        parseZip(mOsDestJar, output, filesFound);
-        for (String s : output.keySet()) {
-            assertFalse(excludedClasses.contains(s));
-        }
-        assertArrayEquals(new String[] {"mock_android/data/dataFile"},
-                filesFound.keySet().toArray());
-    }
-
-    @Test
-    public void testMethodInjection() throws IOException, LogAbortException,
-            ClassNotFoundException, IllegalAccessException, InstantiationException,
-            NoSuchMethodException, InvocationTargetException {
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
-                return Collections.singletonMap("mock_android.util.EmptyArray",
-                        InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER);
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                        "**"
-                },
-                ci.getExcludedClasses(),
-                new String[] {        /* include files */
-                        "mock_android/data/data*"
-                });
-        aa.analyze();
-        agen.generate();
-        Map<String, ClassReader> output = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-        parseZip(mOsDestJar, output, filesFound);
-        final String modifiedClass = "mock_android.util.EmptyArray";
-        final String modifiedClassPath = modifiedClass.replace('.', '/').concat(".class");
-        ZipFile zipFile = new ZipFile(mOsDestJar);
-        ZipEntry entry = zipFile.getEntry(modifiedClassPath);
-        assertNotNull(entry);
-        final byte[] bytes;
-        try (InputStream inputStream = zipFile.getInputStream(entry)) {
-            bytes = getByteArray(inputStream);
-        }
-        ClassLoader classLoader = new ClassLoader(getClass().getClassLoader()) {
-            @Override
-            protected Class<?> findClass(String name) throws ClassNotFoundException {
-                if (name.equals(modifiedClass)) {
-                    return defineClass(null, bytes, 0, bytes.length);
-                }
-                throw new ClassNotFoundException(name + " not found.");
-            }
-        };
-        Class<?> emptyArrayClass = classLoader.loadClass(modifiedClass);
-        Object emptyArrayInstance = emptyArrayClass.newInstance();
-        Method method = emptyArrayClass.getMethod("getFrameworkClassLoader");
-        Object cl = method.invoke(emptyArrayInstance);
-        assertEquals(classLoader, cl);
-    }
-
-    private static byte[] getByteArray(InputStream stream) throws IOException {
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        byte[] buffer = new byte[1024];
-        int read;
-        while ((read = stream.read(buffer, 0, buffer.length)) > -1) {
-            bos.write(buffer, 0, read);
-        }
-        return bos.toByteArray();
-    }
-
-    private void parseZip(String jarPath,
-            Map<String, ClassReader> classes,
-            Map<String, InputStream> filesFound) throws IOException {
-
-            ZipFile zip = new ZipFile(jarPath);
-            Enumeration<? extends ZipEntry> entries = zip.entries();
-            ZipEntry entry;
-            while (entries.hasMoreElements()) {
-                entry = entries.nextElement();
-                if (entry.getName().endsWith(".class")) {
-                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
-                    String className = classReaderToClassName(cr);
-                    classes.put(className, cr);
-                } else {
-                    filesFound.put(entry.getName(), zip.getInputStream(entry));
-                }
-            }
-
-    }
-
-    private String classReaderToClassName(ClassReader classReader) {
-        if (classReader == null) {
-            return null;
-        } else {
-            return classReader.getClassName().replace('/', '.');
-        }
-    }
-
-    /**
-     * {@link ClassVisitor} that records every class that sees.
-     */
-    private static class RecordingClassVisitor extends ClassVisitor {
-        private Set<String> mVisitedClasses = new HashSet<>();
-
-        private RecordingClassVisitor() {
-            super(Main.ASM_VERSION);
-        }
-
-        private void addClass(String className) {
-            if (className == null) {
-                return;
-            }
-
-            int pos = className.indexOf('$');
-            if (pos > 0) {
-                // For inner classes, add also the base class
-                mVisitedClasses.add(className.substring(0, pos));
-            }
-            mVisitedClasses.add(className);
-        }
-
-        @Override
-        public void visit(int version, int access, String name, String signature, String superName,
-                String[] interfaces) {
-            addClass(superName);
-            Arrays.stream(interfaces).forEach(this::addClass);
-        }
-
-        private void processType(Type type) {
-            switch (type.getSort()) {
-                case Type.OBJECT:
-                    addClass(type.getInternalName());
-                    break;
-                case Type.ARRAY:
-                    addClass(type.getElementType().getInternalName());
-                    break;
-                case Type.METHOD:
-                    processType(type.getReturnType());
-                    Arrays.stream(type.getArgumentTypes()).forEach(this::processType);
-                    break;
-            }
-        }
-
-        @Override
-        public FieldVisitor visitField(int access, String name, String desc, String signature,
-                Object value) {
-            processType(Type.getType(desc));
-            return super.visitField(access, name, desc, signature, value);
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
-                String[] exceptions) {
-            MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
-            return new MethodVisitor(Main.ASM_VERSION, mv) {
-
-                @Override
-                public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-                    addClass(owner);
-                    processType(Type.getType(desc));
-                    super.visitFieldInsn(opcode, owner, name, desc);
-                }
-
-                @Override
-                public void visitLdcInsn(Object cst) {
-                    if (cst instanceof Type) {
-                        processType((Type) cst);
-                    }
-                    super.visitLdcInsn(cst);
-                }
-
-                @Override
-                public void visitTypeInsn(int opcode, String type) {
-                    addClass(type);
-                    super.visitTypeInsn(opcode, type);
-                }
-
-                @Override
-                public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                        boolean itf) {
-                    addClass(owner);
-                    processType(Type.getType(desc));
-                    super.visitMethodInsn(opcode, owner, name, desc, itf);
-                }
-
-            };
-        }
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java
deleted file mode 100644
index 0cdcdc0..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import static org.junit.Assert.*;
-
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-
-import java.io.IOException;
-import java.util.ArrayList;
-
-
-/**
- * Tests {@link ClassHasNativeVisitor}.
- */
-public class ClassHasNativeVisitorTest {
-
-    @Test
-    public void testHasNative() throws IOException {
-        MockClassHasNativeVisitor cv = new MockClassHasNativeVisitor();
-        String className =
-                this.getClass().getCanonicalName() + "$" + ClassWithNative.class.getSimpleName();
-        ClassReader cr = new ClassReader(className);
-
-        cr.accept(cv, 0 /* flags */);
-        assertArrayEquals(new String[] { "native_method" }, cv.getMethodsFound());
-        assertTrue(cv.hasNativeMethods());
-    }
-
-    @Test
-    public void testHasNoNative() throws IOException {
-        MockClassHasNativeVisitor cv = new MockClassHasNativeVisitor();
-        String className =
-            this.getClass().getCanonicalName() + "$" + ClassWithoutNative.class.getSimpleName();
-        ClassReader cr = new ClassReader(className);
-
-        cr.accept(cv, 0 /* flags */);
-        assertArrayEquals(new String[0], cv.getMethodsFound());
-        assertFalse(cv.hasNativeMethods());
-    }
-
-    //-------
-
-    /**
-     * Overrides {@link ClassHasNativeVisitor} to collec the name of the native methods found.
-     */
-    private static class MockClassHasNativeVisitor extends ClassHasNativeVisitor {
-        private ArrayList<String> mMethodsFound = new ArrayList<>();
-
-        public String[] getMethodsFound() {
-            return mMethodsFound.toArray(new String[mMethodsFound.size()]);
-        }
-
-        @Override
-        protected void setHasNativeMethods(boolean hasNativeMethods, String methodName) {
-            if (hasNativeMethods) {
-                mMethodsFound.add(methodName);
-            }
-            super.setHasNativeMethods(hasNativeMethods, methodName);
-        }
-    }
-
-    /**
-     * Dummy test class with a native method.
-     */
-    public static class ClassWithNative {
-        public ClassWithNative() {
-        }
-
-        public void callTheNativeMethod() {
-            native_method();
-        }
-
-        private native void native_method();
-    }
-
-    /**
-     * Dummy test class with no native method.
-     */
-    public static class ClassWithoutNative {
-        public ClassWithoutNative() {
-        }
-
-        public void someMethod() {
-        }
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/CreateInfoAdapter.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/CreateInfoAdapter.java
deleted file mode 100644
index ad7cb9a..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/CreateInfoAdapter.java
+++ /dev/null
@@ -1,80 +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.tools.layoutlib.create;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-class CreateInfoAdapter implements ICreateInfo {
-    private static final String[] EMPTY_STRING_ARRAY = new String[0];
-
-    @Override
-    public Class<?>[] getInjectedClasses() {
-        return new Class<?>[0];
-    }
-
-    @Override
-    public String[] getDelegateMethods() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getDelegateClassNatives() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getRenamedClasses() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getRefactoredClasses() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getDeleteReturns() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getJavaPkgClasses() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public Set<String> getExcludedClasses() {
-        return Collections.emptySet();
-    }
-
-    @Override
-    public String[] getPromotedFields() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getPromotedClasses() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
-        return Collections.emptyMap();
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java
deleted file mode 100644
index afaa399..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.tools.layoutlib.create.dataclass.ClassWithNative;
-import com.android.tools.layoutlib.create.dataclass.OuterClass;
-import com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass;
-import com.android.tools.layoutlib.create.dataclass.OuterClass.StaticInnerClass;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-public class DelegateClassAdapterTest {
-
-    private MockLog mLog;
-
-    private static final String NATIVE_CLASS_NAME = ClassWithNative.class.getName();
-    private static final String OUTER_CLASS_NAME = OuterClass.class.getName();
-    private static final String INNER_CLASS_NAME = InnerClass.class.getName();
-    private static final String STATIC_INNER_CLASS_NAME = StaticInnerClass.class.getName();
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-        mLog.setVerbose(true); // capture debug error too
-    }
-
-    /**
-     * Tests that a class not being modified still works.
-     */
-    @Test
-    public void testNoOp() throws Throwable {
-        // create an instance of the class that will be modified
-        // (load the class in a distinct class loader so that we can trash its definition later)
-        ClassLoader cl1 = new ClassLoader(this.getClass().getClassLoader()) { };
-        @SuppressWarnings("unchecked")
-        Class<ClassWithNative> clazz1 = (Class<ClassWithNative>) cl1.loadClass(NATIVE_CLASS_NAME);
-        ClassWithNative instance1 = clazz1.newInstance();
-        assertEquals(42, instance1.add(20, 22));
-        try {
-            instance1.callNativeInstance(10, 3.1415, new Object[0] );
-            fail("Test should have failed to invoke callTheNativeMethod [1]");
-        } catch (UnsatisfiedLinkError e) {
-            // This is expected to fail since the native method is not implemented.
-        }
-
-        // Now process it but tell the delegate to not modify any method
-        ClassWriter cw = new ClassWriter(0 /*flags*/);
-
-        HashSet<String> delegateMethods = new HashSet<>();
-        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cv = new DelegateClassAdapter(
-                mLog, cw, internalClassName, delegateMethods);
-
-        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
-        cr.accept(cv, 0 /* flags */);
-
-        // Load the generated class in a different class loader and try it again
-
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-                    Class<?> clazz2 = loadClass(NATIVE_CLASS_NAME);
-                    Object i2 = clazz2.newInstance();
-                    assertNotNull(i2);
-                    assertEquals(42, callAdd(i2, 20, 22));
-
-                    try {
-                        callCallNativeInstance(i2, 10, 3.1415, new Object[0]);
-                        fail("Test should have failed to invoke callTheNativeMethod [2]");
-                    } catch (InvocationTargetException e) {
-                        // This is expected to fail since the native method has NOT been
-                        // overridden here.
-                        assertEquals(UnsatisfiedLinkError.class, e.getCause().getClass());
-                    }
-
-                    // Check that the native method does NOT have the new annotation
-                    Method[] m = clazz2.getDeclaredMethods();
-                    Method nativeInstanceMethod = null;
-                    for (Method method : m) {
-                        if ("native_instance".equals(method.getName())) {
-                            nativeInstanceMethod = method;
-                            break;
-                        }
-                    }
-                    assertNotNull(nativeInstanceMethod);
-                    assertTrue(Modifier.isNative(nativeInstanceMethod.getModifiers()));
-                    Annotation[] a = nativeInstanceMethod.getAnnotations();
-                    assertEquals(0, a.length);
-                }
-            };
-            cl2.add(NATIVE_CLASS_NAME, cw);
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    /**
-     * {@link DelegateMethodAdapter} does not support overriding constructors yet,
-     * so this should fail with an {@link UnsupportedOperationException}.
-     *
-     * Although not tested here, the message of the exception should contain the
-     * constructor signature.
-     */
-    @Test(expected=UnsupportedOperationException.class)
-    public void testConstructorsNotSupported() throws IOException {
-        ClassWriter cw = new ClassWriter(0 /*flags*/);
-
-        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
-
-        HashSet<String> delegateMethods = new HashSet<>();
-        delegateMethods.add("<init>");
-        DelegateClassAdapter cv = new DelegateClassAdapter(
-                mLog, cw, internalClassName, delegateMethods);
-
-        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
-        cr.accept(cv, 0 /* flags */);
-    }
-
-    @Test
-    public void testDelegateNative() throws Throwable {
-        ClassWriter cw = new ClassWriter(0 /*flags*/);
-        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
-
-        HashSet<String> delegateMethods = new HashSet<>();
-        delegateMethods.add(DelegateClassAdapter.ALL_NATIVES);
-        DelegateClassAdapter cv = new DelegateClassAdapter(
-                mLog, cw, internalClassName, delegateMethods);
-
-        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
-        cr.accept(cv, 0 /* flags */);
-
-        // Load the generated class in a different class loader and try it
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-                    Class<?> clazz2 = loadClass(NATIVE_CLASS_NAME);
-                    Object i2 = clazz2.newInstance();
-                    assertNotNull(i2);
-
-                    // Use reflection to access inner methods
-                    assertEquals(42, callAdd(i2, 20, 22));
-
-                     Object[] objResult = new Object[] { null };
-                     int result = callCallNativeInstance(i2, 10, 3.1415, objResult);
-                     assertEquals((int)(10 + 3.1415), result);
-                     assertSame(i2, objResult[0]);
-
-                     // Check that the native method now has the new annotation and is not native
-                     Method[] m = clazz2.getDeclaredMethods();
-                     Method nativeInstanceMethod = null;
-                     for (Method method : m) {
-                         if ("native_instance".equals(method.getName())) {
-                             nativeInstanceMethod = method;
-                             break;
-                         }
-                     }
-                     assertNotNull(nativeInstanceMethod);
-                     assertFalse(Modifier.isNative(nativeInstanceMethod.getModifiers()));
-                     Annotation[] a = nativeInstanceMethod.getAnnotations();
-                     assertEquals("LayoutlibDelegate", a[0].annotationType().getSimpleName());
-                }
-            };
-            cl2.add(NATIVE_CLASS_NAME, cw);
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    @Test
-    public void testDelegateInner() throws Throwable {
-        // We'll delegate the "get" method of both the inner and outer class.
-        HashSet<String> delegateMethods = new HashSet<>();
-        delegateMethods.add("get");
-        delegateMethods.add("privateMethod");
-
-        // Generate the delegate for the outer class.
-        ClassWriter cwOuter = new ClassWriter(0 /*flags*/);
-        String outerClassName = OUTER_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cvOuter = new DelegateClassAdapter(
-                mLog, cwOuter, outerClassName, delegateMethods);
-        ClassReader cr = new ClassReader(OUTER_CLASS_NAME);
-        cr.accept(cvOuter, 0 /* flags */);
-
-        // Generate the delegate for the inner class.
-        ClassWriter cwInner = new ClassWriter(0 /*flags*/);
-        String innerClassName = INNER_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cvInner = new DelegateClassAdapter(
-                mLog, cwInner, innerClassName, delegateMethods);
-        cr = new ClassReader(INNER_CLASS_NAME);
-        cr.accept(cvInner, 0 /* flags */);
-
-        // Load the generated classes in a different class loader and try them
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-
-                    // Check the outer class
-                    Class<?> outerClazz2 = loadClass(OUTER_CLASS_NAME);
-                    Object o2 = outerClazz2.newInstance();
-                    assertNotNull(o2);
-
-                    // The original Outer.get returns 1+10+20,
-                    // but the delegate makes it return 4+10+20
-                    assertEquals(4+10+20, callGet(o2, 10, 20));
-                    assertEquals(1+10+20, callGet_Original(o2, 10, 20));
-
-                    // The original Outer has a private method,
-                    // so by default we can't access it.
-                    boolean gotIllegalAccessException = false;
-                    try {
-                         callMethod(o2, "privateMethod", false /*makePublic*/);
-                    } catch(IllegalAccessException e) {
-                        gotIllegalAccessException = true;
-                    }
-                    assertTrue(gotIllegalAccessException);
-
-                    // The private method from original Outer has been
-                    // delegated. The delegate generated should have the
-                    // same access.
-                    gotIllegalAccessException = false;
-                    try {
-                        assertEquals("outerPrivateMethod",
-                                callMethod(o2, "privateMethod_Original", false /*makePublic*/));
-                    } catch (IllegalAccessException e) {
-                        gotIllegalAccessException = true;
-                    }
-                    assertTrue(gotIllegalAccessException);
-
-                    // Check the inner class. Since it's not a static inner class, we need
-                    // to use the hidden constructor that takes the outer class as first parameter.
-                    Class<?> innerClazz2 = loadClass(INNER_CLASS_NAME);
-                    Constructor<?> innerCons = innerClazz2.getConstructor(outerClazz2);
-                    Object i2 = innerCons.newInstance(o2);
-                    assertNotNull(i2);
-
-                    // The original Inner.get returns 3+10+20,
-                    // but the delegate makes it return 6+10+20
-                    assertEquals(6+10+20, callGet(i2, 10, 20));
-                    assertEquals(3+10+20, callGet_Original(i2, 10, 20));
-                }
-            };
-            cl2.add(OUTER_CLASS_NAME, cwOuter.toByteArray());
-            cl2.add(INNER_CLASS_NAME, cwInner.toByteArray());
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    @Test
-    public void testDelegateStaticInner() throws Throwable {
-        // We'll delegate the "get" method of both the inner and outer class.
-        HashSet<String> delegateMethods = new HashSet<>();
-        delegateMethods.add("get");
-
-        // Generate the delegate for the outer class.
-        ClassWriter cwOuter = new ClassWriter(0 /*flags*/);
-        String outerClassName = OUTER_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cvOuter = new DelegateClassAdapter(
-                mLog, cwOuter, outerClassName, delegateMethods);
-        ClassReader cr = new ClassReader(OUTER_CLASS_NAME);
-        cr.accept(cvOuter, 0 /* flags */);
-
-        // Generate the delegate for the static inner class.
-        ClassWriter cwInner = new ClassWriter(0 /*flags*/);
-        String innerClassName = STATIC_INNER_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cvInner = new DelegateClassAdapter(
-                mLog, cwInner, innerClassName, delegateMethods);
-        cr = new ClassReader(STATIC_INNER_CLASS_NAME);
-        cr.accept(cvInner, 0 /* flags */);
-
-        // Load the generated classes in a different class loader and try them
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-
-                    // Check the outer class
-                    Class<?> outerClazz2 = loadClass(OUTER_CLASS_NAME);
-                    Object o2 = outerClazz2.newInstance();
-                    assertNotNull(o2);
-
-                    // Check the inner class. Since it's not a static inner class, we need
-                    // to use the hidden constructor that takes the outer class as first parameter.
-                    Class<?> innerClazz2 = loadClass(STATIC_INNER_CLASS_NAME);
-                    Constructor<?> innerCons = innerClazz2.getConstructor();
-                    Object i2 = innerCons.newInstance();
-                    assertNotNull(i2);
-
-                    // The original StaticInner.get returns 100+10+20,
-                    // but the delegate makes it return 6+10+20
-                    assertEquals(6+10+20, callGet(i2, 10, 20));
-                    assertEquals(100+10+20, callGet_Original(i2, 10, 20));
-                }
-            };
-            cl2.add(OUTER_CLASS_NAME, cwOuter.toByteArray());
-            cl2.add(STATIC_INNER_CLASS_NAME, cwInner.toByteArray());
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    //-------
-
-    /**
-     * A class loader than can define and instantiate our modified classes.
-     * <p/>
-     * The trick here is that this class loader will test our <em>modified</em> version
-     * of the classes, the one with the delegate calls.
-     * <p/>
-     * Trying to do so in the original class loader generates all sort of link issues because
-     * there are 2 different definitions of the same class name. This class loader will
-     * define and load the class when requested by name and provide helpers to access the
-     * instance methods via reflection.
-     */
-    private abstract class ClassLoader2 extends ClassLoader {
-
-        private final Map<String, byte[]> mClassDefs = new HashMap<>();
-
-        public ClassLoader2() {
-            super(null);
-        }
-
-        public ClassLoader2 add(String className, byte[] definition) {
-            mClassDefs.put(className, definition);
-            return this;
-        }
-
-        public ClassLoader2 add(String className, ClassWriter rewrittenClass) {
-            mClassDefs.put(className, rewrittenClass.toByteArray());
-            return this;
-        }
-
-        private Set<Entry<String, byte[]>> getByteCode() {
-            return mClassDefs.entrySet();
-        }
-
-        @SuppressWarnings("unused")
-        @Override
-        protected Class<?> findClass(String name) throws ClassNotFoundException {
-            try {
-                return super.findClass(name);
-            } catch (ClassNotFoundException e) {
-
-                byte[] def = mClassDefs.get(name);
-                if (def != null) {
-                    // Load the modified ClassWithNative from its bytes representation.
-                    return defineClass(name, def, 0, def.length);
-                }
-
-                try {
-                    // Load everything else from the original definition into the new class loader.
-                    ClassReader cr = new ClassReader(name);
-                    ClassWriter cw = new ClassWriter(0);
-                    cr.accept(cw, 0);
-                    byte[] bytes = cw.toByteArray();
-                    return defineClass(name, bytes, 0, bytes.length);
-
-                } catch (IOException ioe) {
-                    throw new RuntimeException(ioe);
-                }
-            }
-        }
-
-        /**
-         * Accesses {@link OuterClass#get} or {@link InnerClass#get}via reflection.
-         */
-        public int callGet(Object instance, int a, long b) throws Exception {
-            Method m = instance.getClass().getMethod("get",
-                    int.class, long.class);
-
-            Object result = m.invoke(instance, a, b);
-            return (Integer) result;
-        }
-
-        /**
-         * Accesses the "_Original" methods for {@link OuterClass#get}
-         * or {@link InnerClass#get}via reflection.
-         */
-        public int callGet_Original(Object instance, int a, long b) throws Exception {
-            Method m = instance.getClass().getMethod("get_Original",
-                    int.class, long.class);
-
-            Object result = m.invoke(instance, a, b);
-            return (Integer) result;
-        }
-
-        /**
-         * Accesses the any declared method that takes no parameter via reflection.
-         */
-        @SuppressWarnings("unchecked")
-        public <T> T callMethod(Object instance, String methodName, boolean makePublic) throws Exception {
-            Method m = instance.getClass().getDeclaredMethod(methodName, (Class<?>[])null);
-
-            boolean wasAccessible = m.isAccessible();
-            if (makePublic && !wasAccessible) {
-                m.setAccessible(true);
-            }
-
-            Object result = m.invoke(instance, (Object[])null);
-
-            if (makePublic && !wasAccessible) {
-                m.setAccessible(false);
-            }
-
-            return (T) result;
-        }
-
-        /**
-         * Accesses {@link ClassWithNative#add(int, int)} via reflection.
-         */
-        public int callAdd(Object instance, int a, int b) throws Exception {
-            Method m = instance.getClass().getMethod("add",
-                    int.class, int.class);
-
-            Object result = m.invoke(instance, a, b);
-            return (Integer) result;
-        }
-
-        /**
-         * Accesses {@link ClassWithNative#callNativeInstance(int, double, Object[])}
-         * via reflection.
-         */
-        public int callCallNativeInstance(Object instance, int a, double d, Object[] o)
-                throws Exception {
-            Method m = instance.getClass().getMethod("callNativeInstance",
-                    int.class, double.class, Object[].class);
-
-            Object result = m.invoke(instance, a, d, o);
-            return (Integer) result;
-        }
-
-        public abstract void testModifiedInstance() throws Exception;
-    }
-
-    /**
-     * For debugging, it's useful to dump the content of the generated classes
-     * along with the exception that was generated.
-     *
-     * However to make it work you need to pull in the org.objectweb.asm.util.TraceClassVisitor
-     * class and associated utilities which are found in the ASM source jar. Since we don't
-     * want that dependency in the source code, we only put it manually for development and
-     * access the TraceClassVisitor via reflection if present.
-     *
-     * @param t The exception thrown by {@link ClassLoader2#testModifiedInstance()}
-     * @param cl2 The {@link ClassLoader2} instance with the generated bytecode.
-     * @return Either original {@code t} or a new wrapper {@link Throwable}
-     */
-    private Throwable dumpGeneratedClass(Throwable t, ClassLoader2 cl2) {
-        try {
-            // For debugging, dump the bytecode of the class in case of unexpected error
-            // if we can find the TraceClassVisitor class.
-            Class<?> tcvClass = Class.forName("org.objectweb.asm.util.TraceClassVisitor");
-
-            StringBuilder sb = new StringBuilder();
-            sb.append('\n').append(t.getClass().getCanonicalName());
-            if (t.getMessage() != null) {
-                sb.append(": ").append(t.getMessage());
-              }
-
-            for (Entry<String, byte[]> entry : cl2.getByteCode()) {
-                String className = entry.getKey();
-                byte[] bytes = entry.getValue();
-
-                StringWriter sw = new StringWriter();
-                PrintWriter pw = new PrintWriter(sw);
-                // next 2 lines do: TraceClassVisitor tcv = new TraceClassVisitor(pw);
-                Constructor<?> cons = tcvClass.getConstructor(pw.getClass());
-                Object tcv = cons.newInstance(pw);
-                ClassReader cr2 = new ClassReader(bytes);
-                cr2.accept((ClassVisitor) tcv, 0 /* flags */);
-
-                sb.append("\nBytecode dump: <").append(className).append(">:\n")
-                  .append(sw.toString());
-            }
-
-            // Re-throw exception with new message
-            return new RuntimeException(sb.toString(), t);
-        } catch (Throwable ignore) {
-            // In case of problem, just throw the original exception as-is.
-            return t;
-        }
-    }
-
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java
deleted file mode 100644
index 1a5f653..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import static org.junit.Assert.*;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class LogTest {
-
-    private MockLog mLog;
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        // pass
-    }
-
-    @Test
-    public void testDebug() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        mLog.setVerbose(false);
-        mLog.debug("Test %d", 42);
-        assertEquals("", mLog.getOut());
-
-        mLog.setVerbose(true);
-        mLog.debug("Test %d", 42);
-
-        assertEquals("Test 42\n", mLog.getOut());
-        assertEquals("", mLog.getErr());
-    }
-
-    @Test
-    public void testInfo() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        mLog.info("Test %d", 43);
-
-        assertEquals("Test 43\n", mLog.getOut());
-        assertEquals("", mLog.getErr());
-    }
-
-    @Test
-    public void testError() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        mLog.error("Test %d", 44);
-
-        assertEquals("", mLog.getOut());
-        assertEquals("Test 44\n", mLog.getErr());
-    }
-
-    @Test
-    public void testException() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        Exception e = new Exception("My Exception");
-        mLog.exception(e, "Test %d", 44);
-
-        assertEquals("", mLog.getOut());
-        assertTrue(mLog.getErr().startsWith("Test 44\njava.lang.Exception: My Exception"));
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java
deleted file mode 100644
index de750a3..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-
-public class MockLog extends Log {
-    StringBuilder mOut = new StringBuilder();
-    StringBuilder mErr = new StringBuilder();
-
-    public String getOut() {
-        return mOut.toString();
-    }
-
-    public String getErr() {
-        return mErr.toString();
-    }
-
-    @Override
-    protected void outPrintln(String msg) {
-        mOut.append(msg);
-        mOut.append('\n');
-    }
-
-    @Override
-    protected void errPrintln(String msg) {
-        mErr.append(msg);
-        mErr.append('\n');
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java
deleted file mode 100644
index eeb0b10..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java
+++ /dev/null
@@ -1,170 +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.tools.layoutlib.create;
-
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Opcodes;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.StringJoiner;
-
-import static org.junit.Assert.assertTrue;
-
-/**
- * {@link ClassVisitor} that logs all the calls to the different visit methods so they can be later
- * inspected.
- */
-class LoggingClassVisitor extends ClassVisitor {
-    List<String> mLog = new LinkedList<String>();
-
-    public LoggingClassVisitor() {
-        super(Main.ASM_VERSION);
-    }
-
-    public LoggingClassVisitor(ClassVisitor cv) {
-        super(Main.ASM_VERSION, cv);
-    }
-
-    private static String formatAccess(int access) {
-        StringJoiner modifiers = new StringJoiner(",");
-
-        if ((access & Opcodes.ACC_PUBLIC) != 0) {
-            modifiers.add("public");
-        }
-        if ((access & Opcodes.ACC_PRIVATE) != 0) {
-            modifiers.add("private");
-        }
-        if ((access & Opcodes.ACC_PROTECTED) != 0) {
-            modifiers.add("protected");
-        }
-        if ((access & Opcodes.ACC_STATIC) != 0) {
-            modifiers.add("static");
-        }
-        if ((access & Opcodes.ACC_FINAL) != 0) {
-            modifiers.add("static");
-        }
-
-        return "[" + modifiers.toString() + "]";
-    }
-
-    private void log(String method, String format, Object...args) {
-        mLog.add(
-                String.format("[%s] - %s", method, String.format(format, (Object[]) args))
-        );
-    }
-
-    @Override
-    public void visitOuterClass(String owner, String name, String desc) {
-        log(
-                "visitOuterClass",
-                "owner=%s, name=%s, desc=%s",
-                owner, name, desc
-        );
-
-        super.visitOuterClass(owner, name, desc);
-    }
-
-    @Override
-    public void visitInnerClass(String name, String outerName, String innerName, int access) {
-        log(
-                "visitInnerClass",
-                "name=%s, outerName=%s, innerName=%s, access=%s",
-                name, outerName, innerName, formatAccess(access)
-        );
-
-        super.visitInnerClass(name, outerName, innerName, access);
-    }
-
-    @Override
-    public void visit(int version, int access, String name, String signature, String superName,
-            String[] interfaces) {
-        log(
-                "visit",
-                "version=%d, access=%s, name=%s, signature=%s, superName=%s, interfaces=%s",
-                version, formatAccess(access), name, signature, superName, Arrays.toString(interfaces)
-        );
-
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-}
-
-class PackageProtectedClass {}
-
-public class PromoteClassClassAdapterTest {
-    private static class PrivateClass {}
-    private static class ClassWithPrivateInnerClass {
-        private class InnerPrivateClass {}
-    }
-
-    @Test
-    public void testInnerClassPromotion() throws IOException {
-        ClassReader reader = new ClassReader(PrivateClass.class.getName());
-        LoggingClassVisitor log = new LoggingClassVisitor();
-
-        PromoteClassClassAdapter adapter = new PromoteClassClassAdapter(log, new HashSet<String>() {
-            {
-                add("com.android.tools.layoutlib.create.PromoteClassClassAdapterTest$PrivateClass");
-                add("com.android.tools.layoutlib.create" +
-                        ".PromoteClassClassAdapterTest$ClassWithPrivateInnerClass$InnerPrivateClass");
-            }
-        });
-        reader.accept(adapter, 0);
-        assertTrue(log.mLog.contains(
-                "[visitInnerClass] - " +
-                        "name=com/android/tools/layoutlib/create" +
-                        "/PromoteClassClassAdapterTest$PrivateClass, " +
-                        "outerName=com/android/tools/layoutlib/create" +
-                        "/PromoteClassClassAdapterTest, innerName=PrivateClass, access=[public,static]"));
-
-        // Test inner of inner class
-        log.mLog.clear();
-        reader = new ClassReader(ClassWithPrivateInnerClass.class.getName());
-        reader.accept(adapter, 0);
-
-        assertTrue(log.mLog.contains("[visitInnerClass] - " +
-                "name=com/android/tools/layoutlib/create" +
-                "/PromoteClassClassAdapterTest$ClassWithPrivateInnerClass$InnerPrivateClass, " +
-                "outerName=com/android/tools/layoutlib/create" +
-                "/PromoteClassClassAdapterTest$ClassWithPrivateInnerClass, " +
-                "innerName=InnerPrivateClass, access=[public]"));
-
-    }
-
-    @Test
-    public void testProtectedClassPromotion() throws IOException {
-        ClassReader reader = new ClassReader(PackageProtectedClass.class.getName());
-        LoggingClassVisitor log = new LoggingClassVisitor();
-
-        PromoteClassClassAdapter adapter = new PromoteClassClassAdapter(log, new HashSet<String>() {
-            {
-                add("com.android.tools.layoutlib.create.PackageProtectedClass");
-            }
-        });
-
-        reader.accept(adapter, 0);
-        assertTrue(log.mLog.contains("[visit] - version=52, access=[public], " +
-                "name=com/android/tools/layoutlib/create/PackageProtectedClass, signature=null, " +
-                "superName=java/lang/Object, interfaces=[]"));
-
-    }
-}
\ No newline at end of file
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java
deleted file mode 100644
index 6211e73..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package com.android.tools.layoutlib.create;
-
-import static org.junit.Assert.*;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- *
- */
-public class RenameClassAdapterTest {
-
-    private RenameClassAdapter mOuter;
-    private RenameClassAdapter mInner;
-
-    @Before
-    public void setUp() throws Exception {
-        mOuter = new RenameClassAdapter(null, // cv
-                                         "com.pack.Old",
-                                         "org.blah.New");
-
-        mInner = new RenameClassAdapter(null, // cv
-                                         "com.pack.Old$Inner",
-                                         "org.blah.New$Inner");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-    }
-
-    /**
-     * Renames a type, e.g. "Lcom.package.My;"
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     */
-    @Test
-    public void testRenameTypeDesc() {
-
-        // primitive types are left untouched
-        assertEquals("I", mOuter.renameTypeDesc("I"));
-        assertEquals("D", mOuter.renameTypeDesc("D"));
-        assertEquals("V", mOuter.renameTypeDesc("V"));
-
-        // object types that need no renaming are left untouched
-        assertEquals("Lcom.package.MyClass;", mOuter.renameTypeDesc("Lcom.package.MyClass;"));
-        assertEquals("Lcom.package.MyClass;", mInner.renameTypeDesc("Lcom.package.MyClass;"));
-
-        // object types that match the requirements
-        assertEquals("Lorg.blah.New;", mOuter.renameTypeDesc("Lcom.pack.Old;"));
-        assertEquals("Lorg.blah.New$Inner;", mInner.renameTypeDesc("Lcom.pack.Old$Inner;"));
-        // inner classes match the base type which is being renamed
-        assertEquals("Lorg.blah.New$Other;", mOuter.renameTypeDesc("Lcom.pack.Old$Other;"));
-        assertEquals("Lorg.blah.New$Other;", mInner.renameTypeDesc("Lcom.pack.Old$Other;"));
-
-        // arrays
-        assertEquals("[Lorg.blah.New;",  mOuter.renameTypeDesc("[Lcom.pack.Old;"));
-        assertEquals("[[Lorg.blah.New;", mOuter.renameTypeDesc("[[Lcom.pack.Old;"));
-
-        assertEquals("[Lorg.blah.New;",  mInner.renameTypeDesc("[Lcom.pack.Old;"));
-        assertEquals("[[Lorg.blah.New;", mInner.renameTypeDesc("[[Lcom.pack.Old;"));
-    }
-
-    /**
-     * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
-     * object element, e.g. "[Lcom.package.MyClass;"
-     * If the type doesn't need to be renamed, returns the internal name of the input type.
-     */
-    @Test
-    public void testRenameType() {
-        // Skip. This is actually tested by testRenameTypeDesc above.
-    }
-
-    /**
-     * Renames an internal type name, e.g. "com.package.MyClass".
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     */
-    @Test
-    public void testRenameInternalType() {
-        // an actual FQCN
-        assertEquals("org.blah.New", mOuter.renameInternalType("com.pack.Old"));
-        assertEquals("org.blah.New$Inner", mOuter.renameInternalType("com.pack.Old$Inner"));
-
-        assertEquals("org.blah.New$Other", mInner.renameInternalType("com.pack.Old$Other"));
-        assertEquals("org.blah.New$Other", mInner.renameInternalType("com.pack.Old$Other"));
-    }
-
-    /**
-     * Renames a method descriptor, i.e. applies renameType to all arguments and to the
-     * return value.
-     */
-    @Test
-    public void testRenameMethodDesc() {
-        assertEquals("(IDLorg.blah.New;[Lorg.blah.New$Inner;)Lorg.blah.New$Other;",
-               mOuter.renameMethodDesc("(IDLcom.pack.Old;[Lcom.pack.Old$Inner;)Lcom.pack.Old$Other;"));
-    }
-
-
-
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/StubMethodAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/StubMethodAdapterTest.java
deleted file mode 100644
index 3db3e23..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/StubMethodAdapterTest.java
+++ /dev/null
@@ -1,132 +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.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.create.dataclass.StubClass;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.lang.reflect.Method;
-import java.util.function.BiPredicate;
-import java.util.function.Consumer;
-
-import static org.junit.Assert.*;
-
-public class StubMethodAdapterTest {
-
-    private static final String STUB_CLASS_NAME = StubClass.class.getName();
-
-    /**
-     * Load a dummy class, stub one of its method and ensure that the modified class works as
-     * intended.
-     */
-    @Test
-    public void testBoolean() throws Exception {
-        final String methodName = "returnTrue";
-        // First don't change the method and assert that it returns true
-        testBoolean((name, type) -> false, Assert::assertTrue, methodName);
-        // Change the method now and assert that it returns false.
-        testBoolean((name, type) -> methodName.equals(name) &&
-                Type.BOOLEAN_TYPE.equals(type.getReturnType()), Assert::assertFalse, methodName);
-    }
-
-    /**
-     * @param methodPredicate tests if the method should be replaced
-     */
-    private void testBoolean(BiPredicate<String, Type> methodPredicate, Consumer<Boolean> assertion,
-            String methodName) throws Exception {
-        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
-        // Always rename the class to avoid conflict with the original class.
-        String newClassName = STUB_CLASS_NAME + '_';
-        new ClassReader(STUB_CLASS_NAME).accept(
-                new ClassAdapter(newClassName, writer, methodPredicate), 0);
-        MyClassLoader myClassLoader = new MyClassLoader(newClassName, writer.toByteArray());
-        Class<?> aClass = myClassLoader.loadClass(newClassName);
-        assertTrue("StubClass not loaded by the classloader. Likely a bug in the test.",
-                myClassLoader.findClassCalled);
-        Method method = aClass.getMethod(methodName);
-        Object o = aClass.newInstance();
-        assertion.accept((Boolean) method.invoke(o));
-    }
-
-    private static class ClassAdapter extends ClassVisitor {
-
-        private final String mClassName;
-        private final BiPredicate<String, Type> mMethodPredicate;
-
-        private ClassAdapter(String className, ClassVisitor cv,
-                BiPredicate<String, Type> methodPredicate) {
-            super(Main.ASM_VERSION, cv);
-            mClassName = className.replace('.', '/');
-            mMethodPredicate = methodPredicate;
-        }
-
-        @Override
-        public void visit(int version, int access, String name, String signature, String superName,
-                String[] interfaces) {
-            super.visit(version, access, mClassName, signature, superName,
-                    interfaces);
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
-                String[] exceptions) {
-            // Copied partly from
-            // com.android.tools.layoutlib.create.DelegateClassAdapter.visitMethod()
-            // but not generating the _Original method.
-            boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
-            boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
-            MethodVisitor originalMethod =
-                    super.visitMethod(access, name, desc, signature, exceptions);
-            Type descriptor = Type.getMethodType(desc);
-            if (mMethodPredicate.test(name, descriptor)) {
-                String methodSignature = mClassName + "#" + name;
-                String invokeSignature = methodSignature + desc;
-                return new StubMethodAdapter(originalMethod, name, descriptor.getReturnType(),
-                        invokeSignature, isStatic, isNative);
-            }
-            return originalMethod;
-        }
-    }
-
-    private static class MyClassLoader extends ClassLoader {
-        private final String mName;
-        private final byte[] mBytes;
-        private boolean findClassCalled;
-
-        private MyClassLoader(String name, byte[] bytes) {
-            mName = name;
-            mBytes = bytes;
-        }
-
-        @Override
-        protected Class<?> findClass(String name) throws ClassNotFoundException {
-            if (name.equals(mName)) {
-                findClassCalled = true;
-                return defineClass(name, mBytes, 0, mBytes.length);
-            }
-            return super.findClass(name);
-        }
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java
deleted file mode 100644
index c314853..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * Dummy test class with a native method.
- * The native method is not defined and any attempt to invoke it will
- * throw an {@link UnsatisfiedLinkError}.
- *
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class ClassWithNative {
-    public ClassWithNative() {
-    }
-
-    public int add(int a, int b) {
-        return a + b;
-    }
-
-    // Note: it's good to have a long or double for testing parameters since they take
-    // 2 slots in the stack/locals maps.
-
-    public int callNativeInstance(int a, double d, Object[] o) {
-        return native_instance(a, d, o);
-    }
-
-    private native int native_instance(int a, double d, Object[] o);
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java
deleted file mode 100644
index a3d4dc6..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * The delegate that receives the call to {@link ClassWithNative_Delegate}'s overridden methods.
- *
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class ClassWithNative_Delegate {
-    public static int native_instance(ClassWithNative instance, int a, double d, Object[] o) {
-        if (o != null && o.length > 0) {
-            o[0] = instance;
-        }
-        return (int)(a + d);
-    }
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java
deleted file mode 100644
index 9b5a918..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-public final class JavaClass {
-
-    public static final String test = "test";
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java
deleted file mode 100644
index 6dfb816..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java
+++ /dev/null
@@ -1,63 +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.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * Test class with an inner class.
- *
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass {
-    private int mOuterValue = 1;
-    public OuterClass() {
-    }
-
-    // Outer.get returns 1 + a + b
-    // Note: it's good to have a long or double for testing parameters since they take
-    // 2 slots in the stack/locals maps.
-    public int get(int a, long b) {
-        return mOuterValue + a + (int) b;
-    }
-
-    public class InnerClass {
-        public InnerClass() {
-        }
-
-        // Inner.get returns 2 + 1 + a + b
-        public int get(int a, long b) {
-            return 2 + mOuterValue + a + (int) b;
-        }
-    }
-
-    public static class StaticInnerClass {
-        public StaticInnerClass() {
-        }
-
-        // StaticInnerClass.get returns 100 + a + b
-        public int get(int a, long b) {
-            return 100 + a + (int) b;
-        }
-    }
-
-    @SuppressWarnings("unused")
-    private String privateMethod() {
-        return "outerPrivateMethod";
-    }
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java
deleted file mode 100644
index 774be8e..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java
+++ /dev/null
@@ -1,34 +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.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass_Delegate {
-    // The delegate override of Outer.get returns 4 + a + b
-    public static int get(OuterClass instance, int a, long b) {
-        return 4 + a + (int) b;
-    }
-
-    public static String privateMethod(OuterClass instance) {
-        return "outerPrivate_Delegate";
-    }
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java
deleted file mode 100644
index b472220..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java
+++ /dev/null
@@ -1,30 +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.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-import com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass;
-
-/**
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass_InnerClass_Delegate {
-    // The delegate override of Inner.get return 6 + a + b
-    public static int get(OuterClass outer, InnerClass inner, int a, long b) {
-        return 6 + a + (int) b;
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_StaticInnerClass_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_StaticInnerClass_Delegate.java
deleted file mode 100644
index a29439e..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_StaticInnerClass_Delegate.java
+++ /dev/null
@@ -1,30 +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.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-import com.android.tools.layoutlib.create.dataclass.OuterClass.StaticInnerClass;
-
-/**
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass_StaticInnerClass_Delegate {
-    // The delegate override of Inner.get return 6 + a + b
-    public static int get(StaticInnerClass inner, int a, long b) {
-        return 6 + a + (int) b;
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/StubClass.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/StubClass.java
deleted file mode 100644
index 3ae8e47..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/StubClass.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.StubMethodAdapterTest;
-
-/**
- * Used by {@link StubMethodAdapterTest}
- */
-@SuppressWarnings("unused")
-public class StubClass {
-
-    public boolean returnTrue() {
-        return true;
-    }
-}
diff --git a/tools/layoutlib/create/tests/data/mock_android.jar b/tools/layoutlib/create/tests/data/mock_android.jar
deleted file mode 100644
index c6ca3c4..0000000
--- a/tools/layoutlib/create/tests/data/mock_android.jar
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java b/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java
deleted file mode 100644
index 59612e9..0000000
--- a/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-public class JavaClass {
-
-    public static String test = "test";
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/data/anotherDataFile b/tools/layoutlib/create/tests/mock_data/mock_android/data/anotherDataFile
deleted file mode 100644
index ab29fbe..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/data/anotherDataFile
+++ /dev/null
@@ -1 +0,0 @@
-A simple data file that should *not* be copied to the output jar.
\ No newline at end of file
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/data/dataFile b/tools/layoutlib/create/tests/mock_data/mock_android/data/dataFile
deleted file mode 100644
index 9b01893..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/data/dataFile
+++ /dev/null
@@ -1 +0,0 @@
-A simple data file that should be copied to the output jar unchanged.
\ No newline at end of file
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/dummy/InnerTest.java b/tools/layoutlib/create/tests/mock_data/mock_android/dummy/InnerTest.java
deleted file mode 100644
index d3a1d05..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/dummy/InnerTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.dummy;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-public class InnerTest {
-
-    private int mSomeField;
-    private MyStaticInnerClass mInnerInstance;
-    private MyIntEnum mTheIntEnum;
-    private MyGenerics1<int[][], InnerTest, MyIntEnum, float[]> mGeneric1;
-
-    public class NotStaticInner2 extends NotStaticInner1 {
-
-    }
-
-    public class NotStaticInner1 {
-
-        public void someThing() {
-            mSomeField = 2;
-            mInnerInstance = null;
-        }
-
-    }
-
-    private static class MyStaticInnerClass {
-
-    }
-    
-    private static class DerivingClass extends InnerTest {
-        
-    }
-    
-    // enums are a kind of inner static class
-    public enum MyIntEnum {
-        VALUE0(0),
-        VALUE1(1),
-        VALUE2(2);
-
-        MyIntEnum(int myInt) {
-            this.myInt = myInt;
-        }
-        final int myInt;
-    }
-    
-    public static class MyGenerics1<T, U, V, W> {
-        public MyGenerics1() {
-            int a = 1;
-        }
-    }
-    
-    public <X> void genericMethod1(X a, X[] b) {
-    }
-
-    public <X, Y> void genericMethod2(X a, List<Y> b) {
-    }
-
-    public <X, Y extends InnerTest> void genericMethod3(X a, List<Y> b) {
-    }
-
-    public <T extends InnerTest> void genericMethod4(T[] a, Collection<T> b, Collection<?> c) {
-        Iterator<T> i = b.iterator();
-    }
-
-    public void someMethod(InnerTest self) {
-        mSomeField = self.mSomeField;
-        MyStaticInnerClass m = new MyStaticInnerClass();
-        mInnerInstance = m;
-        mTheIntEnum = null;
-        mGeneric1 = new MyGenerics1();
-        genericMethod4(new DerivingClass[0], new ArrayList<DerivingClass>(), new ArrayList<InnerTest>());
-    }
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/util/EmptyArray.java b/tools/layoutlib/create/tests/mock_data/mock_android/util/EmptyArray.java
deleted file mode 100644
index aaeebf6..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/util/EmptyArray.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.util;
-
-import java.lang.JavaClass;
-
-public class EmptyArray {
-
-        public static final Object[] OBJECT = new Object[0];
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/view/View.java b/tools/layoutlib/create/tests/mock_data/mock_android/view/View.java
deleted file mode 100644
index 84ec8a9..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/view/View.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.view;
-
-import java.lang.JavaClass;
-
-public class View {
-
-        String x = JavaClass.test;
-
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/view/ViewGroup.java b/tools/layoutlib/create/tests/mock_data/mock_android/view/ViewGroup.java
deleted file mode 100644
index 466470f..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/view/ViewGroup.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.view;
-
-public class ViewGroup extends View {
-
-    public class MarginLayoutParams extends LayoutParams {
-
-    }
-
-    public class LayoutParams {
-
-    }
-
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java b/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java
deleted file mode 100644
index af56c4b..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.widget;
-
-import mock_android.util.EmptyArray;
-import mock_android.view.ViewGroup;
-
-public class LinearLayout extends ViewGroup {
-
-    Object[] mObjects = EmptyArray.OBJECT;
-    public class LayoutParams extends MarginLayoutParams {
-
-    }
-
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/widget/TableLayout.java b/tools/layoutlib/create/tests/mock_data/mock_android/widget/TableLayout.java
deleted file mode 100644
index e455e7d..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/widget/TableLayout.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.widget;
-
-import mock_android.view.ViewGroup;
-
-public class TableLayout extends ViewGroup {
-
-    public class LayoutParams extends MarginLayoutParams {
-
-    }
-
-}
diff --git a/tools/layoutlib/legacy/Android.mk b/tools/layoutlib/legacy/Android.mk
deleted file mode 100644
index 5855f89..0000000
--- a/tools/layoutlib/legacy/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-LOCAL_JAVA_LIBRARIES := \
-	layoutlib_api-prebuilt
-
-LOCAL_MODULE := layoutlib-legacy
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/tools/layoutlib/legacy/legacy.iml b/tools/layoutlib/legacy/legacy.iml
deleted file mode 100644
index a167a75..0000000
--- a/tools/layoutlib/legacy/legacy.iml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/tools/layoutlib/legacy/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/legacy/src/com/android/layoutlib/bridge/Bridge.java
deleted file mode 100644
index 0cfc181..0000000
--- a/tools/layoutlib/legacy/src/com/android/layoutlib/bridge/Bridge.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.ide.common.rendering.api.SessionParams;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-
-/**
- * Legacy Bridge used in the SDK version of layoutlib
- */
-public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
-    private static final String SDK_NOT_SUPPORTED = "The SDK layoutlib version is not supported";
-    private static final Result NOT_SUPPORTED_RESULT =
-            Status.NOT_IMPLEMENTED.createResult(SDK_NOT_SUPPORTED);
-    private static BufferedImage sImage;
-
-    private static class BridgeRenderSession extends RenderSession {
-
-        @Override
-        public synchronized BufferedImage getImage() {
-            if (sImage == null) {
-                sImage = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
-                Graphics2D g = sImage.createGraphics();
-                g.clearRect(0, 0, 500, 500);
-                g.drawString(SDK_NOT_SUPPORTED, 20, 20);
-                g.dispose();
-            }
-
-            return sImage;
-        }
-
-        @Override
-        public Result render(long timeout, boolean forceMeasure) {
-            return NOT_SUPPORTED_RESULT;
-        }
-
-        @Override
-        public Result measure(long timeout) {
-            return NOT_SUPPORTED_RESULT;
-        }
-
-        @Override
-        public Result getResult() {
-            return NOT_SUPPORTED_RESULT;
-        }
-    }
-
-
-    @Override
-    public RenderSession createSession(SessionParams params) {
-        return new BridgeRenderSession();
-    }
-
-    @Override
-    public int getApiLevel() {
-        return 0;
-    }
-}
diff --git a/tools/layoutlib/rename_font/README b/tools/layoutlib/rename_font/README
deleted file mode 100644
index 600b756..0000000
--- a/tools/layoutlib/rename_font/README
+++ /dev/null
@@ -1,9 +0,0 @@
-This tool is used to rename the PS name encoded inside the ttf font that we ship
-with the SDK. There is bug in Java that returns incorrect results for
-java.awt.Font#layoutGlyphVector() if two fonts with same name but differnt
-versions are loaded. As a workaround, we rename all the fonts that we ship with
-the SDK by appending the font version to its name.
-
-
-The build_font.py copies all files from input_dir to output_dir while renaming
-the font files (*.ttf) in the process.
diff --git a/tools/layoutlib/rename_font/Roboto-Regular.ttf b/tools/layoutlib/rename_font/Roboto-Regular.ttf
deleted file mode 100644
index 7469063..0000000
--- a/tools/layoutlib/rename_font/Roboto-Regular.ttf
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/rename_font/build_font.py b/tools/layoutlib/rename_font/build_font.py
deleted file mode 100755
index 9713a4cc..0000000
--- a/tools/layoutlib/rename_font/build_font.py
+++ /dev/null
@@ -1,227 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-"""
-Rename the PS name of all fonts in the input directories and copy them to the
-output directory.
-
-Usage: build_font.py /path/to/input_fonts1/ /path/to/input_fonts2/ /path/to/output_fonts/
-
-"""
-
-import glob
-from multiprocessing import Pool
-import os
-import re
-import shutil
-import sys
-import xml.etree.ElementTree as etree
-
-# Prevent .pyc files from being created.
-sys.dont_write_bytecode = True
-
-# fontTools is available at platform/external/fonttools
-from fontTools import ttx
-
-# global variable
-dest_dir = '/tmp'
-
-
-class FontInfo(object):
-  family = None
-  style = None
-  version = None
-  ends_in_regular = False
-  fullname = None
-
-
-class InvalidFontException(Exception):
-  pass
-
-
-# These constants represent the value of nameID parameter in the namerecord for
-# different information.
-# see http://scripts.sil.org/cms/scripts/page.php?item_id=IWS-Chapter08#3054f18b
-NAMEID_FAMILY = 1
-NAMEID_STYLE = 2
-NAMEID_FULLNAME = 4
-NAMEID_VERSION = 5
-
-
-def main(argv):
-  if len(argv) < 2:
-    sys.exit('Usage: build_font.py /path/to/input_fonts/ /path/to/out/dir/')
-  for directory in argv:
-    if not os.path.isdir(directory):
-      sys.exit(directory + ' is not a valid directory')
-  global dest_dir
-  dest_dir = argv[-1]
-  src_dirs = argv[:-1]
-  cwd = os.getcwd()
-  os.chdir(dest_dir)
-  files = glob.glob('*')
-  for filename in files:
-    os.remove(filename)
-  os.chdir(cwd)
-  input_fonts = list()
-  for src_dir in src_dirs:
-    for dirname, dirnames, filenames in os.walk(src_dir):
-      for filename in filenames:
-        input_path = os.path.join(dirname, filename)
-        extension = os.path.splitext(filename)[1].lower()
-        if extension == '.ttf':
-          input_fonts.append(input_path)
-        elif extension == '.xml':
-          shutil.copy(input_path, dest_dir)
-      if '.git' in dirnames:
-        # don't go into any .git directories.
-        dirnames.remove('.git')
-  # Create as many threads as the number of CPUs
-  pool = Pool(processes=None)
-  pool.map(convert_font, input_fonts)
-
-
-def convert_font(input_path):
-  filename = os.path.basename(input_path)
-  print 'Converting font: ' + filename
-  # the path to the output file. The file name is the fontfilename.ttx
-  ttx_path = os.path.join(dest_dir, filename)
-  ttx_path = ttx_path[:-1] + 'x'
-  try:
-    # run ttx to generate an xml file in the output folder which represents all
-    # its info
-    ttx_args = ['-q', '-d', dest_dir, input_path]
-    ttx.main(ttx_args)
-    # now parse the xml file to change its PS name.
-    tree = etree.parse(ttx_path)
-    root = tree.getroot()
-    for name in root.iter('name'):
-      update_tag(name, get_font_info(name))
-    tree.write(ttx_path, xml_declaration=True, encoding='utf-8')
-    # generate the udpated font now.
-    ttx_args = ['-q', '-d', dest_dir, ttx_path]
-    ttx.main(ttx_args)
-  except InvalidFontException:
-    # In case of invalid fonts, we exit.
-    print filename + ' is not a valid font'
-    raise
-  except Exception as e:
-    print 'Error converting font: ' + filename
-    print e
-    # Some fonts are too big to be handled by the ttx library.
-    # Just copy paste them.
-    shutil.copy(input_path, dest_dir)
-  try:
-    # delete the temp ttx file is it exists.
-    os.remove(ttx_path)
-  except OSError:
-    pass
-
-
-def get_font_info(tag):
-  """ Returns a list of FontInfo representing the various sets of namerecords
-      found in the name table of the font. """
-  fonts = []
-  font = None
-  last_name_id = sys.maxint
-  for namerecord in tag.iter('namerecord'):
-    if 'nameID' in namerecord.attrib:
-      name_id = int(namerecord.attrib['nameID'])
-      # A new font should be created for each platform, encoding and language
-      # id. But, since the nameIDs are sorted, we use the easy approach of
-      # creating a new one when the nameIDs reset.
-      if name_id <= last_name_id and font is not None:
-        fonts.append(font)
-        font = None
-      last_name_id = name_id
-      if font is None:
-        font = FontInfo()
-      if name_id == NAMEID_FAMILY:
-        font.family = namerecord.text.strip()
-      if name_id == NAMEID_STYLE:
-        font.style = namerecord.text.strip()
-      if name_id == NAMEID_FULLNAME:
-        font.ends_in_regular = ends_in_regular(namerecord.text)
-        font.fullname = namerecord.text.strip()
-      if name_id == NAMEID_VERSION:
-        font.version = get_version(namerecord.text)
-  if font is not None:
-    fonts.append(font)
-  return fonts
-
-
-def update_tag(tag, fonts):
-  last_name_id = sys.maxint
-  fonts_iterator = fonts.__iter__()
-  font = None
-  for namerecord in tag.iter('namerecord'):
-    if 'nameID' in namerecord.attrib:
-      name_id = int(namerecord.attrib['nameID'])
-      if name_id <= last_name_id:
-        font = fonts_iterator.next()
-        font = update_font_name(font)
-      last_name_id = name_id
-      if name_id == NAMEID_FAMILY:
-        namerecord.text = font.family
-      if name_id == NAMEID_FULLNAME:
-        namerecord.text = font.fullname
-
-
-def update_font_name(font):
-  """ Compute the new font family name and font fullname. If the font has a
-      valid version, it's sanitized and appended to the font family name. The
-      font fullname is then created by joining the new family name and the
-      style. If the style is 'Regular', it is appended only if the original font
-      had it. """
-  if font.family is None or font.style is None:
-    raise InvalidFontException('Font doesn\'t have proper family name or style')
-  if font.version is not None:
-    new_family = font.family + font.version
-  else:
-    new_family = font.family
-  if font.style is 'Regular' and not font.ends_in_regular:
-    font.fullname = new_family
-  else:
-    font.fullname = new_family + ' ' + font.style
-  font.family = new_family
-  return font
-
-
-def ends_in_regular(string):
-  """ According to the specification, the font fullname should not end in
-      'Regular' for plain fonts. However, some fonts don't obey this rule. We
-      keep the style info, to minimize the diff. """
-  string = string.strip().split()[-1]
-  return string is 'Regular'
-
-
-def get_version(string):
-  string = string.strip()
-  # The spec says that the version string should start with "Version ". But not
-  # all fonts do. So, we return the complete string if it doesn't start with
-  # the prefix, else we return the rest of the string after sanitizing it.
-  prefix = 'Version '
-  if string.startswith(prefix):
-    string = string[len(prefix):]
-  return sanitize(string)
-
-
-def sanitize(string):
-  """ Remove non-standard chars. """
-  return re.sub(r'[^\w-]+', '', string)
-
-if __name__ == '__main__':
-  main(sys.argv[1:])
diff --git a/tools/layoutlib/rename_font/build_font_single.py b/tools/layoutlib/rename_font/build_font_single.py
deleted file mode 100755
index 4245cdc..0000000
--- a/tools/layoutlib/rename_font/build_font_single.py
+++ /dev/null
@@ -1,211 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-"""
-Rename the PS name of the input font.
-
-OpenType fonts (*.otf) are not currently supported. They are copied to the destination without renaming.
-XML files are also copied in case they are passed there by mistake.
-
-Usage: build_font_single.py /path/to/input_font.ttf /path/to/output_font.ttf
-
-"""
-
-import glob
-import os
-import re
-import shutil
-import sys
-import xml.etree.ElementTree as etree
-
-# Prevent .pyc files from being created.
-sys.dont_write_bytecode = True
-
-# fontTools is available at platform/external/fonttools
-from fontTools import ttx
-
-
-class FontInfo(object):
-  family = None
-  style = None
-  version = None
-  ends_in_regular = False
-  fullname = None
-
-
-class InvalidFontException(Exception):
-  pass
-
-
-# A constant to copy the font without modifying. This is useful when running
-# locally and speed up the time to build the SDK.
-COPY_ONLY = False
-
-# These constants represent the value of nameID parameter in the namerecord for
-# different information.
-# see http://scripts.sil.org/cms/scripts/page.php?item_id=IWS-Chapter08#3054f18b
-NAMEID_FAMILY = 1
-NAMEID_STYLE = 2
-NAMEID_FULLNAME = 4
-NAMEID_VERSION = 5
-
-# A list of extensions to process.
-EXTENSIONS = ['.ttf', '.otf', '.xml']
-
-def main(argv):
-  if len(argv) < 2:
-    print 'Incorrect usage: ' + str(argv)
-    sys.exit('Usage: build_font_single.py /path/to/input/font.ttf /path/to/out/font.ttf')
-  dest_path = argv[-1]
-  input_path = argv[0]
-  extension = os.path.splitext(input_path)[1].lower()
-  if extension in EXTENSIONS:
-    if not COPY_ONLY and extension == '.ttf':
-      convert_font(input_path, dest_path)
-      return
-    shutil.copy(input_path, dest_path)
-
-
-def convert_font(input_path, dest_path):
-  filename = os.path.basename(input_path)
-  print 'Converting font: ' + filename
-  # the path to the output file. The file name is the fontfilename.ttx
-  ttx_path = dest_path[:-1] + 'x'
-  try:
-    # run ttx to generate an xml file in the output folder which represents all
-    # its info
-    ttx_args = ['-q', '-o', ttx_path, input_path]
-    ttx.main(ttx_args)
-    # now parse the xml file to change its PS name.
-    tree = etree.parse(ttx_path)
-    root = tree.getroot()
-    for name in root.iter('name'):
-      update_tag(name, get_font_info(name))
-    tree.write(ttx_path, xml_declaration=True, encoding='utf-8')
-    # generate the udpated font now.
-    ttx_args = ['-q', '-o', dest_path, ttx_path]
-    ttx.main(ttx_args)
-  except InvalidFontException:
-    # In case of invalid fonts, we exit.
-    print filename + ' is not a valid font'
-    raise
-  except Exception as e:
-    print 'Error converting font: ' + filename
-    print e
-    # Some fonts are too big to be handled by the ttx library.
-    # Just copy paste them.
-    shutil.copy(input_path, dest_path)
-  try:
-    # delete the temp ttx file is it exists.
-    os.remove(ttx_path)
-  except OSError:
-    pass
-
-
-def get_font_info(tag):
-  """ Returns a list of FontInfo representing the various sets of namerecords
-      found in the name table of the font. """
-  fonts = []
-  font = None
-  last_name_id = sys.maxint
-  for namerecord in tag.iter('namerecord'):
-    if 'nameID' in namerecord.attrib:
-      name_id = int(namerecord.attrib['nameID'])
-      # A new font should be created for each platform, encoding and language
-      # id. But, since the nameIDs are sorted, we use the easy approach of
-      # creating a new one when the nameIDs reset.
-      if name_id <= last_name_id and font is not None:
-        fonts.append(font)
-        font = None
-      last_name_id = name_id
-      if font is None:
-        font = FontInfo()
-      if name_id == NAMEID_FAMILY:
-        font.family = namerecord.text.strip()
-      if name_id == NAMEID_STYLE:
-        font.style = namerecord.text.strip()
-      if name_id == NAMEID_FULLNAME:
-        font.ends_in_regular = ends_in_regular(namerecord.text)
-        font.fullname = namerecord.text.strip()
-      if name_id == NAMEID_VERSION:
-        font.version = get_version(namerecord.text)
-  if font is not None:
-    fonts.append(font)
-  return fonts
-
-
-def update_tag(tag, fonts):
-  last_name_id = sys.maxint
-  fonts_iterator = fonts.__iter__()
-  font = None
-  for namerecord in tag.iter('namerecord'):
-    if 'nameID' in namerecord.attrib:
-      name_id = int(namerecord.attrib['nameID'])
-      if name_id <= last_name_id:
-        font = fonts_iterator.next()
-        font = update_font_name(font)
-      last_name_id = name_id
-      if name_id == NAMEID_FAMILY:
-        namerecord.text = font.family
-      if name_id == NAMEID_FULLNAME:
-        namerecord.text = font.fullname
-
-
-def update_font_name(font):
-  """ Compute the new font family name and font fullname. If the font has a
-      valid version, it's sanitized and appended to the font family name. The
-      font fullname is then created by joining the new family name and the
-      style. If the style is 'Regular', it is appended only if the original font
-      had it. """
-  if font.family is None or font.style is None:
-    raise InvalidFontException('Font doesn\'t have proper family name or style')
-  if font.version is not None:
-    new_family = font.family + font.version
-  else:
-    new_family = font.family
-  if font.style is 'Regular' and not font.ends_in_regular:
-    font.fullname = new_family
-  else:
-    font.fullname = new_family + ' ' + font.style
-  font.family = new_family
-  return font
-
-
-def ends_in_regular(string):
-  """ According to the specification, the font fullname should not end in
-      'Regular' for plain fonts. However, some fonts don't obey this rule. We
-      keep the style info, to minimize the diff. """
-  string = string.strip().split()[-1]
-  return string is 'Regular'
-
-
-def get_version(string):
-  string = string.strip()
-  # The spec says that the version string should start with "Version ". But not
-  # all fonts do. So, we return the complete string if it doesn't start with
-  # the prefix, else we return the rest of the string after sanitizing it.
-  prefix = 'Version '
-  if string.startswith(prefix):
-    string = string[len(prefix):]
-  return sanitize(string)
-
-
-def sanitize(string):
-  """ Remove non-standard chars. """
-  return re.sub(r'[^\w-]+', '', string)
-
-if __name__ == '__main__':
-  main(sys.argv[1:])
diff --git a/tools/layoutlib/rename_font/test.py b/tools/layoutlib/rename_font/test.py
deleted file mode 100755
index 2ffddf4..0000000
--- a/tools/layoutlib/rename_font/test.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-"""Tests build_font.py by renaming a font.
-
-The test copies Roboto-Regular.ttf to a tmp directory and ask build_font.py to rename it and put in another dir.
-We then use ttx to dump the new font to its xml and check if rename was successful
-
-To test locally, use:
-PYTHONPATH="$PYTHONPATH:/path/to/android/checkout/external/fonttools/Lib" ./test.py
-"""
-
-import unittest
-import build_font
-
-from fontTools import ttx
-import os
-import xml.etree.ElementTree as etree
-import shutil
-import tempfile
-
-class MyTest(unittest.TestCase):
-  def test(self):
-    font_name = "Roboto-Regular.ttf"
-    srcdir = tempfile.mkdtemp()
-    print "srcdir: " + srcdir
-    shutil.copy(font_name, srcdir)
-    destdir = tempfile.mkdtemp()
-    print "destdir: " + destdir
-    self.assertTrue(build_font.main([srcdir, destdir]) is None)
-    out_path = os.path.join(destdir, font_name)
-    ttx.main([out_path])
-    ttx_path = out_path[:-1] + "x"
-    tree = etree.parse(ttx_path)
-    root = tree.getroot()
-    name_tag = root.find('name')
-    fonts = build_font.get_font_info(name_tag)
-    shutil.rmtree(srcdir)
-    shutil.rmtree(destdir)
-    self.assertEqual(fonts[0].family, "Roboto1200310")
-    self.assertEqual(fonts[0].fullname, "Roboto1200310 Regular")
-
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java b/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java
deleted file mode 100644
index ecf39b3..0000000
--- a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java
+++ /dev/null
@@ -1,94 +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.tools.idea.editors.theme.widgets;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * {@link ViewGroup} that wraps another view and catches any possible exceptions that the child view
- * might generate.
- * This is used by the theme editor to stop custom views from breaking the preview.
- */
-// TODO: This view is just a temporary solution that will be replaced by adding a try / catch
-// for custom views in the ClassConverter
-public class ErrorCatcher extends ViewGroup {
-    public ErrorCatcher(Context context) {
-        super(context);
-    }
-
-    public ErrorCatcher(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public ErrorCatcher(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public ErrorCatcher(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        assert getChildCount() == 1 : "ErrorCatcher can only have one child";
-
-        View child = getChildAt(0);
-        try {
-            measureChild(child, widthMeasureSpec, heightMeasureSpec);
-
-            setMeasuredDimension(resolveSize(child.getMeasuredWidth(), widthMeasureSpec),
-                    resolveSize(child.getMeasuredHeight(), heightMeasureSpec));
-        } catch (Throwable t) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to do onMeasure for view " +
-                    child.getClass().getCanonicalName(), t);
-            setMeasuredDimension(resolveSize(0, widthMeasureSpec),
-                    resolveSize(0, heightMeasureSpec));
-        }
-    }
-
-    @Override
-    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
-        try {
-            return super.drawChild(canvas, child, drawingTime);
-        } catch (Throwable t) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to draw for view " +
-                    child.getClass().getCanonicalName(), t);
-        }
-
-        return false;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        assert getChildCount() == 1 : "ErrorCatcher can only have one child";
-
-        View child = getChildAt(0);
-        try {
-            child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight());
-        } catch (Throwable e) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to do onLayout for view " +
-                    child.getClass().getCanonicalName(), e);
-        }
-    }
-}
diff --git a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/PressedButton.java b/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/PressedButton.java
deleted file mode 100644
index 4320157..0000000
--- a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/PressedButton.java
+++ /dev/null
@@ -1,31 +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.tools.idea.editors.theme.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.Button;
-
-@SuppressWarnings("unused")
-public class PressedButton extends Button {
-    public PressedButton(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        setPressed(true);
-        jumpDrawablesToCurrentState();
-    }
-}
diff --git a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java b/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java
deleted file mode 100644
index af89910..0000000
--- a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java
+++ /dev/null
@@ -1,200 +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.tools.idea.editors.theme.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * Custom layout used in the theme editor to display the component preview. It arranges the child
- * Views as a grid of cards.
- * <p/>
- * The Views are measured and the maximum width and height are used to dimension all the child
- * components. Any margin attributes from the children are ignored and only the item_margin element
- * is used.
- */
-@SuppressWarnings("unused")
-public class ThemePreviewLayout extends ViewGroup {
-    private final int mMaxColumns;
-    private final int mMaxColumnWidth;
-    private final int mMinColumnWidth;
-    private final int mItemHorizontalMargin;
-    private final int mItemVerticalMargin;
-
-    /** Item width to use for every card component. This includes margins. */
-    private int mItemWidth;
-    /** Item height to use for every card component. This includes margins. */
-    private int mItemHeight;
-
-    /** Calculated number of columns */
-    private int mNumColumns;
-
-    public ThemePreviewLayout(Context context) {
-        this(context, null);
-    }
-
-    public ThemePreviewLayout(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public ThemePreviewLayout(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-
-        if (attrs == null) {
-            mMaxColumnWidth = Integer.MAX_VALUE;
-            mMinColumnWidth = 0;
-            mMaxColumns = Integer.MAX_VALUE;
-            mItemHorizontalMargin = 0;
-            mItemVerticalMargin = 0;
-            return;
-        }
-
-        DisplayMetrics dm = getResources().getDisplayMetrics();
-        int maxColumnWidth = attrs.getAttributeIntValue(null, "max_column_width", Integer
-                .MAX_VALUE);
-        int minColumnWidth = attrs.getAttributeIntValue(null, "min_column_width", 0);
-        int itemHorizontalMargin = attrs.getAttributeIntValue(null, "item_horizontal_margin", 0);
-        int itemVerticalMargin = attrs.getAttributeIntValue(null, "item_vertical_margin", 0);
-
-        mMaxColumnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                maxColumnWidth,
-                dm);
-        mMinColumnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                minColumnWidth,
-                dm);
-        mItemHorizontalMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                itemHorizontalMargin,
-                dm);
-        mItemVerticalMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                itemVerticalMargin,
-                dm);
-        mMaxColumns = attrs.getAttributeIntValue(null, "max_columns", Integer.MAX_VALUE);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        // Measure the column size.
-        // The column has a minimum width that will be used to calculate the maximum number of
-        // columns that we can fit in the available space.
-        //
-        // Once we have the maximum number of columns, we will span all columns width evenly to fill
-        // all the available space.
-        int wSize = MeasureSpec.getSize(widthMeasureSpec) - mPaddingLeft - mPaddingRight;
-
-        // Calculate the desired width of all columns and take the maximum.
-        // This step can be skipped if we have a fixed column height so we do not have to
-        // dynamically calculate it.
-        int childWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        int childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        int itemWidth = 0;
-        int itemHeight = 0;
-        for (int i = 0; i < getChildCount(); i++) {
-            View v = getChildAt(i);
-
-            if (v.getVisibility() == GONE) {
-                continue;
-            }
-
-            measureChild(v, childWidthSpec, childHeightSpec);
-
-            itemWidth = Math.max(itemWidth, v.getMeasuredWidth());
-            itemHeight = Math.max(itemHeight, v.getMeasuredHeight());
-        }
-
-        itemWidth = Math.min(Math.max(itemWidth, mMinColumnWidth), mMaxColumnWidth);
-        mNumColumns = Math.min((int) Math.ceil((double) wSize / itemWidth), mMaxColumns);
-
-        // Check how much space this distribution would take taking into account the margins.
-        // If it's bigger than what we have, remove one column.
-        int wSizeNeeded = mNumColumns * itemWidth + (mNumColumns - 1) * mItemHorizontalMargin;
-        if (wSizeNeeded > wSize && mNumColumns > 1) {
-            mNumColumns--;
-        }
-
-        if (getChildCount() < mNumColumns) {
-            mNumColumns = getChildCount();
-        }
-        if (mNumColumns == 0) {
-            mNumColumns = 1;
-        }
-
-        // Inform each child of the measurement
-        childWidthSpec = MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY);
-        childHeightSpec = MeasureSpec.makeMeasureSpec(itemHeight, MeasureSpec.EXACTLY);
-        for (int i = 0; i < getChildCount(); i++) {
-            View v = getChildAt(i);
-
-            if (v.getVisibility() == GONE) {
-                continue;
-            }
-
-            measureChild(v, childWidthSpec, childHeightSpec);
-        }
-
-        // Calculate the height of the first column to measure our own size
-        int firstColumnItems = getChildCount() / mNumColumns + ((getChildCount() % mNumColumns) > 0
-                ? 1 : 0);
-
-        int horizontalMarginsTotalWidth = (mNumColumns - 1) * mItemHorizontalMargin;
-        int verticalMarginsTotalHeight = (firstColumnItems - 1) * mItemVerticalMargin;
-        int totalWidth = mNumColumns * itemWidth + horizontalMarginsTotalWidth +
-                mPaddingRight + mPaddingLeft;
-        int totalHeight = firstColumnItems * itemHeight + verticalMarginsTotalHeight +
-                mPaddingBottom + mPaddingTop;
-
-        setMeasuredDimension(resolveSize(totalWidth, widthMeasureSpec),
-                resolveSize(totalHeight, heightMeasureSpec));
-
-        mItemWidth = itemWidth;
-        mItemHeight = itemHeight;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        int itemsPerColumn = getChildCount() / mNumColumns;
-        // The remainder items are distributed one per column.
-        int remainderItems = getChildCount() % mNumColumns;
-
-        int x = mPaddingLeft;
-        int y = mPaddingTop;
-        int position = 1;
-        for (int i = 0; i < getChildCount(); i++) {
-            View v = getChildAt(i);
-            v.layout(x,
-                    y,
-                    x + mItemWidth,
-                    y + mItemHeight);
-
-            if (position == itemsPerColumn + (remainderItems > 0 ? 1 : 0)) {
-                // Break column
-                position = 1;
-                remainderItems--;
-                x += mItemWidth + mItemHorizontalMargin;
-                y = mPaddingTop;
-            } else {
-                position++;
-                y += mItemHeight + mItemVerticalMargin;
-            }
-        }
-    }
-}
-
-
diff --git a/tools/layoutlib/studio-custom-widgets/studio-android-widgets.iml b/tools/layoutlib/studio-custom-widgets/studio-android-widgets.iml
deleted file mode 100644
index b0363d7..0000000
--- a/tools/layoutlib/studio-custom-widgets/studio-android-widgets.iml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
-    <orderEntry type="library" name="framework.jar" level="project" />
-    <orderEntry type="module" module-name="bridge" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/tools/locked_region_code_injection/Android.bp b/tools/locked_region_code_injection/Android.bp
new file mode 100644
index 0000000..6dd6059
--- /dev/null
+++ b/tools/locked_region_code_injection/Android.bp
@@ -0,0 +1,12 @@
+java_library_host {
+    name: "lockedregioncodeinjection",
+    manifest: "manifest.txt",
+    srcs: ["src/**/*.java"],
+    static_libs: [
+        "asm-6.0",
+        "asm-commons-6.0",
+        "asm-tree-6.0",
+        "asm-analysis-6.0",
+        "guava-21.0",
+    ],
+}
diff --git a/tools/locked_region_code_injection/Android.mk b/tools/locked_region_code_injection/Android.mk
deleted file mode 100644
index d921783..0000000
--- a/tools/locked_region_code_injection/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_JAR_MANIFEST := manifest.txt
-LOCAL_MODULE := lockedregioncodeinjection
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    asm-5.2 \
-    asm-commons-5.2 \
-    asm-tree-5.2 \
-    asm-analysis-5.2 \
-    guava-20.0 \
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockFindingClassVisitor.java b/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockFindingClassVisitor.java
index 99ef8a7..ee0e36c 100644
--- a/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockFindingClassVisitor.java
+++ b/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockFindingClassVisitor.java
@@ -76,7 +76,7 @@
         private MethodVisitor chain;
 
         public LockFindingMethodVisitor(String owner, MethodNode mn, MethodVisitor chain) {
-            super(Opcodes.ASM5, mn);
+            super(Utils.ASM_VERSION, mn);
             assert owner != null;
             this.owner = owner;
             this.chain = chain;
diff --git a/tools/locked_region_code_injection/src/lockedregioncodeinjection/Utils.java b/tools/locked_region_code_injection/src/lockedregioncodeinjection/Utils.java
index d2a2e7b..219c2b3 100644
--- a/tools/locked_region_code_injection/src/lockedregioncodeinjection/Utils.java
+++ b/tools/locked_region_code_injection/src/lockedregioncodeinjection/Utils.java
@@ -19,7 +19,7 @@
 
 public class Utils {
 
-    public static final int ASM_VERSION = Opcodes.ASM5;
+    public static final int ASM_VERSION = Opcodes.ASM6;
 
     /**
      * Reads a comma separated configuration similar to the Jack definition.
diff --git a/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestMain.java b/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestMain.java
index b86954d..c408b9e 100644
--- a/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestMain.java
+++ b/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestMain.java
@@ -23,11 +23,14 @@
  * <code>
  * set -x
  *
+ * croot frameworks/base/tools/locked_region_code_injection
+ *
  * # Clean
+ * mkdir -p out
  * rm -fr out/*
  *
  * # Make booster
- * javac -cp lib/asm-all-5.2.jar src&#47;*&#47;*.java -d out/
+ * javac -cp lib/asm-6.0_BETA.jar:lib/asm-commons-6.0_BETA.jar:lib/asm-tree-6.0_BETA.jar:lib/asm-analysis-6.0_BETA.jar:lib/guava-21.0.jar src&#47;*&#47;*.java -d out/
  * pushd out
  * jar cfe lockedregioncodeinjection.jar lockedregioncodeinjection.Main *&#47;*.class
  * popd
@@ -40,7 +43,7 @@
  * popd
  *
  * # Run tool on unit tests.
- * java -ea -cp lib/asm-all-5.2.jar:out/lockedregioncodeinjection.jar \
+ * java -ea -cp lib/asm-6.0_BETA.jar:lib/asm-commons-6.0_BETA.jar:lib/asm-tree-6.0_BETA.jar:lib/asm-analysis-6.0_BETA.jar:lib/guava-21.0.jar:out/lockedregioncodeinjection.jar \
  *     lockedregioncodeinjection.Main \
  *     -i out/test_input.jar -o out/test_output.jar \
  *     --targets 'Llockedregioncodeinjection/TestTarget;' \
diff --git a/tools/obbtool/Android.bp b/tools/obbtool/Android.bp
new file mode 100644
index 0000000..f879658
--- /dev/null
+++ b/tools/obbtool/Android.bp
@@ -0,0 +1,51 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// Opaque Binary Blob (OBB) Tool
+//
+
+cc_binary_host {
+    name: "obbtool",
+
+    srcs: ["Main.cpp"],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-mismatched-tags",
+    ],
+
+    static_libs: [
+        "libandroidfw",
+        "libutils",
+        "libcutils",
+        "liblog",
+    ],
+
+    // This tool is prebuilt if we're doing an app-only build.
+    product_variables: {
+        unbundled_build: {
+            enabled: false,
+        },
+    },
+}
+
+//####################################################
+cc_binary_host {
+    name: "pbkdf2gen",
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-mismatched-tags",
+    ],
+    srcs: ["pbkdf2gen.cpp"],
+    static_libs: ["libcrypto"],
+
+    // This tool is prebuilt if we're doing an app-only build.
+    product_variables: {
+        unbundled_build: {
+            enabled: false,
+        },
+    },
+}
diff --git a/tools/obbtool/Android.mk b/tools/obbtool/Android.mk
deleted file mode 100644
index 6dc306e..0000000
--- a/tools/obbtool/Android.mk
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# Copyright 2010 The Android Open Source Project
-#
-# Opaque Binary Blob (OBB) Tool
-#
-
-# This tool is prebuilt if we're doing an app-only build.
-ifeq ($(TARGET_BUILD_APPS),)
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	Main.cpp
-
-LOCAL_CFLAGS := -Wall -Werror -Wno-mismatched-tags
-
-#LOCAL_C_INCLUDES +=
-
-LOCAL_STATIC_LIBRARIES := \
-	libandroidfw \
-	libutils \
-	libcutils \
-	liblog
-
-ifeq ($(HOST_OS),linux)
-LOCAL_LDLIBS += -ldl -lpthread
-endif
-
-LOCAL_MODULE := obbtool
-
-include $(BUILD_HOST_EXECUTABLE)
-
-#####################################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := pbkdf2gen
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := -Wall -Werror -Wno-mismatched-tags
-LOCAL_SRC_FILES := pbkdf2gen.cpp
-LOCAL_LDLIBS += -ldl
-LOCAL_STATIC_LIBRARIES := libcrypto
-
-include $(BUILD_HOST_EXECUTABLE)
-
-#######################################################
-endif # TARGET_BUILD_APPS
diff --git a/tools/split-select/Android.bp b/tools/split-select/Android.bp
new file mode 100644
index 0000000..ee822b7
--- /dev/null
+++ b/tools/split-select/Android.bp
@@ -0,0 +1,108 @@
+//
+// 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.
+//
+
+// ==========================================================
+// Setup some common variables for the different build
+// targets here.
+// ==========================================================
+
+cc_defaults {
+    name: "split-select_defaults",
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    include_dirs: ["frameworks/base/tools"],
+    static_libs: [
+        "libaapt",
+        "libandroidfw",
+        "libpng",
+        "libutils",
+        "liblog",
+        "libcutils",
+        "libexpat",
+        "libziparchive",
+        "libbase",
+        "libz",
+    ],
+    group_static_libs: true,
+
+    target: {
+        windows: {
+            enabled: true,
+        },
+    },
+
+    // This tool is prebuilt if we're doing an app-only build.
+    product_variables: {
+        pdk: {
+            enabled: false,
+        },
+        unbundled_build: {
+            enabled: false,
+        },
+    },
+}
+
+// ==========================================================
+// Build the host static library: libsplit-select
+// ==========================================================
+cc_library_host_static {
+    name: "libsplit-select",
+    defaults: ["split-select_defaults"],
+
+    srcs: [
+        "Abi.cpp",
+        "Grouper.cpp",
+        "Rule.cpp",
+        "RuleGenerator.cpp",
+        "SplitDescription.cpp",
+        "SplitSelector.cpp",
+    ],
+    cflags: ["-D_DARWIN_UNLIMITED_STREAMS"],
+
+}
+
+// ==========================================================
+// Build the host tests: libsplit-select_tests
+// ==========================================================
+cc_test_host {
+    name: "libsplit-select_tests",
+    defaults: ["split-select_defaults"],
+
+    srcs: [
+        "Grouper_test.cpp",
+        "Rule_test.cpp",
+        "RuleGenerator_test.cpp",
+        "SplitSelector_test.cpp",
+        "TestRules.cpp",
+    ],
+
+    static_libs: ["libsplit-select"],
+
+}
+
+// ==========================================================
+// Build the host executable: split-select
+// ==========================================================
+cc_binary_host {
+    name: "split-select",
+    defaults: ["split-select_defaults"],
+    srcs: ["Main.cpp"],
+
+    static_libs: ["libsplit-select"],
+}
diff --git a/tools/split-select/Android.mk b/tools/split-select/Android.mk
deleted file mode 100644
index 4a1511e..0000000
--- a/tools/split-select/Android.mk
+++ /dev/null
@@ -1,119 +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.
-#
-
-# This tool is prebuilt if we're doing an app-only build.
-ifeq ($(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)),)
-
-# ==========================================================
-# Setup some common variables for the different build
-# targets here.
-# ==========================================================
-LOCAL_PATH:= $(call my-dir)
-
-main := Main.cpp
-sources := \
-    Abi.cpp \
-    Grouper.cpp \
-    Rule.cpp \
-    RuleGenerator.cpp \
-    SplitDescription.cpp \
-    SplitSelector.cpp
-
-testSources := \
-    Grouper_test.cpp \
-    Rule_test.cpp \
-    RuleGenerator_test.cpp \
-    SplitSelector_test.cpp \
-    TestRules.cpp
-
-cIncludes := \
-    external/zlib \
-    frameworks/base/tools
-
-hostStaticLibs := \
-    libaapt \
-    libandroidfw \
-    libpng \
-    libutils \
-    liblog \
-    libcutils \
-    libexpat \
-    libziparchive \
-    libbase
-
-cFlags := -Wall -Werror
-
-hostLdLibs_linux := -lrt -ldl -lpthread
-
-# Statically link libz for MinGW (Win SDK under Linux),
-# and dynamically link for all others.
-hostStaticLibs_windows := libz
-hostLdLibs_darwin := -lz
-hostLdLibs_linux += -lz
-
-
-# ==========================================================
-# Build the host static library: libsplit-select
-# ==========================================================
-include $(CLEAR_VARS)
-LOCAL_MODULE := libsplit-select
-LOCAL_MODULE_HOST_OS := darwin linux windows
-
-LOCAL_SRC_FILES := $(sources)
-LOCAL_STATIC_LIBRARIES := $(hostStaticLibs)
-LOCAL_C_INCLUDES := $(cIncludes)
-LOCAL_CFLAGS := $(cFlags) -D_DARWIN_UNLIMITED_STREAMS
-
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-
-# ==========================================================
-# Build the host tests: libsplit-select_tests
-# ==========================================================
-include $(CLEAR_VARS)
-LOCAL_MODULE := libsplit-select_tests
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(testSources)
-
-LOCAL_C_INCLUDES := $(cIncludes)
-LOCAL_STATIC_LIBRARIES := libsplit-select $(hostStaticLibs)
-LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
-LOCAL_LDLIBS_darwin := $(hostLdLibs_darwin)
-LOCAL_LDLIBS_linux := $(hostLdLibs_linux)
-LOCAL_CFLAGS := $(cFlags)
-
-include $(BUILD_HOST_NATIVE_TEST)
-
-# ==========================================================
-# Build the host executable: split-select
-# ==========================================================
-include $(CLEAR_VARS)
-LOCAL_MODULE := split-select
-LOCAL_MODULE_HOST_OS := darwin linux windows
-
-LOCAL_SRC_FILES := $(main)
-
-LOCAL_C_INCLUDES := $(cIncludes)
-LOCAL_STATIC_LIBRARIES := libsplit-select $(hostStaticLibs)
-LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
-LOCAL_LDLIBS_darwin := $(hostLdLibs_darwin)
-LOCAL_LDLIBS_linux := $(hostLdLibs_linux)
-LOCAL_CFLAGS := $(cFlags)
-
-include $(BUILD_HOST_EXECUTABLE)
-
-endif # No TARGET_BUILD_APPS or TARGET_BUILD_PDK
diff --git a/tools/streaming_proto/Android.bp b/tools/streaming_proto/Android.bp
new file mode 100644
index 0000000..24068e9
--- /dev/null
+++ b/tools/streaming_proto/Android.bp
@@ -0,0 +1,29 @@
+//
+// 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.
+//
+
+// ==========================================================
+// Build the host executable: protoc-gen-javastream
+// ==========================================================
+cc_binary_host {
+    name: "protoc-gen-javastream",
+    srcs: [
+        "Errors.cpp",
+        "string_utils.cpp",
+        "main.cpp",
+    ],
+
+    shared_libs: ["libprotoc"],
+}
diff --git a/tools/streaming_proto/Android.mk b/tools/streaming_proto/Android.mk
index 5a54fd1..ebb77a1 100644
--- a/tools/streaming_proto/Android.mk
+++ b/tools/streaming_proto/Android.mk
@@ -16,19 +16,6 @@
 LOCAL_PATH:= $(call my-dir)
 
 # ==========================================================
-# Build the host executable: protoc-gen-javastream
-# ==========================================================
-include $(CLEAR_VARS)
-LOCAL_MODULE := protoc-gen-javastream
-LOCAL_SRC_FILES := \
-    Errors.cpp \
-    string_utils.cpp \
-    main.cpp
-LOCAL_SHARED_LIBRARIES := \
-    libprotoc
-include $(BUILD_HOST_EXECUTABLE)
-
-# ==========================================================
 # Build the java test
 # ==========================================================
 include $(CLEAR_VARS)
diff --git a/tools/validatekeymaps/Android.bp b/tools/validatekeymaps/Android.bp
new file mode 100644
index 0000000..6fb278c
--- /dev/null
+++ b/tools/validatekeymaps/Android.bp
@@ -0,0 +1,30 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// Keymap validation tool.
+//
+
+cc_binary_host {
+    name: "validatekeymaps",
+
+    srcs: ["Main.cpp"],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+    static_libs: [
+        "libinput",
+        "libutils",
+        "libcutils",
+        "liblog",
+    ],
+
+    // This tool is prebuilt if we're doing an app-only build.
+    product_variables: {
+        unbundled_build: {
+          enabled: false,
+        },
+    },
+}
diff --git a/tools/validatekeymaps/Android.mk b/tools/validatekeymaps/Android.mk
deleted file mode 100644
index 9af721d..0000000
--- a/tools/validatekeymaps/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright 2010 The Android Open Source Project
-#
-# Keymap validation tool.
-#
-
-# This tool is prebuilt if we're doing an app-only build.
-ifeq ($(TARGET_BUILD_APPS),)
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	Main.cpp
-
-LOCAL_CFLAGS := -Wall -Werror
-
-LOCAL_STATIC_LIBRARIES := \
-	libinput \
-	libutils \
-	libcutils \
-	liblog
-
-ifeq ($(HOST_OS),linux)
-LOCAL_LDLIBS += -ldl -lpthread
-endif
-
-LOCAL_MODULE := validatekeymaps
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_EXECUTABLE)
-
-endif # TARGET_BUILD_APPS
diff --git a/vr/Android.mk b/vr/Android.mk
index 5b65d3f..73e9f23 100644
--- a/vr/Android.mk
+++ b/vr/Android.mk
@@ -18,6 +18,7 @@
 LOCAL_MODULE := libdvr_loader
 LOCAL_MODULE_OWNER := google
 LOCAL_SRC_FILES := dvr_library_loader.cpp
+LOCAL_CFLAGS := -Wall -Werror
 include $(BUILD_SHARED_LIBRARY)
 
 # Java platform library for vr stuff.
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 088cbc6..7972d06 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -19,6 +19,7 @@
 
 import android.content.pm.ParceledListSlice;
 
+import android.net.wifi.hotspot2.OsuProvider;
 import android.net.wifi.hotspot2.PasspointConfiguration;
 
 import android.net.wifi.WifiConfiguration;
@@ -61,6 +62,8 @@
 
     WifiConfiguration getMatchingWifiConfig(in ScanResult scanResult);
 
+    List<OsuProvider> getMatchingOsuProviders(in ScanResult scanResult);
+
     int addOrUpdateNetwork(in WifiConfiguration config);
 
     boolean addOrUpdatePasspointConfiguration(in PasspointConfiguration config);
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 91fc2f7..e7fbe4f 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -891,9 +891,13 @@
          */
         public static final int DISABLED_DUE_TO_USER_SWITCH = 11;
         /**
+         * This network is disabled due to wrong password
+         */
+        public static final int DISABLED_BY_WRONG_PASSWORD = 12;
+        /**
          * This Maximum disable reason value
          */
-        public static final int NETWORK_SELECTION_DISABLED_MAX = 12;
+        public static final int NETWORK_SELECTION_DISABLED_MAX = 13;
 
         /**
          * Quality network selection disable reason String (for debug purpose)
@@ -910,7 +914,8 @@
                 "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS",
                 "NETWORK_SELECTION_DISABLED_NO_INTERNET",
                 "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER",
-                "NETWORK_SELECTION_DISABLED_BY_USER_SWITCH"
+                "NETWORK_SELECTION_DISABLED_BY_USER_SWITCH",
+                "NETWORK_SELECTION_DISABLED_BY_WRONG_PASSWORD"
         };
 
         /**
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index e48f7bdb..476ef97 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -105,34 +105,43 @@
     private boolean mEphemeral;
 
     /**
+     * Running total count of lost (not ACKed) transmitted unicast data packets.
      * @hide
      */
     public long txBad;
     /**
+     * Running total count of transmitted unicast data retry packets.
      * @hide
      */
     public long txRetries;
     /**
+     * Running total count of successfully transmitted (ACKed) unicast data packets.
      * @hide
      */
     public long txSuccess;
     /**
+     * Running total count of received unicast data packets.
      * @hide
      */
     public long rxSuccess;
+
     /**
+     * Average rate of lost transmitted packets, in units of packets per 5 seconds.
      * @hide
      */
     public double txBadRate;
     /**
+     * Average rate of transmitted retry packets, in units of packets per 5 seconds.
      * @hide
      */
     public double txRetriesRate;
     /**
+     * Average rate of successfully transmitted unicast packets, in units of packets per 5 seconds.
      * @hide
      */
     public double txSuccessRate;
     /**
+     * Average rate of received unicast data packets, in units of packets per 5 seconds.
      * @hide
      */
     public double rxSuccessRate;
@@ -142,8 +151,9 @@
     /**
      * This factor is used to adjust the rate output under the new algorithm
      * such that the result is comparable to the previous algorithm.
+     * This actually converts from unit 'packets per second' to 'packets per 5 seconds'.
      */
-    private static final long OUTPUT_SCALE_FACTOR = 5000;
+    private static final long OUTPUT_SCALE_FACTOR = 5;
     private long mLastPacketCountUpdateTimeStamp;
 
     /**
@@ -189,16 +199,16 @@
                     double currentSampleWeight = 1.0 - lastSampleWeight;
 
                     txBadRate = txBadRate * lastSampleWeight
-                        + (txbad - txBad) * OUTPUT_SCALE_FACTOR / timeDelta
+                        + (txbad - txBad) * OUTPUT_SCALE_FACTOR * 1000 / timeDelta
                         * currentSampleWeight;
                     txSuccessRate = txSuccessRate * lastSampleWeight
-                        + (txgood - txSuccess) * OUTPUT_SCALE_FACTOR / timeDelta
+                        + (txgood - txSuccess) * OUTPUT_SCALE_FACTOR * 1000 / timeDelta
                         * currentSampleWeight;
                     rxSuccessRate = rxSuccessRate * lastSampleWeight
-                        + (rxgood - rxSuccess) * OUTPUT_SCALE_FACTOR / timeDelta
+                        + (rxgood - rxSuccess) * OUTPUT_SCALE_FACTOR * 1000 / timeDelta
                         * currentSampleWeight;
                     txRetriesRate = txRetriesRate * lastSampleWeight
-                        + (txretries - txRetries) * OUTPUT_SCALE_FACTOR / timeDelta
+                        + (txretries - txRetries) * OUTPUT_SCALE_FACTOR * 1000/ timeDelta
                         * currentSampleWeight;
             } else {
                 txBadRate = 0;
@@ -438,6 +448,22 @@
     }
 
     /**
+     * @hide
+     * This returns txSuccessRate in packets per second.
+     */
+    public double getTxSuccessRatePps() {
+        return txSuccessRate / OUTPUT_SCALE_FACTOR;
+    }
+
+    /**
+     * @hide
+     * This returns rxSuccessRate in packets per second.
+     */
+    public double getRxSuccessRatePps() {
+        return rxSuccessRate / OUTPUT_SCALE_FACTOR;
+    }
+
+    /**
      * Record the MAC address of the WLAN interface
      * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form
      * @hide
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index c89a9a4..4684c77 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -30,6 +30,7 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.net.wifi.hotspot2.OsuProvider;
 import android.net.wifi.hotspot2.PasspointConfiguration;
 import android.os.Binder;
 import android.os.Build;
@@ -675,16 +676,28 @@
     @SystemApi
     public static final int CHANGE_REASON_CONFIG_CHANGE = 2;
     /**
-     * An access point scan has completed, and results are available from the supplicant.
-     * Call {@link #getScanResults()} to obtain the results. {@link #EXTRA_RESULTS_UPDATED}
-     * indicates if the scan was completed successfully.
+     * An access point scan has completed, and results are available.
+     * Call {@link #getScanResults()} to obtain the results.
+     * The broadcast intent may contain an extra field with the key {@link #EXTRA_RESULTS_UPDATED}
+     * and a {@code boolean} value indicating if the scan was successful.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
 
     /**
-     * Lookup key for a {@code boolean} representing the result of previous {@link #startScan}
-     * operation, reported with {@link #SCAN_RESULTS_AVAILABLE_ACTION}.
+     * Lookup key for a {@code boolean} extra in intent {@link #SCAN_RESULTS_AVAILABLE_ACTION}
+     * representing if the scan was successful or not.
+     * Scans may fail for multiple reasons, these may include:
+     * <ol>
+     * <li>A non-privileged app requested too many scans in a certain period of time.
+     * This may lead to additional scan request rejections via "scan throttling".
+     * See
+     * <a href="https://developer.android.com/preview/features/background-location-limits.html">
+     * here</a> for details.
+     * </li>
+     * <li>The device is idle and scanning is disabled.</li>
+     * <li>Wifi hardware reported a scan failure.</li>
+     * </ol>
      * @return true scan was successful, results are updated
      * @return false scan was not successful, results haven't been updated since previous scan
      */
@@ -1000,11 +1013,9 @@
     /**
      * Returns a WifiConfiguration matching this ScanResult
      *
-     * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled
-     * on the device.
-     *
      * @param scanResult scanResult that represents the BSSID
      * @return {@link WifiConfiguration} that matches this BSSID or null
+     * @throws UnsupportedOperationException if Passpoint is not enabled on the device.
      * @hide
      */
     public WifiConfiguration getMatchingWifiConfig(ScanResult scanResult) {
@@ -1016,6 +1027,24 @@
     }
 
     /**
+     * Returns a list of Hotspot 2.0 OSU (Online Sign-Up) providers associated with the given AP.
+     *
+     * An empty list will be returned if no match is found.
+     *
+     * @param scanResult scanResult that represents the BSSID
+     * @return list of {@link OsuProvider}
+     * @throws UnsupportedOperationException if Passpoint is not enabled on the device.
+     * @hide
+     */
+    public List<OsuProvider> getMatchingOsuProviders(ScanResult scanResult) {
+        try {
+            return mService.getMatchingOsuProviders(scanResult);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Add a new network description to the set of configured networks.
      * The {@code networkId} field of the supplied configuration object
      * is ignored.
@@ -1382,6 +1411,8 @@
     public static final int WIFI_FEATURE_IE_WHITELIST     = 0x1000000; // Probe IE white listing
     /** @hide */
     public static final int WIFI_FEATURE_SCAN_RAND        = 0x2000000; // Random MAC & Probe seq
+    /** @hide */
+    public static final int WIFI_FEATURE_TX_POWER_LIMIT   = 0x4000000; // Set Tx power limit
 
 
     private int getSupportedFeatures() {
@@ -1724,9 +1755,18 @@
 
     /**
      * Enable or disable Wi-Fi.
+     *
+     * Note: This method will return false if wifi cannot be enabled (e.g., an incompatible mode
+     * where the user has enabled tethering or Airplane Mode).
+     *
+     * Applications need to have the {@link android.Manifest.permission#CHANGE_WIFI_STATE}
+     * permission to toggle wifi. Callers without the permissions will trigger a
+     * {@link java.lang.SecurityException}.
+     *
      * @param enabled {@code true} to enable, {@code false} to disable.
      * @return {@code true} if the operation succeeds (or if the existing state
-     *         is the same as the requested state).
+     *         is the same as the requested state). False if wifi cannot be toggled on/off when the
+     *         request is made.
      */
     public boolean setWifiEnabled(boolean enabled) {
         try {
@@ -2273,12 +2313,20 @@
      */
     @SystemApi
     public interface ActionListener {
-        /** The operation succeeded */
+        /**
+         * The operation succeeded.
+         * This is called when the scan request has been validated and ready
+         * to sent to driver.
+         */
         public void onSuccess();
         /**
-         * The operation failed
-         * @param reason The reason for failure could be one of
-         * {@link #ERROR}, {@link #IN_PROGRESS} or {@link #BUSY}
+         * The operation failed.
+         * This is called when the scan request failed.
+         * @param reason The reason for failure could be one of the following:
+         * {@link #REASON_INVALID_REQUEST}} is specified when scan request parameters are invalid.
+         * {@link #REASON_NOT_AUTHORIZED} is specified when requesting app doesn't have the required
+         * permission to request a scan.
+         * {@link #REASON_UNSPECIFIED} is specified when driver reports a scan failure.
          */
         public void onFailure(int reason);
     }
diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java
index 7a3cddf..5deb80a 100644
--- a/wifi/java/android/net/wifi/WifiSsid.java
+++ b/wifi/java/android/net/wifi/WifiSsid.java
@@ -26,6 +26,7 @@
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CoderResult;
 import java.nio.charset.CodingErrorAction;
+import java.util.Arrays;
 import java.util.Locale;
 
 /**
@@ -189,6 +190,23 @@
         return out.toString();
     }
 
+    @Override
+    public boolean equals(Object thatObject) {
+        if (this == thatObject) {
+            return true;
+        }
+        if (!(thatObject instanceof WifiSsid)) {
+            return false;
+        }
+        WifiSsid that = (WifiSsid) thatObject;
+        return Arrays.equals(octets.toByteArray(), that.octets.toByteArray());
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(octets.toByteArray());
+    }
+
     private boolean isArrayAllZeroes(byte[] ssidBytes) {
         for (int i = 0; i< ssidBytes.length; i++) {
             if (ssidBytes[i] != 0) return false;
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySession.java b/wifi/java/android/net/wifi/aware/DiscoverySession.java
index c7e1fc7..357f76e 100644
--- a/wifi/java/android/net/wifi/aware/DiscoverySession.java
+++ b/wifi/java/android/net/wifi/aware/DiscoverySession.java
@@ -82,7 +82,7 @@
         mClientId = clientId;
         mSessionId = sessionId;
 
-        mCloseGuard.open("destroy");
+        mCloseGuard.open("close");
     }
 
     /**
@@ -130,8 +130,11 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            if (!mTerminated) {
+            if (mCloseGuard != null) {
                 mCloseGuard.warnIfOpen();
+            }
+
+            if (!mTerminated) {
                 close();
             }
         } finally {
@@ -339,8 +342,8 @@
      */
     public NetworkSpecifier createNetworkSpecifierPassphrase(
             @Nullable PeerHandle peerHandle, @NonNull String passphrase) {
-        if (passphrase == null || passphrase.length() == 0) {
-            throw new IllegalArgumentException("Passphrase must not be null or empty");
+        if (!WifiAwareUtils.validatePassphrase(passphrase)) {
+            throw new IllegalArgumentException("Passphrase must meet length requirements");
         }
 
         if (mTerminated) {
@@ -402,8 +405,8 @@
     @SystemApi
     public NetworkSpecifier createNetworkSpecifierPmk(@Nullable PeerHandle peerHandle,
             @NonNull byte[] pmk) {
-        if (pmk == null || pmk.length == 0) {
-            throw new IllegalArgumentException("PMK must not be null or empty");
+        if (!WifiAwareUtils.validatePmk(pmk)) {
+            throw new IllegalArgumentException("PMK must 32 bytes");
         }
 
         if (mTerminated) {
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
index d8667e6..115b86d 100644
--- a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
+++ b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
@@ -100,7 +100,12 @@
      * @param serviceSpecificInfo The service specific information (arbitrary
      *            byte array) provided by the peer as part of its discovery
      *            configuration.
-     * @param matchFilter The filter which resulted in this service discovery.
+     * @param matchFilter The filter which resulted in this service discovery. For
+     * {@link PublishConfig#PUBLISH_TYPE_UNSOLICITED},
+     * {@link SubscribeConfig#SUBSCRIBE_TYPE_PASSIVE} discovery sessions this is the publisher's
+     *                    match filter. For {@link PublishConfig#PUBLISH_TYPE_SOLICITED},
+     *                    {@link SubscribeConfig#SUBSCRIBE_TYPE_ACTIVE} discovery sessions this
+     *                    is the subscriber's match filter.
      */
     public void onServiceDiscovered(PeerHandle peerHandle,
             byte[] serviceSpecificInfo, List<byte[]> matchFilter) {
diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java
index 0f1e992..d018620 100644
--- a/wifi/java/android/net/wifi/aware/PublishConfig.java
+++ b/wifi/java/android/net/wifi/aware/PublishConfig.java
@@ -93,12 +93,17 @@
 
     @Override
     public String toString() {
-        return "PublishConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + (
-                (mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo))
-                + ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1,
-                mMatchFilter)).toString() + ", mPublishType=" + mPublishType
-                + ", mTtlSec=" + mTtlSec + ", mEnableTerminateNotification="
-                + mEnableTerminateNotification + "]";
+        return "PublishConfig [mServiceName='" + (mServiceName == null ? "<null>" : String.valueOf(
+                HexEncoding.encode(mServiceName))) + ", mServiceName.length=" + (
+                mServiceName == null ? 0 : mServiceName.length) + ", mServiceSpecificInfo='" + (
+                (mServiceSpecificInfo == null) ? "<null>" : String.valueOf(
+                        HexEncoding.encode(mServiceSpecificInfo)))
+                + ", mServiceSpecificInfo.length=" + (mServiceSpecificInfo == null ? 0
+                : mServiceSpecificInfo.length) + ", mMatchFilter="
+                + (new TlvBufferUtils.TlvIterable(0, 1, mMatchFilter)).toString()
+                + ", mMatchFilter.length=" + (mMatchFilter == null ? 0 : mMatchFilter.length)
+                + ", mPublishType=" + mPublishType + ", mTtlSec=" + mTtlSec
+                + ", mEnableTerminateNotification=" + mEnableTerminateNotification + "]";
     }
 
     @Override
diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
index 31e7e8e..4bf2fb6 100644
--- a/wifi/java/android/net/wifi/aware/SubscribeConfig.java
+++ b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
@@ -92,13 +92,17 @@
 
     @Override
     public String toString() {
-        return "SubscribeConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + (
-                (mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo))
-                + ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1,
-                mMatchFilter)).toString() + ", mSubscribeType=" + mSubscribeType
-                + ", mTtlSec=" + mTtlSec
-                + ", mEnableTerminateNotification=" + mEnableTerminateNotification
-                + "]";
+        return "SubscribeConfig [mServiceName='" + (mServiceName == null ? "<null>"
+                : String.valueOf(HexEncoding.encode(mServiceName))) + ", mServiceName.length=" + (
+                mServiceName == null ? 0 : mServiceName.length) + ", mServiceSpecificInfo='" + (
+                (mServiceSpecificInfo == null) ? "<null>" : String.valueOf(
+                        HexEncoding.encode(mServiceSpecificInfo)))
+                + ", mServiceSpecificInfo.length=" + (mServiceSpecificInfo == null ? 0
+                : mServiceSpecificInfo.length) + ", mMatchFilter="
+                + (new TlvBufferUtils.TlvIterable(0, 1, mMatchFilter)).toString()
+                + ", mMatchFilter.length=" + (mMatchFilter == null ? 0 : mMatchFilter.length)
+                + ", mSubscribeType=" + mSubscribeType + ", mTtlSec=" + mTtlSec
+                + ", mEnableTerminateNotification=" + mEnableTerminateNotification + "]";
     }
 
     @Override
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
index e152f6c..eeabbfa 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
@@ -161,6 +161,16 @@
                 }
             };
 
+    /**
+     * Indicates whether the network specifier specifies an OOB (out-of-band) data-path - i.e. a
+     * data-path created without a corresponding Aware discovery session.
+     *
+     * @hide
+     */
+    public boolean isOutOfBand() {
+        return type == NETWORK_SPECIFIER_TYPE_OOB || type == NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER;
+    }
+
     @Override
     public int describeContents() {
         return 0;
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
index 4e060d5..f26b9f5 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
@@ -54,7 +54,7 @@
         mClientId = clientId;
         mTerminated = false;
 
-        mCloseGuard.open("destroy");
+        mCloseGuard.open("close");
     }
 
     /**
@@ -67,6 +67,7 @@
      * An application may re-attach after a destroy using
      * {@link WifiAwareManager#attach(AttachCallback, Handler)} .
      */
+    @Override
     public void close() {
         WifiAwareManager mgr = mMgr.get();
         if (mgr == null) {
@@ -83,8 +84,11 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            if (!mTerminated) {
+            if (mCloseGuard != null) {
                 mCloseGuard.warnIfOpen();
+            }
+
+            if (!mTerminated) {
                 close();
             }
         } finally {
@@ -266,9 +270,10 @@
             Log.e(TAG, "createNetworkSpecifierPassphrase: called after termination");
             return null;
         }
-        if (passphrase == null || passphrase.length() == 0) {
-            throw new IllegalArgumentException("Passphrase must not be null or empty");
+        if (!WifiAwareUtils.validatePassphrase(passphrase)) {
+            throw new IllegalArgumentException("Passphrase must meet length requirements");
         }
+
         return mgr.createNetworkSpecifier(mClientId, role, peer, null, passphrase);
     }
 
@@ -316,8 +321,8 @@
             Log.e(TAG, "createNetworkSpecifierPmk: called after termination");
             return null;
         }
-        if (pmk == null || pmk.length == 0) {
-            throw new IllegalArgumentException("PMK must not be null or empty");
+        if (!WifiAwareUtils.validatePmk(pmk)) {
+            throw new IllegalArgumentException("PMK must 32 bytes");
         }
         return mgr.createNetworkSpecifier(mClientId, role, peer, pmk, null);
     }
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareUtils.java b/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
index 4083388..fda7a9a 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
@@ -16,6 +16,8 @@
 
 package android.net.wifi.aware;
 
+import android.hardware.wifi.V1_0.Constants;
+
 /**
  * Provides utilities for the Wifi Aware manager/service.
  *
@@ -51,4 +53,35 @@
             ++index;
         }
     }
+
+    /**
+     * Validates that the passphrase is a non-null string of the right size (per the HAL min/max
+     * length parameters).
+     *
+     * @param passphrase Passphrase to test
+     * @return true if passphrase is valid, false if not
+     */
+    public static boolean validatePassphrase(String passphrase) {
+        if (passphrase == null
+                || passphrase.length() < Constants.NanParamSizeLimits.MIN_PASSPHRASE_LENGTH
+                || passphrase.length() > Constants.NanParamSizeLimits.MAX_PASSPHRASE_LENGTH) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Validates that the PMK is a non-null byte array of the right size (32 bytes per spec).
+     *
+     * @param pmk PMK to test
+     * @return true if PMK is valid, false if not
+     */
+    public static boolean validatePmk(byte[] pmk) {
+        if (pmk == null || pmk.length != 32) {
+            return false;
+        }
+
+        return true;
+    }
 }
diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.aidl b/wifi/java/android/net/wifi/hotspot2/OsuProvider.aidl
new file mode 100644
index 0000000..23d0f22
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/OsuProvider.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.net.wifi.hotspot2;
+
+parcelable OsuProvider;
diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java
new file mode 100644
index 0000000..25dcdd8
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.net.wifi.hotspot2;
+
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.net.wifi.WifiSsid;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Contained information for a Hotspot 2.0 OSU (Online Sign-Up provider).
+ *
+ * @hide
+ */
+public final class OsuProvider implements Parcelable {
+    /**
+     * OSU (Online Sign-Up) method: OMA DM (Open Mobile Alliance Device Management).
+     * For more info, refer to Section 8.3 of the Hotspot 2.0 Release 2 Technical Specification.
+     */
+    public static final int METHOD_OMA_DM = 0;
+
+    /**
+     * OSU (Online Sign-Up) method: SOAP XML SPP (Subscription Provisioning Protocol).
+     * For more info, refer to Section 8.4 of the Hotspot 2.0 Release 2 Technical Specification.
+     */
+    public static final int METHOD_SOAP_XML_SPP = 1;
+
+    /**
+     * SSID of the network to connect for service sign-up.
+     */
+    private final WifiSsid mOsuSsid;
+
+    /**
+     * Friendly name of the OSU provider.
+     */
+    private final String mFriendlyName;
+
+    /**
+     * Description of the OSU provider.
+     */
+    private final String mServiceDescription;
+
+    /**
+     * URI to browse to for service sign-up.
+     */
+    private final Uri mServerUri;
+
+    /**
+     * Network Access Identifier used for authenticating with the OSU network when OSEN is used.
+     */
+    private final String mNetworkAccessIdentifier;
+
+    /**
+     * List of OSU (Online Sign-Up) method supported.
+     */
+    private final List<Integer> mMethodList;
+
+    /**
+     * Icon data for the OSU (Online Sign-Up) provider.
+     */
+    private final Icon mIcon;
+
+    public OsuProvider(WifiSsid osuSsid, String friendlyName, String serviceDescription,
+            Uri serverUri, String nai, List<Integer> methodList, Icon icon) {
+        mOsuSsid = osuSsid;
+        mFriendlyName = friendlyName;
+        mServiceDescription = serviceDescription;
+        mServerUri = serverUri;
+        mNetworkAccessIdentifier = nai;
+        if (methodList == null) {
+            mMethodList = new ArrayList<>();
+        } else {
+            mMethodList = new ArrayList<>(methodList);
+        }
+        mIcon = icon;
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param source The source to copy from
+     */
+    public OsuProvider(OsuProvider source) {
+        if (source == null) {
+            mOsuSsid = null;
+            mFriendlyName = null;
+            mServiceDescription = null;
+            mServerUri = null;
+            mNetworkAccessIdentifier = null;
+            mMethodList = new ArrayList<>();
+            mIcon = null;
+            return;
+        }
+
+        mOsuSsid = source.mOsuSsid;
+        mFriendlyName = source.mFriendlyName;
+        mServiceDescription = source.mServiceDescription;
+        mServerUri = source.mServerUri;
+        mNetworkAccessIdentifier = source.mNetworkAccessIdentifier;
+        if (source.mMethodList == null) {
+            mMethodList = new ArrayList<>();
+        } else {
+            mMethodList = new ArrayList<>(source.mMethodList);
+        }
+        mIcon = source.mIcon;
+    }
+
+    public WifiSsid getOsuSsid() {
+        return mOsuSsid;
+    }
+
+    public String getFriendlyName() {
+        return mFriendlyName;
+    }
+
+    public String getServiceDescription() {
+        return mServiceDescription;
+    }
+
+    public Uri getServerUri() {
+        return mServerUri;
+    }
+
+    public String getNetworkAccessIdentifier() {
+        return mNetworkAccessIdentifier;
+    }
+
+    public List<Integer> getMethodList() {
+        return Collections.unmodifiableList(mMethodList);
+    }
+
+    public Icon getIcon() {
+        return mIcon;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(mOsuSsid, flags);
+        dest.writeString(mFriendlyName);
+        dest.writeString(mServiceDescription);
+        dest.writeParcelable(mServerUri, flags);
+        dest.writeString(mNetworkAccessIdentifier);
+        dest.writeList(mMethodList);
+        dest.writeParcelable(mIcon, flags);
+    }
+
+    @Override
+    public boolean equals(Object thatObject) {
+        if (this == thatObject) {
+            return true;
+        }
+        if (!(thatObject instanceof OsuProvider)) {
+            return false;
+        }
+        OsuProvider that = (OsuProvider) thatObject;
+        return (mOsuSsid == null ? that.mOsuSsid == null : mOsuSsid.equals(that.mOsuSsid))
+                && TextUtils.equals(mFriendlyName, that.mFriendlyName)
+                && TextUtils.equals(mServiceDescription, that.mServiceDescription)
+                && (mServerUri == null ? that.mServerUri == null
+                            : mServerUri.equals(that.mServerUri))
+                && TextUtils.equals(mNetworkAccessIdentifier, that.mNetworkAccessIdentifier)
+                && (mMethodList == null ? that.mMethodList == null
+                            : mMethodList.equals(that.mMethodList))
+                && (mIcon == null ? that.mIcon == null : mIcon.sameAs(that.mIcon));
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mOsuSsid, mFriendlyName, mServiceDescription, mServerUri,
+                mNetworkAccessIdentifier, mMethodList, mIcon);
+    }
+
+    @Override
+    public String toString() {
+        return "OsuProvider{mOsuSsid=" + mOsuSsid
+                + " mFriendlyName=" + mFriendlyName
+                + " mServiceDescription=" + mServiceDescription
+                + " mServerUri=" + mServerUri
+                + " mNetworkAccessIdentifier=" + mNetworkAccessIdentifier
+                + " mMethodList=" + mMethodList
+                + " mIcon=" + mIcon;
+    }
+
+    public static final Creator<OsuProvider> CREATOR =
+        new Creator<OsuProvider>() {
+            @Override
+            public OsuProvider createFromParcel(Parcel in) {
+                WifiSsid osuSsid = (WifiSsid) in.readParcelable(null);
+                String friendlyName = in.readString();
+                String serviceDescription = in.readString();
+                Uri serverUri = (Uri) in.readParcelable(null);
+                String nai = in.readString();
+                List<Integer> methodList = new ArrayList<>();
+                in.readList(methodList, null);
+                Icon icon = (Icon) in.readParcelable(null);
+                return new OsuProvider(osuSsid, friendlyName, serviceDescription, serverUri,
+                        nai, methodList, icon);
+            }
+
+            @Override
+            public OsuProvider[] newArray(int size) {
+                return new OsuProvider[size];
+            }
+        };
+}
diff --git a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
index 8b1cfae..bfdd45d 100644
--- a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
+++ b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
@@ -25,8 +25,9 @@
  */
 interface IWifiP2pManager
 {
-    Messenger getMessenger();
+    Messenger getMessenger(in IBinder binder);
     Messenger getP2pStateMachineMessenger();
+    oneway void close(in IBinder binder);
     void setMiracastMode(int mode);
     void checkConfigureWifiDisplayPermission();
 }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 95d0a79..0d4359e 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -28,6 +28,7 @@
 import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo;
 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceResponse;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -668,11 +669,12 @@
      * by doing a call on {@link #initialize}
      */
     public static class Channel {
-        Channel(Context context, Looper looper, ChannelListener l) {
+        Channel(Context context, Looper looper, ChannelListener l, Binder binder) {
             mAsyncChannel = new AsyncChannel();
             mHandler = new P2pHandler(looper);
             mChannelListener = l;
             mContext = context;
+            mBinder = binder;
         }
         private final static int INVALID_LISTENER_KEY = 0;
         private ChannelListener mChannelListener;
@@ -681,9 +683,11 @@
         private DnsSdTxtRecordListener mDnsSdTxtListener;
         private UpnpServiceResponseListener mUpnpServRspListener;
         private HashMap<Integer, Object> mListenerMap = new HashMap<Integer, Object>();
-        private Object mListenerMapLock = new Object();
+        private final Object mListenerMapLock = new Object();
         private int mListenerKey = 0;
 
+        /* package */ final Binder mBinder;
+
         private AsyncChannel mAsyncChannel;
         private P2pHandler mHandler;
         Context mContext;
@@ -889,7 +893,10 @@
      * @return Channel instance that is necessary for performing any further p2p operations
      */
     public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
-        return initalizeChannel(srcContext, srcLooper, listener, getMessenger());
+        Binder binder = new Binder();
+        Channel channel = initalizeChannel(srcContext, srcLooper, listener, getMessenger(binder),
+                binder);
+        return channel;
     }
 
     /**
@@ -898,14 +905,15 @@
      */
     public Channel initializeInternal(Context srcContext, Looper srcLooper,
                                       ChannelListener listener) {
-        return initalizeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger());
+        return initalizeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger(),
+                null);
     }
 
     private Channel initalizeChannel(Context srcContext, Looper srcLooper, ChannelListener listener,
-                                     Messenger messenger) {
+                                     Messenger messenger, Binder binder) {
         if (messenger == null) return null;
 
-        Channel c = new Channel(srcContext, srcLooper, listener);
+        Channel c = new Channel(srcContext, srcLooper, listener, binder);
         if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger)
                 == AsyncChannel.STATUS_SUCCESSFUL) {
             return c;
@@ -1385,12 +1393,14 @@
      * Get a reference to WifiP2pService handler. This is used to establish
      * an AsyncChannel communication with WifiService
      *
+     * @param binder A binder for the service to associate with this client.
+     *
      * @return Messenger pointing to the WifiP2pService handler
      * @hide
      */
-    public Messenger getMessenger() {
+    public Messenger getMessenger(Binder binder) {
         try {
-            return mService.getMessenger();
+            return mService.getMessenger(binder);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1412,6 +1422,24 @@
     }
 
     /**
+     * Close the current P2P connection and clean-up any configuration requested by the
+     * current app. Takes same action as taken when the app dies.
+     *
+     * @param c is the channel created at {@link #initialize}
+     *
+     * @hide
+     */
+    public void close(Channel c) {
+        try {
+            if (c != null) {
+                mService.close(c.mBinder);
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Get a handover request message for use in WFA NFC Handover transfer.
      * @hide
      */
diff --git a/wifi/tests/AndroidTest.xml b/wifi/tests/AndroidTest.xml
index c30dcea..764eb2b 100644
--- a/wifi/tests/AndroidTest.xml
+++ b/wifi/tests/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="FrameworksWifiApiTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.net.wifi.test" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/wifi/tests/src/android/net/wifi/WifiSsidTest.java b/wifi/tests/src/android/net/wifi/WifiSsidTest.java
index c7bdb7b..e5794c5 100644
--- a/wifi/tests/src/android/net/wifi/WifiSsidTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiSsidTest.java
@@ -16,25 +16,43 @@
 
 package android.net.wifi;
 
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import org.junit.Test;
 
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
 /**
  * Unit tests for {@link android.net.wifi.WifiSsid}.
  */
 public class WifiSsidTest {
 
-    private static final byte[] TEST_SSID =
-            new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'};
+    private static final String TEST_SSID = "Test SSID";
+    private static final byte[] TEST_SSID_BYTES = TEST_SSID.getBytes(StandardCharsets.US_ASCII);
+
     /**
      * Check that createFromByteArray() works.
      */
     @Test
     public void testCreateFromByteArray() {
-        WifiSsid wifiSsid = WifiSsid.createFromByteArray(TEST_SSID);
+        WifiSsid wifiSsid = WifiSsid.createFromByteArray(TEST_SSID_BYTES);
         assertTrue(wifiSsid != null);
-        assertEquals(new String(TEST_SSID), wifiSsid.toString());
+        assertEquals(TEST_SSID, wifiSsid.toString());
+    }
+
+    /**
+     * Verify that SSID created from byte array and string with the same content are equal.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testEquals() throws Exception {
+        WifiSsid fromBytes = WifiSsid.createFromByteArray(TEST_SSID_BYTES);
+        WifiSsid fromString = WifiSsid.createFromAsciiEncoded(TEST_SSID);
+        assertTrue(fromBytes != null);
+        assertTrue(fromString != null);
+        assertEquals(fromBytes, fromString);
     }
 }
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index 694b911..d9433c5 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -32,6 +32,7 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Parcel;
+import android.os.RemoteException;
 import android.os.test.TestLooper;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -938,7 +939,7 @@
         final int sessionId = 123;
         final PeerHandle peerHandle = new PeerHandle(123412);
         final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-        final byte[] pmk = "Some arbitrary byte array".getBytes();
+        final byte[] pmk = "01234567890123456789012345678901".getBytes();
         final String passphrase = "A really bad password";
         final ConfigRequest configRequest = new ConfigRequest.Builder().build();
         final PublishConfig publishConfig = new PublishConfig.Builder().build();
@@ -1019,7 +1020,7 @@
         final ConfigRequest configRequest = new ConfigRequest.Builder().build();
         final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
         final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
-        final byte[] pmk = "Some arbitrary pmk data".getBytes();
+        final byte[] pmk = "01234567890123456789012345678901".getBytes();
         final String passphrase = "A really bad password";
 
         ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
@@ -1070,4 +1071,162 @@
         verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
                 mockPublishSession, mockRttListener);
     }
+
+    /**
+     * Validate that a null PMK triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierWithClientNullPmk() throws Exception {
+        executeNetworkSpecifierWithClient(true, null, null);
+    }
+
+    /**
+     * Validate that a non-32-bytes PMK triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierWithClientIncorrectLengthPmk() throws Exception {
+        executeNetworkSpecifierWithClient(true, "012".getBytes(), null);
+    }
+
+    /**
+     * Validate that a null Passphrase triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierWithClientNullPassphrase() throws Exception {
+        executeNetworkSpecifierWithClient(false, null, null);
+    }
+
+    /**
+     * Validate that a too short Passphrase triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierWithClientShortPassphrase() throws Exception {
+        executeNetworkSpecifierWithClient(false, null, "012");
+    }
+
+    /**
+     * Validate that a too long Passphrase triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierWithClientLongPassphrase() throws Exception {
+        executeNetworkSpecifierWithClient(false, null,
+                "0123456789012345678901234567890123456789012345678901234567890123456789");
+    }
+
+    private void executeNetworkSpecifierWithClient(boolean doPmk, byte[] pmk, String passphrase)
+            throws Exception {
+        final int clientId = 4565;
+        final int sessionId = 123;
+        final PeerHandle peerHandle = new PeerHandle(123412);
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        final PublishConfig publishConfig = new PublishConfig.Builder().build();
+
+        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
+                WifiAwareSession.class);
+        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiAwareEventCallback.class);
+        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
+                .forClass(IWifiAwareDiscoverySessionCallback.class);
+        ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
+                .forClass(PublishDiscoverySession.class);
+
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
+                mockPublishSession, mockRttListener);
+
+        // (1) connect successfully
+        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
+        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+                eq(configRequest), eq(false));
+        clientProxyCallback.getValue().onConnectSuccess(clientId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
+        WifiAwareSession session = sessionCaptor.getValue();
+
+        // (2) publish successfully
+        session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
+        inOrder.verify(mockAwareService).publish(eq(clientId), eq(publishConfig),
+                sessionProxyCallback.capture());
+        sessionProxyCallback.getValue().onSessionStarted(sessionId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
+
+        // (3) create network specifier
+        if (doPmk) {
+            publishSession.getValue().createNetworkSpecifierPmk(peerHandle, pmk);
+        } else {
+            publishSession.getValue().createNetworkSpecifierPassphrase(peerHandle, passphrase);
+        }
+    }
+
+    /**
+     * Validate that a null PMK triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierDirectNullPmk() throws Exception {
+        executeNetworkSpecifierDirect(true, null, null);
+    }
+
+    /**
+     * Validate that a non-32-bytes PMK triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierDirectIncorrectLengthPmk() throws Exception {
+        executeNetworkSpecifierDirect(true, "012".getBytes(), null);
+    }
+
+    /**
+     * Validate that a null Passphrase triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierDirectNullPassphrase() throws Exception {
+        executeNetworkSpecifierDirect(false, null, null);
+    }
+
+    /**
+     * Validate that a too short Passphrase triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierDirectShortPassphrase() throws Exception {
+        executeNetworkSpecifierDirect(false, null, "012");
+    }
+
+    /**
+     * Validate that a too long Passphrase triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierDirectLongPassphrase() throws Exception {
+        executeNetworkSpecifierDirect(false, null,
+                "0123456789012345678901234567890123456789012345678901234567890123456789");
+    }
+
+    private void executeNetworkSpecifierDirect(boolean doPmk, byte[] pmk, String passphrase)
+            throws Exception {
+        final int clientId = 134;
+        final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
+        final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+
+        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
+                WifiAwareSession.class);
+        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiAwareEventCallback.class);
+
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
+                mockPublishSession, mockRttListener);
+
+        // (1) connect successfully
+        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
+        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+                eq(configRequest), eq(false));
+        clientProxyCallback.getValue().onConnectSuccess(clientId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
+
+        // (2) create network specifier
+        if (doPmk) {
+            sessionCaptor.getValue().createNetworkSpecifierPmk(role, someMac, pmk);
+        } else {
+            sessionCaptor.getValue().createNetworkSpecifierPassphrase(role, someMac, passphrase);
+        }
+    }
 }
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java
new file mode 100644
index 0000000..9670bfa
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.net.wifi.hotspot2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.net.wifi.WifiSsid;
+import android.os.Parcel;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Unit tests for {@link android.net.wifi.hotspot2.OsuProvider}.
+ */
+@SmallTest
+public class OsuProviderTest {
+    private static final WifiSsid TEST_SSID =
+            WifiSsid.createFromByteArray("TEST SSID".getBytes(StandardCharsets.UTF_8));
+    private static final String TEST_FRIENDLY_NAME = "Friendly Name";
+    private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service";
+    private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com");
+    private static final String TEST_NAI = "test.access.com";
+    private static final List<Integer> TEST_METHOD_LIST =
+            Arrays.asList(OsuProvider.METHOD_SOAP_XML_SPP);
+    private static final Icon TEST_ICON = Icon.createWithData(new byte[10], 0, 10);
+
+    /**
+     * Verify parcel write and read consistency for the given {@link OsuProvider}.
+     *
+     * @param writeInfo The {@link OsuProvider} to verify
+     * @throws Exception
+     */
+    private static void verifyParcel(OsuProvider writeInfo) throws Exception {
+        Parcel parcel = Parcel.obtain();
+        writeInfo.writeToParcel(parcel, 0);
+
+        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
+        OsuProvider readInfo = OsuProvider.CREATOR.createFromParcel(parcel);
+        assertEquals(writeInfo, readInfo);
+    }
+
+    /**
+     * Verify parcel read/write for an OSU provider containing no information.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void verifyParcelWithEmptyProviderInfo() throws Exception {
+        verifyParcel(new OsuProvider(null, null, null, null, null, null, null));
+    }
+
+    /**
+     * Verify parcel read/write for an OSU provider containing full information.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void verifyParcelWithFullProviderInfo() throws Exception {
+        verifyParcel(new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAME, TEST_SERVICE_DESCRIPTION,
+                TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON));
+    }
+
+    /**
+     * Verify copy constructor with a null source.
+     * @throws Exception
+     */
+    @Test
+    public void verifyCopyConstructorWithNullSource() throws Exception {
+        OsuProvider expected = new OsuProvider(null, null, null, null, null, null, null);
+        assertEquals(expected, new OsuProvider(null));
+    }
+
+    /**
+     * Verify copy constructor with a valid source.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void verifyCopyConstructorWithValidSource() throws Exception {
+        OsuProvider source = new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAME, TEST_SERVICE_DESCRIPTION,
+                TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON);
+        assertEquals(source, new OsuProvider(source));
+    }
+
+    /**
+     * Verify getter methods.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void verifyGetters() throws Exception {
+        OsuProvider provider = new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAME,
+                TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON);
+        assertTrue(TEST_SSID.equals(provider.getOsuSsid()));
+        assertTrue(TEST_FRIENDLY_NAME.equals(provider.getFriendlyName()));
+        assertTrue(TEST_SERVICE_DESCRIPTION.equals(provider.getServiceDescription()));
+        assertTrue(TEST_SERVER_URI.equals(provider.getServerUri()));
+        assertTrue(TEST_NAI.equals(provider.getNetworkAccessIdentifier()));
+        assertTrue(TEST_METHOD_LIST.equals(provider.getMethodList()));
+        assertTrue(TEST_ICON.sameAs(provider.getIcon()));
+    }
+}